From 3fcedec752108de5d99b9f0373ff880756a1e87d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 26 Oct 2010 12:25:32 +0200 Subject: drivers/vhost/vhost.c: delete double assignment Delete successive assignments to the same location. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression i; @@ *i = ...; i = ...; // Signed-off-by: Julia Lawall Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94701ff3a23a..ed277276fa98 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -157,7 +157,6 @@ static void vhost_vq_reset(struct vhost_dev *dev, vq->avail_idx = 0; vq->last_used_idx = 0; vq->used_flags = 0; - vq->used_flags = 0; vq->log_used = false; vq->log_addr = -1ull; vq->vhost_hlen = 0; -- cgit v1.2.3-59-g8ed1b From 533a19b4b88fcf81da3106b94f0ac4ac8b33a248 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 6 Oct 2010 15:34:38 +0200 Subject: vhost: put mm after thread stop makes it possible to batch use/unuse mm Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ed277276fa98..9920bae6ee43 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -401,15 +401,14 @@ void vhost_dev_cleanup(struct vhost_dev *dev) kfree(rcu_dereference_protected(dev->memory, lockdep_is_held(&dev->mutex))); RCU_INIT_POINTER(dev->memory, NULL); - if (dev->mm) - mmput(dev->mm); - dev->mm = NULL; - WARN_ON(!list_empty(&dev->work_list)); if (dev->worker) { kthread_stop(dev->worker); dev->worker = NULL; } + if (dev->mm) + mmput(dev->mm); + dev->mm = NULL; } static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) -- cgit v1.2.3-59-g8ed1b From 64e1c80748afca3b4818ebb232a9668bf529886d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 6 Oct 2010 15:34:45 +0200 Subject: vhost-net: batch use/unuse mm Move use/unuse mm to vhost.c which makes it possible to batch these operations. Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 7 ------- drivers/vhost/vhost.c | 7 ++++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 4b4da5b86ff9..d10da280fa0f 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -142,7 +141,6 @@ static void handle_tx(struct vhost_net *net) return; } - use_mm(net->dev.mm); mutex_lock(&vq->mutex); vhost_disable_notify(vq); @@ -207,7 +205,6 @@ static void handle_tx(struct vhost_net *net) } mutex_unlock(&vq->mutex); - unuse_mm(net->dev.mm); } static int peek_head_len(struct sock *sk) @@ -312,7 +309,6 @@ static void handle_rx_big(struct vhost_net *net) if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) return; - use_mm(net->dev.mm); mutex_lock(&vq->mutex); vhost_disable_notify(vq); hdr_size = vq->vhost_hlen; @@ -391,7 +387,6 @@ static void handle_rx_big(struct vhost_net *net) } mutex_unlock(&vq->mutex); - unuse_mm(net->dev.mm); } /* Expects to be always run from workqueue - which acts as @@ -423,7 +418,6 @@ static void handle_rx_mergeable(struct vhost_net *net) if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) return; - use_mm(net->dev.mm); mutex_lock(&vq->mutex); vhost_disable_notify(vq); vhost_hlen = vq->vhost_hlen; @@ -500,7 +494,6 @@ static void handle_rx_mergeable(struct vhost_net *net) } mutex_unlock(&vq->mutex); - unuse_mm(net->dev.mm); } static void handle_rx(struct vhost_net *net) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 9920bae6ee43..c17c881e235a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -177,6 +178,8 @@ static int vhost_worker(void *data) struct vhost_work *work = NULL; unsigned uninitialized_var(seq); + use_mm(dev->mm); + for (;;) { /* mb paired w/ kthread_stop */ set_current_state(TASK_INTERRUPTIBLE); @@ -191,7 +194,7 @@ static int vhost_worker(void *data) if (kthread_should_stop()) { spin_unlock_irq(&dev->work_lock); __set_current_state(TASK_RUNNING); - return 0; + break; } if (!list_empty(&dev->work_list)) { work = list_first_entry(&dev->work_list, @@ -209,6 +212,8 @@ static int vhost_worker(void *data) schedule(); } + unuse_mm(dev->mm); + return 0; } /* Helper to allocate iovec buffers for all vqs. */ -- cgit v1.2.3-59-g8ed1b From dfe5ac5b18be5b10d01a17e734a9905c0def6088 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 21 Sep 2010 14:18:01 +0200 Subject: vhost: copy_to_user -> __copy_to_user We do access_ok checks at setup time, so we don't need to redo them on each access. Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c17c881e235a..e6a093187a0e 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1258,7 +1258,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, start = vq->last_used_idx % vq->num; used = vq->used->ring + start; - if (copy_to_user(used, heads, count * sizeof *used)) { + if (__copy_to_user(used, heads, count * sizeof *used)) { vq_err(vq, "Failed to write used"); return -EFAULT; } -- cgit v1.2.3-59-g8ed1b From 8b7347aab6865ae8a2e5a8b0f1deea12da3d3aff Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 19 Sep 2010 15:56:30 +0200 Subject: vhost: get/put_user -> __get/__put_user We do access_ok checks on all ring values on an ioctl, so we don't need to redo them on each access. Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e6a093187a0e..a29d91c776b4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1095,7 +1095,7 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, /* Check it isn't doing very strange things with descriptor numbers. */ last_avail_idx = vq->last_avail_idx; - if (unlikely(get_user(vq->avail_idx, &vq->avail->idx))) { + if (unlikely(__get_user(vq->avail_idx, &vq->avail->idx))) { vq_err(vq, "Failed to access avail idx at %p\n", &vq->avail->idx); return -EFAULT; @@ -1116,8 +1116,8 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, /* Grab the next descriptor number they're advertising, and increment * the index we've seen. */ - if (unlikely(get_user(head, - &vq->avail->ring[last_avail_idx % vq->num]))) { + if (unlikely(__get_user(head, + &vq->avail->ring[last_avail_idx % vq->num]))) { vq_err(vq, "Failed to read head: idx %d address %p\n", last_avail_idx, &vq->avail->ring[last_avail_idx % vq->num]); @@ -1216,17 +1216,17 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len) /* The virtqueue contains a ring of used buffers. Get a pointer to the * next entry in that used ring. */ used = &vq->used->ring[vq->last_used_idx % vq->num]; - if (put_user(head, &used->id)) { + if (__put_user(head, &used->id)) { vq_err(vq, "Failed to write used id"); return -EFAULT; } - if (put_user(len, &used->len)) { + if (__put_user(len, &used->len)) { vq_err(vq, "Failed to write used len"); return -EFAULT; } /* Make sure buffer is written before we update index. */ smp_wmb(); - if (put_user(vq->last_used_idx + 1, &vq->used->idx)) { + if (__put_user(vq->last_used_idx + 1, &vq->used->idx)) { vq_err(vq, "Failed to increment used idx"); return -EFAULT; } @@ -1319,7 +1319,7 @@ void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) * interrupts. */ smp_mb(); - if (get_user(flags, &vq->avail->flags)) { + if (__get_user(flags, &vq->avail->flags)) { vq_err(vq, "Failed to get flags"); return; } @@ -1370,7 +1370,7 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq) /* They could have slipped one in as we were doing that: make * sure it's written, then check again. */ smp_mb(); - r = get_user(avail_idx, &vq->avail->idx); + r = __get_user(avail_idx, &vq->avail->idx); if (r) { vq_err(vq, "Failed to check avail idx at %p: %d\n", &vq->avail->idx, r); -- cgit v1.2.3-59-g8ed1b From 1d5439b9a29b1386d44a617cbaf2f7acde1d697c Mon Sep 17 00:00:00 2001 From: "Arce, Abraham" Date: Thu, 28 Oct 2010 18:57:20 +0000 Subject: ks8851: suspend resume support Add suspend/resume support using default open/stop interface methods to do hardware dependant operations. On suspend, same low power state (soft power mode) will be kept, the following blocks will be disabled: - Internal PLL Clock - Tx/Rx PHY - MAC - SPI Interface Signed-off-by: Abraham Arce Signed-off-by: David S. Miller --- drivers/net/ks8851.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 51919fcd50c2..0fa4a9887ba2 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -1545,6 +1545,37 @@ static int ks8851_read_selftest(struct ks8851_net *ks) /* driver bus management functions */ +#ifdef CONFIG_PM +static int ks8851_suspend(struct spi_device *spi, pm_message_t state) +{ + struct ks8851_net *ks = dev_get_drvdata(&spi->dev); + struct net_device *dev = ks->netdev; + + if (netif_running(dev)) { + netif_device_detach(dev); + ks8851_net_stop(dev); + } + + return 0; +} + +static int ks8851_resume(struct spi_device *spi) +{ + struct ks8851_net *ks = dev_get_drvdata(&spi->dev); + struct net_device *dev = ks->netdev; + + if (netif_running(dev)) { + ks8851_net_open(dev); + netif_device_attach(dev); + } + + return 0; +} +#else +#define ks8851_suspend NULL +#define ks8851_resume NULL +#endif + static int __devinit ks8851_probe(struct spi_device *spi) { struct net_device *ndev; @@ -1679,6 +1710,8 @@ static struct spi_driver ks8851_driver = { }, .probe = ks8851_probe, .remove = __devexit_p(ks8851_remove), + .suspend = ks8851_suspend, + .resume = ks8851_resume, }; static int __init ks8851_init(void) -- cgit v1.2.3-59-g8ed1b From 840a185dddfd098b78b96a30da4cad722a7aef18 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Oct 2010 01:15:29 +0000 Subject: aoe: remove dev_base_lock use from aoecmd_cfg_pkts() dev_base_lock is the legacy way to lock the device list, and is planned to disappear. (writers hold RTNL, readers hold RCU lock) Convert aoecmd_cfg_pkts() to RCU locking. Signed-off-by: Eric Dumazet Cc: "Ed L. Cashin" Signed-off-by: David S. Miller --- drivers/block/aoe/aoecmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 5674bd01d96d..de0435e63b02 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -297,8 +297,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu struct sk_buff *skb; struct net_device *ifp; - read_lock(&dev_base_lock); - for_each_netdev(&init_net, ifp) { + rcu_read_lock(); + for_each_netdev_rcu(&init_net, ifp) { dev_hold(ifp); if (!is_aoe_netif(ifp)) goto cont; @@ -325,7 +325,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu cont: dev_put(ifp); } - read_unlock(&dev_base_lock); + rcu_read_unlock(); } static void -- cgit v1.2.3-59-g8ed1b From e4a7b93bd5d84e1e79917d024d17d745d190fc9a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Oct 2010 01:52:46 +0000 Subject: bonding: remove dev_base_lock use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bond_info_seq_start() uses a read_lock(&dev_base_lock) to make sure device doesn’t disappear. Same goal can be achieved using RCU. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bdb68a600382..518844852f06 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3209,7 +3209,7 @@ out: #ifdef CONFIG_PROC_FS static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(&dev_base_lock) + __acquires(RCU) __acquires(&bond->lock) { struct bonding *bond = seq->private; @@ -3218,7 +3218,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) int i; /* make sure the bond won't be taken away */ - read_lock(&dev_base_lock); + rcu_read_lock(); read_lock(&bond->lock); if (*pos == 0) @@ -3248,12 +3248,12 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void bond_info_seq_stop(struct seq_file *seq, void *v) __releases(&bond->lock) - __releases(&dev_base_lock) + __releases(RCU) { struct bonding *bond = seq->private; read_unlock(&bond->lock); - read_unlock(&dev_base_lock); + rcu_read_unlock(); } static void bond_info_show_master(struct seq_file *seq) -- cgit v1.2.3-59-g8ed1b From fc766e4c4965915ab52a1d1fa3c7a7b3e7bc07f0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Oct 2010 03:09:24 +0000 Subject: decnet: RCU conversion and get rid of dev_base_lock While tracking dev_base_lock users, I found decnet used it in dnet_select_source(), but for a wrong purpose: Writers only hold RTNL, not dev_base_lock, so readers must use RCU if they cannot use RTNL. Adds an rcu_head in struct dn_ifaddr and handle proper RCU management. Adds __rcu annotation in dn_route as well. Signed-off-by: Eric Dumazet Acked-by: Steven Whitehouse Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- include/net/dn_dev.h | 27 ++++++++----- include/net/dst.h | 8 ++-- net/decnet/af_decnet.c | 2 +- net/decnet/dn_dev.c | 100 +++++++++++++++++++++++++++------------------- net/decnet/dn_fib.c | 6 ++- net/decnet/dn_neigh.c | 2 +- net/decnet/dn_route.c | 68 +++++++++++++++++-------------- 8 files changed, 127 insertions(+), 88 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d8fd2c23a1b9..578debb801f4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -951,7 +951,7 @@ struct net_device { #endif void *atalk_ptr; /* AppleTalk link */ struct in_device __rcu *ip_ptr; /* IPv4 specific data */ - void *dn_ptr; /* DECnet specific data */ + struct dn_dev __rcu *dn_ptr; /* DECnet specific data */ struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */ void *ec_ptr; /* Econet specific data */ void *ax25_ptr; /* AX.25 specific data */ diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h index 0916bbf3bdff..b9e32db03f20 100644 --- a/include/net/dn_dev.h +++ b/include/net/dn_dev.h @@ -5,13 +5,14 @@ struct dn_dev; struct dn_ifaddr { - struct dn_ifaddr *ifa_next; + struct dn_ifaddr __rcu *ifa_next; struct dn_dev *ifa_dev; __le16 ifa_local; __le16 ifa_address; __u8 ifa_flags; __u8 ifa_scope; char ifa_label[IFNAMSIZ]; + struct rcu_head rcu; }; #define DN_DEV_S_RU 0 /* Run - working normally */ @@ -83,7 +84,7 @@ struct dn_dev_parms { struct dn_dev { - struct dn_ifaddr *ifa_list; + struct dn_ifaddr __rcu *ifa_list; struct net_device *dev; struct dn_dev_parms parms; char use_long; @@ -171,19 +172,27 @@ extern int unregister_dnaddr_notifier(struct notifier_block *nb); static inline int dn_dev_islocal(struct net_device *dev, __le16 addr) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db; struct dn_ifaddr *ifa; + int res = 0; + rcu_read_lock(); + dn_db = rcu_dereference(dev->dn_ptr); if (dn_db == NULL) { printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n"); - return 0; + goto out; } - for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) - if ((addr ^ ifa->ifa_local) == 0) - return 1; - - return 0; + for (ifa = rcu_dereference(dn_db->ifa_list); + ifa != NULL; + ifa = rcu_dereference(ifa->ifa_next)) + if ((addr ^ ifa->ifa_local) == 0) { + res = 1; + break; + } +out: + rcu_read_unlock(); + return res; } #endif /* _NET_DN_DEV_H */ diff --git a/include/net/dst.h b/include/net/dst.h index ffe9cb719c0e..a5bd72646d65 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -94,10 +94,10 @@ struct dst_entry { int __use; unsigned long lastuse; union { - struct dst_entry *next; - struct rtable __rcu *rt_next; - struct rt6_info *rt6_next; - struct dn_route *dn_next; + struct dst_entry *next; + struct rtable __rcu *rt_next; + struct rt6_info *rt6_next; + struct dn_route __rcu *dn_next; }; }; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index d6b93d19790f..18b8a2cbdf77 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -1848,7 +1848,7 @@ unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu) { unsigned mss = 230 - DN_MAX_NSP_DATA_HEADER; if (dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); mtu -= LL_RESERVED_SPACE(dev); if (dn_db->use_long) mtu -= 21; diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 4c409b46aa35..0ba15633c418 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -267,7 +267,7 @@ static int dn_forwarding_proc(ctl_table *table, int write, if (table->extra1 == NULL) return -EINVAL; - dn_db = dev->dn_ptr; + dn_db = rcu_dereference_raw(dev->dn_ptr); old = dn_db->parms.forwarding; err = proc_dointvec(table, write, buffer, lenp, ppos); @@ -332,14 +332,19 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void) return ifa; } -static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) +static void dn_dev_free_ifa_rcu(struct rcu_head *head) { - kfree(ifa); + kfree(container_of(head, struct dn_ifaddr, rcu)); } -static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) +static void dn_dev_free_ifa(struct dn_ifaddr *ifa) { - struct dn_ifaddr *ifa1 = *ifap; + call_rcu(&ifa->rcu, dn_dev_free_ifa_rcu); +} + +static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy) +{ + struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap); unsigned char mac_addr[6]; struct net_device *dev = dn_db->dev; @@ -373,7 +378,9 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) ASSERT_RTNL(); /* Check for duplicates */ - for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { + for (ifa1 = rtnl_dereference(dn_db->ifa_list); + ifa1 != NULL; + ifa1 = rtnl_dereference(ifa1->ifa_next)) { if (ifa1->ifa_local == ifa->ifa_local) return -EEXIST; } @@ -386,7 +393,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) } ifa->ifa_next = dn_db->ifa_list; - dn_db->ifa_list = ifa; + rcu_assign_pointer(dn_db->ifa_list, ifa); dn_ifaddr_notify(RTM_NEWADDR, ifa); blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); @@ -396,7 +403,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); int rv; if (dn_db == NULL) { @@ -425,7 +432,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; struct dn_dev *dn_db; struct net_device *dev; - struct dn_ifaddr *ifa = NULL, **ifap = NULL; + struct dn_ifaddr *ifa = NULL; + struct dn_ifaddr __rcu **ifap = NULL; int ret = 0; if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) @@ -454,8 +462,10 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) goto done; } - if ((dn_db = dev->dn_ptr) != NULL) { - for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) + if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) { + for (ifap = &dn_db->ifa_list; + (ifa = rtnl_dereference(*ifap)) != NULL; + ifap = &ifa->ifa_next) if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) break; } @@ -558,7 +568,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) dev = __dev_get_by_index(&init_net, ifindex); if (dev) - dn_dev = dev->dn_ptr; + dn_dev = rtnl_dereference(dev->dn_ptr); return dn_dev; } @@ -576,7 +586,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct nlattr *tb[IFA_MAX+1]; struct dn_dev *dn_db; struct ifaddrmsg *ifm; - struct dn_ifaddr *ifa, **ifap; + struct dn_ifaddr *ifa; + struct dn_ifaddr __rcu **ifap; int err = -EINVAL; if (!net_eq(net, &init_net)) @@ -592,7 +603,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) goto errout; err = -EADDRNOTAVAIL; - for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { + for (ifap = &dn_db->ifa_list; + (ifa = rtnl_dereference(*ifap)) != NULL; + ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) continue; @@ -632,7 +645,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) return -ENODEV; - if ((dn_db = dev->dn_ptr) == NULL) { + if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) { dn_db = dn_dev_create(dev, &err); if (!dn_db) return err; @@ -748,11 +761,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_naddr = 0; } - if ((dn_db = dev->dn_ptr) == NULL) + if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) goto cont; - for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; - ifa = ifa->ifa_next, dn_idx++) { + for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa; + ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) { if (dn_idx < skip_naddr) continue; @@ -773,21 +786,22 @@ done: static int dn_dev_get_first(struct net_device *dev, __le16 *addr) { - struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; + struct dn_dev *dn_db; struct dn_ifaddr *ifa; int rv = -ENODEV; + rcu_read_lock(); + dn_db = rcu_dereference(dev->dn_ptr); if (dn_db == NULL) goto out; - rtnl_lock(); - ifa = dn_db->ifa_list; + ifa = rcu_dereference(dn_db->ifa_list); if (ifa != NULL) { *addr = ifa->ifa_local; rv = 0; } - rtnl_unlock(); out: + rcu_read_unlock(); return rv; } @@ -823,7 +837,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa) struct endnode_hello_message *msg; struct sk_buff *skb = NULL; __le16 *pktlen; - struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) return; @@ -889,7 +903,7 @@ static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) { int n; - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; struct sk_buff *skb; size_t size; @@ -960,7 +974,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) { - struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); if (dn_db->parms.forwarding == 0) dn_send_endnode_hello(dev, ifa); @@ -998,7 +1012,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) static int dn_eth_up(struct net_device *dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); if (dn_db->parms.forwarding == 0) dev_mc_add(dev, dn_rt_all_end_mcast); @@ -1012,7 +1026,7 @@ static int dn_eth_up(struct net_device *dev) static void dn_eth_down(struct net_device *dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); if (dn_db->parms.forwarding == 0) dev_mc_del(dev, dn_rt_all_end_mcast); @@ -1025,12 +1039,16 @@ static void dn_dev_set_timer(struct net_device *dev); static void dn_dev_timer_func(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db; struct dn_ifaddr *ifa; + rcu_read_lock(); + dn_db = rcu_dereference(dev->dn_ptr); if (dn_db->t3 <= dn_db->parms.t2) { if (dn_db->parms.timer3) { - for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { + for (ifa = rcu_dereference(dn_db->ifa_list); + ifa; + ifa = rcu_dereference(ifa->ifa_next)) { if (!(ifa->ifa_flags & IFA_F_SECONDARY)) dn_db->parms.timer3(dev, ifa); } @@ -1039,13 +1057,13 @@ static void dn_dev_timer_func(unsigned long arg) } else { dn_db->t3 -= dn_db->parms.t2; } - + rcu_read_unlock(); dn_dev_set_timer(dev); } static void dn_dev_set_timer(struct net_device *dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); if (dn_db->parms.t2 > dn_db->parms.t3) dn_db->parms.t2 = dn_db->parms.t3; @@ -1077,8 +1095,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) return NULL; memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); - smp_wmb(); - dev->dn_ptr = dn_db; + + rcu_assign_pointer(dev->dn_ptr, dn_db); dn_db->dev = dev; init_timer(&dn_db->timer); @@ -1086,7 +1104,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); if (!dn_db->neigh_parms) { - dev->dn_ptr = NULL; + rcu_assign_pointer(dev->dn_ptr, NULL); kfree(dn_db); return NULL; } @@ -1125,7 +1143,7 @@ void dn_dev_up(struct net_device *dev) struct dn_ifaddr *ifa; __le16 addr = decnet_address; int maybe_default = 0; - struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; + struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) return; @@ -1176,7 +1194,7 @@ void dn_dev_up(struct net_device *dev) static void dn_dev_delete(struct net_device *dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); if (dn_db == NULL) return; @@ -1204,13 +1222,13 @@ static void dn_dev_delete(struct net_device *dev) void dn_dev_down(struct net_device *dev) { - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); struct dn_ifaddr *ifa; if (dn_db == NULL) return; - while((ifa = dn_db->ifa_list) != NULL) { + while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) { dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); dn_dev_free_ifa(ifa); } @@ -1270,7 +1288,7 @@ static inline int is_dn_dev(struct net_device *dev) } static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(rcu) + __acquires(RCU) { int i; struct net_device *dev; @@ -1313,7 +1331,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void dn_dev_seq_stop(struct seq_file *seq, void *v) - __releases(rcu) + __releases(RCU) { rcu_read_unlock(); } @@ -1340,7 +1358,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v) struct net_device *dev = v; char peer_buf[DN_ASCBUF_LEN]; char router_buf[DN_ASCBUF_LEN]; - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr); seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" " %04hu %03d %02x %-10s %-7s %-7s\n", diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 4ab96c15166d..0ef0a81bcd72 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -610,10 +610,12 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa) /* Scan device list */ rcu_read_lock(); for_each_netdev_rcu(&init_net, dev) { - dn_db = dev->dn_ptr; + dn_db = rcu_dereference(dev->dn_ptr); if (dn_db == NULL) continue; - for(ifa2 = dn_db->ifa_list; ifa2; ifa2 = ifa2->ifa_next) { + for (ifa2 = rcu_dereference(dn_db->ifa_list); + ifa2 != NULL; + ifa2 = rcu_dereference(ifa2->ifa_next)) { if (ifa2->ifa_local == ifa->ifa_local) { found_it = 1; break; diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index a085dbcf5c7f..602dade7e9a3 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -391,7 +391,7 @@ int dn_neigh_router_hello(struct sk_buff *skb) write_lock(&neigh->lock); neigh->used = jiffies; - dn_db = (struct dn_dev *)neigh->dev->dn_ptr; + dn_db = rcu_dereference(neigh->dev->dn_ptr); if (!(neigh->nud_state & NUD_PERMANENT)) { neigh->updated = jiffies; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index df0f3e54ff8a..94a9eb1d313e 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -93,7 +93,7 @@ struct dn_rt_hash_bucket { - struct dn_route *chain; + struct dn_route __rcu *chain; spinlock_t lock; }; @@ -157,15 +157,17 @@ static inline void dnrt_drop(struct dn_route *rt) static void dn_dst_check_expire(unsigned long dummy) { int i; - struct dn_route *rt, **rtp; + struct dn_route *rt; + struct dn_route __rcu **rtp; unsigned long now = jiffies; unsigned long expire = 120 * HZ; - for(i = 0; i <= dn_rt_hash_mask; i++) { + for (i = 0; i <= dn_rt_hash_mask; i++) { rtp = &dn_rt_hash_table[i].chain; spin_lock(&dn_rt_hash_table[i].lock); - while((rt=*rtp) != NULL) { + while ((rt = rcu_dereference_protected(*rtp, + lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) { if (atomic_read(&rt->dst.__refcnt) || (now - rt->dst.lastuse) < expire) { rtp = &rt->dst.dn_next; @@ -186,17 +188,19 @@ static void dn_dst_check_expire(unsigned long dummy) static int dn_dst_gc(struct dst_ops *ops) { - struct dn_route *rt, **rtp; + struct dn_route *rt; + struct dn_route __rcu **rtp; int i; unsigned long now = jiffies; unsigned long expire = 10 * HZ; - for(i = 0; i <= dn_rt_hash_mask; i++) { + for (i = 0; i <= dn_rt_hash_mask; i++) { spin_lock_bh(&dn_rt_hash_table[i].lock); rtp = &dn_rt_hash_table[i].chain; - while((rt=*rtp) != NULL) { + while ((rt = rcu_dereference_protected(*rtp, + lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) { if (atomic_read(&rt->dst.__refcnt) || (now - rt->dst.lastuse) < expire) { rtp = &rt->dst.dn_next; @@ -227,7 +231,7 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) { u32 min_mtu = 230; struct dn_dev *dn = dst->neighbour ? - (struct dn_dev *)dst->neighbour->dev->dn_ptr : NULL; + rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL; if (dn && dn->use_long == 0) min_mtu -= 6; @@ -277,13 +281,15 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) { - struct dn_route *rth, **rthp; + struct dn_route *rth; + struct dn_route __rcu **rthp; unsigned long now = jiffies; rthp = &dn_rt_hash_table[hash].chain; spin_lock_bh(&dn_rt_hash_table[hash].lock); - while((rth = *rthp) != NULL) { + while ((rth = rcu_dereference_protected(*rthp, + lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) { if (compare_keys(&rth->fl, &rt->fl)) { /* Put it first */ *rthp = rth->dst.dn_next; @@ -315,15 +321,15 @@ static void dn_run_flush(unsigned long dummy) int i; struct dn_route *rt, *next; - for(i = 0; i < dn_rt_hash_mask; i++) { + for (i = 0; i < dn_rt_hash_mask; i++) { spin_lock_bh(&dn_rt_hash_table[i].lock); - if ((rt = xchg(&dn_rt_hash_table[i].chain, NULL)) == NULL) + if ((rt = xchg((struct dn_route **)&dn_rt_hash_table[i].chain, NULL)) == NULL) goto nothing_to_declare; - for(; rt; rt=next) { - next = rt->dst.dn_next; - rt->dst.dn_next = NULL; + for(; rt; rt = next) { + next = rcu_dereference_raw(rt->dst.dn_next); + RCU_INIT_POINTER(rt->dst.dn_next, NULL); dst_free((struct dst_entry *)rt); } @@ -458,15 +464,16 @@ static int dn_return_long(struct sk_buff *skb) */ static int dn_route_rx_packet(struct sk_buff *skb) { - struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct dn_skb_cb *cb; int err; if ((err = dn_route_input(skb)) == 0) return dst_input(skb); + cb = DN_SKB_CB(skb); if (decnet_debug_level & 4) { char *devname = skb->dev ? skb->dev->name : "???"; - struct dn_skb_cb *cb = DN_SKB_CB(skb); + printk(KERN_DEBUG "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n", (int)cb->rt_flags, devname, skb->len, @@ -573,7 +580,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type struct dn_skb_cb *cb; unsigned char flags = 0; __u16 len = le16_to_cpu(*(__le16 *)skb->data); - struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr; + struct dn_dev *dn = rcu_dereference(dev->dn_ptr); unsigned char padlen = 0; if (!net_eq(dev_net(dev), &init_net)) @@ -728,7 +735,7 @@ static int dn_forward(struct sk_buff *skb) { struct dn_skb_cb *cb = DN_SKB_CB(skb); struct dst_entry *dst = skb_dst(skb); - struct dn_dev *dn_db = dst->dev->dn_ptr; + struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr); struct dn_route *rt; struct neighbour *neigh = dst->neighbour; int header_len; @@ -835,13 +842,16 @@ static inline int dn_match_addr(__le16 addr1, __le16 addr2) static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope) { __le16 saddr = 0; - struct dn_dev *dn_db = dev->dn_ptr; + struct dn_dev *dn_db; struct dn_ifaddr *ifa; int best_match = 0; int ret; - read_lock(&dev_base_lock); - for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { + rcu_read_lock(); + dn_db = rcu_dereference(dev->dn_ptr); + for (ifa = rcu_dereference(dn_db->ifa_list); + ifa != NULL; + ifa = rcu_dereference(ifa->ifa_next)) { if (ifa->ifa_scope > scope) continue; if (!daddr) { @@ -854,7 +864,7 @@ static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int if (best_match == 0) saddr = ifa->ifa_local; } - read_unlock(&dev_base_lock); + rcu_read_unlock(); return saddr; } @@ -1020,7 +1030,7 @@ source_ok: err = -ENODEV; if (dev_out == NULL) goto out; - dn_db = dev_out->dn_ptr; + dn_db = rcu_dereference_raw(dev_out->dn_ptr); /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fl.fld_dst)) { dev_put(dev_out); @@ -1233,7 +1243,7 @@ static int dn_route_input_slow(struct sk_buff *skb) dev_hold(in_dev); - if ((dn_db = in_dev->dn_ptr) == NULL) + if ((dn_db = rcu_dereference(in_dev->dn_ptr)) == NULL) goto out; /* Zero source addresses are not allowed */ @@ -1677,15 +1687,15 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou { struct dn_rt_cache_iter_state *s = seq->private; - rt = rt->dst.dn_next; - while(!rt) { + rt = rcu_dereference_bh(rt->dst.dn_next); + while (!rt) { rcu_read_unlock_bh(); if (--s->bucket < 0) break; rcu_read_lock_bh(); - rt = dn_rt_hash_table[s->bucket].chain; + rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain); } - return rcu_dereference_bh(rt); + return rt; } static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos) -- cgit v1.2.3-59-g8ed1b From 67426b756c4d52c511c4b22b269accea171692a8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Oct 2010 20:44:44 +0000 Subject: af_unix: use keyed wakeups Instead of wakeup all sleepers, use wake_up_interruptible_sync_poll() to wakeup only ones interested into writing the socket. This patch is a specialization of commit 37e5540b3c9d (epoll keyed wakeups: make sockets use keyed wakeups). On a test program provided by Alan Crequy : Before: real 0m3.101s user 0m0.000s sys 0m6.104s After: real 0m0.211s user 0m0.000s sys 0m0.208s Reported-by: Alban Crequy Signed-off-by: Eric Dumazet Cc: Davide Libenzi Signed-off-by: David S. Miller --- net/unix/af_unix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3c95304a0817..f33c5958dbb2 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -316,7 +316,8 @@ static void unix_write_space(struct sock *sk) if (unix_writable(sk)) { wq = rcu_dereference(sk->sk_wq); if (wq_has_sleeper(wq)) - wake_up_interruptible_sync(&wq->wait); + wake_up_interruptible_sync_poll(&wq->wait, + POLLOUT | POLLWRNORM | POLLWRBAND); sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); } rcu_read_unlock(); @@ -1710,7 +1711,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, goto out_unlock; } - wake_up_interruptible_sync(&u->peer_wait); + wake_up_interruptible_sync_poll(&u->peer_wait, + POLLOUT | POLLWRNORM | POLLWRBAND); if (msg->msg_name) unix_copy_addr(msg, skb->sk); -- cgit v1.2.3-59-g8ed1b From 5456f09aaf88731e16dbcea7522cb330b6846415 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 31 Oct 2010 05:36:23 +0000 Subject: af_unix: fix unix_dgram_poll() behavior for EPOLLOUT event Alban Crequy reported a problem with connected dgram af_unix sockets and provided a test program. epoll() would miss to send an EPOLLOUT event when a thread unqueues a packet from the other peer, making its receive queue not full. This is because unix_dgram_poll() fails to call sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); if the socket is not writeable at the time epoll_ctl(ADD) is called. We must call sock_poll_wait(), regardless of 'writable' status, so that epoll can be notified later of states changes. Misc: avoids testing twice (sk->sk_shutdown & RCV_SHUTDOWN) Reported-by: Alban Crequy Cc: Davide Libenzi Signed-off-by: Eric Dumazet Acked-by: Davide Libenzi Signed-off-by: David S. Miller --- net/unix/af_unix.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f33c5958dbb2..e8898758dd31 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2074,13 +2074,12 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ @@ -2092,20 +2091,15 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, return mask; } - /* writable? */ writable = unix_writable(sk); - if (writable) { - other = unix_peer_get(sk); - if (other) { - if (unix_peer(other) != sk) { - sock_poll_wait(file, &unix_sk(other)->peer_wait, - wait); - if (unix_recvq_full(other)) - writable = 0; - } - - sock_put(other); + other = unix_peer_get(sk); + if (other) { + if (unix_peer(other) != sk) { + sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); + if (unix_recvq_full(other)) + writable = 0; } + sock_put(other); } if (writable) -- cgit v1.2.3-59-g8ed1b From 973a34aa8593dbfe84386343c694f5beecb51d8a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 31 Oct 2010 05:38:25 +0000 Subject: af_unix: optimize unix_dgram_poll() unix_dgram_poll() is pretty expensive to check POLLOUT status, because it has to lock the socket to get its peer, take a reference on the peer to check its receive queue status, and queue another poll_wait on peer_wait. This all can be avoided if the process calling unix_dgram_poll() is not interested in POLLOUT status. It makes unix_dgram_recvmsg() faster by not queueing irrelevant pollers in peer_wait. On a test program provided by Alan Crequy : Before: real 0m0.211s user 0m0.000s sys 0m0.208s After: real 0m0.044s user 0m0.000s sys 0m0.040s Suggested-by: Davide Libenzi Reported-by: Alban Crequy Acked-by: Davide Libenzi Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/unix/af_unix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e8898758dd31..7ff31c60186a 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2091,6 +2091,10 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, return mask; } + /* No write status requested, avoid expensive OUT tests. */ + if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT))) + return mask; + writable = unix_writable(sk); other = unix_peer_get(sk); if (other) { -- cgit v1.2.3-59-g8ed1b From c63fdf46ad0a7f8fe3c0252a0e763515617e0ea7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 3 Nov 2010 22:49:35 +0000 Subject: drivers/net: normalize TX_TIMEOUT Some network drivers use old TX_TIMEOUT definitions, assuming HZ=100 of old kernels. Convert these definitions to include HZ, since HZ can be 1000 these days. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/3c507.c | 2 +- drivers/net/3c515.c | 2 +- drivers/net/82596.c | 2 +- drivers/net/arm/w90p910_ether.c | 2 +- drivers/net/at1700.c | 2 +- drivers/net/atarilance.c | 2 +- drivers/net/eepro.c | 2 +- drivers/net/lance.c | 2 +- drivers/net/lib82596.c | 2 +- drivers/net/znet.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index ea9b7a098c9b..475a66d95b34 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -201,7 +201,7 @@ struct net_local { #define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */ #define RX_BUF_END (dev->mem_end - dev->mem_start) -#define TX_TIMEOUT 5 +#define TX_TIMEOUT (HZ/20) /* That's it: only 86 bytes to set up the beast, including every extra diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index cdf7226a7c43..d2bb4b254c57 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -98,7 +98,7 @@ static int rx_nocopy, rx_copy, queued_packet; #define WAIT_TX_AVAIL 200 /* Operational parameter that usually are not changed. */ -#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */ +#define TX_TIMEOUT ((4*HZ)/10) /* Time in jiffies before concluding Tx hung */ /* The size here is somewhat misleading: the Corkscrew also uses the ISA aliased registers at +0x400. diff --git a/drivers/net/82596.c b/drivers/net/82596.c index e2c9c5b949f9..be1f1970c842 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -191,7 +191,7 @@ enum commands { #define RX_SUSPEND 0x0030 #define RX_ABORT 0x0040 -#define TX_TIMEOUT 5 +#define TX_TIMEOUT (HZ/20) struct i596_reg { diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index 4545d5a06c24..bfea499a3513 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c @@ -117,7 +117,7 @@ #define TX_DESC_SIZE 10 #define MAX_RBUFF_SZ 0x600 #define MAX_TBUFF_SZ 0x600 -#define TX_TIMEOUT 50 +#define TX_TIMEOUT (HZ/2) #define DELAY 1000 #define CAM0 0x0 diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 89876897a6fe..871b1633f543 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -150,7 +150,7 @@ struct net_local { #define PORT_OFFSET(o) (o) -#define TX_TIMEOUT 10 +#define TX_TIMEOUT (HZ/10) /* Index to functions, as function prototypes. */ diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 8cb27cb7bca1..ce0091eb06f5 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -116,7 +116,7 @@ MODULE_LICENSE("GPL"); #define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5) #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) -#define TX_TIMEOUT 20 +#define TX_TIMEOUT (HZ/5) /* The LANCE Rx and Tx ring descriptors. */ struct lance_rx_head { diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 7c826319ee5a..9e19fbc2f176 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -302,7 +302,7 @@ struct eepro_local { #define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */ #define ee_id_eepro10p1 0x31 -#define TX_TIMEOUT 40 +#define TX_TIMEOUT ((4*HZ)/10) /* Index to functions, as function prototypes. */ diff --git a/drivers/net/lance.c b/drivers/net/lance.c index f06296bfe293..02336edce748 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -207,7 +207,7 @@ tx_full and tbusy flags. #define LANCE_BUS_IF 0x16 #define LANCE_TOTAL_SIZE 0x18 -#define TX_TIMEOUT 20 +#define TX_TIMEOUT (HZ/5) /* The LANCE Rx and Tx ring descriptors. */ struct lance_rx_head { diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index c27f4291b350..9e042894479b 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -161,7 +161,7 @@ enum commands { #define RX_SUSPEND 0x0030 #define RX_ABORT 0x0040 -#define TX_TIMEOUT 5 +#define TX_TIMEOUT (HZ/20) struct i596_reg { diff --git a/drivers/net/znet.c b/drivers/net/znet.c index c3a329204511..ae07b3dfbcc1 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -124,7 +124,7 @@ MODULE_LICENSE("GPL"); #define TX_BUF_SIZE 8192 #define DMA_BUF_SIZE (RX_BUF_SIZE + 16) /* 8k + 16 bytes for trailers */ -#define TX_TIMEOUT 10 +#define TX_TIMEOUT (HZ/10) struct znet_private { int rx_dma, tx_dma; -- cgit v1.2.3-59-g8ed1b From c389ff80d4b598f57d56aa807d396d4351cac8a4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 11:08:33 +0000 Subject: drivers/net/can: Update WARN uses Add missing newlines. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/can/mscan/mscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 64c378cd0c34..74cd880c7e06 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -182,7 +182,7 @@ static int mscan_restart(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; WARN(!(in_8(®s->canmisc) & MSCAN_BOHOLD), - "bus-off state expected"); + "bus-off state expected\n"); out_8(®s->canmisc, MSCAN_BOHOLD); /* Re-enable receive interrupts. */ out_8(®s->canrier, MSCAN_RX_INTS_ENABLE); -- cgit v1.2.3-59-g8ed1b From 9c413ed55d5b52159e85a3937cda7f210a318048 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 11:08:34 +0000 Subject: drivers/net/usb: Update WARN uses Add missing newlines. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/usb/ipheth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index b2bcf99e6f08..7d42f9a2c068 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -363,7 +363,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) /* Paranoid */ if (skb->len > IPHETH_BUF_SIZE) { - WARN(1, "%s: skb too large: %d bytes", __func__, skb->len); + WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); dev->net->stats.tx_dropped++; dev_kfree_skb_irq(skb); return NETDEV_TX_OK; -- cgit v1.2.3-59-g8ed1b From b194a3674fba6d9f9e470084d192c7cb99194a62 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 11:08:52 +0000 Subject: net/core/dev.c: Update WARN uses Coalesce long formats. Add missing newlines. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/core/dev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 0dd54a69dace..5968c822c999 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1817,8 +1817,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) dev->ethtool_ops->get_drvinfo(dev, &info); - WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d " - "ip_summed=%d", + WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n", info.driver, dev ? dev->features : 0L, skb->sk ? skb->sk->sk_route_caps : 0L, skb->len, skb->data_len, skb->ip_summed); -- cgit v1.2.3-59-g8ed1b From 2af6fd8b18ceed416c9dfa675287c765aabf7d43 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 11:08:53 +0000 Subject: net/ipv4/tcp.c: Update WARN uses Coalesce long formats. Align arguments. Remove KERN_. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1664a0590bb8..5f738c5c0dc4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1193,7 +1193,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq), - KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", + "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt); #endif @@ -1477,10 +1477,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, * shouldn't happen. */ if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), - KERN_INFO "recvmsg bug: copied %X " - "seq %X rcvnxt %X fl %X\n", *seq, - TCP_SKB_CB(skb)->seq, tp->rcv_nxt, - flags)) + "recvmsg bug: copied %X seq %X rcvnxt %X fl %X\n", + *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, + flags)) break; offset = *seq - TCP_SKB_CB(skb)->seq; @@ -1490,10 +1489,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto found_ok_skb; if (tcp_hdr(skb)->fin) goto found_fin_ok; - WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " - "copied %X seq %X rcvnxt %X fl %X\n", - *seq, TCP_SKB_CB(skb)->seq, - tp->rcv_nxt, flags); + WARN(!(flags & MSG_PEEK), + "recvmsg bug 2: copied %X seq %X rcvnxt %X fl %X\n", + *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, flags); } /* Well, if we have backlog, try to process it now yet. */ -- cgit v1.2.3-59-g8ed1b From 038aaa382eb0a8fd6a0bbae7abc1383b9b57c543 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 14 Oct 2010 23:01:02 +0200 Subject: b43: N-PHY: define channel table struct for rev3+ devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.c | 51 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2056.h | 40 ++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index d8563192ce56..f710c01f2cc4 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -24,9 +24,60 @@ #include "radio_2056.h" #include "phy_common.h" +#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ + r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ + r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ + r30, r31, r32, r33, r34, r35, r36) \ + .radio_syn_pll_vcocal1 = r00, \ + .radio_syn_pll_vcocal2 = r01, \ + .radio_syn_pll_refdiv = r02, \ + .radio_syn_pll_mmd2 = r03, \ + .radio_syn_pll_mmd1 = r04, \ + .radio_syn_pll_loopfilter1 = r05, \ + .radio_syn_pll_loopfilter2 = r06, \ + .radio_syn_pll_loopfilter3 = r07, \ + .radio_syn_pll_loopfilter4 = r08, \ + .radio_syn_pll_loopfilter5 = r09, \ + .radio_syn_reserved_addr27 = r10, \ + .radio_syn_reserved_addr28 = r11, \ + .radio_syn_reserved_addr29 = r12, \ + .radio_syn_logen_vcobuf1 = r13, \ + .radio_syn_logen_mixer2 = r14, \ + .radio_syn_logen_buf3 = r15, \ + .radio_syn_logen_buf4 = r16, \ + .radio_rx0_lnaa_tune = r17, \ + .radio_rx0_lnag_tune = r18, \ + .radio_tx0_intpaa_boost_tune = r19, \ + .radio_tx0_intpag_boost_tune = r20, \ + .radio_tx0_pada_boost_tune = r21, \ + .radio_tx0_padg_boost_tune = r22, \ + .radio_tx0_pgaa_boost_tune = r23, \ + .radio_tx0_pgag_boost_tune = r24, \ + .radio_tx0_mixa_boost_tune = r25, \ + .radio_tx0_mixg_boost_tune = r26, \ + .radio_rx1_lnaa_tune = r27, \ + .radio_rx1_lnag_tune = r28, \ + .radio_tx1_intpaa_boost_tune = r29, \ + .radio_tx1_intpag_boost_tune = r30, \ + .radio_tx1_pada_boost_tune = r31, \ + .radio_tx1_padg_boost_tune = r32, \ + .radio_tx1_pgaa_boost_tune = r33, \ + .radio_tx1_pgag_boost_tune = r34, \ + .radio_tx1_mixa_boost_tune = r35, \ + .radio_tx1_mixg_boost_tune = r36 + +#define PHYREGS(r0, r1, r2, r3, r4, r5) \ + .phy_regs.phy_bw1a = r0, \ + .phy_regs.phy_bw2 = r1, \ + .phy_regs.phy_bw3 = r2, \ + .phy_regs.phy_bw4 = r3, \ + .phy_regs.phy_bw5 = r4, \ + .phy_regs.phy_bw6 = r5 + static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { }; +/* TODO: add support for rev4+ devices by searching in rev4+ tables */ const struct b43_nphy_channeltab_entry_rev3 * b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) { diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index fda6dafecb8c..60341d7ae673 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -29,12 +29,46 @@ #include "tables_nphy.h" struct b43_nphy_channeltab_entry_rev3 { - /* The channel number */ - u8 channel; /* The channel frequency in MHz */ u16 freq; /* Radio register values on channelswitch */ - /* TODO */ + u8 radio_syn_pll_vcocal1; + u8 radio_syn_pll_vcocal2; + u8 radio_syn_pll_refdiv; + u8 radio_syn_pll_mmd2; + u8 radio_syn_pll_mmd1; + u8 radio_syn_pll_loopfilter1; + u8 radio_syn_pll_loopfilter2; + u8 radio_syn_pll_loopfilter3; + u8 radio_syn_pll_loopfilter4; + u8 radio_syn_pll_loopfilter5; + u8 radio_syn_reserved_addr27; + u8 radio_syn_reserved_addr28; + u8 radio_syn_reserved_addr29; + u8 radio_syn_logen_vcobuf1; + u8 radio_syn_logen_mixer2; + u8 radio_syn_logen_buf3; + u8 radio_syn_logen_buf4; + u8 radio_rx0_lnaa_tune; + u8 radio_rx0_lnag_tune; + u8 radio_tx0_intpaa_boost_tune; + u8 radio_tx0_intpag_boost_tune; + u8 radio_tx0_pada_boost_tune; + u8 radio_tx0_padg_boost_tune; + u8 radio_tx0_pgaa_boost_tune; + u8 radio_tx0_pgag_boost_tune; + u8 radio_tx0_mixa_boost_tune; + u8 radio_tx0_mixg_boost_tune; + u8 radio_rx1_lnaa_tune; + u8 radio_rx1_lnag_tune; + u8 radio_tx1_intpaa_boost_tune; + u8 radio_tx1_intpag_boost_tune; + u8 radio_tx1_pada_boost_tune; + u8 radio_tx1_padg_boost_tune; + u8 radio_tx1_pgaa_boost_tune; + u8 radio_tx1_pgag_boost_tune; + u8 radio_tx1_mixa_boost_tune; + u8 radio_tx1_mixg_boost_tune; /* PHY register values on channelswitch */ struct b43_phy_n_sfo_cfg phy_regs; }; -- cgit v1.2.3-59-g8ed1b From 794830e691a6b61d2de3fa9daeb609fd4ef4a4e7 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 17 Oct 2010 15:38:51 +0200 Subject: b43: N-PHY: define registers names for 2056 radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Cc: Henry Ptasinski Cc: Brett Rudley Cc: Nohee Ko Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.h | 522 ++++++++++++++++++++++++++++++++++ 1 file changed, 522 insertions(+) diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index 60341d7ae673..6b3264774adf 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -4,6 +4,9 @@ Copyright (c) 2010 Rafał Miłecki + Some parts of the code in this file are derived from the brcm80211 + driver Copyright (c) 2010 Broadcom Corporation + 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 @@ -28,6 +31,525 @@ #include "tables_nphy.h" +#define B2056_SYN (0x0 << 12) +#define B2056_TX0 (0x2 << 12) +#define B2056_TX1 (0x3 << 12) +#define B2056_RX0 (0x6 << 12) +#define B2056_RX1 (0x7 << 12) +#define B2056_ALLTX (0xE << 12) +#define B2056_ALLRX (0xF << 12) + +#define B2056_SYN_RESERVED_ADDR0 0x00 +#define B2056_SYN_IDCODE 0x01 +#define B2056_SYN_RESERVED_ADDR2 0x02 +#define B2056_SYN_RESERVED_ADDR3 0x03 +#define B2056_SYN_RESERVED_ADDR4 0x04 +#define B2056_SYN_RESERVED_ADDR5 0x05 +#define B2056_SYN_RESERVED_ADDR6 0x06 +#define B2056_SYN_RESERVED_ADDR7 0x07 +#define B2056_SYN_COM_CTRL 0x08 +#define B2056_SYN_COM_PU 0x09 +#define B2056_SYN_COM_OVR 0x0A +#define B2056_SYN_COM_RESET 0x0B +#define B2056_SYN_COM_RCAL 0x0C +#define B2056_SYN_COM_RC_RXLPF 0x0D +#define B2056_SYN_COM_RC_TXLPF 0x0E +#define B2056_SYN_COM_RC_RXHPF 0x0F +#define B2056_SYN_RESERVED_ADDR16 0x10 +#define B2056_SYN_RESERVED_ADDR17 0x11 +#define B2056_SYN_RESERVED_ADDR18 0x12 +#define B2056_SYN_RESERVED_ADDR19 0x13 +#define B2056_SYN_RESERVED_ADDR20 0x14 +#define B2056_SYN_RESERVED_ADDR21 0x15 +#define B2056_SYN_RESERVED_ADDR22 0x16 +#define B2056_SYN_RESERVED_ADDR23 0x17 +#define B2056_SYN_RESERVED_ADDR24 0x18 +#define B2056_SYN_RESERVED_ADDR25 0x19 +#define B2056_SYN_RESERVED_ADDR26 0x1A +#define B2056_SYN_RESERVED_ADDR27 0x1B +#define B2056_SYN_RESERVED_ADDR28 0x1C +#define B2056_SYN_RESERVED_ADDR29 0x1D +#define B2056_SYN_RESERVED_ADDR30 0x1E +#define B2056_SYN_RESERVED_ADDR31 0x1F +#define B2056_SYN_GPIO_MASTER1 0x20 +#define B2056_SYN_GPIO_MASTER2 0x21 +#define B2056_SYN_TOPBIAS_MASTER 0x22 +#define B2056_SYN_TOPBIAS_RCAL 0x23 +#define B2056_SYN_AFEREG 0x24 +#define B2056_SYN_TEMPPROCSENSE 0x25 +#define B2056_SYN_TEMPPROCSENSEIDAC 0x26 +#define B2056_SYN_TEMPPROCSENSERCAL 0x27 +#define B2056_SYN_LPO 0x28 +#define B2056_SYN_VDDCAL_MASTER 0x29 +#define B2056_SYN_VDDCAL_IDAC 0x2A +#define B2056_SYN_VDDCAL_STATUS 0x2B +#define B2056_SYN_RCAL_MASTER 0x2C +#define B2056_SYN_RCAL_CODE_OUT 0x2D +#define B2056_SYN_RCCAL_CTRL0 0x2E +#define B2056_SYN_RCCAL_CTRL1 0x2F +#define B2056_SYN_RCCAL_CTRL2 0x30 +#define B2056_SYN_RCCAL_CTRL3 0x31 +#define B2056_SYN_RCCAL_CTRL4 0x32 +#define B2056_SYN_RCCAL_CTRL5 0x33 +#define B2056_SYN_RCCAL_CTRL6 0x34 +#define B2056_SYN_RCCAL_CTRL7 0x35 +#define B2056_SYN_RCCAL_CTRL8 0x36 +#define B2056_SYN_RCCAL_CTRL9 0x37 +#define B2056_SYN_RCCAL_CTRL10 0x38 +#define B2056_SYN_RCCAL_CTRL11 0x39 +#define B2056_SYN_ZCAL_SPARE1 0x3A +#define B2056_SYN_ZCAL_SPARE2 0x3B +#define B2056_SYN_PLL_MAST1 0x3C +#define B2056_SYN_PLL_MAST2 0x3D +#define B2056_SYN_PLL_MAST3 0x3E +#define B2056_SYN_PLL_BIAS_RESET 0x3F +#define B2056_SYN_PLL_XTAL0 0x40 +#define B2056_SYN_PLL_XTAL1 0x41 +#define B2056_SYN_PLL_XTAL3 0x42 +#define B2056_SYN_PLL_XTAL4 0x43 +#define B2056_SYN_PLL_XTAL5 0x44 +#define B2056_SYN_PLL_XTAL6 0x45 +#define B2056_SYN_PLL_REFDIV 0x46 +#define B2056_SYN_PLL_PFD 0x47 +#define B2056_SYN_PLL_CP1 0x48 +#define B2056_SYN_PLL_CP2 0x49 +#define B2056_SYN_PLL_CP3 0x4A +#define B2056_SYN_PLL_LOOPFILTER1 0x4B +#define B2056_SYN_PLL_LOOPFILTER2 0x4C +#define B2056_SYN_PLL_LOOPFILTER3 0x4D +#define B2056_SYN_PLL_LOOPFILTER4 0x4E +#define B2056_SYN_PLL_LOOPFILTER5 0x4F +#define B2056_SYN_PLL_MMD1 0x50 +#define B2056_SYN_PLL_MMD2 0x51 +#define B2056_SYN_PLL_VCO1 0x52 +#define B2056_SYN_PLL_VCO2 0x53 +#define B2056_SYN_PLL_MONITOR1 0x54 +#define B2056_SYN_PLL_MONITOR2 0x55 +#define B2056_SYN_PLL_VCOCAL1 0x56 +#define B2056_SYN_PLL_VCOCAL2 0x57 +#define B2056_SYN_PLL_VCOCAL4 0x58 +#define B2056_SYN_PLL_VCOCAL5 0x59 +#define B2056_SYN_PLL_VCOCAL6 0x5A +#define B2056_SYN_PLL_VCOCAL7 0x5B +#define B2056_SYN_PLL_VCOCAL8 0x5C +#define B2056_SYN_PLL_VCOCAL9 0x5D +#define B2056_SYN_PLL_VCOCAL10 0x5E +#define B2056_SYN_PLL_VCOCAL11 0x5F +#define B2056_SYN_PLL_VCOCAL12 0x60 +#define B2056_SYN_PLL_VCOCAL13 0x61 +#define B2056_SYN_PLL_VREG 0x62 +#define B2056_SYN_PLL_STATUS1 0x63 +#define B2056_SYN_PLL_STATUS2 0x64 +#define B2056_SYN_PLL_STATUS3 0x65 +#define B2056_SYN_LOGEN_PU0 0x66 +#define B2056_SYN_LOGEN_PU1 0x67 +#define B2056_SYN_LOGEN_PU2 0x68 +#define B2056_SYN_LOGEN_PU3 0x69 +#define B2056_SYN_LOGEN_PU5 0x6A +#define B2056_SYN_LOGEN_PU6 0x6B +#define B2056_SYN_LOGEN_PU7 0x6C +#define B2056_SYN_LOGEN_PU8 0x6D +#define B2056_SYN_LOGEN_BIAS_RESET 0x6E +#define B2056_SYN_LOGEN_RCCR1 0x6F +#define B2056_SYN_LOGEN_VCOBUF1 0x70 +#define B2056_SYN_LOGEN_MIXER1 0x71 +#define B2056_SYN_LOGEN_MIXER2 0x72 +#define B2056_SYN_LOGEN_BUF1 0x73 +#define B2056_SYN_LOGENBUF2 0x74 +#define B2056_SYN_LOGEN_BUF3 0x75 +#define B2056_SYN_LOGEN_BUF4 0x76 +#define B2056_SYN_LOGEN_DIV1 0x77 +#define B2056_SYN_LOGEN_DIV2 0x78 +#define B2056_SYN_LOGEN_DIV3 0x79 +#define B2056_SYN_LOGEN_ACL1 0x7A +#define B2056_SYN_LOGEN_ACL2 0x7B +#define B2056_SYN_LOGEN_ACL3 0x7C +#define B2056_SYN_LOGEN_ACL4 0x7D +#define B2056_SYN_LOGEN_ACL5 0x7E +#define B2056_SYN_LOGEN_ACL6 0x7F +#define B2056_SYN_LOGEN_ACLOUT 0x80 +#define B2056_SYN_LOGEN_ACLCAL1 0x81 +#define B2056_SYN_LOGEN_ACLCAL2 0x82 +#define B2056_SYN_LOGEN_ACLCAL3 0x83 +#define B2056_SYN_CALEN 0x84 +#define B2056_SYN_LOGEN_PEAKDET1 0x85 +#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86 +#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87 +#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88 +#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89 +#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A +#define B2056_SYN_LOGEN_VCOBUF2 0x8B +#define B2056_SYN_LOGEN_MIXER3 0x8C +#define B2056_SYN_LOGEN_BUF5 0x8D +#define B2056_SYN_LOGEN_BUF6 0x8E +#define B2056_SYN_LOGEN_CBUFRX1 0x8F +#define B2056_SYN_LOGEN_CBUFRX2 0x90 +#define B2056_SYN_LOGEN_CBUFRX3 0x91 +#define B2056_SYN_LOGEN_CBUFRX4 0x92 +#define B2056_SYN_LOGEN_CBUFTX1 0x93 +#define B2056_SYN_LOGEN_CBUFTX2 0x94 +#define B2056_SYN_LOGEN_CBUFTX3 0x95 +#define B2056_SYN_LOGEN_CBUFTX4 0x96 +#define B2056_SYN_LOGEN_CMOSRX1 0x97 +#define B2056_SYN_LOGEN_CMOSRX2 0x98 +#define B2056_SYN_LOGEN_CMOSRX3 0x99 +#define B2056_SYN_LOGEN_CMOSRX4 0x9A +#define B2056_SYN_LOGEN_CMOSTX1 0x9B +#define B2056_SYN_LOGEN_CMOSTX2 0x9C +#define B2056_SYN_LOGEN_CMOSTX3 0x9D +#define B2056_SYN_LOGEN_CMOSTX4 0x9E +#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F +#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0 +#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1 +#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2 +#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3 +#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4 +#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5 +#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6 +#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7 +#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8 +#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9 +#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA +#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB +#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC +#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD +#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE +#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF +#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0 +#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1 +#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2 +#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3 +#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4 +#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5 +#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6 + +#define B2056_TX_RESERVED_ADDR0 0x00 +#define B2056_TX_IDCODE 0x01 +#define B2056_TX_RESERVED_ADDR2 0x02 +#define B2056_TX_RESERVED_ADDR3 0x03 +#define B2056_TX_RESERVED_ADDR4 0x04 +#define B2056_TX_RESERVED_ADDR5 0x05 +#define B2056_TX_RESERVED_ADDR6 0x06 +#define B2056_TX_RESERVED_ADDR7 0x07 +#define B2056_TX_COM_CTRL 0x08 +#define B2056_TX_COM_PU 0x09 +#define B2056_TX_COM_OVR 0x0A +#define B2056_TX_COM_RESET 0x0B +#define B2056_TX_COM_RCAL 0x0C +#define B2056_TX_COM_RC_RXLPF 0x0D +#define B2056_TX_COM_RC_TXLPF 0x0E +#define B2056_TX_COM_RC_RXHPF 0x0F +#define B2056_TX_RESERVED_ADDR16 0x10 +#define B2056_TX_RESERVED_ADDR17 0x11 +#define B2056_TX_RESERVED_ADDR18 0x12 +#define B2056_TX_RESERVED_ADDR19 0x13 +#define B2056_TX_RESERVED_ADDR20 0x14 +#define B2056_TX_RESERVED_ADDR21 0x15 +#define B2056_TX_RESERVED_ADDR22 0x16 +#define B2056_TX_RESERVED_ADDR23 0x17 +#define B2056_TX_RESERVED_ADDR24 0x18 +#define B2056_TX_RESERVED_ADDR25 0x19 +#define B2056_TX_RESERVED_ADDR26 0x1A +#define B2056_TX_RESERVED_ADDR27 0x1B +#define B2056_TX_RESERVED_ADDR28 0x1C +#define B2056_TX_RESERVED_ADDR29 0x1D +#define B2056_TX_RESERVED_ADDR30 0x1E +#define B2056_TX_RESERVED_ADDR31 0x1F +#define B2056_TX_IQCAL_GAIN_BW 0x20 +#define B2056_TX_LOFT_FINE_I 0x21 +#define B2056_TX_LOFT_FINE_Q 0x22 +#define B2056_TX_LOFT_COARSE_I 0x23 +#define B2056_TX_LOFT_COARSE_Q 0x24 +#define B2056_TX_TX_COM_MASTER1 0x25 +#define B2056_TX_TX_COM_MASTER2 0x26 +#define B2056_TX_RXIQCAL_TXMUX 0x27 +#define B2056_TX_TX_SSI_MASTER 0x28 +#define B2056_TX_IQCAL_VCM_HG 0x29 +#define B2056_TX_IQCAL_IDAC 0x2A +#define B2056_TX_TSSI_VCM 0x2B +#define B2056_TX_TX_AMP_DET 0x2C +#define B2056_TX_TX_SSI_MUX 0x2D +#define B2056_TX_TSSIA 0x2E +#define B2056_TX_TSSIG 0x2F +#define B2056_TX_TSSI_MISC1 0x30 +#define B2056_TX_TSSI_MISC2 0x31 +#define B2056_TX_TSSI_MISC3 0x32 +#define B2056_TX_PA_SPARE1 0x33 +#define B2056_TX_PA_SPARE2 0x34 +#define B2056_TX_INTPAA_MASTER 0x35 +#define B2056_TX_INTPAA_GAIN 0x36 +#define B2056_TX_INTPAA_BOOST_TUNE 0x37 +#define B2056_TX_INTPAA_IAUX_STAT 0x38 +#define B2056_TX_INTPAA_IAUX_DYN 0x39 +#define B2056_TX_INTPAA_IMAIN_STAT 0x3A +#define B2056_TX_INTPAA_IMAIN_DYN 0x3B +#define B2056_TX_INTPAA_CASCBIAS 0x3C +#define B2056_TX_INTPAA_PASLOPE 0x3D +#define B2056_TX_INTPAA_PA_MISC 0x3E +#define B2056_TX_INTPAG_MASTER 0x3F +#define B2056_TX_INTPAG_GAIN 0x40 +#define B2056_TX_INTPAG_BOOST_TUNE 0x41 +#define B2056_TX_INTPAG_IAUX_STAT 0x42 +#define B2056_TX_INTPAG_IAUX_DYN 0x43 +#define B2056_TX_INTPAG_IMAIN_STAT 0x44 +#define B2056_TX_INTPAG_IMAIN_DYN 0x45 +#define B2056_TX_INTPAG_CASCBIAS 0x46 +#define B2056_TX_INTPAG_PASLOPE 0x47 +#define B2056_TX_INTPAG_PA_MISC 0x48 +#define B2056_TX_PADA_MASTER 0x49 +#define B2056_TX_PADA_IDAC 0x4A +#define B2056_TX_PADA_CASCBIAS 0x4B +#define B2056_TX_PADA_GAIN 0x4C +#define B2056_TX_PADA_BOOST_TUNE 0x4D +#define B2056_TX_PADA_SLOPE 0x4E +#define B2056_TX_PADG_MASTER 0x4F +#define B2056_TX_PADG_IDAC 0x50 +#define B2056_TX_PADG_CASCBIAS 0x51 +#define B2056_TX_PADG_GAIN 0x52 +#define B2056_TX_PADG_BOOST_TUNE 0x53 +#define B2056_TX_PADG_SLOPE 0x54 +#define B2056_TX_PGAA_MASTER 0x55 +#define B2056_TX_PGAA_IDAC 0x56 +#define B2056_TX_PGAA_GAIN 0x57 +#define B2056_TX_PGAA_BOOST_TUNE 0x58 +#define B2056_TX_PGAA_SLOPE 0x59 +#define B2056_TX_PGAA_MISC 0x5A +#define B2056_TX_PGAG_MASTER 0x5B +#define B2056_TX_PGAG_IDAC 0x5C +#define B2056_TX_PGAG_GAIN 0x5D +#define B2056_TX_PGAG_BOOST_TUNE 0x5E +#define B2056_TX_PGAG_SLOPE 0x5F +#define B2056_TX_PGAG_MISC 0x60 +#define B2056_TX_MIXA_MASTER 0x61 +#define B2056_TX_MIXA_BOOST_TUNE 0x62 +#define B2056_TX_MIXG 0x63 +#define B2056_TX_MIXG_BOOST_TUNE 0x64 +#define B2056_TX_BB_GM_MASTER 0x65 +#define B2056_TX_GMBB_GM 0x66 +#define B2056_TX_GMBB_IDAC 0x67 +#define B2056_TX_TXLPF_MASTER 0x68 +#define B2056_TX_TXLPF_RCCAL 0x69 +#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A +#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B +#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C +#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D +#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E +#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F +#define B2056_TX_TXLPF_RCCAL_OFF6 0x70 +#define B2056_TX_TXLPF_BW 0x71 +#define B2056_TX_TXLPF_GAIN 0x72 +#define B2056_TX_TXLPF_IDAC 0x73 +#define B2056_TX_TXLPF_IDAC_0 0x74 +#define B2056_TX_TXLPF_IDAC_1 0x75 +#define B2056_TX_TXLPF_IDAC_2 0x76 +#define B2056_TX_TXLPF_IDAC_3 0x77 +#define B2056_TX_TXLPF_IDAC_4 0x78 +#define B2056_TX_TXLPF_IDAC_5 0x79 +#define B2056_TX_TXLPF_IDAC_6 0x7A +#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B +#define B2056_TX_TXLPF_MISC 0x7C +#define B2056_TX_TXSPARE1 0x7D +#define B2056_TX_TXSPARE2 0x7E +#define B2056_TX_TXSPARE3 0x7F +#define B2056_TX_TXSPARE4 0x80 +#define B2056_TX_TXSPARE5 0x81 +#define B2056_TX_TXSPARE6 0x82 +#define B2056_TX_TXSPARE7 0x83 +#define B2056_TX_TXSPARE8 0x84 +#define B2056_TX_TXSPARE9 0x85 +#define B2056_TX_TXSPARE10 0x86 +#define B2056_TX_TXSPARE11 0x87 +#define B2056_TX_TXSPARE12 0x88 +#define B2056_TX_TXSPARE13 0x89 +#define B2056_TX_TXSPARE14 0x8A +#define B2056_TX_TXSPARE15 0x8B +#define B2056_TX_TXSPARE16 0x8C +#define B2056_TX_STATUS_INTPA_GAIN 0x8D +#define B2056_TX_STATUS_PAD_GAIN 0x8E +#define B2056_TX_STATUS_PGA_GAIN 0x8F +#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90 +#define B2056_TX_STATUS_TXLPF_BW 0x91 +#define B2056_TX_STATUS_TXLPF_RC 0x92 +#define B2056_TX_GMBB_IDAC0 0x93 +#define B2056_TX_GMBB_IDAC1 0x94 +#define B2056_TX_GMBB_IDAC2 0x95 +#define B2056_TX_GMBB_IDAC3 0x96 +#define B2056_TX_GMBB_IDAC4 0x97 +#define B2056_TX_GMBB_IDAC5 0x98 +#define B2056_TX_GMBB_IDAC6 0x99 +#define B2056_TX_GMBB_IDAC7 0x9A + +#define B2056_RX_RESERVED_ADDR0 0x00 +#define B2056_RX_IDCODE 0x01 +#define B2056_RX_RESERVED_ADDR2 0x02 +#define B2056_RX_RESERVED_ADDR3 0x03 +#define B2056_RX_RESERVED_ADDR4 0x04 +#define B2056_RX_RESERVED_ADDR5 0x05 +#define B2056_RX_RESERVED_ADDR6 0x06 +#define B2056_RX_RESERVED_ADDR7 0x07 +#define B2056_RX_COM_CTRL 0x08 +#define B2056_RX_COM_PU 0x09 +#define B2056_RX_COM_OVR 0x0A +#define B2056_RX_COM_RESET 0x0B +#define B2056_RX_COM_RCAL 0x0C +#define B2056_RX_COM_RC_RXLPF 0x0D +#define B2056_RX_COM_RC_TXLPF 0x0E +#define B2056_RX_COM_RC_RXHPF 0x0F +#define B2056_RX_RESERVED_ADDR16 0x10 +#define B2056_RX_RESERVED_ADDR17 0x11 +#define B2056_RX_RESERVED_ADDR18 0x12 +#define B2056_RX_RESERVED_ADDR19 0x13 +#define B2056_RX_RESERVED_ADDR20 0x14 +#define B2056_RX_RESERVED_ADDR21 0x15 +#define B2056_RX_RESERVED_ADDR22 0x16 +#define B2056_RX_RESERVED_ADDR23 0x17 +#define B2056_RX_RESERVED_ADDR24 0x18 +#define B2056_RX_RESERVED_ADDR25 0x19 +#define B2056_RX_RESERVED_ADDR26 0x1A +#define B2056_RX_RESERVED_ADDR27 0x1B +#define B2056_RX_RESERVED_ADDR28 0x1C +#define B2056_RX_RESERVED_ADDR29 0x1D +#define B2056_RX_RESERVED_ADDR30 0x1E +#define B2056_RX_RESERVED_ADDR31 0x1F +#define B2056_RX_RXIQCAL_RXMUX 0x20 +#define B2056_RX_RSSI_PU 0x21 +#define B2056_RX_RSSI_SEL 0x22 +#define B2056_RX_RSSI_GAIN 0x23 +#define B2056_RX_RSSI_NB_IDAC 0x24 +#define B2056_RX_RSSI_WB2I_IDAC_1 0x25 +#define B2056_RX_RSSI_WB2I_IDAC_2 0x26 +#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27 +#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28 +#define B2056_RX_RSSI_POLE 0x29 +#define B2056_RX_RSSI_WB1_IDAC 0x2A +#define B2056_RX_RSSI_MISC 0x2B +#define B2056_RX_LNAA_MASTER 0x2C +#define B2056_RX_LNAA_TUNE 0x2D +#define B2056_RX_LNAA_GAIN 0x2E +#define B2056_RX_LNA_A_SLOPE 0x2F +#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30 +#define B2056_RX_LNAA2_IDAC 0x31 +#define B2056_RX_LNA1A_MISC 0x32 +#define B2056_RX_LNAG_MASTER 0x33 +#define B2056_RX_LNAG_TUNE 0x34 +#define B2056_RX_LNAG_GAIN 0x35 +#define B2056_RX_LNA_G_SLOPE 0x36 +#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37 +#define B2056_RX_LNAG2_IDAC 0x38 +#define B2056_RX_LNA1G_MISC 0x39 +#define B2056_RX_MIXA_MASTER 0x3A +#define B2056_RX_MIXA_VCM 0x3B +#define B2056_RX_MIXA_CTRLPTAT 0x3C +#define B2056_RX_MIXA_LOB_BIAS 0x3D +#define B2056_RX_MIXA_CORE_IDAC 0x3E +#define B2056_RX_MIXA_CMFB_IDAC 0x3F +#define B2056_RX_MIXA_BIAS_AUX 0x40 +#define B2056_RX_MIXA_BIAS_MAIN 0x41 +#define B2056_RX_MIXA_BIAS_MISC 0x42 +#define B2056_RX_MIXA_MAST_BIAS 0x43 +#define B2056_RX_MIXG_MASTER 0x44 +#define B2056_RX_MIXG_VCM 0x45 +#define B2056_RX_MIXG_CTRLPTAT 0x46 +#define B2056_RX_MIXG_LOB_BIAS 0x47 +#define B2056_RX_MIXG_CORE_IDAC 0x48 +#define B2056_RX_MIXG_CMFB_IDAC 0x49 +#define B2056_RX_MIXG_BIAS_AUX 0x4A +#define B2056_RX_MIXG_BIAS_MAIN 0x4B +#define B2056_RX_MIXG_BIAS_MISC 0x4C +#define B2056_RX_MIXG_MAST_BIAS 0x4D +#define B2056_RX_TIA_MASTER 0x4E +#define B2056_RX_TIA_IOPAMP 0x4F +#define B2056_RX_TIA_QOPAMP 0x50 +#define B2056_RX_TIA_IMISC 0x51 +#define B2056_RX_TIA_QMISC 0x52 +#define B2056_RX_TIA_GAIN 0x53 +#define B2056_RX_TIA_SPARE1 0x54 +#define B2056_RX_TIA_SPARE2 0x55 +#define B2056_RX_BB_LPF_MASTER 0x56 +#define B2056_RX_AACI_MASTER 0x57 +#define B2056_RX_RXLPF_IDAC 0x58 +#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59 +#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A +#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B +#define B2056_RX_RXLPF_OUTVCM 0x5C +#define B2056_RX_RXLPF_INVCM_BODY 0x5D +#define B2056_RX_RXLPF_CC_OP 0x5E +#define B2056_RX_RXLPF_GAIN 0x5F +#define B2056_RX_RXLPF_Q_BW 0x60 +#define B2056_RX_RXLPF_HP_CORNER_BW 0x61 +#define B2056_RX_RXLPF_RCCAL_HPC 0x62 +#define B2056_RX_RXHPF_OFF0 0x63 +#define B2056_RX_RXHPF_OFF1 0x64 +#define B2056_RX_RXHPF_OFF2 0x65 +#define B2056_RX_RXHPF_OFF3 0x66 +#define B2056_RX_RXHPF_OFF4 0x67 +#define B2056_RX_RXHPF_OFF5 0x68 +#define B2056_RX_RXHPF_OFF6 0x69 +#define B2056_RX_RXHPF_OFF7 0x6A +#define B2056_RX_RXLPF_RCCAL_LPC 0x6B +#define B2056_RX_RXLPF_OFF_0 0x6C +#define B2056_RX_RXLPF_OFF_1 0x6D +#define B2056_RX_RXLPF_OFF_2 0x6E +#define B2056_RX_RXLPF_OFF_3 0x6F +#define B2056_RX_RXLPF_OFF_4 0x70 +#define B2056_RX_UNUSED 0x71 +#define B2056_RX_VGA_MASTER 0x72 +#define B2056_RX_VGA_BIAS 0x73 +#define B2056_RX_VGA_BIAS_DCCANCEL 0x74 +#define B2056_RX_VGA_GAIN 0x75 +#define B2056_RX_VGA_HP_CORNER_BW 0x76 +#define B2056_RX_VGABUF_BIAS 0x77 +#define B2056_RX_VGABUF_GAIN_BW 0x78 +#define B2056_RX_TXFBMIX_A 0x79 +#define B2056_RX_TXFBMIX_G 0x7A +#define B2056_RX_RXSPARE1 0x7B +#define B2056_RX_RXSPARE2 0x7C +#define B2056_RX_RXSPARE3 0x7D +#define B2056_RX_RXSPARE4 0x7E +#define B2056_RX_RXSPARE5 0x7F +#define B2056_RX_RXSPARE6 0x80 +#define B2056_RX_RXSPARE7 0x81 +#define B2056_RX_RXSPARE8 0x82 +#define B2056_RX_RXSPARE9 0x83 +#define B2056_RX_RXSPARE10 0x84 +#define B2056_RX_RXSPARE11 0x85 +#define B2056_RX_RXSPARE12 0x86 +#define B2056_RX_RXSPARE13 0x87 +#define B2056_RX_RXSPARE14 0x88 +#define B2056_RX_RXSPARE15 0x89 +#define B2056_RX_RXSPARE16 0x8A +#define B2056_RX_STATUS_LNAA_GAIN 0x8B +#define B2056_RX_STATUS_LNAG_GAIN 0x8C +#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D +#define B2056_RX_STATUS_RXLPF_GAIN 0x8E +#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F +#define B2056_RX_STATUS_RXLPF_Q 0x90 +#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91 +#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92 +#define B2056_RX_STATUS_RXLPF_RC 0x93 +#define B2056_RX_STATUS_HPC_RC 0x94 + +#define B2056_LNA1_A_PU 0x01 +#define B2056_LNA2_A_PU 0x02 +#define B2056_LNA1_G_PU 0x01 +#define B2056_LNA2_G_PU 0x02 +#define B2056_MIXA_PU_I 0x01 +#define B2056_MIXA_PU_Q 0x02 +#define B2056_MIXA_PU_GM 0x10 +#define B2056_MIXG_PU_I 0x01 +#define B2056_MIXG_PU_Q 0x02 +#define B2056_MIXG_PU_GM 0x10 +#define B2056_TIA_PU 0x01 +#define B2056_BB_LPF_PU 0x20 +#define B2056_W1_PU 0x02 +#define B2056_W2_PU 0x04 +#define B2056_NB_PU 0x08 +#define B2056_RSSI_W1_SEL 0x02 +#define B2056_RSSI_W2_SEL 0x04 +#define B2056_RSSI_NB_SEL 0x08 +#define B2056_VCM_MASK 0x1C +#define B2056_RSSI_VCM_SHIFT 0x02 + struct b43_nphy_channeltab_entry_rev3 { /* The channel frequency in MHz */ u16 freq; -- cgit v1.2.3-59-g8ed1b From 790a11f268373b60069bc1371dc05143107c607c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 14 Oct 2010 23:04:40 +0200 Subject: b43: N-PHY: define registers names for 2056 radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Cc: Henry Ptasinski Cc: Brett Rudley Cc: Nohee Ko Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.h | 519 ++++++++++++++++++++++++++++++++++ 1 file changed, 519 insertions(+) diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index 6b3264774adf..302600c0afa4 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -550,6 +550,525 @@ #define B2056_VCM_MASK 0x1C #define B2056_RSSI_VCM_SHIFT 0x02 +#define B2056_SYN (0x0 << 12) +#define B2056_TX0 (0x2 << 12) +#define B2056_TX1 (0x3 << 12) +#define B2056_RX0 (0x6 << 12) +#define B2056_RX1 (0x7 << 12) +#define B2056_ALLTX (0xE << 12) +#define B2056_ALLRX (0xF << 12) + +#define B2056_SYN_RESERVED_ADDR0 0x00 +#define B2056_SYN_IDCODE 0x01 +#define B2056_SYN_RESERVED_ADDR2 0x02 +#define B2056_SYN_RESERVED_ADDR3 0x03 +#define B2056_SYN_RESERVED_ADDR4 0x04 +#define B2056_SYN_RESERVED_ADDR5 0x05 +#define B2056_SYN_RESERVED_ADDR6 0x06 +#define B2056_SYN_RESERVED_ADDR7 0x07 +#define B2056_SYN_COM_CTRL 0x08 +#define B2056_SYN_COM_PU 0x09 +#define B2056_SYN_COM_OVR 0x0A +#define B2056_SYN_COM_RESET 0x0B +#define B2056_SYN_COM_RCAL 0x0C +#define B2056_SYN_COM_RC_RXLPF 0x0D +#define B2056_SYN_COM_RC_TXLPF 0x0E +#define B2056_SYN_COM_RC_RXHPF 0x0F +#define B2056_SYN_RESERVED_ADDR16 0x10 +#define B2056_SYN_RESERVED_ADDR17 0x11 +#define B2056_SYN_RESERVED_ADDR18 0x12 +#define B2056_SYN_RESERVED_ADDR19 0x13 +#define B2056_SYN_RESERVED_ADDR20 0x14 +#define B2056_SYN_RESERVED_ADDR21 0x15 +#define B2056_SYN_RESERVED_ADDR22 0x16 +#define B2056_SYN_RESERVED_ADDR23 0x17 +#define B2056_SYN_RESERVED_ADDR24 0x18 +#define B2056_SYN_RESERVED_ADDR25 0x19 +#define B2056_SYN_RESERVED_ADDR26 0x1A +#define B2056_SYN_RESERVED_ADDR27 0x1B +#define B2056_SYN_RESERVED_ADDR28 0x1C +#define B2056_SYN_RESERVED_ADDR29 0x1D +#define B2056_SYN_RESERVED_ADDR30 0x1E +#define B2056_SYN_RESERVED_ADDR31 0x1F +#define B2056_SYN_GPIO_MASTER1 0x20 +#define B2056_SYN_GPIO_MASTER2 0x21 +#define B2056_SYN_TOPBIAS_MASTER 0x22 +#define B2056_SYN_TOPBIAS_RCAL 0x23 +#define B2056_SYN_AFEREG 0x24 +#define B2056_SYN_TEMPPROCSENSE 0x25 +#define B2056_SYN_TEMPPROCSENSEIDAC 0x26 +#define B2056_SYN_TEMPPROCSENSERCAL 0x27 +#define B2056_SYN_LPO 0x28 +#define B2056_SYN_VDDCAL_MASTER 0x29 +#define B2056_SYN_VDDCAL_IDAC 0x2A +#define B2056_SYN_VDDCAL_STATUS 0x2B +#define B2056_SYN_RCAL_MASTER 0x2C +#define B2056_SYN_RCAL_CODE_OUT 0x2D +#define B2056_SYN_RCCAL_CTRL0 0x2E +#define B2056_SYN_RCCAL_CTRL1 0x2F +#define B2056_SYN_RCCAL_CTRL2 0x30 +#define B2056_SYN_RCCAL_CTRL3 0x31 +#define B2056_SYN_RCCAL_CTRL4 0x32 +#define B2056_SYN_RCCAL_CTRL5 0x33 +#define B2056_SYN_RCCAL_CTRL6 0x34 +#define B2056_SYN_RCCAL_CTRL7 0x35 +#define B2056_SYN_RCCAL_CTRL8 0x36 +#define B2056_SYN_RCCAL_CTRL9 0x37 +#define B2056_SYN_RCCAL_CTRL10 0x38 +#define B2056_SYN_RCCAL_CTRL11 0x39 +#define B2056_SYN_ZCAL_SPARE1 0x3A +#define B2056_SYN_ZCAL_SPARE2 0x3B +#define B2056_SYN_PLL_MAST1 0x3C +#define B2056_SYN_PLL_MAST2 0x3D +#define B2056_SYN_PLL_MAST3 0x3E +#define B2056_SYN_PLL_BIAS_RESET 0x3F +#define B2056_SYN_PLL_XTAL0 0x40 +#define B2056_SYN_PLL_XTAL1 0x41 +#define B2056_SYN_PLL_XTAL3 0x42 +#define B2056_SYN_PLL_XTAL4 0x43 +#define B2056_SYN_PLL_XTAL5 0x44 +#define B2056_SYN_PLL_XTAL6 0x45 +#define B2056_SYN_PLL_REFDIV 0x46 +#define B2056_SYN_PLL_PFD 0x47 +#define B2056_SYN_PLL_CP1 0x48 +#define B2056_SYN_PLL_CP2 0x49 +#define B2056_SYN_PLL_CP3 0x4A +#define B2056_SYN_PLL_LOOPFILTER1 0x4B +#define B2056_SYN_PLL_LOOPFILTER2 0x4C +#define B2056_SYN_PLL_LOOPFILTER3 0x4D +#define B2056_SYN_PLL_LOOPFILTER4 0x4E +#define B2056_SYN_PLL_LOOPFILTER5 0x4F +#define B2056_SYN_PLL_MMD1 0x50 +#define B2056_SYN_PLL_MMD2 0x51 +#define B2056_SYN_PLL_VCO1 0x52 +#define B2056_SYN_PLL_VCO2 0x53 +#define B2056_SYN_PLL_MONITOR1 0x54 +#define B2056_SYN_PLL_MONITOR2 0x55 +#define B2056_SYN_PLL_VCOCAL1 0x56 +#define B2056_SYN_PLL_VCOCAL2 0x57 +#define B2056_SYN_PLL_VCOCAL4 0x58 +#define B2056_SYN_PLL_VCOCAL5 0x59 +#define B2056_SYN_PLL_VCOCAL6 0x5A +#define B2056_SYN_PLL_VCOCAL7 0x5B +#define B2056_SYN_PLL_VCOCAL8 0x5C +#define B2056_SYN_PLL_VCOCAL9 0x5D +#define B2056_SYN_PLL_VCOCAL10 0x5E +#define B2056_SYN_PLL_VCOCAL11 0x5F +#define B2056_SYN_PLL_VCOCAL12 0x60 +#define B2056_SYN_PLL_VCOCAL13 0x61 +#define B2056_SYN_PLL_VREG 0x62 +#define B2056_SYN_PLL_STATUS1 0x63 +#define B2056_SYN_PLL_STATUS2 0x64 +#define B2056_SYN_PLL_STATUS3 0x65 +#define B2056_SYN_LOGEN_PU0 0x66 +#define B2056_SYN_LOGEN_PU1 0x67 +#define B2056_SYN_LOGEN_PU2 0x68 +#define B2056_SYN_LOGEN_PU3 0x69 +#define B2056_SYN_LOGEN_PU5 0x6A +#define B2056_SYN_LOGEN_PU6 0x6B +#define B2056_SYN_LOGEN_PU7 0x6C +#define B2056_SYN_LOGEN_PU8 0x6D +#define B2056_SYN_LOGEN_BIAS_RESET 0x6E +#define B2056_SYN_LOGEN_RCCR1 0x6F +#define B2056_SYN_LOGEN_VCOBUF1 0x70 +#define B2056_SYN_LOGEN_MIXER1 0x71 +#define B2056_SYN_LOGEN_MIXER2 0x72 +#define B2056_SYN_LOGEN_BUF1 0x73 +#define B2056_SYN_LOGENBUF2 0x74 +#define B2056_SYN_LOGEN_BUF3 0x75 +#define B2056_SYN_LOGEN_BUF4 0x76 +#define B2056_SYN_LOGEN_DIV1 0x77 +#define B2056_SYN_LOGEN_DIV2 0x78 +#define B2056_SYN_LOGEN_DIV3 0x79 +#define B2056_SYN_LOGEN_ACL1 0x7A +#define B2056_SYN_LOGEN_ACL2 0x7B +#define B2056_SYN_LOGEN_ACL3 0x7C +#define B2056_SYN_LOGEN_ACL4 0x7D +#define B2056_SYN_LOGEN_ACL5 0x7E +#define B2056_SYN_LOGEN_ACL6 0x7F +#define B2056_SYN_LOGEN_ACLOUT 0x80 +#define B2056_SYN_LOGEN_ACLCAL1 0x81 +#define B2056_SYN_LOGEN_ACLCAL2 0x82 +#define B2056_SYN_LOGEN_ACLCAL3 0x83 +#define B2056_SYN_CALEN 0x84 +#define B2056_SYN_LOGEN_PEAKDET1 0x85 +#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86 +#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87 +#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88 +#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89 +#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A +#define B2056_SYN_LOGEN_VCOBUF2 0x8B +#define B2056_SYN_LOGEN_MIXER3 0x8C +#define B2056_SYN_LOGEN_BUF5 0x8D +#define B2056_SYN_LOGEN_BUF6 0x8E +#define B2056_SYN_LOGEN_CBUFRX1 0x8F +#define B2056_SYN_LOGEN_CBUFRX2 0x90 +#define B2056_SYN_LOGEN_CBUFRX3 0x91 +#define B2056_SYN_LOGEN_CBUFRX4 0x92 +#define B2056_SYN_LOGEN_CBUFTX1 0x93 +#define B2056_SYN_LOGEN_CBUFTX2 0x94 +#define B2056_SYN_LOGEN_CBUFTX3 0x95 +#define B2056_SYN_LOGEN_CBUFTX4 0x96 +#define B2056_SYN_LOGEN_CMOSRX1 0x97 +#define B2056_SYN_LOGEN_CMOSRX2 0x98 +#define B2056_SYN_LOGEN_CMOSRX3 0x99 +#define B2056_SYN_LOGEN_CMOSRX4 0x9A +#define B2056_SYN_LOGEN_CMOSTX1 0x9B +#define B2056_SYN_LOGEN_CMOSTX2 0x9C +#define B2056_SYN_LOGEN_CMOSTX3 0x9D +#define B2056_SYN_LOGEN_CMOSTX4 0x9E +#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F +#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0 +#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1 +#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2 +#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3 +#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4 +#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5 +#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6 +#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7 +#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8 +#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9 +#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA +#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB +#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC +#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD +#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE +#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF +#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0 +#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1 +#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2 +#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3 +#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4 +#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5 +#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6 + +#define B2056_TX_RESERVED_ADDR0 0x00 +#define B2056_TX_IDCODE 0x01 +#define B2056_TX_RESERVED_ADDR2 0x02 +#define B2056_TX_RESERVED_ADDR3 0x03 +#define B2056_TX_RESERVED_ADDR4 0x04 +#define B2056_TX_RESERVED_ADDR5 0x05 +#define B2056_TX_RESERVED_ADDR6 0x06 +#define B2056_TX_RESERVED_ADDR7 0x07 +#define B2056_TX_COM_CTRL 0x08 +#define B2056_TX_COM_PU 0x09 +#define B2056_TX_COM_OVR 0x0A +#define B2056_TX_COM_RESET 0x0B +#define B2056_TX_COM_RCAL 0x0C +#define B2056_TX_COM_RC_RXLPF 0x0D +#define B2056_TX_COM_RC_TXLPF 0x0E +#define B2056_TX_COM_RC_RXHPF 0x0F +#define B2056_TX_RESERVED_ADDR16 0x10 +#define B2056_TX_RESERVED_ADDR17 0x11 +#define B2056_TX_RESERVED_ADDR18 0x12 +#define B2056_TX_RESERVED_ADDR19 0x13 +#define B2056_TX_RESERVED_ADDR20 0x14 +#define B2056_TX_RESERVED_ADDR21 0x15 +#define B2056_TX_RESERVED_ADDR22 0x16 +#define B2056_TX_RESERVED_ADDR23 0x17 +#define B2056_TX_RESERVED_ADDR24 0x18 +#define B2056_TX_RESERVED_ADDR25 0x19 +#define B2056_TX_RESERVED_ADDR26 0x1A +#define B2056_TX_RESERVED_ADDR27 0x1B +#define B2056_TX_RESERVED_ADDR28 0x1C +#define B2056_TX_RESERVED_ADDR29 0x1D +#define B2056_TX_RESERVED_ADDR30 0x1E +#define B2056_TX_RESERVED_ADDR31 0x1F +#define B2056_TX_IQCAL_GAIN_BW 0x20 +#define B2056_TX_LOFT_FINE_I 0x21 +#define B2056_TX_LOFT_FINE_Q 0x22 +#define B2056_TX_LOFT_COARSE_I 0x23 +#define B2056_TX_LOFT_COARSE_Q 0x24 +#define B2056_TX_TX_COM_MASTER1 0x25 +#define B2056_TX_TX_COM_MASTER2 0x26 +#define B2056_TX_RXIQCAL_TXMUX 0x27 +#define B2056_TX_TX_SSI_MASTER 0x28 +#define B2056_TX_IQCAL_VCM_HG 0x29 +#define B2056_TX_IQCAL_IDAC 0x2A +#define B2056_TX_TSSI_VCM 0x2B +#define B2056_TX_TX_AMP_DET 0x2C +#define B2056_TX_TX_SSI_MUX 0x2D +#define B2056_TX_TSSIA 0x2E +#define B2056_TX_TSSIG 0x2F +#define B2056_TX_TSSI_MISC1 0x30 +#define B2056_TX_TSSI_MISC2 0x31 +#define B2056_TX_TSSI_MISC3 0x32 +#define B2056_TX_PA_SPARE1 0x33 +#define B2056_TX_PA_SPARE2 0x34 +#define B2056_TX_INTPAA_MASTER 0x35 +#define B2056_TX_INTPAA_GAIN 0x36 +#define B2056_TX_INTPAA_BOOST_TUNE 0x37 +#define B2056_TX_INTPAA_IAUX_STAT 0x38 +#define B2056_TX_INTPAA_IAUX_DYN 0x39 +#define B2056_TX_INTPAA_IMAIN_STAT 0x3A +#define B2056_TX_INTPAA_IMAIN_DYN 0x3B +#define B2056_TX_INTPAA_CASCBIAS 0x3C +#define B2056_TX_INTPAA_PASLOPE 0x3D +#define B2056_TX_INTPAA_PA_MISC 0x3E +#define B2056_TX_INTPAG_MASTER 0x3F +#define B2056_TX_INTPAG_GAIN 0x40 +#define B2056_TX_INTPAG_BOOST_TUNE 0x41 +#define B2056_TX_INTPAG_IAUX_STAT 0x42 +#define B2056_TX_INTPAG_IAUX_DYN 0x43 +#define B2056_TX_INTPAG_IMAIN_STAT 0x44 +#define B2056_TX_INTPAG_IMAIN_DYN 0x45 +#define B2056_TX_INTPAG_CASCBIAS 0x46 +#define B2056_TX_INTPAG_PASLOPE 0x47 +#define B2056_TX_INTPAG_PA_MISC 0x48 +#define B2056_TX_PADA_MASTER 0x49 +#define B2056_TX_PADA_IDAC 0x4A +#define B2056_TX_PADA_CASCBIAS 0x4B +#define B2056_TX_PADA_GAIN 0x4C +#define B2056_TX_PADA_BOOST_TUNE 0x4D +#define B2056_TX_PADA_SLOPE 0x4E +#define B2056_TX_PADG_MASTER 0x4F +#define B2056_TX_PADG_IDAC 0x50 +#define B2056_TX_PADG_CASCBIAS 0x51 +#define B2056_TX_PADG_GAIN 0x52 +#define B2056_TX_PADG_BOOST_TUNE 0x53 +#define B2056_TX_PADG_SLOPE 0x54 +#define B2056_TX_PGAA_MASTER 0x55 +#define B2056_TX_PGAA_IDAC 0x56 +#define B2056_TX_PGAA_GAIN 0x57 +#define B2056_TX_PGAA_BOOST_TUNE 0x58 +#define B2056_TX_PGAA_SLOPE 0x59 +#define B2056_TX_PGAA_MISC 0x5A +#define B2056_TX_PGAG_MASTER 0x5B +#define B2056_TX_PGAG_IDAC 0x5C +#define B2056_TX_PGAG_GAIN 0x5D +#define B2056_TX_PGAG_BOOST_TUNE 0x5E +#define B2056_TX_PGAG_SLOPE 0x5F +#define B2056_TX_PGAG_MISC 0x60 +#define B2056_TX_MIXA_MASTER 0x61 +#define B2056_TX_MIXA_BOOST_TUNE 0x62 +#define B2056_TX_MIXG 0x63 +#define B2056_TX_MIXG_BOOST_TUNE 0x64 +#define B2056_TX_BB_GM_MASTER 0x65 +#define B2056_TX_GMBB_GM 0x66 +#define B2056_TX_GMBB_IDAC 0x67 +#define B2056_TX_TXLPF_MASTER 0x68 +#define B2056_TX_TXLPF_RCCAL 0x69 +#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A +#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B +#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C +#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D +#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E +#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F +#define B2056_TX_TXLPF_RCCAL_OFF6 0x70 +#define B2056_TX_TXLPF_BW 0x71 +#define B2056_TX_TXLPF_GAIN 0x72 +#define B2056_TX_TXLPF_IDAC 0x73 +#define B2056_TX_TXLPF_IDAC_0 0x74 +#define B2056_TX_TXLPF_IDAC_1 0x75 +#define B2056_TX_TXLPF_IDAC_2 0x76 +#define B2056_TX_TXLPF_IDAC_3 0x77 +#define B2056_TX_TXLPF_IDAC_4 0x78 +#define B2056_TX_TXLPF_IDAC_5 0x79 +#define B2056_TX_TXLPF_IDAC_6 0x7A +#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B +#define B2056_TX_TXLPF_MISC 0x7C +#define B2056_TX_TXSPARE1 0x7D +#define B2056_TX_TXSPARE2 0x7E +#define B2056_TX_TXSPARE3 0x7F +#define B2056_TX_TXSPARE4 0x80 +#define B2056_TX_TXSPARE5 0x81 +#define B2056_TX_TXSPARE6 0x82 +#define B2056_TX_TXSPARE7 0x83 +#define B2056_TX_TXSPARE8 0x84 +#define B2056_TX_TXSPARE9 0x85 +#define B2056_TX_TXSPARE10 0x86 +#define B2056_TX_TXSPARE11 0x87 +#define B2056_TX_TXSPARE12 0x88 +#define B2056_TX_TXSPARE13 0x89 +#define B2056_TX_TXSPARE14 0x8A +#define B2056_TX_TXSPARE15 0x8B +#define B2056_TX_TXSPARE16 0x8C +#define B2056_TX_STATUS_INTPA_GAIN 0x8D +#define B2056_TX_STATUS_PAD_GAIN 0x8E +#define B2056_TX_STATUS_PGA_GAIN 0x8F +#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90 +#define B2056_TX_STATUS_TXLPF_BW 0x91 +#define B2056_TX_STATUS_TXLPF_RC 0x92 +#define B2056_TX_GMBB_IDAC0 0x93 +#define B2056_TX_GMBB_IDAC1 0x94 +#define B2056_TX_GMBB_IDAC2 0x95 +#define B2056_TX_GMBB_IDAC3 0x96 +#define B2056_TX_GMBB_IDAC4 0x97 +#define B2056_TX_GMBB_IDAC5 0x98 +#define B2056_TX_GMBB_IDAC6 0x99 +#define B2056_TX_GMBB_IDAC7 0x9A + +#define B2056_RX_RESERVED_ADDR0 0x00 +#define B2056_RX_IDCODE 0x01 +#define B2056_RX_RESERVED_ADDR2 0x02 +#define B2056_RX_RESERVED_ADDR3 0x03 +#define B2056_RX_RESERVED_ADDR4 0x04 +#define B2056_RX_RESERVED_ADDR5 0x05 +#define B2056_RX_RESERVED_ADDR6 0x06 +#define B2056_RX_RESERVED_ADDR7 0x07 +#define B2056_RX_COM_CTRL 0x08 +#define B2056_RX_COM_PU 0x09 +#define B2056_RX_COM_OVR 0x0A +#define B2056_RX_COM_RESET 0x0B +#define B2056_RX_COM_RCAL 0x0C +#define B2056_RX_COM_RC_RXLPF 0x0D +#define B2056_RX_COM_RC_TXLPF 0x0E +#define B2056_RX_COM_RC_RXHPF 0x0F +#define B2056_RX_RESERVED_ADDR16 0x10 +#define B2056_RX_RESERVED_ADDR17 0x11 +#define B2056_RX_RESERVED_ADDR18 0x12 +#define B2056_RX_RESERVED_ADDR19 0x13 +#define B2056_RX_RESERVED_ADDR20 0x14 +#define B2056_RX_RESERVED_ADDR21 0x15 +#define B2056_RX_RESERVED_ADDR22 0x16 +#define B2056_RX_RESERVED_ADDR23 0x17 +#define B2056_RX_RESERVED_ADDR24 0x18 +#define B2056_RX_RESERVED_ADDR25 0x19 +#define B2056_RX_RESERVED_ADDR26 0x1A +#define B2056_RX_RESERVED_ADDR27 0x1B +#define B2056_RX_RESERVED_ADDR28 0x1C +#define B2056_RX_RESERVED_ADDR29 0x1D +#define B2056_RX_RESERVED_ADDR30 0x1E +#define B2056_RX_RESERVED_ADDR31 0x1F +#define B2056_RX_RXIQCAL_RXMUX 0x20 +#define B2056_RX_RSSI_PU 0x21 +#define B2056_RX_RSSI_SEL 0x22 +#define B2056_RX_RSSI_GAIN 0x23 +#define B2056_RX_RSSI_NB_IDAC 0x24 +#define B2056_RX_RSSI_WB2I_IDAC_1 0x25 +#define B2056_RX_RSSI_WB2I_IDAC_2 0x26 +#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27 +#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28 +#define B2056_RX_RSSI_POLE 0x29 +#define B2056_RX_RSSI_WB1_IDAC 0x2A +#define B2056_RX_RSSI_MISC 0x2B +#define B2056_RX_LNAA_MASTER 0x2C +#define B2056_RX_LNAA_TUNE 0x2D +#define B2056_RX_LNAA_GAIN 0x2E +#define B2056_RX_LNA_A_SLOPE 0x2F +#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30 +#define B2056_RX_LNAA2_IDAC 0x31 +#define B2056_RX_LNA1A_MISC 0x32 +#define B2056_RX_LNAG_MASTER 0x33 +#define B2056_RX_LNAG_TUNE 0x34 +#define B2056_RX_LNAG_GAIN 0x35 +#define B2056_RX_LNA_G_SLOPE 0x36 +#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37 +#define B2056_RX_LNAG2_IDAC 0x38 +#define B2056_RX_LNA1G_MISC 0x39 +#define B2056_RX_MIXA_MASTER 0x3A +#define B2056_RX_MIXA_VCM 0x3B +#define B2056_RX_MIXA_CTRLPTAT 0x3C +#define B2056_RX_MIXA_LOB_BIAS 0x3D +#define B2056_RX_MIXA_CORE_IDAC 0x3E +#define B2056_RX_MIXA_CMFB_IDAC 0x3F +#define B2056_RX_MIXA_BIAS_AUX 0x40 +#define B2056_RX_MIXA_BIAS_MAIN 0x41 +#define B2056_RX_MIXA_BIAS_MISC 0x42 +#define B2056_RX_MIXA_MAST_BIAS 0x43 +#define B2056_RX_MIXG_MASTER 0x44 +#define B2056_RX_MIXG_VCM 0x45 +#define B2056_RX_MIXG_CTRLPTAT 0x46 +#define B2056_RX_MIXG_LOB_BIAS 0x47 +#define B2056_RX_MIXG_CORE_IDAC 0x48 +#define B2056_RX_MIXG_CMFB_IDAC 0x49 +#define B2056_RX_MIXG_BIAS_AUX 0x4A +#define B2056_RX_MIXG_BIAS_MAIN 0x4B +#define B2056_RX_MIXG_BIAS_MISC 0x4C +#define B2056_RX_MIXG_MAST_BIAS 0x4D +#define B2056_RX_TIA_MASTER 0x4E +#define B2056_RX_TIA_IOPAMP 0x4F +#define B2056_RX_TIA_QOPAMP 0x50 +#define B2056_RX_TIA_IMISC 0x51 +#define B2056_RX_TIA_QMISC 0x52 +#define B2056_RX_TIA_GAIN 0x53 +#define B2056_RX_TIA_SPARE1 0x54 +#define B2056_RX_TIA_SPARE2 0x55 +#define B2056_RX_BB_LPF_MASTER 0x56 +#define B2056_RX_AACI_MASTER 0x57 +#define B2056_RX_RXLPF_IDAC 0x58 +#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59 +#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A +#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B +#define B2056_RX_RXLPF_OUTVCM 0x5C +#define B2056_RX_RXLPF_INVCM_BODY 0x5D +#define B2056_RX_RXLPF_CC_OP 0x5E +#define B2056_RX_RXLPF_GAIN 0x5F +#define B2056_RX_RXLPF_Q_BW 0x60 +#define B2056_RX_RXLPF_HP_CORNER_BW 0x61 +#define B2056_RX_RXLPF_RCCAL_HPC 0x62 +#define B2056_RX_RXHPF_OFF0 0x63 +#define B2056_RX_RXHPF_OFF1 0x64 +#define B2056_RX_RXHPF_OFF2 0x65 +#define B2056_RX_RXHPF_OFF3 0x66 +#define B2056_RX_RXHPF_OFF4 0x67 +#define B2056_RX_RXHPF_OFF5 0x68 +#define B2056_RX_RXHPF_OFF6 0x69 +#define B2056_RX_RXHPF_OFF7 0x6A +#define B2056_RX_RXLPF_RCCAL_LPC 0x6B +#define B2056_RX_RXLPF_OFF_0 0x6C +#define B2056_RX_RXLPF_OFF_1 0x6D +#define B2056_RX_RXLPF_OFF_2 0x6E +#define B2056_RX_RXLPF_OFF_3 0x6F +#define B2056_RX_RXLPF_OFF_4 0x70 +#define B2056_RX_UNUSED 0x71 +#define B2056_RX_VGA_MASTER 0x72 +#define B2056_RX_VGA_BIAS 0x73 +#define B2056_RX_VGA_BIAS_DCCANCEL 0x74 +#define B2056_RX_VGA_GAIN 0x75 +#define B2056_RX_VGA_HP_CORNER_BW 0x76 +#define B2056_RX_VGABUF_BIAS 0x77 +#define B2056_RX_VGABUF_GAIN_BW 0x78 +#define B2056_RX_TXFBMIX_A 0x79 +#define B2056_RX_TXFBMIX_G 0x7A +#define B2056_RX_RXSPARE1 0x7B +#define B2056_RX_RXSPARE2 0x7C +#define B2056_RX_RXSPARE3 0x7D +#define B2056_RX_RXSPARE4 0x7E +#define B2056_RX_RXSPARE5 0x7F +#define B2056_RX_RXSPARE6 0x80 +#define B2056_RX_RXSPARE7 0x81 +#define B2056_RX_RXSPARE8 0x82 +#define B2056_RX_RXSPARE9 0x83 +#define B2056_RX_RXSPARE10 0x84 +#define B2056_RX_RXSPARE11 0x85 +#define B2056_RX_RXSPARE12 0x86 +#define B2056_RX_RXSPARE13 0x87 +#define B2056_RX_RXSPARE14 0x88 +#define B2056_RX_RXSPARE15 0x89 +#define B2056_RX_RXSPARE16 0x8A +#define B2056_RX_STATUS_LNAA_GAIN 0x8B +#define B2056_RX_STATUS_LNAG_GAIN 0x8C +#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D +#define B2056_RX_STATUS_RXLPF_GAIN 0x8E +#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F +#define B2056_RX_STATUS_RXLPF_Q 0x90 +#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91 +#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92 +#define B2056_RX_STATUS_RXLPF_RC 0x93 +#define B2056_RX_STATUS_HPC_RC 0x94 + +#define B2056_LNA1_A_PU 0x01 +#define B2056_LNA2_A_PU 0x02 +#define B2056_LNA1_G_PU 0x01 +#define B2056_LNA2_G_PU 0x02 +#define B2056_MIXA_PU_I 0x01 +#define B2056_MIXA_PU_Q 0x02 +#define B2056_MIXA_PU_GM 0x10 +#define B2056_MIXG_PU_I 0x01 +#define B2056_MIXG_PU_Q 0x02 +#define B2056_MIXG_PU_GM 0x10 +#define B2056_TIA_PU 0x01 +#define B2056_BB_LPF_PU 0x20 +#define B2056_W1_PU 0x02 +#define B2056_W2_PU 0x04 +#define B2056_NB_PU 0x08 +#define B2056_RSSI_W1_SEL 0x02 +#define B2056_RSSI_W2_SEL 0x04 +#define B2056_RSSI_NB_SEL 0x08 +#define B2056_VCM_MASK 0x1C +#define B2056_RSSI_VCM_SHIFT 0x02 + struct b43_nphy_channeltab_entry_rev3 { /* The channel frequency in MHz */ u16 freq; -- cgit v1.2.3-59-g8ed1b From 4df3071ebd92ef7115b409da64d0eb405d24a631 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 8 Nov 2010 20:54:47 +0100 Subject: ath9k_hw: optimize interrupt mask changes OProfile showed that ath9k was spending way too much time in ath9k_hw_set_interrupts. Since most of the interrupt mask changes only need to globally enable/disable interrupts, it makes sense to split this part into separate functions, replacing all calls to ath9k_hw_set_interrupts(ah, 0) with ath9k_hw_disable_interrupts(ah). ath9k_hw_set_interrupts(ah, ah->imask) only gets changed to ath9k_hw_enable_interrupts(ah), whenever ah->imask was not changed since the point where interrupts were disabled. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 6 +-- drivers/net/wireless/ath/ath9k/gpio.c | 4 +- drivers/net/wireless/ath/ath9k/mac.c | 86 +++++++++++++++++++-------------- drivers/net/wireless/ath/ath9k/mac.h | 6 ++- drivers/net/wireless/ath/ath9k/main.c | 18 +++---- 5 files changed, 68 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 19891e7d49ae..333da7bf2d7d 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -503,7 +503,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, /* Set the computed AP beacon timers */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, ah->imask); @@ -638,7 +638,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, /* Set the computed STA beacon timers */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath9k_hw_set_sta_beacon_timers(ah, &bs); ah->imask |= ATH9K_INT_BMISS; ath9k_hw_set_interrupts(ah, ah->imask); @@ -686,7 +686,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, /* Set the computed ADHOC beacon timers */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, ah->imask); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 4a9a68bba324..db9c6fed799c 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -259,7 +259,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah, ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ah->imask |= ATH9K_INT_GENTIMER; ath9k_hw_set_interrupts(ah, ah->imask); } @@ -273,7 +273,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) /* if no timer is enabled, turn off interrupt mask */ if (timer_table->timer_mask.val == 0) { - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ah->imask &= ~ATH9K_INT_GENTIMER; ath9k_hw_set_interrupts(ah, ah->imask); } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17cd..65b1ee2a9792 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) { u32 txcfg, curLevel, newLevel; - enum ath9k_int omask; if (ah->tx_trig_level >= ah->config.max_txtrig_level) return false; - omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL); + ath9k_hw_disable_interrupts(ah); txcfg = REG_READ(ah, AR_TXCFG); curLevel = MS(txcfg, AR_FTRIG); @@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) REG_WRITE(ah, AR_TXCFG, (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG)); - ath9k_hw_set_interrupts(ah, omask); + ath9k_hw_enable_interrupts(ah); ah->tx_trig_level = newLevel; @@ -849,28 +848,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_intrpend); -enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, - enum ath9k_int ints) +void ath9k_hw_disable_interrupts(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); + REG_WRITE(ah, AR_IER, AR_IER_DISABLE); + (void) REG_READ(ah, AR_IER); + if (!AR_SREV_9100(ah)) { + REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); + (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); + + REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); + (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); + } +} +EXPORT_SYMBOL(ath9k_hw_disable_interrupts); + +void ath9k_hw_enable_interrupts(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + if (!(ah->imask & ATH9K_INT_GLOBAL)) + return; + + ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); + REG_WRITE(ah, AR_IER, AR_IER_ENABLE); + if (!AR_SREV_9100(ah)) { + REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, + AR_INTR_MAC_IRQ); + REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); + + + REG_WRITE(ah, AR_INTR_SYNC_ENABLE, + AR_INTR_SYNC_DEFAULT); + REG_WRITE(ah, AR_INTR_SYNC_MASK, + AR_INTR_SYNC_DEFAULT); + } + ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", + REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); +} +EXPORT_SYMBOL(ath9k_hw_enable_interrupts); + +void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) { enum ath9k_int omask = ah->imask; u32 mask, mask2; struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); - ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); - - if (omask & ATH9K_INT_GLOBAL) { - ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); - REG_WRITE(ah, AR_IER, AR_IER_DISABLE); - (void) REG_READ(ah, AR_IER); - if (!AR_SREV_9100(ah)) { - REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); - (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); + if (!(ints & ATH9K_INT_GLOBAL)) + ath9k_hw_enable_interrupts(ah); - REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); - (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); - } - } + ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); /* TODO: global int Ref count */ mask = ints & ATH9K_INT_COMMON; @@ -946,24 +976,8 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); } - if (ints & ATH9K_INT_GLOBAL) { - ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); - REG_WRITE(ah, AR_IER, AR_IER_ENABLE); - if (!AR_SREV_9100(ah)) { - REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, - AR_INTR_MAC_IRQ); - REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); - - - REG_WRITE(ah, AR_INTR_SYNC_ENABLE, - AR_INTR_SYNC_DEFAULT); - REG_WRITE(ah, AR_INTR_SYNC_MASK, - AR_INTR_SYNC_DEFAULT); - } - ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", - REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); - } + ath9k_hw_enable_interrupts(ah); - return omask; + return; } EXPORT_SYMBOL(ath9k_hw_set_interrupts); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 7c1a34d64f6d..538c676e799c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -669,6 +669,7 @@ enum ath9k_key_type { struct ath_hw; struct ath9k_channel; +enum ath9k_int; u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); @@ -700,8 +701,9 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah); /* Interrupt Handling */ bool ath9k_hw_intrpend(struct ath_hw *ah); -enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, - enum ath9k_int ints); +void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); +void ath9k_hw_enable_interrupts(struct ath_hw *ah); +void ath9k_hw_disable_interrupts(struct ath_hw *ah); void ar9002_hw_attach_mac_ops(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b52f1cf8a603..ade9d7c16032 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -239,7 +239,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, false); spin_lock_bh(&sc->rx.pcu_lock); @@ -653,7 +653,7 @@ void ath9k_tasklet(unsigned long data) ath_gen_timer_isr(sc->sc_ah); /* re-enable hardware interrupt */ - ath9k_hw_set_interrupts(ah, ah->imask); + ath9k_hw_enable_interrupts(ah); ath9k_ps_restore(sc); } @@ -752,7 +752,7 @@ irqreturn_t ath_isr(int irq, void *dev) * interrupt; otherwise it will continue to * fire. */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); /* * Let the hal handle the event. We assume * it will clear whatever condition caused @@ -761,7 +761,7 @@ irqreturn_t ath_isr(int irq, void *dev) spin_lock(&common->cc_lock); ath9k_hw_proc_mib_event(ah); spin_unlock(&common->cc_lock); - ath9k_hw_set_interrupts(ah, ah->imask); + ath9k_hw_enable_interrupts(ah); } if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) @@ -778,8 +778,8 @@ chip_reset: ath_debug_stat_interrupt(sc, status); if (sched) { - /* turn off every interrupt except SWBA */ - ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA)); + /* turn off every interrupt */ + ath9k_hw_disable_interrupts(ah); tasklet_schedule(&sc->intr_tq); } @@ -937,7 +937,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) } /* Disable interrupts */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, false); /* clear pending tx frames */ @@ -980,7 +980,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ieee80211_stop_queues(hw); - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, retry_tx); spin_lock_bh(&sc->rx.pcu_lock); @@ -1394,7 +1394,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) /* make sure h/w will not generate any interrupt * before setting the invalid flag. */ - ath9k_hw_set_interrupts(ah, 0); + ath9k_hw_disable_interrupts(ah); spin_lock_bh(&sc->rx.pcu_lock); if (!(sc->sc_flags & SC_OP_INVALID)) { -- cgit v1.2.3-59-g8ed1b From 45684c75f9aa80eb477465bddcf79c9ad95206c7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Oct 2010 20:03:29 +0200 Subject: ath9k_hw: small optimization in ar9002_hw_get_isr ah->config.rx_intr_mitigation does not need to be checked before checking the rx interrupt mask for AR_ISR_RXMINTR or AR_ISR_RXINTM, as those interrupts will be masked out if rx interrupt mitigation is disabled. Avoid reading AR_ISR_S5_S twice by reordering the code to be more concise. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 32 ++++++++++------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 50dda394f8be..f5ed73dac254 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -90,13 +90,10 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) *masked = isr & ATH9K_INT_COMMON; - if (ah->config.rx_intr_mitigation) { - if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) - *masked |= ATH9K_INT_RX; - } - - if (isr & (AR_ISR_RXOK | AR_ISR_RXERR)) + if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM | + AR_ISR_RXOK | AR_ISR_RXERR)) *masked |= ATH9K_INT_RX; + if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL)) { @@ -118,14 +115,6 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) "receive FIFO overrun interrupt\n"); } - if (!AR_SREV_9100(ah)) { - if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { - u32 isr5 = REG_READ(ah, AR_ISR_S5_S); - if (isr5 & AR_ISR_S5_TIM_TIMER) - *masked |= ATH9K_INT_TIM_TIMER; - } - } - *masked |= mask2; } @@ -136,17 +125,18 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) u32 s5_s; s5_s = REG_READ(ah, AR_ISR_S5_S); - if (isr & AR_ISR_GENTMR) { - ah->intr_gen_timer_trigger = + ah->intr_gen_timer_trigger = MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); - ah->intr_gen_timer_thresh = - MS(s5_s, AR_ISR_S5_GENTIMER_THRESH); + ah->intr_gen_timer_thresh = + MS(s5_s, AR_ISR_S5_GENTIMER_THRESH); - if (ah->intr_gen_timer_trigger) - *masked |= ATH9K_INT_GENTIMER; + if (ah->intr_gen_timer_trigger) + *masked |= ATH9K_INT_GENTIMER; - } + if ((s5_s & AR_ISR_S5_TIM_TIMER) && + !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) + *masked |= ATH9K_INT_TIM_TIMER; } if (sync_cause) { -- cgit v1.2.3-59-g8ed1b From e0e9bc82fb0813fd353b0abbba0f1d6a680cc77c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Oct 2010 20:03:30 +0200 Subject: ath9k_hw: optimize tx status descriptor processing Disassembly shows, that at least on MIPS, the compiler generates a lot of memory accesses to the same location in the descriptor field parsing. Since it is operating on uncached memory, this can be quite expensive in this hot path. Change the code a bit to help the compiler optimize it properly, and get rid of some unused fields in the ath_tx_status struct. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 81 +++++++++++++---------------- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 69 ++++++++++++------------ drivers/net/wireless/ath/ath9k/mac.h | 3 -- 3 files changed, 72 insertions(+), 81 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index f5ed73dac254..3b4c52c9181c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -208,77 +208,68 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { struct ar5416_desc *ads = AR5416DESC(ds); + u32 status; - if ((ads->ds_txstatus9 & AR_TxDone) == 0) + status = ACCESS_ONCE(ads->ds_txstatus9); + if ((status & AR_TxDone) == 0) return -EINPROGRESS; - ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); ts->ts_tstamp = ads->AR_SendTimestamp; ts->ts_status = 0; ts->ts_flags = 0; - if (ads->ds_txstatus1 & AR_FrmXmitOK) + if (status & AR_TxOpExceeded) + ts->ts_status |= ATH9K_TXERR_XTXOP; + ts->tid = MS(status, AR_TxTid); + ts->ts_rateindex = MS(status, AR_FinalTxIdx); + ts->ts_seqnum = MS(status, AR_SeqNum); + + status = ACCESS_ONCE(ads->ds_txstatus0); + ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); + ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); + ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02); + if (status & AR_TxBaStatus) { + ts->ts_flags |= ATH9K_TX_BA; + ts->ba_low = ads->AR_BaBitmapLow; + ts->ba_high = ads->AR_BaBitmapHigh; + } + + status = ACCESS_ONCE(ads->ds_txstatus1); + if (status & AR_FrmXmitOK) ts->ts_status |= ATH9K_TX_ACKED; - if (ads->ds_txstatus1 & AR_ExcessiveRetries) + if (status & AR_ExcessiveRetries) ts->ts_status |= ATH9K_TXERR_XRETRY; - if (ads->ds_txstatus1 & AR_Filtered) + if (status & AR_Filtered) ts->ts_status |= ATH9K_TXERR_FILT; - if (ads->ds_txstatus1 & AR_FIFOUnderrun) { + if (status & AR_FIFOUnderrun) { ts->ts_status |= ATH9K_TXERR_FIFO; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->ds_txstatus9 & AR_TxOpExceeded) - ts->ts_status |= ATH9K_TXERR_XTXOP; - if (ads->ds_txstatus1 & AR_TxTimerExpired) + if (status & AR_TxTimerExpired) ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; - - if (ads->ds_txstatus1 & AR_DescCfgErr) + if (status & AR_DescCfgErr) ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; - if (ads->ds_txstatus1 & AR_TxDataUnderrun) { + if (status & AR_TxDataUnderrun) { ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { + if (status & AR_TxDelimUnderrun) { ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->ds_txstatus0 & AR_TxBaStatus) { - ts->ts_flags |= ATH9K_TX_BA; - ts->ba_low = ads->AR_BaBitmapLow; - ts->ba_high = ads->AR_BaBitmapHigh; - } + ts->ts_shortretry = MS(status, AR_RTSFailCnt); + ts->ts_longretry = MS(status, AR_DataFailCnt); + ts->ts_virtcol = MS(status, AR_VirtRetryCnt); - ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); - switch (ts->ts_rateindex) { - case 0: - ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); - break; - case 1: - ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); - break; - case 2: - ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); - break; - case 3: - ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); - break; - } + status = ACCESS_ONCE(ads->ds_txstatus5); + ts->ts_rssi = MS(status, AR_TxRSSICombined); + ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10); + ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); + ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); - ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); - ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); - ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); - ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); - ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); - ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); - ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); ts->evm0 = ads->AR_TxEVM0; ts->evm1 = ads->AR_TxEVM1; ts->evm2 = ads->AR_TxEVM2; - ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); - ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); - ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); - ts->tid = MS(ads->ds_txstatus9, AR_TxTid); - ts->ts_antenna = 0; return 0; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 3b424ca1ba84..10c812e353a6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -237,10 +237,12 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { struct ar9003_txs *ads; + u32 status; ads = &ah->ts_ring[ah->ts_tail]; - if ((ads->status8 & AR_TxDone) == 0) + status = ACCESS_ONCE(ads->status8); + if ((status & AR_TxDone) == 0) return -EINPROGRESS; ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; @@ -253,57 +255,58 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, return -EIO; } + if (status & AR_TxOpExceeded) + ts->ts_status |= ATH9K_TXERR_XTXOP; + ts->ts_rateindex = MS(status, AR_FinalTxIdx); + ts->ts_seqnum = MS(status, AR_SeqNum); + ts->tid = MS(status, AR_TxTid); + ts->qid = MS(ads->ds_info, AR_TxQcuNum); ts->desc_id = MS(ads->status1, AR_TxDescId); - ts->ts_seqnum = MS(ads->status8, AR_SeqNum); ts->ts_tstamp = ads->status4; ts->ts_status = 0; ts->ts_flags = 0; - if (ads->status3 & AR_ExcessiveRetries) + status = ACCESS_ONCE(ads->status2); + ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); + ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); + ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02); + if (status & AR_TxBaStatus) { + ts->ts_flags |= ATH9K_TX_BA; + ts->ba_low = ads->status5; + ts->ba_high = ads->status6; + } + + status = ACCESS_ONCE(ads->status3); + if (status & AR_ExcessiveRetries) ts->ts_status |= ATH9K_TXERR_XRETRY; - if (ads->status3 & AR_Filtered) + if (status & AR_Filtered) ts->ts_status |= ATH9K_TXERR_FILT; - if (ads->status3 & AR_FIFOUnderrun) { + if (status & AR_FIFOUnderrun) { ts->ts_status |= ATH9K_TXERR_FIFO; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->status8 & AR_TxOpExceeded) - ts->ts_status |= ATH9K_TXERR_XTXOP; - if (ads->status3 & AR_TxTimerExpired) + if (status & AR_TxTimerExpired) ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; - - if (ads->status3 & AR_DescCfgErr) + if (status & AR_DescCfgErr) ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; - if (ads->status3 & AR_TxDataUnderrun) { + if (status & AR_TxDataUnderrun) { ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->status3 & AR_TxDelimUnderrun) { + if (status & AR_TxDelimUnderrun) { ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } - if (ads->status2 & AR_TxBaStatus) { - ts->ts_flags |= ATH9K_TX_BA; - ts->ba_low = ads->status5; - ts->ba_high = ads->status6; - } - - ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx); - - ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined); - ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00); - ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01); - ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02); - ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10); - ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11); - ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12); - ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt); - ts->ts_longretry = MS(ads->status3, AR_DataFailCnt); - ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt); - ts->ts_antenna = 0; - - ts->tid = MS(ads->status8, AR_TxTid); + ts->ts_shortretry = MS(status, AR_RTSFailCnt); + ts->ts_longretry = MS(status, AR_DataFailCnt); + ts->ts_virtcol = MS(status, AR_VirtRetryCnt); + + status = ACCESS_ONCE(ads->status7); + ts->ts_rssi = MS(status, AR_TxRSSICombined); + ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10); + ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); + ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); memset(ads, 0, sizeof(*ads)); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 538c676e799c..fdc25074ca1f 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -104,13 +104,11 @@ struct ath_tx_status { u32 ts_tstamp; u16 ts_seqnum; u8 ts_status; - u8 ts_ratecode; u8 ts_rateindex; int8_t ts_rssi; u8 ts_shortretry; u8 ts_longretry; u8 ts_virtcol; - u8 ts_antenna; u8 ts_flags; int8_t ts_rssi_ctl0; int8_t ts_rssi_ctl1; @@ -121,7 +119,6 @@ struct ath_tx_status { u8 qid; u16 desc_id; u8 tid; - u8 pad[2]; u32 ba_low; u32 ba_high; u32 evm0; -- cgit v1.2.3-59-g8ed1b From 9fa23e1741404207c414fad69212a8763c138bf0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Oct 2010 20:03:31 +0200 Subject: ath9k: optimize/fix ANI RSSI processing ANI needs the RSSI average only in station mode, and only for tracking the signal strength of beacons of the AP that it is connected to. Adjust the code to track on the beacon RSSI, and store the average of that in the ath_wiphy struct. With these changes, we can get rid of this extra station lookup in the rx path, which saves precious CPU cycles. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 6 +++-- drivers/net/wireless/ath/ath9k/recv.c | 38 ++++++++++---------------------- drivers/net/wireless/ath/ath9k/virtual.c | 1 + 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9b8e7e3fcebd..81fed83add7a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -270,7 +270,6 @@ struct ath_node { struct ath_atx_ac ac[WME_NUM_AC]; u16 maxampdu; u8 mpdudensity; - int last_rssi; }; #define AGGR_CLEANUP BIT(1) @@ -662,6 +661,7 @@ struct ath_wiphy { bool idle; int chan_idx; int chan_is_ht; + int last_rssi; }; void ath9k_tasklet(unsigned long data); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 95b41db0d86b..12f4fd79c907 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -703,6 +703,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; + struct ath_wiphy *aphy = hw->priv; struct ath_common *common; struct ath_hw *ah; int error = 0; @@ -752,6 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); sc->wiphy_scheduler_int = msecs_to_jiffies(500); + aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; ath_init_leds(sc); ath_start_rfkill_poll(sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ade9d7c16032..7185ef3a3bff 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -562,7 +562,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); - an->last_rssi = ATH_RSSI_DUMMY_MARKER; } } @@ -831,9 +830,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, } static void ath9k_bss_assoc_info(struct ath_softc *sc, + struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) { + struct ath_wiphy *aphy = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -857,6 +858,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_beacon_config(sc, vif); /* Reset rssi stats */ + aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_flags |= SC_OP_ANI_RUN; @@ -1998,7 +2000,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); - ath9k_bss_assoc_info(sc, vif, bss_conf); + ath9k_bss_assoc_info(sc, hw, vif, bss_conf); } mutex_unlock(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index fddb0129bb57..c04a940550bd 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -962,36 +962,23 @@ static void ath9k_process_rssi(struct ath_common *common, struct ieee80211_hdr *hdr, struct ath_rx_status *rx_stats) { + struct ath_wiphy *aphy = hw->priv; struct ath_hw *ah = common->ah; - struct ieee80211_sta *sta; - struct ath_node *an; - int last_rssi = ATH_RSSI_DUMMY_MARKER; + int last_rssi; __le16 fc; + if (ah->opmode != NL80211_IFTYPE_STATION) + return; + fc = hdr->frame_control; + if (!ieee80211_is_beacon(fc) || + compare_ether_addr(hdr->addr3, common->curbssid)) + return; - rcu_read_lock(); - /* - * XXX: use ieee80211_find_sta! This requires quite a bit of work - * under the current ath9k virtual wiphy implementation as we have - * no way of tying a vif to wiphy. Typically vifs are attached to - * at least one sdata of a wiphy on mac80211 but with ath9k virtual - * wiphy you'd have to iterate over every wiphy and each sdata. - */ - if (is_multicast_ether_addr(hdr->addr1)) - sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL); - else - sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1); - - if (sta) { - an = (struct ath_node *) sta->drv_priv; - if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && - !rx_stats->rs_moreaggr) - ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); - last_rssi = an->last_rssi; - } - rcu_read_unlock(); + if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) + ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi); + last_rssi = aphy->last_rssi; if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) rx_stats->rs_rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); @@ -999,8 +986,7 @@ static void ath9k_process_rssi(struct ath_common *common, rx_stats->rs_rssi = 0; /* Update Beacon RSSI, this is used by ANI. */ - if (ieee80211_is_beacon(fc)) - ah->stats.avgbrssi = rx_stats->rs_rssi; + ah->stats.avgbrssi = rx_stats->rs_rssi; } /* diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index ec7cf5ee56bc..cb6c48be1245 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc) aphy->sc = sc; aphy->hw = hw; sc->sec_wiphy[i] = aphy; + aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; spin_unlock_bh(&sc->wiphy_lock); memcpy(addr, common->macaddr, ETH_ALEN); -- cgit v1.2.3-59-g8ed1b From 8eb1dabbd10e067cff671935d3e0c819f8e80d54 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Oct 2010 20:03:32 +0200 Subject: ath9k: remove a redundant call to ath9k_hw_gettsf32 When the timer_next argument to ath9k_gen_timer_start is behind the tsf value, tsf + timer_period is used, which is what ath_btcoex_period_timer was setting it to. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index db9c6fed799c..6a1a482f9dc3 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -310,10 +310,8 @@ static void ath_btcoex_period_timer(unsigned long data) timer_period = is_btscan ? btcoex->btscan_no_stomp : btcoex->btcoex_no_stomp; - ath9k_gen_timer_start(ah, - btcoex->no_stomp_timer, - (ath9k_hw_gettsf32(ah) + - timer_period), timer_period * 10); + ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0, + timer_period * 10); btcoex->hw_timer_enabled = true; } -- cgit v1.2.3-59-g8ed1b From 744bcb42a1ff1b9200e82dd074468877e31ff161 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Oct 2010 20:03:33 +0200 Subject: ath9k_hw: make ath9k_hw_gettsf32 static It is now only used in hw.c Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 3 +-- drivers/net/wireless/ath/ath9k/hw.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index cc13ee117823..d37a8ad03d74 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2312,11 +2312,10 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask) return timer_table->gen_timer_index[b]; } -u32 ath9k_hw_gettsf32(struct ath_hw *ah) +static u32 ath9k_hw_gettsf32(struct ath_hw *ah) { return REG_READ(ah, AR_TSF_L32); } -EXPORT_SYMBOL(ath9k_hw_gettsf32); struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, void (*trigger)(void *), diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d032939768b0..e68204ae899c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -892,7 +892,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer); void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer); void ath_gen_timer_isr(struct ath_hw *hw); -u32 ath9k_hw_gettsf32(struct ath_hw *ah); void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); -- cgit v1.2.3-59-g8ed1b From 191d6a1186f65bc86c24b9d6d9d91acc155285ba Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 15 Oct 2010 13:27:49 -0700 Subject: ath9k: fix sparse complaint on aphy for debugfs This fixes this sparse complaint: CHECK drivers/net/wireless/ath/ath9k/debug.c drivers/net/wireless/ath/ath9k/debug.c:548:34: warning: symbol 'aphy' shadows an earlier one drivers/net/wireless/ath/ath9k/debug.c:491:26: originally declared here Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 43e71a944cb1..a4052711eca8 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -461,16 +461,16 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, /* Put variable-length stuff down here, and check for overflows. */ for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (aphy == NULL) + struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i]; + if (aphy_tmp == NULL) continue; - chan = aphy->hw->conf.channel; + chan = aphy_tmp->hw->conf.channel; len += snprintf(buf + len, sizeof(buf) - len, "secondary: %s (%s chan=%d ht=%d)\n", - wiphy_name(aphy->hw->wiphy), - ath_wiphy_state_str(aphy->state), + wiphy_name(aphy_tmp->hw->wiphy), + ath_wiphy_state_str(aphy_tmp->state), ieee80211_frequency_to_channel(chan->center_freq), - aphy->chan_is_ht); + aphy_tmp->chan_is_ht); } if (len > sizeof(buf)) len = sizeof(buf); -- cgit v1.2.3-59-g8ed1b From f0e94b479c987abef17eb18e5c8e0ed178d00cd4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 16 Oct 2010 00:36:17 +0200 Subject: ath9k: Convert to new PCI PM framework The ath9k driver uses the legacy PCI power management (suspend and resume) callbacks that apparently cause intermittent problems to happen (the adapter sometimes doesn't resume correctly on my Acer Ferrari One). Make it use the new PCI PM and let the PCI core code handle the PCI-specific details of power transitions. Signed-off-by: Rafael J. Wysocki Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 40 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index b5b651413e77..6605bc2c2036 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -247,34 +247,25 @@ static void ath_pci_remove(struct pci_dev *pdev) #ifdef CONFIG_PM -static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int ath_pci_suspend(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - return 0; } -static int ath_pci_resume(struct pci_dev *pdev) +static int ath_pci_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; u32 val; - int err; - - pci_restore_state(pdev); - - err = pci_enable_device(pdev); - if (err) - return err; /* * Suspend/Resume resets the PCI configuration space, so we have to @@ -293,7 +284,23 @@ static int ath_pci_resume(struct pci_dev *pdev) return 0; } -#endif /* CONFIG_PM */ +static const struct dev_pm_ops ath9k_pm_ops = { + .suspend = ath_pci_suspend, + .resume = ath_pci_resume, + .freeze = ath_pci_suspend, + .thaw = ath_pci_resume, + .poweroff = ath_pci_suspend, + .restore = ath_pci_resume, +}; + +#define ATH9K_PM_OPS (&ath9k_pm_ops) + +#else /* !CONFIG_PM */ + +#define ATH9K_PM_OPS NULL + +#endif /* !CONFIG_PM */ + MODULE_DEVICE_TABLE(pci, ath_pci_id_table); @@ -302,10 +309,7 @@ static struct pci_driver ath_pci_driver = { .id_table = ath_pci_id_table, .probe = ath_pci_probe, .remove = ath_pci_remove, -#ifdef CONFIG_PM - .suspend = ath_pci_suspend, - .resume = ath_pci_resume, -#endif /* CONFIG_PM */ + .driver.pm = ATH9K_PM_OPS, }; int ath_pci_init(void) -- cgit v1.2.3-59-g8ed1b From ada9f1cacb66b74a68254521bb5e3ca4eb8fa871 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 16 Oct 2010 01:01:48 +0200 Subject: ath9k_hw: optimize all descriptor access functions Because all of the descriptor data structures are marked as __packed, GCC assumes the worst case wrt. alignment and generates unaligned load/store instructions on MIPS for access to all fields. Since descriptors always have to be 4-byte-aligned, we can just mark the data structures with __aligned(4), which allows GCC to generate much more efficient code. Verified through disassembly and OProfile comparisons. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.h | 6 +++--- drivers/net/wireless/ath/ath9k/mac.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index 9f2cea70a840..45cc7e80436c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h @@ -65,7 +65,7 @@ struct ar9003_rxs { u32 status9; u32 status10; u32 status11; -} __packed; +} __packed __aligned(4); /* Transmit Control Descriptor */ struct ar9003_txc { @@ -93,7 +93,7 @@ struct ar9003_txc { u32 ctl21; /* DMA control 21 */ u32 ctl22; /* DMA control 22 */ u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */ -} __packed; +} __packed __aligned(4); struct ar9003_txs { u32 ds_info; @@ -105,7 +105,7 @@ struct ar9003_txs { u32 status6; u32 status7; u32 status8; -} __packed; +} __packed __aligned(4); void ar9003_hw_attach_mac_ops(struct ath_hw *hw); void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index fdc25074ca1f..22907e21cc46 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -237,7 +237,7 @@ struct ath_desc { u32 ds_ctl1; u32 ds_hw[20]; void *ds_vdata; -} __packed; +} __packed __aligned(4); #define ATH9K_TXDESC_CLRDMASK 0x0001 #define ATH9K_TXDESC_NOACK 0x0002 @@ -307,7 +307,7 @@ struct ar5416_desc { u32 status8; } rx; } u; -} __packed; +} __packed __aligned(4); #define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds)) #define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds)) -- cgit v1.2.3-59-g8ed1b From 123f5b8e6f411d342f2fc8a15c4d9349ace5074a Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 18 Oct 2010 11:37:17 +0530 Subject: ath9k: Remove the median function in rate control With the current rate control selection method the median function is nowhere used, so remove it. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 89978d71617f..1095e18b3627 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -381,25 +381,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = { static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate); -static inline int8_t median(int8_t a, int8_t b, int8_t c) -{ - if (a >= b) { - if (b >= c) - return b; - else if (a > c) - return c; - else - return a; - } else { - if (a >= c) - return a; - else if (b >= c) - return c; - else - return b; - } -} - static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, struct ath_rate_priv *ath_rc_priv) { -- cgit v1.2.3-59-g8ed1b From 3dd0923de491d72a041f82a9d0aaccc473fd2c42 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 19 Oct 2010 16:56:48 +0900 Subject: ath5k: Optimize descriptor alignment Similar to Felix Fietkau "ath9k_hw: optimize all descriptor access functions" (13db2a80244908833502189a24de82a856668b8a). Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h index b2adb2a281c2..2509d0bf037d 100644 --- a/drivers/net/wireless/ath/ath5k/desc.h +++ b/drivers/net/wireless/ath/ath5k/desc.h @@ -26,7 +26,7 @@ struct ath5k_hw_rx_ctl { u32 rx_control_0; /* RX control word 0 */ u32 rx_control_1; /* RX control word 1 */ -} __packed; +} __packed __aligned(4); /* RX control word 1 fields/flags */ #define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */ @@ -39,7 +39,7 @@ struct ath5k_hw_rx_ctl { struct ath5k_hw_rx_status { u32 rx_status_0; /* RX status word 0 */ u32 rx_status_1; /* RX status word 1 */ -} __packed; +} __packed __aligned(4); /* 5210/5211 */ /* RX status word 0 fields/flags */ @@ -129,7 +129,7 @@ enum ath5k_phy_error_code { struct ath5k_hw_2w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ u32 tx_control_1; /* TX control word 1 */ -} __packed; +} __packed __aligned(4); /* TX control word 0 fields/flags */ #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ @@ -185,7 +185,7 @@ struct ath5k_hw_4w_tx_ctl { u32 tx_control_1; /* TX control word 1 */ u32 tx_control_2; /* TX control word 2 */ u32 tx_control_3; /* TX control word 3 */ -} __packed; +} __packed __aligned(4); /* TX control word 0 fields/flags */ #define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ @@ -244,7 +244,7 @@ struct ath5k_hw_4w_tx_ctl { struct ath5k_hw_tx_status { u32 tx_status_0; /* TX status word 0 */ u32 tx_status_1; /* TX status word 1 */ -} __packed; +} __packed __aligned(4); /* TX status word 0 fields/flags */ #define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */ @@ -282,7 +282,7 @@ struct ath5k_hw_tx_status { struct ath5k_hw_5210_tx_desc { struct ath5k_hw_2w_tx_ctl tx_ctl; struct ath5k_hw_tx_status tx_stat; -} __packed; +} __packed __aligned(4); /* * 5212 hardware TX descriptor @@ -290,7 +290,7 @@ struct ath5k_hw_5210_tx_desc { struct ath5k_hw_5212_tx_desc { struct ath5k_hw_4w_tx_ctl tx_ctl; struct ath5k_hw_tx_status tx_stat; -} __packed; +} __packed __aligned(4); /* * Common hardware RX descriptor @@ -298,7 +298,7 @@ struct ath5k_hw_5212_tx_desc { struct ath5k_hw_all_rx_desc { struct ath5k_hw_rx_ctl rx_ctl; struct ath5k_hw_rx_status rx_stat; -} __packed; +} __packed __aligned(4); /* * Atheros hardware DMA descriptor @@ -313,7 +313,7 @@ struct ath5k_desc { struct ath5k_hw_5212_tx_desc ds_tx5212; struct ath5k_hw_all_rx_desc ds_rx; } ud; -} __packed; +} __packed __aligned(4); #define AR5K_RXDESC_INTREQ 0x0020 -- cgit v1.2.3-59-g8ed1b From edb40a23c8dc5b5be219bf4561074b6233bba65f Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 19 Oct 2010 16:56:54 +0900 Subject: ath5k: Add channel time to survey data Include the channel utilization (busy, rx, tx) in the survey results. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8251946842e6..484aad5b11b5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3206,14 +3206,32 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, { struct ath5k_softc *sc = hw->priv; struct ieee80211_conf *conf = &hw->conf; + struct ath_common *common = ath5k_hw_common(sc->ah); + struct ath_cycle_counters *cc = &common->cc_survey; + unsigned int div = common->clockrate * 1000; - if (idx != 0) + if (idx != 0) return -ENOENT; survey->channel = conf->channel; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = sc->ah->ah_noise_floor; + spin_lock_bh(&common->cc_lock); + ath_hw_cycle_counters_update(common); + if (cc->cycles > 0) { + survey->filled |= SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + survey->channel_time += cc->cycles / div; + survey->channel_time_busy += cc->rx_busy / div; + survey->channel_time_rx += cc->rx_frame / div; + survey->channel_time_tx += cc->tx_frame / div; + } + memset(cc, 0, sizeof(*cc)); + spin_unlock_bh(&common->cc_lock); + return 0; } -- cgit v1.2.3-59-g8ed1b From 673483c7d3a25c43d1208bb07e3888bc5136e8cf Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Wed, 10 Nov 2010 09:29:45 +0000 Subject: qlge: Add firmware info to ethtool get regs. By default we add firmware information to ethtool get regs. Optionally firmware info can instead be sent to log. Signed-off-by: Jitendra Kalsaria Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 2 ++ drivers/net/qlge/qlge_dbg.c | 21 ++++++++++++++++++++- drivers/net/qlge/qlge_ethtool.c | 19 ++++++++++++++++--- drivers/net/qlge/qlge_mpi.c | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc63..b1e815127cde 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -2221,6 +2221,7 @@ int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data); int ql_unpause_mpi_risc(struct ql_adapter *qdev); int ql_pause_mpi_risc(struct ql_adapter *qdev); int ql_hard_reset_mpi_risc(struct ql_adapter *qdev); +int ql_soft_reset_mpi_risc(struct ql_adapter *qdev); int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf, u32 ram_addr, int word_count); int ql_core_dump(struct ql_adapter *qdev, @@ -2236,6 +2237,7 @@ int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control); int ql_mb_get_port_cfg(struct ql_adapter *qdev); int ql_mb_set_port_cfg(struct ql_adapter *qdev); int ql_wait_fifo_empty(struct ql_adapter *qdev); +void ql_get_dump(struct ql_adapter *qdev, void *buff); void ql_gen_reg_dump(struct ql_adapter *qdev, struct ql_reg_dump *mpi_coredump); netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev); diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index 4747492935ef..fca804f36d61 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c @@ -1317,9 +1317,28 @@ void ql_gen_reg_dump(struct ql_adapter *qdev, status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]); if (status) return; +} + +void ql_get_dump(struct ql_adapter *qdev, void *buff) +{ + /* + * If the dump has already been taken and is stored + * in our internal buffer and if force dump is set then + * just start the spool to dump it to the log file + * and also, take a snapshot of the general regs to + * to the user's buffer or else take complete dump + * to the user's buffer if force is not set. + */ - if (test_bit(QL_FRC_COREDUMP, &qdev->flags)) + if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) { + if (!ql_core_dump(qdev, buff)) + ql_soft_reset_mpi_risc(qdev); + else + netif_err(qdev, drv, qdev->ndev, "coredump failed!\n"); + } else { + ql_gen_reg_dump(qdev, buff); ql_get_core_dump(qdev); + } } /* Coredump to messages log file using separate worker thread */ diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 4892d64f4e05..8149cc9de4ca 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -375,7 +375,10 @@ static void ql_get_drvinfo(struct net_device *ndev, strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); drvinfo->n_stats = 0; drvinfo->testinfo_len = 0; - drvinfo->regdump_len = 0; + if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) + drvinfo->regdump_len = sizeof(struct ql_mpi_coredump); + else + drvinfo->regdump_len = sizeof(struct ql_reg_dump); drvinfo->eedump_len = 0; } @@ -547,7 +550,12 @@ static void ql_self_test(struct net_device *ndev, static int ql_get_regs_len(struct net_device *ndev) { - return sizeof(struct ql_reg_dump); + struct ql_adapter *qdev = netdev_priv(ndev); + + if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) + return sizeof(struct ql_mpi_coredump); + else + return sizeof(struct ql_reg_dump); } static void ql_get_regs(struct net_device *ndev, @@ -555,7 +563,12 @@ static void ql_get_regs(struct net_device *ndev, { struct ql_adapter *qdev = netdev_priv(ndev); - ql_gen_reg_dump(qdev, p); + ql_get_dump(qdev, p); + qdev->core_is_dumped = 0; + if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) + regs->len = sizeof(struct ql_mpi_coredump); + else + regs->len = sizeof(struct ql_reg_dump); } static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee164..100a462cc916 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -87,7 +87,7 @@ exit: return status; } -static int ql_soft_reset_mpi_risc(struct ql_adapter *qdev) +int ql_soft_reset_mpi_risc(struct ql_adapter *qdev) { int status; status = ql_write_mpi_reg(qdev, 0x00001010, 1); -- cgit v1.2.3-59-g8ed1b From 0c6202b3278b417444a59cecc59e6e5af04db7fd Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Wed, 10 Nov 2010 09:29:46 +0000 Subject: qlge: Version change to v1.00.00.27 Signed-off-by: Jitendra Kalsaria Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index b1e815127cde..bdb8fe868539 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -16,7 +16,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.25.00.00-01" +#define DRV_VERSION "v1.00.00.27.00.00-01" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ -- cgit v1.2.3-59-g8ed1b From f17a37c9b8c4b32c01e501a84fa6f30e344c6110 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 10 Nov 2010 21:20:07 +0100 Subject: dccp ccid-2: Ack Vector interface clean-up This patch brings the Ack Vector interface up to date. Its main purpose is to lay the basis for the subsequent patches of this set, which will use the new data structure fields and routines. There are no real algorithmic changes, rather an adaptation: (1) Replaced the static Ack Vector size (2) with a #define so that it can be adapted (with low loss / Ack Ratio, a value of 1 works, so 2 seems to be sufficient for the moment) and added a solution so that computing the ECN nonce will continue to work - even with larger Ack Vectors. (2) Replaced the #defines for Ack Vector states with a complete enum. (3) Replaced #defines to compute Ack Vector length and state with general purpose routines (inlines), and updated code to use these. (4) Added a `tail' field (conversion to circular buffer in subsequent patch). (5) Updated the (outdated) documentation for Ack Vector struct. (6) All sequence number containers now trimmed to 48 bits. (7) Removal of unused bits: * removed dccpav_ack_nonce from struct dccp_ackvec, since this is already redundantly stored in the `dccpavr_ack_nonce' (of Ack Vector record); * removed Elapsed Time for Ack Vectors (it was nowhere used); * replaced semantics of dccpavr_sent_len with dccpavr_ack_runlen, since the code needs to be able to remember the old run length; * reduced the de-/allocation routines (redundant / duplicate tests). Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 178 ++++++++++++++++++------------------------------- net/dccp/ackvec.h | 103 +++++++++++++++------------- net/dccp/ccids/ccid2.c | 13 ++-- net/dccp/input.c | 6 +- net/dccp/options.c | 1 + 5 files changed, 128 insertions(+), 173 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 92a6fcb40d7d..17bf10f96057 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -1,7 +1,8 @@ /* * net/dccp/ackvec.c * - * An implementation of the DCCP protocol + * An implementation of Ack Vectors for the DCCP protocol + * Copyright (c) 2007 University of Aberdeen, Scotland, UK * Copyright (c) 2005 Arnaldo Carvalho de Melo * * This program is free software; you can redistribute it and/or modify it @@ -23,24 +24,32 @@ static struct kmem_cache *dccp_ackvec_slab; static struct kmem_cache *dccp_ackvec_record_slab; -static struct dccp_ackvec_record *dccp_ackvec_record_new(void) +struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) { - struct dccp_ackvec_record *avr = - kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC); + struct dccp_ackvec *av = kmem_cache_zalloc(dccp_ackvec_slab, priority); + + if (av != NULL) { + av->av_buf_head = DCCPAV_MAX_ACKVEC_LEN - 1; + INIT_LIST_HEAD(&av->av_records); + } + return av; +} - if (avr != NULL) - INIT_LIST_HEAD(&avr->avr_node); +static void dccp_ackvec_purge_records(struct dccp_ackvec *av) +{ + struct dccp_ackvec_record *cur, *next; - return avr; + list_for_each_entry_safe(cur, next, &av->av_records, avr_node) + kmem_cache_free(dccp_ackvec_record_slab, cur); + INIT_LIST_HEAD(&av->av_records); } -static void dccp_ackvec_record_delete(struct dccp_ackvec_record *avr) +void dccp_ackvec_free(struct dccp_ackvec *av) { - if (unlikely(avr == NULL)) - return; - /* Check if deleting a linked record */ - WARN_ON(!list_empty(&avr->avr_node)); - kmem_cache_free(dccp_ackvec_record_slab, avr); + if (likely(av != NULL)) { + dccp_ackvec_purge_records(av); + kmem_cache_free(dccp_ackvec_slab, av); + } } static void dccp_ackvec_insert_avr(struct dccp_ackvec *av, @@ -68,24 +77,16 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; /* Figure out how many options do we need to represent the ackvec */ const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); - u16 len = av->av_vec_len + 2 * nr_opts, i; - u32 elapsed_time; + u16 len = av->av_vec_len + 2 * nr_opts; + u8 i, nonce = 0; const unsigned char *tail, *from; unsigned char *to; struct dccp_ackvec_record *avr; - suseconds_t delta; if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) return -1; - delta = ktime_us_delta(ktime_get_real(), av->av_time); - elapsed_time = delta / 10; - - if (elapsed_time != 0 && - dccp_insert_option_elapsed_time(skb, elapsed_time)) - return -1; - - avr = dccp_ackvec_record_new(); + avr = kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC); if (avr == NULL) return -1; @@ -94,7 +95,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) to = skb_push(skb, len); len = av->av_vec_len; from = av->av_buf + av->av_buf_head; - tail = av->av_buf + DCCP_MAX_ACKVEC_LEN; + tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; for (i = 0; i < nr_opts; ++i) { int copylen = len; @@ -102,7 +103,13 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) if (len > DCCP_SINGLE_OPT_MAXLEN) copylen = DCCP_SINGLE_OPT_MAXLEN; - *to++ = DCCPO_ACK_VECTOR_0; + /* + * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via + * its type; ack_nonce is the sum of all individual buf_nonce's. + */ + nonce ^= av->av_buf_nonce[i]; + + *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i]; *to++ = copylen + 2; /* Check if buf_head wraps */ @@ -123,75 +130,24 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) } /* - * From RFC 4340, A.2: - * - * For each acknowledgement it sends, the HC-Receiver will add an - * acknowledgement record. ack_seqno will equal the HC-Receiver - * sequence number it used for the ack packet; ack_ptr will equal - * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will - * equal buf_nonce. + * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. */ - avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq; - avr->avr_ack_ptr = av->av_buf_head; - avr->avr_ack_ackno = av->av_buf_ackno; - avr->avr_ack_nonce = av->av_buf_nonce; - avr->avr_sent_len = av->av_vec_len; + avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq; + avr->avr_ack_ptr = av->av_buf_head; + avr->avr_ack_ackno = av->av_buf_ackno; + avr->avr_ack_nonce = nonce; + avr->avr_ack_runlen = dccp_ackvec_runlen(av->av_buf + av->av_buf_head); dccp_ackvec_insert_avr(av, avr); dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, " "ack_ackno=%llu\n", - dccp_role(sk), avr->avr_sent_len, + dccp_role(sk), avr->avr_ack_runlen, (unsigned long long)avr->avr_ack_seqno, (unsigned long long)avr->avr_ack_ackno); return 0; } -struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) -{ - struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority); - - if (av != NULL) { - av->av_buf_head = DCCP_MAX_ACKVEC_LEN - 1; - av->av_buf_ackno = UINT48_MAX + 1; - av->av_buf_nonce = 0; - av->av_time = ktime_set(0, 0); - av->av_vec_len = 0; - INIT_LIST_HEAD(&av->av_records); - } - - return av; -} - -void dccp_ackvec_free(struct dccp_ackvec *av) -{ - if (unlikely(av == NULL)) - return; - - if (!list_empty(&av->av_records)) { - struct dccp_ackvec_record *avr, *next; - - list_for_each_entry_safe(avr, next, &av->av_records, avr_node) { - list_del_init(&avr->avr_node); - dccp_ackvec_record_delete(avr); - } - } - - kmem_cache_free(dccp_ackvec_slab, av); -} - -static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, - const u32 index) -{ - return av->av_buf[index] & DCCP_ACKVEC_STATE_MASK; -} - -static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, - const u32 index) -{ - return av->av_buf[index] & DCCP_ACKVEC_LEN_MASK; -} - /* * If several packets are missing, the HC-Receiver may prefer to enter multiple * bytes with run length 0, rather than a single byte with a larger run length; @@ -204,7 +160,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, long gap; long new_head; - if (av->av_vec_len + packets > DCCP_MAX_ACKVEC_LEN) + if (av->av_vec_len + packets > DCCPAV_MAX_ACKVEC_LEN) return -ENOBUFS; gap = packets - 1; @@ -212,18 +168,18 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, if (new_head < 0) { if (gap > 0) { - memset(av->av_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED, + memset(av->av_buf, DCCPAV_NOT_RECEIVED, gap + new_head + 1); gap = -new_head; } - new_head += DCCP_MAX_ACKVEC_LEN; + new_head += DCCPAV_MAX_ACKVEC_LEN; } av->av_buf_head = new_head; if (gap > 0) memset(av->av_buf + av->av_buf_head + 1, - DCCP_ACKVEC_STATE_NOT_RECEIVED, gap); + DCCPAV_NOT_RECEIVED, gap); av->av_buf[av->av_buf_head] = state; av->av_vec_len += packets; @@ -236,6 +192,8 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, const u64 ackno, const u8 state) { + u8 *cur_head = av->av_buf + av->av_buf_head, + *buf_end = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; /* * Check at the right places if the buffer is full, if it is, tell the * caller to start dropping packets till the HC-Sender acks our ACK @@ -260,7 +218,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, /* See if this is the first ackno being inserted */ if (av->av_vec_len == 0) { - av->av_buf[av->av_buf_head] = state; + *cur_head = state; av->av_vec_len = 1; } else if (after48(ackno, av->av_buf_ackno)) { const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno); @@ -269,10 +227,9 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, * Look if the state of this packet is the same as the * previous ackno and if so if we can bump the head len. */ - if (delta == 1 && - dccp_ackvec_state(av, av->av_buf_head) == state && - dccp_ackvec_len(av, av->av_buf_head) < DCCP_ACKVEC_LEN_MASK) - av->av_buf[av->av_buf_head]++; + if (delta == 1 && dccp_ackvec_state(cur_head) == state && + dccp_ackvec_runlen(cur_head) < DCCPAV_MAX_RUNLEN) + *cur_head += 1; else if (dccp_ackvec_set_buf_head_state(av, delta, state)) return -ENOBUFS; } else { @@ -285,21 +242,17 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, * could reduce the complexity of this scan.) */ u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno); - u32 index = av->av_buf_head; while (1) { - const u8 len = dccp_ackvec_len(av, index); - const u8 av_state = dccp_ackvec_state(av, index); + const u8 len = dccp_ackvec_runlen(cur_head); /* * valid packets not yet in av_buf have a reserved * entry, with a len equal to 0. */ - if (av_state == DCCP_ACKVEC_STATE_NOT_RECEIVED && - len == 0 && delta == 0) { /* Found our - reserved seat! */ + if (*cur_head == DCCPAV_NOT_RECEIVED && delta == 0) { dccp_pr_debug("Found %llu reserved seat!\n", (unsigned long long)ackno); - av->av_buf[index] = state; + *cur_head = state; goto out; } /* len == 0 means one packet */ @@ -307,13 +260,12 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, goto out_duplicate; delta -= len + 1; - if (++index == DCCP_MAX_ACKVEC_LEN) - index = 0; + if (++cur_head == buf_end) + cur_head = av->av_buf; } } av->av_buf_ackno = ackno; - av->av_time = ktime_get_real(); out: return 0; @@ -333,13 +285,13 @@ static void dccp_ackvec_throw_record(struct dccp_ackvec *av, if (av->av_buf_head <= avr->avr_ack_ptr) av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head; else - av->av_vec_len = DCCP_MAX_ACKVEC_LEN - 1 - + av->av_vec_len = DCCPAV_MAX_ACKVEC_LEN - 1 - av->av_buf_head + avr->avr_ack_ptr; /* free records */ list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { - list_del_init(&avr->avr_node); - dccp_ackvec_record_delete(avr); + list_del(&avr->avr_node); + kmem_cache_free(dccp_ackvec_record_slab, avr); } } @@ -357,7 +309,7 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, if (ackno == avr->avr_ack_seqno) { dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, " "ack_ackno=%llu, ACKED!\n", - dccp_role(sk), 1, + dccp_role(sk), avr->avr_ack_runlen, (unsigned long long)avr->avr_ack_seqno, (unsigned long long)avr->avr_ack_ackno); dccp_ackvec_throw_record(av, avr); @@ -387,7 +339,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, */ avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node); while (i--) { - const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; + const u8 rl = dccp_ackvec_runlen(vector); u64 ackno_end_rl; dccp_set_seqno(&ackno_end_rl, *ackno - rl); @@ -404,8 +356,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, break; found: if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) { - const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; - if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { + if (dccp_ackvec_state(vector) != DCCPAV_NOT_RECEIVED) { dccp_pr_debug("%s ACK vector 0, len=%d, " "ack_seqno=%llu, ack_ackno=%llu, " "ACKED!\n", @@ -448,10 +399,9 @@ int __init dccp_ackvec_init(void) if (dccp_ackvec_slab == NULL) goto out_err; - dccp_ackvec_record_slab = - kmem_cache_create("dccp_ackvec_record", - sizeof(struct dccp_ackvec_record), - 0, SLAB_HWCACHE_ALIGN, NULL); + dccp_ackvec_record_slab = kmem_cache_create("dccp_ackvec_record", + sizeof(struct dccp_ackvec_record), + 0, SLAB_HWCACHE_ALIGN, NULL); if (dccp_ackvec_record_slab == NULL) goto out_destroy_slab; diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 7ea557b7c6b1..ebcbbc726cff 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -3,9 +3,9 @@ /* * net/dccp/ackvec.h * - * An implementation of the DCCP protocol + * An implementation of Ack Vectors for the DCCP protocol + * Copyright (c) 2007 University of Aberdeen, Scotland, UK * Copyright (c) 2005 Arnaldo Carvalho de Melo - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -13,75 +13,84 @@ #include #include -#include #include #include -/* We can spread an ack vector across multiple options */ -#define DCCP_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * 2) +/* + * Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN, + * the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1 + * will be sufficient for most cases of low Ack Ratios, using a value of 2 gives + * more headroom if Ack Ratio is higher or when the sender acknowledges slowly. + */ +#define DCCPAV_NUM_ACKVECS 2 +#define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS) /* Estimated minimum average Ack Vector length - used for updating MPS */ #define DCCPAV_MIN_OPTLEN 16 -#define DCCP_ACKVEC_STATE_RECEIVED 0 -#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6) -#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6) +enum dccp_ackvec_states { + DCCPAV_RECEIVED = 0x00, + DCCPAV_ECN_MARKED = 0x40, + DCCPAV_RESERVED = 0x80, + DCCPAV_NOT_RECEIVED = 0xC0 +}; +#define DCCPAV_MAX_RUNLEN 0x3F -#define DCCP_ACKVEC_STATE_MASK 0xC0 /* 11000000 */ -#define DCCP_ACKVEC_LEN_MASK 0x3F /* 00111111 */ +static inline u8 dccp_ackvec_runlen(const u8 *cell) +{ + return *cell & DCCPAV_MAX_RUNLEN; +} -/** struct dccp_ackvec - ack vector - * - * This data structure is the one defined in RFC 4340, Appendix A. - * - * @av_buf_head - circular buffer head - * @av_buf_tail - circular buffer tail - * @av_buf_ackno - ack # of the most recent packet acknowledgeable in the - * buffer (i.e. %av_buf_head) - * @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked - * by the buffer with State 0 - * - * Additionally, the HC-Receiver must keep some information about the - * Ack Vectors it has recently sent. For each packet sent carrying an - * Ack Vector, it remembers four variables: +static inline u8 dccp_ackvec_state(const u8 *cell) +{ + return *cell & ~DCCPAV_MAX_RUNLEN; +} + +/** struct dccp_ackvec - Ack Vector main data structure * - * @av_records - list of dccp_ackvec_record - * @av_ack_nonce - the one-bit sum of the ECN Nonces for all State 0. + * This implements a fixed-size circular buffer within an array and is largely + * based on Appendix A of RFC 4340. * - * @av_time - the time in usecs - * @av_buf - circular buffer of acknowledgeable packets + * @av_buf: circular buffer storage area + * @av_buf_head: head index; begin of live portion in @av_buf + * @av_buf_tail: tail index; first index _after_ the live portion in @av_buf + * @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf + * @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to + * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf + * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously) + * @av_veclen: length of the live portion of @av_buf */ struct dccp_ackvec { - u64 av_buf_ackno; - struct list_head av_records; - ktime_t av_time; + u8 av_buf[DCCPAV_MAX_ACKVEC_LEN]; u16 av_buf_head; + u16 av_buf_tail; + u64 av_buf_ackno:48; + bool av_buf_nonce[DCCPAV_NUM_ACKVECS]; + struct list_head av_records; u16 av_vec_len; - u8 av_buf_nonce; - u8 av_ack_nonce; - u8 av_buf[DCCP_MAX_ACKVEC_LEN]; }; -/** struct dccp_ackvec_record - ack vector record +/** struct dccp_ackvec_record - Records information about sent Ack Vectors * - * ACK vector record as defined in Appendix A of spec. + * These list entries define the additional information which the HC-Receiver + * keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A. * - * The list is sorted by avr_ack_seqno + * @avr_node: the list node in @av_records + * @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on + * @avr_ack_ackno: the Ack number that this record/Ack Vector refers to + * @avr_ack_ptr: pointer into @av_buf where this record starts + * @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending + * @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent * - * @avr_node - node in av_records - * @avr_ack_seqno - sequence number of the packet this record was sent on - * @avr_ack_ackno - sequence number being acknowledged - * @avr_ack_ptr - pointer into av_buf where this record starts - * @avr_ack_nonce - av_ack_nonce at the time this record was sent - * @avr_sent_len - lenght of the record in av_buf + * The list as a whole is sorted in descending order by @avr_ack_seqno. */ struct dccp_ackvec_record { struct list_head avr_node; - u64 avr_ack_seqno; - u64 avr_ack_ackno; + u64 avr_ack_seqno:48; + u64 avr_ack_ackno:48; u16 avr_ack_ptr; - u16 avr_sent_len; - u8 avr_ack_nonce; + u8 avr_ack_runlen; + u8 avr_ack_nonce:1; }; struct sock; diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 6576eae9e779..cb1b4a0d1877 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -513,8 +513,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) &vector, &veclen)) != -1) { /* go through this ack vector */ while (veclen--) { - const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; - u64 ackno_end_rl = SUB48(ackno, rl); + u64 ackno_end_rl = SUB48(ackno, dccp_ackvec_runlen(vector)); ccid2_pr_debug("ackvec start:%llu end:%llu\n", (unsigned long long)ackno, @@ -537,17 +536,15 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) * run length */ while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) { - const u8 state = *vector & - DCCP_ACKVEC_STATE_MASK; + const u8 state = dccp_ackvec_state(vector); /* new packet received or marked */ - if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED && + if (state != DCCPAV_NOT_RECEIVED && !seqp->ccid2s_acked) { - if (state == - DCCP_ACKVEC_STATE_ECN_MARKED) { + if (state == DCCPAV_ECN_MARKED) ccid2_congestion_event(sk, seqp); - } else + else ccid2_new_ack(sk, seqp, &maxincr); diff --git a/net/dccp/input.c b/net/dccp/input.c index 265985370fa1..c7aeeba859d4 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -378,8 +378,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, if (dp->dccps_hc_rx_ackvec != NULL && dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_seq, - DCCP_ACKVEC_STATE_RECEIVED)) + DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED)) goto discard; dccp_deliver_input_to_ccids(sk, skb); @@ -637,8 +636,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, if (dp->dccps_hc_rx_ackvec != NULL && dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_seq, - DCCP_ACKVEC_STATE_RECEIVED)) + DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED)) goto discard; dccp_deliver_input_to_ccids(sk, skb); diff --git a/net/dccp/options.c b/net/dccp/options.c index cd3061813009..799c6f4547cd 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -340,6 +340,7 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time) return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; } +/* FIXME: This function is currently not used anywhere */ int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) { const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); -- cgit v1.2.3-59-g8ed1b From 7d870936602533836bba821bd5c679c62c52a95f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 10 Nov 2010 21:21:02 +0100 Subject: dccp ccid-2: Separate internals of Ack Vectors from option-parsing code This patch * separates Ack Vector housekeeping code from option-insertion code; * shifts option-specific code from ackvec.c into options.c; * introduces a dedicated routine to take care of the Ack Vector records; * simplifies the dccp_ackvec_insert_avr() routine: the BUG_ON was redundant, since the list is automatically arranged in descending order of ack_seqno. Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 100 ++++++++++------------------------------------------- net/dccp/ackvec.h | 2 +- net/dccp/options.c | 60 ++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 83 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 17bf10f96057..af976fca407a 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -52,99 +52,35 @@ void dccp_ackvec_free(struct dccp_ackvec *av) } } -static void dccp_ackvec_insert_avr(struct dccp_ackvec *av, - struct dccp_ackvec_record *avr) -{ - /* - * AVRs are sorted by seqno. Since we are sending them in order, we - * just add the AVR at the head of the list. - * -sorbo. - */ - if (!list_empty(&av->av_records)) { - const struct dccp_ackvec_record *head = - list_entry(av->av_records.next, - struct dccp_ackvec_record, - avr_node); - BUG_ON(before48(avr->avr_ack_seqno, head->avr_ack_seqno)); - } - - list_add(&avr->avr_node, &av->av_records); -} - -int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) +/** + * dccp_ackvec_update_records - Record information about sent Ack Vectors + * @av: Ack Vector records to update + * @seqno: Sequence number of the packet carrying the Ack Vector just sent + * @nonce_sum: The sum of all buffer nonces contained in the Ack Vector + */ +int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) { - struct dccp_sock *dp = dccp_sk(sk); - struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; - /* Figure out how many options do we need to represent the ackvec */ - const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); - u16 len = av->av_vec_len + 2 * nr_opts; - u8 i, nonce = 0; - const unsigned char *tail, *from; - unsigned char *to; struct dccp_ackvec_record *avr; - if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) - return -1; - avr = kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC); if (avr == NULL) - return -1; - - DCCP_SKB_CB(skb)->dccpd_opt_len += len; - - to = skb_push(skb, len); - len = av->av_vec_len; - from = av->av_buf + av->av_buf_head; - tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; - - for (i = 0; i < nr_opts; ++i) { - int copylen = len; - - if (len > DCCP_SINGLE_OPT_MAXLEN) - copylen = DCCP_SINGLE_OPT_MAXLEN; - - /* - * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via - * its type; ack_nonce is the sum of all individual buf_nonce's. - */ - nonce ^= av->av_buf_nonce[i]; - - *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i]; - *to++ = copylen + 2; - - /* Check if buf_head wraps */ - if (from + copylen > tail) { - const u16 tailsize = tail - from; - - memcpy(to, from, tailsize); - to += tailsize; - len -= tailsize; - copylen -= tailsize; - from = av->av_buf; - } - - memcpy(to, from, copylen); - from += copylen; - to += copylen; - len -= copylen; - } + return -ENOBUFS; - /* - * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. - */ - avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq; + avr->avr_ack_seqno = seqno; avr->avr_ack_ptr = av->av_buf_head; avr->avr_ack_ackno = av->av_buf_ackno; - avr->avr_ack_nonce = nonce; + avr->avr_ack_nonce = nonce_sum; avr->avr_ack_runlen = dccp_ackvec_runlen(av->av_buf + av->av_buf_head); + /* + * Since GSS is incremented for each packet, the list is automatically + * arranged in descending order of @ack_seqno. + */ + list_add(&avr->avr_node, &av->av_records); - dccp_ackvec_insert_avr(av, avr); - - dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, " - "ack_ackno=%llu\n", - dccp_role(sk), avr->avr_ack_runlen, + dccp_pr_debug("Added Vector, ack_seqno=%llu, ack_ackno=%llu (rl=%u)\n", (unsigned long long)avr->avr_ack_seqno, - (unsigned long long)avr->avr_ack_ackno); + (unsigned long long)avr->avr_ack_ackno, + avr->avr_ack_runlen); return 0; } diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index ebcbbc726cff..3e894a0173a7 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -111,7 +111,7 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, u64 *ackno, const u8 opt, const u8 *value, const u8 len); -extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb); +extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) { diff --git a/net/dccp/options.c b/net/dccp/options.c index 799c6f4547cd..f4ff0a308269 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -425,6 +425,66 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp, return 0; } +static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) +{ + struct dccp_sock *dp = dccp_sk(sk); + struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; + /* Figure out how many options do we need to represent the ackvec */ + const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); + u16 len = av->av_vec_len + 2 * nr_opts; + u8 i, nonce = 0; + const unsigned char *tail, *from; + unsigned char *to; + + if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) + return -1; + + DCCP_SKB_CB(skb)->dccpd_opt_len += len; + + to = skb_push(skb, len); + len = av->av_vec_len; + from = av->av_buf + av->av_buf_head; + tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; + + for (i = 0; i < nr_opts; ++i) { + int copylen = len; + + if (len > DCCP_SINGLE_OPT_MAXLEN) + copylen = DCCP_SINGLE_OPT_MAXLEN; + + /* + * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via + * its type; ack_nonce is the sum of all individual buf_nonce's. + */ + nonce ^= av->av_buf_nonce[i]; + + *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i]; + *to++ = copylen + 2; + + /* Check if buf_head wraps */ + if (from + copylen > tail) { + const u16 tailsize = tail - from; + + memcpy(to, from, tailsize); + to += tailsize; + len -= tailsize; + copylen -= tailsize; + from = av->av_buf; + } + + memcpy(to, from, copylen); + from += copylen; + to += copylen; + len -= copylen; + } + /* + * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. + */ + if (dccp_ackvec_update_records(av, DCCP_SKB_CB(skb)->dccpd_seq, nonce)) + return -ENOBUFS; + return 0; +} + /** * dccp_insert_option_mandatory - Mandatory option (5.8.2) * Note that since we are using skb_push, this function needs to be called -- cgit v1.2.3-59-g8ed1b From b3d14bff12a38ad13a174eb0cc83d2ac7169eee4 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 10 Nov 2010 21:21:35 +0100 Subject: dccp ccid-2: Implementation of circular Ack Vector buffer with overflow handling This completes the implementation of a circular buffer for Ack Vectors, by extending the current (linear array-based) implementation. The changes are: (a) An `overflow' flag to deal with the case of overflow. As before, dynamic growth of the buffer will not be supported; but code will be added to deal robustly with overflowing Ack Vector buffers. (b) A `tail_seqno' field. When naively implementing the algorithm of Appendix A in RFC 4340, problems arise whenever subsequent Ack Vector records overlap, which can bring the entire run length calculation completely out of synch. (This is documented on http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/\ ack_vectors/tracking_tail_ackno/ .) (c) The buffer length is now computed dynamically (i.e. current fill level), as the span between head to tail. As a result, dccp_ackvec_pending() is now simpler - the #ifdef is no longer necessary since buf_empty is always true when IP_DCCP_ACKVEC is not configured. Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 31 ++++++++++++++++++++++++++++++- net/dccp/ackvec.h | 10 ++++++++-- net/dccp/dccp.h | 11 +++++++---- net/dccp/options.c | 10 +++++----- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index af976fca407a..abaf241c7353 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -29,7 +29,7 @@ struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) struct dccp_ackvec *av = kmem_cache_zalloc(dccp_ackvec_slab, priority); if (av != NULL) { - av->av_buf_head = DCCPAV_MAX_ACKVEC_LEN - 1; + av->av_buf_head = av->av_buf_tail = DCCPAV_MAX_ACKVEC_LEN - 1; INIT_LIST_HEAD(&av->av_records); } return av; @@ -71,6 +71,14 @@ int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) avr->avr_ack_ackno = av->av_buf_ackno; avr->avr_ack_nonce = nonce_sum; avr->avr_ack_runlen = dccp_ackvec_runlen(av->av_buf + av->av_buf_head); + /* + * When the buffer overflows, we keep no more than one record. This is + * the simplest way of disambiguating sender-Acks dating from before the + * overflow from sender-Acks which refer to after the overflow; a simple + * solution is preferable here since we are handling an exception. + */ + if (av->av_overflow) + dccp_ackvec_purge_records(av); /* * Since GSS is incremented for each packet, the list is automatically * arranged in descending order of @ack_seqno. @@ -84,6 +92,27 @@ int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) return 0; } +/* + * Buffer index and length computation using modulo-buffersize arithmetic. + * Note that, as pointers move from right to left, head is `before' tail. + */ +static inline u16 __ackvec_idx_add(const u16 a, const u16 b) +{ + return (a + b) % DCCPAV_MAX_ACKVEC_LEN; +} + +static inline u16 __ackvec_idx_sub(const u16 a, const u16 b) +{ + return __ackvec_idx_add(a, DCCPAV_MAX_ACKVEC_LEN - b); +} + +u16 dccp_ackvec_buflen(const struct dccp_ackvec *av) +{ + if (unlikely(av->av_overflow)) + return DCCPAV_MAX_ACKVEC_LEN; + return __ackvec_idx_sub(av->av_buf_tail, av->av_buf_head); +} + /* * If several packets are missing, the HC-Receiver may prefer to enter multiple * bytes with run length 0, rather than a single byte with a larger run length; diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 3e894a0173a7..23880be8fc29 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -21,6 +21,7 @@ * the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1 * will be sufficient for most cases of low Ack Ratios, using a value of 2 gives * more headroom if Ack Ratio is higher or when the sender acknowledges slowly. + * The maximum value is bounded by the u16 types for indices and functions. */ #define DCCPAV_NUM_ACKVECS 2 #define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS) @@ -55,8 +56,10 @@ static inline u8 dccp_ackvec_state(const u8 *cell) * @av_buf_head: head index; begin of live portion in @av_buf * @av_buf_tail: tail index; first index _after_ the live portion in @av_buf * @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf + * @av_tail_ackno: lowest seqno of acknowledgeable packet recorded in @av_buf * @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf + * @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously) * @av_veclen: length of the live portion of @av_buf */ @@ -65,7 +68,9 @@ struct dccp_ackvec { u16 av_buf_head; u16 av_buf_tail; u64 av_buf_ackno:48; + u64 av_tail_ackno:48; bool av_buf_nonce[DCCPAV_NUM_ACKVECS]; + u8 av_overflow:1; struct list_head av_records; u16 av_vec_len; }; @@ -112,9 +117,10 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, const u8 *value, const u8 len); extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); +extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av); -static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) +static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av) { - return av->av_vec_len; + return av->av_overflow == 0 && av->av_buf_head == av->av_buf_tail; } #endif /* _ACKVEC_H */ diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index a8ed459508b2..19fafd597465 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -457,12 +457,15 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) dp->dccps_awh = dp->dccps_gss; } +static inline int dccp_ackvec_pending(const struct sock *sk) +{ + return dccp_sk(sk)->dccps_hc_rx_ackvec != NULL && + !dccp_ackvec_is_empty(dccp_sk(sk)->dccps_hc_rx_ackvec); +} + static inline int dccp_ack_pending(const struct sock *sk) { - const struct dccp_sock *dp = dccp_sk(sk); - return (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || - inet_csk_ack_scheduled(sk); + return dccp_ackvec_pending(sk) || inet_csk_ack_scheduled(sk); } extern int dccp_feat_finalise_settings(struct dccp_sock *dp); diff --git a/net/dccp/options.c b/net/dccp/options.c index f4ff0a308269..5adeeed5e0d2 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -429,9 +429,10 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; + const u16 buflen = dccp_ackvec_buflen(av); /* Figure out how many options do we need to represent the ackvec */ - const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); - u16 len = av->av_vec_len + 2 * nr_opts; + const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN); + u16 len = buflen + 2 * nr_opts; u8 i, nonce = 0; const unsigned char *tail, *from; unsigned char *to; @@ -442,7 +443,7 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) DCCP_SKB_CB(skb)->dccpd_opt_len += len; to = skb_push(skb, len); - len = av->av_vec_len; + len = buflen; from = av->av_buf + av->av_buf_head; tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; @@ -580,8 +581,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb) if (dccp_insert_option_timestamp(skb)) return -1; - } else if (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && + } else if (dccp_ackvec_pending(sk) && dccp_insert_option_ackvec(sk, skb)) { return -1; } -- cgit v1.2.3-59-g8ed1b From 47f01db44b2470d9517848f6b73c75883ef5fda0 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:53 +0000 Subject: vxge: enable rxhash Enable RSS hashing and add ability to pass up the adapter calculated rx hash up the network stack (if feature is available). Add the ability to enable/disable feature via ethtool, which requires that the adapter is not running at the time. Other miscellaneous cleanups and fixes required to get RSS working. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 2 ++ drivers/net/vxge/vxge-config.h | 12 ++++----- drivers/net/vxge/vxge-ethtool.c | 35 ++++++++++++++++++++++++++ drivers/net/vxge/vxge-main.c | 54 ++++++++++++++++++++++++++--------------- drivers/net/vxge/vxge-main.h | 18 +++++++------- drivers/net/vxge/vxge-traffic.h | 28 --------------------- 6 files changed, 86 insertions(+), 63 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 906a3ca3676b..0a35ab1ee2e1 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -3204,6 +3204,8 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set( VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG, 0, &data0, &data1); + if (status != VXGE_HW_OK) + goto exit; data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) | VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3)); diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 5c00861b6c2c..5d7790558f44 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -1413,12 +1413,12 @@ enum vxge_hw_rth_algoritms { * See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get(). */ struct vxge_hw_rth_hash_types { - u8 hash_type_tcpipv4_en; - u8 hash_type_ipv4_en; - u8 hash_type_tcpipv6_en; - u8 hash_type_ipv6_en; - u8 hash_type_tcpipv6ex_en; - u8 hash_type_ipv6ex_en; + u8 hash_type_tcpipv4_en:1, + hash_type_ipv4_en:1, + hash_type_tcpipv6_en:1, + hash_type_ipv6_en:1, + hash_type_tcpipv6ex_en:1, + hash_type_ipv6ex_en:1; }; void vxge_hw_device_debug_set( diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index b67746eef923..f8fd8da4f173 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -1119,6 +1119,40 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) } } +static int vxge_set_flags(struct net_device *dev, u32 data) +{ + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + enum vxge_hw_status status; + + if (data & ~ETH_FLAG_RXHASH) + return -EOPNOTSUPP; + + if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en) + return 0; + + if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING)) + return -EINVAL; + + vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH); + + /* Enabling RTH requires some of the logic in vxge_device_register and a + * vpath reset. Due to these restrictions, only allow modification + * while the interface is down. + */ + status = vxge_reset_all_vpaths(vdev); + if (status != VXGE_HW_OK) { + vdev->devh->config.rth_en = !vdev->devh->config.rth_en; + return -EFAULT; + } + + if (vdev->devh->config.rth_en) + dev->features |= NETIF_F_RXHASH; + else + dev->features &= ~NETIF_F_RXHASH; + + return 0; +} + static const struct ethtool_ops vxge_ethtool_ops = { .get_settings = vxge_ethtool_gset, .set_settings = vxge_ethtool_sset, @@ -1140,6 +1174,7 @@ static const struct ethtool_ops vxge_ethtool_ops = { .phys_id = vxge_ethtool_idnic, .get_sset_count = vxge_ethtool_get_sset_count, .get_ethtool_stats = vxge_get_ethtool_stats, + .set_flags = vxge_set_flags, }; void vxge_initialize_ethtool_ops(struct net_device *ndev) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 813829f3d024..2f26c377e5d9 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -513,6 +513,13 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, else skb_checksum_none_assert(skb); + /* rth_hash_type and rth_it_hit are non-zero regardless of + * whether rss is enabled. Only the rth_value is zero/non-zero + * if rss is disabled/enabled, so key off of that. + */ + if (ext_info.rth_value) + skb->rxhash = ext_info.rth_value; + vxge_rx_complete(ring, skb, ext_info.vlan, pkt_length, &ext_info); @@ -1689,15 +1696,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) mtable[index] = index % vdev->no_of_vpath; } - /* Fill RTH hash types */ - hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4; - hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4; - hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6; - hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6; - hash_types.hash_type_tcpipv6ex_en = - vdev->config.rth_hash_type_tcpipv6ex; - hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex; - /* set indirection table, bucket-to-vpath mapping */ status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles, vdev->no_of_vpath, @@ -1710,12 +1708,21 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) return status; } + /* Fill RTH hash types */ + hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4; + hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4; + hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6; + hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6; + hash_types.hash_type_tcpipv6ex_en = + vdev->config.rth_hash_type_tcpipv6ex; + hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex; + /* - * Because the itable_set() method uses the active_table field - * for the target virtual path the RTH config should be updated - * for all VPATHs. The h/w only uses the lowest numbered VPATH - * when steering frames. - */ + * Because the itable_set() method uses the active_table field + * for the target virtual path the RTH config should be updated + * for all VPATHs. The h/w only uses the lowest numbered VPATH + * when steering frames. + */ for (index = 0; index < vdev->no_of_vpath; index++) { status = vxge_hw_vpath_rts_rth_set( vdev->vpaths[index].handle, @@ -2598,6 +2605,8 @@ vxge_open(struct net_device *dev) goto out2; } } + printk(KERN_INFO "%s: Receive Hashing Offload %s\n", dev->name, + hldev->config.rth_en ? "enabled" : "disabled"); for (i = 0; i < vdev->no_of_vpath; i++) { vpath = &vdev->vpaths[i]; @@ -3178,6 +3187,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vxge_initialize_ethtool_ops(ndev); + if (vdev->config.rth_steering != NO_STEERING) { + ndev->features |= NETIF_F_RXHASH; + hldev->config.rth_en = VXGE_HW_RTH_ENABLE; + } + /* Allocate memory for vpath */ vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) * no_of_vpath, GFP_KERNEL); @@ -4163,12 +4177,12 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS; ll_config->addr_learn_en = addr_learn_en; ll_config->rth_algorithm = RTH_ALG_JENKINS; - ll_config->rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4; - ll_config->rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE; - ll_config->rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE; - ll_config->rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE; - ll_config->rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE; - ll_config->rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE; + ll_config->rth_hash_type_tcpipv4 = 1; + ll_config->rth_hash_type_ipv4 = 0; + ll_config->rth_hash_type_tcpipv6 = 0; + ll_config->rth_hash_type_ipv6 = 0; + ll_config->rth_hash_type_tcpipv6ex = 0; + ll_config->rth_hash_type_ipv6ex = 0; ll_config->rth_bkt_sz = RTH_BUCKET_SIZE; ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index de64536cb7d0..a4f6d864fc8e 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -145,15 +145,15 @@ struct vxge_config { int addr_learn_en; - int rth_steering; - int rth_algorithm; - int rth_hash_type_tcpipv4; - int rth_hash_type_ipv4; - int rth_hash_type_tcpipv6; - int rth_hash_type_ipv6; - int rth_hash_type_tcpipv6ex; - int rth_hash_type_ipv6ex; - int rth_bkt_sz; + u32 rth_steering:2, + rth_algorithm:2, + rth_hash_type_tcpipv4:1, + rth_hash_type_ipv4:1, + rth_hash_type_tcpipv6:1, + rth_hash_type_ipv6:1, + rth_hash_type_tcpipv6ex:1, + rth_hash_type_ipv6ex:1, + rth_bkt_sz:8; int rth_jhash_golden_ratio; int tx_steering_type; int fifo_indicate_max_pkts; diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 9890d4d596d0..1fceee876228 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -1904,34 +1904,6 @@ enum vxge_hw_ring_tcode { VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF }; -/** - * enum enum vxge_hw_ring_hash_type - RTH hash types - * @VXGE_HW_RING_HASH_TYPE_NONE: No Hash - * @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4 - * @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4 - * @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4 - * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6 - * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6 - * @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6 - * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension - * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension - * @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension - * - * RTH hash types - */ -enum vxge_hw_ring_hash_type { - VXGE_HW_RING_HASH_TYPE_NONE = 0x0, - VXGE_HW_RING_HASH_TYPE_TCP_IPV4 = 0x1, - VXGE_HW_RING_HASH_TYPE_UDP_IPV4 = 0x2, - VXGE_HW_RING_HASH_TYPE_IPV4 = 0x3, - VXGE_HW_RING_HASH_TYPE_TCP_IPV6 = 0x4, - VXGE_HW_RING_HASH_TYPE_UDP_IPV6 = 0x5, - VXGE_HW_RING_HASH_TYPE_IPV6 = 0x6, - VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX = 0x7, - VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX = 0x8, - VXGE_HW_RING_HASH_TYPE_IPV6_EX = 0x9 -}; - enum vxge_hw_status vxge_hw_ring_rxd_reserve( struct __vxge_hw_ring *ring_handle, void **rxdh); -- cgit v1.2.3-59-g8ed1b From 4d2a5b406c02b224bd3f50992c8b02450c65a730 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:54 +0000 Subject: vxge: Wait for Rx to become idle before reseting or closing Wait for the receive traffic to become idle before attempting to close or reset the adapter. To enable the processing of packets while Receive Idle, move the clearing of __VXGE_STATE_CARD_UP bit in vxge_close to after it. Also, modify the return value of the ISR when the adapter is down to IRQ_HANDLED. Otherwise there are unhandled interrupts for the device. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 86 ++++++++++++++++++++++++++++++++++++++++-- drivers/net/vxge/vxge-config.h | 7 ++++ drivers/net/vxge/vxge-main.c | 19 +++++++--- drivers/net/vxge/vxge-main.h | 2 + drivers/net/vxge/vxge-reg.h | 1 + 5 files changed, 106 insertions(+), 9 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 0a35ab1ee2e1..212e301bdd68 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -193,6 +193,88 @@ static enum vxge_hw_status __vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats); +static void +vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg) +{ + u64 val64; + + val64 = readq(&vp_reg->rxmac_vcfg0); + val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); + writeq(val64, &vp_reg->rxmac_vcfg0); + val64 = readq(&vp_reg->rxmac_vcfg0); + + return; +} + +/* + * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle + */ +int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id) +{ + struct vxge_hw_vpath_reg __iomem *vp_reg; + struct __vxge_hw_virtualpath *vpath; + u64 val64, rxd_count, rxd_spat; + int count = 0, total_count = 0; + + vpath = &hldev->virtual_paths[vp_id]; + vp_reg = vpath->vp_reg; + + vxge_hw_vpath_set_zero_rx_frm_len(vp_reg); + + /* Check that the ring controller for this vpath has enough free RxDs + * to send frames to the host. This is done by reading the + * PRC_RXD_DOORBELL_VPn register and comparing the read value to the + * RXD_SPAT value for the vpath. + */ + val64 = readq(&vp_reg->prc_cfg6); + rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1; + /* Use a factor of 2 when comparing rxd_count against rxd_spat for some + * leg room. + */ + rxd_spat *= 2; + + do { + mdelay(1); + + rxd_count = readq(&vp_reg->prc_rxd_doorbell); + + /* Check that the ring controller for this vpath does + * not have any frame in its pipeline. + */ + val64 = readq(&vp_reg->frm_in_progress_cnt); + if ((rxd_count <= rxd_spat) || (val64 > 0)) + count = 0; + else + count++; + total_count++; + } while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) && + (total_count < VXGE_HW_MAX_POLLING_COUNT)); + + if (total_count >= VXGE_HW_MAX_POLLING_COUNT) + printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n", + __func__); + + return total_count; +} + +/* vxge_hw_device_wait_receive_idle - This function waits until all frames + * stored in the frame buffer for each vpath assigned to the given + * function (hldev) have been sent to the host. + */ +void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev) +{ + int i, total_count = 0; + + for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!(hldev->vpaths_deployed & vxge_mBIT(i))) + continue; + + total_count += vxge_hw_vpath_wait_receive_idle(hldev, i); + if (total_count >= VXGE_HW_MAX_POLLING_COUNT) + break; + } +} + /* * __vxge_hw_channel_allocate - Allocate memory for channel * This function allocates required memory for the channel and various arrays @@ -390,7 +472,7 @@ __vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis) return ret; } - /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset +/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset * in progress * This routine checks the vpath reset in progress register is turned zero */ @@ -1165,7 +1247,6 @@ exit: * It can be used to set or reset Pause frame generation or reception * support of the NIC. */ - enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev, u32 port, u32 tx, u32 rx) { @@ -1409,7 +1490,6 @@ exit: /* * __vxge_hw_ring_create - Create a Ring * This function creates Ring and initializes it. - * */ static enum vxge_hw_status __vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 5d7790558f44..95e7021f88d8 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -2051,4 +2051,11 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set( enum vxge_hw_status __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id); + +#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5 +#define VXGE_HW_MAX_POLLING_COUNT 100 + +int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); + +void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev); #endif diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 2f26c377e5d9..53db6a4b9601 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -90,7 +90,6 @@ static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac); static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); -static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); static inline int is_vxge_card_up(struct vxgedev *vdev) { @@ -1299,8 +1298,13 @@ static void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id) static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) { struct vxge_vpath *vpath = &vdev->vpaths[vp_id]; + struct __vxge_hw_device *hldev; int msix_id; + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + + vxge_hw_vpath_wait_receive_idle(hldev, vpath->device_id); + vxge_hw_vpath_intr_disable(vpath->handle); if (vdev->config.intr_type == INTA) @@ -1430,6 +1434,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event) } if (event == VXGE_LL_FULL_RESET) { + vxge_hw_device_wait_receive_idle(vdev->devh); vxge_hw_device_intr_disable(vdev->devh); switch (vdev->cric_err_event) { @@ -1935,7 +1940,7 @@ static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath) } /* reset vpaths */ -static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) +enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) { enum vxge_hw_status status = VXGE_HW_OK; struct vxge_vpath *vpath; @@ -2080,7 +2085,7 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) return IRQ_NONE; if (unlikely(!is_vxge_card_up(vdev))) - return IRQ_NONE; + return IRQ_HANDLED; status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, &reason); @@ -2787,7 +2792,6 @@ static int do_vxge_close(struct net_device *dev, int do_io) while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) msleep(50); - clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); if (do_io) { /* Put the vpath back in normal mode */ vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id); @@ -2831,6 +2835,11 @@ static int do_vxge_close(struct net_device *dev, int do_io) del_timer_sync(&vdev->vp_reset_timer); + if (do_io) + vxge_hw_device_wait_receive_idle(hldev); + + clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); + /* Disable napi */ if (vdev->config.intr_type != MSI_X) napi_disable(&vdev->napi); @@ -2847,8 +2856,6 @@ static int do_vxge_close(struct net_device *dev, int do_io) if (do_io) vxge_hw_device_intr_disable(vdev->devh); - mdelay(1000); - vxge_rem_isr(vdev); vxge_napi_del_all(vdev); diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index a4f6d864fc8e..54989d07af34 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -397,6 +397,8 @@ struct vxge_tx_priv { } while (0); extern void vxge_initialize_ethtool_ops(struct net_device *ndev); +enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); + /** * #define VXGE_DEBUG_INIT: debug for initialization functions * #define VXGE_DEBUG_TX : debug transmit related functions diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h index 3dd5c9615ef9..93fd752187bc 100644 --- a/drivers/net/vxge/vxge-reg.h +++ b/drivers/net/vxge/vxge-reg.h @@ -3998,6 +3998,7 @@ struct vxge_hw_vpath_reg { #define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9) #define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9) #define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9) +#define VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val) vxge_bVALn(val, 36, 9) /*0x00a78*/ u64 prc_cfg7; #define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2) #define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11) -- cgit v1.2.3-59-g8ed1b From ddd62726e0bc1ffe0ab791b647f4178161ab451b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:55 +0000 Subject: vxge: cleanup debug printing and asserts Remove all of the unnecessary debug printk indirection and temporary variables for vxge_debug_ll and vxge_assert. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.h | 42 +++++++++--------------------------------- drivers/net/vxge/vxge-main.h | 2 -- 2 files changed, 9 insertions(+), 35 deletions(-) diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 95e7021f88d8..b395d8db318a 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -20,13 +20,6 @@ #define VXGE_CACHE_LINE_SIZE 128 #endif -#define vxge_os_vaprintf(level, mask, fmt, ...) { \ - char buff[255]; \ - snprintf(buff, 255, fmt, __VA_ARGS__); \ - printk(buff); \ - printk("\n"); \ -} - #ifndef VXGE_ALIGN #define VXGE_ALIGN(adrs, size) \ (((size) - (((u64)adrs) & ((size)-1))) & ((size)-1)) @@ -37,7 +30,6 @@ #define VXGE_HW_DEFAULT_MTU 1500 #ifdef VXGE_DEBUG_ASSERT - /** * vxge_assert * @test: C-condition to check @@ -48,16 +40,13 @@ * compilation * time. */ -#define vxge_assert(test) { \ - if (!(test)) \ - vxge_os_bug("bad cond: "#test" at %s:%d\n", \ - __FILE__, __LINE__); } +#define vxge_assert(test) BUG_ON(!(test)) #else #define vxge_assert(test) #endif /* end of VXGE_DEBUG_ASSERT */ /** - * enum enum vxge_debug_level + * enum vxge_debug_level * @VXGE_NONE: debug disabled * @VXGE_ERR: all errors going to be logged out * @VXGE_TRACE: all errors plus all kind of verbose tracing print outs @@ -2000,7 +1989,7 @@ enum vxge_hw_status vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask); /** - * vxge_debug + * vxge_debug_ll * @level: level of debug verbosity. * @mask: mask for the debug * @buf: Circular buffer for tracing @@ -2012,26 +2001,13 @@ vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask); * may be compiled out if DEBUG macro was never defined. * See also: enum vxge_debug_level{}. */ - -#define vxge_trace_aux(level, mask, fmt, ...) \ -{\ - vxge_os_vaprintf(level, mask, fmt, __VA_ARGS__);\ -} - -#define vxge_debug(module, level, mask, fmt, ...) { \ -if ((level >= VXGE_TRACE && ((module & VXGE_DEBUG_TRACE_MASK) == module)) || \ - (level >= VXGE_ERR && ((module & VXGE_DEBUG_ERR_MASK) == module))) {\ - if ((mask & VXGE_DEBUG_MASK) == mask)\ - vxge_trace_aux(level, mask, fmt, __VA_ARGS__); \ -} \ -} - #if (VXGE_COMPONENT_LL & VXGE_DEBUG_MODULE_MASK) -#define vxge_debug_ll(level, mask, fmt, ...) \ -{\ - vxge_debug(VXGE_COMPONENT_LL, level, mask, fmt, __VA_ARGS__);\ -} - +#define vxge_debug_ll(level, mask, fmt, ...) do { \ + if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ + (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ + if ((mask & VXGE_DEBUG_MASK) == mask) \ + printk(fmt "\n", __VA_ARGS__); \ +} while (0) #else #define vxge_debug_ll(level, mask, fmt, ...) #endif diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 54989d07af34..3845e628a597 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -387,8 +387,6 @@ struct vxge_tx_priv { static int p = val; \ module_param(p, int, 0) -#define vxge_os_bug(fmt...) { printk(fmt); BUG(); } - #define vxge_os_timer(timer, handle, arg, exp) do { \ init_timer(&timer); \ timer.function = handle; \ -- cgit v1.2.3-59-g8ed1b From 8424e00dfd5282026a93996a165fc4079d382169 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:56 +0000 Subject: vxge: serialize access to steering control register It is possible for multiple callers to access the firmware interface for the same vpath simultaneously, resulting in uncertain output. Add locks to serialize access. Also, make functions only accessed locally static, thus requiring some movement of code blocks. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 807 +++++++++++++++++------------------------ drivers/net/vxge/vxge-config.h | 1 + 2 files changed, 325 insertions(+), 483 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 212e301bdd68..c822463faf01 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -19,6 +19,7 @@ #include "vxge-traffic.h" #include "vxge-config.h" +#include "vxge-main.h" static enum vxge_hw_status __vxge_hw_fifo_create( @@ -103,12 +104,6 @@ __vxge_hw_device_id_get(struct __vxge_hw_device *hldev); static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev); -static enum vxge_hw_status -__vxge_hw_vpath_card_info_get( - u32 vp_id, - struct vxge_hw_vpath_reg __iomem *vpath_reg, - struct vxge_hw_device_hw_info *hw_info); - static enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev); @@ -153,17 +148,6 @@ vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vpath_handle); static enum vxge_hw_status __vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg); -static u64 -__vxge_hw_vpath_pci_func_mode_get(u32 vp_id, - struct vxge_hw_vpath_reg __iomem *vpath_reg); - -static u32 -__vxge_hw_vpath_func_id_get(u32 vp_id, struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg); - -static enum vxge_hw_status -__vxge_hw_vpath_addr_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, - u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN]); - static enum vxge_hw_status __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath); @@ -171,9 +155,6 @@ __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath); static enum vxge_hw_status __vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id); -static enum vxge_hw_status -__vxge_hw_vpath_fw_ver_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, - struct vxge_hw_device_hw_info *hw_info); static enum vxge_hw_status __vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id); @@ -275,6 +256,72 @@ void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev) } } +static enum vxge_hw_status +vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action, + u32 fw_memo, u32 offset, u64 *data0, u64 *data1, + u64 *steer_ctrl) +{ + struct vxge_hw_vpath_reg __iomem *vp_reg; + enum vxge_hw_status status; + u64 val64; + u32 retry = 0, max_retry = 100; + + vp_reg = vpath->vp_reg; + + if (vpath->vp_open) { + max_retry = 3; + spin_lock(&vpath->lock); + } + + writeq(*data0, &vp_reg->rts_access_steer_data0); + writeq(*data1, &vp_reg->rts_access_steer_data1); + wmb(); + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + *steer_ctrl; + + status = __vxge_hw_pio_mem_write64(val64, + &vp_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); + + /* The __vxge_hw_device_register_poll can udelay for a significant + * amount of time, blocking other proccess from the CPU. If it delays + * for ~5secs, a NMI error can occur. A way around this is to give up + * the processor via msleep, but this is not allowed is under lock. + * So, only allow it to sleep for ~4secs if open. Otherwise, delay for + * 1sec and sleep for 10ms until the firmware operation has completed + * or timed-out. + */ + while ((status != VXGE_HW_OK) && retry++ < max_retry) { + if (!vpath->vp_open) + msleep(20); + status = __vxge_hw_device_register_poll( + &vp_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); + } + + if (status != VXGE_HW_OK) + goto out; + + val64 = readq(&vp_reg->rts_access_steer_ctrl); + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { + *data0 = readq(&vp_reg->rts_access_steer_data0); + *data1 = readq(&vp_reg->rts_access_steer_data1); + *steer_ctrl = val64; + } else + status = VXGE_HW_FAIL; + +out: + if (vpath->vp_open) + spin_unlock(&vpath->lock); + return status; +} + /* * __vxge_hw_channel_allocate - Allocate memory for channel * This function allocates required memory for the channel and various arrays @@ -649,11 +696,26 @@ __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id) return VXGE_HW_ERR_PRIVILAGED_OPEARATION; } +/* + * __vxge_hw_vpath_func_id_get - Get the function id of the vpath. + * Returns the function number of the vpath. + */ +static u32 +__vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg) +{ + u64 val64; + + val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1); + + return + (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64); +} + /* * __vxge_hw_device_host_info_get * This routine returns the host type assignments */ -void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) +static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) { u64 val64; u32 i; @@ -666,16 +728,18 @@ void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments); for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!(hldev->vpath_assignments & vxge_mBIT(i))) continue; hldev->func_id = - __vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]); + __vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]); hldev->access_rights = __vxge_hw_device_access_rights_get( hldev->host_type, hldev->func_id); + hldev->virtual_paths[i].vp_open = VXGE_HW_VP_NOT_OPEN; + hldev->virtual_paths[i].vp_reg = hldev->vpath_reg[i]; + hldev->first_vp_id = i; break; } @@ -732,6 +796,192 @@ exit: return status; } +/* + * __vxge_hw_vpath_fw_ver_get - Get the fw version + * Returns FW Version + */ +static enum vxge_hw_status +__vxge_hw_vpath_fw_ver_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_device_hw_info *hw_info) +{ + struct vxge_hw_device_version *fw_version = &hw_info->fw_version; + struct vxge_hw_device_date *fw_date = &hw_info->fw_date; + struct vxge_hw_device_version *flash_version = &hw_info->flash_version; + struct vxge_hw_device_date *flash_date = &hw_info->flash_date; + u64 data0, data1 = 0, steer_ctrl = 0; + enum vxge_hw_status status; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + goto exit; + + fw_date->day = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(data0); + fw_date->month = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(data0); + fw_date->year = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(data0); + + snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", + fw_date->month, fw_date->day, fw_date->year); + + fw_version->major = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); + fw_version->minor = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); + fw_version->build = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); + + snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", + fw_version->major, fw_version->minor, fw_version->build); + + flash_date->day = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data1); + flash_date->month = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data1); + flash_date->year = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data1); + + snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", + flash_date->month, flash_date->day, flash_date->year); + + flash_version->major = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data1); + flash_version->minor = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data1); + flash_version->build = + (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data1); + + snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", + flash_version->major, flash_version->minor, + flash_version->build); + +exit: + return status; +} + +/* + * __vxge_hw_vpath_card_info_get - Get the serial numbers, + * part number and product description. + */ +static enum vxge_hw_status +__vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_device_hw_info *hw_info) +{ + enum vxge_hw_status status; + u64 data0, data1 = 0, steer_ctrl = 0; + u8 *serial_number = hw_info->serial_number; + u8 *part_number = hw_info->part_number; + u8 *product_desc = hw_info->product_desc; + u32 i, j = 0; + + data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + return status; + + ((u64 *)serial_number)[0] = be64_to_cpu(data0); + ((u64 *)serial_number)[1] = be64_to_cpu(data1); + + data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER; + data1 = steer_ctrl = 0; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + return status; + + ((u64 *)part_number)[0] = be64_to_cpu(data0); + ((u64 *)part_number)[1] = be64_to_cpu(data1); + + for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0; + i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) { + data0 = i; + data1 = steer_ctrl = 0; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + return status; + + ((u64 *)product_desc)[j++] = be64_to_cpu(data0); + ((u64 *)product_desc)[j++] = be64_to_cpu(data1); + } + + return status; +} + +/* + * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode + * Returns pci function mode + */ +static u64 +__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath) +{ + u64 data0, data1 = 0, steer_ctrl = 0; + enum vxge_hw_status status; + + data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); + + return data0; +} + +/* + * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath + * from MAC address table. + */ +static enum vxge_hw_status +__vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath, + u8 *macaddr, u8 *macaddr_mask) +{ + u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY, + data0 = 0, data1 = 0, steer_ctrl = 0; + enum vxge_hw_status status; + int i; + + do { + status = vxge_hw_vpath_fw_api(vpath, action, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + goto exit; + + data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data0); + data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK( + data1); + + for (i = ETH_ALEN; i > 0; i--) { + macaddr[i - 1] = (u8) (data0 & 0xFF); + data0 >>= 8; + + macaddr_mask[i - 1] = (u8) (data1 & 0xFF); + data1 >>= 8; + } + + action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY; + data0 = 0, data1 = 0, steer_ctrl = 0; + + } while (!is_valid_ether_addr(macaddr)); +exit: + return status; +} + /** * vxge_hw_device_hw_info_get - Get the hw information * Returns the vpath mask that has the bits set for each vpath allocated @@ -747,9 +997,9 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, struct vxge_hw_toc_reg __iomem *toc; struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg; struct vxge_hw_common_reg __iomem *common_reg; - struct vxge_hw_vpath_reg __iomem *vpath_reg; struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg; enum vxge_hw_status status; + struct __vxge_hw_virtualpath vpath; memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info)); @@ -784,7 +1034,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *) (bar0 + val64); - hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg); + hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg); if (__vxge_hw_device_access_rights_get(hw_info->host_type, hw_info->func_id) & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) { @@ -800,16 +1050,18 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpath_pointer[i]); - vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64); + vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) + (bar0 + val64); + vpath.vp_open = 0; hw_info->function_mode = - __vxge_hw_vpath_pci_func_mode_get(i, vpath_reg); + __vxge_hw_vpath_pci_func_mode_get(&vpath); - status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info); + status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info); if (status != VXGE_HW_OK) goto exit; - status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info); + status = __vxge_hw_vpath_card_info_get(&vpath, hw_info); if (status != VXGE_HW_OK) goto exit; @@ -817,14 +1069,15 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, } for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!((hw_info->vpath_mask) & vxge_mBIT(i))) continue; val64 = readq(&toc->toc_vpath_pointer[i]); - vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64); + vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) + (bar0 + val64); + vpath.vp_open = 0; - status = __vxge_hw_vpath_addr_get(i, vpath_reg, + status = __vxge_hw_vpath_addr_get(&vpath, hw_info->mac_addrs[i], hw_info->mac_addr_masks[i]); if (status != VXGE_HW_OK) @@ -896,7 +1149,6 @@ vxge_hw_device_initialize( nblocks++; for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!(hldev->vpath_assignments & vxge_mBIT(i))) continue; @@ -921,7 +1173,6 @@ vxge_hw_device_initialize( } status = __vxge_hw_device_initialize(hldev); - if (status != VXGE_HW_OK) { vxge_hw_device_terminate(hldev); goto exit; @@ -958,7 +1209,6 @@ vxge_hw_device_stats_get(struct __vxge_hw_device *hldev, enum vxge_hw_status status = VXGE_HW_OK; for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!(hldev->vpaths_deployed & vxge_mBIT(i)) || (hldev->virtual_paths[i].vp_open == VXGE_HW_VP_NOT_OPEN)) @@ -2755,297 +3005,6 @@ exit: return status; } -/* - * __vxge_hw_vpath_func_id_get - Get the function id of the vpath. - * Returns the function number of the vpath. - */ -static u32 -__vxge_hw_vpath_func_id_get(u32 vp_id, - struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg) -{ - u64 val64; - - val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1); - - return - (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64); -} - -/* - * __vxge_hw_read_rts_ds - Program RTS steering critieria - */ -static inline void -__vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg, - u64 dta_struct_sel) -{ - writeq(0, &vpath_reg->rts_access_steer_ctrl); - wmb(); - writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0); - writeq(0, &vpath_reg->rts_access_steer_data1); - wmb(); -} - - -/* - * __vxge_hw_vpath_card_info_get - Get the serial numbers, - * part number and product description. - */ -static enum vxge_hw_status -__vxge_hw_vpath_card_info_get( - u32 vp_id, - struct vxge_hw_vpath_reg __iomem *vpath_reg, - struct vxge_hw_device_hw_info *hw_info) -{ - u32 i, j; - u64 val64; - u64 data1 = 0ULL; - u64 data2 = 0ULL; - enum vxge_hw_status status = VXGE_HW_OK; - u8 *serial_number = hw_info->serial_number; - u8 *part_number = hw_info->part_number; - u8 *product_desc = hw_info->product_desc; - - __vxge_hw_read_rts_ds(vpath_reg, - VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - return status; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - data1 = readq(&vpath_reg->rts_access_steer_data0); - ((u64 *)serial_number)[0] = be64_to_cpu(data1); - - data2 = readq(&vpath_reg->rts_access_steer_data1); - ((u64 *)serial_number)[1] = be64_to_cpu(data2); - status = VXGE_HW_OK; - } else - *serial_number = 0; - - __vxge_hw_read_rts_ds(vpath_reg, - VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - return status; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - - data1 = readq(&vpath_reg->rts_access_steer_data0); - ((u64 *)part_number)[0] = be64_to_cpu(data1); - - data2 = readq(&vpath_reg->rts_access_steer_data1); - ((u64 *)part_number)[1] = be64_to_cpu(data2); - - status = VXGE_HW_OK; - - } else - *part_number = 0; - - j = 0; - - for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0; - i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) { - - __vxge_hw_read_rts_ds(vpath_reg, i); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - return status; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - - data1 = readq(&vpath_reg->rts_access_steer_data0); - ((u64 *)product_desc)[j++] = be64_to_cpu(data1); - - data2 = readq(&vpath_reg->rts_access_steer_data1); - ((u64 *)product_desc)[j++] = be64_to_cpu(data2); - - status = VXGE_HW_OK; - } else - *product_desc = 0; - } - - return status; -} - -/* - * __vxge_hw_vpath_fw_ver_get - Get the fw version - * Returns FW Version - */ -static enum vxge_hw_status -__vxge_hw_vpath_fw_ver_get( - u32 vp_id, - struct vxge_hw_vpath_reg __iomem *vpath_reg, - struct vxge_hw_device_hw_info *hw_info) -{ - u64 val64; - u64 data1 = 0ULL; - u64 data2 = 0ULL; - struct vxge_hw_device_version *fw_version = &hw_info->fw_version; - struct vxge_hw_device_date *fw_date = &hw_info->fw_date; - struct vxge_hw_device_version *flash_version = &hw_info->flash_version; - struct vxge_hw_device_date *flash_date = &hw_info->flash_date; - enum vxge_hw_status status = VXGE_HW_OK; - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - goto exit; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - - data1 = readq(&vpath_reg->rts_access_steer_data0); - data2 = readq(&vpath_reg->rts_access_steer_data1); - - fw_date->day = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY( - data1); - fw_date->month = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH( - data1); - fw_date->year = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR( - data1); - - snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", - fw_date->month, fw_date->day, fw_date->year); - - fw_version->major = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1); - fw_version->minor = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1); - fw_version->build = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1); - - snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", - fw_version->major, fw_version->minor, fw_version->build); - - flash_date->day = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2); - flash_date->month = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2); - flash_date->year = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2); - - snprintf(flash_date->date, VXGE_HW_FW_STRLEN, - "%2.2d/%2.2d/%4.4d", - flash_date->month, flash_date->day, flash_date->year); - - flash_version->major = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2); - flash_version->minor = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2); - flash_version->build = - (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2); - - snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", - flash_version->major, flash_version->minor, - flash_version->build); - - status = VXGE_HW_OK; - - } else - status = VXGE_HW_FAIL; -exit: - return status; -} - -/* - * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode - * Returns pci function mode - */ -static u64 -__vxge_hw_vpath_pci_func_mode_get( - u32 vp_id, - struct vxge_hw_vpath_reg __iomem *vpath_reg) -{ - u64 val64; - u64 data1 = 0ULL; - enum vxge_hw_status status = VXGE_HW_OK; - - __vxge_hw_read_rts_ds(vpath_reg, - VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - goto exit; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - data1 = readq(&vpath_reg->rts_access_steer_data0); - status = VXGE_HW_OK; - } else { - data1 = 0; - status = VXGE_HW_FAIL; - } -exit: - return data1; -} - /** * vxge_hw_device_flick_link_led - Flick (blink) link LED. * @hldev: HW device. @@ -3054,37 +3013,24 @@ exit: * Flicker the link LED. */ enum vxge_hw_status -vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, - u64 on_off) +vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off) { - u64 val64; - enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_hw_vpath_reg __iomem *vp_reg; + struct __vxge_hw_virtualpath *vpath; + u64 data0, data1 = 0, steer_ctrl = 0; + enum vxge_hw_status status; if (hldev == NULL) { status = VXGE_HW_ERR_INVALID_DEVICE; goto exit; } - vp_reg = hldev->vpath_reg[hldev->first_vp_id]; + vpath = &hldev->virtual_paths[hldev->first_vp_id]; - writeq(0, &vp_reg->rts_access_steer_ctrl); - wmb(); - writeq(on_off, &vp_reg->rts_access_steer_data0); - writeq(0, &vp_reg->rts_access_steer_data1); - wmb(); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vp_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); + data0 = on_off; + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + 0, &data0, &data1, &steer_ctrl); exit: return status; } @@ -3093,63 +3039,38 @@ exit: * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables */ enum vxge_hw_status -__vxge_hw_vpath_rts_table_get( - struct __vxge_hw_vpath_handle *vp, - u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2) +__vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, + u32 action, u32 rts_table, u32 offset, + u64 *data0, u64 *data1) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; - struct vxge_hw_vpath_reg __iomem *vp_reg; - - enum vxge_hw_status status = VXGE_HW_OK; + enum vxge_hw_status status; + u64 steer_ctrl = 0; if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - vpath = vp->vpath; - vp_reg = vpath->vp_reg; - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset); - if ((rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) || + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) || (rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) || + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) || (rts_table == - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) || + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) || (rts_table == - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) { - val64 = val64 | VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL; + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) { + steer_ctrl = VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL; } - status = __vxge_hw_pio_mem_write64(val64, - &vp_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - vpath->hldev->config.device_poll_millis); - + status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, + data0, data1, &steer_ctrl); if (status != VXGE_HW_OK) goto exit; - val64 = readq(&vp_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - - *data1 = readq(&vp_reg->rts_access_steer_data0); - - if ((rts_table == - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || - (rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) { - *data2 = readq(&vp_reg->rts_access_steer_data1); - } - status = VXGE_HW_OK; - } else - status = VXGE_HW_FAIL; + if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || + (rts_table != + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) + *data1 = 0; exit: return status; } @@ -3158,107 +3079,27 @@ exit: * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables */ enum vxge_hw_status -__vxge_hw_vpath_rts_table_set( - struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table, - u32 offset, u64 data1, u64 data2) +__vxge_hw_vpath_rts_table_set(struct __vxge_hw_vpath_handle *vp, u32 action, + u32 rts_table, u32 offset, u64 steer_data0, + u64 steer_data1) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_hw_vpath_reg __iomem *vp_reg; + u64 data0, data1 = 0, steer_ctrl = 0; + enum vxge_hw_status status; if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - vpath = vp->vpath; - vp_reg = vpath->vp_reg; - - writeq(data1, &vp_reg->rts_access_steer_data0); - wmb(); + data0 = steer_data0; if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || (rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) { - writeq(data2, &vp_reg->rts_access_steer_data1); - wmb(); - } + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) + data1 = steer_data1; - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset); - - status = __vxge_hw_pio_mem_write64(val64, - &vp_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - vpath->hldev->config.device_poll_millis); - - if (status != VXGE_HW_OK) - goto exit; - - val64 = readq(&vp_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) - status = VXGE_HW_OK; - else - status = VXGE_HW_FAIL; -exit: - return status; -} - -/* - * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath - * from MAC address table. - */ -static enum vxge_hw_status -__vxge_hw_vpath_addr_get( - u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, - u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN]) -{ - u32 i; - u64 val64; - u64 data1 = 0ULL; - u64 data2 = 0ULL; - enum vxge_hw_status status = VXGE_HW_OK; - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - - status = __vxge_hw_pio_mem_write64(val64, - &vpath_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - if (status != VXGE_HW_OK) - goto exit; - - val64 = readq(&vpath_reg->rts_access_steer_ctrl); - - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - - data1 = readq(&vpath_reg->rts_access_steer_data0); - data2 = readq(&vpath_reg->rts_access_steer_data1); - - data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1); - data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK( - data2); - - for (i = ETH_ALEN; i > 0; i--) { - macaddr[i-1] = (u8)(data1 & 0xFF); - data1 >>= 8; - - macaddr_mask[i-1] = (u8)(data2 & 0xFF); - data2 >>= 8; - } - status = VXGE_HW_OK; - } else - status = VXGE_HW_FAIL; + status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, + &data0, &data1, &steer_ctrl); exit: return status; } @@ -4199,6 +4040,7 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, vpath = &hldev->virtual_paths[vp_id]; + spin_lock_init(&hldev->virtual_paths[vp_id].lock); vpath->vp_id = vp_id; vpath->vp_open = VXGE_HW_VP_OPEN; vpath->hldev = hldev; @@ -4209,14 +4051,12 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, __vxge_hw_vpath_reset(hldev, vp_id); status = __vxge_hw_vpath_reset_check(vpath); - if (status != VXGE_HW_OK) { memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); goto exit; } status = __vxge_hw_vpath_mgmt_read(hldev, vpath); - if (status != VXGE_HW_OK) { memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); goto exit; @@ -4230,7 +4070,6 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, hldev->tim_int_mask1, vp_id); status = __vxge_hw_vpath_initialize(hldev, vp_id); - if (status != VXGE_HW_OK) __vxge_hw_vp_terminate(hldev, vp_id); exit: @@ -4496,7 +4335,9 @@ enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp) __vxge_hw_vp_terminate(devh, vp_id); + spin_lock(&vpath->lock); vpath->vp_open = VXGE_HW_VP_NOT_OPEN; + spin_unlock(&vpath->lock); vpath_close_exit: return status; diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index b395d8db318a..6a81014df597 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -641,6 +641,7 @@ struct __vxge_hw_virtualpath { struct vxge_hw_vpath_stats_hw_info *hw_stats; struct vxge_hw_vpath_stats_hw_info *hw_stats_sav; struct vxge_hw_vpath_stats_sw_info *sw_stats; + spinlock_t lock; }; /* -- cgit v1.2.3-59-g8ed1b From e8ac175615b9458a00193c55617b5b8865e67817 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:57 +0000 Subject: vxge: add support for ethtool firmware flashing Add the ability in the vxge driver to flash firmware via ethtool. Updated to include comments from Ben Hutchings. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 183 +++++++++++++++++++++++++++++++++++++- drivers/net/vxge/vxge-config.h | 71 ++++++++++++++- drivers/net/vxge/vxge-ethtool.c | 20 +++++ drivers/net/vxge/vxge-main.c | 190 ++++++++++++++++++++++++++++++++++++---- drivers/net/vxge/vxge-main.h | 2 + drivers/net/vxge/vxge-reg.h | 29 +++++- drivers/net/vxge/vxge-version.h | 27 ++++++ 7 files changed, 500 insertions(+), 22 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index c822463faf01..7761b9e0ad84 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -155,7 +155,6 @@ __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath); static enum vxge_hw_status __vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id); - static enum vxge_hw_status __vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id); @@ -322,6 +321,188 @@ out: return status; } +enum vxge_hw_status +vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major, + u32 *minor, u32 *build) +{ + u64 data0 = 0, data1 = 0, steer_ctrl = 0; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status; + + vpath = &hldev->virtual_paths[hldev->first_vp_id]; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_FW_UPGRADE_ACTION, + VXGE_HW_FW_UPGRADE_MEMO, + VXGE_HW_FW_UPGRADE_OFFSET_READ, + &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + return status; + + *major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); + *minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); + *build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); + + return status; +} + +enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev) +{ + u64 data0 = 0, data1 = 0, steer_ctrl = 0; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status; + u32 ret; + + vpath = &hldev->virtual_paths[hldev->first_vp_id]; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_FW_UPGRADE_ACTION, + VXGE_HW_FW_UPGRADE_MEMO, + VXGE_HW_FW_UPGRADE_OFFSET_COMMIT, + &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__); + goto exit; + } + + ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F; + if (ret != 1) { + vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d", + __func__, ret); + status = VXGE_HW_FAIL; + } + +exit: + return status; +} + +enum vxge_hw_status +vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size) +{ + u64 data0 = 0, data1 = 0, steer_ctrl = 0; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status; + int ret_code, sec_code; + + vpath = &hldev->virtual_paths[hldev->first_vp_id]; + + /* send upgrade start command */ + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_FW_UPGRADE_ACTION, + VXGE_HW_FW_UPGRADE_MEMO, + VXGE_HW_FW_UPGRADE_OFFSET_START, + &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed", + __func__); + return status; + } + + /* Transfer fw image to adapter 16 bytes at a time */ + for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) { + steer_ctrl = 0; + + /* The next 128bits of fwdata to be loaded onto the adapter */ + data0 = *((u64 *)fwdata); + data1 = *((u64 *)fwdata + 1); + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_FW_UPGRADE_ACTION, + VXGE_HW_FW_UPGRADE_MEMO, + VXGE_HW_FW_UPGRADE_OFFSET_SEND, + &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed", + __func__); + goto out; + } + + ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0); + switch (ret_code) { + case VXGE_HW_FW_UPGRADE_OK: + /* All OK, send next 16 bytes. */ + break; + case VXGE_FW_UPGRADE_BYTES2SKIP: + /* skip bytes in the stream */ + fwdata += (data0 >> 8) & 0xFFFFFFFF; + break; + case VXGE_HW_FW_UPGRADE_DONE: + goto out; + case VXGE_HW_FW_UPGRADE_ERR: + sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0); + switch (sec_code) { + case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: + case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: + printk(KERN_ERR + "corrupted data from .ncf file\n"); + break; + case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: + case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: + case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: + case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: + case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: + printk(KERN_ERR "invalid .ncf file\n"); + break; + case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: + printk(KERN_ERR "buffer overflow\n"); + break; + case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: + printk(KERN_ERR "failed to flash the image\n"); + break; + case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: + printk(KERN_ERR + "generic error. Unknown error type\n"); + break; + default: + printk(KERN_ERR "Unknown error of type %d\n", + sec_code); + break; + } + status = VXGE_HW_FAIL; + goto out; + default: + printk(KERN_ERR "Unknown FW error: %d\n", ret_code); + status = VXGE_HW_FAIL; + goto out; + } + /* point to next 16 bytes */ + fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE; + } +out: + return status; +} + +enum vxge_hw_status +vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, + struct eprom_image *img) +{ + u64 data0 = 0, data1 = 0, steer_ctrl = 0; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status; + int i; + + vpath = &hldev->virtual_paths[hldev->first_vp_id]; + + for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) { + data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i); + data1 = steer_ctrl = 0; + + status = vxge_hw_vpath_fw_api(vpath, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, + VXGE_HW_FW_API_GET_EPROM_REV, + 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + break; + + img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0); + img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0); + img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0); + img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0); + } + + return status; +} + /* * __vxge_hw_channel_allocate - Allocate memory for channel * This function allocates required memory for the channel and various arrays diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 6a81014df597..95230bda0653 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -29,6 +29,15 @@ #define VXGE_HW_MAX_MTU 9600 #define VXGE_HW_DEFAULT_MTU 1500 +#define VXGE_HW_MAX_ROM_IMAGES 8 + +struct eprom_image { + u8 is_valid:1; + u8 index; + u8 type; + u16 version; +}; + #ifdef VXGE_DEBUG_ASSERT /** * vxge_assert @@ -147,6 +156,47 @@ enum vxge_hw_device_link_state { VXGE_HW_LINK_UP }; +/** + * enum enum vxge_hw_fw_upgrade_code - FW upgrade return codes. + * @VXGE_HW_FW_UPGRADE_OK: All OK send next 16 bytes + * @VXGE_HW_FW_UPGRADE_DONE: upload completed + * @VXGE_HW_FW_UPGRADE_ERR: upload error + * @VXGE_FW_UPGRADE_BYTES2SKIP: skip bytes in the stream + * + */ +enum vxge_hw_fw_upgrade_code { + VXGE_HW_FW_UPGRADE_OK = 0, + VXGE_HW_FW_UPGRADE_DONE = 1, + VXGE_HW_FW_UPGRADE_ERR = 2, + VXGE_FW_UPGRADE_BYTES2SKIP = 3 +}; + +/** + * enum enum vxge_hw_fw_upgrade_err_code - FW upgrade error codes. + * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: corrupt data + * @VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: buffer overflow + * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: invalid .ncf file + * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: invalid .ncf file + * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: invalid .ncf file + * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: invalid .ncf file + * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: corrupt data + * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: invalid .ncf file + * @VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: generic error unknown type + * @VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: failed to flash image check failed + */ +enum vxge_hw_fw_upgrade_err_code { + VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1 = 1, + VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW = 2, + VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3 = 3, + VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4 = 4, + VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5 = 5, + VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6 = 6, + VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7 = 7, + VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8 = 8, + VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN = 9, + VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH = 10 +}; + /** * struct vxge_hw_device_date - Date Format * @day: Day @@ -454,7 +504,6 @@ struct vxge_hw_device_config { * See also: vxge_hw_driver_initialize(). */ struct vxge_hw_uld_cbs { - void (*link_up)(struct __vxge_hw_device *devh); void (*link_down)(struct __vxge_hw_device *devh); void (*crit_err)(struct __vxge_hw_device *devh, @@ -721,6 +770,7 @@ struct __vxge_hw_device { u32 debug_level; u32 level_err; u32 level_trace; + u16 eprom_versions[VXGE_HW_MAX_ROM_IMAGES]; }; #define VXGE_HW_INFO_LEN 64 @@ -2032,7 +2082,22 @@ __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id); #define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5 #define VXGE_HW_MAX_POLLING_COUNT 100 -int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); +void +vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev); + +enum vxge_hw_status +vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major, + u32 *minor, u32 *build); + +enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev); -void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev); +enum vxge_hw_status +vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *filebuf, + int size); + +enum vxge_hw_status +vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, + struct eprom_image *eprom_image_data); + +int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); #endif diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index f8fd8da4f173..3d2cd6acf30a 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -1153,6 +1153,25 @@ static int vxge_set_flags(struct net_device *dev, u32 data) return 0; } +static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms) +{ + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + + if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) { + printk(KERN_INFO "Single Function Mode is required to flash the" + " firmware\n"); + return -EINVAL; + } + + if (netif_running(dev)) { + printk(KERN_INFO "Interface %s must be down to flash the " + "firmware\n", dev->name); + return -EBUSY; + } + + return vxge_fw_upgrade(vdev, parms->data, 1); +} + static const struct ethtool_ops vxge_ethtool_ops = { .get_settings = vxge_ethtool_gset, .set_settings = vxge_ethtool_sset, @@ -1175,6 +1194,7 @@ static const struct ethtool_ops vxge_ethtool_ops = { .get_sset_count = vxge_ethtool_get_sset_count, .get_ethtool_stats = vxge_get_ethtool_stats, .set_flags = vxge_set_flags, + .flash_device = vxge_fw_flash, }; void vxge_initialize_ethtool_ops(struct net_device *ndev) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 53db6a4b9601..10549bd39221 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "vxge-main.h" #include "vxge-reg.h" @@ -3248,6 +3249,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, "%s: Ethernet device registered", ndev->name); + hldev->ndev = ndev; *vdev_out = vdev; /* Resetting the Device stats */ @@ -3935,6 +3937,142 @@ static inline u32 vxge_get_num_vfs(u64 function_mode) return num_functions; } +int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override) +{ + struct __vxge_hw_device *hldev = vdev->devh; + u32 maj, min, bld, cmaj, cmin, cbld; + enum vxge_hw_status status; + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, fw_name, &vdev->pdev->dev); + if (ret) { + vxge_debug_init(VXGE_ERR, "%s: Firmware file '%s' not found", + VXGE_DRIVER_NAME, fw_name); + goto out; + } + + /* Load the new firmware onto the adapter */ + status = vxge_update_fw_image(hldev, fw->data, fw->size); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "%s: FW image download to adapter failed '%s'.", + VXGE_DRIVER_NAME, fw_name); + ret = -EIO; + goto out; + } + + /* Read the version of the new firmware */ + status = vxge_hw_upgrade_read_version(hldev, &maj, &min, &bld); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "%s: Upgrade read version failed '%s'.", + VXGE_DRIVER_NAME, fw_name); + ret = -EIO; + goto out; + } + + cmaj = vdev->config.device_hw_info.fw_version.major; + cmin = vdev->config.device_hw_info.fw_version.minor; + cbld = vdev->config.device_hw_info.fw_version.build; + /* It's possible the version in /lib/firmware is not the latest version. + * If so, we could get into a loop of trying to upgrade to the latest + * and flashing the older version. + */ + if (VXGE_FW_VER(maj, min, bld) == VXGE_FW_VER(cmaj, cmin, cbld) && + !override) { + ret = -EINVAL; + goto out; + } + + printk(KERN_NOTICE "Upgrade to firmware version %d.%d.%d commencing\n", + maj, min, bld); + + /* Flash the adapter with the new firmware */ + status = vxge_hw_flash_fw(hldev); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: Upgrade commit failed '%s'.", + VXGE_DRIVER_NAME, fw_name); + ret = -EIO; + goto out; + } + + printk(KERN_NOTICE "Upgrade of firmware successful! Adapter must be " + "hard reset before using, thus requiring a system reboot or a " + "hotplug event.\n"); + +out: + return ret; +} + +static int vxge_probe_fw_update(struct vxgedev *vdev) +{ + u32 maj, min, bld; + int ret, gpxe = 0; + char *fw_name; + + maj = vdev->config.device_hw_info.fw_version.major; + min = vdev->config.device_hw_info.fw_version.minor; + bld = vdev->config.device_hw_info.fw_version.build; + + if (VXGE_FW_VER(maj, min, bld) == VXGE_CERT_FW_VER) + return 0; + + /* Ignore the build number when determining if the current firmware is + * "too new" to load the driver + */ + if (VXGE_FW_VER(maj, min, 0) > VXGE_CERT_FW_VER) { + vxge_debug_init(VXGE_ERR, "%s: Firmware newer than last known " + "version, unable to load driver\n", + VXGE_DRIVER_NAME); + return -EINVAL; + } + + /* Firmware 1.4.4 and older cannot be upgraded, and is too ancient to + * work with this driver. + */ + if (VXGE_FW_VER(maj, min, bld) <= VXGE_FW_DEAD_VER) { + vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d cannot be " + "upgraded\n", VXGE_DRIVER_NAME, maj, min, bld); + return -EINVAL; + } + + /* If file not specified, determine gPXE or not */ + if (VXGE_FW_VER(maj, min, bld) >= VXGE_EPROM_FW_VER) { + int i; + for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) + if (vdev->devh->eprom_versions[i]) { + gpxe = 1; + break; + } + } + if (gpxe) + fw_name = "vxge/X3fw-pxe.ncf"; + else + fw_name = "vxge/X3fw.ncf"; + + ret = vxge_fw_upgrade(vdev, fw_name, 0); + /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on + * probe, so ignore them + */ + if (ret != -EINVAL && ret != -ENOENT) + return -EIO; + else + ret = 0; + + if (VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, VXGE_CERT_FW_VER_MINOR, 0) > + VXGE_FW_VER(maj, min, 0)) { + vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d is too old to" + " be used with this driver.\n" + "Please get the latest version from " + "ftp://ftp.s2io.com/pub/X3100-Drivers/FIRMWARE", + VXGE_DRIVER_NAME, maj, min, bld); + return -EINVAL; + } + + return ret; +} + /** * vxge_probe * @pdev : structure containing the PCI related information of the device. @@ -4093,16 +4231,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit3; } - if (ll_config->device_hw_info.fw_version.major != - VXGE_DRIVER_FW_VERSION_MAJOR) { - vxge_debug_init(VXGE_ERR, - "%s: Incorrect firmware version." - "Please upgrade the firmware to version 1.x.x", - VXGE_DRIVER_NAME); - ret = -EINVAL; - goto _exit3; - } - vpath_mask = ll_config->device_hw_info.vpath_mask; if (vpath_mask == 0) { vxge_debug_ll_config(VXGE_TRACE, @@ -4166,6 +4294,32 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit3; } + if (VXGE_FW_VER(ll_config->device_hw_info.fw_version.major, + ll_config->device_hw_info.fw_version.minor, + ll_config->device_hw_info.fw_version.build) >= + VXGE_EPROM_FW_VER) { + struct eprom_image img[VXGE_HW_MAX_ROM_IMAGES]; + + status = vxge_hw_vpath_eprom_img_ver_get(hldev, img); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: Reading of EPROM failed", + VXGE_DRIVER_NAME); + /* This is a non-fatal error, continue */ + } + + for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) { + hldev->eprom_versions[i] = img[i].version; + if (!img[i].is_valid) + break; + vxge_debug_init(VXGE_TRACE, "%s: EPROM %d, version " + "%d.%d.%d.%d\n", VXGE_DRIVER_NAME, i, + VXGE_EPROM_IMG_MAJOR(img[i].version), + VXGE_EPROM_IMG_MINOR(img[i].version), + VXGE_EPROM_IMG_FIX(img[i].version), + VXGE_EPROM_IMG_BUILD(img[i].version)); + } + } + /* if FCS stripping is not disabled in MAC fail driver load */ if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) { vxge_debug_init(VXGE_ERR, @@ -4194,18 +4348,22 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; - if (vxge_device_register(hldev, ll_config, high_dma, no_of_vpath, - &vdev)) { + ret = vxge_device_register(hldev, ll_config, high_dma, no_of_vpath, + &vdev); + if (ret) { ret = -EINVAL; goto _exit4; } + ret = vxge_probe_fw_update(vdev); + if (ret) + goto _exit5; + vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL); VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev), vxge_hw_device_trace_level_get(hldev)); /* set private HW device info */ - hldev->ndev = vdev->ndev; vdev->mtu = VXGE_HW_DEFAULT_MTU; vdev->bar0 = attr.bar0; vdev->max_vpath_supported = max_vpath_supported; @@ -4307,7 +4465,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) "%s: mac_addr_list : memory allocation failed", vdev->ndev->name); ret = -EPERM; - goto _exit5; + goto _exit6; } macaddr = (u8 *)&entry->macaddr; memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN); @@ -4347,10 +4505,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) kfree(ll_config); return 0; -_exit5: +_exit6: for (i = 0; i < vdev->no_of_vpath; i++) vxge_free_mac_add_list(&vdev->vpaths[i]); - +_exit5: vxge_device_unregister(hldev); _exit4: pci_disable_sriov(pdev); diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 3845e628a597..1699d7590b31 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -397,6 +397,8 @@ struct vxge_tx_priv { extern void vxge_initialize_ethtool_ops(struct net_device *ndev); enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); +int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override); + /** * #define VXGE_DEBUG_INIT: debug for initialization functions * #define VXGE_DEBUG_TX : debug transmit related functions diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h index 93fd752187bc..0df52dbd42a0 100644 --- a/drivers/net/vxge/vxge-reg.h +++ b/drivers/net/vxge/vxge-reg.h @@ -49,6 +49,30 @@ #define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17 #define VXGE_HW_TITAN_VPATH_REG_SPACES 17 +#define VXGE_HW_FW_API_GET_EPROM_REV 31 + +#define VXGE_EPROM_IMG_MAJOR(val) (u32) vxge_bVALn(val, 48, 4) +#define VXGE_EPROM_IMG_MINOR(val) (u32) vxge_bVALn(val, 52, 4) +#define VXGE_EPROM_IMG_FIX(val) (u32) vxge_bVALn(val, 56, 4) +#define VXGE_EPROM_IMG_BUILD(val) (u32) vxge_bVALn(val, 60, 4) + +#define VXGE_HW_GET_EPROM_IMAGE_INDEX(val) vxge_bVALn(val, 16, 8) +#define VXGE_HW_GET_EPROM_IMAGE_VALID(val) vxge_bVALn(val, 31, 1) +#define VXGE_HW_GET_EPROM_IMAGE_TYPE(val) vxge_bVALn(val, 40, 8) +#define VXGE_HW_GET_EPROM_IMAGE_REV(val) vxge_bVALn(val, 48, 16) +#define VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(val) vxge_vBIT(val, 16, 8) + +#define VXGE_HW_FW_UPGRADE_MEMO 13 +#define VXGE_HW_FW_UPGRADE_ACTION 16 +#define VXGE_HW_FW_UPGRADE_OFFSET_START 2 +#define VXGE_HW_FW_UPGRADE_OFFSET_SEND 3 +#define VXGE_HW_FW_UPGRADE_OFFSET_COMMIT 4 +#define VXGE_HW_FW_UPGRADE_OFFSET_READ 5 + +#define VXGE_HW_FW_UPGRADE_BLK_SIZE 16 +#define VXGE_HW_UPGRADE_GET_RET_ERR_CODE(val) (val & 0xff) +#define VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(val) ((val >> 8) & 0xff) + #define VXGE_HW_ASIC_MODE_RESERVED 0 #define VXGE_HW_ASIC_MODE_NO_IOV 1 #define VXGE_HW_ASIC_MODE_SR_IOV 2 @@ -165,13 +189,13 @@ #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5 -#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6 +#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11 -#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12 +#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13 #define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \ @@ -437,6 +461,7 @@ #define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \ vxge_bVALn(bits, 48, 16) #define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16) +#define VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(bits) vxge_bVALn(bits, 0, 8) #define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\ vxge_bVALn(bits, 0, 18) diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index 53fefe137368..b4eced19e45d 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h @@ -19,4 +19,31 @@ #define VXGE_VERSION_FIX "9" #define VXGE_VERSION_BUILD "20840" #define VXGE_VERSION_FOR "k" + +#define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) + +#define VXGE_DEAD_FW_VER_MAJOR 1 +#define VXGE_DEAD_FW_VER_MINOR 4 +#define VXGE_DEAD_FW_VER_BUILD 4 + +#define VXGE_FW_DEAD_VER VXGE_FW_VER(VXGE_DEAD_FW_VER_MAJOR, \ + VXGE_DEAD_FW_VER_MINOR, \ + VXGE_DEAD_FW_VER_BUILD) + +#define VXGE_EPROM_FW_VER_MAJOR 1 +#define VXGE_EPROM_FW_VER_MINOR 6 +#define VXGE_EPROM_FW_VER_BUILD 1 + +#define VXGE_EPROM_FW_VER VXGE_FW_VER(VXGE_EPROM_FW_VER_MAJOR, \ + VXGE_EPROM_FW_VER_MINOR, \ + VXGE_EPROM_FW_VER_BUILD) + +#define VXGE_CERT_FW_VER_MAJOR 1 +#define VXGE_CERT_FW_VER_MINOR 8 +#define VXGE_CERT_FW_VER_BUILD 1 + +#define VXGE_CERT_FW_VER VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, \ + VXGE_CERT_FW_VER_MINOR, \ + VXGE_CERT_FW_VER_BUILD) + #endif -- cgit v1.2.3-59-g8ed1b From b81b37338412e3215670641e5025c85146521dea Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:58 +0000 Subject: vxge: add receive hardware timestamping Add support for enable/disabling hardware timestamping on receive packets via ioctl call. When enabled, the hardware timestamp replaces the FCS in the payload. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 133 +++++++++++++++++++++++++++++++++++++++++-- drivers/net/vxge/vxge-main.h | 8 ++- 2 files changed, 132 insertions(+), 9 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 10549bd39221..ea303a2af3aa 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "vxge-main.h" #include "vxge-reg.h" @@ -369,7 +370,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, u8 t_code, void *userdata) { struct vxge_ring *ring = (struct vxge_ring *)userdata; - struct net_device *dev = ring->ndev; + struct net_device *dev = ring->ndev; unsigned int dma_sizes; void *first_dtr = NULL; int dtr_cnt = 0; @@ -513,6 +514,16 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, else skb_checksum_none_assert(skb); + + if (ring->rx_hwts) { + struct skb_shared_hwtstamps *skb_hwts; + u32 ns = *(u32 *)(skb->head + pkt_length); + + skb_hwts = skb_hwtstamps(skb); + skb_hwts->hwtstamp = ns_to_ktime(ns); + skb_hwts->syststamp.tv64 = 0; + } + /* rth_hash_type and rth_it_hit are non-zero regardless of * whether rss is enabled. Only the rth_value is zero/non-zero * if rss is disabled/enabled, so key off of that. @@ -2037,6 +2048,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vdev->config.fifo_indicate_max_pkts; vpath->ring.rx_vector_no = 0; vpath->ring.rx_csum = vdev->rx_csum; + vpath->ring.rx_hwts = vdev->rx_hwts; vpath->is_open = 1; vdev->vp_handles[i] = vpath->handle; vpath->ring.gro_enable = vdev->config.gro_enable; @@ -2971,6 +2983,101 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) return net_stats; } +static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev, + int enable) +{ + enum vxge_hw_status status; + u64 val64; + + /* Timestamp is passed to the driver via the FCS, therefore we + * must disable the FCS stripping by the adapter. Since this is + * required for the driver to load (due to a hardware bug), + * there is no need to do anything special here. + */ + if (enable) + val64 = VXGE_HW_XMAC_TIMESTAMP_EN | + VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) | + VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0); + else + val64 = 0; + + status = vxge_hw_mgmt_reg_write(vdev->devh, + vxge_hw_mgmt_reg_type_mrpcim, + 0, + offsetof(struct vxge_hw_mrpcim_reg, + xmac_timestamp), + val64); + vxge_hw_device_flush_io(vdev->devh); + return status; +} + +static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data) +{ + struct hwtstamp_config config; + enum vxge_hw_status status; + int i; + + if (copy_from_user(&config, data, sizeof(config))) + return -EFAULT; + + /* reserved for future extensions */ + if (config.flags) + return -EINVAL; + + /* Transmit HW Timestamp not supported */ + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: + break; + case HWTSTAMP_TX_ON: + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_NONE: + status = vxge_timestamp_config(vdev, 0); + if (status != VXGE_HW_OK) + return -EFAULT; + + vdev->rx_hwts = 0; + config.rx_filter = HWTSTAMP_FILTER_NONE; + break; + + case HWTSTAMP_FILTER_ALL: + case HWTSTAMP_FILTER_SOME: + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + status = vxge_timestamp_config(vdev, 1); + if (status != VXGE_HW_OK) + return -EFAULT; + + vdev->rx_hwts = 1; + config.rx_filter = HWTSTAMP_FILTER_ALL; + break; + + default: + return -ERANGE; + } + + for (i = 0; i < vdev->no_of_vpath; i++) + vdev->vpaths[i].ring.rx_hwts = vdev->rx_hwts; + + if (copy_to_user(data, &config, sizeof(config))) + return -EFAULT; + + return 0; +} + /** * vxge_ioctl * @dev: Device pointer. @@ -2983,7 +3090,20 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) */ static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - return -EOPNOTSUPP; + struct vxgedev *vdev = netdev_priv(dev); + int ret; + + switch (cmd) { + case SIOCSHWTSTAMP: + ret = vxge_hwtstamp_ioctl(vdev, rq->ifr_data); + if (ret) + return ret; + break; + default: + return -EOPNOTSUPP; + } + + return 0; } /** @@ -3180,6 +3300,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vdev->pdev = hldev->pdev; memcpy(&vdev->config, config, sizeof(struct vxge_config)); vdev->rx_csum = 1; /* Enable Rx CSUM by default. */ + vdev->rx_hwts = 0; SET_NETDEV_DEV(ndev, &vdev->pdev->dev); @@ -4321,10 +4442,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) } /* if FCS stripping is not disabled in MAC fail driver load */ - if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "%s: FCS stripping is not disabled in MAC" - " failing driver load", VXGE_DRIVER_NAME); + status = vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: FCS stripping is enabled in MAC" + " failing driver load", VXGE_DRIVER_NAME); ret = -EINVAL; goto _exit4; } diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 1699d7590b31..6f6e9ce0bf20 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -248,8 +248,9 @@ struct vxge_ring { */ int driver_id; - /* copy of the flag indicating whether rx_csum is to be used */ - u32 rx_csum; + /* copy of the flag indicating whether rx_csum is to be used */ + u32 rx_csum:1, + rx_hwts:1; int pkts_processed; int budget; @@ -327,7 +328,8 @@ struct vxgedev { u16 all_multi_flg; /* A flag indicating whether rx_csum is to be used or not. */ - u32 rx_csum; + u32 rx_csum:1, + rx_hwts:1; struct vxge_msix_entry *vxge_entries; struct msix_entry *entries; -- cgit v1.2.3-59-g8ed1b From c3150eac9f2e5f770b09d371f7716540219a46f6 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:25:59 +0000 Subject: vxge: Handle errors in vxge_hw_vpath_fw_api Propagate the return code of the call to vxge_hw_vpath_fw_api and __vxge_hw_vpath_pci_func_mode_get. This enables the proper handling of error conditions when querying the function mode of the device during probe. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 7761b9e0ad84..388e6c48696b 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -1107,8 +1107,9 @@ __vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath, * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode * Returns pci function mode */ -static u64 -__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath) +static enum vxge_hw_status +__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_device_hw_info *hw_info) { u64 data0, data1 = 0, steer_ctrl = 0; enum vxge_hw_status status; @@ -1119,8 +1120,11 @@ __vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath) VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 0, &data0, &data1, &steer_ctrl); + if (status != VXGE_HW_OK) + return status; - return data0; + hw_info->function_mode = data0; + return status; } /* @@ -1235,8 +1239,9 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, (bar0 + val64); vpath.vp_open = 0; - hw_info->function_mode = - __vxge_hw_vpath_pci_func_mode_get(&vpath); + status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info); + if (status != VXGE_HW_OK) + goto exit; status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info); if (status != VXGE_HW_OK) -- cgit v1.2.3-59-g8ed1b From e7935c9669c27c5d530bff634c0c15f7a602d697 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:26:00 +0000 Subject: vxge: Titan1A detection Detect if the adapter is Titan or Titan1A, and tune the driver for this hardware. Also, remove unnecessary function __vxge_hw_device_id_get. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 40 ++++++++------------------------- drivers/net/vxge/vxge-config.h | 6 ----- drivers/net/vxge/vxge-main.c | 45 ++++++++++++++++++++++++++++++++----- drivers/net/vxge/vxge-main.h | 51 +++++++++++++++++++++++++++++++----------- 4 files changed, 87 insertions(+), 55 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 388e6c48696b..5903b2e9a6e9 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -98,9 +98,6 @@ __vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config); static enum vxge_hw_status __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config); -static void -__vxge_hw_device_id_get(struct __vxge_hw_device *hldev); - static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev); @@ -805,26 +802,6 @@ exit: return status; } -/* - * __vxge_hw_device_id_get - * This routine returns sets the device id and revision numbers into the device - * structure - */ -void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev) -{ - u64 val64; - - val64 = readq(&hldev->common_reg->titan_asic_id); - hldev->device_id = - (u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64); - - hldev->major_revision = - (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64); - - hldev->minor_revision = - (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64); -} - /* * __vxge_hw_device_access_rights_get: Get Access Rights of the driver * This routine returns the Access Rights of the driver @@ -1327,7 +1304,6 @@ vxge_hw_device_initialize( vfree(hldev); goto exit; } - __vxge_hw_device_id_get(hldev); __vxge_hw_device_host_info_get(hldev); @@ -4442,16 +4418,18 @@ vpath_open_exit1: void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_virtualpath *vpath = NULL; + struct __vxge_hw_virtualpath *vpath = vp->vpath; + struct __vxge_hw_ring *ring = vpath->ringh; + struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev); u64 new_count, val64, val164; - struct __vxge_hw_ring *ring; - vpath = vp->vpath; - ring = vpath->ringh; + if (vdev->titan1) { + new_count = readq(&vpath->vp_reg->rxdmem_size); + new_count &= 0x1fff; + } else + new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8; - new_count = readq(&vpath->vp_reg->rxdmem_size); - new_count &= 0x1fff; - val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count)); + val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count); writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164), &vpath->vp_reg->prc_rxd_doorbell); diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 95230bda0653..5b2c8313426d 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -713,9 +713,6 @@ struct __vxge_hw_vpath_handle{ /** * struct __vxge_hw_device - Hal device object * @magic: Magic Number - * @device_id: PCI Device Id of the adapter - * @major_revision: PCI Device major revision - * @minor_revision: PCI Device minor revision * @bar0: BAR0 virtual address. * @pdev: Physical device handle * @config: Confguration passed by the LL driver at initialization @@ -727,9 +724,6 @@ struct __vxge_hw_device { u32 magic; #define VXGE_HW_DEVICE_MAGIC 0x12345678 #define VXGE_HW_DEVICE_DEAD 0xDEADDEAD - u16 device_id; - u8 major_revision; - u8 minor_revision; void __iomem *bar0; struct pci_dev *pdev; struct net_device *ndev; diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index ea303a2af3aa..b8806a15bcaf 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2012,8 +2012,23 @@ static int vxge_open_vpaths(struct vxgedev *vdev) for (i = 0; i < vdev->no_of_vpath; i++) { vpath = &vdev->vpaths[i]; - vxge_assert(vpath->is_configured); + + if (!vdev->titan1) { + struct vxge_hw_vp_config *vcfg; + vcfg = &vdev->devh->config.vp_config[vpath->device_id]; + + vcfg->rti.urange_a = RTI_T1A_RX_URANGE_A; + vcfg->rti.urange_b = RTI_T1A_RX_URANGE_B; + vcfg->rti.urange_c = RTI_T1A_RX_URANGE_C; + vcfg->tti.uec_a = TTI_T1A_TX_UFC_A; + vcfg->tti.uec_b = TTI_T1A_TX_UFC_B; + vcfg->tti.uec_c = TTI_T1A_TX_UFC_C(vdev->mtu); + vcfg->tti.uec_d = TTI_T1A_TX_UFC_D(vdev->mtu); + vcfg->tti.ltimer_val = VXGE_T1A_TTI_LTIMER_VAL; + vcfg->tti.rtimer_val = VXGE_T1A_TTI_RTIMER_VAL; + } + attr.vp_id = vpath->device_id; attr.fifo_attr.callback = vxge_xmit_compl; attr.fifo_attr.txdl_term = vxge_tx_term; @@ -2710,9 +2725,10 @@ vxge_open(struct net_device *dev) vxge_os_timer(vdev->vp_reset_timer, vxge_poll_vp_reset, vdev, (HZ/2)); - if (vdev->vp_lockup_timer.function == NULL) - vxge_os_timer(vdev->vp_lockup_timer, - vxge_poll_vp_lockup, vdev, (HZ/2)); + /* There is no need to check for RxD leak and RxD lookup on Titan1A */ + if (vdev->titan1 && vdev->vp_lockup_timer.function == NULL) + vxge_os_timer(vdev->vp_lockup_timer, vxge_poll_vp_lockup, vdev, + HZ / 2); set_bit(__VXGE_STATE_CARD_UP, &vdev->state); @@ -2844,7 +2860,9 @@ static int do_vxge_close(struct net_device *dev, int do_io) smp_wmb(); } - del_timer_sync(&vdev->vp_lockup_timer); + + if (vdev->titan1) + del_timer_sync(&vdev->vp_lockup_timer); del_timer_sync(&vdev->vp_reset_timer); @@ -3262,6 +3280,19 @@ static const struct net_device_ops vxge_netdev_ops = { #endif }; +static int __devinit vxge_device_revision(struct vxgedev *vdev) +{ + int ret; + u8 revision; + + ret = pci_read_config_byte(vdev->pdev, PCI_REVISION_ID, &revision); + if (ret) + return -EIO; + + vdev->titan1 = (revision == VXGE_HW_TITAN1_PCI_REVISION); + return 0; +} + static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, struct vxge_config *config, int high_dma, int no_of_vpath, @@ -3302,6 +3333,10 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vdev->rx_csum = 1; /* Enable Rx CSUM by default. */ vdev->rx_hwts = 0; + ret = vxge_device_revision(vdev); + if (ret < 0) + goto _out1; + SET_NETDEV_DEV(ndev, &vdev->pdev->dev); ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 6f6e9ce0bf20..953cb0ded3e1 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -29,6 +29,9 @@ #define PCI_DEVICE_ID_TITAN_WIN 0x5733 #define PCI_DEVICE_ID_TITAN_UNI 0x5833 +#define VXGE_HW_TITAN1_PCI_REVISION 1 +#define VXGE_HW_TITAN1A_PCI_REVISION 2 + #define VXGE_USE_DEFAULT 0xffffffff #define VXGE_HW_VPATH_MSIX_ACTIVE 4 #define VXGE_ALARM_MSIX_ID 2 @@ -53,11 +56,13 @@ #define VXGE_TTI_BTIMER_VAL 250000 -#define VXGE_TTI_LTIMER_VAL 1000 -#define VXGE_TTI_RTIMER_VAL 0 -#define VXGE_RTI_BTIMER_VAL 250 -#define VXGE_RTI_LTIMER_VAL 100 -#define VXGE_RTI_RTIMER_VAL 0 +#define VXGE_TTI_LTIMER_VAL 1000 +#define VXGE_T1A_TTI_LTIMER_VAL 80 +#define VXGE_TTI_RTIMER_VAL 0 +#define VXGE_T1A_TTI_RTIMER_VAL 400 +#define VXGE_RTI_BTIMER_VAL 250 +#define VXGE_RTI_LTIMER_VAL 100 +#define VXGE_RTI_RTIMER_VAL 0 #define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH #define VXGE_ISR_POLLING_CNT 8 #define VXGE_MAX_CONFIG_DEV 0xFF @@ -76,14 +81,32 @@ #define TTI_TX_UFC_B 40 #define TTI_TX_UFC_C 60 #define TTI_TX_UFC_D 100 +#define TTI_T1A_TX_UFC_A 30 +#define TTI_T1A_TX_UFC_B 80 +/* Slope - (max_mtu - min_mtu)/(max_mtu_ufc - min_mtu_ufc) */ +/* Slope - 93 */ +/* 60 - 9k Mtu, 140 - 1.5k mtu */ +#define TTI_T1A_TX_UFC_C(mtu) (60 + ((VXGE_HW_MAX_MTU - mtu) / 93)) + +/* Slope - 37 */ +/* 100 - 9k Mtu, 300 - 1.5k mtu */ +#define TTI_T1A_TX_UFC_D(mtu) (100 + ((VXGE_HW_MAX_MTU - mtu) / 37)) + + +#define RTI_RX_URANGE_A 5 +#define RTI_RX_URANGE_B 15 +#define RTI_RX_URANGE_C 40 +#define RTI_T1A_RX_URANGE_A 1 +#define RTI_T1A_RX_URANGE_B 20 +#define RTI_T1A_RX_URANGE_C 50 +#define RTI_RX_UFC_A 1 +#define RTI_RX_UFC_B 5 +#define RTI_RX_UFC_C 10 +#define RTI_RX_UFC_D 15 +#define RTI_T1A_RX_UFC_B 20 +#define RTI_T1A_RX_UFC_C 50 +#define RTI_T1A_RX_UFC_D 60 -#define RTI_RX_URANGE_A 5 -#define RTI_RX_URANGE_B 15 -#define RTI_RX_URANGE_C 40 -#define RTI_RX_UFC_A 1 -#define RTI_RX_UFC_B 5 -#define RTI_RX_UFC_C 10 -#define RTI_RX_UFC_D 15 /* Milli secs timer period */ #define VXGE_TIMER_DELAY 10000 @@ -329,7 +352,8 @@ struct vxgedev { /* A flag indicating whether rx_csum is to be used or not. */ u32 rx_csum:1, - rx_hwts:1; + rx_hwts:1, + titan1:1; struct vxge_msix_entry *vxge_entries; struct msix_entry *entries; @@ -397,6 +421,7 @@ struct vxge_tx_priv { } while (0); extern void vxge_initialize_ethtool_ops(struct net_device *ndev); + enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override); -- cgit v1.2.3-59-g8ed1b From ca3e3b8fae982400dacbbf19f3112cc84e51d46a Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:26:01 +0000 Subject: vxge: correct multi-function detection The values used to determined if the adapter is running in single or multi-function mode were previously modified to the values necessary when making the VXGE_HW_FW_API_GET_FUNC_MODE firmware call. However, the firmware call was not modified. This had the driver printing out on probe that the adapter was in multi-function mode when in single function mode and vice versa. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 6 +++--- drivers/net/vxge/vxge-reg.h | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 5903b2e9a6e9..14dc8c8f47ef 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -1091,16 +1091,16 @@ __vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath, u64 data0, data1 = 0, steer_ctrl = 0; enum vxge_hw_status status; - data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE; + data0 = 0; status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, + VXGE_HW_FW_API_GET_FUNC_MODE, VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 0, &data0, &data1, &steer_ctrl); if (status != VXGE_HW_OK) return status; - hw_info->function_mode = data0; + hw_info->function_mode = VXGE_HW_GET_FUNC_MODE_VAL(data0); return status; } diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h index 0df52dbd42a0..3e658b175947 100644 --- a/drivers/net/vxge/vxge-reg.h +++ b/drivers/net/vxge/vxge-reg.h @@ -62,6 +62,9 @@ #define VXGE_HW_GET_EPROM_IMAGE_REV(val) vxge_bVALn(val, 48, 16) #define VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(val) vxge_vBIT(val, 16, 8) +#define VXGE_HW_FW_API_GET_FUNC_MODE 29 +#define VXGE_HW_GET_FUNC_MODE_VAL(val) (val & 0xFF) + #define VXGE_HW_FW_UPGRADE_MEMO 13 #define VXGE_HW_FW_UPGRADE_ACTION 16 #define VXGE_HW_FW_UPGRADE_OFFSET_START 2 -- cgit v1.2.3-59-g8ed1b From 1901d042abf10d08a829961a63fd158f9844587e Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:26:02 +0000 Subject: vxge: update Kconfig Update Kconfig to reflect Exar's purchase of Neterion (formerly S2IO). Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/Kconfig | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f6668cdaac85..fa62a63db166 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2772,29 +2772,38 @@ config IXGB will be called ixgb. config S2IO - tristate "S2IO 10Gbe XFrame NIC" + tristate "Exar Xframe 10Gb Ethernet Adapter" depends on PCI ---help--- - This driver supports the 10Gbe XFrame NIC of S2IO. + This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters. + More specific information on configuring the driver is in . + To compile this driver as a module, choose M here. The module + will be called s2io. + config VXGE - tristate "Neterion X3100 Series 10GbE PCIe Server Adapter" + tristate "Exar X3100 Series 10GbE PCIe Server Adapter" depends on PCI && INET ---help--- - This driver supports Neterion Inc's X3100 Series 10 GbE PCIe + This driver supports Exar Corp's X3100 Series 10 GbE PCIe I/O Virtualized Server Adapter. + More specific information on configuring the driver is in . + To compile this driver as a module, choose M here. The module + will be called vxge. + config VXGE_DEBUG_TRACE_ALL bool "Enabling All Debug trace statments in driver" default n depends on VXGE ---help--- Say Y here if you want to enabling all the debug trace statements in - driver. By default only few debug trace statements are enabled. + the vxge driver. By default only few debug trace statements are + enabled. config MYRI10GE tristate "Myricom Myri-10G Ethernet support" -- cgit v1.2.3-59-g8ed1b From 2c91308f449c6705b81bd3370a0ec647e370f35c Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:26:03 +0000 Subject: vxge: sparse and other clean-ups Correct issues found by running sparse on the vxge driver, as well as other miscellaneous cleanups. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 100 +++++++++------------------------------- drivers/net/vxge/vxge-ethtool.c | 35 ++++++-------- drivers/net/vxge/vxge-main.c | 94 ++++++++++++++++--------------------- 3 files changed, 76 insertions(+), 153 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 14dc8c8f47ef..409c2e6053d0 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -21,19 +21,6 @@ #include "vxge-config.h" #include "vxge-main.h" -static enum vxge_hw_status -__vxge_hw_fifo_create( - struct __vxge_hw_vpath_handle *vpath_handle, - struct vxge_hw_fifo_attr *attr); - -static enum vxge_hw_status -__vxge_hw_fifo_abort( - struct __vxge_hw_fifo *fifoh); - -static enum vxge_hw_status -__vxge_hw_fifo_reset( - struct __vxge_hw_fifo *ringh); - static enum vxge_hw_status __vxge_hw_fifo_delete( struct __vxge_hw_vpath_handle *vpath_handle); @@ -72,44 +59,15 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *hldev, u32 size, struct vxge_hw_mempool_dma *dma_object); - -static struct __vxge_hw_channel* -__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, - enum __vxge_hw_channel_type type, u32 length, - u32 per_dtr_space, void *userdata); - static void __vxge_hw_channel_free( struct __vxge_hw_channel *channel); -static enum vxge_hw_status -__vxge_hw_channel_initialize( - struct __vxge_hw_channel *channel); - -static enum vxge_hw_status -__vxge_hw_channel_reset( - struct __vxge_hw_channel *channel); - static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp); -static enum vxge_hw_status -__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config); - static enum vxge_hw_status __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config); -static void -__vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev); - -static enum vxge_hw_status -__vxge_hw_device_initialize(struct __vxge_hw_device *hldev); - -static void -__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev); - -static enum vxge_hw_status -__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev); - static enum vxge_hw_status __vxge_hw_device_register_poll( void __iomem *reg, @@ -130,9 +88,10 @@ __vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr, static struct vxge_hw_mempool* __vxge_hw_mempool_create(struct __vxge_hw_device *devh, u32 memblock_size, - u32 item_size, u32 private_size, u32 items_initial, - u32 items_max, struct vxge_hw_mempool_cbs *mp_callback, - void *userdata); + u32 item_size, u32 private_size, u32 items_initial, + u32 items_max, struct vxge_hw_mempool_cbs *mp_callback, + void *userdata); + static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool); static enum vxge_hw_status @@ -145,23 +104,9 @@ vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vpath_handle); static enum vxge_hw_status __vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg); -static enum vxge_hw_status -__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath); - - -static enum vxge_hw_status -__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id); - -static enum vxge_hw_status -__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id); - static void __vxge_hw_vp_terminate(struct __vxge_hw_device *devh, u32 vp_id); -static enum vxge_hw_status -__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath, - u32 operation, u32 offset, u64 *stat); - static enum vxge_hw_status __vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats); @@ -505,7 +450,7 @@ vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, * This function allocates required memory for the channel and various arrays * in the channel */ -struct __vxge_hw_channel* +static struct __vxge_hw_channel * __vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, enum __vxge_hw_channel_type type, u32 length, u32 per_dtr_space, void *userdata) @@ -576,7 +521,7 @@ exit0: * This function deallocates memory from the channel and various arrays * in the channel */ -void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) +static void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) { kfree(channel->work_arr); kfree(channel->free_arr); @@ -590,7 +535,7 @@ void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) * This function initializes a channel by properly setting the * various references */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel) { u32 i; @@ -625,7 +570,7 @@ __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel) * __vxge_hw_channel_reset - Resets a channel * This function resets a channel by properly setting the various references */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_channel_reset(struct __vxge_hw_channel *channel) { u32 i; @@ -652,8 +597,7 @@ __vxge_hw_channel_reset(struct __vxge_hw_channel *channel) * Initialize certain PCI/PCI-X configuration registers * with recommended values. Save config space for future hw resets. */ -void -__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) +static void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) { u16 cmd = 0; @@ -742,7 +686,7 @@ exit: * register location pointers in the device object. It waits until the ric is * completed initializing registers. */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) { u64 val64; @@ -938,7 +882,8 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) * __vxge_hw_device_initialize * Initialize Titan-V hardware. */ -enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev) +static enum vxge_hw_status +__vxge_hw_device_initialize(struct __vxge_hw_device *hldev) { enum vxge_hw_status status = VXGE_HW_OK; @@ -2337,7 +2282,7 @@ static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) * __vxge_hw_device_fifo_config_check - Check fifo configuration. * Check the fifo configuration */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config) { if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) || @@ -2385,7 +2330,7 @@ __vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config) * __vxge_hw_device_config_check - Check device configuration. * Check the device configuration */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config) { u32 i; @@ -2945,7 +2890,7 @@ __vxge_hw_fifo_mempool_item_alloc( * __vxge_hw_fifo_create - Create a FIFO * This function creates FIFO and initializes it. */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, struct vxge_hw_fifo_attr *attr) { @@ -3109,7 +3054,8 @@ static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) * __vxge_hw_fifo_delete - Removes the FIFO * This function freeup the memory pool and removes the FIFO */ -enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) +static enum vxge_hw_status +__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) { struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; @@ -4897,7 +4843,7 @@ static void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr, * __vxge_hw_blockpool_create - Create block pool */ -enum vxge_hw_status +static enum vxge_hw_status __vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, struct __vxge_hw_blockpool *blockpool, u32 pool_size, @@ -4997,7 +4943,7 @@ blockpool_create_exit: * __vxge_hw_blockpool_destroy - Deallocates the block pool */ -void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) +static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) { struct __vxge_hw_device *hldev; @@ -5163,7 +5109,7 @@ exit: * Allocates a block of memory of given size, either from block pool * or by calling vxge_os_dma_malloc() */ -void * +static void * __vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, struct vxge_hw_mempool_dma *dma_object) { @@ -5227,7 +5173,7 @@ exit: * __vxge_hw_blockpool_free - Frees the memory allcoated with __vxge_hw_blockpool_malloc */ -void +static void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, void *memblock, u32 size, struct vxge_hw_mempool_dma *dma_object) @@ -5279,7 +5225,7 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool * This function allocates a block from block pool or from the system */ -struct __vxge_hw_blockpool_entry * +static struct __vxge_hw_blockpool_entry * __vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) { struct __vxge_hw_blockpool_entry *entry = NULL; @@ -5314,7 +5260,7 @@ __vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) * * This function frees a block from block pool */ -void +static void __vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh, struct __vxge_hw_blockpool_entry *entry) { diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index 3d2cd6acf30a..09f721e10517 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -11,7 +11,7 @@ * Virtualized Server Adapter. * Copyright(c) 2002-2010 Exar Corp. ******************************************************************************/ -#include +#include #include #include #include @@ -29,7 +29,6 @@ * Return value: * 0 on success. */ - static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info) { /* We currently only support 10Gb/FULL */ @@ -79,10 +78,9 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) * Returns driver specefic information like name, version etc.. to ethtool. */ static void vxge_ethtool_gdrvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) + struct ethtool_drvinfo *info) { - struct vxgedev *vdev; - vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME)); strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION)); strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN); @@ -104,15 +102,14 @@ static void vxge_ethtool_gdrvinfo(struct net_device *dev, * buffer area. */ static void vxge_ethtool_gregs(struct net_device *dev, - struct ethtool_regs *regs, void *space) + struct ethtool_regs *regs, void *space) { int index, offset; enum vxge_hw_status status; u64 reg; - u64 *reg_space = (u64 *) space; + u64 *reg_space = (u64 *)space; struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) - pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = vdev->devh; regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath; regs->version = vdev->pdev->subsystem_device; @@ -148,8 +145,7 @@ static void vxge_ethtool_gregs(struct net_device *dev, static int vxge_ethtool_idnic(struct net_device *dev, u32 data) { struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) - pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON); msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME); @@ -168,11 +164,10 @@ static int vxge_ethtool_idnic(struct net_device *dev, u32 data) * void */ static void vxge_ethtool_getpause_data(struct net_device *dev, - struct ethtool_pauseparam *ep) + struct ethtool_pauseparam *ep) { struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) - pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause); } @@ -188,11 +183,10 @@ static void vxge_ethtool_getpause_data(struct net_device *dev, * int, returns 0 on Success */ static int vxge_ethtool_setpause_data(struct net_device *dev, - struct ethtool_pauseparam *ep) + struct ethtool_pauseparam *ep) { struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) - pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause); @@ -209,9 +203,8 @@ static void vxge_get_ethtool_stats(struct net_device *dev, enum vxge_hw_status status; enum vxge_hw_status swstatus; struct vxge_vpath *vpath = NULL; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + struct __vxge_hw_device *hldev = vdev->devh; struct vxge_hw_xmac_stats *xmac_stats; struct vxge_hw_device_stats_sw_info *sw_stats; struct vxge_hw_device_stats_hw_info *hw_stats; @@ -574,8 +567,8 @@ static void vxge_get_ethtool_stats(struct net_device *dev, kfree(hw_stats); } -static void vxge_ethtool_get_strings(struct net_device *dev, - u32 stringset, u8 *data) +static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset, + u8 *data) { int stat_size = 0; int i, j; diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index b8806a15bcaf..3f2d6ed13d3e 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -688,7 +688,7 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) struct vxge_vpath *vpath = NULL; struct __vxge_hw_device *hldev; - hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); mac_address = (u8 *)&mac_addr; memcpy(mac_address, mac_header, ETH_ALEN); @@ -1112,7 +1112,7 @@ static void vxge_set_multicast(struct net_device *dev) /* Delete previous MC's */ for (i = 0; i < mcast_cnt; i++) { list_for_each_safe(entry, next, list_head) { - mac_entry = (struct vxge_mac_addrs *) entry; + mac_entry = (struct vxge_mac_addrs *)entry; /* Copy the mac address to delete */ mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); @@ -1155,7 +1155,7 @@ _set_all_mcast: /* Delete previous MC's */ for (i = 0; i < mcast_cnt; i++) { list_for_each_safe(entry, next, list_head) { - mac_entry = (struct vxge_mac_addrs *) entry; + mac_entry = (struct vxge_mac_addrs *)entry; /* Copy the mac address to delete */ mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); @@ -1202,7 +1202,7 @@ static int vxge_set_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; struct vxgedev *vdev; - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; enum vxge_hw_status status = VXGE_HW_OK; struct macInfo mac_info_new, mac_info_old; int vpath_idx = 0; @@ -1632,7 +1632,7 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) int budget_org = budget; struct vxge_ring *ring; - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); for (i = 0; i < vdev->no_of_vpath; i++) { @@ -1669,7 +1669,7 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) */ static void vxge_netpoll(struct net_device *dev) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; struct vxgedev *vdev; vdev = (struct vxgedev *)netdev_priv(dev); @@ -1821,7 +1821,7 @@ static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) { struct list_head *entry, *next; u64 del_mac = 0; - u8 *mac_address = (u8 *) (&del_mac); + u8 *mac_address = (u8 *)(&del_mac); /* Copy the mac address to delete from the list */ memcpy(mac_address, mac->macaddr, ETH_ALEN); @@ -2102,7 +2102,7 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) struct __vxge_hw_device *hldev; u64 reason; enum vxge_hw_status status; - struct vxgedev *vdev = (struct vxgedev *) dev_id;; + struct vxgedev *vdev = (struct vxgedev *)dev_id; vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__); @@ -2341,8 +2341,8 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) static void vxge_rem_isr(struct vxgedev *vdev) { - struct __vxge_hw_device *hldev; - hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev; + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); #ifdef CONFIG_PCI_MSI if (vdev->config.intr_type == MSI_X) { @@ -2583,7 +2583,7 @@ vxge_open(struct net_device *dev) "%s: %s:%d", dev->name, __func__, __LINE__); vdev = (struct vxgedev *)netdev_priv(dev); - hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); function_mode = vdev->config.device_hw_info.function_mode; /* make sure you have link off by default every time Nic is @@ -2811,7 +2811,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) dev->name, __func__, __LINE__); vdev = (struct vxgedev *)netdev_priv(dev); - hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); if (unlikely(!is_vxge_card_up(vdev))) return 0; @@ -3440,36 +3440,29 @@ _out0: * * This function will unregister and free network device */ -static void -vxge_device_unregister(struct __vxge_hw_device *hldev) +static void vxge_device_unregister(struct __vxge_hw_device *hldev) { struct vxgedev *vdev; struct net_device *dev; char buf[IFNAMSIZ]; -#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ - (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) - u32 level_trace; -#endif dev = hldev->ndev; vdev = netdev_priv(dev); -#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ - (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) - level_trace = vdev->level_trace; -#endif - vxge_debug_entryexit(level_trace, - "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); - memcpy(buf, vdev->ndev->name, IFNAMSIZ); + vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d", vdev->ndev->name, + __func__, __LINE__); + + memcpy(buf, dev->name, IFNAMSIZ); /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); flush_scheduled_work(); - vxge_debug_init(level_trace, "%s: ethernet device unregistered", buf); - vxge_debug_entryexit(level_trace, - "%s: %s:%d Exiting...", buf, __func__, __LINE__); + vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", + buf); + vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, + __func__, __LINE__); } /* @@ -3992,8 +3985,8 @@ static int vxge_pm_resume(struct pci_dev *pdev) static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *) pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *)pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; netif_device_detach(netdev); @@ -4022,8 +4015,8 @@ static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *) pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *)pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; struct vxgedev *vdev = netdev_priv(netdev); @@ -4048,8 +4041,8 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) */ static void vxge_io_resume(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *) pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *)pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; if (netif_running(netdev)) { @@ -4243,7 +4236,7 @@ static int vxge_probe_fw_update(struct vxgedev *vdev) static int __devinit vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; enum vxge_hw_status status; int ret; int high_dma = 0; @@ -4689,34 +4682,25 @@ _exit0: * Description: This function is called by the Pci subsystem to release a * PCI device and free up all resource held up by the device. */ -static void __devexit -vxge_remove(struct pci_dev *pdev) +static void __devexit vxge_remove(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; struct vxgedev *vdev = NULL; struct net_device *dev; int i = 0; -#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ - (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) - u32 level_trace; -#endif - hldev = (struct __vxge_hw_device *) pci_get_drvdata(pdev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(pdev); if (hldev == NULL) return; + dev = hldev->ndev; vdev = netdev_priv(dev); -#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ - (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) - level_trace = vdev->level_trace; -#endif - vxge_debug_entryexit(level_trace, - "%s:%d", __func__, __LINE__); + vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__); - vxge_debug_init(level_trace, - "%s : removing PCI device...", __func__); + vxge_debug_init(vdev->level_trace, "%s : removing PCI device...", + __func__); vxge_device_unregister(hldev); for (i = 0; i < vdev->no_of_vpath; i++) { @@ -4734,16 +4718,16 @@ vxge_remove(struct pci_dev *pdev) /* we are safe to free it now */ free_netdev(dev); - vxge_debug_init(level_trace, - "%s:%d Device unregistered", __func__, __LINE__); + vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered", + __func__, __LINE__); vxge_hw_device_terminate(hldev); pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - vxge_debug_entryexit(level_trace, - "%s:%d Exiting...", __func__, __LINE__); + vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__, + __LINE__); } static struct pci_error_handlers vxge_err_handler = { -- cgit v1.2.3-59-g8ed1b From c0c04c2a89cf6363da2940da59afd2e30001b991 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 11 Nov 2010 04:26:04 +0000 Subject: vxge: update driver version Update vxge driver version Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index b4eced19e45d..f05bb2f55e73 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h @@ -16,8 +16,8 @@ #define VXGE_VERSION_MAJOR "2" #define VXGE_VERSION_MINOR "0" -#define VXGE_VERSION_FIX "9" -#define VXGE_VERSION_BUILD "20840" +#define VXGE_VERSION_FIX "10" +#define VXGE_VERSION_BUILD "21808" #define VXGE_VERSION_FOR "k" #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) -- cgit v1.2.3-59-g8ed1b From 46b13fc5c0f239f36e84665c73087d5fa86bfd86 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 11 Nov 2010 06:57:19 +0000 Subject: neigh: reorder struct neighbour It is important to move nud_state outside of the often modified cache line (because of refcnt), to reduce false sharing in neigh_event_send() This is a followup of commit 0ed8ddf4045f (neigh: Protect neigh->ha[] with a seqlock) This gives a 7% speedup on routing test with IP route cache disabled. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 55590ab16b3e..815b2ce9f4a4 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -96,16 +96,16 @@ struct neighbour { struct neigh_parms *parms; unsigned long confirmed; unsigned long updated; - __u8 flags; - __u8 nud_state; - __u8 type; - __u8 dead; + rwlock_t lock; atomic_t refcnt; struct sk_buff_head arp_queue; struct timer_list timer; unsigned long used; atomic_t probes; - rwlock_t lock; + __u8 flags; + __u8 nud_state; + __u8 type; + __u8 dead; seqlock_t ha_lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; -- cgit v1.2.3-59-g8ed1b From 72cdd1d971c0deb1619c5c339270570c43647a78 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 11 Nov 2010 07:14:07 +0000 Subject: net: get rid of rtable->idev It seems idev field in struct rtable has no special purpose, but adding extra atomic ops. We hold refcounts on the device itself (using percpu data, so pretty cheap in current kernel). infiniband case is solved using dst.dev instead of idev->dev Removal of this field means routing without route cache is now using shared data, percpu data, and only potential contention is a pair of atomic ops on struct neighbour per forwarded packet. About 5% speedup on routing test. Signed-off-by: Eric Dumazet Cc: Herbert Xu Cc: Roland Dreier Cc: Sean Hefty Cc: Hal Rosenstock Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 8 ++++---- include/net/route.h | 2 -- net/ipv4/route.c | 37 ++++--------------------------------- net/ipv4/xfrm4_policy.c | 24 ------------------------ 4 files changed, 8 insertions(+), 63 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index a5ea1bce9689..c15fd2ea56c1 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -200,7 +200,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, src_in->sin_family = AF_INET; src_in->sin_addr.s_addr = rt->rt_src; - if (rt->idev->dev->flags & IFF_LOOPBACK) { + if (rt->dst.dev->flags & IFF_LOOPBACK) { ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); if (!ret) memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); @@ -208,12 +208,12 @@ static int addr4_resolve(struct sockaddr_in *src_in, } /* If the device does ARP internally, return 'done' */ - if (rt->idev->dev->flags & IFF_NOARP) { - rdma_copy_addr(addr, rt->idev->dev, NULL); + if (rt->dst.dev->flags & IFF_NOARP) { + rdma_copy_addr(addr, rt->dst.dev, NULL); goto put; } - neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev); + neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); if (!neigh || !(neigh->nud_state & NUD_VALID)) { neigh_event_send(rt->dst.neighbour, NULL); ret = -ENODATA; diff --git a/include/net/route.h b/include/net/route.h index 7e5e73bfa4de..cea533eaa853 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -55,8 +55,6 @@ struct rtable { /* Cache lookup keys */ struct flowi fl; - struct in_device *idev; - int rt_genid; unsigned rt_flags; __u16 rt_type; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 987bf9adb318..5955965c7953 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -140,13 +140,15 @@ static unsigned long expires_ljiffies; static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); static void ipv4_dst_destroy(struct dst_entry *dst); -static void ipv4_dst_ifdown(struct dst_entry *dst, - struct net_device *dev, int how); static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); static int rt_garbage_collect(struct dst_ops *ops); +static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + int how) +{ +} static struct dst_ops ipv4_dst_ops = { .family = AF_INET, @@ -1433,8 +1435,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt->dst.child = NULL; if (rt->dst.dev) dev_hold(rt->dst.dev); - if (rt->idev) - in_dev_hold(rt->idev); rt->dst.obsolete = -1; rt->dst.lastuse = jiffies; rt->dst.path = &rt->dst; @@ -1728,33 +1728,13 @@ static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer = rt->peer; - struct in_device *idev = rt->idev; if (peer) { rt->peer = NULL; inet_putpeer(peer); } - - if (idev) { - rt->idev = NULL; - in_dev_put(idev); - } } -static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, - int how) -{ - struct rtable *rt = (struct rtable *) dst; - struct in_device *idev = rt->idev; - if (dev != dev_net(dev)->loopback_dev && idev && idev->dev == dev) { - struct in_device *loopback_idev = - in_dev_get(dev_net(dev)->loopback_dev); - if (loopback_idev) { - rt->idev = loopback_idev; - in_dev_put(idev); - } - } -} static void ipv4_link_failure(struct sk_buff *skb) { @@ -1910,7 +1890,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->fl.iif = dev->ifindex; rth->dst.dev = init_net.loopback_dev; dev_hold(rth->dst.dev); - rth->idev = in_dev_get(rth->dst.dev); rth->fl.oif = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; @@ -2050,7 +2029,6 @@ static int __mkroute_input(struct sk_buff *skb, rth->fl.iif = in_dev->dev->ifindex; rth->dst.dev = (out_dev)->dev; dev_hold(rth->dst.dev); - rth->idev = in_dev_get(rth->dst.dev); rth->fl.oif = 0; rth->rt_spec_dst= spec_dst; @@ -2231,7 +2209,6 @@ local_input: rth->fl.iif = dev->ifindex; rth->dst.dev = net->loopback_dev; dev_hold(rth->dst.dev); - rth->idev = in_dev_get(rth->dst.dev); rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->dst.input= ip_local_deliver; @@ -2417,9 +2394,6 @@ static int __mkroute_output(struct rtable **result, if (!rth) return -ENOBUFS; - in_dev_hold(in_dev); - rth->idev = in_dev; - atomic_set(&rth->dst.__refcnt, 1); rth->dst.flags= DST_HOST; if (IN_DEV_CONF_GET(in_dev, NOXFRM)) @@ -2759,9 +2733,6 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi rt->fl = ort->fl; - rt->idev = ort->idev; - if (rt->idev) - in_dev_hold(rt->idev); rt->rt_genid = rt_genid(net); rt->rt_flags = ort->rt_flags; rt->rt_type = ort->rt_type; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 4464f3bff6a7..dd1fd8c473fc 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -80,10 +80,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.dst.dev = dev; dev_hold(dev); - xdst->u.rt.idev = in_dev_get(dev); - if (!xdst->u.rt.idev) - return -ENODEV; - xdst->u.rt.peer = rt->peer; if (rt->peer) atomic_inc(&rt->peer->refcnt); @@ -189,8 +185,6 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; - if (likely(xdst->u.rt.idev)) - in_dev_put(xdst->u.rt.idev); if (likely(xdst->u.rt.peer)) inet_putpeer(xdst->u.rt.peer); xfrm_dst_destroy(xdst); @@ -199,27 +193,9 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int unregister) { - struct xfrm_dst *xdst; - if (!unregister) return; - xdst = (struct xfrm_dst *)dst; - if (xdst->u.rt.idev->dev == dev) { - struct in_device *loopback_idev = - in_dev_get(dev_net(dev)->loopback_dev); - BUG_ON(!loopback_idev); - - do { - in_dev_put(xdst->u.rt.idev); - xdst->u.rt.idev = loopback_idev; - in_dev_hold(loopback_idev); - xdst = (struct xfrm_dst *)xdst->u.dst.child; - } while (xdst->u.dst.xfrm); - - __in_dev_put(loopback_idev); - } - xfrm_dst_ifdown(dst, dev); } -- cgit v1.2.3-59-g8ed1b From c753796769e4fb0cd813b6e5801b3c01f4681d4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Nov 2010 17:07:48 -0800 Subject: ipv4: Make rt->fl.iif tests lest obscure. When we test rt->fl.iif against zero, we're seeing if it's an output or an input route. Make that explicit with some helper functions. Signed-off-by: David S. Miller --- include/net/dn_route.h | 10 ++++++++++ include/net/route.h | 10 ++++++++++ net/decnet/dn_route.c | 4 ++-- net/ipv4/icmp.c | 4 ++-- net/ipv4/igmp.c | 2 +- net/ipv4/ip_gre.c | 2 +- net/ipv4/ipmr.c | 2 +- net/ipv4/route.c | 20 ++++++++++---------- net/netfilter/ipvs/ip_vs_xmit.c | 8 +++++--- 9 files changed, 42 insertions(+), 20 deletions(-) diff --git a/include/net/dn_route.h b/include/net/dn_route.h index ccadab3aa3f6..9b185df265fb 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -80,6 +80,16 @@ struct dn_route { unsigned rt_type; }; +static inline bool dn_is_input_route(struct dn_route *rt) +{ + return rt->fl.iif != 0; +} + +static inline bool dn_is_output_route(struct dn_route *rt) +{ + return rt->fl.iif == 0; +} + extern void dn_route_init(void); extern void dn_route_cleanup(void); diff --git a/include/net/route.h b/include/net/route.h index cea533eaa853..5cd46d1c0e14 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -71,6 +71,16 @@ struct rtable { struct inet_peer *peer; /* long-living peer info */ }; +static inline bool rt_is_input_route(struct rtable *rt) +{ + return rt->fl.iif != 0; +} + +static inline bool rt_is_output_route(struct rtable *rt) +{ + return rt->fl.iif == 0; +} + struct ip_rt_acct { __u32 o_bytes; __u32 o_packets; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 94a9eb1d313e..474d54dd08c2 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1181,7 +1181,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl if ((flp->fld_dst == rt->fl.fld_dst) && (flp->fld_src == rt->fl.fld_src) && (flp->mark == rt->fl.mark) && - (rt->fl.iif == 0) && + dn_is_output_route(rt) && (rt->fl.oif == flp->oif)) { dst_use(&rt->dst, jiffies); rcu_read_unlock_bh(); @@ -1512,7 +1512,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, rt->dst.error) < 0) goto rtattr_failure; - if (rt->fl.iif) + if (dn_is_input_route(rt)) RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); nlh->nlmsg_len = skb_tail_pointer(skb) - b; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 96bc7f9475a3..c6e2affafbd3 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -506,8 +506,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) struct net_device *dev = NULL; rcu_read_lock(); - if (rt->fl.iif && - net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) + if (rt_is_input_route(rt) && + net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) dev = dev_get_by_index_rcu(net, rt->fl.iif); if (dev) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index c8877c6c7216..08d0d81ffc15 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -961,7 +961,7 @@ int igmp_rcv(struct sk_buff *skb) case IGMP_HOST_MEMBERSHIP_REPORT: case IGMPV2_HOST_MEMBERSHIP_REPORT: /* Is it our report looped back? */ - if (skb_rtable(skb)->fl.iif == 0) + if (rt_is_output_route(skb_rtable(skb))) break; /* don't rely on MC router hearing unicast reports */ if (skb->pkt_type == PACKET_MULTICAST || diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 70ff77f02eee..cab2057d5430 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -634,7 +634,7 @@ static int ipgre_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_IPGRE_BROADCAST if (ipv4_is_multicast(iph->daddr)) { /* Looped back packet, drop it! */ - if (skb_rtable(skb)->fl.iif == 0) + if (rt_is_output_route(skb_rtable(skb))) goto drop; tunnel->dev->stats.multicast++; skb->pkt_type = PACKET_BROADCAST; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 86dd5691af46..ef2b0089e0ea 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1654,7 +1654,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (mrt->vif_table[vif].dev != skb->dev) { int true_vifi; - if (skb_rtable(skb)->fl.iif == 0) { + if (rt_is_output_route(skb_rtable(skb))) { /* It is our own packet, looped back. * Very complicated situation... * diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5955965c7953..66610ea3c87b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -623,7 +623,7 @@ static inline int rt_fast_clean(struct rtable *rth) /* Kill broadcast/multicast entries very aggresively, if they collide in hash table with more useful entries */ return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) && - rth->fl.iif && rth->dst.rt_next; + rt_is_input_route(rth) && rth->dst.rt_next; } static inline int rt_valuable(struct rtable *rth) @@ -668,7 +668,7 @@ static inline u32 rt_score(struct rtable *rt) if (rt_valuable(rt)) score |= (1<<31); - if (!rt->fl.iif || + if (rt_is_output_route(rt) || !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL))) score |= (1<<30); @@ -1126,7 +1126,7 @@ restart: */ rt->dst.flags |= DST_NOCACHE; - if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { + if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { int err = arp_bind_neighbour(&rt->dst); if (err) { if (net_ratelimit()) @@ -1224,7 +1224,7 @@ restart: /* Try to bind route to arp only if it is output route or unicast forwarding path. */ - if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { + if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { int err = arp_bind_neighbour(&rt->dst); if (err) { spin_unlock_bh(rt_hash_lock_addr(hash)); @@ -1406,7 +1406,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, if (rth->fl.fl4_dst != daddr || rth->fl.fl4_src != skeys[i] || rth->fl.oif != ikeys[k] || - rth->fl.iif != 0 || + rt_is_input_route(rth) || rt_is_expired(rth) || !net_eq(dev_net(rth->dst.dev), net)) { rthp = &rth->dst.rt_next; @@ -1666,7 +1666,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, rth->rt_dst != daddr || rth->rt_src != iph->saddr || rth->fl.oif != ikeys[k] || - rth->fl.iif != 0 || + rt_is_input_route(rth) || dst_metric_locked(&rth->dst, RTAX_MTU) || !net_eq(dev_net(rth->dst.dev), net) || rt_is_expired(rth)) @@ -1770,7 +1770,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) __be32 src; struct fib_result res; - if (rt->fl.iif == 0) + if (rt_is_output_route(rt)) src = rt->rt_src; else { rcu_read_lock(); @@ -2669,7 +2669,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, rth = rcu_dereference_bh(rth->dst.rt_next)) { if (rth->fl.fl4_dst == flp->fl4_dst && rth->fl.fl4_src == flp->fl4_src && - rth->fl.iif == 0 && + rt_is_output_route(rth) && rth->fl.oif == flp->oif && rth->fl.mark == flp->mark && !((rth->fl.fl4_tos ^ flp->fl4_tos) & @@ -2824,7 +2824,7 @@ static int rt_fill_info(struct net *net, if (rt->dst.tclassid) NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); #endif - if (rt->fl.iif) + if (rt_is_input_route(rt)) NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); else if (rt->rt_src != rt->fl.fl4_src) NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src); @@ -2849,7 +2849,7 @@ static int rt_fill_info(struct net *net, } } - if (rt->fl.iif) { + if (rt_is_input_route(rt)) { #ifdef CONFIG_IP_MROUTE __be32 dst = rt->rt_dst; diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index de04ea39cde8..10bd39c0ae2d 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -169,7 +169,7 @@ __ip_vs_reroute_locally(struct sk_buff *skb) struct net *net = dev_net(dev); struct iphdr *iph = ip_hdr(skb); - if (rt->fl.iif) { + if (rt_is_input_route(rt)) { unsigned long orefdst = skb->_skb_refdst; if (ip_route_input(skb, iph->daddr, iph->saddr, @@ -552,7 +552,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, #endif /* From world but DNAT to loopback address? */ - if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + if (local && ipv4_is_loopback(rt->rt_dst) && + rt_is_input_route(skb_rtable(skb))) { IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): " "stopping DNAT to loopback address"); goto tx_error_put; @@ -1165,7 +1166,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, #endif /* From world but DNAT to loopback address? */ - if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + if (local && ipv4_is_loopback(rt->rt_dst) && + rt_is_input_route(skb_rtable(skb))) { IP_VS_DBG(1, "%s(): " "stopping DNAT to loopback %pI4\n", __func__, &cp->daddr.ip); -- cgit v1.2.3-59-g8ed1b From f5539b5bfa2e00f2a6fd35731db66142a2f327c0 Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Fri, 12 Nov 2010 12:43:34 -0800 Subject: stmmac: update the driver documentation Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- Documentation/networking/stmmac.txt | 48 ++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index 7ee770b5ef5f..80a7a3454902 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -7,7 +7,7 @@ This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers (Synopsys IP blocks); it has been fully tested on STLinux platforms. Currently this network device driver is for all STM embedded MAC/GMAC -(7xxx SoCs). +(7xxx SoCs). Other platforms start using it i.e. ARM SPEAr. DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100 Universal version 4.0 have been used for developing the first code @@ -95,9 +95,14 @@ Several information came from the platform; please refer to the driver's Header file in include/linux directory. struct plat_stmmacenet_data { - int bus_id; - int pbl; - int has_gmac; + int bus_id; + int pbl; + int clk_csr; + int has_gmac; + int enh_desc; + int tx_coe; + int bugged_jumbo; + int pmt; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(unsigned long ioaddr); #ifdef CONFIG_STM_DRIVERS @@ -114,6 +119,12 @@ Where: registers (on STM platforms); - has_gmac: GMAC core is on board (get it at run-time in the next step); - bus_id: bus identifier. +- tx_coe: core is able to perform the tx csum in HW. +- enh_desc: if sets the MAC will use the enhanced descriptor structure. +- clk_csr: CSR Clock range selection. +- bugged_jumbo: some HWs are not able to perform the csum in HW for + over-sized frames due to limited buffer sizes. Setting this + flag the csum will be done in SW on JUMBO frames. struct plat_stmmacphy_data { int bus_id; @@ -131,13 +142,28 @@ Where: - interface: physical MII interface mode; - phy_reset: hook to reset HW function. +SOURCES: +- Kconfig +- Makefile +- stmmac_main.c: main network device driver; +- stmmac_mdio.c: mdio functions; +- stmmac_ethtool.c: ethtool support; +- stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts + Only tested on ST40 platforms based. +- stmmac.h: private driver structure; +- common.h: common definitions and VFTs; +- descs.h: descriptor structure definitions; +- dwmac1000_core.c: GMAC core functions; +- dwmac1000_dma.c: dma functions for the GMAC chip; +- dwmac1000.h: specific header file for the GMAC; +- dwmac100_core: MAC 100 core and dma code; +- dwmac100_dma.c: dma funtions for the MAC chip; +- dwmac1000.h: specific header file for the MAC; +- dwmac_lib.c: generic DMA functions shared among chips +- enh_desc.c: functions for handling enhanced descriptors +- norm_desc.c: functions for handling normal descriptors + TODO: -- Continue to make the driver more generic and suitable for other Synopsys - Ethernet controllers used on other architectures (i.e. ARM). -- 10G controllers are not supported. -- MAC uses Normal descriptors and GMAC uses enhanced ones. - This is a limit that should be reviewed. MAC could want to - use the enhanced structure. -- Checksumming: Rx/Tx csum is done in HW in case of GMAC only. +- XGMAC controller is not supported. - Review the timer optimisation code to use an embedded device that seems to be available in new chip generations. -- cgit v1.2.3-59-g8ed1b From 1d7138de878d1d4210727c1200193e69596f93b3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 12 Nov 2010 05:46:50 +0000 Subject: igmp: RCU conversion of in_dev->mc_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in_dev->mc_list is protected by one rwlock (in_dev->mc_list_lock). This can easily be converted to a RCU protection. Writers hold RTNL, so mc_list_lock is removed, not replaced by a spinlock. Signed-off-by: Eric Dumazet Cc: Cypher Wu Cc: Américo Wang Signed-off-by: David S. Miller --- include/linux/igmp.h | 12 ++- include/linux/inetdevice.h | 5 +- include/net/inet_sock.h | 2 +- net/ipv4/igmp.c | 223 +++++++++++++++++++++------------------------ 4 files changed, 115 insertions(+), 127 deletions(-) diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 93fc2449af10..7d164670f264 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -167,10 +167,10 @@ struct ip_sf_socklist { */ struct ip_mc_socklist { - struct ip_mc_socklist *next; + struct ip_mc_socklist __rcu *next_rcu; struct ip_mreqn multi; unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ - struct ip_sf_socklist *sflist; + struct ip_sf_socklist __rcu *sflist; struct rcu_head rcu; }; @@ -186,11 +186,14 @@ struct ip_sf_list { struct ip_mc_list { struct in_device *interface; __be32 multiaddr; + unsigned int sfmode; struct ip_sf_list *sources; struct ip_sf_list *tomb; - unsigned int sfmode; unsigned long sfcount[2]; - struct ip_mc_list *next; + union { + struct ip_mc_list *next; + struct ip_mc_list __rcu *next_rcu; + }; struct timer_list timer; int users; atomic_t refcnt; @@ -201,6 +204,7 @@ struct ip_mc_list { char loaded; unsigned char gsquery; /* check source marks? */ unsigned char crcount; + struct rcu_head rcu; }; /* V3 exponential field decoding */ diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index ccd5b07d678d..380ba6bc5db1 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -52,9 +52,8 @@ struct in_device { atomic_t refcnt; int dead; struct in_ifaddr *ifa_list; /* IP ifaddr chain */ - rwlock_t mc_list_lock; - struct ip_mc_list *mc_list; /* IP multicast filter chain */ - int mc_count; /* Number of installed mcasts */ + struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ + int mc_count; /* Number of installed mcasts */ spinlock_t mc_tomb_lock; struct ip_mc_list *mc_tomb; unsigned long mr_v1_seen; diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 1989cfd7405f..8945f9fb192a 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -141,7 +141,7 @@ struct inet_sock { nodefrag:1; int mc_index; __be32 mc_addr; - struct ip_mc_socklist *mc_list; + struct ip_mc_socklist __rcu *mc_list; struct { unsigned int flags; unsigned int fragsize; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 08d0d81ffc15..6f49d6c087da 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -149,11 +149,17 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc); static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, int sfcount, __be32 *psfsrc, int delta); + +static void ip_mc_list_reclaim(struct rcu_head *head) +{ + kfree(container_of(head, struct ip_mc_list, rcu)); +} + static void ip_ma_put(struct ip_mc_list *im) { if (atomic_dec_and_test(&im->refcnt)) { in_dev_put(im->interface); - kfree(im); + call_rcu(&im->rcu, ip_mc_list_reclaim); } } @@ -163,7 +169,7 @@ static void ip_ma_put(struct ip_mc_list *im) * Timer management */ -static __inline__ void igmp_stop_timer(struct ip_mc_list *im) +static void igmp_stop_timer(struct ip_mc_list *im) { spin_lock_bh(&im->lock); if (del_timer(&im->timer)) @@ -496,14 +502,24 @@ empty_source: return skb; } +#define for_each_pmc_rcu(in_dev, pmc) \ + for (pmc = rcu_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rcu_dereference(pmc->next_rcu)) + +#define for_each_pmc_rtnl(in_dev, pmc) \ + for (pmc = rtnl_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rtnl_dereference(pmc->next_rcu)) + static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) { struct sk_buff *skb = NULL; int type; if (!pmc) { - read_lock(&in_dev->mc_list_lock); - for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, pmc) { if (pmc->multiaddr == IGMP_ALL_HOSTS) continue; spin_lock_bh(&pmc->lock); @@ -514,7 +530,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) skb = add_grec(skb, pmc, type, 0, 0); spin_unlock_bh(&pmc->lock); } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); } else { spin_lock_bh(&pmc->lock); if (pmc->sfcount[MCAST_EXCLUDE]) @@ -556,7 +572,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) struct sk_buff *skb = NULL; int type, dtype; - read_lock(&in_dev->mc_list_lock); + rcu_read_lock(); spin_lock_bh(&in_dev->mc_tomb_lock); /* deleted MCA's */ @@ -593,7 +609,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) spin_unlock_bh(&in_dev->mc_tomb_lock); /* change recs */ - for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rcu(in_dev, pmc) { spin_lock_bh(&pmc->lock); if (pmc->sfcount[MCAST_EXCLUDE]) { type = IGMPV3_BLOCK_OLD_SOURCES; @@ -616,7 +632,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) } spin_unlock_bh(&pmc->lock); } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); if (!skb) return; @@ -813,14 +829,14 @@ static void igmp_heard_report(struct in_device *in_dev, __be32 group) if (group == IGMP_ALL_HOSTS) return; - read_lock(&in_dev->mc_list_lock); - for (im=in_dev->mc_list; im!=NULL; im=im->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, im) { if (im->multiaddr == group) { igmp_stop_timer(im); break; } } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); } static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, @@ -906,8 +922,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, * - Use the igmp->igmp_code field as the maximum * delay possible */ - read_lock(&in_dev->mc_list_lock); - for (im=in_dev->mc_list; im!=NULL; im=im->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, im) { int changed; if (group && group != im->multiaddr) @@ -925,7 +941,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, if (changed) igmp_mod_timer(im, max_delay); } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); } /* called in rcu_read_lock() section */ @@ -1110,8 +1126,8 @@ static void igmpv3_clear_delrec(struct in_device *in_dev) kfree(pmc); } /* clear dead sources, too */ - read_lock(&in_dev->mc_list_lock); - for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, pmc) { struct ip_sf_list *psf, *psf_next; spin_lock_bh(&pmc->lock); @@ -1123,7 +1139,7 @@ static void igmpv3_clear_delrec(struct in_device *in_dev) kfree(psf); } } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); } #endif @@ -1209,7 +1225,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) ASSERT_RTNL(); - for (im=in_dev->mc_list; im; im=im->next) { + for_each_pmc_rtnl(in_dev, im) { if (im->multiaddr == addr) { im->users++; ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0); @@ -1217,7 +1233,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) } } - im = kmalloc(sizeof(*im), GFP_KERNEL); + im = kzalloc(sizeof(*im), GFP_KERNEL); if (!im) goto out; @@ -1227,26 +1243,18 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) im->multiaddr = addr; /* initial mode is (EX, empty) */ im->sfmode = MCAST_EXCLUDE; - im->sfcount[MCAST_INCLUDE] = 0; im->sfcount[MCAST_EXCLUDE] = 1; - im->sources = NULL; - im->tomb = NULL; - im->crcount = 0; atomic_set(&im->refcnt, 1); spin_lock_init(&im->lock); #ifdef CONFIG_IP_MULTICAST - im->tm_running = 0; setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im); im->unsolicit_count = IGMP_Unsolicited_Report_Count; - im->reporter = 0; - im->gsquery = 0; #endif - im->loaded = 0; - write_lock_bh(&in_dev->mc_list_lock); - im->next = in_dev->mc_list; - in_dev->mc_list = im; + + im->next_rcu = in_dev->mc_list; in_dev->mc_count++; - write_unlock_bh(&in_dev->mc_list_lock); + rcu_assign_pointer(in_dev->mc_list, im); + #ifdef CONFIG_IP_MULTICAST igmpv3_del_delrec(in_dev, im->multiaddr); #endif @@ -1287,17 +1295,18 @@ EXPORT_SYMBOL(ip_mc_rejoin_group); void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) { - struct ip_mc_list *i, **ip; + struct ip_mc_list *i; + struct ip_mc_list __rcu **ip; ASSERT_RTNL(); - for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { + for (ip = &in_dev->mc_list; + (i = rtnl_dereference(*ip)) != NULL; + ip = &i->next_rcu) { if (i->multiaddr == addr) { if (--i->users == 0) { - write_lock_bh(&in_dev->mc_list_lock); - *ip = i->next; + *ip = i->next_rcu; in_dev->mc_count--; - write_unlock_bh(&in_dev->mc_list_lock); igmp_group_dropped(i); if (!in_dev->dead) @@ -1316,34 +1325,34 @@ EXPORT_SYMBOL(ip_mc_dec_group); void ip_mc_unmap(struct in_device *in_dev) { - struct ip_mc_list *i; + struct ip_mc_list *pmc; ASSERT_RTNL(); - for (i = in_dev->mc_list; i; i = i->next) - igmp_group_dropped(i); + for_each_pmc_rtnl(in_dev, pmc) + igmp_group_dropped(pmc); } void ip_mc_remap(struct in_device *in_dev) { - struct ip_mc_list *i; + struct ip_mc_list *pmc; ASSERT_RTNL(); - for (i = in_dev->mc_list; i; i = i->next) - igmp_group_added(i); + for_each_pmc_rtnl(in_dev, pmc) + igmp_group_added(pmc); } /* Device going down */ void ip_mc_down(struct in_device *in_dev) { - struct ip_mc_list *i; + struct ip_mc_list *pmc; ASSERT_RTNL(); - for (i=in_dev->mc_list; i; i=i->next) - igmp_group_dropped(i); + for_each_pmc_rtnl(in_dev, pmc) + igmp_group_dropped(pmc); #ifdef CONFIG_IP_MULTICAST in_dev->mr_ifc_count = 0; @@ -1374,7 +1383,6 @@ void ip_mc_init_dev(struct in_device *in_dev) in_dev->mr_qrv = IGMP_Unsolicited_Report_Count; #endif - rwlock_init(&in_dev->mc_list_lock); spin_lock_init(&in_dev->mc_tomb_lock); } @@ -1382,14 +1390,14 @@ void ip_mc_init_dev(struct in_device *in_dev) void ip_mc_up(struct in_device *in_dev) { - struct ip_mc_list *i; + struct ip_mc_list *pmc; ASSERT_RTNL(); ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); - for (i=in_dev->mc_list; i; i=i->next) - igmp_group_added(i); + for_each_pmc_rtnl(in_dev, pmc) + igmp_group_added(pmc); } /* @@ -1405,17 +1413,13 @@ void ip_mc_destroy_dev(struct in_device *in_dev) /* Deactivate timers */ ip_mc_down(in_dev); - write_lock_bh(&in_dev->mc_list_lock); - while ((i = in_dev->mc_list) != NULL) { - in_dev->mc_list = i->next; + while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) { + in_dev->mc_list = i->next_rcu; in_dev->mc_count--; - write_unlock_bh(&in_dev->mc_list_lock); + igmp_group_dropped(i); ip_ma_put(i); - - write_lock_bh(&in_dev->mc_list_lock); } - write_unlock_bh(&in_dev->mc_list_lock); } /* RTNL is locked */ @@ -1513,18 +1517,18 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode, if (!in_dev) return -ENODEV; - read_lock(&in_dev->mc_list_lock); - for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, pmc) { if (*pmca == pmc->multiaddr) break; } if (!pmc) { /* MCA not found?? bug */ - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); return -ESRCH; } spin_lock_bh(&pmc->lock); - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); #ifdef CONFIG_IP_MULTICAST sf_markstate(pmc); #endif @@ -1685,18 +1689,18 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, if (!in_dev) return -ENODEV; - read_lock(&in_dev->mc_list_lock); - for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, pmc) { if (*pmca == pmc->multiaddr) break; } if (!pmc) { /* MCA not found?? bug */ - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); return -ESRCH; } spin_lock_bh(&pmc->lock); - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); #ifdef CONFIG_IP_MULTICAST sf_markstate(pmc); @@ -1793,7 +1797,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) err = -EADDRINUSE; ifindex = imr->imr_ifindex; - for (i = inet->mc_list; i; i = i->next) { + for_each_pmc_rtnl(inet, i) { if (i->multi.imr_multiaddr.s_addr == addr && i->multi.imr_ifindex == ifindex) goto done; @@ -1807,7 +1811,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) goto done; memcpy(&iml->multi, imr, sizeof(*imr)); - iml->next = inet->mc_list; + iml->next_rcu = inet->mc_list; iml->sflist = NULL; iml->sfmode = MCAST_EXCLUDE; rcu_assign_pointer(inet->mc_list, iml); @@ -1821,17 +1825,14 @@ EXPORT_SYMBOL(ip_mc_join_group); static void ip_sf_socklist_reclaim(struct rcu_head *rp) { - struct ip_sf_socklist *psf; - - psf = container_of(rp, struct ip_sf_socklist, rcu); + kfree(container_of(rp, struct ip_sf_socklist, rcu)); /* sk_omem_alloc should have been decreased by the caller*/ - kfree(psf); } static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, struct in_device *in_dev) { - struct ip_sf_socklist *psf = iml->sflist; + struct ip_sf_socklist *psf = rtnl_dereference(iml->sflist); int err; if (psf == NULL) { @@ -1851,11 +1852,8 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, static void ip_mc_socklist_reclaim(struct rcu_head *rp) { - struct ip_mc_socklist *iml; - - iml = container_of(rp, struct ip_mc_socklist, rcu); + kfree(container_of(rp, struct ip_mc_socklist, rcu)); /* sk_omem_alloc should have been decreased by the caller*/ - kfree(iml); } @@ -1866,7 +1864,8 @@ static void ip_mc_socklist_reclaim(struct rcu_head *rp) int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) { struct inet_sock *inet = inet_sk(sk); - struct ip_mc_socklist *iml, **imlp; + struct ip_mc_socklist *iml; + struct ip_mc_socklist __rcu **imlp; struct in_device *in_dev; struct net *net = sock_net(sk); __be32 group = imr->imr_multiaddr.s_addr; @@ -1876,7 +1875,9 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) rtnl_lock(); in_dev = ip_mc_find_dev(net, imr); ifindex = imr->imr_ifindex; - for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) { + for (imlp = &inet->mc_list; + (iml = rtnl_dereference(*imlp)) != NULL; + imlp = &iml->next_rcu) { if (iml->multi.imr_multiaddr.s_addr != group) continue; if (ifindex) { @@ -1888,7 +1889,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) (void) ip_mc_leave_src(sk, iml, in_dev); - rcu_assign_pointer(*imlp, iml->next); + *imlp = iml->next_rcu; if (in_dev) ip_mc_dec_group(in_dev, group); @@ -1934,7 +1935,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct } err = -EADDRNOTAVAIL; - for (pmc=inet->mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rtnl(inet, pmc) { if ((pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr) && (pmc->multi.imr_ifindex == imr.imr_ifindex)) @@ -1958,7 +1959,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct pmc->sfmode = omode; } - psl = pmc->sflist; + psl = rtnl_dereference(pmc->sflist); if (!add) { if (!psl) goto done; /* err = -EADDRNOTAVAIL */ @@ -2077,7 +2078,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) goto done; } - for (pmc=inet->mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rtnl(inet, pmc) { if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && pmc->multi.imr_ifindex == imr.imr_ifindex) break; @@ -2107,7 +2108,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr, msf->imsf_fmode, 0, NULL, 0); } - psl = pmc->sflist; + psl = rtnl_dereference(pmc->sflist); if (psl) { (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, psl->sl_count, psl->sl_addr, 0); @@ -2155,7 +2156,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, } err = -EADDRNOTAVAIL; - for (pmc=inet->mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rtnl(inet, pmc) { if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && pmc->multi.imr_ifindex == imr.imr_ifindex) break; @@ -2163,7 +2164,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, if (!pmc) /* must have a prior join */ goto done; msf->imsf_fmode = pmc->sfmode; - psl = pmc->sflist; + psl = rtnl_dereference(pmc->sflist); rtnl_unlock(); if (!psl) { len = 0; @@ -2208,7 +2209,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, err = -EADDRNOTAVAIL; - for (pmc=inet->mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rtnl(inet, pmc) { if (pmc->multi.imr_multiaddr.s_addr == addr && pmc->multi.imr_ifindex == gsf->gf_interface) break; @@ -2216,7 +2217,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, if (!pmc) /* must have a prior join */ goto done; gsf->gf_fmode = pmc->sfmode; - psl = pmc->sflist; + psl = rtnl_dereference(pmc->sflist); rtnl_unlock(); count = psl ? psl->sl_count : 0; copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc; @@ -2257,7 +2258,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) goto out; rcu_read_lock(); - for (pmc=rcu_dereference(inet->mc_list); pmc; pmc=rcu_dereference(pmc->next)) { + for_each_pmc_rcu(inet, pmc) { if (pmc->multi.imr_multiaddr.s_addr == loc_addr && pmc->multi.imr_ifindex == dif) break; @@ -2265,7 +2266,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) ret = inet->mc_all; if (!pmc) goto unlock; - psl = pmc->sflist; + psl = rcu_dereference(pmc->sflist); ret = (pmc->sfmode == MCAST_EXCLUDE); if (!psl) goto unlock; @@ -2300,10 +2301,10 @@ void ip_mc_drop_socket(struct sock *sk) return; rtnl_lock(); - while ((iml = inet->mc_list) != NULL) { + while ((iml = rtnl_dereference(inet->mc_list)) != NULL) { struct in_device *in_dev; - rcu_assign_pointer(inet->mc_list, iml->next); + inet->mc_list = iml->next_rcu; in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); (void) ip_mc_leave_src(sk, iml, in_dev); if (in_dev != NULL) { @@ -2323,8 +2324,8 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p struct ip_sf_list *psf; int rv = 0; - read_lock(&in_dev->mc_list_lock); - for (im=in_dev->mc_list; im; im=im->next) { + rcu_read_lock(); + for_each_pmc_rcu(in_dev, im) { if (im->multiaddr == mc_addr) break; } @@ -2345,7 +2346,7 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p } else rv = 1; /* unspecified source; tentatively allow */ } - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); return rv; } @@ -2371,13 +2372,11 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) in_dev = __in_dev_get_rcu(state->dev); if (!in_dev) continue; - read_lock(&in_dev->mc_list_lock); - im = in_dev->mc_list; + im = rcu_dereference(in_dev->mc_list); if (im) { state->in_dev = in_dev; break; } - read_unlock(&in_dev->mc_list_lock); } return im; } @@ -2385,11 +2384,9 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im) { struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - im = im->next; - while (!im) { - if (likely(state->in_dev != NULL)) - read_unlock(&state->in_dev->mc_list_lock); + im = rcu_dereference(im->next_rcu); + while (!im) { state->dev = next_net_device_rcu(state->dev); if (!state->dev) { state->in_dev = NULL; @@ -2398,8 +2395,7 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li state->in_dev = __in_dev_get_rcu(state->dev); if (!state->in_dev) continue; - read_lock(&state->in_dev->mc_list_lock); - im = state->in_dev->mc_list; + im = rcu_dereference(state->in_dev->mc_list); } return im; } @@ -2435,10 +2431,8 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v) __releases(rcu) { struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - if (likely(state->in_dev != NULL)) { - read_unlock(&state->in_dev->mc_list_lock); - state->in_dev = NULL; - } + + state->in_dev = NULL; state->dev = NULL; rcu_read_unlock(); } @@ -2460,7 +2454,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v) querier = "NONE"; #endif - if (state->in_dev->mc_list == im) { + if (rcu_dereference(state->in_dev->mc_list) == im) { seq_printf(seq, "%d\t%-10s: %5d %7s\n", state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier); } @@ -2519,8 +2513,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) idev = __in_dev_get_rcu(state->dev); if (unlikely(idev == NULL)) continue; - read_lock(&idev->mc_list_lock); - im = idev->mc_list; + im = rcu_dereference(idev->mc_list); if (likely(im != NULL)) { spin_lock_bh(&im->lock); psf = im->sources; @@ -2531,7 +2524,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) } spin_unlock_bh(&im->lock); } - read_unlock(&idev->mc_list_lock); } return psf; } @@ -2545,9 +2537,6 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l spin_unlock_bh(&state->im->lock); state->im = state->im->next; while (!state->im) { - if (likely(state->idev != NULL)) - read_unlock(&state->idev->mc_list_lock); - state->dev = next_net_device_rcu(state->dev); if (!state->dev) { state->idev = NULL; @@ -2556,8 +2545,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l state->idev = __in_dev_get_rcu(state->dev); if (!state->idev) continue; - read_lock(&state->idev->mc_list_lock); - state->im = state->idev->mc_list; + state->im = rcu_dereference(state->idev->mc_list); } if (!state->im) break; @@ -2603,10 +2591,7 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) spin_unlock_bh(&state->im->lock); state->im = NULL; } - if (likely(state->idev != NULL)) { - read_unlock(&state->idev->mc_list_lock); - state->idev = NULL; - } + state->idev = NULL; state->dev = NULL; rcu_read_unlock(); } -- cgit v1.2.3-59-g8ed1b From e85eb11782259dc39502807f3ec903a7b82b1bab Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Thu, 11 Nov 2010 12:31:21 +0000 Subject: net: Kconfig whitespace cleanup Many lines in Kconfig start withe 8 spaces instead of a TAB, and even sometimes with 7 spaces. Replace 10 or 9 spaces, or TAB + 1 space, by TAB + 2 spaces, and 8 or 7 spaces by TAB. Signed-off-by: Philippe De Muyter Signed-off-by: David S. Miller --- drivers/net/Kconfig | 224 ++++++++++++++++++++++++++-------------------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index fa62a63db166..0a7e6cea0082 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1533,7 +1533,7 @@ config E100 - to identify the adapter. + to identify the adapter. For the latest Intel PRO/100 network driver for Linux, see: @@ -1786,17 +1786,17 @@ config KS8842 tristate "Micrel KSZ8841/42 with generic bus interface" depends on HAS_IOMEM && DMA_ENGINE help - This platform driver is for KSZ8841(1-port) / KS8842(2-port) - ethernet switch chip (managed, VLAN, QoS) from Micrel or - Timberdale(FPGA). + This platform driver is for KSZ8841(1-port) / KS8842(2-port) + ethernet switch chip (managed, VLAN, QoS) from Micrel or + Timberdale(FPGA). config KS8851 - tristate "Micrel KS8851 SPI" - depends on SPI - select MII + tristate "Micrel KS8851 SPI" + depends on SPI + select MII select CRC32 - help - SPI driver for Micrel KS8851 SPI attached network chip. + help + SPI driver for Micrel KS8851 SPI attached network chip. config KS8851_MLL tristate "Micrel KS8851 MLL" @@ -2133,25 +2133,25 @@ config IP1000 will be called ipg. This is recommended. config IGB - tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" - depends on PCI - ---help--- - This driver supports Intel(R) 82575/82576 gigabit ethernet family of - adapters. For more information on how to identify your adapter, go - to the Adapter & Driver ID Guide at: + tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" + depends on PCI + ---help--- + This driver supports Intel(R) 82575/82576 gigabit ethernet family of + adapters. For more information on how to identify your adapter, go + to the Adapter & Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called igb. + To compile this driver as a module, choose M here. The module + will be called igb. config IGB_DCA bool "Direct Cache Access (DCA) Support" @@ -2163,25 +2163,25 @@ config IGB_DCA is used, with the intent of lessening the impact of cache misses. config IGBVF - tristate "Intel(R) 82576 Virtual Function Ethernet support" - depends on PCI - ---help--- - This driver supports Intel(R) 82576 virtual functions. For more - information on how to identify your adapter, go to the Adapter & - Driver ID Guide at: + tristate "Intel(R) 82576 Virtual Function Ethernet support" + depends on PCI + ---help--- + This driver supports Intel(R) 82576 virtual functions. For more + information on how to identify your adapter, go to the Adapter & + Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called igbvf. + To compile this driver as a module, choose M here. The module + will be called igbvf. source "drivers/net/ixp2000/Kconfig" @@ -2300,14 +2300,14 @@ config SKGE will be called skge. This is recommended. config SKGE_DEBUG - bool "Debugging interface" - depends on SKGE && DEBUG_FS - help - This option adds the ability to dump driver state for debugging. - The file /sys/kernel/debug/skge/ethX displays the state of the internal - transmit and receive rings. + bool "Debugging interface" + depends on SKGE && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file /sys/kernel/debug/skge/ethX displays the state of the internal + transmit and receive rings. - If unsure, say N. + If unsure, say N. config SKY2 tristate "SysKonnect Yukon2 support" @@ -2326,14 +2326,14 @@ config SKY2 will be called sky2. This is recommended. config SKY2_DEBUG - bool "Debugging interface" - depends on SKY2 && DEBUG_FS - help - This option adds the ability to dump driver state for debugging. - The file /sys/kernel/debug/sky2/ethX displays the state of the internal - transmit and receive rings. + bool "Debugging interface" + depends on SKY2 && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file /sys/kernel/debug/sky2/ethX displays the state of the internal + transmit and receive rings. - If unsure, say N. + If unsure, say N. config VIA_VELOCITY tristate "VIA Velocity support" @@ -2573,32 +2573,32 @@ config MDIO tristate config CHELSIO_T1 - tristate "Chelsio 10Gb Ethernet support" - depends on PCI + tristate "Chelsio 10Gb Ethernet support" + depends on PCI select CRC32 select MDIO - help - This driver supports Chelsio gigabit and 10-gigabit - Ethernet cards. More information about adapter features and + help + This driver supports Chelsio gigabit and 10-gigabit + Ethernet cards. More information about adapter features and performance tuning is in . - For general information about Chelsio and our products, visit - our website at . + For general information about Chelsio and our products, visit + our website at . - For customer support, please visit our customer support page at - . + For customer support, please visit our customer support page at + . - Please send feedback to . + Please send feedback to . - To compile this driver as a module, choose M here: the module - will be called cxgb. + To compile this driver as a module, choose M here: the module + will be called cxgb. config CHELSIO_T1_1G - bool "Chelsio gigabit Ethernet support" - depends on CHELSIO_T1 - help - Enables support for Chelsio's gigabit Ethernet PCI cards. If you - are using only 10G cards say 'N' here. + bool "Chelsio gigabit Ethernet support" + depends on CHELSIO_T1 + help + Enables support for Chelsio's gigabit Ethernet PCI cards. If you + are using only 10G cards say 'N' here. config CHELSIO_T3_DEPENDS tristate @@ -2728,26 +2728,26 @@ config IXGBE_DCB If unsure, say N. config IXGBEVF - tristate "Intel(R) 82599 Virtual Function Ethernet support" - depends on PCI_MSI - ---help--- - This driver supports Intel(R) 82599 virtual functions. For more - information on how to identify your adapter, go to the Adapter & - Driver ID Guide at: + tristate "Intel(R) 82599 Virtual Function Ethernet support" + depends on PCI_MSI + ---help--- + This driver supports Intel(R) 82599 virtual functions. For more + information on how to identify your adapter, go to the Adapter & + Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called ixgbevf. MSI-X interrupt support is required - for this driver to work correctly. + To compile this driver as a module, choose M here. The module + will be called ixgbevf. MSI-X interrupt support is required + for this driver to work correctly. config IXGB tristate "Intel(R) PRO/10GbE support" @@ -2915,18 +2915,18 @@ config QLGE will be called qlge. config BNA - tristate "Brocade 1010/1020 10Gb Ethernet Driver support" - depends on PCI - ---help--- - This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet - cards. - To compile this driver as a module, choose M here: the module - will be called bna. + tristate "Brocade 1010/1020 10Gb Ethernet Driver support" + depends on PCI + ---help--- + This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet + cards. + To compile this driver as a module, choose M here: the module + will be called bna. - For general information and support, go to the Brocade support - website at: + For general information and support, go to the Brocade support + website at: - + source "drivers/net/sfc/Kconfig" @@ -3236,18 +3236,18 @@ config PPP_BSDCOMP modules once you have said "make modules". If unsure, say N. config PPP_MPPE - tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" - depends on PPP && EXPERIMENTAL - select CRYPTO - select CRYPTO_SHA1 - select CRYPTO_ARC4 - select CRYPTO_ECB - ---help--- - Support for the MPPE Encryption protocol, as employed by the - Microsoft Point-to-Point Tunneling Protocol. - - See http://pptpclient.sourceforge.net/ for information on - configuring PPTP clients and servers to utilize this method. + tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" + depends on PPP && EXPERIMENTAL + select CRYPTO + select CRYPTO_SHA1 + select CRYPTO_ARC4 + select CRYPTO_ECB + ---help--- + Support for the MPPE Encryption protocol, as employed by the + Microsoft Point-to-Point Tunneling Protocol. + + See http://pptpclient.sourceforge.net/ for information on + configuring PPTP clients and servers to utilize this method. config PPPOE tristate "PPP over Ethernet (EXPERIMENTAL)" @@ -3406,14 +3406,14 @@ config VIRTIO_NET depends on EXPERIMENTAL && VIRTIO ---help--- This is the virtual network driver for virtio. It can be used with - lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. + lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. config VMXNET3 - tristate "VMware VMXNET3 ethernet driver" - depends on PCI && INET - help - This driver supports VMware's vmxnet3 virtual ethernet NIC. - To compile this driver as a module, choose M here: the - module will be called vmxnet3. + tristate "VMware VMXNET3 ethernet driver" + depends on PCI && INET + help + This driver supports VMware's vmxnet3 virtual ethernet NIC. + To compile this driver as a module, choose M here: the + module will be called vmxnet3. endif # NETDEVICES -- cgit v1.2.3-59-g8ed1b From 190683a9d5457e6d962c232ffbecac3ab158dddd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 10 Nov 2010 10:50:44 +0000 Subject: net: net_families __rcu annotations Use modern RCU API / annotations for net_families array. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/socket.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/socket.c b/net/socket.c index 3ca2fd9e3720..c898df76e924 100644 --- a/net/socket.c +++ b/net/socket.c @@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = { */ static DEFINE_SPINLOCK(net_family_lock); -static const struct net_proto_family *net_families[NPROTO] __read_mostly; +static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; /* * Statistics counters of the socket lists @@ -1200,7 +1200,7 @@ int __sock_create(struct net *net, int family, int type, int protocol, * requested real, full-featured networking support upon configuration. * Otherwise module support will break! */ - if (net_families[family] == NULL) + if (rcu_access_pointer(net_families[family]) == NULL) request_module("net-pf-%d", family); #endif @@ -2332,10 +2332,11 @@ int sock_register(const struct net_proto_family *ops) } spin_lock(&net_family_lock); - if (net_families[ops->family]) + if (rcu_dereference_protected(net_families[ops->family], + lockdep_is_held(&net_family_lock))) err = -EEXIST; else { - net_families[ops->family] = ops; + rcu_assign_pointer(net_families[ops->family], ops); err = 0; } spin_unlock(&net_family_lock); @@ -2363,7 +2364,7 @@ void sock_unregister(int family) BUG_ON(family < 0 || family >= NPROTO); spin_lock(&net_family_lock); - net_families[family] = NULL; + rcu_assign_pointer(net_families[family], NULL); spin_unlock(&net_family_lock); synchronize_rcu(); -- cgit v1.2.3-59-g8ed1b From 5753fdfe8bd8e9a2ff9e5af19b0ffc78bfcd502a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:25:11 +0100 Subject: dccp ccid-2: Algorithm to update buffer state This provides a routine to consistently update the buffer state when the peer acknowledges receipt of Ack Vectors; updating state in the list of Ack Vectors as well as in the circular buffer. While based on RFC 4340, several additional (and necessary) precautions were added to protect the consistency of the buffer state. These additions are essential, since analysis and experience showed that the basic algorithm was insufficient for this task (which lead to problems that were hard to debug). The algorithm now * deals with HC-sender acknowledging to HC-receiver and vice versa, * keeps track of the last unacknowledged but received seqno in tail_ackno, * has special cases to reset the overflow condition when appropriate, * is protected against receiving older information (would mess up buffer state). Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/dccp/ackvec.h | 1 + net/dccp/input.c | 4 +-- net/dccp/options.c | 6 ++-- 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index abaf241c7353..e9a0f66e4afe 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -92,6 +92,24 @@ int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) return 0; } +static struct dccp_ackvec_record *dccp_ackvec_lookup(struct list_head *av_list, + const u64 ackno) +{ + struct dccp_ackvec_record *avr; + /* + * Exploit that records are inserted in descending order of sequence + * number, start with the oldest record first. If @ackno is `before' + * the earliest ack_ackno, the packet is too old to be considered. + */ + list_for_each_entry_reverse(avr, av_list, avr_node) { + if (avr->avr_ack_seqno == ackno) + return avr; + if (before48(ackno, avr->avr_ack_seqno)) + break; + } + return NULL; +} + /* * Buffer index and length computation using modulo-buffersize arithmetic. * Note that, as pointers move from right to left, head is `before' tail. @@ -356,6 +374,76 @@ int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, return 0; } +/** + * dccp_ackvec_clear_state - Perform house-keeping / garbage-collection + * This routine is called when the peer acknowledges the receipt of Ack Vectors + * up to and including @ackno. While based on on section A.3 of RFC 4340, here + * are additional precautions to prevent corrupted buffer state. In particular, + * we use tail_ackno to identify outdated records; it always marks the earliest + * packet of group (2) in 11.4.2. + */ +void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno) + { + struct dccp_ackvec_record *avr, *next; + u8 runlen_now, eff_runlen; + s64 delta; + + avr = dccp_ackvec_lookup(&av->av_records, ackno); + if (avr == NULL) + return; + /* + * Deal with outdated acknowledgments: this arises when e.g. there are + * several old records and the acks from the peer come in slowly. In + * that case we may still have records that pre-date tail_ackno. + */ + delta = dccp_delta_seqno(av->av_tail_ackno, avr->avr_ack_ackno); + if (delta < 0) + goto free_records; + /* + * Deal with overlapping Ack Vectors: don't subtract more than the + * number of packets between tail_ackno and ack_ackno. + */ + eff_runlen = delta < avr->avr_ack_runlen ? delta : avr->avr_ack_runlen; + + runlen_now = dccp_ackvec_runlen(av->av_buf + avr->avr_ack_ptr); + /* + * The run length of Ack Vector cells does not decrease over time. If + * the run length is the same as at the time the Ack Vector was sent, we + * free the ack_ptr cell. That cell can however not be freed if the run + * length has increased: in this case we need to move the tail pointer + * backwards (towards higher indices), to its next-oldest neighbour. + */ + if (runlen_now > eff_runlen) { + + av->av_buf[avr->avr_ack_ptr] -= eff_runlen + 1; + av->av_buf_tail = __ackvec_idx_add(avr->avr_ack_ptr, 1); + + /* This move may not have cleared the overflow flag. */ + if (av->av_overflow) + av->av_overflow = (av->av_buf_head == av->av_buf_tail); + } else { + av->av_buf_tail = avr->avr_ack_ptr; + /* + * We have made sure that avr points to a valid cell within the + * buffer. This cell is either older than head, or equals head + * (empty buffer): in both cases we no longer have any overflow. + */ + av->av_overflow = 0; + } + + /* + * The peer has acknowledged up to and including ack_ackno. Hence the + * first packet in group (2) of 11.4.2 is the successor of ack_ackno. + */ + av->av_tail_ackno = ADD48(avr->avr_ack_ackno, 1); + +free_records: + list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { + list_del(&avr->avr_node); + kmem_cache_free(dccp_ackvec_record_slab, avr); + } +} + int __init dccp_ackvec_init(void) { dccp_ackvec_slab = kmem_cache_create("dccp_ackvec", diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 23880be8fc29..3f7008187b8e 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -117,6 +117,7 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, const u8 *value, const u8 len); extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); +extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno); extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av); static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av) diff --git a/net/dccp/input.c b/net/dccp/input.c index c7aeeba859d4..f91cf5ada306 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -165,8 +165,8 @@ static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) struct dccp_sock *dp = dccp_sk(sk); if (dp->dccps_hc_rx_ackvec != NULL) - dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_ack_seq); + dccp_ackvec_clear_state(dp->dccps_hc_rx_ackvec, + DCCP_SKB_CB(skb)->dccpd_ack_seq); } static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) diff --git a/net/dccp/options.c b/net/dccp/options.c index 5adeeed5e0d2..7743df00f5b1 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -54,7 +54,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, struct dccp_sock *dp = dccp_sk(sk); const struct dccp_hdr *dh = dccp_hdr(skb); const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; - u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); unsigned char *opt_ptr = options; const unsigned char *opt_end = (unsigned char *)dh + @@ -133,9 +132,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, case DCCPO_ACK_VECTOR_1: if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ break; - if (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_parse(sk, skb, &ackno, opt, value, len)) - goto out_invalid_option; + dccp_pr_debug("%s Ack Vector (len=%u)\n", dccp_role(sk), + len); break; case DCCPO_TIMESTAMP: if (len != 4) -- cgit v1.2.3-59-g8ed1b From 3802408644515e29fb723d51a5317301b212cf3a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:25:23 +0100 Subject: dccp ccid-2: Update code for the Ack Vector input/registration routine This patch updates the code which registers new packets as received, using the new circular buffer interface. It contributes a new algorithm which * supports both tail/head pointers and buffer wrap-around and * deals with overflow (head/tail move in lock-step). Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/dccp/ackvec.h | 4 ++ 2 files changed, 154 insertions(+) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index e9a0f66e4afe..f7e647e608bb 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -131,6 +131,156 @@ u16 dccp_ackvec_buflen(const struct dccp_ackvec *av) return __ackvec_idx_sub(av->av_buf_tail, av->av_buf_head); } +/** + * dccp_ackvec_update_old - Update previous state as per RFC 4340, 11.4.1 + * @av: non-empty buffer to update + * @distance: negative or zero distance of @seqno from buf_ackno downward + * @seqno: the (old) sequence number whose record is to be updated + * @state: state in which packet carrying @seqno was received + */ +static void dccp_ackvec_update_old(struct dccp_ackvec *av, s64 distance, + u64 seqno, enum dccp_ackvec_states state) +{ + u16 ptr = av->av_buf_head; + + BUG_ON(distance > 0); + if (unlikely(dccp_ackvec_is_empty(av))) + return; + + do { + u8 runlen = dccp_ackvec_runlen(av->av_buf + ptr); + + if (distance + runlen >= 0) { + /* + * Only update the state if packet has not been received + * yet. This is OK as per the second table in RFC 4340, + * 11.4.1; i.e. here we are using the following table: + * RECEIVED + * 0 1 3 + * S +---+---+---+ + * T 0 | 0 | 0 | 0 | + * O +---+---+---+ + * R 1 | 1 | 1 | 1 | + * E +---+---+---+ + * D 3 | 0 | 1 | 3 | + * +---+---+---+ + * The "Not Received" state was set by reserve_seats(). + */ + if (av->av_buf[ptr] == DCCPAV_NOT_RECEIVED) + av->av_buf[ptr] = state; + else + dccp_pr_debug("Not changing %llu state to %u\n", + (unsigned long long)seqno, state); + break; + } + + distance += runlen + 1; + ptr = __ackvec_idx_add(ptr, 1); + + } while (ptr != av->av_buf_tail); +} + +/* Mark @num entries after buf_head as "Not yet received". */ +static void dccp_ackvec_reserve_seats(struct dccp_ackvec *av, u16 num) +{ + u16 start = __ackvec_idx_add(av->av_buf_head, 1), + len = DCCPAV_MAX_ACKVEC_LEN - start; + + /* check for buffer wrap-around */ + if (num > len) { + memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, len); + start = 0; + num -= len; + } + if (num) + memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, num); +} + +/** + * dccp_ackvec_add_new - Record one or more new entries in Ack Vector buffer + * @av: container of buffer to update (can be empty or non-empty) + * @num_packets: number of packets to register (must be >= 1) + * @seqno: sequence number of the first packet in @num_packets + * @state: state in which packet carrying @seqno was received + */ +static void dccp_ackvec_add_new(struct dccp_ackvec *av, u32 num_packets, + u64 seqno, enum dccp_ackvec_states state) +{ + u32 num_cells = num_packets; + + if (num_packets > DCCPAV_BURST_THRESH) { + u32 lost_packets = num_packets - 1; + + DCCP_WARN("Warning: large burst loss (%u)\n", lost_packets); + /* + * We received 1 packet and have a loss of size "num_packets-1" + * which we squeeze into num_cells-1 rather than reserving an + * entire byte for each lost packet. + * The reason is that the vector grows in O(burst_length); when + * it grows too large there will no room left for the payload. + * This is a trade-off: if a few packets out of the burst show + * up later, their state will not be changed; it is simply too + * costly to reshuffle/reallocate/copy the buffer each time. + * Should such problems persist, we will need to switch to a + * different underlying data structure. + */ + for (num_packets = num_cells = 1; lost_packets; ++num_cells) { + u8 len = min(lost_packets, (u32)DCCPAV_MAX_RUNLEN); + + av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, 1); + av->av_buf[av->av_buf_head] = DCCPAV_NOT_RECEIVED | len; + + lost_packets -= len; + } + } + + if (num_cells + dccp_ackvec_buflen(av) >= DCCPAV_MAX_ACKVEC_LEN) { + DCCP_CRIT("Ack Vector buffer overflow: dropping old entries\n"); + av->av_overflow = true; + } + + av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, num_packets); + if (av->av_overflow) + av->av_buf_tail = av->av_buf_head; + + av->av_buf[av->av_buf_head] = state; + av->av_buf_ackno = seqno; + + if (num_packets > 1) + dccp_ackvec_reserve_seats(av, num_packets - 1); +} + +/** + * dccp_ackvec_input - Register incoming packet in the buffer + */ +void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb) +{ + u64 seqno = DCCP_SKB_CB(skb)->dccpd_seq; + enum dccp_ackvec_states state = DCCPAV_RECEIVED; + + if (dccp_ackvec_is_empty(av)) { + dccp_ackvec_add_new(av, 1, seqno, state); + av->av_tail_ackno = seqno; + + } else { + s64 num_packets = dccp_delta_seqno(av->av_buf_ackno, seqno); + u8 *current_head = av->av_buf + av->av_buf_head; + + if (num_packets == 1 && + dccp_ackvec_state(current_head) == state && + dccp_ackvec_runlen(current_head) < DCCPAV_MAX_RUNLEN) { + + *current_head += 1; + av->av_buf_ackno = seqno; + + } else if (num_packets > 0) { + dccp_ackvec_add_new(av, num_packets, seqno, state); + } else { + dccp_ackvec_update_old(av, num_packets, seqno, state); + } + } +} + /* * If several packets are missing, the HC-Receiver may prefer to enter multiple * bytes with run length 0, rather than a single byte with a larger run length; diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 3f7008187b8e..21c4212d1be0 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -29,6 +29,9 @@ /* Estimated minimum average Ack Vector length - used for updating MPS */ #define DCCPAV_MIN_OPTLEN 16 +/* Threshold for coping with large bursts of losses */ +#define DCCPAV_BURST_THRESH (DCCPAV_MAX_ACKVEC_LEN / 8) + enum dccp_ackvec_states { DCCPAV_RECEIVED = 0x00, DCCPAV_ECN_MARKED = 0x40, @@ -116,6 +119,7 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, u64 *ackno, const u8 opt, const u8 *value, const u8 len); +extern void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb); extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno); extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av); -- cgit v1.2.3-59-g8ed1b From 18219463c884bfdb7954d298b9edb5194b14d621 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:25:36 +0100 Subject: dccp ccid-2: Consolidate Ack-Vector processing within main DCCP module This aggregates Ack Vector processing (handling input and clearing old state) into one function, for the following reasons and benefits: * all Ack Vector-specific processing is now in one place; * duplicated code is removed; * ensuring sanity: from an Ack Vector point of view, it is better to clear the old state first before entering new state; * Ack Event handling happens mostly within the CCIDs, not the main DCCP module. Signed-off-by: Gerrit Renker --- net/dccp/input.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/net/dccp/input.c b/net/dccp/input.c index f91cf5ada306..7d230d14ce22 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -160,13 +160,15 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) dccp_time_wait(sk, DCCP_TIME_WAIT, 0); } -static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) +static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) { - struct dccp_sock *dp = dccp_sk(sk); + struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; - if (dp->dccps_hc_rx_ackvec != NULL) - dccp_ackvec_clear_state(dp->dccps_hc_rx_ackvec, - DCCP_SKB_CB(skb)->dccpd_ack_seq); + if (av == NULL) + return; + if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) + dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq); + dccp_ackvec_input(av, skb); } static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) @@ -365,21 +367,13 @@ discard: int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) { - struct dccp_sock *dp = dccp_sk(sk); - if (dccp_check_seqno(sk, skb)) goto discard; if (dccp_parse_options(sk, NULL, skb)) return 1; - if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) - dccp_event_ack_recv(sk, skb); - - if (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED)) - goto discard; + dccp_handle_ackvec_processing(sk, skb); dccp_deliver_input_to_ccids(sk, skb); return __dccp_rcv_established(sk, skb, dh, len); @@ -631,14 +625,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, if (dccp_parse_options(sk, NULL, skb)) return 1; - if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) - dccp_event_ack_recv(sk, skb); - - if (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED)) - goto discard; - + dccp_handle_ackvec_processing(sk, skb); dccp_deliver_input_to_ccids(sk, skb); } -- cgit v1.2.3-59-g8ed1b From d83447f0944e73d690218d79c07762ffa4ceb9e4 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:25:46 +0100 Subject: dccp ccid-2: Schedule Sync as out-of-band mechanism The problem with Ack Vectors is that i) their length is variable and can in principle grow quite large, ii) it is hard to predict exactly how large they will be. Due to the second point it seems not a good idea to reduce the MPS; in particular when on average there is enough room for the Ack Vector and an increase in length is momentarily due to some burst loss, after which the Ack Vector returns to its normal/average length. The solution taken by this patch is to subtract a minimum-expected Ack Vector length from the MPS, and to defer any larger Ack Vectors onto a separate Sync - but only if indeed there is no space left on the skb. This patch provides the infrastructure to schedule Sync-packets for transporting (urgent) out-of-band data. Its signalling is quicker than scheduling an Ack, since it does not need to wait for new application data. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 2 ++ net/dccp/options.c | 24 ++++++++++++++++++++---- net/dccp/output.c | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 749f01ccd26e..eed52bcd35d0 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -462,6 +462,7 @@ struct dccp_ackvec; * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) + * @dccps_sync_scheduled - flag which signals "send out-of-band message soon" * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) @@ -503,6 +504,7 @@ struct dccp_sock { __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; + __u8 dccps_sync_scheduled:1; struct tasklet_struct dccps_xmitlet; struct timer_list dccps_xmit_timer; }; diff --git a/net/dccp/options.c b/net/dccp/options.c index 7743df00f5b1..dabd6ee34d45 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -427,6 +427,7 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; + struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); const u16 buflen = dccp_ackvec_buflen(av); /* Figure out how many options do we need to represent the ackvec */ const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN); @@ -435,10 +436,25 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) const unsigned char *tail, *from; unsigned char *to; - if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) + if (dcb->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { + DCCP_WARN("Lacking space for %u bytes on %s packet\n", len, + dccp_packet_name(dcb->dccpd_type)); return -1; - - DCCP_SKB_CB(skb)->dccpd_opt_len += len; + } + /* + * Since Ack Vectors are variable-length, we can not always predict + * their size. To catch exception cases where the space is running out + * on the skb, a separate Sync is scheduled to carry the Ack Vector. + */ + if (len > DCCPAV_MIN_OPTLEN && + len + dcb->dccpd_opt_len + skb->len > dp->dccps_mss_cache) { + DCCP_WARN("No space left for Ack Vector (%u) on skb (%u+%u), " + "MPS=%u ==> reduce payload size?\n", len, skb->len, + dcb->dccpd_opt_len, dp->dccps_mss_cache); + dp->dccps_sync_scheduled = 1; + return 0; + } + dcb->dccpd_opt_len += len; to = skb_push(skb, len); len = buflen; @@ -479,7 +495,7 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) /* * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. */ - if (dccp_ackvec_update_records(av, DCCP_SKB_CB(skb)->dccpd_seq, nonce)) + if (dccp_ackvec_update_records(av, dcb->dccpd_seq, nonce)) return -ENOBUFS; return 0; } diff --git a/net/dccp/output.c b/net/dccp/output.c index 45b91853f5ae..d96dd9d362ae 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -283,6 +283,15 @@ static void dccp_xmit_packet(struct sock *sk) * any local drop will eventually be reported via receiver feedback. */ ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); + + /* + * If the CCID needs to transfer additional header options out-of-band + * (e.g. Ack Vectors or feature-negotiation options), it activates this + * flag to schedule a Sync. The Sync will automatically incorporate all + * currently pending header options, thus clearing the backlog. + */ + if (dp->dccps_sync_scheduled) + dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC); } /** @@ -636,6 +645,12 @@ void dccp_send_sync(struct sock *sk, const u64 ackno, DCCP_SKB_CB(skb)->dccpd_type = pkt_type; DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; + /* + * Clear the flag in case the Sync was scheduled for out-of-band data, + * such as carrying a long Ack Vector. + */ + dccp_sk(sk)->dccps_sync_scheduled = 0; + dccp_transmit_skb(sk, skb); } -- cgit v1.2.3-59-g8ed1b From 52394eecec4e6fa677a61af26f0bd35de665344e Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:26:02 +0100 Subject: dccp ccid-2: Remove old infrastructure This removes * functions for which updates have been provided in the preceding patches and * the @av_vec_len field - it is no longer necessary since the buffer length is now always computed dynamically. Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 251 ------------------------------------------------------ net/dccp/ackvec.h | 14 --- 2 files changed, 265 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index f7e647e608bb..66b8a51300c0 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -9,18 +9,10 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; version 2 of the License; */ - -#include "ackvec.h" #include "dccp.h" - -#include -#include #include -#include #include -#include - static struct kmem_cache *dccp_ackvec_slab; static struct kmem_cache *dccp_ackvec_record_slab; @@ -281,249 +273,6 @@ void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb) } } -/* - * If several packets are missing, the HC-Receiver may prefer to enter multiple - * bytes with run length 0, rather than a single byte with a larger run length; - * this simplifies table updates if one of the missing packets arrives. - */ -static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, - const unsigned int packets, - const unsigned char state) -{ - long gap; - long new_head; - - if (av->av_vec_len + packets > DCCPAV_MAX_ACKVEC_LEN) - return -ENOBUFS; - - gap = packets - 1; - new_head = av->av_buf_head - packets; - - if (new_head < 0) { - if (gap > 0) { - memset(av->av_buf, DCCPAV_NOT_RECEIVED, - gap + new_head + 1); - gap = -new_head; - } - new_head += DCCPAV_MAX_ACKVEC_LEN; - } - - av->av_buf_head = new_head; - - if (gap > 0) - memset(av->av_buf + av->av_buf_head + 1, - DCCPAV_NOT_RECEIVED, gap); - - av->av_buf[av->av_buf_head] = state; - av->av_vec_len += packets; - return 0; -} - -/* - * Implements the RFC 4340, Appendix A - */ -int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, - const u64 ackno, const u8 state) -{ - u8 *cur_head = av->av_buf + av->av_buf_head, - *buf_end = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; - /* - * Check at the right places if the buffer is full, if it is, tell the - * caller to start dropping packets till the HC-Sender acks our ACK - * vectors, when we will free up space in av_buf. - * - * We may well decide to do buffer compression, etc, but for now lets - * just drop. - * - * From Appendix A.1.1 (`New Packets'): - * - * Of course, the circular buffer may overflow, either when the - * HC-Sender is sending data at a very high rate, when the - * HC-Receiver's acknowledgements are not reaching the HC-Sender, - * or when the HC-Sender is forgetting to acknowledge those acks - * (so the HC-Receiver is unable to clean up old state). In this - * case, the HC-Receiver should either compress the buffer (by - * increasing run lengths when possible), transfer its state to - * a larger buffer, or, as a last resort, drop all received - * packets, without processing them whatsoever, until its buffer - * shrinks again. - */ - - /* See if this is the first ackno being inserted */ - if (av->av_vec_len == 0) { - *cur_head = state; - av->av_vec_len = 1; - } else if (after48(ackno, av->av_buf_ackno)) { - const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno); - - /* - * Look if the state of this packet is the same as the - * previous ackno and if so if we can bump the head len. - */ - if (delta == 1 && dccp_ackvec_state(cur_head) == state && - dccp_ackvec_runlen(cur_head) < DCCPAV_MAX_RUNLEN) - *cur_head += 1; - else if (dccp_ackvec_set_buf_head_state(av, delta, state)) - return -ENOBUFS; - } else { - /* - * A.1.2. Old Packets - * - * When a packet with Sequence Number S <= buf_ackno - * arrives, the HC-Receiver will scan the table for - * the byte corresponding to S. (Indexing structures - * could reduce the complexity of this scan.) - */ - u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno); - - while (1) { - const u8 len = dccp_ackvec_runlen(cur_head); - /* - * valid packets not yet in av_buf have a reserved - * entry, with a len equal to 0. - */ - if (*cur_head == DCCPAV_NOT_RECEIVED && delta == 0) { - dccp_pr_debug("Found %llu reserved seat!\n", - (unsigned long long)ackno); - *cur_head = state; - goto out; - } - /* len == 0 means one packet */ - if (delta < len + 1) - goto out_duplicate; - - delta -= len + 1; - if (++cur_head == buf_end) - cur_head = av->av_buf; - } - } - - av->av_buf_ackno = ackno; -out: - return 0; - -out_duplicate: - /* Duplicate packet */ - dccp_pr_debug("Received a dup or already considered lost " - "packet: %llu\n", (unsigned long long)ackno); - return -EILSEQ; -} - -static void dccp_ackvec_throw_record(struct dccp_ackvec *av, - struct dccp_ackvec_record *avr) -{ - struct dccp_ackvec_record *next; - - /* sort out vector length */ - if (av->av_buf_head <= avr->avr_ack_ptr) - av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head; - else - av->av_vec_len = DCCPAV_MAX_ACKVEC_LEN - 1 - - av->av_buf_head + avr->avr_ack_ptr; - - /* free records */ - list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { - list_del(&avr->avr_node); - kmem_cache_free(dccp_ackvec_record_slab, avr); - } -} - -void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, - const u64 ackno) -{ - struct dccp_ackvec_record *avr; - - /* - * If we traverse backwards, it should be faster when we have large - * windows. We will be receiving ACKs for stuff we sent a while back - * -sorbo. - */ - list_for_each_entry_reverse(avr, &av->av_records, avr_node) { - if (ackno == avr->avr_ack_seqno) { - dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, " - "ack_ackno=%llu, ACKED!\n", - dccp_role(sk), avr->avr_ack_runlen, - (unsigned long long)avr->avr_ack_seqno, - (unsigned long long)avr->avr_ack_ackno); - dccp_ackvec_throw_record(av, avr); - break; - } else if (avr->avr_ack_seqno > ackno) - break; /* old news */ - } -} - -static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, - struct sock *sk, u64 *ackno, - const unsigned char len, - const unsigned char *vector) -{ - unsigned char i; - struct dccp_ackvec_record *avr; - - /* Check if we actually sent an ACK vector */ - if (list_empty(&av->av_records)) - return; - - i = len; - /* - * XXX - * I think it might be more efficient to work backwards. See comment on - * rcv_ackno. -sorbo. - */ - avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node); - while (i--) { - const u8 rl = dccp_ackvec_runlen(vector); - u64 ackno_end_rl; - - dccp_set_seqno(&ackno_end_rl, *ackno - rl); - - /* - * If our AVR sequence number is greater than the ack, go - * forward in the AVR list until it is not so. - */ - list_for_each_entry_from(avr, &av->av_records, avr_node) { - if (!after48(avr->avr_ack_seqno, *ackno)) - goto found; - } - /* End of the av_records list, not found, exit */ - break; -found: - if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) { - if (dccp_ackvec_state(vector) != DCCPAV_NOT_RECEIVED) { - dccp_pr_debug("%s ACK vector 0, len=%d, " - "ack_seqno=%llu, ack_ackno=%llu, " - "ACKED!\n", - dccp_role(sk), len, - (unsigned long long) - avr->avr_ack_seqno, - (unsigned long long) - avr->avr_ack_ackno); - dccp_ackvec_throw_record(av, avr); - break; - } - /* - * If it wasn't received, continue scanning... we might - * find another one. - */ - } - - dccp_set_seqno(ackno, ackno_end_rl - 1); - ++vector; - } -} - -int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, - u64 *ackno, const u8 opt, const u8 *value, const u8 len) -{ - if (len > DCCP_SINGLE_OPT_MAXLEN) - return -1; - - /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */ - dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk, - ackno, len, value); - return 0; -} - /** * dccp_ackvec_clear_state - Perform house-keeping / garbage-collection * This routine is called when the peer acknowledges the receipt of Ack Vectors diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 21c4212d1be0..e19b8d5ee05f 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -64,7 +64,6 @@ static inline u8 dccp_ackvec_state(const u8 *cell) * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf * @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously) - * @av_veclen: length of the live portion of @av_buf */ struct dccp_ackvec { u8 av_buf[DCCPAV_MAX_ACKVEC_LEN]; @@ -75,7 +74,6 @@ struct dccp_ackvec { bool av_buf_nonce[DCCPAV_NUM_ACKVECS]; u8 av_overflow:1; struct list_head av_records; - u16 av_vec_len; }; /** struct dccp_ackvec_record - Records information about sent Ack Vectors @@ -101,24 +99,12 @@ struct dccp_ackvec_record { u8 avr_ack_nonce:1; }; -struct sock; -struct sk_buff; - extern int dccp_ackvec_init(void); extern void dccp_ackvec_exit(void); extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority); extern void dccp_ackvec_free(struct dccp_ackvec *av); -extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, - const u64 ackno, const u8 state); - -extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, - struct sock *sk, const u64 ackno); -extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, - u64 *ackno, const u8 opt, - const u8 *value, const u8 len); - extern void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb); extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno); -- cgit v1.2.3-59-g8ed1b From 7e87fe84303cc54ecf3c7b688cb08ca24322a41d Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:26:13 +0100 Subject: dccp ccid-2: Separate option parsing from CCID processing This patch replaces an almost identical replication of code: large parts of dccp_parse_options() re-appeared as ccid2_ackvector() in ccid2.c. Apart from the duplication, this caused two more problems: 1. CCIDs should not need to be concerned with parsing header options; 2. one can not assume that Ack Vectors appear as a contiguous area within an skb, it is legal to insert other options and/or padding in between. The current code would throw an error and stop reading in such a case. Since Ack Vectors provide CCID-specific information, they are now processed by the CCID directly, separating this functionality from the main DCCP code. Signed-off-by: Gerrit Renker --- net/dccp/ackvec.c | 28 +++++++++++ net/dccp/ackvec.h | 19 +++++++ net/dccp/ccids/ccid2.c | 134 +++++++++++++++---------------------------------- net/dccp/ccids/ccid2.h | 2 + net/dccp/options.c | 17 ++++--- 5 files changed, 100 insertions(+), 100 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 66b8a51300c0..41819848bdda 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -343,6 +343,34 @@ free_records: } } +/* + * Routines to keep track of Ack Vectors received in an skb + */ +int dccp_ackvec_parsed_add(struct list_head *head, u8 *vec, u8 len, u8 nonce) +{ + struct dccp_ackvec_parsed *new = kmalloc(sizeof(*new), GFP_ATOMIC); + + if (new == NULL) + return -ENOBUFS; + new->vec = vec; + new->len = len; + new->nonce = nonce; + + list_add_tail(&new->node, head); + return 0; +} +EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_add); + +void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks) +{ + struct dccp_ackvec_parsed *cur, *next; + + list_for_each_entry_safe(cur, next, parsed_chunks, node) + kfree(cur); + INIT_LIST_HEAD(parsed_chunks); +} +EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_cleanup); + int __init dccp_ackvec_init(void) { dccp_ackvec_slab = kmem_cache_create("dccp_ackvec", diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index e19b8d5ee05f..e2ab0627a5ff 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -114,4 +114,23 @@ static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av) { return av->av_overflow == 0 && av->av_buf_head == av->av_buf_tail; } + +/** + * struct dccp_ackvec_parsed - Record offsets of Ack Vectors in skb + * @vec: start of vector (offset into skb) + * @len: length of @vec + * @nonce: whether @vec had an ECN nonce of 0 or 1 + * @node: FIFO - arranged in descending order of ack_ackno + * This structure is used by CCIDs to access Ack Vectors in a received skb. + */ +struct dccp_ackvec_parsed { + u8 *vec, + len, + nonce:1; + struct list_head node; +}; + +extern int dccp_ackvec_parsed_add(struct list_head *head, + u8 *vec, u8 len, u8 nonce); +extern void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks); #endif /* _ACKVEC_H */ diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index cb1b4a0d1877..e96d5e810039 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -246,68 +246,6 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) #endif } -/* XXX Lame code duplication! - * returns -1 if none was found. - * else returns the next offset to use in the function call. - */ -static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset, - unsigned char **vec, unsigned char *veclen) -{ - const struct dccp_hdr *dh = dccp_hdr(skb); - unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); - unsigned char *opt_ptr; - const unsigned char *opt_end = (unsigned char *)dh + - (dh->dccph_doff * 4); - unsigned char opt, len; - unsigned char *value; - - BUG_ON(offset < 0); - options += offset; - opt_ptr = options; - if (opt_ptr >= opt_end) - return -1; - - while (opt_ptr != opt_end) { - opt = *opt_ptr++; - len = 0; - value = NULL; - - /* Check if this isn't a single byte option */ - if (opt > DCCPO_MAX_RESERVED) { - if (opt_ptr == opt_end) - goto out_invalid_option; - - len = *opt_ptr++; - if (len < 3) - goto out_invalid_option; - /* - * Remove the type and len fields, leaving - * just the value size - */ - len -= 2; - value = opt_ptr; - opt_ptr += len; - - if (opt_ptr > opt_end) - goto out_invalid_option; - } - - switch (opt) { - case DCCPO_ACK_VECTOR_0: - case DCCPO_ACK_VECTOR_1: - *vec = value; - *veclen = len; - return offset + (opt_ptr - options); - } - } - - return -1; - -out_invalid_option: - DCCP_BUG("Invalid option - this should not happen (previous parsing)!"); - return -1; -} - /** * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm * This code is almost identical with TCP's tcp_rtt_estimator(), since @@ -432,16 +370,28 @@ static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) ccid2_change_l_ack_ratio(sk, hc->tx_cwnd); } +static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type, + u8 option, u8 *optval, u8 optlen) +{ + struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + + switch (option) { + case DCCPO_ACK_VECTOR_0: + case DCCPO_ACK_VECTOR_1: + return dccp_ackvec_parsed_add(&hc->tx_av_chunks, optval, optlen, + option - DCCPO_ACK_VECTOR_0); + } + return 0; +} + static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); + struct dccp_ackvec_parsed *avp; u64 ackno, seqno; struct ccid2_seq *seqp; - unsigned char *vector; - unsigned char veclen; - int offset = 0; int done = 0; unsigned int maxincr = 0; @@ -475,17 +425,12 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) } /* check forward path congestion */ - /* still didn't send out new data packets */ - if (hc->tx_seqh == hc->tx_seqt) + if (dccp_packet_without_ack(skb)) return; - switch (DCCP_SKB_CB(skb)->dccpd_type) { - case DCCP_PKT_ACK: - case DCCP_PKT_DATAACK: - break; - default: - return; - } + /* still didn't send out new data packets */ + if (hc->tx_seqh == hc->tx_seqt) + goto done; ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; if (after48(ackno, hc->tx_high_ack)) @@ -509,15 +454,16 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2); /* go through all ack vectors */ - while ((offset = ccid2_ackvector(sk, skb, offset, - &vector, &veclen)) != -1) { + list_for_each_entry(avp, &hc->tx_av_chunks, node) { /* go through this ack vector */ - while (veclen--) { - u64 ackno_end_rl = SUB48(ackno, dccp_ackvec_runlen(vector)); + for (; avp->len--; avp->vec++) { + u64 ackno_end_rl = SUB48(ackno, + dccp_ackvec_runlen(avp->vec)); - ccid2_pr_debug("ackvec start:%llu end:%llu\n", + ccid2_pr_debug("ackvec %llu |%u,%u|\n", (unsigned long long)ackno, - (unsigned long long)ackno_end_rl); + dccp_ackvec_state(avp->vec) >> 6, + dccp_ackvec_runlen(avp->vec)); /* if the seqno we are analyzing is larger than the * current ackno, then move towards the tail of our * seqnos. @@ -536,7 +482,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) * run length */ while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) { - const u8 state = dccp_ackvec_state(vector); + const u8 state = dccp_ackvec_state(avp->vec); /* new packet received or marked */ if (state != DCCPAV_NOT_RECEIVED && @@ -563,7 +509,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) break; ackno = SUB48(ackno_end_rl, 1); - vector++; } if (done) break; @@ -631,10 +576,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) sk_stop_timer(sk, &hc->tx_rtotimer); else sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); - +done: /* check if incoming Acks allow pending packets to be sent */ if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); + dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) @@ -663,6 +609,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_last_cong = ccid2_time_stamp; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk); + INIT_LIST_HEAD(&hc->tx_av_chunks); return 0; } @@ -696,16 +643,17 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) } struct ccid_operations ccid2_ops = { - .ccid_id = DCCPC_CCID2, - .ccid_name = "TCP-like", - .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), - .ccid_hc_tx_init = ccid2_hc_tx_init, - .ccid_hc_tx_exit = ccid2_hc_tx_exit, - .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet, - .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent, - .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv, - .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock), - .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, + .ccid_id = DCCPC_CCID2, + .ccid_name = "TCP-like", + .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), + .ccid_hc_tx_init = ccid2_hc_tx_init, + .ccid_hc_tx_exit = ccid2_hc_tx_exit, + .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet, + .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent, + .ccid_hc_tx_parse_options = ccid2_hc_tx_parse_options, + .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv, + .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock), + .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, }; #ifdef CONFIG_IP_DCCP_CCID2_DEBUG diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 25cb6b216eda..e9985dafc2c7 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -55,6 +55,7 @@ struct ccid2_seq { * @tx_rtt_seq: to decay RTTVAR at most once per flight * @tx_rpseq: last consecutive seqno * @tx_rpdupack: dupacks since rpseq + * @tx_av_chunks: list of Ack Vectors received on current skb */ struct ccid2_hc_tx_sock { u32 tx_cwnd; @@ -79,6 +80,7 @@ struct ccid2_hc_tx_sock { int tx_rpdupack; u32 tx_last_cong; u64 tx_high_ack; + struct list_head tx_av_chunks; }; static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc) diff --git a/net/dccp/options.c b/net/dccp/options.c index dabd6ee34d45..f06ffcfc8d71 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -128,13 +128,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, if (rc) goto out_featneg_failed; break; - case DCCPO_ACK_VECTOR_0: - case DCCPO_ACK_VECTOR_1: - if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ - break; - dccp_pr_debug("%s Ack Vector (len=%u)\n", dccp_role(sk), - len); - break; case DCCPO_TIMESTAMP: if (len != 4) goto out_invalid_option; @@ -224,6 +217,16 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, pkt_type, opt, value, len)) goto out_invalid_option; break; + case DCCPO_ACK_VECTOR_0: + case DCCPO_ACK_VECTOR_1: + if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ + break; + /* + * Ack vectors are processed by the TX CCID if it is + * interested. The RX CCID need not parse Ack Vectors, + * since it is only interested in clearing old state. + * Fall through. + */ case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC: if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, pkt_type, opt, value, len)) -- cgit v1.2.3-59-g8ed1b From d9aa93804e53f2153260568024b75ad3d81784f9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Nov 2010 08:52:02 -0800 Subject: ipv4: Fix build with multicast disabled. net/ipv4/igmp.c: In function 'ip_mc_inc_group': net/ipv4/igmp.c:1228: error: implicit declaration of function 'for_each_pmc_rtnl' net/ipv4/igmp.c:1228: error: expected ';' before '{' token net/ipv4/igmp.c: In function 'ip_mc_unmap': net/ipv4/igmp.c:1333: error: expected ';' before 'igmp_group_dropped' ... Move for_each_pmc_rcu and for_each_pmc_rtnl macro definitions outside of multicast ifdef protection. Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 0f0e0f0279b8..a1bf2f49e716 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -163,6 +163,16 @@ static void ip_ma_put(struct ip_mc_list *im) } } +#define for_each_pmc_rcu(in_dev, pmc) \ + for (pmc = rcu_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rcu_dereference(pmc->next_rcu)) + +#define for_each_pmc_rtnl(in_dev, pmc) \ + for (pmc = rtnl_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rtnl_dereference(pmc->next_rcu)) + #ifdef CONFIG_IP_MULTICAST /* @@ -502,16 +512,6 @@ empty_source: return skb; } -#define for_each_pmc_rcu(in_dev, pmc) \ - for (pmc = rcu_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rcu_dereference(pmc->next_rcu)) - -#define for_each_pmc_rtnl(in_dev, pmc) \ - for (pmc = rtnl_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rtnl_dereference(pmc->next_rcu)) - static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) { struct sk_buff *skb = NULL; -- cgit v1.2.3-59-g8ed1b From caedda35c6dba5a283e5d87e77a8d19ee4be3183 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 11 Nov 2010 09:30:40 +0000 Subject: cxgb4vf: minor comment/symbolic name cleanup. Minor cleanup of comments and symbolic constant names for clarity. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/adapter.h | 2 +- drivers/net/cxgb4vf/cxgb4vf_main.c | 11 ++++------- drivers/net/cxgb4vf/sge.c | 9 ++++++--- drivers/net/cxgb4vf/t4vf_hw.c | 5 +++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h index 8ea01962e045..4766b4116b41 100644 --- a/drivers/net/cxgb4vf/adapter.h +++ b/drivers/net/cxgb4vf/adapter.h @@ -60,7 +60,7 @@ enum { * MSI-X interrupt index usage. */ MSIX_FW = 0, /* MSI-X index for firmware Q */ - MSIX_NIQFLINT = 1, /* MSI-X index base for Ingress Qs */ + MSIX_IQFLINT = 1, /* MSI-X index base for Ingress Qs */ MSIX_EXTRAS = 1, MSIX_ENTRIES = MAX_ETH_QSETS + MSIX_EXTRAS, diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index c3449bbc585a..62357191d4e7 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -280,9 +280,7 @@ static void name_msix_vecs(struct adapter *adapter) const struct port_info *pi = netdev_priv(dev); int qs, msi; - for (qs = 0, msi = MSIX_NIQFLINT; - qs < pi->nqsets; - qs++, msi++) { + for (qs = 0, msi = MSIX_IQFLINT; qs < pi->nqsets; qs++, msi++) { snprintf(adapter->msix_info[msi].desc, namelen, "%s-%d", dev->name, qs); adapter->msix_info[msi].desc[namelen] = 0; @@ -309,7 +307,7 @@ static int request_msix_queue_irqs(struct adapter *adapter) /* * Ethernet queues. */ - msi = MSIX_NIQFLINT; + msi = MSIX_IQFLINT; for_each_ethrxq(s, rxq) { err = request_irq(adapter->msix_info[msi].vec, t4vf_sge_intr_msix, 0, @@ -337,7 +335,7 @@ static void free_msix_queue_irqs(struct adapter *adapter) int rxq, msi; free_irq(adapter->msix_info[MSIX_FW].vec, &s->fw_evtq); - msi = MSIX_NIQFLINT; + msi = MSIX_IQFLINT; for_each_ethrxq(s, rxq) free_irq(adapter->msix_info[msi++].vec, &s->ethrxq[rxq].rspq); @@ -527,7 +525,7 @@ static int setup_sge_queues(struct adapter *adapter) * brought up at which point lots of things get nailed down * permanently ... */ - msix = MSIX_NIQFLINT; + msix = MSIX_IQFLINT; for_each_port(adapter, pidx) { struct net_device *dev = adapter->port[pidx]; struct port_info *pi = netdev_priv(dev); @@ -2470,7 +2468,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, version_printed = 1; } - /* * Initialize generic PCI device state. */ diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index ecf0770bf0ff..e0b3d1bc2fdf 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1568,6 +1568,9 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } else skb_checksum_none_assert(skb); + /* + * Deliver the packet to the stack. + */ if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; @@ -2143,7 +2146,7 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, /* * Calculate the size of the hardware free list ring plus - * status page (which the SGE will place at the end of the + * Status Page (which the SGE will place after the end of the * free list ring) in Egress Queue Units. */ flsz = (fl->size / FL_PER_EQ_UNIT + @@ -2240,8 +2243,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, struct port_info *pi = netdev_priv(dev); /* - * Calculate the size of the hardware TX Queue (including the - * status age on the end) in units of TX Descriptors. + * Calculate the size of the hardware TX Queue (including the Status + * Page on the end of the TX Queue) in units of TX Descriptors. */ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index e306c20dfaee..f7d7f976064b 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -1276,7 +1276,7 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) */ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) { - struct fw_cmd_hdr *cmd_hdr = (struct fw_cmd_hdr *)rpl; + const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl; u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi)); switch (opcode) { @@ -1284,7 +1284,8 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) /* * Link/module state change message. */ - const struct fw_port_cmd *port_cmd = (void *)rpl; + const struct fw_port_cmd *port_cmd = + (const struct fw_port_cmd *)rpl; u32 word; int action, port_id, link_ok, speed, fc, pidx; -- cgit v1.2.3-59-g8ed1b From f12fe3536bebcbd2ccfa80030ec7d9868c488d30 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 11 Nov 2010 09:30:41 +0000 Subject: cxgb4vf: add ethtool statistics for GRO. Add ethtool statistics for GRO. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 62357191d4e7..47417d400371 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -1346,6 +1346,8 @@ struct queue_port_stats { u64 rx_csum; u64 vlan_ex; u64 vlan_ins; + u64 lro_pkts; + u64 lro_merged; }; /* @@ -1383,6 +1385,8 @@ static const char stats_strings[][ETH_GSTRING_LEN] = { "RxCsumGood ", "VLANextractions ", "VLANinsertions ", + "GROPackets ", + "GROMerged ", }; /* @@ -1432,6 +1436,8 @@ static void collect_sge_port_stats(const struct adapter *adapter, stats->rx_csum += rxq->stats.rx_cso; stats->vlan_ex += rxq->stats.vlan_ex; stats->vlan_ins += txq->vlan_ins; + stats->lro_pkts += rxq->stats.lro_pkts; + stats->lro_merged += rxq->stats.lro_merged; } } -- cgit v1.2.3-59-g8ed1b From 4204875dd4b3c3e40e0294a8c2619fdf9e5907e1 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 11 Nov 2010 09:30:42 +0000 Subject: cxgb4vf: fix up "Section Mismatch" compiler warning. Fix up "Section Mismatch" compiler warning and mark another routine as __devinit. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 47417d400371..4cf530ac149d 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2032,7 +2032,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) * Tear down the /sys/kernel/debug/cxgb4vf sub-nodes created above. We leave * it to our caller to tear down the directory (debugfs_root). */ -static void __devexit cleanup_debugfs(struct adapter *adapter) +static void cleanup_debugfs(struct adapter *adapter) { BUG_ON(adapter->debugfs_root == NULL); @@ -2050,7 +2050,7 @@ static void __devexit cleanup_debugfs(struct adapter *adapter) * adapter parameters we're going to be using and initialize basic adapter * hardware support. */ -static int adap_init0(struct adapter *adapter) +static int __devinit adap_init0(struct adapter *adapter) { struct vf_resources *vfres = &adapter->params.vfres; struct sge_params *sge_params = &adapter->params.sge; -- cgit v1.2.3-59-g8ed1b From 410989f65151557701ce86875b141e694281dd6c Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 11 Nov 2010 09:30:43 +0000 Subject: cxgb4vf: Advertise NETIF_F_TSO_ECN. Advertise NETIF_F_TSO_ECN. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 4cf530ac149d..9246d2fa6cf9 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -1533,15 +1533,20 @@ static void cxgb4vf_get_wol(struct net_device *dev, memset(&wol->sopass, 0, sizeof(wol->sopass)); } +/* + * TCP Segmentation Offload flags which we support. + */ +#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) + /* * Set TCP Segmentation Offloading feature capabilities. */ static int cxgb4vf_set_tso(struct net_device *dev, u32 tso) { if (tso) - dev->features |= NETIF_F_TSO | NETIF_F_TSO6; + dev->features |= TSO_FLAGS; else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); + dev->features &= ~TSO_FLAGS; return 0; } @@ -2610,7 +2615,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netif_carrier_off(netdev); netdev->irq = pdev->irq; - netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | + netdev->features = (NETIF_F_SG | TSO_FLAGS | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_GRO); -- cgit v1.2.3-59-g8ed1b From e1e78db628b33c657944865e3bca01ee59cc5b80 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 29 Oct 2010 12:14:53 +0000 Subject: offloading: Make scatter/gather more tolerant of vlans. When checking if it is necessary to linearize a packet, we currently use vlan_features if the packet contains either an in-band or out- of-band vlan tag. However, in-band tags aren't special in any way for scatter/gather since they are part of the packet buffer and are simply more data to DMA. Therefore, only use vlan_features for out- of-band tags, which could potentially have some interaction with scatter/gather. Signed-off-by: Jesse Gross CC: Ben Hutchings Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 5968c822c999..0b403d503311 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1976,15 +1976,20 @@ static inline void skb_orphan_try(struct sk_buff *skb) static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { - int features = dev->features; + if (skb_is_nonlinear(skb)) { + int features = dev->features; - if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) - features &= dev->vlan_features; + if (vlan_tx_tag_present(skb)) + features &= dev->vlan_features; - return skb_is_nonlinear(skb) && - ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || - (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || - illegal_highdma(dev, skb)))); + return (skb_has_frag_list(skb) && + !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && + (!(features & NETIF_F_SG) || + illegal_highdma(dev, skb))); + } + + return 0; } int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, -- cgit v1.2.3-59-g8ed1b From c8d5bcd1aff89199cde4bd82c5c40fb704c8bba4 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 29 Oct 2010 12:14:54 +0000 Subject: offloading: Support multiple vlan tags in GSO. We assume that hardware TSO can't support multiple levels of vlan tags but we allow it to be done. Therefore, enable GSO to parse these tags so we can fallback to software. Signed-off-by: Jesse Gross CC: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 0b403d503311..368930a988e3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1794,16 +1794,18 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); struct packet_type *ptype; __be16 type = skb->protocol; + int vlan_depth = ETH_HLEN; int err; - if (type == htons(ETH_P_8021Q)) { - struct vlan_ethhdr *veh; + while (type == htons(ETH_P_8021Q)) { + struct vlan_hdr *vh; - if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) + if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) return ERR_PTR(-EINVAL); - veh = (struct vlan_ethhdr *)skb->data; - type = veh->h_vlan_encapsulated_proto; + vh = (struct vlan_hdr *)(skb->data + vlan_depth); + type = vh->h_vlan_encapsulated_proto; + vlan_depth += VLAN_HLEN; } skb_reset_mac_header(skb); -- cgit v1.2.3-59-g8ed1b From 58e998c6d23988490162cef0784b19ea274d90bb Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 29 Oct 2010 12:14:55 +0000 Subject: offloading: Force software GSO for multiple vlan tags. We currently use vlan_features to check for TSO support if there is a vlan tag. However, it's quite likely that the NIC is not able to do TSO when there is an arbitrary number of tags. Therefore if there is more than one tag (in-band or out-of-band), fall back to software emulation. Signed-off-by: Jesse Gross CC: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/netdevice.h | 7 +++---- net/core/dev.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 578debb801f4..6e4cfbc53d4c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2239,6 +2239,8 @@ unsigned long netdev_fix_features(unsigned long features, const char *name); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); +int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev); + static inline int net_gso_ok(int features, int gso_type) { int feature = gso_type << NETIF_F_GSO_SHIFT; @@ -2254,10 +2256,7 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features) static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { if (skb_is_gso(skb)) { - int features = dev->features; - - if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci) - features &= dev->vlan_features; + int features = netif_get_vlan_features(skb, dev); return (!skb_gso_ok(skb, features) || unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); diff --git a/net/core/dev.c b/net/core/dev.c index 368930a988e3..8b500c3e0297 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1968,6 +1968,22 @@ static inline void skb_orphan_try(struct sk_buff *skb) } } +int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) +{ + __be16 protocol = skb->protocol; + + if (protocol == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; + protocol = veh->h_vlan_encapsulated_proto; + } else if (!skb->vlan_tci) + return dev->features; + + if (protocol != htons(ETH_P_8021Q)) + return dev->features & dev->vlan_features; + else + return 0; +} + /* * Returns true if either: * 1. skb has frag_list and the device doesn't support FRAGLIST, or -- cgit v1.2.3-59-g8ed1b From 029f5fc31cdb35d6c8a7fe9a54bf21556e175988 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 30 Oct 2010 14:22:32 +0000 Subject: 8021q: set hard_header_len when VLAN offload features are toggled Toggling the vlan tx|rx hw offloads needs to set the hard_header_len as well otherwise we end up using LL_RESERVED_SPACE incorrectly. This results in pskb_expand_head() being used unnecessarily. Signed-off-by: John Fastabend Acked-by: Jesse Gross Signed-off-by: David S. Miller --- net/8021q/vlan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 52077ca22072..55d2135889fc 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -334,6 +334,12 @@ static void vlan_transfer_features(struct net_device *dev, vlandev->features &= ~dev->vlan_features; vlandev->features |= dev->features & dev->vlan_features; vlandev->gso_max_size = dev->gso_max_size; + + if (dev->features & NETIF_F_HW_VLAN_TX) + vlandev->hard_header_len = dev->hard_header_len; + else + vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; + #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; #endif -- cgit v1.2.3-59-g8ed1b From 8f5549f381ced6a255f2c7127b2b3b3b05fdfd6e Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 30 Oct 2010 14:22:37 +0000 Subject: net: remove check for headroom in vlan_dev_create It is possible for the headroom to be smaller then the hard_header_len for a short period of time after toggling the vlan offload setting. This is not a hard error and skb_cow_head is called in __vlan_put_tag() to resolve this. Signed-off-by: John Fastabend Acked-by: Jesse Gross Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 14e3d1fa07a0..afb03c5a7adc 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -274,9 +274,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, u16 vlan_tci = 0; int rc; - if (WARN_ON(skb_headroom(skb) < dev->hard_header_len)) - return -ENOSPC; - if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); -- cgit v1.2.3-59-g8ed1b From 636e19a34275d7d6fda0fefa965b1e2a715e2b02 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 30 Oct 2010 14:22:42 +0000 Subject: net: consolidate 8021q tagging Now that VLAN packets are tagged in dev_hard_start_xmit() at the bottom of the stack we no longer need to tag them in the 8021Q module (Except in the !VLAN_FLAG_REORDER_HDR case). This allows the accel path and non accel paths to be consolidated. Here the vlan_tci in the skb is always set and we allow the stack to add the actual tag in dev_hard_start_xmit(). Signed-off-by: John Fastabend Acked-by: Jesse Gross Signed-off-by: David S. Miller --- net/8021q/vlan.h | 4 -- net/8021q/vlan_dev.c | 105 ++++----------------------------------------------- net/8021q/vlanproc.c | 4 -- 3 files changed, 7 insertions(+), 106 deletions(-) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index db01b3181fdc..4625ba64dfdc 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -45,8 +45,6 @@ struct vlan_rx_stats { * @real_dev: underlying netdevice * @real_dev_addr: address of underlying netdevice * @dent: proc dir entry - * @cnt_inc_headroom_on_tx: statistic - number of skb expansions on TX - * @cnt_encap_on_xmit: statistic - number of skb encapsulations on TX * @vlan_rx_stats: ptr to percpu rx stats */ struct vlan_dev_info { @@ -62,8 +60,6 @@ struct vlan_dev_info { unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; - unsigned long cnt_inc_headroom_on_tx; - unsigned long cnt_encap_on_xmit; struct vlan_rx_stats __percpu *vlan_rx_stats; }; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index afb03c5a7adc..f3c9552f6ba8 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -323,24 +323,12 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { - unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; - - vlan_dev_info(dev)->cnt_encap_on_xmit++; - vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); - skb = __vlan_put_tag(skb, vlan_tci); - if (!skb) { - txq->tx_dropped++; - return NETDEV_TX_OK; - } - - if (orig_headroom < VLAN_HLEN) - vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; + skb = __vlan_hwaccel_put_tag(skb, vlan_tci); } - skb_set_dev(skb, vlan_dev_info(dev)->real_dev); len = skb->len; ret = dev_queue_xmit(skb); @@ -354,32 +342,6 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, return ret; } -static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - int i = skb_get_queue_mapping(skb); - struct netdev_queue *txq = netdev_get_tx_queue(dev, i); - u16 vlan_tci; - unsigned int len; - int ret; - - vlan_tci = vlan_dev_info(dev)->vlan_id; - vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); - skb = __vlan_hwaccel_put_tag(skb, vlan_tci); - - skb->dev = vlan_dev_info(dev)->real_dev; - len = skb->len; - ret = dev_queue_xmit(skb); - - if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - txq->tx_packets++; - txq->tx_bytes += len; - } else - txq->tx_dropped++; - - return ret; -} - static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) { struct net_device *rdev = vlan_dev_info(dev)->real_dev; @@ -716,8 +678,7 @@ static const struct header_ops vlan_header_ops = { .parse = eth_header_parse, }; -static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, - vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; +static const struct net_device_ops vlan_netdev_ops, vlan_netdev_ops_sq; static int vlan_dev_init(struct net_device *dev) { @@ -752,19 +713,16 @@ static int vlan_dev_init(struct net_device *dev) if (real_dev->features & NETIF_F_HW_VLAN_TX) { dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; - if (real_dev->netdev_ops->ndo_select_queue) - dev->netdev_ops = &vlan_netdev_accel_ops_sq; - else - dev->netdev_ops = &vlan_netdev_accel_ops; } else { dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; - if (real_dev->netdev_ops->ndo_select_queue) - dev->netdev_ops = &vlan_netdev_ops_sq; - else - dev->netdev_ops = &vlan_netdev_ops; } + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_ops_sq; + else + dev->netdev_ops = &vlan_netdev_ops; + if (is_vlan_dev(real_dev)) subclass = 1; @@ -905,30 +863,6 @@ static const struct net_device_ops vlan_netdev_ops = { #endif }; -static const struct net_device_ops vlan_netdev_accel_ops = { - .ndo_change_mtu = vlan_dev_change_mtu, - .ndo_init = vlan_dev_init, - .ndo_uninit = vlan_dev_uninit, - .ndo_open = vlan_dev_open, - .ndo_stop = vlan_dev_stop, - .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = vlan_dev_set_mac_address, - .ndo_set_rx_mode = vlan_dev_set_rx_mode, - .ndo_set_multicast_list = vlan_dev_set_rx_mode, - .ndo_change_rx_flags = vlan_dev_change_rx_flags, - .ndo_do_ioctl = vlan_dev_ioctl, - .ndo_neigh_setup = vlan_dev_neigh_setup, - .ndo_get_stats64 = vlan_dev_get_stats64, -#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) - .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, - .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, - .ndo_fcoe_enable = vlan_dev_fcoe_enable, - .ndo_fcoe_disable = vlan_dev_fcoe_disable, - .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, -#endif -}; - static const struct net_device_ops vlan_netdev_ops_sq = { .ndo_select_queue = vlan_dev_select_queue, .ndo_change_mtu = vlan_dev_change_mtu, @@ -954,31 +888,6 @@ static const struct net_device_ops vlan_netdev_ops_sq = { #endif }; -static const struct net_device_ops vlan_netdev_accel_ops_sq = { - .ndo_select_queue = vlan_dev_select_queue, - .ndo_change_mtu = vlan_dev_change_mtu, - .ndo_init = vlan_dev_init, - .ndo_uninit = vlan_dev_uninit, - .ndo_open = vlan_dev_open, - .ndo_stop = vlan_dev_stop, - .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = vlan_dev_set_mac_address, - .ndo_set_rx_mode = vlan_dev_set_rx_mode, - .ndo_set_multicast_list = vlan_dev_set_rx_mode, - .ndo_change_rx_flags = vlan_dev_change_rx_flags, - .ndo_do_ioctl = vlan_dev_ioctl, - .ndo_neigh_setup = vlan_dev_neigh_setup, - .ndo_get_stats64 = vlan_dev_get_stats64, -#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) - .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, - .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, - .ndo_fcoe_enable = vlan_dev_fcoe_enable, - .ndo_fcoe_disable = vlan_dev_fcoe_disable, - .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, -#endif -}; - void vlan_setup(struct net_device *dev) { ether_setup(dev); diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 80e280f56686..8a64db19b8a5 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -299,10 +299,6 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) seq_puts(seq, "\n"); seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); - seq_printf(seq, fmt, "total headroom inc", - dev_info->cnt_inc_headroom_on_tx); - seq_printf(seq, fmt, "total encap on xmit", - dev_info->cnt_encap_on_xmit); seq_printf(seq, "Device: %s", dev_info->real_dev->name); /* now show all PRIORITY mappings relating to this VLAN */ seq_printf(seq, "\nINGRESS priority mappings: " -- cgit v1.2.3-59-g8ed1b From 900fcf091e95fbcc773b72c770afcd2e8eda4da2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Nov 2010 09:29:24 +0000 Subject: net: sh_eth: Move off of deprecated I/O routines. sh_eth is the last in-tree user of the ctrl_xxx I/O routines. This simply converts them over to regular MMIO accesors. Signed-off-by: Paul Mundt Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 244 +++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 50259dfec583..b12660d72338 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -45,9 +45,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -57,10 +57,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); break; case 100:/* 100BASE */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); break; default: break; @@ -96,9 +96,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -108,10 +108,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - ctrl_outl(0, ioaddr + RTRATE); + writel(0, ioaddr + RTRATE); break; case 100:/* 100BASE */ - ctrl_outl(1, ioaddr + RTRATE); + writel(1, ioaddr + RTRATE); break; default: break; @@ -143,7 +143,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { static void sh_eth_chip_reset(struct net_device *ndev) { /* reset device */ - ctrl_outl(ARSTR_ARSTR, ARSTR); + writel(ARSTR_ARSTR, ARSTR); mdelay(1); } @@ -152,10 +152,10 @@ static void sh_eth_reset(struct net_device *ndev) u32 ioaddr = ndev->base_addr; int cnt = 100; - ctrl_outl(EDSR_ENALL, ioaddr + EDSR); - ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + writel(EDSR_ENALL, ioaddr + EDSR); + writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); while (cnt > 0) { - if (!(ctrl_inl(ioaddr + EDMR) & 0x3)) + if (!(readl(ioaddr + EDMR) & 0x3)) break; mdelay(1); cnt--; @@ -164,14 +164,14 @@ static void sh_eth_reset(struct net_device *ndev) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ - ctrl_outl(0x0, ioaddr + TDLAR); - ctrl_outl(0x0, ioaddr + TDFAR); - ctrl_outl(0x0, ioaddr + TDFXR); - ctrl_outl(0x0, ioaddr + TDFFR); - ctrl_outl(0x0, ioaddr + RDLAR); - ctrl_outl(0x0, ioaddr + RDFAR); - ctrl_outl(0x0, ioaddr + RDFXR); - ctrl_outl(0x0, ioaddr + RDFFR); + writel(0x0, ioaddr + TDLAR); + writel(0x0, ioaddr + TDFAR); + writel(0x0, ioaddr + TDFXR); + writel(0x0, ioaddr + TDFFR); + writel(0x0, ioaddr + RDLAR); + writel(0x0, ioaddr + RDFAR); + writel(0x0, ioaddr + RDFXR); + writel(0x0, ioaddr + RDFFR); } static void sh_eth_set_duplex(struct net_device *ndev) @@ -180,9 +180,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -192,13 +192,13 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - ctrl_outl(GECMR_10, ioaddr + GECMR); + writel(GECMR_10, ioaddr + GECMR); break; case 100:/* 100BASE */ - ctrl_outl(GECMR_100, ioaddr + GECMR); + writel(GECMR_100, ioaddr + GECMR); break; case 1000: /* 1000BASE */ - ctrl_outl(GECMR_1000, ioaddr + GECMR); + writel(GECMR_1000, ioaddr + GECMR); break; default: break; @@ -283,9 +283,9 @@ static void sh_eth_reset(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); mdelay(3); - ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); + writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); } #endif @@ -336,10 +336,10 @@ static void update_mac_address(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | + writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), ioaddr + MAHR); - ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), + writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), ioaddr + MALR); } @@ -358,12 +358,12 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac) if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { memcpy(ndev->dev_addr, mac, 6); } else { - ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); - ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; - ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; - ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); - ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; - ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); + ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24); + ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF; + ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF; + ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF); + ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF; + ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF); } } @@ -379,19 +379,19 @@ struct bb_info { /* PHY bit set */ static void bb_set(u32 addr, u32 msk) { - ctrl_outl(ctrl_inl(addr) | msk, addr); + writel(readl(addr) | msk, addr); } /* PHY bit clear */ static void bb_clr(u32 addr, u32 msk) { - ctrl_outl((ctrl_inl(addr) & ~msk), addr); + writel((readl(addr) & ~msk), addr); } /* PHY bit read */ static int bb_read(u32 addr, u32 msk) { - return (ctrl_inl(addr) & msk) != 0; + return (readl(addr) & msk) != 0; } /* Data I/O pin control */ @@ -506,9 +506,9 @@ static void sh_eth_ring_format(struct net_device *ndev) rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); /* Rx descriptor address set */ if (i == 0) { - ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR); + writel(mdp->rx_desc_dma, ioaddr + RDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR); + writel(mdp->rx_desc_dma, ioaddr + RDFAR); #endif } } @@ -528,9 +528,9 @@ static void sh_eth_ring_format(struct net_device *ndev) txdesc->buffer_length = 0; if (i == 0) { /* Tx descriptor address set */ - ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR); + writel(mdp->tx_desc_dma, ioaddr + TDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR); + writel(mdp->tx_desc_dma, ioaddr + TDFAR); #endif } } @@ -623,71 +623,71 @@ static int sh_eth_dev_init(struct net_device *ndev) /* Descriptor format */ sh_eth_ring_format(ndev); if (mdp->cd->rpadir) - ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR); + writel(mdp->cd->rpadir_value, ioaddr + RPADIR); /* all sh_eth int mask */ - ctrl_outl(0, ioaddr + EESIPR); + writel(0, ioaddr + EESIPR); #if defined(__LITTLE_ENDIAN__) if (mdp->cd->hw_swap) - ctrl_outl(EDMR_EL, ioaddr + EDMR); + writel(EDMR_EL, ioaddr + EDMR); else #endif - ctrl_outl(0, ioaddr + EDMR); + writel(0, ioaddr + EDMR); /* FIFO size set */ - ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR); - ctrl_outl(0, ioaddr + TFTR); + writel(mdp->cd->fdr_value, ioaddr + FDR); + writel(0, ioaddr + TFTR); /* Frame recv control */ - ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR); + writel(mdp->cd->rmcr_value, ioaddr + RMCR); rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); + writel(rx_int_var | tx_int_var, ioaddr + TRSCER); if (mdp->cd->bculr) - ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */ + writel(0x800, ioaddr + BCULR); /* Burst sycle set */ - ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR); + writel(mdp->cd->fcftr_value, ioaddr + FCFTR); if (!mdp->cd->no_trimd) - ctrl_outl(0, ioaddr + TRIMD); + writel(0, ioaddr + TRIMD); /* Recv frame limit set register */ - ctrl_outl(RFLR_VALUE, ioaddr + RFLR); + writel(RFLR_VALUE, ioaddr + RFLR); - ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); - ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR); + writel(readl(ioaddr + EESR), ioaddr + EESR); + writel(mdp->cd->eesipr_value, ioaddr + EESIPR); /* PAUSE Prohibition */ - val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) | + val = (readl(ioaddr + ECMR) & ECMR_DM) | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; - ctrl_outl(val, ioaddr + ECMR); + writel(val, ioaddr + ECMR); if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); /* E-MAC Status Register clear */ - ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR); + writel(mdp->cd->ecsr_value, ioaddr + ECSR); /* E-MAC Interrupt Enable register */ - ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR); + writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR); /* Set MAC address */ update_mac_address(ndev); /* mask reset */ if (mdp->cd->apr) - ctrl_outl(APR_AP, ioaddr + APR); + writel(APR_AP, ioaddr + APR); if (mdp->cd->mpr) - ctrl_outl(MPR_MP, ioaddr + MPR); + writel(MPR_MP, ioaddr + MPR); if (mdp->cd->tpauser) - ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); + writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER); /* Setting the Rx mode will start the Rx process. */ - ctrl_outl(EDRRR_R, ioaddr + EDRRR); + writel(EDRRR_R, ioaddr + EDRRR); netif_start_queue(ndev); @@ -811,8 +811,8 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R)) - ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); + if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R)) + writel(EDRRR_R, ndev->base_addr + EDRRR); return 0; } @@ -827,8 +827,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) u32 mask; if (intr_status & EESR_ECI) { - felic_stat = ctrl_inl(ioaddr + ECSR); - ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */ + felic_stat = readl(ioaddr + ECSR); + writel(felic_stat, ioaddr + ECSR); /* clear int */ if (felic_stat & ECSR_ICD) mdp->stats.tx_carrier_errors++; if (felic_stat & ECSR_LCHNG) { @@ -839,25 +839,25 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) else link_stat = PHY_ST_LINK; } else { - link_stat = (ctrl_inl(ioaddr + PSR)); + link_stat = (readl(ioaddr + PSR)); if (mdp->ether_link_active_low) link_stat = ~link_stat; } if (!(link_stat & PHY_ST_LINK)) { /* Link Down : disable tx and rx */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & + writel(readl(ioaddr + ECMR) & ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); } else { /* Link Up */ - ctrl_outl(ctrl_inl(ioaddr + EESIPR) & + writel(readl(ioaddr + EESIPR) & ~DMAC_M_ECI, ioaddr + EESIPR); /*clear int */ - ctrl_outl(ctrl_inl(ioaddr + ECSR), + writel(readl(ioaddr + ECSR), ioaddr + ECSR); - ctrl_outl(ctrl_inl(ioaddr + EESIPR) | + writel(readl(ioaddr + EESIPR) | DMAC_M_ECI, ioaddr + EESIPR); /* enable tx and rx */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | + writel(readl(ioaddr + ECMR) | (ECMR_RE | ECMR_TE), ioaddr + ECMR); } } @@ -888,8 +888,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ mdp->stats.rx_over_errors++; - if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R) - ctrl_outl(EDRRR_R, ioaddr + EDRRR); + if (readl(ioaddr + EDRRR) ^ EDRRR_R) + writel(EDRRR_R, ioaddr + EDRRR); dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } if (intr_status & EESR_RFE) { @@ -903,7 +903,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) mask &= ~EESR_ADE; if (intr_status & mask) { /* Tx error */ - u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); + u32 edtrr = readl(ndev->base_addr + EDTRR); /* dmesg */ dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ", intr_status, mdp->cur_tx); @@ -915,7 +915,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* SH7712 BUG */ if (edtrr ^ EDTRR_TRNS) { /* tx dma start */ - ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); + writel(EDTRR_TRNS, ndev->base_addr + EDTRR); } /* wakeup */ netif_wake_queue(ndev); @@ -934,12 +934,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) spin_lock(&mdp->lock); /* Get interrpt stat */ - intr_status = ctrl_inl(ioaddr + EESR); + intr_status = readl(ioaddr + EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | cd->tx_check | cd->eesr_err_check)) { - ctrl_outl(intr_status, ioaddr + EESR); + writel(intr_status, ioaddr + EESR); ret = IRQ_HANDLED; } else goto other_irq; @@ -1000,7 +1000,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) mdp->cd->set_rate(ndev); } if (mdp->link == PHY_DOWN) { - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) + writel((readl(ioaddr + ECMR) & ~ECMR_TXF) | ECMR_DM, ioaddr + ECMR); new_state = 1; mdp->link = phydev->link; @@ -1125,7 +1125,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) /* worning message out. */ printk(KERN_WARNING "%s: transmit timed out, status %8.8x," - " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR)); + " resetting...\n", ndev->name, (int)readl(ioaddr + EESR)); /* tx_errors count up */ mdp->stats.tx_errors++; @@ -1196,8 +1196,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) mdp->cur_tx++; - if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) - ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); + if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) + writel(EDTRR_TRNS, ndev->base_addr + EDTRR); return NETDEV_TX_OK; } @@ -1212,11 +1212,11 @@ static int sh_eth_close(struct net_device *ndev) netif_stop_queue(ndev); /* Disable interrupts by clearing the interrupt mask. */ - ctrl_outl(0x0000, ioaddr + EESIPR); + writel(0x0000, ioaddr + EESIPR); /* Stop the chip's Tx and Rx processes. */ - ctrl_outl(0, ioaddr + EDTRR); - ctrl_outl(0, ioaddr + EDRRR); + writel(0, ioaddr + EDTRR); + writel(0, ioaddr + EDRRR); /* PHY Disconnect */ if (mdp->phydev) { @@ -1251,20 +1251,20 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) pm_runtime_get_sync(&mdp->pdev->dev); - mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); - ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ - mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); - ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); - ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ + mdp->stats.tx_dropped += readl(ioaddr + TROCR); + writel(0, ioaddr + TROCR); /* (write clear) */ + mdp->stats.collisions += readl(ioaddr + CDCR); + writel(0, ioaddr + CDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR); + writel(0, ioaddr + LCCR); /* (write clear) */ #if defined(CONFIG_CPU_SUBTYPE_SH7763) - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */ - ctrl_outl(0, ioaddr + CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */ - ctrl_outl(0, ioaddr + CEECR); /* (write clear) */ + mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */ + writel(0, ioaddr + CERCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */ + writel(0, ioaddr + CEECR); /* (write clear) */ #else - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); - ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR); + writel(0, ioaddr + CNDCR); /* (write clear) */ #endif pm_runtime_put_sync(&mdp->pdev->dev); @@ -1295,11 +1295,11 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Set promiscuous. */ - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, + writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, ioaddr + ECMR); } else { /* Normal, unicast/broadcast-only mode. */ - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, + writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, ioaddr + ECMR); } } @@ -1307,30 +1307,30 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) /* SuperH's TSU register init function */ static void sh_eth_tsu_init(u32 ioaddr) { - ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ - ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ - ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ - ctrl_outl(0xc, ioaddr + TSU_BSYSL0); - ctrl_outl(0xc, ioaddr + TSU_BSYSL1); - ctrl_outl(0, ioaddr + TSU_PRISL0); - ctrl_outl(0, ioaddr + TSU_PRISL1); - ctrl_outl(0, ioaddr + TSU_FWSL0); - ctrl_outl(0, ioaddr + TSU_FWSL1); - ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); + writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ + writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ + writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ + writel(0xc, ioaddr + TSU_BSYSL0); + writel(0xc, ioaddr + TSU_BSYSL1); + writel(0, ioaddr + TSU_PRISL0); + writel(0, ioaddr + TSU_PRISL1); + writel(0, ioaddr + TSU_FWSL0); + writel(0, ioaddr + TSU_FWSL1); + writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ - ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ + writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ + writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ #else - ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ - ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ + writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ + writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ #endif - ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ - ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ - ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ - ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ - ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ - ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ - ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ + writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ + writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ + writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ + writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ + writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ + writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ + writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ } #endif /* SH_ETH_HAS_TSU */ -- cgit v1.2.3-59-g8ed1b From 6b7b6cf553f881d45bb37a73f5db956afb290a08 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 20 Oct 2010 02:09:44 +0200 Subject: ath9k_hw: initialize regulatory->max_power_level in set_txpower for AR9003 The same is done for the older chip families as well. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c4182359bee4..92cfef225477 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -2133,6 +2133,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, u8 twiceMaxRegulatoryPower, u8 powerLimit) { + struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); u8 targetPowerValT2[ar9300RateSize]; unsigned int i = 0; @@ -2180,6 +2181,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, i = ALL_TARGET_HT20_0_8_16; /* ht20 */ ah->txpower_limit = targetPowerValT2[i]; + regulatory->max_power_level = ratesArray[i]; ar9003_hw_calibration_apply(ah, chan->channel); } -- cgit v1.2.3-59-g8ed1b From de40f316c01b1ba9535e6dc99f6a67e7655b07da Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 20 Oct 2010 03:08:53 +0200 Subject: ath9k_hw: extend ath9k_hw_set_txpowerlimit to test channel txpower ath9k_hw_set_txpowerlimit gets an extra boolean parameter that - if set - causes the rate txpower table and the regulatory limit to be calculated and stored, without changing hardware registers. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 20 ++++++--- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom.h | 3 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 9 +++- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 27 ++++++----- drivers/net/wireless/ath/ath9k/eeprom_def.c | 62 ++++++++++++++------------ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 6 +-- drivers/net/wireless/ath/ath9k/hw.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 2 +- 11 files changed, 79 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ea9f4497f58c..777a602176f2 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -873,7 +873,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, - (u32) regulatory->power_limit)); + (u32) regulatory->power_limit), false); /* Write analog registers */ if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 92cfef225477..a88fe0d6142f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -2131,7 +2131,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, - u8 powerLimit) + u8 powerLimit, bool test) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); @@ -2145,7 +2145,16 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, twiceMaxRegulatoryPower, powerLimit); - while (i < ar9300RateSize) { + regulatory->max_power_level = 0; + for (i = 0; i < ar9300RateSize; i++) { + if (targetPowerValT2[i] > regulatory->max_power_level) + regulatory->max_power_level = targetPowerValT2[i]; + } + + if (test) + return; + + for (i = 0; i < ar9300RateSize; i++) { ath_print(common, ATH_DBG_EEPROM, "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; @@ -2160,9 +2169,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, i++; } - /* Write target power array to registers */ - ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); - /* * This is the TX power we send back to driver core, * and it can use to pass to userspace to display our @@ -2181,8 +2187,10 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, i = ALL_TARGET_HT20_0_8_16; /* ht20 */ ah->txpower_limit = targetPowerValT2[i]; - regulatory->max_power_level = ratesArray[i]; + regulatory->max_power_level = targetPowerValT2[i]; + /* Write target power array to registers */ + ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); ar9003_hw_calibration_apply(ah, chan->channel); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 669b777729b3..06a9c4cd2f44 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -614,7 +614,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, - (u32) regulatory->power_limit)); + (u32) regulatory->power_limit), false); return 0; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index dacb45e1b906..3c99830dab0c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -680,7 +680,8 @@ struct eeprom_ops { void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, - u8 twiceMaxRegulatoryPower, u8 powerLimit); + u8 twiceMaxRegulatoryPower, u8 powerLimit, + bool test); u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); }; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4fa4d8e28c64..c40c534c6662 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -726,7 +726,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, - u8 powerLimit) + u8 powerLimit, bool test) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; @@ -751,15 +751,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); + regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); if (ratesArray[i] > AR5416_MAX_RATE_POWER) ratesArray[i] = AR5416_MAX_RATE_POWER; + + if (ratesArray[i] > regulatory->max_power_level) + regulatory->max_power_level = ratesArray[i]; } + if (test) + return; /* Update regulatory */ - i = rate6mb; if (IS_CHAN_HT40(chan)) i = rateHt40_0; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 966b9496a9dd..ebf7a89f547c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -853,7 +853,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, - u8 powerLimit) + u8 powerLimit, bool test) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; @@ -877,12 +877,26 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset); + regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); if (ratesArray[i] > AR9287_MAX_RATE_POWER) ratesArray[i] = AR9287_MAX_RATE_POWER; + + if (ratesArray[i] > regulatory->max_power_level) + regulatory->max_power_level = ratesArray[i]; } + if (test) + return; + + if (IS_CHAN_2GHZ(chan)) + i = rate1l; + else + i = rate6mb; + + regulatory->max_power_level = ratesArray[i]; + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; @@ -971,17 +985,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); } - - if (IS_CHAN_2GHZ(chan)) - i = rate1l; - else - i = rate6mb; - - if (AR_SREV_9280_20_OR_LATER(ah)) - regulatory->max_power_level = - ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; - else - regulatory->max_power_level = ratesArray[i]; } static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 76b4d65472dd..a819ddc9fdbc 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -1258,7 +1258,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, - u8 powerLimit) + u8 powerLimit, bool test) { #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); @@ -1285,12 +1285,44 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); + regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); if (ratesArray[i] > AR5416_MAX_RATE_POWER) ratesArray[i] = AR5416_MAX_RATE_POWER; + if (ratesArray[i] > regulatory->max_power_level) + regulatory->max_power_level = ratesArray[i]; } + if (!test) { + i = rate6mb; + + if (IS_CHAN_HT40(chan)) + i = rateHt40_0; + else if (IS_CHAN_HT20(chan)) + i = rateHt20_0; + + regulatory->max_power_level = ratesArray[i]; + } + + switch(ar5416_get_ntxchains(ah->txchainmask)) { + case 1: + break; + case 2: + regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; + break; + case 3: + regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; + break; + default: + ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM, + "Invalid chainmask configuration\n"); + break; + } + + if (test) + return; + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) { int8_t pwr_table_offset; @@ -1387,34 +1419,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_POWER_TX_SUB, ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); - - i = rate6mb; - - if (IS_CHAN_HT40(chan)) - i = rateHt40_0; - else if (IS_CHAN_HT20(chan)) - i = rateHt20_0; - - if (AR_SREV_9280_20_OR_LATER(ah)) - regulatory->max_power_level = - ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2; - else - regulatory->max_power_level = ratesArray[i]; - - switch(ar5416_get_ntxchains(ah->txchainmask)) { - case 1: - break; - case 2: - regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; - break; - case 3: - regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; - break; - default: - ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM, - "Invalid chainmask configuration\n"); - break; - } } static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a3be8da755d..26b9a16ce33f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -29,7 +29,7 @@ static void ath_update_txpow(struct ath9k_htc_priv *priv) struct ath_hw *ah = priv->ah; if (priv->curtxpow != priv->txpowlimit) { - ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit); + ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false); /* read back in case value is clamped */ priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit; } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d37a8ad03d74..e75d8e8cf4d2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1166,7 +1166,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, - (u32) regulatory->power_limit)); + (u32) regulatory->power_limit), false); ath9k_hw_rfbus_done(ah); @@ -2165,7 +2165,7 @@ bool ath9k_hw_disable(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable); -void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) +void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath9k_channel *chan = ah->curchan; @@ -2178,7 +2178,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, - (u32) regulatory->power_limit)); + (u32) regulatory->power_limit), test); } EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e68204ae899c..366f088dc15d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -860,7 +860,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah); void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); bool ath9k_hw_phy_disable(struct ath_hw *ah); bool ath9k_hw_disable(struct ath_hw *ah); -void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); +void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test); void ath9k_hw_setopmode(struct ath_hw *ah); void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); void ath9k_hw_setbssidmask(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7185ef3a3bff..92ed5bb71196 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -23,7 +23,7 @@ static void ath_update_txpow(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; if (sc->curtxpow != sc->config.txpowlimit) { - ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); + ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); /* read back in case value is clamped */ sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; } -- cgit v1.2.3-59-g8ed1b From babcbc295fee766ca710235e431686fef744d9a6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 20 Oct 2010 02:09:46 +0200 Subject: ath9k: initialize per-channel tx power limits instead of hardcoding them Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common.c | 15 +++++------- drivers/net/wireless/ath/ath9k/common.h | 5 ++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 +++- drivers/net/wireless/ath/ath9k/init.c | 33 +++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index f43a2d98421c..48b07c319a7f 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -107,12 +107,10 @@ static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan, /* * Update internal channel flags. */ -void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, - struct ath9k_channel *ichan) +void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) { - struct ieee80211_channel *chan = hw->conf.channel; - struct ieee80211_conf *conf = &hw->conf; - ichan->channel = chan->center_freq; ichan->chan = chan; @@ -124,9 +122,8 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; } - if (conf_is_ht(conf)) - ichan->chanmode = ath9k_get_extchanmode(chan, - conf->channel_type); + if (channel_type != NL80211_CHAN_NO_HT) + ichan->chanmode = ath9k_get_extchanmode(chan, channel_type); } EXPORT_SYMBOL(ath9k_cmn_update_ichannel); @@ -142,7 +139,7 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, chan_idx = curchan->hw_value; channel = &ah->channels[chan_idx]; - ath9k_cmn_update_ichannel(hw, channel); + ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); return channel; } diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index fea3b3315391..c76c75a77c62 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -62,8 +62,9 @@ enum ath_stomp_type { int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); -void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, - struct ath9k_channel *ichan); +void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type); struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, struct ath_hw *ah); int ath9k_cmn_count_streams(unsigned int chainmask, int max); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 26b9a16ce33f..8266ce1f02e3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1400,7 +1400,9 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", curchan->center_freq); - ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); + ath9k_cmn_update_ichannel(&priv->ah->channels[pos], + hw->conf.channel, + hw->conf.channel_type); if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { ath_print(common, ATH_DBG_FATAL, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 12f4fd79c907..1b72720b36e2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -642,6 +642,37 @@ err_hw: return ret; } +static void ath9k_init_band_txpower(struct ath_softc *sc, int band) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + struct ath_hw *ah = sc->sc_ah; + struct ath_regulatory *reg = ath9k_hw_regulatory(ah); + int i; + + sband = &sc->sbands[band]; + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; + ah->curchan = &ah->channels[chan->hw_value]; + ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); + ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); + chan->max_power = reg->max_power_level / 2; + } +} + +static void ath9k_init_txpower_limits(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_channel *curchan = ah->curchan; + + if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) + ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); + if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) + ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); + + ah->curchan = curchan; +} + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -736,6 +767,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, if (error != 0) goto error_rx; + ath9k_init_txpower_limits(sc); + /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) -- cgit v1.2.3-59-g8ed1b From a3685d119dacb07a7080169fea2847ef385b209f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 06:59:36 -0700 Subject: ath: make ath_hw_keysetmac() static This fixes this sparse warning: CHECK drivers/net/wireless/ath/key.c drivers/net/wireless/ath/key.c:70:6: warning: symbol 'ath_hw_keysetmac' was not declared. Should it be static? Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/key.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index bd21a4d82085..1e9aa326ca08 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -67,7 +67,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) } EXPORT_SYMBOL(ath_hw_keyreset); -bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) +static bool ath_hw_keysetmac(struct ath_common *common, + u16 entry, const u8 *mac) { u32 macHi, macLo; u32 unicast_flag = AR_KEYTABLE_VALID; -- cgit v1.2.3-59-g8ed1b From f8c2a0871b8462481a02445b38a7321ad63bfc88 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 06:59:37 -0700 Subject: ath: make ath_hw_set_keycache_entry() static This fixes this sparse warning: CHECK drivers/net/wireless/ath/key.c drivers/net/wireless/ath/key.c:110:6: warning: symbol 'ath_hw_set_keycache_entry' was not declared. Should it be static? Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/key.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 1e9aa326ca08..62e3dac8f92a 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -108,9 +108,9 @@ static bool ath_hw_keysetmac(struct ath_common *common, return true; } -bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, - const struct ath_keyval *k, - const u8 *mac) +static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, + const struct ath_keyval *k, + const u8 *mac) { void *ah = common->ah; u32 key0, key1, key2, key3, key4; -- cgit v1.2.3-59-g8ed1b From 14fb7c17e97ea0fcc545393fb1f34e6541647b5b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 06:59:38 -0700 Subject: ath5k: make ath5k_update_bssid_mask_and_opmode() static This fixes this sparse warning: CHECK drivers/net/wireless/ath/ath5k/base.c drivers/net/wireless/ath/ath5k/base.c:569:6: warning: symbol 'ath5k_update_bssid_mask_and_opmode' was not declared. Should it be static? Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 484aad5b11b5..b9f93fbd9728 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -566,8 +566,8 @@ static void ath_do_set_opmode(struct ath5k_softc *sc) sc->opmode, ath_opmode_to_string(sc->opmode)); } -void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, - struct ieee80211_vif *vif) +static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif) { struct ath_common *common = ath5k_hw_common(sc->ah); struct ath_vif_iter_data iter_data; -- cgit v1.2.3-59-g8ed1b From e081685c1bbe8da37c7f61726fdb783ff277f14f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 20 Oct 2010 09:59:33 -0500 Subject: ssb: Clear RETRY_TIMEOUT in PCI Configuration for normal devices MMIO log traces obtained using the Broadcom wl hybrid driver show that the RETRY_TIMEOUT register (0x41) in PCI configuration space is cleared if non-zero. Similar code found in other drivers such as ipw2100 show this operation is needed to keep PCI Tx retries from interfering with C3 CPU state. There are no known cases where omission of this code has caused a problem, but this patch is offered just in case such a situation occurs. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/ssb/pcihost_wrapper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c index 6536a041d90d..f6c8c81a0025 100644 --- a/drivers/ssb/pcihost_wrapper.c +++ b/drivers/ssb/pcihost_wrapper.c @@ -59,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev, struct ssb_bus *ssb; int err = -ENOMEM; const char *name; + u32 val; ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); if (!ssb) @@ -74,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_dev *dev, goto err_pci_disable; pci_set_master(dev); + /* Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_read_config_dword(dev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(dev, 0x40, val & 0xffff00ff); + err = ssb_bus_pcibus_register(ssb, dev); if (err) goto err_pci_release_regions; -- cgit v1.2.3-59-g8ed1b From 2e48928d8a0f38c1b5c81eb3f1294de8a6382c68 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 20 Oct 2010 10:16:58 -0700 Subject: rfkill: remove dead code The following code is defined but never used. Signed-off-by: Stephen Hemminger Signed-off-by: John W. Linville --- include/linux/rfkill.h | 31 ------------------------------- net/rfkill/core.c | 14 -------------- 2 files changed, 45 deletions(-) diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 08c32e4f261a..c6c608482cba 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -354,37 +354,6 @@ static inline bool rfkill_blocked(struct rfkill *rfkill) } #endif /* RFKILL || RFKILL_MODULE */ - -#ifdef CONFIG_RFKILL_LEDS -/** - * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED. - * This function might return a NULL pointer if registering of the - * LED trigger failed. Use this as "default_trigger" for the LED. - */ -const char *rfkill_get_led_trigger_name(struct rfkill *rfkill); - -/** - * rfkill_set_led_trigger_name -- set the LED trigger name - * @rfkill: rfkill struct - * @name: LED trigger name - * - * This function sets the LED trigger name of the radio LED - * trigger that rfkill creates. It is optional, but if called - * must be called before rfkill_register() to be effective. - */ -void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name); -#else -static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) -{ - return NULL; -} - -static inline void -rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) -{ -} -#endif - #endif /* __KERNEL__ */ #endif /* RFKILL_H */ diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 04f599089e6d..0198191b756d 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -149,20 +149,6 @@ static void rfkill_led_trigger_activate(struct led_classdev *led) rfkill_led_trigger_event(rfkill); } -const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) -{ - return rfkill->led_trigger.name; -} -EXPORT_SYMBOL(rfkill_get_led_trigger_name); - -void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) -{ - BUG_ON(!rfkill); - - rfkill->ledtrigname = name; -} -EXPORT_SYMBOL(rfkill_set_led_trigger_name); - static int rfkill_led_trigger_register(struct rfkill *rfkill) { rfkill->led_trigger.name = rfkill->ledtrigname -- cgit v1.2.3-59-g8ed1b From 7ca43d03b1291481bdf894bbaec5d580e7684e7d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 10:18:53 -0700 Subject: cfg80211: pass the reg hint initiator to helpers This is required later. Cc: Easwar Krishnan Cc: stable@kernel.org signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4b9f8912526c..b64596fe7363 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -720,7 +720,9 @@ EXPORT_SYMBOL(freq_reg_info); * on the wiphy with the target_bw specified. Then we can simply use * that below for the desired_bw_khz below. */ -static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, +static void handle_channel(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + enum ieee80211_band band, unsigned int chan_idx) { int r; @@ -784,7 +786,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } -static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) +static void handle_band(struct wiphy *wiphy, + enum ieee80211_band band, + enum nl80211_reg_initiator initiator) { unsigned int i; struct ieee80211_supported_band *sband; @@ -793,7 +797,7 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) sband = wiphy->bands[band]; for (i = 0; i < sband->n_channels; i++) - handle_channel(wiphy, band, i); + handle_channel(wiphy, initiator, band, i); } static bool ignore_reg_update(struct wiphy *wiphy, @@ -1030,7 +1034,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, goto out; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (wiphy->bands[band]) - handle_band(wiphy, band); + handle_band(wiphy, band, initiator); } out: reg_process_beacons(wiphy); -- cgit v1.2.3-59-g8ed1b From 749b527b21465fb079796c03ffb4302584dc31c1 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 10:18:54 -0700 Subject: cfg80211: fix allowing country IEs for WIPHY_FLAG_STRICT_REGULATORY We should be enabling country IE hints for WIPHY_FLAG_STRICT_REGULATORY even if we haven't yet recieved regulatory domain hint for the driver if it needed one. Without this Country IEs are not passed on to drivers that have set WIPHY_FLAG_STRICT_REGULATORY, today this is just all Atheros chipset drivers: ath5k, ath9k, ar9170, carl9170. This was part of the original design, however it was completely overlooked... Cc: Easwar Krishnan Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/net/cfg80211.h | 15 ++++++++------- net/wireless/reg.c | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2a7936d7851d..e5702f5ac57c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1321,13 +1321,14 @@ struct cfg80211_ops { * initiator is %REGDOM_SET_BY_CORE). * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will * ignore regulatory domain settings until it gets its own regulatory - * domain via its regulatory_hint(). After its gets its own regulatory - * domain it will only allow further regulatory domain settings to - * further enhance compliance. For example if channel 13 and 14 are - * disabled by this regulatory domain no user regulatory domain can - * enable these channels at a later time. This can be used for devices - * which do not have calibration information gauranteed for frequencies - * or settings outside of its regulatory domain. + * domain via its regulatory_hint() unless the regulatory hint is + * from a country IE. After its gets its own regulatory domain it will + * only allow further regulatory domain settings to further enhance + * compliance. For example if channel 13 and 14 are disabled by this + * regulatory domain no user regulatory domain can enable these channels + * at a later time. This can be used for devices which do not have + * calibration information guaranteed for frequencies or settings + * outside of its regulatory domain. * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure * that passive scan flags and beaconing flags may not be lifted by * cfg80211 due to regulatory beacon hints. For more information on beacon diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b64596fe7363..1bc8131a5185 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -813,6 +813,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, * desired regulatory domain set */ if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && + initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && !is_world_regdom(last_request->alpha2)) return true; return false; -- cgit v1.2.3-59-g8ed1b From ca4ffe8f2848169a8ded0ea8a60b2d81925564c9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 10:18:55 -0700 Subject: cfg80211: fix disabling channels based on hints After a module loads you will have loaded the world roaming regulatory domain or a custom regulatory domain. Further regulatory hints are welcomed and should be respected unless the regulatory hint is coming from a country IE as the IEEE spec allows for a country IE to be a subset of what is allowed by the local regulatory agencies. So disable all channels that do not fit a regulatory domain sent from a unless the hint is from a country IE and the country IE had no information about the band we are currently processing. This fixes a few regulatory issues, for example for drivers that depend on CRDA and had no 5 GHz freqencies allowed were not properly disabling 5 GHz at all, furthermore it also allows users to restrict devices further as was intended. If you recieve a country IE upon association we will also disable the channels that are not allowed if the country IE had at least one channel on the respective band we are procesing. This was the original intention behind this design but it was completely overlooked... Cc: David Quan Cc: Jouni Malinen cc: Easwar Krishnan Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/linux/nl80211.h | 6 +++++- net/wireless/reg.c | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0edb2566c14c..fb877b5621b7 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1307,7 +1307,11 @@ enum nl80211_bitrate_attr { * wireless core it thinks its knows the regulatory domain we should be in. * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an * 802.11 country information element with regulatory information it - * thinks we should consider. + * thinks we should consider. cfg80211 only processes the country + * code from the IE, and relies on the regulatory domain information + * structure pased by userspace (CRDA) from our wireless-regdb. + * If a channel is enabled but the country code indicates it should + * be disabled we disable the channel and re-enable it upon disassociation. */ enum nl80211_reg_initiator { NL80211_REGDOM_SET_BY_CORE, diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1bc8131a5185..8ab65f2afe70 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -750,8 +750,26 @@ static void handle_channel(struct wiphy *wiphy, desired_bw_khz, ®_rule); - if (r) + if (r) { + /* + * We will disable all channels that do not match our + * recieved regulatory rule unless the hint is coming + * from a Country IE and the Country IE had no information + * about a band. The IEEE 802.11 spec allows for an AP + * to send only a subset of the regulatory rules allowed, + * so an AP in the US that only supports 2.4 GHz may only send + * a country IE with information for the 2.4 GHz band + * while 5 GHz is still supported. + */ + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && + r == -ERANGE) + return; + + REG_DBG_PRINT("cfg80211: Disabling freq %d MHz\n", + chan->center_freq); + chan->flags = IEEE80211_CHAN_DISABLED; return; + } power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; -- cgit v1.2.3-59-g8ed1b From 926a0a094d2b9052db3f7f37438c3d305cea4be7 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 21 Oct 2010 19:17:03 +0530 Subject: cfg80211: add debug prints for when we ignore regulatory hints This can help with debugging issues. You will only see these with CONFIG_CFG80211_REG_DEBUG enabled. Cc: Easwar Krishnan Signed-off-by: Luis R. Rodriguez Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- net/wireless/reg.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 8ab65f2afe70..7bff1c1d6c8f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -711,6 +711,25 @@ int freq_reg_info(struct wiphy *wiphy, } EXPORT_SYMBOL(freq_reg_info); +#ifdef CONFIG_CFG80211_REG_DEBUG +static const char *reg_initiator_name(enum nl80211_reg_initiator initiator) +{ + switch (initiator) { + case NL80211_REGDOM_SET_BY_CORE: + return "Set by core"; + case NL80211_REGDOM_SET_BY_USER: + return "Set by user"; + case NL80211_REGDOM_SET_BY_DRIVER: + return "Set by driver"; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + return "Set by country IE"; + default: + WARN_ON(1); + return "Set by bug"; + } +} +#endif + /* * Note that right now we assume the desired channel bandwidth * is always 20 MHz for each individual channel (HT40 uses 20 MHz @@ -821,19 +840,36 @@ static void handle_band(struct wiphy *wiphy, static bool ignore_reg_update(struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { - if (!last_request) + if (!last_request) { + REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s since " + "last_request is not set\n", + reg_initiator_name(initiator)); return true; + } + if (initiator == NL80211_REGDOM_SET_BY_CORE && - wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) + wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { + REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s " + "since the driver uses its own custom " + "regulatory domain ", + reg_initiator_name(initiator)); return true; + } + /* * wiphy->regd will be set once the device has its own * desired regulatory domain set */ if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && - !is_world_regdom(last_request->alpha2)) + !is_world_regdom(last_request->alpha2)) { + REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s " + "since the driver requires its own regulaotry " + "domain to be set first", + reg_initiator_name(initiator)); return true; + } + return false; } -- cgit v1.2.3-59-g8ed1b From a65185367f9f876448f0f12ac09a673d20371efc Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 10:18:57 -0700 Subject: cfg80211: add debug print when disabling a channel on a custom regd Cc: Easwar Krishnan Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7bff1c1d6c8f..6e7a9d853191 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1125,6 +1125,11 @@ static void handle_channel_custom(struct wiphy *wiphy, regd); if (r) { + REG_DBG_PRINT("cfg80211: Disabling freq %d MHz as custom " + "regd has no rule that fits a %d MHz " + "wide channel\n", + chan->center_freq, + KHZ_TO_MHZ(desired_bw_khz)); chan->flags = IEEE80211_CHAN_DISABLED; return; } -- cgit v1.2.3-59-g8ed1b From e702d3cf29143327679ce2e2a60775eaf829f377 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 21 Oct 2010 19:17:04 +0530 Subject: cfg80211: add debug print when processing a channel In the worst case you are seeing really odd things you want more information than what is provided right now, for those that insist and want debug info through CONFIG_CFG80211_REG_DEBUG provide a print of when we are processing a channel and with what regulatory rule. Cc: Easwar Krishnan Signed-off-by: Luis R. Rodriguez Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- net/wireless/reg.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6e7a9d853191..5556c5fe489a 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -728,6 +728,41 @@ static const char *reg_initiator_name(enum nl80211_reg_initiator initiator) return "Set by bug"; } } + +static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, + u32 desired_bw_khz, + const struct ieee80211_reg_rule *reg_rule) +{ + const struct ieee80211_power_rule *power_rule; + const struct ieee80211_freq_range *freq_range; + char max_antenna_gain[32]; + + power_rule = ®_rule->power_rule; + freq_range = ®_rule->freq_range; + + if (!power_rule->max_antenna_gain) + snprintf(max_antenna_gain, 32, "N/A"); + else + snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); + + REG_DBG_PRINT("cfg80211: Updating information on frequency %d MHz " + "for %d a MHz width channel with regulatory rule:\n", + chan->center_freq, + KHZ_TO_MHZ(desired_bw_khz)); + + REG_DBG_PRINT("cfg80211: %d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", + freq_range->start_freq_khz, + freq_range->end_freq_khz, + max_antenna_gain, + power_rule->max_eirp); +} +#else +static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, + u32 desired_bw_khz, + const struct ieee80211_reg_rule *reg_rule) +{ + return; +} #endif /* @@ -790,6 +825,8 @@ static void handle_channel(struct wiphy *wiphy, return; } + chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule); + power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; @@ -1134,6 +1171,8 @@ static void handle_channel_custom(struct wiphy *wiphy, return; } + chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule); + power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; -- cgit v1.2.3-59-g8ed1b From d91e41b690f795c04af4eb6fe28d2cafd3291051 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 10:18:59 -0700 Subject: cfg80211: prefix REG_DBG_PRINT() with cfg80211 Everyone's doing it, its the cool thing. Cc: Easwar Krishnan Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 5556c5fe489a..3be18d9a944f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -48,7 +48,7 @@ #ifdef CONFIG_CFG80211_REG_DEBUG #define REG_DBG_PRINT(format, args...) \ do { \ - printk(KERN_DEBUG format , ## args); \ + printk(KERN_DEBUG "cfg80211: " format , ## args); \ } while (0) #else #define REG_DBG_PRINT(args...) @@ -745,12 +745,12 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, else snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); - REG_DBG_PRINT("cfg80211: Updating information on frequency %d MHz " + REG_DBG_PRINT("Updating information on frequency %d MHz " "for %d a MHz width channel with regulatory rule:\n", chan->center_freq, KHZ_TO_MHZ(desired_bw_khz)); - REG_DBG_PRINT("cfg80211: %d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", + REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, max_antenna_gain, @@ -819,8 +819,7 @@ static void handle_channel(struct wiphy *wiphy, r == -ERANGE) return; - REG_DBG_PRINT("cfg80211: Disabling freq %d MHz\n", - chan->center_freq); + REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); chan->flags = IEEE80211_CHAN_DISABLED; return; } @@ -878,7 +877,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { if (!last_request) { - REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s since " + REG_DBG_PRINT("Ignoring regulatory request %s since " "last_request is not set\n", reg_initiator_name(initiator)); return true; @@ -886,7 +885,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, if (initiator == NL80211_REGDOM_SET_BY_CORE && wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { - REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s " + REG_DBG_PRINT("Ignoring regulatory request %s " "since the driver uses its own custom " "regulatory domain ", reg_initiator_name(initiator)); @@ -900,7 +899,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && !is_world_regdom(last_request->alpha2)) { - REG_DBG_PRINT("cfg80211: Ignoring regulatory request %s " + REG_DBG_PRINT("Ignoring regulatory request %s " "since the driver requires its own regulaotry " "domain to be set first", reg_initiator_name(initiator)); @@ -1162,7 +1161,7 @@ static void handle_channel_custom(struct wiphy *wiphy, regd); if (r) { - REG_DBG_PRINT("cfg80211: Disabling freq %d MHz as custom " + REG_DBG_PRINT("Disabling freq %d MHz as custom " "regd has no rule that fits a %d MHz " "wide channel\n", chan->center_freq, @@ -1662,7 +1661,7 @@ static void restore_alpha2(char *alpha2, bool reset_user) if (is_user_regdom_saved()) { /* Unless we're asked to ignore it and reset it */ if (reset_user) { - REG_DBG_PRINT("cfg80211: Restoring regulatory settings " + REG_DBG_PRINT("Restoring regulatory settings " "including user preference\n"); user_alpha2[0] = '9'; user_alpha2[1] = '7'; @@ -1673,7 +1672,7 @@ static void restore_alpha2(char *alpha2, bool reset_user) * back as they were for a full restore. */ if (!is_world_regdom(ieee80211_regdom)) { - REG_DBG_PRINT("cfg80211: Keeping preference on " + REG_DBG_PRINT("Keeping preference on " "module parameter ieee80211_regdom: %c%c\n", ieee80211_regdom[0], ieee80211_regdom[1]); @@ -1681,7 +1680,7 @@ static void restore_alpha2(char *alpha2, bool reset_user) alpha2[1] = ieee80211_regdom[1]; } } else { - REG_DBG_PRINT("cfg80211: Restoring regulatory settings " + REG_DBG_PRINT("Restoring regulatory settings " "while preserving user preference for: %c%c\n", user_alpha2[0], user_alpha2[1]); @@ -1689,14 +1688,14 @@ static void restore_alpha2(char *alpha2, bool reset_user) alpha2[1] = user_alpha2[1]; } } else if (!is_world_regdom(ieee80211_regdom)) { - REG_DBG_PRINT("cfg80211: Keeping preference on " + REG_DBG_PRINT("Keeping preference on " "module parameter ieee80211_regdom: %c%c\n", ieee80211_regdom[0], ieee80211_regdom[1]); alpha2[0] = ieee80211_regdom[0]; alpha2[1] = ieee80211_regdom[1]; } else - REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n"); + REG_DBG_PRINT("Restoring regulatory settings\n"); } /* @@ -1764,7 +1763,7 @@ static void restore_regulatory_settings(bool reset_user) void regulatory_hint_disconnect(void) { - REG_DBG_PRINT("cfg80211: All devices are disconnected, going to " + REG_DBG_PRINT("All devices are disconnected, going to " "restore regulatory settings\n"); restore_regulatory_settings(false); } @@ -1794,7 +1793,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy, if (!reg_beacon) return -ENOMEM; - REG_DBG_PRINT("cfg80211: Found new beacon on " + REG_DBG_PRINT("Found new beacon on " "frequency: %d MHz (Ch %d) on %s\n", beacon_chan->center_freq, ieee80211_frequency_to_channel(beacon_chan->center_freq), -- cgit v1.2.3-59-g8ed1b From b87b0128894efd3bbf7272a579f71b3a2bc500d1 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 21 Oct 2010 12:10:11 -0700 Subject: ath: add a ATH_DBG_WARN() To be used to throw out warnings only for developers. This can be used by some corner cases that developers already know can be hit but developers want to address so to avoid spewing out a warning this can only be enabled with CONFIG_ATH_DEBUG enabled. Cc: Ben Greear Cc: Kyungwan Nam Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/debug.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index 64e4af2c2887..f207007ee391 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -70,11 +70,13 @@ enum ATH_DEBUG { #ifdef CONFIG_ATH_DEBUG void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); +#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) #else static inline void __attribute__ ((format (printf, 3, 4))) ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) { } +#define ATH_DBG_WARN(foo, arg) #endif /* CONFIG_ATH_DEBUG */ /** Returns string describing opmode, or NULL if unknown mode. */ -- cgit v1.2.3-59-g8ed1b From 78a7685e1e44c6d4b6f79c73687b9322e40b040e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 20 Oct 2010 16:07:08 -0700 Subject: ath9k: add a debug warning when we cannot stop RX We have seen several DMA races when we race against stopping and starting the PCU. I suspect that when we cannot stop the PCU we may hit some of these same races so warn against them for now but only when debugging (CONFIG_ATH_DEBUG) is enabled. If you run into this warning and are a developer, please fix the cause of the warning. The potential here, although I cannot prove yet, is that the DMA engine can be confused and start writing to a buffer that was already DMA'd before and at least the kernel assumes is not being accessed by hardware anymore. Cc: Ben Greear Cc: Kyungwan Nam Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c04a940550bd..87fabf84e6fb 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -528,6 +528,8 @@ bool ath_stoprecv(struct ath_softc *sc) sc->rx.rxlink = NULL; spin_unlock_bh(&sc->rx.rxbuflock); + ATH_DBG_WARN(!stopped, "Could not stop RX, we could be " + "confusing the DMA engine when we start RX up\n"); return stopped; } -- cgit v1.2.3-59-g8ed1b From ff32d9cd2c4107224a28f39d3c72eec66d566e09 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 21 Oct 2010 02:47:23 +0200 Subject: ath9k_hw: fix potential spurious tx error bit interpretation According to documentation, AR_ExcessiveRetries, AR_Filtered and AR_FIFOUnderrun are only valid if AR_FrmXmitOK is clear. Not checking this might result in suboptimal FIFO settings, unnecessary retransmissions, or other connectivity issues. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 3b4c52c9181c..f0268e5eab34 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -237,13 +237,15 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, status = ACCESS_ONCE(ads->ds_txstatus1); if (status & AR_FrmXmitOK) ts->ts_status |= ATH9K_TX_ACKED; - if (status & AR_ExcessiveRetries) - ts->ts_status |= ATH9K_TXERR_XRETRY; - if (status & AR_Filtered) - ts->ts_status |= ATH9K_TXERR_FILT; - if (status & AR_FIFOUnderrun) { - ts->ts_status |= ATH9K_TXERR_FIFO; - ath9k_hw_updatetxtriglevel(ah, true); + else { + if (status & AR_ExcessiveRetries) + ts->ts_status |= ATH9K_TXERR_XRETRY; + if (status & AR_Filtered) + ts->ts_status |= ATH9K_TXERR_FILT; + if (status & AR_FIFOUnderrun) { + ts->ts_status |= ATH9K_TXERR_FIFO; + ath9k_hw_updatetxtriglevel(ah, true); + } } if (status & AR_TxTimerExpired) ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; -- cgit v1.2.3-59-g8ed1b From c7317e41df30c7e04dca46360e5ebb0cb36dda45 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 21 Oct 2010 02:47:25 +0200 Subject: mac80211: minstrel_ht - reduce the overhead of rate sampling - reduce the number of retransmission attempts for sample rates - sample lower rates less often - do not use RTS/CTS for sampling frames - increase the time between sampling attempts Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2a18d6602d4a..2d6f0259e0c6 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -407,8 +407,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, mi->ampdu_len += info->status.ampdu_len; if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { - mi->sample_wait = 4 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); - mi->sample_tries = 3; + mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); + mi->sample_tries = 2; mi->sample_count--; } @@ -506,7 +506,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (!mr->retry_updated) minstrel_calc_retransmit(mp, mi, index); - if (mr->probability < MINSTREL_FRAC(20, 100)) + if (sample) + rate->count = 1; + else if (mr->probability < MINSTREL_FRAC(20, 100)) rate->count = 2; else if (rtscts) rate->count = mr->retry_count_rtscts; @@ -562,7 +564,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) */ if (minstrel_get_duration(sample_idx) > minstrel_get_duration(mi->max_tp_rate)) { - if (mr->sample_skipped < 10) + if (mr->sample_skipped < 20) goto next; if (mi->sample_slow++ > 2) @@ -586,6 +588,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_priv *mp = priv; int sample_idx; + bool sample = false; if (rate_control_send_low(sta, priv_sta, txrc)) return; @@ -596,10 +599,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, info->flags |= mi->tx_flags; sample_idx = minstrel_get_sample_rate(mp, mi); if (sample_idx >= 0) { + sample = true; minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, txrc, true, false); minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, - txrc, false, true); + txrc, false, false); info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, @@ -607,7 +611,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, txrc, false, true); } - minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, true); + minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, !sample); ar[3].count = 0; ar[3].idx = -1; -- cgit v1.2.3-59-g8ed1b From 4beeba7dc59cc10d6a47346c857d1a64a9ec9642 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 25 Oct 2010 10:34:50 +0200 Subject: iwlwifi: warn when send tx power settings during scan Add WARN_ONCE when scanning is pending. Use STATUS_SCAN_HW bit since we can have scan canceled or completed but STATUS_SCANNING bit still set. v1 -> v2: replace EIO to EAGAIN Signed-off-by: Stanislaw Gruszka Acked-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-4965.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 176e52577673..4d7130c9b72c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1451,6 +1451,10 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv) }; u16 chan; + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b207e3e9299f..ee9c582c8cf2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1377,13 +1377,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) u8 ctrl_chan_high = 0; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (test_bit(STATUS_SCANNING, &priv->status)) { - /* If this gets hit a lot, switch it to a BUG() and catch - * the stack trace to find out who is calling this during - * a scan. */ - IWL_WARN(priv, "TX Power requested while scanning!\n"); + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) return -EAGAIN; - } band = priv->band == IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b555edd53354..5e3d799ea3b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -496,6 +496,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) struct iwlagn_tx_power_dbm_cmd tx_power_cmd; u8 tx_ant_cfg_cmd; + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + /* half dBm need to multiply */ tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); -- cgit v1.2.3-59-g8ed1b From 4cbf1b12491cd43032846acc6c6924d9090fa19f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:25 +0200 Subject: iwlwifi: send tx_power_cmd synchronously On 5xxx and 6xxx change to send tx_power_cmd command synchronously, to do not start other commands when setting tx power is pending. We currently do the same for 4956 and 3945. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 5e3d799ea3b5..c38daf2d9cfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -526,9 +526,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; - return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd, - sizeof(tx_power_cmd), &tx_power_cmd, - NULL); + return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd), + &tx_power_cmd); } void iwlagn_temperature(struct iwl_priv *priv) -- cgit v1.2.3-59-g8ed1b From a25a66ac94db88190653d5725c563e3f8faeee61 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:26 +0200 Subject: iwlwifi: fix set_tx_power vs scan According to comment in iwl_bg_scan_completed, setting tx power should be deferred during pending scan, but we are not doing this. This patch change code to really defer setting tx power after scan complete. Additionally refactor iwl_set_tx_power code and call lib->send_tx_power() directly from iwlagn_commit_rxon. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++--- drivers/net/wireless/iwlwifi/iwl-core.c | 54 ++++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 10 +++--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c2636a7ab9ee..d3435c430273 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -245,13 +245,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); - if (ret) { + ret = priv->cfg->ops->lib->send_tx_power(priv); + if (ret) IWL_ERR(priv, "Error sending TX power (%d)\n", ret); - return ret; - } - - return 0; + return ret; } void iwl_update_chain_flags(struct iwl_priv *priv) @@ -4179,6 +4176,7 @@ static int iwl_init_drv(struct iwl_priv *priv) * this value will get overwritten by channel max power avg * from eeprom */ priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN; + priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN; ret = iwl_init_channel_map(priv); if (ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 25fb3912342c..8bbd152617fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1206,8 +1206,16 @@ EXPORT_SYMBOL(iwl_apm_init); int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { - int ret = 0; - s8 prev_tx_power = priv->tx_power_user_lmt; + int ret; + s8 prev_tx_power; + + lockdep_assert_held(&priv->mutex); + + if (priv->tx_power_user_lmt == tx_power && !force) + return 0; + + if (!priv->cfg->ops->lib->send_tx_power) + return -EOPNOTSUPP; if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { IWL_WARN(priv, @@ -1224,30 +1232,26 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) return -EINVAL; } - if (priv->tx_power_user_lmt != tx_power) - force = true; + if (!iwl_is_ready_rf(priv)) + return -EIO; - /* if nic is not up don't send command */ - if (iwl_is_ready_rf(priv)) { - priv->tx_power_user_lmt = tx_power; - if (force && priv->cfg->ops->lib->send_tx_power) - ret = priv->cfg->ops->lib->send_tx_power(priv); - else if (!priv->cfg->ops->lib->send_tx_power) - ret = -EOPNOTSUPP; - /* - * if fail to set tx_power, restore the orig. tx power - */ - if (ret) - priv->tx_power_user_lmt = prev_tx_power; + /* scan complete use tx_power_next, need to be updated */ + priv->tx_power_next = tx_power; + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { + IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n"); + return 0; } - /* - * Even this is an async host command, the command - * will always report success from uCode - * So once driver can placing the command into the queue - * successfully, driver can use priv->tx_power_user_lmt - * to reflect the current tx power - */ + prev_tx_power = priv->tx_power_user_lmt; + priv->tx_power_user_lmt = tx_power; + + ret = priv->cfg->ops->lib->send_tx_power(priv); + + /* if fail to set tx_power, restore the orig. tx power */ + if (ret) { + priv->tx_power_user_lmt = prev_tx_power; + priv->tx_power_next = prev_tx_power; + } return ret; } EXPORT_SYMBOL(iwl_set_tx_power); @@ -2016,7 +2020,9 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", priv->tx_power_user_lmt, conf->power_level); - iwl_set_tx_power(priv, conf->power_level, false); + ret = iwl_set_tx_power(priv, conf->power_level, false); + if (ret) + IWL_ERR(priv, "Error sending TX power (%d)\n", ret); } if (!iwl_is_ready(priv)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 70e07fa48405..cd6daed99931 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1517,6 +1517,7 @@ struct iwl_priv { s8 tx_power_user_lmt; s8 tx_power_device_lmt; s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ + s8 tx_power_next; #ifdef CONFIG_IWLWIFI_DEBUG diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 67da31295781..d63e30e1106a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -603,13 +603,15 @@ out_settings: if (!iwl_is_ready_rf(priv)) goto out; - /* Since setting the TXPOWER may have been deferred while - * performing the scan, fire one off */ - iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + /* + * We do not commit power settings while scan is pending, + * do it now if the settings changed. + */ + iwl_set_tx_power(priv, priv->tx_power_next, false); priv->cfg->ops->utils->post_scan(priv); - out: +out: mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8f8c4b73f8b9..a75429171c46 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3866,6 +3866,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; + priv->tx_power_next = IWL_DEFAULT_TX_POWER; if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", -- cgit v1.2.3-59-g8ed1b From 749ff4efa14df904c22b28e2f7b10a02119a4d5e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:27 +0200 Subject: iwlwifi: avoid commit rxon during scan in iwlagn_configure_filter Almost anywhere in the code we avoid committing rxon while performing scan, and make rxon commit when scan complete. However in some places in the code we do not follow that rule. This patch fix that problem in iwlagn_configure_filter(). Since we do not commit directly in iwl3945_configure_filter, we can also do the same for agn, so I just remove iwlcore_commit_rxon() function and add a comment. Also change comment for iwl3945. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++++- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d3435c430273..0ba8083ee4cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3983,7 +3983,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, for_each_context(priv, ctx) { ctx->staging.filter_flags &= ~filter_nand; ctx->staging.filter_flags |= filter_or; - iwlcore_commit_rxon(priv, ctx); + + /* + * Not committing directly because hardware can perform a scan, + * but we'll eventually commit the filter flags change anyway. + */ } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a75429171c46..3b8bf8686276 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3407,9 +3407,9 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, ctx->staging.filter_flags |= filter_or; /* - * Committing directly here breaks for some reason, - * but we'll eventually commit the filter flags - * change anyway. + * Not committing directly because hardware can perform a scan, + * but even if hw is ready, committing here breaks for some reason, + * we'll eventually commit the filter flags change anyway. */ mutex_unlock(&priv->mutex); -- cgit v1.2.3-59-g8ed1b From 5eda74a40587139b1d66cd8197cac92ba36e79f4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:28 +0200 Subject: iwlwifi: avoid commit rxon during scan in iwlagn_bt_traffic_change_work Avoid sending commands to firmware (including commit_rxon) when scan is pending and we are calling iwlagn_bt_traffic_change_work simultaneously. Also comment some innocent race conditions. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c38daf2d9cfd..b01d81a3550b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1887,6 +1887,11 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) struct iwl_rxon_context *ctx; int smps_request = -1; + /* + * Note: bt_traffic_load can be overridden by scan complete and + * coex profile notifications. Ignore that since only bad consequence + * can be not matching debug print with actual state. + */ IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", priv->bt_traffic_load); @@ -1909,6 +1914,16 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) mutex_lock(&priv->mutex); + /* + * We can not send command to firmware while scanning. When the scan + * complete we will schedule this work again. We do check with mutex + * locked to prevent new scan request to arrive. We do not check + * STATUS_SCANNING to avoid race when queue_work two times from + * different notifications, but quit and not perform any work at all. + */ + if (test_bit(STATUS_SCAN_HW, &priv->status)) + goto out; + if (priv->cfg->ops->lib->update_chain_flags) priv->cfg->ops->lib->update_chain_flags(priv); @@ -1918,7 +1933,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) ieee80211_request_smps(ctx->vif, smps_request); } } - +out: mutex_unlock(&priv->mutex); } -- cgit v1.2.3-59-g8ed1b From ac4f5457c7617999967e9740f8903b922714bab4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:29 +0200 Subject: iwlwifi: defer update power mode while scan Do not set power mode when scanning, and defer that when scan finish. We still set power mode in force case i.e. when device is overheated. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-power.c | 95 ++++++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-power.h | 3 + drivers/net/wireless/iwlwifi/iwl-scan.c | 1 + 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 49d7788937a9..b7abd86676fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -263,70 +263,95 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) sizeof(struct iwl_powertable_cmd), cmd); } -/* priv->mutex must be held */ -int iwl_power_update_mode(struct iwl_priv *priv, bool force) +static void iwl_power_build_cmd(struct iwl_priv *priv, + struct iwl_powertable_cmd *cmd) { - int ret = 0; bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; - bool update_chains; - struct iwl_powertable_cmd cmd; int dtimper; - /* Don't update the RX chain when chain noise calibration is running */ - update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || - priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; - dtimper = priv->hw->conf.ps_dtim_period ?: 1; if (priv->cfg->base_params->broken_powersave) - iwl_power_sleep_cam_cmd(priv, &cmd); + iwl_power_sleep_cam_cmd(priv, cmd); else if (priv->cfg->base_params->supports_idle && priv->hw->conf.flags & IEEE80211_CONF_IDLE) - iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); + iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && priv->cfg->ops->lib->tt_ops.tt_power_mode && priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { /* in thermal throttling low power state */ - iwl_static_sleep_cmd(priv, &cmd, + iwl_static_sleep_cmd(priv, cmd, priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); } else if (!enabled) - iwl_power_sleep_cam_cmd(priv, &cmd); + iwl_power_sleep_cam_cmd(priv, cmd); else if (priv->power_data.debug_sleep_level_override >= 0) - iwl_static_sleep_cmd(priv, &cmd, + iwl_static_sleep_cmd(priv, cmd, priv->power_data.debug_sleep_level_override, dtimper); else if (no_sleep_autoadjust) - iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper); + iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); else - iwl_power_fill_sleep_cmd(priv, &cmd, + iwl_power_fill_sleep_cmd(priv, cmd, priv->hw->conf.dynamic_ps_timeout, priv->hw->conf.max_sleep_period); +} + +int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, + bool force) +{ + int ret; + bool update_chains; + + lockdep_assert_held(&priv->mutex); + + /* Don't update the RX chain when chain noise calibration is running */ + update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || + priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; + + if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) + return 0; + + if (!iwl_is_ready_rf(priv)) + return -EIO; + + /* scan complete use sleep_power_next, need to be updated */ + memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { + IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); + return 0; + } + + if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK) + set_bit(STATUS_POWER_PMI, &priv->status); - if (iwl_is_ready_rf(priv) && - (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) { - if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK) - set_bit(STATUS_POWER_PMI, &priv->status); - - ret = iwl_set_power(priv, &cmd); - if (!ret) { - if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) - clear_bit(STATUS_POWER_PMI, &priv->status); - - if (priv->cfg->ops->lib->update_chain_flags && - update_chains) - priv->cfg->ops->lib->update_chain_flags(priv); - else if (priv->cfg->ops->lib->update_chain_flags) - IWL_DEBUG_POWER(priv, + ret = iwl_set_power(priv, cmd); + if (!ret) { + if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) + clear_bit(STATUS_POWER_PMI, &priv->status); + + if (priv->cfg->ops->lib->update_chain_flags && update_chains) + priv->cfg->ops->lib->update_chain_flags(priv); + else if (priv->cfg->ops->lib->update_chain_flags) + IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise " "calibration running: %d\n", priv->chain_noise_data.state); - memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)); - } else - IWL_ERR(priv, "set power fail, ret = %d", ret); - } + + memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)); + } else + IWL_ERR(priv, "set power fail, ret = %d", ret); return ret; } +EXPORT_SYMBOL(iwl_power_set_mode); + +int iwl_power_update_mode(struct iwl_priv *priv, bool force) +{ + struct iwl_powertable_cmd cmd; + + iwl_power_build_cmd(priv, &cmd); + return iwl_power_set_mode(priv, &cmd, force); +} EXPORT_SYMBOL(iwl_power_update_mode); /* initialize to default */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index df81565a7cc4..fe012032c28c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -41,10 +41,13 @@ enum iwl_power_level { struct iwl_power_mgr { struct iwl_powertable_cmd sleep_cmd; + struct iwl_powertable_cmd sleep_cmd_next; int debug_sleep_level_override; bool pci_pm; }; +int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, + bool force); int iwl_power_update_mode(struct iwl_priv *priv, bool force); void iwl_power_initialize(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index d63e30e1106a..e1aa0e1daa5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -607,6 +607,7 @@ out_settings: * We do not commit power settings while scan is pending, * do it now if the settings changed. */ + iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); iwl_set_tx_power(priv, priv->tx_power_next, false); priv->cfg->ops->utils->post_scan(priv); -- cgit v1.2.3-59-g8ed1b From 3eb9616af24d6a1910ae6ae5c2d51719eba960cf Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 22 Oct 2010 17:04:30 +0200 Subject: iwlwifi: avoid commit rxon during scan in iwl_set_no_assoc Currently we are canceling scan when changing BSSID. Behave the same when changing association and beacon enablement, to avoid committing rxon during scan in iwl_set_no_assoc(). Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8bbd152617fc..87c18001d2c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1590,6 +1590,19 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (changes & (BSS_CHANGED_BSSID | BSS_CHANGED_ASSOC | + BSS_CHANGED_BEACON_ENABLED)) { + /* + * If there is currently a HW scan going on in the + * background then we need to cancel it else the RXON + * below in post_associate or set_no_assoc can fail. + */ + if (iwl_scan_cancel_timeout(priv, 200)) { + IWL_WARN(priv, "Can not cancel scan\n"); + goto out; + } + } + if (changes & BSS_CHANGED_QOS) { unsigned long flags; @@ -1622,18 +1635,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_BSSID) { IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); - /* - * If there is currently a HW scan going on in the - * background then we need to cancel it else the RXON - * below/in post_associate will fail. - */ - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - mutex_unlock(&priv->mutex); - return; - } - /* mac80211 only sets assoc when in STATION mode */ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { memcpy(ctx->staging.bssid_addr, @@ -1752,6 +1753,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, IWL_ERR(priv, "failed to update PAN params\n"); } +out: mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); -- cgit v1.2.3-59-g8ed1b From c0b102c20972cfa3e10a0cf4a2a563edb70961b1 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 22 Oct 2010 17:43:46 +0200 Subject: b43: N-PHY: fix 2055 radio init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2055.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c index 1b5316586cbf..0d6771515bce 100644 --- a/drivers/net/wireless/b43/radio_2055.c +++ b/drivers/net/wireless/b43/radio_2055.c @@ -244,7 +244,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = { [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCE] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, @@ -256,7 +256,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = { [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDA] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, @@ -1299,7 +1299,7 @@ void b2055_upload_inittab(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag) { const struct b2055_inittab_entry *e; - unsigned int i; + unsigned int i, writes = 0; u16 value; for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { @@ -1312,6 +1312,8 @@ void b2055_upload_inittab(struct b43_wldev *dev, else value = e->ghz2; b43_radio_write16(dev, i, value); + if (++writes % 4 == 0) + b43_read32(dev, B43_MMIO_MACCTL); /* flush */ } } } -- cgit v1.2.3-59-g8ed1b From 7e6da2bfc05c2b96197c12484f3d071fe0c6d0fb Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 22 Oct 2010 17:43:47 +0200 Subject: b43: define known SPROM boardflags2 bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 72821c456b02..9aad2ca3c112 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -153,6 +153,19 @@ #define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna * with bluetooth */ +/* SPROM boardflags2_lo values */ +#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */ +#define B43_BFL2_APLL_WAR 0x0002 /* alternative A-band PLL settings implemented */ +#define B43_BFL2_TXPWRCTRL_EN 0x0004 /* permits enabling TX Power Control */ +#define B43_BFL2_2X4_DIV 0x0008 /* 2x4 diversity switch */ +#define B43_BFL2_5G_PWRGAIN 0x0010 /* supports 5G band power gain */ +#define B43_BFL2_PCIEWAR_OVR 0x0020 /* overrides ASPM and Clkreq settings */ +#define B43_BFL2_CAESERS_BRD 0x0040 /* is Caesers board (unused) */ +#define B43_BFL2_BTC3WIRE 0x0080 /* used 3-wire bluetooth coexist */ +#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */ +#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */ +#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */ + /* GPIO register offset, in both ChipCommon and PCI core. */ #define B43_GPIO_CONTROL 0x6c -- cgit v1.2.3-59-g8ed1b From 7a4db8f5c37d1acf1213b835b3cdd8f7c051eb9b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 22 Oct 2010 17:43:48 +0200 Subject: b43: N-PHY: determine usage of radio regulatory workaround correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e0f2d122e124..c22dbfb987de 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -191,7 +191,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) binfo->type != 0x46D || binfo->rev < 0x41); else - workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0); + workaround = + !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); if (workaround) { -- cgit v1.2.3-59-g8ed1b From a2d9bc6fdc0c8693b5641c69bce7eaf5b47f0593 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 22 Oct 2010 17:43:49 +0200 Subject: b43: N-PHY: improve 2055 radio initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) Upload 5 GHz values when needed. 2) Do not upload all values on first init. Follow wl. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index c22dbfb987de..6facb8ab05d1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -241,10 +241,13 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) static void b43_radio_init2055(struct b43_wldev *dev) { b43_radio_init2055_pre(dev); - if (b43_status(dev) < B43_STAT_INITIALIZED) - b2055_upload_inittab(dev, 0, 1); - else - b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0); + if (b43_status(dev) < B43_STAT_INITIALIZED) { + /* Follow wl, not specs. Do not force uploading all regs */ + b2055_upload_inittab(dev, 0, 0); + } else { + bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ; + b2055_upload_inittab(dev, ghz5, 0); + } b43_radio_init2055_post(dev); } -- cgit v1.2.3-59-g8ed1b From 8e7ce8930165c785ec1c754ef3e3092a3bdffe02 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 23 Oct 2010 19:51:32 +0200 Subject: carl9170: fix typos Signed-off-by: Hauke Mehrtens Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 2 +- drivers/net/wireless/ath/carl9170/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 6cf0c9ef47aa..b69d31972c77 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -48,7 +48,7 @@ #include #ifdef CONFIG_CARL9170_LEDS #include -#endif /* CONFIG_CARL170_LEDS */ +#endif /* CONFIG_CARL9170_LEDS */ #ifdef CONFIG_CARL9170_WPC #include #endif /* CONFIG_CARL9170_WPC */ diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 980ae70ea424..d521bc2b0496 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1828,7 +1828,7 @@ int carl9170_register(struct ar9170 *ar) err = carl9170_led_register(ar); if (err) goto err_unreg; -#endif /* CONFIG_CAR9L170_LEDS */ +#endif /* CONFIG_CARL9170_LEDS */ #ifdef CONFIG_CARL9170_WPC err = carl9170_register_wps_button(ar); -- cgit v1.2.3-59-g8ed1b From 26f94dc264a7ebddcc08d3908e99880703d871e5 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 25 Oct 2010 10:24:09 -0400 Subject: b43: remove extraneous code in free_ringmemory This code seems to have been cut-n-pasted from alloc_ringmemory? Anyway, it is useless. Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 10d0aaf754c5..3d5566e7af0a 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -415,11 +415,6 @@ static int alloc_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring) { - gfp_t flags = GFP_KERNEL; - - if (ring->type == B43_DMA_64BIT) - flags |= GFP_DMA; - dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase, ring->dmabase); } -- cgit v1.2.3-59-g8ed1b From b9237578f8d685bb86901ba9ff0d379218e5a3c5 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 25 Oct 2010 10:33:07 -0400 Subject: rt2x00pci: do not use GFP_DMA Signed-off-by: John W. Linville Acked-by: Ivo van Doorn --- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2449d785cf8d..868ca19b13ea 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -105,7 +105,7 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, */ addr = dma_alloc_coherent(rt2x00dev->dev, queue->limit * queue->desc_size, - &dma, GFP_KERNEL | GFP_DMA); + &dma, GFP_KERNEL); if (!addr) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From f60dc0138aa19769bf8bab9f93b043235428b66f Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 25 Oct 2010 16:12:37 -0400 Subject: iwlwifi: Convert to new PCI PM framework Use the new PCI PM and let the PCI core code handle the PCI-specific details of power transitions. Based on similarly titled ath9k patch posted by Rafael J. Wysocki. Signed-off-by: John W. Linville Acked-by: Rafael J. Wysocki Acked-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-core.c | 26 ++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-core.h | 14 +++++++++++--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 +---- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0ba8083ee4cd..0027bb8299a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4838,10 +4838,7 @@ static struct pci_driver iwl_driver = { .id_table = iwl_hw_card_ids, .probe = iwl_pci_probe, .remove = __devexit_p(iwl_pci_remove), -#ifdef CONFIG_PM - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, -#endif + .driver.pm = IWL_PM_OPS, }; static int __init iwl_init(void) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 87c18001d2c0..2a4d40e5b9f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2592,8 +2592,9 @@ EXPORT_SYMBOL(iwl_add_beacon_time); #ifdef CONFIG_PM -int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) +int iwl_pci_suspend(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct iwl_priv *priv = pci_get_drvdata(pdev); /* @@ -2605,18 +2606,14 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) */ iwl_apm_stop(priv); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - return 0; } EXPORT_SYMBOL(iwl_pci_suspend); -int iwl_pci_resume(struct pci_dev *pdev) +int iwl_pci_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct iwl_priv *priv = pci_get_drvdata(pdev); - int ret; bool hw_rfkill = false; /* @@ -2625,11 +2622,6 @@ int iwl_pci_resume(struct pci_dev *pdev) */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_device(pdev); - if (ret) - return ret; - pci_restore_state(pdev); iwl_enable_interrupts(priv); if (!(iwl_read32(priv, CSR_GP_CNTRL) & @@ -2647,4 +2639,14 @@ int iwl_pci_resume(struct pci_dev *pdev) } EXPORT_SYMBOL(iwl_pci_resume); +const struct dev_pm_ops iwl_pm_ops = { + .suspend = iwl_pci_suspend, + .resume = iwl_pci_resume, + .freeze = iwl_pci_suspend, + .thaw = iwl_pci_resume, + .poweroff = iwl_pci_suspend, + .restore = iwl_pci_resume, +}; +EXPORT_SYMBOL(iwl_pm_ops); + #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 64527def059f..b17de8214eb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -615,9 +615,17 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval); #ifdef CONFIG_PM -int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); -int iwl_pci_resume(struct pci_dev *pdev); -#endif /* CONFIG_PM */ +int iwl_pci_suspend(struct device *device); +int iwl_pci_resume(struct device *device); +extern const struct dev_pm_ops iwl_pm_ops; + +#define IWL_PM_OPS (&iwl_pm_ops) + +#else /* !CONFIG_PM */ + +#define IWL_PM_OPS NULL + +#endif /* !CONFIG_PM */ /***************************************************** * Error Handling Debugging diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3b8bf8686276..9b71921dc2b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4275,10 +4275,7 @@ static struct pci_driver iwl3945_driver = { .id_table = iwl3945_hw_card_ids, .probe = iwl3945_pci_probe, .remove = __devexit_p(iwl3945_pci_remove), -#ifdef CONFIG_PM - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, -#endif + .driver.pm = IWL_PM_OPS, }; static int __init iwl3945_init(void) -- cgit v1.2.3-59-g8ed1b From 446fad5a5b6be765c8ec39bfdbbc6c7aa63fbcbb Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 26 Oct 2010 20:11:29 +0530 Subject: ath9k_htc: Handle monitor mode properly for HTC devices No need to inform about monitor interface changes to firmware. Set the HW mode to monitor type based on mac80211 indication flag is sufficient. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 64 +++------------------------ 1 file changed, 5 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8266ce1f02e3..e9761c2c8700 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -184,47 +184,6 @@ err: return ret; } -static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) -{ - struct ath_common *common = ath9k_hw_common(priv->ah); - struct ath9k_htc_target_vif hvif; - int ret = 0; - u8 cmd_rsp; - - if (priv->nvifs > 0) - return -ENOBUFS; - - memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); - memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - - hvif.opmode = cpu_to_be32(HTC_M_MONITOR); - priv->ah->opmode = NL80211_IFTYPE_MONITOR; - hvif.index = priv->nvifs; - - WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); - if (ret) - return ret; - - priv->nvifs++; - return 0; -} - -static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) -{ - struct ath_common *common = ath9k_hw_common(priv->ah); - struct ath9k_htc_target_vif hvif; - int ret = 0; - u8 cmd_rsp; - - memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); - memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - hvif.index = 0; /* Should do for now */ - WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); - priv->nvifs--; - - return ret; -} - static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -1240,16 +1199,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) WMI_CMD(WMI_STOP_RECV_CMDID); skb_queue_purge(&priv->tx_queue); - /* Remove monitor interface here */ - if (ah->opmode == NL80211_IFTYPE_MONITOR) { - if (ath9k_htc_remove_monitor_interface(priv)) - ath_print(common, ATH_DBG_FATAL, - "Unable to remove monitor interface\n"); - else - ath_print(common, ATH_DBG_CONFIG, - "Monitor interface removed\n"); - } - if (ah->btcoex_hw.enabled) { ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) @@ -1423,16 +1372,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } - if (changed & IEEE80211_CONF_CHANGE_MONITOR) { + if (changed & IEEE80211_CONF_CHANGE_MONITOR) if (conf->flags & IEEE80211_CONF_MONITOR) { - if (ath9k_htc_add_monitor_interface(priv)) - ath_print(common, ATH_DBG_FATAL, - "Failed to set monitor mode\n"); - else - ath_print(common, ATH_DBG_CONFIG, - "HW opmode set to Monitor mode\n"); + ath_print(common, ATH_DBG_CONFIG, + "HW opmode set to Monitor mode\n"); + priv->ah->opmode = NL80211_IFTYPE_MONITOR; } - } + if (changed & IEEE80211_CONF_CHANGE_IDLE) { mutex_lock(&priv->htc_pm_lock); -- cgit v1.2.3-59-g8ed1b From 5d4c428254f73bae272be9d296724b1ee09d76ec Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 26 Oct 2010 21:28:57 +0530 Subject: ath9k: Properly assign boolean types This takes care that boolean types are properly assigned Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 1095e18b3627..85c8e9310cae 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1425,12 +1425,12 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, ath_rc_priv->neg_ht_rates.rs_nrates = j; } - is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; + is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); if (is_cw40) - is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) - is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); /* Choose rate table first */ @@ -1449,10 +1449,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, struct ath_rate_priv *ath_rc_priv = priv_sta; const struct ath_rate_table *rate_table = NULL; bool oper_cw40 = false, oper_sgi; - bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? - true : false; - bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? - true : false; + bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG); + bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG); /* FIXME: Handle AP mode later when we support CWM */ -- cgit v1.2.3-59-g8ed1b From 9d94674ab754be0e275120a183670ead435f9c0d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 26 Oct 2010 15:27:23 -0700 Subject: ath9k: simplify hw reset locking The new PCU lock is better placed so we can just contend against that when trying to reset hardware. This is part of a series of patches which fix stopping TX DMA completley when requested on the driver. For more details about this issue refer to this thread: http://marc.info/?l=linux-wireless&m=128629803703756&w=2 Tested-by: Ben Greear Cc: Kyungwan Nam Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 1 - drivers/net/wireless/ath/ath9k/main.c | 22 ++++++---------------- drivers/net/wireless/ath/ath9k/xmit.c | 4 ++-- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 81fed83add7a..cb9194a5b561 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -599,7 +599,6 @@ struct ath_softc { struct ath_hw *sc_ah; void __iomem *mem; int irq; - spinlock_t sc_resetlock; spinlock_t sc_serial_rw; spinlock_t sc_pm_lock; struct mutex mutex; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1b72720b36e2..adff0da01f4c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -580,7 +580,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, spin_lock_init(&common->cc_lock); spin_lock_init(&sc->wiphy_lock); - spin_lock_init(&sc->sc_resetlock); spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 92ed5bb71196..341d587b686b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -262,19 +262,15 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, channel->center_freq, conf_is_ht40(conf), fastcc); - spin_lock_bh(&sc->sc_resetlock); - r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { ath_print(common, ATH_DBG_FATAL, "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); - spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->rx.pcu_lock); goto ps_restore; } - spin_unlock_bh(&sc->sc_resetlock); if (ath_startrecv(sc) != 0) { ath_print(common, ATH_DBG_FATAL, @@ -886,7 +882,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ah->curchan = ath_get_curchannel(sc, sc->hw); spin_lock_bh(&sc->rx.pcu_lock); - spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { ath_print(common, ATH_DBG_FATAL, @@ -894,7 +889,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) "reset status %d\n", channel->center_freq, r); } - spin_unlock_bh(&sc->sc_resetlock); ath_update_txpow(sc); if (ath_startrecv(sc) != 0) { @@ -951,7 +945,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) if (!ah->curchan) ah->curchan = ath_get_curchannel(sc, hw); - spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, @@ -959,7 +952,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) "reset status %d\n", channel->center_freq, r); } - spin_unlock_bh(&sc->sc_resetlock); ath9k_hw_phy_disable(ah); @@ -990,12 +982,10 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath_stoprecv(sc); ath_flushrecv(sc); - spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d\n", r); - spin_unlock_bh(&sc->sc_resetlock); if (ath_startrecv(sc) != 0) ath_print(common, ATH_DBG_FATAL, @@ -1166,18 +1156,15 @@ static int ath9k_start(struct ieee80211_hw *hw) * and then setup of the interrupt mask. */ spin_lock_bh(&sc->rx.pcu_lock); - spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d " "(freq %u MHz)\n", r, curchan->center_freq); - spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->rx.pcu_lock); goto mutex_unlock; } - spin_unlock_bh(&sc->sc_resetlock); /* * This is needed only to setup initial state @@ -1398,14 +1385,17 @@ static void ath9k_stop(struct ieee80211_hw *hw) * before setting the invalid flag. */ ath9k_hw_disable_interrupts(ah); - spin_lock_bh(&sc->rx.pcu_lock); if (!(sc->sc_flags & SC_OP_INVALID)) { ath_drain_all_txq(sc, false); + spin_lock_bh(&sc->rx.pcu_lock); ath_stoprecv(sc); ath9k_hw_phy_disable(ah); - } else + spin_unlock_bh(&sc->rx.pcu_lock); + } else { + spin_lock_bh(&sc->rx.pcu_lock); sc->rx.rxlink = NULL; - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->rx.pcu_lock); + } /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce2..e662ecade398 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1148,13 +1148,13 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA. Resetting hardware!\n"); - spin_lock_bh(&sc->sc_resetlock); + spin_lock_bh(&sc->rx.pcu_lock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d\n", r); - spin_unlock_bh(&sc->sc_resetlock); + spin_unlock_bh(&sc->rx.pcu_lock); } for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { -- cgit v1.2.3-59-g8ed1b From 4bdd1e978ede034c1211957eb17eaf50de00d234 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 26 Oct 2010 15:27:24 -0700 Subject: ath9k: move the PCU lock to the sc structure The PCU lock should be used to contend TX DMA as well, this will be done next. This is part of a series of patches which fix stopping TX DMA completley when requested on the driver. For more details about this issue refer to this thread: http://marc.info/?l=linux-wireless&m=128629803703756&w=2 Tested-by: Ben Greear Cc: Kyungwan Nam Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 42 +++++++++++++++++----------------- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 4 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index cb9194a5b561..61d450750acb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -309,7 +309,6 @@ struct ath_rx { u8 rxotherant; u32 *rxlink; unsigned int rxfilter; - spinlock_t pcu_lock; spinlock_t rxbuflock; struct list_head rxbuf; struct ath_descdma rxdma; @@ -601,6 +600,7 @@ struct ath_softc { int irq; spinlock_t sc_serial_rw; spinlock_t sc_pm_lock; + spinlock_t sc_pcu_lock; struct mutex mutex; struct work_struct paprd_work; struct work_struct hw_check_work; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 341d587b686b..463ac1229f53 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -242,7 +242,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, false); - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); stopped = ath_stoprecv(sc); @@ -268,7 +268,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); goto ps_restore; } @@ -276,11 +276,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_print(common, ATH_DBG_FATAL, "Unable to restart recv logic\n"); r = -EIO; - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); goto ps_restore; } - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); @@ -615,7 +615,7 @@ void ath9k_tasklet(unsigned long data) rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); if (status & rxmask) { - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); /* Check for high priority Rx first */ if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && @@ -623,7 +623,7 @@ void ath9k_tasklet(unsigned long data) ath_rx_tasklet(sc, 0, true); ath_rx_tasklet(sc, 0, false); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); } if (status & ATH9K_INT_TX) { @@ -881,7 +881,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) if (!ah->curchan) ah->curchan = ath_get_curchannel(sc, sc->hw); - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { ath_print(common, ATH_DBG_FATAL, @@ -894,10 +894,10 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) if (ath_startrecv(sc) != 0) { ath_print(common, ATH_DBG_FATAL, "Unable to restart recv logic\n"); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); return; } - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); /* restart beacons */ @@ -937,7 +937,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath_drain_all_txq(sc, false); /* clear pending tx frames */ - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); ath_stoprecv(sc); /* turn off frame recv */ ath_flushrecv(sc); /* flush recv queue */ @@ -955,7 +955,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_phy_disable(ah); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_hw_configpcipowersave(ah, 1, 1); ath9k_ps_restore(sc); @@ -977,7 +977,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, retry_tx); - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); ath_stoprecv(sc); ath_flushrecv(sc); @@ -991,7 +991,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Unable to start recv logic\n"); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); /* * We may be doing a reset in response to a request @@ -1155,14 +1155,14 @@ static int ath9k_start(struct ieee80211_hw *hw) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d " "(freq %u MHz)\n", r, curchan->center_freq); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); goto mutex_unlock; } @@ -1183,10 +1183,10 @@ static int ath9k_start(struct ieee80211_hw *hw) ath_print(common, ATH_DBG_FATAL, "Unable to start recv logic\n"); r = -EIO; - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); goto mutex_unlock; } - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); /* Setup our intr mask. */ ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | @@ -1387,14 +1387,14 @@ static void ath9k_stop(struct ieee80211_hw *hw) if (!(sc->sc_flags & SC_OP_INVALID)) { ath_drain_all_txq(sc, false); - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); ath_stoprecv(sc); ath9k_hw_phy_disable(ah); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); } else { - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); sc->rx.rxlink = NULL; - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); } /* disable HAL and put h/w to sleep */ diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 87fabf84e6fb..60300b225b6d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -317,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) struct ath_buf *bf; int error = 0; - spin_lock_init(&sc->rx.pcu_lock); + spin_lock_init(&sc->sc_pcu_lock); sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->rx.rxbuflock); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e662ecade398..d97b7a336b5b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1148,13 +1148,13 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA. Resetting hardware!\n"); - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d\n", r); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->sc_pcu_lock); } for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { -- cgit v1.2.3-59-g8ed1b From 6a6733f256f18cbcf4875e13f59eedb593b755a8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 26 Oct 2010 15:27:25 -0700 Subject: ath9k: content DMA start / stop through the PCU lock This helps align resets / RX enable & disable / TX stop / start. Locking around the PCU is important to ensure the hardware doesn't get stale data when working with DMA'able data. This is part of a series of patches which fix stopping TX DMA completley when requested on the driver. For more details about this issue refer to this thread: http://marc.info/?l=linux-wireless&m=128629803703756&w=2 Tested-by: Ben Greear Cc: Kyungwan Nam Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 52 +++++++++++++++++------------------ drivers/net/wireless/ath/ath9k/xmit.c | 2 -- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 463ac1229f53..d522112cf736 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -230,6 +230,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath9k_ps_wakeup(sc); + spin_lock_bh(&sc->sc_pcu_lock); + /* * This is only performed if the channel settings have * actually changed. @@ -242,8 +244,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, false); - spin_lock_bh(&sc->sc_pcu_lock); - stopped = ath_stoprecv(sc); /* XXX: do not flush receive queue here. We don't want @@ -268,7 +268,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); - spin_unlock_bh(&sc->sc_pcu_lock); goto ps_restore; } @@ -276,12 +275,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_print(common, ATH_DBG_FATAL, "Unable to restart recv logic\n"); r = -EIO; - spin_unlock_bh(&sc->sc_pcu_lock); goto ps_restore; } - spin_unlock_bh(&sc->sc_pcu_lock); - ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); @@ -292,6 +288,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, } ps_restore: + spin_unlock_bh(&sc->sc_pcu_lock); + ath9k_ps_restore(sc); return r; } @@ -605,6 +603,8 @@ void ath9k_tasklet(unsigned long data) return; } + spin_lock_bh(&sc->sc_pcu_lock); + if (!ath9k_hw_check_alive(ah)) ieee80211_queue_work(sc->hw, &sc->hw_check_work); @@ -615,15 +615,12 @@ void ath9k_tasklet(unsigned long data) rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); if (status & rxmask) { - spin_lock_bh(&sc->sc_pcu_lock); - /* Check for high priority Rx first */ if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && (status & ATH9K_INT_RXHP)) ath_rx_tasklet(sc, 0, true); ath_rx_tasklet(sc, 0, false); - spin_unlock_bh(&sc->sc_pcu_lock); } if (status & ATH9K_INT_TX) { @@ -649,6 +646,8 @@ void ath9k_tasklet(unsigned long data) /* re-enable hardware interrupt */ ath9k_hw_enable_interrupts(ah); + + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); } @@ -876,12 +875,13 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) int r; ath9k_ps_wakeup(sc); + spin_lock_bh(&sc->sc_pcu_lock); + ath9k_hw_configpcipowersave(ah, 0, 0); if (!ah->curchan) ah->curchan = ath_get_curchannel(sc, sc->hw); - spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { ath_print(common, ATH_DBG_FATAL, @@ -897,8 +897,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); return; } - spin_unlock_bh(&sc->sc_pcu_lock); - if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); /* restart beacons */ @@ -911,6 +909,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_set_gpio(ah, ah->led_pin, 0); ieee80211_wake_queues(hw); + spin_unlock_bh(&sc->sc_pcu_lock); + ath9k_ps_restore(sc); } @@ -921,6 +921,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) int r; ath9k_ps_wakeup(sc); + spin_lock_bh(&sc->sc_pcu_lock); + ieee80211_stop_queues(hw); /* @@ -937,8 +939,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath_drain_all_txq(sc, false); /* clear pending tx frames */ - spin_lock_bh(&sc->sc_pcu_lock); - ath_stoprecv(sc); /* turn off frame recv */ ath_flushrecv(sc); /* flush recv queue */ @@ -955,10 +955,11 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_phy_disable(ah); - spin_unlock_bh(&sc->sc_pcu_lock); - ath9k_hw_configpcipowersave(ah, 1, 1); + + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); + ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); } @@ -972,13 +973,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Stop ANI */ del_timer_sync(&common->ani.timer); + spin_lock_bh(&sc->sc_pcu_lock); + ieee80211_stop_queues(hw); ath9k_hw_disable_interrupts(ah); ath_drain_all_txq(sc, retry_tx); - spin_lock_bh(&sc->sc_pcu_lock); - ath_stoprecv(sc); ath_flushrecv(sc); @@ -991,8 +992,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Unable to start recv logic\n"); - spin_unlock_bh(&sc->sc_pcu_lock); - /* * We may be doing a reset in response to a request * that changes the channel so update any state that @@ -1017,6 +1016,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) } ieee80211_wake_queues(hw); + spin_unlock_bh(&sc->sc_pcu_lock); /* Start ANI */ ath_start_ani(common); @@ -1381,25 +1381,25 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_btcoex_timer_pause(sc); } + spin_lock_bh(&sc->sc_pcu_lock); + /* make sure h/w will not generate any interrupt * before setting the invalid flag. */ ath9k_hw_disable_interrupts(ah); if (!(sc->sc_flags & SC_OP_INVALID)) { ath_drain_all_txq(sc, false); - spin_lock_bh(&sc->sc_pcu_lock); ath_stoprecv(sc); ath9k_hw_phy_disable(ah); - spin_unlock_bh(&sc->sc_pcu_lock); - } else { - spin_lock_bh(&sc->sc_pcu_lock); + } else sc->rx.rxlink = NULL; - spin_unlock_bh(&sc->sc_pcu_lock); - } /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); ath9k_hw_configpcipowersave(ah, 1, 1); + + spin_unlock_bh(&sc->sc_pcu_lock); + ath9k_ps_restore(sc); /* Finally, put the chip in FULL SLEEP mode */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d97b7a336b5b..2bc422eb80c7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1148,13 +1148,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA. Resetting hardware!\n"); - spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d\n", r); - spin_unlock_bh(&sc->sc_pcu_lock); } for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { -- cgit v1.2.3-59-g8ed1b From 07caf9d6c9135ae25a760867f37aab90c1008380 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 27 Oct 2010 14:58:29 +0200 Subject: mac80211: refactor debugfs function generation code refactor mac80211 debugfs code by using a format© function, instead of duplicating the code for each generated function. this change reduces about 600B from mac80211.ko Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/debugfs.c | 60 ++++++++++++++++++++++++---------------------- net/mac80211/debugfs.h | 2 ++ net/mac80211/debugfs_key.c | 19 +++++++-------- net/mac80211/debugfs_sta.c | 26 ++++++++------------ 4 files changed, 52 insertions(+), 55 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 18260aa99c56..1f02e599a318 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -21,16 +21,30 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file) return 0; } -#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ +#define DEBUGFS_FORMAT_BUFFER_SIZE 100 + +int mac80211_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...) +{ + va_list args; + char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; + int res; + + va_start(args, fmt); + res = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ struct ieee80211_local *local = file->private_data; \ - char buf[buflen]; \ - int res; \ \ - res = scnprintf(buf, buflen, fmt "\n", ##value); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ + return mac80211_format_buffer(userbuf, count, ppos, \ + fmt "\n", ##value); \ } \ \ static const struct file_operations name## _ops = { \ @@ -46,13 +60,13 @@ static const struct file_operations name## _ops = { \ debugfs_create_file(#name, mode, phyd, local, &name## _ops); -DEBUGFS_READONLY_FILE(frequency, 20, "%d", +DEBUGFS_READONLY_FILE(frequency, "%d", local->hw.conf.channel->center_freq); -DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", +DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", local->total_ps_buffered); -DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", +DEBUGFS_READONLY_FILE(wep_iv, "%#08x", local->wep_iv & 0xffffff); -DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", +DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s", local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); static ssize_t tsf_read(struct file *file, char __user *user_buf, @@ -60,13 +74,11 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf, { struct ieee80211_local *local = file->private_data; u64 tsf; - char buf[100]; tsf = drv_get_tsf(local); - snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, 19); + return mac80211_format_buffer(user_buf, count, ppos, "0x%016llx\n", + (unsigned long long) tsf); } static ssize_t tsf_write(struct file *file, @@ -131,12 +143,9 @@ static ssize_t noack_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ieee80211_local *local = file->private_data; - int res; - char buf[10]; - res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test); - - return simple_read_from_buffer(user_buf, count, ppos, buf, res); + return mac80211_format_buffer(user_buf, count, ppos, "%d\n", + local->wifi_wme_noack_test); } static ssize_t noack_write(struct file *file, @@ -168,12 +177,8 @@ static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ieee80211_local *local = file->private_data; - int res; - char buf[10]; - - res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues); - - return simple_read_from_buffer(user_buf, count, ppos, buf, res); + return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", + local->uapsd_queues); } static ssize_t uapsd_queues_write(struct file *file, @@ -215,12 +220,9 @@ static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ieee80211_local *local = file->private_data; - int res; - char buf[10]; - res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len); - - return simple_read_from_buffer(user_buf, count, ppos, buf, res); + return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", + local->uapsd_max_sp_len); } static ssize_t uapsd_max_sp_len_write(struct file *file, diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h index 09cc9be34796..7c87529630f5 100644 --- a/net/mac80211/debugfs.h +++ b/net/mac80211/debugfs.h @@ -4,6 +4,8 @@ #ifdef CONFIG_MAC80211_DEBUGFS extern void debugfs_hw_add(struct ieee80211_local *local); extern int mac80211_open_file_generic(struct inode *inode, struct file *file); +extern int mac80211_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...); #else static inline void debugfs_hw_add(struct ieee80211_local *local) { diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 1243d1db5c59..5822a6ce7671 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -15,18 +15,17 @@ #include "debugfs.h" #include "debugfs_key.h" -#define KEY_READ(name, prop, buflen, format_string) \ +#define KEY_READ(name, prop, format_string) \ static ssize_t key_##name##_read(struct file *file, \ char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - char buf[buflen]; \ struct ieee80211_key *key = file->private_data; \ - int res = scnprintf(buf, buflen, format_string, key->prop); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ + return mac80211_format_buffer(userbuf, count, ppos, \ + format_string, key->prop); \ } -#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n") -#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n") +#define KEY_READ_D(name) KEY_READ(name, name, "%d\n") +#define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n") #define KEY_OPS(name) \ static const struct file_operations key_ ##name## _ops = { \ @@ -39,9 +38,9 @@ static const struct file_operations key_ ##name## _ops = { \ KEY_READ_##format(name) \ KEY_OPS(name) -#define KEY_CONF_READ(name, buflen, format_string) \ - KEY_READ(conf_##name, conf.name, buflen, format_string) -#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n") +#define KEY_CONF_READ(name, format_string) \ + KEY_READ(conf_##name, conf.name, format_string) +#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n") #define KEY_CONF_OPS(name) \ static const struct file_operations key_ ##name## _ops = { \ @@ -59,7 +58,7 @@ KEY_CONF_FILE(keyidx, D); KEY_CONF_FILE(hw_key_idx, D); KEY_FILE(flags, X); KEY_FILE(tx_rx_count, D); -KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n"); +KEY_READ(ifindex, sdata->name, "%s\n"); KEY_OPS(ifindex); static ssize_t key_algorithm_read(struct file *file, diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 4601fea1784d..f0fce37f4069 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -17,20 +17,18 @@ /* sta attributtes */ -#define STA_READ(name, buflen, field, format_string) \ +#define STA_READ(name, field, format_string) \ static ssize_t sta_ ##name## _read(struct file *file, \ char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - int res; \ struct sta_info *sta = file->private_data; \ - char buf[buflen]; \ - res = scnprintf(buf, buflen, format_string, sta->field); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ + return mac80211_format_buffer(userbuf, count, ppos, \ + format_string, sta->field); \ } -#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n") -#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n") -#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") +#define STA_READ_D(name, field) STA_READ(name, field, "%d\n") +#define STA_READ_U(name, field) STA_READ(name, field, "%u\n") +#define STA_READ_S(name, field) STA_READ(name, field, "%s\n") #define STA_OPS(name) \ static const struct file_operations sta_ ##name## _ops = { \ @@ -79,22 +77,18 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - char buf[20]; struct sta_info *sta = file->private_data; - int res = scnprintf(buf, sizeof(buf), "%u\n", - skb_queue_len(&sta->ps_tx_buf)); - return simple_read_from_buffer(userbuf, count, ppos, buf, res); + return mac80211_format_buffer(userbuf, count, ppos, "%u\n", + skb_queue_len(&sta->ps_tx_buf)); } STA_OPS(num_ps_buf_frames); static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - char buf[20]; struct sta_info *sta = file->private_data; - int res = scnprintf(buf, sizeof(buf), "%d\n", - jiffies_to_msecs(jiffies - sta->last_rx)); - return simple_read_from_buffer(userbuf, count, ppos, buf, res); + return mac80211_format_buffer(userbuf, count, ppos, "%d\n", + jiffies_to_msecs(jiffies - sta->last_rx)); } STA_OPS(inactive_ms); -- cgit v1.2.3-59-g8ed1b From dc21b5453249e7e9b8878fab356fd60b731cf04d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 23 Oct 2010 09:15:39 -0700 Subject: iwlwifi: make mac80211 ops a device config In the future, 4965 and modern AGN devices will need to have different mac80211 callbacks since they have different capabilities. Prepare for that by making the mac80211 operations a device config. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-3945.c | 1 + drivers/net/wireless/iwlwifi/iwl-3945.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 10 +++++----- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 11 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index db540910b110..4266c855a767 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -243,6 +243,7 @@ static const struct iwl_ops iwl1000_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl1000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4d7130c9b72c..95fed1158452 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2753,6 +2753,7 @@ static const struct iwl_ops iwl3945_ops = { .hcmd = &iwl3945_hcmd, .utils = &iwl3945_hcmd_utils, .led = &iwl3945_led_ops, + .ieee80211_ops = &iwl3945_hw_ops, }; static struct iwl_base_params iwl3945_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 09391f0ee61f..b27f07cbf355 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -282,6 +282,8 @@ extern int iwl3945_commit_rxon(struct iwl_priv *priv, */ extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); +extern struct ieee80211_ops iwl3945_hw_ops; + /* * Forward declare iwl-3945.c functions for iwl-base.c */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ee9c582c8cf2..7921a910b34a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2305,6 +2305,7 @@ static const struct iwl_ops iwl4965_ops = { .hcmd = &iwl4965_hcmd, .utils = &iwl4965_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl4965_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index fd9fbc93ea1b..5f0327721692 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -485,6 +485,7 @@ static const struct iwl_ops iwl5000_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl5150_ops = { @@ -492,6 +493,7 @@ static const struct iwl_ops iwl5150_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl5000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 11e6532fc573..85bde701351e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -439,6 +439,7 @@ static const struct iwl_ops iwl6000_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6050_ops = { @@ -447,6 +448,7 @@ static const struct iwl_ops iwl6050_ops = { .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, .nic = &iwl6050_nic_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6050g2_ops = { @@ -455,6 +457,7 @@ static const struct iwl_ops iwl6050g2_ops = { .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, .nic = &iwl6050g2_nic_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6000g2b_ops = { @@ -462,6 +465,7 @@ static const struct iwl_ops iwl6000g2b_ops = { .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl6000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0027bb8299a8..e3533a89ec9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4211,7 +4211,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } -static struct ieee80211_ops iwl_hw_ops = { +struct ieee80211_ops iwlagn_hw_ops = { .tx = iwl_mac_tx, .start = iwl_mac_start, .stop = iwl_mac_stop, @@ -4300,10 +4300,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (cfg->mod_params->disable_hw_scan) { dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); - iwl_hw_ops.hw_scan = NULL; + iwlagn_hw_ops.hw_scan = NULL; } - hw = iwl_alloc_all(cfg, &iwl_hw_ops); + hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; goto out; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index f525d55f2c0f..ba88e78e6116 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -102,6 +102,8 @@ extern struct iwl_hcmd_ops iwlagn_hcmd; extern struct iwl_hcmd_ops iwlagn_bt_hcmd; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; +extern struct ieee80211_ops iwlagn_hw_ops; + int iwl_reset_ict(struct iwl_priv *priv); void iwl_disable_ict(struct iwl_priv *priv); int iwl_alloc_isr_ict(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2a4d40e5b9f4..c93368083e1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -77,15 +77,15 @@ EXPORT_SYMBOL(iwl_bcast_addr); /* This function both allocates and initializes hw and priv. */ -struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, - struct ieee80211_ops *hw_ops) +struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) { struct iwl_priv *priv; - /* mac80211 allocates memory for this device instance, including * space for this driver's private structure */ - struct ieee80211_hw *hw = - ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); + struct ieee80211_hw *hw; + + hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), + cfg->ops->ieee80211_ops); if (hw == NULL) { pr_err("%s: Can not allocate network device\n", cfg->name); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b17de8214eb5..917d42eae55a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -241,6 +241,7 @@ struct iwl_ops { const struct iwl_hcmd_utils_ops *utils; const struct iwl_led_ops *led; const struct iwl_nic_ops *nic; + const struct ieee80211_ops *ieee80211_ops; }; struct iwl_mod_params { @@ -396,8 +397,7 @@ struct iwl_cfg { * L i b * ***************************/ -struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, - struct ieee80211_ops *hw_ops); +struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 9b71921dc2b6..d42bb22e5ed5 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3824,7 +3824,7 @@ static struct attribute_group iwl3945_attribute_group = { .attrs = iwl3945_sysfs_entries, }; -static struct ieee80211_ops iwl3945_hw_ops = { +struct ieee80211_ops iwl3945_hw_ops = { .tx = iwl3945_mac_tx, .start = iwl3945_mac_start, .stop = iwl3945_mac_stop, @@ -3966,7 +3966,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e /* mac80211 allocates memory for this device instance, including * space for this driver's private structure */ - hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); + hw = iwl_alloc_all(cfg); if (hw == NULL) { pr_err("Can not allocate network device\n"); err = -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 2d4e43c3c6783f956163c11568303b0390725e28 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 23 Oct 2010 09:15:40 -0700 Subject: iwlagn: don't resend RXON timing Resending RXON timing here caused issues with dual-mode under certain circumstances, so avoid doing it here right now. This effectively reverts b01efe434bd6ea807eb72b and partially 2491fa42d9bdf26075765. The next patch will make all this cleaner for just the devices that need it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e3533a89ec9c..3d1f6831cc20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -105,7 +105,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) int ret; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); - bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -EBUSY; @@ -186,19 +185,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - if (!old_assoc) { - /* - * First of all, before setting associated, we need to - * send RXON timing so the device knows about the DTIM - * period and other timing values - */ - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) { - IWL_ERR(priv, "Error setting RXON timing!\n"); - return ret; - } - } - if (priv->cfg->ops->hcmd->set_pan_params) { ret = priv->cfg->ops->hcmd->set_pan_params(priv); if (ret) -- cgit v1.2.3-59-g8ed1b From 2295c66b68ae160dde2e6e2dc4f3061105153bfc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 23 Oct 2010 09:15:41 -0700 Subject: iwlagn: new RXON processing for modern devices In order to simplify the flow, and make new enhancements easier, separate out the RXON processing for modern AGN (5000 and newer) from RXON processing for the older 3945 and 4965 devices. Avoid changing these old ones to avoid regressions and move their code to a new file (iwl-legacy.c). 4965 gets the commit_rxon that used to be common for all AGN devices, but with removed PAN support. The new RXON processing is more central and does more work in committing, so that it is easier to follow. To make it more evident what is split out for legacy, split the necessary operations for that into a new struct iwl_legacy_ops. Those parts that still exist in the new AGN code don't need to be parametrized. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 3 + drivers/net/wireless/iwlwifi/iwl-1000.c | 4 - drivers/net/wireless/iwlwifi/iwl-3945.c | 10 +- drivers/net/wireless/iwlwifi/iwl-3945.h | 6 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 318 +++++++++++++++- drivers/net/wireless/iwlwifi/iwl-5000.c | 8 - drivers/net/wireless/iwlwifi/iwl-6000.c | 8 - drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 562 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 385 +++---------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 34 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 531 -------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 30 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-led.c | 2 + drivers/net/wireless/iwlwifi/iwl-legacy.c | 560 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-legacy.h | 74 ++++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 30 +- 17 files changed, 1631 insertions(+), 936 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 63edbe2e557f..ce05c260870e 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -2,6 +2,8 @@ obj-$(CONFIG_IWLWIFI) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwlcore-objs += iwl-scan.o iwl-led.o +iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o +iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o @@ -16,6 +18,7 @@ iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o +iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwlagn-$(CONFIG_IWL5000) += iwl-5000.o iwlagn-$(CONFIG_IWL5000) += iwl-6000.o iwlagn-$(CONFIG_IWL5000) += iwl-1000.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 4266c855a767..baedea8e4d04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -211,14 +211,10 @@ static struct iwl_lib_ops iwl1000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .post_associate = iwl_post_associate, .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 95fed1158452..d9e676480269 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2726,10 +2726,7 @@ static struct iwl_lib_ops iwl3945_lib = { }, .send_tx_power = iwl3945_send_tx_power, .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, - .post_associate = iwl3945_post_associate, .isr = iwl_isr_legacy, - .config_ap = iwl3945_config_ap, - .manage_ibss_station = iwl3945_manage_ibss_station, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl3945_good_plcp_health, @@ -2740,6 +2737,12 @@ static struct iwl_lib_ops iwl3945_lib = { }, }; +static const struct iwl_legacy_ops iwl3945_legacy_ops = { + .post_associate = iwl3945_post_associate, + .config_ap = iwl3945_config_ap, + .manage_ibss_station = iwl3945_manage_ibss_station, +}; + static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .get_hcmd_size = iwl3945_get_hcmd_size, .build_addsta_hcmd = iwl3945_build_addsta_hcmd, @@ -2753,6 +2756,7 @@ static const struct iwl_ops iwl3945_ops = { .hcmd = &iwl3945_hcmd, .utils = &iwl3945_hcmd_utils, .led = &iwl3945_led_ops, + .legacy = &iwl3945_legacy_ops, .ieee80211_ops = &iwl3945_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index b27f07cbf355..3eef1eb74a78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -264,10 +264,8 @@ void iwl3945_reply_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); extern void iwl3945_disable_events(struct iwl_priv *priv); extern int iwl4965_get_temperature(const struct iwl_priv *priv); -extern void iwl3945_post_associate(struct iwl_priv *priv, - struct ieee80211_vif *vif); -extern void iwl3945_config_ap(struct iwl_priv *priv, - struct ieee80211_vif *vif); +extern void iwl3945_post_associate(struct iwl_priv *priv); +extern void iwl3945_config_ap(struct iwl_priv *priv); extern int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 7921a910b34a..8f07964e4305 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -48,6 +48,7 @@ #include "iwl-agn-led.h" #include "iwl-agn.h" #include "iwl-agn-debugfs.h" +#include "iwl-legacy.h" static int iwl4965_send_tx_power(struct iwl_priv *priv); static int iwl4965_hw_get_temperature(struct iwl_priv *priv); @@ -1443,6 +1444,142 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, return ret; } +static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; + int ret; + bool new_assoc = + !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + + if (!iwl_is_alive(priv)) + return -EBUSY; + + if (!ctx->is_active) + return 0; + + /* always get timestamp with Rx frame */ + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + + ret = iwl_check_rxon_cmd(priv, ctx); + if (ret) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* + * receive commit_rxon request + * abort any previous channel switch if still in process + */ + if (priv->switch_rxon.switch_in_progress && + (priv->switch_rxon.channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", + le16_to_cpu(priv->switch_rxon.channel)); + iwl_chswitch_done(priv, false); + } + + /* If we don't need to send a full RXON, we can use + * iwl_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_full_rxon_required(priv, ctx)) { + ret = iwl_send_rxon_assoc(priv, ctx); + if (ret) { + IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); + return ret; + } + + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_print_rx_config_cmd(priv, ctx); + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_is_associated_ctx(ctx) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), + active_rxon); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (ret) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); + return ret; + } + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); + + iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); + + /* Apply the new configuration + * RXON unassoc clears the station table in uCode so restoration of + * stations is needed after it (the RXON command) completes + */ + if (!new_assoc) { + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + if (new_assoc) { + priv->start_calib = 0; + /* Apply the new configuration + * RXON assoc doesn't clear the station table in uCode, + */ + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + } + iwl_print_rx_config_cmd(priv, ctx); + + iwl_init_sensitivity(priv); + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + if (ret) { + IWL_ERR(priv, "Error sending TX power (%d)\n", ret); + return ret; + } + + return 0; +} + static int iwl4965_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { @@ -2212,7 +2349,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, - .commit_rxon = iwlagn_commit_rxon, + .commit_rxon = iwl4965_commit_rxon, .set_rxon_chain = iwlagn_set_rxon_chain, .send_bt_config = iwl_send_bt_config, }; @@ -2229,6 +2366,149 @@ static void iwl4965_post_scan(struct iwl_priv *priv) iwlcore_commit_rxon(priv, ctx); } +static void iwl4965_post_associate(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_conf *conf = NULL; + int ret = 0; + + if (!vif || !priv->is_open) + return; + + if (vif->type == NL80211_IFTYPE_AP) { + IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); + return; + } + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_scan_cancel_timeout(priv, 200); + + conf = ieee80211_get_hw_conf(priv->hw); + + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing - " + "Attempting to continue.\n"); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + + iwl_set_rxon_ht(priv, &priv->current_ht_config); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + + IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", + vif->bss_conf.aid, vif->bss_conf.beacon_int); + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + } + + iwlcore_commit_rxon(priv, ctx); + + IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", + vif->bss_conf.aid, ctx->active.bssid_addr); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + break; + case NL80211_IFTYPE_ADHOC: + iwlagn_send_beacon_cmd(priv); + break; + default: + IWL_ERR(priv, "%s Should not be called in %d mode\n", + __func__, vif->type); + break; + } + + /* the chain noise calibration will enabled PM upon completion + * If chain noise has already been run, then we need to enable + * power management here */ + if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) + iwl_power_update_mode(priv, false); + + /* Enable Rx differential gain and sensitivity calibrations */ + iwl_chain_noise_reset(priv); + priv->start_calib = 1; +} + +static void iwl4965_config_ap(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + int ret = 0; + + lockdep_assert_held(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* The following should be done only at AP bring up */ + if (!iwl_is_associated_ctx(ctx)) { + + /* RXON - unassoc (to set timing command) */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + /* RXON Timing */ + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing failed - " + "Attempting to continue.\n"); + + /* AP has all antennas */ + priv->chain_noise_data.active_chains = + priv->hw_params.valid_rx_ant; + iwl_set_rxon_ht(priv, &priv->current_ht_config); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = 0; + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= + RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= + RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_SLOT_MSK; + } + /* need to send beacon cmd before committing assoc RXON! */ + iwlagn_send_beacon_cmd(priv); + /* restore RXON assoc */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + } + iwlagn_send_beacon_cmd(priv); + + /* FIXME - we need to add code here to detect a totally new + * configuration, reset the AP, unassoc, rxon timing, assoc, + * clear sta table, add BCAST sta... */ +} + static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .get_hcmd_size = iwl4965_get_hcmd_size, .build_addsta_hcmd = iwl4965_build_addsta_hcmd, @@ -2281,14 +2561,10 @@ static struct iwl_lib_ops iwl4965_lib = { }, .send_tx_power = iwl4965_send_tx_power, .update_chain_flags = iwl_update_chain_flags, - .post_associate = iwl_post_associate, - .config_ap = iwl_config_ap, .isr = iwl_isr_legacy, .temp_ops = { .temperature = iwl4965_temperature_calib, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -2300,12 +2576,42 @@ static struct iwl_lib_ops iwl4965_lib = { .check_plcp_health = iwl_good_plcp_health, }; +static const struct iwl_legacy_ops iwl4965_legacy_ops = { + .post_associate = iwl4965_post_associate, + .config_ap = iwl4965_config_ap, + .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_stations = iwl_update_bcast_stations, +}; + +struct ieee80211_ops iwl4965_hw_ops = { + .tx = iwlagn_mac_tx, + .start = iwlagn_mac_start, + .stop = iwlagn_mac_stop, + .add_interface = iwl_mac_add_interface, + .remove_interface = iwl_mac_remove_interface, + .config = iwl_legacy_mac_config, + .configure_filter = iwlagn_configure_filter, + .set_key = iwlagn_mac_set_key, + .update_tkip_key = iwlagn_mac_update_tkip_key, + .conf_tx = iwl_mac_conf_tx, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, + .ampdu_action = iwlagn_mac_ampdu_action, + .hw_scan = iwl_mac_hw_scan, + .sta_add = iwlagn_mac_sta_add, + .sta_remove = iwl_mac_sta_remove, + .channel_switch = iwlagn_mac_channel_switch, + .flush = iwlagn_mac_flush, + .tx_last_beacon = iwl_mac_tx_last_beacon, +}; + static const struct iwl_ops iwl4965_ops = { .lib = &iwl4965_lib, .hcmd = &iwl4965_hcmd, .utils = &iwl4965_hcmd_utils, .led = &iwlagn_led_ops, - .ieee80211_ops = &iwlagn_hw_ops, + .legacy = &iwl4965_legacy_ops, + .ieee80211_ops = &iwl4965_hw_ops, }; static struct iwl_base_params iwl4965_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5f0327721692..e1f412f915ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -385,14 +385,10 @@ static struct iwl_lib_ops iwl5000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .post_associate = iwl_post_associate, .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -453,14 +449,10 @@ static struct iwl_lib_ops iwl5150_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .post_associate = iwl_post_associate, .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwl5150_temperature, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 85bde701351e..eacbce0d88b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -328,14 +328,10 @@ static struct iwl_lib_ops iwl6000_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .post_associate = iwl_post_associate, .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -399,14 +395,10 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .post_associate = iwl_post_associate, .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c new file mode 100644 index 000000000000..58602457e415 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -0,0 +1,562 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include "iwl-dev.h" +#include "iwl-agn.h" +#include "iwl-sta.h" +#include "iwl-core.h" +#include "iwl-agn-calib.h" + +static int iwlagn_disable_bss(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_rxon_cmd *send) +{ + __le32 old_filter = send->filter_flags; + int ret; + + send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + + send->filter_flags = old_filter; + + if (ret) + IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret); + + return ret; +} + +static int iwlagn_disable_pan(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_rxon_cmd *send) +{ + __le32 old_filter = send->filter_flags; + u8 old_dev_type = send->dev_type; + int ret; + + send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + send->dev_type = RXON_DEV_TYPE_P2P; + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + + send->filter_flags = old_filter; + send->dev_type = old_dev_type; + + if (ret) + IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); + + /* FIXME: WAIT FOR PAN DISABLE */ + msleep(300); + + return ret; +} + +/** + * iwlagn_commit_rxon - commit staging_rxon to hardware + * + * The RXON command in staging_rxon is committed to the hardware and + * the active_rxon structure is updated with the new data. This + * function correctly transitions out of the RXON_ASSOC_MSK state if + * a HW tune is required based on the RXON structure changes. + */ +int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl_rxon_cmd *active = (void *)&ctx->active; + bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); + bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + int ret; + + lockdep_assert_held(&priv->mutex); + + if (!iwl_is_alive(priv)) + return -EBUSY; + + /* This function hardcodes a bunch of dual-mode assumptions */ + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); + + if (!ctx->is_active) + return 0; + + /* always get timestamp with Rx frame */ + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + + if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || + !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + + ret = iwl_check_rxon_cmd(priv, ctx); + if (ret) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* + * receive commit_rxon request + * abort any previous channel switch if still in process + */ + if (priv->switch_rxon.switch_in_progress && + (priv->switch_rxon.channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", + le16_to_cpu(priv->switch_rxon.channel)); + iwl_chswitch_done(priv, false); + } + + /* + * If we don't need to send a full RXON, we can use + * iwl_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. + */ + if (!iwl_full_rxon_required(priv, ctx)) { + ret = iwl_send_rxon_assoc(priv, ctx); + if (ret) { + IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); + return ret; + } + + memcpy(active, &ctx->staging, sizeof(*active)); + iwl_print_rx_config_cmd(priv, ctx); + return 0; + } + + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } + + iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); + + IWL_DEBUG_INFO(priv, + "Going to commit RXON\n" + " * with%s RXON_FILTER_ASSOC_MSK\n" + " * channel = %d\n" + " * bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); + + /* + * If we are currently associated and the new config is also + * going to be associated, OR if the new config is simply not + * associated, clear associated. + */ + if ((old_assoc && new_assoc) || !new_assoc) { + struct iwl_rxon_cmd *send = active; + + if (!new_assoc) + send = &ctx->staging; + + if (ctx->ctxid == IWL_RXON_CTX_BSS) + ret = iwlagn_disable_bss(priv, ctx, send); + else + ret = iwlagn_disable_pan(priv, ctx, send); + if (ret) + return ret; + + if (send != active) + memcpy(active, send, sizeof(*active)); + + /* + * Un-assoc RXON clears the station table and WEP + * keys, so we have to restore those afterwards. + */ + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + + /* RXON timing must be before associated RXON */ + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); + return ret; + } + + if (new_assoc) { + if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP || + ctx->vif->type == NL80211_IFTYPE_ADHOC)) { + /* + * We'll run into this code path when beaconing is + * enabled, but then we also need to send the beacon + * to the device. + */ + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(priv->hw, + ctx->vif); + iwlagn_send_beacon_cmd(priv); + } + + priv->start_calib = 0; + /* + * Apply the new configuration. + * + * Associated RXON doesn't clear the station table in uCode, + * so we don't need to restore stations etc. after this. + */ + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + memcpy(active, &ctx->staging, sizeof(*active)); + } + + iwl_print_rx_config_cmd(priv, ctx); + + iwl_init_sensitivity(priv); + + /* + * If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames. + * + * FIXME: which RXON requires a tune? Can we optimise this out in + * some cases? + */ + ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + if (ret) { + IWL_ERR(priv, "Error sending TX power (%d)\n", ret); + return ret; + } + + return 0; +} + +int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; + const struct iwl_channel_info *ch_info; + int ret = 0; + + IWL_DEBUG_MAC80211(priv, "changed %#x", changed); + + mutex_lock(&priv->mutex); + + if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { + IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); + goto out; + } + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + goto out; + } + + if (changed & (IEEE80211_CONF_CHANGE_SMPS | + IEEE80211_CONF_CHANGE_CHANNEL)) { + /* mac80211 uses static for non-HT which is what we want */ + priv->current_ht_config.smps = conf->smps_mode; + + /* + * Recalculate chain counts. + * + * If monitor mode is enabled then mac80211 will + * set up the SM PS mode to OFF if an HT channel is + * configured. + */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + unsigned long flags; + + ch_info = iwl_get_channel_info(priv, channel->band, + channel->hw_value); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); + ret = -EINVAL; + goto out; + } + + spin_lock_irqsave(&priv->lock, flags); + + for_each_context(priv, ctx) { + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if (le16_to_cpu(ctx->staging.channel) != + channel->hw_value) + ctx->staging.flags = 0; + + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, &priv->current_ht_config); + + iwl_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_update_bcast_stations(priv); + + /* + * The list of supported rates and rate mask can be different + * for each band; since the band may have changed, reset + * the rate mask to what mac80211 lists. + */ + iwl_set_rate(priv); + } + + if (changed & (IEEE80211_CONF_CHANGE_PS | + IEEE80211_CONF_CHANGE_IDLE)) { + ret = iwl_power_update_mode(priv, false); + if (ret) + IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", + priv->tx_power_user_lmt, conf->power_level); + + iwl_set_tx_power(priv, conf->power_level, false); + } + + for_each_context(priv, ctx) { + if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + continue; + iwlagn_commit_rxon(priv, ctx); + } + out: + mutex_unlock(&priv->mutex); + return ret; +} + +static void iwlagn_update_qos(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm); + if (ret) + IWL_ERR(priv, "Failed to update QoS\n"); +} + +static void iwlagn_check_needed_chains(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_bss_conf *bss_conf) +{ + struct ieee80211_vif *vif = ctx->vif; + struct iwl_rxon_context *tmp; + struct ieee80211_sta *sta; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + bool need_multiple; + + lockdep_assert_held(&priv->mutex); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + int maxstreams; + + maxstreams = (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) + >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + maxstreams += 1; + + if ((ht_cap->mcs.rx_mask[1] == 0) && + (ht_cap->mcs.rx_mask[2] == 0)) + need_multiple = false; + if (maxstreams <= 1) + need_multiple = true; + } else { + /* + * If at all, this can only happen through a race + * when the AP disconnects us while we're still + * setting up the connection, in that case mac80211 + * will soon tell us about that. + */ + need_multiple = false; + } + rcu_read_unlock(); + break; + case NL80211_IFTYPE_ADHOC: + /* currently */ + need_multiple = false; + break; + default: + /* only AP really */ + need_multiple = true; + break; + } + + ctx->ht_need_multiple_chains = need_multiple; + + if (!need_multiple) { + /* check all contexts */ + for_each_context(priv, tmp) { + if (!tmp->vif) + continue; + if (tmp->ht_need_multiple_chains) { + need_multiple = true; + break; + } + } + } + + ht_conf->single_chain_sufficient = !need_multiple; +} + +void iwlagn_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + int ret; + bool force = false; + + mutex_lock(&priv->mutex); + + if (changes & BSS_CHANGED_BEACON_INT) + force = true; + + if (changes & BSS_CHANGED_QOS) { + ctx->qos_data.qos_active = bss_conf->qos; + iwlagn_update_qos(priv, ctx); + } + + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (changes & BSS_CHANGED_ASSOC) { + if (bss_conf->assoc) { + iwl_led_associate(priv); + priv->timestamp = bss_conf->timestamp; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + } else { + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_led_disassociate(priv); + } + } + + if (ctx->ht.enabled) { + ctx->ht.protection = bss_conf->ht_operation_mode & + IEEE80211_HT_OP_MODE_PROTECTION; + ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode & + IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + iwlagn_check_needed_chains(priv, ctx, bss_conf); + } + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + + if (bss_conf->use_cts_prot) + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + else + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + + memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); + + if (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_ADHOC) { + if (vif->bss_conf.enable_beacon) { + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + priv->beacon_ctx = ctx; + } else { + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + priv->beacon_ctx = NULL; + } + } + + if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlagn_commit_rxon(priv, ctx); + + if (changes & BSS_CHANGED_IBSS) { + ret = iwlagn_manage_ibss_station(priv, vif, + bss_conf->ibss_joined); + if (ret) + IWL_ERR(priv, "failed to %s IBSS station %pM\n", + bss_conf->ibss_joined ? "add" : "remove", + bss_conf->bssid); + } + + mutex_unlock(&priv->mutex); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3d1f6831cc20..1050f31d90a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -90,153 +90,6 @@ MODULE_ALIAS("iwl4965"); static int iwlagn_ant_coupling; static bool iwlagn_bt_ch_announce = 1; -/** - * iwlagn_commit_rxon - commit staging_rxon to hardware - * - * The RXON command in staging_rxon is committed to the hardware and - * the active_rxon structure is updated with the new data. This - * function correctly transitions out of the RXON_ASSOC_MSK state if - * a HW tune is required based on the RXON structure changes. - */ -int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; - int ret; - bool new_assoc = - !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); - - if (!iwl_is_alive(priv)) - return -EBUSY; - - if (!ctx->is_active) - return 0; - - /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - - ret = iwl_check_rxon_cmd(priv, ctx); - if (ret) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* - * receive commit_rxon request - * abort any previous channel switch if still in process - */ - if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != ctx->staging.channel)) { - IWL_DEBUG_11H(priv, "abort channel switch on %d\n", - le16_to_cpu(priv->switch_rxon.channel)); - iwl_chswitch_done(priv, false); - } - - /* If we don't need to send a full RXON, we can use - * iwl_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv, ctx)) { - ret = iwl_send_rxon_assoc(priv, ctx); - if (ret) { - IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); - return ret; - } - - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_print_rx_config_cmd(priv, ctx); - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated_ctx(ctx) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), - active_rxon); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (ret) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); - return ret; - } - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(ctx->staging.channel), - ctx->staging.bssid_addr); - - iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - - if (priv->cfg->ops->hcmd->set_pan_params) { - ret = priv->cfg->ops->hcmd->set_pan_params(priv); - if (ret) - return ret; - } - - /* Apply the new configuration - * RXON unassoc clears the station table in uCode so restoration of - * stations is needed after it (the RXON command) completes - */ - if (!new_assoc) { - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - if (new_assoc) { - priv->start_calib = 0; - /* Apply the new configuration - * RXON assoc doesn't clear the station table in uCode, - */ - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - } - iwl_print_rx_config_cmd(priv, ctx); - - iwl_init_sensitivity(priv); - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = priv->cfg->ops->lib->send_tx_power(priv); - if (ret) - IWL_ERR(priv, "Error sending TX power (%d)\n", ret); - return ret; -} - void iwl_update_chain_flags(struct iwl_priv *priv) { struct iwl_rxon_context *ctx; @@ -394,7 +247,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, return sizeof(*tx_beacon_cmd) + frame_size; } -static int iwl_send_beacon_cmd(struct iwl_priv *priv) + +int iwlagn_send_beacon_cmd(struct iwl_priv *priv) { struct iwl_frame *frame; unsigned int frame_size; @@ -644,7 +498,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) priv->beacon_skb = beacon; - iwl_send_beacon_cmd(priv); + iwlagn_send_beacon_cmd(priv); out: mutex_unlock(&priv->mutex); } @@ -3292,92 +3146,6 @@ static void iwl_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } -#define IWL_DELAY_NEXT_SCAN (HZ*2) - -void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) -{ - struct iwl_rxon_context *ctx; - struct ieee80211_conf *conf = NULL; - int ret = 0; - - if (!vif || !priv->is_open) - return; - - ctx = iwl_rxon_ctx_from_vif(vif); - - if (vif->type == NL80211_IFTYPE_AP) { - IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); - return; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_scan_cancel_timeout(priv, 200); - - conf = ieee80211_get_hw_conf(priv->hw); - - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing - " - "Attempting to continue.\n"); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - - iwl_set_rxon_ht(priv, &priv->current_ht_config); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); - - IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - vif->bss_conf.aid, vif->bss_conf.beacon_int); - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - } - - iwlcore_commit_rxon(priv, ctx); - - IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, ctx->active.bssid_addr); - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - iwl_send_beacon_cmd(priv); - break; - default: - IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, vif->type); - break; - } - - /* the chain noise calibration will enabled PM upon completion - * If chain noise has already been run, then we need to enable - * power management here */ - if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) - iwl_power_update_mode(priv, false); - - /* Enable Rx differential gain and sensitivity calibrations */ - iwl_chain_noise_reset(priv); - priv->start_calib = 1; - -} - /***************************************************************************** * * mac80211 entry point functions @@ -3457,7 +3225,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, } -static int iwl_mac_start(struct ieee80211_hw *hw) +int iwlagn_mac_start(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; int ret; @@ -3498,7 +3266,7 @@ out: return 0; } -static void iwl_mac_stop(struct ieee80211_hw *hw) +void iwlagn_mac_stop(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -3520,7 +3288,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = hw->priv; @@ -3536,73 +3304,12 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) -{ - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - int ret = 0; - - lockdep_assert_held(&priv->mutex); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* The following should be done only at AP bring up */ - if (!iwl_is_associated_ctx(ctx)) { - - /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - /* RXON Timing */ - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing failed - " - "Attempting to continue.\n"); - - /* AP has all antennas */ - priv->chain_noise_data.active_chains = - priv->hw_params.valid_rx_ant; - iwl_set_rxon_ht(priv, &priv->current_ht_config); - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = 0; - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= - RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= - RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; - } - /* need to send beacon cmd before committing assoc RXON! */ - iwl_send_beacon_cmd(priv); - /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - } - iwl_send_beacon_cmd(priv); - - /* FIXME - we need to add code here to detect a totally new - * configuration, reset the AP, unassoc, rxon timing, assoc, - * clear sta table, add BCAST sta... */ -} - -static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, - u32 iv32, u16 *phase1key) +void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key) { - struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; @@ -3614,10 +3321,9 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) { struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; @@ -3684,10 +3390,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) +int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) { struct iwl_priv *priv = hw->priv; int ret = -EINVAL; @@ -3768,10 +3474,10 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, return ret; } -static void iwl_mac_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) +static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) { struct iwl_priv *priv = hw->priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; @@ -3798,9 +3504,9 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw, } } -static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int iwlagn_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { struct iwl_priv *priv = hw->priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; @@ -3841,8 +3547,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, return 0; } -static void iwl_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch) +void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch) { struct iwl_priv *priv = hw->priv; const struct iwl_channel_info *ch_info; @@ -3939,10 +3645,10 @@ out_exit: IWL_DEBUG_MAC80211(priv, "leave\n"); } -static void iwlagn_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) +void iwlagn_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) { struct iwl_priv *priv = hw->priv; __le32 filter_or = 0, filter_nand = 0; @@ -3988,7 +3694,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } -static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) +void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) { struct iwl_priv *priv = hw->priv; @@ -4198,25 +3904,24 @@ static void iwl_uninit_drv(struct iwl_priv *priv) } struct ieee80211_ops iwlagn_hw_ops = { - .tx = iwl_mac_tx, - .start = iwl_mac_start, - .stop = iwl_mac_stop, + .tx = iwlagn_mac_tx, + .start = iwlagn_mac_start, + .stop = iwlagn_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, - .config = iwl_mac_config, + .config = iwlagn_mac_config, .configure_filter = iwlagn_configure_filter, - .set_key = iwl_mac_set_key, - .update_tkip_key = iwl_mac_update_tkip_key, + .set_key = iwlagn_mac_set_key, + .update_tkip_key = iwlagn_mac_update_tkip_key, .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_mac_reset_tsf, - .bss_info_changed = iwl_bss_info_changed, - .ampdu_action = iwl_mac_ampdu_action, + .bss_info_changed = iwlagn_bss_info_changed, + .ampdu_action = iwlagn_mac_ampdu_action, .hw_scan = iwl_mac_hw_scan, - .sta_notify = iwl_mac_sta_notify, + .sta_notify = iwlagn_mac_sta_notify, .sta_add = iwlagn_mac_sta_add, .sta_remove = iwl_mac_sta_remove, - .channel_switch = iwl_mac_channel_switch, - .flush = iwl_mac_flush, + .channel_switch = iwlagn_mac_channel_switch, + .flush = iwlagn_mac_flush, .tx_last_beacon = iwl_mac_tx_last_beacon, }; @@ -4287,6 +3992,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); iwlagn_hw_ops.hw_scan = NULL; +#ifdef CONFIG_IWL4965 + iwl4965_hw_ops.hw_scan = NULL; +#endif } hw = iwl_alloc_all(cfg); @@ -4321,6 +4029,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) BIT(NL80211_IFTYPE_ADHOC); priv->contexts[IWL_RXON_CTX_BSS].interface_modes = BIT(NL80211_IFTYPE_STATION); + priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ba88e78e6116..aca93f4477a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -103,6 +103,7 @@ extern struct iwl_hcmd_ops iwlagn_bt_hcmd; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; extern struct ieee80211_ops iwlagn_hw_ops; +extern struct ieee80211_ops iwl4965_hw_ops; int iwl_reset_ict(struct iwl_priv *priv); void iwl_disable_ict(struct iwl_priv *priv); @@ -134,6 +135,11 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, /* RXON */ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed); +void iwlagn_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes); /* uCode */ int iwlagn_load_ucode(struct iwl_priv *priv); @@ -251,6 +257,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, int iwlagn_send_rxon_assoc(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); +int iwlagn_send_beacon_cmd(struct iwl_priv *priv); /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); @@ -320,4 +327,31 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); +/* mac80211 handlers (for 4965) */ +int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +int iwlagn_mac_start(struct ieee80211_hw *hw); +void iwlagn_mac_stop(struct ieee80211_hw *hw); +void iwlagn_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast); +int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key); +int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); +int iwlagn_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch); +void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c93368083e1a..776713c6a7ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -100,35 +100,6 @@ out: } EXPORT_SYMBOL(iwl_alloc_all); -/* - * QoS support -*/ -static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); -} - #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, @@ -1456,310 +1427,6 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); -static void iwl_ht_conf(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct ieee80211_sta *sta; - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - IWL_DEBUG_MAC80211(priv, "enter:\n"); - - if (!ctx->ht.enabled) - return; - - ctx->ht.protection = - bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ctx->ht.non_gf_sta_present = - !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - ht_conf->single_chain_sufficient = false; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - rcu_read_lock(); - sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - int maxstreams; - - maxstreams = (ht_cap->mcs.tx_params & - IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) - >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - maxstreams += 1; - - if ((ht_cap->mcs.rx_mask[1] == 0) && - (ht_cap->mcs.rx_mask[2] == 0)) - ht_conf->single_chain_sufficient = true; - if (maxstreams <= 1) - ht_conf->single_chain_sufficient = true; - } else { - /* - * If at all, this can only happen through a race - * when the AP disconnects us while we're still - * setting up the connection, in that case mac80211 - * will soon tell us about that. - */ - ht_conf->single_chain_sufficient = true; - } - rcu_read_unlock(); - break; - case NL80211_IFTYPE_ADHOC: - ht_conf->single_chain_sufficient = true; - break; - default: - break; - } - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - -static inline void iwl_set_no_assoc(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - iwl_led_disassociate(priv); - /* - * inform the ucode that there is no longer an - * association and that no more packets should be - * sent - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = 0; - iwlcore_commit_rxon(priv, ctx); -} - -static void iwlcore_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - struct sk_buff *skb = ieee80211_beacon_get(hw, vif); - - if (!skb) - return; - - IWL_DEBUG_ASSOC(priv, "enter\n"); - - lockdep_assert_held(&priv->mutex); - - if (!priv->beacon_ctx) { - IWL_ERR(priv, "update beacon but no beacon context!\n"); - dev_kfree_skb(skb); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = skb; - - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_ASSOC(priv, "leave\n"); - - spin_unlock_irqrestore(&priv->lock, flags); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return; - } - - priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); -} - -void iwl_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - int ret; - - IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); - - if (!iwl_is_alive(priv)) - return; - - mutex_lock(&priv->mutex); - - if (changes & (BSS_CHANGED_BSSID | BSS_CHANGED_ASSOC | - BSS_CHANGED_BEACON_ENABLED)) { - /* - * If there is currently a HW scan going on in the - * background then we need to cancel it else the RXON - * below in post_associate or set_no_assoc can fail. - */ - if (iwl_scan_cancel_timeout(priv, 200)) { - IWL_WARN(priv, "Can not cancel scan\n"); - goto out; - } - } - - if (changes & BSS_CHANGED_QOS) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - ctx->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv, ctx); - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - /* - * the add_interface code must make sure we only ever - * have a single interface that could be beaconing at - * any time. - */ - if (vif->bss_conf.enable_beacon) - priv->beacon_ctx = ctx; - else - priv->beacon_ctx = NULL; - } - - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = ieee80211_beacon_get(hw, vif); - } - - if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) - iwl_send_rxon_timing(priv, ctx); - - if (changes & BSS_CHANGED_BSSID) { - IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); - - /* mac80211 only sets assoc when in STATION mode */ - if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - - /* currently needed in a few places */ - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - } else { - ctx->staging.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - } - - } - - /* - * This needs to be after setting the BSSID in case - * mac80211 decides to do both changes at once because - * it will invoke post_associate. - */ - if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) - iwlcore_beacon_update(hw, vif); - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - } - - if (changes & BSS_CHANGED_ERP_CTS_PROT) { - IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; - if (bss_conf->use_cts_prot) - ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; - else - ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; - } - - if (changes & BSS_CHANGED_BASIC_RATES) { - /* XXX use this information - * - * To do that, remove code from iwl_set_rate() and put something - * like this here: - * - if (A-band) - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates; - else - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates >> 4; - ctx->staging.cck_basic_rates = - bss_conf->basic_rates & 0xF; - */ - } - - if (changes & BSS_CHANGED_HT) { - iwl_ht_conf(priv, vif); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - if (changes & BSS_CHANGED_ASSOC) { - IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); - if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; - - iwl_led_associate(priv); - - if (!iwl_is_rfkill(priv)) - priv->cfg->ops->lib->post_associate(priv, vif); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { - IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", - changes); - ret = iwl_send_rxon_assoc(priv, ctx); - if (!ret) { - /* Sync active_rxon with latest change. */ - memcpy((void *)&ctx->active, - &ctx->staging, - sizeof(struct iwl_rxon_cmd)); - } - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - if (vif->bss_conf.enable_beacon) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - iwl_led_associate(priv); - iwlcore_config_ap(priv, vif); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes & BSS_CHANGED_IBSS) { - ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif, - bss_conf->ibss_joined); - if (ret) - IWL_ERR(priv, "failed to %s IBSS station %pM\n", - bss_conf->ibss_joined ? "add" : "remove", - bss_conf->bssid); - } - - if (changes & BSS_CHANGED_IDLE && - priv->cfg->ops->hcmd->set_pan_params) { - if (priv->cfg->ops->hcmd->set_pan_params(priv)) - IWL_ERR(priv, "failed to update PAN params\n"); - } - -out: - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_bss_info_changed); - static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); @@ -1899,204 +1566,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_mac_remove_interface); -/** - * iwl_mac_config - mac80211 config callback - */ -int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) -{ - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = conf->channel; - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct iwl_rxon_context *ctx; - unsigned long flags = 0; - int ret = 0; - u16 ch; - int scan_active = 0; - - mutex_lock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - channel->hw_value, changed); - - if (unlikely(!priv->cfg->mod_params->disable_hw_scan && - test_bit(STATUS_SCANNING, &priv->status))) { - scan_active = 1; - IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); - } - - if (changed & (IEEE80211_CONF_CHANGE_SMPS | - IEEE80211_CONF_CHANGE_CHANNEL)) { - /* mac80211 uses static for non-HT which is what we want */ - priv->current_ht_config.smps = conf->smps_mode; - - /* - * Recalculate chain counts. - * - * If monitor mode is enabled then mac80211 will - * set up the SM PS mode to OFF if an HT channel is - * configured. - */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - for_each_context(priv, ctx) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - /* during scanning mac80211 will delay channel setting until - * scan finish with changed = 0 - */ - if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { - if (scan_active) - goto set_ch_out; - - ch = channel->hw_value; - ch_info = iwl_get_channel_info(priv, channel->band, ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - ret = -EINVAL; - goto set_ch_out; - } - - spin_lock_irqsave(&priv->lock, flags); - - for_each_context(priv, ctx) { - /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } - } else - ctx->ht.is_40mhz = false; - - /* - * Default to no protection. Protection mode will - * later be set from BSS config in iwl_ht_conf - */ - ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; - - iwl_set_rxon_channel(priv, channel, ctx); - iwl_set_rxon_ht(priv, ht_conf); - - iwl_set_flags_for_band(priv, ctx, channel->band, - ctx->vif); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->cfg->ops->lib->update_bcast_stations) - ret = priv->cfg->ops->lib->update_bcast_stations(priv); - - set_ch_out: - /* The list of supported rates and rate mask can be different - * for each band; since the band may have changed, reset - * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); - } - - if (changed & (IEEE80211_CONF_CHANGE_PS | - IEEE80211_CONF_CHANGE_IDLE)) { - ret = iwl_power_update_mode(priv, false); - if (ret) - IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", - priv->tx_power_user_lmt, conf->power_level); - - ret = iwl_set_tx_power(priv, conf->power_level, false); - if (ret) - IWL_ERR(priv, "Error sending TX power (%d)\n", ret); - } - - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - goto out; - } - - if (scan_active) - goto out; - - for_each_context(priv, ctx) { - if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); - else - IWL_DEBUG_INFO(priv, - "Not re-sending same RXON configuration.\n"); - } - -out: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - return ret; -} -EXPORT_SYMBOL(iwl_mac_config); - -void iwl_mac_reset_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - /* IBSS can only be the IWL_RXON_CTX_BSS context */ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - spin_lock_irqsave(&priv->lock, flags); - memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); - spin_unlock_irqrestore(&priv->lock, flags); - - spin_lock_irqsave(&priv->lock, flags); - - /* new association get rid of ibss beacon skb */ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = NULL; - - priv->timestamp = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_scan_cancel_timeout(priv, 100); - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - iwl_set_rate(priv); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_mac_reset_tsf); - int iwl_alloc_txq_mem(struct iwl_priv *priv) { if (!priv->txq) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 917d42eae55a..854613e4f2be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -193,9 +193,6 @@ struct iwl_lib_ops { /* power */ int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); - void (*post_associate)(struct iwl_priv *priv, - struct ieee80211_vif *vif); - void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif); irqreturn_t (*isr) (int irq, void *data); /* eeprom operations (as defined in iwl-eeprom.h) */ @@ -203,10 +200,6 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; - /* station management */ - int (*manage_ibss_station)(struct iwl_priv *priv, - struct ieee80211_vif *vif, bool add); - int (*update_bcast_stations)(struct iwl_priv *priv); /* recover from tx queue stall */ void (*recover_from_tx_stall)(unsigned long data); /* check for plcp health */ @@ -235,12 +228,22 @@ struct iwl_nic_ops { void (*additional_nic_config)(struct iwl_priv *priv); }; +struct iwl_legacy_ops { + void (*post_associate)(struct iwl_priv *priv); + void (*config_ap)(struct iwl_priv *priv); + /* station management */ + int (*update_bcast_stations)(struct iwl_priv *priv); + int (*manage_ibss_station)(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add); +}; + struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; const struct iwl_led_ops *led; const struct iwl_nic_ops *nic; + const struct iwl_legacy_ops *legacy; const struct ieee80211_ops *ieee80211_ops; }; @@ -425,18 +428,10 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, u32 decrypt_res, struct ieee80211_rx_status *stats); void iwl_irq_handle_error(struct iwl_priv *priv); -void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); -void iwl_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); -void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif); -void iwl_mac_reset_tsf(struct ieee80211_hw *hw); int iwl_alloc_txq_mem(struct iwl_priv *priv); void iwl_free_txq_mem(struct iwl_priv *priv); void iwlcore_tx_cmd_protection(struct iwl_priv *priv, @@ -732,11 +727,6 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv, { return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); } -static inline void iwlcore_config_ap(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - priv->cfg->ops->lib->config_ap(priv, vif); -} static inline const struct ieee80211_supported_band *iwl_get_hw_mode( struct iwl_priv *priv, enum ieee80211_band band) { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index cd6daed99931..9fcaaf0cfe93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1162,6 +1162,8 @@ struct iwl_rxon_context { */ bool always_active, is_active; + bool ht_need_multiple_chains; + enum iwl_rxon_context_id ctxid; u32 interface_modes, exclusive_interface_modes; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 86c2b6fed0c6..5a9129219c90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -134,6 +134,7 @@ int iwl_led_associate(struct iwl_priv *priv) return 0; } +EXPORT_SYMBOL(iwl_led_associate); int iwl_led_disassociate(struct iwl_priv *priv) { @@ -141,6 +142,7 @@ int iwl_led_disassociate(struct iwl_priv *priv) return 0; } +EXPORT_SYMBOL(iwl_led_disassociate); /* * calculate blink rate according to last second Tx/Rx activities diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c new file mode 100644 index 000000000000..b735fef9ee4b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -0,0 +1,560 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-legacy.h" + +/** + * iwl_legacy_mac_config - mac80211 config callback + */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct iwl_rxon_context *ctx; + unsigned long flags = 0; + int ret = 0; + u16 ch; + int scan_active = 0; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return -EOPNOTSUPP; + + mutex_lock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", + channel->hw_value, changed); + + if (unlikely(!priv->cfg->mod_params->disable_hw_scan && + test_bit(STATUS_SCANNING, &priv->status))) { + scan_active = 1; + IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); + } + + if (changed & (IEEE80211_CONF_CHANGE_SMPS | + IEEE80211_CONF_CHANGE_CHANNEL)) { + /* mac80211 uses static for non-HT which is what we want */ + priv->current_ht_config.smps = conf->smps_mode; + + /* + * Recalculate chain counts. + * + * If monitor mode is enabled then mac80211 will + * set up the SM PS mode to OFF if an HT channel is + * configured. + */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + /* during scanning mac80211 will delay channel setting until + * scan finish with changed = 0 + */ + if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { + if (scan_active) + goto set_ch_out; + + ch = channel->hw_value; + ch_info = iwl_get_channel_info(priv, channel->band, ch); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); + ret = -EINVAL; + goto set_ch_out; + } + + spin_lock_irqsave(&priv->lock, flags); + + for_each_context(priv, ctx) { + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, ht_conf); + + iwl_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->cfg->ops->legacy->update_bcast_stations) + ret = priv->cfg->ops->legacy->update_bcast_stations(priv); + + set_ch_out: + /* The list of supported rates and rate mask can be different + * for each band; since the band may have changed, reset + * the rate mask to what mac80211 lists */ + iwl_set_rate(priv); + } + + if (changed & (IEEE80211_CONF_CHANGE_PS | + IEEE80211_CONF_CHANGE_IDLE)) { + ret = iwl_power_update_mode(priv, false); + if (ret) + IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", + priv->tx_power_user_lmt, conf->power_level); + + iwl_set_tx_power(priv, conf->power_level, false); + } + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + goto out; + } + + if (scan_active) + goto out; + + for_each_context(priv, ctx) { + if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); + else + IWL_DEBUG_INFO(priv, + "Not re-sending same RXON configuration.\n"); + } + +out: + IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); + return ret; +} +EXPORT_SYMBOL(iwl_legacy_mac_config); + +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + /* IBSS can only be the IWL_RXON_CTX_BSS context */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + mutex_lock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "enter\n"); + + spin_lock_irqsave(&priv->lock, flags); + memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); + spin_unlock_irqrestore(&priv->lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + + /* new association get rid of ibss beacon skb */ + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = NULL; + + priv->timestamp = 0; + + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_scan_cancel_timeout(priv, 100); + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + iwl_set_rate(priv); + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf); + +static void iwl_ht_conf(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct ieee80211_sta *sta; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + IWL_DEBUG_ASSOC(priv, "enter:\n"); + + if (!ctx->ht.enabled) + return; + + ctx->ht.protection = + bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; + ctx->ht.non_gf_sta_present = + !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + ht_conf->single_chain_sufficient = false; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + int maxstreams; + + maxstreams = (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) + >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + maxstreams += 1; + + if ((ht_cap->mcs.rx_mask[1] == 0) && + (ht_cap->mcs.rx_mask[2] == 0)) + ht_conf->single_chain_sufficient = true; + if (maxstreams <= 1) + ht_conf->single_chain_sufficient = true; + } else { + /* + * If at all, this can only happen through a race + * when the AP disconnects us while we're still + * setting up the connection, in that case mac80211 + * will soon tell us about that. + */ + ht_conf->single_chain_sufficient = true; + } + rcu_read_unlock(); + break; + case NL80211_IFTYPE_ADHOC: + ht_conf->single_chain_sufficient = true; + break; + default: + break; + } + + IWL_DEBUG_ASSOC(priv, "leave\n"); +} + +static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm, NULL); +} + +static inline void iwl_set_no_assoc(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + iwl_led_disassociate(priv); + /* + * inform the ucode that there is no longer an + * association and that no more packets should be + * sent + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ctx->staging.assoc_id = 0; + iwlcore_commit_rxon(priv, ctx); +} + +static void iwlcore_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); + + if (!skb) + return; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "update beacon but no beacon context!\n"); + dev_kfree_skb(skb); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = skb; + + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return; + } + + priv->cfg->ops->legacy->post_associate(priv); +} + +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + int ret; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); + + if (!iwl_is_alive(priv)) + return; + + mutex_lock(&priv->mutex); + + if (changes & BSS_CHANGED_QOS) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + ctx->qos_data.qos_active = bss_conf->qos; + iwl_update_qos(priv, ctx); + spin_unlock_irqrestore(&priv->lock, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + /* + * the add_interface code must make sure we only ever + * have a single interface that could be beaconing at + * any time. + */ + if (vif->bss_conf.enable_beacon) + priv->beacon_ctx = ctx; + else + priv->beacon_ctx = NULL; + } + + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(hw, vif); + } + + if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) + iwl_send_rxon_timing(priv, ctx); + + if (changes & BSS_CHANGED_BSSID) { + IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); + + /* + * If there is currently a HW scan going on in the + * background then we need to cancel it else the RXON + * below/in post_associate will fail. + */ + if (iwl_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); + IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* mac80211 only sets assoc when in STATION mode */ + if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + + /* currently needed in a few places */ + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + } else { + ctx->staging.filter_flags &= + ~RXON_FILTER_ASSOC_MSK; + } + + } + + /* + * This needs to be after setting the BSSID in case + * mac80211 decides to do both changes at once because + * it will invoke post_associate. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) + iwlcore_beacon_update(hw, vif); + + if (changes & BSS_CHANGED_ERP_PREAMBLE) { + IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", + bss_conf->use_short_preamble); + if (bss_conf->use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + } + + if (changes & BSS_CHANGED_ERP_CTS_PROT) { + IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); + if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + if (bss_conf->use_cts_prot) + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + else + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + } + + if (changes & BSS_CHANGED_BASIC_RATES) { + /* XXX use this information + * + * To do that, remove code from iwl_set_rate() and put something + * like this here: + * + if (A-band) + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates; + else + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates >> 4; + ctx->staging.cck_basic_rates = + bss_conf->basic_rates & 0xF; + */ + } + + if (changes & BSS_CHANGED_HT) { + iwl_ht_conf(priv, vif); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + if (changes & BSS_CHANGED_ASSOC) { + IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); + if (bss_conf->assoc) { + priv->timestamp = bss_conf->timestamp; + + iwl_led_associate(priv); + + if (!iwl_is_rfkill(priv)) + priv->cfg->ops->legacy->post_associate(priv); + } else + iwl_set_no_assoc(priv, vif); + } + + if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { + IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", + changes); + ret = iwl_send_rxon_assoc(priv, ctx); + if (!ret) { + /* Sync active_rxon with latest change. */ + memcpy((void *)&ctx->active, + &ctx->staging, + sizeof(struct iwl_rxon_cmd)); + } + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + if (vif->bss_conf.enable_beacon) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + iwl_led_associate(priv); + priv->cfg->ops->legacy->config_ap(priv); + } else + iwl_set_no_assoc(priv, vif); + } + + if (changes & BSS_CHANGED_IBSS) { + ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif, + bss_conf->ibss_joined); + if (ret) + IWL_ERR(priv, "failed to %s IBSS station %pM\n", + bss_conf->ibss_joined ? "add" : "remove", + bss_conf->bssid); + } + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h new file mode 100644 index 000000000000..2a746cbc30fe --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * 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. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_legacy_h__ +#define __iwl_legacy_h__ + +/* mac80211 handlers */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes); + +#endif /* __iwl_legacy_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d42bb22e5ed5..73f2f3fcb49c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -61,6 +61,7 @@ #include "iwl-helpers.h" #include "iwl-dev.h" #include "iwl-spectrum.h" +#include "iwl-legacy.h" /* * module name, copyright, version, etc. @@ -3057,22 +3058,22 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } -void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) +void iwl3945_post_associate(struct iwl_priv *priv) { int rc = 0; struct ieee80211_conf *conf = NULL; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (!vif || !priv->is_open) + if (!ctx->vif || !priv->is_open) return; - if (vif->type == NL80211_IFTYPE_AP) { + if (ctx->vif->type == NL80211_IFTYPE_AP) { IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); return; } IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, ctx->active.bssid_addr); + ctx->vif->bss_conf.aid, ctx->active.bssid_addr); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -3091,18 +3092,18 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - vif->bss_conf.aid, vif->bss_conf.beacon_int); + ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); - if (vif->bss_conf.use_short_preamble) + if (ctx->vif->bss_conf.use_short_preamble) ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) + if (ctx->vif->bss_conf.use_short_slot) ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; @@ -3110,7 +3111,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) iwl3945_commit_rxon(priv, ctx); - switch (vif->type) { + switch (ctx->vif->type) { case NL80211_IFTYPE_STATION: iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); break; @@ -3119,7 +3120,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) break; default: IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, vif->type); + __func__, ctx->vif->type); break; } } @@ -3234,9 +3235,10 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) +void iwl3945_config_ap(struct iwl_priv *priv) { struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; int rc = 0; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) @@ -3830,12 +3832,12 @@ struct ieee80211_ops iwl3945_hw_ops = { .stop = iwl3945_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, - .config = iwl_mac_config, + .config = iwl_legacy_mac_config, .configure_filter = iwl3945_configure_filter, .set_key = iwl3945_mac_set_key, .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_mac_reset_tsf, - .bss_info_changed = iwl_bss_info_changed, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, .hw_scan = iwl_mac_hw_scan, .sta_add = iwl3945_mac_sta_add, .sta_remove = iwl_mac_sta_remove, -- cgit v1.2.3-59-g8ed1b From bd50a8ab9f48787109f6ff761c8f0e185e3d0690 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 23 Oct 2010 09:15:42 -0700 Subject: iwlwifi: fix IBSS beaconing My previous patch to clean up all RXON handling inadvertently broke IBSS because it failed to take into account that unlike in AP mode, IBSS requires beacons to be sent only after setting the RXON assoc. Fix this, clean up the code a bit, improve the error checking around this, and also react to beacon changes in IBSS mode from mac80211. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 47 ++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58602457e415..11b3d8888360 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -72,6 +72,18 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, return ret; } +static int iwlagn_update_beacon(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + lockdep_assert_held(&priv->mutex); + + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); + if (!priv->beacon_skb) + return -ENOMEM; + return iwlagn_send_beacon_cmd(priv); +} + /** * iwlagn_commit_rxon - commit staging_rxon to hardware * @@ -201,17 +213,19 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } if (new_assoc) { - if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP || - ctx->vif->type == NL80211_IFTYPE_ADHOC)) { - /* - * We'll run into this code path when beaconing is - * enabled, but then we also need to send the beacon - * to the device. - */ - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = ieee80211_beacon_get(priv->hw, - ctx->vif); - iwlagn_send_beacon_cmd(priv); + /* + * We'll run into this code path when beaconing is + * enabled, but then we also need to send the beacon + * to the device. + */ + if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) { + ret = iwlagn_update_beacon(priv, ctx->vif); + if (ret) { + IWL_ERR(priv, + "Error sending required beacon (%d)!\n", + ret); + return ret; + } } priv->start_calib = 0; @@ -228,6 +242,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return ret; } memcpy(active, &ctx->staging, sizeof(*active)); + + /* IBSS beacon needs to be sent after setting assoc */ + if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) + if (iwlagn_update_beacon(priv, ctx->vif)) + IWL_ERR(priv, "Error sending IBSS beacon\n"); } iwl_print_rx_config_cmd(priv, ctx); @@ -558,5 +577,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); } + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC && + priv->beacon_ctx) { + if (iwlagn_update_beacon(priv, vif)) + IWL_ERR(priv, "Error sending IBSS beacon\n"); + } + mutex_unlock(&priv->mutex); } -- cgit v1.2.3-59-g8ed1b From d4daaea656e0b5543c2e37c31934cea8f044b31e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 23 Oct 2010 09:15:43 -0700 Subject: iwlwifi: implement switching iftype while up Implement switching the interface while an interface is up in iwlwifi. Interfaces have to stay on the context they were created on. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 168 ++++++++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-core.h | 3 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 5 files changed, 130 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 8f07964e4305..6d313c817040 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2589,6 +2589,7 @@ struct ieee80211_ops iwl4965_hw_ops = { .stop = iwlagn_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, + .change_interface = iwl_mac_change_interface, .config = iwl_legacy_mac_config, .configure_filter = iwlagn_configure_filter, .set_key = iwlagn_mac_set_key, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1050f31d90a4..481c993c2491 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3909,6 +3909,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .stop = iwlagn_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, + .change_interface = iwl_mac_change_interface, .config = iwlagn_mac_config, .configure_filter = iwlagn_configure_filter, .set_key = iwlagn_mac_set_key, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 776713c6a7ff..180d09ec3136 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1427,10 +1427,8 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); -static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) +static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - iwl_connection_init_rx_config(priv, ctx); if (priv->cfg->ops->hcmd->set_rxon_chain) @@ -1439,12 +1437,49 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) return iwlcore_commit_rxon(priv, ctx); } +static int iwl_setup_interface(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct ieee80211_vif *vif = ctx->vif; + int err; + + lockdep_assert_held(&priv->mutex); + + /* + * This variable will be correct only when there's just + * a single context, but all code using it is for hardware + * that supports only one context. + */ + priv->iw_mode = vif->type; + + ctx->is_active = true; + + err = iwl_set_mode(priv, ctx); + if (err) { + if (!ctx->always_active) + ctx->is_active = false; + return err; + } + + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && + vif->type == NL80211_IFTYPE_ADHOC) { + /* + * pretend to have high BT traffic as long as we + * are operating in IBSS mode, as this will cause + * the rate scaling etc. to behave as intended. + */ + priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + } + + return 0; +} + int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *tmp, *ctx = NULL; - int err = 0; + int err; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", vif->type, vif->addr); @@ -1486,36 +1521,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) vif_priv->ctx = ctx; ctx->vif = vif; - /* - * This variable will be correct only when there's just - * a single context, but all code using it is for hardware - * that supports only one context. - */ - priv->iw_mode = vif->type; - - ctx->is_active = true; - - err = iwl_set_mode(priv, vif); - if (err) { - if (!ctx->always_active) - ctx->is_active = false; - goto out_err; - } - - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - vif->type == NL80211_IFTYPE_ADHOC) { - /* - * pretend to have high BT traffic as long as we - * are operating in IBSS mode, as this will cause - * the rate scaling etc. to behave as intended. - */ - priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; - } - goto out; + err = iwl_setup_interface(priv, ctx); + if (!err) + goto out; - out_err: ctx->vif = NULL; priv->iw_mode = NL80211_IFTYPE_STATION; out: @@ -1526,27 +1536,24 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) } EXPORT_SYMBOL(iwl_mac_add_interface); -void iwl_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void iwl_teardown_interface(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool mode_change) { - struct iwl_priv *priv = hw->priv; struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - mutex_lock(&priv->mutex); - - WARN_ON(ctx->vif != vif); - ctx->vif = NULL; + lockdep_assert_held(&priv->mutex); if (priv->scan_vif == vif) { iwl_scan_cancel_timeout(priv, 200); iwl_force_scan_end(priv); } - iwl_set_mode(priv, vif); - if (!ctx->always_active) - ctx->is_active = false; + if (!mode_change) { + iwl_set_mode(priv, ctx); + if (!ctx->always_active) + ctx->is_active = false; + } /* * When removing the IBSS interface, overwrite the @@ -1557,6 +1564,22 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, */ if (vif->type == NL80211_IFTYPE_ADHOC) priv->bt_traffic_load = priv->notif_bt_traffic_load; +} + +void iwl_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + mutex_lock(&priv->mutex); + + WARN_ON(ctx->vif != vif); + ctx->vif = NULL; + + iwl_teardown_interface(priv, vif, false); memset(priv->bssid, 0, ETH_ALEN); mutex_unlock(&priv->mutex); @@ -1908,6 +1931,63 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) return 0; } +int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum nl80211_iftype newtype, bool newp2p) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + struct iwl_rxon_context *tmp; + u32 interface_modes; + int err; + + newtype = ieee80211_iftype_p2p(newtype, newp2p); + + mutex_lock(&priv->mutex); + + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; + + if (!(interface_modes & BIT(newtype))) { + err = -EBUSY; + goto out; + } + + if (ctx->exclusive_interface_modes & BIT(newtype)) { + for_each_context(priv, tmp) { + if (ctx == tmp) + continue; + + if (!tmp->vif) + continue; + + /* + * The current mode switch would be exclusive, but + * another context is active ... refuse the switch. + */ + err = -EBUSY; + goto out; + } + } + + /* success */ + iwl_teardown_interface(priv, vif, true); + vif->type = newtype; + err = iwl_setup_interface(priv, ctx); + WARN_ON(err); + /* + * We've switched internally, but submitting to the + * device may have failed for some reason. Mask this + * error, because otherwise mac80211 will not switch + * (and set the interface type back) and we'll be + * out of sync with it. + */ + err = 0; + + out: + mutex_unlock(&priv->mutex); + return err; +} +EXPORT_SYMBOL(iwl_mac_change_interface); + /** * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 854613e4f2be..8fb063affac4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -432,6 +432,9 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int iwl_mac_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype newtype, bool newp2p); int iwl_alloc_txq_mem(struct iwl_priv *priv); void iwl_free_txq_mem(struct iwl_priv *priv); void iwlcore_tx_cmd_protection(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 73f2f3fcb49c..6152a86c19b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3832,6 +3832,7 @@ struct ieee80211_ops iwl3945_hw_ops = { .stop = iwl3945_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, + .change_interface = iwl_mac_change_interface, .config = iwl_legacy_mac_config, .configure_filter = iwl3945_configure_filter, .set_key = iwl3945_mac_set_key, -- cgit v1.2.3-59-g8ed1b From f5682c01eb85fce13d064d232c947322bd7e2631 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 23 Oct 2010 09:15:44 -0700 Subject: iwlagn: turn dynamic smps on while BT is on While BT is on and doing iscan and/or pscan, BT is in listen mode which will impact WiFi throughput, we need to enable dynamic smps in order to improve the rx throughput. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b01d81a3550b..3427fc2b7d68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1897,7 +1897,10 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) switch (priv->bt_traffic_load) { case IWL_BT_COEX_TRAFFIC_LOAD_NONE: - smps_request = IEEE80211_SMPS_AUTOMATIC; + if (priv->bt_status) + smps_request = IEEE80211_SMPS_DYNAMIC; + else + smps_request = IEEE80211_SMPS_AUTOMATIC; break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: smps_request = IEEE80211_SMPS_DYNAMIC; -- cgit v1.2.3-59-g8ed1b From 69d826b6c54de113f02a73990b6f6809289b48cc Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 23 Oct 2010 09:15:45 -0700 Subject: iwlwifi: add new devices to Kconfig Adding description to Kconfig to indicate more devices are being supported by iwlagn Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index b82364258dc5..ed424574160e 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -106,6 +106,9 @@ config IWL5000 Intel WiFi Link 1000BGN Intel Wireless WiFi 5150AGN Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN + Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B) + Intel WIreless WiFi Link 6050BGN Gen 2 Adapter + Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) config IWL3945 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" -- cgit v1.2.3-59-g8ed1b From 34d59c07e9ad7130813c28f8554ef1298af923b7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 23 Oct 2010 09:15:46 -0700 Subject: iwlagn: use 6000g2b uCode for 130 series devices For 130 series device, 6000g2b uCode will be used, no need to have additional defines for 130 devices, so remove those. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index eacbce0d88b6..b1816900980c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,13 +53,11 @@ #define IWL6000_UCODE_API_MAX 4 #define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 5 -#define IWL130_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 #define IWL6000G2_UCODE_API_MIN 4 -#define IWL130_UCODE_API_MIN 5 #define IWL6000_FW_PRE "iwlwifi-6000-" #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" @@ -77,10 +75,6 @@ #define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" #define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) -#define IWL130_FW_PRE "iwlwifi-130-" -#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode" -#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api) - static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { /* want Celsius */ @@ -838,8 +832,8 @@ struct iwl_cfg iwl6000_3agn_cfg = { struct iwl_cfg iwl130_bgn_cfg = { .name = "Intel(R) 130 Series 1x1 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL130_UCODE_API_MAX, - .ucode_api_min = IWL130_UCODE_API_MIN, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, @@ -858,8 +852,8 @@ struct iwl_cfg iwl130_bgn_cfg = { struct iwl_cfg iwl130_bg_cfg = { .name = "Intel(R) 130 Series 1x2 BG", .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL130_UCODE_API_MAX, - .ucode_api_min = IWL130_UCODE_API_MIN, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, @@ -878,4 +872,3 @@ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX)); -- cgit v1.2.3-59-g8ed1b From c8aea565e8f715d9f10064b1cbfbc15bf75df501 Mon Sep 17 00:00:00 2001 From: Gery Kahn Date: Tue, 5 Oct 2010 16:09:05 +0200 Subject: wl1271: ref_clock cosmetic changes Cosmetic cleanup for ref_clock code while configured by board. Signed-off-by: Gery Kahn Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_boot.c | 10 ++++------ include/linux/wl12xx.h | 8 ++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index b91021242098..5b190728ca55 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -471,20 +471,19 @@ int wl1271_boot(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; - int ref_clock = wl->ref_clock; wl1271_boot_hw_version(wl); - if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4) + if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; - else if (ref_clock == 1 || ref_clock == 3) + else if (wl->ref_clock == 1 || wl->ref_clock == 3) /* ref clk: 26/52 */ clk = 0x5; else return -EINVAL; - if (ref_clock != 0) { + if (wl->ref_clock != 0) { u16 val; /* Set clock type (open drain) */ val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); @@ -529,8 +528,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); - /* 2 */ - clk |= (ref_clock << 1) << 4; + clk |= (wl->ref_clock << 1) << 4; wl1271_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, &part_table[PART_WORK]); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 4f902e1908aa..bebb8efea0a6 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -24,6 +24,14 @@ #ifndef _LINUX_WL12XX_H #define _LINUX_WL12XX_H +/* The board reference clock values */ +enum { + WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ + WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ + WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ + WL12XX_REFCLOCK_54 = 3, /* 54 MHz */ +}; + struct wl12xx_platform_data { void (*set_power)(bool enable); /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ -- cgit v1.2.3-59-g8ed1b From 6c6e669ed6282788d6045397ce0f201edc400d9d Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 12 Oct 2010 14:49:09 +0200 Subject: wl1271: TX aggregation optimization In case the aggregation buffer is too small to hold all available packets, the buffer is transferred to the FW and no more packets are aggregated. Although there may be enough available TX blocks, no additional packets will be handled by the current TX work. Fix this by flushing the aggregation buffer when it's full, and continue transferring packets as long as there are enough available TX blocks. Signed-off-by: Ido Yariv Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_tx.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index e3dc13c4d01a..b13b37330036 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -52,7 +52,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, int id, ret = -EBUSY; if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) - return -EBUSY; + return -EAGAIN; /* allocate free identifier for the packet */ id = wl1271_tx_id(wl, skb); @@ -210,7 +210,8 @@ void wl1271_tx_work(struct work_struct *work) struct sk_buff *skb; bool woken_up = false; u32 sta_rates = 0; - u32 buf_offset; + u32 buf_offset = 0; + bool sent_packets = false; int ret; /* check if the rates supported by the AP have changed */ @@ -233,9 +234,6 @@ void wl1271_tx_work(struct work_struct *work) wl1271_acx_rate_policies(wl); } - /* Prepare the transfer buffer, by aggregating all - * available packets */ - buf_offset = 0; while ((skb = skb_dequeue(&wl->tx_queue))) { if (!woken_up) { ret = wl1271_ps_elp_wakeup(wl, false); @@ -245,10 +243,20 @@ void wl1271_tx_work(struct work_struct *work) } ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); - if (ret == -EBUSY) { + if (ret == -EAGAIN) { /* - * Either the firmware buffer is full, or the - * aggregation buffer is. + * Aggregation buffer is full. + * Flush buffer and try again. + */ + skb_queue_head(&wl->tx_queue, skb); + wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + sent_packets = true; + buf_offset = 0; + continue; + } else if (ret == -EBUSY) { + /* + * Firmware buffer is full. * Queue back last skb, and stop aggregating. */ skb_queue_head(&wl->tx_queue, skb); @@ -265,6 +273,9 @@ out_ack: if (buf_offset) { wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, buf_offset, true); + sent_packets = true; + } + if (sent_packets) { /* interrupt the firmware with the new packets */ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); } -- cgit v1.2.3-59-g8ed1b From a522550a283de31c7cfc30c7a129ce584e38c582 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 12 Oct 2010 14:49:10 +0200 Subject: wl1271: Fix TX starvation While wl1271_irq_work handles RX directly (by calling wl1271_rx), a different work is scheduled for transmitting packets. The IRQ work might handle more than one interrupt during a single call, including multiple TX completion interrupts. This might starve TX, since no packets are transmitted until all interrupts are handled. Fix this by calling the TX work function directly, instead of deferring it. Signed-off-by: Ido Yariv Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_main.c | 19 +++++++++++++++---- drivers/net/wireless/wl12xx/wl1271_tx.c | 14 ++++++++++---- drivers/net/wireless/wl12xx/wl1271_tx.h | 1 + 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 8a4cd763e5a2..4a034a3f7148 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -351,6 +351,7 @@ struct wl1271 { #define WL1271_FLAG_IDLE_REQUESTED (11) #define WL1271_FLAG_PSPOLL_FAILURE (12) #define WL1271_FLAG_STA_STATE_SENT (13) +#define WL1271_FLAG_FW_TX_BUSY (14) unsigned long flags; struct wl1271_partition_set part; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 48a4b9961ae6..18aff225bf82 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -481,9 +481,9 @@ static void wl1271_fw_status(struct wl1271 *wl, total += cnt; } - /* if more blocks are available now, schedule some tx work */ - if (total && !skb_queue_empty(&wl->tx_queue)) - ieee80211_queue_work(wl->hw, &wl->tx_work); + /* if more blocks are available now, tx work can be scheduled */ + if (total) + clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); /* update the host-chipset time offset */ getnstimeofday(&ts); @@ -537,6 +537,16 @@ static void wl1271_irq_work(struct work_struct *work) (wl->tx_results_count & 0xff)) wl1271_tx_complete(wl); + /* Check if any tx blocks were freed */ + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + !skb_queue_empty(&wl->tx_queue)) { + /* + * In order to avoid starvation of the TX path, + * call the work function directly. + */ + wl1271_tx_work_locked(wl); + } + wl1271_rx(wl, wl->fw_status); } @@ -867,7 +877,8 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * before that, the tx_work will not be initialized! */ - ieee80211_queue_work(wl->hw, &wl->tx_work); + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->tx_work); /* * The workqueue is slow to process the tx_queue and we need stop diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index b13b37330036..cf32a77a4ff5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -204,9 +204,8 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) return enabled_rates; } -void wl1271_tx_work(struct work_struct *work) +void wl1271_tx_work_locked(struct wl1271 *wl) { - struct wl1271 *wl = container_of(work, struct wl1271, tx_work); struct sk_buff *skb; bool woken_up = false; u32 sta_rates = 0; @@ -223,8 +222,6 @@ void wl1271_tx_work(struct work_struct *work) spin_unlock_irqrestore(&wl->wl_lock, flags); } - mutex_lock(&wl->mutex); - if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; @@ -260,6 +257,8 @@ void wl1271_tx_work(struct work_struct *work) * Queue back last skb, and stop aggregating. */ skb_queue_head(&wl->tx_queue, skb); + /* No work left, avoid scheduling redundant tx work */ + set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); goto out_ack; } else if (ret < 0) { dev_kfree_skb(skb); @@ -283,7 +282,14 @@ out_ack: out: if (woken_up) wl1271_ps_elp_sleep(wl); +} +void wl1271_tx_work(struct work_struct *work) +{ + struct wl1271 *wl = container_of(work, struct wl1271, tx_work); + + mutex_lock(&wl->mutex); + wl1271_tx_work_locked(wl); mutex_unlock(&wl->mutex); } diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index d12a129ad11c..f1c906519b7d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h @@ -140,6 +140,7 @@ static inline int wl1271_tx_get_queue(int queue) } void wl1271_tx_work(struct work_struct *work); +void wl1271_tx_work_locked(struct wl1271 *wl); void wl1271_tx_complete(struct wl1271 *wl); void wl1271_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); -- cgit v1.2.3-59-g8ed1b From 25eeb9e3876a161e3afcc820c6cb72e13f9b7c7e Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 12 Oct 2010 16:20:06 +0200 Subject: wl1271: Allocate TX descriptors more efficiently On each TX descriptor allocation, a free entry is found by traversing the TX descriptors array. Improve this by holding a bitmap of all TX descriptors, and using efficient bit operations to search for free entries. Signed-off-by: Ido Yariv Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_main.c | 1 + drivers/net/wireless/wl12xx/wl1271_tx.c | 38 ++++++++++++++++++------------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 4a034a3f7148..718e96d97d0b 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -398,6 +398,7 @@ struct wl1271 { struct work_struct tx_work; /* Pending TX frames */ + unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)]; struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; int tx_frames_cnt; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 18aff225bf82..0fd472597fa6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2532,6 +2532,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->sg_enabled = true; wl->hw_pg_ver = -1; + memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) wl->tx_frames[i] = NULL; diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index cf32a77a4ff5..85878e5e7526 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -30,17 +30,26 @@ #include "wl1271_ps.h" #include "wl1271_tx.h" -static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) +static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) { - int i; - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - if (wl->tx_frames[i] == NULL) { - wl->tx_frames[i] = skb; - wl->tx_frames_cnt++; - return i; - } + int id; + + id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS); + if (id >= ACX_TX_DESCRIPTORS) + return -EBUSY; + + __set_bit(id, wl->tx_frames_map); + wl->tx_frames[id] = skb; + wl->tx_frames_cnt++; + return id; +} - return -EBUSY; +static void wl1271_free_tx_id(struct wl1271 *wl, int id) +{ + if (__test_and_clear_bit(id, wl->tx_frames_map)) { + wl->tx_frames[id] = NULL; + wl->tx_frames_cnt--; + } } static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, @@ -55,7 +64,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, return -EAGAIN; /* allocate free identifier for the packet */ - id = wl1271_tx_id(wl, skb); + id = wl1271_alloc_tx_id(wl, skb); if (id < 0) return id; @@ -79,8 +88,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, "tx_allocate: size: %d, blocks: %d, id: %d", total_len, total_blocks, id); } else { - wl->tx_frames[id] = NULL; - wl->tx_frames_cnt--; + wl1271_free_tx_id(wl, id); } return ret; @@ -352,8 +360,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* return the packet to the stack */ ieee80211_tx_status(wl->hw, skb); - wl->tx_frames[result->id] = NULL; - wl->tx_frames_cnt--; + wl1271_free_tx_id(wl, result->id); } /* Called upon reception of a TX complete interrupt */ @@ -422,11 +429,10 @@ void wl1271_tx_reset(struct wl1271 *wl) for (i = 0; i < ACX_TX_DESCRIPTORS; i++) if (wl->tx_frames[i] != NULL) { skb = wl->tx_frames[i]; - wl->tx_frames[i] = NULL; + wl1271_free_tx_id(wl, i); wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); ieee80211_tx_status(wl->hw, skb); } - wl->tx_frames_cnt = 0; } #define WL1271_TX_FLUSH_TIMEOUT 500000 -- cgit v1.2.3-59-g8ed1b From 2fe33e8cff354a3f320549544bffebbbab680145 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 12 Oct 2010 14:49:12 +0200 Subject: wl1271: Fix TX queue low watermark handling The number of entries in the TX queue is compared to the low watermark value each time TX completion interrupts are handled. However, the fact that a TX completion arrived does not necessarily mean there are any less skbs in the TX queue. In addition, a TX completion interrupt does not necessarily mean that there are any new available TX blocks. Thus, queuing TX work when the low watermark is reached might not be needed. Fix this by moving the low watermark handling to the TX work function, and avoid queuing TX work in this case. Signed-off-by: Ido Yariv Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_tx.c | 35 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 85878e5e7526..dc3172bea0dd 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -212,6 +212,20 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) return enabled_rates; } +static void handle_tx_low_watermark(struct wl1271 *wl) +{ + unsigned long flags; + + if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && + skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { + /* firmware buffer has space, restart queues */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + } +} + void wl1271_tx_work_locked(struct wl1271 *wl) { struct sk_buff *skb; @@ -225,6 +239,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags))) { unsigned long flags; + spin_lock_irqsave(&wl->wl_lock, flags); sta_rates = wl->sta_rate_set; spin_unlock_irqrestore(&wl->wl_lock, flags); @@ -285,6 +300,7 @@ out_ack: if (sent_packets) { /* interrupt the firmware with the new packets */ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); + handle_tx_low_watermark(wl); } out: @@ -399,19 +415,6 @@ void wl1271_tx_complete(struct wl1271 *wl) wl->tx_results_count++; } - - if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { - unsigned long flags; - - /* firmware buffer has space, restart queues */ - wl1271_debug(DEBUG_TX, "tx_complete: waking queues"); - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - ieee80211_queue_work(wl->hw, &wl->tx_work); - } } /* caller must hold wl->mutex */ @@ -426,6 +429,12 @@ void wl1271_tx_reset(struct wl1271 *wl) ieee80211_tx_status(wl->hw, skb); } + /* + * Make sure the driver is at a consistent state, in case this + * function is called from a context other than interface removal. + */ + handle_tx_low_watermark(wl); + for (i = 0; i < ACX_TX_DESCRIPTORS; i++) if (wl->tx_frames[i] != NULL) { skb = wl->tx_frames[i]; -- cgit v1.2.3-59-g8ed1b From e8b03a2b8debc6056f6f43d24f98f601097301a1 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Wed, 13 Oct 2010 16:09:39 +0200 Subject: wl1271: 11n Support, Add Definitions Two acx commands: ht_capabilities & ht_information, 11n sta capabilities macro. Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 11 ++++- drivers/net/wireless/wl12xx/wl1271_acx.h | 81 +++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_main.c | 15 ++++++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 718e96d97d0b..ab53162b4343 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -434,7 +434,12 @@ struct wl1271 { /* Our association ID */ u16 aid; - /* currently configured rate set */ + /* + * currently configured rate set: + * bits 0-15 - 802.11abg rates + * bits 16-23 - 802.11n MCS index mask + * support only 1 stream, thus only 8 bits for the MCS rates (0-7). + */ u32 sta_rate_set; u32 basic_rate_set; u32 basic_rate; @@ -511,4 +516,8 @@ int wl1271_plt_stop(struct wl1271 *wl); #define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ +/* Macros to handle wl1271.sta_rate_set */ +#define HW_BG_RATES_MASK 0xffff +#define HW_HT_RATES_OFFSET 16 + #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index ebb341d36e8c..f090a0470ebc 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -964,6 +964,87 @@ struct wl1271_acx_rssi_snr_avg_weights { u8 snr_data; }; +/* + * ACX_PEER_HT_CAP + * Configure HT capabilities - declare the capabilities of the peer + * we are connected to. + */ +struct wl1271_acx_ht_capabilities { + struct acx_header header; + + /* + * bit 0 - Allow HT Operation + * bit 1 - Allow Greenfield format in TX + * bit 2 - Allow Short GI in TX + * bit 3 - Allow L-SIG TXOP Protection in TX + * bit 4 - Allow HT Control fields in TX. + * Note, driver will still leave space for HT control in packets + * regardless of the value of this field. FW will be responsible + * to drop the HT field from any frame when this Bit set to 0. + * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD. + * Exact policy setting for this feature is TBD. + * Note, this bit can only be set to 1 if bit 3 is set to 1. + */ + __le32 ht_capabilites; + + /* + * Indicates to which peer these capabilities apply. + * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance + * for all peers. + * Only valid for IBSS/DLS operation. + */ + u8 mac_address[ETH_ALEN]; + + /* + * This the maximum A-MPDU length supported by the AP. The FW may not + * exceed this length when sending A-MPDUs + */ + u8 ampdu_max_length; + + /* This is the minimal spacing required when sending A-MPDUs to the AP*/ + u8 ampdu_min_spacing; +} __packed; + +/* HT Capabilites Fw Bit Mask Mapping */ +#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0) +#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1) +#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2) +#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3) +#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4) +#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5) + + +/* + * ACX_HT_BSS_OPERATION + * Configure HT capabilities - AP rules for behavior in the BSS. + */ +struct wl1271_acx_ht_information { + struct acx_header header; + + /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */ + u8 rifs_mode; + + /* Values: 0 - 3 like in spec */ + u8 ht_protection; + + /* Values: 0 - GF protection not required, 1 - GF protection required */ + u8 gf_protection; + + /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/ + u8 ht_tx_burst_limit; + + /* + * Values: 0 - Dual CTS protection not required, + * 1 - Dual CTS Protection required + * Note: When this value is set to 1 FW will protect all TXOP with RTS + * frame and will not use CTS-to-self regardless of the value of the + * ACX_CTS_PROTECTION information element + */ + u8 dual_cts_protection; + + u8 padding[3]; +} __packed; + struct wl1271_acx_fw_tsf_information { struct acx_header header; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 0fd472597fa6..5d5f4c6a9644 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2145,6 +2145,21 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { 0 /* CONF_HW_RXTX_RATE_1 */ }; +/* 11n STA capabilities */ +#define HW_RX_HIGHEST_RATE 72 + +#define WL1271_HT_CAP { \ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ + .ht_supported = true, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ + .mcs = { \ + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ + .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ + }, \ +} + /* can't be const, mac80211 writes to this */ static struct ieee80211_supported_band wl1271_band_2ghz = { .channels = wl1271_channels, -- cgit v1.2.3-59-g8ed1b From c4db1c879679e795689ef3c9dd7d3f6568ea14c5 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Wed, 13 Oct 2010 16:09:40 +0200 Subject: wl1271: 11n Support, ACX Commands Added ACX command to the FW for 11n support. Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_acx.c | 83 ++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_acx.h | 5 ++ 2 files changed, 88 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 618993405262..bd7f95f4eef3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -1226,6 +1226,89 @@ out: return ret; } +int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, + struct ieee80211_sta_ht_cap *ht_cap, + bool allow_ht_operation) +{ + struct wl1271_acx_ht_capabilities *acx; + u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* Allow HT Operation ? */ + if (allow_ht_operation) { + acx->ht_capabilites = + WL1271_ACX_FW_CAP_HT_OPERATION; + if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; + if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; + if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; + + /* get data from A-MPDU parameters field */ + acx->ampdu_max_length = ht_cap->ampdu_factor; + acx->ampdu_min_spacing = ht_cap->ampdu_density; + + memcpy(acx->mac_address, mac_address, ETH_ALEN); + } else { /* HT operations are not allowed */ + acx->ht_capabilites = 0; + } + + ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx ht capabilities setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_set_ht_information(struct wl1271 *wl, + u16 ht_operation_mode) +{ + struct wl1271_acx_ht_information *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ht information setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ht_protection = + (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); + acx->rifs_mode = 0; + acx->gf_protection = 0; + acx->ht_tx_burst_limit = 0; + acx->dual_cts_protection = 0; + + ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx)); + + if (ret < 0) { + wl1271_warning("acx ht information setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) { struct wl1271_acx_fw_tsf_information *tsf_info; diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index f090a0470ebc..758916760912 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -1174,6 +1174,11 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, s16 thold, u8 hyst); int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); +int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, + struct ieee80211_sta_ht_cap *ht_cap, + bool allow_ht_operation); +int wl1271_acx_set_ht_information(struct wl1271 *wl, + u16 ht_operation_mode); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); #endif /* __WL1271_ACX_H__ */ -- cgit v1.2.3-59-g8ed1b From 18357850b694ba3fa29363c7d86ccd8783f4a065 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Wed, 13 Oct 2010 16:09:41 +0200 Subject: wl1271: 11n Support, functionality and configuration ability Add 11n ability in scan, connection and using MCS rates. The configuration is temporary due to the code incomplete and still in testing process. That plans to be remove in the future. Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 10 ++++ drivers/net/wireless/wl12xx/wl1271_main.c | 96 +++++++++++++++++++++++++------ drivers/net/wireless/wl12xx/wl1271_rx.c | 6 ++ drivers/net/wireless/wl12xx/wl1271_tx.c | 11 ++++ 4 files changed, 105 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index b447559f1db5..1b3b7bdd6a19 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -18,6 +18,16 @@ config WL1271 If you choose to build a module, it'll be called wl1271. Say N if unsure. +config WL1271_HT + bool "TI wl1271 802.11 HT support (EXPERIMENTAL)" + depends on WL1271 && EXPERIMENTAL + default n + ---help--- + This will enable 802.11 HT support for TI wl1271 chipset. + + That configuration is temporary due to the code incomplete and + still in testing process. + config WL1271_SPI tristate "TI wl1271 SPI support" depends on WL1271 && SPI_MASTER diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 5d5f4c6a9644..532ccd01cf6f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -861,12 +861,32 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ieee80211_sta *sta = txinfo->control.sta; unsigned long flags; - /* peek into the rates configured in the STA entry */ + /* + * peek into the rates configured in the STA entry. + * The rates set after connection stage, The first block only BG sets: + * the compare is for bit 0-16 of sta_rate_set. The second block add + * HT rates in case of HT supported. + */ spin_lock_irqsave(&wl->wl_lock, flags); - if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) { + if (sta && + (sta->supp_rates[conf->channel->band] != + (wl->sta_rate_set & HW_BG_RATES_MASK))) { wl->sta_rate_set = sta->supp_rates[conf->channel->band]; set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); } + +#ifdef CONFIG_WL1271_HT + if (sta && + sta->ht_cap.ht_supported && + ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != + sta->ht_cap.mcs.rx_mask[0])) { + /* Clean MCS bits before setting them */ + wl->sta_rate_set &= HW_BG_RATES_MASK; + wl->sta_rate_set |= + (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); + set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); + } +#endif spin_unlock_irqrestore(&wl->wl_lock, flags); /* queue the packet */ @@ -1720,6 +1740,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, { enum wl1271_cmd_ps_mode mode; struct wl1271 *wl = hw->priv; + struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); bool do_join = false; bool set_assoc = false; int ret; @@ -1938,6 +1959,37 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, } } + /* + * Takes care of: New association with HT enable, + * HT information change in beacon. + */ + if (sta && + (changed & BSS_CHANGED_HT) && + (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); + if (ret < 0) { + wl1271_warning("Set ht cap true failed %d", ret); + goto out_sleep; + } + ret = wl1271_acx_set_ht_information(wl, + bss_conf->ht_operation_mode); + if (ret < 0) { + wl1271_warning("Set ht information failed %d", ret); + goto out_sleep; + } + } + /* + * Takes care of: New association without HT, + * Disassociation. + */ + else if (sta && (changed & BSS_CHANGED_ASSOC)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); + if (ret < 0) { + wl1271_warning("Set ht cap false failed %d", ret); + goto out_sleep; + } + } + if (changed & BSS_CHANGED_ARP_FILTER) { __be32 addr = bss_conf->arp_addr_list[0]; WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); @@ -2118,14 +2170,14 @@ static struct ieee80211_channel wl1271_channels[] = { /* mapping to indexes for wl1271_rates */ static const u8 wl1271_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ + 7, /* CONF_HW_RXTX_RATE_MCS7 */ + 6, /* CONF_HW_RXTX_RATE_MCS6 */ + 5, /* CONF_HW_RXTX_RATE_MCS5 */ + 4, /* CONF_HW_RXTX_RATE_MCS4 */ + 3, /* CONF_HW_RXTX_RATE_MCS3 */ + 2, /* CONF_HW_RXTX_RATE_MCS2 */ + 1, /* CONF_HW_RXTX_RATE_MCS1 */ + 0, /* CONF_HW_RXTX_RATE_MCS0 */ 11, /* CONF_HW_RXTX_RATE_54 */ 10, /* CONF_HW_RXTX_RATE_48 */ @@ -2148,6 +2200,7 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { /* 11n STA capabilities */ #define HW_RX_HIGHEST_RATE 72 +#ifdef CONFIG_WL1271_HT #define WL1271_HT_CAP { \ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ .ht_supported = true, \ @@ -2159,6 +2212,11 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ }, \ } +#else +#define WL1271_HT_CAP { \ + .ht_supported = false, \ +} +#endif /* can't be const, mac80211 writes to this */ static struct ieee80211_supported_band wl1271_band_2ghz = { @@ -2166,6 +2224,7 @@ static struct ieee80211_supported_band wl1271_band_2ghz = { .n_channels = ARRAY_SIZE(wl1271_channels), .bitrates = wl1271_rates, .n_bitrates = ARRAY_SIZE(wl1271_rates), + .ht_cap = WL1271_HT_CAP, }; /* 5 GHz data rates for WL1273 */ @@ -2248,14 +2307,14 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = { /* mapping to indexes for wl1271_rates_5ghz */ static const u8 wl1271_rate_to_idx_5ghz[] = { /* MCS rates are used only with 11n */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ + 7, /* CONF_HW_RXTX_RATE_MCS7 */ + 6, /* CONF_HW_RXTX_RATE_MCS6 */ + 5, /* CONF_HW_RXTX_RATE_MCS5 */ + 4, /* CONF_HW_RXTX_RATE_MCS4 */ + 3, /* CONF_HW_RXTX_RATE_MCS3 */ + 2, /* CONF_HW_RXTX_RATE_MCS2 */ + 1, /* CONF_HW_RXTX_RATE_MCS1 */ + 0, /* CONF_HW_RXTX_RATE_MCS0 */ 7, /* CONF_HW_RXTX_RATE_54 */ 6, /* CONF_HW_RXTX_RATE_48 */ @@ -2280,6 +2339,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = { .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), .bitrates = wl1271_rates_5ghz, .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), + .ht_cap = WL1271_HT_CAP, }; static const u8 *wl1271_band_rate_to_idx[] = { diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index bea133b6e489..ac13f7d25219 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -53,6 +53,12 @@ static void wl1271_rx_status(struct wl1271 *wl, status->band = wl->band; status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); +#ifdef CONFIG_WL1271_HT + /* 11n support */ + if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) + status->flag |= RX_FLAG_HT; +#endif + status->signal = desc->rssi; /* diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index dc3172bea0dd..87a5aed00c8c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -209,6 +209,17 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) rate_set >>= 1; } +#ifdef CONFIG_WL1271_HT + /* MCS rates indication are on bits 16 - 23 */ + rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; + + for (bit = 0; bit < 8; bit++) { + if (rate_set & 0x1) + enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); + rate_set >>= 1; + } +#endif + return enabled_rates; } -- cgit v1.2.3-59-g8ed1b From 6a2de93b2553c2e9a72997370534993c85c1eee6 Mon Sep 17 00:00:00 2001 From: Teemu Paasikivi Date: Thu, 14 Oct 2010 11:00:04 +0200 Subject: wl1271: Fix warning about unsupported RX rate While scanning, it is possible that beacon and probe response frames are received on other band than configured to the driver. In rx status handling this has caused "Unsupported RX rate from HW" warnings. This patch changes the wl1271_rate_to_index function to take the band of the received frame as a parameter instead of using value configuret to wl->band. Signed-off-by: Teemu Paasikivi Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 6 +++--- drivers/net/wireless/wl12xx/wl1271_rx.c | 10 +++++++++- drivers/net/wireless/wl12xx/wl1271_rx.h | 2 +- drivers/net/wireless/wl12xx/wl1271_tx.c | 2 +- drivers/net/wireless/wl12xx/wl1271_tx.h | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 532ccd01cf6f..63036b53f9e4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2367,18 +2367,18 @@ static const struct ieee80211_ops wl1271_ops = { }; -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate) +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) { u8 idx; - BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); + BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { wl1271_error("Illegal RX rate from HW: %d", rate); return 0; } - idx = wl1271_band_rate_to_idx[wl->band][rate]; + idx = wl1271_band_rate_to_idx[band][rate]; if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { wl1271_error("Unsupported RX rate from HW: %d", rate); return 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index ac13f7d25219..35448e7c0dd5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -48,10 +48,18 @@ static void wl1271_rx_status(struct wl1271 *wl, struct ieee80211_rx_status *status, u8 beacon) { + enum ieee80211_band desc_band; + memset(status, 0, sizeof(struct ieee80211_rx_status)); status->band = wl->band; - status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); + + if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG) + desc_band = IEEE80211_BAND_2GHZ; + else + desc_band = IEEE80211_BAND_5GHZ; + + status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band); #ifdef CONFIG_WL1271_HT /* 11n support */ diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h index 13a232333b13..6d41981ce53f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.h +++ b/drivers/net/wireless/wl12xx/wl1271_rx.h @@ -116,6 +116,6 @@ struct wl1271_rx_descriptor { } __packed; void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 87a5aed00c8c..46fafe08f81a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -350,7 +350,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, if (result->status == TX_SUCCESS) { if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) info->flags |= IEEE80211_TX_STAT_ACK; - rate = wl1271_rate_to_idx(wl, result->rate_class_index); + rate = wl1271_rate_to_idx(result->rate_class_index, wl->band); retries = result->ack_failures; } else if (result->status == TX_RETRY_EXCEEDED) { wl->stats.excessive_retries++; diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index f1c906519b7d..9dc6f228c0de 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h @@ -144,7 +144,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl); void wl1271_tx_complete(struct wl1271 *wl); void wl1271_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); #endif -- cgit v1.2.3-59-g8ed1b From 5404643139c16e56d31a6ebd09cfa6db1eb03a36 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 20 Oct 2010 15:15:52 +0300 Subject: wl1271: exit ELP mode when setting enabled rates in tx This bug was being triggered by a call to acx_rate_policies in tx_work without calling ps_elp_wakeup first. If we have full PSM enabled, this happens rather often, immediately after association. Reported-by: Tuomas Katila Signed-off-by: Luciano Coelho Tested-by: Tuomas Katila --- drivers/net/wireless/wl12xx/wl1271_tx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 46fafe08f81a..279be5b98d9f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -261,6 +261,11 @@ void wl1271_tx_work_locked(struct wl1271 *wl) /* if rates have changed, re-configure the rate policy */ if (unlikely(sta_rates)) { + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + woken_up = true; + wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); wl1271_acx_rate_policies(wl); } -- cgit v1.2.3-59-g8ed1b From ff6d76fd3d45ed5494287e57d76073739721214b Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 25 Oct 2010 15:30:03 +0200 Subject: wireless/wl1271: remove redundant if-statement v2 wl1271_ps_elp_sleep() is void and cannot return a value. Signed-off-by: Nicolas Kaiser Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_event.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 7b3f50382963..38ccef7d73a5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -134,8 +134,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl, /* go to extremely low power mode */ wl1271_ps_elp_sleep(wl); - if (ret < 0) - break; break; case EVENT_EXIT_POWER_SAVE_FAIL: wl1271_debug(DEBUG_PSM, "PSM exit failed"); -- cgit v1.2.3-59-g8ed1b From fb2382c75b1292aff0ebc8e209b0cb9ba70bb2cf Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 25 Oct 2010 11:24:29 +0200 Subject: wl1271: Fix RX path stall The wl1271_rx function loops through packets in an aggregated buffer. Each packet in the buffer is handled by a call to wl1271_rx_handle_data, which will fail if skb memory allocation fails or production mode is enabled. These failures currently prevent the rx counters to be incremented, thus causing the rx loop to run forever. Fix this by ignoring error codes reported wl1271_rx_handle_data function. This essentially means that frames will be dropped in production mode, which is the intetion, and frames will be dropped if memory allocation fails, which is a decent way to recover from that situation. Signed-off-by: Juuso Oikarinen Tested-by: Tuomas Katila Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_rx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 35448e7c0dd5..cacfee56a0d0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -184,10 +184,14 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) while (pkt_offset < buf_size) { pkt_length = wl1271_rx_get_buf_size(status, drv_rx_counter); - if (wl1271_rx_handle_data(wl, - wl->aggr_buf + pkt_offset, - pkt_length) < 0) - break; + /* + * the handle data call can only fail in memory-outage + * conditions, in that case the received frame will just + * be dropped. + */ + wl1271_rx_handle_data(wl, + wl->aggr_buf + pkt_offset, + pkt_length); wl->rx_counter++; drv_rx_counter++; drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; -- cgit v1.2.3-59-g8ed1b From b739a42c921dcb0ae92cc14032b7f75dcba88e3b Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 26 Oct 2010 13:24:38 +0200 Subject: wl1271: Fix scan failure detection In scan_complete_work, because the mutex is released before accessing the scan->failed flag, it is possible for unfounded hardware recovery rounds to be executed. Fix this. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 17 ++++++++++++++--- drivers/net/wireless/wl12xx/wl1271_scan.c | 5 +++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 63036b53f9e4..bec2b3d78782 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1056,6 +1056,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; + wl->scan.req = NULL; ieee80211_scan_completed(wl->hw, true); } @@ -1676,6 +1677,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); + if (wl->state == WL1271_STATE_OFF) { + /* + * We cannot return -EBUSY here because cfg80211 will expect + * a call to ieee80211_scan_completed if we do - in this case + * there won't be any call. + */ + ret = -EAGAIN; + goto out; + } + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; @@ -2093,14 +2104,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, { struct wl1271 *wl = hw->priv; struct ieee80211_conf *conf = &hw->conf; - + if (idx != 0) return -ENOENT; - + survey->channel = conf->channel; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = wl->noise; - + return 0; } diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 909bb47995b6..e0661a543a35 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -48,14 +48,15 @@ void wl1271_scan_complete_work(struct work_struct *work) wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; - mutex_unlock(&wl->mutex); - + wl->scan.req = NULL; ieee80211_scan_completed(wl->hw, false); if (wl->scan.failed) { wl1271_info("Scan completed due to error."); ieee80211_queue_work(wl->hw, &wl->recovery_work); } + mutex_unlock(&wl->mutex); + } -- cgit v1.2.3-59-g8ed1b From f8d9802f66eda9ff14f7667f99a46b31e9a9e273 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 26 Oct 2010 13:24:39 +0200 Subject: wl1271: Check interface state in op_* functions Check the state of the interface on op_* function so we don't try to access the hardware in when its off. The mac80211 may call these in some corner cases related, for instance, to the hardware recovery procedure. These accesses cause a kernel crash on at least some SDIO devices, because the bus is not properly claimed in that scenario. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index bec2b3d78782..c54887c80646 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1344,8 +1344,10 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&wl->mutex); - if (unlikely(wl->state == WL1271_STATE_OFF)) + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; goto out; + } ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) @@ -1568,6 +1570,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out_unlock; + } + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out_unlock; @@ -1708,8 +1715,10 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) mutex_lock(&wl->mutex); - if (unlikely(wl->state == WL1271_STATE_OFF)) + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; goto out; + } ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) @@ -1760,6 +1769,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; @@ -2040,6 +2052,11 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; @@ -2083,6 +2100,9 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; -- cgit v1.2.3-59-g8ed1b From 71125abdf0c297adc00dc5632f0318b2397286f5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 28 Oct 2010 21:46:43 +0200 Subject: wl1271: set wl->vif only if add_interface succeeded. set wl->vif to the newly created interface only after the firmware booted successfully. on the way - make the function flow more clear. Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 33 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index c54887c80646..a3a1ebc578a3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -950,18 +950,19 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct wiphy *wiphy = hw->wiphy; int retries = WL1271_BOOT_RETRIES; int ret = 0; + bool booted = false; wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); mutex_lock(&wl->mutex); if (wl->vif) { + wl1271_debug(DEBUG_MAC80211, + "multiple vifs are not supported yet"); ret = -EBUSY; goto out; } - wl->vif = vif; - switch (vif->type) { case NL80211_IFTYPE_STATION: wl->bss_type = BSS_TYPE_STA_BSS; @@ -999,15 +1000,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, if (ret < 0) goto irq_disable; - wl->state = WL1271_STATE_ON; - wl1271_info("firmware booted (%s)", wl->chip.fw_ver); - - /* update hw/fw version info in wiphy struct */ - wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver, - sizeof(wiphy->fw_version)); - - goto out; + booted = true; + break; irq_disable: wl1271_disable_interrupts(wl); @@ -1025,8 +1019,21 @@ power_off: wl1271_power_off(wl); } - wl1271_error("firmware boot failed despite %d retries", - WL1271_BOOT_RETRIES); + if (!booted) { + wl1271_error("firmware boot failed despite %d retries", + WL1271_BOOT_RETRIES); + goto out; + } + + wl->vif = vif; + wl->state = WL1271_STATE_ON; + wl1271_info("firmware booted (%s)", wl->chip.fw_ver); + + /* update hw/fw version info in wiphy struct */ + wiphy->hw_version = wl->chip.id; + strncpy(wiphy->fw_version, wl->chip.fw_ver, + sizeof(wiphy->fw_version)); + out: mutex_unlock(&wl->mutex); -- cgit v1.2.3-59-g8ed1b From 03107a4b5923aa7767329e857caf227749087e47 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 27 Oct 2010 14:58:30 +0200 Subject: wl1271: refactor debugfs function generation code refactor wl1271_debugfs by using a format© function, instead of duplicating the code for each generated function. this change reduces about 3Kb from wl1271.ko Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_debugfs.c | 215 ++++++++++++++------------- 1 file changed, 111 insertions(+), 104 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c index 66c2b90ddfd4..3468b849852e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c @@ -35,17 +35,28 @@ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 /* debugfs macros idea from mac80211 */ +#define DEBUGFS_FORMAT_BUFFER_SIZE 100 +static int wl1271_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...) +{ + va_list args; + char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; + int res; -#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ + va_start(args, fmt); + res = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ struct wl1271 *wl = file->private_data; \ - char buf[buflen]; \ - int res; \ - \ - res = scnprintf(buf, buflen, fmt "\n", ##value); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ + return wl1271_format_buffer(userbuf, count, ppos, \ + fmt "\n", ##value); \ } \ \ static const struct file_operations name## _ops = { \ @@ -69,20 +80,17 @@ static const struct file_operations name## _ops = { \ wl->debugfs.name = NULL; \ } while (0) -#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \ +#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ static ssize_t sub## _ ##name## _read(struct file *file, \ char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ struct wl1271 *wl = file->private_data; \ - char buf[buflen]; \ - int res; \ \ wl1271_debugfs_update_stats(wl); \ \ - res = scnprintf(buf, buflen, fmt "\n", \ - wl->stats.fw_stats->sub.name); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ + return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ + wl->stats.fw_stats->sub.name); \ } \ \ static const struct file_operations sub## _ ##name## _ops = { \ @@ -126,100 +134,99 @@ static int wl1271_open_file_generic(struct inode *inode, struct file *file) return 0; } -DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u"); +DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); + +DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); +DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); +DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); +DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); +DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); +DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); + +DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); +DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); + +DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); +DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); +DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); +DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); +DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); +DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); +DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); +DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); + +DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); +DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); /* skipping wep.reserved */ -DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u"); +DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); +DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); +DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); + +DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); /* skipping cont_miss_bcns_spread for now */ -DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, - 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u"); - -DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count); -DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u", +DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); + +DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); +DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); + +DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); + +DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); +DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); +DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); +DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); +DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); + +DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); + +DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); + +DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); +DEBUGFS_READONLY_FILE(excessive_retries, "%u", wl->stats.excessive_retries); static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, -- cgit v1.2.3-59-g8ed1b From ccc83b046c03378bbaf7cf095d8d7e9b9abb24c5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 27 Oct 2010 14:09:57 +0200 Subject: wl1271: handle HW watchdog interrupt unmask the WL1271_ACX_INTR_WATCHDOG interrupt. when getting it - enqueue a recovery work and bail out. Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_acx.h | 3 ++- drivers/net/wireless/wl12xx/wl1271_main.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 758916760912..b7c490845f3e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -61,7 +61,8 @@ WL1271_ACX_INTR_HW_AVAILABLE | \ WL1271_ACX_INTR_DATA) -#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \ +#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ WL1271_ACX_INTR_EVENT_B | \ WL1271_ACX_INTR_HW_AVAILABLE | \ WL1271_ACX_INTR_DATA) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index a3a1ebc578a3..f5b1d19bc88d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -529,6 +529,15 @@ static void wl1271_irq_work(struct work_struct *work) intr &= WL1271_INTR_MASK; + if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { + wl1271_error("watchdog interrupt received! " + "starting recovery."); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + + /* restarting the chip. ignore any other interrupt. */ + goto out; + } + if (intr & WL1271_ACX_INTR_DATA) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); -- cgit v1.2.3-59-g8ed1b From e285a5250c0772c5596a9137041a96b2c1f744d6 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 27 Oct 2010 14:09:58 +0200 Subject: wl1271: add recover testmode command add RECOVER testmode command. this command triggers a recovery sequence (by enqueueing a recovery_work). Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_testmode.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index a3aa84386c88..55ec4428922b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c @@ -37,6 +37,7 @@ enum wl1271_tm_commands { WL1271_TM_CMD_CONFIGURE, WL1271_TM_CMD_NVS_PUSH, WL1271_TM_CMD_SET_PLT_MODE, + WL1271_TM_CMD_RECOVER, __WL1271_TM_CMD_AFTER_LAST }; @@ -248,6 +249,15 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) return ret; } +static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[]) +{ + wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover"); + + ieee80211_queue_work(wl->hw, &wl->recovery_work); + + return 0; +} + int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) { struct wl1271 *wl = hw->priv; @@ -272,6 +282,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) return wl1271_tm_cmd_nvs_push(wl, tb); case WL1271_TM_CMD_SET_PLT_MODE: return wl1271_tm_cmd_set_plt_mode(wl, tb); + case WL1271_TM_CMD_RECOVER: + return wl1271_tm_cmd_recover(wl, tb); default: return -EOPNOTSUPP; } -- cgit v1.2.3-59-g8ed1b From 19999792d2889350611ba9e346d6a2924959dc2d Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 28 Oct 2010 20:01:00 -0200 Subject: rtl8187b: do not do per packet TX AGC Clearing the per packet TX AGC for the RTL8187B device appears to increase its overall TX power. This allows the device to associate and a connection to be established using APs a little further away. This is in accordance to what is done for RTL8187L devices and also what Realtek drivers do. Tested-by: Thadeu Lima de Souza Cascardo Signed-off-by: Thadeu Lima de Souza Cascardo Cc: linux-wireless@vger.kernel.org Cc: Larry Finger Cc: Rogerio Luz Coelho Cc: Herton Ronaldo Krzesinski Cc: Hin-Tak Leung Cc: seno Tested-by: Herton Ronaldo Krzesinski Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 38fa8244cc96..6e26149809bf 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -775,10 +775,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); - reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); - reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT | - RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; - rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); @@ -929,6 +925,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) priv->rx_conf = reg; rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, RTL818X_TX_CONF_HW_SEQNUM | RTL818X_TX_CONF_DISREQQSIZE | -- cgit v1.2.3-59-g8ed1b From bdd7bd16439975133d36bcd7c9c489302a114525 Mon Sep 17 00:00:00 2001 From: Blaise Gassend Date: Thu, 28 Oct 2010 02:01:24 -0700 Subject: mac80211_hwsim: Incorporate txpower into rssi Up to now mac80211_hwsim has been reporting an rssi of -50. This patch improves the model slightly by returning txpower-50. This makes it easy to stimulate tests that need to see a varying rssi. Signed-off-by: Blaise Gassend Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7eaaa3bab547..454f045ddff3 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -309,6 +309,8 @@ struct mac80211_hwsim_data { */ u64 group; struct dentry *debugfs_group; + + int power_level; }; @@ -497,7 +499,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, rx_status.band = data->channel->band; rx_status.rate_idx = info->control.rates[0].idx; /* TODO: simulate real signal strength (and optional packet loss) */ - rx_status.signal = -50; + rx_status.signal = data->power_level - 50; if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -698,6 +700,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); data->channel = conf->channel; + data->power_level = conf->power_level; if (!data->started || !data->beacon_int) del_timer(&data->beacon_timer); else -- cgit v1.2.3-59-g8ed1b From 3f1240e4f4b249f2388903864bdc766973f76687 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 29 Oct 2010 22:44:59 +0200 Subject: carl9170: import hw/fw header updates This patch imports all shared header changes from carl9170fw.git. * add some strategic __aligned(4). This allows the compiler generate optimized code for architectures which can't access (unaligned/packed) data efficiently. ("ath9k_hw: optimize all descriptor access functions") * add a forgotten __CARL9170FW__ ifdef around a private firmware-internal struct. * GET_VAL macro helper Very useful for extracting data out of the bit-packed PHY registers. * cosmetic changes e.g.: _CCA_MINCCA_ to just _CCA_MIN_. * version bump 1.8.8.3 -> 1.9.0. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/fwcmd.h | 13 +++++++++---- drivers/net/wireless/ath/carl9170/hw.h | 7 ++++++- drivers/net/wireless/ath/carl9170/phy.h | 24 ++++++++++++------------ drivers/net/wireless/ath/carl9170/version.h | 6 +++--- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index d552166db505..3680dfc70f46 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -97,13 +97,13 @@ struct carl9170_set_key_cmd { __le16 type; u8 macAddr[6]; u32 key[4]; -} __packed; +} __packed __aligned(4); #define CARL9170_SET_KEY_CMD_SIZE 28 struct carl9170_disable_key_cmd { __le16 user; __le16 padding; -} __packed; +} __packed __aligned(4); #define CARL9170_DISABLE_KEY_CMD_SIZE 4 struct carl9170_u32_list { @@ -206,7 +206,7 @@ struct carl9170_cmd { struct carl9170_rx_filter_cmd rx_filter; u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; } __packed; -} __packed; +} __packed __aligned(4); #define CARL9170_TX_STATUS_QUEUE 3 #define CARL9170_TX_STATUS_QUEUE_S 0 @@ -216,6 +216,7 @@ struct carl9170_cmd { #define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) #define CARL9170_TX_STATUS_SUCCESS 0x80 +#ifdef __CARL9170FW__ /* * NOTE: * Both structs [carl9170_tx_status and _carl9170_tx_status] @@ -232,6 +233,8 @@ struct carl9170_tx_status { u8 tries:3; u8 success:1; } __packed; +#endif /* __CARL9170FW__ */ + struct _carl9170_tx_status { /* * This version should be immune to all alignment bugs. @@ -272,13 +275,15 @@ struct carl9170_rsp { struct carl9170_rf_init_result rf_init_res; struct carl9170_u32_list rreg_res; struct carl9170_u32_list echo; +#ifdef __CARL9170FW__ struct carl9170_tx_status tx_status[0]; +#endif /* __CARL9170FW__ */ struct _carl9170_tx_status _tx_status[0]; struct carl9170_gpio gpio; struct carl9170_tsf_rsp tsf; struct carl9170_psm psm; u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; } __packed; -} __packed; +} __packed __aligned(4); #endif /* __CARL9170_SHARED_FWCMD_H */ diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index 2f471b3f05af..e85df6edfed3 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -712,7 +712,8 @@ struct ar9170_stream { __le16 tag; u8 payload[0]; -}; +} __packed __aligned(4); +#define AR9170_STREAM_LEN 4 #define AR9170_MAX_ACKTABLE_ENTRIES 8 #define AR9170_MAX_VIRTUAL_MAC 7 @@ -736,4 +737,8 @@ struct ar9170_stream { #define MOD_VAL(reg, value, newvalue) \ (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) + +#define GET_VAL(reg, value) \ + (((value) & reg) >> reg##_S) + #endif /* __CARL9170_SHARED_HW_H */ diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h index 02c34eb4ebde..024fb42bc787 100644 --- a/drivers/net/wireless/ath/carl9170/phy.h +++ b/drivers/net/wireless/ath/carl9170/phy.h @@ -139,8 +139,8 @@ #define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 #define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) -#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000 -#define AR9170_PHY_CCA_MINCCA_PWR_S 19 +#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000 +#define AR9170_PHY_CCA_MIN_PWR_S 19 #define AR9170_PHY_CCA_THRESH62 0x0007f000 #define AR9170_PHY_CCA_THRESH62_S 12 @@ -338,8 +338,8 @@ #define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 #define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 #define AR9170_PHY_EXT_CCA_THRESH62_S 16 -#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000 -#define AR9170_PHY_EXT_MINCCA_PWR_S 23 +#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000 +#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23 #define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) #define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f @@ -546,19 +546,19 @@ #define AR9170_PHY_FORCE_XPA_CFG_S 0 #define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) -#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000 -#define AR9170_PHY_CH1_MINCCA_PWR_S 19 +#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000 +#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19 #define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) -#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000 -#define AR9170_PHY_CH2_MINCCA_PWR_S 19 +#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000 +#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19 #define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) -#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000 -#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23 +#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000 +#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23 #define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) -#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 -#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 +#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000 +#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23 #endif /* __CARL9170_SHARED_PHY_H */ diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index ff53f078a0b5..ee0f84f2a2f6 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,7 @@ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H #define CARL9170FW_VERSION_YEAR 10 -#define CARL9170FW_VERSION_MONTH 9 -#define CARL9170FW_VERSION_DAY 28 -#define CARL9170FW_VERSION_GIT "1.8.8.3" +#define CARL9170FW_VERSION_MONTH 10 +#define CARL9170FW_VERSION_DAY 29 +#define CARL9170FW_VERSION_GIT "1.9.0" #endif /* __CARL9170_SHARED_VERSION_H */ -- cgit v1.2.3-59-g8ed1b From e27769059ccb15273a7eb69ed31b8e08f9b0eda8 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 29 Oct 2010 23:17:38 +0200 Subject: carl9170: initialize HW aMPDU parameters properly This patch changes the initial aMPDU density and factor settings to match those of Otus. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index 2305bc27151c..c34eeeeb8af3 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar) carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); /* Aggregation MAX number and timeout */ - carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa); - carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00); + carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a); + carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07); carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, AR9170_MAC_FTF_DEFAULTS); -- cgit v1.2.3-59-g8ed1b From e4a668c59080f862af3ecc28b359533027cbe434 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 29 Oct 2010 23:26:13 +0200 Subject: carl9170: fix spurious restart due to high latency RX Stress tests of unidirectional bulk traffic with bitrates of up to 220Mbit/s have revealed that the fatal-event recovery logic [which was solely triggered by an out-of-rx-buffer situation] is too aggressive. The new method now "pings" the device and then decides - based on the response - whenever a restart is needed or not. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 3 ++- drivers/net/wireless/ath/carl9170/main.c | 17 +++++++++++++++++ drivers/net/wireless/ath/carl9170/usb.c | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index b69d31972c77..d07ff7f2fd92 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -215,7 +215,7 @@ enum carl9170_restart_reasons { CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, CARL9170_RR_WATCHDOG, CARL9170_RR_STUCK_TX, - CARL9170_RR_SLOW_SYSTEM, + CARL9170_RR_UNRESPONSIVE_DEVICE, CARL9170_RR_COMMAND_TIMEOUT, CARL9170_RR_TOO_MANY_PHY_ERRORS, CARL9170_RR_LOST_RSP, @@ -287,6 +287,7 @@ struct ar9170 { /* reset / stuck frames/queue detection */ struct work_struct restart_work; + struct work_struct ping_work; unsigned int restart_counter; unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index d521bc2b0496..4ae6a5849076 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar) cancel_delayed_work_sync(&ar->led_work); #endif /* CONFIG_CARL9170_LEDS */ cancel_work_sync(&ar->ps_work); + cancel_work_sync(&ar->ping_work); cancel_work_sync(&ar->ampdu_work); } @@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r) */ } +static void carl9170_ping_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, ping_work); + int err; + + if (!IS_STARTED(ar)) + return; + + mutex_lock(&ar->mutex); + err = carl9170_echo_test(ar, 0xdeadbeef); + if (err) + carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE); + mutex_unlock(&ar->mutex); +} + static int carl9170_init_interface(struct ar9170 *ar, struct ieee80211_vif *vif) { @@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size) skb_queue_head_init(&ar->tx_pending[i]); } INIT_WORK(&ar->ps_work, carl9170_ps_work); + INIT_WORK(&ar->ping_work, carl9170_ping_work); INIT_WORK(&ar->restart_work, carl9170_restart_work); INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index d8607f4c144d..ddf5373ee689 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -431,7 +431,7 @@ static void carl9170_usb_rx_complete(struct urb *urb) * device. */ - carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM); + ieee80211_queue_work(ar->hw, &ar->ping_work); } } else { /* -- cgit v1.2.3-59-g8ed1b From 2a6cef513fab525399e484edc9bfb39b6d462f76 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 29 Oct 2010 23:41:16 +0200 Subject: carl9170: stop stale uplink BA sessions This patch fixes a possible lengthy stall if the device is operating as an experimental 11n AP and an STA [during heavy txrx action] suddenly signalized to go off-channel (old NetworkManager), or (sleep - which is unlikely, because then it wouldn't be *active* at all!?). Because the driver has to manage the BA Window, the sudden PSM transition can leave active uplink BA sessions to the STA in a bad state and a proper cleanup is needed. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b575c865142d..b27969c41812 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -524,6 +524,59 @@ next: } } +static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) +{ + struct carl9170_sta_tid *iter; + struct sk_buff *skb; + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + struct _carl9170_tx_superframe *super; + struct ieee80211_sta *sta; + struct ieee80211_vif *vif; + struct ieee80211_hdr *hdr; + unsigned int vif_id; + + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { + if (iter->state < CARL9170_TID_STATE_IDLE) + continue; + + spin_lock_bh(&iter->lock); + skb = skb_peek(&iter->queue); + if (!skb) + goto unlock; + + txinfo = IEEE80211_SKB_CB(skb); + arinfo = (void *)txinfo->rate_driver_data; + if (time_is_after_jiffies(arinfo->timeout + + msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) + goto unlock; + + super = (void *) skb->data; + hdr = (void *) super->frame_data; + + vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> + CARL9170_TX_SUPER_MISC_VIF_ID_S; + + if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC)) + goto unlock; + + vif = rcu_dereference(ar->vif_priv[vif_id].vif); + if (WARN_ON(!vif)) + goto unlock; + + sta = ieee80211_find_sta(vif, hdr->addr1); + if (WARN_ON(!sta)) + goto unlock; + + ieee80211_stop_tx_ba_session(sta, iter->tid); +unlock: + spin_unlock_bh(&iter->lock); + + } + rcu_read_unlock(); +} + void carl9170_tx_janitor(struct work_struct *work) { struct ar9170 *ar = container_of(work, struct ar9170, @@ -534,6 +587,7 @@ void carl9170_tx_janitor(struct work_struct *work) ar->tx_janitor_last_run = jiffies; carl9170_check_queue_stop_timeout(ar); + carl9170_tx_ampdu_timeout(ar); if (!atomic_read(&ar->tx_total_queued)) return; -- cgit v1.2.3-59-g8ed1b From 3eedb6f436858f3e864139dc184adc9a51440c92 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 30 Oct 2010 00:36:53 +0200 Subject: carl9170: configurable beacon rates Previously, the beacon rate was fixed to either: * 1Mb/s [2.4GHz band] * 6Mb/s [5GHz band] This limitation has been addressed and now the beacon rate is selected by ieee80211_tx_info's rate control info, almost like any ordinary data frame. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/mac.c | 52 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index c34eeeeb8af3..385cf508479b 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar) int carl9170_update_beacon(struct ar9170 *ar, const bool submit) { - struct sk_buff *skb; + struct sk_buff *skb = NULL; struct carl9170_vif_info *cvif; + struct ieee80211_tx_info *txinfo; __le32 *data, *old = NULL; u32 word, off, addr, len; int i = 0, err = 0; @@ -487,7 +488,13 @@ found: if (!skb) { err = -ENOMEM; - goto out_unlock; + goto err_free; + } + + txinfo = IEEE80211_SKB_CB(skb); + if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) { + err = -EINVAL; + goto err_free; } spin_lock_bh(&ar->beacon_lock); @@ -504,11 +511,8 @@ found: wiphy_err(ar->hw->wiphy, "beacon does not " "fit into device memory!\n"); } - - spin_unlock_bh(&ar->beacon_lock); - dev_kfree_skb_any(skb); err = -EINVAL; - goto out_unlock; + goto err_unlock; } if (len > AR9170_MAC_BCN_LENGTH_MAX) { @@ -518,22 +522,22 @@ found: AR9170_MAC_BCN_LENGTH_MAX, len); } - spin_unlock_bh(&ar->beacon_lock); - dev_kfree_skb_any(skb); err = -EMSGSIZE; - goto out_unlock; + goto err_unlock; } - carl9170_async_regwrite_begin(ar); + i = txinfo->control.rates[0].idx; + if (txinfo->band != IEEE80211_BAND_2GHZ) + i += 4; - /* XXX: use skb->cb info */ - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { - carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); - } else { - carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + FCS_LEN) << 16) + 0x001b); - } + word = __carl9170_ratetable[i].hw_value & 0xf; + if (i < 4) + word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; + else + word |= ((skb->len + FCS_LEN) << 16) + 0x0010; + + carl9170_async_regwrite_begin(ar); + carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word); for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { /* @@ -557,7 +561,7 @@ found: cvif->beacon = skb; spin_unlock_bh(&ar->beacon_lock); if (err) - goto out_unlock; + goto err_free; if (submit) { err = carl9170_bcn_ctrl(ar, cvif->id, @@ -565,10 +569,18 @@ found: addr, skb->len + FCS_LEN); if (err) - goto out_unlock; + goto err_free; } out_unlock: rcu_read_unlock(); + return 0; + +err_unlock: + spin_unlock_bh(&ar->beacon_lock); + +err_free: + rcu_read_unlock(); + dev_kfree_skb_any(skb); return err; } -- cgit v1.2.3-59-g8ed1b From c0bf9ca98e07ca72c444a6cfb272aafa9890b9b6 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Mon, 1 Nov 2010 17:55:48 -0700 Subject: mwl8k: force AP mode to use non-AMPDU frames AP firmware uses xmitcontrol to differentiate between AMPDU and non-AMPDU frames. As the support for AMPDU is not yet added, set xmitcontrol to non-AMPDU for all tx frames for AP firmware. This field will be set to indicate ampdu/non-ampdu frames when tx AMPDU support is added. Signed-off-by: Pradeep Nemavat Signed-off-by: Brian Cavagnolo Acked-by: Lennert Buytenhek Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index f152a25be59f..1bbcd7c1d02a 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1125,10 +1125,12 @@ struct mwl8k_tx_desc { __le32 reserved; __le16 rate_info; __u8 peer_id; - __u8 tx_frag_cnt; + __u8 xmitcontrol; } __packed; #define MWL8K_TX_DESCS 128 +#define MWL8K_XMITCONTROL_NON_AMPDU 0x04 + static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) { @@ -1448,6 +1450,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; else tx->peer_id = 0; + + if (priv->ap_fw) + tx->xmitcontrol = MWL8K_XMITCONTROL_NON_AMPDU; wmb(); tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); -- cgit v1.2.3-59-g8ed1b From 327571ea9927beec2ee2ed9a266c57c1515393b4 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:31 -0200 Subject: rtl8187: remove redundant initialization of ARFR This removes redundant write to Auto Rate Fallback Register on RTL8187B. The same value was being written twice in the same function. Avoid this removing the duplicate initialization on rtl8187b_reg_table, and also add comment for this write (information from Realtek source). Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 6e26149809bf..3dbf3053c09f 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -712,10 +712,9 @@ static const u8 rtl8187b_reg_table[][3] = { {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1}, {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1}, - {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1}, - {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1}, - {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1}, - {0xF7, 0x07, 1}, {0xF8, 0x08, 1}, + {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, + {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, + {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1}, {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2}, {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2}, @@ -776,7 +775,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + /* Auto Rate Fallback Register (ARFR): 1M-54M setting */ rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1); rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); -- cgit v1.2.3-59-g8ed1b From f002c25cc13e86762551c0eda29a40c60d6dbf1b Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:32 -0200 Subject: rtl8187: remove setting of beacon/atim registers from initialization On 8187B path, we set a initial value for beacon interval and atim window on initialization. But this isn't needed, since same setup is done on rtl8187_config. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 3dbf3053c09f..30c2120dd302 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -779,8 +779,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1); - rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); - rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, -- cgit v1.2.3-59-g8ed1b From 60f589145d76cf834ec5e485c5412ec0994e52d1 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:33 -0200 Subject: rtl8187: fix wrong register initialization in 8187B We were using wrong address for BRSR (Basic Rate Set Register) while initializing its value, comparing with Realtek sources, for 8187B case. Also, the same register is initialized in rtl8187b_reg_table, so remove the duplicate initialization from the table. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 30c2120dd302..b9ce2a8739cd 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -725,11 +725,11 @@ static const u8 rtl8187b_reg_table[][3] = { {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2}, {0x73, 0x9A, 2}, - {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0}, - {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, - {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0}, - {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, - {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, + {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0}, + {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, + {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, + {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, + {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, {0x8F, 0x00, 0} @@ -770,7 +770,11 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) if (res) return res; - rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF); + /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as + * RESP_RATE on 8187L in Realtek sources: each bit should be each + * one of the 12 rates, all are enabled */ + rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF); + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); -- cgit v1.2.3-59-g8ed1b From a8ff34e37a186ebb7d2d90ee40ef88a3ef95ad47 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:34 -0200 Subject: rtl8187: avoid redundant write to register FF72 (RFSW_CTRL) The table with misc register initialization was setting it, and later on we would set it again with a explicity call to rtl818x_iowrite16_idx. Remove duplicate initialization from the register table. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index b9ce2a8739cd..063374aba863 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -722,8 +722,7 @@ static const u8 rtl8187b_reg_table[][3] = { {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2}, {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2}, {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2}, - {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2}, - {0x73, 0x9A, 2}, + {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, @@ -810,6 +809,7 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001); + /* RFSW_CTRL register */ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, -- cgit v1.2.3-59-g8ed1b From 896cae65fc0489b8e42bb7790f64731d53a2cecf Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:35 -0200 Subject: rtl8187: move pll reset at start out of ANAPARAM write On 8187B start, comment about pll reset, and move it out of ANAPARAM write sequence, so that code is more readable. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 063374aba863..2b4ee26c6745 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -742,7 +742,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT; rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); @@ -752,19 +751,19 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) RTL8187B_RTL8225_ANAPARAM_ON); rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, RTL8187B_RTL8225_ANAPARAM3_ON); - - rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); - reg = rtl818x_ioread8(priv, (u8 *)0xFF62); - rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); - rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + /* Reset PLL sequence on 8187B. Realtek note: reduces power + * consumption about 30 mA */ + rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); + reg = rtl818x_ioread8(priv, (u8 *)0xFF62); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); + res = rtl8187_cmd_reset(dev); if (res) return res; -- cgit v1.2.3-59-g8ed1b From fe3326903d7aafd7b5602d8e178537c8b0465f6c Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:36 -0200 Subject: rtl8187: don't set RTL818X_CONFIG3_GNT_SELECT flag on 8187B The GNTSel bit should only concern pci devices by looking at RTL8180 spec, which is not the case of 8187B. Also testing shows that trying to set this bit fails, a subsequent read from the register after trying to set it shows that the bit isn't set, seems the hardware ignores it, which makes sense. This setting was a left over from Realtek sources. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 2b4ee26c6745..d7ea5d1a2888 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -743,7 +743,7 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT; + reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187B_RTL8225_ANAPARAM2_ON); -- cgit v1.2.3-59-g8ed1b From 0bf198eb4d05a4662143e4a2e2a44fb592e2b177 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:37 -0200 Subject: rtl8187: consolidate anaparam on/off write sequences There are repeated calls for anaparam on/off sequence in the code. Consolidate the common code in rtl8187_set_anaparam and use it where needed. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 84 ++++++++++++++------------ drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | 22 ------- 2 files changed, 44 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index d7ea5d1a2888..c0c75aa13db2 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -553,6 +553,46 @@ static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) return ret; } +static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon) +{ + u32 anaparam, anaparam2; + u8 anaparam3, reg; + + if (!priv->is_rtl8187b) { + if (rfon) { + anaparam = RTL8187_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON; + } else { + anaparam = RTL8187_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF; + } + } else { + if (rfon) { + anaparam = RTL8187B_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON; + } else { + anaparam = RTL8187B_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF; + } + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); + if (priv->is_rtl8187b) + rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3); + reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + static int rtl8187_cmd_reset(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; @@ -603,19 +643,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) int res; /* reset */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | - RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, - RTL8187_RTL8225_ANAPARAM_ON); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187_RTL8225_ANAPARAM2_ON); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & - ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); + rtl8187_set_anaparam(priv, true); rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); @@ -629,17 +657,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) if (res) return res; - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, - RTL8187_RTL8225_ANAPARAM_ON); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187_RTL8225_ANAPARAM2_ON); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + rtl8187_set_anaparam(priv, true); /* setup card */ rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); @@ -740,22 +758,7 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) int res, i; u8 reg; - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187B_RTL8225_ANAPARAM2_ON); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, - RTL8187B_RTL8225_ANAPARAM_ON); - rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, - RTL8187B_RTL8225_ANAPARAM3_ON); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); + rtl8187_set_anaparam(priv, true); /* Reset PLL sequence on 8187B. Realtek note: reduces power * consumption about 30 mA */ @@ -1006,6 +1009,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev) rtl818x_iowrite8(priv, &priv->map->CMD, reg); priv->rf->stop(dev); + rtl8187_set_anaparam(priv, false); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index 97eebdcf7eb9..5c6666f09ac1 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c @@ -898,29 +898,7 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) static void rtl8225_rf_stop(struct ieee80211_hw *dev) { - u8 reg; - struct rtl8187_priv *priv = dev->priv; - rtl8225_write(dev, 0x4, 0x1f); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - if (!priv->is_rtl8187b) { - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187_RTL8225_ANAPARAM2_OFF); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, - RTL8187_RTL8225_ANAPARAM_OFF); - } else { - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187B_RTL8225_ANAPARAM2_OFF); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, - RTL8187B_RTL8225_ANAPARAM_OFF); - rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, - RTL8187B_RTL8225_ANAPARAM3_OFF); - } - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); } static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, -- cgit v1.2.3-59-g8ed1b From 998606cfd75e7a8169ed0d324061a8d6bc60716a Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:38 -0200 Subject: rtl8187: remove uneeded setting of anaparam write Usually you set RTL818X_CONFIG3_ANAPARAM_WRITE when you are going to change/write ANAPARAM registers. But in current initialization of RTL8187B there is a place where ANAPARAM_WRITE bit is set without any ANAPARAM register being written, without reason, so remove it. Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Cc: seno Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index c0c75aa13db2..4448647d6cf6 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -814,14 +814,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) /* RFSW_CTRL register */ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); -- cgit v1.2.3-59-g8ed1b From daeeb074105a80a34f90a454c24efc14e9a8d3c3 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 1 Nov 2010 22:59:39 -0200 Subject: rtl8187: restore anaparam registers after reset with 8187B Current 8187B initialization misses anaparam registers restore after 8187 reset. This causes ANAPARAM register to stay zeroed out (ANAPARAM2 kept its value on my tests). To avoid this, call rtl8187_set_anaparam right after chip reset (to be on the safe side, as it makes sure we restore all ANAPARAM registers). Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Larry Finger Cc: seno Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 4448647d6cf6..eeee244fcaab 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -771,6 +771,8 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) if (res) return res; + rtl8187_set_anaparam(priv, true); + /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as * RESP_RATE on 8187L in Realtek sources: each bit should be each * one of the 12 rates, all are enabled */ -- cgit v1.2.3-59-g8ed1b From 8cecc90e4a302ac214c48e362709ce906a96a295 Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Tue, 2 Nov 2010 23:10:12 +0100 Subject: zd1211rw: add 2 missing usb id's "These USB ID came from Palnex Worked fine." says Mandriva patch for their 2.6.32 and earlier. Web has evidence for both id's to work, so just add them upstream: http://www.mail-archive.com/zd1211-devs@lists.sourceforge.net/msg00507.html http://ubuntuforums.org/showthread.php?t=473046 Signed-off-by: Go Taniguchi Signed-off-by: maximilian attems Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 818e1480ca93..06041cb1c422 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -55,6 +55,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x14ea, 0xab10), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, @@ -92,6 +93,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x2019, 0xed01), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, -- cgit v1.2.3-59-g8ed1b From d94519c1b0de827d5d142b9333b7f114c0b3a021 Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Tue, 2 Nov 2010 23:39:12 +0100 Subject: zd1201: Add missing id The Mandriva patch seems to stem from 2.6.14, so much for their upstreaming effort. Didn't find another Linux reference of it, just an omnious "USB\VID_1044&PID_8004" from GigabyteZD1201U.INF for Gigabyte GN-WLBZ101 802.11b USB Adapter, which matches the Mandriva patch comment. Aboves file also lists an "USB\VID_1044&PID_8006", which I have kept appart as this "Gigabyte GN-WBZB-M 802.11b USB Adapter" didn't show up in googling. Signed-off-by: maximilian attems Signed-off-by: John W. Linville --- drivers/net/wireless/zd1201.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 390d77f762c4..b97aa9c78a96 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -30,6 +30,7 @@ static struct usb_device_id zd1201_table[] = { {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */ {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */ {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */ + {USB_DEVICE(0x1044, 0x8004)}, /* Gigabyte GN-WLBZ101 */ {USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */ {} }; -- cgit v1.2.3-59-g8ed1b From 21e731a1b15bf03927e292af1b4a2c84fc8af817 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 3 Nov 2010 21:36:12 +0100 Subject: b43legacy: rfkill: use status register based on core revision (not PHY's) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/rfkill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index d579df72b783..b90f223fb31c 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -29,7 +29,7 @@ /* Returns TRUE, if the radio is enabled in hardware. */ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) { - if (dev->phy.rev >= 3) { + if (dev->dev->id.revision >= 3) { if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) return 1; -- cgit v1.2.3-59-g8ed1b From 066dae93bdfcc7af5e38a33617773fd5c6457607 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 7 Nov 2010 14:59:39 +0100 Subject: ath9k: rework tx queue selection and fix queue stopping/waking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current ath9k tx queue handling code showed a few issues that could lead to locking issues, tx stalls due to stopped queues, and maybe even DMA issues. The main source of these issues is that in some places the queue is selected via skb queue mapping in places where this mapping may no longer be valid. One such place is when data frames are transmitted via the CAB queue (for powersave buffered frames). This is made even worse by a lookup WMM AC values from the assigned tx queue (which is undefined for the CAB queue). This messed up the pending frame counting, which in turn caused issues with queues getting stopped, but not woken again. To fix these issues, this patch removes an unnecessary abstraction separating a driver internal queue number from the skb queue number (not to be confused with the hardware queue number). It seems that this abstraction may have been necessary because of tx queue preinitialization from the initvals. This patch avoids breakage here by pushing the software <-> hardware queue mapping to the function that assigns the tx queues and redefining the WMM AC definitions to match the numbers used by mac80211 (also affects ath9k_htc). To ensure consistency wrt. pending frame count tracking, these counters are moved to the ath_txq struct, updated with the txq lock held, but only where the tx queue selected by the skb queue map actually matches the tx queue used by the driver for the frame. Signed-off-by: Felix Fietkau Reported-by: Björn Smedman Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 9 +-- drivers/net/wireless/ath/ath9k/beacon.c | 6 +- drivers/net/wireless/ath/ath9k/common.h | 9 +-- drivers/net/wireless/ath/ath9k/debug.c | 36 +++++----- drivers/net/wireless/ath/ath9k/debug.h | 5 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 9 ++- drivers/net/wireless/ath/ath9k/hw.h | 7 ++ drivers/net/wireless/ath/ath9k/init.c | 52 ++------------ drivers/net/wireless/ath/ath9k/main.c | 71 +++--------------- drivers/net/wireless/ath/ath9k/virtual.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 100 ++++++++++++-------------- 11 files changed, 109 insertions(+), 197 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 61d450750acb..21433465bde4 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -195,7 +195,6 @@ enum ATH_AGGR_STATUS { #define ATH_TXFIFO_DEPTH 8 struct ath_txq { - int axq_class; u32 axq_qnum; u32 *axq_link; struct list_head axq_q; @@ -208,11 +207,12 @@ struct ath_txq { struct list_head txq_fifo_pending; u8 txq_headidx; u8 txq_tailidx; + int pending_frames; }; struct ath_atx_ac { + struct ath_txq *txq; int sched; - int qnum; struct list_head list; struct list_head tid_q; }; @@ -290,12 +290,11 @@ struct ath_tx_control { struct ath_tx { u16 seq_no; u32 txqsetup; - int hwq_map[WME_NUM_AC]; spinlock_t txbuflock; struct list_head txbuf; struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; struct ath_descdma txdma; - int pending_frames[WME_NUM_AC]; + struct ath_txq *txq_map[WME_NUM_AC]; }; struct ath_rx_edma { @@ -325,7 +324,6 @@ void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); -int ath_tx_setup(struct ath_softc *sc, int haltype); void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx); @@ -665,7 +663,6 @@ struct ath_wiphy { void ath9k_tasklet(unsigned long data); int ath_reset(struct ath_softc *sc, bool retry_tx); -int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); int ath_cabq_update(struct ath_softc *); static inline void ath_read_cachesize(struct ath_common *common, int *csz) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 333da7bf2d7d..2377376c8d4d 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -28,7 +28,7 @@ int ath_beaconq_config(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_tx_queue_info qi, qi_be; - int qnum; + struct ath_txq *txq; ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { @@ -38,8 +38,8 @@ int ath_beaconq_config(struct ath_softc *sc) qi.tqi_cwmax = 0; } else { /* Adhoc mode; important thing is to use 2x cwmin. */ - qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_get_txq_props(ah, qnum, &qi_be); + txq = sc->tx.txq_map[WME_AC_BE]; + ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; qi.tqi_cwmin = 4*qi_be.tqi_cwmin; qi.tqi_cwmax = qi_be.tqi_cwmax; diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index c76c75a77c62..4c04ee85ff0e 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -31,10 +31,11 @@ #define WME_MAX_BA WME_BA_BMP_SIZE #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) -#define WME_AC_BE 0 -#define WME_AC_BK 1 -#define WME_AC_VI 2 -#define WME_AC_VO 3 +/* These must match mac80211 skb queue mapping numbers */ +#define WME_AC_VO 0 +#define WME_AC_VI 1 +#define WME_AC_BE 2 +#define WME_AC_BK 3 #define WME_NUM_AC 4 #define ATH_RSSI_DUMMY_MARKER 0x127 diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a4052711eca8..0c3c74c157fb 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -585,10 +585,10 @@ static const struct file_operations fops_wiphy = { do { \ len += snprintf(buf + len, size - len, \ "%s%13u%11u%10u%10u\n", str, \ - sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \ + sc->debug.stats.txstats[WME_AC_BE].elem, \ + sc->debug.stats.txstats[WME_AC_BK].elem, \ + sc->debug.stats.txstats[WME_AC_VI].elem, \ + sc->debug.stats.txstats[WME_AC_VO].elem); \ } while(0) static ssize_t read_file_xmit(struct file *file, char __user *user_buf, @@ -630,33 +630,35 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, return retval; } -void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, - struct ath_buf *bf, struct ath_tx_status *ts) +void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_status *ts) { - TX_STAT_INC(txq->axq_qnum, tx_pkts_all); - sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len; + int qnum = skb_get_queue_mapping(bf->bf_mpdu); + + TX_STAT_INC(qnum, tx_pkts_all); + sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; if (bf_isampdu(bf)) { if (bf_isxretried(bf)) - TX_STAT_INC(txq->axq_qnum, a_xretries); + TX_STAT_INC(qnum, a_xretries); else - TX_STAT_INC(txq->axq_qnum, a_completed); + TX_STAT_INC(qnum, a_completed); } else { - TX_STAT_INC(txq->axq_qnum, completed); + TX_STAT_INC(qnum, completed); } if (ts->ts_status & ATH9K_TXERR_FIFO) - TX_STAT_INC(txq->axq_qnum, fifo_underrun); + TX_STAT_INC(qnum, fifo_underrun); if (ts->ts_status & ATH9K_TXERR_XTXOP) - TX_STAT_INC(txq->axq_qnum, xtxop); + TX_STAT_INC(qnum, xtxop); if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) - TX_STAT_INC(txq->axq_qnum, timer_exp); + TX_STAT_INC(qnum, timer_exp); if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) - TX_STAT_INC(txq->axq_qnum, desc_cfg_err); + TX_STAT_INC(qnum, desc_cfg_err); if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) - TX_STAT_INC(txq->axq_qnum, data_underrun); + TX_STAT_INC(qnum, data_underrun); if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) - TX_STAT_INC(txq->axq_qnum, delim_underrun); + TX_STAT_INC(qnum, delim_underrun); } static const struct file_operations fops_xmit = { diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index bb0823242ba0..646ff7e04c88 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -169,8 +169,8 @@ void ath9k_exit_debug(struct ath_hw *ah); int ath9k_debug_create_root(void); void ath9k_debug_remove_root(void); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); -void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, - struct ath_buf *bf, struct ath_tx_status *ts); +void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_status *ts); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); #else @@ -199,7 +199,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, } static inline void ath_debug_stat_tx(struct ath_softc *sc, - struct ath_txq *txq, struct ath_buf *bf, struct ath_tx_status *ts) { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 3d19b5bc937f..5324ffd96ec7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -20,8 +20,15 @@ /* TX */ /******/ +static const int subtype_txq_to_hwq[] = { + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, +}; + #define ATH9K_HTC_INIT_TXQ(subtype) do { \ - qi.tqi_subtype = subtype; \ + qi.tqi_subtype = subtype_txq_to_hwq[subtype]; \ qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \ qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \ qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 366f088dc15d..e5b72262fd96 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -157,6 +157,13 @@ #define PAPRD_GAIN_TABLE_ENTRIES 32 #define PAPRD_TABLE_SZ 24 +enum ath_hw_txq_subtype { + ATH_TXQ_AC_BE = 0, + ATH_TXQ_AC_BK = 1, + ATH_TXQ_AC_VI = 2, + ATH_TXQ_AC_VO = 3, +}; + enum ath_ini_subsys { ATH_INI_PRE = 0, ATH_INI_CORE, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index adff0da01f4c..498f62180f1c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -395,7 +395,8 @@ static void ath9k_init_crypto(struct ath_softc *sc) static int ath9k_init_btcoex(struct ath_softc *sc) { - int r, qnum; + struct ath_txq *txq; + int r; switch (sc->sc_ah->btcoex_hw.scheme) { case ATH_BTCOEX_CFG_NONE: @@ -408,8 +409,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc) r = ath_init_btcoex_timer(sc); if (r) return -1; - qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); + txq = sc->tx.txq_map[WME_AC_BE]; + ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; break; default: @@ -422,59 +423,18 @@ static int ath9k_init_btcoex(struct ath_softc *sc) static int ath9k_init_queues(struct ath_softc *sc) { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) - sc->tx.hwq_map[i] = -1; - sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); - if (sc->beacon.beaconq == -1) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup a beacon xmit queue\n"); - goto err; - } - sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); - if (sc->beacon.cabq == NULL) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup CAB xmit queue\n"); - goto err; - } sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - if (!ath_tx_setup(sc, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); - goto err; - } - - if (!ath_tx_setup(sc, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); - goto err; - } - if (!ath_tx_setup(sc, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); - goto err; - } - if (!ath_tx_setup(sc, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); - goto err; - } + for (i = 0; i < WME_NUM_AC; i++) + sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); return 0; - -err: - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) - if (ATH_TXQ_SETUP(sc, i)) - ath_tx_cleanupq(sc, &sc->tx.txq[i]); - - return -EIO; } static int ath9k_init_channels_rates(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d522112cf736..df7c62d9bec4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -330,7 +330,7 @@ void ath_paprd_calibrate(struct work_struct *work) struct ath_tx_control txctl; struct ath9k_hw_cal_data *caldata = ah->caldata; struct ath_common *common = ath9k_hw_common(ah); - int qnum, ftype; + int ftype; int chain_ok = 0; int chain; int len = 1800; @@ -357,8 +357,7 @@ void ath_paprd_calibrate(struct work_struct *work) memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); memset(&txctl, 0, sizeof(txctl)); - qnum = sc->tx.hwq_map[WME_AC_BE]; - txctl.txq = &sc->tx.txq[qnum]; + txctl.txq = sc->tx.txq_map[WME_AC_BE]; ath9k_ps_wakeup(sc); ar9003_paprd_init_table(ah); @@ -1024,56 +1023,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } -static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) -{ - int qnum; - - switch (queue) { - case 0: - qnum = sc->tx.hwq_map[WME_AC_VO]; - break; - case 1: - qnum = sc->tx.hwq_map[WME_AC_VI]; - break; - case 2: - qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - case 3: - qnum = sc->tx.hwq_map[WME_AC_BK]; - break; - default: - qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - } - - return qnum; -} - -int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) -{ - int qnum; - - switch (queue) { - case WME_AC_VO: - qnum = 0; - break; - case WME_AC_VI: - qnum = 1; - break; - case WME_AC_BE: - qnum = 2; - break; - case WME_AC_BK: - qnum = 3; - break; - default: - qnum = -1; - break; - } - - return qnum; -} - /* XXX: Remove me once we don't depend on ath9k_channel for all * this redundant data */ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, @@ -1243,7 +1192,6 @@ static int ath9k_tx(struct ieee80211_hw *hw, struct ath_tx_control txctl; int padpos, padsize; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - int qnum; if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { ath_print(common, ATH_DBG_XMIT, @@ -1316,8 +1264,7 @@ static int ath9k_tx(struct ieee80211_hw *hw, memmove(skb->data, skb->data + padsize, padpos); } - qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); - txctl.txq = &sc->tx.txq[qnum]; + txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); @@ -1801,12 +1748,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_txq *txq; struct ath9k_tx_queue_info qi; - int ret = 0, qnum; + int ret = 0; if (queue >= WME_NUM_AC) return 0; + txq = sc->tx.txq_map[queue]; + mutex_lock(&sc->mutex); memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); @@ -1815,20 +1765,19 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, qi.tqi_cwmin = params->cw_min; qi.tqi_cwmax = params->cw_max; qi.tqi_burstTime = params->txop; - qnum = ath_get_hal_qnum(queue, sc); ath_print(common, ATH_DBG_CONFIG, "Configure tx [queue/halq] [%d/%d], " "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - queue, qnum, params->aifs, params->cw_min, + queue, txq->axq_qnum, params->aifs, params->cw_min, params->cw_max, params->txop); - ret = ath_txq_update(sc, qnum, &qi); + ret = ath_txq_update(sc, txq->axq_qnum, &qi); if (ret) ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) - if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) + if (queue == WME_AC_BE && !ret) ath_beaconq_config(sc); mutex_unlock(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index cb6c48be1245..4008f51d34c8 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -187,7 +187,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy, info->control.rates[1].idx = -1; memset(&txctl, 0, sizeof(struct ath_tx_control)); - txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]]; + txctl.txq = sc->tx.txq_map[WME_AC_VO]; txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; if (ath_tx_start(aphy->hw, skb, &txctl) != 0) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2bc422eb80c7..6380bbd82d49 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -124,7 +124,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { - struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; + struct ath_txq *txq = tid->ac->txq; WARN_ON(!tid->paused); @@ -142,7 +142,7 @@ unlock: static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { - struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; + struct ath_txq *txq = tid->ac->txq; struct ath_buf *bf; struct list_head bf_head; struct ath_tx_status ts; @@ -817,7 +817,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) { struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); - struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; + struct ath_txq *txq = txtid->ac->txq; if (txtid->state & AGGR_CLEANUP) return; @@ -888,10 +888,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_tx_queue_info qi; + static const int subtype_txq_to_hwq[] = { + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, + }; int qnum, i; memset(&qi, 0, sizeof(qi)); - qi.tqi_subtype = subtype; + qi.tqi_subtype = subtype_txq_to_hwq[subtype]; qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; @@ -940,7 +946,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) if (!ATH_TXQ_SETUP(sc, qnum)) { struct ath_txq *txq = &sc->tx.txq[qnum]; - txq->axq_class = subtype; txq->axq_qnum = qnum; txq->axq_link = NULL; INIT_LIST_HEAD(&txq->axq_q); @@ -1210,24 +1215,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) } } -int ath_tx_setup(struct ath_softc *sc, int haltype) -{ - struct ath_txq *txq; - - if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "HAL AC %u out of range, max %zu!\n", - haltype, ARRAY_SIZE(sc->tx.hwq_map)); - return 0; - } - txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); - if (txq != NULL) { - sc->tx.hwq_map[haltype] = txq->axq_qnum; - return 1; - } else - return 0; -} - /***********/ /* TX, DMA */ /***********/ @@ -1708,6 +1695,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, goto tx_done; } + WARN_ON(tid->ac->txq != txctl->txq); if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { /* * Try aggregation if it's a unicast data frame @@ -1747,6 +1735,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, return -1; } + q = skb_get_queue_mapping(skb); r = ath_tx_setup_buffer(hw, bf, skb, txctl); if (unlikely(r)) { ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); @@ -1756,8 +1745,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, * we will at least have to run TX completionon one buffer * on the queue */ spin_lock_bh(&txq->axq_lock); - if (!txq->stopped && txq->axq_depth > 1) { - ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); + if (txq == sc->tx.txq_map[q] && !txq->stopped && + txq->axq_depth > 1) { + ath_mac80211_stop_queue(sc, q); txq->stopped = 1; } spin_unlock_bh(&txq->axq_lock); @@ -1767,13 +1757,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, return r; } - q = skb_get_queue_mapping(skb); - if (q >= 4) - q = 0; - spin_lock_bh(&txq->axq_lock); - if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { - ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); + if (txq == sc->tx.txq_map[q] && + ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { + ath_mac80211_stop_queue(sc, q); txq->stopped = 1; } spin_unlock_bh(&txq->axq_lock); @@ -1841,7 +1828,8 @@ exit: /*****************/ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, - struct ath_wiphy *aphy, int tx_flags) + struct ath_wiphy *aphy, int tx_flags, + struct ath_txq *txq) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -1888,11 +1876,12 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ath9k_tx_status(hw, skb); else { q = skb_get_queue_mapping(skb); - if (q >= 4) - q = 0; - - if (--sc->tx.pending_frames[q] < 0) - sc->tx.pending_frames[q] = 0; + if (txq == sc->tx.txq_map[q]) { + spin_lock_bh(&txq->axq_lock); + if (WARN_ON(--txq->pending_frames < 0)) + txq->pending_frames = 0; + spin_unlock_bh(&txq->axq_lock); + } ieee80211_tx_status(hw, skb); } @@ -1927,8 +1916,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, else complete(&sc->paprd_complete); } else { - ath_debug_stat_tx(sc, txq, bf, ts); - ath_tx_complete(sc, skb, bf->aphy, tx_flags); + ath_debug_stat_tx(sc, bf, ts); + ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq); } /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't * accidentally reference it later. @@ -2018,16 +2007,13 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; } -static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) +static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum) { - int qnum; - - qnum = ath_get_mac80211_qnum(txq->axq_class, sc); - if (qnum == -1) - return; + struct ath_txq *txq; + txq = sc->tx.txq_map[qnum]; spin_lock_bh(&txq->axq_lock); - if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { + if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { if (ath_mac80211_start_queue(sc, qnum)) txq->stopped = 0; } @@ -2044,6 +2030,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) struct ath_tx_status ts; int txok; int status; + int qnum; ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), @@ -2119,12 +2106,15 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); } + qnum = skb_get_queue_mapping(bf->bf_mpdu); + if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); - ath_wake_mac80211_queue(sc, txq); + if (txq == sc->tx.txq_map[qnum]) + ath_wake_mac80211_queue(sc, qnum); spin_lock_bh(&txq->axq_lock); if (sc->sc_flags & SC_OP_TXAGGR) @@ -2194,6 +2184,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) struct list_head bf_head; int status; int txok; + int qnum; for (;;) { status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); @@ -2237,13 +2228,16 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); } + qnum = skb_get_queue_mapping(bf->bf_mpdu); + if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &txs, txok, 0); - ath_wake_mac80211_queue(sc, txq); + if (txq == sc->tx.txq_map[qnum]) + ath_wake_mac80211_queue(sc, qnum); spin_lock_bh(&txq->axq_lock); if (!list_empty(&txq->txq_fifo_pending)) { @@ -2375,7 +2369,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) for (acno = 0, ac = &an->ac[acno]; acno < WME_NUM_AC; acno++, ac++) { ac->sched = false; - ac->qnum = sc->tx.hwq_map[acno]; + ac->txq = sc->tx.txq_map[acno]; INIT_LIST_HEAD(&ac->tid_q); } } @@ -2385,17 +2379,13 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) struct ath_atx_ac *ac; struct ath_atx_tid *tid; struct ath_txq *txq; - int i, tidno; + int tidno; for (tidno = 0, tid = &an->tid[tidno]; tidno < WME_NUM_TID; tidno++, tid++) { - i = tid->ac->qnum; - - if (!ATH_TXQ_SETUP(sc, i)) - continue; - txq = &sc->tx.txq[i]; ac = tid->ac; + txq = ac->txq; spin_lock_bh(&txq->axq_lock); -- cgit v1.2.3-59-g8ed1b From 961621abee08fde2328daf6f8000e1059e5205e9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:36:59 +0100 Subject: rt2x00: Add TXOP_CTRL_CFG register definition Remove the magic value initialisation of the TXOP_CTRL_CFG register by defining its fields and using them during intialisation. The field RESERVED_TRUN_EN is referred to as reserved, however it is set to 1 by the legacy drivers. Hence, do the same. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 23 +++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 18 +++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index eb8b6cab9925..6cfed0638ceb 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -960,8 +960,31 @@ /* * TXOP_CTRL_CFG: + * TIMEOUT_TRUN_EN: Enable/Disable TXOP timeout truncation + * AC_TRUN_EN: Enable/Disable truncation for AC change + * TXRATEGRP_TRUN_EN: Enable/Disable truncation for TX rate group change + * USER_MODE_TRUN_EN: Enable/Disable truncation for user TXOP mode + * MIMO_PS_TRUN_EN: Enable/Disable truncation for MIMO PS RTS/CTS + * RESERVED_TRUN_EN: Reserved + * LSIG_TXOP_EN: Enable/Disable L-SIG TXOP protection + * EXT_CCA_EN: Enable/Disable extension channel CCA reference (Defer 40Mhz + * transmissions if extension CCA is clear). + * EXT_CCA_DLY: Extension CCA signal delay time (unit: us) + * EXT_CWMIN: CwMin for extension channel backoff + * 0: Disabled + * */ #define TXOP_CTRL_CFG 0x1340 +#define TXOP_CTRL_CFG_TIMEOUT_TRUN_EN FIELD32(0x00000001) +#define TXOP_CTRL_CFG_AC_TRUN_EN FIELD32(0x00000002) +#define TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN FIELD32(0x00000004) +#define TXOP_CTRL_CFG_USER_MODE_TRUN_EN FIELD32(0x00000008) +#define TXOP_CTRL_CFG_MIMO_PS_TRUN_EN FIELD32(0x00000010) +#define TXOP_CTRL_CFG_RESERVED_TRUN_EN FIELD32(0x00000020) +#define TXOP_CTRL_CFG_LSIG_TXOP_EN FIELD32(0x00000040) +#define TXOP_CTRL_CFG_EXT_CCA_EN FIELD32(0x00000080) +#define TXOP_CTRL_CFG_EXT_CCA_DLY FIELD32(0x0000ff00) +#define TXOP_CTRL_CFG_EXT_CWMIN FIELD32(0x000f0000) /* * TX_RTS_CFG: diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5f00e00789d8..54bf08570557 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2097,7 +2097,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); } - rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f); + /* + * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1 + * although it is reserved. + */ + rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, ®); + rt2x00_set_field32(®, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_AC_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_EN, 0); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_DLY, 88); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0); + rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); -- cgit v1.2.3-59-g8ed1b From efd2f271e44c7ea011cdb0363d38f40338ab80d2 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:37:22 +0100 Subject: rt2x00: Sync Tx and RX ring sizes with legacy drivers All rt2x00 devices used the same Tx and Rx ring size (24 entries) till now. Newer devices (like rt2800) can however make use of a larger TX and RX ring due to 11n capabilities (AMPDUs of size 64 for example). Hence, bring rt2x00 in sync with the legacy drivers and use the same TX and RX ring sizes. Also remove the global defines RX_ENTRIES, TX_ENTRIES, BEACON_ENTRIES and ATIM_ENTRIES and use per driver values. That is 24 entries for rt2400pci, 32 entries for rt2500pci, rt2500usb, rt61pci and rt73usb and 128 (RX) and 64 (TX) for rt2800pci and rt2800usb. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2500pci.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2500usb.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2800pci.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2800usb.c | 9 +++++---- drivers/net/wireless/rt2x00/rt2x00queue.h | 16 ---------------- drivers/net/wireless/rt2x00/rt61pci.c | 8 ++++---- drivers/net/wireless/rt2x00/rt73usb.c | 6 +++--- 9 files changed, 29 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4f420a9ec5dc..c94aa1e5d089 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1640,28 +1640,28 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { }; static const struct data_queue_desc rt2400pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 97feb7aef809..ab6c9eccd9bb 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1937,28 +1937,28 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { }; static const struct data_queue_desc rt2500pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 93e44c7f3a74..725ae34f1815 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1829,28 +1829,28 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { }; static const struct data_queue_desc rt2500usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2500usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2500usb_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb_bcn), }; static const struct data_queue_desc rt2500usb_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 54bf08570557..b1738bbf87ff 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -727,7 +727,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) * that the TX_STA_FIFO stack has a size of 16. We stick to our * tx ring size for now. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) break; diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b26739535986..2c12b598be50 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -777,7 +777,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * Since we have only one producer and one consumer we don't * need to lock the kfifo. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) @@ -991,21 +991,21 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { }; static const struct data_queue_desc rt2800pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 128, .data_size = AGGREGATION_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2800pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 64, .data_size = AGGREGATION_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2800pci_queue_bcn = { - .entry_num = 8 * BEACON_ENTRIES, + .entry_num = 8, .data_size = 0, /* No DMA required for beacons */ .desc_size = TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3dff56ec195a..3f44131baeee 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -165,7 +165,8 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) * this limit so reduce the number to prevent errors. */ rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_LIMIT, - ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3); + ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE) + / 1024) - 3); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); @@ -553,21 +554,21 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { }; static const struct data_queue_desc rt2800usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 128, .data_size = AGGREGATION_SIZE, .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 64, .data_size = AGGREGATION_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_bcn = { - .entry_num = 8 * BEACON_ENTRIES, + .entry_num = 8, .data_size = MGMT_FRAME_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index d81d85f34866..64acfb62d909 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -42,22 +42,6 @@ #define MGMT_FRAME_SIZE 256 #define AGGREGATION_SIZE 3840 -/** - * DOC: Number of entries per queue - * - * Under normal load without fragmentation, 12 entries are sufficient - * without the queue being filled up to the maximum. When using fragmentation - * and the queue threshold code, we need to add some additional margins to - * make sure the queue will never (or only under extreme load) fill up - * completely. - * Since we don't use preallocated DMA, having a large number of queue entries - * will have minimal impact on the memory requirements for the queue. - */ -#define RX_ENTRIES 24 -#define TX_ENTRIES 24 -#define BEACON_ENTRIES 1 -#define ATIM_ENTRIES 8 - /** * enum data_queue_qid: Queue identification * diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index af548c87f108..3232336b7f42 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2078,7 +2078,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) * that the TX_STA_FIFO stack has a size of 16. We stick to our * tx ring size for now. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) break; @@ -2857,21 +2857,21 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { }; static const struct data_queue_desc rt61pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt61pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt61pci_queue_bcn = { - .entry_num = 4 * BEACON_ENTRIES, + .entry_num = 4, .data_size = 0, /* No DMA required for beacons */ .desc_size = TXINFO_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 9be8089317e4..67447ec005bf 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2296,21 +2296,21 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { }; static const struct data_queue_desc rt73usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt73usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt73usb_queue_bcn = { - .entry_num = 4 * BEACON_ENTRIES, + .entry_num = 4, .data_size = MGMT_FRAME_SIZE, .desc_size = TXINFO_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), -- cgit v1.2.3-59-g8ed1b From 08e5310028359de2daaa39cd10e9ca493c51792b Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:37:47 +0100 Subject: rt2x00: Wait up to one second on rt2800 for WPDMA to be ready At least some devices need such a long time to inititalize WPDMA. This only increases the maximum wait time and shouldn't affect devices that have been working before. Reported-by: Joshua Smith Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b1738bbf87ff..dcd3a8981ca2 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) unsigned int i; u32 reg; + /* + * Some devices are really slow to respond here. Wait a whole second + * before timing out. + */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) && !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY)) return 0; - msleep(1); + msleep(10); } ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); -- cgit v1.2.3-59-g8ed1b From 2b23cdaa3b0e9567597563e5a7a5103ecda447f0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:38:15 +0100 Subject: rt2x00: Reduce tx descriptor size The tx descriptor values qid, cw_min, cw_max and aifs are directly accessible through the tx entry struct. So there's no need to copy them into the tx descriptor and passing them to the indiviual drivers. Instead we can just get the correct value from the tx entry. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2500usb.c | 6 +++--- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 8 -------- drivers/net/wireless/rt2x00/rt2x00queue.h | 9 --------- drivers/net/wireless/rt2x00/rt61pci.c | 14 +++++++------- drivers/net/wireless/rt2x00/rt73usb.c | 8 ++++---- 7 files changed, 18 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index ab6c9eccd9bb..b69e55fedda9 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1193,9 +1193,9 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, rt2x00_desc_read(txd, 2, &word); rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 725ae34f1815..f20ab79b2817 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1081,9 +1081,9 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_read(txd, 1, &word); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); - rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_AIFS, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index dcd3a8981ca2..6fa654956f4e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -487,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid); rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); rt2x00_desc_write(txwi, 1, word); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index e360d287defb..4e2a8c2e014d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -310,14 +310,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, memset(txdesc, 0, sizeof(*txdesc)); - /* - * Initialize information from queue - */ - txdesc->qid = entry->queue->qid; - txdesc->cw_min = entry->queue->cw_min; - txdesc->cw_max = entry->queue->cw_max; - txdesc->aifs = entry->queue->aifs; - /* * Header and frame information. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 64acfb62d909..8a36ef31e893 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -280,7 +280,6 @@ enum txentry_desc_flags { * Summary of information for the frame descriptor before sending a TX frame. * * @flags: Descriptor flags (See &enum queue_entry_flags). - * @qid: Queue identification (See &enum data_queue_qid). * @length: Length of the entire frame. * @header_length: Length of 802.11 header. * @length_high: PLCP length high word. @@ -293,11 +292,8 @@ enum txentry_desc_flags { * @rate_mode: Rate mode (See @enum rate_modulation). * @mpdu_density: MDPU density. * @retry_limit: Max number of retries. - * @aifs: AIFS value. * @ifs: IFS value. * @txop: IFS value for 11n capable chips. - * @cw_min: cwmin value. - * @cw_max: cwmax value. * @cipher: Cipher type used for encryption. * @key_idx: Key index used for encryption. * @iv_offset: Position where IV should be inserted by hardware. @@ -306,8 +302,6 @@ enum txentry_desc_flags { struct txentry_desc { unsigned long flags; - enum data_queue_qid qid; - u16 length; u16 header_length; @@ -323,11 +317,8 @@ struct txentry_desc { u16 mpdu_density; short retry_limit; - short aifs; short ifs; short txop; - short cw_min; - short cw_max; enum cipher cipher; u16 key_idx; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3232336b7f42..fba9ee11873b 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1789,10 +1789,10 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, * Start writing the descriptor words. */ rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); - rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid); + rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); @@ -1820,7 +1820,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); - if (txdesc->qid != QID_BEACON) { + if (entry->queue->qid != QID_BEACON) { rt2x00_desc_read(txd, 6, &word); rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, skbdesc->skb_dma); @@ -1866,8 +1866,8 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, * Register descriptor details in skb frame descriptor. */ skbdesc->desc = txd; - skbdesc->desc_len = - (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; + skbdesc->desc_len = (entry->queue->qid == QID_BEACON) ? TXINFO_SIZE : + TXD_DESC_SIZE; } /* diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 67447ec005bf..3c86f0075aed 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1472,10 +1472,10 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); - rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid); + rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); -- cgit v1.2.3-59-g8ed1b From e2f8c8752b994026fc0ddb4bb29ca229b3e0c104 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:38:56 +0100 Subject: rt2x00: Optimize rt2x00debug_dump_frame when frame dumping is not active When rt2x00 is compiled with debugging but frame dumping is currently not active we can avoid the call to do_gettimeofday. Furthermore, frame dumping is not the default case, mark it as unlikely. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index fcdb6b0dc40f..8296a9d47bbd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -162,11 +162,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct timeval timestamp; u32 data_len; - do_gettimeofday(×tamp); - - if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) + if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))) return; + do_gettimeofday(×tamp); + if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); return; -- cgit v1.2.3-59-g8ed1b From 7225ce1ea93d24c0914eea0410dcfc426281f996 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 4 Nov 2010 20:39:23 +0100 Subject: rt2x00: Rename rt2x00queue_timeout Rename rt2x00queue_timeout to rt2x00queue_status_timeout to better describe what is actually timing out (note that we already have a rt2x00queue_dma_timeout). Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 4 ++-- drivers/net/wireless/rt2x00/rt2x00usb.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 8a36ef31e893..64c00e2ab716 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -593,10 +593,10 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** - * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts + * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports * @queue: Queue to check. */ -static inline int rt2x00queue_timeout(struct data_queue *queue) +static inline int rt2x00queue_status_timeout(struct data_queue *queue) { return time_after(queue->last_action[Q_INDEX_DMA_DONE], queue->last_action[Q_INDEX_DONE] + (HZ / 10)); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index b3317df7a7d4..88995d50a5c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -361,7 +361,7 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_empty(queue)) { if (rt2x00queue_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00queue_timeout(queue)) + if (rt2x00queue_status_timeout(queue)) rt2x00usb_watchdog_tx_status(queue); } } -- cgit v1.2.3-59-g8ed1b From aaf886bd215396f295bc0489e8ae09d1c03d9aa0 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 4 Nov 2010 20:39:48 +0100 Subject: rt2x00: Remove failsave from rt2x00usb_watchdog_tx_dma When the TX status handler failed to clear the queue in rt2x00usb_watchdog_tx_dma() we shouldn't use a failsave to use the rt2x00usb txdone handler. If a driver has overriden the txdone handler it must make sure the txdone handler is capable of cleaning up the queue itself. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 88995d50a5c7..6dd96192dd91 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -322,21 +322,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) */ rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); - /* - * Security measure: if the driver did override the - * txdone_work function, and the hardware did arrive - * in a state which causes it to malfunction, it is - * possible that the driver couldn't handle the txdone - * event correctly. So after giving the driver the - * chance to cleanup, we now force a cleanup of any - * leftovers. - */ - if (!rt2x00queue_empty(queue)) { - WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," - " status handling failed, invoke hard reset", queue->qid); - rt2x00usb_work_txdone(&rt2x00dev->txdone_work); - } - /* * The queue has been reset, and mac80211 is allowed to use the * queue again. -- cgit v1.2.3-59-g8ed1b From f44df18c58d4debe3ec0bb76a490aa2f3929fd8b Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 4 Nov 2010 20:40:11 +0100 Subject: rt2x00: Implement flush callback Implement a basic flush callback function, which simply loops over all TX queues and waits until all frames have been transmitted and the status reports have been gathered. At this moment we don't support dropping any frames during the flush, but mac80211 will only send 'false' for this argument anyway, so this is not important at this time. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 1 + drivers/net/wireless/rt2x00/rt2500pci.c | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00mac.c | 38 +++++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt61pci.c | 1 + drivers/net/wireless/rt2x00/rt73usb.c | 1 + 9 files changed, 46 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index c94aa1e5d089..bc1ae1ebfdb0 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1612,6 +1612,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .get_tsf = rt2400pci_get_tsf, .tx_last_beacon = rt2400pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index b69e55fedda9..54754150250b 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1909,6 +1909,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .get_tsf = rt2500pci_get_tsf, .tx_last_beacon = rt2500pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index f20ab79b2817..478c4f127ce6 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1801,6 +1801,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2x00mac_conf_tx, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 2c12b598be50..6dc61b7710b9 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -943,6 +943,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .get_tsf = rt2800_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, + .flush = rt2x00mac_flush, }; static const struct rt2800_ops rt2800pci_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3f44131baeee..04dfedc70f85 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -508,6 +508,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .get_tsf = rt2800_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, + .flush = rt2x00mac_flush, }; static const struct rt2800_ops rt2800usb_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94fe589acfaa..42bd3a96f23b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1133,6 +1133,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); +void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); /* * Driver allocation handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c3c206a97d54..283a8d9874ee 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -719,3 +719,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) wiphy_rfkill_set_hw_state(hw->wiphy, !active); } EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); + +void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + unsigned int i = 0; + + ieee80211_stop_queues(hw); + + /* + * Run over all queues to kick them, this will force + * any pending frames to be transmitted. + */ + tx_queue_for_each(rt2x00dev, queue) { + rt2x00dev->ops->lib->kick_tx_queue(queue); + } + + /** + * All queues have been kicked, now wait for each queue + * to become empty. With a bit of luck, we only have to wait + * for the first queue to become empty, because while waiting + * for the that queue, the other queues will have transmitted + * all their frames as well (since they were already kicked). + */ + tx_queue_for_each(rt2x00dev, queue) { + for (i = 0; i < 10; i++) { + if (rt2x00queue_empty(queue)) + break; + msleep(100); + } + + if (!rt2x00queue_empty(queue)) + WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid); + } + + ieee80211_wake_queues(hw); +} +EXPORT_SYMBOL_GPL(rt2x00mac_flush); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index fba9ee11873b..f01bff7656bc 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2824,6 +2824,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .conf_tx = rt61pci_conf_tx, .get_tsf = rt61pci_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 3c86f0075aed..dcb9211c4771 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2264,6 +2264,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .conf_tx = rt73usb_conf_tx, .get_tsf = rt73usb_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { -- cgit v1.2.3-59-g8ed1b From 303c7d6abfd0430e39e84a43361492b4a8c890b6 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 4 Nov 2010 20:40:46 +0100 Subject: rt2x00: Fix MCU_SLEEP arguments Legacy driver uses 0xff as the second argument for the MCU_SLEEP command. It is still unknown what the values actually mean, but this will at least keep the command in-sync with the original driver. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/wireless/rt2x00/rt2800usb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 6dc61b7710b9..1db0c3bf2e1f 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -442,7 +442,7 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, * if the device is booting and wasn't asleep it will return * failure when attempting to wakeup. */ - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); if (state == STATE_AWAKE) { rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 04dfedc70f85..5c31e3350aac 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -184,9 +184,9 @@ static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { if (state == STATE_AWAKE) - rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); + rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2); else - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); return 0; } -- cgit v1.2.3-59-g8ed1b From 070192dd2975c0e97bbdeac7623b755235c6db7d Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 4 Nov 2010 20:41:05 +0100 Subject: rt2x00: Fix crash on USB unplug By not scheduling the TX/RX completion worker threads when Radio is disabled, or hardware has been unplugged, the queues cannot be completely cleaned. This causes crashes when the hardware has been unplugged while the radio is still enabled. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 12 ++++++++++-- drivers/net/wireless/rt2x00/rt2x00usb.c | 8 ++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5ba79b935f09..0f34d996975b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -483,6 +483,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry) unsigned int header_length; int rate_idx; + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || + !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + goto submit_entry; + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) goto submit_entry; @@ -567,9 +571,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry) entry->skb = skb; submit_entry: - rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { + rt2x00dev->ops->lib->clear_entry(entry); + rt2x00queue_index_inc(entry->queue, Q_INDEX); + } } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 6dd96192dd91..9ac14598e2a0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Schedule the delayed work for reading the TX status * from the device. */ - if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && - test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); } static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) @@ -409,9 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Schedule the delayed work for reading the RX status * from the device. */ - if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && - test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); } /* -- cgit v1.2.3-59-g8ed1b From fa8b4b22d543b4052602b0c86065150613ed19e8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 4 Nov 2010 20:42:36 +0100 Subject: rt2x00: Fix hw crypto in AP mode for some devices The BSSID register shouldn't be set in AP mode on some older devices (like rt73usb) as it breaks hw crypto on these. However, rt2800 devices explicitly need the BSSID register set to the same value as our own MAC address (only in AP mode). Hence, don't set the BSSID from rt2x00lib but move it down into rt2800 to avoid problems on older devices. This fixes a regression (at least for rt73usb) and avoids a new regression for rt2800 devices in 2.6.36. Reported-by: Johannes Stezenbach Reported-by: Lee Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 13 ++++++++++++- drivers/net/wireless/rt2x00/rt2x00mac.c | 10 ++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6fa654956f4e..a53536dc882d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1148,6 +1148,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags) { u32 reg; + bool update_bssid = false; if (flags & CONFIG_UPDATE_TYPE) { /* @@ -1177,6 +1178,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } if (flags & CONFIG_UPDATE_MAC) { + if (flags & CONFIG_UPDATE_TYPE && + conf->sync == TSF_SYNC_AP_NONE) { + /* + * The BSSID register has to be set to our own mac + * address in AP mode. + */ + memcpy(conf->bssid, conf->mac, sizeof(conf->mac)); + update_bssid = true; + } + if (!is_zero_ether_addr((const u8 *)conf->mac)) { reg = le32_to_cpu(conf->mac[1]); rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); @@ -1187,7 +1198,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, conf->mac, sizeof(conf->mac)); } - if (flags & CONFIG_UPDATE_BSSID) { + if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) { if (!is_zero_ether_addr((const u8 *)conf->bssid)) { reg = le32_to_cpu(conf->bssid[1]); rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 283a8d9874ee..36ddee8dc9e2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -283,14 +283,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, * invalid behavior in the device. */ memcpy(&intf->mac, vif->addr, ETH_ALEN); - if (vif->type == NL80211_IFTYPE_AP) { - memcpy(&intf->bssid, vif->addr, ETH_ALEN); - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, intf->bssid); - } else { - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, NULL); - } + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, + intf->mac, NULL); /* * Some filters depend on the current working mode. We can force -- cgit v1.2.3-59-g8ed1b From 723fc7af5300dba9eac40cb23dbefa67589e5181 Mon Sep 17 00:00:00 2001 From: Lalith Suresh Date: Thu, 4 Nov 2010 20:43:16 +0100 Subject: rt2x00: Fix comments in rt73usb.h and rt61pci.h This patch fixes a few comments in rt73usb.h and rt61pci.h. Signed-off-by: Lalith Suresh Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.h | 2 +- drivers/net/wireless/rt2x00/rt73usb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e2e728ab0b2e..afc803b7959f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -412,7 +412,7 @@ struct hw_pairwise_ta_entry { * DROP_VERSION_ERROR: Drop version error frame. * DROP_MULTICAST: Drop multicast frames. * DROP_BORADCAST: Drop broadcast frames. - * ROP_ACK_CTS: Drop received ACK and CTS. + * DROP_ACK_CTS: Drop received ACK and CTS. */ #define TXRX_CSR0 0x3040 #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 44d5b2bebd39..1315ce5c992f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -322,7 +322,7 @@ struct hw_pairwise_ta_entry { * DROP_VERSION_ERROR: Drop version error frame. * DROP_MULTICAST: Drop multicast frames. * DROP_BORADCAST: Drop broadcast frames. - * ROP_ACK_CTS: Drop received ACK and CTS. + * DROP_ACK_CTS: Drop received ACK and CTS. */ #define TXRX_CSR0 0x3040 #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) -- cgit v1.2.3-59-g8ed1b From ffa56e540c3949c4560dcce45eca247819e183c1 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 4 Nov 2010 22:59:56 +0100 Subject: mac80211: Remove redundant checks for NULL before calls to crypto_free_cipher() crypto_free_cipher() is a wrapper around crypto_free_tfm() which is a wrapper around crypto_destroy_tfm() and the latter can handle being passed a NULL pointer, so checking for NULL in the ieee80211_aes_key_free()/ieee80211_aes_cmac_key_free() wrappers around crypto_free_cipher() is pointless and just increase object code size needlesly and makes us execute extra test/branch instructions that we don't need. Btw; don't we have to many wrappers around wrappers ad nauseam here? Anyway, this patch removes the redundant conditionals. Signed-off-by: Jesper Juhl Signed-off-by: John W. Linville --- net/mac80211/aes_ccm.c | 3 +-- net/mac80211/aes_cmac.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index d2b03e0851ef..4bd6ef0be380 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -147,6 +147,5 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) void ieee80211_aes_key_free(struct crypto_cipher *tfm) { - if (tfm) - crypto_free_cipher(tfm); + crypto_free_cipher(tfm); } diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index b4d66cca76d6..d502b2684a66 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -128,6 +128,5 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) { - if (tfm) - crypto_free_cipher(tfm); + crypto_free_cipher(tfm); } -- cgit v1.2.3-59-g8ed1b From 041fb8f504fb0a6b61bc2131679da554b2fa8c9d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 6 Nov 2010 14:07:10 +0100 Subject: carl9170: tx path review This patch fixes a few shortcomings in the tx path. * move temp. ampdu_[ack]_len out of txinfo->pad. * fix WARN_ON from tx.c:line 300 when tx_ampdu_queue fails to queue the frame. * In tx_prepare, we already have a local pointer to the station's ieee80211_sta struct. * remove a second !sta check, tx_prepare already takes care of that. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b27969c41812..688eede48516 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -242,9 +242,11 @@ static void carl9170_tx_release(struct kref *ref) ar->tx_ampdu_schedule = true; if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { - txinfo->status.ampdu_len = txinfo->pad[0]; - txinfo->status.ampdu_ack_len = txinfo->pad[1]; - txinfo->pad[0] = txinfo->pad[1] = 0; + struct _carl9170_tx_superframe *super; + + super = (void *)skb->data; + txinfo->status.ampdu_len = super->s.rix; + txinfo->status.ampdu_ack_len = super->s.cnt; } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { /* * drop redundant tx_status reports: @@ -337,7 +339,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, u8 tid; if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || - txinfo->flags & IEEE80211_TX_CTL_INJECTED) + txinfo->flags & IEEE80211_TX_CTL_INJECTED || + (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) return; tx_info = IEEE80211_SKB_CB(skb); @@ -389,8 +392,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, sta_info->stats[tid].ampdu_ack_len++; if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { - txinfo->pad[0] = sta_info->stats[tid].ampdu_len; - txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len; + super->s.rix = sta_info->stats[tid].ampdu_len; + super->s.cnt = sta_info->stats[tid].ampdu_ack_len; txinfo->flags |= IEEE80211_TX_STAT_AMPDU; sta_info->stats[tid].clear = true; } @@ -896,10 +899,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (unlikely(!sta || !cvif)) goto err_out; - factor = min_t(unsigned int, 1u, - info->control.sta->ht_cap.ampdu_factor); - - density = info->control.sta->ht_cap.ampdu_density; + factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor); + density = sta->ht_cap.ampdu_density; if (density) { /* @@ -1260,6 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar) static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, struct ieee80211_sta *sta, struct sk_buff *skb) { + struct _carl9170_tx_superframe *super = (void *) super; struct carl9170_sta_info *sta_info; struct carl9170_sta_tid *agg; struct sk_buff *iter; @@ -1328,6 +1330,7 @@ err_unlock: err_unlock_rcu: rcu_read_unlock(); + super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); carl9170_tx_status(ar, skb, false); ar->tx_dropped++; return false; @@ -1356,9 +1359,6 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) */ if (info->flags & IEEE80211_TX_CTL_AMPDU) { - if (WARN_ON_ONCE(!sta)) - goto err_free; - run = carl9170_tx_ampdu_queue(ar, sta, skb); if (run) carl9170_tx_ampdu(ar); -- cgit v1.2.3-59-g8ed1b From 46b9786975a69a75f25b71796f7e36d203fbd4ee Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:44:00 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2400pci.h rt2400pci.h:812: ERROR: space prohibited after that open parenthesis '(' rt2400pci.h:812: ERROR: space prohibited before that close parenthesis ')' rt2400pci.h:813: ERROR: space prohibited after that open parenthesis '(' rt2400pci.h:813: ERROR: space prohibited before that close parenthesis ')' rt2400pci.h:950: ERROR: Macros with complex values should be enclosed in parenthesis Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index c048b18f4133..d3a4a68cc439 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -809,8 +809,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 8 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 8 * sizeof(__le32) ) +#define TXD_DESC_SIZE (8 * sizeof(__le32)) +#define RXD_DESC_SIZE (8 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. @@ -948,6 +948,6 @@ ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER) #define TXPOWER_TO_DEV(__txpower) \ - MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER) + (MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)) #endif /* RT2400PCI_H */ -- cgit v1.2.3-59-g8ed1b From cb771b1a5de81e3ee59bd8b7ed17da6d09ffcf68 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:44:15 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2500pci.h rt2500pci.h:1091: ERROR: space prohibited after that open parenthesis '(' rt2500pci.h:1091: ERROR: space prohibited before that close parenthesis ')' rt2500pci.h:1092: ERROR: space prohibited after that open parenthesis '(' rt2500pci.h:1092: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index d708031361ac..2aad7ba8a100 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h @@ -1088,8 +1088,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 11 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 11 * sizeof(__le32) ) +#define TXD_DESC_SIZE (11 * sizeof(__le32)) +#define RXD_DESC_SIZE (11 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. -- cgit v1.2.3-59-g8ed1b From cf553477a4dfb819c66ebfcad9f3b5cc3b93a9af Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:44:33 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2500usb.c rt2500usb.c:42: ERROR: do not initialise statics to 0 or NULL Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 478c4f127ce6..10e51f208f07 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -39,7 +39,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); -- cgit v1.2.3-59-g8ed1b From fd8dab9a67b22c35f38f0f5bfff4b3f6ed02e43a Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:44:52 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2800.h rt2800.h:1511: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1511: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1513: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1513: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1515: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1515: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1517: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1517: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1519: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1519: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1521: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1521: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1661: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1661: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1662: ERROR: space prohibited after that open parenthesis '(' rt2800.h:1662: ERROR: space prohibited before that close parenthesis ')' rt2800.h:1663: ERROR: space prohibited before that close parenthesis ')' rt2800.h:2013: ERROR: space prohibited after that open parenthesis '(' rt2800.h:2013: ERROR: space prohibited before that close parenthesis ')' rt2800.h:2014: ERROR: space prohibited after that open parenthesis '(' rt2800.h:2014: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 6cfed0638ceb..c2cc126502d6 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1508,17 +1508,17 @@ #define SHARED_KEY_MODE_BASE 0x7000 #define MAC_WCID_ENTRY(__idx) \ - ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) ) + (MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry))) #define PAIRWISE_KEY_ENTRY(__idx) \ - ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) + (PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry))) #define MAC_IVEIV_ENTRY(__idx) \ - ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) + (MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry))) #define MAC_WCID_ATTR_ENTRY(__idx) \ - ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) + (MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32))) #define SHARED_KEY_ENTRY(__idx) \ - ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) + (SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry))) #define SHARED_KEY_MODE_ENTRY(__idx) \ - ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) ) + (SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32))) struct mac_wcid_entry { u8 mac[6]; @@ -1658,9 +1658,9 @@ struct mac_iveiv_entry { #define HW_BEACON_BASE7 0x5bc0 #define HW_BEACON_OFFSET(__index) \ - ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \ - (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \ - (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) ) + (((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \ + (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \ + (HW_BEACON_BASE6 - ((__index - 6) * 0x0200)))) /* * BBP registers. @@ -2010,8 +2010,8 @@ struct mac_iveiv_entry { /* * DMA descriptor defines. */ -#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) ) -#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) ) +#define TXWI_DESC_SIZE (4 * sizeof(__le32)) +#define RXWI_DESC_SIZE (4 * sizeof(__le32)) /* * TX WI structure -- cgit v1.2.3-59-g8ed1b From bf1b15125e2aa245ddd9348f80d041d4f1fd13a9 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:45:06 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2800lib.c rt2800lib.c:831: ERROR: inline keyword should sit between storage class and type Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a53536dc882d..b5d2ebab6ea8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -828,7 +828,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) } EXPORT_SYMBOL_GPL(rt2800_write_beacon); -static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, +static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, unsigned int beacon_base) { int i; -- cgit v1.2.3-59-g8ed1b From c6cbadeb3afd9471e539791842877d085f367746 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:45:22 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2800pci.h rt2800pci.h:41: ERROR: Macros with complex values should be enclosed in parenthesis rt2800pci.h:42: ERROR: Macros with complex values should be enclosed in parenthesis rt2800pci.h:43: ERROR: Macros with complex values should be enclosed in parenthesis rt2800pci.h:44: ERROR: Macros with complex values should be enclosed in parenthesis rt2800pci.h:55: ERROR: space prohibited after that open parenthesis '(' rt2800pci.h:55: ERROR: space prohibited before that close parenthesis ')' rt2800pci.h:56: ERROR: space prohibited after that open parenthesis '(' rt2800pci.h:56: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index 5a8dda9b5b5a..70e050d904c8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -38,10 +38,10 @@ * Queue register offset macros */ #define TX_QUEUE_REG_OFFSET 0x10 -#define TX_BASE_PTR(__x) TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_MAX_CNT(__x) TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_CTX_IDX(__x) TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) +#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) /* * 8051 firmware image. @@ -52,8 +52,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 4 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 4 * sizeof(__le32) ) +#define TXD_DESC_SIZE (4 * sizeof(__le32)) +#define RXD_DESC_SIZE (4 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO and Beacon Ring. -- cgit v1.2.3-59-g8ed1b From 144b80bc05e76df0acb8b5e86a6e6aaf0c53325e Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:45:41 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2800usb.c rt2800usb.c:48: ERROR: do not initialise statics to 0 or NULL Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5c31e3350aac..67a994247a30 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -45,7 +45,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); -- cgit v1.2.3-59-g8ed1b From 87a46caf920515eb269df0109f0a61a958236568 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:45:58 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2800usb.h rt2800usb.h:43: ERROR: space prohibited after that open parenthesis '(' rt2800usb.h:43: ERROR: space prohibited before that close parenthesis ')' rt2800usb.h:44: ERROR: space prohibited after that open parenthesis '(' rt2800usb.h:44: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index 0722badccf86..671ea3592610 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h @@ -40,8 +40,8 @@ /* * DMA descriptor defines. */ -#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) -#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) +#define TXINFO_DESC_SIZE (1 * sizeof(__le32)) +#define RXINFO_DESC_SIZE (1 * sizeof(__le32)) /* * TX Info structure -- cgit v1.2.3-59-g8ed1b From 8a239033c355be998b8985f12f0cc3a9eaeb93e9 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:46:17 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2x00config.c rt2x00config.c:136: ERROR: space required before the open parenthesis '(' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 54ffb5aeb34e..fca8f22896a5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -133,7 +133,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); - else if(config.rx == ANTENNA_SW_DIVERSITY) + else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) -- cgit v1.2.3-59-g8ed1b From c2361baec100c6f373107346e3fd98e9b267ac6c Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:46:36 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2x00dev.c rt2x00dev.c:689: ERROR: spaces required around that '=' (ctx:WxV) Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 0f34d996975b..5793afef1c08 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -686,7 +686,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry, { entry->flags = 0; entry->bitrate = rate->bitrate; - entry->hw_value =index; + entry->hw_value = index; entry->hw_value_short = index; if (rate->flags & DEV_RATE_SHORT_PREAMBLE) -- cgit v1.2.3-59-g8ed1b From 5f181dc16bbd13b68b54ed5c43c4d2c5ad00297b Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:46:53 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2x00lib.h rt2x00lib.h:60: ERROR: space prohibited after that open parenthesis '(' rt2x00lib.h:60: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00lib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 619da23b7b56..983540200096 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -57,7 +57,7 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) } #define RATE_MCS(__mode, __mcs) \ - ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) ) + ((((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff)) static inline int rt2x00_get_rate_mcs(const u16 mcs_value) { -- cgit v1.2.3-59-g8ed1b From 027e8fd105c82956de9dec232bad21b1628ee7c0 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:47:09 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2x00link.c rt2x00link.c:70: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index b971d8798ebf..bfda60eaf4ef 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -67,7 +67,7 @@ (__avg).avg_weight ? \ ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \ ((__val) * (AVG_FACTOR))) / \ - (AVG_SAMPLES) ) : \ + (AVG_SAMPLES)) : \ ((__val) * (AVG_FACTOR)); \ __new.avg = __new.avg_weight / (AVG_FACTOR); \ __new; \ -- cgit v1.2.3-59-g8ed1b From f8bfbc31794635f6d0b7fd30950d49cecf54e1ce Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:47:25 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt2x00queue.c rt2x00queue.c:804: ERROR: space prohibited after that open parenthesis '(' rt2x00queue.c:805: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4e2a8c2e014d..32d6a17d5aa0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -801,8 +801,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return -ENOMEM; #define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ - ( ((char *)(__base)) + ((__limit) * (__esize)) + \ - ((__index) * (__psize)) ) + (((char *)(__base)) + ((__limit) * (__esize)) + \ + ((__index) * (__psize))) for (i = 0; i < queue->limit; i++) { entries[i].flags = 0; -- cgit v1.2.3-59-g8ed1b From 821cde63b5bd04bc3ca0f95e2abf17b04e640488 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sat, 6 Nov 2010 15:47:46 +0100 Subject: rt2x00: checkpatch.pl error fixes for rt73usb.c rt73usb.c:43: ERROR: do not initialise statics to 0 or NULL Signed-off-by: Mark Einon Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index dcb9211c4771..29602b5f01f8 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -40,7 +40,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); -- cgit v1.2.3-59-g8ed1b From 813f0339dd739c48607f12dac79ec26c61874226 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 6 Nov 2010 15:48:05 +0100 Subject: rt2x00: Rename queue->lock to queue->index_lock The queue->lock is only used to protect the index numbers. Rename the lock accordingly. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00debug.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00queue.c | 18 +++++++++--------- drivers/net/wireless/rt2x00/rt2x00queue.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 8296a9d47bbd..64dfb1f6823e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -342,7 +342,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length, @@ -350,7 +350,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, queue->index[Q_INDEX_DMA_DONE], queue->index[Q_INDEX_DONE]); - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } size = strlen(data); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 32d6a17d5aa0..aa4c8f2dc7df 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -641,10 +641,10 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, * it should not be kicked during this run, since it * is part of another TX operation. */ - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); index_start = queue->index[start]; index_end = queue->index[end]; - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); /* * Start from the TX done pointer, this guarentees that we will @@ -698,11 +698,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, return NULL; } - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); entry = &queue->entries[queue->index[index]]; - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); return entry; } @@ -718,7 +718,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) return; } - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); queue->index[index]++; if (queue->index[index] >= queue->limit) @@ -733,7 +733,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) queue->count++; } - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } static void rt2x00queue_reset(struct data_queue *queue) @@ -741,7 +741,7 @@ static void rt2x00queue_reset(struct data_queue *queue) unsigned long irqflags; unsigned int i; - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); queue->count = 0; queue->length = 0; @@ -751,7 +751,7 @@ static void rt2x00queue_reset(struct data_queue *queue) queue->last_action[i] = jiffies; } - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) @@ -903,7 +903,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { - spin_lock_init(&queue->lock); + spin_lock_init(&queue->index_lock); queue->rt2x00dev = rt2x00dev; queue->qid = qid; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 64c00e2ab716..29b051ac6401 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -398,7 +398,7 @@ enum queue_index { * @entries: Base address of the &struct queue_entry which are * part of this queue. * @qid: The queue identification, see &enum data_queue_qid. - * @lock: Spinlock to protect index handling. Whenever @index, @index_done or + * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or * @index_crypt needs to be changed this lock should be grabbed to prevent * index corruption due to concurrency. * @count: Number of frames handled in the queue. @@ -422,7 +422,7 @@ struct data_queue { enum data_queue_qid qid; - spinlock_t lock; + spinlock_t index_lock; unsigned int count; unsigned short limit; unsigned short threshold; -- cgit v1.2.3-59-g8ed1b From 8be4eed0ea7d8ef38692de878043a949e9db16e8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 6 Nov 2010 15:48:23 +0100 Subject: rt2x00: Fix rt2x00queue_kick_tx_queue arguments The queue_entry argument to rt2x00queue_kick_tx_queue, doesn't make sense due to the function name (it is called kick QUEUE)... But neither do we need the queue_entry, since we need the data_queue. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index aa4c8f2dc7df..dc543174dfad 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -452,12 +452,9 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); } -static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, +static void rt2x00queue_kick_tx_queue(struct data_queue *queue, struct txentry_desc *txdesc) { - struct data_queue *queue = entry->queue; - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - /* * Check if we need to kick the queue, there are however a few rules * 1) Don't kick unless this is the last in frame in a burst. @@ -469,7 +466,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, */ if (rt2x00queue_threshold(queue) || !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - rt2x00dev->ops->lib->kick_tx_queue(queue); + queue->rt2x00dev->ops->lib->kick_tx_queue(queue); } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, @@ -559,7 +556,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rt2x00queue_index_inc(queue, Q_INDEX); rt2x00queue_write_tx_descriptor(entry, &txdesc); - rt2x00queue_kick_tx_queue(entry, &txdesc); + rt2x00queue_kick_tx_queue(queue, &txdesc); return 0; } -- cgit v1.2.3-59-g8ed1b From ea175ee26268370ca07aff91cf6ba1e0f1a3bd36 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 6 Nov 2010 15:48:43 +0100 Subject: rt2x00: Remove rt2x00lib_toggle_rx As part of the queue refactoring, the rt2x00lib_toggle_rx can be removed and replaced with the call directly to the set_device_state callback function. We can remove the STATE_RADIO_RX_ON_LINK and STATE_RADIO_RX_OFF_LINK, as it was only used for special behavior inside rt2x00lib rather then the drivers. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2500pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2500usb.c | 5 +---- drivers/net/wireless/rt2x00/rt2800pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2800usb.c | 5 +---- drivers/net/wireless/rt2x00/rt2x00config.c | 6 ++++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 23 ++++------------------- drivers/net/wireless/rt2x00/rt2x00lib.h | 1 - drivers/net/wireless/rt2x00/rt2x00mac.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00reg.h | 2 -- drivers/net/wireless/rt2x00/rt61pci.c | 5 +---- drivers/net/wireless/rt2x00/rt73usb.c | 5 +---- 12 files changed, 17 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index bc1ae1ebfdb0..9ec6691adf0d 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -885,8 +885,7 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -989,9 +988,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2400pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 54754150250b..3e7f20346243 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1040,8 +1040,7 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -1144,9 +1143,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2500pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 10e51f208f07..8152fec31753 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -938,8 +938,7 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); } @@ -1019,9 +1018,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2500usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 1db0c3bf2e1f..5f3a018c088d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -328,8 +328,7 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON) || - (state == STATE_RADIO_RX_ON_LINK)); + (state == STATE_RADIO_RX_ON)); rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); } @@ -477,9 +476,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2800pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 67a994247a30..f93337128504 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -114,8 +114,7 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON) || - (state == STATE_RADIO_RX_ON_LINK)); + (state == STATE_RADIO_RX_ON)); rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); } @@ -216,9 +215,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2800usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index fca8f22896a5..a238e908c854 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -146,7 +146,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_RX_OFF); /* * Write new antenna setup to device and reset the link tuner. @@ -160,7 +161,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_RX_ON); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5793afef1c08..3afa2a3ebee4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -68,7 +68,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Enable RX. */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00link_start_tuner(rt2x00dev); /* * Start watchdog monitoring. @@ -102,7 +103,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Disable RX. */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00link_stop_tuner(rt2x00dev); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); /* * Disable radio. @@ -113,23 +115,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00leds_led_radio(rt2x00dev, false); } -void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) -{ - /* - * When we are disabling the RX, we should also stop the link tuner. - */ - if (state == STATE_RADIO_RX_OFF) - rt2x00link_stop_tuner(rt2x00dev); - - rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); - - /* - * When we are enabling the RX, we should also start the link tuner. - */ - if (state == STATE_RADIO_RX_ON) - rt2x00link_start_tuner(rt2x00dev); -} - static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 983540200096..2cf68f82674b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -69,7 +69,6 @@ static inline int rt2x00_get_rate_mcs(const u16 mcs_value) */ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); -void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state); /* * Initialization handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 36ddee8dc9e2..829bf4be9bc3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) * if for any reason the link tuner must be reset, this will be * handled by rt2x00lib_config(). */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); /* * When we've just turned on the radio, we want to reprogram @@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index cef94621cef7..ed71be95136d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -85,8 +85,6 @@ enum dev_state { STATE_RADIO_OFF, STATE_RADIO_RX_ON, STATE_RADIO_RX_OFF, - STATE_RADIO_RX_ON_LINK, - STATE_RADIO_RX_OFF_LINK, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, STATE_RADIO_IRQ_ON_ISR, diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f01bff7656bc..6b09b01f634f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1623,8 +1623,7 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1745,9 +1744,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt61pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 29602b5f01f8..6f04552f5819 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1331,8 +1331,7 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1403,9 +1402,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt73usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: -- cgit v1.2.3-59-g8ed1b From 8c5765fda4b382acce4ff386e18ec11790dff893 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 6 Nov 2010 15:49:01 +0100 Subject: rt2x00: Add watchdog functions for HW queue Add watchdog functions for managing the Queues inside the hardware. Normally the driver doesn't have much to do with these queues directly, but the Ralink drivers did implement watchdog functions for these. These watchdog functions are not triggered that often, compared to the other watchdog functions, but I have at least seen them trigger once or twice during a long stresstest run. v2: Add extra documentation for register fields Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 16 ++++++++++-- drivers/net/wireless/rt2x00/rt2800usb.c | 45 ++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c2cc126502d6..002224c9bb62 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -412,10 +412,22 @@ #define BCN_OFFSET1_BCN7 FIELD32(0xff000000) /* - * PBF registers - * Most are for debug. Driver doesn't touch PBF register. + * TXRXQ_PCNT: PBF register + * PCNT_TX0Q: Page count for TX hardware queue 0 + * PCNT_TX1Q: Page count for TX hardware queue 1 + * PCNT_TX2Q: Page count for TX hardware queue 2 + * PCNT_RX0Q: Page count for RX hardware queue */ #define TXRXQ_PCNT 0x0438 +#define TXRXQ_PCNT_TX0Q FIELD32(0x000000ff) +#define TXRXQ_PCNT_TX1Q FIELD32(0x0000ff00) +#define TXRXQ_PCNT_TX2Q FIELD32(0x00ff0000) +#define TXRXQ_PCNT_RX0Q FIELD32(0xff000000) + +/* + * PBF register + * Debug. Driver doesn't touch PBF register. + */ #define PBF_DBG 0x043c /* diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f93337128504..389ecba8e891 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -242,6 +242,49 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, return retval; } +/* + * Watchdog handlers + */ +static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) +{ + unsigned int i; + u32 reg; + + rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { + WARNING(rt2x00dev, "TX HW queue 0 timed out," + " invoke forced kick"); + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); + + for (i = 0; i < 10; i++) { + udelay(10); + if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) + break; + } + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + } + + rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { + WARNING(rt2x00dev, "TX HW queue 1 timed out," + " invoke forced kick"); + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); + + for (i = 0; i < 10; i++) { + udelay(10); + if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) + break; + } + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + } + + rt2x00usb_watchdog(rt2x00dev); +} + /* * TX descriptor initialization */ @@ -534,7 +577,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, - .watchdog = rt2x00usb_watchdog, + .watchdog = rt2800usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, -- cgit v1.2.3-59-g8ed1b From 5d882c97e2c958df9f8b78832fa1ecbecef6ea1d Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 8 Nov 2010 10:50:03 -0800 Subject: ath5k: Print stats as unsigned ints. The debugfs code for ath5k was printing some unsigned int stats with %d instead of %u. This meant that you could see negative numbers instead of a clean wrap. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index acda56ee521b..54dcf77e9646 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -554,63 +554,63 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "RX\n---------------------\n"); - len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n", st->rxerr_crc, st->rx_all_count > 0 ? st->rxerr_crc*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n", st->rxerr_phy, st->rx_all_count > 0 ? st->rxerr_phy*100/st->rx_all_count : 0); for (i = 0; i < 32; i++) { if (st->rxerr_phy_code[i]) len += snprintf(buf+len, sizeof(buf)-len, - " phy_err[%d]\t%d\n", + " phy_err[%u]\t%u\n", i, st->rxerr_phy_code[i]); } - len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n", st->rxerr_fifo, st->rx_all_count > 0 ? st->rxerr_fifo*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n", st->rxerr_decrypt, st->rx_all_count > 0 ? st->rxerr_decrypt*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n", st->rxerr_mic, st->rx_all_count > 0 ? st->rxerr_mic*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n", st->rxerr_proc, st->rx_all_count > 0 ? st->rxerr_proc*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n", st->rxerr_jumbo, st->rx_all_count > 0 ? st->rxerr_jumbo*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", + len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n", st->rx_all_count); - len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n", + len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n", st->rx_bytes_count); len += snprintf(buf+len, sizeof(buf)-len, "\nTX\n---------------------\n"); - len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n", st->txerr_retry, st->tx_all_count > 0 ? st->txerr_retry*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n", st->txerr_fifo, st->tx_all_count > 0 ? st->txerr_fifo*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n", + len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n", st->txerr_filt, st->tx_all_count > 0 ? st->txerr_filt*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", + len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n", st->tx_all_count); - len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n", + len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n", st->tx_bytes_count); if (len > sizeof(buf)) -- cgit v1.2.3-59-g8ed1b From 8b37d9f0a1e114a1c7f5082842fb310a81ea3732 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:35 -0800 Subject: iwlagn: update PCI ID for 6000g2b series devices Update the supported PCI ID list for 6000g2b series devices Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 481c993c2491..073e106e58e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4449,24 +4449,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)}, /* 6x00 Series Gen2b */ - {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)}, - {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl6000g2b_bg_cfg)}, {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl6000g2b_bg_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, -- cgit v1.2.3-59-g8ed1b From fb30eaf38703d7562606e49a5872745d66366a50 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:36 -0800 Subject: iwlagn: update PCI ID for 6000g2a series devices Update the supported PCI ID list for 6000g2a series devices Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 073e106e58e7..cc2683ad7297 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4433,13 +4433,6 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, /* 6x00 Series Gen2a */ - {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)}, -- cgit v1.2.3-59-g8ed1b From 2a21ff446c07b95d08cbb830bd20112f3ee1d76e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:37 -0800 Subject: iwlagn: update PCI ID for 100 series devices Update the supported PCI ID list for 100 series devices Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cc2683ad7297..f7feac22a47c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4491,10 +4491,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { /* 100 Series WiFi */ {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, /* 130 Series WiFi */ {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, -- cgit v1.2.3-59-g8ed1b From ae79d23d0b2c16998e60f49a16dae53521c76a45 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 09:56:38 -0800 Subject: iwlagn: fix non-5000+ build When building 4965 without 5000+ there were a lot of build errors due to functions being used that weren't even compiled in. To fix this move some code around and only compile the HCMD code for 5000+ series as it's not used for 4965. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 16 -------------- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 16 ++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 32 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn.c | 34 ++++------------------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 5 ++++- 6 files changed, 57 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index ce05c260870e..b85a9c8ed01e 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -12,13 +12,13 @@ CFLAGS_iwl-devtrace.o := -I$(src) # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o -iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o +iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o -iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o +iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwlagn-$(CONFIG_IWL5000) += iwl-5000.o iwlagn-$(CONFIG_IWL5000) += iwl-6000.o iwlagn-$(CONFIG_IWL5000) += iwl-1000.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3427fc2b7d68..019d4e7d7348 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1587,22 +1587,6 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) return ret; } -void iwlagn_post_scan(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx; - - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - for_each_context(priv, ctx) - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwlagn_commit_rxon(priv, ctx); - - if (priv->cfg->ops->hcmd->set_pan_params) - priv->cfg->ops->hcmd->set_pan_params(priv); -} - int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 11b3d8888360..f0ddfb1a9c87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -585,3 +585,19 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); } + +void iwlagn_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + for_each_context(priv, ctx) + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlagn_commit_rxon(priv, ctx); + + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 35a30d2e0734..35f085ac336b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -684,7 +684,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) +static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) { unsigned long flags; @@ -714,3 +714,33 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) spin_unlock_irqrestore(&priv->sta_lock, flags); } + +void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + int sta_id; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + WARN_ON(!sta_priv->client); + sta_priv->asleep = true; + if (atomic_read(&sta_priv->pending_frames) > 0) + ieee80211_sta_block_awake(hw, sta, true); + break; + case STA_NOTIFY_AWAKE: + WARN_ON(!sta_priv->client); + if (!sta_priv->asleep) + break; + sta_priv->asleep = false; + sta_id = iwl_sta_id(sta); + if (sta_id != IWL_INVALID_STATION) + iwl_sta_modify_ps_wake(priv, sta_id); + break; + default: + break; + } +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f7feac22a47c..573017474610 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3474,36 +3474,6 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, return ret; } -static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - int sta_id; - - switch (cmd) { - case STA_NOTIFY_SLEEP: - WARN_ON(!sta_priv->client); - sta_priv->asleep = true; - if (atomic_read(&sta_priv->pending_frames) > 0) - ieee80211_sta_block_awake(hw, sta, true); - break; - case STA_NOTIFY_AWAKE: - WARN_ON(!sta_priv->client); - if (!sta_priv->asleep) - break; - sta_priv->asleep = false; - sta_id = iwl_sta_id(sta); - if (sta_id != IWL_INVALID_STATION) - iwl_sta_modify_ps_wake(priv, sta_id); - break; - default: - break; - } -} - int iwlagn_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -3903,6 +3873,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } +#ifdef CONFIG_IWL5000 struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, @@ -3925,6 +3896,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .flush = iwlagn_mac_flush, .tx_last_beacon = iwl_mac_tx_last_beacon, }; +#endif static void iwl_hw_detect(struct iwl_priv *priv) { @@ -3992,7 +3964,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (cfg->mod_params->disable_hw_scan) { dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); +#ifdef CONFIG_IWL5000 iwlagn_hw_ops.hw_scan = NULL; +#endif #ifdef CONFIG_IWL4965 iwl4965_hw_ops.hw_scan = NULL; #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index aca93f4477a8..28837a185a28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -301,9 +301,12 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid, u16 ssn); int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid); -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); int iwl_update_bcast_stations(struct iwl_priv *priv); +void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta); /* rate */ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) -- cgit v1.2.3-59-g8ed1b From 81baf6ec9c190ae128748cf2a026bff5cb811b70 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:39 -0800 Subject: iwlwifi: Legacy isr only used by legacy devices Move iwl_isr_legacy function to iwl_legacy.c since it only used by legacy devices. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 60 ------------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-legacy.c | 62 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-legacy.h | 2 + 5 files changed, 65 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index d9e676480269..a97c09992a73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -51,6 +51,7 @@ #include "iwl-led.h" #include "iwl-3945-led.h" #include "iwl-3945-debugfs.h" +#include "iwl-legacy.h" #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 180d09ec3136..f8d801cc24fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1227,66 +1227,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) } EXPORT_SYMBOL(iwl_set_tx_power); -irqreturn_t iwl_isr_legacy(int irq, void *data) -{ - struct iwl_priv *priv = data; - u32 inta, inta_mask; - u32 inta_fh; - unsigned long flags; - if (!priv) - return IRQ_NONE; - - spin_lock_irqsave(&priv->lock, flags); - - /* Disable (but don't clear!) interrupts here to avoid - * back-to-back ISRs and sporadic interrupts from our NIC. - * If we have something to service, the tasklet will re-enable ints. - * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); - - /* Discover which interrupts are active/pending */ - inta = iwl_read32(priv, CSR_INT); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - - /* Ignore interrupt if there's nothing in NIC to service. - * This may be due to IRQ shared with another device, - * or due to sporadic interrupts thrown from our NIC. */ - if (!inta && !inta_fh) { - IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n"); - goto none; - } - - if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { - /* Hardware disappeared. It might have already raised - * an interrupt */ - IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); - goto unplugged; - } - - IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - - inta &= ~CSR_INT_BIT_SCD; - - /* iwl_irq_tasklet() will service interrupts and re-enable them */ - if (likely(inta || inta_fh)) - tasklet_schedule(&priv->irq_tasklet); - - unplugged: - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_HANDLED; - - none: - /* re-enable interrupts here since we don't have anything to service. */ - /* only Re-enable if diabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_NONE; -} -EXPORT_SYMBOL(iwl_isr_legacy); - void iwl_send_bt_config(struct iwl_priv *priv) { struct iwl_bt_cmd bt_cmd = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8fb063affac4..7505c16db2a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -596,7 +596,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); /***************************************************** * PCI * *****************************************************/ -irqreturn_t iwl_isr_legacy(int irq, void *data); static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index b735fef9ee4b..f49e500cba67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -31,6 +31,7 @@ #include "iwl-dev.h" #include "iwl-core.h" +#include "iwl-helpers.h" #include "iwl-legacy.h" /** @@ -558,3 +559,64 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); + +irqreturn_t iwl_isr_legacy(int irq, void *data) +{ + struct iwl_priv *priv = data; + u32 inta, inta_mask; + u32 inta_fh; + unsigned long flags; + if (!priv) + return IRQ_NONE; + + spin_lock_irqsave(&priv->lock, flags); + + /* Disable (but don't clear!) interrupts here to avoid + * back-to-back ISRs and sporadic interrupts from our NIC. + * If we have something to service, the tasklet will re-enable ints. + * If we *don't* have something, we'll re-enable before leaving here. */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ + iwl_write32(priv, CSR_INT_MASK, 0x00000000); + + /* Discover which interrupts are active/pending */ + inta = iwl_read32(priv, CSR_INT); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + + /* Ignore interrupt if there's nothing in NIC to service. + * This may be due to IRQ shared with another device, + * or due to sporadic interrupts thrown from our NIC. */ + if (!inta && !inta_fh) { + IWL_DEBUG_ISR(priv, + "Ignore interrupt, inta == 0, inta_fh == 0\n"); + goto none; + } + + if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { + /* Hardware disappeared. It might have already raised + * an interrupt */ + IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); + goto unplugged; + } + + IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + + inta &= ~CSR_INT_BIT_SCD; + + /* iwl_irq_tasklet() will service interrupts and re-enable them */ + if (likely(inta || inta_fh)) + tasklet_schedule(&priv->irq_tasklet); + +unplugged: + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; + +none: + /* re-enable interrupts here since we don't have anything to service. */ + /* only Re-enable if diabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_NONE; +} +EXPORT_SYMBOL(iwl_isr_legacy); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h index 2a746cbc30fe..81d1ccdb0746 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.h +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h @@ -71,4 +71,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changes); +irqreturn_t iwl_isr_legacy(int irq, void *data); + #endif /* __iwl_legacy_h__ */ -- cgit v1.2.3-59-g8ed1b From e39fdee1d7856817619326fa114438c146d74510 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:40 -0800 Subject: iwlwifi: put all the isr related function under ops There were two type of isr supported by iwlwifi devices. legacy isr - only used by legacy devices (3945 & 4965) ict isr - used by all new generation of iwlwifi devices Move all the isr related functions into ops, the ict type of isr supports only needed for newer devices. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 4 ++-- drivers/net/wireless/iwlwifi/iwl-1000.c | 8 +++++++- drivers/net/wireless/iwlwifi/iwl-3945.c | 4 +++- drivers/net/wireless/iwlwifi/iwl-4965.c | 4 +++- drivers/net/wireless/iwlwifi/iwl-5000.c | 16 ++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 ++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 ++++++++++++------ drivers/net/wireless/iwlwifi/iwl-core.h | 12 +++++++++++- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 9 files changed, 67 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index b85a9c8ed01e..01aa2468bd69 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -11,14 +11,14 @@ CFLAGS_iwl-devtrace.o := -I$(src) # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o -iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o +iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o -iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o +iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o iwlagn-$(CONFIG_IWL5000) += iwl-5000.o iwlagn-$(CONFIG_IWL5000) += iwl-6000.o iwlagn-$(CONFIG_IWL5000) += iwl-1000.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index baedea8e4d04..068f1e1e3297 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -211,7 +211,13 @@ static struct iwl_lib_ops iwl1000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .isr = iwl_isr_ict, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, .temp_ops = { .temperature = iwlagn_temperature, }, diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a97c09992a73..1ab171949021 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2727,7 +2727,9 @@ static struct iwl_lib_ops iwl3945_lib = { }, .send_tx_power = iwl3945_send_tx_power, .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, - .isr = iwl_isr_legacy, + .isr_ops = { + .isr = iwl_isr_legacy, + }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl3945_good_plcp_health, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6d313c817040..a6518caa405c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2561,7 +2561,9 @@ static struct iwl_lib_ops iwl4965_lib = { }, .send_tx_power = iwl4965_send_tx_power, .update_chain_flags = iwl_update_chain_flags, - .isr = iwl_isr_legacy, + .isr_ops = { + .isr = iwl_isr_legacy, + }, .temp_ops = { .temperature = iwl4965_temperature_calib, }, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e1f412f915ae..ad43f0fdf919 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -385,7 +385,13 @@ static struct iwl_lib_ops iwl5000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .isr = iwl_isr_ict, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, .temp_ops = { .temperature = iwlagn_temperature, }, @@ -449,7 +455,13 @@ static struct iwl_lib_ops iwl5150_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .isr = iwl_isr_ict, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, .temp_ops = { .temperature = iwl5150_temperature, }, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index b1816900980c..21ac2817722e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -322,7 +322,13 @@ static struct iwl_lib_ops iwl6000_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .isr = iwl_isr_ict, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, .temp_ops = { .temperature = iwlagn_temperature, }, @@ -389,7 +395,13 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .isr = iwl_isr_ict, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, .temp_ops = { .temperature = iwlagn_temperature, }, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 573017474610..007fb20d78ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2815,7 +2815,8 @@ static void __iwl_down(struct iwl_priv *priv) STATUS_EXIT_PENDING; /* device going down, Stop using ICT table */ - iwl_disable_ict(priv); + if (priv->cfg->ops->lib->isr_ops.disable) + priv->cfg->ops->lib->isr_ops.disable(priv); iwlagn_txq_ctx_stop(priv); iwlagn_rxq_stop(priv); @@ -3038,7 +3039,8 @@ static void iwl_bg_alive_start(struct work_struct *data) return; /* enable dram interrupt */ - iwl_reset_ict(priv); + if (priv->cfg->ops->lib->isr_ops.reset) + priv->cfg->ops->lib->isr_ops.reset(priv); mutex_lock(&priv->mutex); iwl_alive_start(priv); @@ -4172,8 +4174,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_enable_msi(priv->pci_dev); - iwl_alloc_isr_ict(priv); - err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, + if (priv->cfg->ops->lib->isr_ops.alloc) + priv->cfg->ops->lib->isr_ops.alloc(priv); + + err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); @@ -4220,7 +4224,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) destroy_workqueue(priv->workqueue); priv->workqueue = NULL; free_irq(priv->pci_dev->irq, priv); - iwl_free_isr_ict(priv); + if (priv->cfg->ops->lib->isr_ops.free) + priv->cfg->ops->lib->isr_ops.free(priv); out_disable_msi: pci_disable_msi(priv->pci_dev); iwl_uninit_drv(priv); @@ -4315,7 +4320,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_uninit_drv(priv); - iwl_free_isr_ict(priv); + if (priv->cfg->ops->lib->isr_ops.free) + priv->cfg->ops->lib->isr_ops.free(priv); dev_kfree_skb(priv->beacon_skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7505c16db2a2..c9723da040fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -120,6 +120,14 @@ struct iwl_apm_ops { void (*config)(struct iwl_priv *priv); }; +struct iwl_isr_ops { + irqreturn_t (*isr) (int irq, void *data); + void (*free)(struct iwl_priv *priv); + int (*alloc)(struct iwl_priv *priv); + int (*reset)(struct iwl_priv *priv); + void (*disable)(struct iwl_priv *priv); +}; + struct iwl_debugfs_ops { ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); @@ -193,7 +201,9 @@ struct iwl_lib_ops { /* power */ int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); - irqreturn_t (*isr) (int irq, void *data); + + /* isr */ + struct iwl_isr_ops isr_ops; /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6152a86c19b5..a55b4623e1c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4120,7 +4120,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e pci_enable_msi(priv->pci_dev); - err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, + err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); -- cgit v1.2.3-59-g8ed1b From 708068db4c09f93937a6a83ac8fff8516f482b0f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:41 -0800 Subject: iwlwifi: legacy tx_cmd_protection function Legacy (4965 and 3945) devices has different tx_cmd_protection routine. Move to iwl-legacy.c Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 34 ------------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 4 +--- drivers/net/wireless/iwlwifi/iwl-legacy.c | 34 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-legacy.h | 3 +++ 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 1ab171949021..ebac04b7887c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2749,7 +2749,7 @@ static const struct iwl_legacy_ops iwl3945_legacy_ops = { static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .get_hcmd_size = iwl3945_get_hcmd_size, .build_addsta_hcmd = iwl3945_build_addsta_hcmd, - .tx_cmd_protection = iwlcore_tx_cmd_protection, + .tx_cmd_protection = iwl_legacy_tx_cmd_protection, .request_scan = iwl3945_request_scan, .post_scan = iwl3945_post_scan, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index a6518caa405c..cd14843878ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2514,7 +2514,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .build_addsta_hcmd = iwl4965_build_addsta_hcmd, .chain_noise_reset = iwl4965_chain_noise_reset, .gain_computation = iwl4965_gain_computation, - .tx_cmd_protection = iwlcore_tx_cmd_protection, + .tx_cmd_protection = iwl_legacy_tx_cmd_protection, .calc_rssi = iwl4965_calc_rssi, .request_scan = iwlagn_request_scan, .post_scan = iwl4965_post_scan, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f8d801cc24fc..c884ed385fcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -288,40 +288,6 @@ void iwlcore_free_geos(struct iwl_priv *priv) } EXPORT_SYMBOL(iwlcore_free_geos); -/* - * iwlcore_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this - * function. - */ -void iwlcore_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags) -{ - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - *tx_flags |= TX_CMD_FLG_RTS_MSK; - *tx_flags &= ~TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - - if (!ieee80211_is_mgmt(fc)) - return; - - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - break; - } - } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - } -} -EXPORT_SYMBOL(iwlcore_tx_cmd_protection); - - static bool iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, u16 channel, u8 extension_chan_offset) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c9723da040fc..6064bc412e07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -447,9 +447,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, enum nl80211_iftype newtype, bool newp2p); int iwl_alloc_txq_mem(struct iwl_priv *priv); void iwl_free_txq_mem(struct iwl_priv *priv); -void iwlcore_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags); + #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_alloc_traffic_mem(struct iwl_priv *priv); void iwl_free_traffic_mem(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index f49e500cba67..10d9c4202875 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -620,3 +620,37 @@ none: return IRQ_NONE; } EXPORT_SYMBOL(iwl_isr_legacy); + +/* + * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this + * function. + */ +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags) +{ + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + *tx_flags |= TX_CMD_FLG_RTS_MSK; + *tx_flags &= ~TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + + if (!ieee80211_is_mgmt(fc)) + return; + + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_AUTH): + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): + case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + break; + } + } else if (info->control.rates[0].flags & + IEEE80211_TX_RC_USE_CTS_PROTECT) { + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + } +} +EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h index 81d1ccdb0746..9f7b2f935964 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.h +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h @@ -70,6 +70,9 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags); irqreturn_t iwl_isr_legacy(int irq, void *data); -- cgit v1.2.3-59-g8ed1b From fd11743dd25efe7157ff17b03dd2db0cbb6fed05 Mon Sep 17 00:00:00 2001 From: "Winkler, Tomas" Date: Wed, 10 Nov 2010 09:56:42 -0800 Subject: iwlwlifi: update rx write pointer w/o request mac access in the CAM mode In iwl_rx_queue_update_write_ptr function replace iwl_write_direct32 with iwl_write32 when not in power save mode. We don't have to go through grab nic access as the NIC is already awake. Signed-off-by: Tomas Winkler Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index f436270ca39a..baca4cc0073b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -153,7 +153,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q } else { /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual); + iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual); } q->need_update = 0; -- cgit v1.2.3-59-g8ed1b From 35a6eb36520b938742d8680fd8d821df20982ced Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:43 -0800 Subject: iwlwifi: resending QoS command when HT changes "mac80211: Fix WMM driver queue configuration" inadvertedly broke iwlwifi, because now mac80211 configures the QoS settings before assoc, and therefore before HT. Thus, iwlwifi no longer told the device about the HT setting, which it needs to -- and thus throughput went down a lot. Fix this by resending the QoS command to the device not only when QoS/WMM settings change, but also when HT changes. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 65 ++++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-legacy.c | 60 ++++++++++++++------------ 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index f0ddfb1a9c87..02288779a71f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -269,6 +269,34 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } +static void iwlagn_update_qos(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm); + if (ret) + IWL_ERR(priv, "Failed to update QoS\n"); +} + int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; @@ -277,6 +305,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_channel *channel = conf->channel; const struct iwl_channel_info *ch_info; int ret = 0; + bool ht_changed[NUM_IWL_RXON_CTX] = {}; IWL_DEBUG_MAC80211(priv, "changed %#x", changed); @@ -324,7 +353,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) for_each_context(priv, ctx) { /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled != conf_is_ht(conf)) { + ctx->ht.enabled = conf_is_ht(conf); + ht_changed[ctx->ctxid] = true; + } + if (ctx->ht.enabled) { if (conf_is_ht40_minus(conf)) { ctx->ht.extension_chan_offset = @@ -392,40 +425,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) continue; iwlagn_commit_rxon(priv, ctx); + if (ht_changed[ctx->ctxid]) + iwlagn_update_qos(priv, ctx); } out: mutex_unlock(&priv->mutex); return ret; } -static void iwlagn_update_qos(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int ret; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm); - if (ret) - IWL_ERR(priv, "Failed to update QoS\n"); -} - static void iwlagn_check_needed_chains(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_bss_conf *bss_conf) diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index 10d9c4202875..a08b4e56e6b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -34,6 +34,32 @@ #include "iwl-helpers.h" #include "iwl-legacy.h" +static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm, NULL); +} + /** * iwl_legacy_mac_config - mac80211 config callback */ @@ -49,6 +75,7 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) int ret = 0; u16 ch; int scan_active = 0; + bool ht_changed[NUM_IWL_RXON_CTX] = {}; if (WARN_ON(!priv->cfg->ops->legacy)) return -EOPNOTSUPP; @@ -100,7 +127,10 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) for_each_context(priv, ctx) { /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled != conf_is_ht(conf)) { + ctx->ht.enabled = conf_is_ht(conf); + ht_changed[ctx->ctxid] = true; + } if (ctx->ht.enabled) { if (conf_is_ht40_minus(conf)) { ctx->ht.extension_chan_offset = @@ -177,6 +207,8 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) else IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n"); + if (ht_changed[ctx->ctxid]) + iwl_update_qos(priv, ctx); } out: @@ -295,32 +327,6 @@ static void iwl_ht_conf(struct iwl_priv *priv, IWL_DEBUG_ASSOC(priv, "leave\n"); } -static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); -} - static inline void iwl_set_no_assoc(struct iwl_priv *priv, struct ieee80211_vif *vif) { -- cgit v1.2.3-59-g8ed1b From 2e1fea43aa170e18beb8378465e595e18cd08f6e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 09:56:44 -0800 Subject: iwlagn: fix needed chains calculation Garen noticed that this was wrong. Fix the calibration -- default to multiple chains and fall back to single where possible. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 02288779a71f..1fab1bb5f2b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -458,11 +458,13 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; maxstreams += 1; + need_multiple = true; + if ((ht_cap->mcs.rx_mask[1] == 0) && (ht_cap->mcs.rx_mask[2] == 0)) need_multiple = false; if (maxstreams <= 1) - need_multiple = true; + need_multiple = false; } else { /* * If at all, this can only happen through a race -- cgit v1.2.3-59-g8ed1b From 52d980c01353202332ff4322f3f41db0c49816a5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 09:56:45 -0800 Subject: iwlagn: fix RXON issues The RXON rework resulted in a massive loss of throughput because we weren't programming the device completely correctly -- the BSSID has to be programmed into the device before the AP station is uploaded. To fix this, simply always send the unassoc RXON, i.e. even when it was already unassoc so that the BSSID and some other parameters are updated properly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 50 ++++++++++++----------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 1fab1bb5f2b4..d594a1658a9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -96,7 +96,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active = (void *)&ctx->active; - bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; @@ -172,37 +171,30 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ctx->staging.bssid_addr); /* - * If we are currently associated and the new config is also - * going to be associated, OR if the new config is simply not - * associated, clear associated. + * Always clear associated first, but with the correct config. + * This is required as for example station addition for the + * AP station must be done after the BSSID is set to correctly + * set up filters in the device. */ - if ((old_assoc && new_assoc) || !new_assoc) { - struct iwl_rxon_cmd *send = active; - - if (!new_assoc) - send = &ctx->staging; - - if (ctx->ctxid == IWL_RXON_CTX_BSS) - ret = iwlagn_disable_bss(priv, ctx, send); - else - ret = iwlagn_disable_pan(priv, ctx, send); - if (ret) - return ret; + if (ctx->ctxid == IWL_RXON_CTX_BSS) + ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); + else + ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); + if (ret) + return ret; - if (send != active) - memcpy(active, send, sizeof(*active)); + memcpy(active, &ctx->staging, sizeof(*active)); - /* - * Un-assoc RXON clears the station table and WEP - * keys, so we have to restore those afterwards. - */ - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } + /* + * Un-assoc RXON clears the station table and WEP + * keys, so we have to restore those afterwards. + */ + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; } /* RXON timing must be before associated RXON */ -- cgit v1.2.3-59-g8ed1b From 8da8e62851680772f0422d0f1c4b467190b268e5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 09:56:46 -0800 Subject: iwlagn: re-enable calibration During the RXON rewrite, this code got lost. When we've just associated, we need to enable all calibrations and see if some were already finished. Add back the missing code. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index d594a1658a9e..d9d617fd5078 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -569,6 +569,20 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) iwlagn_commit_rxon(priv, ctx); + if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) { + /* + * The chain noise calibration will enable PM upon + * completion. If calibration has already been run + * then we need to enable power management here. + */ + if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) + iwl_power_update_mode(priv, false); + + /* Enable RX differential gain and sensitivity calibrations */ + iwl_chain_noise_reset(priv); + priv->start_calib = 1; + } + if (changes & BSS_CHANGED_IBSS) { ret = iwlagn_manage_ibss_station(priv, vif, bss_conf->ibss_joined); -- cgit v1.2.3-59-g8ed1b From b2769b84d86a2d29fa131a763d2b23b112834420 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 09:56:47 -0800 Subject: iwlagn: fix RXON HT When the HT information is changed due to BSS changes (like legacy stations joining) we need to recalculate HT RXON parameters. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index d9d617fd5078..2d927a94074d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -538,6 +538,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); iwlagn_check_needed_chains(priv, ctx, bss_conf); + iwl_set_rxon_ht(priv, &priv->current_ht_config); } if (priv->cfg->ops->hcmd->set_rxon_chain) -- cgit v1.2.3-59-g8ed1b From 3031242b31dcd76e1c6b1c1718cfee872f55d5af Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Wed, 10 Nov 2010 09:56:48 -0800 Subject: iwlwifi: seperate disconnected antenna function Disconnected antenna algorithm is seperated into its own function from chain noise calibration routine for better code management. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 231 ++++++++++++++------------- 1 file changed, 123 insertions(+), 108 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index e2019e756936..b4cfc3c16285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -732,8 +732,128 @@ static inline u8 find_first_chain(u8 mask) return CHAIN_C; } +/** + * Run disconnected antenna algorithm to find out which antennas are + * disconnected. + */ +static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, + struct iwl_chain_noise_data *data) +{ + u32 active_chains = 0; + u32 max_average_sig; + u16 max_average_sig_antenna_i; + u8 num_tx_chains; + u8 first_chain; + u16 i = 0; + + average_sig[0] = data->chain_signal_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[1] = data->chain_signal_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[2] = data->chain_signal_c / + priv->cfg->base_params->chain_noise_num_beacons; + + if (average_sig[0] >= average_sig[1]) { + max_average_sig = average_sig[0]; + max_average_sig_antenna_i = 0; + active_chains = (1 << max_average_sig_antenna_i); + } else { + max_average_sig = average_sig[1]; + max_average_sig_antenna_i = 1; + active_chains = (1 << max_average_sig_antenna_i); + } + + if (average_sig[2] >= max_average_sig) { + max_average_sig = average_sig[2]; + max_average_sig_antenna_i = 2; + active_chains = (1 << max_average_sig_antenna_i); + } + + IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n", + average_sig[0], average_sig[1], average_sig[2]); + IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n", + max_average_sig, max_average_sig_antenna_i); + + /* Compare signal strengths for all 3 receivers. */ + for (i = 0; i < NUM_RX_CHAINS; i++) { + if (i != max_average_sig_antenna_i) { + s32 rssi_delta = (max_average_sig - average_sig[i]); + + /* If signal is very weak, compared with + * strongest, mark it as disconnected. */ + if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS) + data->disconn_array[i] = 1; + else + active_chains |= (1 << i); + IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d " + "disconn_array[i] = %d\n", + i, rssi_delta, data->disconn_array[i]); + } + } + + /* + * The above algorithm sometimes fails when the ucode + * reports 0 for all chains. It's not clear why that + * happens to start with, but it is then causing trouble + * because this can make us enable more chains than the + * hardware really has. + * + * To be safe, simply mask out any chains that we know + * are not on the device. + */ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + active_chains &= first_antenna(priv->hw_params.valid_rx_ant); + } else + active_chains &= priv->hw_params.valid_rx_ant; + + num_tx_chains = 0; + for (i = 0; i < NUM_RX_CHAINS; i++) { + /* loops on all the bits of + * priv->hw_setting.valid_tx_ant */ + u8 ant_msk = (1 << i); + if (!(priv->hw_params.valid_tx_ant & ant_msk)) + continue; + + num_tx_chains++; + if (data->disconn_array[i] == 0) + /* there is a Tx antenna connected */ + break; + if (num_tx_chains == priv->hw_params.tx_chains_num && + data->disconn_array[i]) { + /* + * If all chains are disconnected + * connect the first valid tx chain + */ + first_chain = + find_first_chain(priv->cfg->valid_tx_ant); + data->disconn_array[first_chain] = 0; + active_chains |= BIT(first_chain); + IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \ + W/A - declare %d as connected\n", + first_chain); + break; + } + } + + if (active_chains != priv->hw_params.valid_rx_ant && + active_chains != priv->chain_noise_data.active_chains) + IWL_DEBUG_CALIB(priv, + "Detected that not all antennas are connected! " + "Connected: %#x, valid: %#x.\n", + active_chains, priv->hw_params.valid_rx_ant); + + /* Save for use within RXON, TX, SCAN commands, etc. */ + data->active_chains = active_chains; + IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n", + active_chains); +} + + /* - * Accumulate 20 beacons of signal and noise statistics for each of + * Accumulate 16 beacons of signal and noise statistics for each of * 3 receivers/antennas/rx-chains, then figure out: * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. @@ -750,8 +870,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) u32 chain_sig_c; u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; - u32 max_average_sig; - u16 max_average_sig_antenna_i; u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE; u16 min_average_noise_antenna_i = INITIALIZATION_VALUE; u16 i = 0; @@ -759,11 +877,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) u16 stat_chnum = INITIALIZATION_VALUE; u8 rxon_band24; u8 stat_band24; - u32 active_chains = 0; - u8 num_tx_chains; unsigned long flags; struct statistics_rx_non_phy *rx_info; - u8 first_chain; + /* * MULTI-FIXME: * When we support multiple interfaces on different channels, @@ -869,108 +985,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) return; /* Analyze signal for disconnected antenna */ - average_sig[0] = data->chain_signal_a / - priv->cfg->base_params->chain_noise_num_beacons; - average_sig[1] = data->chain_signal_b / - priv->cfg->base_params->chain_noise_num_beacons; - average_sig[2] = data->chain_signal_c / - priv->cfg->base_params->chain_noise_num_beacons; - - if (average_sig[0] >= average_sig[1]) { - max_average_sig = average_sig[0]; - max_average_sig_antenna_i = 0; - active_chains = (1 << max_average_sig_antenna_i); - } else { - max_average_sig = average_sig[1]; - max_average_sig_antenna_i = 1; - active_chains = (1 << max_average_sig_antenna_i); - } - - if (average_sig[2] >= max_average_sig) { - max_average_sig = average_sig[2]; - max_average_sig_antenna_i = 2; - active_chains = (1 << max_average_sig_antenna_i); - } - - IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n", - average_sig[0], average_sig[1], average_sig[2]); - IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n", - max_average_sig, max_average_sig_antenna_i); - - /* Compare signal strengths for all 3 receivers. */ - for (i = 0; i < NUM_RX_CHAINS; i++) { - if (i != max_average_sig_antenna_i) { - s32 rssi_delta = (max_average_sig - average_sig[i]); - - /* If signal is very weak, compared with - * strongest, mark it as disconnected. */ - if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS) - data->disconn_array[i] = 1; - else - active_chains |= (1 << i); - IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d " - "disconn_array[i] = %d\n", - i, rssi_delta, data->disconn_array[i]); - } - } - - /* - * The above algorithm sometimes fails when the ucode - * reports 0 for all chains. It's not clear why that - * happens to start with, but it is then causing trouble - * because this can make us enable more chains than the - * hardware really has. - * - * To be safe, simply mask out any chains that we know - * are not on the device. - */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ - active_chains &= first_antenna(priv->hw_params.valid_rx_ant); - } else - active_chains &= priv->hw_params.valid_rx_ant; - - num_tx_chains = 0; - for (i = 0; i < NUM_RX_CHAINS; i++) { - /* loops on all the bits of - * priv->hw_setting.valid_tx_ant */ - u8 ant_msk = (1 << i); - if (!(priv->hw_params.valid_tx_ant & ant_msk)) - continue; - - num_tx_chains++; - if (data->disconn_array[i] == 0) - /* there is a Tx antenna connected */ - break; - if (num_tx_chains == priv->hw_params.tx_chains_num && - data->disconn_array[i]) { - /* - * If all chains are disconnected - * connect the first valid tx chain - */ - first_chain = - find_first_chain(priv->cfg->valid_tx_ant); - data->disconn_array[first_chain] = 0; - active_chains |= BIT(first_chain); - IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - declare %d as connected\n", - first_chain); - break; - } - } - - if (active_chains != priv->hw_params.valid_rx_ant && - active_chains != priv->chain_noise_data.active_chains) - IWL_DEBUG_CALIB(priv, - "Detected that not all antennas are connected! " - "Connected: %#x, valid: %#x.\n", - active_chains, priv->hw_params.valid_rx_ant); - - /* Save for use within RXON, TX, SCAN commands, etc. */ - priv->chain_noise_data.active_chains = active_chains; - IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n", - active_chains); + iwl_find_disconn_antenna(priv, average_sig, data); /* Analyze noise for rx balance */ average_noise[0] = data->chain_noise_a / -- cgit v1.2.3-59-g8ed1b From 6fe8efb2211fe61caa7b0e1c36c521670b8a10a9 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Wed, 10 Nov 2010 09:56:49 -0800 Subject: iwlwifi: disable disconnected antenna for advanced bt coex Disconnected antenna algorithm is used to find out which antennas are disconnected. It should be disabled for devices that support advanced bluetooth coexist. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index b4cfc3c16285..d16bb5ede014 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -801,13 +801,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * To be safe, simply mask out any chains that we know * are not on the device. */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ - active_chains &= first_antenna(priv->hw_params.valid_rx_ant); - } else - active_chains &= priv->hw_params.valid_rx_ant; + active_chains &= priv->hw_params.valid_rx_ant; num_tx_chains = 0; for (i = 0; i < NUM_RX_CHAINS; i++) { @@ -985,7 +979,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) return; /* Analyze signal for disconnected antenna */ - iwl_find_disconn_antenna(priv, average_sig, data); + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + /* Disable disconnected antenna algorithm for advanced + bt coex, assuming valid antennas are connected */ + data->active_chains = priv->hw_params.valid_rx_ant; + for (i = 0; i < NUM_RX_CHAINS; i++) + if (!(data->active_chains & (1<disconn_array[i] = 1; + } else + iwl_find_disconn_antenna(priv, average_sig, data); /* Analyze noise for rx balance */ average_noise[0] = data->chain_noise_a / -- cgit v1.2.3-59-g8ed1b From f81c1f48384d398dbe8f6c5b10377c7158086791 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 09:56:50 -0800 Subject: iwlagn: enable shadow register For 6000 series devices and up, enable automatic update MAC's register for better power usage in PSP mode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 3 ++ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-csr.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-rx.c | 45 +++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-tx.c | 51 ++++++++++++++++++------------ 6 files changed, 70 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 21ac2817722e..c7ff1bdf42cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -487,6 +487,7 @@ static struct iwl_base_params iwl6000_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .shadow_reg_enable = true, }; static struct iwl_base_params iwl6050_base_params = { @@ -510,6 +511,7 @@ static struct iwl_base_params iwl6050_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .shadow_reg_enable = true, }; static struct iwl_base_params iwl6000_coex_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, @@ -532,6 +534,7 @@ static struct iwl_base_params iwl6000_coex_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .shadow_reg_enable = true, }; static struct iwl_ht_params iwl6000_ht_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 019d4e7d7348..ca3530c4295a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -753,6 +753,12 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) } else iwlagn_txq_ctx_reset(priv); + if (priv->cfg->base_params->shadow_reg_enable) { + /* enable shadow regs in HW */ + iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL, + 0x800FFFFF); + } + set_bit(STATUS_INIT, &priv->status); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6064bc412e07..ee8cf240d65d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -290,6 +290,7 @@ struct iwl_mod_params { * sensitivity calibration operation * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation + * @shadow_reg_enable: HW shadhow register bit */ struct iwl_base_params { int eeprom_size; @@ -320,6 +321,7 @@ struct iwl_base_params { const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; + const bool shadow_reg_enable; }; /* * @advanced_bt_coexist: support advanced bt coexist diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 2aa15ab13892..b80bf7dff55b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -132,6 +132,8 @@ #define CSR_LED_REG (CSR_BASE+0x094) #define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) +#define CSR_MAC_SHADOW_REG_CTRL (CSR_BASE+0x0A8) /* 6000 and up */ + /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index baca4cc0073b..87a6fd84d4d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -134,28 +134,37 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q if (q->need_update == 0) goto exit_unlock; - /* If power-saving is in use, make sure device is awake */ - if (test_bit(STATUS_POWER_PMI, &priv->status)) { - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); - - if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { - IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n", - reg); - iwl_set_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - goto exit_unlock; - } - - q->write_actual = (q->write & ~0x7); - iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual); - - /* Else device is assumed to be awake */ - } else { + if (priv->cfg->base_params->shadow_reg_enable) { + /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual); - } + } else { + /* If power-saving is in use, make sure device is awake */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + + if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { + IWL_DEBUG_INFO(priv, + "Rx queue requesting wakeup," + " GP1 = 0x%x\n", reg); + iwl_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + goto exit_unlock; + } + q->write_actual = (q->write & ~0x7); + iwl_write_direct32(priv, rx_wrt_ptr_reg, + q->write_actual); + + /* Else device is assumed to be awake */ + } else { + /* Device expects a multiple of 8 */ + q->write_actual = (q->write & ~0x7); + iwl_write_direct32(priv, rx_wrt_ptr_reg, + q->write_actual); + } + } q->need_update = 0; exit_unlock: diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 7261ee49f282..feaa3670c6bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -49,30 +49,39 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) if (txq->need_update == 0) return; - /* if we're trying to save power */ - if (test_bit(STATUS_POWER_PMI, &priv->status)) { - /* wake up nic if it's powered down ... - * uCode will wake up, and interrupt us again, so next - * time we'll skip this part. */ - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); - - if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { - IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", - txq_id, reg); - iwl_set_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - return; - } - - iwl_write_direct32(priv, HBUS_TARG_WRPTR, - txq->q.write_ptr | (txq_id << 8)); - - /* else not in power-save mode, uCode will never sleep when we're - * trying to tx (during RFKILL, we're not trying to tx). */ - } else + if (priv->cfg->base_params->shadow_reg_enable) { + /* shadow register enabled */ iwl_write32(priv, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); + } else { + /* if we're trying to save power */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + /* wake up nic if it's powered down ... + * uCode will wake up, and interrupt us again, so next + * time we'll skip this part. */ + reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + + if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { + IWL_DEBUG_INFO(priv, + "Tx queue %d requesting wakeup," + " GP1 = 0x%x\n", txq_id, reg); + iwl_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + return; + } + + iwl_write_direct32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + /* + * else not in power-save mode, + * uCode will never sleep when we're + * trying to tx (during RFKILL, we're not trying to tx). + */ + } else + iwl_write32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + } txq->need_update = 0; } EXPORT_SYMBOL(iwl_txq_update_write_ptr); -- cgit v1.2.3-59-g8ed1b From cb7bbc7a5535ab2333915b83391e1d846a0914df Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 4 Nov 2010 00:13:47 +0200 Subject: wl1251: add power callback to wl1251_if_operations Call interface specific power callback before calling board specific one. Also allow that callback to fail. This is how it's done for wl1271 and will be used for runtime_pm support. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/main.c | 15 +++++++++------ drivers/net/wireless/wl1251/sdio.c | 8 ++++++-- drivers/net/wireless/wl1251/spi.c | 9 +++++++++ drivers/net/wireless/wl1251/wl1251.h | 1 + 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 7a8762553cdc..012e1a4016fe 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -52,14 +52,14 @@ void wl1251_disable_interrupts(struct wl1251 *wl) wl->if_ops->disable_irq(wl); } -static void wl1251_power_off(struct wl1251 *wl) +static int wl1251_power_off(struct wl1251 *wl) { - wl->set_power(false); + return wl->if_ops->power(wl, false); } -static void wl1251_power_on(struct wl1251 *wl) +static int wl1251_power_on(struct wl1251 *wl) { - wl->set_power(true); + return wl->if_ops->power(wl, true); } static int wl1251_fetch_firmware(struct wl1251 *wl) @@ -152,9 +152,12 @@ static void wl1251_fw_wakeup(struct wl1251 *wl) static int wl1251_chip_wakeup(struct wl1251 *wl) { - int ret = 0; + int ret; + + ret = wl1251_power_on(wl); + if (ret < 0) + return ret; - wl1251_power_on(wl); msleep(WL1251_POWER_ON_SLEEP); wl->if_ops->reset(wl); diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 74ba9ced5393..02851901677e 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -171,8 +171,12 @@ static void wl1251_disable_line_irq(struct wl1251 *wl) return disable_irq(wl->irq); } -static void wl1251_sdio_set_power(bool enable) +static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) { + if (wl->set_power) + wl->set_power(enable); + + return 0; } static struct wl1251_if_operations wl1251_sdio_ops = { @@ -181,6 +185,7 @@ static struct wl1251_if_operations wl1251_sdio_ops = { .write_elp = wl1251_sdio_write_elp, .read_elp = wl1251_sdio_read_elp, .reset = wl1251_sdio_reset, + .power = wl1251_sdio_set_power, }; static int wl1251_platform_probe(struct platform_device *pdev) @@ -239,7 +244,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl_sdio->func = func; wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; - wl->set_power = wl1251_sdio_set_power; if (wl12xx_board_data != NULL) { wl->set_power = wl12xx_board_data->set_power; diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c index 88fa8e69d0d1..ac872b38960f 100644 --- a/drivers/net/wireless/wl1251/spi.c +++ b/drivers/net/wireless/wl1251/spi.c @@ -215,12 +215,21 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl) return disable_irq(wl->irq); } +static int wl1251_spi_set_power(struct wl1251 *wl, bool enable) +{ + if (wl->set_power) + wl->set_power(enable); + + return 0; +} + static const struct wl1251_if_operations wl1251_spi_ops = { .read = wl1251_spi_read, .write = wl1251_spi_write, .reset = wl1251_spi_reset_wake, .enable_irq = wl1251_spi_enable_irq, .disable_irq = wl1251_spi_disable_irq, + .power = wl1251_spi_set_power, }; static int __devinit wl1251_spi_probe(struct spi_device *spi) diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index e113d4c1fb35..13fbeeccf609 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -256,6 +256,7 @@ struct wl1251_if_operations { void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); void (*read_elp)(struct wl1251 *wl, int addr, u32 *val); void (*write_elp)(struct wl1251 *wl, int addr, u32 val); + int (*power)(struct wl1251 *wl, bool enable); void (*reset)(struct wl1251 *wl); void (*enable_irq)(struct wl1251 *wl); void (*disable_irq)(struct wl1251 *wl); -- cgit v1.2.3-59-g8ed1b From 1d4b89f2970f9ea0902d0a3bc1090f3c770b5080 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Mon, 8 Nov 2010 15:29:36 +0200 Subject: wl1251: add runtime PM support for SDIO Add runtime PM support, similar to how it's done for wl1271. This allows to power down the card when the driver is loaded but network is not in use. Cc: Ohad Ben-Cohen Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/sdio.c | 64 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 02851901677e..f3e185efe124 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wl1251.h" @@ -173,10 +174,40 @@ static void wl1251_disable_line_irq(struct wl1251 *wl) static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) { - if (wl->set_power) - wl->set_power(enable); + struct sdio_func *func = wl_to_func(wl); + int ret; - return 0; + if (enable) { + /* + * Power is controlled by runtime PM, but we still call board + * callback in case it wants to do any additional setup, + * for example enabling clock buffer for the module. + */ + if (wl->set_power) + wl->set_power(true); + + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + } else { + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + ret = pm_runtime_put_sync(&func->dev); + if (ret < 0) + goto out; + + if (wl->set_power) + wl->set_power(false); + } + +out: + return ret; } static struct wl1251_if_operations wl1251_sdio_ops = { @@ -277,6 +308,10 @@ static int wl1251_sdio_probe(struct sdio_func *func, goto out_free_irq; sdio_set_drvdata(func, wl); + + /* Tell PM core that we don't need the card to be powered now */ + pm_runtime_put_noidle(&func->dev); + return ret; out_free_irq: @@ -298,6 +333,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) struct wl1251 *wl = sdio_get_drvdata(func); struct wl1251_sdio *wl_sdio = wl->if_priv; + /* Undo decrement done above in wl1251_probe */ + pm_runtime_get_noresume(&func->dev); + if (wl->irq) free_irq(wl->irq, wl); kfree(wl_sdio); @@ -309,11 +347,31 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) sdio_release_host(func); } +static int wl1251_suspend(struct device *dev) +{ + /* + * Tell MMC/SDIO core it's OK to power down the card + * (if it isn't already), but not to remove it completely. + */ + return 0; +} + +static int wl1251_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wl1251_sdio_pm_ops = { + .suspend = wl1251_suspend, + .resume = wl1251_resume, +}; + static struct sdio_driver wl1251_sdio_driver = { .name = "wl1251_sdio", .id_table = wl1251_devices, .probe = wl1251_sdio_probe, .remove = __devexit_p(wl1251_sdio_remove), + .drv.pm = &wl1251_sdio_pm_ops, }; static int __init wl1251_sdio_init(void) -- cgit v1.2.3-59-g8ed1b From e4b3fdb80021bc0a3239bfc2a873a6d7c6ac52a1 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 4 Nov 2010 00:13:49 +0200 Subject: wl1251: use wl12xx_platform_data to pass data Make use the newly added method to pass platform data for wl1251 too. This allows to eliminate some redundant code. Cc: Ohad Ben-Cohen Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Acked-by: Luciano Coelho Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- arch/arm/mach-omap2/board-omap3pandora.c | 32 ++++++++--------------------- drivers/net/wireless/wl1251/sdio.c | 35 ++------------------------------ drivers/net/wireless/wl12xx/Kconfig | 2 +- 3 files changed, 12 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 89ed1be2d62e..8be261506056 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -642,31 +642,13 @@ static void __init omap3pandora_init_irq(void) omap_gpio_init(); } -static void pandora_wl1251_set_power(bool enable) -{ - /* - * Keep power always on until wl1251_sdio driver learns to re-init - * the chip after powering it down and back up. - */ -} - -static struct wl12xx_platform_data pandora_wl1251_pdata = { - .set_power = pandora_wl1251_set_power, - .use_eeprom = true, -}; - -static struct platform_device pandora_wl1251_data = { - .name = "wl1251_data", - .id = -1, - .dev = { - .platform_data = &pandora_wl1251_pdata, - }, -}; - -static void pandora_wl1251_init(void) +static void __init pandora_wl1251_init(void) { + struct wl12xx_platform_data pandora_wl1251_pdata; int ret; + memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); + ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq"); if (ret < 0) goto fail; @@ -679,6 +661,11 @@ static void pandora_wl1251_init(void) if (pandora_wl1251_pdata.irq < 0) goto fail_irq; + pandora_wl1251_pdata.use_eeprom = true; + ret = wl12xx_set_platform_data(&pandora_wl1251_pdata); + if (ret < 0) + goto fail_irq; + return; fail_irq: @@ -691,7 +678,6 @@ static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_leds_gpio, &pandora_keys_gpio, &pandora_dss_device, - &pandora_wl1251_data, &pandora_vwlan_device, }; diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index f3e185efe124..596d90ecba33 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -43,8 +43,6 @@ struct wl1251_sdio { u32 elp_val; }; -static struct wl12xx_platform_data *wl12xx_board_data; - static struct sdio_func *wl_to_func(struct wl1251 *wl) { struct wl1251_sdio *wl_sdio = wl->if_priv; @@ -219,30 +217,6 @@ static struct wl1251_if_operations wl1251_sdio_ops = { .power = wl1251_sdio_set_power, }; -static int wl1251_platform_probe(struct platform_device *pdev) -{ - if (pdev->id != -1) { - wl1251_error("can only handle single device"); - return -ENODEV; - } - - wl12xx_board_data = pdev->dev.platform_data; - return 0; -} - -/* - * Dummy platform_driver for passing platform_data to this driver, - * until we have a way to pass this through SDIO subsystem or - * some other way. - */ -static struct platform_driver wl1251_platform_driver = { - .driver = { - .name = "wl1251_data", - .owner = THIS_MODULE, - }, - .probe = wl1251_platform_probe, -}; - static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { @@ -250,6 +224,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, struct wl1251 *wl; struct ieee80211_hw *hw; struct wl1251_sdio *wl_sdio; + const struct wl12xx_platform_data *wl12xx_board_data; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) @@ -276,6 +251,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; + wl12xx_board_data = wl12xx_get_platform_data(); if (wl12xx_board_data != NULL) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; @@ -378,12 +354,6 @@ static int __init wl1251_sdio_init(void) { int err; - err = platform_driver_register(&wl1251_platform_driver); - if (err) { - wl1251_error("failed to register platform driver: %d", err); - return err; - } - err = sdio_register_driver(&wl1251_sdio_driver); if (err) wl1251_error("failed to register sdio driver: %d", err); @@ -393,7 +363,6 @@ static int __init wl1251_sdio_init(void) static void __exit wl1251_sdio_exit(void) { sdio_unregister_driver(&wl1251_sdio_driver); - platform_driver_unregister(&wl1251_platform_driver); wl1251_notice("unloaded"); } diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 1b3b7bdd6a19..02ad4bc15976 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -52,5 +52,5 @@ config WL1271_SDIO config WL12XX_PLATFORM_DATA bool - depends on WL1271_SDIO != n + depends on WL1271_SDIO != n || WL1251_SDIO != n default y -- cgit v1.2.3-59-g8ed1b From 7919a57bc608140aa8614c19eac40c6916fb61d2 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 30 Aug 2010 19:04:01 +0000 Subject: bitops: Provide generic sign_extend32 function This patch moves code out from wireless drivers where two different functions are defined in three code locations for the same purpose and provides a common function to sign extend a 32-bit value. Signed-off-by: Andreas Herrmann Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 8 +------- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/ar9002_phy.c | 8 ++++---- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/hw.h | 6 ------ drivers/net/wireless/iwlwifi/iwl-4965.c | 20 ++------------------ include/linux/bitops.h | 11 +++++++++++ 7 files changed, 30 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 219367884e64..6b43f535ff53 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1102,18 +1102,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) PHY calibration \*****************/ -static int sign_extend(int val, const int nbits) -{ - int order = BIT(nbits-1); - return (val ^ order) - order; -} - static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) { s32 val; val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); - return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9); + return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8); } void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 777a602176f2..c83a22cfbe1e 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1490,25 +1490,25 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah, int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); - nfarray[0] = sign_extend(nf, 9); + nfarray[0] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); - nfarray[1] = sign_extend(nf, 9); + nfarray[1] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); - nfarray[2] = sign_extend(nf, 9); + nfarray[2] = sign_extend32(nf, 8); if (!IS_CHAN_HT40(ah->curchan)) return; nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - nfarray[3] = sign_extend(nf, 9); + nfarray[3] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); - nfarray[4] = sign_extend(nf, 9); + nfarray[4] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); - nfarray[5] = sign_extend(nf, 9); + nfarray[5] = sign_extend32(nf, 8); } /* diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index c00cdc67b55b..3fb97fdc1240 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -473,21 +473,21 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); - nfarray[0] = sign_extend(nf, 9); + nfarray[0] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); if (IS_CHAN_HT40(ah->curchan)) - nfarray[3] = sign_extend(nf, 9); + nfarray[3] = sign_extend32(nf, 8); if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) return; nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); - nfarray[1] = sign_extend(nf, 9); + nfarray[1] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); if (IS_CHAN_HT40(ah->curchan)) - nfarray[4] = sign_extend(nf, 9); + nfarray[4] = sign_extend32(nf, 8); } static void ar9002_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 06a9c4cd2f44..44c5454b2ad8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1023,25 +1023,25 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah, int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); - nfarray[0] = sign_extend(nf, 9); + nfarray[0] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); - nfarray[1] = sign_extend(nf, 9); + nfarray[1] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); - nfarray[2] = sign_extend(nf, 9); + nfarray[2] = sign_extend32(nf, 8); if (!IS_CHAN_HT40(ah->curchan)) return; nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - nfarray[3] = sign_extend(nf, 9); + nfarray[3] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); - nfarray[4] = sign_extend(nf, 9); + nfarray[4] = sign_extend32(nf, 8); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); - nfarray[5] = sign_extend(nf, 9); + nfarray[5] = sign_extend32(nf, 8); } static void ar9003_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e5b72262fd96..f821a28bcda3 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -825,12 +825,6 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah) return &ah->ops; } -static inline int sign_extend(int val, const int nbits) -{ - int order = BIT(nbits-1); - return (val ^ order) - order; -} - /* Initialization, Detach, Reset */ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index cd14843878ae..4748d067eb1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1686,22 +1686,6 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; } -/** - * sign_extend - Sign extend a value using specified bit as sign-bit - * - * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1 - * and bit0..2 is 001b which when sign extended to 1111111111111001b is -7. - * - * @param oper value to sign extend - * @param index 0 based bit index (0<=index<32) to sign bit - */ -static s32 sign_extend(u32 oper, int index) -{ - u8 shift = 31 - index; - - return (s32)(oper << shift) >> shift; -} - /** * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) * @statistics: Provides the temperature reading from the uCode @@ -1739,9 +1723,9 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) * "initialize" ALIVE response. */ if (!test_bit(STATUS_TEMPERATURE, &priv->status)) - vt = sign_extend(R4, 23); + vt = sign_extend32(R4, 23); else - vt = sign_extend(le32_to_cpu(priv->_agn.statistics. + vt = sign_extend32(le32_to_cpu(priv->_agn.statistics. general.common.temperature), 23); IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 827cc95711ef..2184c6b97aeb 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -109,6 +109,17 @@ static inline __u8 ror8(__u8 word, unsigned int shift) return (word >> shift) | (word << (8 - shift)); } +/** + * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit + * @value: value to sign extend + * @index: 0 based bit index (0<=index<32) to sign bit + */ +static inline __s32 sign_extend32(__u32 value, int index) +{ + __u8 shift = 31 - index; + return (__s32)(value << shift) >> shift; +} + static inline unsigned fls_long(unsigned long l) { if (sizeof(l) == 4) -- cgit v1.2.3-59-g8ed1b From b1d771ee33c6e4006676002b9d74abf45b71d3d6 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 29 Oct 2010 23:11:23 +0200 Subject: carl9170: use generic sign_extend32 This patch replaces the handcrafted sign extension cruft with a generic bitop function. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 89deca37a988..82bc81c4c930 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1554,15 +1554,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, return carl9170_regwrite_result(); } -/* TODO: replace this with sign_extend32(noise, 8) */ -static int carl9170_calc_noise_dbm(u32 raw_noise) -{ - if (raw_noise & 0x100) - return ~0x1ff | raw_noise; - else - return raw_noise; -} - int carl9170_get_noisefloor(struct ar9170 *ar) { static const u32 phy_regs[] = { @@ -1578,11 +1569,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar) return err; for (i = 0; i < 2; i++) { - ar->noise[i] = carl9170_calc_noise_dbm( - (phy_res[i] >> 19) & 0x1ff); + ar->noise[i] = sign_extend32(GET_VAL( + AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8); - ar->noise[i + 2] = carl9170_calc_noise_dbm( - (phy_res[i + 2] >> 23) & 0x1ff); + ar->noise[i + 2] = sign_extend32(GET_VAL( + AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8); } return 0; -- cgit v1.2.3-59-g8ed1b From e1f2d8c2cc61d2b9472efe44e8a2b098336914b4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Nov 2010 10:37:30 -0800 Subject: vlan: Fix build warning in vlandev_seq_show() net/8021q/vlanproc.c: In function 'vlandev_seq_show': net/8021q/vlanproc.c:283:20: warning: unused variable 'fmt' Signed-off-by: David S. Miller --- net/8021q/vlanproc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 8a64db19b8a5..d1314cf18adf 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -280,7 +280,6 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; - static const char fmt[] = "%30s %12lu\n"; static const char fmt64[] = "%30s %12llu\n"; int i; -- cgit v1.2.3-59-g8ed1b From cc9ff19da9bf76a2f70bcb80225a1c587c162e52 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 3 Nov 2010 04:41:38 +0000 Subject: xfrm: use gre key as flow upper protocol info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GRE Key field is intended to be used for identifying an individual traffic flow within a tunnel. It is useful to be able to have XFRM policy selector matches to have different policies for different GRE tunnels. Signed-off-by: Timo Teräs Signed-off-by: David S. Miller --- include/net/flow.h | 2 ++ include/net/xfrm.h | 6 ++++++ net/ipv4/ip_gre.c | 12 +++++++----- net/ipv4/xfrm4_policy.c | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index 0ac3fb5e0973..7196e6864b8d 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -67,6 +67,7 @@ struct flowi { } dnports; __be32 spi; + __be32 gre_key; struct { __u8 type; @@ -78,6 +79,7 @@ struct flowi { #define fl_icmp_code uli_u.icmpt.code #define fl_ipsec_spi uli_u.spi #define fl_mh_type uli_u.mht.type +#define fl_gre_key uli_u.gre_key __u32 secid; /* used by xfrm; see secid.txt */ } __attribute__((__aligned__(BITS_PER_LONG/8))); diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bcfb6b24b019..54b283229488 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -805,6 +805,9 @@ __be16 xfrm_flowi_sport(struct flowi *fl) case IPPROTO_MH: port = htons(fl->fl_mh_type); break; + case IPPROTO_GRE: + port = htonl(fl->fl_gre_key) >> 16; + break; default: port = 0; /*XXX*/ } @@ -826,6 +829,9 @@ __be16 xfrm_flowi_dport(struct flowi *fl) case IPPROTO_ICMPV6: port = htons(fl->fl_icmp_code); break; + case IPPROTO_GRE: + port = htonl(fl->fl_gre_key) & 0xffff; + break; default: port = 0; /*XXX*/ } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index cab2057d5430..aace653710f6 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -779,9 +779,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev .tos = RT_TOS(tos) } }, - .proto = IPPROTO_GRE - } -; + .proto = IPPROTO_GRE, + .fl_gre_key = tunnel->parms.o_key + }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { dev->stats.tx_carrier_errors++; goto tx_error; @@ -958,7 +958,8 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_GRE + .proto = IPPROTO_GRE, + .fl_gre_key = tunnel->parms.o_key }; struct rtable *rt; @@ -1223,7 +1224,8 @@ static int ipgre_open(struct net_device *dev) .tos = RT_TOS(t->parms.iph.tos) } }, - .proto = IPPROTO_GRE + .proto = IPPROTO_GRE, + .fl_gre_key = t->parms.o_key }; struct rtable *rt; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index dd1fd8c473fc..4a8c5335770c 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -154,6 +155,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; + + case IPPROTO_GRE: + if (pskb_may_pull(skb, xprth + 12 - skb->data)) { + __be16 *greflags = (__be16 *)xprth; + __be32 *gre_hdr = (__be32 *)xprth; + + if (greflags[0] & GRE_KEY) { + if (greflags[0] & GRE_CSUM) + gre_hdr++; + fl->fl_gre_key = gre_hdr[1]; + } + } + break; + default: fl->fl_ipsec_spi = 0; break; -- cgit v1.2.3-59-g8ed1b From ed9af2e839c06c18f721da2c768fbb444c4a10e5 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 9 Nov 2010 10:47:30 +0000 Subject: net: Move TX queue allocation to alloc_netdev_mq TX queues are now allocated in alloc_netdev_mq and freed in free_netdev. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- net/core/dev.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 8b500c3e0297..75490670e0a9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5136,10 +5136,6 @@ int register_netdevice(struct net_device *dev) if (ret) goto out; - ret = netif_alloc_netdev_queues(dev); - if (ret) - goto out; - netdev_init_queues(dev); /* Init, if this function is available */ @@ -5599,6 +5595,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count; + if (netif_alloc_netdev_queues(dev)) + goto free_pcpu; #ifdef CONFIG_RPS dev->num_rx_queues = queue_count; @@ -5619,6 +5617,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, free_pcpu: free_percpu(dev->pcpu_refcnt); + kfree(dev->_tx); free_p: kfree(p); return NULL; -- cgit v1.2.3-59-g8ed1b From fe8222406c8277a21172479d3a8283d31c209028 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 9 Nov 2010 10:47:38 +0000 Subject: net: Simplify RX queue allocation This patch move RX queue allocation to alloc_netdev_mq and freeing of the queues to free_netdev (symmetric to TX queue allocation). Each kobject RX queue takes a reference to the queue's device so that the device can't be freed before all the kobjects have been released-- this obviates the need for reference counts specific to RX queues. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/netdevice.h | 3 +-- net/core/dev.c | 19 ++++++++++--------- net/core/net-sysfs.c | 7 ++----- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 6e4cfbc53d4c..fccb11f879e5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -592,8 +592,7 @@ struct netdev_rx_queue { struct rps_map __rcu *rps_map; struct rps_dev_flow_table __rcu *rps_flow_table; struct kobject kobj; - struct netdev_rx_queue *first; - atomic_t count; + struct net_device *dev; } ____cacheline_aligned_in_smp; #endif /* CONFIG_RPS */ diff --git a/net/core/dev.c b/net/core/dev.c index 75490670e0a9..8725d168d1f5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5051,12 +5051,8 @@ static int netif_alloc_rx_queues(struct net_device *dev) } dev->_rx = rx; - /* - * Set a pointer to first element in the array which holds the - * reference count. - */ for (i = 0; i < count; i++) - rx[i].first = rx; + rx[i].dev = dev; #endif return 0; } @@ -5132,10 +5128,6 @@ int register_netdevice(struct net_device *dev) dev->iflink = -1; - ret = netif_alloc_rx_queues(dev); - if (ret) - goto out; - netdev_init_queues(dev); /* Init, if this function is available */ @@ -5601,6 +5593,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, #ifdef CONFIG_RPS dev->num_rx_queues = queue_count; dev->real_num_rx_queues = queue_count; + if (netif_alloc_rx_queues(dev)) + goto free_pcpu; #endif dev->gso_max_size = GSO_MAX_SIZE; @@ -5618,6 +5612,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, free_pcpu: free_percpu(dev->pcpu_refcnt); kfree(dev->_tx); +#ifdef CONFIG_RPS + kfree(dev->_rx); +#endif + free_p: kfree(p); return NULL; @@ -5639,6 +5637,9 @@ void free_netdev(struct net_device *dev) release_net(dev_net(dev)); kfree(dev->_tx); +#ifdef CONFIG_RPS + kfree(dev->_rx); +#endif kfree(rcu_dereference_raw(dev->ingress_queue)); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index a5ff5a89f376..3ba526b56fe3 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -706,7 +706,6 @@ static struct attribute *rx_queue_default_attrs[] = { static void rx_queue_release(struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); - struct netdev_rx_queue *first = queue->first; struct rps_map *map; struct rps_dev_flow_table *flow_table; @@ -719,8 +718,7 @@ static void rx_queue_release(struct kobject *kobj) if (flow_table) call_rcu(&flow_table->rcu, rps_dev_flow_table_release); - if (atomic_dec_and_test(&first->count)) - kfree(first); + dev_put(queue->dev); } static struct kobj_type rx_queue_ktype = { @@ -732,7 +730,6 @@ static struct kobj_type rx_queue_ktype = { static int rx_queue_add_kobject(struct net_device *net, int index) { struct netdev_rx_queue *queue = net->_rx + index; - struct netdev_rx_queue *first = queue->first; struct kobject *kobj = &queue->kobj; int error = 0; @@ -745,7 +742,7 @@ static int rx_queue_add_kobject(struct net_device *net, int index) } kobject_uevent(kobj, KOBJ_ADD); - atomic_inc(&first->count); + dev_hold(queue->dev); return error; } -- cgit v1.2.3-59-g8ed1b From ad65ffd12dccf6d1031298eacc060327751084da Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:26 +0000 Subject: drivers/isdn: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/isdn/hardware/mISDN/mISDNinfineon.c | 4 ++-- drivers/isdn/hardware/mISDN/mISDNisar.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index e90db8870b6c..bc0529ac88a1 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -420,7 +420,7 @@ enable_hwirq(struct inf_hw *hw) break; case INF_NICCY: val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); - val |= NICCY_IRQ_ENABLE;; + val |= NICCY_IRQ_ENABLE; outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); break; case INF_SCT_1: @@ -924,7 +924,7 @@ setup_instance(struct inf_hw *card) mISDNipac_init(&card->ipac, card); if (card->ipac.isac.dch.dev.Bprotocols == 0) - goto error_setup;; + goto error_setup; err = mISDN_register_device(&card->ipac.isac.dch.dev, &card->pdev->dev, card->name); diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index 38eb31439a73..d13fa5b119f5 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -264,7 +264,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size) while (noc) { val = le16_to_cpu(*sp++); *mp++ = val >> 8; - *mp++ = val & 0xFF;; + *mp++ = val & 0xFF; noc--; } spin_lock_irqsave(isar->hwlock, flags); -- cgit v1.2.3-59-g8ed1b From 6f38ad93e4882e84c1cc113736db7dc9252dcf11 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:31 +0000 Subject: drivers/net/bnx2x: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 4 ++-- drivers/net/bnx2x/bnx2x_main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 580919619252..38aeffef2a83 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3904,7 +3904,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; + return 0; msleep(1); } return -EINVAL; @@ -3988,7 +3988,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; + return 0; msleep(1); } diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index e9ad16f00b56..7ffcb086cb6f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8078,7 +8078,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) int port = BP_PORT(bp); u32 val, val2; u32 config; - u32 ext_phy_type, ext_phy_config;; + u32 ext_phy_type, ext_phy_config; bp->link_params.bp = bp; bp->link_params.port = port; -- cgit v1.2.3-59-g8ed1b From 1d51c4185bb369cb39ed8cc20b331508e47b35b2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:32 +0000 Subject: drivers/net/e1000e: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c4ca1629f532..a6d54e460001 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4595,7 +4595,7 @@ dma_error: i += tx_ring->count; i--; buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info);; + e1000_put_txbuf(adapter, buffer_info); } return 0; -- cgit v1.2.3-59-g8ed1b From e81a1ba815666ec02ef5bf0e17cf256c88d233b3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:33 +0000 Subject: drivers/net/ixgbe: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_sriov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 5428153af8f3..93f40bcf683c 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -68,7 +68,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, * addresses */ for (i = 0; i < entries; i++) { - vfinfo->vf_mc_hashes[i] = hash_list[i];; + vfinfo->vf_mc_hashes[i] = hash_list[i]; } for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { -- cgit v1.2.3-59-g8ed1b From 779bb41d4bd111d5631d58d1bf2d00b5c4389c80 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:37 +0000 Subject: drivers/net/cnic.c: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/cnic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 92bac19ad60a..594ca9c2c10a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1695,7 +1695,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], *work = num; return -EINVAL; } - *work = 2 + req2->num_additional_wqes;; + *work = 2 + req2->num_additional_wqes; l5_cid = req1->iscsi_conn_id; if (l5_cid >= MAX_ISCSI_TBL_SZ) -- cgit v1.2.3-59-g8ed1b From c59504ebc5baa628706d10c2d3c7e1f4bc3c2147 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:57 +0000 Subject: include/linux/if_macvlan.h: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/linux/if_macvlan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 8a2fd66a8b5f..ac96a2d76291 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -69,7 +69,7 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, rx_stats = this_cpu_ptr(vlan->rx_stats); if (likely(success)) { u64_stats_update_begin(&rx_stats->syncp); - rx_stats->rx_packets++;; + rx_stats->rx_packets++; rx_stats->rx_bytes += len; if (multicast) rx_stats->rx_multicast++; -- cgit v1.2.3-59-g8ed1b From d577f1ccdd8ae8bfbe6063eb2ba2a350259e9031 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:04:58 +0000 Subject: include/net/caif/cfctrl.h: Remove unnecessary semicolons Signed-off-by: Joe Perches Acked-by: Sjur Braendeland Signed-off-by: David S. Miller --- include/net/caif/cfctrl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h index 9402543fc20d..e54f6396fa4c 100644 --- a/include/net/caif/cfctrl.h +++ b/include/net/caif/cfctrl.h @@ -51,7 +51,7 @@ struct cfctrl_rsp { void (*restart_rsp)(void); void (*radioset_rsp)(void); void (*reject_rsp)(struct cflayer *layer, u8 linkid, - struct cflayer *client_layer);; + struct cflayer *client_layer); }; /* Link Setup Parameters for CAIF-Links. */ -- cgit v1.2.3-59-g8ed1b From 8a22c99a80b0926585cfcbcc423ee2c49c1fd820 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 17:05:00 +0000 Subject: net/ipv6/mcast.c: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv6/mcast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index d1444b95ad7e..9c5074528a71 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -257,7 +257,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, return NULL; idev = __in6_dev_get(dev); if (!idev) - return NULL;; + return NULL; read_lock_bh(&idev->lock); if (idev->dead) { read_unlock_bh(&idev->lock); -- cgit v1.2.3-59-g8ed1b From e80516880019aa1f7c5c410276edfea9575ec89f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 15 Nov 2010 06:38:10 +0000 Subject: bridge: add RCU annotation to bridge multicast table Add modern __rcu annotatations to bridge multicast table. Use newer hlist macros to avoid direct access to hlist internals. Signed-off-by: Eric Dumazet Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_forward.c | 4 +-- net/bridge/br_multicast.c | 78 +++++++++++++++++++++++++++++++---------------- net/bridge/br_private.h | 6 ++-- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index cbfe87f0f34a..2bd11ec6d166 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -223,7 +223,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct net_bridge_port_group *p; struct hlist_node *rp; - rp = rcu_dereference(br->router_list.first); + rp = rcu_dereference(hlist_first_rcu(&br->router_list)); p = mdst ? rcu_dereference(mdst->ports) : NULL; while (p || rp) { struct net_bridge_port *port, *lport, *rport; @@ -242,7 +242,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, if ((unsigned long)lport >= (unsigned long)port) p = rcu_dereference(p->next); if ((unsigned long)rport >= (unsigned long)port) - rp = rcu_dereference(rp->next); + rp = rcu_dereference(hlist_next_rcu(rp)); } if (!prev) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index eb5b256ffc88..326e599f83fb 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -33,6 +33,9 @@ #include "br_private.h" +#define mlock_dereference(X, br) \ + rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static inline int ipv6_is_local_multicast(const struct in6_addr *addr) { @@ -135,7 +138,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get( struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, struct sk_buff *skb) { - struct net_bridge_mdb_htable *mdb = br->mdb; + struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb); struct br_ip ip; if (br->multicast_disabled) @@ -235,7 +238,8 @@ static void br_multicast_group_expired(unsigned long data) if (mp->ports) goto out; - mdb = br->mdb; + mdb = mlock_dereference(br->mdb, br); + hlist_del_rcu(&mp->hlist[mdb->ver]); mdb->size--; @@ -249,16 +253,20 @@ out: static void br_multicast_del_pg(struct net_bridge *br, struct net_bridge_port_group *pg) { - struct net_bridge_mdb_htable *mdb = br->mdb; + struct net_bridge_mdb_htable *mdb; struct net_bridge_mdb_entry *mp; struct net_bridge_port_group *p; - struct net_bridge_port_group **pp; + struct net_bridge_port_group __rcu **pp; + + mdb = mlock_dereference(br->mdb, br); mp = br_mdb_ip_get(mdb, &pg->addr); if (WARN_ON(!mp)) return; - for (pp = &mp->ports; (p = *pp); pp = &p->next) { + for (pp = &mp->ports; + (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { if (p != pg) continue; @@ -294,10 +302,10 @@ out: spin_unlock(&br->multicast_lock); } -static int br_mdb_rehash(struct net_bridge_mdb_htable **mdbp, int max, +static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max, int elasticity) { - struct net_bridge_mdb_htable *old = *mdbp; + struct net_bridge_mdb_htable *old = rcu_dereference_protected(*mdbp, 1); struct net_bridge_mdb_htable *mdb; int err; @@ -569,7 +577,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group, int hash) { - struct net_bridge_mdb_htable *mdb = br->mdb; + struct net_bridge_mdb_htable *mdb; struct net_bridge_mdb_entry *mp; struct hlist_node *p; unsigned count = 0; @@ -577,6 +585,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( int elasticity; int err; + mdb = rcu_dereference_protected(br->mdb, 1); hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { count++; if (unlikely(br_ip_equal(group, &mp->addr))) @@ -642,10 +651,11 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group) { - struct net_bridge_mdb_htable *mdb = br->mdb; + struct net_bridge_mdb_htable *mdb; struct net_bridge_mdb_entry *mp; int hash; + mdb = rcu_dereference_protected(br->mdb, 1); if (!mdb) { if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0)) return NULL; @@ -660,7 +670,7 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( case -EAGAIN: rehash: - mdb = br->mdb; + mdb = rcu_dereference_protected(br->mdb, 1); hash = br_ip_hash(mdb, group); break; @@ -692,7 +702,7 @@ static int br_multicast_add_group(struct net_bridge *br, { struct net_bridge_mdb_entry *mp; struct net_bridge_port_group *p; - struct net_bridge_port_group **pp; + struct net_bridge_port_group __rcu **pp; unsigned long now = jiffies; int err; @@ -712,7 +722,9 @@ static int br_multicast_add_group(struct net_bridge *br, goto out; } - for (pp = &mp->ports; (p = *pp); pp = &p->next) { + for (pp = &mp->ports; + (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { if (p->port == port) goto found; if ((unsigned long)p->port < (unsigned long)port) @@ -1106,7 +1118,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, struct net_bridge_mdb_entry *mp; struct igmpv3_query *ih3; struct net_bridge_port_group *p; - struct net_bridge_port_group **pp; + struct net_bridge_port_group __rcu **pp; unsigned long max_delay; unsigned long now = jiffies; __be32 group; @@ -1145,7 +1157,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, if (!group) goto out; - mp = br_mdb_ip4_get(br->mdb, group); + mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group); if (!mp) goto out; @@ -1157,7 +1169,9 @@ static int br_ip4_multicast_query(struct net_bridge *br, try_to_del_timer_sync(&mp->timer) >= 0)) mod_timer(&mp->timer, now + max_delay); - for (pp = &mp->ports; (p = *pp); pp = &p->next) { + for (pp = &mp->ports; + (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) @@ -1178,7 +1192,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); struct net_bridge_mdb_entry *mp; struct mld2_query *mld2q; - struct net_bridge_port_group *p, **pp; + struct net_bridge_port_group *p; + struct net_bridge_port_group __rcu **pp; unsigned long max_delay; unsigned long now = jiffies; struct in6_addr *group = NULL; @@ -1214,7 +1229,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, if (!group) goto out; - mp = br_mdb_ip6_get(br->mdb, group); + mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group); if (!mp) goto out; @@ -1225,7 +1240,9 @@ static int br_ip6_multicast_query(struct net_bridge *br, try_to_del_timer_sync(&mp->timer) >= 0)) mod_timer(&mp->timer, now + max_delay); - for (pp = &mp->ports; (p = *pp); pp = &p->next) { + for (pp = &mp->ports; + (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) @@ -1254,7 +1271,7 @@ static void br_multicast_leave_group(struct net_bridge *br, timer_pending(&br->multicast_querier_timer)) goto out; - mdb = br->mdb; + mdb = mlock_dereference(br->mdb, br); mp = br_mdb_ip_get(mdb, group); if (!mp) goto out; @@ -1277,7 +1294,9 @@ static void br_multicast_leave_group(struct net_bridge *br, goto out; } - for (p = mp->ports; p; p = p->next) { + for (p = mlock_dereference(mp->ports, br); + p != NULL; + p = mlock_dereference(p->next, br)) { if (p->port != port) continue; @@ -1625,7 +1644,7 @@ void br_multicast_stop(struct net_bridge *br) del_timer_sync(&br->multicast_query_timer); spin_lock_bh(&br->multicast_lock); - mdb = br->mdb; + mdb = mlock_dereference(br->mdb, br); if (!mdb) goto out; @@ -1729,6 +1748,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) { struct net_bridge_port *port; int err = 0; + struct net_bridge_mdb_htable *mdb; spin_lock(&br->multicast_lock); if (br->multicast_disabled == !val) @@ -1741,15 +1761,16 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) if (!netif_running(br->dev)) goto unlock; - if (br->mdb) { - if (br->mdb->old) { + mdb = mlock_dereference(br->mdb, br); + if (mdb) { + if (mdb->old) { err = -EEXIST; rollback: br->multicast_disabled = !!val; goto unlock; } - err = br_mdb_rehash(&br->mdb, br->mdb->max, + err = br_mdb_rehash(&br->mdb, mdb->max, br->hash_elasticity); if (err) goto rollback; @@ -1774,6 +1795,7 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) { int err = -ENOENT; u32 old; + struct net_bridge_mdb_htable *mdb; spin_lock(&br->multicast_lock); if (!netif_running(br->dev)) @@ -1782,7 +1804,9 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) err = -EINVAL; if (!is_power_of_2(val)) goto unlock; - if (br->mdb && val < br->mdb->size) + + mdb = mlock_dereference(br->mdb, br); + if (mdb && val < mdb->size) goto unlock; err = 0; @@ -1790,8 +1814,8 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) old = br->hash_max; br->hash_max = val; - if (br->mdb) { - if (br->mdb->old) { + if (mdb) { + if (mdb->old) { err = -EEXIST; rollback: br->hash_max = old; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 75c90edaf7db..b862071bf601 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -72,7 +72,7 @@ struct net_bridge_fdb_entry struct net_bridge_port_group { struct net_bridge_port *port; - struct net_bridge_port_group *next; + struct net_bridge_port_group __rcu *next; struct hlist_node mglist; struct rcu_head rcu; struct timer_list timer; @@ -86,7 +86,7 @@ struct net_bridge_mdb_entry struct hlist_node hlist[2]; struct hlist_node mglist; struct net_bridge *br; - struct net_bridge_port_group *ports; + struct net_bridge_port_group __rcu *ports; struct rcu_head rcu; struct timer_list timer; struct timer_list query_timer; @@ -227,7 +227,7 @@ struct net_bridge unsigned long multicast_startup_query_interval; spinlock_t multicast_lock; - struct net_bridge_mdb_htable *mdb; + struct net_bridge_mdb_htable __rcu *mdb; struct hlist_head router_list; struct hlist_head mglist; -- cgit v1.2.3-59-g8ed1b From a386f99025f13b32502fe5dedf223c20d7283826 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 15 Nov 2010 06:38:11 +0000 Subject: bridge: add proper RCU annotation to should_route_hook Add br_should_route_hook_t typedef, this is the only way we can get a clean RCU implementation for function pointer. Move route_hook to location where it is used. Signed-off-by: Eric Dumazet Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/if_bridge.h | 4 +++- net/bridge/br.c | 4 ---- net/bridge/br_input.c | 10 +++++++--- net/bridge/netfilter/ebtable_broute.c | 3 ++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 0d241a5c4909..f7e73c338c40 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -102,7 +102,9 @@ struct __fdb_entry { #include extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); -extern int (*br_should_route_hook)(struct sk_buff *skb); + +typedef int (*br_should_route_hook_t)(struct sk_buff *skb); +extern br_should_route_hook_t __rcu *br_should_route_hook; #endif diff --git a/net/bridge/br.c b/net/bridge/br.c index c8436fa31344..84bbb82599b2 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -22,8 +22,6 @@ #include "br_private.h" -int (*br_should_route_hook)(struct sk_buff *skb); - static const struct stp_proto br_stp_proto = { .rcv = br_stp_rcv, }; @@ -102,8 +100,6 @@ static void __exit br_deinit(void) br_fdb_fini(); } -EXPORT_SYMBOL(br_should_route_hook); - module_init(br_init) module_exit(br_deinit) MODULE_LICENSE("GPL"); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 25207a1f182b..6f6d8e1b776f 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -21,6 +21,10 @@ /* Bridge group multicast address 802.1d (pg 51). */ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; +/* Hook for brouter */ +br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; +EXPORT_SYMBOL(br_should_route_hook); + static int br_pass_frame_up(struct sk_buff *skb) { struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; @@ -139,7 +143,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) { struct net_bridge_port *p; const unsigned char *dest = eth_hdr(skb)->h_dest; - int (*rhook)(struct sk_buff *skb); + br_should_route_hook_t *rhook; if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return skb; @@ -173,8 +177,8 @@ forward: switch (p->state) { case BR_STATE_FORWARDING: rhook = rcu_dereference(br_should_route_hook); - if (rhook != NULL) { - if (rhook(skb)) + if (rhook) { + if ((*rhook)(skb)) return skb; dest = eth_hdr(skb)->h_dest; } diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index ae3f106c3908..1bcaf36ad612 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -87,7 +87,8 @@ static int __init ebtable_broute_init(void) if (ret < 0) return ret; /* see br_input.c */ - rcu_assign_pointer(br_should_route_hook, ebt_broute); + rcu_assign_pointer(br_should_route_hook, + (br_should_route_hook_t *)ebt_broute); return 0; } -- cgit v1.2.3-59-g8ed1b From 61391cde9eefac5cfcf6d214aa80c77e58b1626b Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 15 Nov 2010 06:38:12 +0000 Subject: netdev: add rcu annotations to receive handler hook Suggested by Eric's bridge RCU changes. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fccb11f879e5..b45c1b8b1d19 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -994,8 +994,8 @@ struct net_device { unsigned int real_num_rx_queues; #endif - rx_handler_func_t *rx_handler; - void *rx_handler_data; + rx_handler_func_t __rcu *rx_handler; + void __rcu *rx_handler_data; struct netdev_queue __rcu *ingress_queue; -- cgit v1.2.3-59-g8ed1b From b5ed54e94d324f17c97852296d61a143f01b227a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 15 Nov 2010 06:38:13 +0000 Subject: bridge: fix RCU races with bridge port The macro br_port_exists() is not enough protection when only RCU is being used. There is a tiny race where other CPU has cleared port handler hook, but is bridge port flag might still be set. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 15 +++++++++------ net/bridge/br_if.c | 5 +---- net/bridge/br_netfilter.c | 13 +++++++------ net/bridge/br_netlink.c | 10 ++++++---- net/bridge/br_notify.c | 2 +- net/bridge/br_private.h | 14 +++++++++++--- net/bridge/br_stp_bpdu.c | 8 ++++---- net/bridge/netfilter/ebtables.c | 11 +++++------ 8 files changed, 44 insertions(+), 34 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 90512ccfd3e9..2872393b2939 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -238,15 +238,18 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) { struct net_bridge_fdb_entry *fdb; + struct net_bridge_port *port; int ret; - if (!br_port_exists(dev)) - return 0; - rcu_read_lock(); - fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr); - ret = fdb && fdb->dst->dev != dev && - fdb->dst->state == BR_STATE_FORWARDING; + port = br_port_get_rcu(dev); + if (!port) + ret = 0; + else { + fdb = __br_fdb_get(port->br, addr); + ret = fdb && fdb->dst->dev != dev && + fdb->dst->state == BR_STATE_FORWARDING; + } rcu_read_unlock(); return ret; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 89ad25a76202..427f90a8ab7b 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -475,11 +475,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; - if (!br_port_exists(dev)) - return -EINVAL; - p = br_port_get(dev); - if (p->br != br) + if (!p || p->br != br) return -EINVAL; del_nbp(p); diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 865fd7634b67..ce8b2eed4e73 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -131,17 +131,18 @@ void br_netfilter_rtable_init(struct net_bridge *br) static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) { - if (!br_port_exists(dev)) - return NULL; - return &br_port_get_rcu(dev)->br->fake_rtable; + struct net_bridge_port *port; + + port = br_port_get_rcu(dev); + return port ? &port->br->fake_rtable : NULL; } static inline struct net_device *bridge_parent(const struct net_device *dev) { - if (!br_port_exists(dev)) - return NULL; + struct net_bridge_port *port; - return br_port_get_rcu(dev)->br->dev; + port = br_port_get_rcu(dev); + return port ? port->br->dev : NULL; } static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 4a6a378c84e3..e3de0a428f5d 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -119,11 +119,13 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) idx = 0; for_each_netdev(net, dev) { + struct net_bridge_port *port = br_port_get(dev); + /* not a bridge port */ - if (!br_port_exists(dev) || idx < cb->args[0]) + if (!port || idx < cb->args[0]) goto skip; - if (br_fill_ifinfo(skb, br_port_get(dev), + if (br_fill_ifinfo(skb, port, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI) < 0) @@ -169,9 +171,9 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (!dev) return -ENODEV; - if (!br_port_exists(dev)) - return -EINVAL; p = br_port_get(dev); + if (!p) + return -EINVAL; /* if kernel STP is running, don't allow changes */ if (p->br->stp_enabled == BR_KERNEL_STP) diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 404d4e14c6a7..ef2175c8b91d 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c @@ -32,7 +32,7 @@ struct notifier_block br_device_notifier = { static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = ptr; - struct net_bridge_port *p = br_port_get(dev); + struct net_bridge_port *p; struct net_bridge *br; int err; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index b862071bf601..46e0bec1d7c5 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -151,11 +151,19 @@ struct net_bridge_port #endif }; -#define br_port_get_rcu(dev) \ - ((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data)) -#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data) #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) +static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) +{ + struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data); + return br_port_exists(dev) ? port : NULL; +} + +static inline struct net_bridge_port *br_port_get(struct net_device *dev) +{ + return br_port_exists(dev) ? dev->rx_handler_data : NULL; +} + struct br_cpu_netstats { u64 rx_packets; u64 rx_bytes; diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 35cf27087b56..3d9a55d3822f 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -141,10 +141,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, struct net_bridge *br; const unsigned char *buf; - if (!br_port_exists(dev)) - goto err; - p = br_port_get_rcu(dev); - if (!pskb_may_pull(skb, 4)) goto err; @@ -153,6 +149,10 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) goto err; + p = br_port_get_rcu(dev); + if (!p) + goto err; + br = p->br; spin_lock(&br->lock); diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index a1dcf83f0d58..cbc9f395ab1e 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -128,6 +128,7 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out) { const struct ethhdr *h = eth_hdr(skb); + const struct net_bridge_port *p; __be16 ethproto; int verdict, i; @@ -148,13 +149,11 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) return 1; /* rcu_read_lock()ed by nf_hook_slow */ - if (in && br_port_exists(in) && - FWINV2(ebt_dev_check(e->logical_in, br_port_get_rcu(in)->br->dev), - EBT_ILOGICALIN)) + if (in && (p = br_port_get_rcu(in)) != NULL && + FWINV2(ebt_dev_check(e->logical_in, p->br->dev), EBT_ILOGICALIN)) return 1; - if (out && br_port_exists(out) && - FWINV2(ebt_dev_check(e->logical_out, br_port_get_rcu(out)->br->dev), - EBT_ILOGICALOUT)) + if (out && (p = br_port_get_rcu(out)) != NULL && + FWINV2(ebt_dev_check(e->logical_out, p->br->dev), EBT_ILOGICALOUT)) return 1; if (e->bitmask & EBT_SOURCEMAC) { -- cgit v1.2.3-59-g8ed1b From ec1e5610c00c7f5bc530d2aadd47faa473b90a30 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 15 Nov 2010 06:38:14 +0000 Subject: bridge: add RCU annotations to bridge port lookup br_port_get() renamed to br_port_get_rtnl() to make clear RTNL is held. Signed-off-by: Eric Dumazet Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 2 +- net/bridge/br_netlink.c | 4 ++-- net/bridge/br_notify.c | 4 ++-- net/bridge/br_private.h | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 427f90a8ab7b..d9d1e2bac1d6 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -475,7 +475,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; - p = br_port_get(dev); + p = br_port_get_rtnl(dev); if (!p || p->br != br) return -EINVAL; diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index e3de0a428f5d..f8bf4c7f842c 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -119,7 +119,7 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) idx = 0; for_each_netdev(net, dev) { - struct net_bridge_port *port = br_port_get(dev); + struct net_bridge_port *port = br_port_get_rtnl(dev); /* not a bridge port */ if (!port || idx < cb->args[0]) @@ -171,7 +171,7 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (!dev) return -ENODEV; - p = br_port_get(dev); + p = br_port_get_rtnl(dev); if (!p) return -EINVAL; diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index ef2175c8b91d..7d337c9b6082 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c @@ -37,10 +37,10 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v int err; /* not a port of a bridge */ - if (!br_port_exists(dev)) + p = br_port_get_rtnl(dev); + if (!p) return NOTIFY_DONE; - p = br_port_get(dev); br = p->br; switch (event) { diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 46e0bec1d7c5..84aac7734bfc 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -159,9 +159,10 @@ static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *d return br_port_exists(dev) ? port : NULL; } -static inline struct net_bridge_port *br_port_get(struct net_device *dev) +static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) { - return br_port_exists(dev) ? dev->rx_handler_data : NULL; + return br_port_exists(dev) ? + rtnl_dereference(dev->rx_handler_data) : NULL; } struct br_cpu_netstats { -- cgit v1.2.3-59-g8ed1b From ce5a121304af02d02489e86efb6ae26a67f95e52 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 15 Nov 2010 07:30:42 +0000 Subject: hso: Fix unused variable warning Fallout from the TIOCGICOUNT work Signed-off-by: Alan Cox Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index b154a94de03e..be8cc2a8e213 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1745,7 +1745,6 @@ static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct hso_serial *serial = get_serial_by_tty(tty); - void __user *uarg = (void __user *)arg; int ret = 0; D4("IOCTL cmd: %d, arg: %ld", cmd, arg); -- cgit v1.2.3-59-g8ed1b From 1f4f067f99cbb2af7af7a67bd025a9fb58b5156c Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Mon, 15 Nov 2010 08:09:55 +0000 Subject: enic: Fix build warnings Fix data type of argument passed to pci_alloc_consistent and pci_free_consistent routines. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index c91d364c5527..70672541364e 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.6" +#define DRV_VERSION "1.4.1.7" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd43..9f293fa24768 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2042,7 +2042,7 @@ static int enic_dev_hang_reset(struct enic *enic) static int enic_set_rsskey(struct enic *enic) { - u64 rss_key_buf_pa; + dma_addr_t rss_key_buf_pa; union vnic_rss_key *rss_key_buf_va = NULL; union vnic_rss_key rss_key = { .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101}, @@ -2073,7 +2073,7 @@ static int enic_set_rsskey(struct enic *enic) static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) { - u64 rss_cpu_buf_pa; + dma_addr_t rss_cpu_buf_pa; union vnic_rss_cpu *rss_cpu_buf_va = NULL; unsigned int i; int err; -- cgit v1.2.3-59-g8ed1b From 6b35308850e1679741e8b646cfb7bb3ab5369888 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Nov 2010 20:15:03 -0800 Subject: net: Export netif_get_vlan_features(). ERROR: "netif_get_vlan_features" [drivers/net/xen-netfront.ko] undefined! Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index 8725d168d1f5..381b8e280162 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1983,6 +1983,7 @@ int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) else return 0; } +EXPORT_SYMBOL(netif_get_vlan_features); /* * Returns true if either: -- cgit v1.2.3-59-g8ed1b From 8829c9e2ec144baeb3cee599e1e653a396ad521b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 11:05:38 -0800 Subject: iwlagn: used frame count info in compressed ba packet For newer devices, uCode provide both "number of frames sent" and "number of frames acked" information inside the compressed_ba packet. So instead of figure the success/failure information through the bitmap, use those information which is much betrer approach. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 68 +++++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-commands.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 5 ++- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 4748d067eb1d..a172bd171a0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2620,6 +2620,7 @@ static struct iwl_base_params iwl4965_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .no_agg_framecnt_info = true, }; struct iwl_cfg iwl4965_agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 2b078a995729..522c77f23e04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1241,37 +1241,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, if (sh < 0) /* tbw something is wrong with indices */ sh += 0x100; - /* don't use 64-bit values for now */ - bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; - if (agg->frame_count > (64 - sh)) { IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); return -1; } - - /* check for success or failure according to the - * transmitted bitmap and block-ack bitmap */ - sent_bitmap = bitmap & agg->bitmap; - - /* For each frame attempted in aggregation, - * update driver's record of tx frame's status. */ - i = 0; - while (sent_bitmap) { - ack = sent_bitmap & 1ULL; - successes += ack; - IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", - ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, - agg->start_idx + i); - sent_bitmap >>= 1; - ++i; + if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { + /* + * sent and ack information provided by uCode + * use it instead of figure out ourself + */ + if (ba_resp->txed_2_done > ba_resp->txed) { + IWL_DEBUG_TX_REPLY(priv, + "bogus sent(%d) and ack(%d) count\n", + ba_resp->txed, ba_resp->txed_2_done); + /* + * set txed_2_done = txed, + * so it won't impact rate scale + */ + ba_resp->txed = ba_resp->txed_2_done; + } + IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", + ba_resp->txed, ba_resp->txed_2_done); + } else { + /* don't use 64-bit values for now */ + bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; + + /* check for success or failure according to the + * transmitted bitmap and block-ack bitmap */ + sent_bitmap = bitmap & agg->bitmap; + + /* For each frame attempted in aggregation, + * update driver's record of tx frame's status. */ + i = 0; + while (sent_bitmap) { + ack = sent_bitmap & 1ULL; + successes += ack; + IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", + ack ? "ACK" : "NACK", i, + (agg->start_idx + i) & 0xff, + agg->start_idx + i); + sent_bitmap >>= 1; + ++i; + } } - info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; - info->status.ampdu_ack_len = successes; - info->status.ampdu_len = agg->frame_count; + if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { + info->status.ampdu_ack_len = ba_resp->txed_2_done; + info->status.ampdu_len = ba_resp->txed; + + } else { + info->status.ampdu_ack_len = successes; + info->status.ampdu_len = agg->frame_count; + } iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 424801abc80e..31c29a5fe8b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp { __le64 bitmap; __le16 scd_flow; __le16 scd_ssn; + /* following only for 5000 series and up */ + u8 txed; /* number of frames sent */ + u8 txed_2_done; /* number of frames acked */ } __packed; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ee8cf240d65d..98b79f627720 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -291,7 +291,9 @@ struct iwl_mod_params { * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation * @shadow_reg_enable: HW shadhow register bit -*/ + * @no_agg_framecnt_info: uCode do not provide aggregation frame count + * information + */ struct iwl_base_params { int eeprom_size; int num_of_queues; /* def: HW dependent */ @@ -322,6 +324,7 @@ struct iwl_base_params { const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; const bool shadow_reg_enable; + const bool no_agg_framecnt_info; }; /* * @advanced_bt_coexist: support advanced bt coexist -- cgit v1.2.3-59-g8ed1b From 95a5ede3ee9269e175bfe0e6f5a4a5fd2914ed6a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 8 Nov 2010 14:55:43 -0800 Subject: iwlagn: set dynamic aggregation threshold for BT Setting the max/min/def value for BT dynamic aggregation threshold. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 31c29a5fe8b1..a3cd8117f6e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2410,9 +2410,9 @@ struct iwl_link_quality_cmd { #define BT_FRAG_THRESHOLD_MAX 0 #define BT_FRAG_THRESHOLD_MIN 0 -#define BT_AGG_THRESHOLD_DEF 0 -#define BT_AGG_THRESHOLD_MAX 0 -#define BT_AGG_THRESHOLD_MIN 0 +#define BT_AGG_THRESHOLD_DEF 1200 +#define BT_AGG_THRESHOLD_MAX 8000 +#define BT_AGG_THRESHOLD_MIN 400 /* * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) -- cgit v1.2.3-59-g8ed1b From 66e863a527f9ed3a871797862aaf0d62b0954813 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 8 Nov 2010 14:54:37 -0800 Subject: iwlagn: support dynamic aggregation for BT coex Use dynamic aggregation threshold if bt traffic load is high to reduce the impact on aggregated frame. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 32 ++++++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +-- 7 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c7ff1bdf42cd..d8f9df699d83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -546,6 +546,7 @@ static struct iwl_bt_params iwl6000_bt_params = { .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ca3530c4295a..c6f65fd7675c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2025,7 +2025,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; - u8 last_traffic_load; IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); @@ -2034,11 +2033,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, coex->bt_ci_compliance); iwlagn_print_uartmsg(priv, uart_msg); - last_traffic_load = priv->notif_bt_traffic_load; - priv->notif_bt_traffic_load = coex->bt_traffic_load; + priv->last_bt_traffic_load = priv->bt_traffic_load; if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { if (priv->bt_status != coex->bt_status || - last_traffic_load != coex->bt_traffic_load) { + priv->last_bt_traffic_load != coex->bt_traffic_load) { if (coex->bt_status) { /* BT on */ if (!priv->bt_ch_announce) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 065553629de5..f450adc72361 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_lq_sta *lq_sta) { struct iwl_scale_tbl_info *tbl; - bool full_concurrent; + bool full_concurrent = priv->bt_full_concurrent; unsigned long flags; - spin_lock_irqsave(&priv->lock, flags); - if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) - full_concurrent = true; - else - full_concurrent = false; - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->bt_full_concurrent != full_concurrent) { + if (priv->bt_ant_couple_ok) { + /* + * Is there a need to switch between + * full concurrency and 3-wire? + */ + spin_lock_irqsave(&priv->lock, flags); + if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) + full_concurrent = true; + else + full_concurrent = false; + spin_unlock_irqrestore(&priv->lock, flags); + } + if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || + (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; /* Update uCode's rate table. */ @@ -1040,8 +1046,7 @@ done: if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); - /* Is there a need to switch between full concurrency and 3-wire? */ - if (priv->bt_ant_couple_ok) + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) rs_bt_update_lq(priv, ctx, lq_sta); } @@ -3010,10 +3015,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, */ if (priv && priv->cfg->bt_params && priv->cfg->bt_params->agg_time_limit && - priv->cfg->bt_params->agg_time_limit >= - LINK_QUAL_AGG_TIME_LIMIT_MIN && - priv->cfg->bt_params->agg_time_limit <= - LINK_QUAL_AGG_TIME_LIMIT_MAX) + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) lq_cmd->agg_params.agg_time_limit = cpu_to_le16(priv->cfg->bt_params->agg_time_limit); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 007fb20d78ab..d97691261ace 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3837,7 +3837,6 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; priv->bt_duration = BT_DURATION_LIMIT_DEF; priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; - priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF; } /* Set the tx_power_user_lmt to the lowest power level diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c884ed385fcf..c41f5a878210 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1469,7 +1469,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, * both values are the same and zero. */ if (vif->type == NL80211_IFTYPE_ADHOC) - priv->bt_traffic_load = priv->notif_bt_traffic_load; + priv->bt_traffic_load = priv->last_bt_traffic_load; } void iwl_mac_remove_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 8fdd4efdb1d3..4876e26e054d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1580,7 +1580,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, priv->bt_full_concurrent ? "full concurrency" : "3-wire"); pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " "last traffic notif: %d\n", - priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load); + priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " "sco_active: %d, kill_ack_mask: %x, " "kill_cts_mask: %x\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9fcaaf0cfe93..ea81ced13756 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1471,7 +1471,7 @@ struct iwl_priv { /* bt coex */ u8 bt_status; - u8 bt_traffic_load, notif_bt_traffic_load; + u8 bt_traffic_load, last_bt_traffic_load; bool bt_ch_announce; bool bt_sco_active; bool bt_full_concurrent; @@ -1482,7 +1482,6 @@ struct iwl_priv { u16 bt_on_thresh; u16 bt_duration; u16 dynamic_frag_thresh; - u16 dynamic_agg_thresh; u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; -- cgit v1.2.3-59-g8ed1b From 05433df23cf16a9ccbdd35964aba781cdf455034 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 8 Nov 2010 12:37:20 -0800 Subject: iwlagn: change default ACK/CTS MASK setting for WiFi/BT coex Change the default BT_KILL_ACK_MASK and BT_KILL_CTS_MASK for BT coex Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index a3cd8117f6e3..9c1b7fbef099 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2450,8 +2450,8 @@ struct iwl_bt_cmd { #define IWLAGN_BT3_T7_DEFAULT 1 -#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) -#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) +#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 -- cgit v1.2.3-59-g8ed1b From 564b344c10b694d433cef5b89f8ff8ac5e33898d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 9 Nov 2010 09:21:34 -0800 Subject: iwlwifi: change default led mode for different devices Set the default led mode for different devices. For the newer devices such as 6000g2a, 6000g2b and newer, the default led mode is On/Off instead of blinking. The led_mode still can be control through module parameter 0: system default 1: On/Off 2: blinking Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-3945.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-6000.c | 18 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-led.c | 10 ++++++---- drivers/net/wireless/iwlwifi/iwl-led.h | 6 ++++-- 8 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 068f1e1e3297..e881b083963c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -287,6 +287,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl1000_bg_cfg = { @@ -302,6 +303,7 @@ struct iwl_cfg iwl1000_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl100_bgn_cfg = { @@ -318,6 +320,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl100_bg_cfg = { @@ -333,6 +336,7 @@ struct iwl_cfg iwl100_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .led_mode = IWL_LED_RF_STATE, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index ebac04b7887c..4503245211ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2788,6 +2788,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { .ops = &iwl3945_ops, .mod_params = &iwl3945_mod_params, .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, }; static struct iwl_cfg iwl3945_abg_cfg = { @@ -2800,6 +2801,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { .ops = &iwl3945_ops, .mod_params = &iwl3945_mod_params, .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, }; DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index a172bd171a0c..19da3e5e9eeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2636,6 +2636,7 @@ struct iwl_cfg iwl4965_agn_cfg = { .ops = &iwl4965_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl4965_base_params, + .led_mode = IWL_LED_BLINK, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ad43f0fdf919..b147580fe228 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -536,6 +536,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_bgn_cfg = { @@ -552,6 +553,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_abg_cfg = { @@ -567,6 +569,7 @@ struct iwl_cfg iwl5100_abg_cfg = { .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -583,6 +586,7 @@ struct iwl_cfg iwl5100_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -599,6 +603,7 @@ struct iwl_cfg iwl5350_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -616,6 +621,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5150_abg_cfg = { @@ -632,6 +638,7 @@ struct iwl_cfg iwl5150_abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d8f9df699d83..9f835ac905f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -567,6 +567,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2a_2abg_cfg = { @@ -584,6 +585,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2a_2bg_cfg = { @@ -601,6 +603,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -620,6 +623,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -640,6 +644,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -661,6 +666,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -681,6 +687,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -702,6 +709,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -722,6 +730,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -744,6 +753,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .base_params = &iwl6000_base_params, .ht_params = &iwl6000_ht_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000i_2abg_cfg = { @@ -760,6 +770,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000i_2bg_cfg = { @@ -776,6 +787,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -793,6 +805,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6050g2_bgn_cfg = { @@ -810,6 +823,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -826,6 +840,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6050_base_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000_3agn_cfg = { @@ -843,6 +858,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { .base_params = &iwl6000_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl130_bgn_cfg = { @@ -861,6 +877,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -880,6 +897,7 @@ struct iwl_cfg iwl130_bg_cfg = { .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 98b79f627720..9035cd82d85b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -363,6 +363,7 @@ struct iwl_ht_params { * @need_dc_calib: need to perform init dc calibration * @need_temp_offset_calib: need to perform temperature offset calibration * @scan_antennas: available antenna for scan operation + * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -409,6 +410,7 @@ struct iwl_cfg { const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + enum iwl_led_mode led_mode; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 5a9129219c90..516e5577ed2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -45,9 +45,8 @@ /* default: IWL_LED_BLINK(0) using blinking index table */ static int led_mode; module_param(led_mode, int, S_IRUGO); -MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " - "(default 0)"); - +MODULE_PARM_DESC(led_mode, "led mode: 0=system default, " + "1=On(RF On)/Off(RF Off), 2=blinking"); static const struct { u16 tpt; /* Mb/s */ @@ -128,7 +127,7 @@ EXPORT_SYMBOL(iwl_led_start); int iwl_led_associate(struct iwl_priv *priv) { IWL_DEBUG_LED(priv, "Associated\n"); - if (led_mode == IWL_LED_BLINK) + if (priv->cfg->led_mode == IWL_LED_BLINK) priv->allow_blinking = 1; priv->last_blink_time = jiffies; @@ -223,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv) priv->last_blink_rate = 0; priv->last_blink_time = 0; priv->allow_blinking = 0; + if (led_mode != IWL_LED_DEFAULT && + led_mode != priv->cfg->led_mode) + priv->cfg->led_mode = led_mode; } EXPORT_SYMBOL(iwl_leds_init); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 49a70baa3fb6..9079b33486ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -47,14 +47,16 @@ enum led_type { /* * LED mode - * IWL_LED_BLINK: adjust led blink rate based on blink table + * IWL_LED_DEFAULT: use system default * IWL_LED_RF_STATE: turn LED on/off based on RF state * LED ON = RF ON * LED OFF = RF OFF + * IWL_LED_BLINK: adjust led blink rate based on blink table */ enum iwl_led_mode { - IWL_LED_BLINK, + IWL_LED_DEFAULT, IWL_LED_RF_STATE, + IWL_LED_BLINK, }; void iwl_leds_init(struct iwl_priv *priv); -- cgit v1.2.3-59-g8ed1b From 76f379cec6df6c9c5c9dbf7377d1bbbb0bf3fd5f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:41 -0800 Subject: iwlagn: fix some naming regarding FIFOs Some variables are misnamed in the FIFO setup code, fix that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 703621107dac..8b129e29d341 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -429,7 +429,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { - const s8 *queues; + const s8 *queue_to_fifo; u32 a; unsigned long flags; int i, chan; @@ -492,9 +492,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* map queues to FIFOs */ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) - queues = iwlagn_ipan_queue_to_tx_fifo; + queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; else - queues = iwlagn_default_queue_to_tx_fifo; + queue_to_fifo = iwlagn_default_queue_to_tx_fifo; iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); @@ -510,14 +510,14 @@ int iwlagn_alive_notify(struct iwl_priv *priv) BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); for (i = 0; i < 10; i++) { - int ac = queues[i]; + int fifo = queue_to_fifo[i]; iwl_txq_ctx_activate(priv, i); - if (ac == IWL_TX_FIFO_UNUSED) + if (fifo == IWL_TX_FIFO_UNUSED) continue; - iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0); + iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0); } spin_unlock_irqrestore(&priv->lock, flags); -- cgit v1.2.3-59-g8ed1b From 8d56396ac3926412dd97dcb9dd8d0cef556b908e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:42 -0800 Subject: iwlagn: remove unused variable swq_id Simply remove the unused variable swq_id. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 522c77f23e04..0fc86c9d8fd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -518,7 +518,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_cmd_meta *out_meta; struct iwl_tx_cmd *tx_cmd; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int swq_id, txq_id; + int txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; dma_addr_t scratch_phys; @@ -620,7 +620,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) } txq = &priv->txq[txq_id]; - swq_id = txq->swq_id; q = &txq->q; if (unlikely(iwl_queue_space(q) < q->high_mark)) { -- cgit v1.2.3-59-g8ed1b From 4bea9b990205e4a3d432d9d6c29687215618a306 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:43 -0800 Subject: iwlagn: remove a bogus AGG_OFF check Even if this check were to happen, using the txq_id here (which is a HW queue) would lead to confusion in mac80211. Luckily, it doesn't seem like this can ever happen. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 19da3e5e9eeb..19400792a3fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2238,12 +2238,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { - if (agg->state == IWL_AGG_OFF) - iwl_wake_queue(priv, txq_id); - else - iwl_wake_queue(priv, txq->swq_id); - } + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_wake_queue(priv, txq->swq_id); } } else { info->status.rates[0].count = tx_resp->failure_frame + 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c6f65fd7675c..2ba83b5bbb8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -445,12 +445,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { - if (agg->state == IWL_AGG_OFF) - iwl_wake_queue(priv, txq_id); - else - iwl_wake_queue(priv, txq->swq_id); - } + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_wake_queue(priv, txq->swq_id); } } else { BUG_ON(txq_id != txq->swq_id); -- cgit v1.2.3-59-g8ed1b From 549a04e092e5e043df82fd0541f3b67ab488359b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:44 -0800 Subject: iwlwifi: pass txq to wake/stop queue Instead of passing the txq->swq_id, pass the txq struct directly to make sure that in the future nobody will pass an invalid number. Only three places actually change from using the txq_id or the skb's queue_mapping to now using txq->swq_id as well. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-helpers.h | 8 ++++++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4503245211ac..56f4ca7e49d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -297,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && (txq_id != IWL39_CMD_QUEUE_NUM) && priv->mac80211_registered) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } /** diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 19400792a3fe..2ec868d328b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2239,7 +2239,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq->swq_id); + iwl_wake_queue(priv, txq); } } else { info->status.rates[0].count = tx_resp->failure_frame + 1; @@ -2263,7 +2263,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } if (qc && likely(sta_id != IWL_INVALID_STATION)) iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 2ba83b5bbb8e..eef90b5c9728 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -446,7 +446,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq->swq_id); + iwl_wake_queue(priv, txq); } } else { BUG_ON(txq_id != txq->swq_id); @@ -456,7 +456,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 0fc86c9d8fd4..179a9c85045c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -783,7 +783,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_txq_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); } else { - iwl_stop_queue(priv, txq->swq_id); + iwl_stop_queue(priv, txq); } } @@ -1408,7 +1408,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && priv->mac80211_registered && (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq->swq_id); + iwl_wake_queue(priv, txq); iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); } diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 1aaef70deaec..23fa8e88356b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -116,8 +116,10 @@ static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) return 0x80 | (hwq << 2) | ac; } -static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue) +static inline void iwl_wake_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) { + u8 queue = txq->swq_id; u8 ac = queue; u8 hwq = queue; @@ -131,8 +133,10 @@ static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue) ieee80211_wake_queue(priv->hw, ac); } -static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue) +static inline void iwl_stop_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) { + u8 queue = txq->swq_id; u8 ac = queue; u8 hwq = queue; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a55b4623e1c8..b8c490624d26 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -662,7 +662,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) spin_unlock_irqrestore(&priv->lock, flags); } - iwl_stop_queue(priv, skb_get_queue_mapping(skb)); + iwl_stop_queue(priv, txq); } return 0; -- cgit v1.2.3-59-g8ed1b From ea9b307f8e859186a6791e0d508c5993448ac900 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:45 -0800 Subject: iwlwifi: always build swq_id as virtual queue ID Previously, we used the swq_id's mechanism to have AC and HW queue different only for aggregation queues. To be able to fix a bug with iPAN simply always build the swq_id as ac | (hwq << 2) and remove the flag bit. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++----- drivers/net/wireless/iwlwifi/iwl-helpers.h | 28 +++++++++------------------- drivers/net/wireless/iwlwifi/iwl-tx.c | 11 +++++------ 5 files changed, 17 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index eef90b5c9728..881475cf5ad7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -449,7 +449,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, iwl_wake_queue(priv, txq); } } else { - BUG_ON(txq_id != txq->swq_id); iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 179a9c85045c..330852cc4690 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1012,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data = &priv->stations[sta_id].tid[tid]; *ssn = SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; - priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); + iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); spin_unlock_irqrestore(&priv->sta_lock, flags); ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 4876e26e054d..3cc58420d445 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, " swq_id=%#.2x (ac %d/hwq %d)\n", cnt, q->read_ptr, q->write_ptr, !!test_bit(cnt, priv->queue_stopped), - txq->swq_id, - txq->swq_id & 0x80 ? txq->swq_id & 3 : - txq->swq_id, - txq->swq_id & 0x80 ? (txq->swq_id >> 2) & - 0x1f : txq->swq_id); + txq->swq_id, txq->swq_id & 3, + (txq->swq_id >> 2) & 0x1f); if (cnt >= 4) continue; /* for the ACs, display the stop count too */ diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 23fa8e88356b..e53cd7f7ea36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -104,29 +104,24 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, * | | | | | | | | * | | | | | | +-+-------- AC queue (0-3) * | | | | | | - * | +-+-+-+-+------------ HW A-MPDU queue + * | +-+-+-+-+------------ HW queue ID * | - * +---------------------- indicates agg queue + * +---------------------- unused */ -static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) +static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) { BUG_ON(ac > 3); /* only have 2 bits */ - BUG_ON(hwq > 31); /* only have 5 bits */ + BUG_ON(hwq > 31); /* only use 5 bits */ - return 0x80 | (hwq << 2) | ac; + txq->swq_id = (hwq << 2) | ac; } static inline void iwl_wake_queue(struct iwl_priv *priv, struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; - u8 ac = queue; - u8 hwq = queue; - - if (queue & 0x80) { - ac = queue & 3; - hwq = (queue >> 2) & 0x1f; - } + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; if (test_and_clear_bit(hwq, priv->queue_stopped)) if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) @@ -137,13 +132,8 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; - u8 ac = queue; - u8 hwq = queue; - - if (queue & 0x80) { - ac = queue & 3; - hwq = (queue >> 2) & 0x1f; - } + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; if (!test_and_set_bit(hwq, priv->queue_stopped)) if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index feaa3670c6bb..90659bcf5804 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, txq->need_update = 0; /* - * Aggregation TX queues will get their ID when aggregation begins; - * they overwrite the setting done here. The command FIFO doesn't - * need an swq_id so don't set one to catch errors, all others can - * be set up to the identity mapping. + * For the default queues 0-3, set up the swq_id + * already -- all others need to get one later + * (if they need one at all). */ - if (txq_id != priv->cmd_queue) - txq->swq_id = txq_id; + if (txq_id < 4) + iwl_set_swq_id(txq, txq_id, txq_id); /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ -- cgit v1.2.3-59-g8ed1b From cfa1da7e9133be9280990b2a64fa7696924c8d9a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:46 -0800 Subject: iwlagn: fix PAN queues Currently, when a PAN queue needs to be stopped, we erroneously stop queue number 5 (for example) with mac80211 -- which doesn't even exist! To avoid that problem, recalculate the swq_id for all queues when setting up the queues, and don't use the default identity mapping that is acceptable for devices which don't support PAN. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 57 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8b129e29d341..411a7a20450a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -40,30 +40,36 @@ #include "iwl-agn.h" #include "iwl-agn-calib.h" -static const s8 iwlagn_default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWLAGN_CMD_FIFO_NUM, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, +#define IWL_AC_UNSET -1 + +struct queue_to_fifo_ac { + s8 fifo, ac; +}; + +static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { + { IWL_TX_FIFO_VO, 0, }, + { IWL_TX_FIFO_VI, 1, }, + { IWL_TX_FIFO_BE, 2, }, + { IWL_TX_FIFO_BK, 3, }, + { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, }; -static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL_TX_FIFO_BK_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWL_TX_FIFO_VI_IPAN, - IWL_TX_FIFO_VO_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWLAGN_CMD_FIFO_NUM, +static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { + { IWL_TX_FIFO_VO, 0, }, + { IWL_TX_FIFO_VI, 1, }, + { IWL_TX_FIFO_BE, 2, }, + { IWL_TX_FIFO_BK, 3, }, + { IWL_TX_FIFO_BK_IPAN, 3, }, + { IWL_TX_FIFO_BE_IPAN, 2, }, + { IWL_TX_FIFO_VI_IPAN, 1, }, + { IWL_TX_FIFO_VO_IPAN, 0, }, + { IWL_TX_FIFO_BE_IPAN, 2, }, + { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, }; static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { @@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { - const s8 *queue_to_fifo; + const struct queue_to_fifo_ac *queue_to_fifo; u32 a; unsigned long flags; int i, chan; @@ -510,13 +516,16 @@ int iwlagn_alive_notify(struct iwl_priv *priv) BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); for (i = 0; i < 10; i++) { - int fifo = queue_to_fifo[i]; + int fifo = queue_to_fifo[i].fifo; + int ac = queue_to_fifo[i].ac; iwl_txq_ctx_activate(priv, i); if (fifo == IWL_TX_FIFO_UNUSED) continue; + if (ac != IWL_AC_UNSET) + iwl_set_swq_id(&priv->txq[i], ac, i); iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0); } -- cgit v1.2.3-59-g8ed1b From 893654de3ff41a4f5037397d06a3f853bbbb3484 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:47 -0800 Subject: iwlagn: avoid crash if vif is not assigned For reasons that aren't entirely clear to me, we sometimes get here during hardware reset without the interface being set. Don't crash, but keep a warning. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 2d927a94074d..fbaa8d293654 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -507,6 +507,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (WARN_ON(!ctx->vif)) { + mutex_unlock(&priv->mutex); + return; + } + if (changes & BSS_CHANGED_BEACON_INT) force = true; -- cgit v1.2.3-59-g8ed1b From 2b5f7a679c2ae34407f6cc9387e77b563578bfdc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:48 -0800 Subject: iwlagn: reprogram AP STA after assoc Instead of unconditionally sending unassoc RXON, before any assoc RXON, re-send only the AP STA entry which is required after the BSSID has been programmed into the device to set up internal filters in the microcode properly. This fixes some issues that we correlated with sending a lot of RXON commands to the device. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 39 ++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-sta.c | 51 ++++++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-sta.h | 1 + 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index fbaa8d293654..9db3924ea1d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -97,6 +97,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active = (void *)&ctx->active; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; lockdep_assert_held(&priv->mutex); @@ -176,25 +177,27 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * AP station must be done after the BSSID is set to correctly * set up filters in the device. */ - if (ctx->ctxid == IWL_RXON_CTX_BSS) - ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); - else - ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); - if (ret) - return ret; + if ((old_assoc && new_assoc) || !new_assoc) { + if (ctx->ctxid == IWL_RXON_CTX_BSS) + ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); + else + ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); + if (ret) + return ret; - memcpy(active, &ctx->staging, sizeof(*active)); + memcpy(active, &ctx->staging, sizeof(*active)); - /* - * Un-assoc RXON clears the station table and WEP - * keys, so we have to restore those afterwards. - */ - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; + /* + * Un-assoc RXON clears the station table and WEP + * keys, so we have to restore those afterwards. + */ + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } } /* RXON timing must be before associated RXON */ @@ -235,6 +238,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active, &ctx->staging, sizeof(*active)); + iwl_reprogram_ap_sta(priv, ctx); + /* IBSS beacon needs to be sent after setting assoc */ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) if (iwlagn_update_beacon(priv, ctx->vif)) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7c7f7dcb1b1e..0a67b2fa52a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) } static int iwl_send_remove_station(struct iwl_priv *priv, - const u8 *addr, int sta_id) + const u8 *addr, int sta_id, + bool temporary) { struct iwl_rx_packet *pkt; int ret; @@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv, if (!ret) { switch (pkt->u.rem_sta.status) { case REM_STA_SUCCESS_MSK: - spin_lock_irqsave(&priv->sta_lock, flags_spin); - iwl_sta_ucode_deactivate(priv, sta_id); - spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + if (!temporary) { + spin_lock_irqsave(&priv->sta_lock, flags_spin); + iwl_sta_ucode_deactivate(priv, sta_id); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + } IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); break; default: @@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl_send_remove_station(priv, addr, sta_id); + return iwl_send_remove_station(priv, addr, sta_id, false); out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; @@ -624,6 +627,44 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } EXPORT_SYMBOL(iwl_restore_stations); +void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + unsigned long flags; + int sta_id = ctx->ap_sta_id; + int ret; + struct iwl_addsta_cmd sta_cmd; + struct iwl_link_quality_cmd lq; + bool active; + + spin_lock_irqsave(&priv->sta_lock, flags); + if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { + spin_unlock_irqrestore(&priv->sta_lock, flags); + return; + } + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); + sta_cmd.mode = 0; + memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); + + active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + if (active) { + ret = iwl_send_remove_station( + priv, priv->stations[sta_id].sta.sta.addr, + sta_id, true); + if (ret) + IWL_ERR(priv, "failed to remove STA %pM (%d)\n", + priv->stations[sta_id].sta.sta.addr, ret); + } + ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); + if (ret) + IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", + priv->stations[sta_id].sta.sta.addr, ret); + iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); +} +EXPORT_SYMBOL(iwl_reprogram_ap_sta); + int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { int i; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 06475872eee4..206f1e1a0caf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); +void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); /** * iwl_clear_driver_stations - clear knowledge of all stations from driver -- cgit v1.2.3-59-g8ed1b From efe54db8233a4b41e68cbe67ca2e30c48532078a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 Nov 2010 18:25:49 -0800 Subject: iwlagn: fix PAN slot timing wrt. DTIM When the DTIM is not 1, then the slot timing is in some cases required to be calclulated based on the DTIM interval instead of the beacon interval, fix that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index ffb2f4111ad0..366340f3fb0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (ctx_bss->vif && ctx_pan->vif) { int bcnint = ctx_pan->vif->bss_conf.beacon_int; + int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; /* should be set, but seems unused?? */ cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE); @@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (test_bit(STATUS_SCAN_HW, &priv->status) || (!ctx_bss->vif->bss_conf.idle && !ctx_bss->vif->bss_conf.assoc)) { - slot0 = bcnint * 3 - 20; + slot0 = dtim * bcnint * 3 - 20; slot1 = 20; } else if (!ctx_pan->vif->bss_conf.idle && - !ctx_pan->vif->bss_conf.assoc) { + !ctx_pan->vif->bss_conf.assoc) { slot1 = bcnint * 3 - 20; slot0 = 20; } -- cgit v1.2.3-59-g8ed1b From f4115d46599464a49a3055d33d499d97ac81fccb Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Wed, 10 Nov 2010 18:25:58 -0800 Subject: iwlagn: update QoS before commit associated RXON RXON command without association bit can clear the QoS info in the uCode. Therefore, before sending the associated RXON, we need to send the QoS command just in case. Signed-off-by: Shanyu Zhao Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 59 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 9db3924ea1d6..203ee60a82b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -72,6 +72,34 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, return ret; } +static void iwlagn_update_qos(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm); + if (ret) + IWL_ERR(priv, "Failed to update QoS\n"); +} + static int iwlagn_update_beacon(struct iwl_priv *priv, struct ieee80211_vif *vif) { @@ -208,6 +236,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } if (new_assoc) { + /* QoS info may be cleared by previous un-assoc RXON */ + iwlagn_update_qos(priv, ctx); + /* * We'll run into this code path when beaconing is * enabled, but then we also need to send the beacon @@ -266,34 +297,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } -static void iwlagn_update_qos(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int ret; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm); - if (ret) - IWL_ERR(priv, "Failed to update QoS\n"); -} - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; -- cgit v1.2.3-59-g8ed1b From 21a5b3c6b19a8b8972ccdd55389be28a8b7c9180 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 10 Nov 2010 13:32:59 -0800 Subject: iwlagn: use SKU information in the EEPROM EEPROM contain the SKU information for the device, use it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-6000.c | 18 ------------------ drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 21 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-eeprom.h | 12 +++++++++++- 7 files changed, 36 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e881b083963c..3100a72b9b44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -278,7 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -295,7 +294,6 @@ struct iwl_cfg iwl1000_bg_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -311,7 +309,6 @@ struct iwl_cfg iwl100_bgn_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -328,7 +325,6 @@ struct iwl_cfg iwl100_bg_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 2ec868d328b9..6788ceb37686 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2624,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = { .fw_name_pre = IWL4965_FW_PRE, .ucode_api_max = IWL4965_UCODE_API_MAX, .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b147580fe228..3ee0f7c035cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -527,7 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -544,7 +543,6 @@ struct iwl_cfg iwl5100_bgn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -561,7 +559,6 @@ struct iwl_cfg iwl5100_abg_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -577,7 +574,6 @@ struct iwl_cfg iwl5100_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -594,7 +590,6 @@ struct iwl_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, @@ -611,7 +606,6 @@ struct iwl_cfg iwl5150_agn_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, @@ -629,7 +623,6 @@ struct iwl_cfg iwl5150_abg_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9f835ac905f1..0cc66fdc7a0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -556,7 +556,6 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -575,7 +574,6 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -593,7 +591,6 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -611,7 +608,6 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -633,7 +629,6 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -654,7 +649,6 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -676,7 +670,6 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -697,7 +690,6 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -719,7 +711,6 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -743,7 +734,6 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -761,7 +751,6 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -778,7 +767,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -795,7 +783,6 @@ struct iwl_cfg iwl6050_2agn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .ops = &iwl6050_ops, @@ -813,7 +800,6 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, @@ -831,7 +817,6 @@ struct iwl_cfg iwl6050_2abg_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, @@ -848,7 +833,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -866,7 +850,6 @@ struct iwl_cfg iwl130_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -887,7 +870,6 @@ struct iwl_cfg iwl130_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index a650baba0809..8a4d3acb9b79 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -248,6 +248,27 @@ err: } +int iwl_eeprom_check_sku(struct iwl_priv *priv) +{ + u16 eeprom_sku; + + eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); + + priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> + EEPROM_SKU_CAP_BAND_POS); + if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) + priv->cfg->sku |= IWL_SKU_N; + + if (!priv->cfg->sku) { + IWL_ERR(priv, "Invalid device sku\n"); + return -EINVAL; + } + + IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); + + return 0; +} + void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) { const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d97691261ace..59af06d3511c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4134,6 +4134,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto out_free_eeprom; + err = iwl_eeprom_check_sku(priv); + if (err) + goto out_free_eeprom; + /* extract MAC Address */ iwl_eeprom_get_mac(priv, priv->addresses[0].addr); IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d9b590625ae4..e87be1e551aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,9 +110,18 @@ enum { }; /* SKU Capabilities */ +/* 3945 only */ #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) #define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) +/* 5000 and up */ +#define EEPROM_SKU_CAP_BAND_POS (4) +#define EEPROM_SKU_CAP_BAND_SELECTION \ + (3 << EEPROM_SKU_CAP_BAND_POS) +#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) +#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) +#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) + /* *regulatory* channel data format in eeprom, one for each channel. * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ struct iwl_eeprom_channel { @@ -397,7 +406,7 @@ struct iwl_eeprom_calib_info { #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ #define EEPROM_VERSION (2*0x44) /* 2 bytes */ -#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ +#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ @@ -504,6 +513,7 @@ struct iwl_eeprom_ops { int iwl_eeprom_init(struct iwl_priv *priv); void iwl_eeprom_free(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv); +int iwl_eeprom_check_sku(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); -- cgit v1.2.3-59-g8ed1b From 6163a3735aad19bdb8d02b3362d3a2d7d2eb78d5 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Fri, 12 Nov 2010 13:48:13 -0800 Subject: iwlagn: check change before commit RXON cmd When setting rxon chain and filter, no need to commit RXON when the chain flag is not changed. This reduces the number of RXON commands we send down to uCode. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 59af06d3511c..c6e455e8845a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -97,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv) if (priv->cfg->ops->hcmd->set_rxon_chain) { for_each_context(priv, ctx) { priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - iwlcore_commit_rxon(priv, ctx); + if (ctx->active.rx_chain != ctx->staging.rx_chain) + iwlcore_commit_rxon(priv, ctx); } } } -- cgit v1.2.3-59-g8ed1b From 9e2e7422d059f9b98c3a0810df92a1ff660ade2f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 12 Nov 2010 13:52:37 -0800 Subject: iwlwifi: set STATUS_READY before commit_rxon Have the STATUS_READY bit set before commit_rxon call to avoid fail to send tx power to uCode. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c6e455e8845a..5b96b0d80091 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2717,6 +2717,8 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_reset_run_time_calib(priv); + set_bit(STATUS_READY, &priv->status); + /* Configure the adapter for unassociated operation */ iwlcore_commit_rxon(priv, ctx); @@ -2726,7 +2728,6 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_leds_init(priv); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); iwl_power_update_mode(priv, true); -- cgit v1.2.3-59-g8ed1b From 9d82ca98f71fd686ef2f3017c5e3e6a4871b6e46 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 15 Nov 2010 20:29:21 +0000 Subject: ipv6: fix missing in6_ifa_put in addrconf Fix ref count bug introduced by commit 2de795707294972f6c34bae9de713e502c431296 Author: Lorenzo Colitti Date: Wed Oct 27 18:16:49 2010 +0000 ipv6: addrconf: don't remove address state on ifdown if the address is being kept Fix logic so that addrconf_ifdown() decrements the inet6_ifaddr refcnt correctly with in6_ifa_put(). Reported-by: Stephen Hemminger Signed-off-by: John Fastabend Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b41ce0f0d514..aaa3ca448d08 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2754,13 +2754,13 @@ static int addrconf_ifdown(struct net_device *dev, int how) ifa->state = INET6_IFADDR_STATE_DEAD; spin_unlock_bh(&ifa->state_lock); - if (state == INET6_IFADDR_STATE_DEAD) { - in6_ifa_put(ifa); - } else { + if (state != INET6_IFADDR_STATE_DEAD) { __ipv6_ifa_notify(RTM_DELADDR, ifa); atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); } + + in6_ifa_put(ifa); write_lock_bh(&idev->lock); } } -- cgit v1.2.3-59-g8ed1b From 3654654f7aa79a37dde130afb7409c55b11807e7 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 16 Nov 2010 09:52:32 -0800 Subject: netlink: let nlmsg and nla functions take pointer-to-const args The changed functions do not modify the NL messages and/or attributes at all. They should use const (similar to strchr), so that callers which have a const nlmsg/nlattr around can make use of them without casting. While at it, constify a data array. Signed-off-by: Jan Engelhardt Signed-off-by: David S. Miller --- include/net/netlink.h | 21 +++++++++++++-------- lib/nlattr.c | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 9801c55de5d6..373f1a900cf4 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -225,13 +225,15 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, unsigned int group, int report, gfp_t flags); -extern int nla_validate(struct nlattr *head, int len, int maxtype, +extern int nla_validate(const struct nlattr *head, + int len, int maxtype, const struct nla_policy *policy); -extern int nla_parse(struct nlattr *tb[], int maxtype, - struct nlattr *head, int len, +extern int nla_parse(struct nlattr **tb, int maxtype, + const struct nlattr *head, int len, const struct nla_policy *policy); extern int nla_policy_len(const struct nla_policy *, int); -extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); +extern struct nlattr * nla_find(const struct nlattr *head, + int len, int attrtype); extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize); extern int nla_memcpy(void *dest, const struct nlattr *src, int count); @@ -346,7 +348,8 @@ static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) * Returns the next netlink message in the message stream and * decrements remaining by the size of the current message. */ -static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) +static inline struct nlmsghdr * +nlmsg_next(const struct nlmsghdr *nlh, int *remaining) { int totlen = NLMSG_ALIGN(nlh->nlmsg_len); @@ -398,7 +401,8 @@ static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, * @maxtype: maximum attribute type to be expected * @policy: validation policy */ -static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, +static inline int nlmsg_validate(const struct nlmsghdr *nlh, + int hdrlen, int maxtype, const struct nla_policy *policy) { if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) @@ -727,7 +731,8 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) * * Returns the first attribute which matches the specified type. */ -static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype) +static inline struct nlattr * +nla_find_nested(const struct nlattr *nla, int attrtype) { return nla_find(nla_data(nla), nla_len(nla), attrtype); } @@ -1032,7 +1037,7 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) * * Returns 0 on success or a negative error code. */ -static inline int nla_validate_nested(struct nlattr *start, int maxtype, +static inline int nla_validate_nested(const struct nlattr *start, int maxtype, const struct nla_policy *policy) { return nla_validate(nla_data(start), nla_len(start), maxtype, policy); diff --git a/lib/nlattr.c b/lib/nlattr.c index c4706eb98d3d..00e8a02681a6 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -15,7 +15,7 @@ #include #include -static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { +static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_U8] = sizeof(u8), [NLA_U16] = sizeof(u16), [NLA_U32] = sizeof(u32), @@ -23,7 +23,7 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { [NLA_NESTED] = NLA_HDRLEN, }; -static int validate_nla(struct nlattr *nla, int maxtype, +static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy) { const struct nla_policy *pt; @@ -115,10 +115,10 @@ static int validate_nla(struct nlattr *nla, int maxtype, * * Returns 0 on success or a negative error code. */ -int nla_validate(struct nlattr *head, int len, int maxtype, +int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy) { - struct nlattr *nla; + const struct nlattr *nla; int rem, err; nla_for_each_attr(nla, head, len, rem) { @@ -173,10 +173,10 @@ nla_policy_len(const struct nla_policy *p, int n) * * Returns 0 on success or a negative error code. */ -int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, - const struct nla_policy *policy) +int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, + int len, const struct nla_policy *policy) { - struct nlattr *nla; + const struct nlattr *nla; int rem, err; memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); @@ -191,7 +191,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, goto errout; } - tb[type] = nla; + tb[type] = (struct nlattr *)nla; } } @@ -212,14 +212,14 @@ errout: * * Returns the first attribute in the stream matching the specified type. */ -struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) +struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype) { - struct nlattr *nla; + const struct nlattr *nla; int rem; nla_for_each_attr(nla, head, len, rem) if (nla_type(nla) == attrtype) - return nla; + return (struct nlattr *)nla; return NULL; } -- cgit v1.2.3-59-g8ed1b From 020f01ebd04f3429c32586d90598c9f59e54ca7d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 9 Nov 2010 14:35:16 +0000 Subject: drivers/isdn/mISDN: Use printf extension %pV Using %pV reduces the number of printk calls and eliminates any possible message interleaving from other printk calls. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/isdn/mISDN/layer1.c | 10 +++++++--- drivers/isdn/mISDN/layer2.c | 12 +++++++++--- drivers/isdn/mISDN/tei.c | 23 +++++++++++++++++------ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c index ac4aa18c632b..5cc7c001c523 100644 --- a/drivers/isdn/mISDN/layer1.c +++ b/drivers/isdn/mISDN/layer1.c @@ -99,12 +99,16 @@ static void l1m_debug(struct FsmInst *fi, char *fmt, ...) { struct layer1 *l1 = fi->userdata; + struct va_format vaf; va_list va; va_start(va, fmt); - printk(KERN_DEBUG "%s: ", dev_name(&l1->dch->dev.dev)); - vprintk(fmt, va); - printk("\n"); + + vaf.fmt = fmt; + vaf.va = &va; + + printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); + va_end(va); } diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index c97371788764..4ae75053c9d2 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c @@ -95,14 +95,20 @@ static void l2m_debug(struct FsmInst *fi, char *fmt, ...) { struct layer2 *l2 = fi->userdata; + struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_FSM)) return; + va_start(va, fmt); - printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei); - vprintk(fmt, va); - printk("\n"); + + vaf.fmt = fmt; + vaf.va = &va; + + printk(KERN_DEBUG "l2 (sapi %d tei %d): %pV\n", + l2->sapi, l2->tei, &vaf); + va_end(va); } diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index 1b85d9d27496..687c9b6264ab 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c @@ -79,14 +79,19 @@ static void da_debug(struct FsmInst *fi, char *fmt, ...) { struct manager *mgr = fi->userdata; + struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_TEIFSM)) return; + va_start(va, fmt); - printk(KERN_DEBUG "mgr(%d): ", mgr->ch.st->dev->id); - vprintk(fmt, va); - printk("\n"); + + vaf.fmt = fmt; + vaf.va = &va; + + printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf); + va_end(va); } @@ -223,14 +228,20 @@ static void tei_debug(struct FsmInst *fi, char *fmt, ...) { struct teimgr *tm = fi->userdata; + struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_TEIFSM)) return; + va_start(va, fmt); - printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei); - vprintk(fmt, va); - printk("\n"); + + vaf.fmt = fmt; + vaf.va = &va; + + printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n", + tm->l2->sapi, tm->l2->tei, &vaf); + va_end(va); } -- cgit v1.2.3-59-g8ed1b From 0e3125c755445664f00ad036e4fc2cd32fd52877 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 16 Nov 2010 10:26:47 -0800 Subject: packet: Enhance AF_PACKET implementation to not require high order contiguous memory allocation (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version 4 of this patch. Change notes: 1) Removed extra memset. Didn't think kcalloc added a GFP_ZERO the way kzalloc did :) Summary: It was shown to me recently that systems under high load were driven very deep into swap when tcpdump was run. The reason this happened was because the AF_PACKET protocol has a SET_RINGBUFFER socket option that allows the user space application to specify how many entries an AF_PACKET socket will have and how large each entry will be. It seems the default setting for tcpdump is to set the ring buffer to 32 entries of 64 Kb each, which implies 32 order 5 allocation. Thats difficult under good circumstances, and horrid under memory pressure. I thought it would be good to make that a bit more usable. I was going to do a simple conversion of the ring buffer from contigous pages to iovecs, but unfortunately, the metadata which AF_PACKET places in these buffers can easily span a page boundary, and given that these buffers get mapped into user space, and the data layout doesn't easily allow for a change to padding between frames to avoid that, a simple iovec change is just going to break user space ABI consistency. So I've done this, I've added a three tiered mechanism to the af_packet set_ring socket option. It attempts to allocate memory in the following order: 1) Using __get_free_pages with GFP_NORETRY set, so as to fail quickly without digging into swap 2) Using vmalloc 3) Using __get_free_pages with GFP_NORETRY clear, causing us to try as hard as needed to get the memory The effect is that we don't disturb the system as much when we're under load, while still being able to conduct tcpdumps effectively. Tested successfully by me. Signed-off-by: Neil Horman Acked-by: Eric Dumazet Acked-by: Maciej Żenczykowski Reported-by: Maciej Żenczykowski Signed-off-by: David S. Miller --- net/packet/af_packet.c | 85 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8298e676f5a0..20964560a0ed 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -163,8 +164,14 @@ struct packet_mreq_max { static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing, int tx_ring); +#define PGV_FROM_VMALLOC 1 +struct pgv { + char *buffer; + unsigned char flags; +}; + struct packet_ring_buffer { - char **pg_vec; + struct pgv *pg_vec; unsigned int head; unsigned int frames_per_block; unsigned int frame_size; @@ -283,7 +290,8 @@ static void *packet_lookup_frame(struct packet_sock *po, pg_vec_pos = position / rb->frames_per_block; frame_offset = position % rb->frames_per_block; - h.raw = rb->pg_vec[pg_vec_pos] + (frame_offset * rb->frame_size); + h.raw = rb->pg_vec[pg_vec_pos].buffer + + (frame_offset * rb->frame_size); if (status != __packet_get_status(po, h.raw)) return NULL; @@ -2325,37 +2333,74 @@ static const struct vm_operations_struct packet_mmap_ops = { .close = packet_mm_close, }; -static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len) +static void free_pg_vec(struct pgv *pg_vec, unsigned int order, + unsigned int len) { int i; for (i = 0; i < len; i++) { - if (likely(pg_vec[i])) - free_pages((unsigned long) pg_vec[i], order); + if (likely(pg_vec[i].buffer)) { + if (pg_vec[i].flags & PGV_FROM_VMALLOC) + vfree(pg_vec[i].buffer); + else + free_pages((unsigned long)pg_vec[i].buffer, + order); + pg_vec[i].buffer = NULL; + } } kfree(pg_vec); } -static inline char *alloc_one_pg_vec_page(unsigned long order) +static inline char *alloc_one_pg_vec_page(unsigned long order, + unsigned char *flags) { - gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | __GFP_NOWARN; + char *buffer = NULL; + gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | + __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY; + + buffer = (char *) __get_free_pages(gfp_flags, order); + + if (buffer) + return buffer; + + /* + * __get_free_pages failed, fall back to vmalloc + */ + *flags |= PGV_FROM_VMALLOC; + buffer = vmalloc((1 << order) * PAGE_SIZE); - return (char *) __get_free_pages(gfp_flags, order); + if (buffer) + return buffer; + + /* + * vmalloc failed, lets dig into swap here + */ + *flags = 0; + gfp_flags &= ~__GFP_NORETRY; + buffer = (char *)__get_free_pages(gfp_flags, order); + if (buffer) + return buffer; + + /* + * complete and utter failure + */ + return NULL; } -static char **alloc_pg_vec(struct tpacket_req *req, int order) +static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) { unsigned int block_nr = req->tp_block_nr; - char **pg_vec; + struct pgv *pg_vec; int i; - pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL); + pg_vec = kcalloc(block_nr, sizeof(struct pgv), GFP_KERNEL); if (unlikely(!pg_vec)) goto out; for (i = 0; i < block_nr; i++) { - pg_vec[i] = alloc_one_pg_vec_page(order); - if (unlikely(!pg_vec[i])) + pg_vec[i].buffer = alloc_one_pg_vec_page(order, + &pg_vec[i].flags); + if (unlikely(!pg_vec[i].buffer)) goto out_free_pgvec; } @@ -2364,6 +2409,7 @@ out: out_free_pgvec: free_pg_vec(pg_vec, order, block_nr); + kfree(pg_vec); pg_vec = NULL; goto out; } @@ -2371,7 +2417,7 @@ out_free_pgvec: static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing, int tx_ring) { - char **pg_vec = NULL; + struct pgv *pg_vec = NULL; struct packet_sock *po = pkt_sk(sk); int was_running, order = 0; struct packet_ring_buffer *rb; @@ -2533,15 +2579,22 @@ static int packet_mmap(struct file *file, struct socket *sock, continue; for (i = 0; i < rb->pg_vec_len; i++) { - struct page *page = virt_to_page(rb->pg_vec[i]); + struct page *page; + void *kaddr = rb->pg_vec[i].buffer; int pg_num; for (pg_num = 0; pg_num < rb->pg_vec_pages; - pg_num++, page++) { + pg_num++) { + if (rb->pg_vec[i].flags & PGV_FROM_VMALLOC) + page = vmalloc_to_page(kaddr); + else + page = virt_to_page(kaddr); + err = vm_insert_page(vma, start, page); if (unlikely(err)) goto out; start += PAGE_SIZE; + kaddr += PAGE_SIZE; } } } -- cgit v1.2.3-59-g8ed1b From 8ffab51b3dfc54876f145f15b351c41f3f703195 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 10 Nov 2010 21:14:04 +0000 Subject: macvlan: lockless tx path macvlan is a stacked device, like tunnels. We should use the lockless mechanism we are using in tunnels and loopback. This patch completely removes locking in TX path. tx stat counters are added into existing percpu stat structure, renamed from rx_stats to pcpu_stats. Note : this reverts commit 2c11455321f37 (macvlan: add multiqueue capability) Note : rx_errors converted to a 32bit counter, like tx_dropped, since they dont need 64bit range. Signed-off-by: Eric Dumazet Cc: Patrick McHardy Cc: Ben Greear Cc: Ben Hutchings Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 80 ++++++++++++++++++++-------------------------- include/linux/if_macvlan.h | 34 ++++++++++++-------- 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 0fc9dc7f20db..93f0ba25c808 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -243,18 +243,22 @@ xmit_world: netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev) { - int i = skb_get_queue_mapping(skb); - struct netdev_queue *txq = netdev_get_tx_queue(dev, i); unsigned int len = skb->len; int ret; + const struct macvlan_dev *vlan = netdev_priv(dev); ret = macvlan_queue_xmit(skb, dev); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - txq->tx_packets++; - txq->tx_bytes += len; - } else - txq->tx_dropped++; + struct macvlan_pcpu_stats *pcpu_stats; + pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); + u64_stats_update_begin(&pcpu_stats->syncp); + pcpu_stats->tx_packets++; + pcpu_stats->tx_bytes += len; + u64_stats_update_end(&pcpu_stats->syncp); + } else { + this_cpu_inc(vlan->pcpu_stats->tx_dropped); + } return ret; } EXPORT_SYMBOL_GPL(macvlan_start_xmit); @@ -414,14 +418,15 @@ static int macvlan_init(struct net_device *dev) dev->state = (dev->state & ~MACVLAN_STATE_MASK) | (lowerdev->state & MACVLAN_STATE_MASK); dev->features = lowerdev->features & MACVLAN_FEATURES; + dev->features |= NETIF_F_LLTX; dev->gso_max_size = lowerdev->gso_max_size; dev->iflink = lowerdev->ifindex; dev->hard_header_len = lowerdev->hard_header_len; macvlan_set_lockdep_class(dev); - vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats); - if (!vlan->rx_stats) + vlan->pcpu_stats = alloc_percpu(struct macvlan_pcpu_stats); + if (!vlan->pcpu_stats) return -ENOMEM; return 0; @@ -431,7 +436,7 @@ static void macvlan_uninit(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); - free_percpu(vlan->rx_stats); + free_percpu(vlan->pcpu_stats); } static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, @@ -439,33 +444,38 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, { struct macvlan_dev *vlan = netdev_priv(dev); - dev_txq_stats_fold(dev, stats); - - if (vlan->rx_stats) { - struct macvlan_rx_stats *p, accum = {0}; - u64 rx_packets, rx_bytes, rx_multicast; + if (vlan->pcpu_stats) { + struct macvlan_pcpu_stats *p; + u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes; + u32 rx_errors = 0, tx_dropped = 0; unsigned int start; int i; for_each_possible_cpu(i) { - p = per_cpu_ptr(vlan->rx_stats, i); + p = per_cpu_ptr(vlan->pcpu_stats, i); do { start = u64_stats_fetch_begin_bh(&p->syncp); rx_packets = p->rx_packets; rx_bytes = p->rx_bytes; rx_multicast = p->rx_multicast; + tx_packets = p->tx_packets; + tx_bytes = p->tx_bytes; } while (u64_stats_fetch_retry_bh(&p->syncp, start)); - accum.rx_packets += rx_packets; - accum.rx_bytes += rx_bytes; - accum.rx_multicast += rx_multicast; - /* rx_errors is an ulong, updated without syncp protection */ - accum.rx_errors += p->rx_errors; + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; + stats->multicast += rx_multicast; + stats->tx_packets += tx_packets; + stats->tx_bytes += tx_bytes; + /* rx_errors & tx_dropped are u32, updated + * without syncp protection. + */ + rx_errors += p->rx_errors; + tx_dropped += p->tx_dropped; } - stats->rx_packets = accum.rx_packets; - stats->rx_bytes = accum.rx_bytes; - stats->rx_errors = accum.rx_errors; - stats->rx_dropped = accum.rx_errors; - stats->multicast = accum.rx_multicast; + stats->rx_errors = rx_errors; + stats->rx_dropped = rx_errors; + stats->tx_dropped = tx_dropped; } return stats; } @@ -601,25 +611,6 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } -static int macvlan_get_tx_queues(struct net *net, - struct nlattr *tb[], - unsigned int *num_tx_queues, - unsigned int *real_num_tx_queues) -{ - struct net_device *real_dev; - - if (!tb[IFLA_LINK]) - return -EINVAL; - - real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); - if (!real_dev) - return -ENODEV; - - *num_tx_queues = real_dev->num_tx_queues; - *real_num_tx_queues = real_dev->real_num_tx_queues; - return 0; -} - int macvlan_common_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], int (*receive)(struct sk_buff *skb), @@ -743,7 +734,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops) { /* common fields */ ops->priv_size = sizeof(struct macvlan_dev); - ops->get_tx_queues = macvlan_get_tx_queues; ops->validate = macvlan_validate; ops->maxtype = IFLA_MACVLAN_MAX; ops->policy = macvlan_policy; diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index ac96a2d76291..e28b2e4959d4 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -25,19 +25,25 @@ struct macvlan_port; struct macvtap_queue; /** - * struct macvlan_rx_stats - MACVLAN percpu rx stats + * struct macvlan_pcpu_stats - MACVLAN percpu stats * @rx_packets: number of received packets * @rx_bytes: number of received bytes * @rx_multicast: number of received multicast packets + * @tx_packets: number of transmitted packets + * @tx_bytes: number of transmitted bytes * @syncp: synchronization point for 64bit counters - * @rx_errors: number of errors + * @rx_errors: number of rx errors + * @tx_dropped: number of tx dropped packets */ -struct macvlan_rx_stats { +struct macvlan_pcpu_stats { u64 rx_packets; u64 rx_bytes; u64 rx_multicast; + u64 tx_packets; + u64 tx_bytes; struct u64_stats_sync syncp; - unsigned long rx_errors; + u32 rx_errors; + u32 tx_dropped; }; /* @@ -52,7 +58,7 @@ struct macvlan_dev { struct hlist_node hlist; struct macvlan_port *port; struct net_device *lowerdev; - struct macvlan_rx_stats __percpu *rx_stats; + struct macvlan_pcpu_stats __percpu *pcpu_stats; enum macvlan_mode mode; int (*receive)(struct sk_buff *skb); int (*forward)(struct net_device *dev, struct sk_buff *skb); @@ -64,18 +70,18 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, unsigned int len, bool success, bool multicast) { - struct macvlan_rx_stats *rx_stats; - - rx_stats = this_cpu_ptr(vlan->rx_stats); if (likely(success)) { - u64_stats_update_begin(&rx_stats->syncp); - rx_stats->rx_packets++; - rx_stats->rx_bytes += len; + struct macvlan_pcpu_stats *pcpu_stats; + + pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); + u64_stats_update_begin(&pcpu_stats->syncp); + pcpu_stats->rx_packets++; + pcpu_stats->rx_bytes += len; if (multicast) - rx_stats->rx_multicast++; - u64_stats_update_end(&rx_stats->syncp); + pcpu_stats->rx_multicast++; + u64_stats_update_end(&pcpu_stats->syncp); } else { - rx_stats->rx_errors++; + this_cpu_inc(vlan->pcpu_stats->rx_errors); } } -- cgit v1.2.3-59-g8ed1b From 4af429d29b341bb1735f04c2fb960178ed5d52e7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 10 Nov 2010 23:42:00 +0000 Subject: vlan: lockless transmit path vlan is a stacked device, like tunnels. We should use the lockless mechanism we are using in tunnels and loopback. This patch completely removes locking in TX path. tx stat counters are added into existing percpu stat structure, renamed from vlan_rx_stats to vlan_pcpu_stats. Note : this partially reverts commit 2e59af3dcbdf (vlan: multiqueue vlan device) Signed-off-by: Eric Dumazet Cc: Patrick McHardy Signed-off-by: David S. Miller --- net/8021q/vlan.c | 4 +--- net/8021q/vlan.h | 18 +++++++++----- net/8021q/vlan_core.c | 4 ++-- net/8021q/vlan_dev.c | 61 +++++++++++++++++++++++++++--------------------- net/8021q/vlan_netlink.c | 20 ---------------- 5 files changed, 50 insertions(+), 57 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 55d2135889fc..dc1071327d87 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -272,13 +272,11 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } - new_dev = alloc_netdev_mq(sizeof(struct vlan_dev_info), name, - vlan_setup, real_dev->num_tx_queues); + new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup); if (new_dev == NULL) return -ENOBUFS; - netif_copy_real_num_queues(new_dev, real_dev); dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 4625ba64dfdc..5687c9b95f33 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -19,19 +19,25 @@ struct vlan_priority_tci_mapping { /** - * struct vlan_rx_stats - VLAN percpu rx stats + * struct vlan_pcpu_stats - VLAN percpu rx/tx stats * @rx_packets: number of received packets * @rx_bytes: number of received bytes * @rx_multicast: number of received multicast packets + * @tx_packets: number of transmitted packets + * @tx_bytes: number of transmitted bytes * @syncp: synchronization point for 64bit counters - * @rx_errors: number of errors + * @rx_errors: number of rx errors + * @tx_dropped: number of tx drops */ -struct vlan_rx_stats { +struct vlan_pcpu_stats { u64 rx_packets; u64 rx_bytes; u64 rx_multicast; + u64 tx_packets; + u64 tx_bytes; struct u64_stats_sync syncp; - unsigned long rx_errors; + u32 rx_errors; + u32 tx_dropped; }; /** @@ -45,7 +51,7 @@ struct vlan_rx_stats { * @real_dev: underlying netdevice * @real_dev_addr: address of underlying netdevice * @dent: proc dir entry - * @vlan_rx_stats: ptr to percpu rx stats + * @vlan_pcpu_stats: ptr to percpu rx stats */ struct vlan_dev_info { unsigned int nr_ingress_mappings; @@ -60,7 +66,7 @@ struct vlan_dev_info { unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; - struct vlan_rx_stats __percpu *vlan_rx_stats; + struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; }; static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 69b2f79800a5..ce8e3ab3e7a5 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -9,7 +9,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp) struct sk_buff *skb = *skbp; u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; struct net_device *vlan_dev; - struct vlan_rx_stats *rx_stats; + struct vlan_pcpu_stats *rx_stats; vlan_dev = vlan_find_dev(skb->dev, vlan_id); if (!vlan_dev) { @@ -26,7 +26,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp) skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); skb->vlan_tci = 0; - rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f3c9552f6ba8..2fa3f4a3f60f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -141,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) { struct vlan_hdr *vhdr; - struct vlan_rx_stats *rx_stats; + struct vlan_pcpu_stats *rx_stats; struct net_device *vlan_dev; u16 vlan_id; u16 vlan_tci; @@ -177,7 +177,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } else { skb->dev = vlan_dev; - rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; @@ -310,8 +310,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { - int i = skb_get_queue_mapping(skb); - struct netdev_queue *txq = netdev_get_tx_queue(dev, i); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; @@ -334,10 +332,16 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - txq->tx_packets++; - txq->tx_bytes += len; - } else - txq->tx_dropped++; + struct vlan_pcpu_stats *stats; + + stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats); + u64_stats_update_begin(&stats->syncp); + stats->tx_packets++; + stats->tx_bytes += len; + u64_stats_update_begin(&stats->syncp); + } else { + this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); + } return ret; } @@ -696,6 +700,7 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_PRESENT); dev->features |= real_dev->features & real_dev->vlan_features; + dev->features |= NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; /* ipv6 shared card related stuff */ @@ -728,8 +733,8 @@ static int vlan_dev_init(struct net_device *dev) vlan_dev_set_lockdep_class(dev, subclass); - vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats); - if (!vlan_dev_info(dev)->vlan_rx_stats) + vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); + if (!vlan_dev_info(dev)->vlan_pcpu_stats) return -ENOMEM; return 0; @@ -741,8 +746,8 @@ static void vlan_dev_uninit(struct net_device *dev) struct vlan_dev_info *vlan = vlan_dev_info(dev); int i; - free_percpu(vlan->vlan_rx_stats); - vlan->vlan_rx_stats = NULL; + free_percpu(vlan->vlan_pcpu_stats); + vlan->vlan_pcpu_stats = NULL; for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { while ((pm = vlan->egress_priority_map[i]) != NULL) { vlan->egress_priority_map[i] = pm->next; @@ -780,33 +785,37 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - dev_txq_stats_fold(dev, stats); - if (vlan_dev_info(dev)->vlan_rx_stats) { - struct vlan_rx_stats *p, accum = {0}; + if (vlan_dev_info(dev)->vlan_pcpu_stats) { + struct vlan_pcpu_stats *p; + u32 rx_errors = 0, tx_dropped = 0; int i; for_each_possible_cpu(i) { - u64 rxpackets, rxbytes, rxmulticast; + u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; unsigned int start; - p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i); + p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i); do { start = u64_stats_fetch_begin_bh(&p->syncp); rxpackets = p->rx_packets; rxbytes = p->rx_bytes; rxmulticast = p->rx_multicast; + txpackets = p->tx_packets; + txbytes = p->tx_bytes; } while (u64_stats_fetch_retry_bh(&p->syncp, start)); - accum.rx_packets += rxpackets; - accum.rx_bytes += rxbytes; - accum.rx_multicast += rxmulticast; - /* rx_errors is ulong, not protected by syncp */ - accum.rx_errors += p->rx_errors; + + stats->rx_packets += rxpackets; + stats->rx_bytes += rxbytes; + stats->multicast += rxmulticast; + stats->tx_packets += txpackets; + stats->tx_bytes += txbytes; + /* rx_errors & tx_dropped are u32 */ + rx_errors += p->rx_errors; + tx_dropped += p->tx_dropped; } - stats->rx_packets = accum.rx_packets; - stats->rx_bytes = accum.rx_bytes; - stats->rx_errors = accum.rx_errors; - stats->multicast = accum.rx_multicast; + stats->rx_errors = rx_errors; + stats->tx_dropped = tx_dropped; } return stats; } diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index ddc105734af7..be9a5c19a775 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c @@ -101,25 +101,6 @@ static int vlan_changelink(struct net_device *dev, return 0; } -static int vlan_get_tx_queues(struct net *net, - struct nlattr *tb[], - unsigned int *num_tx_queues, - unsigned int *real_num_tx_queues) -{ - struct net_device *real_dev; - - if (!tb[IFLA_LINK]) - return -EINVAL; - - real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); - if (!real_dev) - return -ENODEV; - - *num_tx_queues = real_dev->num_tx_queues; - *real_num_tx_queues = real_dev->real_num_tx_queues; - return 0; -} - static int vlan_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -237,7 +218,6 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { .maxtype = IFLA_VLAN_MAX, .policy = vlan_policy, .priv_size = sizeof(struct vlan_dev_info), - .get_tx_queues = vlan_get_tx_queues, .setup = vlan_setup, .validate = vlan_validate, .newlink = vlan_newlink, -- cgit v1.2.3-59-g8ed1b From 213b15ca818adf7766cd7162c2159a6ecdd3bab8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 11 Nov 2010 09:42:45 +0000 Subject: vlan: remove ndo_select_queue() logic Now vlan are lockless, we dont need special ndo_select_queue() logic. dev_pick_tx() will do the multiqueue stuff on the real device transmit. Suggested-by: Jesse Gross Signed-off-by: Eric Dumazet Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 2fa3f4a3f60f..be737539f34d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -346,14 +346,6 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, return ret; } -static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) -{ - struct net_device *rdev = vlan_dev_info(dev)->real_dev; - const struct net_device_ops *ops = rdev->netdev_ops; - - return ops->ndo_select_queue(rdev, skb); -} - static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) { /* TODO: gotta make sure the underlying layer can handle it, @@ -682,7 +674,7 @@ static const struct header_ops vlan_header_ops = { .parse = eth_header_parse, }; -static const struct net_device_ops vlan_netdev_ops, vlan_netdev_ops_sq; +static const struct net_device_ops vlan_netdev_ops; static int vlan_dev_init(struct net_device *dev) { @@ -723,10 +715,7 @@ static int vlan_dev_init(struct net_device *dev) dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; } - if (real_dev->netdev_ops->ndo_select_queue) - dev->netdev_ops = &vlan_netdev_ops_sq; - else - dev->netdev_ops = &vlan_netdev_ops; + dev->netdev_ops = &vlan_netdev_ops; if (is_vlan_dev(real_dev)) subclass = 1; @@ -872,31 +861,6 @@ static const struct net_device_ops vlan_netdev_ops = { #endif }; -static const struct net_device_ops vlan_netdev_ops_sq = { - .ndo_select_queue = vlan_dev_select_queue, - .ndo_change_mtu = vlan_dev_change_mtu, - .ndo_init = vlan_dev_init, - .ndo_uninit = vlan_dev_uninit, - .ndo_open = vlan_dev_open, - .ndo_stop = vlan_dev_stop, - .ndo_start_xmit = vlan_dev_hard_start_xmit, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = vlan_dev_set_mac_address, - .ndo_set_rx_mode = vlan_dev_set_rx_mode, - .ndo_set_multicast_list = vlan_dev_set_rx_mode, - .ndo_change_rx_flags = vlan_dev_change_rx_flags, - .ndo_do_ioctl = vlan_dev_ioctl, - .ndo_neigh_setup = vlan_dev_neigh_setup, - .ndo_get_stats64 = vlan_dev_get_stats64, -#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) - .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, - .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, - .ndo_fcoe_enable = vlan_dev_fcoe_enable, - .ndo_fcoe_disable = vlan_dev_fcoe_disable, - .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, -#endif -}; - void vlan_setup(struct net_device *dev) { ether_setup(dev); -- cgit v1.2.3-59-g8ed1b From c31504dc0d1dc853dcee509d9999169a9097a717 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 15 Nov 2010 19:58:26 +0000 Subject: udp: use atomic_inc_not_zero_hint UDP sockets refcount is usually 2, unless an incoming frame is going to be queued in receive or backlog queue. Using atomic_inc_not_zero_hint() permits to reduce latency, because processor issues less memory transactions. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 2 +- net/ipv4/udp.c | 4 ++-- net/ipv6/udp.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index a6338d039857..eb0c1f504678 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -57,7 +57,7 @@ #include #include -#include +#include #include #include diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e0a3a582a59..491ecd3f7a01 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -430,7 +430,7 @@ begin: if (result) { exact_match: - if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) + if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) result = NULL; else if (unlikely(compute_score2(result, net, saddr, sport, daddr, hnum, dif) < badness)) { @@ -500,7 +500,7 @@ begin: goto begin; if (result) { - if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) + if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) result = NULL; else if (unlikely(compute_score(result, net, saddr, hnum, sport, daddr, dport, dif) < badness)) { diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 91def93bec85..b541a4e009fb 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -227,7 +227,7 @@ begin: if (result) { exact_match: - if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) + if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) result = NULL; else if (unlikely(compute_score2(result, net, saddr, sport, daddr, hnum, dif) < badness)) { @@ -294,7 +294,7 @@ begin: goto begin; if (result) { - if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) + if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) result = NULL; else if (unlikely(compute_score(result, net, hnum, saddr, sport, daddr, dport, dif) < badness)) { -- cgit v1.2.3-59-g8ed1b From b178bb3dfc30d9555bdd2401e95af98e23e83e10 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Nov 2010 05:56:04 +0000 Subject: net: reorder struct sock fields Right now, fields in struct sock are not optimally ordered, because each path (RX softirq, TX completion, RX user, TX user) has to touch fields that are contained in many different cache lines. The really critical thing is to shrink number of cache lines that are used at RX softirq time : CPU handling softirqs for a device can receive many frames per second for many sockets. If load is too big, we can drop frames at NIC level. RPS or multiqueue cards can help, but better reduce latency if possible. This patch starts with UDP protocol, then additional patches will try to reduce latencies of other ones as well. At RX softirq time, fields of interest for UDP protocol are : (not counting ones in inet struct for the lookup) Read/Written: sk_refcnt (atomic increment/decrement) sk_rmem_alloc & sk_backlog.len (to check if there is room in queues) sk_receive_queue sk_backlog (if socket locked by user program) sk_rxhash sk_forward_alloc sk_drops Read only: sk_rcvbuf (sk_rcvqueues_full()) sk_filter sk_wq sk_policy[0] sk_flags Additional notes : - sk_backlog has one hole on 64bit arches. We can fill it to save 8 bytes. - sk_backlog is used only if RX sofirq handler finds the socket while locked by user. - sk_rxhash is written only once per flow. - sk_drops is written only if queues are full Final layout : [1] One section grouping all read/write fields, but placing rxhash and sk_backlog at the end of this section. [2] One section grouping all read fields in RX handler (sk_filter, sk_rcv_buf, sk_wq) [3] Section used by other paths I'll post a patch on its own to put sk_refcnt at the end of struct sock_common so that it shares same cache line than section [1] New offsets on 64bit arch : sizeof(struct sock)=0x268 offsetof(struct sock, sk_refcnt) =0x10 offsetof(struct sock, sk_lock) =0x48 offsetof(struct sock, sk_receive_queue)=0x68 offsetof(struct sock, sk_backlog)=0x80 offsetof(struct sock, sk_rmem_alloc)=0x80 offsetof(struct sock, sk_forward_alloc)=0x98 offsetof(struct sock, sk_rxhash)=0x9c offsetof(struct sock, sk_rcvbuf)=0xa4 offsetof(struct sock, sk_drops) =0xa0 offsetof(struct sock, sk_filter)=0xa8 offsetof(struct sock, sk_wq)=0xb0 offsetof(struct sock, sk_policy)=0xd0 offsetof(struct sock, sk_flags) =0xe0 Instead of : sizeof(struct sock)=0x270 offsetof(struct sock, sk_refcnt) =0x10 offsetof(struct sock, sk_lock) =0x50 offsetof(struct sock, sk_receive_queue)=0xc0 offsetof(struct sock, sk_backlog)=0x70 offsetof(struct sock, sk_rmem_alloc)=0xac offsetof(struct sock, sk_forward_alloc)=0x10c offsetof(struct sock, sk_rxhash)=0x128 offsetof(struct sock, sk_rcvbuf)=0x4c offsetof(struct sock, sk_drops) =0x16c offsetof(struct sock, sk_filter)=0x198 offsetof(struct sock, sk_wq)=0x88 offsetof(struct sock, sk_policy)=0x98 offsetof(struct sock, sk_flags) =0x130 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 55 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index eb0c1f504678..5557dfb3dd68 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -241,59 +241,67 @@ struct sock { #define sk_bind_node __sk_common.skc_bind_node #define sk_prot __sk_common.skc_prot #define sk_net __sk_common.skc_net - kmemcheck_bitfield_begin(flags); - unsigned int sk_shutdown : 2, - sk_no_check : 2, - sk_userlocks : 4, - sk_protocol : 8, - sk_type : 16; - kmemcheck_bitfield_end(flags); - int sk_rcvbuf; socket_lock_t sk_lock; + struct sk_buff_head sk_receive_queue; /* * The backlog queue is special, it is always used with * the per-socket spinlock held and requires low latency * access. Therefore we special case it's implementation. + * Note : rmem_alloc is in this structure to fill a hole + * on 64bit arches, not because its logically part of + * backlog. */ struct { - struct sk_buff *head; - struct sk_buff *tail; - int len; + atomic_t rmem_alloc; + int len; + struct sk_buff *head; + struct sk_buff *tail; } sk_backlog; +#define sk_rmem_alloc sk_backlog.rmem_alloc + int sk_forward_alloc; +#ifdef CONFIG_RPS + __u32 sk_rxhash; +#endif + atomic_t sk_drops; + int sk_rcvbuf; + + struct sk_filter __rcu *sk_filter; struct socket_wq *sk_wq; - struct dst_entry *sk_dst_cache; + +#ifdef CONFIG_NET_DMA + struct sk_buff_head sk_async_wait_queue; +#endif + #ifdef CONFIG_XFRM struct xfrm_policy *sk_policy[2]; #endif + unsigned long sk_flags; + struct dst_entry *sk_dst_cache; spinlock_t sk_dst_lock; - atomic_t sk_rmem_alloc; atomic_t sk_wmem_alloc; atomic_t sk_omem_alloc; int sk_sndbuf; - struct sk_buff_head sk_receive_queue; struct sk_buff_head sk_write_queue; -#ifdef CONFIG_NET_DMA - struct sk_buff_head sk_async_wait_queue; -#endif + kmemcheck_bitfield_begin(flags); + unsigned int sk_shutdown : 2, + sk_no_check : 2, + sk_userlocks : 4, + sk_protocol : 8, + sk_type : 16; + kmemcheck_bitfield_end(flags); int sk_wmem_queued; - int sk_forward_alloc; gfp_t sk_allocation; int sk_route_caps; int sk_route_nocaps; int sk_gso_type; unsigned int sk_gso_max_size; int sk_rcvlowat; -#ifdef CONFIG_RPS - __u32 sk_rxhash; -#endif - unsigned long sk_flags; unsigned long sk_lingertime; struct sk_buff_head sk_error_queue; struct proto *sk_prot_creator; rwlock_t sk_callback_lock; int sk_err, sk_err_soft; - atomic_t sk_drops; unsigned short sk_ack_backlog; unsigned short sk_max_ack_backlog; __u32 sk_priority; @@ -301,7 +309,6 @@ struct sock { const struct cred *sk_peer_cred; long sk_rcvtimeo; long sk_sndtimeo; - struct sk_filter __rcu *sk_filter; void *sk_protinfo; struct timer_list sk_timer; ktime_t sk_stamp; -- cgit v1.2.3-59-g8ed1b From 9d1e5e40d6cac4bf7008e04c202d71918455ca11 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 3 Nov 2010 05:56:38 +0000 Subject: mpc52xx: cleanup locking commit 1e4e0767ecb1 (Fix locking on fec_mpc52xx driver) assumed IRQ are enabled when an IRQ handler is called. It is not the case anymore (IRQF_DISABLED is deprecated), so we can use regular spin_lock(), no need for spin_lock_irqsave(). Signed-off-by: Eric Dumazet Tested-by: Jean-Michel Hautbois Cc: Asier Llano Cc: Grant Likely Signed-off-by: David S. Miller --- drivers/net/fec_mpc52xx.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index e9f5d030bc26..50c1213f61fe 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -366,9 +366,8 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct mpc52xx_fec_priv *priv = netdev_priv(dev); - unsigned long flags; - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); while (bcom_buffer_done(priv->tx_dmatsk)) { struct sk_buff *skb; struct bcom_fec_bd *bd; @@ -379,7 +378,7 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) dev_kfree_skb_irq(skb); } - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); netif_wake_queue(dev); @@ -395,9 +394,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) struct bcom_fec_bd *bd; u32 status, physaddr; int length; - unsigned long flags; - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); while (bcom_buffer_done(priv->rx_dmatsk)) { @@ -429,7 +427,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) /* Process the received skb - Drop the spin lock while * calling into the network stack */ - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); dma_unmap_single(dev->dev.parent, physaddr, rskb->len, DMA_FROM_DEVICE); @@ -438,10 +436,10 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) rskb->protocol = eth_type_trans(rskb, dev); netif_rx(rskb); - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); } - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); return IRQ_HANDLED; } @@ -452,7 +450,6 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id) struct mpc52xx_fec_priv *priv = netdev_priv(dev); struct mpc52xx_fec __iomem *fec = priv->fec; u32 ievent; - unsigned long flags; ievent = in_be32(&fec->ievent); @@ -470,9 +467,9 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id) if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR)) dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n"); - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); mpc52xx_fec_reset(dev); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); return IRQ_HANDLED; } -- cgit v1.2.3-59-g8ed1b From cf43298864fdfd687202db8c736473522bfceb98 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sun, 31 Oct 2010 13:40:12 +0000 Subject: libertas: don't block usb8388 suspend if no wakeup conditions are set This hunk added by commit 66fceb69b72f seems erroneous. We don't want to prevent suspend of the whole system if no wakeup params are set. In the case of the usb8388 we do want to keep the card powered up even if there are no wakeup params. This is because it will continue acting as a mesh node. If the mesh is disabled, it would indeed make more sense to power down the card during suspend, as the equivalent hunk does for the SD interface. But that's a separate task; for now just restore the previous behaviour. Signed-off-by: Daniel Drake Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_usb.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index efaf85032208..35931cf4d6db 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -1090,12 +1090,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) if (priv->psstate != PS_STATE_FULL_POWER) return -1; - if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { - lbs_pr_info("Suspend attempt without " - "configuring wake params!\n"); - return -ENOSYS; - } - ret = lbs_suspend(priv); if (ret) goto out; -- cgit v1.2.3-59-g8ed1b From ae63a33ec9b598b3454cf0d29077fa17b616c42a Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Sun, 31 Oct 2010 13:40:33 +0000 Subject: libertas: EHS_REMOVE_WAKEUP is not always supported Certain firmware versions, particularly the 8388 found on the XO-1, do not support the EHS_REMOVE_WAKEUP command that is used to disable WOL. Sending this command to the card will return a failure that would get propagated up the stack and cause suspend to fail. Instead, fall back to an all-zero wakeup mask. This fixes http://dev.laptop.org/ticket/9967 Signed-off-by: Deepak Saxena Signed-off-by: Daniel Drake [includes fixups by Paul Fox] Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 8 ++++++++ drivers/net/wireless/libertas/dev.h | 1 + drivers/net/wireless/libertas/if_usb.c | 7 +++++++ drivers/net/wireless/libertas/main.c | 3 ++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 70745928f3f8..78c4da150a74 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, struct cmd_ds_host_sleep cmd_config; int ret; + /* + * Certain firmware versions do not support EHS_REMOVE_WAKEUP command + * and the card will return a failure. Since we need to be + * able to reset the mask, in those cases we set a 0 mask instead. + */ + if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported) + criteria = 0; + cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config)); cmd_config.criteria = cpu_to_le32(criteria); cmd_config.gpio = priv->wol_gpio; diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index f062ed583901..f5a9851fc7ee 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -137,6 +137,7 @@ struct lbs_private { uint32_t wol_criteria; uint8_t wol_gpio; uint8_t wol_gap; + bool ehs_remove_supported; /* Transmitting */ int tx_pending_len; /* -1 while building packet */ diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 35931cf4d6db..6524c70363d9 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -345,6 +345,13 @@ static int if_usb_probe(struct usb_interface *intf, if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2)) lbs_pr_err("cannot register lbs_flash_boot2 attribute\n"); + /* + * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware. + */ + priv->wol_criteria = EHS_REMOVE_WAKEUP; + if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL)) + priv->ehs_remove_supported = false; + return 0; err_start_card: diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 47ce5a6ba120..6d7af91d52c2 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -844,9 +844,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) priv->work_thread = create_singlethread_workqueue("lbs_worker"); INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); - priv->wol_criteria = 0xffffffff; + priv->wol_criteria = EHS_REMOVE_WAKEUP; priv->wol_gpio = 0xff; priv->wol_gap = 20; + priv->ehs_remove_supported = true; goto done; -- cgit v1.2.3-59-g8ed1b From a1fe24b0fd8bf16b4e551ae3fb785bfc574b9ffb Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:47 -0800 Subject: mwl8k: revert unnecessary modification of tx descriptor This reverts change 783391c443728febc669e40597193308460e7b4f. The stabilized AP v1 firmware uses the same tx descriptor as the STA firmware. Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 1bbcd7c1d02a..f152a25be59f 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1125,12 +1125,10 @@ struct mwl8k_tx_desc { __le32 reserved; __le16 rate_info; __u8 peer_id; - __u8 xmitcontrol; + __u8 tx_frag_cnt; } __packed; #define MWL8K_TX_DESCS 128 -#define MWL8K_XMITCONTROL_NON_AMPDU 0x04 - static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) { @@ -1450,9 +1448,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; else tx->peer_id = 0; - - if (priv->ap_fw) - tx->xmitcontrol = MWL8K_XMITCONTROL_NON_AMPDU; wmb(); tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); -- cgit v1.2.3-59-g8ed1b From 41fdf0974d9eb81215cb578211a6d8f8a022a9eb Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Fri, 12 Nov 2010 17:23:48 -0800 Subject: mwl8k: rf_tx_power cmd not supported by AP firmware APIv1 APIv1 AP firmware does not support the RF_TX_POWER command. It supports the similar TX_POWER command. Signed-off-by: Pradeep Nemavat Signed-off-by: Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 78 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index f152a25be59f..cfda87a595e3 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -285,8 +285,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { }; /* Set or get info from Firmware */ -#define MWL8K_CMD_SET 0x0001 #define MWL8K_CMD_GET 0x0000 +#define MWL8K_CMD_SET 0x0001 +#define MWL8K_CMD_SET_LIST 0x0002 /* Firmware command codes */ #define MWL8K_CMD_CODE_DNLD 0x0001 @@ -296,6 +297,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_GET_STAT 0x0014 #define MWL8K_CMD_RADIO_CONTROL 0x001c #define MWL8K_CMD_RF_TX_POWER 0x001e +#define MWL8K_CMD_TX_POWER 0x001f #define MWL8K_CMD_RF_ANTENNA 0x0020 #define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */ #define MWL8K_CMD_SET_PRE_SCAN 0x0107 @@ -333,6 +335,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) MWL8K_CMDNAME(GET_STAT); MWL8K_CMDNAME(RADIO_CONTROL); MWL8K_CMDNAME(RF_TX_POWER); + MWL8K_CMDNAME(TX_POWER); MWL8K_CMDNAME(RF_ANTENNA); MWL8K_CMDNAME(SET_BEACON); MWL8K_CMDNAME(SET_PRE_SCAN); @@ -2084,7 +2087,7 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) /* * CMD_RF_TX_POWER. */ -#define MWL8K_TX_POWER_LEVEL_TOTAL 8 +#define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8 struct mwl8k_cmd_rf_tx_power { struct mwl8k_cmd_pkt header; @@ -2092,7 +2095,7 @@ struct mwl8k_cmd_rf_tx_power { __le16 support_level; __le16 current_level; __le16 reserved; - __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; + __le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL]; } __packed; static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) @@ -2115,6 +2118,65 @@ static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) return rc; } +/* + * CMD_TX_POWER. + */ +#define MWL8K_TX_POWER_LEVEL_TOTAL 12 + +struct mwl8k_cmd_tx_power { + struct mwl8k_cmd_pkt header; + __le16 action; + __le16 band; + __le16 channel; + __le16 bw; + __le16 sub_ch; + __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; +} __attribute__((packed)); + +static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, + struct ieee80211_conf *conf, + unsigned short pwr) +{ + struct ieee80211_channel *channel = conf->channel; + struct mwl8k_cmd_tx_power *cmd; + int rc; + int i; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST); + + if (channel->band == IEEE80211_BAND_2GHZ) + cmd->band = cpu_to_le16(0x1); + else if (channel->band == IEEE80211_BAND_5GHZ) + cmd->band = cpu_to_le16(0x4); + + cmd->channel = channel->hw_value; + + if (conf->channel_type == NL80211_CHAN_NO_HT || + conf->channel_type == NL80211_CHAN_HT20) { + cmd->bw = cpu_to_le16(0x2); + } else { + cmd->bw = cpu_to_le16(0x4); + if (conf->channel_type == NL80211_CHAN_HT40MINUS) + cmd->sub_ch = cpu_to_le16(0x3); + else if (conf->channel_type == NL80211_CHAN_HT40PLUS) + cmd->sub_ch = cpu_to_le16(0x1); + } + + for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++) + cmd->power_level_list[i] = cpu_to_le16(pwr); + + rc = mwl8k_post_cmd(hw, &cmd->header); + kfree(cmd); + + return rc; +} + /* * CMD_RF_ANTENNA. */ @@ -3377,15 +3439,19 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) if (conf->power_level > 18) conf->power_level = 18; - rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); - if (rc) - goto out; if (priv->ap_fw) { + rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); + if (rc) + goto out; + rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7); if (!rc) rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); } else { + rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); + if (rc) + goto out; rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7); } -- cgit v1.2.3-59-g8ed1b From 3cc7772c0a3cc193fa9873816168bd34d4f16837 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:49 -0800 Subject: mwl8k: factor out firmware loading and hw init code This is in preparation for supporting different fw images for different interface types, and for supporting asynchronous firmware loading. Based on a patch from Pradeep Nemavat and Yogesh Powar Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 345 +++++++++++++++++++++++++++---------------- 1 file changed, 214 insertions(+), 131 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index cfda87a595e3..7bd861586983 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -3942,73 +3942,10 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { }; MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); -static int __devinit mwl8k_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int mwl8k_init_firmware(struct ieee80211_hw *hw) { - static int printed_version = 0; - struct ieee80211_hw *hw; - struct mwl8k_priv *priv; + struct mwl8k_priv *priv = hw->priv; int rc; - int i; - - if (!printed_version) { - printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION); - printed_version = 1; - } - - - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_ERR "%s: Cannot enable new PCI device\n", - MWL8K_NAME); - return rc; - } - - rc = pci_request_regions(pdev, MWL8K_NAME); - if (rc) { - printk(KERN_ERR "%s: Cannot obtain PCI resources\n", - MWL8K_NAME); - goto err_disable_device; - } - - pci_set_master(pdev); - - - hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); - if (hw == NULL) { - printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); - rc = -ENOMEM; - goto err_free_reg; - } - - SET_IEEE80211_DEV(hw, &pdev->dev); - pci_set_drvdata(pdev, hw); - - priv = hw->priv; - priv->hw = hw; - priv->pdev = pdev; - priv->device_info = &mwl8k_info_tbl[id->driver_data]; - - - priv->sram = pci_iomap(pdev, 0, 0x10000); - if (priv->sram == NULL) { - wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); - goto err_iounmap; - } - - /* - * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. - * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. - */ - priv->regs = pci_iomap(pdev, 1, 0x10000); - if (priv->regs == NULL) { - priv->regs = pci_iomap(pdev, 2, 0x10000); - if (priv->regs == NULL) { - wiphy_err(hw->wiphy, "Cannot map device registers\n"); - goto err_iounmap; - } - } - /* Reset firmware and hardware */ mwl8k_hw_reset(priv); @@ -4017,19 +3954,26 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = mwl8k_request_firmware(priv); if (rc) { wiphy_err(hw->wiphy, "Firmware files not found\n"); - goto err_stop_firmware; + return rc; } /* Load firmware into hardware */ rc = mwl8k_load_firmware(hw); - if (rc) { + if (rc) wiphy_err(hw->wiphy, "Cannot start firmware\n"); - goto err_stop_firmware; - } /* Reclaim memory once firmware is successfully loaded */ mwl8k_release_firmware(priv); + return rc; +} + +/* initialize hw after successfully loading a firmware image */ +static int mwl8k_probe_hw(struct ieee80211_hw *hw) +{ + struct mwl8k_priv *priv = hw->priv; + int rc = 0; + int i; if (priv->ap_fw) { priv->rxd_ops = priv->device_info->ap_rxd_ops; @@ -4046,58 +3990,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, priv->wmm_enabled = false; priv->pending_tx_pkts = 0; - - /* - * Extra headroom is the size of the required DMA header - * minus the size of the smallest 802.11 frame (CTS frame). - */ - hw->extra_tx_headroom = - sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); - - hw->channel_change_time = 10; - - hw->queues = MWL8K_TX_QUEUES; - - /* Set rssi values to dBm */ - hw->flags |= IEEE80211_HW_SIGNAL_DBM; - hw->vif_data_size = sizeof(struct mwl8k_vif); - hw->sta_data_size = sizeof(struct mwl8k_sta); - - priv->macids_used = 0; - INIT_LIST_HEAD(&priv->vif_list); - - /* Set default radio state and preamble */ - priv->radio_on = 0; - priv->radio_short_preamble = 0; - - /* Finalize join worker */ - INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); - - /* TX reclaim and RX tasklets. */ - tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); - tasklet_disable(&priv->poll_tx_task); - tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw); - tasklet_disable(&priv->poll_rx_task); - - /* Power management cookie */ - priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); - if (priv->cookie == NULL) - goto err_stop_firmware; - rc = mwl8k_rxq_init(hw, 0); if (rc) - goto err_free_cookie; + goto err_stop_firmware; rxq_refill(hw, 0, INT_MAX); - mutex_init(&priv->fw_mutex); - priv->fw_mutex_owner = NULL; - priv->fw_mutex_depth = 0; - priv->hostcmd_wait = NULL; - - spin_lock_init(&priv->tx_lock); - - priv->tx_wait = NULL; - for (i = 0; i < MWL8K_TX_QUEUES; i++) { rc = mwl8k_txq_init(hw, i); if (rc) @@ -4137,13 +4034,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, goto err_free_irq; } - hw->wiphy->interface_modes = 0; - if (priv->ap_macids_supported) - hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); - if (priv->sta_macids_supported) - hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); - - /* Turn radio off */ rc = mwl8k_cmd_radio_disable(hw); if (rc) { @@ -4162,12 +4052,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); free_irq(priv->pdev->irq, hw); - rc = ieee80211_register_hw(hw); - if (rc) { - wiphy_err(hw->wiphy, "Cannot register device\n"); - goto err_free_queues; - } - wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", priv->device_info->part_name, priv->hw_rev, hw->wiphy->perm_addr, @@ -4186,14 +4070,213 @@ err_free_queues: mwl8k_txq_deinit(hw, i); mwl8k_rxq_deinit(hw, 0); +err_stop_firmware: + mwl8k_hw_reset(priv); + + return rc; +} + +/* + * invoke mwl8k_reload_firmware to change the firmware image after the device + * has already been registered + */ +static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) +{ + int i, rc = 0; + struct mwl8k_priv *priv = hw->priv; + + mwl8k_stop(hw); + mwl8k_rxq_deinit(hw, 0); + + for (i = 0; i < MWL8K_TX_QUEUES; i++) + mwl8k_txq_deinit(hw, i); + + rc = mwl8k_init_firmware(hw, fw_image); + if (rc) + goto fail; + + rc = mwl8k_probe_hw(hw); + if (rc) + goto fail; + + rc = mwl8k_start(hw); + if (rc) + goto fail; + + rc = mwl8k_config(hw, ~0); + if (rc) + goto fail; + + for (i = 0; i < MWL8K_TX_QUEUES; i++) { + rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]); + if (rc) + goto fail; + } + + return rc; + +fail: + printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n"); + return rc; +} + +static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) +{ + struct ieee80211_hw *hw = priv->hw; + int i, rc; + + /* + * Extra headroom is the size of the required DMA header + * minus the size of the smallest 802.11 frame (CTS frame). + */ + hw->extra_tx_headroom = + sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); + + hw->channel_change_time = 10; + + hw->queues = MWL8K_TX_QUEUES; + + /* Set rssi values to dBm */ + hw->flags |= IEEE80211_HW_SIGNAL_DBM; + hw->vif_data_size = sizeof(struct mwl8k_vif); + hw->sta_data_size = sizeof(struct mwl8k_sta); + + priv->macids_used = 0; + INIT_LIST_HEAD(&priv->vif_list); + + /* Set default radio state and preamble */ + priv->radio_on = 0; + priv->radio_short_preamble = 0; + + /* Finalize join worker */ + INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); + + /* TX reclaim and RX tasklets. */ + tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); + tasklet_disable(&priv->poll_tx_task); + tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw); + tasklet_disable(&priv->poll_rx_task); + + /* Power management cookie */ + priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); + if (priv->cookie == NULL) + return -ENOMEM; + + mutex_init(&priv->fw_mutex); + priv->fw_mutex_owner = NULL; + priv->fw_mutex_depth = 0; + priv->hostcmd_wait = NULL; + + spin_lock_init(&priv->tx_lock); + + priv->tx_wait = NULL; + + rc = mwl8k_probe_hw(hw); + if (rc) + goto err_free_cookie; + + hw->wiphy->interface_modes = 0; + if (priv->ap_macids_supported || priv->device_info->fw_image_ap) + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); + if (priv->sta_macids_supported || priv->device_info->fw_image_sta) + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); + + rc = ieee80211_register_hw(hw); + if (rc) { + wiphy_err(hw->wiphy, "Cannot register device\n"); + goto err_unprobe_hw; + } + + return 0; + +err_unprobe_hw: + for (i = 0; i < MWL8K_TX_QUEUES; i++) + mwl8k_txq_deinit(hw, i); + mwl8k_rxq_deinit(hw, 0); + err_free_cookie: if (priv->cookie != NULL) pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma); + return rc; +} +static int __devinit mwl8k_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + static int printed_version; + struct ieee80211_hw *hw; + struct mwl8k_priv *priv; + int rc; + + if (!printed_version) { + printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION); + printed_version = 1; + } + + + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR "%s: Cannot enable new PCI device\n", + MWL8K_NAME); + return rc; + } + + rc = pci_request_regions(pdev, MWL8K_NAME); + if (rc) { + printk(KERN_ERR "%s: Cannot obtain PCI resources\n", + MWL8K_NAME); + goto err_disable_device; + } + + pci_set_master(pdev); + + + hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); + if (hw == NULL) { + printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); + rc = -ENOMEM; + goto err_free_reg; + } + + SET_IEEE80211_DEV(hw, &pdev->dev); + pci_set_drvdata(pdev, hw); + + priv = hw->priv; + priv->hw = hw; + priv->pdev = pdev; + priv->device_info = &mwl8k_info_tbl[id->driver_data]; + + + priv->sram = pci_iomap(pdev, 0, 0x10000); + if (priv->sram == NULL) { + wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); + goto err_iounmap; + } + + /* + * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. + * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. + */ + priv->regs = pci_iomap(pdev, 1, 0x10000); + if (priv->regs == NULL) { + priv->regs = pci_iomap(pdev, 2, 0x10000); + if (priv->regs == NULL) { + wiphy_err(hw->wiphy, "Cannot map device registers\n"); + goto err_iounmap; + } + } + + rc = mwl8k_init_firmware(hw); + if (rc) + goto err_stop_firmware; + + rc = mwl8k_firmware_load_success(priv); + if (!rc) + return rc; + err_stop_firmware: mwl8k_hw_reset(priv); - mwl8k_release_firmware(priv); err_iounmap: if (priv->regs != NULL) -- cgit v1.2.3-59-g8ed1b From 0863ade8d6bde1d151f75720d999ff27f9fe3533 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:50 -0800 Subject: mwl8k: choose proper firmware image as directed by user The mwl8k can operate in AP or STA mode, depending on the firmware image that is loaded. By default, STA firmware is loaded. Allow the user to override this default mode at module load time. This saves an unnecessary firmware reload for users only interested in AP mode. Also, the firmware image can be swapped to meet the user's add_interface request. For example, suppose the STA firmware is loaded, no STA interface has been added, and the user adds an AP interface. In this case, the AP firmware will be loaded to meet the request. Based on contributions from Pradeep Nemavat , Yogesh Powar , and Lennert Buytenhek . Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 78 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 7bd861586983..cbf72714e74d 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -29,6 +29,12 @@ #define MWL8K_NAME KBUILD_MODNAME #define MWL8K_VERSION "0.12" +/* Module parameters */ +static unsigned ap_mode_default; +module_param(ap_mode_default, bool, 0); +MODULE_PARM_DESC(ap_mode_default, + "Set to 1 to make ap mode the default instead of sta mode"); + /* Register definitions */ #define MWL8K_HIU_GEN_PTR 0x00000c10 #define MWL8K_MODE_STA 0x0000005a @@ -92,7 +98,8 @@ struct rxd_ops { struct mwl8k_device_info { char *part_name; char *helper_image; - char *fw_image; + char *fw_image_sta; + char *fw_image_ap; struct rxd_ops *ap_rxd_ops; }; @@ -210,6 +217,12 @@ struct mwl8k_priv { /* Most recently reported noise in dBm */ s8 noise; + + /* + * preserve the queue configurations so they can be restored if/when + * the firmware image is swapped. + */ + struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES]; }; /* Per interface specific private data */ @@ -401,7 +414,7 @@ static int mwl8k_request_fw(struct mwl8k_priv *priv, fname, &priv->pdev->dev); } -static int mwl8k_request_firmware(struct mwl8k_priv *priv) +static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image) { struct mwl8k_device_info *di = priv->device_info; int rc; @@ -416,10 +429,10 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv) } } - rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode); + rc = mwl8k_request_fw(priv, fw_image, &priv->fw_ucode); if (rc) { printk(KERN_ERR "%s: Error requesting firmware file %s\n", - pci_name(priv->pdev), di->fw_image); + pci_name(priv->pdev), fw_image); mwl8k_release_fw(&priv->fw_helper); return rc; } @@ -3345,13 +3358,16 @@ static void mwl8k_stop(struct ieee80211_hw *hw) mwl8k_txq_reclaim(hw, i, INT_MAX, 1); } +static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image); + static int mwl8k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mwl8k_priv *priv = hw->priv; struct mwl8k_vif *mwl8k_vif; u32 macids_supported; - int macid; + int macid, rc; + struct mwl8k_device_info *di; /* * Reject interface creation if sniffer mode is active, as @@ -3364,12 +3380,28 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, return -EINVAL; } - + di = priv->device_info; switch (vif->type) { case NL80211_IFTYPE_AP: + if (!priv->ap_fw && di->fw_image_ap) { + /* we must load the ap fw to meet this request */ + if (!list_empty(&priv->vif_list)) + return -EBUSY; + rc = mwl8k_reload_firmware(hw, di->fw_image_ap); + if (rc) + return rc; + } macids_supported = priv->ap_macids_supported; break; case NL80211_IFTYPE_STATION: + if (priv->ap_fw && di->fw_image_sta) { + /* we must load the sta fw to meet this request */ + if (!list_empty(&priv->vif_list)) + return -EBUSY; + rc = mwl8k_reload_firmware(hw, di->fw_image_sta); + if (rc) + return rc; + } macids_supported = priv->sta_macids_supported; break; default: @@ -3805,6 +3837,9 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, rc = mwl8k_fw_lock(hw); if (!rc) { + BUG_ON(queue > MWL8K_TX_QUEUES - 1); + memcpy(&priv->wmm_params[queue], params, sizeof(*params)); + if (!priv->wmm_enabled) rc = mwl8k_cmd_set_wmm_mode(hw, 1); @@ -3908,17 +3943,18 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { [MWL8363] = { .part_name = "88w8363", .helper_image = "mwl8k/helper_8363.fw", - .fw_image = "mwl8k/fmimage_8363.fw", + .fw_image_sta = "mwl8k/fmimage_8363.fw", }, [MWL8687] = { .part_name = "88w8687", .helper_image = "mwl8k/helper_8687.fw", - .fw_image = "mwl8k/fmimage_8687.fw", + .fw_image_sta = "mwl8k/fmimage_8687.fw", }, [MWL8366] = { .part_name = "88w8366", .helper_image = "mwl8k/helper_8366.fw", - .fw_image = "mwl8k/fmimage_8366.fw", + .fw_image_sta = "mwl8k/fmimage_8366.fw", + .fw_image_ap = "mwl8k/fmimage_8366_ap-1.fw", .ap_rxd_ops = &rxd_8366_ap_ops, }, }; @@ -3929,6 +3965,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); MODULE_FIRMWARE("mwl8k/helper_8366.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); +MODULE_FIRMWARE("mwl8k/fmimage_8366_ap-1.fw"); static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, @@ -3942,7 +3979,7 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { }; MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); -static int mwl8k_init_firmware(struct ieee80211_hw *hw) +static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image) { struct mwl8k_priv *priv = hw->priv; int rc; @@ -3951,7 +3988,7 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw) mwl8k_hw_reset(priv); /* Ask userland hotplug daemon for the device firmware */ - rc = mwl8k_request_firmware(priv); + rc = mwl8k_request_firmware(priv, fw_image); if (rc) { wiphy_err(hw->wiphy, "Firmware files not found\n"); return rc; @@ -4207,6 +4244,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, static int printed_version; struct ieee80211_hw *hw; struct mwl8k_priv *priv; + struct mwl8k_device_info *di; int rc; if (!printed_version) { @@ -4267,7 +4305,23 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, } } - rc = mwl8k_init_firmware(hw); + /* + * Choose the initial fw image depending on user input and availability + * of images. + */ + di = priv->device_info; + if (ap_mode_default && di->fw_image_ap) + rc = mwl8k_init_firmware(hw, di->fw_image_ap); + else if (!ap_mode_default && di->fw_image_sta) + rc = mwl8k_init_firmware(hw, di->fw_image_sta); + else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { + printk(KERN_WARNING "AP fw is unavailable. Using STA fw."); + rc = mwl8k_init_firmware(hw, di->fw_image_sta); + } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { + printk(KERN_WARNING "STA fw is unavailable. Using AP fw."); + rc = mwl8k_init_firmware(hw, di->fw_image_ap); + } else + rc = mwl8k_init_firmware(hw, di->fw_image_sta); if (rc) goto err_stop_firmware; -- cgit v1.2.3-59-g8ed1b From 952a0e963fb02e50f4afbf502f7d468a8fe2b0fa Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:51 -0800 Subject: mwl8k: add API version checking for AP firmware The AP firmware specifies an API version in the GET_HW_SPEC command response. Currently, the driver only supports AP firmware for the 8366, and only supports API v1. In the future, if higher API version firmwares emerge (possibly for different chips), different ops can be selected based on the reported API version. Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index cbf72714e74d..e5b062c3bd56 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -101,6 +101,7 @@ struct mwl8k_device_info { char *fw_image_sta; char *fw_image_ap; struct rxd_ops *ap_rxd_ops; + u32 fw_api_ap; }; struct mwl8k_rx_queue { @@ -1827,6 +1828,7 @@ struct mwl8k_cmd_get_hw_spec_ap { __le32 wcbbase1; __le32 wcbbase2; __le32 wcbbase3; + __le32 fw_api_version; } __packed; static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) @@ -1834,6 +1836,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) struct mwl8k_priv *priv = hw->priv; struct mwl8k_cmd_get_hw_spec_ap *cmd; int rc; + u32 api_version; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (cmd == NULL) @@ -1850,6 +1853,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) if (!rc) { int off; + api_version = le32_to_cpu(cmd->fw_api_version); + if (priv->device_info->fw_api_ap != api_version) { + printk(KERN_ERR "%s: Unsupported fw API version for %s." + " Expected %d got %d.\n", MWL8K_NAME, + priv->device_info->part_name, + priv->device_info->fw_api_ap, + api_version); + rc = -EINVAL; + goto done; + } SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); priv->fw_rev = le32_to_cpu(cmd->fw_rev); @@ -1877,6 +1890,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) iowrite32(priv->txq[3].txd_dma, priv->sram + off); } +done: kfree(cmd); return rc; } @@ -3939,6 +3953,10 @@ enum { MWL8366, }; +#define MWL8K_8366_AP_FW_API 1 +#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" +#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) + static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { [MWL8363] = { .part_name = "88w8363", @@ -3954,7 +3972,8 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { .part_name = "88w8366", .helper_image = "mwl8k/helper_8366.fw", .fw_image_sta = "mwl8k/fmimage_8366.fw", - .fw_image_ap = "mwl8k/fmimage_8366_ap-1.fw", + .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API), + .fw_api_ap = MWL8K_8366_AP_FW_API, .ap_rxd_ops = &rxd_8366_ap_ops, }, }; @@ -3965,7 +3984,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); MODULE_FIRMWARE("mwl8k/helper_8366.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); -MODULE_FIRMWARE("mwl8k/fmimage_8366_ap-1.fw"); +MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, -- cgit v1.2.3-59-g8ed1b From 99020471001dbbd6edf61f105368cb6667cc683d Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:52 -0800 Subject: mwl8k: make initial firmware load asynchronous Introduce a firmware loading state machine to manage the process of loading firmware asynchronously and completing initialization upon success. The state machine attempts to load the preferred firmware image. If that fails, and if an alternative firmware image is available, it will attempt to load that one. Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 207 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 178 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index e5b062c3bd56..081bb6c848d9 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -224,6 +224,12 @@ struct mwl8k_priv { * the firmware image is swapped. */ struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES]; + + /* async firmware loading state */ + unsigned fw_state; + char *fw_pref; + char *fw_alt; + struct completion firmware_loading_complete; }; /* Per interface specific private data */ @@ -403,34 +409,66 @@ static void mwl8k_release_firmware(struct mwl8k_priv *priv) mwl8k_release_fw(&priv->fw_helper); } +/* states for asynchronous f/w loading */ +static void mwl8k_fw_state_machine(const struct firmware *fw, void *context); +enum { + FW_STATE_INIT = 0, + FW_STATE_LOADING_PREF, + FW_STATE_LOADING_ALT, + FW_STATE_ERROR, +}; + /* Request fw image */ static int mwl8k_request_fw(struct mwl8k_priv *priv, - const char *fname, struct firmware **fw) + const char *fname, struct firmware **fw, + bool nowait) { /* release current image */ if (*fw != NULL) mwl8k_release_fw(fw); - return request_firmware((const struct firmware **)fw, - fname, &priv->pdev->dev); + if (nowait) + return request_firmware_nowait(THIS_MODULE, 1, fname, + &priv->pdev->dev, GFP_KERNEL, + priv, mwl8k_fw_state_machine); + else + return request_firmware((const struct firmware **)fw, + fname, &priv->pdev->dev); } -static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image) +static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image, + bool nowait) { struct mwl8k_device_info *di = priv->device_info; int rc; if (di->helper_image != NULL) { - rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper); - if (rc) { - printk(KERN_ERR "%s: Error requesting helper " - "firmware file %s\n", pci_name(priv->pdev), - di->helper_image); + if (nowait) + rc = mwl8k_request_fw(priv, di->helper_image, + &priv->fw_helper, true); + else + rc = mwl8k_request_fw(priv, di->helper_image, + &priv->fw_helper, false); + if (rc) + printk(KERN_ERR "%s: Error requesting helper fw %s\n", + pci_name(priv->pdev), di->helper_image); + + if (rc || nowait) return rc; - } } - rc = mwl8k_request_fw(priv, fw_image, &priv->fw_ucode); + if (nowait) { + /* + * if we get here, no helper image is needed. Skip the + * FW_STATE_INIT state. + */ + priv->fw_state = FW_STATE_LOADING_PREF; + rc = mwl8k_request_fw(priv, fw_image, + &priv->fw_ucode, + true); + } else + rc = mwl8k_request_fw(priv, fw_image, + &priv->fw_ucode, false); if (rc) { printk(KERN_ERR "%s: Error requesting firmware file %s\n", pci_name(priv->pdev), fw_image); @@ -3998,7 +4036,99 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { }; MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); -static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image) +static int mwl8k_request_alt_fw(struct mwl8k_priv *priv) +{ + int rc; + printk(KERN_ERR "%s: Error requesting preferred fw %s.\n" + "Trying alternative firmware %s\n", pci_name(priv->pdev), + priv->fw_pref, priv->fw_alt); + rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true); + if (rc) { + printk(KERN_ERR "%s: Error requesting alt fw %s\n", + pci_name(priv->pdev), priv->fw_alt); + return rc; + } + return 0; +} + +static int mwl8k_firmware_load_success(struct mwl8k_priv *priv); +static void mwl8k_fw_state_machine(const struct firmware *fw, void *context) +{ + struct mwl8k_priv *priv = context; + struct mwl8k_device_info *di = priv->device_info; + int rc; + + switch (priv->fw_state) { + case FW_STATE_INIT: + if (!fw) { + printk(KERN_ERR "%s: Error requesting helper fw %s\n", + pci_name(priv->pdev), di->helper_image); + goto fail; + } + priv->fw_helper = fw; + rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, + true); + if (rc && priv->fw_alt) { + rc = mwl8k_request_alt_fw(priv); + if (rc) + goto fail; + priv->fw_state = FW_STATE_LOADING_ALT; + } else if (rc) + goto fail; + else + priv->fw_state = FW_STATE_LOADING_PREF; + break; + + case FW_STATE_LOADING_PREF: + if (!fw) { + if (priv->fw_alt) { + rc = mwl8k_request_alt_fw(priv); + if (rc) + goto fail; + priv->fw_state = FW_STATE_LOADING_ALT; + } else + goto fail; + } else { + priv->fw_ucode = fw; + rc = mwl8k_firmware_load_success(priv); + if (rc) + goto fail; + else + complete(&priv->firmware_loading_complete); + } + break; + + case FW_STATE_LOADING_ALT: + if (!fw) { + printk(KERN_ERR "%s: Error requesting alt fw %s\n", + pci_name(priv->pdev), di->helper_image); + goto fail; + } + priv->fw_ucode = fw; + rc = mwl8k_firmware_load_success(priv); + if (rc) + goto fail; + else + complete(&priv->firmware_loading_complete); + break; + + default: + printk(KERN_ERR "%s: Unexpected firmware loading state: %d\n", + MWL8K_NAME, priv->fw_state); + BUG_ON(1); + } + + return; + +fail: + priv->fw_state = FW_STATE_ERROR; + complete(&priv->firmware_loading_complete); + device_release_driver(&priv->pdev->dev); + mwl8k_release_firmware(priv); +} + +static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image, + bool nowait) { struct mwl8k_priv *priv = hw->priv; int rc; @@ -4007,12 +4137,15 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image) mwl8k_hw_reset(priv); /* Ask userland hotplug daemon for the device firmware */ - rc = mwl8k_request_firmware(priv, fw_image); + rc = mwl8k_request_firmware(priv, fw_image, nowait); if (rc) { wiphy_err(hw->wiphy, "Firmware files not found\n"); return rc; } + if (nowait) + return rc; + /* Load firmware into hardware */ rc = mwl8k_load_firmware(hw); if (rc) @@ -4147,7 +4280,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) for (i = 0; i < MWL8K_TX_QUEUES; i++) mwl8k_txq_deinit(hw, i); - rc = mwl8k_init_firmware(hw, fw_image); + rc = mwl8k_init_firmware(hw, fw_image, false); if (rc) goto fail; @@ -4181,6 +4314,13 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) struct ieee80211_hw *hw = priv->hw; int i, rc; + rc = mwl8k_load_firmware(hw); + mwl8k_release_firmware(priv); + if (rc) { + wiphy_err(hw->wiphy, "Cannot start firmware\n"); + return rc; + } + /* * Extra headroom is the size of the required DMA header * minus the size of the smallest 802.11 frame (CTS frame). @@ -4325,28 +4465,29 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, } /* - * Choose the initial fw image depending on user input and availability - * of images. + * Choose the initial fw image depending on user input. If a second + * image is available, make it the alternative image that will be + * loaded if the first one fails. */ + init_completion(&priv->firmware_loading_complete); di = priv->device_info; - if (ap_mode_default && di->fw_image_ap) - rc = mwl8k_init_firmware(hw, di->fw_image_ap); - else if (!ap_mode_default && di->fw_image_sta) - rc = mwl8k_init_firmware(hw, di->fw_image_sta); - else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { + if (ap_mode_default && di->fw_image_ap) { + priv->fw_pref = di->fw_image_ap; + priv->fw_alt = di->fw_image_sta; + } else if (!ap_mode_default && di->fw_image_sta) { + priv->fw_pref = di->fw_image_sta; + priv->fw_alt = di->fw_image_ap; + } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { printk(KERN_WARNING "AP fw is unavailable. Using STA fw."); - rc = mwl8k_init_firmware(hw, di->fw_image_sta); + priv->fw_pref = di->fw_image_sta; } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { printk(KERN_WARNING "STA fw is unavailable. Using AP fw."); - rc = mwl8k_init_firmware(hw, di->fw_image_ap); - } else - rc = mwl8k_init_firmware(hw, di->fw_image_sta); + priv->fw_pref = di->fw_image_ap; + } + rc = mwl8k_init_firmware(hw, priv->fw_pref, true); if (rc) goto err_stop_firmware; - - rc = mwl8k_firmware_load_success(priv); - if (!rc) - return rc; + return rc; err_stop_firmware: mwl8k_hw_reset(priv); @@ -4385,6 +4526,13 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev) return; priv = hw->priv; + wait_for_completion(&priv->firmware_loading_complete); + + if (priv->fw_state == FW_STATE_ERROR) { + mwl8k_hw_reset(priv); + goto unmap; + } + ieee80211_stop_queues(hw); ieee80211_unregister_hw(hw); @@ -4407,6 +4555,7 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev) pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma); +unmap: pci_iounmap(pdev, priv->regs); pci_iounmap(pdev, priv->sram); pci_set_drvdata(pdev, NULL); -- cgit v1.2.3-59-g8ed1b From d1f9e41d1d739cd4393840d35e7554f4a439a4f1 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Fri, 12 Nov 2010 17:23:53 -0800 Subject: mwl8k: use const struct fw pointers throughout This eliminates compiler warnings by doing things how the firmware class expects. Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 081bb6c848d9..9ecf8407cb1b 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -144,8 +144,8 @@ struct mwl8k_priv { void __iomem *regs; /* firmware */ - struct firmware *fw_helper; - struct firmware *fw_ucode; + const struct firmware *fw_helper; + const struct firmware *fw_ucode; /* hardware/firmware parameters */ bool ap_fw; @@ -395,7 +395,7 @@ static void mwl8k_hw_reset(struct mwl8k_priv *priv) } /* Release fw image */ -static void mwl8k_release_fw(struct firmware **fw) +static void mwl8k_release_fw(const struct firmware **fw) { if (*fw == NULL) return; @@ -420,7 +420,7 @@ enum { /* Request fw image */ static int mwl8k_request_fw(struct mwl8k_priv *priv, - const char *fname, struct firmware **fw, + const char *fname, const struct firmware **fw, bool nowait) { /* release current image */ @@ -432,8 +432,7 @@ static int mwl8k_request_fw(struct mwl8k_priv *priv, &priv->pdev->dev, GFP_KERNEL, priv, mwl8k_fw_state_machine); else - return request_firmware((const struct firmware **)fw, - fname, &priv->pdev->dev); + return request_firmware(fw, fname, &priv->pdev->dev); } static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image, @@ -632,12 +631,12 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv, static int mwl8k_load_firmware(struct ieee80211_hw *hw) { struct mwl8k_priv *priv = hw->priv; - struct firmware *fw = priv->fw_ucode; + const struct firmware *fw = priv->fw_ucode; int rc; int loops; if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) { - struct firmware *helper = priv->fw_helper; + const struct firmware *helper = priv->fw_helper; if (helper == NULL) { printk(KERN_ERR "%s: helper image needed but none " -- cgit v1.2.3-59-g8ed1b From 54435f9ec837cf0bb0ea02a2bb6362a6aaef5250 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 3 Nov 2010 22:06:26 +0100 Subject: ssb: workarounds: be verbose about hacking SPROM revision, don't duplicate code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 6e88d2b603b4..3226832df32d 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -573,37 +573,38 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ memset(out->et1mac, 0xFF, 6); + if ((bus->chip_id & 0xFF00) == 0x4400) { /* Workaround: The BCM44XX chip has a stupid revision * number stored in the SPROM. * Always extract r1. */ out->revision = 1; - sprom_extract_r123(out, in); + ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); } else if (bus->chip_id == 0x4321) { /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ out->revision = 4; + ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); + } + + switch (out->revision) { + case 1: + case 2: + case 3: + sprom_extract_r123(out, in); + break; + case 4: + case 5: sprom_extract_r45(out, in); - } else { - switch (out->revision) { - case 1: - case 2: - case 3: - sprom_extract_r123(out, in); - break; - case 4: - case 5: - sprom_extract_r45(out, in); - break; - case 8: - sprom_extract_r8(out, in); - break; - default: - ssb_printk(KERN_WARNING PFX "Unsupported SPROM" - " revision %d detected. Will extract" - " v1\n", out->revision); - out->revision = 1; - sprom_extract_r123(out, in); - } + break; + case 8: + sprom_extract_r8(out, in); + break; + default: + ssb_printk(KERN_WARNING PFX "Unsupported SPROM" + " revision %d detected. Will extract" + " v1\n", out->revision); + out->revision = 1; + sprom_extract_r123(out, in); } if (out->boardflags_lo == 0xFFFF) -- cgit v1.2.3-59-g8ed1b From ca4a0831917d6541b45f03542257fcb20dc9cf4a Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 3 Nov 2010 23:28:45 +0100 Subject: ssb: return -ENOMEM on alloc fail (instead of CRC check's result) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 3226832df32d..b5343ac37ee5 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -619,7 +619,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, struct ssb_sprom *sprom) { const struct ssb_sprom *fallback; - int err = -ENOMEM; + int err; u16 *buf; if (!ssb_is_sprom_available(bus)) { @@ -646,7 +646,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) - goto out; + return -ENOMEM; bus->sprom_size = SSB_SPROMSIZE_WORDS_R123; sprom_do_read(bus, buf); err = sprom_check_crc(buf, bus->sprom_size); @@ -656,7 +656,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), GFP_KERNEL); if (!buf) - goto out; + return -ENOMEM; bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; sprom_do_read(bus, buf); err = sprom_check_crc(buf, bus->sprom_size); @@ -678,7 +678,6 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, out_free: kfree(buf); -out: return err; } -- cgit v1.2.3-59-g8ed1b From f23a478075659db8a4fd62fa6e264a8bb052cc5b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 8 Nov 2010 11:51:06 +0200 Subject: mac80211: support hardware TX fragmentation offload The lower driver is notified when the fragmentation threshold changes and upon a reconfig of the interface. If the driver supports hardware TX fragmentation, don't fragment packets in the stack. Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 7 +++++++ net/mac80211/driver-ops.h | 14 ++++++++++++++ net/mac80211/driver-trace.h | 21 +++++++++++++++++++++ net/mac80211/tx.c | 11 +++++++++-- net/mac80211/util.c | 3 +++ 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9fdf982d1286..6122e8a3297e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1652,6 +1652,11 @@ enum ieee80211_ampdu_mlme_action { * and IV16) for the given key from hardware. * The callback must be atomic. * + * @set_frag_threshold: Configuration of fragmentation threshold. Assign this + * if the device does fragmentation by itself; if this callback is + * implemented then the stack will not do fragmentation. + * The callback can sleep. + * * @set_rts_threshold: Configuration of RTS threshold (if device needs it) * The callback can sleep. * @@ -1765,6 +1770,7 @@ struct ieee80211_ops { struct ieee80211_low_level_stats *stats); void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, u16 *iv16); + int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 18bd0e550600..3df12f7d0cfe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1299,6 +1299,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) struct ieee80211_local *local = wiphy_priv(wiphy); int err; + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { + err = drv_set_frag_threshold(local, wiphy->frag_threshold); + + if (err) + return err; + } + if (changed & WIPHY_PARAM_COVERAGE_CLASS) { err = drv_set_coverage_class(local, wiphy->coverage_class); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 16983825f8e8..79019f94f621 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -233,6 +233,20 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local, trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); } +static inline int drv_set_frag_threshold(struct ieee80211_local *local, + u32 value) +{ + int ret = 0; + + might_sleep(); + + trace_drv_set_frag_threshold(local, value); + if (local->ops->set_frag_threshold) + ret = local->ops->set_frag_threshold(&local->hw, value); + trace_drv_return_int(local, ret); + return ret; +} + static inline int drv_set_rts_threshold(struct ieee80211_local *local, u32 value) { diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 6831fb1641c8..431d65500d6a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -531,6 +531,27 @@ TRACE_EVENT(drv_get_tkip_seq, ) ); +TRACE_EVENT(drv_set_frag_threshold, + TP_PROTO(struct ieee80211_local *local, u32 value), + + TP_ARGS(local, value), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u32, value) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->value = value; + ), + + TP_printk( + LOCAL_PR_FMT " value:%d", + LOCAL_PR_ARG, __entry->value + ) +); + TRACE_EVENT(drv_set_rts_threshold, TP_PROTO(struct ieee80211_local *local, u32 value), diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c594309506..b392876af7d8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1033,6 +1033,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, struct ieee80211_radiotap_header *rthdr = (struct ieee80211_radiotap_header *) skb->data; struct ieee80211_supported_band *sband; + bool hw_frag; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, NULL); @@ -1042,6 +1043,9 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; tx->flags &= ~IEEE80211_TX_FRAGMENTED; + /* packet is fragmented in HW if we have a non-NULL driver callback */ + hw_frag = (tx->local->ops->set_frag_threshold != NULL); + /* * for every radiotap entry that is present * (ieee80211_radiotap_iterator_next returns -ENOENT when no more @@ -1078,7 +1082,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, } if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) + if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) && + !hw_frag) tx->flags |= IEEE80211_TX_FRAGMENTED; break; @@ -1181,8 +1186,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, /* * Set this flag (used below to indicate "automatic fragmentation"), * it will be cleared/left by radiotap as desired. + * Only valid when fragmentation is done by the stack. */ - tx->flags |= IEEE80211_TX_FRAGMENTED; + if (!local->ops->set_frag_threshold) + tx->flags |= IEEE80211_TX_FRAGMENTED; /* process and remove the injection radiotap header */ if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0b6fc92bc0d7..e486286ebf1a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1152,6 +1152,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) } mutex_unlock(&local->sta_mtx); + /* setup fragmentation threshold */ + drv_set_frag_threshold(local, hw->wiphy->frag_threshold); + /* setup RTS threshold */ drv_set_rts_threshold(local, hw->wiphy->rts_threshold); -- cgit v1.2.3-59-g8ed1b From b5257c952dda24df7078c74b7b811b44c6e49206 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 9 Nov 2010 19:25:47 +0200 Subject: rndis_wlan: workaround device not returning bss for currently connected AP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4320a devices do not return bss for currently connected AP in bss-list, althought this is required by NDIS specs. Missing bss leads to warning at net/wireless/sme.c:__cfg80211_connect_result(), WARN_ON(!bss). Workaround this by crafting bss manually with information we can read from device. Workaround is only used when device bss-list does not return current bss, and so is only used with BCM4320a devices and not newer BCM4320b ones. Fixes bug #20152. Reported-by: Luís Picciochi Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 130 +++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 71b5971da597..0a423c49aab9 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -994,7 +994,8 @@ static int level_to_qual(int level) */ static int set_infra_mode(struct usbnet *usbdev, int mode); static void restore_keys(struct usbnet *usbdev); -static int rndis_check_bssid_list(struct usbnet *usbdev); +static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, + bool *matched); static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) { @@ -1911,7 +1912,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, /* Get current bssid list from device before new scan, as new scan * clears internal bssid list. */ - rndis_check_bssid_list(usbdev); + rndis_check_bssid_list(usbdev, NULL, NULL); if (!request) return -EINVAL; @@ -1981,7 +1982,8 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, GFP_KERNEL); } -static int rndis_check_bssid_list(struct usbnet *usbdev) +static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, + bool *matched) { void *buf = NULL; struct ndis_80211_bssid_list_ex *bssid_list; @@ -2017,7 +2019,11 @@ resize_buf: count, len); while (count && ((void *)bssid + bssid_len) <= (buf + len)) { - rndis_bss_info_update(usbdev, bssid); + if (rndis_bss_info_update(usbdev, bssid) && match_bssid && + matched) { + if (compare_ether_addr(bssid->mac, match_bssid)) + *matched = true; + } bssid = (void *)bssid + bssid_len; bssid_len = le32_to_cpu(bssid->length); @@ -2041,7 +2047,7 @@ static void rndis_get_scan_results(struct work_struct *work) if (!priv->scan_request) return; - ret = rndis_check_bssid_list(usbdev); + ret = rndis_check_bssid_list(usbdev, NULL, NULL); cfg80211_scan_done(priv->scan_request, ret < 0); @@ -2495,6 +2501,91 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); } +static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, + struct ndis_80211_assoc_info *info) +{ + struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct ieee80211_channel *channel; + struct ndis_80211_conf config; + struct ndis_80211_ssid ssid; + s32 signal; + u64 timestamp; + u16 capability; + u16 beacon_interval; + __le32 rssi; + u8 ie_buf[34]; + int len, ret, ie_len; + + /* Get signal quality, in case of error use rssi=0 and ignore error. */ + len = sizeof(rssi); + rssi = 0; + rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); + signal = level_to_qual(le32_to_cpu(rssi)); + + netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, " + "rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi), + level_to_qual(le32_to_cpu(rssi))); + + /* Get AP capabilities */ + if (info) { + capability = le16_to_cpu(info->resp_ie.capa); + } else { + /* Set atleast ESS/IBSS capability */ + capability = (priv->infra_mode == NDIS_80211_INFRA_INFRA) ? + WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS; + } + + /* Get channel and beacon interval */ + len = sizeof(config); + ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); + netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n", + __func__, ret); + if (ret >= 0) { + beacon_interval = le16_to_cpu(config.beacon_period); + channel = ieee80211_get_channel(priv->wdev.wiphy, + KHZ_TO_MHZ(le32_to_cpu(config.ds_config))); + if (!channel) { + netdev_warn(usbdev->net, "%s(): could not get channel." + "\n", __func__); + return; + } + } else { + netdev_warn(usbdev->net, "%s(): could not get configuration.\n", + __func__); + return; + } + + /* Get SSID, in case of error, use zero length SSID and ignore error. */ + len = sizeof(ssid); + memset(&ssid, 0, sizeof(ssid)); + ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len); + netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: " + "'%.32s'\n", __func__, ret, + le32_to_cpu(ssid.length), ssid.essid); + + if (le32_to_cpu(ssid.length) > 32) + ssid.length = cpu_to_le32(32); + + ie_buf[0] = WLAN_EID_SSID; + ie_buf[1] = le32_to_cpu(ssid.length); + memcpy(&ie_buf[2], ssid.essid, le32_to_cpu(ssid.length)); + + ie_len = le32_to_cpu(ssid.length) + 2; + + /* no tsf */ + timestamp = 0; + + netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " + "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " + "signal:%d\n", __func__, (channel ? channel->center_freq : -1), + bssid, (u32)timestamp, capability, beacon_interval, ie_len, + ssid.essid, signal); + + cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, + timestamp, capability, beacon_interval, ie_buf, ie_len, + signal, GFP_KERNEL); +} + /* * workers, indication handlers, device poller */ @@ -2507,6 +2598,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) u8 *req_ie, *resp_ie; int ret, offset; bool roamed = false; + bool match_bss; if (priv->infra_mode == NDIS_80211_INFRA_INFRA && priv->connected) { /* received media connect indication while connected, either @@ -2558,6 +2650,13 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) resp_ie_len = CONTROL_BUFFER_SIZE - offset; } + } else { + /* Since rndis_wlan_craft_connected_bss() might use info + * later and expects info to contain valid data if + * non-null, free info and set NULL here. + */ + kfree(info); + info = NULL; } } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC)) return; @@ -2569,13 +2668,26 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) netdev_dbg(usbdev->net, "link up work: [%pM]%s\n", bssid, roamed ? " roamed" : ""); - /* Internal bss list in device always contains at least the currently + /* Internal bss list in device should contain at least the currently * connected bss and we can get it to cfg80211 with * rndis_check_bssid_list(). - * NOTE: This is true for Broadcom chip, but not mentioned in RNDIS - * spec. + * + * NDIS spec says: "If the device is associated, but the associated + * BSSID is not in its BSSID scan list, then the driver must add an + * entry for the BSSID at the end of the data that it returns in + * response to query of OID_802_11_BSSID_LIST." + * + * NOTE: Seems to be true for BCM4320b variant, but not BCM4320a. */ - rndis_check_bssid_list(usbdev); + match_bss = false; + rndis_check_bssid_list(usbdev, bssid, &match_bss); + + if (!is_zero_ether_addr(bssid) && !match_bss) { + /* Couldn't get bss from device, we need to manually craft bss + * for cfg80211. + */ + rndis_wlan_craft_connected_bss(usbdev, bssid, info); + } if (priv->infra_mode == NDIS_80211_INFRA_INFRA) { if (!roamed) -- cgit v1.2.3-59-g8ed1b From 5cb56af29be8d12f74afcb2c1de91e51a577bd52 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 9 Nov 2010 19:25:56 +0200 Subject: rndis_wlan: workaround poor scanning with BCM4320a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4320a devices seem to sometimes do scanning pretty poorly. This can be workaround by issuing new scan every second, while not yet connected. By this new scanning method device catches beacons much faster. Fixes bug #20822. Reported-by: Luís Picciochi Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 67 ++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0a423c49aab9..8a77ff68590b 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -156,6 +156,12 @@ MODULE_PARM_DESC(workaround_interval, #define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012) +/* Known device types */ +#define RNDIS_UNKNOWN 0 +#define RNDIS_BCM4320A 1 +#define RNDIS_BCM4320B 2 + + /* NDIS data structures. Taken from wpa_supplicant driver_ndis.c * slightly modified for datatype endianess, etc */ @@ -478,6 +484,7 @@ struct rndis_wlan_private { struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)]; u32 cipher_suites[ARRAY_SIZE(rndis_cipher_suites)]; + int device_type; int caps; int multicast_size; @@ -997,6 +1004,16 @@ static void restore_keys(struct usbnet *usbdev); static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, bool *matched); +static int rndis_start_bssid_list_scan(struct usbnet *usbdev) +{ + __le32 tmp; + + /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */ + tmp = cpu_to_le32(1); + return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, + sizeof(tmp)); +} + static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); @@ -1905,7 +1922,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, struct usbnet *usbdev = netdev_priv(dev); struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); int ret; - __le32 tmp; + int delay = SCAN_DELAY_JIFFIES; netdev_dbg(usbdev->net, "cfg80211.scan\n"); @@ -1922,13 +1939,13 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, priv->scan_request = request; - tmp = cpu_to_le32(1); - ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, - sizeof(tmp)); + ret = rndis_start_bssid_list_scan(usbdev); if (ret == 0) { + if (priv->device_type == RNDIS_BCM4320A) + delay = HZ; + /* Wait before retrieving scan results from device */ - queue_delayed_work(priv->workqueue, &priv->scan_work, - SCAN_DELAY_JIFFIES); + queue_delayed_work(priv->workqueue, &priv->scan_work, delay); } return ret; @@ -3046,8 +3063,21 @@ static void rndis_device_poller(struct work_struct *work) * also polls device with rndis_command() and catches for media link * indications. */ - if (!is_associated(usbdev)) + if (!is_associated(usbdev)) { + /* Workaround bad scanning in BCM4320a devices with active + * background scanning when not associated. + */ + if (priv->device_type == RNDIS_BCM4320A && priv->radio_on && + !priv->scan_request) { + /* Get previous scan results */ + rndis_check_bssid_list(usbdev, NULL, NULL); + + /* Initiate new scan */ + rndis_start_bssid_list_scan(usbdev); + } + goto end; + } len = sizeof(rssi); ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); @@ -3104,10 +3134,12 @@ end: /* * driver/device initialization */ -static void rndis_copy_module_params(struct usbnet *usbdev) +static void rndis_copy_module_params(struct usbnet *usbdev, int device_type) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + priv->device_type = device_type; + priv->param_country[0] = modparam_country[0]; priv->param_country[1] = modparam_country[1]; priv->param_country[2] = 0; @@ -3150,12 +3182,25 @@ static void rndis_copy_module_params(struct usbnet *usbdev) priv->param_workaround_interval = modparam_workaround_interval; } +static int unknown_early_init(struct usbnet *usbdev) +{ + /* copy module parameters for unknown so that iwconfig reports txpower + * and workaround parameter is copied to private structure correctly. + */ + rndis_copy_module_params(usbdev, RNDIS_UNKNOWN); + + /* This is unknown device, so do not try set configuration parameters. + */ + + return 0; +} + static int bcm4320a_early_init(struct usbnet *usbdev) { /* copy module parameters for bcm4320a so that iwconfig reports txpower * and workaround parameter is copied to private structure correctly. */ - rndis_copy_module_params(usbdev); + rndis_copy_module_params(usbdev, RNDIS_BCM4320A); /* bcm4320a doesn't handle configuration parameters well. Try * set any and you get partially zeroed mac and broken device. @@ -3169,7 +3214,7 @@ static int bcm4320b_early_init(struct usbnet *usbdev) struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); char buf[8]; - rndis_copy_module_params(usbdev); + rndis_copy_module_params(usbdev, RNDIS_BCM4320B); /* Early initialization settings, setting these won't have effect * if called after generic_rndis_bind(). @@ -3432,7 +3477,7 @@ static const struct driver_info rndis_wlan_info = { .tx_fixup = rndis_tx_fixup, .reset = rndis_wlan_reset, .stop = rndis_wlan_stop, - .early_init = bcm4320a_early_init, + .early_init = unknown_early_init, .indication = rndis_wlan_indication, }; -- cgit v1.2.3-59-g8ed1b From 7e559ec31c5625cf85bcb1ae0eb9f8f2a8da4a29 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 9 Nov 2010 16:35:17 -0800 Subject: drivers/net/wireless/ath/debug.c: Use printf extension %pV Using %pV reduces the number of printk calls and eliminates any possible message interleaving from other printk calls. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/debug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c index dacfb234f491..a9600ba8ceaa 100644 --- a/drivers/net/wireless/ath/debug.c +++ b/drivers/net/wireless/ath/debug.c @@ -19,14 +19,19 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) { + struct va_format vaf; va_list args; if (likely(!(common->debug_mask & dbg_mask))) return; va_start(args, fmt); - printk(KERN_DEBUG "ath: "); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_DEBUG "ath: %pV", &vaf); + va_end(args); } EXPORT_SYMBOL(ath_print); -- cgit v1.2.3-59-g8ed1b From 5b736d42bc51fe893fd7d4ceac34c727d23135e1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 9 Nov 2010 16:35:18 -0800 Subject: drivers/net/wireless/b43/main.c: Use printf extension %pV Using %pV reduces the number of printk calls and eliminates any possible message interleaving from other printk calls. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index a1186525c70d..fa4880366586 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -322,59 +322,83 @@ static int b43_ratelimit(struct b43_wl *wl) void b43info(struct b43_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (b43_modparam_verbose < B43_VERBOSITY_INFO) return; if (!b43_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_INFO "b43-%s: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_INFO "b43-%s: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } void b43err(struct b43_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (b43_modparam_verbose < B43_VERBOSITY_ERROR) return; if (!b43_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_ERR "b43-%s ERROR: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_ERR "b43-%s ERROR: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } void b43warn(struct b43_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (b43_modparam_verbose < B43_VERBOSITY_WARN) return; if (!b43_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_WARNING "b43-%s warning: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_WARNING "b43-%s warning: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } void b43dbg(struct b43_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (b43_modparam_verbose < B43_VERBOSITY_DEBUG) return; + va_start(args, fmt); - printk(KERN_DEBUG "b43-%s debug: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_DEBUG "b43-%s debug: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } -- cgit v1.2.3-59-g8ed1b From 0e67d6cb753643fc076a90fa9309301b3fbfb8db Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 9 Nov 2010 16:35:19 -0800 Subject: drivers/net/wireless/b43legacy/main.c: Use printf extension %pV Using %pV reduces the number of printk calls and eliminates any possible message interleaving from other printk calls. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 47 ++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 67f18ecdb3bf..1f11e1670bf0 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -181,52 +181,75 @@ static int b43legacy_ratelimit(struct b43legacy_wl *wl) void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (!b43legacy_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_INFO "b43legacy-%s: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_INFO "b43legacy-%s: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (!b43legacy_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_ERR "b43legacy-%s ERROR: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_ERR "b43legacy-%s ERROR: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; if (!b43legacy_ratelimit(wl)) return; + va_start(args, fmt); - printk(KERN_WARNING "b43legacy-%s warning: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_WARNING "b43legacy-%s warning: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } #if B43legacy_DEBUG void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) { + struct va_format vaf; va_list args; va_start(args, fmt); - printk(KERN_DEBUG "b43legacy-%s debug: ", - (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); - vprintk(fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + printk(KERN_DEBUG "b43legacy-%s debug: %pV", + (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); + va_end(args); } #endif /* DEBUG */ -- cgit v1.2.3-59-g8ed1b From afe0cbf87500f0585d217deb8c6fd329793a7957 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 10 Nov 2010 12:50:50 +0900 Subject: cfg80211: Add nl80211 antenna configuration Allow setting of TX and RX antennas configuration via nl80211. The antenna configuration is defined as a bitmap of allowed antennas to use. This API can be used to mask out antennas which are not attached or should not be used for other reasons like regulatory concerns or special setups. Separate bitmaps are used for RX and TX to allow configuring different antennas for receiving and transmitting. Each bitmap is 32 bit long, each bit representing one antenna, starting with antenna 1 at the first bit. If an antenna bit is set, this means the driver is allowed to use this antenna for RX or TX respectively; if the bit is not set the hardware is not allowed to use this antenna. Using bitmaps has the benefit of allowing for a flexible configuration interface which can support many different configurations and which can be used for 802.11n as well as non-802.11n devices. Instead of relying on some hardware specific assumptions, drivers can use this information to know which antennas are actually attached to the system and derive their capabilities based on that. 802.11n devices should enable or disable chains, based on which antennas are present (If all antennas belonging to a particular chain are disabled, the entire chain should be disabled). HT capabilities (like STBC, TX Beamforming, Antenna selection) should be calculated based on the available chains after applying the antenna masks. Should a 802.11n device have diversity antennas attached to one of their chains, diversity can be enabled or disabled based on the antenna information. Non-802.11n drivers can use the antenna masks to select RX and TX antennas and to enable or disable antenna diversity. While covering chainmasks for 802.11n and the standard "legacy" modes "fixed antenna 1", "fixed antenna 2" and "diversity" this API also allows more rare, but useful configurations as follows: 1) Send on antenna 1, receive on antenna 2 (or vice versa). This can be used to have a low gain antenna for TX in order to keep within the regulatory constraints and a high gain antenna for RX in order to receive weaker signals ("speak softly, but listen harder"). This can be useful for building long-shot outdoor links. Another usage of this setup is having a low-noise pre-amplifier on antenna 1 and a power amplifier on the other antenna. This way transmit noise is mostly kept out of the low noise receive channel. (This would be bitmaps: tx 1 rx 2). 2) Another similar setup is: Use RX diversity on both antennas, but always send on antenna 1. Again that would allow us to benefit from a higher gain RX antenna, while staying within the legal limits. (This would be: tx 0 rx 3). 3) And finally there can be special experimental setups in research and development even with pre 802.11n hardware where more than 2 antennas are available. It's good to keep the API simple, yet flexible. Signed-off-by: Bruno Randolf -- v7: Made bitmasks 32 bit wide and rebased to latest wireless-testing. Signed-off-by: John W. Linville --- include/linux/nl80211.h | 25 +++++++++++++++++++++++++ include/net/cfg80211.h | 3 +++ net/wireless/nl80211.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index fb877b5621b7..17c5c8849250 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -804,6 +804,28 @@ enum nl80211_commands { * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly * means support for per-station GTKs. * + * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting. + * This can be used to mask out antennas which are not attached or should + * not be used for transmitting. If an antenna is not selected in this + * bitmap the hardware is not allowed to transmit on this antenna. + * + * Each bit represents one antenna, starting with antenna 1 at the first + * bit. Depending on which antennas are selected in the bitmap, 802.11n + * drivers can derive which chainmasks to use (if all antennas belonging to + * a particular chain are disabled this chain should be disabled) and if + * a chain has diversity antennas wether diversity should be used or not. + * HT capabilities (STBC, TX Beamforming, Antenna selection) can be + * derived from the available chains after applying the antenna mask. + * Non-802.11n drivers can derive wether to use diversity or not. + * Drivers may reject configurations or RX/TX mask combinations they cannot + * support by returning -EINVAL. + * + * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving. + * This can be used to mask out antennas which are not attached or should + * not be used for receiving. If an antenna is not selected in this bitmap + * the hardware should not be configured to receive on this antenna. + * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -973,6 +995,9 @@ enum nl80211_attrs { NL80211_ATTR_SUPPORT_IBSS_RSN, + NL80211_ATTR_WIPHY_ANTENNA_TX, + NL80211_ATTR_WIPHY_ANTENNA_RX, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e5702f5ac57c..07425e648a09 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1304,6 +1304,9 @@ struct cfg80211_ops { void (*mgmt_frame_register)(struct wiphy *wiphy, struct net_device *dev, u16 frame_type, bool reg); + + int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); + int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); }; /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c506241f8637..5e4dda4c0fd3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -166,7 +166,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, + [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, + + [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 }, + [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -526,7 +530,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, dev->wiphy.rts_threshold); NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, dev->wiphy.coverage_class); - NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, dev->wiphy.max_scan_ssids); NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, @@ -545,6 +548,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); + if (dev->ops->get_antenna) { + u32 tx_ant = 0, rx_ant = 0; + int res; + res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); + if (!res) { + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant); + } + } + nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); if (!nl_modes) goto nla_put_failure; @@ -1024,6 +1037,22 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && + info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { + u32 tx_ant, rx_ant; + if (!rdev->ops->set_antenna) { + result = -EOPNOTSUPP; + goto bad_res; + } + + tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); + rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); + + result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); + if (result) + goto bad_res; + } + changed = 0; if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { -- cgit v1.2.3-59-g8ed1b From 15d967532148a5fcda075282b82a271b6595a386 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 10 Nov 2010 12:50:56 +0900 Subject: mac80211: Add antenna configuration Allow antenna configuration by calling driver's function for it. We disallow antenna configuration if the wiphy is already running, mainly to make life easier for 802.11n drivers which need to recalculate HT capabilites. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/net/mac80211.h | 2 ++ net/mac80211/cfg.c | 19 +++++++++++++++++ net/mac80211/driver-ops.h | 23 +++++++++++++++++++++ net/mac80211/driver-trace.h | 50 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 6122e8a3297e..a7323eca08d1 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1799,6 +1799,8 @@ struct ieee80211_ops { void (*channel_switch)(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch); int (*napi_poll)(struct ieee80211_hw *hw, int budget); + int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); + int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3df12f7d0cfe..0c544074479e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1628,6 +1628,23 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, ieee80211_queue_work(&local->hw, &local->reconfig_filter); } +static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + if (local->started) + return -EOPNOTSUPP; + + return drv_set_antenna(local, tx_ant, rx_ant); +} + +static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + return drv_get_antenna(local, tx_ant, rx_ant); +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1680,4 +1697,6 @@ struct cfg80211_ops mac80211_config_ops = { .mgmt_tx = ieee80211_mgmt_tx, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, .mgmt_frame_register = ieee80211_mgmt_frame_register, + .set_antenna = ieee80211_set_antenna, + .get_antenna = ieee80211_get_antenna, }; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 79019f94f621..4244554d218a 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -442,4 +442,27 @@ static inline void drv_channel_switch(struct ieee80211_local *local, trace_drv_return_void(local); } + +static inline int drv_set_antenna(struct ieee80211_local *local, + u32 tx_ant, u32 rx_ant) +{ + int ret = -EOPNOTSUPP; + might_sleep(); + if (local->ops->set_antenna) + ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); + trace_drv_set_antenna(local, tx_ant, rx_ant, ret); + return ret; +} + +static inline int drv_get_antenna(struct ieee80211_local *local, + u32 *tx_ant, u32 *rx_ant) +{ + int ret = -EOPNOTSUPP; + might_sleep(); + if (local->ops->get_antenna) + ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); + trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); + return ret; +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 431d65500d6a..c2772f23ac9c 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -883,6 +883,56 @@ TRACE_EVENT(drv_channel_switch, ) ); +TRACE_EVENT(drv_set_antenna, + TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret), + + TP_ARGS(local, tx_ant, rx_ant, ret), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u32, tx_ant) + __field(u32, rx_ant) + __field(int, ret) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->tx_ant = tx_ant; + __entry->rx_ant = rx_ant; + __entry->ret = ret; + ), + + TP_printk( + LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d", + LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret + ) +); + +TRACE_EVENT(drv_get_antenna, + TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret), + + TP_ARGS(local, tx_ant, rx_ant, ret), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u32, tx_ant) + __field(u32, rx_ant) + __field(int, ret) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->tx_ant = tx_ant; + __entry->rx_ant = rx_ant; + __entry->ret = ret; + ), + + TP_printk( + LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d", + LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret + ) +); + /* * Tracing for API calls that drivers call. */ -- cgit v1.2.3-59-g8ed1b From 72a801103f07182c0a4f3a761caa62b4ab8eb4e5 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 10 Nov 2010 12:51:01 +0900 Subject: ath5k: Add support for antenna configuration Support setting the antenna configuration via cfg/mac80211. At the moment only allow the simple pre-defined configurations we already have (fixed antenna A/B or diversity), but more advanced settings are possible to implement. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b9f93fbd9728..fe116de41361 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3413,6 +3413,36 @@ static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, return ret; } +static int ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) +{ + struct ath5k_softc *sc = hw->priv; + + if (tx_ant == 1 && rx_ant == 1) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A); + else if (tx_ant == 2 && rx_ant == 2) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B); + else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT); + else + return -EINVAL; + return 0; +} + +static int ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct ath5k_softc *sc = hw->priv; + + switch (sc->ah->ah_ant_mode) { + case AR5K_ANTMODE_FIXED_A: + *tx_ant = 1; *rx_ant = 1; break; + case AR5K_ANTMODE_FIXED_B: + *tx_ant = 2; *rx_ant = 2; break; + case AR5K_ANTMODE_DEFAULT: + *tx_ant = 3; *rx_ant = 3; break; + } + return 0; +} + static const struct ieee80211_ops ath5k_hw_ops = { .tx = ath5k_tx, .start = ath5k_start, @@ -3433,6 +3463,8 @@ static const struct ieee80211_ops ath5k_hw_ops = { .sw_scan_start = ath5k_sw_scan_start, .sw_scan_complete = ath5k_sw_scan_complete, .set_coverage_class = ath5k_set_coverage_class, + .set_antenna = ath5k_set_antenna, + .get_antenna = ath5k_get_antenna, }; /********************\ -- cgit v1.2.3-59-g8ed1b From a9d85fbd3e5f7a0679e6276953cd23ac7bb72789 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Thu, 11 Nov 2010 00:40:33 -0800 Subject: ath9k_hw: Fix a reset failure on AR9382 (2x2). AR9382 needs to be configured for the correct chain mask before running AGC/TxIQ caliberation. Otherwise reset would fail. Signed-off-by: Senthil Balasubramanian Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 17 ++++++++++++----- drivers/net/wireless/ath/ath9k/reg.h | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 9e6edffe0bd1..32eed19ff6f9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -718,12 +718,19 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_common *common = ath9k_hw_common(ah); + int val; - /* - * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before - * running AGC/TxIQ cals - */ - ar9003_hw_set_chain_masks(ah, 0x7, 0x7); + val = REG_READ(ah, AR_ENT_OTP); + ath_print(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); + + if (val & AR_ENT_OTP_CHAIN2_DISABLE) + ar9003_hw_set_chain_masks(ah, 0x3, 0x3); + else + /* + * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain + * mode before running AGC/TxIQ cals + */ + ar9003_hw_set_chain_masks(ah, 0x7, 0x7); /* Do Tx IQ Calibration */ ar9003_hw_tx_iq_cal(ah); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 42976b0a01c1..ac6a13e27352 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1065,6 +1065,8 @@ enum { #define AR_INTR_PRIO_ASYNC_MASK 0x40c8 #define AR_INTR_PRIO_SYNC_MASK 0x40cc #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 +#define AR_ENT_OTP 0x40d8 +#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 #define AR_RTC_9300_PLL_DIV 0x000003ff #define AR_RTC_9300_PLL_DIV_S 0 -- cgit v1.2.3-59-g8ed1b From b3dd6bc1f052ef3a754fa866743e4fda38522811 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 10 Nov 2010 05:03:07 -0800 Subject: ath9k_hw: Add new member into the eeprom structure. Add eeprom base extension structures which are needed for AR938x caliberation changes and gain calculation. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 21 +++++++++++++++------ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 18 +++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index a88fe0d6142f..bc3f49c5c5b4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -147,10 +147,13 @@ static const struct ar9300_eeprom ar9300_default = { .papdRateMaskHt20 = LE32(0x80c080), .papdRateMaskHt40 = LE32(0x80c080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, }, + .base_ext1 = { + .ant_div_control = 0, + .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, .calFreqPier2G = { FREQ2FBIN(2412, 1), FREQ2FBIN(2437, 1), @@ -285,8 +288,7 @@ static const struct ar9300_eeprom ar9300_default = { /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), - /* Data[11].ctlEdges[3].bChannel */ - FREQ2FBIN(2462, 1), + /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), } }, .ctlPowerData_2G = { @@ -346,10 +348,17 @@ static const struct ar9300_eeprom ar9300_default = { .papdRateMaskHt20 = LE32(0xf0e0e0), .papdRateMaskHt40 = LE32(0xf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, }, + .base_ext2 = { + .tempSlopeLow = 0, + .tempSlopeHigh = 0, + .xatten1DBLow = {0, 0, 0}, + .xatten1MarginLow = {0, 0, 0}, + .xatten1DBHigh = {0, 0, 0}, + .xatten1MarginHigh = {0, 0, 0} + }, .calFreqPier5G = { FREQ2FBIN(5180, 0), FREQ2FBIN(5220, 0), diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3c533bb983c7..5301df3e9ec0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -236,7 +236,7 @@ struct ar9300_modal_eep_header { u8 thresh62; __le32 papdRateMaskHt20; __le32 papdRateMaskHt40; - u8 futureModal[24]; + u8 futureModal[10]; } __packed; struct ar9300_cal_data_per_freq_op_loop { @@ -274,6 +274,20 @@ struct cal_ctl_data_5g { struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; } __packed; +struct ar9300_BaseExtension_1 { + u8 ant_div_control; + u8 future[13]; +} __packed; + +struct ar9300_BaseExtension_2 { + int8_t tempSlopeLow; + int8_t tempSlopeHigh; + u8 xatten1DBLow[AR9300_MAX_CHAINS]; + u8 xatten1MarginLow[AR9300_MAX_CHAINS]; + u8 xatten1DBHigh[AR9300_MAX_CHAINS]; + u8 xatten1MarginHigh[AR9300_MAX_CHAINS]; +} __packed; + struct ar9300_eeprom { u8 eepromVersion; u8 templateVersion; @@ -283,6 +297,7 @@ struct ar9300_eeprom { struct ar9300_base_eep_hdr baseEepHeader; struct ar9300_modal_eep_header modalHeader2G; + struct ar9300_BaseExtension_1 base_ext1; u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; struct ar9300_cal_data_per_freq_op_loop calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; @@ -302,6 +317,7 @@ struct ar9300_eeprom { u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; struct ar9300_modal_eep_header modalHeader5G; + struct ar9300_BaseExtension_2 base_ext2; u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; struct ar9300_cal_data_per_freq_op_loop calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; -- cgit v1.2.3-59-g8ed1b From ef5a6a7573b7a12ced67dae155be8a909bc245d6 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 10 Nov 2010 05:03:08 -0800 Subject: ath9k_hw: Initialize 2GHz CTL properly. The last 2GHz CTL was not being initialized, so power was being set to 0 instead of 30dbm. Initialize to 30 like other CTLs. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index bc3f49c5c5b4..b33fb5bd8886 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -306,6 +306,7 @@ static const struct ar9300_eeprom ar9300_default = { { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, }, .modalHeader5G = { /* 4 idle,t1,t2,b (4 bits per setting) */ -- cgit v1.2.3-59-g8ed1b From 3ceb801bffb62bc486f9662cd4dbca2cbdc6f5c7 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 10 Nov 2010 05:03:09 -0800 Subject: ath9k_hw: Fix paprd training frame failure. paprd training frame fails in some rates. Fix the rate mask. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b33fb5bd8886..29a138631f75 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -144,8 +144,8 @@ static const struct ar9300_eeprom ar9300_default = { .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, - .papdRateMaskHt20 = LE32(0x80c080), - .papdRateMaskHt40 = LE32(0x80c080), + .papdRateMaskHt20 = LE32(0x0cf0e0e0), + .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, @@ -346,8 +346,8 @@ static const struct ar9300_eeprom ar9300_default = { .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, - .papdRateMaskHt20 = LE32(0xf0e0e0), - .papdRateMaskHt40 = LE32(0xf0e0e0), + .papdRateMaskHt20 = LE32(0x0c80c080), + .papdRateMaskHt40 = LE32(0x0080c080), .futureModal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, -- cgit v1.2.3-59-g8ed1b From 3092354970381fb8b6439fb4def0c34632277ae9 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 10 Nov 2010 05:03:10 -0800 Subject: ath9k_hw: add eeprom templates for ar9003 family chipsets We are currently using the default eeprom default and it doesn't work properly for all ar9003 family chipsets. So add eeprom templates for different versisons and select the eeprom table based on the template version programmed in the eeprom. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2338 +++++++++++++++++++++++- 1 file changed, 2336 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 29a138631f75..3d467fc13883 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -633,6 +633,2338 @@ static const struct ar9300_eeprom ar9300_default = { } }; +static const struct ar9300_eeprom ar9300_x113 = { + .eepromVersion = 2, + .templateVersion = 6, + .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, + .custData = {"x113-023-f0000"}, + .baseEepHeader = { + .regDmn = { LE16(0), LE16(0x1f) }, + .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { + .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .eepMisc = 0, + }, + .rfSilent = 0, + .blueToothOptions = 0, + .deviceCap = 0, + .deviceType = 5, /* takes lower byte in eeprom location */ + .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, + .params_for_tuning_caps = {0, 0}, + .featureEnable = 0x0d, + /* + * bit0 - enable tx temp comp - disabled + * bit1 - enable tx volt comp - disabled + * bit2 - enable fastClock - enabled + * bit3 - enable doubling - enabled + * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled + */ + .miscConfiguration = 0, /* bit0 - turn down drivestrength */ + .eepromWriteEnableGpio = 6, + .wlanDisableGpio = 0, + .wlanLedGpio = 8, + .rxBandSelectGpio = 0xff, + .txrxgain = 0x21, + .swreg = 0, + }, + .modalHeader2G = { + /* ar9300_modal_eep_header 2g */ + /* 4 idle,t1,t2,b(4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ + .antCtrlCommon2 = LE32(0x44444), + + /* + * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, + * rx1, rx12, b (2 bits each) + */ + .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, + + /* + * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db + * for ar9280 (0xa20c/b20c 5:0) + */ + .xatten1DB = {0, 0, 0}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for ar9280 (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0, 0, 0}, + .tempSlope = 25, + .voltSlope = 0, + + /* + * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur + * channels in usual fbin coding format + */ + .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, + + /* + * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check + * if the register is per chain + */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {1, 1, 1},/* 3 chain */ + .db_stage2 = {1, 1, 1}, /* 3 chain */ + .db_stage3 = {0, 0, 0}, + .db_stage4 = {0, 0, 0}, + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2c, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0c80c080), + .papdRateMaskHt40 = LE32(0x0080c080), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext1 = { + .ant_div_control = 0, + .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + .calFreqPier2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1), + }, + /* ar9300_cal_data_per_freq_op_loop 2g */ + .calPierData2G = { + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + }, + .calTarget_freqbin_Cck = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2472, 1), + }, + .calTarget_freqbin_2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT20 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT40 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTargetPowerCck = { + /* 1L-5L,5S,11L,11S */ + { {34, 34, 34, 34} }, + { {34, 34, 34, 34} }, + }, + .calTargetPower2G = { + /* 6-24,36,48,54 */ + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + }, + .calTargetPower2GHT20 = { + { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, + { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, + { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, + }, + .calTargetPower2GHT40 = { + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + }, + .ctlIndex_2G = { + 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, + 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, + }, + .ctl_freqbin_2G = { + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2457, 1), + FREQ2FBIN(2462, 1) + }, + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + { + FREQ2FBIN(2422, 1), + FREQ2FBIN(2427, 1), + FREQ2FBIN(2447, 1), + FREQ2FBIN(2452, 1) + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + }, + + { + /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + } + }, + .ctlPowerData_2G = { + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, + + { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + }, + .modalHeader5G = { + /* 4 idle,t1,t2,b (4 bits per setting) */ + .antCtrlCommon = LE32(0x220), + /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ + .antCtrlCommon2 = LE32(0x11111), + /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ + .antCtrlChain = { + LE16(0x150), LE16(0x150), LE16(0x150), + }, + /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ + .xatten1DB = {0, 0, 0}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for merlin (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0, 0, 0}, + .tempSlope = 68, + .voltSlope = 0, + /* spurChans spur channels in usual fbin coding format */ + .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, + /* noiseFloorThreshCh Check if the register is per chain */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {3, 3, 3}, /* 3 chain */ + .db_stage2 = {3, 3, 3}, /* 3 chain */ + .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ + .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2d, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0cf0e0e0), + .papdRateMaskHt40 = LE32(0x6cf0e0e0), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext2 = { + .tempSlopeLow = 72, + .tempSlopeHigh = 105, + .xatten1DBLow = {0, 0, 0}, + .xatten1MarginLow = {0, 0, 0}, + .xatten1DBHigh = {0, 0, 0}, + .xatten1MarginHigh = {0, 0, 0} + }, + .calFreqPier5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5785, 0) + }, + .calPierData5G = { + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + + }, + .calTarget_freqbin_5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5785, 0) + }, + .calTarget_freqbin_5GHT20 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT40 = { + FREQ2FBIN(5190, 0), + FREQ2FBIN(5230, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5410, 0), + FREQ2FBIN(5510, 0), + FREQ2FBIN(5670, 0), + FREQ2FBIN(5755, 0), + FREQ2FBIN(5825, 0) + }, + .calTargetPower5G = { + /* 6-24,36,48,54 */ + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + { {42, 40, 40, 34} }, + }, + .calTargetPower5GHT20 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, + { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} }, + { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} }, + }, + .calTargetPower5GHT40 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, + { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} }, + { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} }, + }, + .ctlIndex_5G = { + 0x10, 0x16, 0x18, 0x40, 0x46, + 0x48, 0x30, 0x36, 0x38 + }, + .ctl_freqbin_5G = { + { + /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), + /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + { + /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), + /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), + /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), + /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), + /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), + /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) + }, + + { + /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), + /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), + /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[3].ctlEdges[6].bChannel */ 0xFF, + /* Data[3].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), + /* Data[4].ctlEdges[4].bChannel */ 0xFF, + /* Data[4].ctlEdges[5].bChannel */ 0xFF, + /* Data[4].ctlEdges[6].bChannel */ 0xFF, + /* Data[4].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), + /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), + /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[5].ctlEdges[6].bChannel */ 0xFF, + /* Data[5].ctlEdges[7].bChannel */ 0xFF + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), + /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), + /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), + /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), + /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), + /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), + /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), + /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) + } + }, + .ctlPowerData_5G = { + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 1}, {60, 0}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + {60, 0}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 0}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + } + }, + } +}; + + +static const struct ar9300_eeprom ar9300_h112 = { + .eepromVersion = 2, + .templateVersion = 3, + .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, + .custData = {"h112-241-f0000"}, + .baseEepHeader = { + .regDmn = { LE16(0), LE16(0x1f) }, + .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { + .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .eepMisc = 0, + }, + .rfSilent = 0, + .blueToothOptions = 0, + .deviceCap = 0, + .deviceType = 5, /* takes lower byte in eeprom location */ + .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, + .params_for_tuning_caps = {0, 0}, + .featureEnable = 0x0d, + /* + * bit0 - enable tx temp comp - disabled + * bit1 - enable tx volt comp - disabled + * bit2 - enable fastClock - enabled + * bit3 - enable doubling - enabled + * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled + */ + .miscConfiguration = 0, /* bit0 - turn down drivestrength */ + .eepromWriteEnableGpio = 6, + .wlanDisableGpio = 0, + .wlanLedGpio = 8, + .rxBandSelectGpio = 0xff, + .txrxgain = 0x10, + .swreg = 0, + }, + .modalHeader2G = { + /* ar9300_modal_eep_header 2g */ + /* 4 idle,t1,t2,b(4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ + .antCtrlCommon2 = LE32(0x44444), + + /* + * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, + * rx1, rx12, b (2 bits each) + */ + .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, + + /* + * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db + * for ar9280 (0xa20c/b20c 5:0) + */ + .xatten1DB = {0, 0, 0}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for ar9280 (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0, 0, 0}, + .tempSlope = 25, + .voltSlope = 0, + + /* + * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur + * channels in usual fbin coding format + */ + .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, + + /* + * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check + * if the register is per chain + */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {1, 1, 1},/* 3 chain */ + .db_stage2 = {1, 1, 1}, /* 3 chain */ + .db_stage3 = {0, 0, 0}, + .db_stage4 = {0, 0, 0}, + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2c, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x80c080), + .papdRateMaskHt40 = LE32(0x80c080), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext1 = { + .ant_div_control = 0, + .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + .calFreqPier2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1), + }, + /* ar9300_cal_data_per_freq_op_loop 2g */ + .calPierData2G = { + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + }, + .calTarget_freqbin_Cck = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2484, 1), + }, + .calTarget_freqbin_2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT20 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT40 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTargetPowerCck = { + /* 1L-5L,5S,11L,11S */ + { {34, 34, 34, 34} }, + { {34, 34, 34, 34} }, + }, + .calTargetPower2G = { + /* 6-24,36,48,54 */ + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + }, + .calTargetPower2GHT20 = { + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, + }, + .calTargetPower2GHT40 = { + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, + }, + .ctlIndex_2G = { + 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, + 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, + }, + .ctl_freqbin_2G = { + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2457, 1), + FREQ2FBIN(2462, 1) + }, + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + { + FREQ2FBIN(2422, 1), + FREQ2FBIN(2427, 1), + FREQ2FBIN(2447, 1), + FREQ2FBIN(2452, 1) + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + }, + + { + /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + } + }, + .ctlPowerData_2G = { + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, + + { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + }, + .modalHeader5G = { + /* 4 idle,t1,t2,b (4 bits per setting) */ + .antCtrlCommon = LE32(0x220), + /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ + .antCtrlCommon2 = LE32(0x44444), + /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ + .antCtrlChain = { + LE16(0x150), LE16(0x150), LE16(0x150), + }, + /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ + .xatten1DB = {0, 0, 0}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for merlin (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0, 0, 0}, + .tempSlope = 45, + .voltSlope = 0, + /* spurChans spur channels in usual fbin coding format */ + .spurChans = {0, 0, 0, 0, 0}, + /* noiseFloorThreshCh Check if the register is per chain */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {3, 3, 3}, /* 3 chain */ + .db_stage2 = {3, 3, 3}, /* 3 chain */ + .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ + .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2d, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0cf0e0e0), + .papdRateMaskHt40 = LE32(0x6cf0e0e0), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext2 = { + .tempSlopeLow = 40, + .tempSlopeHigh = 50, + .xatten1DBLow = {0, 0, 0}, + .xatten1MarginLow = {0, 0, 0}, + .xatten1DBHigh = {0, 0, 0}, + .xatten1MarginHigh = {0, 0, 0} + }, + .calFreqPier5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5825, 0) + }, + .calPierData5G = { + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + + }, + .calTarget_freqbin_5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT20 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT40 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5825, 0) + }, + .calTargetPower5G = { + /* 6-24,36,48,54 */ + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + }, + .calTargetPower5GHT20 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} }, + { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} }, + { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} }, + { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} }, + { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} }, + { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} }, + { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} }, + { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} }, + }, + .calTargetPower5GHT40 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} }, + { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} }, + { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} }, + { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} }, + { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} }, + { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} }, + { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} }, + { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} }, + }, + .ctlIndex_5G = { + 0x10, 0x16, 0x18, 0x40, 0x46, + 0x48, 0x30, 0x36, 0x38 + }, + .ctl_freqbin_5G = { + { + /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), + /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + { + /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), + /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), + /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), + /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), + /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), + /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) + }, + + { + /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), + /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), + /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[3].ctlEdges[6].bChannel */ 0xFF, + /* Data[3].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), + /* Data[4].ctlEdges[4].bChannel */ 0xFF, + /* Data[4].ctlEdges[5].bChannel */ 0xFF, + /* Data[4].ctlEdges[6].bChannel */ 0xFF, + /* Data[4].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), + /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), + /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[5].ctlEdges[6].bChannel */ 0xFF, + /* Data[5].ctlEdges[7].bChannel */ 0xFF + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), + /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), + /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), + /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), + /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), + /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), + /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), + /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) + } + }, + .ctlPowerData_5G = { + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 1}, {60, 0}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + {60, 0}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 0}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + } + }, + } +}; + + +static const struct ar9300_eeprom ar9300_x112 = { + .eepromVersion = 2, + .templateVersion = 5, + .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, + .custData = {"x112-041-f0000"}, + .baseEepHeader = { + .regDmn = { LE16(0), LE16(0x1f) }, + .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { + .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .eepMisc = 0, + }, + .rfSilent = 0, + .blueToothOptions = 0, + .deviceCap = 0, + .deviceType = 5, /* takes lower byte in eeprom location */ + .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, + .params_for_tuning_caps = {0, 0}, + .featureEnable = 0x0d, + /* + * bit0 - enable tx temp comp - disabled + * bit1 - enable tx volt comp - disabled + * bit2 - enable fastclock - enabled + * bit3 - enable doubling - enabled + * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled + */ + .miscConfiguration = 0, /* bit0 - turn down drivestrength */ + .eepromWriteEnableGpio = 6, + .wlanDisableGpio = 0, + .wlanLedGpio = 8, + .rxBandSelectGpio = 0xff, + .txrxgain = 0x0, + .swreg = 0, + }, + .modalHeader2G = { + /* ar9300_modal_eep_header 2g */ + /* 4 idle,t1,t2,b(4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ + .antCtrlCommon2 = LE32(0x22222), + + /* + * antCtrlChain[ar9300_max_chains]; 6 idle, t, r, + * rx1, rx12, b (2 bits each) + */ + .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) }, + + /* + * xatten1DB[AR9300_max_chains]; 3 xatten1_db + * for ar9280 (0xa20c/b20c 5:0) + */ + .xatten1DB = {0x1b, 0x1b, 0x1b}, + + /* + * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin + * for ar9280 (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0x15, 0x15, 0x15}, + .tempSlope = 50, + .voltSlope = 0, + + /* + * spurChans[OSPrey_eeprom_modal_sPURS]; spur + * channels in usual fbin coding format + */ + .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, + + /* + * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check + * if the register is per chain + */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {1, 1, 1},/* 3 chain */ + .db_stage2 = {1, 1, 1}, /* 3 chain */ + .db_stage3 = {0, 0, 0}, + .db_stage4 = {0, 0, 0}, + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2c, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0c80c080), + .papdRateMaskHt40 = LE32(0x0080c080), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext1 = { + .ant_div_control = 0, + .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + .calFreqPier2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1), + }, + /* ar9300_cal_data_per_freq_op_loop 2g */ + .calPierData2G = { + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + }, + .calTarget_freqbin_Cck = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2472, 1), + }, + .calTarget_freqbin_2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT20 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT40 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTargetPowerCck = { + /* 1L-5L,5S,11L,11s */ + { {38, 38, 38, 38} }, + { {38, 38, 38, 38} }, + }, + .calTargetPower2G = { + /* 6-24,36,48,54 */ + { {38, 38, 36, 34} }, + { {38, 38, 36, 34} }, + { {38, 38, 34, 32} }, + }, + .calTargetPower2GHT20 = { + { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} }, + { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} }, + { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} }, + }, + .calTargetPower2GHT40 = { + { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} }, + { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} }, + { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} }, + }, + .ctlIndex_2G = { + 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, + 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, + }, + .ctl_freqbin_2G = { + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2457, 1), + FREQ2FBIN(2462, 1) + }, + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + { + FREQ2FBIN(2422, 1), + FREQ2FBIN(2427, 1), + FREQ2FBIN(2447, 1), + FREQ2FBIN(2452, 1) + }, + + { + /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), + /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1), + }, + + { + /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1), + /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1), + /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1), + /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1), + }, + + { + /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), + }, + + { + /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), + /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), + /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1), + /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1), + /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1), + /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1), + } + }, + .ctlPowerData_2G = { + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, + + { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + }, + .modalHeader5G = { + /* 4 idle,t1,t2,b (4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ + .antCtrlCommon2 = LE32(0x22222), + /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ + .antCtrlChain = { + LE16(0x0), LE16(0x0), LE16(0x0), + }, + /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */ + .xatten1DB = {0x13, 0x19, 0x17}, + + /* + * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin + * for merlin (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0x19, 0x19, 0x19}, + .tempSlope = 70, + .voltSlope = 15, + /* spurChans spur channels in usual fbin coding format */ + .spurChans = {0, 0, 0, 0, 0}, + /* noiseFloorThreshch check if the register is per chain */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {3, 3, 3}, /* 3 chain */ + .db_stage2 = {3, 3, 3}, /* 3 chain */ + .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ + .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2d, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0cf0e0e0), + .papdRateMaskHt40 = LE32(0x6cf0e0e0), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext2 = { + .tempSlopeLow = 72, + .tempSlopeHigh = 105, + .xatten1DBLow = {0x10, 0x14, 0x10}, + .xatten1MarginLow = {0x19, 0x19 , 0x19}, + .xatten1DBHigh = {0x1d, 0x20, 0x24}, + .xatten1MarginHigh = {0x10, 0x10, 0x10} + }, + .calFreqPier5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5785, 0) + }, + .calPierData5G = { + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + + }, + .calTarget_freqbin_5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5725, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT20 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5725, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT40 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5725, 0), + FREQ2FBIN(5825, 0) + }, + .calTargetPower5G = { + /* 6-24,36,48,54 */ + { {32, 32, 28, 26} }, + { {32, 32, 28, 26} }, + { {32, 32, 28, 26} }, + { {32, 32, 26, 24} }, + { {32, 32, 26, 24} }, + { {32, 32, 24, 22} }, + { {30, 30, 24, 22} }, + { {30, 30, 24, 22} }, + }, + .calTargetPower5GHT20 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} }, + { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} }, + { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} }, + { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} }, + { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} }, + }, + .calTargetPower5GHT40 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, + { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} }, + { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} }, + { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, + { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, + { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, + }, + .ctlIndex_5G = { + 0x10, 0x16, 0x18, 0x40, 0x46, + 0x48, 0x30, 0x36, 0x38 + }, + .ctl_freqbin_5G = { + { + /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), + /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0), + /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), + /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0), + /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), + /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), + /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) + }, + { + /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), + /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0), + /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), + /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0), + /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), + /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), + /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), + /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0), + /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0), + /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0), + /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0), + /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0), + /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0), + /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0) + }, + + { + /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0), + /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0), + /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0), + /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0), + /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), + /* Data[3].ctledges[6].bchannel */ 0xFF, + /* Data[3].ctledges[7].bchannel */ 0xFF, + }, + + { + /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), + /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0), + /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0), + /* Data[4].ctledges[4].bchannel */ 0xFF, + /* Data[4].ctledges[5].bchannel */ 0xFF, + /* Data[4].ctledges[6].bchannel */ 0xFF, + /* Data[4].ctledges[7].bchannel */ 0xFF, + }, + + { + /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), + /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0), + /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0), + /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0), + /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0), + /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0), + /* Data[5].ctledges[6].bchannel */ 0xFF, + /* Data[5].ctledges[7].bchannel */ 0xFF + }, + + { + /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0), + /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0), + /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0), + /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0), + /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0), + /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0), + /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0) + }, + + { + /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), + /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), + /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0), + /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), + /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0), + /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), + /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), + /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), + /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0), + /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0), + /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0), + /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0), + /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0), + /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0), + /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0) + } + }, + .ctlPowerData_5G = { + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 1}, {60, 0}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + {60, 0}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 0}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + } + }, + } +}; + +static const struct ar9300_eeprom ar9300_h116 = { + .eepromVersion = 2, + .templateVersion = 4, + .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, + .custData = {"h116-041-f0000"}, + .baseEepHeader = { + .regDmn = { LE16(0), LE16(0x1f) }, + .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { + .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .eepMisc = 0, + }, + .rfSilent = 0, + .blueToothOptions = 0, + .deviceCap = 0, + .deviceType = 5, /* takes lower byte in eeprom location */ + .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, + .params_for_tuning_caps = {0, 0}, + .featureEnable = 0x0d, + /* + * bit0 - enable tx temp comp - disabled + * bit1 - enable tx volt comp - disabled + * bit2 - enable fastClock - enabled + * bit3 - enable doubling - enabled + * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled + */ + .miscConfiguration = 0, /* bit0 - turn down drivestrength */ + .eepromWriteEnableGpio = 6, + .wlanDisableGpio = 0, + .wlanLedGpio = 8, + .rxBandSelectGpio = 0xff, + .txrxgain = 0x10, + .swreg = 0, + }, + .modalHeader2G = { + /* ar9300_modal_eep_header 2g */ + /* 4 idle,t1,t2,b(4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ + .antCtrlCommon2 = LE32(0x44444), + + /* + * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, + * rx1, rx12, b (2 bits each) + */ + .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) }, + + /* + * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db + * for ar9280 (0xa20c/b20c 5:0) + */ + .xatten1DB = {0x1f, 0x1f, 0x1f}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for ar9280 (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0x12, 0x12, 0x12}, + .tempSlope = 25, + .voltSlope = 0, + + /* + * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur + * channels in usual fbin coding format + */ + .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, + + /* + * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check + * if the register is per chain + */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {1, 1, 1},/* 3 chain */ + .db_stage2 = {1, 1, 1}, /* 3 chain */ + .db_stage3 = {0, 0, 0}, + .db_stage4 = {0, 0, 0}, + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2c, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0c80C080), + .papdRateMaskHt40 = LE32(0x0080C080), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext1 = { + .ant_div_control = 0, + .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + .calFreqPier2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1), + }, + /* ar9300_cal_data_per_freq_op_loop 2g */ + .calPierData2G = { + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, + }, + .calTarget_freqbin_Cck = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2472, 1), + }, + .calTarget_freqbin_2G = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT20 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTarget_freqbin_2GHT40 = { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), + FREQ2FBIN(2472, 1) + }, + .calTargetPowerCck = { + /* 1L-5L,5S,11L,11S */ + { {34, 34, 34, 34} }, + { {34, 34, 34, 34} }, + }, + .calTargetPower2G = { + /* 6-24,36,48,54 */ + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + { {34, 34, 32, 32} }, + }, + .calTargetPower2GHT20 = { + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, + { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, + }, + .calTargetPower2GHT40 = { + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + }, + .ctlIndex_2G = { + 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, + 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, + }, + .ctl_freqbin_2G = { + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2457, 1), + FREQ2FBIN(2462, 1) + }, + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + + { + FREQ2FBIN(2412, 1), + FREQ2FBIN(2417, 1), + FREQ2FBIN(2462, 1), + 0xFF, + }, + { + FREQ2FBIN(2422, 1), + FREQ2FBIN(2427, 1), + FREQ2FBIN(2447, 1), + FREQ2FBIN(2452, 1) + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + FREQ2FBIN(2472, 1), + 0, + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + }, + + { + /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), + /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), + /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), + 0 + }, + + { + /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), + /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + } + }, + .ctlPowerData_2G = { + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, + + { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + }, + .modalHeader5G = { + /* 4 idle,t1,t2,b (4 bits per setting) */ + .antCtrlCommon = LE32(0x220), + /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ + .antCtrlCommon2 = LE32(0x44444), + /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ + .antCtrlChain = { + LE16(0x150), LE16(0x150), LE16(0x150), + }, + /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ + .xatten1DB = {0x19, 0x19, 0x19}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for merlin (0xa20c/b20c 16:12 + */ + .xatten1Margin = {0x14, 0x14, 0x14}, + .tempSlope = 70, + .voltSlope = 0, + /* spurChans spur channels in usual fbin coding format */ + .spurChans = {0, 0, 0, 0, 0}, + /* noiseFloorThreshCh Check if the register is per chain */ + .noiseFloorThreshCh = {-1, 0, 0}, + .ob = {3, 3, 3}, /* 3 chain */ + .db_stage2 = {3, 3, 3}, /* 3 chain */ + .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ + .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ + .xpaBiasLvl = 0, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ + .antennaGain = 0, + .switchSettling = 0x2d, + .adcDesiredSize = -30, + .txEndToXpaOff = 0, + .txEndToRxOn = 0x2, + .txFrameToXpaOn = 0xe, + .thresh62 = 28, + .papdRateMaskHt20 = LE32(0x0cf0e0e0), + .papdRateMaskHt40 = LE32(0x6cf0e0e0), + .futureModal = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }, + .base_ext2 = { + .tempSlopeLow = 35, + .tempSlopeHigh = 50, + .xatten1DBLow = {0, 0, 0}, + .xatten1MarginLow = {0, 0, 0}, + .xatten1DBHigh = {0, 0, 0}, + .xatten1MarginHigh = {0, 0, 0} + }, + .calFreqPier5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5785, 0) + }, + .calPierData5G = { + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + }, + + }, + .calTarget_freqbin_5G = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT20 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT40 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), + FREQ2FBIN(5825, 0) + }, + .calTargetPower5G = { + /* 6-24,36,48,54 */ + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + { {30, 30, 28, 24} }, + }, + .calTargetPower5GHT20 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} }, + { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} }, + { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} }, + { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} }, + { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} }, + { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} }, + { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} }, + { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} }, + }, + .calTargetPower5GHT40 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ + { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} }, + { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} }, + { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} }, + { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} }, + { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} }, + { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} }, + { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} }, + { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} }, + }, + .ctlIndex_5G = { + 0x10, 0x16, 0x18, 0x40, 0x46, + 0x48, 0x30, 0x36, 0x38 + }, + .ctl_freqbin_5G = { + { + /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), + /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + { + /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), + /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), + /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), + /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), + /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), + /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), + /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) + }, + + { + /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), + /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), + /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[3].ctlEdges[6].bChannel */ 0xFF, + /* Data[3].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), + /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), + /* Data[4].ctlEdges[4].bChannel */ 0xFF, + /* Data[4].ctlEdges[5].bChannel */ 0xFF, + /* Data[4].ctlEdges[6].bChannel */ 0xFF, + /* Data[4].ctlEdges[7].bChannel */ 0xFF, + }, + + { + /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), + /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), + /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), + /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[5].ctlEdges[6].bChannel */ 0xFF, + /* Data[5].ctlEdges[7].bChannel */ 0xFF + }, + + { + /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), + /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), + /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), + /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), + /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), + /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), + /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) + }, + + { + /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), + /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), + /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), + /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), + /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), + /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), + /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), + /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) + }, + + { + /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), + /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), + /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), + /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), + /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), + /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), + /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), + /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) + } + }, + .ctlPowerData_5G = { + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 0}, {60, 1}, {60, 1}, {60, 0}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + {60, 0}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 0}, {60, 0}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 1}, + } + }, + { + { + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + {60, 1}, {60, 1}, {60, 1}, {60, 0}, + } + }, + { + { + {60, 1}, {60, 0}, {60, 1}, {60, 1}, + {60, 1}, {60, 1}, {60, 0}, {60, 1}, + } + }, + } +}; + + +static const struct ar9300_eeprom *ar9300_eep_templates[] = { + &ar9300_default, + &ar9300_x112, + &ar9300_h116, + &ar9300_h112, + &ar9300_x113, +}; + +static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id) +{ +#define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0])) + int it; + + for (it = 0; it < N_LOOP; it++) + if (ar9300_eep_templates[it]->templateVersion == id) + return ar9300_eep_templates[it]; + return NULL; +#undef N_LOOP +} + + static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) { if (fbin == AR9300_BCHAN_UNUSED) @@ -834,6 +3166,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, { struct ath_common *common = ath9k_hw_common(ah); u8 *dptr; + const struct ar9300_eeprom *eep = NULL; switch (code) { case _CompressNone: @@ -851,13 +3184,14 @@ static int ar9300_compress_decision(struct ath_hw *ah, if (reference == 0) { dptr = mptr; } else { - if (reference != 2) { + eep = ar9003_eeprom_struct_find_by_id(reference); + if (eep == NULL) { ath_print(common, ATH_DBG_EEPROM, "cant find reference eeprom" "struct %d\n", reference); return -1; } - memcpy(mptr, &ar9300_default, mdata_size); + memcpy(mptr, eep, mdata_size); } ath_print(common, ATH_DBG_EEPROM, "restore eeprom %d: block, reference %d," -- cgit v1.2.3-59-g8ed1b From 52a0e2477dac2106bc1688cbe9615cdafc9deb7d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Nov 2010 05:03:11 -0800 Subject: ath9k_hw: Fix XPABIAS level configuration for AR9003 Improper configuration of 0x16288 and 0x16290 would affect transmission. Cc:stable@kernel.org Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 3d467fc13883..17f73e4d8f36 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -22,12 +22,14 @@ #define COMP_CKSUM_LEN 2 #define AR_CH0_TOP (0x00016288) -#define AR_CH0_TOP_XPABIASLVL (0x3) +#define AR_CH0_TOP_XPABIASLVL (0x300) #define AR_CH0_TOP_XPABIASLVL_S (8) #define AR_CH0_THERM (0x00016290) -#define AR_CH0_THERM_SPARE (0x3f) -#define AR_CH0_THERM_SPARE_S (0) +#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 +#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 +#define AR_CH0_THERM_XPASHORT2GND 0x4 +#define AR_CH0_THERM_XPASHORT2GND_S 2 #define AR_SWITCH_TABLE_COM_ALL (0xffff) #define AR_SWITCH_TABLE_COM_ALL_S (0) @@ -3336,9 +3338,9 @@ static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) { int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); - REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3)); - REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE, - ((bias >> 2) & 0x3)); + REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); + REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2); + REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); } static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) -- cgit v1.2.3-59-g8ed1b From f4475a6e52fce8d951a96c763f36b835bf89fdec Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Nov 2010 05:03:12 -0800 Subject: ath9k_hw: Enable strong signal detection for AR9003 Attenuation from eeprom is configured into attenuator control register. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 79 ++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 17f73e4d8f36..da26d3704cb2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -57,6 +57,8 @@ #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ +static int ar9003_hw_power_interpolate(int32_t x, + int32_t *px, int32_t *py, u_int16_t np); static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, @@ -3443,6 +3445,82 @@ static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); } +static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain, + struct ath9k_channel *chan) +{ + int f[3], t[3]; + u16 value; + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + + if (chain >= 0 && chain < 3) { + if (IS_CHAN_2GHZ(chan)) + return eep->modalHeader2G.xatten1DB[chain]; + else if (eep->base_ext2.xatten1DBLow[chain] != 0) { + t[0] = eep->base_ext2.xatten1DBLow[chain]; + f[0] = 5180; + t[1] = eep->modalHeader5G.xatten1DB[chain]; + f[1] = 5500; + t[2] = eep->base_ext2.xatten1DBHigh[chain]; + f[2] = 5785; + value = ar9003_hw_power_interpolate((s32) chan->channel, + f, t, 3); + return value; + } else + return eep->modalHeader5G.xatten1DB[chain]; + } + + return 0; +} + + +static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain, + struct ath9k_channel *chan) +{ + int f[3], t[3]; + u16 value; + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + + if (chain >= 0 && chain < 3) { + if (IS_CHAN_2GHZ(chan)) + return eep->modalHeader2G.xatten1Margin[chain]; + else if (eep->base_ext2.xatten1MarginLow[chain] != 0) { + t[0] = eep->base_ext2.xatten1MarginLow[chain]; + f[0] = 5180; + t[1] = eep->modalHeader5G.xatten1Margin[chain]; + f[1] = 5500; + t[2] = eep->base_ext2.xatten1MarginHigh[chain]; + f[2] = 5785; + value = ar9003_hw_power_interpolate((s32) chan->channel, + f, t, 3); + return value; + } else + return eep->modalHeader5G.xatten1Margin[chain]; + } + + return 0; +} + +static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) +{ + int i; + u16 value; + unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0, + AR_PHY_EXT_ATTEN_CTL_1, + AR_PHY_EXT_ATTEN_CTL_2, + }; + + /* Test value. if 0 then attenuation is unused. Don't load anything. */ + for (i = 0; i < 3; i++) { + value = ar9003_hw_atten_chain_get(ah, i, chan); + REG_RMW_FIELD(ah, ext_atten_reg[i], + AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); + + value = ar9003_hw_atten_chain_get_margin(ah, i, chan); + REG_RMW_FIELD(ah, ext_atten_reg[i], + AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); + } +} + static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = @@ -3474,6 +3552,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); ar9003_hw_drive_strength_apply(ah); + ar9003_hw_atten_apply(ah, chan); ar9003_hw_internal_regulator_apply(ah); } -- cgit v1.2.3-59-g8ed1b From 15cbbc44cc4abaaebc37caf0ec9410a3f83d1deb Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Nov 2010 05:03:13 -0800 Subject: ath9k_hw: Improve power control accuracy for AR9003 It is done for 5Ghz by adding three temperature slopes. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index da26d3704cb2..5ffeda25bf14 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4062,6 +4062,7 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, { int tempSlope = 0; struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + int f[3], t[3]; REG_RMW(ah, AR_PHY_TPC_11_B0, (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), @@ -4090,7 +4091,16 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, */ if (frequency < 4000) tempSlope = eep->modalHeader2G.tempSlope; - else + else if (eep->base_ext2.tempSlopeLow != 0) { + t[0] = eep->base_ext2.tempSlopeLow; + f[0] = 5180; + t[1] = eep->modalHeader5G.tempSlope; + f[1] = 5500; + t[2] = eep->base_ext2.tempSlopeHigh; + f[2] = 5785; + tempSlope = ar9003_hw_power_interpolate((s32) frequency, + f, t, 3); + } else tempSlope = eep->modalHeader5G.tempSlope; REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); -- cgit v1.2.3-59-g8ed1b From bc2068020bfa976efd425f3be590f58a012fd747 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Nov 2010 05:03:14 -0800 Subject: ath9k_hw: Add helper function for interpolation Also round off interpolated values this would improve power accuracy by 0.5dB in some cases. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 48 +++++++++++++++----------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 5ffeda25bf14..1b4e99167b6c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -2982,6 +2982,16 @@ static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) return 0; } +static int interpolate(int x, int xa, int xb, int ya, int yb) +{ + int bf, factor, plus; + + bf = 2 * (yb - ya) * (x - xa) / (xb - xa); + factor = bf / 2; + plus = bf % 2; + return ya + factor + plus; +} + static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, enum eeprom_param param) { @@ -3614,7 +3624,7 @@ static int ar9003_hw_power_interpolate(int32_t x, if (hx == lx) y = ly; else /* interpolate */ - y = ly + (((x - lx) * (hy - ly)) / (hx - lx)); + y = interpolate(x, lx, hx, ly, hy); } else /* only low is good, use it */ y = ly; } else if (hhave) /* only high is good, use it */ @@ -4204,25 +4214,23 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) /* so is the high frequency, interpolate */ if (hfrequency[ichain] - frequency < 1000) { - correction[ichain] = lcorrection[ichain] + - (((frequency - lfrequency[ichain]) * - (hcorrection[ichain] - - lcorrection[ichain])) / - (hfrequency[ichain] - lfrequency[ichain])); - - temperature[ichain] = ltemperature[ichain] + - (((frequency - lfrequency[ichain]) * - (htemperature[ichain] - - ltemperature[ichain])) / - (hfrequency[ichain] - lfrequency[ichain])); - - voltage[ichain] = - lvoltage[ichain] + - (((frequency - - lfrequency[ichain]) * (hvoltage[ichain] - - lvoltage[ichain])) - / (hfrequency[ichain] - - lfrequency[ichain])); + correction[ichain] = interpolate(frequency, + lfrequency[ichain], + hfrequency[ichain], + lcorrection[ichain], + hcorrection[ichain]); + + temperature[ichain] = interpolate(frequency, + lfrequency[ichain], + hfrequency[ichain], + ltemperature[ichain], + htemperature[ichain]); + + voltage[ichain] = interpolate(frequency, + lfrequency[ichain], + hfrequency[ichain], + lvoltage[ichain], + hvoltage[ichain]); } /* only low is good, use it */ else { -- cgit v1.2.3-59-g8ed1b From 39ec2997c374b528cdbf65099b6d6b8593a67f7f Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Nov 2010 05:03:15 -0800 Subject: ath9k: Fix bug in delimiter padding computation There is a roundng error in delimiter padding computation which causes severe throughput drop with some of AR9003. signed-off-by: Felix Fietkau Signed-off-by: Vasanthakumar Thiagarajan Cc:stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 21433465bde4..92670ce4ea99 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -177,8 +177,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, /* returns delimiter padding required given the packet length */ #define ATH_AGGR_GET_NDELIM(_len) \ - (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \ - (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2) + (((_len) >= ATH_AGGR_MINPLEN) ? 0 : \ + DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ)) #define BAW_WITHIN(_start, _bawsz, _seqno) \ ((((_seqno) - (_start)) & 4095) < (_bawsz)) -- cgit v1.2.3-59-g8ed1b From 6ee63f55c7754462a45315ac93027a1df60667c9 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 10 Nov 2010 05:03:16 -0800 Subject: ath9k_hw: Fix low throughput issue with AR93xx TX underruns were noticed when RTS/CTS preceded aggregates. This issue was noticed in ar93xx family of chipsets only. The workaround involves padding the RTS or CTS length up to the min packet length of 256 bytes required by the hardware by adding delimiters to the fist descriptor of the aggregate. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 28 ++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/hw.c | 3 +++ drivers/net/wireless/ath/ath9k/hw.h | 3 +++ drivers/net/wireless/ath/ath9k/reg.h | 1 + 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 10c812e353a6..f5896aa30005 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -410,12 +410,36 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, u32 aggrLen) { +#define FIRST_DESC_NDELIMS 60 struct ar9003_txc *ads = (struct ar9003_txc *) ds; ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); - ads->ctl17 &= ~AR_AggrLen; - ads->ctl17 |= SM(aggrLen, AR_AggrLen); + if (ah->ent_mode & AR_ENT_OTP_MPSD) { + u32 ctl17, ndelim; + /* + * Add delimiter when using RTS/CTS with aggregation + * and non enterprise AR9003 card + */ + ctl17 = ads->ctl17; + ndelim = MS(ctl17, AR_PadDelim); + + if (ndelim < FIRST_DESC_NDELIMS) { + aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4; + ndelim = FIRST_DESC_NDELIMS; + } + + ctl17 &= ~AR_AggrLen; + ctl17 |= SM(aggrLen, AR_AggrLen); + + ctl17 &= ~AR_PadDelim; + ctl17 |= SM(ndelim, AR_PadDelim); + + ads->ctl17 = ctl17; + } else { + ads->ctl17 &= ~AR_AggrLen; + ads->ctl17 |= SM(aggrLen, AR_AggrLen); + } } static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index e75d8e8cf4d2..75e23632b968 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1952,6 +1952,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; + if (AR_SREV_9300_20_OR_LATER(ah)) + ah->ent_mode = REG_READ(ah, AR_ENT_OTP); + if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f821a28bcda3..15f51c8943a1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -803,6 +803,9 @@ struct ath_hw { * this register when in sleep states. */ u32 WARegVal; + + /* Enterprise mode cap */ + u32 ent_mode; }; static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index ac6a13e27352..60826b82f4a2 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1067,6 +1067,7 @@ enum { #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 +#define AR_ENT_OTP_MPSD 0x00800000 #define AR_RTC_9300_PLL_DIV 0x000003ff #define AR_RTC_9300_PLL_DIV_S 0 -- cgit v1.2.3-59-g8ed1b From 7afbb2f07028183f50ae4f7ce4dab1f32b36cf48 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 10 Nov 2010 11:43:51 -0800 Subject: ath5k: Cleanup opmode setting logic. An earlier review suggested moving the code in a small method that was only called once inline. This patch accomplishes that. Signed-off-by: Ben Greear Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fe116de41361..13735cc899a5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -549,7 +549,7 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) /* Calculate combined mode - when APs are active, operate in AP mode. * Otherwise use the mode of the new interface. This can currently * only deal with combinations of APs and STAs. Only one ad-hoc - * interfaces is allowed above. + * interfaces is allowed. */ if (avf->opmode == NL80211_IFTYPE_AP) iter_data->opmode = NL80211_IFTYPE_AP; @@ -558,14 +558,6 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->opmode = avf->opmode; } -static void ath_do_set_opmode(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - ath5k_hw_set_opmode(ah, sc->opmode); - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", - sc->opmode, ath_opmode_to_string(sc->opmode)); -} - static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, struct ieee80211_vif *vif) { @@ -595,7 +587,9 @@ static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, /* Nothing active, default to station mode */ sc->opmode = NL80211_IFTYPE_STATION; - ath_do_set_opmode(sc); + ath5k_hw_set_opmode(sc->ah, sc->opmode); + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", + sc->opmode, ath_opmode_to_string(sc->opmode)); if (iter_data.need_set_hw_addr && iter_data.found_active) ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); -- cgit v1.2.3-59-g8ed1b From 1d666d8e05edf5891a7a4bd84a25f493f01dc71a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 03:18:34 +0100 Subject: ath9k: remove the unnecessary private xretry tx flag Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/ath/ath9k/rc.h | 1 - drivers/net/wireless/ath/ath9k/xmit.c | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 85c8e9310cae..c052bd6ddbcd 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1370,7 +1370,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, is_underrun = 1; } - if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) + if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) tx_status = 1; ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 2f46a2266ba1..a1dce437b6af 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -227,7 +227,6 @@ struct ath_rate_priv { #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) -#define ATH_TX_INFO_XRETRY (1 << 3) #define ATH_TX_INFO_UNDERRUN (1 << 4) enum ath9k_internal_frame_type { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6380bbd82d49..eaaeb937fa17 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1993,9 +1993,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; - if ((ts->ts_status & ATH9K_TXERR_XRETRY) || - (ts->ts_status & ATH9K_TXERR_FIFO)) - tx_info->pad[0] |= ATH_TX_INFO_XRETRY; } } -- cgit v1.2.3-59-g8ed1b From f0c255a07fe8a4d450cce6355a22b73ee0e9e6e0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 03:18:35 +0100 Subject: ath9k: handle tx underrun in the driver instead of rate control Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 18 ------------------ drivers/net/wireless/ath/ath9k/rc.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 25 ++++++++++++++++++++----- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index c052bd6ddbcd..33bb33b456ff 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1354,22 +1354,6 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, tx_info->status.ampdu_len = 1; } - /* - * If an underrun error is seen assume it as an excessive retry only - * if max frame trigger level has been reached (2 KB for singel stream, - * and 4 KB for dual stream). Adjust the long retry as if the frame was - * tried hw->max_rate_tries times to affect how ratectrl updates PER for - * the failed rate. In case of congestion on the bus penalizing these - * type of underruns should help hardware actually transmit new frames - * successfully by eventually preferring slower rates. This itself - * should also alleviate congestion on the bus. - */ - if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && - (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { - tx_status = 1; - is_underrun = 1; - } - if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) tx_status = 1; @@ -1596,8 +1580,6 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp return NULL; } - rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max; - return rate_priv; } diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index a1dce437b6af..a96f5eb09c45 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -215,7 +215,6 @@ struct ath_rate_priv { u32 per_down_time; u32 probe_interval; u32 prev_data_rix; - u32 tx_triglevel_max; struct ath_rateset neg_rates; struct ath_rateset neg_ht_rates; struct ath_rate_softc *asc; @@ -227,7 +226,6 @@ struct ath_rate_priv { #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) -#define ATH_TX_INFO_UNDERRUN (1 << 4) enum ath9k_internal_frame_type { ATH9K_IFT_NOT_INTERNAL, diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index eaaeb937fa17..8785ec3b1cb9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1968,6 +1968,8 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hw *hw = bf->aphy->hw; + struct ath_softc *sc = bf->aphy->sc; + struct ath_hw *ah = sc->sc_ah; u8 i, tx_rateindex; if (txok) @@ -1989,11 +1991,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { - if (ieee80211_is_data(hdr->frame_control)) { - if (ts->ts_flags & - (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) - tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; - } + /* + * If an underrun error is seen assume it as an excessive + * retry only if max frame trigger level has been reached + * (2 KB for single stream, and 4 KB for dual stream). + * Adjust the long retry as if the frame was tried + * hw->max_rate_tries times to affect how rate control updates + * PER for the failed rate. + * In case of congestion on the bus penalizing this type of + * underruns should help hardware actually transmit new frames + * successfully by eventually preferring slower rates. + * This itself should also alleviate congestion on the bus. + */ + if (ieee80211_is_data(hdr->frame_control) && + (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | + ATH9K_TX_DELIM_UNDERRUN)) && + ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max) + tx_info->status.rates[tx_rateindex].count = + hw->max_rate_tries; } for (i = tx_rateindex + 1; i < hw->max_rates; i++) { -- cgit v1.2.3-59-g8ed1b From 61117f01e79f7c0da86c23535bed757370f5885f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 03:18:36 +0100 Subject: ath9k: remove the tx info padding byte abuse Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/rc.h | 3 --- drivers/net/wireless/ath/ath9k/virtual.c | 5 ++--- drivers/net/wireless/ath/ath9k/xmit.c | 21 ++++++--------------- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 92670ce4ea99..3e6ebe698852 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -229,6 +229,7 @@ struct ath_buf_state { unsigned long bfs_paprd_timestamp; u32 bfs_keyix; enum ath9k_key_type bfs_keytype; + enum ath9k_internal_frame_type bfs_ftype; }; struct ath_buf { @@ -711,7 +712,7 @@ void ath9k_ps_restore(struct ath_softc *sc); void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int ath9k_wiphy_add(struct ath_softc *sc); int ath9k_wiphy_del(struct ath_wiphy *aphy); -void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); +void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype); int ath9k_wiphy_pause(struct ath_wiphy *aphy); int ath9k_wiphy_unpause(struct ath_wiphy *aphy); int ath9k_wiphy_select(struct ath_wiphy *aphy); diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index a96f5eb09c45..31a004cb60ac 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -224,9 +224,6 @@ struct ath_rate_priv { struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; }; -#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) -#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) - enum ath9k_internal_frame_type { ATH9K_IFT_NOT_INTERNAL, ATH9K_IFT_PAUSE, diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 4008f51d34c8..d5442c3745cc 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -305,13 +305,12 @@ void ath9k_wiphy_chan_work(struct work_struct *work) * ath9k version of ieee80211_tx_status() for TX frames that are generated * internally in the driver. */ -void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) +void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype) { struct ath_wiphy *aphy = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) && - aphy->state == ATH_WIPHY_PAUSING) { + if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) { if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { printk(KERN_DEBUG "ath9k: %s: no ACK for pause " "frame\n", wiphy_name(hw->wiphy)); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 8785ec3b1cb9..32e22677953d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1580,17 +1580,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, int padpos, padsize; bool use_ldpc = false; - tx_info->pad[0] = 0; - switch (txctl->frame_type) { - case ATH9K_IFT_NOT_INTERNAL: - break; - case ATH9K_IFT_PAUSE: - tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; - /* fall through */ - case ATH9K_IFT_UNPAUSE: - tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; - break; - } hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; @@ -1711,6 +1700,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, tid, &bf_head); } } else { + bf->bf_state.bfs_ftype = txctl->frame_type; ath_tx_send_normal(sc, txctl->txq, &bf_head); } @@ -1828,7 +1818,7 @@ exit: /*****************/ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, - struct ath_wiphy *aphy, int tx_flags, + struct ath_wiphy *aphy, int tx_flags, int ftype, struct ath_txq *txq) { struct ieee80211_hw *hw = sc->hw; @@ -1872,8 +1862,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, PS_WAIT_FOR_TX_ACK)); } - if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) - ath9k_tx_status(hw, skb); + if (unlikely(ftype)) + ath9k_tx_status(hw, skb, ftype); else { q = skb_get_queue_mapping(skb); if (txq == sc->tx.txq_map[q]) { @@ -1917,7 +1907,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, complete(&sc->paprd_complete); } else { ath_debug_stat_tx(sc, bf, ts); - ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq); + ath_tx_complete(sc, skb, bf->aphy, tx_flags, + bf->bf_state.bfs_ftype, txq); } /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't * accidentally reference it later. -- cgit v1.2.3-59-g8ed1b From 82b873afe83c81d9b1273a816bbdacb266f71a52 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 03:18:37 +0100 Subject: ath9k: clean up tx buffer setup Merge ath_tx_send_normal and ath_tx_send_ht_normal. Move the paprd state initialization and sequence number assignment to reduce the number of redundant checks. This not only simplifies buffer allocation error handling, but also removes a small inconsistency in the buffer HT flag. This flag should only be set if the frame is also a QoS data frame. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 117 ++++++++++++---------------------- 1 file changed, 39 insertions(+), 78 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 32e22677953d..8ba0e2d86c1f 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -48,9 +48,9 @@ static u16 bits_per_symbol[][2] = { #define IS_HT_RATE(_rate) ((_rate) & 0x80) -static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, - struct list_head *bf_head); +static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, + struct ath_atx_tid *tid, + struct list_head *bf_head); static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_txq *txq, struct list_head *bf_q, struct ath_tx_status *ts, int txok, int sendbar); @@ -160,7 +160,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ath_tx_update_baw(sc, tid, bf->bf_seqno); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } else { - ath_tx_send_ht_normal(sc, txq, tid, &bf_head); + ath_tx_send_normal(sc, txq, tid, &bf_head); } } @@ -1322,9 +1322,9 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ath_tx_txqaddbuf(sc, txctl->txq, bf_head); } -static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, - struct list_head *bf_head) +static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, + struct ath_atx_tid *tid, + struct list_head *bf_head) { struct ath_buf *bf; @@ -1332,7 +1332,8 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, bf->bf_state.bf_type &= ~BUF_AMPDU; /* update starting sequence number for subsequent ADDBA request */ - INCR(tid->seq_start, IEEE80211_SEQ_MAX); + if (tid) + INCR(tid->seq_start, IEEE80211_SEQ_MAX); bf->bf_nframes = 1; bf->bf_lastbf = bf; @@ -1341,20 +1342,6 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, TX_STAT_INC(txq->axq_qnum, queued); } -static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, - struct list_head *bf_head) -{ - struct ath_buf *bf; - - bf = list_first_entry(bf_head, struct ath_buf, list); - - bf->bf_lastbf = bf; - bf->bf_nframes = 1; - ath_buf_set_rate(sc, bf); - ath_tx_txqaddbuf(sc, txq, bf_head); - TX_STAT_INC(txq->axq_qnum, queued); -} - static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) { struct ieee80211_hdr *hdr; @@ -1411,7 +1398,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, INCR(tid->seq_next, IEEE80211_SEQ_MAX); } -static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) +static int setup_tx_flags(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); int flags = 0; @@ -1422,7 +1409,7 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) flags |= ATH9K_TXDESC_NOACK; - if (use_ldpc) + if (tx_info->flags & IEEE80211_TX_CTL_LDPC) flags |= ATH9K_TXDESC_LDPC; return flags; @@ -1567,18 +1554,24 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); } -static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, - struct sk_buff *skb, - struct ath_tx_control *txctl) +static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, + struct sk_buff *skb) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ath_buf *bf; int hdrlen; __le16 fc; int padpos, padsize; - bool use_ldpc = false; + + bf = ath_tx_get_buffer(sc); + if (!bf) { + ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); + return NULL; + } hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; @@ -1594,16 +1587,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_frmlen -= padsize; } - if (!txctl->paprd && conf_is_ht(&hw->conf)) { + if (ieee80211_is_data_qos(fc) && conf_is_ht(&hw->conf)) { bf->bf_state.bf_type |= BUF_HT; - if (tx_info->flags & IEEE80211_TX_CTL_LDPC) - use_ldpc = true; + if (sc->sc_flags & SC_OP_TXAGGR) + assign_aggr_tid_seqno(skb, bf); } - bf->bf_state.bfs_paprd = txctl->paprd; - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; - bf->bf_flags = setup_tx_flags(skb, use_ldpc); + bf->bf_flags = setup_tx_flags(skb); bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { @@ -1613,10 +1603,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_keyix = ATH9K_TXKEYIX_INVALID; } - if (ieee80211_is_data_qos(fc) && bf_isht(bf) && - (sc->sc_flags & SC_OP_TXAGGR)) - assign_aggr_tid_seqno(skb, bf); - bf->bf_mpdu = skb; bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, @@ -1626,12 +1612,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_buf_addr = 0; ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, "dma_mapping_error() on TX\n"); - return -ENOMEM; + ath_tx_return_buffer(sc, bf); + return NULL; } bf->bf_tx_aborted = false; - return 0; + return bf; } /* FIXME: tx power */ @@ -1679,11 +1666,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, an = (struct ath_node *)tx_info->control.sta->drv_priv; tid = ATH_AN_2_TID(an, bf->bf_tidno); - if (!ieee80211_is_data_qos(fc)) { - ath_tx_send_normal(sc, txctl->txq, &bf_head); - goto tx_done; - } - WARN_ON(tid->ac->txq != txctl->txq); if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { /* @@ -1696,15 +1678,18 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, * Send this frame as regular when ADDBA * exchange is neither complete nor pending. */ - ath_tx_send_ht_normal(sc, txctl->txq, - tid, &bf_head); + ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); } } else { bf->bf_state.bfs_ftype = txctl->frame_type; - ath_tx_send_normal(sc, txctl->txq, &bf_head); + bf->bf_state.bfs_paprd = txctl->paprd; + + if (txctl->paprd) + bf->bf_state.bfs_paprd_timestamp = jiffies; + + ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); } -tx_done: spin_unlock_bh(&txctl->txq->axq_lock); } @@ -1714,39 +1699,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_txq *txq = txctl->txq; struct ath_buf *bf; - int q, r; + int q; - bf = ath_tx_get_buffer(sc); - if (!bf) { - ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); - return -1; - } + bf = ath_tx_setup_buffer(hw, skb); + if (unlikely(!bf)) + return -ENOMEM; q = skb_get_queue_mapping(skb); - r = ath_tx_setup_buffer(hw, bf, skb, txctl); - if (unlikely(r)) { - ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); - - /* upon ath_tx_processq() this TX queue will be resumed, we - * guarantee this will happen by knowing beforehand that - * we will at least have to run TX completionon one buffer - * on the queue */ - spin_lock_bh(&txq->axq_lock); - if (txq == sc->tx.txq_map[q] && !txq->stopped && - txq->axq_depth > 1) { - ath_mac80211_stop_queue(sc, q); - txq->stopped = 1; - } - spin_unlock_bh(&txq->axq_lock); - - ath_tx_return_buffer(sc, bf); - - return r; - } - spin_lock_bh(&txq->axq_lock); if (txq == sc->tx.txq_map[q] && ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { -- cgit v1.2.3-59-g8ed1b From 4e8c14e9587c38f4cce8049c766935629fdb8d46 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 03:18:38 +0100 Subject: ath9k_hw: add a private op for configuring radar pulse detection Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 32 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_phy.c | 32 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 36 +++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index c83a22cfbe1e..3686811cc8df 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1579,6 +1579,37 @@ static void ar5008_hw_set_nf_limits(struct ath_hw *ah) ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ; } +static void ar5008_hw_set_radar_params(struct ath_hw *ah, + struct ath_hw_radar_conf *conf) +{ + u32 radar_0 = 0, radar_1 = 0; + + if (!conf) { + REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); + return; + } + + radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA; + radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR); + radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI); + radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT); + radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); + radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); + + radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; + radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; + radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); + radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH); + radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH); + + REG_WRITE(ah, AR_PHY_RADAR_0, radar_0); + REG_WRITE(ah, AR_PHY_RADAR_1, radar_1); + if (conf->ext_channel) + REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); + else + REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); +} + void ar5008_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1609,6 +1640,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->restore_chainmask = ar5008_restore_chainmask; priv_ops->set_diversity = ar5008_set_diversity; priv_ops->do_getnf = ar5008_hw_do_getnf; + priv_ops->set_radar_params = ar5008_hw_set_radar_params; if (modparam_force_new_ani) { priv_ops->ani_control = ar5008_hw_ani_control_new; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 44c5454b2ad8..f676b21ac437 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1113,6 +1113,37 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; } +static void ar9003_hw_set_radar_params(struct ath_hw *ah, + struct ath_hw_radar_conf *conf) +{ + u32 radar_0 = 0, radar_1 = 0; + + if (!conf) { + REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); + return; + } + + radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA; + radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR); + radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI); + radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT); + radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); + radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); + + radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; + radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; + radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); + radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH); + radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH); + + REG_WRITE(ah, AR_PHY_RADAR_0, radar_0); + REG_WRITE(ah, AR_PHY_RADAR_1, radar_1); + if (conf->ext_channel) + REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); + else + REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); +} + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1141,6 +1172,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->ani_control = ar9003_hw_ani_control; priv_ops->do_getnf = ar9003_hw_do_getnf; priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; + priv_ops->set_radar_params = ar9003_hw_set_radar_params; ar9003_hw_set_nf_limits(ah); memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 15f51c8943a1..c20a5421f870 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -484,6 +484,40 @@ struct ath_hw_antcomb_conf { u8 fast_div_bias; }; +/** + * struct ath_hw_radar_conf - radar detection initialization parameters + * + * @pulse_inband: threshold for checking the ratio of in-band power + * to total power for short radar pulses (half dB steps) + * @pulse_inband_step: threshold for checking an in-band power to total + * power ratio increase for short radar pulses (half dB steps) + * @pulse_height: threshold for detecting the beginning of a short + * radar pulse (dB step) + * @pulse_rssi: threshold for detecting if a short radar pulse is + * gone (dB step) + * @pulse_maxlen: maximum pulse length (0.8 us steps) + * + * @radar_rssi: RSSI threshold for starting long radar detection (dB steps) + * @radar_inband: threshold for checking the ratio of in-band power + * to total power for long radar pulses (half dB steps) + * @fir_power: threshold for detecting the end of a long radar pulse (dB) + * + * @ext_channel: enable extension channel radar detection + */ +struct ath_hw_radar_conf { + unsigned int pulse_inband; + unsigned int pulse_inband_step; + unsigned int pulse_height; + unsigned int pulse_rssi; + unsigned int pulse_maxlen; + + unsigned int radar_rssi; + unsigned int radar_inband; + int fir_power; + + bool ext_channel; +}; + /** * struct ath_hw_private_ops - callbacks used internally by hardware code * @@ -549,6 +583,8 @@ struct ath_hw_private_ops { bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param); void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); + void (*set_radar_params)(struct ath_hw *ah, + struct ath_hw_radar_conf *conf); /* ANI */ void (*ani_cache_ini_regs)(struct ath_hw *ah); -- cgit v1.2.3-59-g8ed1b From a619a4c0e1fd4e8c360c63d0df3fa0a401107d69 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 11 Nov 2010 08:50:18 +0200 Subject: mac80211: Add function to get probe request template for current AP Chipsets with hardware based connection monitoring need to autonomically send directed probe-request frames to the AP (in the event of beacon loss, for example.) For the hardware to be able to do this, it requires a template for the frame to transmit to the AP, filled in with the BSSID and SSID of the AP, but also the supported rate IE's. This patch adds a function to mac80211, which allows the hardware driver to fetch this template after association, so it can be configured to the hardware. Signed-off-by: Juuso Oikarinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 15 +++++++++++++++ net/mac80211/ieee80211_i.h | 4 ++++ net/mac80211/mlme.c | 24 ++++++++++++++++++++++++ net/mac80211/util.c | 23 ++++++++++++++++++----- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a7323eca08d1..af7e84199e62 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2508,6 +2508,21 @@ struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, void ieee80211_sta_block_awake(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, bool block); +/** + * ieee80211_ap_probereq_get - retrieve a Probe Request template + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * Creates a Probe Request template which can, for example, be uploaded to + * hardware. The template is filled with bssid, ssid and supported rate + * information. This function must only be called from within the + * .bss_info_changed callback function and only in managed mode. The function + * is only useful when the interface is associated, otherwise it will return + * NULL. + */ +struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + /** * ieee80211_beacon_loss - inform hardware does not receive beacons * diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b80c38689927..59a1d38212fd 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1287,6 +1287,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, enum ieee80211_band band, u32 rate_mask, u8 channel); +struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, + u8 *dst, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a3a9421555af..dfc4a316ac1c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1108,6 +1108,30 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, mutex_unlock(&ifmgd->mtx); } +struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct sk_buff *skb; + const u8 *ssid; + + if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) + return NULL; + + ASSERT_MGD_MTX(ifmgd); + + if (!ifmgd->associated) + return NULL; + + ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); + skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, + ssid + 2, ssid[1], NULL, 0); + + return skb; +} +EXPORT_SYMBOL(ieee80211_ap_probereq_get); + static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e486286ebf1a..68d0518254dd 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1011,9 +1011,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, return pos - buffer; } -void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len) +struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, + u8 *dst, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb; @@ -1027,7 +1028,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, if (!buf) { printk(KERN_DEBUG "%s: failed to allocate temporary IE " "buffer\n", sdata->name); - return; + return NULL; } chan = ieee80211_frequency_to_channel( @@ -1050,8 +1051,20 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, } IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; - ieee80211_tx_skb(sdata, skb); kfree(buf); + + return skb; +} + +void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len) +{ + struct sk_buff *skb; + + skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len); + if (skb) + ieee80211_tx_skb(sdata, skb); } u32 ieee80211_sta_get_rates(struct ieee80211_local *local, -- cgit v1.2.3-59-g8ed1b From 885a46d0f7942d76c2f3860acb45f75237d3bb42 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 15:07:22 +0100 Subject: cfg80211: add support for setting the ad-hoc multicast rate Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 17c5c8849250..037b4e498890 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -826,6 +826,8 @@ enum nl80211_commands { * the hardware should not be configured to receive on this antenna. * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX. * + * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -998,6 +1000,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_ANTENNA_TX, NL80211_ATTR_WIPHY_ANTENNA_RX, + NL80211_ATTR_MCAST_RATE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 07425e648a09..8fd9eebd0cc9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -923,6 +923,7 @@ struct cfg80211_disassoc_request { * @privacy: this is a protected network, keys will be configured * after joining * @basic_rates: bitmap of basic rates to use when creating the IBSS + * @mcast_rate: multicast tx rate (in 100 kbps) */ struct cfg80211_ibss_params { u8 *ssid; @@ -934,6 +935,7 @@ struct cfg80211_ibss_params { u32 basic_rates; bool channel_fixed; bool privacy; + int mcast_rate; }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5e4dda4c0fd3..605553842226 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -171,6 +171,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, + + [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -3681,6 +3683,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } } + if (info->attrs[NL80211_ATTR_MCAST_RATE]) + ibss.mcast_rate = + nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]); if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { connkeys = nl80211_parse_connkeys(rdev, -- cgit v1.2.3-59-g8ed1b From 8f0729b16ae354f9db89394fc1d2d65003455d56 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 11 Nov 2010 15:07:23 +0100 Subject: mac80211: add support for setting the ad-hoc multicast rate Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/mac80211.h | 6 ++++-- net/mac80211/ibss.c | 1 + net/mac80211/rate.c | 19 +++++++++++++++---- net/mac80211/tx.c | 5 +++-- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index af7e84199e62..1248369a7c30 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -205,6 +205,7 @@ enum ieee80211_bss_change { * @basic_rates: bitmap of basic rates, each bit stands for an * index into the rate table configured by the driver in * the current band. + * @mcast_rate: multicast rate for AP and Ad-Hoc (in 100 kbps) * @bssid: The BSSID for this BSS * @enable_beacon: whether beaconing should be enabled or not * @channel_type: Channel type for this BSS -- the hardware might be @@ -244,6 +245,7 @@ struct ieee80211_bss_conf { u16 assoc_capability; u64 timestamp; u32 basic_rates; + u32 mcast_rate; u16 ht_operation_mode; s32 cqm_rssi_thold; u32 cqm_rssi_hyst; @@ -2663,7 +2665,7 @@ enum rate_control_changed { * @rate_idx_mask: user-requested rate mask (not MCS for now) * @skb: the skb that will be transmitted, the control information in it needs * to be filled in - * @ap: whether this frame is sent out in AP mode + * @bss: whether this frame is sent out in AP or IBSS mode */ struct ieee80211_tx_rate_control { struct ieee80211_hw *hw; @@ -2674,7 +2676,7 @@ struct ieee80211_tx_rate_control { bool rts, short_preamble; u8 max_rate_idx; u32 rate_idx_mask; - bool ap; + bool bss; }; struct rate_control_ops { diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 239c4836a946..6fe6837dc134 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -915,6 +915,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.privacy = params->privacy; sdata->u.ibss.basic_rates = params->basic_rates; + sdata->vif.bss_conf.mcast_rate = params->mcast_rate; sdata->vif.bss_conf.beacon_int = params->beacon_interval; diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 33f76993da08..76de4f8d9327 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -211,10 +211,20 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); } -static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) +static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u32 mcast_rate, + struct ieee80211_supported_band *sband) { u8 i; + if (mcast_rate) { + for (i = 0; i < sband->n_bitrates; i++) { + if (sband->bitrates[i].bitrate == mcast_rate) { + *idx = i; + return; + } + } + } + if (basic_rates == 0) return; /* assume basic rates unknown and accept rate */ if (*idx < 0) @@ -222,7 +232,7 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) if (basic_rates & (1 << *idx)) return; /* selected rate is a basic rate */ - for (i = *idx + 1; i <= max_rate_idx; i++) { + for (i = *idx + 1; i <= sband->n_bitrates; i++) { if (basic_rates & (1 << i)) { *idx = i; return; @@ -243,10 +253,11 @@ bool rate_control_send_low(struct ieee80211_sta *sta, info->control.rates[0].count = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 1 : txrc->hw->max_rate_tries; - if (!sta && txrc->ap) + if (!sta && txrc->bss) rc_send_low_broadcast(&info->control.rates[0].idx, txrc->bss_conf->basic_rates, - txrc->sband->n_bitrates); + txrc->bss_conf->mcast_rate, + txrc->sband); return true; } return false; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b392876af7d8..e69483647f33 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -622,7 +622,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) txrc.max_rate_idx = -1; else txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; - txrc.ap = tx->sdata->vif.type == NL80211_IFTYPE_AP; + txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || + tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); /* set up RTS protection if desired */ if (len > tx->local->hw.wiphy->rts_threshold) { @@ -2308,7 +2309,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, txrc.max_rate_idx = -1; else txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; - txrc.ap = true; + txrc.bss = true; rate_control_get_rate(sdata, NULL, &txrc); info->control.vif = vif; -- cgit v1.2.3-59-g8ed1b From 2cb7865648e44647a976875428c9dfd9d5553221 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 12 Nov 2010 08:47:05 +0100 Subject: iwl3945: remove unused len_org variable Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a55b4623e1c8..6d09c0965645 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -475,7 +475,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) dma_addr_t phys_addr; dma_addr_t txcmd_phys; int txq_id = skb_get_queue_mapping(skb); - u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */ + u16 len, idx, hdr_len; u8 id; u8 unicast; u8 sta_id; @@ -612,15 +612,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) */ len = sizeof(struct iwl3945_tx_cmd) + sizeof(struct iwl_cmd_header) + hdr_len; - - len_org = len; len = (len + 3) & ~3; - if (len_org != len) - len_org = 1; - else - len_org = 0; - /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, -- cgit v1.2.3-59-g8ed1b From 70f3876f09ccf1f2819aee6caee9266b2c4b1622 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 12 Nov 2010 08:47:06 +0100 Subject: iwlagn: simplify iwlagn_tx_skb We can simplify length calculation in iwlagn_tx_skb, that function is enough complex, without fuzz it more than necessary. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 33 +++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 2b078a995729..1205cecfcaf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -522,7 +522,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) dma_addr_t phys_addr; dma_addr_t txcmd_phys; dma_addr_t scratch_phys; - u16 len, len_org, firstlen, secondlen; + u16 len, firstlen, secondlen; u16 seq_number = 0; __le16 fc; u8 hdr_len; @@ -687,30 +687,23 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) */ len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + hdr_len; - - len_org = len; - firstlen = len = (len + 3) & ~3; - - if (len_org != len) - len_org = 1; - else - len_org = 0; + firstlen = (len + 3) & ~3; /* Tell NIC about any 2-byte padding after MAC header */ - if (len_org) + if (firstlen != len) tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ txcmd_phys = pci_map_single(priv->pci_dev, - &out_cmd->hdr, len, + &out_cmd->hdr, firstlen, PCI_DMA_BIDIRECTIONAL); dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, len); + dma_unmap_len_set(out_meta, len, firstlen); /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - txcmd_phys, len, 1, 0); + txcmd_phys, firstlen, 1, 0); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; @@ -721,23 +714,21 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ - secondlen = len = skb->len - hdr_len; - if (len) { + secondlen = skb->len - hdr_len; + if (secondlen > 0) { phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, - len, PCI_DMA_TODEVICE); + secondlen, PCI_DMA_TODEVICE); priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - phys_addr, len, + phys_addr, secondlen, 0, 0); } scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + offsetof(struct iwl_tx_cmd, scratch); - len = sizeof(struct iwl_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; /* take back ownership of DMA buffer to enable update */ pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, - len, PCI_DMA_BIDIRECTIONAL); + firstlen, PCI_DMA_BIDIRECTIONAL); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -753,7 +744,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) le16_to_cpu(tx_cmd->len)); pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, - len, PCI_DMA_BIDIRECTIONAL); + firstlen, PCI_DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(priv, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], -- cgit v1.2.3-59-g8ed1b From ef1b21f7eb074a8c8ddfea70ed70e988545c8d54 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 12 Nov 2010 08:47:07 +0100 Subject: iwlwifi: kill elapsed_jiffies Subtract of jiffies is fine even if one variable overwrap. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-helpers.h | 9 --------- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +-- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 1aaef70deaec..923368304153 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -44,15 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf( return &hw->conf; } -static inline unsigned long elapsed_jiffies(unsigned long start, - unsigned long end) -{ - if (end >= start) - return end - start; - - return end + (MAX_JIFFY_OFFSET - start) + 1; -} - /** * iwl_queue_inc_wrap - increment queue index, wrap back to beginning * @index -- current index diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index e1aa0e1daa5a..12d9363d0afe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -252,8 +252,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n", (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2", - jiffies_to_msecs(elapsed_jiffies - (priv->scan_start, jiffies))); + jiffies_to_msecs(jiffies - priv->scan_start)); queue_work(priv->workqueue, &priv->scan_completed); -- cgit v1.2.3-59-g8ed1b From 28d9cc7f21da6a70fc8c1516fa0ee5588572eb92 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Sat, 13 Nov 2010 20:58:27 +0530 Subject: ath9k_htc: Use macro for caldata array size The calibration data variable size is based on the number of channels available in the ath9k driver. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 75ecf6a30d25..db00289103fc 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -368,7 +368,7 @@ struct ath9k_htc_priv { u16 seq_no; u32 bmiss_cnt; - struct ath9k_hw_cal_data caldata[38]; + struct ath9k_hw_cal_data caldata[ATH9K_NUM_CHANNELS]; spinlock_t beacon_lock; -- cgit v1.2.3-59-g8ed1b From 1a51502bddca7ac1e921d918b741ffd2bec149ed Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Nov 2010 19:26:42 -0800 Subject: ixgbe: delay rx_ring freeing "cat /proc/net/dev" uses RCU protection only. Its quite possible we call a driver get_stats() method while device is dismantling and freeing its data structures. So get_stats() methods must be very careful not accessing driver private data without appropriate locking. In ixgbe case, we access rx_ring pointers. These pointers are freed in ixgbe_clear_interrupt_scheme() and set to NULL, this can trigger NULL dereference in ixgbe_get_stats64() A possible fix is to use RCU locking in ixgbe_get_stats64() and defer rx_ring freeing after a grace period in ixgbe_clear_interrupt_scheme() Signed-off-by: Eric Dumazet Reported-by: Tantilov, Emil S Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 1 + drivers/net/ixgbe/ixgbe_main.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index ed8703cfffb7..018e143612b2 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -192,6 +192,7 @@ struct ixgbe_ring { unsigned int size; /* length in bytes */ dma_addr_t dma; /* phys. address of descriptor ring */ + struct rcu_head rcu; } ____cacheline_internodealigned_in_smp; enum ixgbe_ring_f_enum { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d819608..a137f9dbaacd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4751,6 +4751,11 @@ err_set_interrupt: return err; } +static void ring_free_rcu(struct rcu_head *head) +{ + kfree(container_of(head, struct ixgbe_ring, rcu)); +} + /** * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings * @adapter: board private structure to clear interrupt scheme on @@ -4767,7 +4772,12 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) adapter->tx_ring[i] = NULL; } for (i = 0; i < adapter->num_rx_queues; i++) { - kfree(adapter->rx_ring[i]); + struct ixgbe_ring *ring = adapter->rx_ring[i]; + + /* ixgbe_get_stats64() might access this ring, we must wait + * a grace period before freeing it. + */ + call_rcu(&ring->rcu, ring_free_rcu); adapter->rx_ring[i] = NULL; } @@ -6563,20 +6573,23 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, /* accurate rx/tx bytes/packets stats */ dev_txq_stats_fold(netdev, stats); + rcu_read_lock(); for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; + struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]); u64 bytes, packets; unsigned int start; - do { - start = u64_stats_fetch_begin_bh(&ring->syncp); - packets = ring->stats.packets; - bytes = ring->stats.bytes; - } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); - stats->rx_packets += packets; - stats->rx_bytes += bytes; + if (ring) { + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } } - + rcu_read_unlock(); /* following stats updated by ixgbe_watchdog_task() */ stats->multicast = netdev->stats.multicast; stats->rx_errors = netdev->stats.rx_errors; @@ -7282,6 +7295,7 @@ static void __exit ixgbe_exit_module(void) dca_unregister_notify(&dca_notifier); #endif pci_unregister_driver(&ixgbe_driver); + rcu_barrier(); /* Wait for completion of call_rcu()'s */ } #ifdef CONFIG_IXGBE_DCA -- cgit v1.2.3-59-g8ed1b From 66c87bd50ddae681ebedfda0d75e6e73ecd29ce7 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 16 Nov 2010 19:26:43 -0800 Subject: ixgbevf: Update Version String and Copyright Notice Update version string and copyright notice. Signed-off-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/Makefile | 2 +- drivers/net/ixgbevf/defines.h | 2 +- drivers/net/ixgbevf/ixgbevf.h | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 7 ++++--- drivers/net/ixgbevf/mbx.c | 2 +- drivers/net/ixgbevf/mbx.h | 2 +- drivers/net/ixgbevf/regs.h | 2 +- drivers/net/ixgbevf/vf.c | 2 +- drivers/net/ixgbevf/vf.h | 2 +- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbevf/Makefile b/drivers/net/ixgbevf/Makefile index dd4e0d27e8cc..1f35d229e71a 100644 --- a/drivers/net/ixgbevf/Makefile +++ b/drivers/net/ixgbevf/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel 82599 Virtual Function driver -# Copyright(c) 1999 - 2009 Intel Corporation. +# Copyright(c) 1999 - 2010 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/defines.h b/drivers/net/ixgbevf/defines.h index ca2c81f49a05..f8a807d606c7 100644 --- a/drivers/net/ixgbevf/defines.h +++ b/drivers/net/ixgbevf/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index da4033c6efa2..0cd6abcf9306 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index dc03c9652389..1d7de555e630 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -51,9 +51,10 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 82599 Virtual Function"; -#define DRV_VERSION "1.0.0-k0" +#define DRV_VERSION "1.0.12-k0" const char ixgbevf_driver_version[] = DRV_VERSION; -static char ixgbevf_copyright[] = "Copyright (c) 2009 Intel Corporation."; +static char ixgbevf_copyright[] = + "Copyright (c) 2009 - 2010 Intel Corporation."; static const struct ixgbevf_info *ixgbevf_info_tbl[] = { [board_82599_vf] = &ixgbevf_vf_info, diff --git a/drivers/net/ixgbevf/mbx.c b/drivers/net/ixgbevf/mbx.c index 84ac486f4a65..7a8833125770 100644 --- a/drivers/net/ixgbevf/mbx.c +++ b/drivers/net/ixgbevf/mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h index 8c063bebee7f..b2b5bf5daa3d 100644 --- a/drivers/net/ixgbevf/mbx.h +++ b/drivers/net/ixgbevf/mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/regs.h b/drivers/net/ixgbevf/regs.h index 12f75960aec1..fb80ca1bcc93 100644 --- a/drivers/net/ixgbevf/regs.h +++ b/drivers/net/ixgbevf/regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c index bfe42c1fcfaf..971019d819b4 100644 --- a/drivers/net/ixgbevf/vf.c +++ b/drivers/net/ixgbevf/vf.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 61f9dc831424..144c99d5363a 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-59-g8ed1b From 16b61beb39f2446460f93c08d4d263dc24f22dd8 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 16 Nov 2010 19:26:44 -0800 Subject: ixgbe: DCB set PFC high and low water marks per data sheet specs Currently the high and low water marks for PFC are being set conservatively for jumbo frames. This means the RX buffers are being underutilized in the default 1500 MTU. This patch fixes this so that the water marks are set as described in the data sheet considering the MTU size. The equation used is, RTT * 1.44 + MTU * 1.44 + MTU Where RTT is the round trip time and MTU is the max frame size in KB. To avoid floating point arithmetic FC_HIGH_WATER is defined ((((RTT + MTU) * 144) + 99) / 100) + MTU This changes how the hardware field fc.low_water and fc.high_water are used. With this change they are no longer storing the actual low water and high water markers but are storing the required head room in the buffer. This simplifies the logic and we do not need to account for the size of the buffer when setting the thresholds. Testing with iperf and 16 threads showed a slight uptick in throughput over a single traffic class .1-.2Gbps and a reduction in pause frames. Without the patch a 30 second run would show ~10-15 pause frames being transmitted with the patch ~2-5 are seen. Test were run back to back with 82599. Note RXPBSIZE is in KB and low and high water marks fields are also in KB. However the FCRT* registers are 32B granularity and right shifted 5 into the register, (((rx_pbsize - water_mark) * 1024) / 32) << 5 is the most explicit conversion here we simplify (rx_pbsize - water_mark) * 32 << 5 = (rx_pbsize - water_mark) << 10 This patch updates the PFC thresholds and legacy FC thresholds. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 -- drivers/net/ixgbe/ixgbe_82598.c | 21 ++++++++++-------- drivers/net/ixgbe/ixgbe_common.c | 43 +++++++++++-------------------------- drivers/net/ixgbe/ixgbe_dcb_82598.c | 12 ++++------- drivers/net/ixgbe/ixgbe_dcb_82599.c | 12 +++++------ drivers/net/ixgbe/ixgbe_main.c | 9 ++++++-- drivers/net/ixgbe/ixgbe_type.h | 8 +++++++ 7 files changed, 48 insertions(+), 59 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 018e143612b2..4f98486d8c2c 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -61,10 +61,8 @@ #define IXGBE_MIN_RXD 64 /* flow control */ -#define IXGBE_DEFAULT_FCRTL 0x10000 #define IXGBE_MIN_FCRTL 0x40 #define IXGBE_MAX_FCRTL 0x7FF80 -#define IXGBE_DEFAULT_FCRTH 0x20000 #define IXGBE_MIN_FCRTH 0x600 #define IXGBE_MAX_FCRTH 0x7FFF0 #define IXGBE_DEFAULT_FCPAUSE 0xFFFF diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 9c02d6014cc4..25b20f93190a 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -357,6 +357,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) u32 fctrl_reg; u32 rmcs_reg; u32 reg; + u32 rx_pba_size; u32 link_speed = 0; bool link_up; @@ -459,16 +460,18 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) /* Set up and enable Rx high/low water mark thresholds, enable XON. */ if (hw->fc.current_mode & ixgbe_fc_tx_pause) { - if (hw->fc.send_xon) { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), - (hw->fc.low_water | IXGBE_FCRTL_XONE)); - } else { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), - hw->fc.low_water); - } + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); + rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; + + reg = (rx_pba_size - hw->fc.low_water) << 6; + if (hw->fc.send_xon) + reg |= IXGBE_FCRTL_XONE; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg); + + reg = (rx_pba_size - hw->fc.high_water) << 10; + reg |= IXGBE_FCRTH_FCEN; - IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), - (hw->fc.high_water | IXGBE_FCRTH_FCEN)); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg); } /* Configure pause time (2 TCs per register) */ diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index e3eca1316389..62aa2be199f1 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1595,6 +1595,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) u32 mflcn_reg, fccfg_reg; u32 reg; u32 rx_pba_size; + u32 fcrtl, fcrth; #ifdef CONFIG_DCB if (hw->fc.requested_mode == ixgbe_fc_pfc) @@ -1671,41 +1672,21 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); - reg = IXGBE_READ_REG(hw, IXGBE_MTQC); - /* Thresholds are different for link flow control when in DCB mode */ - if (reg & IXGBE_MTQC_RT_ENA) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); + rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; - /* Always disable XON for LFC when in DCB mode */ - reg = (rx_pba_size >> 5) & 0xFFE0; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg); + fcrth = (rx_pba_size - hw->fc.high_water) << 10; + fcrtl = (rx_pba_size - hw->fc.low_water) << 10; - reg = (rx_pba_size >> 2) & 0xFFE0; - if (hw->fc.current_mode & ixgbe_fc_tx_pause) - reg |= IXGBE_FCRTH_FCEN; - IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg); - } else { - /* - * Set up and enable Rx high/low water mark thresholds, - * enable XON. - */ - if (hw->fc.current_mode & ixgbe_fc_tx_pause) { - if (hw->fc.send_xon) { - IXGBE_WRITE_REG(hw, - IXGBE_FCRTL_82599(packetbuf_num), - (hw->fc.low_water | - IXGBE_FCRTL_XONE)); - } else { - IXGBE_WRITE_REG(hw, - IXGBE_FCRTL_82599(packetbuf_num), - hw->fc.low_water); - } - - IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), - (hw->fc.high_water | IXGBE_FCRTH_FCEN)); - } + if (hw->fc.current_mode & ixgbe_fc_tx_pause) { + fcrth |= IXGBE_FCRTH_FCEN; + if (hw->fc.send_xon) + fcrtl |= IXGBE_FCRTL_XONE; } + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth); + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl); + /* Configure pause time (2 TCs per register) */ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); if ((packetbuf_num & 1) == 0) diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 50288bcadc59..9a5e89c12e05 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -256,21 +256,17 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, * for each traffic class. */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - if (dcb_config->rx_pba_cfg == pba_equal) { - rx_pba_size = IXGBE_RXPBSIZE_64KB; - } else { - rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB - : IXGBE_RXPBSIZE_48KB; - } + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); + rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; + reg = (rx_pba_size - hw->fc.low_water) << 10; - reg = ((rx_pba_size >> 5) & 0xFFF0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); - reg = ((rx_pba_size >> 2) & 0xFFF0); + reg = (rx_pba_size - hw->fc.high_water) << 10; if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) reg |= IXGBE_FCRTH_FCEN; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 05f224715073..374e1f74d0f5 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -251,19 +251,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, /* Configure PFC Tx thresholds per TC */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - if (dcb_config->rx_pba_cfg == pba_equal) - rx_pba_size = IXGBE_RXPBSIZE_64KB; - else - rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB - : IXGBE_RXPBSIZE_48KB; + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); + rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; + + reg = (rx_pba_size - hw->fc.low_water) << 10; - reg = ((rx_pba_size >> 5) & 0xFFE0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); - reg = ((rx_pba_size >> 2) & 0xFFE0); + reg = (rx_pba_size - hw->fc.high_water) << 10; if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) reg |= IXGBE_FCRTH_FCEN; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a137f9dbaacd..f374207e14b4 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4854,6 +4854,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) int j; struct tc_configuration *tc; #endif + int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; /* PCI config space info */ @@ -4930,8 +4931,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) #ifdef CONFIG_DCB adapter->last_lfc_mode = hw->fc.current_mode; #endif - hw->fc.high_water = IXGBE_DEFAULT_FCRTH; - hw->fc.low_water = IXGBE_DEFAULT_FCRTL; + hw->fc.high_water = FC_HIGH_WATER(max_frame); + hw->fc.low_water = FC_LOW_WATER(max_frame); hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; hw->fc.send_xon = true; hw->fc.disable_fc_autoneg = false; @@ -5193,6 +5194,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* MTU < 68 is an error and causes problems on some kernels */ @@ -5203,6 +5205,9 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; + hw->fc.high_water = FC_HIGH_WATER(max_frame); + hw->fc.low_water = FC_LOW_WATER(max_frame); + if (netif_running(netdev)) ixgbe_reinit_locked(adapter); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index d3cc6ce7c973..96dea7731e68 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2113,6 +2113,14 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 #define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 +/* Flow Control Macros */ +#define PAUSE_RTT 8 +#define PAUSE_MTU(MTU) ((MTU + 1024 - 1) / 1024) + +#define FC_HIGH_WATER(MTU) ((((PAUSE_RTT + PAUSE_MTU(MTU)) * 144) + 99) / 100 +\ + PAUSE_MTU(MTU)) +#define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT)) + /* Software ATR hash keys */ #define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D #define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 -- cgit v1.2.3-59-g8ed1b From 80ab193dce048e7b7afa43c99e69f508167e29ab Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 16 Nov 2010 19:26:45 -0800 Subject: ixgbe: DCB: credit max only needs to be gt TSO size for 82598 The maximum credits per traffic class only needs to be greater then the TSO size for 82598 devices. The 82599 devices do not have this requirement so only do this test for 82598 devices. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.c | 6 ++++-- drivers/net/ixgbe/ixgbe_dcb.h | 3 ++- drivers/net/ixgbe/ixgbe_main.c | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 0d44c6470ca3..4f2f0ae67354 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -42,7 +42,8 @@ * It should be called only after the rules are checked by * ixgbe_dcb_check_config(). */ -s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, +s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config, int max_frame, u8 direction) { struct tc_bw_alloc *p; @@ -124,7 +125,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, * credit may not be enough to send out a TSO * packet in descriptor plane arbitration. */ - if (credit_max && + if ((hw->mac.type == ixgbe_mac_82598EB) && + credit_max && (credit_max < MINIMUM_CREDIT_FOR_TSO)) credit_max = MINIMUM_CREDIT_FOR_TSO; diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 0208a87b129e..1cfe38ee1644 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -150,7 +150,8 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ /* DCB credits calculation */ -s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8); +s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, + struct ixgbe_dcb_config *, int, u8); /* DCB hw initialization */ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f374207e14b4..45d988741fe9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3366,9 +3366,9 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, + ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, + ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, DCB_RX_CONFIG); /* reconfigure the hardware */ -- cgit v1.2.3-59-g8ed1b From 4c0ec6544a0cd5e3eed08df2c14cf98185098abe Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:46 -0800 Subject: ixgbe: remove unnecessary re-init of adapter on Rx-csum change There is no need to reset the adapter when changing the Rx checksum settings. Since the only change is a software flag we can disable it without needing to reset the entire adapter. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 3dc731c22ff2..81fa1ac1c9ba 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -412,11 +412,6 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) else adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); - return 0; } -- cgit v1.2.3-59-g8ed1b From 8ad494b0e59950e2b4e587c32cb67a2452795ea0 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:47 -0800 Subject: ixgbe: move GSO segments and byte count processing into ixgbe_tx_map This change simplifies the work being done by the TX interrupt handler and pushes it into the tx_map call. This allows for fewer cache misses since the TX cleanup now accesses almost none of the skb members. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 ++- drivers/net/ixgbe/ixgbe_main.c | 57 ++++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 4f98486d8c2c..93946b683ad8 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -128,7 +128,9 @@ struct ixgbe_tx_buffer { unsigned long time_stamp; u16 length; u16 next_to_watch; - u16 mapped_as_page; + unsigned int bytecount; + u16 gso_segs; + u8 mapped_as_page; }; struct ixgbe_rx_buffer { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 45d988741fe9..480f0b0f038a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -749,45 +749,23 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, bool cleaned = false; rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { - struct sk_buff *skb; tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; + + tx_desc->wb.status = 0; cleaned = (i == eop); - skb = tx_buffer_info->skb; - if (cleaned && skb) { - unsigned int segs, bytecount; - unsigned int hlen = skb_headlen(skb); + i++; + if (i == tx_ring->count) + i = 0; - /* gso_segs is currently only valid for tcp */ - segs = skb_shinfo(skb)->gso_segs ?: 1; -#ifdef IXGBE_FCOE - /* adjust for FCoE Sequence Offload */ - if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) - && skb_is_gso(skb) - && vlan_get_protocol(skb) == - htons(ETH_P_FCOE)) { - hlen = skb_transport_offset(skb) + - sizeof(struct fc_frame_header) + - sizeof(struct fcoe_crc_eof); - segs = DIV_ROUND_UP(skb->len - hlen, - skb_shinfo(skb)->gso_size); - } -#endif /* IXGBE_FCOE */ - /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * hlen) + skb->len; - total_packets += segs; - total_bytes += bytecount; + if (cleaned && tx_buffer_info->skb) { + total_bytes += tx_buffer_info->bytecount; + total_packets += tx_buffer_info->gso_segs; } ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); - - tx_desc->wb.status = 0; - - i++; - if (i == tx_ring->count) - i = 0; } eop = tx_ring->tx_buffer_info[i].next_to_watch; @@ -6015,7 +5993,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, static int ixgbe_tx_map(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, - unsigned int first) + unsigned int first, const u8 hdr_len) { struct pci_dev *pdev = adapter->pdev; struct ixgbe_tx_buffer *tx_buffer_info; @@ -6024,6 +6002,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, unsigned int offset = 0, size, count = 0, i; unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; + unsigned int bytecount = skb->len; + u16 gso_segs = 1; i = tx_ring->next_to_use; @@ -6093,6 +6073,19 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, break; } + if (tx_flags & IXGBE_TX_FLAGS_TSO) + gso_segs = skb_shinfo(skb)->gso_segs; +#ifdef IXGBE_FCOE + /* adjust for FCoE Sequence Offload */ + else if (tx_flags & IXGBE_TX_FLAGS_FSO) + gso_segs = DIV_ROUND_UP(skb->len - hdr_len, + skb_shinfo(skb)->gso_size); +#endif /* IXGBE_FCOE */ + bytecount += (gso_segs - 1) * hdr_len; + + /* multiply data chunks by size of headers */ + tx_ring->tx_buffer_info[i].bytecount = bytecount; + tx_ring->tx_buffer_info[i].gso_segs = gso_segs; tx_ring->tx_buffer_info[i].skb = skb; tx_ring->tx_buffer_info[first].next_to_watch = i; @@ -6402,7 +6395,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev tx_flags |= IXGBE_TX_FLAGS_CSUM; } - count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first); + count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first, hdr_len); if (count) { /* add the ATR filter if ATR is on */ if (tx_ring->atr_sample_rate) { -- cgit v1.2.3-59-g8ed1b From d5f398ed73522b9f76861af6553775c5851de0d0 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:48 -0800 Subject: ixgbe: cleanup ixgbe_alloc_rx_buffers This change re-orders alloc_rx_buffers to make better use of the packet split enabled flag. The new setup should require less branching in the code since now we are down to fewer if statements since we either are handling packet split or aren't. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 +- drivers/net/ixgbe/ixgbe_main.c | 81 ++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 93946b683ad8..149cf26b2545 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -472,7 +472,7 @@ extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *, struct ixgbe_tx_buffer *); extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, - int cleaned_count); + u16 cleaned_count); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 480f0b0f038a..e838479d2d95 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1010,63 +1010,70 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, **/ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, - int cleaned_count) + u16 cleaned_count) { - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; - unsigned int i; - unsigned int bufsz = rx_ring->rx_buf_len; - - i = rx_ring->next_to_use; - bi = &rx_ring->rx_buffer_info[i]; + struct sk_buff *skb; + u16 i = rx_ring->next_to_use; while (cleaned_count--) { rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); + bi = &rx_ring->rx_buffer_info[i]; + skb = bi->skb; - if (!bi->page_dma && - (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) { - if (!bi->page) { - bi->page = netdev_alloc_page(netdev); - if (!bi->page) { - adapter->alloc_rx_page_failed++; - goto no_buffers; - } - bi->page_offset = 0; - } else { - /* use a half page if we're re-using */ - bi->page_offset ^= (PAGE_SIZE / 2); - } - - bi->page_dma = dma_map_page(&pdev->dev, bi->page, - bi->page_offset, - (PAGE_SIZE / 2), - DMA_FROM_DEVICE); - } - - if (!bi->skb) { - struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, - bufsz); - bi->skb = skb; - + if (!skb) { + skb = netdev_alloc_skb_ip_align(adapter->netdev, + rx_ring->rx_buf_len); if (!skb) { adapter->alloc_rx_buff_failed++; goto no_buffers; } /* initialize queue mapping */ skb_record_rx_queue(skb, rx_ring->queue_index); + bi->skb = skb; } if (!bi->dma) { bi->dma = dma_map_single(&pdev->dev, - bi->skb->data, + skb->data, rx_ring->rx_buf_len, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, bi->dma)) { + adapter->alloc_rx_buff_failed++; + bi->dma = 0; + goto no_buffers; + } } - /* Refresh the desc even if buffer_addrs didn't change because - * each write-back erases this info. */ + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (!bi->page) { + bi->page = netdev_alloc_page(adapter->netdev); + if (!bi->page) { + adapter->alloc_rx_page_failed++; + goto no_buffers; + } + } + + if (!bi->page_dma) { + /* use a half page if we're re-using */ + bi->page_offset ^= PAGE_SIZE / 2; + bi->page_dma = dma_map_page(&pdev->dev, + bi->page, + bi->page_offset, + PAGE_SIZE / 2, + DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, + bi->page_dma)) { + adapter->alloc_rx_page_failed++; + bi->page_dma = 0; + goto no_buffers; + } + } + + /* Refresh the desc even if buffer_addrs didn't change + * because each write-back erases this info. */ rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); } else { @@ -1077,15 +1084,11 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, i++; if (i == rx_ring->count) i = 0; - bi = &rx_ring->rx_buffer_info[i]; } no_buffers: if (rx_ring->next_to_use != i) { rx_ring->next_to_use = i; - if (i-- == 0) - i = (rx_ring->count - 1); - ixgbe_release_rx_desc(&adapter->hw, rx_ring, i); } } -- cgit v1.2.3-59-g8ed1b From 84ea2591e4a24775c2735511a1cc3cf88edd249d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:49 -0800 Subject: ixgbe: drop ring->head, make ring->tail a pointer instead of offset This change drops ring->head since it is not used in any hot-path and can easily be determined using IXGBE_[RT]DH(ring->reg_idx). It also changes ring->tail into a true pointer so we can avoid unnecessary pointer math to find the location of the tail. In addition I also dropped the setting of head and tail in ixgbe_clean_[rx|tx]_ring. The only location that should be setting the head and tail values is ixgbe_configure_[rx|tx]_ring and that is only while the queue is disabled. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 3 +-- drivers/net/ixgbe/ixgbe_main.c | 35 ++++++++++------------------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 149cf26b2545..c993fc3ab8a5 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -163,8 +163,7 @@ struct ixgbe_ring { #define IXGBE_RING_RX_PS_ENABLED (u8)(1) u8 flags; /* per ring feature flags */ - u16 head; - u16 tail; + u8 __iomem *tail; unsigned int total_bytes; unsigned int total_packets; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e838479d2d95..8f2afaa35dd9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -704,8 +704,8 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, " time_stamp <%lx>\n" " jiffies <%lx>\n", tx_ring->queue_index, - IXGBE_READ_REG(hw, tx_ring->head), - IXGBE_READ_REG(hw, tx_ring->tail), + IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)), + IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)), tx_ring->next_to_use, eop, tx_ring->tx_buffer_info[eop].time_stamp, jiffies); return true; @@ -991,8 +991,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, skb->ip_summed = CHECKSUM_UNNECESSARY; } -static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, - struct ixgbe_ring *rx_ring, u32 val) +static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) { /* * Force memory writes to complete before letting h/w @@ -1001,7 +1000,7 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, * such as IA-64). */ wmb(); - IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val); + writel(val, rx_ring->tail); } /** @@ -1089,7 +1088,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, no_buffers: if (rx_ring->next_to_use != i) { rx_ring->next_to_use = i; - ixgbe_release_rx_desc(&adapter->hw, rx_ring, i); + ixgbe_release_rx_desc(rx_ring, i); } } @@ -2465,8 +2464,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, ring->count * sizeof(union ixgbe_adv_tx_desc)); IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0); IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0); - ring->head = IXGBE_TDH(reg_idx); - ring->tail = IXGBE_TDT(reg_idx); + ring->tail = hw->hw_addr + IXGBE_TDT(reg_idx); /* configure fetching thresholds */ if (adapter->rx_itr_setting == 0) { @@ -2791,8 +2789,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, ring->count * sizeof(union ixgbe_adv_rx_desc)); IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0); IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); - ring->head = IXGBE_RDH(reg_idx); - ring->tail = IXGBE_RDT(reg_idx); + ring->tail = hw->hw_addr + IXGBE_RDT(reg_idx); ixgbe_configure_srrctl(adapter, ring); ixgbe_configure_rscctl(adapter, ring); @@ -3730,11 +3727,6 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; - - if (rx_ring->head) - writel(0, adapter->hw.hw_addr + rx_ring->head); - if (rx_ring->tail) - writel(0, adapter->hw.hw_addr + rx_ring->tail); } /** @@ -3767,11 +3759,6 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - - if (tx_ring->head) - writel(0, adapter->hw.hw_addr + tx_ring->head); - if (tx_ring->tail) - writel(0, adapter->hw.hw_addr + tx_ring->tail); } /** @@ -6116,8 +6103,7 @@ dma_error: return 0; } -static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, +static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring, int tx_flags, int count, u32 paylen, u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; @@ -6182,7 +6168,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, wmb(); tx_ring->next_to_use = i; - writel(i, adapter->hw.hw_addr + tx_ring->tail); + writel(i, tx_ring->tail); } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, @@ -6414,8 +6400,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev txq = netdev_get_tx_queue(netdev, tx_ring->queue_index); txq->tx_bytes += skb->len; txq->tx_packets++; - ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, - hdr_len); + ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len); ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); } else { -- cgit v1.2.3-59-g8ed1b From b6ec895ecd32c0070c3b2b17918c030275cd834d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:49 -0800 Subject: ixgbe: move device pointer into the ring structure This change is meant to simplify DMA map/unmap by providing a device pointer. As a result the adapter pointer can be dropped from many of the calls. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 11 +-- drivers/net/ixgbe/ixgbe_ethtool.c | 32 ++++---- drivers/net/ixgbe/ixgbe_main.c | 157 ++++++++++++++++++-------------------- 3 files changed, 93 insertions(+), 107 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index c993fc3ab8a5..70ccab074658 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -148,6 +148,7 @@ struct ixgbe_queue_stats { struct ixgbe_ring { void *desc; /* descriptor ring memory */ + struct device *dev; /* device for DMA mapping */ union { struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info; @@ -454,10 +455,10 @@ extern void ixgbe_down(struct ixgbe_adapter *adapter); extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); extern void ixgbe_reset(struct ixgbe_adapter *adapter); extern void ixgbe_set_ethtool_ops(struct net_device *netdev); -extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); -extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); -extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); -extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern int ixgbe_setup_rx_resources(struct ixgbe_ring *); +extern int ixgbe_setup_tx_resources(struct ixgbe_ring *); +extern void ixgbe_free_rx_resources(struct ixgbe_ring *); +extern void ixgbe_free_tx_resources(struct ixgbe_ring *); extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); @@ -467,7 +468,7 @@ extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct net_device *, struct ixgbe_adapter *, struct ixgbe_ring *); -extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *, +extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, struct ixgbe_tx_buffer *); extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 81fa1ac1c9ba..cc7804962b2e 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -900,13 +900,11 @@ static int ixgbe_set_ringparam(struct net_device *netdev, memcpy(&temp_tx_ring[i], adapter->tx_ring[i], sizeof(struct ixgbe_ring)); temp_tx_ring[i].count = new_tx_count; - err = ixgbe_setup_tx_resources(adapter, - &temp_tx_ring[i]); + err = ixgbe_setup_tx_resources(&temp_tx_ring[i]); if (err) { while (i) { i--; - ixgbe_free_tx_resources(adapter, - &temp_tx_ring[i]); + ixgbe_free_tx_resources(&temp_tx_ring[i]); } goto clear_reset; } @@ -925,13 +923,11 @@ static int ixgbe_set_ringparam(struct net_device *netdev, memcpy(&temp_rx_ring[i], adapter->rx_ring[i], sizeof(struct ixgbe_ring)); temp_rx_ring[i].count = new_rx_count; - err = ixgbe_setup_rx_resources(adapter, - &temp_rx_ring[i]); + err = ixgbe_setup_rx_resources(&temp_rx_ring[i]); if (err) { while (i) { i--; - ixgbe_free_rx_resources(adapter, - &temp_rx_ring[i]); + ixgbe_free_rx_resources(&temp_rx_ring[i]); } goto err_setup; } @@ -946,8 +942,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* tx */ if (new_tx_count != adapter->tx_ring_count) { for (i = 0; i < adapter->num_tx_queues; i++) { - ixgbe_free_tx_resources(adapter, - adapter->tx_ring[i]); + ixgbe_free_tx_resources(adapter->tx_ring[i]); memcpy(adapter->tx_ring[i], &temp_tx_ring[i], sizeof(struct ixgbe_ring)); } @@ -957,8 +952,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* rx */ if (new_rx_count != adapter->rx_ring_count) { for (i = 0; i < adapter->num_rx_queues; i++) { - ixgbe_free_rx_resources(adapter, - adapter->rx_ring[i]); + ixgbe_free_rx_resources(adapter->rx_ring[i]); memcpy(adapter->rx_ring[i], &temp_rx_ring[i], sizeof(struct ixgbe_ring)); } @@ -1463,8 +1457,8 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) ixgbe_reset(adapter); - ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring); - ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring); + ixgbe_free_tx_resources(&adapter->test_tx_ring); + ixgbe_free_rx_resources(&adapter->test_rx_ring); } static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) @@ -1478,10 +1472,11 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) /* Setup Tx descriptor ring and Tx buffers */ tx_ring->count = IXGBE_DEFAULT_TXD; tx_ring->queue_index = 0; + tx_ring->dev = &adapter->pdev->dev; tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; tx_ring->numa_node = adapter->node; - err = ixgbe_setup_tx_resources(adapter, tx_ring); + err = ixgbe_setup_tx_resources(tx_ring); if (err) return 1; @@ -1496,11 +1491,12 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) /* Setup Rx Descriptor ring and Rx buffers */ rx_ring->count = IXGBE_DEFAULT_RXD; rx_ring->queue_index = 0; + rx_ring->dev = &adapter->pdev->dev; rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048; rx_ring->numa_node = adapter->node; - err = ixgbe_setup_rx_resources(adapter, rx_ring); + err = ixgbe_setup_rx_resources(rx_ring); if (err) { ret_val = 4; goto err_nomem; @@ -1622,7 +1618,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; /* unmap Rx buffer, will be remapped by alloc_rx_buffers */ - dma_unmap_single(&adapter->pdev->dev, + dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, bufsz, DMA_FROM_DEVICE); @@ -1634,7 +1630,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, /* unmap buffer on Tx side */ tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; - ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); /* increment Rx/Tx next to clean counters */ rx_ntc++; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 8f2afaa35dd9..be76dd9b94a9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -600,18 +600,17 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, } } -void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, - struct ixgbe_tx_buffer - *tx_buffer_info) +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *tx_buffer_info) { if (tx_buffer_info->dma) { if (tx_buffer_info->mapped_as_page) - dma_unmap_page(&adapter->pdev->dev, + dma_unmap_page(tx_ring->dev, tx_buffer_info->dma, tx_buffer_info->length, DMA_TO_DEVICE); else - dma_unmap_single(&adapter->pdev->dev, + dma_unmap_single(tx_ring->dev, tx_buffer_info->dma, tx_buffer_info->length, DMA_TO_DEVICE); @@ -764,7 +763,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, total_packets += tx_buffer_info->gso_segs; } - ixgbe_unmap_and_free_tx_resource(adapter, + ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); } @@ -1011,7 +1010,6 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, u16 cleaned_count) { - struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; struct sk_buff *skb; @@ -1035,11 +1033,11 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, } if (!bi->dma) { - bi->dma = dma_map_single(&pdev->dev, + bi->dma = dma_map_single(rx_ring->dev, skb->data, rx_ring->rx_buf_len, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, bi->dma)) { + if (dma_mapping_error(rx_ring->dev, bi->dma)) { adapter->alloc_rx_buff_failed++; bi->dma = 0; goto no_buffers; @@ -1058,12 +1056,12 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->page_dma) { /* use a half page if we're re-using */ bi->page_offset ^= PAGE_SIZE / 2; - bi->page_dma = dma_map_page(&pdev->dev, + bi->page_dma = dma_map_page(rx_ring->dev, bi->page, bi->page_offset, PAGE_SIZE / 2, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, + if (dma_mapping_error(rx_ring->dev, bi->page_dma)) { adapter->alloc_rx_page_failed++; bi->page_dma = 0; @@ -1151,7 +1149,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, int *work_done, int work_to_do) { struct ixgbe_adapter *adapter = q_vector->adapter; - struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; struct sk_buff *skb; @@ -1208,7 +1205,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->delay_unmap = true; IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; } else { - dma_unmap_single(&pdev->dev, + dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); @@ -1218,8 +1215,10 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } if (upper_len) { - dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, - PAGE_SIZE / 2, DMA_FROM_DEVICE); + dma_unmap_page(rx_ring->dev, + rx_buffer_info->page_dma, + PAGE_SIZE / 2, + DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, rx_buffer_info->page, @@ -1262,7 +1261,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, &(rx_ring->rsc_count)); if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { if (IXGBE_RSC_CB(skb)->delay_unmap) { - dma_unmap_single(&pdev->dev, + dma_unmap_single(rx_ring->dev, IXGBE_RSC_CB(skb)->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); @@ -3665,15 +3664,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) /** * ixgbe_clean_rx_ring - Free Rx Buffers per Queue - * @adapter: board private structure * @rx_ring: ring to free buffers from **/ -static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) +static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) { - struct pci_dev *pdev = adapter->pdev; + struct device *dev = rx_ring->dev; unsigned long size; - unsigned int i; + u16 i; /* ring already cleared, nothing to do */ if (!rx_ring->rx_buffer_info) @@ -3685,7 +3682,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_buffer_info = &rx_ring->rx_buffer_info[i]; if (rx_buffer_info->dma) { - dma_unmap_single(&pdev->dev, rx_buffer_info->dma, + dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); rx_buffer_info->dma = 0; @@ -3696,7 +3693,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, do { struct sk_buff *this = skb; if (IXGBE_RSC_CB(this)->delay_unmap) { - dma_unmap_single(&pdev->dev, + dma_unmap_single(dev, IXGBE_RSC_CB(this)->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); @@ -3710,7 +3707,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, if (!rx_buffer_info->page) continue; if (rx_buffer_info->page_dma) { - dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, + dma_unmap_page(dev, rx_buffer_info->page_dma, PAGE_SIZE / 2, DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; } @@ -3731,15 +3728,13 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, /** * ixgbe_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure * @tx_ring: ring to be cleaned **/ -static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) +static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned long size; - unsigned int i; + u16 i; /* ring already cleared, nothing to do */ if (!tx_ring->tx_buffer_info) @@ -3748,7 +3743,7 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, /* Free all the Tx ring sk_buffs */ for (i = 0; i < tx_ring->count; i++) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; - ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); } size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; @@ -3770,7 +3765,7 @@ static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter) int i; for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_clean_rx_ring(adapter, adapter->rx_ring[i]); + ixgbe_clean_rx_ring(adapter->rx_ring[i]); } /** @@ -3782,7 +3777,7 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) int i; for (i = 0; i < adapter->num_tx_queues; i++) - ixgbe_clean_tx_ring(adapter, adapter->tx_ring[i]); + ixgbe_clean_tx_ring(adapter->tx_ring[i]); } void ixgbe_down(struct ixgbe_adapter *adapter) @@ -4440,6 +4435,7 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) { int i; + int rx_count; int orig_node = adapter->node; for (i = 0; i < adapter->num_tx_queues; i++) { @@ -4458,6 +4454,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) goto err_tx_ring_allocation; ring->count = adapter->tx_ring_count; ring->queue_index = i; + ring->dev = &adapter->pdev->dev; ring->numa_node = adapter->node; adapter->tx_ring[i] = ring; @@ -4466,6 +4463,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) /* Restore the adapter's original node */ adapter->node = orig_node; + rx_count = adapter->rx_ring_count; for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i]; if (orig_node == -1) { @@ -4480,8 +4478,9 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) goto err_rx_ring_allocation; - ring->count = adapter->rx_ring_count; + ring->count = rx_count; ring->queue_index = i; + ring->dev = &adapter->pdev->dev; ring->numa_node = adapter->node; adapter->rx_ring[i] = ring; @@ -4938,15 +4937,13 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) /** * ixgbe_setup_tx_resources - allocate Tx resources (Descriptors) - * @adapter: board private structure * @tx_ring: tx descriptor ring (for a specific queue) to setup * * Return 0 on success, negative on failure **/ -int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) +int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) { - struct pci_dev *pdev = adapter->pdev; + struct device *dev = tx_ring->dev; int size; size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; @@ -4961,7 +4958,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); tx_ring->size = ALIGN(tx_ring->size, 4096); - tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, + tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size, &tx_ring->dma, GFP_KERNEL); if (!tx_ring->desc) goto err; @@ -4974,7 +4971,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, err: vfree(tx_ring->tx_buffer_info); tx_ring->tx_buffer_info = NULL; - e_err(probe, "Unable to allocate memory for the Tx descriptor ring\n"); + dev_err(dev, "Unable to allocate memory for the Tx descriptor ring\n"); return -ENOMEM; } @@ -4993,7 +4990,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) int i, err = 0; for (i = 0; i < adapter->num_tx_queues; i++) { - err = ixgbe_setup_tx_resources(adapter, adapter->tx_ring[i]); + err = ixgbe_setup_tx_resources(adapter->tx_ring[i]); if (!err) continue; e_err(probe, "Allocation for Tx Queue %u failed\n", i); @@ -5005,48 +5002,41 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) /** * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors) - * @adapter: board private structure * @rx_ring: rx descriptor ring (for a specific queue) to setup * * Returns 0 on success, negative on failure **/ -int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) +int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring) { - struct pci_dev *pdev = adapter->pdev; + struct device *dev = rx_ring->dev; int size; size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; - rx_ring->rx_buffer_info = vmalloc_node(size, adapter->node); + rx_ring->rx_buffer_info = vmalloc_node(size, rx_ring->numa_node); if (!rx_ring->rx_buffer_info) rx_ring->rx_buffer_info = vmalloc(size); - if (!rx_ring->rx_buffer_info) { - e_err(probe, "vmalloc allocation failed for the Rx " - "descriptor ring\n"); - goto alloc_failed; - } + if (!rx_ring->rx_buffer_info) + goto err; memset(rx_ring->rx_buffer_info, 0, size); /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); rx_ring->size = ALIGN(rx_ring->size, 4096); - rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, + rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); - if (!rx_ring->desc) { - e_err(probe, "Memory allocation failed for the Rx " - "descriptor ring\n"); - vfree(rx_ring->rx_buffer_info); - goto alloc_failed; - } + if (!rx_ring->desc) + goto err; rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; return 0; - -alloc_failed: +err: + vfree(rx_ring->rx_buffer_info); + rx_ring->rx_buffer_info = NULL; + dev_err(dev, "Unable to allocate memory for the Rx descriptor ring\n"); return -ENOMEM; } @@ -5060,13 +5050,12 @@ alloc_failed: * * Return 0 on success, negative on failure **/ - static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) { int i, err = 0; for (i = 0; i < adapter->num_rx_queues; i++) { - err = ixgbe_setup_rx_resources(adapter, adapter->rx_ring[i]); + err = ixgbe_setup_rx_resources(adapter->rx_ring[i]); if (!err) continue; e_err(probe, "Allocation for Rx Queue %u failed\n", i); @@ -5078,23 +5067,23 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) /** * ixgbe_free_tx_resources - Free Tx Resources per Queue - * @adapter: board private structure * @tx_ring: Tx descriptor ring for a specific queue * * Free all transmit software resources **/ -void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) +void ixgbe_free_tx_resources(struct ixgbe_ring *tx_ring) { - struct pci_dev *pdev = adapter->pdev; - - ixgbe_clean_tx_ring(adapter, tx_ring); + ixgbe_clean_tx_ring(tx_ring); vfree(tx_ring->tx_buffer_info); tx_ring->tx_buffer_info = NULL; - dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, - tx_ring->dma); + /* if not set, then don't free */ + if (!tx_ring->desc) + return; + + dma_free_coherent(tx_ring->dev, tx_ring->size, + tx_ring->desc, tx_ring->dma); tx_ring->desc = NULL; } @@ -5111,28 +5100,28 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) if (adapter->tx_ring[i]->desc) - ixgbe_free_tx_resources(adapter, adapter->tx_ring[i]); + ixgbe_free_tx_resources(adapter->tx_ring[i]); } /** * ixgbe_free_rx_resources - Free Rx Resources - * @adapter: board private structure * @rx_ring: ring to clean the resources from * * Free all receive software resources **/ -void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) +void ixgbe_free_rx_resources(struct ixgbe_ring *rx_ring) { - struct pci_dev *pdev = adapter->pdev; - - ixgbe_clean_rx_ring(adapter, rx_ring); + ixgbe_clean_rx_ring(rx_ring); vfree(rx_ring->rx_buffer_info); rx_ring->rx_buffer_info = NULL; - dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, - rx_ring->dma); + /* if not set, then don't free */ + if (!rx_ring->desc) + return; + + dma_free_coherent(rx_ring->dev, rx_ring->size, + rx_ring->desc, rx_ring->dma); rx_ring->desc = NULL; } @@ -5149,7 +5138,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) if (adapter->rx_ring[i]->desc) - ixgbe_free_rx_resources(adapter, adapter->rx_ring[i]); + ixgbe_free_rx_resources(adapter->rx_ring[i]); } /** @@ -5985,7 +5974,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, struct sk_buff *skb, u32 tx_flags, unsigned int first, const u8 hdr_len) { - struct pci_dev *pdev = adapter->pdev; + struct device *dev = tx_ring->dev; struct ixgbe_tx_buffer *tx_buffer_info; unsigned int len; unsigned int total = skb->len; @@ -6008,10 +5997,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, tx_buffer_info->length = size; tx_buffer_info->mapped_as_page = false; - tx_buffer_info->dma = dma_map_single(&pdev->dev, + tx_buffer_info->dma = dma_map_single(dev, skb->data + offset, size, DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma)) + if (dma_mapping_error(dev, tx_buffer_info->dma)) goto dma_error; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -6044,12 +6033,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = dma_map_page(&adapter->pdev->dev, + tx_buffer_info->dma = dma_map_page(dev, frag->page, offset, size, DMA_TO_DEVICE); tx_buffer_info->mapped_as_page = true; - if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma)) + if (dma_mapping_error(dev, tx_buffer_info->dma)) goto dma_error; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -6097,7 +6086,7 @@ dma_error: i += tx_ring->count; i--; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); } return 0; -- cgit v1.2.3-59-g8ed1b From 5b7da51547cc3ab5461e45a8ee0ca73051416fda Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:50 -0800 Subject: ixgbe: combine some stats into a union to allow for Tx/Rx stats overlap This change moved some of the RX and TX stats into separate structures and them placed those structures in a union in order to help reduce the size of the ring structure. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 24 +++++++++++---- drivers/net/ixgbe/ixgbe_main.c | 68 ++++++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 70ccab074658..3c63ee6be2ee 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -146,6 +146,19 @@ struct ixgbe_queue_stats { u64 bytes; }; +struct ixgbe_tx_queue_stats { + u64 restart_queue; + u64 tx_busy; +}; + +struct ixgbe_rx_queue_stats { + u64 rsc_count; + u64 rsc_flush; + u64 non_eop_descs; + u64 alloc_rx_page_failed; + u64 alloc_rx_buff_failed; +}; + struct ixgbe_ring { void *desc; /* descriptor ring memory */ struct device *dev; /* device for DMA mapping */ @@ -183,13 +196,12 @@ struct ixgbe_ring { struct ixgbe_queue_stats stats; struct u64_stats_sync syncp; - int numa_node; + union { + struct ixgbe_tx_queue_stats tx_stats; + struct ixgbe_rx_queue_stats rx_stats; + }; unsigned long reinit_state; - u64 rsc_count; /* stat for coalesced packets */ - u64 rsc_flush; /* stats for flushed packets */ - u32 restart_queue; /* track tx queue restarts */ - u32 non_eop_descs; /* track hardware descriptor chaining */ - + int numa_node; unsigned int size; /* length in bytes */ dma_addr_t dma; /* phys. address of descriptor ring */ struct rcu_head rcu; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index be76dd9b94a9..a47e09098166 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -783,7 +783,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && !test_bit(__IXGBE_DOWN, &adapter->state)) { netif_wake_subqueue(netdev, tx_ring->queue_index); - ++tx_ring->restart_queue; + ++tx_ring->tx_stats.restart_queue; } } @@ -1024,7 +1024,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, skb = netdev_alloc_skb_ip_align(adapter->netdev, rx_ring->rx_buf_len); if (!skb) { - adapter->alloc_rx_buff_failed++; + rx_ring->rx_stats.alloc_rx_buff_failed++; goto no_buffers; } /* initialize queue mapping */ @@ -1038,7 +1038,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, rx_ring->rx_buf_len, DMA_FROM_DEVICE); if (dma_mapping_error(rx_ring->dev, bi->dma)) { - adapter->alloc_rx_buff_failed++; + rx_ring->rx_stats.alloc_rx_buff_failed++; bi->dma = 0; goto no_buffers; } @@ -1048,7 +1048,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->page) { bi->page = netdev_alloc_page(adapter->netdev); if (!bi->page) { - adapter->alloc_rx_page_failed++; + rx_ring->rx_stats.alloc_rx_page_failed++; goto no_buffers; } } @@ -1063,7 +1063,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, DMA_FROM_DEVICE); if (dma_mapping_error(rx_ring->dev, bi->page_dma)) { - adapter->alloc_rx_page_failed++; + rx_ring->rx_stats.alloc_rx_page_failed++; bi->page_dma = 0; goto no_buffers; } @@ -1258,7 +1258,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (staterr & IXGBE_RXD_STAT_EOP) { if (skb->prev) skb = ixgbe_transform_rsc_queue(skb, - &(rx_ring->rsc_count)); + &(rx_ring->rx_stats.rsc_count)); if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { if (IXGBE_RSC_CB(skb)->delay_unmap) { dma_unmap_single(rx_ring->dev, @@ -1269,11 +1269,11 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->delay_unmap = false; } if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) - rx_ring->rsc_count += - skb_shinfo(skb)->nr_frags; + rx_ring->rx_stats.rsc_count += + skb_shinfo(skb)->nr_frags; else - rx_ring->rsc_count++; - rx_ring->rsc_flush++; + rx_ring->rx_stats.rsc_count++; + rx_ring->rx_stats.rsc_flush++; } u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets++; @@ -1289,7 +1289,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->next = next_buffer->skb; skb->next->prev = skb; } - rx_ring->non_eop_descs++; + rx_ring->rx_stats.non_eop_descs++; goto next_desc; } @@ -5406,10 +5406,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; u64 total_mpc = 0; u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; - u64 non_eop_descs = 0, restart_queue = 0; - struct ixgbe_hw_stats *hwstats = &adapter->stats; + u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0; + u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0; + u64 bytes = 0, packets = 0; if (test_bit(__IXGBE_DOWN, &adapter->state) || test_bit(__IXGBE_RESETTING, &adapter->state)) @@ -5422,21 +5424,41 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) adapter->hw_rx_no_dma_resources += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); for (i = 0; i < adapter->num_rx_queues; i++) { - rsc_count += adapter->rx_ring[i]->rsc_count; - rsc_flush += adapter->rx_ring[i]->rsc_flush; + rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count; + rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush; } adapter->rsc_total_count = rsc_count; adapter->rsc_total_flush = rsc_flush; } + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *rx_ring = adapter->rx_ring[i]; + non_eop_descs += rx_ring->rx_stats.non_eop_descs; + alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; + alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed; + bytes += rx_ring->stats.bytes; + packets += rx_ring->stats.packets; + } + adapter->non_eop_descs = non_eop_descs; + adapter->alloc_rx_page_failed = alloc_rx_page_failed; + adapter->alloc_rx_buff_failed = alloc_rx_buff_failed; + netdev->stats.rx_bytes = bytes; + netdev->stats.rx_packets = packets; + + bytes = 0; + packets = 0; /* gather some stats to the adapter struct that are per queue */ - for (i = 0; i < adapter->num_tx_queues; i++) - restart_queue += adapter->tx_ring[i]->restart_queue; + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + restart_queue += tx_ring->tx_stats.restart_queue; + tx_busy += tx_ring->tx_stats.tx_busy; + bytes += tx_ring->stats.bytes; + packets += tx_ring->stats.packets; + } adapter->restart_queue = restart_queue; - - for (i = 0; i < adapter->num_rx_queues; i++) - non_eop_descs += adapter->rx_ring[i]->non_eop_descs; - adapter->non_eop_descs = non_eop_descs; + adapter->tx_busy = tx_busy; + netdev->stats.tx_bytes = bytes; + netdev->stats.tx_packets = packets; hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (i = 0; i < 8; i++) { @@ -6223,7 +6245,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, /* A reprieve! - use start_queue because it doesn't call schedule */ netif_start_subqueue(netdev, tx_ring->queue_index); - ++tx_ring->restart_queue; + ++tx_ring->tx_stats.restart_queue; return 0; } @@ -6339,7 +6361,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) { - adapter->tx_busy++; + tx_ring->tx_stats.tx_busy++; return NETDEV_TX_BUSY; } -- cgit v1.2.3-59-g8ed1b From fc77dc3cc15144bbaf18203e9ef7a3e1beedfc3f Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:51 -0800 Subject: ixgbe: add a netdev pointer to the ring structure This change places a netdev pointer directly into the ring structure. This way we can avoid having to determine which netdev we are supposed to be using and can just access the one on the ring directly. As a result of this change further collapse of the code is possible by dropping the adapter from ixgbe_alloc_rx_buffers, and the netdev pointer from ixgbe_xmit_frame_ring_adv and ixgbe_maybe_stop_tx. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 6 ++--- drivers/net/ixgbe/ixgbe_ethtool.c | 11 ++++---- drivers/net/ixgbe/ixgbe_main.c | 55 +++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 3c63ee6be2ee..dc4b97e5777f 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -162,6 +162,7 @@ struct ixgbe_rx_queue_stats { struct ixgbe_ring { void *desc; /* descriptor ring memory */ struct device *dev; /* device for DMA mapping */ + struct net_device *netdev; /* netdev ring belongs to */ union { struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info; @@ -477,14 +478,11 @@ extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, - struct net_device *, struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, struct ixgbe_tx_buffer *); -extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - u16 cleaned_count); +extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index cc7804962b2e..c19594a4e8f8 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1473,6 +1473,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) tx_ring->count = IXGBE_DEFAULT_TXD; tx_ring->queue_index = 0; tx_ring->dev = &adapter->pdev->dev; + tx_ring->netdev = adapter->netdev; tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; tx_ring->numa_node = adapter->node; @@ -1492,6 +1493,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) rx_ring->count = IXGBE_DEFAULT_RXD; rx_ring->queue_index = 0; rx_ring->dev = &adapter->pdev->dev; + rx_ring->netdev = adapter->netdev; rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048; rx_ring->numa_node = adapter->node; @@ -1595,8 +1597,7 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb, return 13; } -static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, +static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, struct ixgbe_ring *tx_ring, unsigned int size) { @@ -1646,7 +1647,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, } /* re-map buffers to ring, store next to clean values */ - ixgbe_alloc_rx_buffers(adapter, rx_ring, count); + ixgbe_alloc_rx_buffers(rx_ring, count); rx_ring->next_to_clean = rx_ntc; tx_ring->next_to_clean = tx_ntc; @@ -1690,7 +1691,6 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) for (i = 0; i < 64; i++) { skb_get(skb); tx_ret_val = ixgbe_xmit_frame_ring(skb, - adapter->netdev, adapter, tx_ring); if (tx_ret_val == NETDEV_TX_OK) @@ -1705,8 +1705,7 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) /* allow 200 milliseconds for packets to go from Tx to Rx */ msleep(200); - good_cnt = ixgbe_clean_test_rings(adapter, rx_ring, - tx_ring, size); + good_cnt = ixgbe_clean_test_rings(rx_ring, tx_ring, size); if (good_cnt != 64) { ret_val = 13; break; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a47e09098166..29523cec2704 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -733,7 +733,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *tx_ring) { struct ixgbe_adapter *adapter = q_vector->adapter; - struct net_device *netdev = adapter->netdev; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbe_tx_buffer *tx_buffer_info; unsigned int i, eop, count = 0; @@ -774,15 +773,15 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_ring->next_to_clean = i; #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) - if (unlikely(count && netif_carrier_ok(netdev) && + if (unlikely(count && netif_carrier_ok(tx_ring->netdev) && (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ smp_mb(); - if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && + if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) && !test_bit(__IXGBE_DOWN, &adapter->state)) { - netif_wake_subqueue(netdev, tx_ring->queue_index); + netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index); ++tx_ring->tx_stats.restart_queue; } } @@ -1004,24 +1003,27 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) /** * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split - * @adapter: address of board private structure + * @rx_ring: ring to place buffers on + * @cleaned_count: number of buffers to replace **/ -void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - u16 cleaned_count) +void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) { union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; struct sk_buff *skb; u16 i = rx_ring->next_to_use; + /* do nothing if no valid netdev defined */ + if (!rx_ring->netdev) + return; + while (cleaned_count--) { rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); bi = &rx_ring->rx_buffer_info[i]; skb = bi->skb; if (!skb) { - skb = netdev_alloc_skb_ip_align(adapter->netdev, + skb = netdev_alloc_skb_ip_align(rx_ring->netdev, rx_ring->rx_buf_len); if (!skb) { rx_ring->rx_stats.alloc_rx_buff_failed++; @@ -1046,7 +1048,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { if (!bi->page) { - bi->page = netdev_alloc_page(adapter->netdev); + bi->page = netdev_alloc_page(rx_ring->netdev); if (!bi->page) { rx_ring->rx_stats.alloc_rx_page_failed++; goto no_buffers; @@ -1304,7 +1306,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, total_rx_bytes += skb->len; total_rx_packets++; - skb->protocol = eth_type_trans(skb, adapter->netdev); + skb->protocol = eth_type_trans(skb, rx_ring->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { @@ -1320,7 +1322,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { - ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); cleaned_count = 0; } @@ -1335,14 +1337,14 @@ next_desc: cleaned_count = IXGBE_DESC_UNUSED(rx_ring); if (cleaned_count) - ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); #ifdef IXGBE_FCOE /* include DDPed FCoE data */ if (ddp_bytes > 0) { unsigned int mss; - mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) - + mss = rx_ring->netdev->mtu - sizeof(struct fcoe_hdr) - sizeof(struct fc_frame_header) - sizeof(struct fcoe_crc_eof); if (mss > 512) @@ -2810,7 +2812,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); ixgbe_rx_desc_queue_enable(adapter, ring); - ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring)); + ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring)); } static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) @@ -4455,6 +4457,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) ring->count = adapter->tx_ring_count; ring->queue_index = i; ring->dev = &adapter->pdev->dev; + ring->netdev = adapter->netdev; ring->numa_node = adapter->node; adapter->tx_ring[i] = ring; @@ -4481,6 +4484,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) ring->count = rx_count; ring->queue_index = i; ring->dev = &adapter->pdev->dev; + ring->netdev = adapter->netdev; ring->numa_node = adapter->node; adapter->rx_ring[i] = ring; @@ -6229,10 +6233,9 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue); } -static int __ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) +static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) { - netif_stop_subqueue(netdev, tx_ring->queue_index); + netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); /* Herbert's original patch had: * smp_mb__after_netif_stop_queue(); * but since that doesn't exist yet, just open code it. */ @@ -6244,17 +6247,16 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, return -EBUSY; /* A reprieve! - use start_queue because it doesn't call schedule */ - netif_start_subqueue(netdev, tx_ring->queue_index); + netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index); ++tx_ring->tx_stats.restart_queue; return 0; } -static int ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) +static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) { if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) return 0; - return __ixgbe_maybe_stop_tx(netdev, tx_ring, size); + return __ixgbe_maybe_stop_tx(tx_ring, size); } static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) @@ -6299,10 +6301,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) return skb_tx_hash(dev, skb); } -netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev, +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { + struct net_device *netdev = tx_ring->netdev; struct netdev_queue *txq; unsigned int first; unsigned int tx_flags = 0; @@ -6360,7 +6363,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); - if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) { + if (ixgbe_maybe_stop_tx(tx_ring, count)) { tx_ring->tx_stats.tx_busy++; return NETDEV_TX_BUSY; } @@ -6412,7 +6415,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev txq->tx_bytes += skb->len; txq->tx_packets++; ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len); - ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); + ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); } else { dev_kfree_skb_any(skb); @@ -6429,7 +6432,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netd struct ixgbe_ring *tx_ring; tx_ring = adapter->tx_ring[skb->queue_mapping]; - return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring); + return ixgbe_xmit_frame_ring(skb, adapter, tx_ring); } /** -- cgit v1.2.3-59-g8ed1b From 5f5ae6fc86083526088e2c2ca4454e0f44f1e0cb Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:52 -0800 Subject: ixgbe: move ixgbe_clear_interrupt_scheme to before pci_save_state The main reason for this change is to keep the suspend/resume logic matched up. The clear_interrupt_scheme function will disable MSI-X which will effect the PCIe configuration space. Therefore we will want to do it before we save state to avoid having the interrupt state restored by pci_restore_state, and then trying to re-enable MSI/MSI-X interrupts via ixgbe_setup_interrupt_scheme. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 29523cec2704..cbb3570f920e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5327,6 +5327,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) ixgbe_free_all_rx_resources(adapter); } + ixgbe_clear_interrupt_scheme(adapter); + #ifdef CONFIG_PM retval = pci_save_state(pdev); if (retval) @@ -5360,8 +5362,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) *enable_wake = !!wufc; - ixgbe_clear_interrupt_scheme(adapter); - ixgbe_release_hw_control(adapter); pci_disable_device(pdev); -- cgit v1.2.3-59-g8ed1b From 01fa7d905fe9a5b045615fbde19e6c0f78063206 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:53 -0800 Subject: ixgbe: remove residual code left over from earlier combining of TXDCTL Missed some code that was left floating around in the DCB configuration for the TXDCTL register. As a result the register was being messed with in two different spots when we only needed to do the change once. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index cbb3570f920e..dd73ebc545d3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3328,8 +3328,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - u32 txdctl; - int i, j; if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) { if (hw->mac.type == ixgbe_mac_82598EB) @@ -3350,20 +3348,13 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, DCB_RX_CONFIG); - /* reconfigure the hardware */ - ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg); - - for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - /* PThresh workaround for Tx hang with DFP enabled. */ - txdctl |= 32; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); - } /* Enable VLAN tag insert/strip */ adapter->netdev->features |= NETIF_F_HW_VLAN_RX; hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); + + /* reconfigure the hardware */ + ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg); } #endif -- cgit v1.2.3-59-g8ed1b From c60fbb00f0400792adf873dbacd431885653b77d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:54 -0800 Subject: ixgbe: move adapter into pci_dev driver data instead of netdev This change moves an adapter pointer into the private portion of the pci_dev instead of a pointer to the netdev. The reason for this change is because in most cases we just want the adapter anyway. In addition as we start moving toward multiple netdevs per port we may want to move the adapter pointer out of the netdevs entirely. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 30 ++++++++++++++---------------- drivers/net/ixgbe/ixgbe_sriov.c | 3 +-- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index dd73ebc545d3..75e25bc91a99 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -887,8 +887,7 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) static int __ixgbe_notify_dca(struct device *dev, void *data) { - struct net_device *netdev = dev_get_drvdata(dev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = dev_get_drvdata(dev); unsigned long event = *(unsigned long *)data; switch (event) { @@ -5255,8 +5254,8 @@ static int ixgbe_close(struct net_device *netdev) #ifdef CONFIG_PM static int ixgbe_resume(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; u32 err; pci_set_power_state(pdev, PCI_D0); @@ -5287,7 +5286,7 @@ static int ixgbe_resume(struct pci_dev *pdev) IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); if (netif_running(netdev)) { - err = ixgbe_open(adapter->netdev); + err = ixgbe_open(netdev); if (err) return err; } @@ -5300,8 +5299,8 @@ static int ixgbe_resume(struct pci_dev *pdev) static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; u32 ctrl, fctrl; u32 wufc = adapter->wol; @@ -6762,8 +6761,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, SET_NETDEV_DEV(netdev, &pdev->dev); - pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); + pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; adapter->pdev = pdev; @@ -7086,8 +7085,8 @@ err_dma: **/ static void __devexit ixgbe_remove(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; set_bit(__IXGBE_DOWN, &adapter->state); /* clear the module not found bit to make sure the worker won't @@ -7157,8 +7156,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; netif_device_detach(netdev); @@ -7181,8 +7180,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); pci_ers_result_t result; int err; @@ -7220,8 +7218,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) */ static void ixgbe_io_resume(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; if (netif_running(netdev)) { if (ixgbe_up(adapter)) { diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 93f40bcf683c..6e3e94b5a5f6 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -178,8 +178,7 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) { unsigned char vf_mac_addr[6]; - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); unsigned int vfn = (event_mask & 0x3f); bool enable = ((event_mask & 0x10000000U) != 0); -- cgit v1.2.3-59-g8ed1b From 33cf09c9586a0dce472ecd2aac13e8140c9ed1a1 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:55 -0800 Subject: ixgbe: move CPU variable from ring into q_vector, add ring->q_vector This is the start of work to sort out what belongs in the rings and what belongs in the q_vector. Items like the CPU variable for make much more sense in the q_vector since the CPU is a per-interrupt thing rather than a per ring thing. I also added a back-pointer from the ring to the q_vector. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 9 +-- drivers/net/ixgbe/ixgbe_main.c | 174 +++++++++++++++++++++++++---------------- 2 files changed, 111 insertions(+), 72 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index dc4b97e5777f..e87b0ffd5832 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -183,11 +183,6 @@ struct ixgbe_ring { unsigned int total_bytes; unsigned int total_packets; -#ifdef CONFIG_IXGBE_DCA - /* cpu for tx queue */ - int cpu; -#endif - u16 work_limit; /* max work per interrupt */ u16 reg_idx; /* holds the special value that gets * the hardware register offset @@ -206,6 +201,7 @@ struct ixgbe_ring { unsigned int size; /* length in bytes */ dma_addr_t dma; /* phys. address of descriptor ring */ struct rcu_head rcu; + struct ixgbe_q_vector *q_vector; /* back-pointer to host q_vector */ } ____cacheline_internodealigned_in_smp; enum ixgbe_ring_f_enum { @@ -251,6 +247,9 @@ struct ixgbe_q_vector { unsigned int v_idx; /* index of q_vector within array, also used for * finding the bit in EICR and friends that * represents the vector for this ring */ +#ifdef CONFIG_IXGBE_DCA + int cpu; /* CPU for DCA */ +#endif struct napi_struct napi; DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 75e25bc91a99..dc78736d3052 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -810,63 +810,98 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, #ifdef CONFIG_IXGBE_DCA static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring, + int cpu) { + struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; - int cpu = get_cpu(); - int q = rx_ring->reg_idx; + u8 reg_idx = rx_ring->reg_idx; - if (rx_ring->cpu != cpu) { - rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q)); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK; - rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; - rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); - } - rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; - rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; - rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); - rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); - rx_ring->cpu = cpu; + rxctrl = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(reg_idx)); + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK; + rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); + break; + case ixgbe_mac_82599EB: + rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; + rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << + IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); + break; + default: + break; } - put_cpu(); + rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; + rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl); } static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring, + int cpu) { + struct ixgbe_hw *hw = &adapter->hw; u32 txctrl; + u8 reg_idx = tx_ring->reg_idx; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(reg_idx)); + txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; + txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl); + break; + case ixgbe_mac_82599EB: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx)); + txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; + txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << + IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl); + break; + default: + break; + } +} + +static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector) +{ + struct ixgbe_adapter *adapter = q_vector->adapter; int cpu = get_cpu(); - int q = tx_ring->reg_idx; - struct ixgbe_hw *hw = &adapter->hw; + long r_idx; + int i; - if (tx_ring->cpu != cpu) { - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q)); - txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; - txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); - txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl); - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q)); - txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; - txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); - txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl); - } - tx_ring->cpu = cpu; + if (q_vector->cpu == cpu) + goto out_no_update; + + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->txr_count; i++) { + ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu); + r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx + 1); } + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu); + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } + + q_vector->cpu = cpu; +out_no_update: put_cpu(); } static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) { + int num_q_vectors; int i; if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) @@ -875,13 +910,14 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) /* always use CB2 mode, difference is masked in the CB driver */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); - for (i = 0; i < adapter->num_tx_queues; i++) { - adapter->tx_ring[i]->cpu = -1; - ixgbe_update_tx_dca(adapter, adapter->tx_ring[i]); - } - for (i = 0; i < adapter->num_rx_queues; i++) { - adapter->rx_ring[i]->cpu = -1; - ixgbe_update_rx_dca(adapter, adapter->rx_ring[i]); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) + num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + else + num_q_vectors = 1; + + for (i = 0; i < num_q_vectors; i++) { + adapter->q_vector[i]->cpu = -1; + ixgbe_update_dca(adapter->q_vector[i]); } } @@ -890,6 +926,9 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) struct ixgbe_adapter *adapter = dev_get_drvdata(dev); unsigned long event = *(unsigned long *)data; + if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) + return 0; + switch (event) { case DCA_PROVIDER_ADD: /* if we're already enabled, don't do it again */ @@ -1827,8 +1866,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) int r_idx; int i; +#ifdef CONFIG_IXGBE_DCA + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_dca(q_vector); +#endif + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = adapter->rx_ring[r_idx]; rx_ring->total_bytes = 0; rx_ring->total_packets = 0; @@ -1839,7 +1883,6 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) if (!q_vector->rxr_count) return IRQ_HANDLED; - /* disable interrupts on this vector only */ /* EIAM disabled interrupts (on this vector) for us */ napi_schedule(&q_vector->napi); @@ -1898,13 +1941,14 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) int work_done = 0; long r_idx; - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - rx_ring = adapter->rx_ring[r_idx]; #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_rx_dca(adapter, rx_ring); + ixgbe_update_dca(q_vector); #endif + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = adapter->rx_ring[r_idx]; + ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget); /* If all Rx work done, exit the polling mode */ @@ -1938,13 +1982,14 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) long r_idx; bool tx_clean_complete = true; +#ifdef CONFIG_IXGBE_DCA + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_dca(q_vector); +#endif + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { ring = adapter->tx_ring[r_idx]; -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_tx_dca(adapter, ring); -#endif tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); @@ -1957,10 +2002,6 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { ring = adapter->rx_ring[r_idx]; -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_rx_dca(adapter, ring); -#endif ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, r_idx + 1); @@ -1999,13 +2040,14 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) int work_done = 0; long r_idx; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - tx_ring = adapter->tx_ring[r_idx]; #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_tx_dca(adapter, tx_ring); + ixgbe_update_dca(q_vector); #endif + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + tx_ring = adapter->tx_ring[r_idx]; + if (!ixgbe_clean_tx_irq(q_vector, tx_ring)) work_done = budget; @@ -3880,10 +3922,8 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) int tx_clean_complete, work_done = 0; #ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { - ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]); - ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]); - } + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_dca(q_vector); #endif tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]); -- cgit v1.2.3-59-g8ed1b From 7d637bcc8f461f19e1d018078792ec0cd9b07b1d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:56 -0800 Subject: ixgbe: add a state flags to ring This change adds a set of state flags to the rings that allow them to independently function allowing for features like RSC, packet split, and TX hang detection to be done per ring instead of for the entire device. This is accomplished by re-purposing the flow director reinit_state member and making it a global state instead since a long for a single bit flag is a bit wasteful. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 44 ++++++++++++++++++++------- drivers/net/ixgbe/ixgbe_main.c | 67 ++++++++++++++++++++++++------------------ 2 files changed, 72 insertions(+), 39 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index e87b0ffd5832..160ce9234546 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -159,6 +159,31 @@ struct ixgbe_rx_queue_stats { u64 alloc_rx_buff_failed; }; +enum ixbge_ring_state_t { + __IXGBE_TX_FDIR_INIT_DONE, + __IXGBE_TX_DETECT_HANG, + __IXGBE_RX_PS_ENABLED, + __IXGBE_RX_RSC_ENABLED, +}; + +#define ring_is_ps_enabled(ring) \ + test_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) +#define set_ring_ps_enabled(ring) \ + set_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) +#define clear_ring_ps_enabled(ring) \ + clear_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) +#define check_for_tx_hang(ring) \ + test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define set_check_for_tx_hang(ring) \ + set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define clear_check_for_tx_hang(ring) \ + clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define ring_is_rsc_enabled(ring) \ + test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) +#define set_ring_rsc_enabled(ring) \ + set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) +#define clear_ring_rsc_enabled(ring) \ + clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) struct ixgbe_ring { void *desc; /* descriptor ring memory */ struct device *dev; /* device for DMA mapping */ @@ -167,6 +192,7 @@ struct ixgbe_ring { struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info; }; + unsigned long state; u8 atr_sample_rate; u8 atr_count; u16 count; /* amount of descriptors */ @@ -175,28 +201,25 @@ struct ixgbe_ring { u16 next_to_clean; u8 queue_index; /* needed for multiqueue queue management */ + u8 reg_idx; /* holds the special value that gets + * the hardware register offset + * associated with this ring, which is + * different for DCB and RSS modes + */ + + u16 work_limit; /* max work per interrupt */ -#define IXGBE_RING_RX_PS_ENABLED (u8)(1) - u8 flags; /* per ring feature flags */ u8 __iomem *tail; unsigned int total_bytes; unsigned int total_packets; - u16 work_limit; /* max work per interrupt */ - u16 reg_idx; /* holds the special value that gets - * the hardware register offset - * associated with this ring, which is - * different for DCB and RSS modes - */ - struct ixgbe_queue_stats stats; struct u64_stats_sync syncp; union { struct ixgbe_tx_queue_stats tx_stats; struct ixgbe_rx_queue_stats rx_stats; }; - unsigned long reinit_state; int numa_node; unsigned int size; /* length in bytes */ dma_addr_t dma; /* phys. address of descriptor ring */ @@ -441,7 +464,6 @@ enum ixbge_state_t { __IXGBE_TESTING, __IXGBE_RESETTING, __IXGBE_DOWN, - __IXGBE_FDIR_INIT_DONE, __IXGBE_SFP_MODULE_NOT_FOUND }; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index dc78736d3052..b798501500e6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -687,7 +687,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, /* Detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of eop */ - adapter->detect_tx_hung = false; + clear_check_for_tx_hang(tx_ring); if (tx_ring->tx_buffer_info[eop].time_stamp && time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && ixgbe_tx_xon_state(adapter, tx_ring)) { @@ -786,13 +786,12 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } } - if (adapter->detect_tx_hung) { - if (ixgbe_check_tx_hang(adapter, tx_ring, i)) { - /* schedule immediate reset if we believe we hung */ - e_info(probe, "tx hang %d detected, resetting " - "adapter\n", adapter->tx_timeout_count + 1); - ixgbe_tx_timeout(adapter->netdev); - } + if (check_for_tx_hang(tx_ring) && + ixgbe_check_tx_hang(adapter, tx_ring, i)) { + /* schedule immediate reset if we believe we hung */ + e_info(probe, "tx hang %d detected, resetting " + "adapter\n", adapter->tx_timeout_count + 1); + ixgbe_tx_timeout(adapter->netdev); } /* re-arm the interrupt */ @@ -1084,7 +1083,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) } } - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring_is_ps_enabled(rx_ring)) { if (!bi->page) { bi->page = netdev_alloc_page(rx_ring->netdev); if (!bi->page) { @@ -1214,7 +1213,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, (*work_done)++; rmb(); /* read descriptor and rx_buffer_info after status DD */ - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring_is_ps_enabled(rx_ring)) { hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc)); len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> IXGBE_RXDADV_HDRBUFLEN_SHIFT; @@ -1284,7 +1283,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + if (ring_is_rsc_enabled(rx_ring)) rsc_count = ixgbe_get_rsc_count(rx_desc); if (rsc_count) { @@ -1299,7 +1298,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (skb->prev) skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rx_stats.rsc_count)); - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + if (ring_is_rsc_enabled(rx_ring)) { if (IXGBE_RSC_CB(skb)->delay_unmap) { dma_unmap_single(rx_ring->dev, IXGBE_RSC_CB(skb)->dma, @@ -1308,7 +1307,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; } - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) + if (ring_is_ps_enabled(rx_ring)) rx_ring->rx_stats.rsc_count += skb_shinfo(skb)->nr_frags; else @@ -1320,7 +1319,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_ring->stats.bytes += skb->len; u64_stats_update_end(&rx_ring->syncp); } else { - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring_is_ps_enabled(rx_ring)) { rx_buffer_info->skb = next_buffer->skb; rx_buffer_info->dma = next_buffer->dma; next_buffer->skb = skb; @@ -1782,8 +1781,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; - if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) + if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE, + &tx_ring->state)) schedule_work(&adapter->fdir_reinit_task); } } @@ -2522,7 +2521,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, } /* reinitialize flowdirector state */ - set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state); + set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); /* enable queue */ txdctl |= IXGBE_TXDCTL_ENABLE; @@ -2632,7 +2631,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK; - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring_is_ps_enabled(rx_ring)) { #if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; #else @@ -2727,7 +2726,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int rx_buf_len; u16 reg_idx = ring->reg_idx; - if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) + if (!ring_is_rsc_enabled(ring)) return; rx_buf_len = ring->rx_buf_len; @@ -2738,7 +2737,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, * total size of max desc * buf_len is not greater * than 65535 */ - if (ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring_is_ps_enabled(ring)) { #if (MAX_SKB_FRAGS > 16) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; #elif (MAX_SKB_FRAGS > 8) @@ -2976,19 +2975,28 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) rx_ring->rx_buf_len = rx_buf_len; if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) - rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED; + set_ring_ps_enabled(rx_ring); + else + clear_ring_ps_enabled(rx_ring); + + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + set_ring_rsc_enabled(rx_ring); else - rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; + clear_ring_rsc_enabled(rx_ring); #ifdef IXGBE_FCOE if (netdev->features & NETIF_F_FCOE_MTU) { struct ixgbe_ring_feature *f; f = &adapter->ring_feature[RING_F_FCOE]; if ((i >= f->mask) && (i < f->mask + f->indices)) { - rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; + clear_ring_ps_enabled(rx_ring); if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) rx_ring->rx_buf_len = IXGBE_FCOE_JUMBO_FRAME_SIZE; + } else if (!ring_is_rsc_enabled(rx_ring) && + !ring_is_ps_enabled(rx_ring)) { + rx_ring->rx_buf_len = + IXGBE_FCOE_JUMBO_FRAME_SIZE; } } #endif /* IXGBE_FCOE */ @@ -5729,8 +5737,8 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work) if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->reinit_state)); + set_bit(__IXGBE_TX_FDIR_INIT_DONE, + &(adapter->tx_ring[i]->state)); } else { e_err(probe, "failed to finish FDIR re-initialization, " "ignored adding FDIR ATR filters\n"); @@ -5816,7 +5824,10 @@ static void ixgbe_watchdog_task(struct work_struct *work) netif_carrier_on(netdev); } else { /* Force detection of hung controller */ - adapter->detect_tx_hung = true; + for (i = 0; i < adapter->num_tx_queues; i++) { + tx_ring = adapter->tx_ring[i]; + set_check_for_tx_hang(tx_ring); + } } } else { adapter->link_up = false; @@ -6434,8 +6445,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, if (tx_ring->atr_sample_rate) { ++tx_ring->atr_count; if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) && - test_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) { + test_bit(__IXGBE_TX_FDIR_INIT_DONE, + &tx_ring->state)) { ixgbe_atr(adapter, skb, tx_ring->queue_index, tx_flags, protocol); tx_ring->atr_count = 0; -- cgit v1.2.3-59-g8ed1b From 73c4b7cdd25a8a769baf6dae5bc498400a9ddd93 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:57 -0800 Subject: ixgbe: cleanup race conditions in link setup This change makes it so that we perform link setup with interrupts disabled. If the SFP has not been detected previously we will schedule the SFP detection task to run in order to detect link. By doing this we avoid the possibility of interrupts firing in the middle of our link setup during ixgbe_up_complete. In addition this change makes it so that the multi-speed fiber setup and SFP setup are not mutually exclusive. The addresses issues seen in which a link would only come up at 1G on some multi-speed fiber modules. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 47 +++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b798501500e6..0128fe666f0b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1712,17 +1712,18 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) { struct ixgbe_hw *hw = &adapter->hw; + if (eicr & IXGBE_EICR_GPI_SDP2) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + schedule_work(&adapter->sfp_config_module_task); + } + if (eicr & IXGBE_EICR_GPI_SDP1) { /* Clear the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); - schedule_work(&adapter->multispeed_fiber_task); - } else if (eicr & IXGBE_EICR_GPI_SDP2) { - /* Clear the interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); - schedule_work(&adapter->sfp_config_module_task); - } else { - /* Interrupt isn't for us... */ - return; + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + schedule_work(&adapter->multispeed_fiber_task); } } @@ -3587,6 +3588,14 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) clear_bit(__IXGBE_DOWN, &adapter->state); ixgbe_napi_enable_all(adapter); + if (ixgbe_is_sfp(hw)) { + ixgbe_sfp_link_config(adapter); + } else { + err = ixgbe_non_sfp_link_config(hw); + if (err) + e_err(probe, "link_config FAILED %d\n", err); + } + /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_EICR); ixgbe_irq_enable(adapter, true, true); @@ -3609,26 +3618,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) * If we're not hot-pluggable SFP+, we just need to configure link * and bring it up. */ - if (hw->phy.type == ixgbe_phy_unknown) { - err = hw->phy.ops.identify(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - /* - * Take the device down and schedule the sfp tasklet - * which will unregister_netdev and log it. - */ - ixgbe_down(adapter); - schedule_work(&adapter->sfp_config_module_task); - return err; - } - } - - if (ixgbe_is_sfp(hw)) { - ixgbe_sfp_link_config(adapter); - } else { - err = ixgbe_non_sfp_link_config(hw); - if (err) - e_err(probe, "link_config FAILED %d\n", err); - } + if (hw->phy.type == ixgbe_phy_unknown) + schedule_work(&adapter->sfp_config_module_task); /* enable transmits */ netif_tx_start_all_queues(adapter->netdev); -- cgit v1.2.3-59-g8ed1b From 80fba3f4341b1c98430bee620b507d3f5b7086cd Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:57 -0800 Subject: ixgbe: Disable RSC when ITR setting is too high to allow RSC RSC will flush its descriptors every time the interrupt throttle timer expires. In addition there are known issues with RSC when the rx-usecs value is set too low. As such we are forced to clear the RSC_ENABLED bit and reset the adapter when the rx-usecs value is set too low. However we do not need to clear the NETIF_F_LRO flag because it is used to indicate that the user wants to leave the LRO feature enabled, and in fact with this change we will now re-enable RSC as soon as the rx-usecs value is increased and the flag is still set. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 90 +++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index c19594a4e8f8..561d47895d82 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1975,6 +1975,41 @@ static int ixgbe_get_coalesce(struct net_device *netdev, return 0; } +/* + * this function must be called before setting the new value of + * rx_itr_setting + */ +static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter, + struct ethtool_coalesce *ec) +{ + struct net_device *netdev = adapter->netdev; + + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) + return false; + + /* if interrupt rate is too high then disable RSC */ + if (ec->rx_coalesce_usecs != 1 && + ec->rx_coalesce_usecs <= 1000000/IXGBE_MAX_RSC_INT_RATE) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + e_info(probe, "rx-usecs set too low, " + "disabling RSC\n"); + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + return true; + } + } else { + /* check the feature flag value and enable RSC if necessary */ + if ((netdev->features & NETIF_F_LRO) && + !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + e_info(probe, "rx-usecs set to %d, " + "re-enabling RSC\n", + ec->rx_coalesce_usecs); + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + return true; + } + } + return false; +} + static int ixgbe_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { @@ -1992,17 +2027,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev, adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq; if (ec->rx_coalesce_usecs > 1) { - u32 max_int; - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) - max_int = IXGBE_MAX_RSC_INT_RATE; - else - max_int = IXGBE_MAX_INT_RATE; - /* check the limits */ - if ((1000000/ec->rx_coalesce_usecs > max_int) || + if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) || (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE)) return -EINVAL; + /* check the old value and enable RSC if necessary */ + need_reset = ixgbe_update_rsc(adapter, ec); + /* store the value in ints/second */ adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs; @@ -2011,32 +2043,21 @@ static int ixgbe_set_coalesce(struct net_device *netdev, /* clear the lower bit as its used for dynamic state */ adapter->rx_itr_setting &= ~1; } else if (ec->rx_coalesce_usecs == 1) { + /* check the old value and enable RSC if necessary */ + need_reset = ixgbe_update_rsc(adapter, ec); + /* 1 means dynamic mode */ adapter->rx_eitr_param = 20000; adapter->rx_itr_setting = 1; } else { + /* check the old value and enable RSC if necessary */ + need_reset = ixgbe_update_rsc(adapter, ec); /* * any other value means disable eitr, which is best * served by setting the interrupt rate very high */ adapter->rx_eitr_param = IXGBE_MAX_INT_RATE; adapter->rx_itr_setting = 0; - - /* - * if hardware RSC is enabled, disable it when - * setting low latency mode, to avoid errata, assuming - * that when the user set low latency mode they want - * it at the cost of anything else - */ - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; - if (netdev->features & NETIF_F_LRO) { - netdev->features &= ~NETIF_F_LRO; - e_info(probe, "rx-usecs set to 0, " - "disabling RSC\n"); - } - need_reset = true; - } } if (ec->tx_coalesce_usecs > 1) { @@ -2123,15 +2144,15 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) return rc; /* if state changes we need to update adapter->flags and reset */ - if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { - /* - * cast both to bool and verify if they are set the same - * but only enable RSC if itr is non-zero, as - * itr=0 and RSC are mutually exclusive - */ - if (((!!(data & ETH_FLAG_LRO)) != - (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) && - adapter->rx_itr_setting) { + if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && + (!!(data & ETH_FLAG_LRO) != + !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { + if ((data & ETH_FLAG_LRO) && + (!adapter->rx_itr_setting || + (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) { + e_info(probe, "rx-usecs set too low, " + "not enabling RSC.\n"); + } else { adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: @@ -2140,11 +2161,6 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) default: break; } - } else if (!adapter->rx_itr_setting) { - netdev->features &= ~NETIF_F_LRO; - if (data & ETH_FLAG_LRO) - e_info(probe, "rx-usecs set to 0, " - "LRO/RSC cannot be enabled.\n"); } } -- cgit v1.2.3-59-g8ed1b From b953799ee29075afd30afe4c0fb65f278b088f69 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:58 -0800 Subject: ixgbe: reorder Tx cleanup so that if adapter will reset we don't rearm The code as it existed could re-arm the queues when it was requesting a HW reset due to a TX hang. Instead of doing that this change makes it so that we will just exit if the hardware is believed to be hung. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0128fe666f0b..1d78b554b0ea 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -735,8 +735,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_adapter *adapter = q_vector->adapter; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbe_tx_buffer *tx_buffer_info; - unsigned int i, eop, count = 0; unsigned int total_bytes = 0, total_packets = 0; + u16 i, eop, count = 0; i = tx_ring->next_to_clean; eop = tx_ring->tx_buffer_info[i].next_to_watch; @@ -771,6 +771,23 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } tx_ring->next_to_clean = i; + tx_ring->total_bytes += total_bytes; + tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->stats.packets += total_packets; + tx_ring->stats.bytes += total_bytes; + u64_stats_update_end(&tx_ring->syncp); + + if (check_for_tx_hang(tx_ring) && + ixgbe_check_tx_hang(adapter, tx_ring, i)) { + /* schedule immediate reset if we believe we hung */ + e_info(probe, "tx hang %d detected, resetting " + "adapter\n", adapter->tx_timeout_count + 1); + ixgbe_tx_timeout(adapter->netdev); + + /* the adapter is about to reset, no point in enabling stuff */ + return true; + } #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) if (unlikely(count && netif_carrier_ok(tx_ring->netdev) && @@ -786,24 +803,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } } - if (check_for_tx_hang(tx_ring) && - ixgbe_check_tx_hang(adapter, tx_ring, i)) { - /* schedule immediate reset if we believe we hung */ - e_info(probe, "tx hang %d detected, resetting " - "adapter\n", adapter->tx_timeout_count + 1); - ixgbe_tx_timeout(adapter->netdev); - } - - /* re-arm the interrupt */ - if (count >= tx_ring->work_limit) - ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx)); - - tx_ring->total_bytes += total_bytes; - tx_ring->total_packets += total_packets; - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->stats.packets += total_packets; - tx_ring->stats.bytes += total_bytes; - u64_stats_update_end(&tx_ring->syncp); return count < tx_ring->work_limit; } -- cgit v1.2.3-59-g8ed1b From 32aa77a4fc06bd1116f83c25bf0389a3e9b80533 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:26:59 -0800 Subject: ixgbe: change vector numbering so that queues end up on correct CPUs This changes the numbering scheme slightly. Previously the ordering was coming out like this: Rx-2 Rx-1 Rx-0 TxRx-0 Which would drop two queues on CPU 0. This change makes it so that the ordering is like this: Rx-3 Rx-2 Rx-1 TxRx-0 This means that each CPU will have it's own Rx queue, and only CPU 0 will have the Tx queue. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1d78b554b0ea..5dde7d63c3a3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2182,9 +2182,11 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) } else if (handler == &ixgbe_msix_clean_tx) { sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "tx", ti++); - } else + } else { sprintf(adapter->name[vector], "%s-%s-%d", - netdev->name, "TxRx", vector); + netdev->name, "TxRx", ri++); + ti++; + } err = request_irq(adapter->msix_entries[vector].vector, handler, 0, adapter->name[vector], -- cgit v1.2.3-59-g8ed1b From c267fc166a3308c45c7f0ad2ddd6fc696caaeb80 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:00 -0800 Subject: ixgbe: cleanup ixgbe_clean_rx_irq The code for ixgbe_clean_rx_irq was much more tangled up than it needed to be in terms of logic statements and unused variables. This change untangles much of that and drops several unused variables such as cleaned which was being returned but never checked. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 149 +++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 71 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5dde7d63c3a3..584608d267b2 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1128,14 +1128,18 @@ no_buffers: } } -static inline u16 ixgbe_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc) +static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) { - return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info; -} - -static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) -{ - return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + /* HW will not DMA in data larger than the given buffer, even if it + * parses the (NFS, of course) header to be larger. In that case, it + * fills the header buffer and spills the rest into the page. + */ + u16 hdr_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info); + u16 hlen = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> + IXGBE_RXDADV_HDRBUFLEN_SHIFT; + if (hlen > IXGBE_RX_HDR_SIZE) + hlen = IXGBE_RX_HDR_SIZE; + return hlen; } static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) @@ -1182,7 +1186,7 @@ struct ixgbe_rsc_cb { #define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) -static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, +static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int *work_done, int work_to_do) { @@ -1190,49 +1194,40 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; struct sk_buff *skb; - unsigned int i, rsc_count = 0; - u32 len, staterr; - u16 hdr_info; - bool cleaned = false; - int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; + const int current_node = numa_node_id(); + unsigned int rsc_count = 0; #ifdef IXGBE_FCOE int ddp_bytes = 0; #endif /* IXGBE_FCOE */ + u32 staterr; + u16 i; + u16 cleaned_count = 0; i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); - rx_buffer_info = &rx_ring->rx_buffer_info[i]; while (staterr & IXGBE_RXD_STAT_DD) { u32 upper_len = 0; - if (*work_done >= work_to_do) - break; - (*work_done)++; rmb(); /* read descriptor and rx_buffer_info after status DD */ - if (ring_is_ps_enabled(rx_ring)) { - hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc)); - len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> - IXGBE_RXDADV_HDRBUFLEN_SHIFT; - upper_len = le16_to_cpu(rx_desc->wb.upper.length); - if ((len > IXGBE_RX_HDR_SIZE) || - (upper_len && !(hdr_info & IXGBE_RXDADV_SPH))) - len = IXGBE_RX_HDR_SIZE; - } else { - len = le16_to_cpu(rx_desc->wb.upper.length); - } - cleaned = true; + rx_buffer_info = &rx_ring->rx_buffer_info[i]; + skb = rx_buffer_info->skb; - prefetch(skb->data); rx_buffer_info->skb = NULL; + prefetch(skb->data); + if (ring_is_rsc_enabled(rx_ring)) + rsc_count = ixgbe_get_rsc_count(rx_desc); + + /* if this is a skb from previous receive DMA will be 0 */ if (rx_buffer_info->dma) { - if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && - (!(staterr & IXGBE_RXD_STAT_EOP)) && - (!(skb->prev))) { + u16 hlen; + if (rsc_count && + !(staterr & IXGBE_RXD_STAT_EOP) && + !skb->prev) { /* * When HWRSC is enabled, delay unmapping * of the first packet. It carries the @@ -1249,7 +1244,18 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, DMA_FROM_DEVICE); } rx_buffer_info->dma = 0; - skb_put(skb, len); + + if (ring_is_ps_enabled(rx_ring)) { + hlen = ixgbe_get_hlen(rx_desc); + upper_len = le16_to_cpu(rx_desc->wb.upper.length); + } else { + hlen = le16_to_cpu(rx_desc->wb.upper.length); + } + + skb_put(skb, hlen); + } else { + /* assume packet split since header is unmapped */ + upper_len = le16_to_cpu(rx_desc->wb.upper.length); } if (upper_len) { @@ -1263,11 +1269,11 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_buffer_info->page_offset, upper_len); - if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || - (page_count(rx_buffer_info->page) != 1)) - rx_buffer_info->page = NULL; - else + if ((page_count(rx_buffer_info->page) == 1) && + (page_to_nid(rx_buffer_info->page) == current_node)) get_page(rx_buffer_info->page); + else + rx_buffer_info->page = NULL; skb->len += upper_len; skb->data_len += upper_len; @@ -1282,9 +1288,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (ring_is_rsc_enabled(rx_ring)) - rsc_count = ixgbe_get_rsc_count(rx_desc); - if (rsc_count) { u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >> IXGBE_RXDADV_NEXTP_SHIFT; @@ -1293,31 +1296,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, next_buffer = &rx_ring->rx_buffer_info[i]; } - if (staterr & IXGBE_RXD_STAT_EOP) { - if (skb->prev) - skb = ixgbe_transform_rsc_queue(skb, - &(rx_ring->rx_stats.rsc_count)); - if (ring_is_rsc_enabled(rx_ring)) { - if (IXGBE_RSC_CB(skb)->delay_unmap) { - dma_unmap_single(rx_ring->dev, - IXGBE_RSC_CB(skb)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_RSC_CB(skb)->dma = 0; - IXGBE_RSC_CB(skb)->delay_unmap = false; - } - if (ring_is_ps_enabled(rx_ring)) - rx_ring->rx_stats.rsc_count += - skb_shinfo(skb)->nr_frags; - else - rx_ring->rx_stats.rsc_count++; - rx_ring->rx_stats.rsc_flush++; - } - u64_stats_update_begin(&rx_ring->syncp); - rx_ring->stats.packets++; - rx_ring->stats.bytes += skb->len; - u64_stats_update_end(&rx_ring->syncp); - } else { + if (!(staterr & IXGBE_RXD_STAT_EOP)) { if (ring_is_ps_enabled(rx_ring)) { rx_buffer_info->skb = next_buffer->skb; rx_buffer_info->dma = next_buffer->dma; @@ -1331,8 +1310,32 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } + if (skb->prev) + skb = ixgbe_transform_rsc_queue(skb, + &(rx_ring->rx_stats.rsc_count)); + + if (ring_is_rsc_enabled(rx_ring)) { + if (IXGBE_RSC_CB(skb)->delay_unmap) { + dma_unmap_single(rx_ring->dev, + IXGBE_RSC_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + IXGBE_RSC_CB(skb)->dma = 0; + IXGBE_RSC_CB(skb)->delay_unmap = false; + } + if (ring_is_ps_enabled(rx_ring)) + rx_ring->rx_stats.rsc_count += + skb_shinfo(skb)->nr_frags; + else + rx_ring->rx_stats.rsc_count++; + rx_ring->rx_stats.rsc_flush++; + } + + /* ERR_MASK will only have valid bits if EOP set */ if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) { - dev_kfree_skb_irq(skb); + /* trim packet back to size 0 and recycle it */ + __pskb_trim(skb, 0); + rx_buffer_info->skb = skb; goto next_desc; } @@ -1356,6 +1359,10 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, next_desc: rx_desc->wb.upper.status_error = 0; + (*work_done)++; + if (*work_done >= work_to_do) + break; + /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); @@ -1364,8 +1371,6 @@ next_desc: /* use prefetched values */ rx_desc = next_rxd; - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } @@ -1392,8 +1397,10 @@ next_desc: rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - - return cleaned; + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->stats.packets += total_rx_packets; + rx_ring->stats.bytes += total_rx_bytes; + u64_stats_update_end(&rx_ring->syncp); } static int ixgbe_clean_rxonly(struct napi_struct *, int); -- cgit v1.2.3-59-g8ed1b From ee9e0f0b40c4fb4ad71d677c094d518db42f7076 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:01 -0800 Subject: ixgbe: cleanup ATR filter setup function This change cleans up the ixgbe_atr filter setup function so that it uses fewer items from the stack. Since the code is only applicable to IPv4 w/ TCP it makes sense to just use the pointers based on the headers themselves instead of copying them to temp variables and then writing those to the filters. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 50 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 584608d267b2..402ab7b2706a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2530,7 +2530,14 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, } /* reinitialize flowdirector state */ - set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && + adapter->atr_sample_rate) { + ring->atr_sample_rate = adapter->atr_sample_rate; + ring->atr_count = 0; + set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); + } else { + ring->atr_sample_rate = 0; + } /* enable queue */ txdctl |= IXGBE_TXDCTL_ENABLE; @@ -6227,47 +6234,34 @@ static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring, } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - int queue, u32 tx_flags, __be16 protocol) + u8 queue, u32 tx_flags, __be16 protocol) { struct ixgbe_atr_input atr_input; - struct tcphdr *th; struct iphdr *iph = ip_hdr(skb); struct ethhdr *eth = (struct ethhdr *)skb->data; - u16 vlan_id, src_port, dst_port, flex_bytes; - u32 src_ipv4_addr, dst_ipv4_addr; - u8 l4type = 0; + struct tcphdr *th; + u16 vlan_id; - /* Right now, we support IPv4 only */ - if (protocol != htons(ETH_P_IP)) + /* Right now, we support IPv4 w/ TCP only */ + if (protocol != htons(ETH_P_IP) || + iph->protocol != IPPROTO_TCP) return; - /* check if we're UDP or TCP */ - if (iph->protocol == IPPROTO_TCP) { - th = tcp_hdr(skb); - src_port = th->source; - dst_port = th->dest; - l4type |= IXGBE_ATR_L4TYPE_TCP; - /* l4type IPv4 type is 0, no need to assign */ - } else { - /* Unsupported L4 header, just bail here */ - return; - } memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> IXGBE_TX_FLAGS_VLAN_SHIFT; - src_ipv4_addr = iph->saddr; - dst_ipv4_addr = iph->daddr; - flex_bytes = eth->h_proto; + + th = tcp_hdr(skb); ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id); - ixgbe_atr_set_src_port_82599(&atr_input, dst_port); - ixgbe_atr_set_dst_port_82599(&atr_input, src_port); - ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes); - ixgbe_atr_set_l4type_82599(&atr_input, l4type); + ixgbe_atr_set_src_port_82599(&atr_input, th->dest); + ixgbe_atr_set_dst_port_82599(&atr_input, th->source); + ixgbe_atr_set_flex_byte_82599(&atr_input, eth->h_proto); + ixgbe_atr_set_l4type_82599(&atr_input, IXGBE_ATR_L4TYPE_TCP); /* src and dst are inverted, think how the receiver sees them */ - ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr); - ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr); + ixgbe_atr_set_src_ipv4_82599(&atr_input, iph->daddr); + ixgbe_atr_set_dst_ipv4_82599(&atr_input, iph->saddr); /* This assumes the Rx queue and Tx queue are bound to the same CPU */ ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue); -- cgit v1.2.3-59-g8ed1b From aa80175a539a47fd11e2fbf1696a29f7a2652930 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:02 -0800 Subject: ixgbe: cleanup use of ixgbe_rsc_count and RSC_CB This change cleans up the use of rsc_count and changes it to a boolean since the actual numerical value is used nowhere in the Rx cleanup path. I am also moving the skb count into the RSC_CB path since it is much easier to track it there than when it is passed as a parameter to various function calls. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 7 ++++++ drivers/net/ixgbe/ixgbe_main.c | 55 +++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 160ce9234546..6d9fcb4e0854 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -467,6 +467,13 @@ enum ixbge_state_t { __IXGBE_SFP_MODULE_NOT_FOUND }; +struct ixgbe_rsc_cb { + dma_addr_t dma; + u16 skb_cnt; + bool delay_unmap; +}; +#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) + enum ixgbe_boards { board_82598, board_82599, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 402ab7b2706a..9f5331bc5985 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1142,33 +1142,25 @@ static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) return hlen; } -static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) -{ - return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & - IXGBE_RXDADV_RSCCNT_MASK) >> - IXGBE_RXDADV_RSCCNT_SHIFT; -} - /** * ixgbe_transform_rsc_queue - change rsc queue into a full packet * @skb: pointer to the last skb in the rsc queue - * @count: pointer to number of packets coalesced in this context * * This function changes a queue full of hw rsc buffers into a completed * packet. It uses the ->prev pointers to find the first packet and then * turns it into the frag list owner. **/ -static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, - u64 *count) +static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb) { unsigned int frag_list_size = 0; + unsigned int skb_cnt = 1; while (skb->prev) { struct sk_buff *prev = skb->prev; frag_list_size += skb->len; skb->prev = NULL; skb = prev; - *count += 1; + skb_cnt++; } skb_shinfo(skb)->frag_list = skb->next; @@ -1176,15 +1168,16 @@ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, skb->len += frag_list_size; skb->data_len += frag_list_size; skb->truesize += frag_list_size; + IXGBE_RSC_CB(skb)->skb_cnt = skb_cnt; + return skb; } -struct ixgbe_rsc_cb { - dma_addr_t dma; - bool delay_unmap; -}; - -#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) +static inline bool ixgbe_get_rsc_state(union ixgbe_adv_rx_desc *rx_desc) +{ + return !!(le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & + IXGBE_RXDADV_RSCCNT_MASK); +} static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, @@ -1196,13 +1189,13 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct sk_buff *skb; unsigned int total_rx_bytes = 0, total_rx_packets = 0; const int current_node = numa_node_id(); - unsigned int rsc_count = 0; #ifdef IXGBE_FCOE int ddp_bytes = 0; #endif /* IXGBE_FCOE */ u32 staterr; u16 i; u16 cleaned_count = 0; + bool pkt_is_rsc = false; i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); @@ -1220,12 +1213,12 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(skb->data); if (ring_is_rsc_enabled(rx_ring)) - rsc_count = ixgbe_get_rsc_count(rx_desc); + pkt_is_rsc = ixgbe_get_rsc_state(rx_desc); /* if this is a skb from previous receive DMA will be 0 */ if (rx_buffer_info->dma) { u16 hlen; - if (rsc_count && + if (pkt_is_rsc && !(staterr & IXGBE_RXD_STAT_EOP) && !skb->prev) { /* @@ -1288,7 +1281,7 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (rsc_count) { + if (pkt_is_rsc) { u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >> IXGBE_RXDADV_NEXTP_SHIFT; next_buffer = &rx_ring->rx_buffer_info[nextp]; @@ -1310,9 +1303,15 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - if (skb->prev) - skb = ixgbe_transform_rsc_queue(skb, - &(rx_ring->rx_stats.rsc_count)); + if (skb->prev) { + skb = ixgbe_transform_rsc_queue(skb); + /* if we got here without RSC the packet is invalid */ + if (!pkt_is_rsc) { + __pskb_trim(skb, 0); + rx_buffer_info->skb = skb; + goto next_desc; + } + } if (ring_is_rsc_enabled(rx_ring)) { if (IXGBE_RSC_CB(skb)->delay_unmap) { @@ -1323,11 +1322,14 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; } + } + if (pkt_is_rsc) { if (ring_is_ps_enabled(rx_ring)) rx_ring->rx_stats.rsc_count += - skb_shinfo(skb)->nr_frags; + skb_shinfo(skb)->nr_frags; else - rx_ring->rx_stats.rsc_count++; + rx_ring->rx_stats.rsc_count += + IXGBE_RSC_CB(skb)->skb_cnt; rx_ring->rx_stats.rsc_flush++; } @@ -3017,7 +3019,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) } #endif /* IXGBE_FCOE */ } - } static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) -- cgit v1.2.3-59-g8ed1b From bd50817859e7e82ba6e4adc75ebd8ac19459d8a4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:03 -0800 Subject: ixgbe: change mac_type if statements to switch statements This change replaces a number of if/elseif/else statements with switch statements to support the addition of future devices to the ixgbe driver. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 45 +++-- drivers/net/ixgbe/ixgbe_main.c | 351 +++++++++++++++++++++++--------------- 2 files changed, 252 insertions(+), 144 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 561d47895d82..9483faf91ea4 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -525,10 +525,20 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[32] = IXGBE_READ_REG(hw, IXGBE_FCTTV(1)); regs_buff[33] = IXGBE_READ_REG(hw, IXGBE_FCTTV(2)); regs_buff[34] = IXGBE_READ_REG(hw, IXGBE_FCTTV(3)); - for (i = 0; i < 8; i++) - regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i)); - for (i = 0; i < 8; i++) - regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i)); + for (i = 0; i < 8; i++) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i)); + regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i)); + break; + case ixgbe_mac_82599EB: + regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i)); + regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i)); + break; + default: + break; + } + } regs_buff[51] = IXGBE_READ_REG(hw, IXGBE_FCRTV); regs_buff[52] = IXGBE_READ_REG(hw, IXGBE_TFCS); @@ -1226,12 +1236,19 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) u32 value, before, after; u32 i, toggle; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - toggle = 0x7FFFF30F; - test = reg_test_82599; - } else { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: toggle = 0x7FFFF3FF; test = reg_test_82598; + break; + case ixgbe_mac_82599EB: + toggle = 0x7FFFF30F; + test = reg_test_82599; + break; + default: + *data = 1; + return 1; + break; } /* @@ -1449,10 +1466,14 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) reg_ctl &= ~IXGBE_TXDCTL_ENABLE; IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl); - if (hw->mac.type == ixgbe_mac_82599EB) { + switch (hw->mac.type) { + case ixgbe_mac_82599EB: reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); + break; + default: + break; } ixgbe_reset(adapter); @@ -1481,10 +1502,14 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) if (err) return 1; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); + break; + default: + break; } ixgbe_configure_tx_ring(adapter, tx_ring); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 9f5331bc5985..10fff68088e6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -589,14 +589,19 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, { u32 mask; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: mask = (IXGBE_EIMS_RTX_QUEUE & qmask); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - } else { + break; + case ixgbe_mac_82599EB: mask = (qmask & 0xFFFFFFFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); mask = (qmask >> 32); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask); + break; + default: + break; } } @@ -672,6 +677,7 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, break; default: tc = 0; + break; } txoff <<= tc; } @@ -1474,11 +1480,18 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) } } - if (adapter->hw.mac.type == ixgbe_mac_82598EB) + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx); - else if (adapter->hw.mac.type == ixgbe_mac_82599EB) + break; + case ixgbe_mac_82599EB: ixgbe_set_ivar(adapter, -1, 1, v_idx); + break; + + default: + break; + } IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); /* set up to autoclear timer, and the vectors */ @@ -1574,10 +1587,12 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) int v_idx = q_vector->v_idx; u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: /* must write high and low 16 bits to reset counter */ itr_reg |= (itr_reg << 16); - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + break; + case ixgbe_mac_82599EB: /* * 82599 can support a value of zero, so allow it for * max interrupt rate, but there is an errata where it can @@ -1592,6 +1607,9 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) * immediate assertion of the interrupt */ itr_reg |= IXGBE_EITR_CNT_WDIS; + break; + default: + break; } IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg); } @@ -1771,16 +1789,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) if (eicr & IXGBE_EICR_MAILBOX) ixgbe_msg_task(adapter); - if (hw->mac.type == ixgbe_mac_82598EB) - ixgbe_check_fan_failure(adapter, eicr); - - if (hw->mac.type == ixgbe_mac_82599EB) { - ixgbe_check_sfp_event(adapter, eicr); - adapter->interrupt_event = eicr; - if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && - ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) - schedule_work(&adapter->check_overtemp_task); - + switch (hw->mac.type) { + case ixgbe_mac_82599EB: /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { int i; @@ -1795,7 +1805,19 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) schedule_work(&adapter->fdir_reinit_task); } } + ixgbe_check_sfp_event(adapter, eicr); + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { + adapter->interrupt_event = eicr; + schedule_work(&adapter->check_overtemp_task); + } + break; + default: + break; } + + ixgbe_check_fan_failure(adapter, eicr); + if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); @@ -1806,15 +1828,23 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, u64 qmask) { u32 mask; + struct ixgbe_hw *hw = &adapter->hw; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - } else { + IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); + break; + case ixgbe_mac_82599EB: mask = (qmask & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); mask = (qmask >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); + break; + default: + break; } /* skip the flush */ } @@ -1823,15 +1853,23 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, u64 qmask) { u32 mask; + struct ixgbe_hw *hw = &adapter->hw; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask); - } else { + IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask); + break; + case ixgbe_mac_82599EB: mask = (qmask & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); mask = (qmask >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask); + break; + default: + break; } /* skip the flush */ } @@ -2288,12 +2326,16 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, mask |= IXGBE_EIMS_GPI_SDP0; if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) mask |= IXGBE_EIMS_GPI_SDP1; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: mask |= IXGBE_EIMS_ECC; mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; if (adapter->num_vfs) mask |= IXGBE_EIMS_MAILBOX; + break; + default: + break; } if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) @@ -2349,13 +2391,20 @@ static irqreturn_t ixgbe_intr(int irq, void *data) if (eicr & IXGBE_EICR_LSC) ixgbe_check_lsc(adapter); - if (hw->mac.type == ixgbe_mac_82599EB) + switch (hw->mac.type) { + case ixgbe_mac_82599EB: ixgbe_check_sfp_event(adapter, eicr); + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { + adapter->interrupt_event = eicr; + schedule_work(&adapter->check_overtemp_task); + } + break; + default: + break; + } ixgbe_check_fan_failure(adapter, eicr); - if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && - ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) - schedule_work(&adapter->check_overtemp_task); if (napi_schedule_prep(&(q_vector->napi))) { adapter->tx_ring[0]->total_packets = 0; @@ -2448,14 +2497,19 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) **/ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) { - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); - } else { + break; + case ixgbe_mac_82599EB: IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); if (adapter->num_vfs > 32) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0); + break; + default: + break; } IXGBE_WRITE_FLUSH(&adapter->hw); if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { @@ -2630,15 +2684,20 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring) { u32 srrctl; - int index; - struct ixgbe_ring_feature *feature = adapter->ring_feature; + int index = rx_ring->reg_idx; - index = rx_ring->reg_idx; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - unsigned long mask; - mask = (unsigned long) feature[RING_F_RSS].mask; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: { + struct ixgbe_ring_feature *feature = adapter->ring_feature; + const int mask = feature[RING_F_RSS].mask; index = index & mask; } + break; + case ixgbe_mac_82599EB: + default: + break; + } + srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index)); srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; @@ -3899,10 +3958,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter) (txdctl & ~IXGBE_TXDCTL_ENABLE)); } /* Disable the Tx DMA engine on 82599 */ - if (hw->mac.type == ixgbe_mac_82599EB) + switch (hw->mac.type) { + case ixgbe_mac_82599EB: IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & ~IXGBE_DMATXCTL_TE)); + break; + default: + break; + } /* power down the optics */ if (hw->phy.multispeed_fiber) @@ -4260,71 +4324,66 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) bool ret = false; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - /* the number of queues is assumed to be symmetric */ - for (i = 0; i < dcb_i; i++) { - adapter->rx_ring[i]->reg_idx = i << 3; - adapter->tx_ring[i]->reg_idx = i << 2; - } - ret = true; - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - if (dcb_i == 8) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 32 - * Tx TC2 starts at: descriptor queue 64 - * Tx TC3 starts at: descriptor queue 80 - * Tx TC4 starts at: descriptor queue 96 - * Tx TC5 starts at: descriptor queue 104 - * Tx TC6 starts at: descriptor queue 112 - * Tx TC7 starts at: descriptor queue 120 - * - * Rx TC0-TC7 are offset by 16 queues each - */ - for (i = 0; i < 3; i++) { - adapter->tx_ring[i]->reg_idx = i << 5; - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < 5; i++) { - adapter->tx_ring[i]->reg_idx = - ((i + 2) << 4); - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < dcb_i; i++) { - adapter->tx_ring[i]->reg_idx = - ((i + 8) << 3); - adapter->rx_ring[i]->reg_idx = i << 4; - } + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return false; - ret = true; - } else if (dcb_i == 4) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 64 - * Tx TC2 starts at: descriptor queue 96 - * Tx TC3 starts at: descriptor queue 112 - * - * Rx TC0-TC3 are offset by 32 queues each - */ - adapter->tx_ring[0]->reg_idx = 0; - adapter->tx_ring[1]->reg_idx = 64; - adapter->tx_ring[2]->reg_idx = 96; - adapter->tx_ring[3]->reg_idx = 112; - for (i = 0 ; i < dcb_i; i++) - adapter->rx_ring[i]->reg_idx = i << 5; - - ret = true; - } else { - ret = false; + /* the number of queues is assumed to be symmetric */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + for (i = 0; i < dcb_i; i++) { + adapter->rx_ring[i]->reg_idx = i << 3; + adapter->tx_ring[i]->reg_idx = i << 2; + } + ret = true; + break; + case ixgbe_mac_82599EB: + if (dcb_i == 8) { + /* + * Tx TC0 starts at: descriptor queue 0 + * Tx TC1 starts at: descriptor queue 32 + * Tx TC2 starts at: descriptor queue 64 + * Tx TC3 starts at: descriptor queue 80 + * Tx TC4 starts at: descriptor queue 96 + * Tx TC5 starts at: descriptor queue 104 + * Tx TC6 starts at: descriptor queue 112 + * Tx TC7 starts at: descriptor queue 120 + * + * Rx TC0-TC7 are offset by 16 queues each + */ + for (i = 0; i < 3; i++) { + adapter->tx_ring[i]->reg_idx = i << 5; + adapter->rx_ring[i]->reg_idx = i << 4; } - } else { - ret = false; + for ( ; i < 5; i++) { + adapter->tx_ring[i]->reg_idx = ((i + 2) << 4); + adapter->rx_ring[i]->reg_idx = i << 4; + } + for ( ; i < dcb_i; i++) { + adapter->tx_ring[i]->reg_idx = ((i + 8) << 3); + adapter->rx_ring[i]->reg_idx = i << 4; + } + ret = true; + } else if (dcb_i == 4) { + /* + * Tx TC0 starts at: descriptor queue 0 + * Tx TC1 starts at: descriptor queue 64 + * Tx TC2 starts at: descriptor queue 96 + * Tx TC3 starts at: descriptor queue 112 + * + * Rx TC0-TC3 are offset by 32 queues each + */ + adapter->tx_ring[0]->reg_idx = 0; + adapter->tx_ring[1]->reg_idx = 64; + adapter->tx_ring[2]->reg_idx = 96; + adapter->tx_ring[3]->reg_idx = 112; + for (i = 0 ; i < dcb_i; i++) + adapter->rx_ring[i]->reg_idx = i << 5; + ret = true; } - } else { - ret = false; + break; + default: + break; } - return ret; } #endif @@ -4885,11 +4944,13 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->ring_feature[RING_F_RSS].indices = rss; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: if (hw->device_id == IXGBE_DEV_ID_82598AT) adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; - } else if (hw->mac.type == ixgbe_mac_82599EB) { + break; + case ixgbe_mac_82599EB: adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; @@ -4918,6 +4979,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->fcoe.up = IXGBE_FCOE_DEFTC; #endif #endif /* IXGBE_FCOE */ + break; + default: + break; } #ifdef CONFIG_IXGBE_DCB @@ -5400,10 +5464,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); } - if (wufc && hw->mac.type == ixgbe_mac_82599EB) - pci_wake_from_d3(pdev, true); - else + switch (hw->mac.type) { + case ixgbe_mac_82598EB: pci_wake_from_d3(pdev, false); + break; + case ixgbe_mac_82599EB: + pci_wake_from_d3(pdev, !!wufc); + break; + default: + break; + } *enable_wake = !!wufc; @@ -5522,17 +5592,21 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); - if (hw->mac.type == ixgbe_mac_82599EB) { - hwstats->pxonrxc[i] += - IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); - hwstats->pxoffrxc[i] += - IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); - hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); - } else { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); hwstats->pxoffrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + break; + case ixgbe_mac_82599EB: + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + break; + default: + break; } hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); @@ -5542,18 +5616,21 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->gprc -= missed_rx; /* 82598 hardware only has a 32 bit counter in the high register */ - if (hw->mac.type == ixgbe_mac_82599EB) { - u64 tmp; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); + break; + case ixgbe_mac_82599EB: hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; - /* 4 high bits of GORC */ - hwstats->gorc += (tmp << 32); + IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; - /* 4 high bits of GOTC */ - hwstats->gotc += (tmp << 32); + IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); - IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ + IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); @@ -5566,12 +5643,9 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); #endif /* IXGBE_FCOE */ - } else { - hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); + break; + default: + break; } bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); hwstats->bprc += bprc; @@ -5807,17 +5881,26 @@ static void ixgbe_watchdog_task(struct work_struct *work) if (!netif_carrier_ok(netdev)) { bool flow_rx, flow_tx; - if (hw->mac.type == ixgbe_mac_82599EB) { - u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); - u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); - flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); - flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); - } else { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: { u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); } + break; + case ixgbe_mac_82599EB: { + u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); + u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); + flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); + flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); + } + break; + default: + flow_tx = false; + flow_rx = false; + break; + } e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? -- cgit v1.2.3-59-g8ed1b From e2b4e216b7e9da09175c76887c754489681533b9 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:04 -0800 Subject: ixgbe: cleanup ixgbe_set_tx_csum ethtool flags configuration This change makes it so that we always disable SCTP regardless of mac type since we shouldn't need to check mac type before disabling a feature that isn't supported on a given piece of hardware. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 9483faf91ea4..f61a8ce908ed 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -425,13 +425,12 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) struct ixgbe_adapter *adapter = netdev_priv(netdev); if (data) { - netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (adapter->hw.mac.type == ixgbe_mac_82599EB) netdev->features |= NETIF_F_SCTP_CSUM; } else { - netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) - netdev->features &= ~NETIF_F_SCTP_CSUM; + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_SCTP_CSUM); } return 0; -- cgit v1.2.3-59-g8ed1b From 50d6c681d0c38208e494f0c6302ef13d21dababa Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:05 -0800 Subject: ixgbe: add WOL support for backplane adapters This change adds support for certain 82599 based Mezzanine adapters. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 17 +++++++++++++++++ drivers/net/ixgbe/ixgbe_main.c | 7 +++++++ drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 25 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f61a8ce908ed..0a4b322fab6a 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -185,6 +185,16 @@ static int ixgbe_get_settings(struct net_device *netdev, ADVERTISED_FIBRE); ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; + } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE) || + (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) { + ecmd->supported |= (SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE); + ecmd->advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | + ADVERTISED_Autoneg | + ADVERTISED_FIBRE); + ecmd->port = PORT_FIBRE; } else { ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE); @@ -1862,6 +1872,13 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, int retval = 1; switch(hw->device_id) { + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + /* All except this subdevice support WOL */ + if (hw->subsystem_device_id == + IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) { + wol->supported = 0; + break; + } case IXGBE_DEV_ID_82599_KX4: retval = 0; break; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 10fff68088e6..af4ef29cae11 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7088,6 +7088,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_sw_init; switch (pdev->device) { + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + /* All except this subdevice support WOL */ + if (pdev->subsystem_device == + IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) { + adapter->wol = 0; + break; + } case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | IXGBE_WUFC_MC | IXGBE_WUFC_BC); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 96dea7731e68..9e6908dff9bc 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -57,6 +57,7 @@ #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 +#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C /* General Registers */ #define IXGBE_CTRL 0x00000 -- cgit v1.2.3-59-g8ed1b From 673ac60461082e07be58b23f237d651c2605ce60 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:05 -0800 Subject: ixgbe: Cleanup DCB logic, whitespace, and comments in ixgbe_ethtool.c This change address a few whitespace issues in DCB #ifdefs, adds a comment calling out the DCB specific registers, and nests an if statement inline with a number of if statements related to flow control. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 0a4b322fab6a..6871b2be64f6 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -342,13 +342,6 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, else pause->autoneg = 1; -#ifdef CONFIG_DCB - if (hw->fc.current_mode == ixgbe_fc_pfc) { - pause->rx_pause = 0; - pause->tx_pause = 0; - } - -#endif if (hw->fc.current_mode == ixgbe_fc_rx_pause) { pause->rx_pause = 1; } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) { @@ -356,6 +349,11 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, } else if (hw->fc.current_mode == ixgbe_fc_full) { pause->rx_pause = 1; pause->tx_pause = 1; +#ifdef CONFIG_DCB + } else if (hw->fc.current_mode == ixgbe_fc_pfc) { + pause->rx_pause = 0; + pause->tx_pause = 0; +#endif } } @@ -373,7 +371,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return -EINVAL; #endif - fc = hw->fc; if (pause->autoneg != AUTONEG_ENABLE) @@ -629,6 +626,7 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM); regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0)); + /* DCB */ regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS); regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS); regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS); -- cgit v1.2.3-59-g8ed1b From 9d6b758f428d2ad9ca4208d5c4d4cdbd4261b0d8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:06 -0800 Subject: ixgbe: cleanup unnecessary return value in ixgbe_cache_ring_rss This change is just to cleanup some confusing logic in ixgbe_cache_ring_rss which can be simplified by adding a conditional with return to the start of the call. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index af4ef29cae11..5f7929f52fe4 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4295,19 +4295,16 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) { int i; - bool ret = false; - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i]->reg_idx = i; - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_ring[i]->reg_idx = i; - ret = true; - } else { - ret = false; - } + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + return false; - return ret; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i]->reg_idx = i; + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i]->reg_idx = i; + + return true; } #ifdef CONFIG_IXGBE_DCB -- cgit v1.2.3-59-g8ed1b From bf29ee6c4819a86ba0209281550b230889b8ebe6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:07 -0800 Subject: ixgbe: cleanup unclear references to reg_idx There are a number of places where we use the variable j to contain the register index of the ring. Instead of using such a non-descriptive variable name it is better that we name it reg_idx so that it is clear what the variable contains. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 120 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5f7929f52fe4..f2e81a21186a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -647,8 +647,8 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, #ifdef CONFIG_IXGBE_DCB if (adapter->dcb_cfg.pfc_mode_enable) { int tc; - int reg_idx = tx_ring->reg_idx; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; + u8 reg_idx = tx_ring->reg_idx; switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: @@ -1422,7 +1422,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *, int); static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) { struct ixgbe_q_vector *q_vector; - int i, j, q_vectors, v_idx, r_idx; + int i, q_vectors, v_idx, r_idx; u32 mask; q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; @@ -1438,8 +1438,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { - j = adapter->rx_ring[r_idx]->reg_idx; - ixgbe_set_ivar(adapter, 0, j, v_idx); + u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx; + ixgbe_set_ivar(adapter, 0, reg_idx, v_idx); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, r_idx + 1); @@ -1448,8 +1448,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { - j = adapter->tx_ring[r_idx]->reg_idx; - ixgbe_set_ivar(adapter, 1, j, v_idx); + u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx; + ixgbe_set_ivar(adapter, 1, reg_idx, v_idx); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); @@ -2555,7 +2555,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, u64 tdba = ring->dma; int wait_loop = 10; u32 txdctl; - u16 reg_idx = ring->reg_idx; + u8 reg_idx = ring->reg_idx; /* disable queue to avoid issues while updating state */ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); @@ -2684,13 +2684,13 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring) { u32 srrctl; - int index = rx_ring->reg_idx; + u8 reg_idx = rx_ring->reg_idx; switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: { struct ixgbe_ring_feature *feature = adapter->ring_feature; const int mask = feature[RING_F_RSS].mask; - index = index & mask; + reg_idx = reg_idx & mask; } break; case ixgbe_mac_82599EB: @@ -2698,7 +2698,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, break; } - srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index)); + srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx)); srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; @@ -2721,7 +2721,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx), srrctl); } static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) @@ -2801,7 +2801,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; u32 rscctrl; int rx_buf_len; - u16 reg_idx = ring->reg_idx; + u8 reg_idx = ring->reg_idx; if (!ring_is_rsc_enabled(ring)) return; @@ -2867,9 +2867,9 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; - int reg_idx = ring->reg_idx; int wait_loop = IXGBE_MAX_RX_DESC_POLL; u32 rxdctl; + u8 reg_idx = ring->reg_idx; /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB && @@ -2893,7 +2893,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; u64 rdba = ring->dma; u32 rxdctl; - u16 reg_idx = ring->reg_idx; + u8 reg_idx = ring->reg_idx; /* disable queue to avoid issues while updating state */ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); @@ -3894,7 +3894,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; u32 txdctl; - int i, j; + int i; int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; /* signal that we are down to the interrupt handler */ @@ -3952,9 +3952,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* disable transmits in the hardware now that interrupts are off */ for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), + u8 reg_idx = adapter->tx_ring[i]->reg_idx; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), (txdctl & ~IXGBE_TXDCTL_ENABLE)); } /* Disable the Tx DMA engine on 82599 */ @@ -4420,55 +4420,55 @@ static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) */ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) { - int i, fcoe_rx_i = 0, fcoe_tx_i = 0; - bool ret = false; struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; + int i; + u8 fcoe_rx_i = 0, fcoe_tx_i = 0; + + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return false; - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - struct ixgbe_fcoe *fcoe = &adapter->fcoe; + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + struct ixgbe_fcoe *fcoe = &adapter->fcoe; - ixgbe_cache_ring_dcb(adapter); - /* find out queues in TC for FCoE */ - fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1; - fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1; - /* - * In 82599, the number of Tx queues for each traffic - * class for both 8-TC and 4-TC modes are: - * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 - * 8 TCs: 32 32 16 16 8 8 8 8 - * 4 TCs: 64 64 32 32 - * We have max 8 queues for FCoE, where 8 the is - * FCoE redirection table size. If TC for FCoE is - * less than or equal to TC3, we have enough queues - * to add max of 8 queues for FCoE, so we start FCoE - * tx descriptor from the next one, i.e., reg_idx + 1. - * If TC for FCoE is above TC3, implying 8 TC mode, - * and we need 8 for FCoE, we have to take all queues - * in that traffic class for FCoE. - */ - if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) - fcoe_tx_i--; - } + ixgbe_cache_ring_dcb(adapter); + /* find out queues in TC for FCoE */ + fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1; + fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1; + /* + * In 82599, the number of Tx queues for each traffic + * class for both 8-TC and 4-TC modes are: + * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 + * 8 TCs: 32 32 16 16 8 8 8 8 + * 4 TCs: 64 64 32 32 + * We have max 8 queues for FCoE, where 8 the is + * FCoE redirection table size. If TC for FCoE is + * less than or equal to TC3, we have enough queues + * to add max of 8 queues for FCoE, so we start FCoE + * Tx queue from the next one, i.e., reg_idx + 1. + * If TC for FCoE is above TC3, implying 8 TC mode, + * and we need 8 for FCoE, we have to take all queues + * in that traffic class for FCoE. + */ + if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) + fcoe_tx_i--; + } #endif /* CONFIG_IXGBE_DCB */ - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) - ixgbe_cache_ring_fdir(adapter); - else - ixgbe_cache_ring_rss(adapter); + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + ixgbe_cache_ring_fdir(adapter); + else + ixgbe_cache_ring_rss(adapter); - fcoe_rx_i = f->mask; - fcoe_tx_i = f->mask; - } - for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { - adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i; - adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i; - } - ret = true; + fcoe_rx_i = f->mask; + fcoe_tx_i = f->mask; } - return ret; + for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { + adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i; + adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i; + } + return true; } #endif /* IXGBE_FCOE */ -- cgit v1.2.3-59-g8ed1b From 125601bf03a13e24d3785ccbc3a25ad401c92772 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:08 -0800 Subject: ixgbe: simplify math and improve stack use of ixgbe_set_itr functions This change is meant to improve the stack utilization and simplify the math used in ixgbe_set_itr_msix. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f2e81a21186a..3ad754824ffa 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1617,14 +1617,13 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) { struct ixgbe_adapter *adapter = q_vector->adapter; + int i, r_idx; u32 new_itr; u8 current_itr, ret_itr; - int i, r_idx; - struct ixgbe_ring *rx_ring, *tx_ring; r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { - tx_ring = adapter->tx_ring[r_idx]; + struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, q_vector->tx_itr, tx_ring->total_packets, @@ -1639,7 +1638,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { - rx_ring = adapter->rx_ring[r_idx]; + struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, q_vector->rx_itr, rx_ring->total_packets, @@ -1670,7 +1669,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + new_itr = ((q_vector->eitr * 9) + new_itr)/10; /* save the algorithm value here, not the smoothed one */ q_vector->eitr = new_itr; @@ -2270,10 +2269,10 @@ out: static void ixgbe_set_itr(struct ixgbe_adapter *adapter) { struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; - u8 current_itr; - u32 new_itr = q_vector->eitr; struct ixgbe_ring *rx_ring = adapter->rx_ring[0]; struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; + u32 new_itr = q_vector->eitr; + u8 current_itr; q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, q_vector->tx_itr, @@ -2303,9 +2302,9 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + new_itr = ((q_vector->eitr * 9) + new_itr)/10; - /* save the algorithm value here, not the smoothed one */ + /* save the algorithm value here */ q_vector->eitr = new_itr; ixgbe_write_eitr(q_vector); -- cgit v1.2.3-59-g8ed1b From d0759ebb051972f8557a19aa13cf02fc314856e9 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:09 -0800 Subject: ixgbe: cleanup ixgbe_map_rings_to_vectors This change cleans up some of the items in ixgbe_map_rings_to_vectors. Specifically it merges the two for loops and drops the unnecessary vectors parameter. It also moves the vector names into the q_vectors themselves. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 3 ++- drivers/net/ixgbe/ixgbe_main.c | 55 +++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 6d9fcb4e0854..ce43c9352681 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -282,6 +282,7 @@ struct ixgbe_q_vector { u8 rx_itr; u32 eitr; cpumask_var_t affinity_mask; + char name[IFNAMSIZ + 9]; }; /* Helper macros to switch between ints/sec and what the register uses. @@ -330,7 +331,6 @@ struct ixgbe_adapter { u16 bd_number; struct work_struct reset_task; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; - char name[MAX_MSIX_COUNT][IFNAMSIZ + 9]; struct ixgbe_dcb_config dcb_cfg; struct ixgbe_dcb_config temp_dcb_cfg; u8 dcb_set_bitmap; @@ -453,6 +453,7 @@ struct ixgbe_adapter { int node; struct work_struct check_overtemp_task; u32 interrupt_event; + char lsc_int_name[IFNAMSIZ + 9]; /* SR-IOV */ DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3ad754824ffa..0d6422c59723 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2130,7 +2130,6 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, /** * ixgbe_map_rings_to_vectors - Maps descriptor rings to vectors * @adapter: board private structure to initialize - * @vectors: allotted vector count for descriptor rings * * This function maps descriptor rings to the queue-specific vectors * we were allotted through the MSI-X enabling code. Ideally, we'd have @@ -2138,9 +2137,9 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, * group the rings as "efficiently" as possible. You would add new * mapping configurations in here. **/ -static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, - int vectors) +static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter) { + int q_vectors; int v_start = 0; int rxr_idx = 0, txr_idx = 0; int rxr_remaining = adapter->num_rx_queues; @@ -2153,11 +2152,13 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) goto out; + q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + /* * The ideal configuration... * We have enough vectors to map one per queue. */ - if (vectors == adapter->num_rx_queues + adapter->num_tx_queues) { + if (q_vectors == adapter->num_rx_queues + adapter->num_tx_queues) { for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++) map_vector_to_rxq(adapter, v_start, rxr_idx); @@ -2173,23 +2174,20 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, * multiple queues per vector. */ /* Re-adjusting *qpv takes care of the remainder. */ - for (i = v_start; i < vectors; i++) { - rqpv = DIV_ROUND_UP(rxr_remaining, vectors - i); + for (i = v_start; i < q_vectors; i++) { + rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - i); for (j = 0; j < rqpv; j++) { map_vector_to_rxq(adapter, i, rxr_idx); rxr_idx++; rxr_remaining--; } - } - for (i = v_start; i < vectors; i++) { - tqpv = DIV_ROUND_UP(txr_remaining, vectors - i); + tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - i); for (j = 0; j < tqpv; j++) { map_vector_to_txq(adapter, i, txr_idx); txr_idx++; txr_remaining--; } } - out: return err; } @@ -2211,32 +2209,36 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) /* Decrement for Other and TCP Timer vectors */ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - /* Map the Tx/Rx rings to the vectors we were allotted. */ - err = ixgbe_map_rings_to_vectors(adapter, q_vectors); + err = ixgbe_map_rings_to_vectors(adapter); if (err) - goto out; + return err; -#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \ - (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ - &ixgbe_msix_clean_many) +#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \ + ? &ixgbe_msix_clean_many : \ + (_v)->rxr_count ? &ixgbe_msix_clean_rx : \ + (_v)->txr_count ? &ixgbe_msix_clean_tx : \ + NULL) for (vector = 0; vector < q_vectors; vector++) { - handler = SET_HANDLER(adapter->q_vector[vector]); + struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; + handler = SET_HANDLER(q_vector); if (handler == &ixgbe_msix_clean_rx) { - sprintf(adapter->name[vector], "%s-%s-%d", + sprintf(q_vector->name, "%s-%s-%d", netdev->name, "rx", ri++); } else if (handler == &ixgbe_msix_clean_tx) { - sprintf(adapter->name[vector], "%s-%s-%d", + sprintf(q_vector->name, "%s-%s-%d", netdev->name, "tx", ti++); - } else { - sprintf(adapter->name[vector], "%s-%s-%d", + } else if (handler == &ixgbe_msix_clean_many) { + sprintf(q_vector->name, "%s-%s-%d", netdev->name, "TxRx", ri++); ti++; + } else { + /* skip this unused q_vector */ + continue; } - err = request_irq(adapter->msix_entries[vector].vector, - handler, 0, adapter->name[vector], - adapter->q_vector[vector]); + handler, 0, q_vector->name, + q_vector); if (err) { e_err(probe, "request_irq failed for MSIX interrupt " "Error: %d\n", err); @@ -2244,9 +2246,9 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) } } - sprintf(adapter->name[vector], "%s:lsc", netdev->name); + sprintf(adapter->lsc_int_name, "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - ixgbe_msix_lsc, 0, adapter->name[vector], netdev); + ixgbe_msix_lsc, 0, adapter->lsc_int_name, netdev); if (err) { e_err(probe, "request_irq for msix_lsc failed: %d\n", err); goto free_queue_irqs; @@ -2262,7 +2264,6 @@ free_queue_irqs: pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); adapter->msix_entries = NULL; -out: return err; } -- cgit v1.2.3-59-g8ed1b From 2274543f15133165b855b9a4a1503b2c1268c6cf Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:10 -0800 Subject: ixgbe: populate the ring->q_vector pointer during ring mapping The q_vector back pointer was not being set in the rings so it would not have been possible to determine the parent q_vector of the ring. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0d6422c59723..38dd85340352 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2113,18 +2113,22 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, int r_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; + struct ixgbe_ring *rx_ring = a->rx_ring[r_idx]; set_bit(r_idx, q_vector->rxr_idx); q_vector->rxr_count++; + rx_ring->q_vector = q_vector; } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, int t_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; + struct ixgbe_ring *tx_ring = a->tx_ring[t_idx]; set_bit(t_idx, q_vector->txr_idx); q_vector->txr_count++; + tx_ring->q_vector = q_vector; } /** -- cgit v1.2.3-59-g8ed1b From e3de4b7bdfd2c06884c95cfb4ad4d64be046595e Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 16 Nov 2010 19:27:11 -0800 Subject: ixgbe: Resolve null function pointer accesses on 82598 w/ multi-speed fiber This change resolves some null function pointer accesses on 82598 when a multi-speed fiber module is inserted into the adapter. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 38dd85340352..def5c6e047cf 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3661,7 +3661,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ixgbe_configure_msi_and_legacy(adapter); /* enable the optics */ - if (hw->phy.multispeed_fiber) + if (hw->phy.multispeed_fiber && hw->mac.ops.enable_tx_laser) hw->mac.ops.enable_tx_laser(hw); clear_bit(__IXGBE_DOWN, &adapter->state); @@ -3973,7 +3973,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) } /* power down the optics */ - if (hw->phy.multispeed_fiber) + if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) hw->mac.ops.disable_tx_laser(hw); /* clear n-tuple filters that are cached */ @@ -7074,7 +7074,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } /* power down the optics */ - if (hw->phy.multispeed_fiber) + if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) hw->mac.ops.disable_tx_laser(hw); init_timer(&adapter->watchdog_timer); -- cgit v1.2.3-59-g8ed1b From c84d324c770dc81acebc1042163da33c8ded2364 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 16 Nov 2010 19:27:12 -0800 Subject: ixgbe: rework Tx hang detection to fix reoccurring false Tx hangs The Tx hang logic has been known to detect false hangs when the device is receiving pause frames or has delayed processing for some other reason. This patch makes the logic more robust and resolves these known issues. The old logic checked to see if the device was paused by querying the HW then the hang logic was aborted if the device was currently paused. This check was racy because the device could have been in the pause state any time up to this check. The other operation of the hang logic is to verify the Tx ring is still advancing the old logic checked the EOP timestamp. This is not sufficient to determine the ring is not advancing but only infers that it may be moving slowly. Here we add logic to track the number of completed Tx descriptors and use the adapter stats to check if any pause frames have been received since the previous Tx hang check. This way we avoid racing with the HW register and do not detect false hangs if the ring is advancing slowly. This patch is primarily the work of Jesse Brandeburg. I clean it up some and fixed the PFC checking. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 + drivers/net/ixgbe/ixgbe_main.c | 250 ++++++++++++++++++++++++++++------------- 2 files changed, 175 insertions(+), 79 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index ce43c9352681..2b8cbb3a81fa 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -149,6 +149,8 @@ struct ixgbe_queue_stats { struct ixgbe_tx_queue_stats { u64 restart_queue; u64 tx_busy; + u64 completed; + u64 tx_done_old; }; struct ixgbe_rx_queue_stats { @@ -162,6 +164,7 @@ struct ixgbe_rx_queue_stats { enum ixbge_ring_state_t { __IXGBE_TX_FDIR_INIT_DONE, __IXGBE_TX_DETECT_HANG, + __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_PS_ENABLED, __IXGBE_RX_RSC_ENABLED, }; @@ -514,6 +517,7 @@ extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); +extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index def5c6e047cf..6e56f7b7c8fd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -630,93 +630,166 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, } /** - * ixgbe_tx_xon_state - check the tx ring xon state - * @adapter: the ixgbe adapter - * @tx_ring: the corresponding tx_ring + * ixgbe_dcb_txq_to_tc - convert a reg index to a traffic class + * @adapter: driver private struct + * @index: reg idx of queue to query (0-127) * - * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the - * corresponding TC of this tx_ring when checking TFCS. + * Helper function to determine the traffic index for a paticular + * register index. * - * Returns : true if in xon state (currently not paused) + * Returns : a tc index for use in range 0-7, or 0-3 */ -static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) +u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) { - u32 txoff = IXGBE_TFCS_TXOFF; + int tc = -1; + int dcb_i = adapter->ring_feature[RING_F_DCB].indices; -#ifdef CONFIG_IXGBE_DCB - if (adapter->dcb_cfg.pfc_mode_enable) { - int tc; - int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - u8 reg_idx = tx_ring->reg_idx; + /* if DCB is not enabled the queues have no TC */ + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return tc; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - tc = reg_idx >> 2; - txoff = IXGBE_TFCS_TXOFF0; + /* check valid range */ + if (reg_idx >= adapter->hw.mac.max_tx_queues) + return tc; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + tc = reg_idx >> 2; + break; + default: + if (dcb_i != 4 && dcb_i != 8) break; - case ixgbe_mac_82599EB: - tc = 0; - txoff = IXGBE_TFCS_TXOFF; - if (dcb_i == 8) { - /* TC0, TC1 */ - tc = reg_idx >> 5; - if (tc == 2) /* TC2, TC3 */ - tc += (reg_idx - 64) >> 4; - else if (tc == 3) /* TC4, TC5, TC6, TC7 */ - tc += 1 + ((reg_idx - 96) >> 3); - } else if (dcb_i == 4) { - /* TC0, TC1 */ - tc = reg_idx >> 6; - if (tc == 1) { - tc += (reg_idx - 64) >> 5; - if (tc == 2) /* TC2, TC3 */ - tc += (reg_idx - 96) >> 4; - } - } + + /* if VMDq is enabled the lowest order bits determine TC */ + if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED | + IXGBE_FLAG_VMDQ_ENABLED)) { + tc = reg_idx & (dcb_i - 1); + break; + } + + /* + * Convert the reg_idx into the correct TC. This bitmask + * targets the last full 32 ring traffic class and assigns + * it a value of 1. From there the rest of the rings are + * based on shifting the mask further up to include the + * reg_idx / 16 and then reg_idx / 8. It assumes dcB_i + * will only ever be 8 or 4 and that reg_idx will never + * be greater then 128. The code without the power of 2 + * optimizations would be: + * (((reg_idx % 32) + 32) * dcb_i) >> (9 - reg_idx / 32) + */ + tc = ((reg_idx & 0X1F) + 0x20) * dcb_i; + tc >>= 9 - (reg_idx >> 5); + } + + return tc; +} + +static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; + u32 data = 0; + u32 xoff[8] = {0}; + int i; + + if ((hw->fc.current_mode == ixgbe_fc_full) || + (hw->fc.current_mode == ixgbe_fc_rx_pause)) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); break; default: - tc = 0; + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } + hwstats->lxoffrxc += data; + + /* refill credits (no tx hang) if we received xoff */ + if (!data) + return; + + for (i = 0; i < adapter->num_tx_queues; i++) + clear_bit(__IXGBE_HANG_CHECK_ARMED, + &adapter->tx_ring[i]->state); + return; + } else if (!(adapter->dcb_cfg.pfc_mode_enable)) + return; + + /* update stats for each tc, only valid with PFC enabled */ + for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); break; + default: + xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); } - txoff <<= tc; + hwstats->pxoffrxc[i] += xoff[i]; + } + + /* disarm tx queues that have received xoff frames */ + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + u32 tc = ixgbe_dcb_txq_to_tc(adapter, tx_ring->reg_idx); + + if (xoff[tc]) + clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); } -#endif - return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff; } -static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - unsigned int eop) +static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring) { + return ring->tx_stats.completed; +} + +static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring) +{ + struct ixgbe_adapter *adapter = netdev_priv(ring->netdev); struct ixgbe_hw *hw = &adapter->hw; - /* Detect a transmit hang in hardware, this serializes the - * check with the clearing of time_stamp and movement of eop */ + u32 head = IXGBE_READ_REG(hw, IXGBE_TDH(ring->reg_idx)); + u32 tail = IXGBE_READ_REG(hw, IXGBE_TDT(ring->reg_idx)); + + if (head != tail) + return (head < tail) ? + tail - head : (tail + ring->count - head); + + return 0; +} + +static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) +{ + u32 tx_done = ixgbe_get_tx_completed(tx_ring); + u32 tx_done_old = tx_ring->tx_stats.tx_done_old; + u32 tx_pending = ixgbe_get_tx_pending(tx_ring); + bool ret = false; + clear_check_for_tx_hang(tx_ring); - if (tx_ring->tx_buffer_info[eop].time_stamp && - time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && - ixgbe_tx_xon_state(adapter, tx_ring)) { - /* detected Tx unit hang */ - union ixgbe_adv_tx_desc *tx_desc; - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); - e_err(drv, "Detected Tx Unit Hang\n" - " Tx Queue <%d>\n" - " TDH, TDT <%x>, <%x>\n" - " next_to_use <%x>\n" - " next_to_clean <%x>\n" - "tx_buffer_info[next_to_clean]\n" - " time_stamp <%lx>\n" - " jiffies <%lx>\n", - tx_ring->queue_index, - IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)), - IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)), - tx_ring->next_to_use, eop, - tx_ring->tx_buffer_info[eop].time_stamp, jiffies); - return true; + + /* + * Check for a hung queue, but be thorough. This verifies + * that a transmit has been completed since the previous + * check AND there is at least one packet pending. The + * ARMED bit is set to indicate a potential hang. The + * bit is cleared if a pause frame is received to remove + * false hang detection due to PFC or 802.3x frames. By + * requiring this to fail twice we avoid races with + * pfc clearing the ARMED bit and conditions where we + * run the check_tx_hang logic with a transmit completion + * pending but without time to complete it yet. + */ + if ((tx_done_old == tx_done) && tx_pending) { + /* make sure it is true for two checks in a row */ + ret = test_and_set_bit(__IXGBE_HANG_CHECK_ARMED, + &tx_ring->state); + } else { + /* update completed stats and continue */ + tx_ring->tx_stats.tx_done_old = tx_done; + /* reset the countdown */ + clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); } - return false; + return ret; } #define IXGBE_MAX_TXD_PWR 14 @@ -772,6 +845,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_buffer_info); } + tx_ring->tx_stats.completed++; eop = tx_ring->tx_buffer_info[i].next_to_watch; eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); } @@ -784,11 +858,31 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_ring->stats.bytes += total_bytes; u64_stats_update_end(&tx_ring->syncp); - if (check_for_tx_hang(tx_ring) && - ixgbe_check_tx_hang(adapter, tx_ring, i)) { + if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { + /* schedule immediate reset if we believe we hung */ + struct ixgbe_hw *hw = &adapter->hw; + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); + e_err(drv, "Detected Tx Unit Hang\n" + " Tx Queue <%d>\n" + " TDH, TDT <%x>, <%x>\n" + " next_to_use <%x>\n" + " next_to_clean <%x>\n" + "tx_buffer_info[next_to_clean]\n" + " time_stamp <%lx>\n" + " jiffies <%lx>\n", + tx_ring->queue_index, + IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)), + IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)), + tx_ring->next_to_use, eop, + tx_ring->tx_buffer_info[eop].time_stamp, jiffies); + + netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); + + e_info(probe, + "tx hang %d detected on queue %d, resetting adapter\n", + adapter->tx_timeout_count + 1, tx_ring->queue_index); + /* schedule immediate reset if we believe we hung */ - e_info(probe, "tx hang %d detected, resetting " - "adapter\n", adapter->tx_timeout_count + 1); ixgbe_tx_timeout(adapter->netdev); /* the adapter is about to reset, no point in enabling stuff */ @@ -2599,6 +2693,8 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, ring->atr_sample_rate = 0; } + clear_bit(__IXGBE_HANG_CHECK_ARMED, &ring->state); + /* enable queue */ txdctl |= IXGBE_TXDCTL_ENABLE; IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); @@ -4034,6 +4130,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + adapter->tx_timeout_count++; + /* Do the reset outside of interrupt context */ schedule_work(&adapter->reset_task); } @@ -4048,8 +4146,6 @@ static void ixgbe_reset_task(struct work_struct *work) test_bit(__IXGBE_RESETTING, &adapter->state)) return; - adapter->tx_timeout_count++; - ixgbe_dump(adapter); netdev_err(adapter->netdev, "Reset adapter\n"); ixgbe_reinit_locked(adapter); @@ -5597,14 +5693,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) case ixgbe_mac_82598EB: hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); - hwstats->pxoffrxc[i] += - IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); break; case ixgbe_mac_82599EB: hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); - hwstats->pxoffrxc[i] += - IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); break; default: break; @@ -5616,11 +5708,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) /* work around hardware counting issue */ hwstats->gprc -= missed_rx; + ixgbe_update_xoff_received(adapter); + /* 82598 hardware only has a 32 bit counter in the high register */ switch (hw->mac.type) { case ixgbe_mac_82598EB: hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); @@ -5633,7 +5726,6 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); - hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); #ifdef IXGBE_FCOE -- cgit v1.2.3-59-g8ed1b From a41c059741570779c0254a3a1aa4da3baa463d7c Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Tue, 16 Nov 2010 19:27:13 -0800 Subject: ixgbe: avoid doing FCoE DDP when adapter is DOWN or RESETTING There is no point to allow incoming DDP requests from the upper layer stack if the adapter is going down or being reset. Signed-off-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 05efa6a8ce8e..07346b8ebb04 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -168,6 +168,11 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, return 0; } + /* no DDP if we are already down or resetting */ + if (test_bit(__IXGBE_DOWN, &adapter->state) || + test_bit(__IXGBE_RESETTING, &adapter->state)) + return 0; + fcoe = &adapter->fcoe; if (!fcoe->pool) { e_warn(drv, "xid=0x%x no ddp pool for fcoe\n", xid); -- cgit v1.2.3-59-g8ed1b From 8ca371e484e2e5ceb9b90fdb83d8d251017d852b Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Tue, 16 Nov 2010 19:27:13 -0800 Subject: ixgbe: invalidate FCoE DDP context when no error status is available The hw automatically invalidates the context if DDP is successful or there is error detected. In case there is no error status available from the hw, initializing the per context error status to be 1 allows the DDP context to be still invalidated via the upper layer call to ddp_put(). Signed-off-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 07346b8ebb04..26dd27479e2c 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -68,7 +68,7 @@ static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc) static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp) { ddp->len = 0; - ddp->err = 0; + ddp->err = 1; ddp->udl = NULL; ddp->udp = 0UL; ddp->sgl = NULL; -- cgit v1.2.3-59-g8ed1b From 9b55bb038468a7b504ccdc1d956952598ae1b85b Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Tue, 16 Nov 2010 19:27:14 -0800 Subject: ixgbe: make sure FCoE DDP user buffers are really released by the HW When invalidating the DDP context is invalidated, the HW may not be done with the user buffer right away. In which case, we poll the FCBUFF register to check if the buffer valid bit is cleared or not, if not, we wait for max 100us that is guaranteed by the HW. Signed-off-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 26dd27479e2c..6342d4859790 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -92,6 +92,7 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) struct ixgbe_fcoe *fcoe; struct ixgbe_adapter *adapter; struct ixgbe_fcoe_ddp *ddp; + u32 fcbuff; if (!netdev) goto out_ddp_put; @@ -115,7 +116,14 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, (xid | IXGBE_FCDMARW_WE)); + + /* guaranteed to be invalidated after 100us */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, + (xid | IXGBE_FCDMARW_RE)); + fcbuff = IXGBE_READ_REG(&adapter->hw, IXGBE_FCBUFF); spin_unlock_bh(&fcoe->lock); + if (fcbuff & IXGBE_FCBUFF_VALID) + udelay(100); } if (ddp->sgl) pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, -- cgit v1.2.3-59-g8ed1b From a391f1d51244b8274920a33c5d11aeebec3aa68f Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Tue, 16 Nov 2010 19:27:15 -0800 Subject: ixgbe: make silicon specific functions generic The new MAC type X540 shares much of the same functionality of some silicon specific functions. To reduce duplicate code, made these functions generic. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 37 +---------------- drivers/net/ixgbe/ixgbe_82599.c | 86 ++-------------------------------------- drivers/net/ixgbe/ixgbe_common.c | 55 ++++++++++++++++++++++--- drivers/net/ixgbe/ixgbe_common.h | 5 ++- drivers/net/ixgbe/ixgbe_mbx.c | 2 +- drivers/net/ixgbe/ixgbe_mbx.h | 2 +- drivers/net/ixgbe/ixgbe_phy.c | 33 +++++++++++++++ drivers/net/ixgbe/ixgbe_phy.h | 3 ++ drivers/net/ixgbe/ixgbe_type.h | 1 + 9 files changed, 98 insertions(+), 126 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 25b20f93190a..d0f1d9d2c416 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -38,9 +38,6 @@ #define IXGBE_82598_MC_TBL_SIZE 128 #define IXGBE_82598_VFT_TBL_SIZE 128 -static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg); static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, @@ -156,7 +153,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82598; mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_82598; + &ixgbe_get_copper_link_capabilities_generic; } switch (hw->phy.type) { @@ -273,37 +270,6 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, return status; } -/** - * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @autoneg: boolean auto-negotiation value - * - * Determines the link capabilities by reading the AUTOC register. - **/ -static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) -{ - s32 status = IXGBE_ERR_LINK_SETUP; - u16 speed_ability; - - *speed = 0; - *autoneg = true; - - status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, - &speed_ability); - - if (status == 0) { - if (speed_ability & MDIO_SPEED_10G) - *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & MDIO_PMA_SPEED_1000) - *speed |= IXGBE_LINK_SPEED_1GB_FULL; - } - - return status; -} - /** * ixgbe_get_media_type_82598 - Determines media type * @hw: pointer to hardware structure @@ -1225,6 +1191,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { static struct ixgbe_eeprom_operations eeprom_ops_82598 = { .init_params = &ixgbe_init_eeprom_params_generic, .read = &ixgbe_read_eerd_generic, + .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic, }; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 0bd8fbb5bfd0..144c44a6b216 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -56,9 +56,6 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg); static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, @@ -174,7 +171,7 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82599; mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_82599; + &ixgbe_get_copper_link_capabilities_generic; } /* Set necessary function pointers based on phy type */ @@ -289,37 +286,6 @@ out: return status; } -/** - * ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @autoneg: boolean auto-negotiation value - * - * Determines the link capabilities by reading the AUTOC register. - **/ -static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) -{ - s32 status = IXGBE_ERR_LINK_SETUP; - u16 speed_ability; - - *speed = 0; - *autoneg = true; - - status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, - &speed_ability); - - if (status == 0) { - if (speed_ability & MDIO_SPEED_10G) - *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & MDIO_PMA_SPEED_1000) - *speed |= IXGBE_LINK_SPEED_1GB_FULL; - } - - return status; -} - /** * ixgbe_get_media_type_82599 - Get media type * @hw: pointer to hardware structure @@ -2125,51 +2091,6 @@ fw_version_out: return status; } -/** - * ixgbe_get_wwn_prefix_82599 - Get alternative WWNN/WWPN prefix from - * the EEPROM - * @hw: pointer to hardware structure - * @wwnn_prefix: the alternative WWNN prefix - * @wwpn_prefix: the alternative WWPN prefix - * - * This function will read the EEPROM from the alternative SAN MAC address - * block to check the support for the alternative WWNN/WWPN prefix support. - **/ -static s32 ixgbe_get_wwn_prefix_82599(struct ixgbe_hw *hw, u16 *wwnn_prefix, - u16 *wwpn_prefix) -{ - u16 offset, caps; - u16 alt_san_mac_blk_offset; - - /* clear output first */ - *wwnn_prefix = 0xFFFF; - *wwpn_prefix = 0xFFFF; - - /* check if alternative SAN MAC is supported */ - hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, - &alt_san_mac_blk_offset); - - if ((alt_san_mac_blk_offset == 0) || - (alt_san_mac_blk_offset == 0xFFFF)) - goto wwn_prefix_out; - - /* check capability in alternative san mac address block */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; - hw->eeprom.ops.read(hw, offset, &caps); - if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) - goto wwn_prefix_out; - - /* get the corresponding prefix for WWNN/WWPN */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwnn_prefix); - - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwpn_prefix); - -wwn_prefix_out: - return 0; -} - static struct ixgbe_mac_operations mac_ops_82599 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82599, @@ -2181,7 +2102,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .get_mac_addr = &ixgbe_get_mac_addr_generic, .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, .get_device_caps = &ixgbe_get_device_caps_82599, - .get_wwn_prefix = &ixgbe_get_wwn_prefix_82599, + .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, .stop_adapter = &ixgbe_stop_adapter_generic, .get_bus_info = &ixgbe_get_bus_info_generic, .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, @@ -2214,6 +2135,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = { .init_params = &ixgbe_init_eeprom_params_generic, .read = &ixgbe_read_eerd_generic, .write = &ixgbe_write_eeprom_generic, + .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic, }; @@ -2240,5 +2162,5 @@ struct ixgbe_info ixgbe_82599_info = { .mac_ops = &mac_ops_82599, .eeprom_ops = &eeprom_ops_82599, .phy_ops = &phy_ops_82599, - .mbx_ops = &mbx_ops_82599, + .mbx_ops = &mbx_ops_generic, }; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 62aa2be199f1..56052570cac5 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -45,14 +45,12 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); -static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); -static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); /** * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx @@ -638,7 +636,7 @@ out: * Polls the status bit (bit 1) of the EERD or EEWR to determine when the * read or write is done respectively. **/ -static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; @@ -1009,7 +1007,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum * @hw: pointer to hardware structure **/ -static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) +u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) { u16 i; u16 j; @@ -1072,7 +1070,7 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == 0) { - checksum = ixgbe_calc_eeprom_checksum(hw); + checksum = hw->eeprom.ops.calc_checksum(hw); hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); @@ -1110,7 +1108,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == 0) { - checksum = ixgbe_calc_eeprom_checksum(hw); + checksum = hw->eeprom.ops.calc_checksum(hw); status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum); } else { @@ -2686,3 +2684,48 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return 0; } + +/** + * ixgbe_get_wwn_prefix_generic Get alternative WWNN/WWPN prefix from + * the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + u16 offset, caps; + u16 alt_san_mac_blk_offset; + + /* clear output first */ + *wwnn_prefix = 0xFFFF; + *wwpn_prefix = 0xFFFF; + + /* check if alternative SAN MAC is supported */ + hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, + &alt_san_mac_blk_offset); + + if ((alt_san_mac_blk_offset == 0) || + (alt_san_mac_blk_offset == 0xFFFF)) + goto wwn_prefix_out; + + /* check capability in alternative san mac address block */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; + hw->eeprom.ops.read(hw, offset, &caps); + if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) + goto wwn_prefix_out; + + /* get the corresponding prefix for WWNN/WWPN */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwnn_prefix); + + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwpn_prefix); + +wwn_prefix_out: + return 0; +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 424c223437dc..341ca514a281 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -49,9 +49,11 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); +u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); @@ -81,7 +83,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete); - +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix); s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index 471f0f2cdb98..aede6eb0e67d 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -454,7 +454,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) mbx->stats.rsts = 0; } -struct ixgbe_mbx_operations mbx_ops_82599 = { +struct ixgbe_mbx_operations mbx_ops_generic = { .read = ixgbe_read_mbx_pf, .write = ixgbe_write_mbx_pf, .read_posted = ixgbe_read_posted_mbx, diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index 7e0d08ff5b53..3df9b1590218 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -88,6 +88,6 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); -extern struct ixgbe_mbx_operations mbx_ops_82599; +extern struct ixgbe_mbx_operations mbx_ops_generic; #endif /* _IXGBE_MBX_H_ */ diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 6c0d42e33f21..bc255ec48428 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -424,6 +424,39 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, return 0; } +/** + * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + * + * Determines the link capabilities by reading the AUTOC register. + */ +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_ERR_LINK_SETUP; + u16 speed_ability; + + *speed = 0; + *autoneg = true; + + status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, + &speed_ability); + + if (status == 0) { + if (speed_ability & MDIO_SPEED_10G) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & MDIO_PMA_SPEED_1000) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed_ability & MDIO_PMA_SPEED_100) + *speed |= IXGBE_LINK_SPEED_100_FULL; + } + + return status; +} + /** * ixgbe_reset_phy_nl - Performs a PHY reset * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index fb3898f12fc5..86f83bd130cb 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -96,6 +96,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); /* PHY specific */ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 9e6908dff9bc..86c0049ba199 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2414,6 +2414,7 @@ struct ixgbe_eeprom_operations { s32 (*write)(struct ixgbe_hw *, u16, u16); s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); s32 (*update_checksum)(struct ixgbe_hw *); + u16 (*calc_checksum)(struct ixgbe_hw *); }; struct ixgbe_mac_operations { -- cgit v1.2.3-59-g8ed1b From fe15e8e1c78521e0b4e375d6ed415b82265419c9 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Tue, 16 Nov 2010 19:27:16 -0800 Subject: ixgbe: add MAC and PHY support for x540 Adds the new x540.c file and Aquantia 1202 PHY for X540 support. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/Makefile | 2 +- drivers/net/ixgbe/ixgbe.h | 2 + drivers/net/ixgbe/ixgbe_82599.c | 8 +- drivers/net/ixgbe/ixgbe_ethtool.c | 1 + drivers/net/ixgbe/ixgbe_main.c | 1 + drivers/net/ixgbe/ixgbe_phy.c | 23 +- drivers/net/ixgbe/ixgbe_phy.h | 2 + drivers/net/ixgbe/ixgbe_type.h | 9 + drivers/net/ixgbe/ixgbe_x540.c | 722 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 766 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ixgbe/ixgbe_x540.c diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile index 8f81efb49169..7d7387fbdecd 100644 --- a/drivers/net/ixgbe/Makefile +++ b/drivers/net/ixgbe/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ - ixgbe_mbx.o + ixgbe_mbx.o ixgbe_x540.o ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 2b8cbb3a81fa..4806736785a3 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -481,10 +481,12 @@ struct ixgbe_rsc_cb { enum ixgbe_boards { board_82598, board_82599, + board_X540, }; extern struct ixgbe_info ixgbe_82598_info; extern struct ixgbe_info ixgbe_82599_info; +extern struct ixgbe_info ixgbe_X540_info; #ifdef CONFIG_IXGBE_DCB extern const struct dcbnl_rtnl_ops dcbnl_ops; extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 144c44a6b216..e34643eef162 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -181,6 +181,10 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; + case ixgbe_phy_aq: + phy->ops.get_firmware_version = + &ixgbe_get_phy_firmware_version_generic; + break; default: break; } @@ -298,7 +302,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) /* Detect if there is a copper PHY attached. */ if (hw->phy.type == ixgbe_phy_cu_unknown || - hw->phy.type == ixgbe_phy_tn) { + hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_aq) { media_type = ixgbe_media_type_copper; goto out; } @@ -1890,6 +1895,7 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) hw->phy.ops.identify(hw); if (hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_aq || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 6871b2be64f6..b884f90b5805 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -214,6 +214,7 @@ static int ixgbe_get_settings(struct net_device *netdev, /* Get PHY type */ switch (adapter->hw.phy.type) { case ixgbe_phy_tn: + case ixgbe_phy_aq: case ixgbe_phy_cu_unknown: /* Copper 10G-BASET */ ecmd->port = PORT_TP; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 6e56f7b7c8fd..94c30b4f489e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -59,6 +59,7 @@ static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { [board_82598] = &ixgbe_82598_info, [board_82599] = &ixgbe_82599_info, + [board_X540] = &ixgbe_X540_info, }; /* ixgbe_pci_tbl - PCI Device ID Table diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index bc255ec48428..c445fbce56ee 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -115,6 +115,9 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; + case AQ1202_PHY_ID: + phy_type = ixgbe_phy_aq; + break; case QT2022_PHY_ID: phy_type = ixgbe_phy_qt; break; @@ -433,8 +436,8 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, * Determines the link capabilities by reading the AUTOC register. */ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) + ixgbe_link_speed *speed, + bool *autoneg) { s32 status = IXGBE_ERR_LINK_SETUP; u16 speed_ability; @@ -1410,6 +1413,22 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version +**/ +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status = 0; + + status = hw->phy.ops.read_reg(hw, AQ_FW_REV, MDIO_MMD_VEND1, + firmware_version); + + return status; +} + /** * ixgbe_tn_check_overtemp - Checks if an overtemp occured. * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 86f83bd130cb..e2c6b7eac641 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -106,6 +106,8 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, bool *link_up); s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, u16 *firmware_version); +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, + u16 *firmware_version); s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 86c0049ba199..cbcb15277b47 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -995,8 +995,10 @@ /* PHY IDs*/ #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB +#define AQ1202_PHY_ID 0x03A1B440 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 +#define AQ_FW_REV 0x20 /* PHY Types */ #define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 @@ -1492,6 +1494,7 @@ #define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */ #define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */ #define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */ +#define IXGBE_EEC_SEC1VAL 0x02000000 /* Sector 1 Valid */ #define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */ /* EEPROM Addressing bits based on type (0-small, 1-large) */ #define IXGBE_EEC_ADDR_SIZE 0x00000400 @@ -1506,7 +1509,9 @@ #define IXGBE_EEPROM_SUM 0xBABA #define IXGBE_PCIE_ANALOG_PTR 0x03 #define IXGBE_ATLAS0_CONFIG_PTR 0x04 +#define IXGBE_PHY_PTR 0x04 #define IXGBE_ATLAS1_CONFIG_PTR 0x05 +#define IXGBE_OPTION_ROM_PTR 0x05 #define IXGBE_PCIE_GENERAL_PTR 0x06 #define IXGBE_PCIE_CONFIG0_PTR 0x07 #define IXGBE_PCIE_CONFIG1_PTR 0x08 @@ -2173,6 +2178,7 @@ struct ixgbe_atr_input_masks { enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, + ixgbe_flash, ixgbe_eeprom_none /* No NVM support */ }; @@ -2180,12 +2186,14 @@ enum ixgbe_mac_type { ixgbe_mac_unknown = 0, ixgbe_mac_82598EB, ixgbe_mac_82599EB, + ixgbe_mac_X540, ixgbe_num_macs }; enum ixgbe_phy_type { ixgbe_phy_unknown = 0, ixgbe_phy_tn, + ixgbe_phy_aq, ixgbe_phy_cu_unknown, ixgbe_phy_qt, ixgbe_phy_xaui, @@ -2584,6 +2592,7 @@ struct ixgbe_hw { u16 subsystem_vendor_id; u8 revision_id; bool adapter_stopped; + bool force_full_reset; }; struct ixgbe_info { diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c new file mode 100644 index 000000000000..7de5f7ea7104 --- /dev/null +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -0,0 +1,722 @@ +/******************************************************************************* + + Intel 10 Gigabit PCI Express Linux driver + Copyright(c) 1999 - 2010 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope 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., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include +#include +#include + +#include "ixgbe.h" +#include "ixgbe_phy.h" +//#include "ixgbe_mbx.h" + +#define IXGBE_X540_MAX_TX_QUEUES 128 +#define IXGBE_X540_MAX_RX_QUEUES 128 +#define IXGBE_X540_RAR_ENTRIES 128 +#define IXGBE_X540_MC_TBL_SIZE 128 +#define IXGBE_X540_VFT_TBL_SIZE 128 + +static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); +static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); +static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); +static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); +static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); +static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); + +enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) +{ + return ixgbe_media_type_copper; +} + +static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + + /* Call PHY identify routine to get the phy type */ + ixgbe_identify_phy_generic(hw); + + mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; + mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; + mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); + + return 0; +} + +/** + * ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg: true if autonegotiation enabled + * @autoneg_wait_to_complete: true when waiting for completion is needed + **/ +s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete) +{ + return hw->phy.ops.setup_link_speed(hw, speed, autoneg, + autoneg_wait_to_complete); +} + +/** + * ixgbe_reset_hw_X540 - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, perform a PHY reset, and perform a link (MAC) + * reset. + **/ +s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) +{ + ixgbe_link_speed link_speed; + s32 status = 0; + u32 ctrl; + u32 ctrl_ext; + u32 reset_bit; + u32 i; + u32 autoc; + u32 autoc2; + bool link_up = false; + + /* Call adapter stop to disable tx/rx and clear interrupts */ + hw->mac.ops.stop_adapter(hw); + + /* + * Prevent the PCI-E bus from from hanging by disabling PCI-E master + * access and verify no pending requests before reset + */ + status = ixgbe_disable_pcie_master(hw); + if (status != 0) { + status = IXGBE_ERR_MASTER_REQUESTS_PENDING; + hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); + } + + /* + * Issue global reset to the MAC. Needs to be SW reset if link is up. + * If link reset is used when link is up, it might reset the PHY when + * mng is using it. If link is down or the flag to force full link + * reset is set, then perform link reset. + */ + if (hw->force_full_reset) { + reset_bit = IXGBE_CTRL_LNK_RST; + } else { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (!link_up) + reset_bit = IXGBE_CTRL_LNK_RST; + else + reset_bit = IXGBE_CTRL_RST; + } + + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); + IXGBE_WRITE_FLUSH(hw); + + /* Poll for reset bit to self-clear indicating reset is complete */ + for (i = 0; i < 10; i++) { + udelay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST)) + break; + } + if (ctrl & IXGBE_CTRL_RST) { + status = IXGBE_ERR_RESET_FAILED; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + + /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); + ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + + msleep(50); + + /* Set the Rx packet buffer size. */ + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store the original AUTOC/AUTOC2 values if they have not been + * stored off yet. Otherwise restore the stored original + * values since the reset operation sets back to defaults. + */ + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + if (hw->mac.orig_link_settings_stored == false) { + hw->mac.orig_autoc = autoc; + hw->mac.orig_autoc2 = autoc2; + hw->mac.orig_link_settings_stored = true; + } else { + if (autoc != hw->mac.orig_autoc) + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc | + IXGBE_AUTOC_AN_RESTART)); + + if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != + (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { + autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK; + autoc2 |= (hw->mac.orig_autoc2 & + IXGBE_AUTOC2_UPPER_MASK); + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2); + } + } + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries = 128; + hw->mac.ops.init_rx_addrs(hw); + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* Store the permanent SAN mac address */ + hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); + + /* Add the SAN MAC address to the RAR only if it's a valid address */ + if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { + hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, + hw->mac.san_addr, 0, IXGBE_RAH_AV); + + /* Reserve the last RAR for the SAN MAC address */ + hw->mac.num_rar_entries--; + } + + /* Store the alternative WWNN/WWPN prefix */ + hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, + &hw->mac.wwpn_prefix); + + return status; +} + +/** + * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) +{ + u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u16 ext_ability = 0; + + hw->phy.ops.identify(hw); + + hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, + &ext_ability); + if (ext_ability & MDIO_PMA_EXTABLE_10GBT) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & MDIO_PMA_EXTABLE_1000BT) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & MDIO_PMA_EXTABLE_100BTX) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + + return physical_layer; +} + +/** + * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params + * @hw: pointer to hardware structure + **/ +s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 eec; + u16 eeprom_size; + + if (eeprom->type == ixgbe_eeprom_uninitialized) { + eeprom->semaphore_delay = 10; + eeprom->type = ixgbe_flash; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> + IXGBE_EEC_SIZE_SHIFT); + eeprom->word_size = 1 << (eeprom_size + + IXGBE_EEPROM_WORD_SIZE_SHIFT); + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", + eeprom->type, eeprom->word_size); + } + + return 0; +} + +/** + * ixgbe_read_eerd_X540 - Read EEPROM word using EERD + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EERPOM + **/ +s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + s32 status; + + if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) + status = ixgbe_read_eerd_generic(hw, offset, data); + else + status = IXGBE_ERR_SWFW_SYNC; + + ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM); + return status; +} + +/** + * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the EEWR register. + **/ +s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) +{ + u32 eewr; + s32 status; + + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) | + (data << IXGBE_EEPROM_RW_REG_DATA) | + IXGBE_EEPROM_RW_REG_START; + + if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) { + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); + if (status != 0) { + hw_dbg(hw, "Eeprom write EEWR timed out\n"); + goto out; + } + + IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); + + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); + if (status != 0) { + hw_dbg(hw, "Eeprom write EEWR timed out\n"); + goto out; + } + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + +out: + ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM); + return status; +} + +/** + * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum + * @hw: pointer to hardware structure + **/ +static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) +{ + u16 i; + u16 j; + u16 checksum = 0; + u16 length = 0; + u16 pointer = 0; + u16 word = 0; + + /* Include 0x0-0x3F in the checksum */ + for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { + if (hw->eeprom.ops.read(hw, i, &word) != 0) { + hw_dbg(hw, "EEPROM read failed\n"); + break; + } + checksum += word; + } + + /* + * Include all data from pointers 0x3, 0x6-0xE. This excludes the + * FW, PHY module, and PCIe Expansion/Option ROM pointers. + */ + for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { + if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) + continue; + + if (hw->eeprom.ops.read(hw, i, &pointer) != 0) { + hw_dbg(hw, "EEPROM read failed\n"); + break; + } + + /* Skip pointer section if the pointer is invalid. */ + if (pointer == 0xFFFF || pointer == 0 || + pointer >= hw->eeprom.word_size) + continue; + + if (hw->eeprom.ops.read(hw, pointer, &length) != 0) { + hw_dbg(hw, "EEPROM read failed\n"); + break; + } + + /* Skip pointer section if length is invalid. */ + if (length == 0xFFFF || length == 0 || + (pointer + length) >= hw->eeprom.word_size) + continue; + + for (j = pointer+1; j <= pointer+length; j++) { + if (hw->eeprom.ops.read(hw, j, &word) != 0) { + hw_dbg(hw, "EEPROM read failed\n"); + break; + } + checksum += word; + } + } + + checksum = (u16)IXGBE_EEPROM_SUM - checksum; + + return checksum; +} + +/** + * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash + * @hw: pointer to hardware structure + * + * After writing EEPROM to shadow RAM using EEWR register, software calculates + * checksum and updates the EEPROM and instructs the hardware to update + * the flash. + **/ +s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) +{ + s32 status; + + status = ixgbe_update_eeprom_checksum_generic(hw); + + if (status) + status = ixgbe_update_flash_X540(hw); + + return status; +} + +/** + * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device + * @hw: pointer to hardware structure + * + * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy + * EEPROM from shadow RAM to the flash device. + **/ +static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) +{ + u32 flup; + s32 status = IXGBE_ERR_EEPROM; + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status == IXGBE_ERR_EEPROM) { + hw_dbg(hw, "Flash update time out\n"); + goto out; + } + + flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP; + IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status) + hw_dbg(hw, "Flash update complete\n"); + else + hw_dbg(hw, "Flash update time out\n"); + + if (hw->revision_id == 0) { + flup = IXGBE_READ_REG(hw, IXGBE_EEC); + + if (flup & IXGBE_EEC_SEC1VAL) { + flup |= IXGBE_EEC_FLUP; + IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); + } + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status) + hw_dbg(hw, "Flash update complete\n"); + else + hw_dbg(hw, "Flash update time out\n"); + + } +out: + return status; +} + +/** + * ixgbe_poll_flash_update_done_X540 - Poll flash update status + * @hw: pointer to hardware structure + * + * Polls the FLUDONE (bit 26) of the EEC Register to determine when the + * flash update is done. + **/ +static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) +{ + u32 i; + u32 reg; + s32 status = IXGBE_ERR_EEPROM; + + for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { + reg = IXGBE_READ_REG(hw, IXGBE_EEC); + if (reg & IXGBE_EEC_FLUDONE) { + status = 0; + break; + } + udelay(5); + } + return status; +} + +/** + * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore thought the SW_FW_SYNC register for + * the specified function (CSR, PHY0, PHY1, NVM, Flash) + **/ +static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 5; + u32 hwmask = 0; + u32 timeout = 200; + u32 i; + + if (swmask == IXGBE_GSSR_EEP_SM) + hwmask = IXGBE_GSSR_FLASH_SM; + + for (i = 0; i < timeout; i++) { + /* + * SW NVM semaphore bit is used for access to all + * SW_FW_SYNC bits (not just NVM) + */ + if (ixgbe_get_swfw_sync_semaphore(hw)) + return IXGBE_ERR_SWFW_SYNC; + + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); + if (!(swfw_sync & (fwmask | swmask | hwmask))) { + swfw_sync |= swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); + ixgbe_release_swfw_sync_semaphore(hw); + break; + } else { + /* + * Firmware currently using resource (fwmask), + * hardware currently using resource (hwmask), + * or other software thread currently using + * resource (swmask) + */ + ixgbe_release_swfw_sync_semaphore(hw); + msleep(5); + } + } + + /* + * If the resource is not released by the FW/HW the SW can assume that + * the FW/HW malfunctions. In that case the SW should sets the + * SW bit(s) of the requested resource(s) while ignoring the + * corresponding FW/HW bits in the SW_FW_SYNC register. + */ + if (i >= timeout) { + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); + if (swfw_sync & (fwmask | hwmask)) { + if (ixgbe_get_swfw_sync_semaphore(hw)) + return IXGBE_ERR_SWFW_SYNC; + + swfw_sync |= swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); + ixgbe_release_swfw_sync_semaphore(hw); + } + } + + msleep(5); + return 0; +} + +/** + * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore throught the SW_FW_SYNC register + * for the specified function (CSR, PHY0, PHY1, EVM, Flash) + **/ +static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + + ixgbe_get_swfw_sync_semaphore(hw); + + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); + swfw_sync &= ~swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); + + ixgbe_release_swfw_sync_semaphore(hw); + msleep(5); +} + +/** + * ixgbe_get_nvm_semaphore - Get hardware semaphore + * @hw: pointer to hardware structure + * + * Sets the hardware semaphores so SW/FW can gain control of shared resources + **/ +static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_EEPROM; + u32 timeout = 2000; + u32 i; + u32 swsm; + + /* Get SMBI software semaphore between device drivers first */ + for (i = 0; i < timeout; i++) { + /* + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + if (!(swsm & IXGBE_SWSM_SMBI)) { + status = 0; + break; + } + udelay(50); + } + + /* Now get the semaphore between SW/FW through the REGSMP bit */ + if (status) { + for (i = 0; i < timeout; i++) { + swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); + if (!(swsm & IXGBE_SWFW_REGSMP)) + break; + + udelay(50); + } + } else { + hw_dbg(hw, "Software semaphore SMBI between device drivers " + "not granted.\n"); + } + + return status; +} + +/** + * ixgbe_release_nvm_semaphore - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function clears hardware semaphore bits. + **/ +static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) +{ + u32 swsm; + + /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ + + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + swsm &= ~IXGBE_SWSM_SMBI; + IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); + + swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); + swsm &= ~IXGBE_SWFW_REGSMP; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm); + + IXGBE_WRITE_FLUSH(hw); +} + +static struct ixgbe_mac_operations mac_ops_X540 = { + .init_hw = &ixgbe_init_hw_generic, + .reset_hw = &ixgbe_reset_hw_X540, + .start_hw = &ixgbe_start_hw_generic, + .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, + .get_media_type = &ixgbe_get_media_type_X540, + .get_supported_physical_layer = + &ixgbe_get_supported_physical_layer_X540, + .enable_rx_dma = &ixgbe_enable_rx_dma_generic, + .get_mac_addr = &ixgbe_get_mac_addr_generic, + .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, + .get_device_caps = NULL, + .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, + .stop_adapter = &ixgbe_stop_adapter_generic, + .get_bus_info = &ixgbe_get_bus_info_generic, + .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, + .read_analog_reg8 = NULL, + .write_analog_reg8 = NULL, + .setup_link = &ixgbe_setup_mac_link_X540, + .check_link = &ixgbe_check_mac_link_generic, + .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic, + .led_on = &ixgbe_led_on_generic, + .led_off = &ixgbe_led_off_generic, + .blink_led_start = &ixgbe_blink_led_start_generic, + .blink_led_stop = &ixgbe_blink_led_stop_generic, + .set_rar = &ixgbe_set_rar_generic, + .clear_rar = &ixgbe_clear_rar_generic, + .set_vmdq = &ixgbe_set_vmdq_generic, + .clear_vmdq = &ixgbe_clear_vmdq_generic, + .init_rx_addrs = &ixgbe_init_rx_addrs_generic, + .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, + .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, + .enable_mc = &ixgbe_enable_mc_generic, + .disable_mc = &ixgbe_disable_mc_generic, + .clear_vfta = &ixgbe_clear_vfta_generic, + .set_vfta = &ixgbe_set_vfta_generic, + .fc_enable = &ixgbe_fc_enable_generic, + .init_uta_tables = &ixgbe_init_uta_tables_generic, + .setup_sfp = NULL, +}; + +static struct ixgbe_eeprom_operations eeprom_ops_X540 = { + .init_params = &ixgbe_init_eeprom_params_X540, + .read = &ixgbe_read_eerd_X540, + .write = &ixgbe_write_eewr_X540, + .calc_checksum = &ixgbe_calc_eeprom_checksum_X540, + .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, + .update_checksum = &ixgbe_update_eeprom_checksum_X540, +}; + +static struct ixgbe_phy_operations phy_ops_X540 = { + .identify = &ixgbe_identify_phy_generic, + .identify_sfp = &ixgbe_identify_sfp_module_generic, + .init = NULL, + .reset = &ixgbe_reset_phy_generic, + .read_reg = &ixgbe_read_phy_reg_generic, + .write_reg = &ixgbe_write_phy_reg_generic, + .setup_link = &ixgbe_setup_phy_link_generic, + .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, + .read_i2c_byte = &ixgbe_read_i2c_byte_generic, + .write_i2c_byte = &ixgbe_write_i2c_byte_generic, + .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, + .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, + .check_overtemp = &ixgbe_tn_check_overtemp, +}; + +struct ixgbe_info ixgbe_X540_info = { + .mac = ixgbe_mac_X540, + .get_invariants = &ixgbe_get_invariants_X540, + .mac_ops = &mac_ops_X540, + .eeprom_ops = &eeprom_ops_X540, + .phy_ops = &phy_ops_X540, + .mbx_ops = &mbx_ops_generic, +}; -- cgit v1.2.3-59-g8ed1b From b93a22260f6f4bcf6c92c54de8530a97d3e921f0 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Tue, 16 Nov 2010 19:27:17 -0800 Subject: ixgbe: add support for x540 MAC This patch adds support for the x540 MAC which is the next MAC in the 82598/82599 line. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 +++ drivers/net/ixgbe/ixgbe_dcb.c | 11 ++++++-- drivers/net/ixgbe/ixgbe_dcb_nl.c | 55 ++++++++++++++++++++++++++++-------- drivers/net/ixgbe/ixgbe_ethtool.c | 39 +++++++++++++++++++++----- drivers/net/ixgbe/ixgbe_main.c | 59 +++++++++++++++++++++++++++++++++++---- drivers/net/ixgbe/ixgbe_mbx.c | 38 +++++++++++++++---------- drivers/net/ixgbe/ixgbe_type.h | 1 + drivers/net/ixgbe/ixgbe_x540.c | 20 ++++++------- 8 files changed, 177 insertions(+), 50 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 4806736785a3..3ae30b8cb7d6 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -544,6 +544,10 @@ extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte); extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type); +extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring); +extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 4f2f0ae67354..d16c260c1f50 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -152,10 +152,17 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ret = ixgbe_dcb_hw_config_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: ret = ixgbe_dcb_hw_config_82599(hw, dcb_config); + break; + default: + break; + } return ret; } diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index b53b465e24af..bf566e8a455e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -130,15 +130,21 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) netdev->netdev_ops->ndo_stop(netdev); ixgbe_clear_interrupt_scheme(adapter); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: adapter->last_lfc_mode = adapter->hw.fc.current_mode; adapter->hw.fc.requested_mode = ixgbe_fc_none; - } - adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + break; + default: + break; } + adapter->flags |= IXGBE_FLAG_DCB_ENABLED; ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -155,8 +161,14 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->dcb_cfg.pfc_mode_enable = false; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + break; + default: + break; + } ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -178,9 +190,14 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, for (i = 0; i < netdev->addr_len; i++) perm_addr[i] = adapter->hw.mac.perm_addr[i]; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: for (j = 0; j < netdev->addr_len; j++, i++) perm_addr[i] = adapter->hw.mac.san_addr[j]; + break; + default: + break; } } @@ -366,15 +383,29 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } if (adapter->dcb_cfg.pfc_mode_enable) { - if ((adapter->hw.mac.type != ixgbe_mac_82598EB) && - (adapter->hw.fc.current_mode != ixgbe_fc_pfc)) - adapter->last_lfc_mode = adapter->hw.fc.current_mode; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) + adapter->last_lfc_mode = + adapter->hw.fc.current_mode; + break; + default: + break; + } adapter->hw.fc.requested_mode = ixgbe_fc_pfc; } else { - if (adapter->hw.mac.type != ixgbe_mac_82598EB) - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; - else + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: adapter->hw.fc.requested_mode = ixgbe_fc_none; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + break; + default: + break; + } } if (adapter->dcb_set_bitmap & BIT_RESETLINK) { diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index b884f90b5805..f9b58394fbb6 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -431,15 +431,21 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev) static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + u32 feature_list; - if (data) { - netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) - netdev->features |= NETIF_F_SCTP_CSUM; - } else { - netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SCTP_CSUM); + feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + feature_list |= NETIF_F_SCTP_CSUM; + break; + default: + break; } + if (data) + netdev->features |= feature_list; + else + netdev->features &= ~feature_list; return 0; } @@ -1250,6 +1256,7 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) test = reg_test_82598; break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: toggle = 0x7FFFF30F; test = reg_test_82599; break; @@ -1476,6 +1483,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) switch (hw->mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); @@ -1512,6 +1520,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); @@ -2198,6 +2207,22 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) case ixgbe_mac_82599EB: need_reset = true; break; + case ixgbe_mac_X540: { + int i; + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = + adapter->rx_ring[i]; + if (adapter->flags2 & + IXGBE_FLAG2_RSC_ENABLED) { + ixgbe_configure_rscctl(adapter, + ring); + } else { + ixgbe_clear_rscctl(adapter, + ring); + } + } + } + break; default: break; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 94c30b4f489e..b859a298cd2a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -113,6 +113,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), + board_82599 }, /* required last entry */ {0, } @@ -561,6 +563,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: if (direction == -1) { /* other causes */ msix_vector |= IXGBE_IVAR_ALLOC_VAL; @@ -596,6 +599,7 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: mask = (qmask & 0xFFFFFFFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); mask = (qmask >> 32); @@ -923,6 +927,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); @@ -956,6 +961,7 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx)); txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << @@ -1581,6 +1587,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) v_idx); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: ixgbe_set_ivar(adapter, -1, 1, v_idx); break; @@ -1688,8 +1695,9 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) itr_reg |= (itr_reg << 16); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: /* - * 82599 can support a value of zero, so allow it for + * 82599 and X540 can support a value of zero, so allow it for * max interrupt rate, but there is an errata where it can * not be zero with RSC */ @@ -1885,6 +1893,7 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) switch (hw->mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { int i; @@ -1930,6 +1939,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: mask = (qmask & 0xFFFFFFFF); if (mask) IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); @@ -1955,6 +1965,7 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: mask = (qmask & 0xFFFFFFFF); if (mask) IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); @@ -2427,6 +2438,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, mask |= IXGBE_EIMS_GPI_SDP1; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: mask |= IXGBE_EIMS_ECC; mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; @@ -2492,6 +2504,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data) switch (hw->mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: ixgbe_check_sfp_event(adapter, eicr); if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { @@ -2601,6 +2614,7 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); @@ -2795,6 +2809,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, } break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: default: break; } @@ -2891,12 +2906,29 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } +/** + * ixgbe_clear_rscctl - disable RSC for the indicated ring + * @adapter: address of board private structure + * @ring: structure containing ring specific data + **/ +void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rscctrl; + u8 reg_idx = ring->reg_idx; + + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); + rscctrl &= ~IXGBE_RSCCTL_RSCEN; + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); +} + /** * ixgbe_configure_rscctl - enable RSC for the indicated ring * @adapter: address of board private structure * @index: index of ring to set **/ -static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, +void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; @@ -3201,6 +3233,7 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) rdrxctl |= IXGBE_RDRXCTL_MVMEN; break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: /* Disable RSC for ACK packets */ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); @@ -3328,6 +3361,7 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3357,6 +3391,7 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3712,8 +3747,9 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) case ixgbe_mac_82598EB: IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); break; - default: case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + default: IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); break; @@ -4061,6 +4097,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* Disable the Tx DMA engine on 82599 */ switch (hw->mac.type) { case ixgbe_mac_82599EB: + case ixgbe_mac_X540: IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & ~IXGBE_DMATXCTL_TE)); @@ -4435,6 +4472,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) ret = true; break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: if (dcb_i == 8) { /* * Tx TC0 starts at: descriptor queue 0 @@ -5049,6 +5087,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; @@ -5567,6 +5606,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) pci_wake_from_d3(pdev, false); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: pci_wake_from_d3(pdev, !!wufc); break; default: @@ -5696,6 +5736,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); break; @@ -5720,6 +5761,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); @@ -5983,7 +6025,8 @@ static void ixgbe_watchdog_task(struct work_struct *work) flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); } break; - case ixgbe_mac_82599EB: { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: { u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); @@ -7057,8 +7100,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_sw_init; /* Make it possible the adapter to be woken up via WOL */ - if (adapter->hw.mac.type == ixgbe_mac_82599EB) + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); + break; + default: + break; + } /* * If there is a fan on this device and it has failed log the diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index aede6eb0e67d..027c628c3aae 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -319,8 +319,14 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) u32 vflre = 0; s32 ret_val = IXGBE_ERR_MBX; - if (hw->mac.type == ixgbe_mac_82599EB) + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); + break; + default: + break; + } if (vflre & (1 << vf_shift)) { ret_val = 0; @@ -439,19 +445,23 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; - if (hw->mac.type != ixgbe_mac_82599EB) - return; - - mbx->timeout = 0; - mbx->usec_delay = 0; - - mbx->size = IXGBE_VFMAILBOX_SIZE; - - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + mbx->timeout = 0; + mbx->usec_delay = 0; + + mbx->size = IXGBE_VFMAILBOX_SIZE; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; + break; + default: + break; + } } struct ixgbe_mbx_operations mbx_ops_generic = { diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index cbcb15277b47..42c607339a62 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -58,6 +58,7 @@ #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C +#define IXGBE_DEV_ID_X540T 0x1528 /* General Registers */ #define IXGBE_CTRL 0x00000 diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 7de5f7ea7104..9649fa727e31 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -46,7 +46,7 @@ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); -enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) +static enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) { return ixgbe_media_type_copper; } @@ -75,9 +75,9 @@ static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed **/ -s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, - bool autoneg_wait_to_complete) +static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete) { return hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); @@ -91,7 +91,7 @@ s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, * and clears all interrupts, perform a PHY reset, and perform a link (MAC) * reset. **/ -s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) +static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) { ixgbe_link_speed link_speed; s32 status = 0; @@ -222,7 +222,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) +static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) { u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u16 ext_ability = 0; @@ -245,7 +245,7 @@ u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params * @hw: pointer to hardware structure **/ -s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) +static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) { struct ixgbe_eeprom_info *eeprom = &hw->eeprom; u32 eec; @@ -274,7 +274,7 @@ s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) * @offset: offset of word in the EEPROM to read * @data: word read from the EERPOM **/ -s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) +static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) { s32 status; @@ -295,7 +295,7 @@ s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) * * Write a 16 bit word to the EEPROM using the EEWR register. **/ -s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) +static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) { u32 eewr; s32 status; @@ -406,7 +406,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) * checksum and updates the EEPROM and instructs the hardware to update * the flash. **/ -s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) +static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) { s32 status; -- cgit v1.2.3-59-g8ed1b From e2ddeba95c09d0d44719ff005e915dc06ff46571 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Nov 2010 19:27:18 -0800 Subject: ixgbe: refactor ixgbe_alloc_queues() I noticed ring variable was initialized before allocations, and that memory node management was a bit ugly. We also leak memory in case of ring allocations error. Signed-off-by: Eric Dumazet Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 72 ++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 44 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b859a298cd2a..5409af3da06c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4676,71 +4676,55 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) **/ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) { - int i; - int rx_count; - int orig_node = adapter->node; + int rx = 0, tx = 0, nid = adapter->node; - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *ring = adapter->tx_ring[i]; - if (orig_node == -1) { - int cur_node = next_online_node(adapter->node); - if (cur_node == MAX_NUMNODES) - cur_node = first_online_node; - adapter->node = cur_node; - } - ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + if (nid < 0 || !node_online(nid)) + nid = first_online_node; + + for (; tx < adapter->num_tx_queues; tx++) { + struct ixgbe_ring *ring; + + ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid); if (!ring) - ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); + ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) - goto err_tx_ring_allocation; + goto err_allocation; ring->count = adapter->tx_ring_count; - ring->queue_index = i; + ring->queue_index = tx; + ring->numa_node = nid; ring->dev = &adapter->pdev->dev; ring->netdev = adapter->netdev; - ring->numa_node = adapter->node; - adapter->tx_ring[i] = ring; + adapter->tx_ring[tx] = ring; } - /* Restore the adapter's original node */ - adapter->node = orig_node; + for (; rx < adapter->num_rx_queues; rx++) { + struct ixgbe_ring *ring; - rx_count = adapter->rx_ring_count; - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; - if (orig_node == -1) { - int cur_node = next_online_node(adapter->node); - if (cur_node == MAX_NUMNODES) - cur_node = first_online_node; - adapter->node = cur_node; - } - ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid); if (!ring) - ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); + ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) - goto err_rx_ring_allocation; - ring->count = rx_count; - ring->queue_index = i; + goto err_allocation; + ring->count = adapter->rx_ring_count; + ring->queue_index = rx; + ring->numa_node = nid; ring->dev = &adapter->pdev->dev; ring->netdev = adapter->netdev; - ring->numa_node = adapter->node; - adapter->rx_ring[i] = ring; + adapter->rx_ring[rx] = ring; } - /* Restore the adapter's original node */ - adapter->node = orig_node; - ixgbe_cache_ring_register(adapter); return 0; -err_rx_ring_allocation: - for (i = 0; i < adapter->num_tx_queues; i++) - kfree(adapter->tx_ring[i]); -err_tx_ring_allocation: +err_allocation: + while (tx) + kfree(adapter->tx_ring[--tx]); + + while (rx) + kfree(adapter->rx_ring[--rx]); return -ENOMEM; } -- cgit v1.2.3-59-g8ed1b From 5d426ad1af31ac27d7c2222f20eec9d0a8aeac42 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 16 Nov 2010 19:27:19 -0800 Subject: ixgbevf: Fix Oops The driver is calling netif_carrier_off and netif_tx_stop_all_queues before the netdevice is registered which causes an Oops. Move call to netif_carrier_off after the netdevice is registered and remove call to netif_tx_stop_all_queues because there aren't any TX queues yet. Signed-off-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 1d7de555e630..5b8063cb4e6c 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3425,10 +3425,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, if (hw->mac.ops.get_bus_info) hw->mac.ops.get_bus_info(hw); - - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); @@ -3437,6 +3433,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, adapter->netdev_registered = true; + netif_carrier_off(netdev); + ixgbevf_init_last_counter_stats(adapter); /* print the MAC address */ -- cgit v1.2.3-59-g8ed1b From 2c20ebbaed7f3f21506629ee931941a9bba199ab Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 16 Nov 2010 19:41:35 -0800 Subject: igbvf: Update version and Copyright Update version string and copyright notice Signed-off-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/Makefile | 2 +- drivers/net/igbvf/defines.h | 2 +- drivers/net/igbvf/ethtool.c | 2 +- drivers/net/igbvf/igbvf.h | 2 +- drivers/net/igbvf/mbx.c | 2 +- drivers/net/igbvf/mbx.h | 2 +- drivers/net/igbvf/netdev.c | 7 ++++--- drivers/net/igbvf/regs.h | 2 +- drivers/net/igbvf/vf.c | 2 +- drivers/net/igbvf/vf.h | 2 +- 10 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/igbvf/Makefile b/drivers/net/igbvf/Makefile index c2f150d8f2d9..0fa3db3dd8b6 100644 --- a/drivers/net/igbvf/Makefile +++ b/drivers/net/igbvf/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel(R) 82576 Virtual Function Linux driver -# Copyright(c) 2009 Intel Corporation. +# Copyright(c) 2009 - 2010 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/defines.h b/drivers/net/igbvf/defines.h index 88a47537518a..79f2604673fe 100644 --- a/drivers/net/igbvf/defines.h +++ b/drivers/net/igbvf/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index 33add708bcbe..abb3606928fb 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index debeee2dc717..63284e3ae3a7 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/mbx.c b/drivers/net/igbvf/mbx.c index 819a8ec901dc..3d6f4cc3998a 100644 --- a/drivers/net/igbvf/mbx.c +++ b/drivers/net/igbvf/mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/mbx.h b/drivers/net/igbvf/mbx.h index 4938609dbfb5..c2883c45d477 100644 --- a/drivers/net/igbvf/mbx.h +++ b/drivers/net/igbvf/mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 28af019c97bb..1e7bfca79a58 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -44,12 +44,13 @@ #include "igbvf.h" -#define DRV_VERSION "1.0.0-k0" +#define DRV_VERSION "1.0.8-k0" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; static const char igbvf_driver_string[] = "Intel(R) Virtual Function Network Driver"; -static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; +static const char igbvf_copyright[] = + "Copyright (c) 2009 - 2010 Intel Corporation."; static int igbvf_poll(struct napi_struct *napi, int budget); static void igbvf_reset(struct igbvf_adapter *); diff --git a/drivers/net/igbvf/regs.h b/drivers/net/igbvf/regs.h index b9e24ed70d0a..77e18d3d6b15 100644 --- a/drivers/net/igbvf/regs.h +++ b/drivers/net/igbvf/regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index a9a61efa964c..0cc13c6ed418 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h index 1e8ce3741a67..c36ea21f17fa 100644 --- a/drivers/net/igbvf/vf.h +++ b/drivers/net/igbvf/vf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 Intel Corporation. + Copyright(c) 2009 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-59-g8ed1b From eca2a33c985eb19dd0ca4b37d66c7fb5d8b76308 Mon Sep 17 00:00:00 2001 From: Julian Stecklina Date: Tue, 16 Nov 2010 19:41:36 -0800 Subject: igbvf: Remove some dead code in igbvf Removed unused variable in igbvf. Signed-off-by: Julian Stecklina Acked-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/netdev.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 1e7bfca79a58..4c998b7726da 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1852,8 +1852,6 @@ static void igbvf_watchdog_task(struct work_struct *work) if (link) { if (!netif_carrier_ok(netdev)) { - bool txb2b = 1; - mac->ops.get_link_up_info(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); @@ -1863,11 +1861,9 @@ static void igbvf_watchdog_task(struct work_struct *work) adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: - txb2b = 0; adapter->tx_timeout_factor = 16; break; case SPEED_100: - txb2b = 0; /* maybe add some timeout factor ? */ break; } -- cgit v1.2.3-59-g8ed1b From b1d670f10e8078485884f0cf7e384d890909aeaa Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 16 Nov 2010 19:41:36 -0800 Subject: Remove extra struct page member from the buffer info structure declaration. Reported-by: Andi Kleen Signed-off-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/igbvf.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index 63284e3ae3a7..9d4d63e536d4 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -126,7 +126,6 @@ struct igbvf_buffer { unsigned int page_offset; }; }; - struct page *page; }; union igbvf_desc { -- cgit v1.2.3-59-g8ed1b From d478eb44f7a6b53256ae399fa7e597525b4034ee Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 16 Nov 2010 19:50:13 -0800 Subject: e1000e: 82571 SerDes link handle null code word from partner SerDes Link detection on certain 82571 mezzanine cards can fail when the link is forced, the link partner does not recognize forced link and the link partner sends null code words. Detect the null code words and return to auto-negotiation state which causes the link partner to begin responding with valid code words. Within a reasonable interval the link will finally settle as forced by both partners. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 4 +++- drivers/net/e1000e/defines.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 7236f1a53ba0..235856375ff3 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1431,8 +1431,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * auto-negotiation in the TXCW register and disable * forced link in the Device Control register in an * attempt to auto-negotiate with our link partner. + * If the partner code word is null, stop forcing + * and restart auto negotiation. */ - if (rxcw & E1000_RXCW_C) { + if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index d3f7a9c3f973..016ea383145a 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -516,6 +516,7 @@ #define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ /* Receive Configuration Word */ +#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ #define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ #define E1000_RXCW_C 0x20000000 /* Receive config */ #define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ -- cgit v1.2.3-59-g8ed1b From 1b98c2bb63a4b415d8d894d001b6d0256409e0d9 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 16 Nov 2010 19:50:14 -0800 Subject: e1000e: 82574 intermittently fails to initialize with manageability f/w The driver can fail initializing the hardware when manageability firmware is performing concurrent MDIO operations because the hardware semaphore scheme to prevent concurrent operations between software and firmware is incorrect for 82574/82583. Instead of using the SWSM register, the driver should be using the EXTCNF_CTRL register. A software mutex is also added to prevent simultaneous software threads from performing similar concurrent accesses. Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 139 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 19 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 235856375ff3..9333921010cc 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -74,6 +74,9 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); static s32 e1000_led_on_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); +static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); /** * e1000_init_phy_params_82571 - Init PHY func ptrs. @@ -107,6 +110,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) case e1000_82574: case e1000_82583: phy->type = e1000_phy_bm; + phy->ops.acquire = e1000_get_hw_semaphore_82574; + phy->ops.release = e1000_put_hw_semaphore_82574; break; default: return -E1000_ERR_PHY; @@ -200,6 +205,17 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) break; } + /* Function Pointers */ + switch (hw->mac.type) { + case e1000_82574: + case e1000_82583: + nvm->ops.acquire = e1000_get_hw_semaphore_82574; + nvm->ops.release = e1000_put_hw_semaphore_82574; + break; + default: + break; + } + return 0; } @@ -542,6 +558,94 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); ew32(SWSM, swsm); } +/** + * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore during reset. + * + **/ +static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) +{ + u32 extcnf_ctrl; + s32 ret_val = 0; + s32 i = 0; + + extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + do { + ew32(EXTCNF_CTRL, extcnf_ctrl); + extcnf_ctrl = er32(EXTCNF_CTRL); + + if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + break; + + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + msleep(2); + i++; + } while (i < MDIO_OWNERSHIP_TIMEOUT); + + if (i == MDIO_OWNERSHIP_TIMEOUT) { + /* Release semaphores */ + e1000_put_hw_semaphore_82573(hw); + e_dbg("Driver can't access the PHY\n"); + ret_val = -E1000_ERR_PHY; + goto out; + } + +out: + return ret_val; +} + +/** + * e1000_put_hw_semaphore_82573 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used during reset. + * + **/ +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) +{ + u32 extcnf_ctrl; + + extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + ew32(EXTCNF_CTRL, extcnf_ctrl); +} + +static DEFINE_MUTEX(swflag_mutex); + +/** + * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM. + * + **/ +static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) +{ + s32 ret_val; + + mutex_lock(&swflag_mutex); + ret_val = e1000_get_hw_semaphore_82573(hw); + if (ret_val) + mutex_unlock(&swflag_mutex); + return ret_val; +} + +/** + * e1000_put_hw_semaphore_82574 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + * + **/ +static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) +{ + e1000_put_hw_semaphore_82573(hw); + mutex_unlock(&swflag_mutex); +} /** * e1000_acquire_nvm_82571 - Request for access to the EEPROM @@ -562,8 +666,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82573: - case e1000_82574: - case e1000_82583: break; default: ret_val = e1000e_acquire_nvm(hw); @@ -853,9 +955,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) **/ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { - u32 ctrl, extcnf_ctrl, ctrl_ext, icr; + u32 ctrl, ctrl_ext, icr; s32 ret_val; - u16 i = 0; /* * Prevent the PCI-E bus from sticking if there is no TLP connection @@ -880,33 +981,33 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) */ switch (hw->mac.type) { case e1000_82573: + ret_val = e1000_get_hw_semaphore_82573(hw); + break; case e1000_82574: case e1000_82583: - extcnf_ctrl = er32(EXTCNF_CTRL); - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - - do { - ew32(EXTCNF_CTRL, extcnf_ctrl); - extcnf_ctrl = er32(EXTCNF_CTRL); - - if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) - break; - - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - - msleep(2); - i++; - } while (i < MDIO_OWNERSHIP_TIMEOUT); + ret_val = e1000_get_hw_semaphore_82574(hw); break; default: break; } + if (ret_val) + e_dbg("Cannot acquire MDIO ownership\n"); ctrl = er32(CTRL); e_dbg("Issuing a global reset to MAC\n"); ew32(CTRL, ctrl | E1000_CTRL_RST); + /* Must release MDIO ownership and mutex after MAC reset. */ + switch (hw->mac.type) { + case e1000_82574: + case e1000_82583: + e1000_put_hw_semaphore_82574(hw); + break; + default: + break; + } + if (hw->nvm.type == e1000_nvm_flash_hw) { udelay(10); ctrl_ext = er32(CTRL_EXT); -- cgit v1.2.3-59-g8ed1b From 147b2c8cb4f3e16aafc87096365a913d01ee3a21 Mon Sep 17 00:00:00 2001 From: Dongdong Deng Date: Tue, 16 Nov 2010 19:50:15 -0800 Subject: e1000e: add netpoll support for MSI/MSI-X IRQ modes With enabling CONFIG_PCI_MSI, e1000e could work in MSI/MSI-X IRQ mode, and netpoll controller didn't deal with those IRQ modes on e1000e. This patch add the handling MSI/MSI-X IRQ modes to netpoll controller, so that netconsole could work with those IRQ modes. Signed-off-by: Dongdong Deng Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 49 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index a6d54e460001..9b3f0a996b00 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5465,6 +5465,36 @@ static void e1000_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_NET_POLL_CONTROLLER + +static irqreturn_t e1000_intr_msix(int irq, void *data) +{ + struct net_device *netdev = data; + struct e1000_adapter *adapter = netdev_priv(netdev); + int vector, msix_irq; + + if (adapter->msix_entries) { + vector = 0; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_intr_msix_rx(msix_irq, netdev); + enable_irq(msix_irq); + + vector++; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_intr_msix_tx(msix_irq, netdev); + enable_irq(msix_irq); + + vector++; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_msix_other(msix_irq, netdev); + enable_irq(msix_irq); + } + + return IRQ_HANDLED; +} + /* * Polling 'interrupt' - used by things like netconsole to send skbs * without having to re-enable interrupts. It's not called while @@ -5474,10 +5504,21 @@ static void e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - disable_irq(adapter->pdev->irq); - e1000_intr(adapter->pdev->irq, netdev); - - enable_irq(adapter->pdev->irq); + switch (adapter->int_mode) { + case E1000E_INT_MODE_MSIX: + e1000_intr_msix(adapter->pdev->irq, netdev); + break; + case E1000E_INT_MODE_MSI: + disable_irq(adapter->pdev->irq); + e1000_intr_msi(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); + break; + default: /* E1000E_INT_MODE_LEGACY */ + disable_irq(adapter->pdev->irq); + e1000_intr(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); + break; + } } #endif -- cgit v1.2.3-59-g8ed1b From a17531fa4c951f32ca4f90b04ca42cfb11924098 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:24 +0000 Subject: drivers/isdn/i4l: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_concap.c | 2 +- drivers/isdn/i4l/isdn_net.c | 20 ++++++++++---------- drivers/isdn/i4l/isdn_ppp.c | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c index 46048e55f241..d568689669f8 100644 --- a/drivers/isdn/i4l/isdn_concap.c +++ b/drivers/isdn/i4l/isdn_concap.c @@ -61,7 +61,7 @@ static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff * static int isdn_concap_dl_connect_req(struct concap_proto *concap) { struct net_device *ndev = concap -> net_dev; - isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); + isdn_net_local *lp = netdev_priv(ndev); int ret; IX25DEBUG( "isdn_concap_dl_connect_req: %s \n", ndev -> name); diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 26d44c3ca1d8..afeede7ee295 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -827,7 +827,7 @@ isdn_net_dial(void) void isdn_net_hangup(struct net_device *d) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(d); + isdn_net_local *lp = netdev_priv(d); isdn_ctrl cmd; #ifdef CONFIG_ISDN_X25 struct concap_proto *cprot = lp->netdev->cprot; @@ -1052,7 +1052,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) { isdn_net_dev *nd; isdn_net_local *slp; - isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); + isdn_net_local *lp = netdev_priv(ndev); int retv = NETDEV_TX_OK; if (((isdn_net_local *) netdev_priv(ndev))->master) { @@ -1116,7 +1116,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) static void isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); if (!skb) return; if (lp->p_encap == ISDN_NET_ENCAP_ETHER) { @@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) static void isdn_net_tx_timeout(struct net_device * ndev) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); + isdn_net_local *lp = netdev_priv(ndev); printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate); if (!lp->dialstate){ @@ -1165,7 +1165,7 @@ static void isdn_net_tx_timeout(struct net_device * ndev) static netdev_tx_t isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); + isdn_net_local *lp = netdev_priv(ndev); #ifdef CONFIG_ISDN_X25 struct concap_proto * cprot = lp -> netdev -> cprot; /* At this point hard_start_xmit() passes control to the encapsulation @@ -1347,7 +1347,7 @@ isdn_net_close(struct net_device *dev) static struct net_device_stats * isdn_net_get_stats(struct net_device *dev) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); return &lp->stats; } @@ -1426,7 +1426,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len) static int isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); unsigned long len = 0; unsigned long expires = 0; int tmp = 0; @@ -1493,7 +1493,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int isdn_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); switch (lp->p_encap) { #ifdef CONFIG_ISDN_PPP @@ -1786,7 +1786,7 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb) static void isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) { - isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); + isdn_net_local *lp = netdev_priv(ndev); isdn_net_local *olp = lp; /* original 'lp' */ #ifdef CONFIG_ISDN_X25 struct concap_proto *cprot = lp -> netdev -> cprot; @@ -1800,7 +1800,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) * handle master's statistics and hangup-timeout */ ndev = lp->master; - lp = (isdn_net_local *) netdev_priv(ndev); + lp = netdev_priv(ndev); lp->stats.rx_packets++; lp->stats.rx_bytes += skb->len; } diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index fe824e0cbb25..97c5cc2997f5 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -1221,7 +1221,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) struct ippp_struct *ipt,*ipts; int slot, retval = NETDEV_TX_OK; - mlp = (isdn_net_local *) netdev_priv(netdev); + mlp = netdev_priv(netdev); nd = mlp->netdev; /* get master lp */ slot = mlp->ppp_slot; @@ -1985,7 +1985,7 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev) { struct ppp_stats __user *res = ifr->ifr_data; struct ppp_stats t; - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); if (!access_ok(VERIFY_WRITE, res, sizeof(struct ppp_stats))) return -EFAULT; @@ -2024,7 +2024,7 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int error=0; int len; - isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); + isdn_net_local *lp = netdev_priv(dev); if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) @@ -2091,7 +2091,7 @@ isdn_ppp_dial_slave(char *name) sdev = lp->slave; while (sdev) { - isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev); + isdn_net_local *mlp = netdev_priv(sdev); if (!(mlp->flags & ISDN_NET_CONNECTED)) break; sdev = mlp->slave; @@ -2099,7 +2099,7 @@ isdn_ppp_dial_slave(char *name) if (!sdev) return 2; - isdn_net_dial_req((isdn_net_local *) netdev_priv(sdev)); + isdn_net_dial_req(netdev_priv(sdev)); return 0; #else return -1; @@ -2122,7 +2122,7 @@ isdn_ppp_hangup_slave(char *name) sdev = lp->slave; while (sdev) { - isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev); + isdn_net_local *mlp = netdev_priv(sdev); if (mlp->slave) { /* find last connected link in chain */ isdn_net_local *nlp = ISDN_SLAVE_PRIV(mlp); -- cgit v1.2.3-59-g8ed1b From c04914af6861d62df303aeedbbe554972ce4e736 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:25 +0000 Subject: drivers/net/bonding: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 3 +-- drivers/net/bonding/bonding.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 881914bc4e9c..48cf24ff4e6f 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2474,8 +2474,7 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac goto out; read_lock(&bond->lock); - slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), - orig_dev); + slave = bond_get_slave_by_dev(netdev_priv(dev), orig_dev); if (!slave) goto out_unlock; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6ca..ad3ae46a4c01 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -286,7 +286,7 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) return NULL; } - return (struct bonding *)netdev_priv(slave->dev->master); + return netdev_priv(slave->dev->master); } static inline bool bond_is_lb(const struct bonding *bond) -- cgit v1.2.3-59-g8ed1b From a887e220760c12e00b0591d67987e26f6e270d71 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:26 +0000 Subject: drivers/net/pcmcia: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/pcmcia/axnet_cs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8a4d19e5de06..1a0eb128e607 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -875,7 +875,7 @@ static void do_set_multicast_list(struct net_device *dev); static int ax_open(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); /* * Grab the page lock so we own the register set, then call @@ -926,7 +926,7 @@ static int ax_close(struct net_device *dev) static void axnet_tx_timeout(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); unsigned long flags; @@ -973,7 +973,7 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int length, send_length, output_page; unsigned long flags; u8 packet[ETH_ZLEN]; @@ -1270,7 +1270,7 @@ static void ei_tx_err(struct net_device *dev) static void ei_tx_intr(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int status = inb(e8390_base + EN0_TSR); /* @@ -1354,7 +1354,7 @@ static void ei_tx_intr(struct net_device *dev) static void ei_receive(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned char rxing_page, this_frame, next_frame; unsigned short current_offset; int rx_pkt_count = 0; @@ -1539,7 +1539,7 @@ static void ei_rx_overrun(struct net_device *dev) static struct net_device_stats *get_stats(struct net_device *dev) { long ioaddr = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned long flags; /* If the card is stopped, just return the present stats. */ @@ -1588,7 +1588,7 @@ static void do_set_multicast_list(struct net_device *dev) { long e8390_base = dev->base_addr; int i; - struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { memset(ei_local->mcfilter, 0, 8); @@ -1646,7 +1646,7 @@ static void AX88190_init(struct net_device *dev, int startp) { axnet_dev_t *info = PRIV(dev); long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; @@ -1712,7 +1712,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); if (inb_p(e8390_base) & E8390_TRANS) { -- cgit v1.2.3-59-g8ed1b From 4dd151876b6b81040121708ebc23c6cd1a3d5be8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:27 +0000 Subject: drivers/net/qla3xxx.c: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/qla3xxx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 7496ed2c34ab..1a3584edd79c 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2467,7 +2467,7 @@ map_error: static netdev_tx_t ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) { - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); + struct ql3_adapter *qdev = netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct ql_tx_buf_cb *tx_cb; @@ -3390,7 +3390,7 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) static void ql_display_dev_info(struct net_device *ndev) { - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); + struct ql3_adapter *qdev = netdev_priv(ndev); struct pci_dev *pdev = qdev->pdev; netdev_info(ndev, @@ -3573,7 +3573,7 @@ static int ql3xxx_open(struct net_device *ndev) static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) { - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); + struct ql3_adapter *qdev = netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct sockaddr *addr = p; @@ -3608,7 +3608,7 @@ static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) static void ql3xxx_tx_timeout(struct net_device *ndev) { - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); + struct ql3_adapter *qdev = netdev_priv(ndev); netdev_err(ndev, "Resetting...\n"); /* -- cgit v1.2.3-59-g8ed1b From b16fed0af8416ee0fe9af6c1977f7b05e7e7c9b2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:28 +0000 Subject: drivers/net/qlge: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c30e0fe55a31..d9a76260880b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3844,7 +3844,7 @@ static int ql_adapter_reset(struct ql_adapter *qdev) static void ql_display_dev_info(struct net_device *ndev) { - struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); + struct ql_adapter *qdev = netdev_priv(ndev); netif_info(qdev, probe, qdev->ndev, "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " @@ -4264,7 +4264,7 @@ static struct net_device_stats *qlge_get_stats(struct net_device static void qlge_set_multicast_list(struct net_device *ndev) { - struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); + struct ql_adapter *qdev = netdev_priv(ndev); struct netdev_hw_addr *ha; int i, status; @@ -4354,7 +4354,7 @@ exit: static int qlge_set_mac_address(struct net_device *ndev, void *p) { - struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); + struct ql_adapter *qdev = netdev_priv(ndev); struct sockaddr *addr = p; int status; @@ -4377,7 +4377,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) static void qlge_tx_timeout(struct net_device *ndev) { - struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); + struct ql_adapter *qdev = netdev_priv(ndev); ql_queue_asic_error(qdev); } -- cgit v1.2.3-59-g8ed1b From 8739cfef1ab8bc02e1bf38c02399afe62f3a7800 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:29 +0000 Subject: drivers/net/usb: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 6710f09346d6..ef3667690b12 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -359,7 +359,7 @@ fail: static int mdio_read(struct net_device *dev, int phy_id, int loc) { - pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev); + pegasus_t *pegasus = netdev_priv(dev); u16 res; read_mii_word(pegasus, phy_id, loc, &res); @@ -397,7 +397,7 @@ fail: static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) { - pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev); + pegasus_t *pegasus = netdev_priv(dev); write_mii_word(pegasus, phy_id, loc, val); } -- cgit v1.2.3-59-g8ed1b From 5f54cebb13cdb8dcd85036f8bee29f14db18b6e1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:30 +0000 Subject: drivers/net/vxge: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-ethtool.c | 26 +++++++++++++------------- drivers/net/vxge/vxge-main.c | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index 09f721e10517..bc9bd1035706 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -80,7 +80,7 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) static void vxge_ethtool_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME)); strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION)); strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN); @@ -108,7 +108,7 @@ static void vxge_ethtool_gregs(struct net_device *dev, enum vxge_hw_status status; u64 reg; u64 *reg_space = (u64 *)space; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct __vxge_hw_device *hldev = vdev->devh; regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath; @@ -144,7 +144,7 @@ static void vxge_ethtool_gregs(struct net_device *dev, */ static int vxge_ethtool_idnic(struct net_device *dev, u32 data) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON); @@ -166,7 +166,7 @@ static int vxge_ethtool_idnic(struct net_device *dev, u32 data) static void vxge_ethtool_getpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause); @@ -185,7 +185,7 @@ static void vxge_ethtool_getpause_data(struct net_device *dev, static int vxge_ethtool_setpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct __vxge_hw_device *hldev = vdev->devh; vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause); @@ -203,7 +203,7 @@ static void vxge_get_ethtool_stats(struct net_device *dev, enum vxge_hw_status status; enum vxge_hw_status swstatus; struct vxge_vpath *vpath = NULL; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct __vxge_hw_device *hldev = vdev->devh; struct vxge_hw_xmac_stats *xmac_stats; struct vxge_hw_device_stats_sw_info *sw_stats; @@ -572,7 +572,7 @@ static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset, { int stat_size = 0; int i, j; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); switch (stringset) { case ETH_SS_STATS: vxge_add_string("VPATH STATISTICS%s\t\t\t", @@ -1059,21 +1059,21 @@ static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset, static int vxge_ethtool_get_regs_len(struct net_device *dev) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath; } static u32 vxge_get_rx_csum(struct net_device *dev) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); return vdev->rx_csum; } static int vxge_set_rx_csum(struct net_device *dev, u32 data) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); if (data) vdev->rx_csum = 1; @@ -1095,7 +1095,7 @@ static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data) static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); switch (sset) { case ETH_SS_STATS: @@ -1114,7 +1114,7 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) static int vxge_set_flags(struct net_device *dev, u32 data) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); enum vxge_hw_status status; if (data & ~ETH_FLAG_RXHASH) @@ -1148,7 +1148,7 @@ static int vxge_set_flags(struct net_device *dev, u32 data) static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms) { - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) { printk(KERN_INFO "Single Function Mode is required to flash the" diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 3f2d6ed13d3e..29f0ec88cfea 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -153,7 +153,7 @@ static void vxge_callback_link_up(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); @@ -177,7 +177,7 @@ static void vxge_callback_link_down(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); @@ -787,7 +787,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); if (unlikely(!is_vxge_card_up(vdev))) { vxge_debug_tx(VXGE_ERR, @@ -1052,7 +1052,7 @@ static void vxge_set_multicast(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); hldev = (struct __vxge_hw_device *)vdev->devh; if (unlikely(!is_vxge_card_up(vdev))) @@ -1209,7 +1209,7 @@ static int vxge_set_mac_addr(struct net_device *dev, void *p) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); hldev = vdev->devh; if (!is_valid_ether_addr(addr->sa_data)) @@ -1672,7 +1672,7 @@ static void vxge_netpoll(struct net_device *dev) struct __vxge_hw_device *hldev; struct vxgedev *vdev; - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); @@ -2582,7 +2582,7 @@ vxge_open(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); function_mode = vdev->config.device_hw_info.function_mode; @@ -2810,7 +2810,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); if (unlikely(!is_vxge_card_up(vdev))) @@ -3139,7 +3139,7 @@ vxge_tx_watchdog(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); vdev->cric_err_event = VXGE_HW_EVENT_RESET_START; @@ -3167,7 +3167,7 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); vpath = &vdev->vpaths[0]; if ((NULL == grp) && (vpath->is_open)) { @@ -3216,7 +3216,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct vxge_vpath *vpath; int vp_id; - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); /* Add these vlan to the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { @@ -3243,7 +3243,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = (struct vxgedev *)netdev_priv(dev); + vdev = netdev_priv(dev); vlan_group_set_device(vdev->vlgrp, vid, NULL); @@ -3476,7 +3476,7 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev, enum vxge_hw_event type, u64 vp_id) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct vxgedev *vdev = netdev_priv(dev); struct vxge_vpath *vpath = NULL; int vpath_idx; -- cgit v1.2.3-59-g8ed1b From ece49153b601d95bcebd45a6394e370972f0b0a0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:31 +0000 Subject: drivers/net: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ax88796.c | 8 ++++---- drivers/net/dm9000.c | 2 +- drivers/net/iseries_veth.c | 2 +- drivers/net/lib8390.c | 24 ++++++++++++------------ drivers/net/ne-h8300.c | 12 ++++++------ drivers/net/xilinx_emaclite.c | 20 ++++++++++---------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index b6da4cf3694b..4bebff3faeab 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -325,7 +325,7 @@ static void ax_block_output(struct net_device *dev, int count, static void ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; unsigned int memr; @@ -364,7 +364,7 @@ ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) static unsigned int ax_phy_ei_inbits(struct net_device *dev, int no) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; unsigned int memr; unsigned int result = 0; @@ -412,7 +412,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc) static int ax_phy_read(struct net_device *dev, int phy_addr, int reg) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned long flags; unsigned int result; @@ -435,7 +435,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg) static void ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) { - struct ei_device *ei = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei = netdev_priv(dev); struct ax_device *ax = to_ax_dev(dev); unsigned long flags; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 9f6aeefa06bf..2d4c4fc1d900 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1675,7 +1675,7 @@ dm9000_drv_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev)); + dm9000_release_board(pdev, netdev_priv(ndev)); free_netdev(ndev); /* free device structure */ dev_dbg(&pdev->dev, "released and freed device\n"); diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 8df645e78f2e..38e15be6d513 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1605,7 +1605,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) } veth_dev[i] = dev; - port = (struct veth_port*)netdev_priv(dev); + port = netdev_priv(dev); /* Start the state machine on each connection on this vlan. If we're * the first dev to do so this will commence link negotiation */ diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index e7030ceb178b..da74db4a03d4 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -203,7 +203,7 @@ static void __NS8390_init(struct net_device *dev, int startp); static int __ei_open(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); if (dev->watchdog_timeo <= 0) dev->watchdog_timeo = TX_TIMEOUT; @@ -231,7 +231,7 @@ static int __ei_open(struct net_device *dev) */ static int __ei_close(struct net_device *dev) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned long flags; /* @@ -256,7 +256,7 @@ static int __ei_close(struct net_device *dev) static void __ei_tx_timeout(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); unsigned long flags; @@ -303,7 +303,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int send_length = skb->len, output_page; unsigned long flags; char buf[ETH_ZLEN]; @@ -592,7 +592,7 @@ static void ei_tx_err(struct net_device *dev) static void ei_tx_intr(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int status = ei_inb(e8390_base + EN0_TSR); ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */ @@ -675,7 +675,7 @@ static void ei_tx_intr(struct net_device *dev) static void ei_receive(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned char rxing_page, this_frame, next_frame; unsigned short current_offset; int rx_pkt_count = 0; @@ -879,7 +879,7 @@ static void ei_rx_overrun(struct net_device *dev) static struct net_device_stats *__ei_get_stats(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned long flags; /* If the card is stopped, just return the present stats. */ @@ -927,7 +927,7 @@ static void do_set_multicast_list(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; int i; - struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { @@ -981,7 +981,7 @@ static void do_set_multicast_list(struct net_device *dev) static void __ei_set_multicast_list(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); spin_lock_irqsave(&ei_local->page_lock, flags); do_set_multicast_list(dev); @@ -998,7 +998,7 @@ static void __ei_set_multicast_list(struct net_device *dev) static void ethdev_setup(struct net_device *dev) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); if (ei_debug > 1) printk(version); @@ -1036,7 +1036,7 @@ static struct net_device *____alloc_ei_netdev(int size) static void __NS8390_init(struct net_device *dev, int startp) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0)) @@ -1099,7 +1099,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c index e0b0ef11f110..30be8c634ebd 100644 --- a/drivers/net/ne-h8300.c +++ b/drivers/net/ne-h8300.c @@ -86,7 +86,7 @@ static u32 reg_offset[16]; static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); int i; unsigned char bus_width; @@ -218,7 +218,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) int start_page, stop_page; int reg0, ret; static unsigned version_printed; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned char bus_width; if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) @@ -371,7 +371,7 @@ static int ne_close(struct net_device *dev) static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); if (ei_debug > 1) printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); @@ -397,7 +397,7 @@ static void ne_reset_8390(struct net_device *dev) static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) @@ -437,7 +437,7 @@ static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, i static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); #ifdef NE_SANITY_CHECK int xfer_count = count; #endif @@ -507,7 +507,7 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + struct ei_device *ei_local = netdev_priv(dev); unsigned long dma_start; #ifdef NE_SANITY_CHECK int retries = 0; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 14f0955eca68..2de52d18152f 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -515,7 +515,7 @@ static void xemaclite_update_address(struct net_local *drvdata, */ static int xemaclite_set_mac_address(struct net_device *dev, void *address) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); struct sockaddr *addr = address; if (netif_running(dev)) @@ -534,7 +534,7 @@ static int xemaclite_set_mac_address(struct net_device *dev, void *address) */ static void xemaclite_tx_timeout(struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); unsigned long flags; dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n", @@ -578,7 +578,7 @@ static void xemaclite_tx_timeout(struct net_device *dev) */ static void xemaclite_tx_handler(struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); dev->stats.tx_packets++; if (lp->deferred_skb) { @@ -605,7 +605,7 @@ static void xemaclite_tx_handler(struct net_device *dev) */ static void xemaclite_rx_handler(struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); struct sk_buff *skb; unsigned int align; u32 len; @@ -661,7 +661,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) { bool tx_complete = 0; struct net_device *dev = dev_id; - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); void __iomem *base_addr = lp->base_addr; u32 tx_status; @@ -918,7 +918,7 @@ void xemaclite_adjust_link(struct net_device *ndev) */ static int xemaclite_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); int retval; /* Just to be safe, stop the device first */ @@ -987,7 +987,7 @@ static int xemaclite_open(struct net_device *dev) */ static int xemaclite_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); netif_stop_queue(dev); xemaclite_disable_interrupts(lp); @@ -1031,7 +1031,7 @@ static struct net_device_stats *xemaclite_get_stats(struct net_device *dev) */ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *) netdev_priv(dev); + struct net_local *lp = netdev_priv(dev); struct sk_buff *new_skb; unsigned int len; unsigned long flags; @@ -1068,7 +1068,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) static void xemaclite_remove_ndev(struct net_device *ndev) { if (ndev) { - struct net_local *lp = (struct net_local *) netdev_priv(ndev); + struct net_local *lp = netdev_priv(ndev); if (lp->base_addr) iounmap((void __iomem __force *) (lp->base_addr)); @@ -1245,7 +1245,7 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev) struct device *dev = &of_dev->dev; struct net_device *ndev = dev_get_drvdata(dev); - struct net_local *lp = (struct net_local *) netdev_priv(ndev); + struct net_local *lp = netdev_priv(ndev); /* Un-register the mii_bus, if configured */ if (lp->has_mdio) { -- cgit v1.2.3-59-g8ed1b From 37d668004289d202f71dc5bfdadf6c18b34577a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 11:12:33 +0000 Subject: net/atm: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/atm/br2684.c | 2 +- net/atm/lec.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index ad2b232a2055..fce2eae8d476 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -97,7 +97,7 @@ static LIST_HEAD(br2684_devs); static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev) { - return (struct br2684_dev *)netdev_priv(net_dev); + return netdev_priv(net_dev); } static inline struct net_device *list_entry_brdev(const struct list_head *le) diff --git a/net/atm/lec.c b/net/atm/lec.c index 181d70c73d70..179e04bc99dd 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -816,8 +816,7 @@ static int lec_mcast_attach(struct atm_vcc *vcc, int arg) if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) return -EINVAL; vcc->proto_data = dev_lec[arg]; - return lec_mcast_make((struct lec_priv *)netdev_priv(dev_lec[arg]), - vcc); + return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); } /* Initialize device. */ -- cgit v1.2.3-59-g8ed1b From da6836500414ae734cd9873c2d553db594f831e9 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 16 Nov 2010 11:52:38 +0000 Subject: netfilter: allow hooks to pass error code back up the stack SELinux would like to pass certain fatal errors back up the stack. This patch implements the generic netfilter support for this functionality. Based-on-patch-by: Patrick McHardy Signed-off-by: Eric Paris Signed-off-by: David S. Miller --- include/linux/netfilter.h | 2 ++ net/netfilter/core.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 03317c8d4077..1893837b3966 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -33,6 +33,8 @@ #define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) +#define NF_DROP_ERR(x) (((-x) << NF_VERDICT_BITS) | NF_DROP) + /* only for userspace compatibility */ #ifndef __KERNEL__ /* Generic cache responses from hook functions. diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 85dabb86be6f..32fcbe290c04 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -173,9 +173,11 @@ next_hook: outdev, &elem, okfn, hook_thresh); if (verdict == NF_ACCEPT || verdict == NF_STOP) { ret = 1; - } else if (verdict == NF_DROP) { + } else if ((verdict & NF_VERDICT_MASK) == NF_DROP) { kfree_skb(skb); - ret = -EPERM; + ret = -(verdict >> NF_VERDICT_BITS); + if (ret == 0) + ret = -EPERM; } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn, verdict >> NF_VERDICT_BITS)) -- cgit v1.2.3-59-g8ed1b From ee58681195bf243bafc44ca53f3c24429d096cce Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 16 Nov 2010 11:52:49 +0000 Subject: network: tcp_connect should return certain errors up the stack The current tcp_connect code completely ignores errors from sending an skb. This makes sense in many situations (like -ENOBUFFS) but I want to be able to immediately fail connections if they are denied by the SELinux netfilter hook. Netfilter does not normally return ECONNREFUSED when it drops a packet so we respect that error code as a final and fatal error that can not be recovered. Based-on-patch-by: Patrick McHardy Signed-off-by: Eric Paris Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf36763..bb8f547fc7d2 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2592,6 +2592,7 @@ int tcp_connect(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *buff; + int err; tcp_connect_init(sk); @@ -2614,7 +2615,9 @@ int tcp_connect(struct sock *sk) sk->sk_wmem_queued += buff->truesize; sk_mem_charge(sk, buff->truesize); tp->packets_out += tcp_skb_pcount(buff); - tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); + err = tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); + if (err == -ECONNREFUSED) + return err; /* We change tp->snd_nxt after the tcp_transmit_skb() call * in order to make this packet get counted in tcpOutSegs. -- cgit v1.2.3-59-g8ed1b From 1f1aaf82825865a50cef0b4722607abb12aeee52 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 16 Nov 2010 11:52:57 +0000 Subject: SELinux: return -ECONNREFUSED from ip_postroute to signal fatal error The SELinux netfilter hooks just return NF_DROP if they drop a packet. We want to signal that a drop in this hook is a permanant fatal error and is not transient. If we do this the error will be passed back up the stack in some places and applications will get a faster interaction that something went wrong. Signed-off-by: Eric Paris Signed-off-by: David S. Miller --- security/selinux/hooks.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d9154cf90ae1..2c145f12d991 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4585,11 +4585,11 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, secmark_perm = PACKET__SEND; break; default: - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); } if (secmark_perm == PACKET__FORWARD_OUT) { if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); } else peer_sid = SECINITSID_KERNEL; } else { @@ -4602,28 +4602,28 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, ad.u.net.netif = ifindex; ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (secmark_active) if (avc_has_perm(peer_sid, skb->secmark, SECCLASS_PACKET, secmark_perm, &ad)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (peerlbl_active) { u32 if_sid; u32 node_sid; if (sel_netif_sid(ifindex, &if_sid)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (avc_has_perm(peer_sid, if_sid, SECCLASS_NETIF, NETIF__EGRESS, &ad)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (sel_netnode_sid(addrp, family, &node_sid)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (avc_has_perm(peer_sid, node_sid, SECCLASS_NODE, NODE__SENDTO, &ad)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); } return NF_ACCEPT; -- cgit v1.2.3-59-g8ed1b From 9920239c90d5f6dadfb44325abf3568a5e3fd827 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 10 Nov 2010 18:54:58 +0000 Subject: drivers/isdn/hisax: Add printf format/argument verification and fix fallout Add __attribute__((format... to several functins Make formats and arguments match. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/isdn/hisax/avm_pci.c | 2 +- drivers/isdn/hisax/callc.c | 4 ++-- drivers/isdn/hisax/hfc_2bds0.c | 4 ++-- drivers/isdn/hisax/hfc_2bs0.c | 2 +- drivers/isdn/hisax/hfc_pci.c | 4 ++-- drivers/isdn/hisax/hfc_sx.c | 6 +++--- drivers/isdn/hisax/hisax.h | 2 ++ drivers/isdn/hisax/ipacx.c | 2 +- drivers/isdn/hisax/isar.c | 6 +++--- drivers/isdn/hisax/isdnl1.h | 1 + drivers/isdn/hisax/isdnl3.c | 2 +- drivers/isdn/hisax/netjet.c | 10 +++++----- drivers/isdn/hisax/st5481_d.c | 6 ++++-- 13 files changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index fcf4ed1cb4b9..0e66af1decd4 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -314,7 +314,7 @@ hdlc_fill_fifo(struct BCState *bcs) bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME; } if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len); + debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len); p = bcs->tx_skb->data; ptr = (u_int *)p; skb_pull(bcs->tx_skb, count); diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index f150330b5a23..37e685eafd24 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -65,7 +65,7 @@ hisax_findcard(int driverid) return (struct IsdnCardState *) 0; } -static void +static __attribute__((format(printf, 3, 4))) void link_debug(struct Channel *chanp, int direction, char *fmt, ...) { va_list args; @@ -1068,7 +1068,7 @@ init_d_st(struct Channel *chanp) return 0; } -static void +static __attribute__((format(printf, 2, 3))) void callc_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index 7250f56a5246..a16459a1332c 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c @@ -292,7 +292,7 @@ hfc_fill_fifo(struct BCState *bcs) } count = GetFreeFifoBytes_B(bcs); if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx", + debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); if (count < bcs->tx_skb->len) { @@ -719,7 +719,7 @@ hfc_fill_dfifo(struct IsdnCardState *cs) } count = GetFreeFifoBytes_D(cs); if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfc_fill_Dfifo count(%ld/%d)", + debugl1(cs, "hfc_fill_Dfifo count(%u/%d)", cs->tx_skb->len, count); if (count < cs->tx_skb->len) { if (cs->debug & L1_DEB_ISAC) diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index b1f6481e1193..626f85df302b 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -282,7 +282,7 @@ hfc_fill_fifo(struct BCState *bcs) count += cs->hw.hfc.fifosize; } /* L1_MODE_TRANS */ if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)", + debugl1(cs, "hfc_fill_fifo %d count(%u/%d)", bcs->channel, bcs->tx_skb->len, count); if (count < bcs->tx_skb->len) { diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 917cc84065bd..3147020d188b 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -550,7 +550,7 @@ hfcpci_fill_dfifo(struct IsdnCardState *cs) count += D_FIFO_SIZE; /* count now contains available bytes */ if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo count(%ld/%d)", + debugl1(cs, "hfcpci_fill_Dfifo count(%u/%d)", cs->tx_skb->len, count); if (count < cs->tx_skb->len) { if (cs->debug & L1_DEB_ISAC) @@ -681,7 +681,7 @@ hfcpci_fill_fifo(struct BCState *bcs) count += B_FIFO_SIZE; /* count now contains available bytes */ if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo %d count(%ld/%d),%lx", + debugl1(cs, "hfcpci_fill_fifo %d count(%u/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 5aa138eb0b3c..1235b7131ae1 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -179,7 +179,7 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans count += fifo_size; /* count now contains available bytes */ if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)", + debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)", fifo, skb->len, count); if (count < skb->len) { if (cs->debug & L1_DEB_ISAC_FIFO) @@ -265,7 +265,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) count++; if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_read_fifo %d count %ld)", + debugl1(cs, "hfcsx_read_fifo %d count %u)", fifo, count); if ((count > fifo_size) || (count < 4)) { @@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) default: spin_unlock_irqrestore(&cs->lock, flags); if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg); + debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg); return; } cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */ diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 32ab3924aa73..de1c669c7b13 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1286,7 +1286,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl * ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); +__attribute__((format(printf, 3, 4))) void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +__attribute__((format(printf, 3, 0))) void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char * p, int cnt); diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 751b25f2ff58..332104103e18 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -717,7 +717,7 @@ bch_mode(struct BCState *bcs, int mode, int bc) bc = bc ? 1 : 0; // in case bc is greater than 1 if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc); + debugl1(cs, "mode_bch() switch B-%d mode %d chan %d", hscx, mode, bc); bcs->mode = mode; bcs->channel = bc; diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 2e72227bd071..1be4552d94b4 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -953,7 +953,7 @@ isar_pump_statev_modem(struct BCState *bcs, u_char devt) { break; case PSEV_GSTN_CLR: if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev GSTN CLEAR", devt); + debugl1(cs, "pump stev GSTN CLEAR"); break; default: if (cs->debug & L1_DEB_HSCX) @@ -1268,7 +1268,7 @@ isar_int_main(struct IsdnCardState *cs) static void ftimer_handler(struct BCState *bcs) { if (bcs->cs->debug) - debugl1(bcs->cs, "ftimer flags %04x", + debugl1(bcs->cs, "ftimer flags %04lx", bcs->Flag); test_and_clear_bit(BC_FLG_FTI_RUN, &bcs->Flag); if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) { @@ -1748,7 +1748,7 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { struct BCState *bcs; if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd cmd/ch %x/%d", ic->command, ic->arg); + debugl1(cs, "isar_auxcmd cmd/ch %x/%ld", ic->command, ic->arg); switch (ic->command) { case (ISDN_CMD_FAXCMD): bcs = cs->channel[ic->arg].bcs; diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h index 172ad4c8c961..425d86116f2b 100644 --- a/drivers/isdn/hisax/isdnl1.h +++ b/drivers/isdn/hisax/isdnl1.h @@ -21,6 +21,7 @@ #define B_XMTBUFREADY 1 #define B_ACKPENDING 2 +__attribute__((format(printf, 2, 3))) void debugl1(struct IsdnCardState *cs, char *fmt, ...); void DChannel_proc_xmt(struct IsdnCardState *cs); void DChannel_proc_rcv(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index fd0b643ab740..ad291f21b201 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c @@ -66,7 +66,7 @@ static char *strL3Event[] = "EV_TIMEOUT", }; -static void +static __attribute__((format(printf, 2, 3))) void l3m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index 5d7f0f2ff9b9..644891efc26f 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -254,7 +254,7 @@ static int make_raw_data(struct BCState *bcs) { val >>= 1; } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d", + debugl1(bcs->cs,"tiger make_raw: in %u out %d.%d", bcs->tx_skb->len, s_cnt, bitcnt); if (bitcnt) { while (8>bitcnt++) { @@ -361,7 +361,7 @@ static int make_raw_data_56k(struct BCState *bcs) { val >>= 1; } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d", + debugl1(bcs->cs,"tiger make_raw_56k: in %u out %d.%d", bcs->tx_skb->len, s_cnt, bitcnt); if (bitcnt) { while (8>bitcnt++) { @@ -612,7 +612,7 @@ void netjet_fill_dma(struct BCState *bcs) if (!bcs->tx_skb) return; if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma1: c%d %4lx", bcs->channel, bcs->Flag); if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) return; @@ -625,7 +625,7 @@ void netjet_fill_dma(struct BCState *bcs) return; }; if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma2: c%d %4lx", bcs->channel, bcs->Flag); if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); @@ -667,7 +667,7 @@ void netjet_fill_dma(struct BCState *bcs) write_raw(bcs, p, cnt); } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma3: c%d %4lx", bcs->channel, bcs->Flag); } diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index b7876b19fe73..44082637a09f 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -167,7 +167,8 @@ static struct FsmNode L1FnList[] __initdata = {ST_L1_F8, EV_IND_RSY, l1_ignore}, }; -static void l1m_debug(struct FsmInst *fi, char *fmt, ...) +static __attribute__((format(printf, 2, 3))) +void l1m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; char buf[256]; @@ -269,7 +270,8 @@ static char *strDoutEvent[] = "EV_DOUT_UNDERRUN", }; -static void dout_debug(struct FsmInst *fi, char *fmt, ...) +static __attribute__((format(printf, 2, 3))) +void dout_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; char buf[256]; -- cgit v1.2.3-59-g8ed1b From d67ef35fff67845c64d806c033cc7c569ccebfff Mon Sep 17 00:00:00 2001 From: Jeremy Eder Date: Mon, 15 Nov 2010 05:41:31 +0000 Subject: clarify documentation for net.ipv4.igmp_max_memberships This patch helps clarify documentation for net.ipv4.igmp_max_memberships by providing a formula for calculating the maximum number of multicast groups that can be subscribed to, plus defining the theoretical limit. Signed-off-by: Jiri Pirko Signed-off-by: Jeremy Eder Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fe95105992c5..ae5522703d16 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -707,10 +707,28 @@ igmp_max_memberships - INTEGER Change the maximum number of multicast groups we can subscribe to. Default: 20 -conf/interface/* changes special settings per interface (where "interface" is - the name of your network interface) -conf/all/* is special, changes the settings for all interfaces + Theoretical maximum value is bounded by having to send a membership + report in a single datagram (i.e. the report can't span multiple + datagrams, or risk confusing the switch and leaving groups you don't + intend to). + The number of supported groups 'M' is bounded by the number of group + report entries you can fit into a single datagram of 65535 bytes. + + M = 65536-sizeof (ip header)/(sizeof(Group record)) + + Group records are variable length, with a minimum of 12 bytes. + So net.ipv4.igmp_max_memberships should not be set higher than: + + (65536-24) / 12 = 5459 + + The value 5459 assumes no IP header options, so in practice + this number may be lower. + + conf/interface/* changes special settings per interface (where + "interface" is the name of your network interface) + + conf/all/* is special, changes the settings for all interfaces log_martians - BOOLEAN Log packets with impossible addresses to kernel log. -- cgit v1.2.3-59-g8ed1b From f8ff182c716c6f11ca3061961f5722f26a14e101 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 16 Nov 2010 04:30:14 +0000 Subject: rtnetlink: Link address family API Each net_device contains address family specific data such as per device settings and statistics. We already expose this data via procfs/sysfs and partially netlink. The netlink method requires the requester to send one RTM_GETLINK request for each address family it wishes to receive data of and then merge this data itself. This patch implements a new API which combines all address family specific link data in a new netlink attribute IFLA_AF_SPEC. IFLA_AF_SPEC contains a sequence of nested attributes, one for each address family which in turn defines the structure of its own attribute. Example: [IFLA_AF_SPEC] = { [AF_INET] = { [IFLA_INET_CONF] = ..., }, [AF_INET6] = { [IFLA_INET6_FLAGS] = ..., [IFLA_INET6_CONF] = ..., } } The API also allows for address families to implement a function which parses the IFLA_AF_SPEC attribute sent by userspace to implement address family specific link options. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/if_link.h | 19 +++++++ include/net/rtnetlink.h | 31 ++++++++++ net/core/rtnetlink.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 195 insertions(+), 2 deletions(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 2fc66dd783ee..443d04a66a79 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -80,6 +80,24 @@ struct rtnl_link_ifmap { __u8 port; }; +/* + * IFLA_AF_SPEC + * Contains nested attributes for address family specific attributes. + * Each address family may create a attribute with the address family + * number as type and create its own attribute structure in it. + * + * Example: + * [IFLA_AF_SPEC] = { + * [AF_INET] = { + * [IFLA_INET_CONF] = ..., + * }, + * [AF_INET6] = { + * [IFLA_INET6_FLAGS] = ..., + * [IFLA_INET6_CONF] = ..., + * } + * } + */ + enum { IFLA_UNSPEC, IFLA_ADDRESS, @@ -116,6 +134,7 @@ enum { IFLA_STATS64, IFLA_VF_PORTS, IFLA_PORT_SELF, + IFLA_AF_SPEC, __IFLA_MAX }; diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index e013c68bfb00..35be0bbcd7da 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -83,6 +83,37 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); +/** + * struct rtnl_af_ops - rtnetlink address family operations + * + * @list: Used internally + * @family: Address family + * @fill_link_af: Function to fill IFLA_AF_SPEC with address family + * specific netlink attributes. + * @get_link_af_size: Function to calculate size of address family specific + * netlink attributes exlusive the container attribute. + * @parse_link_af: Function to parse a IFLA_AF_SPEC attribute and modify + * net_device accordingly. + */ +struct rtnl_af_ops { + struct list_head list; + int family; + + int (*fill_link_af)(struct sk_buff *skb, + const struct net_device *dev); + size_t (*get_link_af_size)(const struct net_device *dev); + + int (*parse_link_af)(struct net_device *dev, + const struct nlattr *attr); +}; + +extern int __rtnl_af_register(struct rtnl_af_ops *ops); +extern void __rtnl_af_unregister(struct rtnl_af_ops *ops); + +extern int rtnl_af_register(struct rtnl_af_ops *ops); +extern void rtnl_af_unregister(struct rtnl_af_ops *ops); + + extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net, char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 841c287ef40a..bf69e5871b1a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -362,6 +362,95 @@ static size_t rtnl_link_get_size(const struct net_device *dev) return size; } +static LIST_HEAD(rtnl_af_ops); + +static const struct rtnl_af_ops *rtnl_af_lookup(const int family) +{ + const struct rtnl_af_ops *ops; + + list_for_each_entry(ops, &rtnl_af_ops, list) { + if (ops->family == family) + return ops; + } + + return NULL; +} + +/** + * __rtnl_af_register - Register rtnl_af_ops with rtnetlink. + * @ops: struct rtnl_af_ops * to register + * + * The caller must hold the rtnl_mutex. + * + * Returns 0 on success or a negative error code. + */ +int __rtnl_af_register(struct rtnl_af_ops *ops) +{ + list_add_tail(&ops->list, &rtnl_af_ops); + return 0; +} +EXPORT_SYMBOL_GPL(__rtnl_af_register); + +/** + * rtnl_af_register - Register rtnl_af_ops with rtnetlink. + * @ops: struct rtnl_af_ops * to register + * + * Returns 0 on success or a negative error code. + */ +int rtnl_af_register(struct rtnl_af_ops *ops) +{ + int err; + + rtnl_lock(); + err = __rtnl_af_register(ops); + rtnl_unlock(); + return err; +} +EXPORT_SYMBOL_GPL(rtnl_af_register); + +/** + * __rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. + * @ops: struct rtnl_af_ops * to unregister + * + * The caller must hold the rtnl_mutex. + */ +void __rtnl_af_unregister(struct rtnl_af_ops *ops) +{ + list_del(&ops->list); +} +EXPORT_SYMBOL_GPL(__rtnl_af_unregister); + +/** + * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. + * @ops: struct rtnl_af_ops * to unregister + */ +void rtnl_af_unregister(struct rtnl_af_ops *ops) +{ + rtnl_lock(); + __rtnl_af_unregister(ops); + rtnl_unlock(); +} +EXPORT_SYMBOL_GPL(rtnl_af_unregister); + +static size_t rtnl_link_get_af_size(const struct net_device *dev) +{ + struct rtnl_af_ops *af_ops; + size_t size; + + /* IFLA_AF_SPEC */ + size = nla_total_size(sizeof(struct nlattr)); + + list_for_each_entry(af_ops, &rtnl_af_ops, list) { + if (af_ops->get_link_af_size) { + /* AF_* + nested data */ + size += nla_total_size(sizeof(struct nlattr)) + + af_ops->get_link_af_size(dev); + } + } + + return size; +} + static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) { const struct rtnl_link_ops *ops = dev->rtnl_link_ops; @@ -671,7 +760,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev) + nla_total_size(4) /* IFLA_NUM_VF */ + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ - + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ + + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ + + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */ } static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) @@ -757,7 +847,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct nlmsghdr *nlh; struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; - struct nlattr *attr; + struct nlattr *attr, *af_spec; + struct rtnl_af_ops *af_ops; nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) @@ -866,6 +957,36 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, goto nla_put_failure; } + if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC))) + goto nla_put_failure; + + list_for_each_entry(af_ops, &rtnl_af_ops, list) { + if (af_ops->fill_link_af) { + struct nlattr *af; + int err; + + if (!(af = nla_nest_start(skb, af_ops->family))) + goto nla_put_failure; + + err = af_ops->fill_link_af(skb, dev); + + /* + * Caller may return ENODATA to indicate that there + * was no data to be dumped. This is not an error, it + * means we should trim the attribute header and + * continue. + */ + if (err == -ENODATA) + nla_nest_cancel(skb, af); + else if (err < 0) + goto nla_put_failure; + + nla_nest_end(skb, af); + } + } + + nla_nest_end(skb, af_spec); + return nlmsg_end(skb, nlh); nla_put_failure: @@ -924,6 +1045,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, [IFLA_VF_PORTS] = { .type = NLA_NESTED }, [IFLA_PORT_SELF] = { .type = NLA_NESTED }, + [IFLA_AF_SPEC] = { .type = NLA_NESTED }, }; EXPORT_SYMBOL(ifla_policy); @@ -1225,6 +1347,27 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, goto errout; modified = 1; } + + if (tb[IFLA_AF_SPEC]) { + struct nlattr *af; + int rem; + + nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { + const struct rtnl_af_ops *af_ops; + + if (!(af_ops = rtnl_af_lookup(nla_type(af)))) + continue; + + if (!af_ops->parse_link_af) + continue; + + err = af_ops->parse_link_af(dev, af); + if (err < 0) + goto errout; + + modified = 1; + } + } err = 0; errout: -- cgit v1.2.3-59-g8ed1b From ca7479ebbd9f7621646bf2792cb7143647f035bb Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 16 Nov 2010 04:31:20 +0000 Subject: inet: Define IPV4_DEVCONF_MAX Define IPV4_DEVCONF_MAX to get rid of MAX - 1 notation. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 380ba6bc5db1..2b86eaf11773 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -41,10 +41,12 @@ enum __IPV4_DEVCONF_MAX }; +#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1) + struct ipv4_devconf { void *sysctl; - int data[__IPV4_DEVCONF_MAX - 1]; - DECLARE_BITMAP(state, __IPV4_DEVCONF_MAX - 1); + int data[IPV4_DEVCONF_MAX]; + DECLARE_BITMAP(state, IPV4_DEVCONF_MAX); }; struct in_device { @@ -90,7 +92,7 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index, static inline void ipv4_devconf_setall(struct in_device *in_dev) { - bitmap_fill(in_dev->cnf.state, __IPV4_DEVCONF_MAX - 1); + bitmap_fill(in_dev->cnf.state, IPV4_DEVCONF_MAX); } #define IN_DEV_CONF_GET(in_dev, attr) \ -- cgit v1.2.3-59-g8ed1b From 9f0f7272ac9506f4c8c05cc597b7e376b0b9f3e4 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 16 Nov 2010 04:32:48 +0000 Subject: ipv4: AF_INET link address family Implements the AF_INET link address family exposing the per device configuration settings via netlink using the attribute IFLA_INET_CONF. The format of IFLA_INET_CONF differs depending on the direction the attribute is sent. The attribute sent by the kernel consists of a u32 array, basically a 1:1 copy of in_device->cnf.data[]. The attribute expected by the kernel must consist of a sequence of nested u32 attributes, each representing a change request, e.g. [IFLA_INET_CONF] = { [IPV4_DEVCONF_FORWARDING] = 1, [IPV4_DEVCONF_NOXFRM] = 0, } libnl userspace API documentation and example available from: http://www.infradead.org/~tgr/libnl/doc-git/group__link__inet.html Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/if_link.h | 8 ++++++ net/ipv4/devinet.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 443d04a66a79..2e02e4d7b11e 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -147,6 +147,14 @@ enum { #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) #endif +enum { + IFLA_INET_UNSPEC, + IFLA_INET_CONF, + __IFLA_INET_MAX, +}; + +#define IFLA_INET_MAX (__IFLA_INET_MAX - 1) + /* ifi_flags. IFF_* flags. diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index dc94b0316b78..71afc26c2df8 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1256,6 +1256,72 @@ errout: rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err); } +static size_t inet_get_link_af_size(const struct net_device *dev) +{ + struct in_device *in_dev = __in_dev_get_rcu(dev); + + if (!in_dev) + return 0; + + return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */ +} + +static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev) +{ + struct in_device *in_dev = __in_dev_get_rcu(dev); + struct nlattr *nla; + int i; + + if (!in_dev) + return -ENODATA; + + nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4); + if (nla == NULL) + return -EMSGSIZE; + + for (i = 0; i < IPV4_DEVCONF_MAX; i++) + ((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i]; + + return 0; +} + +static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = { + [IFLA_INET_CONF] = { .type = NLA_NESTED }, +}; + +static int inet_parse_link_af(struct net_device *dev, const struct nlattr *nla) +{ + struct in_device *in_dev = __in_dev_get_rcu(dev); + struct nlattr *a, *tb[IFLA_INET_MAX+1]; + int err, rem; + + if (!in_dev) + return -EOPNOTSUPP; + + err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy); + if (err < 0) + return err; + + if (tb[IFLA_INET_CONF]) { + nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) { + int cfgid = nla_type(a); + + if (nla_len(a) < 4) + return -EINVAL; + + if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) + return -EINVAL; + } + } + + if (tb[IFLA_INET_CONF]) { + nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) + ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a)); + } + + return 0; +} + #ifdef CONFIG_SYSCTL static void devinet_copy_dflt_conf(struct net *net, int i) @@ -1619,6 +1685,13 @@ static __net_initdata struct pernet_operations devinet_ops = { .exit = devinet_exit_net, }; +static struct rtnl_af_ops inet_af_ops = { + .family = AF_INET, + .fill_link_af = inet_fill_link_af, + .get_link_af_size = inet_get_link_af_size, + .parse_link_af = inet_parse_link_af, +}; + void __init devinet_init(void) { register_pernet_subsys(&devinet_ops); @@ -1626,6 +1699,8 @@ void __init devinet_init(void) register_gifconf(PF_INET, inet_gifconf); register_netdevice_notifier(&ip_netdev_notifier); + rtnl_af_register(&inet_af_ops); + rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL); rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); -- cgit v1.2.3-59-g8ed1b From b382b191ea9e9ccefc437433d23befe91f4a8925 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 16 Nov 2010 04:33:57 +0000 Subject: ipv6: AF_INET6 link address family IPv6 already exposes some address family data via netlink in the IFLA_PROTINFO attribute if RTM_GETLINK request is sent with the address family set to AF_INET6. We take over this format and reuse all the code. Signed-off-by: Thomas Graf Cc: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 122 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 33 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index aaa3ca448d08..470e7acb91df 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3831,6 +3831,15 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; } +static inline size_t inet6_ifla6_size(void) +{ + return nla_total_size(4) /* IFLA_INET6_FLAGS */ + + nla_total_size(sizeof(struct ifla_cacheinfo)) + + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ + + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ + + nla_total_size(ICMP6_MIB_MAX * 8); /* IFLA_INET6_ICMP6STATS */ +} + static inline size_t inet6_if_nlmsg_size(void) { return NLMSG_ALIGN(sizeof(struct ifinfomsg)) @@ -3838,13 +3847,7 @@ static inline size_t inet6_if_nlmsg_size(void) + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ + nla_total_size(4) /* IFLA_MTU */ + nla_total_size(4) /* IFLA_LINK */ - + nla_total_size( /* IFLA_PROTINFO */ - nla_total_size(4) /* IFLA_INET6_FLAGS */ - + nla_total_size(sizeof(struct ifla_cacheinfo)) - + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ - + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ - + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */ - ); + + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */ } static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, @@ -3891,15 +3894,76 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, } } +static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev) +{ + struct nlattr *nla; + struct ifla_cacheinfo ci; + + NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); + + ci.max_reasm_len = IPV6_MAXPLEN; + ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 + + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); + ci.reachable_time = idev->nd_parms->reachable_time; + ci.retrans_time = idev->nd_parms->retrans_time; + NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); + + nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); + if (nla == NULL) + goto nla_put_failure; + ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla)); + + /* XXX - MC not implemented */ + + nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); + if (nla == NULL) + goto nla_put_failure; + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); + + nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); + if (nla == NULL) + goto nla_put_failure; + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); + + return 0; + +nla_put_failure: + return -EMSGSIZE; +} + +static size_t inet6_get_link_af_size(const struct net_device *dev) +{ + if (!__in6_dev_get(dev)) + return 0; + + return inet6_ifla6_size(); +} + +static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev) +{ + struct inet6_dev *idev = __in6_dev_get(dev); + + if (!idev) + return -ENODATA; + + if (inet6_fill_ifla6_attrs(skb, idev) < 0) + return -EMSGSIZE; + + return 0; +} + +static int inet6_parse_link_af(struct net_device *dev, const struct nlattr *nla) +{ + return -EOPNOTSUPP; +} + static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, u32 pid, u32 seq, int event, unsigned int flags) { struct net_device *dev = idev->dev; - struct nlattr *nla; struct ifinfomsg *hdr; struct nlmsghdr *nlh; void *protoinfo; - struct ifla_cacheinfo ci; nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) @@ -3926,31 +3990,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, if (protoinfo == NULL) goto nla_put_failure; - NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); - - ci.max_reasm_len = IPV6_MAXPLEN; - ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 - + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); - ci.reachable_time = idev->nd_parms->reachable_time; - ci.retrans_time = idev->nd_parms->retrans_time; - NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); - - nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); - if (nla == NULL) - goto nla_put_failure; - ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla)); - - /* XXX - MC not implemented */ - - nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); - if (nla == NULL) - goto nla_put_failure; - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); - - nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); - if (nla == NULL) + if (inet6_fill_ifla6_attrs(skb, idev) < 0) goto nla_put_failure; - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); nla_nest_end(skb, protoinfo); return nlmsg_end(skb, nlh); @@ -4621,6 +4662,13 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_inet6addr_notifier); +static struct rtnl_af_ops inet6_ops = { + .family = AF_INET6, + .fill_link_af = inet6_fill_link_af, + .get_link_af_size = inet6_get_link_af_size, + .parse_link_af = inet6_parse_link_af, +}; + /* * Init / cleanup code */ @@ -4672,6 +4720,10 @@ int __init addrconf_init(void) addrconf_verify(0); + err = rtnl_af_register(&inet6_ops); + if (err < 0) + goto errout_af; + err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo); if (err < 0) goto errout; @@ -4687,6 +4739,8 @@ int __init addrconf_init(void) return 0; errout: + rtnl_af_unregister(&inet6_ops); +errout_af: unregister_netdevice_notifier(&ipv6_dev_notf); errlo: unregister_pernet_subsys(&addrconf_ops); @@ -4707,6 +4761,8 @@ void addrconf_cleanup(void) rtnl_lock(); + __rtnl_af_unregister(&inet6_ops); + /* clean dev list */ for_each_netdev(&init_net, dev) { if (__in6_dev_get(dev) == NULL) -- cgit v1.2.3-59-g8ed1b From 2abea2f0a5ab161facd865356d2e59b23204414e Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Tue, 16 Nov 2010 14:07:53 +0000 Subject: qlcnic: Allow minimum bandwidth of zero Allow minimum bandwidth to be set zero Signed-off-by: Sucheta Chakraborty Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 8ecc170c9b74..a6b71fe81d07 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1126,8 +1126,7 @@ struct qlcnic_eswitch { /* Return codes for Error handling */ #define QL_STATUS_INVALID_PARAM -1 -#define MAX_BW 100 -#define MIN_BW 1 +#define MAX_BW 100 /* % of link speed */ #define MAX_VLAN_ID 4095 #define MIN_VLAN_ID 2 #define MAX_TX_QUEUES 1 @@ -1135,7 +1134,7 @@ struct qlcnic_eswitch { #define DEFAULT_MAC_LEARN 1 #define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan < MAX_VLAN_ID) -#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) +#define IS_VALID_BW(bw) (bw <= MAX_BW) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) -- cgit v1.2.3-59-g8ed1b From c21fd48c22bd1a9c4a5286963086f246c782e47e Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 16 Nov 2010 14:08:06 +0000 Subject: qlcnic: Fix for kdump In case of kdump environment the function may be in unknown state. Reset the function using PCI FLR before initializing it. Signed-off-by: Rajesh Borundia Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ctx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 1cdc05dade6b..3ad1f3eba289 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -480,6 +480,9 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter) { int err; + if (reset_devices) + pci_reset_function(adapter->pdev); + err = qlcnic_fw_cmd_create_rx_ctx(adapter); if (err) return err; -- cgit v1.2.3-59-g8ed1b From 2679a135e6452359cd807754617db0d05ad404e5 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Tue, 16 Nov 2010 14:08:23 +0000 Subject: qlcnic: Add description for CN1000Q adapter Add description for CN1000Q adapter Signed-off-by: Sritej Velaga Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index a6b71fe81d07..1375981bf730 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1376,6 +1376,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x103c, 0x3733, "NC523SFP 10Gb 2-port Server Adapter"}, + {0x1077, 0x8020, 0x103c, 0x3346, + "CN1000Q Dual Port Converged Network Adapter"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; -- cgit v1.2.3-59-g8ed1b From 706f23ada68746ed475488e7d2e2ca392fc4f731 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Tue, 16 Nov 2010 14:08:46 +0000 Subject: qlcnic: lro off message log from set rx checsum Log LRO off message while disabling rx checksum only when LRO is already enabled. Signed-off-by: Sony Chacko Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index ec21d24015c4..c38929636488 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -925,9 +925,10 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) dev->features &= ~NETIF_F_LRO; qlcnic_send_lro_cleanup(adapter); + dev_info(&adapter->pdev->dev, + "disabling LRO as rx_csum is off\n"); } adapter->rx_csum = !!data; - dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n"); return 0; } -- cgit v1.2.3-59-g8ed1b From 802aa9c058f2046f0a5683f04d7755c362734010 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Tue, 16 Nov 2010 14:09:06 +0000 Subject: qlcnic: Bumped up driver version to 5.0.12 Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 1375981bf730..56f54ffabb2f 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 11 -#define QLCNIC_LINUX_VERSIONID "5.0.11" +#define _QLCNIC_LINUX_SUBVERSION 12 +#define QLCNIC_LINUX_VERSIONID "5.0.12" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3-59-g8ed1b From a31ff3880578c37fd5c71ee863c23897dacfa9f8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 10:13:57 +0000 Subject: drivers/net/s2io.c: Remove unnecessary casts of pci_get_drvdata Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/s2io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ecc25aab896a..0f4219cb0be2 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -8321,8 +8321,7 @@ mem_alloc_failed: static void __devexit s2io_rem_nic(struct pci_dev *pdev) { - struct net_device *dev = - (struct net_device *)pci_get_drvdata(pdev); + struct net_device *dev = pci_get_drvdata(pdev); struct s2io_nic *sp; if (dev == NULL) { -- cgit v1.2.3-59-g8ed1b From d8ee707114bc3615fd7be90eb942eba2dbe668ed Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 10:13:58 +0000 Subject: drivers/net/vxge/vxge-main.c: Remove unnecessary casts of pci_get_drvdata Signed-off-by: Joe Perches Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 29f0ec88cfea..5cba4a684f08 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -688,7 +688,7 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) struct vxge_vpath *vpath = NULL; struct __vxge_hw_device *hldev; - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); mac_address = (u8 *)&mac_addr; memcpy(mac_address, mac_header, ETH_ALEN); @@ -1313,7 +1313,7 @@ static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) struct __vxge_hw_device *hldev; int msix_id; - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); vxge_hw_vpath_wait_receive_idle(hldev, vpath->device_id); @@ -1632,8 +1632,7 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) int budget_org = budget; struct vxge_ring *ring; - struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) - pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = pci_get_drvdata(vdev->pdev); for (i = 0; i < vdev->no_of_vpath; i++) { ring = &vdev->vpaths[i].ring; @@ -1673,7 +1672,7 @@ static void vxge_netpoll(struct net_device *dev) struct vxgedev *vdev; vdev = netdev_priv(dev); - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); @@ -2107,7 +2106,7 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__); dev = vdev->ndev; - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); if (pci_channel_offline(vdev->pdev)) return IRQ_NONE; @@ -2342,7 +2341,7 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) static void vxge_rem_isr(struct vxgedev *vdev) { struct __vxge_hw_device *hldev; - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); #ifdef CONFIG_PCI_MSI if (vdev->config.intr_type == MSI_X) { @@ -2583,7 +2582,7 @@ vxge_open(struct net_device *dev) "%s: %s:%d", dev->name, __func__, __LINE__); vdev = netdev_priv(dev); - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); function_mode = vdev->config.device_hw_info.function_mode; /* make sure you have link off by default every time Nic is @@ -2811,7 +2810,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) dev->name, __func__, __LINE__); vdev = netdev_priv(dev); - hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); + hldev = pci_get_drvdata(vdev->pdev); if (unlikely(!is_vxge_card_up(vdev))) return 0; @@ -3985,8 +3984,7 @@ static int vxge_pm_resume(struct pci_dev *pdev) static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *)pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; netif_device_detach(netdev); @@ -4015,8 +4013,7 @@ static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *)pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; struct vxgedev *vdev = netdev_priv(netdev); @@ -4041,8 +4038,7 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) */ static void vxge_io_resume(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = - (struct __vxge_hw_device *)pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; if (netif_running(netdev)) { @@ -4689,7 +4685,7 @@ static void __devexit vxge_remove(struct pci_dev *pdev) struct net_device *dev; int i = 0; - hldev = (struct __vxge_hw_device *)pci_get_drvdata(pdev); + hldev = pci_get_drvdata(pdev); if (hldev == NULL) return; -- cgit v1.2.3-59-g8ed1b From b1323c8fa153f63e20d5a7fc0be72073c3beb05b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 12 Nov 2010 11:37:59 +0000 Subject: drivers/net/can/sja1000: Use printf extension %pR for struct resource Using %pR standardizes the struct resource output. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/can/sja1000/sja1000_of_platform.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 5bfccfdf3bbb..09c3e9db9316 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -107,17 +107,13 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev, res_size = resource_size(&res); if (!request_mem_region(res.start, res_size, DRV_NAME)) { - dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_err(&ofdev->dev, "couldn't request %pR\n", &res); return -EBUSY; } base = ioremap_nocache(res.start, res_size); if (!base) { - dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); err = -ENOMEM; goto exit_release_mem; } -- cgit v1.2.3-59-g8ed1b From dd68ad2235b4625e0dc928b2b4c614d265f976d3 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Sat, 13 Nov 2010 08:43:29 +0000 Subject: net: more Kconfig whitespace cleanup indentation for TSI108_ETH entry was too big. Signed-off-by: Philippe De Muyter Signed-off-by: David S. Miller --- drivers/net/Kconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 0a7e6cea0082..a11dc735752c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2389,12 +2389,12 @@ config SPIDER_NET Cell Processor-Based Blades from IBM. config TSI108_ETH - tristate "Tundra TSI108 gigabit Ethernet support" - depends on TSI108_BRIDGE - help - This driver supports Tundra TSI108 gigabit Ethernet ports. - To compile this driver as a module, choose M here: the module - will be called tsi108_eth. + tristate "Tundra TSI108 gigabit Ethernet support" + depends on TSI108_BRIDGE + help + This driver supports Tundra TSI108 gigabit Ethernet ports. + To compile this driver as a module, choose M here: the module + will be called tsi108_eth. config GELIC_NET tristate "PS3 Gigabit Ethernet driver" -- cgit v1.2.3-59-g8ed1b From 5811662b15db018c740c57d037523683fd3e6123 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 12 Nov 2010 18:43:55 +0000 Subject: net: use the macros defined for the members of flowi Use the macros defined for the members of flowi to clean the code up. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/net/route.h | 12 +++++------- net/atm/clip.c | 3 ++- net/bridge/br_netfilter.c | 9 ++------- net/dccp/ipv4.c | 13 +++++-------- net/decnet/dn_route.c | 22 +++++++++------------ net/decnet/dn_rules.c | 2 +- net/ipv4/af_inet.c | 18 +++++------------ net/ipv4/arp.c | 12 ++++++------ net/ipv4/fib_frontend.c | 28 ++++++++------------------- net/ipv4/fib_semantics.c | 8 ++------ net/ipv4/icmp.c | 28 +++++++++------------------ net/ipv4/igmp.c | 8 +++----- net/ipv4/inet_connection_sock.c | 15 ++++++-------- net/ipv4/ip_gre.c | 31 +++++++++-------------------- net/ipv4/ip_output.c | 25 ++++++++++-------------- net/ipv4/ipip.c | 20 ++++++------------- net/ipv4/ipmr.c | 18 +++++------------ net/ipv4/netfilter.c | 8 ++++---- net/ipv4/raw.c | 7 +++---- net/ipv4/route.c | 43 ++++++++++++++++------------------------- net/ipv4/syncookies.c | 15 ++++++-------- net/ipv4/udp.c | 12 +++++------- net/ipv4/xfrm4_policy.c | 8 ++------ net/ipv6/ip6mr.c | 4 +--- net/ipv6/netfilter.c | 6 ++---- net/ipv6/route.c | 24 ++++++----------------- net/ipv6/sit.c | 14 ++++++-------- net/l2tp/l2tp_ip.c | 12 +++++------- net/netfilter/ipvs/ip_vs_ctl.c | 6 ++---- net/netfilter/ipvs/ip_vs_xmit.c | 34 ++++++++------------------------ net/netfilter/xt_TEE.c | 12 ++++++------ net/rxrpc/ar-peer.c | 10 +++++----- 32 files changed, 171 insertions(+), 316 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 5cd46d1c0e14..b8c1f7703fc6 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -169,14 +169,12 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, - .nl_u = { .ip4_u = { .daddr = dst, - .saddr = src, - .tos = tos } }, + .fl4_dst = dst, + .fl4_src = src, + .fl4_tos = tos, .proto = protocol, - .uli_u = { .ports = - { .sport = sport, - .dport = dport } } }; - + .fl_ip_sport = sport, + .fl_ip_dport = dport }; int err; struct net *net = sock_net(sk); diff --git a/net/atm/clip.c b/net/atm/clip.c index ff956d1115bc..d257da50fcfb 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -502,7 +502,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) struct atmarp_entry *entry; int error; struct clip_vcc *clip_vcc; - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} }; + struct flowi fl = { .fl4_dst = ip, + .fl4_tos = 1 }; struct rtable *rt; if (vcc->push != clip_push) { diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index ce8b2eed4e73..6e1392093911 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -413,13 +413,8 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) if (dnat_took_place(skb)) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = 0, - .tos = RT_TOS(iph->tos) }, - }, - .proto = 0, + .fl4_dst = iph->daddr, + .fl4_tos = RT_TOS(iph->tos), }; struct in_device *in_dev = __in_dev_get_rcu(dev); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 3f69ea114829..45a434f94169 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -462,15 +462,12 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, { struct rtable *rt; struct flowi fl = { .oif = skb_rtable(skb)->rt_iif, - .nl_u = { .ip4_u = - { .daddr = ip_hdr(skb)->saddr, - .saddr = ip_hdr(skb)->daddr, - .tos = RT_CONN_FLAGS(sk) } }, + .fl4_dst = ip_hdr(skb)->saddr, + .fl4_src = ip_hdr(skb)->daddr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = sk->sk_protocol, - .uli_u = { .ports = - { .sport = dccp_hdr(skb)->dccph_dport, - .dport = dccp_hdr(skb)->dccph_sport } - } + .fl_ip_sport = dccp_hdr(skb)->dccph_dport, + .fl_ip_dport = dccp_hdr(skb)->dccph_sport }; security_skb_classify_flow(skb, &fl); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 474d54dd08c2..8280e43c8861 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -271,10 +271,10 @@ static void dn_dst_link_failure(struct sk_buff *skb) static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | - (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | + return ((fl1->fld_dst ^ fl2->fld_dst) | + (fl1->fld_src ^ fl2->fld_src) | (fl1->mark ^ fl2->mark) | - (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | + (fl1->fld_scope ^ fl2->fld_scope) | (fl1->oif ^ fl2->oif) | (fl1->iif ^ fl2->iif)) == 0; } @@ -882,11 +882,9 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard) { - struct flowi fl = { .nl_u = { .dn_u = - { .daddr = oldflp->fld_dst, - .saddr = oldflp->fld_src, - .scope = RT_SCOPE_UNIVERSE, - } }, + struct flowi fl = { .fld_dst = oldflp->fld_dst, + .fld_src = oldflp->fld_src, + .fld_scope = RT_SCOPE_UNIVERSE, .mark = oldflp->mark, .iif = init_net.loopback_dev->ifindex, .oif = oldflp->oif }; @@ -1230,11 +1228,9 @@ static int dn_route_input_slow(struct sk_buff *skb) int flags = 0; __le16 gateway = 0; __le16 local_src = 0; - struct flowi fl = { .nl_u = { .dn_u = - { .daddr = cb->dst, - .saddr = cb->src, - .scope = RT_SCOPE_UNIVERSE, - } }, + struct flowi fl = { .fld_dst = cb->dst, + .fld_src = cb->src, + .fld_scope = RT_SCOPE_UNIVERSE, .mark = skb->mark, .iif = skb->dev->ifindex }; struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 48fdf10be7a1..6eb91df3c550 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -175,7 +175,7 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, unsigned dnet_addr_type(__le16 addr) { - struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } }; + struct flowi fl = { .fld_dst = addr }; struct dn_fib_res res; unsigned ret = RTN_UNICAST; struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f581f77d1097..f2b61107df6c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1148,21 +1148,13 @@ int inet_sk_rebuild_header(struct sock *sk) struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .nl_u = { - .ip4_u = { - .daddr = daddr, - .saddr = inet->inet_saddr, - .tos = RT_CONN_FLAGS(sk), - }, - }, + .fl4_dst = daddr, + .fl4_src = inet->inet_saddr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .uli_u = { - .ports = { - .sport = inet->inet_sport, - .dport = inet->inet_dport, - }, - }, + .fl_ip_sport = inet->inet_sport, + .fl_ip_dport = inet->inet_dport, }; security_sk_classify_flow(sk, &fl); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index d8e540c5b071..7833f17b648a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -433,8 +433,8 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip, - .saddr = tip } } }; + struct flowi fl = { .fl4_dst = sip, + .fl4_src = tip }; struct rtable *rt; int flag = 0; /*unsigned long now; */ @@ -1061,8 +1061,8 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (r->arp_flags & ATF_PERM) r->arp_flags |= ATF_COM; if (dev == NULL) { - struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } }; + struct flowi fl = { .fl4_dst = ip, + .fl4_tos = RTO_ONLINK }; struct rtable *rt; err = ip_route_output_key(net, &rt, &fl); if (err != 0) @@ -1169,8 +1169,8 @@ static int arp_req_delete(struct net *net, struct arpreq *r, ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; if (dev == NULL) { - struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } }; + struct flowi fl = { .fl4_dst = ip, + .fl4_tos = RTO_ONLINK }; struct rtable *rt; err = ip_route_output_key(net, &rt, &fl); if (err != 0) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index eb6f69a8f27a..d3a1112b9d9c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -158,11 +158,7 @@ static void fib_flush(struct net *net) struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = addr - } - }, + .fl4_dst = addr, .flags = FLOWI_FLAG_MATCH_ANY_IIF }; struct fib_result res = { 0 }; @@ -193,7 +189,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; + struct flowi fl = { .fl4_dst = addr }; struct fib_result res; unsigned ret = RTN_BROADCAST; struct fib_table *local_table; @@ -247,13 +243,9 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, { struct in_device *in_dev; struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = src, - .saddr = dst, - .tos = tos - } - }, + .fl4_dst = src, + .fl4_src = dst, + .fl4_tos = tos, .mark = mark, .iif = oif }; @@ -853,13 +845,9 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) struct fib_result res; struct flowi fl = { .mark = frn->fl_mark, - .nl_u = { - .ip4_u = { - .daddr = frn->fl_addr, - .tos = frn->fl_tos, - .scope = frn->fl_scope - } - } + .fl4_dst = frn->fl_addr, + .fl4_tos = frn->fl_tos, + .fl4_scope = frn->fl_scope, }; #ifdef CONFIG_IP_MULTIPLE_TABLES diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 3e0da3ef6116..12d3dc3df1b7 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -563,12 +563,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, rcu_read_lock(); { struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = nh->nh_gw, - .scope = cfg->fc_scope + 1, - }, - }, + .fl4_dst = nh->nh_gw, + .fl4_scope = cfg->fc_scope + 1, .oif = nh->nh_oif, }; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c6e2affafbd3..4daebd17b6ed 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -386,10 +386,9 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) daddr = icmp_param->replyopts.faddr; } { - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = daddr, - .saddr = rt->rt_spec_dst, - .tos = RT_TOS(ip_hdr(skb)->tos) } }, + struct flowi fl = { .fl4_dst= daddr, + .fl4_src = rt->rt_spec_dst, + .fl4_tos = RT_TOS(ip_hdr(skb)->tos), .proto = IPPROTO_ICMP }; security_skb_classify_flow(skb, &fl); if (ip_route_output_key(net, &rt, &fl)) @@ -542,22 +541,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) { struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = icmp_param.replyopts.srr ? - icmp_param.replyopts.faddr : - iph->saddr, - .saddr = saddr, - .tos = RT_TOS(tos) - } - }, + .fl4_dst = icmp_param.replyopts.srr ? + icmp_param.replyopts.faddr : iph->saddr, + .fl4_src = saddr, + .fl4_tos = RT_TOS(tos), .proto = IPPROTO_ICMP, - .uli_u = { - .icmpt = { - .type = type, - .code = code - } - } + .fl_icmp_type = type, + .fl_icmp_code = code, }; int err; struct rtable *rt2; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a1bf2f49e716..afb1e82a59f9 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -314,8 +314,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) { struct flowi fl = { .oif = dev->ifindex, - .nl_u = { .ip4_u = { - .daddr = IGMPV3_ALL_MCR } }, + .fl4_dst = IGMPV3_ALL_MCR, .proto = IPPROTO_IGMP }; if (ip_route_output_key(net, &rt, &fl)) { kfree_skb(skb); @@ -660,7 +659,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, { struct flowi fl = { .oif = dev->ifindex, - .nl_u = { .ip4_u = { .daddr = dst } }, + .fl4_dst = dst, .proto = IPPROTO_IGMP }; if (ip_route_output_key(net, &rt, &fl)) return -1; @@ -1425,8 +1424,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev) /* RTNL is locked */ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = imr->imr_multiaddr.s_addr } } }; + struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; struct rtable *rt; struct net_device *dev = NULL; struct in_device *idev = NULL; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 7174370b1195..06f5f8f482f0 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -358,17 +358,14 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct ip_options *opt = inet_rsk(req)->opt; struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .nl_u = { .ip4_u = - { .daddr = ((opt && opt->srr) ? - opt->faddr : - ireq->rmt_addr), - .saddr = ireq->loc_addr, - .tos = RT_CONN_FLAGS(sk) } }, + .fl4_dst = ((opt && opt->srr) ? + opt->faddr : ireq->rmt_addr), + .fl4_src = ireq->loc_addr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .uli_u = { .ports = - { .sport = inet_sk(sk)->inet_sport, - .dport = ireq->rmt_port } } }; + .fl_ip_sport = inet_sk(sk)->inet_sport, + .fl_ip_dport = ireq->rmt_port }; struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index aace653710f6..897210adaa77 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -772,14 +772,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev { struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { - .ip4_u = { - .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) - } - }, - .proto = IPPROTO_GRE, + .fl4_dst = dst, + .fl4_src = tiph->saddr, + .fl4_tos = RT_TOS(tos), .fl_gre_key = tunnel->parms.o_key }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { @@ -951,13 +946,9 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) if (iph->daddr) { struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) - } - }, + .fl4_dst = iph->daddr, + .fl4_src = iph->saddr, + .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_GRE, .fl_gre_key = tunnel->parms.o_key }; @@ -1217,13 +1208,9 @@ static int ipgre_open(struct net_device *dev) if (ipv4_is_multicast(t->parms.iph.daddr)) { struct flowi fl = { .oif = t->parms.link, - .nl_u = { - .ip4_u = { - .daddr = t->parms.iph.daddr, - .saddr = t->parms.iph.saddr, - .tos = RT_TOS(t->parms.iph.tos) - } - }, + .fl4_dst = t->parms.iph.daddr, + .fl4_src = t->parms.iph.saddr, + .fl4_tos = RT_TOS(t->parms.iph.tos), .proto = IPPROTO_GRE, .fl_gre_key = t->parms.o_key }; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 439d2a34ee44..5090c7ff525e 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -341,15 +341,13 @@ int ip_queue_xmit(struct sk_buff *skb) { struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .nl_u = { .ip4_u = - { .daddr = daddr, - .saddr = inet->inet_saddr, - .tos = RT_CONN_FLAGS(sk) } }, + .fl4_dst = daddr, + .fl4_src = inet->inet_saddr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .uli_u = { .ports = - { .sport = inet->inet_sport, - .dport = inet->inet_dport } } }; + .fl_ip_sport = inet->inet_sport, + .fl_ip_dport = inet->inet_dport }; /* If this fails, retransmit mechanism of transport layer will * keep trying until route appears or the connection times @@ -1404,14 +1402,11 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar { struct flowi fl = { .oif = arg->bound_dev_if, - .nl_u = { .ip4_u = - { .daddr = daddr, - .saddr = rt->rt_spec_dst, - .tos = RT_TOS(ip_hdr(skb)->tos) } }, - /* Not quite clean, but right. */ - .uli_u = { .ports = - { .sport = tcp_hdr(skb)->dest, - .dport = tcp_hdr(skb)->source } }, + .fl4_dst = daddr, + .fl4_src = rt->rt_spec_dst, + .fl4_tos = RT_TOS(ip_hdr(skb)->tos), + .fl_ip_sport = tcp_hdr(skb)->dest, + .fl_ip_dport = tcp_hdr(skb)->source, .proto = sk->sk_protocol, .flags = ip_reply_arg_flowi_flags(arg) }; security_skb_classify_flow(skb, &fl); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index cd300aaee78f..e70ad581398e 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -463,13 +463,9 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { - .ip4_u = { - .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) - } - }, + .fl4_dst = dst, + .fl4_src= tiph->saddr, + .fl4_tos = RT_TOS(tos), .proto = IPPROTO_IPIP }; @@ -589,13 +585,9 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) if (iph->daddr) { struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) - } - }, + .fl4_dst = iph->daddr, + .fl4_src = iph->saddr, + .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; struct rtable *rt; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index ef2b0089e0ea..3f3a9afd73e0 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1537,13 +1537,9 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, if (vif->flags & VIFF_TUNNEL) { struct flowi fl = { .oif = vif->link, - .nl_u = { - .ip4_u = { - .daddr = vif->remote, - .saddr = vif->local, - .tos = RT_TOS(iph->tos) - } - }, + .fl4_dst = vif->remote, + .fl4_src = vif->local, + .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; @@ -1553,12 +1549,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, } else { struct flowi fl = { .oif = vif->link, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .tos = RT_TOS(iph->tos) - } - }, + .fl4_dst = iph->daddr, + .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index d88a46c54fd1..994a1f29ebbc 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -31,10 +31,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. */ if (addr_type == RTN_LOCAL) { - fl.nl_u.ip4_u.daddr = iph->daddr; + fl.fl4_dst = iph->daddr; if (type == RTN_LOCAL) - fl.nl_u.ip4_u.saddr = iph->saddr; - fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); + fl.fl4_src = iph->saddr; + fl.fl4_tos = RT_TOS(iph->tos); fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl.mark = skb->mark; fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; @@ -47,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) } else { /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ - fl.nl_u.ip4_u.daddr = iph->saddr; + fl.fl4_dst = iph->saddr; if (ip_route_output_key(net, &rt, &fl) != 0) return -1; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 1f85ef289895..a3d5ab786e81 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -549,10 +549,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, { struct flowi fl = { .oif = ipc.oif, .mark = sk->sk_mark, - .nl_u = { .ip4_u = - { .daddr = daddr, - .saddr = saddr, - .tos = tos } }, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, .proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, }; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 66610ea3c87b..ec2333fb637e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -684,17 +684,17 @@ static inline bool rt_caching(const struct net *net) static inline bool compare_hash_inputs(const struct flowi *fl1, const struct flowi *fl2) { - return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | - ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | + return ((((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) | + ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) | (fl1->iif ^ fl2->iif)) == 0); } static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | - ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | + return (((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) | + ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) | (fl1->mark ^ fl2->mark) | - (*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) | + (*(u16 *)&fl1->fl4_tos ^ *(u16 *)&fl2->fl4_tos) | (fl1->oif ^ fl2->oif) | (fl1->iif ^ fl2->iif)) == 0; } @@ -2089,12 +2089,10 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, { struct fib_result res; struct in_device *in_dev = __in_dev_get_rcu(dev); - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = daddr, - .saddr = saddr, - .tos = tos, - .scope = RT_SCOPE_UNIVERSE, - } }, + struct flowi fl = { .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + .fl4_scope = RT_SCOPE_UNIVERSE, .mark = skb->mark, .iif = dev->ifindex }; unsigned flags = 0; @@ -2480,14 +2478,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, const struct flowi *oldflp) { u32 tos = RT_FL_TOS(oldflp); - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = oldflp->fl4_dst, - .saddr = oldflp->fl4_src, - .tos = tos & IPTOS_RT_MASK, - .scope = ((tos & RTO_ONLINK) ? - RT_SCOPE_LINK : - RT_SCOPE_UNIVERSE), - } }, + struct flowi fl = { .fl4_dst = oldflp->fl4_dst, + .fl4_src = oldflp->fl4_src, + .fl4_tos = tos & IPTOS_RT_MASK, + .fl4_scope = ((tos & RTO_ONLINK) ? + RT_SCOPE_LINK : RT_SCOPE_UNIVERSE), .mark = oldflp->mark, .iif = net->loopback_dev->ifindex, .oif = oldflp->oif }; @@ -2944,13 +2939,9 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void err = -rt->dst.error; } else { struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = dst, - .saddr = src, - .tos = rtm->rtm_tos, - }, - }, + .fl4_dst = dst, + .fl4_src = src, + .fl4_tos = rtm->rtm_tos, .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, .mark = mark, }; diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 650cace2180d..47519205a014 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -346,17 +346,14 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, */ { struct flowi fl = { .mark = sk->sk_mark, - .nl_u = { .ip4_u = - { .daddr = ((opt && opt->srr) ? - opt->faddr : - ireq->rmt_addr), - .saddr = ireq->loc_addr, - .tos = RT_CONN_FLAGS(sk) } }, + .fl4_dst = ((opt && opt->srr) ? + opt->faddr : ireq->rmt_addr), + .fl4_src = ireq->loc_addr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = IPPROTO_TCP, .flags = inet_sk_flowi_flags(sk), - .uli_u = { .ports = - { .sport = th->dest, - .dport = th->source } } }; + .fl_ip_sport = th->dest, + .fl_ip_dport = th->source }; security_req_classify_flow(req, &fl); if (ip_route_output_key(sock_net(sk), &rt, &fl)) { reqsk_free(req); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 491ecd3f7a01..b37181da487c 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -890,15 +890,13 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (rt == NULL) { struct flowi fl = { .oif = ipc.oif, .mark = sk->sk_mark, - .nl_u = { .ip4_u = - { .daddr = faddr, - .saddr = saddr, - .tos = tos } }, + .fl4_dst = faddr, + .fl4_src = saddr, + .fl4_tos = tos, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .uli_u = { .ports = - { .sport = inet->inet_sport, - .dport = dport } } }; + .fl_ip_sport = inet->inet_sport, + .fl_ip_dport = dport }; struct net *net = sock_net(sk); security_sk_classify_flow(sk, &fl); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 4a8c5335770c..b057d40addec 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -23,12 +23,8 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, xfrm_address_t *daddr) { struct flowi fl = { - .nl_u = { - .ip4_u = { - .tos = tos, - .daddr = daddr->a4, - }, - }, + .fl4_dst = daddr->a4, + .fl4_tos = tos, }; struct dst_entry *dst; struct rtable *rt; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 6f32ffce7022..9fab274019c0 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1843,9 +1843,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, fl = (struct flowi) { .oif = vif->link, - .nl_u = { .ip6_u = - { .daddr = ipv6h->daddr, } - } + .fl6_dst = ipv6h->daddr, }; dst = ip6_route_output(net, NULL, &fl); diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 7155b2451d7c..35915e8617f0 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -18,10 +18,8 @@ int ip6_route_me_harder(struct sk_buff *skb) struct flowi fl = { .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, .mark = skb->mark, - .nl_u = - { .ip6_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, } }, + .fl6_dst = iph->daddr, + .fl6_src = iph->saddr, }; dst = ip6_route_output(net, skb->sk, &fl); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 96455ffb76fb..c346ccf66ae1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -558,11 +558,7 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, { struct flowi fl = { .oif = oif, - .nl_u = { - .ip6_u = { - .daddr = *daddr, - }, - }, + .fl6_dst = *daddr, }; struct dst_entry *dst; int flags = strict ? RT6_LOOKUP_F_IFACE : 0; @@ -778,13 +774,9 @@ void ip6_route_input(struct sk_buff *skb) int flags = RT6_LOOKUP_F_HAS_SADDR; struct flowi fl = { .iif = skb->dev->ifindex, - .nl_u = { - .ip6_u = { - .daddr = iph->daddr, - .saddr = iph->saddr, - .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, - }, - }, + .fl6_dst = iph->daddr, + .fl6_src = iph->saddr, + .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, .mark = skb->mark, .proto = iph->nexthdr, }; @@ -1463,12 +1455,8 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, struct ip6rd_flowi rdfl = { .fl = { .oif = dev->ifindex, - .nl_u = { - .ip6_u = { - .daddr = *dest, - .saddr = *src, - }, - }, + .fl6_dst = *dest, + .fl6_src = *src, }, }; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d6bfaec3bbbf..6e48a80d0f25 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -730,10 +730,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, } { - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) } }, + struct flowi fl = { .fl4_dst = dst, + .fl4_src = tiph->saddr, + .fl4_tos = RT_TOS(tos), .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { @@ -855,10 +854,9 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) } }, + struct flowi fl = { .fl4_dst = iph->daddr, + .fl4_src = iph->saddr, + .fl4_tos = RT_TOS(iph->tos), .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; struct rtable *rt; diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0bf6a59545ab..04635e88e8ed 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -476,15 +476,13 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m { struct flowi fl = { .oif = sk->sk_bound_dev_if, - .nl_u = { .ip4_u = { - .daddr = daddr, - .saddr = inet->inet_saddr, - .tos = RT_CONN_FLAGS(sk) } }, + .fl4_dst = daddr, + .fl4_src = inet->inet_saddr, + .fl4_tos = RT_CONN_FLAGS(sk), .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .uli_u = { .ports = { - .sport = inet->inet_sport, - .dport = inet->inet_dport } } }; + .fl_ip_sport = inet->inet_sport, + .fl_ip_dport = inet->inet_dport }; /* If this fails, retransmit mechanism of transport layer will * keep trying until route appears or the connection times diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 5f5daa30b0af..c6f293639220 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -110,10 +110,8 @@ static int __ip_vs_addr_is_local_v6(const struct in6_addr *addr) struct rt6_info *rt; struct flowi fl = { .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = *addr, - .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } }, + .fl6_dst = *addr, + .fl6_src = { .s6_addr32 = {0, 0, 0, 0} }, }; rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 10bd39c0ae2d..5325a3fbe4ac 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -96,12 +96,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, if (!(rt = (struct rtable *) __ip_vs_dst_check(dest, rtos))) { struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = dest->addr.ip, - .saddr = 0, - .tos = rtos, } }, + .fl4_dst = dest->addr.ip, + .fl4_tos = rtos, }; if (ip_route_output_key(net, &rt, &fl)) { @@ -118,12 +114,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, spin_unlock(&dest->dst_lock); } else { struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = daddr, - .saddr = 0, - .tos = rtos, } }, + .fl4_dst = daddr, + .fl4_tos = rtos, }; if (ip_route_output_key(net, &rt, &fl)) { @@ -178,14 +170,9 @@ __ip_vs_reroute_locally(struct sk_buff *skb) refdst_drop(orefdst); } else { struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos), - } - }, + .fl4_dst = iph->daddr, + .fl4_src = iph->saddr, + .fl4_tos = RT_TOS(iph->tos), .mark = skb->mark, }; struct rtable *rt; @@ -216,12 +203,7 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, { struct dst_entry *dst; struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = *daddr, - }, - }, + .fl6_dst = *daddr, }; dst = ip6_route_output(net, NULL, &fl); diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index 22a2d421e7eb..5128a6c4cb2c 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -70,9 +70,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) return false; fl.oif = info->priv->oif; } - fl.nl_u.ip4_u.daddr = info->gw.ip; - fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); - fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE; + fl.fl4_dst = info->gw.ip; + fl.fl4_tos = RT_TOS(iph->tos); + fl.fl4_scope = RT_SCOPE_UNIVERSE; if (ip_route_output_key(net, &rt, &fl) != 0) return false; @@ -150,9 +150,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) return false; fl.oif = info->priv->oif; } - fl.nl_u.ip6_u.daddr = info->gw.in6; - fl.nl_u.ip6_u.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | - (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; + fl.fl6_dst = info->gw.in6; + fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | + (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; dst = ip6_route_output(net, NULL, &fl); if (dst == NULL) return false; diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index 9f1729bd60de..a53fb25a64ed 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c @@ -47,12 +47,12 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) case AF_INET: fl.oif = 0; fl.proto = IPPROTO_UDP, - fl.nl_u.ip4_u.saddr = 0; - fl.nl_u.ip4_u.daddr = peer->srx.transport.sin.sin_addr.s_addr; - fl.nl_u.ip4_u.tos = 0; + fl.fl4_dst = peer->srx.transport.sin.sin_addr.s_addr; + fl.fl4_src = 0; + fl.fl4_tos = 0; /* assume AFS.CM talking to AFS.FS */ - fl.uli_u.ports.sport = htons(7001); - fl.uli_u.ports.dport = htons(7000); + fl.fl_ip_sport = htons(7001); + fl.fl_ip_dport = htons(7000); break; default: BUG(); -- cgit v1.2.3-59-g8ed1b From 9ea19481db31d614f729f346bdcf28e4e60ff14a Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 16 Nov 2010 06:31:39 +0000 Subject: net: zero kobject in rx_queue_release netif_set_real_num_rx_queues() can decrement and increment the number of rx queues. For example ixgbe does this as features and offloads are toggled. Presumably this could also happen across down/up on most devices if the available resources changed (cpu offlined). The kobject needs to be zero'd in this case so that the state is not preserved across kobject_put()/kobject_init_and_add(). This resolves the following error report. ixgbe 0000:03:00.0: eth2: NIC Link is Up 10 Gbps, Flow Control: RX/TX kobject (ffff880324b83210): tried to init an initialized object, something is seriously wrong. Pid: 1972, comm: lldpad Not tainted 2.6.37-rc18021qaz+ #169 Call Trace: [] kobject_init+0x3a/0x83 [] kobject_init_and_add+0x23/0x57 [] ? mark_lock+0x21/0x267 [] net_rx_queue_update_kobjects+0x63/0xc6 [] netif_set_real_num_rx_queues+0x5f/0x78 [] ixgbe_set_num_queues+0x1c6/0x1ca [ixgbe] [] ixgbe_init_interrupt_scheme+0x1e/0x79c [ixgbe] [] ixgbe_dcbnl_set_state+0x167/0x189 [ixgbe] Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- net/core/net-sysfs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 3ba526b56fe3..7abeb7ceaa4c 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -711,13 +711,18 @@ static void rx_queue_release(struct kobject *kobj) map = rcu_dereference_raw(queue->rps_map); - if (map) + if (map) { + RCU_INIT_POINTER(queue->rps_map, NULL); call_rcu(&map->rcu, rps_map_release); + } flow_table = rcu_dereference_raw(queue->rps_flow_table); - if (flow_table) + if (flow_table) { + RCU_INIT_POINTER(queue->rps_flow_table, NULL); call_rcu(&flow_table->rcu, rps_dev_flow_table_release); + } + memset(kobj, 0, sizeof(*kobj)); dev_put(queue->dev); } -- cgit v1.2.3-59-g8ed1b From dda0b38692a7298f433b92b1329867b1ecabb4bb Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 14 Nov 2010 07:06:08 +0000 Subject: net: ipv4: tcp_probe: cleanup snprintf() use snprintf() returns number of bytes that were copied if there is no overflow. This code uses return value as number of copied bytes. Theoretically format string '%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n' may be expanded up to 163 bytes. In reality tv.tv_sec is just few bytes instead of 20, 2 ports are just 5 bytes each instead of 10, length is 5 bytes instead of 10. The rest is an unstrusted input. Theoretically if tv_sec is big then copy_to_user() would overflow tbuf. tbuf was increased to fit in 163 bytes. snprintf() is used to follow return value semantic. Signed-off-by: Vasiliy Kulikov Signed-off-by: David S. Miller --- net/ipv4/tcp_probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 6211e2114173..85ee7eb7e38e 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -154,7 +154,7 @@ static int tcpprobe_sprint(char *tbuf, int n) struct timespec tv = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); - return snprintf(tbuf, n, + return scnprintf(tbuf, n, "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n", (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec, @@ -174,7 +174,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf, return -EINVAL; while (cnt < len) { - char tbuf[128]; + char tbuf[164]; int width; /* Wait for data in buffer */ -- cgit v1.2.3-59-g8ed1b From ae4ecb9f8f01eb9deffb5bd837dc90f4e646cd2d Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 13 Nov 2010 19:08:14 +0100 Subject: rt2x00: Increase REGISTER_BUSY_COUNT For some hardware the REGISTER_BUSY_COUNT isn't sufficient, increase the REGISTER_BUSY_COUNT to 100 to catch most devices which have more problems with accessing the registers. For normal operating devices nothing would change as they will exit the loop early anyway. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 42bd3a96f23b..0a55eeff871e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -915,7 +915,7 @@ struct rt2x00_dev { * in those cases REGISTER_BUSY_COUNT attempts should be * taken with a REGISTER_BUSY_DELAY interval. */ -#define REGISTER_BUSY_COUNT 5 +#define REGISTER_BUSY_COUNT 100 #define REGISTER_BUSY_DELAY 100 /* -- cgit v1.2.3-59-g8ed1b From f93bc9b3ce379800b30b3c2f4fc945ae35a80039 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 13 Nov 2010 19:09:50 +0100 Subject: rt2x00: Add initial support for RT3370/RT3390 devices. Modified from Eddy's patch by adding the RT3370 USB support as well. Signed-off-by: Gertjan van Wingerde Cc: Eddy Tsai Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 22 ++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800.h | 1 + drivers/net/wireless/rt2x00/rt2800lib.c | 9 ++++++--- drivers/net/wireless/rt2x00/rt2800pci.c | 3 +++ drivers/net/wireless/rt2x00/rt2800usb.c | 10 +++++++--- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index eea1ef2f502b..f0f01526556d 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -96,6 +96,17 @@ config RT2800PCI_RT30XX Support for these devices is non-functional at the moment and is intended for testers and developers. +config RT2800PCI_RT33XX + bool "rt2800pci - Include support for rt33xx (PCI/PCIe/PCMCIA) devices" + default n + ---help--- + This adds support for rt33xx wireless chipset family to the + rt2800pci driver. + Supported chips: RT3390 + + Support for these devices is non-functional at the moment and is + intended for testers and developers. + config RT2800PCI_RT35XX bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices" default n @@ -165,6 +176,17 @@ config RT2800USB_RT30XX Support for these devices is non-functional at the moment and is intended for testers and developers. +config RT2800USB_RT33XX + bool "rt2800usb - Include support for rt33xx (USB) devices" + default n + ---help--- + This adds support for rt33xx wireless chipset family to the + rt2800usb driver. + Supported chips: RT3370 + + Support for these devices is non-functional at the moment and is + intended for testers and developers. + config RT2800USB_RT35XX bool "rt2800usb - Include support for rt35xx (USB) devices" default n diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 002224c9bb62..a81c4371835b 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -47,6 +47,7 @@ * RF3021 2.4G 1T2R * RF3022 2.4G 2T2R * RF3052 2.4G 2T2R + * RF3320 2.4G 1T1R */ #define RF2820 0x0001 #define RF2850 0x0002 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b5d2ebab6ea8..ce8df66a3de8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1544,7 +1544,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3052)) + rt2x00_rf(rt2x00dev, RF3052) || + rt2x00_rf(rt2x00dev, RF3320)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); @@ -3012,7 +3013,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF2020) && !rt2x00_rf(rt2x00dev, RF3021) && !rt2x00_rf(rt2x00dev, RF3022) && - !rt2x00_rf(rt2x00dev, RF3052)) { + !rt2x00_rf(rt2x00dev, RF3052) && + !rt2x00_rf(rt2x00dev, RF3320)) { ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } @@ -3276,7 +3278,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) } else if (rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022)) { + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3320)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 5f3a018c088d..6642f134aaac 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1051,6 +1051,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif +#ifdef CONFIG_RT2800PCI_RT33XX + { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, +#endif #ifdef CONFIG_RT2800PCI_RT35XX { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 389ecba8e891..61852c5dc6d5 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -839,6 +839,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif +#ifdef CONFIG_RT2800USB_RT33XX + /* Ralink */ + { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Sitecom */ + { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, +#endif #ifdef CONFIG_RT2800USB_RT35XX /* Allwin */ { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -851,12 +858,9 @@ static struct usb_device_id rt2800usb_device_table[] = { /* I-O DATA */ { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ - { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zinwell */ { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif -- cgit v1.2.3-59-g8ed1b From 46af584d2ea86518c4cdf521903cd93ba6de2ec0 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 13 Nov 2010 19:10:10 +0100 Subject: rt2x00: Clean up Kconfig for RT2800 devices. General clean up of the Kconfig part for RT28XX devices. Also remove the indications of non functional support for rt27xx/rt28xx/rt30xx devices, as this is no longer true. They just work fine. Finally, remove the experimental indications for rt27xx/rt28xx/rt30xx devices as that is no longer true. Keep the experimental indications for rt33xx/rt35xx devices, though. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 47 +++++++++++++++---------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index f0f01526556d..f2be1d35a5c8 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -64,8 +64,8 @@ config RT2800PCI_SOC default y config RT2800PCI - tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)" - depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL + tristate "Ralink rt27xx/rt28xx (PCI/PCIe/PCMCIA) support" + depends on RT2800PCI_PCI || RT2800PCI_SOC select RT2800_LIB select RT2X00_LIB_PCI if RT2800PCI_PCI select RT2X00_LIB_SOC if RT2800PCI_SOC @@ -75,29 +75,24 @@ config RT2800PCI select CRC_CCITT select EEPROM_93CX6 ---help--- - This adds support for rt2800/rt3000/rt3500 wireless chipset family. + This adds support for rt27xx/rt28xx wireless chipset family. Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052 - This driver is non-functional at the moment and is intended for - developers. - When compiled as a module, this driver will be called "rt2800pci.ko". if RT2800PCI config RT2800PCI_RT30XX - bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" + bool "rt2800pci - Include support for rt30xx devices" default y ---help--- This adds support for rt30xx wireless chipset family to the rt2800pci driver. Supported chips: RT3090, RT3091 & RT3092 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - config RT2800PCI_RT33XX - bool "rt2800pci - Include support for rt33xx (PCI/PCIe/PCMCIA) devices" + bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt33xx wireless chipset family to the @@ -108,7 +103,8 @@ config RT2800PCI_RT33XX intended for testers and developers. config RT2800PCI_RT35XX - bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices" + bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt35xx wireless chipset family to the @@ -145,8 +141,8 @@ config RT73USB When compiled as a module, this driver will be called rt73usb. config RT2800USB - tristate "Ralink rt2800 (USB) support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "Ralink rt27xx/rt28xx (USB) support" + depends on USB select RT2800_LIB select RT2X00_LIB_USB select RT2X00_LIB_HT @@ -154,30 +150,24 @@ config RT2800USB select RT2X00_LIB_CRYPTO select CRC_CCITT ---help--- - This adds experimental support for rt2800 wireless chipset family. + This adds support for rt27xx/rt28xx wireless chipset family. Supported chips: RT2770, RT2870 & RT3070. - Known issues: - - support for RT2870 chips doesn't work with 802.11n APs yet - - support for RT3070 chips is non-functional at the moment - When compiled as a module, this driver will be called "rt2800usb.ko". if RT2800USB config RT2800USB_RT30XX - bool "rt2800usb - Include support for rt30xx (USB) devices" + bool "rt2800usb - Include support for rt30xx devices" default y ---help--- This adds support for rt30xx wireless chipset family to the rt2800usb driver. Supported chips: RT3070, RT3071 & RT3072 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - config RT2800USB_RT33XX - bool "rt2800usb - Include support for rt33xx (USB) devices" + bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt33xx wireless chipset family to the @@ -188,7 +178,8 @@ config RT2800USB_RT33XX intended for testers and developers. config RT2800USB_RT35XX - bool "rt2800usb - Include support for rt35xx (USB) devices" + bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt35xx wireless chipset family to the @@ -202,9 +193,9 @@ config RT2800USB_UNKNOWN bool "rt2800usb - Include support for unknown (USB) devices" default n ---help--- - This adds support for rt2800 family devices that are known to - have a rt2800 family chipset, but for which the exact chipset - is unknown. + This adds support for rt2800usb devices that are known to + have a rt28xx family compatible chipset, but for which the exact + chipset is unknown. Support status for these devices is unknown, and enabling these devices may or may not work. -- cgit v1.2.3-59-g8ed1b From a6a8d66ebaea1e78d779af221bd6f01c5cbe71f5 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 13 Nov 2010 19:10:31 +0100 Subject: rt2x00: Remove RT30XX Kconfig variables. Enabling of RT30xx devices via Kconfig variables was introduced when these devices weren't properly supported yet. Now that that they are properly supported and functional, we can remove these Kconfig variables for RT30xx devices and simply enable them whenever rt2800pci and/or rt2800usb is enabled. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 29 ++---- drivers/net/wireless/rt2x00/rt2800pci.c | 10 +- drivers/net/wireless/rt2x00/rt2800usb.c | 167 ++++++++++++++------------------ 3 files changed, 85 insertions(+), 121 deletions(-) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index f2be1d35a5c8..a6939ccd68cc 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -64,7 +64,7 @@ config RT2800PCI_SOC default y config RT2800PCI - tristate "Ralink rt27xx/rt28xx (PCI/PCIe/PCMCIA) support" + tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" depends on RT2800PCI_PCI || RT2800PCI_SOC select RT2800_LIB select RT2X00_LIB_PCI if RT2800PCI_PCI @@ -75,21 +75,14 @@ config RT2800PCI select CRC_CCITT select EEPROM_93CX6 ---help--- - This adds support for rt27xx/rt28xx wireless chipset family. - Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052 + This adds support for rt27xx/rt28xx/rt30xx wireless chipset family. + Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052, + RT3090, RT3091 & RT3092 When compiled as a module, this driver will be called "rt2800pci.ko". if RT2800PCI -config RT2800PCI_RT30XX - bool "rt2800pci - Include support for rt30xx devices" - default y - ---help--- - This adds support for rt30xx wireless chipset family to the - rt2800pci driver. - Supported chips: RT3090, RT3091 & RT3092 - config RT2800PCI_RT33XX bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -141,7 +134,7 @@ config RT73USB When compiled as a module, this driver will be called rt73usb. config RT2800USB - tristate "Ralink rt27xx/rt28xx (USB) support" + tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support" depends on USB select RT2800_LIB select RT2X00_LIB_USB @@ -150,21 +143,13 @@ config RT2800USB select RT2X00_LIB_CRYPTO select CRC_CCITT ---help--- - This adds support for rt27xx/rt28xx wireless chipset family. - Supported chips: RT2770, RT2870 & RT3070. + This adds support for rt27xx/rt28xx/rt30xx wireless chipset family. + Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072 When compiled as a module, this driver will be called "rt2800usb.ko". if RT2800USB -config RT2800USB_RT30XX - bool "rt2800usb - Include support for rt30xx devices" - default y - ---help--- - This adds support for rt30xx wireless chipset family to the - rt2800usb driver. - Supported chips: RT3070, RT3071 & RT3072 - config RT2800USB_RT33XX bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 6642f134aaac..97f4df62ee63 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1037,6 +1037,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) }, @@ -1044,13 +1047,8 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, -#ifdef CONFIG_RT2800PCI_RT30XX - { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, -#endif + { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, #ifdef CONFIG_RT2800PCI_RT33XX { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 61852c5dc6d5..2933bf1d74bb 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -641,11 +641,19 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Abocom */ { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* AirTies */ + { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Allwin */ { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amit */ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Askey */ @@ -654,8 +662,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, /* AzureWave */ { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Belkin */ { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -666,6 +679,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -674,113 +688,27 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Edimax */ - { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* EnGenius */ - { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Gigabyte */ - { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Hawking */ - { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Linksys */ - { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Logitec */ - { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Motorola */ - { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* MSI */ - { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Philips */ - { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Planex */ - { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Ralink */ - { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Samsung */ - { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Siemens */ - { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* SMC */ - { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Sparklan */ - { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Sweex */ - { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* U-Media*/ - { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* ZCOM */ - { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Zinwell */ - { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Zyxel */ - { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, -#ifdef CONFIG_RT2800USB_RT30XX - /* Abocom */ - { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* AirTies */ - { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Allwin */ - { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* ASUS */ - { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* AzureWave */ - { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Corega */ { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, /* D-Link */ + { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Encore */ { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, /* EnGenius */ + { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -788,19 +716,37 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Gigabyte */ + { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Hawking */ + { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) }, /* I-O DATA */ { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Linksys */ + { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Logitec */ + { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Motorola */ + { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, /* MSI */ { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -815,30 +761,65 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Pegatron */ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Philips */ + { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Quanta */ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Samsung */ + { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Siemens */ + { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ + { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, /* SMC */ + { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Sparklan */ + { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Sweex */ + { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* U-Media*/ + { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* ZCOM */ + { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zinwell */ + { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, -#endif + /* Zyxel */ + { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, -- cgit v1.2.3-59-g8ed1b From 72c7296e03e381b49958809915105b18b09fa7a3 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 13 Nov 2010 19:10:54 +0100 Subject: rt2x00: Remove unneccessary internal Kconfig symbols. CONFIG_RT2800PCI_PCI and CONFIG_RT2800PCI_SOC are strictly not needed as we can check the dependent symbols directly in the rest of Kconfig and the code, so clean up the Kconfig namespace a bit. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 16 +++------------- drivers/net/wireless/rt2x00/rt2800pci.c | 34 ++++++++++++++++----------------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index a6939ccd68cc..ade30251608e 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -53,22 +53,12 @@ config RT61PCI When compiled as a module, this driver will be called rt61pci. -config RT2800PCI_PCI - boolean - depends on PCI - default y - -config RT2800PCI_SOC - boolean - depends on RALINK_RT288X || RALINK_RT305X - default y - config RT2800PCI tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" - depends on RT2800PCI_PCI || RT2800PCI_SOC + depends on PCI || RALINK_RT288X || RALINK_RT305X select RT2800_LIB - select RT2X00_LIB_PCI if RT2800PCI_PCI - select RT2X00_LIB_SOC if RT2800PCI_SOC + select RT2X00_LIB_PCI if PCI + select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X select RT2X00_LIB_HT select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 97f4df62ee63..b0946f8f3457 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -84,7 +84,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */ @@ -95,9 +95,9 @@ static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { } -#endif /* CONFIG_RT2800PCI_SOC */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) { struct rt2x00_dev *rt2x00dev = eeprom->data; @@ -181,7 +181,7 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { } -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ /* * Firmware functions @@ -1031,7 +1031,7 @@ static const struct rt2x00_ops rt2800pci_ops = { /* * RT2800pci module information. */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, @@ -1061,19 +1061,19 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif { 0, } }; -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ MODULE_AUTHOR(DRV_PROJECT); MODULE_VERSION(DRV_VERSION); MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards"); -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI MODULE_FIRMWARE(FIRMWARE_RT2860); MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ MODULE_LICENSE("GPL"); -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static int rt2800soc_probe(struct platform_device *pdev) { return rt2x00soc_probe(pdev, &rt2800pci_ops); @@ -1090,9 +1090,9 @@ static struct platform_driver rt2800soc_driver = { .suspend = rt2x00soc_suspend, .resume = rt2x00soc_resume, }; -#endif /* CONFIG_RT2800PCI_SOC */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static struct pci_driver rt2800pci_driver = { .name = KBUILD_MODNAME, .id_table = rt2800pci_device_table, @@ -1101,21 +1101,21 @@ static struct pci_driver rt2800pci_driver = { .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, }; -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ static int __init rt2800pci_init(void) { int ret = 0; -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) ret = platform_driver_register(&rt2800soc_driver); if (ret) return ret; #endif -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI ret = pci_register_driver(&rt2800pci_driver); if (ret) { -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif return ret; @@ -1127,10 +1127,10 @@ static int __init rt2800pci_init(void) static void __exit rt2800pci_exit(void) { -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI pci_unregister_driver(&rt2800pci_driver); #endif -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif } -- cgit v1.2.3-59-g8ed1b From ef8397cfb3a385bc57a32213d0e4a5b7903a9dc6 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 13 Nov 2010 19:11:22 +0100 Subject: rt2x00: Use ioremap for SoC devices instead of KSEG1ADDR. Make the code a bit more portable to architectures that do not support KSEG1ADDR. Signed-off-by: Gertjan van Wingerde Tested-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 4 +++- drivers/net/wireless/rt2x00/rt2x00soc.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b0946f8f3457..433c7f3ef837 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -87,9 +87,11 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { - u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */ + void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); + + iounmap(base_addr); } #else static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index fc98063de71d..2aa5c38022f3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c @@ -40,6 +40,8 @@ static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev) kfree(rt2x00dev->eeprom); rt2x00dev->eeprom = NULL; + + iounmap(rt2x00dev->csr.base); } static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev) @@ -51,9 +53,9 @@ static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev) if (!res) return -ENODEV; - rt2x00dev->csr.base = (void __iomem *)KSEG1ADDR(res->start); + rt2x00dev->csr.base = ioremap(res->start, resource_size(res)); if (!rt2x00dev->csr.base) - goto exit; + return -ENOMEM; rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); if (!rt2x00dev->eeprom) -- cgit v1.2.3-59-g8ed1b From b43d63bd69ae5464a52bf1796e84097607917b2f Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sat, 13 Nov 2010 19:11:46 +0100 Subject: rt2x00: Fix rt2800 USB TX Path DMA issue rt2800usb chips need to add 1~3 bytes zero padding after each 802.11 header & payload, and at the end need to add 4 bytes zero padding whether doing TX bulk aggregation or not, TXINFO_W0_USB_DMA_TX_PKT_LEN in TXINFO must include 1-3 bytes padding after 802.11 header & payload but do not include 4 bytes end zero padding. In rt2800usb_get_tx_data_len do not consider multiple of the USB packet size case, sometimes this will cause USB DMA problem. Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 39 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2933bf1d74bb..935b76d3ce4f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -307,8 +307,14 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, * Initialize TXINFO descriptor */ rt2x00_desc_read(txi, 0, &word); + + /* + * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is + * TXWI + 802.11 header + L2 pad + payload + pad, + * so need to decrease size of TXINFO and USB end pad. + */ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - entry->skb->len - TXINFO_DESC_SIZE); + entry->skb->len - TXINFO_DESC_SIZE - 4); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); @@ -326,22 +332,29 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; } -/* - * TX data initialization - */ -static int rt2800usb_get_tx_data_len(struct queue_entry *entry) +static void rt2800usb_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc) { - int length; + u8 padding_len; /* - * The length _must_ include 4 bytes padding, - * it should always be multiple of 4, - * but it must _not_ be a multiple of the USB packet size. + * pad(1~3 bytes) is added after each 802.11 payload. + * USB end pad(4 bytes) is added at each USB bulk out packet end. + * TX frame format is : + * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | + * |<------------- tx_pkt_len ------------->| */ - length = roundup(entry->skb->len + 4, 4); - length += (4 * !(length % entry->queue->usb_maxpacket)); + rt2800_write_tx_data(entry, txdesc); + padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len; + memset(skb_put(entry->skb, padding_len), 0, padding_len); +} - return length; +/* + * TX data initialization + */ +static int rt2800usb_get_tx_data_len(struct queue_entry *entry) +{ + return entry->skb->len; } /* @@ -579,7 +592,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .watchdog = rt2800usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2800_write_tx_data, + .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, -- cgit v1.2.3-59-g8ed1b From f8eaec659f8a7a4e0086fca7c5d5c5e0fbc76d1a Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sat, 13 Nov 2010 19:12:54 +0100 Subject: rt2x00: Fix header_length in rt2x00lib_txdone Put the assignment of header_length after pull out extra tx headroom Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 3afa2a3ebee4..c879f9a7037c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -250,10 +250,9 @@ void rt2x00lib_txdone(struct queue_entry *entry, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); - unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + unsigned int header_length, i; u8 rate_idx, rate_flags, retry_rates; u8 skbdesc_flags = skbdesc->flags; - unsigned int i; bool success; /* @@ -271,6 +270,11 @@ void rt2x00lib_txdone(struct queue_entry *entry, */ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; + /* + * Determine the length of 802.11 header. + */ + header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + /* * Remove L2 padding which was added during */ -- cgit v1.2.3-59-g8ed1b From 387e68846413f3dcfc5a5afca9841430057e3340 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sat, 13 Nov 2010 19:13:53 +0100 Subject: rt2x00: Modify rt2x00queue_remove_l2pad to make skb->data two-byte alignment When send out skb data to mac80211, orignal code will cause mac80211 unaligned access, so modify code to make mac80211 can natural access. Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index dc543174dfad..a3d79c7a21c6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -204,8 +204,10 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) if (!l2pad) return; - memmove(skb->data + l2pad, skb->data, header_length); - skb_pull(skb, l2pad); + memmove(skb->data + header_length, skb->data + header_length + l2pad, + skb->len - header_length - l2pad); + + skb_trim(skb, skb->len - l2pad); } static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, -- cgit v1.2.3-59-g8ed1b From c5d0855acfa4d6801c4c45bc02ddddd959262050 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 13 Nov 2010 20:22:41 +0100 Subject: ath9k_hw: set default values for radar pulse detection Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 15 +++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_phy.c | 15 +++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 2 ++ 3 files changed, 32 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 3686811cc8df..7303d98e4100 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1610,6 +1610,20 @@ static void ar5008_hw_set_radar_params(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); } +static void ar5008_hw_set_radar_conf(struct ath_hw *ah) +{ + struct ath_hw_radar_conf *conf = &ah->radar_conf; + + conf->fir_power = -33; + conf->radar_rssi = 20; + conf->pulse_height = 10; + conf->pulse_rssi = 24; + conf->pulse_inband = 15; + conf->pulse_maxlen = 255; + conf->pulse_inband_step = 12; + conf->radar_inband = 8; +} + void ar5008_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1656,5 +1670,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; ar5008_hw_set_nf_limits(ah); + ar5008_hw_set_radar_conf(ah); memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index f676b21ac437..e8d6455b5948 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1144,6 +1144,20 @@ static void ar9003_hw_set_radar_params(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); } +static void ar9003_hw_set_radar_conf(struct ath_hw *ah) +{ + struct ath_hw_radar_conf *conf = &ah->radar_conf; + + conf->fir_power = -28; + conf->radar_rssi = 0; + conf->pulse_height = 10; + conf->pulse_rssi = 24; + conf->pulse_inband = 8; + conf->pulse_maxlen = 255; + conf->pulse_inband_step = 12; + conf->radar_inband = 8; +} + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1175,6 +1189,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->set_radar_params = ar9003_hw_set_radar_params; ar9003_hw_set_nf_limits(ah); + ar9003_hw_set_radar_conf(ah); memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c20a5421f870..d5e68347ef72 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -782,6 +782,8 @@ struct ath_hw { u8 txchainmask; u8 rxchainmask; + struct ath_hw_radar_conf radar_conf; + u32 originalGain[22]; int initPDADC; int PDADCdelta; -- cgit v1.2.3-59-g8ed1b From 9a6b82706317333a1fab5dcafa2c33b91253a7a2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 00:03:01 +0100 Subject: ath9k: fix PA predistortion training frame setup Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 8ba0e2d86c1f..dc648a5798bc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1656,9 +1656,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, bf->bf_buf_addr, txctl->txq->axq_qnum); - if (bf->bf_state.bfs_paprd) - ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); - spin_lock_bh(&txctl->txq->axq_lock); if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && @@ -1684,6 +1681,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, bf->bf_state.bfs_ftype = txctl->frame_type; bf->bf_state.bfs_paprd = txctl->paprd; + if (bf->bf_state.bfs_paprd) + ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); + if (txctl->paprd) bf->bf_state.bfs_paprd_timestamp = jiffies; -- cgit v1.2.3-59-g8ed1b From 2d3bcba0827013dfc60f727e7370dea00bc0638a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:01 +0100 Subject: ath9k: remove bfs_seqno from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 44 +++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3e6ebe698852..3b5257795420 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -105,7 +105,6 @@ enum buffer_type { #define bf_al bf_state.bfs_al #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries -#define bf_seqno bf_state.bfs_seqno #define bf_tidno bf_state.bfs_tidno #define bf_keyix bf_state.bfs_keyix #define bf_keytype bf_state.bfs_keytype @@ -221,7 +220,6 @@ struct ath_buf_state { int bfs_nframes; u16 bfs_al; u16 bfs_frmlen; - int bfs_seqno; int bfs_tidno; int bfs_retries; u8 bf_type; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index dc648a5798bc..e84c9c282cdc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -140,6 +140,12 @@ unlock: spin_unlock_bh(&txq->axq_lock); } +static u16 ath_frame_seqno(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + return le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT; +} + static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { struct ath_txq *txq = tid->ac->txq; @@ -157,7 +163,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) list_move_tail(&bf->list, &bf_head); if (bf_isretried(bf)) { - ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_update_baw(sc, tid, ath_frame_seqno(bf->bf_mpdu)); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } else { ath_tx_send_normal(sc, txq, tid, &bf_head); @@ -184,14 +190,11 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, } static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, - struct ath_buf *bf) + u16 seqno) { int index, cindex; - if (bf_isretried(bf)) - return; - - index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); + index = ATH_BA_INDEX(tid->seq_start, seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); __set_bit(cindex, tid->tx_buf); @@ -215,6 +218,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf; struct list_head bf_head; struct ath_tx_status ts; + u16 bf_seqno; memset(&ts, 0, sizeof(ts)); INIT_LIST_HEAD(&bf_head); @@ -226,8 +230,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, bf = list_first_entry(&tid->buf_q, struct ath_buf, list); list_move_tail(&bf->list, &bf_head); + bf_seqno = ath_frame_seqno(bf->bf_mpdu); if (bf_isretried(bf)) - ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_update_baw(sc, tid, bf_seqno); spin_unlock(&txq->axq_lock); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); @@ -316,6 +321,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; struct ieee80211_tx_rate rates[4]; + u16 bf_seqno; int nframes; skb = bf->bf_mpdu; @@ -392,8 +398,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); + bf_seqno = ath_frame_seqno(skb); - if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { + if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf_seqno))) { /* transmit completion, subframe is * acked by block ack */ acked_cnt++; @@ -442,7 +449,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, * block-ack window */ spin_lock_bh(&txq->axq_lock); - ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_update_baw(sc, tid, bf_seqno); spin_unlock_bh(&txq->axq_lock); if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { @@ -471,7 +478,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (!tbf) { spin_lock_bh(&txq->axq_lock); ath_tx_update_baw(sc, tid, - bf->bf_seqno); + bf_seqno); spin_unlock_bh(&txq->axq_lock); bf->bf_state.bf_type |= @@ -674,14 +681,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, al_delta, h_baw = tid->baw_size / 2; enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; struct ieee80211_tx_info *tx_info; + u16 bf_seqno; bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); do { bf = list_first_entry(&tid->buf_q, struct ath_buf, list); + bf_seqno = ath_frame_seqno(bf->bf_mpdu); /* do not step over block-ack window */ - if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) { + if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno)) { status = ATH_AGGR_BAW_CLOSED; break; } @@ -726,7 +735,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); /* link buffers of this frame to the aggregate */ - ath_tx_addto_baw(sc, tid, bf); + if (!bf_isretried(bf)) + ath_tx_addto_baw(sc, tid, bf_seqno); ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); list_move_tail(&bf->list, bf_q); if (bf_prev) { @@ -1288,10 +1298,12 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, struct ath_tx_control *txctl) { struct ath_buf *bf; + u16 bf_seqno; bf = list_first_entry(bf_head, struct ath_buf, list); bf->bf_state.bf_type |= BUF_AMPDU; TX_STAT_INC(txctl->txq->axq_qnum, a_queued); + bf_seqno = ath_frame_seqno(bf->bf_mpdu); /* * Do not queue to h/w when any of the following conditions is true: @@ -1301,7 +1313,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, * - h/w queue depth exceeds low water mark */ if (!list_empty(&tid->buf_q) || tid->paused || - !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) || + !BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno) || txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { /* * Add this frame to software queue for scheduling later @@ -1313,7 +1325,8 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, } /* Add sub-frame to BAW */ - ath_tx_addto_baw(sc, tid, bf); + if (!bf_isretried(bf)) + ath_tx_addto_baw(sc, tid, bf_seqno); /* Queue to h/w without aggregation */ bf->bf_nframes = 1; @@ -1394,7 +1407,6 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, */ tid = ATH_AN_2_TID(an, bf->bf_tidno); hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); - bf->bf_seqno = tid->seq_next; INCR(tid->seq_next, IEEE80211_SEQ_MAX); } @@ -1903,7 +1915,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, } while (bf) { - ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno); + ba_index = ATH_BA_INDEX(seq_st, ath_frame_seqno(bf->bf_mpdu)); if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) nbad++; -- cgit v1.2.3-59-g8ed1b From 5daefbd061d9509644058b6886abe2b6672ee386 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:02 +0100 Subject: ath9k: remove bfs_tidno from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3b5257795420..905d3c4d798a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -105,7 +105,6 @@ enum buffer_type { #define bf_al bf_state.bfs_al #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries -#define bf_tidno bf_state.bfs_tidno #define bf_keyix bf_state.bfs_keyix #define bf_keytype bf_state.bfs_keytype #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) @@ -220,7 +219,6 @@ struct ath_buf_state { int bfs_nframes; u16 bfs_al; u16 bfs_frmlen; - int bfs_tidno; int bfs_retries; u8 bf_type; u8 bfs_paprd; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e84c9c282cdc..c7097a5e33da 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -323,6 +323,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ieee80211_tx_rate rates[4]; u16 bf_seqno; int nframes; + u8 tidno; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -358,14 +359,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, } an = (struct ath_node *)sta->drv_priv; - tid = ATH_AN_2_TID(an, bf->bf_tidno); + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(an, tidno); /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted */ - if (bf->bf_tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1386,7 +1388,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, struct ath_node *an; struct ath_atx_tid *tid; __le16 fc; - u8 *qc; + u8 tidno; if (!tx_info->control.sta) return; @@ -1394,18 +1396,13 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, an = (struct ath_node *)tx_info->control.sta->drv_priv; hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; - - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); - bf->bf_tidno = qc[0] & 0xf; - } + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; /* - * For HT capable stations, we save tidno for later use. - * We also override seqno set by upper layer with the one + * Override seqno set by upper layer with the one * in tx aggregation state. */ - tid = ATH_AN_2_TID(an, bf->bf_tidno); + tid = ATH_AN_2_TID(an, tidno); hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); INCR(tid->seq_next, IEEE80211_SEQ_MAX); } @@ -1647,6 +1644,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct ath_hw *ah = sc->sc_ah; int frm_type; __le16 fc; + u8 tidno; frm_type = get_hw_packet_type(skb); fc = hdr->frame_control; @@ -1673,7 +1671,10 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && tx_info->control.sta) { an = (struct ath_node *)tx_info->control.sta->drv_priv; - tid = ATH_AN_2_TID(an, bf->bf_tidno); + tidno = ieee80211_get_qos_ctl(hdr)[0] & + IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(an, tidno); + WARN_ON(tid->ac->txq != txctl->txq); if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { -- cgit v1.2.3-59-g8ed1b From 952cd693718d8ac796d5323fe7876241cf15ecfa Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:03 +0100 Subject: ath9k: remove bfs_keytype from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 9 +++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 905d3c4d798a..bd988ea88bd1 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -106,7 +106,6 @@ enum buffer_type { #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries #define bf_keyix bf_state.bfs_keyix -#define bf_keytype bf_state.bfs_keytype #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) @@ -224,7 +223,6 @@ struct ath_buf_state { u8 bfs_paprd; unsigned long bfs_paprd_timestamp; u32 bfs_keyix; - enum ath9k_key_type bfs_keytype; enum ath9k_internal_frame_type bfs_ftype; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c7097a5e33da..6e0467cf0812 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -630,7 +630,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, * TODO - this could be improved to be dependent on the rate. * The hardware can keep up at lower rates, but not higher rates */ - if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) + if (tx_info->control.hw_key) ndelim += ATH_AGGR_ENCRYPTDELIM; /* @@ -1604,8 +1604,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, bf->bf_flags = setup_tx_flags(skb); - bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); - if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { + if (tx_info->control.hw_key) { bf->bf_frmlen += tx_info->control.hw_key->icv_len; bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; } else { @@ -1642,6 +1641,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct ath_desc *ds; struct ath_atx_tid *tid; struct ath_hw *ah = sc->sc_ah; + enum ath9k_key_type keytype; int frm_type; __le16 fc; u8 tidno; @@ -1655,8 +1655,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, ds = bf->bf_desc; ath9k_hw_set_desc_link(ah, ds, 0); + keytype = ath9k_cmn_get_hw_crypto_keytype(skb); ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, - bf->bf_keyix, bf->bf_keytype, bf->bf_flags); + bf->bf_keyix, keytype, bf->bf_flags); ath9k_hw_filltxdesc(ah, ds, skb->len, /* segment length */ -- cgit v1.2.3-59-g8ed1b From 82259b77f6e55c5b81f5f4a2852f6216c196ef30 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:04 +0100 Subject: ath9k: remove bfs_paprd_timestamp from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 2 ++ drivers/net/wireless/ath/ath9k/xmit.c | 7 +------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bd988ea88bd1..826b665de9c2 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -221,7 +221,6 @@ struct ath_buf_state { int bfs_retries; u8 bf_type; u8 bfs_paprd; - unsigned long bfs_paprd_timestamp; u32 bfs_keyix; enum ath9k_internal_frame_type bfs_ftype; }; @@ -598,6 +597,7 @@ struct ath_softc { struct work_struct paprd_work; struct work_struct hw_check_work; struct completion paprd_complete; + bool paprd_pending; u32 intrstatus; u32 sc_flags; /* SC_OP_* */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index df7c62d9bec4..cfec2ad664d8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -375,6 +375,7 @@ void ath_paprd_calibrate(struct work_struct *work) } init_completion(&sc->paprd_complete); + sc->paprd_pending = true; ar9003_paprd_setup_gain_table(ah, chain); txctl.paprd = BIT(chain); if (ath_tx_start(hw, skb, &txctl) != 0) @@ -382,6 +383,7 @@ void ath_paprd_calibrate(struct work_struct *work) time_left = wait_for_completion_timeout(&sc->paprd_complete, msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); + sc->paprd_pending = false; if (!time_left) { ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, "Timeout waiting for paprd training on " diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6e0467cf0812..9f3d23a4e580 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1698,9 +1698,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, if (bf->bf_state.bfs_paprd) ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; - ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); } @@ -1874,9 +1871,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, bf->bf_buf_addr = 0; if (bf->bf_state.bfs_paprd) { - if (time_after(jiffies, - bf->bf_state.bfs_paprd_timestamp + - msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) + if (!sc->paprd_pending) dev_kfree_skb_any(skb); else complete(&sc->paprd_complete); -- cgit v1.2.3-59-g8ed1b From 3017047f564d5101009c8318b94bdacd3ca3312e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:05 +0100 Subject: ath9k: remove bfs_keyix from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 14 ++++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 826b665de9c2..e78f7f9bc3c7 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -105,7 +105,6 @@ enum buffer_type { #define bf_al bf_state.bfs_al #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries -#define bf_keyix bf_state.bfs_keyix #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) @@ -221,7 +220,6 @@ struct ath_buf_state { int bfs_retries; u8 bf_type; u8 bfs_paprd; - u32 bfs_keyix; enum ath9k_internal_frame_type bfs_ftype; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9f3d23a4e580..176d88c154c6 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1604,12 +1604,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, bf->bf_flags = setup_tx_flags(skb); - if (tx_info->control.hw_key) { + if (tx_info->control.hw_key) bf->bf_frmlen += tx_info->control.hw_key->icv_len; - bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; - } else { - bf->bf_keyix = ATH9K_TXKEYIX_INVALID; - } bf->bf_mpdu = skb; @@ -1642,6 +1638,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct ath_atx_tid *tid; struct ath_hw *ah = sc->sc_ah; enum ath9k_key_type keytype; + u32 keyix; int frm_type; __le16 fc; u8 tidno; @@ -1656,8 +1653,13 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, ath9k_hw_set_desc_link(ah, ds, 0); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); + if (tx_info->control.hw_key) + keyix = tx_info->control.hw_key->hw_key_idx; + else + keyix = ATH9K_TXKEYIX_INVALID; + ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, - bf->bf_keyix, keytype, bf->bf_flags); + keyix, keytype, bf->bf_flags); ath9k_hw_filltxdesc(ah, ds, skb->len, /* segment length */ -- cgit v1.2.3-59-g8ed1b From 269c44bc8415ad78fb4dc3de25e6de3420332e9f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:06 +0100 Subject: ath9k: remove bfs_al from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 +--- drivers/net/wireless/ath/ath9k/xmit.c | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e78f7f9bc3c7..b70ac3a6db21 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -102,7 +102,6 @@ enum buffer_type { }; #define bf_nframes bf_state.bfs_nframes -#define bf_al bf_state.bfs_al #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) @@ -215,11 +214,10 @@ struct ath_atx_ac { struct ath_buf_state { int bfs_nframes; - u16 bfs_al; - u16 bfs_frmlen; int bfs_retries; u8 bf_type; u8 bfs_paprd; + u16 bfs_frmlen; enum ath9k_internal_frame_type bfs_ftype; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 176d88c154c6..88efcc1671b1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -56,7 +56,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok, int sendbar); static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, struct list_head *head); -static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); +static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok); static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, @@ -674,7 +674,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct list_head *bf_q) + struct list_head *bf_q, + int *aggr_len) { #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) struct ath_buf *bf, *bf_first, *bf_prev = NULL; @@ -750,7 +751,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } while (!list_empty(&tid->buf_q)); - bf_first->bf_al = al; + *aggr_len = al; bf_first->bf_nframes = nframes; return status; @@ -763,6 +764,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf; enum ATH_AGGR_STATUS status; struct list_head bf_q; + int aggr_len; do { if (list_empty(&tid->buf_q)) @@ -770,7 +772,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, INIT_LIST_HEAD(&bf_q); - status = ath_tx_form_aggr(sc, txq, tid, &bf_q); + status = ath_tx_form_aggr(sc, txq, tid, &bf_q, &aggr_len); /* * no frames picked up to be aggregated; @@ -786,15 +788,15 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, if (bf->bf_nframes == 1) { bf->bf_state.bf_type &= ~BUF_AGGR; ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); - ath_buf_set_rate(sc, bf); + ath_buf_set_rate(sc, bf, bf->bf_frmlen); ath_tx_txqaddbuf(sc, txq, &bf_q); continue; } /* setup first desc of aggregate */ bf->bf_state.bf_type |= BUF_AGGR; - ath_buf_set_rate(sc, bf); - ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); + ath_buf_set_rate(sc, bf, aggr_len); + ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len); /* anchor last desc of aggregate */ ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); @@ -1333,7 +1335,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, /* Queue to h/w without aggregation */ bf->bf_nframes = 1; bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf); + ath_buf_set_rate(sc, bf, bf->bf_frmlen); ath_tx_txqaddbuf(sc, txctl->txq, bf_head); } @@ -1352,7 +1354,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, bf->bf_nframes = 1; bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf); + ath_buf_set_rate(sc, bf, bf->bf_frmlen); ath_tx_txqaddbuf(sc, txq, bf_head); TX_STAT_INC(txq->axq_qnum, queued); } @@ -1430,13 +1432,11 @@ static int setup_tx_flags(struct sk_buff *skb) * width - 0 for 20 MHz, 1 for 40 MHz * half_gi - to use 4us v/s 3.6 us for symbol time */ -static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, +static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, int width, int half_gi, bool shortPreamble) { u32 nbits, nsymbits, duration, nsymbols; - int streams, pktlen; - - pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; + int streams; /* find number of symbols: PLCP + data */ streams = HT_RC_2_STREAMS(rix); @@ -1455,7 +1455,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, return duration; } -static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) +static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_11n_rate_series series[4]; @@ -1518,7 +1518,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) if (rates[i].flags & IEEE80211_TX_RC_MCS) { /* MCS rates */ series[i].Rate = rix | 0x80; - series[i].PktDuration = ath_pkt_duration(sc, rix, bf, + series[i].PktDuration = ath_pkt_duration(sc, rix, len, is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) series[i].RateFlags |= ATH9K_RATESERIES_STBC; @@ -1542,11 +1542,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) } series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, - phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); + phy, rate->bitrate * 100, len, rix, is_sp); } /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ - if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) + if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) flags &= ~ATH9K_TXDESC_RTSENA; /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ -- cgit v1.2.3-59-g8ed1b From b572d0335fcb26e526f6ae087a9a09371b22e739 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:07 +0100 Subject: ath9k: remove bfs_nframes from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 - drivers/net/wireless/ath/ath9k/xmit.c | 97 ++++++++++++++++------------------ 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b70ac3a6db21..b1c45b8e49c8 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -101,7 +101,6 @@ enum buffer_type { BUF_XRETRY = BIT(5), }; -#define bf_nframes bf_state.bfs_nframes #define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) @@ -213,7 +212,6 @@ struct ath_atx_ac { }; struct ath_buf_state { - int bfs_nframes; int bfs_retries; u8 bf_type; u8 bfs_paprd; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 88efcc1671b1..87b79ef9dbef 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -57,10 +57,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, struct list_head *head); static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); -static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, int txok); static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, - int nbad, int txok, bool update_rc); + int nframes, int nbad, int txok, bool update_rc); static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, int seqno); @@ -303,6 +301,39 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) return tbf; } +static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_status *ts, int txok, + int *nframes, int *nbad) +{ + u16 seq_st = 0; + u32 ba[WME_BA_BMP_SIZE >> 5]; + int ba_index; + int isaggr = 0; + + *nbad = 0; + *nframes = 0; + + if (bf->bf_lastbf->bf_tx_aborted) + return; + + isaggr = bf_isaggr(bf); + if (isaggr) { + seq_st = ts->ts_seqnum; + memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); + } + + while (bf) { + ba_index = ATH_BA_INDEX(seq_st, ath_frame_seqno(bf->bf_mpdu)); + + (*nframes)++; + if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) + (*nbad)++; + + bf = bf->bf_next; + } +} + + static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct list_head *bf_q, struct ath_tx_status *ts, int txok) @@ -332,7 +363,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, hw = bf->aphy->hw; memcpy(rates, tx_info->control.rates, sizeof(rates)); - nframes = bf->bf_nframes; rcu_read_lock(); @@ -349,7 +379,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - ath_tx_rc_status(bf, ts, 1, 0, false); + ath_tx_rc_status(bf, ts, 1, 1, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -393,7 +423,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, INIT_LIST_HEAD(&bf_pending); INIT_LIST_HEAD(&bf_head); - nbad = ath_tx_num_badfrms(sc, bf, ts, txok); + ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); while (bf) { txfail = txpending = 0; bf_next = bf->bf_next; @@ -456,11 +486,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { memcpy(tx_info->control.rates, rates, sizeof(rates)); - bf->bf_nframes = nframes; - ath_tx_rc_status(bf, ts, nbad, txok, true); + ath_tx_rc_status(bf, ts, nframes, nbad, txok, true); rc_update = false; } else { - ath_tx_rc_status(bf, ts, nbad, txok, false); + ath_tx_rc_status(bf, ts, nframes, nbad, txok, false); } ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, @@ -485,8 +514,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, ts, nbad, - 0, false); + ath_tx_rc_status(bf, ts, nframes, + nbad, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -752,7 +781,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } while (!list_empty(&tid->buf_q)); *aggr_len = al; - bf_first->bf_nframes = nframes; return status; #undef PADBYTES @@ -785,7 +813,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); /* if only one frame, send as non-aggregate */ - if (bf->bf_nframes == 1) { + if (bf == bf->bf_lastbf) { bf->bf_state.bf_type &= ~BUF_AGGR; ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); ath_buf_set_rate(sc, bf, bf->bf_frmlen); @@ -1333,7 +1361,6 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ath_tx_addto_baw(sc, tid, bf_seqno); /* Queue to h/w without aggregation */ - bf->bf_nframes = 1; bf->bf_lastbf = bf; ath_buf_set_rate(sc, bf, bf->bf_frmlen); ath_tx_txqaddbuf(sc, txctl->txq, bf_head); @@ -1352,7 +1379,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, if (tid) INCR(tid->seq_start, IEEE80211_SEQ_MAX); - bf->bf_nframes = 1; bf->bf_lastbf = bf; ath_buf_set_rate(sc, bf, bf->bf_frmlen); ath_tx_txqaddbuf(sc, txq, bf_head); @@ -1895,37 +1921,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, spin_unlock_irqrestore(&sc->tx.txbuflock, flags); } -static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, int txok) -{ - u16 seq_st = 0; - u32 ba[WME_BA_BMP_SIZE >> 5]; - int ba_index; - int nbad = 0; - int isaggr = 0; - - if (bf->bf_lastbf->bf_tx_aborted) - return 0; - - isaggr = bf_isaggr(bf); - if (isaggr) { - seq_st = ts->ts_seqnum; - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); - } - - while (bf) { - ba_index = ATH_BA_INDEX(seq_st, ath_frame_seqno(bf->bf_mpdu)); - if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) - nbad++; - - bf = bf->bf_next; - } - - return nbad; -} - static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, - int nbad, int txok, bool update_rc) + int nframes, int nbad, int txok, bool update_rc) { struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -1946,10 +1943,10 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; - BUG_ON(nbad > bf->bf_nframes); + BUG_ON(nbad > nframes); - tx_info->status.ampdu_len = bf->bf_nframes; - tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; + tx_info->status.ampdu_len = nframes; + tx_info->status.ampdu_ack_len = nframes - nbad; } if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && @@ -2078,7 +2075,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) */ if (ts.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); + ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); } qnum = skb_get_queue_mapping(bf->bf_mpdu); @@ -2200,7 +2197,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) if (!bf_isampdu(bf)) { if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); + ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); } qnum = skb_get_queue_mapping(bf->bf_mpdu); -- cgit v1.2.3-59-g8ed1b From 76e4522177de81ac89ade01a394aeb3704a66f1b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:08 +0100 Subject: ath9k: remove bfs_frmlen from struct ath_buf_state Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 63 ++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b1c45b8e49c8..84518dc0925f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -101,7 +101,6 @@ enum buffer_type { BUF_XRETRY = BIT(5), }; -#define bf_frmlen bf_state.bfs_frmlen #define bf_retries bf_state.bfs_retries #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) @@ -215,7 +214,6 @@ struct ath_buf_state { int bfs_retries; u8 bf_type; u8 bfs_paprd; - u16 bfs_frmlen; enum ath9k_internal_frame_type bfs_ftype; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 87b79ef9dbef..527151e44f10 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -50,7 +50,7 @@ static u16 bits_per_symbol[][2] = { static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct list_head *bf_head); + struct list_head *bf_head, int frmlen); static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_txq *txq, struct list_head *bf_q, struct ath_tx_status *ts, int txok, int sendbar); @@ -144,6 +144,26 @@ static u16 ath_frame_seqno(struct sk_buff *skb) return le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT; } +static int ath_frame_len(struct sk_buff *skb) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + int frmlen = skb->len + FCS_LEN; + int padpos, padsize; + + /* Remove the padding size, if any */ + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + + if (padsize && skb->len > padpos + padsize) + frmlen -= padsize; + + if (tx_info->control.hw_key) + frmlen += tx_info->control.hw_key->icv_len; + + return frmlen; +} + static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { struct ath_txq *txq = tid->ac->txq; @@ -164,7 +184,8 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ath_tx_update_baw(sc, tid, ath_frame_seqno(bf->bf_mpdu)); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } else { - ath_tx_send_normal(sc, txq, tid, &bf_head); + ath_tx_send_normal(sc, txq, tid, &bf_head, + ath_frame_len(bf->bf_mpdu)); } } @@ -713,6 +734,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, al_delta, h_baw = tid->baw_size / 2; enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; struct ieee80211_tx_info *tx_info; + int frmlen; u16 bf_seqno; bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); @@ -733,7 +755,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } /* do not exceed aggregation limit */ - al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen; + frmlen = ath_frame_len(bf->bf_mpdu); + al_delta = ATH_AGGR_DELIM_SZ + frmlen; if (nframes && (aggr_limit < (al + bpad + al_delta + prev_al))) { @@ -760,7 +783,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, * Get the delimiters needed to meet the MPDU * density for this node. */ - ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); + ndelim = ath_compute_num_delims(sc, tid, bf_first, frmlen); bpad = PADBYTES(al_delta) + (ndelim << 2); bf->bf_next = NULL; @@ -816,7 +839,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, if (bf == bf->bf_lastbf) { bf->bf_state.bf_type &= ~BUF_AGGR; ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); - ath_buf_set_rate(sc, bf, bf->bf_frmlen); + ath_buf_set_rate(sc, bf, ath_frame_len(bf->bf_mpdu)); ath_tx_txqaddbuf(sc, txq, &bf_q); continue; } @@ -1327,7 +1350,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, struct list_head *bf_head, - struct ath_tx_control *txctl) + struct ath_tx_control *txctl, int frmlen) { struct ath_buf *bf; u16 bf_seqno; @@ -1362,13 +1385,13 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, /* Queue to h/w without aggregation */ bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, bf->bf_frmlen); + ath_buf_set_rate(sc, bf, frmlen); ath_tx_txqaddbuf(sc, txctl->txq, bf_head); } static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct list_head *bf_head) + struct list_head *bf_head, int frmlen) { struct ath_buf *bf; @@ -1380,7 +1403,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, INCR(tid->seq_start, IEEE80211_SEQ_MAX); bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, bf->bf_frmlen); + ath_buf_set_rate(sc, bf, frmlen); ath_tx_txqaddbuf(sc, txq, bf_head); TX_STAT_INC(txq->axq_qnum, queued); } @@ -1595,12 +1618,10 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_buf *bf; int hdrlen; __le16 fc; - int padpos, padsize; bf = ath_tx_get_buffer(sc); if (!bf) { @@ -1614,13 +1635,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, ATH_TXBUF_RESET(bf); bf->aphy = aphy; - bf->bf_frmlen = skb->len + FCS_LEN; - /* Remove the padding size from bf_frmlen, if any */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len>padpos+padsize) { - bf->bf_frmlen -= padsize; - } if (ieee80211_is_data_qos(fc) && conf_is_ht(&hw->conf)) { bf->bf_state.bf_type |= BUF_HT; @@ -1630,9 +1644,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, bf->bf_flags = setup_tx_flags(skb); - if (tx_info->control.hw_key) - bf->bf_frmlen += tx_info->control.hw_key->icv_len; - bf->bf_mpdu = skb; bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, @@ -1668,6 +1679,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, int frm_type; __le16 fc; u8 tidno; + int frmlen; frm_type = get_hw_packet_type(skb); fc = hdr->frame_control; @@ -1684,7 +1696,8 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, else keyix = ATH9K_TXKEYIX_INVALID; - ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, + frmlen = ath_frame_len(bf->bf_mpdu); + ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER, keyix, keytype, bf->bf_flags); ath9k_hw_filltxdesc(ah, ds, @@ -1711,13 +1724,13 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, * Try aggregation if it's a unicast data frame * and the destination is HT capable. */ - ath_tx_send_ampdu(sc, tid, &bf_head, txctl); + ath_tx_send_ampdu(sc, tid, &bf_head, txctl, frmlen); } else { /* * Send this frame as regular when ADDBA * exchange is neither complete nor pending. */ - ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); + ath_tx_send_normal(sc, txctl->txq, tid, &bf_head, frmlen); } } else { bf->bf_state.bfs_ftype = txctl->frame_type; @@ -1726,7 +1739,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, if (bf->bf_state.bfs_paprd) ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); - ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); + ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, frmlen); } spin_unlock_bh(&txctl->txq->axq_lock); -- cgit v1.2.3-59-g8ed1b From c5992618259598ade82c386aa1595bf105e92d1f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:09 +0100 Subject: ath9k: remove bf_tx_aborted from struct ath_buf Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/xmit.c | 23 +++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 84518dc0925f..3fecd03cfb23 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -227,7 +227,6 @@ struct ath_buf { dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ bool bf_stale; - bool bf_tx_aborted; u16 bf_flags; struct ath_buf_state bf_state; struct ath_wiphy *aphy; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 527151e44f10..c35033f1a5e0 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -334,9 +334,6 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, *nbad = 0; *nframes = 0; - if (bf->bf_lastbf->bf_tx_aborted) - return; - isaggr = bf_isaggr(bf); if (isaggr) { seq_st = ts->ts_seqnum; @@ -357,7 +354,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct list_head *bf_q, - struct ath_tx_status *ts, int txok) + struct ath_tx_status *ts, int txok, bool retry) { struct ath_node *an = NULL; struct sk_buff *skb; @@ -461,8 +458,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, /* transmit completion */ acked_cnt++; } else { - if (!(tid->state & AGGR_CLEANUP) && - !bf_last->bf_tx_aborted) { + if (!(tid->state & AGGR_CLEANUP) && retry) { if (bf->bf_retries < ATH_MAX_SW_RETRIES) { ath_tx_set_retry(sc, txq, bf); txpending = 1; @@ -1132,8 +1128,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) } lastbf = bf->bf_lastbf; - if (!retry_tx) - lastbf->bf_tx_aborted = true; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { list_cut_position(&bf_head, @@ -1150,7 +1144,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) spin_unlock_bh(&txq->axq_lock); if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0); + ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, + retry_tx); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } @@ -1171,7 +1166,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, - &ts, 0); + &ts, 0, retry_tx); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); @@ -1657,8 +1652,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, return NULL; } - bf->bf_tx_aborted = false; - return bf; } @@ -2094,7 +2087,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) qnum = skb_get_queue_mapping(bf->bf_mpdu); if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); + ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, + true); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); @@ -2216,7 +2210,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) qnum = skb_get_queue_mapping(bf->bf_mpdu); if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); + ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, + txok, true); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &txs, txok, 0); -- cgit v1.2.3-59-g8ed1b From 28d167086227969fd6586953ee4ac682a3c394ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:10 +0100 Subject: ath9k: clean up code duplication around ath_tx_start Merge initial processing for the CAB queue and regular tx. Also move ath_tx_cabq() to beacon.c and make it static. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/beacon.c | 19 ++++++++++ drivers/net/wireless/ath/ath9k/main.c | 25 ------------ drivers/net/wireless/ath/ath9k/xmit.c | 67 ++++++++++----------------------- 4 files changed, 39 insertions(+), 73 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3fecd03cfb23..711100793081 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -323,7 +323,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath_tx_control *txctl); void ath_tx_tasklet(struct ath_softc *sc); void ath_tx_edma_tasklet(struct ath_softc *sc); -void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 2377376c8d4d..30724a4e8bb2 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -109,6 +109,25 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, series, 4, 0); } +static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_tx_control txctl; + + memset(&txctl, 0, sizeof(struct ath_tx_control)); + txctl.txq = sc->beacon.cabq; + + ath_print(common, ATH_DBG_XMIT, + "transmitting CABQ packet, skb: %p\n", skb); + + if (ath_tx_start(hw, skb, &txctl) != 0) { + ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n"); + dev_kfree_skb_any(skb); + } +} + static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cfec2ad664d8..6e93a53c5e32 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1187,12 +1187,10 @@ mutex_unlock: static int ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; - int padpos, padsize; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { @@ -1243,29 +1241,6 @@ static int ath9k_tx(struct ieee80211_hw *hw, } memset(&txctl, 0, sizeof(struct ath_tx_control)); - - /* - * As a temporary workaround, assign seq# here; this will likely need - * to be cleaned up to work better with Beacon transmission and virtual - * BSSes. - */ - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) - sc->tx.seq_no += 0x10; - hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); - } - - /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len>padpos) { - if (skb_headroom(skb) < padsize) - return -1; - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); - } - txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c35033f1a5e0..f3f0d1c6ad0a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1742,41 +1742,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath_tx_control *txctl) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_txq *txq = txctl->txq; struct ath_buf *bf; - int q; - - bf = ath_tx_setup_buffer(hw, skb); - if (unlikely(!bf)) - return -ENOMEM; - - q = skb_get_queue_mapping(skb); - spin_lock_bh(&txq->axq_lock); - if (txq == sc->tx.txq_map[q] && - ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { - ath_mac80211_stop_queue(sc, q); - txq->stopped = 1; - } - spin_unlock_bh(&txq->axq_lock); - - ath_tx_start_dma(sc, bf, txctl); - - return 0; -} - -void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; int padpos, padsize; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ath_tx_control txctl; - - memset(&txctl, 0, sizeof(struct ath_tx_control)); + int q; /* * As a temporary workaround, assign seq# here; this will likely need @@ -1793,30 +1766,30 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) /* Add the padding after the header if this is not already done */ padpos = ath9k_cmn_padpos(hdr->frame_control); padsize = padpos & 3; - if (padsize && skb->len>padpos) { - if (skb_headroom(skb) < padsize) { - ath_print(common, ATH_DBG_XMIT, - "TX CABQ padding failed\n"); - dev_kfree_skb_any(skb); - return; - } + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) + return -ENOMEM; + skb_push(skb, padsize); memmove(skb->data, skb->data + padsize, padpos); } - txctl.txq = sc->beacon.cabq; - - ath_print(common, ATH_DBG_XMIT, - "transmitting CABQ packet, skb: %p\n", skb); + bf = ath_tx_setup_buffer(hw, skb); + if (unlikely(!bf)) + return -ENOMEM; - if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n"); - goto exit; + q = skb_get_queue_mapping(skb); + spin_lock_bh(&txq->axq_lock); + if (txq == sc->tx.txq_map[q] && + ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { + ath_mac80211_stop_queue(sc, q); + txq->stopped = 1; } + spin_unlock_bh(&txq->axq_lock); - return; -exit: - dev_kfree_skb_any(skb); + ath_tx_start_dma(sc, bf, txctl); + + return 0; } /*****************/ -- cgit v1.2.3-59-g8ed1b From 71a3bf3e94b745467fc4c3451a294910f0369555 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:11 +0100 Subject: ath9k: block new AMPDU sessions if SC_OP_TXAGGR is not set This makes further tx path cleanups easier Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6e93a53c5e32..dede9a9aa689 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1979,6 +1979,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: + if (!(sc->sc_flags & SC_OP_TXAGGR)) + return -EOPNOTSUPP; + ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) -- cgit v1.2.3-59-g8ed1b From 04caf863750bc7e042d1e8d57e5ce9d6326ab435 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:12 +0100 Subject: ath9k: more tx setup cleanups - remove the BUF_HT flag, and instead check for IEEE80211_TX_CTL_AMPDU before calling ath_tx_send_ampdu. - remove a few unused variables - calculate frame length before adding the frame padding - merge the misnamed ath_tx_start_dma function into ath_tx_start - remove an unused argument for assign_aggr_tid_seqno Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 +- drivers/net/wireless/ath/ath9k/xmit.c | 129 +++++++++++++++------------------ 2 files changed, 59 insertions(+), 74 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 711100793081..d12123a6576b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -86,7 +86,6 @@ struct ath_config { /** * enum buffer_type - Buffer type flags * - * @BUF_HT: Send this buffer using HT capabilities * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) * @BUF_AGGR: Indicates whether the buffer can be aggregated * (used in aggregation scheduling) @@ -94,7 +93,6 @@ struct ath_config { * @BUF_XRETRY: To denote excessive retries of the buffer */ enum buffer_type { - BUF_HT = BIT(1), BUF_AMPDU = BIT(2), BUF_AGGR = BIT(3), BUF_RETRY = BIT(4), @@ -102,7 +100,6 @@ enum buffer_type { }; #define bf_retries bf_state.bfs_retries -#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) @@ -265,6 +262,7 @@ struct ath_tx_control { struct ath_txq *txq; int if_id; enum ath9k_internal_frame_type frame_type; + int frmlen; u8 paprd; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f3f0d1c6ad0a..5eeffaea551e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1344,13 +1344,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, } static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, - struct list_head *bf_head, - struct ath_tx_control *txctl, int frmlen) + struct ath_buf *bf, struct ath_tx_control *txctl) { - struct ath_buf *bf; + struct list_head bf_head; u16 bf_seqno; - bf = list_first_entry(bf_head, struct ath_buf, list); bf->bf_state.bf_type |= BUF_AMPDU; TX_STAT_INC(txctl->txq->axq_qnum, a_queued); bf_seqno = ath_frame_seqno(bf->bf_mpdu); @@ -1369,19 +1367,22 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, * Add this frame to software queue for scheduling later * for aggregation. */ - list_move_tail(&bf->list, &tid->buf_q); + list_add_tail(&bf->list, &tid->buf_q); ath_tx_queue_tid(txctl->txq, tid); return; } + INIT_LIST_HEAD(&bf_head); + list_add(&bf->list, &bf_head); + /* Add sub-frame to BAW */ if (!bf_isretried(bf)) ath_tx_addto_baw(sc, tid, bf_seqno); /* Queue to h/w without aggregation */ bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, frmlen); - ath_tx_txqaddbuf(sc, txctl->txq, bf_head); + ath_buf_set_rate(sc, bf, txctl->frmlen); + ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); } static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, @@ -1426,8 +1427,7 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static void assign_aggr_tid_seqno(struct sk_buff *skb, - struct ath_buf *bf) +static void assign_aggr_tid_seqno(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; @@ -1608,15 +1608,20 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) } static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, - struct sk_buff *skb) + struct ath_txq *txq, + struct sk_buff *skb, int frmlen) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb; struct ath_buf *bf; - int hdrlen; - __le16 fc; + struct ath_desc *ds; + enum ath9k_key_type keytype; + u32 keyix; + int frm_type; bf = ath_tx_get_buffer(sc); if (!bf) { @@ -1624,21 +1629,14 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, return NULL; } - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - fc = hdr->frame_control; - ATH_TXBUF_RESET(bf); - bf->aphy = aphy; - - if (ieee80211_is_data_qos(fc) && conf_is_ht(&hw->conf)) { - bf->bf_state.bf_type |= BUF_HT; - if (sc->sc_flags & SC_OP_TXAGGR) - assign_aggr_tid_seqno(skb, bf); - } + if (ieee80211_is_data_qos(hdr->frame_control) && + conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) + assign_aggr_tid_seqno(skb); + bf->aphy = aphy; bf->bf_flags = setup_tx_flags(skb); - bf->bf_mpdu = skb; bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, @@ -1652,33 +1650,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, return NULL; } - return bf; -} - -/* FIXME: tx power */ -static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_control *txctl) -{ - struct sk_buff *skb = bf->bf_mpdu; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ath_node *an = NULL; - struct list_head bf_head; - struct ath_desc *ds; - struct ath_atx_tid *tid; - struct ath_hw *ah = sc->sc_ah; - enum ath9k_key_type keytype; - u32 keyix; - int frm_type; - __le16 fc; - u8 tidno; - int frmlen; - frm_type = get_hw_packet_type(skb); - fc = hdr->frame_control; - - INIT_LIST_HEAD(&bf_head); - list_add_tail(&bf->list, &bf_head); ds = bf->bf_desc; ath9k_hw_set_desc_link(ah, ds, 0); @@ -1689,7 +1661,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, else keyix = ATH9K_TXKEYIX_INVALID; - frmlen = ath_frame_len(bf->bf_mpdu); ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER, keyix, keytype, bf->bf_flags); @@ -1699,40 +1670,50 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, true, /* last segment */ ds, /* first descriptor */ bf->bf_buf_addr, - txctl->txq->axq_qnum); + txq->axq_qnum); + + + return bf; +} + +/* FIXME: tx power */ +static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_control *txctl) +{ + struct sk_buff *skb = bf->bf_mpdu; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ath_node *an = NULL; + struct list_head bf_head; + struct ath_atx_tid *tid; + u8 tidno; spin_lock_bh(&txctl->txq->axq_lock); - if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && - tx_info->control.sta) { + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tx_info->control.sta) { an = (struct ath_node *)tx_info->control.sta->drv_priv; tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); - WARN_ON(tid->ac->txq != txctl->txq); - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - /* - * Try aggregation if it's a unicast data frame - * and the destination is HT capable. - */ - ath_tx_send_ampdu(sc, tid, &bf_head, txctl, frmlen); - } else { - /* - * Send this frame as regular when ADDBA - * exchange is neither complete nor pending. - */ - ath_tx_send_normal(sc, txctl->txq, tid, &bf_head, frmlen); - } + /* + * Try aggregation if it's a unicast data frame + * and the destination is HT capable. + */ + ath_tx_send_ampdu(sc, tid, bf, txctl); } else { + INIT_LIST_HEAD(&bf_head); + list_add_tail(&bf->list, &bf_head); + bf->bf_state.bfs_ftype = txctl->frame_type; bf->bf_state.bfs_paprd = txctl->paprd; if (bf->bf_state.bfs_paprd) - ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); + ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, + bf->bf_state.bfs_paprd); - ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, frmlen); + ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, txctl->frmlen); } spin_unlock_bh(&txctl->txq->axq_lock); @@ -1749,8 +1730,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath_txq *txq = txctl->txq; struct ath_buf *bf; int padpos, padsize; + int frmlen = skb->len + FCS_LEN; int q; + if (info->control.hw_key) + frmlen += info->control.hw_key->icv_len; + + txctl->frmlen = frmlen; + /* * As a temporary workaround, assign seq# here; this will likely need * to be cleaned up to work better with Beacon transmission and virtual @@ -1774,7 +1761,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, memmove(skb->data, skb->data + padsize, padpos); } - bf = ath_tx_setup_buffer(hw, skb); + bf = ath_tx_setup_buffer(hw, txctl->txq, skb, frmlen); if (unlikely(!bf)) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 2d42efc44e38d3a8b2bf30e34559036bb6541672 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 14 Nov 2010 15:20:13 +0100 Subject: ath9k: store frame information used by aggregation inside the skb tx info Since the pointers after the rates in the tx info cannot be used anymore after frames have been queued, this area can be used to store information that was previously stored in the ath_buf. With these changes, we can delay the ath_buf assignment in the aggregation code until aggregates are formed. That will not only make it possible to simplify DMA descriptor setup to do less rewriting of uncached memory, but will also make it easier to move aggregation out of the core of the ath9k tx path. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 15 ++- drivers/net/wireless/ath/ath9k/xmit.c | 203 ++++++++++++++++----------------- 2 files changed, 109 insertions(+), 109 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d12123a6576b..be9c8d3b3337 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -89,20 +89,16 @@ struct ath_config { * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) * @BUF_AGGR: Indicates whether the buffer can be aggregated * (used in aggregation scheduling) - * @BUF_RETRY: Indicates whether the buffer is retried * @BUF_XRETRY: To denote excessive retries of the buffer */ enum buffer_type { BUF_AMPDU = BIT(2), BUF_AGGR = BIT(3), - BUF_RETRY = BIT(4), BUF_XRETRY = BIT(5), }; -#define bf_retries bf_state.bfs_retries #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) -#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) #define ATH_TXSTATUS_RING_SIZE 64 @@ -207,8 +203,15 @@ struct ath_atx_ac { struct list_head tid_q; }; +struct ath_frame_info { + int framelen; + u32 keyix; + enum ath9k_key_type keytype; + u8 retries; + u16 seqno; +}; + struct ath_buf_state { - int bfs_retries; u8 bf_type; u8 bfs_paprd; enum ath9k_internal_frame_type bfs_ftype; @@ -260,9 +263,9 @@ struct ath_node { struct ath_tx_control { struct ath_txq *txq; + struct ath_node *an; int if_id; enum ath9k_internal_frame_type frame_type; - int frmlen; u8 paprd; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5eeffaea551e..c63e283ff97f 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -50,7 +50,7 @@ static u16 bits_per_symbol[][2] = { static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct list_head *bf_head, int frmlen); + struct list_head *bf_head); static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_txq *txq, struct list_head *bf_q, struct ath_tx_status *ts, int txok, int sendbar); @@ -138,30 +138,12 @@ unlock: spin_unlock_bh(&txq->axq_lock); } -static u16 ath_frame_seqno(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - return le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT; -} - -static int ath_frame_len(struct sk_buff *skb) +static struct ath_frame_info *get_frame_info(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - int frmlen = skb->len + FCS_LEN; - int padpos, padsize; - - /* Remove the padding size, if any */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - - if (padsize && skb->len > padpos + padsize) - frmlen -= padsize; - - if (tx_info->control.hw_key) - frmlen += tx_info->control.hw_key->icv_len; - - return frmlen; + BUILD_BUG_ON(sizeof(struct ath_frame_info) > + sizeof(tx_info->rate_driver_data)); + return (struct ath_frame_info *) &tx_info->rate_driver_data[0]; } static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) @@ -170,6 +152,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) struct ath_buf *bf; struct list_head bf_head; struct ath_tx_status ts; + struct ath_frame_info *fi; INIT_LIST_HEAD(&bf_head); @@ -180,12 +163,12 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) bf = list_first_entry(&tid->buf_q, struct ath_buf, list); list_move_tail(&bf->list, &bf_head); - if (bf_isretried(bf)) { - ath_tx_update_baw(sc, tid, ath_frame_seqno(bf->bf_mpdu)); + fi = get_frame_info(bf->bf_mpdu); + if (fi->retries) { + ath_tx_update_baw(sc, tid, fi->seqno); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } else { - ath_tx_send_normal(sc, txq, tid, &bf_head, - ath_frame_len(bf->bf_mpdu)); + ath_tx_send_normal(sc, txq, tid, &bf_head); } } @@ -237,7 +220,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf; struct list_head bf_head; struct ath_tx_status ts; - u16 bf_seqno; + struct ath_frame_info *fi; memset(&ts, 0, sizeof(ts)); INIT_LIST_HEAD(&bf_head); @@ -249,9 +232,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, bf = list_first_entry(&tid->buf_q, struct ath_buf, list); list_move_tail(&bf->list, &bf_head); - bf_seqno = ath_frame_seqno(bf->bf_mpdu); - if (bf_isretried(bf)) - ath_tx_update_baw(sc, tid, bf_seqno); + fi = get_frame_info(bf->bf_mpdu); + if (fi->retries) + ath_tx_update_baw(sc, tid, fi->seqno); spin_unlock(&txq->axq_lock); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); @@ -263,16 +246,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, } static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, - struct ath_buf *bf) + struct sk_buff *skb) { - struct sk_buff *skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; - bf->bf_state.bf_type |= BUF_RETRY; - bf->bf_retries++; TX_STAT_INC(txq->axq_qnum, a_retries); + if (tx_info->control.rates[4].count++ > 0) + return; - skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); } @@ -326,6 +308,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok, int *nframes, int *nbad) { + struct ath_frame_info *fi; u16 seq_st = 0; u32 ba[WME_BA_BMP_SIZE >> 5]; int ba_index; @@ -341,7 +324,8 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, } while (bf) { - ba_index = ATH_BA_INDEX(seq_st, ath_frame_seqno(bf->bf_mpdu)); + fi = get_frame_info(bf->bf_mpdu); + ba_index = ATH_BA_INDEX(seq_st, fi->seqno); (*nframes)++; if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) @@ -370,7 +354,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; struct ieee80211_tx_rate rates[4]; - u16 bf_seqno; + struct ath_frame_info *fi; int nframes; u8 tidno; @@ -448,9 +432,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); - bf_seqno = ath_frame_seqno(skb); + fi = get_frame_info(skb); - if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf_seqno))) { + if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) { /* transmit completion, subframe is * acked by block ack */ acked_cnt++; @@ -459,8 +443,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, acked_cnt++; } else { if (!(tid->state & AGGR_CLEANUP) && retry) { - if (bf->bf_retries < ATH_MAX_SW_RETRIES) { - ath_tx_set_retry(sc, txq, bf); + if (fi->retries < ATH_MAX_SW_RETRIES) { + ath_tx_set_retry(sc, txq, bf->bf_mpdu); txpending = 1; } else { bf->bf_state.bf_type |= BUF_XRETRY; @@ -498,7 +482,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, * block-ack window */ spin_lock_bh(&txq->axq_lock); - ath_tx_update_baw(sc, tid, bf_seqno); + ath_tx_update_baw(sc, tid, fi->seqno); spin_unlock_bh(&txq->axq_lock); if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { @@ -525,8 +509,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, */ if (!tbf) { spin_lock_bh(&txq->axq_lock); - ath_tx_update_baw(sc, tid, - bf_seqno); + ath_tx_update_baw(sc, tid, fi->seqno); spin_unlock_bh(&txq->axq_lock); bf->bf_state.bf_type |= @@ -666,6 +649,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, u16 minlen; u8 flags, rix; int width, streams, half_gi, ndelim, mindelim; + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); /* Select standard number of delimiters based on frame length alone */ ndelim = ATH_AGGR_GET_NDELIM(frmlen); @@ -676,7 +660,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, * TODO - this could be improved to be dependent on the rate. * The hardware can keep up at lower rates, but not higher rates */ - if (tx_info->control.hw_key) + if (fi->keyix != ATH9K_TXKEYIX_INVALID) ndelim += ATH_AGGR_ENCRYPTDELIM; /* @@ -730,17 +714,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, al_delta, h_baw = tid->baw_size / 2; enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; struct ieee80211_tx_info *tx_info; - int frmlen; - u16 bf_seqno; + struct ath_frame_info *fi; bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); do { bf = list_first_entry(&tid->buf_q, struct ath_buf, list); - bf_seqno = ath_frame_seqno(bf->bf_mpdu); + fi = get_frame_info(bf->bf_mpdu); /* do not step over block-ack window */ - if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno)) { + if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) { status = ATH_AGGR_BAW_CLOSED; break; } @@ -751,8 +734,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } /* do not exceed aggregation limit */ - frmlen = ath_frame_len(bf->bf_mpdu); - al_delta = ATH_AGGR_DELIM_SZ + frmlen; + al_delta = ATH_AGGR_DELIM_SZ + fi->framelen; if (nframes && (aggr_limit < (al + bpad + al_delta + prev_al))) { @@ -779,15 +761,15 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, * Get the delimiters needed to meet the MPDU * density for this node. */ - ndelim = ath_compute_num_delims(sc, tid, bf_first, frmlen); + ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen); bpad = PADBYTES(al_delta) + (ndelim << 2); bf->bf_next = NULL; ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); /* link buffers of this frame to the aggregate */ - if (!bf_isretried(bf)) - ath_tx_addto_baw(sc, tid, bf_seqno); + if (!fi->retries) + ath_tx_addto_baw(sc, tid, fi->seqno); ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); list_move_tail(&bf->list, bf_q); if (bf_prev) { @@ -810,6 +792,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, { struct ath_buf *bf; enum ATH_AGGR_STATUS status; + struct ath_frame_info *fi; struct list_head bf_q; int aggr_len; @@ -833,9 +816,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, /* if only one frame, send as non-aggregate */ if (bf == bf->bf_lastbf) { + fi = get_frame_info(bf->bf_mpdu); + bf->bf_state.bf_type &= ~BUF_AGGR; ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); - ath_buf_set_rate(sc, bf, ath_frame_len(bf->bf_mpdu)); + ath_buf_set_rate(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_q); continue; } @@ -1346,12 +1331,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, struct ath_buf *bf, struct ath_tx_control *txctl) { + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); struct list_head bf_head; - u16 bf_seqno; bf->bf_state.bf_type |= BUF_AMPDU; TX_STAT_INC(txctl->txq->axq_qnum, a_queued); - bf_seqno = ath_frame_seqno(bf->bf_mpdu); /* * Do not queue to h/w when any of the following conditions is true: @@ -1361,7 +1345,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, * - h/w queue depth exceeds low water mark */ if (!list_empty(&tid->buf_q) || tid->paused || - !BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno) || + !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) || txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { /* * Add this frame to software queue for scheduling later @@ -1376,19 +1360,20 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, list_add(&bf->list, &bf_head); /* Add sub-frame to BAW */ - if (!bf_isretried(bf)) - ath_tx_addto_baw(sc, tid, bf_seqno); + if (!fi->retries) + ath_tx_addto_baw(sc, tid, fi->seqno); /* Queue to h/w without aggregation */ bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, txctl->frmlen); + ath_buf_set_rate(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); } static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct list_head *bf_head, int frmlen) + struct list_head *bf_head) { + struct ath_frame_info *fi; struct ath_buf *bf; bf = list_first_entry(bf_head, struct ath_buf, list); @@ -1399,7 +1384,8 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, INCR(tid->seq_start, IEEE80211_SEQ_MAX); bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, frmlen); + fi = get_frame_info(bf->bf_mpdu); + ath_buf_set_rate(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txq, bf_head); TX_STAT_INC(txq->axq_qnum, queued); } @@ -1427,30 +1413,49 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static void assign_aggr_tid_seqno(struct sk_buff *skb) +static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, + int framelen) { + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = tx_info->control.sta; + struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr; + struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an; struct ath_atx_tid *tid; - __le16 fc; + enum ath9k_key_type keytype; + u16 seqno = 0; u8 tidno; - if (!tx_info->control.sta) - return; + keytype = ath9k_cmn_get_hw_crypto_keytype(skb); - an = (struct ath_node *)tx_info->control.sta->drv_priv; hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + if (sta && ieee80211_is_data_qos(hdr->frame_control) && + conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { - /* - * Override seqno set by upper layer with the one - * in tx aggregation state. - */ - tid = ATH_AN_2_TID(an, tidno); - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); - INCR(tid->seq_next, IEEE80211_SEQ_MAX); + an = (struct ath_node *) sta->drv_priv; + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + + /* + * Override seqno set by upper layer with the one + * in tx aggregation state. + */ + tid = ATH_AN_2_TID(an, tidno); + seqno = tid->seq_next; + hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT); + INCR(tid->seq_next, IEEE80211_SEQ_MAX); + } + + memset(fi, 0, sizeof(*fi)); + if (hw_key) + fi->keyix = hw_key->hw_key_idx; + else + fi->keyix = ATH9K_TXKEYIX_INVALID; + fi->keytype = keytype; + fi->framelen = framelen; + fi->seqno = seqno; } static int setup_tx_flags(struct sk_buff *skb) @@ -1609,18 +1614,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_txq *txq, - struct sk_buff *skb, int frmlen) + struct sk_buff *skb) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb; + struct ath_frame_info *fi = get_frame_info(skb); struct ath_buf *bf; struct ath_desc *ds; - enum ath9k_key_type keytype; - u32 keyix; int frm_type; bf = ath_tx_get_buffer(sc); @@ -1631,10 +1633,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, ATH_TXBUF_RESET(bf); - if (ieee80211_is_data_qos(hdr->frame_control) && - conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) - assign_aggr_tid_seqno(skb); - bf->aphy = aphy; bf->bf_flags = setup_tx_flags(skb); bf->bf_mpdu = skb; @@ -1655,14 +1653,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, ds = bf->bf_desc; ath9k_hw_set_desc_link(ah, ds, 0); - keytype = ath9k_cmn_get_hw_crypto_keytype(skb); - if (tx_info->control.hw_key) - keyix = tx_info->control.hw_key->hw_key_idx; - else - keyix = ATH9K_TXKEYIX_INVALID; - - ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER, - keyix, keytype, bf->bf_flags); + ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, + fi->keyix, fi->keytype, bf->bf_flags); ath9k_hw_filltxdesc(ah, ds, skb->len, /* segment length */ @@ -1683,18 +1675,16 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ath_node *an = NULL; struct list_head bf_head; struct ath_atx_tid *tid; u8 tidno; spin_lock_bh(&txctl->txq->axq_lock); - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tx_info->control.sta) { - an = (struct ath_node *)tx_info->control.sta->drv_priv; + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) { tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; - tid = ATH_AN_2_TID(an, tidno); + tid = ATH_AN_2_TID(txctl->an, tidno); WARN_ON(tid->ac->txq != txctl->txq); /* @@ -1713,7 +1703,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, bf->bf_state.bfs_paprd); - ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, txctl->frmlen); + ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); } spin_unlock_bh(&txctl->txq->axq_lock); @@ -1725,6 +1715,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->control.sta; struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_txq *txq = txctl->txq; @@ -1733,11 +1724,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, int frmlen = skb->len + FCS_LEN; int q; + txctl->an = (struct ath_node *)sta->drv_priv; if (info->control.hw_key) frmlen += info->control.hw_key->icv_len; - txctl->frmlen = frmlen; - /* * As a temporary workaround, assign seq# here; this will likely need * to be cleaned up to work better with Beacon transmission and virtual @@ -1761,7 +1751,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, memmove(skb->data, skb->data + padsize, padpos); } - bf = ath_tx_setup_buffer(hw, txctl->txq, skb, frmlen); + setup_frame_info(hw, skb, frmlen); + + /* + * At this point, the vif, hw_key and sta pointers in the tx control + * info are no longer valid (overwritten by the ath_frame_info data. + */ + + bf = ath_tx_setup_buffer(hw, txctl->txq, skb); if (unlikely(!bf)) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 488f6ba75b5deaa7e89d6cdac07e0f2120899b6f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 16 Nov 2010 19:20:28 +0100 Subject: ath9k_hw: add support for reading EEPROM data from the internal OTP ROM Some of the new AR9003 cards do not come with an external EEPROM chip anymore. Calibration data on these cards is stored in the OTP ROM on the chip. This patch adds support for reading this data, and also adds support for different EEPROM chip sizes (512 bytes instead of 1K). Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 90 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 9 +++ 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 1b4e99167b6c..230a1228de8e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3104,6 +3104,36 @@ error: return false; } +static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data) +{ + REG_READ(ah, AR9300_OTP_BASE + (4 * addr)); + + if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE, + AR9300_OTP_STATUS_VALID, 1000)) + return false; + + *data = REG_READ(ah, AR9300_OTP_READ_DATA); + return true; +} + +static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer, + int count) +{ + u32 data; + int i; + + for (i = 0; i < count; i++) { + int offset = 8 * ((address - i) % 4); + if (!ar9300_otp_read_word(ah, (address - i) / 4, &data)) + return false; + + buffer[i] = (data >> offset) & 0xff; + } + + return true; +} + + static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, int *length, int *major, int *minor) { @@ -3221,6 +3251,26 @@ static int ar9300_compress_decision(struct ath_hw *ah, return 0; } +typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer, + int count); + +static bool ar9300_check_header(void *data) +{ + u32 *word = data; + return !(*word == 0 || *word == ~0); +} + +static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read, + int base_addr) +{ + u8 header[4]; + + if (!read(ah, base_addr, header, 4)) + return false; + + return ar9300_check_header(header); +} + /* * Read the configuration data from the eeprom. * The data can be put in any specified memory buffer. @@ -3241,6 +3291,7 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, int it; u16 checksum, mchecksum; struct ath_common *common = ath9k_hw_common(ah); + eeprom_read_op read; word = kzalloc(2048, GFP_KERNEL); if (!word) @@ -3248,14 +3299,42 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, memcpy(mptr, &ar9300_default, mdata_size); + read = ar9300_read_eeprom; cptr = AR9300_BASE_ADDR; + ath_print(common, ATH_DBG_EEPROM, + "Trying EEPROM accesss at Address 0x%04x\n", cptr); + if (ar9300_check_eeprom_header(ah, read, cptr)) + goto found; + + cptr = AR9300_BASE_ADDR_512; + ath_print(common, ATH_DBG_EEPROM, + "Trying EEPROM accesss at Address 0x%04x\n", cptr); + if (ar9300_check_eeprom_header(ah, read, cptr)) + goto found; + + read = ar9300_read_otp; + cptr = AR9300_BASE_ADDR; + ath_print(common, ATH_DBG_EEPROM, + "Trying OTP accesss at Address 0x%04x\n", cptr); + if (ar9300_check_eeprom_header(ah, read, cptr)) + goto found; + + cptr = AR9300_BASE_ADDR_512; + ath_print(common, ATH_DBG_EEPROM, + "Trying OTP accesss at Address 0x%04x\n", cptr); + if (ar9300_check_eeprom_header(ah, read, cptr)) + goto found; + + goto fail; + +found: + ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data"); + for (it = 0; it < MSTATE; it++) { - if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) + if (!read(ah, cptr, word, COMP_HDR_LEN)) goto fail; - if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && - word[3] == 0) || (word[0] == 0xff && word[1] == 0xff - && word[2] == 0xff && word[3] == 0xff)) + if (!ar9300_check_header(word)) break; ar9300_comp_hdr_unpack(word, &code, &reference, @@ -3272,8 +3351,7 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, } osize = length; - ar9300_read_eeprom(ah, cptr, word, - COMP_HDR_LEN + osize + COMP_CKSUM_LEN); + read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN); checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); mchecksum = word[COMP_HDR_LEN + osize] | (word[COMP_HDR_LEN + osize + 1] << 8); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 5301df3e9ec0..57f64dbbcd89 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -79,6 +79,15 @@ #define FIXED_CCA_THRESHOLD 15 #define AR9300_BASE_ADDR 0x3ff +#define AR9300_BASE_ADDR_512 0x1ff + +#define AR9300_OTP_BASE 0x14000 +#define AR9300_OTP_STATUS 0x15f18 +#define AR9300_OTP_STATUS_TYPE 0x7 +#define AR9300_OTP_STATUS_VALID 0x4 +#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 +#define AR9300_OTP_STATUS_SM_BUSY 0x1 +#define AR9300_OTP_READ_DATA 0x15f1c enum targetPowerHTRates { HT_TARGET_RATE_0_8_16, -- cgit v1.2.3-59-g8ed1b From 4bce22b9b84032c77c7e038b07b24fcc706dfc10 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Nov 2010 11:49:58 -0800 Subject: mac80211: defines for AC numbers In many places we've just hardcoded the AC numbers -- which is a relic from the original mac80211 (d80211). Add constants for them so we know what we're talking about. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 14 ++++++++++++++ net/mac80211/wme.c | 11 ++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1248369a7c30..5b0fff2178bb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -96,6 +96,20 @@ enum ieee80211_max_queues { IEEE80211_MAX_QUEUES = 4, }; +/** + * enum ieee80211_ac_numbers - AC numbers as used in mac80211 + * @IEEE80211_AC_VO: voice + * @IEEE80211_AC_VI: video + * @IEEE80211_AC_BE: best effort + * @IEEE80211_AC_BK: background + */ +enum ieee80211_ac_numbers { + IEEE80211_AC_VO = 0, + IEEE80211_AC_VI = 1, + IEEE80211_AC_BE = 2, + IEEE80211_AC_BK = 3, +}; + /** * struct ieee80211_tx_queue_params - transmit queue configuration * diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 34e6d02da779..58e75bbc1f91 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -21,7 +21,16 @@ /* Default mapping in classifier to work with default * queue setup. */ -const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; +const int ieee802_1d_to_ac[8] = { + IEEE80211_AC_BE, + IEEE80211_AC_BK, + IEEE80211_AC_BK, + IEEE80211_AC_BE, + IEEE80211_AC_VI, + IEEE80211_AC_VI, + IEEE80211_AC_VO, + IEEE80211_AC_VO +}; static int wme_downgrade_ac(struct sk_buff *skb) { -- cgit v1.2.3-59-g8ed1b From 50a9432daeece6fc1309bef1dc0a7b8fde8204cb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Nov 2010 11:50:28 -0800 Subject: mac80211: fix powersaving clients races The code to handle powersaving stations has a race: when the powersave flag is lifted from a station, we could transmit a packet that is being processed for TX at the same time right away, even if there are other frames queued for it. This would cause frame reordering. To fix this, lift the flag only under the appropriate lock that blocks TX. Additionally, the code to allow drivers to block a station while frames for it are on the HW queue is never re-enabled the station, so traffic would get stuck indefinitely. Fix this by clearing the flag for this appropriately. Finally, as an optimisation, don't do anything if the driver unblocks an already unblocked station. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/rx.c | 2 -- net/mac80211/sta_info.c | 17 ++++++++++++++--- net/mac80211/util.c | 14 ++++++++++++-- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 59a1d38212fd..3598abf21844 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1278,6 +1278,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, struct sk_buff *skb); int ieee80211_add_pending_skbs(struct ieee80211_local *local, struct sk_buff_head *skbs); +int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, + struct sk_buff_head *skbs, + void (*fn)(void *data), void *data); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 902b03ee8f60..d2fcd22ab06d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1102,8 +1102,6 @@ static void ap_sta_ps_end(struct sta_info *sta) atomic_dec(&sdata->bss->num_sta_ps); - clear_sta_flags(sta, WLAN_STA_PS_STA); - #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", sdata->name, sta->sta.addr, sta->sta.aid); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6d8f897d8763..eff58571fd7e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -199,8 +199,11 @@ static void sta_unblock(struct work_struct *wk) if (!test_sta_flags(sta, WLAN_STA_PS_STA)) ieee80211_sta_ps_deliver_wakeup(sta); - else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) + else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { + clear_sta_flags(sta, WLAN_STA_PS_DRIVER); ieee80211_sta_ps_deliver_poll_response(sta); + } else + clear_sta_flags(sta, WLAN_STA_PS_DRIVER); } static int sta_prepare_rate_control(struct ieee80211_local *local, @@ -880,6 +883,13 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, } EXPORT_SYMBOL(ieee80211_find_sta); +static void clear_sta_ps_flags(void *_sta) +{ + struct sta_info *sta = _sta; + + clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA); +} + /* powersave support code */ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) { @@ -894,7 +904,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) /* Send all buffered frames to the station */ sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); - buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); + buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf, + clear_sta_ps_flags, sta); sent += buffered; local->total_ps_buffered -= buffered; @@ -973,7 +984,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, if (block) set_sta_flags(sta, WLAN_STA_PS_DRIVER); - else + else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) ieee80211_queue_work(hw, &sta->drv_unblock_wk); } EXPORT_SYMBOL(ieee80211_sta_block_awake); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 68d0518254dd..e497476174ce 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -368,8 +368,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); } -int ieee80211_add_pending_skbs(struct ieee80211_local *local, - struct sk_buff_head *skbs) +int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, + struct sk_buff_head *skbs, + void (*fn)(void *data), void *data) { struct ieee80211_hw *hw = &local->hw; struct sk_buff *skb; @@ -394,6 +395,9 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, __skb_queue_tail(&local->pending[queue], skb); } + if (fn) + fn(data); + for (i = 0; i < hw->queues; i++) __ieee80211_wake_queue(hw, i, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); @@ -402,6 +406,12 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, return ret; } +int ieee80211_add_pending_skbs(struct ieee80211_local *local, + struct sk_buff_head *skbs) +{ + return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); +} + void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, enum queue_stop_reason reason) { -- cgit v1.2.3-59-g8ed1b From 866f3b25a2eb60d7529c227a0ecd80c3aba443fd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Nov 2010 09:33:19 -0800 Subject: bonding: IGMP handling cleanup Instead of iterating in_dev->mc_list from bonding driver, its better to call a helper function provided by igmp.c Details of implementation (locking) are private to igmp code. ip_mc_rejoin_group(struct ip_mc_list *im) becomes ip_mc_rejoin_groups(struct in_device *in_dev); Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 ++------ include/linux/igmp.h | 2 +- net/ipv4/igmp.c | 32 +++++++++++++++++++------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 518844852f06..e588b2e1c3b3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -873,15 +873,11 @@ static void bond_mc_del(struct bonding *bond, void *addr) static void __bond_resend_igmp_join_requests(struct net_device *dev) { struct in_device *in_dev; - struct ip_mc_list *im; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); - if (in_dev) { - for (im = in_dev->mc_list; im; im = im->next) - ip_mc_rejoin_group(im); - } - + if (in_dev) + ip_mc_rejoin_groups(in_dev); rcu_read_unlock(); } diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 7d164670f264..c4987f265109 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -238,7 +238,7 @@ extern void ip_mc_unmap(struct in_device *); extern void ip_mc_remap(struct in_device *); extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); -extern void ip_mc_rejoin_group(struct ip_mc_list *im); +extern void ip_mc_rejoin_groups(struct in_device *in_dev); #endif #endif diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index afb1e82a59f9..50f6bc1a002a 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1267,26 +1267,32 @@ EXPORT_SYMBOL(ip_mc_inc_group); /* * Resend IGMP JOIN report; used for bonding. + * Called with rcu_read_lock() */ -void ip_mc_rejoin_group(struct ip_mc_list *im) +void ip_mc_rejoin_groups(struct in_device *in_dev) { #ifdef CONFIG_IP_MULTICAST - struct in_device *in_dev = im->interface; + struct ip_mc_list *im; + int type; - if (im->multiaddr == IGMP_ALL_HOSTS) - return; + for_each_pmc_rcu(in_dev, im) { + if (im->multiaddr == IGMP_ALL_HOSTS) + continue; - /* a failover is happening and switches - * must be notified immediately */ - if (IGMP_V1_SEEN(in_dev)) - igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); - else if (IGMP_V2_SEEN(in_dev)) - igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); - else - igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); + /* a failover is happening and switches + * must be notified immediately + */ + if (IGMP_V1_SEEN(in_dev)) + type = IGMP_HOST_MEMBERSHIP_REPORT; + else if (IGMP_V2_SEEN(in_dev)) + type = IGMPV2_HOST_MEMBERSHIP_REPORT; + else + type = IGMPV3_HOST_MEMBERSHIP_REPORT; + igmp_send_report(in_dev, im, type); + } #endif } -EXPORT_SYMBOL(ip_mc_rejoin_group); +EXPORT_SYMBOL(ip_mc_rejoin_groups); /* * A socket has left a multicast group on device dev -- cgit v1.2.3-59-g8ed1b From f72f2f4cdeb67bc262d80a6d474292f00182a4dc Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 18 Nov 2010 09:37:07 -0800 Subject: dccp ccid-2: whitespace fix-up This fixes whitespace noise introduced in commit "dccp ccid-2: Algorithm to update buffer state", 5753fdfe8bd8e9a2ff9e5af19b0ffc78bfcd502a, 14 Nov 2010. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ackvec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 41819848bdda..25b7a8d1ad58 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -282,7 +282,7 @@ void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb) * packet of group (2) in 11.4.2. */ void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno) - { +{ struct dccp_ackvec_record *avr, *next; u8 runlen_now, eff_runlen; s64 delta; -- cgit v1.2.3-59-g8ed1b From 9e50e3ac5a5bbb1fd2949bdd57444ad1b93e5f41 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 16 Nov 2010 19:12:28 +0000 Subject: net: add priority field to pktgen Add option to set skb priority to pktgen. Useful for testing QOS features. Also by running pktgen on the vlan device the qdisc on the real device can be tested. Signed-off-by: John Fastabend Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/pktgen.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 33bc3823ac6f..52fc1e08a7c4 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -378,6 +378,7 @@ struct pktgen_dev { u16 queue_map_min; u16 queue_map_max; + __u32 skb_priority; /* skb priority field */ int node; /* Memory node */ #ifdef CONFIG_XFRM @@ -547,6 +548,10 @@ static int pktgen_if_show(struct seq_file *seq, void *v) pkt_dev->queue_map_min, pkt_dev->queue_map_max); + if (pkt_dev->skb_priority) + seq_printf(seq, " skb_priority: %u\n", + pkt_dev->skb_priority); + if (pkt_dev->flags & F_IPV6) { char b1[128], b2[128], b3[128]; fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); @@ -1711,6 +1716,18 @@ static ssize_t pktgen_if_write(struct file *file, return count; } + if (!strcmp(name, "skb_priority")) { + len = num_arg(&user_buffer[i], 9, &value); + if (len < 0) + return len; + + i += len; + pkt_dev->skb_priority = value; + sprintf(pg_result, "OK: skb_priority=%i", + pkt_dev->skb_priority); + return count; + } + sprintf(pkt_dev->result, "No such parameter \"%s\"", name); return -EINVAL; } @@ -2671,6 +2688,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, skb->transport_header = skb->network_header + sizeof(struct iphdr); skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr)); skb_set_queue_mapping(skb, queue_map); + skb->priority = pkt_dev->skb_priority; + iph = ip_hdr(skb); udph = udp_hdr(skb); @@ -3016,6 +3035,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr)); skb_set_queue_mapping(skb, queue_map); + skb->priority = pkt_dev->skb_priority; iph = ipv6_hdr(skb); udph = udp_hdr(skb); -- cgit v1.2.3-59-g8ed1b From cba328fc5ede9091616e7296483840869b615a46 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 16 Nov 2010 15:19:51 +0000 Subject: filter: Optimize instruction revalidation code. Since repeating u16 value to u8 value conversion using switch() clause's case statement is wasteful, this patch introduces u16 to u8 mapping table and removes most of case statements. As a result, the size of net/core/filter.o is reduced by about 29% on x86. Signed-off-by: Tetsuo Handa Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/filter.c | 231 +++++++++++++++++------------------------------------- 1 file changed, 72 insertions(+), 159 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 23e9b2a6b4c8..03dc0710194f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -383,7 +383,57 @@ EXPORT_SYMBOL(sk_run_filter); */ int sk_chk_filter(struct sock_filter *filter, int flen) { - struct sock_filter *ftest; + /* + * Valid instructions are initialized to non-0. + * Invalid instructions are initialized to 0. + */ + static const u8 codes[] = { + [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K + 1, + [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X + 1, + [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K + 1, + [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X + 1, + [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K + 1, + [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X + 1, + [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X + 1, + [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K + 1, + [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X + 1, + [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K + 1, + [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X + 1, + [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K + 1, + [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X + 1, + [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K + 1, + [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X + 1, + [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG + 1, + [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS + 1, + [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS + 1, + [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS + 1, + [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN + 1, + [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND + 1, + [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND + 1, + [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND + 1, + [BPF_LD|BPF_IMM] = BPF_S_LD_IMM + 1, + [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN + 1, + [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH + 1, + [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM + 1, + [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX + 1, + [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA + 1, + [BPF_RET|BPF_K] = BPF_S_RET_K + 1, + [BPF_RET|BPF_A] = BPF_S_RET_A + 1, + [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K + 1, + [BPF_LD|BPF_MEM] = BPF_S_LD_MEM + 1, + [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM + 1, + [BPF_ST] = BPF_S_ST + 1, + [BPF_STX] = BPF_S_STX + 1, + [BPF_JMP|BPF_JA] = BPF_S_JMP_JA + 1, + [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K + 1, + [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X + 1, + [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K + 1, + [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X + 1, + [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K + 1, + [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X + 1, + [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K + 1, + [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X + 1, + }; int pc; if (flen == 0 || flen > BPF_MAXINSNS) @@ -391,136 +441,31 @@ int sk_chk_filter(struct sock_filter *filter, int flen) /* check the filter code now */ for (pc = 0; pc < flen; pc++) { - ftest = &filter[pc]; - - /* Only allow valid instructions */ - switch (ftest->code) { - case BPF_ALU|BPF_ADD|BPF_K: - ftest->code = BPF_S_ALU_ADD_K; - break; - case BPF_ALU|BPF_ADD|BPF_X: - ftest->code = BPF_S_ALU_ADD_X; - break; - case BPF_ALU|BPF_SUB|BPF_K: - ftest->code = BPF_S_ALU_SUB_K; - break; - case BPF_ALU|BPF_SUB|BPF_X: - ftest->code = BPF_S_ALU_SUB_X; - break; - case BPF_ALU|BPF_MUL|BPF_K: - ftest->code = BPF_S_ALU_MUL_K; - break; - case BPF_ALU|BPF_MUL|BPF_X: - ftest->code = BPF_S_ALU_MUL_X; - break; - case BPF_ALU|BPF_DIV|BPF_X: - ftest->code = BPF_S_ALU_DIV_X; - break; - case BPF_ALU|BPF_AND|BPF_K: - ftest->code = BPF_S_ALU_AND_K; - break; - case BPF_ALU|BPF_AND|BPF_X: - ftest->code = BPF_S_ALU_AND_X; - break; - case BPF_ALU|BPF_OR|BPF_K: - ftest->code = BPF_S_ALU_OR_K; - break; - case BPF_ALU|BPF_OR|BPF_X: - ftest->code = BPF_S_ALU_OR_X; - break; - case BPF_ALU|BPF_LSH|BPF_K: - ftest->code = BPF_S_ALU_LSH_K; - break; - case BPF_ALU|BPF_LSH|BPF_X: - ftest->code = BPF_S_ALU_LSH_X; - break; - case BPF_ALU|BPF_RSH|BPF_K: - ftest->code = BPF_S_ALU_RSH_K; - break; - case BPF_ALU|BPF_RSH|BPF_X: - ftest->code = BPF_S_ALU_RSH_X; - break; - case BPF_ALU|BPF_NEG: - ftest->code = BPF_S_ALU_NEG; - break; - case BPF_LD|BPF_W|BPF_ABS: - ftest->code = BPF_S_LD_W_ABS; - break; - case BPF_LD|BPF_H|BPF_ABS: - ftest->code = BPF_S_LD_H_ABS; - break; - case BPF_LD|BPF_B|BPF_ABS: - ftest->code = BPF_S_LD_B_ABS; - break; - case BPF_LD|BPF_W|BPF_LEN: - ftest->code = BPF_S_LD_W_LEN; - break; - case BPF_LD|BPF_W|BPF_IND: - ftest->code = BPF_S_LD_W_IND; - break; - case BPF_LD|BPF_H|BPF_IND: - ftest->code = BPF_S_LD_H_IND; - break; - case BPF_LD|BPF_B|BPF_IND: - ftest->code = BPF_S_LD_B_IND; - break; - case BPF_LD|BPF_IMM: - ftest->code = BPF_S_LD_IMM; - break; - case BPF_LDX|BPF_W|BPF_LEN: - ftest->code = BPF_S_LDX_W_LEN; - break; - case BPF_LDX|BPF_B|BPF_MSH: - ftest->code = BPF_S_LDX_B_MSH; - break; - case BPF_LDX|BPF_IMM: - ftest->code = BPF_S_LDX_IMM; - break; - case BPF_MISC|BPF_TAX: - ftest->code = BPF_S_MISC_TAX; - break; - case BPF_MISC|BPF_TXA: - ftest->code = BPF_S_MISC_TXA; - break; - case BPF_RET|BPF_K: - ftest->code = BPF_S_RET_K; - break; - case BPF_RET|BPF_A: - ftest->code = BPF_S_RET_A; - break; + struct sock_filter *ftest = &filter[pc]; + u16 code = ftest->code; + if (code >= ARRAY_SIZE(codes)) + return -EINVAL; + code = codes[code]; + /* Undo the '+ 1' in codes[] after validation. */ + if (!code--) + return -EINVAL; /* Some instructions need special checks */ - + switch (code) { + case BPF_S_ALU_DIV_K: /* check for division by zero */ - case BPF_ALU|BPF_DIV|BPF_K: if (ftest->k == 0) return -EINVAL; - ftest->code = BPF_S_ALU_DIV_K; break; - - /* check for invalid memory addresses */ - case BPF_LD|BPF_MEM: - if (ftest->k >= BPF_MEMWORDS) - return -EINVAL; - ftest->code = BPF_S_LD_MEM; - break; - case BPF_LDX|BPF_MEM: - if (ftest->k >= BPF_MEMWORDS) - return -EINVAL; - ftest->code = BPF_S_LDX_MEM; - break; - case BPF_ST: - if (ftest->k >= BPF_MEMWORDS) - return -EINVAL; - ftest->code = BPF_S_ST; - break; - case BPF_STX: + case BPF_S_LD_MEM: + case BPF_S_LDX_MEM: + case BPF_S_ST: + case BPF_S_STX: + /* check for invalid memory addresses */ if (ftest->k >= BPF_MEMWORDS) return -EINVAL; - ftest->code = BPF_S_STX; break; - - case BPF_JMP|BPF_JA: + case BPF_S_JMP_JA: /* * Note, the large ftest->k might cause loops. * Compare this with conditional jumps below, @@ -528,40 +473,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) */ if (ftest->k >= (unsigned)(flen-pc-1)) return -EINVAL; - ftest->code = BPF_S_JMP_JA; - break; - - case BPF_JMP|BPF_JEQ|BPF_K: - ftest->code = BPF_S_JMP_JEQ_K; - break; - case BPF_JMP|BPF_JEQ|BPF_X: - ftest->code = BPF_S_JMP_JEQ_X; break; - case BPF_JMP|BPF_JGE|BPF_K: - ftest->code = BPF_S_JMP_JGE_K; - break; - case BPF_JMP|BPF_JGE|BPF_X: - ftest->code = BPF_S_JMP_JGE_X; - break; - case BPF_JMP|BPF_JGT|BPF_K: - ftest->code = BPF_S_JMP_JGT_K; - break; - case BPF_JMP|BPF_JGT|BPF_X: - ftest->code = BPF_S_JMP_JGT_X; - break; - case BPF_JMP|BPF_JSET|BPF_K: - ftest->code = BPF_S_JMP_JSET_K; - break; - case BPF_JMP|BPF_JSET|BPF_X: - ftest->code = BPF_S_JMP_JSET_X; - break; - - default: - return -EINVAL; - } - - /* for conditionals both must be safe */ - switch (ftest->code) { case BPF_S_JMP_JEQ_K: case BPF_S_JMP_JEQ_X: case BPF_S_JMP_JGE_K: @@ -570,10 +482,13 @@ int sk_chk_filter(struct sock_filter *filter, int flen) case BPF_S_JMP_JGT_X: case BPF_S_JMP_JSET_X: case BPF_S_JMP_JSET_K: + /* for conditionals both must be safe */ if (pc + ftest->jt + 1 >= flen || pc + ftest->jf + 1 >= flen) return -EINVAL; + break; } + ftest->code = code; } /* last instruction must be a RET code */ @@ -581,10 +496,8 @@ int sk_chk_filter(struct sock_filter *filter, int flen) case BPF_S_RET_K: case BPF_S_RET_A: return 0; - break; - default: - return -EINVAL; - } + } + return -EINVAL; } EXPORT_SYMBOL(sk_chk_filter); -- cgit v1.2.3-59-g8ed1b From 4c3710afbc333c33100739dec10662b4ee64e219 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 16 Nov 2010 20:28:24 +0000 Subject: net: move definitions of BPF_S_* to net/core/filter.c BPF_S_* are used internally, should not be exposed to the others. Signed-off-by: Changli Gao Acked-by: Eric Dumazet Acked-by: Hagen Paul Pfeifer Signed-off-by: David S. Miller --- include/linux/filter.h | 48 ------------------------------------------------ net/core/filter.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 69b43dbea6c6..151f5d703b7e 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -91,54 +91,6 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #define BPF_TAX 0x00 #define BPF_TXA 0x80 -enum { - BPF_S_RET_K = 0, - BPF_S_RET_A, - BPF_S_ALU_ADD_K, - BPF_S_ALU_ADD_X, - BPF_S_ALU_SUB_K, - BPF_S_ALU_SUB_X, - BPF_S_ALU_MUL_K, - BPF_S_ALU_MUL_X, - BPF_S_ALU_DIV_X, - BPF_S_ALU_AND_K, - BPF_S_ALU_AND_X, - BPF_S_ALU_OR_K, - BPF_S_ALU_OR_X, - BPF_S_ALU_LSH_K, - BPF_S_ALU_LSH_X, - BPF_S_ALU_RSH_K, - BPF_S_ALU_RSH_X, - BPF_S_ALU_NEG, - BPF_S_LD_W_ABS, - BPF_S_LD_H_ABS, - BPF_S_LD_B_ABS, - BPF_S_LD_W_LEN, - BPF_S_LD_W_IND, - BPF_S_LD_H_IND, - BPF_S_LD_B_IND, - BPF_S_LD_IMM, - BPF_S_LDX_W_LEN, - BPF_S_LDX_B_MSH, - BPF_S_LDX_IMM, - BPF_S_MISC_TAX, - BPF_S_MISC_TXA, - BPF_S_ALU_DIV_K, - BPF_S_LD_MEM, - BPF_S_LDX_MEM, - BPF_S_ST, - BPF_S_STX, - BPF_S_JMP_JA, - BPF_S_JMP_JEQ_K, - BPF_S_JMP_JEQ_X, - BPF_S_JMP_JGE_K, - BPF_S_JMP_JGE_X, - BPF_S_JMP_JGT_K, - BPF_S_JMP_JGT_X, - BPF_S_JMP_JSET_K, - BPF_S_JMP_JSET_X, -}; - #ifndef BPF_MAXINSNS #define BPF_MAXINSNS 4096 #endif diff --git a/net/core/filter.c b/net/core/filter.c index 03dc0710194f..15a545d39cd3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -38,6 +38,54 @@ #include #include +enum { + BPF_S_RET_K = 0, + BPF_S_RET_A, + BPF_S_ALU_ADD_K, + BPF_S_ALU_ADD_X, + BPF_S_ALU_SUB_K, + BPF_S_ALU_SUB_X, + BPF_S_ALU_MUL_K, + BPF_S_ALU_MUL_X, + BPF_S_ALU_DIV_X, + BPF_S_ALU_AND_K, + BPF_S_ALU_AND_X, + BPF_S_ALU_OR_K, + BPF_S_ALU_OR_X, + BPF_S_ALU_LSH_K, + BPF_S_ALU_LSH_X, + BPF_S_ALU_RSH_K, + BPF_S_ALU_RSH_X, + BPF_S_ALU_NEG, + BPF_S_LD_W_ABS, + BPF_S_LD_H_ABS, + BPF_S_LD_B_ABS, + BPF_S_LD_W_LEN, + BPF_S_LD_W_IND, + BPF_S_LD_H_IND, + BPF_S_LD_B_IND, + BPF_S_LD_IMM, + BPF_S_LDX_W_LEN, + BPF_S_LDX_B_MSH, + BPF_S_LDX_IMM, + BPF_S_MISC_TAX, + BPF_S_MISC_TXA, + BPF_S_ALU_DIV_K, + BPF_S_LD_MEM, + BPF_S_LDX_MEM, + BPF_S_ST, + BPF_S_STX, + BPF_S_JMP_JA, + BPF_S_JMP_JEQ_K, + BPF_S_JMP_JEQ_X, + BPF_S_JMP_JGE_K, + BPF_S_JMP_JGE_X, + BPF_S_JMP_JGT_K, + BPF_S_JMP_JGT_X, + BPF_S_JMP_JSET_K, + BPF_S_JMP_JSET_X, +}; + /* No hurry in this branch */ static void *__load_pointer(struct sk_buff *skb, int k) { -- cgit v1.2.3-59-g8ed1b From 57e1ab6eaddc9f2c358cd4afb497cda6e3c6821a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Nov 2010 20:36:42 +0000 Subject: igmp: refine skb allocations IGMP allocates MTU sized skbs. This may fail for large MTU (order-2 allocations), so add a fallback to try lower sizes. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 50f6bc1a002a..e0e77e297de3 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -300,6 +300,8 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) return scount; } +#define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb)) + static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) { struct sk_buff *skb; @@ -308,9 +310,16 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) struct igmpv3_report *pig; struct net *net = dev_net(dev); - skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); - if (skb == NULL) - return NULL; + while (1) { + skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), + GFP_ATOMIC | __GFP_NOWARN); + if (skb) + break; + size >>= 1; + if (size < 256) + return NULL; + } + igmp_skb_size(skb) = size; { struct flowi fl = { .oif = dev->ifindex, @@ -399,7 +408,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, return skb; } -#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \ +#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \ skb_tailroom(skb)) : 0) static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, -- cgit v1.2.3-59-g8ed1b From c5485a7e7569ab32eea240c850198519e2a765ef Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 16 Nov 2010 10:58:37 +0900 Subject: lib: Add generic exponentially weighted moving average (EWMA) function This adds generic functions for calculating Exponentially Weighted Moving Averages (EWMA). This implementation makes use of a structure which keeps the EWMA parameters and a scaled up internal representation to reduce rounding errors. The original idea for this implementation came from the rt2x00 driver (rt2x00link.c). I would like to use it in several places in the mac80211 and ath5k code and I hope it can be useful in many other places in the kernel code. Signed-off-by: Bruno Randolf Reviewed-by: KOSAKI Motohiro Signed-off-by: John W. Linville --- include/linux/average.h | 32 +++++++++++++++++++++++++++ lib/Kconfig | 3 +++ lib/Makefile | 2 ++ lib/average.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 include/linux/average.h create mode 100644 lib/average.c diff --git a/include/linux/average.h b/include/linux/average.h new file mode 100644 index 000000000000..7706e40f95fa --- /dev/null +++ b/include/linux/average.h @@ -0,0 +1,32 @@ +#ifndef _LINUX_AVERAGE_H +#define _LINUX_AVERAGE_H + +#include + +/* Exponentially weighted moving average (EWMA) */ + +/* For more documentation see lib/average.c */ + +struct ewma { + unsigned long internal; + unsigned long factor; + unsigned long weight; +}; + +extern void ewma_init(struct ewma *avg, unsigned long factor, + unsigned long weight); + +extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); + +/** + * ewma_read() - Get average value + * @avg: Average structure + * + * Returns the average value held in @avg. + */ +static inline unsigned long ewma_read(const struct ewma *avg) +{ + return DIV_ROUND_CLOSEST(avg->internal, avg->factor); +} + +#endif /* _LINUX_AVERAGE_H */ diff --git a/lib/Kconfig b/lib/Kconfig index fa9bf2c06199..3116aa631af6 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -210,4 +210,7 @@ config GENERIC_ATOMIC64 config LRU_CACHE tristate +config AVERAGE + bool + endmenu diff --git a/lib/Makefile b/lib/Makefile index e6a3763b8212..76d3b8514903 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -106,6 +106,8 @@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o +obj-$(CONFIG_AVERAGE) += average.o + hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/lib/average.c b/lib/average.c new file mode 100644 index 000000000000..f1d1b4660c42 --- /dev/null +++ b/lib/average.c @@ -0,0 +1,57 @@ +/* + * lib/average.c + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include + +/** + * DOC: Exponentially Weighted Moving Average (EWMA) + * + * These are generic functions for calculating Exponentially Weighted Moving + * Averages (EWMA). We keep a structure with the EWMA parameters and a scaled + * up internal representation of the average value to prevent rounding errors. + * The factor for scaling up and the exponential weight (or decay rate) have to + * be specified thru the init fuction. The structure should not be accessed + * directly but only thru the helper functions. + */ + +/** + * ewma_init() - Initialize EWMA parameters + * @avg: Average structure + * @factor: Factor to use for the scaled up internal value. The maximum value + * of averages can be ULONG_MAX/(factor*weight). + * @weight: Exponential weight, or decay rate. This defines how fast the + * influence of older values decreases. Has to be bigger than 1. + * + * Initialize the EWMA parameters for a given struct ewma @avg. + */ +void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight) +{ + WARN_ON(weight <= 1 || factor == 0); + avg->internal = 0; + avg->weight = weight; + avg->factor = factor; +} +EXPORT_SYMBOL(ewma_init); + +/** + * ewma_add() - Exponentially weighted moving average (EWMA) + * @avg: Average structure + * @val: Current value + * + * Add a sample to the average. + */ +struct ewma *ewma_add(struct ewma *avg, unsigned long val) +{ + avg->internal = avg->internal ? + (((avg->internal * (avg->weight - 1)) + + (val * avg->factor)) / avg->weight) : + (val * avg->factor); + return avg; +} +EXPORT_SYMBOL(ewma_add); -- cgit v1.2.3-59-g8ed1b From eef39befaae2a1559efe197d795c376a317af2af Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 16 Nov 2010 10:58:43 +0900 Subject: ath5k: Use generic EWMA library Remove ath5k's private moving average implementation in favour of the generic library version. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/Kconfig | 1 + drivers/net/wireless/ath/ath5k/ani.c | 4 ++-- drivers/net/wireless/ath/ath5k/ath5k.h | 26 ++------------------------ drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/debug.c | 2 +- 5 files changed, 8 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index eb83b7b4d0e3..47844575caa3 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig @@ -4,6 +4,7 @@ config ATH5K select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS + select AVERAGE ---help--- This module adds support for wireless adapters based on Atheros 5xxx chipset. diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index f1419198a479..db98a853ff35 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -216,7 +216,7 @@ static void ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, bool ofdm_trigger) { - int rssi = ah->ah_beacon_rssi_avg.avg; + int rssi = ewma_read(&ah->ah_beacon_rssi_avg); ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)", ofdm_trigger ? "ODFM" : "CCK"); @@ -301,7 +301,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, static void ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) { - int rssi = ah->ah_beacon_rssi_avg.avg; + int rssi = ewma_read(&ah->ah_beacon_rssi_avg); ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity"); diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 308b79e1ff08..2718136e4886 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -25,6 +25,7 @@ #include #include +#include #include /* RX/TX descriptor hw structs @@ -1102,7 +1103,7 @@ struct ath5k_hw { struct ath5k_nfcal_hist ah_nfcal_hist; /* average beacon RSSI in our BSS (used by ANI) */ - struct ath5k_avg_val ah_beacon_rssi_avg; + struct ewma ah_beacon_rssi_avg; /* noise floor from last periodic calibration */ s32 ah_noise_floor; @@ -1315,27 +1316,4 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) return retval; } -#define AVG_SAMPLES 8 -#define AVG_FACTOR 1000 - -/** - * ath5k_moving_average - Exponentially weighted moving average - * @avg: average structure - * @val: current value - * - * This implementation make use of a struct ath5k_avg_val to prevent rounding - * errors. - */ -static inline struct ath5k_avg_val -ath5k_moving_average(const struct ath5k_avg_val avg, const int val) -{ - struct ath5k_avg_val new; - new.avg_weight = avg.avg_weight ? - (((avg.avg_weight * ((AVG_SAMPLES) - 1)) + - (val * (AVG_FACTOR))) / (AVG_SAMPLES)) : - (val * (AVG_FACTOR)); - new.avg = new.avg_weight / (AVG_FACTOR); - return new; -} - #endif diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 13735cc899a5..7f783d9462aa 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1301,8 +1301,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) return; - ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, - rssi); + ewma_add(&ah->ah_beacon_rssi_avg, rssi); /* in IBSS mode we should keep RSSI statistics per neighbour */ /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ @@ -2556,6 +2555,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ah->ah_cal_next_full = jiffies; ah->ah_cal_next_ani = jiffies; ah->ah_cal_next_nf = jiffies; + ewma_init(&ah->ah_beacon_rssi_avg, 1000, 8); /* * Change channels and update the h/w rate map if we're switching; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 54dcf77e9646..7d785cb60ce0 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -719,7 +719,7 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, st->mib_intr); len += snprintf(buf+len, sizeof(buf)-len, "beacon RSSI average:\t%d\n", - sc->ah->ah_beacon_rssi_avg.avg); + (int)ewma_read(&sc->ah->ah_beacon_rssi_avg)); #define CC_PRINT(_struct, _field) \ _struct._field, \ -- cgit v1.2.3-59-g8ed1b From 86107fd170bc379869250eb7e1bd393a3a70e8ae Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 16 Nov 2010 10:58:48 +0900 Subject: nl80211/mac80211: Report signal average Extend nl80211 to report an exponential weighted moving average (EWMA) of the signal value. Since the signal value usually fluctuates between different packets, an average can be more useful than the value of the last packet. This uses the recently added generic EWMA library function. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ include/net/cfg80211.h | 4 ++++ net/mac80211/Kconfig | 1 + net/mac80211/cfg.c | 3 ++- net/mac80211/rx.c | 1 + net/mac80211/sta_info.c | 2 ++ net/mac80211/sta_info.h | 3 +++ net/wireless/nl80211.c | 3 +++ 8 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 037b4e498890..1ce3775e9e26 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1161,6 +1161,7 @@ enum nl80211_rate_info { * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) + * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute * containing info as possible, see &enum nl80211_sta_info_txrate. * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) @@ -1178,6 +1179,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_PLID, NL80211_STA_INFO_PLINK_STATE, NL80211_STA_INFO_SIGNAL, + NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_TX_BITRATE, NL80211_STA_INFO_RX_PACKETS, NL80211_STA_INFO_TX_PACKETS, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8fd9eebd0cc9..69e2364889f1 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -424,6 +424,7 @@ struct station_parameters { * @STATION_INFO_TX_RETRIES: @tx_retries filled * @STATION_INFO_TX_FAILED: @tx_failed filled * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled + * @STATION_INFO_SIGNAL_AVG: @signal_avg filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -439,6 +440,7 @@ enum station_info_flags { STATION_INFO_TX_RETRIES = 1<<10, STATION_INFO_TX_FAILED = 1<<11, STATION_INFO_RX_DROP_MISC = 1<<12, + STATION_INFO_SIGNAL_AVG = 1<<13, }; /** @@ -485,6 +487,7 @@ struct rate_info { * @plid: mesh peer link id * @plink_state: mesh peer link state * @signal: signal strength of last received packet in dBm + * @signal_avg: signal strength average in dBm * @txrate: current unicast bitrate to this station * @rx_packets: packets received from this station * @tx_packets: packets transmitted to this station @@ -505,6 +508,7 @@ struct station_info { u16 plid; u8 plink_state; s8 signal; + s8 signal_avg; struct rate_info txrate; u32 rx_packets; u32 tx_packets; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 4d6f8653ec88..798d9b9462e2 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -6,6 +6,7 @@ config MAC80211 select CRYPTO_ARC4 select CRYPTO_AES select CRC32 + select AVERAGE ---help--- This option enables the hardware independent IEEE 802.11 networking stack. diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0c544074479e..92c9cf6a7d1c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -343,8 +343,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { - sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; sinfo->signal = (s8)sta->last_signal; + sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } sinfo->txrate.flags = 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d2fcd22ab06d..9dd60a74181f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1156,6 +1156,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->rx_fragments++; sta->rx_bytes += rx->skb->len; sta->last_signal = status->signal; + ewma_add(&sta->avg_signal, -status->signal); /* * Change STA power saving mode only at the end of a frame diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index eff58571fd7e..f43fca8907f7 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -244,6 +244,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->local = local; sta->sdata = sdata; + ewma_init(&sta->avg_signal, 1000, 8); + if (sta_prepare_rate_control(local, sta, gfp)) { kfree(sta); return NULL; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9265acadef32..84062e2c782c 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "key.h" /** @@ -224,6 +225,7 @@ enum plink_state { * @rx_fragments: number of received MPDUs * @rx_dropped: number of dropped MPDUs from this STA * @last_signal: signal of last received frame from this STA + * @avg_signal: moving average of signal of received frames from this STA * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) * @tx_filtered_count: number of frames the hardware filtered for this STA * @tx_retry_failed: number of frames that failed retry @@ -291,6 +293,7 @@ struct sta_info { unsigned long rx_fragments; unsigned long rx_dropped; int last_signal; + struct ewma avg_signal; __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; /* Updated from TX status path only, no locking requirements */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 605553842226..d06a40d17002 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1872,6 +1872,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_SIGNAL) NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, sinfo->signal); + if (sinfo->filled & STATION_INFO_SIGNAL_AVG) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, + sinfo->signal_avg); if (sinfo->filled & STATION_INFO_TX_BITRATE) { txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); if (!txrate) -- cgit v1.2.3-59-g8ed1b From 8befba6f2262a6e31d6e3bcf7d07ff46da444ec0 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 16 Nov 2010 16:08:56 -0500 Subject: iwmc3200wifi: clarify potentially undefined operation in iwm_scan_ssids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC [M] drivers/net/wireless/iwmc3200wifi/commands.o drivers/net/wireless/iwmc3200wifi/commands.c: In function ‘iwm_scan_ssids’: drivers/net/wireless/iwmc3200wifi/commands.c:911:15: warning: operation on ‘iwm->scan_id’ may be undefined Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 330c7d9cf101..50dee6a0a5ca 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -908,7 +908,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids, return ret; } - iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX; + iwm->scan_id = (iwm->scan_id + 1) % IWM_SCAN_ID_MAX; return 0; } -- cgit v1.2.3-59-g8ed1b From 458fafdd579dcb58c8288c55c9cd92d6816ba094 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 16 Nov 2010 16:49:08 -0500 Subject: rndis_wlan: avoid uninitialized var warning in rndis_wlan_craft_connected_bss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC [M] drivers/net/wireless/rndis_wlan.o drivers/net/wireless/rndis_wlan.c: In function ‘rndis_wlan_craft_connected_bss’: drivers/net/wireless/rndis_wlan.c:2542:2: warning: ‘ret’ may be used uninitialized in this function Signed-off-by: John W. Linville Acked-by: Jussi Kivilinna --- drivers/net/wireless/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 8a77ff68590b..ee08bcaaf47a 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2536,7 +2536,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, /* Get signal quality, in case of error use rssi=0 and ignore error. */ len = sizeof(rssi); rssi = 0; - rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); + ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); signal = level_to_qual(le32_to_cpu(rssi)); netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, " -- cgit v1.2.3-59-g8ed1b From a05b5d45049d60a06a1b12976150572304a51928 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 17 Nov 2010 04:25:33 +0100 Subject: ath9k: add support for reading eeprom from platform data on PCI devices Some embedded boards store platform data for connected PCIe AR92xx chips in the system flash instead of a separate EEPROM chip. Signed-off-by: Gabor Juhos Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ---- drivers/net/wireless/ath/ath9k/init.c | 3 +++ drivers/net/wireless/ath/ath9k/pci.c | 42 ++++++++++++++++++++++++----------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 75e23632b968..5a13a761c30c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -419,10 +419,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->hw_version.magic = AR5416_MAGIC; ah->hw_version.subvendorid = 0; - ah->ah_flags = 0; - if (!AR_SREV_9100(ah)) - ah->ah_flags = AH_USE_EEPROM; - ah->atim_window = 0; ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 498f62180f1c..e7764ce881df 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -530,6 +530,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; + if (!sc->dev->platform_data) + ah->ah_flags |= AH_USE_EEPROM; + common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; common->bus_ops = bus_ops; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 6605bc2c2036..09f69a9617f4 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -16,6 +16,7 @@ #include #include +#include #include "ath9k.h" static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { @@ -53,21 +54,36 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz) static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) { - struct ath_hw *ah = (struct ath_hw *) common->ah; - - common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); - - if (!ath9k_hw_wait(ah, - AR_EEPROM_STATUS_DATA, - AR_EEPROM_STATUS_DATA_BUSY | - AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, - AH_WAIT_TIMEOUT)) { - return false; + struct ath_softc *sc = (struct ath_softc *) common->priv; + struct ath9k_platform_data *pdata = sc->dev->platform_data; + + if (pdata) { + if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { + ath_print(common, ATH_DBG_FATAL, + "%s: eeprom read failed, offset %08x " + "is out of range\n", + __func__, off); + } + + *data = pdata->eeprom_data[off]; + } else { + struct ath_hw *ah = (struct ath_hw *) common->ah; + + common->ops->read(ah, AR5416_EEPROM_OFFSET + + (off << AR5416_EEPROM_S)); + + if (!ath9k_hw_wait(ah, + AR_EEPROM_STATUS_DATA, + AR_EEPROM_STATUS_DATA_BUSY | + AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, + AH_WAIT_TIMEOUT)) { + return false; + } + + *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA), + AR_EEPROM_STATUS_DATA_VAL); } - *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA), - AR_EEPROM_STATUS_DATA_VAL); - return true; } -- cgit v1.2.3-59-g8ed1b From aaa13ca2428789b3c8096b5edc175d4d78b5f504 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 17 Nov 2010 04:19:47 +0100 Subject: ath9k_hw: support reading calibration data from flash on AR9003 Embedded boards do not have compressed EEPROM data, they use the struct ar9003_eeprom layout, with little endian fields, so copying the raw data to the eeprom buffer is enough. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 230a1228de8e..9a7e151f0796 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3271,6 +3271,18 @@ static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read, return ar9300_check_header(header); } +static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr, + int mdata_size) +{ + struct ath_common *common = ath9k_hw_common(ah); + u16 *data = (u16 *) mptr; + int i; + + for (i = 0; i < mdata_size / 2; i++, data++) + ath9k_hw_nvram_read(common, i, data); + + return 0; +} /* * Read the configuration data from the eeprom. * The data can be put in any specified memory buffer. @@ -3293,6 +3305,9 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, struct ath_common *common = ath9k_hw_common(ah); eeprom_read_op read; + if (ath9k_hw_use_flash(ah)) + return ar9300_eeprom_restore_flash(ah, mptr, mdata_size); + word = kzalloc(2048, GFP_KERNEL); if (!word) return -1; -- cgit v1.2.3-59-g8ed1b From a76a574ca9ce7c05791cee42f000f2a42c687837 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 17 Nov 2010 19:52:13 +0100 Subject: ssb: drop BCM4328 hack for SPROM revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This hacks leads to incorrect SPROM parsing for me and reading for example MAC as: 00:00:00:54:00:00. Michael G. who introduced this confirmed it is not needed anymore. Signed-off-by: Rafał Miłecki Tested-by: Michael Gerdau Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index b5343ac37ee5..f52966305e05 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -580,10 +580,6 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, * Always extract r1. */ out->revision = 1; ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); - } else if (bus->chip_id == 0x4321) { - /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ - out->revision = 4; - ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); } switch (out->revision) { -- cgit v1.2.3-59-g8ed1b From 30dfe2c05037fbc021121c037872c09956938c2f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 18 Nov 2010 11:49:25 -0800 Subject: atm: fore200e: Fix build warning. GCC (rightfully) complains that: drivers/atm/fore200e.c:614:5: warning: operation on 'cmdq->head' may be undefined This is due to the FORE200E_NEXT_ENTRY macro, which essentially evaluates to: i = ++i % m Make it what's explicitly intended here which is: i = (i + 1) % m and the warning goes away. Signed-off-by: David S. Miller --- drivers/atm/fore200e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index c8fc69c85a06..c09761959354 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -92,7 +92,7 @@ #define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ]) -#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) +#define FORE200E_NEXT_ENTRY(index, modulo) (index = ((index) + 1) % (modulo)) #if 1 #define ASSERT(expr) if (!(expr)) { \ -- cgit v1.2.3-59-g8ed1b From 086b5650dcdaae7c4aa60a5d0724f775e733610e Mon Sep 17 00:00:00 2001 From: Tomoya Date: Wed, 17 Nov 2010 01:13:16 +0000 Subject: can: EG20T PCH: add prefix to macro For easy to readable/identifiable, add prefix "PCH_" to all of #define macros. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 391 ++++++++++++++++++++++------------------------ 1 file changed, 189 insertions(+), 202 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 672718261c68..c523e3dd5d10 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -32,49 +32,47 @@ #include #include -#define MAX_MSG_OBJ 32 -#define MSG_OBJ_RX 0 /* The receive message object flag. */ -#define MSG_OBJ_TX 1 /* The transmit message object flag. */ - -#define ENABLE 1 /* The enable flag */ -#define DISABLE 0 /* The disable flag */ -#define CAN_CTRL_INIT 0x0001 /* The INIT bit of CANCONT register. */ -#define CAN_CTRL_IE 0x0002 /* The IE bit of CAN control register */ -#define CAN_CTRL_IE_SIE_EIE 0x000e -#define CAN_CTRL_CCE 0x0040 -#define CAN_CTRL_OPT 0x0080 /* The OPT bit of CANCONT register. */ -#define CAN_OPT_SILENT 0x0008 /* The Silent bit of CANOPT reg. */ -#define CAN_OPT_LBACK 0x0010 /* The LoopBack bit of CANOPT reg. */ -#define CAN_CMASK_RX_TX_SET 0x00f3 -#define CAN_CMASK_RX_TX_GET 0x0073 -#define CAN_CMASK_ALL 0xff -#define CAN_CMASK_RDWR 0x80 -#define CAN_CMASK_ARB 0x20 -#define CAN_CMASK_CTRL 0x10 -#define CAN_CMASK_MASK 0x40 -#define CAN_CMASK_NEWDAT 0x04 -#define CAN_CMASK_CLRINTPND 0x08 - -#define CAN_IF_MCONT_NEWDAT 0x8000 -#define CAN_IF_MCONT_INTPND 0x2000 -#define CAN_IF_MCONT_UMASK 0x1000 -#define CAN_IF_MCONT_TXIE 0x0800 -#define CAN_IF_MCONT_RXIE 0x0400 -#define CAN_IF_MCONT_RMTEN 0x0200 -#define CAN_IF_MCONT_TXRQXT 0x0100 -#define CAN_IF_MCONT_EOB 0x0080 -#define CAN_IF_MCONT_DLC 0x000f -#define CAN_IF_MCONT_MSGLOST 0x4000 -#define CAN_MASK2_MDIR_MXTD 0xc000 -#define CAN_ID2_DIR 0x2000 -#define CAN_ID_MSGVAL 0x8000 - -#define CAN_STATUS_INT 0x8000 -#define CAN_IF_CREQ_BUSY 0x8000 -#define CAN_ID2_XTD 0x4000 - -#define CAN_REC 0x00007f00 -#define CAN_TEC 0x000000ff +#define PCH_MAX_MSG_OBJ 32 +#define PCH_MSG_OBJ_RX 0 /* The receive message object flag. */ +#define PCH_MSG_OBJ_TX 1 /* The transmit message object flag. */ + +#define PCH_ENABLE 1 /* The enable flag */ +#define PCH_DISABLE 0 /* The disable flag */ +#define PCH_CTRL_INIT 0x0001 /* The INIT bit of CANCONT register. */ +#define PCH_CTRL_IE 0x0002 /* The IE bit of CAN control register */ +#define PCH_CTRL_IE_SIE_EIE 0x000e +#define PCH_CTRL_CCE 0x0040 +#define PCH_CTRL_OPT 0x0080 /* The OPT bit of CANCONT register. */ +#define PCH_OPT_SILENT 0x0008 /* The Silent bit of CANOPT reg. */ +#define PCH_OPT_LBACK 0x0010 /* The LoopBack bit of CANOPT reg. */ +#define PCH_CMASK_RX_TX_SET 0x00f3 +#define PCH_CMASK_RX_TX_GET 0x0073 +#define PCH_CMASK_ALL 0xff +#define PCH_CMASK_RDWR 0x80 +#define PCH_CMASK_ARB 0x20 +#define PCH_CMASK_CTRL 0x10 +#define PCH_CMASK_MASK 0x40 +#define PCH_CMASK_NEWDAT 0x04 +#define PCH_CMASK_CLRINTPND 0x08 +#define PCH_IF_MCONT_NEWDAT 0x8000 +#define PCH_IF_MCONT_INTPND 0x2000 +#define PCH_IF_MCONT_UMASK 0x1000 +#define PCH_IF_MCONT_TXIE 0x0800 +#define PCH_IF_MCONT_RXIE 0x0400 +#define PCH_IF_MCONT_RMTEN 0x0200 +#define PCH_IF_MCONT_TXRQXT 0x0100 +#define PCH_IF_MCONT_EOB 0x0080 +#define PCH_IF_MCONT_DLC 0x000f +#define PCH_IF_MCONT_MSGLOST 0x4000 +#define PCH_MASK2_MDIR_MXTD 0xc000 +#define PCH_ID2_DIR 0x2000 +#define PCH_ID2_XTD 0x4000 +#define PCH_ID_MSGVAL 0x8000 +#define PCH_IF_CREQ_BUSY 0x8000 + +#define PCH_STATUS_INT 0x8000 +#define PCH_REC 0x00007f00 +#define PCH_TEC 0x000000ff #define PCH_RX_OK 0x00000010 #define PCH_TX_OK 0x00000008 @@ -93,26 +91,15 @@ #define PCH_CRC_ERR (PCH_LEC1 | PCH_LEC2) /* bit position of certain controller bits. */ -#define BIT_BITT_BRP 0 -#define BIT_BITT_SJW 6 -#define BIT_BITT_TSEG1 8 -#define BIT_BITT_TSEG2 12 -#define BIT_IF1_MCONT_RXIE 10 -#define BIT_IF2_MCONT_TXIE 11 -#define BIT_BRPE_BRPE 6 -#define BIT_ES_TXERRCNT 0 -#define BIT_ES_RXERRCNT 8 -#define MSK_BITT_BRP 0x3f -#define MSK_BITT_SJW 0xc0 -#define MSK_BITT_TSEG1 0xf00 -#define MSK_BITT_TSEG2 0x7000 -#define MSK_BRPE_BRPE 0x3c0 -#define MSK_BRPE_GET 0x0f -#define MSK_CTRL_IE_SIE_EIE 0x07 -#define MSK_MCONT_TXIE 0x08 -#define MSK_MCONT_RXIE 0x10 -#define PCH_CAN_NO_TX_BUFF 1 -#define COUNTER_LIMIT 10 +#define PCH_BIT_BRP 0 +#define PCH_BIT_SJW 6 +#define PCH_BIT_TSEG1 8 +#define PCH_BIT_TSEG2 12 +#define PCH_BIT_BRPE_BRPE 6 +#define PCH_MSK_BITT_BRP 0x3f +#define PCH_MSK_BRPE_BRPE 0x3c0 +#define PCH_MSK_CTRL_IE_SIE_EIE 0x07 +#define PCH_COUNTER_LIMIT 10 #define PCH_CAN_CLK 50000000 /* 50MHz */ @@ -181,14 +168,14 @@ struct pch_can_priv { struct can_priv can; unsigned int can_num; struct pci_dev *dev; - unsigned int tx_enable[MAX_MSG_OBJ]; - unsigned int rx_enable[MAX_MSG_OBJ]; - unsigned int rx_link[MAX_MSG_OBJ]; + unsigned int tx_enable[PCH_MAX_MSG_OBJ]; + unsigned int rx_enable[PCH_MAX_MSG_OBJ]; + unsigned int rx_link[PCH_MAX_MSG_OBJ]; unsigned int int_enables; unsigned int int_stat; struct net_device *ndev; spinlock_t msgif_reg_lock; /* Message Interface Registers Access Lock*/ - unsigned int msg_obj[MAX_MSG_OBJ]; + unsigned int msg_obj[PCH_MAX_MSG_OBJ]; struct pch_can_regs __iomem *regs; struct napi_struct napi; unsigned int tx_obj; /* Point next Tx Obj index */ @@ -228,11 +215,11 @@ static void pch_can_set_run_mode(struct pch_can_priv *priv, { switch (mode) { case PCH_CAN_RUN: - pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_INIT); + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_INIT); break; case PCH_CAN_STOP: - pch_can_bit_set(&priv->regs->cont, CAN_CTRL_INIT); + pch_can_bit_set(&priv->regs->cont, PCH_CTRL_INIT); break; default: @@ -246,30 +233,30 @@ static void pch_can_set_optmode(struct pch_can_priv *priv) u32 reg_val = ioread32(&priv->regs->opt); if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) - reg_val |= CAN_OPT_SILENT; + reg_val |= PCH_OPT_SILENT; if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) - reg_val |= CAN_OPT_LBACK; + reg_val |= PCH_OPT_LBACK; - pch_can_bit_set(&priv->regs->cont, CAN_CTRL_OPT); + pch_can_bit_set(&priv->regs->cont, PCH_CTRL_OPT); iowrite32(reg_val, &priv->regs->opt); } static void pch_can_set_int_custom(struct pch_can_priv *priv) { /* Clearing the IE, SIE and EIE bits of Can control register. */ - pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); /* Appropriately setting them. */ pch_can_bit_set(&priv->regs->cont, - ((priv->int_enables & MSK_CTRL_IE_SIE_EIE) << 1)); + ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1)); } /* This function retrieves interrupt enabled for the CAN device. */ static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables) { /* Obtaining the status of IE, SIE and EIE interrupt bits. */ - *enables = ((ioread32(&priv->regs->cont) & CAN_CTRL_IE_SIE_EIE) >> 1); + *enables = ((ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1); } static void pch_can_set_int_enables(struct pch_can_priv *priv, @@ -277,19 +264,19 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, { switch (interrupt_no) { case PCH_CAN_ENABLE: - pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE); + pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE); break; case PCH_CAN_DISABLE: - pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE); + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE); break; case PCH_CAN_ALL: - pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); + pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); break; case PCH_CAN_NONE: - pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); break; default: @@ -300,12 +287,12 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num) { - u32 counter = COUNTER_LIMIT; + u32 counter = PCH_COUNTER_LIMIT; u32 ifx_creq; iowrite32(num, creq_addr); while (counter) { - ifx_creq = ioread32(creq_addr) & CAN_IF_CREQ_BUSY; + ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY; if (!ifx_creq) break; counter--; @@ -322,22 +309,22 @@ static void pch_can_set_rx_enable(struct pch_can_priv *priv, u32 buff_num, spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the receive buffer data from RAM to Interface1 registers */ - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if1_cmask); - if (set == ENABLE) { + if (set == PCH_ENABLE) { /* Setting the MsgVal and RxIE bits */ - pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE); - pch_can_bit_set(&priv->regs->if1_id2, CAN_ID_MSGVAL); + pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); + pch_can_bit_set(&priv->regs->if1_id2, PCH_ID_MSGVAL); - } else if (set == DISABLE) { + } else if (set == PCH_DISABLE) { /* Resetting the MsgVal and RxIE bits */ - pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE); - pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID_MSGVAL); + pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); + pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID_MSGVAL); } pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); @@ -350,8 +337,8 @@ static void pch_can_rx_enable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as receivers. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, ENABLE); + if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) + pch_can_set_rx_enable(priv, i + 1, PCH_ENABLE); } } @@ -361,8 +348,8 @@ static void pch_can_rx_disable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as receivers. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, DISABLE); + if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) + pch_can_set_rx_enable(priv, i + 1, PCH_DISABLE); } } @@ -373,22 +360,22 @@ static void pch_can_set_tx_enable(struct pch_can_priv *priv, u32 buff_num, spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the Msg buffer from Message RAM to Interface2 registers. */ - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); /* Setting the IF2CMASK register for accessing the MsgVal and TxIE bits */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if2_cmask); - if (set == ENABLE) { + if (set == PCH_ENABLE) { /* Setting the MsgVal and TxIE bits */ - pch_can_bit_set(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE); - pch_can_bit_set(&priv->regs->if2_id2, CAN_ID_MSGVAL); - } else if (set == DISABLE) { + pch_can_bit_set(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); + pch_can_bit_set(&priv->regs->if2_id2, PCH_ID_MSGVAL); + } else if (set == PCH_DISABLE) { /* Resetting the MsgVal and TxIE bits. */ - pch_can_bit_clear(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE); - pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID_MSGVAL); + pch_can_bit_clear(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); + pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID_MSGVAL); } pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); @@ -401,8 +388,8 @@ static void pch_can_tx_enable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as transmit object. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, ENABLE); + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) + pch_can_set_tx_enable(priv, i + 1, PCH_ENABLE); } } @@ -412,8 +399,8 @@ static void pch_can_tx_disable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as transmit object. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, DISABLE); + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) + pch_can_set_tx_enable(priv, i + 1, PCH_DISABLE); } } @@ -423,15 +410,15 @@ static void pch_can_get_rx_enable(struct pch_can_priv *priv, u32 buff_num, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); - if (((ioread32(&priv->regs->if1_id2)) & CAN_ID_MSGVAL) && + if (((ioread32(&priv->regs->if1_id2)) & PCH_ID_MSGVAL) && ((ioread32(&priv->regs->if1_mcont)) & - CAN_IF_MCONT_RXIE)) - *enable = ENABLE; + PCH_IF_MCONT_RXIE)) + *enable = PCH_ENABLE; else - *enable = DISABLE; + *enable = PCH_DISABLE; spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -441,15 +428,15 @@ static void pch_can_get_tx_enable(struct pch_can_priv *priv, u32 buff_num, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); - if (((ioread32(&priv->regs->if2_id2)) & CAN_ID_MSGVAL) && + if (((ioread32(&priv->regs->if2_id2)) & PCH_ID_MSGVAL) && ((ioread32(&priv->regs->if2_mcont)) & - CAN_IF_MCONT_TXIE)) { - *enable = ENABLE; + PCH_IF_MCONT_TXIE)) { + *enable = PCH_ENABLE; } else { - *enable = DISABLE; + *enable = PCH_DISABLE; } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -465,13 +452,13 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL, &priv->regs->if1_cmask); - if (set == ENABLE) - pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->if1_cmask); + if (set == PCH_ENABLE) + pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); else - pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB); + pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -483,13 +470,13 @@ static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); - if (ioread32(&priv->regs->if1_mcont) & CAN_IF_MCONT_EOB) - *link = DISABLE; + if (ioread32(&priv->regs->if1_mcont) & PCH_IF_MCONT_EOB) + *link = PCH_DISABLE; else - *link = ENABLE; + *link = PCH_ENABLE; spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -498,7 +485,7 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) int i; for (i = 0; i < PCH_RX_OBJ_NUM; i++) { - iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if1_cmask); iowrite32(0xffff, &priv->regs->if1_mask1); iowrite32(0xffff, &priv->regs->if1_mask2); iowrite32(0x0, &priv->regs->if1_id1); @@ -508,14 +495,14 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if1_dataa2); iowrite32(0x0, &priv->regs->if1_datab1); iowrite32(0x0, &priv->regs->if1_datab2); - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | - CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); } for (i = i; i < PCH_OBJ_NUM; i++) { - iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if2_cmask); + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if2_cmask); iowrite32(0xffff, &priv->regs->if2_mask1); iowrite32(0xffff, &priv->regs->if2_mask2); iowrite32(0x0, &priv->regs->if2_id1); @@ -525,8 +512,8 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if2_dataa2); iowrite32(0x0, &priv->regs->if2_datab1); iowrite32(0x0, &priv->regs->if2_datab2); - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | - CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); } @@ -540,8 +527,8 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) spin_lock_irqsave(&priv->msgif_reg_lock, flags); for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_RX) { - iowrite32(CAN_CMASK_RX_TX_GET, + if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); @@ -549,48 +536,48 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if1_id2); pch_can_bit_set(&priv->regs->if1_mcont, - CAN_IF_MCONT_UMASK); + PCH_IF_MCONT_UMASK); /* Set FIFO mode set to 0 except last Rx Obj*/ pch_can_bit_clear(&priv->regs->if1_mcont, - CAN_IF_MCONT_EOB); + PCH_IF_MCONT_EOB); /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ if (i == (PCH_RX_OBJ_NUM - 1)) pch_can_bit_set(&priv->regs->if1_mcont, - CAN_IF_MCONT_EOB); + PCH_IF_MCONT_EOB); iowrite32(0, &priv->regs->if1_mask1); pch_can_bit_clear(&priv->regs->if1_mask2, - 0x1fff | CAN_MASK2_MDIR_MXTD); + 0x1fff | PCH_MASK2_MDIR_MXTD); /* Setting CMASK for writing */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | - CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); - } else if (priv->msg_obj[i] == MSG_OBJ_TX) { - iowrite32(CAN_CMASK_RX_TX_GET, + } else if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); /* Resetting DIR bit for reception */ iowrite32(0x0, &priv->regs->if2_id1); iowrite32(0x0, &priv->regs->if2_id2); - pch_can_bit_set(&priv->regs->if2_id2, CAN_ID2_DIR); + pch_can_bit_set(&priv->regs->if2_id2, PCH_ID2_DIR); /* Setting EOB bit for transmitter */ - iowrite32(CAN_IF_MCONT_EOB, &priv->regs->if2_mcont); + iowrite32(PCH_IF_MCONT_EOB, &priv->regs->if2_mcont); pch_can_bit_set(&priv->regs->if2_mcont, - CAN_IF_MCONT_UMASK); + PCH_IF_MCONT_UMASK); iowrite32(0, &priv->regs->if2_mask1); pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff); /* Setting CMASK for writing */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | - CAN_CMASK_ARB | CAN_CMASK_CTRL, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); @@ -632,39 +619,39 @@ static void pch_can_release(struct pch_can_priv *priv) /* This function clears interrupt(s) from the CAN device. */ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) { - if (mask == CAN_STATUS_INT) { + if (mask == PCH_STATUS_INT) { ioread32(&priv->regs->stat); return; } /* Clear interrupt for transmit object */ - if (priv->msg_obj[mask - 1] == MSG_OBJ_TX) { + if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_TX) { /* Setting CMASK for clearing interrupts for frame transmission. */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, &priv->regs->if2_cmask); /* Resetting the ID registers. */ pch_can_bit_set(&priv->regs->if2_id2, - CAN_ID2_DIR | (0x7ff << 2)); + PCH_ID2_DIR | (0x7ff << 2)); iowrite32(0x0, &priv->regs->if2_id1); /* Claring NewDat, TxRqst & IntPnd */ pch_can_bit_clear(&priv->regs->if2_mcont, - CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND | - CAN_IF_MCONT_TXRQXT); + PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | + PCH_IF_MCONT_TXRQXT); pch_can_check_if_busy(&priv->regs->if2_creq, mask); - } else if (priv->msg_obj[mask - 1] == MSG_OBJ_RX) { + } else if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_RX) { /* Setting CMASK for clearing the reception interrupts. */ - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB, + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, &priv->regs->if1_cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR); + pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); /* Clearing NewDat & IntPnd */ pch_can_bit_clear(&priv->regs->if1_mcont, - CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND); + PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); pch_can_check_if_busy(&priv->regs->if1_creq, mask); } @@ -712,9 +699,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) priv->can.can_stats.error_warning++; cf->can_id |= CAN_ERR_CRTL; errc = ioread32(&priv->regs->errc); - if (((errc & CAN_REC) >> 8) > 96) + if (((errc & PCH_REC) >> 8) > 96) cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; - if ((errc & CAN_TEC) > 96) + if ((errc & PCH_TEC) > 96) cf->data[1] |= CAN_ERR_CRTL_TX_WARNING; dev_warn(&ndev->dev, "%s -> Error Counter is more than 96.\n", __func__); @@ -725,9 +712,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) state = CAN_STATE_ERROR_PASSIVE; cf->can_id |= CAN_ERR_CRTL; errc = ioread32(&priv->regs->errc); - if (((errc & CAN_REC) >> 8) > 127) + if (((errc & PCH_REC) >> 8) > 127) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; - if ((errc & CAN_TEC) > 127) + if ((errc & PCH_TEC) > 127) cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; dev_err(&ndev->dev, "%s -> CAN controller is ERROR PASSIVE .\n", __func__); @@ -795,20 +782,20 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) struct net_device_stats *stats = &(priv->ndev->stats); /* Reading the messsage object from the Message RAM */ - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, int_stat); /* Reading the MCONT register. */ reg = ioread32(&priv->regs->if1_mcont); reg &= 0xffff; - for (k = int_stat; !(reg & CAN_IF_MCONT_EOB); k++) { + for (k = int_stat; !(reg & PCH_IF_MCONT_EOB); k++) { /* If MsgLost bit set. */ - if (reg & CAN_IF_MCONT_MSGLOST) { + if (reg & PCH_IF_MCONT_MSGLOST) { dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n"); pch_can_bit_clear(&priv->regs->if1_mcont, - CAN_IF_MCONT_MSGLOST); - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL, + PCH_IF_MCONT_MSGLOST); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, k); @@ -828,7 +815,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) rcv_pkts++; goto RX_NEXT; } - if (!(reg & CAN_IF_MCONT_NEWDAT)) + if (!(reg & PCH_IF_MCONT_NEWDAT)) goto RX_NEXT; skb = alloc_can_skb(priv->ndev, &cf); @@ -836,7 +823,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) return -ENOMEM; /* Get Received data */ - ide = ((ioread32(&priv->regs->if1_id2)) & CAN_ID2_XTD) >> 14; + ide = ((ioread32(&priv->regs->if1_id2)) & PCH_ID2_XTD) >> 14; if (ide) { id = (ioread32(&priv->regs->if1_id1) & 0xffff); id |= (((ioread32(&priv->regs->if1_id2)) & @@ -848,7 +835,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) cf->can_id = (id & CAN_SFF_MASK); } - rtr = (ioread32(&priv->regs->if1_id2) & CAN_ID2_DIR); + rtr = (ioread32(&priv->regs->if1_id2) & PCH_ID2_DIR); if (rtr) { cf->can_dlc = 0; cf->can_id |= CAN_RTR_FLAG; @@ -871,15 +858,15 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) stats->rx_bytes += cf->can_dlc; if (k < PCH_FIFO_THRESH) { - iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | - CAN_CMASK_ARB, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | + PCH_CMASK_ARB, &priv->regs->if1_cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR); + pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); /* Clearing NewDat & IntPnd */ pch_can_bit_clear(&priv->regs->if1_mcont, - CAN_IF_MCONT_INTPND); + PCH_IF_MCONT_INTPND); pch_can_check_if_busy(&priv->regs->if1_creq, k); } else if (k > PCH_FIFO_THRESH) { pch_can_int_clr(priv, k); @@ -890,7 +877,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) } RX_NEXT: /* Reading the messsage object from the Message RAM */ - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, k + 1); reg = ioread32(&priv->regs->if1_mcont); } @@ -913,7 +900,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) return 0; INT_STAT: - if (int_stat == CAN_STATUS_INT) { + if (int_stat == PCH_STATUS_INT) { reg_stat = ioread32(&priv->regs->stat); if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) { if ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) @@ -922,7 +909,7 @@ INT_STAT: if (reg_stat & PCH_TX_OK) { spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, ioread32(&priv->regs->intr)); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -933,7 +920,7 @@ INT_STAT: pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK); int_stat = pch_can_int_pending(priv); - if (int_stat == CAN_STATUS_INT) + if (int_stat == PCH_STATUS_INT) goto INT_STAT; } @@ -945,14 +932,14 @@ MSG_OBJ: if (rcv_pkts < 0) return 0; } else if ((int_stat > PCH_RX_OBJ_NUM) && (int_stat <= PCH_OBJ_NUM)) { - if (priv->msg_obj[int_stat - 1] == MSG_OBJ_TX) { + if (priv->msg_obj[int_stat - 1] == PCH_MSG_OBJ_TX) { /* Handle transmission interrupt */ can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1); spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(CAN_CMASK_RX_TX_GET | CAN_CMASK_CLRINTPND, + iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, &priv->regs->if2_cmask); dlc = ioread32(&priv->regs->if2_mcont) & - CAN_IF_MCONT_DLC; + PCH_IF_MCONT_DLC; pch_can_check_if_busy(&priv->regs->if2_creq, int_stat); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (dlc > 8) @@ -963,7 +950,7 @@ MSG_OBJ: } int_stat = pch_can_int_pending(priv); - if (int_stat == CAN_STATUS_INT) + if (int_stat == PCH_STATUS_INT) goto INT_STAT; else if (int_stat >= 1 && int_stat <= 32) goto MSG_OBJ; @@ -983,17 +970,17 @@ static int pch_set_bittiming(struct net_device *ndev) u32 brp; /* Setting the CCE bit for accessing the Can Timing register. */ - pch_can_bit_set(&priv->regs->cont, CAN_CTRL_CCE); + pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE); brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1; - canbit = brp & MSK_BITT_BRP; - canbit |= (bt->sjw - 1) << BIT_BITT_SJW; - canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << BIT_BITT_TSEG1; - canbit |= (bt->phase_seg2 - 1) << BIT_BITT_TSEG2; - bepe = (brp & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE; + canbit = brp & PCH_MSK_BITT_BRP; + canbit |= (bt->sjw - 1) << PCH_BIT_SJW; + canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1; + canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2; + bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE; iowrite32(canbit, &priv->regs->bitt); iowrite32(bepe, &priv->regs->brpe); - pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_CCE); + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE); return 0; } @@ -1137,19 +1124,19 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the Msg Obj from the Msg RAM to the Interface register. */ - iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); /* Setting the CMASK register. */ - pch_can_bit_set(&priv->regs->if2_cmask, CAN_CMASK_ALL); + pch_can_bit_set(&priv->regs->if2_cmask, PCH_CMASK_ALL); /* If ID extended is set. */ pch_can_bit_clear(&priv->regs->if2_id1, 0xffff); - pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | CAN_ID2_XTD); + pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | PCH_ID2_XTD); if (cf->can_id & CAN_EFF_FLAG) { pch_can_bit_set(&priv->regs->if2_id1, cf->can_id & 0xffff); pch_can_bit_set(&priv->regs->if2_id2, - ((cf->can_id >> 16) & 0x1fff) | CAN_ID2_XTD); + ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD); } else { pch_can_bit_set(&priv->regs->if2_id1, 0); pch_can_bit_set(&priv->regs->if2_id2, @@ -1158,7 +1145,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) /* If remote frame has to be transmitted.. */ if (cf->can_id & CAN_RTR_FLAG) - pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID2_DIR); + pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID2_DIR); for (i = 0, j = 0; i < cf->can_dlc; j++) { iowrite32(le32_to_cpu(cf->data[i++]), @@ -1177,12 +1164,12 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) /* Clearing IntPend, NewDat & TxRqst */ pch_can_bit_clear(&priv->regs->if2_mcont, - CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND | - CAN_IF_MCONT_TXRQXT); + PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | + PCH_IF_MCONT_TXRQXT); /* Setting NewDat, TxRqst bits */ pch_can_bit_set(&priv->regs->if2_mcont, - CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_TXRQXT); + PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT); pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); @@ -1245,7 +1232,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Tx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_TX) + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) pch_can_get_tx_enable(priv, i + 1, &(priv->tx_enable[i])); } @@ -1255,7 +1242,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Rx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_RX) { + if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { pch_can_get_rx_enable(priv, i + 1, &(priv->rx_enable[i])); pch_can_get_rx_buffer_link(priv, i + 1, @@ -1313,7 +1300,7 @@ static int pch_can_resume(struct pci_dev *pdev) /* Enabling the transmit buffer. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_TX) { + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { pch_can_set_tx_enable(priv, i + 1, priv->tx_enable[i]); } @@ -1321,7 +1308,7 @@ static int pch_can_resume(struct pci_dev *pdev) /* Configuring the receive buffer and enabling them. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == MSG_OBJ_RX) { + if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { /* Restore buffer link */ pch_can_set_rx_buffer_link(priv, i + 1, priv->rx_link[i]); @@ -1349,8 +1336,8 @@ static int pch_can_get_berr_counter(const struct net_device *dev, { struct pch_can_priv *priv = netdev_priv(dev); - bec->txerr = ioread32(&priv->regs->errc) & CAN_TEC; - bec->rxerr = (ioread32(&priv->regs->errc) & CAN_REC) >> 8; + bec->txerr = ioread32(&priv->regs->errc) & PCH_TEC; + bec->rxerr = (ioread32(&priv->regs->errc) & PCH_REC) >> 8; return 0; } @@ -1410,10 +1397,10 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ for (index = 0; index < PCH_RX_OBJ_NUM;) - priv->msg_obj[index++] = MSG_OBJ_RX; + priv->msg_obj[index++] = PCH_MSG_OBJ_RX; for (index = index; index < PCH_OBJ_NUM;) - priv->msg_obj[index++] = MSG_OBJ_TX; + priv->msg_obj[index++] = PCH_MSG_OBJ_TX; netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_NUM); -- cgit v1.2.3-59-g8ed1b From 0a80410dc53cf68e56456bef1ca66949b87412f9 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Wed, 17 Nov 2010 14:06:25 +0000 Subject: can: EG20T PCH: use BIT(X) Replace bit assignment value to BIT(X). For easy to readable/identifiable, replace all bit assigned macros to BIT(X) Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 73 ++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c523e3dd5d10..238622a04bc1 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -38,50 +38,51 @@ #define PCH_ENABLE 1 /* The enable flag */ #define PCH_DISABLE 0 /* The disable flag */ -#define PCH_CTRL_INIT 0x0001 /* The INIT bit of CANCONT register. */ -#define PCH_CTRL_IE 0x0002 /* The IE bit of CAN control register */ -#define PCH_CTRL_IE_SIE_EIE 0x000e -#define PCH_CTRL_CCE 0x0040 -#define PCH_CTRL_OPT 0x0080 /* The OPT bit of CANCONT register. */ -#define PCH_OPT_SILENT 0x0008 /* The Silent bit of CANOPT reg. */ -#define PCH_OPT_LBACK 0x0010 /* The LoopBack bit of CANOPT reg. */ +#define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */ +#define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */ +#define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1)) +#define PCH_CTRL_CCE BIT(6) +#define PCH_CTRL_OPT BIT(7) /* The OPT bit of CANCONT register. */ +#define PCH_OPT_SILENT BIT(3) /* The Silent bit of CANOPT reg. */ +#define PCH_OPT_LBACK BIT(4) /* The LoopBack bit of CANOPT reg. */ + #define PCH_CMASK_RX_TX_SET 0x00f3 #define PCH_CMASK_RX_TX_GET 0x0073 #define PCH_CMASK_ALL 0xff -#define PCH_CMASK_RDWR 0x80 -#define PCH_CMASK_ARB 0x20 -#define PCH_CMASK_CTRL 0x10 -#define PCH_CMASK_MASK 0x40 -#define PCH_CMASK_NEWDAT 0x04 -#define PCH_CMASK_CLRINTPND 0x08 -#define PCH_IF_MCONT_NEWDAT 0x8000 -#define PCH_IF_MCONT_INTPND 0x2000 -#define PCH_IF_MCONT_UMASK 0x1000 -#define PCH_IF_MCONT_TXIE 0x0800 -#define PCH_IF_MCONT_RXIE 0x0400 -#define PCH_IF_MCONT_RMTEN 0x0200 -#define PCH_IF_MCONT_TXRQXT 0x0100 -#define PCH_IF_MCONT_EOB 0x0080 -#define PCH_IF_MCONT_DLC 0x000f -#define PCH_IF_MCONT_MSGLOST 0x4000 -#define PCH_MASK2_MDIR_MXTD 0xc000 -#define PCH_ID2_DIR 0x2000 -#define PCH_ID2_XTD 0x4000 -#define PCH_ID_MSGVAL 0x8000 -#define PCH_IF_CREQ_BUSY 0x8000 +#define PCH_CMASK_NEWDAT BIT(2) +#define PCH_CMASK_CLRINTPND BIT(3) +#define PCH_CMASK_CTRL BIT(4) +#define PCH_CMASK_ARB BIT(5) +#define PCH_CMASK_MASK BIT(6) +#define PCH_CMASK_RDWR BIT(7) +#define PCH_IF_MCONT_NEWDAT BIT(15) +#define PCH_IF_MCONT_MSGLOST BIT(14) +#define PCH_IF_MCONT_INTPND BIT(13) +#define PCH_IF_MCONT_UMASK BIT(12) +#define PCH_IF_MCONT_TXIE BIT(11) +#define PCH_IF_MCONT_RXIE BIT(10) +#define PCH_IF_MCONT_RMTEN BIT(9) +#define PCH_IF_MCONT_TXRQXT BIT(8) +#define PCH_IF_MCONT_EOB BIT(7) +#define PCH_IF_MCONT_DLC (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define PCH_MASK2_MDIR_MXTD (BIT(14) | BIT(15)) +#define PCH_ID2_DIR BIT(13) +#define PCH_ID2_XTD BIT(14) +#define PCH_ID_MSGVAL BIT(15) +#define PCH_IF_CREQ_BUSY BIT(15) #define PCH_STATUS_INT 0x8000 #define PCH_REC 0x00007f00 #define PCH_TEC 0x000000ff -#define PCH_RX_OK 0x00000010 -#define PCH_TX_OK 0x00000008 -#define PCH_BUS_OFF 0x00000080 -#define PCH_EWARN 0x00000040 -#define PCH_EPASSIV 0x00000020 -#define PCH_LEC0 0x00000001 -#define PCH_LEC1 0x00000002 -#define PCH_LEC2 0x00000004 +#define PCH_TX_OK BIT(3) +#define PCH_RX_OK BIT(4) +#define PCH_EPASSIV BIT(5) +#define PCH_EWARN BIT(6) +#define PCH_BUS_OFF BIT(7) +#define PCH_LEC0 BIT(0) +#define PCH_LEC1 BIT(1) +#define PCH_LEC2 BIT(2) #define PCH_LEC_ALL (PCH_LEC0 | PCH_LEC1 | PCH_LEC2) #define PCH_STUF_ERR PCH_LEC0 #define PCH_FORM_ERR PCH_LEC1 -- cgit v1.2.3-59-g8ed1b From 93aaae2e01e57483256b7da05c9a7ebd65ad4686 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 19 Nov 2010 09:49:59 -0800 Subject: filter: optimize sk_run_filter Remove pc variable to avoid arithmetic to compute fentry at each filter instruction. Jumps directly manipulate fentry pointer. As the last instruction of filter[] is guaranteed to be a RETURN, and all jumps are before the last instruction, we dont need to check filter bounds (number of instructions in filter array) at each iteration, so we remove it from sk_run_filter() params. On x86_32 remove f_k var introduced in commit 57fe93b374a6b871 (filter: make sure filters dont read uninitialized memory) Note : We could use a CONFIG_ARCH_HAS_{FEW|MANY}_REGISTERS in order to avoid too many ifdefs in this code. This helps compiler to use cpu registers to hold fentry and A accumulator. On x86_32, this saves 401 bytes, and more important, sk_run_filter() runs much faster because less register pressure (One less conditional branch per BPF instruction) # size net/core/filter.o net/core/filter_pre.o text data bss dec hex filename 2948 0 0 2948 b84 net/core/filter.o 3349 0 0 3349 d15 net/core/filter_pre.o on x86_64 : # size net/core/filter.o net/core/filter_pre.o text data bss dec hex filename 5173 0 0 5173 1435 net/core/filter.o 5224 0 0 5224 1468 net/core/filter_pre.o Signed-off-by: Eric Dumazet Acked-by: Changli Gao Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_ppp.c | 14 +++---- drivers/net/ppp_generic.c | 12 ++---- include/linux/filter.h | 2 +- net/core/filter.c | 93 +++++++++++++++++++++++---------------------- net/core/timestamping.c | 2 +- net/packet/af_packet.c | 2 +- 6 files changed, 61 insertions(+), 64 deletions(-) diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 97c5cc2997f5..9e8162c80bb0 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -1147,15 +1147,14 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff } if (is->pass_filter - && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0) { + && sk_run_filter(skb, is->pass_filter) == 0) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); kfree_skb(skb); return; } if (!(is->active_filter - && sk_run_filter(skb, is->active_filter, - is->active_len) == 0)) { + && sk_run_filter(skb, is->active_filter) == 0)) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1294,15 +1293,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) } if (ipt->pass_filter - && sk_run_filter(skb, ipt->pass_filter, ipt->pass_len) == 0) { + && sk_run_filter(skb, ipt->pass_filter) == 0) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); kfree_skb(skb); goto unlock; } if (!(ipt->active_filter - && sk_run_filter(skb, ipt->active_filter, - ipt->active_len) == 0)) { + && sk_run_filter(skb, ipt->active_filter) == 0)) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1492,9 +1490,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) } drop |= is->pass_filter - && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0; + && sk_run_filter(skb, is->pass_filter) == 0; drop |= is->active_filter - && sk_run_filter(skb, is->active_filter, is->active_len) == 0; + && sk_run_filter(skb, is->active_filter) == 0; skb_push(skb, IPPP_MAX_HEADER - 4); return drop; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 09cf56d0416a..0c91598ae280 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1136,8 +1136,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) a four-byte PPP header on each packet */ *skb_push(skb, 2) = 1; if (ppp->pass_filter && - sk_run_filter(skb, ppp->pass_filter, - ppp->pass_len) == 0) { + sk_run_filter(skb, ppp->pass_filter) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: outbound frame not passed\n"); kfree_skb(skb); @@ -1145,8 +1144,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) } /* if this packet passes the active filter, record the time */ if (!(ppp->active_filter && - sk_run_filter(skb, ppp->active_filter, - ppp->active_len) == 0)) + sk_run_filter(skb, ppp->active_filter) == 0)) ppp->last_xmit = jiffies; skb_pull(skb, 2); #else @@ -1758,8 +1756,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) *skb_push(skb, 2) = 0; if (ppp->pass_filter && - sk_run_filter(skb, ppp->pass_filter, - ppp->pass_len) == 0) { + sk_run_filter(skb, ppp->pass_filter) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: inbound frame " "not passed\n"); @@ -1767,8 +1764,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) return; } if (!(ppp->active_filter && - sk_run_filter(skb, ppp->active_filter, - ppp->active_len) == 0)) + sk_run_filter(skb, ppp->active_filter) == 0)) ppp->last_recv = jiffies; __skb_pull(skb, 2); } else diff --git a/include/linux/filter.h b/include/linux/filter.h index 151f5d703b7e..447a775878fb 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -147,7 +147,7 @@ struct sock; extern int sk_filter(struct sock *sk, struct sk_buff *skb); extern unsigned int sk_run_filter(struct sk_buff *skb, - struct sock_filter *filter, int flen); + const struct sock_filter *filter); extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, int flen); diff --git a/net/core/filter.c b/net/core/filter.c index 15a545d39cd3..9e77b3c816c5 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -137,7 +137,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) rcu_read_lock_bh(); filter = rcu_dereference_bh(sk->sk_filter); if (filter) { - unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len); + unsigned int pkt_len = sk_run_filter(skb, filter->insns); err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; } @@ -151,14 +151,15 @@ EXPORT_SYMBOL(sk_filter); * sk_run_filter - run a filter on a socket * @skb: buffer to run the filter on * @filter: filter to apply - * @flen: length of filter * * Decode and apply filter instructions to the skb->data. - * Return length to keep, 0 for none. skb is the data we are - * filtering, filter is the array of filter instructions, and - * len is the number of filter blocks in the array. + * Return length to keep, 0 for none. @skb is the data we are + * filtering, @filter is the array of filter instructions. + * Because all jumps are guaranteed to be before last instruction, + * and last instruction guaranteed to be a RET, we dont need to check + * flen. (We used to pass to this function the length of filter) */ -unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) +unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry) { void *ptr; u32 A = 0; /* Accumulator */ @@ -167,34 +168,36 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int unsigned long memvalid = 0; u32 tmp; int k; - int pc; BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG); /* * Process array of filter instructions. */ - for (pc = 0; pc < flen; pc++) { - const struct sock_filter *fentry = &filter[pc]; - u32 f_k = fentry->k; + for (;; fentry++) { +#if defined(CONFIG_X86_32) +#define K (fentry->k) +#else + const u32 K = fentry->k; +#endif switch (fentry->code) { case BPF_S_ALU_ADD_X: A += X; continue; case BPF_S_ALU_ADD_K: - A += f_k; + A += K; continue; case BPF_S_ALU_SUB_X: A -= X; continue; case BPF_S_ALU_SUB_K: - A -= f_k; + A -= K; continue; case BPF_S_ALU_MUL_X: A *= X; continue; case BPF_S_ALU_MUL_K: - A *= f_k; + A *= K; continue; case BPF_S_ALU_DIV_X: if (X == 0) @@ -202,64 +205,64 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int A /= X; continue; case BPF_S_ALU_DIV_K: - A /= f_k; + A /= K; continue; case BPF_S_ALU_AND_X: A &= X; continue; case BPF_S_ALU_AND_K: - A &= f_k; + A &= K; continue; case BPF_S_ALU_OR_X: A |= X; continue; case BPF_S_ALU_OR_K: - A |= f_k; + A |= K; continue; case BPF_S_ALU_LSH_X: A <<= X; continue; case BPF_S_ALU_LSH_K: - A <<= f_k; + A <<= K; continue; case BPF_S_ALU_RSH_X: A >>= X; continue; case BPF_S_ALU_RSH_K: - A >>= f_k; + A >>= K; continue; case BPF_S_ALU_NEG: A = -A; continue; case BPF_S_JMP_JA: - pc += f_k; + fentry += K; continue; case BPF_S_JMP_JGT_K: - pc += (A > f_k) ? fentry->jt : fentry->jf; + fentry += (A > K) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGE_K: - pc += (A >= f_k) ? fentry->jt : fentry->jf; + fentry += (A >= K) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JEQ_K: - pc += (A == f_k) ? fentry->jt : fentry->jf; + fentry += (A == K) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JSET_K: - pc += (A & f_k) ? fentry->jt : fentry->jf; + fentry += (A & K) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGT_X: - pc += (A > X) ? fentry->jt : fentry->jf; + fentry += (A > X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGE_X: - pc += (A >= X) ? fentry->jt : fentry->jf; + fentry += (A >= X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JEQ_X: - pc += (A == X) ? fentry->jt : fentry->jf; + fentry += (A == X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JSET_X: - pc += (A & X) ? fentry->jt : fentry->jf; + fentry += (A & X) ? fentry->jt : fentry->jf; continue; case BPF_S_LD_W_ABS: - k = f_k; + k = K; load_w: ptr = load_pointer(skb, k, 4, &tmp); if (ptr != NULL) { @@ -268,7 +271,7 @@ load_w: } break; case BPF_S_LD_H_ABS: - k = f_k; + k = K; load_h: ptr = load_pointer(skb, k, 2, &tmp); if (ptr != NULL) { @@ -277,7 +280,7 @@ load_h: } break; case BPF_S_LD_B_ABS: - k = f_k; + k = K; load_b: ptr = load_pointer(skb, k, 1, &tmp); if (ptr != NULL) { @@ -292,34 +295,34 @@ load_b: X = skb->len; continue; case BPF_S_LD_W_IND: - k = X + f_k; + k = X + K; goto load_w; case BPF_S_LD_H_IND: - k = X + f_k; + k = X + K; goto load_h; case BPF_S_LD_B_IND: - k = X + f_k; + k = X + K; goto load_b; case BPF_S_LDX_B_MSH: - ptr = load_pointer(skb, f_k, 1, &tmp); + ptr = load_pointer(skb, K, 1, &tmp); if (ptr != NULL) { X = (*(u8 *)ptr & 0xf) << 2; continue; } return 0; case BPF_S_LD_IMM: - A = f_k; + A = K; continue; case BPF_S_LDX_IMM: - X = f_k; + X = K; continue; case BPF_S_LD_MEM: - A = (memvalid & (1UL << f_k)) ? - mem[f_k] : 0; + A = (memvalid & (1UL << K)) ? + mem[K] : 0; continue; case BPF_S_LDX_MEM: - X = (memvalid & (1UL << f_k)) ? - mem[f_k] : 0; + X = (memvalid & (1UL << K)) ? + mem[K] : 0; continue; case BPF_S_MISC_TAX: X = A; @@ -328,16 +331,16 @@ load_b: A = X; continue; case BPF_S_RET_K: - return f_k; + return K; case BPF_S_RET_A: return A; case BPF_S_ST: - memvalid |= 1UL << f_k; - mem[f_k] = A; + memvalid |= 1UL << K; + mem[K] = A; continue; case BPF_S_STX: - memvalid |= 1UL << f_k; - mem[f_k] = X; + memvalid |= 1UL << K; + mem[K] = X; continue; default: WARN_ON(1); diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 0ae6c22da85b..dac7ed687f60 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c @@ -31,7 +31,7 @@ static unsigned int classify(struct sk_buff *skb) if (likely(skb->dev && skb->dev->phydev && skb->dev->phydev->drv)) - return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter)); + return sk_run_filter(skb, ptp_filter); else return PTP_CLASS_NONE; } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 20964560a0ed..b6372dd128d7 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -519,7 +519,7 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, rcu_read_lock_bh(); filter = rcu_dereference_bh(sk->sk_filter); if (filter != NULL) - res = sk_run_filter(skb, filter->insns, filter->len); + res = sk_run_filter(skb, filter->insns); rcu_read_unlock_bh(); return res; -- cgit v1.2.3-59-g8ed1b From 8c1592d68bc89248bfd0ee287648f41c1370d826 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Nov 2010 21:56:38 +0000 Subject: filter: cleanup codes[] init Starting the translated instruction to 1 instead of 0 allows us to remove one descrement at check time and makes codes[] array init cleaner. Signed-off-by: Eric Dumazet Acked-by: Changli Gao Signed-off-by: David S. Miller --- net/core/filter.c | 95 +++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 9e77b3c816c5..c0b68f7c8036 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -39,7 +39,7 @@ #include enum { - BPF_S_RET_K = 0, + BPF_S_RET_K = 1, BPF_S_RET_A, BPF_S_ALU_ADD_K, BPF_S_ALU_ADD_X, @@ -439,51 +439,51 @@ int sk_chk_filter(struct sock_filter *filter, int flen) * Invalid instructions are initialized to 0. */ static const u8 codes[] = { - [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K + 1, - [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X + 1, - [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K + 1, - [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X + 1, - [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K + 1, - [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X + 1, - [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X + 1, - [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K + 1, - [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X + 1, - [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K + 1, - [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X + 1, - [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K + 1, - [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X + 1, - [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K + 1, - [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X + 1, - [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG + 1, - [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS + 1, - [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS + 1, - [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS + 1, - [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN + 1, - [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND + 1, - [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND + 1, - [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND + 1, - [BPF_LD|BPF_IMM] = BPF_S_LD_IMM + 1, - [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN + 1, - [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH + 1, - [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM + 1, - [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX + 1, - [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA + 1, - [BPF_RET|BPF_K] = BPF_S_RET_K + 1, - [BPF_RET|BPF_A] = BPF_S_RET_A + 1, - [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K + 1, - [BPF_LD|BPF_MEM] = BPF_S_LD_MEM + 1, - [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM + 1, - [BPF_ST] = BPF_S_ST + 1, - [BPF_STX] = BPF_S_STX + 1, - [BPF_JMP|BPF_JA] = BPF_S_JMP_JA + 1, - [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K + 1, - [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X + 1, - [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K + 1, - [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X + 1, - [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K + 1, - [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X + 1, - [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K + 1, - [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X + 1, + [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K, + [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X, + [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K, + [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X, + [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K, + [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X, + [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X, + [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K, + [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X, + [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K, + [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X, + [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K, + [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X, + [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K, + [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X, + [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG, + [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS, + [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS, + [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS, + [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN, + [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND, + [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND, + [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND, + [BPF_LD|BPF_IMM] = BPF_S_LD_IMM, + [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN, + [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH, + [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM, + [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX, + [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA, + [BPF_RET|BPF_K] = BPF_S_RET_K, + [BPF_RET|BPF_A] = BPF_S_RET_A, + [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K, + [BPF_LD|BPF_MEM] = BPF_S_LD_MEM, + [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM, + [BPF_ST] = BPF_S_ST, + [BPF_STX] = BPF_S_STX, + [BPF_JMP|BPF_JA] = BPF_S_JMP_JA, + [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K, + [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X, + [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K, + [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X, + [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K, + [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X, + [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K, + [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X, }; int pc; @@ -498,8 +498,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) if (code >= ARRAY_SIZE(codes)) return -EINVAL; code = codes[code]; - /* Undo the '+ 1' in codes[] after validation. */ - if (!code--) + if (!code) return -EINVAL; /* Some instructions need special checks */ switch (code) { -- cgit v1.2.3-59-g8ed1b From c26aed40f4fd18f86bcc6aba557cab700b129b73 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Nov 2010 22:04:46 +0000 Subject: filter: use reciprocal divide At compile time, we can replace the DIV_K instruction (divide by a constant value) by a reciprocal divide. At exec time, the expensive divide is replaced by a multiply, a less expensive operation on most processors. Signed-off-by: Eric Dumazet Acked-by: Changli Gao Signed-off-by: David S. Miller --- net/core/filter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index c0b68f7c8036..23e0a2a9a4de 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -37,6 +37,7 @@ #include #include #include +#include enum { BPF_S_RET_K = 1, @@ -205,7 +206,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry A /= X; continue; case BPF_S_ALU_DIV_K: - A /= K; + A = reciprocal_divide(A, K); continue; case BPF_S_ALU_AND_X: A &= X; @@ -506,6 +507,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) /* check for division by zero */ if (ftest->k == 0) return -EINVAL; + ftest->k = reciprocal_value(ftest->k); break; case BPF_S_LD_MEM: case BPF_S_LDX_MEM: -- cgit v1.2.3-59-g8ed1b From 70be998c2b44f942f11383496622500136816acb Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:20:57 +0000 Subject: X25: pushdown bkl in ioctls Push down the bkl in the ioctls so they can be removed one at a time. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index f7af98dff409..c99029bc411c 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1357,14 +1357,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) void __user *argp = (void __user *)arg; int rc; - lock_kernel(); switch (cmd) { case TIOCOUTQ: { - int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); + int amount; + lock_kernel(); + amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); if (amount < 0) amount = 0; rc = put_user(amount, (unsigned int __user *)argp); + unlock_kernel(); break; } @@ -1375,23 +1377,29 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) * These two are safe on a single CPU system as * only user tasks fiddle here */ + lock_kernel(); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; rc = put_user(amount, (unsigned int __user *)argp); + unlock_kernel(); break; } case SIOCGSTAMP: rc = -EINVAL; + lock_kernel(); if (sk) rc = sock_get_timestamp(sk, (struct timeval __user *)argp); + unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; + lock_kernel(); if (sk) rc = sock_get_timestampns(sk, (struct timespec __user *)argp); + unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -1410,27 +1418,36 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = x25_route_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GSUBSCRIP: + lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GFACILITIES: { struct x25_facilities fac = x25->facilities; + lock_kernel(); rc = copy_to_user(argp, &fac, sizeof(fac)) ? -EFAULT : 0; + unlock_kernel(); break; } case SIOCX25SFACILITIES: { struct x25_facilities facilities; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&facilities, argp, sizeof(facilities))) break; @@ -1466,12 +1483,15 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25->facilities = facilities; rc = 0; + unlock_kernel(); break; } case SIOCX25GDTEFACILITIES: { + lock_kernel(); rc = copy_to_user(argp, &x25->dte_facilities, sizeof(x25->dte_facilities)); + unlock_kernel(); if (rc) rc = -EFAULT; break; @@ -1480,6 +1500,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SDTEFACILITIES: { struct x25_dte_facilities dtefacs; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) break; rc = -EINVAL; @@ -1496,13 +1517,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25->dte_facilities = dtefacs; rc = 0; + unlock_kernel(); break; } case SIOCX25GCALLUSERDATA: { struct x25_calluserdata cud = x25->calluserdata; + lock_kernel(); rc = copy_to_user(argp, &cud, sizeof(cud)) ? -EFAULT : 0; + unlock_kernel(); break; } @@ -1510,6 +1534,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) struct x25_calluserdata calluserdata; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&calluserdata, argp, sizeof(calluserdata))) break; @@ -1517,24 +1542,29 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (calluserdata.cudlength > X25_MAX_CUD_LEN) break; x25->calluserdata = calluserdata; + unlock_kernel(); rc = 0; break; } case SIOCX25GCAUSEDIAG: { struct x25_causediag causediag; + lock_kernel(); causediag = x25->causediag; rc = copy_to_user(argp, &causediag, sizeof(causediag)) ? -EFAULT : 0; + unlock_kernel(); break; } case SIOCX25SCAUSEDIAG: { struct x25_causediag causediag; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&causediag, argp, sizeof(causediag))) break; x25->causediag = causediag; + unlock_kernel(); rc = 0; break; @@ -1543,6 +1573,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SCUDMATCHLEN: { struct x25_subaddr sub_addr; rc = -EINVAL; + lock_kernel(); if(sk->sk_state != TCP_CLOSE) break; rc = -EFAULT; @@ -1553,21 +1584,25 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) break; x25->cudmatchlength = sub_addr.cudmatchlength; + unlock_kernel(); rc = 0; break; } case SIOCX25CALLACCPTAPPRV: { rc = -EINVAL; + lock_kernel(); if (sk->sk_state != TCP_CLOSE) break; clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); + unlock_kernel(); rc = 0; break; } case SIOCX25SENDCALLACCPT: { rc = -EINVAL; + lock_kernel(); if (sk->sk_state != TCP_ESTABLISHED) break; /* must call accptapprv above */ @@ -1575,6 +1610,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25_write_internal(sk, X25_CALL_ACCEPTED); x25->state = X25_STATE_3; + unlock_kernel(); rc = 0; break; } @@ -1583,7 +1619,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -ENOIOCTLCMD; break; } - unlock_kernel(); return rc; } -- cgit v1.2.3-59-g8ed1b From 1ecd66bf2ce5e0f2bc72ffdeed814bb0e55a60dc Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:20 +0000 Subject: X25: remove bkl in timestamp ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c99029bc411c..22597838cc76 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1387,19 +1387,15 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCGSTAMP: rc = -EINVAL; - lock_kernel(); if (sk) rc = sock_get_timestamp(sk, (struct timeval __user *)argp); - unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; - lock_kernel(); if (sk) rc = sock_get_timestampns(sk, (struct timespec __user *)argp); - unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -1689,19 +1685,15 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, break; case SIOCGSTAMP: rc = -EINVAL; - lock_kernel(); if (sk) rc = compat_sock_get_timestamp(sk, (struct timeval __user*)argp); - unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; - lock_kernel(); if (sk) rc = compat_sock_get_timestampns(sk, (struct timespec __user*)argp); - unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: -- cgit v1.2.3-59-g8ed1b From 54aafbd4989a684ca876e49bf3e6eb931654dc02 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:28 +0000 Subject: X25: remove bkl in inq and outq ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 22597838cc76..2f235a6cb3b1 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1361,12 +1361,10 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case TIOCOUTQ: { int amount; - lock_kernel(); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); if (amount < 0) amount = 0; rc = put_user(amount, (unsigned int __user *)argp); - unlock_kernel(); break; } @@ -1377,11 +1375,11 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) * These two are safe on a single CPU system as * only user tasks fiddle here */ - lock_kernel(); + lock_sock(sk); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; + release_sock(sk); rc = put_user(amount, (unsigned int __user *)argp); - unlock_kernel(); break; } -- cgit v1.2.3-59-g8ed1b From 0670b8ae66daf1d326c7bd10e73daff5f18fcf92 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:35 +0000 Subject: X25: remove bkl in routing ioctls Routing doesn't use the socket data and is protected by x25_route_list_lock Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2f235a6cb3b1..2351aceb296d 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1412,9 +1412,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = x25_route_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GSUBSCRIP: lock_kernel(); @@ -1710,9 +1708,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = x25_route_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GSUBSCRIP: lock_kernel(); -- cgit v1.2.3-59-g8ed1b From 09c5088e5c5993be217a2c85dca088147ffc9b72 Mon Sep 17 00:00:00 2001 From: Shreyas Bhatewara Date: Fri, 19 Nov 2010 10:55:24 +0000 Subject: net-next: Add multiqueue support to vmxnet3 driver Add multiqueue support to vmxnet3 driver This change adds multiqueue and thus receive side scaling support to vmxnet3 device driver. Number of rx queues is limited to 1 in cases where MSI is not configured or one MSIx vector is not available per rx queue Signed-off-by: Shreyas Bhatewara Reviewed-by: Bhavesh Davda Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 951 +++++++++++++++++++++++++++------- drivers/net/vmxnet3/vmxnet3_ethtool.c | 171 ++++-- drivers/net/vmxnet3/vmxnet3_int.h | 73 ++- 3 files changed, 921 insertions(+), 274 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 21314e06e6d7..65860a998321 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -44,6 +44,9 @@ MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table); static atomic_t devices_found; +#define VMXNET3_MAX_DEVICES 10 +static int enable_mq = 1; +static int irq_share_mode; /* * Enable/Disable the given intr @@ -99,7 +102,7 @@ vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events) static bool vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { - return netif_queue_stopped(adapter->netdev); + return tq->stopped; } @@ -107,7 +110,7 @@ static void vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = false; - netif_start_queue(adapter->netdev); + netif_start_subqueue(adapter->netdev, tq - adapter->tx_queue); } @@ -115,7 +118,7 @@ static void vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = false; - netif_wake_queue(adapter->netdev); + netif_wake_subqueue(adapter->netdev, (tq - adapter->tx_queue)); } @@ -124,7 +127,7 @@ vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = true; tq->num_stop++; - netif_stop_queue(adapter->netdev); + netif_stop_subqueue(adapter->netdev, (tq - adapter->tx_queue)); } @@ -135,6 +138,7 @@ static void vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) { u32 ret; + int i; VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK); ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); @@ -145,22 +149,28 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) if (!netif_carrier_ok(adapter->netdev)) netif_carrier_on(adapter->netdev); - if (affectTxQueue) - vmxnet3_tq_start(&adapter->tx_queue, adapter); + if (affectTxQueue) { + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_start(&adapter->tx_queue[i], + adapter); + } } else { printk(KERN_INFO "%s: NIC Link is Down\n", adapter->netdev->name); if (netif_carrier_ok(adapter->netdev)) netif_carrier_off(adapter->netdev); - if (affectTxQueue) - vmxnet3_tq_stop(&adapter->tx_queue, adapter); + if (affectTxQueue) { + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_stop(&adapter->tx_queue[i], adapter); + } } } static void vmxnet3_process_events(struct vmxnet3_adapter *adapter) { + int i; u32 events = le32_to_cpu(adapter->shared->ecr); if (!events) return; @@ -176,16 +186,18 @@ vmxnet3_process_events(struct vmxnet3_adapter *adapter) VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_QUEUE_STATUS); - if (adapter->tqd_start->status.stopped) { - printk(KERN_ERR "%s: tq error 0x%x\n", - adapter->netdev->name, - le32_to_cpu(adapter->tqd_start->status.error)); - } - if (adapter->rqd_start->status.stopped) { - printk(KERN_ERR "%s: rq error 0x%x\n", - adapter->netdev->name, - adapter->rqd_start->status.error); - } + for (i = 0; i < adapter->num_tx_queues; i++) + if (adapter->tqd_start[i].status.stopped) + dev_err(&adapter->netdev->dev, + "%s: tq[%d] error 0x%x\n", + adapter->netdev->name, i, le32_to_cpu( + adapter->tqd_start[i].status.error)); + for (i = 0; i < adapter->num_rx_queues; i++) + if (adapter->rqd_start[i].status.stopped) + dev_err(&adapter->netdev->dev, + "%s: rq[%d] error 0x%x\n", + adapter->netdev->name, i, + adapter->rqd_start[i].status.error); schedule_work(&adapter->work); } @@ -410,7 +422,7 @@ vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq, } -void +static void vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { @@ -437,6 +449,17 @@ vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, } +/* Destroy all tx queues */ +void +vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_destroy(&adapter->tx_queue[i], adapter); +} + + static void vmxnet3_tq_init(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) @@ -518,6 +541,14 @@ err: return -ENOMEM; } +static void +vmxnet3_tq_cleanup_all(struct vmxnet3_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_cleanup(&adapter->tx_queue[i], adapter); +} /* * starting from ring->next2fill, allocate rx buffers for the given ring @@ -732,6 +763,17 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, } +/* Init all tx queues */ +static void +vmxnet3_tq_init_all(struct vmxnet3_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_init(&adapter->tx_queue[i], adapter); +} + + /* * parse and copy relevant protocol headers: * For a tso pkt, relevant headers are L2/3/4 including options @@ -903,6 +945,21 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, } } + spin_lock_irqsave(&tq->tx_lock, flags); + + if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) { + tq->stats.tx_ring_full++; + dev_dbg(&adapter->netdev->dev, + "tx queue stopped on %s, next2comp %u" + " next2fill %u\n", adapter->netdev->name, + tq->tx_ring.next2comp, tq->tx_ring.next2fill); + + vmxnet3_tq_stop(tq, adapter); + spin_unlock_irqrestore(&tq->tx_lock, flags); + return NETDEV_TX_BUSY; + } + + ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter); if (ret >= 0) { BUG_ON(ret <= 0 && ctx.copy_size != 0); @@ -926,20 +983,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, goto drop_pkt; } - spin_lock_irqsave(&tq->tx_lock, flags); - - if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) { - tq->stats.tx_ring_full++; - dev_dbg(&adapter->netdev->dev, - "tx queue stopped on %s, next2comp %u" - " next2fill %u\n", adapter->netdev->name, - tq->tx_ring.next2comp, tq->tx_ring.next2fill); - - vmxnet3_tq_stop(tq, adapter); - spin_unlock_irqrestore(&tq->tx_lock, flags); - return NETDEV_TX_BUSY; - } - /* fill tx descs related to addr & len */ vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter); @@ -1000,7 +1043,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (le32_to_cpu(tq->shared->txNumDeferred) >= le32_to_cpu(tq->shared->txThreshold)) { tq->shared->txNumDeferred = 0; - VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD, + VMXNET3_WRITE_BAR0_REG(adapter, + VMXNET3_REG_TXPROD + tq->qid * 8, tq->tx_ring.next2fill); } @@ -1020,7 +1064,10 @@ vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); - return vmxnet3_tq_xmit(skb, &adapter->tx_queue, adapter, netdev); + BUG_ON(skb->queue_mapping > adapter->num_tx_queues); + return vmxnet3_tq_xmit(skb, + &adapter->tx_queue[skb->queue_mapping], + adapter, netdev); } @@ -1106,9 +1153,9 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, break; } num_rxd++; - + BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); idx = rcd->rxdIdx; - ring_idx = rcd->rqID == rq->qid ? 0 : 1; + ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, &rxCmdDesc); rbi = rq->buf_info[ring_idx] + idx; @@ -1260,6 +1307,16 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq, } +static void +vmxnet3_rq_cleanup_all(struct vmxnet3_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) + vmxnet3_rq_cleanup(&adapter->rx_queue[i], adapter); +} + + void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) { @@ -1350,6 +1407,25 @@ vmxnet3_rq_init(struct vmxnet3_rx_queue *rq, } +static int +vmxnet3_rq_init_all(struct vmxnet3_adapter *adapter) +{ + int i, err = 0; + + for (i = 0; i < adapter->num_rx_queues; i++) { + err = vmxnet3_rq_init(&adapter->rx_queue[i], adapter); + if (unlikely(err)) { + dev_err(&adapter->netdev->dev, "%s: failed to " + "initialize rx queue%i\n", + adapter->netdev->name, i); + break; + } + } + return err; + +} + + static int vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) { @@ -1397,34 +1473,178 @@ err: } +static int +vmxnet3_rq_create_all(struct vmxnet3_adapter *adapter) +{ + int i, err = 0; + + for (i = 0; i < adapter->num_rx_queues; i++) { + err = vmxnet3_rq_create(&adapter->rx_queue[i], adapter); + if (unlikely(err)) { + dev_err(&adapter->netdev->dev, + "%s: failed to create rx queue%i\n", + adapter->netdev->name, i); + goto err_out; + } + } + return err; +err_out: + vmxnet3_rq_destroy_all(adapter); + return err; + +} + +/* Multiple queue aware polling function for tx and rx */ + static int vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget) { + int rcd_done = 0, i; if (unlikely(adapter->shared->ecr)) vmxnet3_process_events(adapter); + for (i = 0; i < adapter->num_tx_queues; i++) + vmxnet3_tq_tx_complete(&adapter->tx_queue[i], adapter); - vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter); - return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget); + for (i = 0; i < adapter->num_rx_queues; i++) + rcd_done += vmxnet3_rq_rx_complete(&adapter->rx_queue[i], + adapter, budget); + return rcd_done; } static int vmxnet3_poll(struct napi_struct *napi, int budget) { - struct vmxnet3_adapter *adapter = container_of(napi, - struct vmxnet3_adapter, napi); + struct vmxnet3_rx_queue *rx_queue = container_of(napi, + struct vmxnet3_rx_queue, napi); + int rxd_done; + + rxd_done = vmxnet3_do_poll(rx_queue->adapter, budget); + + if (rxd_done < budget) { + napi_complete(napi); + vmxnet3_enable_all_intrs(rx_queue->adapter); + } + return rxd_done; +} + +/* + * NAPI polling function for MSI-X mode with multiple Rx queues + * Returns the # of the NAPI credit consumed (# of rx descriptors processed) + */ + +static int +vmxnet3_poll_rx_only(struct napi_struct *napi, int budget) +{ + struct vmxnet3_rx_queue *rq = container_of(napi, + struct vmxnet3_rx_queue, napi); + struct vmxnet3_adapter *adapter = rq->adapter; int rxd_done; - rxd_done = vmxnet3_do_poll(adapter, budget); + /* When sharing interrupt with corresponding tx queue, process + * tx completions in that queue as well + */ + if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE) { + struct vmxnet3_tx_queue *tq = + &adapter->tx_queue[rq - adapter->rx_queue]; + vmxnet3_tq_tx_complete(tq, adapter); + } + + rxd_done = vmxnet3_rq_rx_complete(rq, adapter, budget); if (rxd_done < budget) { napi_complete(napi); - vmxnet3_enable_intr(adapter, 0); + vmxnet3_enable_intr(adapter, rq->comp_ring.intr_idx); } return rxd_done; } +#ifdef CONFIG_PCI_MSI + +/* + * Handle completion interrupts on tx queues + * Returns whether or not the intr is handled + */ + +static irqreturn_t +vmxnet3_msix_tx(int irq, void *data) +{ + struct vmxnet3_tx_queue *tq = data; + struct vmxnet3_adapter *adapter = tq->adapter; + + if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) + vmxnet3_disable_intr(adapter, tq->comp_ring.intr_idx); + + /* Handle the case where only one irq is allocate for all tx queues */ + if (adapter->share_intr == VMXNET3_INTR_TXSHARE) { + int i; + for (i = 0; i < adapter->num_tx_queues; i++) { + struct vmxnet3_tx_queue *txq = &adapter->tx_queue[i]; + vmxnet3_tq_tx_complete(txq, adapter); + } + } else { + vmxnet3_tq_tx_complete(tq, adapter); + } + vmxnet3_enable_intr(adapter, tq->comp_ring.intr_idx); + + return IRQ_HANDLED; +} + + +/* + * Handle completion interrupts on rx queues. Returns whether or not the + * intr is handled + */ + +static irqreturn_t +vmxnet3_msix_rx(int irq, void *data) +{ + struct vmxnet3_rx_queue *rq = data; + struct vmxnet3_adapter *adapter = rq->adapter; + + /* disable intr if needed */ + if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) + vmxnet3_disable_intr(adapter, rq->comp_ring.intr_idx); + napi_schedule(&rq->napi); + + return IRQ_HANDLED; +} + +/* + *---------------------------------------------------------------------------- + * + * vmxnet3_msix_event -- + * + * vmxnet3 msix event intr handler + * + * Result: + * whether or not the intr is handled + * + *---------------------------------------------------------------------------- + */ + +static irqreturn_t +vmxnet3_msix_event(int irq, void *data) +{ + struct net_device *dev = data; + struct vmxnet3_adapter *adapter = netdev_priv(dev); + + /* disable intr if needed */ + if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) + vmxnet3_disable_intr(adapter, adapter->intr.event_intr_idx); + + if (adapter->shared->ecr) + vmxnet3_process_events(adapter); + + vmxnet3_enable_intr(adapter, adapter->intr.event_intr_idx); + + return IRQ_HANDLED; +} + +#endif /* CONFIG_PCI_MSI */ + + /* Interrupt handler for vmxnet3 */ static irqreturn_t vmxnet3_intr(int irq, void *dev_id) @@ -1432,7 +1652,7 @@ vmxnet3_intr(int irq, void *dev_id) struct net_device *dev = dev_id; struct vmxnet3_adapter *adapter = netdev_priv(dev); - if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) { + if (adapter->intr.type == VMXNET3_IT_INTX) { u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR); if (unlikely(icr == 0)) /* not ours */ @@ -1442,77 +1662,144 @@ vmxnet3_intr(int irq, void *dev_id) /* disable intr if needed */ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_intr(adapter, 0); + vmxnet3_disable_all_intrs(adapter); - napi_schedule(&adapter->napi); + napi_schedule(&adapter->rx_queue[0].napi); return IRQ_HANDLED; } #ifdef CONFIG_NET_POLL_CONTROLLER - /* netpoll callback. */ static void vmxnet3_netpoll(struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); - int irq; -#ifdef CONFIG_PCI_MSI - if (adapter->intr.type == VMXNET3_IT_MSIX) - irq = adapter->intr.msix_entries[0].vector; - else -#endif - irq = adapter->pdev->irq; + if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) + vmxnet3_disable_all_intrs(adapter); + + vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); + vmxnet3_enable_all_intrs(adapter); - disable_irq(irq); - vmxnet3_intr(irq, netdev); - enable_irq(irq); } -#endif +#endif /* CONFIG_NET_POLL_CONTROLLER */ static int vmxnet3_request_irqs(struct vmxnet3_adapter *adapter) { - int err; + struct vmxnet3_intr *intr = &adapter->intr; + int err = 0, i; + int vector = 0; #ifdef CONFIG_PCI_MSI if (adapter->intr.type == VMXNET3_IT_MSIX) { - /* we only use 1 MSI-X vector */ - err = request_irq(adapter->intr.msix_entries[0].vector, - vmxnet3_intr, 0, adapter->netdev->name, - adapter->netdev); - } else if (adapter->intr.type == VMXNET3_IT_MSI) { + for (i = 0; i < adapter->num_tx_queues; i++) { + if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) { + sprintf(adapter->tx_queue[i].name, "%s-tx-%d", + adapter->netdev->name, vector); + err = request_irq( + intr->msix_entries[vector].vector, + vmxnet3_msix_tx, 0, + adapter->tx_queue[i].name, + &adapter->tx_queue[i]); + } else { + sprintf(adapter->tx_queue[i].name, "%s-rxtx-%d", + adapter->netdev->name, vector); + } + if (err) { + dev_err(&adapter->netdev->dev, + "Failed to request irq for MSIX, %s, " + "error %d\n", + adapter->tx_queue[i].name, err); + return err; + } + + /* Handle the case where only 1 MSIx was allocated for + * all tx queues */ + if (adapter->share_intr == VMXNET3_INTR_TXSHARE) { + for (; i < adapter->num_tx_queues; i++) + adapter->tx_queue[i].comp_ring.intr_idx + = vector; + vector++; + break; + } else { + adapter->tx_queue[i].comp_ring.intr_idx + = vector++; + } + } + if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE) + vector = 0; + + for (i = 0; i < adapter->num_rx_queues; i++) { + if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) + sprintf(adapter->rx_queue[i].name, "%s-rx-%d", + adapter->netdev->name, vector); + else + sprintf(adapter->rx_queue[i].name, "%s-rxtx-%d", + adapter->netdev->name, vector); + err = request_irq(intr->msix_entries[vector].vector, + vmxnet3_msix_rx, 0, + adapter->rx_queue[i].name, + &(adapter->rx_queue[i])); + if (err) { + printk(KERN_ERR "Failed to request irq for MSIX" + ", %s, error %d\n", + adapter->rx_queue[i].name, err); + return err; + } + + adapter->rx_queue[i].comp_ring.intr_idx = vector++; + } + + sprintf(intr->event_msi_vector_name, "%s-event-%d", + adapter->netdev->name, vector); + err = request_irq(intr->msix_entries[vector].vector, + vmxnet3_msix_event, 0, + intr->event_msi_vector_name, adapter->netdev); + intr->event_intr_idx = vector; + + } else if (intr->type == VMXNET3_IT_MSI) { + adapter->num_rx_queues = 1; err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0, adapter->netdev->name, adapter->netdev); - } else + } else { #endif - { + adapter->num_rx_queues = 1; err = request_irq(adapter->pdev->irq, vmxnet3_intr, IRQF_SHARED, adapter->netdev->name, adapter->netdev); +#ifdef CONFIG_PCI_MSI } - - if (err) +#endif + intr->num_intrs = vector + 1; + if (err) { printk(KERN_ERR "Failed to request irq %s (intr type:%d), error" - ":%d\n", adapter->netdev->name, adapter->intr.type, err); + ":%d\n", adapter->netdev->name, intr->type, err); + } else { + /* Number of rx queues will not change after this */ + for (i = 0; i < adapter->num_rx_queues; i++) { + struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; + rq->qid = i; + rq->qid2 = i + adapter->num_rx_queues; + } - if (!err) { - int i; - /* init our intr settings */ - for (i = 0; i < adapter->intr.num_intrs; i++) - adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE; - /* next setup intr index for all intr sources */ - adapter->tx_queue.comp_ring.intr_idx = 0; - adapter->rx_queue.comp_ring.intr_idx = 0; - adapter->intr.event_intr_idx = 0; + /* init our intr settings */ + for (i = 0; i < intr->num_intrs; i++) + intr->mod_levels[i] = UPT1_IML_ADAPTIVE; + if (adapter->intr.type != VMXNET3_IT_MSIX) { + adapter->intr.event_intr_idx = 0; + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_queue[i].comp_ring.intr_idx = 0; + adapter->rx_queue[0].comp_ring.intr_idx = 0; + } printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors " - "allocated\n", adapter->netdev->name, adapter->intr.type, - adapter->intr.mask_mode, adapter->intr.num_intrs); + "allocated\n", adapter->netdev->name, intr->type, + intr->mask_mode, intr->num_intrs); } return err; @@ -1522,18 +1809,32 @@ vmxnet3_request_irqs(struct vmxnet3_adapter *adapter) static void vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) { - BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO || - adapter->intr.num_intrs <= 0); + struct vmxnet3_intr *intr = &adapter->intr; + BUG_ON(intr->type == VMXNET3_IT_AUTO || intr->num_intrs <= 0); - switch (adapter->intr.type) { + switch (intr->type) { #ifdef CONFIG_PCI_MSI case VMXNET3_IT_MSIX: { - int i; + int i, vector = 0; - for (i = 0; i < adapter->intr.num_intrs; i++) - free_irq(adapter->intr.msix_entries[i].vector, - adapter->netdev); + if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) { + for (i = 0; i < adapter->num_tx_queues; i++) { + free_irq(intr->msix_entries[vector++].vector, + &(adapter->tx_queue[i])); + if (adapter->share_intr == VMXNET3_INTR_TXSHARE) + break; + } + } + + for (i = 0; i < adapter->num_rx_queues; i++) { + free_irq(intr->msix_entries[vector++].vector, + &(adapter->rx_queue[i])); + } + + free_irq(intr->msix_entries[vector].vector, + adapter->netdev); + BUG_ON(vector >= intr->num_intrs); break; } #endif @@ -1727,6 +2028,15 @@ vmxnet3_set_mc(struct net_device *netdev) kfree(new_table); } +void +vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) + vmxnet3_rq_destroy(&adapter->rx_queue[i], adapter); +} + /* * Set up driver_shared based on settings in adapter. @@ -1774,40 +2084,72 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu); devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa); devRead->misc.queueDescLen = cpu_to_le32( - sizeof(struct Vmxnet3_TxQueueDesc) + - sizeof(struct Vmxnet3_RxQueueDesc)); + adapter->num_tx_queues * sizeof(struct Vmxnet3_TxQueueDesc) + + adapter->num_rx_queues * sizeof(struct Vmxnet3_RxQueueDesc)); /* tx queue settings */ - BUG_ON(adapter->tx_queue.tx_ring.base == NULL); - - devRead->misc.numTxQueues = 1; - tqc = &adapter->tqd_start->conf; - tqc->txRingBasePA = cpu_to_le64(adapter->tx_queue.tx_ring.basePA); - tqc->dataRingBasePA = cpu_to_le64(adapter->tx_queue.data_ring.basePA); - tqc->compRingBasePA = cpu_to_le64(adapter->tx_queue.comp_ring.basePA); - tqc->ddPA = cpu_to_le64(virt_to_phys( - adapter->tx_queue.buf_info)); - tqc->txRingSize = cpu_to_le32(adapter->tx_queue.tx_ring.size); - tqc->dataRingSize = cpu_to_le32(adapter->tx_queue.data_ring.size); - tqc->compRingSize = cpu_to_le32(adapter->tx_queue.comp_ring.size); - tqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_tx_buf_info) * - tqc->txRingSize); - tqc->intrIdx = adapter->tx_queue.comp_ring.intr_idx; + devRead->misc.numTxQueues = adapter->num_tx_queues; + for (i = 0; i < adapter->num_tx_queues; i++) { + struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i]; + BUG_ON(adapter->tx_queue[i].tx_ring.base == NULL); + tqc = &adapter->tqd_start[i].conf; + tqc->txRingBasePA = cpu_to_le64(tq->tx_ring.basePA); + tqc->dataRingBasePA = cpu_to_le64(tq->data_ring.basePA); + tqc->compRingBasePA = cpu_to_le64(tq->comp_ring.basePA); + tqc->ddPA = cpu_to_le64(virt_to_phys(tq->buf_info)); + tqc->txRingSize = cpu_to_le32(tq->tx_ring.size); + tqc->dataRingSize = cpu_to_le32(tq->data_ring.size); + tqc->compRingSize = cpu_to_le32(tq->comp_ring.size); + tqc->ddLen = cpu_to_le32( + sizeof(struct vmxnet3_tx_buf_info) * + tqc->txRingSize); + tqc->intrIdx = tq->comp_ring.intr_idx; + } /* rx queue settings */ - devRead->misc.numRxQueues = 1; - rqc = &adapter->rqd_start->conf; - rqc->rxRingBasePA[0] = cpu_to_le64(adapter->rx_queue.rx_ring[0].basePA); - rqc->rxRingBasePA[1] = cpu_to_le64(adapter->rx_queue.rx_ring[1].basePA); - rqc->compRingBasePA = cpu_to_le64(adapter->rx_queue.comp_ring.basePA); - rqc->ddPA = cpu_to_le64(virt_to_phys( - adapter->rx_queue.buf_info)); - rqc->rxRingSize[0] = cpu_to_le32(adapter->rx_queue.rx_ring[0].size); - rqc->rxRingSize[1] = cpu_to_le32(adapter->rx_queue.rx_ring[1].size); - rqc->compRingSize = cpu_to_le32(adapter->rx_queue.comp_ring.size); - rqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_rx_buf_info) * - (rqc->rxRingSize[0] + rqc->rxRingSize[1])); - rqc->intrIdx = adapter->rx_queue.comp_ring.intr_idx; + devRead->misc.numRxQueues = adapter->num_rx_queues; + for (i = 0; i < adapter->num_rx_queues; i++) { + struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; + rqc = &adapter->rqd_start[i].conf; + rqc->rxRingBasePA[0] = cpu_to_le64(rq->rx_ring[0].basePA); + rqc->rxRingBasePA[1] = cpu_to_le64(rq->rx_ring[1].basePA); + rqc->compRingBasePA = cpu_to_le64(rq->comp_ring.basePA); + rqc->ddPA = cpu_to_le64(virt_to_phys( + rq->buf_info)); + rqc->rxRingSize[0] = cpu_to_le32(rq->rx_ring[0].size); + rqc->rxRingSize[1] = cpu_to_le32(rq->rx_ring[1].size); + rqc->compRingSize = cpu_to_le32(rq->comp_ring.size); + rqc->ddLen = cpu_to_le32( + sizeof(struct vmxnet3_rx_buf_info) * + (rqc->rxRingSize[0] + + rqc->rxRingSize[1])); + rqc->intrIdx = rq->comp_ring.intr_idx; + } + +#ifdef VMXNET3_RSS + memset(adapter->rss_conf, 0, sizeof(*adapter->rss_conf)); + + if (adapter->rss) { + struct UPT1_RSSConf *rssConf = adapter->rss_conf; + devRead->misc.uptFeatures |= UPT1_F_RSS; + devRead->misc.numRxQueues = adapter->num_rx_queues; + rssConf->hashType = UPT1_RSS_HASH_TYPE_TCP_IPV4 | + UPT1_RSS_HASH_TYPE_IPV4 | + UPT1_RSS_HASH_TYPE_TCP_IPV6 | + UPT1_RSS_HASH_TYPE_IPV6; + rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ; + rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE; + rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE; + get_random_bytes(&rssConf->hashKey[0], rssConf->hashKeySize); + for (i = 0; i < rssConf->indTableSize; i++) + rssConf->indTable[i] = i % adapter->num_rx_queues; + + devRead->rssConfDesc.confVer = 1; + devRead->rssConfDesc.confLen = sizeof(*rssConf); + devRead->rssConfDesc.confPA = virt_to_phys(rssConf); + } + +#endif /* VMXNET3_RSS */ /* intr settings */ devRead->intrConf.autoMask = adapter->intr.mask_mode == @@ -1829,18 +2171,18 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) int vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) { - int err; + int err, i; u32 ret; - dev_dbg(&adapter->netdev->dev, - "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes" - " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size, - adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size, - adapter->rx_queue.rx_ring[0].size, - adapter->rx_queue.rx_ring[1].size); - - vmxnet3_tq_init(&adapter->tx_queue, adapter); - err = vmxnet3_rq_init(&adapter->rx_queue, adapter); + dev_dbg(&adapter->netdev->dev, "%s: skb_buf_size %d, rx_buf_per_pkt %d," + " ring sizes %u %u %u\n", adapter->netdev->name, + adapter->skb_buf_size, adapter->rx_buf_per_pkt, + adapter->tx_queue[0].tx_ring.size, + adapter->rx_queue[0].rx_ring[0].size, + adapter->rx_queue[0].rx_ring[1].size); + + vmxnet3_tq_init_all(adapter); + err = vmxnet3_rq_init_all(adapter); if (err) { printk(KERN_ERR "Failed to init rx queue for %s: error %d\n", adapter->netdev->name, err); @@ -1870,10 +2212,15 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) err = -EINVAL; goto activate_err; } - VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD, - adapter->rx_queue.rx_ring[0].next2fill); - VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2, - adapter->rx_queue.rx_ring[1].next2fill); + + for (i = 0; i < adapter->num_rx_queues; i++) { + VMXNET3_WRITE_BAR0_REG(adapter, + VMXNET3_REG_RXPROD + i * VMXNET3_REG_ALIGN, + adapter->rx_queue[i].rx_ring[0].next2fill); + VMXNET3_WRITE_BAR0_REG(adapter, (VMXNET3_REG_RXPROD2 + + (i * VMXNET3_REG_ALIGN)), + adapter->rx_queue[i].rx_ring[1].next2fill); + } /* Apply the rx filter settins last. */ vmxnet3_set_mc(adapter->netdev); @@ -1883,8 +2230,8 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) * tx queue if the link is up. */ vmxnet3_check_link(adapter, true); - - napi_enable(&adapter->napi); + for (i = 0; i < adapter->num_rx_queues; i++) + napi_enable(&adapter->rx_queue[i].napi); vmxnet3_enable_all_intrs(adapter); clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); return 0; @@ -1896,7 +2243,7 @@ activate_err: irq_err: rq_err: /* free up buffers we allocated */ - vmxnet3_rq_cleanup(&adapter->rx_queue, adapter); + vmxnet3_rq_cleanup_all(adapter); return err; } @@ -1911,6 +2258,7 @@ vmxnet3_reset_dev(struct vmxnet3_adapter *adapter) int vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter) { + int i; if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state)) return 0; @@ -1919,13 +2267,14 @@ vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter) VMXNET3_CMD_QUIESCE_DEV); vmxnet3_disable_all_intrs(adapter); - napi_disable(&adapter->napi); + for (i = 0; i < adapter->num_rx_queues; i++) + napi_disable(&adapter->rx_queue[i].napi); netif_tx_disable(adapter->netdev); adapter->link_speed = 0; netif_carrier_off(adapter->netdev); - vmxnet3_tq_cleanup(&adapter->tx_queue, adapter); - vmxnet3_rq_cleanup(&adapter->rx_queue, adapter); + vmxnet3_tq_cleanup_all(adapter); + vmxnet3_rq_cleanup_all(adapter); vmxnet3_free_irqs(adapter); return 0; } @@ -2047,7 +2396,9 @@ vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter) static void vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) { - size_t sz; + size_t sz, i, ring0_size, ring1_size, comp_size; + struct vmxnet3_rx_queue *rq = &adapter->rx_queue[0]; + if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE - VMXNET3_MAX_ETH_HDR_SIZE) { @@ -2069,11 +2420,19 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN */ sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN; - adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size + - sz - 1) / sz * sz; - adapter->rx_queue.rx_ring[0].size = min_t(u32, - adapter->rx_queue.rx_ring[0].size, - VMXNET3_RX_RING_MAX_SIZE / sz * sz); + ring0_size = adapter->rx_queue[0].rx_ring[0].size; + ring0_size = (ring0_size + sz - 1) / sz * sz; + ring0_size = min_t(u32, rq->rx_ring[0].size, VMXNET3_RX_RING_MAX_SIZE / + sz * sz); + ring1_size = adapter->rx_queue[0].rx_ring[1].size; + comp_size = ring0_size + ring1_size; + + for (i = 0; i < adapter->num_rx_queues; i++) { + rq = &adapter->rx_queue[i]; + rq->rx_ring[0].size = ring0_size; + rq->rx_ring[1].size = ring1_size; + rq->comp_ring.size = comp_size; + } } @@ -2081,29 +2440,53 @@ int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size) { - int err; - - adapter->tx_queue.tx_ring.size = tx_ring_size; - adapter->tx_queue.data_ring.size = tx_ring_size; - adapter->tx_queue.comp_ring.size = tx_ring_size; - adapter->tx_queue.shared = &adapter->tqd_start->ctrl; - adapter->tx_queue.stopped = true; - err = vmxnet3_tq_create(&adapter->tx_queue, adapter); - if (err) - return err; + int err = 0, i; + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i]; + tq->tx_ring.size = tx_ring_size; + tq->data_ring.size = tx_ring_size; + tq->comp_ring.size = tx_ring_size; + tq->shared = &adapter->tqd_start[i].ctrl; + tq->stopped = true; + tq->adapter = adapter; + tq->qid = i; + err = vmxnet3_tq_create(tq, adapter); + /* + * Too late to change num_tx_queues. We cannot do away with + * lesser number of queues than what we asked for + */ + if (err) + goto queue_err; + } - adapter->rx_queue.rx_ring[0].size = rx_ring_size; - adapter->rx_queue.rx_ring[1].size = rx_ring2_size; + adapter->rx_queue[0].rx_ring[0].size = rx_ring_size; + adapter->rx_queue[0].rx_ring[1].size = rx_ring2_size; vmxnet3_adjust_rx_ring_size(adapter); - adapter->rx_queue.comp_ring.size = adapter->rx_queue.rx_ring[0].size + - adapter->rx_queue.rx_ring[1].size; - adapter->rx_queue.qid = 0; - adapter->rx_queue.qid2 = 1; - adapter->rx_queue.shared = &adapter->rqd_start->ctrl; - err = vmxnet3_rq_create(&adapter->rx_queue, adapter); - if (err) - vmxnet3_tq_destroy(&adapter->tx_queue, adapter); - + for (i = 0; i < adapter->num_rx_queues; i++) { + struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; + /* qid and qid2 for rx queues will be assigned later when num + * of rx queues is finalized after allocating intrs */ + rq->shared = &adapter->rqd_start[i].ctrl; + rq->adapter = adapter; + err = vmxnet3_rq_create(rq, adapter); + if (err) { + if (i == 0) { + printk(KERN_ERR "Could not allocate any rx" + "queues. Aborting.\n"); + goto queue_err; + } else { + printk(KERN_INFO "Number of rx queues changed " + "to : %d.\n", i); + adapter->num_rx_queues = i; + err = 0; + break; + } + } + } + return err; +queue_err: + vmxnet3_tq_destroy_all(adapter); return err; } @@ -2111,11 +2494,12 @@ static int vmxnet3_open(struct net_device *netdev) { struct vmxnet3_adapter *adapter; - int err; + int err, i; adapter = netdev_priv(netdev); - spin_lock_init(&adapter->tx_queue.tx_lock); + for (i = 0; i < adapter->num_tx_queues; i++) + spin_lock_init(&adapter->tx_queue[i].tx_lock); err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE, VMXNET3_DEF_RX_RING_SIZE, @@ -2130,8 +2514,8 @@ vmxnet3_open(struct net_device *netdev) return 0; activate_err: - vmxnet3_rq_destroy(&adapter->rx_queue, adapter); - vmxnet3_tq_destroy(&adapter->tx_queue, adapter); + vmxnet3_rq_destroy_all(adapter); + vmxnet3_tq_destroy_all(adapter); queue_err: return err; } @@ -2151,8 +2535,8 @@ vmxnet3_close(struct net_device *netdev) vmxnet3_quiesce_dev(adapter); - vmxnet3_rq_destroy(&adapter->rx_queue, adapter); - vmxnet3_tq_destroy(&adapter->tx_queue, adapter); + vmxnet3_rq_destroy_all(adapter); + vmxnet3_tq_destroy_all(adapter); clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state); @@ -2164,6 +2548,8 @@ vmxnet3_close(struct net_device *netdev) void vmxnet3_force_close(struct vmxnet3_adapter *adapter) { + int i; + /* * we must clear VMXNET3_STATE_BIT_RESETTING, otherwise * vmxnet3_close() will deadlock. @@ -2171,7 +2557,8 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter) BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state)); /* we need to enable NAPI, otherwise dev_close will deadlock */ - napi_enable(&adapter->napi); + for (i = 0; i < adapter->num_rx_queues; i++) + napi_enable(&adapter->rx_queue[i].napi); dev_close(adapter->netdev); } @@ -2202,14 +2589,11 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu) vmxnet3_reset_dev(adapter); /* we need to re-create the rx queue based on the new mtu */ - vmxnet3_rq_destroy(&adapter->rx_queue, adapter); + vmxnet3_rq_destroy_all(adapter); vmxnet3_adjust_rx_ring_size(adapter); - adapter->rx_queue.comp_ring.size = - adapter->rx_queue.rx_ring[0].size + - adapter->rx_queue.rx_ring[1].size; - err = vmxnet3_rq_create(&adapter->rx_queue, adapter); + err = vmxnet3_rq_create_all(adapter); if (err) { - printk(KERN_ERR "%s: failed to re-create rx queue," + printk(KERN_ERR "%s: failed to re-create rx queues," " error %d. Closing it.\n", netdev->name, err); goto out; } @@ -2274,6 +2658,55 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) mac[5] = (tmp >> 8) & 0xff; } +#ifdef CONFIG_PCI_MSI + +/* + * Enable MSIx vectors. + * Returns : + * 0 on successful enabling of required vectors, + * VMXNET3_LINUX_MIN_MSIX_VECT when only minumum number of vectors required + * could be enabled. + * number of vectors which can be enabled otherwise (this number is smaller + * than VMXNET3_LINUX_MIN_MSIX_VECT) + */ + +static int +vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, + int vectors) +{ + int err = 0, vector_threshold; + vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; + + while (vectors >= vector_threshold) { + err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, + vectors); + if (!err) { + adapter->intr.num_intrs = vectors; + return 0; + } else if (err < 0) { + printk(KERN_ERR "Failed to enable MSI-X for %s, error" + " %d\n", adapter->netdev->name, err); + vectors = 0; + } else if (err < vector_threshold) { + break; + } else { + /* If fails to enable required number of MSI-x vectors + * try enabling 3 of them. One each for rx, tx and event + */ + vectors = vector_threshold; + printk(KERN_ERR "Failed to enable %d MSI-X for %s, try" + " %d instead\n", vectors, adapter->netdev->name, + vector_threshold); + } + } + + printk(KERN_INFO "Number of MSI-X interrupts which can be allocatedi" + " are lower than min threshold required.\n"); + return err; +} + + +#endif /* CONFIG_PCI_MSI */ static void vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) @@ -2293,16 +2726,47 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) #ifdef CONFIG_PCI_MSI if (adapter->intr.type == VMXNET3_IT_MSIX) { - int err; - - adapter->intr.msix_entries[0].entry = 0; - err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, - VMXNET3_LINUX_MAX_MSIX_VECT); - if (!err) { - adapter->intr.num_intrs = 1; - adapter->intr.type = VMXNET3_IT_MSIX; + int vector, err = 0; + + adapter->intr.num_intrs = (adapter->share_intr == + VMXNET3_INTR_TXSHARE) ? 1 : + adapter->num_tx_queues; + adapter->intr.num_intrs += (adapter->share_intr == + VMXNET3_INTR_BUDDYSHARE) ? 0 : + adapter->num_rx_queues; + adapter->intr.num_intrs += 1; /* for link event */ + + adapter->intr.num_intrs = (adapter->intr.num_intrs > + VMXNET3_LINUX_MIN_MSIX_VECT + ? adapter->intr.num_intrs : + VMXNET3_LINUX_MIN_MSIX_VECT); + + for (vector = 0; vector < adapter->intr.num_intrs; vector++) + adapter->intr.msix_entries[vector].entry = vector; + + err = vmxnet3_acquire_msix_vectors(adapter, + adapter->intr.num_intrs); + /* If we cannot allocate one MSIx vector per queue + * then limit the number of rx queues to 1 + */ + if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { + if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE + || adapter->num_rx_queues != 2) { + adapter->share_intr = VMXNET3_INTR_TXSHARE; + printk(KERN_ERR "Number of rx queues : 1\n"); + adapter->num_rx_queues = 1; + adapter->intr.num_intrs = + VMXNET3_LINUX_MIN_MSIX_VECT; + } return; } + if (!err) + return; + + /* If we cannot allocate MSIx vectors use only one rx queue */ + printk(KERN_INFO "Failed to enable MSI-X for %s, error %d." + "#rx queues : 1, try MSI\n", adapter->netdev->name, err); + adapter->intr.type = VMXNET3_IT_MSI; } @@ -2310,12 +2774,15 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) int err; err = pci_enable_msi(adapter->pdev); if (!err) { + adapter->num_rx_queues = 1; adapter->intr.num_intrs = 1; return; } } #endif /* CONFIG_PCI_MSI */ + adapter->num_rx_queues = 1; + printk(KERN_INFO "Using INTx interrupt, #Rx queues: 1.\n"); adapter->intr.type = VMXNET3_IT_INTX; /* INT-X related setting */ @@ -2343,6 +2810,7 @@ vmxnet3_tx_timeout(struct net_device *netdev) printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name); schedule_work(&adapter->work); + netif_wake_queue(adapter->netdev); } @@ -2399,8 +2867,29 @@ vmxnet3_probe_device(struct pci_dev *pdev, struct net_device *netdev; struct vmxnet3_adapter *adapter; u8 mac[ETH_ALEN]; + int size; + int num_tx_queues; + int num_rx_queues; + +#ifdef VMXNET3_RSS + if (enable_mq) + num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES, + (int)num_online_cpus()); + else +#endif + num_rx_queues = 1; + + if (enable_mq) + num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES, + (int)num_online_cpus()); + else + num_tx_queues = 1; + + netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter), + max(num_tx_queues, num_rx_queues)); + printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", + num_tx_queues, num_rx_queues); - netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter)); if (!netdev) { printk(KERN_ERR "Failed to alloc ethernet device for adapter " "%s\n", pci_name(pdev)); @@ -2422,9 +2911,12 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_alloc_shared; } - adapter->tqd_start = pci_alloc_consistent(adapter->pdev, - sizeof(struct Vmxnet3_TxQueueDesc) + - sizeof(struct Vmxnet3_RxQueueDesc), + adapter->num_rx_queues = num_rx_queues; + adapter->num_tx_queues = num_tx_queues; + + size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; + size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues; + adapter->tqd_start = pci_alloc_consistent(adapter->pdev, size, &adapter->queue_desc_pa); if (!adapter->tqd_start) { @@ -2433,8 +2925,8 @@ vmxnet3_probe_device(struct pci_dev *pdev, err = -ENOMEM; goto err_alloc_queue_desc; } - adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start - + 1); + adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start + + adapter->num_tx_queues); adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL); if (adapter->pm_conf == NULL) { @@ -2444,6 +2936,17 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_alloc_pm; } +#ifdef VMXNET3_RSS + + adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL); + if (adapter->rss_conf == NULL) { + printk(KERN_ERR "Failed to allocate memory for %s\n", + pci_name(pdev)); + err = -ENOMEM; + goto err_alloc_rss; + } +#endif /* VMXNET3_RSS */ + err = vmxnet3_alloc_pci_resources(adapter, &dma64); if (err < 0) goto err_alloc_pci; @@ -2471,18 +2974,48 @@ vmxnet3_probe_device(struct pci_dev *pdev, vmxnet3_declare_features(adapter, dma64); adapter->dev_number = atomic_read(&devices_found); + + adapter->share_intr = irq_share_mode; + if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE && + adapter->num_tx_queues != adapter->num_rx_queues) + adapter->share_intr = VMXNET3_INTR_DONTSHARE; + vmxnet3_alloc_intr_resources(adapter); +#ifdef VMXNET3_RSS + if (adapter->num_rx_queues > 1 && + adapter->intr.type == VMXNET3_IT_MSIX) { + adapter->rss = true; + printk(KERN_INFO "RSS is enabled.\n"); + } else { + adapter->rss = false; + } +#endif + vmxnet3_read_mac_addr(adapter, mac); memcpy(netdev->dev_addr, mac, netdev->addr_len); netdev->netdev_ops = &vmxnet3_netdev_ops; - netdev->watchdog_timeo = 5 * HZ; vmxnet3_set_ethtool_ops(netdev); + netdev->watchdog_timeo = 5 * HZ; INIT_WORK(&adapter->work, vmxnet3_reset_work); - netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64); + if (adapter->intr.type == VMXNET3_IT_MSIX) { + int i; + for (i = 0; i < adapter->num_rx_queues; i++) { + netif_napi_add(adapter->netdev, + &adapter->rx_queue[i].napi, + vmxnet3_poll_rx_only, 64); + } + } else { + netif_napi_add(adapter->netdev, &adapter->rx_queue[0].napi, + vmxnet3_poll, 64); + } + + netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); + netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); + SET_NETDEV_DEV(netdev, &pdev->dev); err = register_netdev(netdev); @@ -2502,11 +3035,14 @@ err_register: err_ver: vmxnet3_free_pci_resources(adapter); err_alloc_pci: +#ifdef VMXNET3_RSS + kfree(adapter->rss_conf); +err_alloc_rss: +#endif kfree(adapter->pm_conf); err_alloc_pm: - pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) + - sizeof(struct Vmxnet3_RxQueueDesc), - adapter->tqd_start, adapter->queue_desc_pa); + pci_free_consistent(adapter->pdev, size, adapter->tqd_start, + adapter->queue_desc_pa); err_alloc_queue_desc: pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared), adapter->shared, adapter->shared_pa); @@ -2522,6 +3058,16 @@ vmxnet3_remove_device(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct vmxnet3_adapter *adapter = netdev_priv(netdev); + int size = 0; + int num_rx_queues; + +#ifdef VMXNET3_RSS + if (enable_mq) + num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES, + (int)num_online_cpus()); + else +#endif + num_rx_queues = 1; flush_scheduled_work(); @@ -2529,10 +3075,15 @@ vmxnet3_remove_device(struct pci_dev *pdev) vmxnet3_free_intr_resources(adapter); vmxnet3_free_pci_resources(adapter); +#ifdef VMXNET3_RSS + kfree(adapter->rss_conf); +#endif kfree(adapter->pm_conf); - pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) + - sizeof(struct Vmxnet3_RxQueueDesc), - adapter->tqd_start, adapter->queue_desc_pa); + + size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; + size += sizeof(struct Vmxnet3_RxQueueDesc) * num_rx_queues; + pci_free_consistent(adapter->pdev, size, adapter->tqd_start, + adapter->queue_desc_pa); pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared), adapter->shared, adapter->shared_pa); free_netdev(netdev); @@ -2563,7 +3114,7 @@ vmxnet3_suspend(struct device *device) vmxnet3_free_intr_resources(adapter); netif_device_detach(netdev); - netif_stop_queue(netdev); + netif_tx_stop_all_queues(netdev); /* Create wake-up filters. */ pmConf = adapter->pm_conf; diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index b79070bcc92e..9ddaea636cfa 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -151,44 +151,42 @@ vmxnet3_get_stats(struct net_device *netdev) struct UPT1_TxStats *devTxStats; struct UPT1_RxStats *devRxStats; struct net_device_stats *net_stats = &netdev->stats; + int i; adapter = netdev_priv(netdev); /* Collect the dev stats into the shared area */ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); - /* Assuming that we have a single queue device */ - devTxStats = &adapter->tqd_start->stats; - devRxStats = &adapter->rqd_start->stats; - - /* Get access to the driver stats per queue */ - drvTxStats = &adapter->tx_queue.stats; - drvRxStats = &adapter->rx_queue.stats; - memset(net_stats, 0, sizeof(*net_stats)); + for (i = 0; i < adapter->num_tx_queues; i++) { + devTxStats = &adapter->tqd_start[i].stats; + drvTxStats = &adapter->tx_queue[i].stats; + net_stats->tx_packets += devTxStats->ucastPktsTxOK + + devTxStats->mcastPktsTxOK + + devTxStats->bcastPktsTxOK; + net_stats->tx_bytes += devTxStats->ucastBytesTxOK + + devTxStats->mcastBytesTxOK + + devTxStats->bcastBytesTxOK; + net_stats->tx_errors += devTxStats->pktsTxError; + net_stats->tx_dropped += drvTxStats->drop_total; + } - net_stats->rx_packets = devRxStats->ucastPktsRxOK + - devRxStats->mcastPktsRxOK + - devRxStats->bcastPktsRxOK; - - net_stats->tx_packets = devTxStats->ucastPktsTxOK + - devTxStats->mcastPktsTxOK + - devTxStats->bcastPktsTxOK; - - net_stats->rx_bytes = devRxStats->ucastBytesRxOK + - devRxStats->mcastBytesRxOK + - devRxStats->bcastBytesRxOK; - - net_stats->tx_bytes = devTxStats->ucastBytesTxOK + - devTxStats->mcastBytesTxOK + - devTxStats->bcastBytesTxOK; + for (i = 0; i < adapter->num_rx_queues; i++) { + devRxStats = &adapter->rqd_start[i].stats; + drvRxStats = &adapter->rx_queue[i].stats; + net_stats->rx_packets += devRxStats->ucastPktsRxOK + + devRxStats->mcastPktsRxOK + + devRxStats->bcastPktsRxOK; - net_stats->rx_errors = devRxStats->pktsRxError; - net_stats->tx_errors = devTxStats->pktsTxError; - net_stats->rx_dropped = drvRxStats->drop_total; - net_stats->tx_dropped = drvTxStats->drop_total; - net_stats->multicast = devRxStats->mcastPktsRxOK; + net_stats->rx_bytes += devRxStats->ucastBytesRxOK + + devRxStats->mcastBytesRxOK + + devRxStats->bcastBytesRxOK; + net_stats->rx_errors += devRxStats->pktsRxError; + net_stats->rx_dropped += drvRxStats->drop_total; + net_stats->multicast += devRxStats->mcastPktsRxOK; + } return net_stats; } @@ -307,24 +305,26 @@ vmxnet3_get_ethtool_stats(struct net_device *netdev, struct vmxnet3_adapter *adapter = netdev_priv(netdev); u8 *base; int i; + int j = 0; VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); /* this does assume each counter is 64-bit wide */ +/* TODO change this for multiple queues */ - base = (u8 *)&adapter->tqd_start->stats; + base = (u8 *)&adapter->tqd_start[j].stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset); - base = (u8 *)&adapter->tx_queue.stats; + base = (u8 *)&adapter->tx_queue[j].stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset); - base = (u8 *)&adapter->rqd_start->stats; + base = (u8 *)&adapter->rqd_start[j].stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset); - base = (u8 *)&adapter->rx_queue.stats; + base = (u8 *)&adapter->rx_queue[j].stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset); @@ -339,6 +339,7 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); u32 *buf = p; + int i = 0; memset(p, 0, vmxnet3_get_regs_len(netdev)); @@ -347,28 +348,29 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) /* Update vmxnet3_get_regs_len if we want to dump more registers */ /* make each ring use multiple of 16 bytes */ - buf[0] = adapter->tx_queue.tx_ring.next2fill; - buf[1] = adapter->tx_queue.tx_ring.next2comp; - buf[2] = adapter->tx_queue.tx_ring.gen; +/* TODO change this for multiple queues */ + buf[0] = adapter->tx_queue[i].tx_ring.next2fill; + buf[1] = adapter->tx_queue[i].tx_ring.next2comp; + buf[2] = adapter->tx_queue[i].tx_ring.gen; buf[3] = 0; - buf[4] = adapter->tx_queue.comp_ring.next2proc; - buf[5] = adapter->tx_queue.comp_ring.gen; - buf[6] = adapter->tx_queue.stopped; + buf[4] = adapter->tx_queue[i].comp_ring.next2proc; + buf[5] = adapter->tx_queue[i].comp_ring.gen; + buf[6] = adapter->tx_queue[i].stopped; buf[7] = 0; - buf[8] = adapter->rx_queue.rx_ring[0].next2fill; - buf[9] = adapter->rx_queue.rx_ring[0].next2comp; - buf[10] = adapter->rx_queue.rx_ring[0].gen; + buf[8] = adapter->rx_queue[i].rx_ring[0].next2fill; + buf[9] = adapter->rx_queue[i].rx_ring[0].next2comp; + buf[10] = adapter->rx_queue[i].rx_ring[0].gen; buf[11] = 0; - buf[12] = adapter->rx_queue.rx_ring[1].next2fill; - buf[13] = adapter->rx_queue.rx_ring[1].next2comp; - buf[14] = adapter->rx_queue.rx_ring[1].gen; + buf[12] = adapter->rx_queue[i].rx_ring[1].next2fill; + buf[13] = adapter->rx_queue[i].rx_ring[1].next2comp; + buf[14] = adapter->rx_queue[i].rx_ring[1].gen; buf[15] = 0; - buf[16] = adapter->rx_queue.comp_ring.next2proc; - buf[17] = adapter->rx_queue.comp_ring.gen; + buf[16] = adapter->rx_queue[i].comp_ring.next2proc; + buf[17] = adapter->rx_queue[i].comp_ring.gen; buf[18] = 0; buf[19] = 0; } @@ -435,8 +437,10 @@ vmxnet3_get_ringparam(struct net_device *netdev, param->rx_mini_max_pending = 0; param->rx_jumbo_max_pending = 0; - param->rx_pending = adapter->rx_queue.rx_ring[0].size; - param->tx_pending = adapter->tx_queue.tx_ring.size; + param->rx_pending = adapter->rx_queue[0].rx_ring[0].size * + adapter->num_rx_queues; + param->tx_pending = adapter->tx_queue[0].tx_ring.size * + adapter->num_tx_queues; param->rx_mini_pending = 0; param->rx_jumbo_pending = 0; } @@ -480,8 +484,8 @@ vmxnet3_set_ringparam(struct net_device *netdev, sz) != 0) return -EINVAL; - if (new_tx_ring_size == adapter->tx_queue.tx_ring.size && - new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) { + if (new_tx_ring_size == adapter->tx_queue[0].tx_ring.size && + new_rx_ring_size == adapter->rx_queue[0].rx_ring[0].size) { return 0; } @@ -498,11 +502,12 @@ vmxnet3_set_ringparam(struct net_device *netdev, /* recreate the rx queue and the tx queue based on the * new sizes */ - vmxnet3_tq_destroy(&adapter->tx_queue, adapter); - vmxnet3_rq_destroy(&adapter->rx_queue, adapter); + vmxnet3_tq_destroy_all(adapter); + vmxnet3_rq_destroy_all(adapter); err = vmxnet3_create_queues(adapter, new_tx_ring_size, new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE); + if (err) { /* failed, most likely because of OOM, try default * size */ @@ -535,6 +540,65 @@ out: } +static int +vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info, + void *rules) +{ + struct vmxnet3_adapter *adapter = netdev_priv(netdev); + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data = adapter->num_rx_queues; + return 0; + } + return -EOPNOTSUPP; +} + + +static int +vmxnet3_get_rss_indir(struct net_device *netdev, + struct ethtool_rxfh_indir *p) +{ + struct vmxnet3_adapter *adapter = netdev_priv(netdev); + struct UPT1_RSSConf *rssConf = adapter->rss_conf; + unsigned int n = min_t(unsigned int, p->size, rssConf->indTableSize); + + p->size = rssConf->indTableSize; + while (n--) + p->ring_index[n] = rssConf->indTable[n]; + return 0; + +} + +static int +vmxnet3_set_rss_indir(struct net_device *netdev, + const struct ethtool_rxfh_indir *p) +{ + unsigned int i; + struct vmxnet3_adapter *adapter = netdev_priv(netdev); + struct UPT1_RSSConf *rssConf = adapter->rss_conf; + + if (p->size != rssConf->indTableSize) + return -EINVAL; + for (i = 0; i < rssConf->indTableSize; i++) { + /* + * Return with error code if any of the queue indices + * is out of range + */ + if (p->ring_index[i] < 0 || + p->ring_index[i] >= adapter->num_rx_queues) + return -EINVAL; + } + + for (i = 0; i < rssConf->indTableSize; i++) + rssConf->indTable[i] = p->ring_index[i]; + + VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_RSSIDT); + + return 0; + +} + static struct ethtool_ops vmxnet3_ethtool_ops = { .get_settings = vmxnet3_get_settings, .get_drvinfo = vmxnet3_get_drvinfo, @@ -558,6 +622,9 @@ static struct ethtool_ops vmxnet3_ethtool_ops = { .get_ethtool_stats = vmxnet3_get_ethtool_stats, .get_ringparam = vmxnet3_get_ringparam, .set_ringparam = vmxnet3_set_ringparam, + .get_rxnfc = vmxnet3_get_rxnfc, + .get_rxfh_indir = vmxnet3_get_rss_indir, + .set_rxfh_indir = vmxnet3_set_rss_indir, }; void vmxnet3_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index edf228843afc..7fadeed37f03 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -68,11 +68,15 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.0.14.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.0.16.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01000E00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01001000 +#if defined(CONFIG_PCI_MSI) + /* RSS only makes sense if MSI-X is supported. */ + #define VMXNET3_RSS +#endif /* * Capabilities @@ -218,16 +222,19 @@ struct vmxnet3_tx_ctx { }; struct vmxnet3_tx_queue { + char name[IFNAMSIZ+8]; /* To identify interrupt */ + struct vmxnet3_adapter *adapter; spinlock_t tx_lock; struct vmxnet3_cmd_ring tx_ring; - struct vmxnet3_tx_buf_info *buf_info; + struct vmxnet3_tx_buf_info *buf_info; struct vmxnet3_tx_data_ring data_ring; struct vmxnet3_comp_ring comp_ring; - struct Vmxnet3_TxQueueCtrl *shared; + struct Vmxnet3_TxQueueCtrl *shared; struct vmxnet3_tq_driver_stats stats; bool stopped; int num_stop; /* # of times the queue is * stopped */ + int qid; } __attribute__((__aligned__(SMP_CACHE_BYTES))); enum vmxnet3_rx_buf_type { @@ -259,6 +266,9 @@ struct vmxnet3_rq_driver_stats { }; struct vmxnet3_rx_queue { + char name[IFNAMSIZ + 8]; /* To identify interrupt */ + struct vmxnet3_adapter *adapter; + struct napi_struct napi; struct vmxnet3_cmd_ring rx_ring[2]; struct vmxnet3_comp_ring comp_ring; struct vmxnet3_rx_ctx rx_ctx; @@ -271,7 +281,16 @@ struct vmxnet3_rx_queue { struct vmxnet3_rq_driver_stats stats; } __attribute__((__aligned__(SMP_CACHE_BYTES))); -#define VMXNET3_LINUX_MAX_MSIX_VECT 1 +#define VMXNET3_DEVICE_MAX_TX_QUEUES 8 +#define VMXNET3_DEVICE_MAX_RX_QUEUES 8 /* Keep this value as a power of 2 */ + +/* Should be less than UPT1_RSS_MAX_IND_TABLE_SIZE */ +#define VMXNET3_RSS_IND_TABLE_SIZE (VMXNET3_DEVICE_MAX_RX_QUEUES * 4) + +#define VMXNET3_LINUX_MAX_MSIX_VECT (VMXNET3_DEVICE_MAX_TX_QUEUES + \ + VMXNET3_DEVICE_MAX_RX_QUEUES + 1) +#define VMXNET3_LINUX_MIN_MSIX_VECT 3 /* 1 for each : tx, rx and event */ + struct vmxnet3_intr { enum vmxnet3_intr_mask_mode mask_mode; @@ -279,27 +298,32 @@ struct vmxnet3_intr { u8 num_intrs; /* # of intr vectors */ u8 event_intr_idx; /* idx of the intr vector for event */ u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */ + char event_msi_vector_name[IFNAMSIZ+11]; #ifdef CONFIG_PCI_MSI struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT]; #endif }; +/* Interrupt sharing schemes, share_intr */ +#define VMXNET3_INTR_BUDDYSHARE 0 /* Corresponding tx,rx queues share irq */ +#define VMXNET3_INTR_TXSHARE 1 /* All tx queues share one irq */ +#define VMXNET3_INTR_DONTSHARE 2 /* each queue has its own irq */ + + #define VMXNET3_STATE_BIT_RESETTING 0 #define VMXNET3_STATE_BIT_QUIESCED 1 struct vmxnet3_adapter { - struct vmxnet3_tx_queue tx_queue; - struct vmxnet3_rx_queue rx_queue; - struct napi_struct napi; - struct vlan_group *vlan_grp; - - struct vmxnet3_intr intr; - - struct Vmxnet3_DriverShared *shared; - struct Vmxnet3_PMConf *pm_conf; - struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */ - struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */ - struct net_device *netdev; - struct pci_dev *pdev; + struct vmxnet3_tx_queue tx_queue[VMXNET3_DEVICE_MAX_TX_QUEUES]; + struct vmxnet3_rx_queue rx_queue[VMXNET3_DEVICE_MAX_RX_QUEUES]; + struct vlan_group *vlan_grp; + struct vmxnet3_intr intr; + struct Vmxnet3_DriverShared *shared; + struct Vmxnet3_PMConf *pm_conf; + struct Vmxnet3_TxQueueDesc *tqd_start; /* all tx queue desc */ + struct Vmxnet3_RxQueueDesc *rqd_start; /* all rx queue desc */ + struct net_device *netdev; + struct net_device_stats net_stats; + struct pci_dev *pdev; u8 __iomem *hw_addr0; /* for BAR 0 */ u8 __iomem *hw_addr1; /* for BAR 1 */ @@ -308,6 +332,12 @@ struct vmxnet3_adapter { bool rxcsum; bool lro; bool jumbo_frame; +#ifdef VMXNET3_RSS + struct UPT1_RSSConf *rss_conf; + bool rss; +#endif + u32 num_rx_queues; + u32 num_tx_queues; /* rx buffer related */ unsigned skb_buf_size; @@ -327,6 +357,7 @@ struct vmxnet3_adapter { unsigned long state; /* VMXNET3_STATE_BIT_xxx */ int dev_number; + int share_intr; }; #define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \ @@ -366,12 +397,10 @@ void vmxnet3_reset_dev(struct vmxnet3_adapter *adapter); void -vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, - struct vmxnet3_adapter *adapter); +vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter); void -vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, - struct vmxnet3_adapter *adapter); +vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, -- cgit v1.2.3-59-g8ed1b From 9a2d09cf61c9d9f1b31998bec5363a583e4564a4 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Sun, 21 Nov 2010 09:55:10 -0800 Subject: ixgbe: update version number for ixgbe This will reflect addition of new X540 hardware Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5409af3da06c..025419567440 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -52,7 +52,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "2.0.84-k2" +#define DRV_VERSION "3.0.12-k2" const char ixgbe_driver_version[] = DRV_VERSION; static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; -- cgit v1.2.3-59-g8ed1b From bbce5a59e4e0e6e1dbc85492caaf310ff6611309 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 20 Nov 2010 07:31:54 +0000 Subject: packet: use vzalloc() alloc_one_pg_vec_page() is supposed to return zeroed memory, so use vzalloc() instead of vmalloc() Signed-off-by: Eric Dumazet Cc: Neil Horman Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/packet/af_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index b6372dd128d7..422705d62b5b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2367,7 +2367,7 @@ static inline char *alloc_one_pg_vec_page(unsigned long order, * __get_free_pages failed, fall back to vmalloc */ *flags |= PGV_FROM_VMALLOC; - buffer = vmalloc((1 << order) * PAGE_SIZE); + buffer = vzalloc((1 << order) * PAGE_SIZE); if (buffer) return buffer; -- cgit v1.2.3-59-g8ed1b From 20a95a2169d1cd3da50cf65ba882d0e27a4a2d4f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 20 Nov 2010 18:07:21 +0000 Subject: netns: let net_generic take pointer-to-const args This commit is same in nature as v2.6.37-rc1-755-g3654654; the network namespace itself is not modified when calling net_generic, so the parameter can be const. Signed-off-by: Jan Engelhardt Signed-off-by: David S. Miller --- include/net/netns/generic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h index 81a31c0db3e7..3419bf5cd154 100644 --- a/include/net/netns/generic.h +++ b/include/net/netns/generic.h @@ -30,7 +30,7 @@ struct net_generic { void *ptr[0]; }; -static inline void *net_generic(struct net *net, int id) +static inline void *net_generic(const struct net *net, int id) { struct net_generic *ng; void *ptr; -- cgit v1.2.3-59-g8ed1b From 551eaff1b384cc107eab6332ba8424b3ca1f304b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 21 Nov 2010 10:26:44 -0800 Subject: pktgen: allow faster module unload Unloading pktgen module needs ~6 seconds on a 64 cpus machine, to stop 64 kthreads. Add a pktgen_exiting variable to let kernel threads die faster, so that kthread_stop() doesnt have to wait too long for them. This variable is not tested in fast path. Note : Before exiting from pktgen_thread_worker(), we must make sure kthread_stop() is waiting for this thread to be stopped, like its done in kernel/softirq.c Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/pktgen.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 52fc1e08a7c4..2e57830cbeb2 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -395,6 +395,8 @@ struct pktgen_hdr { __be32 tv_usec; }; +static bool pktgen_exiting __read_mostly; + struct pktgen_thread { spinlock_t if_lock; /* for list of devices */ struct list_head if_list; /* All device here */ @@ -3451,11 +3453,6 @@ static void pktgen_rem_thread(struct pktgen_thread *t) remove_proc_entry(t->tsk->comm, pg_proc_dir); - mutex_lock(&pktgen_thread_lock); - - list_del(&t->th_list); - - mutex_unlock(&pktgen_thread_lock); } static void pktgen_resched(struct pktgen_dev *pkt_dev) @@ -3602,6 +3599,8 @@ static int pktgen_thread_worker(void *arg) pkt_dev = next_to_run(t); if (unlikely(!pkt_dev && t->control == 0)) { + if (pktgen_exiting) + break; wait_event_interruptible_timeout(t->queue, t->control != 0, HZ/10); @@ -3654,6 +3653,13 @@ static int pktgen_thread_worker(void *arg) pr_debug("%s removing thread\n", t->tsk->comm); pktgen_rem_thread(t); + /* Wait for kthread_stop */ + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + __set_current_state(TASK_RUNNING); + return 0; } @@ -3928,6 +3934,7 @@ static void __exit pg_cleanup(void) struct list_head *q, *n; /* Stop all interfaces & threads */ + pktgen_exiting = true; list_for_each_safe(q, n, &pktgen_threads) { t = list_entry(q, struct pktgen_thread, th_list); -- cgit v1.2.3-59-g8ed1b From 00d201001bd4e8a46e3d03c970abcb72256c368b Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Mon, 8 Nov 2010 11:20:10 +0000 Subject: wl1271: Change wl12xx Files Names All files name prefix removed due to the fact that wl12xx driver supports wl1271 and wl1273. Also the definition in Kconfig and header files changed respectively. Signed-off-by: Shahar Levi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 52 +- drivers/net/wireless/wl12xx/Makefile | 17 +- drivers/net/wireless/wl12xx/acx.c | 1336 ++++++++++++ drivers/net/wireless/wl12xx/acx.h | 1185 +++++++++++ drivers/net/wireless/wl12xx/boot.c | 591 ++++++ drivers/net/wireless/wl12xx/boot.h | 71 + drivers/net/wireless/wl12xx/cmd.c | 783 +++++++ drivers/net/wireless/wl12xx/cmd.h | 459 +++++ drivers/net/wireless/wl12xx/conf.h | 1105 ++++++++++ drivers/net/wireless/wl12xx/debugfs.c | 590 ++++++ drivers/net/wireless/wl12xx/debugfs.h | 33 + drivers/net/wireless/wl12xx/event.c | 293 +++ drivers/net/wireless/wl12xx/event.h | 126 ++ drivers/net/wireless/wl12xx/ini.h | 123 ++ drivers/net/wireless/wl12xx/init.c | 369 ++++ drivers/net/wireless/wl12xx/init.h | 36 + drivers/net/wireless/wl12xx/io.c | 170 ++ drivers/net/wireless/wl12xx/io.h | 172 ++ drivers/net/wireless/wl12xx/main.c | 2749 +++++++++++++++++++++++++ drivers/net/wireless/wl12xx/ps.c | 178 ++ drivers/net/wireless/wl12xx/ps.h | 36 + drivers/net/wireless/wl12xx/reg.h | 614 ++++++ drivers/net/wireless/wl12xx/rx.c | 203 ++ drivers/net/wireless/wl12xx/rx.h | 121 ++ drivers/net/wireless/wl12xx/scan.c | 307 +++ drivers/net/wireless/wl12xx/scan.h | 109 + drivers/net/wireless/wl12xx/sdio.c | 347 ++++ drivers/net/wireless/wl12xx/spi.c | 498 +++++ drivers/net/wireless/wl12xx/testmode.c | 290 +++ drivers/net/wireless/wl12xx/testmode.h | 31 + drivers/net/wireless/wl12xx/tx.c | 485 +++++ drivers/net/wireless/wl12xx/tx.h | 150 ++ drivers/net/wireless/wl12xx/wl1271.h | 523 ----- drivers/net/wireless/wl12xx/wl1271_acx.c | 1336 ------------ drivers/net/wireless/wl12xx/wl1271_acx.h | 1185 ----------- drivers/net/wireless/wl12xx/wl1271_boot.c | 591 ------ drivers/net/wireless/wl12xx/wl1271_boot.h | 71 - drivers/net/wireless/wl12xx/wl1271_cmd.c | 783 ------- drivers/net/wireless/wl12xx/wl1271_cmd.h | 459 ----- drivers/net/wireless/wl12xx/wl1271_conf.h | 1105 ---------- drivers/net/wireless/wl12xx/wl1271_debugfs.c | 590 ------ drivers/net/wireless/wl12xx/wl1271_debugfs.h | 33 - drivers/net/wireless/wl12xx/wl1271_event.c | 293 --- drivers/net/wireless/wl12xx/wl1271_event.h | 126 -- drivers/net/wireless/wl12xx/wl1271_ini.h | 123 -- drivers/net/wireless/wl12xx/wl1271_init.c | 369 ---- drivers/net/wireless/wl12xx/wl1271_init.h | 36 - drivers/net/wireless/wl12xx/wl1271_io.c | 170 -- drivers/net/wireless/wl12xx/wl1271_io.h | 172 -- drivers/net/wireless/wl12xx/wl1271_main.c | 2749 ------------------------- drivers/net/wireless/wl12xx/wl1271_ps.c | 178 -- drivers/net/wireless/wl12xx/wl1271_ps.h | 36 - drivers/net/wireless/wl12xx/wl1271_reg.h | 614 ------ drivers/net/wireless/wl12xx/wl1271_rx.c | 203 -- drivers/net/wireless/wl12xx/wl1271_rx.h | 121 -- drivers/net/wireless/wl12xx/wl1271_scan.c | 307 --- drivers/net/wireless/wl12xx/wl1271_scan.h | 109 - drivers/net/wireless/wl12xx/wl1271_sdio.c | 347 ---- drivers/net/wireless/wl12xx/wl1271_spi.c | 498 ----- drivers/net/wireless/wl12xx/wl1271_testmode.c | 290 --- drivers/net/wireless/wl12xx/wl1271_testmode.h | 31 - drivers/net/wireless/wl12xx/wl1271_tx.c | 485 ----- drivers/net/wireless/wl12xx/wl1271_tx.h | 150 -- drivers/net/wireless/wl12xx/wl12xx.h | 523 +++++ 64 files changed, 14119 insertions(+), 14116 deletions(-) create mode 100644 drivers/net/wireless/wl12xx/acx.c create mode 100644 drivers/net/wireless/wl12xx/acx.h create mode 100644 drivers/net/wireless/wl12xx/boot.c create mode 100644 drivers/net/wireless/wl12xx/boot.h create mode 100644 drivers/net/wireless/wl12xx/cmd.c create mode 100644 drivers/net/wireless/wl12xx/cmd.h create mode 100644 drivers/net/wireless/wl12xx/conf.h create mode 100644 drivers/net/wireless/wl12xx/debugfs.c create mode 100644 drivers/net/wireless/wl12xx/debugfs.h create mode 100644 drivers/net/wireless/wl12xx/event.c create mode 100644 drivers/net/wireless/wl12xx/event.h create mode 100644 drivers/net/wireless/wl12xx/ini.h create mode 100644 drivers/net/wireless/wl12xx/init.c create mode 100644 drivers/net/wireless/wl12xx/init.h create mode 100644 drivers/net/wireless/wl12xx/io.c create mode 100644 drivers/net/wireless/wl12xx/io.h create mode 100644 drivers/net/wireless/wl12xx/main.c create mode 100644 drivers/net/wireless/wl12xx/ps.c create mode 100644 drivers/net/wireless/wl12xx/ps.h create mode 100644 drivers/net/wireless/wl12xx/reg.h create mode 100644 drivers/net/wireless/wl12xx/rx.c create mode 100644 drivers/net/wireless/wl12xx/rx.h create mode 100644 drivers/net/wireless/wl12xx/scan.c create mode 100644 drivers/net/wireless/wl12xx/scan.h create mode 100644 drivers/net/wireless/wl12xx/sdio.c create mode 100644 drivers/net/wireless/wl12xx/spi.c create mode 100644 drivers/net/wireless/wl12xx/testmode.c create mode 100644 drivers/net/wireless/wl12xx/testmode.h create mode 100644 drivers/net/wireless/wl12xx/tx.c create mode 100644 drivers/net/wireless/wl12xx/tx.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_acx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_acx.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_boot.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_boot.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_cmd.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_cmd.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_conf.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_debugfs.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_debugfs.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_event.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_event.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_ini.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_init.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_init.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_io.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_io.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_main.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_ps.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_ps.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_reg.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_rx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_rx.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_scan.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_scan.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_sdio.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_spi.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_testmode.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_testmode.h delete mode 100644 drivers/net/wireless/wl12xx/wl1271_tx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_tx.h create mode 100644 drivers/net/wireless/wl12xx/wl12xx.h diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 02ad4bc15976..d2adeb1f72b7 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -1,56 +1,58 @@ -menuconfig WL12XX +menuconfig WL12XX_MENU tristate "TI wl12xx driver support" depends on MAC80211 && EXPERIMENTAL ---help--- - This will enable TI wl12xx driver support. The drivers make - use of the mac80211 stack. + This will enable TI wl12xx driver support for the following chips: + wl1271 and wl1273. + The drivers make use of the mac80211 stack. -config WL1271 - tristate "TI wl1271 support" - depends on WL12XX && GENERIC_HARDIRQS +config WL12XX + tristate "TI wl12xx support" + depends on WL12XX_MENU && GENERIC_HARDIRQS depends on INET select FW_LOADER select CRC7 ---help--- - This module adds support for wireless adapters based on the - TI wl1271 chipset. + This module adds support for wireless adapters based on TI wl1271 and + TI wl1273 chipsets. This module does *not* include support for wl1251. + For wl1251 support, use the separate homonymous driver instead. - If you choose to build a module, it'll be called wl1271. Say N if + If you choose to build a module, it will be called wl12xx. Say N if unsure. -config WL1271_HT - bool "TI wl1271 802.11 HT support (EXPERIMENTAL)" - depends on WL1271 && EXPERIMENTAL +config WL12XX_HT + bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)" + depends on WL12XX && EXPERIMENTAL default n ---help--- - This will enable 802.11 HT support for TI wl1271 chipset. + This will enable 802.11 HT support in the wl12xx module. That configuration is temporary due to the code incomplete and still in testing process. -config WL1271_SPI - tristate "TI wl1271 SPI support" - depends on WL1271 && SPI_MASTER +config WL12XX_SPI + tristate "TI wl12xx SPI support" + depends on WL12XX && SPI_MASTER ---help--- This module adds support for the SPI interface of adapters using - TI wl1271 chipset. Select this if your platform is using + TI wl12xx chipsets. Select this if your platform is using the SPI bus. - If you choose to build a module, it'll be called wl1251_spi. + If you choose to build a module, it'll be called wl12xx_spi. Say N if unsure. -config WL1271_SDIO - tristate "TI wl1271 SDIO support" - depends on WL1271 && MMC +config WL12XX_SDIO + tristate "TI wl12xx SDIO support" + depends on WL12XX && MMC ---help--- This module adds support for the SDIO interface of adapters using - TI wl1271 chipset. Select this if your platform is using + TI wl12xx chipsets. Select this if your platform is using the SDIO bus. - If you choose to build a module, it'll be called - wl1271_sdio. Say N if unsure. + If you choose to build a module, it'll be called wl12xx_sdio. + Say N if unsure. config WL12XX_PLATFORM_DATA bool - depends on WL1271_SDIO != n || WL1251_SDIO != n + depends on WL12XX_SDIO != n || WL1251_SDIO != n default y diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 3a807444b2af..005a758174d9 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -1,12 +1,13 @@ -wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ - wl1271_event.o wl1271_tx.o wl1271_rx.o \ - wl1271_ps.o wl1271_acx.o wl1271_boot.o \ - wl1271_init.o wl1271_debugfs.o wl1271_scan.o +wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \ + boot.o init.o debugfs.o scan.o -wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o -obj-$(CONFIG_WL1271) += wl1271.o -obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o -obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o +wl12xx_spi-objs = spi.o +wl12xx_sdio-objs = sdio.o + +wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_WL12XX) += wl12xx.o +obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o +obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o # small builtin driver bit obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c new file mode 100644 index 000000000000..bc1085bb6cfb --- /dev/null +++ b/drivers/net/wireless/wl12xx/acx.c @@ -0,0 +1,1336 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "acx.h" + +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "wl12xx_80211.h" +#include "reg.h" +#include "ps.h" + +int wl1271_acx_wake_up_conditions(struct wl1271 *wl) +{ + struct acx_wake_up_condition *wake_up; + int ret; + + wl1271_debug(DEBUG_ACX, "acx wake up conditions"); + + wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); + if (!wake_up) { + ret = -ENOMEM; + goto out; + } + + wake_up->wake_up_event = wl->conf.conn.wake_up_event; + wake_up->listen_interval = wl->conf.conn.listen_interval; + + ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, + wake_up, sizeof(*wake_up)); + if (ret < 0) { + wl1271_warning("could not set wake up conditions: %d", ret); + goto out; + } + +out: + kfree(wake_up); + return ret; +} + +int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) +{ + struct acx_sleep_auth *auth; + int ret; + + wl1271_debug(DEBUG_ACX, "acx sleep auth"); + + auth = kzalloc(sizeof(*auth), GFP_KERNEL); + if (!auth) { + ret = -ENOMEM; + goto out; + } + + auth->sleep_auth = sleep_auth; + + ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); + if (ret < 0) + return ret; + +out: + kfree(auth); + return ret; +} + +int wl1271_acx_tx_power(struct wl1271 *wl, int power) +{ + struct acx_current_tx_power *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); + + if (power < 0 || power > 25) + return -EINVAL; + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->current_tx_power = power * 10; + + ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("configure of tx power failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_feature_cfg(struct wl1271 *wl) +{ + struct acx_feature_config *feature; + int ret; + + wl1271_debug(DEBUG_ACX, "acx feature cfg"); + + feature = kzalloc(sizeof(*feature), GFP_KERNEL); + if (!feature) { + ret = -ENOMEM; + goto out; + } + + /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ + feature->data_flow_options = 0; + feature->options = 0; + + ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG, + feature, sizeof(*feature)); + if (ret < 0) { + wl1271_error("Couldnt set HW encryption"); + goto out; + } + +out: + kfree(feature); + return ret; +} + +int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map, + size_t len) +{ + int ret; + + wl1271_debug(DEBUG_ACX, "acx mem map"); + + ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); + if (ret < 0) + return ret; + + return 0; +} + +int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl) +{ + struct acx_rx_msdu_lifetime *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx rx msdu life time"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time); + ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to set rx msdu life time: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter) +{ + struct acx_rx_config *rx_config; + int ret; + + wl1271_debug(DEBUG_ACX, "acx rx config"); + + rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); + if (!rx_config) { + ret = -ENOMEM; + goto out; + } + + rx_config->config_options = cpu_to_le32(config); + rx_config->filter_options = cpu_to_le32(filter); + + ret = wl1271_cmd_configure(wl, ACX_RX_CFG, + rx_config, sizeof(*rx_config)); + if (ret < 0) { + wl1271_warning("failed to set rx config: %d", ret); + goto out; + } + +out: + kfree(rx_config); + return ret; +} + +int wl1271_acx_pd_threshold(struct wl1271 *wl) +{ + struct acx_packet_detection *pd; + int ret; + + wl1271_debug(DEBUG_ACX, "acx data pd threshold"); + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + ret = -ENOMEM; + goto out; + } + + pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold); + + ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); + if (ret < 0) { + wl1271_warning("failed to set pd threshold: %d", ret); + goto out; + } + +out: + kfree(pd); + return ret; +} + +int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time) +{ + struct acx_slot *slot; + int ret; + + wl1271_debug(DEBUG_ACX, "acx slot"); + + slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) { + ret = -ENOMEM; + goto out; + } + + slot->wone_index = STATION_WONE_INDEX; + slot->slot_time = slot_time; + + ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); + if (ret < 0) { + wl1271_warning("failed to set slot time: %d", ret); + goto out; + } + +out: + kfree(slot); + return ret; +} + +int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, + void *mc_list, u32 mc_list_len) +{ + struct acx_dot11_grp_addr_tbl *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx group address tbl"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* MAC filtering */ + acx->enabled = enable; + acx->num_groups = mc_list_len; + memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN); + + ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to set group addr table: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_service_period_timeout(struct wl1271 *wl) +{ + struct acx_rx_timeout *rx_timeout; + int ret; + + rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); + if (!rx_timeout) { + ret = -ENOMEM; + goto out; + } + + wl1271_debug(DEBUG_ACX, "acx service period timeout"); + + rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout); + rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout); + + ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, + rx_timeout, sizeof(*rx_timeout)); + if (ret < 0) { + wl1271_warning("failed to set service period timeout: %d", + ret); + goto out; + } + +out: + kfree(rx_timeout); + return ret; +} + +int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold) +{ + struct acx_rts_threshold *rts; + int ret; + + wl1271_debug(DEBUG_ACX, "acx rts threshold"); + + rts = kzalloc(sizeof(*rts), GFP_KERNEL); + if (!rts) { + ret = -ENOMEM; + goto out; + } + + rts->threshold = cpu_to_le16(rts_threshold); + + ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); + if (ret < 0) { + wl1271_warning("failed to set rts threshold: %d", ret); + goto out; + } + +out: + kfree(rts); + return ret; +} + +int wl1271_acx_dco_itrim_params(struct wl1271 *wl) +{ + struct acx_dco_itrim_params *dco; + struct conf_itrim_settings *c = &wl->conf.itrim; + int ret; + + wl1271_debug(DEBUG_ACX, "acx dco itrim parameters"); + + dco = kzalloc(sizeof(*dco), GFP_KERNEL); + if (!dco) { + ret = -ENOMEM; + goto out; + } + + dco->enable = c->enable; + dco->timeout = cpu_to_le32(c->timeout); + + ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS, + dco, sizeof(*dco)); + if (ret < 0) { + wl1271_warning("failed to set dco itrim parameters: %d", ret); + goto out; + } + +out: + kfree(dco); + return ret; +} + +int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter) +{ + struct acx_beacon_filter_option *beacon_filter = NULL; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); + + if (enable_filter && + wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) + goto out; + + beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); + if (!beacon_filter) { + ret = -ENOMEM; + goto out; + } + + beacon_filter->enable = enable_filter; + + /* + * When set to zero, and the filter is enabled, beacons + * without the unicast TIM bit set are dropped. + */ + beacon_filter->max_num_beacons = 0; + + ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT, + beacon_filter, sizeof(*beacon_filter)); + if (ret < 0) { + wl1271_warning("failed to set beacon filter opt: %d", ret); + goto out; + } + +out: + kfree(beacon_filter); + return ret; +} + +int wl1271_acx_beacon_filter_table(struct wl1271 *wl) +{ + struct acx_beacon_filter_ie_table *ie_table; + int i, idx = 0; + int ret; + bool vendor_spec = false; + + wl1271_debug(DEBUG_ACX, "acx beacon filter table"); + + ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); + if (!ie_table) { + ret = -ENOMEM; + goto out; + } + + /* configure default beacon pass-through rules */ + ie_table->num_ie = 0; + for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) { + struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]); + ie_table->table[idx++] = r->ie; + ie_table->table[idx++] = r->rule; + + if (r->ie == WLAN_EID_VENDOR_SPECIFIC) { + /* only one vendor specific ie allowed */ + if (vendor_spec) + continue; + + /* for vendor specific rules configure the + additional fields */ + memcpy(&(ie_table->table[idx]), r->oui, + CONF_BCN_IE_OUI_LEN); + idx += CONF_BCN_IE_OUI_LEN; + ie_table->table[idx++] = r->type; + memcpy(&(ie_table->table[idx]), r->version, + CONF_BCN_IE_VER_LEN); + idx += CONF_BCN_IE_VER_LEN; + vendor_spec = true; + } + + ie_table->num_ie++; + } + + ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, + ie_table, sizeof(*ie_table)); + if (ret < 0) { + wl1271_warning("failed to set beacon filter table: %d", ret); + goto out; + } + +out: + kfree(ie_table); + return ret; +} + +#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff + +int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable) +{ + struct acx_conn_monit_params *acx; + u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE; + u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE; + int ret; + + wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s", + enable ? "enabled" : "disabled"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + if (enable) { + threshold = wl->conf.conn.synch_fail_thold; + timeout = wl->conf.conn.bss_lose_timeout; + } + + acx->synch_fail_thold = cpu_to_le32(threshold); + acx->bss_lose_timeout = cpu_to_le32(timeout); + + ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to set connection monitor " + "parameters: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + + +int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) +{ + struct acx_bt_wlan_coex *pta; + int ret; + + wl1271_debug(DEBUG_ACX, "acx sg enable"); + + pta = kzalloc(sizeof(*pta), GFP_KERNEL); + if (!pta) { + ret = -ENOMEM; + goto out; + } + + if (enable) + pta->enable = wl->conf.sg.state; + else + pta->enable = CONF_SG_DISABLE; + + ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); + if (ret < 0) { + wl1271_warning("failed to set softgemini enable: %d", ret); + goto out; + } + +out: + kfree(pta); + return ret; +} + +int wl1271_acx_sg_cfg(struct wl1271 *wl) +{ + struct acx_bt_wlan_coex_param *param; + struct conf_sg_settings *c = &wl->conf.sg; + int i, ret; + + wl1271_debug(DEBUG_ACX, "acx sg cfg"); + + param = kzalloc(sizeof(*param), GFP_KERNEL); + if (!param) { + ret = -ENOMEM; + goto out; + } + + /* BT-WLAN coext parameters */ + for (i = 0; i < CONF_SG_PARAMS_MAX; i++) + param->params[i] = cpu_to_le32(c->params[i]); + param->param_idx = CONF_SG_PARAMS_ALL; + + ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); + if (ret < 0) { + wl1271_warning("failed to set sg config: %d", ret); + goto out; + } + +out: + kfree(param); + return ret; +} + +int wl1271_acx_cca_threshold(struct wl1271 *wl) +{ + struct acx_energy_detection *detection; + int ret; + + wl1271_debug(DEBUG_ACX, "acx cca threshold"); + + detection = kzalloc(sizeof(*detection), GFP_KERNEL); + if (!detection) { + ret = -ENOMEM; + goto out; + } + + detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold); + detection->tx_energy_detection = wl->conf.tx.tx_energy_detection; + + ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, + detection, sizeof(*detection)); + if (ret < 0) { + wl1271_warning("failed to set cca threshold: %d", ret); + return ret; + } + +out: + kfree(detection); + return ret; +} + +int wl1271_acx_bcn_dtim_options(struct wl1271 *wl) +{ + struct acx_beacon_broadcast *bb; + int ret; + + wl1271_debug(DEBUG_ACX, "acx bcn dtim options"); + + bb = kzalloc(sizeof(*bb), GFP_KERNEL); + if (!bb) { + ret = -ENOMEM; + goto out; + } + + bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout); + bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout); + bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps; + bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold; + + ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); + if (ret < 0) { + wl1271_warning("failed to set rx config: %d", ret); + goto out; + } + +out: + kfree(bb); + return ret; +} + +int wl1271_acx_aid(struct wl1271 *wl, u16 aid) +{ + struct acx_aid *acx_aid; + int ret; + + wl1271_debug(DEBUG_ACX, "acx aid"); + + acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); + if (!acx_aid) { + ret = -ENOMEM; + goto out; + } + + acx_aid->aid = cpu_to_le16(aid); + + ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); + if (ret < 0) { + wl1271_warning("failed to set aid: %d", ret); + goto out; + } + +out: + kfree(acx_aid); + return ret; +} + +int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask) +{ + struct acx_event_mask *mask; + int ret; + + wl1271_debug(DEBUG_ACX, "acx event mbox mask"); + + mask = kzalloc(sizeof(*mask), GFP_KERNEL); + if (!mask) { + ret = -ENOMEM; + goto out; + } + + /* high event mask is unused */ + mask->high_event_mask = cpu_to_le32(0xffffffff); + mask->event_mask = cpu_to_le32(event_mask); + + ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK, + mask, sizeof(*mask)); + if (ret < 0) { + wl1271_warning("failed to set acx_event_mbox_mask: %d", ret); + goto out; + } + +out: + kfree(mask); + return ret; +} + +int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble) +{ + struct acx_preamble *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx_set_preamble"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->preamble = preamble; + + ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of preamble failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_cts_protect(struct wl1271 *wl, + enum acx_ctsprotect_type ctsprotect) +{ + struct acx_ctsprotect *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ctsprotect = ctsprotect; + + ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of ctsprotect failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) +{ + int ret; + + wl1271_debug(DEBUG_ACX, "acx statistics"); + + ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, + sizeof(*stats)); + if (ret < 0) { + wl1271_warning("acx statistics failed: %d", ret); + return -ENOMEM; + } + + return 0; +} + +int wl1271_acx_rate_policies(struct wl1271 *wl) +{ + struct acx_rate_policy *acx; + struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; + int idx = 0; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx rate policies"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* configure one basic rate class */ + idx = ACX_TX_BASIC_RATE; + acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate); + acx->rate_class[idx].short_retry_limit = c->short_retry_limit; + acx->rate_class[idx].long_retry_limit = c->long_retry_limit; + acx->rate_class[idx].aflags = c->aflags; + + /* configure one AP supported rate class */ + idx = ACX_TX_AP_FULL_RATE; + acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set); + acx->rate_class[idx].short_retry_limit = c->short_retry_limit; + acx->rate_class[idx].long_retry_limit = c->long_retry_limit; + acx->rate_class[idx].aflags = c->aflags; + + acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); + + ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of rate policies failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, + u8 aifsn, u16 txop) +{ + struct acx_ac_cfg *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " + "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ac = ac; + acx->cw_min = cw_min; + acx->cw_max = cpu_to_le16(cw_max); + acx->aifsn = aifsn; + acx->tx_op_limit = cpu_to_le16(txop); + + ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx ac cfg failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, + u8 tsid, u8 ps_scheme, u8 ack_policy, + u32 apsd_conf0, u32 apsd_conf1) +{ + struct acx_tid_config *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx tid config"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->queue_id = queue_id; + acx->channel_type = channel_type; + acx->tsid = tsid; + acx->ps_scheme = ps_scheme; + acx->ack_policy = ack_policy; + acx->apsd_conf[0] = cpu_to_le32(apsd_conf0); + acx->apsd_conf[1] = cpu_to_le32(apsd_conf1); + + ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of tid config failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_frag_threshold(struct wl1271 *wl) +{ + struct acx_frag_threshold *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx frag threshold"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold); + ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of frag threshold failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_tx_config_options(struct wl1271 *wl) +{ + struct acx_tx_config_options *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx tx config options"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout); + acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold); + ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of tx options failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_mem_cfg(struct wl1271 *wl) +{ + struct wl1271_acx_config_memory *mem_conf; + int ret; + + wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); + + mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); + if (!mem_conf) { + ret = -ENOMEM; + goto out; + } + + /* memory config */ + mem_conf->num_stations = DEFAULT_NUM_STATIONS; + mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; + mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; + mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; + mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); + + ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, + sizeof(*mem_conf)); + if (ret < 0) { + wl1271_warning("wl1271 mem config failed: %d", ret); + goto out; + } + +out: + kfree(mem_conf); + return ret; +} + +int wl1271_acx_init_mem_config(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_mem_cfg(wl); + if (ret < 0) + return ret; + + wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), + GFP_KERNEL); + if (!wl->target_mem_map) { + wl1271_error("couldn't allocate target memory map"); + return -ENOMEM; + } + + /* we now ask for the firmware built memory map */ + ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map, + sizeof(struct wl1271_acx_mem_map)); + if (ret < 0) { + wl1271_error("couldn't retrieve firmware memory map"); + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; + return ret; + } + + /* initialize TX block book keeping */ + wl->tx_blocks_available = + le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks); + wl1271_debug(DEBUG_TX, "available tx blocks: %d", + wl->tx_blocks_available); + + return 0; +} + +int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) +{ + struct wl1271_acx_rx_config_opt *rx_conf; + int ret; + + wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config"); + + rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL); + if (!rx_conf) { + ret = -ENOMEM; + goto out; + } + + rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold); + rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout); + rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold); + rx_conf->queue_type = wl->conf.rx.queue_type; + + ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf, + sizeof(*rx_conf)); + if (ret < 0) { + wl1271_warning("wl1271 rx config opt failed: %d", ret); + goto out; + } + +out: + kfree(rx_conf); + return ret; +} + +int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable) +{ + struct wl1271_acx_bet_enable *acx = NULL; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx bet enable"); + + if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE) + goto out; + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE; + acx->max_consecutive = wl->conf.conn.bet_max_consecutive; + + ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx bet enable failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) +{ + struct wl1271_acx_arp_filter *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->version = ACX_IPV4_VERSION; + acx->enable = enable; + + if (enable == true) + memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); + + ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to set arp ip filter: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_pm_config(struct wl1271 *wl) +{ + struct wl1271_acx_pm_config *acx = NULL; + struct conf_pm_config_settings *c = &wl->conf.pm_config; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx pm config"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time); + acx->host_fast_wakeup_support = c->host_fast_wakeup_support; + + ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx pm config failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable) +{ + struct wl1271_acx_keep_alive_mode *acx = NULL; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->enabled = enable; + + ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx keep alive mode failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid) +{ + struct wl1271_acx_keep_alive_config *acx = NULL; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx keep alive config"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval); + acx->index = index; + acx->tpl_validation = tpl_valid; + acx->trigger = ACX_KEEP_ALIVE_NO_TX; + + ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx keep alive config failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, + s16 thold, u8 hyst) +{ + struct wl1271_acx_rssi_snr_trigger *acx = NULL; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + wl->last_rssi_event = -1; + + acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing); + acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON; + acx->type = WL1271_ACX_TRIG_TYPE_EDGE; + if (enable) + acx->enable = WL1271_ACX_TRIG_ENABLE; + else + acx->enable = WL1271_ACX_TRIG_DISABLE; + + acx->index = WL1271_ACX_TRIG_IDX_RSSI; + acx->dir = WL1271_ACX_TRIG_DIR_BIDIR; + acx->threshold = cpu_to_le16(thold); + acx->hysteresis = hyst; + + ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx rssi snr trigger setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl) +{ + struct wl1271_acx_rssi_snr_avg_weights *acx = NULL; + struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->rssi_beacon = c->avg_weight_rssi_beacon; + acx->rssi_data = c->avg_weight_rssi_data; + acx->snr_beacon = c->avg_weight_snr_beacon; + acx->snr_data = c->avg_weight_snr_data; + + ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx rssi snr trigger weights failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, + struct ieee80211_sta_ht_cap *ht_cap, + bool allow_ht_operation) +{ + struct wl1271_acx_ht_capabilities *acx; + u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* Allow HT Operation ? */ + if (allow_ht_operation) { + acx->ht_capabilites = + WL1271_ACX_FW_CAP_HT_OPERATION; + if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; + if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; + if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) + acx->ht_capabilites |= + WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; + + /* get data from A-MPDU parameters field */ + acx->ampdu_max_length = ht_cap->ampdu_factor; + acx->ampdu_min_spacing = ht_cap->ampdu_density; + + memcpy(acx->mac_address, mac_address, ETH_ALEN); + } else { /* HT operations are not allowed */ + acx->ht_capabilites = 0; + } + + ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx ht capabilities setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_set_ht_information(struct wl1271 *wl, + u16 ht_operation_mode) +{ + struct wl1271_acx_ht_information *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ht information setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ht_protection = + (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); + acx->rifs_mode = 0; + acx->gf_protection = 0; + acx->ht_tx_burst_limit = 0; + acx->dual_cts_protection = 0; + + ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx)); + + if (ret < 0) { + wl1271_warning("acx ht information setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) +{ + struct wl1271_acx_fw_tsf_information *tsf_info; + int ret; + + tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); + if (!tsf_info) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, + tsf_info, sizeof(*tsf_info)); + if (ret < 0) { + wl1271_warning("acx tsf info interrogate failed"); + goto out; + } + + *mactime = le32_to_cpu(tsf_info->current_tsf_low) | + ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32); + +out: + kfree(tsf_info); + return ret; +} diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h new file mode 100644 index 000000000000..f41a9c1df12f --- /dev/null +++ b/drivers/net/wireless/wl12xx/acx.h @@ -0,0 +1,1185 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __ACX_H__ +#define __ACX_H__ + +#include "wl12xx.h" +#include "cmd.h" + +/************************************************************************* + + Host Interrupt Register (WiLink -> Host) + +**************************************************************************/ +/* HW Initiated interrupt Watchdog timer expiration */ +#define WL1271_ACX_INTR_WATCHDOG BIT(0) +/* Init sequence is done (masked interrupt, detection through polling only ) */ +#define WL1271_ACX_INTR_INIT_COMPLETE BIT(1) +/* Event was entered to Event MBOX #A*/ +#define WL1271_ACX_INTR_EVENT_A BIT(2) +/* Event was entered to Event MBOX #B*/ +#define WL1271_ACX_INTR_EVENT_B BIT(3) +/* Command processing completion*/ +#define WL1271_ACX_INTR_CMD_COMPLETE BIT(4) +/* Signaling the host on HW wakeup */ +#define WL1271_ACX_INTR_HW_AVAILABLE BIT(5) +/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */ +#define WL1271_ACX_INTR_DATA BIT(6) +/* Trace meassge on MBOX #A */ +#define WL1271_ACX_INTR_TRACE_A BIT(7) +/* Trace meassge on MBOX #B */ +#define WL1271_ACX_INTR_TRACE_B BIT(8) + +#define WL1271_ACX_INTR_ALL 0xFFFFFFFF +#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_INIT_COMPLETE | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_CMD_COMPLETE | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +/* Target's information element */ +struct acx_header { + struct wl1271_cmd_header cmd; + + /* acx (or information element) header */ + __le16 id; + + /* payload length (not including headers */ + __le16 len; +} __packed; + +struct acx_error_counter { + struct acx_header header; + + /* The number of PLCP errors since the last time this */ + /* information element was interrogated. This field is */ + /* automatically cleared when it is interrogated.*/ + __le32 PLCP_error; + + /* The number of FCS errors since the last time this */ + /* information element was interrogated. This field is */ + /* automatically cleared when it is interrogated.*/ + __le32 FCS_error; + + /* The number of MPDUs without PLCP header errors received*/ + /* since the last time this information element was interrogated. */ + /* This field is automatically cleared when it is interrogated.*/ + __le32 valid_frame; + + /* the number of missed sequence numbers in the squentially */ + /* values of frames seq numbers */ + __le32 seq_num_miss; +} __packed; + +enum wl1271_psm_mode { + /* Active mode */ + WL1271_PSM_CAM = 0, + + /* Power save mode */ + WL1271_PSM_PS = 1, + + /* Extreme low power */ + WL1271_PSM_ELP = 2, +}; + +struct acx_sleep_auth { + struct acx_header header; + + /* The sleep level authorization of the device. */ + /* 0 - Always active*/ + /* 1 - Power down mode: light / fast sleep*/ + /* 2 - ELP mode: Deep / Max sleep*/ + u8 sleep_auth; + u8 padding[3]; +} __packed; + +enum { + HOSTIF_PCI_MASTER_HOST_INDIRECT, + HOSTIF_PCI_MASTER_HOST_DIRECT, + HOSTIF_SLAVE, + HOSTIF_PKT_RING, + HOSTIF_DONTCARE = 0xFF +}; + +#define DEFAULT_UCAST_PRIORITY 0 +#define DEFAULT_RX_Q_PRIORITY 0 +#define DEFAULT_NUM_STATIONS 1 +#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ +#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ +#define TRACE_BUFFER_MAX_SIZE 256 + +#define DP_RX_PACKET_RING_CHUNK_SIZE 1600 +#define DP_TX_PACKET_RING_CHUNK_SIZE 1600 +#define DP_RX_PACKET_RING_CHUNK_NUM 2 +#define DP_TX_PACKET_RING_CHUNK_NUM 2 +#define DP_TX_COMPLETE_TIME_OUT 20 + +#define TX_MSDU_LIFETIME_MIN 0 +#define TX_MSDU_LIFETIME_MAX 3000 +#define TX_MSDU_LIFETIME_DEF 512 +#define RX_MSDU_LIFETIME_MIN 0 +#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF +#define RX_MSDU_LIFETIME_DEF 512000 + +struct acx_rx_msdu_lifetime { + struct acx_header header; + + /* + * The maximum amount of time, in TU, before the + * firmware discards the MSDU. + */ + __le32 lifetime; +} __packed; + +/* + * RX Config Options Table + * Bit Definition + * === ========== + * 31:14 Reserved + * 13 Copy RX Status - when set, write three receive status words + * to top of rx'd MPDUs. + * When cleared, do not write three status words (added rev 1.5) + * 12 Reserved + * 11 RX Complete upon FCS error - when set, give rx complete + * interrupt for FCS errors, after the rx filtering, e.g. unicast + * frames not to us with FCS error will not generate an interrupt. + * 10 SSID Filter Enable - When set, the WiLink discards all beacon, + * probe request, and probe response frames with an SSID that does + * not match the SSID specified by the host in the START/JOIN + * command. + * When clear, the WiLink receives frames with any SSID. + * 9 Broadcast Filter Enable - When set, the WiLink discards all + * broadcast frames. When clear, the WiLink receives all received + * broadcast frames. + * 8:6 Reserved + * 5 BSSID Filter Enable - When set, the WiLink discards any frames + * with a BSSID that does not match the BSSID specified by the + * host. + * When clear, the WiLink receives frames from any BSSID. + * 4 MAC Addr Filter - When set, the WiLink discards any frames + * with a destination address that does not match the MAC address + * of the adaptor. + * When clear, the WiLink receives frames destined to any MAC + * address. + * 3 Promiscuous - When set, the WiLink receives all valid frames + * (i.e., all frames that pass the FCS check). + * When clear, only frames that pass the other filters specified + * are received. + * 2 FCS - When set, the WiLink includes the FCS with the received + * frame. + * When cleared, the FCS is discarded. + * 1 PLCP header - When set, write all data from baseband to frame + * buffer including PHY header. + * 0 Reserved - Always equal to 0. + * + * RX Filter Options Table + * Bit Definition + * === ========== + * 31:12 Reserved - Always equal to 0. + * 11 Association - When set, the WiLink receives all association + * related frames (association request/response, reassocation + * request/response, and disassociation). When clear, these frames + * are discarded. + * 10 Auth/De auth - When set, the WiLink receives all authentication + * and de-authentication frames. When clear, these frames are + * discarded. + * 9 Beacon - When set, the WiLink receives all beacon frames. + * When clear, these frames are discarded. + * 8 Contention Free - When set, the WiLink receives all contention + * free frames. + * When clear, these frames are discarded. + * 7 Control - When set, the WiLink receives all control frames. + * When clear, these frames are discarded. + * 6 Data - When set, the WiLink receives all data frames. + * When clear, these frames are discarded. + * 5 FCS Error - When set, the WiLink receives frames that have FCS + * errors. + * When clear, these frames are discarded. + * 4 Management - When set, the WiLink receives all management + * frames. + * When clear, these frames are discarded. + * 3 Probe Request - When set, the WiLink receives all probe request + * frames. + * When clear, these frames are discarded. + * 2 Probe Response - When set, the WiLink receives all probe + * response frames. + * When clear, these frames are discarded. + * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK + * frames. + * When clear, these frames are discarded. + * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames + * that have reserved frame types and sub types as defined by the + * 802.11 specification. + * When clear, these frames are discarded. + */ +struct acx_rx_config { + struct acx_header header; + + __le32 config_options; + __le32 filter_options; +} __packed; + +struct acx_packet_detection { + struct acx_header header; + + __le32 threshold; +} __packed; + + +enum acx_slot_type { + SLOT_TIME_LONG = 0, + SLOT_TIME_SHORT = 1, + DEFAULT_SLOT_TIME = SLOT_TIME_SHORT, + MAX_SLOT_TIMES = 0xFF +}; + +#define STATION_WONE_INDEX 0 + +struct acx_slot { + struct acx_header header; + + u8 wone_index; /* Reserved */ + u8 slot_time; + u8 reserved[6]; +} __packed; + + +#define ACX_MC_ADDRESS_GROUP_MAX (8) +#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX) + +struct acx_dot11_grp_addr_tbl { + struct acx_header header; + + u8 enabled; + u8 num_groups; + u8 pad[2]; + u8 mac_table[ADDRESS_GROUP_MAX_LEN]; +} __packed; + +struct acx_rx_timeout { + struct acx_header header; + + __le16 ps_poll_timeout; + __le16 upsd_timeout; +} __packed; + +struct acx_rts_threshold { + struct acx_header header; + + __le16 threshold; + u8 pad[2]; +} __packed; + +struct acx_beacon_filter_option { + struct acx_header header; + + u8 enable; + + /* + * The number of beacons without the unicast TIM + * bit set that the firmware buffers before + * signaling the host about ready frames. + * When set to 0 and the filter is enabled, beacons + * without the unicast TIM bit set are dropped. + */ + u8 max_num_beacons; + u8 pad[2]; +} __packed; + +/* + * ACXBeaconFilterEntry (not 221) + * Byte Offset Size (Bytes) Definition + * =========== ============ ========== + * 0 1 IE identifier + * 1 1 Treatment bit mask + * + * ACXBeaconFilterEntry (221) + * Byte Offset Size (Bytes) Definition + * =========== ============ ========== + * 0 1 IE identifier + * 1 1 Treatment bit mask + * 2 3 OUI + * 5 1 Type + * 6 2 Version + * + * + * Treatment bit mask - The information element handling: + * bit 0 - The information element is compared and transferred + * in case of change. + * bit 1 - The information element is transferred to the host + * with each appearance or disappearance. + * Note that both bits can be set at the same time. + */ +#define BEACON_FILTER_TABLE_MAX_IE_NUM (32) +#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6) +#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2) +#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6) +#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \ + BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \ + (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ + BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) + +struct acx_beacon_filter_ie_table { + struct acx_header header; + + u8 num_ie; + u8 pad[3]; + u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; +} __packed; + +struct acx_conn_monit_params { + struct acx_header header; + + __le32 synch_fail_thold; /* number of beacons missed */ + __le32 bss_lose_timeout; /* number of TU's from synch fail */ +} __packed; + +struct acx_bt_wlan_coex { + struct acx_header header; + + u8 enable; + u8 pad[3]; +} __packed; + +struct acx_bt_wlan_coex_param { + struct acx_header header; + + __le32 params[CONF_SG_PARAMS_MAX]; + u8 param_idx; + u8 padding[3]; +} __packed; + +struct acx_dco_itrim_params { + struct acx_header header; + + u8 enable; + u8 padding[3]; + __le32 timeout; +} __packed; + +struct acx_energy_detection { + struct acx_header header; + + /* The RX Clear Channel Assessment threshold in the PHY */ + __le16 rx_cca_threshold; + u8 tx_energy_detection; + u8 pad; +} __packed; + +struct acx_beacon_broadcast { + struct acx_header header; + + __le16 beacon_rx_timeout; + __le16 broadcast_timeout; + + /* Enables receiving of broadcast packets in PS mode */ + u8 rx_broadcast_in_ps; + + /* Consecutive PS Poll failures before updating the host */ + u8 ps_poll_threshold; + u8 pad[2]; +} __packed; + +struct acx_event_mask { + struct acx_header header; + + __le32 event_mask; + __le32 high_event_mask; /* Unused */ +} __packed; + +#define CFG_RX_FCS BIT(2) +#define CFG_RX_ALL_GOOD BIT(3) +#define CFG_UNI_FILTER_EN BIT(4) +#define CFG_BSSID_FILTER_EN BIT(5) +#define CFG_MC_FILTER_EN BIT(6) +#define CFG_MC_ADDR0_EN BIT(7) +#define CFG_MC_ADDR1_EN BIT(8) +#define CFG_BC_REJECT_EN BIT(9) +#define CFG_SSID_FILTER_EN BIT(10) +#define CFG_RX_INT_FCS_ERROR BIT(11) +#define CFG_RX_INT_ENCRYPTED BIT(12) +#define CFG_RX_WR_RX_STATUS BIT(13) +#define CFG_RX_FILTER_NULTI BIT(14) +#define CFG_RX_RESERVE BIT(15) +#define CFG_RX_TIMESTAMP_TSF BIT(16) + +#define CFG_RX_RSV_EN BIT(0) +#define CFG_RX_RCTS_ACK BIT(1) +#define CFG_RX_PRSP_EN BIT(2) +#define CFG_RX_PREQ_EN BIT(3) +#define CFG_RX_MGMT_EN BIT(4) +#define CFG_RX_FCS_ERROR BIT(5) +#define CFG_RX_DATA_EN BIT(6) +#define CFG_RX_CTL_EN BIT(7) +#define CFG_RX_CF_EN BIT(8) +#define CFG_RX_BCN_EN BIT(9) +#define CFG_RX_AUTH_EN BIT(10) +#define CFG_RX_ASSOC_EN BIT(11) + +#define SCAN_PASSIVE BIT(0) +#define SCAN_5GHZ_BAND BIT(1) +#define SCAN_TRIGGERED BIT(2) +#define SCAN_PRIORITY_HIGH BIT(3) + +/* When set, disable HW encryption */ +#define DF_ENCRYPTION_DISABLE 0x01 +#define DF_SNIFF_MODE_ENABLE 0x80 + +struct acx_feature_config { + struct acx_header header; + + __le32 options; + __le32 data_flow_options; +} __packed; + +struct acx_current_tx_power { + struct acx_header header; + + u8 current_tx_power; + u8 padding[3]; +} __packed; + +struct acx_wake_up_condition { + struct acx_header header; + + u8 wake_up_event; /* Only one bit can be set */ + u8 listen_interval; + u8 pad[2]; +} __packed; + +struct acx_aid { + struct acx_header header; + + /* + * To be set when associated with an AP. + */ + __le16 aid; + u8 pad[2]; +} __packed; + +enum acx_preamble_type { + ACX_PREAMBLE_LONG = 0, + ACX_PREAMBLE_SHORT = 1 +}; + +struct acx_preamble { + struct acx_header header; + + /* + * When set, the WiLink transmits the frames with a short preamble and + * when cleared, the WiLink transmits the frames with a long preamble. + */ + u8 preamble; + u8 padding[3]; +} __packed; + +enum acx_ctsprotect_type { + CTSPROTECT_DISABLE = 0, + CTSPROTECT_ENABLE = 1 +}; + +struct acx_ctsprotect { + struct acx_header header; + u8 ctsprotect; + u8 padding[3]; +} __packed; + +struct acx_tx_statistics { + __le32 internal_desc_overflow; +} __packed; + +struct acx_rx_statistics { + __le32 out_of_mem; + __le32 hdr_overflow; + __le32 hw_stuck; + __le32 dropped; + __le32 fcs_err; + __le32 xfr_hint_trig; + __le32 path_reset; + __le32 reset_counter; +} __packed; + +struct acx_dma_statistics { + __le32 rx_requested; + __le32 rx_errors; + __le32 tx_requested; + __le32 tx_errors; +} __packed; + +struct acx_isr_statistics { + /* host command complete */ + __le32 cmd_cmplt; + + /* fiqisr() */ + __le32 fiqs; + + /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ + __le32 rx_headers; + + /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ + __le32 rx_completes; + + /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ + __le32 rx_mem_overflow; + + /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ + __le32 rx_rdys; + + /* irqisr() */ + __le32 irqs; + + /* (INT_STS_ND & INT_TRIG_TX_PROC) */ + __le32 tx_procs; + + /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ + __le32 decrypt_done; + + /* (INT_STS_ND & INT_TRIG_DMA0) */ + __le32 dma0_done; + + /* (INT_STS_ND & INT_TRIG_DMA1) */ + __le32 dma1_done; + + /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ + __le32 tx_exch_complete; + + /* (INT_STS_ND & INT_TRIG_COMMAND) */ + __le32 commands; + + /* (INT_STS_ND & INT_TRIG_RX_PROC) */ + __le32 rx_procs; + + /* (INT_STS_ND & INT_TRIG_PM_802) */ + __le32 hw_pm_mode_changes; + + /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ + __le32 host_acknowledges; + + /* (INT_STS_ND & INT_TRIG_PM_PCI) */ + __le32 pci_pm; + + /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ + __le32 wakeups; + + /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ + __le32 low_rssi; +} __packed; + +struct acx_wep_statistics { + /* WEP address keys configured */ + __le32 addr_key_count; + + /* default keys configured */ + __le32 default_key_count; + + __le32 reserved; + + /* number of times that WEP key not found on lookup */ + __le32 key_not_found; + + /* number of times that WEP key decryption failed */ + __le32 decrypt_fail; + + /* WEP packets decrypted */ + __le32 packets; + + /* WEP decrypt interrupts */ + __le32 interrupt; +} __packed; + +#define ACX_MISSED_BEACONS_SPREAD 10 + +struct acx_pwr_statistics { + /* the amount of enters into power save mode (both PD & ELP) */ + __le32 ps_enter; + + /* the amount of enters into ELP mode */ + __le32 elp_enter; + + /* the amount of missing beacon interrupts to the host */ + __le32 missing_bcns; + + /* the amount of wake on host-access times */ + __le32 wake_on_host; + + /* the amount of wake on timer-expire */ + __le32 wake_on_timer_exp; + + /* the number of packets that were transmitted with PS bit set */ + __le32 tx_with_ps; + + /* the number of packets that were transmitted with PS bit clear */ + __le32 tx_without_ps; + + /* the number of received beacons */ + __le32 rcvd_beacons; + + /* the number of entering into PowerOn (power save off) */ + __le32 power_save_off; + + /* the number of entries into power save mode */ + __le16 enable_ps; + + /* + * the number of exits from power save, not including failed PS + * transitions + */ + __le16 disable_ps; + + /* + * the number of times the TSF counter was adjusted because + * of drift + */ + __le32 fix_tsf_ps; + + /* Gives statistics about the spread continuous missed beacons. + * The 16 LSB are dedicated for the PS mode. + * The 16 MSB are dedicated for the PS mode. + * cont_miss_bcns_spread[0] - single missed beacon. + * cont_miss_bcns_spread[1] - two continuous missed beacons. + * cont_miss_bcns_spread[2] - three continuous missed beacons. + * ... + * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. + */ + __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; + + /* the number of beacons in awake mode */ + __le32 rcvd_awake_beacons; +} __packed; + +struct acx_mic_statistics { + __le32 rx_pkts; + __le32 calc_failure; +} __packed; + +struct acx_aes_statistics { + __le32 encrypt_fail; + __le32 decrypt_fail; + __le32 encrypt_packets; + __le32 decrypt_packets; + __le32 encrypt_interrupt; + __le32 decrypt_interrupt; +} __packed; + +struct acx_event_statistics { + __le32 heart_beat; + __le32 calibration; + __le32 rx_mismatch; + __le32 rx_mem_empty; + __le32 rx_pool; + __le32 oom_late; + __le32 phy_transmit_error; + __le32 tx_stuck; +} __packed; + +struct acx_ps_statistics { + __le32 pspoll_timeouts; + __le32 upsd_timeouts; + __le32 upsd_max_sptime; + __le32 upsd_max_apturn; + __le32 pspoll_max_apturn; + __le32 pspoll_utilization; + __le32 upsd_utilization; +} __packed; + +struct acx_rxpipe_statistics { + __le32 rx_prep_beacon_drop; + __le32 descr_host_int_trig_rx_data; + __le32 beacon_buffer_thres_host_int_trig_rx_data; + __le32 missed_beacon_host_int_trig_rx_data; + __le32 tx_xfr_host_int_trig_rx_data; +} __packed; + +struct acx_statistics { + struct acx_header header; + + struct acx_tx_statistics tx; + struct acx_rx_statistics rx; + struct acx_dma_statistics dma; + struct acx_isr_statistics isr; + struct acx_wep_statistics wep; + struct acx_pwr_statistics pwr; + struct acx_aes_statistics aes; + struct acx_mic_statistics mic; + struct acx_event_statistics event; + struct acx_ps_statistics ps; + struct acx_rxpipe_statistics rxpipe; +} __packed; + +struct acx_rate_class { + __le32 enabled_rates; + u8 short_retry_limit; + u8 long_retry_limit; + u8 aflags; + u8 reserved; +}; + +#define ACX_TX_BASIC_RATE 0 +#define ACX_TX_AP_FULL_RATE 1 +#define ACX_TX_RATE_POLICY_CNT 2 +struct acx_rate_policy { + struct acx_header header; + + __le32 rate_class_cnt; + struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES]; +} __packed; + +struct acx_ac_cfg { + struct acx_header header; + u8 ac; + u8 cw_min; + __le16 cw_max; + u8 aifsn; + u8 reserved; + __le16 tx_op_limit; +} __packed; + +struct acx_tid_config { + struct acx_header header; + u8 queue_id; + u8 channel_type; + u8 tsid; + u8 ps_scheme; + u8 ack_policy; + u8 padding[3]; + __le32 apsd_conf[2]; +} __packed; + +struct acx_frag_threshold { + struct acx_header header; + __le16 frag_threshold; + u8 padding[2]; +} __packed; + +struct acx_tx_config_options { + struct acx_header header; + __le16 tx_compl_timeout; /* msec */ + __le16 tx_compl_threshold; /* number of packets */ +} __packed; + +#define ACX_RX_MEM_BLOCKS 70 +#define ACX_TX_MIN_MEM_BLOCKS 40 +#define ACX_TX_DESCRIPTORS 32 +#define ACX_NUM_SSID_PROFILES 1 + +struct wl1271_acx_config_memory { + struct acx_header header; + + u8 rx_mem_block_num; + u8 tx_min_mem_block_num; + u8 num_stations; + u8 num_ssid_profiles; + __le32 total_tx_descriptors; +} __packed; + +struct wl1271_acx_mem_map { + struct acx_header header; + + __le32 code_start; + __le32 code_end; + + __le32 wep_defkey_start; + __le32 wep_defkey_end; + + __le32 sta_table_start; + __le32 sta_table_end; + + __le32 packet_template_start; + __le32 packet_template_end; + + /* Address of the TX result interface (control block) */ + __le32 tx_result; + __le32 tx_result_queue_start; + + __le32 queue_memory_start; + __le32 queue_memory_end; + + __le32 packet_memory_pool_start; + __le32 packet_memory_pool_end; + + __le32 debug_buffer1_start; + __le32 debug_buffer1_end; + + __le32 debug_buffer2_start; + __le32 debug_buffer2_end; + + /* Number of blocks FW allocated for TX packets */ + __le32 num_tx_mem_blocks; + + /* Number of blocks FW allocated for RX packets */ + __le32 num_rx_mem_blocks; + + /* the following 4 fields are valid in SLAVE mode only */ + u8 *tx_cbuf; + u8 *rx_cbuf; + __le32 rx_ctrl; + __le32 tx_ctrl; +} __packed; + +struct wl1271_acx_rx_config_opt { + struct acx_header header; + + __le16 mblk_threshold; + __le16 threshold; + __le16 timeout; + u8 queue_type; + u8 reserved; +} __packed; + + +struct wl1271_acx_bet_enable { + struct acx_header header; + + u8 enable; + u8 max_consecutive; + u8 padding[2]; +} __packed; + +#define ACX_IPV4_VERSION 4 +#define ACX_IPV6_VERSION 6 +#define ACX_IPV4_ADDR_SIZE 4 +struct wl1271_acx_arp_filter { + struct acx_header header; + u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */ + u8 enable; /* 1 to enable ARP filtering, 0 to disable */ + u8 padding[2]; + u8 address[16]; /* The configured device IP address - all ARP + requests directed to this IP address will pass + through. For IPv4, the first four bytes are + used. */ +} __packed; + +struct wl1271_acx_pm_config { + struct acx_header header; + + __le32 host_clk_settling_time; + u8 host_fast_wakeup_support; + u8 padding[3]; +} __packed; + +struct wl1271_acx_keep_alive_mode { + struct acx_header header; + + u8 enabled; + u8 padding[3]; +} __packed; + +enum { + ACX_KEEP_ALIVE_NO_TX = 0, + ACX_KEEP_ALIVE_PERIOD_ONLY +}; + +enum { + ACX_KEEP_ALIVE_TPL_INVALID = 0, + ACX_KEEP_ALIVE_TPL_VALID +}; + +struct wl1271_acx_keep_alive_config { + struct acx_header header; + + __le32 period; + u8 index; + u8 tpl_validation; + u8 trigger; + u8 padding; +} __packed; + +enum { + WL1271_ACX_TRIG_TYPE_LEVEL = 0, + WL1271_ACX_TRIG_TYPE_EDGE, +}; + +enum { + WL1271_ACX_TRIG_DIR_LOW = 0, + WL1271_ACX_TRIG_DIR_HIGH, + WL1271_ACX_TRIG_DIR_BIDIR, +}; + +enum { + WL1271_ACX_TRIG_ENABLE = 1, + WL1271_ACX_TRIG_DISABLE, +}; + +enum { + WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0, + WL1271_ACX_TRIG_METRIC_RSSI_DATA, + WL1271_ACX_TRIG_METRIC_SNR_BEACON, + WL1271_ACX_TRIG_METRIC_SNR_DATA, +}; + +enum { + WL1271_ACX_TRIG_IDX_RSSI = 0, + WL1271_ACX_TRIG_COUNT = 8, +}; + +struct wl1271_acx_rssi_snr_trigger { + struct acx_header header; + + __le16 threshold; + __le16 pacing; /* 0 - 60000 ms */ + u8 metric; + u8 type; + u8 dir; + u8 hysteresis; + u8 index; + u8 enable; + u8 padding[2]; +}; + +struct wl1271_acx_rssi_snr_avg_weights { + struct acx_header header; + + u8 rssi_beacon; + u8 rssi_data; + u8 snr_beacon; + u8 snr_data; +}; + +/* + * ACX_PEER_HT_CAP + * Configure HT capabilities - declare the capabilities of the peer + * we are connected to. + */ +struct wl1271_acx_ht_capabilities { + struct acx_header header; + + /* + * bit 0 - Allow HT Operation + * bit 1 - Allow Greenfield format in TX + * bit 2 - Allow Short GI in TX + * bit 3 - Allow L-SIG TXOP Protection in TX + * bit 4 - Allow HT Control fields in TX. + * Note, driver will still leave space for HT control in packets + * regardless of the value of this field. FW will be responsible + * to drop the HT field from any frame when this Bit set to 0. + * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD. + * Exact policy setting for this feature is TBD. + * Note, this bit can only be set to 1 if bit 3 is set to 1. + */ + __le32 ht_capabilites; + + /* + * Indicates to which peer these capabilities apply. + * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance + * for all peers. + * Only valid for IBSS/DLS operation. + */ + u8 mac_address[ETH_ALEN]; + + /* + * This the maximum A-MPDU length supported by the AP. The FW may not + * exceed this length when sending A-MPDUs + */ + u8 ampdu_max_length; + + /* This is the minimal spacing required when sending A-MPDUs to the AP*/ + u8 ampdu_min_spacing; +} __packed; + +/* HT Capabilites Fw Bit Mask Mapping */ +#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0) +#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1) +#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2) +#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3) +#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4) +#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5) + + +/* + * ACX_HT_BSS_OPERATION + * Configure HT capabilities - AP rules for behavior in the BSS. + */ +struct wl1271_acx_ht_information { + struct acx_header header; + + /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */ + u8 rifs_mode; + + /* Values: 0 - 3 like in spec */ + u8 ht_protection; + + /* Values: 0 - GF protection not required, 1 - GF protection required */ + u8 gf_protection; + + /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/ + u8 ht_tx_burst_limit; + + /* + * Values: 0 - Dual CTS protection not required, + * 1 - Dual CTS Protection required + * Note: When this value is set to 1 FW will protect all TXOP with RTS + * frame and will not use CTS-to-self regardless of the value of the + * ACX_CTS_PROTECTION information element + */ + u8 dual_cts_protection; + + u8 padding[3]; +} __packed; + +struct wl1271_acx_fw_tsf_information { + struct acx_header header; + + __le32 current_tsf_high; + __le32 current_tsf_low; + __le32 last_bttt_high; + __le32 last_tbtt_low; + u8 last_dtim_count; + u8 padding[3]; +} __packed; + +enum { + ACX_WAKE_UP_CONDITIONS = 0x0002, + ACX_MEM_CFG = 0x0003, + ACX_SLOT = 0x0004, + ACX_AC_CFG = 0x0007, + ACX_MEM_MAP = 0x0008, + ACX_AID = 0x000A, + /* ACX_FW_REV is missing in the ref driver, but seems to work */ + ACX_FW_REV = 0x000D, + ACX_MEDIUM_USAGE = 0x000F, + ACX_RX_CFG = 0x0010, + ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ + ACX_STATISTICS = 0x0013, /* Debug API */ + ACX_PWR_CONSUMPTION_STATISTICS = 0x0014, + ACX_FEATURE_CFG = 0x0015, + ACX_TID_CFG = 0x001A, + ACX_PS_RX_STREAMING = 0x001B, + ACX_BEACON_FILTER_OPT = 0x001F, + ACX_NOISE_HIST = 0x0021, + ACX_HDK_VERSION = 0x0022, /* ??? */ + ACX_PD_THRESHOLD = 0x0023, + ACX_TX_CONFIG_OPT = 0x0024, + ACX_CCA_THRESHOLD = 0x0025, + ACX_EVENT_MBOX_MASK = 0x0026, + ACX_CONN_MONIT_PARAMS = 0x002D, + ACX_CONS_TX_FAILURE = 0x002F, + ACX_BCN_DTIM_OPTIONS = 0x0031, + ACX_SG_ENABLE = 0x0032, + ACX_SG_CFG = 0x0033, + ACX_BEACON_FILTER_TABLE = 0x0038, + ACX_ARP_IP_FILTER = 0x0039, + ACX_ROAMING_STATISTICS_TBL = 0x003B, + ACX_RATE_POLICY = 0x003D, + ACX_CTS_PROTECTION = 0x003E, + ACX_SLEEP_AUTH = 0x003F, + ACX_PREAMBLE_TYPE = 0x0040, + ACX_ERROR_CNT = 0x0041, + ACX_IBSS_FILTER = 0x0044, + ACX_SERVICE_PERIOD_TIMEOUT = 0x0045, + ACX_TSF_INFO = 0x0046, + ACX_CONFIG_PS_WMM = 0x0049, + ACX_ENABLE_RX_DATA_FILTER = 0x004A, + ACX_SET_RX_DATA_FILTER = 0x004B, + ACX_GET_DATA_FILTER_STATISTICS = 0x004C, + ACX_RX_CONFIG_OPT = 0x004E, + ACX_FRAG_CFG = 0x004F, + ACX_BET_ENABLE = 0x0050, + ACX_RSSI_SNR_TRIGGER = 0x0051, + ACX_RSSI_SNR_WEIGHTS = 0x0052, + ACX_KEEP_ALIVE_MODE = 0x0053, + ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, + ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, + ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, + ACX_PEER_HT_CAP = 0x0057, + ACX_HT_BSS_OPERATION = 0x0058, + ACX_COEX_ACTIVITY = 0x0059, + ACX_SET_DCO_ITRIM_PARAMS = 0x0061, + DOT11_RX_MSDU_LIFE_TIME = 0x1004, + DOT11_CUR_TX_PWR = 0x100D, + DOT11_RX_DOT11_MODE = 0x1012, + DOT11_RTS_THRESHOLD = 0x1013, + DOT11_GROUP_ADDRESS_TBL = 0x1014, + ACX_PM_CONFIG = 0x1016, + + MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, + + MAX_IE = 0xFFFF +}; + + +int wl1271_acx_wake_up_conditions(struct wl1271 *wl); +int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); +int wl1271_acx_tx_power(struct wl1271 *wl, int power); +int wl1271_acx_feature_cfg(struct wl1271 *wl); +int wl1271_acx_mem_map(struct wl1271 *wl, + struct acx_header *mem_map, size_t len); +int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl); +int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter); +int wl1271_acx_pd_threshold(struct wl1271 *wl); +int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time); +int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, + void *mc_list, u32 mc_list_len); +int wl1271_acx_service_period_timeout(struct wl1271 *wl); +int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold); +int wl1271_acx_dco_itrim_params(struct wl1271 *wl); +int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); +int wl1271_acx_beacon_filter_table(struct wl1271 *wl); +int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable); +int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); +int wl1271_acx_sg_cfg(struct wl1271 *wl); +int wl1271_acx_cca_threshold(struct wl1271 *wl); +int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); +int wl1271_acx_aid(struct wl1271 *wl, u16 aid); +int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); +int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); +int wl1271_acx_cts_protect(struct wl1271 *wl, + enum acx_ctsprotect_type ctsprotect); +int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); +int wl1271_acx_rate_policies(struct wl1271 *wl); +int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, + u8 aifsn, u16 txop); +int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, + u8 tsid, u8 ps_scheme, u8 ack_policy, + u32 apsd_conf0, u32 apsd_conf1); +int wl1271_acx_frag_threshold(struct wl1271 *wl); +int wl1271_acx_tx_config_options(struct wl1271 *wl); +int wl1271_acx_mem_cfg(struct wl1271 *wl); +int wl1271_acx_init_mem_config(struct wl1271 *wl); +int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); +int wl1271_acx_smart_reflex(struct wl1271 *wl); +int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); +int wl1271_acx_pm_config(struct wl1271 *wl); +int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); +int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); +int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, + s16 thold, u8 hyst); +int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); +int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, + struct ieee80211_sta_ht_cap *ht_cap, + bool allow_ht_operation); +int wl1271_acx_set_ht_information(struct wl1271 *wl, + u16 ht_operation_mode); +int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); + +#endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c new file mode 100644 index 000000000000..1eafb8175832 --- /dev/null +++ b/drivers/net/wireless/wl12xx/boot.c @@ -0,0 +1,591 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "acx.h" +#include "reg.h" +#include "boot.h" +#include "io.h" +#include "event.h" + +static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { + [PART_DOWN] = { + .mem = { + .start = 0x00000000, + .size = 0x000177c0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x00008800 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + }, + }, + + [PART_WORK] = { + .mem = { + .start = 0x00040000, + .size = 0x00014fc0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x0000a000 + }, + .mem2 = { + .start = 0x003004f8, + .size = 0x00000004 + }, + .mem3 = { + .start = 0x00040404, + .size = 0x00000000 + }, + }, + + [PART_DRPW] = { + .mem = { + .start = 0x00040000, + .size = 0x00014fc0 + }, + .reg = { + .start = DRPW_BASE, + .size = 0x00006000 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + } + } +}; + +static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) +{ + u32 cpu_ctrl; + + /* 10.5.0 run the firmware (I) */ + cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL); + + /* 10.5.1 run the firmware (II) */ + cpu_ctrl |= flag; + wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); +} + +static void wl1271_boot_fw_version(struct wl1271 *wl) +{ + struct wl1271_static_data static_data; + + wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data), + false); + + strncpy(wl->chip.fw_ver, static_data.fw_version, + sizeof(wl->chip.fw_ver)); + + /* make sure the string is NULL-terminated */ + wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0'; +} + +static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, + size_t fw_data_len, u32 dest) +{ + struct wl1271_partition_set partition; + int addr, chunk_num, partition_limit; + u8 *p, *chunk; + + /* whal_FwCtrl_LoadFwImageSm() */ + + wl1271_debug(DEBUG_BOOT, "starting firmware upload"); + + wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d", + fw_data_len, CHUNK_SIZE); + + if ((fw_data_len % 4) != 0) { + wl1271_error("firmware length not multiple of four"); + return -EIO; + } + + chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL); + if (!chunk) { + wl1271_error("allocation for firmware upload chunk failed"); + return -ENOMEM; + } + + memcpy(&partition, &part_table[PART_DOWN], sizeof(partition)); + partition.mem.start = dest; + wl1271_set_partition(wl, &partition); + + /* 10.1 set partition limit and chunk num */ + chunk_num = 0; + partition_limit = part_table[PART_DOWN].mem.size; + + while (chunk_num < fw_data_len / CHUNK_SIZE) { + /* 10.2 update partition, if needed */ + addr = dest + (chunk_num + 2) * CHUNK_SIZE; + if (addr > partition_limit) { + addr = dest + chunk_num * CHUNK_SIZE; + partition_limit = chunk_num * CHUNK_SIZE + + part_table[PART_DOWN].mem.size; + partition.mem.start = addr; + wl1271_set_partition(wl, &partition); + } + + /* 10.3 upload the chunk */ + addr = dest + chunk_num * CHUNK_SIZE; + p = buf + chunk_num * CHUNK_SIZE; + memcpy(chunk, p, CHUNK_SIZE); + wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", + p, addr); + wl1271_write(wl, addr, chunk, CHUNK_SIZE, false); + + chunk_num++; + } + + /* 10.4 upload the last chunk */ + addr = dest + chunk_num * CHUNK_SIZE; + p = buf + chunk_num * CHUNK_SIZE; + memcpy(chunk, p, fw_data_len % CHUNK_SIZE); + wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", + fw_data_len % CHUNK_SIZE, p, addr); + wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); + + kfree(chunk); + return 0; +} + +static int wl1271_boot_upload_firmware(struct wl1271 *wl) +{ + u32 chunks, addr, len; + int ret = 0; + u8 *fw; + + fw = wl->fw; + chunks = be32_to_cpup((__be32 *) fw); + fw += sizeof(u32); + + wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks); + + while (chunks--) { + addr = be32_to_cpup((__be32 *) fw); + fw += sizeof(u32); + len = be32_to_cpup((__be32 *) fw); + fw += sizeof(u32); + + if (len > 300000) { + wl1271_info("firmware chunk too long: %u", len); + return -EINVAL; + } + wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u", + chunks, addr, len); + ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr); + if (ret != 0) + break; + fw += len; + } + + return ret; +} + +static int wl1271_boot_upload_nvs(struct wl1271 *wl) +{ + size_t nvs_len, burst_len; + int i; + u32 dest_addr, val; + u8 *nvs_ptr, *nvs_aligned; + + if (wl->nvs == NULL) + return -ENODEV; + + /* + * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band + * configurations) can be removed when those NVS files stop floating + * around. + */ + if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || + wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { + if (wl->nvs->general_params.dual_mode_select) + wl->enable_11a = true; + } + + if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && + (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || + wl->enable_11a)) { + wl1271_error("nvs size is not as expected: %zu != %zu", + wl->nvs_len, sizeof(struct wl1271_nvs_file)); + kfree(wl->nvs); + wl->nvs = NULL; + wl->nvs_len = 0; + return -EILSEQ; + } + + /* only the first part of the NVS needs to be uploaded */ + nvs_len = sizeof(wl->nvs->nvs); + nvs_ptr = (u8 *)wl->nvs->nvs; + + /* update current MAC address to NVS */ + nvs_ptr[11] = wl->mac_addr[0]; + nvs_ptr[10] = wl->mac_addr[1]; + nvs_ptr[6] = wl->mac_addr[2]; + nvs_ptr[5] = wl->mac_addr[3]; + nvs_ptr[4] = wl->mac_addr[4]; + nvs_ptr[3] = wl->mac_addr[5]; + + /* + * Layout before the actual NVS tables: + * 1 byte : burst length. + * 2 bytes: destination address. + * n bytes: data to burst copy. + * + * This is ended by a 0 length, then the NVS tables. + */ + + /* FIXME: Do we need to check here whether the LSB is 1? */ + while (nvs_ptr[0]) { + burst_len = nvs_ptr[0]; + dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); + + /* + * Due to our new wl1271_translate_reg_addr function, + * we need to add the REGISTER_BASE to the destination + */ + dest_addr += REGISTERS_BASE; + + /* We move our pointer to the data */ + nvs_ptr += 3; + + for (i = 0; i < burst_len; i++) { + val = (nvs_ptr[0] | (nvs_ptr[1] << 8) + | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); + + wl1271_debug(DEBUG_BOOT, + "nvs burst write 0x%x: 0x%x", + dest_addr, val); + wl1271_write32(wl, dest_addr, val); + + nvs_ptr += 4; + dest_addr += 4; + } + } + + /* + * We've reached the first zero length, the first NVS table + * is located at an aligned offset which is at least 7 bytes further. + */ + nvs_ptr = (u8 *)wl->nvs->nvs + + ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); + nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; + + /* Now we must set the partition correctly */ + wl1271_set_partition(wl, &part_table[PART_WORK]); + + /* Copy the NVS tables to a new block to ensure alignment */ + nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); + if (!nvs_aligned) + return -ENOMEM; + + /* And finally we upload the NVS tables */ + wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); + + kfree(nvs_aligned); + return 0; +} + +static void wl1271_boot_enable_interrupts(struct wl1271 *wl) +{ + wl1271_enable_interrupts(wl); + wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); + wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); +} + +static int wl1271_boot_soft_reset(struct wl1271 *wl) +{ + unsigned long timeout; + u32 boot_data; + + /* perform soft reset */ + wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); + + /* SOFT_RESET is self clearing */ + timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); + while (1) { + boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET); + wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); + if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) + break; + + if (time_after(jiffies, timeout)) { + /* 1.2 check pWhalBus->uSelfClearTime if the + * timeout was reached */ + wl1271_error("soft reset timeout"); + return -1; + } + + udelay(SOFT_RESET_STALL_TIME); + } + + /* disable Rx/Tx */ + wl1271_write32(wl, ENABLE, 0x0); + + /* disable auto calibration on start*/ + wl1271_write32(wl, SPARE_A2, 0xffff); + + return 0; +} + +static int wl1271_boot_run_firmware(struct wl1271 *wl) +{ + int loop, ret; + u32 chip_id, intr; + + wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); + + chip_id = wl1271_read32(wl, CHIP_ID_B); + + wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); + + if (chip_id != wl->chip.id) { + wl1271_error("chip id doesn't match after firmware boot"); + return -EIO; + } + + /* wait for init to complete */ + loop = 0; + while (loop++ < INIT_LOOP) { + udelay(INIT_LOOP_DELAY); + intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + + if (intr == 0xffffffff) { + wl1271_error("error reading hardware complete " + "init indication"); + return -EIO; + } + /* check that ACX_INTR_INIT_COMPLETE is enabled */ + else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { + wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, + WL1271_ACX_INTR_INIT_COMPLETE); + break; + } + } + + if (loop > INIT_LOOP) { + wl1271_error("timeout waiting for the hardware to " + "complete initialization"); + return -EIO; + } + + /* get hardware config command mail box */ + wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR); + + /* get hardware config event mail box */ + wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); + + /* set the working partition to its "running" mode offset */ + wl1271_set_partition(wl, &part_table[PART_WORK]); + + wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", + wl->cmd_box_addr, wl->event_box_addr); + + wl1271_boot_fw_version(wl); + + /* + * in case of full asynchronous mode the firmware event must be + * ready to receive event from the command mailbox + */ + + /* unmask required mbox events */ + wl->event_mask = BSS_LOSE_EVENT_ID | + SCAN_COMPLETE_EVENT_ID | + PS_REPORT_EVENT_ID | + JOIN_EVENT_COMPLETE_ID | + DISCONNECT_EVENT_COMPLETE_ID | + RSSI_SNR_TRIGGER_0_EVENT_ID | + PSPOLL_DELIVERY_FAILURE_EVENT_ID | + SOFT_GEMINI_SENSE_EVENT_ID; + + ret = wl1271_event_unmask(wl); + if (ret < 0) { + wl1271_error("EVENT mask setting failed"); + return ret; + } + + wl1271_event_mbox_config(wl); + + /* firmware startup completed */ + return 0; +} + +static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) +{ + u32 polarity; + + polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY); + + /* We use HIGH polarity, so unset the LOW bit */ + polarity &= ~POLARITY_LOW; + wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity); + + return 0; +} + +static void wl1271_boot_hw_version(struct wl1271 *wl) +{ + u32 fuse; + + fuse = wl1271_top_reg_read(wl, REG_FUSE_DATA_2_1); + fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; + + wl->hw_pg_ver = (s8)fuse; +} + +int wl1271_boot(struct wl1271 *wl) +{ + int ret = 0; + u32 tmp, clk, pause; + + wl1271_boot_hw_version(wl); + + if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4) + /* ref clk: 19.2/38.4/38.4-XTAL */ + clk = 0x3; + else if (wl->ref_clock == 1 || wl->ref_clock == 3) + /* ref clk: 26/52 */ + clk = 0x5; + else + return -EINVAL; + + if (wl->ref_clock != 0) { + u16 val; + /* Set clock type (open drain) */ + val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); + val &= FREF_CLK_TYPE_BITS; + wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); + + /* Set clock pull mode (no pull) */ + val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL); + val |= NO_PULL; + wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val); + } else { + u16 val; + /* Set clock polarity */ + val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY); + val &= FREF_CLK_POLARITY_BITS; + val |= CLK_REQ_OUTN_SEL; + wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); + } + + wl1271_write32(wl, PLL_PARAMETERS, clk); + + pause = wl1271_read32(wl, PLL_PARAMETERS); + + wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); + + pause &= ~(WU_COUNTER_PAUSE_VAL); + pause |= WU_COUNTER_PAUSE_VAL; + wl1271_write32(wl, WU_COUNTER_PAUSE, pause); + + /* Continue the ELP wake up sequence */ + wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + udelay(500); + + wl1271_set_partition(wl, &part_table[PART_DRPW]); + + /* Read-modify-write DRPW_SCRATCH_START register (see next state) + to be used by DRPw FW. The RTRIM value will be added by the FW + before taking DRPw out of reset */ + + wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); + clk = wl1271_read32(wl, DRPW_SCRATCH_START); + + wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); + + clk |= (wl->ref_clock << 1) << 4; + wl1271_write32(wl, DRPW_SCRATCH_START, clk); + + wl1271_set_partition(wl, &part_table[PART_WORK]); + + /* Disable interrupts */ + wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + + ret = wl1271_boot_soft_reset(wl); + if (ret < 0) + goto out; + + /* 2. start processing NVS file */ + ret = wl1271_boot_upload_nvs(wl); + if (ret < 0) + goto out; + + /* write firmware's last address (ie. it's length) to + * ACX_EEPROMLESS_IND_REG */ + wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); + + wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG); + + tmp = wl1271_read32(wl, CHIP_ID_B); + + wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); + + /* 6. read the EEPROM parameters */ + tmp = wl1271_read32(wl, SCR_PAD2); + + ret = wl1271_boot_write_irq_polarity(wl); + if (ret < 0) + goto out; + + wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, + WL1271_ACX_ALL_EVENTS_VECTOR); + + /* WL1271: The reference driver skips steps 7 to 10 (jumps directly + * to upload_fw) */ + + ret = wl1271_boot_upload_firmware(wl); + if (ret < 0) + goto out; + + /* 10.5 start firmware */ + ret = wl1271_boot_run_firmware(wl); + if (ret < 0) + goto out; + + /* Enable firmware interrupts now */ + wl1271_boot_enable_interrupts(wl); + + /* set the wl1271 default filters */ + wl->rx_config = WL1271_DEFAULT_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + + wl1271_event_mbox_config(wl); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h new file mode 100644 index 000000000000..c7d771959f3a --- /dev/null +++ b/drivers/net/wireless/wl12xx/boot.h @@ -0,0 +1,71 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __BOOT_H__ +#define __BOOT_H__ + +#include "wl12xx.h" + +int wl1271_boot(struct wl1271 *wl); + +#define WL1271_NO_SUBBANDS 8 +#define WL1271_NO_POWER_LEVELS 4 +#define WL1271_FW_VERSION_MAX_LEN 20 + +struct wl1271_static_data { + u8 mac_address[ETH_ALEN]; + u8 padding[2]; + u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; + u32 hw_version; + u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; +}; + +/* number of times we try to read the INIT interrupt */ +#define INIT_LOOP 20000 + +/* delay between retries */ +#define INIT_LOOP_DELAY 50 + +#define WU_COUNTER_PAUSE_VAL 0x3FF +#define WELP_ARM_COMMAND_VAL 0x4 + +#define OCP_REG_POLARITY 0x0064 +#define OCP_REG_CLK_TYPE 0x0448 +#define OCP_REG_CLK_POLARITY 0x0cb2 +#define OCP_REG_CLK_PULL 0x0cb4 + +#define REG_FUSE_DATA_2_1 0x050a +#define PG_VER_MASK 0x3c +#define PG_VER_OFFSET 2 + +#define CMD_MBOX_ADDRESS 0x407B4 + +#define POLARITY_LOW BIT(1) +#define NO_PULL (BIT(14) | BIT(15)) + +#define FREF_CLK_TYPE_BITS 0xfffffe7f +#define CLK_REQ_PRCM 0x100 +#define FREF_CLK_POLARITY_BITS 0xfffff8ff +#define CLK_REQ_OUTN_SEL 0x700 + +#endif diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c new file mode 100644 index 000000000000..f3d0541aaad6 --- /dev/null +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -0,0 +1,783 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "reg.h" +#include "io.h" +#include "acx.h" +#include "wl12xx_80211.h" +#include "cmd.h" +#include "event.h" + +#define WL1271_CMD_FAST_POLL_COUNT 50 + +/* + * send command to firmware + * + * @wl: wl struct + * @id: command id + * @buf: buffer containing the command, must work with dma + * @len: length of the buffer + */ +int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, + size_t res_len) +{ + struct wl1271_cmd_header *cmd; + unsigned long timeout; + u32 intr; + int ret = 0; + u16 status; + u16 poll_count = 0; + + cmd = buf; + cmd->id = cpu_to_le16(id); + cmd->status = 0; + + WARN_ON(len % 4 != 0); + + wl1271_write(wl, wl->cmd_box_addr, buf, len, false); + + wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); + + timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); + + intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { + if (time_after(jiffies, timeout)) { + wl1271_error("command complete timeout"); + ret = -ETIMEDOUT; + goto out; + } + + poll_count++; + if (poll_count < WL1271_CMD_FAST_POLL_COUNT) + udelay(10); + else + msleep(1); + + intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + } + + /* read back the status code of the command */ + if (res_len == 0) + res_len = sizeof(struct wl1271_cmd_header); + wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false); + + status = le16_to_cpu(cmd->status); + if (status != CMD_STATUS_SUCCESS) { + wl1271_error("command execute failure %d", status); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + ret = -EIO; + } + + wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, + WL1271_ACX_INTR_CMD_COMPLETE); + +out: + return ret; +} + +int wl1271_cmd_general_parms(struct wl1271 *wl) +{ + struct wl1271_general_parms_cmd *gen_parms; + struct wl1271_ini_general_params *gp = &wl->nvs->general_params; + bool answer = false; + int ret; + + if (!wl->nvs) + return -ENODEV; + + gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); + if (!gen_parms) + return -ENOMEM; + + gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; + + memcpy(&gen_parms->general_params, gp, sizeof(*gp)); + + if (gp->tx_bip_fem_auto_detect) + answer = true; + + ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); + if (ret < 0) { + wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); + goto out; + } + + gp->tx_bip_fem_manufacturer = + gen_parms->general_params.tx_bip_fem_manufacturer; + + wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", + answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); + +out: + kfree(gen_parms); + return ret; +} + +int wl1271_cmd_radio_parms(struct wl1271 *wl) +{ + struct wl1271_radio_parms_cmd *radio_parms; + struct wl1271_ini_general_params *gp = &wl->nvs->general_params; + int ret; + + if (!wl->nvs) + return -ENODEV; + + radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); + if (!radio_parms) + return -ENOMEM; + + radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; + + /* 2.4GHz parameters */ + memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2, + sizeof(struct wl1271_ini_band_params_2)); + memcpy(&radio_parms->dyn_params_2, + &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, + sizeof(struct wl1271_ini_fem_params_2)); + + /* 5GHz parameters */ + memcpy(&radio_parms->static_params_5, + &wl->nvs->stat_radio_params_5, + sizeof(struct wl1271_ini_band_params_5)); + memcpy(&radio_parms->dyn_params_5, + &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, + sizeof(struct wl1271_ini_fem_params_5)); + + wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", + radio_parms, sizeof(*radio_parms)); + + ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); + if (ret < 0) + wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); + + kfree(radio_parms); + return ret; +} + +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) +{ + struct wl1271_ext_radio_parms_cmd *ext_radio_parms; + struct conf_rf_settings *rf = &wl->conf.rf; + int ret; + + if (!wl->nvs) + return -ENODEV; + + ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); + if (!ext_radio_parms) + return -ENOMEM; + + ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; + + memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, + rf->tx_per_channel_power_compensation_2, + CONF_TX_PWR_COMPENSATION_LEN_2); + memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, + rf->tx_per_channel_power_compensation_5, + CONF_TX_PWR_COMPENSATION_LEN_5); + + wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", + ext_radio_parms, sizeof(*ext_radio_parms)); + + ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); + if (ret < 0) + wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); + + kfree(ext_radio_parms); + return ret; +} + +/* + * Poll the mailbox event field until any of the bits in the mask is set or a + * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) + */ +static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) +{ + u32 events_vector, event; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); + + do { + if (time_after(jiffies, timeout)) { + ieee80211_queue_work(wl->hw, &wl->recovery_work); + return -ETIMEDOUT; + } + + msleep(1); + + /* read from both event fields */ + wl1271_read(wl, wl->mbox_ptr[0], &events_vector, + sizeof(events_vector), false); + event = events_vector & mask; + wl1271_read(wl, wl->mbox_ptr[1], &events_vector, + sizeof(events_vector), false); + event |= events_vector & mask; + } while (!event); + + return 0; +} + +int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) +{ + struct wl1271_cmd_join *join; + int ret, i; + u8 *bssid; + + join = kzalloc(sizeof(*join), GFP_KERNEL); + if (!join) { + ret = -ENOMEM; + goto out; + } + + wl1271_debug(DEBUG_CMD, "cmd join"); + + /* Reverse order BSSID */ + bssid = (u8 *) &join->bssid_lsb; + for (i = 0; i < ETH_ALEN; i++) + bssid[i] = wl->bssid[ETH_ALEN - i - 1]; + + join->rx_config_options = cpu_to_le32(wl->rx_config); + join->rx_filter_options = cpu_to_le32(wl->rx_filter); + join->bss_type = bss_type; + join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); + + if (wl->band == IEEE80211_BAND_5GHZ) + join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; + + join->beacon_interval = cpu_to_le16(wl->beacon_int); + join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; + + join->channel = wl->channel; + join->ssid_len = wl->ssid_len; + memcpy(join->ssid, wl->ssid, wl->ssid_len); + + join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; + + /* reset TX security counters */ + wl->tx_security_last_seq = 0; + wl->tx_security_seq = 0; + + ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); + if (ret < 0) { + wl1271_error("failed to initiate cmd join"); + goto out_free; + } + + ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); + if (ret < 0) + wl1271_error("cmd join event completion error"); + +out_free: + kfree(join); + +out: + return ret; +} + +/** + * send test command to firmware + * + * @wl: wl struct + * @buf: buffer containing the command, with all headers, must work with dma + * @len: length of the buffer + * @answer: is answer needed + */ +int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) +{ + int ret; + size_t res_len = 0; + + wl1271_debug(DEBUG_CMD, "cmd test"); + + if (answer) + res_len = buf_len; + + ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len); + + if (ret < 0) { + wl1271_warning("TEST command failed"); + return ret; + } + + return ret; +} + +/** + * read acx from firmware + * + * @wl: wl struct + * @id: acx id + * @buf: buffer for the response, including all headers, must work with dma + * @len: lenght of buf + */ +int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) +{ + struct acx_header *acx = buf; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd interrogate"); + + acx->id = cpu_to_le16(id); + + /* payload length, does not include any headers */ + acx->len = cpu_to_le16(len - sizeof(*acx)); + + ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); + if (ret < 0) + wl1271_error("INTERROGATE command failed"); + + return ret; +} + +/** + * write acx value to firmware + * + * @wl: wl struct + * @id: acx id + * @buf: buffer containing acx, including all headers, must work with dma + * @len: length of buf + */ +int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) +{ + struct acx_header *acx = buf; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd configure"); + + acx->id = cpu_to_le16(id); + + /* payload length, does not include any headers */ + acx->len = cpu_to_le16(len - sizeof(*acx)); + + ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0); + if (ret < 0) { + wl1271_warning("CONFIGURE command NOK"); + return ret; + } + + return 0; +} + +int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) +{ + struct cmd_enabledisable_path *cmd; + int ret; + u16 cmd_rx, cmd_tx; + + wl1271_debug(DEBUG_CMD, "cmd data path"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + /* the channel here is only used for calibration, so hardcoded to 1 */ + cmd->channel = 1; + + if (enable) { + cmd_rx = CMD_ENABLE_RX; + cmd_tx = CMD_ENABLE_TX; + } else { + cmd_rx = CMD_DISABLE_RX; + cmd_tx = CMD_DISABLE_TX; + } + + ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("rx %s cmd for channel %d failed", + enable ? "start" : "stop", cmd->channel); + goto out; + } + + wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", + enable ? "start" : "stop", cmd->channel); + + ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("tx %s cmd for channel %d failed", + enable ? "start" : "stop", cmd->channel); + goto out; + } + + wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", + enable ? "start" : "stop", cmd->channel); + +out: + kfree(cmd); + return ret; +} + +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) +{ + struct wl1271_cmd_ps_params *ps_params = NULL; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set ps mode"); + + ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); + if (!ps_params) { + ret = -ENOMEM; + goto out; + } + + ps_params->ps_mode = ps_mode; + ps_params->send_null_data = send; + ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; + ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; + ps_params->null_data_rate = cpu_to_le32(rates); + + ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, + sizeof(*ps_params), 0); + if (ret < 0) { + wl1271_error("cmd set_ps_mode failed"); + goto out; + } + +out: + kfree(ps_params); + return ret; +} + +int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, + void *buf, size_t buf_len, int index, u32 rates) +{ + struct wl1271_cmd_template_set *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id); + + WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); + buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->len = cpu_to_le16(buf_len); + cmd->template_type = template_id; + cmd->enabled_rates = cpu_to_le32(rates); + cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; + cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; + cmd->index = index; + + if (buf) + memcpy(cmd->template_data, buf, buf_len); + + ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_warning("cmd set_template failed: %d", ret); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl1271_cmd_build_null_data(struct wl1271 *wl) +{ + struct sk_buff *skb = NULL; + int size; + void *ptr; + int ret = -ENOMEM; + + + if (wl->bss_type == BSS_TYPE_IBSS) { + size = sizeof(struct wl12xx_null_data_template); + ptr = NULL; + } else { + skb = ieee80211_nullfunc_get(wl->hw, wl->vif); + if (!skb) + goto out; + size = skb->len; + ptr = skb->data; + } + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, + wl->basic_rate); + +out: + dev_kfree_skb(skb); + if (ret) + wl1271_warning("cmd buld null data failed %d", ret); + + return ret; + +} + +int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) +{ + struct sk_buff *skb = NULL; + int ret = -ENOMEM; + + skb = ieee80211_nullfunc_get(wl->hw, wl->vif); + if (!skb) + goto out; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, + skb->data, skb->len, + CMD_TEMPL_KLV_IDX_NULL_DATA, + wl->basic_rate); + +out: + dev_kfree_skb(skb); + if (ret) + wl1271_warning("cmd build klv null data failed %d", ret); + + return ret; + +} + +int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) +{ + struct sk_buff *skb; + int ret = 0; + + skb = ieee80211_pspoll_get(wl->hw, wl->vif); + if (!skb) + goto out; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, + skb->len, 0, wl->basic_rate_set); + +out: + dev_kfree_skb(skb); + return ret; +} + +int wl1271_cmd_build_probe_req(struct wl1271 *wl, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len, u8 band) +{ + struct sk_buff *skb; + int ret; + + skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, + ie, ie_len); + if (!skb) { + ret = -ENOMEM; + goto out; + } + + wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); + + if (band == IEEE80211_BAND_2GHZ) + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, + skb->data, skb->len, 0, + wl->conf.tx.basic_rate); + else + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + skb->data, skb->len, 0, + wl->conf.tx.basic_rate_5); + +out: + dev_kfree_skb(skb); + return ret; +} + +int wl1271_build_qos_null_data(struct wl1271 *wl) +{ + struct ieee80211_qos_hdr template; + + memset(&template, 0, sizeof(template)); + + memcpy(template.addr1, wl->bssid, ETH_ALEN); + memcpy(template.addr2, wl->mac_addr, ETH_ALEN); + memcpy(template.addr3, wl->bssid, ETH_ALEN); + + template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_QOS_NULLFUNC | + IEEE80211_FCTL_TODS); + + /* FIXME: not sure what priority to use here */ + template.qos_ctrl = cpu_to_le16(0); + + return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, + sizeof(template), 0, + wl->basic_rate); +} + +int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) +{ + struct wl1271_cmd_set_keys *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->id = id; + cmd->key_action = cpu_to_le16(KEY_SET_ID); + cmd->key_type = KEY_WEP; + + ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_warning("cmd set_default_wep_key failed: %d", ret); + goto out; + } + +out: + kfree(cmd); + + return ret; +} + +int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, const u8 *addr, + u32 tx_seq_32, u16 tx_seq_16) +{ + struct wl1271_cmd_set_keys *cmd; + int ret = 0; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + if (key_type != KEY_WEP) + memcpy(cmd->addr, addr, ETH_ALEN); + + cmd->key_action = cpu_to_le16(action); + cmd->key_size = key_size; + cmd->key_type = key_type; + + cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); + cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); + + /* we have only one SSID profile */ + cmd->ssid_profile = 0; + + cmd->id = id; + + if (key_type == KEY_TKIP) { + /* + * We get the key in the following form: + * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) + * but the target is expecting: + * TKIP - RX MIC - TX MIC + */ + memcpy(cmd->key, key, 16); + memcpy(cmd->key + 16, key + 24, 8); + memcpy(cmd->key + 24, key + 16, 8); + + } else { + memcpy(cmd->key, key, key_size); + } + + wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd)); + + ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_warning("could not set keys"); + goto out; + } + +out: + kfree(cmd); + + return ret; +} + +int wl1271_cmd_disconnect(struct wl1271 *wl) +{ + struct wl1271_cmd_disconnect *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd disconnect"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->rx_config_options = cpu_to_le32(wl->rx_config); + cmd->rx_filter_options = cpu_to_le32(wl->rx_filter); + /* disconnect reason is not used in immediate disconnections */ + cmd->type = DISCONNECT_IMMEDIATE; + + ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send disconnect command"); + goto out_free; + } + + ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID); + if (ret < 0) + wl1271_error("cmd disconnect event completion error"); + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl1271_cmd_set_sta_state(struct wl1271 *wl) +{ + struct wl1271_cmd_set_sta_state *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set sta state"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->state = WL1271_CMD_STA_STATE_CONNECTED; + + ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send set STA state command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h new file mode 100644 index 000000000000..893dbf72c2d9 --- /dev/null +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -0,0 +1,459 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __CMD_H__ +#define __CMD_H__ + +#include "wl12xx.h" + +struct acx_header; + +int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, + size_t res_len); +int wl1271_cmd_general_parms(struct wl1271 *wl); +int wl1271_cmd_radio_parms(struct wl1271 *wl); +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); +int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); +int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); +int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); +int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); +int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); +int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, + size_t len); +int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, + void *buf, size_t buf_len, int index, u32 rates); +int wl1271_cmd_build_null_data(struct wl1271 *wl); +int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); +int wl1271_cmd_build_probe_req(struct wl1271 *wl, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len, u8 band); +int wl1271_build_qos_null_data(struct wl1271 *wl); +int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); +int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); +int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, const u8 *addr, + u32 tx_seq_32, u16 tx_seq_16); +int wl1271_cmd_disconnect(struct wl1271 *wl); +int wl1271_cmd_set_sta_state(struct wl1271 *wl); + +enum wl1271_commands { + CMD_INTERROGATE = 1, /*use this to read information elements*/ + CMD_CONFIGURE = 2, /*use this to write information elements*/ + CMD_ENABLE_RX = 3, + CMD_ENABLE_TX = 4, + CMD_DISABLE_RX = 5, + CMD_DISABLE_TX = 6, + CMD_SCAN = 8, + CMD_STOP_SCAN = 9, + CMD_START_JOIN = 11, + CMD_SET_KEYS = 12, + CMD_READ_MEMORY = 13, + CMD_WRITE_MEMORY = 14, + CMD_SET_TEMPLATE = 19, + CMD_TEST = 23, + CMD_NOISE_HIST = 28, + CMD_LNA_CONTROL = 32, + CMD_SET_BCN_MODE = 33, + CMD_MEASUREMENT = 34, + CMD_STOP_MEASUREMENT = 35, + CMD_DISCONNECT = 36, + CMD_SET_PS_MODE = 37, + CMD_CHANNEL_SWITCH = 38, + CMD_STOP_CHANNEL_SWICTH = 39, + CMD_AP_DISCOVERY = 40, + CMD_STOP_AP_DISCOVERY = 41, + CMD_SPS_SCAN = 42, + CMD_STOP_SPS_SCAN = 43, + CMD_HEALTH_CHECK = 45, + CMD_DEBUG = 46, + CMD_TRIGGER_SCAN_TO = 47, + CMD_CONNECTION_SCAN_CFG = 48, + CMD_CONNECTION_SCAN_SSID_CFG = 49, + CMD_START_PERIODIC_SCAN = 50, + CMD_STOP_PERIODIC_SCAN = 51, + CMD_SET_STA_STATE = 52, + + NUM_COMMANDS, + MAX_COMMAND_ID = 0xFFFF, +}; + +#define MAX_CMD_PARAMS 572 + +enum { + CMD_TEMPL_KLV_IDX_NULL_DATA = 0, + CMD_TEMPL_KLV_IDX_MAX = 4 +}; + +enum cmd_templ { + CMD_TEMPL_NULL_DATA = 0, + CMD_TEMPL_BEACON, + CMD_TEMPL_CFG_PROBE_REQ_2_4, + CMD_TEMPL_CFG_PROBE_REQ_5, + CMD_TEMPL_PROBE_RESPONSE, + CMD_TEMPL_QOS_NULL_DATA, + CMD_TEMPL_PS_POLL, + CMD_TEMPL_KLV, + CMD_TEMPL_DISCONNECT, + CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */ + CMD_TEMPL_PROBE_REQ_5, /* for firmware internal use only */ + CMD_TEMPL_BAR, /* for firmware internal use only */ + CMD_TEMPL_CTS, /* + * For CTS-to-self (FastCTS) mechanism + * for BT/WLAN coexistence (SoftGemini). */ + CMD_TEMPL_MAX = 0xff +}; + +/* unit ms */ +#define WL1271_COMMAND_TIMEOUT 2000 +#define WL1271_CMD_TEMPL_MAX_SIZE 252 +#define WL1271_EVENT_TIMEOUT 750 + +struct wl1271_cmd_header { + __le16 id; + __le16 status; + /* payload */ + u8 data[0]; +} __packed; + +#define WL1271_CMD_MAX_PARAMS 572 + +struct wl1271_command { + struct wl1271_cmd_header header; + u8 parameters[WL1271_CMD_MAX_PARAMS]; +} __packed; + +enum { + CMD_MAILBOX_IDLE = 0, + CMD_STATUS_SUCCESS = 1, + CMD_STATUS_UNKNOWN_CMD = 2, + CMD_STATUS_UNKNOWN_IE = 3, + CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11, + CMD_STATUS_RX_BUSY = 13, + CMD_STATUS_INVALID_PARAM = 14, + CMD_STATUS_TEMPLATE_TOO_LARGE = 15, + CMD_STATUS_OUT_OF_MEMORY = 16, + CMD_STATUS_STA_TABLE_FULL = 17, + CMD_STATUS_RADIO_ERROR = 18, + CMD_STATUS_WRONG_NESTING = 19, + CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/ + CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/ + MAX_COMMAND_STATUS = 0xff +}; + +#define CMDMBOX_HEADER_LEN 4 +#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 + +enum { + BSS_TYPE_IBSS = 0, + BSS_TYPE_STA_BSS = 2, + BSS_TYPE_AP_BSS = 3, + MAX_BSS_TYPE = 0xFF +}; + +#define WL1271_JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */ +#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1 +#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10 + +struct wl1271_cmd_join { + struct wl1271_cmd_header header; + + __le32 bssid_lsb; + __le16 bssid_msb; + __le16 beacon_interval; /* in TBTTs */ + __le32 rx_config_options; + __le32 rx_filter_options; + + /* + * The target uses this field to determine the rate at + * which to transmit control frame responses (such as + * ACK or CTS frames). + */ + __le32 basic_rate_set; + u8 dtim_interval; + /* + * bits 0-2: This bitwise field specifies the type + * of BSS to start or join (BSS_TYPE_*). + * bit 4: Band - The radio band in which to join + * or start. + * 0 - 2.4GHz band + * 1 - 5GHz band + * bits 3, 5-7: Reserved + */ + u8 bss_type; + u8 channel; + u8 ssid_len; + u8 ssid[IW_ESSID_MAX_SIZE]; + u8 ctrl; /* JOIN_CMD_CTRL_* */ + u8 reserved[3]; +} __packed; + +struct cmd_enabledisable_path { + struct wl1271_cmd_header header; + + u8 channel; + u8 padding[3]; +} __packed; + +#define WL1271_RATE_AUTOMATIC 0 + +struct wl1271_cmd_template_set { + struct wl1271_cmd_header header; + + __le16 len; + u8 template_type; + u8 index; /* relevant only for KLV_TEMPLATE type */ + __le32 enabled_rates; + u8 short_retry_limit; + u8 long_retry_limit; + u8 aflags; + u8 reserved; + u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE]; +} __packed; + +#define TIM_ELE_ID 5 +#define PARTIAL_VBM_MAX 251 + +struct wl1271_tim { + u8 identity; + u8 length; + u8 dtim_count; + u8 dtim_period; + u8 bitmap_ctrl; + u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ +} __packed; + +enum wl1271_cmd_ps_mode { + STATION_ACTIVE_MODE, + STATION_POWER_SAVE_MODE +}; + +struct wl1271_cmd_ps_params { + struct wl1271_cmd_header header; + + u8 ps_mode; /* STATION_* */ + u8 send_null_data; /* Do we have to send NULL data packet ? */ + u8 retries; /* Number of retires for the initial NULL data packet */ + + /* + * TUs during which the target stays awake after switching + * to power save mode. + */ + u8 hang_over_period; + __le32 null_data_rate; +} __packed; + +/* HW encryption keys */ +#define NUM_ACCESS_CATEGORIES_COPY 4 +#define MAX_KEY_SIZE 32 + +enum wl1271_cmd_key_action { + KEY_ADD_OR_REPLACE = 1, + KEY_REMOVE = 2, + KEY_SET_ID = 3, + MAX_KEY_ACTION = 0xffff, +}; + +enum wl1271_cmd_key_type { + KEY_NONE = 0, + KEY_WEP = 1, + KEY_TKIP = 2, + KEY_AES = 3, + KEY_GEM = 4, +}; + +/* FIXME: Add description for key-types */ + +struct wl1271_cmd_set_keys { + struct wl1271_cmd_header header; + + /* Ignored for default WEP key */ + u8 addr[ETH_ALEN]; + + /* key_action_e */ + __le16 key_action; + + __le16 reserved_1; + + /* key size in bytes */ + u8 key_size; + + /* key_type_e */ + u8 key_type; + u8 ssid_profile; + + /* + * TKIP, AES: frame's key id field. + * For WEP default key: key id; + */ + u8 id; + u8 reserved_2[6]; + u8 key[MAX_KEY_SIZE]; + __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; + __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; +} __packed; + +struct wl1271_cmd_test_header { + u8 id; + u8 padding[3]; +} __packed; + +enum wl1271_channel_tune_bands { + WL1271_CHANNEL_TUNE_BAND_2_4, + WL1271_CHANNEL_TUNE_BAND_5, + WL1271_CHANNEL_TUNE_BAND_4_9 +}; + +#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 + +#define TEST_CMD_P2G_CAL 0x02 +#define TEST_CMD_CHANNEL_TUNE 0x0d +#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d +#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 +#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E +#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26 + +struct wl1271_general_parms_cmd { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + struct wl1271_ini_general_params general_params; + + u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 sr_sen_n_p; + u8 sr_sen_n_p_gain; + u8 sr_sen_nrn; + u8 sr_sen_prn; + u8 padding[3]; +} __packed; + +struct wl1271_radio_parms_cmd { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + /* Static radio parameters */ + struct wl1271_ini_band_params_2 static_params_2; + struct wl1271_ini_band_params_5 static_params_5; + + /* Dynamic radio parameters */ + struct wl1271_ini_fem_params_2 dyn_params_2; + u8 padding2; + struct wl1271_ini_fem_params_5 dyn_params_5; + u8 padding3[2]; +} __packed; + +struct wl1271_ext_radio_parms_cmd { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; + u8 padding[3]; +} __packed; + +struct wl1271_cmd_cal_channel_tune { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + u8 band; + u8 channel; + + __le16 radio_status; +} __packed; + +struct wl1271_cmd_cal_update_ref_point { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + __le32 ref_power; + __le32 ref_detector; + u8 sub_band; + u8 padding[3]; +} __packed; + +#define MAX_TLV_LENGTH 400 +#define MAX_NVS_VERSION_LENGTH 12 + +#define WL1271_CAL_P2G_BAND_B_G BIT(0) + +struct wl1271_cmd_cal_p2g { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + __le16 len; + u8 buf[MAX_TLV_LENGTH]; + u8 type; + u8 padding; + + __le16 radio_status; + u8 nvs_version[MAX_NVS_VERSION_LENGTH]; + + u8 sub_band_mask; + u8 padding2; +} __packed; + + +/* + * There are three types of disconnections: + * + * DISCONNECT_IMMEDIATE: the fw doesn't send any frames + * DISCONNECT_DEAUTH: the fw generates a DEAUTH request with the reason + * we have passed + * DISCONNECT_DISASSOC: the fw generates a DESASSOC request with the reason + * we have passed + */ +enum wl1271_disconnect_type { + DISCONNECT_IMMEDIATE, + DISCONNECT_DEAUTH, + DISCONNECT_DISASSOC +}; + +struct wl1271_cmd_disconnect { + struct wl1271_cmd_header header; + + __le32 rx_config_options; + __le32 rx_filter_options; + + __le16 reason; + u8 type; + + u8 padding; +} __packed; + +#define WL1271_CMD_STA_STATE_CONNECTED 1 + +struct wl1271_cmd_set_sta_state { + struct wl1271_cmd_header header; + + u8 state; + u8 padding[3]; +} __packed; + +#endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h new file mode 100644 index 000000000000..a16b3616e430 --- /dev/null +++ b/drivers/net/wireless/wl12xx/conf.h @@ -0,0 +1,1105 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __CONF_H__ +#define __CONF_H__ + +enum { + CONF_HW_BIT_RATE_1MBPS = BIT(0), + CONF_HW_BIT_RATE_2MBPS = BIT(1), + CONF_HW_BIT_RATE_5_5MBPS = BIT(2), + CONF_HW_BIT_RATE_6MBPS = BIT(3), + CONF_HW_BIT_RATE_9MBPS = BIT(4), + CONF_HW_BIT_RATE_11MBPS = BIT(5), + CONF_HW_BIT_RATE_12MBPS = BIT(6), + CONF_HW_BIT_RATE_18MBPS = BIT(7), + CONF_HW_BIT_RATE_22MBPS = BIT(8), + CONF_HW_BIT_RATE_24MBPS = BIT(9), + CONF_HW_BIT_RATE_36MBPS = BIT(10), + CONF_HW_BIT_RATE_48MBPS = BIT(11), + CONF_HW_BIT_RATE_54MBPS = BIT(12), + CONF_HW_BIT_RATE_MCS_0 = BIT(13), + CONF_HW_BIT_RATE_MCS_1 = BIT(14), + CONF_HW_BIT_RATE_MCS_2 = BIT(15), + CONF_HW_BIT_RATE_MCS_3 = BIT(16), + CONF_HW_BIT_RATE_MCS_4 = BIT(17), + CONF_HW_BIT_RATE_MCS_5 = BIT(18), + CONF_HW_BIT_RATE_MCS_6 = BIT(19), + CONF_HW_BIT_RATE_MCS_7 = BIT(20) +}; + +enum { + CONF_HW_RATE_INDEX_1MBPS = 0, + CONF_HW_RATE_INDEX_2MBPS = 1, + CONF_HW_RATE_INDEX_5_5MBPS = 2, + CONF_HW_RATE_INDEX_6MBPS = 3, + CONF_HW_RATE_INDEX_9MBPS = 4, + CONF_HW_RATE_INDEX_11MBPS = 5, + CONF_HW_RATE_INDEX_12MBPS = 6, + CONF_HW_RATE_INDEX_18MBPS = 7, + CONF_HW_RATE_INDEX_22MBPS = 8, + CONF_HW_RATE_INDEX_24MBPS = 9, + CONF_HW_RATE_INDEX_36MBPS = 10, + CONF_HW_RATE_INDEX_48MBPS = 11, + CONF_HW_RATE_INDEX_54MBPS = 12, + CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, +}; + +enum { + CONF_HW_RXTX_RATE_MCS7 = 0, + CONF_HW_RXTX_RATE_MCS6, + CONF_HW_RXTX_RATE_MCS5, + CONF_HW_RXTX_RATE_MCS4, + CONF_HW_RXTX_RATE_MCS3, + CONF_HW_RXTX_RATE_MCS2, + CONF_HW_RXTX_RATE_MCS1, + CONF_HW_RXTX_RATE_MCS0, + CONF_HW_RXTX_RATE_54, + CONF_HW_RXTX_RATE_48, + CONF_HW_RXTX_RATE_36, + CONF_HW_RXTX_RATE_24, + CONF_HW_RXTX_RATE_22, + CONF_HW_RXTX_RATE_18, + CONF_HW_RXTX_RATE_12, + CONF_HW_RXTX_RATE_11, + CONF_HW_RXTX_RATE_9, + CONF_HW_RXTX_RATE_6, + CONF_HW_RXTX_RATE_5_5, + CONF_HW_RXTX_RATE_2, + CONF_HW_RXTX_RATE_1, + CONF_HW_RXTX_RATE_MAX, + CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff +}; + +enum { + CONF_SG_DISABLE = 0, + CONF_SG_PROTECTIVE, + CONF_SG_OPPORTUNISTIC +}; + +enum { + /* + * PER threshold in PPM of the BT voice + * + * Range: 0 - 10000000 + */ + CONF_SG_BT_PER_THRESHOLD = 0, + + /* + * Number of consequent RX_ACTIVE activities to override BT voice + * frames to ensure WLAN connection + * + * Range: 0 - 100 + */ + CONF_SG_HV3_MAX_OVERRIDE, + + /* + * Defines the PER threshold of the BT voice + * + * Range: 0 - 65000 + */ + CONF_SG_BT_NFS_SAMPLE_INTERVAL, + + /* + * Defines the load ratio of BT + * + * Range: 0 - 100 (%) + */ + CONF_SG_BT_LOAD_RATIO, + + /* + * Defines whether the SG will force WLAN host to enter/exit PSM + * + * Range: 1 - SG can force, 0 - host handles PSM + */ + CONF_SG_AUTO_PS_MODE, + + /* + * Compensation percentage of probe requests when scan initiated + * during BT voice/ACL link. + * + * Range: 0 - 255 (%) + */ + CONF_SG_AUTO_SCAN_PROBE_REQ, + + /* + * Compensation percentage of probe requests when active scan initiated + * during BT voice + * + * Range: 0 - 255 (%) + */ + CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3, + + /* + * Defines antenna configuration (single/dual antenna) + * + * Range: 0 - single antenna, 1 - dual antenna + */ + CONF_SG_ANTENNA_CONFIGURATION, + + /* + * The threshold (percent) of max consequtive beacon misses before + * increasing priority of beacon reception. + * + * Range: 0 - 100 (%) + */ + CONF_SG_BEACON_MISS_PERCENT, + + /* + * The rate threshold below which receiving a data frame from the AP + * will increase the priority of the data frame above BT traffic. + * + * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54 + */ + CONF_SG_RATE_ADAPT_THRESH, + + /* + * Not used currently. + * + * Range: 0 + */ + CONF_SG_RATE_ADAPT_SNR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN PSM / BT master basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR, + CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR, + + /* + * The time after it expires no new WLAN trigger frame is trasmitted + * in WLAN PSM / BT master basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN PSM / BT slave basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR, + CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR, + + /* + * The time after it expires no new WLAN trigger frame is trasmitted + * in WLAN PSM / BT slave basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN PSM / BT master EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR, + CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR, + + /* + * The time after it expires no new WLAN trigger frame is trasmitted + * in WLAN PSM / BT master EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN PSM / BT slave EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR, + CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR, + + /* + * The time after it expires no new WLAN trigger frame is trasmitted + * in WLAN PSM / BT slave EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR, + + /* + * RX guard time before the beginning of a new BT voice frame during + * which no new WLAN trigger frame is transmitted. + * + * Range: 0 - 100000 (us) + */ + CONF_SG_RXT, + + /* + * TX guard time before the beginning of a new BT voice frame during + * which no new WLAN frame is transmitted. + * + * Range: 0 - 100000 (us) + */ + + CONF_SG_TXT, + + /* + * Enable adaptive RXT/TXT algorithm. If disabled, the host values + * will be utilized. + * + * Range: 0 - disable, 1 - enable + */ + CONF_SG_ADAPTIVE_RXT_TXT, + + /* + * The used WLAN legacy service period during active BT ACL link + * + * Range: 0 - 255 (ms) + */ + CONF_SG_PS_POLL_TIMEOUT, + + /* + * The used WLAN UPSD service period during active BT ACL link + * + * Range: 0 - 255 (ms) + */ + CONF_SG_UPSD_TIMEOUT, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN Active / BT master EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR, + CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR, + + /* + * The maximum time WLAN can gain the antenna for + * in WLAN Active / BT master EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN Active / BT slave EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR, + CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR, + + /* + * The maximum time WLAN can gain the antenna for + * in WLAN Active / BT slave EDR + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR, + + /* + * Configure the min and max time BT gains the antenna + * in WLAN Active / BT basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR, + CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR, + + /* + * The maximum time WLAN can gain the antenna for + * in WLAN Active / BT basic rate + * + * Range: 0 - 255 (ms) + */ + CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR, + + /* + * Compensation percentage of WLAN passive scan window if initiated + * during BT voice + * + * Range: 0 - 1000 (%) + */ + CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3, + + /* + * Compensation percentage of WLAN passive scan window if initiated + * during BT A2DP + * + * Range: 0 - 1000 (%) + */ + CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP, + + /* + * Fixed time ensured for BT traffic to gain the antenna during WLAN + * passive scan. + * + * Range: 0 - 1000 ms + */ + CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME, + + /* + * Fixed time ensured for WLAN traffic to gain the antenna during WLAN + * passive scan. + * + * Range: 0 - 1000 ms + */ + CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME, + + /* + * Number of consequent BT voice frames not interrupted by WLAN + * + * Range: 0 - 100 + */ + CONF_SG_HV3_MAX_SERVED, + + /* + * Protection time of the DHCP procedure. + * + * Range: 0 - 100000 (ms) + */ + CONF_SG_DHCP_TIME, + + /* + * Compensation percentage of WLAN active scan window if initiated + * during BT A2DP + * + * Range: 0 - 1000 (%) + */ + CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP, + CONF_SG_TEMP_PARAM_1, + CONF_SG_TEMP_PARAM_2, + CONF_SG_TEMP_PARAM_3, + CONF_SG_TEMP_PARAM_4, + CONF_SG_TEMP_PARAM_5, + CONF_SG_PARAMS_MAX, + CONF_SG_PARAMS_ALL = 0xff +}; + +struct conf_sg_settings { + u32 params[CONF_SG_PARAMS_MAX]; + u8 state; +}; + +enum conf_rx_queue_type { + CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ + CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */ +}; + +struct conf_rx_settings { + /* + * The maximum amount of time, in TU, before the + * firmware discards the MSDU. + * + * Range: 0 - 0xFFFFFFFF + */ + u32 rx_msdu_life_time; + + /* + * Packet detection threshold in the PHY. + * + * FIXME: details unknown. + */ + u32 packet_detection_threshold; + + /* + * The longest time the STA will wait to receive traffic from the AP + * after a PS-poll has been transmitted. + * + * Range: 0 - 200000 + */ + u16 ps_poll_timeout; + /* + * The longest time the STA will wait to receive traffic from the AP + * after a frame has been sent from an UPSD enabled queue. + * + * Range: 0 - 200000 + */ + u16 upsd_timeout; + + /* + * The number of octets in an MPDU, below which an RTS/CTS + * handshake is not performed. + * + * Range: 0 - 4096 + */ + u16 rts_threshold; + + /* + * The RX Clear Channel Assessment threshold in the PHY + * (the energy threshold). + * + * Range: ENABLE_ENERGY_D == 0x140A + * DISABLE_ENERGY_D == 0xFFEF + */ + u16 rx_cca_threshold; + + /* + * Occupied Rx mem-blocks number which requires interrupting the host + * (0 = no buffering, 0xffff = disabled). + * + * Range: u16 + */ + u16 irq_blk_threshold; + + /* + * Rx packets number which requires interrupting the host + * (0 = no buffering). + * + * Range: u16 + */ + u16 irq_pkt_threshold; + + /* + * Max time in msec the FW may delay RX-Complete interrupt. + * + * Range: 1 - 100 + */ + u16 irq_timeout; + + /* + * The RX queue type. + * + * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, + */ + u8 queue_type; +}; + +#define CONF_TX_MAX_RATE_CLASSES 8 + +#define CONF_TX_RATE_MASK_UNSPECIFIED 0 +#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \ + CONF_HW_BIT_RATE_2MBPS) +#define CONF_TX_RATE_RETRY_LIMIT 10 + +struct conf_tx_rate_class { + + /* + * The rates enabled for this rate class. + * + * Range: CONF_HW_BIT_RATE_* bit mask + */ + u32 enabled_rates; + + /* + * The dot11 short retry limit used for TX retries. + * + * Range: u8 + */ + u8 short_retry_limit; + + /* + * The dot11 long retry limit used for TX retries. + * + * Range: u8 + */ + u8 long_retry_limit; + + /* + * Flags controlling the attributes of TX transmission. + * + * Range: bit 0: Truncate - when set, FW attempts to send a frame stop + * when the total valid per-rate attempts have + * been exhausted; otherwise transmissions + * will continue at the lowest available rate + * until the appropriate one of the + * short_retry_limit, long_retry_limit, + * dot11_max_transmit_msdu_life_time, or + * max_tx_life_time, is exhausted. + * 1: Preamble Override - indicates if the preamble type + * should be used in TX. + * 2: Preamble Type - the type of the preamble to be used by + * the policy (0 - long preamble, 1 - short preamble. + */ + u8 aflags; +}; + +#define CONF_TX_MAX_AC_COUNT 4 + +/* Slot number setting to start transmission at PIFS interval */ +#define CONF_TX_AIFS_PIFS 1 +/* Slot number setting to start transmission at DIFS interval normal + * DCF access */ +#define CONF_TX_AIFS_DIFS 2 + + +enum conf_tx_ac { + CONF_TX_AC_BE = 0, /* best effort / legacy */ + CONF_TX_AC_BK = 1, /* background */ + CONF_TX_AC_VI = 2, /* video */ + CONF_TX_AC_VO = 3, /* voice */ + CONF_TX_AC_CTS2SELF = 4, /* fictious AC, follows AC_VO */ + CONF_TX_AC_ANY_TID = 0x1f +}; + +struct conf_tx_ac_category { + /* + * The AC class identifier. + * + * Range: enum conf_tx_ac + */ + u8 ac; + + /* + * The contention window minimum size (in slots) for the access + * class. + * + * Range: u8 + */ + u8 cw_min; + + /* + * The contention window maximum size (in slots) for the access + * class. + * + * Range: u8 + */ + u16 cw_max; + + /* + * The AIF value (in slots) for the access class. + * + * Range: u8 + */ + u8 aifsn; + + /* + * The TX Op Limit (in microseconds) for the access class. + * + * Range: u16 + */ + u16 tx_op_limit; +}; + +#define CONF_TX_MAX_TID_COUNT 8 + +enum { + CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ + CONF_CHANNEL_TYPE_EDCF = 1, /* EDCA*/ + CONF_CHANNEL_TYPE_HCCA = 2, /* HCCA*/ +}; + +enum { + CONF_PS_SCHEME_LEGACY = 0, + CONF_PS_SCHEME_UPSD_TRIGGER = 1, + CONF_PS_SCHEME_LEGACY_PSPOLL = 2, + CONF_PS_SCHEME_SAPSD = 3, +}; + +enum { + CONF_ACK_POLICY_LEGACY = 0, + CONF_ACK_POLICY_NO_ACK = 1, + CONF_ACK_POLICY_BLOCK = 2, +}; + + +struct conf_tx_tid { + u8 queue_id; + u8 channel_type; + u8 tsid; + u8 ps_scheme; + u8 ack_policy; + u32 apsd_conf[2]; +}; + +struct conf_tx_settings { + /* + * The TX ED value for TELEC Enable/Disable. + * + * Range: 0, 1 + */ + u8 tx_energy_detection; + + /* + * Configuration for rate classes for TX (currently only one + * rate class supported.) + */ + struct conf_tx_rate_class rc_conf; + + /* + * Configuration for access categories for TX rate control. + */ + u8 ac_conf_count; + struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT]; + + /* + * Configuration for TID parameters. + */ + u8 tid_conf_count; + struct conf_tx_tid tid_conf[CONF_TX_MAX_TID_COUNT]; + + /* + * The TX fragmentation threshold. + * + * Range: u16 + */ + u16 frag_threshold; + + /* + * Max time in msec the FW may delay frame TX-Complete interrupt. + * + * Range: u16 + */ + u16 tx_compl_timeout; + + /* + * Completed TX packet count which requires to issue the TX-Complete + * interrupt. + * + * Range: u16 + */ + u16 tx_compl_threshold; + + /* + * The rate used for control messages and scanning on the 2.4GHz band + * + * Range: CONF_HW_BIT_RATE_* bit mask + */ + u32 basic_rate; + + /* + * The rate used for control messages and scanning on the 5GHz band + * + * Range: CONF_HW_BIT_RATE_* bit mask + */ + u32 basic_rate_5; +}; + +enum { + CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ + CONF_WAKE_UP_EVENT_DTIM = 0x02, /* Wake on every DTIM*/ + CONF_WAKE_UP_EVENT_N_DTIM = 0x04, /* Wake every Nth DTIM */ + CONF_WAKE_UP_EVENT_N_BEACONS = 0x08, /* Wake every Nth beacon */ + CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F +}; + +#define CONF_MAX_BCN_FILT_IE_COUNT 32 + +#define CONF_BCN_RULE_PASS_ON_CHANGE BIT(0) +#define CONF_BCN_RULE_PASS_ON_APPEARANCE BIT(1) + +#define CONF_BCN_IE_OUI_LEN 3 +#define CONF_BCN_IE_VER_LEN 2 + +struct conf_bcn_filt_rule { + /* + * IE number to which to associate a rule. + * + * Range: u8 + */ + u8 ie; + + /* + * Rule to associate with the specific ie. + * + * Range: CONF_BCN_RULE_PASS_ON_* + */ + u8 rule; + + /* + * OUI for the vendor specifie IE (221) + */ + u8 oui[CONF_BCN_IE_OUI_LEN]; + + /* + * Type for the vendor specifie IE (221) + */ + u8 type; + + /* + * Version for the vendor specifie IE (221) + */ + u8 version[CONF_BCN_IE_VER_LEN]; +}; + +#define CONF_MAX_RSSI_SNR_TRIGGERS 8 + +enum { + CONF_TRIG_METRIC_RSSI_BEACON = 0, + CONF_TRIG_METRIC_RSSI_DATA, + CONF_TRIG_METRIC_SNR_BEACON, + CONF_TRIG_METRIC_SNR_DATA +}; + +enum { + CONF_TRIG_EVENT_TYPE_LEVEL = 0, + CONF_TRIG_EVENT_TYPE_EDGE +}; + +enum { + CONF_TRIG_EVENT_DIR_LOW = 0, + CONF_TRIG_EVENT_DIR_HIGH, + CONF_TRIG_EVENT_DIR_BIDIR +}; + +struct conf_sig_weights { + + /* + * RSSI from beacons average weight. + * + * Range: u8 + */ + u8 rssi_bcn_avg_weight; + + /* + * RSSI from data average weight. + * + * Range: u8 + */ + u8 rssi_pkt_avg_weight; + + /* + * SNR from beacons average weight. + * + * Range: u8 + */ + u8 snr_bcn_avg_weight; + + /* + * SNR from data average weight. + * + * Range: u8 + */ + u8 snr_pkt_avg_weight; +}; + +enum conf_bcn_filt_mode { + CONF_BCN_FILT_MODE_DISABLED = 0, + CONF_BCN_FILT_MODE_ENABLED = 1 +}; + +enum conf_bet_mode { + CONF_BET_MODE_DISABLE = 0, + CONF_BET_MODE_ENABLE = 1, +}; + +struct conf_conn_settings { + /* + * Firmware wakeup conditions configuration. The host may set only + * one bit. + * + * Range: CONF_WAKE_UP_EVENT_* + */ + u8 wake_up_event; + + /* + * Listen interval for beacons or Dtims. + * + * Range: 0 for beacon and Dtim wakeup + * 1-10 for x Dtims + * 1-255 for x beacons + */ + u8 listen_interval; + + /* + * Enable or disable the beacon filtering. + * + * Range: CONF_BCN_FILT_MODE_* + */ + enum conf_bcn_filt_mode bcn_filt_mode; + + /* + * Configure Beacon filter pass-thru rules. + */ + u8 bcn_filt_ie_count; + struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT]; + + /* + * The number of consequtive beacons to lose, before the firmware + * becomes out of synch. + * + * Range: u32 + */ + u32 synch_fail_thold; + + /* + * After out-of-synch, the number of TU's to wait without a further + * received beacon (or probe response) before issuing the BSS_EVENT_LOSE + * event. + * + * Range: u32 + */ + u32 bss_lose_timeout; + + /* + * Beacon receive timeout. + * + * Range: u32 + */ + u32 beacon_rx_timeout; + + /* + * Broadcast receive timeout. + * + * Range: u32 + */ + u32 broadcast_timeout; + + /* + * Enable/disable reception of broadcast packets in power save mode + * + * Range: 1 - enable, 0 - disable + */ + u8 rx_broadcast_in_ps; + + /* + * Consequtive PS Poll failures before sending event to driver + * + * Range: u8 + */ + u8 ps_poll_threshold; + + /* + * PS Poll failure recovery ACTIVE period length + * + * Range: u32 (ms) + */ + u32 ps_poll_recovery_period; + + /* + * Configuration of signal average weights. + */ + struct conf_sig_weights sig_weights; + + /* + * Specifies if beacon early termination procedure is enabled or + * disabled. + * + * Range: CONF_BET_MODE_* + */ + u8 bet_enable; + + /* + * Specifies the maximum number of consecutive beacons that may be + * early terminated. After this number is reached at least one full + * beacon must be correctly received in FW before beacon ET + * resumes. + * + * Range 0 - 255 + */ + u8 bet_max_consecutive; + + /* + * Specifies the maximum number of times to try PSM entry if it fails + * (if sending the appropriate null-func message fails.) + * + * Range 0 - 255 + */ + u8 psm_entry_retries; + + /* + * Specifies the maximum number of times to try transmit the PSM entry + * null-func frame for each PSM entry attempt + * + * Range 0 - 255 + */ + u8 psm_entry_nullfunc_retries; + + /* + * Specifies the time to linger in active mode after successfully + * transmitting the PSM entry null-func frame. + * + * Range 0 - 255 TU's + */ + u8 psm_entry_hangover_period; + + /* + * + * Specifies the interval of the connection keep-alive null-func + * frame in ms. + * + * Range: 1000 - 3600000 + */ + u32 keep_alive_interval; + + /* + * Maximum listen interval supported by the driver in units of beacons. + * + * Range: u16 + */ + u8 max_listen_interval; +}; + +enum { + CONF_REF_CLK_19_2_E, + CONF_REF_CLK_26_E, + CONF_REF_CLK_38_4_E, + CONF_REF_CLK_52_E +}; + +enum single_dual_band_enum { + CONF_SINGLE_BAND, + CONF_DUAL_BAND +}; + +#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15 +#define CONF_NUMBER_OF_SUB_BANDS_5 7 +#define CONF_NUMBER_OF_RATE_GROUPS 6 +#define CONF_NUMBER_OF_CHANNELS_2_4 14 +#define CONF_NUMBER_OF_CHANNELS_5 35 + +struct conf_radio_parms { + /* + * FEM parameter set to use + * + * Range: 0 or 1 + */ + u8 fem; +}; + +struct conf_itrim_settings { + /* enable dco itrim */ + u8 enable; + + /* moderation timeout in microsecs from the last TX */ + u32 timeout; +}; + +struct conf_pm_config_settings { + /* + * Host clock settling time + * + * Range: 0 - 30000 us + */ + u32 host_clk_settling_time; + + /* + * Host fast wakeup support + * + * Range: true, false + */ + bool host_fast_wakeup_support; +}; + +struct conf_roam_trigger_settings { + /* + * The minimum interval between two trigger events. + * + * Range: 0 - 60000 ms + */ + u16 trigger_pacing; + + /* + * The weight for rssi/beacon average calculation + * + * Range: 0 - 255 + */ + u8 avg_weight_rssi_beacon; + + /* + * The weight for rssi/data frame average calculation + * + * Range: 0 - 255 + */ + u8 avg_weight_rssi_data; + + /* + * The weight for snr/beacon average calculation + * + * Range: 0 - 255 + */ + u8 avg_weight_snr_beacon; + + /* + * The weight for snr/data frame average calculation + * + * Range: 0 - 255 + */ + u8 avg_weight_snr_data; +}; + +struct conf_scan_settings { + /* + * The minimum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_active; + + /* + * The maximum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_active; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_passive; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_passive; + + /* + * Number of probe requests to transmit on each active scan channel + * + * Range: u8 + */ + u16 num_probe_reqs; + +}; + +/* these are number of channels on the band divided by two, rounded up */ +#define CONF_TX_PWR_COMPENSATION_LEN_2 7 +#define CONF_TX_PWR_COMPENSATION_LEN_5 18 + +struct conf_rf_settings { + /* + * Per channel power compensation for 2.4GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + + /* + * Per channel power compensation for 5GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; +}; + +struct conf_drv_settings { + struct conf_sg_settings sg; + struct conf_rx_settings rx; + struct conf_tx_settings tx; + struct conf_conn_settings conn; + struct conf_itrim_settings itrim; + struct conf_pm_config_settings pm_config; + struct conf_roam_trigger_settings roam_trigger; + struct conf_scan_settings scan; + struct conf_rf_settings rf; +}; + +#endif diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c new file mode 100644 index 000000000000..dd71b7d2105c --- /dev/null +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -0,0 +1,590 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "debugfs.h" + +#include +#include + +#include "wl12xx.h" +#include "acx.h" +#include "ps.h" +#include "io.h" + +/* ms */ +#define WL1271_DEBUGFS_STATS_LIFETIME 1000 + +/* debugfs macros idea from mac80211 */ +#define DEBUGFS_FORMAT_BUFFER_SIZE 100 +static int wl1271_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...) +{ + va_list args; + char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; + int res; + + va_start(args, fmt); + res = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ +static ssize_t name## _read(struct file *file, char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1271 *wl = file->private_data; \ + return wl1271_format_buffer(userbuf, count, ppos, \ + fmt "\n", ##value); \ +} \ + \ +static const struct file_operations name## _ops = { \ + .read = name## _read, \ + .open = wl1271_open_file_generic, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_ADD(name, parent) \ + wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ + wl, &name## _ops); \ + if (IS_ERR(wl->debugfs.name)) { \ + ret = PTR_ERR(wl->debugfs.name); \ + wl->debugfs.name = NULL; \ + goto out; \ + } + +#define DEBUGFS_DEL(name) \ + do { \ + debugfs_remove(wl->debugfs.name); \ + wl->debugfs.name = NULL; \ + } while (0) + +#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ +static ssize_t sub## _ ##name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1271 *wl = file->private_data; \ + \ + wl1271_debugfs_update_stats(wl); \ + \ + return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ + wl->stats.fw_stats->sub.name); \ +} \ + \ +static const struct file_operations sub## _ ##name## _ops = { \ + .read = sub## _ ##name## _read, \ + .open = wl1271_open_file_generic, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_FWSTATS_ADD(sub, name) \ + DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) + +#define DEBUGFS_FWSTATS_DEL(sub, name) \ + DEBUGFS_DEL(sub## _ ##name) + +static void wl1271_debugfs_update_stats(struct wl1271 *wl) +{ + int ret; + + mutex_lock(&wl->mutex); + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if (wl->state == WL1271_STATE_ON && + time_after(jiffies, wl->stats.fw_stats_update + + msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { + wl1271_acx_statistics(wl, wl->stats.fw_stats); + wl->stats.fw_stats_update = jiffies; + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1271_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); + +DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); +DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); +DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); +DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); +DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); +DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); + +DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); +DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); + +DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); +DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); +DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); +DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); +DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); +DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); +DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); +DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); +DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); + +DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); +DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); +/* skipping wep.reserved */ +DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); +DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); +DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); + +DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); +/* skipping cont_miss_bcns_spread for now */ +DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); + +DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); +DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); + +DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); + +DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); +DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); +DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); +DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); +DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); + +DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); + +DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); + +DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); +DEBUGFS_READONLY_FILE(excessive_retries, "%u", + wl->stats.excessive_retries); + +static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + u32 queue_len; + char buf[20]; + int res; + + queue_len = skb_queue_len(&wl->tx_queue); + + res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static const struct file_operations tx_queue_len_ops = { + .read = tx_queue_len_read, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + +static ssize_t gpio_power_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + + int res; + char buf[10]; + + res = scnprintf(buf, sizeof(buf), "%d\n", state); + + return simple_read_from_buffer(user_buf, count, ppos, buf, res); +} + +static ssize_t gpio_power_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + char buf[10]; + size_t len; + unsigned long value; + int ret; + + mutex_lock(&wl->mutex); + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) { + ret = -EFAULT; + goto out; + } + buf[len] = '\0'; + + ret = strict_strtoul(buf, 0, &value); + if (ret < 0) { + wl1271_warning("illegal value in gpio_power"); + goto out; + } + + if (value) + wl1271_power_on(wl); + else + wl1271_power_off(wl); + +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations gpio_power_ops = { + .read = gpio_power_read, + .write = gpio_power_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + +static void wl1271_debugfs_delete_files(struct wl1271 *wl) +{ + DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); + + DEBUGFS_FWSTATS_DEL(rx, out_of_mem); + DEBUGFS_FWSTATS_DEL(rx, hdr_overflow); + DEBUGFS_FWSTATS_DEL(rx, hw_stuck); + DEBUGFS_FWSTATS_DEL(rx, dropped); + DEBUGFS_FWSTATS_DEL(rx, fcs_err); + DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig); + DEBUGFS_FWSTATS_DEL(rx, path_reset); + DEBUGFS_FWSTATS_DEL(rx, reset_counter); + + DEBUGFS_FWSTATS_DEL(dma, rx_requested); + DEBUGFS_FWSTATS_DEL(dma, rx_errors); + DEBUGFS_FWSTATS_DEL(dma, tx_requested); + DEBUGFS_FWSTATS_DEL(dma, tx_errors); + + DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt); + DEBUGFS_FWSTATS_DEL(isr, fiqs); + DEBUGFS_FWSTATS_DEL(isr, rx_headers); + DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow); + DEBUGFS_FWSTATS_DEL(isr, rx_rdys); + DEBUGFS_FWSTATS_DEL(isr, irqs); + DEBUGFS_FWSTATS_DEL(isr, tx_procs); + DEBUGFS_FWSTATS_DEL(isr, decrypt_done); + DEBUGFS_FWSTATS_DEL(isr, dma0_done); + DEBUGFS_FWSTATS_DEL(isr, dma1_done); + DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete); + DEBUGFS_FWSTATS_DEL(isr, commands); + DEBUGFS_FWSTATS_DEL(isr, rx_procs); + DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes); + DEBUGFS_FWSTATS_DEL(isr, host_acknowledges); + DEBUGFS_FWSTATS_DEL(isr, pci_pm); + DEBUGFS_FWSTATS_DEL(isr, wakeups); + DEBUGFS_FWSTATS_DEL(isr, low_rssi); + + DEBUGFS_FWSTATS_DEL(wep, addr_key_count); + DEBUGFS_FWSTATS_DEL(wep, default_key_count); + /* skipping wep.reserved */ + DEBUGFS_FWSTATS_DEL(wep, key_not_found); + DEBUGFS_FWSTATS_DEL(wep, decrypt_fail); + DEBUGFS_FWSTATS_DEL(wep, packets); + DEBUGFS_FWSTATS_DEL(wep, interrupt); + + DEBUGFS_FWSTATS_DEL(pwr, ps_enter); + DEBUGFS_FWSTATS_DEL(pwr, elp_enter); + DEBUGFS_FWSTATS_DEL(pwr, missing_bcns); + DEBUGFS_FWSTATS_DEL(pwr, wake_on_host); + DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp); + DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps); + DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps); + DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons); + DEBUGFS_FWSTATS_DEL(pwr, power_save_off); + DEBUGFS_FWSTATS_DEL(pwr, enable_ps); + DEBUGFS_FWSTATS_DEL(pwr, disable_ps); + DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps); + /* skipping cont_miss_bcns_spread for now */ + DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons); + + DEBUGFS_FWSTATS_DEL(mic, rx_pkts); + DEBUGFS_FWSTATS_DEL(mic, calc_failure); + + DEBUGFS_FWSTATS_DEL(aes, encrypt_fail); + DEBUGFS_FWSTATS_DEL(aes, decrypt_fail); + DEBUGFS_FWSTATS_DEL(aes, encrypt_packets); + DEBUGFS_FWSTATS_DEL(aes, decrypt_packets); + DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt); + DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt); + + DEBUGFS_FWSTATS_DEL(event, heart_beat); + DEBUGFS_FWSTATS_DEL(event, calibration); + DEBUGFS_FWSTATS_DEL(event, rx_mismatch); + DEBUGFS_FWSTATS_DEL(event, rx_mem_empty); + DEBUGFS_FWSTATS_DEL(event, rx_pool); + DEBUGFS_FWSTATS_DEL(event, oom_late); + DEBUGFS_FWSTATS_DEL(event, phy_transmit_error); + DEBUGFS_FWSTATS_DEL(event, tx_stuck); + + DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts); + DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts); + DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime); + DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn); + DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn); + DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization); + DEBUGFS_FWSTATS_DEL(ps, upsd_utilization); + + DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop); + DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); + + DEBUGFS_DEL(tx_queue_len); + DEBUGFS_DEL(retry_count); + DEBUGFS_DEL(excessive_retries); + + DEBUGFS_DEL(gpio_power); +} + +static int wl1271_debugfs_add_files(struct wl1271 *wl) +{ + int ret = 0; + + DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); + + DEBUGFS_FWSTATS_ADD(rx, out_of_mem); + DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); + DEBUGFS_FWSTATS_ADD(rx, hw_stuck); + DEBUGFS_FWSTATS_ADD(rx, dropped); + DEBUGFS_FWSTATS_ADD(rx, fcs_err); + DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); + DEBUGFS_FWSTATS_ADD(rx, path_reset); + DEBUGFS_FWSTATS_ADD(rx, reset_counter); + + DEBUGFS_FWSTATS_ADD(dma, rx_requested); + DEBUGFS_FWSTATS_ADD(dma, rx_errors); + DEBUGFS_FWSTATS_ADD(dma, tx_requested); + DEBUGFS_FWSTATS_ADD(dma, tx_errors); + + DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); + DEBUGFS_FWSTATS_ADD(isr, fiqs); + DEBUGFS_FWSTATS_ADD(isr, rx_headers); + DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); + DEBUGFS_FWSTATS_ADD(isr, rx_rdys); + DEBUGFS_FWSTATS_ADD(isr, irqs); + DEBUGFS_FWSTATS_ADD(isr, tx_procs); + DEBUGFS_FWSTATS_ADD(isr, decrypt_done); + DEBUGFS_FWSTATS_ADD(isr, dma0_done); + DEBUGFS_FWSTATS_ADD(isr, dma1_done); + DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); + DEBUGFS_FWSTATS_ADD(isr, commands); + DEBUGFS_FWSTATS_ADD(isr, rx_procs); + DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); + DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); + DEBUGFS_FWSTATS_ADD(isr, pci_pm); + DEBUGFS_FWSTATS_ADD(isr, wakeups); + DEBUGFS_FWSTATS_ADD(isr, low_rssi); + + DEBUGFS_FWSTATS_ADD(wep, addr_key_count); + DEBUGFS_FWSTATS_ADD(wep, default_key_count); + /* skipping wep.reserved */ + DEBUGFS_FWSTATS_ADD(wep, key_not_found); + DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); + DEBUGFS_FWSTATS_ADD(wep, packets); + DEBUGFS_FWSTATS_ADD(wep, interrupt); + + DEBUGFS_FWSTATS_ADD(pwr, ps_enter); + DEBUGFS_FWSTATS_ADD(pwr, elp_enter); + DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); + DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); + DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); + DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); + DEBUGFS_FWSTATS_ADD(pwr, power_save_off); + DEBUGFS_FWSTATS_ADD(pwr, enable_ps); + DEBUGFS_FWSTATS_ADD(pwr, disable_ps); + DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); + /* skipping cont_miss_bcns_spread for now */ + DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); + + DEBUGFS_FWSTATS_ADD(mic, rx_pkts); + DEBUGFS_FWSTATS_ADD(mic, calc_failure); + + DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); + DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); + + DEBUGFS_FWSTATS_ADD(event, heart_beat); + DEBUGFS_FWSTATS_ADD(event, calibration); + DEBUGFS_FWSTATS_ADD(event, rx_mismatch); + DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); + DEBUGFS_FWSTATS_ADD(event, rx_pool); + DEBUGFS_FWSTATS_ADD(event, oom_late); + DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); + DEBUGFS_FWSTATS_ADD(event, tx_stuck); + + DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); + DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); + + DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); + DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); + + DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); + DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); + DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); + + DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir); + +out: + if (ret < 0) + wl1271_debugfs_delete_files(wl); + + return ret; +} + +void wl1271_debugfs_reset(struct wl1271 *wl) +{ + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + wl->stats.retry_count = 0; + wl->stats.excessive_retries = 0; +} + +int wl1271_debugfs_init(struct wl1271 *wl) +{ + int ret; + + wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); + + if (IS_ERR(wl->debugfs.rootdir)) { + ret = PTR_ERR(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + goto err; + } + + wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics", + wl->debugfs.rootdir); + + if (IS_ERR(wl->debugfs.fw_statistics)) { + ret = PTR_ERR(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + goto err_root; + } + + wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), + GFP_KERNEL); + + if (!wl->stats.fw_stats) { + ret = -ENOMEM; + goto err_fw; + } + + wl->stats.fw_stats_update = jiffies; + + ret = wl1271_debugfs_add_files(wl); + + if (ret < 0) + goto err_file; + + return 0; + +err_file: + kfree(wl->stats.fw_stats); + wl->stats.fw_stats = NULL; + +err_fw: + debugfs_remove(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + +err_root: + debugfs_remove(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + +err: + return ret; +} + +void wl1271_debugfs_exit(struct wl1271 *wl) +{ + wl1271_debugfs_delete_files(wl); + + kfree(wl->stats.fw_stats); + wl->stats.fw_stats = NULL; + + debugfs_remove(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + + debugfs_remove(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + +} diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h new file mode 100644 index 000000000000..254c5b292cf6 --- /dev/null +++ b/drivers/net/wireless/wl12xx/debugfs.h @@ -0,0 +1,33 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __DEBUGFS_H__ +#define __DEBUGFS_H__ + +#include "wl12xx.h" + +int wl1271_debugfs_init(struct wl1271 *wl); +void wl1271_debugfs_exit(struct wl1271 *wl); +void wl1271_debugfs_reset(struct wl1271 *wl); + +#endif /* WL1271_DEBUGFS_H */ diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c new file mode 100644 index 000000000000..f9146f5242fb --- /dev/null +++ b/drivers/net/wireless/wl12xx/event.c @@ -0,0 +1,293 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "wl12xx.h" +#include "reg.h" +#include "io.h" +#include "event.h" +#include "ps.h" +#include "scan.h" +#include "wl12xx_80211.h" + +void wl1271_pspoll_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, pspoll_work); + + wl1271_debug(DEBUG_EVENT, "pspoll work"); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) + goto out; + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + /* + * if we end up here, then we were in powersave when the pspoll + * delivery failure occurred, and no-one changed state since, so + * we should go back to powersave. + */ + wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); + +out: + mutex_unlock(&wl->mutex); +}; + +static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl) +{ + int delay = wl->conf.conn.ps_poll_recovery_period; + int ret; + + wl->ps_poll_failures++; + if (wl->ps_poll_failures == 1) + wl1271_info("AP with dysfunctional ps-poll, " + "trying to work around it."); + + /* force active mode receive data from the AP */ + if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, true); + if (ret < 0) + return; + set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); + ieee80211_queue_delayed_work(wl->hw, &wl->pspoll_work, + msecs_to_jiffies(delay)); + } + + /* + * If already in active mode, lets we should be getting data from + * the AP right away. If we enter PSM too fast after this, and data + * remains on the AP, we will get another event like this, and we'll + * go into active once more. + */ +} + +static int wl1271_event_ps_report(struct wl1271 *wl, + struct event_mailbox *mbox, + bool *beacon_loss) +{ + int ret = 0; + u32 total_retries = wl->conf.conn.psm_entry_retries; + + wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); + + switch (mbox->ps_status) { + case EVENT_ENTER_POWER_SAVE_FAIL: + wl1271_debug(DEBUG_PSM, "PSM entry failed"); + + if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) { + /* remain in active mode */ + wl->psm_entry_retry = 0; + break; + } + + if (wl->psm_entry_retry < total_retries) { + wl->psm_entry_retry++; + ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, + wl->basic_rate, true); + } else { + wl1271_info("No ack to nullfunc from AP."); + wl->psm_entry_retry = 0; + *beacon_loss = true; + } + break; + case EVENT_ENTER_POWER_SAVE_SUCCESS: + wl->psm_entry_retry = 0; + + /* enable beacon filtering */ + ret = wl1271_acx_beacon_filter_opt(wl, true); + if (ret < 0) + break; + + /* enable beacon early termination */ + ret = wl1271_acx_bet_enable(wl, true); + if (ret < 0) + break; + + /* go to extremely low power mode */ + wl1271_ps_elp_sleep(wl); + break; + case EVENT_EXIT_POWER_SAVE_FAIL: + wl1271_debug(DEBUG_PSM, "PSM exit failed"); + + if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { + wl->psm_entry_retry = 0; + break; + } + + /* make sure the firmware goes to active mode - the frame to + be sent next will indicate to the AP, that we are active. */ + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, false); + break; + case EVENT_EXIT_POWER_SAVE_SUCCESS: + default: + break; + } + + return ret; +} + +static void wl1271_event_rssi_trigger(struct wl1271 *wl, + struct event_mailbox *mbox) +{ + enum nl80211_cqm_rssi_threshold_event event; + s8 metric = mbox->rssi_snr_trigger_metric[0]; + + wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric); + + if (metric <= wl->rssi_thold) + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + else + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + + if (event != wl->last_rssi_event) + ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL); + wl->last_rssi_event = event; +} + +static void wl1271_event_mbox_dump(struct event_mailbox *mbox) +{ + wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); + wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); + wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); +} + +static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) +{ + int ret; + u32 vector; + bool beacon_loss = false; + + wl1271_event_mbox_dump(mbox); + + vector = le32_to_cpu(mbox->events_vector); + vector &= ~(le32_to_cpu(mbox->events_mask)); + wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector); + + if (vector & SCAN_COMPLETE_EVENT_ID) { + wl1271_debug(DEBUG_EVENT, "status: 0x%x", + mbox->scheduled_scan_status); + + wl1271_scan_stm(wl); + } + + /* disable dynamic PS when requested by the firmware */ + if (vector & SOFT_GEMINI_SENSE_EVENT_ID && + wl->bss_type == BSS_TYPE_STA_BSS) { + if (mbox->soft_gemini_sense_info) + ieee80211_disable_dyn_ps(wl->vif); + else + ieee80211_enable_dyn_ps(wl->vif); + } + + /* + * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon + * filtering) is enabled. Without PSM, the stack will receive all + * beacons and can detect beacon loss by itself. + * + * As there's possibility that the driver disables PSM before receiving + * BSS_LOSE_EVENT, beacon loss has to be reported to the stack. + * + */ + if (vector & BSS_LOSE_EVENT_ID) { + wl1271_info("Beacon loss detected."); + + /* indicate to the stack, that beacons have been lost */ + beacon_loss = true; + } + + if (vector & PS_REPORT_EVENT_ID) { + wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); + ret = wl1271_event_ps_report(wl, mbox, &beacon_loss); + if (ret < 0) + return ret; + } + + if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) + wl1271_event_pspoll_delivery_fail(wl); + + if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { + wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); + if (wl->vif) + wl1271_event_rssi_trigger(wl, mbox); + } + + if (wl->vif && beacon_loss) + ieee80211_connection_loss(wl->vif); + + return 0; +} + +int wl1271_event_unmask(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask)); + if (ret < 0) + return ret; + + return 0; +} + +void wl1271_event_mbox_config(struct wl1271 *wl) +{ + wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); + wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); + + wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", + wl->mbox_ptr[0], wl->mbox_ptr[1]); +} + +int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) +{ + struct event_mailbox mbox; + int ret; + + wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); + + if (mbox_num > 1) + return -EINVAL; + + /* first we read the mbox descriptor */ + wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox, + sizeof(struct event_mailbox), false); + + /* process the descriptor */ + ret = wl1271_event_process(wl, &mbox); + if (ret < 0) + return ret; + + /* then we let the firmware know it can go on...*/ + wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); + + return 0; +} diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h new file mode 100644 index 000000000000..6cce0143adb5 --- /dev/null +++ b/drivers/net/wireless/wl12xx/event.h @@ -0,0 +1,126 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __EVENT_H__ +#define __EVENT_H__ + +/* + * Mbox events + * + * The event mechanism is based on a pair of event buffers (buffers A and + * B) at fixed locations in the target's memory. The host processes one + * buffer while the other buffer continues to collect events. If the host + * is not processing events, an interrupt is issued to signal that a buffer + * is ready. Once the host is done with processing events from one buffer, + * it signals the target (with an ACK interrupt) that the event buffer is + * free. + */ + +enum { + RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0), + RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1), + RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2), + RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3), + RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4), + RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5), + RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6), + RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7), + MEASUREMENT_START_EVENT_ID = BIT(8), + MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), + SCAN_COMPLETE_EVENT_ID = BIT(10), + SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(11), + AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12), + PS_REPORT_EVENT_ID = BIT(13), + PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14), + DISCONNECT_EVENT_COMPLETE_ID = BIT(15), + JOIN_EVENT_COMPLETE_ID = BIT(16), + CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), + BSS_LOSE_EVENT_ID = BIT(18), + REGAINED_BSS_EVENT_ID = BIT(19), + ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), + SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), + SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), + SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), + PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), + DBG_EVENT_ID = BIT(26), + HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), + PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), + PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), + BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30), + EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, +}; + +enum { + EVENT_ENTER_POWER_SAVE_FAIL = 0, + EVENT_ENTER_POWER_SAVE_SUCCESS, + EVENT_EXIT_POWER_SAVE_FAIL, + EVENT_EXIT_POWER_SAVE_SUCCESS, +}; + +struct event_debug_report { + u8 debug_event_id; + u8 num_params; + __le16 pad; + __le32 report_1; + __le32 report_2; + __le32 report_3; +} __packed; + +#define NUM_OF_RSSI_SNR_TRIGGERS 8 + +struct event_mailbox { + __le32 events_vector; + __le32 events_mask; + __le32 reserved_1; + __le32 reserved_2; + + u8 dbg_event_id; + u8 num_relevant_params; + __le16 reserved_3; + __le32 event_report_p1; + __le32 event_report_p2; + __le32 event_report_p3; + + u8 number_of_scan_results; + u8 scan_tag; + u8 reserved_4[2]; + __le32 compl_scheduled_scan_status; + + __le16 scheduled_scan_attended_channels; + u8 soft_gemini_sense_info; + u8 soft_gemini_protective_info; + s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS]; + u8 channel_switch_status; + u8 scheduled_scan_status; + u8 ps_status; + + u8 reserved_5[29]; +} __packed; + +int wl1271_event_unmask(struct wl1271 *wl); +void wl1271_event_mbox_config(struct wl1271 *wl); +int wl1271_event_handle(struct wl1271 *wl, u8 mbox); +void wl1271_pspoll_work(struct work_struct *work); + +#endif diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/wl12xx/ini.h new file mode 100644 index 000000000000..c330a2583dfd --- /dev/null +++ b/drivers/net/wireless/wl12xx/ini.h @@ -0,0 +1,123 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __INI_H__ +#define __INI_H__ + +#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16 + +struct wl1271_ini_general_params { + u8 ref_clock; + u8 settling_time; + u8 clk_valid_on_wakeup; + u8 dc2dc_mode; + u8 dual_mode_select; + u8 tx_bip_fem_auto_detect; + u8 tx_bip_fem_manufacturer; + u8 general_settings; + u8 sr_state; + u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; +} __packed; + +#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 + +struct wl1271_ini_band_params_2 { + u8 rx_trace_insertion_loss; + u8 tx_trace_loss; + u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; +} __packed; + +#define WL1271_INI_RATE_GROUP_COUNT 6 +#define WL1271_INI_CHANNEL_COUNT_2 14 + +struct wl1271_ini_fem_params_2 { + __le16 tx_bip_ref_pd_voltage; + u8 tx_bip_ref_power; + u8 tx_bip_ref_offset; + u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; + u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; + u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; + u8 rx_fem_insertion_loss; + u8 degraded_low_to_normal_thr; + u8 normal_to_degraded_high_thr; +} __packed; + +#define WL1271_INI_CHANNEL_COUNT_5 35 +#define WL1271_INI_SUB_BAND_COUNT_5 7 + +struct wl1271_ini_band_params_5 { + u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; +} __packed; + +struct wl1271_ini_fem_params_5 { + __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; + u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; + u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 degraded_low_to_normal_thr; + u8 normal_to_degraded_high_thr; +} __packed; + + +/* NVS data structure */ +#define WL1271_INI_NVS_SECTION_SIZE 468 +#define WL1271_INI_FEM_MODULE_COUNT 2 + +#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 + +struct wl1271_nvs_file { + /* NVS section */ + u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; + + /* INI section */ + struct wl1271_ini_general_params general_params; + u8 padding1; + struct wl1271_ini_band_params_2 stat_radio_params_2; + u8 padding2; + struct { + struct wl1271_ini_fem_params_2 params; + u8 padding; + } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; + struct wl1271_ini_band_params_5 stat_radio_params_5; + u8 padding3; + struct { + struct wl1271_ini_fem_params_5 params; + u8 padding; + } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; +} __packed; + +#endif diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c new file mode 100644 index 000000000000..492edc0f7aca --- /dev/null +++ b/drivers/net/wireless/wl12xx/init.c @@ -0,0 +1,369 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +#include "init.h" +#include "wl12xx_80211.h" +#include "acx.h" +#include "cmd.h" +#include "reg.h" + +static int wl1271_init_hwenc_config(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_feature_cfg(wl); + if (ret < 0) { + wl1271_warning("couldn't set feature config"); + return ret; + } + + ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key); + if (ret < 0) { + wl1271_warning("couldn't set default key"); + return ret; + } + + return 0; +} + +int wl1271_init_templates_config(struct wl1271 *wl) +{ + int ret, i; + size_t size; + + /* send empty templates for fw memory reservation */ + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, + sizeof(struct wl12xx_probe_req_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + size = sizeof(struct wl12xx_probe_req_template); + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + NULL, size, 0, + WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, + sizeof(struct wl12xx_null_data_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, + sizeof(struct wl12xx_ps_poll_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, + sizeof + (struct wl12xx_qos_null_data_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, + sizeof + (struct wl12xx_probe_resp_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, + sizeof + (struct wl12xx_beacon_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, + WL1271_CMD_TEMPL_MAX_SIZE, i, + WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + } + + return 0; +} + +static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) +{ + int ret; + + ret = wl1271_acx_rx_msdu_life_time(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_rx_config(wl, config, filter); + if (ret < 0) + return ret; + + return 0; +} + +int wl1271_init_phy_config(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_pd_threshold(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME); + if (ret < 0) + return ret; + + ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); + if (ret < 0) + return ret; + + ret = wl1271_acx_service_period_timeout(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold); + if (ret < 0) + return ret; + + return 0; +} + +static int wl1271_init_beacon_filter(struct wl1271 *wl) +{ + int ret; + + /* disable beacon filtering at this stage */ + ret = wl1271_acx_beacon_filter_opt(wl, false); + if (ret < 0) + return ret; + + ret = wl1271_acx_beacon_filter_table(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1271_init_pta(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_sg_cfg(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); + if (ret < 0) + return ret; + + return 0; +} + +int wl1271_init_energy_detection(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_cca_threshold(wl); + if (ret < 0) + return ret; + + return 0; +} + +static int wl1271_init_beacon_broadcast(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_acx_bcn_dtim_options(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1271_hw_init(struct wl1271 *wl) +{ + struct conf_tx_ac_category *conf_ac; + struct conf_tx_tid *conf_tid; + int ret, i; + + ret = wl1271_cmd_general_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_cmd_radio_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + + /* Template settings */ + ret = wl1271_init_templates_config(wl); + if (ret < 0) + return ret; + + /* Default memory configuration */ + ret = wl1271_acx_init_mem_config(wl); + if (ret < 0) + return ret; + + /* RX config */ + ret = wl1271_init_rx_config(wl, + RX_CFG_PROMISCUOUS | RX_CFG_TSF, + RX_FILTER_OPTION_DEF); + /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS, + RX_FILTER_OPTION_FILTER_ALL); */ + if (ret < 0) + goto out_free_memmap; + + /* PHY layer config */ + ret = wl1271_init_phy_config(wl); + if (ret < 0) + goto out_free_memmap; + + ret = wl1271_acx_dco_itrim_params(wl); + if (ret < 0) + goto out_free_memmap; + + /* Initialize connection monitoring thresholds */ + ret = wl1271_acx_conn_monit_params(wl, false); + if (ret < 0) + goto out_free_memmap; + + /* Beacon filtering */ + ret = wl1271_init_beacon_filter(wl); + if (ret < 0) + goto out_free_memmap; + + /* Configure TX patch complete interrupt behavior */ + ret = wl1271_acx_tx_config_options(wl); + if (ret < 0) + goto out_free_memmap; + + /* RX complete interrupt pacing */ + ret = wl1271_acx_init_rx_interrupt(wl); + if (ret < 0) + goto out_free_memmap; + + /* Bluetooth WLAN coexistence */ + ret = wl1271_init_pta(wl); + if (ret < 0) + goto out_free_memmap; + + /* Energy detection */ + ret = wl1271_init_energy_detection(wl); + if (ret < 0) + goto out_free_memmap; + + /* Beacons and boradcast settings */ + ret = wl1271_init_beacon_broadcast(wl); + if (ret < 0) + goto out_free_memmap; + + /* Default fragmentation threshold */ + ret = wl1271_acx_frag_threshold(wl); + if (ret < 0) + goto out_free_memmap; + + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); + for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + + conf_tid = &wl->conf.tx.tid_conf[i]; + ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, + conf_tid->channel_type, + conf_tid->tsid, + conf_tid->ps_scheme, + conf_tid->ack_policy, + conf_tid->apsd_conf[0], + conf_tid->apsd_conf[1]); + if (ret < 0) + goto out_free_memmap; + } + + /* Configure TX rate classes */ + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + goto out_free_memmap; + + /* Enable data path */ + ret = wl1271_cmd_data_path(wl, 1); + if (ret < 0) + goto out_free_memmap; + + /* Configure for ELP power saving */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + if (ret < 0) + goto out_free_memmap; + + /* Configure HW encryption */ + ret = wl1271_init_hwenc_config(wl); + if (ret < 0) + goto out_free_memmap; + + /* configure PM */ + ret = wl1271_acx_pm_config(wl); + if (ret < 0) + goto out_free_memmap; + + /* disable all keep-alive templates */ + for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { + ret = wl1271_acx_keep_alive_config(wl, i, + ACX_KEEP_ALIVE_TPL_INVALID); + if (ret < 0) + goto out_free_memmap; + } + + /* disable the keep-alive feature */ + ret = wl1271_acx_keep_alive_mode(wl, false); + if (ret < 0) + goto out_free_memmap; + + /* Configure rssi/snr averaging weights */ + ret = wl1271_acx_rssi_snr_avg_weights(wl); + if (ret < 0) + goto out_free_memmap; + + return 0; + + out_free_memmap: + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; + + return ret; +} diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h new file mode 100644 index 000000000000..7762421f8602 --- /dev/null +++ b/drivers/net/wireless/wl12xx/init.h @@ -0,0 +1,36 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __INIT_H__ +#define __INIT_H__ + +#include "wl12xx.h" + +int wl1271_hw_init_power_auth(struct wl1271 *wl); +int wl1271_init_templates_config(struct wl1271 *wl); +int wl1271_init_phy_config(struct wl1271 *wl); +int wl1271_init_pta(struct wl1271 *wl); +int wl1271_init_energy_detection(struct wl1271 *wl); +int wl1271_hw_init(struct wl1271 *wl); + +#endif diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c new file mode 100644 index 000000000000..35c2f1aca6ba --- /dev/null +++ b/drivers/net/wireless/wl12xx/io.c @@ -0,0 +1,170 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include + +#include "wl12xx.h" +#include "wl12xx_80211.h" +#include "io.h" + +#define OCP_CMD_LOOP 32 + +#define OCP_CMD_WRITE 0x1 +#define OCP_CMD_READ 0x2 + +#define OCP_READY_MASK BIT(18) +#define OCP_STATUS_MASK (BIT(16) | BIT(17)) + +#define OCP_STATUS_NO_RESP 0x00000 +#define OCP_STATUS_OK 0x10000 +#define OCP_STATUS_REQ_FAILED 0x20000 +#define OCP_STATUS_RESP_ERROR 0x30000 + +void wl1271_disable_interrupts(struct wl1271 *wl) +{ + wl->if_ops->disable_irq(wl); +} + +void wl1271_enable_interrupts(struct wl1271 *wl) +{ + wl->if_ops->enable_irq(wl); +} + +/* Set the SPI partitions to access the chip addresses + * + * To simplify driver code, a fixed (virtual) memory map is defined for + * register and memory addresses. Because in the chipset, in different stages + * of operation, those addresses will move around, an address translation + * mechanism is required. + * + * There are four partitions (three memory and one register partition), + * which are mapped to two different areas of the hardware memory. + * + * Virtual address + * space + * + * | | + * ...+----+--> mem.start + * Physical address ... | | + * space ... | | [PART_0] + * ... | | + * 00000000 <--+----+... ...+----+--> mem.start + mem.size + * | | ... | | + * |MEM | ... | | + * | | ... | | + * mem.size <--+----+... | | {unused area) + * | | ... | | + * |REG | ... | | + * mem.size | | ... | | + * + <--+----+... ...+----+--> reg.start + * reg.size | | ... | | + * |MEM2| ... | | [PART_1] + * | | ... | | + * ...+----+--> reg.start + reg.size + * | | + * + */ +int wl1271_set_partition(struct wl1271 *wl, + struct wl1271_partition_set *p) +{ + /* copy partition info */ + memcpy(&wl->part, p, sizeof(*p)); + + wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", + p->mem.start, p->mem.size); + wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", + p->reg.start, p->reg.size); + wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", + p->mem2.start, p->mem2.size); + wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", + p->mem3.start, p->mem3.size); + + /* write partition info to the chipset */ + wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); + wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); + wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); + wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); + wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); + wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); + wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); + + return 0; +} + +void wl1271_io_reset(struct wl1271 *wl) +{ + wl->if_ops->reset(wl); +} + +void wl1271_io_init(struct wl1271 *wl) +{ + wl->if_ops->init(wl); +} + +void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) +{ + /* write address >> 1 + 0x30000 to OCP_POR_CTR */ + addr = (addr >> 1) + 0x30000; + wl1271_write32(wl, OCP_POR_CTR, addr); + + /* write value to OCP_POR_WDATA */ + wl1271_write32(wl, OCP_DATA_WRITE, val); + + /* write 1 to OCP_CMD */ + wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE); +} + +u16 wl1271_top_reg_read(struct wl1271 *wl, int addr) +{ + u32 val; + int timeout = OCP_CMD_LOOP; + + /* write address >> 1 + 0x30000 to OCP_POR_CTR */ + addr = (addr >> 1) + 0x30000; + wl1271_write32(wl, OCP_POR_CTR, addr); + + /* write 2 to OCP_CMD */ + wl1271_write32(wl, OCP_CMD, OCP_CMD_READ); + + /* poll for data ready */ + do { + val = wl1271_read32(wl, OCP_DATA_READ); + } while (!(val & OCP_READY_MASK) && --timeout); + + if (!timeout) { + wl1271_warning("Top register access timed out."); + return 0xffff; + } + + /* check data status and return if OK */ + if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) + return val & 0xffff; + else { + wl1271_warning("Top register access returned error."); + return 0xffff; + } +} + diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h new file mode 100644 index 000000000000..844b32b170bb --- /dev/null +++ b/drivers/net/wireless/wl12xx/io.h @@ -0,0 +1,172 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __IO_H__ +#define __IO_H__ + +#include "reg.h" + +#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 + +#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0 +#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) +#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) +#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) +#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) +#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) +#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) +#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) + +#define HW_ACCESS_REGISTER_SIZE 4 + +#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 + +struct wl1271; + +void wl1271_disable_interrupts(struct wl1271 *wl); +void wl1271_enable_interrupts(struct wl1271 *wl); + +void wl1271_io_reset(struct wl1271 *wl); +void wl1271_io_init(struct wl1271 *wl); + +static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl) +{ + return wl->if_ops->dev(wl); +} + + +/* Raw target IO, address is not translated */ +static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + wl->if_ops->write(wl, addr, buf, len, fixed); +} + +static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + wl->if_ops->read(wl, addr, buf, len, fixed); +} + +static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) +{ + wl1271_raw_read(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); + + return le32_to_cpu(wl->buffer_32); +} + +static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) +{ + wl->buffer_32 = cpu_to_le32(val); + wl1271_raw_write(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); +} + +/* Translated target IO */ +static inline int wl1271_translate_addr(struct wl1271 *wl, int addr) +{ + /* + * To translate, first check to which window of addresses the + * particular address belongs. Then subtract the starting address + * of that window from the address. Then, add offset of the + * translated region. + * + * The translated regions occur next to each other in physical device + * memory, so just add the sizes of the preceeding address regions to + * get the offset to the new region. + * + * Currently, only the two first regions are addressed, and the + * assumption is that all addresses will fall into either of those + * two. + */ + if ((addr >= wl->part.reg.start) && + (addr < wl->part.reg.start + wl->part.reg.size)) + return addr - wl->part.reg.start + wl->part.mem.size; + else + return addr - wl->part.mem.start; +} + +static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int physical; + + physical = wl1271_translate_addr(wl, addr); + + wl1271_raw_read(wl, physical, buf, len, fixed); +} + +static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int physical; + + physical = wl1271_translate_addr(wl, addr); + + wl1271_raw_write(wl, physical, buf, len, fixed); +} + +static inline u32 wl1271_read32(struct wl1271 *wl, int addr) +{ + return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); +} + +static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) +{ + wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); +} + +static inline void wl1271_power_off(struct wl1271 *wl) +{ + wl->if_ops->power(wl, false); + clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); +} + +static inline int wl1271_power_on(struct wl1271 *wl) +{ + int ret = wl->if_ops->power(wl, true); + if (ret == 0) + set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + + return ret; +} + + +/* Top Register IO */ +void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); +u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); + +int wl1271_set_partition(struct wl1271 *wl, + struct wl1271_partition_set *p); + +/* Functions from wl1271_main.c */ + +int wl1271_register_hw(struct wl1271 *wl); +void wl1271_unregister_hw(struct wl1271 *wl); +int wl1271_init_ieee80211(struct wl1271 *wl); +struct ieee80211_hw *wl1271_alloc_hw(void); +int wl1271_free_hw(struct wl1271 *wl); + +#endif diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c new file mode 100644 index 000000000000..c00523008be4 --- /dev/null +++ b/drivers/net/wireless/wl12xx/main.c @@ -0,0 +1,2749 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "wl12xx_80211.h" +#include "reg.h" +#include "io.h" +#include "event.h" +#include "tx.h" +#include "rx.h" +#include "ps.h" +#include "init.h" +#include "debugfs.h" +#include "cmd.h" +#include "boot.h" +#include "testmode.h" +#include "scan.h" + +#define WL1271_BOOT_RETRIES 3 + +static struct conf_drv_settings default_conf = { + .sg = { + .params = { + [CONF_SG_BT_PER_THRESHOLD] = 7500, + [CONF_SG_HV3_MAX_OVERRIDE] = 0, + [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, + [CONF_SG_BT_LOAD_RATIO] = 50, + [CONF_SG_AUTO_PS_MODE] = 1, + [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, + [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, + [CONF_SG_ANTENNA_CONFIGURATION] = 0, + [CONF_SG_BEACON_MISS_PERCENT] = 60, + [CONF_SG_RATE_ADAPT_THRESH] = 12, + [CONF_SG_RATE_ADAPT_SNR] = 0, + [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10, + [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30, + [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8, + [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20, + [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50, + /* Note: with UPSD, this should be 4 */ + [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8, + [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7, + [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25, + [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20, + /* Note: with UPDS, this should be 15 */ + [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8, + /* Note: with UPDS, this should be 50 */ + [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40, + /* Note: with UPDS, this should be 10 */ + [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20, + [CONF_SG_RXT] = 1200, + [CONF_SG_TXT] = 1000, + [CONF_SG_ADAPTIVE_RXT_TXT] = 1, + [CONF_SG_PS_POLL_TIMEOUT] = 10, + [CONF_SG_UPSD_TIMEOUT] = 10, + [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7, + [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15, + [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15, + [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8, + [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20, + [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15, + [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20, + [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50, + [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10, + [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, + [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800, + [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75, + [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15, + [CONF_SG_HV3_MAX_SERVED] = 6, + [CONF_SG_DHCP_TIME] = 5000, + [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, + }, + .state = CONF_SG_PROTECTIVE, + }, + .rx = { + .rx_msdu_life_time = 512000, + .packet_detection_threshold = 0, + .ps_poll_timeout = 15, + .upsd_timeout = 15, + .rts_threshold = 2347, + .rx_cca_threshold = 0, + .irq_blk_threshold = 0xFFFF, + .irq_pkt_threshold = 0, + .irq_timeout = 600, + .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, + }, + .tx = { + .tx_energy_detection = 0, + .rc_conf = { + .enabled_rates = 0, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0 + }, + .ac_conf_count = 4, + .ac_conf = { + [CONF_TX_AC_BE] = { + .ac = CONF_TX_AC_BE, + .cw_min = 15, + .cw_max = 63, + .aifsn = 3, + .tx_op_limit = 0, + }, + [CONF_TX_AC_BK] = { + .ac = CONF_TX_AC_BK, + .cw_min = 15, + .cw_max = 63, + .aifsn = 7, + .tx_op_limit = 0, + }, + [CONF_TX_AC_VI] = { + .ac = CONF_TX_AC_VI, + .cw_min = 15, + .cw_max = 63, + .aifsn = CONF_TX_AIFS_PIFS, + .tx_op_limit = 3008, + }, + [CONF_TX_AC_VO] = { + .ac = CONF_TX_AC_VO, + .cw_min = 15, + .cw_max = 63, + .aifsn = CONF_TX_AIFS_PIFS, + .tx_op_limit = 1504, + }, + }, + .tid_conf_count = 4, + .tid_conf = { + [CONF_TX_AC_BE] = { + .queue_id = CONF_TX_AC_BE, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BE, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_BK] = { + .queue_id = CONF_TX_AC_BK, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BK, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_VI] = { + .queue_id = CONF_TX_AC_VI, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VI, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_VO] = { + .queue_id = CONF_TX_AC_VO, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VO, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + }, + .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, + .tx_compl_timeout = 700, + .tx_compl_threshold = 4, + .basic_rate = CONF_HW_BIT_RATE_1MBPS, + .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, + }, + .conn = { + .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, + .listen_interval = 1, + .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, + .bcn_filt_ie_count = 1, + .bcn_filt_ie = { + [0] = { + .ie = WLAN_EID_CHANNEL_SWITCH, + .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, + } + }, + .synch_fail_thold = 10, + .bss_lose_timeout = 100, + .beacon_rx_timeout = 10000, + .broadcast_timeout = 20000, + .rx_broadcast_in_ps = 1, + .ps_poll_threshold = 10, + .ps_poll_recovery_period = 700, + .bet_enable = CONF_BET_MODE_ENABLE, + .bet_max_consecutive = 10, + .psm_entry_retries = 5, + .psm_entry_nullfunc_retries = 3, + .psm_entry_hangover_period = 1, + .keep_alive_interval = 55000, + .max_listen_interval = 20, + }, + .itrim = { + .enable = false, + .timeout = 50000, + }, + .pm_config = { + .host_clk_settling_time = 5000, + .host_fast_wakeup_support = false + }, + .roam_trigger = { + .trigger_pacing = 1, + .avg_weight_rssi_beacon = 20, + .avg_weight_rssi_data = 10, + .avg_weight_snr_beacon = 20, + .avg_weight_snr_data = 10 + }, + .scan = { + .min_dwell_time_active = 7500, + .max_dwell_time_active = 30000, + .min_dwell_time_passive = 30000, + .max_dwell_time_passive = 60000, + .num_probe_reqs = 2, + }, + .rf = { + .tx_per_channel_power_compensation_2 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .tx_per_channel_power_compensation_5 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + }, +}; + +static void __wl1271_op_remove_interface(struct wl1271 *wl); + + +static void wl1271_device_release(struct device *dev) +{ + +} + +static struct platform_device wl1271_device = { + .name = "wl1271", + .id = -1, + + /* device model insists to have a release function */ + .dev = { + .release = wl1271_device_release, + }, +}; + +static LIST_HEAD(wl_list); + +static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, + void *arg) +{ + struct net_device *dev = arg; + struct wireless_dev *wdev; + struct wiphy *wiphy; + struct ieee80211_hw *hw; + struct wl1271 *wl; + struct wl1271 *wl_temp; + int ret = 0; + + /* Check that this notification is for us. */ + if (what != NETDEV_CHANGE) + return NOTIFY_DONE; + + wdev = dev->ieee80211_ptr; + if (wdev == NULL) + return NOTIFY_DONE; + + wiphy = wdev->wiphy; + if (wiphy == NULL) + return NOTIFY_DONE; + + hw = wiphy_priv(wiphy); + if (hw == NULL) + return NOTIFY_DONE; + + wl_temp = hw->priv; + list_for_each_entry(wl, &wl_list, list) { + if (wl == wl_temp) + break; + } + if (wl != wl_temp) + return NOTIFY_DONE; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if ((dev->operstate == IF_OPER_UP) && + !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) { + wl1271_cmd_set_sta_state(wl); + wl1271_info("Association completed."); + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return NOTIFY_OK; +} + +static void wl1271_conf_init(struct wl1271 *wl) +{ + + /* + * This function applies the default configuration to the driver. This + * function is invoked upon driver load (spi probe.) + * + * The configuration is stored in a run-time structure in order to + * facilitate for run-time adjustment of any of the parameters. Making + * changes to the configuration structure will apply the new values on + * the next interface up (wl1271_op_start.) + */ + + /* apply driver default configuration */ + memcpy(&wl->conf, &default_conf, sizeof(default_conf)); +} + + +static int wl1271_plt_init(struct wl1271 *wl) +{ + struct conf_tx_ac_category *conf_ac; + struct conf_tx_tid *conf_tid; + int ret, i; + + ret = wl1271_cmd_general_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_cmd_radio_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_init_templates_config(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_init_mem_config(wl); + if (ret < 0) + return ret; + + /* PHY layer config */ + ret = wl1271_init_phy_config(wl); + if (ret < 0) + goto out_free_memmap; + + ret = wl1271_acx_dco_itrim_params(wl); + if (ret < 0) + goto out_free_memmap; + + /* Initialize connection monitoring thresholds */ + ret = wl1271_acx_conn_monit_params(wl, false); + if (ret < 0) + goto out_free_memmap; + + /* Bluetooth WLAN coexistence */ + ret = wl1271_init_pta(wl); + if (ret < 0) + goto out_free_memmap; + + /* Energy detection */ + ret = wl1271_init_energy_detection(wl); + if (ret < 0) + goto out_free_memmap; + + /* Default fragmentation threshold */ + ret = wl1271_acx_frag_threshold(wl); + if (ret < 0) + goto out_free_memmap; + + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); + for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + + conf_tid = &wl->conf.tx.tid_conf[i]; + ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, + conf_tid->channel_type, + conf_tid->tsid, + conf_tid->ps_scheme, + conf_tid->ack_policy, + conf_tid->apsd_conf[0], + conf_tid->apsd_conf[1]); + if (ret < 0) + goto out_free_memmap; + } + + /* Enable data path */ + ret = wl1271_cmd_data_path(wl, 1); + if (ret < 0) + goto out_free_memmap; + + /* Configure for CAM power saving (ie. always active) */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + goto out_free_memmap; + + /* configure PM */ + ret = wl1271_acx_pm_config(wl); + if (ret < 0) + goto out_free_memmap; + + return 0; + + out_free_memmap: + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; + + return ret; +} + +static void wl1271_fw_status(struct wl1271 *wl, + struct wl1271_fw_status *status) +{ + struct timespec ts; + u32 total = 0; + int i; + + wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); + + wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " + "drv_rx_counter = %d, tx_results_counter = %d)", + status->intr, + status->fw_rx_counter, + status->drv_rx_counter, + status->tx_results_counter); + + /* update number of available TX blocks */ + for (i = 0; i < NUM_TX_QUEUES; i++) { + u32 cnt = le32_to_cpu(status->tx_released_blks[i]) - + wl->tx_blocks_freed[i]; + + wl->tx_blocks_freed[i] = + le32_to_cpu(status->tx_released_blks[i]); + wl->tx_blocks_available += cnt; + total += cnt; + } + + /* if more blocks are available now, tx work can be scheduled */ + if (total) + clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); + + /* update the host-chipset time offset */ + getnstimeofday(&ts); + wl->time_offset = (timespec_to_ns(&ts) >> 10) - + (s64)le32_to_cpu(status->fw_localtime); +} + +#define WL1271_IRQ_MAX_LOOPS 10 + +static void wl1271_irq_work(struct work_struct *work) +{ + int ret; + u32 intr; + int loopcount = WL1271_IRQ_MAX_LOOPS; + unsigned long flags; + struct wl1271 *wl = + container_of(work, struct wl1271, irq_work); + + mutex_lock(&wl->mutex); + + wl1271_debug(DEBUG_IRQ, "IRQ work"); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, true); + if (ret < 0) + goto out; + + spin_lock_irqsave(&wl->wl_lock, flags); + while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { + clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + loopcount--; + + wl1271_fw_status(wl, wl->fw_status); + intr = le32_to_cpu(wl->fw_status->intr); + if (!intr) { + wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); + spin_lock_irqsave(&wl->wl_lock, flags); + continue; + } + + intr &= WL1271_INTR_MASK; + + if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { + wl1271_error("watchdog interrupt received! " + "starting recovery."); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + + /* restarting the chip. ignore any other interrupt. */ + goto out; + } + + if (intr & WL1271_ACX_INTR_DATA) { + wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); + + /* check for tx results */ + if (wl->fw_status->tx_results_counter != + (wl->tx_results_count & 0xff)) + wl1271_tx_complete(wl); + + /* Check if any tx blocks were freed */ + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + !skb_queue_empty(&wl->tx_queue)) { + /* + * In order to avoid starvation of the TX path, + * call the work function directly. + */ + wl1271_tx_work_locked(wl); + } + + wl1271_rx(wl, wl->fw_status); + } + + if (intr & WL1271_ACX_INTR_EVENT_A) { + wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); + wl1271_event_handle(wl, 0); + } + + if (intr & WL1271_ACX_INTR_EVENT_B) { + wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); + wl1271_event_handle(wl, 1); + } + + if (intr & WL1271_ACX_INTR_INIT_COMPLETE) + wl1271_debug(DEBUG_IRQ, + "WL1271_ACX_INTR_INIT_COMPLETE"); + + if (intr & WL1271_ACX_INTR_HW_AVAILABLE) + wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); + + spin_lock_irqsave(&wl->wl_lock, flags); + } + + if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->irq_work); + else + clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1271_fetch_firmware(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get firmware: %d", ret); + return ret; + } + + if (fw->size % 4) { + wl1271_error("firmware size is not multiple of 32 bits: %zu", + fw->size); + ret = -EILSEQ; + goto out; + } + + wl->fw_len = fw->size; + wl->fw = vmalloc(wl->fw_len); + + if (!wl->fw) { + wl1271_error("could not allocate memory for the firmware"); + ret = -ENOMEM; + goto out; + } + + memcpy(wl->fw, fw->data, wl->fw_len); + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1271_fetch_nvs(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get nvs file: %d", ret); + return ret; + } + + wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); + + if (!wl->nvs) { + wl1271_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; + goto out; + } + + wl->nvs_len = fw->size; + +out: + release_firmware(fw); + + return ret; +} + +static void wl1271_recovery_work(struct work_struct *work) +{ + struct wl1271 *wl = + container_of(work, struct wl1271, recovery_work); + + mutex_lock(&wl->mutex); + + if (wl->state != WL1271_STATE_ON) + goto out; + + wl1271_info("Hardware recovery in progress."); + + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + ieee80211_connection_loss(wl->vif); + + /* reboot the chipset */ + __wl1271_op_remove_interface(wl); + ieee80211_restart_hw(wl->hw); + +out: + mutex_unlock(&wl->mutex); +} + +static void wl1271_fw_wakeup(struct wl1271 *wl) +{ + u32 elp_reg; + + elp_reg = ELPCTRL_WAKE_UP; + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); +} + +static int wl1271_setup(struct wl1271 *wl) +{ + wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL); + if (!wl->fw_status) + return -ENOMEM; + + wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); + if (!wl->tx_res_if) { + kfree(wl->fw_status); + return -ENOMEM; + } + + return 0; +} + +static int wl1271_chip_wakeup(struct wl1271 *wl) +{ + struct wl1271_partition_set partition; + int ret = 0; + + msleep(WL1271_PRE_POWER_ON_SLEEP); + ret = wl1271_power_on(wl); + if (ret < 0) + goto out; + msleep(WL1271_POWER_ON_SLEEP); + wl1271_io_reset(wl); + wl1271_io_init(wl); + + /* We don't need a real memory partition here, because we only want + * to use the registers at this point. */ + memset(&partition, 0, sizeof(partition)); + partition.reg.start = REGISTERS_BASE; + partition.reg.size = REGISTERS_DOWN_SIZE; + wl1271_set_partition(wl, &partition); + + /* ELP module wake up */ + wl1271_fw_wakeup(wl); + + /* whal_FwCtrl_BootSm() */ + + /* 0. read chip id from CHIP_ID */ + wl->chip.id = wl1271_read32(wl, CHIP_ID_B); + + /* 1. check if chip id is valid */ + + switch (wl->chip.id) { + case CHIP_ID_1271_PG10: + wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", + wl->chip.id); + + ret = wl1271_setup(wl); + if (ret < 0) + goto out; + break; + case CHIP_ID_1271_PG20: + wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", + wl->chip.id); + + ret = wl1271_setup(wl); + if (ret < 0) + goto out; + break; + default: + wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); + ret = -ENODEV; + goto out; + } + + if (wl->fw == NULL) { + ret = wl1271_fetch_firmware(wl); + if (ret < 0) + goto out; + } + + /* No NVS from netlink, try to get it from the filesystem */ + if (wl->nvs == NULL) { + ret = wl1271_fetch_nvs(wl); + if (ret < 0) + goto out; + } + +out: + return ret; +} + +int wl1271_plt_start(struct wl1271 *wl) +{ + int retries = WL1271_BOOT_RETRIES; + int ret; + + mutex_lock(&wl->mutex); + + wl1271_notice("power up"); + + if (wl->state != WL1271_STATE_OFF) { + wl1271_error("cannot go into PLT state because not " + "in off state: %d", wl->state); + ret = -EBUSY; + goto out; + } + + while (retries) { + retries--; + ret = wl1271_chip_wakeup(wl); + if (ret < 0) + goto power_off; + + ret = wl1271_boot(wl); + if (ret < 0) + goto power_off; + + ret = wl1271_plt_init(wl); + if (ret < 0) + goto irq_disable; + + wl->state = WL1271_STATE_PLT; + wl1271_notice("firmware booted in PLT mode (%s)", + wl->chip.fw_ver); + goto out; + +irq_disable: + wl1271_disable_interrupts(wl); + mutex_unlock(&wl->mutex); + /* Unlocking the mutex in the middle of handling is + inherently unsafe. In this case we deem it safe to do, + because we need to let any possibly pending IRQ out of + the system (and while we are WL1271_STATE_OFF the IRQ + work function will not do anything.) Also, any other + possible concurrent operations will fail due to the + current state, hence the wl1271 struct should be safe. */ + cancel_work_sync(&wl->irq_work); + mutex_lock(&wl->mutex); +power_off: + wl1271_power_off(wl); + } + + wl1271_error("firmware boot in PLT mode failed despite %d retries", + WL1271_BOOT_RETRIES); +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +int wl1271_plt_stop(struct wl1271 *wl) +{ + int ret = 0; + + mutex_lock(&wl->mutex); + + wl1271_notice("power down"); + + if (wl->state != WL1271_STATE_PLT) { + wl1271_error("cannot power down because not in PLT " + "state: %d", wl->state); + ret = -EBUSY; + goto out; + } + + wl1271_disable_interrupts(wl); + wl1271_power_off(wl); + + wl->state = WL1271_STATE_OFF; + wl->rx_counter = 0; + +out: + mutex_unlock(&wl->mutex); + + cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->recovery_work); + + return ret; +} + +static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct wl1271 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = txinfo->control.sta; + unsigned long flags; + + /* + * peek into the rates configured in the STA entry. + * The rates set after connection stage, The first block only BG sets: + * the compare is for bit 0-16 of sta_rate_set. The second block add + * HT rates in case of HT supported. + */ + spin_lock_irqsave(&wl->wl_lock, flags); + if (sta && + (sta->supp_rates[conf->channel->band] != + (wl->sta_rate_set & HW_BG_RATES_MASK))) { + wl->sta_rate_set = sta->supp_rates[conf->channel->band]; + set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); + } + +#ifdef CONFIG_WL12XX_HT + if (sta && + sta->ht_cap.ht_supported && + ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != + sta->ht_cap.mcs.rx_mask[0])) { + /* Clean MCS bits before setting them */ + wl->sta_rate_set &= HW_BG_RATES_MASK; + wl->sta_rate_set |= + (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); + set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); + } +#endif + spin_unlock_irqrestore(&wl->wl_lock, flags); + + /* queue the packet */ + skb_queue_tail(&wl->tx_queue, skb); + + /* + * The chip specific setup must run before the first TX packet - + * before that, the tx_work will not be initialized! + */ + + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->tx_work); + + /* + * The workqueue is slow to process the tx_queue and we need stop + * the queue here, otherwise the queue will get too long. + */ + if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); + + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_stop_queues(wl->hw); + set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + + return NETDEV_TX_OK; +} + +static struct notifier_block wl1271_dev_notifier = { + .notifier_call = wl1271_dev_notify, +}; + +static int wl1271_op_start(struct ieee80211_hw *hw) +{ + wl1271_debug(DEBUG_MAC80211, "mac80211 start"); + + /* + * We have to delay the booting of the hardware because + * we need to know the local MAC address before downloading and + * initializing the firmware. The MAC address cannot be changed + * after boot, and without the proper MAC address, the firmware + * will not function properly. + * + * The MAC address is first known when the corresponding interface + * is added. That is where we will initialize the hardware. + */ + + return 0; +} + +static void wl1271_op_stop(struct ieee80211_hw *hw) +{ + wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); +} + +static int wl1271_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1271 *wl = hw->priv; + struct wiphy *wiphy = hw->wiphy; + int retries = WL1271_BOOT_RETRIES; + int ret = 0; + bool booted = false; + + wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", + vif->type, vif->addr); + + mutex_lock(&wl->mutex); + if (wl->vif) { + wl1271_debug(DEBUG_MAC80211, + "multiple vifs are not supported yet"); + ret = -EBUSY; + goto out; + } + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + wl->bss_type = BSS_TYPE_STA_BSS; + wl->set_bss_type = BSS_TYPE_STA_BSS; + break; + case NL80211_IFTYPE_ADHOC: + wl->bss_type = BSS_TYPE_IBSS; + wl->set_bss_type = BSS_TYPE_STA_BSS; + break; + default: + ret = -EOPNOTSUPP; + goto out; + } + + memcpy(wl->mac_addr, vif->addr, ETH_ALEN); + + if (wl->state != WL1271_STATE_OFF) { + wl1271_error("cannot start because not in off state: %d", + wl->state); + ret = -EBUSY; + goto out; + } + + while (retries) { + retries--; + ret = wl1271_chip_wakeup(wl); + if (ret < 0) + goto power_off; + + ret = wl1271_boot(wl); + if (ret < 0) + goto power_off; + + ret = wl1271_hw_init(wl); + if (ret < 0) + goto irq_disable; + + booted = true; + break; + +irq_disable: + wl1271_disable_interrupts(wl); + mutex_unlock(&wl->mutex); + /* Unlocking the mutex in the middle of handling is + inherently unsafe. In this case we deem it safe to do, + because we need to let any possibly pending IRQ out of + the system (and while we are WL1271_STATE_OFF the IRQ + work function will not do anything.) Also, any other + possible concurrent operations will fail due to the + current state, hence the wl1271 struct should be safe. */ + cancel_work_sync(&wl->irq_work); + mutex_lock(&wl->mutex); +power_off: + wl1271_power_off(wl); + } + + if (!booted) { + wl1271_error("firmware boot failed despite %d retries", + WL1271_BOOT_RETRIES); + goto out; + } + + wl->vif = vif; + wl->state = WL1271_STATE_ON; + wl1271_info("firmware booted (%s)", wl->chip.fw_ver); + + /* update hw/fw version info in wiphy struct */ + wiphy->hw_version = wl->chip.id; + strncpy(wiphy->fw_version, wl->chip.fw_ver, + sizeof(wiphy->fw_version)); + +out: + mutex_unlock(&wl->mutex); + + if (!ret) + list_add(&wl->list, &wl_list); + + return ret; +} + +static void __wl1271_op_remove_interface(struct wl1271 *wl) +{ + int i; + + wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); + + wl1271_info("down"); + + list_del(&wl->list); + + WARN_ON(wl->state != WL1271_STATE_ON); + + /* enable dyn ps just in case (if left on due to fw crash etc) */ + if (wl->bss_type == BSS_TYPE_STA_BSS) + ieee80211_enable_dyn_ps(wl->vif); + + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { + wl->scan.state = WL1271_SCAN_STATE_IDLE; + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; + wl->scan.req = NULL; + ieee80211_scan_completed(wl->hw, true); + } + + wl->state = WL1271_STATE_OFF; + + wl1271_disable_interrupts(wl); + + mutex_unlock(&wl->mutex); + + cancel_delayed_work_sync(&wl->scan_complete_work); + cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->tx_work); + cancel_delayed_work_sync(&wl->pspoll_work); + cancel_delayed_work_sync(&wl->elp_work); + + mutex_lock(&wl->mutex); + + /* let's notify MAC80211 about the remaining pending TX frames */ + wl1271_tx_reset(wl); + wl1271_power_off(wl); + + memset(wl->bssid, 0, ETH_ALEN); + memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); + wl->ssid_len = 0; + wl->bss_type = MAX_BSS_TYPE; + wl->set_bss_type = MAX_BSS_TYPE; + wl->band = IEEE80211_BAND_2GHZ; + + wl->rx_counter = 0; + wl->psm_entry_retry = 0; + wl->power_level = WL1271_DEFAULT_POWER_LEVEL; + wl->tx_blocks_available = 0; + wl->tx_results_count = 0; + wl->tx_packets_count = 0; + wl->tx_security_last_seq = 0; + wl->tx_security_seq = 0; + wl->time_offset = 0; + wl->session_counter = 0; + wl->rate_set = CONF_TX_RATE_MASK_BASIC; + wl->sta_rate_set = 0; + wl->flags = 0; + wl->vif = NULL; + wl->filters = 0; + + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_blocks_freed[i] = 0; + + wl1271_debugfs_reset(wl); + + kfree(wl->fw_status); + wl->fw_status = NULL; + kfree(wl->tx_res_if); + wl->tx_res_if = NULL; + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; +} + +static void wl1271_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1271 *wl = hw->priv; + + mutex_lock(&wl->mutex); + WARN_ON(wl->vif != vif); + __wl1271_op_remove_interface(wl); + mutex_unlock(&wl->mutex); + + cancel_work_sync(&wl->recovery_work); +} + +static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) +{ + wl->rx_config = WL1271_DEFAULT_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + + /* combine requested filters with current filter config */ + filters = wl->filters | filters; + + wl1271_debug(DEBUG_FILTERS, "RX filters set: "); + + if (filters & FIF_PROMISC_IN_BSS) { + wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS"); + wl->rx_config &= ~CFG_UNI_FILTER_EN; + wl->rx_config |= CFG_BSSID_FILTER_EN; + } + if (filters & FIF_BCN_PRBRESP_PROMISC) { + wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC"); + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + wl->rx_config &= ~CFG_SSID_FILTER_EN; + } + if (filters & FIF_OTHER_BSS) { + wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS"); + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + } + if (filters & FIF_CONTROL) { + wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL"); + wl->rx_filter |= CFG_RX_CTL_EN; + } + if (filters & FIF_FCSFAIL) { + wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL"); + wl->rx_filter |= CFG_RX_FCS_ERROR; + } +} + +static int wl1271_dummy_join(struct wl1271 *wl) +{ + int ret = 0; + /* we need to use a dummy BSSID for now */ + static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, + 0xad, 0xbe, 0xef }; + + memcpy(wl->bssid, dummy_bssid, ETH_ALEN); + + /* pass through frames from all BSS */ + wl1271_configure_filters(wl, FIF_OTHER_BSS); + + ret = wl1271_cmd_join(wl, wl->set_bss_type); + if (ret < 0) + goto out; + + set_bit(WL1271_FLAG_JOINED, &wl->flags); + +out: + return ret; +} + +static int wl1271_join(struct wl1271 *wl, bool set_assoc) +{ + int ret; + + /* + * One of the side effects of the JOIN command is that is clears + * WPA/WPA2 keys from the chipset. Performing a JOIN while associated + * to a WPA/WPA2 access point will therefore kill the data-path. + * Currently there is no supported scenario for JOIN during + * association - if it becomes a supported scenario, the WPA/WPA2 keys + * must be handled somehow. + * + */ + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + wl1271_info("JOIN while associated."); + + if (set_assoc) + set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); + + ret = wl1271_cmd_join(wl, wl->set_bss_type); + if (ret < 0) + goto out; + + set_bit(WL1271_FLAG_JOINED, &wl->flags); + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + /* + * The join command disable the keep-alive mode, shut down its process, + * and also clear the template config, so we need to reset it all after + * the join. The acx_aid starts the keep-alive process, and the order + * of the commands below is relevant. + */ + ret = wl1271_acx_keep_alive_mode(wl, true); + if (ret < 0) + goto out; + + ret = wl1271_acx_aid(wl, wl->aid); + if (ret < 0) + goto out; + + ret = wl1271_cmd_build_klv_null_data(wl); + if (ret < 0) + goto out; + + ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, + ACX_KEEP_ALIVE_TPL_VALID); + if (ret < 0) + goto out; + +out: + return ret; +} + +static int wl1271_unjoin(struct wl1271 *wl) +{ + int ret; + + /* to stop listening to a channel, we disconnect */ + ret = wl1271_cmd_disconnect(wl); + if (ret < 0) + goto out; + + clear_bit(WL1271_FLAG_JOINED, &wl->flags); + memset(wl->bssid, 0, ETH_ALEN); + + /* stop filterting packets based on bssid */ + wl1271_configure_filters(wl, FIF_OTHER_BSS); + +out: + return ret; +} + +static void wl1271_set_band_rate(struct wl1271 *wl) +{ + if (wl->band == IEEE80211_BAND_2GHZ) + wl->basic_rate_set = wl->conf.tx.basic_rate; + else + wl->basic_rate_set = wl->conf.tx.basic_rate_5; +} + +static u32 wl1271_min_rate_get(struct wl1271 *wl) +{ + int i; + u32 rate = 0; + + if (!wl->basic_rate_set) { + WARN_ON(1); + wl->basic_rate_set = wl->conf.tx.basic_rate; + } + + for (i = 0; !rate; i++) { + if ((wl->basic_rate_set >> i) & 0x1) + rate = 1 << i; + } + + return rate; +} + +static int wl1271_handle_idle(struct wl1271 *wl, bool idle) +{ + int ret; + + if (idle) { + if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { + ret = wl1271_unjoin(wl); + if (ret < 0) + goto out; + } + wl->rate_set = wl1271_min_rate_get(wl); + wl->sta_rate_set = 0; + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + goto out; + ret = wl1271_acx_keep_alive_config( + wl, CMD_TEMPL_KLV_IDX_NULL_DATA, + ACX_KEEP_ALIVE_TPL_INVALID); + if (ret < 0) + goto out; + set_bit(WL1271_FLAG_IDLE, &wl->flags); + } else { + /* increment the session counter */ + wl->session_counter++; + if (wl->session_counter >= SESSION_COUNTER_MAX) + wl->session_counter = 0; + ret = wl1271_dummy_join(wl); + if (ret < 0) + goto out; + clear_bit(WL1271_FLAG_IDLE, &wl->flags); + } + +out: + return ret; +} + +static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct wl1271 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + int channel, ret = 0; + + channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + + wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s", + channel, + conf->flags & IEEE80211_CONF_PS ? "on" : "off", + conf->power_level, + conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); + + /* + * mac80211 will go to idle nearly immediately after transmitting some + * frames, such as the deauth. To make sure those frames reach the air, + * wait here until the TX queue is fully flushed. + */ + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (conf->flags & IEEE80211_CONF_IDLE)) + wl1271_tx_flush(wl); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + /* if the channel changes while joined, join again */ + if (changed & IEEE80211_CONF_CHANGE_CHANNEL && + ((wl->band != conf->channel->band) || + (wl->channel != channel))) { + wl->band = conf->channel->band; + wl->channel = channel; + + /* + * FIXME: the mac80211 should really provide a fixed rate + * to use here. for now, just use the smallest possible rate + * for the band as a fixed rate for association frames and + * other control messages. + */ + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + wl1271_set_band_rate(wl); + + wl->basic_rate = wl1271_min_rate_get(wl); + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + wl1271_warning("rate policy for update channel " + "failed %d", ret); + + if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { + ret = wl1271_join(wl, false); + if (ret < 0) + wl1271_warning("cmd join to update channel " + "failed %d", ret); + } + } + + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + ret = wl1271_handle_idle(wl, conf->flags & IEEE80211_CONF_IDLE); + if (ret < 0) + wl1271_warning("idle mode change failed %d", ret); + } + + /* + * if mac80211 changes the PSM mode, make sure the mode is not + * incorrectly changed after the pspoll failure active window. + */ + if (changed & IEEE80211_CONF_CHANGE_PS) + clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); + + if (conf->flags & IEEE80211_CONF_PS && + !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { + set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); + + /* + * We enter PSM only if we're already associated. + * If we're not, we'll enter it when joining an SSID, + * through the bss_info_changed() hook. + */ + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { + wl1271_debug(DEBUG_PSM, "psm enabled"); + ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, + wl->basic_rate, true); + } + } else if (!(conf->flags & IEEE80211_CONF_PS) && + test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { + wl1271_debug(DEBUG_PSM, "psm disabled"); + + clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); + + if (test_bit(WL1271_FLAG_PSM, &wl->flags)) + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, true); + } + + if (conf->power_level != wl->power_level) { + ret = wl1271_acx_tx_power(wl, conf->power_level); + if (ret < 0) + goto out_sleep; + + wl->power_level = conf->power_level; + } + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +struct wl1271_filter_params { + bool enabled; + int mc_list_length; + u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; +}; + +static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + struct wl1271_filter_params *fp; + struct netdev_hw_addr *ha; + struct wl1271 *wl = hw->priv; + + if (unlikely(wl->state == WL1271_STATE_OFF)) + return 0; + + fp = kzalloc(sizeof(*fp), GFP_ATOMIC); + if (!fp) { + wl1271_error("Out of memory setting filters."); + return 0; + } + + /* update multicast filtering parameters */ + fp->mc_list_length = 0; + if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) { + fp->enabled = false; + } else { + fp->enabled = true; + netdev_hw_addr_list_for_each(ha, mc_list) { + memcpy(fp->mc_list[fp->mc_list_length], + ha->addr, ETH_ALEN); + fp->mc_list_length++; + } + } + + return (u64)(unsigned long)fp; +} + +#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | \ + FIF_FCSFAIL | \ + FIF_BCN_PRBRESP_PROMISC | \ + FIF_CONTROL | \ + FIF_OTHER_BSS) + +static void wl1271_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed, + unsigned int *total, u64 multicast) +{ + struct wl1271_filter_params *fp = (void *)(unsigned long)multicast; + struct wl1271 *wl = hw->priv; + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter"); + + mutex_lock(&wl->mutex); + + *total &= WL1271_SUPPORTED_FILTERS; + changed &= WL1271_SUPPORTED_FILTERS; + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + + if (*total & FIF_ALLMULTI) + ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); + else if (fp) + ret = wl1271_acx_group_address_tbl(wl, fp->enabled, + fp->mc_list, + fp->mc_list_length); + if (ret < 0) + goto out_sleep; + + /* determine, whether supported filter values have changed */ + if (changed == 0) + goto out_sleep; + + /* configure filters */ + wl->filters = *total; + wl1271_configure_filters(wl, 0); + + /* apply configured filters */ + ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + kfree(fp); +} + +static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf) +{ + struct wl1271 *wl = hw->priv; + const u8 *addr; + int ret; + u32 tx_seq_32 = 0; + u16 tx_seq_16 = 0; + u8 key_type; + + static const u8 bcast_addr[ETH_ALEN] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); + + addr = sta ? sta->addr : bcast_addr; + + wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); + wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); + wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", + key_conf->cipher, key_conf->keyidx, + key_conf->keylen, key_conf->flags); + wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); + + if (is_zero_ether_addr(addr)) { + /* We dont support TX only encryption */ + ret = -EOPNOTSUPP; + goto out; + } + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out_unlock; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out_unlock; + + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + key_type = KEY_WEP; + + key_conf->hw_key_idx = key_conf->keyidx; + break; + case WLAN_CIPHER_SUITE_TKIP: + key_type = KEY_TKIP; + + key_conf->hw_key_idx = key_conf->keyidx; + tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); + break; + case WLAN_CIPHER_SUITE_CCMP: + key_type = KEY_AES; + + key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); + break; + case WL1271_CIPHER_SUITE_GEM: + key_type = KEY_GEM; + tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); + break; + default: + wl1271_error("Unknown key algo 0x%x", key_conf->cipher); + + ret = -EOPNOTSUPP; + goto out_sleep; + } + + switch (cmd) { + case SET_KEY: + ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE, + key_conf->keyidx, key_type, + key_conf->keylen, key_conf->key, + addr, tx_seq_32, tx_seq_16); + if (ret < 0) { + wl1271_error("Could not add or replace key"); + goto out_sleep; + } + + /* the default WEP key needs to be configured at least once */ + if (key_type == KEY_WEP) { + ret = wl1271_cmd_set_default_wep_key(wl, + wl->default_key); + if (ret < 0) + goto out_sleep; + } + break; + + case DISABLE_KEY: + /* The wl1271 does not allow to remove unicast keys - they + will be cleared automatically on next CMD_JOIN. Ignore the + request silently, as we dont want the mac80211 to emit + an error message. */ + if (!is_broadcast_ether_addr(addr)) + break; + + ret = wl1271_cmd_set_key(wl, KEY_REMOVE, + key_conf->keyidx, key_type, + key_conf->keylen, key_conf->key, + addr, 0, 0); + if (ret < 0) { + wl1271_error("Could not remove key"); + goto out_sleep; + } + break; + + default: + wl1271_error("Unsupported key cmd 0x%x", cmd); + ret = -EOPNOTSUPP; + break; + } + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out_unlock: + mutex_unlock(&wl->mutex); + +out: + return ret; +} + +static int wl1271_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_scan_request *req) +{ + struct wl1271 *wl = hw->priv; + int ret; + u8 *ssid = NULL; + size_t len = 0; + + wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan"); + + if (req->n_ssids) { + ssid = req->ssids[0].ssid; + len = req->ssids[0].ssid_len; + } + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) { + /* + * We cannot return -EBUSY here because cfg80211 will expect + * a call to ieee80211_scan_completed if we do - in this case + * there won't be any call. + */ + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_scan(hw->priv, ssid, len, req); + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + struct wl1271 *wl = hw->priv; + int ret = 0; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_acx_rts_threshold(wl, (u16) value); + if (ret < 0) + wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret); + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) +{ + u8 *ptr = beacon->data + + offsetof(struct ieee80211_mgmt, u.beacon.variable); + + /* find the location of the ssid in the beacon */ + while (ptr < beacon->data + beacon->len) { + if (ptr[0] == WLAN_EID_SSID) { + wl->ssid_len = ptr[1]; + memcpy(wl->ssid, ptr+2, wl->ssid_len); + return; + } + ptr += ptr[1]; + } + wl1271_error("ad-hoc beacon template has no SSID!\n"); +} + +static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + enum wl1271_cmd_ps_mode mode; + struct wl1271 *wl = hw->priv; + struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); + bool do_join = false; + bool set_assoc = false; + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if ((changed & BSS_CHANGED_BEACON_INT) && + (wl->bss_type == BSS_TYPE_IBSS)) { + wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", + bss_conf->beacon_int); + + wl->beacon_int = bss_conf->beacon_int; + do_join = true; + } + + if ((changed & BSS_CHANGED_BEACON) && + (wl->bss_type == BSS_TYPE_IBSS)) { + struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); + + wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated"); + + if (beacon) { + struct ieee80211_hdr *hdr; + + wl1271_ssid_set(wl, beacon); + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, + beacon->data, + beacon->len, 0, + wl1271_min_rate_get(wl)); + + if (ret < 0) { + dev_kfree_skb(beacon); + goto out_sleep; + } + + hdr = (struct ieee80211_hdr *) beacon->data; + hdr->frame_control = cpu_to_le16( + IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_PROBE_RESP); + + ret = wl1271_cmd_template_set(wl, + CMD_TEMPL_PROBE_RESPONSE, + beacon->data, + beacon->len, 0, + wl1271_min_rate_get(wl)); + dev_kfree_skb(beacon); + if (ret < 0) + goto out_sleep; + + /* Need to update the SSID (for filtering etc) */ + do_join = true; + } + } + + if ((changed & BSS_CHANGED_BEACON_ENABLED) && + (wl->bss_type == BSS_TYPE_IBSS)) { + wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s", + bss_conf->enable_beacon ? "enabled" : "disabled"); + + if (bss_conf->enable_beacon) + wl->set_bss_type = BSS_TYPE_IBSS; + else + wl->set_bss_type = BSS_TYPE_STA_BSS; + do_join = true; + } + + if (changed & BSS_CHANGED_CQM) { + bool enable = false; + if (bss_conf->cqm_rssi_thold) + enable = true; + ret = wl1271_acx_rssi_snr_trigger(wl, enable, + bss_conf->cqm_rssi_thold, + bss_conf->cqm_rssi_hyst); + if (ret < 0) + goto out; + wl->rssi_thold = bss_conf->cqm_rssi_thold; + } + + if ((changed & BSS_CHANGED_BSSID) && + /* + * Now we know the correct bssid, so we send a new join command + * and enable the BSSID filter + */ + memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { + memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); + + ret = wl1271_cmd_build_null_data(wl); + if (ret < 0) + goto out_sleep; + + ret = wl1271_build_qos_null_data(wl); + if (ret < 0) + goto out_sleep; + + /* filter out all packets not from this BSSID */ + wl1271_configure_filters(wl, 0); + + /* Need to update the BSSID (for filtering etc) */ + do_join = true; + } + + if (changed & BSS_CHANGED_ASSOC) { + if (bss_conf->assoc) { + u32 rates; + wl->aid = bss_conf->aid; + set_assoc = true; + + wl->ps_poll_failures = 0; + + /* + * use basic rates from AP, and determine lowest rate + * to use with control frames. + */ + rates = bss_conf->basic_rates; + wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, + rates); + wl->basic_rate = wl1271_min_rate_get(wl); + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + goto out_sleep; + + /* + * with wl1271, we don't need to update the + * beacon_int and dtim_period, because the firmware + * updates it by itself when the first beacon is + * received after a join. + */ + ret = wl1271_cmd_build_ps_poll(wl, wl->aid); + if (ret < 0) + goto out_sleep; + + /* + * The SSID is intentionally set to NULL here - the + * firmware will set the probe request with a + * broadcast SSID regardless of what we set in the + * template. + */ + ret = wl1271_cmd_build_probe_req(wl, NULL, 0, + NULL, 0, wl->band); + + /* enable the connection monitoring feature */ + ret = wl1271_acx_conn_monit_params(wl, true); + if (ret < 0) + goto out_sleep; + + /* If we want to go in PSM but we're not there yet */ + if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && + !test_bit(WL1271_FLAG_PSM, &wl->flags)) { + mode = STATION_POWER_SAVE_MODE; + ret = wl1271_ps_set_mode(wl, mode, + wl->basic_rate, + true); + if (ret < 0) + goto out_sleep; + } + } else { + /* use defaults when not associated */ + clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags); + clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); + wl->aid = 0; + + /* re-enable dynamic ps - just in case */ + ieee80211_enable_dyn_ps(wl->vif); + + /* revert back to minimum rates for the current band */ + wl1271_set_band_rate(wl); + wl->basic_rate = wl1271_min_rate_get(wl); + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + goto out_sleep; + + /* disable connection monitor features */ + ret = wl1271_acx_conn_monit_params(wl, false); + + /* Disable the keep-alive feature */ + ret = wl1271_acx_keep_alive_mode(wl, false); + + if (ret < 0) + goto out_sleep; + } + + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + if (bss_conf->use_short_slot) + ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT); + else + ret = wl1271_acx_slot(wl, SLOT_TIME_LONG); + if (ret < 0) { + wl1271_warning("Set slot time failed %d", ret); + goto out_sleep; + } + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + if (bss_conf->use_short_preamble) + wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); + else + wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG); + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + if (bss_conf->use_cts_prot) + ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE); + else + ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE); + if (ret < 0) { + wl1271_warning("Set ctsprotect failed %d", ret); + goto out_sleep; + } + } + + /* + * Takes care of: New association with HT enable, + * HT information change in beacon. + */ + if (sta && + (changed & BSS_CHANGED_HT) && + (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); + if (ret < 0) { + wl1271_warning("Set ht cap true failed %d", ret); + goto out_sleep; + } + ret = wl1271_acx_set_ht_information(wl, + bss_conf->ht_operation_mode); + if (ret < 0) { + wl1271_warning("Set ht information failed %d", ret); + goto out_sleep; + } + } + /* + * Takes care of: New association without HT, + * Disassociation. + */ + else if (sta && (changed & BSS_CHANGED_ASSOC)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); + if (ret < 0) { + wl1271_warning("Set ht cap false failed %d", ret); + goto out_sleep; + } + } + + if (changed & BSS_CHANGED_ARP_FILTER) { + __be32 addr = bss_conf->arp_addr_list[0]; + WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); + + if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled) + ret = wl1271_acx_arp_ip_filter(wl, true, addr); + else + ret = wl1271_acx_arp_ip_filter(wl, false, addr); + + if (ret < 0) + goto out_sleep; + } + + if (do_join) { + ret = wl1271_join(wl, set_assoc); + if (ret < 0) { + wl1271_warning("cmd join failed %d", ret); + goto out_sleep; + } + } + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct wl1271 *wl = hw->priv; + u8 ps_scheme; + int ret; + + mutex_lock(&wl->mutex); + + wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + /* the txop is confed in units of 32us by the mac80211, we need us */ + ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), + params->cw_min, params->cw_max, + params->aifs, params->txop << 5); + if (ret < 0) + goto out_sleep; + + if (params->uapsd) + ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER; + else + ps_scheme = CONF_PS_SCHEME_LEGACY; + + ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), + CONF_CHANNEL_TYPE_EDCF, + wl1271_tx_get_queue(queue), + ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) +{ + + struct wl1271 *wl = hw->priv; + u64 mactime = ULLONG_MAX; + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf"); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_acx_tsf_info(wl, &mactime); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return mactime; +} + +static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct wl1271 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = wl->noise; + + return 0; +} + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_rate wl1271_rates[] = { + { .bitrate = 10, + .hw_value = CONF_HW_BIT_RATE_1MBPS, + .hw_value_short = CONF_HW_BIT_RATE_1MBPS, }, + { .bitrate = 20, + .hw_value = CONF_HW_BIT_RATE_2MBPS, + .hw_value_short = CONF_HW_BIT_RATE_2MBPS, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 55, + .hw_value = CONF_HW_BIT_RATE_5_5MBPS, + .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 110, + .hw_value = CONF_HW_BIT_RATE_11MBPS, + .hw_value_short = CONF_HW_BIT_RATE_11MBPS, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 60, + .hw_value = CONF_HW_BIT_RATE_6MBPS, + .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, + { .bitrate = 90, + .hw_value = CONF_HW_BIT_RATE_9MBPS, + .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, + { .bitrate = 120, + .hw_value = CONF_HW_BIT_RATE_12MBPS, + .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, + { .bitrate = 180, + .hw_value = CONF_HW_BIT_RATE_18MBPS, + .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, + { .bitrate = 240, + .hw_value = CONF_HW_BIT_RATE_24MBPS, + .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, + { .bitrate = 360, + .hw_value = CONF_HW_BIT_RATE_36MBPS, + .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, + { .bitrate = 480, + .hw_value = CONF_HW_BIT_RATE_48MBPS, + .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, + { .bitrate = 540, + .hw_value = CONF_HW_BIT_RATE_54MBPS, + .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, +}; + +/* + * Can't be const, mac80211 writes to this. The order of the channels here + * is designed to improve scanning. + */ +static struct ieee80211_channel wl1271_channels[] = { + { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, + { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, + { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, + { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, + { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, + { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, + { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, + { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, + { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, + { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, + { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, + { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, + { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, +}; + +/* mapping to indexes for wl1271_rates */ +static const u8 wl1271_rate_to_idx_2ghz[] = { + /* MCS rates are used only with 11n */ + 7, /* CONF_HW_RXTX_RATE_MCS7 */ + 6, /* CONF_HW_RXTX_RATE_MCS6 */ + 5, /* CONF_HW_RXTX_RATE_MCS5 */ + 4, /* CONF_HW_RXTX_RATE_MCS4 */ + 3, /* CONF_HW_RXTX_RATE_MCS3 */ + 2, /* CONF_HW_RXTX_RATE_MCS2 */ + 1, /* CONF_HW_RXTX_RATE_MCS1 */ + 0, /* CONF_HW_RXTX_RATE_MCS0 */ + + 11, /* CONF_HW_RXTX_RATE_54 */ + 10, /* CONF_HW_RXTX_RATE_48 */ + 9, /* CONF_HW_RXTX_RATE_36 */ + 8, /* CONF_HW_RXTX_RATE_24 */ + + /* TI-specific rate */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ + + 7, /* CONF_HW_RXTX_RATE_18 */ + 6, /* CONF_HW_RXTX_RATE_12 */ + 3, /* CONF_HW_RXTX_RATE_11 */ + 5, /* CONF_HW_RXTX_RATE_9 */ + 4, /* CONF_HW_RXTX_RATE_6 */ + 2, /* CONF_HW_RXTX_RATE_5_5 */ + 1, /* CONF_HW_RXTX_RATE_2 */ + 0 /* CONF_HW_RXTX_RATE_1 */ +}; + +/* 11n STA capabilities */ +#define HW_RX_HIGHEST_RATE 72 + +#ifdef CONFIG_WL12XX_HT +#define WL12XX_HT_CAP { \ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ + .ht_supported = true, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ + .mcs = { \ + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ + .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ + }, \ +} +#else +#define WL12XX_HT_CAP { \ + .ht_supported = false, \ +} +#endif + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_supported_band wl1271_band_2ghz = { + .channels = wl1271_channels, + .n_channels = ARRAY_SIZE(wl1271_channels), + .bitrates = wl1271_rates, + .n_bitrates = ARRAY_SIZE(wl1271_rates), + .ht_cap = WL12XX_HT_CAP, +}; + +/* 5 GHz data rates for WL1273 */ +static struct ieee80211_rate wl1271_rates_5ghz[] = { + { .bitrate = 60, + .hw_value = CONF_HW_BIT_RATE_6MBPS, + .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, + { .bitrate = 90, + .hw_value = CONF_HW_BIT_RATE_9MBPS, + .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, + { .bitrate = 120, + .hw_value = CONF_HW_BIT_RATE_12MBPS, + .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, + { .bitrate = 180, + .hw_value = CONF_HW_BIT_RATE_18MBPS, + .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, + { .bitrate = 240, + .hw_value = CONF_HW_BIT_RATE_24MBPS, + .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, + { .bitrate = 360, + .hw_value = CONF_HW_BIT_RATE_36MBPS, + .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, + { .bitrate = 480, + .hw_value = CONF_HW_BIT_RATE_48MBPS, + .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, + { .bitrate = 540, + .hw_value = CONF_HW_BIT_RATE_54MBPS, + .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, +}; + +/* + * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this. + * The order of the channels here is designed to improve scanning. + */ +static struct ieee80211_channel wl1271_channels_5ghz[] = { + { .hw_value = 183, .center_freq = 4915}, + { .hw_value = 188, .center_freq = 4940}, + { .hw_value = 8, .center_freq = 5040}, + { .hw_value = 34, .center_freq = 5170}, + { .hw_value = 44, .center_freq = 5220}, + { .hw_value = 60, .center_freq = 5300}, + { .hw_value = 112, .center_freq = 5560}, + { .hw_value = 132, .center_freq = 5660}, + { .hw_value = 157, .center_freq = 5785}, + { .hw_value = 184, .center_freq = 4920}, + { .hw_value = 189, .center_freq = 4945}, + { .hw_value = 9, .center_freq = 5045}, + { .hw_value = 36, .center_freq = 5180}, + { .hw_value = 46, .center_freq = 5230}, + { .hw_value = 64, .center_freq = 5320}, + { .hw_value = 116, .center_freq = 5580}, + { .hw_value = 136, .center_freq = 5680}, + { .hw_value = 192, .center_freq = 4960}, + { .hw_value = 11, .center_freq = 5055}, + { .hw_value = 38, .center_freq = 5190}, + { .hw_value = 48, .center_freq = 5240}, + { .hw_value = 100, .center_freq = 5500}, + { .hw_value = 120, .center_freq = 5600}, + { .hw_value = 140, .center_freq = 5700}, + { .hw_value = 185, .center_freq = 4925}, + { .hw_value = 196, .center_freq = 4980}, + { .hw_value = 12, .center_freq = 5060}, + { .hw_value = 40, .center_freq = 5200}, + { .hw_value = 52, .center_freq = 5260}, + { .hw_value = 104, .center_freq = 5520}, + { .hw_value = 124, .center_freq = 5620}, + { .hw_value = 149, .center_freq = 5745}, + { .hw_value = 161, .center_freq = 5805}, + { .hw_value = 187, .center_freq = 4935}, + { .hw_value = 7, .center_freq = 5035}, + { .hw_value = 16, .center_freq = 5080}, + { .hw_value = 42, .center_freq = 5210}, + { .hw_value = 56, .center_freq = 5280}, + { .hw_value = 108, .center_freq = 5540}, + { .hw_value = 128, .center_freq = 5640}, + { .hw_value = 153, .center_freq = 5765}, + { .hw_value = 165, .center_freq = 5825}, +}; + +/* mapping to indexes for wl1271_rates_5ghz */ +static const u8 wl1271_rate_to_idx_5ghz[] = { + /* MCS rates are used only with 11n */ + 7, /* CONF_HW_RXTX_RATE_MCS7 */ + 6, /* CONF_HW_RXTX_RATE_MCS6 */ + 5, /* CONF_HW_RXTX_RATE_MCS5 */ + 4, /* CONF_HW_RXTX_RATE_MCS4 */ + 3, /* CONF_HW_RXTX_RATE_MCS3 */ + 2, /* CONF_HW_RXTX_RATE_MCS2 */ + 1, /* CONF_HW_RXTX_RATE_MCS1 */ + 0, /* CONF_HW_RXTX_RATE_MCS0 */ + + 7, /* CONF_HW_RXTX_RATE_54 */ + 6, /* CONF_HW_RXTX_RATE_48 */ + 5, /* CONF_HW_RXTX_RATE_36 */ + 4, /* CONF_HW_RXTX_RATE_24 */ + + /* TI-specific rate */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ + + 3, /* CONF_HW_RXTX_RATE_18 */ + 2, /* CONF_HW_RXTX_RATE_12 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */ + 1, /* CONF_HW_RXTX_RATE_9 */ + 0, /* CONF_HW_RXTX_RATE_6 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */ + CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */ +}; + +static struct ieee80211_supported_band wl1271_band_5ghz = { + .channels = wl1271_channels_5ghz, + .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), + .bitrates = wl1271_rates_5ghz, + .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), + .ht_cap = WL12XX_HT_CAP, +}; + +static const u8 *wl1271_band_rate_to_idx[] = { + [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz, + [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz +}; + +static const struct ieee80211_ops wl1271_ops = { + .start = wl1271_op_start, + .stop = wl1271_op_stop, + .add_interface = wl1271_op_add_interface, + .remove_interface = wl1271_op_remove_interface, + .config = wl1271_op_config, + .prepare_multicast = wl1271_op_prepare_multicast, + .configure_filter = wl1271_op_configure_filter, + .tx = wl1271_op_tx, + .set_key = wl1271_op_set_key, + .hw_scan = wl1271_op_hw_scan, + .bss_info_changed = wl1271_op_bss_info_changed, + .set_rts_threshold = wl1271_op_set_rts_threshold, + .conf_tx = wl1271_op_conf_tx, + .get_tsf = wl1271_op_get_tsf, + .get_survey = wl1271_op_get_survey, + CFG80211_TESTMODE_CMD(wl1271_tm_cmd) +}; + + +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) +{ + u8 idx; + + BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); + + if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { + wl1271_error("Illegal RX rate from HW: %d", rate); + return 0; + } + + idx = wl1271_band_rate_to_idx[band][rate]; + if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { + wl1271_error("Unsupported RX rate from HW: %d", rate); + return 0; + } + + return idx; +} + +static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wl1271 *wl = dev_get_drvdata(dev); + ssize_t len; + + len = PAGE_SIZE; + + mutex_lock(&wl->mutex); + len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", + wl->sg_enabled); + mutex_unlock(&wl->mutex); + + return len; + +} + +static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct wl1271 *wl = dev_get_drvdata(dev); + unsigned long res; + int ret; + + ret = strict_strtoul(buf, 10, &res); + + if (ret < 0) { + wl1271_warning("incorrect value written to bt_coex_mode"); + return count; + } + + mutex_lock(&wl->mutex); + + res = !!res; + + if (res == wl->sg_enabled) + goto out; + + wl->sg_enabled = res; + + if (wl->state == WL1271_STATE_OFF) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + wl1271_acx_sg_enable(wl, wl->sg_enabled); + wl1271_ps_elp_sleep(wl); + + out: + mutex_unlock(&wl->mutex); + return count; +} + +static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, + wl1271_sysfs_show_bt_coex_state, + wl1271_sysfs_store_bt_coex_state); + +static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wl1271 *wl = dev_get_drvdata(dev); + ssize_t len; + + len = PAGE_SIZE; + + mutex_lock(&wl->mutex); + if (wl->hw_pg_ver >= 0) + len = snprintf(buf, len, "%d\n", wl->hw_pg_ver); + else + len = snprintf(buf, len, "n/a\n"); + mutex_unlock(&wl->mutex); + + return len; +} + +static DEVICE_ATTR(hw_pg_ver, S_IRUGO | S_IWUSR, + wl1271_sysfs_show_hw_pg_ver, NULL); + +int wl1271_register_hw(struct wl1271 *wl) +{ + int ret; + + if (wl->mac80211_registered) + return 0; + + SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); + + ret = ieee80211_register_hw(wl->hw); + if (ret < 0) { + wl1271_error("unable to register mac80211 hw: %d", ret); + return ret; + } + + wl->mac80211_registered = true; + + register_netdevice_notifier(&wl1271_dev_notifier); + + wl1271_notice("loaded"); + + return 0; +} +EXPORT_SYMBOL_GPL(wl1271_register_hw); + +void wl1271_unregister_hw(struct wl1271 *wl) +{ + unregister_netdevice_notifier(&wl1271_dev_notifier); + ieee80211_unregister_hw(wl->hw); + wl->mac80211_registered = false; + +} +EXPORT_SYMBOL_GPL(wl1271_unregister_hw); + +int wl1271_init_ieee80211(struct wl1271 *wl) +{ + static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + WL1271_CIPHER_SUITE_GEM, + }; + + /* The tx descriptor buffer and the TKIP space. */ + wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + + sizeof(struct wl1271_tx_hw_descr); + + /* unit us */ + /* FIXME: find a proper value */ + wl->hw->channel_change_time = 10000; + wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; + + wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_BEACON_FILTER | + IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_UAPSD | + IEEE80211_HW_HAS_RATE_CONTROL | + IEEE80211_HW_CONNECTION_MONITOR | + IEEE80211_HW_SUPPORTS_CQM_RSSI; + + wl->hw->wiphy->cipher_suites = cipher_suites; + wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + + wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + wl->hw->wiphy->max_scan_ssids = 1; + wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; + wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; + + wl->hw->queues = 4; + wl->hw->max_rates = 1; + + SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); + + return 0; +} +EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); + +#define WL1271_DEFAULT_CHANNEL 0 + +struct ieee80211_hw *wl1271_alloc_hw(void) +{ + struct ieee80211_hw *hw; + struct platform_device *plat_dev = NULL; + struct wl1271 *wl; + int i, ret; + unsigned int order; + + hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); + if (!hw) { + wl1271_error("could not alloc ieee80211_hw"); + ret = -ENOMEM; + goto err_hw_alloc; + } + + plat_dev = kmemdup(&wl1271_device, sizeof(wl1271_device), GFP_KERNEL); + if (!plat_dev) { + wl1271_error("could not allocate platform_device"); + ret = -ENOMEM; + goto err_plat_alloc; + } + + wl = hw->priv; + memset(wl, 0, sizeof(*wl)); + + INIT_LIST_HEAD(&wl->list); + + wl->hw = hw; + wl->plat_dev = plat_dev; + + skb_queue_head_init(&wl->tx_queue); + + INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); + INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); + INIT_WORK(&wl->irq_work, wl1271_irq_work); + INIT_WORK(&wl->tx_work, wl1271_tx_work); + INIT_WORK(&wl->recovery_work, wl1271_recovery_work); + INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + wl->channel = WL1271_DEFAULT_CHANNEL; + wl->beacon_int = WL1271_DEFAULT_BEACON_INT; + wl->default_key = 0; + wl->rx_counter = 0; + wl->rx_config = WL1271_DEFAULT_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + wl->psm_entry_retry = 0; + wl->power_level = WL1271_DEFAULT_POWER_LEVEL; + wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; + wl->basic_rate = CONF_TX_RATE_MASK_BASIC; + wl->rate_set = CONF_TX_RATE_MASK_BASIC; + wl->sta_rate_set = 0; + wl->band = IEEE80211_BAND_2GHZ; + wl->vif = NULL; + wl->flags = 0; + wl->sg_enabled = true; + wl->hw_pg_ver = -1; + + memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); + for (i = 0; i < ACX_TX_DESCRIPTORS; i++) + wl->tx_frames[i] = NULL; + + spin_lock_init(&wl->wl_lock); + + wl->state = WL1271_STATE_OFF; + mutex_init(&wl->mutex); + + /* Apply default driver configuration. */ + wl1271_conf_init(wl); + + wl1271_debugfs_init(wl); + + order = get_order(WL1271_AGGR_BUFFER_SIZE); + wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); + if (!wl->aggr_buf) { + ret = -ENOMEM; + goto err_hw; + } + + /* Register platform device */ + ret = platform_device_register(wl->plat_dev); + if (ret) { + wl1271_error("couldn't register platform device"); + goto err_aggr; + } + dev_set_drvdata(&wl->plat_dev->dev, wl); + + /* Create sysfs file to control bt coex state */ + ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); + if (ret < 0) { + wl1271_error("failed to create sysfs file bt_coex_state"); + goto err_platform; + } + + /* Create sysfs file to get HW PG version */ + ret = device_create_file(&wl->plat_dev->dev, &dev_attr_hw_pg_ver); + if (ret < 0) { + wl1271_error("failed to create sysfs file hw_pg_ver"); + goto err_bt_coex_state; + } + + return hw; + +err_bt_coex_state: + device_remove_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); + +err_platform: + platform_device_unregister(wl->plat_dev); + +err_aggr: + free_pages((unsigned long)wl->aggr_buf, order); + +err_hw: + wl1271_debugfs_exit(wl); + kfree(plat_dev); + +err_plat_alloc: + ieee80211_free_hw(hw); + +err_hw_alloc: + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(wl1271_alloc_hw); + +int wl1271_free_hw(struct wl1271 *wl) +{ + platform_device_unregister(wl->plat_dev); + free_pages((unsigned long)wl->aggr_buf, + get_order(WL1271_AGGR_BUFFER_SIZE)); + kfree(wl->plat_dev); + + wl1271_debugfs_exit(wl); + + vfree(wl->fw); + wl->fw = NULL; + kfree(wl->nvs); + wl->nvs = NULL; + + kfree(wl->fw_status); + kfree(wl->tx_res_if); + + ieee80211_free_hw(wl->hw); + + return 0; +} +EXPORT_SYMBOL_GPL(wl1271_free_hw); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Luciano Coelho "); +MODULE_AUTHOR("Juuso Oikarinen "); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c new file mode 100644 index 000000000000..60a3738eadb0 --- /dev/null +++ b/drivers/net/wireless/wl12xx/ps.c @@ -0,0 +1,178 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "reg.h" +#include "ps.h" +#include "io.h" + +#define WL1271_WAKEUP_TIMEOUT 500 + +void wl1271_elp_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, elp_work); + + wl1271_debug(DEBUG_PSM, "elp work"); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || + (!test_bit(WL1271_FLAG_PSM, &wl->flags) && + !test_bit(WL1271_FLAG_IDLE, &wl->flags))) + goto out; + + wl1271_debug(DEBUG_PSM, "chip to elp"); + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); + set_bit(WL1271_FLAG_IN_ELP, &wl->flags); + +out: + mutex_unlock(&wl->mutex); +} + +#define ELP_ENTRY_DELAY 5 + +/* Routines to toggle sleep mode while in ELP */ +void wl1271_ps_elp_sleep(struct wl1271 *wl) +{ + if (test_bit(WL1271_FLAG_PSM, &wl->flags) || + test_bit(WL1271_FLAG_IDLE, &wl->flags)) { + cancel_delayed_work(&wl->elp_work); + ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, + msecs_to_jiffies(ELP_ENTRY_DELAY)); + } +} + +int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) +{ + DECLARE_COMPLETION_ONSTACK(compl); + unsigned long flags; + int ret; + u32 start_time = jiffies; + bool pending = false; + + if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) + return 0; + + wl1271_debug(DEBUG_PSM, "waking up chip from elp"); + + /* + * The spinlock is required here to synchronize both the work and + * the completion variable in one entity. + */ + spin_lock_irqsave(&wl->wl_lock, flags); + if (work_pending(&wl->irq_work) || chip_awake) + pending = true; + else + wl->elp_compl = &compl; + spin_unlock_irqrestore(&wl->wl_lock, flags); + + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); + + if (!pending) { + ret = wait_for_completion_timeout( + &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); + if (ret == 0) { + wl1271_error("ELP wakeup timeout!"); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + ret = -ETIMEDOUT; + goto err; + } else if (ret < 0) { + wl1271_error("ELP wakeup completion error."); + goto err; + } + } + + clear_bit(WL1271_FLAG_IN_ELP, &wl->flags); + + wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", + jiffies_to_msecs(jiffies - start_time)); + goto out; + +err: + spin_lock_irqsave(&wl->wl_lock, flags); + wl->elp_compl = NULL; + spin_unlock_irqrestore(&wl->wl_lock, flags); + return ret; + +out: + return 0; +} + +int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, + u32 rates, bool send) +{ + int ret; + + switch (mode) { + case STATION_POWER_SAVE_MODE: + wl1271_debug(DEBUG_PSM, "entering psm"); + + ret = wl1271_acx_wake_up_conditions(wl); + if (ret < 0) { + wl1271_error("couldn't set wake up conditions"); + return ret; + } + + ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, + rates, send); + if (ret < 0) + return ret; + + set_bit(WL1271_FLAG_PSM, &wl->flags); + break; + case STATION_ACTIVE_MODE: + default: + wl1271_debug(DEBUG_PSM, "leaving psm"); + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + return ret; + + /* disable beacon early termination */ + ret = wl1271_acx_bet_enable(wl, false); + if (ret < 0) + return ret; + + /* disable beacon filtering */ + ret = wl1271_acx_beacon_filter_opt(wl, false); + if (ret < 0) + return ret; + + ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, + rates, send); + if (ret < 0) + return ret; + + clear_bit(WL1271_FLAG_PSM, &wl->flags); + break; + } + + return ret; +} + + diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h new file mode 100644 index 000000000000..8415060f08e5 --- /dev/null +++ b/drivers/net/wireless/wl12xx/ps.h @@ -0,0 +1,36 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __PS_H__ +#define __PS_H__ + +#include "wl12xx.h" +#include "acx.h" + +int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, + u32 rates, bool send); +void wl1271_ps_elp_sleep(struct wl1271 *wl); +int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); +void wl1271_elp_work(struct work_struct *work); + +#endif /* __WL1271_PS_H__ */ diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h new file mode 100644 index 000000000000..990960771528 --- /dev/null +++ b/drivers/net/wireless/wl12xx/reg.h @@ -0,0 +1,614 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __REG_H__ +#define __REG_H__ + +#include + +#define REGISTERS_BASE 0x00300000 +#define DRPW_BASE 0x00310000 + +#define REGISTERS_DOWN_SIZE 0x00008800 +#define REGISTERS_WORK_SIZE 0x0000b000 + +#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC +#define FW_STATUS_ADDR (0x14FC0 + 0xA000) + +/* ELP register commands */ +#define ELPCTRL_WAKE_UP 0x1 +#define ELPCTRL_WAKE_UP_WLAN_READY 0x5 +#define ELPCTRL_SLEEP 0x0 +/* ELP WLAN_READY bit */ +#define ELPCTRL_WLAN_READY 0x2 + +/*=============================================== + Host Software Reset - 32bit RW + ------------------------------------------ + [31:1] Reserved + 0 SOFT_RESET Soft Reset - When this bit is set, + it holds the Wlan hardware in a soft reset state. + This reset disables all MAC and baseband processor + clocks except the CardBus/PCI interface clock. + It also initializes all MAC state machines except + the host interface. It does not reload the + contents of the EEPROM. When this bit is cleared + (not self-clearing), the Wlan hardware + exits the software reset state. +===============================================*/ +#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000) + +#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) +#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) +#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) + +#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) +#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) + +/*============================================= + Host Interrupt Mask Register - 32bit (RW) + ------------------------------------------ + Setting a bit in this register masks the + corresponding interrupt to the host. + 0 - RX0 - Rx first dubble buffer Data Interrupt + 1 - TXD - Tx Data Interrupt + 2 - TXXFR - Tx Transfer Interrupt + 3 - RX1 - Rx second dubble buffer Data Interrupt + 4 - RXXFR - Rx Transfer Interrupt + 5 - EVENT_A - Event Mailbox interrupt + 6 - EVENT_B - Event Mailbox interrupt + 7 - WNONHST - Wake On Host Interrupt + 8 - TRACE_A - Debug Trace interrupt + 9 - TRACE_B - Debug Trace interrupt + 10 - CDCMP - Command Complete Interrupt + 11 - + 12 - + 13 - + 14 - ICOMP - Initialization Complete Interrupt + 16 - SG SE - Soft Gemini - Sense enable interrupt + 17 - SG SD - Soft Gemini - Sense disable interrupt + 18 - - + 19 - - + 20 - - + 21- - + Default: 0x0001 +*==============================================*/ +#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC) + +/*============================================= + Host Interrupt Mask Set 16bit, (Write only) + ------------------------------------------ + Setting a bit in this register sets + the corresponding bin in ACX_HINT_MASK register + without effecting the mask + state of other bits (0 = no effect). +==============================================*/ +#define ACX_REG_HINT_MASK_SET (REGISTERS_BASE + 0x04E0) + +/*============================================= + Host Interrupt Mask Clear 16bit,(Write only) + ------------------------------------------ + Setting a bit in this register clears + the corresponding bin in ACX_HINT_MASK register + without effecting the mask + state of other bits (0 = no effect). +=============================================*/ +#define ACX_REG_HINT_MASK_CLR (REGISTERS_BASE + 0x04E4) + +/*============================================= + Host Interrupt Status Nondestructive Read + 16bit,(Read only) + ------------------------------------------ + The host can read this register to determine + which interrupts are active. + Reading this register doesn't + effect its content. +=============================================*/ +#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8) + +/*============================================= + Host Interrupt Status Clear on Read Register + 16bit,(Read only) + ------------------------------------------ + The host can read this register to determine + which interrupts are active. + Reading this register clears it, + thus making all interrupts inactive. +==============================================*/ +#define ACX_REG_INTERRUPT_CLEAR (REGISTERS_BASE + 0x04F8) + +/*============================================= + Host Interrupt Acknowledge Register + 16bit,(Write only) + ------------------------------------------ + The host can set individual bits in this + register to clear (acknowledge) the corresp. + interrupt status bits in the HINT_STS_CLR and + HINT_STS_ND registers, thus making the + assotiated interrupt inactive. (0-no effect) +==============================================*/ +#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0) + +#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538) + +/* Device Configuration registers*/ +#define SOR_CFG (REGISTERS_BASE + 0x0800) + +/* Embedded ARM CPU Control */ + +/*=============================================== + Halt eCPU - 32bit RW + ------------------------------------------ + 0 HALT_ECPU Halt Embedded CPU - This bit is the + compliment of bit 1 (MDATA2) in the SOR_CFG register. + During a hardware reset, this bit holds + the inverse of MDATA2. + When downloading firmware from the host, + set this bit (pull down MDATA2). + The host clears this bit after downloading the firmware into + zero-wait-state SSRAM. + When loading firmware from Flash, clear this bit (pull up MDATA2) + so that the eCPU can run the bootloader code in Flash + HALT_ECPU eCPU State + -------------------- + 1 halt eCPU + 0 enable eCPU + ===============================================*/ +#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804) + +#define HI_CFG (REGISTERS_BASE + 0x0808) + +/*=============================================== + EEPROM Burst Read Start - 32bit RW + ------------------------------------------ + [31:1] Reserved + 0 ACX_EE_START - EEPROM Burst Read Start 0 + Setting this bit starts a burst read from + the external EEPROM. + If this bit is set (after reset) before an EEPROM read/write, + the burst read starts at EEPROM address 0. + Otherwise, it starts at the address + following the address of the previous access. + TheWlan hardware hardware clears this bit automatically. + + Default: 0x00000000 +*================================================*/ +#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C) + +#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4) +#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8) +#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC) +#define OCP_CMD (REGISTERS_BASE + 0x09C0) + +#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8) + +#define CHIP_ID_B (REGISTERS_BASE + 0x5674) + +#define CHIP_ID_1271_PG10 (0x4030101) +#define CHIP_ID_1271_PG20 (0x4030111) + +#define ENABLE (REGISTERS_BASE + 0x5450) + +/* Power Management registers */ +#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) +#define ELP_CMD (REGISTERS_BASE + 0x5808) +#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) +#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) +#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) + +#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) + +/* Scratch Pad registers*/ +#define SCR_PAD0 (REGISTERS_BASE + 0x5608) +#define SCR_PAD1 (REGISTERS_BASE + 0x560C) +#define SCR_PAD2 (REGISTERS_BASE + 0x5610) +#define SCR_PAD3 (REGISTERS_BASE + 0x5614) +#define SCR_PAD4 (REGISTERS_BASE + 0x5618) +#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) +#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) +#define SCR_PAD5 (REGISTERS_BASE + 0x5624) +#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) +#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) +#define SCR_PAD6 (REGISTERS_BASE + 0x5630) +#define SCR_PAD7 (REGISTERS_BASE + 0x5634) +#define SCR_PAD8 (REGISTERS_BASE + 0x5638) +#define SCR_PAD9 (REGISTERS_BASE + 0x563C) + +/* Spare registers*/ +#define SPARE_A1 (REGISTERS_BASE + 0x0994) +#define SPARE_A2 (REGISTERS_BASE + 0x0998) +#define SPARE_A3 (REGISTERS_BASE + 0x099C) +#define SPARE_A4 (REGISTERS_BASE + 0x09A0) +#define SPARE_A5 (REGISTERS_BASE + 0x09A4) +#define SPARE_A6 (REGISTERS_BASE + 0x09A8) +#define SPARE_A7 (REGISTERS_BASE + 0x09AC) +#define SPARE_A8 (REGISTERS_BASE + 0x09B0) +#define SPARE_B1 (REGISTERS_BASE + 0x5420) +#define SPARE_B2 (REGISTERS_BASE + 0x5424) +#define SPARE_B3 (REGISTERS_BASE + 0x5428) +#define SPARE_B4 (REGISTERS_BASE + 0x542C) +#define SPARE_B5 (REGISTERS_BASE + 0x5430) +#define SPARE_B6 (REGISTERS_BASE + 0x5434) +#define SPARE_B7 (REGISTERS_BASE + 0x5438) +#define SPARE_B8 (REGISTERS_BASE + 0x543C) + +#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040) +#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008) +#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100) +#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C) + + +#define ACX_SLV_SOFT_RESET_BIT BIT(1) +#define ACX_REG_EEPROM_START_BIT BIT(1) + +/* Command/Information Mailbox Pointers */ + +/*=============================================== + Command Mailbox Pointer - 32bit RW + ------------------------------------------ + This register holds the start address of + the command mailbox located in the Wlan hardware memory. + The host must read this pointer after a reset to + find the location of the command mailbox. + The Wlan hardware initializes the command mailbox + pointer with the default address of the command mailbox. + The command mailbox pointer is not valid until after + the host receives the Init Complete interrupt from + the Wlan hardware. + ===============================================*/ +#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) + +/*=============================================== + Information Mailbox Pointer - 32bit RW + ------------------------------------------ + This register holds the start address of + the information mailbox located in the Wlan hardware memory. + The host must read this pointer after a reset to find + the location of the information mailbox. + The Wlan hardware initializes the information mailbox pointer + with the default address of the information mailbox. + The information mailbox pointer is not valid + until after the host receives the Init Complete interrupt from + the Wlan hardware. + ===============================================*/ +#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) + + +/* Misc */ + +#define REG_ENABLE_TX_RX (ENABLE) +/* + * Rx configuration (filter) information element + * --------------------------------------------- + */ +#define REG_RX_CONFIG (RX_CFG) +#define REG_RX_FILTER (RX_FILTER_CFG) + + +#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002 + +/* promiscuous - receives all valid frames */ +#define RX_CFG_PROMISCUOUS 0x0008 + +/* receives frames from any BSSID */ +#define RX_CFG_BSSID 0x0020 + +/* receives frames destined to any MAC address */ +#define RX_CFG_MAC 0x0010 + +#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010 +#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000 +#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020 +#define RX_CFG_ENABLE_ANY_BSSID 0x0000 + +/* discards all broadcast frames */ +#define RX_CFG_DISABLE_BCAST 0x0200 + +#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400 +#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800 +#define RX_CFG_COPY_RX_STATUS 0x2000 +#define RX_CFG_TSF 0x10000 + +#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ + RX_CFG_ENABLE_ONLY_MY_BSSID) + +#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ + | RX_CFG_ENABLE_ANY_BSSID) + +#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ + RX_CFG_ENABLE_ANY_BSSID) + +#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ + | RX_CFG_ENABLE_ONLY_MY_BSSID) + +#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \ + | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \ + | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF) + +#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC) + +#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \ + RX_CFG_ENABLE_ONLY_MY_DEST_MAC) + +#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \ + RX_CFG_ENABLE_ONLY_MY_DEST_MAC) + +#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ + | CFG_RX_CTL_EN | CFG_RX_BCN_EN\ + | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) + +#define RX_FILTER_OPTION_FILTER_ALL 0 + +#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\ + | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN) + +#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ + | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\ + | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\ + | CFG_RX_PRSP_EN) + + +/*=============================================== + EEPROM Read/Write Request 32bit RW + ------------------------------------------ + 1 EE_READ - EEPROM Read Request 1 - Setting this bit + loads a single byte of data into the EE_DATA + register from the EEPROM location specified in + the EE_ADDR register. + The Wlan hardware hardware clears this bit automatically. + EE_DATA is valid when this bit is cleared. + + 0 EE_WRITE - EEPROM Write Request - Setting this bit + writes a single byte of data from the EE_DATA register into the + EEPROM location specified in the EE_ADDR register. + The Wlan hardware hardware clears this bit automatically. +*===============================================*/ +#define ACX_EE_CTL_REG EE_CTL +#define EE_WRITE 0x00000001ul +#define EE_READ 0x00000002ul + +/*=============================================== + EEPROM Address - 32bit RW + ------------------------------------------ + This register specifies the address + within the EEPROM from/to which to read/write data. + ===============================================*/ +#define ACX_EE_ADDR_REG EE_ADDR + +/*=============================================== + EEPROM Data - 32bit RW + ------------------------------------------ + This register either holds the read 8 bits of + data from the EEPROM or the write data + to be written to the EEPROM. + ===============================================*/ +#define ACX_EE_DATA_REG EE_DATA + +/*=============================================== + EEPROM Base Address - 32bit RW + ------------------------------------------ + This register holds the upper nine bits + [23:15] of the 24-bit Wlan hardware memory + address for burst reads from EEPROM accesses. + The EEPROM provides the lower 15 bits of this address. + The MSB of the address from the EEPROM is ignored. + ===============================================*/ +#define ACX_EE_CFG EE_CFG + +/*=============================================== + GPIO Output Values -32bit, RW + ------------------------------------------ + [31:16] Reserved + [15: 0] Specify the output values (at the output driver inputs) for + GPIO[15:0], respectively. + ===============================================*/ +#define ACX_GPIO_OUT_REG GPIO_OUT +#define ACX_MAX_GPIO_LINES 15 + +/*=============================================== + Contention window -32bit, RW + ------------------------------------------ + [31:26] Reserved + [25:16] Max (0x3ff) + [15:07] Reserved + [06:00] Current contention window value - default is 0x1F + ===============================================*/ +#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG +#define ACX_CONT_WIND_MIN_MASK 0x0000007f +#define ACX_CONT_WIND_MAX 0x03ff0000 + +/*=============================================== + HI_CFG Interface Configuration Register Values + ------------------------------------------ + ===============================================*/ +#define HI_CFG_UART_ENABLE 0x00000004 +#define HI_CFG_RST232_ENABLE 0x00000008 +#define HI_CFG_CLOCK_REQ_SELECT 0x00000010 +#define HI_CFG_HOST_INT_ENABLE 0x00000020 +#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040 +#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080 +#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100 +#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 +#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 + +/* + * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile + * for platforms using active high interrupt level + */ +#ifdef USE_ACTIVE_HIGH +#define HI_CFG_DEF_VAL \ + (HI_CFG_UART_ENABLE | \ + HI_CFG_RST232_ENABLE | \ + HI_CFG_CLOCK_REQ_SELECT | \ + HI_CFG_HOST_INT_ENABLE) +#else +#define HI_CFG_DEF_VAL \ + (HI_CFG_UART_ENABLE | \ + HI_CFG_RST232_ENABLE | \ + HI_CFG_CLOCK_REQ_SELECT | \ + HI_CFG_HOST_INT_ENABLE) + +#endif + +#define REF_FREQ_19_2 0 +#define REF_FREQ_26_0 1 +#define REF_FREQ_38_4 2 +#define REF_FREQ_40_0 3 +#define REF_FREQ_33_6 4 +#define REF_FREQ_NUM 5 + +#define LUT_PARAM_INTEGER_DIVIDER 0 +#define LUT_PARAM_FRACTIONAL_DIVIDER 1 +#define LUT_PARAM_ATTN_BB 2 +#define LUT_PARAM_ALPHA_BB 3 +#define LUT_PARAM_STOP_TIME_BB 4 +#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 +#define LUT_PARAM_NUM 6 + +#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) +#define USE_EEPROM 0 +#define SOFT_RESET_MAX_TIME 1000000 +#define SOFT_RESET_STALL_TIME 1000 +#define NVS_DATA_BUNDARY_ALIGNMENT 4 + + +/* Firmware image load chunk size */ +#define CHUNK_SIZE 512 + +/* Firmware image header size */ +#define FW_HDR_SIZE 8 + +#define ECPU_CONTROL_HALT 0x00000101 + + +/****************************************************************************** + + CHANNELS, BAND & REG DOMAINS definitions + +******************************************************************************/ + + +enum { + RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */ + RADIO_BAND_5GHZ = 1, /* 5 Ghz band */ + RADIO_BAND_JAPAN_4_9_GHZ = 2, + DEFAULT_BAND = RADIO_BAND_2_4GHZ, + INVALID_BAND = 0xFE, + MAX_RADIO_BANDS = 0xFF +}; + +#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ +#define OFDM_RATE_BIT BIT(6) +#define PBCC_RATE_BIT BIT(7) + +enum { + CCK_LONG = 0, + CCK_SHORT = SHORT_PREAMBLE_BIT, + PBCC_LONG = PBCC_RATE_BIT, + PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT, + OFDM = OFDM_RATE_BIT +}; + +/****************************************************************************** + +Transmit-Descriptor RATE-SET field definitions... + +Define a new "Rate-Set" for TX path that incorporates the +Rate & Modulation info into a single 16-bit field. + +TxdRateSet_t: +b15 - Indicates Preamble type (1=SHORT, 0=LONG). + Notes: + Must be LONG (0) for 1Mbps rate. + Does not apply (set to 0) for RevG-OFDM rates. +b14 - Indicates PBCC encoding (1=PBCC, 0=not). + Notes: + Does not apply (set to 0) for rates 1 and 2 Mbps. + Does not apply (set to 0) for RevG-OFDM rates. +b13 - Unused (set to 0). +b12-b0 - Supported Rate indicator bits as defined below. + +******************************************************************************/ + + +/************************************************************************* + + Interrupt Trigger Register (Host -> WiLink) + +**************************************************************************/ + +/* Hardware to Embedded CPU Interrupts - first 32-bit register set */ + +/* + * Host Command Interrupt. Setting this bit masks + * the interrupt that the host issues to inform + * the FW that it has sent a command + * to the Wlan hardware Command Mailbox. + */ +#define INTR_TRIG_CMD BIT(0) + +/* + * Host Event Acknowlegde Interrupt. The host + * sets this bit to acknowledge that it received + * the unsolicited information from the event + * mailbox. + */ +#define INTR_TRIG_EVENT_ACK BIT(1) + +/* + * The host sets this bit to inform the Wlan + * FW that a TX packet is in the XFER + * Buffer #0. + */ +#define INTR_TRIG_TX_PROC0 BIT(2) + +/* + * The host sets this bit to inform the FW + * that it read a packet from RX XFER + * Buffer #0. + */ +#define INTR_TRIG_RX_PROC0 BIT(3) + +#define INTR_TRIG_DEBUG_ACK BIT(4) + +#define INTR_TRIG_STATE_CHANGED BIT(5) + + +/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ + +/* + * The host sets this bit to inform the FW + * that it read a packet from RX XFER + * Buffer #1. + */ +#define INTR_TRIG_RX_PROC1 BIT(17) + +/* + * The host sets this bit to inform the Wlan + * hardware that a TX packet is in the XFER + * Buffer #1. + */ +#define INTR_TRIG_TX_PROC1 BIT(18) + +#endif diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c new file mode 100644 index 000000000000..682304c30b81 --- /dev/null +++ b/drivers/net/wireless/wl12xx/rx.c @@ -0,0 +1,203 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include + +#include "wl12xx.h" +#include "acx.h" +#include "reg.h" +#include "rx.h" +#include "io.h" + +static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, + u32 drv_rx_counter) +{ + return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & + RX_MEM_BLOCK_MASK; +} + +static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status, + u32 drv_rx_counter) +{ + return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & + RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; +} + +static void wl1271_rx_status(struct wl1271 *wl, + struct wl1271_rx_descriptor *desc, + struct ieee80211_rx_status *status, + u8 beacon) +{ + enum ieee80211_band desc_band; + + memset(status, 0, sizeof(struct ieee80211_rx_status)); + + status->band = wl->band; + + if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG) + desc_band = IEEE80211_BAND_2GHZ; + else + desc_band = IEEE80211_BAND_5GHZ; + + status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band); + +#ifdef CONFIG_WL12XX_HT + /* 11n support */ + if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) + status->flag |= RX_FLAG_HT; +#endif + + status->signal = desc->rssi; + + /* + * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we + * need to divide by two for now, but TI has been discussing about + * changing it. This needs to be rechecked. + */ + wl->noise = desc->rssi - (desc->snr >> 1); + + status->freq = ieee80211_channel_to_frequency(desc->channel); + + if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { + status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; + + if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL))) + status->flag |= RX_FLAG_DECRYPTED; + if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL)) + status->flag |= RX_FLAG_MMIC_ERROR; + } +} + +static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) +{ + struct wl1271_rx_descriptor *desc; + struct sk_buff *skb; + u16 *fc; + u8 *buf; + u8 beacon = 0; + + /* + * In PLT mode we seem to get frames and mac80211 warns about them, + * workaround this by not retrieving them at all. + */ + if (unlikely(wl->state == WL1271_STATE_PLT)) + return -EINVAL; + + skb = __dev_alloc_skb(length, GFP_KERNEL); + if (!skb) { + wl1271_error("Couldn't allocate RX frame"); + return -ENOMEM; + } + + buf = skb_put(skb, length); + memcpy(buf, data, length); + + /* the data read starts with the descriptor */ + desc = (struct wl1271_rx_descriptor *) buf; + + /* now we pull the descriptor out of the buffer */ + skb_pull(skb, sizeof(*desc)); + + fc = (u16 *)skb->data; + if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) + beacon = 1; + + wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); + + wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, + beacon ? "beacon" : ""); + + skb_trim(skb, skb->len - desc->pad_len); + + ieee80211_rx_ni(wl->hw, skb); + + return 0; +} + +void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) +{ + struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; + u32 buf_size; + u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + u32 rx_counter; + u32 mem_block; + u32 pkt_length; + u32 pkt_offset; + + while (drv_rx_counter != fw_rx_counter) { + buf_size = 0; + rx_counter = drv_rx_counter; + while (rx_counter != fw_rx_counter) { + pkt_length = wl1271_rx_get_buf_size(status, rx_counter); + if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) + break; + buf_size += pkt_length; + rx_counter++; + rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + } + + if (buf_size == 0) { + wl1271_warning("received empty data"); + break; + } + + /* + * Choose the block we want to read + * For aggregated packets, only the first memory block should + * be retrieved. The FW takes care of the rest. + */ + mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); + wl->rx_mem_pool_addr.addr = (mem_block << 8) + + le32_to_cpu(wl_mem_map->packet_memory_pool_start); + wl->rx_mem_pool_addr.addr_extra = + wl->rx_mem_pool_addr.addr + 4; + wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, + sizeof(wl->rx_mem_pool_addr), false); + + /* Read all available packets at once */ + wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_size, true); + + /* Split data into separate packets */ + pkt_offset = 0; + while (pkt_offset < buf_size) { + pkt_length = wl1271_rx_get_buf_size(status, + drv_rx_counter); + /* + * the handle data call can only fail in memory-outage + * conditions, in that case the received frame will just + * be dropped. + */ + wl1271_rx_handle_data(wl, + wl->aggr_buf + pkt_offset, + pkt_length); + wl->rx_counter++; + drv_rx_counter++; + drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + pkt_offset += pkt_length; + } + } + wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, + cpu_to_le32(wl->rx_counter)); +} diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h new file mode 100644 index 000000000000..3abb26fe0364 --- /dev/null +++ b/drivers/net/wireless/wl12xx/rx.h @@ -0,0 +1,121 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __RX_H__ +#define __RX_H__ + +#include + +#define WL1271_RX_MAX_RSSI -30 +#define WL1271_RX_MIN_RSSI -95 + +#define WL1271_RX_ALIGN_TO 4 +#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \ + ~(WL1271_RX_ALIGN_TO - 1)) + +#define SHORT_PREAMBLE_BIT BIT(0) +#define OFDM_RATE_BIT BIT(6) +#define PBCC_RATE_BIT BIT(7) + +#define PLCP_HEADER_LENGTH 8 +#define RX_DESC_PACKETID_SHIFT 11 +#define RX_MAX_PACKET_ID 3 + +#define NUM_RX_PKT_DESC_MOD_MASK 7 + +#define RX_DESC_VALID_FCS 0x0001 +#define RX_DESC_MATCH_RXADDR1 0x0002 +#define RX_DESC_MCAST 0x0004 +#define RX_DESC_STAINTIM 0x0008 +#define RX_DESC_VIRTUAL_BM 0x0010 +#define RX_DESC_BCAST 0x0020 +#define RX_DESC_MATCH_SSID 0x0040 +#define RX_DESC_MATCH_BSSID 0x0080 +#define RX_DESC_ENCRYPTION_MASK 0x0300 +#define RX_DESC_MEASURMENT 0x0400 +#define RX_DESC_SEQNUM_MASK 0x1800 +#define RX_DESC_MIC_FAIL 0x2000 +#define RX_DESC_DECRYPT_FAIL 0x4000 + +/* + * RX Descriptor flags: + * + * Bits 0-1 - band + * Bit 2 - STBC + * Bit 3 - A-MPDU + * Bit 4 - HT + * Bits 5-7 - encryption + */ +#define WL1271_RX_DESC_BAND_MASK 0x03 +#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0 + +#define WL1271_RX_DESC_BAND_BG 0x00 +#define WL1271_RX_DESC_BAND_J 0x01 +#define WL1271_RX_DESC_BAND_A 0x02 + +#define WL1271_RX_DESC_STBC BIT(2) +#define WL1271_RX_DESC_A_MPDU BIT(3) +#define WL1271_RX_DESC_HT BIT(4) + +#define WL1271_RX_DESC_ENCRYPT_WEP 0x20 +#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40 +#define WL1271_RX_DESC_ENCRYPT_AES 0x60 +#define WL1271_RX_DESC_ENCRYPT_GEM 0x80 + +/* + * RX Descriptor status + * + * Bits 0-2 - status + * Bits 3-7 - reserved + */ +#define WL1271_RX_DESC_STATUS_MASK 0x07 + +#define WL1271_RX_DESC_SUCCESS 0x00 +#define WL1271_RX_DESC_DECRYPT_FAIL 0x01 +#define WL1271_RX_DESC_MIC_FAIL 0x02 +#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03 + +#define RX_MEM_BLOCK_MASK 0xFF +#define RX_BUF_SIZE_MASK 0xFFF00 +#define RX_BUF_SIZE_SHIFT_DIV 6 + +struct wl1271_rx_descriptor { + __le16 length; + u8 status; + u8 flags; + u8 rate; + u8 channel; + s8 rssi; + u8 snr; + __le32 timestamp; + u8 packet_class; + u8 process_id; + u8 pad_len; + u8 reserved; +} __packed; + +void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); + +#endif diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c new file mode 100644 index 000000000000..f3f2c5b011ee --- /dev/null +++ b/drivers/net/wireless/wl12xx/scan.c @@ -0,0 +1,307 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include + +#include "wl12xx.h" +#include "cmd.h" +#include "scan.h" +#include "acx.h" + +void wl1271_scan_complete_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, scan_complete_work); + + wl1271_debug(DEBUG_SCAN, "Scanning complete"); + + mutex_lock(&wl->mutex); + + if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { + mutex_unlock(&wl->mutex); + return; + } + + wl->scan.state = WL1271_SCAN_STATE_IDLE; + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; + wl->scan.req = NULL; + ieee80211_scan_completed(wl->hw, false); + + if (wl->scan.failed) { + wl1271_info("Scan completed due to error."); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + } + mutex_unlock(&wl->mutex); + +} + + +static int wl1271_get_scan_channels(struct wl1271 *wl, + struct cfg80211_scan_request *req, + struct basic_scan_channel_params *channels, + enum ieee80211_band band, bool passive) +{ + struct conf_scan_settings *c = &wl->conf.scan; + int i, j; + u32 flags; + + for (i = 0, j = 0; + i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; + i++) { + + flags = req->channels[i]->flags; + + if (!wl->scan.scanned_ch[i] && + !(flags & IEEE80211_CHAN_DISABLED) && + ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && + (req->channels[i]->band == band)) { + + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", + req->channels[i]->band, + req->channels[i]->center_freq); + wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", + req->channels[i]->hw_value, + req->channels[i]->flags); + wl1271_debug(DEBUG_SCAN, + "max_antenna_gain %d, max_power %d", + req->channels[i]->max_antenna_gain, + req->channels[i]->max_power); + wl1271_debug(DEBUG_SCAN, "beacon_found %d", + req->channels[i]->beacon_found); + + if (!passive) { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_active); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_active); + } else { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_passive); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_passive); + } + channels[j].early_termination = 0; + channels[j].tx_power_att = req->channels[i]->max_power; + channels[j].channel = req->channels[i]->hw_value; + + memset(&channels[j].bssid_lsb, 0xff, 4); + memset(&channels[j].bssid_msb, 0xff, 2); + + /* Mark the channels we already used */ + wl->scan.scanned_ch[i] = true; + + j++; + } + } + + return j; +} + +#define WL1271_NOTHING_TO_SCAN 1 + +static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, + bool passive, u32 basic_rate) +{ + struct wl1271_cmd_scan *cmd; + struct wl1271_cmd_trigger_scan_to *trigger; + int ret; + u16 scan_options = 0; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); + if (!cmd || !trigger) { + ret = -ENOMEM; + goto out; + } + + /* We always use high priority scans */ + scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; + + /* No SSIDs means that we have a forced passive scan */ + if (passive || wl->scan.req->n_ssids == 0) + scan_options |= WL1271_SCAN_OPT_PASSIVE; + + cmd->params.scan_options = cpu_to_le16(scan_options); + + cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, + cmd->channels, + band, passive); + if (cmd->params.n_ch == 0) { + ret = WL1271_NOTHING_TO_SCAN; + goto out; + } + + cmd->params.tx_rate = cpu_to_le32(basic_rate); + cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); + cmd->params.rx_filter_options = + cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); + + cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; + cmd->params.tx_rate = cpu_to_le32(basic_rate); + cmd->params.tid_trigger = 0; + cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; + + if (band == IEEE80211_BAND_2GHZ) + cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ; + else + cmd->params.band = WL1271_SCAN_BAND_5_GHZ; + + if (wl->scan.ssid_len && wl->scan.ssid) { + cmd->params.ssid_len = wl->scan.ssid_len; + memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); + } + + ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len, + wl->scan.req->ie, wl->scan.req->ie_len, + band); + if (ret < 0) { + wl1271_error("PROBE request template failed"); + goto out; + } + + /* disable the timeout */ + trigger->timeout = 0; + ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, + sizeof(*trigger), 0); + if (ret < 0) { + wl1271_error("trigger scan to failed for hw scan"); + goto out; + } + + wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd)); + + ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("SCAN failed"); + goto out; + } + +out: + kfree(cmd); + kfree(trigger); + return ret; +} + +void wl1271_scan_stm(struct wl1271 *wl) +{ + int ret = 0; + + switch (wl->scan.state) { + case WL1271_SCAN_STATE_IDLE: + break; + + case WL1271_SCAN_STATE_2GHZ_ACTIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, + wl->conf.tx.basic_rate); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_2GHZ_PASSIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, + wl->conf.tx.basic_rate); + if (ret == WL1271_NOTHING_TO_SCAN) { + if (wl->enable_11a) + wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; + else + wl->scan.state = WL1271_SCAN_STATE_DONE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_5GHZ_ACTIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, + wl->conf.tx.basic_rate_5); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_5GHZ_PASSIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, + wl->conf.tx.basic_rate_5); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_DONE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_DONE: + wl->scan.failed = false; + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); + break; + + default: + wl1271_error("invalid scan state"); + break; + } + + if (ret < 0) { + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); + } +} + +int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, + struct cfg80211_scan_request *req) +{ + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) + return -EBUSY; + + wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; + + if (ssid_len && ssid) { + wl->scan.ssid_len = ssid_len; + memcpy(wl->scan.ssid, ssid, ssid_len); + } else { + wl->scan.ssid_len = 0; + } + + wl->scan.req = req; + + wl->scan.scanned_ch = kcalloc(req->n_channels, + sizeof(*wl->scan.scanned_ch), + GFP_KERNEL); + /* we assume failure so that timeout scenarios are handled correctly */ + wl->scan.failed = true; + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); + + wl1271_scan_stm(wl); + + return 0; +} diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h new file mode 100644 index 000000000000..421a750add5a --- /dev/null +++ b/drivers/net/wireless/wl12xx/scan.h @@ -0,0 +1,109 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __SCAN_H__ +#define __SCAN_H__ + +#include "wl12xx.h" + +int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, + struct cfg80211_scan_request *req); +int wl1271_scan_build_probe_req(struct wl1271 *wl, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len, u8 band); +void wl1271_scan_stm(struct wl1271 *wl); +void wl1271_scan_complete_work(struct work_struct *work); + +#define WL1271_SCAN_MAX_CHANNELS 24 +#define WL1271_SCAN_DEFAULT_TAG 1 +#define WL1271_SCAN_CURRENT_TX_PWR 0 +#define WL1271_SCAN_OPT_ACTIVE 0 +#define WL1271_SCAN_OPT_PASSIVE 1 +#define WL1271_SCAN_OPT_PRIORITY_HIGH 4 +#define WL1271_SCAN_BAND_2_4_GHZ 0 +#define WL1271_SCAN_BAND_5_GHZ 1 + +#define WL1271_SCAN_TIMEOUT 10000 /* msec */ + +enum { + WL1271_SCAN_STATE_IDLE, + WL1271_SCAN_STATE_2GHZ_ACTIVE, + WL1271_SCAN_STATE_2GHZ_PASSIVE, + WL1271_SCAN_STATE_5GHZ_ACTIVE, + WL1271_SCAN_STATE_5GHZ_PASSIVE, + WL1271_SCAN_STATE_DONE +}; + +struct basic_scan_params { + __le32 rx_config_options; + __le32 rx_filter_options; + /* Scan option flags (WL1271_SCAN_OPT_*) */ + __le16 scan_options; + /* Number of scan channels in the list (maximum 30) */ + u8 n_ch; + /* This field indicates the number of probe requests to send + per channel for an active scan */ + u8 n_probe_reqs; + /* Rate bit field for sending the probes */ + __le32 tx_rate; + u8 tid_trigger; + u8 ssid_len; + /* in order to align */ + u8 padding1[2]; + u8 ssid[IW_ESSID_MAX_SIZE]; + /* Band to scan */ + u8 band; + u8 use_ssid_list; + u8 scan_tag; + u8 padding2; +} __packed; + +struct basic_scan_channel_params { + /* Duration in TU to wait for frames on a channel for active scan */ + __le32 min_duration; + __le32 max_duration; + __le32 bssid_lsb; + __le16 bssid_msb; + u8 early_termination; + u8 tx_power_att; + u8 channel; + /* FW internal use only! */ + u8 dfs_candidate; + u8 activity_detected; + u8 pad; +} __packed; + +struct wl1271_cmd_scan { + struct wl1271_cmd_header header; + + struct basic_scan_params params; + struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS]; +} __packed; + +struct wl1271_cmd_trigger_scan_to { + struct wl1271_cmd_header header; + + __le32 timeout; +} __packed; + +#endif /* __WL1271_SCAN_H__ */ diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c new file mode 100644 index 000000000000..93cbb8d5aba9 --- /dev/null +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -0,0 +1,347 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "wl12xx_80211.h" +#include "io.h" + +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI 0x0097 +#endif + +#ifndef SDIO_DEVICE_ID_TI_WL1271 +#define SDIO_DEVICE_ID_TI_WL1271 0x4076 +#endif + +static const struct sdio_device_id wl1271_devices[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, + {} +}; +MODULE_DEVICE_TABLE(sdio, wl1271_devices); + +static inline struct sdio_func *wl_to_func(struct wl1271 *wl) +{ + return wl->if_priv; +} + +static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) +{ + return &(wl_to_func(wl)->dev); +} + +static irqreturn_t wl1271_irq(int irq, void *cookie) +{ + struct wl1271 *wl = cookie; + unsigned long flags; + + wl1271_debug(DEBUG_IRQ, "IRQ"); + + /* complete the ELP completion */ + spin_lock_irqsave(&wl->wl_lock, flags); + if (wl->elp_compl) { + complete(wl->elp_compl); + wl->elp_compl = NULL; + } + + if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->irq_work); + set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + + return IRQ_HANDLED; +} + +static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) +{ + disable_irq(wl->irq); +} + +static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) +{ + enable_irq(wl->irq); +} + +static void wl1271_sdio_reset(struct wl1271 *wl) +{ +} + +static void wl1271_sdio_init(struct wl1271 *wl) +{ +} + +static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret; + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + if (fixed) + ret = sdio_readsb(func, buf, addr, len); + else + ret = sdio_memcpy_fromio(func, buf, addr, len); + + wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + } + + sdio_release_host(func); + + if (ret) + wl1271_error("sdio read failed (%d)", ret); +} + +static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret; + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + + if (fixed) + ret = sdio_writesb(func, addr, buf, len); + else + ret = sdio_memcpy_toio(func, addr, buf, len); + } + + sdio_release_host(func); + + if (ret) + wl1271_error("sdio write failed (%d)", ret); +} + +static int wl1271_sdio_power_on(struct wl1271 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + int ret; + + /* Power up the card */ + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + +out: + return ret; +} + +static int wl1271_sdio_power_off(struct wl1271 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + /* Power down the card */ + return pm_runtime_put_sync(&func->dev); +} + +static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +{ + if (enable) + return wl1271_sdio_power_on(wl); + else + return wl1271_sdio_power_off(wl); +} + +static struct wl1271_if_operations sdio_ops = { + .read = wl1271_sdio_raw_read, + .write = wl1271_sdio_raw_write, + .reset = wl1271_sdio_reset, + .init = wl1271_sdio_init, + .power = wl1271_sdio_set_power, + .dev = wl1271_sdio_wl_to_dev, + .enable_irq = wl1271_sdio_enable_interrupts, + .disable_irq = wl1271_sdio_disable_interrupts +}; + +static int __devinit wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + struct ieee80211_hw *hw; + const struct wl12xx_platform_data *wlan_data; + struct wl1271 *wl; + int ret; + + /* We are only able to handle the wlan function */ + if (func->num != 0x02) + return -ENODEV; + + hw = wl1271_alloc_hw(); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + wl = hw->priv; + + wl->if_priv = func; + wl->if_ops = &sdio_ops; + + /* Grab access to FN0 for ELP reg. */ + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + + wlan_data = wl12xx_get_platform_data(); + if (IS_ERR(wlan_data)) { + ret = PTR_ERR(wlan_data); + wl1271_error("missing wlan platform data: %d", ret); + goto out_free; + } + + wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; + + ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); + if (ret < 0) { + wl1271_error("request_irq() failed: %d", ret); + goto out_free; + } + + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + + disable_irq(wl->irq); + + ret = wl1271_init_ieee80211(wl); + if (ret) + goto out_irq; + + ret = wl1271_register_hw(wl); + if (ret) + goto out_irq; + + sdio_set_drvdata(func, wl); + + /* Tell PM core that we don't need the card to be powered now */ + pm_runtime_put_noidle(&func->dev); + + wl1271_notice("initialized"); + + return 0; + + out_irq: + free_irq(wl->irq, wl); + + + out_free: + wl1271_free_hw(wl); + + return ret; +} + +static void __devexit wl1271_remove(struct sdio_func *func) +{ + struct wl1271 *wl = sdio_get_drvdata(func); + + /* Undo decrement done above in wl1271_probe */ + pm_runtime_get_noresume(&func->dev); + + wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); + wl1271_free_hw(wl); +} + +static int wl1271_suspend(struct device *dev) +{ + /* Tell MMC/SDIO core it's OK to power down the card + * (if it isn't already), but not to remove it completely */ + return 0; +} + +static int wl1271_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wl1271_sdio_pm_ops = { + .suspend = wl1271_suspend, + .resume = wl1271_resume, +}; + +static struct sdio_driver wl1271_sdio_driver = { + .name = "wl1271_sdio", + .id_table = wl1271_devices, + .probe = wl1271_probe, + .remove = __devexit_p(wl1271_remove), + .drv = { + .pm = &wl1271_sdio_pm_ops, + }, +}; + +static int __init wl1271_init(void) +{ + int ret; + + ret = sdio_register_driver(&wl1271_sdio_driver); + if (ret < 0) { + wl1271_error("failed to register sdio driver: %d", ret); + goto out; + } + +out: + return ret; +} + +static void __exit wl1271_exit(void) +{ + sdio_unregister_driver(&wl1271_sdio_driver); + + wl1271_notice("unloaded"); +} + +module_init(wl1271_init); +module_exit(wl1271_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Luciano Coelho "); +MODULE_AUTHOR("Juuso Oikarinen "); +MODULE_FIRMWARE(WL1271_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c new file mode 100644 index 000000000000..46714910f98c --- /dev/null +++ b/drivers/net/wireless/wl12xx/spi.c @@ -0,0 +1,498 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "wl12xx_80211.h" +#include "io.h" + +#include "reg.h" + +#define WSPI_CMD_READ 0x40000000 +#define WSPI_CMD_WRITE 0x00000000 +#define WSPI_CMD_FIXED 0x20000000 +#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 +#define WSPI_CMD_BYTE_LENGTH_OFFSET 17 +#define WSPI_CMD_BYTE_ADDR 0x0001FFFF + +#define WSPI_INIT_CMD_CRC_LEN 5 + +#define WSPI_INIT_CMD_START 0x00 +#define WSPI_INIT_CMD_TX 0x40 +/* the extra bypass bit is sampled by the TNET as '1' */ +#define WSPI_INIT_CMD_BYPASS_BIT 0x80 +#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 +#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 +#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 +#define WSPI_INIT_CMD_IOD 0x40 +#define WSPI_INIT_CMD_IP 0x20 +#define WSPI_INIT_CMD_CS 0x10 +#define WSPI_INIT_CMD_WS 0x08 +#define WSPI_INIT_CMD_WSPI 0x01 +#define WSPI_INIT_CMD_END 0x01 + +#define WSPI_INIT_CMD_LEN 8 + +#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ + ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) +#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 + +/* HW limitation: maximum possible chunk size is 4095 bytes */ +#define WSPI_MAX_CHUNK_SIZE 4092 + +#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + +static inline struct spi_device *wl_to_spi(struct wl1271 *wl) +{ + return wl->if_priv; +} + +static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) +{ + return &(wl_to_spi(wl)->dev); +} + +static void wl1271_spi_disable_interrupts(struct wl1271 *wl) +{ + disable_irq(wl->irq); +} + +static void wl1271_spi_enable_interrupts(struct wl1271 *wl) +{ + enable_irq(wl->irq); +} + +static void wl1271_spi_reset(struct wl1271 *wl) +{ + u8 *cmd; + struct spi_transfer t; + struct spi_message m; + + cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); + if (!cmd) { + wl1271_error("could not allocate cmd for spi reset"); + return; + } + + memset(&t, 0, sizeof(t)); + spi_message_init(&m); + + memset(cmd, 0xff, WSPI_INIT_CMD_LEN); + + t.tx_buf = cmd; + t.len = WSPI_INIT_CMD_LEN; + spi_message_add_tail(&t, &m); + + spi_sync(wl_to_spi(wl), &m); + kfree(cmd); + + wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); +} + +static void wl1271_spi_init(struct wl1271 *wl) +{ + u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; + struct spi_transfer t; + struct spi_message m; + + cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); + if (!cmd) { + wl1271_error("could not allocate cmd for spi init"); + return; + } + + memset(crc, 0, sizeof(crc)); + memset(&t, 0, sizeof(t)); + spi_message_init(&m); + + /* + * Set WSPI_INIT_COMMAND + * the data is being send from the MSB to LSB + */ + cmd[2] = 0xff; + cmd[3] = 0xff; + cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX; + cmd[0] = 0; + cmd[7] = 0; + cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3; + cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN; + + if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0) + cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY; + else + cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY; + + cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS + | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS; + + crc[0] = cmd[1]; + crc[1] = cmd[0]; + crc[2] = cmd[7]; + crc[3] = cmd[6]; + crc[4] = cmd[5]; + + cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1; + cmd[4] |= WSPI_INIT_CMD_END; + + t.tx_buf = cmd; + t.len = WSPI_INIT_CMD_LEN; + spi_message_add_tail(&t, &m); + + spi_sync(wl_to_spi(wl), &m); + wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); + kfree(cmd); +} + +#define WL1271_BUSY_WORD_TIMEOUT 1000 + +static int wl1271_spi_read_busy(struct wl1271 *wl) +{ + struct spi_transfer t[1]; + struct spi_message m; + u32 *busy_buf; + int num_busy_bytes = 0; + + /* + * Read further busy words from SPI until a non-busy word is + * encountered, then read the data itself into the buffer. + */ + + num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; + busy_buf = wl->buffer_busyword; + while (num_busy_bytes) { + num_busy_bytes--; + spi_message_init(&m); + memset(t, 0, sizeof(t)); + t[0].rx_buf = busy_buf; + t[0].len = sizeof(u32); + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); + spi_sync(wl_to_spi(wl), &m); + + if (*busy_buf & 0x1) + return 0; + } + + /* The SPI bus is unresponsive, the read failed. */ + wl1271_error("SPI read busy-word timeout!\n"); + return -ETIMEDOUT; +} + +static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + struct spi_transfer t[2]; + struct spi_message m; + u32 *busy_buf; + u32 *cmd; + u32 chunk_len; + + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); + + cmd = &wl->buffer_cmd; + busy_buf = wl->buffer_busyword; + + *cmd = 0; + *cmd |= WSPI_CMD_READ; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; + + if (fixed) + *cmd |= WSPI_CMD_FIXED; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = 4; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); + + /* Busy and non busy words read */ + t[1].rx_buf = busy_buf; + t[1].len = WL1271_BUSY_WORD_LEN; + t[1].cs_change = true; + spi_message_add_tail(&t[1], &m); + + spi_sync(wl_to_spi(wl), &m); + + if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && + wl1271_spi_read_busy(wl)) { + memset(buf, 0, chunk_len); + return; + } + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].rx_buf = buf; + t[0].len = chunk_len; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); + + spi_sync(wl_to_spi(wl), &m); + + wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + } +} + +static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; + struct spi_message m; + u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; + u32 *cmd; + u32 chunk_len; + int i; + + WARN_ON(len > WL1271_AGGR_BUFFER_SIZE); + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + cmd = &commands[0]; + i = 0; + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); + + *cmd = 0; + *cmd |= WSPI_CMD_WRITE; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; + + if (fixed) + *cmd |= WSPI_CMD_FIXED; + + t[i].tx_buf = cmd; + t[i].len = sizeof(*cmd); + spi_message_add_tail(&t[i++], &m); + + t[i].tx_buf = buf; + t[i].len = chunk_len; + spi_message_add_tail(&t[i++], &m); + + wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + cmd++; + } + + spi_sync(wl_to_spi(wl), &m); +} + +static irqreturn_t wl1271_irq(int irq, void *cookie) +{ + struct wl1271 *wl; + unsigned long flags; + + wl1271_debug(DEBUG_IRQ, "IRQ"); + + wl = cookie; + + /* complete the ELP completion */ + spin_lock_irqsave(&wl->wl_lock, flags); + if (wl->elp_compl) { + complete(wl->elp_compl); + wl->elp_compl = NULL; + } + + if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->irq_work); + set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + + return IRQ_HANDLED; +} + +static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) +{ + if (wl->set_power) + wl->set_power(enable); + + return 0; +} + +static struct wl1271_if_operations spi_ops = { + .read = wl1271_spi_raw_read, + .write = wl1271_spi_raw_write, + .reset = wl1271_spi_reset, + .init = wl1271_spi_init, + .power = wl1271_spi_set_power, + .dev = wl1271_spi_wl_to_dev, + .enable_irq = wl1271_spi_enable_interrupts, + .disable_irq = wl1271_spi_disable_interrupts +}; + +static int __devinit wl1271_probe(struct spi_device *spi) +{ + struct wl12xx_platform_data *pdata; + struct ieee80211_hw *hw; + struct wl1271 *wl; + int ret; + + pdata = spi->dev.platform_data; + if (!pdata) { + wl1271_error("no platform data"); + return -ENODEV; + } + + hw = wl1271_alloc_hw(); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + wl = hw->priv; + + dev_set_drvdata(&spi->dev, wl); + wl->if_priv = spi; + + wl->if_ops = &spi_ops; + + /* This is the only SPI value that we need to set here, the rest + * comes from the board-peripherals file */ + spi->bits_per_word = 32; + + ret = spi_setup(spi); + if (ret < 0) { + wl1271_error("spi_setup failed"); + goto out_free; + } + + wl->set_power = pdata->set_power; + if (!wl->set_power) { + wl1271_error("set power function missing in platform data"); + ret = -ENODEV; + goto out_free; + } + + wl->ref_clock = pdata->board_ref_clock; + + wl->irq = spi->irq; + if (wl->irq < 0) { + wl1271_error("irq missing in platform data"); + ret = -ENODEV; + goto out_free; + } + + ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); + if (ret < 0) { + wl1271_error("request_irq() failed: %d", ret); + goto out_free; + } + + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + + disable_irq(wl->irq); + + ret = wl1271_init_ieee80211(wl); + if (ret) + goto out_irq; + + ret = wl1271_register_hw(wl); + if (ret) + goto out_irq; + + wl1271_notice("initialized"); + + return 0; + + out_irq: + free_irq(wl->irq, wl); + + out_free: + wl1271_free_hw(wl); + + return ret; +} + +static int __devexit wl1271_remove(struct spi_device *spi) +{ + struct wl1271 *wl = dev_get_drvdata(&spi->dev); + + wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); + wl1271_free_hw(wl); + + return 0; +} + + +static struct spi_driver wl1271_spi_driver = { + .driver = { + .name = "wl1271_spi", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = wl1271_probe, + .remove = __devexit_p(wl1271_remove), +}; + +static int __init wl1271_init(void) +{ + int ret; + + ret = spi_register_driver(&wl1271_spi_driver); + if (ret < 0) { + wl1271_error("failed to register spi driver: %d", ret); + goto out; + } + +out: + return ret; +} + +static void __exit wl1271_exit(void) +{ + spi_unregister_driver(&wl1271_spi_driver); + + wl1271_notice("unloaded"); +} + +module_init(wl1271_init); +module_exit(wl1271_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Luciano Coelho "); +MODULE_AUTHOR("Juuso Oikarinen "); +MODULE_FIRMWARE(WL1271_FW_NAME); +MODULE_ALIAS("spi:wl1271"); diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c new file mode 100644 index 000000000000..e64403b6896d --- /dev/null +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -0,0 +1,290 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#include "testmode.h" + +#include +#include + +#include "wl12xx.h" +#include "acx.h" + +#define WL1271_TM_MAX_DATA_LENGTH 1024 + +enum wl1271_tm_commands { + WL1271_TM_CMD_UNSPEC, + WL1271_TM_CMD_TEST, + WL1271_TM_CMD_INTERROGATE, + WL1271_TM_CMD_CONFIGURE, + WL1271_TM_CMD_NVS_PUSH, + WL1271_TM_CMD_SET_PLT_MODE, + WL1271_TM_CMD_RECOVER, + + __WL1271_TM_CMD_AFTER_LAST +}; +#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1) + +enum wl1271_tm_attrs { + WL1271_TM_ATTR_UNSPEC, + WL1271_TM_ATTR_CMD_ID, + WL1271_TM_ATTR_ANSWER, + WL1271_TM_ATTR_DATA, + WL1271_TM_ATTR_IE_ID, + WL1271_TM_ATTR_PLT_MODE, + + __WL1271_TM_ATTR_AFTER_LAST +}; +#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1) + +static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = { + [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 }, + [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 }, + [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY, + .len = WL1271_TM_MAX_DATA_LENGTH }, + [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 }, + [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 }, +}; + + +static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) +{ + int buf_len, ret, len; + struct sk_buff *skb; + void *buf; + u8 answer = 0; + + wl1271_debug(DEBUG_TESTMODE, "testmode cmd test"); + + if (!tb[WL1271_TM_ATTR_DATA]) + return -EINVAL; + + buf = nla_data(tb[WL1271_TM_ATTR_DATA]); + buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); + + if (tb[WL1271_TM_ATTR_ANSWER]) + answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]); + + if (buf_len > sizeof(struct wl1271_command)) + return -EMSGSIZE; + + mutex_lock(&wl->mutex); + ret = wl1271_cmd_test(wl, buf, buf_len, answer); + mutex_unlock(&wl->mutex); + + if (ret < 0) { + wl1271_warning("testmode cmd test failed: %d", ret); + return ret; + } + + if (answer) { + len = nla_total_size(buf_len); + skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); + if (!skb) + return -ENOMEM; + + NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf); + ret = cfg80211_testmode_reply(skb); + if (ret < 0) + return ret; + } + + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EMSGSIZE; +} + +static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) +{ + int ret; + struct wl1271_command *cmd; + struct sk_buff *skb; + u8 ie_id; + + wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate"); + + if (!tb[WL1271_TM_ATTR_IE_ID]) + return -EINVAL; + + ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + mutex_lock(&wl->mutex); + ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); + mutex_unlock(&wl->mutex); + + if (ret < 0) { + wl1271_warning("testmode cmd interrogate failed: %d", ret); + return ret; + } + + skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); + + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EMSGSIZE; +} + +static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) +{ + int buf_len, ret; + void *buf; + u8 ie_id; + + wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure"); + + if (!tb[WL1271_TM_ATTR_DATA]) + return -EINVAL; + if (!tb[WL1271_TM_ATTR_IE_ID]) + return -EINVAL; + + ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); + buf = nla_data(tb[WL1271_TM_ATTR_DATA]); + buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); + + if (buf_len > sizeof(struct wl1271_command)) + return -EMSGSIZE; + + mutex_lock(&wl->mutex); + ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len); + mutex_unlock(&wl->mutex); + + if (ret < 0) { + wl1271_warning("testmode cmd configure failed: %d", ret); + return ret; + } + + return 0; +} + +static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) +{ + int ret = 0; + size_t len; + void *buf; + + wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); + + if (!tb[WL1271_TM_ATTR_DATA]) + return -EINVAL; + + buf = nla_data(tb[WL1271_TM_ATTR_DATA]); + len = nla_len(tb[WL1271_TM_ATTR_DATA]); + + mutex_lock(&wl->mutex); + + kfree(wl->nvs); + + wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); + if (!wl->nvs) { + wl1271_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; + goto out; + } + + memcpy(wl->nvs, buf, len); + wl->nvs_len = len; + + wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) +{ + u32 val; + int ret; + + wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode"); + + if (!tb[WL1271_TM_ATTR_PLT_MODE]) + return -EINVAL; + + val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]); + + switch (val) { + case 0: + ret = wl1271_plt_stop(wl); + break; + case 1: + ret = wl1271_plt_start(wl); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[]) +{ + wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover"); + + ieee80211_queue_work(wl->hw, &wl->recovery_work); + + return 0; +} + +int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) +{ + struct wl1271 *wl = hw->priv; + struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; + int err; + + err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy); + if (err) + return err; + + if (!tb[WL1271_TM_ATTR_CMD_ID]) + return -EINVAL; + + switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) { + case WL1271_TM_CMD_TEST: + return wl1271_tm_cmd_test(wl, tb); + case WL1271_TM_CMD_INTERROGATE: + return wl1271_tm_cmd_interrogate(wl, tb); + case WL1271_TM_CMD_CONFIGURE: + return wl1271_tm_cmd_configure(wl, tb); + case WL1271_TM_CMD_NVS_PUSH: + return wl1271_tm_cmd_nvs_push(wl, tb); + case WL1271_TM_CMD_SET_PLT_MODE: + return wl1271_tm_cmd_set_plt_mode(wl, tb); + case WL1271_TM_CMD_RECOVER: + return wl1271_tm_cmd_recover(wl, tb); + default: + return -EOPNOTSUPP; + } +} diff --git a/drivers/net/wireless/wl12xx/testmode.h b/drivers/net/wireless/wl12xx/testmode.h new file mode 100644 index 000000000000..8071654259ea --- /dev/null +++ b/drivers/net/wireless/wl12xx/testmode.h @@ -0,0 +1,31 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TESTMODE_H__ +#define __TESTMODE_H__ + +#include + +int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len); + +#endif /* __WL1271_TESTMODE_H__ */ diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c new file mode 100644 index 000000000000..d332b3f6d0fa --- /dev/null +++ b/drivers/net/wireless/wl12xx/tx.c @@ -0,0 +1,485 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "wl12xx.h" +#include "io.h" +#include "reg.h" +#include "ps.h" +#include "tx.h" + +static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) +{ + int id; + + id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS); + if (id >= ACX_TX_DESCRIPTORS) + return -EBUSY; + + __set_bit(id, wl->tx_frames_map); + wl->tx_frames[id] = skb; + wl->tx_frames_cnt++; + return id; +} + +static void wl1271_free_tx_id(struct wl1271 *wl, int id) +{ + if (__test_and_clear_bit(id, wl->tx_frames_map)) { + wl->tx_frames[id] = NULL; + wl->tx_frames_cnt--; + } +} + +static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, + u32 buf_offset) +{ + struct wl1271_tx_hw_descr *desc; + u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; + u32 total_blocks; + int id, ret = -EBUSY; + + if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) + return -EAGAIN; + + /* allocate free identifier for the packet */ + id = wl1271_alloc_tx_id(wl, skb); + if (id < 0) + return id; + + /* approximate the number of blocks required for this packet + in the firmware */ + total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; + total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; + if (total_blocks <= wl->tx_blocks_available) { + desc = (struct wl1271_tx_hw_descr *)skb_push( + skb, total_len - skb->len); + + desc->extra_mem_blocks = TX_HW_BLOCK_SPARE; + desc->total_mem_blocks = total_blocks; + desc->id = id; + + wl->tx_blocks_available -= total_blocks; + + ret = 0; + + wl1271_debug(DEBUG_TX, + "tx_allocate: size: %d, blocks: %d, id: %d", + total_len, total_blocks, id); + } else { + wl1271_free_tx_id(wl, id); + } + + return ret; +} + +static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, + u32 extra, struct ieee80211_tx_info *control) +{ + struct timespec ts; + struct wl1271_tx_hw_descr *desc; + int pad, ac; + s64 hosttime; + u16 tx_attr; + + desc = (struct wl1271_tx_hw_descr *) skb->data; + + /* relocate space for security header */ + if (extra) { + void *framestart = skb->data + sizeof(*desc); + u16 fc = *(u16 *)(framestart + extra); + int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc)); + memmove(framestart, framestart + extra, hdrlen); + } + + /* configure packet life time */ + getnstimeofday(&ts); + hosttime = (timespec_to_ns(&ts) >> 10); + desc->start_time = cpu_to_le32(hosttime - wl->time_offset); + desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); + + /* configure the tx attributes */ + tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; + + /* queue (we use same identifiers for tid's and ac's */ + ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + desc->tid = ac; + + desc->aid = TX_HW_DEFAULT_AID; + desc->reserved = 0; + + /* align the length (and store in terms of words) */ + pad = WL1271_TX_ALIGN(skb->len); + desc->length = cpu_to_le16(pad >> 2); + + /* calculate number of padding bytes */ + pad = pad - skb->len; + tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; + + /* if the packets are destined for AP (have a STA entry) send them + with AP rate policies, otherwise use default basic rates */ + if (control->control.sta) + tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY; + + desc->tx_attr = cpu_to_le16(tx_attr); + + wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); +} + +/* caller must hold wl->mutex */ +static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, + u32 buf_offset) +{ + struct ieee80211_tx_info *info; + u32 extra = 0; + int ret = 0; + u8 idx; + u32 total_len; + + if (!skb) + return -EINVAL; + + info = IEEE80211_SKB_CB(skb); + + if (info->control.hw_key && + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) + extra = WL1271_TKIP_IV_SPACE; + + if (info->control.hw_key) { + idx = info->control.hw_key->hw_key_idx; + + /* FIXME: do we have to do this if we're not using WEP? */ + if (unlikely(wl->default_key != idx)) { + ret = wl1271_cmd_set_default_wep_key(wl, idx); + if (ret < 0) + return ret; + wl->default_key = idx; + } + } + + ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); + if (ret < 0) + return ret; + + wl1271_tx_fill_hdr(wl, skb, extra, info); + + /* + * The length of each packet is stored in terms of words. Thus, we must + * pad the skb data to make sure its length is aligned. + * The number of padding bytes is computed and set in wl1271_tx_fill_hdr + */ + total_len = WL1271_TX_ALIGN(skb->len); + memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); + memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); + + return total_len; +} + +u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) +{ + struct ieee80211_supported_band *band; + u32 enabled_rates = 0; + int bit; + + band = wl->hw->wiphy->bands[wl->band]; + for (bit = 0; bit < band->n_bitrates; bit++) { + if (rate_set & 0x1) + enabled_rates |= band->bitrates[bit].hw_value; + rate_set >>= 1; + } + +#ifdef CONFIG_WL12XX_HT + /* MCS rates indication are on bits 16 - 23 */ + rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; + + for (bit = 0; bit < 8; bit++) { + if (rate_set & 0x1) + enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); + rate_set >>= 1; + } +#endif + + return enabled_rates; +} + +static void handle_tx_low_watermark(struct wl1271 *wl) +{ + unsigned long flags; + + if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && + skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { + /* firmware buffer has space, restart queues */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + } +} + +void wl1271_tx_work_locked(struct wl1271 *wl) +{ + struct sk_buff *skb; + bool woken_up = false; + u32 sta_rates = 0; + u32 buf_offset = 0; + bool sent_packets = false; + int ret; + + /* check if the rates supported by the AP have changed */ + if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, + &wl->flags))) { + unsigned long flags; + + spin_lock_irqsave(&wl->wl_lock, flags); + sta_rates = wl->sta_rate_set; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + /* if rates have changed, re-configure the rate policy */ + if (unlikely(sta_rates)) { + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + woken_up = true; + + wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); + wl1271_acx_rate_policies(wl); + } + + while ((skb = skb_dequeue(&wl->tx_queue))) { + if (!woken_up) { + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out_ack; + woken_up = true; + } + + ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); + if (ret == -EAGAIN) { + /* + * Aggregation buffer is full. + * Flush buffer and try again. + */ + skb_queue_head(&wl->tx_queue, skb); + wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + sent_packets = true; + buf_offset = 0; + continue; + } else if (ret == -EBUSY) { + /* + * Firmware buffer is full. + * Queue back last skb, and stop aggregating. + */ + skb_queue_head(&wl->tx_queue, skb); + /* No work left, avoid scheduling redundant tx work */ + set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); + goto out_ack; + } else if (ret < 0) { + dev_kfree_skb(skb); + goto out_ack; + } + buf_offset += ret; + wl->tx_packets_count++; + } + +out_ack: + if (buf_offset) { + wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + sent_packets = true; + } + if (sent_packets) { + /* interrupt the firmware with the new packets */ + wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); + handle_tx_low_watermark(wl); + } + +out: + if (woken_up) + wl1271_ps_elp_sleep(wl); +} + +void wl1271_tx_work(struct work_struct *work) +{ + struct wl1271 *wl = container_of(work, struct wl1271, tx_work); + + mutex_lock(&wl->mutex); + wl1271_tx_work_locked(wl); + mutex_unlock(&wl->mutex); +} + +static void wl1271_tx_complete_packet(struct wl1271 *wl, + struct wl1271_tx_hw_res_descr *result) +{ + struct ieee80211_tx_info *info; + struct sk_buff *skb; + int id = result->id; + int rate = -1; + u8 retries = 0; + + /* check for id legality */ + if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { + wl1271_warning("TX result illegal id: %d", id); + return; + } + + skb = wl->tx_frames[id]; + info = IEEE80211_SKB_CB(skb); + + /* update the TX status info */ + if (result->status == TX_SUCCESS) { + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + info->flags |= IEEE80211_TX_STAT_ACK; + rate = wl1271_rate_to_idx(result->rate_class_index, wl->band); + retries = result->ack_failures; + } else if (result->status == TX_RETRY_EXCEEDED) { + wl->stats.excessive_retries++; + retries = result->ack_failures; + } + + info->status.rates[0].idx = rate; + info->status.rates[0].count = retries; + info->status.rates[0].flags = 0; + info->status.ack_signal = -1; + + wl->stats.retry_count += result->ack_failures; + + /* update security sequence number */ + wl->tx_security_seq += (result->lsb_security_sequence_number - + wl->tx_security_last_seq); + wl->tx_security_last_seq = result->lsb_security_sequence_number; + + /* remove private header from packet */ + skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); + + /* remove TKIP header space if present */ + if (info->control.hw_key && + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { + int hdrlen = ieee80211_get_hdrlen_from_skb(skb); + memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); + skb_pull(skb, WL1271_TKIP_IV_SPACE); + } + + wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" + " status 0x%x", + result->id, skb, result->ack_failures, + result->rate_class_index, result->status); + + /* return the packet to the stack */ + ieee80211_tx_status(wl->hw, skb); + wl1271_free_tx_id(wl, result->id); +} + +/* Called upon reception of a TX complete interrupt */ +void wl1271_tx_complete(struct wl1271 *wl) +{ + struct wl1271_acx_mem_map *memmap = + (struct wl1271_acx_mem_map *)wl->target_mem_map; + u32 count, fw_counter; + u32 i; + + /* read the tx results from the chipset */ + wl1271_read(wl, le32_to_cpu(memmap->tx_result), + wl->tx_res_if, sizeof(*wl->tx_res_if), false); + fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); + + /* write host counter to chipset (to ack) */ + wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + + offsetof(struct wl1271_tx_hw_res_if, + tx_result_host_counter), fw_counter); + + count = fw_counter - wl->tx_results_count; + wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); + + /* verify that the result buffer is not getting overrun */ + if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) + wl1271_warning("TX result overflow from chipset: %d", count); + + /* process the results */ + for (i = 0; i < count; i++) { + struct wl1271_tx_hw_res_descr *result; + u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK; + + /* process the packet */ + result = &(wl->tx_res_if->tx_results_queue[offset]); + wl1271_tx_complete_packet(wl, result); + + wl->tx_results_count++; + } +} + +/* caller must hold wl->mutex */ +void wl1271_tx_reset(struct wl1271 *wl) +{ + int i; + struct sk_buff *skb; + + /* TX failure */ + while ((skb = skb_dequeue(&wl->tx_queue))) { + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + ieee80211_tx_status(wl->hw, skb); + } + + /* + * Make sure the driver is at a consistent state, in case this + * function is called from a context other than interface removal. + */ + handle_tx_low_watermark(wl); + + for (i = 0; i < ACX_TX_DESCRIPTORS; i++) + if (wl->tx_frames[i] != NULL) { + skb = wl->tx_frames[i]; + wl1271_free_tx_id(wl, i); + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + ieee80211_tx_status(wl->hw, skb); + } +} + +#define WL1271_TX_FLUSH_TIMEOUT 500000 + +/* caller must *NOT* hold wl->mutex */ +void wl1271_tx_flush(struct wl1271 *wl) +{ + unsigned long timeout; + timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); + + while (!time_after(jiffies, timeout)) { + mutex_lock(&wl->mutex); + wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", + wl->tx_frames_cnt); + if ((wl->tx_frames_cnt == 0) && + skb_queue_empty(&wl->tx_queue)) { + mutex_unlock(&wl->mutex); + return; + } + mutex_unlock(&wl->mutex); + msleep(1); + } + + wl1271_warning("Unable to flush all TX buffers, timed out."); +} diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h new file mode 100644 index 000000000000..903e5dc69b7a --- /dev/null +++ b/drivers/net/wireless/wl12xx/tx.h @@ -0,0 +1,150 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TX_H__ +#define __TX_H__ + +#define TX_HW_BLOCK_SPARE 2 +#define TX_HW_BLOCK_SIZE 252 + +#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 +/* The chipset reference driver states, that the "aid" value 1 + * is for infra-BSS, but is still always used */ +#define TX_HW_DEFAULT_AID 1 + +#define TX_HW_ATTR_SAVE_RETRIES BIT(0) +#define TX_HW_ATTR_HEADER_PAD BIT(1) +#define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4)) +#define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \ + BIT(8) | BIT(9)) +#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) +#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) + +#define TX_HW_ATTR_OFST_SAVE_RETRIES 0 +#define TX_HW_ATTR_OFST_HEADER_PAD 1 +#define TX_HW_ATTR_OFST_SESSION_COUNTER 2 +#define TX_HW_ATTR_OFST_RATE_POLICY 5 +#define TX_HW_ATTR_OFST_LAST_WORD_PAD 10 +#define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12 + +#define TX_HW_RESULT_QUEUE_LEN 16 +#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf + +#define WL1271_TX_ALIGN_TO 4 +#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \ + ~(WL1271_TX_ALIGN_TO - 1)) +#define WL1271_TKIP_IV_SPACE 4 + +struct wl1271_tx_hw_descr { + /* Length of packet in words, including descriptor+header+data */ + __le16 length; + /* Number of extra memory blocks to allocate for this packet in + addition to the number of blocks derived from the packet length */ + u8 extra_mem_blocks; + /* Total number of memory blocks allocated by the host for this packet. + Must be equal or greater than the actual blocks number allocated by + HW!! */ + u8 total_mem_blocks; + /* Device time (in us) when the packet arrived to the driver */ + __le32 start_time; + /* Max delay in TUs until transmission. The last device time the + packet can be transmitted is: startTime+(1024*LifeTime) */ + __le16 life_time; + /* Bitwise fields - see TX_ATTR... definitions above. */ + __le16 tx_attr; + /* Packet identifier used also in the Tx-Result. */ + u8 id; + /* The packet TID value (as User-Priority) */ + u8 tid; + /* Identifier of the remote STA in IBSS, 1 in infra-BSS */ + u8 aid; + u8 reserved; +} __packed; + +enum wl1271_tx_hw_res_status { + TX_SUCCESS = 0, + TX_HW_ERROR = 1, + TX_DISABLED = 2, + TX_RETRY_EXCEEDED = 3, + TX_TIMEOUT = 4, + TX_KEY_NOT_FOUND = 5, + TX_PEER_NOT_FOUND = 6, + TX_SESSION_MISMATCH = 7 +}; + +struct wl1271_tx_hw_res_descr { + /* Packet Identifier - same value used in the Tx descriptor.*/ + u8 id; + /* The status of the transmission, indicating success or one of + several possible reasons for failure. */ + u8 status; + /* Total air access duration including all retrys and overheads.*/ + __le16 medium_usage; + /* The time passed from host xfer to Tx-complete.*/ + __le32 fw_handling_time; + /* Total media delay + (from 1st EDCA AIFS counter until TX Complete). */ + __le32 medium_delay; + /* LS-byte of last TKIP seq-num (saved per AC for recovery). */ + u8 lsb_security_sequence_number; + /* Retry count - number of transmissions without successful ACK.*/ + u8 ack_failures; + /* The rate that succeeded getting ACK + (Valid only if status=SUCCESS). */ + u8 rate_class_index; + /* for 4-byte alignment. */ + u8 spare; +} __packed; + +struct wl1271_tx_hw_res_if { + __le32 tx_result_fw_counter; + __le32 tx_result_host_counter; + struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; +} __packed; + +static inline int wl1271_tx_get_queue(int queue) +{ + switch (queue) { + case 0: + return CONF_TX_AC_VO; + case 1: + return CONF_TX_AC_VI; + case 2: + return CONF_TX_AC_BE; + case 3: + return CONF_TX_AC_BK; + default: + return CONF_TX_AC_BE; + } +} + +void wl1271_tx_work(struct work_struct *work); +void wl1271_tx_work_locked(struct wl1271 *wl); +void wl1271_tx_complete(struct wl1271 *wl); +void wl1271_tx_reset(struct wl1271 *wl); +void wl1271_tx_flush(struct wl1271 *wl); +u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); +u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); + +#endif diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h deleted file mode 100644 index ab53162b4343..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ /dev/null @@ -1,523 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_H__ -#define __WL1271_H__ - -#include -#include -#include -#include -#include -#include - -#include "wl1271_conf.h" -#include "wl1271_ini.h" - -#define DRIVER_NAME "wl1271" -#define DRIVER_PREFIX DRIVER_NAME ": " - -enum { - DEBUG_NONE = 0, - DEBUG_IRQ = BIT(0), - DEBUG_SPI = BIT(1), - DEBUG_BOOT = BIT(2), - DEBUG_MAILBOX = BIT(3), - DEBUG_TESTMODE = BIT(4), - DEBUG_EVENT = BIT(5), - DEBUG_TX = BIT(6), - DEBUG_RX = BIT(7), - DEBUG_SCAN = BIT(8), - DEBUG_CRYPT = BIT(9), - DEBUG_PSM = BIT(10), - DEBUG_MAC80211 = BIT(11), - DEBUG_CMD = BIT(12), - DEBUG_ACX = BIT(13), - DEBUG_SDIO = BIT(14), - DEBUG_FILTERS = BIT(15), - DEBUG_ADHOC = BIT(16), - DEBUG_ALL = ~0, -}; - -#define DEBUG_LEVEL (DEBUG_NONE) - -#define DEBUG_DUMP_LIMIT 1024 - -#define wl1271_error(fmt, arg...) \ - printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) - -#define wl1271_warning(fmt, arg...) \ - printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) - -#define wl1271_notice(fmt, arg...) \ - printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1271_info(fmt, arg...) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1271_debug(level, fmt, arg...) \ - do { \ - if (level & DEBUG_LEVEL) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ - } while (0) - -#define wl1271_dump(level, prefix, buf, len) \ - do { \ - if (level & DEBUG_LEVEL) \ - print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ - DUMP_PREFIX_OFFSET, 16, 1, \ - buf, \ - min_t(size_t, len, DEBUG_DUMP_LIMIT), \ - 0); \ - } while (0) - -#define wl1271_dump_ascii(level, prefix, buf, len) \ - do { \ - if (level & DEBUG_LEVEL) \ - print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ - DUMP_PREFIX_OFFSET, 16, 1, \ - buf, \ - min_t(size_t, len, DEBUG_DUMP_LIMIT), \ - true); \ - } while (0) - -#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ - CFG_BSSID_FILTER_EN | \ - CFG_MC_FILTER_EN) - -#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \ - CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \ - CFG_RX_CTL_EN | CFG_RX_BCN_EN | \ - CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) - -#define WL1271_FW_NAME "wl1271-fw.bin" -#define WL1271_NVS_NAME "wl1271-nvs.bin" - -#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) -#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) - -#define WL1271_CIPHER_SUITE_GEM 0x00147201 - -#define WL1271_BUSY_WORD_CNT 1 -#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) - -#define WL1271_ELP_HW_STATE_ASLEEP 0 -#define WL1271_ELP_HW_STATE_IRQ 1 - -#define WL1271_DEFAULT_BEACON_INT 100 -#define WL1271_DEFAULT_DTIM_PERIOD 1 - -#define ACX_TX_DESCRIPTORS 32 - -#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) - -enum wl1271_state { - WL1271_STATE_OFF, - WL1271_STATE_ON, - WL1271_STATE_PLT, -}; - -enum wl1271_partition_type { - PART_DOWN, - PART_WORK, - PART_DRPW, - - PART_TABLE_LEN -}; - -struct wl1271_partition { - u32 size; - u32 start; -}; - -struct wl1271_partition_set { - struct wl1271_partition mem; - struct wl1271_partition reg; - struct wl1271_partition mem2; - struct wl1271_partition mem3; -}; - -struct wl1271; - -/* FIXME: I'm not sure about this structure name */ -struct wl1271_chip { - u32 id; - char fw_ver[21]; -}; - -struct wl1271_stats { - struct acx_statistics *fw_stats; - unsigned long fw_stats_update; - - unsigned int retry_count; - unsigned int excessive_retries; -}; - -struct wl1271_debugfs { - struct dentry *rootdir; - struct dentry *fw_statistics; - - struct dentry *tx_internal_desc_overflow; - - struct dentry *rx_out_of_mem; - struct dentry *rx_hdr_overflow; - struct dentry *rx_hw_stuck; - struct dentry *rx_dropped; - struct dentry *rx_fcs_err; - struct dentry *rx_xfr_hint_trig; - struct dentry *rx_path_reset; - struct dentry *rx_reset_counter; - - struct dentry *dma_rx_requested; - struct dentry *dma_rx_errors; - struct dentry *dma_tx_requested; - struct dentry *dma_tx_errors; - - struct dentry *isr_cmd_cmplt; - struct dentry *isr_fiqs; - struct dentry *isr_rx_headers; - struct dentry *isr_rx_mem_overflow; - struct dentry *isr_rx_rdys; - struct dentry *isr_irqs; - struct dentry *isr_tx_procs; - struct dentry *isr_decrypt_done; - struct dentry *isr_dma0_done; - struct dentry *isr_dma1_done; - struct dentry *isr_tx_exch_complete; - struct dentry *isr_commands; - struct dentry *isr_rx_procs; - struct dentry *isr_hw_pm_mode_changes; - struct dentry *isr_host_acknowledges; - struct dentry *isr_pci_pm; - struct dentry *isr_wakeups; - struct dentry *isr_low_rssi; - - struct dentry *wep_addr_key_count; - struct dentry *wep_default_key_count; - /* skipping wep.reserved */ - struct dentry *wep_key_not_found; - struct dentry *wep_decrypt_fail; - struct dentry *wep_packets; - struct dentry *wep_interrupt; - - struct dentry *pwr_ps_enter; - struct dentry *pwr_elp_enter; - struct dentry *pwr_missing_bcns; - struct dentry *pwr_wake_on_host; - struct dentry *pwr_wake_on_timer_exp; - struct dentry *pwr_tx_with_ps; - struct dentry *pwr_tx_without_ps; - struct dentry *pwr_rcvd_beacons; - struct dentry *pwr_power_save_off; - struct dentry *pwr_enable_ps; - struct dentry *pwr_disable_ps; - struct dentry *pwr_fix_tsf_ps; - /* skipping cont_miss_bcns_spread for now */ - struct dentry *pwr_rcvd_awake_beacons; - - struct dentry *mic_rx_pkts; - struct dentry *mic_calc_failure; - - struct dentry *aes_encrypt_fail; - struct dentry *aes_decrypt_fail; - struct dentry *aes_encrypt_packets; - struct dentry *aes_decrypt_packets; - struct dentry *aes_encrypt_interrupt; - struct dentry *aes_decrypt_interrupt; - - struct dentry *event_heart_beat; - struct dentry *event_calibration; - struct dentry *event_rx_mismatch; - struct dentry *event_rx_mem_empty; - struct dentry *event_rx_pool; - struct dentry *event_oom_late; - struct dentry *event_phy_transmit_error; - struct dentry *event_tx_stuck; - - struct dentry *ps_pspoll_timeouts; - struct dentry *ps_upsd_timeouts; - struct dentry *ps_upsd_max_sptime; - struct dentry *ps_upsd_max_apturn; - struct dentry *ps_pspoll_max_apturn; - struct dentry *ps_pspoll_utilization; - struct dentry *ps_upsd_utilization; - - struct dentry *rxpipe_rx_prep_beacon_drop; - struct dentry *rxpipe_descr_host_int_trig_rx_data; - struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data; - struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data; - struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; - - struct dentry *tx_queue_len; - - struct dentry *retry_count; - struct dentry *excessive_retries; - struct dentry *gpio_power; -}; - -#define NUM_TX_QUEUES 4 -#define NUM_RX_PKT_DESC 8 - -/* FW status registers */ -struct wl1271_fw_status { - __le32 intr; - u8 fw_rx_counter; - u8 drv_rx_counter; - u8 reserved; - u8 tx_results_counter; - __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; - __le32 tx_released_blks[NUM_TX_QUEUES]; - __le32 fw_localtime; - __le32 padding[2]; -} __packed; - -struct wl1271_rx_mem_pool_addr { - u32 addr; - u32 addr_extra; -}; - -struct wl1271_scan { - struct cfg80211_scan_request *req; - bool *scanned_ch; - bool failed; - u8 state; - u8 ssid[IW_ESSID_MAX_SIZE+1]; - size_t ssid_len; -}; - -struct wl1271_if_operations { - void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len, - bool fixed); - void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len, - bool fixed); - void (*reset)(struct wl1271 *wl); - void (*init)(struct wl1271 *wl); - int (*power)(struct wl1271 *wl, bool enable); - struct device* (*dev)(struct wl1271 *wl); - void (*enable_irq)(struct wl1271 *wl); - void (*disable_irq)(struct wl1271 *wl); -}; - -struct wl1271 { - struct platform_device *plat_dev; - struct ieee80211_hw *hw; - bool mac80211_registered; - - void *if_priv; - - struct wl1271_if_operations *if_ops; - - void (*set_power)(bool enable); - int irq; - int ref_clock; - - spinlock_t wl_lock; - - enum wl1271_state state; - struct mutex mutex; - -#define WL1271_FLAG_STA_RATES_CHANGED (0) -#define WL1271_FLAG_STA_ASSOCIATED (1) -#define WL1271_FLAG_JOINED (2) -#define WL1271_FLAG_GPIO_POWER (3) -#define WL1271_FLAG_TX_QUEUE_STOPPED (4) -#define WL1271_FLAG_IN_ELP (5) -#define WL1271_FLAG_PSM (6) -#define WL1271_FLAG_PSM_REQUESTED (7) -#define WL1271_FLAG_IRQ_PENDING (8) -#define WL1271_FLAG_IRQ_RUNNING (9) -#define WL1271_FLAG_IDLE (10) -#define WL1271_FLAG_IDLE_REQUESTED (11) -#define WL1271_FLAG_PSPOLL_FAILURE (12) -#define WL1271_FLAG_STA_STATE_SENT (13) -#define WL1271_FLAG_FW_TX_BUSY (14) - unsigned long flags; - - struct wl1271_partition_set part; - - struct wl1271_chip chip; - - int cmd_box_addr; - int event_box_addr; - - u8 *fw; - size_t fw_len; - struct wl1271_nvs_file *nvs; - size_t nvs_len; - - s8 hw_pg_ver; - - u8 bssid[ETH_ALEN]; - u8 mac_addr[ETH_ALEN]; - u8 bss_type; - u8 set_bss_type; - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - int channel; - - struct wl1271_acx_mem_map *target_mem_map; - - /* Accounting for allocated / available TX blocks on HW */ - u32 tx_blocks_freed[NUM_TX_QUEUES]; - u32 tx_blocks_available; - u32 tx_results_count; - - /* Transmitted TX packets counter for chipset interface */ - u32 tx_packets_count; - - /* Time-offset between host and chipset clocks */ - s64 time_offset; - - /* Session counter for the chipset */ - int session_counter; - - /* Frames scheduled for transmission, not handled yet */ - struct sk_buff_head tx_queue; - - struct work_struct tx_work; - - /* Pending TX frames */ - unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)]; - struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; - int tx_frames_cnt; - - /* Security sequence number counters */ - u8 tx_security_last_seq; - s64 tx_security_seq; - - /* FW Rx counter */ - u32 rx_counter; - - /* Rx memory pool address */ - struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; - - /* Intermediate buffer, used for packet aggregation */ - u8 *aggr_buf; - - /* The target interrupt mask */ - struct work_struct irq_work; - - /* Hardware recovery work */ - struct work_struct recovery_work; - - /* The mbox event mask */ - u32 event_mask; - - /* Mailbox pointers */ - u32 mbox_ptr[2]; - - /* Are we currently scanning */ - struct wl1271_scan scan; - struct delayed_work scan_complete_work; - - /* Our association ID */ - u16 aid; - - /* - * currently configured rate set: - * bits 0-15 - 802.11abg rates - * bits 16-23 - 802.11n MCS index mask - * support only 1 stream, thus only 8 bits for the MCS rates (0-7). - */ - u32 sta_rate_set; - u32 basic_rate_set; - u32 basic_rate; - u32 rate_set; - - /* The current band */ - enum ieee80211_band band; - - /* Beaconing interval (needed for ad-hoc) */ - u32 beacon_int; - - /* Default key (for WEP) */ - u32 default_key; - - unsigned int filters; - unsigned int rx_config; - unsigned int rx_filter; - - struct completion *elp_compl; - struct delayed_work elp_work; - struct delayed_work pspoll_work; - - /* counter for ps-poll delivery failures */ - int ps_poll_failures; - - /* retry counter for PSM entries */ - u8 psm_entry_retry; - - /* in dBm */ - int power_level; - - int rssi_thold; - int last_rssi_event; - - struct wl1271_stats stats; - struct wl1271_debugfs debugfs; - - __le32 buffer_32; - u32 buffer_cmd; - u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; - - struct wl1271_fw_status *fw_status; - struct wl1271_tx_hw_res_if *tx_res_if; - - struct ieee80211_vif *vif; - - /* Current chipset configuration */ - struct conf_drv_settings conf; - - bool sg_enabled; - - bool enable_11a; - - struct list_head list; - - /* Most recently reported noise in dBm */ - s8 noise; -}; - -int wl1271_plt_start(struct wl1271 *wl); -int wl1271_plt_stop(struct wl1271 *wl); - -#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ - -#define SESSION_COUNTER_MAX 7 /* maximum value for the session counter */ - -#define WL1271_DEFAULT_POWER_LEVEL 0 - -#define WL1271_TX_QUEUE_LOW_WATERMARK 10 -#define WL1271_TX_QUEUE_HIGH_WATERMARK 25 - -/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power - on in case is has been shut down shortly before */ -#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ -#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ - -/* Macros to handle wl1271.sta_rate_set */ -#define HW_BG_RATES_MASK 0xffff -#define HW_HT_RATES_OFFSET 16 - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c deleted file mode 100644 index bd7f95f4eef3..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1271_acx.h" - -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_reg.h" -#include "wl1271_ps.h" - -int wl1271_acx_wake_up_conditions(struct wl1271 *wl) -{ - struct acx_wake_up_condition *wake_up; - int ret; - - wl1271_debug(DEBUG_ACX, "acx wake up conditions"); - - wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); - if (!wake_up) { - ret = -ENOMEM; - goto out; - } - - wake_up->wake_up_event = wl->conf.conn.wake_up_event; - wake_up->listen_interval = wl->conf.conn.listen_interval; - - ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, - wake_up, sizeof(*wake_up)); - if (ret < 0) { - wl1271_warning("could not set wake up conditions: %d", ret); - goto out; - } - -out: - kfree(wake_up); - return ret; -} - -int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) -{ - struct acx_sleep_auth *auth; - int ret; - - wl1271_debug(DEBUG_ACX, "acx sleep auth"); - - auth = kzalloc(sizeof(*auth), GFP_KERNEL); - if (!auth) { - ret = -ENOMEM; - goto out; - } - - auth->sleep_auth = sleep_auth; - - ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) - return ret; - -out: - kfree(auth); - return ret; -} - -int wl1271_acx_tx_power(struct wl1271 *wl, int power) -{ - struct acx_current_tx_power *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); - - if (power < 0 || power > 25) - return -EINVAL; - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->current_tx_power = power * 10; - - ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("configure of tx power failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_feature_cfg(struct wl1271 *wl) -{ - struct acx_feature_config *feature; - int ret; - - wl1271_debug(DEBUG_ACX, "acx feature cfg"); - - feature = kzalloc(sizeof(*feature), GFP_KERNEL); - if (!feature) { - ret = -ENOMEM; - goto out; - } - - /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ - feature->data_flow_options = 0; - feature->options = 0; - - ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG, - feature, sizeof(*feature)); - if (ret < 0) { - wl1271_error("Couldnt set HW encryption"); - goto out; - } - -out: - kfree(feature); - return ret; -} - -int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map, - size_t len) -{ - int ret; - - wl1271_debug(DEBUG_ACX, "acx mem map"); - - ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl) -{ - struct acx_rx_msdu_lifetime *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx rx msdu life time"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time); - ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set rx msdu life time: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter) -{ - struct acx_rx_config *rx_config; - int ret; - - wl1271_debug(DEBUG_ACX, "acx rx config"); - - rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); - if (!rx_config) { - ret = -ENOMEM; - goto out; - } - - rx_config->config_options = cpu_to_le32(config); - rx_config->filter_options = cpu_to_le32(filter); - - ret = wl1271_cmd_configure(wl, ACX_RX_CFG, - rx_config, sizeof(*rx_config)); - if (ret < 0) { - wl1271_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(rx_config); - return ret; -} - -int wl1271_acx_pd_threshold(struct wl1271 *wl) -{ - struct acx_packet_detection *pd; - int ret; - - wl1271_debug(DEBUG_ACX, "acx data pd threshold"); - - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) { - ret = -ENOMEM; - goto out; - } - - pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold); - - ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); - if (ret < 0) { - wl1271_warning("failed to set pd threshold: %d", ret); - goto out; - } - -out: - kfree(pd); - return ret; -} - -int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time) -{ - struct acx_slot *slot; - int ret; - - wl1271_debug(DEBUG_ACX, "acx slot"); - - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) { - ret = -ENOMEM; - goto out; - } - - slot->wone_index = STATION_WONE_INDEX; - slot->slot_time = slot_time; - - ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); - if (ret < 0) { - wl1271_warning("failed to set slot time: %d", ret); - goto out; - } - -out: - kfree(slot); - return ret; -} - -int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, - void *mc_list, u32 mc_list_len) -{ - struct acx_dot11_grp_addr_tbl *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx group address tbl"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* MAC filtering */ - acx->enabled = enable; - acx->num_groups = mc_list_len; - memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN); - - ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set group addr table: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_service_period_timeout(struct wl1271 *wl) -{ - struct acx_rx_timeout *rx_timeout; - int ret; - - rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); - if (!rx_timeout) { - ret = -ENOMEM; - goto out; - } - - wl1271_debug(DEBUG_ACX, "acx service period timeout"); - - rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout); - rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout); - - ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, - rx_timeout, sizeof(*rx_timeout)); - if (ret < 0) { - wl1271_warning("failed to set service period timeout: %d", - ret); - goto out; - } - -out: - kfree(rx_timeout); - return ret; -} - -int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold) -{ - struct acx_rts_threshold *rts; - int ret; - - wl1271_debug(DEBUG_ACX, "acx rts threshold"); - - rts = kzalloc(sizeof(*rts), GFP_KERNEL); - if (!rts) { - ret = -ENOMEM; - goto out; - } - - rts->threshold = cpu_to_le16(rts_threshold); - - ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); - if (ret < 0) { - wl1271_warning("failed to set rts threshold: %d", ret); - goto out; - } - -out: - kfree(rts); - return ret; -} - -int wl1271_acx_dco_itrim_params(struct wl1271 *wl) -{ - struct acx_dco_itrim_params *dco; - struct conf_itrim_settings *c = &wl->conf.itrim; - int ret; - - wl1271_debug(DEBUG_ACX, "acx dco itrim parameters"); - - dco = kzalloc(sizeof(*dco), GFP_KERNEL); - if (!dco) { - ret = -ENOMEM; - goto out; - } - - dco->enable = c->enable; - dco->timeout = cpu_to_le32(c->timeout); - - ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS, - dco, sizeof(*dco)); - if (ret < 0) { - wl1271_warning("failed to set dco itrim parameters: %d", ret); - goto out; - } - -out: - kfree(dco); - return ret; -} - -int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter) -{ - struct acx_beacon_filter_option *beacon_filter = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); - - if (enable_filter && - wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) - goto out; - - beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); - if (!beacon_filter) { - ret = -ENOMEM; - goto out; - } - - beacon_filter->enable = enable_filter; - - /* - * When set to zero, and the filter is enabled, beacons - * without the unicast TIM bit set are dropped. - */ - beacon_filter->max_num_beacons = 0; - - ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT, - beacon_filter, sizeof(*beacon_filter)); - if (ret < 0) { - wl1271_warning("failed to set beacon filter opt: %d", ret); - goto out; - } - -out: - kfree(beacon_filter); - return ret; -} - -int wl1271_acx_beacon_filter_table(struct wl1271 *wl) -{ - struct acx_beacon_filter_ie_table *ie_table; - int i, idx = 0; - int ret; - bool vendor_spec = false; - - wl1271_debug(DEBUG_ACX, "acx beacon filter table"); - - ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); - if (!ie_table) { - ret = -ENOMEM; - goto out; - } - - /* configure default beacon pass-through rules */ - ie_table->num_ie = 0; - for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) { - struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]); - ie_table->table[idx++] = r->ie; - ie_table->table[idx++] = r->rule; - - if (r->ie == WLAN_EID_VENDOR_SPECIFIC) { - /* only one vendor specific ie allowed */ - if (vendor_spec) - continue; - - /* for vendor specific rules configure the - additional fields */ - memcpy(&(ie_table->table[idx]), r->oui, - CONF_BCN_IE_OUI_LEN); - idx += CONF_BCN_IE_OUI_LEN; - ie_table->table[idx++] = r->type; - memcpy(&(ie_table->table[idx]), r->version, - CONF_BCN_IE_VER_LEN); - idx += CONF_BCN_IE_VER_LEN; - vendor_spec = true; - } - - ie_table->num_ie++; - } - - ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, - ie_table, sizeof(*ie_table)); - if (ret < 0) { - wl1271_warning("failed to set beacon filter table: %d", ret); - goto out; - } - -out: - kfree(ie_table); - return ret; -} - -#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff - -int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable) -{ - struct acx_conn_monit_params *acx; - u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE; - u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE; - int ret; - - wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s", - enable ? "enabled" : "disabled"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - if (enable) { - threshold = wl->conf.conn.synch_fail_thold; - timeout = wl->conf.conn.bss_lose_timeout; - } - - acx->synch_fail_thold = cpu_to_le32(threshold); - acx->bss_lose_timeout = cpu_to_le32(timeout); - - ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set connection monitor " - "parameters: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - - -int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) -{ - struct acx_bt_wlan_coex *pta; - int ret; - - wl1271_debug(DEBUG_ACX, "acx sg enable"); - - pta = kzalloc(sizeof(*pta), GFP_KERNEL); - if (!pta) { - ret = -ENOMEM; - goto out; - } - - if (enable) - pta->enable = wl->conf.sg.state; - else - pta->enable = CONF_SG_DISABLE; - - ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); - if (ret < 0) { - wl1271_warning("failed to set softgemini enable: %d", ret); - goto out; - } - -out: - kfree(pta); - return ret; -} - -int wl1271_acx_sg_cfg(struct wl1271 *wl) -{ - struct acx_bt_wlan_coex_param *param; - struct conf_sg_settings *c = &wl->conf.sg; - int i, ret; - - wl1271_debug(DEBUG_ACX, "acx sg cfg"); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (!param) { - ret = -ENOMEM; - goto out; - } - - /* BT-WLAN coext parameters */ - for (i = 0; i < CONF_SG_PARAMS_MAX; i++) - param->params[i] = cpu_to_le32(c->params[i]); - param->param_idx = CONF_SG_PARAMS_ALL; - - ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); - if (ret < 0) { - wl1271_warning("failed to set sg config: %d", ret); - goto out; - } - -out: - kfree(param); - return ret; -} - -int wl1271_acx_cca_threshold(struct wl1271 *wl) -{ - struct acx_energy_detection *detection; - int ret; - - wl1271_debug(DEBUG_ACX, "acx cca threshold"); - - detection = kzalloc(sizeof(*detection), GFP_KERNEL); - if (!detection) { - ret = -ENOMEM; - goto out; - } - - detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold); - detection->tx_energy_detection = wl->conf.tx.tx_energy_detection; - - ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, - detection, sizeof(*detection)); - if (ret < 0) { - wl1271_warning("failed to set cca threshold: %d", ret); - return ret; - } - -out: - kfree(detection); - return ret; -} - -int wl1271_acx_bcn_dtim_options(struct wl1271 *wl) -{ - struct acx_beacon_broadcast *bb; - int ret; - - wl1271_debug(DEBUG_ACX, "acx bcn dtim options"); - - bb = kzalloc(sizeof(*bb), GFP_KERNEL); - if (!bb) { - ret = -ENOMEM; - goto out; - } - - bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout); - bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout); - bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps; - bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold; - - ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); - if (ret < 0) { - wl1271_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(bb); - return ret; -} - -int wl1271_acx_aid(struct wl1271 *wl, u16 aid) -{ - struct acx_aid *acx_aid; - int ret; - - wl1271_debug(DEBUG_ACX, "acx aid"); - - acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); - if (!acx_aid) { - ret = -ENOMEM; - goto out; - } - - acx_aid->aid = cpu_to_le16(aid); - - ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); - if (ret < 0) { - wl1271_warning("failed to set aid: %d", ret); - goto out; - } - -out: - kfree(acx_aid); - return ret; -} - -int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask) -{ - struct acx_event_mask *mask; - int ret; - - wl1271_debug(DEBUG_ACX, "acx event mbox mask"); - - mask = kzalloc(sizeof(*mask), GFP_KERNEL); - if (!mask) { - ret = -ENOMEM; - goto out; - } - - /* high event mask is unused */ - mask->high_event_mask = cpu_to_le32(0xffffffff); - mask->event_mask = cpu_to_le32(event_mask); - - ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK, - mask, sizeof(*mask)); - if (ret < 0) { - wl1271_warning("failed to set acx_event_mbox_mask: %d", ret); - goto out; - } - -out: - kfree(mask); - return ret; -} - -int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble) -{ - struct acx_preamble *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx_set_preamble"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->preamble = preamble; - - ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of preamble failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_cts_protect(struct wl1271 *wl, - enum acx_ctsprotect_type ctsprotect) -{ - struct acx_ctsprotect *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ctsprotect = ctsprotect; - - ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of ctsprotect failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) -{ - int ret; - - wl1271_debug(DEBUG_ACX, "acx statistics"); - - ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, - sizeof(*stats)); - if (ret < 0) { - wl1271_warning("acx statistics failed: %d", ret); - return -ENOMEM; - } - - return 0; -} - -int wl1271_acx_rate_policies(struct wl1271 *wl) -{ - struct acx_rate_policy *acx; - struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; - int idx = 0; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rate policies"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* configure one basic rate class */ - idx = ACX_TX_BASIC_RATE; - acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate); - acx->rate_class[idx].short_retry_limit = c->short_retry_limit; - acx->rate_class[idx].long_retry_limit = c->long_retry_limit; - acx->rate_class[idx].aflags = c->aflags; - - /* configure one AP supported rate class */ - idx = ACX_TX_AP_FULL_RATE; - acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set); - acx->rate_class[idx].short_retry_limit = c->short_retry_limit; - acx->rate_class[idx].long_retry_limit = c->long_retry_limit; - acx->rate_class[idx].aflags = c->aflags; - - acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); - - ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of rate policies failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifsn, u16 txop) -{ - struct acx_ac_cfg *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " - "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ac = ac; - acx->cw_min = cw_min; - acx->cw_max = cpu_to_le16(cw_max); - acx->aifsn = aifsn; - acx->tx_op_limit = cpu_to_le16(txop); - - ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx ac cfg failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, - u8 tsid, u8 ps_scheme, u8 ack_policy, - u32 apsd_conf0, u32 apsd_conf1) -{ - struct acx_tid_config *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx tid config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->queue_id = queue_id; - acx->channel_type = channel_type; - acx->tsid = tsid; - acx->ps_scheme = ps_scheme; - acx->ack_policy = ack_policy; - acx->apsd_conf[0] = cpu_to_le32(apsd_conf0); - acx->apsd_conf[1] = cpu_to_le32(apsd_conf1); - - ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of tid config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_frag_threshold(struct wl1271 *wl) -{ - struct acx_frag_threshold *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx frag threshold"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold); - ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of frag threshold failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_tx_config_options(struct wl1271 *wl) -{ - struct acx_tx_config_options *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx tx config options"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout); - acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold); - ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of tx options failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_mem_cfg(struct wl1271 *wl) -{ - struct wl1271_acx_config_memory *mem_conf; - int ret; - - wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); - - mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); - if (!mem_conf) { - ret = -ENOMEM; - goto out; - } - - /* memory config */ - mem_conf->num_stations = DEFAULT_NUM_STATIONS; - mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; - mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; - mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; - mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); - - ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, - sizeof(*mem_conf)); - if (ret < 0) { - wl1271_warning("wl1271 mem config failed: %d", ret); - goto out; - } - -out: - kfree(mem_conf); - return ret; -} - -int wl1271_acx_init_mem_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_mem_cfg(wl); - if (ret < 0) - return ret; - - wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), - GFP_KERNEL); - if (!wl->target_mem_map) { - wl1271_error("couldn't allocate target memory map"); - return -ENOMEM; - } - - /* we now ask for the firmware built memory map */ - ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map, - sizeof(struct wl1271_acx_mem_map)); - if (ret < 0) { - wl1271_error("couldn't retrieve firmware memory map"); - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - return ret; - } - - /* initialize TX block book keeping */ - wl->tx_blocks_available = - le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks); - wl1271_debug(DEBUG_TX, "available tx blocks: %d", - wl->tx_blocks_available); - - return 0; -} - -int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) -{ - struct wl1271_acx_rx_config_opt *rx_conf; - int ret; - - wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config"); - - rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL); - if (!rx_conf) { - ret = -ENOMEM; - goto out; - } - - rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold); - rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout); - rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold); - rx_conf->queue_type = wl->conf.rx.queue_type; - - ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf, - sizeof(*rx_conf)); - if (ret < 0) { - wl1271_warning("wl1271 rx config opt failed: %d", ret); - goto out; - } - -out: - kfree(rx_conf); - return ret; -} - -int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable) -{ - struct wl1271_acx_bet_enable *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx bet enable"); - - if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE) - goto out; - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE; - acx->max_consecutive = wl->conf.conn.bet_max_consecutive; - - ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx bet enable failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) -{ - struct wl1271_acx_arp_filter *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->version = ACX_IPV4_VERSION; - acx->enable = enable; - - if (enable == true) - memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); - - ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set arp ip filter: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_pm_config(struct wl1271 *wl) -{ - struct wl1271_acx_pm_config *acx = NULL; - struct conf_pm_config_settings *c = &wl->conf.pm_config; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx pm config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time); - acx->host_fast_wakeup_support = c->host_fast_wakeup_support; - - ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx pm config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable) -{ - struct wl1271_acx_keep_alive_mode *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->enabled = enable; - - ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx keep alive mode failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid) -{ - struct wl1271_acx_keep_alive_config *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx keep alive config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval); - acx->index = index; - acx->tpl_validation = tpl_valid; - acx->trigger = ACX_KEEP_ALIVE_NO_TX; - - ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx keep alive config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, - s16 thold, u8 hyst) -{ - struct wl1271_acx_rssi_snr_trigger *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - wl->last_rssi_event = -1; - - acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing); - acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON; - acx->type = WL1271_ACX_TRIG_TYPE_EDGE; - if (enable) - acx->enable = WL1271_ACX_TRIG_ENABLE; - else - acx->enable = WL1271_ACX_TRIG_DISABLE; - - acx->index = WL1271_ACX_TRIG_IDX_RSSI; - acx->dir = WL1271_ACX_TRIG_DIR_BIDIR; - acx->threshold = cpu_to_le16(thold); - acx->hysteresis = hyst; - - ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx rssi snr trigger setting failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl) -{ - struct wl1271_acx_rssi_snr_avg_weights *acx = NULL; - struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->rssi_beacon = c->avg_weight_rssi_beacon; - acx->rssi_data = c->avg_weight_rssi_data; - acx->snr_beacon = c->avg_weight_snr_beacon; - acx->snr_data = c->avg_weight_snr_data; - - ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx rssi snr trigger weights failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, - struct ieee80211_sta_ht_cap *ht_cap, - bool allow_ht_operation) -{ - struct wl1271_acx_ht_capabilities *acx; - u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* Allow HT Operation ? */ - if (allow_ht_operation) { - acx->ht_capabilites = - WL1271_ACX_FW_CAP_HT_OPERATION; - if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) - acx->ht_capabilites |= - WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; - if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) - acx->ht_capabilites |= - WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; - if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) - acx->ht_capabilites |= - WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; - - /* get data from A-MPDU parameters field */ - acx->ampdu_max_length = ht_cap->ampdu_factor; - acx->ampdu_min_spacing = ht_cap->ampdu_density; - - memcpy(acx->mac_address, mac_address, ETH_ALEN); - } else { /* HT operations are not allowed */ - acx->ht_capabilites = 0; - } - - ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx ht capabilities setting failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_set_ht_information(struct wl1271 *wl, - u16 ht_operation_mode) -{ - struct wl1271_acx_ht_information *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx ht information setting"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ht_protection = - (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); - acx->rifs_mode = 0; - acx->gf_protection = 0; - acx->ht_tx_burst_limit = 0; - acx->dual_cts_protection = 0; - - ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx)); - - if (ret < 0) { - wl1271_warning("acx ht information setting failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) -{ - struct wl1271_acx_fw_tsf_information *tsf_info; - int ret; - - tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); - if (!tsf_info) { - ret = -ENOMEM; - goto out; - } - - ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, - tsf_info, sizeof(*tsf_info)); - if (ret < 0) { - wl1271_warning("acx tsf info interrogate failed"); - goto out; - } - - *mactime = le32_to_cpu(tsf_info->current_tsf_low) | - ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32); - -out: - kfree(tsf_info); - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h deleted file mode 100644 index b7c490845f3e..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ /dev/null @@ -1,1185 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_ACX_H__ -#define __WL1271_ACX_H__ - -#include "wl1271.h" -#include "wl1271_cmd.h" - -/************************************************************************* - - Host Interrupt Register (WiLink -> Host) - -**************************************************************************/ -/* HW Initiated interrupt Watchdog timer expiration */ -#define WL1271_ACX_INTR_WATCHDOG BIT(0) -/* Init sequence is done (masked interrupt, detection through polling only ) */ -#define WL1271_ACX_INTR_INIT_COMPLETE BIT(1) -/* Event was entered to Event MBOX #A*/ -#define WL1271_ACX_INTR_EVENT_A BIT(2) -/* Event was entered to Event MBOX #B*/ -#define WL1271_ACX_INTR_EVENT_B BIT(3) -/* Command processing completion*/ -#define WL1271_ACX_INTR_CMD_COMPLETE BIT(4) -/* Signaling the host on HW wakeup */ -#define WL1271_ACX_INTR_HW_AVAILABLE BIT(5) -/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */ -#define WL1271_ACX_INTR_DATA BIT(6) -/* Trace meassge on MBOX #A */ -#define WL1271_ACX_INTR_TRACE_A BIT(7) -/* Trace meassge on MBOX #B */ -#define WL1271_ACX_INTR_TRACE_B BIT(8) - -#define WL1271_ACX_INTR_ALL 0xFFFFFFFF -#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_INIT_COMPLETE | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_CMD_COMPLETE | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -/* Target's information element */ -struct acx_header { - struct wl1271_cmd_header cmd; - - /* acx (or information element) header */ - __le16 id; - - /* payload length (not including headers */ - __le16 len; -} __packed; - -struct acx_error_counter { - struct acx_header header; - - /* The number of PLCP errors since the last time this */ - /* information element was interrogated. This field is */ - /* automatically cleared when it is interrogated.*/ - __le32 PLCP_error; - - /* The number of FCS errors since the last time this */ - /* information element was interrogated. This field is */ - /* automatically cleared when it is interrogated.*/ - __le32 FCS_error; - - /* The number of MPDUs without PLCP header errors received*/ - /* since the last time this information element was interrogated. */ - /* This field is automatically cleared when it is interrogated.*/ - __le32 valid_frame; - - /* the number of missed sequence numbers in the squentially */ - /* values of frames seq numbers */ - __le32 seq_num_miss; -} __packed; - -enum wl1271_psm_mode { - /* Active mode */ - WL1271_PSM_CAM = 0, - - /* Power save mode */ - WL1271_PSM_PS = 1, - - /* Extreme low power */ - WL1271_PSM_ELP = 2, -}; - -struct acx_sleep_auth { - struct acx_header header; - - /* The sleep level authorization of the device. */ - /* 0 - Always active*/ - /* 1 - Power down mode: light / fast sleep*/ - /* 2 - ELP mode: Deep / Max sleep*/ - u8 sleep_auth; - u8 padding[3]; -} __packed; - -enum { - HOSTIF_PCI_MASTER_HOST_INDIRECT, - HOSTIF_PCI_MASTER_HOST_DIRECT, - HOSTIF_SLAVE, - HOSTIF_PKT_RING, - HOSTIF_DONTCARE = 0xFF -}; - -#define DEFAULT_UCAST_PRIORITY 0 -#define DEFAULT_RX_Q_PRIORITY 0 -#define DEFAULT_NUM_STATIONS 1 -#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ -#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ -#define TRACE_BUFFER_MAX_SIZE 256 - -#define DP_RX_PACKET_RING_CHUNK_SIZE 1600 -#define DP_TX_PACKET_RING_CHUNK_SIZE 1600 -#define DP_RX_PACKET_RING_CHUNK_NUM 2 -#define DP_TX_PACKET_RING_CHUNK_NUM 2 -#define DP_TX_COMPLETE_TIME_OUT 20 - -#define TX_MSDU_LIFETIME_MIN 0 -#define TX_MSDU_LIFETIME_MAX 3000 -#define TX_MSDU_LIFETIME_DEF 512 -#define RX_MSDU_LIFETIME_MIN 0 -#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF -#define RX_MSDU_LIFETIME_DEF 512000 - -struct acx_rx_msdu_lifetime { - struct acx_header header; - - /* - * The maximum amount of time, in TU, before the - * firmware discards the MSDU. - */ - __le32 lifetime; -} __packed; - -/* - * RX Config Options Table - * Bit Definition - * === ========== - * 31:14 Reserved - * 13 Copy RX Status - when set, write three receive status words - * to top of rx'd MPDUs. - * When cleared, do not write three status words (added rev 1.5) - * 12 Reserved - * 11 RX Complete upon FCS error - when set, give rx complete - * interrupt for FCS errors, after the rx filtering, e.g. unicast - * frames not to us with FCS error will not generate an interrupt. - * 10 SSID Filter Enable - When set, the WiLink discards all beacon, - * probe request, and probe response frames with an SSID that does - * not match the SSID specified by the host in the START/JOIN - * command. - * When clear, the WiLink receives frames with any SSID. - * 9 Broadcast Filter Enable - When set, the WiLink discards all - * broadcast frames. When clear, the WiLink receives all received - * broadcast frames. - * 8:6 Reserved - * 5 BSSID Filter Enable - When set, the WiLink discards any frames - * with a BSSID that does not match the BSSID specified by the - * host. - * When clear, the WiLink receives frames from any BSSID. - * 4 MAC Addr Filter - When set, the WiLink discards any frames - * with a destination address that does not match the MAC address - * of the adaptor. - * When clear, the WiLink receives frames destined to any MAC - * address. - * 3 Promiscuous - When set, the WiLink receives all valid frames - * (i.e., all frames that pass the FCS check). - * When clear, only frames that pass the other filters specified - * are received. - * 2 FCS - When set, the WiLink includes the FCS with the received - * frame. - * When cleared, the FCS is discarded. - * 1 PLCP header - When set, write all data from baseband to frame - * buffer including PHY header. - * 0 Reserved - Always equal to 0. - * - * RX Filter Options Table - * Bit Definition - * === ========== - * 31:12 Reserved - Always equal to 0. - * 11 Association - When set, the WiLink receives all association - * related frames (association request/response, reassocation - * request/response, and disassociation). When clear, these frames - * are discarded. - * 10 Auth/De auth - When set, the WiLink receives all authentication - * and de-authentication frames. When clear, these frames are - * discarded. - * 9 Beacon - When set, the WiLink receives all beacon frames. - * When clear, these frames are discarded. - * 8 Contention Free - When set, the WiLink receives all contention - * free frames. - * When clear, these frames are discarded. - * 7 Control - When set, the WiLink receives all control frames. - * When clear, these frames are discarded. - * 6 Data - When set, the WiLink receives all data frames. - * When clear, these frames are discarded. - * 5 FCS Error - When set, the WiLink receives frames that have FCS - * errors. - * When clear, these frames are discarded. - * 4 Management - When set, the WiLink receives all management - * frames. - * When clear, these frames are discarded. - * 3 Probe Request - When set, the WiLink receives all probe request - * frames. - * When clear, these frames are discarded. - * 2 Probe Response - When set, the WiLink receives all probe - * response frames. - * When clear, these frames are discarded. - * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK - * frames. - * When clear, these frames are discarded. - * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames - * that have reserved frame types and sub types as defined by the - * 802.11 specification. - * When clear, these frames are discarded. - */ -struct acx_rx_config { - struct acx_header header; - - __le32 config_options; - __le32 filter_options; -} __packed; - -struct acx_packet_detection { - struct acx_header header; - - __le32 threshold; -} __packed; - - -enum acx_slot_type { - SLOT_TIME_LONG = 0, - SLOT_TIME_SHORT = 1, - DEFAULT_SLOT_TIME = SLOT_TIME_SHORT, - MAX_SLOT_TIMES = 0xFF -}; - -#define STATION_WONE_INDEX 0 - -struct acx_slot { - struct acx_header header; - - u8 wone_index; /* Reserved */ - u8 slot_time; - u8 reserved[6]; -} __packed; - - -#define ACX_MC_ADDRESS_GROUP_MAX (8) -#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX) - -struct acx_dot11_grp_addr_tbl { - struct acx_header header; - - u8 enabled; - u8 num_groups; - u8 pad[2]; - u8 mac_table[ADDRESS_GROUP_MAX_LEN]; -} __packed; - -struct acx_rx_timeout { - struct acx_header header; - - __le16 ps_poll_timeout; - __le16 upsd_timeout; -} __packed; - -struct acx_rts_threshold { - struct acx_header header; - - __le16 threshold; - u8 pad[2]; -} __packed; - -struct acx_beacon_filter_option { - struct acx_header header; - - u8 enable; - - /* - * The number of beacons without the unicast TIM - * bit set that the firmware buffers before - * signaling the host about ready frames. - * When set to 0 and the filter is enabled, beacons - * without the unicast TIM bit set are dropped. - */ - u8 max_num_beacons; - u8 pad[2]; -} __packed; - -/* - * ACXBeaconFilterEntry (not 221) - * Byte Offset Size (Bytes) Definition - * =========== ============ ========== - * 0 1 IE identifier - * 1 1 Treatment bit mask - * - * ACXBeaconFilterEntry (221) - * Byte Offset Size (Bytes) Definition - * =========== ============ ========== - * 0 1 IE identifier - * 1 1 Treatment bit mask - * 2 3 OUI - * 5 1 Type - * 6 2 Version - * - * - * Treatment bit mask - The information element handling: - * bit 0 - The information element is compared and transferred - * in case of change. - * bit 1 - The information element is transferred to the host - * with each appearance or disappearance. - * Note that both bits can be set at the same time. - */ -#define BEACON_FILTER_TABLE_MAX_IE_NUM (32) -#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6) -#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2) -#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6) -#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \ - BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \ - (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ - BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) - -struct acx_beacon_filter_ie_table { - struct acx_header header; - - u8 num_ie; - u8 pad[3]; - u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; -} __packed; - -struct acx_conn_monit_params { - struct acx_header header; - - __le32 synch_fail_thold; /* number of beacons missed */ - __le32 bss_lose_timeout; /* number of TU's from synch fail */ -} __packed; - -struct acx_bt_wlan_coex { - struct acx_header header; - - u8 enable; - u8 pad[3]; -} __packed; - -struct acx_bt_wlan_coex_param { - struct acx_header header; - - __le32 params[CONF_SG_PARAMS_MAX]; - u8 param_idx; - u8 padding[3]; -} __packed; - -struct acx_dco_itrim_params { - struct acx_header header; - - u8 enable; - u8 padding[3]; - __le32 timeout; -} __packed; - -struct acx_energy_detection { - struct acx_header header; - - /* The RX Clear Channel Assessment threshold in the PHY */ - __le16 rx_cca_threshold; - u8 tx_energy_detection; - u8 pad; -} __packed; - -struct acx_beacon_broadcast { - struct acx_header header; - - __le16 beacon_rx_timeout; - __le16 broadcast_timeout; - - /* Enables receiving of broadcast packets in PS mode */ - u8 rx_broadcast_in_ps; - - /* Consecutive PS Poll failures before updating the host */ - u8 ps_poll_threshold; - u8 pad[2]; -} __packed; - -struct acx_event_mask { - struct acx_header header; - - __le32 event_mask; - __le32 high_event_mask; /* Unused */ -} __packed; - -#define CFG_RX_FCS BIT(2) -#define CFG_RX_ALL_GOOD BIT(3) -#define CFG_UNI_FILTER_EN BIT(4) -#define CFG_BSSID_FILTER_EN BIT(5) -#define CFG_MC_FILTER_EN BIT(6) -#define CFG_MC_ADDR0_EN BIT(7) -#define CFG_MC_ADDR1_EN BIT(8) -#define CFG_BC_REJECT_EN BIT(9) -#define CFG_SSID_FILTER_EN BIT(10) -#define CFG_RX_INT_FCS_ERROR BIT(11) -#define CFG_RX_INT_ENCRYPTED BIT(12) -#define CFG_RX_WR_RX_STATUS BIT(13) -#define CFG_RX_FILTER_NULTI BIT(14) -#define CFG_RX_RESERVE BIT(15) -#define CFG_RX_TIMESTAMP_TSF BIT(16) - -#define CFG_RX_RSV_EN BIT(0) -#define CFG_RX_RCTS_ACK BIT(1) -#define CFG_RX_PRSP_EN BIT(2) -#define CFG_RX_PREQ_EN BIT(3) -#define CFG_RX_MGMT_EN BIT(4) -#define CFG_RX_FCS_ERROR BIT(5) -#define CFG_RX_DATA_EN BIT(6) -#define CFG_RX_CTL_EN BIT(7) -#define CFG_RX_CF_EN BIT(8) -#define CFG_RX_BCN_EN BIT(9) -#define CFG_RX_AUTH_EN BIT(10) -#define CFG_RX_ASSOC_EN BIT(11) - -#define SCAN_PASSIVE BIT(0) -#define SCAN_5GHZ_BAND BIT(1) -#define SCAN_TRIGGERED BIT(2) -#define SCAN_PRIORITY_HIGH BIT(3) - -/* When set, disable HW encryption */ -#define DF_ENCRYPTION_DISABLE 0x01 -#define DF_SNIFF_MODE_ENABLE 0x80 - -struct acx_feature_config { - struct acx_header header; - - __le32 options; - __le32 data_flow_options; -} __packed; - -struct acx_current_tx_power { - struct acx_header header; - - u8 current_tx_power; - u8 padding[3]; -} __packed; - -struct acx_wake_up_condition { - struct acx_header header; - - u8 wake_up_event; /* Only one bit can be set */ - u8 listen_interval; - u8 pad[2]; -} __packed; - -struct acx_aid { - struct acx_header header; - - /* - * To be set when associated with an AP. - */ - __le16 aid; - u8 pad[2]; -} __packed; - -enum acx_preamble_type { - ACX_PREAMBLE_LONG = 0, - ACX_PREAMBLE_SHORT = 1 -}; - -struct acx_preamble { - struct acx_header header; - - /* - * When set, the WiLink transmits the frames with a short preamble and - * when cleared, the WiLink transmits the frames with a long preamble. - */ - u8 preamble; - u8 padding[3]; -} __packed; - -enum acx_ctsprotect_type { - CTSPROTECT_DISABLE = 0, - CTSPROTECT_ENABLE = 1 -}; - -struct acx_ctsprotect { - struct acx_header header; - u8 ctsprotect; - u8 padding[3]; -} __packed; - -struct acx_tx_statistics { - __le32 internal_desc_overflow; -} __packed; - -struct acx_rx_statistics { - __le32 out_of_mem; - __le32 hdr_overflow; - __le32 hw_stuck; - __le32 dropped; - __le32 fcs_err; - __le32 xfr_hint_trig; - __le32 path_reset; - __le32 reset_counter; -} __packed; - -struct acx_dma_statistics { - __le32 rx_requested; - __le32 rx_errors; - __le32 tx_requested; - __le32 tx_errors; -} __packed; - -struct acx_isr_statistics { - /* host command complete */ - __le32 cmd_cmplt; - - /* fiqisr() */ - __le32 fiqs; - - /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ - __le32 rx_headers; - - /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ - __le32 rx_completes; - - /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ - __le32 rx_mem_overflow; - - /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ - __le32 rx_rdys; - - /* irqisr() */ - __le32 irqs; - - /* (INT_STS_ND & INT_TRIG_TX_PROC) */ - __le32 tx_procs; - - /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ - __le32 decrypt_done; - - /* (INT_STS_ND & INT_TRIG_DMA0) */ - __le32 dma0_done; - - /* (INT_STS_ND & INT_TRIG_DMA1) */ - __le32 dma1_done; - - /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ - __le32 tx_exch_complete; - - /* (INT_STS_ND & INT_TRIG_COMMAND) */ - __le32 commands; - - /* (INT_STS_ND & INT_TRIG_RX_PROC) */ - __le32 rx_procs; - - /* (INT_STS_ND & INT_TRIG_PM_802) */ - __le32 hw_pm_mode_changes; - - /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ - __le32 host_acknowledges; - - /* (INT_STS_ND & INT_TRIG_PM_PCI) */ - __le32 pci_pm; - - /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ - __le32 wakeups; - - /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ - __le32 low_rssi; -} __packed; - -struct acx_wep_statistics { - /* WEP address keys configured */ - __le32 addr_key_count; - - /* default keys configured */ - __le32 default_key_count; - - __le32 reserved; - - /* number of times that WEP key not found on lookup */ - __le32 key_not_found; - - /* number of times that WEP key decryption failed */ - __le32 decrypt_fail; - - /* WEP packets decrypted */ - __le32 packets; - - /* WEP decrypt interrupts */ - __le32 interrupt; -} __packed; - -#define ACX_MISSED_BEACONS_SPREAD 10 - -struct acx_pwr_statistics { - /* the amount of enters into power save mode (both PD & ELP) */ - __le32 ps_enter; - - /* the amount of enters into ELP mode */ - __le32 elp_enter; - - /* the amount of missing beacon interrupts to the host */ - __le32 missing_bcns; - - /* the amount of wake on host-access times */ - __le32 wake_on_host; - - /* the amount of wake on timer-expire */ - __le32 wake_on_timer_exp; - - /* the number of packets that were transmitted with PS bit set */ - __le32 tx_with_ps; - - /* the number of packets that were transmitted with PS bit clear */ - __le32 tx_without_ps; - - /* the number of received beacons */ - __le32 rcvd_beacons; - - /* the number of entering into PowerOn (power save off) */ - __le32 power_save_off; - - /* the number of entries into power save mode */ - __le16 enable_ps; - - /* - * the number of exits from power save, not including failed PS - * transitions - */ - __le16 disable_ps; - - /* - * the number of times the TSF counter was adjusted because - * of drift - */ - __le32 fix_tsf_ps; - - /* Gives statistics about the spread continuous missed beacons. - * The 16 LSB are dedicated for the PS mode. - * The 16 MSB are dedicated for the PS mode. - * cont_miss_bcns_spread[0] - single missed beacon. - * cont_miss_bcns_spread[1] - two continuous missed beacons. - * cont_miss_bcns_spread[2] - three continuous missed beacons. - * ... - * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. - */ - __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; - - /* the number of beacons in awake mode */ - __le32 rcvd_awake_beacons; -} __packed; - -struct acx_mic_statistics { - __le32 rx_pkts; - __le32 calc_failure; -} __packed; - -struct acx_aes_statistics { - __le32 encrypt_fail; - __le32 decrypt_fail; - __le32 encrypt_packets; - __le32 decrypt_packets; - __le32 encrypt_interrupt; - __le32 decrypt_interrupt; -} __packed; - -struct acx_event_statistics { - __le32 heart_beat; - __le32 calibration; - __le32 rx_mismatch; - __le32 rx_mem_empty; - __le32 rx_pool; - __le32 oom_late; - __le32 phy_transmit_error; - __le32 tx_stuck; -} __packed; - -struct acx_ps_statistics { - __le32 pspoll_timeouts; - __le32 upsd_timeouts; - __le32 upsd_max_sptime; - __le32 upsd_max_apturn; - __le32 pspoll_max_apturn; - __le32 pspoll_utilization; - __le32 upsd_utilization; -} __packed; - -struct acx_rxpipe_statistics { - __le32 rx_prep_beacon_drop; - __le32 descr_host_int_trig_rx_data; - __le32 beacon_buffer_thres_host_int_trig_rx_data; - __le32 missed_beacon_host_int_trig_rx_data; - __le32 tx_xfr_host_int_trig_rx_data; -} __packed; - -struct acx_statistics { - struct acx_header header; - - struct acx_tx_statistics tx; - struct acx_rx_statistics rx; - struct acx_dma_statistics dma; - struct acx_isr_statistics isr; - struct acx_wep_statistics wep; - struct acx_pwr_statistics pwr; - struct acx_aes_statistics aes; - struct acx_mic_statistics mic; - struct acx_event_statistics event; - struct acx_ps_statistics ps; - struct acx_rxpipe_statistics rxpipe; -} __packed; - -struct acx_rate_class { - __le32 enabled_rates; - u8 short_retry_limit; - u8 long_retry_limit; - u8 aflags; - u8 reserved; -}; - -#define ACX_TX_BASIC_RATE 0 -#define ACX_TX_AP_FULL_RATE 1 -#define ACX_TX_RATE_POLICY_CNT 2 -struct acx_rate_policy { - struct acx_header header; - - __le32 rate_class_cnt; - struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES]; -} __packed; - -struct acx_ac_cfg { - struct acx_header header; - u8 ac; - u8 cw_min; - __le16 cw_max; - u8 aifsn; - u8 reserved; - __le16 tx_op_limit; -} __packed; - -struct acx_tid_config { - struct acx_header header; - u8 queue_id; - u8 channel_type; - u8 tsid; - u8 ps_scheme; - u8 ack_policy; - u8 padding[3]; - __le32 apsd_conf[2]; -} __packed; - -struct acx_frag_threshold { - struct acx_header header; - __le16 frag_threshold; - u8 padding[2]; -} __packed; - -struct acx_tx_config_options { - struct acx_header header; - __le16 tx_compl_timeout; /* msec */ - __le16 tx_compl_threshold; /* number of packets */ -} __packed; - -#define ACX_RX_MEM_BLOCKS 70 -#define ACX_TX_MIN_MEM_BLOCKS 40 -#define ACX_TX_DESCRIPTORS 32 -#define ACX_NUM_SSID_PROFILES 1 - -struct wl1271_acx_config_memory { - struct acx_header header; - - u8 rx_mem_block_num; - u8 tx_min_mem_block_num; - u8 num_stations; - u8 num_ssid_profiles; - __le32 total_tx_descriptors; -} __packed; - -struct wl1271_acx_mem_map { - struct acx_header header; - - __le32 code_start; - __le32 code_end; - - __le32 wep_defkey_start; - __le32 wep_defkey_end; - - __le32 sta_table_start; - __le32 sta_table_end; - - __le32 packet_template_start; - __le32 packet_template_end; - - /* Address of the TX result interface (control block) */ - __le32 tx_result; - __le32 tx_result_queue_start; - - __le32 queue_memory_start; - __le32 queue_memory_end; - - __le32 packet_memory_pool_start; - __le32 packet_memory_pool_end; - - __le32 debug_buffer1_start; - __le32 debug_buffer1_end; - - __le32 debug_buffer2_start; - __le32 debug_buffer2_end; - - /* Number of blocks FW allocated for TX packets */ - __le32 num_tx_mem_blocks; - - /* Number of blocks FW allocated for RX packets */ - __le32 num_rx_mem_blocks; - - /* the following 4 fields are valid in SLAVE mode only */ - u8 *tx_cbuf; - u8 *rx_cbuf; - __le32 rx_ctrl; - __le32 tx_ctrl; -} __packed; - -struct wl1271_acx_rx_config_opt { - struct acx_header header; - - __le16 mblk_threshold; - __le16 threshold; - __le16 timeout; - u8 queue_type; - u8 reserved; -} __packed; - - -struct wl1271_acx_bet_enable { - struct acx_header header; - - u8 enable; - u8 max_consecutive; - u8 padding[2]; -} __packed; - -#define ACX_IPV4_VERSION 4 -#define ACX_IPV6_VERSION 6 -#define ACX_IPV4_ADDR_SIZE 4 -struct wl1271_acx_arp_filter { - struct acx_header header; - u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */ - u8 enable; /* 1 to enable ARP filtering, 0 to disable */ - u8 padding[2]; - u8 address[16]; /* The configured device IP address - all ARP - requests directed to this IP address will pass - through. For IPv4, the first four bytes are - used. */ -} __packed; - -struct wl1271_acx_pm_config { - struct acx_header header; - - __le32 host_clk_settling_time; - u8 host_fast_wakeup_support; - u8 padding[3]; -} __packed; - -struct wl1271_acx_keep_alive_mode { - struct acx_header header; - - u8 enabled; - u8 padding[3]; -} __packed; - -enum { - ACX_KEEP_ALIVE_NO_TX = 0, - ACX_KEEP_ALIVE_PERIOD_ONLY -}; - -enum { - ACX_KEEP_ALIVE_TPL_INVALID = 0, - ACX_KEEP_ALIVE_TPL_VALID -}; - -struct wl1271_acx_keep_alive_config { - struct acx_header header; - - __le32 period; - u8 index; - u8 tpl_validation; - u8 trigger; - u8 padding; -} __packed; - -enum { - WL1271_ACX_TRIG_TYPE_LEVEL = 0, - WL1271_ACX_TRIG_TYPE_EDGE, -}; - -enum { - WL1271_ACX_TRIG_DIR_LOW = 0, - WL1271_ACX_TRIG_DIR_HIGH, - WL1271_ACX_TRIG_DIR_BIDIR, -}; - -enum { - WL1271_ACX_TRIG_ENABLE = 1, - WL1271_ACX_TRIG_DISABLE, -}; - -enum { - WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0, - WL1271_ACX_TRIG_METRIC_RSSI_DATA, - WL1271_ACX_TRIG_METRIC_SNR_BEACON, - WL1271_ACX_TRIG_METRIC_SNR_DATA, -}; - -enum { - WL1271_ACX_TRIG_IDX_RSSI = 0, - WL1271_ACX_TRIG_COUNT = 8, -}; - -struct wl1271_acx_rssi_snr_trigger { - struct acx_header header; - - __le16 threshold; - __le16 pacing; /* 0 - 60000 ms */ - u8 metric; - u8 type; - u8 dir; - u8 hysteresis; - u8 index; - u8 enable; - u8 padding[2]; -}; - -struct wl1271_acx_rssi_snr_avg_weights { - struct acx_header header; - - u8 rssi_beacon; - u8 rssi_data; - u8 snr_beacon; - u8 snr_data; -}; - -/* - * ACX_PEER_HT_CAP - * Configure HT capabilities - declare the capabilities of the peer - * we are connected to. - */ -struct wl1271_acx_ht_capabilities { - struct acx_header header; - - /* - * bit 0 - Allow HT Operation - * bit 1 - Allow Greenfield format in TX - * bit 2 - Allow Short GI in TX - * bit 3 - Allow L-SIG TXOP Protection in TX - * bit 4 - Allow HT Control fields in TX. - * Note, driver will still leave space for HT control in packets - * regardless of the value of this field. FW will be responsible - * to drop the HT field from any frame when this Bit set to 0. - * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD. - * Exact policy setting for this feature is TBD. - * Note, this bit can only be set to 1 if bit 3 is set to 1. - */ - __le32 ht_capabilites; - - /* - * Indicates to which peer these capabilities apply. - * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance - * for all peers. - * Only valid for IBSS/DLS operation. - */ - u8 mac_address[ETH_ALEN]; - - /* - * This the maximum A-MPDU length supported by the AP. The FW may not - * exceed this length when sending A-MPDUs - */ - u8 ampdu_max_length; - - /* This is the minimal spacing required when sending A-MPDUs to the AP*/ - u8 ampdu_min_spacing; -} __packed; - -/* HT Capabilites Fw Bit Mask Mapping */ -#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0) -#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1) -#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2) -#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3) -#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4) -#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5) - - -/* - * ACX_HT_BSS_OPERATION - * Configure HT capabilities - AP rules for behavior in the BSS. - */ -struct wl1271_acx_ht_information { - struct acx_header header; - - /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */ - u8 rifs_mode; - - /* Values: 0 - 3 like in spec */ - u8 ht_protection; - - /* Values: 0 - GF protection not required, 1 - GF protection required */ - u8 gf_protection; - - /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/ - u8 ht_tx_burst_limit; - - /* - * Values: 0 - Dual CTS protection not required, - * 1 - Dual CTS Protection required - * Note: When this value is set to 1 FW will protect all TXOP with RTS - * frame and will not use CTS-to-self regardless of the value of the - * ACX_CTS_PROTECTION information element - */ - u8 dual_cts_protection; - - u8 padding[3]; -} __packed; - -struct wl1271_acx_fw_tsf_information { - struct acx_header header; - - __le32 current_tsf_high; - __le32 current_tsf_low; - __le32 last_bttt_high; - __le32 last_tbtt_low; - u8 last_dtim_count; - u8 padding[3]; -} __packed; - -enum { - ACX_WAKE_UP_CONDITIONS = 0x0002, - ACX_MEM_CFG = 0x0003, - ACX_SLOT = 0x0004, - ACX_AC_CFG = 0x0007, - ACX_MEM_MAP = 0x0008, - ACX_AID = 0x000A, - /* ACX_FW_REV is missing in the ref driver, but seems to work */ - ACX_FW_REV = 0x000D, - ACX_MEDIUM_USAGE = 0x000F, - ACX_RX_CFG = 0x0010, - ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ - ACX_STATISTICS = 0x0013, /* Debug API */ - ACX_PWR_CONSUMPTION_STATISTICS = 0x0014, - ACX_FEATURE_CFG = 0x0015, - ACX_TID_CFG = 0x001A, - ACX_PS_RX_STREAMING = 0x001B, - ACX_BEACON_FILTER_OPT = 0x001F, - ACX_NOISE_HIST = 0x0021, - ACX_HDK_VERSION = 0x0022, /* ??? */ - ACX_PD_THRESHOLD = 0x0023, - ACX_TX_CONFIG_OPT = 0x0024, - ACX_CCA_THRESHOLD = 0x0025, - ACX_EVENT_MBOX_MASK = 0x0026, - ACX_CONN_MONIT_PARAMS = 0x002D, - ACX_CONS_TX_FAILURE = 0x002F, - ACX_BCN_DTIM_OPTIONS = 0x0031, - ACX_SG_ENABLE = 0x0032, - ACX_SG_CFG = 0x0033, - ACX_BEACON_FILTER_TABLE = 0x0038, - ACX_ARP_IP_FILTER = 0x0039, - ACX_ROAMING_STATISTICS_TBL = 0x003B, - ACX_RATE_POLICY = 0x003D, - ACX_CTS_PROTECTION = 0x003E, - ACX_SLEEP_AUTH = 0x003F, - ACX_PREAMBLE_TYPE = 0x0040, - ACX_ERROR_CNT = 0x0041, - ACX_IBSS_FILTER = 0x0044, - ACX_SERVICE_PERIOD_TIMEOUT = 0x0045, - ACX_TSF_INFO = 0x0046, - ACX_CONFIG_PS_WMM = 0x0049, - ACX_ENABLE_RX_DATA_FILTER = 0x004A, - ACX_SET_RX_DATA_FILTER = 0x004B, - ACX_GET_DATA_FILTER_STATISTICS = 0x004C, - ACX_RX_CONFIG_OPT = 0x004E, - ACX_FRAG_CFG = 0x004F, - ACX_BET_ENABLE = 0x0050, - ACX_RSSI_SNR_TRIGGER = 0x0051, - ACX_RSSI_SNR_WEIGHTS = 0x0052, - ACX_KEEP_ALIVE_MODE = 0x0053, - ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, - ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, - ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, - ACX_PEER_HT_CAP = 0x0057, - ACX_HT_BSS_OPERATION = 0x0058, - ACX_COEX_ACTIVITY = 0x0059, - ACX_SET_DCO_ITRIM_PARAMS = 0x0061, - DOT11_RX_MSDU_LIFE_TIME = 0x1004, - DOT11_CUR_TX_PWR = 0x100D, - DOT11_RX_DOT11_MODE = 0x1012, - DOT11_RTS_THRESHOLD = 0x1013, - DOT11_GROUP_ADDRESS_TBL = 0x1014, - ACX_PM_CONFIG = 0x1016, - - MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, - - MAX_IE = 0xFFFF -}; - - -int wl1271_acx_wake_up_conditions(struct wl1271 *wl); -int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); -int wl1271_acx_tx_power(struct wl1271 *wl, int power); -int wl1271_acx_feature_cfg(struct wl1271 *wl); -int wl1271_acx_mem_map(struct wl1271 *wl, - struct acx_header *mem_map, size_t len); -int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl); -int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter); -int wl1271_acx_pd_threshold(struct wl1271 *wl); -int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time); -int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, - void *mc_list, u32 mc_list_len); -int wl1271_acx_service_period_timeout(struct wl1271 *wl); -int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold); -int wl1271_acx_dco_itrim_params(struct wl1271 *wl); -int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); -int wl1271_acx_beacon_filter_table(struct wl1271 *wl); -int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable); -int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_sg_cfg(struct wl1271 *wl); -int wl1271_acx_cca_threshold(struct wl1271 *wl); -int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); -int wl1271_acx_aid(struct wl1271 *wl, u16 aid); -int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); -int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); -int wl1271_acx_cts_protect(struct wl1271 *wl, - enum acx_ctsprotect_type ctsprotect); -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); -int wl1271_acx_rate_policies(struct wl1271 *wl); -int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifsn, u16 txop); -int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, - u8 tsid, u8 ps_scheme, u8 ack_policy, - u32 apsd_conf0, u32 apsd_conf1); -int wl1271_acx_frag_threshold(struct wl1271 *wl); -int wl1271_acx_tx_config_options(struct wl1271 *wl); -int wl1271_acx_mem_cfg(struct wl1271 *wl); -int wl1271_acx_init_mem_config(struct wl1271 *wl); -int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); -int wl1271_acx_smart_reflex(struct wl1271 *wl); -int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); -int wl1271_acx_pm_config(struct wl1271 *wl); -int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); -int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); -int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, - s16 thold, u8 hyst); -int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); -int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, - struct ieee80211_sta_ht_cap *ht_cap, - bool allow_ht_operation); -int wl1271_acx_set_ht_information(struct wl1271 *wl, - u16 ht_operation_mode); -int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); - -#endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c deleted file mode 100644 index 5b190728ca55..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include - -#include "wl1271_acx.h" -#include "wl1271_reg.h" -#include "wl1271_boot.h" -#include "wl1271_io.h" -#include "wl1271_event.h" - -static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { - [PART_DOWN] = { - .mem = { - .start = 0x00000000, - .size = 0x000177c0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x00008800 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - }, - }, - - [PART_WORK] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x0000a000 - }, - .mem2 = { - .start = 0x003004f8, - .size = 0x00000004 - }, - .mem3 = { - .start = 0x00040404, - .size = 0x00000000 - }, - }, - - [PART_DRPW] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = DRPW_BASE, - .size = 0x00006000 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - } - } -}; - -static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) -{ - u32 cpu_ctrl; - - /* 10.5.0 run the firmware (I) */ - cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL); - - /* 10.5.1 run the firmware (II) */ - cpu_ctrl |= flag; - wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); -} - -static void wl1271_boot_fw_version(struct wl1271 *wl) -{ - struct wl1271_static_data static_data; - - wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data), - false); - - strncpy(wl->chip.fw_ver, static_data.fw_version, - sizeof(wl->chip.fw_ver)); - - /* make sure the string is NULL-terminated */ - wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0'; -} - -static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, - size_t fw_data_len, u32 dest) -{ - struct wl1271_partition_set partition; - int addr, chunk_num, partition_limit; - u8 *p, *chunk; - - /* whal_FwCtrl_LoadFwImageSm() */ - - wl1271_debug(DEBUG_BOOT, "starting firmware upload"); - - wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d", - fw_data_len, CHUNK_SIZE); - - if ((fw_data_len % 4) != 0) { - wl1271_error("firmware length not multiple of four"); - return -EIO; - } - - chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL); - if (!chunk) { - wl1271_error("allocation for firmware upload chunk failed"); - return -ENOMEM; - } - - memcpy(&partition, &part_table[PART_DOWN], sizeof(partition)); - partition.mem.start = dest; - wl1271_set_partition(wl, &partition); - - /* 10.1 set partition limit and chunk num */ - chunk_num = 0; - partition_limit = part_table[PART_DOWN].mem.size; - - while (chunk_num < fw_data_len / CHUNK_SIZE) { - /* 10.2 update partition, if needed */ - addr = dest + (chunk_num + 2) * CHUNK_SIZE; - if (addr > partition_limit) { - addr = dest + chunk_num * CHUNK_SIZE; - partition_limit = chunk_num * CHUNK_SIZE + - part_table[PART_DOWN].mem.size; - partition.mem.start = addr; - wl1271_set_partition(wl, &partition); - } - - /* 10.3 upload the chunk */ - addr = dest + chunk_num * CHUNK_SIZE; - p = buf + chunk_num * CHUNK_SIZE; - memcpy(chunk, p, CHUNK_SIZE); - wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", - p, addr); - wl1271_write(wl, addr, chunk, CHUNK_SIZE, false); - - chunk_num++; - } - - /* 10.4 upload the last chunk */ - addr = dest + chunk_num * CHUNK_SIZE; - p = buf + chunk_num * CHUNK_SIZE; - memcpy(chunk, p, fw_data_len % CHUNK_SIZE); - wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", - fw_data_len % CHUNK_SIZE, p, addr); - wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); - - kfree(chunk); - return 0; -} - -static int wl1271_boot_upload_firmware(struct wl1271 *wl) -{ - u32 chunks, addr, len; - int ret = 0; - u8 *fw; - - fw = wl->fw; - chunks = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - - wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks); - - while (chunks--) { - addr = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - len = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - - if (len > 300000) { - wl1271_info("firmware chunk too long: %u", len); - return -EINVAL; - } - wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u", - chunks, addr, len); - ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr); - if (ret != 0) - break; - fw += len; - } - - return ret; -} - -static int wl1271_boot_upload_nvs(struct wl1271 *wl) -{ - size_t nvs_len, burst_len; - int i; - u32 dest_addr, val; - u8 *nvs_ptr, *nvs_aligned; - - if (wl->nvs == NULL) - return -ENODEV; - - /* - * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band - * configurations) can be removed when those NVS files stop floating - * around. - */ - if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || - wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { - if (wl->nvs->general_params.dual_mode_select) - wl->enable_11a = true; - } - - if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && - (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || - wl->enable_11a)) { - wl1271_error("nvs size is not as expected: %zu != %zu", - wl->nvs_len, sizeof(struct wl1271_nvs_file)); - kfree(wl->nvs); - wl->nvs = NULL; - wl->nvs_len = 0; - return -EILSEQ; - } - - /* only the first part of the NVS needs to be uploaded */ - nvs_len = sizeof(wl->nvs->nvs); - nvs_ptr = (u8 *)wl->nvs->nvs; - - /* update current MAC address to NVS */ - nvs_ptr[11] = wl->mac_addr[0]; - nvs_ptr[10] = wl->mac_addr[1]; - nvs_ptr[6] = wl->mac_addr[2]; - nvs_ptr[5] = wl->mac_addr[3]; - nvs_ptr[4] = wl->mac_addr[4]; - nvs_ptr[3] = wl->mac_addr[5]; - - /* - * Layout before the actual NVS tables: - * 1 byte : burst length. - * 2 bytes: destination address. - * n bytes: data to burst copy. - * - * This is ended by a 0 length, then the NVS tables. - */ - - /* FIXME: Do we need to check here whether the LSB is 1? */ - while (nvs_ptr[0]) { - burst_len = nvs_ptr[0]; - dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); - - /* - * Due to our new wl1271_translate_reg_addr function, - * we need to add the REGISTER_BASE to the destination - */ - dest_addr += REGISTERS_BASE; - - /* We move our pointer to the data */ - nvs_ptr += 3; - - for (i = 0; i < burst_len; i++) { - val = (nvs_ptr[0] | (nvs_ptr[1] << 8) - | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); - - wl1271_debug(DEBUG_BOOT, - "nvs burst write 0x%x: 0x%x", - dest_addr, val); - wl1271_write32(wl, dest_addr, val); - - nvs_ptr += 4; - dest_addr += 4; - } - } - - /* - * We've reached the first zero length, the first NVS table - * is located at an aligned offset which is at least 7 bytes further. - */ - nvs_ptr = (u8 *)wl->nvs->nvs + - ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); - nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; - - /* Now we must set the partition correctly */ - wl1271_set_partition(wl, &part_table[PART_WORK]); - - /* Copy the NVS tables to a new block to ensure alignment */ - nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); - if (!nvs_aligned) - return -ENOMEM; - - /* And finally we upload the NVS tables */ - wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); - - kfree(nvs_aligned); - return 0; -} - -static void wl1271_boot_enable_interrupts(struct wl1271 *wl) -{ - wl1271_enable_interrupts(wl); - wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); - wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); -} - -static int wl1271_boot_soft_reset(struct wl1271 *wl) -{ - unsigned long timeout; - u32 boot_data; - - /* perform soft reset */ - wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); - - /* SOFT_RESET is self clearing */ - timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); - while (1) { - boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET); - wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); - if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) - break; - - if (time_after(jiffies, timeout)) { - /* 1.2 check pWhalBus->uSelfClearTime if the - * timeout was reached */ - wl1271_error("soft reset timeout"); - return -1; - } - - udelay(SOFT_RESET_STALL_TIME); - } - - /* disable Rx/Tx */ - wl1271_write32(wl, ENABLE, 0x0); - - /* disable auto calibration on start*/ - wl1271_write32(wl, SPARE_A2, 0xffff); - - return 0; -} - -static int wl1271_boot_run_firmware(struct wl1271 *wl) -{ - int loop, ret; - u32 chip_id, intr; - - wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); - - chip_id = wl1271_read32(wl, CHIP_ID_B); - - wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); - - if (chip_id != wl->chip.id) { - wl1271_error("chip id doesn't match after firmware boot"); - return -EIO; - } - - /* wait for init to complete */ - loop = 0; - while (loop++ < INIT_LOOP) { - udelay(INIT_LOOP_DELAY); - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - - if (intr == 0xffffffff) { - wl1271_error("error reading hardware complete " - "init indication"); - return -EIO; - } - /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { - wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1271_ACX_INTR_INIT_COMPLETE); - break; - } - } - - if (loop > INIT_LOOP) { - wl1271_error("timeout waiting for the hardware to " - "complete initialization"); - return -EIO; - } - - /* get hardware config command mail box */ - wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR); - - /* get hardware config event mail box */ - wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); - - /* set the working partition to its "running" mode offset */ - wl1271_set_partition(wl, &part_table[PART_WORK]); - - wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", - wl->cmd_box_addr, wl->event_box_addr); - - wl1271_boot_fw_version(wl); - - /* - * in case of full asynchronous mode the firmware event must be - * ready to receive event from the command mailbox - */ - - /* unmask required mbox events */ - wl->event_mask = BSS_LOSE_EVENT_ID | - SCAN_COMPLETE_EVENT_ID | - PS_REPORT_EVENT_ID | - JOIN_EVENT_COMPLETE_ID | - DISCONNECT_EVENT_COMPLETE_ID | - RSSI_SNR_TRIGGER_0_EVENT_ID | - PSPOLL_DELIVERY_FAILURE_EVENT_ID | - SOFT_GEMINI_SENSE_EVENT_ID; - - ret = wl1271_event_unmask(wl); - if (ret < 0) { - wl1271_error("EVENT mask setting failed"); - return ret; - } - - wl1271_event_mbox_config(wl); - - /* firmware startup completed */ - return 0; -} - -static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) -{ - u32 polarity; - - polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY); - - /* We use HIGH polarity, so unset the LOW bit */ - polarity &= ~POLARITY_LOW; - wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity); - - return 0; -} - -static void wl1271_boot_hw_version(struct wl1271 *wl) -{ - u32 fuse; - - fuse = wl1271_top_reg_read(wl, REG_FUSE_DATA_2_1); - fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; - - wl->hw_pg_ver = (s8)fuse; -} - -int wl1271_boot(struct wl1271 *wl) -{ - int ret = 0; - u32 tmp, clk, pause; - - wl1271_boot_hw_version(wl); - - if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4) - /* ref clk: 19.2/38.4/38.4-XTAL */ - clk = 0x3; - else if (wl->ref_clock == 1 || wl->ref_clock == 3) - /* ref clk: 26/52 */ - clk = 0x5; - else - return -EINVAL; - - if (wl->ref_clock != 0) { - u16 val; - /* Set clock type (open drain) */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); - val &= FREF_CLK_TYPE_BITS; - wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); - - /* Set clock pull mode (no pull) */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL); - val |= NO_PULL; - wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val); - } else { - u16 val; - /* Set clock polarity */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY); - val &= FREF_CLK_POLARITY_BITS; - val |= CLK_REQ_OUTN_SEL; - wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); - } - - wl1271_write32(wl, PLL_PARAMETERS, clk); - - pause = wl1271_read32(wl, PLL_PARAMETERS); - - wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); - - pause &= ~(WU_COUNTER_PAUSE_VAL); - pause |= WU_COUNTER_PAUSE_VAL; - wl1271_write32(wl, WU_COUNTER_PAUSE, pause); - - /* Continue the ELP wake up sequence */ - wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); - udelay(500); - - wl1271_set_partition(wl, &part_table[PART_DRPW]); - - /* Read-modify-write DRPW_SCRATCH_START register (see next state) - to be used by DRPw FW. The RTRIM value will be added by the FW - before taking DRPw out of reset */ - - wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); - clk = wl1271_read32(wl, DRPW_SCRATCH_START); - - wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); - - clk |= (wl->ref_clock << 1) << 4; - wl1271_write32(wl, DRPW_SCRATCH_START, clk); - - wl1271_set_partition(wl, &part_table[PART_WORK]); - - /* Disable interrupts */ - wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); - - ret = wl1271_boot_soft_reset(wl); - if (ret < 0) - goto out; - - /* 2. start processing NVS file */ - ret = wl1271_boot_upload_nvs(wl); - if (ret < 0) - goto out; - - /* write firmware's last address (ie. it's length) to - * ACX_EEPROMLESS_IND_REG */ - wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); - - wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG); - - tmp = wl1271_read32(wl, CHIP_ID_B); - - wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); - - /* 6. read the EEPROM parameters */ - tmp = wl1271_read32(wl, SCR_PAD2); - - ret = wl1271_boot_write_irq_polarity(wl); - if (ret < 0) - goto out; - - wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, - WL1271_ACX_ALL_EVENTS_VECTOR); - - /* WL1271: The reference driver skips steps 7 to 10 (jumps directly - * to upload_fw) */ - - ret = wl1271_boot_upload_firmware(wl); - if (ret < 0) - goto out; - - /* 10.5 start firmware */ - ret = wl1271_boot_run_firmware(wl); - if (ret < 0) - goto out; - - /* Enable firmware interrupts now */ - wl1271_boot_enable_interrupts(wl); - - /* set the wl1271 default filters */ - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - - wl1271_event_mbox_config(wl); - -out: - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h deleted file mode 100644 index f73b0b15a280..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_boot.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __BOOT_H__ -#define __BOOT_H__ - -#include "wl1271.h" - -int wl1271_boot(struct wl1271 *wl); - -#define WL1271_NO_SUBBANDS 8 -#define WL1271_NO_POWER_LEVELS 4 -#define WL1271_FW_VERSION_MAX_LEN 20 - -struct wl1271_static_data { - u8 mac_address[ETH_ALEN]; - u8 padding[2]; - u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; - u32 hw_version; - u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; -}; - -/* number of times we try to read the INIT interrupt */ -#define INIT_LOOP 20000 - -/* delay between retries */ -#define INIT_LOOP_DELAY 50 - -#define WU_COUNTER_PAUSE_VAL 0x3FF -#define WELP_ARM_COMMAND_VAL 0x4 - -#define OCP_REG_POLARITY 0x0064 -#define OCP_REG_CLK_TYPE 0x0448 -#define OCP_REG_CLK_POLARITY 0x0cb2 -#define OCP_REG_CLK_PULL 0x0cb4 - -#define REG_FUSE_DATA_2_1 0x050a -#define PG_VER_MASK 0x3c -#define PG_VER_OFFSET 2 - -#define CMD_MBOX_ADDRESS 0x407B4 - -#define POLARITY_LOW BIT(1) -#define NO_PULL (BIT(14) | BIT(15)) - -#define FREF_CLK_TYPE_BITS 0xfffffe7f -#define CLK_REQ_PRCM 0x100 -#define FREF_CLK_POLARITY_BITS 0xfffff8ff -#define CLK_REQ_OUTN_SEL 0x700 - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c deleted file mode 100644 index 5d3e8485ea4e..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_acx.h" -#include "wl12xx_80211.h" -#include "wl1271_cmd.h" -#include "wl1271_event.h" - -#define WL1271_CMD_FAST_POLL_COUNT 50 - -/* - * send command to firmware - * - * @wl: wl struct - * @id: command id - * @buf: buffer containing the command, must work with dma - * @len: length of the buffer - */ -int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, - size_t res_len) -{ - struct wl1271_cmd_header *cmd; - unsigned long timeout; - u32 intr; - int ret = 0; - u16 status; - u16 poll_count = 0; - - cmd = buf; - cmd->id = cpu_to_le16(id); - cmd->status = 0; - - WARN_ON(len % 4 != 0); - - wl1271_write(wl, wl->cmd_box_addr, buf, len, false); - - wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); - - timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); - - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { - if (time_after(jiffies, timeout)) { - wl1271_error("command complete timeout"); - ret = -ETIMEDOUT; - goto out; - } - - poll_count++; - if (poll_count < WL1271_CMD_FAST_POLL_COUNT) - udelay(10); - else - msleep(1); - - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - } - - /* read back the status code of the command */ - if (res_len == 0) - res_len = sizeof(struct wl1271_cmd_header); - wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false); - - status = le16_to_cpu(cmd->status); - if (status != CMD_STATUS_SUCCESS) { - wl1271_error("command execute failure %d", status); - ieee80211_queue_work(wl->hw, &wl->recovery_work); - ret = -EIO; - } - - wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1271_ACX_INTR_CMD_COMPLETE); - -out: - return ret; -} - -int wl1271_cmd_general_parms(struct wl1271 *wl) -{ - struct wl1271_general_parms_cmd *gen_parms; - struct wl1271_ini_general_params *gp = &wl->nvs->general_params; - bool answer = false; - int ret; - - if (!wl->nvs) - return -ENODEV; - - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); - if (!gen_parms) - return -ENOMEM; - - gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; - - memcpy(&gen_parms->general_params, gp, sizeof(*gp)); - - if (gp->tx_bip_fem_auto_detect) - answer = true; - - ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); - if (ret < 0) { - wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); - goto out; - } - - gp->tx_bip_fem_manufacturer = - gen_parms->general_params.tx_bip_fem_manufacturer; - - wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", - answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); - -out: - kfree(gen_parms); - return ret; -} - -int wl1271_cmd_radio_parms(struct wl1271 *wl) -{ - struct wl1271_radio_parms_cmd *radio_parms; - struct wl1271_ini_general_params *gp = &wl->nvs->general_params; - int ret; - - if (!wl->nvs) - return -ENODEV; - - radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); - if (!radio_parms) - return -ENOMEM; - - radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; - - /* 2.4GHz parameters */ - memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2, - sizeof(struct wl1271_ini_band_params_2)); - memcpy(&radio_parms->dyn_params_2, - &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, - sizeof(struct wl1271_ini_fem_params_2)); - - /* 5GHz parameters */ - memcpy(&radio_parms->static_params_5, - &wl->nvs->stat_radio_params_5, - sizeof(struct wl1271_ini_band_params_5)); - memcpy(&radio_parms->dyn_params_5, - &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, - sizeof(struct wl1271_ini_fem_params_5)); - - wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", - radio_parms, sizeof(*radio_parms)); - - ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); - if (ret < 0) - wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); - - kfree(radio_parms); - return ret; -} - -int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) -{ - struct wl1271_ext_radio_parms_cmd *ext_radio_parms; - struct conf_rf_settings *rf = &wl->conf.rf; - int ret; - - if (!wl->nvs) - return -ENODEV; - - ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); - if (!ext_radio_parms) - return -ENOMEM; - - ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; - - memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, - rf->tx_per_channel_power_compensation_2, - CONF_TX_PWR_COMPENSATION_LEN_2); - memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, - rf->tx_per_channel_power_compensation_5, - CONF_TX_PWR_COMPENSATION_LEN_5); - - wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", - ext_radio_parms, sizeof(*ext_radio_parms)); - - ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); - - kfree(ext_radio_parms); - return ret; -} - -/* - * Poll the mailbox event field until any of the bits in the mask is set or a - * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) - */ -static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) -{ - u32 events_vector, event; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); - - do { - if (time_after(jiffies, timeout)) { - ieee80211_queue_work(wl->hw, &wl->recovery_work); - return -ETIMEDOUT; - } - - msleep(1); - - /* read from both event fields */ - wl1271_read(wl, wl->mbox_ptr[0], &events_vector, - sizeof(events_vector), false); - event = events_vector & mask; - wl1271_read(wl, wl->mbox_ptr[1], &events_vector, - sizeof(events_vector), false); - event |= events_vector & mask; - } while (!event); - - return 0; -} - -int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) -{ - struct wl1271_cmd_join *join; - int ret, i; - u8 *bssid; - - join = kzalloc(sizeof(*join), GFP_KERNEL); - if (!join) { - ret = -ENOMEM; - goto out; - } - - wl1271_debug(DEBUG_CMD, "cmd join"); - - /* Reverse order BSSID */ - bssid = (u8 *) &join->bssid_lsb; - for (i = 0; i < ETH_ALEN; i++) - bssid[i] = wl->bssid[ETH_ALEN - i - 1]; - - join->rx_config_options = cpu_to_le32(wl->rx_config); - join->rx_filter_options = cpu_to_le32(wl->rx_filter); - join->bss_type = bss_type; - join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); - - if (wl->band == IEEE80211_BAND_5GHZ) - join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; - - join->beacon_interval = cpu_to_le16(wl->beacon_int); - join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; - - join->channel = wl->channel; - join->ssid_len = wl->ssid_len; - memcpy(join->ssid, wl->ssid, wl->ssid_len); - - join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; - - /* reset TX security counters */ - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; - - ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); - if (ret < 0) { - wl1271_error("failed to initiate cmd join"); - goto out_free; - } - - ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); - if (ret < 0) - wl1271_error("cmd join event completion error"); - -out_free: - kfree(join); - -out: - return ret; -} - -/** - * send test command to firmware - * - * @wl: wl struct - * @buf: buffer containing the command, with all headers, must work with dma - * @len: length of the buffer - * @answer: is answer needed - */ -int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) -{ - int ret; - size_t res_len = 0; - - wl1271_debug(DEBUG_CMD, "cmd test"); - - if (answer) - res_len = buf_len; - - ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len); - - if (ret < 0) { - wl1271_warning("TEST command failed"); - return ret; - } - - return ret; -} - -/** - * read acx from firmware - * - * @wl: wl struct - * @id: acx id - * @buf: buffer for the response, including all headers, must work with dma - * @len: lenght of buf - */ -int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1271_debug(DEBUG_CMD, "cmd interrogate"); - - acx->id = cpu_to_le16(id); - - /* payload length, does not include any headers */ - acx->len = cpu_to_le16(len - sizeof(*acx)); - - ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); - if (ret < 0) - wl1271_error("INTERROGATE command failed"); - - return ret; -} - -/** - * write acx value to firmware - * - * @wl: wl struct - * @id: acx id - * @buf: buffer containing acx, including all headers, must work with dma - * @len: length of buf - */ -int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1271_debug(DEBUG_CMD, "cmd configure"); - - acx->id = cpu_to_le16(id); - - /* payload length, does not include any headers */ - acx->len = cpu_to_le16(len - sizeof(*acx)); - - ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0); - if (ret < 0) { - wl1271_warning("CONFIGURE command NOK"); - return ret; - } - - return 0; -} - -int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) -{ - struct cmd_enabledisable_path *cmd; - int ret; - u16 cmd_rx, cmd_tx; - - wl1271_debug(DEBUG_CMD, "cmd data path"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - /* the channel here is only used for calibration, so hardcoded to 1 */ - cmd->channel = 1; - - if (enable) { - cmd_rx = CMD_ENABLE_RX; - cmd_tx = CMD_ENABLE_TX; - } else { - cmd_rx = CMD_DISABLE_RX; - cmd_tx = CMD_DISABLE_TX; - } - - ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("rx %s cmd for channel %d failed", - enable ? "start" : "stop", cmd->channel); - goto out; - } - - wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", - enable ? "start" : "stop", cmd->channel); - - ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("tx %s cmd for channel %d failed", - enable ? "start" : "stop", cmd->channel); - goto out; - } - - wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", - enable ? "start" : "stop", cmd->channel); - -out: - kfree(cmd); - return ret; -} - -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) -{ - struct wl1271_cmd_ps_params *ps_params = NULL; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd set ps mode"); - - ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); - if (!ps_params) { - ret = -ENOMEM; - goto out; - } - - ps_params->ps_mode = ps_mode; - ps_params->send_null_data = send; - ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; - ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; - ps_params->null_data_rate = cpu_to_le32(rates); - - ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, - sizeof(*ps_params), 0); - if (ret < 0) { - wl1271_error("cmd set_ps_mode failed"); - goto out; - } - -out: - kfree(ps_params); - return ret; -} - -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates) -{ - struct wl1271_cmd_template_set *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id); - - WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); - buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->len = cpu_to_le16(buf_len); - cmd->template_type = template_id; - cmd->enabled_rates = cpu_to_le32(rates); - cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; - cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; - cmd->index = index; - - if (buf) - memcpy(cmd->template_data, buf, buf_len); - - ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("cmd set_template failed: %d", ret); - goto out_free; - } - -out_free: - kfree(cmd); - -out: - return ret; -} - -int wl1271_cmd_build_null_data(struct wl1271 *wl) -{ - struct sk_buff *skb = NULL; - int size; - void *ptr; - int ret = -ENOMEM; - - - if (wl->bss_type == BSS_TYPE_IBSS) { - size = sizeof(struct wl12xx_null_data_template); - ptr = NULL; - } else { - skb = ieee80211_nullfunc_get(wl->hw, wl->vif); - if (!skb) - goto out; - size = skb->len; - ptr = skb->data; - } - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, - wl->basic_rate); - -out: - dev_kfree_skb(skb); - if (ret) - wl1271_warning("cmd buld null data failed %d", ret); - - return ret; - -} - -int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) -{ - struct sk_buff *skb = NULL; - int ret = -ENOMEM; - - skb = ieee80211_nullfunc_get(wl->hw, wl->vif); - if (!skb) - goto out; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, - skb->data, skb->len, - CMD_TEMPL_KLV_IDX_NULL_DATA, - wl->basic_rate); - -out: - dev_kfree_skb(skb); - if (ret) - wl1271_warning("cmd build klv null data failed %d", ret); - - return ret; - -} - -int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) -{ - struct sk_buff *skb; - int ret = 0; - - skb = ieee80211_pspoll_get(wl->hw, wl->vif); - if (!skb) - goto out; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, - skb->len, 0, wl->basic_rate_set); - -out: - dev_kfree_skb(skb); - return ret; -} - -int wl1271_cmd_build_probe_req(struct wl1271 *wl, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band) -{ - struct sk_buff *skb; - int ret; - - skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, - ie, ie_len); - if (!skb) { - ret = -ENOMEM; - goto out; - } - - wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); - - if (band == IEEE80211_BAND_2GHZ) - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, - skb->data, skb->len, 0, - wl->conf.tx.basic_rate); - else - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - skb->data, skb->len, 0, - wl->conf.tx.basic_rate_5); - -out: - dev_kfree_skb(skb); - return ret; -} - -int wl1271_build_qos_null_data(struct wl1271 *wl) -{ - struct ieee80211_qos_hdr template; - - memset(&template, 0, sizeof(template)); - - memcpy(template.addr1, wl->bssid, ETH_ALEN); - memcpy(template.addr2, wl->mac_addr, ETH_ALEN); - memcpy(template.addr3, wl->bssid, ETH_ALEN); - - template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_QOS_NULLFUNC | - IEEE80211_FCTL_TODS); - - /* FIXME: not sure what priority to use here */ - template.qos_ctrl = cpu_to_le16(0); - - return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, - sizeof(template), 0, - wl->basic_rate); -} - -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) -{ - struct wl1271_cmd_set_keys *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->id = id; - cmd->key_action = cpu_to_le16(KEY_SET_ID); - cmd->key_type = KEY_WEP; - - ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("cmd set_default_wep_key failed: %d", ret); - goto out; - } - -out: - kfree(cmd); - - return ret; -} - -int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, - u8 key_size, const u8 *key, const u8 *addr, - u32 tx_seq_32, u16 tx_seq_16) -{ - struct wl1271_cmd_set_keys *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - if (key_type != KEY_WEP) - memcpy(cmd->addr, addr, ETH_ALEN); - - cmd->key_action = cpu_to_le16(action); - cmd->key_size = key_size; - cmd->key_type = key_type; - - cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); - cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); - - /* we have only one SSID profile */ - cmd->ssid_profile = 0; - - cmd->id = id; - - if (key_type == KEY_TKIP) { - /* - * We get the key in the following form: - * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) - * but the target is expecting: - * TKIP - RX MIC - TX MIC - */ - memcpy(cmd->key, key, 16); - memcpy(cmd->key + 16, key + 24, 8); - memcpy(cmd->key + 24, key + 16, 8); - - } else { - memcpy(cmd->key, key, key_size); - } - - wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd)); - - ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("could not set keys"); - goto out; - } - -out: - kfree(cmd); - - return ret; -} - -int wl1271_cmd_disconnect(struct wl1271 *wl) -{ - struct wl1271_cmd_disconnect *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd disconnect"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->rx_config_options = cpu_to_le32(wl->rx_config); - cmd->rx_filter_options = cpu_to_le32(wl->rx_filter); - /* disconnect reason is not used in immediate disconnections */ - cmd->type = DISCONNECT_IMMEDIATE; - - ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("failed to send disconnect command"); - goto out_free; - } - - ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID); - if (ret < 0) - wl1271_error("cmd disconnect event completion error"); - -out_free: - kfree(cmd); - -out: - return ret; -} - -int wl1271_cmd_set_sta_state(struct wl1271 *wl) -{ - struct wl1271_cmd_set_sta_state *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd set sta state"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->state = WL1271_CMD_STA_STATE_CONNECTED; - - ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("failed to send set STA state command"); - goto out_free; - } - -out_free: - kfree(cmd); - -out: - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h deleted file mode 100644 index a0caf4fc37b1..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_CMD_H__ -#define __WL1271_CMD_H__ - -#include "wl1271.h" - -struct acx_header; - -int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, - size_t res_len); -int wl1271_cmd_general_parms(struct wl1271 *wl); -int wl1271_cmd_radio_parms(struct wl1271 *wl); -int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); -int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); -int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); -int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); -int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); -int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); -int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, - size_t len); -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates); -int wl1271_cmd_build_null_data(struct wl1271 *wl); -int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); -int wl1271_cmd_build_probe_req(struct wl1271 *wl, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band); -int wl1271_build_qos_null_data(struct wl1271 *wl); -int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); -int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, - u8 key_size, const u8 *key, const u8 *addr, - u32 tx_seq_32, u16 tx_seq_16); -int wl1271_cmd_disconnect(struct wl1271 *wl); -int wl1271_cmd_set_sta_state(struct wl1271 *wl); - -enum wl1271_commands { - CMD_INTERROGATE = 1, /*use this to read information elements*/ - CMD_CONFIGURE = 2, /*use this to write information elements*/ - CMD_ENABLE_RX = 3, - CMD_ENABLE_TX = 4, - CMD_DISABLE_RX = 5, - CMD_DISABLE_TX = 6, - CMD_SCAN = 8, - CMD_STOP_SCAN = 9, - CMD_START_JOIN = 11, - CMD_SET_KEYS = 12, - CMD_READ_MEMORY = 13, - CMD_WRITE_MEMORY = 14, - CMD_SET_TEMPLATE = 19, - CMD_TEST = 23, - CMD_NOISE_HIST = 28, - CMD_LNA_CONTROL = 32, - CMD_SET_BCN_MODE = 33, - CMD_MEASUREMENT = 34, - CMD_STOP_MEASUREMENT = 35, - CMD_DISCONNECT = 36, - CMD_SET_PS_MODE = 37, - CMD_CHANNEL_SWITCH = 38, - CMD_STOP_CHANNEL_SWICTH = 39, - CMD_AP_DISCOVERY = 40, - CMD_STOP_AP_DISCOVERY = 41, - CMD_SPS_SCAN = 42, - CMD_STOP_SPS_SCAN = 43, - CMD_HEALTH_CHECK = 45, - CMD_DEBUG = 46, - CMD_TRIGGER_SCAN_TO = 47, - CMD_CONNECTION_SCAN_CFG = 48, - CMD_CONNECTION_SCAN_SSID_CFG = 49, - CMD_START_PERIODIC_SCAN = 50, - CMD_STOP_PERIODIC_SCAN = 51, - CMD_SET_STA_STATE = 52, - - NUM_COMMANDS, - MAX_COMMAND_ID = 0xFFFF, -}; - -#define MAX_CMD_PARAMS 572 - -enum { - CMD_TEMPL_KLV_IDX_NULL_DATA = 0, - CMD_TEMPL_KLV_IDX_MAX = 4 -}; - -enum cmd_templ { - CMD_TEMPL_NULL_DATA = 0, - CMD_TEMPL_BEACON, - CMD_TEMPL_CFG_PROBE_REQ_2_4, - CMD_TEMPL_CFG_PROBE_REQ_5, - CMD_TEMPL_PROBE_RESPONSE, - CMD_TEMPL_QOS_NULL_DATA, - CMD_TEMPL_PS_POLL, - CMD_TEMPL_KLV, - CMD_TEMPL_DISCONNECT, - CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */ - CMD_TEMPL_PROBE_REQ_5, /* for firmware internal use only */ - CMD_TEMPL_BAR, /* for firmware internal use only */ - CMD_TEMPL_CTS, /* - * For CTS-to-self (FastCTS) mechanism - * for BT/WLAN coexistence (SoftGemini). */ - CMD_TEMPL_MAX = 0xff -}; - -/* unit ms */ -#define WL1271_COMMAND_TIMEOUT 2000 -#define WL1271_CMD_TEMPL_MAX_SIZE 252 -#define WL1271_EVENT_TIMEOUT 750 - -struct wl1271_cmd_header { - __le16 id; - __le16 status; - /* payload */ - u8 data[0]; -} __packed; - -#define WL1271_CMD_MAX_PARAMS 572 - -struct wl1271_command { - struct wl1271_cmd_header header; - u8 parameters[WL1271_CMD_MAX_PARAMS]; -} __packed; - -enum { - CMD_MAILBOX_IDLE = 0, - CMD_STATUS_SUCCESS = 1, - CMD_STATUS_UNKNOWN_CMD = 2, - CMD_STATUS_UNKNOWN_IE = 3, - CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11, - CMD_STATUS_RX_BUSY = 13, - CMD_STATUS_INVALID_PARAM = 14, - CMD_STATUS_TEMPLATE_TOO_LARGE = 15, - CMD_STATUS_OUT_OF_MEMORY = 16, - CMD_STATUS_STA_TABLE_FULL = 17, - CMD_STATUS_RADIO_ERROR = 18, - CMD_STATUS_WRONG_NESTING = 19, - CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/ - CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/ - MAX_COMMAND_STATUS = 0xff -}; - -#define CMDMBOX_HEADER_LEN 4 -#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 - -enum { - BSS_TYPE_IBSS = 0, - BSS_TYPE_STA_BSS = 2, - BSS_TYPE_AP_BSS = 3, - MAX_BSS_TYPE = 0xFF -}; - -#define WL1271_JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */ -#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1 -#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10 - -struct wl1271_cmd_join { - struct wl1271_cmd_header header; - - __le32 bssid_lsb; - __le16 bssid_msb; - __le16 beacon_interval; /* in TBTTs */ - __le32 rx_config_options; - __le32 rx_filter_options; - - /* - * The target uses this field to determine the rate at - * which to transmit control frame responses (such as - * ACK or CTS frames). - */ - __le32 basic_rate_set; - u8 dtim_interval; - /* - * bits 0-2: This bitwise field specifies the type - * of BSS to start or join (BSS_TYPE_*). - * bit 4: Band - The radio band in which to join - * or start. - * 0 - 2.4GHz band - * 1 - 5GHz band - * bits 3, 5-7: Reserved - */ - u8 bss_type; - u8 channel; - u8 ssid_len; - u8 ssid[IW_ESSID_MAX_SIZE]; - u8 ctrl; /* JOIN_CMD_CTRL_* */ - u8 reserved[3]; -} __packed; - -struct cmd_enabledisable_path { - struct wl1271_cmd_header header; - - u8 channel; - u8 padding[3]; -} __packed; - -#define WL1271_RATE_AUTOMATIC 0 - -struct wl1271_cmd_template_set { - struct wl1271_cmd_header header; - - __le16 len; - u8 template_type; - u8 index; /* relevant only for KLV_TEMPLATE type */ - __le32 enabled_rates; - u8 short_retry_limit; - u8 long_retry_limit; - u8 aflags; - u8 reserved; - u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE]; -} __packed; - -#define TIM_ELE_ID 5 -#define PARTIAL_VBM_MAX 251 - -struct wl1271_tim { - u8 identity; - u8 length; - u8 dtim_count; - u8 dtim_period; - u8 bitmap_ctrl; - u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ -} __packed; - -enum wl1271_cmd_ps_mode { - STATION_ACTIVE_MODE, - STATION_POWER_SAVE_MODE -}; - -struct wl1271_cmd_ps_params { - struct wl1271_cmd_header header; - - u8 ps_mode; /* STATION_* */ - u8 send_null_data; /* Do we have to send NULL data packet ? */ - u8 retries; /* Number of retires for the initial NULL data packet */ - - /* - * TUs during which the target stays awake after switching - * to power save mode. - */ - u8 hang_over_period; - __le32 null_data_rate; -} __packed; - -/* HW encryption keys */ -#define NUM_ACCESS_CATEGORIES_COPY 4 -#define MAX_KEY_SIZE 32 - -enum wl1271_cmd_key_action { - KEY_ADD_OR_REPLACE = 1, - KEY_REMOVE = 2, - KEY_SET_ID = 3, - MAX_KEY_ACTION = 0xffff, -}; - -enum wl1271_cmd_key_type { - KEY_NONE = 0, - KEY_WEP = 1, - KEY_TKIP = 2, - KEY_AES = 3, - KEY_GEM = 4, -}; - -/* FIXME: Add description for key-types */ - -struct wl1271_cmd_set_keys { - struct wl1271_cmd_header header; - - /* Ignored for default WEP key */ - u8 addr[ETH_ALEN]; - - /* key_action_e */ - __le16 key_action; - - __le16 reserved_1; - - /* key size in bytes */ - u8 key_size; - - /* key_type_e */ - u8 key_type; - u8 ssid_profile; - - /* - * TKIP, AES: frame's key id field. - * For WEP default key: key id; - */ - u8 id; - u8 reserved_2[6]; - u8 key[MAX_KEY_SIZE]; - __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; - __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; -} __packed; - -struct wl1271_cmd_test_header { - u8 id; - u8 padding[3]; -} __packed; - -enum wl1271_channel_tune_bands { - WL1271_CHANNEL_TUNE_BAND_2_4, - WL1271_CHANNEL_TUNE_BAND_5, - WL1271_CHANNEL_TUNE_BAND_4_9 -}; - -#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 - -#define TEST_CMD_P2G_CAL 0x02 -#define TEST_CMD_CHANNEL_TUNE 0x0d -#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d -#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 -#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E -#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26 - -struct wl1271_general_parms_cmd { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - struct wl1271_ini_general_params general_params; - - u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM]; - u8 sr_sen_n_p; - u8 sr_sen_n_p_gain; - u8 sr_sen_nrn; - u8 sr_sen_prn; - u8 padding[3]; -} __packed; - -struct wl1271_radio_parms_cmd { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - /* Static radio parameters */ - struct wl1271_ini_band_params_2 static_params_2; - struct wl1271_ini_band_params_5 static_params_5; - - /* Dynamic radio parameters */ - struct wl1271_ini_fem_params_2 dyn_params_2; - u8 padding2; - struct wl1271_ini_fem_params_5 dyn_params_5; - u8 padding3[2]; -} __packed; - -struct wl1271_ext_radio_parms_cmd { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; - u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; - u8 padding[3]; -} __packed; - -struct wl1271_cmd_cal_channel_tune { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 band; - u8 channel; - - __le16 radio_status; -} __packed; - -struct wl1271_cmd_cal_update_ref_point { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le32 ref_power; - __le32 ref_detector; - u8 sub_band; - u8 padding[3]; -} __packed; - -#define MAX_TLV_LENGTH 400 -#define MAX_NVS_VERSION_LENGTH 12 - -#define WL1271_CAL_P2G_BAND_B_G BIT(0) - -struct wl1271_cmd_cal_p2g { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le16 len; - u8 buf[MAX_TLV_LENGTH]; - u8 type; - u8 padding; - - __le16 radio_status; - u8 nvs_version[MAX_NVS_VERSION_LENGTH]; - - u8 sub_band_mask; - u8 padding2; -} __packed; - - -/* - * There are three types of disconnections: - * - * DISCONNECT_IMMEDIATE: the fw doesn't send any frames - * DISCONNECT_DEAUTH: the fw generates a DEAUTH request with the reason - * we have passed - * DISCONNECT_DISASSOC: the fw generates a DESASSOC request with the reason - * we have passed - */ -enum wl1271_disconnect_type { - DISCONNECT_IMMEDIATE, - DISCONNECT_DEAUTH, - DISCONNECT_DISASSOC -}; - -struct wl1271_cmd_disconnect { - struct wl1271_cmd_header header; - - __le32 rx_config_options; - __le32 rx_filter_options; - - __le16 reason; - u8 type; - - u8 padding; -} __packed; - -#define WL1271_CMD_STA_STATE_CONNECTED 1 - -struct wl1271_cmd_set_sta_state { - struct wl1271_cmd_header header; - - u8 state; - u8 padding[3]; -} __packed; - -#endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h deleted file mode 100644 index 5f78a6cb1433..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_CONF_H__ -#define __WL1271_CONF_H__ - -enum { - CONF_HW_BIT_RATE_1MBPS = BIT(0), - CONF_HW_BIT_RATE_2MBPS = BIT(1), - CONF_HW_BIT_RATE_5_5MBPS = BIT(2), - CONF_HW_BIT_RATE_6MBPS = BIT(3), - CONF_HW_BIT_RATE_9MBPS = BIT(4), - CONF_HW_BIT_RATE_11MBPS = BIT(5), - CONF_HW_BIT_RATE_12MBPS = BIT(6), - CONF_HW_BIT_RATE_18MBPS = BIT(7), - CONF_HW_BIT_RATE_22MBPS = BIT(8), - CONF_HW_BIT_RATE_24MBPS = BIT(9), - CONF_HW_BIT_RATE_36MBPS = BIT(10), - CONF_HW_BIT_RATE_48MBPS = BIT(11), - CONF_HW_BIT_RATE_54MBPS = BIT(12), - CONF_HW_BIT_RATE_MCS_0 = BIT(13), - CONF_HW_BIT_RATE_MCS_1 = BIT(14), - CONF_HW_BIT_RATE_MCS_2 = BIT(15), - CONF_HW_BIT_RATE_MCS_3 = BIT(16), - CONF_HW_BIT_RATE_MCS_4 = BIT(17), - CONF_HW_BIT_RATE_MCS_5 = BIT(18), - CONF_HW_BIT_RATE_MCS_6 = BIT(19), - CONF_HW_BIT_RATE_MCS_7 = BIT(20) -}; - -enum { - CONF_HW_RATE_INDEX_1MBPS = 0, - CONF_HW_RATE_INDEX_2MBPS = 1, - CONF_HW_RATE_INDEX_5_5MBPS = 2, - CONF_HW_RATE_INDEX_6MBPS = 3, - CONF_HW_RATE_INDEX_9MBPS = 4, - CONF_HW_RATE_INDEX_11MBPS = 5, - CONF_HW_RATE_INDEX_12MBPS = 6, - CONF_HW_RATE_INDEX_18MBPS = 7, - CONF_HW_RATE_INDEX_22MBPS = 8, - CONF_HW_RATE_INDEX_24MBPS = 9, - CONF_HW_RATE_INDEX_36MBPS = 10, - CONF_HW_RATE_INDEX_48MBPS = 11, - CONF_HW_RATE_INDEX_54MBPS = 12, - CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, -}; - -enum { - CONF_HW_RXTX_RATE_MCS7 = 0, - CONF_HW_RXTX_RATE_MCS6, - CONF_HW_RXTX_RATE_MCS5, - CONF_HW_RXTX_RATE_MCS4, - CONF_HW_RXTX_RATE_MCS3, - CONF_HW_RXTX_RATE_MCS2, - CONF_HW_RXTX_RATE_MCS1, - CONF_HW_RXTX_RATE_MCS0, - CONF_HW_RXTX_RATE_54, - CONF_HW_RXTX_RATE_48, - CONF_HW_RXTX_RATE_36, - CONF_HW_RXTX_RATE_24, - CONF_HW_RXTX_RATE_22, - CONF_HW_RXTX_RATE_18, - CONF_HW_RXTX_RATE_12, - CONF_HW_RXTX_RATE_11, - CONF_HW_RXTX_RATE_9, - CONF_HW_RXTX_RATE_6, - CONF_HW_RXTX_RATE_5_5, - CONF_HW_RXTX_RATE_2, - CONF_HW_RXTX_RATE_1, - CONF_HW_RXTX_RATE_MAX, - CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff -}; - -enum { - CONF_SG_DISABLE = 0, - CONF_SG_PROTECTIVE, - CONF_SG_OPPORTUNISTIC -}; - -enum { - /* - * PER threshold in PPM of the BT voice - * - * Range: 0 - 10000000 - */ - CONF_SG_BT_PER_THRESHOLD = 0, - - /* - * Number of consequent RX_ACTIVE activities to override BT voice - * frames to ensure WLAN connection - * - * Range: 0 - 100 - */ - CONF_SG_HV3_MAX_OVERRIDE, - - /* - * Defines the PER threshold of the BT voice - * - * Range: 0 - 65000 - */ - CONF_SG_BT_NFS_SAMPLE_INTERVAL, - - /* - * Defines the load ratio of BT - * - * Range: 0 - 100 (%) - */ - CONF_SG_BT_LOAD_RATIO, - - /* - * Defines whether the SG will force WLAN host to enter/exit PSM - * - * Range: 1 - SG can force, 0 - host handles PSM - */ - CONF_SG_AUTO_PS_MODE, - - /* - * Compensation percentage of probe requests when scan initiated - * during BT voice/ACL link. - * - * Range: 0 - 255 (%) - */ - CONF_SG_AUTO_SCAN_PROBE_REQ, - - /* - * Compensation percentage of probe requests when active scan initiated - * during BT voice - * - * Range: 0 - 255 (%) - */ - CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3, - - /* - * Defines antenna configuration (single/dual antenna) - * - * Range: 0 - single antenna, 1 - dual antenna - */ - CONF_SG_ANTENNA_CONFIGURATION, - - /* - * The threshold (percent) of max consequtive beacon misses before - * increasing priority of beacon reception. - * - * Range: 0 - 100 (%) - */ - CONF_SG_BEACON_MISS_PERCENT, - - /* - * The rate threshold below which receiving a data frame from the AP - * will increase the priority of the data frame above BT traffic. - * - * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54 - */ - CONF_SG_RATE_ADAPT_THRESH, - - /* - * Not used currently. - * - * Range: 0 - */ - CONF_SG_RATE_ADAPT_SNR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT master basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR, - CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT master basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT slave basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR, - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT slave basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR, - CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR, - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR, - - /* - * RX guard time before the beginning of a new BT voice frame during - * which no new WLAN trigger frame is transmitted. - * - * Range: 0 - 100000 (us) - */ - CONF_SG_RXT, - - /* - * TX guard time before the beginning of a new BT voice frame during - * which no new WLAN frame is transmitted. - * - * Range: 0 - 100000 (us) - */ - - CONF_SG_TXT, - - /* - * Enable adaptive RXT/TXT algorithm. If disabled, the host values - * will be utilized. - * - * Range: 0 - disable, 1 - enable - */ - CONF_SG_ADAPTIVE_RXT_TXT, - - /* - * The used WLAN legacy service period during active BT ACL link - * - * Range: 0 - 255 (ms) - */ - CONF_SG_PS_POLL_TIMEOUT, - - /* - * The used WLAN UPSD service period during active BT ACL link - * - * Range: 0 - 255 (ms) - */ - CONF_SG_UPSD_TIMEOUT, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR, - CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR, - CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR, - CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR, - - /* - * Compensation percentage of WLAN passive scan window if initiated - * during BT voice - * - * Range: 0 - 1000 (%) - */ - CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3, - - /* - * Compensation percentage of WLAN passive scan window if initiated - * during BT A2DP - * - * Range: 0 - 1000 (%) - */ - CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP, - - /* - * Fixed time ensured for BT traffic to gain the antenna during WLAN - * passive scan. - * - * Range: 0 - 1000 ms - */ - CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME, - - /* - * Fixed time ensured for WLAN traffic to gain the antenna during WLAN - * passive scan. - * - * Range: 0 - 1000 ms - */ - CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME, - - /* - * Number of consequent BT voice frames not interrupted by WLAN - * - * Range: 0 - 100 - */ - CONF_SG_HV3_MAX_SERVED, - - /* - * Protection time of the DHCP procedure. - * - * Range: 0 - 100000 (ms) - */ - CONF_SG_DHCP_TIME, - - /* - * Compensation percentage of WLAN active scan window if initiated - * during BT A2DP - * - * Range: 0 - 1000 (%) - */ - CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP, - CONF_SG_TEMP_PARAM_1, - CONF_SG_TEMP_PARAM_2, - CONF_SG_TEMP_PARAM_3, - CONF_SG_TEMP_PARAM_4, - CONF_SG_TEMP_PARAM_5, - CONF_SG_PARAMS_MAX, - CONF_SG_PARAMS_ALL = 0xff -}; - -struct conf_sg_settings { - u32 params[CONF_SG_PARAMS_MAX]; - u8 state; -}; - -enum conf_rx_queue_type { - CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ - CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */ -}; - -struct conf_rx_settings { - /* - * The maximum amount of time, in TU, before the - * firmware discards the MSDU. - * - * Range: 0 - 0xFFFFFFFF - */ - u32 rx_msdu_life_time; - - /* - * Packet detection threshold in the PHY. - * - * FIXME: details unknown. - */ - u32 packet_detection_threshold; - - /* - * The longest time the STA will wait to receive traffic from the AP - * after a PS-poll has been transmitted. - * - * Range: 0 - 200000 - */ - u16 ps_poll_timeout; - /* - * The longest time the STA will wait to receive traffic from the AP - * after a frame has been sent from an UPSD enabled queue. - * - * Range: 0 - 200000 - */ - u16 upsd_timeout; - - /* - * The number of octets in an MPDU, below which an RTS/CTS - * handshake is not performed. - * - * Range: 0 - 4096 - */ - u16 rts_threshold; - - /* - * The RX Clear Channel Assessment threshold in the PHY - * (the energy threshold). - * - * Range: ENABLE_ENERGY_D == 0x140A - * DISABLE_ENERGY_D == 0xFFEF - */ - u16 rx_cca_threshold; - - /* - * Occupied Rx mem-blocks number which requires interrupting the host - * (0 = no buffering, 0xffff = disabled). - * - * Range: u16 - */ - u16 irq_blk_threshold; - - /* - * Rx packets number which requires interrupting the host - * (0 = no buffering). - * - * Range: u16 - */ - u16 irq_pkt_threshold; - - /* - * Max time in msec the FW may delay RX-Complete interrupt. - * - * Range: 1 - 100 - */ - u16 irq_timeout; - - /* - * The RX queue type. - * - * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, - */ - u8 queue_type; -}; - -#define CONF_TX_MAX_RATE_CLASSES 8 - -#define CONF_TX_RATE_MASK_UNSPECIFIED 0 -#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \ - CONF_HW_BIT_RATE_2MBPS) -#define CONF_TX_RATE_RETRY_LIMIT 10 - -struct conf_tx_rate_class { - - /* - * The rates enabled for this rate class. - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 enabled_rates; - - /* - * The dot11 short retry limit used for TX retries. - * - * Range: u8 - */ - u8 short_retry_limit; - - /* - * The dot11 long retry limit used for TX retries. - * - * Range: u8 - */ - u8 long_retry_limit; - - /* - * Flags controlling the attributes of TX transmission. - * - * Range: bit 0: Truncate - when set, FW attempts to send a frame stop - * when the total valid per-rate attempts have - * been exhausted; otherwise transmissions - * will continue at the lowest available rate - * until the appropriate one of the - * short_retry_limit, long_retry_limit, - * dot11_max_transmit_msdu_life_time, or - * max_tx_life_time, is exhausted. - * 1: Preamble Override - indicates if the preamble type - * should be used in TX. - * 2: Preamble Type - the type of the preamble to be used by - * the policy (0 - long preamble, 1 - short preamble. - */ - u8 aflags; -}; - -#define CONF_TX_MAX_AC_COUNT 4 - -/* Slot number setting to start transmission at PIFS interval */ -#define CONF_TX_AIFS_PIFS 1 -/* Slot number setting to start transmission at DIFS interval normal - * DCF access */ -#define CONF_TX_AIFS_DIFS 2 - - -enum conf_tx_ac { - CONF_TX_AC_BE = 0, /* best effort / legacy */ - CONF_TX_AC_BK = 1, /* background */ - CONF_TX_AC_VI = 2, /* video */ - CONF_TX_AC_VO = 3, /* voice */ - CONF_TX_AC_CTS2SELF = 4, /* fictious AC, follows AC_VO */ - CONF_TX_AC_ANY_TID = 0x1f -}; - -struct conf_tx_ac_category { - /* - * The AC class identifier. - * - * Range: enum conf_tx_ac - */ - u8 ac; - - /* - * The contention window minimum size (in slots) for the access - * class. - * - * Range: u8 - */ - u8 cw_min; - - /* - * The contention window maximum size (in slots) for the access - * class. - * - * Range: u8 - */ - u16 cw_max; - - /* - * The AIF value (in slots) for the access class. - * - * Range: u8 - */ - u8 aifsn; - - /* - * The TX Op Limit (in microseconds) for the access class. - * - * Range: u16 - */ - u16 tx_op_limit; -}; - -#define CONF_TX_MAX_TID_COUNT 8 - -enum { - CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ - CONF_CHANNEL_TYPE_EDCF = 1, /* EDCA*/ - CONF_CHANNEL_TYPE_HCCA = 2, /* HCCA*/ -}; - -enum { - CONF_PS_SCHEME_LEGACY = 0, - CONF_PS_SCHEME_UPSD_TRIGGER = 1, - CONF_PS_SCHEME_LEGACY_PSPOLL = 2, - CONF_PS_SCHEME_SAPSD = 3, -}; - -enum { - CONF_ACK_POLICY_LEGACY = 0, - CONF_ACK_POLICY_NO_ACK = 1, - CONF_ACK_POLICY_BLOCK = 2, -}; - - -struct conf_tx_tid { - u8 queue_id; - u8 channel_type; - u8 tsid; - u8 ps_scheme; - u8 ack_policy; - u32 apsd_conf[2]; -}; - -struct conf_tx_settings { - /* - * The TX ED value for TELEC Enable/Disable. - * - * Range: 0, 1 - */ - u8 tx_energy_detection; - - /* - * Configuration for rate classes for TX (currently only one - * rate class supported.) - */ - struct conf_tx_rate_class rc_conf; - - /* - * Configuration for access categories for TX rate control. - */ - u8 ac_conf_count; - struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT]; - - /* - * Configuration for TID parameters. - */ - u8 tid_conf_count; - struct conf_tx_tid tid_conf[CONF_TX_MAX_TID_COUNT]; - - /* - * The TX fragmentation threshold. - * - * Range: u16 - */ - u16 frag_threshold; - - /* - * Max time in msec the FW may delay frame TX-Complete interrupt. - * - * Range: u16 - */ - u16 tx_compl_timeout; - - /* - * Completed TX packet count which requires to issue the TX-Complete - * interrupt. - * - * Range: u16 - */ - u16 tx_compl_threshold; - - /* - * The rate used for control messages and scanning on the 2.4GHz band - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 basic_rate; - - /* - * The rate used for control messages and scanning on the 5GHz band - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 basic_rate_5; -}; - -enum { - CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ - CONF_WAKE_UP_EVENT_DTIM = 0x02, /* Wake on every DTIM*/ - CONF_WAKE_UP_EVENT_N_DTIM = 0x04, /* Wake every Nth DTIM */ - CONF_WAKE_UP_EVENT_N_BEACONS = 0x08, /* Wake every Nth beacon */ - CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F -}; - -#define CONF_MAX_BCN_FILT_IE_COUNT 32 - -#define CONF_BCN_RULE_PASS_ON_CHANGE BIT(0) -#define CONF_BCN_RULE_PASS_ON_APPEARANCE BIT(1) - -#define CONF_BCN_IE_OUI_LEN 3 -#define CONF_BCN_IE_VER_LEN 2 - -struct conf_bcn_filt_rule { - /* - * IE number to which to associate a rule. - * - * Range: u8 - */ - u8 ie; - - /* - * Rule to associate with the specific ie. - * - * Range: CONF_BCN_RULE_PASS_ON_* - */ - u8 rule; - - /* - * OUI for the vendor specifie IE (221) - */ - u8 oui[CONF_BCN_IE_OUI_LEN]; - - /* - * Type for the vendor specifie IE (221) - */ - u8 type; - - /* - * Version for the vendor specifie IE (221) - */ - u8 version[CONF_BCN_IE_VER_LEN]; -}; - -#define CONF_MAX_RSSI_SNR_TRIGGERS 8 - -enum { - CONF_TRIG_METRIC_RSSI_BEACON = 0, - CONF_TRIG_METRIC_RSSI_DATA, - CONF_TRIG_METRIC_SNR_BEACON, - CONF_TRIG_METRIC_SNR_DATA -}; - -enum { - CONF_TRIG_EVENT_TYPE_LEVEL = 0, - CONF_TRIG_EVENT_TYPE_EDGE -}; - -enum { - CONF_TRIG_EVENT_DIR_LOW = 0, - CONF_TRIG_EVENT_DIR_HIGH, - CONF_TRIG_EVENT_DIR_BIDIR -}; - -struct conf_sig_weights { - - /* - * RSSI from beacons average weight. - * - * Range: u8 - */ - u8 rssi_bcn_avg_weight; - - /* - * RSSI from data average weight. - * - * Range: u8 - */ - u8 rssi_pkt_avg_weight; - - /* - * SNR from beacons average weight. - * - * Range: u8 - */ - u8 snr_bcn_avg_weight; - - /* - * SNR from data average weight. - * - * Range: u8 - */ - u8 snr_pkt_avg_weight; -}; - -enum conf_bcn_filt_mode { - CONF_BCN_FILT_MODE_DISABLED = 0, - CONF_BCN_FILT_MODE_ENABLED = 1 -}; - -enum conf_bet_mode { - CONF_BET_MODE_DISABLE = 0, - CONF_BET_MODE_ENABLE = 1, -}; - -struct conf_conn_settings { - /* - * Firmware wakeup conditions configuration. The host may set only - * one bit. - * - * Range: CONF_WAKE_UP_EVENT_* - */ - u8 wake_up_event; - - /* - * Listen interval for beacons or Dtims. - * - * Range: 0 for beacon and Dtim wakeup - * 1-10 for x Dtims - * 1-255 for x beacons - */ - u8 listen_interval; - - /* - * Enable or disable the beacon filtering. - * - * Range: CONF_BCN_FILT_MODE_* - */ - enum conf_bcn_filt_mode bcn_filt_mode; - - /* - * Configure Beacon filter pass-thru rules. - */ - u8 bcn_filt_ie_count; - struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT]; - - /* - * The number of consequtive beacons to lose, before the firmware - * becomes out of synch. - * - * Range: u32 - */ - u32 synch_fail_thold; - - /* - * After out-of-synch, the number of TU's to wait without a further - * received beacon (or probe response) before issuing the BSS_EVENT_LOSE - * event. - * - * Range: u32 - */ - u32 bss_lose_timeout; - - /* - * Beacon receive timeout. - * - * Range: u32 - */ - u32 beacon_rx_timeout; - - /* - * Broadcast receive timeout. - * - * Range: u32 - */ - u32 broadcast_timeout; - - /* - * Enable/disable reception of broadcast packets in power save mode - * - * Range: 1 - enable, 0 - disable - */ - u8 rx_broadcast_in_ps; - - /* - * Consequtive PS Poll failures before sending event to driver - * - * Range: u8 - */ - u8 ps_poll_threshold; - - /* - * PS Poll failure recovery ACTIVE period length - * - * Range: u32 (ms) - */ - u32 ps_poll_recovery_period; - - /* - * Configuration of signal average weights. - */ - struct conf_sig_weights sig_weights; - - /* - * Specifies if beacon early termination procedure is enabled or - * disabled. - * - * Range: CONF_BET_MODE_* - */ - u8 bet_enable; - - /* - * Specifies the maximum number of consecutive beacons that may be - * early terminated. After this number is reached at least one full - * beacon must be correctly received in FW before beacon ET - * resumes. - * - * Range 0 - 255 - */ - u8 bet_max_consecutive; - - /* - * Specifies the maximum number of times to try PSM entry if it fails - * (if sending the appropriate null-func message fails.) - * - * Range 0 - 255 - */ - u8 psm_entry_retries; - - /* - * Specifies the maximum number of times to try transmit the PSM entry - * null-func frame for each PSM entry attempt - * - * Range 0 - 255 - */ - u8 psm_entry_nullfunc_retries; - - /* - * Specifies the time to linger in active mode after successfully - * transmitting the PSM entry null-func frame. - * - * Range 0 - 255 TU's - */ - u8 psm_entry_hangover_period; - - /* - * - * Specifies the interval of the connection keep-alive null-func - * frame in ms. - * - * Range: 1000 - 3600000 - */ - u32 keep_alive_interval; - - /* - * Maximum listen interval supported by the driver in units of beacons. - * - * Range: u16 - */ - u8 max_listen_interval; -}; - -enum { - CONF_REF_CLK_19_2_E, - CONF_REF_CLK_26_E, - CONF_REF_CLK_38_4_E, - CONF_REF_CLK_52_E -}; - -enum single_dual_band_enum { - CONF_SINGLE_BAND, - CONF_DUAL_BAND -}; - -#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15 -#define CONF_NUMBER_OF_SUB_BANDS_5 7 -#define CONF_NUMBER_OF_RATE_GROUPS 6 -#define CONF_NUMBER_OF_CHANNELS_2_4 14 -#define CONF_NUMBER_OF_CHANNELS_5 35 - -struct conf_radio_parms { - /* - * FEM parameter set to use - * - * Range: 0 or 1 - */ - u8 fem; -}; - -struct conf_itrim_settings { - /* enable dco itrim */ - u8 enable; - - /* moderation timeout in microsecs from the last TX */ - u32 timeout; -}; - -struct conf_pm_config_settings { - /* - * Host clock settling time - * - * Range: 0 - 30000 us - */ - u32 host_clk_settling_time; - - /* - * Host fast wakeup support - * - * Range: true, false - */ - bool host_fast_wakeup_support; -}; - -struct conf_roam_trigger_settings { - /* - * The minimum interval between two trigger events. - * - * Range: 0 - 60000 ms - */ - u16 trigger_pacing; - - /* - * The weight for rssi/beacon average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_rssi_beacon; - - /* - * The weight for rssi/data frame average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_rssi_data; - - /* - * The weight for snr/beacon average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_snr_beacon; - - /* - * The weight for snr/data frame average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_snr_data; -}; - -struct conf_scan_settings { - /* - * The minimum time to wait on each channel for active scans - * - * Range: 0 - 65536 tu - */ - u16 min_dwell_time_active; - - /* - * The maximum time to wait on each channel for active scans - * - * Range: 0 - 65536 tu - */ - u16 max_dwell_time_active; - - /* - * The maximum time to wait on each channel for passive scans - * - * Range: 0 - 65536 tu - */ - u16 min_dwell_time_passive; - - /* - * The maximum time to wait on each channel for passive scans - * - * Range: 0 - 65536 tu - */ - u16 max_dwell_time_passive; - - /* - * Number of probe requests to transmit on each active scan channel - * - * Range: u8 - */ - u16 num_probe_reqs; - -}; - -/* these are number of channels on the band divided by two, rounded up */ -#define CONF_TX_PWR_COMPENSATION_LEN_2 7 -#define CONF_TX_PWR_COMPENSATION_LEN_5 18 - -struct conf_rf_settings { - /* - * Per channel power compensation for 2.4GHz - * - * Range: s8 - */ - u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; - - /* - * Per channel power compensation for 5GHz - * - * Range: s8 - */ - u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; -}; - -struct conf_drv_settings { - struct conf_sg_settings sg; - struct conf_rx_settings rx; - struct conf_tx_settings tx; - struct conf_conn_settings conn; - struct conf_itrim_settings itrim; - struct conf_pm_config_settings pm_config; - struct conf_roam_trigger_settings roam_trigger; - struct conf_scan_settings scan; - struct conf_rf_settings rf; -}; - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c deleted file mode 100644 index 3468b849852e..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1271_debugfs.h" - -#include -#include - -#include "wl1271.h" -#include "wl1271_acx.h" -#include "wl1271_ps.h" -#include "wl1271_io.h" - -/* ms */ -#define WL1271_DEBUGFS_STATS_LIFETIME 1000 - -/* debugfs macros idea from mac80211 */ -#define DEBUGFS_FORMAT_BUFFER_SIZE 100 -static int wl1271_format_buffer(char __user *userbuf, size_t count, - loff_t *ppos, char *fmt, ...) -{ - va_list args; - char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; - int res; - - va_start(args, fmt); - res = vscnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - return simple_read_from_buffer(userbuf, count, ppos, buf, res); -} - -#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ -static ssize_t name## _read(struct file *file, char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1271 *wl = file->private_data; \ - return wl1271_format_buffer(userbuf, count, ppos, \ - fmt "\n", ##value); \ -} \ - \ -static const struct file_operations name## _ops = { \ - .read = name## _read, \ - .open = wl1271_open_file_generic, \ - .llseek = generic_file_llseek, \ -}; - -#define DEBUGFS_ADD(name, parent) \ - wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ - wl, &name## _ops); \ - if (IS_ERR(wl->debugfs.name)) { \ - ret = PTR_ERR(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - goto out; \ - } - -#define DEBUGFS_DEL(name) \ - do { \ - debugfs_remove(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - } while (0) - -#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ -static ssize_t sub## _ ##name## _read(struct file *file, \ - char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1271 *wl = file->private_data; \ - \ - wl1271_debugfs_update_stats(wl); \ - \ - return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ - wl->stats.fw_stats->sub.name); \ -} \ - \ -static const struct file_operations sub## _ ##name## _ops = { \ - .read = sub## _ ##name## _read, \ - .open = wl1271_open_file_generic, \ - .llseek = generic_file_llseek, \ -}; - -#define DEBUGFS_FWSTATS_ADD(sub, name) \ - DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) - -#define DEBUGFS_FWSTATS_DEL(sub, name) \ - DEBUGFS_DEL(sub## _ ##name) - -static void wl1271_debugfs_update_stats(struct wl1271 *wl) -{ - int ret; - - mutex_lock(&wl->mutex); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - if (wl->state == WL1271_STATE_ON && - time_after(jiffies, wl->stats.fw_stats_update + - msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { - wl1271_acx_statistics(wl, wl->stats.fw_stats); - wl->stats.fw_stats_update = jiffies; - } - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); - -DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); -DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); -DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); -DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); -DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); -DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); - -DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); -DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); - -DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); -DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); -DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); -DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); -DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); -DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); -DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); -DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); - -DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); -DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); -/* skipping wep.reserved */ -DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); -DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); -DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); - -DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); -/* skipping cont_miss_bcns_spread for now */ -DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); - -DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); -DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); - -DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); - -DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); -DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); -DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); -DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); -DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); - -DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); - -DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); - -DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); -DEBUGFS_READONLY_FILE(excessive_retries, "%u", - wl->stats.excessive_retries); - -static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - u32 queue_len; - char buf[20]; - int res; - - queue_len = skb_queue_len(&wl->tx_queue); - - res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); - return simple_read_from_buffer(userbuf, count, ppos, buf, res); -} - -static const struct file_operations tx_queue_len_ops = { - .read = tx_queue_len_read, - .open = wl1271_open_file_generic, - .llseek = default_llseek, -}; - -static ssize_t gpio_power_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); - - int res; - char buf[10]; - - res = scnprintf(buf, sizeof(buf), "%d\n", state); - - return simple_read_from_buffer(user_buf, count, ppos, buf, res); -} - -static ssize_t gpio_power_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; - unsigned long value; - int ret; - - mutex_lock(&wl->mutex); - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) { - ret = -EFAULT; - goto out; - } - buf[len] = '\0'; - - ret = strict_strtoul(buf, 0, &value); - if (ret < 0) { - wl1271_warning("illegal value in gpio_power"); - goto out; - } - - if (value) - wl1271_power_on(wl); - else - wl1271_power_off(wl); - -out: - mutex_unlock(&wl->mutex); - return count; -} - -static const struct file_operations gpio_power_ops = { - .read = gpio_power_read, - .write = gpio_power_write, - .open = wl1271_open_file_generic, - .llseek = default_llseek, -}; - -static void wl1271_debugfs_delete_files(struct wl1271 *wl) -{ - DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_DEL(rx, out_of_mem); - DEBUGFS_FWSTATS_DEL(rx, hdr_overflow); - DEBUGFS_FWSTATS_DEL(rx, hw_stuck); - DEBUGFS_FWSTATS_DEL(rx, dropped); - DEBUGFS_FWSTATS_DEL(rx, fcs_err); - DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_DEL(rx, path_reset); - DEBUGFS_FWSTATS_DEL(rx, reset_counter); - - DEBUGFS_FWSTATS_DEL(dma, rx_requested); - DEBUGFS_FWSTATS_DEL(dma, rx_errors); - DEBUGFS_FWSTATS_DEL(dma, tx_requested); - DEBUGFS_FWSTATS_DEL(dma, tx_errors); - - DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt); - DEBUGFS_FWSTATS_DEL(isr, fiqs); - DEBUGFS_FWSTATS_DEL(isr, rx_headers); - DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_DEL(isr, rx_rdys); - DEBUGFS_FWSTATS_DEL(isr, irqs); - DEBUGFS_FWSTATS_DEL(isr, tx_procs); - DEBUGFS_FWSTATS_DEL(isr, decrypt_done); - DEBUGFS_FWSTATS_DEL(isr, dma0_done); - DEBUGFS_FWSTATS_DEL(isr, dma1_done); - DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete); - DEBUGFS_FWSTATS_DEL(isr, commands); - DEBUGFS_FWSTATS_DEL(isr, rx_procs); - DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_DEL(isr, host_acknowledges); - DEBUGFS_FWSTATS_DEL(isr, pci_pm); - DEBUGFS_FWSTATS_DEL(isr, wakeups); - DEBUGFS_FWSTATS_DEL(isr, low_rssi); - - DEBUGFS_FWSTATS_DEL(wep, addr_key_count); - DEBUGFS_FWSTATS_DEL(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_DEL(wep, key_not_found); - DEBUGFS_FWSTATS_DEL(wep, decrypt_fail); - DEBUGFS_FWSTATS_DEL(wep, packets); - DEBUGFS_FWSTATS_DEL(wep, interrupt); - - DEBUGFS_FWSTATS_DEL(pwr, ps_enter); - DEBUGFS_FWSTATS_DEL(pwr, elp_enter); - DEBUGFS_FWSTATS_DEL(pwr, missing_bcns); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_host); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps); - DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps); - DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_DEL(pwr, power_save_off); - DEBUGFS_FWSTATS_DEL(pwr, enable_ps); - DEBUGFS_FWSTATS_DEL(pwr, disable_ps); - DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_DEL(mic, rx_pkts); - DEBUGFS_FWSTATS_DEL(mic, calc_failure); - - DEBUGFS_FWSTATS_DEL(aes, encrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, decrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, encrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, decrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_DEL(event, heart_beat); - DEBUGFS_FWSTATS_DEL(event, calibration); - DEBUGFS_FWSTATS_DEL(event, rx_mismatch); - DEBUGFS_FWSTATS_DEL(event, rx_mem_empty); - DEBUGFS_FWSTATS_DEL(event, rx_pool); - DEBUGFS_FWSTATS_DEL(event, oom_late); - DEBUGFS_FWSTATS_DEL(event, phy_transmit_error); - DEBUGFS_FWSTATS_DEL(event, tx_stuck); - - DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization); - DEBUGFS_FWSTATS_DEL(ps, upsd_utilization); - - DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); - - DEBUGFS_DEL(tx_queue_len); - DEBUGFS_DEL(retry_count); - DEBUGFS_DEL(excessive_retries); - - DEBUGFS_DEL(gpio_power); -} - -static int wl1271_debugfs_add_files(struct wl1271 *wl) -{ - int ret = 0; - - DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_ADD(rx, out_of_mem); - DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); - DEBUGFS_FWSTATS_ADD(rx, hw_stuck); - DEBUGFS_FWSTATS_ADD(rx, dropped); - DEBUGFS_FWSTATS_ADD(rx, fcs_err); - DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_ADD(rx, path_reset); - DEBUGFS_FWSTATS_ADD(rx, reset_counter); - - DEBUGFS_FWSTATS_ADD(dma, rx_requested); - DEBUGFS_FWSTATS_ADD(dma, rx_errors); - DEBUGFS_FWSTATS_ADD(dma, tx_requested); - DEBUGFS_FWSTATS_ADD(dma, tx_errors); - - DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); - DEBUGFS_FWSTATS_ADD(isr, fiqs); - DEBUGFS_FWSTATS_ADD(isr, rx_headers); - DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_ADD(isr, rx_rdys); - DEBUGFS_FWSTATS_ADD(isr, irqs); - DEBUGFS_FWSTATS_ADD(isr, tx_procs); - DEBUGFS_FWSTATS_ADD(isr, decrypt_done); - DEBUGFS_FWSTATS_ADD(isr, dma0_done); - DEBUGFS_FWSTATS_ADD(isr, dma1_done); - DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); - DEBUGFS_FWSTATS_ADD(isr, commands); - DEBUGFS_FWSTATS_ADD(isr, rx_procs); - DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); - DEBUGFS_FWSTATS_ADD(isr, pci_pm); - DEBUGFS_FWSTATS_ADD(isr, wakeups); - DEBUGFS_FWSTATS_ADD(isr, low_rssi); - - DEBUGFS_FWSTATS_ADD(wep, addr_key_count); - DEBUGFS_FWSTATS_ADD(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_ADD(wep, key_not_found); - DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); - DEBUGFS_FWSTATS_ADD(wep, packets); - DEBUGFS_FWSTATS_ADD(wep, interrupt); - - DEBUGFS_FWSTATS_ADD(pwr, ps_enter); - DEBUGFS_FWSTATS_ADD(pwr, elp_enter); - DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); - DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); - DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_ADD(pwr, power_save_off); - DEBUGFS_FWSTATS_ADD(pwr, enable_ps); - DEBUGFS_FWSTATS_ADD(pwr, disable_ps); - DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_ADD(mic, rx_pkts); - DEBUGFS_FWSTATS_ADD(mic, calc_failure); - - DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_ADD(event, heart_beat); - DEBUGFS_FWSTATS_ADD(event, calibration); - DEBUGFS_FWSTATS_ADD(event, rx_mismatch); - DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); - DEBUGFS_FWSTATS_ADD(event, rx_pool); - DEBUGFS_FWSTATS_ADD(event, oom_late); - DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); - DEBUGFS_FWSTATS_ADD(event, tx_stuck); - - DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); - DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); - - DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); - - DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); - DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); - DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); - - DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir); - -out: - if (ret < 0) - wl1271_debugfs_delete_files(wl); - - return ret; -} - -void wl1271_debugfs_reset(struct wl1271 *wl) -{ - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); - wl->stats.retry_count = 0; - wl->stats.excessive_retries = 0; -} - -int wl1271_debugfs_init(struct wl1271 *wl) -{ - int ret; - - wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); - - if (IS_ERR(wl->debugfs.rootdir)) { - ret = PTR_ERR(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - goto err; - } - - wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics", - wl->debugfs.rootdir); - - if (IS_ERR(wl->debugfs.fw_statistics)) { - ret = PTR_ERR(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - goto err_root; - } - - wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), - GFP_KERNEL); - - if (!wl->stats.fw_stats) { - ret = -ENOMEM; - goto err_fw; - } - - wl->stats.fw_stats_update = jiffies; - - ret = wl1271_debugfs_add_files(wl); - - if (ret < 0) - goto err_file; - - return 0; - -err_file: - kfree(wl->stats.fw_stats); - wl->stats.fw_stats = NULL; - -err_fw: - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - -err_root: - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - -err: - return ret; -} - -void wl1271_debugfs_exit(struct wl1271 *wl) -{ - wl1271_debugfs_delete_files(wl); - - kfree(wl->stats.fw_stats); - wl->stats.fw_stats = NULL; - - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - -} diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/wl1271_debugfs.h deleted file mode 100644 index 00a45b2669ad..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef WL1271_DEBUGFS_H -#define WL1271_DEBUGFS_H - -#include "wl1271.h" - -int wl1271_debugfs_init(struct wl1271 *wl); -void wl1271_debugfs_exit(struct wl1271 *wl); -void wl1271_debugfs_reset(struct wl1271 *wl); - -#endif /* WL1271_DEBUGFS_H */ diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c deleted file mode 100644 index 38ccef7d73a5..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1271.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_event.h" -#include "wl1271_ps.h" -#include "wl1271_scan.h" -#include "wl12xx_80211.h" - -void wl1271_pspoll_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1271 *wl; - - dwork = container_of(work, struct delayed_work, work); - wl = container_of(dwork, struct wl1271, pspoll_work); - - wl1271_debug(DEBUG_EVENT, "pspoll work"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) - goto out; - - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - goto out; - - /* - * if we end up here, then we were in powersave when the pspoll - * delivery failure occurred, and no-one changed state since, so - * we should go back to powersave. - */ - wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); - -out: - mutex_unlock(&wl->mutex); -}; - -static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl) -{ - int delay = wl->conf.conn.ps_poll_recovery_period; - int ret; - - wl->ps_poll_failures++; - if (wl->ps_poll_failures == 1) - wl1271_info("AP with dysfunctional ps-poll, " - "trying to work around it."); - - /* force active mode receive data from the AP */ - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate, true); - if (ret < 0) - return; - set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); - ieee80211_queue_delayed_work(wl->hw, &wl->pspoll_work, - msecs_to_jiffies(delay)); - } - - /* - * If already in active mode, lets we should be getting data from - * the AP right away. If we enter PSM too fast after this, and data - * remains on the AP, we will get another event like this, and we'll - * go into active once more. - */ -} - -static int wl1271_event_ps_report(struct wl1271 *wl, - struct event_mailbox *mbox, - bool *beacon_loss) -{ - int ret = 0; - u32 total_retries = wl->conf.conn.psm_entry_retries; - - wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); - - switch (mbox->ps_status) { - case EVENT_ENTER_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM entry failed"); - - if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) { - /* remain in active mode */ - wl->psm_entry_retry = 0; - break; - } - - if (wl->psm_entry_retry < total_retries) { - wl->psm_entry_retry++; - ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - wl->basic_rate, true); - } else { - wl1271_info("No ack to nullfunc from AP."); - wl->psm_entry_retry = 0; - *beacon_loss = true; - } - break; - case EVENT_ENTER_POWER_SAVE_SUCCESS: - wl->psm_entry_retry = 0; - - /* enable beacon filtering */ - ret = wl1271_acx_beacon_filter_opt(wl, true); - if (ret < 0) - break; - - /* enable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, true); - if (ret < 0) - break; - - /* go to extremely low power mode */ - wl1271_ps_elp_sleep(wl); - break; - case EVENT_EXIT_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM exit failed"); - - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - wl->psm_entry_retry = 0; - break; - } - - /* make sure the firmware goes to active mode - the frame to - be sent next will indicate to the AP, that we are active. */ - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate, false); - break; - case EVENT_EXIT_POWER_SAVE_SUCCESS: - default: - break; - } - - return ret; -} - -static void wl1271_event_rssi_trigger(struct wl1271 *wl, - struct event_mailbox *mbox) -{ - enum nl80211_cqm_rssi_threshold_event event; - s8 metric = mbox->rssi_snr_trigger_metric[0]; - - wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric); - - if (metric <= wl->rssi_thold) - event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; - else - event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; - - if (event != wl->last_rssi_event) - ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL); - wl->last_rssi_event = event; -} - -static void wl1271_event_mbox_dump(struct event_mailbox *mbox) -{ - wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); - wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); - wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); -} - -static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) -{ - int ret; - u32 vector; - bool beacon_loss = false; - - wl1271_event_mbox_dump(mbox); - - vector = le32_to_cpu(mbox->events_vector); - vector &= ~(le32_to_cpu(mbox->events_mask)); - wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector); - - if (vector & SCAN_COMPLETE_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "status: 0x%x", - mbox->scheduled_scan_status); - - wl1271_scan_stm(wl); - } - - /* disable dynamic PS when requested by the firmware */ - if (vector & SOFT_GEMINI_SENSE_EVENT_ID && - wl->bss_type == BSS_TYPE_STA_BSS) { - if (mbox->soft_gemini_sense_info) - ieee80211_disable_dyn_ps(wl->vif); - else - ieee80211_enable_dyn_ps(wl->vif); - } - - /* - * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon - * filtering) is enabled. Without PSM, the stack will receive all - * beacons and can detect beacon loss by itself. - * - * As there's possibility that the driver disables PSM before receiving - * BSS_LOSE_EVENT, beacon loss has to be reported to the stack. - * - */ - if (vector & BSS_LOSE_EVENT_ID) { - wl1271_info("Beacon loss detected."); - - /* indicate to the stack, that beacons have been lost */ - beacon_loss = true; - } - - if (vector & PS_REPORT_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); - ret = wl1271_event_ps_report(wl, mbox, &beacon_loss); - if (ret < 0) - return ret; - } - - if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) - wl1271_event_pspoll_delivery_fail(wl); - - if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); - if (wl->vif) - wl1271_event_rssi_trigger(wl, mbox); - } - - if (wl->vif && beacon_loss) - ieee80211_connection_loss(wl->vif); - - return 0; -} - -int wl1271_event_unmask(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask)); - if (ret < 0) - return ret; - - return 0; -} - -void wl1271_event_mbox_config(struct wl1271 *wl) -{ - wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); - wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); - - wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", - wl->mbox_ptr[0], wl->mbox_ptr[1]); -} - -int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) -{ - struct event_mailbox mbox; - int ret; - - wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); - - if (mbox_num > 1) - return -EINVAL; - - /* first we read the mbox descriptor */ - wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox, - sizeof(struct event_mailbox), false); - - /* process the descriptor */ - ret = wl1271_event_process(wl, &mbox); - if (ret < 0) - return ret; - - /* then we let the firmware know it can go on...*/ - wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); - - return 0; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h deleted file mode 100644 index e4751667cf5e..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_event.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_EVENT_H__ -#define __WL1271_EVENT_H__ - -/* - * Mbox events - * - * The event mechanism is based on a pair of event buffers (buffers A and - * B) at fixed locations in the target's memory. The host processes one - * buffer while the other buffer continues to collect events. If the host - * is not processing events, an interrupt is issued to signal that a buffer - * is ready. Once the host is done with processing events from one buffer, - * it signals the target (with an ACK interrupt) that the event buffer is - * free. - */ - -enum { - RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0), - RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1), - RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2), - RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3), - RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4), - RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5), - RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6), - RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7), - MEASUREMENT_START_EVENT_ID = BIT(8), - MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), - SCAN_COMPLETE_EVENT_ID = BIT(10), - SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(11), - AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12), - PS_REPORT_EVENT_ID = BIT(13), - PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14), - DISCONNECT_EVENT_COMPLETE_ID = BIT(15), - JOIN_EVENT_COMPLETE_ID = BIT(16), - CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), - BSS_LOSE_EVENT_ID = BIT(18), - REGAINED_BSS_EVENT_ID = BIT(19), - ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), - SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), - SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), - SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), - PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), - DBG_EVENT_ID = BIT(26), - HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), - PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), - PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), - BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30), - EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, -}; - -enum { - EVENT_ENTER_POWER_SAVE_FAIL = 0, - EVENT_ENTER_POWER_SAVE_SUCCESS, - EVENT_EXIT_POWER_SAVE_FAIL, - EVENT_EXIT_POWER_SAVE_SUCCESS, -}; - -struct event_debug_report { - u8 debug_event_id; - u8 num_params; - __le16 pad; - __le32 report_1; - __le32 report_2; - __le32 report_3; -} __packed; - -#define NUM_OF_RSSI_SNR_TRIGGERS 8 - -struct event_mailbox { - __le32 events_vector; - __le32 events_mask; - __le32 reserved_1; - __le32 reserved_2; - - u8 dbg_event_id; - u8 num_relevant_params; - __le16 reserved_3; - __le32 event_report_p1; - __le32 event_report_p2; - __le32 event_report_p3; - - u8 number_of_scan_results; - u8 scan_tag; - u8 reserved_4[2]; - __le32 compl_scheduled_scan_status; - - __le16 scheduled_scan_attended_channels; - u8 soft_gemini_sense_info; - u8 soft_gemini_protective_info; - s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS]; - u8 channel_switch_status; - u8 scheduled_scan_status; - u8 ps_status; - - u8 reserved_5[29]; -} __packed; - -int wl1271_event_unmask(struct wl1271 *wl); -void wl1271_event_mbox_config(struct wl1271 *wl); -int wl1271_event_handle(struct wl1271 *wl, u8 mbox); -void wl1271_pspoll_work(struct work_struct *work); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_ini.h b/drivers/net/wireless/wl12xx/wl1271_ini.h deleted file mode 100644 index 2313047d4015..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_ini.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_INI_H__ -#define __WL1271_INI_H__ - -#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16 - -struct wl1271_ini_general_params { - u8 ref_clock; - u8 settling_time; - u8 clk_valid_on_wakeup; - u8 dc2dc_mode; - u8 dual_mode_select; - u8 tx_bip_fem_auto_detect; - u8 tx_bip_fem_manufacturer; - u8 general_settings; - u8 sr_state; - u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; - u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; - u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; -} __packed; - -#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 - -struct wl1271_ini_band_params_2 { - u8 rx_trace_insertion_loss; - u8 tx_trace_loss; - u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; -} __packed; - -#define WL1271_INI_RATE_GROUP_COUNT 6 -#define WL1271_INI_CHANNEL_COUNT_2 14 - -struct wl1271_ini_fem_params_2 { - __le16 tx_bip_ref_pd_voltage; - u8 tx_bip_ref_power; - u8 tx_bip_ref_offset; - u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; - u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; - u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; - u8 rx_fem_insertion_loss; - u8 degraded_low_to_normal_thr; - u8 normal_to_degraded_high_thr; -} __packed; - -#define WL1271_INI_CHANNEL_COUNT_5 35 -#define WL1271_INI_SUB_BAND_COUNT_5 7 - -struct wl1271_ini_band_params_5 { - u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; - u8 tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5]; - u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; -} __packed; - -struct wl1271_ini_fem_params_5 { - __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; - u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; - u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; - u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; - u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; - u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; - u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; - u8 degraded_low_to_normal_thr; - u8 normal_to_degraded_high_thr; -} __packed; - - -/* NVS data structure */ -#define WL1271_INI_NVS_SECTION_SIZE 468 -#define WL1271_INI_FEM_MODULE_COUNT 2 - -#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 - -struct wl1271_nvs_file { - /* NVS section */ - u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; - - /* INI section */ - struct wl1271_ini_general_params general_params; - u8 padding1; - struct wl1271_ini_band_params_2 stat_radio_params_2; - u8 padding2; - struct { - struct wl1271_ini_fem_params_2 params; - u8 padding; - } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; - struct wl1271_ini_band_params_5 stat_radio_params_5; - u8 padding3; - struct { - struct wl1271_ini_fem_params_5 params; - u8 padding; - } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; -} __packed; - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c deleted file mode 100644 index 8044bba70ee7..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include - -#include "wl1271_init.h" -#include "wl12xx_80211.h" -#include "wl1271_acx.h" -#include "wl1271_cmd.h" -#include "wl1271_reg.h" - -static int wl1271_init_hwenc_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_feature_cfg(wl); - if (ret < 0) { - wl1271_warning("couldn't set feature config"); - return ret; - } - - ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key); - if (ret < 0) { - wl1271_warning("couldn't set default key"); - return ret; - } - - return 0; -} - -int wl1271_init_templates_config(struct wl1271 *wl) -{ - int ret, i; - size_t size; - - /* send empty templates for fw memory reservation */ - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, - sizeof(struct wl12xx_probe_req_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - size = sizeof(struct wl12xx_probe_req_template); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - NULL, size, 0, - WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, - sizeof(struct wl12xx_null_data_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, - sizeof(struct wl12xx_ps_poll_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, - sizeof - (struct wl12xx_qos_null_data_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, - sizeof - (struct wl12xx_probe_resp_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, - sizeof - (struct wl12xx_beacon_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, - WL1271_CMD_TEMPL_MAX_SIZE, i, - WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - } - - return 0; -} - -static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) -{ - int ret; - - ret = wl1271_acx_rx_msdu_life_time(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_rx_config(wl, config, filter); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_phy_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_pd_threshold(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME); - if (ret < 0) - return ret; - - ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); - if (ret < 0) - return ret; - - ret = wl1271_acx_service_period_timeout(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold); - if (ret < 0) - return ret; - - return 0; -} - -static int wl1271_init_beacon_filter(struct wl1271 *wl) -{ - int ret; - - /* disable beacon filtering at this stage */ - ret = wl1271_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1271_acx_beacon_filter_table(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_pta(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_sg_cfg(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_energy_detection(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_cca_threshold(wl); - if (ret < 0) - return ret; - - return 0; -} - -static int wl1271_init_beacon_broadcast(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_bcn_dtim_options(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_hw_init(struct wl1271 *wl) -{ - struct conf_tx_ac_category *conf_ac; - struct conf_tx_tid *conf_tid; - int ret, i; - - ret = wl1271_cmd_general_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_radio_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_ext_radio_parms(wl); - if (ret < 0) - return ret; - - /* Template settings */ - ret = wl1271_init_templates_config(wl); - if (ret < 0) - return ret; - - /* Default memory configuration */ - ret = wl1271_acx_init_mem_config(wl); - if (ret < 0) - return ret; - - /* RX config */ - ret = wl1271_init_rx_config(wl, - RX_CFG_PROMISCUOUS | RX_CFG_TSF, - RX_FILTER_OPTION_DEF); - /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS, - RX_FILTER_OPTION_FILTER_ALL); */ - if (ret < 0) - goto out_free_memmap; - - /* PHY layer config */ - ret = wl1271_init_phy_config(wl); - if (ret < 0) - goto out_free_memmap; - - ret = wl1271_acx_dco_itrim_params(wl); - if (ret < 0) - goto out_free_memmap; - - /* Initialize connection monitoring thresholds */ - ret = wl1271_acx_conn_monit_params(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Beacon filtering */ - ret = wl1271_init_beacon_filter(wl); - if (ret < 0) - goto out_free_memmap; - - /* Configure TX patch complete interrupt behavior */ - ret = wl1271_acx_tx_config_options(wl); - if (ret < 0) - goto out_free_memmap; - - /* RX complete interrupt pacing */ - ret = wl1271_acx_init_rx_interrupt(wl); - if (ret < 0) - goto out_free_memmap; - - /* Bluetooth WLAN coexistence */ - ret = wl1271_init_pta(wl); - if (ret < 0) - goto out_free_memmap; - - /* Energy detection */ - ret = wl1271_init_energy_detection(wl); - if (ret < 0) - goto out_free_memmap; - - /* Beacons and boradcast settings */ - ret = wl1271_init_beacon_broadcast(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default TID/AC configuration */ - BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); - for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - - conf_tid = &wl->conf.tx.tid_conf[i]; - ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, - conf_tid->channel_type, - conf_tid->tsid, - conf_tid->ps_scheme, - conf_tid->ack_policy, - conf_tid->apsd_conf[0], - conf_tid->apsd_conf[1]); - if (ret < 0) - goto out_free_memmap; - } - - /* Configure TX rate classes */ - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out_free_memmap; - - /* Enable data path */ - ret = wl1271_cmd_data_path(wl, 1); - if (ret < 0) - goto out_free_memmap; - - /* Configure for ELP power saving */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - if (ret < 0) - goto out_free_memmap; - - /* Configure HW encryption */ - ret = wl1271_init_hwenc_config(wl); - if (ret < 0) - goto out_free_memmap; - - /* configure PM */ - ret = wl1271_acx_pm_config(wl); - if (ret < 0) - goto out_free_memmap; - - /* disable all keep-alive templates */ - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_acx_keep_alive_config(wl, i, - ACX_KEEP_ALIVE_TPL_INVALID); - if (ret < 0) - goto out_free_memmap; - } - - /* disable the keep-alive feature */ - ret = wl1271_acx_keep_alive_mode(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Configure rssi/snr averaging weights */ - ret = wl1271_acx_rssi_snr_avg_weights(wl); - if (ret < 0) - goto out_free_memmap; - - return 0; - - out_free_memmap: - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/wl1271_init.h deleted file mode 100644 index bc26f8c53b91..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_init.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_INIT_H__ -#define __WL1271_INIT_H__ - -#include "wl1271.h" - -int wl1271_hw_init_power_auth(struct wl1271 *wl); -int wl1271_init_templates_config(struct wl1271 *wl); -int wl1271_init_phy_config(struct wl1271 *wl); -int wl1271_init_pta(struct wl1271 *wl); -int wl1271_init_energy_detection(struct wl1271 *wl); -int wl1271_hw_init(struct wl1271 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c deleted file mode 100644 index c8759acef131..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_io.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_io.h" - -#define OCP_CMD_LOOP 32 - -#define OCP_CMD_WRITE 0x1 -#define OCP_CMD_READ 0x2 - -#define OCP_READY_MASK BIT(18) -#define OCP_STATUS_MASK (BIT(16) | BIT(17)) - -#define OCP_STATUS_NO_RESP 0x00000 -#define OCP_STATUS_OK 0x10000 -#define OCP_STATUS_REQ_FAILED 0x20000 -#define OCP_STATUS_RESP_ERROR 0x30000 - -void wl1271_disable_interrupts(struct wl1271 *wl) -{ - wl->if_ops->disable_irq(wl); -} - -void wl1271_enable_interrupts(struct wl1271 *wl) -{ - wl->if_ops->enable_irq(wl); -} - -/* Set the SPI partitions to access the chip addresses - * - * To simplify driver code, a fixed (virtual) memory map is defined for - * register and memory addresses. Because in the chipset, in different stages - * of operation, those addresses will move around, an address translation - * mechanism is required. - * - * There are four partitions (three memory and one register partition), - * which are mapped to two different areas of the hardware memory. - * - * Virtual address - * space - * - * | | - * ...+----+--> mem.start - * Physical address ... | | - * space ... | | [PART_0] - * ... | | - * 00000000 <--+----+... ...+----+--> mem.start + mem.size - * | | ... | | - * |MEM | ... | | - * | | ... | | - * mem.size <--+----+... | | {unused area) - * | | ... | | - * |REG | ... | | - * mem.size | | ... | | - * + <--+----+... ...+----+--> reg.start - * reg.size | | ... | | - * |MEM2| ... | | [PART_1] - * | | ... | | - * ...+----+--> reg.start + reg.size - * | | - * - */ -int wl1271_set_partition(struct wl1271 *wl, - struct wl1271_partition_set *p) -{ - /* copy partition info */ - memcpy(&wl->part, p, sizeof(*p)); - - wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - p->mem.start, p->mem.size); - wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - p->reg.start, p->reg.size); - wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", - p->mem2.start, p->mem2.size); - wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", - p->mem3.start, p->mem3.size); - - /* write partition info to the chipset */ - wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); - wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); - wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); - wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); - wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); - wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); - wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); - - return 0; -} - -void wl1271_io_reset(struct wl1271 *wl) -{ - wl->if_ops->reset(wl); -} - -void wl1271_io_init(struct wl1271 *wl) -{ - wl->if_ops->init(wl); -} - -void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) -{ - /* write address >> 1 + 0x30000 to OCP_POR_CTR */ - addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, OCP_POR_CTR, addr); - - /* write value to OCP_POR_WDATA */ - wl1271_write32(wl, OCP_DATA_WRITE, val); - - /* write 1 to OCP_CMD */ - wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE); -} - -u16 wl1271_top_reg_read(struct wl1271 *wl, int addr) -{ - u32 val; - int timeout = OCP_CMD_LOOP; - - /* write address >> 1 + 0x30000 to OCP_POR_CTR */ - addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, OCP_POR_CTR, addr); - - /* write 2 to OCP_CMD */ - wl1271_write32(wl, OCP_CMD, OCP_CMD_READ); - - /* poll for data ready */ - do { - val = wl1271_read32(wl, OCP_DATA_READ); - } while (!(val & OCP_READY_MASK) && --timeout); - - if (!timeout) { - wl1271_warning("Top register access timed out."); - return 0xffff; - } - - /* check data status and return if OK */ - if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) - return val & 0xffff; - else { - wl1271_warning("Top register access returned error."); - return 0xffff; - } -} - diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h deleted file mode 100644 index c1f92e65ded0..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_IO_H__ -#define __WL1271_IO_H__ - -#include "wl1271_reg.h" - -#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 - -#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0 -#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) -#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) -#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) -#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) -#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) -#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) -#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) - -#define HW_ACCESS_REGISTER_SIZE 4 - -#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 - -struct wl1271; - -void wl1271_disable_interrupts(struct wl1271 *wl); -void wl1271_enable_interrupts(struct wl1271 *wl); - -void wl1271_io_reset(struct wl1271 *wl); -void wl1271_io_init(struct wl1271 *wl); - -static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl) -{ - return wl->if_ops->dev(wl); -} - - -/* Raw target IO, address is not translated */ -static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - wl->if_ops->write(wl, addr, buf, len, fixed); -} - -static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - wl->if_ops->read(wl, addr, buf, len, fixed); -} - -static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) -{ - wl1271_raw_read(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); - - return le32_to_cpu(wl->buffer_32); -} - -static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) -{ - wl->buffer_32 = cpu_to_le32(val); - wl1271_raw_write(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); -} - -/* Translated target IO */ -static inline int wl1271_translate_addr(struct wl1271 *wl, int addr) -{ - /* - * To translate, first check to which window of addresses the - * particular address belongs. Then subtract the starting address - * of that window from the address. Then, add offset of the - * translated region. - * - * The translated regions occur next to each other in physical device - * memory, so just add the sizes of the preceeding address regions to - * get the offset to the new region. - * - * Currently, only the two first regions are addressed, and the - * assumption is that all addresses will fall into either of those - * two. - */ - if ((addr >= wl->part.reg.start) && - (addr < wl->part.reg.start + wl->part.reg.size)) - return addr - wl->part.reg.start + wl->part.mem.size; - else - return addr - wl->part.mem.start; -} - -static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int physical; - - physical = wl1271_translate_addr(wl, addr); - - wl1271_raw_read(wl, physical, buf, len, fixed); -} - -static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int physical; - - physical = wl1271_translate_addr(wl, addr); - - wl1271_raw_write(wl, physical, buf, len, fixed); -} - -static inline u32 wl1271_read32(struct wl1271 *wl, int addr) -{ - return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); -} - -static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) -{ - wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); -} - -static inline void wl1271_power_off(struct wl1271 *wl) -{ - wl->if_ops->power(wl, false); - clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); -} - -static inline int wl1271_power_on(struct wl1271 *wl) -{ - int ret = wl->if_ops->power(wl, true); - if (ret == 0) - set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); - - return ret; -} - - -/* Top Register IO */ -void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); -u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); - -int wl1271_set_partition(struct wl1271 *wl, - struct wl1271_partition_set *p); - -/* Functions from wl1271_main.c */ - -int wl1271_register_hw(struct wl1271 *wl); -void wl1271_unregister_hw(struct wl1271 *wl); -int wl1271_init_ieee80211(struct wl1271 *wl); -struct ieee80211_hw *wl1271_alloc_hw(void); -int wl1271_free_hw(struct wl1271 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c deleted file mode 100644 index f5b1d19bc88d..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ /dev/null @@ -1,2749 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_event.h" -#include "wl1271_tx.h" -#include "wl1271_rx.h" -#include "wl1271_ps.h" -#include "wl1271_init.h" -#include "wl1271_debugfs.h" -#include "wl1271_cmd.h" -#include "wl1271_boot.h" -#include "wl1271_testmode.h" -#include "wl1271_scan.h" - -#define WL1271_BOOT_RETRIES 3 - -static struct conf_drv_settings default_conf = { - .sg = { - .params = { - [CONF_SG_BT_PER_THRESHOLD] = 7500, - [CONF_SG_HV3_MAX_OVERRIDE] = 0, - [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, - [CONF_SG_BT_LOAD_RATIO] = 50, - [CONF_SG_AUTO_PS_MODE] = 1, - [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, - [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, - [CONF_SG_ANTENNA_CONFIGURATION] = 0, - [CONF_SG_BEACON_MISS_PERCENT] = 60, - [CONF_SG_RATE_ADAPT_THRESH] = 12, - [CONF_SG_RATE_ADAPT_SNR] = 0, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30, - [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8, - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20, - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50, - /* Note: with UPSD, this should be 4 */ - [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25, - [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20, - /* Note: with UPDS, this should be 15 */ - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8, - /* Note: with UPDS, this should be 50 */ - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40, - /* Note: with UPDS, this should be 10 */ - [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20, - [CONF_SG_RXT] = 1200, - [CONF_SG_TXT] = 1000, - [CONF_SG_ADAPTIVE_RXT_TXT] = 1, - [CONF_SG_PS_POLL_TIMEOUT] = 10, - [CONF_SG_UPSD_TIMEOUT] = 10, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8, - [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10, - [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, - [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800, - [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75, - [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15, - [CONF_SG_HV3_MAX_SERVED] = 6, - [CONF_SG_DHCP_TIME] = 5000, - [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, - }, - .state = CONF_SG_PROTECTIVE, - }, - .rx = { - .rx_msdu_life_time = 512000, - .packet_detection_threshold = 0, - .ps_poll_timeout = 15, - .upsd_timeout = 15, - .rts_threshold = 2347, - .rx_cca_threshold = 0, - .irq_blk_threshold = 0xFFFF, - .irq_pkt_threshold = 0, - .irq_timeout = 600, - .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, - }, - .tx = { - .tx_energy_detection = 0, - .rc_conf = { - .enabled_rates = 0, - .short_retry_limit = 10, - .long_retry_limit = 10, - .aflags = 0 - }, - .ac_conf_count = 4, - .ac_conf = { - [CONF_TX_AC_BE] = { - .ac = CONF_TX_AC_BE, - .cw_min = 15, - .cw_max = 63, - .aifsn = 3, - .tx_op_limit = 0, - }, - [CONF_TX_AC_BK] = { - .ac = CONF_TX_AC_BK, - .cw_min = 15, - .cw_max = 63, - .aifsn = 7, - .tx_op_limit = 0, - }, - [CONF_TX_AC_VI] = { - .ac = CONF_TX_AC_VI, - .cw_min = 15, - .cw_max = 63, - .aifsn = CONF_TX_AIFS_PIFS, - .tx_op_limit = 3008, - }, - [CONF_TX_AC_VO] = { - .ac = CONF_TX_AC_VO, - .cw_min = 15, - .cw_max = 63, - .aifsn = CONF_TX_AIFS_PIFS, - .tx_op_limit = 1504, - }, - }, - .tid_conf_count = 4, - .tid_conf = { - [CONF_TX_AC_BE] = { - .queue_id = CONF_TX_AC_BE, - .channel_type = CONF_CHANNEL_TYPE_EDCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [CONF_TX_AC_BK] = { - .queue_id = CONF_TX_AC_BK, - .channel_type = CONF_CHANNEL_TYPE_EDCF, - .tsid = CONF_TX_AC_BK, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [CONF_TX_AC_VI] = { - .queue_id = CONF_TX_AC_VI, - .channel_type = CONF_CHANNEL_TYPE_EDCF, - .tsid = CONF_TX_AC_VI, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [CONF_TX_AC_VO] = { - .queue_id = CONF_TX_AC_VO, - .channel_type = CONF_CHANNEL_TYPE_EDCF, - .tsid = CONF_TX_AC_VO, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - }, - .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, - .tx_compl_timeout = 700, - .tx_compl_threshold = 4, - .basic_rate = CONF_HW_BIT_RATE_1MBPS, - .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, - }, - .conn = { - .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, - .listen_interval = 1, - .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, - .bcn_filt_ie_count = 1, - .bcn_filt_ie = { - [0] = { - .ie = WLAN_EID_CHANNEL_SWITCH, - .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, - } - }, - .synch_fail_thold = 10, - .bss_lose_timeout = 100, - .beacon_rx_timeout = 10000, - .broadcast_timeout = 20000, - .rx_broadcast_in_ps = 1, - .ps_poll_threshold = 10, - .ps_poll_recovery_period = 700, - .bet_enable = CONF_BET_MODE_ENABLE, - .bet_max_consecutive = 10, - .psm_entry_retries = 5, - .psm_entry_nullfunc_retries = 3, - .psm_entry_hangover_period = 1, - .keep_alive_interval = 55000, - .max_listen_interval = 20, - }, - .itrim = { - .enable = false, - .timeout = 50000, - }, - .pm_config = { - .host_clk_settling_time = 5000, - .host_fast_wakeup_support = false - }, - .roam_trigger = { - .trigger_pacing = 1, - .avg_weight_rssi_beacon = 20, - .avg_weight_rssi_data = 10, - .avg_weight_snr_beacon = 20, - .avg_weight_snr_data = 10 - }, - .scan = { - .min_dwell_time_active = 7500, - .max_dwell_time_active = 30000, - .min_dwell_time_passive = 30000, - .max_dwell_time_passive = 60000, - .num_probe_reqs = 2, - }, - .rf = { - .tx_per_channel_power_compensation_2 = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }, - .tx_per_channel_power_compensation_5 = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }, - }, -}; - -static void __wl1271_op_remove_interface(struct wl1271 *wl); - - -static void wl1271_device_release(struct device *dev) -{ - -} - -static struct platform_device wl1271_device = { - .name = "wl1271", - .id = -1, - - /* device model insists to have a release function */ - .dev = { - .release = wl1271_device_release, - }, -}; - -static LIST_HEAD(wl_list); - -static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, - void *arg) -{ - struct net_device *dev = arg; - struct wireless_dev *wdev; - struct wiphy *wiphy; - struct ieee80211_hw *hw; - struct wl1271 *wl; - struct wl1271 *wl_temp; - int ret = 0; - - /* Check that this notification is for us. */ - if (what != NETDEV_CHANGE) - return NOTIFY_DONE; - - wdev = dev->ieee80211_ptr; - if (wdev == NULL) - return NOTIFY_DONE; - - wiphy = wdev->wiphy; - if (wiphy == NULL) - return NOTIFY_DONE; - - hw = wiphy_priv(wiphy); - if (hw == NULL) - return NOTIFY_DONE; - - wl_temp = hw->priv; - list_for_each_entry(wl, &wl_list, list) { - if (wl == wl_temp) - break; - } - if (wl != wl_temp) - return NOTIFY_DONE; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) - goto out; - - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - if ((dev->operstate == IF_OPER_UP) && - !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) { - wl1271_cmd_set_sta_state(wl); - wl1271_info("Association completed."); - } - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return NOTIFY_OK; -} - -static void wl1271_conf_init(struct wl1271 *wl) -{ - - /* - * This function applies the default configuration to the driver. This - * function is invoked upon driver load (spi probe.) - * - * The configuration is stored in a run-time structure in order to - * facilitate for run-time adjustment of any of the parameters. Making - * changes to the configuration structure will apply the new values on - * the next interface up (wl1271_op_start.) - */ - - /* apply driver default configuration */ - memcpy(&wl->conf, &default_conf, sizeof(default_conf)); -} - - -static int wl1271_plt_init(struct wl1271 *wl) -{ - struct conf_tx_ac_category *conf_ac; - struct conf_tx_tid *conf_tid; - int ret, i; - - ret = wl1271_cmd_general_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_radio_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_ext_radio_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_init_templates_config(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_init_mem_config(wl); - if (ret < 0) - return ret; - - /* PHY layer config */ - ret = wl1271_init_phy_config(wl); - if (ret < 0) - goto out_free_memmap; - - ret = wl1271_acx_dco_itrim_params(wl); - if (ret < 0) - goto out_free_memmap; - - /* Initialize connection monitoring thresholds */ - ret = wl1271_acx_conn_monit_params(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Bluetooth WLAN coexistence */ - ret = wl1271_init_pta(wl); - if (ret < 0) - goto out_free_memmap; - - /* Energy detection */ - ret = wl1271_init_energy_detection(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default TID/AC configuration */ - BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); - for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - - conf_tid = &wl->conf.tx.tid_conf[i]; - ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, - conf_tid->channel_type, - conf_tid->tsid, - conf_tid->ps_scheme, - conf_tid->ack_policy, - conf_tid->apsd_conf[0], - conf_tid->apsd_conf[1]); - if (ret < 0) - goto out_free_memmap; - } - - /* Enable data path */ - ret = wl1271_cmd_data_path(wl, 1); - if (ret < 0) - goto out_free_memmap; - - /* Configure for CAM power saving (ie. always active) */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - goto out_free_memmap; - - /* configure PM */ - ret = wl1271_acx_pm_config(wl); - if (ret < 0) - goto out_free_memmap; - - return 0; - - out_free_memmap: - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - return ret; -} - -static void wl1271_fw_status(struct wl1271 *wl, - struct wl1271_fw_status *status) -{ - struct timespec ts; - u32 total = 0; - int i; - - wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); - - wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " - "drv_rx_counter = %d, tx_results_counter = %d)", - status->intr, - status->fw_rx_counter, - status->drv_rx_counter, - status->tx_results_counter); - - /* update number of available TX blocks */ - for (i = 0; i < NUM_TX_QUEUES; i++) { - u32 cnt = le32_to_cpu(status->tx_released_blks[i]) - - wl->tx_blocks_freed[i]; - - wl->tx_blocks_freed[i] = - le32_to_cpu(status->tx_released_blks[i]); - wl->tx_blocks_available += cnt; - total += cnt; - } - - /* if more blocks are available now, tx work can be scheduled */ - if (total) - clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); - - /* update the host-chipset time offset */ - getnstimeofday(&ts); - wl->time_offset = (timespec_to_ns(&ts) >> 10) - - (s64)le32_to_cpu(status->fw_localtime); -} - -#define WL1271_IRQ_MAX_LOOPS 10 - -static void wl1271_irq_work(struct work_struct *work) -{ - int ret; - u32 intr; - int loopcount = WL1271_IRQ_MAX_LOOPS; - unsigned long flags; - struct wl1271 *wl = - container_of(work, struct wl1271, irq_work); - - mutex_lock(&wl->mutex); - - wl1271_debug(DEBUG_IRQ, "IRQ work"); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, true); - if (ret < 0) - goto out; - - spin_lock_irqsave(&wl->wl_lock, flags); - while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { - clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - loopcount--; - - wl1271_fw_status(wl, wl->fw_status); - intr = le32_to_cpu(wl->fw_status->intr); - if (!intr) { - wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); - spin_lock_irqsave(&wl->wl_lock, flags); - continue; - } - - intr &= WL1271_INTR_MASK; - - if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { - wl1271_error("watchdog interrupt received! " - "starting recovery."); - ieee80211_queue_work(wl->hw, &wl->recovery_work); - - /* restarting the chip. ignore any other interrupt. */ - goto out; - } - - if (intr & WL1271_ACX_INTR_DATA) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - - /* check for tx results */ - if (wl->fw_status->tx_results_counter != - (wl->tx_results_count & 0xff)) - wl1271_tx_complete(wl); - - /* Check if any tx blocks were freed */ - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - !skb_queue_empty(&wl->tx_queue)) { - /* - * In order to avoid starvation of the TX path, - * call the work function directly. - */ - wl1271_tx_work_locked(wl); - } - - wl1271_rx(wl, wl->fw_status); - } - - if (intr & WL1271_ACX_INTR_EVENT_A) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); - wl1271_event_handle(wl, 0); - } - - if (intr & WL1271_ACX_INTR_EVENT_B) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); - wl1271_event_handle(wl, 1); - } - - if (intr & WL1271_ACX_INTR_INIT_COMPLETE) - wl1271_debug(DEBUG_IRQ, - "WL1271_ACX_INTR_INIT_COMPLETE"); - - if (intr & WL1271_ACX_INTR_HW_AVAILABLE) - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); - - spin_lock_irqsave(&wl->wl_lock, flags); - } - - if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - else - clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_fetch_firmware(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get firmware: %d", ret); - return ret; - } - - if (fw->size % 4) { - wl1271_error("firmware size is not multiple of 32 bits: %zu", - fw->size); - ret = -EILSEQ; - goto out; - } - - wl->fw_len = fw->size; - wl->fw = vmalloc(wl->fw_len); - - if (!wl->fw) { - wl1271_error("could not allocate memory for the firmware"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->fw, fw->data, wl->fw_len); - - ret = 0; - -out: - release_firmware(fw); - - return ret; -} - -static int wl1271_fetch_nvs(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get nvs file: %d", ret); - return ret; - } - - wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); - - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - wl->nvs_len = fw->size; - -out: - release_firmware(fw); - - return ret; -} - -static void wl1271_recovery_work(struct work_struct *work) -{ - struct wl1271 *wl = - container_of(work, struct wl1271, recovery_work); - - mutex_lock(&wl->mutex); - - if (wl->state != WL1271_STATE_ON) - goto out; - - wl1271_info("Hardware recovery in progress."); - - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - ieee80211_connection_loss(wl->vif); - - /* reboot the chipset */ - __wl1271_op_remove_interface(wl); - ieee80211_restart_hw(wl->hw); - -out: - mutex_unlock(&wl->mutex); -} - -static void wl1271_fw_wakeup(struct wl1271 *wl) -{ - u32 elp_reg; - - elp_reg = ELPCTRL_WAKE_UP; - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); -} - -static int wl1271_setup(struct wl1271 *wl) -{ - wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL); - if (!wl->fw_status) - return -ENOMEM; - - wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); - if (!wl->tx_res_if) { - kfree(wl->fw_status); - return -ENOMEM; - } - - return 0; -} - -static int wl1271_chip_wakeup(struct wl1271 *wl) -{ - struct wl1271_partition_set partition; - int ret = 0; - - msleep(WL1271_PRE_POWER_ON_SLEEP); - ret = wl1271_power_on(wl); - if (ret < 0) - goto out; - msleep(WL1271_POWER_ON_SLEEP); - wl1271_io_reset(wl); - wl1271_io_init(wl); - - /* We don't need a real memory partition here, because we only want - * to use the registers at this point. */ - memset(&partition, 0, sizeof(partition)); - partition.reg.start = REGISTERS_BASE; - partition.reg.size = REGISTERS_DOWN_SIZE; - wl1271_set_partition(wl, &partition); - - /* ELP module wake up */ - wl1271_fw_wakeup(wl); - - /* whal_FwCtrl_BootSm() */ - - /* 0. read chip id from CHIP_ID */ - wl->chip.id = wl1271_read32(wl, CHIP_ID_B); - - /* 1. check if chip id is valid */ - - switch (wl->chip.id) { - case CHIP_ID_1271_PG10: - wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", - wl->chip.id); - - ret = wl1271_setup(wl); - if (ret < 0) - goto out; - break; - case CHIP_ID_1271_PG20: - wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", - wl->chip.id); - - ret = wl1271_setup(wl); - if (ret < 0) - goto out; - break; - default: - wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); - ret = -ENODEV; - goto out; - } - - if (wl->fw == NULL) { - ret = wl1271_fetch_firmware(wl); - if (ret < 0) - goto out; - } - - /* No NVS from netlink, try to get it from the filesystem */ - if (wl->nvs == NULL) { - ret = wl1271_fetch_nvs(wl); - if (ret < 0) - goto out; - } - -out: - return ret; -} - -int wl1271_plt_start(struct wl1271 *wl) -{ - int retries = WL1271_BOOT_RETRIES; - int ret; - - mutex_lock(&wl->mutex); - - wl1271_notice("power up"); - - if (wl->state != WL1271_STATE_OFF) { - wl1271_error("cannot go into PLT state because not " - "in off state: %d", wl->state); - ret = -EBUSY; - goto out; - } - - while (retries) { - retries--; - ret = wl1271_chip_wakeup(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_boot(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_plt_init(wl); - if (ret < 0) - goto irq_disable; - - wl->state = WL1271_STATE_PLT; - wl1271_notice("firmware booted in PLT mode (%s)", - wl->chip.fw_ver); - goto out; - -irq_disable: - wl1271_disable_interrupts(wl); - mutex_unlock(&wl->mutex); - /* Unlocking the mutex in the middle of handling is - inherently unsafe. In this case we deem it safe to do, - because we need to let any possibly pending IRQ out of - the system (and while we are WL1271_STATE_OFF the IRQ - work function will not do anything.) Also, any other - possible concurrent operations will fail due to the - current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); - mutex_lock(&wl->mutex); -power_off: - wl1271_power_off(wl); - } - - wl1271_error("firmware boot in PLT mode failed despite %d retries", - WL1271_BOOT_RETRIES); -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -int wl1271_plt_stop(struct wl1271 *wl) -{ - int ret = 0; - - mutex_lock(&wl->mutex); - - wl1271_notice("power down"); - - if (wl->state != WL1271_STATE_PLT) { - wl1271_error("cannot power down because not in PLT " - "state: %d", wl->state); - ret = -EBUSY; - goto out; - } - - wl1271_disable_interrupts(wl); - wl1271_power_off(wl); - - wl->state = WL1271_STATE_OFF; - wl->rx_counter = 0; - -out: - mutex_unlock(&wl->mutex); - - cancel_work_sync(&wl->irq_work); - cancel_work_sync(&wl->recovery_work); - - return ret; -} - -static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *sta = txinfo->control.sta; - unsigned long flags; - - /* - * peek into the rates configured in the STA entry. - * The rates set after connection stage, The first block only BG sets: - * the compare is for bit 0-16 of sta_rate_set. The second block add - * HT rates in case of HT supported. - */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (sta && - (sta->supp_rates[conf->channel->band] != - (wl->sta_rate_set & HW_BG_RATES_MASK))) { - wl->sta_rate_set = sta->supp_rates[conf->channel->band]; - set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); - } - -#ifdef CONFIG_WL1271_HT - if (sta && - sta->ht_cap.ht_supported && - ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != - sta->ht_cap.mcs.rx_mask[0])) { - /* Clean MCS bits before setting them */ - wl->sta_rate_set &= HW_BG_RATES_MASK; - wl->sta_rate_set |= - (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); - set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); - } -#endif - spin_unlock_irqrestore(&wl->wl_lock, flags); - - /* queue the packet */ - skb_queue_tail(&wl->tx_queue, skb); - - /* - * The chip specific setup must run before the first TX packet - - * before that, the tx_work will not be initialized! - */ - - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->tx_work); - - /* - * The workqueue is slow to process the tx_queue and we need stop - * the queue here, otherwise the queue will get too long. - */ - if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { - wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); - - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_stop_queues(wl->hw); - set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - - return NETDEV_TX_OK; -} - -static struct notifier_block wl1271_dev_notifier = { - .notifier_call = wl1271_dev_notify, -}; - -static int wl1271_op_start(struct ieee80211_hw *hw) -{ - wl1271_debug(DEBUG_MAC80211, "mac80211 start"); - - /* - * We have to delay the booting of the hardware because - * we need to know the local MAC address before downloading and - * initializing the firmware. The MAC address cannot be changed - * after boot, and without the proper MAC address, the firmware - * will not function properly. - * - * The MAC address is first known when the corresponding interface - * is added. That is where we will initialize the hardware. - */ - - return 0; -} - -static void wl1271_op_stop(struct ieee80211_hw *hw) -{ - wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); -} - -static int wl1271_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1271 *wl = hw->priv; - struct wiphy *wiphy = hw->wiphy; - int retries = WL1271_BOOT_RETRIES; - int ret = 0; - bool booted = false; - - wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", - vif->type, vif->addr); - - mutex_lock(&wl->mutex); - if (wl->vif) { - wl1271_debug(DEBUG_MAC80211, - "multiple vifs are not supported yet"); - ret = -EBUSY; - goto out; - } - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - wl->bss_type = BSS_TYPE_STA_BSS; - wl->set_bss_type = BSS_TYPE_STA_BSS; - break; - case NL80211_IFTYPE_ADHOC: - wl->bss_type = BSS_TYPE_IBSS; - wl->set_bss_type = BSS_TYPE_STA_BSS; - break; - default: - ret = -EOPNOTSUPP; - goto out; - } - - memcpy(wl->mac_addr, vif->addr, ETH_ALEN); - - if (wl->state != WL1271_STATE_OFF) { - wl1271_error("cannot start because not in off state: %d", - wl->state); - ret = -EBUSY; - goto out; - } - - while (retries) { - retries--; - ret = wl1271_chip_wakeup(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_boot(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_hw_init(wl); - if (ret < 0) - goto irq_disable; - - booted = true; - break; - -irq_disable: - wl1271_disable_interrupts(wl); - mutex_unlock(&wl->mutex); - /* Unlocking the mutex in the middle of handling is - inherently unsafe. In this case we deem it safe to do, - because we need to let any possibly pending IRQ out of - the system (and while we are WL1271_STATE_OFF the IRQ - work function will not do anything.) Also, any other - possible concurrent operations will fail due to the - current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); - mutex_lock(&wl->mutex); -power_off: - wl1271_power_off(wl); - } - - if (!booted) { - wl1271_error("firmware boot failed despite %d retries", - WL1271_BOOT_RETRIES); - goto out; - } - - wl->vif = vif; - wl->state = WL1271_STATE_ON; - wl1271_info("firmware booted (%s)", wl->chip.fw_ver); - - /* update hw/fw version info in wiphy struct */ - wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver, - sizeof(wiphy->fw_version)); - -out: - mutex_unlock(&wl->mutex); - - if (!ret) - list_add(&wl->list, &wl_list); - - return ret; -} - -static void __wl1271_op_remove_interface(struct wl1271 *wl) -{ - int i; - - wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); - - wl1271_info("down"); - - list_del(&wl->list); - - WARN_ON(wl->state != WL1271_STATE_ON); - - /* enable dyn ps just in case (if left on due to fw crash etc) */ - if (wl->bss_type == BSS_TYPE_STA_BSS) - ieee80211_enable_dyn_ps(wl->vif); - - if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { - wl->scan.state = WL1271_SCAN_STATE_IDLE; - kfree(wl->scan.scanned_ch); - wl->scan.scanned_ch = NULL; - wl->scan.req = NULL; - ieee80211_scan_completed(wl->hw, true); - } - - wl->state = WL1271_STATE_OFF; - - wl1271_disable_interrupts(wl); - - mutex_unlock(&wl->mutex); - - cancel_delayed_work_sync(&wl->scan_complete_work); - cancel_work_sync(&wl->irq_work); - cancel_work_sync(&wl->tx_work); - cancel_delayed_work_sync(&wl->pspoll_work); - cancel_delayed_work_sync(&wl->elp_work); - - mutex_lock(&wl->mutex); - - /* let's notify MAC80211 about the remaining pending TX frames */ - wl1271_tx_reset(wl); - wl1271_power_off(wl); - - memset(wl->bssid, 0, ETH_ALEN); - memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); - wl->ssid_len = 0; - wl->bss_type = MAX_BSS_TYPE; - wl->set_bss_type = MAX_BSS_TYPE; - wl->band = IEEE80211_BAND_2GHZ; - - wl->rx_counter = 0; - wl->psm_entry_retry = 0; - wl->power_level = WL1271_DEFAULT_POWER_LEVEL; - wl->tx_blocks_available = 0; - wl->tx_results_count = 0; - wl->tx_packets_count = 0; - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; - wl->time_offset = 0; - wl->session_counter = 0; - wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; - wl->flags = 0; - wl->vif = NULL; - wl->filters = 0; - - for (i = 0; i < NUM_TX_QUEUES; i++) - wl->tx_blocks_freed[i] = 0; - - wl1271_debugfs_reset(wl); - - kfree(wl->fw_status); - wl->fw_status = NULL; - kfree(wl->tx_res_if); - wl->tx_res_if = NULL; - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; -} - -static void wl1271_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1271 *wl = hw->priv; - - mutex_lock(&wl->mutex); - WARN_ON(wl->vif != vif); - __wl1271_op_remove_interface(wl); - mutex_unlock(&wl->mutex); - - cancel_work_sync(&wl->recovery_work); -} - -static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) -{ - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - - /* combine requested filters with current filter config */ - filters = wl->filters | filters; - - wl1271_debug(DEBUG_FILTERS, "RX filters set: "); - - if (filters & FIF_PROMISC_IN_BSS) { - wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS"); - wl->rx_config &= ~CFG_UNI_FILTER_EN; - wl->rx_config |= CFG_BSSID_FILTER_EN; - } - if (filters & FIF_BCN_PRBRESP_PROMISC) { - wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC"); - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - wl->rx_config &= ~CFG_SSID_FILTER_EN; - } - if (filters & FIF_OTHER_BSS) { - wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS"); - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - } - if (filters & FIF_CONTROL) { - wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL"); - wl->rx_filter |= CFG_RX_CTL_EN; - } - if (filters & FIF_FCSFAIL) { - wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL"); - wl->rx_filter |= CFG_RX_FCS_ERROR; - } -} - -static int wl1271_dummy_join(struct wl1271 *wl) -{ - int ret = 0; - /* we need to use a dummy BSSID for now */ - static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, - 0xad, 0xbe, 0xef }; - - memcpy(wl->bssid, dummy_bssid, ETH_ALEN); - - /* pass through frames from all BSS */ - wl1271_configure_filters(wl, FIF_OTHER_BSS); - - ret = wl1271_cmd_join(wl, wl->set_bss_type); - if (ret < 0) - goto out; - - set_bit(WL1271_FLAG_JOINED, &wl->flags); - -out: - return ret; -} - -static int wl1271_join(struct wl1271 *wl, bool set_assoc) -{ - int ret; - - /* - * One of the side effects of the JOIN command is that is clears - * WPA/WPA2 keys from the chipset. Performing a JOIN while associated - * to a WPA/WPA2 access point will therefore kill the data-path. - * Currently there is no supported scenario for JOIN during - * association - if it becomes a supported scenario, the WPA/WPA2 keys - * must be handled somehow. - * - */ - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_info("JOIN while associated."); - - if (set_assoc) - set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); - - ret = wl1271_cmd_join(wl, wl->set_bss_type); - if (ret < 0) - goto out; - - set_bit(WL1271_FLAG_JOINED, &wl->flags); - - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - goto out; - - /* - * The join command disable the keep-alive mode, shut down its process, - * and also clear the template config, so we need to reset it all after - * the join. The acx_aid starts the keep-alive process, and the order - * of the commands below is relevant. - */ - ret = wl1271_acx_keep_alive_mode(wl, true); - if (ret < 0) - goto out; - - ret = wl1271_acx_aid(wl, wl->aid); - if (ret < 0) - goto out; - - ret = wl1271_cmd_build_klv_null_data(wl); - if (ret < 0) - goto out; - - ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_VALID); - if (ret < 0) - goto out; - -out: - return ret; -} - -static int wl1271_unjoin(struct wl1271 *wl) -{ - int ret; - - /* to stop listening to a channel, we disconnect */ - ret = wl1271_cmd_disconnect(wl); - if (ret < 0) - goto out; - - clear_bit(WL1271_FLAG_JOINED, &wl->flags); - memset(wl->bssid, 0, ETH_ALEN); - - /* stop filterting packets based on bssid */ - wl1271_configure_filters(wl, FIF_OTHER_BSS); - -out: - return ret; -} - -static void wl1271_set_band_rate(struct wl1271 *wl) -{ - if (wl->band == IEEE80211_BAND_2GHZ) - wl->basic_rate_set = wl->conf.tx.basic_rate; - else - wl->basic_rate_set = wl->conf.tx.basic_rate_5; -} - -static u32 wl1271_min_rate_get(struct wl1271 *wl) -{ - int i; - u32 rate = 0; - - if (!wl->basic_rate_set) { - WARN_ON(1); - wl->basic_rate_set = wl->conf.tx.basic_rate; - } - - for (i = 0; !rate; i++) { - if ((wl->basic_rate_set >> i) & 0x1) - rate = 1 << i; - } - - return rate; -} - -static int wl1271_handle_idle(struct wl1271 *wl, bool idle) -{ - int ret; - - if (idle) { - if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { - ret = wl1271_unjoin(wl); - if (ret < 0) - goto out; - } - wl->rate_set = wl1271_min_rate_get(wl); - wl->sta_rate_set = 0; - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out; - ret = wl1271_acx_keep_alive_config( - wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_INVALID); - if (ret < 0) - goto out; - set_bit(WL1271_FLAG_IDLE, &wl->flags); - } else { - /* increment the session counter */ - wl->session_counter++; - if (wl->session_counter >= SESSION_COUNTER_MAX) - wl->session_counter = 0; - ret = wl1271_dummy_join(wl); - if (ret < 0) - goto out; - clear_bit(WL1271_FLAG_IDLE, &wl->flags); - } - -out: - return ret; -} - -static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - int channel, ret = 0; - - channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - - wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s", - channel, - conf->flags & IEEE80211_CONF_PS ? "on" : "off", - conf->power_level, - conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); - - /* - * mac80211 will go to idle nearly immediately after transmitting some - * frames, such as the deauth. To make sure those frames reach the air, - * wait here until the TX queue is fully flushed. - */ - if ((changed & IEEE80211_CONF_CHANGE_IDLE) && - (conf->flags & IEEE80211_CONF_IDLE)) - wl1271_tx_flush(wl); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) { - ret = -EAGAIN; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - /* if the channel changes while joined, join again */ - if (changed & IEEE80211_CONF_CHANGE_CHANNEL && - ((wl->band != conf->channel->band) || - (wl->channel != channel))) { - wl->band = conf->channel->band; - wl->channel = channel; - - /* - * FIXME: the mac80211 should really provide a fixed rate - * to use here. for now, just use the smallest possible rate - * for the band as a fixed rate for association frames and - * other control messages. - */ - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_set_band_rate(wl); - - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - wl1271_warning("rate policy for update channel " - "failed %d", ret); - - if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { - ret = wl1271_join(wl, false); - if (ret < 0) - wl1271_warning("cmd join to update channel " - "failed %d", ret); - } - } - - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - ret = wl1271_handle_idle(wl, conf->flags & IEEE80211_CONF_IDLE); - if (ret < 0) - wl1271_warning("idle mode change failed %d", ret); - } - - /* - * if mac80211 changes the PSM mode, make sure the mode is not - * incorrectly changed after the pspoll failure active window. - */ - if (changed & IEEE80211_CONF_CHANGE_PS) - clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); - - if (conf->flags & IEEE80211_CONF_PS && - !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { - set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); - - /* - * We enter PSM only if we're already associated. - * If we're not, we'll enter it when joining an SSID, - * through the bss_info_changed() hook. - */ - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { - wl1271_debug(DEBUG_PSM, "psm enabled"); - ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - wl->basic_rate, true); - } - } else if (!(conf->flags & IEEE80211_CONF_PS) && - test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { - wl1271_debug(DEBUG_PSM, "psm disabled"); - - clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); - - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate, true); - } - - if (conf->power_level != wl->power_level) { - ret = wl1271_acx_tx_power(wl, conf->power_level); - if (ret < 0) - goto out_sleep; - - wl->power_level = conf->power_level; - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -struct wl1271_filter_params { - bool enabled; - int mc_list_length; - u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; -}; - -static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct wl1271_filter_params *fp; - struct netdev_hw_addr *ha; - struct wl1271 *wl = hw->priv; - - if (unlikely(wl->state == WL1271_STATE_OFF)) - return 0; - - fp = kzalloc(sizeof(*fp), GFP_ATOMIC); - if (!fp) { - wl1271_error("Out of memory setting filters."); - return 0; - } - - /* update multicast filtering parameters */ - fp->mc_list_length = 0; - if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) { - fp->enabled = false; - } else { - fp->enabled = true; - netdev_hw_addr_list_for_each(ha, mc_list) { - memcpy(fp->mc_list[fp->mc_list_length], - ha->addr, ETH_ALEN); - fp->mc_list_length++; - } - } - - return (u64)(unsigned long)fp; -} - -#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_BCN_PRBRESP_PROMISC | \ - FIF_CONTROL | \ - FIF_OTHER_BSS) - -static void wl1271_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, - unsigned int *total, u64 multicast) -{ - struct wl1271_filter_params *fp = (void *)(unsigned long)multicast; - struct wl1271 *wl = hw->priv; - int ret; - - wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter"); - - mutex_lock(&wl->mutex); - - *total &= WL1271_SUPPORTED_FILTERS; - changed &= WL1271_SUPPORTED_FILTERS; - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - - if (*total & FIF_ALLMULTI) - ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); - else if (fp) - ret = wl1271_acx_group_address_tbl(wl, fp->enabled, - fp->mc_list, - fp->mc_list_length); - if (ret < 0) - goto out_sleep; - - /* determine, whether supported filter values have changed */ - if (changed == 0) - goto out_sleep; - - /* configure filters */ - wl->filters = *total; - wl1271_configure_filters(wl, 0); - - /* apply configured filters */ - ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - kfree(fp); -} - -static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key_conf) -{ - struct wl1271 *wl = hw->priv; - const u8 *addr; - int ret; - u32 tx_seq_32 = 0; - u16 tx_seq_16 = 0; - u8 key_type; - - static const u8 bcast_addr[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); - - addr = sta ? sta->addr : bcast_addr; - - wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); - wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); - wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key_conf->cipher, key_conf->keyidx, - key_conf->keylen, key_conf->flags); - wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); - - if (is_zero_ether_addr(addr)) { - /* We dont support TX only encryption */ - ret = -EOPNOTSUPP; - goto out; - } - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) { - ret = -EAGAIN; - goto out_unlock; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out_unlock; - - switch (key_conf->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - key_type = KEY_WEP; - - key_conf->hw_key_idx = key_conf->keyidx; - break; - case WLAN_CIPHER_SUITE_TKIP: - key_type = KEY_TKIP; - - key_conf->hw_key_idx = key_conf->keyidx; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); - break; - case WLAN_CIPHER_SUITE_CCMP: - key_type = KEY_AES; - - key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); - break; - case WL1271_CIPHER_SUITE_GEM: - key_type = KEY_GEM; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); - break; - default: - wl1271_error("Unknown key algo 0x%x", key_conf->cipher); - - ret = -EOPNOTSUPP; - goto out_sleep; - } - - switch (cmd) { - case SET_KEY: - ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, tx_seq_32, tx_seq_16); - if (ret < 0) { - wl1271_error("Could not add or replace key"); - goto out_sleep; - } - - /* the default WEP key needs to be configured at least once */ - if (key_type == KEY_WEP) { - ret = wl1271_cmd_set_default_wep_key(wl, - wl->default_key); - if (ret < 0) - goto out_sleep; - } - break; - - case DISABLE_KEY: - /* The wl1271 does not allow to remove unicast keys - they - will be cleared automatically on next CMD_JOIN. Ignore the - request silently, as we dont want the mac80211 to emit - an error message. */ - if (!is_broadcast_ether_addr(addr)) - break; - - ret = wl1271_cmd_set_key(wl, KEY_REMOVE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, 0, 0); - if (ret < 0) { - wl1271_error("Could not remove key"); - goto out_sleep; - } - break; - - default: - wl1271_error("Unsupported key cmd 0x%x", cmd); - ret = -EOPNOTSUPP; - break; - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out_unlock: - mutex_unlock(&wl->mutex); - -out: - return ret; -} - -static int wl1271_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) -{ - struct wl1271 *wl = hw->priv; - int ret; - u8 *ssid = NULL; - size_t len = 0; - - wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan"); - - if (req->n_ssids) { - ssid = req->ssids[0].ssid; - len = req->ssids[0].ssid_len; - } - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) { - /* - * We cannot return -EBUSY here because cfg80211 will expect - * a call to ieee80211_scan_completed if we do - in this case - * there won't be any call. - */ - ret = -EAGAIN; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - ret = wl1271_scan(hw->priv, ssid, len, req); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct wl1271 *wl = hw->priv; - int ret = 0; - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) { - ret = -EAGAIN; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - ret = wl1271_acx_rts_threshold(wl, (u16) value); - if (ret < 0) - wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) -{ - u8 *ptr = beacon->data + - offsetof(struct ieee80211_mgmt, u.beacon.variable); - - /* find the location of the ssid in the beacon */ - while (ptr < beacon->data + beacon->len) { - if (ptr[0] == WLAN_EID_SSID) { - wl->ssid_len = ptr[1]; - memcpy(wl->ssid, ptr+2, wl->ssid_len); - return; - } - ptr += ptr[1]; - } - wl1271_error("ad-hoc beacon template has no SSID!\n"); -} - -static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - enum wl1271_cmd_ps_mode mode; - struct wl1271 *wl = hw->priv; - struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); - bool do_join = false; - bool set_assoc = false; - int ret; - - wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - if ((changed & BSS_CHANGED_BEACON_INT) && - (wl->bss_type == BSS_TYPE_IBSS)) { - wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", - bss_conf->beacon_int); - - wl->beacon_int = bss_conf->beacon_int; - do_join = true; - } - - if ((changed & BSS_CHANGED_BEACON) && - (wl->bss_type == BSS_TYPE_IBSS)) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - - wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated"); - - if (beacon) { - struct ieee80211_hdr *hdr; - - wl1271_ssid_set(wl, beacon); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, - beacon->data, - beacon->len, 0, - wl1271_min_rate_get(wl)); - - if (ret < 0) { - dev_kfree_skb(beacon); - goto out_sleep; - } - - hdr = (struct ieee80211_hdr *) beacon->data; - hdr->frame_control = cpu_to_le16( - IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - - ret = wl1271_cmd_template_set(wl, - CMD_TEMPL_PROBE_RESPONSE, - beacon->data, - beacon->len, 0, - wl1271_min_rate_get(wl)); - dev_kfree_skb(beacon); - if (ret < 0) - goto out_sleep; - - /* Need to update the SSID (for filtering etc) */ - do_join = true; - } - } - - if ((changed & BSS_CHANGED_BEACON_ENABLED) && - (wl->bss_type == BSS_TYPE_IBSS)) { - wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s", - bss_conf->enable_beacon ? "enabled" : "disabled"); - - if (bss_conf->enable_beacon) - wl->set_bss_type = BSS_TYPE_IBSS; - else - wl->set_bss_type = BSS_TYPE_STA_BSS; - do_join = true; - } - - if (changed & BSS_CHANGED_CQM) { - bool enable = false; - if (bss_conf->cqm_rssi_thold) - enable = true; - ret = wl1271_acx_rssi_snr_trigger(wl, enable, - bss_conf->cqm_rssi_thold, - bss_conf->cqm_rssi_hyst); - if (ret < 0) - goto out; - wl->rssi_thold = bss_conf->cqm_rssi_thold; - } - - if ((changed & BSS_CHANGED_BSSID) && - /* - * Now we know the correct bssid, so we send a new join command - * and enable the BSSID filter - */ - memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { - memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); - - ret = wl1271_cmd_build_null_data(wl); - if (ret < 0) - goto out_sleep; - - ret = wl1271_build_qos_null_data(wl); - if (ret < 0) - goto out_sleep; - - /* filter out all packets not from this BSSID */ - wl1271_configure_filters(wl, 0); - - /* Need to update the BSSID (for filtering etc) */ - do_join = true; - } - - if (changed & BSS_CHANGED_ASSOC) { - if (bss_conf->assoc) { - u32 rates; - wl->aid = bss_conf->aid; - set_assoc = true; - - wl->ps_poll_failures = 0; - - /* - * use basic rates from AP, and determine lowest rate - * to use with control frames. - */ - rates = bss_conf->basic_rates; - wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, - rates); - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out_sleep; - - /* - * with wl1271, we don't need to update the - * beacon_int and dtim_period, because the firmware - * updates it by itself when the first beacon is - * received after a join. - */ - ret = wl1271_cmd_build_ps_poll(wl, wl->aid); - if (ret < 0) - goto out_sleep; - - /* - * The SSID is intentionally set to NULL here - the - * firmware will set the probe request with a - * broadcast SSID regardless of what we set in the - * template. - */ - ret = wl1271_cmd_build_probe_req(wl, NULL, 0, - NULL, 0, wl->band); - - /* enable the connection monitoring feature */ - ret = wl1271_acx_conn_monit_params(wl, true); - if (ret < 0) - goto out_sleep; - - /* If we want to go in PSM but we're not there yet */ - if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && - !test_bit(WL1271_FLAG_PSM, &wl->flags)) { - mode = STATION_POWER_SAVE_MODE; - ret = wl1271_ps_set_mode(wl, mode, - wl->basic_rate, - true); - if (ret < 0) - goto out_sleep; - } - } else { - /* use defaults when not associated */ - clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags); - clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); - wl->aid = 0; - - /* re-enable dynamic ps - just in case */ - ieee80211_enable_dyn_ps(wl->vif); - - /* revert back to minimum rates for the current band */ - wl1271_set_band_rate(wl); - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out_sleep; - - /* disable connection monitor features */ - ret = wl1271_acx_conn_monit_params(wl, false); - - /* Disable the keep-alive feature */ - ret = wl1271_acx_keep_alive_mode(wl, false); - - if (ret < 0) - goto out_sleep; - } - - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - if (bss_conf->use_short_slot) - ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT); - else - ret = wl1271_acx_slot(wl, SLOT_TIME_LONG); - if (ret < 0) { - wl1271_warning("Set slot time failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (bss_conf->use_short_preamble) - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); - else - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG); - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (bss_conf->use_cts_prot) - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE); - else - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE); - if (ret < 0) { - wl1271_warning("Set ctsprotect failed %d", ret); - goto out_sleep; - } - } - - /* - * Takes care of: New association with HT enable, - * HT information change in beacon. - */ - if (sta && - (changed & BSS_CHANGED_HT) && - (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); - if (ret < 0) { - wl1271_warning("Set ht cap true failed %d", ret); - goto out_sleep; - } - ret = wl1271_acx_set_ht_information(wl, - bss_conf->ht_operation_mode); - if (ret < 0) { - wl1271_warning("Set ht information failed %d", ret); - goto out_sleep; - } - } - /* - * Takes care of: New association without HT, - * Disassociation. - */ - else if (sta && (changed & BSS_CHANGED_ASSOC)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); - if (ret < 0) { - wl1271_warning("Set ht cap false failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ARP_FILTER) { - __be32 addr = bss_conf->arp_addr_list[0]; - WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); - - if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled) - ret = wl1271_acx_arp_ip_filter(wl, true, addr); - else - ret = wl1271_acx_arp_ip_filter(wl, false, addr); - - if (ret < 0) - goto out_sleep; - } - - if (do_join) { - ret = wl1271_join(wl, set_assoc); - if (ret < 0) { - wl1271_warning("cmd join failed %d", ret); - goto out_sleep; - } - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct wl1271 *wl = hw->priv; - u8 ps_scheme; - int ret; - - mutex_lock(&wl->mutex); - - wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); - - if (unlikely(wl->state == WL1271_STATE_OFF)) { - ret = -EAGAIN; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - /* the txop is confed in units of 32us by the mac80211, we need us */ - ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), - params->cw_min, params->cw_max, - params->aifs, params->txop << 5); - if (ret < 0) - goto out_sleep; - - if (params->uapsd) - ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER; - else - ps_scheme = CONF_PS_SCHEME_LEGACY; - - ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), - CONF_CHANNEL_TYPE_EDCF, - wl1271_tx_get_queue(queue), - ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) -{ - - struct wl1271 *wl = hw->priv; - u64 mactime = ULLONG_MAX; - int ret; - - wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - ret = wl1271_acx_tsf_info(wl, &mactime); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - return mactime; -} - -static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = wl->noise; - - return 0; -} - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_rate wl1271_rates[] = { - { .bitrate = 10, - .hw_value = CONF_HW_BIT_RATE_1MBPS, - .hw_value_short = CONF_HW_BIT_RATE_1MBPS, }, - { .bitrate = 20, - .hw_value = CONF_HW_BIT_RATE_2MBPS, - .hw_value_short = CONF_HW_BIT_RATE_2MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, - .hw_value = CONF_HW_BIT_RATE_5_5MBPS, - .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, - .hw_value = CONF_HW_BIT_RATE_11MBPS, - .hw_value_short = CONF_HW_BIT_RATE_11MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60, - .hw_value = CONF_HW_BIT_RATE_6MBPS, - .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, - { .bitrate = 90, - .hw_value = CONF_HW_BIT_RATE_9MBPS, - .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, - { .bitrate = 120, - .hw_value = CONF_HW_BIT_RATE_12MBPS, - .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, - { .bitrate = 180, - .hw_value = CONF_HW_BIT_RATE_18MBPS, - .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, - { .bitrate = 240, - .hw_value = CONF_HW_BIT_RATE_24MBPS, - .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, - { .bitrate = 360, - .hw_value = CONF_HW_BIT_RATE_36MBPS, - .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, - { .bitrate = 480, - .hw_value = CONF_HW_BIT_RATE_48MBPS, - .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, - { .bitrate = 540, - .hw_value = CONF_HW_BIT_RATE_54MBPS, - .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, -}; - -/* - * Can't be const, mac80211 writes to this. The order of the channels here - * is designed to improve scanning. - */ -static struct ieee80211_channel wl1271_channels[] = { - { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, - { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, - { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, - { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, - { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, - { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, - { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, - { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, - { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, - { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, - { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, - { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, - { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, -}; - -/* mapping to indexes for wl1271_rates */ -static const u8 wl1271_rate_to_idx_2ghz[] = { - /* MCS rates are used only with 11n */ - 7, /* CONF_HW_RXTX_RATE_MCS7 */ - 6, /* CONF_HW_RXTX_RATE_MCS6 */ - 5, /* CONF_HW_RXTX_RATE_MCS5 */ - 4, /* CONF_HW_RXTX_RATE_MCS4 */ - 3, /* CONF_HW_RXTX_RATE_MCS3 */ - 2, /* CONF_HW_RXTX_RATE_MCS2 */ - 1, /* CONF_HW_RXTX_RATE_MCS1 */ - 0, /* CONF_HW_RXTX_RATE_MCS0 */ - - 11, /* CONF_HW_RXTX_RATE_54 */ - 10, /* CONF_HW_RXTX_RATE_48 */ - 9, /* CONF_HW_RXTX_RATE_36 */ - 8, /* CONF_HW_RXTX_RATE_24 */ - - /* TI-specific rate */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ - - 7, /* CONF_HW_RXTX_RATE_18 */ - 6, /* CONF_HW_RXTX_RATE_12 */ - 3, /* CONF_HW_RXTX_RATE_11 */ - 5, /* CONF_HW_RXTX_RATE_9 */ - 4, /* CONF_HW_RXTX_RATE_6 */ - 2, /* CONF_HW_RXTX_RATE_5_5 */ - 1, /* CONF_HW_RXTX_RATE_2 */ - 0 /* CONF_HW_RXTX_RATE_1 */ -}; - -/* 11n STA capabilities */ -#define HW_RX_HIGHEST_RATE 72 - -#ifdef CONFIG_WL1271_HT -#define WL1271_HT_CAP { \ - .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ - .ht_supported = true, \ - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \ - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ - .mcs = { \ - .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ - .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \ - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ - }, \ -} -#else -#define WL1271_HT_CAP { \ - .ht_supported = false, \ -} -#endif - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_supported_band wl1271_band_2ghz = { - .channels = wl1271_channels, - .n_channels = ARRAY_SIZE(wl1271_channels), - .bitrates = wl1271_rates, - .n_bitrates = ARRAY_SIZE(wl1271_rates), - .ht_cap = WL1271_HT_CAP, -}; - -/* 5 GHz data rates for WL1273 */ -static struct ieee80211_rate wl1271_rates_5ghz[] = { - { .bitrate = 60, - .hw_value = CONF_HW_BIT_RATE_6MBPS, - .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, - { .bitrate = 90, - .hw_value = CONF_HW_BIT_RATE_9MBPS, - .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, - { .bitrate = 120, - .hw_value = CONF_HW_BIT_RATE_12MBPS, - .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, - { .bitrate = 180, - .hw_value = CONF_HW_BIT_RATE_18MBPS, - .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, - { .bitrate = 240, - .hw_value = CONF_HW_BIT_RATE_24MBPS, - .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, - { .bitrate = 360, - .hw_value = CONF_HW_BIT_RATE_36MBPS, - .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, - { .bitrate = 480, - .hw_value = CONF_HW_BIT_RATE_48MBPS, - .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, - { .bitrate = 540, - .hw_value = CONF_HW_BIT_RATE_54MBPS, - .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, -}; - -/* - * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this. - * The order of the channels here is designed to improve scanning. - */ -static struct ieee80211_channel wl1271_channels_5ghz[] = { - { .hw_value = 183, .center_freq = 4915}, - { .hw_value = 188, .center_freq = 4940}, - { .hw_value = 8, .center_freq = 5040}, - { .hw_value = 34, .center_freq = 5170}, - { .hw_value = 44, .center_freq = 5220}, - { .hw_value = 60, .center_freq = 5300}, - { .hw_value = 112, .center_freq = 5560}, - { .hw_value = 132, .center_freq = 5660}, - { .hw_value = 157, .center_freq = 5785}, - { .hw_value = 184, .center_freq = 4920}, - { .hw_value = 189, .center_freq = 4945}, - { .hw_value = 9, .center_freq = 5045}, - { .hw_value = 36, .center_freq = 5180}, - { .hw_value = 46, .center_freq = 5230}, - { .hw_value = 64, .center_freq = 5320}, - { .hw_value = 116, .center_freq = 5580}, - { .hw_value = 136, .center_freq = 5680}, - { .hw_value = 192, .center_freq = 4960}, - { .hw_value = 11, .center_freq = 5055}, - { .hw_value = 38, .center_freq = 5190}, - { .hw_value = 48, .center_freq = 5240}, - { .hw_value = 100, .center_freq = 5500}, - { .hw_value = 120, .center_freq = 5600}, - { .hw_value = 140, .center_freq = 5700}, - { .hw_value = 185, .center_freq = 4925}, - { .hw_value = 196, .center_freq = 4980}, - { .hw_value = 12, .center_freq = 5060}, - { .hw_value = 40, .center_freq = 5200}, - { .hw_value = 52, .center_freq = 5260}, - { .hw_value = 104, .center_freq = 5520}, - { .hw_value = 124, .center_freq = 5620}, - { .hw_value = 149, .center_freq = 5745}, - { .hw_value = 161, .center_freq = 5805}, - { .hw_value = 187, .center_freq = 4935}, - { .hw_value = 7, .center_freq = 5035}, - { .hw_value = 16, .center_freq = 5080}, - { .hw_value = 42, .center_freq = 5210}, - { .hw_value = 56, .center_freq = 5280}, - { .hw_value = 108, .center_freq = 5540}, - { .hw_value = 128, .center_freq = 5640}, - { .hw_value = 153, .center_freq = 5765}, - { .hw_value = 165, .center_freq = 5825}, -}; - -/* mapping to indexes for wl1271_rates_5ghz */ -static const u8 wl1271_rate_to_idx_5ghz[] = { - /* MCS rates are used only with 11n */ - 7, /* CONF_HW_RXTX_RATE_MCS7 */ - 6, /* CONF_HW_RXTX_RATE_MCS6 */ - 5, /* CONF_HW_RXTX_RATE_MCS5 */ - 4, /* CONF_HW_RXTX_RATE_MCS4 */ - 3, /* CONF_HW_RXTX_RATE_MCS3 */ - 2, /* CONF_HW_RXTX_RATE_MCS2 */ - 1, /* CONF_HW_RXTX_RATE_MCS1 */ - 0, /* CONF_HW_RXTX_RATE_MCS0 */ - - 7, /* CONF_HW_RXTX_RATE_54 */ - 6, /* CONF_HW_RXTX_RATE_48 */ - 5, /* CONF_HW_RXTX_RATE_36 */ - 4, /* CONF_HW_RXTX_RATE_24 */ - - /* TI-specific rate */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ - - 3, /* CONF_HW_RXTX_RATE_18 */ - 2, /* CONF_HW_RXTX_RATE_12 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */ - 1, /* CONF_HW_RXTX_RATE_9 */ - 0, /* CONF_HW_RXTX_RATE_6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */ -}; - -static struct ieee80211_supported_band wl1271_band_5ghz = { - .channels = wl1271_channels_5ghz, - .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), - .bitrates = wl1271_rates_5ghz, - .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), - .ht_cap = WL1271_HT_CAP, -}; - -static const u8 *wl1271_band_rate_to_idx[] = { - [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz, - [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz -}; - -static const struct ieee80211_ops wl1271_ops = { - .start = wl1271_op_start, - .stop = wl1271_op_stop, - .add_interface = wl1271_op_add_interface, - .remove_interface = wl1271_op_remove_interface, - .config = wl1271_op_config, - .prepare_multicast = wl1271_op_prepare_multicast, - .configure_filter = wl1271_op_configure_filter, - .tx = wl1271_op_tx, - .set_key = wl1271_op_set_key, - .hw_scan = wl1271_op_hw_scan, - .bss_info_changed = wl1271_op_bss_info_changed, - .set_rts_threshold = wl1271_op_set_rts_threshold, - .conf_tx = wl1271_op_conf_tx, - .get_tsf = wl1271_op_get_tsf, - .get_survey = wl1271_op_get_survey, - CFG80211_TESTMODE_CMD(wl1271_tm_cmd) -}; - - -u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) -{ - u8 idx; - - BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); - - if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { - wl1271_error("Illegal RX rate from HW: %d", rate); - return 0; - } - - idx = wl1271_band_rate_to_idx[band][rate]; - if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { - wl1271_error("Unsupported RX rate from HW: %d", rate); - return 0; - } - - return idx; -} - -static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - ssize_t len; - - len = PAGE_SIZE; - - mutex_lock(&wl->mutex); - len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", - wl->sg_enabled); - mutex_unlock(&wl->mutex); - - return len; - -} - -static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - unsigned long res; - int ret; - - ret = strict_strtoul(buf, 10, &res); - - if (ret < 0) { - wl1271_warning("incorrect value written to bt_coex_mode"); - return count; - } - - mutex_lock(&wl->mutex); - - res = !!res; - - if (res == wl->sg_enabled) - goto out; - - wl->sg_enabled = res; - - if (wl->state == WL1271_STATE_OFF) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - wl1271_acx_sg_enable(wl, wl->sg_enabled); - wl1271_ps_elp_sleep(wl); - - out: - mutex_unlock(&wl->mutex); - return count; -} - -static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, - wl1271_sysfs_show_bt_coex_state, - wl1271_sysfs_store_bt_coex_state); - -static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - ssize_t len; - - len = PAGE_SIZE; - - mutex_lock(&wl->mutex); - if (wl->hw_pg_ver >= 0) - len = snprintf(buf, len, "%d\n", wl->hw_pg_ver); - else - len = snprintf(buf, len, "n/a\n"); - mutex_unlock(&wl->mutex); - - return len; -} - -static DEVICE_ATTR(hw_pg_ver, S_IRUGO | S_IWUSR, - wl1271_sysfs_show_hw_pg_ver, NULL); - -int wl1271_register_hw(struct wl1271 *wl) -{ - int ret; - - if (wl->mac80211_registered) - return 0; - - SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); - - ret = ieee80211_register_hw(wl->hw); - if (ret < 0) { - wl1271_error("unable to register mac80211 hw: %d", ret); - return ret; - } - - wl->mac80211_registered = true; - - register_netdevice_notifier(&wl1271_dev_notifier); - - wl1271_notice("loaded"); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_register_hw); - -void wl1271_unregister_hw(struct wl1271 *wl) -{ - unregister_netdevice_notifier(&wl1271_dev_notifier); - ieee80211_unregister_hw(wl->hw); - wl->mac80211_registered = false; - -} -EXPORT_SYMBOL_GPL(wl1271_unregister_hw); - -int wl1271_init_ieee80211(struct wl1271 *wl) -{ - static const u32 cipher_suites[] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104, - WLAN_CIPHER_SUITE_TKIP, - WLAN_CIPHER_SUITE_CCMP, - WL1271_CIPHER_SUITE_GEM, - }; - - /* The tx descriptor buffer and the TKIP space. */ - wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + - sizeof(struct wl1271_tx_hw_descr); - - /* unit us */ - /* FIXME: find a proper value */ - wl->hw->channel_change_time = 10000; - wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; - - wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_UAPSD | - IEEE80211_HW_HAS_RATE_CONTROL | - IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI; - - wl->hw->wiphy->cipher_suites = cipher_suites; - wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); - wl->hw->wiphy->max_scan_ssids = 1; - wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; - wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; - - wl->hw->queues = 4; - wl->hw->max_rates = 1; - - SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); - -#define WL1271_DEFAULT_CHANNEL 0 - -struct ieee80211_hw *wl1271_alloc_hw(void) -{ - struct ieee80211_hw *hw; - struct platform_device *plat_dev = NULL; - struct wl1271 *wl; - int i, ret; - unsigned int order; - - hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); - if (!hw) { - wl1271_error("could not alloc ieee80211_hw"); - ret = -ENOMEM; - goto err_hw_alloc; - } - - plat_dev = kmemdup(&wl1271_device, sizeof(wl1271_device), GFP_KERNEL); - if (!plat_dev) { - wl1271_error("could not allocate platform_device"); - ret = -ENOMEM; - goto err_plat_alloc; - } - - wl = hw->priv; - memset(wl, 0, sizeof(*wl)); - - INIT_LIST_HEAD(&wl->list); - - wl->hw = hw; - wl->plat_dev = plat_dev; - - skb_queue_head_init(&wl->tx_queue); - - INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); - INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); - INIT_WORK(&wl->irq_work, wl1271_irq_work); - INIT_WORK(&wl->tx_work, wl1271_tx_work); - INIT_WORK(&wl->recovery_work, wl1271_recovery_work); - INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); - wl->channel = WL1271_DEFAULT_CHANNEL; - wl->beacon_int = WL1271_DEFAULT_BEACON_INT; - wl->default_key = 0; - wl->rx_counter = 0; - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - wl->psm_entry_retry = 0; - wl->power_level = WL1271_DEFAULT_POWER_LEVEL; - wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; - wl->basic_rate = CONF_TX_RATE_MASK_BASIC; - wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; - wl->band = IEEE80211_BAND_2GHZ; - wl->vif = NULL; - wl->flags = 0; - wl->sg_enabled = true; - wl->hw_pg_ver = -1; - - memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - wl->tx_frames[i] = NULL; - - spin_lock_init(&wl->wl_lock); - - wl->state = WL1271_STATE_OFF; - mutex_init(&wl->mutex); - - /* Apply default driver configuration. */ - wl1271_conf_init(wl); - - wl1271_debugfs_init(wl); - - order = get_order(WL1271_AGGR_BUFFER_SIZE); - wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); - if (!wl->aggr_buf) { - ret = -ENOMEM; - goto err_hw; - } - - /* Register platform device */ - ret = platform_device_register(wl->plat_dev); - if (ret) { - wl1271_error("couldn't register platform device"); - goto err_aggr; - } - dev_set_drvdata(&wl->plat_dev->dev, wl); - - /* Create sysfs file to control bt coex state */ - ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); - if (ret < 0) { - wl1271_error("failed to create sysfs file bt_coex_state"); - goto err_platform; - } - - /* Create sysfs file to get HW PG version */ - ret = device_create_file(&wl->plat_dev->dev, &dev_attr_hw_pg_ver); - if (ret < 0) { - wl1271_error("failed to create sysfs file hw_pg_ver"); - goto err_bt_coex_state; - } - - return hw; - -err_bt_coex_state: - device_remove_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); - -err_platform: - platform_device_unregister(wl->plat_dev); - -err_aggr: - free_pages((unsigned long)wl->aggr_buf, order); - -err_hw: - wl1271_debugfs_exit(wl); - kfree(plat_dev); - -err_plat_alloc: - ieee80211_free_hw(hw); - -err_hw_alloc: - - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(wl1271_alloc_hw); - -int wl1271_free_hw(struct wl1271 *wl) -{ - platform_device_unregister(wl->plat_dev); - free_pages((unsigned long)wl->aggr_buf, - get_order(WL1271_AGGR_BUFFER_SIZE)); - kfree(wl->plat_dev); - - wl1271_debugfs_exit(wl); - - vfree(wl->fw); - wl->fw = NULL; - kfree(wl->nvs); - wl->nvs = NULL; - - kfree(wl->fw_status); - kfree(wl->tx_res_if); - - ieee80211_free_hw(wl->hw); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_free_hw); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho "); -MODULE_AUTHOR("Juuso Oikarinen "); diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c deleted file mode 100644 index e3c332e2f97c..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1271_reg.h" -#include "wl1271_ps.h" -#include "wl1271_io.h" - -#define WL1271_WAKEUP_TIMEOUT 500 - -void wl1271_elp_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1271 *wl; - - dwork = container_of(work, struct delayed_work, work); - wl = container_of(dwork, struct wl1271, elp_work); - - wl1271_debug(DEBUG_PSM, "elp work"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || - (!test_bit(WL1271_FLAG_PSM, &wl->flags) && - !test_bit(WL1271_FLAG_IDLE, &wl->flags))) - goto out; - - wl1271_debug(DEBUG_PSM, "chip to elp"); - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); - set_bit(WL1271_FLAG_IN_ELP, &wl->flags); - -out: - mutex_unlock(&wl->mutex); -} - -#define ELP_ENTRY_DELAY 5 - -/* Routines to toggle sleep mode while in ELP */ -void wl1271_ps_elp_sleep(struct wl1271 *wl) -{ - if (test_bit(WL1271_FLAG_PSM, &wl->flags) || - test_bit(WL1271_FLAG_IDLE, &wl->flags)) { - cancel_delayed_work(&wl->elp_work); - ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(ELP_ENTRY_DELAY)); - } -} - -int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) -{ - DECLARE_COMPLETION_ONSTACK(compl); - unsigned long flags; - int ret; - u32 start_time = jiffies; - bool pending = false; - - if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) - return 0; - - wl1271_debug(DEBUG_PSM, "waking up chip from elp"); - - /* - * The spinlock is required here to synchronize both the work and - * the completion variable in one entity. - */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (work_pending(&wl->irq_work) || chip_awake) - pending = true; - else - wl->elp_compl = &compl; - spin_unlock_irqrestore(&wl->wl_lock, flags); - - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); - - if (!pending) { - ret = wait_for_completion_timeout( - &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); - if (ret == 0) { - wl1271_error("ELP wakeup timeout!"); - ieee80211_queue_work(wl->hw, &wl->recovery_work); - ret = -ETIMEDOUT; - goto err; - } else if (ret < 0) { - wl1271_error("ELP wakeup completion error."); - goto err; - } - } - - clear_bit(WL1271_FLAG_IN_ELP, &wl->flags); - - wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", - jiffies_to_msecs(jiffies - start_time)); - goto out; - -err: - spin_lock_irqsave(&wl->wl_lock, flags); - wl->elp_compl = NULL; - spin_unlock_irqrestore(&wl->wl_lock, flags); - return ret; - -out: - return 0; -} - -int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - u32 rates, bool send) -{ - int ret; - - switch (mode) { - case STATION_POWER_SAVE_MODE: - wl1271_debug(DEBUG_PSM, "entering psm"); - - ret = wl1271_acx_wake_up_conditions(wl); - if (ret < 0) { - wl1271_error("couldn't set wake up conditions"); - return ret; - } - - ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, - rates, send); - if (ret < 0) - return ret; - - set_bit(WL1271_FLAG_PSM, &wl->flags); - break; - case STATION_ACTIVE_MODE: - default: - wl1271_debug(DEBUG_PSM, "leaving psm"); - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - return ret; - - /* disable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, false); - if (ret < 0) - return ret; - - /* disable beacon filtering */ - ret = wl1271_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, - rates, send); - if (ret < 0) - return ret; - - clear_bit(WL1271_FLAG_PSM, &wl->flags); - break; - } - - return ret; -} - - diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h deleted file mode 100644 index 6ba7b032736f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_ps.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_PS_H__ -#define __WL1271_PS_H__ - -#include "wl1271.h" -#include "wl1271_acx.h" - -int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - u32 rates, bool send); -void wl1271_ps_elp_sleep(struct wl1271 *wl); -int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); -void wl1271_elp_work(struct work_struct *work); - -#endif /* __WL1271_PS_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h deleted file mode 100644 index 990960771528..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_reg.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __REG_H__ -#define __REG_H__ - -#include - -#define REGISTERS_BASE 0x00300000 -#define DRPW_BASE 0x00310000 - -#define REGISTERS_DOWN_SIZE 0x00008800 -#define REGISTERS_WORK_SIZE 0x0000b000 - -#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC -#define FW_STATUS_ADDR (0x14FC0 + 0xA000) - -/* ELP register commands */ -#define ELPCTRL_WAKE_UP 0x1 -#define ELPCTRL_WAKE_UP_WLAN_READY 0x5 -#define ELPCTRL_SLEEP 0x0 -/* ELP WLAN_READY bit */ -#define ELPCTRL_WLAN_READY 0x2 - -/*=============================================== - Host Software Reset - 32bit RW - ------------------------------------------ - [31:1] Reserved - 0 SOFT_RESET Soft Reset - When this bit is set, - it holds the Wlan hardware in a soft reset state. - This reset disables all MAC and baseband processor - clocks except the CardBus/PCI interface clock. - It also initializes all MAC state machines except - the host interface. It does not reload the - contents of the EEPROM. When this bit is cleared - (not self-clearing), the Wlan hardware - exits the software reset state. -===============================================*/ -#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000) - -#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) -#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) -#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) - -#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) -#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) - -/*============================================= - Host Interrupt Mask Register - 32bit (RW) - ------------------------------------------ - Setting a bit in this register masks the - corresponding interrupt to the host. - 0 - RX0 - Rx first dubble buffer Data Interrupt - 1 - TXD - Tx Data Interrupt - 2 - TXXFR - Tx Transfer Interrupt - 3 - RX1 - Rx second dubble buffer Data Interrupt - 4 - RXXFR - Rx Transfer Interrupt - 5 - EVENT_A - Event Mailbox interrupt - 6 - EVENT_B - Event Mailbox interrupt - 7 - WNONHST - Wake On Host Interrupt - 8 - TRACE_A - Debug Trace interrupt - 9 - TRACE_B - Debug Trace interrupt - 10 - CDCMP - Command Complete Interrupt - 11 - - 12 - - 13 - - 14 - ICOMP - Initialization Complete Interrupt - 16 - SG SE - Soft Gemini - Sense enable interrupt - 17 - SG SD - Soft Gemini - Sense disable interrupt - 18 - - - 19 - - - 20 - - - 21- - - Default: 0x0001 -*==============================================*/ -#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC) - -/*============================================= - Host Interrupt Mask Set 16bit, (Write only) - ------------------------------------------ - Setting a bit in this register sets - the corresponding bin in ACX_HINT_MASK register - without effecting the mask - state of other bits (0 = no effect). -==============================================*/ -#define ACX_REG_HINT_MASK_SET (REGISTERS_BASE + 0x04E0) - -/*============================================= - Host Interrupt Mask Clear 16bit,(Write only) - ------------------------------------------ - Setting a bit in this register clears - the corresponding bin in ACX_HINT_MASK register - without effecting the mask - state of other bits (0 = no effect). -=============================================*/ -#define ACX_REG_HINT_MASK_CLR (REGISTERS_BASE + 0x04E4) - -/*============================================= - Host Interrupt Status Nondestructive Read - 16bit,(Read only) - ------------------------------------------ - The host can read this register to determine - which interrupts are active. - Reading this register doesn't - effect its content. -=============================================*/ -#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8) - -/*============================================= - Host Interrupt Status Clear on Read Register - 16bit,(Read only) - ------------------------------------------ - The host can read this register to determine - which interrupts are active. - Reading this register clears it, - thus making all interrupts inactive. -==============================================*/ -#define ACX_REG_INTERRUPT_CLEAR (REGISTERS_BASE + 0x04F8) - -/*============================================= - Host Interrupt Acknowledge Register - 16bit,(Write only) - ------------------------------------------ - The host can set individual bits in this - register to clear (acknowledge) the corresp. - interrupt status bits in the HINT_STS_CLR and - HINT_STS_ND registers, thus making the - assotiated interrupt inactive. (0-no effect) -==============================================*/ -#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0) - -#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538) - -/* Device Configuration registers*/ -#define SOR_CFG (REGISTERS_BASE + 0x0800) - -/* Embedded ARM CPU Control */ - -/*=============================================== - Halt eCPU - 32bit RW - ------------------------------------------ - 0 HALT_ECPU Halt Embedded CPU - This bit is the - compliment of bit 1 (MDATA2) in the SOR_CFG register. - During a hardware reset, this bit holds - the inverse of MDATA2. - When downloading firmware from the host, - set this bit (pull down MDATA2). - The host clears this bit after downloading the firmware into - zero-wait-state SSRAM. - When loading firmware from Flash, clear this bit (pull up MDATA2) - so that the eCPU can run the bootloader code in Flash - HALT_ECPU eCPU State - -------------------- - 1 halt eCPU - 0 enable eCPU - ===============================================*/ -#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804) - -#define HI_CFG (REGISTERS_BASE + 0x0808) - -/*=============================================== - EEPROM Burst Read Start - 32bit RW - ------------------------------------------ - [31:1] Reserved - 0 ACX_EE_START - EEPROM Burst Read Start 0 - Setting this bit starts a burst read from - the external EEPROM. - If this bit is set (after reset) before an EEPROM read/write, - the burst read starts at EEPROM address 0. - Otherwise, it starts at the address - following the address of the previous access. - TheWlan hardware hardware clears this bit automatically. - - Default: 0x00000000 -*================================================*/ -#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C) - -#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4) -#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8) -#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC) -#define OCP_CMD (REGISTERS_BASE + 0x09C0) - -#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8) - -#define CHIP_ID_B (REGISTERS_BASE + 0x5674) - -#define CHIP_ID_1271_PG10 (0x4030101) -#define CHIP_ID_1271_PG20 (0x4030111) - -#define ENABLE (REGISTERS_BASE + 0x5450) - -/* Power Management registers */ -#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) -#define ELP_CMD (REGISTERS_BASE + 0x5808) -#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) -#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) -#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) - -#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) - -/* Scratch Pad registers*/ -#define SCR_PAD0 (REGISTERS_BASE + 0x5608) -#define SCR_PAD1 (REGISTERS_BASE + 0x560C) -#define SCR_PAD2 (REGISTERS_BASE + 0x5610) -#define SCR_PAD3 (REGISTERS_BASE + 0x5614) -#define SCR_PAD4 (REGISTERS_BASE + 0x5618) -#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) -#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) -#define SCR_PAD5 (REGISTERS_BASE + 0x5624) -#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) -#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) -#define SCR_PAD6 (REGISTERS_BASE + 0x5630) -#define SCR_PAD7 (REGISTERS_BASE + 0x5634) -#define SCR_PAD8 (REGISTERS_BASE + 0x5638) -#define SCR_PAD9 (REGISTERS_BASE + 0x563C) - -/* Spare registers*/ -#define SPARE_A1 (REGISTERS_BASE + 0x0994) -#define SPARE_A2 (REGISTERS_BASE + 0x0998) -#define SPARE_A3 (REGISTERS_BASE + 0x099C) -#define SPARE_A4 (REGISTERS_BASE + 0x09A0) -#define SPARE_A5 (REGISTERS_BASE + 0x09A4) -#define SPARE_A6 (REGISTERS_BASE + 0x09A8) -#define SPARE_A7 (REGISTERS_BASE + 0x09AC) -#define SPARE_A8 (REGISTERS_BASE + 0x09B0) -#define SPARE_B1 (REGISTERS_BASE + 0x5420) -#define SPARE_B2 (REGISTERS_BASE + 0x5424) -#define SPARE_B3 (REGISTERS_BASE + 0x5428) -#define SPARE_B4 (REGISTERS_BASE + 0x542C) -#define SPARE_B5 (REGISTERS_BASE + 0x5430) -#define SPARE_B6 (REGISTERS_BASE + 0x5434) -#define SPARE_B7 (REGISTERS_BASE + 0x5438) -#define SPARE_B8 (REGISTERS_BASE + 0x543C) - -#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040) -#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008) -#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100) -#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C) - - -#define ACX_SLV_SOFT_RESET_BIT BIT(1) -#define ACX_REG_EEPROM_START_BIT BIT(1) - -/* Command/Information Mailbox Pointers */ - -/*=============================================== - Command Mailbox Pointer - 32bit RW - ------------------------------------------ - This register holds the start address of - the command mailbox located in the Wlan hardware memory. - The host must read this pointer after a reset to - find the location of the command mailbox. - The Wlan hardware initializes the command mailbox - pointer with the default address of the command mailbox. - The command mailbox pointer is not valid until after - the host receives the Init Complete interrupt from - the Wlan hardware. - ===============================================*/ -#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) - -/*=============================================== - Information Mailbox Pointer - 32bit RW - ------------------------------------------ - This register holds the start address of - the information mailbox located in the Wlan hardware memory. - The host must read this pointer after a reset to find - the location of the information mailbox. - The Wlan hardware initializes the information mailbox pointer - with the default address of the information mailbox. - The information mailbox pointer is not valid - until after the host receives the Init Complete interrupt from - the Wlan hardware. - ===============================================*/ -#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) - - -/* Misc */ - -#define REG_ENABLE_TX_RX (ENABLE) -/* - * Rx configuration (filter) information element - * --------------------------------------------- - */ -#define REG_RX_CONFIG (RX_CFG) -#define REG_RX_FILTER (RX_FILTER_CFG) - - -#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002 - -/* promiscuous - receives all valid frames */ -#define RX_CFG_PROMISCUOUS 0x0008 - -/* receives frames from any BSSID */ -#define RX_CFG_BSSID 0x0020 - -/* receives frames destined to any MAC address */ -#define RX_CFG_MAC 0x0010 - -#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010 -#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000 -#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020 -#define RX_CFG_ENABLE_ANY_BSSID 0x0000 - -/* discards all broadcast frames */ -#define RX_CFG_DISABLE_BCAST 0x0200 - -#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400 -#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800 -#define RX_CFG_COPY_RX_STATUS 0x2000 -#define RX_CFG_TSF 0x10000 - -#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ - RX_CFG_ENABLE_ONLY_MY_BSSID) - -#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ - | RX_CFG_ENABLE_ANY_BSSID) - -#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ - RX_CFG_ENABLE_ANY_BSSID) - -#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ - | RX_CFG_ENABLE_ONLY_MY_BSSID) - -#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \ - | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \ - | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF) - -#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC) - -#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \ - RX_CFG_ENABLE_ONLY_MY_DEST_MAC) - -#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \ - RX_CFG_ENABLE_ONLY_MY_DEST_MAC) - -#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ - | CFG_RX_CTL_EN | CFG_RX_BCN_EN\ - | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) - -#define RX_FILTER_OPTION_FILTER_ALL 0 - -#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\ - | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN) - -#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ - | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\ - | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\ - | CFG_RX_PRSP_EN) - - -/*=============================================== - EEPROM Read/Write Request 32bit RW - ------------------------------------------ - 1 EE_READ - EEPROM Read Request 1 - Setting this bit - loads a single byte of data into the EE_DATA - register from the EEPROM location specified in - the EE_ADDR register. - The Wlan hardware hardware clears this bit automatically. - EE_DATA is valid when this bit is cleared. - - 0 EE_WRITE - EEPROM Write Request - Setting this bit - writes a single byte of data from the EE_DATA register into the - EEPROM location specified in the EE_ADDR register. - The Wlan hardware hardware clears this bit automatically. -*===============================================*/ -#define ACX_EE_CTL_REG EE_CTL -#define EE_WRITE 0x00000001ul -#define EE_READ 0x00000002ul - -/*=============================================== - EEPROM Address - 32bit RW - ------------------------------------------ - This register specifies the address - within the EEPROM from/to which to read/write data. - ===============================================*/ -#define ACX_EE_ADDR_REG EE_ADDR - -/*=============================================== - EEPROM Data - 32bit RW - ------------------------------------------ - This register either holds the read 8 bits of - data from the EEPROM or the write data - to be written to the EEPROM. - ===============================================*/ -#define ACX_EE_DATA_REG EE_DATA - -/*=============================================== - EEPROM Base Address - 32bit RW - ------------------------------------------ - This register holds the upper nine bits - [23:15] of the 24-bit Wlan hardware memory - address for burst reads from EEPROM accesses. - The EEPROM provides the lower 15 bits of this address. - The MSB of the address from the EEPROM is ignored. - ===============================================*/ -#define ACX_EE_CFG EE_CFG - -/*=============================================== - GPIO Output Values -32bit, RW - ------------------------------------------ - [31:16] Reserved - [15: 0] Specify the output values (at the output driver inputs) for - GPIO[15:0], respectively. - ===============================================*/ -#define ACX_GPIO_OUT_REG GPIO_OUT -#define ACX_MAX_GPIO_LINES 15 - -/*=============================================== - Contention window -32bit, RW - ------------------------------------------ - [31:26] Reserved - [25:16] Max (0x3ff) - [15:07] Reserved - [06:00] Current contention window value - default is 0x1F - ===============================================*/ -#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG -#define ACX_CONT_WIND_MIN_MASK 0x0000007f -#define ACX_CONT_WIND_MAX 0x03ff0000 - -/*=============================================== - HI_CFG Interface Configuration Register Values - ------------------------------------------ - ===============================================*/ -#define HI_CFG_UART_ENABLE 0x00000004 -#define HI_CFG_RST232_ENABLE 0x00000008 -#define HI_CFG_CLOCK_REQ_SELECT 0x00000010 -#define HI_CFG_HOST_INT_ENABLE 0x00000020 -#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040 -#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080 -#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100 -#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 -#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 - -/* - * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile - * for platforms using active high interrupt level - */ -#ifdef USE_ACTIVE_HIGH -#define HI_CFG_DEF_VAL \ - (HI_CFG_UART_ENABLE | \ - HI_CFG_RST232_ENABLE | \ - HI_CFG_CLOCK_REQ_SELECT | \ - HI_CFG_HOST_INT_ENABLE) -#else -#define HI_CFG_DEF_VAL \ - (HI_CFG_UART_ENABLE | \ - HI_CFG_RST232_ENABLE | \ - HI_CFG_CLOCK_REQ_SELECT | \ - HI_CFG_HOST_INT_ENABLE) - -#endif - -#define REF_FREQ_19_2 0 -#define REF_FREQ_26_0 1 -#define REF_FREQ_38_4 2 -#define REF_FREQ_40_0 3 -#define REF_FREQ_33_6 4 -#define REF_FREQ_NUM 5 - -#define LUT_PARAM_INTEGER_DIVIDER 0 -#define LUT_PARAM_FRACTIONAL_DIVIDER 1 -#define LUT_PARAM_ATTN_BB 2 -#define LUT_PARAM_ALPHA_BB 3 -#define LUT_PARAM_STOP_TIME_BB 4 -#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 -#define LUT_PARAM_NUM 6 - -#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) -#define USE_EEPROM 0 -#define SOFT_RESET_MAX_TIME 1000000 -#define SOFT_RESET_STALL_TIME 1000 -#define NVS_DATA_BUNDARY_ALIGNMENT 4 - - -/* Firmware image load chunk size */ -#define CHUNK_SIZE 512 - -/* Firmware image header size */ -#define FW_HDR_SIZE 8 - -#define ECPU_CONTROL_HALT 0x00000101 - - -/****************************************************************************** - - CHANNELS, BAND & REG DOMAINS definitions - -******************************************************************************/ - - -enum { - RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */ - RADIO_BAND_5GHZ = 1, /* 5 Ghz band */ - RADIO_BAND_JAPAN_4_9_GHZ = 2, - DEFAULT_BAND = RADIO_BAND_2_4GHZ, - INVALID_BAND = 0xFE, - MAX_RADIO_BANDS = 0xFF -}; - -#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ -#define OFDM_RATE_BIT BIT(6) -#define PBCC_RATE_BIT BIT(7) - -enum { - CCK_LONG = 0, - CCK_SHORT = SHORT_PREAMBLE_BIT, - PBCC_LONG = PBCC_RATE_BIT, - PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT, - OFDM = OFDM_RATE_BIT -}; - -/****************************************************************************** - -Transmit-Descriptor RATE-SET field definitions... - -Define a new "Rate-Set" for TX path that incorporates the -Rate & Modulation info into a single 16-bit field. - -TxdRateSet_t: -b15 - Indicates Preamble type (1=SHORT, 0=LONG). - Notes: - Must be LONG (0) for 1Mbps rate. - Does not apply (set to 0) for RevG-OFDM rates. -b14 - Indicates PBCC encoding (1=PBCC, 0=not). - Notes: - Does not apply (set to 0) for rates 1 and 2 Mbps. - Does not apply (set to 0) for RevG-OFDM rates. -b13 - Unused (set to 0). -b12-b0 - Supported Rate indicator bits as defined below. - -******************************************************************************/ - - -/************************************************************************* - - Interrupt Trigger Register (Host -> WiLink) - -**************************************************************************/ - -/* Hardware to Embedded CPU Interrupts - first 32-bit register set */ - -/* - * Host Command Interrupt. Setting this bit masks - * the interrupt that the host issues to inform - * the FW that it has sent a command - * to the Wlan hardware Command Mailbox. - */ -#define INTR_TRIG_CMD BIT(0) - -/* - * Host Event Acknowlegde Interrupt. The host - * sets this bit to acknowledge that it received - * the unsolicited information from the event - * mailbox. - */ -#define INTR_TRIG_EVENT_ACK BIT(1) - -/* - * The host sets this bit to inform the Wlan - * FW that a TX packet is in the XFER - * Buffer #0. - */ -#define INTR_TRIG_TX_PROC0 BIT(2) - -/* - * The host sets this bit to inform the FW - * that it read a packet from RX XFER - * Buffer #0. - */ -#define INTR_TRIG_RX_PROC0 BIT(3) - -#define INTR_TRIG_DEBUG_ACK BIT(4) - -#define INTR_TRIG_STATE_CHANGED BIT(5) - - -/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ - -/* - * The host sets this bit to inform the FW - * that it read a packet from RX XFER - * Buffer #1. - */ -#define INTR_TRIG_RX_PROC1 BIT(17) - -/* - * The host sets this bit to inform the Wlan - * hardware that a TX packet is in the XFER - * Buffer #1. - */ -#define INTR_TRIG_TX_PROC1 BIT(18) - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c deleted file mode 100644 index cacfee56a0d0..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include - -#include "wl1271.h" -#include "wl1271_acx.h" -#include "wl1271_reg.h" -#include "wl1271_rx.h" -#include "wl1271_io.h" - -static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, - u32 drv_rx_counter) -{ - return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & - RX_MEM_BLOCK_MASK; -} - -static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status, - u32 drv_rx_counter) -{ - return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & - RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; -} - -static void wl1271_rx_status(struct wl1271 *wl, - struct wl1271_rx_descriptor *desc, - struct ieee80211_rx_status *status, - u8 beacon) -{ - enum ieee80211_band desc_band; - - memset(status, 0, sizeof(struct ieee80211_rx_status)); - - status->band = wl->band; - - if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG) - desc_band = IEEE80211_BAND_2GHZ; - else - desc_band = IEEE80211_BAND_5GHZ; - - status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band); - -#ifdef CONFIG_WL1271_HT - /* 11n support */ - if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) - status->flag |= RX_FLAG_HT; -#endif - - status->signal = desc->rssi; - - /* - * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we - * need to divide by two for now, but TI has been discussing about - * changing it. This needs to be rechecked. - */ - wl->noise = desc->rssi - (desc->snr >> 1); - - status->freq = ieee80211_channel_to_frequency(desc->channel); - - if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { - status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; - - if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL))) - status->flag |= RX_FLAG_DECRYPTED; - if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL)) - status->flag |= RX_FLAG_MMIC_ERROR; - } -} - -static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) -{ - struct wl1271_rx_descriptor *desc; - struct sk_buff *skb; - u16 *fc; - u8 *buf; - u8 beacon = 0; - - /* - * In PLT mode we seem to get frames and mac80211 warns about them, - * workaround this by not retrieving them at all. - */ - if (unlikely(wl->state == WL1271_STATE_PLT)) - return -EINVAL; - - skb = __dev_alloc_skb(length, GFP_KERNEL); - if (!skb) { - wl1271_error("Couldn't allocate RX frame"); - return -ENOMEM; - } - - buf = skb_put(skb, length); - memcpy(buf, data, length); - - /* the data read starts with the descriptor */ - desc = (struct wl1271_rx_descriptor *) buf; - - /* now we pull the descriptor out of the buffer */ - skb_pull(skb, sizeof(*desc)); - - fc = (u16 *)skb->data; - if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) - beacon = 1; - - wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); - - wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, - beacon ? "beacon" : ""); - - skb_trim(skb, skb->len - desc->pad_len); - - ieee80211_rx_ni(wl->hw, skb); - - return 0; -} - -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) -{ - struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; - u32 buf_size; - u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; - u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; - u32 rx_counter; - u32 mem_block; - u32 pkt_length; - u32 pkt_offset; - - while (drv_rx_counter != fw_rx_counter) { - buf_size = 0; - rx_counter = drv_rx_counter; - while (rx_counter != fw_rx_counter) { - pkt_length = wl1271_rx_get_buf_size(status, rx_counter); - if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) - break; - buf_size += pkt_length; - rx_counter++; - rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; - } - - if (buf_size == 0) { - wl1271_warning("received empty data"); - break; - } - - /* - * Choose the block we want to read - * For aggregated packets, only the first memory block should - * be retrieved. The FW takes care of the rest. - */ - mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); - wl->rx_mem_pool_addr.addr = (mem_block << 8) + - le32_to_cpu(wl_mem_map->packet_memory_pool_start); - wl->rx_mem_pool_addr.addr_extra = - wl->rx_mem_pool_addr.addr + 4; - wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, - sizeof(wl->rx_mem_pool_addr), false); - - /* Read all available packets at once */ - wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, - buf_size, true); - - /* Split data into separate packets */ - pkt_offset = 0; - while (pkt_offset < buf_size) { - pkt_length = wl1271_rx_get_buf_size(status, - drv_rx_counter); - /* - * the handle data call can only fail in memory-outage - * conditions, in that case the received frame will just - * be dropped. - */ - wl1271_rx_handle_data(wl, - wl->aggr_buf + pkt_offset, - pkt_length); - wl->rx_counter++; - drv_rx_counter++; - drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; - pkt_offset += pkt_length; - } - } - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, - cpu_to_le32(wl->rx_counter)); -} diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h deleted file mode 100644 index 6d41981ce53f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_rx.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_RX_H__ -#define __WL1271_RX_H__ - -#include - -#define WL1271_RX_MAX_RSSI -30 -#define WL1271_RX_MIN_RSSI -95 - -#define WL1271_RX_ALIGN_TO 4 -#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \ - ~(WL1271_RX_ALIGN_TO - 1)) - -#define SHORT_PREAMBLE_BIT BIT(0) -#define OFDM_RATE_BIT BIT(6) -#define PBCC_RATE_BIT BIT(7) - -#define PLCP_HEADER_LENGTH 8 -#define RX_DESC_PACKETID_SHIFT 11 -#define RX_MAX_PACKET_ID 3 - -#define NUM_RX_PKT_DESC_MOD_MASK 7 - -#define RX_DESC_VALID_FCS 0x0001 -#define RX_DESC_MATCH_RXADDR1 0x0002 -#define RX_DESC_MCAST 0x0004 -#define RX_DESC_STAINTIM 0x0008 -#define RX_DESC_VIRTUAL_BM 0x0010 -#define RX_DESC_BCAST 0x0020 -#define RX_DESC_MATCH_SSID 0x0040 -#define RX_DESC_MATCH_BSSID 0x0080 -#define RX_DESC_ENCRYPTION_MASK 0x0300 -#define RX_DESC_MEASURMENT 0x0400 -#define RX_DESC_SEQNUM_MASK 0x1800 -#define RX_DESC_MIC_FAIL 0x2000 -#define RX_DESC_DECRYPT_FAIL 0x4000 - -/* - * RX Descriptor flags: - * - * Bits 0-1 - band - * Bit 2 - STBC - * Bit 3 - A-MPDU - * Bit 4 - HT - * Bits 5-7 - encryption - */ -#define WL1271_RX_DESC_BAND_MASK 0x03 -#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0 - -#define WL1271_RX_DESC_BAND_BG 0x00 -#define WL1271_RX_DESC_BAND_J 0x01 -#define WL1271_RX_DESC_BAND_A 0x02 - -#define WL1271_RX_DESC_STBC BIT(2) -#define WL1271_RX_DESC_A_MPDU BIT(3) -#define WL1271_RX_DESC_HT BIT(4) - -#define WL1271_RX_DESC_ENCRYPT_WEP 0x20 -#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40 -#define WL1271_RX_DESC_ENCRYPT_AES 0x60 -#define WL1271_RX_DESC_ENCRYPT_GEM 0x80 - -/* - * RX Descriptor status - * - * Bits 0-2 - status - * Bits 3-7 - reserved - */ -#define WL1271_RX_DESC_STATUS_MASK 0x07 - -#define WL1271_RX_DESC_SUCCESS 0x00 -#define WL1271_RX_DESC_DECRYPT_FAIL 0x01 -#define WL1271_RX_DESC_MIC_FAIL 0x02 -#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03 - -#define RX_MEM_BLOCK_MASK 0xFF -#define RX_BUF_SIZE_MASK 0xFFF00 -#define RX_BUF_SIZE_SHIFT_DIV 6 - -struct wl1271_rx_descriptor { - __le16 length; - u8 status; - u8 flags; - u8 rate; - u8 channel; - s8 rssi; - u8 snr; - __le32 timestamp; - u8 packet_class; - u8 process_id; - u8 pad_len; - u8 reserved; -} __packed; - -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); -u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c deleted file mode 100644 index e0661a543a35..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include - -#include "wl1271.h" -#include "wl1271_cmd.h" -#include "wl1271_scan.h" -#include "wl1271_acx.h" - -void wl1271_scan_complete_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1271 *wl; - - dwork = container_of(work, struct delayed_work, work); - wl = container_of(dwork, struct wl1271, scan_complete_work); - - wl1271_debug(DEBUG_SCAN, "Scanning complete"); - - mutex_lock(&wl->mutex); - - if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { - mutex_unlock(&wl->mutex); - return; - } - - wl->scan.state = WL1271_SCAN_STATE_IDLE; - kfree(wl->scan.scanned_ch); - wl->scan.scanned_ch = NULL; - wl->scan.req = NULL; - ieee80211_scan_completed(wl->hw, false); - - if (wl->scan.failed) { - wl1271_info("Scan completed due to error."); - ieee80211_queue_work(wl->hw, &wl->recovery_work); - } - mutex_unlock(&wl->mutex); - -} - - -static int wl1271_get_scan_channels(struct wl1271 *wl, - struct cfg80211_scan_request *req, - struct basic_scan_channel_params *channels, - enum ieee80211_band band, bool passive) -{ - struct conf_scan_settings *c = &wl->conf.scan; - int i, j; - u32 flags; - - for (i = 0, j = 0; - i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; - i++) { - - flags = req->channels[i]->flags; - - if (!wl->scan.scanned_ch[i] && - !(flags & IEEE80211_CHAN_DISABLED) && - ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && - (req->channels[i]->band == band)) { - - wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", - req->channels[i]->band, - req->channels[i]->center_freq); - wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", - req->channels[i]->hw_value, - req->channels[i]->flags); - wl1271_debug(DEBUG_SCAN, - "max_antenna_gain %d, max_power %d", - req->channels[i]->max_antenna_gain, - req->channels[i]->max_power); - wl1271_debug(DEBUG_SCAN, "beacon_found %d", - req->channels[i]->beacon_found); - - if (!passive) { - channels[j].min_duration = - cpu_to_le32(c->min_dwell_time_active); - channels[j].max_duration = - cpu_to_le32(c->max_dwell_time_active); - } else { - channels[j].min_duration = - cpu_to_le32(c->min_dwell_time_passive); - channels[j].max_duration = - cpu_to_le32(c->max_dwell_time_passive); - } - channels[j].early_termination = 0; - channels[j].tx_power_att = req->channels[i]->max_power; - channels[j].channel = req->channels[i]->hw_value; - - memset(&channels[j].bssid_lsb, 0xff, 4); - memset(&channels[j].bssid_msb, 0xff, 2); - - /* Mark the channels we already used */ - wl->scan.scanned_ch[i] = true; - - j++; - } - } - - return j; -} - -#define WL1271_NOTHING_TO_SCAN 1 - -static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, - bool passive, u32 basic_rate) -{ - struct wl1271_cmd_scan *cmd; - struct wl1271_cmd_trigger_scan_to *trigger; - int ret; - u16 scan_options = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); - if (!cmd || !trigger) { - ret = -ENOMEM; - goto out; - } - - /* We always use high priority scans */ - scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; - - /* No SSIDs means that we have a forced passive scan */ - if (passive || wl->scan.req->n_ssids == 0) - scan_options |= WL1271_SCAN_OPT_PASSIVE; - - cmd->params.scan_options = cpu_to_le16(scan_options); - - cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, - cmd->channels, - band, passive); - if (cmd->params.n_ch == 0) { - ret = WL1271_NOTHING_TO_SCAN; - goto out; - } - - cmd->params.tx_rate = cpu_to_le32(basic_rate); - cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); - cmd->params.rx_filter_options = - cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - - cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; - cmd->params.tx_rate = cpu_to_le32(basic_rate); - cmd->params.tid_trigger = 0; - cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; - - if (band == IEEE80211_BAND_2GHZ) - cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ; - else - cmd->params.band = WL1271_SCAN_BAND_5_GHZ; - - if (wl->scan.ssid_len && wl->scan.ssid) { - cmd->params.ssid_len = wl->scan.ssid_len; - memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); - } - - ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len, - wl->scan.req->ie, wl->scan.req->ie_len, - band); - if (ret < 0) { - wl1271_error("PROBE request template failed"); - goto out; - } - - /* disable the timeout */ - trigger->timeout = 0; - ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, - sizeof(*trigger), 0); - if (ret < 0) { - wl1271_error("trigger scan to failed for hw scan"); - goto out; - } - - wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd)); - - ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("SCAN failed"); - goto out; - } - -out: - kfree(cmd); - kfree(trigger); - return ret; -} - -void wl1271_scan_stm(struct wl1271 *wl) -{ - int ret = 0; - - switch (wl->scan.state) { - case WL1271_SCAN_STATE_IDLE: - break; - - case WL1271_SCAN_STATE_2GHZ_ACTIVE: - ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, - wl->conf.tx.basic_rate); - if (ret == WL1271_NOTHING_TO_SCAN) { - wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; - wl1271_scan_stm(wl); - } - - break; - - case WL1271_SCAN_STATE_2GHZ_PASSIVE: - ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, - wl->conf.tx.basic_rate); - if (ret == WL1271_NOTHING_TO_SCAN) { - if (wl->enable_11a) - wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; - else - wl->scan.state = WL1271_SCAN_STATE_DONE; - wl1271_scan_stm(wl); - } - - break; - - case WL1271_SCAN_STATE_5GHZ_ACTIVE: - ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, - wl->conf.tx.basic_rate_5); - if (ret == WL1271_NOTHING_TO_SCAN) { - wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; - wl1271_scan_stm(wl); - } - - break; - - case WL1271_SCAN_STATE_5GHZ_PASSIVE: - ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, - wl->conf.tx.basic_rate_5); - if (ret == WL1271_NOTHING_TO_SCAN) { - wl->scan.state = WL1271_SCAN_STATE_DONE; - wl1271_scan_stm(wl); - } - - break; - - case WL1271_SCAN_STATE_DONE: - wl->scan.failed = false; - cancel_delayed_work(&wl->scan_complete_work); - ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, - msecs_to_jiffies(0)); - break; - - default: - wl1271_error("invalid scan state"); - break; - } - - if (ret < 0) { - cancel_delayed_work(&wl->scan_complete_work); - ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, - msecs_to_jiffies(0)); - } -} - -int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - struct cfg80211_scan_request *req) -{ - if (wl->scan.state != WL1271_SCAN_STATE_IDLE) - return -EBUSY; - - wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; - - if (ssid_len && ssid) { - wl->scan.ssid_len = ssid_len; - memcpy(wl->scan.ssid, ssid, ssid_len); - } else { - wl->scan.ssid_len = 0; - } - - wl->scan.req = req; - - wl->scan.scanned_ch = kcalloc(req->n_channels, - sizeof(*wl->scan.scanned_ch), - GFP_KERNEL); - /* we assume failure so that timeout scenarios are handled correctly */ - wl->scan.failed = true; - ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, - msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); - - wl1271_scan_stm(wl); - - return 0; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h deleted file mode 100644 index 6d57127b5e6b..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_SCAN_H__ -#define __WL1271_SCAN_H__ - -#include "wl1271.h" - -int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - struct cfg80211_scan_request *req); -int wl1271_scan_build_probe_req(struct wl1271 *wl, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band); -void wl1271_scan_stm(struct wl1271 *wl); -void wl1271_scan_complete_work(struct work_struct *work); - -#define WL1271_SCAN_MAX_CHANNELS 24 -#define WL1271_SCAN_DEFAULT_TAG 1 -#define WL1271_SCAN_CURRENT_TX_PWR 0 -#define WL1271_SCAN_OPT_ACTIVE 0 -#define WL1271_SCAN_OPT_PASSIVE 1 -#define WL1271_SCAN_OPT_PRIORITY_HIGH 4 -#define WL1271_SCAN_BAND_2_4_GHZ 0 -#define WL1271_SCAN_BAND_5_GHZ 1 - -#define WL1271_SCAN_TIMEOUT 10000 /* msec */ - -enum { - WL1271_SCAN_STATE_IDLE, - WL1271_SCAN_STATE_2GHZ_ACTIVE, - WL1271_SCAN_STATE_2GHZ_PASSIVE, - WL1271_SCAN_STATE_5GHZ_ACTIVE, - WL1271_SCAN_STATE_5GHZ_PASSIVE, - WL1271_SCAN_STATE_DONE -}; - -struct basic_scan_params { - __le32 rx_config_options; - __le32 rx_filter_options; - /* Scan option flags (WL1271_SCAN_OPT_*) */ - __le16 scan_options; - /* Number of scan channels in the list (maximum 30) */ - u8 n_ch; - /* This field indicates the number of probe requests to send - per channel for an active scan */ - u8 n_probe_reqs; - /* Rate bit field for sending the probes */ - __le32 tx_rate; - u8 tid_trigger; - u8 ssid_len; - /* in order to align */ - u8 padding1[2]; - u8 ssid[IW_ESSID_MAX_SIZE]; - /* Band to scan */ - u8 band; - u8 use_ssid_list; - u8 scan_tag; - u8 padding2; -} __packed; - -struct basic_scan_channel_params { - /* Duration in TU to wait for frames on a channel for active scan */ - __le32 min_duration; - __le32 max_duration; - __le32 bssid_lsb; - __le16 bssid_msb; - u8 early_termination; - u8 tx_power_att; - u8 channel; - /* FW internal use only! */ - u8 dfs_candidate; - u8 activity_detected; - u8 pad; -} __packed; - -struct wl1271_cmd_scan { - struct wl1271_cmd_header header; - - struct basic_scan_params params; - struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS]; -} __packed; - -struct wl1271_cmd_trigger_scan_to { - struct wl1271_cmd_header header; - - __le32 timeout; -} __packed; - -#endif /* __WL1271_SCAN_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c deleted file mode 100644 index 784ef3432641..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_io.h" - -#ifndef SDIO_VENDOR_ID_TI -#define SDIO_VENDOR_ID_TI 0x0097 -#endif - -#ifndef SDIO_DEVICE_ID_TI_WL1271 -#define SDIO_DEVICE_ID_TI_WL1271 0x4076 -#endif - -static const struct sdio_device_id wl1271_devices[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, - {} -}; -MODULE_DEVICE_TABLE(sdio, wl1271_devices); - -static inline struct sdio_func *wl_to_func(struct wl1271 *wl) -{ - return wl->if_priv; -} - -static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) -{ - return &(wl_to_func(wl)->dev); -} - -static irqreturn_t wl1271_irq(int irq, void *cookie) -{ - struct wl1271 *wl = cookie; - unsigned long flags; - - wl1271_debug(DEBUG_IRQ, "IRQ"); - - /* complete the ELP completion */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (wl->elp_compl) { - complete(wl->elp_compl); - wl->elp_compl = NULL; - } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - return IRQ_HANDLED; -} - -static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) -{ - disable_irq(wl->irq); -} - -static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) -{ - enable_irq(wl->irq); -} - -static void wl1271_sdio_reset(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_init(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { - ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); - wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", - addr, ((u8 *)buf)[0]); - } else { - if (fixed) - ret = sdio_readsb(func, buf, addr, len); - else - ret = sdio_memcpy_fromio(func, buf, addr, len); - - wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - } - - sdio_release_host(func); - - if (ret) - wl1271_error("sdio read failed (%d)", ret); -} - -static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { - sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); - wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", - addr, ((u8 *)buf)[0]); - } else { - wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - - if (fixed) - ret = sdio_writesb(func, addr, buf, len); - else - ret = sdio_memcpy_toio(func, addr, buf, len); - } - - sdio_release_host(func); - - if (ret) - wl1271_error("sdio write failed (%d)", ret); -} - -static int wl1271_sdio_power_on(struct wl1271 *wl) -{ - struct sdio_func *func = wl_to_func(wl); - int ret; - - /* Power up the card */ - ret = pm_runtime_get_sync(&func->dev); - if (ret < 0) - goto out; - - sdio_claim_host(func); - sdio_enable_func(func); - sdio_release_host(func); - -out: - return ret; -} - -static int wl1271_sdio_power_off(struct wl1271 *wl) -{ - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - sdio_disable_func(func); - sdio_release_host(func); - - /* Power down the card */ - return pm_runtime_put_sync(&func->dev); -} - -static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) -{ - if (enable) - return wl1271_sdio_power_on(wl); - else - return wl1271_sdio_power_off(wl); -} - -static struct wl1271_if_operations sdio_ops = { - .read = wl1271_sdio_raw_read, - .write = wl1271_sdio_raw_write, - .reset = wl1271_sdio_reset, - .init = wl1271_sdio_init, - .power = wl1271_sdio_set_power, - .dev = wl1271_sdio_wl_to_dev, - .enable_irq = wl1271_sdio_enable_interrupts, - .disable_irq = wl1271_sdio_disable_interrupts -}; - -static int __devinit wl1271_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - struct ieee80211_hw *hw; - const struct wl12xx_platform_data *wlan_data; - struct wl1271 *wl; - int ret; - - /* We are only able to handle the wlan function */ - if (func->num != 0x02) - return -ENODEV; - - hw = wl1271_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - wl->if_priv = func; - wl->if_ops = &sdio_ops; - - /* Grab access to FN0 for ELP reg. */ - func->card->quirks |= MMC_QUIRK_LENIENT_FN0; - - wlan_data = wl12xx_get_platform_data(); - if (IS_ERR(wlan_data)) { - ret = PTR_ERR(wlan_data); - wl1271_error("missing wlan platform data: %d", ret); - goto out_free; - } - - wl->irq = wlan_data->irq; - wl->ref_clock = wlan_data->board_ref_clock; - - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); - if (ret < 0) { - wl1271_error("request_irq() failed: %d", ret); - goto out_free; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - - disable_irq(wl->irq); - - ret = wl1271_init_ieee80211(wl); - if (ret) - goto out_irq; - - ret = wl1271_register_hw(wl); - if (ret) - goto out_irq; - - sdio_set_drvdata(func, wl); - - /* Tell PM core that we don't need the card to be powered now */ - pm_runtime_put_noidle(&func->dev); - - wl1271_notice("initialized"); - - return 0; - - out_irq: - free_irq(wl->irq, wl); - - - out_free: - wl1271_free_hw(wl); - - return ret; -} - -static void __devexit wl1271_remove(struct sdio_func *func) -{ - struct wl1271 *wl = sdio_get_drvdata(func); - - /* Undo decrement done above in wl1271_probe */ - pm_runtime_get_noresume(&func->dev); - - wl1271_unregister_hw(wl); - free_irq(wl->irq, wl); - wl1271_free_hw(wl); -} - -static int wl1271_suspend(struct device *dev) -{ - /* Tell MMC/SDIO core it's OK to power down the card - * (if it isn't already), but not to remove it completely */ - return 0; -} - -static int wl1271_resume(struct device *dev) -{ - return 0; -} - -static const struct dev_pm_ops wl1271_sdio_pm_ops = { - .suspend = wl1271_suspend, - .resume = wl1271_resume, -}; - -static struct sdio_driver wl1271_sdio_driver = { - .name = "wl1271_sdio", - .id_table = wl1271_devices, - .probe = wl1271_probe, - .remove = __devexit_p(wl1271_remove), - .drv = { - .pm = &wl1271_sdio_pm_ops, - }, -}; - -static int __init wl1271_init(void) -{ - int ret; - - ret = sdio_register_driver(&wl1271_sdio_driver); - if (ret < 0) { - wl1271_error("failed to register sdio driver: %d", ret); - goto out; - } - -out: - return ret; -} - -static void __exit wl1271_exit(void) -{ - sdio_unregister_driver(&wl1271_sdio_driver); - - wl1271_notice("unloaded"); -} - -module_init(wl1271_init); -module_exit(wl1271_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho "); -MODULE_AUTHOR("Juuso Oikarinen "); -MODULE_FIRMWARE(WL1271_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c deleted file mode 100644 index ef801680773f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_io.h" - -#include "wl1271_reg.h" - -#define WSPI_CMD_READ 0x40000000 -#define WSPI_CMD_WRITE 0x00000000 -#define WSPI_CMD_FIXED 0x20000000 -#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 -#define WSPI_CMD_BYTE_LENGTH_OFFSET 17 -#define WSPI_CMD_BYTE_ADDR 0x0001FFFF - -#define WSPI_INIT_CMD_CRC_LEN 5 - -#define WSPI_INIT_CMD_START 0x00 -#define WSPI_INIT_CMD_TX 0x40 -/* the extra bypass bit is sampled by the TNET as '1' */ -#define WSPI_INIT_CMD_BYPASS_BIT 0x80 -#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 -#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 -#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 -#define WSPI_INIT_CMD_IOD 0x40 -#define WSPI_INIT_CMD_IP 0x20 -#define WSPI_INIT_CMD_CS 0x10 -#define WSPI_INIT_CMD_WS 0x08 -#define WSPI_INIT_CMD_WSPI 0x01 -#define WSPI_INIT_CMD_END 0x01 - -#define WSPI_INIT_CMD_LEN 8 - -#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ - ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) -#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 - -/* HW limitation: maximum possible chunk size is 4095 bytes */ -#define WSPI_MAX_CHUNK_SIZE 4092 - -#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) - -static inline struct spi_device *wl_to_spi(struct wl1271 *wl) -{ - return wl->if_priv; -} - -static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) -{ - return &(wl_to_spi(wl)->dev); -} - -static void wl1271_spi_disable_interrupts(struct wl1271 *wl) -{ - disable_irq(wl->irq); -} - -static void wl1271_spi_enable_interrupts(struct wl1271 *wl) -{ - enable_irq(wl->irq); -} - -static void wl1271_spi_reset(struct wl1271 *wl) -{ - u8 *cmd; - struct spi_transfer t; - struct spi_message m; - - cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); - if (!cmd) { - wl1271_error("could not allocate cmd for spi reset"); - return; - } - - memset(&t, 0, sizeof(t)); - spi_message_init(&m); - - memset(cmd, 0xff, WSPI_INIT_CMD_LEN); - - t.tx_buf = cmd; - t.len = WSPI_INIT_CMD_LEN; - spi_message_add_tail(&t, &m); - - spi_sync(wl_to_spi(wl), &m); - kfree(cmd); - - wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); -} - -static void wl1271_spi_init(struct wl1271 *wl) -{ - u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; - struct spi_transfer t; - struct spi_message m; - - cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); - if (!cmd) { - wl1271_error("could not allocate cmd for spi init"); - return; - } - - memset(crc, 0, sizeof(crc)); - memset(&t, 0, sizeof(t)); - spi_message_init(&m); - - /* - * Set WSPI_INIT_COMMAND - * the data is being send from the MSB to LSB - */ - cmd[2] = 0xff; - cmd[3] = 0xff; - cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX; - cmd[0] = 0; - cmd[7] = 0; - cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3; - cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN; - - if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0) - cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY; - else - cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY; - - cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS - | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS; - - crc[0] = cmd[1]; - crc[1] = cmd[0]; - crc[2] = cmd[7]; - crc[3] = cmd[6]; - crc[4] = cmd[5]; - - cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1; - cmd[4] |= WSPI_INIT_CMD_END; - - t.tx_buf = cmd; - t.len = WSPI_INIT_CMD_LEN; - spi_message_add_tail(&t, &m); - - spi_sync(wl_to_spi(wl), &m); - wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); - kfree(cmd); -} - -#define WL1271_BUSY_WORD_TIMEOUT 1000 - -static int wl1271_spi_read_busy(struct wl1271 *wl) -{ - struct spi_transfer t[1]; - struct spi_message m; - u32 *busy_buf; - int num_busy_bytes = 0; - - /* - * Read further busy words from SPI until a non-busy word is - * encountered, then read the data itself into the buffer. - */ - - num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; - busy_buf = wl->buffer_busyword; - while (num_busy_bytes) { - num_busy_bytes--; - spi_message_init(&m); - memset(t, 0, sizeof(t)); - t[0].rx_buf = busy_buf; - t[0].len = sizeof(u32); - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); - spi_sync(wl_to_spi(wl), &m); - - if (*busy_buf & 0x1) - return 0; - } - - /* The SPI bus is unresponsive, the read failed. */ - wl1271_error("SPI read busy-word timeout!\n"); - return -ETIMEDOUT; -} - -static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - struct spi_transfer t[2]; - struct spi_message m; - u32 *busy_buf; - u32 *cmd; - u32 chunk_len; - - while (len > 0) { - chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - - cmd = &wl->buffer_cmd; - busy_buf = wl->buffer_busyword; - - *cmd = 0; - *cmd |= WSPI_CMD_READ; - *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & - WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = 4; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); - - /* Busy and non busy words read */ - t[1].rx_buf = busy_buf; - t[1].len = WL1271_BUSY_WORD_LEN; - t[1].cs_change = true; - spi_message_add_tail(&t[1], &m); - - spi_sync(wl_to_spi(wl), &m); - - if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && - wl1271_spi_read_busy(wl)) { - memset(buf, 0, chunk_len); - return; - } - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].rx_buf = buf; - t[0].len = chunk_len; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); - - spi_sync(wl_to_spi(wl), &m); - - wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); - - if (!fixed) - addr += chunk_len; - buf += chunk_len; - len -= chunk_len; - } -} - -static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; - struct spi_message m; - u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; - u32 *cmd; - u32 chunk_len; - int i; - - WARN_ON(len > WL1271_AGGR_BUFFER_SIZE); - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - cmd = &commands[0]; - i = 0; - while (len > 0) { - chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - - *cmd = 0; - *cmd |= WSPI_CMD_WRITE; - *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & - WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; - - t[i].tx_buf = cmd; - t[i].len = sizeof(*cmd); - spi_message_add_tail(&t[i++], &m); - - t[i].tx_buf = buf; - t[i].len = chunk_len; - spi_message_add_tail(&t[i++], &m); - - wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len); - - if (!fixed) - addr += chunk_len; - buf += chunk_len; - len -= chunk_len; - cmd++; - } - - spi_sync(wl_to_spi(wl), &m); -} - -static irqreturn_t wl1271_irq(int irq, void *cookie) -{ - struct wl1271 *wl; - unsigned long flags; - - wl1271_debug(DEBUG_IRQ, "IRQ"); - - wl = cookie; - - /* complete the ELP completion */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (wl->elp_compl) { - complete(wl->elp_compl); - wl->elp_compl = NULL; - } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - return IRQ_HANDLED; -} - -static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) -{ - if (wl->set_power) - wl->set_power(enable); - - return 0; -} - -static struct wl1271_if_operations spi_ops = { - .read = wl1271_spi_raw_read, - .write = wl1271_spi_raw_write, - .reset = wl1271_spi_reset, - .init = wl1271_spi_init, - .power = wl1271_spi_set_power, - .dev = wl1271_spi_wl_to_dev, - .enable_irq = wl1271_spi_enable_interrupts, - .disable_irq = wl1271_spi_disable_interrupts -}; - -static int __devinit wl1271_probe(struct spi_device *spi) -{ - struct wl12xx_platform_data *pdata; - struct ieee80211_hw *hw; - struct wl1271 *wl; - int ret; - - pdata = spi->dev.platform_data; - if (!pdata) { - wl1271_error("no platform data"); - return -ENODEV; - } - - hw = wl1271_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - dev_set_drvdata(&spi->dev, wl); - wl->if_priv = spi; - - wl->if_ops = &spi_ops; - - /* This is the only SPI value that we need to set here, the rest - * comes from the board-peripherals file */ - spi->bits_per_word = 32; - - ret = spi_setup(spi); - if (ret < 0) { - wl1271_error("spi_setup failed"); - goto out_free; - } - - wl->set_power = pdata->set_power; - if (!wl->set_power) { - wl1271_error("set power function missing in platform data"); - ret = -ENODEV; - goto out_free; - } - - wl->ref_clock = pdata->board_ref_clock; - - wl->irq = spi->irq; - if (wl->irq < 0) { - wl1271_error("irq missing in platform data"); - ret = -ENODEV; - goto out_free; - } - - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); - if (ret < 0) { - wl1271_error("request_irq() failed: %d", ret); - goto out_free; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - - disable_irq(wl->irq); - - ret = wl1271_init_ieee80211(wl); - if (ret) - goto out_irq; - - ret = wl1271_register_hw(wl); - if (ret) - goto out_irq; - - wl1271_notice("initialized"); - - return 0; - - out_irq: - free_irq(wl->irq, wl); - - out_free: - wl1271_free_hw(wl); - - return ret; -} - -static int __devexit wl1271_remove(struct spi_device *spi) -{ - struct wl1271 *wl = dev_get_drvdata(&spi->dev); - - wl1271_unregister_hw(wl); - free_irq(wl->irq, wl); - wl1271_free_hw(wl); - - return 0; -} - - -static struct spi_driver wl1271_spi_driver = { - .driver = { - .name = "wl1271_spi", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = wl1271_probe, - .remove = __devexit_p(wl1271_remove), -}; - -static int __init wl1271_init(void) -{ - int ret; - - ret = spi_register_driver(&wl1271_spi_driver); - if (ret < 0) { - wl1271_error("failed to register spi driver: %d", ret); - goto out; - } - -out: - return ret; -} - -static void __exit wl1271_exit(void) -{ - spi_unregister_driver(&wl1271_spi_driver); - - wl1271_notice("unloaded"); -} - -module_init(wl1271_init); -module_exit(wl1271_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho "); -MODULE_AUTHOR("Juuso Oikarinen "); -MODULE_FIRMWARE(WL1271_FW_NAME); -MODULE_ALIAS("spi:wl1271"); diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c deleted file mode 100644 index 55ec4428922b..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ -#include "wl1271_testmode.h" - -#include -#include - -#include "wl1271.h" -#include "wl1271_acx.h" - -#define WL1271_TM_MAX_DATA_LENGTH 1024 - -enum wl1271_tm_commands { - WL1271_TM_CMD_UNSPEC, - WL1271_TM_CMD_TEST, - WL1271_TM_CMD_INTERROGATE, - WL1271_TM_CMD_CONFIGURE, - WL1271_TM_CMD_NVS_PUSH, - WL1271_TM_CMD_SET_PLT_MODE, - WL1271_TM_CMD_RECOVER, - - __WL1271_TM_CMD_AFTER_LAST -}; -#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1) - -enum wl1271_tm_attrs { - WL1271_TM_ATTR_UNSPEC, - WL1271_TM_ATTR_CMD_ID, - WL1271_TM_ATTR_ANSWER, - WL1271_TM_ATTR_DATA, - WL1271_TM_ATTR_IE_ID, - WL1271_TM_ATTR_PLT_MODE, - - __WL1271_TM_ATTR_AFTER_LAST -}; -#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1) - -static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = { - [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 }, - [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 }, - [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY, - .len = WL1271_TM_MAX_DATA_LENGTH }, - [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 }, - [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 }, -}; - - -static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) -{ - int buf_len, ret, len; - struct sk_buff *skb; - void *buf; - u8 answer = 0; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd test"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - if (tb[WL1271_TM_ATTR_ANSWER]) - answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]); - - if (buf_len > sizeof(struct wl1271_command)) - return -EMSGSIZE; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_test(wl, buf, buf_len, answer); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd test failed: %d", ret); - return ret; - } - - if (answer) { - len = nla_total_size(buf_len); - skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); - if (!skb) - return -ENOMEM; - - NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf); - ret = cfg80211_testmode_reply(skb); - if (ret < 0) - return ret; - } - - return 0; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; -} - -static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret; - struct wl1271_command *cmd; - struct sk_buff *skb; - u8 ie_id; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate"); - - if (!tb[WL1271_TM_ATTR_IE_ID]) - return -EINVAL; - - ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd interrogate failed: %d", ret); - return ret; - } - - skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); - - return 0; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; -} - -static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) -{ - int buf_len, ret; - void *buf; - u8 ie_id; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - if (!tb[WL1271_TM_ATTR_IE_ID]) - return -EINVAL; - - ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - if (buf_len > sizeof(struct wl1271_command)) - return -EMSGSIZE; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd configure failed: %d", ret); - return ret; - } - - return 0; -} - -static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret = 0; - size_t len; - void *buf; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - mutex_lock(&wl->mutex); - - kfree(wl->nvs); - - wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, buf, len); - wl->nvs_len = len; - - wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) -{ - u32 val; - int ret; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode"); - - if (!tb[WL1271_TM_ATTR_PLT_MODE]) - return -EINVAL; - - val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]); - - switch (val) { - case 0: - ret = wl1271_plt_stop(wl); - break; - case 1: - ret = wl1271_plt_start(wl); - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[]) -{ - wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover"); - - ieee80211_queue_work(wl->hw, &wl->recovery_work); - - return 0; -} - -int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) -{ - struct wl1271 *wl = hw->priv; - struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; - int err; - - err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy); - if (err) - return err; - - if (!tb[WL1271_TM_ATTR_CMD_ID]) - return -EINVAL; - - switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) { - case WL1271_TM_CMD_TEST: - return wl1271_tm_cmd_test(wl, tb); - case WL1271_TM_CMD_INTERROGATE: - return wl1271_tm_cmd_interrogate(wl, tb); - case WL1271_TM_CMD_CONFIGURE: - return wl1271_tm_cmd_configure(wl, tb); - case WL1271_TM_CMD_NVS_PUSH: - return wl1271_tm_cmd_nvs_push(wl, tb); - case WL1271_TM_CMD_SET_PLT_MODE: - return wl1271_tm_cmd_set_plt_mode(wl, tb); - case WL1271_TM_CMD_RECOVER: - return wl1271_tm_cmd_recover(wl, tb); - default: - return -EOPNOTSUPP; - } -} diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.h b/drivers/net/wireless/wl12xx/wl1271_testmode.h deleted file mode 100644 index c196d28f9d9d..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_TESTMODE_H__ -#define __WL1271_TESTMODE_H__ - -#include - -int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len); - -#endif /* __WL1271_TESTMODE_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c deleted file mode 100644 index 279be5b98d9f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include - -#include "wl1271.h" -#include "wl1271_io.h" -#include "wl1271_reg.h" -#include "wl1271_ps.h" -#include "wl1271_tx.h" - -static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) -{ - int id; - - id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS); - if (id >= ACX_TX_DESCRIPTORS) - return -EBUSY; - - __set_bit(id, wl->tx_frames_map); - wl->tx_frames[id] = skb; - wl->tx_frames_cnt++; - return id; -} - -static void wl1271_free_tx_id(struct wl1271 *wl, int id) -{ - if (__test_and_clear_bit(id, wl->tx_frames_map)) { - wl->tx_frames[id] = NULL; - wl->tx_frames_cnt--; - } -} - -static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, - u32 buf_offset) -{ - struct wl1271_tx_hw_descr *desc; - u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; - u32 total_blocks; - int id, ret = -EBUSY; - - if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) - return -EAGAIN; - - /* allocate free identifier for the packet */ - id = wl1271_alloc_tx_id(wl, skb); - if (id < 0) - return id; - - /* approximate the number of blocks required for this packet - in the firmware */ - total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; - total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; - if (total_blocks <= wl->tx_blocks_available) { - desc = (struct wl1271_tx_hw_descr *)skb_push( - skb, total_len - skb->len); - - desc->extra_mem_blocks = TX_HW_BLOCK_SPARE; - desc->total_mem_blocks = total_blocks; - desc->id = id; - - wl->tx_blocks_available -= total_blocks; - - ret = 0; - - wl1271_debug(DEBUG_TX, - "tx_allocate: size: %d, blocks: %d, id: %d", - total_len, total_blocks, id); - } else { - wl1271_free_tx_id(wl, id); - } - - return ret; -} - -static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, - u32 extra, struct ieee80211_tx_info *control) -{ - struct timespec ts; - struct wl1271_tx_hw_descr *desc; - int pad, ac; - s64 hosttime; - u16 tx_attr; - - desc = (struct wl1271_tx_hw_descr *) skb->data; - - /* relocate space for security header */ - if (extra) { - void *framestart = skb->data + sizeof(*desc); - u16 fc = *(u16 *)(framestart + extra); - int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc)); - memmove(framestart, framestart + extra, hdrlen); - } - - /* configure packet life time */ - getnstimeofday(&ts); - hosttime = (timespec_to_ns(&ts) >> 10); - desc->start_time = cpu_to_le32(hosttime - wl->time_offset); - desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); - - /* configure the tx attributes */ - tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; - - /* queue (we use same identifiers for tid's and ac's */ - ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - desc->tid = ac; - - desc->aid = TX_HW_DEFAULT_AID; - desc->reserved = 0; - - /* align the length (and store in terms of words) */ - pad = WL1271_TX_ALIGN(skb->len); - desc->length = cpu_to_le16(pad >> 2); - - /* calculate number of padding bytes */ - pad = pad - skb->len; - tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; - - /* if the packets are destined for AP (have a STA entry) send them - with AP rate policies, otherwise use default basic rates */ - if (control->control.sta) - tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY; - - desc->tx_attr = cpu_to_le16(tx_attr); - - wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); -} - -/* caller must hold wl->mutex */ -static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, - u32 buf_offset) -{ - struct ieee80211_tx_info *info; - u32 extra = 0; - int ret = 0; - u8 idx; - u32 total_len; - - if (!skb) - return -EINVAL; - - info = IEEE80211_SKB_CB(skb); - - if (info->control.hw_key && - info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) - extra = WL1271_TKIP_IV_SPACE; - - if (info->control.hw_key) { - idx = info->control.hw_key->hw_key_idx; - - /* FIXME: do we have to do this if we're not using WEP? */ - if (unlikely(wl->default_key != idx)) { - ret = wl1271_cmd_set_default_wep_key(wl, idx); - if (ret < 0) - return ret; - wl->default_key = idx; - } - } - - ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); - if (ret < 0) - return ret; - - wl1271_tx_fill_hdr(wl, skb, extra, info); - - /* - * The length of each packet is stored in terms of words. Thus, we must - * pad the skb data to make sure its length is aligned. - * The number of padding bytes is computed and set in wl1271_tx_fill_hdr - */ - total_len = WL1271_TX_ALIGN(skb->len); - memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); - memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); - - return total_len; -} - -u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) -{ - struct ieee80211_supported_band *band; - u32 enabled_rates = 0; - int bit; - - band = wl->hw->wiphy->bands[wl->band]; - for (bit = 0; bit < band->n_bitrates; bit++) { - if (rate_set & 0x1) - enabled_rates |= band->bitrates[bit].hw_value; - rate_set >>= 1; - } - -#ifdef CONFIG_WL1271_HT - /* MCS rates indication are on bits 16 - 23 */ - rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; - - for (bit = 0; bit < 8; bit++) { - if (rate_set & 0x1) - enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); - rate_set >>= 1; - } -#endif - - return enabled_rates; -} - -static void handle_tx_low_watermark(struct wl1271 *wl) -{ - unsigned long flags; - - if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { - /* firmware buffer has space, restart queues */ - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - } -} - -void wl1271_tx_work_locked(struct wl1271 *wl) -{ - struct sk_buff *skb; - bool woken_up = false; - u32 sta_rates = 0; - u32 buf_offset = 0; - bool sent_packets = false; - int ret; - - /* check if the rates supported by the AP have changed */ - if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, - &wl->flags))) { - unsigned long flags; - - spin_lock_irqsave(&wl->wl_lock, flags); - sta_rates = wl->sta_rate_set; - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - /* if rates have changed, re-configure the rate policy */ - if (unlikely(sta_rates)) { - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - woken_up = true; - - wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); - wl1271_acx_rate_policies(wl); - } - - while ((skb = skb_dequeue(&wl->tx_queue))) { - if (!woken_up) { - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out_ack; - woken_up = true; - } - - ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); - if (ret == -EAGAIN) { - /* - * Aggregation buffer is full. - * Flush buffer and try again. - */ - skb_queue_head(&wl->tx_queue, skb); - wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); - sent_packets = true; - buf_offset = 0; - continue; - } else if (ret == -EBUSY) { - /* - * Firmware buffer is full. - * Queue back last skb, and stop aggregating. - */ - skb_queue_head(&wl->tx_queue, skb); - /* No work left, avoid scheduling redundant tx work */ - set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); - goto out_ack; - } else if (ret < 0) { - dev_kfree_skb(skb); - goto out_ack; - } - buf_offset += ret; - wl->tx_packets_count++; - } - -out_ack: - if (buf_offset) { - wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); - sent_packets = true; - } - if (sent_packets) { - /* interrupt the firmware with the new packets */ - wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); - handle_tx_low_watermark(wl); - } - -out: - if (woken_up) - wl1271_ps_elp_sleep(wl); -} - -void wl1271_tx_work(struct work_struct *work) -{ - struct wl1271 *wl = container_of(work, struct wl1271, tx_work); - - mutex_lock(&wl->mutex); - wl1271_tx_work_locked(wl); - mutex_unlock(&wl->mutex); -} - -static void wl1271_tx_complete_packet(struct wl1271 *wl, - struct wl1271_tx_hw_res_descr *result) -{ - struct ieee80211_tx_info *info; - struct sk_buff *skb; - int id = result->id; - int rate = -1; - u8 retries = 0; - - /* check for id legality */ - if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { - wl1271_warning("TX result illegal id: %d", id); - return; - } - - skb = wl->tx_frames[id]; - info = IEEE80211_SKB_CB(skb); - - /* update the TX status info */ - if (result->status == TX_SUCCESS) { - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - info->flags |= IEEE80211_TX_STAT_ACK; - rate = wl1271_rate_to_idx(result->rate_class_index, wl->band); - retries = result->ack_failures; - } else if (result->status == TX_RETRY_EXCEEDED) { - wl->stats.excessive_retries++; - retries = result->ack_failures; - } - - info->status.rates[0].idx = rate; - info->status.rates[0].count = retries; - info->status.rates[0].flags = 0; - info->status.ack_signal = -1; - - wl->stats.retry_count += result->ack_failures; - - /* update security sequence number */ - wl->tx_security_seq += (result->lsb_security_sequence_number - - wl->tx_security_last_seq); - wl->tx_security_last_seq = result->lsb_security_sequence_number; - - /* remove private header from packet */ - skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); - - /* remove TKIP header space if present */ - if (info->control.hw_key && - info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { - int hdrlen = ieee80211_get_hdrlen_from_skb(skb); - memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); - skb_pull(skb, WL1271_TKIP_IV_SPACE); - } - - wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" - " status 0x%x", - result->id, skb, result->ack_failures, - result->rate_class_index, result->status); - - /* return the packet to the stack */ - ieee80211_tx_status(wl->hw, skb); - wl1271_free_tx_id(wl, result->id); -} - -/* Called upon reception of a TX complete interrupt */ -void wl1271_tx_complete(struct wl1271 *wl) -{ - struct wl1271_acx_mem_map *memmap = - (struct wl1271_acx_mem_map *)wl->target_mem_map; - u32 count, fw_counter; - u32 i; - - /* read the tx results from the chipset */ - wl1271_read(wl, le32_to_cpu(memmap->tx_result), - wl->tx_res_if, sizeof(*wl->tx_res_if), false); - fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); - - /* write host counter to chipset (to ack) */ - wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + - offsetof(struct wl1271_tx_hw_res_if, - tx_result_host_counter), fw_counter); - - count = fw_counter - wl->tx_results_count; - wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); - - /* verify that the result buffer is not getting overrun */ - if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) - wl1271_warning("TX result overflow from chipset: %d", count); - - /* process the results */ - for (i = 0; i < count; i++) { - struct wl1271_tx_hw_res_descr *result; - u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK; - - /* process the packet */ - result = &(wl->tx_res_if->tx_results_queue[offset]); - wl1271_tx_complete_packet(wl, result); - - wl->tx_results_count++; - } -} - -/* caller must hold wl->mutex */ -void wl1271_tx_reset(struct wl1271 *wl) -{ - int i; - struct sk_buff *skb; - - /* TX failure */ - while ((skb = skb_dequeue(&wl->tx_queue))) { - wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); - ieee80211_tx_status(wl->hw, skb); - } - - /* - * Make sure the driver is at a consistent state, in case this - * function is called from a context other than interface removal. - */ - handle_tx_low_watermark(wl); - - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - if (wl->tx_frames[i] != NULL) { - skb = wl->tx_frames[i]; - wl1271_free_tx_id(wl, i); - wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); - ieee80211_tx_status(wl->hw, skb); - } -} - -#define WL1271_TX_FLUSH_TIMEOUT 500000 - -/* caller must *NOT* hold wl->mutex */ -void wl1271_tx_flush(struct wl1271 *wl) -{ - unsigned long timeout; - timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); - - while (!time_after(jiffies, timeout)) { - mutex_lock(&wl->mutex); - wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", - wl->tx_frames_cnt); - if ((wl->tx_frames_cnt == 0) && - skb_queue_empty(&wl->tx_queue)) { - mutex_unlock(&wl->mutex); - return; - } - mutex_unlock(&wl->mutex); - msleep(1); - } - - wl1271_warning("Unable to flush all TX buffers, timed out."); -} diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h deleted file mode 100644 index 9dc6f228c0de..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1271_TX_H__ -#define __WL1271_TX_H__ - -#define TX_HW_BLOCK_SPARE 2 -#define TX_HW_BLOCK_SIZE 252 - -#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 -/* The chipset reference driver states, that the "aid" value 1 - * is for infra-BSS, but is still always used */ -#define TX_HW_DEFAULT_AID 1 - -#define TX_HW_ATTR_SAVE_RETRIES BIT(0) -#define TX_HW_ATTR_HEADER_PAD BIT(1) -#define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4)) -#define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \ - BIT(8) | BIT(9)) -#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) -#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) - -#define TX_HW_ATTR_OFST_SAVE_RETRIES 0 -#define TX_HW_ATTR_OFST_HEADER_PAD 1 -#define TX_HW_ATTR_OFST_SESSION_COUNTER 2 -#define TX_HW_ATTR_OFST_RATE_POLICY 5 -#define TX_HW_ATTR_OFST_LAST_WORD_PAD 10 -#define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12 - -#define TX_HW_RESULT_QUEUE_LEN 16 -#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf - -#define WL1271_TX_ALIGN_TO 4 -#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \ - ~(WL1271_TX_ALIGN_TO - 1)) -#define WL1271_TKIP_IV_SPACE 4 - -struct wl1271_tx_hw_descr { - /* Length of packet in words, including descriptor+header+data */ - __le16 length; - /* Number of extra memory blocks to allocate for this packet in - addition to the number of blocks derived from the packet length */ - u8 extra_mem_blocks; - /* Total number of memory blocks allocated by the host for this packet. - Must be equal or greater than the actual blocks number allocated by - HW!! */ - u8 total_mem_blocks; - /* Device time (in us) when the packet arrived to the driver */ - __le32 start_time; - /* Max delay in TUs until transmission. The last device time the - packet can be transmitted is: startTime+(1024*LifeTime) */ - __le16 life_time; - /* Bitwise fields - see TX_ATTR... definitions above. */ - __le16 tx_attr; - /* Packet identifier used also in the Tx-Result. */ - u8 id; - /* The packet TID value (as User-Priority) */ - u8 tid; - /* Identifier of the remote STA in IBSS, 1 in infra-BSS */ - u8 aid; - u8 reserved; -} __packed; - -enum wl1271_tx_hw_res_status { - TX_SUCCESS = 0, - TX_HW_ERROR = 1, - TX_DISABLED = 2, - TX_RETRY_EXCEEDED = 3, - TX_TIMEOUT = 4, - TX_KEY_NOT_FOUND = 5, - TX_PEER_NOT_FOUND = 6, - TX_SESSION_MISMATCH = 7 -}; - -struct wl1271_tx_hw_res_descr { - /* Packet Identifier - same value used in the Tx descriptor.*/ - u8 id; - /* The status of the transmission, indicating success or one of - several possible reasons for failure. */ - u8 status; - /* Total air access duration including all retrys and overheads.*/ - __le16 medium_usage; - /* The time passed from host xfer to Tx-complete.*/ - __le32 fw_handling_time; - /* Total media delay - (from 1st EDCA AIFS counter until TX Complete). */ - __le32 medium_delay; - /* LS-byte of last TKIP seq-num (saved per AC for recovery). */ - u8 lsb_security_sequence_number; - /* Retry count - number of transmissions without successful ACK.*/ - u8 ack_failures; - /* The rate that succeeded getting ACK - (Valid only if status=SUCCESS). */ - u8 rate_class_index; - /* for 4-byte alignment. */ - u8 spare; -} __packed; - -struct wl1271_tx_hw_res_if { - __le32 tx_result_fw_counter; - __le32 tx_result_host_counter; - struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; -} __packed; - -static inline int wl1271_tx_get_queue(int queue) -{ - switch (queue) { - case 0: - return CONF_TX_AC_VO; - case 1: - return CONF_TX_AC_VI; - case 2: - return CONF_TX_AC_BE; - case 3: - return CONF_TX_AC_BK; - default: - return CONF_TX_AC_BE; - } -} - -void wl1271_tx_work(struct work_struct *work); -void wl1271_tx_work_locked(struct wl1271 *wl); -void wl1271_tx_complete(struct wl1271 *wl); -void wl1271_tx_reset(struct wl1271 *wl); -void wl1271_tx_flush(struct wl1271 *wl); -u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); -u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h new file mode 100644 index 000000000000..3c836e6063e6 --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -0,0 +1,523 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. + * Copyright (C) 2008-2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL12XX_H__ +#define __WL12XX_H__ + +#include +#include +#include +#include +#include +#include + +#include "conf.h" +#include "ini.h" + +#define DRIVER_NAME "wl1271" +#define DRIVER_PREFIX DRIVER_NAME ": " + +enum { + DEBUG_NONE = 0, + DEBUG_IRQ = BIT(0), + DEBUG_SPI = BIT(1), + DEBUG_BOOT = BIT(2), + DEBUG_MAILBOX = BIT(3), + DEBUG_TESTMODE = BIT(4), + DEBUG_EVENT = BIT(5), + DEBUG_TX = BIT(6), + DEBUG_RX = BIT(7), + DEBUG_SCAN = BIT(8), + DEBUG_CRYPT = BIT(9), + DEBUG_PSM = BIT(10), + DEBUG_MAC80211 = BIT(11), + DEBUG_CMD = BIT(12), + DEBUG_ACX = BIT(13), + DEBUG_SDIO = BIT(14), + DEBUG_FILTERS = BIT(15), + DEBUG_ADHOC = BIT(16), + DEBUG_ALL = ~0, +}; + +#define DEBUG_LEVEL (DEBUG_NONE) + +#define DEBUG_DUMP_LIMIT 1024 + +#define wl1271_error(fmt, arg...) \ + printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) + +#define wl1271_warning(fmt, arg...) \ + printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) + +#define wl1271_notice(fmt, arg...) \ + printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) + +#define wl1271_info(fmt, arg...) \ + printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) + +#define wl1271_debug(level, fmt, arg...) \ + do { \ + if (level & DEBUG_LEVEL) \ + printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ + } while (0) + +#define wl1271_dump(level, prefix, buf, len) \ + do { \ + if (level & DEBUG_LEVEL) \ + print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ + DUMP_PREFIX_OFFSET, 16, 1, \ + buf, \ + min_t(size_t, len, DEBUG_DUMP_LIMIT), \ + 0); \ + } while (0) + +#define wl1271_dump_ascii(level, prefix, buf, len) \ + do { \ + if (level & DEBUG_LEVEL) \ + print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ + DUMP_PREFIX_OFFSET, 16, 1, \ + buf, \ + min_t(size_t, len, DEBUG_DUMP_LIMIT), \ + true); \ + } while (0) + +#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ + CFG_BSSID_FILTER_EN | \ + CFG_MC_FILTER_EN) + +#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \ + CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \ + CFG_RX_CTL_EN | CFG_RX_BCN_EN | \ + CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) + +#define WL1271_FW_NAME "wl1271-fw.bin" +#define WL1271_NVS_NAME "wl1271-nvs.bin" + +#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) +#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) + +#define WL1271_CIPHER_SUITE_GEM 0x00147201 + +#define WL1271_BUSY_WORD_CNT 1 +#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) + +#define WL1271_ELP_HW_STATE_ASLEEP 0 +#define WL1271_ELP_HW_STATE_IRQ 1 + +#define WL1271_DEFAULT_BEACON_INT 100 +#define WL1271_DEFAULT_DTIM_PERIOD 1 + +#define ACX_TX_DESCRIPTORS 32 + +#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) + +enum wl1271_state { + WL1271_STATE_OFF, + WL1271_STATE_ON, + WL1271_STATE_PLT, +}; + +enum wl1271_partition_type { + PART_DOWN, + PART_WORK, + PART_DRPW, + + PART_TABLE_LEN +}; + +struct wl1271_partition { + u32 size; + u32 start; +}; + +struct wl1271_partition_set { + struct wl1271_partition mem; + struct wl1271_partition reg; + struct wl1271_partition mem2; + struct wl1271_partition mem3; +}; + +struct wl1271; + +/* FIXME: I'm not sure about this structure name */ +struct wl1271_chip { + u32 id; + char fw_ver[21]; +}; + +struct wl1271_stats { + struct acx_statistics *fw_stats; + unsigned long fw_stats_update; + + unsigned int retry_count; + unsigned int excessive_retries; +}; + +struct wl1271_debugfs { + struct dentry *rootdir; + struct dentry *fw_statistics; + + struct dentry *tx_internal_desc_overflow; + + struct dentry *rx_out_of_mem; + struct dentry *rx_hdr_overflow; + struct dentry *rx_hw_stuck; + struct dentry *rx_dropped; + struct dentry *rx_fcs_err; + struct dentry *rx_xfr_hint_trig; + struct dentry *rx_path_reset; + struct dentry *rx_reset_counter; + + struct dentry *dma_rx_requested; + struct dentry *dma_rx_errors; + struct dentry *dma_tx_requested; + struct dentry *dma_tx_errors; + + struct dentry *isr_cmd_cmplt; + struct dentry *isr_fiqs; + struct dentry *isr_rx_headers; + struct dentry *isr_rx_mem_overflow; + struct dentry *isr_rx_rdys; + struct dentry *isr_irqs; + struct dentry *isr_tx_procs; + struct dentry *isr_decrypt_done; + struct dentry *isr_dma0_done; + struct dentry *isr_dma1_done; + struct dentry *isr_tx_exch_complete; + struct dentry *isr_commands; + struct dentry *isr_rx_procs; + struct dentry *isr_hw_pm_mode_changes; + struct dentry *isr_host_acknowledges; + struct dentry *isr_pci_pm; + struct dentry *isr_wakeups; + struct dentry *isr_low_rssi; + + struct dentry *wep_addr_key_count; + struct dentry *wep_default_key_count; + /* skipping wep.reserved */ + struct dentry *wep_key_not_found; + struct dentry *wep_decrypt_fail; + struct dentry *wep_packets; + struct dentry *wep_interrupt; + + struct dentry *pwr_ps_enter; + struct dentry *pwr_elp_enter; + struct dentry *pwr_missing_bcns; + struct dentry *pwr_wake_on_host; + struct dentry *pwr_wake_on_timer_exp; + struct dentry *pwr_tx_with_ps; + struct dentry *pwr_tx_without_ps; + struct dentry *pwr_rcvd_beacons; + struct dentry *pwr_power_save_off; + struct dentry *pwr_enable_ps; + struct dentry *pwr_disable_ps; + struct dentry *pwr_fix_tsf_ps; + /* skipping cont_miss_bcns_spread for now */ + struct dentry *pwr_rcvd_awake_beacons; + + struct dentry *mic_rx_pkts; + struct dentry *mic_calc_failure; + + struct dentry *aes_encrypt_fail; + struct dentry *aes_decrypt_fail; + struct dentry *aes_encrypt_packets; + struct dentry *aes_decrypt_packets; + struct dentry *aes_encrypt_interrupt; + struct dentry *aes_decrypt_interrupt; + + struct dentry *event_heart_beat; + struct dentry *event_calibration; + struct dentry *event_rx_mismatch; + struct dentry *event_rx_mem_empty; + struct dentry *event_rx_pool; + struct dentry *event_oom_late; + struct dentry *event_phy_transmit_error; + struct dentry *event_tx_stuck; + + struct dentry *ps_pspoll_timeouts; + struct dentry *ps_upsd_timeouts; + struct dentry *ps_upsd_max_sptime; + struct dentry *ps_upsd_max_apturn; + struct dentry *ps_pspoll_max_apturn; + struct dentry *ps_pspoll_utilization; + struct dentry *ps_upsd_utilization; + + struct dentry *rxpipe_rx_prep_beacon_drop; + struct dentry *rxpipe_descr_host_int_trig_rx_data; + struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data; + struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data; + struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; + + struct dentry *tx_queue_len; + + struct dentry *retry_count; + struct dentry *excessive_retries; + struct dentry *gpio_power; +}; + +#define NUM_TX_QUEUES 4 +#define NUM_RX_PKT_DESC 8 + +/* FW status registers */ +struct wl1271_fw_status { + __le32 intr; + u8 fw_rx_counter; + u8 drv_rx_counter; + u8 reserved; + u8 tx_results_counter; + __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; + __le32 tx_released_blks[NUM_TX_QUEUES]; + __le32 fw_localtime; + __le32 padding[2]; +} __packed; + +struct wl1271_rx_mem_pool_addr { + u32 addr; + u32 addr_extra; +}; + +struct wl1271_scan { + struct cfg80211_scan_request *req; + bool *scanned_ch; + bool failed; + u8 state; + u8 ssid[IW_ESSID_MAX_SIZE+1]; + size_t ssid_len; +}; + +struct wl1271_if_operations { + void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len, + bool fixed); + void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len, + bool fixed); + void (*reset)(struct wl1271 *wl); + void (*init)(struct wl1271 *wl); + int (*power)(struct wl1271 *wl, bool enable); + struct device* (*dev)(struct wl1271 *wl); + void (*enable_irq)(struct wl1271 *wl); + void (*disable_irq)(struct wl1271 *wl); +}; + +struct wl1271 { + struct platform_device *plat_dev; + struct ieee80211_hw *hw; + bool mac80211_registered; + + void *if_priv; + + struct wl1271_if_operations *if_ops; + + void (*set_power)(bool enable); + int irq; + int ref_clock; + + spinlock_t wl_lock; + + enum wl1271_state state; + struct mutex mutex; + +#define WL1271_FLAG_STA_RATES_CHANGED (0) +#define WL1271_FLAG_STA_ASSOCIATED (1) +#define WL1271_FLAG_JOINED (2) +#define WL1271_FLAG_GPIO_POWER (3) +#define WL1271_FLAG_TX_QUEUE_STOPPED (4) +#define WL1271_FLAG_IN_ELP (5) +#define WL1271_FLAG_PSM (6) +#define WL1271_FLAG_PSM_REQUESTED (7) +#define WL1271_FLAG_IRQ_PENDING (8) +#define WL1271_FLAG_IRQ_RUNNING (9) +#define WL1271_FLAG_IDLE (10) +#define WL1271_FLAG_IDLE_REQUESTED (11) +#define WL1271_FLAG_PSPOLL_FAILURE (12) +#define WL1271_FLAG_STA_STATE_SENT (13) +#define WL1271_FLAG_FW_TX_BUSY (14) + unsigned long flags; + + struct wl1271_partition_set part; + + struct wl1271_chip chip; + + int cmd_box_addr; + int event_box_addr; + + u8 *fw; + size_t fw_len; + struct wl1271_nvs_file *nvs; + size_t nvs_len; + + s8 hw_pg_ver; + + u8 bssid[ETH_ALEN]; + u8 mac_addr[ETH_ALEN]; + u8 bss_type; + u8 set_bss_type; + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + int channel; + + struct wl1271_acx_mem_map *target_mem_map; + + /* Accounting for allocated / available TX blocks on HW */ + u32 tx_blocks_freed[NUM_TX_QUEUES]; + u32 tx_blocks_available; + u32 tx_results_count; + + /* Transmitted TX packets counter for chipset interface */ + u32 tx_packets_count; + + /* Time-offset between host and chipset clocks */ + s64 time_offset; + + /* Session counter for the chipset */ + int session_counter; + + /* Frames scheduled for transmission, not handled yet */ + struct sk_buff_head tx_queue; + + struct work_struct tx_work; + + /* Pending TX frames */ + unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)]; + struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; + int tx_frames_cnt; + + /* Security sequence number counters */ + u8 tx_security_last_seq; + s64 tx_security_seq; + + /* FW Rx counter */ + u32 rx_counter; + + /* Rx memory pool address */ + struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; + + /* Intermediate buffer, used for packet aggregation */ + u8 *aggr_buf; + + /* The target interrupt mask */ + struct work_struct irq_work; + + /* Hardware recovery work */ + struct work_struct recovery_work; + + /* The mbox event mask */ + u32 event_mask; + + /* Mailbox pointers */ + u32 mbox_ptr[2]; + + /* Are we currently scanning */ + struct wl1271_scan scan; + struct delayed_work scan_complete_work; + + /* Our association ID */ + u16 aid; + + /* + * currently configured rate set: + * bits 0-15 - 802.11abg rates + * bits 16-23 - 802.11n MCS index mask + * support only 1 stream, thus only 8 bits for the MCS rates (0-7). + */ + u32 sta_rate_set; + u32 basic_rate_set; + u32 basic_rate; + u32 rate_set; + + /* The current band */ + enum ieee80211_band band; + + /* Beaconing interval (needed for ad-hoc) */ + u32 beacon_int; + + /* Default key (for WEP) */ + u32 default_key; + + unsigned int filters; + unsigned int rx_config; + unsigned int rx_filter; + + struct completion *elp_compl; + struct delayed_work elp_work; + struct delayed_work pspoll_work; + + /* counter for ps-poll delivery failures */ + int ps_poll_failures; + + /* retry counter for PSM entries */ + u8 psm_entry_retry; + + /* in dBm */ + int power_level; + + int rssi_thold; + int last_rssi_event; + + struct wl1271_stats stats; + struct wl1271_debugfs debugfs; + + __le32 buffer_32; + u32 buffer_cmd; + u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; + + struct wl1271_fw_status *fw_status; + struct wl1271_tx_hw_res_if *tx_res_if; + + struct ieee80211_vif *vif; + + /* Current chipset configuration */ + struct conf_drv_settings conf; + + bool sg_enabled; + + bool enable_11a; + + struct list_head list; + + /* Most recently reported noise in dBm */ + s8 noise; +}; + +int wl1271_plt_start(struct wl1271 *wl); +int wl1271_plt_stop(struct wl1271 *wl); + +#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ + +#define SESSION_COUNTER_MAX 7 /* maximum value for the session counter */ + +#define WL1271_DEFAULT_POWER_LEVEL 0 + +#define WL1271_TX_QUEUE_LOW_WATERMARK 10 +#define WL1271_TX_QUEUE_HIGH_WATERMARK 25 + +/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power + on in case is has been shut down shortly before */ +#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ +#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ + +/* Macros to handle wl1271.sta_rate_set */ +#define HW_BG_RATES_MASK 0xffff +#define HW_HT_RATES_OFFSET 16 + +#endif -- cgit v1.2.3-59-g8ed1b From 91433029e42e58d8536299f32fa55cf589adff35 Mon Sep 17 00:00:00 2001 From: Gery Kahn Date: Sun, 7 Nov 2010 10:04:20 +0100 Subject: wl1271: cleanup unused code of calibration structures The cleanup unused code for calibration procedures. Signed-off-by: Gery Kahn Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.h | 48 --------------------------------------- 1 file changed, 48 deletions(-) diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 893dbf72c2d9..16d1bf814e76 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -327,9 +327,6 @@ enum wl1271_channel_tune_bands { #define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 -#define TEST_CMD_P2G_CAL 0x02 -#define TEST_CMD_CHANNEL_TUNE 0x0d -#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d #define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 #define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E #define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26 @@ -375,51 +372,6 @@ struct wl1271_ext_radio_parms_cmd { u8 padding[3]; } __packed; -struct wl1271_cmd_cal_channel_tune { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 band; - u8 channel; - - __le16 radio_status; -} __packed; - -struct wl1271_cmd_cal_update_ref_point { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le32 ref_power; - __le32 ref_detector; - u8 sub_band; - u8 padding[3]; -} __packed; - -#define MAX_TLV_LENGTH 400 -#define MAX_NVS_VERSION_LENGTH 12 - -#define WL1271_CAL_P2G_BAND_B_G BIT(0) - -struct wl1271_cmd_cal_p2g { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le16 len; - u8 buf[MAX_TLV_LENGTH]; - u8 type; - u8 padding; - - __le16 radio_status; - u8 nvs_version[MAX_NVS_VERSION_LENGTH]; - - u8 sub_band_mask; - u8 padding2; -} __packed; - - /* * There are three types of disconnections: * -- cgit v1.2.3-59-g8ed1b From b7417d930afdc214daa24299912d984e7f4f390a Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 10 Nov 2010 11:27:19 +0100 Subject: wl1271: Prevent ad-hoc and active scanning on 11a DFS frequencies The wl1271 does not support radar detection. Hence, prevent ad-hoc and active scanning on frequencies requiring DFS. Signed-off-by: Juuso Oikarinen Tested-by: Tuomas Katila Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index c00523008be4..07243282e50a 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -335,6 +335,27 @@ out: return NOTIFY_OK; } +static int wl1271_reg_notify(struct wiphy *wiphy, + struct regulatory_request *request) { + struct ieee80211_supported_band *band; + struct ieee80211_channel *ch; + int i; + + band = wiphy->bands[IEEE80211_BAND_5GHZ]; + for (i = 0; i < band->n_channels; i++) { + ch = &band->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (ch->flags & IEEE80211_CHAN_RADAR) + ch->flags |= IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + + } + + return 0; +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -2590,6 +2611,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->queues = 4; wl->hw->max_rates = 1; + wl->hw->wiphy->reg_notifier = wl1271_reg_notify; + SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); return 0; -- cgit v1.2.3-59-g8ed1b From fa97f46b30357a50f3ee193e6f82864f95bc55ec Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 10 Nov 2010 11:27:20 +0100 Subject: Revert "wl1271: Change supported channel order for a more optimal scan" This reverts commit fa21c7a9e4be439e217fe72edbd39b643b643791. The reverted patch caused more harm than benefit. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Tested-by: Tuomas Katila Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 86 ++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 07243282e50a..6af270d382bb 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2215,24 +2215,21 @@ static struct ieee80211_rate wl1271_rates[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* - * Can't be const, mac80211 writes to this. The order of the channels here - * is designed to improve scanning. - */ +/* can't be const, mac80211 writes to this */ static struct ieee80211_channel wl1271_channels[] = { { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, - { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, - { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, - { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, - { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, - { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, - { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, - { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, - { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, - { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, + { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, + { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, + { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, + { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, + { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, + { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, + { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, + { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, + { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, }; /* mapping to indexes for wl1271_rates */ @@ -2323,52 +2320,49 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* - * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this. - * The order of the channels here is designed to improve scanning. - */ +/* 5 GHz band channels for WL1273 */ static struct ieee80211_channel wl1271_channels_5ghz[] = { { .hw_value = 183, .center_freq = 4915}, - { .hw_value = 188, .center_freq = 4940}, - { .hw_value = 8, .center_freq = 5040}, - { .hw_value = 34, .center_freq = 5170}, - { .hw_value = 44, .center_freq = 5220}, - { .hw_value = 60, .center_freq = 5300}, - { .hw_value = 112, .center_freq = 5560}, - { .hw_value = 132, .center_freq = 5660}, - { .hw_value = 157, .center_freq = 5785}, { .hw_value = 184, .center_freq = 4920}, + { .hw_value = 185, .center_freq = 4925}, + { .hw_value = 187, .center_freq = 4935}, + { .hw_value = 188, .center_freq = 4940}, { .hw_value = 189, .center_freq = 4945}, - { .hw_value = 9, .center_freq = 5045}, - { .hw_value = 36, .center_freq = 5180}, - { .hw_value = 46, .center_freq = 5230}, - { .hw_value = 64, .center_freq = 5320}, - { .hw_value = 116, .center_freq = 5580}, - { .hw_value = 136, .center_freq = 5680}, { .hw_value = 192, .center_freq = 4960}, - { .hw_value = 11, .center_freq = 5055}, - { .hw_value = 38, .center_freq = 5190}, - { .hw_value = 48, .center_freq = 5240}, - { .hw_value = 100, .center_freq = 5500}, - { .hw_value = 120, .center_freq = 5600}, - { .hw_value = 140, .center_freq = 5700}, - { .hw_value = 185, .center_freq = 4925}, { .hw_value = 196, .center_freq = 4980}, - { .hw_value = 12, .center_freq = 5060}, - { .hw_value = 40, .center_freq = 5200}, - { .hw_value = 52, .center_freq = 5260}, - { .hw_value = 104, .center_freq = 5520}, - { .hw_value = 124, .center_freq = 5620}, - { .hw_value = 149, .center_freq = 5745}, - { .hw_value = 161, .center_freq = 5805}, - { .hw_value = 187, .center_freq = 4935}, { .hw_value = 7, .center_freq = 5035}, + { .hw_value = 8, .center_freq = 5040}, + { .hw_value = 9, .center_freq = 5045}, + { .hw_value = 11, .center_freq = 5055}, + { .hw_value = 12, .center_freq = 5060}, { .hw_value = 16, .center_freq = 5080}, + { .hw_value = 34, .center_freq = 5170}, + { .hw_value = 36, .center_freq = 5180}, + { .hw_value = 38, .center_freq = 5190}, + { .hw_value = 40, .center_freq = 5200}, { .hw_value = 42, .center_freq = 5210}, + { .hw_value = 44, .center_freq = 5220}, + { .hw_value = 46, .center_freq = 5230}, + { .hw_value = 48, .center_freq = 5240}, + { .hw_value = 52, .center_freq = 5260}, { .hw_value = 56, .center_freq = 5280}, + { .hw_value = 60, .center_freq = 5300}, + { .hw_value = 64, .center_freq = 5320}, + { .hw_value = 100, .center_freq = 5500}, + { .hw_value = 104, .center_freq = 5520}, { .hw_value = 108, .center_freq = 5540}, + { .hw_value = 112, .center_freq = 5560}, + { .hw_value = 116, .center_freq = 5580}, + { .hw_value = 120, .center_freq = 5600}, + { .hw_value = 124, .center_freq = 5620}, { .hw_value = 128, .center_freq = 5640}, + { .hw_value = 132, .center_freq = 5660}, + { .hw_value = 136, .center_freq = 5680}, + { .hw_value = 140, .center_freq = 5700}, + { .hw_value = 149, .center_freq = 5745}, { .hw_value = 153, .center_freq = 5765}, + { .hw_value = 157, .center_freq = 5785}, + { .hw_value = 161, .center_freq = 5805}, { .hw_value = 165, .center_freq = 5825}, }; -- cgit v1.2.3-59-g8ed1b From 68d069c45f73e8aeda0249891daec1f7e2f0e067 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 8 Nov 2010 10:51:07 +0100 Subject: wl1271: add support for HW TX fragmentation Indicate to mac80211 we support HW fragmentation. Support updates of the fragmentation threshold via the set_frag_threshold callback. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 4 ++-- drivers/net/wireless/wl12xx/acx.h | 2 +- drivers/net/wireless/wl12xx/init.c | 2 +- drivers/net/wireless/wl12xx/main.c | 31 ++++++++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index bc1085bb6cfb..7cbaeb6d2a37 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -862,7 +862,7 @@ out: return ret; } -int wl1271_acx_frag_threshold(struct wl1271 *wl) +int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold) { struct acx_frag_threshold *acx; int ret = 0; @@ -876,7 +876,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl) goto out; } - acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold); + acx->frag_threshold = cpu_to_le16(frag_threshold); ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); if (ret < 0) { wl1271_warning("Setting of frag threshold failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index f41a9c1df12f..75a6306ff554 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1161,7 +1161,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, u8 tsid, u8 ps_scheme, u8 ack_policy, u32 apsd_conf0, u32 apsd_conf1); -int wl1271_acx_frag_threshold(struct wl1271 *wl); +int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold); int wl1271_acx_tx_config_options(struct wl1271 *wl); int wl1271_acx_mem_cfg(struct wl1271 *wl); int wl1271_acx_init_mem_config(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 492edc0f7aca..7949d346aadb 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -290,7 +290,7 @@ int wl1271_hw_init(struct wl1271 *wl) goto out_free_memmap; /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); + ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); if (ret < 0) goto out_free_memmap; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 6af270d382bb..31f0e2f6ffc3 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -425,7 +425,7 @@ static int wl1271_plt_init(struct wl1271 *wl) goto out_free_memmap; /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); + ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); if (ret < 0) goto out_free_memmap; @@ -1745,6 +1745,34 @@ out: return ret; } +static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) +{ + struct wl1271 *wl = hw->priv; + int ret = 0; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_acx_frag_threshold(wl, (u16)value); + if (ret < 0) + wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret); + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { struct wl1271 *wl = hw->priv; @@ -2421,6 +2449,7 @@ static const struct ieee80211_ops wl1271_ops = { .set_key = wl1271_op_set_key, .hw_scan = wl1271_op_hw_scan, .bss_info_changed = wl1271_op_bss_info_changed, + .set_frag_threshold = wl1271_op_set_frag_threshold, .set_rts_threshold = wl1271_op_set_rts_threshold, .conf_tx = wl1271_op_conf_tx, .get_tsf = wl1271_op_get_tsf, -- cgit v1.2.3-59-g8ed1b From b84a7d3d9e7cd5a25f4fd32142cebdf4481a74a4 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 22 Nov 2010 12:59:08 +0200 Subject: wl12xx: Unset bssid filter, ssid and bssid from firmware on disassoc On the disassociation event from the mac80211, the wl12xx driver does not clear the chipset configuration related to the AP - i.e. it does not perform a DISCONNECT and then a JOIN with zero SSID and dummy BSSID. Also, it does not unset the BSSID filter. Often this is not a problem, as the above is performed upon entering idle state. But if a scenario arises where a new association is attempted without cycling through idle state, the new association will fail. Fix this by resetting the firmware state on disassociation. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 31f0e2f6ffc3..708ffe304c6d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2011,9 +2011,12 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, /* Disable the keep-alive feature */ ret = wl1271_acx_keep_alive_mode(wl, false); - if (ret < 0) goto out_sleep; + + /* restore the bssid filter and go to dummy bssid */ + wl1271_unjoin(wl); + wl1271_dummy_join(wl); } } -- cgit v1.2.3-59-g8ed1b From 87217502d4f45a9925c5eda5b2179f1220e87537 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:12 +0000 Subject: Net: bluetooth: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/bluetooth/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index d1e433f7d673..7ca1f46a471a 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ -bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o +bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o -- cgit v1.2.3-59-g8ed1b From a3106d032fb17283c96fa041f8285e6926ae074d Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:13 +0000 Subject: Net: caif: Makefile: Remove deprecated items Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Also, use the ccflags-$ flag instead of EXTRA_CFLAGS because EXTRA_CFLAGS is deprecated and should now be switched. Last but not least, took out if-conditionals. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/caif/Makefile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/caif/Makefile b/net/caif/Makefile index f87481fb0e65..9d38e406e4a4 100644 --- a/net/caif/Makefile +++ b/net/caif/Makefile @@ -1,8 +1,6 @@ -ifeq ($(CONFIG_CAIF_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif +ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG -caif-objs := caif_dev.o \ +caif-y := caif_dev.o \ cfcnfg.o cfmuxl.o cfctrl.o \ cffrml.o cfveil.o cfdbgl.o\ cfserl.o cfdgml.o \ @@ -13,4 +11,4 @@ obj-$(CONFIG_CAIF) += caif.o obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o obj-$(CONFIG_CAIF) += caif_socket.o -export-objs := caif.o +export-y := caif.o -- cgit v1.2.3-59-g8ed1b From bac14e017830bd204b3a1bd55f42b0841c02e995 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:14 +0000 Subject: Net: can: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/can/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/can/Makefile b/net/can/Makefile index 9cd3c4b3abda..2d3894b32742 100644 --- a/net/can/Makefile +++ b/net/can/Makefile @@ -3,10 +3,10 @@ # obj-$(CONFIG_CAN) += can.o -can-objs := af_can.o proc.o +can-y := af_can.o proc.o obj-$(CONFIG_CAN_RAW) += can-raw.o -can-raw-objs := raw.o +can-raw-y := raw.o obj-$(CONFIG_CAN_BCM) += can-bcm.o -can-bcm-objs := bcm.o +can-bcm-y := bcm.o -- cgit v1.2.3-59-g8ed1b From fa13bc3daa5954ce58f68fd34fb1611df6ea6e6f Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:15 +0000 Subject: Net: ceph: Makefile: remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/ceph/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ceph/Makefile b/net/ceph/Makefile index aab1cabb8035..153bdec40835 100644 --- a/net/ceph/Makefile +++ b/net/ceph/Makefile @@ -6,7 +6,7 @@ ifneq ($(KERNELRELEASE),) obj-$(CONFIG_CEPH_LIB) += libceph.o -libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ +libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ mon_client.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ -- cgit v1.2.3-59-g8ed1b From 22674a24b44ac53f244ef6edadd02021a270df5a Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:16 +0000 Subject: Net: dns_resolver: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/dns_resolver/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns_resolver/Makefile b/net/dns_resolver/Makefile index c0ef4e71dc49..d5c13c2eb36d 100644 --- a/net/dns_resolver/Makefile +++ b/net/dns_resolver/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_DNS_RESOLVER) += dns_resolver.o -dns_resolver-objs := dns_key.o dns_query.o +dns_resolver-y := dns_key.o dns_query.o -- cgit v1.2.3-59-g8ed1b From cc0bdac399b1881626cd5512f292e396c9c96685 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:17 +0000 Subject: Net: econet: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/econet/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/econet/Makefile b/net/econet/Makefile index 39f0a77abdbd..05fae8be2fed 100644 --- a/net/econet/Makefile +++ b/net/econet/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_ECONET) += econet.o -econet-objs := af_econet.o +econet-y := af_econet.o -- cgit v1.2.3-59-g8ed1b From 6b8ff8c517008d93a6da62b106072a12dea8cb7c Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:18 +0000 Subject: Net: ipv4: netfilter: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/ipv4/netfilter/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 48111594ee9b..19eb59d01037 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -3,15 +3,15 @@ # # objects for l3 independent conntrack -nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o +nf_conntrack_ipv4-y := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y) ifeq ($(CONFIG_PROC_FS),y) nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o endif endif -nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o -iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o +nf_nat-y := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o +iptable_nat-y := nf_nat_rule.o nf_nat_standalone.o # connection tracking obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o -- cgit v1.2.3-59-g8ed1b From 4de58dfebe6882dc1e8e8dc5ec062e28e99623cd Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:19 +0000 Subject: Net: ipv6: netfiliter: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/ipv6/netfilter/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index 0a432c9b0795..abfee91ce816 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -11,13 +11,13 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o # objects for l3 independent conntrack -nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o +nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o # l3 independent conntrack obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o # defrag -nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o +nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o # matches -- cgit v1.2.3-59-g8ed1b From f91c4ae4989322ed5cd10b5247e1a7bd3868a84e Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:20 +0000 Subject: Net: irda: ircomm: Makefile: Remove deprecated kbuild goal defintions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/irda/ircomm/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile index 48689458c086..ab23b5ba7e33 100644 --- a/net/irda/ircomm/Makefile +++ b/net/irda/ircomm/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o -ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o -ircomm-tty-objs := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o +ircomm-y := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o +ircomm-tty-y := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o -- cgit v1.2.3-59-g8ed1b From cd30c62024904951392e21a200fe5427a6286736 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:21 +0000 Subject: Net: irda: irlan: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/irda/irlan/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/irda/irlan/Makefile b/net/irda/irlan/Makefile index 77549bc8641b..94eefbc8e6b9 100644 --- a/net/irda/irlan/Makefile +++ b/net/irda/irlan/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_IRLAN) += irlan.o -irlan-objs := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o +irlan-y := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o -- cgit v1.2.3-59-g8ed1b From 94ee288e94ab31cefe2c5af3b59c25a1374ca3e5 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:22 +0000 Subject: Net: irda: irnet: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/irda/irnet/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/irda/irnet/Makefile b/net/irda/irnet/Makefile index b3ee01e0def3..61c365c8a2a0 100644 --- a/net/irda/irnet/Makefile +++ b/net/irda/irnet/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_IRNET) += irnet.o -irnet-objs := irnet_ppp.o irnet_irda.o +irnet-y := irnet_ppp.o irnet_irda.o -- cgit v1.2.3-59-g8ed1b From 64387df8da1e4f178a47d53930288a46a357a479 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:23 +0000 Subject: Net: lapb: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/lapb/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/lapb/Makefile b/net/lapb/Makefile index 53f7c90db163..fff797dfc88c 100644 --- a/net/lapb/Makefile +++ b/net/lapb/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_LAPB) += lapb.o -lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o +lapb-y := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o -- cgit v1.2.3-59-g8ed1b From 927a41f50c83b539fde5c01911f4968d717199bf Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:24 +0000 Subject: Net: phonet: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/phonet/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/phonet/Makefile b/net/phonet/Makefile index d62bbba649b3..e10b1b182ce3 100644 --- a/net/phonet/Makefile +++ b/net/phonet/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_PHONET) += phonet.o pn_pep.o -phonet-objs := \ +phonet-y := \ pn_dev.o \ pn_netlink.o \ socket.o \ @@ -8,4 +8,4 @@ phonet-objs := \ sysctl.o \ af_phonet.o -pn_pep-objs := pep.o pep-gprs.o +pn_pep-y := pep.o pep-gprs.o -- cgit v1.2.3-59-g8ed1b From 094f2faaa2c4973e50979158f655a1d31a97ba98 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:25 +0000 Subject: Net: rds: Makefile: Remove deprecated items Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Also, use the ccflags-$ flag instead of EXTRA_CFLAGS because EXTRA_CFLAGS is deprecated and should now be switched. Last but not least, took out if-conditionals. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/rds/Makefile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/rds/Makefile b/net/rds/Makefile index b46eca109688..56d3f6023ced 100644 --- a/net/rds/Makefile +++ b/net/rds/Makefile @@ -4,7 +4,7 @@ rds-y := af_rds.o bind.o cong.o connection.o info.o message.o \ loop.o page.o rdma.o obj-$(CONFIG_RDS_RDMA) += rds_rdma.o -rds_rdma-objs := rdma_transport.o \ +rds_rdma-y := rdma_transport.o \ ib.o ib_cm.o ib_recv.o ib_ring.o ib_send.o ib_stats.o \ ib_sysctl.o ib_rdma.o \ iw.o iw_cm.o iw_recv.o iw_ring.o iw_send.o iw_stats.o \ @@ -12,10 +12,8 @@ rds_rdma-objs := rdma_transport.o \ obj-$(CONFIG_RDS_TCP) += rds_tcp.o -rds_tcp-objs := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \ +rds_tcp-y := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \ tcp_send.o tcp_stats.o -ifeq ($(CONFIG_RDS_DEBUG), y) -EXTRA_CFLAGS += -DDEBUG -endif +ccflags-$(CONFIG_RDS_DEBUG) := -DDEBUG -- cgit v1.2.3-59-g8ed1b From 9ed05ad3c0629f434b18d20c51162f9bbb4f5d31 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:26 +0000 Subject: Net: rxrpc: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/rxrpc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile index c46867c61c98..d1c3429b69ed 100644 --- a/net/rxrpc/Makefile +++ b/net/rxrpc/Makefile @@ -2,7 +2,7 @@ # Makefile for Linux kernel RxRPC # -af-rxrpc-objs := \ +af-rxrpc-y := \ af_rxrpc.o \ ar-accept.o \ ar-ack.o \ @@ -21,7 +21,7 @@ af-rxrpc-objs := \ ar-transport.o ifeq ($(CONFIG_PROC_FS),y) -af-rxrpc-objs += ar-proc.o +af-rxrpc-y += ar-proc.o endif obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o -- cgit v1.2.3-59-g8ed1b From fdb26195f494988fc155c204aab0f0953ba7ec6f Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:27 +0000 Subject: Net: sunrpc: auth_gss: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/sunrpc/auth_gss/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile index 7350d86a32ee..9e4cb59ef9f0 100644 --- a/net/sunrpc/auth_gss/Makefile +++ b/net/sunrpc/auth_gss/Makefile @@ -4,10 +4,10 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o -auth_rpcgss-objs := auth_gss.o gss_generic_token.o \ +auth_rpcgss-y := auth_gss.o gss_generic_token.o \ gss_mech_switch.o svcauth_gss.o obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o -rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ +rpcsec_gss_krb5-y := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o -- cgit v1.2.3-59-g8ed1b From e5700c740da2cb9f5a3aa978cd1fa3a79916ba04 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:28 +0000 Subject: Net: wanrouter: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/wanrouter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wanrouter/Makefile b/net/wanrouter/Makefile index 9f188ab3dcd0..4da14bc48078 100644 --- a/net/wanrouter/Makefile +++ b/net/wanrouter/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_WAN_ROUTER) += wanrouter.o -wanrouter-objs := wanproc.o wanmain.o +wanrouter-y := wanproc.o wanmain.o -- cgit v1.2.3-59-g8ed1b From eb06acdc85585f28864261f28659157848762ee4 Mon Sep 17 00:00:00 2001 From: Sridhar Samudrala Date: Thu, 28 Oct 2010 13:10:50 +0000 Subject: macvlan: Introduce 'passthru' mode to takeover the underlying device With the current default 'vepa' mode, a KVM guest using virtio with macvtap backend has the following limitations. - cannot change/add a mac address on the guest virtio-net - cannot create a vlan device on the guest virtio-net - cannot enable promiscuous mode on guest virtio-net To address these limitations, this patch introduces a new mode called 'passthru' when creating a macvlan device which allows takeover of the underlying device and passing it to a guest using virtio with macvtap backend. Only one macvlan device is allowed in passthru mode and it inherits the mac address from the underlying device and sets it in promiscuous mode to receive and forward all the packets. Signed-off-by: Sridhar Samudrala ------------------------------------------------------------------------- Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 33 ++++++++++++++++++++++++++++++++- include/linux/if_link.h | 1 + 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 93f0ba25c808..6ed577b065df 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -38,6 +38,7 @@ struct macvlan_port { struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; struct list_head vlans; struct rcu_head rcu; + bool passthru; }; #define macvlan_port_get_rcu(dev) \ @@ -169,6 +170,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) macvlan_broadcast(skb, port, NULL, MACVLAN_MODE_PRIVATE | MACVLAN_MODE_VEPA | + MACVLAN_MODE_PASSTHRU| MACVLAN_MODE_BRIDGE); else if (src->mode == MACVLAN_MODE_VEPA) /* flood to everyone except source */ @@ -185,7 +187,10 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) return skb; } - vlan = macvlan_hash_lookup(port, eth->h_dest); + if (port->passthru) + vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); + else + vlan = macvlan_hash_lookup(port, eth->h_dest); if (vlan == NULL) return skb; @@ -288,6 +293,11 @@ static int macvlan_open(struct net_device *dev) struct net_device *lowerdev = vlan->lowerdev; int err; + if (vlan->port->passthru) { + dev_set_promiscuity(lowerdev, 1); + goto hash_add; + } + err = -EBUSY; if (macvlan_addr_busy(vlan->port, dev->dev_addr)) goto out; @@ -300,6 +310,8 @@ static int macvlan_open(struct net_device *dev) if (err < 0) goto del_unicast; } + +hash_add: macvlan_hash_add(vlan); return 0; @@ -314,12 +326,18 @@ static int macvlan_stop(struct net_device *dev) struct macvlan_dev *vlan = netdev_priv(dev); struct net_device *lowerdev = vlan->lowerdev; + if (vlan->port->passthru) { + dev_set_promiscuity(lowerdev, -1); + goto hash_del; + } + dev_mc_unsync(lowerdev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(lowerdev, -1); dev_uc_del(lowerdev, dev->dev_addr); +hash_del: macvlan_hash_del(vlan); return 0; } @@ -559,6 +577,7 @@ static int macvlan_port_create(struct net_device *dev) if (port == NULL) return -ENOMEM; + port->passthru = false; port->dev = dev; INIT_LIST_HEAD(&port->vlans); for (i = 0; i < MACVLAN_HASH_SIZE; i++) @@ -603,6 +622,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) case MACVLAN_MODE_PRIVATE: case MACVLAN_MODE_VEPA: case MACVLAN_MODE_BRIDGE: + case MACVLAN_MODE_PASSTHRU: break; default: return -EINVAL; @@ -652,6 +672,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, } port = macvlan_port_get(lowerdev); + /* Only 1 macvlan device can be created in passthru mode */ + if (port->passthru) + return -EINVAL; + vlan->lowerdev = lowerdev; vlan->dev = dev; vlan->port = port; @@ -662,6 +686,13 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, if (data && data[IFLA_MACVLAN_MODE]) vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); + if (vlan->mode == MACVLAN_MODE_PASSTHRU) { + if (!list_empty(&port->vlans)) + return -EINVAL; + port->passthru = true; + memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN); + } + err = register_netdevice(dev); if (err < 0) goto destroy_port; diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 2e02e4d7b11e..6485d2a89bec 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -259,6 +259,7 @@ enum macvlan_mode { MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ + MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ }; /* SR-IOV virtual function management section */ -- cgit v1.2.3-59-g8ed1b From 8933f90c777c5728822206a2313c9c1361f5274f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 14 Oct 2010 22:58:58 +0200 Subject: b43: N-PHY: add 2056 radio channels tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.c | 5968 +++++++++++++++++++++++++++++++++ 1 file changed, 5968 insertions(+) diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index f710c01f2cc4..0cdf6a46ba4b 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -74,7 +74,5975 @@ .phy_regs.phy_bw5 = r4, \ .phy_regs.phy_bw6 = r5 +/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfc, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf6, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, + 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x05, 0x00, 0xf2, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, + 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x05, 0x00, 0xf2, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, +}; + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf0, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf0, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, +}; + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6e, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, + 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6b, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6b, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x6b, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x6b, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x5b, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x5a, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, + 0xff, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x5a, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x5a, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x5a, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x5a, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x59, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x59, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x59, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, + 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x78, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, + 0x84, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x75, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x75, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x75, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, + 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x74, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x84, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x83, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x82, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x72, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x72, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x72, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x72, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x71, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x71, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x71, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x71, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x71, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0b), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, +}; + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, + 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, + 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, + 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6d, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, +}; + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x6e, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6e, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, + 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x6d, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, + 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6c, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6b, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x6b, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x6b, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x6b, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x7b, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x7a, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x7a, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x7a, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x7a, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x7a, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, + 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x79, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x79, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x79, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x79, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x94, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x79, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x83, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x72, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x78, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x72, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x78, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x71, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x77, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x76, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x60, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x86, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x85, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x85, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x85, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x84, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x84, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0b), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, +}; + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = { + { .freq = 4920, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216), + }, + { .freq = 4930, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215), + }, + { .freq = 4940, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214), + }, + { .freq = 4950, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213), + }, + { .freq = 4960, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212), + }, + { .freq = 4970, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211), + }, + { .freq = 4980, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f), + }, + { .freq = 4990, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e), + }, + { .freq = 5000, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d), + }, + { .freq = 5010, + RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c), + }, + { .freq = 5020, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b), + }, + { .freq = 5030, + RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a), + }, + { .freq = 5040, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209), + }, + { .freq = 5050, + RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208), + }, + { .freq = 5060, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207), + }, + { .freq = 5070, + RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206), + }, + { .freq = 5080, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205), + }, + { .freq = 5090, + RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204), + }, + { .freq = 5100, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203), + }, + { .freq = 5110, + RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202), + }, + { .freq = 5120, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201), + }, + { .freq = 5130, + RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200), + }, + { .freq = 5140, + RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00), + PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff), + }, + { .freq = 5160, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd), + }, + { .freq = 5170, + RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc), + }, + { .freq = 5180, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00), + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), + }, + { .freq = 5190, + RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa), + }, + { .freq = 5200, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), + }, + { .freq = 5210, + RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, + 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8), + }, + { .freq = 5220, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), + }, + { .freq = 5230, + RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6), + }, + { .freq = 5240, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), + }, + { .freq = 5250, + RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, + 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4), + }, + { .freq = 5260, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, + 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00), + PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), + }, + { .freq = 5270, + RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, + 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2), + }, + { .freq = 5280, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), + }, + { .freq = 5290, + RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0), + }, + { .freq = 5300, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), + }, + { .freq = 5310, + RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef), + }, + { .freq = 5320, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, + 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00), + PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), + }, + { .freq = 5330, + RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed), + }, + { .freq = 5340, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, + 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec), + }, + { .freq = 5350, + RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00), + PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb), + }, + { .freq = 5360, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea), + }, + { .freq = 5370, + RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, + 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9), + }, + { .freq = 5380, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8), + }, + { .freq = 5390, + RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7), + }, + { .freq = 5400, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6), + }, + { .freq = 5410, + RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5), + }, + { .freq = 5420, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, + 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5), + }, + { .freq = 5430, + RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, + 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00), + PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4), + }, + { .freq = 5440, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3), + }, + { .freq = 5450, + RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2), + }, + { .freq = 5460, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1), + }, + { .freq = 5470, + RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, + 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0), + }, + { .freq = 5480, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df), + }, + { .freq = 5490, + RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de), + }, + { .freq = 5500, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), + }, + { .freq = 5510, + RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd), + }, + { .freq = 5520, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, + 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), + }, + { .freq = 5530, + RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db), + }, + { .freq = 5540, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, + 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), + }, + { .freq = 5550, + RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9), + }, + { .freq = 5560, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), + }, + { .freq = 5570, + RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, + 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00), + PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7), + }, + { .freq = 5580, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), + }, + { .freq = 5590, + RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, + 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6), + }, + { .freq = 5600, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), + }, + { .freq = 5610, + RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00), + PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4), + }, + { .freq = 5620, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, + 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), + }, + { .freq = 5630, + RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2), + }, + { .freq = 5640, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), + }, + { .freq = 5650, + RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00), + PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1), + }, + { .freq = 5660, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), + }, + { .freq = 5670, + RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, + 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf), + }, + { .freq = 5680, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), + }, + { .freq = 5690, + RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00), + PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce), + }, + { .freq = 5700, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), + }, + { .freq = 5710, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc), + }, + { .freq = 5720, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5725, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb), + }, + { .freq = 5730, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00), + PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca), + }, + { .freq = 5735, + RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca), + }, + { .freq = 5740, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9), + }, + { .freq = 5745, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00), + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), + }, + { .freq = 5750, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6d, 0x00), + PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9), + }, + { .freq = 5755, + RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8), + }, + { .freq = 5760, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5765, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00), + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), + }, + { .freq = 5770, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7), + }, + { .freq = 5775, + RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7), + }, + { .freq = 5780, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6), + }, + { .freq = 5785, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5790, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6), + }, + { .freq = 5795, + RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5), + }, + { .freq = 5800, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00), + PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5), + }, + { .freq = 5805, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), + }, + { .freq = 5810, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5815, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4), + }, + { .freq = 5820, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00), + PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3), + }, + { .freq = 5825, + RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, + 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00), + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), + }, + { .freq = 5830, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00), + PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2), + }, + { .freq = 5840, + RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2), + }, + { .freq = 5850, + RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1), + }, + { .freq = 5860, + RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00), + PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0), + }, + { .freq = 5870, + RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf), + }, + { .freq = 5880, + RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf), + }, + { .freq = 5890, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be), + }, + { .freq = 5900, + RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd), + }, + { .freq = 5910, + RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, + 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00), + PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc), + }, + { .freq = 2412, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, + { .freq = 2484, + RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, + 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09), + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), + }, }; /* TODO: add support for rev4+ devices by searching in rev4+ tables */ -- cgit v1.2.3-59-g8ed1b From 8ce469999552b0c3325350cd9b4be417f2bbfc23 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 17 Nov 2010 22:14:37 +0100 Subject: b43: rfkill: use HI enabled bit for all devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Devices which use LO enabled bit are covered by b43legacy Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/rfkill.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 78016ae21c50..86bc0a0f735c 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -28,23 +28,8 @@ /* Returns TRUE, if the radio is enabled in hardware. */ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) { - if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) { - if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) - & B43_MMIO_RADIO_HWENABLED_HI_MASK)) - return 1; - } else { - /* To prevent CPU fault on PPC, do not read a register - * unless the interface is started; however, on resume - * for hibernation, this routine is entered early. When - * that happens, unconditionally return TRUE. - */ - if (b43_status(dev) < B43_STAT_STARTED) - return 1; - if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) - & B43_MMIO_RADIO_HWENABLED_LO_MASK) - return 1; - } - return 0; + return !(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) + & B43_MMIO_RADIO_HWENABLED_HI_MASK); } /* The poll callback for the hardware button. */ -- cgit v1.2.3-59-g8ed1b From 31e99729ae66d8b74316547c40eed15172f14ea8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 17 Nov 2010 21:46:06 -0800 Subject: cfg80211: put core regulatory request into queue This will simplify the synchronization for pending requests. Without this we have a race between the core and when we restore regulatory settings, although this is unlikely its best to just avoid that race altogether. Signed-off-by: Luis R. Rodriguez Tested-by: Mark Mentovai Tested-by: Bruno Randolf Signed-off-by: John W. Linville --- net/wireless/reg.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3be18d9a944f..9830db61019e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1530,12 +1530,7 @@ static int regulatory_hint_core(const char *alpha2) request->alpha2[1] = alpha2[1]; request->initiator = NL80211_REGDOM_SET_BY_CORE; - /* - * This ensures last_request is populated once modules - * come swinging in and calling regulatory hints and - * wiphy_apply_custom_regulatory(). - */ - reg_process_hint(request); + queue_regulatory_request(request); return 0; } -- cgit v1.2.3-59-g8ed1b From f333a7a2f49e2a9b46f8d18962bd750b18beeecd Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 17 Nov 2010 21:46:07 -0800 Subject: cfg80211: move reg_work and reg_todo above These will be used earlier in the next few patches. Signed-off-by: Luis R. Rodriguez Tested-by: Mark Mentovai Tested-by: Bruno Randolf Signed-off-by: John W. Linville --- net/wireless/reg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9830db61019e..3fa247488f87 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -96,6 +96,9 @@ struct reg_beacon { struct ieee80211_channel chan; }; +static void reg_todo(struct work_struct *work); +static DECLARE_WORK(reg_work, reg_todo); + /* We keep a static world regulatory domain in case of the absence of CRDA */ static const struct ieee80211_regdomain world_regdom = { .n_reg_rules = 5, @@ -1494,8 +1497,6 @@ static void reg_todo(struct work_struct *work) reg_process_pending_beacon_hints(); } -static DECLARE_WORK(reg_work, reg_todo); - static void queue_regulatory_request(struct regulatory_request *request) { if (isalpha(request->alpha2[0])) -- cgit v1.2.3-59-g8ed1b From b0e2880b0518ad11af20c7c93ec5cac93f9f03b0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 17 Nov 2010 21:46:08 -0800 Subject: cfg80211: move mutex locking to reg_process_pending_hints() This will be required in the next patch and it makes the next patch easier to review. Signed-off-by: Luis R. Rodriguez Tested-by: Mark Mentovai Tested-by: Bruno Randolf Signed-off-by: John W. Linville --- net/wireless/reg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3fa247488f87..b522c46c4748 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1412,16 +1412,13 @@ static void reg_process_hint(struct regulatory_request *reg_request) BUG_ON(!reg_request->alpha2); - mutex_lock(&cfg80211_mutex); - mutex_lock(®_mutex); - if (wiphy_idx_valid(reg_request->wiphy_idx)) wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) { kfree(reg_request); - goto out; + return; } r = __regulatory_hint(wiphy, reg_request); @@ -1429,16 +1426,16 @@ static void reg_process_hint(struct regulatory_request *reg_request) if (r == -EALREADY && wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) wiphy_update_regulatory(wiphy, initiator); -out: - mutex_unlock(®_mutex); - mutex_unlock(&cfg80211_mutex); } /* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */ static void reg_process_pending_hints(void) - { +{ struct regulatory_request *reg_request; + mutex_lock(&cfg80211_mutex); + mutex_lock(®_mutex); + spin_lock(®_requests_lock); while (!list_empty(®_requests_list)) { reg_request = list_first_entry(®_requests_list, @@ -1451,6 +1448,9 @@ static void reg_process_pending_hints(void) spin_lock(®_requests_lock); } spin_unlock(®_requests_lock); + + mutex_unlock(®_mutex); + mutex_unlock(&cfg80211_mutex); } /* Processes beacon hints -- this has nothing to do with country IEs */ -- cgit v1.2.3-59-g8ed1b From b2e253cf300c5e33f49b7dd8b593bfc722177401 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 17 Nov 2010 21:46:09 -0800 Subject: cfg80211: Fix regulatory bug with multiple cards and delays When two cards are connected with the same regulatory domain if CRDA had a delayed response then cfg80211's own set regulatory domain would still be the world regulatory domain. There was a bug on cfg80211's logic such that it assumed that once you pegged a request as the last request it was already the currently set regulatory domain. This would mean we would race setting a stale regulatory domain to secondary cards which had the same regulatory domain since the alpha2 would match. We fix this by processing each regulatory request atomically, and only move on to the next one once we get it fully processed. In the case CRDA is not present we will simply world roam. This issue is only present when you have a slow system and the CRDA processing is delayed. Because of this it is not a known regression. Without this fix when a delay is present with CRDA the second card would end up with an intersected regulatory domain and not allow it to use the channels it really is designed for. When two cards with two different regulatory domains were inserted you'd end up rejecting the second card's regulatory domain request. This fails with mac80211_hswim's regtest=2 (two requests, same alpha2) and regtest=3 (two requests, different alpha2) module parameter options. This was reproduced and tested against mac80211_hwsim using this CRDA delayer: #!/bin/bash echo $COUNTRY >> /tmp/log sleep 2 /sbin/crda.orig And these regulatory tests: modprobe mac80211_hwsim regtest=2 modprobe mac80211_hwsim regtest=3 Reported-by: Mark Mentovai Signed-off-by: Luis R. Rodriguez Tested-by: Mark Mentovai Tested-by: Bruno Randolf Signed-off-by: John W. Linville --- include/net/regulatory.h | 7 +++++++ net/wireless/reg.c | 52 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 9e103a4e91ee..356d6e3dc20a 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -43,6 +43,12 @@ enum environment_cap { * @intersect: indicates whether the wireless core should intersect * the requested regulatory domain with the presently set regulatory * domain. + * @processed: indicates whether or not this requests has already been + * processed. When the last request is processed it means that the + * currently regulatory domain set on cfg80211 is updated from + * CRDA and can be used by other regulatory requests. When a + * the last request is not yet processed we must yield until it + * is processed before processing any new requests. * @country_ie_checksum: checksum of the last processed and accepted * country IE * @country_ie_env: lets us know if the AP is telling us we are outdoor, @@ -54,6 +60,7 @@ struct regulatory_request { enum nl80211_reg_initiator initiator; char alpha2[2]; bool intersect; + bool processed; enum environment_cap country_ie_env; struct list_head list; }; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b522c46c4748..bc14caab19cd 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1320,6 +1320,21 @@ static int ignore_request(struct wiphy *wiphy, return -EINVAL; } +static void reg_set_request_processed(void) +{ + bool need_more_processing = false; + + last_request->processed = true; + + spin_lock(®_requests_lock); + if (!list_empty(®_requests_list)) + need_more_processing = true; + spin_unlock(®_requests_lock); + + if (need_more_processing) + schedule_work(®_work); +} + /** * __regulatory_hint - hint to the wireless core a regulatory domain * @wiphy: if the hint comes from country information from an AP, this @@ -1395,8 +1410,10 @@ new_request: * have applied the requested regulatory domain before we just * inform userspace we have processed the request */ - if (r == -EALREADY) + if (r == -EALREADY) { nl80211_send_reg_change_event(last_request); + reg_set_request_processed(); + } return r; } @@ -1428,7 +1445,11 @@ static void reg_process_hint(struct regulatory_request *reg_request) wiphy_update_regulatory(wiphy, initiator); } -/* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */ +/* + * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* + * Regulatory hints come on a first come first serve basis and we + * must process each one atomically. + */ static void reg_process_pending_hints(void) { struct regulatory_request *reg_request; @@ -1436,19 +1457,30 @@ static void reg_process_pending_hints(void) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); + /* When last_request->processed becomes true this will be rescheduled */ + if (last_request && !last_request->processed) { + REG_DBG_PRINT("Pending regulatory request, waiting " + "for it to be processed..."); + goto out; + } + spin_lock(®_requests_lock); - while (!list_empty(®_requests_list)) { - reg_request = list_first_entry(®_requests_list, - struct regulatory_request, - list); - list_del_init(®_request->list); + if (list_empty(®_requests_list)) { spin_unlock(®_requests_lock); - reg_process_hint(reg_request); - spin_lock(®_requests_lock); + goto out; } + + reg_request = list_first_entry(®_requests_list, + struct regulatory_request, + list); + list_del_init(®_request->list); + spin_unlock(®_requests_lock); + reg_process_hint(reg_request); + +out: mutex_unlock(®_mutex); mutex_unlock(&cfg80211_mutex); } @@ -2057,6 +2089,8 @@ int set_regdom(const struct ieee80211_regdomain *rd) nl80211_send_reg_change_event(last_request); + reg_set_request_processed(); + mutex_unlock(®_mutex); return r; -- cgit v1.2.3-59-g8ed1b From 18890d4b89d8507ad09289f6f57a71591c7e9e83 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 19 Nov 2010 08:11:01 +0100 Subject: mac80211: Disable hw crypto for GTKs on AP VLAN interfaces When using AP VLAN interfaces, each VLAN interface should be in its own broadcast domain. Hostapd achieves this by assigning different GTKs to different AP VLAN interfaces. However, mac80211 drivers are not aware of AP VLAN interfaces and as such mac80211 sends the GTK to the driver in the context of the base AP mode interface. This causes problems when multiple AP VLAN interfaces are used since the driver will use the same key slot for the different GTKs (there's no way for the driver to distinguish the different GTKs from different AP VLAN interfaces). Thus, only the clients associated to one AP VLAN interface (the one that was created last) can actually use broadcast traffic. Fix this by not programming any GTKs for AP VLAN interfaces into the hw but fall back to using software crypto. The GTK for the underlying AP interface is still sent to the driver. That means, broadcast traffic to stations associated to an AP VLAN interface is encrypted in software whereas broadcast traffic to stations associated to the non-VLAN AP interface is encrypted in hardware. Cc: Johannes Berg Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/key.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index ccd676b2f599..72df1ca7299b 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -84,10 +84,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) goto out_unsupported; sdata = key->sdata; - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + /* + * The driver doesn't know anything about VLAN interfaces. + * Hence, don't send GTKs for VLAN interfaces to the driver. + */ + if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) + goto out_unsupported; sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); + } ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); -- cgit v1.2.3-59-g8ed1b From b5bb2f2beb4d54597fd54075480fc4874a9c08dc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 18 Nov 2010 12:08:10 -0800 Subject: iwlwifi: fix modular 3945 only build If only 3945 is selected, and is a module, build fails because iwl-legacy.c won't be compiled. Fix this by adding it to the build correctly. This doesn't happen for 4965 because it is a bool option, not tristate, since it's built into the AGN module. Reported-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 01aa2468bd69..93380f97835f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -7,6 +7,10 @@ iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o +# If 3945 is selected only, iwl-legacy.o will be added +# to iwlcore-m above, but it needs to be built in. +iwlcore-objs += $(iwlcore-m) + CFLAGS_iwl-devtrace.o := -I$(src) # AGN -- cgit v1.2.3-59-g8ed1b From e1566d1f322b41b1ac3acf33407a0cfe2a311b75 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 20 Nov 2010 03:08:46 +0100 Subject: ath9k: fix recursive locking in the tx flush path Signed-off-by: Felix Fietkau Tested-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c63e283ff97f..495432ec85a9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -163,6 +163,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) bf = list_first_entry(&tid->buf_q, struct ath_buf, list); list_move_tail(&bf->list, &bf_head); + spin_unlock_bh(&txq->axq_lock); fi = get_frame_info(bf->bf_mpdu); if (fi->retries) { ath_tx_update_baw(sc, tid, fi->seqno); @@ -170,6 +171,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) } else { ath_tx_send_normal(sc, txq, tid, &bf_head); } + spin_lock_bh(&txq->axq_lock); } spin_unlock_bh(&txq->axq_lock); -- cgit v1.2.3-59-g8ed1b From 3b1d6dfaaf89694c2aa56fe9a6b0f0221b98a209 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 20 Nov 2010 20:06:02 +0800 Subject: libertas: remove duplicated #include Remove duplicated #include('s) in drivers/net/wireless/libertas/cfg.c Signed-off-by: Huang Weiyi Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 5046a0005034..73b2beef86b1 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From a9ab21133581580f6907abbc33fd3870e75dc935 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Nov 2010 16:53:26 +0100 Subject: carl9170: fix init-self regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit: "carl9170: tx path review" introduced a regression. gcc (with -Winit-self): tx.c:1264: warning: ‘super’ is used uninitialized in this function Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 688eede48516..aee5c9d89a14 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1261,7 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar) static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, struct ieee80211_sta *sta, struct sk_buff *skb) { - struct _carl9170_tx_superframe *super = (void *) super; + struct _carl9170_tx_superframe *super = (void *) skb->data; struct carl9170_sta_info *sta_info; struct carl9170_sta_tid *agg; struct sk_buff *iter; -- cgit v1.2.3-59-g8ed1b From 85be3d98dbc8d9cff9411c52c619c3752737b7b4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:51 -0800 Subject: ar9170: Use const Mark an array const. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c index 4604de09a8b2..6452c5055a63 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ b/drivers/net/wireless/ath/ar9170/cmd.c @@ -54,7 +54,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) { - __le32 buf[2] = { + const __le32 buf[2] = { cpu_to_le32(reg), cpu_to_le32(val), }; -- cgit v1.2.3-59-g8ed1b From 8b22523b045858042c6700f556f840853de163ea Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:52 -0800 Subject: ath5k: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 11266 56 2464 13786 35da drivers/net/wireless/ath/ath5k/ani.o.old 11181 56 2464 13701 3585 drivers/net/wireless/ath/ath5k/ani.o.new Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index db98a853ff35..6b75b22a929a 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -63,15 +63,15 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) * so i stick with the HAL version for now... */ #if 0 - const s8 hi[] = { -18, -18, -16, -14, -12 }; - const s8 lo[] = { -52, -56, -60, -64, -70 }; - const s8 sz[] = { -34, -41, -48, -55, -62 }; - const s8 fr[] = { -70, -72, -75, -78, -80 }; + static const s8 hi[] = { -18, -18, -16, -14, -12 }; + static const s8 lo[] = { -52, -56, -60, -64, -70 }; + static const s8 sz[] = { -34, -41, -48, -55, -62 }; + static const s8 fr[] = { -70, -72, -75, -78, -80 }; #else - const s8 sz[] = { -55, -62 }; - const s8 lo[] = { -64, -70 }; - const s8 hi[] = { -14, -12 }; - const s8 fr[] = { -78, -80 }; + static const s8 sz[] = { -55, -62 }; + static const s8 lo[] = { -64, -70 }; + static const s8 hi[] = { -14, -12 }; + static const s8 fr[] = { -78, -80 }; #endif if (level < 0 || level >= ARRAY_SIZE(sz)) { ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", @@ -102,7 +102,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) { - const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; + static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; if (level < 0 || level >= ARRAY_SIZE(val) || level > ah->ah_sc->ani_state.max_spur_level) { @@ -127,7 +127,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) { - const int val[] = { 0, 4, 8 }; + static const int val[] = { 0, 4, 8 }; if (level < 0 || level >= ARRAY_SIZE(val)) { ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level); @@ -151,12 +151,12 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) { - const int m1l[] = { 127, 50 }; - const int m2l[] = { 127, 40 }; - const int m1[] = { 127, 0x4d }; - const int m2[] = { 127, 0x40 }; - const int m2cnt[] = { 31, 16 }; - const int m2lcnt[] = { 63, 48 }; + static const int m1l[] = { 127, 50 }; + static const int m2l[] = { 127, 40 }; + static const int m1[] = { 127, 0x4d }; + static const int m2[] = { 127, 0x40 }; + static const int m2cnt[] = { 31, 16 }; + static const int m2lcnt[] = { 63, 48 }; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); @@ -192,7 +192,7 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) { - const int val[] = { 8, 6 }; + static const int val[] = { 8, 6 }; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); ah->ah_sc->ani_state.cck_weak_sig = on; -- cgit v1.2.3-59-g8ed1b From 07b2fa5a2368accf0fe6cb16e7eca6d1150554ed Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:53 -0800 Subject: ath9k: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 11161 56 2136 13353 3429 drivers/net/wireless/ath/ath9k/ar9003_paprd.o.new 11167 56 2136 13359 342f drivers/net/wireless/ath/ath9k/ar9003_paprd.o.old 15428 56 3056 18540 486c drivers/net/wireless/ath/ath9k/eeprom_4k.o.old 15451 56 3056 18563 4883 drivers/net/wireless/ath/ath9k/eeprom_4k.o.new 14087 56 2560 16703 413f drivers/net/wireless/ath/ath9k/eeprom_9287.o.old 14036 56 2560 16652 410c drivers/net/wireless/ath/ath9k/eeprom_9287.o.new 10041 56 2384 12481 30c1 drivers/net/wireless/ath/ath9k/ani.o.new 10088 56 2384 12528 30f0 drivers/net/wireless/ath/ath9k/ani.o.old 9316 1580 2304 13200 3390 drivers/net/wireless/ath/ath9k/htc_drv_init.o.new 9316 1580 2304 13200 3390 drivers/net/wireless/ath/ath9k/htc_drv_init.o.old 16483 56 3432 19971 4e03 drivers/net/wireless/ath/ath9k/ar9003_phy.o.new 16517 56 3432 20005 4e25 drivers/net/wireless/ath/ath9k/ar9003_phy.o.old 18221 104 2960 21285 5325 drivers/net/wireless/ath/ath9k/rc.o.old 18203 104 2960 21267 5313 drivers/net/wireless/ath/ath9k/rc.o.new 19985 56 4288 24329 5f09 drivers/net/wireless/ath/ath9k/eeprom_def.o.new 20040 56 4288 24384 5f40 drivers/net/wireless/ath/ath9k/eeprom_def.o.old 23997 56 4984 29037 716d drivers/net/wireless/ath/ath9k/ar5008_phy.o.old 23846 56 4984 28886 70d6 drivers/net/wireless/ath/ath9k/ar5008_phy.o.new 24285 56 3184 27525 6b85 drivers/net/wireless/ath/ath9k/ar9003_eeprom.o.old 24101 56 3184 27341 6acd drivers/net/wireless/ath/ath9k/ar9003_eeprom.o.new 6834 56 1032 7922 1ef2 drivers/net/wireless/ath/ath9k/ar9002_phy.o.old 6780 56 1032 7868 1ebc drivers/net/wireless/ath/ath9k/ar9002_phy.o.new 36211 64 8624 44899 af63 drivers/net/wireless/ath/ath9k/hw.o.new 36401 64 8624 45089 b021 drivers/net/wireless/ath/ath9k/hw.o.old 9281 56 1496 10833 2a51 drivers/net/wireless/ath/ath9k/ar9003_calib.o.old 9150 56 1496 10702 29ce drivers/net/wireless/ath/ath9k/ar9003_calib.o.new Use ARRAY_SIZE instead of a magic number. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 8 +++---- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 32 ++++++++++++++------------ drivers/net/wireless/ath/ath9k/ar9002_phy.c | 12 ++++++---- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 10 ++++---- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++++--- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 4 ++-- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 ++-- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 12 ++++++---- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 14 +++++------ drivers/net/wireless/ath/ath9k/eeprom_def.c | 17 ++++++++------ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 9 ++++---- drivers/net/wireless/ath/ath9k/rc.c | 6 ++--- 13 files changed, 74 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 63ccb39cdcd4..29a045da184b 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -834,10 +834,10 @@ void ath9k_hw_ani_setup(struct ath_hw *ah) { int i; - const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; - const int coarseHigh[] = { -14, -14, -14, -14, -12 }; - const int coarseLow[] = { -64, -64, -64, -64, -70 }; - const int firpwr[] = { -78, -78, -78, -78, -80 }; + static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; + static const int coarseHigh[] = { -14, -14, -14, -14, -12 }; + static const int coarseLow[] = { -64, -64, -64, -64, -70 }; + static const int firpwr[] = { -78, -78, -78, -78, -80 }; for (i = 0; i < 5; i++) { ah->totalSizeDesired[i] = totalSizeDesired[i]; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 7303d98e4100..06e34d293dc8 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -244,13 +244,15 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, int upper, lower, cur_vit_mask; int tmp, new; int i; - int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, - AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 + static int pilot_mask_reg[4] = { + AR_PHY_TIMING7, AR_PHY_TIMING8, + AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; - int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, - AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 + static int chan_mask_reg[4] = { + AR_PHY_TIMING9, AR_PHY_TIMING10, + AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; - int inc[4] = { 0, 100, 0, 0 }; + static int inc[4] = { 0, 100, 0, 0 }; int8_t mask_m[123]; int8_t mask_p[123]; @@ -1084,12 +1086,12 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, break; } case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ - const int m1ThreshLow[] = { 127, 50 }; - const int m2ThreshLow[] = { 127, 40 }; - const int m1Thresh[] = { 127, 0x4d }; - const int m2Thresh[] = { 127, 0x40 }; - const int m2CountThr[] = { 31, 16 }; - const int m2CountThrLow[] = { 63, 48 }; + static const int m1ThreshLow[] = { 127, 50 }; + static const int m2ThreshLow[] = { 127, 40 }; + static const int m1Thresh[] = { 127, 0x4d }; + static const int m2Thresh[] = { 127, 0x40 }; + static const int m2CountThr[] = { 31, 16 }; + static const int m2CountThrLow[] = { 63, 48 }; u32 on = param ? 1 : 0; REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, @@ -1141,7 +1143,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, break; } case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ - const int weakSigThrCck[] = { 8, 6 }; + static const int weakSigThrCck[] = { 8, 6 }; u32 high = param ? 1 : 0; REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, @@ -1157,7 +1159,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, break; } case ATH9K_ANI_FIRSTEP_LEVEL:{ - const int firstep[] = { 0, 4, 8 }; + static const int firstep[] = { 0, 4, 8 }; u32 level = param; if (level >= ARRAY_SIZE(firstep)) { @@ -1178,7 +1180,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, break; } case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ - const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; + static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; u32 level = param; if (level >= ARRAY_SIZE(cycpwrThr1)) { @@ -1627,7 +1629,7 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah) void ar5008_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); - const u32 ar5416_cca_regs[6] = { + static const u32 ar5416_cca_regs[6] = { AR_PHY_CCA, AR_PHY_CH1_CCA, AR_PHY_CH2_CCA, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 3fb97fdc1240..7ae66a889f5a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -175,13 +175,15 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, int upper, lower, cur_vit_mask; int tmp, newVal; int i; - int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, - AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 + static const int pilot_mask_reg[4] = { + AR_PHY_TIMING7, AR_PHY_TIMING8, + AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; - int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, - AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 + static const int chan_mask_reg[4] = { + AR_PHY_TIMING9, AR_PHY_TIMING10, + AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; - int inc[4] = { 0, 100, 0, 0 }; + static const int inc[4] = { 0, 100, 0, 0 }; struct chan_centers centers; int8_t mask_m[123]; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 32eed19ff6f9..4c94c9ed5f81 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -196,7 +196,7 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) u32 qCoffDenom, iCoffDenom; int32_t qCoff, iCoff; int iqCorrNeg, i; - const u_int32_t offset_array[3] = { + static const u_int32_t offset_array[3] = { AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_B1, AR_PHY_RX_IQCAL_CORR_B2, @@ -603,22 +603,22 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - const u32 txiqcal_status[AR9300_MAX_CHAINS] = { + static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { AR_PHY_TX_IQCAL_STATUS_B0, AR_PHY_TX_IQCAL_STATUS_B1, AR_PHY_TX_IQCAL_STATUS_B2, }; - const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = { + static const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, AR_PHY_TX_IQCAL_CORR_COEFF_01_B2, }; - const u32 rx_corr[AR9300_MAX_CHAINS] = { + static const u32 rx_corr[AR9300_MAX_CHAINS] = { AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_B1, AR_PHY_RX_IQCAL_CORR_B2, }; - const u_int32_t chan_info_tab[] = { + static const u_int32_t chan_info_tab[] = { AR_PHY_CHAN_INFO_TAB_0, AR_PHY_CHAN_INFO_TAB_1, AR_PHY_CHAN_INFO_TAB_2, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 9a7e151f0796..3161a5901a7a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4455,14 +4455,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, int i; int16_t twiceLargestAntenna; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; - u16 ctlModesFor11a[] = { + static const u16 ctlModesFor11a[] = { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; - u16 ctlModesFor11g[] = { + static const u16 ctlModesFor11g[] = { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 }; - u16 numCtlModes, *pCtlMode, ctlMode, freq; + u16 numCtlModes; + const u16 *pCtlMode; + u16 ctlMode, freq; struct chan_centers centers; u8 *ctlIndex; u8 ctlNum; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 716db414c258..850bc9866c19 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -32,12 +32,12 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) { struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; struct ar9300_modal_eep_header *hdr; - const u32 ctrl0[3] = { + static const u32 ctrl0[3] = { AR_PHY_PAPRD_CTRL0_B0, AR_PHY_PAPRD_CTRL0_B1, AR_PHY_PAPRD_CTRL0_B2 }; - const u32 ctrl1[3] = { + static const u32 ctrl1[3] = { AR_PHY_PAPRD_CTRL1_B0, AR_PHY_PAPRD_CTRL1_B1, AR_PHY_PAPRD_CTRL1_B2 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e8d6455b5948..656d8ce251a7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -128,7 +128,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, struct ath9k_channel *chan) { - u32 spur_freq[4] = { 2420, 2440, 2464, 2480 }; + static const u32 spur_freq[4] = { 2420, 2440, 2464, 2480 }; int cur_bb_spur, negative = 0, cck_spur_freq; int i; @@ -1161,7 +1161,7 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah) void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); - const u32 ar9300_cca_regs[6] = { + static const u32 ar9300_cca_regs[6] = { AR_PHY_CCA_0, AR_PHY_CCA_1, AR_PHY_CCA_2, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index c40c534c6662..c2481b3ac7e6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -534,7 +534,9 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, u16 twiceMinEdgePower; u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; - u16 numCtlModes, *pCtlMode, ctlMode, freq; + u16 numCtlModes; + const u16 *pCtlMode; + u16 ctlMode, freq; struct chan_centers centers; struct cal_ctl_data_4k *rep; struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; @@ -550,10 +552,10 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 0, {0, 0, 0, 0} }; - u16 ctlModesFor11g[] = - { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, - CTL_2GHT40 - }; + static const u16 ctlModesFor11g[] = { + CTL_11B, CTL_11G, CTL_2GHT20, + CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 + }; ath9k_hw_get_channel_centers(ah, chan, ¢ers); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index ebf7a89f547c..34a588837d4d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -626,13 +626,13 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0} }; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; - u16 ctlModesFor11g[] = {CTL_11B, - CTL_11G, - CTL_2GHT20, - CTL_11B_EXT, - CTL_11G_EXT, - CTL_2GHT40}; - u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; + static const u16 ctlModesFor11g[] = { + CTL_11B, CTL_11G, CTL_2GHT20, + CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 + }; + u16 numCtlModes = 0; + const u16 *pCtlMode = NULL; + u16 ctlMode, freq; struct chan_centers centers; int tx_chainmask; u16 twiceMinEdgePower; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index a819ddc9fdbc..e94216e1e107 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -1021,13 +1021,16 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, 0, {0, 0, 0, 0} }; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; - u16 ctlModesFor11a[] = - { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; - u16 ctlModesFor11g[] = - { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, - CTL_2GHT40 - }; - u16 numCtlModes, *pCtlMode, ctlMode, freq; + static const u16 ctlModesFor11a[] = { + CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 + }; + static const u16 ctlModesFor11g[] = { + CTL_11B, CTL_11G, CTL_2GHT20, + CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 + }; + u16 numCtlModes; + const u16 *pCtlMode; + u16 ctlMode, freq; struct chan_centers centers; int tx_chainmask; u16 twiceMinEdgePower; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 3d7b97f1b3ae..8f05fc98721c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -306,7 +306,7 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) struct ath_hw *ah = (struct ath_hw *) hw_priv; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - __be32 buf[2] = { + const __be32 buf[2] = { cpu_to_be32(reg_offset), cpu_to_be32(val), }; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5a13a761c30c..fd4fdb57e570 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -310,10 +310,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); u32 regAddr[2] = { AR_STA_ID0 }; u32 regHold[2]; - u32 patternData[4] = { 0x55555555, - 0xaaaaaaaa, - 0x66666666, - 0x99999999 }; + static const u32 patternData[4] = { + 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 + }; int i, j, loop_max; if (!AR_SREV_9300_20_OR_LATER(ah)) { @@ -436,7 +435,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) u32 sum; int i; u16 eeval; - u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; + static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; sum = 0; for (i = 0; i < 3; i++) { diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 33bb33b456ff..ee4566d9d234 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -864,7 +864,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, bool state_change = false; int count, n_bad_frames; u8 last_per; - static u32 nretry_to_per_lookup[10] = { + static const u32 nretry_to_per_lookup[10] = { 100 * 0 / 1, 100 * 1 / 4, 100 * 1 / 2, @@ -1087,13 +1087,13 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate) { int rix = 0, i = 0; - int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; + static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; if (!(rate->flags & IEEE80211_TX_RC_MCS)) return rate->idx; while (rate->idx > mcs_rix_off[i] && - i < sizeof(mcs_rix_off)/sizeof(int)) { + i < ARRAY_SIZE(mcs_rix_off)) { rix++; i++; } -- cgit v1.2.3-59-g8ed1b From 5653a63d85300dbed71b76ab7ada03808bdfb170 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:54 -0800 Subject: carl9170: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 1897 56 672 2625 a41 drivers/net/wireless/ath/carl9170/cmd.o.new 1897 56 672 2625 a41 drivers/net/wireless/ath/carl9170/cmd.o.old Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index c21f3364bfec..cdfc94c371b4 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -41,7 +41,7 @@ int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) { - __le32 buf[2] = { + const __le32 buf[2] = { cpu_to_le32(reg), cpu_to_le32(val), }; -- cgit v1.2.3-59-g8ed1b From 3370a895454ad814d0fb5f50352cea4e51d7392f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:55 -0800 Subject: atmel: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 42578 720 8528 51826 ca72 drivers/net/wireless/atmel.o.old 42578 720 8528 51826 ca72 drivers/net/wireless/atmel.o.new Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/atmel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index c8f7090b27d3..46e382ed46aa 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1161,7 +1161,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id) struct atmel_private *priv = netdev_priv(dev); u8 isr; int i = -1; - static u8 irq_order[] = { + static const u8 irq_order[] = { ISR_OUT_OF_RANGE, ISR_RxCOMPLETE, ISR_TxCOMPLETE, @@ -3771,7 +3771,9 @@ static int probe_atmel_card(struct net_device *dev) if (rc) { if (dev->dev_addr[0] == 0xFF) { - u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00}; + static const u8 default_mac[] = { + 0x00, 0x04, 0x25, 0x00, 0x00, 0x00 + }; printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name); memcpy(dev->dev_addr, default_mac, 6); } -- cgit v1.2.3-59-g8ed1b From 5b4bc649e18539a5d5a5482670d77f3f72de0eea Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:56 -0800 Subject: b43: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 5502 56 1336 6894 1aee drivers/net/wireless/b43/phy_common.o.new 5511 56 1336 6903 1af7 drivers/net/wireless/b43/phy_common.o.old Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 7b2ea6781457..fa7f83fc8db9 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -427,9 +427,11 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) /* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ struct b43_c32 b43_cordic(int theta) { - u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, - 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, - 229, 115, 57, 29, }; + static const u32 arctg[] = { + 2949120, 1740967, 919879, 466945, 234379, 117304, + 58666, 29335, 14668, 7334, 3667, 1833, + 917, 458, 229, 115, 57, 29, + }; u8 i; s32 tmp; s8 signx = 1; -- cgit v1.2.3-59-g8ed1b From 20407ed8a5bb271dd8e8bd4678e1d3dadeb318bd Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:57 -0800 Subject: iwlwifi: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 48644 57 12120 60821 ed95 drivers/net/wireless/b43/phy_n.o.new 48661 57 12120 60838 eda6 drivers/net/wireless/b43/phy_n.o.old 37906 86 7904 45896 b348 drivers/net/wireless/iwlwifi/iwl-agn-lib.o.new 37937 86 7904 45927 b367 drivers/net/wireless/iwlwifi/iwl-agn-lib.o.old 37781 523 6752 45056 b000 drivers/net/wireless/iwlwifi/iwl-3945.o.new 37781 523 6752 45056 b000 drivers/net/wireless/iwlwifi/iwl-3945.o.old Changed b43_nphy_write_clip_detection to take a const u16 * Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 6facb8ab05d1..afbfdf0ee6e0 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -655,7 +655,8 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ -static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st) +static void b43_nphy_write_clip_detection(struct b43_wldev *dev, + const u16 *clip_st) { b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]); b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]); @@ -731,7 +732,7 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) struct b43_phy_n *nphy = phy->n; if (enable) { - u16 clip[] = { 0xFFFF, 0xFFFF }; + static const u16 clip[] = { 0xFFFF, 0xFFFF }; if (nphy->deaf_count++ == 0) { nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); b43_nphy_classifier(dev, 0x7, 0); @@ -843,7 +844,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) u16 data[4]; s16 gain[2]; u16 minmax[2]; - u16 lna_gain[4] = { -2, 10, 19, 25 }; + static const u16 lna_gain[4] = { -2, 10, 19, 25 }; if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 1); @@ -2299,7 +2300,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev) { int i, j; /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */ - u16 offset[] = { 0x186, 0x195, 0x2C5 }; + static const u16 offset[] = { 0x186, 0x195, 0x2C5 }; for (i = 0; i < 3; i++) for (j = 0; j < 15; j++) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 56f4ca7e49d9..d39f449a9bb0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -116,7 +116,7 @@ void iwl3945_disable_events(struct iwl_priv *priv) u32 base; /* SRAM address of event log header */ u32 disable_ptr; /* SRAM address of event-disable bitmap array */ u32 array_size; /* # of u32 entries in array */ - u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { + static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { 0x00000000, /* 31 - 0 Event id numbers */ 0x00000000, /* 63 - 32 */ 0x00000000, /* 95 - 64 */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 881475cf5ad7..c4491f7641fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1996,7 +1996,7 @@ static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv, struct iwl_bt_uart_msg *uart_msg) { u8 kill_ack_msk; - __le32 bt_kill_ack_msg[2] = { + static const __le32 bt_kill_ack_msg[2] = { cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | @@ -2280,7 +2280,7 @@ static const char *get_csr_string(int cmd) void iwl_dump_csr(struct iwl_priv *priv) { int i; - u32 csr_tbl[] = { + static const u32 csr_tbl[] = { CSR_HW_IF_CONFIG_REG, CSR_INT_COALESCING, CSR_INT, @@ -2339,7 +2339,7 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) int pos = 0; size_t bufsz = 0; #endif - u32 fh_tbl[] = { + static const u32 fh_tbl[] = { FH_RSCSR_CHNL0_STTS_WPTR_REG, FH_RSCSR_CHNL0_RBDCB_BASE_REG, FH_RSCSR_CHNL0_WPTR, -- cgit v1.2.3-59-g8ed1b From 482e039f2a6546ee2ecf718ae6c02e84d1a7f00b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:58 -0800 Subject: libertas: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 3650 56 704 4410 113a drivers/net/wireless/libertas/rx.o.new 3695 56 704 4455 1167 drivers/net/wireless/libertas/rx.o.old 27328 964 5240 33532 82fc drivers/net/wireless/libertas/cfg.o.new 27328 964 5240 33532 82fc drivers/net/wireless/libertas/cfg.o.old Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 2 +- drivers/net/wireless/libertas/rx.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 73b2beef86b1..a90953678b99 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -2059,7 +2059,7 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv) }; /* Section 5.17.2 */ - static struct region_code_mapping regmap[] = { + static const struct region_code_mapping regmap[] = { {"US ", 0x10}, /* US FCC */ {"CA ", 0x20}, /* Canada */ {"EU ", 0x30}, /* ETSI */ diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index a4d0bca9ef2c..a2b1df21d286 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -55,7 +55,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) struct rxpd *p_rx_pd; int hdrchop; struct ethhdr *p_ethhdr; - const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; + static const u8 rfc1042_eth_hdr[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 + }; lbs_deb_enter(LBS_DEB_RX); -- cgit v1.2.3-59-g8ed1b From ff273b91ff04e6f232234b70c45101074a0daa27 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:38:59 -0800 Subject: ray_cs: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 42607 3581 8536 54724 d5c4 drivers/net/wireless/ray_cs.o.new 42603 3585 8536 54724 d5c4 drivers/net/wireless/ray_cs.o.old Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ray_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 97007d9e2c1f..2b1cbba90a84 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -2286,8 +2286,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) struct ethhdr *peth; UCHAR srcaddr[ADDRLEN]; UCHAR destaddr[ADDRLEN]; - static UCHAR org_bridge[3] = { 0, 0, 0xf8 }; - static UCHAR org_1042[3] = { 0, 0, 0 }; + static const UCHAR org_bridge[3] = { 0, 0, 0xf8 }; + static const UCHAR org_1042[3] = { 0, 0, 0 }; memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN); memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN); -- cgit v1.2.3-59-g8ed1b From 22288a5847df30fb8ba298914f144c3b1d6e1fbe Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:39:00 -0800 Subject: rndis_wlan: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 41757 2205 9896 53858 d262 drivers/net/wireless/rndis_wlan.o.old 41653 2205 9880 53738 d1ea drivers/net/wireless/rndis_wlan.o.new Changed functions rndis_set_oid and set_bssid to take const *'s. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index ee08bcaaf47a..19f3d568f700 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -817,7 +817,8 @@ exit_unlock: return ret; } -static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) +static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data, + int len) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); union { @@ -1033,7 +1034,7 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) return ret; } -static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) +static int set_bssid(struct usbnet *usbdev, const u8 *bssid) { int ret; @@ -1049,7 +1050,9 @@ static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) static int clear_bssid(struct usbnet *usbdev) { - u8 broadcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + static const u8 broadcast_mac[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; return set_bssid(usbdev, broadcast_mac); } -- cgit v1.2.3-59-g8ed1b From f4e16e41d62ddc75704a0344567a807ebb41a929 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:39:01 -0800 Subject: rt2x00: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 40197 56 8336 48589 bdcd drivers/net/wireless/rt2x00/rt2800lib.o.new 40205 56 8336 48597 bdd5 drivers/net/wireless/rt2x00/rt2800lib.o.old Signed-off-by: Joe Perches Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ce8df66a3de8..75631614aba3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2166,7 +2166,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) SHARED_KEY_MODE_ENTRY(i), 0); for (i = 0; i < 256; i++) { - u32 wcid[2] = { 0xffffffff, 0x00ffffff }; + static const u32 wcid[2] = { 0xffffffff, 0x00ffffff }; rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), wcid, sizeof(wcid)); -- cgit v1.2.3-59-g8ed1b From 7253965a1cfbd22dd20f92b7a054e831777e284e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 20 Nov 2010 18:39:03 -0800 Subject: zd1211rw: Use const Mark arrays const that are unmodified after initializations. text data bss dec hex filename 19291 56 4136 23483 5bbb drivers/net/wireless/zd1211rw/zd_chip.o.old 19291 56 4136 23483 5bbb drivers/net/wireless/zd1211rw/zd_chip.o.new Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 87a95bcfee57..30f8d404958b 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1448,7 +1448,7 @@ int zd_rfwritev_locked(struct zd_chip *chip, */ int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value) { - struct zd_ioreq16 ioreqs[] = { + const struct zd_ioreq16 ioreqs[] = { { CR244, (value >> 16) & 0xff }, { CR243, (value >> 8) & 0xff }, { CR242, value & 0xff }, @@ -1475,7 +1475,7 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip, int zd_chip_set_multicast_hash(struct zd_chip *chip, struct zd_mc_hash *hash) { - struct zd_ioreq32 ioreqs[] = { + const struct zd_ioreq32 ioreqs[] = { { CR_GROUP_HASH_P1, hash->low }, { CR_GROUP_HASH_P2, hash->high }, }; -- cgit v1.2.3-59-g8ed1b From 02d2ebb2a0aa2cae0446289c8f927067aec06079 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 22 Nov 2010 15:39:39 +0100 Subject: ath9k_hw: fix A-MPDU key search issues on AR9003 Under load, a large number of frames can produce decryption errors, even when no key cache update is being done. Performing a key search for every single frame in an A-MPDU improves reliability. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++++ drivers/net/wireless/ath/ath9k/reg.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fd4fdb57e570..c686987c4840 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1817,6 +1817,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; + /* enable key search for every frame in an aggregate */ + if (AR_SREV_9300_20_OR_LATER(ah)) + ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; + pCap->low_2ghz_chan = 2312; pCap->high_2ghz_chan = 2732; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 60826b82f4a2..f6058b439fb3 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1568,6 +1568,7 @@ enum { #define AR_PCU_TBTT_PROTECT 0x00200000 #define AR_PCU_CLEAR_VMF 0x01000000 #define AR_PCU_CLEAR_BA_VALID 0x04000000 +#define AR_PCU_ALWAYS_PERFORM_KEYSEARCH 0x10000000 #define AR_PCU_BT_ANT_PREVENT_RX 0x00100000 #define AR_PCU_BT_ANT_PREVENT_RX_S 20 -- cgit v1.2.3-59-g8ed1b From f8afa42b01c7a9f45b7cbaadb0481a0eeb96f18d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 22 Nov 2010 18:26:51 +0100 Subject: ath9k_htc: fix eeprom access wireless-testing commit a05b5d45049d60a06a1b12976150572304a51928 ath9k: add support for reading eeprom from platform data on PCI devices This change moved the initialization of the AH_USE_EEPROM flag from ath9k_hw to ath9k. This needs to be added to ath9k_htc as well Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8f05fc98721c..f214e8e581ca 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -639,6 +639,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ah->hw_version.devid = devid; ah->hw_version.subsysid = 0; /* FIXME */ + ah->ah_flags |= AH_USE_EEPROM; priv->ah = ah; common = ath9k_hw_common(ah); -- cgit v1.2.3-59-g8ed1b From 6735329934e9acc1941a991ed6f6ad4be3e082a5 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 18 Nov 2010 15:19:02 +0200 Subject: wl12xx: Fix kernel crash related to hw recovery and interface shutdown It is possible that the op_remove_interface function is invoked exactly at the same time has hw recovery is started. In this case it is possible for the interface to be already removed in the op_remove_interface call, which currently leads to a kernel warning and a subsequent kernel crash. Fix this by ignoring the op_remove_interface call if the interface is already down at that point. Signed-off-by: Juuso Oikarinen Tested-by: Tuomas Katila Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 708ffe304c6d..35cfcf675795 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1157,10 +1157,16 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, struct wl1271 *wl = hw->priv; mutex_lock(&wl->mutex); - WARN_ON(wl->vif != vif); - __wl1271_op_remove_interface(wl); - mutex_unlock(&wl->mutex); + /* + * wl->vif can be null here if someone shuts down the interface + * just when hardware recovery has been started. + */ + if (wl->vif) { + WARN_ON(wl->vif != vif); + __wl1271_op_remove_interface(wl); + } + mutex_unlock(&wl->mutex); cancel_work_sync(&wl->recovery_work); } -- cgit v1.2.3-59-g8ed1b From 04f6d70f6e64900a5d70a5fc199dd9d5fa787738 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 23 Nov 2010 06:28:02 +0000 Subject: SELinux: Only return netlink error when we know the return is fatal Some of the SELinux netlink code returns a fatal error when the error might actually be transient. This patch just silently drops packets on potentially transient errors but continues to return a permanant error indicator when the denial was because of policy. Based-on-comments-by: Paul Moore Signed-off-by: Eric Paris Reviewed-by: Paul Moore Signed-off-by: David S. Miller --- security/selinux/hooks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2c145f12d991..f590fb8e9143 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4589,7 +4589,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, } if (secmark_perm == PACKET__FORWARD_OUT) { if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; } else peer_sid = SECINITSID_KERNEL; } else { @@ -4602,7 +4602,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, ad.u.net.netif = ifindex; ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (secmark_active) if (avc_has_perm(peer_sid, skb->secmark, @@ -4614,13 +4614,13 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, u32 node_sid; if (sel_netif_sid(ifindex, &if_sid)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (avc_has_perm(peer_sid, if_sid, SECCLASS_NETIF, NETIF__EGRESS, &ad)) return NF_DROP_ERR(-ECONNREFUSED); if (sel_netnode_sid(addrp, family, &node_sid)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (avc_has_perm(peer_sid, node_sid, SECCLASS_NODE, NODE__SENDTO, &ad)) return NF_DROP_ERR(-ECONNREFUSED); -- cgit v1.2.3-59-g8ed1b From 2fe66ec242d3f76e3b0101f36419e7e5405bcff3 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 23 Nov 2010 06:28:08 +0000 Subject: SELinux: indicate fatal error in compat netfilter code The SELinux ip postroute code indicates when policy rejected a packet and passes the error back up the stack. The compat code does not. This patch sends the same kind of error back up the stack in the compat code. Based-on-patch-by: Paul Moore Signed-off-by: Eric Paris Reviewed-by: Paul Moore Signed-off-by: David S. Miller --- security/selinux/hooks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f590fb8e9143..156ef93d6f7d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4524,11 +4524,11 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, if (selinux_secmark_enabled()) if (avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET, PACKET__SEND, &ad)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); if (selinux_policycap_netpeer) if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) - return NF_DROP; + return NF_DROP_ERR(-ECONNREFUSED); return NF_ACCEPT; } -- cgit v1.2.3-59-g8ed1b From 5093eedc8bdfd7d906836a44a248f66a99e27d22 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:45 +0000 Subject: tg3: Apply 10Mbps fix to all 57765 revisions Commit a977dbe8445b8a81d6127c4aa9112a2c29a1a008, entitled "tg3: Reduce 57765 core clock when link at 10Mbps" needs to be applied to all revisions of the 57765 asic rev, not just the A0 revision. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 30ccbb6d097a..ca6b3cbf44d5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7860,18 +7860,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(GRC_MODE, grc_mode); } - if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) { - u32 grc_mode = tr32(GRC_MODE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) { + u32 grc_mode = tr32(GRC_MODE); - /* Access the lower 1K of PL PCIE block registers. */ - val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; - tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); + /* Access the lower 1K of PL PCIE block registers. */ + val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; + tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); - val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5); - tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5, - val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ); + val = tr32(TG3_PCIE_TLDLPL_PORT + + TG3_PCIE_PL_LO_PHYCTL5); + tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5, + val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ); - tw32(GRC_MODE, grc_mode); + tw32(GRC_MODE, grc_mode); + } val = tr32(TG3_CPMU_LSPD_10MB_CLK); val &= ~CPMU_LSPD_10MB_MACCLK_MASK; -- cgit v1.2.3-59-g8ed1b From b75cc0e4c1caac63941d96a73b2214e8007b934b Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:46 +0000 Subject: tg3: Assign correct tx margin for 5719 Commit d309a46e42542223946d3a9e4e239fdc945cb53e, entitled "tg3: 5719: Prevent tx data corruption", was supposed to contain the tx margin adjustment but it looks like it somehow was omitted. This patch fixes the problem. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++++ drivers/net/tg3.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ca6b3cbf44d5..4dc07564e141 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8206,6 +8206,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + val &= ~TG3_RDMA_RSRVCTRL_TXMRGN_MASK; + val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B; + } tw32(TG3_RDMA_RSRVCTRL_REG, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4a1974804b9f..06a4e7e8fff3 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1327,6 +1327,8 @@ #define TG3_RDMA_RSRVCTRL_REG 0x00004900 #define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 +#define TG3_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000 +#define TG3_RDMA_RSRVCTRL_TXMRGN_MASK 0xffe00000 /* 0x4904 --> 0x4910 unused */ #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 -- cgit v1.2.3-59-g8ed1b From d2394e6bb1aa636f3bd142cb6f7845a4332514b5 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:47 +0000 Subject: tg3: Always turn on APE features in mac_mode reg The APE needs certain bits in the mac_mode register to be enabled for traffic to flow correctly. This patch changes the code to always enable these bits in the presence of the APE. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4dc07564e141..2624d714d16e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2728,12 +2728,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))) mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL; - if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { - mac_mode |= tp->mac_mode & - (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); - if (mac_mode & MAC_MODE_APE_TX_EN) - mac_mode |= MAC_MODE_TDE_ENABLE; - } + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) + mac_mode |= MAC_MODE_APE_TX_EN | + MAC_MODE_APE_RX_EN | + MAC_MODE_TDE_ENABLE; tw32_f(MAC_MODE, mac_mode); udelay(100); @@ -7222,19 +7220,21 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) + tp->mac_mode = MAC_MODE_APE_TX_EN | + MAC_MODE_APE_RX_EN | + MAC_MODE_TDE_ENABLE; + if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_TBI; - tw32_f(MAC_MODE, tp->mac_mode); + tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; + val = tp->mac_mode; } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_GMII; - tw32_f(MAC_MODE, tp->mac_mode); - } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { - tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); - if (tp->mac_mode & MAC_MODE_APE_TX_EN) - tp->mac_mode |= MAC_MODE_TDE_ENABLE; - tw32_f(MAC_MODE, tp->mac_mode); + tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; + val = tp->mac_mode; } else - tw32_f(MAC_MODE, 0); + val = 0; + + tw32_f(MAC_MODE, val); udelay(40); tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); @@ -8287,7 +8287,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; else tp->mac_mode = 0; tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | @@ -13729,8 +13729,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Preserve the APE MAC_MODE bits */ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - tp->mac_mode = tr32(MAC_MODE) | - MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; else tp->mac_mode = TG3_DEF_MAC_MODE; -- cgit v1.2.3-59-g8ed1b From cf79003d598b1f82a4caa0564107283b4f560e14 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:48 +0000 Subject: tg3: Fix 5719 internal FIFO overflow problem Under load, there an internal FIFO can overflow on the 5719. The fix is to scale back the PCIe maximum read request size based on the current link speed and width. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 44 +++++++++++++++++++++++++++++++++++++++++--- drivers/net/tg3.h | 1 + 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2624d714d16e..226e60dfaeaf 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6985,7 +6985,7 @@ static void tg3_restore_pci_state(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) { if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) - pcie_set_readrq(tp->pdev, 4096); + pcie_set_readrq(tp->pdev, tp->pcie_readrq); else { pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, tp->pci_cacheline_sz); @@ -7179,7 +7179,7 @@ static int tg3_chip_reset(struct tg3 *tp) tp->pcie_cap + PCI_EXP_DEVCTL, val16); - pcie_set_readrq(tp->pdev, 4096); + pcie_set_readrq(tp->pdev, tp->pcie_readrq); /* Clear error status */ pci_write_config_word(tp->pdev, @@ -13366,7 +13366,45 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; - pcie_set_readrq(tp->pdev, 4096); + tp->pcie_readrq = 4096; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + u16 word; + + pci_read_config_word(tp->pdev, + tp->pcie_cap + PCI_EXP_LNKSTA, + &word); + switch (word & PCI_EXP_LNKSTA_CLS) { + case PCI_EXP_LNKSTA_CLS_2_5GB: + word &= PCI_EXP_LNKSTA_NLW; + word >>= PCI_EXP_LNKSTA_NLW_SHIFT; + switch (word) { + case 2: + tp->pcie_readrq = 2048; + break; + case 4: + tp->pcie_readrq = 1024; + break; + } + break; + + case PCI_EXP_LNKSTA_CLS_5_0GB: + word &= PCI_EXP_LNKSTA_NLW; + word >>= PCI_EXP_LNKSTA_NLW_SHIFT; + switch (word) { + case 1: + tp->pcie_readrq = 2048; + break; + case 2: + tp->pcie_readrq = 1024; + break; + case 4: + tp->pcie_readrq = 512; + break; + } + } + } + + pcie_set_readrq(tp->pdev, tp->pcie_readrq); pci_read_config_word(tp->pdev, tp->pcie_cap + PCI_EXP_LNKCTL, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 06a4e7e8fff3..410703684e39 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2948,6 +2948,7 @@ struct tg3 { int pcix_cap; int pcie_cap; }; + int pcie_readrq; struct mii_bus *mdio_bus; int mdio_irq[PHY_MAX_ADDR]; -- cgit v1.2.3-59-g8ed1b From 07ae8fc00bcc97d2f896b257da225a0789b0aa5d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:49 +0000 Subject: tg3: Reorg tg3_napi members This patch reorders and realigns the tg3_napi members for a ~3-4% performance improvement on small packet performance tests. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 410703684e39..2938d18d12f7 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2715,17 +2715,17 @@ struct tg3_napi { u32 last_irq_tag; u32 int_mbox; u32 coal_now; - u32 tx_prod; - u32 tx_cons; - u32 tx_pending; - u32 prodmbox; - u32 consmbox; + u32 consmbox ____cacheline_aligned; u32 rx_rcb_ptr; u16 *rx_rcb_prod_idx; struct tg3_rx_prodring_set prodring; - struct tg3_rx_buffer_desc *rx_rcb; + + u32 tx_prod ____cacheline_aligned; + u32 tx_cons; + u32 tx_pending; + u32 prodmbox; struct tg3_tx_buffer_desc *tx_ring; struct ring_info *tx_buffers; -- cgit v1.2.3-59-g8ed1b From deabaac8beeccdfee5358c0cd4c63258f28f3a74 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:50 +0000 Subject: tg3: Enable mult rd DMA engine on 5719 The multiple DMA read engine bugs have been fixed on the 5719. This patch reenables support for this feature. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 226e60dfaeaf..4fa8ee30b70f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8165,8 +8165,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || -- cgit v1.2.3-59-g8ed1b From b92b9040f6e4997b895b7b9c655a158354d28964 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:51 +0000 Subject: tg3: Reenable TSS for 5719 All TSS bugs have been fixed in the 5719. This patch reenables the feature. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4fa8ee30b70f..75ebebc9115a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9037,8 +9037,14 @@ static bool tg3_enable_msix(struct tg3 *tp) pci_disable_msix(tp->pdev); return false; } - if (tp->irq_cnt > 1) + + if (tp->irq_cnt > 1) { tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; + netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1); + } + } return true; } -- cgit v1.2.3-59-g8ed1b From 4bae65c892b4ff9a2797cbfa8526a5f9aaf1b2ed Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:52 +0000 Subject: tg3: use dma_alloc_coherent() instead of pci_alloc_consistent() Using dma_alloc_coherent() permits to use GFP_KERNEL allocations instead of GFP_ATOMIC ones. Its better when a machine is out of memory, because this allows driver to sleep to get its memory and succeed its init, especially when allocating high order pages. Signed-off-by: Eric Dumazet Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 75ebebc9115a..3079e1f540fd 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6337,13 +6337,13 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, kfree(tpr->rx_jmb_buffers); tpr->rx_jmb_buffers = NULL; if (tpr->rx_std) { - pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), - tpr->rx_std, tpr->rx_std_mapping); + dma_free_coherent(&tp->pdev->dev, TG3_RX_STD_RING_BYTES(tp), + tpr->rx_std, tpr->rx_std_mapping); tpr->rx_std = NULL; } if (tpr->rx_jmb) { - pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp), - tpr->rx_jmb, tpr->rx_jmb_mapping); + dma_free_coherent(&tp->pdev->dev, TG3_RX_JMB_RING_BYTES(tp), + tpr->rx_jmb, tpr->rx_jmb_mapping); tpr->rx_jmb = NULL; } } @@ -6356,8 +6356,10 @@ static int tg3_rx_prodring_init(struct tg3 *tp, if (!tpr->rx_std_buffers) return -ENOMEM; - tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), - &tpr->rx_std_mapping); + tpr->rx_std = dma_alloc_coherent(&tp->pdev->dev, + TG3_RX_STD_RING_BYTES(tp), + &tpr->rx_std_mapping, + GFP_KERNEL); if (!tpr->rx_std) goto err_out; @@ -6368,9 +6370,10 @@ static int tg3_rx_prodring_init(struct tg3 *tp, if (!tpr->rx_jmb_buffers) goto err_out; - tpr->rx_jmb = pci_alloc_consistent(tp->pdev, - TG3_RX_JMB_RING_BYTES(tp), - &tpr->rx_jmb_mapping); + tpr->rx_jmb = dma_alloc_coherent(&tp->pdev->dev, + TG3_RX_JMB_RING_BYTES(tp), + &tpr->rx_jmb_mapping, + GFP_KERNEL); if (!tpr->rx_jmb) goto err_out; } @@ -6489,7 +6492,7 @@ static void tg3_free_consistent(struct tg3 *tp) struct tg3_napi *tnapi = &tp->napi[i]; if (tnapi->tx_ring) { - pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES, + dma_free_coherent(&tp->pdev->dev, TG3_TX_RING_BYTES, tnapi->tx_ring, tnapi->tx_desc_mapping); tnapi->tx_ring = NULL; } @@ -6498,25 +6501,26 @@ static void tg3_free_consistent(struct tg3 *tp) tnapi->tx_buffers = NULL; if (tnapi->rx_rcb) { - pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), - tnapi->rx_rcb, - tnapi->rx_rcb_mapping); + dma_free_coherent(&tp->pdev->dev, + TG3_RX_RCB_RING_BYTES(tp), + tnapi->rx_rcb, + tnapi->rx_rcb_mapping); tnapi->rx_rcb = NULL; } tg3_rx_prodring_fini(tp, &tnapi->prodring); if (tnapi->hw_status) { - pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE, - tnapi->hw_status, - tnapi->status_mapping); + dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE, + tnapi->hw_status, + tnapi->status_mapping); tnapi->hw_status = NULL; } } if (tp->hw_stats) { - pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats), - tp->hw_stats, tp->stats_mapping); + dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), + tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } } @@ -6529,9 +6533,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) { int i; - tp->hw_stats = pci_alloc_consistent(tp->pdev, - sizeof(struct tg3_hw_stats), - &tp->stats_mapping); + tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev, + sizeof(struct tg3_hw_stats), + &tp->stats_mapping, + GFP_KERNEL); if (!tp->hw_stats) goto err_out; @@ -6541,9 +6546,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) struct tg3_napi *tnapi = &tp->napi[i]; struct tg3_hw_status *sblk; - tnapi->hw_status = pci_alloc_consistent(tp->pdev, - TG3_HW_STATUS_SIZE, - &tnapi->status_mapping); + tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev, + TG3_HW_STATUS_SIZE, + &tnapi->status_mapping, + GFP_KERNEL); if (!tnapi->hw_status) goto err_out; @@ -6564,9 +6570,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!tnapi->tx_buffers) goto err_out; - tnapi->tx_ring = pci_alloc_consistent(tp->pdev, - TG3_TX_RING_BYTES, - &tnapi->tx_desc_mapping); + tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev, + TG3_TX_RING_BYTES, + &tnapi->tx_desc_mapping, + GFP_KERNEL); if (!tnapi->tx_ring) goto err_out; } @@ -6599,9 +6606,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) continue; - tnapi->rx_rcb = pci_alloc_consistent(tp->pdev, - TG3_RX_RCB_RING_BYTES(tp), - &tnapi->rx_rcb_mapping); + tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev, + TG3_RX_RCB_RING_BYTES(tp), + &tnapi->rx_rcb_mapping, + GFP_KERNEL); if (!tnapi->rx_rcb) goto err_out; @@ -14208,7 +14216,8 @@ static int __devinit tg3_test_dma(struct tg3 *tp) u32 *buf, saved_dma_rwctrl; int ret = 0; - buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma); + buf = dma_alloc_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, + &buf_dma, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out_nofree; @@ -14392,7 +14401,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } out: - pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma); + dma_free_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, buf, buf_dma); out_nofree: return ret; } -- cgit v1.2.3-59-g8ed1b From 2e1e3291d4727e14c8f0f48df561afb1a5c26ffe Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:53 +0000 Subject: tg3: Enable phy APD for 5717 and later asic revs This patch enables the gphy autopowerdown feature in the phy for all new devices that support it. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3079e1f540fd..afb79db5327e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12431,8 +12431,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (cfg2 & (1 << 18)) tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS; - if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && - GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) && + if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) || + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && + GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) && (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN)) tp->phy_flags |= TG3_PHYFLG_ENABLE_APD; -- cgit v1.2.3-59-g8ed1b From 37a118452cbc9c0cf0d23bfd16d3ca56058be754 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 24 Nov 2010 08:31:54 +0000 Subject: tg3: Remove tg3_config_info definition This structure isn't used anywhere in the driver. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 2938d18d12f7..59b0e096149e 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2564,10 +2564,6 @@ struct ring_info { DEFINE_DMA_UNMAP_ADDR(mapping); }; -struct tg3_config_info { - u32 flags; -}; - struct tg3_link_config { /* Describes what we're trying to get. */ u32 advertising; -- cgit v1.2.3-59-g8ed1b From e1210d127d11fc40d229648c9754aa60776ef796 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 24 Nov 2010 03:45:10 +0000 Subject: bnx2x: Disable local BHes to prevent a dead-lock situation According to Eric's suggestion: Disable local BHes to prevent a dead-lock situation between sch_direct_xmit() (Soft_IRQ context) and bnx2x_tx_int (called by bnx2x_run_loopback() - syscall context), as both are taking a netif_tx_lock(). Signed-off-by: Eric Dumazet Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index d02ffbdc9f0e..03012787de2f 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1499,8 +1499,15 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) * updates that have been performed while interrupts were * disabled. */ - if (bp->common.int_block == INT_BLOCK_IGU) + if (bp->common.int_block == INT_BLOCK_IGU) { + /* Disable local BHes to prevent a dead-lock situation between + * sch_direct_xmit() and bnx2x_run_loopback() (calling + * bnx2x_tx_int()), as both are taking netif_tx_lock(). + */ + local_bh_disable(); bnx2x_tx_int(fp_tx); + local_bh_enable(); + } rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) -- cgit v1.2.3-59-g8ed1b From b340007f79941297c44a7dfba4d3c587ff81590f Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 24 Nov 2010 11:09:50 -0800 Subject: bnx2x: Do interrupt mode initialization and NAPIs adding before register_netdev() Move the interrupt mode configuration and NAPIs adding before a register_netdev() call to prevent netdev->open() from running before these functions are done. Advance a driver version number. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Reported-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- drivers/net/bnx2x/bnx2x_main.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fbe..342ab58b14b3 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-4" -#define DRV_MODULE_RELDATE "2010/11/01" +#define DRV_MODULE_VERSION "1.60.00-5" +#define DRV_MODULE_RELDATE "2010/11/24" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 92057d7058da..f53edfd011bf 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9096,12 +9096,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* calc qm_cid_count */ bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); - rc = register_netdev(dev); - if (rc) { - dev_err(&pdev->dev, "Cannot register net device\n"); - goto init_one_exit; - } - /* Configure interupt mode: try to enable MSI-X/MSI if * needed, set bp->num_queues appropriately. */ @@ -9110,6 +9104,12 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* Add all NAPI objects */ bnx2x_add_all_napi(bp); + rc = register_netdev(dev); + if (rc) { + dev_err(&pdev->dev, "Cannot register net device\n"); + goto init_one_exit; + } + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," -- cgit v1.2.3-59-g8ed1b From 9dfeb4d953f914bd3bb56ce60e22ee84687399ce Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 24 Nov 2010 02:37:58 +0000 Subject: stmmac: tidy-up stmmac_priv structure This patch tidies-up the stmmac_priv structure that had many fileds alredy defined in the plat_stmmacenet_data structure. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 15 ++------ drivers/net/stmmac/stmmac_ethtool.c | 4 +-- drivers/net/stmmac/stmmac_main.c | 69 +++++++++++++++++++------------------ drivers/net/stmmac/stmmac_mdio.c | 8 ++--- 4 files changed, 44 insertions(+), 52 deletions(-) diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 79bdc2e13224..31575670d862 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -37,7 +37,6 @@ struct stmmac_priv { unsigned int cur_tx; unsigned int dirty_tx; unsigned int dma_tx_size; - int tx_coe; int tx_coalesce; struct dma_desc *dma_rx ; @@ -48,7 +47,6 @@ struct stmmac_priv { struct sk_buff_head rx_recycle; struct net_device *dev; - int is_gmac; dma_addr_t dma_rx_phy; unsigned int dma_rx_size; unsigned int dma_buf_sz; @@ -60,14 +58,11 @@ struct stmmac_priv { struct napi_struct napi; phy_interface_t phy_interface; - int pbl; - int bus_id; int phy_addr; int phy_mask; int (*phy_reset) (void *priv); - void (*fix_mac_speed) (void *priv, unsigned int speed); - void (*bus_setup)(void __iomem *ioaddr); - void *bsp_priv; + int rx_coe; + int no_csum_insertion; int phy_irq; struct phy_device *phydev; @@ -77,7 +72,6 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; - int mii_clk_csr; u32 msg_enable; spinlock_t lock; @@ -90,10 +84,7 @@ struct stmmac_priv { #ifdef STMMAC_VLAN_TAG_USED struct vlan_group *vlgrp; #endif - int enh_desc; - int rx_coe; - int bugged_jumbo; - int no_csum_insertion; + struct plat_stmmacenet_data *plat; }; #ifdef CONFIG_STM_DRIVERS diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 6d65482e789a..f2695fd180ca 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -94,7 +94,7 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev, { struct stmmac_priv *priv = netdev_priv(dev); - if (!priv->is_gmac) + if (!priv->plat->has_gmac) strcpy(info->driver, MAC100_ETHTOOL_NAME); else strcpy(info->driver, GMAC_ETHTOOL_NAME); @@ -176,7 +176,7 @@ static void stmmac_ethtool_gregs(struct net_device *dev, memset(reg_space, 0x0, REG_SPACE_SIZE); - if (!priv->is_gmac) { + if (!priv->plat->has_gmac) { /* MAC registers */ for (i = 0; i < 12; i++) reg_space[i] = readl(priv->ioaddr + (i * 4)); diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 06bc6034ce81..29ba28660fa9 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -186,6 +186,18 @@ static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; } +/* On some ST platforms, some HW system configuraton registers have to be + * set according to the link speed negotiated. + */ +static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) +{ + struct phy_device *phydev = priv->phydev; + + if (likely(priv->plat->fix_mac_speed)) + priv->plat->fix_mac_speed(priv->plat->bsp_priv, + phydev->speed); +} + /** * stmmac_adjust_link * @dev: net device structure @@ -228,15 +240,13 @@ static void stmmac_adjust_link(struct net_device *dev) new_state = 1; switch (phydev->speed) { case 1000: - if (likely(priv->is_gmac)) + if (likely(priv->plat->has_gmac)) ctrl &= ~priv->hw->link.port; - if (likely(priv->fix_mac_speed)) - priv->fix_mac_speed(priv->bsp_priv, - phydev->speed); + stmmac_hw_fix_mac_speed(priv); break; case 100: case 10: - if (priv->is_gmac) { + if (priv->plat->has_gmac) { ctrl |= priv->hw->link.port; if (phydev->speed == SPEED_100) { ctrl |= priv->hw->link.speed; @@ -246,9 +256,7 @@ static void stmmac_adjust_link(struct net_device *dev) } else { ctrl &= ~priv->hw->link.port; } - if (likely(priv->fix_mac_speed)) - priv->fix_mac_speed(priv->bsp_priv, - phydev->speed); + stmmac_hw_fix_mac_speed(priv); break; default: if (netif_msg_link(priv)) @@ -305,7 +313,7 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } - snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id); + snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, priv->phy_addr); pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); @@ -552,7 +560,7 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { - if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) { + if (likely((priv->plat->tx_coe) && (!priv->no_csum_insertion))) { /* In case of GMAC, SF mode has to be enabled * to perform the TX COE. This depends on: * 1) TX COE if actually supported @@ -814,7 +822,7 @@ static int stmmac_open(struct net_device *dev) init_dma_desc_rings(dev); /* DMA initialization and SW reset */ - if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl, + if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) { @@ -825,15 +833,15 @@ static int stmmac_open(struct net_device *dev) /* Copy the MAC addr into the HW */ priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); /* If required, perform hw setup of the bus. */ - if (priv->bus_setup) - priv->bus_setup(priv->ioaddr); + if (priv->plat->bus_setup) + priv->plat->bus_setup(priv->ioaddr); /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); if (priv->rx_coe) pr_info("stmmac: Rx Checksum Offload Engine supported\n"); - if (priv->tx_coe) + if (priv->plat->tx_coe) pr_info("\tTX Checksum insertion supported\n"); priv->shutdown = 0; @@ -1042,7 +1050,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return stmmac_sw_tso(priv, skb); if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { - if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion))) + if (unlikely((!priv->plat->tx_coe) || + (priv->no_csum_insertion))) skb_checksum_help(skb); else csum_insertion = 1; @@ -1146,7 +1155,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) DMA_FROM_DEVICE); (p + entry)->des2 = priv->rx_skbuff_dma[entry]; - if (unlikely(priv->is_gmac)) { + if (unlikely(priv->plat->has_gmac)) { if (bfsize >= BUF_SIZE_8KiB) (p + entry)->des3 = (p + entry)->des2 + BUF_SIZE_8KiB; @@ -1356,7 +1365,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return -EBUSY; } - if (priv->is_gmac) + if (priv->plat->has_gmac) max_mtu = JUMBO_LEN; else max_mtu = ETH_DATA_LEN; @@ -1370,7 +1379,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) * needs to have the Tx COE disabled for oversized frames * (due to limited buffer sizes). In this case we disable * the TX csum insertionin the TDES and not use SF. */ - if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) + if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) priv->no_csum_insertion = 1; else priv->no_csum_insertion = 0; @@ -1390,7 +1399,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_NONE; } - if (priv->is_gmac) + if (priv->plat->has_gmac) /* To handle GMAC own interrupts */ priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); @@ -1536,7 +1545,7 @@ static int stmmac_mac_device_setup(struct net_device *dev) struct mac_device_info *device; - if (priv->is_gmac) + if (priv->plat->has_gmac) device = dwmac1000_setup(priv->ioaddr); else device = dwmac100_setup(priv->ioaddr); @@ -1544,7 +1553,7 @@ static int stmmac_mac_device_setup(struct net_device *dev) if (!device) return -ENOMEM; - if (priv->enh_desc) { + if (priv->plat->enh_desc) { device->desc = &enh_desc_ops; pr_info("\tEnhanced descriptor structure\n"); } else @@ -1598,7 +1607,7 @@ static int stmmac_associate_phy(struct device *dev, void *data) plat_dat->bus_id); /* Check that this phy is for the MAC being initialised */ - if (priv->bus_id != plat_dat->bus_id) + if (priv->plat->bus_id != plat_dat->bus_id) return 0; /* OK, this PHY is connected to the MAC. @@ -1683,13 +1692,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->device = &(pdev->dev); priv->dev = ndev; plat_dat = pdev->dev.platform_data; - priv->bus_id = plat_dat->bus_id; - priv->pbl = plat_dat->pbl; /* TLI */ - priv->mii_clk_csr = plat_dat->clk_csr; - priv->tx_coe = plat_dat->tx_coe; - priv->bugged_jumbo = plat_dat->bugged_jumbo; - priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ - priv->enh_desc = plat_dat->enh_desc; + + priv->plat = plat_dat; + priv->ioaddr = addr; /* PMT module is not integrated in all the MAC devices. */ @@ -1727,16 +1732,12 @@ static int stmmac_dvr_probe(struct platform_device *pdev) goto out; } - priv->fix_mac_speed = plat_dat->fix_mac_speed; - priv->bus_setup = plat_dat->bus_setup; - priv->bsp_priv = plat_dat->bsp_priv; - pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, pdev->id, ndev->irq, addr); /* MDIO bus Registration */ - pr_debug("\tMDIO bus (id: %d)...", priv->bus_id); + pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id); ret = stmmac_mdio_register(ndev); if (ret < 0) goto out; diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index d7441616357d..234b4068a1fc 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -53,7 +53,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) int data; u16 regValue = (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))); - regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); + regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2); do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); writel(regValue, priv->ioaddr + mii_address); @@ -85,7 +85,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) | MII_WRITE; - value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); + value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2); /* Wait until any existing MII operation is complete */ @@ -114,7 +114,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus) if (priv->phy_reset) { pr_debug("stmmac_mdio_reset: calling phy_reset\n"); - priv->phy_reset(priv->bsp_priv); + priv->phy_reset(priv->plat->bsp_priv); } /* This is a workaround for problems with the STE101P PHY. @@ -157,7 +157,7 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); new_bus->priv = ndev; new_bus->irq = irqlist; new_bus->phy_mask = priv->phy_mask; -- cgit v1.2.3-59-g8ed1b From 293bb1c41b728d4aa248fe8a0acd2b9066ff5c34 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 24 Nov 2010 02:38:05 +0000 Subject: stmmac: add init/exit callback in plat_stmmacenet_data struct This patch adds in the plat_stmmacenet_data the init and exit callbacks that can be used for invoking specific platform functions. For example, on ST targets, these call the PAD manager functions to set PIO lines and syscfg registers. The patch removes the stmmac_claim_resource only used on STM Kernels as well. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 22 ---------------------- drivers/net/stmmac/stmmac_main.c | 18 +++++++++++++----- include/linux/stmmac.h | 6 +++--- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 31575670d862..8ae76501eb74 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -87,28 +87,6 @@ struct stmmac_priv { struct plat_stmmacenet_data *plat; }; -#ifdef CONFIG_STM_DRIVERS -#include -static inline int stmmac_claim_resource(struct platform_device *pdev) -{ - int ret = 0; - struct plat_stmmacenet_data *plat_dat = pdev->dev.platform_data; - - /* Pad routing setup */ - if (IS_ERR(devm_stm_pad_claim(&pdev->dev, plat_dat->pad_config, - dev_name(&pdev->dev)))) { - printk(KERN_ERR "%s: Failed to request pads!\n", __func__); - ret = -ENODEV; - } - return ret; -} -#else -static inline int stmmac_claim_resource(struct platform_device *pdev) -{ - return 0; -} -#endif - extern int stmmac_mdio_unregister(struct net_device *ndev); extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 29ba28660fa9..b806cd3515b4 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1643,7 +1643,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) struct resource *res; void __iomem *addr = NULL; struct net_device *ndev = NULL; - struct stmmac_priv *priv; + struct stmmac_priv *priv = NULL; struct plat_stmmacenet_data *plat_dat; pr_info("STMMAC driver:\n\tplatform registration... "); @@ -1708,10 +1708,12 @@ static int stmmac_dvr_probe(struct platform_device *pdev) /* Set the I/O base addr */ ndev->base_addr = (unsigned long)addr; - /* Verify embedded resource for the platform */ - ret = stmmac_claim_resource(pdev); - if (ret < 0) - goto out; + /* Custom initialisation */ + if (priv->plat->init) { + ret = priv->plat->init(pdev); + if (unlikely(ret)) + goto out; + } /* MAC HW revice detection */ ret = stmmac_mac_device_setup(ndev); @@ -1745,6 +1747,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev) out: if (ret < 0) { + if (priv->plat->exit) + priv->plat->exit(pdev); + platform_set_drvdata(pdev, NULL); release_mem_region(res->start, resource_size(res)); if (addr != NULL) @@ -1778,6 +1783,9 @@ static int stmmac_dvr_remove(struct platform_device *pdev) stmmac_mdio_unregister(ndev); + if (priv->plat->exit) + priv->plat->exit(pdev); + platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index d66c61774d95..e10352915698 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -40,9 +40,9 @@ struct plat_stmmacenet_data { int pmt; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); -#ifdef CONFIG_STM_DRIVERS - struct stm_pad_config *pad_config; -#endif + int (*init)(struct platform_device *pdev); + void (*exit)(struct platform_device *pdev); + void *custom_cfg; void *bsp_priv; }; -- cgit v1.2.3-59-g8ed1b From 874bd42d24c2a74f5dbd65e81e175982240fecd8 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 24 Nov 2010 02:38:11 +0000 Subject: stmmac: convert to dev_pm_ops. This patch updates the PM support using the dev_pm_ops and reviews the hibernation support. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 1 - drivers/net/stmmac/stmmac_main.c | 124 ++++++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 54 deletions(-) diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 8ae76501eb74..eb258e2319e1 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -77,7 +77,6 @@ struct stmmac_priv { spinlock_t lock; int wolopts; int wolenabled; - int shutdown; #ifdef CONFIG_STMMAC_TIMER struct stmmac_timer *tm; #endif diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index b806cd3515b4..f1dbc182c8df 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -844,8 +844,6 @@ static int stmmac_open(struct net_device *dev) if (priv->plat->tx_coe) pr_info("\tTX Checksum insertion supported\n"); - priv->shutdown = 0; - /* Initialise the MMC (if present) to disable all interrupts. */ writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); @@ -1799,61 +1797,53 @@ static int stmmac_dvr_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) +static int stmmac_suspend(struct device *dev) { - struct net_device *dev = platform_get_drvdata(pdev); - struct stmmac_priv *priv = netdev_priv(dev); + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); int dis_ic = 0; - if (!dev || !netif_running(dev)) + if (!ndev || !netif_running(ndev)) return 0; spin_lock(&priv->lock); - if (state.event == PM_EVENT_SUSPEND) { - netif_device_detach(dev); - netif_stop_queue(dev); - if (priv->phydev) - phy_stop(priv->phydev); + netif_device_detach(ndev); + netif_stop_queue(ndev); + if (priv->phydev) + phy_stop(priv->phydev); #ifdef CONFIG_STMMAC_TIMER - priv->tm->timer_stop(); - if (likely(priv->tm->enable)) - dis_ic = 1; + priv->tm->timer_stop(); + if (likely(priv->tm->enable)) + dis_ic = 1; #endif - napi_disable(&priv->napi); - - /* Stop TX/RX DMA */ - priv->hw->dma->stop_tx(priv->ioaddr); - priv->hw->dma->stop_rx(priv->ioaddr); - /* Clear the Rx/Tx descriptors */ - priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, - dis_ic); - priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); - - /* Enable Power down mode by programming the PMT regs */ - if (device_can_wakeup(priv->device)) - priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); - else - stmmac_disable_mac(priv->ioaddr); - } else { - priv->shutdown = 1; - /* Although this can appear slightly redundant it actually - * makes fast the standby operation and guarantees the driver - * working if hibernation is on media. */ - stmmac_release(dev); - } + napi_disable(&priv->napi); + + /* Stop TX/RX DMA */ + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); + /* Clear the Rx/Tx descriptors */ + priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, + dis_ic); + priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); + + /* Enable Power down mode by programming the PMT regs */ + if (device_may_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); + else + stmmac_disable_mac(priv->ioaddr); spin_unlock(&priv->lock); return 0; } -static int stmmac_resume(struct platform_device *pdev) +static int stmmac_resume(struct device *dev) { - struct net_device *dev = platform_get_drvdata(pdev); - struct stmmac_priv *priv = netdev_priv(dev); + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); - if (!netif_running(dev)) + if (!netif_running(ndev)) return 0; if (priv->shutdown) { @@ -1870,10 +1860,10 @@ static int stmmac_resume(struct platform_device *pdev) * is received. Anyway, it's better to manually clear * this bit because it can generate problems while resuming * from another devices (e.g. serial console). */ - if (device_can_wakeup(priv->device)) + if (device_may_wakeup(priv->device)) priv->hw->mac->pmt(priv->ioaddr, 0); - netif_device_attach(dev); + netif_device_attach(ndev); /* Enable the MAC and DMA */ stmmac_enable_mac(priv->ioaddr); @@ -1881,31 +1871,59 @@ static int stmmac_resume(struct platform_device *pdev) priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER - priv->tm->timer_start(tmrate); + if (likely(priv->tm->enable)) + priv->tm->timer_start(tmrate); #endif napi_enable(&priv->napi); if (priv->phydev) phy_start(priv->phydev); - netif_start_queue(dev); + netif_start_queue(ndev); spin_unlock(&priv->lock); return 0; } -#endif -static struct platform_driver stmmac_driver = { - .driver = { - .name = STMMAC_RESOURCE_NAME, - }, - .probe = stmmac_dvr_probe, - .remove = stmmac_dvr_remove, -#ifdef CONFIG_PM +static int stmmac_freeze(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + + if (!ndev || !netif_running(ndev)) + return 0; + + return stmmac_release(ndev); +} + +static int stmmac_restore(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + + if (!ndev || !netif_running(ndev)) + return 0; + + return stmmac_open(ndev); +} + +static const struct dev_pm_ops stmmac_pm_ops = { .suspend = stmmac_suspend, .resume = stmmac_resume, -#endif + .freeze = stmmac_freeze, + .thaw = stmmac_restore, + .restore = stmmac_restore, +}; +#else +static const struct dev_pm_ops stmmac_pm_ops; +#endif /* CONFIG_PM */ +static struct platform_driver stmmac_driver = { + .probe = stmmac_dvr_probe, + .remove = stmmac_dvr_remove, + .driver = { + .name = STMMAC_RESOURCE_NAME, + .owner = THIS_MODULE, + .pm = &stmmac_pm_ops, + }, }; /** -- cgit v1.2.3-59-g8ed1b From 2757a15f08adbed9480c30bdb4e9a0bbf2b6f33a Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 24 Nov 2010 02:38:17 +0000 Subject: stmmac: update the driver version Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index eb258e2319e1..5f06c4706abe 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -20,7 +20,7 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#define DRV_MODULE_VERSION "Apr_2010" +#define DRV_MODULE_VERSION "Nov_2010" #include #include -- cgit v1.2.3-59-g8ed1b From 456b61bca8ee324ab6c18b065e632c9a8c88aa39 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 23 Nov 2010 13:12:15 +0000 Subject: ipv6: mcast: RCU conversion ipv6_sk_mc_lock rwlock becomes a spinlock. readers (inet6_mc_check()) now takes rcu_read_lock() instead of read lock. Writers dont need to disable BH anymore. struct ipv6_mc_socklist objects are reclaimed after one RCU grace period. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/ipv6.h | 2 +- include/net/if_inet6.h | 3 +- net/ipv6/mcast.c | 75 +++++++++++++++++++++++++++++--------------------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 8e429d0e0405..0c997767429a 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -364,7 +364,7 @@ struct ipv6_pinfo { __u32 dst_cookie; - struct ipv6_mc_socklist *ipv6_mc_list; + struct ipv6_mc_socklist __rcu *ipv6_mc_list; struct ipv6_ac_socklist *ipv6_ac_list; struct ipv6_fl_socklist *ipv6_fl_list; diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index f95ff8d9aa47..04977eefb0ee 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -89,10 +89,11 @@ struct ip6_sf_socklist { struct ipv6_mc_socklist { struct in6_addr addr; int ifindex; - struct ipv6_mc_socklist *next; + struct ipv6_mc_socklist __rcu *next; rwlock_t sflock; unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ struct ip6_sf_socklist *sflist; + struct rcu_head rcu; }; struct ip6_sf_list { diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9c5074528a71..49f986d626a0 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -82,7 +82,7 @@ static void *__mld2_query_bugs[] __attribute__((__unused__)) = { static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; /* Big mc list lock for all the sockets */ -static DEFINE_RWLOCK(ipv6_sk_mc_lock); +static DEFINE_SPINLOCK(ipv6_sk_mc_lock); static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); @@ -123,6 +123,11 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; * socket join on multicast group */ +#define for_each_pmc_rcu(np, pmc) \ + for (pmc = rcu_dereference(np->ipv6_mc_list); \ + pmc != NULL; \ + pmc = rcu_dereference(pmc->next)) + int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct net_device *dev = NULL; @@ -134,15 +139,15 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) if (!ipv6_addr_is_multicast(addr)) return -EINVAL; - read_lock_bh(&ipv6_sk_mc_lock); - for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) { + rcu_read_lock(); + for_each_pmc_rcu(np, mc_lst) { if ((ifindex == 0 || mc_lst->ifindex == ifindex) && ipv6_addr_equal(&mc_lst->addr, addr)) { - read_unlock_bh(&ipv6_sk_mc_lock); + rcu_read_unlock(); return -EADDRINUSE; } } - read_unlock_bh(&ipv6_sk_mc_lock); + rcu_read_unlock(); mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); @@ -186,33 +191,41 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) return err; } - write_lock_bh(&ipv6_sk_mc_lock); + spin_lock(&ipv6_sk_mc_lock); mc_lst->next = np->ipv6_mc_list; - np->ipv6_mc_list = mc_lst; - write_unlock_bh(&ipv6_sk_mc_lock); + rcu_assign_pointer(np->ipv6_mc_list, mc_lst); + spin_unlock(&ipv6_sk_mc_lock); rcu_read_unlock(); return 0; } +static void ipv6_mc_socklist_reclaim(struct rcu_head *head) +{ + kfree(container_of(head, struct ipv6_mc_socklist, rcu)); +} /* * socket leave on multicast group */ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct ipv6_pinfo *np = inet6_sk(sk); - struct ipv6_mc_socklist *mc_lst, **lnk; + struct ipv6_mc_socklist *mc_lst; + struct ipv6_mc_socklist __rcu **lnk; struct net *net = sock_net(sk); - write_lock_bh(&ipv6_sk_mc_lock); - for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) { + spin_lock(&ipv6_sk_mc_lock); + for (lnk = &np->ipv6_mc_list; + (mc_lst = rcu_dereference_protected(*lnk, + lockdep_is_held(&ipv6_sk_mc_lock))) !=NULL ; + lnk = &mc_lst->next) { if ((ifindex == 0 || mc_lst->ifindex == ifindex) && ipv6_addr_equal(&mc_lst->addr, addr)) { struct net_device *dev; *lnk = mc_lst->next; - write_unlock_bh(&ipv6_sk_mc_lock); + spin_unlock(&ipv6_sk_mc_lock); rcu_read_lock(); dev = dev_get_by_index_rcu(net, mc_lst->ifindex); @@ -225,11 +238,12 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) } else (void) ip6_mc_leave_src(sk, mc_lst, NULL); rcu_read_unlock(); - sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); + atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); + call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); return 0; } } - write_unlock_bh(&ipv6_sk_mc_lock); + spin_unlock(&ipv6_sk_mc_lock); return -EADDRNOTAVAIL; } @@ -272,12 +286,13 @@ void ipv6_sock_mc_close(struct sock *sk) struct ipv6_mc_socklist *mc_lst; struct net *net = sock_net(sk); - write_lock_bh(&ipv6_sk_mc_lock); - while ((mc_lst = np->ipv6_mc_list) != NULL) { + spin_lock(&ipv6_sk_mc_lock); + while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list, + lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) { struct net_device *dev; np->ipv6_mc_list = mc_lst->next; - write_unlock_bh(&ipv6_sk_mc_lock); + spin_unlock(&ipv6_sk_mc_lock); rcu_read_lock(); dev = dev_get_by_index_rcu(net, mc_lst->ifindex); @@ -290,11 +305,13 @@ void ipv6_sock_mc_close(struct sock *sk) } else (void) ip6_mc_leave_src(sk, mc_lst, NULL); rcu_read_unlock(); - sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); - write_lock_bh(&ipv6_sk_mc_lock); + atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); + call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); + + spin_lock(&ipv6_sk_mc_lock); } - write_unlock_bh(&ipv6_sk_mc_lock); + spin_unlock(&ipv6_sk_mc_lock); } int ip6_mc_source(int add, int omode, struct sock *sk, @@ -328,8 +345,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, err = -EADDRNOTAVAIL; - read_lock(&ipv6_sk_mc_lock); - for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rcu(inet6, pmc) { if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) continue; if (ipv6_addr_equal(&pmc->addr, group)) @@ -428,7 +444,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, done: if (pmclocked) write_unlock(&pmc->sflock); - read_unlock(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); rcu_read_unlock(); if (leavegroup) @@ -466,14 +481,13 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) dev = idev->dev; err = 0; - read_lock(&ipv6_sk_mc_lock); if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { leavegroup = 1; goto done; } - for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rcu(inet6, pmc) { if (pmc->ifindex != gsf->gf_interface) continue; if (ipv6_addr_equal(&pmc->addr, group)) @@ -521,7 +535,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) write_unlock(&pmc->sflock); err = 0; done: - read_unlock(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); rcu_read_unlock(); if (leavegroup) @@ -562,7 +575,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, * so reading the list is safe. */ - for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { + for_each_pmc_rcu(inet6, pmc) { if (pmc->ifindex != gsf->gf_interface) continue; if (ipv6_addr_equal(group, &pmc->addr)) @@ -612,13 +625,13 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, struct ip6_sf_socklist *psl; int rv = 1; - read_lock(&ipv6_sk_mc_lock); - for (mc = np->ipv6_mc_list; mc; mc = mc->next) { + rcu_read_lock(); + for_each_pmc_rcu(np, mc) { if (ipv6_addr_equal(&mc->addr, mc_addr)) break; } if (!mc) { - read_unlock(&ipv6_sk_mc_lock); + rcu_read_unlock(); return 1; } read_lock(&mc->sflock); @@ -638,7 +651,7 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, rv = 0; } read_unlock(&mc->sflock); - read_unlock(&ipv6_sk_mc_lock); + rcu_read_unlock(); return rv; } -- cgit v1.2.3-59-g8ed1b From bba14de98753cb6599a2dae0e520714b2153522d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 23 Nov 2010 14:09:15 +0000 Subject: scm: lower SCM_MAX_FD Lower SCM_MAX_FD from 255 to 253 so that allocations for scm_fp_list are halved. (commit f8d570a4 added two pointers in this structure) scm_fp_dup() should not copy whole structure (and trigger kmemcheck warnings), but only the used part. While we are at it, only allocate needed size. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/scm.h | 5 +++-- net/core/scm.c | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/net/scm.h b/include/net/scm.h index 31656506d967..745460fa2f02 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -10,11 +10,12 @@ /* Well, we should have at least one descriptor open * to accept passed FDs 8) */ -#define SCM_MAX_FD 255 +#define SCM_MAX_FD 253 struct scm_fp_list { struct list_head list; - int count; + short count; + short max; struct file *fp[SCM_MAX_FD]; }; diff --git a/net/core/scm.c b/net/core/scm.c index 413cab89017d..bbe454450801 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -79,10 +79,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) return -ENOMEM; *fplp = fpl; fpl->count = 0; + fpl->max = SCM_MAX_FD; } fpp = &fpl->fp[fpl->count]; - if (fpl->count + num > SCM_MAX_FD) + if (fpl->count + num > fpl->max) return -EINVAL; /* @@ -331,11 +332,12 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) if (!fpl) return NULL; - new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); + new_fpl = kmemdup(fpl, offsetof(struct scm_fp_list, fp[fpl->count]), + GFP_KERNEL); if (new_fpl) { - for (i=fpl->count-1; i>=0; i--) + for (i = 0; i < fpl->count; i++) get_file(fpl->fp[i]); - memcpy(new_fpl, fpl, sizeof(*fpl)); + new_fpl->max = new_fpl->count; } return new_fpl; } -- cgit v1.2.3-59-g8ed1b From 22f4fbd9bd283ef85126e511171932a4af703776 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 24 Nov 2010 11:41:56 -0800 Subject: infiniband: remove dev_base_lock use dev_base_lock is the legacy way to lock the device list, and is planned to disappear. (writers hold RTNL, readers hold RCU lock) Convert rdma_translate_ip() and update_ipv6_gids() to RCU locking. Signed-off-by: Eric Dumazet Acked-by: Roland Dreier Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 6 +++--- drivers/infiniband/hw/mlx4/main.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index c15fd2ea56c1..8aba0ba57de5 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -130,8 +130,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: - read_lock(&dev_base_lock); - for_each_netdev(&init_net, dev) { + rcu_read_lock(); + for_each_netdev_rcu(&init_net, dev) { if (ipv6_chk_addr(&init_net, &((struct sockaddr_in6 *) addr)->sin6_addr, dev, 1)) { @@ -139,7 +139,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) break; } } - read_unlock(&dev_base_lock); + rcu_read_unlock(); break; #endif } diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index bf3e20cd0298..4e55a28fb6d4 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -848,8 +848,8 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear) goto out; } - read_lock(&dev_base_lock); - for_each_netdev(&init_net, tmp) { + rcu_read_lock(); + for_each_netdev_rcu(&init_net, tmp) { if (ndev && (tmp == ndev || rdma_vlan_dev_real_dev(tmp) == ndev)) { gid.global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); vid = rdma_vlan_dev_vlan_id(tmp); @@ -884,7 +884,7 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear) } } } - read_unlock(&dev_base_lock); + rcu_read_unlock(); for (i = 0; i < 128; ++i) if (!hits[i]) { -- cgit v1.2.3-59-g8ed1b From 3853b5841c01a3f492fe137afaad9c209e5162c6 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Sun, 21 Nov 2010 13:17:29 +0000 Subject: xps: Improvements in TX queue selection In dev_pick_tx, don't do work in calculating queue index or setting the index in the sock unless the device has more than one queue. This allows the sock to be set only with a queue index of a multi-queue device which is desirable if device are stacked like in a tunnel. We also allow the mapping of a socket to queue to be changed. To maintain in order packet transmission a flag (ooo_okay) has been added to the sk_buff structure. If a transport layer sets this flag on a packet, the transmit queue can be changed for the socket. Presumably, the transport would set this if there was no possbility of creating OOO packets (for instance, there are no packets in flight for the socket). This patch includes the modification in TCP output for setting this flag. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 ++- net/core/dev.c | 18 +++++++++++------- net/ipv4/tcp_output.c | 5 ++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e6ba898de61c..19f37a6ee6c4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -386,9 +386,10 @@ struct sk_buff { #else __u8 deliver_no_wcard:1; #endif + __u8 ooo_okay:1; kmemcheck_bitfield_end(flags2); - /* 0/14 bit hole */ + /* 0/13 bit hole */ #ifdef CONFIG_NET_DMA dma_cookie_t dma_cookie; diff --git a/net/core/dev.c b/net/core/dev.c index 381b8e280162..7b17674a29ec 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2148,20 +2148,24 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, int queue_index; const struct net_device_ops *ops = dev->netdev_ops; - if (ops->ndo_select_queue) { + if (dev->real_num_tx_queues == 1) + queue_index = 0; + else if (ops->ndo_select_queue) { queue_index = ops->ndo_select_queue(dev, skb); queue_index = dev_cap_txqueue(dev, queue_index); } else { struct sock *sk = skb->sk; queue_index = sk_tx_queue_get(sk); - if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) { - queue_index = 0; - if (dev->real_num_tx_queues > 1) - queue_index = skb_tx_hash(dev, skb); + if (queue_index < 0 || skb->ooo_okay || + queue_index >= dev->real_num_tx_queues) { + int old_index = queue_index; - if (sk) { - struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1); + queue_index = skb_tx_hash(dev, skb); + + if (queue_index != old_index && sk) { + struct dst_entry *dst = + rcu_dereference_check(sk->sk_dst_cache, 1); if (dst && skb_dst(skb) == dst) sk_tx_queue_set(sk, queue_index); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index bb8f547fc7d2..5f29b2e20e23 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -822,8 +822,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, &md5); tcp_header_size = tcp_options_size + sizeof(struct tcphdr); - if (tcp_packets_in_flight(tp) == 0) + if (tcp_packets_in_flight(tp) == 0) { tcp_ca_event(sk, CA_EVENT_TX_START); + skb->ooo_okay = 1; + } else + skb->ooo_okay = 0; skb_push(skb, tcp_header_size); skb_reset_transport_header(skb); -- cgit v1.2.3-59-g8ed1b From 1d24eb4815d1e0e8b451ecc546645f8ef1176d4f Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Sun, 21 Nov 2010 13:17:27 +0000 Subject: xps: Transmit Packet Steering This patch implements transmit packet steering (XPS) for multiqueue devices. XPS selects a transmit queue during packet transmission based on configuration. This is done by mapping the CPU transmitting the packet to a queue. This is the transmit side analogue to RPS-- where RPS is selecting a CPU based on receive queue, XPS selects a queue based on the CPU (previously there was an XPS patch from Eric Dumazet, but that might more appropriately be called transmit completion steering). Each transmit queue can be associated with a number of CPUs which will use the queue to send packets. This is configured as a CPU mask on a per queue basis in: /sys/class/net/eth/queues/tx-/xps_cpus The mappings are stored per device in an inverted data structure that maps CPUs to queues. In the netdevice structure this is an array of num_possible_cpu structures where each structure holds and array of queue_indexes for queues which that CPU can use. The benefits of XPS are improved locality in the per queue data structures. Also, transmit completions are more likely to be done nearer to the sending thread, so this should promote locality back to the socket on free (e.g. UDP). The benefits of XPS are dependent on cache hierarchy, application load, and other factors. XPS would nominally be configured so that a queue would only be shared by CPUs which are sharing a cache, the degenerative configuration woud be that each CPU has it's own queue. Below are some benchmark results which show the potential benfit of this patch. The netperf test has 500 instances of netperf TCP_RR test with 1 byte req. and resp. bnx2x on 16 core AMD XPS (16 queues, 1 TX queue per CPU) 1234K at 100% CPU No XPS (16 queues) 996K at 100% CPU Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/netdevice.h | 30 ++++ net/core/dev.c | 53 ++++++- net/core/net-sysfs.c | 369 +++++++++++++++++++++++++++++++++++++++++++++- net/core/net-sysfs.h | 3 + 4 files changed, 447 insertions(+), 8 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b45c1b8b1d19..badf9285fe0d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -503,6 +503,10 @@ struct netdev_queue { struct Qdisc *qdisc; unsigned long state; struct Qdisc *qdisc_sleeping; +#ifdef CONFIG_RPS + struct kobject kobj; +#endif + /* * write mostly part */ @@ -529,6 +533,30 @@ struct rps_map { }; #define RPS_MAP_SIZE(_num) (sizeof(struct rps_map) + (_num * sizeof(u16))) +/* + * This structure holds an XPS map which can be of variable length. The + * map is an array of queues. + */ +struct xps_map { + unsigned int len; + unsigned int alloc_len; + struct rcu_head rcu; + u16 queues[0]; +}; +#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) +#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ + / sizeof(u16)) + +/* + * This structure holds all XPS maps for device. Maps are indexed by CPU. + */ +struct xps_dev_maps { + struct rcu_head rcu; + struct xps_map *cpu_map[0]; +}; +#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ + (nr_cpu_ids * sizeof(struct xps_map *))) + /* * The rps_dev_flow structure contains the mapping of a flow to a CPU and the * tail pointer for that CPU's input queue at the time of last enqueue. @@ -1016,6 +1044,8 @@ struct net_device { unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; + struct xps_dev_maps *xps_maps; + /* These may be needed for future network-power-down code. */ /* diff --git a/net/core/dev.c b/net/core/dev.c index 7b17674a29ec..c852f0038a08 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1557,12 +1557,16 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) */ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) { + int rc; + if (txq < 1 || txq > dev->num_tx_queues) return -EINVAL; if (dev->reg_state == NETREG_REGISTERED) { ASSERT_RTNL(); + rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, + txq); if (txq < dev->real_num_tx_queues) qdisc_reset_all_tx_gt(dev, txq); } @@ -2142,6 +2146,44 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) return queue_index; } +static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) +{ +#ifdef CONFIG_RPS + struct xps_dev_maps *dev_maps; + struct xps_map *map; + int queue_index = -1; + + rcu_read_lock(); + dev_maps = rcu_dereference(dev->xps_maps); + if (dev_maps) { + map = rcu_dereference( + dev_maps->cpu_map[raw_smp_processor_id()]); + if (map) { + if (map->len == 1) + queue_index = map->queues[0]; + else { + u32 hash; + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else + hash = (__force u16) skb->protocol ^ + skb->rxhash; + hash = jhash_1word(hash, hashrnd); + queue_index = map->queues[ + ((u64)hash * map->len) >> 32]; + } + if (unlikely(queue_index >= dev->real_num_tx_queues)) + queue_index = -1; + } + } + rcu_read_unlock(); + + return queue_index; +#else + return -1; +#endif +} + static struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb) { @@ -2161,7 +2203,9 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, queue_index >= dev->real_num_tx_queues) { int old_index = queue_index; - queue_index = skb_tx_hash(dev, skb); + queue_index = get_xps_queue(dev, skb); + if (queue_index < 0) + queue_index = skb_tx_hash(dev, skb); if (queue_index != old_index && sk) { struct dst_entry *dst = @@ -5066,6 +5110,7 @@ static int netif_alloc_netdev_queues(struct net_device *dev) { unsigned int count = dev->num_tx_queues; struct netdev_queue *tx; + int i; BUG_ON(count < 1); @@ -5076,6 +5121,10 @@ static int netif_alloc_netdev_queues(struct net_device *dev) return -ENOMEM; } dev->_tx = tx; + + for (i = 0; i < count; i++) + tx[i].dev = dev; + return 0; } @@ -5083,8 +5132,6 @@ static void netdev_init_one_queue(struct net_device *dev, struct netdev_queue *queue, void *_unused) { - queue->dev = dev; - /* Initialize queue lock */ spin_lock_init(&queue->_xmit_lock); netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 7abeb7ceaa4c..68dbbfdee274 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -772,18 +772,377 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) return error; } -static int rx_queue_register_kobjects(struct net_device *net) +/* + * netdev_queue sysfs structures and functions. + */ +struct netdev_queue_attribute { + struct attribute attr; + ssize_t (*show)(struct netdev_queue *queue, + struct netdev_queue_attribute *attr, char *buf); + ssize_t (*store)(struct netdev_queue *queue, + struct netdev_queue_attribute *attr, const char *buf, size_t len); +}; +#define to_netdev_queue_attr(_attr) container_of(_attr, \ + struct netdev_queue_attribute, attr) + +#define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj) + +static ssize_t netdev_queue_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); + struct netdev_queue *queue = to_netdev_queue(kobj); + + if (!attribute->show) + return -EIO; + + return attribute->show(queue, attribute, buf); +} + +static ssize_t netdev_queue_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, size_t count) +{ + struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); + struct netdev_queue *queue = to_netdev_queue(kobj); + + if (!attribute->store) + return -EIO; + + return attribute->store(queue, attribute, buf, count); +} + +static const struct sysfs_ops netdev_queue_sysfs_ops = { + .show = netdev_queue_attr_show, + .store = netdev_queue_attr_store, +}; + +static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue) { + struct net_device *dev = queue->dev; + int i; + + for (i = 0; i < dev->num_tx_queues; i++) + if (queue == &dev->_tx[i]) + break; + + BUG_ON(i >= dev->num_tx_queues); + + return i; +} + + +static ssize_t show_xps_map(struct netdev_queue *queue, + struct netdev_queue_attribute *attribute, char *buf) +{ + struct net_device *dev = queue->dev; + struct xps_dev_maps *dev_maps; + cpumask_var_t mask; + unsigned long index; + size_t len = 0; + int i; + + if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) + return -ENOMEM; + + index = get_netdev_queue_index(queue); + + rcu_read_lock(); + dev_maps = rcu_dereference(dev->xps_maps); + if (dev_maps) { + for_each_possible_cpu(i) { + struct xps_map *map = + rcu_dereference(dev_maps->cpu_map[i]); + if (map) { + int j; + for (j = 0; j < map->len; j++) { + if (map->queues[j] == index) { + cpumask_set_cpu(i, mask); + break; + } + } + } + } + } + rcu_read_unlock(); + + len += cpumask_scnprintf(buf + len, PAGE_SIZE, mask); + if (PAGE_SIZE - len < 3) { + free_cpumask_var(mask); + return -EINVAL; + } + + free_cpumask_var(mask); + len += sprintf(buf + len, "\n"); + return len; +} + +static void xps_map_release(struct rcu_head *rcu) +{ + struct xps_map *map = container_of(rcu, struct xps_map, rcu); + + kfree(map); +} + +static void xps_dev_maps_release(struct rcu_head *rcu) +{ + struct xps_dev_maps *dev_maps = + container_of(rcu, struct xps_dev_maps, rcu); + + kfree(dev_maps); +} + +static DEFINE_MUTEX(xps_map_mutex); + +static ssize_t store_xps_map(struct netdev_queue *queue, + struct netdev_queue_attribute *attribute, + const char *buf, size_t len) +{ + struct net_device *dev = queue->dev; + cpumask_var_t mask; + int err, i, cpu, pos, map_len, alloc_len, need_set; + unsigned long index; + struct xps_map *map, *new_map; + struct xps_dev_maps *dev_maps, *new_dev_maps; + int nonempty = 0; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return -ENOMEM; + + index = get_netdev_queue_index(queue); + + err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits); + if (err) { + free_cpumask_var(mask); + return err; + } + + new_dev_maps = kzalloc(max_t(unsigned, + XPS_DEV_MAPS_SIZE, L1_CACHE_BYTES), GFP_KERNEL); + if (!new_dev_maps) { + free_cpumask_var(mask); + return -ENOMEM; + } + + mutex_lock(&xps_map_mutex); + + dev_maps = dev->xps_maps; + + for_each_possible_cpu(cpu) { + new_map = map = dev_maps ? dev_maps->cpu_map[cpu] : NULL; + + if (map) { + for (pos = 0; pos < map->len; pos++) + if (map->queues[pos] == index) + break; + map_len = map->len; + alloc_len = map->alloc_len; + } else + pos = map_len = alloc_len = 0; + + need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); + + if (need_set && pos >= map_len) { + /* Need to add queue to this CPU's map */ + if (map_len >= alloc_len) { + alloc_len = alloc_len ? + 2 * alloc_len : XPS_MIN_MAP_ALLOC; + new_map = kzalloc(XPS_MAP_SIZE(alloc_len), + GFP_KERNEL); + if (!new_map) + goto error; + new_map->alloc_len = alloc_len; + for (i = 0; i < map_len; i++) + new_map->queues[i] = map->queues[i]; + new_map->len = map_len; + } + new_map->queues[new_map->len++] = index; + } else if (!need_set && pos < map_len) { + /* Need to remove queue from this CPU's map */ + if (map_len > 1) + new_map->queues[pos] = + new_map->queues[--new_map->len]; + else + new_map = NULL; + } + new_dev_maps->cpu_map[cpu] = new_map; + } + + /* Cleanup old maps */ + for_each_possible_cpu(cpu) { + map = dev_maps ? dev_maps->cpu_map[cpu] : NULL; + if (map && new_dev_maps->cpu_map[cpu] != map) + call_rcu(&map->rcu, xps_map_release); + if (new_dev_maps->cpu_map[cpu]) + nonempty = 1; + } + + if (nonempty) + rcu_assign_pointer(dev->xps_maps, new_dev_maps); + else { + kfree(new_dev_maps); + rcu_assign_pointer(dev->xps_maps, NULL); + } + + if (dev_maps) + call_rcu(&dev_maps->rcu, xps_dev_maps_release); + + mutex_unlock(&xps_map_mutex); + + free_cpumask_var(mask); + return len; + +error: + mutex_unlock(&xps_map_mutex); + + if (new_dev_maps) + for_each_possible_cpu(i) + kfree(new_dev_maps->cpu_map[i]); + kfree(new_dev_maps); + free_cpumask_var(mask); + return -ENOMEM; +} + +static struct netdev_queue_attribute xps_cpus_attribute = + __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map); + +static struct attribute *netdev_queue_default_attrs[] = { + &xps_cpus_attribute.attr, + NULL +}; + +static void netdev_queue_release(struct kobject *kobj) +{ + struct netdev_queue *queue = to_netdev_queue(kobj); + struct net_device *dev = queue->dev; + struct xps_dev_maps *dev_maps; + struct xps_map *map; + unsigned long index; + int i, pos, nonempty = 0; + + index = get_netdev_queue_index(queue); + + mutex_lock(&xps_map_mutex); + dev_maps = dev->xps_maps; + + if (dev_maps) { + for_each_possible_cpu(i) { + map = dev_maps->cpu_map[i]; + if (!map) + continue; + + for (pos = 0; pos < map->len; pos++) + if (map->queues[pos] == index) + break; + + if (pos < map->len) { + if (map->len > 1) + map->queues[pos] = + map->queues[--map->len]; + else { + RCU_INIT_POINTER(dev_maps->cpu_map[i], + NULL); + call_rcu(&map->rcu, xps_map_release); + map = NULL; + } + } + if (map) + nonempty = 1; + } + + if (!nonempty) { + RCU_INIT_POINTER(dev->xps_maps, NULL); + call_rcu(&dev_maps->rcu, xps_dev_maps_release); + } + } + + mutex_unlock(&xps_map_mutex); + + memset(kobj, 0, sizeof(*kobj)); + dev_put(queue->dev); +} + +static struct kobj_type netdev_queue_ktype = { + .sysfs_ops = &netdev_queue_sysfs_ops, + .release = netdev_queue_release, + .default_attrs = netdev_queue_default_attrs, +}; + +static int netdev_queue_add_kobject(struct net_device *net, int index) +{ + struct netdev_queue *queue = net->_tx + index; + struct kobject *kobj = &queue->kobj; + int error = 0; + + kobj->kset = net->queues_kset; + error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL, + "tx-%u", index); + if (error) { + kobject_put(kobj); + return error; + } + + kobject_uevent(kobj, KOBJ_ADD); + dev_hold(queue->dev); + + return error; +} + +int +netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) +{ + int i; + int error = 0; + + for (i = old_num; i < new_num; i++) { + error = netdev_queue_add_kobject(net, i); + if (error) { + new_num = old_num; + break; + } + } + + while (--i >= new_num) + kobject_put(&net->_tx[i].kobj); + + return error; +} + +static int register_queue_kobjects(struct net_device *net) +{ + int error = 0, txq = 0, rxq = 0; + net->queues_kset = kset_create_and_add("queues", NULL, &net->dev.kobj); if (!net->queues_kset) return -ENOMEM; - return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); + + error = net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); + if (error) + goto error; + rxq = net->real_num_rx_queues; + + error = netdev_queue_update_kobjects(net, 0, + net->real_num_tx_queues); + if (error) + goto error; + txq = net->real_num_tx_queues; + + return 0; + +error: + netdev_queue_update_kobjects(net, txq, 0); + net_rx_queue_update_kobjects(net, rxq, 0); + return error; } -static void rx_queue_remove_kobjects(struct net_device *net) +static void remove_queue_kobjects(struct net_device *net) { net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); + netdev_queue_update_kobjects(net, net->real_num_tx_queues, 0); kset_unregister(net->queues_kset); } #endif /* CONFIG_RPS */ @@ -886,7 +1245,7 @@ void netdev_unregister_kobject(struct net_device * net) kobject_get(&dev->kobj); #ifdef CONFIG_RPS - rx_queue_remove_kobjects(net); + remove_queue_kobjects(net); #endif device_del(dev); @@ -927,7 +1286,7 @@ int netdev_register_kobject(struct net_device *net) return error; #ifdef CONFIG_RPS - error = rx_queue_register_kobjects(net); + error = register_queue_kobjects(net); if (error) { device_del(dev); return error; diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h index 778e1571548d..25ec2ee57df7 100644 --- a/net/core/net-sysfs.h +++ b/net/core/net-sysfs.h @@ -6,6 +6,9 @@ int netdev_register_kobject(struct net_device *); void netdev_unregister_kobject(struct net_device *); #ifdef CONFIG_RPS int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); +int netdev_queue_update_kobjects(struct net_device *net, + int old_num, int new_num); + #endif #endif -- cgit v1.2.3-59-g8ed1b From ccb14354017272ddac002e859a2711610b6af174 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 24 Nov 2010 16:18:36 -0500 Subject: Revert "nl80211/mac80211: Report signal average" This reverts commit 86107fd170bc379869250eb7e1bd393a3a70e8ae. This patch inadvertantly changed the userland ABI. Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 -- include/net/cfg80211.h | 4 ---- net/mac80211/Kconfig | 1 - net/mac80211/cfg.c | 3 +-- net/mac80211/rx.c | 1 - net/mac80211/sta_info.c | 2 -- net/mac80211/sta_info.h | 3 --- net/wireless/nl80211.c | 3 --- 8 files changed, 1 insertion(+), 18 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 1ce3775e9e26..037b4e498890 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1161,7 +1161,6 @@ enum nl80211_rate_info { * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) - * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute * containing info as possible, see &enum nl80211_sta_info_txrate. * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) @@ -1179,7 +1178,6 @@ enum nl80211_sta_info { NL80211_STA_INFO_PLID, NL80211_STA_INFO_PLINK_STATE, NL80211_STA_INFO_SIGNAL, - NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_TX_BITRATE, NL80211_STA_INFO_RX_PACKETS, NL80211_STA_INFO_TX_PACKETS, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 69e2364889f1..8fd9eebd0cc9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -424,7 +424,6 @@ struct station_parameters { * @STATION_INFO_TX_RETRIES: @tx_retries filled * @STATION_INFO_TX_FAILED: @tx_failed filled * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled - * @STATION_INFO_SIGNAL_AVG: @signal_avg filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -440,7 +439,6 @@ enum station_info_flags { STATION_INFO_TX_RETRIES = 1<<10, STATION_INFO_TX_FAILED = 1<<11, STATION_INFO_RX_DROP_MISC = 1<<12, - STATION_INFO_SIGNAL_AVG = 1<<13, }; /** @@ -487,7 +485,6 @@ struct rate_info { * @plid: mesh peer link id * @plink_state: mesh peer link state * @signal: signal strength of last received packet in dBm - * @signal_avg: signal strength average in dBm * @txrate: current unicast bitrate to this station * @rx_packets: packets received from this station * @tx_packets: packets transmitted to this station @@ -508,7 +505,6 @@ struct station_info { u16 plid; u8 plink_state; s8 signal; - s8 signal_avg; struct rate_info txrate; u32 rx_packets; u32 tx_packets; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 798d9b9462e2..4d6f8653ec88 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -6,7 +6,6 @@ config MAC80211 select CRYPTO_ARC4 select CRYPTO_AES select CRC32 - select AVERAGE ---help--- This option enables the hardware independent IEEE 802.11 networking stack. diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 92c9cf6a7d1c..0c544074479e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -343,9 +343,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { - sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; + sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = (s8)sta->last_signal; - sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } sinfo->txrate.flags = 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9dd60a74181f..d2fcd22ab06d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1156,7 +1156,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->rx_fragments++; sta->rx_bytes += rx->skb->len; sta->last_signal = status->signal; - ewma_add(&sta->avg_signal, -status->signal); /* * Change STA power saving mode only at the end of a frame diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f43fca8907f7..eff58571fd7e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -244,8 +244,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->local = local; sta->sdata = sdata; - ewma_init(&sta->avg_signal, 1000, 8); - if (sta_prepare_rate_control(local, sta, gfp)) { kfree(sta); return NULL; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 84062e2c782c..9265acadef32 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -13,7 +13,6 @@ #include #include #include -#include #include "key.h" /** @@ -225,7 +224,6 @@ enum plink_state { * @rx_fragments: number of received MPDUs * @rx_dropped: number of dropped MPDUs from this STA * @last_signal: signal of last received frame from this STA - * @avg_signal: moving average of signal of received frames from this STA * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) * @tx_filtered_count: number of frames the hardware filtered for this STA * @tx_retry_failed: number of frames that failed retry @@ -293,7 +291,6 @@ struct sta_info { unsigned long rx_fragments; unsigned long rx_dropped; int last_signal; - struct ewma avg_signal; __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; /* Updated from TX status path only, no locking requirements */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d06a40d17002..605553842226 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1872,9 +1872,6 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_SIGNAL) NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, sinfo->signal); - if (sinfo->filled & STATION_INFO_SIGNAL_AVG) - NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, - sinfo->signal_avg); if (sinfo->filled & STATION_INFO_TX_BITRATE) { txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); if (!txrate) -- cgit v1.2.3-59-g8ed1b From e9c0268f02f8970149158a9b7ea1e5c1c45c819d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 16 Nov 2010 19:56:49 -0800 Subject: net/wireless: Use pr_ and netdev_ No change in output for pr_ prefixes. netdev_ output is different, arguably improved. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/wireless/core.c | 8 +++---- net/wireless/lib80211.c | 8 ++++--- net/wireless/lib80211_crypt_tkip.c | 16 ++++++------- net/wireless/reg.c | 47 +++++++++++++++----------------------- net/wireless/util.c | 11 ++++----- net/wireless/wext-core.c | 10 ++++---- 6 files changed, 44 insertions(+), 56 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 9c21ebf9780e..630bcf0a2f04 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -4,6 +4,8 @@ * Copyright 2006-2010 Johannes Berg */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -216,8 +218,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, rdev->wiphy.debugfsdir, rdev->wiphy.debugfsdir->d_parent, newname)) - printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", - newname); + pr_err("failed to rename debugfs dir to %s!\n", newname); nl80211_notify_dev_rename(rdev); @@ -699,8 +700,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, "phy80211")) { - printk(KERN_ERR "wireless: failed to add phy80211 " - "symlink to netdev!\n"); + pr_err("failed to add phy80211 symlink to netdev!\n"); } wdev->netdev = dev; wdev->sme_state = CFG80211_SME_IDLE; diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c index 97d411f74507..3268fac5ab22 100644 --- a/net/wireless/lib80211.c +++ b/net/wireless/lib80211.c @@ -13,6 +13,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -224,8 +226,8 @@ int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops) return -EINVAL; found: - printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm " - "'%s'\n", ops->name); + printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm '%s'\n", + ops->name); list_del(&alg->list); spin_unlock_irqrestore(&lib80211_crypto_lock, flags); kfree(alg); @@ -270,7 +272,7 @@ static struct lib80211_crypto_ops lib80211_crypt_null = { static int __init lib80211_init(void) { - printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n"); + pr_info(DRV_DESCRIPTION "\n"); return lib80211_register_crypto_ops(&lib80211_crypt_null); } diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 0fe40510e2cb..7ea4f2b0770e 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c @@ -10,6 +10,8 @@ * more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -99,8 +101,7 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " - "crypto API arc4\n"); + printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->tx_tfm_arc4 = NULL; goto fail; } @@ -108,8 +109,7 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); + printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->tx_tfm_michael = NULL; goto fail; } @@ -117,8 +117,7 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " - "crypto API arc4\n"); + printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->rx_tfm_arc4 = NULL; goto fail; } @@ -126,8 +125,7 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); + printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->rx_tfm_michael = NULL; goto fail; } @@ -536,7 +534,7 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, struct scatterlist sg[2]; if (tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + pr_warn("%s(): tfm_michael == NULL\n", __func__); return -1; } sg_init_table(sg, 2); diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bc14caab19cd..5ed615f94e0c 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -32,6 +32,9 @@ * rely on some SHA1 checksum of the regdomain for example. * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -48,7 +51,7 @@ #ifdef CONFIG_CFG80211_REG_DEBUG #define REG_DBG_PRINT(format, args...) \ do { \ - printk(KERN_DEBUG "cfg80211: " format , ## args); \ + printk(KERN_DEBUG pr_fmt(format), ##args); \ } while (0) #else #define REG_DBG_PRINT(args...) @@ -370,11 +373,10 @@ static int call_crda(const char *alpha2) }; if (!is_world_regdom((char *) alpha2)) - printk(KERN_INFO "cfg80211: Calling CRDA for country: %c%c\n", + pr_info("Calling CRDA for country: %c%c\n", alpha2[0], alpha2[1]); else - printk(KERN_INFO "cfg80211: Calling CRDA to update world " - "regulatory domain\n"); + pr_info("Calling CRDA to update world regulatory domain\n"); /* query internal regulatory database (if it exists) */ reg_regdb_query(alpha2); @@ -1851,8 +1853,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) const struct ieee80211_freq_range *freq_range = NULL; const struct ieee80211_power_rule *power_rule = NULL; - printk(KERN_INFO " (start_freq - end_freq @ bandwidth), " - "(max_antenna_gain, max_eirp)\n"); + pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n"); for (i = 0; i < rd->n_reg_rules; i++) { reg_rule = &rd->reg_rules[i]; @@ -1864,16 +1865,14 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) * in certain regions */ if (power_rule->max_antenna_gain) - printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), " - "(%d mBi, %d mBm)\n", + pr_info(" (%d KHz - %d KHz @ %d KHz), (%d mBi, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, freq_range->max_bandwidth_khz, power_rule->max_antenna_gain, power_rule->max_eirp); else - printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), " - "(N/A, %d mBm)\n", + pr_info(" (%d KHz - %d KHz @ %d KHz), (N/A, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, freq_range->max_bandwidth_khz, @@ -1892,27 +1891,20 @@ static void print_regdomain(const struct ieee80211_regdomain *rd) rdev = cfg80211_rdev_by_wiphy_idx( last_request->wiphy_idx); if (rdev) { - printk(KERN_INFO "cfg80211: Current regulatory " - "domain updated by AP to: %c%c\n", + pr_info("Current regulatory domain updated by AP to: %c%c\n", rdev->country_ie_alpha2[0], rdev->country_ie_alpha2[1]); } else - printk(KERN_INFO "cfg80211: Current regulatory " - "domain intersected:\n"); + pr_info("Current regulatory domain intersected:\n"); } else - printk(KERN_INFO "cfg80211: Current regulatory " - "domain intersected:\n"); + pr_info("Current regulatory domain intersected:\n"); } else if (is_world_regdom(rd->alpha2)) - printk(KERN_INFO "cfg80211: World regulatory " - "domain updated:\n"); + pr_info("World regulatory domain updated:\n"); else { if (is_unknown_alpha2(rd->alpha2)) - printk(KERN_INFO "cfg80211: Regulatory domain " - "changed to driver built-in settings " - "(unknown country)\n"); + pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n"); else - printk(KERN_INFO "cfg80211: Regulatory domain " - "changed to country: %c%c\n", + pr_info("Regulatory domain changed to country: %c%c\n", rd->alpha2[0], rd->alpha2[1]); } print_rd_rules(rd); @@ -1920,8 +1912,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd) static void print_regdomain_info(const struct ieee80211_regdomain *rd) { - printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n", - rd->alpha2[0], rd->alpha2[1]); + pr_info("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]); print_rd_rules(rd); } @@ -1972,8 +1963,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) return -EINVAL; if (!is_valid_rd(rd)) { - printk(KERN_ERR "cfg80211: Invalid " - "regulatory domain detected:\n"); + pr_err("Invalid regulatory domain detected:\n"); print_regdomain_info(rd); return -EINVAL; } @@ -2147,8 +2137,7 @@ int __init regulatory_init(void) * early boot for call_usermodehelper(). For now treat these * errors as non-fatal. */ - printk(KERN_ERR "cfg80211: kobject_uevent_env() was unable " - "to call CRDA during init"); + pr_err("kobject_uevent_env() was unable to call CRDA during init\n"); #ifdef CONFIG_CFG80211_REG_DEBUG /* We want to find out exactly why when debugging */ WARN_ON(err); diff --git a/net/wireless/util.c b/net/wireless/util.c index 76120aeda57d..fee020b15a4e 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -502,7 +502,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, skb_orphan(skb); if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { - printk(KERN_ERR "failed to reallocate Tx buffer\n"); + pr_err("failed to reallocate Tx buffer\n"); return -ENOMEM; } skb->truesize += head_need; @@ -685,20 +685,17 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) continue; if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, &wdev->connect_keys->params[i])) { - printk(KERN_ERR "%s: failed to set key %d\n", - dev->name, i); + netdev_err(dev, "failed to set key %d\n", i); continue; } if (wdev->connect_keys->def == i) if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { - printk(KERN_ERR "%s: failed to set defkey %d\n", - dev->name, i); + netdev_err(dev, "failed to set defkey %d\n", i); continue; } if (wdev->connect_keys->defmgmt == i) if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i)) - printk(KERN_ERR "%s: failed to set mgtdef %d\n", - dev->name, i); + netdev_err(dev, "failed to set mgtdef %d\n", i); } kfree(wdev->connect_keys); diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index dc675a3daa3d..fdbc23c10d8c 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -467,8 +467,8 @@ void wireless_send_event(struct net_device * dev, * The best the driver could do is to log an error message. * We will do it ourselves instead... */ - printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n", - dev->name, cmd); + netdev_err(dev, "(WE) : Invalid/Unknown Wireless Event (0x%04X)\n", + cmd); return; } @@ -476,11 +476,13 @@ void wireless_send_event(struct net_device * dev, if (descr->header_type == IW_HEADER_TYPE_POINT) { /* Check if number of token fits within bounds */ if (wrqu->data.length > descr->max_tokens) { - printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length); + netdev_err(dev, "(WE) : Wireless Event too big (%d)\n", + wrqu->data.length); return; } if (wrqu->data.length < descr->min_tokens) { - printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length); + netdev_err(dev, "(WE) : Wireless Event too small (%d)\n", + wrqu->data.length); return; } /* Calculate extra_len - extra is NULL for restricted events */ -- cgit v1.2.3-59-g8ed1b From 69a3229edcf0c354e1cd93a811843fba7b6e1472 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 13:27:57 +0100 Subject: b43: N-PHY: fix values for PHY regs in channel tables of 2055 radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additional comment by Larry Finger : This change deserves a bit more explanation. You might include something like "These tables came from reverse engineering the 5.10.56.46 version of the Broadcom driver. Trace comparisons between b43 and the current Broadcom driver (5.10.120.0) show byte reversals for the PHY register writes." Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2055.c | 248 +++++++++++++++++----------------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c index 0d6771515bce..10910dc4184b 100644 --- a/drivers/net/wireless/b43/radio_2055.c +++ b/drivers/net/wireless/b43/radio_2055.c @@ -307,7 +307,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602), + PHYREGS(0x07B4, 0x07B0, 0x07AC, 0x0214, 0x0215, 0x0216), }, { .channel = 186, .freq = 4930, /* MHz */ @@ -315,7 +315,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502), + PHYREGS(0x07B8, 0x07B4, 0x07B0, 0x0213, 0x0214, 0x0215), }, { .channel = 188, .freq = 4940, /* MHz */ @@ -323,7 +323,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402), + PHYREGS(0x07BC, 0x07B8, 0x07B4, 0x0212, 0x0213, 0x0214), }, { .channel = 190, .freq = 4950, /* MHz */ @@ -331,7 +331,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302), + PHYREGS(0x07C0, 0x07BC, 0x07B8, 0x0211, 0x0212, 0x0213), }, { .channel = 192, .freq = 4960, /* MHz */ @@ -339,7 +339,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202), + PHYREGS(0x07C4, 0x07C0, 0x07BC, 0x020F, 0x0211, 0x0212), }, { .channel = 194, .freq = 4970, /* MHz */ @@ -347,7 +347,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102), + PHYREGS(0x07C8, 0x07C4, 0x07C0, 0x020E, 0x020F, 0x0211), }, { .channel = 196, .freq = 4980, /* MHz */ @@ -355,7 +355,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02), + PHYREGS(0x07CC, 0x07C8, 0x07C4, 0x020D, 0x020E, 0x020F), }, { .channel = 198, .freq = 4990, /* MHz */ @@ -363,7 +363,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02), + PHYREGS(0x07D0, 0x07CC, 0x07C8, 0x020C, 0x020D, 0x020E), }, { .channel = 200, .freq = 5000, /* MHz */ @@ -371,7 +371,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02), + PHYREGS(0x07D4, 0x07D0, 0x07CC, 0x020B, 0x020C, 0x020D), }, { .channel = 202, .freq = 5010, /* MHz */ @@ -379,7 +379,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02), + PHYREGS(0x07D8, 0x07D4, 0x07D0, 0x020A, 0x020B, 0x020C), }, { .channel = 204, .freq = 5020, /* MHz */ @@ -387,7 +387,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02), + PHYREGS(0x07DC, 0x07D8, 0x07D4, 0x0209, 0x020A, 0x020B), }, { .channel = 206, .freq = 5030, /* MHz */ @@ -395,7 +395,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02), + PHYREGS(0x07E0, 0x07DC, 0x07D8, 0x0208, 0x0209, 0x020A), }, { .channel = 208, .freq = 5040, /* MHz */ @@ -403,7 +403,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902), + PHYREGS(0x07E4, 0x07E0, 0x07DC, 0x0207, 0x0208, 0x0209), }, { .channel = 210, .freq = 5050, /* MHz */ @@ -411,7 +411,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802), + PHYREGS(0x07E8, 0x07E4, 0x07E0, 0x0206, 0x0207, 0x0208), }, { .channel = 212, .freq = 5060, /* MHz */ @@ -419,7 +419,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702), + PHYREGS(0x07EC, 0x07E8, 0x07E4, 0x0205, 0x0206, 0x0207), }, { .channel = 214, .freq = 5070, /* MHz */ @@ -427,7 +427,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602), + PHYREGS(0x07F0, 0x07EC, 0x07E8, 0x0204, 0x0205, 0x0206), }, { .channel = 216, .freq = 5080, /* MHz */ @@ -435,7 +435,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502), + PHYREGS(0x07F4, 0x07F0, 0x07EC, 0x0203, 0x0204, 0x0205), }, { .channel = 218, .freq = 5090, /* MHz */ @@ -443,7 +443,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402), + PHYREGS(0x07F8, 0x07F4, 0x07F0, 0x0202, 0x0203, 0x0204), }, { .channel = 220, .freq = 5100, /* MHz */ @@ -451,7 +451,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302), + PHYREGS(0x07FC, 0x07F8, 0x07F4, 0x0201, 0x0202, 0x0203), }, { .channel = 222, .freq = 5110, /* MHz */ @@ -459,7 +459,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202), + PHYREGS(0x0800, 0x07FC, 0x07F8, 0x0200, 0x0201, 0x0202), }, { .channel = 224, .freq = 5120, /* MHz */ @@ -467,7 +467,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102), + PHYREGS(0x0804, 0x0800, 0x07FC, 0x01FF, 0x0200, 0x0201), }, { .channel = 226, .freq = 5130, /* MHz */ @@ -475,7 +475,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002), + PHYREGS(0x0808, 0x0804, 0x0800, 0x01FE, 0x01FF, 0x0200), }, { .channel = 228, .freq = 5140, /* MHz */ @@ -483,7 +483,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B), - PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01), + PHYREGS(0x080C, 0x0808, 0x0804, 0x01FD, 0x01FE, 0x01FF), }, { .channel = 32, .freq = 5160, /* MHz */ @@ -491,7 +491,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01), + PHYREGS(0x0814, 0x0810, 0x080C, 0x01FB, 0x01FC, 0x01FD), }, { .channel = 34, .freq = 5170, /* MHz */ @@ -499,7 +499,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01), + PHYREGS(0x0818, 0x0814, 0x0810, 0x01FA, 0x01FB, 0x01FC), }, { .channel = 36, .freq = 5180, /* MHz */ @@ -507,7 +507,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01), + PHYREGS(0x081C, 0x0818, 0x0814, 0x01F9, 0x01FA, 0x01FB), }, { .channel = 38, .freq = 5190, /* MHz */ @@ -515,7 +515,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01), + PHYREGS(0x0820, 0x081C, 0x0818, 0x01F8, 0x01F9, 0x01FA), }, { .channel = 40, .freq = 5200, /* MHz */ @@ -523,7 +523,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901), + PHYREGS(0x0824, 0x0820, 0x081C, 0x01F7, 0x01F8, 0x01F9), }, { .channel = 42, .freq = 5210, /* MHz */ @@ -531,7 +531,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801), + PHYREGS(0x0828, 0x0824, 0x0820, 0x01F6, 0x01F7, 0x01F8), }, { .channel = 44, .freq = 5220, /* MHz */ @@ -539,7 +539,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701), + PHYREGS(0x082C, 0x0828, 0x0824, 0x01F5, 0x01F6, 0x01F7), }, { .channel = 46, .freq = 5230, /* MHz */ @@ -547,7 +547,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601), + PHYREGS(0x0830, 0x082C, 0x0828, 0x01F4, 0x01F5, 0x01F6), }, { .channel = 48, .freq = 5240, /* MHz */ @@ -555,7 +555,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501), + PHYREGS(0x0834, 0x0830, 0x082C, 0x01F3, 0x01F4, 0x01F5), }, { .channel = 50, .freq = 5250, /* MHz */ @@ -563,7 +563,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401), + PHYREGS(0x0838, 0x0834, 0x0830, 0x01F2, 0x01F3, 0x01F4), }, { .channel = 52, .freq = 5260, /* MHz */ @@ -571,7 +571,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301), + PHYREGS(0x083C, 0x0838, 0x0834, 0x01F1, 0x01F2, 0x01F3), }, { .channel = 54, .freq = 5270, /* MHz */ @@ -579,7 +579,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201), + PHYREGS(0x0840, 0x083C, 0x0838, 0x01F0, 0x01F1, 0x01F2), }, { .channel = 56, .freq = 5280, /* MHz */ @@ -587,7 +587,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101), + PHYREGS(0x0844, 0x0840, 0x083C, 0x01F0, 0x01F0, 0x01F1), }, { .channel = 58, .freq = 5290, /* MHz */ @@ -595,7 +595,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001), + PHYREGS(0x0848, 0x0844, 0x0840, 0x01EF, 0x01F0, 0x01F0), }, { .channel = 60, .freq = 5300, /* MHz */ @@ -603,7 +603,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001), + PHYREGS(0x084C, 0x0848, 0x0844, 0x01EE, 0x01EF, 0x01F0), }, { .channel = 62, .freq = 5310, /* MHz */ @@ -611,7 +611,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01), + PHYREGS(0x0850, 0x084C, 0x0848, 0x01ED, 0x01EE, 0x01EF), }, { .channel = 64, .freq = 5320, /* MHz */ @@ -619,7 +619,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01), + PHYREGS(0x0854, 0x0850, 0x084C, 0x01EC, 0x01ED, 0x01EE), }, { .channel = 66, .freq = 5330, /* MHz */ @@ -627,7 +627,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01), + PHYREGS(0x0858, 0x0854, 0x0850, 0x01EB, 0x01EC, 0x01ED), }, { .channel = 68, .freq = 5340, /* MHz */ @@ -635,7 +635,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01), + PHYREGS(0x085C, 0x0858, 0x0854, 0x01EA, 0x01EB, 0x01EC), }, { .channel = 70, .freq = 5350, /* MHz */ @@ -643,7 +643,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01), + PHYREGS(0x0860, 0x085C, 0x0858, 0x01E9, 0x01EA, 0x01EB), }, { .channel = 72, .freq = 5360, /* MHz */ @@ -651,7 +651,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01), + PHYREGS(0x0864, 0x0860, 0x085C, 0x01E8, 0x01E9, 0x01EA), }, { .channel = 74, .freq = 5370, /* MHz */ @@ -659,7 +659,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901), + PHYREGS(0x0868, 0x0864, 0x0860, 0x01E7, 0x01E8, 0x01E9), }, { .channel = 76, .freq = 5380, /* MHz */ @@ -667,7 +667,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801), + PHYREGS(0x086C, 0x0868, 0x0864, 0x01E6, 0x01E7, 0x01E8), }, { .channel = 78, .freq = 5390, /* MHz */ @@ -675,7 +675,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701), + PHYREGS(0x0870, 0x086C, 0x0868, 0x01E5, 0x01E6, 0x01E7), }, { .channel = 80, .freq = 5400, /* MHz */ @@ -683,7 +683,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601), + PHYREGS(0x0874, 0x0870, 0x086C, 0x01E5, 0x01E5, 0x01E6), }, { .channel = 82, .freq = 5410, /* MHz */ @@ -691,7 +691,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501), + PHYREGS(0x0878, 0x0874, 0x0870, 0x01E4, 0x01E5, 0x01E5), }, { .channel = 84, .freq = 5420, /* MHz */ @@ -699,7 +699,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501), + PHYREGS(0x087C, 0x0878, 0x0874, 0x01E3, 0x01E4, 0x01E5), }, { .channel = 86, .freq = 5430, /* MHz */ @@ -707,7 +707,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401), + PHYREGS(0x0880, 0x087C, 0x0878, 0x01E2, 0x01E3, 0x01E4), }, { .channel = 88, .freq = 5440, /* MHz */ @@ -715,7 +715,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301), + PHYREGS(0x0884, 0x0880, 0x087C, 0x01E1, 0x01E2, 0x01E3), }, { .channel = 90, .freq = 5450, /* MHz */ @@ -723,7 +723,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201), + PHYREGS(0x0888, 0x0884, 0x0880, 0x01E0, 0x01E1, 0x01E2), }, { .channel = 92, .freq = 5460, /* MHz */ @@ -731,7 +731,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101), + PHYREGS(0x088C, 0x0888, 0x0884, 0x01DF, 0x01E0, 0x01E1), }, { .channel = 94, .freq = 5470, /* MHz */ @@ -739,7 +739,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001), + PHYREGS(0x0890, 0x088C, 0x0888, 0x01DE, 0x01DF, 0x01E0), }, { .channel = 96, .freq = 5480, /* MHz */ @@ -747,7 +747,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01), + PHYREGS(0x0894, 0x0890, 0x088C, 0x01DD, 0x01DE, 0x01DF), }, { .channel = 98, .freq = 5490, /* MHz */ @@ -755,7 +755,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01), + PHYREGS(0x0898, 0x0894, 0x0890, 0x01DD, 0x01DD, 0x01DE), }, { .channel = 100, .freq = 5500, /* MHz */ @@ -763,7 +763,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01), + PHYREGS(0x089C, 0x0898, 0x0894, 0x01DC, 0x01DD, 0x01DD), }, { .channel = 102, .freq = 5510, /* MHz */ @@ -771,7 +771,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01), + PHYREGS(0x08A0, 0x089C, 0x0898, 0x01DB, 0x01DC, 0x01DD), }, { .channel = 104, .freq = 5520, /* MHz */ @@ -779,7 +779,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01), + PHYREGS(0x08A4, 0x08A0, 0x089C, 0x01DA, 0x01DB, 0x01DC), }, { .channel = 106, .freq = 5530, /* MHz */ @@ -787,7 +787,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01), + PHYREGS(0x08A8, 0x08A4, 0x08A0, 0x01D9, 0x01DA, 0x01DB), }, { .channel = 108, .freq = 5540, /* MHz */ @@ -795,7 +795,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01), + PHYREGS(0x08AC, 0x08A8, 0x08A4, 0x01D8, 0x01D9, 0x01DA), }, { .channel = 110, .freq = 5550, /* MHz */ @@ -803,7 +803,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901), + PHYREGS(0x08B0, 0x08AC, 0x08A8, 0x01D7, 0x01D8, 0x01D9), }, { .channel = 112, .freq = 5560, /* MHz */ @@ -811,7 +811,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801), + PHYREGS(0x08B4, 0x08B0, 0x08AC, 0x01D7, 0x01D7, 0x01D8), }, { .channel = 114, .freq = 5570, /* MHz */ @@ -819,7 +819,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701), + PHYREGS(0x08B8, 0x08B4, 0x08B0, 0x01D6, 0x01D7, 0x01D7), }, { .channel = 116, .freq = 5580, /* MHz */ @@ -827,7 +827,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701), + PHYREGS(0x08BC, 0x08B8, 0x08B4, 0x01D5, 0x01D6, 0x01D7), }, { .channel = 118, .freq = 5590, /* MHz */ @@ -835,7 +835,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601), + PHYREGS(0x08C0, 0x08BC, 0x08B8, 0x01D4, 0x01D5, 0x01D6), }, { .channel = 120, .freq = 5600, /* MHz */ @@ -843,7 +843,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501), + PHYREGS(0x08C4, 0x08C0, 0x08BC, 0x01D3, 0x01D4, 0x01D5), }, { .channel = 122, .freq = 5610, /* MHz */ @@ -851,7 +851,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401), + PHYREGS(0x08C8, 0x08C4, 0x08C0, 0x01D2, 0x01D3, 0x01D4), }, { .channel = 124, .freq = 5620, /* MHz */ @@ -859,7 +859,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301), + PHYREGS(0x08CC, 0x08C8, 0x08C4, 0x01D2, 0x01D2, 0x01D3), }, { .channel = 126, .freq = 5630, /* MHz */ @@ -867,7 +867,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201), + PHYREGS(0x08D0, 0x08CC, 0x08C8, 0x01D1, 0x01D2, 0x01D2), }, { .channel = 128, .freq = 5640, /* MHz */ @@ -875,7 +875,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201), + PHYREGS(0x08D4, 0x08D0, 0x08CC, 0x01D0, 0x01D1, 0x01D2), }, { .channel = 130, .freq = 5650, /* MHz */ @@ -883,7 +883,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101), + PHYREGS(0x08D8, 0x08D4, 0x08D0, 0x01CF, 0x01D0, 0x01D1), }, { .channel = 132, .freq = 5660, /* MHz */ @@ -891,7 +891,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001), + PHYREGS(0x08DC, 0x08D8, 0x08D4, 0x01CE, 0x01CF, 0x01D0), }, { .channel = 134, .freq = 5670, /* MHz */ @@ -899,7 +899,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01), + PHYREGS(0x08E0, 0x08DC, 0x08D8, 0x01CE, 0x01CE, 0x01CF), }, { .channel = 136, .freq = 5680, /* MHz */ @@ -907,7 +907,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01), + PHYREGS(0x08E4, 0x08E0, 0x08DC, 0x01CD, 0x01CE, 0x01CE), }, { .channel = 138, .freq = 5690, /* MHz */ @@ -915,7 +915,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01), + PHYREGS(0x08E8, 0x08E4, 0x08E0, 0x01CC, 0x01CD, 0x01CE), }, { .channel = 140, .freq = 5700, /* MHz */ @@ -923,7 +923,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01), + PHYREGS(0x08EC, 0x08E8, 0x08E4, 0x01CB, 0x01CC, 0x01CD), }, { .channel = 142, .freq = 5710, /* MHz */ @@ -931,7 +931,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01), + PHYREGS(0x08F0, 0x08EC, 0x08E8, 0x01CA, 0x01CB, 0x01CC), }, { .channel = 144, .freq = 5720, /* MHz */ @@ -939,7 +939,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01), + PHYREGS(0x08F4, 0x08F0, 0x08EC, 0x01C9, 0x01CA, 0x01CB), }, { .channel = 145, .freq = 5725, /* MHz */ @@ -947,7 +947,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01), + PHYREGS(0x08F6, 0x08F2, 0x08EE, 0x01C9, 0x01CA, 0x01CB), }, { .channel = 146, .freq = 5730, /* MHz */ @@ -955,7 +955,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01), + PHYREGS(0x08F8, 0x08F4, 0x08F0, 0x01C9, 0x01C9, 0x01CA), }, { .channel = 147, .freq = 5735, /* MHz */ @@ -963,7 +963,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01), + PHYREGS(0x08FA, 0x08F6, 0x08F2, 0x01C8, 0x01C9, 0x01CA), }, { .channel = 148, .freq = 5740, /* MHz */ @@ -971,7 +971,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901), + PHYREGS(0x08FC, 0x08F8, 0x08F4, 0x01C8, 0x01C9, 0x01C9), }, { .channel = 149, .freq = 5745, /* MHz */ @@ -979,7 +979,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901), + PHYREGS(0x08FE, 0x08FA, 0x08F6, 0x01C8, 0x01C8, 0x01C9), }, { .channel = 150, .freq = 5750, /* MHz */ @@ -987,7 +987,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901), + PHYREGS(0x0900, 0x08FC, 0x08F8, 0x01C7, 0x01C8, 0x01C9), }, { .channel = 151, .freq = 5755, /* MHz */ @@ -995,7 +995,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801), + PHYREGS(0x0902, 0x08FE, 0x08FA, 0x01C7, 0x01C8, 0x01C8), }, { .channel = 152, .freq = 5760, /* MHz */ @@ -1003,7 +1003,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801), + PHYREGS(0x0904, 0x0900, 0x08FC, 0x01C6, 0x01C7, 0x01C8), }, { .channel = 153, .freq = 5765, /* MHz */ @@ -1011,7 +1011,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801), + PHYREGS(0x0906, 0x0902, 0x08FE, 0x01C6, 0x01C7, 0x01C8), }, { .channel = 154, .freq = 5770, /* MHz */ @@ -1019,7 +1019,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701), + PHYREGS(0x0908, 0x0904, 0x0900, 0x01C6, 0x01C6, 0x01C7), }, { .channel = 155, .freq = 5775, /* MHz */ @@ -1027,7 +1027,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701), + PHYREGS(0x090A, 0x0906, 0x0902, 0x01C5, 0x01C6, 0x01C7), }, { .channel = 156, .freq = 5780, /* MHz */ @@ -1035,7 +1035,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601), + PHYREGS(0x090C, 0x0908, 0x0904, 0x01C5, 0x01C6, 0x01C6), }, { .channel = 157, .freq = 5785, /* MHz */ @@ -1043,7 +1043,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601), + PHYREGS(0x090E, 0x090A, 0x0906, 0x01C4, 0x01C5, 0x01C6), }, { .channel = 158, .freq = 5790, /* MHz */ @@ -1051,7 +1051,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601), + PHYREGS(0x0910, 0x090C, 0x0908, 0x01C4, 0x01C5, 0x01C6), }, { .channel = 159, .freq = 5795, /* MHz */ @@ -1059,7 +1059,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501), + PHYREGS(0x0912, 0x090E, 0x090A, 0x01C4, 0x01C4, 0x01C5), }, { .channel = 160, .freq = 5800, /* MHz */ @@ -1067,7 +1067,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501), + PHYREGS(0x0914, 0x0910, 0x090C, 0x01C3, 0x01C4, 0x01C5), }, { .channel = 161, .freq = 5805, /* MHz */ @@ -1075,7 +1075,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401), + PHYREGS(0x0916, 0x0912, 0x090E, 0x01C3, 0x01C4, 0x01C4), }, { .channel = 162, .freq = 5810, /* MHz */ @@ -1083,7 +1083,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401), + PHYREGS(0x0918, 0x0914, 0x0910, 0x01C2, 0x01C3, 0x01C4), }, { .channel = 163, .freq = 5815, /* MHz */ @@ -1091,7 +1091,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401), + PHYREGS(0x091A, 0x0916, 0x0912, 0x01C2, 0x01C3, 0x01C4), }, { .channel = 164, .freq = 5820, /* MHz */ @@ -1099,7 +1099,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301), + PHYREGS(0x091C, 0x0918, 0x0914, 0x01C2, 0x01C2, 0x01C3), }, { .channel = 165, .freq = 5825, /* MHz */ @@ -1107,7 +1107,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301), + PHYREGS(0x091E, 0x091A, 0x0916, 0x01C1, 0x01C2, 0x01C3), }, { .channel = 166, .freq = 5830, /* MHz */ @@ -1115,7 +1115,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201), + PHYREGS(0x0920, 0x091C, 0x0918, 0x01C1, 0x01C2, 0x01C2), }, { .channel = 168, .freq = 5840, /* MHz */ @@ -1123,7 +1123,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201), + PHYREGS(0x0924, 0x0920, 0x091C, 0x01C0, 0x01C1, 0x01C2), }, { .channel = 170, .freq = 5850, /* MHz */ @@ -1131,7 +1131,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101), + PHYREGS(0x0928, 0x0924, 0x0920, 0x01BF, 0x01C0, 0x01C1), }, { .channel = 172, .freq = 5860, /* MHz */ @@ -1139,7 +1139,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001), + PHYREGS(0x092C, 0x0928, 0x0924, 0x01BF, 0x01BF, 0x01C0), }, { .channel = 174, .freq = 5870, /* MHz */ @@ -1147,7 +1147,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01), + PHYREGS(0x0930, 0x092C, 0x0928, 0x01BE, 0x01BF, 0x01BF), }, { .channel = 176, .freq = 5880, /* MHz */ @@ -1155,7 +1155,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01), + PHYREGS(0x0934, 0x0930, 0x092C, 0x01BD, 0x01BE, 0x01BF), }, { .channel = 178, .freq = 5890, /* MHz */ @@ -1163,7 +1163,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01), + PHYREGS(0x0938, 0x0934, 0x0930, 0x01BC, 0x01BD, 0x01BE), }, { .channel = 180, .freq = 5900, /* MHz */ @@ -1171,7 +1171,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01), + PHYREGS(0x093C, 0x0938, 0x0934, 0x01BC, 0x01BC, 0x01BD), }, { .channel = 182, .freq = 5910, /* MHz */ @@ -1179,7 +1179,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01), + PHYREGS(0x0940, 0x093C, 0x0938, 0x01BB, 0x01BC, 0x01BC), }, { .channel = 1, .freq = 2412, /* MHz */ @@ -1187,7 +1187,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), - PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304), + PHYREGS(0x03C9, 0x03C5, 0x03C1, 0x043A, 0x043F, 0x0443), }, { .channel = 2, .freq = 2417, /* MHz */ @@ -1195,7 +1195,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), - PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104), + PHYREGS(0x03CB, 0x03C7, 0x03C3, 0x0438, 0x043D, 0x0441), }, { .channel = 3, .freq = 2422, /* MHz */ @@ -1203,7 +1203,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04), + PHYREGS(0x03CD, 0x03C9, 0x03C5, 0x0436, 0x043A, 0x043F), }, { .channel = 4, .freq = 2427, /* MHz */ @@ -1211,7 +1211,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04), + PHYREGS(0x03CF, 0x03CB, 0x03C7, 0x0434, 0x0438, 0x043D), }, { .channel = 5, .freq = 2432, /* MHz */ @@ -1219,7 +1219,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), - PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04), + PHYREGS(0x03D1, 0x03CD, 0x03C9, 0x0431, 0x0436, 0x043A), }, { .channel = 6, .freq = 2437, /* MHz */ @@ -1227,7 +1227,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), - PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804), + PHYREGS(0x03D3, 0x03CF, 0x03CB, 0x042F, 0x0434, 0x0438), }, { .channel = 7, .freq = 2442, /* MHz */ @@ -1235,7 +1235,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), - PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604), + PHYREGS(0x03D5, 0x03D1, 0x03CD, 0x042D, 0x0431, 0x0436), }, { .channel = 8, .freq = 2447, /* MHz */ @@ -1243,7 +1243,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), - PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404), + PHYREGS(0x03D7, 0x03D3, 0x03CF, 0x042B, 0x042F, 0x0434), }, { .channel = 9, .freq = 2452, /* MHz */ @@ -1251,7 +1251,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), - PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104), + PHYREGS(0x03D9, 0x03D5, 0x03D1, 0x0429, 0x042D, 0x0431), }, { .channel = 10, .freq = 2457, /* MHz */ @@ -1259,7 +1259,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), - PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04), + PHYREGS(0x03DB, 0x03D7, 0x03D3, 0x0427, 0x042B, 0x042F), }, { .channel = 11, .freq = 2462, /* MHz */ @@ -1267,7 +1267,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), - PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04), + PHYREGS(0x03DD, 0x03D9, 0x03D5, 0x0424, 0x0429, 0x042D), }, { .channel = 12, .freq = 2467, /* MHz */ @@ -1275,7 +1275,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), - PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04), + PHYREGS(0x03DF, 0x03DB, 0x03D7, 0x0422, 0x0427, 0x042B), }, { .channel = 13, .freq = 2472, /* MHz */ @@ -1283,7 +1283,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), - PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904), + PHYREGS(0x03E1, 0x03DD, 0x03D9, 0x0420, 0x0424, 0x0429), }, { .channel = 14, .freq = 2484, /* MHz */ @@ -1291,7 +1291,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), - PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404), + PHYREGS(0x03E6, 0x03E2, 0x03DE, 0x041B, 0x041F, 0x0424), }, }; -- cgit v1.2.3-59-g8ed1b From c0f05b9879a324937f14270e4a14d661d2beca63 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 13:27:58 +0100 Subject: b43: N-PHY: minor fixes to match specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index afbfdf0ee6e0..fce5232336b4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -876,7 +876,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) data[2] = lna_gain[2] + gain[i]; data[3] = lna_gain[3] + gain[i]; } - b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data); + b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data); minmax[i] = 23 + gain[i]; } @@ -896,6 +896,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) struct b43_phy_n *nphy = dev->phy.n; u8 i, j; u8 code; + u16 tmp; /* TODO: for PHY >= 3 s8 *lna1_gain, *lna2_gain; @@ -1000,9 +1001,11 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) for (i = 0; i < 4; i++) { b43_phy_write(dev, B43_NPHY_TABLE_ADDR, (0x0400 * i) + 0x0020); - for (j = 0; j < 21; j++) + for (j = 0; j < 21; j++) { + tmp = j * (i < 2 ? 3 : 1); b43_phy_write(dev, - B43_NPHY_TABLE_DATALO, 3 * j); + B43_NPHY_TABLE_DATALO, tmp); + } } b43_nphy_set_rf_sequence(dev, 5, -- cgit v1.2.3-59-g8ed1b From a5d3598de086cd38f71fe2fec43ac3ca97bb24bb Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 13:27:59 +0100 Subject: b43: N-PHY: fix some typos, conditions, set gain_boost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index fce5232336b4..cbdee308bb50 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -919,15 +919,15 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) B43_NPHY_C2_CGAINI_CL2DETECT); /* Set narrowband clip threshold */ - b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); - b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); + b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); + b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); if (!dev->phy.is_40mhz) { /* Set dwell lengths */ - b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); - b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); - b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); - b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); + b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); + b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); + b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); + b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); } /* Set wideband clip 2 threshold */ @@ -949,7 +949,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); } - b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); + b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); if (nphy->gain_boost) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && @@ -970,10 +970,10 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, - (code << 8 | 0x7C)); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, - (code << 8 | 0x7C)); + /* specs say about 2 loops, but wl does 4 */ + for (i = 0; i < 4; i++) + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x7C)); b43_nphy_adjust_lna_gain_table(dev); @@ -991,10 +991,10 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, - (code << 8 | 0x74)); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, - (code << 8 | 0x74)); + /* specs say about 2 loops, but wl does 4 */ + for (i = 0; i < 4; i++) + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x74)); } if (dev->phy.rev == 2) { @@ -1034,7 +1034,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) b43_nphy_classifier(dev, 1, 0); else b43_nphy_classifier(dev, 1, 1); @@ -3459,7 +3459,8 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev) memset(nphy, 0, sizeof(*nphy)); - //TODO init struct b43_phy_n + /* wl goes path which is executed for gain_boost, assume it is true */ + nphy->gain_boost = true; } static void b43_nphy_op_free(struct b43_wldev *dev) -- cgit v1.2.3-59-g8ed1b From bec186452b4cfecff9e2c579bfd4016119d39614 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 13:28:00 +0100 Subject: b43: N-PHY: init BPHY when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index cbdee308bb50..d52d51491055 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1573,6 +1573,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, } } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */ static void b43_nphy_bphy_init(struct b43_wldev *dev) { unsigned int i; @@ -3240,6 +3241,9 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_classifier(dev, 0, 0); b43_nphy_read_clip_detection(dev, clip); + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_nphy_bphy_init(dev); + tx_pwr_state = nphy->txpwrctrl; /* TODO N PHY TX power control with argument 0 (turning off power control) */ -- cgit v1.2.3-59-g8ed1b From fee613b77df721781b9794945f0f1a8f535456ff Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 21:11:41 +0100 Subject: b43: N-PHY: fix BPHY init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d52d51491055..bf0d63d61b6a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1580,13 +1580,13 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev) u16 val; val = 0x1E1F; - for (i = 0; i < 14; i++) { + for (i = 0; i < 16; i++) { b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val); val -= 0x202; } val = 0x3E3F; for (i = 0; i < 16; i++) { - b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val); + b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val); val -= 0x202; } b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); -- cgit v1.2.3-59-g8ed1b From a529cecd29ecf1e5416316ae06ce515bf67b5d5a Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 21:11:42 +0100 Subject: b43: N-PHY: rev2: save and restore PHY regs on RSSI poll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index bf0d63d61b6a..dc4045de61f2 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1846,6 +1846,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); + } else if (dev->phy.rev == 2) { + save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); + save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD); + save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); + save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); + save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); } b43_nphy_rssi_select(dev, 5, type); @@ -1889,6 +1897,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); + } else if (dev->phy.rev == 2) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]); + b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]); + b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]); + b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]); + b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]); } return out; -- cgit v1.2.3-59-g8ed1b From 0b81c23d2e3a8589514fa69b2f153f006a4ad773 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 18 Nov 2010 21:11:43 +0100 Subject: b43: N-PHY: little cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove some typos, warnings, initialize some values to follow wl's code path. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index dc4045de61f2..9769483156e7 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -573,7 +573,6 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) ii = est.i1_pwr; qq = est.q1_pwr; } else { - B43_WARN_ON(1); continue; } @@ -2029,7 +2028,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) } b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); - b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]); + b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]); switch (state[2]) { case 1: @@ -3113,7 +3112,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) { struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; - u16 buf[16]; + /* u16 buf[16]; it's rev3+ */ nphy->phyrxchain = mask; @@ -3409,7 +3408,6 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, enum nl80211_channel_type channel_type) { struct b43_phy *phy = &dev->phy; - struct b43_phy_n *nphy = dev->phy.n; const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; @@ -3479,8 +3477,9 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev) memset(nphy, 0, sizeof(*nphy)); - /* wl goes path which is executed for gain_boost, assume it is true */ - nphy->gain_boost = true; + nphy->gain_boost = true; /* this way we follow wl, assume it is true */ + nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ + nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */ } static void b43_nphy_op_free(struct b43_wldev *dev) @@ -3553,8 +3552,6 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, bool blocked) { - struct b43_phy_n *nphy = dev->phy.n; - if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) b43err(dev->wl, "MAC not suspended\n"); -- cgit v1.2.3-59-g8ed1b From c8a7972c3b3633bf90daf50b135665d8ca4838c4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 19 Nov 2010 22:55:37 +0100 Subject: mac80211: restart beacon miss timer on system resume from suspend Signed-off-by: Paul Stewart Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dfc4a316ac1c..84e24df234e2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2012,6 +2012,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) add_timer(&ifmgd->timer); if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) add_timer(&ifmgd->chswitch_timer); + ieee80211_sta_reset_beacon_monitor(sdata); } #endif -- cgit v1.2.3-59-g8ed1b From 7ccc8bd7593634d827e8bc55898a5038e29848b5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 19 Nov 2010 22:55:38 +0100 Subject: mac80211: calculate beacon loss time accurately Instead of using a fixed 2 second timeout, calculate beacon loss interval from the advertised beacon interval and a frame count. With this beacon loss happens after N (default 7) consecutive frames are missed which for a typical setup (100TU beacon interval) is ~700ms (or ~1/3 previous). Signed-off-by: Sam Leffler Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3598abf21844..ff7bc307827b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -349,6 +349,7 @@ struct ieee80211_if_managed { struct work_struct chswitch_work; struct work_struct beacon_connection_loss_work; + unsigned long beacon_timeout; unsigned long probe_timeout; int probe_send_count; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 84e24df234e2..729aba49cf98 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -31,10 +31,15 @@ #define IEEE80211_MAX_PROBE_TRIES 5 /* - * beacon loss detection timeout - * XXX: should depend on beacon interval + * Beacon loss timeout is calculated as N frames times the + * advertised beacon interval. This may need to be somewhat + * higher than what hardware might detect to account for + * delays in the host processing frames. But since we also + * probe on beacon miss before declaring the connection lost + * default to what we want. */ -#define IEEE80211_BEACON_LOSS_TIME (2 * HZ) +#define IEEE80211_BEACON_LOSS_COUNT 7 + /* * Time the connection can be idle before we probe * it to see if we can still talk to the AP. @@ -121,7 +126,7 @@ void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) return; mod_timer(&sdata->u.mgd.bcn_mon_timer, - round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); + round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout)); } void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) @@ -871,6 +876,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= ieee80211_handle_bss_capability(sdata, cbss->capability, bss->has_erp_value, bss->erp_value); + sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( + IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); + sdata->u.mgd.associated = cbss; memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); -- cgit v1.2.3-59-g8ed1b From 46090979a55a0dc2cdb3d939f94fa47742108194 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 23 Nov 2010 20:28:03 +0100 Subject: mac80211: probe the AP when resuming Check the connection by probing the AP (either using nullfunc or a probe request). If nullfunc probing is supported and the assoc is no longer valid, the AP will send a disassoc/deauth immediately. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 729aba49cf98..849d9c639add 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2021,6 +2021,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) add_timer(&ifmgd->chswitch_timer); ieee80211_sta_reset_beacon_monitor(sdata); + ieee80211_restart_sta_timer(sdata); } #endif -- cgit v1.2.3-59-g8ed1b From dd5b4cc71cd09c33e1579cc6d5720656e94e52de Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 22 Nov 2010 20:58:24 +0100 Subject: cfg80211/mac80211: improve ad-hoc multicast rate handling - store the multicast rate as an index instead of the rate value (reduces cpu overhead in a hotpath) - validate the rate values (must match a bitrate in at least one sband) Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 ++-- include/net/mac80211.h | 4 ++-- net/mac80211/ibss.c | 3 ++- net/mac80211/rate.c | 25 ++++++++++++------------- net/wireless/nl80211.c | 36 +++++++++++++++++++++++++++++++++--- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 91f099556ac1..dd4c43f512e2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -923,7 +923,7 @@ struct cfg80211_disassoc_request { * @privacy: this is a protected network, keys will be configured * after joining * @basic_rates: bitmap of basic rates to use when creating the IBSS - * @mcast_rate: multicast tx rate (in 100 kbps) + * @mcast_rate: per-band multicast rate index + 1 (0: disabled) */ struct cfg80211_ibss_params { u8 *ssid; @@ -935,7 +935,7 @@ struct cfg80211_ibss_params { u32 basic_rates; bool channel_fixed; bool privacy; - int mcast_rate; + int mcast_rate[IEEE80211_NUM_BANDS]; }; /** diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5b0fff2178bb..08e97e5d03fd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -219,7 +219,7 @@ enum ieee80211_bss_change { * @basic_rates: bitmap of basic rates, each bit stands for an * index into the rate table configured by the driver in * the current band. - * @mcast_rate: multicast rate for AP and Ad-Hoc (in 100 kbps) + * @mcast_rate: per-band multicast rate index + 1 (0: disabled) * @bssid: The BSSID for this BSS * @enable_beacon: whether beaconing should be enabled or not * @channel_type: Channel type for this BSS -- the hardware might be @@ -259,7 +259,7 @@ struct ieee80211_bss_conf { u16 assoc_capability; u64 timestamp; u32 basic_rates; - u32 mcast_rate; + int mcast_rate[IEEE80211_NUM_BANDS]; u16 ht_operation_mode; s32 cqm_rssi_thold; u32 cqm_rssi_hyst; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 6fe6837dc134..410d104b1347 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -915,7 +915,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.privacy = params->privacy; sdata->u.ibss.basic_rates = params->basic_rates; - sdata->vif.bss_conf.mcast_rate = params->mcast_rate; + memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, + sizeof(params->mcast_rate)); sdata->vif.bss_conf.beacon_int = params->beacon_interval; diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 76de4f8d9327..3d5a2cb835c4 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -211,20 +211,11 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); } -static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u32 mcast_rate, +static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, struct ieee80211_supported_band *sband) { u8 i; - if (mcast_rate) { - for (i = 0; i < sband->n_bitrates; i++) { - if (sband->bitrates[i].bitrate == mcast_rate) { - *idx = i; - return; - } - } - } - if (basic_rates == 0) return; /* assume basic rates unknown and accept rate */ if (*idx < 0) @@ -247,17 +238,25 @@ bool rate_control_send_low(struct ieee80211_sta *sta, struct ieee80211_tx_rate_control *txrc) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); + struct ieee80211_supported_band *sband = txrc->sband; + int mcast_rate; if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) { info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta); info->control.rates[0].count = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 1 : txrc->hw->max_rate_tries; - if (!sta && txrc->bss) + if (!sta && txrc->bss) { + mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; + if (mcast_rate > 0) { + info->control.rates[0].idx = mcast_rate - 1; + return true; + } + rc_send_low_broadcast(&info->control.rates[0].idx, txrc->bss_conf->basic_rates, - txrc->bss_conf->mcast_rate, - txrc->sband); + sband); + } return true; } return false; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b15eb77195d8..8734efa663d1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3600,6 +3600,34 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) local_state_change); } +static bool +nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev, + int mcast_rate[IEEE80211_NUM_BANDS], + int rateval) +{ + struct wiphy *wiphy = &rdev->wiphy; + bool found = false; + int band, i; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + struct ieee80211_supported_band *sband; + + sband = wiphy->bands[band]; + if (!sband) + continue; + + for (i = 0; i < sband->n_bitrates; i++) { + if (sband->bitrates[i].bitrate == rateval) { + mcast_rate[band] = i + 1; + found = true; + break; + } + } + } + + return found; +} + static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -3683,9 +3711,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } } - if (info->attrs[NL80211_ATTR_MCAST_RATE]) - ibss.mcast_rate = - nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]); + + if (info->attrs[NL80211_ATTR_MCAST_RATE] && + !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate, + nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) + return -EINVAL; if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { connkeys = nl80211_parse_connkeys(rdev, -- cgit v1.2.3-59-g8ed1b From 4e5ff37692df35c8826f1291204841b174d3c3ce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 23 Nov 2010 03:10:31 +0100 Subject: mac80211: use nullfunc instead of probe request for connection monitoring nullfunc frames are better for connection monitoring, because probe requests are answered even if the AP has already dropped the connection, whereas nullfunc frames from an unassociated station will trigger a disassoc/deauth frame from the AP (WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA), which allows the station to reconnect immediately instead of waiting until it attempts to transmit the next unicast frame. This only works on hardware with reliable tx ACK reporting, any other hardware needs to fall back to the probe request method. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 + net/mac80211/mlme.c | 92 +++++++++++++++++++++++++++++++++------------- net/mac80211/status.c | 4 ++ 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ff7bc307827b..5bc0745368fe 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1265,6 +1265,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, int powersave); void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr); +void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr); void ieee80211_beacon_connection_loss_work(struct work_struct *work); void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 849d9c639add..33ffce3ec605 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1034,6 +1034,51 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, ieee80211_sta_reset_conn_monitor(sdata); } +static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | + IEEE80211_STA_CONNECTION_POLL))) + return; + + ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | + IEEE80211_STA_BEACON_POLL); + mutex_lock(&sdata->local->iflist_mtx); + ieee80211_recalc_ps(sdata->local, -1); + mutex_unlock(&sdata->local->iflist_mtx); + + if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) + return; + + /* + * We've received a probe response, but are not sure whether + * we have or will be receiving any beacons or data, so let's + * schedule the timers again, just in case. + */ + ieee80211_sta_reset_beacon_monitor(sdata); + + mod_timer(&ifmgd->conn_mon_timer, + round_jiffies_up(jiffies + + IEEE80211_CONNECTION_IDLE_TIME)); +} + +void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr) +{ + if (!ieee80211_is_data(hdr->frame_control) && + !ieee80211_is_nullfunc(hdr->frame_control)) + return; + + ieee80211_sta_reset_conn_monitor(sdata); + + if (ieee80211_is_nullfunc(hdr->frame_control) && + sdata->u.mgd.probe_send_count > 0) { + sdata->u.mgd.probe_send_count = 0; + ieee80211_queue_work(&sdata->local->hw, &sdata->work); + } +} + static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; @@ -1049,8 +1094,19 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) if (ifmgd->probe_send_count >= unicast_limit) dst = NULL; - ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); - ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); + /* + * When the hardware reports an accurate Tx ACK status, it's + * better to send a nullfunc frame instead of a probe request, + * as it will kick us off the AP quickly if we aren't associated + * anymore. The timeout will be reset if the frame is ACKed by + * the AP. + */ + if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) + ieee80211_send_nullfunc(sdata->local, sdata, 0); + else { + ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); + ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); + } ifmgd->probe_send_count++; ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; @@ -1517,29 +1573,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); if (ifmgd->associated && - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 && - ifmgd->flags & (IEEE80211_STA_BEACON_POLL | - IEEE80211_STA_CONNECTION_POLL)) { - ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | - IEEE80211_STA_BEACON_POLL); - mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_ps(sdata->local, -1); - mutex_unlock(&sdata->local->iflist_mtx); - - if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) - return; - - /* - * We've received a probe response, but are not sure whether - * we have or will be receiving any beacons or data, so let's - * schedule the timers again, just in case. - */ - ieee80211_sta_reset_beacon_monitor(sdata); - - mod_timer(&ifmgd->conn_mon_timer, - round_jiffies_up(jiffies + - IEEE80211_CONNECTION_IDLE_TIME)); - } + memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) + ieee80211_reset_ap_probe(sdata); } /* @@ -1891,7 +1926,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) u8 bssid[ETH_ALEN]; memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); - if (time_is_after_jiffies(ifmgd->probe_timeout)) + + /* ACK received for nullfunc probing frame */ + if (!ifmgd->probe_send_count) + ieee80211_reset_ap_probe(sdata); + + else if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3153c19893b8..8695cd11dfd9 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -155,6 +155,10 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) ieee80211_queue_work(&local->hw, &local->recalc_smps); } + + if ((sdata->vif.type == NL80211_IFTYPE_STATION) && + (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) + ieee80211_sta_tx_notify(sdata, (void *) skb->data); } void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) -- cgit v1.2.3-59-g8ed1b From 72a8a3edd630995662bdc85957206685f376f9c4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 23 Nov 2010 03:10:32 +0100 Subject: mac80211: reduce the number of retries for nullfunc probing Since nullfunc frames are transmitted as unicast frames, they're more reliable than the broadcast probe requests, so we need fewer retries to figure out whether the AP is really gone. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 33ffce3ec605..794807914940 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -28,6 +28,7 @@ #include "rate.h" #include "led.h" +#define IEEE80211_MAX_NULLFUNC_TRIES 2 #define IEEE80211_MAX_PROBE_TRIES 5 /* @@ -1924,9 +1925,15 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) IEEE80211_STA_CONNECTION_POLL) && ifmgd->associated) { u8 bssid[ETH_ALEN]; + int max_tries; memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) + max_tries = IEEE80211_MAX_NULLFUNC_TRIES; + else + max_tries = IEEE80211_MAX_PROBE_TRIES; + /* ACK received for nullfunc probing frame */ if (!ifmgd->probe_send_count) ieee80211_reset_ap_probe(sdata); @@ -1934,7 +1941,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) else if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); - else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { + else if (ifmgd->probe_send_count < max_tries) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG wiphy_debug(local->hw.wiphy, "%s: No probe response from AP %pM" -- cgit v1.2.3-59-g8ed1b From c8b576061d87e2a4fb100e70c6a6dae189b3a310 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 23 Nov 2010 15:05:01 -0800 Subject: ath9k: avoid aggregation for VO traffic This should help with latency issues which can happen when using aggregation. Cc: Matt Smith Cc: Senthil Balasubramanian Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ee4566d9d234..3e6ea3bc3d89 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1363,7 +1363,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, /* Check if aggregation has to be enabled for this tid */ if (conf_is_ht(&sc->hw->conf) && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { - if (ieee80211_is_data_qos(fc)) { + if (ieee80211_is_data_qos(fc) && + skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { u8 *qc, tid; struct ath_node *an; -- cgit v1.2.3-59-g8ed1b From 48124d1a91fb77defc9734b4556350d59671fb2c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 23 Nov 2010 15:05:02 -0800 Subject: mac80211: avoid aggregation for VO traffic This should help with latency issues which can happen when using aggregation. Cc: Felix Fietkau Cc: Matt Smith Cc: Senthil Balasubramanian Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2d6f0259e0c6..4ad7a362fcc1 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -371,6 +371,9 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru if (likely(sta->ampdu_mlme.tid_tx[tid])) return; + if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) + return; + ieee80211_start_tx_ba_session(pubsta, tid); } -- cgit v1.2.3-59-g8ed1b From 79b1c460a0b55e55981c25c56597c4d5d2872de3 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 24 Nov 2010 14:34:41 +0900 Subject: cfg80211: Add documentation for antenna ops Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/net/mac80211.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 08e97e5d03fd..eaa4affd40cd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1745,6 +1745,13 @@ enum ieee80211_ampdu_mlme_action { * completion of the channel switch. * * @napi_poll: Poll Rx queue for incoming data frames. + * + * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. + * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may + * reject TX/RX mask combinations they cannot support by returning -EINVAL + * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). + * + * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). */ struct ieee80211_ops { int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); -- cgit v1.2.3-59-g8ed1b From c063dbf52b998b852122dff07a8b8dd430b38437 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 24 Nov 2010 08:10:05 +0100 Subject: cfg80211: allow using CQM event to notify packet loss This adds the ability for drivers to use CQM events to notify about packet loss for specific stations (which could be the AP for the managed mode case). Since the threshold might be determined by the driver (it isn't passed in right now) it will be passed out of the driver to userspace in the event. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 3 +++ include/net/cfg80211.h | 12 ++++++++++++ net/wireless/mlme.c | 12 ++++++++++++ net/wireless/nl80211.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 5 files changed, 76 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 037b4e498890..d706bf3badc8 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1819,6 +1819,8 @@ enum nl80211_ps_state { * the minimum amount the RSSI level must change after an event before a * new event may be issued (to reduce effects of RSSI oscillation). * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event + * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many + * consecutive packets were not acknowledged by the peer * @__NL80211_ATTR_CQM_AFTER_LAST: internal * @NL80211_ATTR_CQM_MAX: highest key attribute */ @@ -1827,6 +1829,7 @@ enum nl80211_attr_cqm { NL80211_ATTR_CQM_RSSI_THOLD, NL80211_ATTR_CQM_RSSI_HYST, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, + NL80211_ATTR_CQM_PKT_LOSS_EVENT, /* keep last */ __NL80211_ATTR_CQM_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index dd4c43f512e2..0663945cfa48 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2601,6 +2601,18 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); +/** + * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer + * @dev: network device + * @peer: peer's MAC address + * @num_packets: how many packets were lost -- should be a fixed threshold + * but probably no less than maybe 50, or maybe a throughput dependent + * threshold (to account for temporary interference) + * @gfp: context flags + */ +void cfg80211_cqm_pktloss_notify(struct net_device *dev, + const u8 *peer, u32 num_packets, gfp_t gfp); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 26838d903b9a..6980a0c315b2 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1028,3 +1028,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); } EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); + +void cfg80211_cqm_pktloss_notify(struct net_device *dev, + const u8 *peer, u32 num_packets, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + /* Indicate roaming trigger event to user space */ + nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); +} +EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8734efa663d1..67ff7e92cb99 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5715,6 +5715,51 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void +nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *peer, + u32 num_packets, gfp_t gfp) +{ + struct sk_buff *msg; + struct nlattr *pinfoattr; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer); + + pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); + if (!pinfoattr) + goto nla_put_failure; + + NLA_PUT_U32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets); + + nla_nest_end(msg, pinfoattr); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + static int nl80211_netlink_notify(struct notifier_block * nb, unsigned long state, void *_notify) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 30d2f939150d..16c2f7190768 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -87,5 +87,9 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); +void +nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *peer, + u32 num_packets, gfp_t gfp); #endif /* __NET_WIRELESS_NL80211_H */ -- cgit v1.2.3-59-g8ed1b From 99ba2a14283be96a682e04455061c08a46bbf4ec Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 24 Nov 2010 08:10:06 +0100 Subject: mac80211: implement packet loss notification For drivers that have accurate TX status reporting we can report the number of consecutive lost packets to userspace using the new cfg80211 CQM event. The threshold is fixed right now, this may need to be improved in the future. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/sta_info.h | 3 +++ net/mac80211/status.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9265acadef32..b562d9b6a702 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -248,6 +248,7 @@ enum plink_state { * @sta: station information we share with the driver * @dead: set to true when sta is unlinked * @uploaded: set to true when sta is uploaded to the driver + * @lost_packets: number of consecutive lost packets */ struct sta_info { /* General information, mostly static */ @@ -335,6 +336,8 @@ struct sta_info { } debugfs; #endif + unsigned int lost_packets; + /* keep last! */ struct ieee80211_sta sta; }; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 8695cd11dfd9..bed7e32ed908 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -161,6 +161,15 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) ieee80211_sta_tx_notify(sdata, (void *) skb->data); } +/* + * Use a static threshold for now, best value to be determined + * by testing ... + * Should it depend on: + * - on # of retransmissions + * - current throughput (higher value for higher tpt)? + */ +#define STA_LOST_PKT_THRESHOLD 50 + void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) { struct sk_buff *skb2; @@ -247,6 +256,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && (info->flags & IEEE80211_TX_STAT_ACK)) ieee80211_frame_acked(sta, skb); + + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { + if (info->flags & IEEE80211_TX_STAT_ACK) { + if (sta->lost_packets) + sta->lost_packets = 0; + } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) { + cfg80211_cqm_pktloss_notify(sta->sdata->dev, + sta->sta.addr, + sta->lost_packets, + GFP_ATOMIC); + sta->lost_packets = 0; + } + } } rcu_read_unlock(); -- cgit v1.2.3-59-g8ed1b From eeb1f83fa8f96501331cc17b73c57999e3a1ec5d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 23 Nov 2010 10:58:52 -0800 Subject: iwlagn: name change for BT config flag Bit 7 of BT config flag is used to enable/disable PSPoll sync. Make the name to match it. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9c1b7fbef099..4028ed387a82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2439,8 +2439,9 @@ struct iwl_bt_cmd { #define IWLAGN_BT_FLAG_COEX_MODE_3W 2 #define IWLAGN_BT_FLAG_COEX_MODE_4W 3 -#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) -#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7) +#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) +/* Disable Sync PSPoll on SCO/eSCO */ +#define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7) #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 -- cgit v1.2.3-59-g8ed1b From 97badb0eefc9b6f23f864c5348b695be35f05882 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 23 Nov 2010 10:58:53 -0800 Subject: iwlwifi: add more power management flags Adding additional power management option available for the device. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 4028ed387a82..f9e7fa4b532c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2671,6 +2671,11 @@ struct iwl_spectrum_notification { #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) +#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) +#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) +#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) +#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) +#define IWL_POWER_ADVANCE_PM_ENA cpu_to_le16(BIT(9)) struct iwl3945_powertable_cmd { __le16 flags; -- cgit v1.2.3-59-g8ed1b From e366176e5c7f37d2d4cd0708e63b939e3fa3b5c6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 23 Nov 2010 10:58:54 -0800 Subject: iwlwifi: consider BT for power management Check the BT PSPoll flag when fill PM command to uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-power.c | 17 +++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 0cc66fdc7a0d..f650282a3ad3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -549,6 +549,7 @@ static struct iwl_bt_params iwl6000_bt_params = { .agg_time_limit = BT_AGG_THRESHOLD_DEF, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, + .bt_sco_disable = true, }; struct iwl_cfg iwl6000g2a_2agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c4491f7641fe..f8fe5f44e19f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1829,6 +1829,10 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) } else { bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << IWLAGN_BT_FLAG_COEX_MODE_SHIFT; + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_sco_disable) + bt_cmd.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE; + if (priv->bt_ch_announce) bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 9035cd82d85b..3f7bd4012c29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -334,6 +334,7 @@ struct iwl_base_params { * @agg_time_limit: maximum number of uSec in aggregation * @ampdu_factor: Maximum A-MPDU length factor * @ampdu_density: Minimum A-MPDU spacing + * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode */ struct iwl_bt_params { bool advanced_bt_coexist; @@ -343,6 +344,7 @@ struct iwl_bt_params { u16 agg_time_limit; u8 ampdu_factor; u8 ampdu_density; + bool bt_sco_disable; }; /* * @use_rts_for_aggregation: use rts/cts protection for HT traffic diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index b7abd86676fd..306c852b1578 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -163,6 +163,15 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + if (!priv->cfg->bt_params->bt_sco_disable) + cmd->flags |= IWL_POWER_BT_SCO_ENA; + else + cmd->flags &= ~IWL_POWER_BT_SCO_ENA; + } + + slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL) cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = @@ -236,6 +245,14 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, if (priv->power_data.pci_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + if (!priv->cfg->bt_params->bt_sco_disable) + cmd->flags |= IWL_POWER_BT_SCO_ENA; + else + cmd->flags &= ~IWL_POWER_BT_SCO_ENA; + } + cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms); cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); -- cgit v1.2.3-59-g8ed1b From 1f37daf3233ccda5072f715d6c322d84833cdd92 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 23 Nov 2010 10:58:55 -0800 Subject: iwlwifi: power management checking for shadow register If shadow register is enable, modify the power management command to inform uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-power.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 306c852b1578..21c5e6abfbd0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -163,6 +163,11 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; + if (priv->cfg->base_params->shadow_reg_enable) + cmd->flags |= IWL_POWER_SHADOW_REG_ENA; + else + cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { if (!priv->cfg->bt_params->bt_sco_disable) @@ -245,6 +250,11 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, if (priv->power_data.pci_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; + if (priv->cfg->base_params->shadow_reg_enable) + cmd->flags |= IWL_POWER_SHADOW_REG_ENA; + else + cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { if (!priv->cfg->bt_params->bt_sco_disable) -- cgit v1.2.3-59-g8ed1b From 35162ba75900209755628ccf7357763797037ba6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 23 Nov 2010 10:58:56 -0800 Subject: iwlwifi: advance power management support For 6000g2b and up, adding advance power management support for better power consumption Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 ++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 4 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-power.c | 68 ++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f650282a3ad3..93e3fe92f389 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -621,6 +621,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -641,6 +642,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -662,6 +664,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -682,6 +685,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -703,6 +707,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -723,6 +728,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -862,6 +868,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -881,6 +888,7 @@ struct iwl_cfg iwl130_bg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, + .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index f9e7fa4b532c..c9448cba1e20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2668,6 +2668,8 @@ struct iwl_spectrum_notification { #define IWL_POWER_VEC_SIZE 5 #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) @@ -2675,7 +2677,7 @@ struct iwl_spectrum_notification { #define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) #define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) #define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) -#define IWL_POWER_ADVANCE_PM_ENA cpu_to_le16(BIT(9)) +#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9)) struct iwl3945_powertable_cmd { __le16 flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3f7bd4012c29..808be731ecb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -366,6 +366,7 @@ struct iwl_ht_params { * @need_temp_offset_calib: need to perform temperature offset calibration * @scan_antennas: available antenna for scan operation * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) + * @adv_pm: advance power management * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -413,6 +414,7 @@ struct iwl_cfg { u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; enum iwl_led_mode led_mode; + const bool adv_pm; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 21c5e6abfbd0..1eec18d909d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -75,6 +75,10 @@ struct iwl_power_vec_entry { #define NOSLP cpu_to_le16(0), 0, 0 #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 +#define ASLP (IWL_POWER_POWER_SAVE_ENA_MSK | \ + IWL_POWER_POWER_MANAGEMENT_ENA_MSK | \ + IWL_POWER_ADVANCE_PM_ENA_MSK) +#define ASLP_TOUT(T) cpu_to_le32(T) #define TU_TO_USEC 1024 #define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ @@ -114,6 +118,52 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} }; +/* advance power management */ +/* DTIM 0 - 2 */ +static const struct iwl_power_vec_entry apm_range_0[IWL_POWER_NUM] = { + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} +}; + + +/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ +/* DTIM 3 - 10 */ +static const struct iwl_power_vec_entry apm_range_1[IWL_POWER_NUM] = { + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 6, 8, 0xFF), 0}, 2} +}; + +/* for DTIM period > IWL_DTIM_RANGE_1_MAX */ +/* DTIM 11 - */ +static const struct iwl_power_vec_entry apm_range_2[IWL_POWER_NUM] = { + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, + {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), + SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} +}; + static void iwl_static_sleep_cmd(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, enum iwl_power_level lvl, int period) @@ -124,11 +174,19 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, u8 skip; u32 slp_itrvl; - table = range_2; - if (period <= IWL_DTIM_RANGE_1_MAX) - table = range_1; - if (period <= IWL_DTIM_RANGE_0_MAX) - table = range_0; + if (priv->cfg->adv_pm) { + table = apm_range_2; + if (period <= IWL_DTIM_RANGE_1_MAX) + table = apm_range_1; + if (period <= IWL_DTIM_RANGE_0_MAX) + table = apm_range_0; + } else { + table = range_2; + if (period <= IWL_DTIM_RANGE_1_MAX) + table = range_1; + if (period <= IWL_DTIM_RANGE_0_MAX) + table = range_0; + } BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); -- cgit v1.2.3-59-g8ed1b From bedbbb959d2c1d1dbb4c2215f5b7074b1da3030a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 19 Nov 2010 16:53:19 +0530 Subject: ath: Add a driver_info bitmask field The driver_info stores the device category information which is used to load appropriate device firmware, select firmware offset and eeprom starting location. The driver_info is accessed across ath9k_htc and ath9k_hw. Hence placed under common structure. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 501050c0296f..20ea68c59f7b 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -104,6 +104,11 @@ enum ath_cipher { ATH_CIPHER_MIC = 127 }; +enum ath_drv_info { + AR7010_DEVICE = BIT(0), + AR9287_DEVICE = BIT(1), +}; + /** * struct ath_ops - Register read/write operations * @@ -147,6 +152,7 @@ struct ath_common { u8 rx_chainmask; u32 rx_bufsize; + u32 driver_info; u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); -- cgit v1.2.3-59-g8ed1b From 64f121708342afec306ce52920cc9982f4f1008f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 19 Nov 2010 16:53:20 +0530 Subject: ath9k_htc: Add driver_info in usb device list Added driver_info to identify AR7010, R9287 HTC devices. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab92..6a0dbd153349 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -28,10 +28,16 @@ MODULE_FIRMWARE(FIRMWARE_AR9271); static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */ - { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */ - { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */ + { USB_DEVICE(0x0cf3, 0x7010), + .driver_info = AR7010_DEVICE }, + /* Atheros */ + { USB_DEVICE(0x0cf3, 0x7015), + .driver_info = AR7010_DEVICE | AR9287_DEVICE }, + /* Atheros */ { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */ - { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */ + { USB_DEVICE(0x0846, 0x9018), + .driver_info = AR7010_DEVICE }, + /* Netgear WNDA3200 */ { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ @@ -40,9 +46,13 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ - { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ + { USB_DEVICE(0x083A, 0xA704), + .driver_info = AR7010_DEVICE }, + /* SMC Networks */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ - { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */ + { USB_DEVICE(0x1668, 0x1200), + .driver_info = AR7010_DEVICE | AR9287_DEVICE }, + /* Verizon */ { }, }; -- cgit v1.2.3-59-g8ed1b From f7ec8fb4d6f8f3ecb8b11e9e46ece95aa66139cc Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 19 Nov 2010 16:53:21 +0530 Subject: ath9k_hw: Fix eeprom offset for AR9287 devices (PCI/USB) AR9287 devices (PCI/USB) use different eeprom start location to read nvram. New devices might endup with same devid. So use driver_info to set offset, instead of devid. driver_info is valid for HTC devices alone which is filled in usb_device_id. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 +++--- drivers/net/wireless/ath/ath9k/reg.h | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index e75697858ae8..bcb9ed39c047 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -37,10 +37,10 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) int addr, eep_start_loc; eep_data = (u16 *)eep; - if (AR9287_HTC_DEVID(ah)) - eep_start_loc = AR9287_HTC_EEP_START_LOC; - else + if (!common->driver_info) eep_start_loc = AR9287_EEP_START_LOC; + else + eep_start_loc = AR9287_HTC_EEP_START_LOC; if (!ath9k_hw_use_flash(ah)) { ath_print(common, ATH_DBG_EEPROM, diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index f1bbc7560c86..9d68237e4d9c 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -870,10 +870,6 @@ ((_ah)->hw_version.devid == 0xA704) || \ ((_ah)->hw_version.devid == 0x1200)) -#define AR9287_HTC_DEVID(_ah) \ - (((_ah)->hw_version.devid == 0x7015) || \ - ((_ah)->hw_version.devid == 0x1200)) - #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 #define AR_RAD2133_SREV_MAJOR 0xd0 -- cgit v1.2.3-59-g8ed1b From fa6e15e0b5952fd2cd99fc6d4f4473f6b9da18df Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 19 Nov 2010 16:53:22 +0530 Subject: ath9k_htc: Identify devices using driver_info Categorize AR7010 & AR9287 devices based on driver_info of usb_device_id, instead of PIDs. This avoids per-device cases and minimize code changes for new device addition. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 41 +++++++++------------------ drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 35 +++++++++++------------ drivers/net/wireless/ath/ath9k/htc_hst.c | 5 ++-- drivers/net/wireless/ath/ath9k/htc_hst.h | 3 +- drivers/net/wireless/ath/ath9k/reg.h | 6 +--- 6 files changed, 37 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 6a0dbd153349..ae842dbf9b50 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -786,7 +786,8 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } -static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) +static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, + u32 drv_info) { int transfer, err; const void *data = hif_dev->firmware->data; @@ -817,18 +818,10 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) } kfree(buf); - switch (hif_dev->device_id) { - case 0x7010: - case 0x7015: - case 0x9018: - case 0xA704: - case 0x1200: + if (drv_info & AR7010_DEVICE) firm_offset = AR7010_FIRMWARE_TEXT; - break; - default: + else firm_offset = AR9271_FIRMWARE_TEXT; - break; - } /* * Issue FW download complete command to firmware. @@ -846,7 +839,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) return 0; } -static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) +static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) { int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; @@ -862,7 +855,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) } /* Download firmware */ - ret = ath9k_hif_usb_download_fw(hif_dev); + ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", @@ -941,23 +934,15 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, /* Find out which firmware to load */ - switch(hif_dev->device_id) { - case 0x7010: - case 0x7015: - case 0x9018: - case 0xA704: - case 0x1200: + if (id->driver_info & AR7010_DEVICE) if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) hif_dev->fw_name = FIRMWARE_AR7010_1_1; else hif_dev->fw_name = FIRMWARE_AR7010; - break; - default: + else hif_dev->fw_name = FIRMWARE_AR9271; - break; - } - ret = ath9k_hif_usb_dev_init(hif_dev); + ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); if (ret) { ret = -EINVAL; goto err_hif_init_usb; @@ -965,7 +950,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, ret = ath9k_htc_hw_init(hif_dev->htc_handle, &hif_dev->udev->dev, hif_dev->device_id, - hif_dev->udev->product); + hif_dev->udev->product, id->driver_info); if (ret) { ret = -EINVAL; goto err_htc_hw_init; @@ -1043,6 +1028,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) { struct hif_device_usb *hif_dev = (struct hif_device_usb *) usb_get_intfdata(interface); + struct htc_target *htc_handle = hif_dev->htc_handle; int ret; ret = ath9k_hif_usb_alloc_urbs(hif_dev); @@ -1050,7 +1036,8 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { - ret = ath9k_hif_usb_download_fw(hif_dev); + ret = ath9k_hif_usb_download_fw(hif_dev, + htc_handle->drv_priv->ah->common.driver_info); if (ret) goto fail_resume; } else { @@ -1060,7 +1047,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) mdelay(100); - ret = ath9k_htc_resume(hif_dev->htc_handle); + ret = ath9k_htc_resume(htc_handle); if (ret) goto fail_resume; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index db00289103fc..afe39a911906 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -461,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv); void ath9k_deinit_leds(struct ath9k_htc_priv *priv); int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid, char *product); + u16 devid, char *product, u32 drv_info); void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); #ifdef CONFIG_PM int ath9k_htc_resume(struct htc_target *htc_handle); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index cba904a3e320..071d0c974747 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -181,7 +181,8 @@ static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv, return htc_connect_service(priv->htc, &req, ep_id); } -static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) +static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, + u32 drv_info) { int ret; @@ -245,17 +246,10 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) * the HIF layer, shouldn't matter much. */ - switch(devid) { - case 0x7010: - case 0x7015: - case 0x9018: - case 0xA704: - case 0x1200: + if (drv_info & AR7010_DEVICE) priv->htc->credits = 45; - break; - default: + else priv->htc->credits = 33; - } ret = htc_init(priv->htc); if (ret) @@ -627,7 +621,8 @@ static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) } static int ath9k_init_priv(struct ath9k_htc_priv *priv, - u16 devid, char *product) + u16 devid, char *product, + u32 drv_info) { struct ath_hw *ah = NULL; struct ath_common *common; @@ -651,6 +646,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common->hw = priv->hw; common->priv = priv; common->debug_mask = ath9k_debug; + common->driver_info = drv_info; spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); @@ -763,7 +759,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, } static int ath9k_init_device(struct ath9k_htc_priv *priv, - u16 devid, char *product) + u16 devid, char *product, u32 drv_info) { struct ieee80211_hw *hw = priv->hw; struct ath_common *common; @@ -772,7 +768,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, struct ath_regulatory *reg; /* Bring up device */ - error = ath9k_init_priv(priv, devid, product); + error = ath9k_init_priv(priv, devid, product, drv_info); if (error != 0) goto err_init; @@ -830,7 +826,7 @@ err_init: } int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid, char *product) + u16 devid, char *product, u32 drv_info) { struct ieee80211_hw *hw; struct ath9k_htc_priv *priv; @@ -857,14 +853,14 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, goto err_free; } - ret = ath9k_init_htc_services(priv, devid); + ret = ath9k_init_htc_services(priv, devid, drv_info); if (ret) goto err_init; /* The device may have been unplugged earlier. */ priv->op_flags &= ~OP_UNPLUGGED; - ret = ath9k_init_device(priv, devid, product); + ret = ath9k_init_device(priv, devid, product, drv_info); if (ret) goto err_init; @@ -894,14 +890,15 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) #ifdef CONFIG_PM int ath9k_htc_resume(struct htc_target *htc_handle) { + struct ath9k_htc_priv *priv = htc_handle->drv_priv; int ret; - ret = ath9k_htc_wait_for_target(htc_handle->drv_priv); + ret = ath9k_htc_wait_for_target(priv); if (ret) return ret; - ret = ath9k_init_htc_services(htc_handle->drv_priv, - htc_handle->drv_priv->ah->hw_version.devid); + ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid, + priv->ah->common.driver_info); return ret; } #endif diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 861ec9269309..c41ab8c30161 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -462,9 +462,10 @@ void ath9k_htc_hw_free(struct htc_target *htc) } int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid, char *product) + struct device *dev, u16 devid, + char *product, u32 drv_info) { - if (ath9k_htc_probe_device(target, dev, devid, product)) { + if (ath9k_htc_probe_device(target, dev, devid, product, drv_info)) { printk(KERN_ERR "Failed to initialize the device\n"); return -ENODEV; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 07b6509d5896..6fc1b21faa5d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -239,7 +239,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct device *dev); void ath9k_htc_hw_free(struct htc_target *htc); int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid, char *product); + struct device *dev, u16 devid, char *product, + u32 drv_info); void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); #endif /* HTC_HST_H */ diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 9d68237e4d9c..a597cc8d8644 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -864,11 +864,7 @@ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) #define AR_DEVID_7010(_ah) \ - (((_ah)->hw_version.devid == 0x7010) || \ - ((_ah)->hw_version.devid == 0x7015) || \ - ((_ah)->hw_version.devid == 0x9018) || \ - ((_ah)->hw_version.devid == 0xA704) || \ - ((_ah)->hw_version.devid == 0x1200)) + ((_ah)->common.driver_info & AR7010_DEVICE) #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 -- cgit v1.2.3-59-g8ed1b From 4f8559383c41262b50dc758e2e310f257ce6a14d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 20 Nov 2010 03:08:48 +0100 Subject: ath9k_hw: remove ath9k_hw_stoppcurecv It is no longer used anywhere Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 8 -------- drivers/net/wireless/ath/ath9k/mac.h | 1 - 2 files changed, 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 65b1ee2a9792..b04b37b1124b 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -766,14 +766,6 @@ void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning) } EXPORT_SYMBOL(ath9k_hw_startpcureceive); -void ath9k_hw_stoppcurecv(struct ath_hw *ah) -{ - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); - - ath9k_hw_disable_mib_counters(ah); -} -EXPORT_SYMBOL(ath9k_hw_stoppcurecv); - void ath9k_hw_abortpcurecv(struct ath_hw *ah) { REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 22907e21cc46..7512f97e8f49 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -691,7 +691,6 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning); -void ath9k_hw_stoppcurecv(struct ath_hw *ah); void ath9k_hw_abortpcurecv(struct ath_hw *ah); bool ath9k_hw_stopdmarecv(struct ath_hw *ah); int ath9k_hw_beaconq_setup(struct ath_hw *ah); -- cgit v1.2.3-59-g8ed1b From 4b7384f936817489a4172b9c5d946f63f479ca15 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 15 Nov 2010 13:56:10 -0800 Subject: iwlwifi: remove unused define was not used, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index e87be1e551aa..583916db46e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -410,7 +410,6 @@ struct iwl_eeprom_calib_info { #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ -#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */ #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ -- cgit v1.2.3-59-g8ed1b From dbbf1755b09eef8ff6dd21c8dafe1606f051ce12 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 15 Nov 2010 13:43:07 -0800 Subject: iwlwifi: use antenna information in EEPROM The valid tx/rx antenna information is part of EEPROM, so use it to configure the device. For few cases, the EEPROM did not reflect the correct antenna, but it is too late to modify the EEPROM, so overwrite with .cfg parameters Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 8 ----- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 20 ++++--------- drivers/net/wireless/iwlwifi/iwl-6000.c | 42 ++++----------------------- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 20 +++++++++++++ 5 files changed, 32 insertions(+), 60 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 3100a72b9b44..9170120ce5d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -278,8 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, .ops = &iwl1000_ops, @@ -294,8 +292,6 @@ struct iwl_cfg iwl1000_bg_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, .ops = &iwl1000_ops, @@ -309,8 +305,6 @@ struct iwl_cfg iwl100_bgn_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, .ops = &iwl1000_ops, @@ -325,8 +319,6 @@ struct iwl_cfg iwl100_bg_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, .ops = &iwl1000_ops, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6788ceb37686..9f1d8d8c8fcc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2624,8 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = { .fw_name_pre = IWL4965_FW_PRE, .ucode_api_max = IWL4965_UCODE_API_MAX, .ucode_api_min = IWL4965_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, .ops = &iwl4965_ops, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 3ee0f7c035cf..cf74edb82a70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -527,8 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .ops = &iwl5000_ops, @@ -543,8 +541,8 @@ struct iwl_cfg iwl5100_bgn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .ops = &iwl5000_ops, @@ -559,8 +557,8 @@ struct iwl_cfg iwl5100_abg_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .ops = &iwl5000_ops, @@ -574,8 +572,8 @@ struct iwl_cfg iwl5100_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .ops = &iwl5000_ops, @@ -590,8 +588,6 @@ struct iwl_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .ops = &iwl5000_ops, @@ -606,8 +602,6 @@ struct iwl_cfg iwl5150_agn_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .ops = &iwl5150_ops, @@ -623,8 +617,6 @@ struct iwl_cfg iwl5150_abg_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .ops = &iwl5150_ops, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 93e3fe92f389..a3a055f7fd43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -557,8 +557,6 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -575,8 +573,6 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -592,8 +588,6 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -609,8 +603,6 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -631,8 +623,6 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -652,8 +642,6 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -674,8 +662,6 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -695,8 +681,6 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -717,8 +701,6 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -741,8 +723,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -758,8 +740,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -774,8 +756,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -790,8 +772,6 @@ struct iwl_cfg iwl6050_2agn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .ops = &iwl6050_ops, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, @@ -807,8 +787,6 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, .ops = &iwl6050g2_ops, @@ -824,8 +802,6 @@ struct iwl_cfg iwl6050_2abg_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, .ops = &iwl6050_ops, @@ -840,8 +816,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .ops = &iwl6000_ops, @@ -857,8 +831,6 @@ struct iwl_cfg iwl130_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, @@ -878,8 +850,6 @@ struct iwl_cfg iwl130_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 8a4d3acb9b79..dbada761624d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -251,6 +251,7 @@ err: int iwl_eeprom_check_sku(struct iwl_priv *priv) { u16 eeprom_sku; + u16 radio_cfg; eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); @@ -266,6 +267,25 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); + if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) { + /* not using .cfg overwrite */ + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) { + IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n", + priv->cfg->valid_tx_ant, + priv->cfg->valid_rx_ant); + return -EINVAL; + } + IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n", + priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant); + } + /* + * for some special cases, + * EEPROM did not reflect the correct antenna setting + * so overwrite the valid tx/rx antenna from .cfg + */ return 0; } -- cgit v1.2.3-59-g8ed1b From 67158b67cea0c92dba1dda74cde926d149cc1a2e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Nov 2010 11:51:04 -0800 Subject: iwlagn: remove powersave warning Through races, a packet may be enqueued for transmission to a station while that station is going to sleep, in which case the warning here triggers. Instead of warning, check the condition -- if this packet is not a PS-poll response then we still enqueue it but it will be rejected by the device since the station is marked as asleep. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 07bbc915529a..e8bd0b311946 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -567,8 +567,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta) sta_priv = (void *)sta->drv_priv; - if (sta_priv && sta_priv->asleep) { - WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); + if (sta_priv && sta_priv->asleep && + (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) { /* * This sends an asynchronous command to the device, * but we can rely on it being processed before the -- cgit v1.2.3-59-g8ed1b From 2e34034e8c9755ff144379d410d5227926e91cce Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Nov 2010 11:51:38 -0800 Subject: iwlagn: fix station powersave accounting for aggregation Since aggregation queues are station-specific, the device will not reject packets in them but rather will stop the appropriate aggregation queues when a station goes to sleep. I forgot to account for this in the driver, so if a station went to sleep that had aggregation enabled, traffic would stop indefinitely. Fix this by only accounting frames queued on the normal AC queues for associated station. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index e8bd0b311946..c114c3a704f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -531,6 +531,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) u8 tid = 0; u8 *qc = NULL; unsigned long flags; + bool is_agg = false; if (info->control.vif) ctx = iwl_rxon_ctx_from_vif(info->control.vif); @@ -616,6 +617,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_AMPDU && priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; + is_agg = true; } } @@ -763,8 +765,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * whether or not we should update the write pointer. */ - /* avoid atomic ops if it isn't an associated client */ - if (sta_priv && sta_priv->client) + /* + * Avoid atomic ops if it isn't an associated client. + * Also, if this is a packet for aggregation, don't + * increase the counter because the ucode will stop + * aggregation queues when their respective station + * goes to sleep. + */ + if (sta_priv && sta_priv->client && !is_agg) atomic_inc(&sta_priv->pending_frames); if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) { @@ -1143,14 +1151,15 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, return 0; } -static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info) +static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr1) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data; struct ieee80211_sta *sta; struct iwl_station_priv *sta_priv; rcu_read_lock(); - sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1); + sta = ieee80211_find_sta(ctx->vif, addr1); if (sta) { sta_priv = (void *)sta->drv_priv; /* avoid atomic ops if this isn't a client */ @@ -1159,6 +1168,15 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info) ieee80211_sta_block_awake(priv->hw, sta, false); } rcu_read_unlock(); +} + +static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info, + bool is_agg) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data; + + if (!is_agg) + iwlagn_non_agg_tx_status(priv, tx_info->ctx, hdr->addr1); ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); } @@ -1183,7 +1201,8 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - iwlagn_tx_status(priv, tx_info); + iwlagn_tx_status(priv, tx_info, + txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); hdr = (struct ieee80211_hdr *)tx_info->skb->data; if (hdr && ieee80211_is_data_qos(hdr->frame_control)) -- cgit v1.2.3-59-g8ed1b From 6fb5511ab96d9f31be747bab842f96227a5c7aec Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Nov 2010 11:55:02 -0800 Subject: iwlagn: advertise reliable TX status Our hardware has reliable TX status, but we're not currently advertising that to mac80211. Since the packet loss monitoring will depend on it, advertise it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5b96b0d80091..50cee2b5a6b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3175,7 +3175,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_NEED_DTIM_PERIOD | - IEEE80211_HW_SPECTRUM_MGMT; + IEEE80211_HW_SPECTRUM_MGMT | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | -- cgit v1.2.3-59-g8ed1b From 0c4ac342997c9597706a8fcbb0ccf920b3d33570 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 17 Nov 2010 11:33:27 -0800 Subject: iwlwifi: use mac80211 AC defines Instead of hardcoding the numbers that must match mac80211, use the constants. Not that this means we could change the constants, but at least this way it's clearer. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 10 ++++++++-- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 24 ++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c114c3a704f8..72b1f262796c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -67,8 +67,14 @@ */ static const u8 tid_to_ac[] = { - /* this matches the mac80211 numbers */ - 2, 3, 3, 2, 1, 1, 0, 0 + IEEE80211_AC_BE, + IEEE80211_AC_BK, + IEEE80211_AC_BK, + IEEE80211_AC_BE, + IEEE80211_AC_VI, + IEEE80211_AC_VI, + IEEE80211_AC_VO, + IEEE80211_AC_VO }; static inline int get_ac_from_tid(u16 tid) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 411a7a20450a..0bdd2bb0bbd3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -47,10 +47,10 @@ struct queue_to_fifo_ac { }; static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { - { IWL_TX_FIFO_VO, 0, }, - { IWL_TX_FIFO_VI, 1, }, - { IWL_TX_FIFO_BE, 2, }, - { IWL_TX_FIFO_BK, 3, }, + { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, + { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, + { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, + { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, @@ -60,14 +60,14 @@ static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { }; static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { - { IWL_TX_FIFO_VO, 0, }, - { IWL_TX_FIFO_VI, 1, }, - { IWL_TX_FIFO_BE, 2, }, - { IWL_TX_FIFO_BK, 3, }, - { IWL_TX_FIFO_BK_IPAN, 3, }, - { IWL_TX_FIFO_BE_IPAN, 2, }, - { IWL_TX_FIFO_VI_IPAN, 1, }, - { IWL_TX_FIFO_VO_IPAN, 0, }, + { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, + { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, + { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, + { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, + { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, }, + { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, }, + { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, }, + { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, { IWL_TX_FIFO_BE_IPAN, 2, }, { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, }; -- cgit v1.2.3-59-g8ed1b From f9dc6467223319acaea64d95ff208409e4e48d07 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 17 Nov 2010 12:13:52 -0800 Subject: iwlagn: Offical name for 6050g2 device Change to offical name for 6050g2 devices: "Intel(R) Centrino(R) Wireless-N 6150" Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a3a055f7fd43..43eb99b2b83c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -783,7 +783,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { }; struct iwl_cfg iwl6050g2_bgn_cfg = { - .name = "6050 Series 1x2 BGN Gen2", + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, -- cgit v1.2.3-59-g8ed1b From 55017ab87831b3ca449b81b83b180baac2895666 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 17 Nov 2010 12:13:53 -0800 Subject: iwlagn: Offical name for 6000g2a device Change to offical name for 6000g2a devices: "Intel(R) Centrino(R) Advanced-N 6205" Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 43eb99b2b83c..d087cb531093 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -553,7 +553,7 @@ static struct iwl_bt_params iwl6000_bt_params = { }; struct iwl_cfg iwl6000g2a_2agn_cfg = { - .name = "6000 Series 2x2 AGN Gen2a", + .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -569,7 +569,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { }; struct iwl_cfg iwl6000g2a_2abg_cfg = { - .name = "6000 Series 2x2 ABG Gen2a", + .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -584,7 +584,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { }; struct iwl_cfg iwl6000g2a_2bg_cfg = { - .name = "6000 Series 2x2 BG Gen2a", + .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, -- cgit v1.2.3-59-g8ed1b From d2eceef02e717751d4f6a01eddea6f241d63c213 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 17 Nov 2010 12:13:54 -0800 Subject: iwlagn: Offical name for 6000g2b device Change to offical name for 6000g2b devices: "Intel(R) Centrino(R) Wireless-N 1030" "Intel(R) Centrino(R) Advanced-N 6230" Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d087cb531093..3591dc88d961 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -599,7 +599,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { }; struct iwl_cfg iwl6000g2b_2agn_cfg = { - .name = "6000 Series 2x2 AGN Gen2b", + .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -619,7 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { }; struct iwl_cfg iwl6000g2b_2abg_cfg = { - .name = "6000 Series 2x2 ABG Gen2b", + .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -638,7 +638,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { - .name = "6000 Series 2x2 BGN Gen2b", + .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -658,7 +658,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { }; struct iwl_cfg iwl6000g2b_2bg_cfg = { - .name = "6000 Series 2x2 BG Gen2b", + .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -677,7 +677,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { }; struct iwl_cfg iwl6000g2b_bgn_cfg = { - .name = "6000 Series 1x2 BGN Gen2b", + .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -697,7 +697,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { }; struct iwl_cfg iwl6000g2b_bg_cfg = { - .name = "6000 Series 1x2 BG Gen2b", + .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, -- cgit v1.2.3-59-g8ed1b From 638514ff5d5845c6eba8c266ea04325be6e7d106 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 17 Nov 2010 12:13:55 -0800 Subject: iwlagn: Offical name for 100/130 device Change to offical name for 100 devices: "Intel(R) Centrino(R) Wireless-N 100" Change to offical name for 130 devices: "Intel(R) Centrino(R) Wireless-N 130" Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 9170120ce5d1..fb3e3713bae4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -301,7 +301,7 @@ struct iwl_cfg iwl1000_bg_cfg = { }; struct iwl_cfg iwl100_bgn_cfg = { - .name = "Intel(R) 100 Series 1x1 BGN", + .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, @@ -315,7 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = { }; struct iwl_cfg iwl100_bg_cfg = { - .name = "Intel(R) 100 Series 1x1 BG", + .name = "Intel(R) Centrino(R) Wireless-N 100 BG", .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 3591dc88d961..ec41f2725292 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -827,7 +827,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { }; struct iwl_cfg iwl130_bgn_cfg = { - .name = "Intel(R) 130 Series 1x1 BGN", + .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, @@ -846,7 +846,7 @@ struct iwl_cfg iwl130_bgn_cfg = { }; struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) 130 Series 1x2 BG", + .name = "Intel(R) Centrino(R) Wireless-N 130 BG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, -- cgit v1.2.3-59-g8ed1b From 506aa156fa736e9f9ce476239c9549ebbf6b08ea Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 24 Nov 2010 17:25:03 -0800 Subject: iwlagn: use different kill mask when SCO active use different kill_ack_mask and kill_cts_mask when detect SCO is active. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 32 +++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-commands.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f8fe5f44e19f..3342513ca6b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1814,6 +1814,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) bt_cmd.prio_boost = 0; bt_cmd.kill_ack_mask = priv->kill_ack_mask; bt_cmd.kill_cts_mask = priv->kill_cts_mask; + bt_cmd.valid = priv->bt_valid; bt_cmd.tx_prio_boost = 0; bt_cmd.rx_prio_boost = 0; @@ -1996,24 +1997,29 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, BT_UART_MSG_FRAME7CONNECTABLE_POS); } -static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv, - struct iwl_bt_uart_msg *uart_msg) +static void iwlagn_set_kill_msk(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) { - u8 kill_ack_msk; + u8 kill_msk; static const __le32 bt_kill_ack_msg[2] = { - cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; - - kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | - BT_UART_MSG_FRAME3SNIFF_MSK | - BT_UART_MSG_FRAME3SCOESCO_MSK) & - uart_msg->frame3) == 0) ? 1 : 0; - if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) { + IWLAGN_BT_KILL_ACK_MASK_DEFAULT, + IWLAGN_BT_KILL_ACK_CTS_MASK_SCO }; + static const __le32 bt_kill_cts_msg[2] = { + IWLAGN_BT_KILL_CTS_MASK_DEFAULT, + IWLAGN_BT_KILL_ACK_CTS_MASK_SCO }; + + kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) + ? 1 : 0; + if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] || + priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) { priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK; - priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk]; + priv->kill_ack_mask = bt_kill_ack_msg[kill_msk]; + priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK; + priv->kill_cts_mask = bt_kill_cts_msg[kill_msk]; + /* schedule to send runtime bt_config */ queue_work(priv->workqueue, &priv->bt_runtime_config); } - } void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, @@ -2064,7 +2070,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, } } - iwlagn_set_kill_ack_msk(priv, uart_msg); + iwlagn_set_kill_msk(priv, uart_msg); /* FIXME: based on notification, adjust the prio_boost */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c9448cba1e20..f893d4a6aa87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2453,6 +2453,7 @@ struct iwl_bt_cmd { #define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) #define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) +#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff) #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 -- cgit v1.2.3-59-g8ed1b From 9a67d761b39614c0495dcab9a204e21a9f4c4d31 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 18 Nov 2010 10:40:03 -0800 Subject: iwlagn: minor change in bt coex normal LUT Minor changes in LUT Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3342513ca6b2..407f0bb8422a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1778,7 +1778,7 @@ static const __le32 iwlagn_def_3w_lookup[12] = { cpu_to_le32(0xc0004000), cpu_to_le32(0x00004000), cpu_to_le32(0xf0005000), - cpu_to_le32(0xf0004000), + cpu_to_le32(0xf0005000), }; static const __le32 iwlagn_concurrent_lookup[12] = { -- cgit v1.2.3-59-g8ed1b From 573c67cf819d52d2e12adf75a9a8cfbd216190a3 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 26 Nov 2010 13:44:59 +0200 Subject: wl12xx: disable 11a channels when regulatory changes if 11a is not supported Instead of simply not scanning for the 11a channels when not supported by the hardware, disable the channels in reg_notify. This centralizes the decision on whether to scan 5GHz channel in one place and allows userspace to know exactly which channels are in use. Based on Juuso Oikarinen's idea. Cc: Juuso Oikarinen Signed-off-by: Luciano Coelho Reviewed-by: Juuso Oikarinen --- drivers/net/wireless/wl12xx/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 35cfcf675795..97eb186b5a8a 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -336,7 +336,9 @@ out: } static int wl1271_reg_notify(struct wiphy *wiphy, - struct regulatory_request *request) { + struct regulatory_request *request) +{ + struct wl1271 *wl = wiphy_to_ieee80211_hw(wiphy)->priv; struct ieee80211_supported_band *band; struct ieee80211_channel *ch; int i; @@ -347,6 +349,11 @@ static int wl1271_reg_notify(struct wiphy *wiphy, if (ch->flags & IEEE80211_CHAN_DISABLED) continue; + if (!wl->enable_11a) { + ch->flags |= IEEE80211_CHAN_DISABLED; + continue; + } + if (ch->flags & IEEE80211_CHAN_RADAR) ch->flags |= IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; -- cgit v1.2.3-59-g8ed1b From 2f6724b24525fc989c0707974b23d96b36132385 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 24 Nov 2010 08:16:57 +0200 Subject: wl1271: Fix setting of the hardware connection monitoring probe-req template The probe-request template used in the hardware connection monitoring feature thus far has been an empty one, without the SSID IE and without supported rate IEs. This causes problems with some AP's. Additionally, after connected scans, the template for connection maintenance would remain to be the one last used for scanning - potentially incorrect. Fix these by getting a pre-filled directed probe-request template for the associated-to AP from mac80211. Signed-off-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/cmd.h | 2 ++ drivers/net/wireless/wl12xx/main.c | 34 +++++++++++++++++++++------------- drivers/net/wireless/wl12xx/scan.c | 4 ++++ drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index f3d0541aaad6..8e438e27e496 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -611,6 +611,34 @@ out: return ret; } +struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, + struct sk_buff *skb) +{ + int ret; + + if (!skb) + skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); + if (!skb) + goto out; + + wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); + + if (wl->band == IEEE80211_BAND_2GHZ) + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, + skb->data, skb->len, 0, + wl->conf.tx.basic_rate); + else + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + skb->data, skb->len, 0, + wl->conf.tx.basic_rate_5); + + if (ret < 0) + wl1271_error("Unable to set ap probe request template."); + +out: + return skb; +} + int wl1271_build_qos_null_data(struct wl1271 *wl) { struct ieee80211_qos_hdr template; diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 16d1bf814e76..111d112544fc 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -49,6 +49,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); int wl1271_cmd_build_probe_req(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u8 band); +struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, + struct sk_buff *skb); int wl1271_build_qos_null_data(struct wl1271 *wl); int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 97eb186b5a8a..b2432dab4b51 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1814,21 +1814,21 @@ out: return ret; } -static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) +static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, + int offset) { - u8 *ptr = beacon->data + - offsetof(struct ieee80211_mgmt, u.beacon.variable); + u8 *ptr = skb->data + offset; /* find the location of the ssid in the beacon */ - while (ptr < beacon->data + beacon->len) { + while (ptr < skb->data + skb->len) { if (ptr[0] == WLAN_EID_SSID) { wl->ssid_len = ptr[1]; memcpy(wl->ssid, ptr+2, wl->ssid_len); return; } - ptr += ptr[1]; + ptr += (ptr[1] + 2); } - wl1271_error("ad-hoc beacon template has no SSID!\n"); + wl1271_error("No SSID in IEs!\n"); } static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, @@ -1871,8 +1871,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (beacon) { struct ieee80211_hdr *hdr; + int ieoffset = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + + wl1271_ssid_set(wl, beacon, ieoffset); - wl1271_ssid_set(wl, beacon); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, beacon->data, beacon->len, 0, @@ -1952,6 +1955,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { u32 rates; + int ieoffset; wl->aid = bss_conf->aid; set_assoc = true; @@ -1980,13 +1984,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, goto out_sleep; /* - * The SSID is intentionally set to NULL here - the - * firmware will set the probe request with a - * broadcast SSID regardless of what we set in the - * template. + * Get a template for hardware connection maintenance */ - ret = wl1271_cmd_build_probe_req(wl, NULL, 0, - NULL, 0, wl->band); + dev_kfree_skb(wl->probereq); + wl->probereq = wl1271_cmd_build_ap_probe_req(wl, NULL); + ieoffset = offsetof(struct ieee80211_mgmt, + u.probe_req.variable); + wl1271_ssid_set(wl, wl->probereq, ieoffset); /* enable the connection monitoring feature */ ret = wl1271_acx_conn_monit_params(wl, true); @@ -2009,6 +2013,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); wl->aid = 0; + /* free probe-request template */ + dev_kfree_skb(wl->probereq); + wl->probereq = NULL; + /* re-enable dynamic ps - just in case */ ieee80211_enable_dyn_ps(wl->vif); diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index f3f2c5b011ee..6f897b9d90ca 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -51,6 +51,10 @@ void wl1271_scan_complete_work(struct work_struct *work) wl->scan.req = NULL; ieee80211_scan_completed(wl->hw, false); + /* restore hardware connection monitoring template */ + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + wl1271_cmd_build_ap_probe_req(wl, wl->probereq); + if (wl->scan.failed) { wl1271_info("Scan completed due to error."); ieee80211_queue_work(wl->hw, &wl->recovery_work); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 3c836e6063e6..9f8aa695c3af 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -431,6 +431,9 @@ struct wl1271 { struct wl1271_scan scan; struct delayed_work scan_complete_work; + /* probe-req template for the current AP */ + struct sk_buff *probereq; + /* Our association ID */ u16 aid; -- cgit v1.2.3-59-g8ed1b From fe6d2a38b2076cba515dc95b5dc1589a7ab51c17 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 21 Nov 2010 23:25:50 +0000 Subject: be2net: adding support for Lancer family of CNAs Key changes are: - EQ ids are not assigned consecutively in Lancer. So, fix mapping of MSIx vector to EQ-id. - BAR mapping and some req locations different for Lancer. - TCP,UDP,IP checksum fields must be compulsorily set in TX wrb for TSO in Lancer. - CEV_IST reg not present in Lancer; so, peek into event queue to check for new entries - cq_create and mcc_create cmd interface is different for Lancer; handle accordingly Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 35 ++++++--- drivers/net/benet/be_cmds.c | 96 +++++++++++++++++------ drivers/net/benet/be_cmds.h | 42 ++++++++-- drivers/net/benet/be_hw.h | 39 +++++++++- drivers/net/benet/be_main.c | 181 ++++++++++++++++++++++++++++++++------------ 5 files changed, 301 insertions(+), 92 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4594a28b1f66..b61a1dfebcaf 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -38,14 +38,17 @@ #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" #define OC_NAME "Emulex OneConnect 10Gbps NIC" -#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)" +#define OC_NAME_BE OC_NAME "(be3)" +#define OC_NAME_LANCER OC_NAME "(Lancer)" #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" #define BE_VENDOR_ID 0x19a2 +#define EMULEX_VENDOR_ID 0x10df #define BE_DEVICE_ID1 0x211 #define BE_DEVICE_ID2 0x221 -#define OC_DEVICE_ID1 0x700 -#define OC_DEVICE_ID2 0x710 +#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */ +#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */ +#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ static inline char *nic_name(struct pci_dev *pdev) { @@ -53,7 +56,9 @@ static inline char *nic_name(struct pci_dev *pdev) case OC_DEVICE_ID1: return OC_NAME; case OC_DEVICE_ID2: - return OC_NAME1; + return OC_NAME_BE; + case OC_DEVICE_ID3: + return OC_NAME_LANCER; case BE_DEVICE_ID2: return BE3_NAME; default: @@ -149,6 +154,7 @@ struct be_eq_obj { u16 min_eqd; /* in usecs */ u16 max_eqd; /* in usecs */ u16 cur_eqd; /* in usecs */ + u8 msix_vec_idx; struct napi_struct napi; }; @@ -260,6 +266,8 @@ struct be_adapter { u32 num_rx_qs; u32 big_page_size; /* Compounded page size shared by rx wrbs */ + u8 msix_vec_next_idx; + struct vlan_group *vlan_grp; u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ @@ -299,8 +307,8 @@ struct be_adapter { bool sriov_enabled; struct be_vf_cfg vf_cfg[BE_MAX_VF]; - u8 base_eq_id; u8 is_virtfn; + u32 sli_family; }; #define be_physfn(adapter) (!adapter->is_virtfn) @@ -309,6 +317,8 @@ struct be_adapter { #define BE_GEN2 2 #define BE_GEN3 3 +#define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3) + extern const struct ethtool_ops be_ethtool_ops; #define tx_stats(adapter) (&adapter->tx_stats) @@ -416,10 +426,17 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) static inline void be_check_sriov_fn_type(struct be_adapter *adapter) { u8 data; - - pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); - pci_read_config_byte(adapter->pdev, 0xFE, &data); - adapter->is_virtfn = (data != 0xAA); + u32 sli_intf; + + if (lancer_chip(adapter)) { + pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, + &sli_intf); + adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; + } else { + pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); + pci_read_config_byte(adapter->pdev, 0xFE, &data); + adapter->is_virtfn = (data != 0xAA); + } } static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 36eca1ce75d4..3865b2bc65e6 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -323,7 +323,12 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) { - u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); + u32 sem; + + if (lancer_chip(adapter)) + sem = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET); + else + sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) @@ -465,14 +470,25 @@ int be_cmd_fw_init(struct be_adapter *adapter) spin_lock(&adapter->mbox_lock); wrb = (u8 *)wrb_from_mbox(adapter); - *wrb++ = 0xFF; - *wrb++ = 0x12; - *wrb++ = 0x34; - *wrb++ = 0xFF; - *wrb++ = 0xFF; - *wrb++ = 0x56; - *wrb++ = 0x78; - *wrb = 0xFF; + if (lancer_chip(adapter)) { + *wrb++ = 0xFF; + *wrb++ = 0x34; + *wrb++ = 0x12; + *wrb++ = 0xFF; + *wrb++ = 0xFF; + *wrb++ = 0x78; + *wrb++ = 0x56; + *wrb = 0xFF; + } else { + *wrb++ = 0xFF; + *wrb++ = 0x12; + *wrb++ = 0x34; + *wrb++ = 0xFF; + *wrb++ = 0xFF; + *wrb++ = 0x56; + *wrb++ = 0x78; + *wrb = 0xFF; + } status = be_mbox_notify_wait(adapter); @@ -680,16 +696,36 @@ int be_cmd_cq_create(struct be_adapter *adapter, OPCODE_COMMON_CQ_CREATE, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); + if (lancer_chip(adapter)) { + req->hdr.version = 1; + req->page_size = 1; /* 1 for 4K */ + AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt, + coalesce_wm); + AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt, + no_delay); + AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt, + __ilog2_u32(cq->len/256)); + AMAP_SET_BITS(struct amap_cq_context_lancer, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context_lancer, eventable, + ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context_lancer, eqid, + ctxt, eq->id); + AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1); + } else { + AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt, + coalesce_wm); + AMAP_SET_BITS(struct amap_cq_context_be, nodelay, + ctxt, no_delay); + AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt, + __ilog2_u32(cq->len/256)); + AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context_be, solevent, + ctxt, sol_evts); + AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id); + AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1); + } - AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm); - AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); - AMAP_SET_BITS(struct amap_cq_context, count, ctxt, - __ilog2_u32(cq->len/256)); - AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); - AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); - AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); @@ -737,13 +773,27 @@ int be_cmd_mccq_create(struct be_adapter *adapter, OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); + if (lancer_chip(adapter)) { + req->hdr.version = 1; + req->cq_id = cpu_to_le16(cq->id); + + AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt, + be_encoded_q_len(mccq->len)); + AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id, + ctxt, cq->id); + AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid, + ctxt, 1); + + } else { + AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt, + be_encoded_q_len(mccq->len)); + AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id); + } - AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, - be_encoded_q_len(mccq->len)); - AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ - req->async_event_bitmap[0] |= 0x00000022; + req->async_event_bitmap[0] = cpu_to_le32(0x00000022); be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 8469ff061f30..83d15c8a9fa3 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -309,7 +309,7 @@ struct be_cmd_req_pmac_del { /******************** Create CQ ***************************/ /* Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_cq_context { +struct amap_cq_context_be { u8 cidx[11]; /* dword 0*/ u8 rsvd0; /* dword 0*/ u8 coalescwm[2]; /* dword 0*/ @@ -332,14 +332,32 @@ struct amap_cq_context { u8 rsvd5[32]; /* dword 3*/ } __packed; +struct amap_cq_context_lancer { + u8 rsvd0[12]; /* dword 0*/ + u8 coalescwm[2]; /* dword 0*/ + u8 nodelay; /* dword 0*/ + u8 rsvd1[12]; /* dword 0*/ + u8 count[2]; /* dword 0*/ + u8 valid; /* dword 0*/ + u8 rsvd2; /* dword 0*/ + u8 eventable; /* dword 0*/ + u8 eqid[16]; /* dword 1*/ + u8 rsvd3[15]; /* dword 1*/ + u8 armed; /* dword 1*/ + u8 rsvd4[32]; /* dword 2*/ + u8 rsvd5[32]; /* dword 3*/ +} __packed; + struct be_cmd_req_cq_create { struct be_cmd_req_hdr hdr; u16 num_pages; - u16 rsvd0; - u8 context[sizeof(struct amap_cq_context) / 8]; + u8 page_size; + u8 rsvd0; + u8 context[sizeof(struct amap_cq_context_be) / 8]; struct phys_addr pages[8]; } __packed; + struct be_cmd_resp_cq_create { struct be_cmd_resp_hdr hdr; u16 cq_id; @@ -349,7 +367,7 @@ struct be_cmd_resp_cq_create { /******************** Create MCCQ ***************************/ /* Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_mcc_context { +struct amap_mcc_context_be { u8 con_index[14]; u8 rsvd0[2]; u8 ring_size[4]; @@ -364,12 +382,23 @@ struct amap_mcc_context { u8 rsvd2[32]; } __packed; +struct amap_mcc_context_lancer { + u8 async_cq_id[16]; + u8 ring_size[4]; + u8 rsvd0[12]; + u8 rsvd1[31]; + u8 valid; + u8 async_cq_valid[1]; + u8 rsvd2[31]; + u8 rsvd3[32]; +} __packed; + struct be_cmd_req_mcc_create { struct be_cmd_req_hdr hdr; u16 num_pages; - u16 rsvd0; + u16 cq_id; u32 async_event_bitmap[1]; - u8 context[sizeof(struct amap_mcc_context) / 8]; + u8 context[sizeof(struct amap_mcc_context_be) / 8]; struct phys_addr pages[8]; } __packed; @@ -605,6 +634,7 @@ struct be_hw_stats { struct be_rxf_stats rxf; u32 rsvd[48]; struct be_erx_stats erx; + u32 rsvd1[6]; }; struct be_cmd_req_get_stats { diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index a2ec5df0d733..4096d9778234 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -32,10 +32,12 @@ #define MPU_EP_CONTROL 0 /********** MPU semphore ******************/ -#define MPU_EP_SEMAPHORE_OFFSET 0xac -#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF -#define EP_SEMAPHORE_POST_ERR_MASK 0x1 -#define EP_SEMAPHORE_POST_ERR_SHIFT 31 +#define MPU_EP_SEMAPHORE_OFFSET 0xac +#define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400 +#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF +#define EP_SEMAPHORE_POST_ERR_MASK 0x1 +#define EP_SEMAPHORE_POST_ERR_SHIFT 31 + /* MPU semphore POST stage values */ #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ #define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ @@ -66,6 +68,28 @@ #define PCICFG_UE_STATUS_LOW_MASK 0xA8 #define PCICFG_UE_STATUS_HI_MASK 0xAC +/******** SLI_INTF ***********************/ +#define SLI_INTF_REG_OFFSET 0x58 +#define SLI_INTF_VALID_MASK 0xE0000000 +#define SLI_INTF_VALID 0xC0000000 +#define SLI_INTF_HINT2_MASK 0x1F000000 +#define SLI_INTF_HINT2_SHIFT 24 +#define SLI_INTF_HINT1_MASK 0x00FF0000 +#define SLI_INTF_HINT1_SHIFT 16 +#define SLI_INTF_FAMILY_MASK 0x00000F00 +#define SLI_INTF_FAMILY_SHIFT 8 +#define SLI_INTF_IF_TYPE_MASK 0x0000F000 +#define SLI_INTF_IF_TYPE_SHIFT 12 +#define SLI_INTF_REV_MASK 0x000000F0 +#define SLI_INTF_REV_SHIFT 4 +#define SLI_INTF_FT_MASK 0x00000001 + + +/* SLI family */ +#define BE_SLI_FAMILY 0x0 +#define LANCER_A0_SLI_FAMILY 0xA + + /********* ISR0 Register offset **********/ #define CEV_ISR0_OFFSET 0xC18 #define CEV_ISR_SIZE 4 @@ -73,6 +97,9 @@ /********* Event Q door bell *************/ #define DB_EQ_OFFSET DB_CQ_OFFSET #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ +#define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */ +#define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */ + /* Clear the interrupt for this eq */ #define DB_EQ_CLR_SHIFT (9) /* bit 9 */ /* Must be 1 */ @@ -85,6 +112,10 @@ /********* Compl Q door bell *************/ #define DB_CQ_OFFSET 0x120 #define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ +#define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */ +#define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14 + placing at 11-15 */ + /* Number of event entries processed */ #define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ /* Rearm bit */ diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 93354eee2cfd..102567ee68c2 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -41,6 +41,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, + { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); @@ -188,6 +189,8 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid, { u32 val = 0; val |= qid & DB_EQ_RING_ID_MASK; + val |= ((qid & DB_EQ_RING_ID_EXT_MASK) << + DB_EQ_RING_ID_EXT_MASK_SHIFT); if (adapter->eeh_err) return; @@ -205,6 +208,8 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped) { u32 val = 0; val |= qid & DB_CQ_RING_ID_MASK; + val |= ((qid & DB_CQ_RING_ID_EXT_MASK) << + DB_CQ_RING_ID_EXT_MASK_SHIFT); if (adapter->eeh_err) return; @@ -404,7 +409,8 @@ static void be_tx_stats_update(struct be_adapter *adapter, } /* Determine number of WRB entries needed to xmit data in an skb */ -static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) +static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb, + bool *dummy) { int cnt = (skb->len > skb->data_len); @@ -412,12 +418,13 @@ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) /* to account for hdr wrb */ cnt++; - if (cnt & 1) { + if (lancer_chip(adapter) || !(cnt & 1)) { + *dummy = false; + } else { /* add a dummy to make it an even num */ cnt++; *dummy = true; - } else - *dummy = false; + } BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); return cnt; } @@ -443,8 +450,18 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, hdr, skb_shinfo(skb)->gso_size); - if (skb_is_gso_v6(skb)) + if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); + if (lancer_chip(adapter) && adapter->sli_family == + LANCER_A0_SLI_FAMILY) { + AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1); + if (is_tcp_pkt(skb)) + AMAP_SET_BITS(struct amap_eth_hdr_wrb, + tcpcs, hdr, 1); + else if (is_udp_pkt(skb)) + AMAP_SET_BITS(struct amap_eth_hdr_wrb, + udpcs, hdr, 1); + } } else if (skb->ip_summed == CHECKSUM_PARTIAL) { if (is_tcp_pkt(skb)) AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); @@ -566,7 +583,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, u32 start = txq->head; bool dummy_wrb, stopped = false; - wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb); + wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); if (copied) { @@ -1035,7 +1052,8 @@ static void be_rx_compl_process(struct be_adapter *adapter, return; } vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - vid = swab16(vid); + if (!lancer_chip(adapter)) + vid = swab16(vid); vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); } else { netif_receive_skb(skb); @@ -1113,7 +1131,8 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, napi_gro_frags(&eq_obj->napi); } else { vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - vid = swab16(vid); + if (!lancer_chip(adapter)) + vid = swab16(vid); if (!adapter->vlan_grp || adapter->vlans_added == 0) return; @@ -1381,7 +1400,8 @@ static void be_tx_compl_clean(struct be_adapter *adapter) sent_skb = sent_skbs[txq->tail]; end_idx = txq->tail; index_adv(&end_idx, - wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); + wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, + txq->len); be_tx_compl_process(adapter, end_idx); } } @@ -1476,7 +1496,9 @@ static int be_tx_queues_create(struct be_adapter *adapter) /* Ask BE to create Tx Event queue */ if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) goto tx_eq_free; - adapter->base_eq_id = adapter->tx_eq.q.id; + + adapter->tx_eq.msix_vec_idx = adapter->msix_vec_next_idx++; + /* Alloc TX eth compl queue */ cq = &adapter->tx_obj.cq; @@ -1568,6 +1590,8 @@ static int be_rx_queues_create(struct be_adapter *adapter) if (rc) goto err; + rxo->rx_eq.msix_vec_idx = adapter->msix_vec_next_idx++; + /* CQ */ cq = &rxo->cq; rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, @@ -1578,7 +1602,6 @@ static int be_rx_queues_create(struct be_adapter *adapter) rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); if (rc) goto err; - /* Rx Q */ q = &rxo->q; rc = be_queue_alloc(adapter, q, RX_Q_LEN, @@ -1611,29 +1634,45 @@ err: return -1; } -/* There are 8 evt ids per func. Retruns the evt id's bit number */ -static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) +static bool event_peek(struct be_eq_obj *eq_obj) { - return eq_id - adapter->base_eq_id; + struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q); + if (!eqe->evt) + return false; + else + return true; } static irqreturn_t be_intx(int irq, void *dev) { struct be_adapter *adapter = dev; struct be_rx_obj *rxo; - int isr, i; + int isr, i, tx = 0 , rx = 0; - isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + - (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); - if (!isr) - return IRQ_NONE; + if (lancer_chip(adapter)) { + if (event_peek(&adapter->tx_eq)) + tx = event_handle(adapter, &adapter->tx_eq); + for_all_rx_queues(adapter, rxo, i) { + if (event_peek(&rxo->rx_eq)) + rx |= event_handle(adapter, &rxo->rx_eq); + } - if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr)) - event_handle(adapter, &adapter->tx_eq); + if (!(tx || rx)) + return IRQ_NONE; - for_all_rx_queues(adapter, rxo, i) { - if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr)) - event_handle(adapter, &rxo->rx_eq); + } else { + isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + + (adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE); + if (!isr) + return IRQ_NONE; + + if ((1 << adapter->tx_eq.msix_vec_idx & isr)) + event_handle(adapter, &adapter->tx_eq); + + for_all_rx_queues(adapter, rxo, i) { + if ((1 << rxo->rx_eq.msix_vec_idx & isr)) + event_handle(adapter, &rxo->rx_eq); + } } return IRQ_HANDLED; @@ -1830,8 +1869,7 @@ static void be_worker(struct work_struct *work) be_post_rx_frags(rxo); } } - - if (!adapter->ue_detected) + if (!adapter->ue_detected && !lancer_chip(adapter)) be_detect_dump_ue(adapter); reschedule: @@ -1910,10 +1948,10 @@ static void be_sriov_disable(struct be_adapter *adapter) #endif } -static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) +static inline int be_msix_vec_get(struct be_adapter *adapter, + struct be_eq_obj *eq_obj) { - return adapter->msix_entries[ - be_evt_bit_get(adapter, eq_id)].vector; + return adapter->msix_entries[eq_obj->msix_vec_idx].vector; } static int be_request_irq(struct be_adapter *adapter, @@ -1924,14 +1962,14 @@ static int be_request_irq(struct be_adapter *adapter, int vec; sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); - vec = be_msix_vec_get(adapter, eq_obj->q.id); + vec = be_msix_vec_get(adapter, eq_obj); return request_irq(vec, handler, 0, eq_obj->desc, context); } static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, void *context) { - int vec = be_msix_vec_get(adapter, eq_obj->q.id); + int vec = be_msix_vec_get(adapter, eq_obj); free_irq(vec, context); } @@ -2036,14 +2074,15 @@ static int be_close(struct net_device *netdev) netif_carrier_off(netdev); adapter->link_up = false; - be_intr_set(adapter, false); + if (!lancer_chip(adapter)) + be_intr_set(adapter, false); if (adapter->msix_enabled) { - vec = be_msix_vec_get(adapter, tx_eq->q.id); + vec = be_msix_vec_get(adapter, tx_eq); synchronize_irq(vec); for_all_rx_queues(adapter, rxo, i) { - vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id); + vec = be_msix_vec_get(adapter, &rxo->rx_eq); synchronize_irq(vec); } } else { @@ -2082,7 +2121,8 @@ static int be_open(struct net_device *netdev) be_irq_register(adapter); - be_intr_set(adapter, true); + if (!lancer_chip(adapter)) + be_intr_set(adapter, true); /* The evt queues are created in unarmed state; arm them */ for_all_rx_queues(adapter, rxo, i) { @@ -2548,6 +2588,9 @@ static void be_netdev_init(struct net_device *netdev) netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM; + if (lancer_chip(adapter)) + netdev->vlan_features |= NETIF_F_TSO6; + netdev->flags |= IFF_MULTICAST; adapter->rx_csum = true; @@ -2587,6 +2630,15 @@ static int be_map_pci_bars(struct be_adapter *adapter) u8 __iomem *addr; int pcicfg_reg, db_reg; + if (lancer_chip(adapter)) { + addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0), + pci_resource_len(adapter->pdev, 0)); + if (addr == NULL) + return -ENOMEM; + adapter->db = addr; + return 0; + } + if (be_physfn(adapter)) { addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), pci_resource_len(adapter->pdev, 2)); @@ -2783,6 +2835,44 @@ static int be_get_config(struct be_adapter *adapter) return 0; } +static int be_dev_family_check(struct be_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + u32 sli_intf = 0, if_type; + + switch (pdev->device) { + case BE_DEVICE_ID1: + case OC_DEVICE_ID1: + adapter->generation = BE_GEN2; + break; + case BE_DEVICE_ID2: + case OC_DEVICE_ID2: + adapter->generation = BE_GEN3; + break; + case OC_DEVICE_ID3: + pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); + if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> + SLI_INTF_IF_TYPE_SHIFT; + + if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || + if_type != 0x02) { + dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); + return -EINVAL; + } + if (num_vfs > 0) { + dev_err(&pdev->dev, "VFs not supported\n"); + return -EINVAL; + } + adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> + SLI_INTF_FAMILY_SHIFT); + adapter->generation = BE_GEN3; + break; + default: + adapter->generation = 0; + } + return 0; +} + static int __devinit be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { @@ -2805,22 +2895,13 @@ static int __devinit be_probe(struct pci_dev *pdev, goto rel_reg; } adapter = netdev_priv(netdev); - - switch (pdev->device) { - case BE_DEVICE_ID1: - case OC_DEVICE_ID1: - adapter->generation = BE_GEN2; - break; - case BE_DEVICE_ID2: - case OC_DEVICE_ID2: - adapter->generation = BE_GEN3; - break; - default: - adapter->generation = 0; - } - adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); + + status = be_dev_family_check(adapter); + if (!status) + goto free_netdev; + adapter->netdev = netdev; SET_NETDEV_DEV(netdev, &pdev->dev); @@ -2895,7 +2976,7 @@ ctrl_clean: be_ctrl_cleanup(adapter); free_netdev: be_sriov_disable(adapter); - free_netdev(adapter->netdev); + free_netdev(netdev); pci_set_drvdata(pdev, NULL); rel_reg: pci_release_regions(pdev); -- cgit v1.2.3-59-g8ed1b From 89bf67f1f080c947c92f8773482d9e57767ca292 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 22 Nov 2010 00:15:06 +0000 Subject: drivers/net: use vzalloc() Use vzalloc() and vzalloc_node() in net drivers Signed-off-by: Eric Dumazet Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 9 ++------- drivers/net/cxgb3/cxgb3_offload.c | 6 ++---- drivers/net/cxgb4/cxgb4_main.c | 6 ++---- drivers/net/e1000/e1000_main.c | 6 ++---- drivers/net/e1000e/netdev.c | 6 ++---- drivers/net/ehea/ehea_main.c | 4 +--- drivers/net/igb/igb_main.c | 6 ++---- drivers/net/igbvf/netdev.c | 6 ++---- drivers/net/ixgb/ixgb_main.c | 6 ++---- drivers/net/ixgbe/ixgbe_main.c | 10 ++++------ drivers/net/ixgbevf/ixgbevf_main.c | 6 ++---- drivers/net/netxen/netxen_nic_init.c | 6 ++---- drivers/net/pch_gbe/pch_gbe_main.c | 6 ++---- drivers/net/pptp.c | 3 +-- drivers/net/qlcnic/qlcnic_init.c | 6 ++---- drivers/net/sfc/filter.c | 3 +-- drivers/net/vxge/vxge-config.c | 31 ++++++++----------------------- 17 files changed, 39 insertions(+), 87 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 062600be073b..0de196da4d4a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -766,13 +766,10 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) int j; rxr->rx_buf_ring = - vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); + vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); if (rxr->rx_buf_ring == NULL) return -ENOMEM; - memset(rxr->rx_buf_ring, 0, - SW_RXBD_RING_SIZE * bp->rx_max_ring); - for (j = 0; j < bp->rx_max_ring; j++) { rxr->rx_desc_ring[j] = dma_alloc_coherent(&bp->pdev->dev, @@ -785,13 +782,11 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) } if (bp->rx_pg_ring_size) { - rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE * + rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE * bp->rx_max_pg_ring); if (rxr->rx_pg_ring == NULL) return -ENOMEM; - memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE * - bp->rx_max_pg_ring); } for (j = 0; j < bp->rx_max_pg_ring; j++) { diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index bcf07532953d..ef02aa68c926 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -1164,12 +1164,10 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) */ void *cxgb_alloc_mem(unsigned long size) { - void *p = kmalloc(size, GFP_KERNEL); + void *p = kzalloc(size, GFP_KERNEL); if (!p) - p = vmalloc(size); - if (p) - memset(p, 0, size); + p = vzalloc(size); return p; } diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index f50bc98310f8..848f89d19fb7 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -868,12 +868,10 @@ out: release_firmware(fw); */ void *t4_alloc_mem(size_t size) { - void *p = kmalloc(size, GFP_KERNEL); + void *p = kzalloc(size, GFP_KERNEL); if (!p) - p = vmalloc(size); - if (p) - memset(p, 0, size); + p = vzalloc(size); return p; } diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4686c3983fc3..dcb7f82c2701 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1425,13 +1425,12 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, int size; size = sizeof(struct e1000_buffer) * txdr->count; - txdr->buffer_info = vmalloc(size); + txdr->buffer_info = vzalloc(size); if (!txdr->buffer_info) { e_err(probe, "Unable to allocate memory for the Tx descriptor " "ring\n"); return -ENOMEM; } - memset(txdr->buffer_info, 0, size); /* round up to nearest 4K */ @@ -1621,13 +1620,12 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, int size, desc_len; size = sizeof(struct e1000_buffer) * rxdr->count; - rxdr->buffer_info = vmalloc(size); + rxdr->buffer_info = vzalloc(size); if (!rxdr->buffer_info) { e_err(probe, "Unable to allocate memory for the Rx descriptor " "ring\n"); return -ENOMEM; } - memset(rxdr->buffer_info, 0, size); desc_len = sizeof(struct e1000_rx_desc); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9b3f0a996b00..0adcb79e6386 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2059,10 +2059,9 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter) int err = -ENOMEM, size; size = sizeof(struct e1000_buffer) * tx_ring->count; - tx_ring->buffer_info = vmalloc(size); + tx_ring->buffer_info = vzalloc(size); if (!tx_ring->buffer_info) goto err; - memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); @@ -2095,10 +2094,9 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter) int i, size, desc_len, err = -ENOMEM; size = sizeof(struct e1000_buffer) * rx_ring->count; - rx_ring->buffer_info = vmalloc(size); + rx_ring->buffer_info = vzalloc(size); if (!rx_ring->buffer_info) goto err; - memset(rx_ring->buffer_info, 0, size); for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 182b2a7be8dc..a84c389d3db7 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1496,12 +1496,10 @@ static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) { int arr_size = sizeof(void *) * max_q_entries; - q_skba->arr = vmalloc(arr_size); + q_skba->arr = vzalloc(arr_size); if (!q_skba->arr) return -ENOMEM; - memset(q_skba->arr, 0, arr_size); - q_skba->len = max_q_entries; q_skba->index = 0; q_skba->os_skbs = 0; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 892d196f17ac..67ea262e482a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2436,10 +2436,9 @@ int igb_setup_tx_resources(struct igb_ring *tx_ring) int size; size = sizeof(struct igb_buffer) * tx_ring->count; - tx_ring->buffer_info = vmalloc(size); + tx_ring->buffer_info = vzalloc(size); if (!tx_ring->buffer_info) goto err; - memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); @@ -2587,10 +2586,9 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring) int size, desc_len; size = sizeof(struct igb_buffer) * rx_ring->count; - rx_ring->buffer_info = vmalloc(size); + rx_ring->buffer_info = vzalloc(size); if (!rx_ring->buffer_info) goto err; - memset(rx_ring->buffer_info, 0, size); desc_len = sizeof(union e1000_adv_rx_desc); diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 4c998b7726da..8dbde2397c10 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -430,10 +430,9 @@ int igbvf_setup_tx_resources(struct igbvf_adapter *adapter, int size; size = sizeof(struct igbvf_buffer) * tx_ring->count; - tx_ring->buffer_info = vmalloc(size); + tx_ring->buffer_info = vzalloc(size); if (!tx_ring->buffer_info) goto err; - memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); @@ -470,10 +469,9 @@ int igbvf_setup_rx_resources(struct igbvf_adapter *adapter, int size, desc_len; size = sizeof(struct igbvf_buffer) * rx_ring->count; - rx_ring->buffer_info = vmalloc(size); + rx_ring->buffer_info = vzalloc(size); if (!rx_ring->buffer_info) goto err; - memset(rx_ring->buffer_info, 0, size); desc_len = sizeof(union e1000_adv_rx_desc); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index caa8192fff2a..211a1694667e 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -669,13 +669,12 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) int size; size = sizeof(struct ixgb_buffer) * txdr->count; - txdr->buffer_info = vmalloc(size); + txdr->buffer_info = vzalloc(size); if (!txdr->buffer_info) { netif_err(adapter, probe, adapter->netdev, "Unable to allocate transmit descriptor ring memory\n"); return -ENOMEM; } - memset(txdr->buffer_info, 0, size); /* round up to nearest 4K */ @@ -759,13 +758,12 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) int size; size = sizeof(struct ixgb_buffer) * rxdr->count; - rxdr->buffer_info = vmalloc(size); + rxdr->buffer_info = vzalloc(size); if (!rxdr->buffer_info) { netif_err(adapter, probe, adapter->netdev, "Unable to allocate receive descriptor ring\n"); return -ENOMEM; } - memset(rxdr->buffer_info, 0, size); /* Round up to nearest 4K */ diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 025419567440..494cb57b700d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5181,12 +5181,11 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) int size; size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; - tx_ring->tx_buffer_info = vmalloc_node(size, tx_ring->numa_node); + tx_ring->tx_buffer_info = vzalloc_node(size, tx_ring->numa_node); if (!tx_ring->tx_buffer_info) - tx_ring->tx_buffer_info = vmalloc(size); + tx_ring->tx_buffer_info = vzalloc(size); if (!tx_ring->tx_buffer_info) goto err; - memset(tx_ring->tx_buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); @@ -5246,12 +5245,11 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring) int size; size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; - rx_ring->rx_buffer_info = vmalloc_node(size, rx_ring->numa_node); + rx_ring->rx_buffer_info = vzalloc_node(size, rx_ring->numa_node); if (!rx_ring->rx_buffer_info) - rx_ring->rx_buffer_info = vmalloc(size); + rx_ring->rx_buffer_info = vzalloc(size); if (!rx_ring->rx_buffer_info) goto err; - memset(rx_ring->rx_buffer_info, 0, size); /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 5b8063cb4e6c..2216a3c8b12b 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -2489,10 +2489,9 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter, int size; size = sizeof(struct ixgbevf_tx_buffer) * tx_ring->count; - tx_ring->tx_buffer_info = vmalloc(size); + tx_ring->tx_buffer_info = vzalloc(size); if (!tx_ring->tx_buffer_info) goto err; - memset(tx_ring->tx_buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); @@ -2556,14 +2555,13 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter, int size; size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; - rx_ring->rx_buffer_info = vmalloc(size); + rx_ring->rx_buffer_info = vzalloc(size); if (!rx_ring->rx_buffer_info) { hw_dbg(&adapter->hw, "Unable to vmalloc buffer memory for " "the receive descriptor ring\n"); goto alloc_failed; } - memset(rx_ring->rx_buffer_info, 0, size); /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 95fe552aa279..f946de23fe76 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -214,13 +214,12 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) tx_ring->num_desc = adapter->num_txd; tx_ring->txq = netdev_get_tx_queue(netdev, 0); - cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); + cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); goto err_out; } - memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; @@ -280,7 +279,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) } rds_ring->rx_buf_arr = (struct netxen_rx_buffer *) - vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); + vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { printk(KERN_ERR "%s: Failed to allocate " "rx buffer ring %d\n", @@ -288,7 +287,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) /* free whatever was already allocated */ goto err_out; } - memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 472056b47440..afb75066b14d 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -1523,12 +1523,11 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, int desNo; size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; - tx_ring->buffer_info = vmalloc(size); + tx_ring->buffer_info = vzalloc(size); if (!tx_ring->buffer_info) { pr_err("Unable to allocate memory for the buffer infomation\n"); return -ENOMEM; } - memset(tx_ring->buffer_info, 0, size); tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); @@ -1573,12 +1572,11 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, int desNo; size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; - rx_ring->buffer_info = vmalloc(size); + rx_ring->buffer_info = vzalloc(size); if (!rx_ring->buffer_info) { pr_err("Unable to allocate memory for the receive descriptor ring\n"); return -ENOMEM; } - memset(rx_ring->buffer_info, 0, size); rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index ccbc91326bfa..7556a9224f72 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -673,8 +673,7 @@ static int __init pptp_init_module(void) int err = 0; pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); - callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *), - GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); + callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *)); if (!callid_sock) { pr_err("PPTP: cann't allocate memory\n"); return -ENOMEM; diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 0d180c6e41fe..3f970187cfce 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -236,12 +236,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) tx_ring->num_desc = adapter->num_txd; tx_ring->txq = netdev_get_tx_queue(netdev, 0); - cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); + cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n"); goto err_out; } - memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; @@ -276,13 +275,12 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) break; } rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *) - vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); + vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { dev_err(&netdev->dev, "Failed to allocate " "rx buffer ring %d\n", ring); goto err_out; } - memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 52cb6082b910..44500b54fd5f 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -428,10 +428,9 @@ int efx_probe_filters(struct efx_nic *efx) GFP_KERNEL); if (!table->used_bitmap) goto fail; - table->spec = vmalloc(table->size * sizeof(*table->spec)); + table->spec = vzalloc(table->size * sizeof(*table->spec)); if (!table->spec) goto fail; - memset(table->spec, 0, table->size * sizeof(*table->spec)); } return 0; diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 409c2e6053d0..44d3ddd37b3e 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -1220,13 +1220,12 @@ vxge_hw_device_initialize( goto exit; hldev = (struct __vxge_hw_device *) - vmalloc(sizeof(struct __vxge_hw_device)); + vzalloc(sizeof(struct __vxge_hw_device)); if (hldev == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } - memset(hldev, 0, sizeof(struct __vxge_hw_device)); hldev->magic = VXGE_HW_DEVICE_MAGIC; vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL); @@ -2064,15 +2063,12 @@ __vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, * allocate new memblock and its private part at once. * This helps to minimize memory usage a lot. */ mempool->memblocks_priv_arr[i] = - vmalloc(mempool->items_priv_size * n_items); + vzalloc(mempool->items_priv_size * n_items); if (mempool->memblocks_priv_arr[i] == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } - memset(mempool->memblocks_priv_arr[i], 0, - mempool->items_priv_size * n_items); - /* allocate DMA-capable memblock */ mempool->memblocks_arr[i] = __vxge_hw_blockpool_malloc(mempool->devh, @@ -2145,12 +2141,11 @@ __vxge_hw_mempool_create( } mempool = (struct vxge_hw_mempool *) - vmalloc(sizeof(struct vxge_hw_mempool)); + vzalloc(sizeof(struct vxge_hw_mempool)); if (mempool == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } - memset(mempool, 0, sizeof(struct vxge_hw_mempool)); mempool->devh = devh; mempool->memblock_size = memblock_size; @@ -2170,31 +2165,27 @@ __vxge_hw_mempool_create( /* allocate array of memblocks */ mempool->memblocks_arr = - (void **) vmalloc(sizeof(void *) * mempool->memblocks_max); + (void **) vzalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } - memset(mempool->memblocks_arr, 0, - sizeof(void *) * mempool->memblocks_max); /* allocate array of private parts of items per memblocks */ mempool->memblocks_priv_arr = - (void **) vmalloc(sizeof(void *) * mempool->memblocks_max); + (void **) vzalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_priv_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } - memset(mempool->memblocks_priv_arr, 0, - sizeof(void *) * mempool->memblocks_max); /* allocate array of memblocks DMA objects */ mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *) - vmalloc(sizeof(struct vxge_hw_mempool_dma) * + vzalloc(sizeof(struct vxge_hw_mempool_dma) * mempool->memblocks_max); if (mempool->memblocks_dma_arr == NULL) { @@ -2203,20 +2194,16 @@ __vxge_hw_mempool_create( mempool = NULL; goto exit; } - memset(mempool->memblocks_dma_arr, 0, - sizeof(struct vxge_hw_mempool_dma) * - mempool->memblocks_max); /* allocate hash array of items */ mempool->items_arr = - (void **) vmalloc(sizeof(void *) * mempool->items_max); + (void **) vzalloc(sizeof(void *) * mempool->items_max); if (mempool->items_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } - memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max); /* calculate initial number of memblocks */ memblocks_to_allocate = (mempool->items_initial + @@ -4272,14 +4259,12 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev, goto vpath_open_exit1; vp = (struct __vxge_hw_vpath_handle *) - vmalloc(sizeof(struct __vxge_hw_vpath_handle)); + vzalloc(sizeof(struct __vxge_hw_vpath_handle)); if (vp == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto vpath_open_exit2; } - memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle)); - vp->vpath = vpath; if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { -- cgit v1.2.3-59-g8ed1b From cf7afbfeb8ceb0187348d0a1a0db61305e25f05f Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Mon, 22 Nov 2010 01:31:54 +0000 Subject: rtnl: make link af-specific updates atomic As David pointed out correctly, updates to af-specific attributes are currently not atomic. If multiple changes are requested and one of them fails, previous updates may have been applied already leaving the link behind in a undefined state. This patch splits the function parse_link_af() into two functions validate_link_af() and set_link_at(). validate_link_af() is placed to validate_linkmsg() check for errors as early as possible before any changes to the link have been made. set_link_af() is called to commit the changes later. This method is not fail proof, while it is currently sufficient to make set_link_af() inerrable and thus 100% atomic, the validation function method will not be able to detect all error scenarios in the future, there will likely always be errors depending on states which are f.e. not protected by rtnl_mutex and thus may change between validation and setting. Also, instead of silently ignoring unknown address families and config blocks for address families which did not register a set function the errors EAFNOSUPPORT respectively EOPNOSUPPORT are returned to avoid comitting 4 out of 5 update requests without notifying the user. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/net/rtnetlink.h | 12 ++++++++---- net/core/rtnetlink.c | 29 ++++++++++++++++++++++++----- net/ipv4/devinet.c | 26 +++++++++++++++++++++----- net/ipv6/addrconf.c | 6 ------ 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 35be0bbcd7da..4093ca78cf60 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -92,8 +92,10 @@ extern void rtnl_link_unregister(struct rtnl_link_ops *ops); * specific netlink attributes. * @get_link_af_size: Function to calculate size of address family specific * netlink attributes exlusive the container attribute. - * @parse_link_af: Function to parse a IFLA_AF_SPEC attribute and modify - * net_device accordingly. + * @validate_link_af: Validate a IFLA_AF_SPEC attribute, must check attr + * for invalid configuration settings. + * @set_link_af: Function to parse a IFLA_AF_SPEC attribute and modify + * net_device accordingly. */ struct rtnl_af_ops { struct list_head list; @@ -103,8 +105,10 @@ struct rtnl_af_ops { const struct net_device *dev); size_t (*get_link_af_size)(const struct net_device *dev); - int (*parse_link_af)(struct net_device *dev, - const struct nlattr *attr); + int (*validate_link_af)(const struct net_device *dev, + const struct nlattr *attr); + int (*set_link_af)(struct net_device *dev, + const struct nlattr *attr); }; extern int __rtnl_af_register(struct rtnl_af_ops *ops); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index bf69e5871b1a..750db57f3bb3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1107,6 +1107,28 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) return -EINVAL; } + if (tb[IFLA_AF_SPEC]) { + struct nlattr *af; + int rem, err; + + nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { + const struct rtnl_af_ops *af_ops; + + if (!(af_ops = rtnl_af_lookup(nla_type(af)))) + return -EAFNOSUPPORT; + + if (!af_ops->set_link_af) + return -EOPNOTSUPP; + + if (af_ops->validate_link_af) { + err = af_ops->validate_link_af(dev, + tb[IFLA_AF_SPEC]); + if (err < 0) + return err; + } + } + } + return 0; } @@ -1356,12 +1378,9 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, const struct rtnl_af_ops *af_ops; if (!(af_ops = rtnl_af_lookup(nla_type(af)))) - continue; - - if (!af_ops->parse_link_af) - continue; + BUG(); - err = af_ops->parse_link_af(dev, af); + err = af_ops->set_link_af(dev, af); if (err < 0) goto errout; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 71afc26c2df8..d9f71bae45c4 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1289,14 +1289,14 @@ static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = { [IFLA_INET_CONF] = { .type = NLA_NESTED }, }; -static int inet_parse_link_af(struct net_device *dev, const struct nlattr *nla) +static int inet_validate_link_af(const struct net_device *dev, + const struct nlattr *nla) { - struct in_device *in_dev = __in_dev_get_rcu(dev); struct nlattr *a, *tb[IFLA_INET_MAX+1]; int err, rem; - if (!in_dev) - return -EOPNOTSUPP; + if (dev && !__in_dev_get_rcu(dev)) + return -EAFNOSUPPORT; err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy); if (err < 0) @@ -1314,6 +1314,21 @@ static int inet_parse_link_af(struct net_device *dev, const struct nlattr *nla) } } + return 0; +} + +static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) +{ + struct in_device *in_dev = __in_dev_get_rcu(dev); + struct nlattr *a, *tb[IFLA_INET_MAX+1]; + int rem; + + if (!in_dev) + return -EAFNOSUPPORT; + + if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL) < 0) + BUG(); + if (tb[IFLA_INET_CONF]) { nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a)); @@ -1689,7 +1704,8 @@ static struct rtnl_af_ops inet_af_ops = { .family = AF_INET, .fill_link_af = inet_fill_link_af, .get_link_af_size = inet_get_link_af_size, - .parse_link_af = inet_parse_link_af, + .validate_link_af = inet_validate_link_af, + .set_link_af = inet_set_link_af, }; void __init devinet_init(void) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 4cf760598c2a..1023ad0d2b15 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3956,11 +3956,6 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev) return 0; } -static int inet6_parse_link_af(struct net_device *dev, const struct nlattr *nla) -{ - return -EOPNOTSUPP; -} - static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, u32 pid, u32 seq, int event, unsigned int flags) { @@ -4670,7 +4665,6 @@ static struct rtnl_af_ops inet6_ops = { .family = AF_INET6, .fill_link_af = inet6_fill_link_af, .get_link_af_size = inet6_get_link_af_size, - .parse_link_af = inet6_parse_link_af, }; /* -- cgit v1.2.3-59-g8ed1b From 5584b8078a60e34ec7d37c9b67a0f3d389a1a2f6 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Mon, 22 Nov 2010 23:00:42 +0000 Subject: sctp: kill unused macro definition These macros have been existed for several years since v2.6.12-rc2. But they never be used. So remove them now. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- include/net/sctp/constants.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 63908840eef0..c70d8ccc55cb 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -61,7 +61,6 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM }; * symbols. CIDs are dense through SCTP_CID_BASE_MAX. */ #define SCTP_CID_BASE_MAX SCTP_CID_SHUTDOWN_COMPLETE -#define SCTP_CID_MAX SCTP_CID_ASCONF_ACK #define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1) @@ -86,9 +85,6 @@ typedef enum { } sctp_event_t; -#define SCTP_EVENT_T_MAX SCTP_EVENT_T_PRIMITIVE -#define SCTP_EVENT_T_NUM (SCTP_EVENT_T_MAX + 1) - /* As a convenience for the state machine, we append SCTP_EVENT_* and * SCTP_ULP_* to the list of possible chunks. */ @@ -162,9 +158,6 @@ SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive) - (unsigned long)(c->chunk_hdr)\ - sizeof(sctp_data_chunk_t))) -#define SCTP_MAX_ERROR_CAUSE SCTP_ERROR_NONEXIST_IP -#define SCTP_NUM_ERROR_CAUSE 10 - /* Internal error codes */ typedef enum { @@ -266,7 +259,6 @@ enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 }; #define SCTP_TSN_MAP_INITIAL BITS_PER_LONG #define SCTP_TSN_MAP_INCREMENT SCTP_TSN_MAP_INITIAL #define SCTP_TSN_MAP_SIZE 4096 -#define SCTP_TSN_MAX_GAP 65535 /* We will not record more than this many duplicate TSNs between two * SACKs. The minimum PMTU is 576. Remove all the headers and there @@ -301,9 +293,6 @@ enum { SCTP_MAX_GABS = 16 }; #define SCTP_CLOCK_GRANULARITY 1 /* 1 jiffy */ -#define SCTP_DEF_MAX_INIT 6 -#define SCTP_DEF_MAX_SEND 10 - #define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */ #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ @@ -317,9 +306,6 @@ enum { SCTP_MAX_GABS = 16 }; */ #define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ #define SCTP_HOW_MANY_SECRETS 2 /* How many secrets I keep */ -#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* How many seconds the current - * secret will live? - */ #define SCTP_SECRET_SIZE 32 /* Number of octets in a 256 bits. */ #define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */ -- cgit v1.2.3-59-g8ed1b From b0044bcfa95ddf2e317863fb29121c284b6725ca Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 23 Nov 2010 01:25:21 +0000 Subject: qlcnic: avoid using reset_devices as it may become obsolete. In kdump environment do not depend upon reset_devices parameter to reset the pci function as this parameter may become obsolete. Instead use an adapter specific mechanism to determine if the pci function needs to be reset. Per function refcount is maintained in driver, which is set in probe and reset in remove handler of adapter. If the probe detects the count as non zero then reset the function. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_ctx.c | 4 +++- drivers/net/qlcnic/qlcnic_hdr.h | 2 +- drivers/net/qlcnic/qlcnic_main.c | 5 +++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 56f54ffabb2f..9513a83b9537 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -923,6 +923,7 @@ struct qlcnic_ipaddr { #define QLCNIC_MACSPOOF 0x200 #define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 #define QLCNIC_PROMISC_DISABLED 0x800 +#define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 3ad1f3eba289..29cbc2a6e79f 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -480,8 +480,10 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter) { int err; - if (reset_devices) + if (adapter->flags & QLCNIC_NEED_FLR) { pci_reset_function(adapter->pdev); + adapter->flags &= ~QLCNIC_NEED_FLR; + } err = qlcnic_fw_cmd_create_rx_ctx(adapter); if (err) diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 4290b80cde1a..566e0e8437e4 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -722,7 +722,7 @@ enum { #define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */ #define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */ -#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) +#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) & (1 << (FN * 4))) #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) #define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4))) #define QLC_DEV_SET_RST_RDY(VAL, FN) ((VAL) |= (1 << (FN * 4))) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a3dcd04be22f..899df5a81fda 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1485,6 +1485,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) uint8_t revision_id; uint8_t pci_using_dac; char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; + u32 val; err = pci_enable_device(pdev); if (err) @@ -1546,6 +1547,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_out_iounmap; + val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); + if (QLC_DEV_CHECK_ACTIVE(val, adapter->portnum)) + adapter->flags |= QLCNIC_NEED_FLR; + err = adapter->nic_ops->start_firmware(adapter); if (err) { dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); -- cgit v1.2.3-59-g8ed1b From 5a6f95e653adf52ee1ff09cd5e66c2640c65ff66 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 23 Nov 2010 03:08:27 +0000 Subject: netxen: avoid using reset_devices as it may become obsolete In kdump environment do not depend on reset_devices parameter to reset the device as the parameter may become obsolete. Instead use an adapter specific mechanism to determine if the device needs a reset. Driver maintains a count of number of pci functions probed and decrements the count when remove handler of that pci function is called. If the first probe, probe of function 0, detects the count as non zero then reset the device. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index e1d30d7f2071..ceeaac989df2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1277,6 +1277,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int i = 0, err; int pci_func_id = PCI_FUNC(pdev->devfn); uint8_t revision_id; + u32 val; if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { pr_warning("%s: chip revisions between 0x%x-0x%x " @@ -1352,8 +1353,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - if (reset_devices) { - if (adapter->portnum == 0) { + if (adapter->portnum == 0) { + val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); + if (val != 0xffffffff && val != 0) { NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0); adapter->need_fw_reset = 1; } -- cgit v1.2.3-59-g8ed1b From a40c9f88b5e3da500ddab9440e5ddac170c12281 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 23 Nov 2010 22:57:47 +0000 Subject: net: add some KERN_CONT markers to continuation lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: netdev@vger.kernel.org Signed-off-by: Uwe Kleine-König Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 4 ++-- net/ipv4/ipconfig.c | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7670aac0e93f..a8445c72fc13 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -47,11 +47,11 @@ void phy_print_status(struct phy_device *phydev) pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev), phydev->link ? "Up" : "Down"); if (phydev->link) - printk(" - %d/%s", phydev->speed, + printk(KERN_CONT " - %d/%s", phydev->speed, DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); - printk("\n"); + printk(KERN_CONT "\n"); } EXPORT_SYMBOL(phy_print_status); diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 3a6e1ec5e9ae..2b097752426b 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1191,13 +1191,13 @@ static int __init ic_dynamic(void) (ic_proto_enabled & IC_USE_DHCP) && ic_dhcp_msgtype != DHCPACK) { ic_got_reply = 0; - printk(","); + printk(KERN_CONT ","); continue; } #endif /* IPCONFIG_DHCP */ if (ic_got_reply) { - printk(" OK\n"); + printk(KERN_CONT " OK\n"); break; } @@ -1205,7 +1205,7 @@ static int __init ic_dynamic(void) continue; if (! --retries) { - printk(" timed out!\n"); + printk(KERN_CONT " timed out!\n"); break; } @@ -1215,7 +1215,7 @@ static int __init ic_dynamic(void) if (timeout > CONF_TIMEOUT_MAX) timeout = CONF_TIMEOUT_MAX; - printk("."); + printk(KERN_CONT "."); } #ifdef IPCONFIG_BOOTP @@ -1236,7 +1236,7 @@ static int __init ic_dynamic(void) ((ic_got_reply & IC_RARP) ? "RARP" : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"), &ic_servaddr); - printk("my address is %pI4\n", &ic_myaddr); + printk(KERN_CONT "my address is %pI4\n", &ic_myaddr); return 0; } @@ -1468,19 +1468,19 @@ static int __init ip_auto_config(void) /* * Clue in the operator. */ - printk("IP-Config: Complete:"); - printk("\n device=%s", ic_dev->name); - printk(", addr=%pI4", &ic_myaddr); - printk(", mask=%pI4", &ic_netmask); - printk(", gw=%pI4", &ic_gateway); - printk(",\n host=%s, domain=%s, nis-domain=%s", + printk("IP-Config: Complete:\n"); + printk(" device=%s", ic_dev->name); + printk(KERN_CONT ", addr=%pI4", &ic_myaddr); + printk(KERN_CONT ", mask=%pI4", &ic_netmask); + printk(KERN_CONT ", gw=%pI4", &ic_gateway); + printk(KERN_CONT ",\n host=%s, domain=%s, nis-domain=%s", utsname()->nodename, ic_domain, utsname()->domainname); - printk(",\n bootserver=%pI4", &ic_servaddr); - printk(", rootserver=%pI4", &root_server_addr); - printk(", rootpath=%s", root_server_path); + printk(KERN_CONT ",\n bootserver=%pI4", &ic_servaddr); + printk(KERN_CONT ", rootserver=%pI4", &root_server_addr); + printk(KERN_CONT ", rootpath=%s", root_server_path); if (ic_dev_mtu) - printk(", mtu=%d", ic_dev_mtu); - printk("\n"); + printk(KERN_CONT ", mtu=%d", ic_dev_mtu); + printk(KERN_CONT "\n"); #endif /* !SILENT */ return 0; -- cgit v1.2.3-59-g8ed1b From d3c15cab213becc49a6f2ad7f48a59513a5f17dd Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 24 Nov 2010 21:47:56 +0000 Subject: ipv6: kill two unused macro definition 1. IPV6_TLV_TEL_DST_SIZE This has not been using for several years since created. 2. RT6_INFO_LEN commit 33120b30 kill all RT6_INFO_LEN's references, but only this definition remained. commit 33120b30cc3b8665204d4fcde7288638b0dd04d5 Author: Alexey Dobriyan Date: Tue Nov 6 05:27:11 2007 -0800 [IPV6]: Convert /proc/net/ipv6_route to seq_file interface Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 2 -- net/ipv6/route.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a59610c2a58..b1155554bb18 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -58,8 +58,6 @@ MODULE_AUTHOR("Ville Nuorvala"); MODULE_DESCRIPTION("IPv6 tunneling device"); MODULE_LICENSE("GPL"); -#define IPV6_TLV_TEL_DST_SIZE 8 - #ifdef IP6_TNL_DEBUG #define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__) #else diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c346ccf66ae1..a0c4ad109c63 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2453,8 +2453,6 @@ static int ip6_route_dev_notify(struct notifier_block *this, #ifdef CONFIG_PROC_FS -#define RT6_INFO_LEN (32 + 4 + 32 + 4 + 32 + 40 + 5 + 1) - struct rt6_proc_arg { char *buffer; -- cgit v1.2.3-59-g8ed1b From 5a0d2268d259886f0c87131639d19eb4a67b4532 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 23 Nov 2010 10:42:02 +0000 Subject: net: add netif_tx_queue_frozen_or_stopped When testing struct netdev_queue state against FROZEN bit, we also test XOFF bit. We can test both bits at once and save some cycles. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 6 ++++-- net/core/netpoll.c | 3 +-- net/core/pktgen.c | 2 +- net/sched/sch_generic.c | 8 +++----- net/sched/sch_teql.c | 3 +-- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index badf9285fe0d..7c6ae2f4b9ab 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -493,6 +493,8 @@ static inline void napi_synchronize(const struct napi_struct *n) enum netdev_queue_state_t { __QUEUE_STATE_XOFF, __QUEUE_STATE_FROZEN, +#define QUEUE_STATE_XOFF_OR_FROZEN ((1 << __QUEUE_STATE_XOFF) | \ + (1 << __QUEUE_STATE_FROZEN)) }; struct netdev_queue { @@ -1629,9 +1631,9 @@ static inline int netif_queue_stopped(const struct net_device *dev) return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0)); } -static inline int netif_tx_queue_frozen(const struct netdev_queue *dev_queue) +static inline int netif_tx_queue_frozen_or_stopped(const struct netdev_queue *dev_queue) { - return test_bit(__QUEUE_STATE_FROZEN, &dev_queue->state); + return dev_queue->state & QUEUE_STATE_XOFF_OR_FROZEN; } /** diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 4e98ffac3af0..ee38acb6d463 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -76,8 +76,7 @@ static void queue_process(struct work_struct *work) local_irq_save(flags); __netif_tx_lock(txq, smp_processor_id()); - if (netif_tx_queue_stopped(txq) || - netif_tx_queue_frozen(txq) || + if (netif_tx_queue_frozen_or_stopped(txq) || ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) { skb_queue_head(&npinfo->txq, skb); __netif_tx_unlock(txq); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2e57830cbeb2..2953b2abc971 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3527,7 +3527,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) __netif_tx_lock_bh(txq); - if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq))) { + if (unlikely(netif_tx_queue_frozen_or_stopped(txq))) { ret = NETDEV_TX_BUSY; pkt_dev->last_ok = 0; goto unlock; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 5dbb3cd96e59..7f0bd8952646 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -60,8 +60,7 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q) /* check the reason of requeuing without tx lock first */ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); - if (!netif_tx_queue_stopped(txq) && - !netif_tx_queue_frozen(txq)) { + if (!netif_tx_queue_frozen_or_stopped(txq)) { q->gso_skb = NULL; q->q.qlen--; } else @@ -122,7 +121,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, spin_unlock(root_lock); HARD_TX_LOCK(dev, txq, smp_processor_id()); - if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq)) + if (!netif_tx_queue_frozen_or_stopped(txq)) ret = dev_hard_start_xmit(skb, dev, txq); HARD_TX_UNLOCK(dev, txq); @@ -144,8 +143,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, ret = dev_requeue_skb(skb, q); } - if (ret && (netif_tx_queue_stopped(txq) || - netif_tx_queue_frozen(txq))) + if (ret && netif_tx_queue_frozen_or_stopped(txq)) ret = 0; return ret; diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 401af9596709..106479a7c94a 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -309,8 +309,7 @@ restart: if (__netif_tx_trylock(slave_txq)) { unsigned int length = qdisc_pkt_len(skb); - if (!netif_tx_queue_stopped(slave_txq) && - !netif_tx_queue_frozen(slave_txq) && + if (!netif_tx_queue_frozen_or_stopped(slave_txq) && slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) { txq_trans_update(slave_txq); __netif_tx_unlock(slave_txq); -- cgit v1.2.3-59-g8ed1b From 19eb5cc559f716dc98ce03a5bad6030fdc71e897 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 24 Nov 2010 13:14:50 +0000 Subject: 8021q: vlan device is lockless do not transfer real_num_{tx|rx}_queues Now that the vlan device is lockless and single queue do not transfer the real num queues. This is causing a BUG_ON to occur. kernel BUG at net/8021q/vlan.c:345! Call Trace: [] ? fib_rules_event+0x28/0x1b0 [] notifier_call_chain+0x55/0x80 [] raw_notifier_call_chain+0x16/0x20 [] call_netdevice_notifiers+0x37/0x70 [] netdev_features_change+0x16/0x20 [] ixgbe_fcoe_enable+0xae/0x100 [ixgbe] [] vlan_dev_fcoe_enable+0x2a/0x30 [8021q] [] fcoe_create+0x163/0x630 [fcoe] [] ? mmap_region+0x255/0x5a0 [] param_attr_store+0x50/0x80 [] module_attr_store+0x26/0x30 [] sysfs_write_file+0xf2/0x180 [] vfs_write+0xc8/0x190 [] sys_write+0x51/0x90 [] system_call_fastpath+0x16/0x1b Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- net/8021q/vlan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index dc1071327d87..6e64f7c6a2e9 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -341,9 +341,6 @@ static void vlan_transfer_features(struct net_device *dev, #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; #endif - vlandev->real_num_tx_queues = dev->real_num_tx_queues; - BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues); - if (old_features != vlandev->features) netdev_features_change(vlandev); } -- cgit v1.2.3-59-g8ed1b From a5dac108d57072eec4d6745f32c162524509f2cb Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Wed, 24 Nov 2010 13:48:54 +0000 Subject: bnx2: Fix reset bug on 5709 The 5709 chip requires the BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE bit to be cleared and polling for pending DMAs to complete before chip reset. Without this step, we've seen NMIs during repeated resets of the chip. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 29 ++++++++++++++++++++++------- drivers/net/bnx2.h | 2 ++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0de196da4d4a..78f91ef44969 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -4640,13 +4640,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) /* Wait for the current PCI transaction to complete before * issuing a reset. */ - REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, - BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); - val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); - udelay(5); + if ((CHIP_NUM(bp) == CHIP_NUM_5706) || + (CHIP_NUM(bp) == CHIP_NUM_5708)) { + REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, + BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); + val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); + udelay(5); + } else { /* 5709 */ + val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); + val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE; + REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val); + val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); + + for (i = 0; i < 100; i++) { + msleep(1); + val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL); + if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND)) + break; + } + } /* Wait for the firmware to tell us it is ok to issue a reset. */ bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index bf4c3421067d..5488a2e82fe9 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -461,6 +461,8 @@ struct l2_fhdr { #define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090 #define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094 +#define BNX2_PCICFG_DEVICE_CONTROL 0x000000b4 +#define BNX2_PCICFG_DEVICE_STATUS_NO_PEND ((1L<<5)<<16) /* * pci_reg definition -- cgit v1.2.3-59-g8ed1b From be7ff1afec25f2700ca85e3956a2cb3a7b74acd5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 24 Nov 2010 13:48:55 +0000 Subject: bnx2: Remove config access to non-standard registers In KVM passthrough mode, the driver may not have config access to non-standard registers. The BNX2_PCICFG_MISC_CONFIG config register access to setup mailbox swapping can be done using MMIO. Update version to 2.0.20. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 78f91ef44969..03209a37883e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.18" -#define DRV_MODULE_RELDATE "Oct 7, 2010" +#define DRV_MODULE_VERSION "2.0.20" +#define DRV_MODULE_RELDATE "Nov 24, 2010" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" @@ -4683,7 +4683,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; - pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val); + REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); } else { val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | @@ -7924,15 +7924,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) goto err_out_release; } + bnx2_set_power_state(bp, PCI_D0); + /* Configure byte swap and enable write to the reg_window registers. * Rely on CPU to do target byte swapping on big endian systems * The chip's target access swapping will not swap all accesses */ - pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, - BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | - BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); - - bnx2_set_power_state(bp, PCI_D0); + REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, + BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | + BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); bp->chip_id = REG_RD(bp, BNX2_MISC_ID); -- cgit v1.2.3-59-g8ed1b From 5892b9e9ebdde50fbd524570d61ceb74f8be33f3 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 28 Nov 2010 00:23:35 +0000 Subject: bnx2x: Use helpers instead of direct access to the shinfo(skb) fields Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6f..e20b2d378929 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1692,11 +1692,10 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) } } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) - rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); - - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); + if (skb_is_gso_v6(skb)) + rc |= XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6; + else if (skb_is_gso(skb)) + rc |= XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP; return rc; } -- cgit v1.2.3-59-g8ed1b From 5595a1a5997953dbd8c5df7c2f7d4b3a2eb2be4b Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:15 +0000 Subject: X25 remove bkl in subscription ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- include/net/x25.h | 2 ++ net/x25/af_x25.c | 12 ++++-------- net/x25/x25_link.c | 8 ++++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/net/x25.h b/include/net/x25.h index 1479cb4a41fc..a06119a05129 100644 --- a/include/net/x25.h +++ b/include/net/x25.h @@ -315,6 +315,8 @@ extern struct list_head x25_route_list; extern rwlock_t x25_route_list_lock; extern struct list_head x25_forward_list; extern rwlock_t x25_forward_list_lock; +extern struct list_head x25_neigh_list; +extern rwlock_t x25_neigh_list_lock; extern int x25_proc_init(void); extern void x25_proc_exit(void); diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2351aceb296d..45be72c3f940 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1415,17 +1415,13 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = x25_route_ioctl(cmd, argp); break; case SIOCX25GSUBSCRIP: - lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GFACILITIES: { struct x25_facilities fac = x25->facilities; @@ -1646,16 +1642,20 @@ static int compat_x25_subscr_ioctl(unsigned int cmd, dev_put(dev); if (cmd == SIOCX25GSUBSCRIP) { + read_lock_bh(&x25_neigh_list_lock); x25_subscr.extended = nb->extended; x25_subscr.global_facil_mask = nb->global_facil_mask; + read_unlock_bh(&x25_neigh_list_lock); rc = copy_to_user(x25_subscr32, &x25_subscr, sizeof(*x25_subscr32)) ? -EFAULT : 0; } else { rc = -EINVAL; if (x25_subscr.extended == 0 || x25_subscr.extended == 1) { rc = 0; + write_lock_bh(&x25_neigh_list_lock); nb->extended = x25_subscr.extended; nb->global_facil_mask = x25_subscr.global_facil_mask; + write_unlock_bh(&x25_neigh_list_lock); } } x25_neigh_put(nb); @@ -1711,17 +1711,13 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, rc = x25_route_ioctl(cmd, argp); break; case SIOCX25GSUBSCRIP: - lock_kernel(); rc = compat_x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = compat_x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GFACILITIES: case SIOCX25SFACILITIES: diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 73e7b954ad28..4c81f6abb65b 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -31,8 +31,8 @@ #include #include -static LIST_HEAD(x25_neigh_list); -static DEFINE_RWLOCK(x25_neigh_list_lock); +LIST_HEAD(x25_neigh_list); +DEFINE_RWLOCK(x25_neigh_list_lock); static void x25_t20timer_expiry(unsigned long); @@ -360,16 +360,20 @@ int x25_subscr_ioctl(unsigned int cmd, void __user *arg) dev_put(dev); if (cmd == SIOCX25GSUBSCRIP) { + read_lock_bh(&x25_neigh_list_lock); x25_subscr.extended = nb->extended; x25_subscr.global_facil_mask = nb->global_facil_mask; + read_unlock_bh(&x25_neigh_list_lock); rc = copy_to_user(arg, &x25_subscr, sizeof(x25_subscr)) ? -EFAULT : 0; } else { rc = -EINVAL; if (!(x25_subscr.extended && x25_subscr.extended != 1)) { rc = 0; + write_lock_bh(&x25_neigh_list_lock); nb->extended = x25_subscr.extended; nb->global_facil_mask = x25_subscr.global_facil_mask; + write_unlock_bh(&x25_neigh_list_lock); } } x25_neigh_put(nb); -- cgit v1.2.3-59-g8ed1b From f90de660678cf553f63c387945830a2e4d26dd3e Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:35 +0000 Subject: X25 remove bkl in facility ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 45be72c3f940..2518efae8ec9 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1424,34 +1424,34 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = x25_subscr_ioctl(cmd, argp); break; case SIOCX25GFACILITIES: { - struct x25_facilities fac = x25->facilities; - lock_kernel(); - rc = copy_to_user(argp, &fac, - sizeof(fac)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->facilities, + sizeof(x25->facilities)) + ? -EFAULT : 0; + release_sock(sk); break; } case SIOCX25SFACILITIES: { struct x25_facilities facilities; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&facilities, argp, sizeof(facilities))) break; rc = -EINVAL; + lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - break; + goto out_fac_release; if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096) - break; + goto out_fac_release; if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096) - break; + goto out_fac_release; if (facilities.winsize_in < 1 || facilities.winsize_in > 127) - break; + goto out_fac_release; if (facilities.throughput) { int out = facilities.throughput & 0xf0; int in = facilities.throughput & 0x0f; @@ -1459,27 +1459,28 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) facilities.throughput |= X25_DEFAULT_THROUGHPUT << 4; else if (out < 0x30 || out > 0xD0) - break; + goto out_fac_release; if (!in) facilities.throughput |= X25_DEFAULT_THROUGHPUT; else if (in < 0x03 || in > 0x0D) - break; + goto out_fac_release; } if (facilities.reverse && (facilities.reverse & 0x81) != 0x81) - break; + goto out_fac_release; x25->facilities = facilities; rc = 0; - unlock_kernel(); +out_fac_release: + release_sock(sk); break; } case SIOCX25GDTEFACILITIES: { - lock_kernel(); + lock_sock(sk); rc = copy_to_user(argp, &x25->dte_facilities, sizeof(x25->dte_facilities)); - unlock_kernel(); + release_sock(sk); if (rc) rc = -EFAULT; break; @@ -1488,24 +1489,25 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SDTEFACILITIES: { struct x25_dte_facilities dtefacs; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) break; rc = -EINVAL; + lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - break; + goto out_dtefac_release; if (dtefacs.calling_len > X25_MAX_AE_LEN) - break; + goto out_dtefac_release; if (dtefacs.calling_ae == NULL) - break; + goto out_dtefac_release; if (dtefacs.called_len > X25_MAX_AE_LEN) - break; + goto out_dtefac_release; if (dtefacs.called_ae == NULL) - break; + goto out_dtefac_release; x25->dte_facilities = dtefacs; rc = 0; - unlock_kernel(); +out_dtefac_release: + release_sock(sk); break; } -- cgit v1.2.3-59-g8ed1b From 5b7958dfa5db758e36e92e1790075b470b4947f8 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:40 +0000 Subject: X25 remove bkl from calluserdata ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2518efae8ec9..e2eea0aec466 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1512,11 +1512,11 @@ out_dtefac_release: } case SIOCX25GCALLUSERDATA: { - struct x25_calluserdata cud = x25->calluserdata; - lock_kernel(); - rc = copy_to_user(argp, &cud, - sizeof(cud)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->calluserdata, + sizeof(x25->calluserdata)) + ? -EFAULT : 0; + release_sock(sk); break; } @@ -1524,15 +1524,15 @@ out_dtefac_release: struct x25_calluserdata calluserdata; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&calluserdata, argp, sizeof(calluserdata))) break; rc = -EINVAL; if (calluserdata.cudlength > X25_MAX_CUD_LEN) break; + lock_sock(sk); x25->calluserdata = calluserdata; - unlock_kernel(); + release_sock(sk); rc = 0; break; } -- cgit v1.2.3-59-g8ed1b From 74a7e440807d34e586e9feb8e14851b5c80fbfe5 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:43 +0000 Subject: X25 remove bkl from causediag ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index e2eea0aec466..8cfc419cef4b 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1538,23 +1538,22 @@ out_dtefac_release: } case SIOCX25GCAUSEDIAG: { - struct x25_causediag causediag; - lock_kernel(); - causediag = x25->causediag; - rc = copy_to_user(argp, &causediag, - sizeof(causediag)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->causediag, + sizeof(x25->causediag)) + ? -EFAULT : 0; + release_sock(sk); break; } case SIOCX25SCAUSEDIAG: { struct x25_causediag causediag; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&causediag, argp, sizeof(causediag))) break; + lock_sock(sk); x25->causediag = causediag; - unlock_kernel(); + release_sock(sk); rc = 0; break; -- cgit v1.2.3-59-g8ed1b From 3f0a069a1d5c0ccace735e3a62c1bcef53e4c354 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:45 +0000 Subject: X25 remove bkl in call user data length ioctl Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 8cfc419cef4b..ad96ee90fe27 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1562,19 +1562,20 @@ out_dtefac_release: case SIOCX25SCUDMATCHLEN: { struct x25_subaddr sub_addr; rc = -EINVAL; - lock_kernel(); + lock_sock(sk); if(sk->sk_state != TCP_CLOSE) - break; + goto out_cud_release; rc = -EFAULT; if (copy_from_user(&sub_addr, argp, sizeof(sub_addr))) - break; + goto out_cud_release; rc = -EINVAL; if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) - break; + goto out_cud_release; x25->cudmatchlength = sub_addr.cudmatchlength; - unlock_kernel(); rc = 0; +out_cud_release: + release_sock(sk); break; } -- cgit v1.2.3-59-g8ed1b From e0f4258be2515afce8ef1e6fb22312525c281798 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:25 +0000 Subject: ethoc: Add device tree configuration This patch adds the ability to describe ethernet devices via a flattened device tree. As device tree remains an optional feature, these bits all need to be guarded by CONFIG_OF ifdefs. MAC address is settable via the device tree parameter "local-mac-address"; however, the selection of the phy id is limited to probing, for now. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index c5a2fe099a8d..9ea3c54e1a38 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include static int buffer_size = 0x8000; /* 32 KBytes */ @@ -982,10 +983,23 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* Allow the platform setup code to pass in a MAC address. */ if (pdev->dev.platform_data) { - struct ethoc_platform_data *pdata = - (struct ethoc_platform_data *)pdev->dev.platform_data; + struct ethoc_platform_data *pdata = pdev->dev.platform_data; memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); priv->phy_id = pdata->phy_id; + } else { + priv->phy_id = -1; + +#ifdef CONFIG_OF + { + const uint8_t* mac; + + mac = of_get_property(pdev->dev.of_node, + "local-mac-address", + NULL); + if (mac) + memcpy(netdev->dev_addr, mac, IFHWADDRLEN); + } +#endif } /* Check that the given MAC address is valid. If it isn't, read the @@ -1113,6 +1127,16 @@ static int ethoc_resume(struct platform_device *pdev) # define ethoc_resume NULL #endif +#ifdef CONFIG_OF +static struct of_device_id ethoc_match[] = { + { + .compatible = "opencores,ethoc", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ethoc_match); +#endif + static struct platform_driver ethoc_driver = { .probe = ethoc_probe, .remove = __devexit_p(ethoc_remove), @@ -1120,6 +1144,10 @@ static struct platform_driver ethoc_driver = { .resume = ethoc_resume, .driver = { .name = "ethoc", + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = ethoc_match, +#endif }, }; -- cgit v1.2.3-59-g8ed1b From eac0d3ff5a92de410964fdf0d072314821ca39fc Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:26 +0000 Subject: ethoc: remove unused spinlock Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 9ea3c54e1a38..e9e712e0f92c 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -185,7 +185,6 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); * @netdev: pointer to network device structure * @napi: NAPI structure * @msg_enable: device state flags - * @rx_lock: receive lock * @lock: device lock * @phy: attached PHY * @mdio: MDIO bus for PHY access @@ -210,7 +209,6 @@ struct ethoc { struct napi_struct napi; u32 msg_enable; - spinlock_t rx_lock; spinlock_t lock; struct phy_device *phy; @@ -1060,7 +1058,6 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* setup NAPI */ netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); - spin_lock_init(&priv->rx_lock); spin_lock_init(&priv->lock); ret = register_netdev(netdev); -- cgit v1.2.3-59-g8ed1b From 7438a5455734d109fdf18d97147dc57a6dbe5a44 Mon Sep 17 00:00:00 2001 From: Adam Edvardsson Date: Thu, 25 Nov 2010 02:30:27 +0000 Subject: ethoc: enable interrupts after napi_complete Occasionally, it seems that some race is causing the interrupts to not be reenabled otherwise with the end result that networking just stops working. Enabling interrupts after calling napi_complete is more in line with what other drivers do. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index e9e712e0f92c..db444a73e4b1 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -569,8 +569,8 @@ static int ethoc_poll(struct napi_struct *napi, int budget) work_done = ethoc_rx(priv->netdev, budget); if (work_done < budget) { - ethoc_enable_irq(priv, INT_MASK_RX); napi_complete(napi); + ethoc_enable_irq(priv, INT_MASK_RX); } return work_done; -- cgit v1.2.3-59-g8ed1b From 20f70ddd6558a39a89dba4af675686c5a8dbd7b3 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:28 +0000 Subject: ethoc: Double check pending RX packet An interrupt may occur between checking bd.stat and clearing the interrupt source register which would result in the packet going totally unnoticed as the interrupt will be missed. Double check bd.stat after clearing the interrupt source register to guard against such an occurrence. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index db444a73e4b1..a12a07ea02b6 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -414,8 +414,19 @@ static int ethoc_rx(struct net_device *dev, int limit) entry = priv->num_tx + (priv->cur_rx % priv->num_rx); ethoc_read_bd(priv, entry, &bd); - if (bd.stat & RX_BD_EMPTY) - break; + if (bd.stat & RX_BD_EMPTY) { + ethoc_ack_irq(priv, INT_MASK_RX); + /* If packet (interrupt) came in between checking + * BD_EMTPY and clearing the interrupt source, then we + * risk missing the packet as the RX interrupt won't + * trigger right away when we reenable it; hence, check + * BD_EMTPY here again to make sure there isn't such a + * packet waiting for us... + */ + ethoc_read_bd(priv, entry, &bd); + if (bd.stat & RX_BD_EMPTY) + break; + } if (ethoc_update_rx_stats(priv, &bd) == 0) { int size = bd.stat >> 16; -- cgit v1.2.3-59-g8ed1b From fa98eb0e867c6c16e239545d4deb7ad8f40631b3 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:29 +0000 Subject: ethoc: rework interrupt handling The old interrupt handling was incorrect in that it did not account for the fact that the interrupt source bits get set irregardless of whether or not their corresponding mask is set. This patch fixes that by masking off the source bits for masked interrupts. Furthermore, the handling of transmission events is moved to the NAPI polling handler alongside the reception handler, thus preventing a whole bunch of interrupts during heavy traffic. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 76 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index a12a07ea02b6..43431ffcf6c1 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -495,29 +495,42 @@ static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) return 0; } -static void ethoc_tx(struct net_device *dev) +static int ethoc_tx(struct net_device *dev, int limit) { struct ethoc *priv = netdev_priv(dev); + int count; + struct ethoc_bd bd; - spin_lock(&priv->lock); + for (count = 0; count < limit; ++count) { + unsigned int entry; - while (priv->dty_tx != priv->cur_tx) { - unsigned int entry = priv->dty_tx % priv->num_tx; - struct ethoc_bd bd; + entry = priv->dty_tx % priv->num_tx; ethoc_read_bd(priv, entry, &bd); - if (bd.stat & TX_BD_READY) - break; - entry = (++priv->dty_tx) % priv->num_tx; + if (bd.stat & TX_BD_READY || (priv->dty_tx == priv->cur_tx)) { + ethoc_ack_irq(priv, INT_MASK_TX); + /* If interrupt came in between reading in the BD + * and clearing the interrupt source, then we risk + * missing the event as the TX interrupt won't trigger + * right away when we reenable it; hence, check + * BD_EMPTY here again to make sure there isn't such an + * event pending... + */ + ethoc_read_bd(priv, entry, &bd); + if (bd.stat & TX_BD_READY || + (priv->dty_tx == priv->cur_tx)) + break; + } + (void)ethoc_update_tx_stats(priv, &bd); + priv->dty_tx++; } if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2)) netif_wake_queue(dev); - ethoc_ack_irq(priv, INT_MASK_TX); - spin_unlock(&priv->lock); + return count; } static irqreturn_t ethoc_interrupt(int irq, void *dev_id) @@ -525,32 +538,38 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id) struct net_device *dev = dev_id; struct ethoc *priv = netdev_priv(dev); u32 pending; - - ethoc_disable_irq(priv, INT_MASK_ALL); + u32 mask; + + /* Figure out what triggered the interrupt... + * The tricky bit here is that the interrupt source bits get + * set in INT_SOURCE for an event irregardless of whether that + * event is masked or not. Thus, in order to figure out what + * triggered the interrupt, we need to remove the sources + * for all events that are currently masked. This behaviour + * is not particularly well documented but reasonable... + */ + mask = ethoc_read(priv, INT_MASK); pending = ethoc_read(priv, INT_SOURCE); + pending &= mask; + if (unlikely(pending == 0)) { - ethoc_enable_irq(priv, INT_MASK_ALL); return IRQ_NONE; } ethoc_ack_irq(priv, pending); + /* We always handle the dropped packet interrupt */ if (pending & INT_MASK_BUSY) { dev_err(&dev->dev, "packet dropped\n"); dev->stats.rx_dropped++; } - if (pending & INT_MASK_RX) { - if (napi_schedule_prep(&priv->napi)) - __napi_schedule(&priv->napi); - } else { - ethoc_enable_irq(priv, INT_MASK_RX); + /* Handle receive/transmit event by switching to polling */ + if (pending & (INT_MASK_TX | INT_MASK_RX)) { + ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX); + napi_schedule(&priv->napi); } - if (pending & INT_MASK_TX) - ethoc_tx(dev); - - ethoc_enable_irq(priv, INT_MASK_ALL & ~INT_MASK_RX); return IRQ_HANDLED; } @@ -576,15 +595,18 @@ static int ethoc_get_mac_address(struct net_device *dev, void *addr) static int ethoc_poll(struct napi_struct *napi, int budget) { struct ethoc *priv = container_of(napi, struct ethoc, napi); - int work_done = 0; + int rx_work_done = 0; + int tx_work_done = 0; + + rx_work_done = ethoc_rx(priv->netdev, budget); + tx_work_done = ethoc_tx(priv->netdev, budget); - work_done = ethoc_rx(priv->netdev, budget); - if (work_done < budget) { + if (rx_work_done < budget && tx_work_done < budget) { napi_complete(napi); - ethoc_enable_irq(priv, INT_MASK_RX); + ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); } - return work_done; + return rx_work_done; } static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) -- cgit v1.2.3-59-g8ed1b From 8dac428ae9ae54d8e8540ac157d92925dd7ebed8 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:30 +0000 Subject: ethoc: rework mdio read/write MDIO read and write were checking whether a timeout had expired to determine whether to recheck the result of the MDIO operation. Under heavy CPU usage, however, it was possible for the timeout to expire before the routine got around to be able to check a second time even, thus erroneousy returning an -EBUSY. This patch changes the the MDIO IO routines to try up to five times to complete the operation before giving up, thus lessening the dependency on CPU load. This resolves a problem whereby a ping flood would keep the CPU so busy that the above problem would manifest itself; the MDIO command to check link status would fail and the interface would erroneously be shut down. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 43431ffcf6c1..f3048faa3c66 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -611,13 +611,13 @@ static int ethoc_poll(struct napi_struct *napi, int budget) static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) { - unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT; struct ethoc *priv = bus->priv; + int i; ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ); - while (time_before(jiffies, timeout)) { + for (i=0; i < 5; i++) { u32 status = ethoc_read(priv, MIISTATUS); if (!(status & MIISTATUS_BUSY)) { u32 data = ethoc_read(priv, MIIRX_DATA); @@ -625,8 +625,7 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) ethoc_write(priv, MIICOMMAND, 0); return data; } - - schedule(); + usleep_range(100,200); } return -EBUSY; @@ -634,22 +633,21 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) { - unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT; struct ethoc *priv = bus->priv; + int i; ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); ethoc_write(priv, MIITX_DATA, val); ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE); - while (time_before(jiffies, timeout)) { + for (i=0; i < 5; i++) { u32 stat = ethoc_read(priv, MIISTATUS); if (!(stat & MIISTATUS_BUSY)) { /* reset MII command register */ ethoc_write(priv, MIICOMMAND, 0); return 0; } - - schedule(); + usleep_range(100,200); } return -EBUSY; -- cgit v1.2.3-59-g8ed1b From 4f64bcb2fc093a3a9d7d41220004491ce88e4dd3 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:31 +0000 Subject: ethoc: fix function return type update_ethoc_tx_stats doesn't need to return anything so make its return type void in order to avoid an unnecessary cast when the function is called. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index f3048faa3c66..93b50d674b1e 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -462,7 +462,7 @@ static int ethoc_rx(struct net_device *dev, int limit) return count; } -static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) +static void ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) { struct net_device *netdev = dev->netdev; @@ -492,7 +492,6 @@ static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) netdev->stats.collisions += (bd->stat >> 4) & 0xf; netdev->stats.tx_bytes += bd->stat >> 16; netdev->stats.tx_packets++; - return 0; } static int ethoc_tx(struct net_device *dev, int limit) @@ -523,7 +522,7 @@ static int ethoc_tx(struct net_device *dev, int limit) break; } - (void)ethoc_update_tx_stats(priv, &bd); + ethoc_update_tx_stats(priv, &bd); priv->dty_tx++; } -- cgit v1.2.3-59-g8ed1b From 6a632625c7da7594d059b88dae0e9c591af147ba Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 25 Nov 2010 02:30:32 +0000 Subject: ethoc: remove division from loops Calculating the BD entry using a modulus operation isn't optimal, especially inside the loop. This patch removes the modulus operations in favour of: i) simply checking for wrapping in the case of cur_rx ii) forcing num_tx to be a power of two and using it to mask out the entry from cur_tx The also prevents possible issues related overflow of the cur_rx and cur_tx counters. Signed-off-by: Jonas Bonn Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 93b50d674b1e..b79d7e1555d5 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -412,7 +412,7 @@ static int ethoc_rx(struct net_device *dev, int limit) unsigned int entry; struct ethoc_bd bd; - entry = priv->num_tx + (priv->cur_rx % priv->num_rx); + entry = priv->num_tx + priv->cur_rx; ethoc_read_bd(priv, entry, &bd); if (bd.stat & RX_BD_EMPTY) { ethoc_ack_irq(priv, INT_MASK_RX); @@ -456,7 +456,8 @@ static int ethoc_rx(struct net_device *dev, int limit) bd.stat &= ~RX_BD_STATS; bd.stat |= RX_BD_EMPTY; ethoc_write_bd(priv, entry, &bd); - priv->cur_rx++; + if (++priv->cur_rx == priv->num_rx) + priv->cur_rx = 0; } return count; @@ -503,7 +504,7 @@ static int ethoc_tx(struct net_device *dev, int limit) for (count = 0; count < limit; ++count) { unsigned int entry; - entry = priv->dty_tx % priv->num_tx; + entry = priv->dty_tx & (priv->num_tx-1); ethoc_read_bd(priv, entry, &bd); @@ -1000,9 +1001,17 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* calculate the number of TX/RX buffers, maximum 128 supported */ num_bd = min_t(unsigned int, 128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ); - priv->num_tx = max(2, num_bd / 4); + if (num_bd < 4) { + ret = -ENODEV; + goto error; + } + /* num_tx must be a power of two */ + priv->num_tx = rounddown_pow_of_two(num_bd >> 1); priv->num_rx = num_bd - priv->num_tx; + dev_dbg(&pdev->dev, "ethoc: num_tx: %d num_rx: %d\n", + priv->num_tx, priv->num_rx); + priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL); if (!priv->vma) { ret = -ENOMEM; -- cgit v1.2.3-59-g8ed1b From aa285b1740f5b13e5a2606a927f3129954583d78 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Tue, 23 Nov 2010 04:03:45 +0000 Subject: xfrm: fix gre key endianess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fl->fl_gre_key is network byte order contrary to fl->fl_icmp_*. Make xfrm_flowi_{s|d}port return network byte order values for gre key too. Signed-off-by: Timo Teräs Signed-off-by: David S. Miller --- include/net/xfrm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 54b283229488..7fa5b005893e 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -806,7 +806,7 @@ __be16 xfrm_flowi_sport(struct flowi *fl) port = htons(fl->fl_mh_type); break; case IPPROTO_GRE: - port = htonl(fl->fl_gre_key) >> 16; + port = htons(ntohl(fl->fl_gre_key) >> 16); break; default: port = 0; /*XXX*/ @@ -830,7 +830,7 @@ __be16 xfrm_flowi_dport(struct flowi *fl) port = htons(fl->fl_icmp_code); break; case IPPROTO_GRE: - port = htonl(fl->fl_gre_key) & 0xffff; + port = htons(ntohl(fl->fl_gre_key) & 0xffff); break; default: port = 0; /*XXX*/ -- cgit v1.2.3-59-g8ed1b From 82a39eb6b3829a02e235656feddb4542517fcabc Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 25 Nov 2010 03:15:07 +0000 Subject: ipv6: Prepare the tree for un-inlined jhash. jhash is widely used in the kernel and because the functions are inlined, the cost in size is significant. Also, the new jhash functions are slightly larger than the previous ones so better un-inline. As a preparation step, the calls to the internal macros are replaced with the plain jhash function calls. Signed-off-by: Jozsef Kadlecsik Signed-off-by: David S. Miller --- net/ipv6/inet6_connection_sock.c | 22 ++++++++++------------ net/ipv6/reassembly.c | 36 ++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 8a1628023bd1..861d252bd1ba 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -60,18 +60,16 @@ EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport, const u32 rnd, const u16 synq_hsize) { - u32 a = (__force u32)raddr->s6_addr32[0]; - u32 b = (__force u32)raddr->s6_addr32[1]; - u32 c = (__force u32)raddr->s6_addr32[2]; - - a += JHASH_GOLDEN_RATIO; - b += JHASH_GOLDEN_RATIO; - c += rnd; - __jhash_mix(a, b, c); - - a += (__force u32)raddr->s6_addr32[3]; - b += (__force u32)rport; - __jhash_mix(a, b, c); + u32 c; + + c = jhash_3words((__force u32)raddr->s6_addr32[0], + (__force u32)raddr->s6_addr32[1], + (__force u32)raddr->s6_addr32[2], + rnd); + + c = jhash_2words((__force u32)raddr->s6_addr32[3], + (__force u32)rport, + c); return c & (synq_hsize - 1); } diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 0f2766453759..07beeb06f752 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -104,26 +104,22 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr, const struct in6_addr *daddr, u32 rnd) { - u32 a, b, c; - - a = (__force u32)saddr->s6_addr32[0]; - b = (__force u32)saddr->s6_addr32[1]; - c = (__force u32)saddr->s6_addr32[2]; - - a += JHASH_GOLDEN_RATIO; - b += JHASH_GOLDEN_RATIO; - c += rnd; - __jhash_mix(a, b, c); - - a += (__force u32)saddr->s6_addr32[3]; - b += (__force u32)daddr->s6_addr32[0]; - c += (__force u32)daddr->s6_addr32[1]; - __jhash_mix(a, b, c); - - a += (__force u32)daddr->s6_addr32[2]; - b += (__force u32)daddr->s6_addr32[3]; - c += (__force u32)id; - __jhash_mix(a, b, c); + u32 c; + + c = jhash_3words((__force u32)saddr->s6_addr32[0], + (__force u32)saddr->s6_addr32[1], + (__force u32)saddr->s6_addr32[2], + rnd); + + c = jhash_3words((__force u32)saddr->s6_addr32[3], + (__force u32)daddr->s6_addr32[0], + (__force u32)daddr->s6_addr32[1], + c); + + c = jhash_3words((__force u32)daddr->s6_addr32[2], + (__force u32)daddr->s6_addr32[3], + (__force u32)id, + c); return c & (INETFRAGS_HASHSZ - 1); } -- cgit v1.2.3-59-g8ed1b From c661c4a2b0d64c33afc9018a406162b1f8ac5617 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Thu, 25 Nov 2010 07:53:55 +0000 Subject: cxgb3: Removing unused return variable Currently the ret variable is not used for anything other than receive the value of the t3_adapter_error(), which will always be 0, because the reset parameter is 0. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 046d846c652d..386461750d0f 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -3006,12 +3006,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { struct adapter *adapter = pci_get_drvdata(pdev); - int ret; if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - ret = t3_adapter_error(adapter, 0, 0); + t3_adapter_error(adapter, 0, 0); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; -- cgit v1.2.3-59-g8ed1b From 0acdf68f495793143802dd4f3e47918dddcceed7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 27 Nov 2010 23:05:43 +0000 Subject: netxen: remove unnecessary [kv][mcz]alloc casts Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index f946de23fe76..731077d8d962 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -278,8 +278,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) break; } - rds_ring->rx_buf_arr = (struct netxen_rx_buffer *) - vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); + rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { printk(KERN_ERR "%s: Failed to allocate " "rx buffer ring %d\n", -- cgit v1.2.3-59-g8ed1b From f3167460144cd2c24b964a32d40d32f851b5d5f4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 27 Nov 2010 23:05:44 +0000 Subject: qlcnic: remove unnecessary [kv][mcz]alloc casts Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 3f970187cfce..c5ea2f4eb980 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -274,8 +274,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) rds_ring->dma_size + NET_IP_ALIGN; break; } - rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *) - vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); + rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { dev_err(&netdev->dev, "Failed to allocate " "rx buffer ring %d\n", ring); -- cgit v1.2.3-59-g8ed1b From e80be0b0ee307a2801e57cf36333d3d659e4bcc6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 27 Nov 2010 23:05:45 +0000 Subject: vxge: remove unnecessary [kv][mcz]alloc casts Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 24 +++++++++--------------- drivers/net/vxge/vxge-main.c | 4 +--- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 44d3ddd37b3e..a0241fe72d8b 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -1219,8 +1219,7 @@ vxge_hw_device_initialize( if (status != VXGE_HW_OK) goto exit; - hldev = (struct __vxge_hw_device *) - vzalloc(sizeof(struct __vxge_hw_device)); + hldev = vzalloc(sizeof(struct __vxge_hw_device)); if (hldev == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; @@ -2140,8 +2139,7 @@ __vxge_hw_mempool_create( goto exit; } - mempool = (struct vxge_hw_mempool *) - vzalloc(sizeof(struct vxge_hw_mempool)); + mempool = vzalloc(sizeof(struct vxge_hw_mempool)); if (mempool == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; @@ -2165,7 +2163,7 @@ __vxge_hw_mempool_create( /* allocate array of memblocks */ mempool->memblocks_arr = - (void **) vzalloc(sizeof(void *) * mempool->memblocks_max); + vzalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2175,7 +2173,7 @@ __vxge_hw_mempool_create( /* allocate array of private parts of items per memblocks */ mempool->memblocks_priv_arr = - (void **) vzalloc(sizeof(void *) * mempool->memblocks_max); + vzalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_priv_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2184,7 +2182,7 @@ __vxge_hw_mempool_create( } /* allocate array of memblocks DMA objects */ - mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *) + mempool->memblocks_dma_arr = vzalloc(sizeof(struct vxge_hw_mempool_dma) * mempool->memblocks_max); @@ -2196,8 +2194,7 @@ __vxge_hw_mempool_create( } /* allocate hash array of items */ - mempool->items_arr = - (void **) vzalloc(sizeof(void *) * mempool->items_max); + mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max); if (mempool->items_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -4258,8 +4255,7 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev, if (status != VXGE_HW_OK) goto vpath_open_exit1; - vp = (struct __vxge_hw_vpath_handle *) - vzalloc(sizeof(struct __vxge_hw_vpath_handle)); + vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle)); if (vp == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto vpath_open_exit2; @@ -5065,8 +5061,7 @@ static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, item); if (entry == NULL) - entry = (struct __vxge_hw_blockpool_entry *) - vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); + entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); else list_del(&entry->item); @@ -5182,8 +5177,7 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, item); if (entry == NULL) - entry = (struct __vxge_hw_blockpool_entry *) - vmalloc(sizeof( + entry = vmalloc(sizeof( struct __vxge_hw_blockpool_entry)); else list_del(&entry->item); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 5cba4a684f08..a21dae1183e0 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -4602,9 +4602,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) /* Copy the station mac address to the list */ for (i = 0; i < vdev->no_of_vpath; i++) { - entry = (struct vxge_mac_addrs *) - kzalloc(sizeof(struct vxge_mac_addrs), - GFP_KERNEL); + entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_KERNEL); if (NULL == entry) { vxge_debug_init(VXGE_ERR, "%s: mac_addr_list : memory allocation failed", -- cgit v1.2.3-59-g8ed1b From 47c05314328d9c40f6006783dc4c1e3080bd2914 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 28 Nov 2010 00:02:59 +0000 Subject: zd1211rw: document need for kmalloc cast Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wireless/zd1211rw/zd_chip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 87a95bcfee57..dd0bb0cc22d9 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -117,6 +117,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr /* Allocate a single memory block for values and addresses. */ count16 = 2*count; + /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */ a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), GFP_KERNEL); if (!a16) { -- cgit v1.2.3-59-g8ed1b From 78aea4fc67a7534d5f5bbb0419a2bcb50b0547c9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 27 Nov 2010 08:39:43 +0000 Subject: forcedeth: fix multiple code style issues Signed-off-by: Szymon Janc Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 301 ++++++++++++++++++++++-------------------------- 1 file changed, 135 insertions(+), 166 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 0fa1776563a3..87757c89caef 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -186,9 +186,9 @@ enum { NvRegSlotTime = 0x9c, #define NVREG_SLOTTIME_LEGBF_ENABLED 0x80000000 #define NVREG_SLOTTIME_10_100_FULL 0x00007f00 -#define NVREG_SLOTTIME_1000_FULL 0x0003ff00 +#define NVREG_SLOTTIME_1000_FULL 0x0003ff00 #define NVREG_SLOTTIME_HALF 0x0000ff00 -#define NVREG_SLOTTIME_DEFAULT 0x00007f00 +#define NVREG_SLOTTIME_DEFAULT 0x00007f00 #define NVREG_SLOTTIME_MASK 0x000000ff NvRegTxDeferral = 0xA0, @@ -297,7 +297,7 @@ enum { #define NVREG_WAKEUPFLAGS_ENABLE 0x1111 NvRegMgmtUnitGetVersion = 0x204, -#define NVREG_MGMTUNITGETVERSION 0x01 +#define NVREG_MGMTUNITGETVERSION 0x01 NvRegMgmtUnitVersion = 0x208, #define NVREG_MGMTUNITVERSION 0x08 NvRegPowerCap = 0x268, @@ -368,8 +368,8 @@ struct ring_desc_ex { }; union ring_type { - struct ring_desc* orig; - struct ring_desc_ex* ex; + struct ring_desc *orig; + struct ring_desc_ex *ex; }; #define FLAG_MASK_V1 0xffff0000 @@ -444,10 +444,10 @@ union ring_type { #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) /* Miscelaneous hardware related defines: */ -#define NV_PCI_REGSZ_VER1 0x270 -#define NV_PCI_REGSZ_VER2 0x2d4 -#define NV_PCI_REGSZ_VER3 0x604 -#define NV_PCI_REGSZ_MAX 0x604 +#define NV_PCI_REGSZ_VER1 0x270 +#define NV_PCI_REGSZ_VER2 0x2d4 +#define NV_PCI_REGSZ_VER3 0x604 +#define NV_PCI_REGSZ_MAX 0x604 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 @@ -717,7 +717,7 @@ static const struct register_test nv_registers_test[] = { { NvRegMulticastAddrA, 0xffffffff }, { NvRegTxWatermark, 0x0ff }, { NvRegWakeUpFlags, 0x07777 }, - { 0,0 } + { 0, 0 } }; struct nv_skb_map { @@ -911,7 +911,7 @@ static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; * Power down phy when interface is down (persists through reboot; * older Linux and other OSes may not power it up again) */ -static int phy_power_down = 0; +static int phy_power_down; static inline struct fe_priv *get_nvpriv(struct net_device *dev) { @@ -984,12 +984,10 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags) u8 __iomem *base = get_hwbase(dev); if (!nv_optimized(np)) { - if (rxtx_flags & NV_SETUP_RX_RING) { + if (rxtx_flags & NV_SETUP_RX_RING) writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr); - } - if (rxtx_flags & NV_SETUP_TX_RING) { + if (rxtx_flags & NV_SETUP_TX_RING) writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); - } } else { if (rxtx_flags & NV_SETUP_RX_RING) { writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr); @@ -1174,9 +1172,8 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup) unsigned int tries = 0; miicontrol = BMCR_RESET | bmcr_setup; - if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { + if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) return -1; - } /* wait for 500ms */ msleep(500); @@ -1196,7 +1193,7 @@ static int phy_init(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); u8 __iomem *base = get_hwbase(dev); - u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; + u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000, reg; /* phy errata for E3016 phy */ if (np->phy_model == PHY_MODEL_MARVELL_E3016) { @@ -1313,8 +1310,7 @@ static int phy_init(struct net_device *dev) printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); return PHY_ERROR; } - } - else + } else np->gigabit = 0; mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); @@ -1340,7 +1336,7 @@ static int phy_init(struct net_device *dev) } /* phy vendor specific configuration */ - if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { + if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) { phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); @@ -1501,12 +1497,10 @@ static int phy_init(struct net_device *dev) /* restart auto negotiation, power down phy */ mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); - if (phy_power_down) { + if (phy_power_down) mii_control |= BMCR_PDOWN; - } - if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { + if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) return PHY_ERROR; - } return 0; } @@ -1526,8 +1520,8 @@ static void nv_start_rx(struct net_device *dev) } writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); - rx_ctrl |= NVREG_RCVCTL_START; - if (np->mac_in_use) + rx_ctrl |= NVREG_RCVCTL_START; + if (np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN; writel(rx_ctrl, base + NvRegReceiverControl); dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", @@ -1745,7 +1739,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) static int nv_alloc_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - struct ring_desc* less_rx; + struct ring_desc *less_rx; less_rx = np->get_rx.orig; if (less_rx-- == np->first_rx.orig) @@ -1767,9 +1761,8 @@ static int nv_alloc_rx(struct net_device *dev) np->put_rx.orig = np->first_rx.orig; if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) np->put_rx_ctx = np->first_rx_ctx; - } else { + } else return 1; - } } return 0; } @@ -1777,7 +1770,7 @@ static int nv_alloc_rx(struct net_device *dev) static int nv_alloc_rx_optimized(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - struct ring_desc_ex* less_rx; + struct ring_desc_ex *less_rx; less_rx = np->get_rx.ex; if (less_rx-- == np->first_rx.ex) @@ -1800,9 +1793,8 @@ static int nv_alloc_rx_optimized(struct net_device *dev) np->put_rx.ex = np->first_rx.ex; if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) np->put_rx_ctx = np->first_rx_ctx; - } else { + } else return 1; - } } return 0; } @@ -2018,24 +2010,24 @@ static void nv_legacybackoff_reseed(struct net_device *dev) /* Known Good seed sets */ static const u32 main_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { - {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, - {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974}, - {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, - {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974}, - {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984}, - {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984}, - {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84}, - {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}}; + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974}, + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974}, + {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984}, + {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984}, + {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84}, + {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184} }; static const u32 gear_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397}, - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}}; + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395} }; static void nv_gear_backoff_reseed(struct net_device *dev) { @@ -2083,13 +2075,12 @@ static void nv_gear_backoff_reseed(struct net_device *dev) temp = NVREG_BKOFFCTRL_DEFAULT | (0 << NVREG_BKOFFCTRL_SELECT); temp |= combinedSeed & NVREG_BKOFFCTRL_SEED_MASK; temp |= combinedSeed >> NVREG_BKOFFCTRL_GEAR; - writel(temp,base + NvRegBackOffControl); + writel(temp, base + NvRegBackOffControl); - /* Setup seeds for all gear LFSRs. */ + /* Setup seeds for all gear LFSRs. */ get_random_bytes(&seedset, sizeof(seedset)); seedset = seedset % BACKOFF_SEEDSET_ROWS; - for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) - { + for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) { temp = NVREG_BKOFFCTRL_DEFAULT | (i << NVREG_BKOFFCTRL_SELECT); temp |= main_seedset[seedset][i-1] & 0x3ff; temp |= ((gear_seedset[seedset][i-1] & 0x3ff) << NVREG_BKOFFCTRL_GEAR); @@ -2113,10 +2104,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 size = skb_headlen(skb); u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); u32 empty_slots; - struct ring_desc* put_tx; - struct ring_desc* start_tx; - struct ring_desc* prev_tx; - struct nv_skb_map* prev_tx_ctx; + struct ring_desc *put_tx; + struct ring_desc *start_tx; + struct ring_desc *prev_tx; + struct nv_skb_map *prev_tx_ctx; unsigned long flags; /* add fragments to entries count */ @@ -2208,10 +2199,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, entries, tx_flags_extra); { int j; - for (j=0; j<64; j++) { + for (j = 0; j < 64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); + dprintk(" %02x", ((unsigned char *)skb->data)[j]); } dprintk("\n"); } @@ -2233,11 +2224,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, u32 size = skb_headlen(skb); u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); u32 empty_slots; - struct ring_desc_ex* put_tx; - struct ring_desc_ex* start_tx; - struct ring_desc_ex* prev_tx; - struct nv_skb_map* prev_tx_ctx; - struct nv_skb_map* start_tx_ctx; + struct ring_desc_ex *put_tx; + struct ring_desc_ex *start_tx; + struct ring_desc_ex *prev_tx; + struct nv_skb_map *prev_tx_ctx; + struct nv_skb_map *start_tx_ctx; unsigned long flags; /* add fragments to entries count */ @@ -2359,10 +2350,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, dev->name, entries, tx_flags_extra); { int j; - for (j=0; j<64; j++) { + for (j = 0; j < 64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); + dprintk(" %02x", ((unsigned char *)skb->data)[j]); } dprintk("\n"); } @@ -2399,7 +2390,7 @@ static int nv_tx_done(struct net_device *dev, int limit) struct fe_priv *np = netdev_priv(dev); u32 flags; int tx_work = 0; - struct ring_desc* orig_get_tx = np->get_tx.orig; + struct ring_desc *orig_get_tx = np->get_tx.orig; while ((np->get_tx.orig != np->put_tx.orig) && !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) && @@ -2464,7 +2455,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) struct fe_priv *np = netdev_priv(dev); u32 flags; int tx_work = 0; - struct ring_desc_ex* orig_get_tx = np->get_tx.ex; + struct ring_desc_ex *orig_get_tx = np->get_tx.ex; while ((np->get_tx.ex != np->put_tx.ex) && !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) && @@ -2491,9 +2482,8 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) np->get_tx_ctx->skb = NULL; tx_work++; - if (np->tx_limit) { + if (np->tx_limit) nv_tx_flip_ownership(dev); - } } if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) np->get_tx.ex = np->first_tx.ex; @@ -2532,7 +2522,7 @@ static void nv_tx_timeout(struct net_device *dev) printk(KERN_INFO "%s: Ring at %lx\n", dev->name, (unsigned long)np->ring_addr); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); - for (i=0;i<=np->register_size;i+= 32) { + for (i = 0; i <= np->register_size; i += 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, readl(base + i + 0), readl(base + i + 4), @@ -2541,7 +2531,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;itx_ring_size;i+= 4) { + for (i = 0; i < np->tx_ring_size; i += 4) { if (!nv_optimized(np)) { printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", i, @@ -2616,11 +2606,11 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) int protolen; /* length as stored in the proto field */ /* 1) calculate len according to header */ - if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { - protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto ); + if (((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { + protolen = ntohs(((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto); hdrlen = VLAN_HLEN; } else { - protolen = ntohs( ((struct ethhdr *)packet)->h_proto); + protolen = ntohs(((struct ethhdr *)packet)->h_proto); hdrlen = ETH_HLEN; } dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n", @@ -2667,7 +2657,7 @@ static int nv_rx_process(struct net_device *dev, int limit) struct sk_buff *skb; int len; - while((np->get_rx.orig != np->put_rx.orig) && + while ((np->get_rx.orig != np->put_rx.orig) && !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) && (rx_work < limit)) { @@ -2687,11 +2677,11 @@ static int nv_rx_process(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); - for (j=0; j<64; j++) { + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); + for (j = 0; j < 64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); + dprintk(" %02x", ((unsigned char *)skb->data)[j]); } dprintk("\n"); } @@ -2710,9 +2700,8 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX_ERROR_MASK) == NV_RX_FRAMINGERR) { - if (flags & NV_RX_SUBSTRACT1) { + if (flags & NV_RX_SUBSTRACT1) len--; - } } /* the rest are hard errors */ else { @@ -2745,9 +2734,8 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) { + if (flags & NV_RX2_SUBSTRACT1) len--; - } } /* the rest are hard errors */ else { @@ -2797,7 +2785,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) struct sk_buff *skb; int len; - while((np->get_rx.ex != np->put_rx.ex) && + while ((np->get_rx.ex != np->put_rx.ex) && !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && (rx_work < limit)) { @@ -2817,11 +2805,11 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); - for (j=0; j<64; j++) { + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); + for (j = 0; j < 64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); + dprintk(" %02x", ((unsigned char *)skb->data)[j]); } dprintk("\n"); } @@ -2838,9 +2826,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) { + if (flags & NV_RX2_SUBSTRACT1) len--; - } } /* the rest are hard errors */ else { @@ -2949,7 +2936,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) /* 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), + 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); @@ -2986,7 +2973,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev) static int nv_set_mac_address(struct net_device *dev, void *addr) { struct fe_priv *np = netdev_priv(dev); - struct sockaddr *macaddr = (struct sockaddr*)addr; + struct sockaddr *macaddr = (struct sockaddr *)addr; if (!is_valid_ether_addr(macaddr->sa_data)) return -EADDRNOTAVAIL; @@ -3302,7 +3289,7 @@ set_speed: } writel(txreg, base + NvRegTxWatermark); - writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), + writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); pci_push(base); writel(np->linkspeed, base + NvRegLinkSpeed); @@ -3312,8 +3299,8 @@ set_speed: /* setup pause frame */ if (np->duplex != 0) { 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); + 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: @@ -3324,22 +3311,17 @@ set_speed: } break; case ADVERTISE_PAUSE_ASYM: - if (lpa_pause == (LPA_PAUSE_CAP| LPA_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) - { + 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; } } else { @@ -3514,7 +3496,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); - for (i=0; ; i++) { + for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events); @@ -3553,7 +3535,7 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) u8 __iomem *base = get_hwbase(dev); unsigned long flags; int retcode; - int rx_count, tx_work=0, rx_work=0; + int rx_count, tx_work = 0, rx_work = 0; do { if (!nv_optimized(np)) { @@ -3628,7 +3610,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); - for (i=0; ; i++) { + for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); @@ -3675,7 +3657,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); - for (i=0; ; i++) { + for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); @@ -3776,17 +3758,15 @@ static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) * the remaining 8 interrupts. */ for (i = 0; i < 8; i++) { - if ((irqmask >> i) & 0x1) { + 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) { + if ((irqmask >> (i + 8)) & 0x1) msixmap |= vector << (i << 2); - } } writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); } @@ -3809,9 +3789,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } if (np->msi_flags & NV_MSI_X_CAPABLE) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { + 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) { @@ -3903,9 +3882,8 @@ static void nv_free_irq(struct net_device *dev) int i; if (np->msi_flags & NV_MSI_X_ENABLED) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { + 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 { @@ -3975,7 +3953,7 @@ static void nv_do_nic_poll(unsigned long data) /* 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), + 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); @@ -4105,7 +4083,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } if (netif_carrier_ok(dev)) { - switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) { + switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) { case NVREG_LINKSPEED_10: ecmd->speed = SPEED_10; break; @@ -4344,7 +4322,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); - for (i = 0;i <= np->register_size/sizeof(u32); i++) + for (i = 0; i <= np->register_size/sizeof(u32); i++) rbuf[i] = readl(base + i*sizeof(u32)); spin_unlock_irq(&np->lock); } @@ -4491,14 +4469,14 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri np->tx_ring_size = ring->tx_pending; if (!nv_optimized(np)) { - np->rx_ring.orig = (struct ring_desc*)rxtx_ring; + np->rx_ring.orig = (struct ring_desc *)rxtx_ring; np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size]; } else { - np->rx_ring.ex = (struct ring_desc_ex*)rxtx_ring; + np->rx_ring.ex = (struct ring_desc_ex *)rxtx_ring; np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } - np->rx_skb = (struct nv_skb_map*)rx_skbuff; - np->tx_skb = (struct nv_skb_map*)tx_skbuff; + np->rx_skb = (struct nv_skb_map *)rx_skbuff; + np->tx_skb = (struct nv_skb_map *)tx_skbuff; np->ring_addr = ring_addr; memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size); @@ -4515,7 +4493,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri /* 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), + 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); @@ -4841,7 +4819,7 @@ static int nv_loopback_test(struct net_device *dev) /* 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), + writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); @@ -4893,9 +4871,8 @@ static int nv_loopback_test(struct net_device *dev) if (flags & NV_RX_ERROR) ret = 0; } else { - if (flags & NV_RX2_ERROR) { + if (flags & NV_RX2_ERROR) ret = 0; - } } if (ret) { @@ -4958,11 +4935,10 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 netif_addr_lock(dev); spin_lock_irq(&np->lock); nv_disable_hw_interrupts(dev, np->irqmask); - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { + if (!(np->msi_flags & NV_MSI_X_ENABLED)) writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - } else { + else writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); - } /* stop engines */ nv_stop_rxtx(dev); nv_txrx_reset(dev); @@ -5003,7 +4979,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 /* 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), + 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); @@ -5106,8 +5082,7 @@ static int nv_mgmt_acquire_sema(struct net_device *dev) ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) { np->mgmt_sema = 1; return 1; - } - else + } else udelay(50); } @@ -5204,7 +5179,7 @@ static int nv_open(struct net_device *dev) /* give hw rings */ 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), + writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); writel(np->linkspeed, base + NvRegLinkSpeed); @@ -5251,8 +5226,7 @@ static int nv_open(struct net_device *dev) writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval); else writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval); - } - else + } else writel(poll_interval & 0xFFFF, base + NvRegPollingInterval); writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING, @@ -5263,7 +5237,7 @@ static int nv_open(struct net_device *dev) writel(NVREG_WAKEUPFLAGS_ENABLE , base + NvRegWakeUpFlags); i = readl(base + NvRegPowerState); - if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) + if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); pci_push(base); @@ -5276,9 +5250,8 @@ static int nv_open(struct net_device *dev) writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); - if (nv_request_irq(dev, 0)) { + if (nv_request_irq(dev, 0)) goto out_drain; - } /* ask for interrupts */ nv_enable_hw_interrupts(dev, np->irqmask); @@ -5466,7 +5439,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dprintk(KERN_DEBUG "%s: resource %d start %p len %ld flags 0x%08lx.\n", - pci_name(pci_dev), i, (void*)pci_resource_start(pci_dev, i), + pci_name(pci_dev), i, (void *)pci_resource_start(pci_dev, i), pci_resource_len(pci_dev, i), pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && @@ -5631,7 +5604,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i */ dev_printk(KERN_ERR, &pci_dev->dev, "Invalid Mac address detected: %pM\n", - dev->dev_addr); + dev->dev_addr); dev_printk(KERN_ERR, &pci_dev->dev, "Please complain to your hardware vendor. Switching to a random MAC.\n"); random_ether_addr(dev->dev_addr); @@ -5663,16 +5636,15 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i writel(powerstate, base + NvRegPowerState2); } - if (np->desc_ver == DESC_VER_1) { + if (np->desc_ver == DESC_VER_1) np->tx_flags = NV_TX_VALID; - } else { + else np->tx_flags = NV_TX2_VALID; - } np->msi_flags = 0; - if ((id->driver_data & DEV_HAS_MSI) && msi) { + if ((id->driver_data & DEV_HAS_MSI) && msi) np->msi_flags |= NV_MSI_CAPABLE; - } + if ((id->driver_data & DEV_HAS_MSI_X) && msix) { /* msix has had reported issues when modifying irqmask as in the case of napi, therefore, disable for now @@ -5735,9 +5707,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i nv_mgmt_acquire_sema(dev) && nv_mgmt_get_version(dev)) { np->mac_in_use = 1; - if (np->mgmt_version > 0) { + if (np->mgmt_version > 0) np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE; - } dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use); /* management unit setup the phy already? */ @@ -5799,9 +5770,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } else { /* see if it is a gigabit phy */ u32 mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); - if (mii_status & PHY_GIGABIT) { + if (mii_status & PHY_GIGABIT) np->gigabit = PHY_GIGABIT; - } } /* set default link speed settings */ @@ -5829,19 +5799,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[5]); dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", - dev->features & NETIF_F_HIGHDMA ? "highdma " : "", - dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? - "csum " : "", - dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? - "vlan " : "", - id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", - id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", - id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", - np->gigabit == PHY_GIGABIT ? "gbit " : "", - np->need_linktimer ? "lnktim " : "", - np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", - np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", - np->desc_ver); + dev->features & NETIF_F_HIGHDMA ? "highdma " : "", + dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? + "csum " : "", + dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? + "vlan " : "", + id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", + id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", + id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", + np->gigabit == PHY_GIGABIT ? "gbit " : "", + np->need_linktimer ? "lnktim " : "", + np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", + np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", + np->desc_ver); return 0; @@ -5931,13 +5901,13 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) int i; if (netif_running(dev)) { - // Gross. + /* Gross. */ nv_close(dev); } netif_device_detach(dev); /* save non-pci configuration space */ - for (i = 0;i <= np->register_size/sizeof(u32); i++) + for (i = 0; i <= np->register_size/sizeof(u32); i++) np->saved_config_space[i] = readl(base + i*sizeof(u32)); pci_save_state(pdev); @@ -5960,7 +5930,7 @@ static int nv_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D0, 0); /* restore non-pci configuration space */ - for (i = 0;i <= np->register_size/sizeof(u32); i++) + for (i = 0; i <= np->register_size/sizeof(u32); i++) writel(np->saved_config_space[i], base+i*sizeof(u32)); if (np->driver_data & DEV_NEED_MSI_FIX) @@ -5990,9 +5960,8 @@ static void nv_shutdown(struct pci_dev *pdev) * If we really go for poweroff, we must not restore the MAC, * otherwise the MAC for WOL will be reversed at least on some boards. */ - if (system_state != SYSTEM_POWER_OFF) { + if (system_state != SYSTEM_POWER_OFF) nv_restore_mac_addr(pdev); - } pci_disable_device(pdev); /* -- cgit v1.2.3-59-g8ed1b From 9b03b06b65856f70564c53654d44053f3072379e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 27 Nov 2010 08:39:44 +0000 Subject: forcedeth: remove unnecessary checks before kfree Signed-off-by: Szymon Janc Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 87757c89caef..81722fb51a36 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1013,10 +1013,8 @@ static void free_rings(struct net_device *dev) 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_skb) - kfree(np->rx_skb); - if (np->tx_skb) - kfree(np->tx_skb); + kfree(np->rx_skb); + kfree(np->tx_skb); } static int using_multi_irqs(struct net_device *dev) @@ -4442,10 +4440,9 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri 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 (tx_skbuff) - kfree(tx_skbuff); + + kfree(rx_skbuff); + kfree(tx_skbuff); goto exit; } -- cgit v1.2.3-59-g8ed1b From 5504e1397cc860e61fbb68c56e7a10db613275fd Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 27 Nov 2010 08:39:45 +0000 Subject: forcedeth: include and instead of and as suggested by checkpatch Signed-off-by: Szymon Janc Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 81722fb51a36..8deae909bbda 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -60,10 +60,10 @@ #include #include #include +#include +#include #include -#include -#include #include #if 0 -- cgit v1.2.3-59-g8ed1b From 34cf97eb255b09751f1eb1b5573813e9ea3fe21f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 27 Nov 2010 08:39:46 +0000 Subject: forcedeth: do not use assignment in if conditions Signed-off-by: Szymon Janc Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 8deae909bbda..2f092d75d78e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3789,7 +3789,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) 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) { + ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK)); + if (ret == 0) { np->msi_flags |= NV_MSI_X_ENABLED; if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) { /* Request irq for rx handling */ @@ -3841,7 +3842,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } } if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { - if ((ret = pci_enable_msi(np->pci_dev)) == 0) { + ret = pci_enable_msi(np->pci_dev); + if (ret == 0) { np->msi_flags |= NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { -- cgit v1.2.3-59-g8ed1b From de855b992d75e49816eb09231764e7a63a4f555d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 27 Nov 2010 08:39:48 +0000 Subject: forcedeth: use usleep_range not msleep for small sleeps Signed-off-by: Szymon Janc Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 2f092d75d78e..2fd1ae9e13b5 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1178,7 +1178,7 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup) /* must wait till reset is deasserted */ while (miicontrol & BMCR_RESET) { - msleep(10); + usleep_range(10000, 20000); miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); /* FIXME: 100 tries seem excessive */ if (tries++ > 100) -- cgit v1.2.3-59-g8ed1b From 5e9559689735f760f3a1fb9b2aafeb4d8efbf8f5 Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Sun, 28 Nov 2010 18:10:53 -0800 Subject: stmmac: fix stmmac_resume removing not yet used shutdown flag The commit to convert to use the dev_pm_ops struct introduces a bug. The shutdown flag is not yet used because the hibernation on memory is done by using the freeze callback. Thanks to Vlad for having reported it. Reported-by: Vlad Lungu Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index f1dbc182c8df..730a6fd79ee0 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1846,13 +1846,6 @@ static int stmmac_resume(struct device *dev) if (!netif_running(ndev)) return 0; - if (priv->shutdown) { - /* Re-open the interface and re-init the MAC/DMA - and the rings (i.e. on hibernation stage) */ - stmmac_open(dev); - return 0; - } - spin_lock(&priv->lock); /* Power Down bit, into the PM register, is cleared -- cgit v1.2.3-59-g8ed1b From f3aa3136d9c15ff693198eb34701a74bb0b6b969 Mon Sep 17 00:00:00 2001 From: Sachin Sant Date: Fri, 26 Nov 2010 02:41:17 +0000 Subject: qeth lcs: convert mc rwlock to RCU Commit 1d7138de878d1d4210727c1200193e69596f93b3 igmp: RCU conversion of in_dev->mc_list converted rwlock to RCU. Update the s390 network drivers(qeth & lcs) code to adapt to this change. V2 : Changes based on suggestions given by Eric Dumazet Signed-off-by: Sachin Sant Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/lcs.c | 10 ++++++---- drivers/s390/net/qeth_l3_main.c | 11 ++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0f19d540b655..c9f13b9ea339 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1188,7 +1188,8 @@ lcs_remove_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) spin_lock_irqsave(&card->ipm_lock, flags); list_for_each(l, &card->ipm_list) { ipm = list_entry(l, struct lcs_ipm_list, list); - for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); + im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); if ( (ipm->ipm.ip_addr == im4->multiaddr) && (memcmp(buf, &ipm->ipm.mac_addr, @@ -1233,7 +1234,8 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) unsigned long flags; LCS_DBF_TEXT(4, trace, "setmclst"); - for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; + im4 = rcu_dereference(im4->next_rcu)) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); ipm = lcs_check_addr_entry(card, im4, buf); if (ipm != NULL) @@ -1269,10 +1271,10 @@ lcs_register_mc_addresses(void *data) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) goto out; - read_lock(&in4_dev->mc_list_lock); + rcu_read_lock(); lcs_remove_mc_addresses(card,in4_dev); lcs_set_mc_addresses(card, in4_dev); - read_unlock(&in4_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in4_dev); netif_carrier_off(card->dev); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 74d1401a5d5e..65291db324f5 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1796,7 +1796,8 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) char buf[MAX_ADDR_LEN]; QETH_CARD_TEXT(card, 4, "addmc"); - for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; + im4 = rcu_dereference(im4->next_rcu)) { qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev); ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (!ipm) @@ -1828,9 +1829,9 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) in_dev = in_dev_get(netdev); if (!in_dev) continue; - read_lock(&in_dev->mc_list_lock); + rcu_read_lock(); qeth_l3_add_mc(card, in_dev); - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in_dev); } } @@ -1843,10 +1844,10 @@ static void qeth_l3_add_multicast_ipv4(struct qeth_card *card) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) return; - read_lock(&in4_dev->mc_list_lock); + rcu_read_lock(); qeth_l3_add_mc(card, in4_dev); qeth_l3_add_vlan_mc(card); - read_unlock(&in4_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in4_dev); } -- cgit v1.2.3-59-g8ed1b From cdac082e051136a021f28d0f63c56e916b541253 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 26 Nov 2010 02:41:18 +0000 Subject: drivers/s390/net: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 42fa783a70c8..b5e967cf7e2d 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -372,7 +372,7 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, i = simple_strtoul(buf, &tmp, 16); if ((i == 0) || (i == 1)) { if (i == card->options.performance_stats) - goto out;; + goto out; card->options.performance_stats = i; if (i == 0) memset(&card->perf_stats, 0, -- cgit v1.2.3-59-g8ed1b From 2b6203bb7d85e6a2ca2088b8684f30be70246ddf Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Fri, 26 Nov 2010 02:41:19 +0000 Subject: qeth: enable interface setup if LAN is offline Device initialization of a qeth device contains a STARTLAN step. This step may fail, if cable is not yet plugged in. The qeth device stays in state HARDSETUP until cable is plugged in. This prevents further preparational initialization steps of the qeth device and its network interface. This patch makes sure initialization of qeth device continues, even though cable is not yet plugged in. Once carrier is available, qeth is notified, triggers a recovery which results in a working network interface. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 11 ++++++----- drivers/s390/net/qeth_l3_main.c | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 847e8797073c..7a7a1b664781 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -849,8 +849,6 @@ static int qeth_l2_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); - if (!card->lan_online && netif_carrier_ok(dev)) - netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -1013,13 +1011,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto out; + goto contin; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; +contin: if ((card->info.type == QETH_CARD_TYPE_OSD) || (card->info.type == QETH_CARD_TYPE_OSX)) /* configure isolation level */ @@ -1038,7 +1037,10 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; - netif_carrier_on(card->dev); + if (card->lan_online) + netif_carrier_on(card->dev); + else + netif_carrier_off(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); if (recover_flag == CARD_STATE_RECOVER) { @@ -1055,7 +1057,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); -out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 65291db324f5..3ddd5add7984 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3177,8 +3177,6 @@ static int qeth_l3_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); - if (!card->lan_online && netif_carrier_ok(dev)) - netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -3450,13 +3448,14 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto out; + goto contin; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; +contin: rc = qeth_l3_setadapter_parms(card); if (rc) QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); @@ -3481,10 +3480,13 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; - netif_carrier_on(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_l3_set_ip_addr_list(card); + if (card->lan_online) + netif_carrier_on(card->dev); + else + netif_carrier_off(card->dev); if (recover_flag == CARD_STATE_RECOVER) { if (recovery_mode) qeth_l3_open(card->dev); @@ -3497,7 +3499,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); -out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; -- cgit v1.2.3-59-g8ed1b From 8fa9208e305e24978b897d6ea057604444ce77e1 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Fri, 26 Nov 2010 02:41:20 +0000 Subject: qeth: l3 fix len in tso hdr The tso hdr is longer then the regular l3 hdr. Fix the calculation of the total len by accounting the size of the tso hdr. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3ddd5add7984..a1abb37db000 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2939,6 +2939,7 @@ static void qeth_tso_fill_header(struct qeth_card *card, /*fix header to TSO values ...*/ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; + hdr->hdr.hdr.l3.length = skb->len - sizeof(struct qeth_hdr_tso); /*set values which are fix for the first approach ...*/ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); hdr->ext.imb_hdr_no = 1; -- cgit v1.2.3-59-g8ed1b From bf26414510103448ad3dc069c7422462f03ea3d7 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Fri, 26 Nov 2010 08:36:09 +0000 Subject: xps: Add CONFIG_XPS This patch adds XPS_CONFIG option to enable and disable XPS. This is done in the same manner as RPS_CONFIG. This is also fixes build failure in XPS code when SMP is not enabled. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/netdevice.h | 52 +++++++++++++++++++++++++---------------------- net/Kconfig | 5 +++++ net/core/dev.c | 9 +++++--- net/core/net-sysfs.c | 47 ++++++++++++++++++++++++++++++------------ net/core/net-sysfs.h | 3 --- 5 files changed, 73 insertions(+), 43 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7c6ae2f4b9ab..9ae4544f0cf0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -535,30 +535,6 @@ struct rps_map { }; #define RPS_MAP_SIZE(_num) (sizeof(struct rps_map) + (_num * sizeof(u16))) -/* - * This structure holds an XPS map which can be of variable length. The - * map is an array of queues. - */ -struct xps_map { - unsigned int len; - unsigned int alloc_len; - struct rcu_head rcu; - u16 queues[0]; -}; -#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) -#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ - / sizeof(u16)) - -/* - * This structure holds all XPS maps for device. Maps are indexed by CPU. - */ -struct xps_dev_maps { - struct rcu_head rcu; - struct xps_map *cpu_map[0]; -}; -#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ - (nr_cpu_ids * sizeof(struct xps_map *))) - /* * The rps_dev_flow structure contains the mapping of a flow to a CPU and the * tail pointer for that CPU's input queue at the time of last enqueue. @@ -626,6 +602,32 @@ struct netdev_rx_queue { } ____cacheline_aligned_in_smp; #endif /* CONFIG_RPS */ +#ifdef CONFIG_XPS +/* + * This structure holds an XPS map which can be of variable length. The + * map is an array of queues. + */ +struct xps_map { + unsigned int len; + unsigned int alloc_len; + struct rcu_head rcu; + u16 queues[0]; +}; +#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) +#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ + / sizeof(u16)) + +/* + * This structure holds all XPS maps for device. Maps are indexed by CPU. + */ +struct xps_dev_maps { + struct rcu_head rcu; + struct xps_map *cpu_map[0]; +}; +#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ + (nr_cpu_ids * sizeof(struct xps_map *))) +#endif /* CONFIG_XPS */ + /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -1046,7 +1048,9 @@ struct net_device { unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; +#ifdef CONFIG_XPS struct xps_dev_maps *xps_maps; +#endif /* These may be needed for future network-power-down code. */ diff --git a/net/Kconfig b/net/Kconfig index 55fd82e9ffd9..126c2af0fc1f 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -220,6 +220,11 @@ config RPS depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS default y +config XPS + boolean + depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS + default y + menu "Network testing" config NET_PKTGEN diff --git a/net/core/dev.c b/net/core/dev.c index c852f0038a08..3259d2c323a6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1567,6 +1567,9 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, txq); + if (rc) + return rc; + if (txq < dev->real_num_tx_queues) qdisc_reset_all_tx_gt(dev, txq); } @@ -2148,7 +2151,7 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) { -#ifdef CONFIG_RPS +#ifdef CONFIG_XPS struct xps_dev_maps *dev_maps; struct xps_map *map; int queue_index = -1; @@ -5085,9 +5088,9 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev, } EXPORT_SYMBOL(netif_stacked_transfer_operstate); +#ifdef CONFIG_RPS static int netif_alloc_rx_queues(struct net_device *dev) { -#ifdef CONFIG_RPS unsigned int i, count = dev->num_rx_queues; struct netdev_rx_queue *rx; @@ -5102,9 +5105,9 @@ static int netif_alloc_rx_queues(struct net_device *dev) for (i = 0; i < count; i++) rx[i].dev = dev; -#endif return 0; } +#endif static int netif_alloc_netdev_queues(struct net_device *dev) { diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 68dbbfdee274..99c11294623f 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -751,10 +751,12 @@ static int rx_queue_add_kobject(struct net_device *net, int index) return error; } +#endif /* CONFIG_RPS */ int net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) { +#ifdef CONFIG_RPS int i; int error = 0; @@ -770,8 +772,12 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) kobject_put(&net->_rx[i].kobj); return error; +#else + return 0; +#endif } +#ifdef CONFIG_XPS /* * netdev_queue sysfs structures and functions. */ @@ -1090,10 +1096,12 @@ static int netdev_queue_add_kobject(struct net_device *net, int index) return error; } +#endif /* CONFIG_XPS */ int netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) { +#ifdef CONFIG_XPS int i; int error = 0; @@ -1109,27 +1117,36 @@ netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) kobject_put(&net->_tx[i].kobj); return error; +#else + return 0; +#endif } static int register_queue_kobjects(struct net_device *net) { - int error = 0, txq = 0, rxq = 0; + int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) net->queues_kset = kset_create_and_add("queues", NULL, &net->dev.kobj); if (!net->queues_kset) return -ENOMEM; +#endif + +#ifdef CONFIG_RPS + real_rx = net->real_num_rx_queues; +#endif + real_tx = net->real_num_tx_queues; - error = net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); + error = net_rx_queue_update_kobjects(net, 0, real_rx); if (error) goto error; - rxq = net->real_num_rx_queues; + rxq = real_rx; - error = netdev_queue_update_kobjects(net, 0, - net->real_num_tx_queues); + error = netdev_queue_update_kobjects(net, 0, real_tx); if (error) goto error; - txq = net->real_num_tx_queues; + txq = real_tx; return 0; @@ -1141,11 +1158,19 @@ error: static void remove_queue_kobjects(struct net_device *net) { - net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); - netdev_queue_update_kobjects(net, net->real_num_tx_queues, 0); + int real_rx = 0, real_tx = 0; + +#ifdef CONFIG_RPS + real_rx = net->real_num_rx_queues; +#endif + real_tx = net->real_num_tx_queues; + + net_rx_queue_update_kobjects(net, real_rx, 0); + netdev_queue_update_kobjects(net, real_tx, 0); +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) kset_unregister(net->queues_kset); +#endif } -#endif /* CONFIG_RPS */ static const void *net_current_ns(void) { @@ -1244,9 +1269,7 @@ void netdev_unregister_kobject(struct net_device * net) kobject_get(&dev->kobj); -#ifdef CONFIG_RPS remove_queue_kobjects(net); -#endif device_del(dev); } @@ -1285,13 +1308,11 @@ int netdev_register_kobject(struct net_device *net) if (error) return error; -#ifdef CONFIG_RPS error = register_queue_kobjects(net); if (error) { device_del(dev); return error; } -#endif return error; } diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h index 25ec2ee57df7..bd7751ec1c4d 100644 --- a/net/core/net-sysfs.h +++ b/net/core/net-sysfs.h @@ -4,11 +4,8 @@ int netdev_kobject_init(void); int netdev_register_kobject(struct net_device *); void netdev_unregister_kobject(struct net_device *); -#ifdef CONFIG_RPS int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); int netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num); #endif - -#endif -- cgit v1.2.3-59-g8ed1b From e9248fbd6b6f7ef1917bfffe998654e40dfb4cfd Mon Sep 17 00:00:00 2001 From: "Scott J. Goldman" Date: Sat, 27 Nov 2010 10:33:55 +0000 Subject: vmxnet3: fix compilation when RSS is disabled If RSS is disabled, we can ifdef out some RSS specific code. This fixes the compile error found by Randy Dunlap. Signed-off-by: Scott J. Goldman Reviewed-by: Bhavesh Davda Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_ethtool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 9ddaea636cfa..8e17fc8a7fe7 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -553,7 +553,7 @@ vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info, return -EOPNOTSUPP; } - +#ifdef VMXNET3_RSS static int vmxnet3_get_rss_indir(struct net_device *netdev, struct ethtool_rxfh_indir *p) @@ -598,6 +598,7 @@ vmxnet3_set_rss_indir(struct net_device *netdev, return 0; } +#endif static struct ethtool_ops vmxnet3_ethtool_ops = { .get_settings = vmxnet3_get_settings, @@ -623,8 +624,10 @@ static struct ethtool_ops vmxnet3_ethtool_ops = { .get_ringparam = vmxnet3_get_ringparam, .set_ringparam = vmxnet3_set_ringparam, .get_rxnfc = vmxnet3_get_rxnfc, +#ifdef VMXNET3_RSS .get_rxfh_indir = vmxnet3_get_rss_indir, .set_rxfh_indir = vmxnet3_set_rss_indir, +#endif }; void vmxnet3_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.3-59-g8ed1b From 49b4a6546fac02f58784f0744e0f99a6562ccc03 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Mon, 29 Nov 2010 00:14:58 +0000 Subject: sctp: kill unused macros in head file 1. SCTP_CMD_NUM_VERBS,SCTP_CMD_MAX These two macros have never been used for several years since v2.6.12-rc2. 2.sctp_port_rover,sctp_port_alloc_lock The commit 063930 abandoned global variables of port_rover and port_alloc_lock, but still keep two macros to refer to them. So, remove them now. commit 06393009000779b00a558fd2f280882cc7dc2008 Author: Stephen Hemminger Date: Wed Oct 10 17:30:18 2007 -0700 [SCTP]: port randomization Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- include/net/sctp/command.h | 3 --- include/net/sctp/structs.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 2c55a7ea20af..c01dc99def07 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -111,9 +111,6 @@ typedef enum { SCTP_CMD_LAST } sctp_verb_t; -#define SCTP_CMD_MAX (SCTP_CMD_LAST - 1) -#define SCTP_CMD_NUM_VERBS (SCTP_CMD_MAX + 1) - /* How many commands can you put in an sctp_cmd_seq_t? * This is a rather arbitrary number, ideally derived from a careful * analysis of the state functions, but in reality just taken from diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 69fef4fb79c0..cc9185ca8fd1 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -261,8 +261,6 @@ extern struct sctp_globals { #define sctp_assoc_hashsize (sctp_globals.assoc_hashsize) #define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) #define sctp_port_hashsize (sctp_globals.port_hashsize) -#define sctp_port_rover (sctp_globals.port_rover) -#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock) #define sctp_port_hashtable (sctp_globals.port_hashtable) #define sctp_local_addr_list (sctp_globals.local_addr_list) #define sctp_local_addr_lock (sctp_globals.addr_list_lock) -- cgit v1.2.3-59-g8ed1b From b02038a17b271e0f70616c54e4eccb5cc33d1b74 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 28 Nov 2010 05:43:24 +0000 Subject: xps: NUMA allocations for per cpu data store_xps_map() allocates maps that are used by single cpu, it makes sense to use NUMA allocations. Signed-off-by: Eric Dumazet Cc: Tom Herbert Signed-off-by: David S. Miller --- net/core/net-sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 99c11294623f..35ef42fa0cf3 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -956,8 +956,9 @@ static ssize_t store_xps_map(struct netdev_queue *queue, if (map_len >= alloc_len) { alloc_len = alloc_len ? 2 * alloc_len : XPS_MIN_MAP_ALLOC; - new_map = kzalloc(XPS_MAP_SIZE(alloc_len), - GFP_KERNEL); + new_map = kzalloc_node(XPS_MAP_SIZE(alloc_len), + GFP_KERNEL, + cpu_to_node(cpu)); if (!new_map) goto error; new_map->alloc_len = alloc_len; -- cgit v1.2.3-59-g8ed1b From a41778694806ac1ccd4b1dafed1abef8d5ba98ac Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 28 Nov 2010 21:43:02 +0000 Subject: xps: add __rcu annotations Avoid sparse warnings : add __rcu annotations and use rcu_dereference_protected() where necessary. Signed-off-by: Eric Dumazet Cc: Tom Herbert Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++-- net/core/net-sysfs.c | 24 +++++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9ae4544f0cf0..4b0c7f3aa32b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -622,7 +622,7 @@ struct xps_map { */ struct xps_dev_maps { struct rcu_head rcu; - struct xps_map *cpu_map[0]; + struct xps_map __rcu *cpu_map[0]; }; #define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ (nr_cpu_ids * sizeof(struct xps_map *))) @@ -1049,7 +1049,7 @@ struct net_device { spinlock_t tx_global_lock; #ifdef CONFIG_XPS - struct xps_dev_maps *xps_maps; + struct xps_dev_maps __rcu *xps_maps; #endif /* These may be needed for future network-power-down code. */ diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 35ef42fa0cf3..f85cee3d869e 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -899,6 +899,8 @@ static void xps_dev_maps_release(struct rcu_head *rcu) } static DEFINE_MUTEX(xps_map_mutex); +#define xmap_dereference(P) \ + rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex)) static ssize_t store_xps_map(struct netdev_queue *queue, struct netdev_queue_attribute *attribute, @@ -935,11 +937,12 @@ static ssize_t store_xps_map(struct netdev_queue *queue, mutex_lock(&xps_map_mutex); - dev_maps = dev->xps_maps; + dev_maps = xmap_dereference(dev->xps_maps); for_each_possible_cpu(cpu) { - new_map = map = dev_maps ? dev_maps->cpu_map[cpu] : NULL; - + map = dev_maps ? + xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; + new_map = map; if (map) { for (pos = 0; pos < map->len; pos++) if (map->queues[pos] == index) @@ -975,13 +978,14 @@ static ssize_t store_xps_map(struct netdev_queue *queue, else new_map = NULL; } - new_dev_maps->cpu_map[cpu] = new_map; + RCU_INIT_POINTER(new_dev_maps->cpu_map[cpu], new_map); } /* Cleanup old maps */ for_each_possible_cpu(cpu) { - map = dev_maps ? dev_maps->cpu_map[cpu] : NULL; - if (map && new_dev_maps->cpu_map[cpu] != map) + map = dev_maps ? + xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; + if (map && xmap_dereference(new_dev_maps->cpu_map[cpu]) != map) call_rcu(&map->rcu, xps_map_release); if (new_dev_maps->cpu_map[cpu]) nonempty = 1; @@ -1007,7 +1011,9 @@ error: if (new_dev_maps) for_each_possible_cpu(i) - kfree(new_dev_maps->cpu_map[i]); + kfree(rcu_dereference_protected( + new_dev_maps->cpu_map[i], + 1)); kfree(new_dev_maps); free_cpumask_var(mask); return -ENOMEM; @@ -1033,11 +1039,11 @@ static void netdev_queue_release(struct kobject *kobj) index = get_netdev_queue_index(queue); mutex_lock(&xps_map_mutex); - dev_maps = dev->xps_maps; + dev_maps = xmap_dereference(dev->xps_maps); if (dev_maps) { for_each_possible_cpu(i) { - map = dev_maps->cpu_map[i]; + map = xmap_dereference(dev_maps->cpu_map[i]); if (!map) continue; -- cgit v1.2.3-59-g8ed1b From 344d0dce5164d0bf2d73cf10510fe08ed8cf8248 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:52 +0000 Subject: forcedeth: Change reg_delay arguments and use Move the printk out of reg_delay and make the callers emit a message on error. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 2fd1ae9e13b5..e5f9d4b5ee05 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -948,7 +948,7 @@ static bool nv_optimized(struct fe_priv *np) } static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, - int delay, int delaymax, const char *msg) + int delay, int delaymax) { u8 __iomem *base = get_hwbase(dev); @@ -956,11 +956,8 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, do { udelay(delay); delaymax -= delay; - if (delaymax < 0) { - if (msg) - printk("%s", msg); + if (delaymax < 0) return 1; - } } while ((readl(base + offset) & mask) != target); return 0; } @@ -1141,9 +1138,9 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value) writel(reg, base + NvRegMIIControl); if (reg_delay(dev, NvRegMIIControl, NVREG_MIICTL_INUSE, 0, - NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) { + NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX)) { dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d timed out.\n", - dev->name, miireg, addr); + dev->name, miireg, addr); retval = -1; } else if (value != MII_READ) { /* it was a write operation - fewer failures are detectable */ @@ -1539,9 +1536,9 @@ static void nv_stop_rx(struct net_device *dev) else rx_ctrl |= NVREG_RCVCTL_RX_PATH_EN; writel(rx_ctrl, base + NvRegReceiverControl); - reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, - NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); + if (reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, + NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX)) + printk(KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); udelay(NV_RXSTOP_DELAY2); if (!np->mac_in_use) @@ -1574,9 +1571,9 @@ static void nv_stop_tx(struct net_device *dev) else tx_ctrl |= NVREG_XMITCTL_TX_PATH_EN; writel(tx_ctrl, base + NvRegTransmitterControl); - reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, - NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); + if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, + NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX)) + printk(KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); if (!np->mac_in_use) @@ -5190,9 +5187,10 @@ static int nv_open(struct net_device *dev) writel(np->vlanctl_bits, base + NvRegVlanControl); pci_push(base); writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl); - reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, - NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, - KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); + if (reg_delay(dev, NvRegUnknownSetupReg5, + NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, + NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX)) + printk(KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); writel(0, base + NvRegMIIMask); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); -- cgit v1.2.3-59-g8ed1b From 6b80858d2c0a378894b9df35d3703d62b0b12dbc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:53 +0000 Subject: forcedeth: convert dprintk(KERN_DEBUG to netdev_dbg Use the more standard macro to preface netdev->name. Fix casting on resource use. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 176 ++++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index e5f9d4b5ee05..767d1eb87c94 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1139,22 +1139,22 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value) if (reg_delay(dev, NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX)) { - dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d timed out.\n", - dev->name, miireg, addr); + netdev_dbg(dev, "mii_rw of reg %d at PHY %d timed out\n", + miireg, addr); retval = -1; } else if (value != MII_READ) { /* it was a write operation - fewer failures are detectable */ - dprintk(KERN_DEBUG "%s: mii_rw wrote 0x%x to reg %d at PHY %d\n", - dev->name, value, miireg, addr); + netdev_dbg(dev, "mii_rw wrote 0x%x to reg %d at PHY %d\n", + value, miireg, addr); retval = 0; } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) { - dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d failed.\n", - dev->name, miireg, addr); + netdev_dbg(dev, "mii_rw of reg %d at PHY %d failed\n", + miireg, addr); retval = -1; } else { retval = readl(base + NvRegMIIData); - dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n", - dev->name, miireg, addr, retval); + netdev_dbg(dev, "mii_rw read from reg %d at PHY %d: 0x%x\n", + miireg, addr, retval); } return retval; @@ -1506,7 +1506,7 @@ static void nv_start_rx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 rx_ctrl = readl(base + NvRegReceiverControl); - dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); /* Already running? Stop it. */ if ((readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) && !np->mac_in_use) { rx_ctrl &= ~NVREG_RCVCTL_START; @@ -1519,8 +1519,8 @@ static void nv_start_rx(struct net_device *dev) if (np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN; writel(rx_ctrl, base + NvRegReceiverControl); - dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", - dev->name, np->duplex, np->linkspeed); + netdev_dbg(dev, "%s: duplex %d, speed 0x%08x\n", + __func__, np->duplex, np->linkspeed); pci_push(base); } @@ -1530,7 +1530,7 @@ static void nv_stop_rx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 rx_ctrl = readl(base + NvRegReceiverControl); - dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); if (!np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_START; else @@ -1551,7 +1551,7 @@ static void nv_start_tx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 tx_ctrl = readl(base + NvRegTransmitterControl); - dprintk(KERN_DEBUG "%s: nv_start_tx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); tx_ctrl |= NVREG_XMITCTL_START; if (np->mac_in_use) tx_ctrl &= ~NVREG_XMITCTL_TX_PATH_EN; @@ -1565,7 +1565,7 @@ static void nv_stop_tx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 tx_ctrl = readl(base + NvRegTransmitterControl); - dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); if (!np->mac_in_use) tx_ctrl &= ~NVREG_XMITCTL_START; else @@ -1598,7 +1598,7 @@ static void nv_txrx_reset(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); @@ -1612,7 +1612,7 @@ static void nv_mac_reset(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 temp1, temp2, temp3; - dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); @@ -2190,8 +2190,8 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&np->lock, flags); - dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n", - dev->name, entries, tx_flags_extra); + netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", + __func__, entries, tx_flags_extra); { int j; for (j = 0; j < 64; j++) { @@ -2341,8 +2341,8 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, spin_unlock_irqrestore(&np->lock, flags); - dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n", - dev->name, entries, tx_flags_extra); + netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", + __func__, entries, tx_flags_extra); { int j; for (j = 0; j < 64; j++) { @@ -2391,8 +2391,7 @@ static int nv_tx_done(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) && (tx_work < limit)) { - dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n", - dev->name, flags); + netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); nv_unmap_txskb(np, np->get_tx_ctx); @@ -2456,8 +2455,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) && (tx_work < limit)) { - dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n", - dev->name, flags); + netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); nv_unmap_txskb(np, np->get_tx_ctx); @@ -2608,8 +2606,8 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) protolen = ntohs(((struct ethhdr *)packet)->h_proto); hdrlen = ETH_HLEN; } - dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n", - dev->name, datalen, protolen, hdrlen); + netdev_dbg(dev, "%s: datalen %d, protolen %d, hdrlen %d\n", + __func__, datalen, protolen, hdrlen); if (protolen > ETH_DATA_LEN) return datalen; /* Value in proto field not a len, no checks possible */ @@ -2620,26 +2618,25 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) /* more data on wire than in 802 header, trim of * additional data. */ - dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", - dev->name, protolen); + netdev_dbg(dev, "%s: accepting %d bytes\n", + __func__, protolen); return protolen; } else { /* less data on wire than mentioned in header. * Discard the packet. */ - dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n", - dev->name); + netdev_dbg(dev, "%s: discarding long packet\n", + __func__); return -1; } } else { /* short packet. Accept only if 802 values are also short */ if (protolen > ETH_ZLEN) { - dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n", - dev->name); + netdev_dbg(dev, "%s: discarding short packet\n", + __func__); return -1; } - dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", - dev->name, datalen); + netdev_dbg(dev, "%s: accepting %d bytes\n", __func__, datalen); return datalen; } } @@ -2656,8 +2653,7 @@ static int nv_rx_process(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) && (rx_work < limit)) { - dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n", - dev->name, flags); + netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); /* * the packet is for us - immediately tear down the pci mapping. @@ -2672,9 +2668,9 @@ static int nv_rx_process(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); + netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); for (j = 0; j < 64; j++) { - if ((j%16) == 0) + if ((j%16) == 0 && j) dprintk("\n%03x:", j); dprintk(" %02x", ((unsigned char *)skb->data)[j]); } @@ -2754,8 +2750,8 @@ static int nv_rx_process(struct net_device *dev, int limit) /* got a valid packet - forward it to the network core */ skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); - dprintk(KERN_DEBUG "%s: nv_rx_process: %d bytes, proto %d accepted.\n", - dev->name, len, skb->protocol); + netdev_dbg(dev, "%s: %d bytes, proto %d accepted\n", + __func__, len, skb->protocol); napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -2784,8 +2780,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && (rx_work < limit)) { - dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n", - dev->name, flags); + netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); /* * the packet is for us - immediately tear down the pci mapping. @@ -2800,9 +2795,9 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); + netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); for (j = 0; j < 64; j++) { - if ((j%16) == 0) + if ((j%16) == 0 && j) dprintk("\n%03x:", j); dprintk(" %02x", ((unsigned char *)skb->data)[j]); } @@ -2840,8 +2835,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); prefetch(skb->data); - dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: %d bytes, proto %d accepted.\n", - dev->name, len, skb->protocol); + netdev_dbg(dev, "%s: %d bytes, proto %d accepted\n", + __func__, len, skb->protocol); if (likely(!np->vlangrp)) { napi_gro_receive(&np->napi, skb); @@ -3134,8 +3129,8 @@ static int nv_update_linkspeed(struct net_device *dev) mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); if (!(mii_status & BMSR_LSTATUS)) { - dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n", - dev->name); + netdev_dbg(dev, + "no link detected by phy - falling back to 10HD\n"); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; retval = 0; @@ -3143,8 +3138,8 @@ static int nv_update_linkspeed(struct net_device *dev) } if (np->autoneg == 0) { - dprintk(KERN_DEBUG "%s: nv_update_linkspeed: autoneg off, PHY set to 0x%04x.\n", - dev->name, np->fixed_mode); + netdev_dbg(dev, "%s: autoneg off, PHY set to 0x%04x\n", + __func__, np->fixed_mode); if (np->fixed_mode & LPA_100FULL) { newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; newdup = 1; @@ -3167,14 +3162,15 @@ static int nv_update_linkspeed(struct net_device *dev) newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; retval = 0; - dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name); + netdev_dbg(dev, + "autoneg not completed - falling back to 10HD\n"); 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); + netdev_dbg(dev, "%s: PHY advertises 0x%04x, lpa 0x%04x\n", + __func__, adv, lpa); retval = 1; if (np->gigabit == PHY_GIGABIT) { @@ -3183,8 +3179,8 @@ static int nv_update_linkspeed(struct net_device *dev) if ((control_1000 & ADVERTISE_1000FULL) && (status_1000 & LPA_1000FULL)) { - dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n", - dev->name); + netdev_dbg(dev, "%s: GBit ethernet detected\n", + __func__); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000; newdup = 1; goto set_speed; @@ -3206,7 +3202,8 @@ static int nv_update_linkspeed(struct net_device *dev) newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } else { - dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, adv_lpa); + netdev_dbg(dev, "bad ability %04x - falling back to 10HD\n", + adv_lpa); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } @@ -3363,7 +3360,7 @@ static void nv_link_irq(struct net_device *dev) if (miistat & (NVREG_MIISTAT_LINKCHANGE)) nv_linkchange(dev); - dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); + netdev_dbg(dev, "link change notification done\n"); } static void nv_msi_workaround(struct fe_priv *np) @@ -3414,7 +3411,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); if (!(np->msi_flags & NV_MSI_X_ENABLED)) { np->events = readl(base + NvRegIrqStatus); @@ -3423,7 +3420,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data) np->events = readl(base + NvRegMSIXIrqStatus); writel(np->events, base + NvRegMSIXIrqStatus); } - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); + netdev_dbg(dev, "irq: %08x\n", np->events); if (!(np->events & np->irqmask)) return IRQ_NONE; @@ -3437,7 +3434,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data) __napi_schedule(&np->napi); } - dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_HANDLED; } @@ -3453,7 +3450,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); if (!(np->msi_flags & NV_MSI_X_ENABLED)) { np->events = readl(base + NvRegIrqStatus); @@ -3462,7 +3459,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) np->events = readl(base + NvRegMSIXIrqStatus); writel(np->events, base + NvRegMSIXIrqStatus); } - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); + netdev_dbg(dev, "irq: %08x\n", np->events); if (!(np->events & np->irqmask)) return IRQ_NONE; @@ -3475,7 +3472,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) writel(0, base + NvRegIrqMask); __napi_schedule(&np->napi); } - dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_HANDLED; } @@ -3489,12 +3486,12 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) int i; unsigned long flags; - dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); - dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events); + netdev_dbg(dev, "tx irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3518,7 +3515,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) } } - dprintk(KERN_DEBUG "%s: nv_nic_irq_tx completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3603,12 +3600,12 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) int i; unsigned long flags; - dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); - dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); + netdev_dbg(dev, "rx irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3636,7 +3633,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) break; } } - dprintk(KERN_DEBUG "%s: nv_nic_irq_rx completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3650,12 +3647,12 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) int i; unsigned long flags; - dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); + netdev_dbg(dev, "irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3705,7 +3702,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) } } - dprintk(KERN_DEBUG "%s: nv_nic_irq_other completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3717,7 +3714,7 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) u8 __iomem *base = get_hwbase(dev); u32 events; - dprintk(KERN_DEBUG "%s: nv_nic_irq_test\n", dev->name); + netdev_dbg(dev, "%s\n", __func__); if (!(np->msi_flags & NV_MSI_X_ENABLED)) { events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; @@ -3727,7 +3724,7 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); } pci_push(base); - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); + netdev_dbg(dev, "irq: %08x\n", events); if (!(events & NVREG_IRQ_TIMER)) return IRQ_RETVAL(0); @@ -3737,7 +3734,7 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) np->intr_test = 1; spin_unlock(&np->lock); - dprintk(KERN_DEBUG "%s: nv_nic_irq_test completed\n", dev->name); + netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(1); } @@ -4874,21 +4871,21 @@ static int nv_loopback_test(struct net_device *dev) if (ret) { if (len != pkt_len) { ret = 0; - dprintk(KERN_DEBUG "%s: loopback len mismatch %d vs %d\n", - dev->name, len, pkt_len); + netdev_dbg(dev, "loopback len mismatch %d vs %d\n", + len, pkt_len); } else { rx_skb = np->rx_skb[0].skb; 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); + netdev_dbg(dev, "loopback pattern check failed on byte %d\n", + i); break; } } } } else { - dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name); + netdev_dbg(dev, "loopback - did not receive test packet\n"); } pci_unmap_single(np->pci_dev, test_dma_addr, @@ -5138,7 +5135,7 @@ static int nv_open(struct net_device *dev) int oom, i; u32 low; - dprintk(KERN_DEBUG "nv_open: begin\n"); + netdev_dbg(dev, "%s\n", __func__); /* power up phy */ mii_rw(dev, np->phyaddr, MII_BMCR, @@ -5435,10 +5432,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i err = -EINVAL; addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - dprintk(KERN_DEBUG "%s: resource %d start %p len %ld flags 0x%08lx.\n", - pci_name(pci_dev), i, (void *)pci_resource_start(pci_dev, i), - pci_resource_len(pci_dev, i), - pci_resource_flags(pci_dev, i)); + netdev_dbg(dev, "%s: resource %d start %p len %lld flags 0x%08lx\n", + pci_name(pci_dev), i, + (void *)(unsigned long)pci_resource_start(pci_dev, i), + (long long)pci_resource_len(pci_dev, i), + pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && pci_resource_len(pci_dev, i) >= np->register_size) { addr = pci_resource_start(pci_dev, i); @@ -5607,8 +5605,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i random_ether_addr(dev->dev_addr); } - dprintk(KERN_DEBUG "%s: MAC Address %pM\n", - pci_name(pci_dev), dev->dev_addr); + netdev_dbg(dev, "%s: MAC Address %pM\n", + pci_name(pci_dev), dev->dev_addr); /* set mac address */ nv_copy_mac_to_hw(dev); @@ -5741,8 +5739,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->phy_model = id2 & PHYID2_MODEL_MASK; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; - dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", - pci_name(pci_dev), id1, id2, phyaddr); + netdev_dbg(dev, "%s: %s: Found PHY %04x:%04x at address %d\n", + pci_name(pci_dev), __func__, id1, id2, phyaddr); np->phyaddr = phyaddr; np->phy_oui = id1 | id2; -- cgit v1.2.3-59-g8ed1b From e649985b4ab1e86b3a389cf0d7c48f9cb1e27ae6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:54 +0000 Subject: forcedeth: Use print_hex_dump Use the standard code to emit hex dumps. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 54 ++++++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 767d1eb87c94..1ac8b4e87276 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2192,15 +2192,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", __func__, entries, tx_flags_extra); - { - int j; - for (j = 0; j < 64; j++) { - if ((j%16) == 0) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); - } - dprintk("\n"); - } +#ifdef DEBUG + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, + skb->data, 64, true); +#endif writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); return NETDEV_TX_OK; @@ -2343,15 +2338,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", __func__, entries, tx_flags_extra); - { - int j; - for (j = 0; j < 64; j++) { - if ((j%16) == 0) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); - } - dprintk("\n"); - } +#ifdef DEBUG + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, + skb->data, 64, true); +#endif writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); return NETDEV_TX_OK; @@ -2666,16 +2656,11 @@ static int nv_rx_process(struct net_device *dev, int limit) skb = np->get_rx_ctx->skb; np->get_rx_ctx->skb = NULL; - { - int j; netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); - for (j = 0; j < 64; j++) { - if ((j%16) == 0 && j) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); - } - dprintk("\n"); - } +#ifdef DEBUG + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, + 16, 1, skb->data, 64, true); +#endif /* look at what we actually got: */ if (np->desc_ver == DESC_VER_1) { if (likely(flags & NV_RX_DESCRIPTORVALID)) { @@ -2793,16 +2778,11 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb = np->get_rx_ctx->skb; np->get_rx_ctx->skb = NULL; - { - int j; - netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); - for (j = 0; j < 64; j++) { - if ((j%16) == 0 && j) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); - } - dprintk("\n"); - } + netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); +#ifdef DEBUG + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, + skb->data, 64, true); +#endif /* look at what we actually got: */ if (likely(flags & NV_RX2_DESCRIPTORVALID)) { len = flags & LEN_MASK_V2; -- cgit v1.2.3-59-g8ed1b From f52dafc1a67c98baa9b6fa1866a4caa4be4831fb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:55 +0000 Subject: forcedeth: Convert remaining dprintk to netdev_dbg The remaining dprintk uses are emitted as KERN_INFO. Change these dprintk uses to netdev_dbg. Remove the now unused dprintk macros. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 1ac8b4e87276..b30a5992e332 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -66,12 +66,6 @@ #include #include -#if 0 -#define dprintk printk -#else -#define dprintk(x...) do { } while (0) -#endif - #define TX_WORK_PER_LOOP 64 #define RX_WORK_PER_LOOP 64 @@ -3033,8 +3027,7 @@ static void nv_set_multicast(struct net_device *dev) writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); - dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n", - dev->name); + netdev_dbg(dev, "reconfiguration for multicast lists\n"); nv_start_rx(dev); spin_unlock_irq(&np->lock); } @@ -3192,8 +3185,8 @@ set_speed: if (np->duplex == newdup && np->linkspeed == newls) return retval; - dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n", - dev->name, np->linkspeed, np->duplex, newls, newdup); + netdev_dbg(dev, "changing link setting from %d/%d to %d/%d\n", + np->linkspeed, np->duplex, newls, newdup); np->duplex = newdup; np->linkspeed = newls; @@ -3336,7 +3329,7 @@ static void nv_link_irq(struct net_device *dev) miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus); - dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat); + netdev_dbg(dev, "link change irq, status 0x%x\n", miistat); if (miistat & (NVREG_MIISTAT_LINKCHANGE)) nv_linkchange(dev); @@ -5243,7 +5236,7 @@ static int nv_open(struct net_device *dev) u32 miistat; miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); - dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); + netdev_dbg(dev, "startup: got 0x%08x\n", miistat); } /* set linkspeed to invalid value, thus force nv_update_linkspeed * to init hw */ @@ -5299,7 +5292,7 @@ static int nv_close(struct net_device *dev) base = get_hwbase(dev); nv_disable_hw_interrupts(dev, np->irqmask); pci_push(base); - dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); + netdev_dbg(dev, "Irqmask is zero again\n"); spin_unlock_irq(&np->lock); @@ -5649,11 +5642,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; if (id->driver_data & DEV_NEED_LINKTIMER) { - dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev)); + netdev_dbg(dev, "%s: link timer on\n", pci_name(pci_dev)); np->need_linktimer = 1; np->link_timeout = jiffies + LINK_TIMEOUT; } else { - dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev)); + netdev_dbg(dev, "%s: link timer off\n", pci_name(pci_dev)); np->need_linktimer = 0; } @@ -5684,16 +5677,16 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->mac_in_use = 1; if (np->mgmt_version > 0) np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE; - dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", - pci_name(pci_dev), np->mac_in_use); + netdev_dbg(dev, "%s: mgmt unit is running. mac in use %x\n", + pci_name(pci_dev), np->mac_in_use); /* management unit setup the phy already? */ if (np->mac_in_use && ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) == NVREG_XMITCTL_SYNC_PHY_INIT)) { /* phy is inited by mgmt unit */ phyinitialized = 1; - dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", - pci_name(pci_dev)); + netdev_dbg(dev, "%s: Phy already initialized by mgmt unit\n", + pci_name(pci_dev)); } else { /* we need to init the phy */ } -- cgit v1.2.3-59-g8ed1b From 294a554e274f961ac33c7d739d5b912bd0005f5b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:56 +0000 Subject: forcedeth: Use pr_fmt and pr_ Convert printks to pr_. Remove "forcedeth: " from some calls as it's now added by pr_fmt. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 256 +++++++++++++++++++++++++++--------------------- 1 file changed, 142 insertions(+), 114 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index b30a5992e332..1c6f4ef9f928 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -39,6 +39,9 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define FORCEDETH_VERSION "0.64" #define DRV_NAME "forcedeth" @@ -1189,7 +1192,8 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); reg &= ~PHY_MARVELL_E3016_INITMASK; if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) { - printk(KERN_INFO "%s: phy write to errata reg failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy write to errata reg failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1197,31 +1201,38 @@ static int phy_init(struct net_device *dev) if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1241,23 +1252,27 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); reg |= PHY_REALTEK_INIT9; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ); if (!(reg & PHY_REALTEK_INIT11)) { reg |= PHY_REALTEK_INIT11; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1266,7 +1281,8 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1277,7 +1293,8 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP); if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { - printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy write to advertise failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } @@ -1296,7 +1313,7 @@ static int phy_init(struct net_device *dev) mii_control_1000 &= ~ADVERTISE_1000FULL; if (mii_rw(dev, np->phyaddr, MII_CTRL1000, mii_control_1000)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } else @@ -1311,7 +1328,7 @@ static int phy_init(struct net_device *dev) /* start autoneg since we already performed hw reset above */ mii_control |= BMCR_ANRESTART; if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { - printk(KERN_INFO "%s: phy init failed\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } else { @@ -1319,7 +1336,7 @@ static int phy_init(struct net_device *dev) * (certain phys need bmcr to be setup with reset) */ if (phy_reset(dev, mii_control)) { - printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev)); + pr_info("%s: phy reset failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1330,13 +1347,13 @@ static int phy_init(struct net_device *dev) phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); phy_reserved |= PHY_CICADA_INIT5; if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1344,77 +1361,77 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); phy_reserved |= PHY_CICADA_INIT6; if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } if (np->phy_oui == PHY_OUI_VITESSE) { if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK1; phy_reserved |= PHY_VITESSE_INIT3; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK1; phy_reserved |= PHY_VITESSE_INIT3; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK2; phy_reserved |= PHY_VITESSE_INIT8; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1423,31 +1440,38 @@ static int phy_init(struct net_device *dev) np->phy_rev == PHY_REV_REALTEK_8211B) { /* reset could have cleared these out, set them back */ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1456,24 +1480,28 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); phy_reserved &= ~PHY_REALTEK_INIT_MSK1; phy_reserved |= PHY_REALTEK_INIT3; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + pr_info("%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1532,7 +1560,7 @@ static void nv_stop_rx(struct net_device *dev) writel(rx_ctrl, base + NvRegReceiverControl); if (reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX)) - printk(KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); + pr_info("%s: ReceiverStatus remained busy\n", __func__); udelay(NV_RXSTOP_DELAY2); if (!np->mac_in_use) @@ -1567,7 +1595,7 @@ static void nv_stop_tx(struct net_device *dev) writel(tx_ctrl, base + NvRegTransmitterControl); if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX)) - printk(KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); + pr_info("%s: TransmitterStatus remained busy\n", __func__); udelay(NV_TXSTOP_DELAY2); if (!np->mac_in_use) @@ -2485,57 +2513,53 @@ static void nv_tx_timeout(struct net_device *dev) u32 status; union ring_type put_tx; int saved_tx_limit; + int i; if (np->msi_flags & NV_MSI_X_ENABLED) status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; else status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, status); + pr_info("%s: Got tx_timeout. irq: %08x\n", dev->name, status); - { - int i; - - printk(KERN_INFO "%s: Ring at %lx\n", - dev->name, (unsigned long)np->ring_addr); - printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); - for (i = 0; i <= np->register_size; i += 32) { - printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - i, - readl(base + i + 0), readl(base + i + 4), - readl(base + i + 8), readl(base + i + 12), - readl(base + i + 16), readl(base + i + 20), - readl(base + i + 24), readl(base + i + 28)); - } - printk(KERN_INFO "%s: Dumping tx ring\n", dev->name); - for (i = 0; i < np->tx_ring_size; i += 4) { - if (!nv_optimized(np)) { - printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", - i, - le32_to_cpu(np->tx_ring.orig[i].buf), - le32_to_cpu(np->tx_ring.orig[i].flaglen), - le32_to_cpu(np->tx_ring.orig[i+1].buf), - le32_to_cpu(np->tx_ring.orig[i+1].flaglen), - le32_to_cpu(np->tx_ring.orig[i+2].buf), - le32_to_cpu(np->tx_ring.orig[i+2].flaglen), - le32_to_cpu(np->tx_ring.orig[i+3].buf), - le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); - } else { - printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", - i, - le32_to_cpu(np->tx_ring.ex[i].bufhigh), - le32_to_cpu(np->tx_ring.ex[i].buflow), - le32_to_cpu(np->tx_ring.ex[i].flaglen), - le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+1].buflow), - le32_to_cpu(np->tx_ring.ex[i+1].flaglen), - le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+2].buflow), - le32_to_cpu(np->tx_ring.ex[i+2].flaglen), - le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+3].buflow), - le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); - } + pr_info("%s: Ring at %lx\n", dev->name, (unsigned long)np->ring_addr); + pr_info("%s: Dumping tx registers\n", dev->name); + for (i = 0; i <= np->register_size; i += 32) { + pr_info("%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + i, + readl(base + i + 0), readl(base + i + 4), + readl(base + i + 8), readl(base + i + 12), + readl(base + i + 16), readl(base + i + 20), + readl(base + i + 24), readl(base + i + 28)); + } + pr_info("%s: Dumping tx ring\n", dev->name); + for (i = 0; i < np->tx_ring_size; i += 4) { + if (!nv_optimized(np)) { + pr_info("%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", + i, + le32_to_cpu(np->tx_ring.orig[i].buf), + le32_to_cpu(np->tx_ring.orig[i].flaglen), + le32_to_cpu(np->tx_ring.orig[i+1].buf), + le32_to_cpu(np->tx_ring.orig[i+1].flaglen), + le32_to_cpu(np->tx_ring.orig[i+2].buf), + le32_to_cpu(np->tx_ring.orig[i+2].flaglen), + le32_to_cpu(np->tx_ring.orig[i+3].buf), + le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); + } else { + pr_info("%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", + i, + le32_to_cpu(np->tx_ring.ex[i].bufhigh), + le32_to_cpu(np->tx_ring.ex[i].buflow), + le32_to_cpu(np->tx_ring.ex[i].flaglen), + le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+1].buflow), + le32_to_cpu(np->tx_ring.ex[i+1].flaglen), + le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+2].buflow), + le32_to_cpu(np->tx_ring.ex[i+2].flaglen), + le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+3].buflow), + le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); } } @@ -3308,14 +3332,14 @@ static void nv_linkchange(struct net_device *dev) if (nv_update_linkspeed(dev)) { if (!netif_carrier_ok(dev)) { netif_carrier_on(dev); - printk(KERN_INFO "%s: link up.\n", dev->name); + pr_info("%s: link up\n", dev->name); nv_txrx_gate(dev, false); nv_start_rx(dev); } } else { if (netif_carrier_ok(dev)) { netif_carrier_off(dev); - printk(KERN_INFO "%s: link down.\n", dev->name); + pr_info("%s: link down\n", dev->name); nv_txrx_gate(dev, true); nv_stop_rx(dev); } @@ -3764,7 +3788,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_rx, "%s-rx", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); + pr_info("request_irq failed for rx %d\n", + ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_err; @@ -3773,7 +3798,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_tx, "%s-tx", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); + pr_info("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; @@ -3782,7 +3808,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_other, "%s-other", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); + pr_info("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; @@ -3796,7 +3823,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } else { /* Request irq for all interrupts */ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, handler, IRQF_SHARED, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); + pr_info("request_irq failed %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_err; @@ -3814,7 +3841,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test) np->msi_flags |= NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); + pr_info("request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; @@ -3899,7 +3926,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->recover_error) { np->recover_error = 0; - printk(KERN_INFO "%s: MAC in recoverable error state\n", dev->name); + pr_info("%s: MAC in recoverable error state\n", dev->name); if (netif_running(dev)) { netif_tx_lock_bh(dev); netif_addr_lock(dev); @@ -4195,14 +4222,14 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } if (netif_running(dev)) - printk(KERN_INFO "%s: link down.\n", dev->name); + pr_info("%s: link down\n", dev->name); bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); if (np->phy_model == PHY_MODEL_MARVELL_E3016) { bmcr |= BMCR_ANENABLE; /* reset the phy in order for settings to stick, * and cause autoneg to start */ if (phy_reset(dev, bmcr)) { - printk(KERN_INFO "%s: phy reset failed\n", dev->name); + pr_info("%s: phy reset failed\n", dev->name); return -EINVAL; } } else { @@ -4251,7 +4278,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (np->phy_oui == PHY_OUI_MARVELL) { /* reset the phy in order for forced mode settings to stick */ if (phy_reset(dev, bmcr)) { - printk(KERN_INFO "%s: phy reset failed\n", dev->name); + pr_info("%s: phy reset failed\n", dev->name); return -EINVAL; } } else { @@ -4313,7 +4340,7 @@ static int nv_nway_reset(struct net_device *dev) spin_unlock(&np->lock); netif_addr_unlock(dev); netif_tx_unlock_bh(dev); - printk(KERN_INFO "%s: link down.\n", dev->name); + pr_info("%s: link down\n", dev->name); } bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); @@ -4321,7 +4348,7 @@ static int nv_nway_reset(struct net_device *dev) bmcr |= BMCR_ANENABLE; /* reset the phy in order for settings to stick*/ if (phy_reset(dev, bmcr)) { - printk(KERN_INFO "%s: phy reset failed\n", dev->name); + pr_info("%s: phy reset failed\n", dev->name); return -EINVAL; } } else { @@ -4494,12 +4521,13 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* 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); + pr_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); + pr_info("%s: hardware does not support tx pause frames\n", + dev->name); return -EINVAL; } @@ -4534,7 +4562,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); if (netif_running(dev)) - printk(KERN_INFO "%s: link down.\n", dev->name); + pr_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); @@ -4796,8 +4824,8 @@ static int nv_loopback_test(struct net_device *dev) pkt_len = ETH_DATA_LEN; tx_skb = dev_alloc_skb(pkt_len); if (!tx_skb) { - printk(KERN_ERR "dev_alloc_skb() failed during loopback test" - " of %s\n", dev->name); + pr_err("dev_alloc_skb() failed during loopback test of %s\n", + dev->name); ret = 0; goto out; } @@ -5160,7 +5188,7 @@ static int nv_open(struct net_device *dev) if (reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX)) - printk(KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); + pr_info("%s: SetupReg5, Bit 31 remained off\n", __func__); writel(0, base + NvRegMIIMask); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); @@ -5249,7 +5277,7 @@ static int nv_open(struct net_device *dev) if (ret) { netif_carrier_on(dev); } else { - printk(KERN_INFO "%s: no link during initialization.\n", dev->name); + pr_info("%s: no link during initialization\n", dev->name); netif_carrier_off(dev); } if (oom) @@ -5361,8 +5389,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i static int printed_version; if (!printed_version++) - printk(KERN_INFO "%s: Reverse Engineered nForce ethernet" - " driver. Version %s.\n", DRV_NAME, FORCEDETH_VERSION); + pr_info("Reverse Engineered nForce ethernet driver. Version %s.\n", + FORCEDETH_VERSION); dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 1d397f3698ec438c3c14abf45bfac88cca1882d9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:57 +0000 Subject: forcedeth: Convert pr_ to netdev_ Use netdev_ when a struct net_device * is available. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 293 ++++++++++++++++++++++++++---------------------- 1 file changed, 161 insertions(+), 132 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 1c6f4ef9f928..c3a9783b7c46 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1192,8 +1192,8 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); reg &= ~PHY_MARVELL_E3016_INITMASK; if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) { - pr_info("%s: phy write to errata reg failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy write to errata reg failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1201,38 +1201,38 @@ static int phy_init(struct net_device *dev) if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1252,27 +1252,27 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); reg |= PHY_REALTEK_INIT9; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ); if (!(reg & PHY_REALTEK_INIT11)) { reg |= PHY_REALTEK_INIT11; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1281,8 +1281,8 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1293,8 +1293,8 @@ static int phy_init(struct net_device *dev) reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP); if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { - pr_info("%s: phy write to advertise failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy write to advertise failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } @@ -1313,7 +1313,8 @@ static int phy_init(struct net_device *dev) mii_control_1000 &= ~ADVERTISE_1000FULL; if (mii_rw(dev, np->phyaddr, MII_CTRL1000, mii_control_1000)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } else @@ -1328,7 +1329,8 @@ static int phy_init(struct net_device *dev) /* start autoneg since we already performed hw reset above */ mii_control |= BMCR_ANRESTART; if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } else { @@ -1336,7 +1338,8 @@ static int phy_init(struct net_device *dev) * (certain phys need bmcr to be setup with reset) */ if (phy_reset(dev, mii_control)) { - pr_info("%s: phy reset failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy reset failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1347,13 +1350,15 @@ static int phy_init(struct net_device *dev) phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); phy_reserved |= PHY_CICADA_INIT5; if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1361,77 +1366,92 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); phy_reserved |= PHY_CICADA_INIT6; if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } if (np->phy_oui == PHY_OUI_VITESSE) { if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK1; phy_reserved |= PHY_VITESSE_INIT3; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK1; phy_reserved |= PHY_VITESSE_INIT3; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); phy_reserved &= ~PHY_VITESSE_INIT_MSK2; phy_reserved |= PHY_VITESSE_INIT8; if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) { - pr_info("%s: phy init failed\n", pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1440,38 +1460,38 @@ static int phy_init(struct net_device *dev) np->phy_rev == PHY_REV_REALTEK_8211B) { /* reset could have cleared these out, set them back */ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1480,28 +1500,28 @@ static int phy_init(struct net_device *dev) phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); phy_reserved &= ~PHY_REALTEK_INIT_MSK1; phy_reserved |= PHY_REALTEK_INIT3; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - pr_info("%s: phy init failed\n", - pci_name(np->pci_dev)); + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; } } @@ -1560,7 +1580,8 @@ static void nv_stop_rx(struct net_device *dev) writel(rx_ctrl, base + NvRegReceiverControl); if (reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX)) - pr_info("%s: ReceiverStatus remained busy\n", __func__); + netdev_info(dev, "%s: ReceiverStatus remained busy\n", + __func__); udelay(NV_RXSTOP_DELAY2); if (!np->mac_in_use) @@ -1595,7 +1616,8 @@ static void nv_stop_tx(struct net_device *dev) writel(tx_ctrl, base + NvRegTransmitterControl); if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX)) - pr_info("%s: TransmitterStatus remained busy\n", __func__); + netdev_info(dev, "%s: TransmitterStatus remained busy\n", + __func__); udelay(NV_TXSTOP_DELAY2); if (!np->mac_in_use) @@ -2520,46 +2542,49 @@ static void nv_tx_timeout(struct net_device *dev) else status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - pr_info("%s: Got tx_timeout. irq: %08x\n", dev->name, status); + netdev_info(dev, "Got tx_timeout. irq: %08x\n", status); - pr_info("%s: Ring at %lx\n", dev->name, (unsigned long)np->ring_addr); - pr_info("%s: Dumping tx registers\n", dev->name); + netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr); + netdev_info(dev, "Dumping tx registers\n"); for (i = 0; i <= np->register_size; i += 32) { - pr_info("%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - i, - readl(base + i + 0), readl(base + i + 4), - readl(base + i + 8), readl(base + i + 12), - readl(base + i + 16), readl(base + i + 20), - readl(base + i + 24), readl(base + i + 28)); - } - pr_info("%s: Dumping tx ring\n", dev->name); + netdev_info(dev, + "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + i, + readl(base + i + 0), readl(base + i + 4), + readl(base + i + 8), readl(base + i + 12), + readl(base + i + 16), readl(base + i + 20), + readl(base + i + 24), readl(base + i + 28)); + } + netdev_info(dev, "Dumping tx ring\n"); for (i = 0; i < np->tx_ring_size; i += 4) { if (!nv_optimized(np)) { - pr_info("%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", - i, - le32_to_cpu(np->tx_ring.orig[i].buf), - le32_to_cpu(np->tx_ring.orig[i].flaglen), - le32_to_cpu(np->tx_ring.orig[i+1].buf), - le32_to_cpu(np->tx_ring.orig[i+1].flaglen), - le32_to_cpu(np->tx_ring.orig[i+2].buf), - le32_to_cpu(np->tx_ring.orig[i+2].flaglen), - le32_to_cpu(np->tx_ring.orig[i+3].buf), - le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); + netdev_info(dev, + "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", + i, + le32_to_cpu(np->tx_ring.orig[i].buf), + le32_to_cpu(np->tx_ring.orig[i].flaglen), + le32_to_cpu(np->tx_ring.orig[i+1].buf), + le32_to_cpu(np->tx_ring.orig[i+1].flaglen), + le32_to_cpu(np->tx_ring.orig[i+2].buf), + le32_to_cpu(np->tx_ring.orig[i+2].flaglen), + le32_to_cpu(np->tx_ring.orig[i+3].buf), + le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); } else { - pr_info("%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", - i, - le32_to_cpu(np->tx_ring.ex[i].bufhigh), - le32_to_cpu(np->tx_ring.ex[i].buflow), - le32_to_cpu(np->tx_ring.ex[i].flaglen), - le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+1].buflow), - le32_to_cpu(np->tx_ring.ex[i+1].flaglen), - le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+2].buflow), - le32_to_cpu(np->tx_ring.ex[i+2].flaglen), - le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+3].buflow), - le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); + netdev_info(dev, + "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", + i, + le32_to_cpu(np->tx_ring.ex[i].bufhigh), + le32_to_cpu(np->tx_ring.ex[i].buflow), + le32_to_cpu(np->tx_ring.ex[i].flaglen), + le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+1].buflow), + le32_to_cpu(np->tx_ring.ex[i+1].flaglen), + le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+2].buflow), + le32_to_cpu(np->tx_ring.ex[i+2].flaglen), + le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), + le32_to_cpu(np->tx_ring.ex[i+3].buflow), + le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); } } @@ -3332,14 +3357,14 @@ static void nv_linkchange(struct net_device *dev) if (nv_update_linkspeed(dev)) { if (!netif_carrier_ok(dev)) { netif_carrier_on(dev); - pr_info("%s: link up\n", dev->name); + netdev_info(dev, "link up\n"); nv_txrx_gate(dev, false); nv_start_rx(dev); } } else { if (netif_carrier_ok(dev)) { netif_carrier_off(dev); - pr_info("%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); nv_txrx_gate(dev, true); nv_stop_rx(dev); } @@ -3788,8 +3813,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_rx, "%s-rx", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) { - pr_info("request_irq failed for rx %d\n", - ret); + netdev_info(dev, + "request_irq failed for rx %d\n", + ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_err; @@ -3798,8 +3824,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_tx, "%s-tx", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) { - pr_info("request_irq failed for tx %d\n", - ret); + netdev_info(dev, + "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; @@ -3808,8 +3835,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test) sprintf(np->name_other, "%s-other", dev->name); if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) { - pr_info("request_irq failed for link %d\n", - ret); + netdev_info(dev, + "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; @@ -3823,7 +3851,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } else { /* Request irq for all interrupts */ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, handler, IRQF_SHARED, dev->name, dev) != 0) { - pr_info("request_irq failed %d\n", ret); + netdev_info(dev, + "request_irq failed %d\n", + ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_err; @@ -3841,7 +3871,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) np->msi_flags |= NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { - pr_info("request_irq failed %d\n", ret); + netdev_info(dev, "request_irq failed %d\n", + ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; @@ -3926,7 +3957,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->recover_error) { np->recover_error = 0; - pr_info("%s: MAC in recoverable error state\n", dev->name); + netdev_info(dev, "MAC in recoverable error state\n"); if (netif_running(dev)) { netif_tx_lock_bh(dev); netif_addr_lock(dev); @@ -4222,14 +4253,14 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } if (netif_running(dev)) - pr_info("%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); if (np->phy_model == PHY_MODEL_MARVELL_E3016) { bmcr |= BMCR_ANENABLE; /* reset the phy in order for settings to stick, * and cause autoneg to start */ if (phy_reset(dev, bmcr)) { - pr_info("%s: phy reset failed\n", dev->name); + netdev_info(dev, "phy reset failed\n"); return -EINVAL; } } else { @@ -4278,7 +4309,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (np->phy_oui == PHY_OUI_MARVELL) { /* reset the phy in order for forced mode settings to stick */ if (phy_reset(dev, bmcr)) { - pr_info("%s: phy reset failed\n", dev->name); + netdev_info(dev, "phy reset failed\n"); return -EINVAL; } } else { @@ -4340,7 +4371,7 @@ static int nv_nway_reset(struct net_device *dev) spin_unlock(&np->lock); netif_addr_unlock(dev); netif_tx_unlock_bh(dev); - pr_info("%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); } bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); @@ -4348,7 +4379,7 @@ static int nv_nway_reset(struct net_device *dev) bmcr |= BMCR_ANENABLE; /* reset the phy in order for settings to stick*/ if (phy_reset(dev, bmcr)) { - pr_info("%s: phy reset failed\n", dev->name); + netdev_info(dev, "phy reset failed\n"); return -EINVAL; } } else { @@ -4521,13 +4552,11 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* if ((!np->autoneg && np->duplex == 0) || (np->autoneg && !pause->autoneg && np->duplex == 0)) { - pr_info("%s: can not set pause settings when forced link is in half duplex\n", - dev->name); + netdev_info(dev, "can not set pause settings when forced link is in half duplex\n"); return -EINVAL; } if (pause->tx_pause && !(np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE)) { - pr_info("%s: hardware does not support tx pause frames\n", - dev->name); + netdev_info(dev, "hardware does not support tx pause frames\n"); return -EINVAL; } @@ -4562,7 +4591,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); if (netif_running(dev)) - pr_info("%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); @@ -4824,8 +4853,7 @@ static int nv_loopback_test(struct net_device *dev) pkt_len = ETH_DATA_LEN; tx_skb = dev_alloc_skb(pkt_len); if (!tx_skb) { - pr_err("dev_alloc_skb() failed during loopback test of %s\n", - dev->name); + netdev_err(dev, "dev_alloc_skb() failed during loopback test\n"); ret = 0; goto out; } @@ -5188,7 +5216,8 @@ static int nv_open(struct net_device *dev) if (reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX)) - pr_info("%s: SetupReg5, Bit 31 remained off\n", __func__); + netdev_info(dev, + "%s: SetupReg5, Bit 31 remained off\n", __func__); writel(0, base + NvRegMIIMask); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); @@ -5277,7 +5306,7 @@ static int nv_open(struct net_device *dev) if (ret) { netif_carrier_on(dev); } else { - pr_info("%s: no link during initialization\n", dev->name); + netdev_info(dev, "no link during initialization\n"); netif_carrier_off(dev); } if (oom) -- cgit v1.2.3-59-g8ed1b From c41d41e1687dcf344f55dd15c7121532e5c195d4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:58 +0000 Subject: forcedeth: Add function init_realtek_8211b Deduplicate the code use for the init/reset of this device. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 105 +++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 73 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index c3a9783b7c46..300748ccc5c1 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1181,6 +1181,33 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup) return 0; } +static int init_realtek_8211b(struct net_device *dev, struct fe_priv *np) +{ + static const struct { + int reg; + int init; + } ri[] = { + { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1 }, + { PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2 }, + { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3 }, + { PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4 }, + { PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5 }, + { PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6 }, + { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1 }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(ri); i++) { + if (mii_rw(dev, np->phyaddr, ri[i].reg, ri[i].init)) { + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + + return 0; +} + static int phy_init(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -1200,44 +1227,10 @@ static int phy_init(struct net_device *dev) if (np->phy_oui == PHY_OUI_REALTEK) { if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); + if (init_realtek_8211b(dev, np)) return PHY_ERROR; - } - } - if (np->phy_model == PHY_MODEL_REALTEK_8211 && - np->phy_rev == PHY_REV_REALTEK_8211C) { + } else if (np->phy_model == PHY_MODEL_REALTEK_8211 && + np->phy_rev == PHY_REV_REALTEK_8211C) { u32 powerstate = readl(base + NvRegPowerState2); /* need to perform hw phy reset */ @@ -1459,43 +1452,9 @@ static int phy_init(struct net_device *dev) if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { /* reset could have cleared these out, set them back */ - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); + if (init_realtek_8211b(dev, np)) return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - if (np->phy_model == PHY_MODEL_REALTEK_8201) { + } else if (np->phy_model == PHY_MODEL_REALTEK_8201) { if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; -- cgit v1.2.3-59-g8ed1b From cd66328bdab782ee40d17b573a3067a591cb7b4f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:41:59 +0000 Subject: forcedeth: Separate vendor specific initializations into functions Neaten the phy_init function by adding and calling vendor specific functions. object size is reduced by ~1kb: $ size drivers/net/forcedeth.o.* text data bss dec hex filename 83475 1848 19304 104627 198b3 drivers/net/forcedeth.o.new 84459 1848 19544 105851 19d7b drivers/net/forcedeth.o.old Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 367 +++++++++++++++++++++++++----------------------- 1 file changed, 188 insertions(+), 179 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 300748ccc5c1..0b1d562ec4a2 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1198,21 +1198,179 @@ static int init_realtek_8211b(struct net_device *dev, struct fe_priv *np) int i; for (i = 0; i < ARRAY_SIZE(ri); i++) { - if (mii_rw(dev, np->phyaddr, ri[i].reg, ri[i].init)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); + if (mii_rw(dev, np->phyaddr, ri[i].reg, ri[i].init)) + return PHY_ERROR; + } + + return 0; +} + +static int init_realtek_8211c(struct net_device *dev, struct fe_priv *np) +{ + u32 reg; + u8 __iomem *base = get_hwbase(dev); + u32 powerstate = readl(base + NvRegPowerState2); + + /* need to perform hw phy reset */ + powerstate |= NVREG_POWERSTATE2_PHY_RESET; + writel(powerstate, base + NvRegPowerState2); + msleep(25); + + powerstate &= ~NVREG_POWERSTATE2_PHY_RESET; + writel(powerstate, base + NvRegPowerState2); + msleep(25); + + reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); + reg |= PHY_REALTEK_INIT9; + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) + return PHY_ERROR; + reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ); + if (!(reg & PHY_REALTEK_INIT11)) { + reg |= PHY_REALTEK_INIT11; + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) + return PHY_ERROR; + + return 0; +} + +static int init_realtek_8201(struct net_device *dev, struct fe_priv *np) +{ + u32 phy_reserved; + + if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG6, MII_READ); + phy_reserved |= PHY_REALTEK_INIT7; + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG6, phy_reserved)) return PHY_ERROR; - } } return 0; } +static int init_realtek_8201_cross(struct net_device *dev, struct fe_priv *np) +{ + u32 phy_reserved; + + if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG2, MII_READ); + phy_reserved &= ~PHY_REALTEK_INIT_MSK1; + phy_reserved |= PHY_REALTEK_INIT3; + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG2, phy_reserved)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) + return PHY_ERROR; + } + + return 0; +} + +static int init_cicada(struct net_device *dev, struct fe_priv *np, + u32 phyinterface) +{ + u32 phy_reserved; + + if (phyinterface & PHY_RGMII) { + phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); + phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); + phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); + if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); + phy_reserved |= PHY_CICADA_INIT5; + if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); + phy_reserved |= PHY_CICADA_INIT6; + if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) + return PHY_ERROR; + + return 0; +} + +static int init_vitesse(struct net_device *dev, struct fe_priv *np) +{ + u32 phy_reserved; + + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG4, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG3, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK1; + phy_reserved |= PHY_VITESSE_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG4, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK1; + phy_reserved |= PHY_VITESSE_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG3, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG4, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) + return PHY_ERROR; + phy_reserved = mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG3, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK2; + phy_reserved |= PHY_VITESSE_INIT8; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) + return PHY_ERROR; + if (mii_rw(dev, np->phyaddr, + PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) + return PHY_ERROR; + + return 0; +} + static int phy_init(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); u8 __iomem *base = get_hwbase(dev); - u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000, reg; + u32 phyinterface; + u32 mii_status, mii_control, mii_control_1000, reg; /* phy errata for E3016 phy */ if (np->phy_model == PHY_MODEL_MARVELL_E3016) { @@ -1227,64 +1385,32 @@ static int phy_init(struct net_device *dev) if (np->phy_oui == PHY_OUI_REALTEK) { if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { - if (init_realtek_8211b(dev, np)) - return PHY_ERROR; - } else if (np->phy_model == PHY_MODEL_REALTEK_8211 && - np->phy_rev == PHY_REV_REALTEK_8211C) { - u32 powerstate = readl(base + NvRegPowerState2); - - /* need to perform hw phy reset */ - powerstate |= NVREG_POWERSTATE2_PHY_RESET; - writel(powerstate, base + NvRegPowerState2); - msleep(25); - - powerstate &= ~NVREG_POWERSTATE2_PHY_RESET; - writel(powerstate, base + NvRegPowerState2); - msleep(25); - - reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); - reg |= PHY_REALTEK_INIT9; - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) { + if (init_realtek_8211b(dev, np)) { netdev_info(dev, "%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) { + } else if (np->phy_model == PHY_MODEL_REALTEK_8211 && + np->phy_rev == PHY_REV_REALTEK_8211C) { + if (init_realtek_8211c(dev, np)) { netdev_info(dev, "%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } - reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ); - if (!(reg & PHY_REALTEK_INIT11)) { - reg |= PHY_REALTEK_INIT11; - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + } else if (np->phy_model == PHY_MODEL_REALTEK_8201) { + if (init_realtek_8201(dev, np)) { netdev_info(dev, "%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } } - if (np->phy_model == PHY_MODEL_REALTEK_8201) { - if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { - phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); - phy_reserved |= PHY_REALTEK_INIT7; - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - } } /* set advertise register */ reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); - reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP); + reg |= (ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL | + ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP); if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { netdev_info(dev, "%s: phy write to advertise failed\n", pci_name(np->pci_dev)); @@ -1298,7 +1424,8 @@ static int phy_init(struct net_device *dev) mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); if (mii_status & PHY_GIGABIT) { np->gigabit = PHY_GIGABIT; - mii_control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); + mii_control_1000 = mii_rw(dev, np->phyaddr, + MII_CTRL1000, MII_READ); mii_control_1000 &= ~ADVERTISE_1000HALF; if (phyinterface & PHY_RGMII) mii_control_1000 |= ADVERTISE_1000FULL; @@ -1338,151 +1465,33 @@ static int phy_init(struct net_device *dev) } /* phy vendor specific configuration */ - if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) { - phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); - phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); - phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); - if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); - phy_reserved |= PHY_CICADA_INIT5; - if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - if (np->phy_oui == PHY_OUI_CICADA) { - phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); - phy_reserved |= PHY_CICADA_INIT6; - if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - if (np->phy_oui == PHY_OUI_VITESSE) { - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); - phy_reserved &= ~PHY_VITESSE_INIT_MSK1; - phy_reserved |= PHY_VITESSE_INIT3; - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) { + if ((np->phy_oui == PHY_OUI_CICADA)) { + if (init_cicada(dev, np, phyinterface)) { netdev_info(dev, "%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); - phy_reserved &= ~PHY_VITESSE_INIT_MSK1; - phy_reserved |= PHY_VITESSE_INIT3; - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { + } else if (np->phy_oui == PHY_OUI_VITESSE) { + if (init_vitesse(dev, np)) { netdev_info(dev, "%s: phy init failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); - phy_reserved &= ~PHY_VITESSE_INIT_MSK2; - phy_reserved |= PHY_VITESSE_INIT8; - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - if (np->phy_oui == PHY_OUI_REALTEK) { + } else if (np->phy_oui == PHY_OUI_REALTEK) { if (np->phy_model == PHY_MODEL_REALTEK_8211 && np->phy_rev == PHY_REV_REALTEK_8211B) { /* reset could have cleared these out, set them back */ - if (init_realtek_8211b(dev, np)) + if (init_realtek_8211b(dev, np)) { + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); return PHY_ERROR; - } else if (np->phy_model == PHY_MODEL_REALTEK_8201) { - if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { - phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); - phy_reserved |= PHY_REALTEK_INIT7; - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } } - if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); - phy_reserved &= ~PHY_REALTEK_INIT_MSK1; - phy_reserved |= PHY_REALTEK_INIT3; - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - netdev_info(dev, "%s: phy init failed\n", - pci_name(np->pci_dev)); - return PHY_ERROR; - } + } else if (np->phy_model == PHY_MODEL_REALTEK_8201) { + if (init_realtek_8201(dev, np) || + init_realtek_8201_cross(dev, np)) { + netdev_info(dev, "%s: phy init failed\n", + pci_name(np->pci_dev)); + return PHY_ERROR; } } } -- cgit v1.2.3-59-g8ed1b From b2ba08e606dfd106a394c3ac7a56c497b4c8f230 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:42:00 +0000 Subject: forcedeth: Convert dev_printk( to dev_( Use vsprintf extension %pM for a mac address in one instance. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 64 ++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 0b1d562ec4a2..60edf0185b13 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5442,8 +5442,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } } if (i == DEVICE_COUNT_RESOURCE) { - dev_printk(KERN_INFO, &pci_dev->dev, - "Couldn't find register window\n"); + dev_info(&pci_dev->dev, "Couldn't find register window\n"); goto out_relreg; } @@ -5459,13 +5458,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; if (dma_64bit) { if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(39))) - dev_printk(KERN_INFO, &pci_dev->dev, - "64-bit DMA failed, using 32-bit addressing\n"); + dev_info(&pci_dev->dev, + "64-bit DMA failed, using 32-bit addressing\n"); else dev->features |= NETIF_F_HIGHDMA; if (pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(39))) { - dev_printk(KERN_INFO, &pci_dev->dev, - "64-bit DMA (consistent) failed, using 32-bit ring buffers\n"); + dev_info(&pci_dev->dev, + "64-bit DMA (consistent) failed, using 32-bit ring buffers\n"); } } } else if (id->driver_data & DEV_HAS_LARGEDESC) { @@ -5595,11 +5594,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i * Bad mac address. At least one bios sets the mac address * to 01:23:45:67:89:ab */ - dev_printk(KERN_ERR, &pci_dev->dev, - "Invalid Mac address detected: %pM\n", + dev_err(&pci_dev->dev, + "Invalid MAC address detected: %pM\n", dev->dev_addr); - dev_printk(KERN_ERR, &pci_dev->dev, - "Please complain to your hardware vendor. Switching to a random MAC.\n"); + dev_err(&pci_dev->dev, + "Please complain to your hardware vendor. Switched to a random MAC address.\n"); random_ether_addr(dev->dev_addr); } @@ -5752,8 +5751,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i break; } if (i == 33) { - dev_printk(KERN_INFO, &pci_dev->dev, - "open: Could not find a valid PHY.\n"); + dev_info(&pci_dev->dev, "open: Could not find a valid PHY\n"); goto out_error; } @@ -5774,37 +5772,27 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i err = register_netdev(dev); if (err) { - dev_printk(KERN_INFO, &pci_dev->dev, - "unable to register netdev: %d\n", err); + dev_info(&pci_dev->dev, "unable to register netdev: %d\n", err); goto out_error; } - dev_printk(KERN_INFO, &pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, " - "addr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", - dev->name, - np->phy_oui, - np->phyaddr, - dev->dev_addr[0], - dev->dev_addr[1], - dev->dev_addr[2], - dev->dev_addr[3], - dev->dev_addr[4], - dev->dev_addr[5]); - - dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", - dev->features & NETIF_F_HIGHDMA ? "highdma " : "", - dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? + dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", + dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); + + dev_info(&pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", + dev->features & NETIF_F_HIGHDMA ? "highdma " : "", + dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? "csum " : "", - dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? + dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? "vlan " : "", - id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", - id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", - id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", - np->gigabit == PHY_GIGABIT ? "gbit " : "", - np->need_linktimer ? "lnktim " : "", - np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", - np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", - np->desc_ver); + id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", + id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", + id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", + np->gigabit == PHY_GIGABIT ? "gbit " : "", + np->need_linktimer ? "lnktim " : "", + np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", + np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", + np->desc_ver); return 0; -- cgit v1.2.3-59-g8ed1b From ef46ffbc2841dddebe521764c06673474ca5d041 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:42:01 +0000 Subject: forcedeth: Remove netdev_dbg uses These were probably just for initial driver debugging and have not been enabled in builds in git history. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 133 ------------------------------------------------ 1 file changed, 133 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 60edf0185b13..c2945d669b4f 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1136,22 +1136,14 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value) if (reg_delay(dev, NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX)) { - netdev_dbg(dev, "mii_rw of reg %d at PHY %d timed out\n", - miireg, addr); retval = -1; } else if (value != MII_READ) { /* it was a write operation - fewer failures are detectable */ - netdev_dbg(dev, "mii_rw wrote 0x%x to reg %d at PHY %d\n", - value, miireg, addr); retval = 0; } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) { - netdev_dbg(dev, "mii_rw of reg %d at PHY %d failed\n", - miireg, addr); retval = -1; } else { retval = readl(base + NvRegMIIData); - netdev_dbg(dev, "mii_rw read from reg %d at PHY %d: 0x%x\n", - miireg, addr, retval); } return retval; @@ -1516,7 +1508,6 @@ static void nv_start_rx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 rx_ctrl = readl(base + NvRegReceiverControl); - netdev_dbg(dev, "%s\n", __func__); /* Already running? Stop it. */ if ((readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) && !np->mac_in_use) { rx_ctrl &= ~NVREG_RCVCTL_START; @@ -1529,8 +1520,6 @@ static void nv_start_rx(struct net_device *dev) if (np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN; writel(rx_ctrl, base + NvRegReceiverControl); - netdev_dbg(dev, "%s: duplex %d, speed 0x%08x\n", - __func__, np->duplex, np->linkspeed); pci_push(base); } @@ -1540,7 +1529,6 @@ static void nv_stop_rx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 rx_ctrl = readl(base + NvRegReceiverControl); - netdev_dbg(dev, "%s\n", __func__); if (!np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_START; else @@ -1562,7 +1550,6 @@ static void nv_start_tx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 tx_ctrl = readl(base + NvRegTransmitterControl); - netdev_dbg(dev, "%s\n", __func__); tx_ctrl |= NVREG_XMITCTL_START; if (np->mac_in_use) tx_ctrl &= ~NVREG_XMITCTL_TX_PATH_EN; @@ -1576,7 +1563,6 @@ static void nv_stop_tx(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 tx_ctrl = readl(base + NvRegTransmitterControl); - netdev_dbg(dev, "%s\n", __func__); if (!np->mac_in_use) tx_ctrl &= ~NVREG_XMITCTL_START; else @@ -1610,7 +1596,6 @@ static void nv_txrx_reset(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - netdev_dbg(dev, "%s\n", __func__); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); @@ -1624,8 +1609,6 @@ static void nv_mac_reset(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 temp1, temp2, temp3; - netdev_dbg(dev, "%s\n", __func__); - writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); @@ -2202,13 +2185,6 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&np->lock, flags); - netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", - __func__, entries, tx_flags_extra); -#ifdef DEBUG - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, 64, true); -#endif - writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); return NETDEV_TX_OK; } @@ -2348,13 +2324,6 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, spin_unlock_irqrestore(&np->lock, flags); - netdev_dbg(dev, "%s: entries %d queued for transmission. tx_flags_extra: %x\n", - __func__, entries, tx_flags_extra); -#ifdef DEBUG - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, 64, true); -#endif - writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); return NETDEV_TX_OK; } @@ -2393,8 +2362,6 @@ static int nv_tx_done(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) && (tx_work < limit)) { - netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); - nv_unmap_txskb(np, np->get_tx_ctx); if (np->desc_ver == DESC_VER_1) { @@ -2457,8 +2424,6 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) && (tx_work < limit)) { - netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); - nv_unmap_txskb(np, np->get_tx_ctx); if (flags & NV_TX2_LASTPACKET) { @@ -2607,8 +2572,6 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) protolen = ntohs(((struct ethhdr *)packet)->h_proto); hdrlen = ETH_HLEN; } - netdev_dbg(dev, "%s: datalen %d, protolen %d, hdrlen %d\n", - __func__, datalen, protolen, hdrlen); if (protolen > ETH_DATA_LEN) return datalen; /* Value in proto field not a len, no checks possible */ @@ -2619,25 +2582,18 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) /* more data on wire than in 802 header, trim of * additional data. */ - netdev_dbg(dev, "%s: accepting %d bytes\n", - __func__, protolen); return protolen; } else { /* less data on wire than mentioned in header. * Discard the packet. */ - netdev_dbg(dev, "%s: discarding long packet\n", - __func__); return -1; } } else { /* short packet. Accept only if 802 values are also short */ if (protolen > ETH_ZLEN) { - netdev_dbg(dev, "%s: discarding short packet\n", - __func__); return -1; } - netdev_dbg(dev, "%s: accepting %d bytes\n", __func__, datalen); return datalen; } } @@ -2654,8 +2610,6 @@ static int nv_rx_process(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) && (rx_work < limit)) { - netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); - /* * the packet is for us - immediately tear down the pci mapping. * TODO: check if a prefetch of the first cacheline improves @@ -2667,11 +2621,6 @@ static int nv_rx_process(struct net_device *dev, int limit) skb = np->get_rx_ctx->skb; np->get_rx_ctx->skb = NULL; - netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); -#ifdef DEBUG - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, - 16, 1, skb->data, 64, true); -#endif /* look at what we actually got: */ if (np->desc_ver == DESC_VER_1) { if (likely(flags & NV_RX_DESCRIPTORVALID)) { @@ -2746,8 +2695,6 @@ static int nv_rx_process(struct net_device *dev, int limit) /* got a valid packet - forward it to the network core */ skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); - netdev_dbg(dev, "%s: %d bytes, proto %d accepted\n", - __func__, len, skb->protocol); napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -2776,8 +2723,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && (rx_work < limit)) { - netdev_dbg(dev, "%s: flags 0x%x\n", __func__, flags); - /* * the packet is for us - immediately tear down the pci mapping. * TODO: check if a prefetch of the first cacheline improves @@ -2789,11 +2734,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb = np->get_rx_ctx->skb; np->get_rx_ctx->skb = NULL; - netdev_dbg(dev, "Dumping packet (flags 0x%x)\n", flags); -#ifdef DEBUG - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, 64, true); -#endif /* look at what we actually got: */ if (likely(flags & NV_RX2_DESCRIPTORVALID)) { len = flags & LEN_MASK_V2; @@ -2826,9 +2766,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); prefetch(skb->data); - netdev_dbg(dev, "%s: %d bytes, proto %d accepted\n", - __func__, len, skb->protocol); - if (likely(!np->vlangrp)) { napi_gro_receive(&np->napi, skb); } else { @@ -3044,7 +2981,6 @@ static void nv_set_multicast(struct net_device *dev) writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); - netdev_dbg(dev, "reconfiguration for multicast lists\n"); nv_start_rx(dev); spin_unlock_irq(&np->lock); } @@ -3119,8 +3055,6 @@ static int nv_update_linkspeed(struct net_device *dev) mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); if (!(mii_status & BMSR_LSTATUS)) { - netdev_dbg(dev, - "no link detected by phy - falling back to 10HD\n"); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; retval = 0; @@ -3128,8 +3062,6 @@ static int nv_update_linkspeed(struct net_device *dev) } if (np->autoneg == 0) { - netdev_dbg(dev, "%s: autoneg off, PHY set to 0x%04x\n", - __func__, np->fixed_mode); if (np->fixed_mode & LPA_100FULL) { newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; newdup = 1; @@ -3152,15 +3084,11 @@ static int nv_update_linkspeed(struct net_device *dev) newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; retval = 0; - netdev_dbg(dev, - "autoneg not completed - falling back to 10HD\n"); goto set_speed; } adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); - netdev_dbg(dev, "%s: PHY advertises 0x%04x, lpa 0x%04x\n", - __func__, adv, lpa); retval = 1; if (np->gigabit == PHY_GIGABIT) { @@ -3169,8 +3097,6 @@ static int nv_update_linkspeed(struct net_device *dev) if ((control_1000 & ADVERTISE_1000FULL) && (status_1000 & LPA_1000FULL)) { - netdev_dbg(dev, "%s: GBit ethernet detected\n", - __func__); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000; newdup = 1; goto set_speed; @@ -3192,8 +3118,6 @@ static int nv_update_linkspeed(struct net_device *dev) newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } else { - netdev_dbg(dev, "bad ability %04x - falling back to 10HD\n", - adv_lpa); newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } @@ -3202,9 +3126,6 @@ set_speed: if (np->duplex == newdup && np->linkspeed == newls) return retval; - netdev_dbg(dev, "changing link setting from %d/%d to %d/%d\n", - np->linkspeed, np->duplex, newls, newdup); - np->duplex = newdup; np->linkspeed = newls; @@ -3346,11 +3267,9 @@ static void nv_link_irq(struct net_device *dev) miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus); - netdev_dbg(dev, "link change irq, status 0x%x\n", miistat); if (miistat & (NVREG_MIISTAT_LINKCHANGE)) nv_linkchange(dev); - netdev_dbg(dev, "link change notification done\n"); } static void nv_msi_workaround(struct fe_priv *np) @@ -3401,8 +3320,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - netdev_dbg(dev, "%s\n", __func__); - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { np->events = readl(base + NvRegIrqStatus); writel(np->events, base + NvRegIrqStatus); @@ -3410,7 +3327,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data) np->events = readl(base + NvRegMSIXIrqStatus); writel(np->events, base + NvRegMSIXIrqStatus); } - netdev_dbg(dev, "irq: %08x\n", np->events); if (!(np->events & np->irqmask)) return IRQ_NONE; @@ -3424,8 +3340,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data) __napi_schedule(&np->napi); } - netdev_dbg(dev, "%s: completed\n", __func__); - return IRQ_HANDLED; } @@ -3440,8 +3354,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - netdev_dbg(dev, "%s\n", __func__); - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { np->events = readl(base + NvRegIrqStatus); writel(np->events, base + NvRegIrqStatus); @@ -3449,7 +3361,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) np->events = readl(base + NvRegMSIXIrqStatus); writel(np->events, base + NvRegMSIXIrqStatus); } - netdev_dbg(dev, "irq: %08x\n", np->events); if (!(np->events & np->irqmask)) return IRQ_NONE; @@ -3462,7 +3373,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) writel(0, base + NvRegIrqMask); __napi_schedule(&np->napi); } - netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_HANDLED; } @@ -3476,12 +3386,9 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) int i; unsigned long flags; - netdev_dbg(dev, "%s\n", __func__); - for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); - netdev_dbg(dev, "tx irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3505,7 +3412,6 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) } } - netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3590,12 +3496,9 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) int i; unsigned long flags; - netdev_dbg(dev, "%s\n", __func__); - for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); - netdev_dbg(dev, "rx irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3623,7 +3526,6 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) break; } } - netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3637,12 +3539,9 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) int i; unsigned long flags; - netdev_dbg(dev, "%s\n", __func__); - for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); - netdev_dbg(dev, "irq: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3692,7 +3591,6 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) } } - netdev_dbg(dev, "%s: completed\n", __func__); return IRQ_RETVAL(i); } @@ -3704,8 +3602,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) u8 __iomem *base = get_hwbase(dev); u32 events; - netdev_dbg(dev, "%s\n", __func__); - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus); @@ -3714,7 +3610,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); } pci_push(base); - netdev_dbg(dev, "irq: %08x\n", events); if (!(events & NVREG_IRQ_TIMER)) return IRQ_RETVAL(0); @@ -3724,8 +3619,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) np->intr_test = 1; spin_unlock(&np->lock); - netdev_dbg(dev, "%s: completed\n", __func__); - return IRQ_RETVAL(1); } @@ -4868,21 +4761,15 @@ static int nv_loopback_test(struct net_device *dev) if (ret) { if (len != pkt_len) { ret = 0; - netdev_dbg(dev, "loopback len mismatch %d vs %d\n", - len, pkt_len); } else { rx_skb = np->rx_skb[0].skb; for (i = 0; i < pkt_len; i++) { if (rx_skb->data[i] != (u8)(i & 0xff)) { ret = 0; - netdev_dbg(dev, "loopback pattern check failed on byte %d\n", - i); break; } } } - } else { - netdev_dbg(dev, "loopback - did not receive test packet\n"); } pci_unmap_single(np->pci_dev, test_dma_addr, @@ -5132,8 +5019,6 @@ static int nv_open(struct net_device *dev) int oom, i; u32 low; - netdev_dbg(dev, "%s\n", __func__); - /* power up phy */ mii_rw(dev, np->phyaddr, MII_BMCR, mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN); @@ -5261,7 +5146,6 @@ static int nv_open(struct net_device *dev) u32 miistat; miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); - netdev_dbg(dev, "startup: got 0x%08x\n", miistat); } /* set linkspeed to invalid value, thus force nv_update_linkspeed * to init hw */ @@ -5317,7 +5201,6 @@ static int nv_close(struct net_device *dev) base = get_hwbase(dev); nv_disable_hw_interrupts(dev, np->irqmask); pci_push(base); - netdev_dbg(dev, "Irqmask is zero again\n"); spin_unlock_irq(&np->lock); @@ -5430,11 +5313,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i err = -EINVAL; addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - netdev_dbg(dev, "%s: resource %d start %p len %lld flags 0x%08lx\n", - pci_name(pci_dev), i, - (void *)(unsigned long)pci_resource_start(pci_dev, i), - (long long)pci_resource_len(pci_dev, i), - pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && pci_resource_len(pci_dev, i) >= np->register_size) { addr = pci_resource_start(pci_dev, i); @@ -5602,9 +5480,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i random_ether_addr(dev->dev_addr); } - netdev_dbg(dev, "%s: MAC Address %pM\n", - pci_name(pci_dev), dev->dev_addr); - /* set mac address */ nv_copy_mac_to_hw(dev); @@ -5666,11 +5541,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; if (id->driver_data & DEV_NEED_LINKTIMER) { - netdev_dbg(dev, "%s: link timer on\n", pci_name(pci_dev)); np->need_linktimer = 1; np->link_timeout = jiffies + LINK_TIMEOUT; } else { - netdev_dbg(dev, "%s: link timer off\n", pci_name(pci_dev)); np->need_linktimer = 0; } @@ -5701,16 +5574,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->mac_in_use = 1; if (np->mgmt_version > 0) np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE; - netdev_dbg(dev, "%s: mgmt unit is running. mac in use %x\n", - pci_name(pci_dev), np->mac_in_use); /* management unit setup the phy already? */ if (np->mac_in_use && ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) == NVREG_XMITCTL_SYNC_PHY_INIT)) { /* phy is inited by mgmt unit */ phyinitialized = 1; - netdev_dbg(dev, "%s: Phy already initialized by mgmt unit\n", - pci_name(pci_dev)); } else { /* we need to init the phy */ } @@ -5736,8 +5605,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->phy_model = id2 & PHYID2_MODEL_MASK; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; - netdev_dbg(dev, "%s: %s: Found PHY %04x:%04x at address %d\n", - pci_name(pci_dev), __func__, id1, id2, phyaddr); np->phyaddr = phyaddr; np->phy_oui = id1 | id2; -- cgit v1.2.3-59-g8ed1b From c20ec76157747434652e721cdd4dccd8654ad370 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Nov 2010 07:42:02 +0000 Subject: forcedeth: Use netdev_dbg for printk(KERN_DEBUG Use the normal debugging functions. Print mac address when using random_ether_addr. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index c2945d669b4f..cd2d72d825df 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3407,7 +3407,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } spin_unlock_irqrestore(&np->lock, flags); - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); + netdev_dbg(dev, "%s: too many iterations (%d)\n", + __func__, i); break; } @@ -3522,7 +3523,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } spin_unlock_irqrestore(&np->lock, flags); - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); + netdev_dbg(dev, "%s: too many iterations (%d)\n", + __func__, i); break; } } @@ -3586,7 +3588,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } spin_unlock_irqrestore(&np->lock, flags); - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); + netdev_dbg(dev, "%s: too many iterations (%d)\n", + __func__, i); break; } @@ -5463,7 +5466,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); - printk(KERN_DEBUG "nv_probe: set workaround bit for reversed mac addr\n"); + dev_dbg(&pci_dev->dev, + "%s: set workaround bit for reversed mac addr\n", + __func__); } memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); @@ -5473,11 +5478,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i * to 01:23:45:67:89:ab */ dev_err(&pci_dev->dev, - "Invalid MAC address detected: %pM\n", + "Invalid MAC address detected: %pM - Please complain to your hardware vendor.\n", dev->dev_addr); - dev_err(&pci_dev->dev, - "Please complain to your hardware vendor. Switched to a random MAC address.\n"); random_ether_addr(dev->dev_addr); + dev_err(&pci_dev->dev, + "Using random MAC address: %pM\n", dev->dev_addr); } /* set mac address */ -- cgit v1.2.3-59-g8ed1b From f7ca38dfe58c20cb1aa2ed9643187e8b194b5bae Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 25 Nov 2010 10:02:29 +0100 Subject: nl80211/cfg80211: extend mgmt-tx API for off-channel With p2p, it is sometimes necessary to transmit a frame (typically an action frame) on another channel than the current channel. Enable this through the CMD_FRAME API, and allow it to wait for a response. A new command allows that wait to be aborted. However, allow userspace to specify whether or not it wants to allow off-channel TX, it may actually want to use the same channel only. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 25 +++++++++++++++++----- include/net/cfg80211.h | 11 +++++++--- net/mac80211/cfg.c | 7 ++++-- net/wireless/core.h | 4 ++-- net/wireless/mlme.c | 9 ++++---- net/wireless/nl80211.c | 57 +++++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 91 insertions(+), 22 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index d706bf3badc8..5cfa579df476 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -358,11 +358,16 @@ * user space application). %NL80211_ATTR_FRAME is used to specify the * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on - * which channel the frame is to be transmitted or was received. This - * channel has to be the current channel (remain-on-channel or the - * operational channel). When called, this operation returns a cookie - * (%NL80211_ATTR_COOKIE) that will be included with the TX status event - * pertaining to the TX request. + * which channel the frame is to be transmitted or was received. If this + * channel is not the current channel (remain-on-channel or the + * operational channel) the device will switch to the given channel and + * transmit the frame, optionally waiting for a response for the time + * specified using %NL80211_ATTR_DURATION. When called, this operation + * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the + * TX status event pertaining to the TX request. + * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this + * command may be used with the corresponding cookie to cancel the wait + * time if it is known that it is no longer necessary. * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies @@ -493,6 +498,8 @@ enum nl80211_commands { NL80211_CMD_SET_CHANNEL, NL80211_CMD_SET_WDS_PEER, + NL80211_CMD_FRAME_WAIT_CANCEL, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -828,6 +835,12 @@ enum nl80211_commands { * * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS * + * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be + * transmitted on another channel when the channel given doesn't match + * the current channel. If the current channel doesn't match and this + * flag isn't set, the frame will be rejected. This is also used as an + * nl80211 capability flag. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1002,6 +1015,8 @@ enum nl80211_attrs { NL80211_ATTR_MCAST_RATE, + NL80211_ATTR_OFFCHANNEL_TX_OK, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0663945cfa48..49a7c53a48ca 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1134,7 +1134,9 @@ struct cfg80211_pmksa { * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. * This allows the operation to be terminated prior to timeout based on * the duration value. - * @mgmt_tx: Transmit a management frame + * @mgmt_tx: Transmit a management frame. + * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management + * frame on another channel * * @testmode_cmd: run a test mode command * @@ -1291,10 +1293,13 @@ struct cfg80211_ops { u64 cookie); int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, + struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, - bool channel_type_valid, + bool channel_type_valid, unsigned int wait, const u8 *buf, size_t len, u64 *cookie); + int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie); int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0c544074479e..aac2d7de828e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1552,9 +1552,9 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, } static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, + struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, - bool channel_type_valid, + bool channel_type_valid, unsigned int wait, const u8 *buf, size_t len, u64 *cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1565,6 +1565,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | IEEE80211_TX_CTL_REQ_TX_STATUS; + if (offchan) + return -EOPNOTSUPP; + /* Check that we are on the requested channel for transmission */ if (chan != local->tmp_channel && chan != local->oper_channel) diff --git a/net/wireless/core.h b/net/wireless/core.h index 6583cca0e2ee..ee80ad8dc655 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -341,9 +341,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, struct net_device *dev, - struct ieee80211_channel *chan, + struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, - bool channel_type_valid, + bool channel_type_valid, unsigned int wait, const u8 *buf, size_t len, u64 *cookie); /* SME */ diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 6980a0c315b2..d7680f2a4c5b 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -864,9 +864,9 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, struct net_device *dev, - struct ieee80211_channel *chan, + struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, - bool channel_type_valid, + bool channel_type_valid, unsigned int wait, const u8 *buf, size_t len, u64 *cookie) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -946,8 +946,9 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, return -EINVAL; /* Transmit the Action frame as requested by user space */ - return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type, - channel_type_valid, buf, len, cookie); + return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, + channel_type, channel_type_valid, + wait, buf, len, cookie); } bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 67ff7e92cb99..960be4e650f0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -163,16 +163,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, - [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, - [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, - [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, - [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, + [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -677,6 +674,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(remain_on_channel, REMAIN_ON_CHANNEL); CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); CMD(mgmt_tx, FRAME); + CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { i++; NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); @@ -698,6 +696,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_cmds); + /* for now at least assume all drivers have it */ + if (dev->ops->mgmt_tx) + NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); + if (mgmt_stypes) { u16 stypes; struct nlattr *nl_ftypes, *nl_ifs; @@ -4244,6 +4246,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) void *hdr; u64 cookie; struct sk_buff *msg; + unsigned int wait = 0; + bool offchan; if (!info->attrs[NL80211_ATTR_FRAME] || !info->attrs[NL80211_ATTR_WIPHY_FREQ]) @@ -4260,6 +4264,12 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; + if (info->attrs[NL80211_ATTR_DURATION]) { + if (!rdev->ops->mgmt_tx_cancel_wait) + return -EINVAL; + wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); + } + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); @@ -4271,6 +4281,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) channel_type_valid = true; } + offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; + freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); if (chan == NULL) @@ -4287,8 +4299,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) err = PTR_ERR(hdr); goto free_msg; } - err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type, - channel_type_valid, + err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, + channel_type_valid, wait, nla_data(info->attrs[NL80211_ATTR_FRAME]), nla_len(info->attrs[NL80211_ATTR_FRAME]), &cookie); @@ -4307,6 +4319,31 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) return err; } +static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + u64 cookie; + + if (!info->attrs[NL80211_ATTR_COOKIE]) + return -EINVAL; + + if (!rdev->ops->mgmt_tx_cancel_wait) + return -EOPNOTSUPP; + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; + + cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); + + return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie); +} + static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -4879,6 +4916,14 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_FRAME_WAIT_CANCEL, + .doit = nl80211_tx_mgmt_cancel_wait, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, { .cmd = NL80211_CMD_SET_POWER_SAVE, .doit = nl80211_set_power_save, -- cgit v1.2.3-59-g8ed1b From f30221e4ec62d905b56d5e8f7ccab6b406a97cf5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 25 Nov 2010 10:02:30 +0100 Subject: mac80211: implement off-channel mgmt TX This implements the new off-channel TX API in mac80211 with a new work item type. The operation doesn't add a new work item when we're on the right channel and there's no wait time so that for example p2p probe responses will be transmitted without delay. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 93 +++++++++++++++++++++++++++++++++++++++++++--- net/mac80211/ieee80211_i.h | 5 +++ net/mac80211/status.c | 15 +++++++- net/mac80211/work.c | 22 +++++++++++ 4 files changed, 129 insertions(+), 6 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index aac2d7de828e..db134b500caa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1551,6 +1551,28 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); } +static enum work_done_result +ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) +{ + /* + * Use the data embedded in the work struct for reporting + * here so if the driver mangled the SKB before dropping + * it (which is the only way we really should get here) + * then we don't report mangled data. + * + * If there was no wait time, then by the time we get here + * the driver will likely not have reported the status yet, + * so in that case userspace will have to deal with it. + */ + + if (wk->offchan_tx.wait && wk->offchan_tx.frame) + cfg80211_mgmt_tx_status(wk->sdata->dev, + (unsigned long) wk->offchan_tx.frame, + wk->ie, wk->ie_len, false, GFP_KERNEL); + + return WORK_DONE_DESTROY; +} + static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, @@ -1561,20 +1583,22 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct sta_info *sta; + struct ieee80211_work *wk; const struct ieee80211_mgmt *mgmt = (void *)buf; u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | IEEE80211_TX_CTL_REQ_TX_STATUS; - - if (offchan) - return -EOPNOTSUPP; + bool is_offchan = false; /* Check that we are on the requested channel for transmission */ if (chan != local->tmp_channel && chan != local->oper_channel) - return -EBUSY; + is_offchan = true; if (channel_type_valid && (channel_type != local->tmp_channel_type && channel_type != local->_oper_channel_type)) + is_offchan = true; + + if (is_offchan && !offchan) return -EBUSY; switch (sdata->vif.type) { @@ -1608,12 +1632,70 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, IEEE80211_SKB_CB(skb)->flags = flags; skb->dev = sdata->dev; - ieee80211_tx_skb(sdata, skb); *cookie = (unsigned long) skb; + + /* + * Can transmit right away if the channel was the + * right one and there's no wait involved... If a + * wait is involved, we might otherwise not be on + * the right channel for long enough! + */ + if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) { + ieee80211_tx_skb(sdata, skb); + return 0; + } + + wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL); + if (!wk) { + kfree_skb(skb); + return -ENOMEM; + } + + wk->type = IEEE80211_WORK_OFFCHANNEL_TX; + wk->chan = chan; + wk->sdata = sdata; + wk->done = ieee80211_offchan_tx_done; + wk->offchan_tx.frame = skb; + wk->offchan_tx.wait = wait; + wk->ie_len = len; + memcpy(wk->ie, buf, len); + + ieee80211_add_work(wk); return 0; } +static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct ieee80211_work *wk; + int ret = -ENOENT; + + mutex_lock(&local->mtx); + list_for_each_entry(wk, &local->work_list, list) { + if (wk->sdata != sdata) + continue; + + if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) + continue; + + if (cookie != (unsigned long) wk->offchan_tx.frame) + continue; + + wk->timeout = jiffies; + + ieee80211_queue_work(&local->hw, &local->work_work); + ret = 0; + break; + } + mutex_unlock(&local->mtx); + + return ret; +} + static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, u16 frame_type, bool reg) @@ -1698,6 +1780,7 @@ struct cfg80211_ops mac80211_config_ops = { .remain_on_channel = ieee80211_remain_on_channel, .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, .mgmt_tx = ieee80211_mgmt_tx, + .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, .mgmt_frame_register = ieee80211_mgmt_frame_register, .set_antenna = ieee80211_set_antenna, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 5bc0745368fe..66b0b52b828d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -260,6 +260,7 @@ enum ieee80211_work_type { IEEE80211_WORK_ASSOC_BEACON_WAIT, IEEE80211_WORK_ASSOC, IEEE80211_WORK_REMAIN_ON_CHANNEL, + IEEE80211_WORK_OFFCHANNEL_TX, }; /** @@ -320,6 +321,10 @@ struct ieee80211_work { struct { u32 duration; } remain; + struct { + struct sk_buff *frame; + u32 wait; + } offchan_tx; }; int ie_len; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index bed7e32ed908..4958710a7d92 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -321,10 +321,23 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) msecs_to_jiffies(10)); } - if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) + if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { + struct ieee80211_work *wk; + + rcu_read_lock(); + list_for_each_entry_rcu(wk, &local->work_list, list) { + if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) + continue; + if (wk->offchan_tx.frame != skb) + continue; + wk->offchan_tx.frame = NULL; + break; + } + rcu_read_unlock(); cfg80211_mgmt_tx_status( skb->dev, (unsigned long) skb, skb->data, skb->len, !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); + } /* this was a transmitted frame, but now we want to reuse it */ skb_orphan(skb); diff --git a/net/mac80211/work.c b/net/mac80211/work.c index ae344d1ba056..2b5c3f267198 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -560,6 +560,25 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) return WORK_ACT_TIMEOUT; } +static enum work_action __must_check +ieee80211_offchannel_tx(struct ieee80211_work *wk) +{ + if (!wk->started) { + wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait); + + /* + * After this, offchan_tx.frame remains but now is no + * longer a valid pointer -- we still need it as the + * cookie for canceling this work. + */ + ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); + + return WORK_ACT_NONE; + } + + return WORK_ACT_TIMEOUT; +} + static enum work_action __must_check ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) { @@ -955,6 +974,9 @@ static void ieee80211_work_work(struct work_struct *work) case IEEE80211_WORK_REMAIN_ON_CHANNEL: rma = ieee80211_remain_on_channel_timeout(wk); break; + case IEEE80211_WORK_OFFCHANNEL_TX: + rma = ieee80211_offchannel_tx(wk); + break; case IEEE80211_WORK_ASSOC_BEACON_WAIT: rma = ieee80211_assoc_beacon_wait(wk); break; -- cgit v1.2.3-59-g8ed1b From 8f5dcb1cfb71ce832f53a4723deba72e6695078b Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 26 Nov 2010 06:10:06 -0800 Subject: ath9k: Reintroduce modparam to enable btcoex It is not ideal to enable btcoex based on subsys id as it is not unique, they are so random. It is also a pain keeping all of them in a table to enable btcoex for a particular hw. Going back to the old idea. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 ++ drivers/net/wireless/ath/ath9k/hw.c | 3 +-- drivers/net/wireless/ath/ath9k/init.c | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 20ea68c59f7b..26bdbeee424f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -168,6 +168,8 @@ struct ath_common { struct ath_regulatory regulatory; const struct ath_ops *ops; const struct ath_bus_ops *bus_ops; + + bool btcoex_enabled; }; struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ce9e59f4cd3d..883f6cc7b82c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1925,8 +1925,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_antcfg_2ghz = ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); - if (AR_SREV_9280_20_OR_LATER(ah) && - ath9k_hw_btcoex_supported(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 7eef1faee668..d11e6da4d892 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -38,6 +38,10 @@ int led_blink; module_param_named(blink, led_blink, int, 0444); MODULE_PARM_DESC(blink, "Enable LED blink on activity"); +static int ath9k_btcoex_enable; +module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); +MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); + /* We use the hw_value as an index into our private channel structure */ #define CHAN2G(_freq, _idx) { \ @@ -543,6 +547,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, common->hw = sc->hw; common->priv = sc; common->debug_mask = ath9k_debug; + common->btcoex_enabled = ath9k_btcoex_enable == 1; spin_lock_init(&common->cc_lock); spin_lock_init(&sc->wiphy_lock); -- cgit v1.2.3-59-g8ed1b From 8c5e9c830a04ece8f0c35db2c1e0f6d87bd64894 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 26 Nov 2010 06:10:07 -0800 Subject: ath9k: Remove code which enables btcoex based on subsys id Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/btcoex.c | 23 ----------------------- drivers/net/wireless/ath/ath9k/btcoex.h | 1 - 2 files changed, 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 6a92e57fddf0..d33bf204c995 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -35,29 +35,6 @@ struct ath_btcoex_config { bool bt_hold_rx_clear; }; -static const u16 ath_subsysid_tbl[] = { - AR9280_COEX2WIRE_SUBSYSID, - AT9285_COEX3WIRE_SA_SUBSYSID, - AT9285_COEX3WIRE_DA_SUBSYSID -}; - -/* - * Checks the subsystem id of the device to see if it - * supports btcoex - */ -bool ath9k_hw_btcoex_supported(struct ath_hw *ah) -{ - int i; - - if (!ah->hw_version.subsysid) - return false; - - for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++) - if (ah->hw_version.subsysid == ath_subsysid_tbl[i]) - return true; - - return false; -} void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) { diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 1ee5a15ccbb1..588dfd464dd1 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -49,7 +49,6 @@ struct ath_btcoex_hw { u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ }; -bool ath9k_hw_btcoex_supported(struct ath_hw *ah); void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah); void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah); void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); -- cgit v1.2.3-59-g8ed1b From 81fc2a332045dc1dae24f24d3e2dc4656f2cc498 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 26 Nov 2010 23:24:33 +0530 Subject: Revert "ath9k_htc: Handle monitor mode properly for HTC devices" This reverts commit 446fad5a5b6be765c8ec39bfdbbc6c7aa63fbcbb. The change had broken the packet injection on monitoring mode. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 64 ++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index e9761c2c8700..8266ce1f02e3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -184,6 +184,47 @@ err: return ret; } +static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_vif hvif; + int ret = 0; + u8 cmd_rsp; + + if (priv->nvifs > 0) + return -ENOBUFS; + + memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); + memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); + + hvif.opmode = cpu_to_be32(HTC_M_MONITOR); + priv->ah->opmode = NL80211_IFTYPE_MONITOR; + hvif.index = priv->nvifs; + + WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); + if (ret) + return ret; + + priv->nvifs++; + return 0; +} + +static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_vif hvif; + int ret = 0; + u8 cmd_rsp; + + memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); + memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); + hvif.index = 0; /* Should do for now */ + WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); + priv->nvifs--; + + return ret; +} + static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -1199,6 +1240,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) WMI_CMD(WMI_STOP_RECV_CMDID); skb_queue_purge(&priv->tx_queue); + /* Remove monitor interface here */ + if (ah->opmode == NL80211_IFTYPE_MONITOR) { + if (ath9k_htc_remove_monitor_interface(priv)) + ath_print(common, ATH_DBG_FATAL, + "Unable to remove monitor interface\n"); + else + ath_print(common, ATH_DBG_CONFIG, + "Monitor interface removed\n"); + } + if (ah->btcoex_hw.enabled) { ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) @@ -1372,13 +1423,16 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } - if (changed & IEEE80211_CONF_CHANGE_MONITOR) + if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { - ath_print(common, ATH_DBG_CONFIG, - "HW opmode set to Monitor mode\n"); - priv->ah->opmode = NL80211_IFTYPE_MONITOR; + if (ath9k_htc_add_monitor_interface(priv)) + ath_print(common, ATH_DBG_FATAL, + "Failed to set monitor mode\n"); + else + ath_print(common, ATH_DBG_CONFIG, + "HW opmode set to Monitor mode\n"); } - + } if (changed & IEEE80211_CONF_CHANGE_IDLE) { mutex_lock(&priv->htc_pm_lock); -- cgit v1.2.3-59-g8ed1b From 8b7f8532d15631776ce8bec2bbbc58f6aad738d1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 28 Nov 2010 19:37:48 +0100 Subject: ath9k: fix software retry counter tracking The recent tx path cleanups moved the software retry count tracking from the ath_buf to the skb cb, however the actual counter update referred to the wrong location, confusing block-ack window tracking. Fix this by using the retries counter in the struct ath_frame_info. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 495432ec85a9..177a7b1de322 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -250,11 +250,11 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, struct sk_buff *skb) { - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_frame_info *fi = get_frame_info(skb); struct ieee80211_hdr *hdr; TX_STAT_INC(txq->axq_qnum, a_retries); - if (tx_info->control.rates[4].count++ > 0) + if (fi->retries++ > 0) return; hdr = (struct ieee80211_hdr *)skb->data; -- cgit v1.2.3-59-g8ed1b From dd318575ff0aae91ac4cbcc5b60c184e59267212 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 29 Nov 2010 11:09:16 +0100 Subject: mac80211: fix RX aggregation locking The RX aggregation locking documentation was wrong, which led Christian to also code the timer timeout handling for it somewhat wrongly. Fix the documentation, the two places that need to hold the reorder lock across accesses to the structure, and the debugfs code that should just use RCU. Also, remove acquiring the sta->lock across reorder timeouts since it isn't necessary, and change a few places to GFP_KERNEL because the code path here doesn't need atomic allocations as I noticed when reviewing all this. Signed-off-by: Johannes Berg Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 8 +++----- net/mac80211/debugfs_sta.c | 29 +++++++++++++++-------------- net/mac80211/rx.c | 17 +++++++++++++---- net/mac80211/sta_info.h | 29 ++++++++++++++--------------- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 720b7a84af59..f138b195d657 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -129,9 +129,7 @@ static void sta_rx_agg_reorder_timer_expired(unsigned long data) timer_to_tid[0]); rcu_read_lock(); - spin_lock(&sta->lock); ieee80211_release_reorder_timeout(sta, *ptid); - spin_unlock(&sta->lock); rcu_read_unlock(); } @@ -256,7 +254,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, } /* prepare A-MPDU MLME for Rx aggregation */ - tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); + tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); if (!tid_agg_rx) { #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) @@ -280,9 +278,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = - kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); + kcalloc(buf_size, sizeof(struct sk_buff *), GFP_KERNEL); tid_agg_rx->reorder_time = - kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC); + kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL); if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) { #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index f0fce37f4069..8bb5af85f469 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -112,34 +112,35 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, char buf[71 + STA_TID_NUM * 40], *p = buf; int i; struct sta_info *sta = file->private_data; + struct tid_ampdu_rx *tid_rx; + struct tid_ampdu_tx *tid_tx; + + rcu_read_lock(); - spin_lock_bh(&sta->lock); p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", sta->ampdu_mlme.dialog_token_allocator + 1); p += scnprintf(p, sizeof(buf) + buf - p, "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n"); + for (i = 0; i < STA_TID_NUM; i++) { + tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]); + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]); + p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i); - p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", - !!sta->ampdu_mlme.tid_rx[i]); + p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_rx); p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", - sta->ampdu_mlme.tid_rx[i] ? - sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); + tid_rx ? tid_rx->dialog_token : 0); p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x", - sta->ampdu_mlme.tid_rx[i] ? - sta->ampdu_mlme.tid_rx[i]->ssn : 0); + tid_rx ? tid_rx->ssn : 0); - p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", - !!sta->ampdu_mlme.tid_tx[i]); + p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_tx); p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", - sta->ampdu_mlme.tid_tx[i] ? - sta->ampdu_mlme.tid_tx[i]->dialog_token : 0); + tid_tx ? tid_tx->dialog_token : 0); p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d", - sta->ampdu_mlme.tid_tx[i] ? - skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0); + tid_tx ? skb_queue_len(&tid_tx->pending) : 0); p += scnprintf(p, sizeof(buf) + buf - p, "\n"); } - spin_unlock_bh(&sta->lock); + rcu_read_unlock(); return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d2fcd22ab06d..fdeabb19943c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -538,6 +538,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, { struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; + lockdep_assert_held(&tid_agg_rx->reorder_lock); + if (!skb) goto no_frame; @@ -557,6 +559,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, { int index; + lockdep_assert_held(&tid_agg_rx->reorder_lock); + while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; @@ -581,6 +585,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, { int index, j; + lockdep_assert_held(&tid_agg_rx->reorder_lock); + /* release the buffer until next missing frame */ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; @@ -683,10 +689,11 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, int index; bool ret = true; + spin_lock(&tid_agg_rx->reorder_lock); + buf_size = tid_agg_rx->buf_size; head_seq_num = tid_agg_rx->head_seq_num; - spin_lock(&tid_agg_rx->reorder_lock); /* frame with out of date sequence number */ if (seq_less(mpdu_seq_num, head_seq_num)) { dev_kfree_skb(skb); @@ -1921,9 +1928,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(tid_agg_rx->timeout)); + spin_lock(&tid_agg_rx->reorder_lock); /* release stored frames up to start of BAR */ ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, frames); + spin_unlock(&tid_agg_rx->reorder_lock); + kfree_skb(skb); return RX_QUEUED; } @@ -2515,9 +2525,8 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) } /* - * This function makes calls into the RX path. Therefore the - * caller must hold the sta_info->lock and everything has to - * be under rcu_read_lock protection as well. + * This function makes calls into the RX path, therefore + * it has to be invoked under RCU read lock. */ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index b562d9b6a702..05f11302443b 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -81,13 +81,14 @@ enum ieee80211_sta_info_flags { * @stop_initiator: initiator of a session stop * @tx_stop: TX DelBA frame when stopping * - * This structure is protected by RCU and the per-station - * spinlock. Assignments to the array holding it must hold - * the spinlock, only the TX path can access it under RCU - * lock-free if, and only if, the state has the flag - * %HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path - * must also acquire the spinlock and re-check the state, - * see comments in the tx code touching it. + * This structure's lifetime is managed by RCU, assignments to + * the array holding it must hold the aggregation mutex. + * + * The TX path can access it under RCU lock-free if, and + * only if, the state has the flag %HT_AGG_STATE_OPERATIONAL + * set. Otherwise, the TX path must also acquire the spinlock + * and re-check the state, see comments in the tx code + * touching it. */ struct tid_ampdu_tx { struct rcu_head rcu_head; @@ -115,15 +116,13 @@ struct tid_ampdu_tx { * @rcu_head: RCU head used for freeing this struct * @reorder_lock: serializes access to reorder buffer, see below. * - * This structure is protected by RCU and the per-station - * spinlock. Assignments to the array holding it must hold - * the spinlock. + * This structure's lifetime is managed by RCU, assignments to + * the array holding it must hold the aggregation mutex. * - * The @reorder_lock is used to protect the variables and - * arrays such as @reorder_buf, @reorder_time, @head_seq_num, - * @stored_mpdu_num and @reorder_time from being corrupted by - * concurrent access of the RX path and the expired frame - * release timer. + * The @reorder_lock is used to protect the members of this + * struct, except for @timeout, @buf_size and @dialog_token, + * which are constant across the lifetime of the struct (the + * dialog token being used only for debugging). */ struct tid_ampdu_rx { struct rcu_head rcu_head; -- cgit v1.2.3-59-g8ed1b From ea066d5a91f2610116dcd27054f749e4f07799d8 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 23 Nov 2010 20:42:27 +0530 Subject: ath9k: Add support for Adaptive Power Management This feature is to mitigate the problem of certain 3 stream chips that exceed the PCIe power requirements.An EEPROM flag controls which chips have APM enabled which is basically read from miscellaneous configuration element of the EEPROM header. This workaround will reduce power consumption by using 2 Tx chains for Single and Double stream rates (5 GHz only).All self generated frames (regardless of rate) are sent on 2 chains when this feature is enabled(Chip Limitation). Cc: Paul Shaw Signed-off-by: Mohammed Shafi Shajakhan Tested-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 ++ drivers/net/wireless/ath/ath9k/ar9003_phy.c | 6 +++++- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ drivers/net/wireless/ath/ath9k/beacon.c | 3 ++- drivers/net/wireless/ath/ath9k/eeprom.h | 1 + drivers/net/wireless/ath/ath9k/hw.c | 6 ++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 5 ++++- drivers/net/wireless/ath/ath9k/xmit.c | 23 +++++++++++++++++++++-- 9 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 3161a5901a7a..4aecc10cb3a6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3029,6 +3029,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, return le32_to_cpu(pBase->swreg); case EEP_PAPRD: return !!(pBase->featureEnable & BIT(5)); + case EEP_CHAIN_MASK_REDUCE: + return (pBase->miscConfiguration >> 0x3) & 0x1; default: return 0; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 656d8ce251a7..b34a9e91edd8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -487,7 +487,11 @@ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) break; } - REG_WRITE(ah, AR_SELFGEN_MASK, tx); + if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) + REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); + else + REG_WRITE(ah, AR_SELFGEN_MASK, tx); + if (tx == 0x5) { REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6f90acc5cca7..efba413561a4 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -544,6 +544,7 @@ struct ath_ant_comb { #define SC_OP_BT_PRIORITY_DETECTED BIT(12) #define SC_OP_BT_SCAN BIT(13) #define SC_OP_ANI_RUN BIT(14) +#define SC_OP_ENABLE_APM BIT(15) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) @@ -695,6 +696,8 @@ static inline void ath_ahb_exit(void) {}; void ath9k_ps_wakeup(struct ath_softc *sc); void ath9k_ps_restore(struct ath_softc *sc); +u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); + void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int ath9k_wiphy_add(struct ath_softc *sc); int ath9k_wiphy_del(struct ath_wiphy *aphy); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 30724a4e8bb2..47bedd82e9a9 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -103,7 +103,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); series[0].Tries = 1; series[0].Rate = rate; - series[0].ChSel = common->tx_chainmask; + series[0].ChSel = ath_txchainmask_reduction(sc, + common->tx_chainmask, series[0].Rate); series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, series, 4, 0); diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 3c99830dab0c..7755fb996caa 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -268,6 +268,7 @@ enum eeprom_param { EEP_PAPRD, EEP_MODAL_VER, EEP_ANT_DIV_CTL1, + EEP_CHAIN_MASK_REDUCE }; enum ar5416_rates { diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 883f6cc7b82c..b4396a9578e5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1974,6 +1974,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; } + if (AR_SREV_9300_20_OR_LATER(ah)) { + if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE)) + pCap->hw_caps |= ATH9K_HW_CAP_APM; + } + + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index cc8f3b9af71f..5fcfa48a45df 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -187,6 +187,7 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), ATH9K_HW_CAP_2GHZ = BIT(13), ATH9K_HW_CAP_5GHZ = BIT(14), + ATH9K_HW_CAP_APM = BIT(15), }; struct ath9k_hw_capabilities { diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 50bdb5db23b4..df1bfcfeb734 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -554,9 +554,12 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) { struct ath_node *an; - + struct ath_hw *ah = sc->sc_ah; an = (struct ath_node *)sta->drv_priv; + if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM) + sc->sc_flags |= SC_OP_ENABLE_APM; + if (sc->sc_flags & SC_OP_TXAGGR) { ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 177a7b1de322..821d3679c6ff 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1506,6 +1506,18 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, return duration; } +u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_channel *curchan = ah->curchan; + if ((sc->sc_flags & SC_OP_ENABLE_APM) && + (curchan->channelFlags & CHANNEL_5GHZ) && + (chainmask == 0x7) && (rate < 0x90)) + return 0x3; + else + return chainmask; +} + static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -1546,7 +1558,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) rix = rates[i].idx; series[i].Tries = rates[i].count; - series[i].ChSel = common->tx_chainmask; if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) { @@ -1569,6 +1580,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) if (rates[i].flags & IEEE80211_TX_RC_MCS) { /* MCS rates */ series[i].Rate = rix | 0x80; + series[i].ChSel = ath_txchainmask_reduction(sc, + common->tx_chainmask, series[i].Rate); series[i].PktDuration = ath_pkt_duration(sc, rix, len, is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) @@ -1576,7 +1589,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) continue; } - /* legcay rates */ + /* legacy rates */ if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; @@ -1592,6 +1605,12 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) is_sp = false; } + if (bf->bf_state.bfs_paprd) + series[i].ChSel = common->tx_chainmask; + else + series[i].ChSel = ath_txchainmask_reduction(sc, + common->tx_chainmask, series[i].Rate); + series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, phy, rate->bitrate * 100, len, rix, is_sp); } -- cgit v1.2.3-59-g8ed1b From 9320b5c4a7260d9593102f378201d17e3f030739 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:36:45 +0200 Subject: ath5k: Reset cleanup and generic cleanup * No functional changes * Clean up reset: Introduce init functions for each unit and call them instead of having everything inside ath5k_hw_reset (it's just c/p for now so nothing changes except calling order -I tested it with various cards and it's ok-) * Further cleanups: ofdm_timings belongs to phy.c rate_duration belongs to pcu.c clock functions are general and belong to reset.c (more to follow) * Reorder functions for better organization: We start with helpers and other functions follow in categories, init functions are last Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 6 +- drivers/net/wireless/ath/ath5k/ath5k.h | 60 +-- drivers/net/wireless/ath/ath5k/desc.c | 24 +- drivers/net/wireless/ath/ath5k/dma.c | 45 +++ drivers/net/wireless/ath/ath5k/eeprom.c | 147 ++++---- drivers/net/wireless/ath/ath5k/pcu.c | 438 +++++++++++++--------- drivers/net/wireless/ath/ath5k/phy.c | 444 +++++++++++++++++----- drivers/net/wireless/ath/ath5k/qcu.c | 130 ++++--- drivers/net/wireless/ath/ath5k/reset.c | 642 +++++++++----------------------- 9 files changed, 1042 insertions(+), 894 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 6b75b22a929a..f915f404302d 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -58,19 +58,19 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) { /* TODO: * ANI documents suggest the following five levels to use, but the HAL - * and ath9k use only use the last two levels, making this + * and ath9k use only the last two levels, making this * essentially an on/off option. There *may* be a reason for this (???), * so i stick with the HAL version for now... */ #if 0 - static const s8 hi[] = { -18, -18, -16, -14, -12 }; static const s8 lo[] = { -52, -56, -60, -64, -70 }; + static const s8 hi[] = { -18, -18, -16, -14, -12 }; static const s8 sz[] = { -34, -41, -48, -55, -62 }; static const s8 fr[] = { -70, -72, -75, -78, -80 }; #else - static const s8 sz[] = { -55, -62 }; static const s8 lo[] = { -64, -70 }; static const s8 hi[] = { -14, -12 }; + static const s8 sz[] = { -55, -62 }; static const s8 fr[] = { -78, -80 }; #endif if (level < 0 || level >= ARRAY_SIZE(sz)) { diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 2718136e4886..85ff822c81f4 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1140,12 +1140,14 @@ void ath5k_hw_detach(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); + /* LED functions */ int ath5k_init_leds(struct ath5k_softc *sc); void ath5k_led_enable(struct ath5k_softc *sc); void ath5k_led_off(struct ath5k_softc *sc); void ath5k_unregister_leds(struct ath5k_softc *sc); + /* Reset Functions */ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); int ath5k_hw_on_hold(struct ath5k_hw *ah); @@ -1155,6 +1157,13 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set); /* Power management functions */ + +/* Clock rate related functions */ +unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); +unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); +void ath5k_hw_set_clockrate(struct ath5k_hw *ah); + + /* DMA Related Functions */ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); @@ -1171,26 +1180,28 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); +/* Init function */ +void ath5k_hw_dma_init(struct ath5k_hw *ah); /* EEPROM access functions */ int ath5k_eeprom_init(struct ath5k_hw *ah); void ath5k_eeprom_detach(struct ath5k_hw *ah); int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); + /* Protocol Control Unit Functions */ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); -/* BSSID Functions */ +/* RX filter control*/ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); void ath5k_hw_set_bssid(struct ath5k_hw *ah); void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); -/* Receive start/stop functions */ -void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); -void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); -/* RX Filter functions */ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); +/* Receive (DRU) start/stop functions */ +void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); +void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); /* Beacon control functions */ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); @@ -1199,10 +1210,9 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); /* ACK bit rate */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); -/* Clock rate related functions */ -unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); -unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); -void ath5k_hw_set_clockrate(struct ath5k_hw *ah); +/* Init function */ +void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, + u8 mode); /* Queue Control Unit, DFS Control Unit Functions */ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, @@ -1216,6 +1226,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); +/* Init function */ +int ath5k_hw_init_queues(struct ath5k_hw *ah); /* Hardware Descriptor Functions */ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); @@ -1225,6 +1237,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3); + /* GPIO Functions */ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); @@ -1234,11 +1247,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); -/* rfkill Functions */ + +/* RFkill Functions */ void ath5k_rfkill_hw_start(struct ath5k_hw *ah); void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); -/* Misc functions */ + +/* Misc functions TODO: Cleanup */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah); int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, @@ -1246,19 +1261,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah, int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); + /* Initial register settings functions */ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); -/* Initialize RF */ -int ath5k_hw_rfregs_init(struct ath5k_hw *ah, - struct ieee80211_channel *channel, - unsigned int mode); -int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); + +/* PHY functions */ +/* Misc PHY functions */ +u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); +int ath5k_hw_phy_disable(struct ath5k_hw *ah); +/* Gain_F optimization */ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); /* PHY/RF channel functions */ bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); -int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); /* PHY calibration */ void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, @@ -1267,18 +1283,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah); /* Spur mitigation */ bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, struct ieee80211_channel *channel); -void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, - struct ieee80211_channel *channel); -/* Misc PHY functions */ -u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); -int ath5k_hw_phy_disable(struct ath5k_hw *ah); /* Antenna control */ void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); /* TX power setup */ -int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 ee_mode, u8 txpower); int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); +/* Init function */ +int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, + u8 mode, u8 ee_mode, u8 freq); /* * Functions used internaly diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 43244382f213..16b44ff7dd3e 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -26,9 +26,10 @@ #include "debug.h" #include "base.h" -/* - * TX Descriptors - */ + +/************************\ +* TX Control descriptors * +\************************/ /* * Initialize the 2-word tx control descriptor on 5210/5211 @@ -335,6 +336,11 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, return 0; } + +/***********************\ +* TX Status descriptors * +\***********************/ + /* * Proccess the tx status descriptor on 5210/5211 */ @@ -476,9 +482,10 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, return 0; } -/* - * RX Descriptors - */ + +/****************\ +* RX Descriptors * +\****************/ /* * Initialize an rx control descriptor @@ -666,6 +673,11 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, return 0; } + +/********\ +* Attach * +\********/ + /* * Init function pointers inside ath5k_hw struct */ diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 923c9ca5c4f0..b991b0585090 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -37,6 +37,7 @@ #include "debug.h" #include "base.h" + /*********\ * Receive * \*********/ @@ -427,6 +428,7 @@ done: return ret; } + /*******************\ * Interrupt masking * \*******************/ @@ -688,3 +690,46 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask) return old_mask; } + +/********************\ + Init/Stop functions +\********************/ + +/** + * ath5k_hw_dma_init - Initialize DMA unit + * + * @ah: The &struct ath5k_hw + * + * Set DMA size and pre-enable interrupts + * (driver handles tx/rx buffer setup and + * dma start/stop) + * + * XXX: Save/restore RXDP/TXDP registers ? + */ +void ath5k_hw_dma_init(struct ath5k_hw *ah) +{ + /* + * Set Rx/Tx DMA Configuration + * + * Set standard DMA size (128). Note that + * a DMA size of 512 causes rx overruns and tx errors + * on pci-e cards (tested on 5424 but since rx overruns + * also occur on 5416/5418 with madwifi we set 128 + * for all PCI-E cards to be safe). + * + * XXX: need to check 5210 for this + * TODO: Check out tx triger level, it's always 64 on dumps but I + * guess we can tweak it and see how it goes ;-) + */ + if (ah->ah_version != AR5K_AR5210) { + AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); + AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, + AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); + } + + /* Pre-enable interrupts on 5211/5212*/ + if (ah->ah_version != AR5K_AR5210) + ath5k_hw_set_imr(ah, ah->ah_imr); + +} diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 39722dd73e43..033eab9ad4e7 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -28,6 +28,43 @@ #include "debug.h" #include "base.h" + +/******************\ +* Helper functions * +\******************/ + +/* + * Translate binary channel representation in EEPROM to frequency + */ +static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, + unsigned int mode) +{ + u16 val; + + if (bin == AR5K_EEPROM_CHANNEL_DIS) + return bin; + + if (mode == AR5K_EEPROM_MODE_11A) { + if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) + val = (5 * bin) + 4800; + else + val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : + (bin * 10) + 5100; + } else { + if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) + val = bin + 2300; + else + val = bin + 2400; + } + + return val; +} + + +/*********\ +* Parsers * +\*********/ + /* * Read from eeprom */ @@ -62,33 +99,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) return -ETIMEDOUT; } -/* - * Translate binary channel representation in EEPROM to frequency - */ -static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, - unsigned int mode) -{ - u16 val; - - if (bin == AR5K_EEPROM_CHANNEL_DIS) - return bin; - - if (mode == AR5K_EEPROM_MODE_11A) { - if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) - val = (5 * bin) + 4800; - else - val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : - (bin * 10) + 5100; - } else { - if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) - val = bin + 2300; - else - val = bin + 2400; - } - - return val; -} - /* * Initialize eeprom & capabilities structs */ @@ -647,6 +657,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) return 0; } + /* * Read power calibration for RF5111 chips * @@ -1514,6 +1525,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) return 0; } + /* * Read per channel calibration info from EEPROM * @@ -1607,15 +1619,6 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) return 0; } -void -ath5k_eeprom_detach(struct ath5k_hw *ah) -{ - u8 mode; - - for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) - ath5k_eeprom_free_pcal_info(ah, mode); -} - /* Read conformance test limits used for regulatory control */ static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) @@ -1756,6 +1759,44 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) return ret; } +/* + * Read the MAC address from eeprom + */ +int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + u8 mac_d[ETH_ALEN] = {}; + u32 total, offset; + u16 data; + int octet, ret; + + ret = ath5k_hw_eeprom_read(ah, 0x20, &data); + if (ret) + return ret; + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { + ret = ath5k_hw_eeprom_read(ah, offset, &data); + if (ret) + return ret; + + total += data; + mac_d[octet + 1] = data & 0xff; + mac_d[octet] = data >> 8; + octet += 2; + } + + if (!total || total == 3 * 0xffff) + return -EINVAL; + + memcpy(mac, mac_d, ETH_ALEN); + + return 0; +} + + +/***********************\ +* Init/Detach functions * +\***********************/ + /* * Initialize eeprom data structure */ @@ -1787,35 +1828,11 @@ ath5k_eeprom_init(struct ath5k_hw *ah) return 0; } -/* - * Read the MAC address from eeprom - */ -int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +void +ath5k_eeprom_detach(struct ath5k_hw *ah) { - u8 mac_d[ETH_ALEN] = {}; - u32 total, offset; - u16 data; - int octet, ret; - - ret = ath5k_hw_eeprom_read(ah, 0x20, &data); - if (ret) - return ret; - - for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - ret = ath5k_hw_eeprom_read(ah, offset, &data); - if (ret) - return ret; - - total += data; - mac_d[octet + 1] = data & 0xff; - mac_d[octet] = data >> 8; - octet += 2; - } - - if (!total || total == 3 * 0xffff) - return -EINVAL; - - memcpy(mac, mac_d, ETH_ALEN); + u8 mode; - return 0; + for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) + ath5k_eeprom_free_pcal_info(ah, mode); } diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 074b4c644399..2c2ea1539849 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -32,86 +32,47 @@ #include "base.h" /*******************\ -* Generic functions * +* Helper functions * \*******************/ /** - * ath5k_hw_set_opmode - Set PCU operating mode + * ath5k_hw_get_default_slottime - Get the default slot time for current mode * * @ah: The &struct ath5k_hw - * @op_mode: &enum nl80211_iftype operating mode - * - * Initialize PCU for the various operating modes (AP/STA etc) */ -int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) +static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) { - struct ath_common *common = ath5k_hw_common(ah); - u32 pcu_reg, beacon_reg, low_id, high_id; - - ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); - - /* Preserve rest settings */ - pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; - pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP - | AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); - - beacon_reg = 0; + struct ieee80211_channel *channel = ah->ah_current_channel; - switch (op_mode) { - case NL80211_IFTYPE_ADHOC: - pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; - beacon_reg |= AR5K_BCR_ADHOC; - if (ah->ah_version == AR5K_AR5210) - pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; - else - AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); - break; + if (channel->hw_value & CHANNEL_TURBO) + return 6; /* both turbo modes */ - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_MESH_POINT: - pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE; - beacon_reg |= AR5K_BCR_AP; - if (ah->ah_version == AR5K_AR5210) - pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; - else - AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); - break; + if (channel->hw_value & CHANNEL_CCK) + return 20; /* 802.11b */ - case NL80211_IFTYPE_STATION: - pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - AR5K_STA_ID1_PWR_SV : 0); - case NL80211_IFTYPE_MONITOR: - pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - AR5K_STA_ID1_NO_PSPOLL : 0); - break; + return 9; /* 802.11 a/g */ +} - default: - return -EINVAL; - } +/** + * ath5k_hw_get_default_sifs - Get the default SIFS for current mode + * + * @ah: The &struct ath5k_hw + */ +static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) +{ + struct ieee80211_channel *channel = ah->ah_current_channel; - /* - * Set PCU registers - */ - low_id = get_unaligned_le32(common->macaddr); - high_id = get_unaligned_le16(common->macaddr + 4); - ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); - ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); + if (channel->hw_value & CHANNEL_TURBO) + return 8; /* both turbo modes */ - /* - * Set Beacon Control Register on 5210 - */ - if (ah->ah_version == AR5K_AR5210) - ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); + if (channel->hw_value & CHANNEL_5GHZ) + return 16; /* 802.11a */ - return 0; + return 10; /* 802.11 b/g */ } /** - * ath5k_hw_update - Update MIB counters (mac layer statistics) + * ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics) * * @ah: The &struct ath5k_hw * @@ -163,6 +124,82 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) * ACK/CTS Timeouts * \******************/ +/* + * index into rates for control rates, we can set it up like this because + * this is only used for AR5212 and we know it supports G mode + */ +static const unsigned int control_rates[] = + { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; + +/** + * ath5k_hw_write_rate_duration - fill rate code to duration table + * + * @ah: the &struct ath5k_hw + * @mode: one of enum ath5k_driver_mode + * + * Write the rate code to duration table upon hw reset. This is a helper for + * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on + * the hardware, based on current mode, for each rate. The rates which are + * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have + * different rate code so we write their value twice (one for long preamble + * and one for short). + * + * Note: Band doesn't matter here, if we set the values for OFDM it works + * on both a and g modes. So all we have to do is set values for all g rates + * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ + * quarter rate mode, we need to use another set of bitrates (that's why we + * need the mode parameter) but we don't handle these proprietary modes yet. + */ +static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, + unsigned int mode) +{ + struct ath5k_softc *sc = ah->ah_sc; + struct ieee80211_rate *rate; + unsigned int i; + + /* Write rate duration table */ + for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { + u32 reg; + u16 tx_time; + + rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; + + /* Set ACK timeout */ + reg = AR5K_RATE_DUR(rate->hw_value); + + /* An ACK frame consists of 10 bytes. If you add the FCS, + * which ieee80211_generic_frame_duration() adds, + * its 14 bytes. Note we use the control rate and not the + * actual rate for this rate. See mac80211 tx.c + * ieee80211_duration() for a brief description of + * what rate we should choose to TX ACKs. */ + tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, + NULL, 10, rate)); + + ath5k_hw_reg_write(ah, tx_time, reg); + + if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) + continue; + + /* + * We're not distinguishing short preamble here, + * This is true, all we'll get is a longer value here + * which is not necessarilly bad. We could use + * export ieee80211_frame_duration() but that needs to be + * fixed first to be properly used by mac802111 drivers: + * + * - remove erp stuff and let the routine figure ofdm + * erp rates + * - remove passing argument ieee80211_local as + * drivers don't have access to it + * - move drivers using ieee80211_generic_frame_duration() + * to this + */ + ath5k_hw_reg_write(ah, tx_time, + reg + (AR5K_SET_SHORT_PREAMBLE << 2)); + } +} + /** * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU * @@ -199,88 +236,10 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) return 0; } -/** - * ath5k_hw_htoclock - Translate usec to hw clock units - * - * @ah: The &struct ath5k_hw - * @usec: value in microseconds - */ -unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) -{ - struct ath_common *common = ath5k_hw_common(ah); - return usec * common->clockrate; -} - -/** - * ath5k_hw_clocktoh - Translate hw clock units to usec - * @clock: value in hw clock units - */ -unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) -{ - struct ath_common *common = ath5k_hw_common(ah); - return clock / common->clockrate; -} - -/** - * ath5k_hw_set_clockrate - Set common->clockrate for the current channel - * - * @ah: The &struct ath5k_hw - */ -void ath5k_hw_set_clockrate(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - struct ath_common *common = ath5k_hw_common(ah); - int clock; - - if (channel->hw_value & CHANNEL_5GHZ) - clock = 40; /* 802.11a */ - else if (channel->hw_value & CHANNEL_CCK) - clock = 22; /* 802.11b */ - else - clock = 44; /* 802.11g */ - - /* Clock rate in turbo modes is twice the normal rate */ - if (channel->hw_value & CHANNEL_TURBO) - clock *= 2; - - common->clockrate = clock; -} - -/** - * ath5k_hw_get_default_slottime - Get the default slot time for current mode - * - * @ah: The &struct ath5k_hw - */ -static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - - if (channel->hw_value & CHANNEL_TURBO) - return 6; /* both turbo modes */ - - if (channel->hw_value & CHANNEL_CCK) - return 20; /* 802.11b */ - - return 9; /* 802.11 a/g */ -} - -/** - * ath5k_hw_get_default_sifs - Get the default SIFS for current mode - * - * @ah: The &struct ath5k_hw - */ -static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - - if (channel->hw_value & CHANNEL_TURBO) - return 8; /* both turbo modes */ - - if (channel->hw_value & CHANNEL_5GHZ) - return 16; /* 802.11a */ - return 10; /* 802.11 b/g */ -} +/*******************\ +* RX filter Control * +\*******************/ /** * ath5k_hw_set_lladdr - Set station id @@ -362,39 +321,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) ath_hw_setbssidmask(common); } -/************\ -* RX Control * -\************/ - -/** - * ath5k_hw_start_rx_pcu - Start RX engine - * - * @ah: The &struct ath5k_hw - * - * Starts RX engine on PCU so that hw can process RXed frames - * (ACK etc). - * - * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma - */ -void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) -{ - AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); -} - -/** - * at5k_hw_stop_rx_pcu - Stop RX engine - * - * @ah: The &struct ath5k_hw - * - * Stops RX engine on PCU - * - * TODO: Detach ANI here - */ -void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) -{ - AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); -} - /* * Set multicast filter */ @@ -761,3 +687,161 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) ah->ah_coverage_class = coverage_class; } + +/***************************\ +* Init/Start/Stop functions * +\***************************/ + +/** + * ath5k_hw_start_rx_pcu - Start RX engine + * + * @ah: The &struct ath5k_hw + * + * Starts RX engine on PCU so that hw can process RXed frames + * (ACK etc). + * + * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma + */ +void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) +{ + AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); +} + +/** + * at5k_hw_stop_rx_pcu - Stop RX engine + * + * @ah: The &struct ath5k_hw + * + * Stops RX engine on PCU + */ +void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) +{ + AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); +} + +/** + * ath5k_hw_set_opmode - Set PCU operating mode + * + * @ah: The &struct ath5k_hw + * @op_mode: &enum nl80211_iftype operating mode + * + * Configure PCU for the various operating modes (AP/STA etc) + */ +int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) +{ + struct ath_common *common = ath5k_hw_common(ah); + u32 pcu_reg, beacon_reg, low_id, high_id; + + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); + + /* Preserve rest settings */ + pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; + pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP + | AR5K_STA_ID1_KEYSRCH_MODE + | (ah->ah_version == AR5K_AR5210 ? + (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); + + beacon_reg = 0; + + switch (op_mode) { + case NL80211_IFTYPE_ADHOC: + pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; + beacon_reg |= AR5K_BCR_ADHOC; + if (ah->ah_version == AR5K_AR5210) + pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; + else + AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: + pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE; + beacon_reg |= AR5K_BCR_AP; + if (ah->ah_version == AR5K_AR5210) + pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; + else + AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); + break; + + case NL80211_IFTYPE_STATION: + pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE + | (ah->ah_version == AR5K_AR5210 ? + AR5K_STA_ID1_PWR_SV : 0); + case NL80211_IFTYPE_MONITOR: + pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE + | (ah->ah_version == AR5K_AR5210 ? + AR5K_STA_ID1_NO_PSPOLL : 0); + break; + + default: + return -EINVAL; + } + + /* + * Set PCU registers + */ + low_id = get_unaligned_le32(common->macaddr); + high_id = get_unaligned_le16(common->macaddr + 4); + ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); + ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); + + /* + * Set Beacon Control Register on 5210 + */ + if (ah->ah_version == AR5K_AR5210) + ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); + + return 0; +} + +void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, + u8 mode) +{ + /* Set bssid and bssid mask */ + ath5k_hw_set_bssid(ah); + + /* Set PCU config */ + ath5k_hw_set_opmode(ah, op_mode); + + /* Write rate duration table only on AR5212 and if + * virtual interface has already been brought up + * XXX: rethink this after new mode changes to + * mac80211 are integrated */ + if (ah->ah_version == AR5K_AR5212 && + ah->ah_sc->nvifs) + ath5k_hw_write_rate_duration(ah, mode); + + /* Set RSSI/BRSSI thresholds + * + * Note: If we decide to set this value + * dynamicaly, have in mind that when AR5K_RSSI_THR + * register is read it might return 0x40 if we haven't + * wrote anything to it plus BMISS RSSI threshold is zeroed. + * So doing a save/restore procedure here isn't the right + * choice. Instead store it on ath5k_hw */ + ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | + AR5K_TUNE_BMISS_THRES << + AR5K_RSSI_THR_BMISS_S), + AR5K_RSSI_THR); + + /* MIC QoS support */ + if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { + ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); + ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); + } + + /* QoS NOACK Policy */ + if (ah->ah_version == AR5K_AR5212) { + ath5k_hw_reg_write(ah, + AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | + AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | + AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), + AR5K_QOS_NOACK); + } + + /* Restore slot time and ACK timeouts */ + if (ah->ah_coverage_class > 0) + ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); + + return; +} diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6b43f535ff53..1c41fa837451 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -29,6 +29,95 @@ #include "rfbuffer.h" #include "rfgain.h" + +/******************\ +* Helper functions * +\******************/ + +/* + * Get the PHY Chip revision + */ +u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) +{ + unsigned int i; + u32 srev; + u16 ret; + + /* + * Set the radio chip access register + */ + switch (chan) { + case CHANNEL_2GHZ: + ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); + break; + case CHANNEL_5GHZ: + ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); + break; + default: + return 0; + } + + mdelay(2); + + /* ...wait until PHY is ready and read the selected radio revision */ + ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); + + for (i = 0; i < 8; i++) + ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); + + if (ah->ah_version == AR5K_AR5210) { + srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; + ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; + } else { + srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; + ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | + ((srev & 0x0f) << 4), 8); + } + + /* Reset to the 5GHz mode */ + ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); + + return ret; +} + +/* + * Check if a channel is supported + */ +bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) +{ + /* Check if the channel is in our supported range */ + if (flags & CHANNEL_2GHZ) { + if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && + (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) + return true; + } else if (flags & CHANNEL_5GHZ) + if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && + (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) + return true; + + return false; +} + +bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, + struct ieee80211_channel *channel) +{ + u8 refclk_freq; + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) + refclk_freq = 40; + else + refclk_freq = 32; + + if ((channel->center_freq % refclk_freq != 0) && + ((channel->center_freq % refclk_freq < 10) || + (channel->center_freq % refclk_freq > 22))) + return true; + else + return false; +} + /* * Used to modify RF Banks before writing them to AR5K_RF_BUFFER */ @@ -110,6 +199,78 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, return data; } +/** + * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 + * + * @ah: the &struct ath5k_hw + * @channel: the currently set channel upon reset + * + * Write the delta slope coefficient (used on pilot tracking ?) for OFDM + * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init. + * + * Since delta slope is floating point we split it on its exponent and + * mantissa and provide these values on hw. + * + * For more infos i think this patent is related + * http://www.freepatentsonline.com/7184495.html + */ +static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, + struct ieee80211_channel *channel) +{ + /* Get exponent and mantissa and set it */ + u32 coef_scaled, coef_exp, coef_man, + ds_coef_exp, ds_coef_man, clock; + + BUG_ON(!(ah->ah_version == AR5K_AR5212) || + !(channel->hw_value & CHANNEL_OFDM)); + + /* Get coefficient + * ALGO: coef = (5 * clock / carrier_freq) / 2 + * we scale coef by shifting clock value by 24 for + * better precision since we use integers */ + /* TODO: Half/quarter rate */ + clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40; + coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; + + /* Get exponent + * ALGO: coef_exp = 14 - highest set bit position */ + coef_exp = ilog2(coef_scaled); + + /* Doesn't make sense if it's zero*/ + if (!coef_scaled || !coef_exp) + return -EINVAL; + + /* Note: we've shifted coef_scaled by 24 */ + coef_exp = 14 - (coef_exp - 24); + + + /* Get mantissa (significant digits) + * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ + coef_man = coef_scaled + + (1 << (24 - coef_exp - 1)); + + /* Calculate delta slope coefficient exponent + * and mantissa (remove scaling) and set them on hw */ + ds_coef_man = coef_man >> (24 - coef_exp); + ds_coef_exp = coef_exp - 16; + + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, + AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, + AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); + + return 0; +} + +int ath5k_hw_phy_disable(struct ath5k_hw *ah) +{ + /*Just a try M.F.*/ + ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); + + return 0; +} + + /**********************\ * RF Gain optimization * \**********************/ @@ -436,7 +597,7 @@ done: /* Write initial RF gain table to set the RF sensitivity * this one works on all RF chips and has nothing to do * with gain_F calibration */ -int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) +static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) { const struct ath5k_ini_rfgain *ath5k_rfg; unsigned int i, size; @@ -494,12 +655,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) * RF Registers setup * \********************/ - /* * Setup RF registers by writing RF buffer on hw */ -int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - unsigned int mode) +static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, + struct ieee80211_channel *channel, unsigned int mode) { const struct ath5k_rf_reg *rf_regs; const struct ath5k_ini_rfbuffer *ini_rfb; @@ -821,24 +981,6 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, PHY/RF channel functions \**************************/ -/* - * Check if a channel is supported - */ -bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) -{ - /* Check if the channel is in our supported range */ - if (flags & CHANNEL_2GHZ) { - if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && - (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) - return true; - } else if (flags & CHANNEL_5GHZ) - if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && - (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) - return true; - - return false; -} - /* * Convertion needed for RF5110 */ @@ -1045,7 +1187,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, /* * Set a channel on the radio chip */ -int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) +static int ath5k_hw_channel(struct ath5k_hw *ah, + struct ieee80211_channel *channel) { int ret; /* @@ -1419,31 +1562,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, return ret; } + /***************************\ * Spur mitigation functions * \***************************/ -bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u8 refclk_freq; - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - refclk_freq = 40; - else - refclk_freq = 32; - - if ((channel->center_freq % refclk_freq != 0) && - ((channel->center_freq % refclk_freq < 10) || - (channel->center_freq % refclk_freq > 22))) - return true; - else - return false; -} - -void +static void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, struct ieee80211_channel *channel) { @@ -1666,63 +1790,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, } } -/********************\ - Misc PHY functions -\********************/ - -int ath5k_hw_phy_disable(struct ath5k_hw *ah) -{ - /*Just a try M.F.*/ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); - - return 0; -} - -/* - * Get the PHY Chip revision - */ -u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) -{ - unsigned int i; - u32 srev; - u16 ret; - - /* - * Set the radio chip access register - */ - switch (chan) { - case CHANNEL_2GHZ: - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); - break; - case CHANNEL_5GHZ: - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); - break; - default: - return 0; - } - - mdelay(2); - - /* ...wait until PHY is ready and read the selected radio revision */ - ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); - - for (i = 0; i < 8; i++) - ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); - - if (ah->ah_version == AR5K_AR5210) { - srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; - ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; - } else { - srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; - ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | - ((srev & 0x0f) << 4), 8); - } - - /* Reset to the 5GHz mode */ - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); - - return ret; -} /*****************\ * Antenna control * @@ -2984,7 +3051,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, /* * Set transmission power */ -int +static int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower) { @@ -3108,3 +3175,176 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) return ath5k_hw_txpower(ah, channel, ee_mode, txpower); } + +/*************\ + Init function +\*************/ + +int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, + u8 mode, u8 ee_mode, u8 freq) +{ + int ret, i; + u32 phy_tst1; + + ret = 0; + + /* + * 5211/5212 Specific + */ + if (ah->ah_version != AR5K_AR5210) { + + /* + * Write initial RF gain settings + * This should work for both 5111/5112 + */ + ret = ath5k_hw_rfgain_init(ah, freq); + if (ret) + return ret; + + mdelay(1); + + /* + * Set TX power + */ + ret = ath5k_hw_txpower(ah, channel, ee_mode, + ah->ah_txpower.txp_max_pwr / 2); + if (ret) + return ret; + + /* + * Write RF buffer + */ + ret = ath5k_hw_rfregs_init(ah, channel, mode); + if (ret) + return ret; + + + /* Write OFDM timings on 5212*/ + if (ah->ah_version == AR5K_AR5212 && + channel->hw_value & CHANNEL_OFDM) { + + ret = ath5k_hw_write_ofdm_timings(ah, channel); + if (ret) + return ret; + + /* Spur info is available only from EEPROM versions + * greater than 5.3, but the EEPROM routines will use + * static values for older versions */ + if (ah->ah_mac_srev >= AR5K_SREV_AR5424) + ath5k_hw_set_spur_mitigation_filter(ah, + channel); + } + + /*Enable/disable 802.11b mode on 5111 + (enable 2111 frequency converter + CCK)*/ + if (ah->ah_radio == AR5K_RF5111) { + if (mode == AR5K_MODE_11B) + AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_B_MODE); + else + AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_B_MODE); + } + + } else { + /* + * For 5210 we do all initialization using + * initvals, so we don't have to modify + * any settings (5210 also only supports + * a/aturbo modes) + */ + mdelay(1); + /* Disable phy and wait */ + ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); + mdelay(1); + } + + /* Set channel on PHY */ + ret = ath5k_hw_channel(ah, channel); + if (ret) + return ret; + + /* + * Enable the PHY and wait until completion + * This includes BaseBand and Synthesizer + * activation. + */ + ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); + + /* + * On 5211+ read activation -> rx delay + * and use it. + * + * TODO: Half/quarter rate support + */ + if (ah->ah_version != AR5K_AR5210) { + u32 delay; + delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & + AR5K_PHY_RX_DELAY_M; + delay = (channel->hw_value & CHANNEL_CCK) ? + ((delay << 2) / 22) : (delay / 10); + + udelay(100 + (2 * delay)); + } else { + mdelay(1); + } + + /* + * Perform ADC test to see if baseband is ready + * Set TX hold and check ADC test register + */ + phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); + ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); + for (i = 0; i <= 20; i++) { + if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) + break; + udelay(200); + } + ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); + + /* + * Start automatic gain control calibration + * + * During AGC calibration RX path is re-routed to + * a power detector so we don't receive anything. + * + * This method is used to calibrate some static offsets + * used together with on-the fly I/Q calibration (the + * one performed via ath5k_hw_phy_calibrate), which doesn't + * interrupt rx path. + * + * While rx path is re-routed to the power detector we also + * start a noise floor calibration to measure the + * card's noise floor (the noise we measure when we are not + * transmitting or receiving anything). + * + * If we are in a noisy environment, AGC calibration may time + * out and/or noise floor calibration might timeout. + */ + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF); + + /* At the same time start I/Q calibration for QAM constellation + * -no need for CCK- */ + ah->ah_calibration = false; + if (!(mode == AR5K_MODE_11B)) { + ah->ah_calibration = true; + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, + AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, + AR5K_PHY_IQ_RUN); + } + + /* Wait for gain calibration to finish (we check for I/Q calibration + * during ath5k_phy_calibrate) */ + if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_CAL, 0, false)) { + ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", + channel->center_freq); + } + + /* Restore antenna mode */ + ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); + + return ret; +} diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 84c717ded1c5..52eee34fd54d 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -25,14 +25,52 @@ Queue Control Unit, DFS Control Unit Functions #include "debug.h" #include "base.h" + +/******************\ +* Helper functions * +\******************/ + /* - * Get properties for a transmit queue + * Get number of pending frames + * for a specific queue [5211+] */ -int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, - struct ath5k_txq_info *queue_info) +u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) { - memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); - return 0; + u32 pending; + AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); + + /* Return if queue is declared inactive */ + if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) + return false; + + /* XXX: How about AR5K_CFG_TXCNT ? */ + if (ah->ah_version == AR5K_AR5210) + return false; + + pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)); + pending &= AR5K_QCU_STS_FRMPENDCNT; + + /* It's possible to have no frames pending even if TXE + * is set. To indicate that q has not stopped return + * true */ + if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) + return true; + + return pending; +} + +/* + * Set a transmit queue inactive + */ +void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) +{ + if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) + return; + + /* This queue will be skipped in further operations */ + ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; + /*For SIMR setup*/ + AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); } /* @@ -49,6 +87,16 @@ static u16 ath5k_cw_validate(u16 cw_req) return cw; } +/* + * Get properties for a transmit queue + */ +int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, + struct ath5k_txq_info *queue_info) +{ + memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); + return 0; +} + /* * Set properties for a transmit queue */ @@ -172,48 +220,10 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, return queue; } -/* - * Get number of pending frames - * for a specific queue [5211+] - */ -u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) -{ - u32 pending; - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* Return if queue is declared inactive */ - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return false; - - /* XXX: How about AR5K_CFG_TXCNT ? */ - if (ah->ah_version == AR5K_AR5210) - return false; - - pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)); - pending &= AR5K_QCU_STS_FRMPENDCNT; - - /* It's possible to have no frames pending even if TXE - * is set. To indicate that q has not stopped return - * true */ - if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) - return true; - - return pending; -} - -/* - * Set a transmit queue inactive - */ -void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) -{ - if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) - return; - /* This queue will be skipped in further operations */ - ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; - /*For SIMR setup*/ - AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); -} +/*******************************\ +* Single QCU/DCU initialization * +\*******************************/ /* * Set DFS properties for a transmit queue on DCU @@ -512,6 +522,11 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) return 0; } + +/**************************\ +* Global QCU/DCU functions * +\**************************/ + /* * Set slot time on DCU */ @@ -530,3 +545,26 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) return 0; } +int ath5k_hw_init_queues(struct ath5k_hw *ah) +{ + int i, ret; + + /* TODO: HW Compression support for data queues */ + /* TODO: Burst prefetch for data queues */ + + /* + * Reset queues and start beacon timers at the end of the reset routine + * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping + * Note: If we want we can assign multiple qcus on one dcu. + */ + for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { + ret = ath5k_hw_reset_tx_queue(ah, i); + if (ret) { + ATH5K_ERR(ah->ah_sc, + "failed to reset TX queue #%d\n", i); + return ret; + } + } + + return 0; +} diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 5b179d01f97d..9dd5792780ba 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -32,6 +32,11 @@ #include "base.h" #include "debug.h" + +/******************\ +* Helper functions * +\******************/ + /* * Check if a register write has been completed */ @@ -53,146 +58,165 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, return (i <= 0) ? -EAGAIN : 0; } + +/*************************\ +* Clock related functions * +\*************************/ + /** - * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 - * - * @ah: the &struct ath5k_hw - * @channel: the currently set channel upon reset + * ath5k_hw_htoclock - Translate usec to hw clock units * - * Write the delta slope coefficient (used on pilot tracking ?) for OFDM - * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset(). - * - * Since delta slope is floating point we split it on its exponent and - * mantissa and provide these values on hw. - * - * For more infos i think this patent is related - * http://www.freepatentsonline.com/7184495.html + * @ah: The &struct ath5k_hw + * @usec: value in microseconds */ -static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, - struct ieee80211_channel *channel) +unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) { - /* Get exponent and mantissa and set it */ - u32 coef_scaled, coef_exp, coef_man, - ds_coef_exp, ds_coef_man, clock; - - BUG_ON(!(ah->ah_version == AR5K_AR5212) || - !(channel->hw_value & CHANNEL_OFDM)); - - /* Get coefficient - * ALGO: coef = (5 * clock / carrier_freq) / 2 - * we scale coef by shifting clock value by 24 for - * better precision since we use integers */ - /* TODO: Half/quarter rate */ - clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40; - coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; - - /* Get exponent - * ALGO: coef_exp = 14 - highest set bit position */ - coef_exp = ilog2(coef_scaled); - - /* Doesn't make sense if it's zero*/ - if (!coef_scaled || !coef_exp) - return -EINVAL; - - /* Note: we've shifted coef_scaled by 24 */ - coef_exp = 14 - (coef_exp - 24); + struct ath_common *common = ath5k_hw_common(ah); + return usec * common->clockrate; +} +/** + * ath5k_hw_clocktoh - Translate hw clock units to usec + * @clock: value in hw clock units + */ +unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) +{ + struct ath_common *common = ath5k_hw_common(ah); + return clock / common->clockrate; +} - /* Get mantissa (significant digits) - * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ - coef_man = coef_scaled + - (1 << (24 - coef_exp - 1)); +/** + * ath5k_hw_set_clockrate - Set common->clockrate for the current channel + * + * @ah: The &struct ath5k_hw + */ +void ath5k_hw_set_clockrate(struct ath5k_hw *ah) +{ + struct ieee80211_channel *channel = ah->ah_current_channel; + struct ath_common *common = ath5k_hw_common(ah); + int clock; - /* Calculate delta slope coefficient exponent - * and mantissa (remove scaling) and set them on hw */ - ds_coef_man = coef_man >> (24 - coef_exp); - ds_coef_exp = coef_exp - 16; + if (channel->hw_value & CHANNEL_5GHZ) + clock = 40; /* 802.11a */ + else if (channel->hw_value & CHANNEL_CCK) + clock = 22; /* 802.11b */ + else + clock = 44; /* 802.11g */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, - AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, - AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); + /* Clock rate in turbo modes is twice the normal rate */ + if (channel->hw_value & CHANNEL_TURBO) + clock *= 2; - return 0; + common->clockrate = clock; } - /* - * index into rates for control rates, we can set it up like this because - * this is only used for AR5212 and we know it supports G mode - */ -static const unsigned int control_rates[] = - { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; - -/** - * ath5k_hw_write_rate_duration - fill rate code to duration table - * - * @ah: the &struct ath5k_hw - * @mode: one of enum ath5k_driver_mode - * - * Write the rate code to duration table upon hw reset. This is a helper for - * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on - * the hardware, based on current mode, for each rate. The rates which are - * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have - * different rate code so we write their value twice (one for long preample - * and one for short). + * If there is an external 32KHz crystal available, use it + * as ref. clock instead of 32/40MHz clock and baseband clocks + * to save power during sleep or restore normal 32/40MHz + * operation. * - * Note: Band doesn't matter here, if we set the values for OFDM it works - * on both a and g modes. So all we have to do is set values for all g rates - * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ - * quarter rate mode, we need to use another set of bitrates (that's why we - * need the mode parameter) but we don't handle these proprietary modes yet. + * XXX: When operating on 32KHz certain PHY registers (27 - 31, + * 123 - 127) require delay on access. */ -static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, - unsigned int mode) +static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) { - struct ath5k_softc *sc = ah->ah_sc; - struct ieee80211_rate *rate; - unsigned int i; + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + u32 scal, spending, usec32; + + /* Only set 32KHz settings if we have an external + * 32KHz crystal present */ + if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) || + AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) && + enable) { + + /* 1 usec/cycle */ + AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1); + /* Set up tsf increment on each cycle */ + AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61); + + /* Set baseband sleep control registers + * and sleep control rate */ + ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) + spending = 0x14; + else + spending = 0x18; + ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { + ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT); + ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL); + ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK); + ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY); + AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, + AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02); + } else { + ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT); + ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL); + ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK); + ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY); + AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, + AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03); + } - /* Write rate duration table */ - for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { - u32 reg; - u16 tx_time; + /* Enable sleep clock operation */ + AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, + AR5K_PCICFG_SLEEP_CLOCK_EN); - rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; + } else { - /* Set ACK timeout */ - reg = AR5K_RATE_DUR(rate->hw_value); + /* Disable sleep clock operation and + * restore default parameters */ + AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, + AR5K_PCICFG_SLEEP_CLOCK_EN); - /* An ACK frame consists of 10 bytes. If you add the FCS, - * which ieee80211_generic_frame_duration() adds, - * its 14 bytes. Note we use the control rate and not the - * actual rate for this rate. See mac80211 tx.c - * ieee80211_duration() for a brief description of - * what rate we should choose to TX ACKs. */ - tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, - NULL, 10, rate)); + AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, + AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); - ath5k_hw_reg_write(ah, tx_time, reg); + ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); + ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); - if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) - continue; + if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) + scal = AR5K_PHY_SCAL_32MHZ_2417; + else if (ee->ee_is_hb63) + scal = AR5K_PHY_SCAL_32MHZ_HB63; + else + scal = AR5K_PHY_SCAL_32MHZ; + ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); - /* - * We're not distinguishing short preamble here, - * This is true, all we'll get is a longer value here - * which is not necessarilly bad. We could use - * export ieee80211_frame_duration() but that needs to be - * fixed first to be properly used by mac802111 drivers: - * - * - remove erp stuff and let the routine figure ofdm - * erp rates - * - remove passing argument ieee80211_local as - * drivers don't have access to it - * - move drivers using ieee80211_generic_frame_duration() - * to this - */ - ath5k_hw_reg_write(ah, tx_time, - reg + (AR5K_SET_SHORT_PREAMBLE << 2)); + ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); + ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) + spending = 0x14; + else + spending = 0x18; + ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413)) + usec32 = 39; + else + usec32 = 31; + AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32); + + AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); } } + +/*********************\ +* Reset/Sleep control * +\*********************/ + /* * Reset chipset */ @@ -522,107 +546,10 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) return 0; } -/* - * If there is an external 32KHz crystal available, use it - * as ref. clock instead of 32/40MHz clock and baseband clocks - * to save power during sleep or restore normal 32/40MHz - * operation. - * - * XXX: When operating on 32KHz certain PHY registers (27 - 31, - * 123 - 127) require delay on access. - */ -static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 scal, spending, usec32; - - /* Only set 32KHz settings if we have an external - * 32KHz crystal present */ - if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) || - AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) && - enable) { - - /* 1 usec/cycle */ - AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1); - /* Set up tsf increment on each cycle */ - AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61); - - /* Set baseband sleep control registers - * and sleep control rate */ - ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - spending = 0x14; - else - spending = 0x18; - ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { - ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT); - ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL); - ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY); - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02); - } else { - ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT); - ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL); - ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY); - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03); - } - /* Enable sleep clock operation */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_EN); - - } else { - - /* Disable sleep clock operation and - * restore default parameters */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_EN); - - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); - - ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); - ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); - - if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) - scal = AR5K_PHY_SCAL_32MHZ_2417; - else if (ee->ee_is_hb63) - scal = AR5K_PHY_SCAL_32MHZ_HB63; - else - scal = AR5K_PHY_SCAL_32MHZ; - ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); - - ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - spending = 0x14; - else - spending = 0x18; - ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413)) - usec32 = 39; - else - usec32 = 31; - AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32); - - AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); - } -} +/**************************************\ +* Post-initvals register modifications * +\**************************************/ /* TODO: Half/Quarter rate */ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, @@ -705,7 +632,8 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); } - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { + if ((ah->ah_radio == AR5K_RF5112) && + (ah->ah_mac_srev < AR5K_SREV_AR5211)) { u32 usec_reg; /* 5311 has different tx/rx latency masks * from 5211, since we deal 5311 the same @@ -734,6 +662,10 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; s16 cck_ofdm_pwr_delta; + /* TODO: Add support for AR5210 EEPROM */ + if (ah->ah_version == AR5K_AR5210) + return; + /* Adjust power delta for channel 14 */ if (channel->center_freq == 2484) cck_ofdm_pwr_delta = @@ -870,15 +802,16 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); } -/* - * Main reset function - */ + +/*********************\ +* Main reset function * +\*********************/ + int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel) { struct ath_common *common = ath5k_hw_common(ah); u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; - u32 phy_tst1; u8 mode, freq, ee_mode; int i, ret; @@ -1026,93 +959,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, return ret; /* - * 5211/5212 Specific + * Tweak initval settings for revised + * chipsets and add some more config + * bits */ - if (ah->ah_version != AR5K_AR5210) { - - /* - * Write initial RF gain settings - * This should work for both 5111/5112 - */ - ret = ath5k_hw_rfgain_init(ah, freq); - if (ret) - return ret; - - mdelay(1); - - /* - * Tweak initval settings for revised - * chipsets and add some more config - * bits - */ - ath5k_hw_tweak_initval_settings(ah, channel); - - /* - * Set TX power - */ - ret = ath5k_hw_txpower(ah, channel, ee_mode, - ah->ah_txpower.txp_max_pwr / 2); - if (ret) - return ret; - - /* Write rate duration table only on AR5212 and if - * virtual interface has already been brought up - * XXX: rethink this after new mode changes to - * mac80211 are integrated */ - if (ah->ah_version == AR5K_AR5212 && - ah->ah_sc->nvifs) - ath5k_hw_write_rate_duration(ah, mode); - - /* - * Write RF buffer - */ - ret = ath5k_hw_rfregs_init(ah, channel, mode); - if (ret) - return ret; - - - /* Write OFDM timings on 5212*/ - if (ah->ah_version == AR5K_AR5212 && - channel->hw_value & CHANNEL_OFDM) { + ath5k_hw_tweak_initval_settings(ah, channel); - ret = ath5k_hw_write_ofdm_timings(ah, channel); - if (ret) - return ret; + /* Commit values from EEPROM */ + ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode); - /* Spur info is available only from EEPROM versions - * greater than 5.3, but the EEPROM routines will use - * static values for older versions */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424) - ath5k_hw_set_spur_mitigation_filter(ah, - channel); - } - - /*Enable/disable 802.11b mode on 5111 - (enable 2111 frequency converter + CCK)*/ - if (ah->ah_radio == AR5K_RF5111) { - if (mode == AR5K_MODE_11B) - AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_B_MODE); - else - AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_B_MODE); - } - - /* Commit values from EEPROM */ - ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode); - - } else { - /* - * For 5210 we do all initialization using - * initvals, so we don't have to modify - * any settings (5210 also only supports - * a/aturbo modes) - */ - mdelay(1); - /* Disable phy and wait */ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); - mdelay(1); - } /* * Restore saved values @@ -1156,193 +1011,38 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* - * Configure PCU + * Initialize PCU */ - - /* Restore bssid and bssid mask */ - ath5k_hw_set_bssid(ah); - - /* Set PCU config */ - ath5k_hw_set_opmode(ah, op_mode); + ath5k_hw_pcu_init(ah, op_mode, mode); /* Clear any pending interrupts * PISR/SISR Not available on 5210 */ if (ah->ah_version != AR5K_AR5210) ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); - /* Set RSSI/BRSSI thresholds - * - * Note: If we decide to set this value - * dynamically, keep in mind that when AR5K_RSSI_THR - * register is read, it might return 0x40 if we haven't - * written anything to it. Also, BMISS RSSI threshold is zeroed. - * So doing a save/restore procedure here isn't the right - * choice. Instead, store it in ath5k_hw */ - ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | - AR5K_TUNE_BMISS_THRES << - AR5K_RSSI_THR_BMISS_S), - AR5K_RSSI_THR); - - /* MIC QoS support */ - if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { - ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); - ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); - } - - /* QoS NOACK Policy */ - if (ah->ah_version == AR5K_AR5212) { - ath5k_hw_reg_write(ah, - AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | - AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | - AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), - AR5K_QOS_NOACK); - } - - /* - * Configure PHY + * Initialize PHY */ - - /* Set channel on PHY */ - ret = ath5k_hw_channel(ah, channel); - if (ret) + ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq); + if (ret) { + ATH5K_ERR(ah->ah_sc, + "failed to initialize PHY (%i) !\n", ret); return ret; - - /* - * Enable the PHY and wait until completion - * This includes BaseBand and Synthesizer - * activation. - */ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); - - /* - * On 5211+ read activation -> rx delay - * and use it. - * - * TODO: Half/quarter rate support - */ - if (ah->ah_version != AR5K_AR5210) { - u32 delay; - delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & - AR5K_PHY_RX_DELAY_M; - delay = (channel->hw_value & CHANNEL_CCK) ? - ((delay << 2) / 22) : (delay / 10); - - udelay(100 + (2 * delay)); - } else { - mdelay(1); - } - - /* - * Perform ADC test to see if baseband is ready - * Set TX hold and check ADC test register - */ - phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); - ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); - for (i = 0; i <= 20; i++) { - if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) - break; - udelay(200); - } - ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); - - /* - * Start automatic gain control calibration - * - * During AGC calibration RX path is re-routed to - * a power detector so we don't receive anything. - * - * This method is used to calibrate some static offsets - * used together with on-the fly I/Q calibration (the - * one performed via ath5k_hw_phy_calibrate), which doesn't - * interrupt rx path. - * - * While rx path is re-routed to the power detector we also - * start a noise floor calibration to measure the - * card's noise floor (the noise we measure when we are not - * transmitting or receiving anything). - * - * If we are in a noisy environment, AGC calibration may time - * out and/or noise floor calibration might timeout. - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF); - - /* At the same time start I/Q calibration for QAM constellation - * -no need for CCK- */ - ah->ah_calibration = false; - if (!(mode == AR5K_MODE_11B)) { - ah->ah_calibration = true; - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_RUN); - } - - /* Wait for gain calibration to finish (we check for I/Q calibration - * during ath5k_phy_calibrate) */ - if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL, 0, false)) { - ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", - channel->center_freq); } - /* Restore antenna mode */ - ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); - - /* Restore slot time and ACK timeouts */ - if (ah->ah_coverage_class > 0) - ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); - /* * Configure QCUs/DCUs */ + ret = ath5k_hw_init_queues(ah); + if (ret) + return ret; - /* TODO: HW Compression support for data queues */ - /* TODO: Burst prefetch for data queues */ - - /* - * Reset queues and start beacon timers at the end of the reset routine - * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping - * Note: If we want we can assign multiple qcus on one dcu. - */ - for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { - ret = ath5k_hw_reset_tx_queue(ah, i); - if (ret) { - ATH5K_ERR(ah->ah_sc, - "failed to reset TX queue #%d\n", i); - return ret; - } - } - - - /* - * Configure DMA/Interrupts - */ /* - * Set Rx/Tx DMA Configuration - * - * Set standard DMA size (128). Note that - * a DMA size of 512 causes rx overruns and tx errors - * on pci-e cards (tested on 5424 but since rx overruns - * also occur on 5416/5418 with madwifi we set 128 - * for all PCI-E cards to be safe). - * - * XXX: need to check 5210 for this - * TODO: Check out tx triger level, it's always 64 on dumps but I - * guess we can tweak it and see how it goes ;-) + * Initialize DMA/Interrupts */ - if (ah->ah_version != AR5K_AR5210) { - AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); - AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, - AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); - } + ath5k_hw_dma_init(ah); - /* Pre-enable interrupts on 5211/5212*/ - if (ah->ah_version != AR5K_AR5210) - ath5k_hw_set_imr(ah, ah->ah_imr); /* Enable 32KHz clock function for AR5212+ chips * Set clocks to 32KHz operation and use an -- cgit v1.2.3-59-g8ed1b From d41174fabdae348c6583cf05aeb329da232c342c Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:41:15 +0200 Subject: ath5k: Add new function to stop rx/tx DMA * Add a new function to stop rx/tx dma and use in when reset starts Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +- drivers/net/wireless/ath/ath5k/dma.c | 52 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath5k/reset.c | 13 +++++---- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 85ff822c81f4..629a5eebe302 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1180,8 +1180,9 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); -/* Init function */ +/* Init/Stop functions */ void ath5k_hw_dma_init(struct ath5k_hw *ah); +int ath5k_hw_dma_stop(struct ath5k_hw *ah); /* EEPROM access functions */ int ath5k_eeprom_init(struct ath5k_hw *ah); diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index b991b0585090..ca0467e21e56 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -126,7 +126,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Return if queue is declared inactive */ if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return -EIO; + return -EINVAL; if (ah->ah_version == AR5K_AR5210) { tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); @@ -174,7 +174,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) * * Stop DMA transmit on a specific hw queue and drain queue so we don't * have any pending frames. Returns -EBUSY if we still have pending frames, - * -EINVAL if queue number is out of range. + * -EINVAL if queue number is out of range or inactive. * */ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) @@ -186,7 +186,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Return if queue is declared inactive */ if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return -EIO; + return -EINVAL; if (ah->ah_version == AR5K_AR5210) { tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); @@ -733,3 +733,49 @@ void ath5k_hw_dma_init(struct ath5k_hw *ah) ath5k_hw_set_imr(ah, ah->ah_imr); } + +/** + * ath5k_hw_dma_stop - stop DMA unit + * + * @ah: The &struct ath5k_hw + * + * Stop tx/rx DMA and interrupts. Returns + * -EBUSY if tx or rx dma failed to stop. + * + * XXX: Sometimes DMA unit hangs and we have + * stuck frames on tx queues, only a reset + * can fix that. + */ +int ath5k_hw_dma_stop(struct ath5k_hw *ah) +{ + int i, qmax, err; + err = 0; + + /* Disable interrupts */ + ath5k_hw_set_imr(ah, 0); + + /* Stop rx dma */ + err = ath5k_hw_stop_rx_dma(ah); + if (err) + return err; + + /* Clear any pending interrupts + * and disable tx dma */ + if (ah->ah_version != AR5K_AR5210) { + ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); + qmax = AR5K_NUM_TX_QUEUES; + } else { + /* PISR/SISR Not available on 5210 */ + ath5k_hw_reg_read(ah, AR5K_ISR); + qmax = AR5K_NUM_TX_QUEUES_NOQCU; + } + + for (i = 0; i < qmax; i++) { + err = ath5k_hw_stop_tx_dma(ah, i); + /* -EINVAL -> queue inactive */ + if (err != -EINVAL) + return err; + } + + return err; +} diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 9dd5792780ba..083367712d67 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -822,6 +822,14 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, freq = 0; mode = 0; + /* + * Stop DMA + * + * Note: If DMA didn't stop continue + * since only a reset will fix it. + */ + ath5k_hw_dma_stop(ah); + /* * Save some registers before a reset */ @@ -1015,11 +1023,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, */ ath5k_hw_pcu_init(ah, op_mode, mode); - /* Clear any pending interrupts - * PISR/SISR Not available on 5210 */ - if (ah->ah_version != AR5K_AR5210) - ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); - /* * Initialize PHY */ -- cgit v1.2.3-59-g8ed1b From e088f23be166635b3938571c00c686094efa7cc4 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:43:18 +0200 Subject: ath5k: Stop PCU on reset * Stop PCU receive logic (DRU) durring reset We need to be sure pcu is not active when trying to stop rx dma right now this is done on ath5k_reset (base.c) but later we are going to clean it up. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 083367712d67..91a2b2166def 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -822,6 +822,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, freq = 0; mode = 0; + /* + * Stop PCU + */ + ath5k_hw_stop_rx_pcu(ah); + /* * Stop DMA * -- cgit v1.2.3-59-g8ed1b From 80dac9eecbdb95f61b9b3c7081e02412155982b7 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:45:38 +0200 Subject: ath5k: Use new dma_stop function on base.c * Since we stop rx/tx dma and pcu durring reset there is no need to call ath5k_hw_stop_rx/tx_dma before, also there is no need to call them durring stop_locked since we can use ath5k_hw_dma_stop for both. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 95 ++++++++++++++--------------------- 1 file changed, 39 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 7f783d9462aa..eea5879575ba 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1063,62 +1063,44 @@ err: return ret; } +/** + * ath5k_drain_tx_buffs - Empty tx buffers + * + * @sc The &struct ath5k_softc + * + * Empty tx buffers from all queues in preparation + * of a reset or during shutdown. + * + * NB: this assumes output has been stopped and + * we do not need to block ath5k_tx_tasklet + */ static void -ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) +ath5k_drain_tx_buffs(struct ath5k_softc *sc) { + struct ath5k_txq *txq; struct ath5k_buf *bf, *bf0; + int i; - /* - * NB: this assumes output has been stopped and - * we do not need to block ath5k_tx_tasklet - */ - spin_lock_bh(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ath5k_debug_printtxbuf(sc, bf); - - ath5k_txbuf_free_skb(sc, bf); - - spin_lock_bh(&sc->txbuflock); - list_move_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - txq->txq_len--; - spin_unlock_bh(&sc->txbuflock); - } - txq->link = NULL; - txq->txq_poll_mark = false; - spin_unlock_bh(&txq->lock); -} + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { + if (sc->txqs[i].setup) { + txq = &sc->txqs[i]; + spin_lock_bh(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { + ath5k_debug_printtxbuf(sc, bf); -/* - * Drain the transmit queues and reclaim resources. - */ -static void -ath5k_txq_cleanup(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - unsigned int i; + ath5k_txbuf_free_skb(sc, bf); - /* XXX return value */ - if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) { - /* don't touch the hardware if marked invalid */ - ath5k_hw_stop_tx_dma(ah, sc->bhalq); - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", - ath5k_hw_get_txdp(ah, sc->bhalq)); - for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) - if (sc->txqs[i].setup) { - ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " - "link %p\n", - sc->txqs[i].qnum, - ath5k_hw_get_txdp(ah, - sc->txqs[i].qnum), - sc->txqs[i].link); + spin_lock_bh(&sc->txbuflock); + list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + txq->txq_len--; + spin_unlock_bh(&sc->txbuflock); } + txq->link = NULL; + txq->txq_poll_mark = false; + spin_unlock_bh(&txq->lock); + } } - - for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) - if (sc->txqs[i].setup) - ath5k_txq_drainq(sc, &sc->txqs[i]); } static void @@ -1178,16 +1160,19 @@ err: } /* - * Disable the receive h/w in preparation for a reset. + * Disable the receive logic on PCU (DRU) + * In preparation for a shutdown. + * + * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop + * does. */ static void ath5k_rx_stop(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; - ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ - ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ + ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ ath5k_debug_printrxbuffs(sc, ah); } @@ -2383,10 +2368,9 @@ ath5k_stop_locked(struct ath5k_softc *sc) ath5k_led_off(sc); ath5k_hw_set_imr(ah, 0); synchronize_irq(sc->pdev->irq); - } - ath5k_txq_cleanup(sc); - if (!test_bit(ATH_STAT_INVALID, sc->status)) { ath5k_rx_stop(sc); + ath5k_hw_dma_stop(ah); + ath5k_drain_tx_buffs(sc); ath5k_hw_phy_disable(ah); } @@ -2532,8 +2516,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) stop_tasklets(sc); if (chan) { - ath5k_txq_cleanup(sc); - ath5k_rx_stop(sc); + ath5k_drain_tx_buffs(sc); sc->curchan = chan; sc->curband = &sc->sbands[chan->band]; -- cgit v1.2.3-59-g8ed1b From b3a28e68d5c8d788a4e538a119a5d326545add8a Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:47:31 +0200 Subject: ath5k: Debug DMA timeouts * Increase timeouts on ath5k_hw_stop_tx_dma and also wait for tx queue to stop before checking for pending frames * Add a new debug level to debug dma start/stop Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 1 + drivers/net/wireless/ath/ath5k/debug.h | 2 ++ drivers/net/wireless/ath/ath5k/dma.c | 34 +++++++++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 7d785cb60ce0..5341dd2860d3 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -312,6 +312,7 @@ static const struct { { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, + { ATH5K_DEBUG_DMA, "dma", "dma start/stop" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, { ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 236edbd2507d..3e34428d5126 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -95,6 +95,7 @@ struct ath5k_dbg_info { * @ATH5K_DEBUG_DUMP_RX: print received skb content * @ATH5K_DEBUG_DUMP_TX: print transmit skb content * @ATH5K_DEBUG_DUMPBANDS: dump bands + * @ATH5K_DEBUG_DMA: debug dma start/stop * @ATH5K_DEBUG_TRACE: trace function calls * @ATH5K_DEBUG_DESC: descriptor setup * @ATH5K_DEBUG_ANY: show at any debug level @@ -118,6 +119,7 @@ enum ath5k_debug_level { ATH5K_DEBUG_DUMP_RX = 0x00000100, ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMPBANDS = 0x00000400, + ATH5K_DEBUG_DMA = 0x00000800, ATH5K_DEBUG_ANI = 0x00002000, ATH5K_DEBUG_DESC = 0x00004000, ATH5K_DEBUG_ANY = 0xffffffff diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index ca0467e21e56..e39c95340841 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -70,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) for (i = 1000; i > 0 && (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; i--) - udelay(10); + udelay(100); + + if (i) + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "failed to stop RX DMA !\n"); return i ? 0 : -EBUSY; } @@ -217,7 +221,18 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) */ AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); - /*Check for pending frames*/ + /* Wait for queue to stop */ + for (i = 1000; i > 0 && + (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0); + i--) + udelay(100); + + if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "queue %i didn't stop !\n", queue); + + /* Check for pending frames */ + i = 1000; do { pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)) & @@ -248,12 +263,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); /* Wait a while and disable mechanism */ - udelay(200); + udelay(400); AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, AR5K_QUIET_CTL1_QT_EN); /* Re-check for pending frames */ - i = 40; + i = 100; do { pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)) & @@ -263,12 +278,21 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); + + if (pending) + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "quiet mechanism didn't work q:%i !\n", + queue); } /* Clear register */ ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); - if (pending) + if (pending) { + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "tx dma didn't stop (q:%i, frm:%i) !\n", + queue, pending); return -EBUSY; + } } /* TODO: Check for success on 5210 else return error */ -- cgit v1.2.3-59-g8ed1b From f7317ba2d669c1b54fb31ed7834361a700a79217 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:50:16 +0200 Subject: ath5k: Use DCU early termination correctly * DCU early termination should be used to quickly flush QCU according to docs so don't enable it for all queues, enable it only when stopping each queue and disable it when we are done. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/dma.c | 14 ++++++++++++++ drivers/net/wireless/ath/ath5k/qcu.c | 3 --- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index e39c95340841..bfdfcff42a1e 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -216,6 +216,14 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR); } else { + + /* + * Enable DCU early termination to quickly + * flush any pending frames from QCU + */ + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + AR5K_QCU_MISC_DCU_EARLY); + /* * Schedule TX disable and wait until queue is empty */ @@ -285,6 +293,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) queue); } + /* + * Disable DCU early termination + */ + AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + AR5K_QCU_MISC_DCU_EARLY); + /* Clear register */ ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); if (pending) { diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 52eee34fd54d..ed62273cdf01 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -340,9 +340,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* * Set misc registers */ - /* Enable DCU early termination for this queue */ - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_DCU_EARLY); /* Enable DCU to wait for next fragment from QCU */ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), -- cgit v1.2.3-59-g8ed1b From e8325ed87457e07b9ceeb1e7a31df787dd7ee106 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:52:24 +0200 Subject: ath5k: Check RXE when setting RXDP * Make sure we are not trying to set RXDP while RX is active, for now ignore the return value. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/dma.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 629a5eebe302..b36d3a530258 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1168,7 +1168,7 @@ void ath5k_hw_set_clockrate(struct ath5k_hw *ah); void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); -void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); +int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index bfdfcff42a1e..3fe634f588c2 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -95,11 +95,18 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) * @ah: The &struct ath5k_hw * @phys_addr: RX descriptor address * - * XXX: Should we check if rx is enabled before setting rxdp ? + * Returns -EIO if rx is active */ -void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) +int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) { + if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) { + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "tried to set RXDP while rx was active !\n"); + return -EIO; + } + ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); + return 0; } -- cgit v1.2.3-59-g8ed1b From 14fae2d4b61b890cea58d63091406b86ec9bafcd Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:55:17 +0200 Subject: ath5k: Use new function to stop beacon queue * Since we only use ath5k_hw_stop_tx_dma to stop the beacon queue, introduce a new function ath5k_hw_stop_beacon_queue so that we can use that instead and have better control. In the future we can add more beacon queue specific stuff there (maybe tweak beacon timers or something), for now just call ath5k_hw_stop_tx_dma. * Also since we don't call ath5k_hw_stop_rx/tx_dma from outside dma.c, make them static. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/dma.c | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index b36d3a530258..66359dca3224 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1166,11 +1166,10 @@ void ath5k_hw_set_clockrate(struct ath5k_hw *ah); /* DMA Related Functions */ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); -int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); +int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue); u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index eea5879575ba..9af7e461a236 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1922,7 +1922,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) * This should never fail since we check above that no frames * are still pending on the queue. */ - if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) { + if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) { ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq); /* NB: hw still stops DMA, so proceed */ } @@ -2091,7 +2091,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) } else ath5k_beacon_update_timers(sc, -1); } else { - ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); + ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq); } ath5k_hw_set_imr(ah, sc->imask); diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 3fe634f588c2..82541fec9f0e 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -58,7 +58,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) * * @ah: The &struct ath5k_hw */ -int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) +static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) { unsigned int i; @@ -188,7 +188,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) * -EINVAL if queue number is out of range or inactive. * */ -int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) +static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) { unsigned int i = 40; u32 tx_queue, pending; @@ -320,6 +320,26 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) return 0; } +/** + * ath5k_hw_stop_beacon_queue - Stop beacon queue + * + * @ah The &struct ath5k_hw + * @queue The queue number + * + * Returns -EIO if queue didn't stop + */ +int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue) +{ + int ret; + ret = ath5k_hw_stop_tx_dma(ah, queue); + if (ret) { + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, + "beacon queue didn't stop !\n"); + return -EIO; + } + return 0; +} + /** * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue * -- cgit v1.2.3-59-g8ed1b From fa3d2feeff4723cce8d4722902492d60b7f75fcc Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 20:58:34 +0200 Subject: ath5k: Add new field on ath5k_hw to track bandwidth modes * Prepare for half/quarter/turbo support, introduce a new ah_bwmode parameter and get rid of ah_turbo. Bwmode stands for "bandwidth mode" and can have 4 values, default (20MHz), turbo (40MHz), half rate (10MHz), and quarter rate (5MHz). Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 8 +++++++- drivers/net/wireless/ath/ath5k/attach.c | 2 +- drivers/net/wireless/ath/ath5k/phy.c | 1 - drivers/net/wireless/ath/ath5k/qcu.c | 16 ++++++++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 66359dca3224..b1429da41a80 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -424,6 +424,12 @@ enum ath5k_ant_mode { AR5K_ANTMODE_MAX, }; +enum ath5k_bw_mode { + AR5K_BWMODE_DEFAULT = 0, /* 20MHz, default operation */ + AR5K_BWMODE_5MHZ = 1, /* Quarter rate */ + AR5K_BWMODE_10MHZ = 2, /* Half rate */ + AR5K_BWMODE_40MHZ = 3 /* Turbo */ +}; /****************\ TX DEFINITIONS @@ -1026,7 +1032,6 @@ struct ath5k_hw { enum ath5k_int ah_imr; struct ieee80211_channel *ah_current_channel; - bool ah_turbo; bool ah_calibration; bool ah_single_chip; @@ -1044,6 +1049,7 @@ struct ath5k_hw { u32 ah_limit_tx_retries; u8 ah_coverage_class; + u8 ah_bwmode; /* Antenna Control */ u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index fbe8aca975d8..ed86b9dde1b4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -115,7 +115,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) * HW information */ ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; - ah->ah_turbo = false; + ah->ah_bwmode = AR5K_BWMODE_DEFAULT; ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_imr = 0; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1c41fa837451..02869c7d596b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1235,7 +1235,6 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, } ah->ah_current_channel = channel; - ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; ath5k_hw_set_clockrate(ah); return 0; diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index ed62273cdf01..778fb59d89f5 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -246,21 +246,21 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) return 0; /* Set Slot time */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, AR5K_SLOT_TIME); /* Set ACK_CTS timeout */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); /* Set Transmit Latency */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_TRANSMIT_LATENCY_TURBO : AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); /* Set IFS0 */ - if (ah->ah_turbo) { - ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { + ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) << AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, AR5K_IFS0); @@ -272,18 +272,18 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) } /* Set IFS1 */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_PROTO_TIME_CNTRL_TURBO : AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); /* Set AR5K_PHY_SETTLING */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | 0x38 : (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | 0x1C, AR5K_PHY_SETTLING); /* Set Frame Control Register */ - ath5k_hw_reg_write(ah, ah->ah_turbo ? + ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT | 0x2020) : (AR5K_PHY_FRAME_CTL_INI | 0x1020), -- cgit v1.2.3-59-g8ed1b From c297560206adf0cda8ce38ef9b20b0a025754c4d Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:00:37 +0200 Subject: ath5k: Put core clock initialization on a new function * Handle all usec parameters in one function. It's much cleaner this way. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 26 +++++-- drivers/net/wireless/ath/ath5k/phy.c | 1 - drivers/net/wireless/ath/ath5k/qcu.c | 4 - drivers/net/wireless/ath/ath5k/reset.c | 130 +++++++++++++++++++++++++++++---- 4 files changed, 134 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index b1429da41a80..c9535447a8ab 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -242,14 +242,6 @@ #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY #define AR5K_INIT_TX_RETRY 10 -#define AR5K_INIT_TRANSMIT_LATENCY ( \ - (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ - (AR5K_INIT_USEC) \ -) -#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \ - (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ - (AR5K_INIT_USEC_TURBO) \ -) #define AR5K_INIT_PROTO_TIME_CNTRL ( \ (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \ (AR5K_INIT_PROG_IFS) \ @@ -259,6 +251,24 @@ (AR5K_INIT_PROG_IFS_TURBO) \ ) +/* Rx latency for 5 and 10MHz operation (max ?) */ +#define AR5K_INIT_RX_LAT_MAX 63 +/* Tx latencies from initvals (5212 only but no problem + * because we only tweak them on 5212) */ +#define AR5K_INIT_TX_LAT_A 54 +#define AR5K_INIT_TX_LAT_BG 384 +/* Tx latency for 40MHz (turbo) operation (min ?) */ +#define AR5K_INIT_TX_LAT_MIN 32 + +/* Tx frame to Tx data start delay */ +#define AR5K_INIT_TXF2TXD_START_DEFAULT 14 +#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12 +#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13 + +/* Default Tx/Rx latencies (same for 5211)*/ +#define AR5K_INIT_TX_LATENCY_5210 54 +#define AR5K_INIT_RX_LATENCY_5210 29 + /* GENERIC CHIPSET DEFINITIONS */ diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 02869c7d596b..706fc461be61 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1235,7 +1235,6 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, } ah->ah_current_channel = channel; - ath5k_hw_set_clockrate(ah); return 0; } diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 778fb59d89f5..f89bc9403f8f 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -253,10 +253,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); - /* Set Transmit Latency */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - AR5K_INIT_TRANSMIT_LATENCY_TURBO : - AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); /* Set IFS0 */ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 91a2b2166def..7db984ce90fb 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -86,16 +86,21 @@ unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) } /** - * ath5k_hw_set_clockrate - Set common->clockrate for the current channel + * ath5k_hw_init_core_clock - Initialize core clock * - * @ah: The &struct ath5k_hw + * @ah The &struct ath5k_hw + * + * Initialize core clock parameters (usec, usec32, latencies etc). */ -void ath5k_hw_set_clockrate(struct ath5k_hw *ah) +static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; struct ath_common *common = ath5k_hw_common(ah); - int clock; + u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs; + /* + * Set core clock frequency + */ if (channel->hw_value & CHANNEL_5GHZ) clock = 40; /* 802.11a */ else if (channel->hw_value & CHANNEL_CCK) @@ -103,11 +108,109 @@ void ath5k_hw_set_clockrate(struct ath5k_hw *ah) else clock = 44; /* 802.11g */ - /* Clock rate in turbo modes is twice the normal rate */ - if (channel->hw_value & CHANNEL_TURBO) + /* Use clock multiplier for non-default + * bwmode */ + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: clock *= 2; + break; + case AR5K_BWMODE_10MHZ: + clock /= 2; + break; + case AR5K_BWMODE_5MHZ: + clock /= 4; + break; + default: + break; + } common->clockrate = clock; + + /* + * Set USEC parameters + */ + /* Set USEC counter on PCU*/ + usec = clock - 1; + usec = AR5K_REG_SM(usec, AR5K_USEC_1); + + /* Set usec duration on DCU */ + if (ah->ah_version != AR5K_AR5210) + AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, + AR5K_DCU_GBL_IFS_MISC_USEC_DUR, + clock); + + /* Set 32MHz USEC counter */ + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413)) + /* Remain on 40MHz clock ? */ + sclock = 40 - 1; + else + sclock = 32 - 1; + sclock = AR5K_REG_SM(sclock, AR5K_USEC_32); + + /* + * Set tx/rx latencies + */ + usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); + txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211); + rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); + + /* + * 5210 initvals don't include usec settings + * so we need to use magic values here for + * tx/rx latencies + */ + if (ah->ah_version == AR5K_AR5210) { + /* same for turbo */ + txlat = AR5K_INIT_TX_LATENCY_5210; + rxlat = AR5K_INIT_RX_LATENCY_5210; + } + + if (ah->ah_mac_srev < AR5K_SREV_AR5211) { + /* 5311 has different tx/rx latency masks + * from 5211, since we deal 5311 the same + * as 5211 when setting initvals, shift + * values here to their proper locations + * + * Note: Initvals indicate tx/rx/ latencies + * are the same for turbo mode */ + txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210); + rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210); + } else + switch (ah->ah_bwmode) { + case AR5K_BWMODE_10MHZ: + txlat = AR5K_REG_SM(txlat * 2, + AR5K_USEC_TX_LATENCY_5211); + rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX, + AR5K_USEC_RX_LATENCY_5211); + txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ; + break; + case AR5K_BWMODE_5MHZ: + txlat = AR5K_REG_SM(txlat * 4, + AR5K_USEC_TX_LATENCY_5211); + rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX, + AR5K_USEC_RX_LATENCY_5211); + txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ; + break; + case AR5K_BWMODE_40MHZ: + txlat = AR5K_INIT_TX_LAT_MIN; + rxlat = AR5K_REG_SM(rxlat / 2, + AR5K_USEC_RX_LATENCY_5211); + txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; + break; + default: + break; + } + + usec_reg = (usec | sclock | txlat | rxlat); + ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC); + + /* On 5112 set tx frane to tx data start delay */ + if (ah->ah_radio == AR5K_RF5112) { + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2, + AR5K_PHY_RF_CTL2_TXF2TXD_START, + txf2txs); + } } /* @@ -122,7 +225,7 @@ void ath5k_hw_set_clockrate(struct ath5k_hw *ah) static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 scal, spending, usec32; + u32 scal, spending; /* Only set 32KHz settings if we have an external * 32KHz crystal present */ @@ -179,6 +282,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); + /* Set DAC/ADC delays */ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); @@ -201,13 +305,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) spending = 0x18; ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413)) - usec32 = 39; - else - usec32 = 31; - AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32); - + /* Set up tsf increment on each cycle */ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); } } @@ -822,6 +920,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, freq = 0; mode = 0; + /* * Stop PCU */ @@ -971,6 +1070,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, if (ret) return ret; + /* Initialize core clock settings */ + ath5k_hw_init_core_clock(ah); + /* * Tweak initval settings for revised * chipsets and add some more config -- cgit v1.2.3-59-g8ed1b From 325089ab5847f5c1e43f42bb90d32f981867c4c1 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:02:20 +0200 Subject: ath5k: Small cleanup on tweak_initvals * Now that we properly set rx/tx latencies for AR5311 remove that old buggy part of code left inside ath5k_hw_tweak_initval_settings that was never executed (you can't have an RF5112 radio on a mac older than AR5212). Also use a magic value for 5311 PHY_SCAL value. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reg.h | 1 + drivers/net/wireless/ath/ath5k/reset.c | 18 +++--------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index ca79ecd832fd..4d610617af3c 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2058,6 +2058,7 @@ #define AR5K_PHY_SCAL 0x9878 #define AR5K_PHY_SCAL_32MHZ 0x0000000e +#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008 #define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a #define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 7db984ce90fb..c9e5bad7cffc 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -730,24 +730,12 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); } - if ((ah->ah_radio == AR5K_RF5112) && - (ah->ah_mac_srev < AR5K_SREV_AR5211)) { - u32 usec_reg; - /* 5311 has different tx/rx latency masks - * from 5211, since we deal 5311 the same - * as 5211 when setting initvals, shift - * values here to their proper locations */ - usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); - ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 | - AR5K_USEC_32 | - AR5K_USEC_TX_LATENCY_5211 | - AR5K_REG_SM(29, - AR5K_USEC_RX_LATENCY_5210)), - AR5K_USEC_5211); + if (ah->ah_mac_srev < AR5K_SREV_AR5211) { /* Clear QCU/DCU clock gating register */ ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); /* Set DAC/ADC delays */ - ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); + ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311, + AR5K_PHY_SCAL); /* Enable PCU FIFO corruption ECO */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_ECO_ENABLE); -- cgit v1.2.3-59-g8ed1b From b405086ba47678a5b8f6e7cd835a3d27ebb6f744 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:04:43 +0200 Subject: ath5k: Increase PHY settling parameters for turo mode * On turbo mode increase PHY settling times, note that we only increase switch settling time on AR5212 as indicated by initvals. * A few cleanups: Move frame control settings for AR5210 from reset_tx_queue to tweak_initvals and remove phy_scal settings from tweak_initvals (we tweak them alread on set_sleep_clock). Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 14 +++++++-- drivers/net/wireless/ath/ath5k/qcu.c | 13 --------- drivers/net/wireless/ath/ath5k/reg.h | 2 ++ drivers/net/wireless/ath/ath5k/reset.c | 52 +++++++++++++++++++++++++--------- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index c9535447a8ab..005cad025170 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -259,15 +259,23 @@ #define AR5K_INIT_TX_LAT_BG 384 /* Tx latency for 40MHz (turbo) operation (min ?) */ #define AR5K_INIT_TX_LAT_MIN 32 +/* Default Tx/Rx latencies (same for 5211)*/ +#define AR5K_INIT_TX_LATENCY_5210 54 +#define AR5K_INIT_RX_LATENCY_5210 29 /* Tx frame to Tx data start delay */ #define AR5K_INIT_TXF2TXD_START_DEFAULT 14 #define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12 #define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13 -/* Default Tx/Rx latencies (same for 5211)*/ -#define AR5K_INIT_TX_LATENCY_5210 54 -#define AR5K_INIT_RX_LATENCY_5210 29 +/* We need to increase PHY switch and agc settling time + * on turbo mode */ +#define AR5K_SWITCH_SETTLING 5760 +#define AR5K_SWITCH_SETTLING_TURBO 7168 + +#define AR5K_AGC_SETTLING 28 +/* 38 on 5210 but shouldn't matter */ +#define AR5K_AGC_SETTLING_TURBO 37 /* GENERIC CHIPSET DEFINITIONS */ diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index f89bc9403f8f..00c490833ba7 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -271,19 +271,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_PROTO_TIME_CNTRL_TURBO : AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); - /* Set AR5K_PHY_SETTLING */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) - | 0x38 : - (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) - | 0x1C, - AR5K_PHY_SETTLING); - /* Set Frame Control Register */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | - AR5K_PHY_TURBO_SHORT | 0x2020) : - (AR5K_PHY_FRAME_CTL_INI | 0x1020), - AR5K_PHY_FRAME_CTL_5210); } /* diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 4d610617af3c..dc213bb121e6 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2245,6 +2245,8 @@ #define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \ AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211) /*---[5111+]---*/ +#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */ +#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0 #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index c9e5bad7cffc..c871d40b1ad7 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -688,19 +688,6 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_DCU_DBL_BUF_DIS); - /* Set DAC/ADC delays */ - if (ah->ah_version == AR5K_AR5212) { - u32 scal; - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) - scal = AR5K_PHY_SCAL_32MHZ_2417; - else if (ee->ee_is_hb63) - scal = AR5K_PHY_SCAL_32MHZ_HB63; - else - scal = AR5K_PHY_SCAL_32MHZ; - ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); - } - /* Set fast ADC */ if ((ah->ah_radio == AR5K_RF5413) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { @@ -740,6 +727,45 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_ECO_ENABLE); } + + if (ah->ah_bwmode) { + /* Increase PHY switch and AGC settling time + * on turbo mode (ath5k_hw_commit_eeprom_settings + * will override settling time if available) */ + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { + + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, + AR5K_PHY_SETTLING_AGC, + AR5K_AGC_SETTLING_TURBO); + + /* XXX: Initvals indicate we only increase + * switch time on AR5212, 5211 and 5210 + * only change agc time (bug?) */ + if (ah->ah_version == AR5K_AR5212) + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, + AR5K_PHY_SETTLING_SWITCH, + AR5K_SWITCH_SETTLING_TURBO); + + if (ah->ah_version == AR5K_AR5210) { + /* Set Frame Control Register */ + ath5k_hw_reg_write(ah, + (AR5K_PHY_FRAME_CTL_INI | + AR5K_PHY_TURBO_MODE | + AR5K_PHY_TURBO_SHORT | 0x2020), + AR5K_PHY_FRAME_CTL_5210); + } + /* On 5413 PHY force window length for half/quarter rate*/ + } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) && + (ah->ah_mac_srev <= AR5K_SREV_AR5414)) { + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211, + AR5K_PHY_FRAME_CTL_WIN_LEN, + 3); + } + } else if (ah->ah_version == AR5K_AR5210) { + /* Set Frame Control Register for normal operation */ + ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020), + AR5K_PHY_FRAME_CTL_5210); + } } static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, -- cgit v1.2.3-59-g8ed1b From 25ddfa195735934256fda55bb4f2d749c19386ff Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:07:04 +0200 Subject: ath5k: Move tx retries setting outside reset_tx_queue * Move setting of tx retry limits on a separate function (we 'll clean up this AR5210 mess later) Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/qcu.c | 92 ++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 00c490833ba7..c422d5c92d46 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -225,12 +225,62 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, * Single QCU/DCU initialization * \*******************************/ +/* + * Set tx retry limits on DCU + */ +static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, + unsigned int queue) +{ + u32 retry_lg, retry_sh; + + /* + * Calculate and set retry limits + */ + if (ah->ah_software_retry) { + /* XXX Need to test this */ + retry_lg = ah->ah_limit_tx_retries; + retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? + AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; + } else { + retry_lg = AR5K_INIT_LG_RETRY; + retry_sh = AR5K_INIT_SH_RETRY; + } + + /* Single data queue on AR5210 */ + if (ah->ah_version == AR5K_AR5210) { + struct ath5k_txq_info *tq = &ah->ah_txq[queue]; + + if (queue > 0) + return; + + ath5k_hw_reg_write(ah, + (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) + | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, + AR5K_NODCU_RETRY_LMT_SLG_RETRY) + | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, + AR5K_NODCU_RETRY_LMT_SSH_RETRY) + | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) + | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), + AR5K_NODCU_RETRY_LMT); + /* DCU on AR5211+ */ + } else { + ath5k_hw_reg_write(ah, + AR5K_REG_SM(AR5K_INIT_SLG_RETRY, + AR5K_DCU_RETRY_LMT_SLG_RETRY) | + AR5K_REG_SM(AR5K_INIT_SSH_RETRY, + AR5K_DCU_RETRY_LMT_SSH_RETRY) | + AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | + AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), + AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); + } + return; +} + /* * Set DFS properties for a transmit queue on DCU */ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) { - u32 retry_lg, retry_sh; struct ath5k_txq_info *tq = &ah->ah_txq[queue]; AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); @@ -271,42 +321,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? AR5K_INIT_PROTO_TIME_CNTRL_TURBO : AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); - } - - /* - * Calculate and set retry limits - */ - if (ah->ah_software_retry) { - /* XXX Need to test this */ - retry_lg = ah->ah_limit_tx_retries; - retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? - AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; } else { - retry_lg = AR5K_INIT_LG_RETRY; - retry_sh = AR5K_INIT_SH_RETRY; - } - - /*No QCU/DCU [5210]*/ - if (ah->ah_version == AR5K_AR5210) { - ath5k_hw_reg_write(ah, - (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) - | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, - AR5K_NODCU_RETRY_LMT_SLG_RETRY) - | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, - AR5K_NODCU_RETRY_LMT_SSH_RETRY) - | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) - | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), - AR5K_NODCU_RETRY_LMT); - } else { - /*QCU/DCU [5211+]*/ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(AR5K_INIT_SLG_RETRY, - AR5K_DCU_RETRY_LMT_SLG_RETRY) | - AR5K_REG_SM(AR5K_INIT_SSH_RETRY, - AR5K_DCU_RETRY_LMT_SSH_RETRY) | - AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | - AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), - AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); /*===Rest is also for QCU/DCU only [5211+]===*/ @@ -320,6 +335,11 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), AR5K_QUEUE_DFS_LOCAL_IFS(queue)); + /* + * Set tx retry limits for this queue + */ + ath5k_hw_set_tx_retry_limits(ah, queue); + /* * Set misc registers */ -- cgit v1.2.3-59-g8ed1b From 3017fcab416d8d1ee48ca16aa9a3062f600dab8e Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:09:11 +0200 Subject: ath5k: Extend get_default_sifs/slot_time * Extend get_default_sifs/slot_time to include timings for turbo half and quarter rate modes. * AR5210 code for now uses timings already on core clock units instead of usecs so rename them (we 'll clean it up later). Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 24 +++++++++++++--- drivers/net/wireless/ath/ath5k/pcu.c | 52 +++++++++++++++++++++++++--------- drivers/net/wireless/ath/ath5k/qcu.c | 16 ++++++----- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 005cad025170..e11fc8f39192 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -226,16 +226,16 @@ #define AR5K_INIT_USEC 39 #define AR5K_INIT_USEC_TURBO 79 #define AR5K_INIT_USEC_32 31 -#define AR5K_INIT_SLOT_TIME 396 -#define AR5K_INIT_SLOT_TIME_TURBO 480 +#define AR5K_INIT_SLOT_TIME_CLOCK 396 +#define AR5K_INIT_SLOT_TIME_TURBO_CLOCK 480 #define AR5K_INIT_ACK_CTS_TIMEOUT 1024 #define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 #define AR5K_INIT_PROG_IFS 920 #define AR5K_INIT_PROG_IFS_TURBO 960 #define AR5K_INIT_EIFS 3440 #define AR5K_INIT_EIFS_TURBO 6880 -#define AR5K_INIT_SIFS 560 -#define AR5K_INIT_SIFS_TURBO 480 +#define AR5K_INIT_SIFS_CLOCK 560 +#define AR5K_INIT_SIFS_TURBO_CLOCK 480 #define AR5K_INIT_SH_RETRY 10 #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY #define AR5K_INIT_SSH_RETRY 32 @@ -251,6 +251,22 @@ (AR5K_INIT_PROG_IFS_TURBO) \ ) +/* Slot time */ +#define AR5K_INIT_SLOT_TIME_TURBO 6 +#define AR5K_INIT_SLOT_TIME_DEFAULT 9 +#define AR5K_INIT_SLOT_TIME_HALF_RATE 13 +#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21 +#define AR5K_INIT_SLOT_TIME_B 20 +#define AR5K_SLOT_TIME_MAX 0xffff + +/* SIFS */ +#define AR5K_INIT_SIFS_TURBO 6 +/* XXX: 8 from initvals 10 from standard */ +#define AR5K_INIT_SIFS_DEFAULT_BG 8 +#define AR5K_INIT_SIFS_DEFAULT_A 16 +#define AR5K_INIT_SIFS_HALF_RATE 32 +#define AR5K_INIT_SIFS_QUARTER_RATE 64 + /* Rx latency for 5 and 10MHz operation (max ?) */ #define AR5K_INIT_RX_LAT_MAX 63 /* Tx latencies from initvals (5212 only but no problem diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 2c2ea1539849..2118f7048f37 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -43,14 +43,27 @@ static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; + unsigned int slot_time; - if (channel->hw_value & CHANNEL_TURBO) - return 6; /* both turbo modes */ - - if (channel->hw_value & CHANNEL_CCK) - return 20; /* 802.11b */ + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: + slot_time = AR5K_INIT_SLOT_TIME_TURBO; + break; + case AR5K_BWMODE_10MHZ: + slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE; + break; + case AR5K_BWMODE_5MHZ: + slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; + break; + case AR5K_BWMODE_DEFAULT: + slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; + default: + if (channel->hw_value & CHANNEL_CCK) + slot_time = AR5K_INIT_SLOT_TIME_B; + break; + } - return 9; /* 802.11 a/g */ + return slot_time; } /** @@ -58,17 +71,30 @@ static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) * * @ah: The &struct ath5k_hw */ -static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) +unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; + unsigned int sifs; - if (channel->hw_value & CHANNEL_TURBO) - return 8; /* both turbo modes */ - - if (channel->hw_value & CHANNEL_5GHZ) - return 16; /* 802.11a */ + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: + sifs = AR5K_INIT_SIFS_TURBO; + break; + case AR5K_BWMODE_10MHZ: + sifs = AR5K_INIT_SIFS_HALF_RATE; + break; + case AR5K_BWMODE_5MHZ: + sifs = AR5K_INIT_SIFS_QUARTER_RATE; + break; + case AR5K_BWMODE_DEFAULT: + sifs = AR5K_INIT_SIFS_DEFAULT_BG; + default: + if (channel->hw_value & CHANNEL_5GHZ) + sifs = AR5K_INIT_SIFS_DEFAULT_A; + break; + } - return 10; /* 802.11 b/g */ + return sifs; } /** diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index c422d5c92d46..6eb6838d906d 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -297,7 +297,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* Set Slot time */ ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, + AR5K_INIT_SLOT_TIME_TURBO_CLOCK : + AR5K_INIT_SLOT_TIME_CLOCK, AR5K_SLOT_TIME); /* Set ACK_CTS timeout */ ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? @@ -306,15 +307,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* Set IFS0 */ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + - tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) << - AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, + ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO_CLOCK + + tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO_CLOCK) + << AR5K_IFS0_DIFS_S) | + AR5K_INIT_SIFS_TURBO_CLOCK, AR5K_IFS0); } else { - ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + - tq->tqi_aifs * AR5K_INIT_SLOT_TIME) << + ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_CLOCK + + tq->tqi_aifs * AR5K_INIT_SLOT_TIME_CLOCK) << AR5K_IFS0_DIFS_S) | - AR5K_INIT_SIFS, AR5K_IFS0); + AR5K_INIT_SIFS_CLOCK, AR5K_IFS0); } /* Set IFS1 */ -- cgit v1.2.3-59-g8ed1b From 61cde037234c4b8e6497a23f5f236c64cbf9d41d Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:12:23 +0200 Subject: ath5k: Extend rate_duration * Extend ieee80211_generic_frame_duration to support the various bwmodes. * Better document what's going on with ack bitrates and update write_rate_duration to support the standard ack bitrates (when we don't set the high bit). * Get rid of set_ack_bitrate_high and introduce a flag on ath5k_hw for this (we only called the function on init anyway so there is no difference). Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 12 ++- drivers/net/wireless/ath/ath5k/base.c | 4 +- drivers/net/wireless/ath/ath5k/pcu.c | 159 ++++++++++++++++++++++++--------- 3 files changed, 129 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e11fc8f39192..7df5b46ab690 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -267,6 +267,15 @@ #define AR5K_INIT_SIFS_HALF_RATE 32 #define AR5K_INIT_SIFS_QUARTER_RATE 64 +/* Used to calculate tx time for non 5/10/40MHz + * operation */ +/* It's preamble time + signal time (16 + 4) */ +#define AR5K_INIT_OFDM_PREAMPLE_TIME 20 +/* Preamble time for 40MHz (turbo) operation (min ?) */ +#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14 +#define AR5K_INIT_OFDM_SYMBOL_TIME 4 +#define AR5K_INIT_OFDM_PLCP_BITS 22 + /* Rx latency for 5 and 10MHz operation (max ?) */ #define AR5K_INIT_RX_LAT_MAX 63 /* Tx latencies from initvals (5212 only but no problem @@ -1083,6 +1092,7 @@ struct ath5k_hw { u32 ah_limit_tx_retries; u8 ah_coverage_class; + bool ah_ack_bitrate_high; u8 ah_bwmode; /* Antenna Control */ @@ -1248,8 +1258,6 @@ void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); void ath5k_hw_reset_tsf(struct ath5k_hw *ah); void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); -/* ACK bit rate */ -void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); /* Init function */ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, u8 mode); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9af7e461a236..526d8bc412c0 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2420,7 +2420,9 @@ ath5k_init(struct ath5k_softc *sc) for (i = 0; i < common->keymax; i++) ath_hw_keyreset(common, (u16) i); - ath5k_hw_set_ack_bitrate_high(ah, true); + /* Use higher rates for acks instead of base + * rate */ + ah->ah_ack_bitrate_high = true; for (i = 0; i < ARRAY_SIZE(sc->bslot); i++) sc->bslot[i] = NULL; diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 2118f7048f37..e7f6be9cdf1a 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -31,10 +31,99 @@ #include "debug.h" #include "base.h" +/* + * AR5212+ can use higher rates for ack transmition + * based on current tx rate instead of the base rate. + * It does this to better utilize channel usage. + * This is a mapping between G rates (that cover both + * CCK and OFDM) and ack rates that we use when setting + * rate -> duration table. This mapping is hw-based so + * don't change anything. + * + * To enable this functionality we must set + * ah->ah_ack_bitrate_high to true else base rate is + * used (1Mb for CCK, 6Mb for OFDM). + */ +static const unsigned int ack_rates_high[] = +/* Tx -> ACK */ +/* 1Mb -> 1Mb */ { 0, +/* 2MB -> 2Mb */ 1, +/* 5.5Mb -> 2Mb */ 1, +/* 11Mb -> 2Mb */ 1, +/* 6Mb -> 6Mb */ 4, +/* 9Mb -> 6Mb */ 4, +/* 12Mb -> 12Mb */ 6, +/* 18Mb -> 12Mb */ 6, +/* 24Mb -> 24Mb */ 8, +/* 36Mb -> 24Mb */ 8, +/* 48Mb -> 24Mb */ 8, +/* 54Mb -> 24Mb */ 8 }; + /*******************\ * Helper functions * \*******************/ +/** + * ath5k_hw_get_frame_duration - Get tx time of a frame + * + * @ah: The &struct ath5k_hw + * @len: Frame's length in bytes + * @rate: The @struct ieee80211_rate + * + * Calculate tx duration of a frame given it's rate and length + * It extends ieee80211_generic_frame_duration for non standard + * bwmodes. + */ +int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, + int len, struct ieee80211_rate *rate) +{ + struct ath5k_softc *sc = ah->ah_sc; + int sifs, preamble, plcp_bits, sym_time; + int bitrate, bits, symbols, symbol_bits; + int dur; + + /* Fallback */ + if (!ah->ah_bwmode) { + dur = ieee80211_generic_frame_duration(sc->hw, + NULL, len, rate); + return dur; + } + + bitrate = rate->bitrate; + preamble = AR5K_INIT_OFDM_PREAMPLE_TIME; + plcp_bits = AR5K_INIT_OFDM_PLCP_BITS; + sym_time = AR5K_INIT_OFDM_SYMBOL_TIME; + + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: + sifs = AR5K_INIT_SIFS_TURBO; + preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN; + break; + case AR5K_BWMODE_10MHZ: + sifs = AR5K_INIT_SIFS_HALF_RATE; + preamble *= 2; + sym_time *= 2; + break; + case AR5K_BWMODE_5MHZ: + sifs = AR5K_INIT_SIFS_QUARTER_RATE; + preamble *= 4; + sym_time *= 4; + break; + default: + sifs = AR5K_INIT_SIFS_DEFAULT_BG; + break; + } + + bits = plcp_bits + (len << 3); + /* Bit rate is in 100Kbits */ + symbol_bits = bitrate * sym_time; + symbols = DIV_ROUND_UP(bits * 10, symbol_bits); + + dur = sifs + preamble + (sym_time * symbols); + + return dur; +} + /** * ath5k_hw_get_default_slottime - Get the default slot time for current mode * @@ -120,43 +209,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); } -/** - * ath5k_hw_set_ack_bitrate - set bitrate for ACKs - * - * @ah: The &struct ath5k_hw - * @high: Flag to determine if we want to use high transmission rate - * for ACKs or not - * - * If high flag is set, we tell hw to use a set of control rates based on - * the current transmission rate (check out control_rates array inside reset.c). - * If not hw just uses the lowest rate available for the current modulation - * scheme being used (1Mbit for CCK and 6Mbits for OFDM). - */ -void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) -{ - if (ah->ah_version != AR5K_AR5212) - return; - else { - u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; - if (high) - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); - else - AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); - } -} - /******************\ * ACK/CTS Timeouts * \******************/ -/* - * index into rates for control rates, we can set it up like this because - * this is only used for AR5212 and we know it supports G mode - */ -static const unsigned int control_rates[] = - { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; - /** * ath5k_hw_write_rate_duration - fill rate code to duration table * @@ -164,7 +221,7 @@ static const unsigned int control_rates[] = * @mode: one of enum ath5k_driver_mode * * Write the rate code to duration table upon hw reset. This is a helper for - * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on + * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on * the hardware, based on current mode, for each rate. The rates which are * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have * different rate code so we write their value twice (one for long preamble @@ -172,23 +229,30 @@ static const unsigned int control_rates[] = * * Note: Band doesn't matter here, if we set the values for OFDM it works * on both a and g modes. So all we have to do is set values for all g rates - * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ - * quarter rate mode, we need to use another set of bitrates (that's why we - * need the mode parameter) but we don't handle these proprietary modes yet. + * that include all OFDM and CCK rates. + * */ -static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, - unsigned int mode) +static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) { struct ath5k_softc *sc = ah->ah_sc; struct ieee80211_rate *rate; unsigned int i; + /* 802.11g covers both OFDM and CCK */ + u8 band = IEEE80211_BAND_2GHZ; /* Write rate duration table */ - for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { + for (i = 0; i < sc->sbands[band].n_bitrates; i++) { u32 reg; u16 tx_time; - rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; + if (ah->ah_ack_bitrate_high) + rate = &sc->sbands[band].bitrates[ack_rates_high[i]]; + /* CCK -> 1Mb */ + else if (i < 4) + rate = &sc->sbands[band].bitrates[0]; + /* OFDM -> 6Mb */ + else + rate = &sc->sbands[band].bitrates[4]; /* Set ACK timeout */ reg = AR5K_RATE_DUR(rate->hw_value); @@ -199,8 +263,9 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, * actual rate for this rate. See mac80211 tx.c * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ - tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, - NULL, 10, rate)); + tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); + + tx_time = le16_to_cpu(tx_time); ath5k_hw_reg_write(ah, tx_time, reg); @@ -835,7 +900,7 @@ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * mac80211 are integrated */ if (ah->ah_version == AR5K_AR5212 && ah->ah_sc->nvifs) - ath5k_hw_write_rate_duration(ah, mode); + ath5k_hw_write_rate_duration(ah); /* Set RSSI/BRSSI thresholds * @@ -869,5 +934,13 @@ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, if (ah->ah_coverage_class > 0) ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); + /* Set ACK bitrate mode (see ack_rates_high) */ + if (ah->ah_version == AR5K_AR5212) { + u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; + if (ah->ah_ack_bitrate_high) + AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); + else + AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); + } return; } -- cgit v1.2.3-59-g8ed1b From eeb8832b3181d6ca8593051b68c466e5d2653bb3 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:19:45 +0200 Subject: ath5k: Set all IFS intervals, not just slot time * Replace set_slot_time with set_ifs_intervals that also sets the various inter-frame space intervals based on current bwmode. * Clean up AR5210 mess from reset_tx_queue, AR5210 only has one data queue and we set IFS intervals for that queue on set_ifs_intervals so there is nothing left to do for 5210 on reset_tx_queue. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 31 +- drivers/net/wireless/ath/ath5k/pcu.c | 4 +- drivers/net/wireless/ath/ath5k/qcu.c | 513 +++++++++++++++++++-------------- drivers/net/wireless/ath/ath5k/reg.h | 3 +- 4 files changed, 308 insertions(+), 243 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 7df5b46ab690..ddbbf4c02fe1 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -222,34 +222,15 @@ /* Initial values */ #define AR5K_INIT_CYCRSSI_THR1 2 -#define AR5K_INIT_TX_LATENCY 502 -#define AR5K_INIT_USEC 39 -#define AR5K_INIT_USEC_TURBO 79 -#define AR5K_INIT_USEC_32 31 -#define AR5K_INIT_SLOT_TIME_CLOCK 396 -#define AR5K_INIT_SLOT_TIME_TURBO_CLOCK 480 -#define AR5K_INIT_ACK_CTS_TIMEOUT 1024 -#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 -#define AR5K_INIT_PROG_IFS 920 -#define AR5K_INIT_PROG_IFS_TURBO 960 -#define AR5K_INIT_EIFS 3440 -#define AR5K_INIT_EIFS_TURBO 6880 -#define AR5K_INIT_SIFS_CLOCK 560 -#define AR5K_INIT_SIFS_TURBO_CLOCK 480 + +/* Tx retry limits */ #define AR5K_INIT_SH_RETRY 10 #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY +/* For station mode */ #define AR5K_INIT_SSH_RETRY 32 #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY #define AR5K_INIT_TX_RETRY 10 -#define AR5K_INIT_PROTO_TIME_CNTRL ( \ - (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \ - (AR5K_INIT_PROG_IFS) \ -) -#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \ - (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \ - (AR5K_INIT_PROG_IFS_TURBO) \ -) /* Slot time */ #define AR5K_INIT_SLOT_TIME_TURBO 6 @@ -1240,6 +1221,10 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); /* Protocol Control Unit Functions */ +/* Helpers */ +int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, + int len, struct ieee80211_rate *rate); +unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); /* RX filter control*/ @@ -1273,7 +1258,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); +int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time); /* Init function */ int ath5k_hw_init_queues(struct ath5k_hw *ah); diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e7f6be9cdf1a..6af9504cc7f8 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -763,7 +763,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) * @ah: The &struct ath5k_hw * @coverage_class: IEEE 802.11 coverage class number * - * Sets slot time, ACK timeout and CTS timeout for given coverage class. + * Sets IFS intervals and ACK/CTS timeouts for given coverage class. */ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) { @@ -772,7 +772,7 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time; int cts_timeout = ack_timeout; - ath5k_hw_set_slot_time(ah, slot_time); + ath5k_hw_set_ifs_intervals(ah, slot_time); ath5k_hw_set_ack_timeout(ah, ack_timeout); ath5k_hw_set_cts_timeout(ah, cts_timeout); diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 6eb6838d906d..e13142a3b957 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -276,8 +276,14 @@ static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, return; } -/* - * Set DFS properties for a transmit queue on DCU +/** + * ath5k_hw_reset_tx_queue - Initialize a single hw queue + * + * @ah The &struct ath5k_hw + * @queue The hw queue number + * + * Set DFS properties for the given transmit queue on DCU + * and configures all queue-specific parameters. */ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) { @@ -287,239 +293,216 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) tq = &ah->ah_txq[queue]; - if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) + /* Skip if queue inactive or if we are on AR5210 + * that doesn't have QCU/DCU */ + if ((ah->ah_version == AR5K_AR5210) || + (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)) return 0; - if (ah->ah_version == AR5K_AR5210) { - /* Only handle data queues, others will be ignored */ - if (tq->tqi_type != AR5K_TX_QUEUE_DATA) - return 0; - - /* Set Slot time */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - AR5K_INIT_SLOT_TIME_TURBO_CLOCK : - AR5K_INIT_SLOT_TIME_CLOCK, - AR5K_SLOT_TIME); - /* Set ACK_CTS timeout */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : - AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); - - /* Set IFS0 */ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO_CLOCK + - tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO_CLOCK) - << AR5K_IFS0_DIFS_S) | - AR5K_INIT_SIFS_TURBO_CLOCK, - AR5K_IFS0); - } else { - ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_CLOCK + - tq->tqi_aifs * AR5K_INIT_SLOT_TIME_CLOCK) << - AR5K_IFS0_DIFS_S) | - AR5K_INIT_SIFS_CLOCK, AR5K_IFS0); - } - - /* Set IFS1 */ - ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? - AR5K_INIT_PROTO_TIME_CNTRL_TURBO : - AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); - } else { + /* + * Set contention window (cw_min/cw_max) + * and arbitrated interframe space (aifs)... + */ + ath5k_hw_reg_write(ah, + AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | + AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | + AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), + AR5K_QUEUE_DFS_LOCAL_IFS(queue)); - /*===Rest is also for QCU/DCU only [5211+]===*/ + /* + * Set tx retry limits for this queue + */ + ath5k_hw_set_tx_retry_limits(ah, queue); - /* - * Set contention window (cw_min/cw_max) - * and arbitrated interframe space (aifs)... - */ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | - AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | - AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), - AR5K_QUEUE_DFS_LOCAL_IFS(queue)); - /* - * Set tx retry limits for this queue - */ - ath5k_hw_set_tx_retry_limits(ah, queue); + /* + * Set misc registers + */ - /* - * Set misc registers - */ + /* Enable DCU to wait for next fragment from QCU */ + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), + AR5K_DCU_MISC_FRAG_WAIT); - /* Enable DCU to wait for next fragment from QCU */ + /* On Maui and Spirit use the global seqnum on DCU */ + if (ah->ah_mac_version < AR5K_SREV_AR5211) AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - AR5K_DCU_MISC_FRAG_WAIT); - - /* On Maui and Spirit use the global seqnum on DCU */ - if (ah->ah_mac_version < AR5K_SREV_AR5211) - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - AR5K_DCU_MISC_SEQNUM_CTL); - - if (tq->tqi_cbr_period) { - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, - AR5K_QCU_CBRCFG_INTVAL) | - AR5K_REG_SM(tq->tqi_cbr_overflow_limit, - AR5K_QCU_CBRCFG_ORN_THRES), - AR5K_QUEUE_CBRCFG(queue)); + AR5K_DCU_MISC_SEQNUM_CTL); + + /* Constant bit rate period */ + if (tq->tqi_cbr_period) { + ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, + AR5K_QCU_CBRCFG_INTVAL) | + AR5K_REG_SM(tq->tqi_cbr_overflow_limit, + AR5K_QCU_CBRCFG_ORN_THRES), + AR5K_QUEUE_CBRCFG(queue)); + + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + AR5K_QCU_MISC_FRSHED_CBR); + + if (tq->tqi_cbr_overflow_limit) AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_CBR); - if (tq->tqi_cbr_overflow_limit) - AR5K_REG_ENABLE_BITS(ah, - AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_CBR_THRES_ENABLE); - } + } + + /* Ready time interval */ + if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB)) + ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, + AR5K_QCU_RDYTIMECFG_INTVAL) | + AR5K_QCU_RDYTIMECFG_ENABLE, + AR5K_QUEUE_RDYTIMECFG(queue)); + + if (tq->tqi_burst_time) { + ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, + AR5K_DCU_CHAN_TIME_DUR) | + AR5K_DCU_CHAN_TIME_ENABLE, + AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); - if (tq->tqi_ready_time && - (tq->tqi_type != AR5K_TX_QUEUE_CAB)) - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, - AR5K_QCU_RDYTIMECFG_INTVAL) | - AR5K_QCU_RDYTIMECFG_ENABLE, - AR5K_QUEUE_RDYTIMECFG(queue)); - - if (tq->tqi_burst_time) { - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, - AR5K_DCU_CHAN_TIME_DUR) | - AR5K_DCU_CHAN_TIME_ENABLE, - AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); - - if (tq->tqi_flags - & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) - AR5K_REG_ENABLE_BITS(ah, - AR5K_QUEUE_MISC(queue), + if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_RDY_VEOL_POLICY); - } + } - if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) - ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, - AR5K_QUEUE_DFS_MISC(queue)); + /* Enable/disable Post frame backoff */ + if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) + ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, + AR5K_QUEUE_DFS_MISC(queue)); - if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) - ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, - AR5K_QUEUE_DFS_MISC(queue)); + /* Enable/disable fragmentation burst backoff */ + if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) + ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, + AR5K_QUEUE_DFS_MISC(queue)); - /* - * Set registers by queue type - */ - switch (tq->tqi_type) { - case AR5K_TX_QUEUE_BEACON: - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + /* + * Set registers by queue type + */ + switch (tq->tqi_type) { + case AR5K_TX_QUEUE_BEACON: + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_FRSHED_DBA_GT | AR5K_QCU_MISC_CBREXP_BCN_DIS | AR5K_QCU_MISC_BCN_ENABLE); - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << AR5K_DCU_MISC_ARBLOCK_CTL_S) | AR5K_DCU_MISC_ARBLOCK_IGNORE | AR5K_DCU_MISC_POST_FR_BKOFF_DIS | AR5K_DCU_MISC_BCN_ENABLE); - break; + break; + + case AR5K_TX_QUEUE_CAB: + /* XXX: use BCN_SENT_GT, if we can figure out how */ + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + AR5K_QCU_MISC_FRSHED_DBA_GT | + AR5K_QCU_MISC_CBREXP_DIS | + AR5K_QCU_MISC_CBREXP_BCN_DIS); + + ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - + (AR5K_TUNE_SW_BEACON_RESP - + AR5K_TUNE_DMA_BEACON_RESP) - + AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | + AR5K_QCU_RDYTIMECFG_ENABLE, + AR5K_QUEUE_RDYTIMECFG(queue)); - case AR5K_TX_QUEUE_CAB: - /* XXX: use BCN_SENT_GT, if we can figure out how */ - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_DBA_GT | - AR5K_QCU_MISC_CBREXP_DIS | - AR5K_QCU_MISC_CBREXP_BCN_DIS); + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), + (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << + AR5K_DCU_MISC_ARBLOCK_CTL_S)); + break; - ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - - (AR5K_TUNE_SW_BEACON_RESP - - AR5K_TUNE_DMA_BEACON_RESP) - - AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | - AR5K_QCU_RDYTIMECFG_ENABLE, - AR5K_QUEUE_RDYTIMECFG(queue)); + case AR5K_TX_QUEUE_UAPSD: + AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), + AR5K_QCU_MISC_CBREXP_DIS); + break; - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << - AR5K_DCU_MISC_ARBLOCK_CTL_S)); + case AR5K_TX_QUEUE_DATA: + default: break; + } - case AR5K_TX_QUEUE_UAPSD: - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_CBREXP_DIS); - break; + /* TODO: Handle frame compression */ - case AR5K_TX_QUEUE_DATA: - default: - break; - } + /* + * Enable interrupts for this tx queue + * in the secondary interrupt mask registers + */ + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); - /* TODO: Handle frame compression */ - - /* - * Enable interrupts for this tx queue - * in the secondary interrupt mask registers - */ - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); - - /* Update secondary interrupt mask registers */ - - /* Filter out inactive queues */ - ah->ah_txq_imr_txok &= ah->ah_txq_status; - ah->ah_txq_imr_txerr &= ah->ah_txq_status; - ah->ah_txq_imr_txurn &= ah->ah_txq_status; - ah->ah_txq_imr_txdesc &= ah->ah_txq_status; - ah->ah_txq_imr_txeol &= ah->ah_txq_status; - ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; - ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; - ah->ah_txq_imr_qtrig &= ah->ah_txq_status; - ah->ah_txq_imr_nofrm &= ah->ah_txq_status; - - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, - AR5K_SIMR0_QCU_TXOK) | - AR5K_REG_SM(ah->ah_txq_imr_txdesc, - AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0); - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, - AR5K_SIMR1_QCU_TXERR) | - AR5K_REG_SM(ah->ah_txq_imr_txeol, - AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); - /* Update simr2 but don't overwrite rest simr2 settings */ - AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); - AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, - AR5K_REG_SM(ah->ah_txq_imr_txurn, - AR5K_SIMR2_QCU_TXURN)); - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, - AR5K_SIMR3_QCBRORN) | - AR5K_REG_SM(ah->ah_txq_imr_cbrurn, - AR5K_SIMR3_QCBRURN), AR5K_SIMR3); - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, - AR5K_SIMR4_QTRIG), AR5K_SIMR4); - /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, - AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); - /* No queue has TXNOFRM enabled, disable the interrupt - * by setting AR5K_TXNOFRM to zero */ - if (ah->ah_txq_imr_nofrm == 0) - ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); - - /* Set QCU mask for this DCU to save power */ - AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); - } + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); + + if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) + AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); + + /* Update secondary interrupt mask registers */ + + /* Filter out inactive queues */ + ah->ah_txq_imr_txok &= ah->ah_txq_status; + ah->ah_txq_imr_txerr &= ah->ah_txq_status; + ah->ah_txq_imr_txurn &= ah->ah_txq_status; + ah->ah_txq_imr_txdesc &= ah->ah_txq_status; + ah->ah_txq_imr_txeol &= ah->ah_txq_status; + ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; + ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; + ah->ah_txq_imr_qtrig &= ah->ah_txq_status; + ah->ah_txq_imr_nofrm &= ah->ah_txq_status; + + ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, + AR5K_SIMR0_QCU_TXOK) | + AR5K_REG_SM(ah->ah_txq_imr_txdesc, + AR5K_SIMR0_QCU_TXDESC), + AR5K_SIMR0); + + ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, + AR5K_SIMR1_QCU_TXERR) | + AR5K_REG_SM(ah->ah_txq_imr_txeol, + AR5K_SIMR1_QCU_TXEOL), + AR5K_SIMR1); + + /* Update SIMR2 but don't overwrite rest simr2 settings */ + AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); + AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, + AR5K_REG_SM(ah->ah_txq_imr_txurn, + AR5K_SIMR2_QCU_TXURN)); + + ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, + AR5K_SIMR3_QCBRORN) | + AR5K_REG_SM(ah->ah_txq_imr_cbrurn, + AR5K_SIMR3_QCBRURN), + AR5K_SIMR3); + + ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, + AR5K_SIMR4_QTRIG), AR5K_SIMR4); + + /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ + ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, + AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); + + /* No queue has TXNOFRM enabled, disable the interrupt + * by setting AR5K_TXNOFRM to zero */ + if (ah->ah_txq_imr_nofrm == 0) + ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); + + /* Set QCU mask for this DCU to save power */ + AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); return 0; } @@ -529,24 +512,114 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) * Global QCU/DCU functions * \**************************/ -/* - * Set slot time on DCU +/** + * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU + * + * @ah The &struct ath5k_hw + * @slot_time Slot time in us + * + * Sets the global IFS intervals on DCU (also works on AR5210) for + * the given slot time and the current bwmode. */ -int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) +int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) { + struct ieee80211_channel *channel = ah->ah_current_channel; + struct ath5k_softc *sc = ah->ah_sc; + struct ieee80211_rate *rate; + u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) return -EINVAL; - if (ah->ah_version == AR5K_AR5210) - ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); + sifs = ath5k_hw_get_default_sifs(ah); + sifs_clock = ath5k_hw_htoclock(ah, sifs); + + /* EIFS + * Txtime of ack at lowest rate + SIFS + DIFS + * (DIFS = SIFS + 2 * Slot time) + * + * Note: HAL has some predefined values for EIFS + * Turbo: (37 + 2 * 6) + * Default: (74 + 2 * 9) + * Half: (149 + 2 * 13) + * Quarter: (298 + 2 * 21) + * + * (74 + 2 * 6) for AR5210 default and turbo ! + * + * According to the formula we have + * ack_tx_time = 25 for turbo and + * ack_tx_time = 42.5 * clock multiplier + * for default/half/quarter. + * + * This can't be right, 42 is what we would get + * from ath5k_hw_get_frame_dur_for_bwmode or + * ieee80211_generic_frame_duration for zero frame + * length and without SIFS ! + * + * Also we have different lowest rate for 802.11a + */ + if (channel->hw_value & CHANNEL_5GHZ) + rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; else - ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); + rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; + + ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); + + /* ack_tx_time includes an SIFS already */ + eifs = ack_tx_time + sifs + 2 * slot_time; + eifs_clock = ath5k_hw_htoclock(ah, eifs); + + /* Set IFS settings on AR5210 */ + if (ah->ah_version == AR5K_AR5210) { + u32 pifs, pifs_clock, difs, difs_clock; + + /* Set slot time */ + ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); + + /* Set EIFS */ + eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS); + + /* PIFS = Slot time + SIFS */ + pifs = slot_time + sifs; + pifs_clock = ath5k_hw_htoclock(ah, pifs); + pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS); + + /* DIFS = SIFS + 2 * Slot time */ + difs = sifs + 2 * slot_time; + difs_clock = ath5k_hw_htoclock(ah, difs); + + /* Set SIFS/DIFS */ + ath5k_hw_reg_write(ah, (difs_clock << + AR5K_IFS0_DIFS_S) | sifs_clock, + AR5K_IFS0); + + /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */ + ath5k_hw_reg_write(ah, pifs_clock | eifs_clock | + (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S), + AR5K_IFS1); + + return 0; + } + + /* Set IFS slot time */ + ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); + + /* Set EIFS interval */ + ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS); + + /* Set SIFS interval in usecs */ + AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, + AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC, + sifs); + + /* Set SIFS interval in clock cycles */ + ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS); return 0; } + int ath5k_hw_init_queues(struct ath5k_hw *ah) { int i, ret; @@ -559,14 +632,20 @@ int ath5k_hw_init_queues(struct ath5k_hw *ah) * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping * Note: If we want we can assign multiple qcus on one dcu. */ - for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { - ret = ath5k_hw_reset_tx_queue(ah, i); - if (ret) { - ATH5K_ERR(ah->ah_sc, - "failed to reset TX queue #%d\n", i); - return ret; + if (ah->ah_version != AR5K_AR5210) + for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { + ret = ath5k_hw_reset_tx_queue(ah, i); + if (ret) { + ATH5K_ERR(ah->ah_sc, + "failed to reset TX queue #%d\n", i); + return ret; + } } - } + else + /* No QCU/DCU on AR5210, just set tx + * retry limits. We set IFS parameters + * on ath5k_hw_set_ifs_intervals */ + ath5k_hw_set_tx_retry_limits(ah, 0); return 0; } diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index dc213bb121e6..8516728a407e 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -787,6 +787,7 @@ #define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ +#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4 #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ @@ -1311,7 +1312,7 @@ #define AR5K_IFS1_EIFS 0x03fff000 #define AR5K_IFS1_EIFS_S 12 #define AR5K_IFS1_CS_EN 0x04000000 - +#define AR5K_IFS1_CS_EN_S 26 /* * CFP duration register -- cgit v1.2.3-59-g8ed1b From 473cae27620c27377e278a6f92aaa483060e3c19 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:21:50 +0200 Subject: ath5k: Use turbo flag on DCU * Set AR5K_DCU_GBL_IFS_MISC_TURBO_MODE flag on DCU when operating on 40MHz Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/qcu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index e13142a3b957..69bff047a49a 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -647,5 +647,10 @@ int ath5k_hw_init_queues(struct ath5k_hw *ah) * on ath5k_hw_set_ifs_intervals */ ath5k_hw_set_tx_retry_limits(ah, 0); + /* Set the turbo flag when operating on 40MHz */ + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) + AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, + AR5K_DCU_GBL_IFS_MISC_TURBO_MODE); + return 0; } -- cgit v1.2.3-59-g8ed1b From 71ba1c30851575b43ba76b0f9c26ff5567e8136c Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:24:54 +0200 Subject: ath5k: Always set IFS intervals on reset * Make sure we always set IFS timings even if no coverage class is set. If we don't we'll miss the needed changes for different bwmodes. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/pcu.c | 2 +- drivers/net/wireless/ath/ath5k/qcu.c | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ddbbf4c02fe1..e2588308e677 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1224,6 +1224,7 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); /* Helpers */ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, int len, struct ieee80211_rate *rate); +unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 6af9504cc7f8..e5f2b96a4c63 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -129,7 +129,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, * * @ah: The &struct ath5k_hw */ -static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) +unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; unsigned int slot_time; diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 69bff047a49a..1849eee8235c 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -652,5 +652,13 @@ int ath5k_hw_init_queues(struct ath5k_hw *ah) AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, AR5K_DCU_GBL_IFS_MISC_TURBO_MODE); + /* If we didn't set IFS timings through + * ath5k_hw_set_coverage_class make sure + * we set them here */ + if (!ah->ah_coverage_class) { + unsigned int slot_time = ath5k_hw_get_default_slottime(ah); + ath5k_hw_set_ifs_intervals(ah, slot_time); + } + return 0; } -- cgit v1.2.3-59-g8ed1b From b2b4c69f682a2868411899a77842061dd745884f Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:26:13 +0200 Subject: ath5k: Tweak power detector delays on RF5111/RF5112 * Tweak power detector delays on AR5111/AR5112 when using half/quarter modes. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 706fc461be61..6913a52cecc5 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -851,7 +851,23 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], AR5K_RF_PLO_SEL, true); - /* TODO: Half/quarter channel support */ + /* Tweak power detectors for half/quarter rate support */ + if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || + ah->ah_bwmode == AR5K_BWMODE_10MHZ) { + u8 wait_i; + + ath5k_hw_rfb_op(ah, rf_regs, 0x1f, + AR5K_RF_WAIT_S, true); + + wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? + 0x1f : 0x10; + + ath5k_hw_rfb_op(ah, rf_regs, wait_i, + AR5K_RF_WAIT_I, true); + ath5k_hw_rfb_op(ah, rf_regs, 3, + AR5K_RF_MAX_TIME, true); + + } } if (ah->ah_radio == AR5K_RF5112) { @@ -949,8 +965,20 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], AR5K_RF_GAIN_I, true); - /* TODO: Half/quarter channel support */ + /* Tweak power detector for half/quarter rates */ + if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || + ah->ah_bwmode == AR5K_BWMODE_10MHZ) { + u8 pd_delay; + + pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? + 0xf : 0x8; + ath5k_hw_rfb_op(ah, rf_regs, pd_delay, + AR5K_RF_PD_PERIOD_A, true); + ath5k_hw_rfb_op(ah, rf_regs, 0xf, + AR5K_RF_PD_DELAY_A, true); + + } } if (ah->ah_radio == AR5K_RF5413 && -- cgit v1.2.3-59-g8ed1b From a2677fe4298c61f0e93c063e59815bf21c530c4a Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:28:15 +0200 Subject: ath5k: Update spur mitigation filter for turbo/half/quarter * Add spur mitigation filter support for half/quarter and turbo. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 53 ++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6913a52cecc5..b9089151e7dc 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1622,7 +1622,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, spur_chan_fbin = AR5K_EEPROM_NO_SPUR; spur_detection_window = AR5K_SPUR_CHAN_WIDTH; /* XXX: Half/Quarter channels ?*/ - if (channel->hw_value & CHANNEL_TURBO) + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) spur_detection_window *= 2; for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { @@ -1651,32 +1651,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, * Calculate deltas: * spur_freq_sigma_delta -> spur_offset / sample_freq << 21 * spur_delta_phase -> spur_offset / chip_freq << 11 - * Note: Both values have 100KHz resolution + * Note: Both values have 100Hz resolution */ - /* XXX: Half/Quarter rate channels ? */ - switch (channel->hw_value) { - case CHANNEL_A: - /* Both sample_freq and chip_freq are 40MHz */ - spur_delta_phase = (spur_offset << 17) / 25; - spur_freq_sigma_delta = (spur_delta_phase >> 10); - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; - break; - case CHANNEL_G: - /* sample_freq -> 40MHz chip_freq -> 44MHz - * (for b compatibility) */ - spur_freq_sigma_delta = (spur_offset << 8) / 55; - spur_delta_phase = (spur_offset << 17) / 25; - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; - break; - case CHANNEL_T: - case CHANNEL_TG: + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: /* Both sample_freq and chip_freq are 80MHz */ spur_delta_phase = (spur_offset << 16) / 25; spur_freq_sigma_delta = (spur_delta_phase >> 10); - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz; + symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2; break; + case AR5K_BWMODE_10MHZ: + /* Both sample_freq and chip_freq are 20MHz (?) */ + spur_delta_phase = (spur_offset << 18) / 25; + spur_freq_sigma_delta = (spur_delta_phase >> 10); + symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2; + case AR5K_BWMODE_5MHZ: + /* Both sample_freq and chip_freq are 10MHz (?) */ + spur_delta_phase = (spur_offset << 19) / 25; + spur_freq_sigma_delta = (spur_delta_phase >> 10); + symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; default: - return; + if (channel->hw_value == CHANNEL_A) { + /* Both sample_freq and chip_freq are 40MHz */ + spur_delta_phase = (spur_offset << 17) / 25; + spur_freq_sigma_delta = + (spur_delta_phase >> 10); + symbol_width = + AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; + } else { + /* sample_freq -> 40MHz chip_freq -> 44MHz + * (for b compatibility) */ + spur_delta_phase = (spur_offset << 17) / 25; + spur_freq_sigma_delta = + (spur_offset << 8) / 55; + symbol_width = + AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; + } + break; } /* Calculate pilot and magnitude masks */ -- cgit v1.2.3-59-g8ed1b From f08fbf6cf4a31c8df52b21440c7a7e6fbe474b28 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:33:22 +0200 Subject: ath5k: Update PLL programming for turbo/half/quarter * Set correct PLL settings for each bwmode Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index c871d40b1ad7..ec013103a6af 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -500,7 +500,6 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) /* * Bring up MAC + PHY Chips and program PLL - * TODO: Half/Quarter rate support */ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) { @@ -588,7 +587,8 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) * CCK headers) operation. We need to test * this, 5211 might support ofdm-only g after * all, there are also initial register values - * in the code for g mode (see initvals.c). */ + * in the code for g mode (see initvals.c). + */ if (ah->ah_version == AR5K_AR5211) mode |= AR5K_PHY_MODE_MOD_OFDM; else @@ -601,6 +601,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) } else if (flags & CHANNEL_5GHZ) { mode |= AR5K_PHY_MODE_FREQ_5GHZ; + /* Different PLL setting for 5413 */ if (ah->ah_radio == AR5K_RF5413) clock = AR5K_PHY_PLL_40MHZ_5413; else @@ -618,12 +619,29 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) return -EINVAL; } - if (flags & CHANNEL_TURBO) - turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; + /*XXX: Can bwmode be used with dynamic mode ? + * (I don't think it supports 44MHz) */ + /* On 2425 initvals TURBO_SHORT is not pressent */ + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { + turbo = AR5K_PHY_TURBO_MODE | + (ah->ah_radio == AR5K_RF2425) ? 0 : + AR5K_PHY_TURBO_SHORT; + } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { + if (ah->ah_radio == AR5K_RF5413) { + mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? + AR5K_PHY_MODE_HALF_RATE : + AR5K_PHY_MODE_QUARTER_RATE; + } else if (ah->ah_version == AR5K_AR5212) { + clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? + AR5K_PHY_PLL_HALF_RATE : + AR5K_PHY_PLL_QUARTER_RATE; + } + } + } else { /* Reset the device */ /* ...enable Atheros turbo mode if requested */ - if (flags & CHANNEL_TURBO) + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, AR5K_PHY_TURBO); } -- cgit v1.2.3-59-g8ed1b From 4c57581d939fd0f8f244b9730812069f4dac308a Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:37:30 +0200 Subject: ath5k: Skip powertable setting when we are on the same channel * Only set power table if we are changing channel/mode there is no need to recalculate and reset the power table all the time. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 65 +++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index b9089151e7dc..9392320eb301 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3090,7 +3090,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, */ static int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 ee_mode, u8 txpower) + u8 ee_mode, u8 txpower, bool fast) { struct ath5k_rate_pcal_info rate_info; u8 type; @@ -3126,10 +3126,15 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - /* FIXME: Only on channel/mode change */ - ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type); - if (ret) - return ret; + /* If fast is set it means we are on the same channel/mode + * so there is no need to recalculate the powertable, we 'll + * just use the cached one */ + if (!fast) { + ret = ath5k_setup_channel_powertable(ah, channel, + ee_mode, type); + if (ret) + return ret; + } /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); @@ -3210,7 +3215,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, "changing txpower to %d\n", txpower); - return ath5k_hw_txpower(ah, channel, ee_mode, txpower); + return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true); } /*************\ @@ -3220,13 +3225,42 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 mode, u8 ee_mode, u8 freq) { + struct ieee80211_channel *curr_channel; int ret, i; u32 phy_tst1; - + bool fast_txp; ret = 0; /* - * 5211/5212 Specific + * If we don't change channel/mode skip + * tx powertable calculation and use the + * cached one. + */ + curr_channel = ah->ah_current_channel; + if ((channel->hw_value == curr_channel->hw_value) && + (channel->center_freq == curr_channel->center_freq)) + fast_txp = true; + else + fast_txp = false; + + /* + * Set TX power + * + * Note: We need to do that before we set + * RF buffer settings on 5211/5212+ so that we + * properly set curve indices. + */ + ret = ath5k_hw_txpower(ah, channel, ee_mode, + ah->ah_txpower.txp_max_pwr / 2, + fast_txp); + if (ret) + return ret; + + /* + * For 5210 we do all initialization using + * initvals, so we don't have to modify + * any settings (5210 also only supports + * a/aturbo modes) */ if (ah->ah_version != AR5K_AR5210) { @@ -3240,14 +3274,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, mdelay(1); - /* - * Set TX power - */ - ret = ath5k_hw_txpower(ah, channel, ee_mode, - ah->ah_txpower.txp_max_pwr / 2); - if (ret) - return ret; - /* * Write RF buffer */ @@ -3255,7 +3281,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, if (ret) return ret; - /* Write OFDM timings on 5212*/ if (ah->ah_version == AR5K_AR5212 && channel->hw_value & CHANNEL_OFDM) { @@ -3284,12 +3309,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, } } else { - /* - * For 5210 we do all initialization using - * initvals, so we don't have to modify - * any settings (5210 also only supports - * a/aturbo modes) - */ mdelay(1); /* Disable phy and wait */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); -- cgit v1.2.3-59-g8ed1b From 8aec7af99b1e4594c4bb9e1c48005e6111f97e8e Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:39:28 +0200 Subject: ath5k: Support synth-only channel change for AR2413/AR5413 * Add synth-only channel change for AR2413/5413. When we call ath5k_reset with a channel ath5k_hw_reset will first try to set channel on PHY while PHY is running instead of doing a normal full reset. To do this phy_init has to change to implement this functionality. * Clean up change_channel flag, what it really did was skip PCU registers when setting initvals. This is done because on reset PCU registers are not affected (except the registers we set in pcu init and -due to hw problems- TSF). Use a new skip_pcu flag that's not misleading instead. In the future we might use that to also skip PCU reset and save us the TSF etc problems (needs testing because standard practice is to reset everything). * Use fast channel change only when setting channel, and set skip_pcu to false only on init. When we reset the card due to DMA or PHY problems skip pcu but never do a fast channel change. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 4 +- drivers/net/wireless/ath/ath5k/base.c | 17 ++- drivers/net/wireless/ath/ath5k/phy.c | 64 ++++++-- drivers/net/wireless/ath/ath5k/reset.c | 267 +++++++++++++++++++-------------- 4 files changed, 218 insertions(+), 134 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e2588308e677..385b91911abc 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1183,7 +1183,7 @@ void ath5k_unregister_leds(struct ath5k_softc *sc); int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); int ath5k_hw_on_hold(struct ath5k_hw *ah); int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, - struct ieee80211_channel *channel, bool change_channel); + struct ieee80211_channel *channel, bool fast, bool skip_pcu); int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set); /* Power management functions */ @@ -1324,7 +1324,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); /* Init function */ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, u8 freq); + u8 mode, u8 ee_mode, u8 freq, bool fast); /* * Functions used internaly diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 526d8bc412c0..33cd1bc4a71c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -80,7 +80,8 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); -static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, + bool skip_pcu); static int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); @@ -496,7 +497,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - return ath5k_reset(sc, chan); + return ath5k_reset(sc, chan, true); } static void @@ -2327,7 +2328,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work) if (needreset) { ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "TX queues stuck, resetting\n"); - ath5k_reset(sc, sc->curchan); + ath5k_reset(sc, NULL, true); } ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, @@ -2407,7 +2408,7 @@ ath5k_init(struct ath5k_softc *sc) AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; - ret = ath5k_reset(sc, NULL); + ret = ath5k_reset(sc, NULL, false); if (ret) goto done; @@ -2506,7 +2507,8 @@ ath5k_stop_hw(struct ath5k_softc *sc) * This should be called with sc->lock. */ static int -ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) +ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, + bool skip_pcu) { struct ath5k_hw *ah = sc->ah; int ret; @@ -2523,7 +2525,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) sc->curchan = chan; sc->curband = &sc->sbands[chan->band]; } - ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL); + ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, + skip_pcu); if (ret) { ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); goto err; @@ -2569,7 +2572,7 @@ static void ath5k_reset_work(struct work_struct *work) reset_work); mutex_lock(&sc->lock); - ath5k_reset(sc, sc->curchan); + ath5k_reset(sc, NULL, true); mutex_unlock(&sc->lock); } diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 9392320eb301..1b6fcf9e097b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3223,7 +3223,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) \*************/ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, u8 freq) + u8 mode, u8 ee_mode, u8 freq, bool fast) { struct ieee80211_channel *curr_channel; int ret, i; @@ -3231,12 +3231,38 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, bool fast_txp; ret = 0; + /* + * Sanity check for fast flag + * Don't try fast channel change when changing modulation + * mode/band. We check for chip compatibility on + * ath5k_hw_reset. + */ + curr_channel = ah->ah_current_channel; + if (fast && (channel->hw_value != curr_channel->hw_value)) + return -EINVAL; + + /* + * On fast channel change we only set the synth parameters + * while PHY is running, enable calibration and skip the rest. + */ + if (fast) { + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, + AR5K_PHY_RFBUS_REQ_REQUEST); + for (i = 0; i < 100; i++) { + if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT)) + break; + udelay(5); + } + /* Failed */ + if (i >= 100) + return -EIO; + } + /* * If we don't change channel/mode skip * tx powertable calculation and use the * cached one. */ - curr_channel = ah->ah_current_channel; if ((channel->hw_value == curr_channel->hw_value) && (channel->center_freq == curr_channel->center_freq)) fast_txp = true; @@ -3262,7 +3288,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, * any settings (5210 also only supports * a/aturbo modes) */ - if (ah->ah_version != AR5K_AR5210) { + if ((ah->ah_version != AR5K_AR5210) && !fast) { /* * Write initial RF gain settings @@ -3308,7 +3334,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, AR5K_TXCFG_B_MODE); } - } else { + } else if (ah->ah_version == AR5K_AR5210) { mdelay(1); /* Disable phy and wait */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); @@ -3345,18 +3371,26 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, mdelay(1); } - /* - * Perform ADC test to see if baseband is ready - * Set TX hold and check ADC test register - */ - phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); - ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); - for (i = 0; i <= 20; i++) { - if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) - break; - udelay(200); + if (fast) + /* + * Release RF Bus grant + */ + AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, + AR5K_PHY_RFBUS_REQ_REQUEST); + else { + /* + * Perform ADC test to see if baseband is ready + * Set tx hold and check adc test register + */ + phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); + ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); + for (i = 0; i <= 20; i++) { + if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) + break; + udelay(200); + } + ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); } - ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); /* * Start automatic gain control calibration diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index ec013103a6af..e02bcbbd7a80 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -938,7 +938,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, \*********************/ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, - struct ieee80211_channel *channel, bool change_channel) + struct ieee80211_channel *channel, bool fast, bool skip_pcu) { struct ath_common *common = ath5k_hw_common(ah); u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; @@ -952,6 +952,20 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, freq = 0; mode = 0; + /* + * Sanity check for fast flag + * Fast channel change only available + * on AR2413/AR5413. + */ + if (fast && (ah->ah_radio != AR5K_RF2413) && + (ah->ah_radio != AR5K_RF5413)) + fast = 0; + + /* Disable sleep clock operation + * to avoid register access delay on certain + * PHY registers */ + if (ah->ah_version == AR5K_AR5212) + ath5k_hw_set_sleep_clock(ah, false); /* * Stop PCU @@ -964,111 +978,137 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * Note: If DMA didn't stop continue * since only a reset will fix it. */ - ath5k_hw_dma_stop(ah); + ret = ath5k_hw_dma_stop(ah); + + /* RF Bus grant won't work if we have pending + * frames */ + if (ret && fast) { + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, + "DMA didn't stop, falling back to normal reset\n"); + fast = 0; + /* Non fatal, just continue with + * normal reset */ + ret = 0; + } - /* - * Save some registers before a reset - */ - /*DCU/Antenna selection not available on 5210*/ - if (ah->ah_version != AR5K_AR5210) { + switch (channel->hw_value & CHANNEL_MODES) { + case CHANNEL_A: + mode = AR5K_MODE_11A; + freq = AR5K_INI_RFGAIN_5GHZ; + ee_mode = AR5K_EEPROM_MODE_11A; + break; + case CHANNEL_G: - switch (channel->hw_value & CHANNEL_MODES) { - case CHANNEL_A: - mode = AR5K_MODE_11A; - freq = AR5K_INI_RFGAIN_5GHZ; - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_G: - mode = AR5K_MODE_11G; - freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11G; - break; - case CHANNEL_B: - mode = AR5K_MODE_11B; - freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11B; - break; - case CHANNEL_T: - mode = AR5K_MODE_11A_TURBO; - freq = AR5K_INI_RFGAIN_5GHZ; - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_TG: - if (ah->ah_version == AR5K_AR5211) { - ATH5K_ERR(ah->ah_sc, - "TurboG mode not available on 5211"); - return -EINVAL; - } - mode = AR5K_MODE_11G_TURBO; - freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11G; - break; - case CHANNEL_XR: - if (ah->ah_version == AR5K_AR5211) { - ATH5K_ERR(ah->ah_sc, - "XR mode not available on 5211"); - return -EINVAL; - } - mode = AR5K_MODE_XR; - freq = AR5K_INI_RFGAIN_5GHZ; - ee_mode = AR5K_EEPROM_MODE_11A; - break; - default: + if (ah->ah_version <= AR5K_AR5211) { ATH5K_ERR(ah->ah_sc, - "invalid channel: %d\n", channel->center_freq); + "G mode not available on 5210/5211"); return -EINVAL; } - if (change_channel) { - /* - * Save frame sequence count - * For revs. after Oahu, only save - * seq num for DCU 0 (Global seq num) - */ - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - - for (i = 0; i < 10; i++) - s_seq[i] = ath5k_hw_reg_read(ah, - AR5K_QUEUE_DCU_SEQNUM(i)); + mode = AR5K_MODE_11G; + freq = AR5K_INI_RFGAIN_2GHZ; + ee_mode = AR5K_EEPROM_MODE_11G; + break; + case CHANNEL_B: - } else { - s_seq[0] = ath5k_hw_reg_read(ah, - AR5K_QUEUE_DCU_SEQNUM(0)); - } + if (ah->ah_version < AR5K_AR5211) { + ATH5K_ERR(ah->ah_sc, + "B mode not available on 5210"); + return -EINVAL; + } - /* TSF accelerates on AR5211 during reset - * As a workaround save it here and restore - * it later so that it's back in time after - * reset. This way it'll get re-synced on the - * next beacon without breaking ad-hoc. - * - * On AR5212 TSF is almost preserved across a - * reset so it stays back in time anyway and - * we don't have to save/restore it. - * - * XXX: Since this breaks power saving we have - * to disable power saving until we receive the - * next beacon, so we can resync beacon timers */ - if (ah->ah_version == AR5K_AR5211) { - tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); - tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); - } + mode = AR5K_MODE_11B; + freq = AR5K_INI_RFGAIN_2GHZ; + ee_mode = AR5K_EEPROM_MODE_11B; + break; + case CHANNEL_T: + mode = AR5K_MODE_11A_TURBO; + freq = AR5K_INI_RFGAIN_5GHZ; + ee_mode = AR5K_EEPROM_MODE_11A; + break; + case CHANNEL_TG: + if (ah->ah_version == AR5K_AR5211) { + ATH5K_ERR(ah->ah_sc, + "TurboG mode not available on 5211"); + return -EINVAL; } + mode = AR5K_MODE_11G_TURBO; + freq = AR5K_INI_RFGAIN_2GHZ; + ee_mode = AR5K_EEPROM_MODE_11G; + break; + case CHANNEL_XR: + if (ah->ah_version == AR5K_AR5211) { + ATH5K_ERR(ah->ah_sc, + "XR mode not available on 5211"); + return -EINVAL; + } + mode = AR5K_MODE_XR; + freq = AR5K_INI_RFGAIN_5GHZ; + ee_mode = AR5K_EEPROM_MODE_11A; + break; + default: + ATH5K_ERR(ah->ah_sc, + "invalid channel: %d\n", channel->center_freq); + return -EINVAL; + } - if (ah->ah_version == AR5K_AR5212) { - /* Restore normal 32/40MHz clock operation - * to avoid register access delay on certain - * PHY registers */ - ath5k_hw_set_sleep_clock(ah, false); + /* + * If driver requested fast channel change and DMA has stopped + * go on. If it fails continue with a normal reset. + */ + if (fast) { + ret = ath5k_hw_phy_init(ah, channel, mode, + ee_mode, freq, true); + if (ret) { + ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, + "fast chan change failed, falling back to normal reset\n"); + /* Non fatal, can happen eg. + * on mode change */ + ret = 0; + } else + return 0; + } - /* Since we are going to write rf buffer - * check if we have any pending gain_F - * optimization settings */ - if (change_channel && ah->ah_rf_banks != NULL) - ath5k_hw_gainf_calibrate(ah); + /* + * Save some registers before a reset + */ + if (ah->ah_version != AR5K_AR5210) { + /* + * Save frame sequence count + * For revs. after Oahu, only save + * seq num for DCU 0 (Global seq num) + */ + if (ah->ah_mac_srev < AR5K_SREV_AR5211) { + + for (i = 0; i < 10; i++) + s_seq[i] = ath5k_hw_reg_read(ah, + AR5K_QUEUE_DCU_SEQNUM(i)); + + } else { + s_seq[0] = ath5k_hw_reg_read(ah, + AR5K_QUEUE_DCU_SEQNUM(0)); + } + + /* TSF accelerates on AR5211 during reset + * As a workaround save it here and restore + * it later so that it's back in time after + * reset. This way it'll get re-synced on the + * next beacon without breaking ad-hoc. + * + * On AR5212 TSF is almost preserved across a + * reset so it stays back in time anyway and + * we don't have to save/restore it. + * + * XXX: Since this breaks power saving we have + * to disable power saving until we receive the + * next beacon, so we can resync beacon timers */ + if (ah->ah_version == AR5K_AR5211) { + tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); + tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); } } + /*GPIOs*/ s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE; @@ -1085,6 +1125,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_SELFGEN_DEF_ANT); + /* + * Since we are going to write rf buffer + * check if we have any pending gain_F + * optimization settings + */ + if (ah->ah_version == AR5K_AR5212 && + (ah->ah_radio <= AR5K_RF5112)) { + if (!fast && ah->ah_rf_banks != NULL) + ath5k_hw_gainf_calibrate(ah); + } + /* Wakeup the device */ ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); if (ret) @@ -1098,7 +1149,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, AR5K_PHY(0)); /* Write initial settings */ - ret = ath5k_hw_write_initvals(ah, mode, change_channel); + ret = ath5k_hw_write_initvals(ah, mode, skip_pcu); if (ret) return ret; @@ -1120,24 +1171,20 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * Restore saved values */ - /*DCU/Antenna selection not available on 5210*/ + /* Seqnum, TSF */ if (ah->ah_version != AR5K_AR5210) { + if (ah->ah_mac_srev < AR5K_SREV_AR5211) { + for (i = 0; i < 10; i++) + ath5k_hw_reg_write(ah, s_seq[i], + AR5K_QUEUE_DCU_SEQNUM(i)); + } else { + ath5k_hw_reg_write(ah, s_seq[0], + AR5K_QUEUE_DCU_SEQNUM(0)); + } - if (change_channel) { - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - for (i = 0; i < 10; i++) - ath5k_hw_reg_write(ah, s_seq[i], - AR5K_QUEUE_DCU_SEQNUM(i)); - } else { - ath5k_hw_reg_write(ah, s_seq[0], - AR5K_QUEUE_DCU_SEQNUM(0)); - } - - - if (ah->ah_version == AR5K_AR5211) { - ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32); - ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); - } + if (ah->ah_version == AR5K_AR5211) { + ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32); + ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); } } @@ -1165,7 +1212,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* * Initialize PHY */ - ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq); + ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false); if (ret) { ATH5K_ERR(ah->ah_sc, "failed to initialize PHY (%i) !\n", ret); -- cgit v1.2.3-59-g8ed1b From c2b0ebef262e0a9b64f7ea8ec837cfc29605bef7 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:42:22 +0200 Subject: ath5k: No need to save/restore staid flags on reset * Since we set antenna flags on phy init and ack bitrate mode on pcu init, there is no need to save/restore sta_id flags on ath5k_hw_reset. Also we don't need to re-set our mac address because it's not affected by resets. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index e02bcbbd7a80..c72910015454 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -940,13 +940,11 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool fast, bool skip_pcu) { - struct ath_common *common = ath5k_hw_common(ah); - u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; + u32 s_seq[10], s_led[3], tsf_up, tsf_lo; u8 mode, freq, ee_mode; int i, ret; ee_mode = 0; - staid1_flags = 0; tsf_up = 0; tsf_lo = 0; freq = 0; @@ -1115,15 +1113,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); - /* AR5K_STA_ID1 flags, only preserve antenna - * settings and ack/cts rate mode */ - staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & - (AR5K_STA_ID1_DEFAULT_ANTENNA | - AR5K_STA_ID1_DESC_ANTENNA | - AR5K_STA_ID1_RTS_DEF_ANTENNA | - AR5K_STA_ID1_ACKCTS_6MB | - AR5K_STA_ID1_BASE_RATE_11B | - AR5K_STA_ID1_SELFGEN_DEF_ANT); /* * Since we are going to write rf buffer @@ -1195,15 +1184,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); - /* Restore sta_id flags and preserve our mac address*/ - ath5k_hw_reg_write(ah, - get_unaligned_le32(common->macaddr), - AR5K_STA_ID0); - ath5k_hw_reg_write(ah, - staid1_flags | get_unaligned_le16(common->macaddr + 4), - AR5K_STA_ID1); - - /* * Initialize PCU */ -- cgit v1.2.3-59-g8ed1b From b02f5d1a17c652a74098f2a04db7fb8e6220057e Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:44:02 +0200 Subject: ath5k: Tweak phy activate to rx start delay based on bwmode * Tweak phy activation -> rx delay for different bwmodes Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1b6fcf9e097b..8790f0ab1983 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3356,8 +3356,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* * On 5211+ read activation -> rx delay * and use it. - * - * TODO: Half/quarter rate support */ if (ah->ah_version != AR5K_AR5210) { u32 delay; @@ -3365,8 +3363,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, AR5K_PHY_RX_DELAY_M; delay = (channel->hw_value & CHANNEL_CCK) ? ((delay << 2) / 22) : (delay / 10); - - udelay(100 + (2 * delay)); + if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) + delay = delay << 1; + if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) + delay = delay << 2; + /* XXX: /2 on turbo ? Let's be safe + * for now */ + udelay(100 + delay); } else { mdelay(1); } -- cgit v1.2.3-59-g8ed1b From 3bb17654605965226e5b322dbc22ece5ff354ac5 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:45:21 +0200 Subject: ath5k: Skip tx power setting on AR5210 for now * Don't return -EINVAL when trying to set tx power on RF5110 because AR5210 reset will fail. We need to add support for RF5110 and AR5210 eeprom in the future but for now just skip it. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 8790f0ab1983..31239ab6a003 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3109,6 +3109,9 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Initialize TX power table */ switch (ah->ah_radio) { + case AR5K_RF5110: + /* TODO */ + return 0; case AR5K_RF5111: type = AR5K_PWRTABLE_PWR_TO_PCDAC; break; -- cgit v1.2.3-59-g8ed1b From 73a06a683455f472cc09ad249064c66a41e29e39 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:48:32 +0200 Subject: ath5k: Use correct clock when setting ofdm timings * Use correct clock value when setting OFDM timings on non-default bwmodes. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 31239ab6a003..95b602b4f446 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -228,8 +228,20 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, * ALGO: coef = (5 * clock / carrier_freq) / 2 * we scale coef by shifting clock value by 24 for * better precision since we use integers */ - /* TODO: Half/quarter rate */ - clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40; + switch (ah->ah_bwmode) { + case AR5K_BWMODE_40MHZ: + clock = 40 * 2; + break; + case AR5K_BWMODE_10MHZ: + clock = 40 / 2; + break; + case AR5K_BWMODE_5MHZ: + clock = 40 / 4; + break; + default: + clock = 40; + break; + } coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; /* Get exponent -- cgit v1.2.3-59-g8ed1b From acb091d67c5c9649cf5d25055ef6fd64239a6762 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:49:53 +0200 Subject: ath5k: Cleanup turbo channel flags * Clean up CHANNEL_T(URBO), use AR5K_BWMODE_40MHZ instead Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 9 +-------- drivers/net/wireless/ath/ath5k/base.c | 5 ----- drivers/net/wireless/ath/ath5k/phy.c | 22 ++++++++-------------- drivers/net/wireless/ath/ath5k/reset.c | 17 +---------------- 4 files changed, 10 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 385b91911abc..81ad236932c8 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -686,7 +686,6 @@ struct ath5k_gain { /* channel_flags */ #define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */ -#define CHANNEL_TURBO 0x0010 /* Turbo Channel */ #define CHANNEL_CCK 0x0020 /* CCK channel */ #define CHANNEL_OFDM 0x0040 /* OFDM channel */ #define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */ @@ -698,16 +697,10 @@ struct ath5k_gain { #define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) #define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) #define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) -#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO) -#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO) -#define CHANNEL_108A CHANNEL_T -#define CHANNEL_108G CHANNEL_TG #define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR) -#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \ - CHANNEL_TURBO) +#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ) -#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO) #define CHANNEL_MODES CHANNEL_ALL /* diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 33cd1bc4a71c..80831171f1b0 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -364,11 +364,6 @@ ath5k_copy_channels(struct ath5k_hw *ah, case AR5K_MODE_11G: channels[count].hw_value = chfreq | CHANNEL_OFDM; break; - case AR5K_MODE_11A_TURBO: - case AR5K_MODE_11G_TURBO: - channels[count].hw_value = chfreq | - CHANNEL_OFDM | CHANNEL_TURBO; - break; case AR5K_MODE_11B: channels[count].hw_value = CHANNEL_B; } diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 95b602b4f446..61d3800c8118 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1358,12 +1358,10 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: - case CHANNEL_T: case CHANNEL_XR: ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: - case CHANNEL_TG: ee_mode = AR5K_EEPROM_MODE_11G; break; default: @@ -1946,12 +1944,10 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: - case CHANNEL_T: case CHANNEL_XR: ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: - case CHANNEL_TG: ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_B: @@ -2385,20 +2381,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah, switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: - ctl_mode |= AR5K_CTL_11A; + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) + ctl_mode |= AR5K_CTL_TURBO; + else + ctl_mode |= AR5K_CTL_11A; break; case CHANNEL_G: - ctl_mode |= AR5K_CTL_11G; + if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) + ctl_mode |= AR5K_CTL_TURBOG; + else + ctl_mode |= AR5K_CTL_11G; break; case CHANNEL_B: ctl_mode |= AR5K_CTL_11B; break; - case CHANNEL_T: - ctl_mode |= AR5K_CTL_TURBO; - break; - case CHANNEL_TG: - ctl_mode |= AR5K_CTL_TURBOG; - break; case CHANNEL_XR: /* Fall through */ default: @@ -3210,12 +3206,10 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: - case CHANNEL_T: case CHANNEL_XR: ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: - case CHANNEL_TG: ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_B: diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index c72910015454..7d8ef8decf00 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -834,7 +834,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), AR5K_PHY_NFTHRES); - if ((channel->hw_value & CHANNEL_TURBO) && + if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) && (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { /* Switch settling time (Turbo) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, @@ -1019,21 +1019,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11B; break; - case CHANNEL_T: - mode = AR5K_MODE_11A_TURBO; - freq = AR5K_INI_RFGAIN_5GHZ; - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_TG: - if (ah->ah_version == AR5K_AR5211) { - ATH5K_ERR(ah->ah_sc, - "TurboG mode not available on 5211"); - return -EINVAL; - } - mode = AR5K_MODE_11G_TURBO; - freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11G; - break; case CHANNEL_XR: if (ah->ah_version == AR5K_AR5211) { ATH5K_ERR(ah->ah_sc, -- cgit v1.2.3-59-g8ed1b From 8c2b418a07b4dc77d7efadb890ba9ad1a4161c3f Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:51:38 +0200 Subject: ath5k: Clean up turbo mode initvals/rfregs * Clean up what's left of turbo mode, since we handle all register modifications (rfbuffer comes next) on code there is no need to have duplicated arrays. * Rename change_channel to skip_pcu on initvals.c as we did on reset.c Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 17 +- drivers/net/wireless/ath/ath5k/base.c | 2 - drivers/net/wireless/ath/ath5k/caps.c | 6 - drivers/net/wireless/ath/ath5k/initvals.c | 386 +++++----- drivers/net/wireless/ath/ath5k/rfbuffer.h | 1142 ++++++++++------------------- 5 files changed, 577 insertions(+), 976 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 81ad236932c8..899bf4b99b76 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -158,15 +158,6 @@ #define AR5K_INI_RFGAIN_5GHZ 0 #define AR5K_INI_RFGAIN_2GHZ 1 -/* TODO: Clean this up */ -#define AR5K_INI_VAL_11A 0 -#define AR5K_INI_VAL_11A_TURBO 1 -#define AR5K_INI_VAL_11B 2 -#define AR5K_INI_VAL_11G 3 -#define AR5K_INI_VAL_11G_TURBO 4 -#define AR5K_INI_VAL_XR 0 -#define AR5K_INI_VAL_MAX 5 - /* * Some tuneable values (these should be changeable by the user) * TODO: Make use of them and add more options OR use debug/configfs @@ -429,12 +420,10 @@ struct ath5k_srev_name { enum ath5k_driver_mode { AR5K_MODE_11A = 0, - AR5K_MODE_11A_TURBO = 1, - AR5K_MODE_11B = 2, - AR5K_MODE_11G = 3, - AR5K_MODE_11G_TURBO = 4, + AR5K_MODE_11B = 1, + AR5K_MODE_11G = 2, AR5K_MODE_XR = 0, - AR5K_MODE_MAX = 5 + AR5K_MODE_MAX = 3 }; enum ath5k_ant_mode { diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 80831171f1b0..a8d380aae658 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -328,14 +328,12 @@ ath5k_copy_channels(struct ath5k_hw *ah, switch (mode) { case AR5K_MODE_11A: - case AR5K_MODE_11A_TURBO: /* 1..220, but 2GHz frequencies are filtered by check_channel */ size = 220 ; chfreq = CHANNEL_5GHZ; break; case AR5K_MODE_11B: case AR5K_MODE_11G: - case AR5K_MODE_11G_TURBO: size = 26; chfreq = CHANNEL_2GHZ; break; diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index beae519aa735..31cad80e9b01 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -49,7 +49,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) /* Set supported modes */ __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); - __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); } else { /* * XXX The tranceiver supports frequencies from 4920 to 6100GHz @@ -74,11 +73,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) /* Set supported modes */ __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); - __set_bit(AR5K_MODE_11A_TURBO, - ah->ah_capabilities.cap_mode); - if (ah->ah_version == AR5K_AR5212) - __set_bit(AR5K_MODE_11G_TURBO, - ah->ah_capabilities.cap_mode); } /* Enable 802.11b if a 2GHz capable radio (2111/5112) is diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c index 8fa439308828..905e4fdffc6d 100644 --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c @@ -44,7 +44,7 @@ struct ath5k_ini { struct ath5k_ini_mode { u16 mode_register; - u32 mode_value[5]; + u32 mode_value[3]; }; /* Initial register settings for AR5210 */ @@ -391,76 +391,74 @@ static const struct ath5k_ini ar5211_ini[] = { */ static const struct ath5k_ini_mode ar5211_ini_mode[] = { { AR5K_TXCFG, - /* a aTurbo b g (OFDM) */ - { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } }, + /* A/XR B G */ + { 0x00000015, 0x0000001d, 0x00000015 } }, { AR5K_QUEUE_DFS_LOCAL_IFS(0), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(1), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(2), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(3), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(4), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(5), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(6), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(7), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(8), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(9), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_DCU_GBL_IFS_SLOT, - { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } }, + { 0x00000168, 0x000001b8, 0x00000168 } }, { AR5K_DCU_GBL_IFS_SIFS, - { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } }, + { 0x00000230, 0x000000b0, 0x00000230 } }, { AR5K_DCU_GBL_IFS_EIFS, - { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } }, + { 0x00000d98, 0x00001f48, 0x00000d98 } }, { AR5K_DCU_GBL_IFS_MISC, - { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } }, + { 0x0000a0e0, 0x00005880, 0x0000a0e0 } }, { AR5K_TIME_OUT, - { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } }, + { 0x04000400, 0x20003000, 0x04000400 } }, { AR5K_USEC_5211, - { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } }, - { AR5K_PHY_TURBO, - { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } }, + { 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } }, { AR5K_PHY(8), - { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } }, - { AR5K_PHY(9), - { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } }, - { AR5K_PHY(10), - { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } }, - { AR5K_PHY(13), - { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY(14), - { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } }, - { AR5K_PHY(17), - { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } }, - { AR5K_PHY(18), - { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, - { AR5K_PHY(20), - { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, + { 0x02020200, 0x02010200, 0x02020200 } }, + { AR5K_PHY_RF_CTL2, + { 0x00000e0e, 0x00000707, 0x00000e0e } }, + { AR5K_PHY_RF_CTL3, + { 0x0a020001, 0x05010000, 0x0a020001 } }, + { AR5K_PHY_RF_CTL4, + { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, + { AR5K_PHY_PA_CTL, + { 0x00000007, 0x0000000b, 0x0000000b } }, + { AR5K_PHY_SETTLING, + { 0x1372169c, 0x137216a8, 0x1372169c } }, + { AR5K_PHY_GAIN, + { 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, + { AR5K_PHY_DESIRED_SIZE, + { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, + { 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, + { 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, { AR5K_PHY_AGCCTL, - { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, + { 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, { AR5K_PHY_NF, - { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, + { 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, { AR5K_PHY_RX_DELAY, - { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } }, + { 0x00002710, 0x0000157c, 0x00002710 } }, { AR5K_PHY(70), - { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } }, + { 0x00000190, 0x00000084, 0x00000190 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, + { 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, { AR5K_PHY_PCDAC_TXPOWER_BASE, - { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, + { 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, { AR5K_RF_BUFFER_CONTROL_4, - { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } }, + { 0x00000010, 0x00000010, 0x00000010 } }, }; /* Initial register settings for AR5212 */ @@ -677,89 +675,87 @@ static const struct ath5k_ini ar5212_ini_common_start[] = { /* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */ static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { { AR5K_QUEUE_DFS_LOCAL_IFS(0), - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + /* A/XR B G */ + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(1), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(2), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(3), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(4), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(5), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(6), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(7), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(8), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(9), - { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, + { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_DCU_GBL_IFS_SIFS, - { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } }, + { 0x00000230, 0x000000b0, 0x00000160 } }, { AR5K_DCU_GBL_IFS_SLOT, - { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } }, + { 0x00000168, 0x000001b8, 0x0000018c } }, { AR5K_DCU_GBL_IFS_EIFS, - { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } }, + { 0x00000e60, 0x00001f1c, 0x00003e38 } }, { AR5K_DCU_GBL_IFS_MISC, - { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } }, + { 0x0000a0e0, 0x00005880, 0x0000b0e0 } }, { AR5K_TIME_OUT, - { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } }, - { AR5K_PHY_TURBO, - { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } }, + { 0x03e803e8, 0x04200420, 0x08400840 } }, { AR5K_PHY(8), - { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } }, + { 0x02020200, 0x02010200, 0x02020200 } }, { AR5K_PHY_RF_CTL2, - { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } }, + { 0x00000e0e, 0x00000707, 0x00000e0e } }, { AR5K_PHY_SETTLING, - { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } }, + { 0x1372161c, 0x13721722, 0x137216a2 } }, { AR5K_PHY_AGCCTL, - { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } }, + { 0x00009d10, 0x00009d18, 0x00009d18 } }, { AR5K_PHY_NF, - { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, + { 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, { AR5K_PHY_WEAK_OFDM_HIGH_THR, - { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } }, + { 0x409a4190, 0x409a4190, 0x409a4190 } }, { AR5K_PHY(70), - { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } }, + { 0x000001b8, 0x00000084, 0x00000108 } }, { AR5K_PHY_OFDM_SELFCORR, - { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } }, + { 0x10058a05, 0x10058a05, 0x10058a05 } }, { 0xa230, - { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } }, + { 0x00000000, 0x00000000, 0x00000108 } }, }; /* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5111_ini_mode_end[] = { { AR5K_TXCFG, - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, + /* A/XR B G */ + { 0x00008015, 0x00008015, 0x00008015 } }, { AR5K_USEC_5211, - { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } }, + { 0x128d8fa7, 0x04e00f95, 0x12e00fab } }, { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } }, + { 0x0a020001, 0x05010100, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, + { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, - { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, + { 0x00000007, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, - { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } }, + { 0x0018da5a, 0x0018ca69, 0x0018ca69 } }, { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, + { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } }, + { 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } }, + { 0x3137665e, 0x3137665e, 0x3137665e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } }, + { 0x050cb081, 0x050cb081, 0x050cb080 } }, { AR5K_PHY_RX_DELAY, - { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } }, + { 0x00002710, 0x0000157c, 0x00002af8 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } }, + { 0xf7b81020, 0xf7b80d20, 0xf7b81020 } }, { AR5K_PHY_GAIN_2GHZ, - { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } }, + { 0x642c416a, 0x6440416a, 0x6440416a } }, { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, + { 0x1883800a, 0x1873800a, 0x1883800a } }, }; static const struct ath5k_ini rf5111_ini_common_end[] = { @@ -782,38 +778,38 @@ static const struct ath5k_ini rf5111_ini_common_end[] = { /* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5112_ini_mode_end[] = { { AR5K_TXCFG, - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, + /* A/XR B G */ + { 0x00008015, 0x00008015, 0x00008015 } }, { AR5K_USEC_5211, - { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, + { 0x128d93a7, 0x04e01395, 0x12e013ab } }, { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, + { 0x0a020001, 0x05020100, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, + { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, - { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, + { 0x00000007, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, - { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } }, + { 0x0018da6d, 0x0018ca75, 0x0018ca75 } }, { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, + { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } }, + { 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } }, + { 0x3137665e, 0x3137665e, 0x3137665e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, + { 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, + { 0x000007d0, 0x0000044c, 0x00000898 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } }, + { 0xf7b81020, 0xf7b80d10, 0xf7b81010 } }, { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } }, + { 0x00000000, 0x00000008, 0x00000008 } }, { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, + { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, - { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } }, + { 0x642c0140, 0x6442c160, 0x6442c160 } }, { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, + { 0x1883800a, 0x1873800a, 0x1883800a } }, }; static const struct ath5k_ini rf5112_ini_common_end[] = { @@ -833,66 +829,66 @@ static const struct ath5k_ini rf5112_ini_common_end[] = { /* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { { AR5K_TXCFG, - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, + /* A/XR B G */ + { 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, - { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, + { 0x128d93a7, 0x04e01395, 0x12e013ab } }, { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, + { 0x0a020001, 0x05020100, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, + { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, - { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, + { 0x00000007, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, - { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } }, + { 0x0018fa61, 0x001a1a63, 0x001a1a63 } }, { AR5K_PHY_DESIRED_SIZE, - { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, + { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } }, { AR5K_PHY_SIG, - { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, + { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, + { 0x3139605e, 0x3139605e, 0x3139605e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, + { 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, + { 0x000007d0, 0x0000044c, 0x00000898 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, + { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, + { 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, + { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, - { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } }, + { 0x002ec1e0, 0x002ac120, 0x002ac120 } }, { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, + { 0x1883800a, 0x1863800a, 0x1883800a } }, { 0xa300, - { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } }, + { 0x18010000, 0x18010000, 0x18010000 } }, { 0xa304, - { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } }, + { 0x30032602, 0x30032602, 0x30032602 } }, { 0xa308, - { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } }, + { 0x48073e06, 0x48073e06, 0x48073e06 } }, { 0xa30c, - { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, + { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, { 0xa310, - { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } }, + { 0x641a600f, 0x641a600f, 0x641a600f } }, { 0xa314, - { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, + { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, { 0xa318, - { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, + { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, { 0xa31c, - { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } }, + { 0x90cf865b, 0x8ecf865b, 0x8ecf865b } }, { 0xa320, - { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } }, + { 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } }, { 0xa324, - { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } }, + { 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } }, { 0xa328, - { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } }, + { 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } }, { 0xa32c, - { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } }, + { 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } }, { 0xa330, - { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } }, + { 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } }, { 0xa334, - { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, + { 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, }; static const struct ath5k_ini rf5413_ini_common_end[] = { @@ -972,38 +968,38 @@ static const struct ath5k_ini rf5413_ini_common_end[] = { /* XXX: a mode ? */ static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { { AR5K_TXCFG, - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, + /* A/XR B G */ + { 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, - { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, + { 0x128d93a7, 0x04e01395, 0x12e013ab } }, { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } }, + { 0x0a020001, 0x05020000, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, - { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } }, + { 0x00000e00, 0x00000e00, 0x00000e00 } }, { AR5K_PHY_PA_CTL, - { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } }, + { 0x00000002, 0x0000000a, 0x0000000a } }, { AR5K_PHY_GAIN, - { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } }, + { 0x0018da6d, 0x001a6a64, 0x001a6a64 } }, { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } }, + { 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } }, { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } }, + { 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } }, + { 0x3137665e, 0x3137665e, 0x3139605e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, + { 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, + { 0x000007d0, 0x0000044c, 0x00000898 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, + { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, + { 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, + { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, - { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } }, + { 0x002c0140, 0x0042c140, 0x0042c140 } }, { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, + { 0x1883800a, 0x1863800a, 0x1883800a } }, }; static const struct ath5k_ini rf2413_ini_common_end[] = { @@ -1094,52 +1090,50 @@ static const struct ath5k_ini rf2413_ini_common_end[] = { /* XXX: a mode ? */ static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { { AR5K_TXCFG, - /* a/XR aTurbo b g (DYN) gTurbo */ - { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, + /* A/XR B G */ + { 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, - { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, - { AR5K_PHY_TURBO, - { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } }, + { 0x128d93a7, 0x04e01395, 0x12e013ab } }, { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, + { 0x0a020001, 0x05020100, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, + { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, - { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } }, + { 0x00000003, 0x0000000b, 0x0000000b } }, { AR5K_PHY_SETTLING, - { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } }, + { 0x1372161c, 0x13721722, 0x13721422 } }, { AR5K_PHY_GAIN, - { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } }, + { 0x0018fa61, 0x00199a65, 0x00199a65 } }, { AR5K_PHY_DESIRED_SIZE, - { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, + { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } }, { AR5K_PHY_SIG, - { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, + { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, { AR5K_PHY_AGCCOARSE, - { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, + { 0x3139605e, 0x3139605e, 0x3139605e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, + { 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, + { 0x000007d0, 0x0000044c, 0x00000898 } }, { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, + { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, + { 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, + { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, - { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } }, + { 0x00000140, 0x0052c140, 0x0052c140 } }, { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, + { 0x1883800a, 0x1863800a, 0x1883800a } }, { 0xa324, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa328, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa32c, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa330, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa334, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, }; static const struct ath5k_ini rf2425_ini_common_end[] = { @@ -1368,15 +1362,15 @@ static const struct ath5k_ini rf5112_ini_bbgain[] = { * Write initial register dump */ static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size, - const struct ath5k_ini *ini_regs, bool change_channel) + const struct ath5k_ini *ini_regs, bool skip_pcu) { unsigned int i; /* Write initial registers */ for (i = 0; i < size; i++) { - /* On channel change there is - * no need to mess with PCU */ - if (change_channel && + /* Skip PCU registers if + * requested */ + if (skip_pcu && ini_regs[i].ini_register >= AR5K_PCU_MIN && ini_regs[i].ini_register <= AR5K_PCU_MAX) continue; @@ -1409,7 +1403,7 @@ static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah, } -int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) +int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu) { /* * Write initial register settings @@ -1427,7 +1421,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) * Write initial settings common for all modes */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start), - ar5212_ini_common_start, change_channel); + ar5212_ini_common_start, skip_pcu); /* Second set of mode-specific settings */ switch (ah->ah_radio) { @@ -1439,12 +1433,12 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_common_end), - rf5111_ini_common_end, change_channel); + rf5111_ini_common_end, skip_pcu); /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), - rf5111_ini_bbgain, change_channel); + rf5111_ini_bbgain, skip_pcu); break; case AR5K_RF5112: @@ -1455,11 +1449,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_common_end), - rf5112_ini_common_end, change_channel); + rf5112_ini_common_end, skip_pcu); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, change_channel); + rf5112_ini_bbgain, skip_pcu); break; case AR5K_RF5413: @@ -1470,11 +1464,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5413_ini_common_end), - rf5413_ini_common_end, change_channel); + rf5413_ini_common_end, skip_pcu); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, change_channel); + rf5112_ini_bbgain, skip_pcu); break; case AR5K_RF2316: @@ -1486,7 +1480,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf2413_ini_common_end), - rf2413_ini_common_end, change_channel); + rf2413_ini_common_end, skip_pcu); /* Override settings from rf2413_ini_common_end */ if (ah->ah_radio == AR5K_RF2316) { @@ -1498,7 +1492,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, change_channel); + rf5112_ini_bbgain, skip_pcu); break; case AR5K_RF2317: case AR5K_RF2425: @@ -1509,11 +1503,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf2425_ini_common_end), - rf2425_ini_common_end, change_channel); + rf2425_ini_common_end, skip_pcu); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, change_channel); + rf5112_ini_bbgain, skip_pcu); break; default: return -EINVAL; @@ -1538,17 +1532,17 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) * Write initial settings common for all modes */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini), - ar5211_ini, change_channel); + ar5211_ini, skip_pcu); /* AR5211 only comes with 5111 */ /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), - rf5111_ini_bbgain, change_channel); + rf5111_ini_bbgain, skip_pcu); /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */ } else if (ah->ah_version == AR5K_AR5210) { ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini), - ar5210_ini, change_channel); + ar5210_ini, skip_pcu); } return 0; diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index 3ac4cff4239d..70356bacd5db 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h @@ -51,7 +51,7 @@ struct ath5k_ini_rfbuffer { u8 rfb_bank; /* RF Bank number */ u16 rfb_ctrl_register; /* RF Buffer control register */ - u32 rfb_mode_data[5]; /* RF Buffer data for each mode */ + u32 rfb_mode_data[3]; /* RF Buffer data for each mode */ }; /* @@ -177,97 +177,52 @@ static const struct ath5k_rf_reg rf_regs_5111[] = { /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5111[] = { - { 0, 0x989c, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, - { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } }, - { 0, 0x989c, - { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } }, - { 0, 0x98d4, - { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } }, - { 1, 0x98d4, - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d4, - { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } }, - { 3, 0x98d8, - { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, - { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } }, - { 6, 0x989c, - { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } }, - { 6, 0x989c, - { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } }, - { 6, 0x989c, - { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } }, - { 6, 0x989c, - { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } }, - { 6, 0x98d4, - { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } }, - { 7, 0x989c, - { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } }, - { 7, 0x989c, - { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } }, - { 7, 0x989c, - { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } }, - { 7, 0x989c, - { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } }, - { 7, 0x989c, - { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } }, - { 7, 0x989c, - { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } }, - { 7, 0x989c, - { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 0, 0x989c, { 0x00000000, 0x000000c0, 0x00000080 } }, + { 0, 0x989c, { 0x000400f9, 0x000400ff, 0x000400fd } }, + { 0, 0x98d4, { 0x00000000, 0x00000004, 0x00000004 } }, + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d4, { 0x00000010, 0x00000010, 0x00000010 } }, + { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, + { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x0a000000, 0x00000000 } }, + { 6, 0x989c, { 0x003800c0, 0x023800c0, 0x003800c0 } }, + { 6, 0x989c, { 0x00020006, 0x00000006, 0x00020006 } }, + { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089 } }, + { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0 } }, + { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007 } }, + { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a } }, + { 7, 0x989c, { 0x00000040, 0x00000040, 0x00000040 } }, + { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010 } }, + { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008 } }, + { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f } }, + { 7, 0x989c, { 0x000000f1, 0x00000061, 0x000000f1 } }, + { 7, 0x989c, { 0x0000904f, 0x0000904c, 0x0000904f } }, + { 7, 0x989c, { 0x0000125a, 0x0000129a, 0x0000125a } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000f, 0x0000000e } }, }; @@ -335,115 +290,61 @@ static const struct ath5k_rf_reg rf_regs_5112[] = { /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5112[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, - { 3, 0x98dc, - { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } }, - { 6, 0x989c, - { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } }, - { 6, 0x989c, - { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } }, - { 6, 0x989c, - { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } }, - { 6, 0x989c, - { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } }, - { 6, 0x989c, - { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, - { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, - { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } }, - { 6, 0x989c, - { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } }, - { 6, 0x989c, - { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, - { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, - { 6, 0x989c, - { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } }, - { 6, 0x989c, - { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } }, - { 6, 0x989c, - { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, - { 6, 0x989c, - { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } }, - { 6, 0x989c, - { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, - { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, - { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } }, - { 6, 0x989c, - { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } }, - { 6, 0x989c, - { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } }, - { 6, 0x989c, - { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } }, - { 6, 0x989c, - { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } }, - { 6, 0x989c, - { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } }, - { 6, 0x989c, - { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } }, - { 6, 0x989c, - { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } }, - { 6, 0x989c, - { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } }, - { 6, 0x989c, - { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } }, - { 6, 0x989c, - { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } }, - { 6, 0x989c, - { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } }, - { 6, 0x989c, - { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } }, - { 6, 0x98d0, - { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } }, - { 7, 0x989c, - { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } }, - { 7, 0x989c, - { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } }, - { 7, 0x989c, - { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } }, - { 7, 0x989c, - { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } }, - { 7, 0x989c, - { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } }, - { 7, 0x989c, - { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, - { 7, 0x989c, - { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } }, - { 7, 0x989c, - { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } }, - { 7, 0x989c, - { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } }, - { 7, 0x989c, - { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } }, - { 7, 0x989c, - { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } }, - { 7, 0x989c, - { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } }, - { 7, 0x98c4, - { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } }, + { 3, 0x98dc, { 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0 } }, + { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000 } }, + { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000 } }, + { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000 } }, + { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000 } }, + { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, + { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, + { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000 } }, + { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000 } }, + { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, + { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } }, + { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000 } }, + { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000 } }, + { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } }, + { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000 } }, + { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, + { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, + { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000 } }, + { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000 } }, + { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } }, + { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000 } }, + { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000 } }, + { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000 } }, + { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000 } }, + { 6, 0x989c, { 0x000000b0, 0x000000a8, 0x000000a8 } }, + { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e } }, + { 6, 0x989c, { 0x006c4a41, 0x006c4af1, 0x006c4a61 } }, + { 6, 0x989c, { 0x0050892a, 0x0050892b, 0x0050892b } }, + { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400 } }, + { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200 } }, + { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c } }, + { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } }, + { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } }, + { 7, 0x989c, { 0x0000000a, 0x00000012, 0x00000012 } }, + { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } }, + { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1 } }, + { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, + { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } }, + { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022 } }, + { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092 } }, + { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } }, + { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } }, + { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } }, + { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } }, }; /* RFX112A (Derby 2) */ @@ -515,119 +416,63 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = { /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5112a[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } }, - { 6, 0x989c, - { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, - { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } }, - { 6, 0x989c, - { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } }, - { 6, 0x989c, - { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } }, - { 6, 0x989c, - { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } }, - { 6, 0x989c, - { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } }, - { 6, 0x989c, - { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } }, - { 6, 0x989c, - { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } }, - { 6, 0x989c, - { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, - { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } }, - { 6, 0x989c, - { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, - { 6, 0x989c, - { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } }, - { 6, 0x989c, - { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } }, - { 6, 0x989c, - { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } }, - { 6, 0x989c, - { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, - { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, - { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } }, - { 6, 0x989c, - { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } }, - { 6, 0x989c, - { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, - { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } }, - { 6, 0x989c, - { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } }, - { 6, 0x989c, - { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } }, - { 6, 0x989c, - { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } }, - { 6, 0x989c, - { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } }, - { 6, 0x989c, - { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } }, - { 6, 0x989c, - { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } }, - { 6, 0x989c, - { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } }, - { 6, 0x989c, - { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } }, - { 6, 0x98d8, - { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } }, - { 7, 0x989c, - { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } }, - { 7, 0x989c, - { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } }, - { 7, 0x989c, - { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } }, - { 7, 0x989c, - { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } }, - { 7, 0x989c, - { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } }, - { 7, 0x989c, - { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, - { 7, 0x989c, - { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } }, - { 7, 0x989c, - { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } }, - { 7, 0x989c, - { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } }, - { 7, 0x989c, - { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } }, - { 7, 0x989c, - { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } }, - { 7, 0x989c, - { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } }, - { 7, 0x98c4, - { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000 } }, + { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, + { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000 } }, + { 6, 0x989c, { 0x00600000, 0x006e0000, 0x006e0000 } }, + { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000 } }, + { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000 } }, + { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000 } }, + { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000 } }, + { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000 } }, + { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, + { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000 } }, + { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } }, + { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000 } }, + { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000 } }, + { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000 } }, + { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, + { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, + { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000 } }, + { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000 } }, + { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, + { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000 } }, + { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000 } }, + { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080 } }, + { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019 } }, + { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2 } }, + { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084 } }, + { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4 } }, + { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220 } }, + { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800 } }, + { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230 } }, + { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } }, + { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } }, + { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012 } }, + { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } }, + { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9 } }, + { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, + { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } }, + { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2 } }, + { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052 } }, + { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } }, + { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } }, + { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } }, + { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } }, }; @@ -649,73 +494,40 @@ static const struct ath5k_rf_reg rf_regs_2413[] = { * XXX: a/aTurbo ??? */ static const struct ath5k_ini_rfbuffer rfb_2413[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } }, - { 6, 0x989c, - { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } }, - { 6, 0x989c, - { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } }, - { 6, 0x989c, - { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } }, - { 6, 0x989c, - { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } }, - { 6, 0x989c, - { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } }, - { 6, 0x989c, - { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } }, - { 6, 0x989c, - { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } }, - { 6, 0x989c, - { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } }, - { 6, 0x989c, - { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } }, - { 6, 0x989c, - { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } }, - { 6, 0x989c, - { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } }, - { 6, 0x989c, - { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } }, - { 6, 0x98d8, - { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000 } }, + { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000 } }, + { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000 } }, + { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000 } }, + { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000 } }, + { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000 } }, + { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000 } }, + { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000 } }, + { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018 } }, + { 6, 0x989c, { 0x00280000, 0x00280060, 0x00280060 } }, + { 6, 0x989c, { 0x005000c0, 0x005000c3, 0x005000c3 } }, + { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f } }, + { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000 } }, + { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; @@ -735,77 +547,42 @@ static const struct ath5k_rf_reg rf_regs_2316[] = { /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_2316[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } }, - { 6, 0x989c, - { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, - { 6, 0x989c, - { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } }, - { 6, 0x989c, - { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } }, - { 6, 0x989c, - { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } }, - { 6, 0x989c, - { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } }, - { 6, 0x989c, - { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } }, - { 6, 0x989c, - { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } }, - { 6, 0x989c, - { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } }, - { 6, 0x989c, - { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } }, - { 6, 0x989c, - { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } }, - { 6, 0x989c, - { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } }, - { 6, 0x989c, - { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } }, - { 6, 0x989c, - { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } }, - { 6, 0x989c, - { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, - { 6, 0x989c, - { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, - { 6, 0x989c, - { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } }, - { 6, 0x989c, - { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } }, - { 6, 0x98c0, - { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000 } }, + { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } }, + { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000 } }, + { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000 } }, + { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000 } }, + { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000 } }, + { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000 } }, + { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } }, + { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000 } }, + { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000 } }, + { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060 } }, + { 6, 0x989c, { 0x00a00000, 0x00a00080, 0x00a00080 } }, + { 6, 0x989c, { 0x00400000, 0x0040000d, 0x0040000d } }, + { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400 } }, + { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, + { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001 } }, + { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00 } }, + { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8 } }, + { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; @@ -835,93 +612,50 @@ static const struct ath5k_rf_reg rf_regs_5413[] = { /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5413[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } }, - { 3, 0x98dc, - { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } }, - { 6, 0x989c, - { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } }, - { 6, 0x989c, - { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } }, - { 6, 0x989c, - { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } }, - { 6, 0x989c, - { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, - { 6, 0x989c, - { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } }, - { 6, 0x989c, - { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, - { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } }, - { 6, 0x989c, - { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } }, - { 6, 0x989c, - { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } }, - { 6, 0x989c, - { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } }, - { 6, 0x989c, - { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } }, - { 6, 0x989c, - { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } }, - { 6, 0x989c, - { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } }, - { 6, 0x989c, - { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } }, - { 6, 0x989c, - { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } }, - { 6, 0x989c, - { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } }, - { 6, 0x989c, - { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } }, - { 6, 0x989c, - { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } }, - { 6, 0x989c, - { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } }, - { 6, 0x989c, - { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } }, - { 6, 0x989c, - { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } }, - { 6, 0x989c, - { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } }, - { 6, 0x98c8, - { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008 } }, + { 3, 0x98dc, { 0x00a000c0, 0x00e000c0, 0x00e000c0 } }, + { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000 } }, + { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000 } }, + { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000 } }, + { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } }, + { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } }, + { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, + { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000 } }, + { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000 } }, + { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000 } }, + { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000 } }, + { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000 } }, + { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000 } }, + { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } }, + { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000 } }, + { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } }, + { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080 } }, + { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034 } }, + { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0 } }, + { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f } }, + { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040 } }, + { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0 } }, + { 6, 0x989c, { 0x00002c00, 0x00003600, 0x00003600 } }, + { 6, 0x98c8, { 0x00000403, 0x00040403, 0x00040403 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; @@ -944,79 +678,43 @@ static const struct ath5k_rf_reg rf_regs_2425[] = { * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2425[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, - { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, - { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, - { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, - { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } }, - { 6, 0x989c, - { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } }, - { 6, 0x989c, - { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, - { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } }, - { 6, 0x989c, - { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, - { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, - { 6, 0x989c, - { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, - { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } }, - { 6, 0x98c4, - { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, + { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, + { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, + { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, + { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } }, + { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } }, + { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, + { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } }, + { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, + { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, + { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, + { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } }, + { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; /* @@ -1024,79 +722,43 @@ static const struct ath5k_ini_rfbuffer rfb_2425[] = { * bank modification and get rid of this */ static const struct ath5k_ini_rfbuffer rfb_2317[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, - { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, - { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, - { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, - { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } }, - { 6, 0x989c, - { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } }, - { 6, 0x989c, - { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, - { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } }, - { 6, 0x989c, - { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, - { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, - { 6, 0x989c, - { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, - { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } }, - { 6, 0x98c4, - { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, + { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, + { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, + { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, + { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } }, + { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100 } }, + { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, + { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } }, + { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, + { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, + { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, + { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688 } }, + { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; /* @@ -1105,77 +767,41 @@ static const struct ath5k_ini_rfbuffer rfb_2317[] = { * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2417[] = { - { 1, 0x98d4, - /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ - { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, - { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, - { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, - { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, - { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, - { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, - { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, - { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } }, - { 6, 0x989c, - { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } }, - { 6, 0x989c, - { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, - { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } }, - { 6, 0x989c, - { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, - { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, - { 6, 0x989c, - { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, - { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, - { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } }, - { 6, 0x98c4, - { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, - { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, - { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, - { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, + /* BANK / C.R. A/XR B G */ + { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, + { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, + { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, + { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, + { 6, 0x989c, { 0x00e70000, 0x80e70000, 0x80e70000 } }, + { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } }, + { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, + { 6, 0x989c, { 0x0007001a, 0x0207001a, 0x0207001a } }, + { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, + { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, + { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, + { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } }, + { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, + { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, }; -- cgit v1.2.3-59-g8ed1b From 4352fab5c2a1a602447d711c84d149bf2f0bc7ba Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Tue, 23 Nov 2010 21:53:28 +0200 Subject: ath5k: Set turbo bit on rf bank 2 * A diff between rfbuffer settings of turbo and non-turbo modes indicates there is a bit on bank 2 related to turbo operation (it's set on turbo modes). This bit is present on all radios except RF5413 that seems to have a completely different bank 2. Also since 2317 has the same rf-registers locations with 2425 and since the bit exists on 2317 I assume it also exists on 2425/2417). So in case we use turbo mode (40MHz) enable it on bank modification. Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 5 +++++ drivers/net/wireless/ath/ath5k/rfbuffer.h | 27 ++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 61d3800c8118..df5cd0fd69d6 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -824,6 +824,11 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, g_step = &go->go_step[ah->ah_gain.g_step_idx]; + /* Set turbo mode (N/A on RF5413) */ + if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) && + (ah->ah_radio != AR5K_RF5413)) + ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false); + /* Bank Modifications (chip-specific) */ if (ah->ah_radio == AR5K_RF5111) { diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index 70356bacd5db..16b67e84906d 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h @@ -79,8 +79,10 @@ struct ath5k_rf_reg { * life easier by using an index for each register * instead of a full rfb_field */ enum ath5k_rf_regs_idx { + /* BANK 2 */ + AR5K_RF_TURBO = 0, /* BANK 6 */ - AR5K_RF_OB_2GHZ = 0, + AR5K_RF_OB_2GHZ, AR5K_RF_OB_5GHZ, AR5K_RF_DB_2GHZ, AR5K_RF_DB_5GHZ, @@ -134,6 +136,9 @@ enum ath5k_rf_regs_idx { * RF5111 (Sombrero) * \*******************/ +/* BANK 2 len pos col */ +#define AR5K_RF5111_RF_TURBO { 1, 3, 0 } + /* BANK 6 len pos col */ #define AR5K_RF5111_OB_2GHZ { 3, 119, 0 } #define AR5K_RF5111_DB_2GHZ { 3, 122, 0 } @@ -158,6 +163,7 @@ enum ath5k_rf_regs_idx { #define AR5K_RF5111_MAX_TIME { 2, 49, 0 } static const struct ath5k_rf_reg rf_regs_5111[] = { + {2, AR5K_RF_TURBO, AR5K_RF5111_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, @@ -231,6 +237,9 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = { * RF5112/RF2112 (Derby) * \***********************/ +/* BANK 2 (Common) len pos col */ +#define AR5K_RF5112X_RF_TURBO { 1, 1, 2 } + /* BANK 7 (Common) len pos col */ #define AR5K_RF5112X_GAIN_I { 6, 14, 0 } #define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 } @@ -262,6 +271,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = { #define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 } static const struct ath5k_rf_reg rf_regs_5112[] = { + {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ}, @@ -378,6 +388,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112[] = { #define AR5K_RF5112A_XB5_LVL { 2, 3, 3 } static const struct ath5k_rf_reg rf_regs_5112a[] = { + {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ}, @@ -481,11 +492,15 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = { * RF2413 (Griffin) * \******************/ +/* BANK 2 len pos col */ +#define AR5K_RF2413_RF_TURBO { 1, 1, 2 } + /* BANK 6 len pos col */ #define AR5K_RF2413_OB_2GHZ { 3, 168, 0 } #define AR5K_RF2413_DB_2GHZ { 3, 165, 0 } static const struct ath5k_rf_reg rf_regs_2413[] = { + {2, AR5K_RF_TURBO, AR5K_RF2413_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ}, }; @@ -536,11 +551,15 @@ static const struct ath5k_ini_rfbuffer rfb_2413[] = { * RF2315/RF2316 (Cobra SoC) * \***************************/ +/* BANK 2 len pos col */ +#define AR5K_RF2316_RF_TURBO { 1, 1, 2 } + /* BANK 6 len pos col */ #define AR5K_RF2316_OB_2GHZ { 3, 178, 0 } #define AR5K_RF2316_DB_2GHZ { 3, 175, 0 } static const struct ath5k_rf_reg rf_regs_2316[] = { + {2, AR5K_RF_TURBO, AR5K_RF2316_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ}, }; @@ -665,17 +684,20 @@ static const struct ath5k_ini_rfbuffer rfb_5413[] = { * AR2317 (Spider SoC) * \***************************/ +/* BANK 2 len pos col */ +#define AR5K_RF2425_RF_TURBO { 1, 1, 2 } + /* BANK 6 len pos col */ #define AR5K_RF2425_OB_2GHZ { 3, 193, 0 } #define AR5K_RF2425_DB_2GHZ { 3, 190, 0 } static const struct ath5k_rf_reg rf_regs_2425[] = { + {2, AR5K_RF_TURBO, AR5K_RF2425_RF_TURBO}, {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ}, }; /* Default mode specific settings - * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2425[] = { /* BANK / C.R. A/XR B G */ @@ -764,7 +786,6 @@ static const struct ath5k_ini_rfbuffer rfb_2317[] = { /* * TODO: Handle the few differences with swan during * bank modification and get rid of this - * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2417[] = { /* BANK / C.R. A/XR B G */ -- cgit v1.2.3-59-g8ed1b From 20ed3166c84d145589a89d8cde12aa32cf2d17f4 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Tue, 30 Nov 2010 16:49:23 +0100 Subject: mac80211/rt2x00: add ieee80211_tx_status_ni() All rt2x00 drivers except rt2800pci call ieee80211_tx_status() from a workqueue, which causes "NOHZ: local_softirq_pending 08" messages. To fix it, add ieee80211_tx_status_ni() similar to ieee80211_rx_ni() which can be called from process context, and call it from rt2x00lib_txdone(). For the rt2800pci special case a driver flag is introduced. Signed-off-by: Johannes Stezenbach Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00dev.c | 9 ++++++--- include/net/mac80211.h | 28 ++++++++++++++++++++++++---- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 433c7f3ef837..b989b0d3ed49 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -911,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0a55eeff871e..e72117f3fdf5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -664,6 +664,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_COPY_IV, DRIVER_REQUIRE_L2PAD, DRIVER_REQUIRE_TXSTATUS_FIFO, + DRIVER_REQUIRE_TASKLET_CONTEXT, /* * Driver features diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c879f9a7037c..bd3afc92f434 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -379,9 +379,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, * through a mac80211 library call (RTS/CTS) then we should not * send the status report back. */ - if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - ieee80211_tx_status(rt2x00dev->hw, entry->skb); - else + if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { + if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags)) + ieee80211_tx_status(rt2x00dev->hw, entry->skb); + else + ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); + } else dev_kfree_skb_any(entry->skb); /* diff --git a/include/net/mac80211.h b/include/net/mac80211.h index eaa4affd40cd..e411cf87fb41 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2055,8 +2055,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, * * This function may not be called in IRQ context. Calls to this function * for a single hardware must be synchronized against each other. Calls - * to this function and ieee80211_tx_status_irqsafe() may not be mixed - * for a single hardware. + * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() + * may not be mixed for a single hardware. * * @hw: the hardware the frame was transmitted by * @skb: the frame that was transmitted, owned by mac80211 after this call @@ -2064,14 +2064,34 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); +/** + * ieee80211_tx_status_ni - transmit status callback (in process context) + * + * Like ieee80211_tx_status() but can be called in process context. + * + * Calls to this function, ieee80211_tx_status() and + * ieee80211_tx_status_irqsafe() may not be mixed + * for a single hardware. + * + * @hw: the hardware the frame was transmitted by + * @skb: the frame that was transmitted, owned by mac80211 after this call + */ +static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + local_bh_disable(); + ieee80211_tx_status(hw, skb); + local_bh_enable(); +} + /** * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback * * Like ieee80211_tx_status() but can be called in IRQ context * (internally defers to a tasklet.) * - * Calls to this function and ieee80211_tx_status() may not be mixed for a - * single hardware. + * Calls to this function, ieee80211_tx_status() and + * ieee80211_tx_status_ni() may not be mixed for a single hardware. * * @hw: the hardware the frame was transmitted by * @skb: the frame that was transmitted, owned by mac80211 after this call -- cgit v1.2.3-59-g8ed1b From 08ca944eb240b2299e743c76b43fbc7c2dd251de Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Tue, 30 Nov 2010 12:19:34 +0100 Subject: mac80211: Minor optimization in ieee80211_rx_h_data Remove a superfluous ieee80211_is_data check as that was checked a few lines before already and we wont't get here for non-data frames at all. Second, the frame was already converted to 802.3 header format and reading the fc and addr1 fields was only possible because the 802.3 header is short enough and didn't overwrite the relevant parts of the 802.11 header. Make the code more obvious by checking the ethernet header's h_dest field. Furthermore reorder the conditions to reduce the number of checks when dynamic powersave is not needed (AP mode for example). Signed-off-by: Helmut Schaa Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fdeabb19943c..d83334bbb245 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1877,9 +1877,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) dev->stats.rx_packets++; dev->stats.rx_bytes += rx->skb->len; - if (ieee80211_is_data(hdr->frame_control) && - !is_multicast_ether_addr(hdr->addr1) && - local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) { + if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 && + !is_multicast_ether_addr(((struct ethhdr *)rx->skb->data)->h_dest)) { mod_timer(&local->dynamic_ps_timer, jiffies + msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); } -- cgit v1.2.3-59-g8ed1b From 61790c5f3c5f158821821a00797d94504531839f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 30 Nov 2010 15:33:40 +0100 Subject: iwlagn: fix microcode error on 4965 Commit dbbf1755b09eef8ff6dd21c8dafe1606f051ce12 "iwlwifi: use antenna information in EEPROM" caused 4965 device breakage with "Microcode SW error detected. Restarting 0x82000000." message. This patch reverts 4965 part of that commit. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9f1d8d8c8fcc..6788ceb37686 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2624,6 +2624,8 @@ struct iwl_cfg iwl4965_agn_cfg = { .fw_name_pre = IWL4965_FW_PRE, .ucode_api_max = IWL4965_UCODE_API_MAX, .ucode_api_min = IWL4965_UCODE_API_MIN, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, .ops = &iwl4965_ops, -- cgit v1.2.3-59-g8ed1b From 98158f5a853cafd33b254ae0eacc0dd69f90b93b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 11:41:59 -0800 Subject: inetpeer: Abstract out the tree root accesses. Instead of directly accessing "peer", change to code to operate using a "struct inet_peer_base *" pointer. This will facilitate the addition of a seperate tree for ipv6 peer entries. Signed-off-by: David S. Miller --- net/ipv4/inetpeer.c | 119 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 9e94d7cf4f8a..f94400848921 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -79,13 +79,13 @@ static const struct inet_peer peer_fake_node = { .avl_height = 0 }; -static struct { +static struct inet_peer_base { struct inet_peer __rcu *root; spinlock_t lock; int total; -} peers = { +} v4_peers = { .root = peer_avl_empty_rcu, - .lock = __SPIN_LOCK_UNLOCKED(peers.lock), + .lock = __SPIN_LOCK_UNLOCKED(v4_peers.lock), .total = 0, }; #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ @@ -155,15 +155,15 @@ static void unlink_from_unused(struct inet_peer *p) /* * Called with local BH disabled and the pool lock held. */ -#define lookup(_daddr, _stack) \ +#define lookup(_daddr, _stack, _base) \ ({ \ struct inet_peer *u; \ struct inet_peer __rcu **v; \ \ stackptr = _stack; \ - *stackptr++ = &peers.root; \ - for (u = rcu_dereference_protected(peers.root, \ - lockdep_is_held(&peers.lock)); \ + *stackptr++ = &_base->root; \ + for (u = rcu_dereference_protected(_base->root, \ + lockdep_is_held(&_base->lock)); \ u != peer_avl_empty; ) { \ if (_daddr == u->v4daddr) \ break; \ @@ -173,7 +173,7 @@ static void unlink_from_unused(struct inet_peer *p) v = &u->avl_right; \ *stackptr++ = v; \ u = rcu_dereference_protected(*v, \ - lockdep_is_held(&peers.lock)); \ + lockdep_is_held(&_base->lock)); \ } \ u; \ }) @@ -185,9 +185,9 @@ static void unlink_from_unused(struct inet_peer *p) * But every pointer we follow is guaranteed to be valid thanks to RCU. * We exit from this function if number of links exceeds PEER_MAXDEPTH */ -static struct inet_peer *lookup_rcu_bh(__be32 daddr) +static struct inet_peer *lookup_rcu_bh(__be32 daddr, struct inet_peer_base *base) { - struct inet_peer *u = rcu_dereference_bh(peers.root); + struct inet_peer *u = rcu_dereference_bh(base->root); int count = 0; while (u != peer_avl_empty) { @@ -212,19 +212,19 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr) } /* Called with local BH disabled and the pool lock held. */ -#define lookup_rightempty(start) \ +#define lookup_rightempty(start, base) \ ({ \ struct inet_peer *u; \ struct inet_peer __rcu **v; \ *stackptr++ = &start->avl_left; \ v = &start->avl_left; \ for (u = rcu_dereference_protected(*v, \ - lockdep_is_held(&peers.lock)); \ + lockdep_is_held(&base->lock)); \ u->avl_right != peer_avl_empty_rcu; ) { \ v = &u->avl_right; \ *stackptr++ = v; \ u = rcu_dereference_protected(*v, \ - lockdep_is_held(&peers.lock)); \ + lockdep_is_held(&base->lock)); \ } \ u; \ }) @@ -234,7 +234,8 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr) * Look into mm/map_avl.c for more detail description of the ideas. */ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], - struct inet_peer __rcu ***stackend) + struct inet_peer __rcu ***stackend, + struct inet_peer_base *base) { struct inet_peer __rcu **nodep; struct inet_peer *node, *l, *r; @@ -243,20 +244,20 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], while (stackend > stack) { nodep = *--stackend; node = rcu_dereference_protected(*nodep, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); l = rcu_dereference_protected(node->avl_left, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); r = rcu_dereference_protected(node->avl_right, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); lh = node_height(l); rh = node_height(r); if (lh > rh + 1) { /* l: RH+2 */ struct inet_peer *ll, *lr, *lrl, *lrr; int lrh; ll = rcu_dereference_protected(l->avl_left, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); lr = rcu_dereference_protected(l->avl_right, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); lrh = node_height(lr); if (lrh <= node_height(ll)) { /* ll: RH+1 */ RCU_INIT_POINTER(node->avl_left, lr); /* lr: RH or RH+1 */ @@ -268,9 +269,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], RCU_INIT_POINTER(*nodep, l); } else { /* ll: RH, lr: RH+1 */ lrl = rcu_dereference_protected(lr->avl_left, - lockdep_is_held(&peers.lock)); /* lrl: RH or RH-1 */ + lockdep_is_held(&base->lock)); /* lrl: RH or RH-1 */ lrr = rcu_dereference_protected(lr->avl_right, - lockdep_is_held(&peers.lock)); /* lrr: RH or RH-1 */ + lockdep_is_held(&base->lock)); /* lrr: RH or RH-1 */ RCU_INIT_POINTER(node->avl_left, lrr); /* lrr: RH or RH-1 */ RCU_INIT_POINTER(node->avl_right, r); /* r: RH */ node->avl_height = rh + 1; /* node: RH+1 */ @@ -286,9 +287,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], struct inet_peer *rr, *rl, *rlr, *rll; int rlh; rr = rcu_dereference_protected(r->avl_right, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); rl = rcu_dereference_protected(r->avl_left, - lockdep_is_held(&peers.lock)); + lockdep_is_held(&base->lock)); rlh = node_height(rl); if (rlh <= node_height(rr)) { /* rr: LH+1 */ RCU_INIT_POINTER(node->avl_right, rl); /* rl: LH or LH+1 */ @@ -300,9 +301,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], RCU_INIT_POINTER(*nodep, r); } else { /* rr: RH, rl: RH+1 */ rlr = rcu_dereference_protected(rl->avl_right, - lockdep_is_held(&peers.lock)); /* rlr: LH or LH-1 */ + lockdep_is_held(&base->lock)); /* rlr: LH or LH-1 */ rll = rcu_dereference_protected(rl->avl_left, - lockdep_is_held(&peers.lock)); /* rll: LH or LH-1 */ + lockdep_is_held(&base->lock)); /* rll: LH or LH-1 */ RCU_INIT_POINTER(node->avl_right, rll); /* rll: LH or LH-1 */ RCU_INIT_POINTER(node->avl_left, l); /* l: LH */ node->avl_height = lh + 1; /* node: LH+1 */ @@ -321,14 +322,14 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[], } /* Called with local BH disabled and the pool lock held. */ -#define link_to_pool(n) \ +#define link_to_pool(n, base) \ do { \ n->avl_height = 1; \ n->avl_left = peer_avl_empty_rcu; \ n->avl_right = peer_avl_empty_rcu; \ /* lockless readers can catch us now */ \ rcu_assign_pointer(**--stackptr, n); \ - peer_avl_rebalance(stack, stackptr); \ + peer_avl_rebalance(stack, stackptr, base); \ } while (0) static void inetpeer_free_rcu(struct rcu_head *head) @@ -337,13 +338,13 @@ static void inetpeer_free_rcu(struct rcu_head *head) } /* May be called with local BH enabled. */ -static void unlink_from_pool(struct inet_peer *p) +static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) { int do_free; do_free = 0; - spin_lock_bh(&peers.lock); + spin_lock_bh(&base->lock); /* Check the reference counter. It was artificially incremented by 1 * in cleanup() function to prevent sudden disappearing. If we can * atomically (because of lockless readers) take this last reference, @@ -353,7 +354,7 @@ static void unlink_from_pool(struct inet_peer *p) if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { struct inet_peer __rcu **stack[PEER_MAXDEPTH]; struct inet_peer __rcu ***stackptr, ***delp; - if (lookup(p->v4daddr, stack) != p) + if (lookup(p->v4daddr, stack, base) != p) BUG(); delp = stackptr - 1; /* *delp[0] == p */ if (p->avl_left == peer_avl_empty_rcu) { @@ -362,9 +363,9 @@ static void unlink_from_pool(struct inet_peer *p) } else { /* look for a node to insert instead of p */ struct inet_peer *t; - t = lookup_rightempty(p); + t = lookup_rightempty(p, base); BUG_ON(rcu_dereference_protected(*stackptr[-1], - lockdep_is_held(&peers.lock)) != t); + lockdep_is_held(&base->lock)) != t); **--stackptr = t->avl_left; /* t is removed, t->v4daddr > x->v4daddr for any * x in p->avl_left subtree. @@ -376,11 +377,11 @@ static void unlink_from_pool(struct inet_peer *p) BUG_ON(delp[1] != &p->avl_left); delp[1] = &t->avl_left; /* was &p->avl_left */ } - peer_avl_rebalance(stack, stackptr); - peers.total--; + peer_avl_rebalance(stack, stackptr, base); + base->total--; do_free = 1; } - spin_unlock_bh(&peers.lock); + spin_unlock_bh(&base->lock); if (do_free) call_rcu_bh(&p->rcu, inetpeer_free_rcu); @@ -395,6 +396,11 @@ static void unlink_from_pool(struct inet_peer *p) inet_putpeer(p); } +static struct inet_peer_base *peer_to_base(struct inet_peer *p) +{ + return &v4_peers; +} + /* May be called with local BH enabled. */ static int cleanup_once(unsigned long ttl) { @@ -428,21 +434,27 @@ static int cleanup_once(unsigned long ttl) * happen because of entry limits in route cache. */ return -1; - unlink_from_pool(p); + unlink_from_pool(p, peer_to_base(p)); return 0; } +static struct inet_peer_base *family_to_base(int family) +{ + return &v4_peers; +} + /* Called with or without local BH being disabled. */ struct inet_peer *inet_getpeer(__be32 daddr, int create) { - struct inet_peer *p; struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; + struct inet_peer_base *base = family_to_base(AF_INET); + struct inet_peer *p; /* Look up for the address quickly, lockless. * Because of a concurrent writer, we might not find an existing entry. */ rcu_read_lock_bh(); - p = lookup_rcu_bh(daddr); + p = lookup_rcu_bh(daddr, base); rcu_read_unlock_bh(); if (p) { @@ -456,11 +468,11 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) /* retry an exact lookup, taking the lock before. * At least, nodes should be hot in our cache. */ - spin_lock_bh(&peers.lock); - p = lookup(daddr, stack); + spin_lock_bh(&base->lock); + p = lookup(daddr, stack, base); if (p != peer_avl_empty) { atomic_inc(&p->refcnt); - spin_unlock_bh(&peers.lock); + spin_unlock_bh(&base->lock); /* Remove the entry from unused list if it was there. */ unlink_from_unused(p); return p; @@ -476,30 +488,36 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) /* Link the node. */ - link_to_pool(p); - peers.total++; + link_to_pool(p, base); + base->total++; } - spin_unlock_bh(&peers.lock); + spin_unlock_bh(&base->lock); - if (peers.total >= inet_peer_threshold) + if (base->total >= inet_peer_threshold) /* Remove one less-recently-used entry. */ cleanup_once(0); return p; } +static int compute_total(void) +{ + return v4_peers.total; +} + /* Called with local BH disabled. */ static void peer_check_expire(unsigned long dummy) { unsigned long now = jiffies; - int ttl; + int ttl, total; - if (peers.total >= inet_peer_threshold) + total = compute_total(); + if (total >= inet_peer_threshold) ttl = inet_peer_minttl; else ttl = inet_peer_maxttl - (inet_peer_maxttl - inet_peer_minttl) / HZ * - peers.total / inet_peer_threshold * HZ; + total / inet_peer_threshold * HZ; while (!cleanup_once(ttl)) { if (jiffies != now) break; @@ -508,13 +526,14 @@ static void peer_check_expire(unsigned long dummy) /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime * interval depending on the total number of entries (more entries, * less interval). */ - if (peers.total >= inet_peer_threshold) + total = compute_total(); + if (total >= inet_peer_threshold) peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime; else peer_periodic_timer.expires = jiffies + inet_peer_gc_maxtime - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ * - peers.total / inet_peer_threshold * HZ; + total / inet_peer_threshold * HZ; add_timer(&peer_periodic_timer); } -- cgit v1.2.3-59-g8ed1b From 582a72da9a41be9227dc931d728ae2906880a589 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 11:53:55 -0800 Subject: inetpeer: Introduce inet_peer_address_t. Currently only the v4 aspect is used, but this will change. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 10 +++++++++- net/ipv4/inetpeer.c | 16 ++++++++-------- net/ipv4/tcp_ipv4.c | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index fe239bfe5f7f..d7e60792d76e 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -13,10 +13,18 @@ #include #include +typedef struct { + union { + __be32 a4; + __be32 a6[4]; + }; + __u16 family; +} inet_peer_address_t; + struct inet_peer { /* group together avl_left,avl_right,v4daddr to speedup lookups */ struct inet_peer __rcu *avl_left, *avl_right; - __be32 v4daddr; /* peer's address */ + inet_peer_address_t daddr; __u32 avl_height; struct list_head unused; __u32 dtime; /* the time of last use of not diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index f94400848921..893f998efdbb 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -63,7 +63,7 @@ * refcnt: atomically against modifications on other CPU; * usually under some other lock to prevent node disappearing * dtime: unused node list lock - * v4daddr: unchangeable + * daddr: unchangeable * ip_id_count: atomic value (no lock needed) */ @@ -165,9 +165,9 @@ static void unlink_from_unused(struct inet_peer *p) for (u = rcu_dereference_protected(_base->root, \ lockdep_is_held(&_base->lock)); \ u != peer_avl_empty; ) { \ - if (_daddr == u->v4daddr) \ + if (_daddr == u->daddr.a4) \ break; \ - if ((__force __u32)_daddr < (__force __u32)u->v4daddr) \ + if ((__force __u32)_daddr < (__force __u32)u->daddr.a4) \ v = &u->avl_left; \ else \ v = &u->avl_right; \ @@ -191,7 +191,7 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr, struct inet_peer_base *base int count = 0; while (u != peer_avl_empty) { - if (daddr == u->v4daddr) { + if (daddr == u->daddr.a4) { /* Before taking a reference, check if this entry was * deleted, unlink_from_pool() sets refcnt=-1 to make * distinction between an unused entry (refcnt=0) and @@ -201,7 +201,7 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr, struct inet_peer_base *base u = NULL; return u; } - if ((__force __u32)daddr < (__force __u32)u->v4daddr) + if ((__force __u32)daddr < (__force __u32)u->daddr.a4) u = rcu_dereference_bh(u->avl_left); else u = rcu_dereference_bh(u->avl_right); @@ -354,7 +354,7 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { struct inet_peer __rcu **stack[PEER_MAXDEPTH]; struct inet_peer __rcu ***stackptr, ***delp; - if (lookup(p->v4daddr, stack, base) != p) + if (lookup(p->daddr.a4, stack, base) != p) BUG(); delp = stackptr - 1; /* *delp[0] == p */ if (p->avl_left == peer_avl_empty_rcu) { @@ -367,7 +367,7 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) BUG_ON(rcu_dereference_protected(*stackptr[-1], lockdep_is_held(&base->lock)) != t); **--stackptr = t->avl_left; - /* t is removed, t->v4daddr > x->v4daddr for any + /* t is removed, t->daddr > x->daddr for any * x in p->avl_left subtree. * Put t in the old place of p. */ RCU_INIT_POINTER(*delp[0], t); @@ -479,7 +479,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) } p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; if (p) { - p->v4daddr = daddr; + p->daddr.a4 = daddr; atomic_set(&p->refcnt, 1); atomic_set(&p->rid, 0); atomic_set(&p->ip_id_count, secure_ip_id(daddr)); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 69ccbc1dde9c..b8bbf89409b0 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1347,7 +1347,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) tcp_death_row.sysctl_tw_recycle && (dst = inet_csk_route_req(sk, req)) != NULL && (peer = rt_get_peer((struct rtable *)dst)) != NULL && - peer->v4daddr == saddr) { + peer->daddr.a4 == saddr) { inet_peer_refcheck(peer); if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && (s32)(peer->tcp_ts - req->ts_recent) > -- cgit v1.2.3-59-g8ed1b From b534ecf1cd26f094497da6ae28a6ab64cdbe1617 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 11:54:19 -0800 Subject: inetpeer: Make inet_getpeer() take an inet_peer_adress_t pointer. And make an inet_getpeer_v4() helper, update callers. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 11 ++++++++++- net/ipv4/inetpeer.c | 10 +++++----- net/ipv4/ip_fragment.c | 2 +- net/ipv4/route.c | 2 +- net/ipv4/tcp_ipv4.c | 4 ++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index d7e60792d76e..834f0456c87e 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -50,7 +50,16 @@ struct inet_peer { void inet_initpeers(void) __init; /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(__be32 daddr, int create); +struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create); + +static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) +{ + inet_peer_address_t daddr; + + daddr.a4 = v4daddr; + daddr.family = AF_INET; + return inet_getpeer(&daddr, create); +} /* can be called from BH context or outside */ extern void inet_putpeer(struct inet_peer *p); diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 893f998efdbb..9aa76b8dd490 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -444,7 +444,7 @@ static struct inet_peer_base *family_to_base(int family) } /* Called with or without local BH being disabled. */ -struct inet_peer *inet_getpeer(__be32 daddr, int create) +struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; struct inet_peer_base *base = family_to_base(AF_INET); @@ -454,7 +454,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) * Because of a concurrent writer, we might not find an existing entry. */ rcu_read_lock_bh(); - p = lookup_rcu_bh(daddr, base); + p = lookup_rcu_bh(daddr->a4, base); rcu_read_unlock_bh(); if (p) { @@ -469,7 +469,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) * At least, nodes should be hot in our cache. */ spin_lock_bh(&base->lock); - p = lookup(daddr, stack, base); + p = lookup(daddr->a4, stack, base); if (p != peer_avl_empty) { atomic_inc(&p->refcnt); spin_unlock_bh(&base->lock); @@ -479,10 +479,10 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) } p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; if (p) { - p->daddr.a4 = daddr; + p->daddr = *daddr; atomic_set(&p->refcnt, 1); atomic_set(&p->rid, 0); - atomic_set(&p->ip_id_count, secure_ip_id(daddr)); + atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4)); p->tcp_ts_stamp = 0; INIT_LIST_HEAD(&p->unused); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 168440834ade..e6215bdd96c0 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -141,7 +141,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a) qp->daddr = arg->iph->daddr; qp->user = arg->user; qp->peer = sysctl_ipfrag_max_dist ? - inet_getpeer(arg->iph->saddr, 1) : NULL; + inet_getpeer_v4(arg->iph->saddr, 1) : NULL; } static __inline__ void ip4_frag_free(struct inet_frag_queue *q) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ec2333fb637e..3843c2dfde82 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1289,7 +1289,7 @@ void rt_bind_peer(struct rtable *rt, int create) { struct inet_peer *peer; - peer = inet_getpeer(rt->rt_dst, create); + peer = inet_getpeer_v4(rt->rt_dst, create); if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) inet_putpeer(peer); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b8bbf89409b0..00285fcf6788 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1778,7 +1778,7 @@ int tcp_v4_remember_stamp(struct sock *sk) int release_it = 0; if (!rt || rt->rt_dst != inet->inet_daddr) { - peer = inet_getpeer(inet->inet_daddr, 1); + peer = inet_getpeer_v4(inet->inet_daddr, 1); release_it = 1; } else { if (!rt->peer) @@ -1804,7 +1804,7 @@ EXPORT_SYMBOL(tcp_v4_remember_stamp); int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw) { - struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1); + struct inet_peer *peer = inet_getpeer_v4(tw->tw_daddr, 1); if (peer) { const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); -- cgit v1.2.3-59-g8ed1b From 026630450244b8f8d1baf54548be0800aa1823ed Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 12:08:53 -0800 Subject: inetpeer: Abstract address comparisons. Now v4 and v6 addresses will both work properly. Signed-off-by: David S. Miller --- net/ipv4/inetpeer.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 9aa76b8dd490..c96dc51c2e49 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -152,6 +152,22 @@ static void unlink_from_unused(struct inet_peer *p) } } +static int addr_compare(const inet_peer_address_t *a, + const inet_peer_address_t *b) +{ + int i, n = (a->family == AF_INET ? 1 : 4); + + for (i = 0; i < n; i++) { + if (a->a6[i] == b->a6[i]) + continue; + if (a->a6[i] < b->a6[i]) + return -1; + return 1; + } + + return 0; +} + /* * Called with local BH disabled and the pool lock held. */ @@ -165,9 +181,10 @@ static void unlink_from_unused(struct inet_peer *p) for (u = rcu_dereference_protected(_base->root, \ lockdep_is_held(&_base->lock)); \ u != peer_avl_empty; ) { \ - if (_daddr == u->daddr.a4) \ + int cmp = addr_compare(_daddr, &u->daddr); \ + if (cmp == 0) \ break; \ - if ((__force __u32)_daddr < (__force __u32)u->daddr.a4) \ + if (cmp == -1) \ v = &u->avl_left; \ else \ v = &u->avl_right; \ @@ -185,13 +202,15 @@ static void unlink_from_unused(struct inet_peer *p) * But every pointer we follow is guaranteed to be valid thanks to RCU. * We exit from this function if number of links exceeds PEER_MAXDEPTH */ -static struct inet_peer *lookup_rcu_bh(__be32 daddr, struct inet_peer_base *base) +static struct inet_peer *lookup_rcu_bh(const inet_peer_address_t *daddr, + struct inet_peer_base *base) { struct inet_peer *u = rcu_dereference_bh(base->root); int count = 0; while (u != peer_avl_empty) { - if (daddr == u->daddr.a4) { + int cmp = addr_compare(daddr, &u->daddr); + if (cmp == 0) { /* Before taking a reference, check if this entry was * deleted, unlink_from_pool() sets refcnt=-1 to make * distinction between an unused entry (refcnt=0) and @@ -201,7 +220,7 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr, struct inet_peer_base *base u = NULL; return u; } - if ((__force __u32)daddr < (__force __u32)u->daddr.a4) + if (cmp == -1) u = rcu_dereference_bh(u->avl_left); else u = rcu_dereference_bh(u->avl_right); @@ -354,7 +373,7 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { struct inet_peer __rcu **stack[PEER_MAXDEPTH]; struct inet_peer __rcu ***stackptr, ***delp; - if (lookup(p->daddr.a4, stack, base) != p) + if (lookup(&p->daddr, stack, base) != p) BUG(); delp = stackptr - 1; /* *delp[0] == p */ if (p->avl_left == peer_avl_empty_rcu) { @@ -454,7 +473,7 @@ struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) * Because of a concurrent writer, we might not find an existing entry. */ rcu_read_lock_bh(); - p = lookup_rcu_bh(daddr->a4, base); + p = lookup_rcu_bh(daddr, base); rcu_read_unlock_bh(); if (p) { @@ -469,7 +488,7 @@ struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) * At least, nodes should be hot in our cache. */ spin_lock_bh(&base->lock); - p = lookup(daddr->a4, stack, base); + p = lookup(daddr, stack, base); if (p != peer_avl_empty) { atomic_inc(&p->refcnt); spin_unlock_bh(&base->lock); -- cgit v1.2.3-59-g8ed1b From 021e9299113363cc1b713f86b2cba30b8e6cb5dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 12:12:23 -0800 Subject: inetpeer: Add v6 peers tree, abstract root properly. Add the ipv6 peer tree instance, and adapt remaining direct references to 'v4_peers' as needed. Signed-off-by: David S. Miller --- net/ipv4/inetpeer.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index c96dc51c2e49..1c1335b0d401 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -79,15 +79,24 @@ static const struct inet_peer peer_fake_node = { .avl_height = 0 }; -static struct inet_peer_base { +struct inet_peer_base { struct inet_peer __rcu *root; spinlock_t lock; int total; -} v4_peers = { +}; + +static struct inet_peer_base v4_peers = { .root = peer_avl_empty_rcu, .lock = __SPIN_LOCK_UNLOCKED(v4_peers.lock), .total = 0, }; + +static struct inet_peer_base v6_peers = { + .root = peer_avl_empty_rcu, + .lock = __SPIN_LOCK_UNLOCKED(v6_peers.lock), + .total = 0, +}; + #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ /* Exported for sysctl_net_ipv4. */ @@ -415,9 +424,14 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) inet_putpeer(p); } +static struct inet_peer_base *family_to_base(int family) +{ + return (family == AF_INET ? &v4_peers : &v6_peers); +} + static struct inet_peer_base *peer_to_base(struct inet_peer *p) { - return &v4_peers; + return family_to_base(p->daddr.family); } /* May be called with local BH enabled. */ @@ -457,11 +471,6 @@ static int cleanup_once(unsigned long ttl) return 0; } -static struct inet_peer_base *family_to_base(int family) -{ - return &v4_peers; -} - /* Called with or without local BH being disabled. */ struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) { @@ -521,7 +530,7 @@ struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) static int compute_total(void) { - return v4_peers.total; + return v4_peers.total + v6_peers.total; } /* Called with local BH disabled. */ -- cgit v1.2.3-59-g8ed1b From 672f007d65f50468a4a1e55825fe58e5b035324d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 12:20:00 -0800 Subject: inetpeer: Add inet_getpeer_v6() Now that all of the infrastructure is in place, we can add the ipv6 shorthand for peer creation. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 834f0456c87e..fb8aeb1fd23f 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -11,6 +11,7 @@ #include #include #include +#include #include typedef struct { @@ -61,6 +62,15 @@ static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) return inet_getpeer(&daddr, create); } +static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int create) +{ + inet_peer_address_t daddr; + + ipv6_addr_copy((struct in6_addr *)daddr.a6, v6daddr); + daddr.family = AF_INET6; + return inet_getpeer(&daddr, create); +} + /* can be called from BH context or outside */ extern void inet_putpeer(struct inet_peer *p); -- cgit v1.2.3-59-g8ed1b From b3419363808f2481b24a817f491878e1795db4c7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 12:27:11 -0800 Subject: ipv6: Add infrastructure to bind inet_peer objects to routes. They are only allowed on cached ipv6 routes. Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 2 ++ include/net/ip6_route.h | 3 +++ net/ipv4/inetpeer.c | 2 ++ net/ipv6/route.c | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 062a823d311c..708ff7cb8806 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_IPV6_MULTIPLE_TABLES #define FIB6_TABLE_HASHSZ 256 @@ -109,6 +110,7 @@ struct rt6_info { u32 rt6i_metric; struct inet6_dev *rt6i_idev; + struct inet_peer *rt6i_peer; #ifdef CONFIG_XFRM u32 rt6i_flow_cache_genid; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 278312c95f96..23fed28db4bb 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -56,6 +56,9 @@ static inline unsigned int rt6_flags2srcprefs(int flags) return (flags >> 3) & 7; } +extern void rt6_bind_peer(struct rt6_info *rt, + int create); + extern void ip6_route_input(struct sk_buff *skb); extern struct dst_entry * ip6_route_output(struct net *net, diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 1c1335b0d401..f95b89f3916d 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -532,6 +532,7 @@ static int compute_total(void) { return v4_peers.total + v6_peers.total; } +EXPORT_SYMBOL_GPL(inet_getpeer); /* Called with local BH disabled. */ static void peer_check_expire(unsigned long dummy) @@ -577,3 +578,4 @@ void inet_putpeer(struct inet_peer *p) local_bh_enable(); } +EXPORT_SYMBOL_GPL(inet_putpeer); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a0c4ad109c63..026caef0326c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -188,11 +188,29 @@ static void ip6_dst_destroy(struct dst_entry *dst) { struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; + struct inet_peer *peer = rt->rt6i_peer; if (idev != NULL) { rt->rt6i_idev = NULL; in6_dev_put(idev); } + if (peer) { + BUG_ON(!(rt->rt6i_flags & RTF_CACHE)); + rt->rt6i_peer = NULL; + inet_putpeer(peer); + } +} + +void rt6_bind_peer(struct rt6_info *rt, int create) +{ + struct inet_peer *peer; + + if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE))) + return; + + peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); + if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) + inet_putpeer(peer); } static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, -- cgit v1.2.3-59-g8ed1b From 3f419d2d487821093ee46e898b5f8747f9edc9cd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 29 Nov 2010 13:37:14 -0800 Subject: inet: Turn ->remember_stamp into ->get_peer in connection AF ops. Then we can make a completely generic tcp_remember_stamp() that uses ->get_peer() as a helper, minimizing the AF specific code and minimizing the eventual code duplication when we implement the ipv6 side of TW recycling. Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 2 +- include/net/tcp.h | 2 +- net/ipv4/tcp_ipv4.c | 35 ++++++++--------------------------- net/ipv4/tcp_minisocks.c | 31 ++++++++++++++++++++++++++++++- net/ipv6/tcp_ipv6.c | 8 ++++---- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index e4f494b42e06..6c93a56cc958 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -43,7 +43,7 @@ struct inet_connection_sock_af_ops { struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst); - int (*remember_stamp)(struct sock *sk); + struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it); u16 net_header_len; u16 sockaddr_len; int (*setsockopt)(struct sock *sk, int level, int optname, diff --git a/include/net/tcp.h b/include/net/tcp.h index e36c874c7fb1..3e239641d4ee 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -312,7 +312,7 @@ extern void tcp_shutdown (struct sock *sk, int how); extern int tcp_v4_rcv(struct sk_buff *skb); -extern int tcp_v4_remember_stamp(struct sock *sk); +extern struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it); extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 00285fcf6788..0ddf819cfb5d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1763,44 +1763,25 @@ do_time_wait: goto discard_it; } -/* VJ's idea. Save last timestamp seen from this destination - * and hold it at least for normal timewait interval to use for duplicate - * segment detection in subsequent connections, before they enter synchronized - * state. - */ - -int tcp_v4_remember_stamp(struct sock *sk) +struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) { + struct rtable *rt = (struct rtable *) __sk_dst_get(sk); struct inet_sock *inet = inet_sk(sk); - struct tcp_sock *tp = tcp_sk(sk); - struct rtable *rt = (struct rtable *)__sk_dst_get(sk); - struct inet_peer *peer = NULL; - int release_it = 0; + struct inet_peer *peer; if (!rt || rt->rt_dst != inet->inet_daddr) { peer = inet_getpeer_v4(inet->inet_daddr, 1); - release_it = 1; + *release_it = true; } else { if (!rt->peer) rt_bind_peer(rt, 1); peer = rt->peer; + *release_it = false; } - if (peer) { - if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 || - ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && - peer->tcp_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) { - peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp; - peer->tcp_ts = tp->rx_opt.ts_recent; - } - if (release_it) - inet_putpeer(peer); - return 1; - } - - return 0; + return peer; } -EXPORT_SYMBOL(tcp_v4_remember_stamp); +EXPORT_SYMBOL(tcp_v4_get_peer); int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw) { @@ -1828,7 +1809,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = { .rebuild_header = inet_sk_rebuild_header, .conn_request = tcp_v4_conn_request, .syn_recv_sock = tcp_v4_syn_recv_sock, - .remember_stamp = tcp_v4_remember_stamp, + .get_peer = tcp_v4_get_peer, .net_header_len = sizeof(struct iphdr), .setsockopt = ip_setsockopt, .getsockopt = ip_getsockopt, diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43cf901d7659..059082c873cf 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -49,6 +49,35 @@ struct inet_timewait_death_row tcp_death_row = { }; EXPORT_SYMBOL_GPL(tcp_death_row); +/* VJ's idea. Save last timestamp seen from this destination + * and hold it at least for normal timewait interval to use for duplicate + * segment detection in subsequent connections, before they enter synchronized + * state. + */ + +static int tcp_remember_stamp(struct sock *sk) +{ + const struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); + struct inet_peer *peer; + bool release_it; + + peer = icsk->icsk_af_ops->get_peer(sk, &release_it); + if (peer) { + if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 || + ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && + peer->tcp_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) { + peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp; + peer->tcp_ts = tp->rx_opt.ts_recent; + } + if (release_it) + inet_putpeer(peer); + return 1; + } + + return 0; +} + static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) { if (seq == s_win) @@ -274,7 +303,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) int recycle_ok = 0; if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) - recycle_ok = icsk->icsk_af_ops->remember_stamp(sk); + recycle_ok = tcp_remember_stamp(sk); if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets) tw = inet_twsk_alloc(sk, state); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 7e41e2cbb85e..e394d0029d8d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1818,10 +1818,10 @@ do_time_wait: goto discard_it; } -static int tcp_v6_remember_stamp(struct sock *sk) +struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) { /* Alas, not yet... */ - return 0; + return NULL; } static const struct inet_connection_sock_af_ops ipv6_specific = { @@ -1830,7 +1830,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = { .rebuild_header = inet6_sk_rebuild_header, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, - .remember_stamp = tcp_v6_remember_stamp, + .get_peer = tcp_v6_get_peer, .net_header_len = sizeof(struct ipv6hdr), .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, @@ -1862,7 +1862,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = { .rebuild_header = inet_sk_rebuild_header, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, - .remember_stamp = tcp_v4_remember_stamp, + .get_peer = tcp_v4_get_peer, .net_header_len = sizeof(struct iphdr), .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, -- cgit v1.2.3-59-g8ed1b From 0793f83f0ec2142d06abe53570417c8d95e0310a Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 1 Dec 2010 12:39:28 -0800 Subject: bnx2x: Add Nic partitioning mode (57712 devices) NIC partitioning is another flavor of multi function - having few PCI functions share the same physical port. Unlike the currently supported mode of multi-function which depends on the switch configuration and uses outer-VLAN, the NPAR mode is switch independent and uses the MAC addresses to distribute incoming packets to the different functions. This patch adds the specific HW setting of the NPAR mode and some distinctions between switch dependent (SD) and switch independent (SI) multi-function (MF) modes where the configuration is not the same. Advance driver version to 1.60.00-6 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 11 +- drivers/net/bnx2x/bnx2x_cmn.c | 34 ++-- drivers/net/bnx2x/bnx2x_cmn.h | 10 ++ drivers/net/bnx2x/bnx2x_ethtool.c | 58 +++++-- drivers/net/bnx2x/bnx2x_hsi.h | 42 ++++- drivers/net/bnx2x/bnx2x_main.c | 336 ++++++++++++++++++++++++++++++-------- drivers/net/bnx2x/bnx2x_reg.h | 5 + 7 files changed, 400 insertions(+), 96 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 342ab58b14b3..cfc25cf064d3 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-5" -#define DRV_MODULE_RELDATE "2010/11/24" +#define DRV_MODULE_VERSION "1.60.00-6" +#define DRV_MODULE_RELDATE "2010/11/29" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE @@ -671,6 +671,10 @@ enum { CAM_ISCSI_ETH_LINE, CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE }; +/* number of MACs per function in NIG memory - used for SI mode */ +#define NIG_LLH_FUNC_MEM_SIZE 16 +/* number of entries in NIG_REG_LLHX_FUNC_MEM */ +#define NIG_LLH_FUNC_MEM_MAX_OFFSET 8 #define BNX2X_VF_ID_INVALID 0xFF @@ -967,6 +971,8 @@ struct bnx2x { u16 mf_ov; u8 mf_mode; #define IS_MF(bp) (bp->mf_mode != 0) +#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI) +#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD) u8 wol; @@ -1010,6 +1016,7 @@ struct bnx2x { #define BNX2X_ACCEPT_ALL_UNICAST 0x0004 #define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 #define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020 #define BNX2X_PROMISCUOUS_MODE 0x10000 u32 rx_mode; diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index e20b2d378929..a4555edbe9ce 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -698,6 +698,29 @@ void bnx2x_release_phy_lock(struct bnx2x *bp) mutex_unlock(&bp->port.phy_mutex); } +/* calculates MF speed according to current linespeed and MF configuration */ +u16 bnx2x_get_mf_speed(struct bnx2x *bp) +{ + u16 line_speed = bp->link_vars.line_speed; + if (IS_MF(bp)) { + u16 maxCfg = (bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT; + /* Calculate the current MAX line speed limit for the DCC + * capable devices + */ + if (IS_MF_SD(bp)) { + u16 vn_max_rate = maxCfg * 100; + + if (vn_max_rate < line_speed) + line_speed = vn_max_rate; + } else /* IS_MF_SI(bp)) */ + line_speed = (line_speed * maxCfg) / 100; + } + + return line_speed; +} + void bnx2x_link_report(struct bnx2x *bp) { if (bp->flags & MF_FUNC_DIS) { @@ -713,17 +736,8 @@ void bnx2x_link_report(struct bnx2x *bp) netif_carrier_on(bp->dev); netdev_info(bp->dev, "NIC Link is Up, "); - line_speed = bp->link_vars.line_speed; - if (IS_MF(bp)) { - u16 vn_max_rate; + line_speed = bnx2x_get_mf_speed(bp); - vn_max_rate = - ((bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < line_speed) - line_speed = vn_max_rate; - } pr_cont("%d Mbps ", line_speed); if (bp->link_vars.duplex == DUPLEX_FULL) diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 6b28739c5302..cb8f2a040a18 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -72,6 +72,16 @@ void bnx2x__link_status_update(struct bnx2x *bp); */ void bnx2x_link_report(struct bnx2x *bp); +/** + * calculates MF speed according to current linespeed and MF + * configuration + * + * @param bp + * + * @return u16 + */ +u16 bnx2x_get_mf_speed(struct bnx2x *bp); + /** * MSI-X slowpath interrupt handler * diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 03012787de2f..bd94827e5e57 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -45,14 +45,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->speed = bp->link_params.req_line_speed[cfg_idx]; cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } - if (IS_MF(bp)) { - u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * - 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } + if (IS_MF(bp)) + cmd->speed = bnx2x_get_mf_speed(bp); if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; @@ -87,18 +82,57 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; + u32 speed; - if (IS_MF(bp)) + if (IS_MF_SD(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" - DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" - DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + " supported 0x%x advertising 0x%x speed %d speed_hi %d\n" + " duplex %d port %d phy_address %d transceiver %d\n" + " autoneg %d maxtxpkt %d maxrxpkt %d\n", cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->speed_hi, cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + speed = cmd->speed; + speed |= (cmd->speed_hi << 16); + + if (IS_MF_SI(bp)) { + u32 param = 0; + u32 line_speed = bp->link_vars.line_speed; + + /* use 10G if no link detected */ + if (!line_speed) + line_speed = 10000; + + if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) { + BNX2X_DEV_INFO("To set speed BC %X or higher " + "is required, please upgrade BC\n", + REQ_BC_VER_4_SET_MF_BW); + return -EINVAL; + } + if (line_speed < speed) { + BNX2X_DEV_INFO("New speed should be less or equal " + "to actual line speed\n"); + return -EINVAL; + } + /* load old values */ + param = bp->mf_config[BP_VN(bp)]; + + /* leave only MIN value */ + param &= FUNC_MF_CFG_MIN_BW_MASK; + + /* set new MAX value */ + param |= (((speed * 100) / line_speed) + << FUNC_MF_CFG_MAX_BW_SHIFT) + & FUNC_MF_CFG_MAX_BW_MASK; + + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); + return 0; + } + cfg_idx = bnx2x_get_link_cfg_idx(bp); old_multi_phy_config = bp->link_params.multi_phy_config; switch (cmd->port) { @@ -168,8 +202,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ - u32 speed = cmd->speed; - speed |= (cmd->speed_hi << 16); switch (speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 4cfd4e9b5586..6555c477f893 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -434,7 +434,12 @@ struct shared_feat_cfg { /* NVRAM Offset */ #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000 #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002 -#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_MASK 0x00000700 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SHIFT 8 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED 0x00000000 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF 0x00000100 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300 }; @@ -815,6 +820,9 @@ struct drv_func_mb { #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 +#define DRV_MSG_CODE_SET_MF_BW 0xe0000000 +#define REQ_BC_VER_4_SET_MF_BW 0x00060202 +#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 @@ -888,6 +896,7 @@ struct drv_func_mb { u32 drv_status; #define DRV_STATUS_PMF 0x00000001 +#define DRV_STATUS_SET_MF_BW 0x00000004 #define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 #define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 @@ -988,12 +997,43 @@ struct func_mf_cfg { }; +/* This structure is not applicable and should not be accessed on 57711 */ +struct func_ext_cfg { + u32 func_cfg; +#define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF +#define MACP_FUNC_CFG_FLAGS_SHIFT 0 +#define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001 +#define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002 +#define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004 +#define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008 + + u32 iscsi_mac_addr_upper; + u32 iscsi_mac_addr_lower; + + u32 fcoe_mac_addr_upper; + u32 fcoe_mac_addr_lower; + + u32 fcoe_wwn_port_name_upper; + u32 fcoe_wwn_port_name_lower; + + u32 fcoe_wwn_node_name_upper; + u32 fcoe_wwn_node_name_lower; + + u32 preserve_data; +#define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0) +#define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1) +#define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2) +#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3) +#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4) +}; + struct mf_cfg { struct shared_mf_cfg shared_mf_config; struct port_mf_cfg port_mf_config[PORT_MAX]; struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; + struct func_ext_cfg func_ext_config[E1H_FUNC_MAX]; }; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f53edfd011bf..1552fc3c1351 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2026,13 +2026,28 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) static void bnx2x_read_mf_cfg(struct bnx2x *bp) { - int vn; + int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1); if (BP_NOMCP(bp)) return; /* what should be the default bvalue in this case */ + /* For 2 port configuration the absolute function number formula + * is: + * abs_func = 2 * vn + BP_PORT + BP_PATH + * + * and there are 4 functions per port + * + * For 4 port configuration it is + * abs_func = 4 * vn + 2 * BP_PORT + BP_PATH + * + * and there are 2 functions per port + */ for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int /*abs*/func = 2*vn + BP_PORT(bp); + int /*abs*/func = n * (2 * vn + BP_PORT(bp)) + BP_PATH(bp); + + if (func >= E1H_FUNC_MAX) + break; + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } @@ -2248,10 +2263,21 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; u8 unmatched_unicast = 0; + if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) + unmatched_unicast = 1; + if (filters & BNX2X_PROMISCUOUS_MODE) { /* promiscious - accept all, drop none */ drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + if (IS_MF_SI(bp)) { + /* + * SI mode defines to accept in promiscuos mode + * only unmatched packets + */ + unmatched_unicast = 1; + accp_all_ucast = 0; + } } if (filters & BNX2X_ACCEPT_UNICAST) { /* accept matched ucast */ @@ -2260,6 +2286,11 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) if (filters & BNX2X_ACCEPT_MULTICAST) { /* accept matched mcast */ drop_all_mcast = 0; + if (IS_MF_SI(bp)) + /* since mcast addresses won't arrive with ovlan, + * fw needs to accept all of them in + * switch-independent mode */ + accp_all_mcast = 1; } if (filters & BNX2X_ACCEPT_ALL_UNICAST) { /* accept all mcast */ @@ -2372,7 +2403,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, /* calculate queue flags */ flags |= QUEUE_FLG_CACHE_ALIGN; flags |= QUEUE_FLG_HC; - flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; + flags |= IS_MF_SD(bp) ? QUEUE_FLG_OV : 0; flags |= QUEUE_FLG_VLAN; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); @@ -2573,6 +2604,26 @@ static void bnx2x_e1h_enable(struct bnx2x *bp) */ } +/* called due to MCP event (on pmf): + * reread new bandwidth configuration + * configure FW + * notify others function about the change + */ +static inline void bnx2x_config_mf_bw(struct bnx2x *bp) +{ + if (bp->link_vars.link_up) { + bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); + bnx2x_link_sync_notify(bp); + } + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); +} + +static inline void bnx2x_set_mf_bw(struct bnx2x *bp) +{ + bnx2x_config_mf_bw(bp); + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); +} + static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) { DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); @@ -2598,10 +2649,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; } if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { - - bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); - bnx2x_link_sync_notify(bp); - storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + bnx2x_config_mf_bw(bp); dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; } @@ -3022,6 +3070,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, (val & DRV_STATUS_DCC_EVENT_MASK)); + + if (val & DRV_STATUS_SET_MF_BW) + bnx2x_set_mf_bw(bp); + bnx2x__link_status_update(bp); if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) bnx2x_pmf_update(bp); @@ -4232,6 +4284,15 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) bp->mf_mode); } + if (IS_MF_SI(bp)) + /* + * In switch independent mode, the TSTORM needs to accept + * packets that failed classification, since approximate match + * mac addresses aren't written to NIG LLH + */ + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2); + /* Zero this manually as its initialization is currently missing in the initTool */ for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) @@ -5048,12 +5109,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif if (!CHIP_IS_E1(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF_SD(bp)); if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ - int has_ovlan = IS_MF(bp); + int has_ovlan = IS_MF_SD(bp); REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); } @@ -5087,7 +5148,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); if (CHIP_IS_E2(bp)) { - int has_ovlan = IS_MF(bp); + int has_ovlan = IS_MF_SD(bp); REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); } @@ -5164,12 +5225,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); if (!CHIP_IS_E1(bp)) { REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp)); } if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ - REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); + REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF_SD(bp) ? 7 : 6)); } if (CHIP_REV_IS_SLOW(bp)) @@ -5386,7 +5447,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) if (!CHIP_IS_E1(bp)) { /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_MF(bp) ? 0x1 : 0x2)); + (IS_MF_SD(bp) ? 0x1 : 0x2)); if (CHIP_IS_E2(bp)) { val = 0; @@ -6170,6 +6231,70 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) return BP_VN(bp) * 32 + rel_offset; } +/** + * LLH CAM line allocations: currently only iSCSI and ETH macs are + * relevant. In addition, current implementation is tuned for a + * single ETH MAC. + * + * When multiple unicast ETH MACs PF configuration in switch + * independent mode is required (NetQ, multiple netdev MACs, + * etc.), consider better utilisation of 16 per function MAC + * entries in the LLH memory. + */ +enum { + LLH_CAM_ISCSI_ETH_LINE = 0, + LLH_CAM_ETH_LINE, + LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE +}; + +static void bnx2x_set_mac_in_nig(struct bnx2x *bp, + int set, + unsigned char *dev_addr, + int index) +{ + u32 wb_data[2]; + u32 mem_offset, ena_offset, mem_index; + /** + * indexes mapping: + * 0..7 - goes to MEM + * 8..15 - goes to MEM2 + */ + + if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) + return; + + /* calculate memory start offset according to the mapping + * and index in the memory */ + if (index < NIG_LLH_FUNC_MEM_MAX_OFFSET) { + mem_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : + NIG_REG_LLH0_FUNC_MEM; + ena_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : + NIG_REG_LLH0_FUNC_MEM_ENABLE; + mem_index = index; + } else { + mem_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2 : + NIG_REG_P0_LLH_FUNC_MEM2; + ena_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE : + NIG_REG_P0_LLH_FUNC_MEM2_ENABLE; + mem_index = index - NIG_LLH_FUNC_MEM_MAX_OFFSET; + } + + if (set) { + /* LLH_FUNC_MEM is a u64 WB register */ + mem_offset += 8*mem_index; + + wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | + (dev_addr[4] << 8) | dev_addr[5]); + wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); + + REG_WR_DMAE(bp, mem_offset, wb_data, 2); + } + + /* enable/disable the entry */ + REG_WR(bp, ena_offset + 4*mem_index, set); + +} + void bnx2x_set_eth_mac(struct bnx2x *bp, int set) { u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : @@ -6179,6 +6304,8 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, (1 << bp->fp->cl_id), cam_offset , 0); + bnx2x_set_mac_in_nig(bp, set, bp->dev->dev_addr, LLH_CAM_ETH_LINE); + if (CHIP_IS_E1(bp)) { /* broadcast MAC */ u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -6289,6 +6416,8 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) /* Send a SET_MAC ramrod */ bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, cam_offset, 0); + + bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); return 0; } #endif @@ -8076,7 +8205,6 @@ static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) { int port = BP_PORT(bp); - u32 val, val2; u32 config; u32 ext_phy_type, ext_phy_config; @@ -8135,25 +8263,62 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) bp->mdio.prtad = XGXS_EXT_PHY_ADDR(ext_phy_config); +} - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); - bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); +static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) +{ + u32 val, val2; + int func = BP_ABS_FUNC(bp); + int port = BP_PORT(bp); + + if (BP_NOMCP(bp)) { + BNX2X_ERROR("warning: random MAC workaround active\n"); + random_ether_addr(bp->dev->dev_addr); + } else if (IS_MF(bp)) { + val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); + val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); + if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && + (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) + bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); #ifdef BCM_CNIC - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower); - bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); + /* iSCSI NPAR MAC */ + if (IS_MF_SI(bp)) { + u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); + if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { + val2 = MF_CFG_RD(bp, func_ext_config[func]. + iscsi_mac_addr_upper); + val = MF_CFG_RD(bp, func_ext_config[func]. + iscsi_mac_addr_lower); + bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); + } + } #endif + } else { + /* in SF read MACs from port configuration */ + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); + bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); + +#ifdef BCM_CNIC + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. + iscsi_mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port]. + iscsi_mac_lower); + bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); +#endif + } + + memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); + } static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { - int func = BP_ABS_FUNC(bp); - int vn; - u32 val, val2; + int /*abs*/func = BP_ABS_FUNC(bp); + int vn, port; + u32 val = 0; int rc = 0; bnx2x_get_common_hwinfo(bp); @@ -8186,44 +8351,99 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->mf_ov = 0; bp->mf_mode = 0; vn = BP_E1HVN(bp); + port = BP_PORT(bp); + if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { + DP(NETIF_MSG_PROBE, + "shmem2base 0x%x, size %d, mfcfg offset %d\n", + bp->common.shmem2_base, SHMEM2_RD(bp, size), + (u32)offsetof(struct shmem2_region, mf_cfg_addr)); if (SHMEM2_HAS(bp, mf_cfg_addr)) bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); else bp->common.mf_cfg_base = bp->common.shmem_base + offsetof(struct shmem_region, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb); - bp->mf_config[vn] = - MF_CFG_RD(bp, func_mf_config[func].config); + /* + * get mf configuration: + * 1. existance of MF configuration + * 2. MAC address must be legal (check only upper bytes) + * for Switch-Independent mode; + * OVLAN must be legal for Switch-Dependent mode + * 3. SF_MODE configures specific MF mode + */ + if (bp->common.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE) { + /* get mf configuration */ + val = SHMEM_RD(bp, + dev_info.shared_feature_config.config); + val &= SHARED_FEAT_CFG_FORCE_SF_MODE_MASK; + + switch (val) { + case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT: + val = MF_CFG_RD(bp, func_mf_config[func]. + mac_upper); + /* check for legal mac (upper bytes)*/ + if (val != 0xffff) { + bp->mf_mode = MULTI_FUNCTION_SI; + bp->mf_config[vn] = MF_CFG_RD(bp, + func_mf_config[func].config); + } else + DP(NETIF_MSG_PROBE, "illegal MAC " + "address for SI\n"); + break; + case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED: + /* get OV configuration */ + val = MF_CFG_RD(bp, + func_mf_config[FUNC_0].e1hov_tag); + val &= FUNC_MF_CFG_E1HOV_TAG_MASK; + + if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { + bp->mf_mode = MULTI_FUNCTION_SD; + bp->mf_config[vn] = MF_CFG_RD(bp, + func_mf_config[func].config); + } else + DP(NETIF_MSG_PROBE, "illegal OV for " + "SD\n"); + break; + default: + /* Unknown configuration: reset mf_config */ + bp->mf_config[vn] = 0; + DP(NETIF_MSG_PROBE, "Unkown MF mode 0x%x\n", + val); + } + } - val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); - if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->mf_mode = 1; BNX2X_DEV_INFO("%s function mode\n", IS_MF(bp) ? "multi" : "single"); - if (IS_MF(bp)) { - val = (MF_CFG_RD(bp, func_mf_config[func]. - e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + val = MF_CFG_RD(bp, func_mf_config[func].e1hov_tag) & + FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { bp->mf_ov = val; - BNX2X_DEV_INFO("MF OV for func %d is %d " - "(0x%04x)\n", - func, bp->mf_ov, bp->mf_ov); + BNX2X_DEV_INFO("MF OV for func %d is %d" + " (0x%04x)\n", func, + bp->mf_ov, bp->mf_ov); } else { - BNX2X_ERROR("No valid MF OV for func %d," - " aborting\n", func); + BNX2X_ERR("No valid MF OV for func %d," + " aborting\n", func); rc = -EPERM; } - } else { - if (BP_VN(bp)) { - BNX2X_ERROR("VN %d in single function mode," - " aborting\n", BP_E1HVN(bp)); + break; + case MULTI_FUNCTION_SI: + BNX2X_DEV_INFO("func %d is in MF " + "switch-independent mode\n", func); + break; + default: + if (vn) { + BNX2X_ERR("VN %d in single function mode," + " aborting\n", vn); rc = -EPERM; } + break; } + } /* adjust igu_sb_cnt to MF for E1x */ @@ -8248,32 +8468,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } - if (IS_MF(bp)) { - val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); - val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); - if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && - (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { - bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); - bp->dev->dev_addr[1] = (u8)(val2 & 0xff); - bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); - bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); - bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); - bp->dev->dev_addr[5] = (u8)(val & 0xff); - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, - ETH_ALEN); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, - ETH_ALEN); - } - - return rc; - } - - if (BP_NOMCP(bp)) { - /* only supposed to happen on emulation/FPGA */ - BNX2X_ERROR("warning: random MAC workaround active\n"); - random_ether_addr(bp->dev->dev_addr); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); - } + /* Get MAC addresses */ + bnx2x_get_mac_hwinfo(bp); return rc; } diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1cefe489a955..64bdda189e5a 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1774,6 +1774,8 @@ /* [RW 8] event id for llh0 */ #define NIG_REG_LLH0_EVENT_ID 0x10084 #define NIG_REG_LLH0_FUNC_EN 0x160fc +#define NIG_REG_LLH0_FUNC_MEM 0x16180 +#define NIG_REG_LLH0_FUNC_MEM_ENABLE 0x16140 #define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100 /* [RW 1] Determine the IP version to look for in ~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */ @@ -1797,6 +1799,9 @@ #define NIG_REG_LLH1_ERROR_MASK 0x10090 /* [RW 8] event id for llh1 */ #define NIG_REG_LLH1_EVENT_ID 0x10088 +#define NIG_REG_LLH1_FUNC_MEM 0x161c0 +#define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 +#define NIG_REG_LLH1_FUNC_MEM_SIZE 16 /* [RW 8] init credit counter for port1 in LLH */ #define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 #define NIG_REG_LLH1_XCM_MASK 0x10134 -- cgit v1.2.3-59-g8ed1b From f2cd2d3e9b3ef960612e362f0ad129d735452df2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 29 Nov 2010 08:14:37 +0000 Subject: net sched: use xps information for qdisc NUMA affinity Allocate qdisc memory according to NUMA properties of cpus included in xps map. To be effective, qdisc should be (re)setup after changes of /sys/class/net/eth/queues/tx-/xps_cpus I added a numa_node field in struct netdev_queue, containing NUMA node if all cpus included in xps_cpus share same node, else -1. Signed-off-by: Eric Dumazet Cc: Ben Hutchings Cc: Tom Herbert Signed-off-by: David S. Miller --- include/linux/netdevice.h | 20 +++++++++++++++++++- net/core/dev.c | 5 +++-- net/core/net-sysfs.c | 12 +++++++++++- net/sched/sch_generic.c | 4 +++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4b0c7f3aa32b..a9ac5dc26e3c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -508,7 +508,9 @@ struct netdev_queue { #ifdef CONFIG_RPS struct kobject kobj; #endif - +#if defined(CONFIG_XPS) && defined(CONFIG_NUMA) + int numa_node; +#endif /* * write mostly part */ @@ -523,6 +525,22 @@ struct netdev_queue { u64 tx_dropped; } ____cacheline_aligned_in_smp; +static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) +{ +#if defined(CONFIG_XPS) && defined(CONFIG_NUMA) + return q->numa_node; +#else + return -1; +#endif +} + +static inline void netdev_queue_numa_node_write(struct netdev_queue *q, int node) +{ +#if defined(CONFIG_XPS) && defined(CONFIG_NUMA) + q->numa_node = node; +#endif +} + #ifdef CONFIG_RPS /* * This structure holds an RPS map which can be of variable length. The diff --git a/net/core/dev.c b/net/core/dev.c index 3259d2c323a6..cd2437495428 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5125,9 +5125,10 @@ static int netif_alloc_netdev_queues(struct net_device *dev) } dev->_tx = tx; - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { + netdev_queue_numa_node_write(&tx[i], -1); tx[i].dev = dev; - + } return 0; } diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index f85cee3d869e..85e8b5326dd6 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -913,6 +913,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue, struct xps_map *map, *new_map; struct xps_dev_maps *dev_maps, *new_dev_maps; int nonempty = 0; + int numa_node = -2; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -953,7 +954,14 @@ static ssize_t store_xps_map(struct netdev_queue *queue, pos = map_len = alloc_len = 0; need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); - +#ifdef CONFIG_NUMA + if (need_set) { + if (numa_node == -2) + numa_node = cpu_to_node(cpu); + else if (numa_node != cpu_to_node(cpu)) + numa_node = -1; + } +#endif if (need_set && pos >= map_len) { /* Need to add queue to this CPU's map */ if (map_len >= alloc_len) { @@ -1001,6 +1009,8 @@ static ssize_t store_xps_map(struct netdev_queue *queue, if (dev_maps) call_rcu(&dev_maps->rcu, xps_dev_maps_release); + netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : -1); + mutex_unlock(&xps_map_mutex); free_cpumask_var(mask); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7f0bd8952646..0918834ee4a1 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -553,7 +553,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, size = QDISC_ALIGN(sizeof(*sch)); size += ops->priv_size + (QDISC_ALIGNTO - 1); - p = kzalloc(size, GFP_KERNEL); + p = kzalloc_node(size, GFP_KERNEL, + netdev_queue_numa_node_read(dev_queue)); + if (!p) goto errout; sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); -- cgit v1.2.3-59-g8ed1b From 407d6fcbfdd011bcc2dd9e6923c5cca00abbfc6f Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 29 Nov 2010 09:47:47 +0000 Subject: gre: minor cleanups Use strcpy() rather the sprintf() for the case where name is getting generated. Fix indentation. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 897210adaa77..98769c399d9e 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -405,11 +405,11 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else - sprintf(name, "gre%%d"); + strcpy(name, "gre%d"); dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); if (!dev) - return NULL; + return NULL; dev_net_set(dev, net); -- cgit v1.2.3-59-g8ed1b From 4da6a738ffdb99b88efbe5b4c4fe521ca453640d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 29 Nov 2010 09:47:48 +0000 Subject: gre: add module alias for gre0 tunnel device If gre is built as a module the 'ip tunnel add' command would fail because the ip_gre module was not being autoloaded. Adding an alias for the gre0 device name cause dev_load() to autoload it when needed. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 98769c399d9e..258c98d5fa79 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1764,3 +1764,4 @@ module_exit(ipgre_fini); MODULE_LICENSE("GPL"); MODULE_ALIAS_RTNL_LINK("gre"); MODULE_ALIAS_RTNL_LINK("gretap"); +MODULE_ALIAS("gre0"); -- cgit v1.2.3-59-g8ed1b From 8afe7c8acd33bc52c56546e73e46e9d546269e2c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 29 Nov 2010 09:47:49 +0000 Subject: ipip: add module alias for tunl0 tunnel device If ipip is built as a module the 'ip tunnel add' command would fail because the ipip module was not being autoloaded. Adding an alias for the tunl0 device name cause dev_load() to autoload it when needed. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e70ad581398e..988f52fba54a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -913,3 +913,4 @@ static void __exit ipip_fini(void) module_init(ipip_init); module_exit(ipip_fini); MODULE_LICENSE("GPL"); +MODULE_ALIAS("tunl0"); -- cgit v1.2.3-59-g8ed1b From 1bacdbb341e8c92c58651f06727318c3d0c1c30e Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 29 Nov 2010 18:02:45 +0000 Subject: vxge: remove unnecessary printks Remove printks for ring blocks, fifo blocks, and rx doorbell mode as they clutter the dmesg output during modprobe and provide no useful information. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index a21dae1183e0..44129c3ca42a 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3922,9 +3922,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask) vxge_debug_init(VXGE_TRACE, "%s: MAC Address learning enabled", vdev->ndev->name); - vxge_debug_init(VXGE_TRACE, - "%s: Rx doorbell mode enabled", vdev->ndev->name); - for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { if (!vxge_bVALn(vpath_mask, i, 1)) continue; @@ -3937,14 +3934,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask) ((struct __vxge_hw_device *)(vdev->devh))-> config.vp_config[i].rpa_strip_vlan_tag ? "Enabled" : "Disabled"); - vxge_debug_init(VXGE_TRACE, - "%s: Ring blocks : %d", vdev->ndev->name, - ((struct __vxge_hw_device *)(vdev->devh))-> - config.vp_config[i].ring.ring_blocks); - vxge_debug_init(VXGE_TRACE, - "%s: Fifo blocks : %d", vdev->ndev->name, - ((struct __vxge_hw_device *)(vdev->devh))-> - config.vp_config[i].fifo.fifo_blocks); vxge_debug_ll_config(VXGE_TRACE, "%s: Max frags : %d", vdev->ndev->name, ((struct __vxge_hw_device *)(vdev->devh))-> -- cgit v1.2.3-59-g8ed1b From ead5d238146981f922e3848fac83825d87c518f0 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 29 Nov 2010 18:02:46 +0000 Subject: vxge: use strcpy for strings Use strncpy instead of memcpy when working on strings Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 44129c3ca42a..8a84152e320a 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3451,7 +3451,7 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); - memcpy(buf, dev->name, IFNAMSIZ); + strncpy(buf, dev->name, IFNAMSIZ); /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); -- cgit v1.2.3-59-g8ed1b From 67d5288049f46f816181f63eaa8f1371877ad8ea Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 29 Nov 2010 18:02:47 +0000 Subject: vxge: update driver version Update vxge driver version Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index f05bb2f55e73..9c93e0a17175 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h @@ -16,8 +16,8 @@ #define VXGE_VERSION_MAJOR "2" #define VXGE_VERSION_MINOR "0" -#define VXGE_VERSION_FIX "10" -#define VXGE_VERSION_BUILD "21808" +#define VXGE_VERSION_FIX "11" +#define VXGE_VERSION_BUILD "21932" #define VXGE_VERSION_FOR "k" #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) -- cgit v1.2.3-59-g8ed1b From ccd556fe334914bf2e465eb5bc480d49cd4406d7 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 10 Nov 2010 17:11:51 +0200 Subject: Bluetooth: Simplify remote features callback function logic The current remote and remote extended features event callbacks logic can be made simpler by using a label and goto statements instead of the current multiple levels of nested if statements. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 91 ++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 84093b0000b9..84302768939a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1162,33 +1162,33 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (conn) { - if (!ev->status) - memcpy(conn->features, ev->features, 8); + if (!conn) + goto unlock; - if (conn->state == BT_CONFIG) { - if (!ev->status && lmp_ssp_capable(hdev) && - lmp_ssp_capable(conn)) { - struct hci_cp_read_remote_ext_features cp; - cp.handle = ev->handle; - cp.page = 0x01; - hci_send_cmd(hdev, - HCI_OP_READ_REMOTE_EXT_FEATURES, - sizeof(cp), &cp); - } else if (!ev->status && conn->out && - conn->sec_level == BT_SECURITY_HIGH) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, + if (!ev->status) + memcpy(conn->features, ev->features, 8); + + if (conn->state != BT_CONFIG) + goto unlock; + + if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { + struct hci_cp_read_remote_ext_features cp; + cp.handle = ev->handle; + cp.page = 0x01; + hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); - } else { - conn->state = BT_CONNECTED; - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } - } + } else if (!ev->status && conn->out && + conn->sec_level == BT_SECURITY_HIGH) { + struct hci_cp_auth_requested cp; + cp.handle = ev->handle; + hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); + } else { + conn->state = BT_CONNECTED; + hci_proto_connect_cfm(conn, ev->status); + hci_conn_put(conn); } +unlock: hci_dev_unlock(hdev); } @@ -1646,32 +1646,35 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (conn) { - if (!ev->status && ev->page == 0x01) { - struct inquiry_entry *ie; + if (!conn) + goto unlock; - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) - ie->data.ssp_mode = (ev->features[0] & 0x01); + if (!ev->status && ev->page == 0x01) { + struct inquiry_entry *ie; - conn->ssp_mode = (ev->features[0] & 0x01); - } + if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) + ie->data.ssp_mode = (ev->features[0] & 0x01); - if (conn->state == BT_CONFIG) { - if (!ev->status && hdev->ssp_mode > 0 && - conn->ssp_mode > 0 && conn->out && - conn->sec_level != BT_SECURITY_SDP) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); - } else { - conn->state = BT_CONNECTED; - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } - } + conn->ssp_mode = (ev->features[0] & 0x01); + } + + if (conn->state != BT_CONFIG) + goto unlock; + + if (!ev->status && hdev->ssp_mode > 0 && + conn->ssp_mode > 0 && conn->out && + conn->sec_level != BT_SECURITY_SDP) { + struct hci_cp_auth_requested cp; + cp.handle = ev->handle; + hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, + sizeof(cp), &cp); + } else { + conn->state = BT_CONNECTED; + hci_proto_connect_cfm(conn, ev->status); + hci_conn_put(conn); } +unlock: hci_dev_unlock(hdev); } -- cgit v1.2.3-59-g8ed1b From 392599b95d76f4f3102d8614bdc1957795cd1a3a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 18 Nov 2010 22:22:28 +0200 Subject: Bluetooth: Create a unified authentication request function This patch adds a single function that's responsible for requesting authentication for outgoing connections. This is preparation for the next patch which will add automated name requests and thereby move the authentication requests to a different location. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 54 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 84302768939a..9c6d9bc1d8af 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -677,6 +677,29 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } +static int hci_request_outgoing_auth(struct hci_dev *hdev, + struct hci_conn *conn) +{ + struct hci_cp_auth_requested cp; + + if (conn->state != BT_CONFIG || !conn->out) + return 0; + + if (conn->sec_level == BT_SECURITY_SDP) + return 0; + + /* Only request authentication for SSP connections or non-SSP + * devices with sec_level HIGH */ + if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && + conn->sec_level != BT_SECURITY_HIGH) + return 0; + + cp.handle = __cpu_to_le16(conn->handle); + hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); + + return 1; +} + static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); @@ -1156,6 +1179,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; + int auth_requested; BT_DBG("%s status %d", hdev->name, ev->status); @@ -1177,12 +1201,15 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff cp.page = 0x01; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); - } else if (!ev->status && conn->out && - conn->sec_level == BT_SECURITY_HIGH) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); - } else { + goto unlock; + } + + if (!ev->status) + auth_requested = hci_request_outgoing_auth(hdev, conn); + else + auth_requested = 0; + + if (!auth_requested) { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); @@ -1640,6 +1667,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b { struct hci_ev_remote_ext_features *ev = (void *) skb->data; struct hci_conn *conn; + int auth_requested; BT_DBG("%s", hdev->name); @@ -1661,14 +1689,12 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b if (conn->state != BT_CONFIG) goto unlock; - if (!ev->status && hdev->ssp_mode > 0 && - conn->ssp_mode > 0 && conn->out && - conn->sec_level != BT_SECURITY_SDP) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); - } else { + if (!ev->status) + auth_requested = hci_request_outgoing_auth(hdev, conn); + else + auth_requested = 0; + + if (!auth_requested) { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); -- cgit v1.2.3-59-g8ed1b From 127178d24c7eb2df53b1ba2b6f6f743e88178a1b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 18 Nov 2010 22:22:29 +0200 Subject: Bluetooth: Automate remote name requests In Bluetooth there are no automatic updates of remote device names when they get changed on the remote side. Instead, it is a good idea to do a manual name request when a new connection gets created (for whatever reason) since at this point it is very cheap (no costly baseband connection creation needed just for the sake of the name request). So far userspace has been responsible for this extra name request but tighter control is needed in order not to flood Bluetooth controllers with two many commands during connection creation. It has been shown that some controllers simply fail to function correctly if they get too many (almost) simultaneous commands during connection creation. The simplest way to acheive better control of these commands is to move their sending completely to the kernel side. This patch inserts name requests into the sequence of events that the kernel performs during connection creation. It does this after the remote features have been successfully requested and before any pending authentication requests are performed. The code will work sub-optimally with userspace versions that still do the name requesting themselves (it shouldn't break anything though) so it is recommended to combine this with a userspace software version that doesn't have automated name requests. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 72 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9c6d9bc1d8af..4165895049b3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -677,11 +677,9 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } -static int hci_request_outgoing_auth(struct hci_dev *hdev, +static int hci_outgoing_auth_needed(struct hci_dev *hdev, struct hci_conn *conn) { - struct hci_cp_auth_requested cp; - if (conn->state != BT_CONFIG || !conn->out) return 0; @@ -694,15 +692,35 @@ static int hci_request_outgoing_auth(struct hci_dev *hdev, conn->sec_level != BT_SECURITY_HIGH) return 0; - cp.handle = __cpu_to_le16(conn->handle); - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); - return 1; } static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) { + struct hci_cp_remote_name_req *cp; + struct hci_conn *conn; + BT_DBG("%s status 0x%x", hdev->name, status); + + /* If successful wait for the name req complete event before + * checking for the need to do authentication */ + if (!status) + return; + + cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); + if (!cp) + return; + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); + if (conn && hci_outgoing_auth_needed(hdev, conn)) { + struct hci_cp_auth_requested cp; + cp.handle = __cpu_to_le16(conn->handle); + hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); + } + + hci_dev_unlock(hdev); } static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) @@ -1113,9 +1131,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) { + struct hci_ev_remote_name *ev = (void *) skb->data; + struct hci_conn *conn; + BT_DBG("%s", hdev->name); hci_conn_check_pending(hdev); + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); + if (conn && hci_outgoing_auth_needed(hdev, conn)) { + struct hci_cp_auth_requested cp; + cp.handle = __cpu_to_le16(conn->handle); + hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); + } + + hci_dev_unlock(hdev); } static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) @@ -1179,7 +1211,6 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; - int auth_requested; BT_DBG("%s status %d", hdev->name, ev->status); @@ -1204,12 +1235,15 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff goto unlock; } - if (!ev->status) - auth_requested = hci_request_outgoing_auth(hdev, conn); - else - auth_requested = 0; + if (!ev->status) { + struct hci_cp_remote_name_req cp; + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, &conn->dst); + cp.pscan_rep_mode = 0x02; + hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); + } - if (!auth_requested) { + if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); @@ -1667,7 +1701,6 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b { struct hci_ev_remote_ext_features *ev = (void *) skb->data; struct hci_conn *conn; - int auth_requested; BT_DBG("%s", hdev->name); @@ -1689,12 +1722,15 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b if (conn->state != BT_CONFIG) goto unlock; - if (!ev->status) - auth_requested = hci_request_outgoing_auth(hdev, conn); - else - auth_requested = 0; + if (!ev->status) { + struct hci_cp_remote_name_req cp; + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, &conn->dst); + cp.pscan_rep_mode = 0x02; + hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); + } - if (!auth_requested) { + if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); -- cgit v1.2.3-59-g8ed1b From 5520d20f68310fc158dcbbecfd5eac5cdfc5a241 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 30 Oct 2010 18:26:21 +0400 Subject: Bluetooth: bnep: fix information leak to userland Structure bnep_conninfo is copied to userland with the field "device" that has the last elements unitialized. It leads to leaking of contents of kernel stack memory. Signed-off-by: Vasiliy Kulikov Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index f10b41fb05a0..5868597534e5 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -648,6 +648,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) { + memset(ci, 0, sizeof(*ci)); memcpy(ci->dst, s->eh.h_source, ETH_ALEN); strcpy(ci->device, s->dev->name); ci->flags = s->flags; -- cgit v1.2.3-59-g8ed1b From 3185fbd9d7bb166992f072440b3329f58bf2c60a Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 30 Oct 2010 18:26:26 +0400 Subject: Bluetooth: cmtp: fix information leak to userland Structure cmtp_conninfo is copied to userland with some padding fields unitialized. It leads to leaking of contents of kernel stack memory. Signed-off-by: Vasiliy Kulikov Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index ec0a1347f933..8e5f292529ac 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -78,6 +78,7 @@ static void __cmtp_unlink_session(struct cmtp_session *session) static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci) { + memset(ci, 0, sizeof(*ci)); bacpy(&ci->bdaddr, &session->bdaddr); ci->flags = session->flags; -- cgit v1.2.3-59-g8ed1b From d31dbf6e5989b2fd9a30ec5b25436e94f009d6df Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 30 Oct 2010 18:26:31 +0400 Subject: Bluetooth: hidp: fix information leak to userland Structure hidp_conninfo is copied to userland with version, product, vendor and name fields unitialized if both session->input and session->hid are NULL. It leads to leaking of contents of kernel stack memory. Signed-off-by: Vasiliy Kulikov Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index c0ee8b3928ed..29544c21f4b5 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -107,6 +107,7 @@ static void __hidp_unlink_session(struct hidp_session *session) static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) { + memset(ci, 0, sizeof(*ci)); bacpy(&ci->bdaddr, &session->bdaddr); ci->flags = session->flags; @@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin ci->vendor = 0x0000; ci->product = 0x0000; ci->version = 0x0000; - memset(ci->name, 0, 128); if (session->input) { ci->vendor = session->input->id.vendor; -- cgit v1.2.3-59-g8ed1b From a49184c229535ebedbb659214db2d4d1d77b7c07 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 3 Nov 2010 12:32:44 +0200 Subject: Bluetooth: Check sk is not owned before freeing l2cap_conn Check that socket sk is not locked in user process before removing l2cap connection handler. lock_sock and release_sock do not hold a normal spinlock directly but instead hold the owner field. This means bh_lock_sock can still execute even if the socket is "locked". More info can be found here: http://www.linuxfoundation.org/collaborate/workgroups/networking/socketlocks krfcommd kernel thread may be preempted with l2cap tasklet which remove l2cap_conn structure. If krfcommd is in process of sending of RFCOMM reply (like "RFCOMM UA" reply to "RFCOMM DISC") then kernel crash happens. ... [ 694.175933] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 694.184936] pgd = c0004000 [ 694.187683] [00000000] *pgd=00000000 [ 694.191711] Internal error: Oops: 5 [#1] PREEMPT [ 694.196350] last sysfs file: /sys/devices/platform/hci_h4p/firmware/hci_h4p/loading [ 694.260375] CPU: 0 Not tainted (2.6.32.10 #1) [ 694.265106] PC is at l2cap_sock_sendmsg+0x43c/0x73c [l2cap] [ 694.270721] LR is at 0xd7017303 ... [ 694.525085] Backtrace: [ 694.527587] [] (l2cap_sock_sendmsg+0x0/0x73c [l2cap]) from [] (sock_sendmsg+0xb8/0xd8) [ 694.537292] [] (sock_sendmsg+0x0/0xd8) from [] (kernel_sendmsg+0x48/0x80) Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index cd8f6ea03841..4ed38272df78 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3078,6 +3078,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd break; default: + /* don't delete l2cap channel if sk is owned by user */ + if (sock_owned_by_user(sk)) { + sk->sk_state = BT_DISCONN; + l2cap_sock_clear_timer(sk); + l2cap_sock_set_timer(sk, HZ / 5); + break; + } + l2cap_chan_del(sk, ECONNREFUSED); break; } @@ -3283,6 +3291,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd sk->sk_shutdown = SHUTDOWN_MASK; + /* don't delete l2cap channel if sk is owned by user */ + if (sock_owned_by_user(sk)) { + sk->sk_state = BT_DISCONN; + l2cap_sock_clear_timer(sk); + l2cap_sock_set_timer(sk, HZ / 5); + bh_unlock_sock(sk); + return 0; + } + l2cap_chan_del(sk, ECONNRESET); bh_unlock_sock(sk); @@ -3305,6 +3322,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd if (!sk) return 0; + /* don't delete l2cap channel if sk is owned by user */ + if (sock_owned_by_user(sk)) { + sk->sk_state = BT_DISCONN; + l2cap_sock_clear_timer(sk); + l2cap_sock_set_timer(sk, HZ / 5); + bh_unlock_sock(sk); + return 0; + } + l2cap_chan_del(sk, 0); bh_unlock_sock(sk); -- cgit v1.2.3-59-g8ed1b From 940a9eea80946b64b96bd8af1fc71b30c602d057 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 3 Nov 2010 12:32:45 +0200 Subject: Bluetooth: timer check sk is not owned before freeing In timer context we might delete l2cap channel used by krfcommd. The check makes sure that sk is not owned. If sk is owned we restart timer for HZ/5. Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 4ed38272df78..18a802cc0469 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -83,6 +83,18 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); /* ---- L2CAP timers ---- */ +static void l2cap_sock_set_timer(struct sock *sk, long timeout) +{ + BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); + sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); +} + +static void l2cap_sock_clear_timer(struct sock *sk) +{ + BT_DBG("sock %p state %d", sk, sk->sk_state); + sk_stop_timer(sk, &sk->sk_timer); +} + static void l2cap_sock_timeout(unsigned long arg) { struct sock *sk = (struct sock *) arg; @@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg) bh_lock_sock(sk); + if (sock_owned_by_user(sk)) { + /* sk is owned by user. Try again later */ + l2cap_sock_set_timer(sk, HZ / 5); + bh_unlock_sock(sk); + sock_put(sk); + return; + } + if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) reason = ECONNREFUSED; else if (sk->sk_state == BT_CONNECT && @@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg) sock_put(sk); } -static void l2cap_sock_set_timer(struct sock *sk, long timeout) -{ - BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); - sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); -} - -static void l2cap_sock_clear_timer(struct sock *sk) -{ - BT_DBG("sock %p state %d", sk, sk->sk_state); - sk_stop_timer(sk, &sk->sk_timer); -} - /* ---- L2CAP channels ---- */ static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) { -- cgit v1.2.3-59-g8ed1b From cc11b9c14da4ca1c545b424dae2ae8fb1ab04063 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 22 Nov 2010 13:21:37 +0200 Subject: Bluetooth: do not use assignment in if condition Fix checkpatch errors like: "ERROR: do not use assignment in if condition" Simplify code and fix one long line. Signed-off-by: Andrei Emeltchenko Acked-by: Ville Tervo Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4165895049b3..3c1957c82b61 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -996,12 +996,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk hci_dev_lock(hdev); - if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) + ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); + if (ie) memcpy(ie->data.dev_class, ev->dev_class, 3); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { - if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { + conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); + if (!conn) { BT_ERR("No memory for new connection"); hci_dev_unlock(hdev); return; @@ -1608,7 +1610,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk if (conn && !ev->status) { struct inquiry_entry *ie; - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) { + ie = hci_inquiry_cache_lookup(hdev, &conn->dst); + if (ie) { ie->data.clock_offset = ev->clock_offset; ie->timestamp = jiffies; } @@ -1642,7 +1645,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_lock(hdev); - if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) { + ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); + if (ie) { ie->data.pscan_rep_mode = ev->pscan_rep_mode; ie->timestamp = jiffies; } @@ -1713,7 +1717,8 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b if (!ev->status && ev->page == 0x01) { struct inquiry_entry *ie; - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) + ie = hci_inquiry_cache_lookup(hdev, &conn->dst); + if (ie) ie->data.ssp_mode = (ev->features[0] & 0x01); conn->ssp_mode = (ev->features[0] & 0x01); @@ -1886,7 +1891,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_ hci_dev_lock(hdev); - if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) + ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); + if (ie) ie->data.ssp_mode = (ev->features[0] & 0x01); hci_dev_unlock(hdev); -- cgit v1.2.3-59-g8ed1b From e0f0cb56364958223f0cb1f1b0b0eecf1b8dcb95 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 1 Nov 2010 18:43:53 +0000 Subject: Bluetooth: Get rid of __l2cap_get_sock_by_psm() l2cap_get_sock_by_psm() was the only user of this function, so I merged both into l2cap_get_sock_by_psm(). The socket lock now should be hold outside of l2cap_get_sock_by_psm() once we hold and release it inside the same function now. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 18a802cc0469..12b4aa2f8fc9 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -751,11 +751,13 @@ found: /* Find socket with psm and source bdaddr. * Returns closest match. */ -static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) +static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) { struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; + read_lock(&l2cap_sk_list.lock); + sk_for_each(sk, node, &l2cap_sk_list.head) { if (state && sk->sk_state != state) continue; @@ -770,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src sk1 = sk; } } - return node ? sk : sk1; -} -/* Find socket with given address (psm, src). - * Returns locked socket */ -static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) -{ - struct sock *s; - read_lock(&l2cap_sk_list.lock); - s = __l2cap_get_sock_by_psm(state, psm, src); - if (s) - bh_lock_sock(s); read_unlock(&l2cap_sk_list.lock); - return s; + + return node ? sk : sk1; } static void l2cap_sock_destruct(struct sock *sk) @@ -2934,6 +2926,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd goto sendresp; } + bh_lock_sock(parent); + /* Check if the ACL is secure enough (if not SDP) */ if (psm != cpu_to_le16(0x0001) && !hci_conn_check_link_mode(conn->hcon)) { @@ -4464,6 +4458,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str if (!sk) goto drop; + bh_lock_sock(sk); + BT_DBG("sk %p, len %d", sk, skb->len); if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) -- cgit v1.2.3-59-g8ed1b From eeb366564be7c311b31c70821d18a43a8a57f9bc Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 1 Nov 2010 18:43:53 +0000 Subject: Bluetooth: Get rid of __rfcomm_get_sock_by_channel() rfcomm_get_sock_by_channel() was the only user of this function, so I merged both into rfcomm_get_sock_by_channel(). The socket lock now should be hold outside of rfcomm_get_sock_by_channel() once we hold and release it inside the same function now. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/sock.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index aec505f934df..0207bd6dbfc5 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) /* Find socket with channel and source bdaddr. * Returns closest match. */ -static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) +static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) { struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; + read_lock(&rfcomm_sk_list.lock); + sk_for_each(sk, node, &rfcomm_sk_list.head) { if (state && sk->sk_state != state) continue; @@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t sk1 = sk; } } - return node ? sk : sk1; -} -/* Find socket with given address (channel, src). - * Returns locked socket */ -static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) -{ - struct sock *s; - read_lock(&rfcomm_sk_list.lock); - s = __rfcomm_get_sock_by_channel(state, channel, src); - if (s) bh_lock_sock(s); read_unlock(&rfcomm_sk_list.lock); - return s; + + return node ? sk : sk1; } static void rfcomm_sock_destruct(struct sock *sk) @@ -945,6 +938,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * if (!parent) return 0; + bh_lock_sock(parent); + /* Check for backlog size */ if (sk_acceptq_is_full(parent)) { BT_DBG("backlog full %d", parent->sk_ack_backlog); -- cgit v1.2.3-59-g8ed1b From b78d7b4f204a6ba1901af36c95e10fded9816054 Mon Sep 17 00:00:00 2001 From: Anderson Lizardo Date: Mon, 29 Nov 2010 12:15:50 -0400 Subject: Bluetooth: Fix error handling for l2cap_init() create_singlethread_workqueue() may fail with errors such as -ENOMEM. If this happens, the return value is not set to a negative value and the module load will succeed. It will then crash on module unload because of a destroy_workqueue() call on a NULL pointer. Additionally, the _busy_wq workqueue is not being destroyed if any errors happen on l2cap_init(). Signed-off-by: Anderson Lizardo Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 12b4aa2f8fc9..a1c7ae88dd1f 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -4871,8 +4871,10 @@ static int __init l2cap_init(void) return err; _busy_wq = create_singlethread_workqueue("l2cap"); - if (!_busy_wq) - goto error; + if (!_busy_wq) { + proto_unregister(&l2cap_proto); + return -ENOMEM; + } err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); if (err < 0) { @@ -4900,6 +4902,7 @@ static int __init l2cap_init(void) return 0; error: + destroy_workqueue(_busy_wq); proto_unregister(&l2cap_proto); return err; } -- cgit v1.2.3-59-g8ed1b From 735cbc4784a084b7a76c43c69f9dba683bb3b48b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Dec 2010 16:58:22 +0200 Subject: Bluetooth: clean up sco code Do not use assignments in IF condition, remove extra spaces Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/sco.h | 8 ++++---- net/bluetooth/sco.c | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index e28a2a771471..ea5c6641243f 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -55,11 +55,11 @@ struct sco_conninfo { struct sco_conn { struct hci_conn *hcon; - bdaddr_t *dst; - bdaddr_t *src; - + bdaddr_t *dst; + bdaddr_t *src; + spinlock_t lock; - struct sock *sk; + struct sock *sk; unsigned int mtu; }; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 66b9e5c0523a..960c6d1637da 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include @@ -52,7 +52,7 @@ #define VERSION "0.6" -static int disable_esco = 0; +static int disable_esco; static const struct proto_ops sco_sock_ops; @@ -138,16 +138,17 @@ static inline struct sock *sco_chan_get(struct sco_conn *conn) static int sco_conn_del(struct hci_conn *hcon, int err) { - struct sco_conn *conn; + struct sco_conn *conn = hcon->sco_data; struct sock *sk; - if (!(conn = hcon->sco_data)) + if (!conn) return 0; BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); /* Kill socket */ - if ((sk = sco_chan_get(conn))) { + sk = sco_chan_get(conn); + if (sk) { bh_lock_sock(sk); sco_sock_clear_timer(sk); sco_chan_del(sk, err); @@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk) BT_DBG("%s -> %s", batostr(src), batostr(dst)); - if (!(hdev = hci_get_route(dst, src))) + hdev = hci_get_route(dst, src); + if (!hdev) return -EHOSTUNREACH; hci_dev_lock_bh(hdev); @@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen /* Set destination address and psm */ bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr); - if ((err = sco_connect(sk))) + err = sco_connect(sk); + if (err) goto done; err = bt_sock_wait_state(sk, BT_CONNECTED, @@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err) static void sco_conn_ready(struct sco_conn *conn) { - struct sock *parent, *sk; + struct sock *parent; + struct sock *sk = conn->sk; BT_DBG("conn %p", conn); sco_conn_lock(conn); - if ((sk = conn->sk)) { + if (sk) { sco_sock_clear_timer(sk); bh_lock_sock(sk); sk->sk_state = BT_CONNECTED; -- cgit v1.2.3-59-g8ed1b From 285b4e90318dcf421a00b2ac3fe8ab713f3281e3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Dec 2010 16:58:23 +0200 Subject: Bluetooth: clean up rfcomm code Remove extra spaces, assignments in if statement, zeroing static variables, extra braces. Fix includes. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/rfcomm.h | 4 ++-- net/bluetooth/rfcomm/core.c | 8 ++++---- net/bluetooth/rfcomm/sock.c | 5 +++-- net/bluetooth/rfcomm/tty.c | 28 ++++++++++++++++------------ 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 71047bc0af84..2e7875691f0a 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -105,7 +105,7 @@ struct rfcomm_hdr { u8 addr; u8 ctrl; - u8 len; // Actual size can be 2 bytes + u8 len; /* Actual size can be 2 bytes */ } __packed; struct rfcomm_cmd { @@ -228,7 +228,7 @@ struct rfcomm_dlc { /* ---- RFCOMM SEND RPN ---- */ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, u8 bit_rate, u8 data_bits, u8 stop_bits, - u8 parity, u8 flow_ctrl_settings, + u8 parity, u8 flow_ctrl_settings, u8 xon_char, u8 xoff_char, u16 param_mask); /* ---- RFCOMM DLCs (channels) ---- */ diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fa642aa652bd..c1e2bbafb549 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include @@ -51,10 +51,10 @@ #define VERSION "1.11" -static int disable_cfc = 0; +static int disable_cfc; +static int l2cap_ertm; static int channel_mtu = -1; static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; -static int l2cap_ertm = 0; static struct task_struct *rfcomm_thread; @@ -1901,7 +1901,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s) BT_DBG("%p state %ld", s, s->state); - switch(sk->sk_state) { + switch (sk->sk_state) { case BT_CONNECTED: s->state = BT_CONNECT; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 0207bd6dbfc5..66cc1f0c3df8 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include @@ -888,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) BT_DBG("sock %p, sk %p", sock, sk); - if (!sk) return 0; + if (!sk) + return 0; lock_sock(sk); if (!sk->sk_shutdown) { diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index a9b81f5dacd1..2575c2db6404 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -58,9 +58,9 @@ struct rfcomm_dev { bdaddr_t src; bdaddr_t dst; - u8 channel; + u8 channel; - uint modem_status; + uint modem_status; struct rfcomm_dlc *dlc; struct tty_struct *tty; @@ -69,7 +69,7 @@ struct rfcomm_dev { struct device *tty_dev; - atomic_t wmem_alloc; + atomic_t wmem_alloc; struct sk_buff_head pending; }; @@ -431,7 +431,8 @@ static int rfcomm_release_dev(void __user *arg) BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags); - if (!(dev = rfcomm_dev_get(req.dev_id))) + dev = rfcomm_dev_get(req.dev_id); + if (!dev) return -ENODEV; if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) { @@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg) size = sizeof(*dl) + dev_num * sizeof(*di); - if (!(dl = kmalloc(size, GFP_KERNEL))) + dl = kmalloc(size, GFP_KERNEL); + if (!dl) return -ENOMEM; di = dl->dev_info; @@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg) if (copy_from_user(&di, arg, sizeof(di))) return -EFAULT; - if (!(dev = rfcomm_dev_get(di.id))) + dev = rfcomm_dev_get(di.id); + if (!dev) return -ENODEV; di.flags = dev->flags; @@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) return; } - if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) { + tty = dev->tty; + if (!tty || !skb_queue_empty(&dev->pending)) { skb_queue_tail(&dev->pending, skb); return; } @@ -796,7 +800,8 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in memcpy(skb_put(skb, size), buf + sent, size); - if ((err = rfcomm_dlc_send(dlc, skb)) < 0) { + err = rfcomm_dlc_send(dlc, skb); + if (err < 0) { kfree_skb(skb); break; } @@ -892,7 +897,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) /* Parity on/off and when on, odd/even */ if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) || - ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) { + ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) { changes |= RFCOMM_RPN_PM_PARITY; BT_DBG("Parity change detected."); } @@ -937,11 +942,10 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) /* POSIX does not support 1.5 stop bits and RFCOMM does not * support 2 stop bits. So a request for 2 stop bits gets * translated to 1.5 stop bits */ - if (new->c_cflag & CSTOPB) { + if (new->c_cflag & CSTOPB) stop_bits = RFCOMM_RPN_STOP_15; - } else { + else stop_bits = RFCOMM_RPN_STOP_1; - } /* Handle number of data bits [5-8] */ if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE)) -- cgit v1.2.3-59-g8ed1b From 894718a6be69d8cfd191dc291b42be32a1e4851b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Dec 2010 16:58:24 +0200 Subject: Bluetooth: clean up l2cap code Do not initialize static vars to zero, macros with complex values shall be enclosed with (), remove unneeded braces. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 10 +++++----- net/bluetooth/l2cap.c | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index c819c8bf9b68..217bb91a7345 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk) return sub == pi->remote_tx_win; } -#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1 -#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8 -#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE) -#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE -#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START +#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) +#define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8) +#define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE)) +#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) +#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) void l2cap_load(void); diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index a1c7ae88dd1f..c12eccfdfe01 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -57,7 +57,7 @@ #define VERSION "2.15" -static int disable_ertm = 0; +static int disable_ertm; static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; static u8 l2cap_fixed_chan[8] = { 0x02, }; @@ -4162,11 +4162,10 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) __mod_retrans_timer(); pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { + if (pi->conn_state & L2CAP_CONN_SREJ_SENT) l2cap_send_ack(pi); - } else { + else l2cap_ertm_send(sk); - } } } -- cgit v1.2.3-59-g8ed1b From 70f23020e6d89155504b5b39f22505f4aec6fa6f Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Dec 2010 16:58:25 +0200 Subject: Bluetooth: clean up hci code Do not use assignment in IF condition, remove extra spaces, fixing typos, simplify code. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 4 +-- include/net/bluetooth/hci_core.h | 14 ++++----- net/bluetooth/hci_conn.c | 23 +++++++++----- net/bluetooth/hci_core.c | 66 +++++++++++++++++++++++++--------------- net/bluetooth/hci_event.c | 8 +++-- net/bluetooth/hci_sock.c | 17 +++++++---- 6 files changed, 82 insertions(+), 50 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e30e00834340..e9527c512345 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -489,7 +489,7 @@ struct hci_rp_read_local_name { #define HCI_OP_WRITE_PG_TIMEOUT 0x0c18 -#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a +#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a #define SCAN_DISABLED 0x00 #define SCAN_INQUIRY 0x01 #define SCAN_PAGE 0x02 @@ -874,7 +874,7 @@ struct hci_ev_si_security { struct hci_command_hdr { __le16 opcode; /* OCF & OGF */ - __u8 plen; + __u8 plen; } __packed; struct hci_event_hdr { diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ebec8c9a929d..9c08625617a1 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -44,15 +44,15 @@ struct inquiry_data { }; struct inquiry_entry { - struct inquiry_entry *next; + struct inquiry_entry *next; __u32 timestamp; struct inquiry_data data; }; struct inquiry_cache { - spinlock_t lock; + spinlock_t lock; __u32 timestamp; - struct inquiry_entry *list; + struct inquiry_entry *list; }; struct hci_conn_hash { @@ -141,7 +141,7 @@ struct hci_dev { void *driver_data; void *core_data; - atomic_t promisc; + atomic_t promisc; struct dentry *debugfs; @@ -150,7 +150,7 @@ struct hci_dev { struct rfkill *rfkill; - struct module *owner; + struct module *owner; int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); @@ -215,8 +215,8 @@ extern rwlock_t hci_dev_list_lock; extern rwlock_t hci_cb_list_lock; /* ----- Inquiry cache ----- */ -#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds -#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds +#define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ +#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ #define inquiry_cache_lock(c) spin_lock(&c->lock) #define inquiry_cache_unlock(c) spin_unlock(&c->lock) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 0b1e460fe440..6b90a4191734 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include @@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn) bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) { + ie = hci_inquiry_cache_lookup(hdev, &conn->dst); + if (ie) { if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { cp.pscan_rep_mode = ie->data.pscan_rep_mode; cp.pscan_mode = ie->data.pscan_mode; @@ -368,8 +369,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 BT_DBG("%s dst %s", hdev->name, batostr(dst)); - if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) { - if (!(acl = hci_conn_add(hdev, ACL_LINK, dst))) + acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!acl) { + acl = hci_conn_add(hdev, ACL_LINK, dst); + if (!acl) return NULL; } @@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 if (type == ACL_LINK) return acl; - if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) { - if (!(sco = hci_conn_add(hdev, type, dst))) { + sco = hci_conn_hash_lookup_ba(hdev, type, dst); + if (!sco) { + sco = hci_conn_add(hdev, type, dst); + if (!sco) { hci_conn_put(acl); return NULL; } @@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg) size = sizeof(req) + req.conn_num * sizeof(*ci); - if (!(cl = kmalloc(size, GFP_KERNEL))) + cl = kmalloc(size, GFP_KERNEL); + if (!cl) return -ENOMEM; - if (!(hdev = hci_dev_get(req.dev_id))) { + hdev = hci_dev_get(req.dev_id); + if (!hdev) { kfree(cl); return -ENODEV; } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bc2a052e518b..51c61f75a797 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include @@ -349,20 +349,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data) { struct inquiry_cache *cache = &hdev->inq_cache; - struct inquiry_entry *e; + struct inquiry_entry *ie; BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); - if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) { + ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); + if (!ie) { /* Entry not in the cache. Add new one. */ - if (!(e = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC))) + ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); + if (!ie) return; - e->next = cache->list; - cache->list = e; + + ie->next = cache->list; + cache->list = ie; } - memcpy(&e->data, data, sizeof(*data)); - e->timestamp = jiffies; + memcpy(&ie->data, data, sizeof(*data)); + ie->timestamp = jiffies; cache->timestamp = jiffies; } @@ -422,16 +425,20 @@ int hci_inquiry(void __user *arg) hci_dev_lock_bh(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || - inquiry_cache_empty(hdev) || - ir.flags & IREQ_CACHE_FLUSH) { + inquiry_cache_empty(hdev) || + ir.flags & IREQ_CACHE_FLUSH) { inquiry_cache_flush(hdev); do_inquiry = 1; } hci_dev_unlock_bh(hdev); timeo = ir.length * msecs_to_jiffies(2000); - if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0) - goto done; + + if (do_inquiry) { + err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); + if (err < 0) + goto done; + } /* for unlimited number of responses we will use buffer with 255 entries */ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; @@ -439,7 +446,8 @@ int hci_inquiry(void __user *arg) /* cache_dump can't sleep. Therefore we allocate temp buffer and then * copy it to the user space. */ - if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) { + buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL); + if (!buf) { err = -ENOMEM; goto done; } @@ -611,7 +619,8 @@ int hci_dev_close(__u16 dev) struct hci_dev *hdev; int err; - if (!(hdev = hci_dev_get(dev))) + hdev = hci_dev_get(dev); + if (!hdev) return -ENODEV; err = hci_dev_do_close(hdev); hci_dev_put(hdev); @@ -623,7 +632,8 @@ int hci_dev_reset(__u16 dev) struct hci_dev *hdev; int ret = 0; - if (!(hdev = hci_dev_get(dev))) + hdev = hci_dev_get(dev); + if (!hdev) return -ENODEV; hci_req_lock(hdev); @@ -663,7 +673,8 @@ int hci_dev_reset_stat(__u16 dev) struct hci_dev *hdev; int ret = 0; - if (!(hdev = hci_dev_get(dev))) + hdev = hci_dev_get(dev); + if (!hdev) return -ENODEV; memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); @@ -682,7 +693,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) if (copy_from_user(&dr, arg, sizeof(dr))) return -EFAULT; - if (!(hdev = hci_dev_get(dr.dev_id))) + hdev = hci_dev_get(dr.dev_id); + if (!hdev) return -ENODEV; switch (cmd) { @@ -763,7 +775,8 @@ int hci_get_dev_list(void __user *arg) size = sizeof(*dl) + dev_num * sizeof(*dr); - if (!(dl = kzalloc(size, GFP_KERNEL))) + dl = kzalloc(size, GFP_KERNEL); + if (!dl) return -ENOMEM; dr = dl->dev_req; @@ -797,7 +810,8 @@ int hci_get_dev_info(void __user *arg) if (copy_from_user(&di, arg, sizeof(di))) return -EFAULT; - if (!(hdev = hci_dev_get(di.dev_id))) + hdev = hci_dev_get(di.dev_id); + if (!hdev) return -ENODEV; strcpy(di.name, hdev->name); @@ -905,7 +919,7 @@ int hci_register_dev(struct hci_dev *hdev) hdev->sniff_max_interval = 800; hdev->sniff_min_interval = 80; - tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev); + tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev); tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev); tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev); @@ -1368,7 +1382,8 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; hci_add_acl_hdr(skb, conn->handle, flags | ACL_START); - if (!(list = skb_shinfo(skb)->frag_list)) { + list = skb_shinfo(skb)->frag_list; + if (!list) { /* Non fragmented */ BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); @@ -1609,7 +1624,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_conn_enter_active_mode(conn); /* Send to upper protocol */ - if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) { + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->recv_acldata) { hp->recv_acldata(conn, skb, flags); return; } @@ -1644,7 +1660,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) register struct hci_proto *hp; /* Send to upper protocol */ - if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) { + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->recv_scodata) { hp->recv_scodata(conn, skb); return; } @@ -1727,7 +1744,8 @@ static void hci_cmd_task(unsigned long arg) if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) { kfree_skb(hdev->sent_cmd); - if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) { + hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); + if (hdev->sent_cmd) { atomic_dec(&hdev->cmd_cnt); hci_send_frame(skb); hdev->cmd_last_tx = jiffies; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3c1957c82b61..8923b36a67a2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include @@ -1512,10 +1512,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s conn->sent -= count; if (conn->type == ACL_LINK) { - if ((hdev->acl_cnt += count) > hdev->acl_pkts) + hdev->acl_cnt += count; + if (hdev->acl_cnt > hdev->acl_pkts) hdev->acl_cnt = hdev->acl_pkts; } else { - if ((hdev->sco_cnt += count) > hdev->sco_pkts) + hdev->sco_cnt += count; + if (hdev->sco_cnt > hdev->sco_pkts) hdev->sco_cnt = hdev->sco_pkts; } } diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 83acd164d39e..b3753bad2a55 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include @@ -125,7 +125,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) continue; } - if (!(nskb = skb_clone(skb, GFP_ATOMIC))) + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) continue; /* Put type byte before the data */ @@ -370,7 +371,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le } if (haddr->hci_dev != HCI_DEV_NONE) { - if (!(hdev = hci_dev_get(haddr->hci_dev))) { + hdev = hci_dev_get(haddr->hci_dev); + if (!hdev) { err = -ENODEV; goto done; } @@ -457,7 +459,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_state == BT_CLOSED) return 0; - if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) return err; msg->msg_namelen = 0; @@ -499,7 +502,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); - if (!(hdev = hci_pi(sk)->hdev)) { + hdev = hci_pi(sk)->hdev; + if (!hdev) { err = -EBADFD; goto done; } @@ -509,7 +513,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, goto done; } - if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) + skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); + if (!skb) goto done; if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { -- cgit v1.2.3-59-g8ed1b From be21871f24b0fcd8d0d09c8090385c9cec80efa3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Dec 2010 16:58:26 +0200 Subject: Bluetooth: clean up legal text Remove extra spaces from legal text so that legal stuff looks the same for all bluetooth code. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 12 ++++++------ include/net/bluetooth/l2cap.h | 12 ++++++------ include/net/bluetooth/rfcomm.h | 14 +++++++------- include/net/bluetooth/sco.h | 12 ++++++------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e9527c512345..f3c5ed6d7bda 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1,4 +1,4 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated @@ -12,13 +12,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 217bb91a7345..7ad25ca60ec0 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -1,4 +1,4 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2009-2010 Gustavo F. Padovan @@ -14,13 +14,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 2e7875691f0a..6eac4a760c3b 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -1,5 +1,5 @@ -/* - RFCOMM implementation for Linux Bluetooth stack (BlueZ). +/* + RFCOMM implementation for Linux Bluetooth stack (BlueZ) Copyright (C) 2002 Maxim Krasnyansky Copyright (C) 2002 Marcel Holtmann @@ -11,13 +11,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index ea5c6641243f..1e35c43657c8 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -1,4 +1,4 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated @@ -12,13 +12,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ -- cgit v1.2.3-59-g8ed1b From 8790ca172a1550949804a2ad59ccea310f680c9f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Dec 2010 17:28:18 -0800 Subject: inetpeer: Kill use of inet_peer_address_t typedef. They are verboten these days. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 12 ++++++------ net/ipv4/inetpeer.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index fb8aeb1fd23f..5161bfdf5a52 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -14,18 +14,18 @@ #include #include -typedef struct { +struct inetpeer_addr { union { __be32 a4; __be32 a6[4]; }; __u16 family; -} inet_peer_address_t; +}; struct inet_peer { /* group together avl_left,avl_right,v4daddr to speedup lookups */ struct inet_peer __rcu *avl_left, *avl_right; - inet_peer_address_t daddr; + struct inetpeer_addr daddr; __u32 avl_height; struct list_head unused; __u32 dtime; /* the time of last use of not @@ -51,11 +51,11 @@ struct inet_peer { void inet_initpeers(void) __init; /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create); +struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create); static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) { - inet_peer_address_t daddr; + struct inetpeer_addr daddr; daddr.a4 = v4daddr; daddr.family = AF_INET; @@ -64,7 +64,7 @@ static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int create) { - inet_peer_address_t daddr; + struct inetpeer_addr daddr; ipv6_addr_copy((struct in6_addr *)daddr.a6, v6daddr); daddr.family = AF_INET6; diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index f95b89f3916d..d9bc85751c74 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -161,8 +161,8 @@ static void unlink_from_unused(struct inet_peer *p) } } -static int addr_compare(const inet_peer_address_t *a, - const inet_peer_address_t *b) +static int addr_compare(const struct inetpeer_addr *a, + const struct inetpeer_addr *b) { int i, n = (a->family == AF_INET ? 1 : 4); @@ -211,7 +211,7 @@ static int addr_compare(const inet_peer_address_t *a, * But every pointer we follow is guaranteed to be valid thanks to RCU. * We exit from this function if number of links exceeds PEER_MAXDEPTH */ -static struct inet_peer *lookup_rcu_bh(const inet_peer_address_t *daddr, +static struct inet_peer *lookup_rcu_bh(const struct inetpeer_addr *daddr, struct inet_peer_base *base) { struct inet_peer *u = rcu_dereference_bh(base->root); @@ -472,7 +472,7 @@ static int cleanup_once(unsigned long ttl) } /* Called with or without local BH being disabled. */ -struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create) +struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; struct inet_peer_base *base = family_to_base(AF_INET); -- cgit v1.2.3-59-g8ed1b From 4399ce402c7c837dec80bf9fb40d079b39b9265a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Dec 2010 17:29:08 -0800 Subject: inetpeer: Fix incorrect comment about inetpeer struct size. Now with ipv6 support it is no longer less than 64 bytes. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 5161bfdf5a52..599d96e74114 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -35,7 +35,6 @@ struct inet_peer { * Once inet_peer is queued for deletion (refcnt == -1), following fields * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp * We can share memory with rcu_head to keep inet_peer small - * (less then 64 bytes) */ union { struct { -- cgit v1.2.3-59-g8ed1b From ccb7c410ddc054b8c1ae780319bc98ae092d3854 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Dec 2010 18:09:13 -0800 Subject: timewait_sock: Create and use getpeer op. The only thing AF-specific about remembering the timestamp for a time-wait TCP socket is getting the peer. Abstract that behind a new timewait_sock_ops vector. Support for real IPV6 sockets is not filled in yet, but curiously this makes timewait recycling start to work for v4-mapped ipv6 sockets. Signed-off-by: David S. Miller --- include/net/tcp.h | 1 + include/net/timewait_sock.h | 8 ++++++++ net/ipv4/tcp_ipv4.c | 33 +++++++++++---------------------- net/ipv4/tcp_minisocks.c | 32 ++++++++++++++++++++++++-------- net/ipv6/tcp_ipv6.c | 26 +++++++++++++++++++------- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 3e239641d4ee..4097320caa25 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -313,6 +313,7 @@ extern void tcp_shutdown (struct sock *sk, int how); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it); +extern void *tcp_v4_tw_get_peer(struct sock *sk); extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size); diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h index 97c3b14da55d..053b3cf2c66a 100644 --- a/include/net/timewait_sock.h +++ b/include/net/timewait_sock.h @@ -21,6 +21,7 @@ struct timewait_sock_ops { int (*twsk_unique)(struct sock *sk, struct sock *sktw, void *twp); void (*twsk_destructor)(struct sock *sk); + void *(*twsk_getpeer)(struct sock *sk); }; static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) @@ -39,4 +40,11 @@ static inline void twsk_destructor(struct sock *sk) sk->sk_prot->twsk_prot->twsk_destructor(sk); } +static inline void *twsk_getpeer(struct sock *sk) +{ + if (sk->sk_prot->twsk_prot->twsk_getpeer) + return sk->sk_prot->twsk_prot->twsk_getpeer(sk); + return NULL; +} + #endif /* _TIMEWAIT_SOCK_H */ diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 0ddf819cfb5d..dd555051ec8b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1210,12 +1210,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { }; #endif -static struct timewait_sock_ops tcp_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor= tcp_twsk_destructor, -}; - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { struct tcp_extend_values tmp_ext; @@ -1783,25 +1777,20 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) } EXPORT_SYMBOL(tcp_v4_get_peer); -int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw) +void *tcp_v4_tw_get_peer(struct sock *sk) { - struct inet_peer *peer = inet_getpeer_v4(tw->tw_daddr, 1); - - if (peer) { - const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - - if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 || - ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && - peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { - peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; - peer->tcp_ts = tcptw->tw_ts_recent; - } - inet_putpeer(peer); - return 1; - } + struct inet_timewait_sock *tw = inet_twsk(sk); - return 0; + return inet_getpeer_v4(tw->tw_daddr, 1); } +EXPORT_SYMBOL(tcp_v4_tw_get_peer); + +static struct timewait_sock_ops tcp_timewait_sock_ops = { + .twsk_obj_size = sizeof(struct tcp_timewait_sock), + .twsk_unique = tcp_twsk_unique, + .twsk_destructor= tcp_twsk_destructor, + .twsk_getpeer = tcp_v4_tw_get_peer, +}; const struct inet_connection_sock_af_ops ipv4_specific = { .queue_xmit = ip_queue_xmit, diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 059082c873cf..3527b51d6159 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -78,6 +78,27 @@ static int tcp_remember_stamp(struct sock *sk) return 0; } +static int tcp_tw_remember_stamp(struct inet_timewait_sock *tw) +{ + struct sock *sk = (struct sock *) tw; + struct inet_peer *peer; + + peer = twsk_getpeer(sk); + if (peer) { + const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); + + if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 || + ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && + peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { + peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; + peer->tcp_ts = tcptw->tw_ts_recent; + } + inet_putpeer(peer); + return 1; + } + return 0; +} + static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) { if (seq == s_win) @@ -178,14 +199,9 @@ kill_with_rst: tcptw->tw_ts_recent = tmp_opt.rcv_tsval; } - /* I am shamed, but failed to make it more elegant. - * Yes, it is direct reference to IP, which is impossible - * to generalize to IPv6. Taking into account that IPv6 - * do not understand recycling in any case, it not - * a big problem in practice. --ANK */ - if (tw->tw_family == AF_INET && - tcp_death_row.sysctl_tw_recycle && tcptw->tw_ts_recent_stamp && - tcp_v4_tw_remember_stamp(tw)) + if (tcp_death_row.sysctl_tw_recycle && + tcptw->tw_ts_recent_stamp && + tcp_tw_remember_stamp(tw)) inet_twsk_schedule(tw, &tcp_death_row, tw->tw_timeout, TCP_TIMEWAIT_LEN); else diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e394d0029d8d..5f73a1808e36 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -906,12 +906,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { }; #endif -static struct timewait_sock_ops tcp6_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp6_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor= tcp_twsk_destructor, -}; - static void __tcp_v6_send_check(struct sk_buff *skb, struct in6_addr *saddr, struct in6_addr *daddr) { @@ -1818,12 +1812,30 @@ do_time_wait: goto discard_it; } -struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) +static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) +{ + /* Alas, not yet... */ + return NULL; +} + +static void *tcp_v6_tw_get_peer(struct sock *sk) { + struct inet_timewait_sock *tw = inet_twsk(sk); + + if (tw->tw_family == AF_INET) + return tcp_v4_tw_get_peer(sk); + /* Alas, not yet... */ return NULL; } +static struct timewait_sock_ops tcp6_timewait_sock_ops = { + .twsk_obj_size = sizeof(struct tcp6_timewait_sock), + .twsk_unique = tcp_twsk_unique, + .twsk_destructor= tcp_twsk_destructor, + .twsk_getpeer = tcp_v6_tw_get_peer, +}; + static const struct inet_connection_sock_af_ops ipv6_specific = { .queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, -- cgit v1.2.3-59-g8ed1b From 7cb2cea9f0f207f819db9823413fa263175b6230 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 24 Nov 2010 12:53:15 +0200 Subject: wl1271: use debugfs_remove_recursive Documentation/filesystems/debugfs.txt: """ Once upon a time, debugfs users were required to remember the dentry pointer for every debugfs file they created so that all files could be cleaned up. We live in more civilized times now, though, and debugfs users can call: void debugfs_remove_recursive(struct dentry *dentry); """ Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 181 ++++++---------------------------- drivers/net/wireless/wl12xx/wl12xx.h | 104 +------------------ 2 files changed, 32 insertions(+), 253 deletions(-) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index dd71b7d2105c..402df14e091b 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -66,19 +66,10 @@ static const struct file_operations name## _ops = { \ }; #define DEBUGFS_ADD(name, parent) \ - wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ - wl, &name## _ops); \ - if (IS_ERR(wl->debugfs.name)) { \ - ret = PTR_ERR(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - goto out; \ - } - -#define DEBUGFS_DEL(name) \ - do { \ - debugfs_remove(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - } while (0) + entry = debugfs_create_file(#name, 0400, parent, \ + wl, &name## _ops); \ + if (!entry || IS_ERR(entry)) \ + goto err; \ #define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ static ssize_t sub## _ ##name## _read(struct file *file, \ @@ -100,10 +91,7 @@ static const struct file_operations sub## _ ##name## _ops = { \ }; #define DEBUGFS_FWSTATS_ADD(sub, name) \ - DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) - -#define DEBUGFS_FWSTATS_DEL(sub, name) \ - DEBUGFS_DEL(sub## _ ##name) + DEBUGFS_ADD(sub## _ ##name, stats) static void wl1271_debugfs_update_stats(struct wl1271 *wl) { @@ -305,109 +293,16 @@ static const struct file_operations gpio_power_ops = { .llseek = default_llseek, }; -static void wl1271_debugfs_delete_files(struct wl1271 *wl) -{ - DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_DEL(rx, out_of_mem); - DEBUGFS_FWSTATS_DEL(rx, hdr_overflow); - DEBUGFS_FWSTATS_DEL(rx, hw_stuck); - DEBUGFS_FWSTATS_DEL(rx, dropped); - DEBUGFS_FWSTATS_DEL(rx, fcs_err); - DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_DEL(rx, path_reset); - DEBUGFS_FWSTATS_DEL(rx, reset_counter); - - DEBUGFS_FWSTATS_DEL(dma, rx_requested); - DEBUGFS_FWSTATS_DEL(dma, rx_errors); - DEBUGFS_FWSTATS_DEL(dma, tx_requested); - DEBUGFS_FWSTATS_DEL(dma, tx_errors); - - DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt); - DEBUGFS_FWSTATS_DEL(isr, fiqs); - DEBUGFS_FWSTATS_DEL(isr, rx_headers); - DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_DEL(isr, rx_rdys); - DEBUGFS_FWSTATS_DEL(isr, irqs); - DEBUGFS_FWSTATS_DEL(isr, tx_procs); - DEBUGFS_FWSTATS_DEL(isr, decrypt_done); - DEBUGFS_FWSTATS_DEL(isr, dma0_done); - DEBUGFS_FWSTATS_DEL(isr, dma1_done); - DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete); - DEBUGFS_FWSTATS_DEL(isr, commands); - DEBUGFS_FWSTATS_DEL(isr, rx_procs); - DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_DEL(isr, host_acknowledges); - DEBUGFS_FWSTATS_DEL(isr, pci_pm); - DEBUGFS_FWSTATS_DEL(isr, wakeups); - DEBUGFS_FWSTATS_DEL(isr, low_rssi); - - DEBUGFS_FWSTATS_DEL(wep, addr_key_count); - DEBUGFS_FWSTATS_DEL(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_DEL(wep, key_not_found); - DEBUGFS_FWSTATS_DEL(wep, decrypt_fail); - DEBUGFS_FWSTATS_DEL(wep, packets); - DEBUGFS_FWSTATS_DEL(wep, interrupt); - - DEBUGFS_FWSTATS_DEL(pwr, ps_enter); - DEBUGFS_FWSTATS_DEL(pwr, elp_enter); - DEBUGFS_FWSTATS_DEL(pwr, missing_bcns); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_host); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps); - DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps); - DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_DEL(pwr, power_save_off); - DEBUGFS_FWSTATS_DEL(pwr, enable_ps); - DEBUGFS_FWSTATS_DEL(pwr, disable_ps); - DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_DEL(mic, rx_pkts); - DEBUGFS_FWSTATS_DEL(mic, calc_failure); - - DEBUGFS_FWSTATS_DEL(aes, encrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, decrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, encrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, decrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_DEL(event, heart_beat); - DEBUGFS_FWSTATS_DEL(event, calibration); - DEBUGFS_FWSTATS_DEL(event, rx_mismatch); - DEBUGFS_FWSTATS_DEL(event, rx_mem_empty); - DEBUGFS_FWSTATS_DEL(event, rx_pool); - DEBUGFS_FWSTATS_DEL(event, oom_late); - DEBUGFS_FWSTATS_DEL(event, phy_transmit_error); - DEBUGFS_FWSTATS_DEL(event, tx_stuck); - - DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization); - DEBUGFS_FWSTATS_DEL(ps, upsd_utilization); - - DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); - - DEBUGFS_DEL(tx_queue_len); - DEBUGFS_DEL(retry_count); - DEBUGFS_DEL(excessive_retries); - - DEBUGFS_DEL(gpio_power); -} - static int wl1271_debugfs_add_files(struct wl1271 *wl) { int ret = 0; + struct dentry *entry, *stats; + + stats = debugfs_create_dir("fw-statistics", wl->rootdir); + if (!stats || IS_ERR(stats)) { + entry = stats; + goto err; + } DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); @@ -500,15 +395,19 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl) DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); - DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); - DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); - DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); + DEBUGFS_ADD(tx_queue_len, wl->rootdir); + DEBUGFS_ADD(retry_count, wl->rootdir); + DEBUGFS_ADD(excessive_retries, wl->rootdir); - DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir); + DEBUGFS_ADD(gpio_power, wl->rootdir); -out: - if (ret < 0) - wl1271_debugfs_delete_files(wl); + return 0; + +err: + if (IS_ERR(entry)) + ret = PTR_ERR(entry); + else + ret = -ENOMEM; return ret; } @@ -524,23 +423,14 @@ int wl1271_debugfs_init(struct wl1271 *wl) { int ret; - wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); + wl->rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (IS_ERR(wl->debugfs.rootdir)) { - ret = PTR_ERR(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; + if (IS_ERR(wl->rootdir)) { + ret = PTR_ERR(wl->rootdir); + wl->rootdir = NULL; goto err; } - wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics", - wl->debugfs.rootdir); - - if (IS_ERR(wl->debugfs.fw_statistics)) { - ret = PTR_ERR(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - goto err_root; - } - wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), GFP_KERNEL); @@ -563,12 +453,8 @@ err_file: wl->stats.fw_stats = NULL; err_fw: - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - -err_root: - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; + debugfs_remove_recursive(wl->rootdir); + wl->rootdir = NULL; err: return ret; @@ -576,15 +462,10 @@ err: void wl1271_debugfs_exit(struct wl1271 *wl) { - wl1271_debugfs_delete_files(wl); - kfree(wl->stats.fw_stats); wl->stats.fw_stats = NULL; - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; + debugfs_remove_recursive(wl->rootdir); + wl->rootdir = NULL; } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9f8aa695c3af..e904c72e8c8f 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -174,108 +174,6 @@ struct wl1271_stats { unsigned int excessive_retries; }; -struct wl1271_debugfs { - struct dentry *rootdir; - struct dentry *fw_statistics; - - struct dentry *tx_internal_desc_overflow; - - struct dentry *rx_out_of_mem; - struct dentry *rx_hdr_overflow; - struct dentry *rx_hw_stuck; - struct dentry *rx_dropped; - struct dentry *rx_fcs_err; - struct dentry *rx_xfr_hint_trig; - struct dentry *rx_path_reset; - struct dentry *rx_reset_counter; - - struct dentry *dma_rx_requested; - struct dentry *dma_rx_errors; - struct dentry *dma_tx_requested; - struct dentry *dma_tx_errors; - - struct dentry *isr_cmd_cmplt; - struct dentry *isr_fiqs; - struct dentry *isr_rx_headers; - struct dentry *isr_rx_mem_overflow; - struct dentry *isr_rx_rdys; - struct dentry *isr_irqs; - struct dentry *isr_tx_procs; - struct dentry *isr_decrypt_done; - struct dentry *isr_dma0_done; - struct dentry *isr_dma1_done; - struct dentry *isr_tx_exch_complete; - struct dentry *isr_commands; - struct dentry *isr_rx_procs; - struct dentry *isr_hw_pm_mode_changes; - struct dentry *isr_host_acknowledges; - struct dentry *isr_pci_pm; - struct dentry *isr_wakeups; - struct dentry *isr_low_rssi; - - struct dentry *wep_addr_key_count; - struct dentry *wep_default_key_count; - /* skipping wep.reserved */ - struct dentry *wep_key_not_found; - struct dentry *wep_decrypt_fail; - struct dentry *wep_packets; - struct dentry *wep_interrupt; - - struct dentry *pwr_ps_enter; - struct dentry *pwr_elp_enter; - struct dentry *pwr_missing_bcns; - struct dentry *pwr_wake_on_host; - struct dentry *pwr_wake_on_timer_exp; - struct dentry *pwr_tx_with_ps; - struct dentry *pwr_tx_without_ps; - struct dentry *pwr_rcvd_beacons; - struct dentry *pwr_power_save_off; - struct dentry *pwr_enable_ps; - struct dentry *pwr_disable_ps; - struct dentry *pwr_fix_tsf_ps; - /* skipping cont_miss_bcns_spread for now */ - struct dentry *pwr_rcvd_awake_beacons; - - struct dentry *mic_rx_pkts; - struct dentry *mic_calc_failure; - - struct dentry *aes_encrypt_fail; - struct dentry *aes_decrypt_fail; - struct dentry *aes_encrypt_packets; - struct dentry *aes_decrypt_packets; - struct dentry *aes_encrypt_interrupt; - struct dentry *aes_decrypt_interrupt; - - struct dentry *event_heart_beat; - struct dentry *event_calibration; - struct dentry *event_rx_mismatch; - struct dentry *event_rx_mem_empty; - struct dentry *event_rx_pool; - struct dentry *event_oom_late; - struct dentry *event_phy_transmit_error; - struct dentry *event_tx_stuck; - - struct dentry *ps_pspoll_timeouts; - struct dentry *ps_upsd_timeouts; - struct dentry *ps_upsd_max_sptime; - struct dentry *ps_upsd_max_apturn; - struct dentry *ps_pspoll_max_apturn; - struct dentry *ps_pspoll_utilization; - struct dentry *ps_upsd_utilization; - - struct dentry *rxpipe_rx_prep_beacon_drop; - struct dentry *rxpipe_descr_host_int_trig_rx_data; - struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data; - struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data; - struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; - - struct dentry *tx_queue_len; - - struct dentry *retry_count; - struct dentry *excessive_retries; - struct dentry *gpio_power; -}; - #define NUM_TX_QUEUES 4 #define NUM_RX_PKT_DESC 8 @@ -478,7 +376,7 @@ struct wl1271 { int last_rssi_event; struct wl1271_stats stats; - struct wl1271_debugfs debugfs; + struct dentry *rootdir; __le32 buffer_32; u32 buffer_cmd; -- cgit v1.2.3-59-g8ed1b From d60080ae06b98790036104f07fa897cfc151ce12 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 24 Nov 2010 12:53:16 +0200 Subject: wl1271: move wl12xx debugfs directory to under wiphy's debugfs Use per-device debugfs path, so multiple devices won't collide. in order to use wl->hw->wiphy->debugfsdir, we have to move the debugfs creation from wl1271_debugfs_init() to wl1271_register_hw(). Reported-by: Johannes Berg Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 3 ++- drivers/net/wireless/wl12xx/main.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 402df14e091b..2ac289e51484 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -423,7 +423,8 @@ int wl1271_debugfs_init(struct wl1271 *wl) { int ret; - wl->rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); + wl->rootdir = debugfs_create_dir(KBUILD_MODNAME, + wl->hw->wiphy->debugfsdir); if (IS_ERR(wl->rootdir)) { ret = PTR_ERR(wl->rootdir); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index b2432dab4b51..7fecefe8d3c1 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2602,6 +2602,8 @@ int wl1271_register_hw(struct wl1271 *wl) wl->mac80211_registered = true; + wl1271_debugfs_init(wl); + register_netdevice_notifier(&wl1271_dev_notifier); wl1271_notice("loaded"); @@ -2736,8 +2738,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void) /* Apply default driver configuration. */ wl1271_conf_init(wl); - wl1271_debugfs_init(wl); - order = get_order(WL1271_AGGR_BUFFER_SIZE); wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); if (!wl->aggr_buf) { -- cgit v1.2.3-59-g8ed1b From 43a598d5e40485fcfbebe0700077e83afd803ed5 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 30 Nov 2010 14:58:46 +0200 Subject: wl12xx: fix illegal memset if debugfs is not enabled If we try to reset the debugfs statistics when debugfs is not configured in the kernel, we're memset an illegal pointer, because it has never been allocated. So check whether we have debugfs enabled by looking into the wl->rootdir before trying to reset the fw_stats struct. Reported-by: Joerie de Gram Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 2ac289e51484..8106a6c8a1ba 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -414,6 +414,9 @@ err: void wl1271_debugfs_reset(struct wl1271 *wl) { + if (!wl->rootdir) + return; + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); wl->stats.retry_count = 0; wl->stats.excessive_retries = 0; -- cgit v1.2.3-59-g8ed1b From 870c367cf829466f315de785ac613dd94eff5c50 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 29 Nov 2010 16:24:57 +0200 Subject: wl1271: Add wl1271_load_firmware() and export some functions For the SDIO testing module we need to load the firmware but not boot it. wl1271_load_firmware() is meant to do just the firmware loading part. We also export some functions so they are usable in the testing module. Signed-off-by: Roger Quadros Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 17 ++++++++++++++++- drivers/net/wireless/wl12xx/boot.h | 1 + drivers/net/wireless/wl12xx/io.c | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 1eafb8175832..4a9f929725fd 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -467,7 +467,8 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) wl->hw_pg_ver = (s8)fuse; } -int wl1271_boot(struct wl1271 *wl) +/* uploads NVS and firmware */ +int wl1271_load_firmware(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; @@ -572,6 +573,20 @@ int wl1271_boot(struct wl1271 *wl) if (ret < 0) goto out; +out: + return ret; +} +EXPORT_SYMBOL_GPL(wl1271_load_firmware); + +int wl1271_boot(struct wl1271 *wl) +{ + int ret; + + /* upload NVS and firmware */ + ret = wl1271_load_firmware(wl); + if (ret) + return ret; + /* 10.5 start firmware */ ret = wl1271_boot_run_firmware(wl); if (ret < 0) diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index c7d771959f3a..d67dcffa31eb 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h @@ -27,6 +27,7 @@ #include "wl12xx.h" int wl1271_boot(struct wl1271 *wl); +int wl1271_load_firmware(struct wl1271 *wl); #define WL1271_NO_SUBBANDS 8 #define WL1271_NO_POWER_LEVELS 4 diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index 35c2f1aca6ba..d557f73e7c19 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c @@ -113,6 +113,7 @@ int wl1271_set_partition(struct wl1271 *wl, return 0; } +EXPORT_SYMBOL_GPL(wl1271_set_partition); void wl1271_io_reset(struct wl1271 *wl) { -- cgit v1.2.3-59-g8ed1b From 1036dc169f4cc6e5b753b1596d285d1cc3311a23 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 29 Nov 2010 12:05:53 +0200 Subject: wl12xx: Remove 11j channels from the supported channels list. Because we don't support them at this stage. Signed-off-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 7fecefe8d3c1..dc3a09319d12 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2374,14 +2374,6 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { /* 5 GHz band channels for WL1273 */ static struct ieee80211_channel wl1271_channels_5ghz[] = { - { .hw_value = 183, .center_freq = 4915}, - { .hw_value = 184, .center_freq = 4920}, - { .hw_value = 185, .center_freq = 4925}, - { .hw_value = 187, .center_freq = 4935}, - { .hw_value = 188, .center_freq = 4940}, - { .hw_value = 189, .center_freq = 4945}, - { .hw_value = 192, .center_freq = 4960}, - { .hw_value = 196, .center_freq = 4980}, { .hw_value = 7, .center_freq = 5035}, { .hw_value = 8, .center_freq = 5040}, { .hw_value = 9, .center_freq = 5045}, -- cgit v1.2.3-59-g8ed1b From 40b97c2fe96a476f1c228345f0c6a2d135a8b226 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 17 Nov 2010 14:17:53 -0800 Subject: iwlagn: fix race condition when reprogram sta During reprogram stations, do not send link quality command. uCode will crash if receive link quality command for invalid station Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-sta.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 0a67b2fa52a1..4776323b1eba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -647,6 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; + priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; spin_unlock_irqrestore(&priv->sta_lock, flags); if (active) { @@ -657,6 +658,10 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) IWL_ERR(priv, "failed to remove STA %pM (%d)\n", priv->stations[sta_id].sta.sta.addr, ret); } + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + spin_unlock_irqrestore(&priv->sta_lock, flags); + ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", @@ -777,6 +782,14 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) return -EINVAL; + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return -EINVAL; + } + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + iwl_dump_lq_cmd(priv, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); -- cgit v1.2.3-59-g8ed1b From e7cad69cdab4d6f0caadbcdd58b54214243ba98a Mon Sep 17 00:00:00 2001 From: "Grumbach, Emmanuel" Date: Thu, 18 Nov 2010 03:47:38 -0800 Subject: iwlagn: Enable PCI L1 ACTIVE state after uCode has been loaded PCI L1 Active needs to be disabled while loading the uCode so that the bus doesn't go to sleep. The enablement of L1 Active should be done after the uCode has sent the ALIVE response. The enablement of L1 Active was missing. Enabling L1 Active allows to save power if the BIOS / bus driver allows it. I measured the power consumption while not associated and idle/associated: L1 Active disabled: 39 mA = 130mW L1 Active enabled: 6 mA = 20 mW Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 0bdd2bb0bbd3..24dabcd2a36c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -531,6 +531,10 @@ int iwlagn_alive_notify(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); + /* Enable L1-Active */ + iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + iwlagn_send_wimax_coex(priv); iwlagn_set_Xtal_calib(priv); -- cgit v1.2.3-59-g8ed1b From 8b3ee29626031155c7844988ebe4321c151c03a2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 18 Nov 2010 11:41:48 -0800 Subject: iwlagn: remove structure name reference to gen2 Give the corresponding name for .cfg data structure Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 20 ++++++------ drivers/net/wireless/iwlwifi/iwl-agn.c | 58 ++++++++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 20 ++++++------ 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ec41f2725292..8018f38d5165 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -552,7 +552,7 @@ static struct iwl_bt_params iwl6000_bt_params = { .bt_sco_disable = true, }; -struct iwl_cfg iwl6000g2a_2agn_cfg = { +struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -568,7 +568,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .led_mode = IWL_LED_RF_STATE, }; -struct iwl_cfg iwl6000g2a_2abg_cfg = { +struct iwl_cfg iwl6005_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -583,7 +583,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .led_mode = IWL_LED_RF_STATE, }; -struct iwl_cfg iwl6000g2a_2bg_cfg = { +struct iwl_cfg iwl6005_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -598,7 +598,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .led_mode = IWL_LED_RF_STATE, }; -struct iwl_cfg iwl6000g2b_2agn_cfg = { +struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -618,7 +618,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; -struct iwl_cfg iwl6000g2b_2abg_cfg = { +struct iwl_cfg iwl6030_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -637,7 +637,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; -struct iwl_cfg iwl6000g2b_2bgn_cfg = { +struct iwl_cfg iwl6030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -657,7 +657,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; -struct iwl_cfg iwl6000g2b_2bg_cfg = { +struct iwl_cfg iwl6030_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -676,7 +676,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; -struct iwl_cfg iwl6000g2b_bgn_cfg = { +struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -696,7 +696,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; -struct iwl_cfg iwl6000g2b_bg_cfg = { +struct iwl_cfg iwl1030_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, @@ -782,7 +782,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .led_mode = IWL_LED_BLINK, }; -struct iwl_cfg iwl6050g2_bgn_cfg = { +struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 50cee2b5a6b7..9a6f7a03be88 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4419,31 +4419,31 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, /* 6x00 Series Gen2a */ - {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, /* 6x00 Series Gen2b */ - {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5327, iwl6000g2b_bg_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5317, iwl6000g2b_bg_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, /* 6x50 WiFi/WiMax Series */ {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, @@ -4454,12 +4454,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, /* 6x50 WiFi/WiMax Series Gen2 */ - {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6050g2_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6050g2_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6050g2_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6050g2_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6050g2_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)}, /* 1000 Series WiFi */ {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 28837a185a28..da303585f801 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -74,22 +74,22 @@ extern struct iwl_cfg iwl5100_bgn_cfg; extern struct iwl_cfg iwl5100_abg_cfg; extern struct iwl_cfg iwl5150_agn_cfg; extern struct iwl_cfg iwl5150_abg_cfg; -extern struct iwl_cfg iwl6000g2a_2agn_cfg; -extern struct iwl_cfg iwl6000g2a_2abg_cfg; -extern struct iwl_cfg iwl6000g2a_2bg_cfg; -extern struct iwl_cfg iwl6000g2b_bgn_cfg; -extern struct iwl_cfg iwl6000g2b_bg_cfg; -extern struct iwl_cfg iwl6000g2b_2agn_cfg; -extern struct iwl_cfg iwl6000g2b_2abg_cfg; -extern struct iwl_cfg iwl6000g2b_2bgn_cfg; -extern struct iwl_cfg iwl6000g2b_2bg_cfg; +extern struct iwl_cfg iwl6005_2agn_cfg; +extern struct iwl_cfg iwl6005_2abg_cfg; +extern struct iwl_cfg iwl6005_2bg_cfg; +extern struct iwl_cfg iwl1030_bgn_cfg; +extern struct iwl_cfg iwl1030_bg_cfg; +extern struct iwl_cfg iwl6030_2agn_cfg; +extern struct iwl_cfg iwl6030_2abg_cfg; +extern struct iwl_cfg iwl6030_2bgn_cfg; +extern struct iwl_cfg iwl6030_2bg_cfg; extern struct iwl_cfg iwl6000i_2agn_cfg; extern struct iwl_cfg iwl6000i_2abg_cfg; extern struct iwl_cfg iwl6000i_2bg_cfg; extern struct iwl_cfg iwl6000_3agn_cfg; extern struct iwl_cfg iwl6050_2agn_cfg; extern struct iwl_cfg iwl6050_2abg_cfg; -extern struct iwl_cfg iwl6050g2_bgn_cfg; +extern struct iwl_cfg iwl6150_bgn_cfg; extern struct iwl_cfg iwl1000_bgn_cfg; extern struct iwl_cfg iwl1000_bg_cfg; extern struct iwl_cfg iwl100_bgn_cfg; -- cgit v1.2.3-59-g8ed1b From adb90a00371a9a06a55c7b7ed7b38152f8e960c3 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 26 Nov 2010 11:09:42 -0800 Subject: iwlwifi: check for STATUS_EXIT_PENDING when send RXON command If driver is on the way down, there is no need to send RXON to uCode, check the condition before continuous the process. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index d39f449a9bb0..cac9647da71c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1784,6 +1784,9 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) int rc = 0; bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EINVAL; + if (!iwl_is_alive(priv)) return -1; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 203ee60a82b4..4865b82355d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -130,6 +130,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) lockdep_assert_held(&priv->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EINVAL; + if (!iwl_is_alive(priv)) return -EBUSY; -- cgit v1.2.3-59-g8ed1b From 9f28ebc381ca00af0f9033a29776775068344b06 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 26 Nov 2010 13:24:19 -0800 Subject: iwlagn: name change for bt_ch_announce module parameter Change the module parameter name to bt_ch_inhibition from bt_ch_announce to better describe the functionality In order to allow Bluetooth to activate a smart AFH mechanism and to maximize its available bandwidth the WiFi will request BT Core to inhibit its activity in channels that interfere with WiFi activity (and vice versa) if bt_ch_inhibition is enabled Set module parameter "bt_ch_inhibition=0" will disable the channel inhibition function Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9a6f7a03be88..32ab4a0215a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2502,7 +2502,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } - /* enable/disable bt channel announcement */ + /* enable/disable bt channel inhibition */ priv->bt_ch_announce = iwlagn_bt_ch_announce; #ifdef CONFIG_IWLWIFI_DEBUG @@ -4044,8 +4044,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? true : false; - /* enable/disable bt channel announcement */ + /* enable/disable bt channel inhibition */ priv->bt_ch_announce = iwlagn_bt_ch_announce; + IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", + (priv->bt_ch_announce) ? "On" : "Off"); if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); @@ -4588,6 +4590,6 @@ module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO); MODULE_PARM_DESC(antenna_coupling, "specify antenna coupling in dB (defualt: 0 dB)"); -module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO); -MODULE_PARM_DESC(bt_ch_announce, - "Enable BT channel announcement mode (default: enable)"); +module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO); +MODULE_PARM_DESC(bt_ch_inhibition, + "Disable BT channel inhibition (default: enable)"); -- cgit v1.2.3-59-g8ed1b From 15c054251ab84895ec043e90826612c1a3d6d4f1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Dec 2010 10:16:06 -0800 Subject: ipv6: Add rt6_get_peer() helper. To go along side ipv4's rt_get_peer(). Signed-off-by: David S. Miller --- include/net/ip6_route.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 23fed28db4bb..67d154a3f31b 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -59,6 +59,15 @@ static inline unsigned int rt6_flags2srcprefs(int flags) extern void rt6_bind_peer(struct rt6_info *rt, int create); +static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) +{ + if (rt->rt6i_peer) + return rt->rt6i_peer; + + rt6_bind_peer(rt, 0); + return rt->rt6i_peer; +} + extern void ip6_route_input(struct sk_buff *skb); extern struct dst_entry * ip6_route_output(struct net *net, -- cgit v1.2.3-59-g8ed1b From ae4694b2d3e4c0f47c0e804a68417be57e5daf85 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Dec 2010 10:59:22 -0800 Subject: ipv6: Create inet6_csk_route_req(). Brother of ipv4's inet_csk_route_req(). Signed-off-by: David S. Miller --- include/net/inet6_connection_sock.h | 3 +++ net/ipv6/inet6_connection_sock.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index aae08f686633..ff013505236b 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -25,6 +25,9 @@ struct sockaddr; extern int inet6_csk_bind_conflict(const struct sock *sk, const struct inet_bind_bucket *tb); +extern struct dst_entry* inet6_csk_route_req(struct sock *sk, + const struct request_sock *req); + extern struct request_sock *inet6_csk_search_req(const struct sock *sk, struct request_sock ***prevp, const __be16 rport, diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 861d252bd1ba..e46305d1815a 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -54,6 +54,38 @@ int inet6_csk_bind_conflict(const struct sock *sk, EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); +struct dst_entry *inet6_csk_route_req(struct sock *sk, + const struct request_sock *req) +{ + struct inet6_request_sock *treq = inet6_rsk(req); + struct ipv6_pinfo *np = inet6_sk(sk); + struct in6_addr *final_p, final; + struct dst_entry *dst; + struct flowi fl; + + memset(&fl, 0, sizeof(fl)); + fl.proto = IPPROTO_TCP; + ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); + final_p = fl6_update_dst(&fl, np->opt, &final); + ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); + fl.oif = sk->sk_bound_dev_if; + fl.mark = sk->sk_mark; + fl.fl_ip_dport = inet_rsk(req)->rmt_port; + fl.fl_ip_sport = inet_rsk(req)->loc_port; + security_req_classify_flow(req, &fl); + + if (ip6_dst_lookup(sk, &dst, &fl)) + return NULL; + + if (final_p) + ipv6_addr_copy(&fl.fl6_dst, final_p); + + if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) + return NULL; + + return dst; +} + /* * request_sock (formerly open request) hash tables. */ -- cgit v1.2.3-59-g8ed1b From 172c69a47675dc1ca9c7243c031d8d77701bccc0 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 28 Nov 2010 10:39:35 +0100 Subject: ssb: extract indexes for power tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Acked-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/ssb/ssb.h | 4 ++++ include/linux/ssb/ssb_regs.h | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index f52966305e05..158449e55044 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -406,6 +406,46 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) out->antenna_gain.ghz5.a3 = gain; } +/* Revs 4 5 and 8 have partially shared layout */ +static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in) +{ + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, + SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT); + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, + SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT); + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, + SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT); + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, + SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT); + + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, + SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT); + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, + SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT); + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, + SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT); + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, + SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT); + + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, + SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT); + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, + SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT); + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, + SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT); + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, + SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT); + + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, + SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT); + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, + SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT); + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, + SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT); + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, + SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT); +} + static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) { int i; @@ -471,6 +511,8 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, sizeof(out->antenna_gain.ghz5)); + sprom_extract_r458(out, in); + /* TODO - get remaining rev 4 stuff needed */ } @@ -561,6 +603,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, sizeof(out->antenna_gain.ghz5)); + sprom_extract_r458(out, in); + /* TODO - get remaining rev 8 stuff needed */ } diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 623b704fdc42..9659eff52ca2 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -55,6 +55,10 @@ struct ssb_sprom { u8 tri5gl; /* 5.2GHz TX isolation */ u8 tri5g; /* 5.3GHz TX isolation */ u8 tri5gh; /* 5.8GHz TX isolation */ + u8 txpid2g[4]; /* 2GHz TX power index */ + u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */ + u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */ + u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */ u8 rxpo2g; /* 2GHz RX power offset */ u8 rxpo5g; /* 5GHz RX power offset */ u8 rssisav2g; /* 2GHz RSSI params */ diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 11daf9c140e7..489f7b6d61c5 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -299,6 +299,46 @@ #define SSB_SPROM4_AGAIN2_SHIFT 0 #define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */ #define SSB_SPROM4_AGAIN3_SHIFT 8 +#define SSB_SPROM4_TXPID2G01 0x0062 /* TX Power Index 2GHz */ +#define SSB_SPROM4_TXPID2G0 0x00FF +#define SSB_SPROM4_TXPID2G0_SHIFT 0 +#define SSB_SPROM4_TXPID2G1 0xFF00 +#define SSB_SPROM4_TXPID2G1_SHIFT 8 +#define SSB_SPROM4_TXPID2G23 0x0064 /* TX Power Index 2GHz */ +#define SSB_SPROM4_TXPID2G2 0x00FF +#define SSB_SPROM4_TXPID2G2_SHIFT 0 +#define SSB_SPROM4_TXPID2G3 0xFF00 +#define SSB_SPROM4_TXPID2G3_SHIFT 8 +#define SSB_SPROM4_TXPID5G01 0x0066 /* TX Power Index 5GHz middle subband */ +#define SSB_SPROM4_TXPID5G0 0x00FF +#define SSB_SPROM4_TXPID5G0_SHIFT 0 +#define SSB_SPROM4_TXPID5G1 0xFF00 +#define SSB_SPROM4_TXPID5G1_SHIFT 8 +#define SSB_SPROM4_TXPID5G23 0x0068 /* TX Power Index 5GHz middle subband */ +#define SSB_SPROM4_TXPID5G2 0x00FF +#define SSB_SPROM4_TXPID5G2_SHIFT 0 +#define SSB_SPROM4_TXPID5G3 0xFF00 +#define SSB_SPROM4_TXPID5G3_SHIFT 8 +#define SSB_SPROM4_TXPID5GL01 0x006A /* TX Power Index 5GHz low subband */ +#define SSB_SPROM4_TXPID5GL0 0x00FF +#define SSB_SPROM4_TXPID5GL0_SHIFT 0 +#define SSB_SPROM4_TXPID5GL1 0xFF00 +#define SSB_SPROM4_TXPID5GL1_SHIFT 8 +#define SSB_SPROM4_TXPID5GL23 0x006C /* TX Power Index 5GHz low subband */ +#define SSB_SPROM4_TXPID5GL2 0x00FF +#define SSB_SPROM4_TXPID5GL2_SHIFT 0 +#define SSB_SPROM4_TXPID5GL3 0xFF00 +#define SSB_SPROM4_TXPID5GL3_SHIFT 8 +#define SSB_SPROM4_TXPID5GH01 0x006E /* TX Power Index 5GHz high subband */ +#define SSB_SPROM4_TXPID5GH0 0x00FF +#define SSB_SPROM4_TXPID5GH0_SHIFT 0 +#define SSB_SPROM4_TXPID5GH1 0xFF00 +#define SSB_SPROM4_TXPID5GH1_SHIFT 8 +#define SSB_SPROM4_TXPID5GH23 0x0070 /* TX Power Index 5GHz high subband */ +#define SSB_SPROM4_TXPID5GH2 0x00FF +#define SSB_SPROM4_TXPID5GH2_SHIFT 0 +#define SSB_SPROM4_TXPID5GH3 0xFF00 +#define SSB_SPROM4_TXPID5GH3_SHIFT 8 #define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */ #define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */ #define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ -- cgit v1.2.3-59-g8ed1b From aa3bf280dd3214db5b9e1f8cad7c5868ccbe71b7 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 28 Nov 2010 12:22:52 +0100 Subject: ssb: Add sysfs attributes to ssb devices Make it possible to read out the attributes, till now only show on dmesg, through sysfs. This patch was some time in OpenWrt. Signed-off-by: Bernhard Loos Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/ssb/main.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index c68b3dc19e11..3918d2cc5856 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -383,6 +383,35 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env) ssb_dev->id.revision); } +#define ssb_config_attr(attrib, field, format_string) \ +static ssize_t \ +attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \ +} + +ssb_config_attr(core_num, core_index, "%u\n") +ssb_config_attr(coreid, id.coreid, "0x%04x\n") +ssb_config_attr(vendor, id.vendor, "0x%04x\n") +ssb_config_attr(revision, id.revision, "%u\n") +ssb_config_attr(irq, irq, "%u\n") +static ssize_t +name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", + ssb_core_name(dev_to_ssb_dev(dev)->id.coreid)); +} + +static struct device_attribute ssb_device_attrs[] = { + __ATTR_RO(name), + __ATTR_RO(core_num), + __ATTR_RO(coreid), + __ATTR_RO(vendor), + __ATTR_RO(revision), + __ATTR_RO(irq), + __ATTR_NULL, +}; + static struct bus_type ssb_bustype = { .name = "ssb", .match = ssb_bus_match, @@ -392,6 +421,7 @@ static struct bus_type ssb_bustype = { .suspend = ssb_device_suspend, .resume = ssb_device_resume, .uevent = ssb_device_uevent, + .dev_attrs = ssb_device_attrs, }; static void ssb_buses_lock(void) -- cgit v1.2.3-59-g8ed1b From 40277cabfee7c8ef45055155895dcbef0f983c63 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 28 Nov 2010 12:59:42 +0100 Subject: b43: N-PHY: swap values for radio registers 0x3b and 0x3c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specs were updated plus we become wl compatible. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2055.c | 246 +++++++++++++++++----------------- 1 file changed, 123 insertions(+), 123 deletions(-) diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c index 10910dc4184b..44c6dea66882 100644 --- a/drivers/net/wireless/b43/radio_2055.c +++ b/drivers/net/wireless/b43/radio_2055.c @@ -304,7 +304,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 184, .freq = 4920, /* MHz */ .unk2 = 3280, - RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xEC, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07B4, 0x07B0, 0x07AC, 0x0214, 0x0215, 0x0216), @@ -312,7 +312,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 186, .freq = 4930, /* MHz */ .unk2 = 3287, - RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xED, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07B8, 0x07B4, 0x07B0, 0x0213, 0x0214, 0x0215), @@ -320,7 +320,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 188, .freq = 4940, /* MHz */ .unk2 = 3293, - RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xEE, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07BC, 0x07B8, 0x07B4, 0x0212, 0x0213, 0x0214), @@ -328,7 +328,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 190, .freq = 4950, /* MHz */ .unk2 = 3300, - RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xEF, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07C0, 0x07BC, 0x07B8, 0x0211, 0x0212, 0x0213), @@ -336,7 +336,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 192, .freq = 4960, /* MHz */ .unk2 = 3307, - RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF0, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07C4, 0x07C0, 0x07BC, 0x020F, 0x0211, 0x0212), @@ -344,7 +344,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 194, .freq = 4970, /* MHz */ .unk2 = 3313, - RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF1, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07C8, 0x07C4, 0x07C0, 0x020E, 0x020F, 0x0211), @@ -352,7 +352,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 196, .freq = 4980, /* MHz */ .unk2 = 3320, - RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF2, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07CC, 0x07C8, 0x07C4, 0x020D, 0x020E, 0x020F), @@ -360,7 +360,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 198, .freq = 4990, /* MHz */ .unk2 = 3327, - RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF3, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07D0, 0x07CC, 0x07C8, 0x020C, 0x020D, 0x020E), @@ -368,7 +368,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 200, .freq = 5000, /* MHz */ .unk2 = 3333, - RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF4, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07D4, 0x07D0, 0x07CC, 0x020B, 0x020C, 0x020D), @@ -376,7 +376,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 202, .freq = 5010, /* MHz */ .unk2 = 3340, - RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF5, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07D8, 0x07D4, 0x07D0, 0x020A, 0x020B, 0x020C), @@ -384,7 +384,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 204, .freq = 5020, /* MHz */ .unk2 = 3347, - RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF6, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07DC, 0x07D8, 0x07D4, 0x0209, 0x020A, 0x020B), @@ -392,7 +392,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 206, .freq = 5030, /* MHz */ .unk2 = 3353, - RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF7, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07E0, 0x07DC, 0x07D8, 0x0208, 0x0209, 0x020A), @@ -400,7 +400,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 208, .freq = 5040, /* MHz */ .unk2 = 3360, - RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF8, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07E4, 0x07E0, 0x07DC, 0x0207, 0x0208, 0x0209), @@ -408,7 +408,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 210, .freq = 5050, /* MHz */ .unk2 = 3367, - RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xF9, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), PHYREGS(0x07E8, 0x07E4, 0x07E0, 0x0206, 0x0207, 0x0208), @@ -416,7 +416,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 212, .freq = 5060, /* MHz */ .unk2 = 3373, - RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFA, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), PHYREGS(0x07EC, 0x07E8, 0x07E4, 0x0205, 0x0206, 0x0207), @@ -424,7 +424,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 214, .freq = 5070, /* MHz */ .unk2 = 3380, - RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFB, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), PHYREGS(0x07F0, 0x07EC, 0x07E8, 0x0204, 0x0205, 0x0206), @@ -432,7 +432,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 216, .freq = 5080, /* MHz */ .unk2 = 3387, - RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFC, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), PHYREGS(0x07F4, 0x07F0, 0x07EC, 0x0203, 0x0204, 0x0205), @@ -440,7 +440,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 218, .freq = 5090, /* MHz */ .unk2 = 3393, - RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFD, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), PHYREGS(0x07F8, 0x07F4, 0x07F0, 0x0202, 0x0203, 0x0204), @@ -448,7 +448,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 220, .freq = 5100, /* MHz */ .unk2 = 3400, - RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFE, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), PHYREGS(0x07FC, 0x07F8, 0x07F4, 0x0201, 0x0202, 0x0203), @@ -456,7 +456,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 222, .freq = 5110, /* MHz */ .unk2 = 3407, - RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0xFF, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A, 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), PHYREGS(0x0800, 0x07FC, 0x07F8, 0x0200, 0x0201, 0x0202), @@ -464,7 +464,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 224, .freq = 5120, /* MHz */ .unk2 = 3413, - RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x00, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A, 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), PHYREGS(0x0804, 0x0800, 0x07FC, 0x01FF, 0x0200, 0x0201), @@ -472,7 +472,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 226, .freq = 5130, /* MHz */ .unk2 = 3420, - RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x01, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A, 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), PHYREGS(0x0808, 0x0804, 0x0800, 0x01FE, 0x01FF, 0x0200), @@ -488,7 +488,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 32, .freq = 5160, /* MHz */ .unk2 = 3440, - RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x04, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), PHYREGS(0x0814, 0x0810, 0x080C, 0x01FB, 0x01FC, 0x01FD), @@ -496,7 +496,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 34, .freq = 5170, /* MHz */ .unk2 = 3447, - RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x05, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), PHYREGS(0x0818, 0x0814, 0x0810, 0x01FA, 0x01FB, 0x01FC), @@ -504,7 +504,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 36, .freq = 5180, /* MHz */ .unk2 = 3453, - RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x06, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), PHYREGS(0x081C, 0x0818, 0x0814, 0x01F9, 0x01FA, 0x01FB), @@ -512,7 +512,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 38, .freq = 5190, /* MHz */ .unk2 = 3460, - RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x07, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A, 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), PHYREGS(0x0820, 0x081C, 0x0818, 0x01F8, 0x01F9, 0x01FA), @@ -520,7 +520,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 40, .freq = 5200, /* MHz */ .unk2 = 3467, - RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x08, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), PHYREGS(0x0824, 0x0820, 0x081C, 0x01F7, 0x01F8, 0x01F9), @@ -528,7 +528,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 42, .freq = 5210, /* MHz */ .unk2 = 3473, - RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x09, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), PHYREGS(0x0828, 0x0824, 0x0820, 0x01F6, 0x01F7, 0x01F8), @@ -536,7 +536,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 44, .freq = 5220, /* MHz */ .unk2 = 3480, - RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0A, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), PHYREGS(0x082C, 0x0828, 0x0824, 0x01F5, 0x01F6, 0x01F7), @@ -544,7 +544,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 46, .freq = 5230, /* MHz */ .unk2 = 3487, - RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0B, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A, 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), PHYREGS(0x0830, 0x082C, 0x0828, 0x01F4, 0x01F5, 0x01F6), @@ -552,7 +552,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 48, .freq = 5240, /* MHz */ .unk2 = 3493, - RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0C, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), PHYREGS(0x0834, 0x0830, 0x082C, 0x01F3, 0x01F4, 0x01F5), @@ -560,7 +560,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 50, .freq = 5250, /* MHz */ .unk2 = 3500, - RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0D, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), PHYREGS(0x0838, 0x0834, 0x0830, 0x01F2, 0x01F3, 0x01F4), @@ -568,7 +568,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 52, .freq = 5260, /* MHz */ .unk2 = 3507, - RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0E, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), PHYREGS(0x083C, 0x0838, 0x0834, 0x01F1, 0x01F2, 0x01F3), @@ -576,7 +576,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 54, .freq = 5270, /* MHz */ .unk2 = 3513, - RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x0F, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A, 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), PHYREGS(0x0840, 0x083C, 0x0838, 0x01F0, 0x01F1, 0x01F2), @@ -584,7 +584,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 56, .freq = 5280, /* MHz */ .unk2 = 3520, - RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x10, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), PHYREGS(0x0844, 0x0840, 0x083C, 0x01F0, 0x01F0, 0x01F1), @@ -592,7 +592,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 58, .freq = 5290, /* MHz */ .unk2 = 3527, - RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x11, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), PHYREGS(0x0848, 0x0844, 0x0840, 0x01EF, 0x01F0, 0x01F0), @@ -600,7 +600,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 60, .freq = 5300, /* MHz */ .unk2 = 3533, - RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x12, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), PHYREGS(0x084C, 0x0848, 0x0844, 0x01EE, 0x01EF, 0x01F0), @@ -608,7 +608,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 62, .freq = 5310, /* MHz */ .unk2 = 3540, - RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x13, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A, 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), PHYREGS(0x0850, 0x084C, 0x0848, 0x01ED, 0x01EE, 0x01EF), @@ -616,7 +616,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 64, .freq = 5320, /* MHz */ .unk2 = 3547, - RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x14, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), PHYREGS(0x0854, 0x0850, 0x084C, 0x01EC, 0x01ED, 0x01EE), @@ -624,7 +624,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 66, .freq = 5330, /* MHz */ .unk2 = 3553, - RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x15, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), PHYREGS(0x0858, 0x0854, 0x0850, 0x01EB, 0x01EC, 0x01ED), @@ -632,7 +632,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 68, .freq = 5340, /* MHz */ .unk2 = 3560, - RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x16, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), PHYREGS(0x085C, 0x0858, 0x0854, 0x01EA, 0x01EB, 0x01EC), @@ -640,7 +640,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 70, .freq = 5350, /* MHz */ .unk2 = 3567, - RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x17, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A, 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), PHYREGS(0x0860, 0x085C, 0x0858, 0x01E9, 0x01EA, 0x01EB), @@ -648,7 +648,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 72, .freq = 5360, /* MHz */ .unk2 = 3573, - RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x18, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), PHYREGS(0x0864, 0x0860, 0x085C, 0x01E8, 0x01E9, 0x01EA), @@ -656,7 +656,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 74, .freq = 5370, /* MHz */ .unk2 = 3580, - RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x19, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), PHYREGS(0x0868, 0x0864, 0x0860, 0x01E7, 0x01E8, 0x01E9), @@ -664,7 +664,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 76, .freq = 5380, /* MHz */ .unk2 = 3587, - RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1A, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), PHYREGS(0x086C, 0x0868, 0x0864, 0x01E6, 0x01E7, 0x01E8), @@ -672,7 +672,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 78, .freq = 5390, /* MHz */ .unk2 = 3593, - RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1B, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A, 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), PHYREGS(0x0870, 0x086C, 0x0868, 0x01E5, 0x01E6, 0x01E7), @@ -680,7 +680,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 80, .freq = 5400, /* MHz */ .unk2 = 3600, - RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1C, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), PHYREGS(0x0874, 0x0870, 0x086C, 0x01E5, 0x01E5, 0x01E6), @@ -688,7 +688,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 82, .freq = 5410, /* MHz */ .unk2 = 3607, - RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1D, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), PHYREGS(0x0878, 0x0874, 0x0870, 0x01E4, 0x01E5, 0x01E5), @@ -696,7 +696,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 84, .freq = 5420, /* MHz */ .unk2 = 3613, - RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1E, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), PHYREGS(0x087C, 0x0878, 0x0874, 0x01E3, 0x01E4, 0x01E5), @@ -704,7 +704,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 86, .freq = 5430, /* MHz */ .unk2 = 3620, - RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x1F, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A, 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), PHYREGS(0x0880, 0x087C, 0x0878, 0x01E2, 0x01E3, 0x01E4), @@ -712,7 +712,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 88, .freq = 5440, /* MHz */ .unk2 = 3627, - RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x20, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), PHYREGS(0x0884, 0x0880, 0x087C, 0x01E1, 0x01E2, 0x01E3), @@ -720,7 +720,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 90, .freq = 5450, /* MHz */ .unk2 = 3633, - RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x21, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), PHYREGS(0x0888, 0x0884, 0x0880, 0x01E0, 0x01E1, 0x01E2), @@ -728,7 +728,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 92, .freq = 5460, /* MHz */ .unk2 = 3640, - RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x22, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), PHYREGS(0x088C, 0x0888, 0x0884, 0x01DF, 0x01E0, 0x01E1), @@ -736,7 +736,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 94, .freq = 5470, /* MHz */ .unk2 = 3647, - RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x23, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A, 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), PHYREGS(0x0890, 0x088C, 0x0888, 0x01DE, 0x01DF, 0x01E0), @@ -744,7 +744,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 96, .freq = 5480, /* MHz */ .unk2 = 3653, - RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x24, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), PHYREGS(0x0894, 0x0890, 0x088C, 0x01DD, 0x01DE, 0x01DF), @@ -752,7 +752,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 98, .freq = 5490, /* MHz */ .unk2 = 3660, - RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x25, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), PHYREGS(0x0898, 0x0894, 0x0890, 0x01DD, 0x01DD, 0x01DE), @@ -760,7 +760,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 100, .freq = 5500, /* MHz */ .unk2 = 3667, - RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x26, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), PHYREGS(0x089C, 0x0898, 0x0894, 0x01DC, 0x01DD, 0x01DD), @@ -768,7 +768,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 102, .freq = 5510, /* MHz */ .unk2 = 3673, - RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x27, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A, 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), PHYREGS(0x08A0, 0x089C, 0x0898, 0x01DB, 0x01DC, 0x01DD), @@ -776,7 +776,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 104, .freq = 5520, /* MHz */ .unk2 = 3680, - RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x28, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), PHYREGS(0x08A4, 0x08A0, 0x089C, 0x01DA, 0x01DB, 0x01DC), @@ -784,7 +784,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 106, .freq = 5530, /* MHz */ .unk2 = 3687, - RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x29, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), PHYREGS(0x08A8, 0x08A4, 0x08A0, 0x01D9, 0x01DA, 0x01DB), @@ -792,7 +792,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 108, .freq = 5540, /* MHz */ .unk2 = 3693, - RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2A, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), PHYREGS(0x08AC, 0x08A8, 0x08A4, 0x01D8, 0x01D9, 0x01DA), @@ -800,7 +800,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 110, .freq = 5550, /* MHz */ .unk2 = 3700, - RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2B, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A, 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), PHYREGS(0x08B0, 0x08AC, 0x08A8, 0x01D7, 0x01D8, 0x01D9), @@ -808,7 +808,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 112, .freq = 5560, /* MHz */ .unk2 = 3707, - RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2C, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08B4, 0x08B0, 0x08AC, 0x01D7, 0x01D7, 0x01D8), @@ -816,7 +816,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 114, .freq = 5570, /* MHz */ .unk2 = 3713, - RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2D, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08B8, 0x08B4, 0x08B0, 0x01D6, 0x01D7, 0x01D7), @@ -824,7 +824,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 116, .freq = 5580, /* MHz */ .unk2 = 3720, - RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2E, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08BC, 0x08B8, 0x08B4, 0x01D5, 0x01D6, 0x01D7), @@ -832,7 +832,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 118, .freq = 5590, /* MHz */ .unk2 = 3727, - RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x2F, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A, 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08C0, 0x08BC, 0x08B8, 0x01D4, 0x01D5, 0x01D6), @@ -840,7 +840,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 120, .freq = 5600, /* MHz */ .unk2 = 3733, - RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x30, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08C4, 0x08C0, 0x08BC, 0x01D3, 0x01D4, 0x01D5), @@ -848,7 +848,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 122, .freq = 5610, /* MHz */ .unk2 = 3740, - RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x31, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), PHYREGS(0x08C8, 0x08C4, 0x08C0, 0x01D2, 0x01D3, 0x01D4), @@ -856,7 +856,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 124, .freq = 5620, /* MHz */ .unk2 = 3747, - RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x32, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08CC, 0x08C8, 0x08C4, 0x01D2, 0x01D2, 0x01D3), @@ -864,7 +864,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 126, .freq = 5630, /* MHz */ .unk2 = 3753, - RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x33, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A, 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08D0, 0x08CC, 0x08C8, 0x01D1, 0x01D2, 0x01D2), @@ -872,7 +872,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 128, .freq = 5640, /* MHz */ .unk2 = 3760, - RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x34, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08D4, 0x08D0, 0x08CC, 0x01D0, 0x01D1, 0x01D2), @@ -880,7 +880,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 130, .freq = 5650, /* MHz */ .unk2 = 3767, - RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x35, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08D8, 0x08D4, 0x08D0, 0x01CF, 0x01D0, 0x01D1), @@ -888,7 +888,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 132, .freq = 5660, /* MHz */ .unk2 = 3773, - RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x36, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08DC, 0x08D8, 0x08D4, 0x01CE, 0x01CF, 0x01D0), @@ -896,7 +896,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 134, .freq = 5670, /* MHz */ .unk2 = 3780, - RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x37, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08E0, 0x08DC, 0x08D8, 0x01CE, 0x01CE, 0x01CF), @@ -904,7 +904,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 136, .freq = 5680, /* MHz */ .unk2 = 3787, - RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x38, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08E4, 0x08E0, 0x08DC, 0x01CD, 0x01CE, 0x01CE), @@ -912,7 +912,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 138, .freq = 5690, /* MHz */ .unk2 = 3793, - RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x39, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08E8, 0x08E4, 0x08E0, 0x01CC, 0x01CD, 0x01CE), @@ -920,7 +920,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 140, .freq = 5700, /* MHz */ .unk2 = 3800, - RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3A, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08EC, 0x08E8, 0x08E4, 0x01CB, 0x01CC, 0x01CD), @@ -928,7 +928,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 142, .freq = 5710, /* MHz */ .unk2 = 3807, - RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3B, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08F0, 0x08EC, 0x08E8, 0x01CA, 0x01CB, 0x01CC), @@ -936,7 +936,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 144, .freq = 5720, /* MHz */ .unk2 = 3813, - RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3C, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08F4, 0x08F0, 0x08EC, 0x01C9, 0x01CA, 0x01CB), @@ -944,7 +944,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 145, .freq = 5725, /* MHz */ .unk2 = 3817, - RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, + RADIOREGS(0x72, 0x79, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08F6, 0x08F2, 0x08EE, 0x01C9, 0x01CA, 0x01CB), @@ -952,7 +952,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 146, .freq = 5730, /* MHz */ .unk2 = 3820, - RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3D, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08F8, 0x08F4, 0x08F0, 0x01C9, 0x01C9, 0x01CA), @@ -960,7 +960,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 147, .freq = 5735, /* MHz */ .unk2 = 3823, - RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, + RADIOREGS(0x72, 0x7B, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08FA, 0x08F6, 0x08F2, 0x01C8, 0x01C9, 0x01CA), @@ -968,7 +968,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 148, .freq = 5740, /* MHz */ .unk2 = 3827, - RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3E, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08FC, 0x08F8, 0x08F4, 0x01C8, 0x01C9, 0x01C9), @@ -976,7 +976,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 149, .freq = 5745, /* MHz */ .unk2 = 3830, - RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x7D, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x08FE, 0x08FA, 0x08F6, 0x01C8, 0x01C8, 0x01C9), @@ -984,7 +984,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 150, .freq = 5750, /* MHz */ .unk2 = 3833, - RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x3F, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0900, 0x08FC, 0x08F8, 0x01C7, 0x01C8, 0x01C9), @@ -992,7 +992,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 151, .freq = 5755, /* MHz */ .unk2 = 3837, - RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x7F, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0902, 0x08FE, 0x08FA, 0x01C7, 0x01C8, 0x01C8), @@ -1000,7 +1000,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 152, .freq = 5760, /* MHz */ .unk2 = 3840, - RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x40, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0904, 0x0900, 0x08FC, 0x01C6, 0x01C7, 0x01C8), @@ -1008,7 +1008,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 153, .freq = 5765, /* MHz */ .unk2 = 3843, - RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x81, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0906, 0x0902, 0x08FE, 0x01C6, 0x01C7, 0x01C8), @@ -1016,7 +1016,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 154, .freq = 5770, /* MHz */ .unk2 = 3847, - RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x41, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0908, 0x0904, 0x0900, 0x01C6, 0x01C6, 0x01C7), @@ -1024,7 +1024,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 155, .freq = 5775, /* MHz */ .unk2 = 3850, - RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x83, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x090A, 0x0906, 0x0902, 0x01C5, 0x01C6, 0x01C7), @@ -1032,7 +1032,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 156, .freq = 5780, /* MHz */ .unk2 = 3853, - RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x42, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x090C, 0x0908, 0x0904, 0x01C5, 0x01C6, 0x01C6), @@ -1040,7 +1040,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 157, .freq = 5785, /* MHz */ .unk2 = 3857, - RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x85, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x090E, 0x090A, 0x0906, 0x01C4, 0x01C5, 0x01C6), @@ -1048,7 +1048,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 158, .freq = 5790, /* MHz */ .unk2 = 3860, - RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x43, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0910, 0x090C, 0x0908, 0x01C4, 0x01C5, 0x01C6), @@ -1056,7 +1056,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 159, .freq = 5795, /* MHz */ .unk2 = 3863, - RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x87, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0912, 0x090E, 0x090A, 0x01C4, 0x01C4, 0x01C5), @@ -1064,7 +1064,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 160, .freq = 5800, /* MHz */ .unk2 = 3867, - RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x44, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0914, 0x0910, 0x090C, 0x01C3, 0x01C4, 0x01C5), @@ -1072,7 +1072,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 161, .freq = 5805, /* MHz */ .unk2 = 3870, - RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x89, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0916, 0x0912, 0x090E, 0x01C3, 0x01C4, 0x01C4), @@ -1080,7 +1080,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 162, .freq = 5810, /* MHz */ .unk2 = 3873, - RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x45, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0918, 0x0914, 0x0910, 0x01C2, 0x01C3, 0x01C4), @@ -1088,7 +1088,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 163, .freq = 5815, /* MHz */ .unk2 = 3877, - RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x8B, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x091A, 0x0916, 0x0912, 0x01C2, 0x01C3, 0x01C4), @@ -1096,7 +1096,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 164, .freq = 5820, /* MHz */ .unk2 = 3880, - RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x46, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x091C, 0x0918, 0x0914, 0x01C2, 0x01C2, 0x01C3), @@ -1104,7 +1104,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 165, .freq = 5825, /* MHz */ .unk2 = 3883, - RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, + RADIOREGS(0x72, 0x8D, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x091E, 0x091A, 0x0916, 0x01C1, 0x01C2, 0x01C3), @@ -1112,7 +1112,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 166, .freq = 5830, /* MHz */ .unk2 = 3887, - RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x47, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0920, 0x091C, 0x0918, 0x01C1, 0x01C2, 0x01C2), @@ -1120,7 +1120,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 168, .freq = 5840, /* MHz */ .unk2 = 3893, - RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, + RADIOREGS(0x71, 0x48, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0924, 0x0920, 0x091C, 0x01C0, 0x01C1, 0x01C2), @@ -1128,7 +1128,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 170, .freq = 5850, /* MHz */ .unk2 = 3900, - RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x49, 0x02, 0x01, 0xE0, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0928, 0x0924, 0x0920, 0x01BF, 0x01C0, 0x01C1), @@ -1136,7 +1136,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 172, .freq = 5860, /* MHz */ .unk2 = 3907, - RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4A, 0x02, 0x01, 0xDE, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x092C, 0x0928, 0x0924, 0x01BF, 0x01BF, 0x01C0), @@ -1144,7 +1144,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 174, .freq = 5870, /* MHz */ .unk2 = 3913, - RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4B, 0x02, 0x00, 0xDB, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0930, 0x092C, 0x0928, 0x01BE, 0x01BF, 0x01BF), @@ -1152,7 +1152,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 176, .freq = 5880, /* MHz */ .unk2 = 3920, - RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4C, 0x02, 0x00, 0xD8, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0934, 0x0930, 0x092C, 0x01BD, 0x01BE, 0x01BF), @@ -1160,7 +1160,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 178, .freq = 5890, /* MHz */ .unk2 = 3927, - RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4D, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0938, 0x0934, 0x0930, 0x01BC, 0x01BD, 0x01BE), @@ -1168,7 +1168,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 180, .freq = 5900, /* MHz */ .unk2 = 3933, - RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4E, 0x02, 0x00, 0xD3, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x093C, 0x0938, 0x0934, 0x01BC, 0x01BC, 0x01BD), @@ -1176,7 +1176,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 182, .freq = 5910, /* MHz */ .unk2 = 3940, - RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, + RADIOREGS(0x71, 0x4F, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), PHYREGS(0x0940, 0x093C, 0x0938, 0x01BB, 0x01BC, 0x01BC), @@ -1184,7 +1184,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 1, .freq = 2412, /* MHz */ .unk2 = 3216, - RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x6C, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), PHYREGS(0x03C9, 0x03C5, 0x03C1, 0x043A, 0x043F, 0x0443), @@ -1192,7 +1192,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 2, .freq = 2417, /* MHz */ .unk2 = 3223, - RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x71, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), PHYREGS(0x03CB, 0x03C7, 0x03C3, 0x0438, 0x043D, 0x0441), @@ -1200,7 +1200,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 3, .freq = 2422, /* MHz */ .unk2 = 3229, - RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x76, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), PHYREGS(0x03CD, 0x03C9, 0x03C5, 0x0436, 0x043A, 0x043F), @@ -1208,7 +1208,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 4, .freq = 2427, /* MHz */ .unk2 = 3236, - RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x7B, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), PHYREGS(0x03CF, 0x03CB, 0x03C7, 0x0434, 0x0438, 0x043D), @@ -1216,7 +1216,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 5, .freq = 2432, /* MHz */ .unk2 = 3243, - RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x80, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), PHYREGS(0x03D1, 0x03CD, 0x03C9, 0x0431, 0x0436, 0x043A), @@ -1224,7 +1224,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 6, .freq = 2437, /* MHz */ .unk2 = 3249, - RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x85, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), PHYREGS(0x03D3, 0x03CF, 0x03CB, 0x042F, 0x0434, 0x0438), @@ -1232,7 +1232,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 7, .freq = 2442, /* MHz */ .unk2 = 3256, - RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x8A, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), PHYREGS(0x03D5, 0x03D1, 0x03CD, 0x042D, 0x0431, 0x0436), @@ -1240,7 +1240,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 8, .freq = 2447, /* MHz */ .unk2 = 3263, - RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x8F, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), PHYREGS(0x03D7, 0x03D3, 0x03CF, 0x042B, 0x042F, 0x0434), @@ -1248,7 +1248,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 9, .freq = 2452, /* MHz */ .unk2 = 3269, - RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x94, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), PHYREGS(0x03D9, 0x03D5, 0x03D1, 0x0429, 0x042D, 0x0431), @@ -1256,7 +1256,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 10, .freq = 2457, /* MHz */ .unk2 = 3276, - RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x99, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), PHYREGS(0x03DB, 0x03D7, 0x03D3, 0x0427, 0x042B, 0x042F), @@ -1264,7 +1264,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 11, .freq = 2462, /* MHz */ .unk2 = 3283, - RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0x9E, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), PHYREGS(0x03DD, 0x03D9, 0x03D5, 0x0424, 0x0429, 0x042D), @@ -1272,7 +1272,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 12, .freq = 2467, /* MHz */ .unk2 = 3289, - RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0xA3, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), PHYREGS(0x03DF, 0x03DB, 0x03D7, 0x0422, 0x0427, 0x042B), @@ -1280,7 +1280,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 13, .freq = 2472, /* MHz */ .unk2 = 3296, - RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0xA8, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), PHYREGS(0x03E1, 0x03DD, 0x03D9, 0x0420, 0x0424, 0x0429), @@ -1288,7 +1288,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { .channel = 14, .freq = 2484, /* MHz */ .unk2 = 3312, - RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, + RADIOREGS(0x73, 0xB4, 0x09, 0x0F, 0xFF, 0x01, 0x07, 0x15, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), PHYREGS(0x03E6, 0x03E2, 0x03DE, 0x041B, 0x041F, 0x0424), -- cgit v1.2.3-59-g8ed1b From 161d540c8ef31e5adbced3248873024476e2c26f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 28 Nov 2010 12:59:43 +0100 Subject: b43: N-PHY: implement very basic TX power control management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 159 +++++++++++++++++++++++++++++++++++++-- drivers/net/wireless/b43/phy_n.h | 2 +- 2 files changed, 153 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9769483156e7..8690551f087c 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -67,6 +67,8 @@ enum b43_nphy_rf_sequence { B43_RFSEQ_UPDATE_GAINU, }; +static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, + bool enable); static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, u8 *events, u8 *delays, u8 length); static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, @@ -145,9 +147,153 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev, b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ +static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) +{ + struct b43_phy_n *nphy = dev->phy.n; + u8 i; + u16 tmp; + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + nphy->txpwrctrl = enable; + if (!enable) { + if (dev->phy.rev >= 3) + ; /* TODO */ + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840); + for (i = 0; i < 84; i++) + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40); + for (i = 0; i < 84; i++) + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0); + + tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN; + if (dev->phy.rev >= 3) + tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN; + b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp); + + if (dev->phy.rev >= 3) { + b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100); + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100); + } else { + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000); + } + + if (dev->phy.rev == 2) + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, + ~B43_NPHY_BPHY_CTL3_SCALE, 0x53); + else if (dev->phy.rev < 2) + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, + ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A); + + if (dev->phy.rev < 2 && 0) + ; /* TODO */ + } else { + b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n"); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 0); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) { - //TODO + struct b43_phy_n *nphy = dev->phy.n; + struct ssb_sprom *sprom = &(dev->dev->bus->sprom); + + u8 txpi[2], bbmult, i; + u16 tmp, radio_gain, dac_gain; + u16 freq = dev->phy.channel_freq; + u32 txgain; + /* u32 gaintbl; rev3+ */ + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + if (dev->phy.rev >= 3) { + txpi[0] = 40; + txpi[1] = 40; + } else if (sprom->revision < 4) { + txpi[0] = 72; + txpi[1] = 72; + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + txpi[0] = sprom->txpid2g[0]; + txpi[1] = sprom->txpid2g[1]; + } else if (freq >= 4900 && freq < 5100) { + txpi[0] = sprom->txpid5gl[0]; + txpi[1] = sprom->txpid5gl[1]; + } else if (freq >= 5100 && freq < 5500) { + txpi[0] = sprom->txpid5g[0]; + txpi[1] = sprom->txpid5g[1]; + } else if (freq >= 5500) { + txpi[0] = sprom->txpid5gh[0]; + txpi[1] = sprom->txpid5gh[1]; + } else { + txpi[0] = 91; + txpi[1] = 91; + } + } + + /* + for (i = 0; i < 2; i++) { + nphy->txpwrindex[i].index_internal = txpi[i]; + nphy->txpwrindex[i].index_internal_save = txpi[i]; + } + */ + + for (i = 0; i < 2; i++) { + if (dev->phy.rev >= 3) { + /* TODO */ + radio_gain = (txgain >> 16) & 0x1FFFF; + } else { + txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; + radio_gain = (txgain >> 16) & 0x1FFF; + } + + dac_gain = (txgain >> 8) & 0x3F; + bbmult = txgain & 0xFF; + + if (dev->phy.rev >= 3) { + if (i == 0) + b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100); + else + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100); + } else { + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000); + } + + if (i == 0) + b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain); + else + b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); + tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + + if (i == 0) + tmp = (tmp & 0x00FF) | (bbmult << 8); + else + tmp = (tmp & 0xFF00) | bbmult; + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp); + + if (0) + ; /* TODO */ + } + + b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 0); } @@ -2351,7 +2497,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) struct nphy_txgains target; const u32 *table = NULL; - if (nphy->txpwrctrl == 0) { + if (!nphy->txpwrctrl) { int i; if (nphy->hang_avoid) @@ -3260,9 +3406,8 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_bphy_init(dev); tx_pwr_state = nphy->txpwrctrl; - /* TODO N PHY TX power control with argument 0 - (turning off power control) */ - /* TODO Fix the TX Power Settings */ + b43_nphy_tx_power_ctrl(dev, false); + b43_nphy_tx_power_fix(dev); /* TODO N PHY TX Power Control Idle TSSI */ /* TODO N PHY TX Power Control Setup */ @@ -3333,7 +3478,7 @@ int b43_phy_initn(struct b43_wldev *dev) } b43_nphy_tx_pwr_ctrl_coef_setup(dev); - /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */ + b43_nphy_tx_power_ctrl(dev, tx_pwr_state); b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); if (phy->rev >= 3 && phy->rev <= 6) @@ -3384,7 +3529,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev, b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); } - if (nphy->txpwrctrl) + if (!nphy->txpwrctrl) b43_nphy_tx_power_fix(dev); if (dev->phy.rev < 3) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index c144e59a708b..001e841f118c 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -782,7 +782,7 @@ struct b43_phy_n { u16 mphase_txcal_numcmds; u16 mphase_txcal_bestcoeffs[11]; - u8 txpwrctrl; + bool txpwrctrl; u16 txcal_bbmult; u16 txiqlocal_bestc[11]; bool txiqlocal_coeffsvalid; -- cgit v1.2.3-59-g8ed1b From 8c1d5a7a2230a162af709fa118f051e0d18ff427 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 28 Nov 2010 12:59:44 +0100 Subject: b43: N-PHY: initialize perical variable, add missing call to CCA reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8690551f087c..a721cac42976 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2212,6 +2212,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) b43_nphy_classifier(dev, 7, class); b43_nphy_write_clip_detection(dev, clip_state); + /* Specs don't say about reset here, but it makes wl and b43 dumps + identical, it really seems wl performs this */ + b43_nphy_reset_cca(dev); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ @@ -3625,6 +3628,7 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev) nphy->gain_boost = true; /* this way we follow wl, assume it is true */ nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */ + nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */ } static void b43_nphy_op_free(struct b43_wldev *dev) -- cgit v1.2.3-59-g8ed1b From 8cbe6e66889d2e4dbea37b2fc6f276bd69d1ef67 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 28 Nov 2010 12:59:45 +0100 Subject: b43: N-PHY: fix RSSI calibration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index a721cac42976..85a7a60c54bf 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2064,7 +2064,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) u16 class, override; u8 regs_save_radio[2]; u16 regs_save_phy[2]; + s8 offset[4]; + u8 core; + u8 rail; u16 clip_state[2]; u16 clip_off[2] = { 0xFFFF, 0xFFFF }; @@ -2165,12 +2168,11 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) if (results_min[i] == 248) offset[i] = code - 32; - if (i % 2 == 0) - b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0, - type); - else - b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1, - type); + core = (i / 2) ? 2 : 1; + rail = (i % 2) ? 1 : 0; + + b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, + type); } b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); -- cgit v1.2.3-59-g8ed1b From 493f377d6dd56f4e98b198d637fe714ab124681b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Dec 2010 12:14:29 -0800 Subject: tcp: Add timewait recycling bits to ipv6 connect code. This will also improve handling of ipv6 tcp socket request backlog when syncookies are not enabled. When backlog becomes very deep, last quarter of backlog is limited to validated destinations. Previously only ipv4 implemented this logic, but now ipv6 does too. Now we are only one step away from enabling timewait recycling for ipv6, and that step is simply filling in the implementation of tcp_v6_get_peer() and tcp_v6_tw_get_peer(). Signed-off-by: David S. Miller --- net/core/request_sock.c | 1 + net/ipv6/tcp_ipv6.c | 101 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 7552495aff7a..41d99435f62d 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c @@ -33,6 +33,7 @@ * Note : Dont forget somaxconn that may limit backlog too. */ int sysctl_max_syn_backlog = 256; +EXPORT_SYMBOL(sysctl_max_syn_backlog); int reqsk_queue_alloc(struct request_sock_queue *queue, unsigned int nr_table_entries) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5f73a1808e36..c2ebbe1c5a47 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -130,6 +130,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct rt6_info *rt; struct flowi fl; struct dst_entry *dst; int addr_type; @@ -280,6 +281,26 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, sk->sk_gso_type = SKB_GSO_TCPV6; __ip6_dst_store(sk, dst, NULL, NULL); + rt = (struct rt6_info *) dst; + if (tcp_death_row.sysctl_tw_recycle && + !tp->rx_opt.ts_recent_stamp && + ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) { + struct inet_peer *peer = rt6_get_peer(rt); + /* + * VJ's idea. We save last timestamp seen from + * the destination in peer table, when entering state + * TIME-WAIT * and initialize rx_opt.ts_recent from it, + * when trying new connection. + */ + if (peer) { + inet_peer_refcheck(peer); + if ((u32)get_seconds() - peer->tcp_ts_stamp <= TCP_PAWS_MSL) { + tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp; + tp->rx_opt.ts_recent = peer->tcp_ts; + } + } + } + icsk->icsk_ext_hdr_len = 0; if (np->opt) icsk->icsk_ext_hdr_len = (np->opt->opt_flen + @@ -1170,6 +1191,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); __u32 isn = TCP_SKB_CB(skb)->when; + struct dst_entry *dst = NULL; #ifdef CONFIG_SYN_COOKIES int want_cookie = 0; #else @@ -1267,6 +1289,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) TCP_ECN_create_request(req, tcp_hdr(skb)); if (!isn) { + struct inet_peer *peer = NULL; + if (ipv6_opt_accepted(sk, skb) || np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { @@ -1279,13 +1303,57 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) if (!sk->sk_bound_dev_if && ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) treq->iif = inet6_iif(skb); - if (!want_cookie) { - isn = tcp_v6_init_sequence(skb); - } else { + + if (want_cookie) { isn = cookie_v6_init_sequence(sk, skb, &req->mss); req->cookie_ts = tmp_opt.tstamp_ok; + goto have_isn; + } + + /* VJ's idea. We save last timestamp seen + * from the destination in peer table, when entering + * state TIME-WAIT, and check against it before + * accepting new connection request. + * + * If "isn" is not zero, this request hit alive + * timewait bucket, so that all the necessary checks + * are made in the function processing timewait state. + */ + if (tmp_opt.saw_tstamp && + tcp_death_row.sysctl_tw_recycle && + (dst = inet6_csk_route_req(sk, req)) != NULL && + (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL && + ipv6_addr_equal((struct in6_addr *)peer->daddr.a6, + &treq->rmt_addr)) { + inet_peer_refcheck(peer); + if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && + (s32)(peer->tcp_ts - req->ts_recent) > + TCP_PAWS_WINDOW) { + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); + goto drop_and_release; + } + } + /* Kill the following clause, if you dislike this way. */ + else if (!sysctl_tcp_syncookies && + (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < + (sysctl_max_syn_backlog >> 2)) && + (!peer || !peer->tcp_ts_stamp) && + (!dst || !dst_metric(dst, RTAX_RTT))) { + /* Without syncookies last quarter of + * backlog is filled with destinations, + * proven to be alive. + * It means that we continue to communicate + * to destinations, already remembered + * to the moment of synflood. + */ + LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open request from %pI6/%u\n", + &treq->rmt_addr, ntohs(tcp_hdr(skb)->source)); + goto drop_and_release; } + + isn = tcp_v6_init_sequence(skb); } +have_isn: tcp_rsk(req)->snt_isn = isn; security_inet_conn_request(sk, skb, req); @@ -1298,6 +1366,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); return 0; +drop_and_release: + dst_release(dst); drop_and_free: reqsk_free(req); drop: @@ -1376,28 +1446,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, if (sk_acceptq_is_full(sk)) goto out_overflow; - if (dst == NULL) { - struct in6_addr *final_p, final; - struct flowi fl; - - memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); - final_p = fl6_update_dst(&fl, opt, &final); - ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; - fl.fl_ip_dport = inet_rsk(req)->rmt_port; - fl.fl_ip_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, &fl); - - if (ip6_dst_lookup(sk, &dst, &fl)) - goto out; - - if (final_p) - ipv6_addr_copy(&fl.fl6_dst, final_p); - - if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) + if (!dst) { + dst = inet6_csk_route_req(sk, req); + if (!dst) goto out; } -- cgit v1.2.3-59-g8ed1b From db3949c4506a21633469d71f2915cf660eea0a35 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Dec 2010 11:52:07 -0800 Subject: tcp: Implement ipv6 ->get_peer() and ->tw_get_peer(). Now ipv6 timewait recycling is fully implemented and enabled. Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c2ebbe1c5a47..319458558df9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1865,19 +1865,33 @@ do_time_wait: static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) { - /* Alas, not yet... */ - return NULL; + struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + struct inet_peer *peer; + + if (!rt || + !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) { + peer = inet_getpeer_v6(&np->daddr, 1); + *release_it = true; + } else { + if (!rt->rt6i_peer) + rt6_bind_peer(rt, 1); + peer = rt->rt6i_peer; + *release_it = true; + } + + return peer; } static void *tcp_v6_tw_get_peer(struct sock *sk) { + struct inet6_timewait_sock *tw6 = inet6_twsk(sk); struct inet_timewait_sock *tw = inet_twsk(sk); if (tw->tw_family == AF_INET) return tcp_v4_tw_get_peer(sk); - /* Alas, not yet... */ - return NULL; + return inet_getpeer_v6(&tw6->tw_v6_daddr, 1); } static struct timewait_sock_ops tcp6_timewait_sock_ops = { -- cgit v1.2.3-59-g8ed1b From eb272441fc14ad126abfa46de8a9c58bda8added Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 29 Nov 2010 14:13:22 -0800 Subject: ath9k: Move debugfs under ieee80211/[phyname]/ath9k/ This fixes debugfs problems when a phy is renamed, and is able to remove a bit of code that is no longer needed. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 35 ++++------------------------------ drivers/net/wireless/ath/ath9k/debug.h | 16 ---------------- drivers/net/wireless/ath/ath9k/init.c | 30 ++++++++--------------------- 3 files changed, 12 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 0c3c74c157fb..3586c43077a7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -24,8 +24,6 @@ #define REG_READ_D(_ah, _reg) \ ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) -static struct dentry *ath9k_debugfs_root; - static int ath9k_debugfs_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -878,11 +876,8 @@ int ath9k_init_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath_softc *sc = (struct ath_softc *) common->priv; - if (!ath9k_debugfs_root) - return -ENOENT; - - sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), - ath9k_debugfs_root); + sc->debug.debugfs_phy = debugfs_create_dir("ath9k", + sc->hw->wiphy->debugfsdir); if (!sc->debug.debugfs_phy) return -ENOMEM; @@ -935,29 +930,7 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.regidx = 0; return 0; err: - ath9k_exit_debug(ah); - return -ENOMEM; -} - -void ath9k_exit_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath_softc *sc = (struct ath_softc *) common->priv; - debugfs_remove_recursive(sc->debug.debugfs_phy); -} - -int ath9k_debug_create_root(void) -{ - ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!ath9k_debugfs_root) - return -ENOENT; - - return 0; -} - -void ath9k_debug_remove_root(void) -{ - debugfs_remove(ath9k_debugfs_root); - ath9k_debugfs_root = NULL; + sc->debug.debugfs_phy = NULL; + return -ENOMEM; } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 646ff7e04c88..1e5078bd0344 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -164,10 +164,7 @@ struct ath9k_debug { }; int ath9k_init_debug(struct ath_hw *ah); -void ath9k_exit_debug(struct ath_hw *ah); -int ath9k_debug_create_root(void); -void ath9k_debug_remove_root(void); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts); @@ -180,19 +177,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah) return 0; } -static inline void ath9k_exit_debug(struct ath_hw *ah) -{ -} - -static inline int ath9k_debug_create_root(void) -{ - return 0; -} - -static inline void ath9k_debug_remove_root(void) -{ -} - static inline void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d11e6da4d892..ef39a4551bd5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -570,13 +570,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_hw; - ret = ath9k_init_debug(ah); - if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to create debugfs files\n"); - goto err_debug; - } - ret = ath9k_init_queues(sc); if (ret) goto err_queues; @@ -599,8 +592,6 @@ err_btcoex: if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->tx.txq[i]); err_queues: - ath9k_exit_debug(ah); -err_debug: ath9k_hw_deinit(ah); err_hw: tasklet_kill(&sc->intr_tq); @@ -744,6 +735,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, if (error) goto error_register; + error = ath9k_init_debug(ah); + if (error) { + ath_print(common, ATH_DBG_FATAL, + "Unable to create debugfs files\n"); + goto error_world; + } + /* Handle world regulatory */ if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); @@ -802,7 +800,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->tx.txq[i]); - ath9k_exit_debug(sc->sc_ah); ath9k_hw_deinit(sc->sc_ah); tasklet_kill(&sc->intr_tq); @@ -869,20 +866,12 @@ static int __init ath9k_init(void) goto err_out; } - error = ath9k_debug_create_root(); - if (error) { - printk(KERN_ERR - "ath9k: Unable to create debugfs root: %d\n", - error); - goto err_rate_unregister; - } - error = ath_pci_init(); if (error < 0) { printk(KERN_ERR "ath9k: No PCI devices found, driver not installed.\n"); error = -ENODEV; - goto err_remove_root; + goto err_rate_unregister; } error = ath_ahb_init(); @@ -896,8 +885,6 @@ static int __init ath9k_init(void) err_pci_exit: ath_pci_exit(); - err_remove_root: - ath9k_debug_remove_root(); err_rate_unregister: ath_rate_control_unregister(); err_out: @@ -909,7 +896,6 @@ static void __exit ath9k_exit(void) { ath_ahb_exit(); ath_pci_exit(); - ath9k_debug_remove_root(); ath_rate_control_unregister(); printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } -- cgit v1.2.3-59-g8ed1b From 44b23b488d44e56d467764ecb661830e5b02b308 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 30 Nov 2010 12:19:11 -0800 Subject: ath9k: hif_usb: Reduce indent 1 column Invert test and return early. Move variable declarations to local scope. Don't initialize variables to 0 unnecessarily. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 106 +++++++++++++++---------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index ae842dbf9b50..63bf9a713ce0 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -363,9 +363,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, struct sk_buff *skb) { struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER]; - int index = 0, i = 0, chk_idx, len = skb->len; - int rx_remain_len = 0, rx_pkt_len = 0; - u16 pkt_len, pkt_tag, pool_index = 0; + int index = 0, i = 0, len = skb->len; + int rx_remain_len, rx_pkt_len; + u16 pool_index = 0; u8 *ptr; spin_lock(&hif_dev->rx_lock); @@ -399,64 +399,64 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, spin_unlock(&hif_dev->rx_lock); while (index < len) { + u16 pkt_len; + u16 pkt_tag; + u16 pad_len; + int chk_idx; + ptr = (u8 *) skb->data; pkt_len = ptr[index] + (ptr[index+1] << 8); pkt_tag = ptr[index+2] + (ptr[index+3] << 8); - if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) { - u16 pad_len; - - pad_len = 4 - (pkt_len & 0x3); - if (pad_len == 4) - pad_len = 0; - - chk_idx = index; - index = index + 4 + pkt_len + pad_len; - - if (index > MAX_RX_BUF_SIZE) { - spin_lock(&hif_dev->rx_lock); - hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; - hif_dev->rx_transfer_len = - MAX_RX_BUF_SIZE - chk_idx - 4; - hif_dev->rx_pad_len = pad_len; - - nskb = __dev_alloc_skb(pkt_len + 32, - GFP_ATOMIC); - if (!nskb) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: RX memory allocation" - " error\n"); - spin_unlock(&hif_dev->rx_lock); - goto err; - } - skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); - - memcpy(nskb->data, &(skb->data[chk_idx+4]), - hif_dev->rx_transfer_len); - - /* Record the buffer pointer */ - hif_dev->remain_skb = nskb; + if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) { + RX_STAT_INC(skb_dropped); + return; + } + + pad_len = 4 - (pkt_len & 0x3); + if (pad_len == 4) + pad_len = 0; + + chk_idx = index; + index = index + 4 + pkt_len + pad_len; + + if (index > MAX_RX_BUF_SIZE) { + spin_lock(&hif_dev->rx_lock); + hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; + hif_dev->rx_transfer_len = + MAX_RX_BUF_SIZE - chk_idx - 4; + hif_dev->rx_pad_len = pad_len; + + nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); + if (!nskb) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: RX memory allocation error\n"); spin_unlock(&hif_dev->rx_lock); - } else { - nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); - if (!nskb) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: RX memory allocation" - " error\n"); - goto err; - } - skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); - - memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len); - skb_put(nskb, pkt_len); - skb_pool[pool_index++] = nskb; + goto err; } + skb_reserve(nskb, 32); + RX_STAT_INC(skb_allocated); + + memcpy(nskb->data, &(skb->data[chk_idx+4]), + hif_dev->rx_transfer_len); + + /* Record the buffer pointer */ + hif_dev->remain_skb = nskb; + spin_unlock(&hif_dev->rx_lock); } else { - RX_STAT_INC(skb_dropped); - return; + nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); + if (!nskb) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: RX memory allocation error\n"); + goto err; + } + skb_reserve(nskb, 32); + RX_STAT_INC(skb_allocated); + + memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len); + skb_put(nskb, pkt_len); + skb_pool[pool_index++] = nskb; } } -- cgit v1.2.3-59-g8ed1b From 99f6c2ef1e968c0dbdfa8c5b8f2869129b860d88 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 30 Nov 2010 22:33:14 +0100 Subject: b43: N-PHY: fix RSSI selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 85a7a60c54bf..1d0847624bb4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1822,27 +1822,39 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) (type + 1) << 4); } - /* TODO use some definitions */ if (code == 0) { - b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); if (type < 3) { - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0); - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0); + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, + ~(B43_NPHY_RFCTL_CMD_RXEN | + B43_NPHY_RFCTL_CMD_CORESEL)); + b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, + ~(0x1 << 12 | + 0x1 << 5 | + 0x1 << 1 | + 0x1)); + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, + ~B43_NPHY_RFCTL_CMD_START); udelay(20); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); + b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); } } else { - b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, - 0x3000); + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); if (type < 3) { b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, - 0xFEC7, 0x0180); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, - 0xEFDC, (code << 1 | 0x1021)); - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1); + ~(B43_NPHY_RFCTL_CMD_RXEN | + B43_NPHY_RFCTL_CMD_CORESEL), + (B43_NPHY_RFCTL_CMD_RXEN | + code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT)); + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, + (0x1 << 12 | + 0x1 << 5 | + 0x1 << 1 | + 0x1)); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_CMD_START); udelay(20); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); + b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); } } } -- cgit v1.2.3-59-g8ed1b From 76b002bd6dfdd66c58669cbdfa5cd92084b6936e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 30 Nov 2010 22:33:15 +0100 Subject: b43: N-PHY: use defines for RSSI types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 73 +++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 1d0847624bb4..f26b60b95dba 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -67,6 +67,16 @@ enum b43_nphy_rf_sequence { B43_RFSEQ_UPDATE_GAINU, }; +enum b43_nphy_rssi_type { + B43_NPHY_RSSI_X = 0, + B43_NPHY_RSSI_Y, + B43_NPHY_RSSI_Z, + B43_NPHY_RSSI_PWRDET, + B43_NPHY_RSSI_TSSI_I, + B43_NPHY_RSSI_TSSI_Q, + B43_NPHY_RSSI_TBD, +}; + static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable); static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, @@ -1739,7 +1749,8 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, - s8 offset, u8 core, u8 rail, u8 type) + s8 offset, u8 core, u8 rail, + enum b43_nphy_rssi_type type) { u16 tmp; bool core1or5 = (core == 1) || (core == 5); @@ -1748,53 +1759,59 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, offset = clamp_val(offset, -32, 31); tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); - if (core1or5 && (rail == 0) && (type == 2)) + if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); - if (core1or5 && (rail == 1) && (type == 2)) + if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); - if (core2or5 && (rail == 0) && (type == 2)) + if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); - if (core2or5 && (rail == 1) && (type == 2)) + if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); - if (core1or5 && (rail == 0) && (type == 0)) + + if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); - if (core1or5 && (rail == 1) && (type == 0)) + if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); - if (core2or5 && (rail == 0) && (type == 0)) + if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); - if (core2or5 && (rail == 1) && (type == 0)) + if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); - if (core1or5 && (rail == 0) && (type == 1)) + + if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); - if (core1or5 && (rail == 1) && (type == 1)) + if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); - if (core2or5 && (rail == 0) && (type == 1)) + if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); - if (core2or5 && (rail == 1) && (type == 1)) + if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); - if (core1or5 && (rail == 0) && (type == 6)) + + if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); - if (core1or5 && (rail == 1) && (type == 6)) + if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); - if (core2or5 && (rail == 0) && (type == 6)) + if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); - if (core2or5 && (rail == 1) && (type == 6)) + if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); - if (core1or5 && (rail == 0) && (type == 3)) + + if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); - if (core1or5 && (rail == 1) && (type == 3)) + if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); - if (core2or5 && (rail == 0) && (type == 3)) + if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); - if (core2or5 && (rail == 1) && (type == 3)) + if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); - if (core1or5 && (type == 4)) + + if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I)) b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); - if (core2or5 && (type == 4)) + if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I)) b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); - if (core1or5 && (type == 5)) + + if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q)) b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); - if (core2or5 && (type == 5)) + if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q)) b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); } @@ -2246,9 +2263,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev) if (dev->phy.rev >= 3) { b43_nphy_rev3_rssi_cal(dev); } else { - b43_nphy_rev2_rssi_cal(dev, 2); - b43_nphy_rev2_rssi_cal(dev, 0); - b43_nphy_rev2_rssi_cal(dev, 1); + b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z); + b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X); + b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y); } } -- cgit v1.2.3-59-g8ed1b From e7797bf2c0297098056a95b6b03ea5a9a3285e36 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 30 Nov 2010 22:33:16 +0100 Subject: b43: N-PHY: fix code path on PHY init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f26b60b95dba..905f1d7bac20 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3498,19 +3498,16 @@ int b43_phy_initn(struct b43_wldev *dev) /* TODO N PHY Pre Calibrate TX Gain */ target = b43_nphy_get_tx_gains(dev); } - } + if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) + if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) + b43_nphy_save_cal(dev); + } else if (nphy->mphase_cal_phase_id == 0) + ;/* N PHY Periodic Calibration with arg 3 */ + } else { + b43_nphy_restore_cal(dev); } } - if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) { - if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) - b43_nphy_save_cal(dev); - else if (nphy->mphase_cal_phase_id == 0) - ;/* N PHY Periodic Calibration with argument 3 */ - } else { - b43_nphy_restore_cal(dev); - } - b43_nphy_tx_pwr_ctrl_coef_setup(dev); b43_nphy_tx_power_ctrl(dev, tx_pwr_state); b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); -- cgit v1.2.3-59-g8ed1b From b2767363192d5937e0f61f05b1b6b881da9ee55a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 30 Nov 2010 13:42:08 -0800 Subject: wireless: Remove unnecessary casts of usb_get_intfdata Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/usb.c | 6 ++---- drivers/net/wireless/ath/ath9k/hif_usb.c | 13 +++++-------- drivers/net/wireless/ath/carl9170/usb.c | 3 +-- drivers/net/wireless/p54/p54usb.c | 2 +- drivers/net/wireless/zd1201.c | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 5dbb5361fd51..d3be6f9816b5 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -161,8 +161,7 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru) static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) { struct sk_buff *skb = urb->context; - struct ar9170_usb *aru = (struct ar9170_usb *) - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); if (unlikely(!aru)) { dev_kfree_skb_irq(skb); @@ -219,8 +218,7 @@ free: static void ar9170_usb_rx_completed(struct urb *urb) { struct sk_buff *skb = urb->context; - struct ar9170_usb *aru = (struct ar9170_usb *) - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); int err; if (!aru) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 63bf9a713ce0..8946e8ad1b85 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -471,7 +471,7 @@ err: static void ath9k_hif_usb_rx_cb(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct hif_device_usb *hif_dev = (struct hif_device_usb *) + struct hif_device_usb *hif_dev = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); int ret; @@ -518,7 +518,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct sk_buff *nskb; - struct hif_device_usb *hif_dev = (struct hif_device_usb *) + struct hif_device_usb *hif_dev = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); int ret; @@ -993,8 +993,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) static void ath9k_hif_usb_disconnect(struct usb_interface *interface) { struct usb_device *udev = interface_to_usbdev(interface); - struct hif_device_usb *hif_dev = - (struct hif_device_usb *) usb_get_intfdata(interface); + struct hif_device_usb *hif_dev = usb_get_intfdata(interface); if (hif_dev) { ath9k_htc_hw_deinit(hif_dev->htc_handle, @@ -1016,8 +1015,7 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) static int ath9k_hif_usb_suspend(struct usb_interface *interface, pm_message_t message) { - struct hif_device_usb *hif_dev = - (struct hif_device_usb *) usb_get_intfdata(interface); + struct hif_device_usb *hif_dev = usb_get_intfdata(interface); ath9k_hif_usb_dealloc_urbs(hif_dev); @@ -1026,8 +1024,7 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, static int ath9k_hif_usb_resume(struct usb_interface *interface) { - struct hif_device_usb *hif_dev = - (struct hif_device_usb *) usb_get_intfdata(interface); + struct hif_device_usb *hif_dev = usb_get_intfdata(interface); struct htc_target *htc_handle = hif_dev->htc_handle; int ret; diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index a268053e18e5..2d947a30d29e 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -160,8 +160,7 @@ err_acc: static void carl9170_usb_tx_data_complete(struct urb *urb) { - struct ar9170 *ar = (struct ar9170 *) - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); if (WARN_ON_ONCE(!ar)) { dev_kfree_skb_irq(urb->context); diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5bc21e5a02c..dd4d8fc9ad7a 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -183,7 +183,7 @@ static void p54u_rx_cb(struct urb *urb) static void p54u_tx_cb(struct urb *urb) { struct sk_buff *skb = urb->context; - struct ieee80211_hw *dev = (struct ieee80211_hw *) + struct ieee80211_hw *dev = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); p54_free_skb(dev, skb); diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index b97aa9c78a96..415eec401e2e 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -1830,7 +1830,7 @@ err_zd: static void zd1201_disconnect(struct usb_interface *interface) { - struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface); + struct zd1201 *zd = usb_get_intfdata(interface); struct hlist_node *node, *node2; struct zd1201_frag *frag; -- cgit v1.2.3-59-g8ed1b From 6a0141175b6026e13652339e607a35f4b6687f27 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 1 Dec 2010 12:30:09 +0530 Subject: ath9k_htc: Remove unused structures Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_hst.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 6fc1b21faa5d..ecd018798c47 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -77,20 +77,6 @@ struct htc_config_pipe_msg { u8 credits; } __packed; -struct htc_packet { - void *pktcontext; - u8 *buf; - u8 *buf_payload; - u32 buflen; - u32 payload_len; - - int endpoint; - int status; - - void *context; - u32 reserved; -}; - struct htc_ep_callbacks { void *priv; void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok); @@ -123,11 +109,6 @@ struct htc_endpoint { #define HTC_CONTROL_BUFFER_SIZE \ (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr)) -struct htc_control_buf { - struct htc_packet htc_pkt; - u8 buf[HTC_CONTROL_BUFFER_SIZE]; -}; - #define HTC_OP_START_WAIT BIT(0) #define HTC_OP_CONFIG_PIPE_CREDITS BIT(1) -- cgit v1.2.3-59-g8ed1b From 2e54a7a20cf7c02ee17c56488fedb8cd3d2c2f35 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:27 +0100 Subject: cfg80211: include CQM packet loss docs Just include them in the list of functions, there aren't any more detailed docs (yet). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 19a1210c2530..20db115cadcf 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -146,6 +146,7 @@ !Finclude/net/cfg80211.h cfg80211_rx_mgmt !Finclude/net/cfg80211.h cfg80211_mgmt_tx_status !Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify +!Finclude/net/cfg80211.h cfg80211_cqm_pktloss_notify !Finclude/net/cfg80211.h cfg80211_michael_mic_failure -- cgit v1.2.3-59-g8ed1b From d7ae30f073a179a9cebd663e7502843ddf4ba672 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:28 +0100 Subject: mac80211: document workqueue Create a new chapter for the mac80211 workqueue that contains the documentation written for it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 20db115cadcf..c3c211eebd2f 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -355,6 +355,13 @@ !Pinclude/net/mac80211.h Frame filtering !Finclude/net/mac80211.h ieee80211_filter_flags + + + The mac80211 workqueue +!Pinclude/net/mac80211.h mac80211 workqueue +!Finclude/net/mac80211.h ieee80211_queue_work +!Finclude/net/mac80211.h ieee80211_queue_delayed_work + -- cgit v1.2.3-59-g8ed1b From 7bcfda13fea4a8770deaf4b22093dc2708760128 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:29 +0100 Subject: mac80211: publish docs for _ni functions Put them along with their "regular" versions for now, we should write more docs in the future. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index c3c211eebd2f..a346c0fc45bc 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -335,8 +335,10 @@ !Finclude/net/mac80211.h mac80211_rx_flags !Finclude/net/mac80211.h ieee80211_tx_info !Finclude/net/mac80211.h ieee80211_rx +!Finclude/net/mac80211.h ieee80211_rx_ni !Finclude/net/mac80211.h ieee80211_rx_irqsafe !Finclude/net/mac80211.h ieee80211_tx_status +!Finclude/net/mac80211.h ieee80211_tx_status_ni !Finclude/net/mac80211.h ieee80211_tx_status_irqsafe !Finclude/net/mac80211.h ieee80211_rts_get !Finclude/net/mac80211.h ieee80211_rts_duration -- cgit v1.2.3-59-g8ed1b From 625208138550562fd3bc731f53f43cb66a3be70a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:30 +0100 Subject: mac80211: publish some misc docs There isn't a clear TX documentation yet, so put these into the misc section for now. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index a346c0fc45bc..7b30331bc444 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -333,7 +333,11 @@ functions/definitions !Finclude/net/mac80211.h ieee80211_rx_status !Finclude/net/mac80211.h mac80211_rx_flags +!Finclude/net/mac80211.h mac80211_tx_control_flags +!Finclude/net/mac80211.h mac80211_rate_control_flags +!Finclude/net/mac80211.h ieee80211_tx_rate !Finclude/net/mac80211.h ieee80211_tx_info +!Finclude/net/mac80211.h ieee80211_tx_info_clear_status !Finclude/net/mac80211.h ieee80211_rx !Finclude/net/mac80211.h ieee80211_rx_ni !Finclude/net/mac80211.h ieee80211_rx_irqsafe @@ -349,6 +353,7 @@ !Finclude/net/mac80211.h ieee80211_stop_queue !Finclude/net/mac80211.h ieee80211_wake_queues !Finclude/net/mac80211.h ieee80211_stop_queues +!Finclude/net/mac80211.h ieee80211_queue_stopped @@ -384,6 +389,9 @@ !Finclude/net/mac80211.h set_key_cmd !Finclude/net/mac80211.h ieee80211_key_conf !Finclude/net/mac80211.h ieee80211_key_flags +!Finclude/net/mac80211.h ieee80211_tkip_key_type +!Finclude/net/mac80211.h ieee80211_get_tkip_key +!Finclude/net/mac80211.h ieee80211_key_removed -- cgit v1.2.3-59-g8ed1b From cf6cb7ab59e0b37afe6e76b2e444479bf86bf933 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:31 +0100 Subject: mac80211: publish some rate control docs Add an API chapter to the rate control part of the mac80211 book and populate it with some existing documentation. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 7b30331bc444..a9384e871882 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -453,9 +453,16 @@ interface and how it relates to mac80211 and drivers. - - dummy chapter + + Rate Control API TBD +!Finclude/net/mac80211.h ieee80211_start_tx_ba_session +!Finclude/net/mac80211.h ieee80211_start_tx_ba_cb_irqsafe +!Finclude/net/mac80211.h ieee80211_stop_tx_ba_session +!Finclude/net/mac80211.h ieee80211_stop_tx_ba_cb_irqsafe +!Finclude/net/mac80211.h rate_control_changed +!Finclude/net/mac80211.h ieee80211_tx_rate_control +!Finclude/net/mac80211.h rate_control_send_low -- cgit v1.2.3-59-g8ed1b From e16c01030b8794992590ff9b1b1e4b1b89e0cad3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:32 +0100 Subject: mac80211: document aggregation Include the aggregation documentation in the docbook, split up by public and internal docs. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index a9384e871882..3d230cf57cff 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -442,6 +442,21 @@ TBD !Finclude/net/mac80211.h ieee80211_scan_completed + + + Aggregation + + TX A-MPDU aggregation +!Pnet/mac80211/agg-tx.c TX A-MPDU aggregation +!Cnet/mac80211/agg-tx.c + + + RX A-MPDU aggregation +!Pnet/mac80211/agg-rx.c RX A-MPDU aggregation +!Cnet/mac80211/agg-rx.c + +!Finclude/net/mac80211.h ieee80211_ampdu_mlme_action + @@ -510,6 +525,13 @@ + + Aggregation +!Fnet/mac80211/sta_info.h sta_ampdu_mlme +!Fnet/mac80211/sta_info.h tid_ampdu_tx +!Fnet/mac80211/sta_info.h tid_ampdu_rx + + Synchronisation TBD -- cgit v1.2.3-59-g8ed1b From eebbb348df5a8c239a6300188907dec7e427bf70 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:33 +0100 Subject: mac80211: publish interface iteration docs Publish the documentation for the interface iteration functions in the right section of the book. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 3d230cf57cff..50e75f370bd6 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -435,6 +435,8 @@ supported by mac80211, add notes about supporting hw crypto with it. +!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces +!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces_atomic -- cgit v1.2.3-59-g8ed1b From f6b8bef3634a5c9ea326b3ab0c9615fdac5f18ab Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:34 +0100 Subject: mac80211: document station handling Add some existing documentation about station handling to a new chapter about advanced APIs. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 50e75f370bd6..601ea785fc91 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -439,6 +439,16 @@ !Finclude/net/mac80211.h ieee80211_iterate_active_interfaces_atomic + + Station handling + TODO +!Finclude/net/mac80211.h ieee80211_sta +!Finclude/net/mac80211.h sta_notify_cmd +!Finclude/net/mac80211.h ieee80211_find_sta +!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr +!Finclude/net/mac80211.h ieee80211_sta_block_awake + + Hardware scan offload TBD -- cgit v1.2.3-59-g8ed1b From c1927d7a8fab07171d08f7a3a8b7e5fe87bb70d4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Dec 2010 09:43:35 +0100 Subject: mac80211: publish SMPS docs Create a new chapter about SMPS in the driver API part of the mac80211 book and populate it with the existing docs. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 601ea785fc91..03641a08e275 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -469,6 +469,13 @@ !Finclude/net/mac80211.h ieee80211_ampdu_mlme_action + + + Spatial Multiplexing Powersave (SMPS) +!Pinclude/net/mac80211.h Spatial multiplexing power save +!Finclude/net/mac80211.h ieee80211_request_smps +!Finclude/net/mac80211.h ieee80211_smps_mode + -- cgit v1.2.3-59-g8ed1b From 547025d5d4d1056fb4b5a0c9c3c0d5c2fe22c082 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 2 Dec 2010 16:23:12 +0900 Subject: cfg80211: Add documentation for antenna ops The last patch with the same title was for mac80211 ops, accidentally. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/net/cfg80211.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 49a7c53a48ca..6b2af7aeddd3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1154,6 +1154,13 @@ struct cfg80211_pmksa { * @mgmt_frame_register: Notify driver that a management frame type was * registered. Note that this callback may not sleep, and cannot run * concurrently with itself. + * + * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. + * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may + * reject TX/RX mask combinations they cannot support by returning -EINVAL + * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). + * + * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); -- cgit v1.2.3-59-g8ed1b From 78b8595691c34478a51d1c2bcbbb0f6ec8a28247 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Dec 2010 14:45:07 +0200 Subject: wireless: ray_cs: use '%pm' format option to print MAC Signed-off-by: Andy Shevchenko Cc: "John W. Linville" Cc: linux-wireless@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ray_cs.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 2b1cbba90a84..0764d1a30d13 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1776,11 +1776,8 @@ static void ray_update_multi_list(struct net_device *dev, int all) /* Copy the kernel's list of MC addresses to card */ netdev_for_each_mc_addr(ha, dev) { memcpy_toio(p, ha->addr, ETH_ALEN); - dev_dbg(&link->dev, - "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n", - ha->addr[0], ha->addr[1], - ha->addr[2], ha->addr[3], - ha->addr[4], ha->addr[5]); + dev_dbg(&link->dev, "ray_update_multi add addr %pm\n", + ha->addr); p += ETH_ALEN; i++; } @@ -2015,11 +2012,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete. bssid, ADDRLEN); - dev_dbg(&link->dev, - "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n", - local->bss_id[0], local->bss_id[1], - local->bss_id[2], local->bss_id[3], - local->bss_id[4], local->bss_id[5]); + dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n", + local->bss_id); if (!sniffer) authenticate(local); } -- cgit v1.2.3-59-g8ed1b From aeae4ac9090462ea38387dcdbac4f01b944af6a4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:26:51 +0100 Subject: ath5k: Use Generic DMA for later support of AHB bus. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 66 +++++++++++++++++++---------------- drivers/net/wireless/ath/ath5k/base.h | 4 ++- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a8d380aae658..2d7d8bac4610 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -198,8 +198,8 @@ static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, BUG_ON(!bf); if (!bf->skb) return; - pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len, - PCI_DMA_TODEVICE); + dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len, + DMA_TO_DEVICE); dev_kfree_skb_any(bf->skb); bf->skb = NULL; bf->skbaddr = 0; @@ -215,8 +215,8 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, BUG_ON(!bf); if (!bf->skb) return; - pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, - PCI_DMA_FROMDEVICE); + dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize, + DMA_FROM_DEVICE); dev_kfree_skb_any(bf->skb); bf->skb = NULL; bf->skbaddr = 0; @@ -647,10 +647,11 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) return NULL; } - *skb_addr = pci_map_single(sc->pdev, + *skb_addr = dma_map_single(sc->dev, skb->data, common->rx_bufsize, - PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { + DMA_FROM_DEVICE); + + if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) { ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); dev_kfree_skb(skb); return NULL; @@ -746,8 +747,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; /* XXX endianness */ - bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); + bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len, + DMA_TO_DEVICE); rate = ieee80211_get_tx_rate(sc->hw, info); if (!rate) { @@ -827,7 +828,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, return 0; err_unmap: - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); return ret; } @@ -836,7 +837,7 @@ err_unmap: \*******************/ static int -ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) +ath5k_desc_alloc(struct ath5k_softc *sc) { struct ath5k_desc *ds; struct ath5k_buf *bf; @@ -847,7 +848,9 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) /* allocate descriptors */ sc->desc_len = sizeof(struct ath5k_desc) * (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); - sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); + + sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len, + &sc->desc_daddr, GFP_KERNEL); if (sc->desc == NULL) { ATH5K_ERR(sc, "can't allocate descriptors\n"); ret = -ENOMEM; @@ -893,14 +896,14 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) return 0; err_free: - pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); + dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr); err: sc->desc = NULL; return ret; } static void -ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) +ath5k_desc_free(struct ath5k_softc *sc) { struct ath5k_buf *bf; @@ -912,7 +915,7 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) ath5k_txbuf_free_skb(sc, bf); /* Free memory associated with all descriptors */ - pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); + dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr); sc->desc = NULL; sc->desc_daddr = 0; @@ -1523,9 +1526,9 @@ ath5k_tasklet_rx(unsigned long data) if (!next_skb) goto next; - pci_unmap_single(sc->pdev, bf->skbaddr, + dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); skb_put(skb, rs.rs_datalen); @@ -1688,8 +1691,9 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) skb = bf->skb; bf->skb = NULL; - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, - PCI_DMA_TODEVICE); + + dma_unmap_single(sc->dev, bf->skbaddr, skb->len, + DMA_TO_DEVICE); ath5k_tx_frame_completed(sc, skb, &ts); } @@ -1743,12 +1747,13 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) u32 flags; const int padsize = 0; - bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); + bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len, + DMA_TO_DEVICE); ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " "skbaddr %llx\n", skb, skb->data, skb->len, (unsigned long long)bf->skbaddr); - if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { + + if (dma_mapping_error(sc->dev, bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); return -EIO; } @@ -1800,7 +1805,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) return 0; err_unmap: - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); return ret; } @@ -2361,7 +2366,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) if (!test_bit(ATH_STAT_INVALID, sc->status)) { ath5k_led_off(sc); ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); + synchronize_irq(sc->irq); ath5k_rx_stop(sc); ath5k_hw_dma_stop(ah); ath5k_drain_tx_buffs(sc); @@ -2509,7 +2514,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); + synchronize_irq(sc->irq); stop_tasklets(sc); if (chan) { @@ -2616,7 +2621,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) /* * Allocate tx+rx descriptors and populate the lists. */ - ret = ath5k_desc_alloc(sc, pdev); + ret = ath5k_desc_alloc(sc); if (ret) { ATH5K_ERR(sc, "can't allocate descriptors\n"); goto err; @@ -2680,8 +2685,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { - ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", - sc->pdev->device); + ATH5K_ERR(sc, "unable to read address from EEPROM\n"); goto err_queues; } @@ -2716,7 +2720,7 @@ err_queues: err_bhal: ath5k_hw_release_tx_queue(ah, sc->bhalq); err_desc: - ath5k_desc_free(sc, pdev); + ath5k_desc_free(sc); err: return ret; } @@ -2740,7 +2744,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) * Other than that, it's straightforward... */ ieee80211_unregister_hw(hw); - ath5k_desc_free(sc, pdev); + ath5k_desc_free(sc); ath5k_txq_release(sc); ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); ath5k_unregister_leds(sc); @@ -3565,6 +3569,8 @@ ath5k_pci_probe(struct pci_dev *pdev, sc = hw->priv; sc->hw = hw; sc->pdev = pdev; + sc->dev = &pdev->dev; + sc->irq = pdev->irq; /* * Mark the device as detached to avoid processing diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 9a79773cdc2a..0362f8eb9510 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -169,7 +169,9 @@ struct ath5k_vif { /* Software Carrier, keeps track of the driver state * associated with an instance of a device */ struct ath5k_softc { - struct pci_dev *pdev; /* for dma mapping */ + struct pci_dev *pdev; + struct device *dev; /* for dma mapping */ + int irq; void __iomem *iobase; /* address of the device */ struct mutex lock; /* dev-level lock */ struct ieee80211_hw *hw; /* IEEE 802.11 common */ -- cgit v1.2.3-59-g8ed1b From 132b1c3ee38ea6fa0501004fd0f19acb554e5a44 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:26:56 +0100 Subject: ath5k: Introduce ath5k_init_softc function as in ath9k Split pci initialization into hardware specific functions and softc structure initialization. Make function naming similar to ones ath9k. Introduce ath_bus_opts in ath5k for later AHB bus integration. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 13 +- drivers/net/wireless/ath/ath5k/attach.c | 10 +- drivers/net/wireless/ath/ath5k/base.c | 344 +++++++++++++++++++------------- drivers/net/wireless/ath/ath5k/base.h | 1 + drivers/net/wireless/ath/ath5k/eeprom.c | 2 +- 5 files changed, 217 insertions(+), 153 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 899bf4b99b76..a74f448f7d72 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1146,9 +1146,11 @@ struct ath5k_hw { * Prototypes */ -/* Attach/Detach Functions */ -int ath5k_hw_attach(struct ath5k_softc *sc); -void ath5k_hw_detach(struct ath5k_hw *ah); +/* Initialization and detach functions */ +int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops); +void ath5k_deinit_softc(struct ath5k_softc *sc); +int ath5k_hw_init(struct ath5k_softc *sc); +void ath5k_hw_deinit(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); @@ -1332,6 +1334,11 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) iowrite32(val, ah->ah_iobase + reg); } +static inline void ath5k_read_cachesize(struct ath_common *common, int *csz) +{ + common->bus_ops->read_cachesize(common, csz); +} + static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) { u32 retval = 0, bit, i; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index ed86b9dde1b4..a84782a63e0a 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah) } /** - * ath5k_hw_attach - Check if hw is supported and init the needed structs + * ath5k_hw_init - Check if hw is supported and init the needed structs * - * @sc: The &struct ath5k_softc we got from the driver's attach function + * @sc: The &struct ath5k_softc we got from the driver's init_softc function * * Check if the device is supported, perform a POST and initialize the needed * structs. Returns -ENOMEM if we don't have memory for the needed structs, * -ENODEV if the device is not supported or prints an error msg if something * else went wrong. */ -int ath5k_hw_attach(struct ath5k_softc *sc) +int ath5k_hw_init(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); @@ -346,11 +346,11 @@ err: } /** - * ath5k_hw_detach - Free the ath5k_hw struct + * ath5k_hw_deinit - Free the ath5k_hw struct * * @ah: The &struct ath5k_hw */ -void ath5k_hw_detach(struct ath5k_hw *ah) +void ath5k_hw_deinit(struct ath5k_hw *ah) { __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2d7d8bac4610..b11ea3d2872d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -80,6 +80,7 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); +static int ath5k_init(struct ieee80211_hw *hw); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu); static int ath5k_beacon_update(struct ieee80211_hw *hw, @@ -192,6 +193,32 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; +/* return bus cachesize in 4B word units */ +static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) +{ + struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; + u8 u8tmp; + + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); + *csz = (int)u8tmp; + + /* + * This check was put in to avoid "unplesant" consequences if + * the bootrom has not fully initialized all PCI devices. + * Sometimes the cache line size register is not set + */ + + if (*csz == 0) + *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ +} + +/* Common ath_bus_opts structure */ +static const struct ath_bus_ops ath_pci_bus_ops = { + .ath_bus_type = ATH_PCI, + .read_cachesize = ath5k_pci_read_cachesize, +}; + + static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { @@ -2152,7 +2179,7 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ } -static irqreturn_t +irqreturn_t ath5k_intr(int irq, void *dev_id) { struct ath5k_softc *sc = dev_id; @@ -2338,6 +2365,158 @@ ath5k_tx_complete_poll_work(struct work_struct *work) * Initialization routines * \*************************/ +int +ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) +{ + struct ieee80211_hw *hw = sc->hw; + struct ath_common *common; + int ret; + int csz; + + /* Initialize driver private data */ + SET_IEEE80211_DEV(hw, sc->dev); + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; + + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + + hw->extra_tx_headroom = 2; + hw->channel_change_time = 5000; + + /* + * Mark the device as detached to avoid processing + * interrupts until setup is complete. + */ + __set_bit(ATH_STAT_INVALID, sc->status); + + sc->opmode = NL80211_IFTYPE_STATION; + sc->bintval = 1000; + mutex_init(&sc->lock); + spin_lock_init(&sc->rxbuflock); + spin_lock_init(&sc->txbuflock); + spin_lock_init(&sc->block); + + + /* Setup interrupt handler */ + ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); + if (ret) { + ATH5K_ERR(sc, "request_irq failed\n"); + goto err; + } + + /* If we passed the test, malloc an ath5k_hw struct */ + sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); + if (!sc->ah) { + ret = -ENOMEM; + ATH5K_ERR(sc, "out of memory\n"); + goto err_irq; + } + + sc->ah->ah_sc = sc; + sc->ah->ah_iobase = sc->iobase; + common = ath5k_hw_common(sc->ah); + common->ops = &ath5k_common_ops; + common->bus_ops = bus_ops; + common->ah = sc->ah; + common->hw = hw; + common->priv = sc; + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + ath5k_read_cachesize(common, &csz); + common->cachelsz = csz << 2; /* convert to bytes */ + + spin_lock_init(&common->cc_lock); + + /* Initialize device */ + ret = ath5k_hw_init(sc); + if (ret) + goto err_free_ah; + + /* set up multi-rate retry capabilities */ + if (sc->ah->ah_version == AR5K_AR5212) { + hw->max_rates = 4; + hw->max_rate_tries = 11; + } + + hw->vif_data_size = sizeof(struct ath5k_vif); + + /* Finish private driver data initialization */ + ret = ath5k_init(hw); + if (ret) + goto err_ah; + + ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", + ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), + sc->ah->ah_mac_srev, + sc->ah->ah_phy_revision); + + if (!sc->ah->ah_single_chip) { + /* Single chip radio (!RF5111) */ + if (sc->ah->ah_radio_5ghz_revision && + !sc->ah->ah_radio_2ghz_revision) { + /* No 5GHz support -> report 2GHz radio */ + if (!test_bit(AR5K_MODE_11A, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* No 2GHz support (5110 and some + * 5Ghz only cards) -> report 5Ghz radio */ + } else if (!test_bit(AR5K_MODE_11B, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* Multiband radio */ + } else { + ATH5K_INFO(sc, "RF%s multiband radio found" + " (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + } + } + /* Multi chip radio (RF5111 - RF2111) -> + * report both 2GHz/5GHz radios */ + else if (sc->ah->ah_radio_5ghz_revision && + sc->ah->ah_radio_2ghz_revision){ + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_2ghz_revision), + sc->ah->ah_radio_2ghz_revision); + } + } + + ath5k_debug_init_device(sc); + + /* ready to process interrupts */ + __clear_bit(ATH_STAT_INVALID, sc->status); + + return 0; +err_ah: + ath5k_hw_deinit(sc->ah); +err_free_ah: + kfree(sc->ah); +err_irq: + free_irq(sc->irq, sc); +err: + return ret; +} + static int ath5k_stop_locked(struct ath5k_softc *sc) { @@ -2377,7 +2556,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) } static int -ath5k_init(struct ath5k_softc *sc) +ath5k_init_hw(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); @@ -2575,8 +2754,9 @@ static void ath5k_reset_work(struct work_struct *work) } static int -ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) +ath5k_init(struct ieee80211_hw *hw) { + struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); @@ -2584,7 +2764,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) u8 mac[ETH_ALEN] = {}; int ret; - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); /* * Check if the MAC has multi-rate retry support. @@ -2725,10 +2904,10 @@ err: return ret; } -static void -ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) +void +ath5k_deinit_softc(struct ath5k_softc *sc) { - struct ath5k_softc *sc = hw->priv; + struct ieee80211_hw *hw = sc->hw; /* * NB: the order of these is important: @@ -2743,6 +2922,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) * XXX: ??? detach ath5k_hw ??? * Other than that, it's straightforward... */ + ath5k_debug_finish_device(sc); ieee80211_unregister_hw(hw); ath5k_desc_free(sc); ath5k_txq_release(sc); @@ -2755,6 +2935,8 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) * returns because we'll get called back to reclaim node * state and potentially want to use them. */ + ath5k_hw_deinit(sc->ah); + free_irq(sc->irq, sc); } /********************\ @@ -2777,7 +2959,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int ath5k_start(struct ieee80211_hw *hw) { - return ath5k_init(hw->priv); + return ath5k_init_hw(hw->priv); } static void ath5k_stop(struct ieee80211_hw *hw) @@ -3422,7 +3604,7 @@ static int ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) return 0; } -static const struct ieee80211_ops ath5k_hw_ops = { +const struct ieee80211_ops ath5k_hw_ops = { .tx = ath5k_tx, .start = ath5k_start, .stop = ath5k_stop, @@ -3456,7 +3638,6 @@ ath5k_pci_probe(struct pci_dev *pdev, { void __iomem *mem; struct ath5k_softc *sc; - struct ath_common *common; struct ieee80211_hw *hw; int ret; u8 csz; @@ -3552,146 +3733,24 @@ ath5k_pci_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - /* Initialize driver private data */ - SET_IEEE80211_DEV(hw, &pdev->dev); - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; - - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT); - - hw->extra_tx_headroom = 2; - hw->channel_change_time = 5000; sc = hw->priv; sc->hw = hw; sc->pdev = pdev; sc->dev = &pdev->dev; sc->irq = pdev->irq; - - /* - * Mark the device as detached to avoid processing - * interrupts until setup is complete. - */ - __set_bit(ATH_STAT_INVALID, sc->status); - + sc->devid = id->device; sc->iobase = mem; /* So we can unmap it on detach */ - sc->opmode = NL80211_IFTYPE_STATION; - sc->bintval = 1000; - mutex_init(&sc->lock); - spin_lock_init(&sc->rxbuflock); - spin_lock_init(&sc->txbuflock); - spin_lock_init(&sc->block); - /* Set private data */ - pci_set_drvdata(pdev, sc); - - /* Setup interrupt handler */ - ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); + /* Initialize */ + ret = ath5k_init_softc(sc, &ath_pci_bus_ops); if (ret) { - ATH5K_ERR(sc, "request_irq failed\n"); goto err_free; } - /* If we passed the test, malloc an ath5k_hw struct */ - sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); - if (!sc->ah) { - ret = -ENOMEM; - ATH5K_ERR(sc, "out of memory\n"); - goto err_irq; - } - - sc->ah->ah_sc = sc; - sc->ah->ah_iobase = sc->iobase; - common = ath5k_hw_common(sc->ah); - common->ops = &ath5k_common_ops; - common->ah = sc->ah; - common->hw = hw; - common->cachelsz = csz << 2; /* convert to bytes */ - spin_lock_init(&common->cc_lock); - - /* Initialize device */ - ret = ath5k_hw_attach(sc); - if (ret) { - goto err_free_ah; - } - - /* set up multi-rate retry capabilities */ - if (sc->ah->ah_version == AR5K_AR5212) { - hw->max_rates = 4; - hw->max_rate_tries = 11; - } - - hw->vif_data_size = sizeof(struct ath5k_vif); - - /* Finish private driver data initialization */ - ret = ath5k_attach(pdev, hw); - if (ret) - goto err_ah; - - ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", - ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), - sc->ah->ah_mac_srev, - sc->ah->ah_phy_revision); - - if (!sc->ah->ah_single_chip) { - /* Single chip radio (!RF5111) */ - if (sc->ah->ah_radio_5ghz_revision && - !sc->ah->ah_radio_2ghz_revision) { - /* No 5GHz support -> report 2GHz radio */ - if (!test_bit(AR5K_MODE_11A, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* No 2GHz support (5110 and some - * 5Ghz only cards) -> report 5Ghz radio */ - } else if (!test_bit(AR5K_MODE_11B, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* Multiband radio */ - } else { - ATH5K_INFO(sc, "RF%s multiband radio found" - " (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - } - } - /* Multi chip radio (RF5111 - RF2111) -> - * report both 2GHz/5GHz radios */ - else if (sc->ah->ah_radio_5ghz_revision && - sc->ah->ah_radio_2ghz_revision){ - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_2ghz_revision), - sc->ah->ah_radio_2ghz_revision); - } - } - - ath5k_debug_init_device(sc); - - /* ready to process interrupts */ - __clear_bit(ATH_STAT_INVALID, sc->status); + /* Set private data */ + pci_set_drvdata(pdev, hw); return 0; -err_ah: - ath5k_hw_detach(sc->ah); -err_free_ah: - kfree(sc->ah); -err_irq: - free_irq(pdev->irq, sc); err_free: ieee80211_free_hw(hw); err_map: @@ -3707,17 +3766,14 @@ err: static void __devexit ath5k_pci_remove(struct pci_dev *pdev) { - struct ath5k_softc *sc = pci_get_drvdata(pdev); + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct ath5k_softc *sc = hw->priv; - ath5k_debug_finish_device(sc); - ath5k_detach(pdev, sc->hw); - ath5k_hw_detach(sc->ah); - kfree(sc->ah); - free_irq(pdev->irq, sc); + ath5k_deinit_softc(sc); pci_iounmap(pdev, sc->iobase); pci_release_region(pdev, 0); pci_disable_device(pdev); - ieee80211_free_hw(sc->hw); + ieee80211_free_hw(hw); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 0362f8eb9510..aa6c32aafb59 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -172,6 +172,7 @@ struct ath5k_softc { struct pci_dev *pdev; struct device *dev; /* for dma mapping */ int irq; + u16 devid; void __iomem *iobase; /* address of the device */ struct mutex lock; /* dev-level lock */ struct ieee80211_hw *hw; /* IEEE 802.11 common */ diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 033eab9ad4e7..a648957501e2 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -208,7 +208,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) * * XXX: Serdes values seem to be fixed so * no need to read them here, we write them - * during ath5k_hw_attach */ + * during ath5k_hw_init */ AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? true : false; -- cgit v1.2.3-59-g8ed1b From e5b046d86fac609f636d127a38de94a175c7e83b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:01 +0100 Subject: ath5k: Move PCI bus functions to separate file. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/Makefile | 1 + drivers/net/wireless/ath/ath5k/ath5k.h | 3 + drivers/net/wireless/ath/ath5k/base.c | 267 +----------------------------- drivers/net/wireless/ath/ath5k/pci.c | 284 ++++++++++++++++++++++++++++++++ 4 files changed, 289 insertions(+), 266 deletions(-) create mode 100644 drivers/net/wireless/ath/ath5k/pci.c diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 2242a140e4fe..dae881cd7dd1 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -15,4 +15,5 @@ ath5k-y += rfkill.o ath5k-y += ani.o ath5k-y += sysfs.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o +ath5k-y += pci.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index a74f448f7d72..ee3c0af3ab3c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1145,6 +1145,7 @@ struct ath5k_hw { /* * Prototypes */ +extern const struct ieee80211_ops ath5k_hw_ops; /* Initialization and detach functions */ int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops); @@ -1155,6 +1156,8 @@ void ath5k_hw_deinit(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); +/*Chip id helper function */ +const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); /* LED functions */ int ath5k_init_leds(struct ath5k_softc *sc); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b11ea3d2872d..9fcc4e14d1e5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -47,8 +47,6 @@ #include #include #include -#include -#include #include #include #include @@ -87,30 +85,6 @@ static int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); -/* Known PCI ids */ -static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { - { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ - { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ - { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ - { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ - { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ - { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ - { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ - { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ - { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ - { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ - { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ - { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); - /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, @@ -193,32 +167,6 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; -/* return bus cachesize in 4B word units */ -static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) -{ - struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; - u8 u8tmp; - - pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); - *csz = (int)u8tmp; - - /* - * This check was put in to avoid "unplesant" consequences if - * the bootrom has not fully initialized all PCI devices. - * Sometimes the cache line size register is not set - */ - - if (*csz == 0) - *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ -} - -/* Common ath_bus_opts structure */ -static const struct ath_bus_ops ath_pci_bus_ops = { - .ath_bus_type = ATH_PCI, - .read_cachesize = ath5k_pci_read_cachesize, -}; - - static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { @@ -261,7 +209,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) return (tsf & ~0x7fff) | rstamp; } -static const char * +const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) { const char *name = "xxxxx"; @@ -3627,216 +3575,3 @@ const struct ieee80211_ops ath5k_hw_ops = { .set_antenna = ath5k_set_antenna, .get_antenna = ath5k_get_antenna, }; - -/********************\ -* PCI Initialization * -\********************/ - -static int __devinit -ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - void __iomem *mem; - struct ath5k_softc *sc; - struct ieee80211_hw *hw; - int ret; - u8 csz; - - /* - * L0s needs to be disabled on all ath5k cards. - * - * For distributions shipping with CONFIG_PCIEASPM (this will be enabled - * by default in the future in 2.6.36) this will also mean both L1 and - * L0s will be disabled when a pre 1.1 PCIe device is detected. We do - * know L1 works correctly even for all ath5k pre 1.1 PCIe devices - * though but cannot currently undue the effect of a blacklist, for - * details you can read pcie_aspm_sanity_check() and see how it adjusts - * the device link capability. - * - * It may be possible in the future to implement some PCI API to allow - * drivers to override blacklists for pre 1.1 PCIe but for now it is - * best to accept that both L0s and L1 will be disabled completely for - * distributions shipping with CONFIG_PCIEASPM rather than having this - * issue present. Motivation for adding this new API will be to help - * with power consumption for some of these devices. - */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "can't enable device\n"); - goto err; - } - - /* XXX 32-bit addressing only */ - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "32-bit DMA not available\n"); - goto err_dis; - } - - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); - if (csz == 0) { - /* - * Linux 2.4.18 (at least) writes the cache line size - * register as a 16-bit wide register which is wrong. - * We must have this setup properly for rx buffer - * DMA to work so force a reasonable value here if it - * comes up zero. - */ - csz = L1_CACHE_BYTES >> 2; - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); - } - /* - * The default setting of latency timer yields poor results, - * set it to the value used by other systems. It may be worth - * tweaking this setting more. - */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); - - /* Enable bus mastering */ - pci_set_master(pdev); - - /* - * Disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, 0x41, 0); - - ret = pci_request_region(pdev, 0, "ath5k"); - if (ret) { - dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); - goto err_dis; - } - - mem = pci_iomap(pdev, 0, 0); - if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; - ret = -EIO; - goto err_reg; - } - - /* - * Allocate hw (mac80211 main struct) - * and hw->priv (driver private data) - */ - hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); - ret = -ENOMEM; - goto err_map; - } - - dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - - sc = hw->priv; - sc->hw = hw; - sc->pdev = pdev; - sc->dev = &pdev->dev; - sc->irq = pdev->irq; - sc->devid = id->device; - sc->iobase = mem; /* So we can unmap it on detach */ - - /* Initialize */ - ret = ath5k_init_softc(sc, &ath_pci_bus_ops); - if (ret) { - goto err_free; - } - - /* Set private data */ - pci_set_drvdata(pdev, hw); - - return 0; -err_free: - ieee80211_free_hw(hw); -err_map: - pci_iounmap(pdev, mem); -err_reg: - pci_release_region(pdev, 0); -err_dis: - pci_disable_device(pdev); -err: - return ret; -} - -static void __devexit -ath5k_pci_remove(struct pci_dev *pdev) -{ - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_softc *sc = hw->priv; - - ath5k_deinit_softc(sc); - pci_iounmap(pdev, sc->iobase); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - ieee80211_free_hw(hw); -} - -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev) -{ - struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); - - ath5k_led_off(sc); - return 0; -} - -static int ath5k_pci_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ath5k_softc *sc = pci_get_drvdata(pdev); - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state - */ - pci_write_config_byte(pdev, 0x41, 0); - - ath5k_led_enable(sc); - return 0; -} - -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); -#define ATH5K_PM_OPS (&ath5k_pm_ops) -#else -#define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ - -static struct pci_driver ath5k_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ath5k_pci_id_table, - .probe = ath5k_pci_probe, - .remove = __devexit_p(ath5k_pci_remove), - .driver.pm = ATH5K_PM_OPS, -}; - -/* - * Module init/exit functions - */ -static int __init -init_ath5k_pci(void) -{ - int ret; - - ret = pci_register_driver(&ath5k_pci_driver); - if (ret) { - printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); - return ret; - } - - return 0; -} - -static void __exit -exit_ath5k_pci(void) -{ - pci_unregister_driver(&ath5k_pci_driver); -} - -module_init(init_ath5k_pci); -module_exit(exit_ath5k_pci); diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c new file mode 100644 index 000000000000..9f7d3ca6ea21 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "../ath.h" +#include "ath5k.h" +#include "debug.h" +#include "base.h" +#include "reg.h" + +/* Known PCI ids */ +static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { + { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ + { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ + { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ + { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ + { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ + { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ + { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ + { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ + { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ + { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ + { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ + { 0 } +}; + +/* return bus cachesize in 4B word units */ +static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) +{ + struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; + u8 u8tmp; + + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); + *csz = (int)u8tmp; + + /* + * This check was put in to avoid "unplesant" consequences if + * the bootrom has not fully initialized all PCI devices. + * Sometimes the cache line size register is not set + */ + + if (*csz == 0) + *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ +} + +/* Common ath_bus_opts structure */ +static const struct ath_bus_ops ath_pci_bus_ops = { + .ath_bus_type = ATH_PCI, + .read_cachesize = ath5k_pci_read_cachesize, +}; + +/********************\ +* PCI Initialization * +\********************/ + +static int __devinit +ath5k_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + void __iomem *mem; + struct ath5k_softc *sc; + struct ieee80211_hw *hw; + int ret; + u8 csz; + + /* + * L0s needs to be disabled on all ath5k cards. + * + * For distributions shipping with CONFIG_PCIEASPM (this will be enabled + * by default in the future in 2.6.36) this will also mean both L1 and + * L0s will be disabled when a pre 1.1 PCIe device is detected. We do + * know L1 works correctly even for all ath5k pre 1.1 PCIe devices + * though but cannot currently undue the effect of a blacklist, for + * details you can read pcie_aspm_sanity_check() and see how it adjusts + * the device link capability. + * + * It may be possible in the future to implement some PCI API to allow + * drivers to override blacklists for pre 1.1 PCIe but for now it is + * best to accept that both L0s and L1 will be disabled completely for + * distributions shipping with CONFIG_PCIEASPM rather than having this + * issue present. Motivation for adding this new API will be to help + * with power consumption for some of these devices. + */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "can't enable device\n"); + goto err; + } + + /* XXX 32-bit addressing only */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "32-bit DMA not available\n"); + goto err_dis; + } + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); + if (csz == 0) { + /* + * Linux 2.4.18 (at least) writes the cache line size + * register as a 16-bit wide register which is wrong. + * We must have this setup properly for rx buffer + * DMA to work so force a reasonable value here if it + * comes up zero. + */ + csz = L1_CACHE_BYTES >> 2; + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); + } + /* + * The default setting of latency timer yields poor results, + * set it to the value used by other systems. It may be worth + * tweaking this setting more. + */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); + + /* Enable bus mastering */ + pci_set_master(pdev); + + /* + * Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, 0x41, 0); + + ret = pci_request_region(pdev, 0, "ath5k"); + if (ret) { + dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); + goto err_dis; + } + + mem = pci_iomap(pdev, 0, 0); + if (!mem) { + dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; + ret = -EIO; + goto err_reg; + } + + /* + * Allocate hw (mac80211 main struct) + * and hw->priv (driver private data) + */ + hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); + ret = -ENOMEM; + goto err_map; + } + + dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); + + sc = hw->priv; + sc->hw = hw; + sc->pdev = pdev; + sc->dev = &pdev->dev; + sc->irq = pdev->irq; + sc->devid = id->device; + sc->iobase = mem; /* So we can unmap it on detach */ + + /* Initialize */ + ret = ath5k_init_softc(sc, &ath_pci_bus_ops); + if (ret) + goto err_free; + + /* Set private data */ + pci_set_drvdata(pdev, hw); + + return 0; +err_free: + ieee80211_free_hw(hw); +err_map: + pci_iounmap(pdev, mem); +err_reg: + pci_release_region(pdev, 0); +err_dis: + pci_disable_device(pdev); +err: + return ret; +} + +static void __devexit +ath5k_pci_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct ath5k_softc *sc = hw->priv; + + ath5k_deinit_softc(sc); + pci_iounmap(pdev, sc->iobase); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + ieee80211_free_hw(hw); +} + +#ifdef CONFIG_PM_SLEEP +static int ath5k_pci_suspend(struct device *dev) +{ + struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); + + ath5k_led_off(sc); + return 0; +} + +static int ath5k_pci_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ath5k_softc *sc = pci_get_drvdata(pdev); + + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state + */ + pci_write_config_byte(pdev, 0x41, 0); + + ath5k_led_enable(sc); + return 0; +} + +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); +#define ATH5K_PM_OPS (&ath5k_pm_ops) +#else +#define ATH5K_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver ath5k_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = ath5k_pci_id_table, + .probe = ath5k_pci_probe, + .remove = __devexit_p(ath5k_pci_remove), + .driver.pm = ATH5K_PM_OPS, +}; + +/* + * Module init/exit functions + */ +static int __init +init_ath5k_pci(void) +{ + int ret; + + ret = pci_register_driver(&ath5k_pci_driver); + if (ret) { + printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); + return ret; + } + + return 0; +} + +static void __exit +exit_ath5k_pci(void) +{ + pci_unregister_driver(&ath5k_pci_driver); +} + +module_init(init_ath5k_pci); +module_exit(exit_ath5k_pci); -- cgit v1.2.3-59-g8ed1b From 4aa5d783c9e1c72e4950ff34f388077ccecac74a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:01 +0100 Subject: ath5k: Use generic eeprom read from common ath_bus_opts struct. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 6 ++++++ drivers/net/wireless/ath/ath5k/eeprom.c | 38 ++------------------------------- drivers/net/wireless/ath/ath5k/eeprom.h | 2 +- drivers/net/wireless/ath/ath5k/pci.c | 36 +++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ee3c0af3ab3c..5d9fdc2ccfaa 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1342,6 +1342,12 @@ static inline void ath5k_read_cachesize(struct ath_common *common, int *csz) common->bus_ops->read_cachesize(common, csz); } +static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data) +{ + struct ath_common *common = ath5k_hw_common(ah); + return common->bus_ops->eeprom_read(common, off, data); +} + static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) { u32 retval = 0, bit, i; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index a648957501e2..97eaa9a4415e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -65,40 +65,6 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, * Parsers * \*********/ -/* - * Read from eeprom - */ -static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) -{ - u32 status, timeout; - - /* - * Initialize EEPROM access - */ - if (ah->ah_version == AR5K_AR5210) { - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); - (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); - } else { - ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); - AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, - AR5K_EEPROM_CMD_READ); - } - - for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { - status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); - if (status & AR5K_EEPROM_STAT_RDDONE) { - if (status & AR5K_EEPROM_STAT_RDERR) - return -EIO; - *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & - 0xffff); - return 0; - } - udelay(15); - } - - return -ETIMEDOUT; -} - /* * Initialize eeprom & capabilities structs */ @@ -1769,12 +1735,12 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) u16 data; int octet, ret; - ret = ath5k_hw_eeprom_read(ah, 0x20, &data); + ret = ath5k_hw_nvram_read(ah, 0x20, &data); if (ret) return ret; for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - ret = ath5k_hw_eeprom_read(ah, offset, &data); + ret = ath5k_hw_nvram_read(ah, offset, &data); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index c4a6d5f26af4..0017006be841 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -241,7 +241,7 @@ enum ath5k_eeprom_freq_bands{ #define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250 #define AR5K_EEPROM_READ(_o, _v) do { \ - ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \ + ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \ if (ret) \ return ret; \ } while (0) diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 9f7d3ca6ea21..3f26cf200196 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -65,10 +65,46 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ } +/* + * Read from eeprom + */ +bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) +{ + struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; + u32 status, timeout; + + /* + * Initialize EEPROM access + */ + if (ah->ah_version == AR5K_AR5210) { + AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); + (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); + } else { + ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); + AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, + AR5K_EEPROM_CMD_READ); + } + + for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { + status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); + if (status & AR5K_EEPROM_STAT_RDDONE) { + if (status & AR5K_EEPROM_STAT_RDERR) + return -EIO; + *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & + 0xffff); + return 0; + } + udelay(15); + } + + return -ETIMEDOUT; +} + /* Common ath_bus_opts structure */ static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath5k_pci_read_cachesize, + .eeprom_read = ath5k_pci_eeprom_read, }; /********************\ -- cgit v1.2.3-59-g8ed1b From 8efa5d7d6ad307ae2d220def37ca89594062c40d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:06 +0100 Subject: ath5k: Check if pci pdev struct is initialized in common functions. To be able to support other busses than PCI check if pci device structure is initialized. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 5 ++--- drivers/net/wireless/ath/ath5k/led.c | 5 ++++- drivers/net/wireless/ath/ath5k/reset.c | 4 ++-- drivers/net/wireless/ath/ath5k/sysfs.c | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index a84782a63e0a..86f6fec069e8 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -273,7 +273,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) /* * Write PCI-E power save settings */ - if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { + if ((ah->ah_version == AR5K_AR5212) && pdev && (pdev->is_pcie)) { ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); @@ -305,8 +305,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) /* Get misc capabilities */ ret = ath5k_hw_set_capabilities(ah); if (ret) { - ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", - sc->pdev->device); + ATH5K_ERR(sc, "unable to get device capabilities\n"); goto err; } diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 67aa52e9bf94..1f5a991aa0a9 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -133,7 +133,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led, led->led_dev.default_trigger = trigger; led->led_dev.brightness_set = ath5k_led_brightness_set; - err = led_classdev_register(&sc->pdev->dev, &led->led_dev); + err = led_classdev_register(sc->dev, &led->led_dev); if (err) { ATH5K_WARN(sc, "could not register LED %s\n", name); led->sc = NULL; @@ -165,6 +165,9 @@ int ath5k_init_leds(struct ath5k_softc *sc) char name[ATH5K_LED_MAX_NAME_LEN + 1]; const struct pci_device_id *match; + if (!sc->pdev) + return 0; + match = pci_match_id(&ath5k_led_devices[0], pdev); if (match) { __set_bit(ATH_STAT_LEDSOFT, sc->status); diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 7d8ef8decf00..f2f889d0cf59 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -471,7 +471,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ - bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; + bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; if (ah->ah_version == AR5K_AR5210) { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | @@ -526,7 +526,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ - bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; + bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; if (ah->ah_version == AR5K_AR5210) { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 90757de7bf59..929c68cdf8ab 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c @@ -95,7 +95,7 @@ static struct attribute_group ath5k_attribute_group_ani = { int ath5k_sysfs_register(struct ath5k_softc *sc) { - struct device *dev = &sc->pdev->dev; + struct device *dev = sc->dev; int err; err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani); @@ -110,7 +110,7 @@ ath5k_sysfs_register(struct ath5k_softc *sc) void ath5k_sysfs_unregister(struct ath5k_softc *sc) { - struct device *dev = &sc->pdev->dev; + struct device *dev = sc->dev; sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani); } -- cgit v1.2.3-59-g8ed1b From e7aecd327d80b2f156b54769013aaccb2a20645a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:06 +0100 Subject: ath5k: Add a function to read chipset's MAC revision Add bus dependent revision read function which is used to determine chipset's MAC before hardware is initialized. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 4 +++- drivers/net/wireless/ath/ath5k/attach.c | 11 +++++++---- drivers/net/wireless/ath/ath5k/pci.c | 6 ++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 5d9fdc2ccfaa..5e525eba61be 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1046,6 +1046,7 @@ struct ath5k_hw { u32 ah_phy; u32 ah_mac_srev; u16 ah_mac_version; + u16 ah_mac_revision; u16 ah_phy_revision; u16 ah_radio_5ghz_revision; u16 ah_radio_2ghz_revision; @@ -1156,8 +1157,9 @@ void ath5k_hw_deinit(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); -/*Chip id helper function */ +/*Chip id helper functions */ const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); +int ath5k_hw_read_srev(struct ath5k_hw *ah); /* LED functions */ int ath5k_init_leds(struct ath5k_softc *sc); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 86f6fec069e8..9dbc1fa81795 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -128,7 +128,8 @@ int ath5k_hw_init(struct ath5k_softc *sc) /* * Find the mac version */ - srev = ath5k_hw_reg_read(ah, AR5K_SREV); + ath5k_hw_read_srev(ah); + srev = ah->ah_mac_srev; if (srev < AR5K_SREV_AR5311) ah->ah_version = AR5K_AR5210; else if (srev < AR5K_SREV_AR5212) @@ -136,6 +137,10 @@ int ath5k_hw_init(struct ath5k_softc *sc) else ah->ah_version = AR5K_AR5212; + /* Get the MAC revision */ + ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); + ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); + /* Fill the ath5k_hw struct with the needed functions */ ret = ath5k_hw_init_desc_functions(ah); if (ret) @@ -146,9 +151,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) if (ret) goto err; - /* Get MAC, PHY and RADIO revisions */ - ah->ah_mac_srev = srev; - ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); + /* Get PHY and RADIO revisions */ ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 0xffffffff; ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 3f26cf200196..39f033128c5a 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -100,6 +100,12 @@ bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) return -ETIMEDOUT; } +int ath5k_hw_read_srev(struct ath5k_hw *ah) +{ + ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV); + return 0; +} + /* Common ath_bus_opts structure */ static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, -- cgit v1.2.3-59-g8ed1b From c31b5c9c806b1fbdc9e98885d897664a0d482989 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:11 +0100 Subject: ath5k: Add initial registers values for radio RF2317 chip. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/initvals.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c index 905e4fdffc6d..e49340d18df4 100644 --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c @@ -1495,6 +1495,29 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu) rf5112_ini_bbgain, skip_pcu); break; case AR5K_RF2317: + + ath5k_hw_ini_mode_registers(ah, + ARRAY_SIZE(rf2413_ini_mode_end), + rf2413_ini_mode_end, mode); + + ath5k_hw_ini_registers(ah, + ARRAY_SIZE(rf2425_ini_common_end), + rf2425_ini_common_end, skip_pcu); + + /* Override settings from rf2413_ini_mode_end */ + ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN); + + /* Override settings from rf2413_ini_common_end */ + ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5, + AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa); + ath5k_hw_reg_write(ah, 0x800000a8, 0x8140); + ath5k_hw_reg_write(ah, 0x000000ff, 0x9958); + + ath5k_hw_ini_registers(ah, + ARRAY_SIZE(rf5112_ini_bbgain), + rf5112_ini_bbgain, skip_pcu); + break; case AR5K_RF2425: ath5k_hw_ini_mode_registers(ah, -- cgit v1.2.3-59-g8ed1b From a0b907ee2a71052fefdf6151764095f3f97b3275 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:16 +0100 Subject: ath5k: Add AHB bus support. AHB specific functions are now in ahb.c file. AHB bus is compiled in when CONFIG_ATHEROS_AR231X is set in kernel. All other platforms will use PCI bus. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/Kconfig | 17 ++- drivers/net/wireless/ath/ath5k/Makefile | 3 +- drivers/net/wireless/ath/ath5k/ahb.c | 219 ++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath5k/ath5k.h | 40 ++++++ drivers/net/wireless/ath/ath5k/base.c | 16 ++- drivers/net/wireless/ath/ath5k/led.c | 6 + drivers/net/wireless/ath/ath5k/reg.h | 25 ++++ 7 files changed, 322 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/ath/ath5k/ahb.c diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index 47844575caa3..e0793319389d 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig @@ -1,10 +1,12 @@ config ATH5K tristate "Atheros 5xxx wireless cards support" - depends on PCI && MAC80211 + depends on (PCI || ATHEROS_AR231X) && MAC80211 select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS select AVERAGE + select ATH5K_AHB if (ATHEROS_AR231X && !PCI) + select ATH5K_PCI if (!ATHEROS_AR231X && PCI) ---help--- This module adds support for wireless adapters based on Atheros 5xxx chipset. @@ -38,3 +40,16 @@ config ATH5K_DEBUG modprobe ath5k debug=0x00000400 +config ATH5K_AHB + bool "Atheros 5xxx AHB bus support" + depends on (ATHEROS_AR231X && !PCI) + ---help--- + This adds support for WiSoC type chipsets of the 5xxx Atheros + family. + +config ATH5K_PCI + bool "Atheros 5xxx PCI bus support" + depends on (!ATHEROS_AR231X && PCI) + ---help--- + This adds support for PCI type chipsets of the 5xxx Atheros + family. diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index dae881cd7dd1..67dd9fd0650e 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -15,5 +15,6 @@ ath5k-y += rfkill.o ath5k-y += ani.o ath5k-y += sysfs.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o -ath5k-y += pci.o +ath5k-$(CONFIG_ATH5K_AHB) += ahb.o +ath5k-$(CONFIG_ATH5K_PCI) += pci.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c new file mode 100644 index 000000000000..707cde149248 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2009 Gabor Juhos + * Copyright (c) 2009 Imre Kaloz + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "ath5k.h" +#include "debug.h" +#include "base.h" +#include "reg.h" +#include "debug.h" + +/* return bus cachesize in 4B word units */ +static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) +{ + *csz = L1_CACHE_BYTES >> 2; +} + +bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) +{ + struct ath5k_softc *sc = common->priv; + struct platform_device *pdev = to_platform_device(sc->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; + u16 *eeprom, *eeprom_end; + + + + bcfg = pdev->dev.platform_data; + eeprom = (u16 *) bcfg->radio; + eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; + + eeprom += off; + if (eeprom > eeprom_end) + return -EINVAL; + + *data = *eeprom; + return 0; +} + +int ath5k_hw_read_srev(struct ath5k_hw *ah) +{ + struct ath5k_softc *sc = ah->ah_sc; + struct platform_device *pdev = to_platform_device(sc->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; + ah->ah_mac_srev = bcfg->devid; + return 0; +} + +static const struct ath_bus_ops ath_ahb_bus_ops = { + .ath_bus_type = ATH_AHB, + .read_cachesize = ath5k_ahb_read_cachesize, + .eeprom_read = ath5k_ahb_eeprom_read, +}; + +/*Initialization*/ +static int ath_ahb_probe(struct platform_device *pdev) +{ + struct ar231x_board_config *bcfg = pdev->dev.platform_data; + struct ath5k_softc *sc; + struct ieee80211_hw *hw; + struct resource *res; + void __iomem *mem; + int irq; + int ret = 0; + u32 reg; + + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "no platform data specified\n"); + ret = -EINVAL; + goto err_out; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no memory resource found\n"); + ret = -ENXIO; + goto err_out; + } + + mem = ioremap_nocache(res->start, res->end - res->start + 1); + if (mem == NULL) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -ENOMEM; + goto err_out; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no IRQ resource found\n"); + ret = -ENXIO; + goto err_out; + } + + irq = res->start; + + hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); + ret = -ENOMEM; + goto err_out; + } + + sc = hw->priv; + sc->hw = hw; + sc->dev = &pdev->dev; + sc->iobase = mem; + sc->irq = irq; + sc->devid = bcfg->devid; + + if (bcfg->devid >= AR5K_SREV_AR2315_R6) { + /* Enable WMAC AHB arbitration */ + reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; + __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + + /* Enable global WMAC swapping */ + reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP); + reg |= AR5K_AR2315_BYTESWAP_WMAC; + __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); + } else { + /* Enable WMAC DMA access (assuming 5312 or 231x*/ + /* TODO: check other platforms */ + reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); + if (to_platform_device(sc->dev)->id == 0) + reg |= AR5K_AR5312_ENABLE_WLAN0; + else + reg |= AR5K_AR5312_ENABLE_WLAN1; + __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + } + + ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); + if (ret != 0) { + dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); + ret = -ENODEV; + goto err_free_hw; + } + + platform_set_drvdata(pdev, hw); + + return 0; + + err_free_hw: + ieee80211_free_hw(hw); + platform_set_drvdata(pdev, NULL); + err_out: + return ret; +} + +static int ath_ahb_remove(struct platform_device *pdev) +{ + struct ar231x_board_config *bcfg = pdev->dev.platform_data; + struct ieee80211_hw *hw = platform_get_drvdata(pdev); + struct ath5k_softc *sc; + u32 reg; + + if (!hw) + return 0; + + sc = hw->priv; + + if (bcfg->devid >= AR5K_SREV_AR2315_R6) { + /* Disable WMAC AHB arbitration */ + reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; + __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + } else { + /*Stop DMA access */ + reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); + if (to_platform_device(sc->dev)->id == 0) + reg &= ~AR5K_AR5312_ENABLE_WLAN0; + else + reg &= ~AR5K_AR5312_ENABLE_WLAN1; + __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + } + + ath5k_deinit_softc(sc); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver ath_ahb_driver = { + .probe = ath_ahb_probe, + .remove = ath_ahb_remove, + .driver = { + .name = "ar231x-wmac", + .owner = THIS_MODULE, + }, +}; + +static int __init +ath5k_ahb_init(void) +{ + return platform_driver_register(&ath_ahb_driver); +} + +static void __exit +ath5k_ahb_exit(void) +{ + platform_driver_unregister(&ath_ahb_driver); +} + +module_init(ath5k_ahb_init); +module_exit(ath5k_ahb_exit); diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 5e525eba61be..d6e744088bc6 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -319,12 +319,19 @@ struct ath5k_srev_name { #define AR5K_SREV_AR5311B 0x30 /* Spirit */ #define AR5K_SREV_AR5211 0x40 /* Oahu */ #define AR5K_SREV_AR5212 0x50 /* Venice */ +#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */ #define AR5K_SREV_AR5212_V4 0x54 /* ??? */ #define AR5K_SREV_AR5213 0x55 /* ??? */ +#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */ +#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */ #define AR5K_SREV_AR5213A 0x59 /* Hainan */ #define AR5K_SREV_AR2413 0x78 /* Griffin lite */ #define AR5K_SREV_AR2414 0x70 /* Griffin */ +#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */ +#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */ #define AR5K_SREV_AR5424 0x90 /* Condor */ +#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */ +#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */ #define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ #define AR5K_SREV_AR5414 0xa0 /* Eagle */ #define AR5K_SREV_AR2415 0xb0 /* Talon */ @@ -1329,6 +1336,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) return &(ath5k_hw_common(ah)->regulatory); } +#ifdef CONFIG_ATHEROS_AR231X +#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) + +static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) +{ + /* On AR2315 and AR2317 the PCI clock domain registers + * are outside of the WMAC register space */ + if (unlikely((reg >= 0x4000) && (reg < 0x5000) && + (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) + return AR5K_AR2315_PCI_BASE + reg; + + return ah->ah_iobase + reg; +} + +static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) +{ + return __raw_readl(ath5k_ahb_reg(ah, reg)); +} + +static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) +{ + __raw_writel(val, ath5k_ahb_reg(ah, reg)); +} + +#else + static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) { return ioread32(ah->ah_iobase + reg); @@ -1339,6 +1372,13 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) iowrite32(val, ah->ah_iobase + reg); } +#endif + +static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) +{ + return ath5k_hw_common(ah)->bus_ops->ath_bus_type; +} + static inline void ath5k_read_cachesize(struct ath_common *common, int *csz) { common->bus_ops->read_cachesize(common, csz); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9fcc4e14d1e5..685de2d75725 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -87,6 +87,15 @@ static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { +#ifdef CONFIG_ATHEROS_AR231X + { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, + { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, + { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, + { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, + { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, + { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, + { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, +#else { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, @@ -105,6 +114,7 @@ static const struct ath5k_srev_name srev_names[] = { { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, +#endif { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, @@ -118,10 +128,12 @@ static const struct ath5k_srev_name srev_names[] = { { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, - { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, - { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, +#ifdef CONFIG_ATHEROS_AR231X + { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, + { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, +#endif { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, }; diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 1f5a991aa0a9..576edf2965dc 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -161,14 +161,20 @@ int ath5k_init_leds(struct ath5k_softc *sc) { int ret = 0; struct ieee80211_hw *hw = sc->hw; +#ifndef CONFIG_ATHEROS_AR231X struct pci_dev *pdev = sc->pdev; +#endif char name[ATH5K_LED_MAX_NAME_LEN + 1]; const struct pci_device_id *match; if (!sc->pdev) return 0; +#ifdef CONFIG_ATHEROS_AR231X + match = NULL; +#else match = pci_match_id(&ath5k_led_devices[0], pdev); +#endif if (match) { __set_bit(ATH_STAT_LEDSOFT, sc->status); sc->led_pin = ATH_PIN(match->driver_data); diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 8516728a407e..7ad05d401ab5 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2562,3 +2562,28 @@ */ #define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280 #define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2)) + +/* + * Platform registers for WiSoC + */ +#define AR5K_AR5312_RESET 0xbc003020 +#define AR5K_AR5312_RESET_BB0_COLD 0x00000004 +#define AR5K_AR5312_RESET_BB1_COLD 0x00000200 +#define AR5K_AR5312_RESET_WMAC0 0x00002000 +#define AR5K_AR5312_RESET_BB0_WARM 0x00004000 +#define AR5K_AR5312_RESET_WMAC1 0x00020000 +#define AR5K_AR5312_RESET_BB1_WARM 0x00040000 + +#define AR5K_AR5312_ENABLE 0xbc003080 +#define AR5K_AR5312_ENABLE_WLAN0 0x00000001 +#define AR5K_AR5312_ENABLE_WLAN1 0x00000008 + +#define AR5K_AR2315_RESET 0xb1000004 +#define AR5K_AR2315_RESET_WMAC 0x00000001 +#define AR5K_AR2315_RESET_BB_WARM 0x00000002 + +#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008 +#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002 + +#define AR5K_AR2315_BYTESWAP 0xb100000c +#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002 -- cgit v1.2.3-59-g8ed1b From 4cebb34caa5122216a1e2451eae9e0fc47ec2589 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 10:27:21 +0100 Subject: ath5k: Fix reset and interrupts for AHB type of devices. On WiSoc we cannot access mac register before it is resetted. It will crash hardware otherwise. Signed-off-by: Felix Fietkau Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 ++- drivers/net/wireless/ath/ath5k/reset.c | 103 +++++++++++++++++++++++++++++---- 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 685de2d75725..0a7071a6dd7a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2148,7 +2148,8 @@ ath5k_intr(int irq, void *dev_id) unsigned int counter = 1000; if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || - !ath5k_hw_is_intr_pending(ah))) + ((ath5k_get_bus_type(ah) != ATH_AHB) && + !ath5k_hw_is_intr_pending(ah)))) return IRQ_NONE; do { @@ -2214,6 +2215,10 @@ ath5k_intr(int irq, void *dev_id) tasklet_schedule(&sc->rf_kill.toggleq); } + + if (ath5k_get_bus_type(ah) == ATH_AHB) + break; + } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); if (unlikely(!counter)) diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index f2f889d0cf59..bc84aaa31446 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -27,6 +27,7 @@ #include /* To determine if a card is pci-e */ #include +#include #include "ath5k.h" #include "reg.h" #include "base.h" @@ -141,7 +142,9 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) /* Set 32MHz USEC counter */ if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413)) + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2316) || + (ah->ah_radio == AR5K_RF2317)) /* Remain on 40MHz clock ? */ sclock = 40 - 1; else @@ -244,6 +247,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) if ((ah->ah_radio == AR5K_RF5112) || (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2316) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) spending = 0x14; else @@ -299,6 +303,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) if ((ah->ah_radio == AR5K_RF5112) || (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2316) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) spending = 0x14; else @@ -357,6 +362,64 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) return ret; } +/* + * Reset AHB chipset + * AR5K_RESET_CTL_PCU flag resets WMAC + * AR5K_RESET_CTL_BASEBAND flag resets WBB + */ +static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) +{ + u32 mask = flags ? flags : ~0U; + volatile u32 *reg; + u32 regval; + u32 val = 0; + + /* ah->ah_mac_srev is not available at this point yet */ + if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) { + reg = (u32 *) AR5K_AR2315_RESET; + if (mask & AR5K_RESET_CTL_PCU) + val |= AR5K_AR2315_RESET_WMAC; + if (mask & AR5K_RESET_CTL_BASEBAND) + val |= AR5K_AR2315_RESET_BB_WARM; + } else { + reg = (u32 *) AR5K_AR5312_RESET; + if (to_platform_device(ah->ah_sc->dev)->id == 0) { + if (mask & AR5K_RESET_CTL_PCU) + val |= AR5K_AR5312_RESET_WMAC0; + if (mask & AR5K_RESET_CTL_BASEBAND) + val |= AR5K_AR5312_RESET_BB0_COLD | + AR5K_AR5312_RESET_BB0_WARM; + } else { + if (mask & AR5K_RESET_CTL_PCU) + val |= AR5K_AR5312_RESET_WMAC1; + if (mask & AR5K_RESET_CTL_BASEBAND) + val |= AR5K_AR5312_RESET_BB1_COLD | + AR5K_AR5312_RESET_BB1_WARM; + } + } + + /* Put BB/MAC into reset */ + regval = __raw_readl(reg); + __raw_writel(regval | val, reg); + regval = __raw_readl(reg); + udelay(100); + + /* Bring BB/MAC out of reset */ + __raw_writel(regval & ~val, reg); + regval = __raw_readl(reg); + + /* + * Reset configuration register (for hw byte-swap). Note that this + * is only set for big endian. We do the necessary magic in + * AR5K_INIT_CFG. + */ + if ((flags & AR5K_RESET_CTL_PCU) == 0) + ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); + + return 0; +} + + /* * Sleep control */ @@ -456,6 +519,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) u32 bus_flags; int ret; + if (ath5k_get_bus_type(ah) == ATH_AHB) + return 0; + /* Make sure device is awake */ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); if (ret) { @@ -511,11 +577,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) mode = 0; clock = 0; - /* Wakeup the device */ - ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); - if (ret) { - ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); - return ret; + if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) { + /* Wakeup the device */ + ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); + if (ret) { + ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); + return ret; + } } /* @@ -534,8 +602,12 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); mdelay(2); } else { - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_BASEBAND | bus_flags); + if (ath5k_get_bus_type(ah) == ATH_AHB) + ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU | + AR5K_RESET_CTL_BASEBAND); + else + ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | + AR5K_RESET_CTL_BASEBAND | bus_flags); } if (ret) { @@ -550,9 +622,15 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) return ret; } - /* ...clear reset control register and pull device out of - * warm reset */ - if (ath5k_hw_nic_reset(ah, 0)) { + /* ...reset configuration regiter on Wisoc ... + * ...clear reset control register and pull device out of + * warm reset on others */ + if (ath5k_get_bus_type(ah) == ATH_AHB) + ret = ath5k_hw_wisoc_reset(ah, 0); + else + ret = ath5k_hw_nic_reset(ah, 0); + + if (ret) { ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n"); return -EIO; } @@ -708,7 +786,8 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, /* Set fast ADC */ if ((ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { + (ah->ah_radio == AR5K_RF2317) || + (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { u32 fast_adc = true; if (channel->center_freq == 2462 || -- cgit v1.2.3-59-g8ed1b From 8339a7ed562719e040ca783bf59fa2d614d10ac9 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Mon, 29 Nov 2010 18:11:52 +0000 Subject: can: EG20T PCH: Separate Interface Register(IF1/IF2) CAN register of Intel PCH EG20T has 2 sets of interface register. To reduce whole of code size, separate interface register. As a result, the number of function also can be reduced. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 445 +++++++++++++++++++++------------------------- 1 file changed, 201 insertions(+), 244 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 238622a04bc1..dae8ed19630e 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -113,6 +113,11 @@ #define PCH_FIFO_THRESH 16 +enum pch_ifreg { + PCH_RX_IFREG, + PCH_TX_IFREG, +}; + enum pch_can_mode { PCH_CAN_ENABLE, PCH_CAN_DISABLE, @@ -122,6 +127,21 @@ enum pch_can_mode { PCH_CAN_RUN }; +struct pch_can_if_regs { + u32 creq; + u32 cmask; + u32 mask1; + u32 mask2; + u32 id1; + u32 id2; + u32 mcont; + u32 dataa1; + u32 dataa2; + u32 datab1; + u32 datab2; + u32 rsv[13]; +}; + struct pch_can_regs { u32 cont; u32 stat; @@ -130,38 +150,21 @@ struct pch_can_regs { u32 intr; u32 opt; u32 brpe; - u32 reserve1; - u32 if1_creq; - u32 if1_cmask; - u32 if1_mask1; - u32 if1_mask2; - u32 if1_id1; - u32 if1_id2; - u32 if1_mcont; - u32 if1_dataa1; - u32 if1_dataa2; - u32 if1_datab1; - u32 if1_datab2; - u32 reserve2; - u32 reserve3[12]; - u32 if2_creq; - u32 if2_cmask; - u32 if2_mask1; - u32 if2_mask2; - u32 if2_id1; - u32 if2_id2; - u32 if2_mcont; - u32 if2_dataa1; - u32 if2_dataa2; - u32 if2_datab1; - u32 if2_datab2; - u32 reserve4; - u32 reserve5[20]; + u32 reserve; + struct pch_can_if_regs ifregs[2]; /* [0]=if1 [1]=if2 */ + u32 reserve1[8]; u32 treq1; u32 treq2; - u32 reserve6[2]; - u32 reserve7[56]; - u32 reserve8[3]; + u32 reserve2[6]; + u32 data1; + u32 data2; + u32 reserve3[6]; + u32 canipend1; + u32 canipend2; + u32 reserve4[6]; + u32 canmval1; + u32 canmval2; + u32 reserve5[37]; u32 srst; }; @@ -303,143 +306,87 @@ static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num) pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__); } -static void pch_can_set_rx_enable(struct pch_can_priv *priv, u32 buff_num, - u32 set) +static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, + u32 set, enum pch_ifreg dir) { unsigned long flags; + u32 ie; + + if (dir) + ie = PCH_IF_MCONT_TXIE; + else + ie = PCH_IF_MCONT_RXIE; spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the receive buffer data from RAM to Interface1 registers */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if1_cmask); + &priv->regs->ifregs[dir].cmask); if (set == PCH_ENABLE) { /* Setting the MsgVal and RxIE bits */ - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); - pch_can_bit_set(&priv->regs->if1_id2, PCH_ID_MSGVAL); + pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie); + pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); } else if (set == PCH_DISABLE) { /* Resetting the MsgVal and RxIE bits */ - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID_MSGVAL); + pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie); + pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); } - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } -static void pch_can_rx_enable_all(struct pch_can_priv *priv) -{ - int i; - - /* Traversing to obtain the object configured as receivers. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, PCH_ENABLE); - } -} -static void pch_can_rx_disable_all(struct pch_can_priv *priv) +static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set) { int i; /* Traversing to obtain the object configured as receivers. */ for (i = 0; i < PCH_OBJ_NUM; i++) { if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, PCH_DISABLE); - } -} - -static void pch_can_set_tx_enable(struct pch_can_priv *priv, u32 buff_num, - u32 set) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->msgif_reg_lock, flags); - /* Reading the Msg buffer from Message RAM to Interface2 registers. */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); - - /* Setting the IF2CMASK register for accessing the - MsgVal and TxIE bits */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if2_cmask); - - if (set == PCH_ENABLE) { - /* Setting the MsgVal and TxIE bits */ - pch_can_bit_set(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID_MSGVAL); - } else if (set == PCH_DISABLE) { - /* Resetting the MsgVal and TxIE bits. */ - pch_can_bit_clear(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID_MSGVAL); - } - - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); -} - -static void pch_can_tx_enable_all(struct pch_can_priv *priv) -{ - int i; - - /* Traversing to obtain the object configured as transmit object. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, PCH_ENABLE); + pch_can_set_rxtx(priv, i + 1, set, PCH_RX_IFREG); } } -static void pch_can_tx_disable_all(struct pch_can_priv *priv) +static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) { int i; /* Traversing to obtain the object configured as transmit object. */ for (i = 0; i < PCH_OBJ_NUM; i++) { if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, PCH_DISABLE); + pch_can_set_rxtx(priv, i + 1, set, PCH_TX_IFREG); } } -static void pch_can_get_rx_enable(struct pch_can_priv *priv, u32 buff_num, - u32 *enable) +static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, + enum pch_ifreg dir) { unsigned long flags; + u32 ie, enable; - spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); - - if (((ioread32(&priv->regs->if1_id2)) & PCH_ID_MSGVAL) && - ((ioread32(&priv->regs->if1_mcont)) & - PCH_IF_MCONT_RXIE)) - *enable = PCH_ENABLE; + if (dir) + ie = PCH_IF_MCONT_RXIE; else - *enable = PCH_DISABLE; - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); -} - -static void pch_can_get_tx_enable(struct pch_can_priv *priv, u32 buff_num, - u32 *enable) -{ - unsigned long flags; + ie = PCH_IF_MCONT_TXIE; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); - if (((ioread32(&priv->regs->if2_id2)) & PCH_ID_MSGVAL) && - ((ioread32(&priv->regs->if2_mcont)) & - PCH_IF_MCONT_TXIE)) { - *enable = PCH_ENABLE; + if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && + ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { + enable = PCH_ENABLE; } else { - *enable = PCH_DISABLE; + enable = PCH_DISABLE; } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); + return enable; } static int pch_can_int_pending(struct pch_can_priv *priv) @@ -453,15 +400,17 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->if1_cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, + &priv->regs->ifregs[0].cmask); if (set == PCH_ENABLE) - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_EOB); else - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -471,10 +420,10 @@ static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); - if (ioread32(&priv->regs->if1_mcont) & PCH_IF_MCONT_EOB) + if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) *link = PCH_DISABLE; else *link = PCH_ENABLE; @@ -486,37 +435,37 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) int i; for (i = 0; i < PCH_RX_OBJ_NUM; i++) { - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if1_cmask); - iowrite32(0xffff, &priv->regs->if1_mask1); - iowrite32(0xffff, &priv->regs->if1_mask2); - iowrite32(0x0, &priv->regs->if1_id1); - iowrite32(0x0, &priv->regs->if1_id2); - iowrite32(0x0, &priv->regs->if1_mcont); - iowrite32(0x0, &priv->regs->if1_dataa1); - iowrite32(0x0, &priv->regs->if1_dataa2); - iowrite32(0x0, &priv->regs->if1_datab1); - iowrite32(0x0, &priv->regs->if1_datab2); + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask); + iowrite32(0xffff, &priv->regs->ifregs[0].mask1); + iowrite32(0xffff, &priv->regs->ifregs[0].mask2); + iowrite32(0x0, &priv->regs->ifregs[0].id1); + iowrite32(0x0, &priv->regs->ifregs[0].id2); + iowrite32(0x0, &priv->regs->ifregs[0].mcont); + iowrite32(0x0, &priv->regs->ifregs[0].dataa1); + iowrite32(0x0, &priv->regs->ifregs[0].dataa2); + iowrite32(0x0, &priv->regs->ifregs[0].datab1); + iowrite32(0x0, &priv->regs->ifregs[0].datab2); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, i+1); + &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); } for (i = i; i < PCH_OBJ_NUM; i++) { - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if2_cmask); - iowrite32(0xffff, &priv->regs->if2_mask1); - iowrite32(0xffff, &priv->regs->if2_mask2); - iowrite32(0x0, &priv->regs->if2_id1); - iowrite32(0x0, &priv->regs->if2_id2); - iowrite32(0x0, &priv->regs->if2_mcont); - iowrite32(0x0, &priv->regs->if2_dataa1); - iowrite32(0x0, &priv->regs->if2_dataa2); - iowrite32(0x0, &priv->regs->if2_datab1); - iowrite32(0x0, &priv->regs->if2_datab2); + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[1].cmask); + iowrite32(0xffff, &priv->regs->ifregs[1].mask1); + iowrite32(0xffff, &priv->regs->ifregs[1].mask2); + iowrite32(0x0, &priv->regs->ifregs[1].id1); + iowrite32(0x0, &priv->regs->ifregs[1].id2); + iowrite32(0x0, &priv->regs->ifregs[1].mcont); + iowrite32(0x0, &priv->regs->ifregs[1].dataa1); + iowrite32(0x0, &priv->regs->ifregs[1].dataa2); + iowrite32(0x0, &priv->regs->ifregs[1].datab1); + iowrite32(0x0, &priv->regs->ifregs[1].datab2); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, i+1); + &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); } } @@ -530,58 +479,60 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) for (i = 0; i < PCH_OBJ_NUM; i++) { if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, i+1); + &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); - iowrite32(0x0, &priv->regs->if1_id1); - iowrite32(0x0, &priv->regs->if1_id2); + iowrite32(0x0, &priv->regs->ifregs[0].id1); + iowrite32(0x0, &priv->regs->ifregs[0].id2); - pch_can_bit_set(&priv->regs->if1_mcont, + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_UMASK); /* Set FIFO mode set to 0 except last Rx Obj*/ - pch_can_bit_clear(&priv->regs->if1_mcont, + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ if (i == (PCH_RX_OBJ_NUM - 1)) - pch_can_bit_set(&priv->regs->if1_mcont, + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); - iowrite32(0, &priv->regs->if1_mask1); - pch_can_bit_clear(&priv->regs->if1_mask2, + iowrite32(0, &priv->regs->ifregs[0].mask1); + pch_can_bit_clear(&priv->regs->ifregs[0].mask2, 0x1fff | PCH_MASK2_MDIR_MXTD); /* Setting CMASK for writing */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if1_cmask); + &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, i+1); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); } else if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, i+1); + &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); /* Resetting DIR bit for reception */ - iowrite32(0x0, &priv->regs->if2_id1); - iowrite32(0x0, &priv->regs->if2_id2); - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID2_DIR); + iowrite32(0x0, &priv->regs->ifregs[1].id1); + iowrite32(0x0, &priv->regs->ifregs[1].id2); + pch_can_bit_set(&priv->regs->ifregs[1].id2, + PCH_ID2_DIR); /* Setting EOB bit for transmitter */ - iowrite32(PCH_IF_MCONT_EOB, &priv->regs->if2_mcont); + iowrite32(PCH_IF_MCONT_EOB, + &priv->regs->ifregs[1].mcont); - pch_can_bit_set(&priv->regs->if2_mcont, + pch_can_bit_set(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_UMASK); - iowrite32(0, &priv->regs->if2_mask1); - pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff); + iowrite32(0, &priv->regs->ifregs[1].mask1); + pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); /* Setting CMASK for writing */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->if2_cmask); + &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, i+1); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); } } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -611,10 +562,10 @@ static void pch_can_release(struct pch_can_priv *priv) pch_can_set_int_enables(priv, PCH_CAN_NONE); /* Disabling all the receive object. */ - pch_can_rx_disable_all(priv); + pch_can_set_rx_all(priv, 0); /* Disabling all the transmit object. */ - pch_can_tx_disable_all(priv); + pch_can_set_tx_all(priv, 0); } /* This function clears interrupt(s) from the CAN device. */ @@ -630,31 +581,31 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) /* Setting CMASK for clearing interrupts for frame transmission. */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, - &priv->regs->if2_cmask); + &priv->regs->ifregs[1].cmask); /* Resetting the ID registers. */ - pch_can_bit_set(&priv->regs->if2_id2, + pch_can_bit_set(&priv->regs->ifregs[1].id2, PCH_ID2_DIR | (0x7ff << 2)); - iowrite32(0x0, &priv->regs->if2_id1); + iowrite32(0x0, &priv->regs->ifregs[1].id1); /* Claring NewDat, TxRqst & IntPnd */ - pch_can_bit_clear(&priv->regs->if2_mcont, + pch_can_bit_clear(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | PCH_IF_MCONT_TXRQXT); - pch_can_check_if_busy(&priv->regs->if2_creq, mask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, mask); } else if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_RX) { /* Setting CMASK for clearing the reception interrupts. */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, - &priv->regs->if1_cmask); + &priv->regs->ifregs[0].cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); /* Clearing NewDat & IntPnd */ - pch_can_bit_clear(&priv->regs->if1_mcont, + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); - pch_can_check_if_busy(&priv->regs->if1_creq, mask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, mask); } } @@ -685,8 +636,8 @@ static void pch_can_error(struct net_device *ndev, u32 status) return; if (status & PCH_BUS_OFF) { - pch_can_tx_disable_all(priv); - pch_can_rx_disable_all(priv); + pch_can_set_tx_all(priv, 0); + pch_can_set_rx_all(priv, 0); state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; can_bus_off(ndev); @@ -783,22 +734,22 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) struct net_device_stats *stats = &(priv->ndev->stats); /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, int_stat); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, int_stat); /* Reading the MCONT register. */ - reg = ioread32(&priv->regs->if1_mcont); + reg = ioread32(&priv->regs->ifregs[0].mcont); reg &= 0xffff; for (k = int_stat; !(reg & PCH_IF_MCONT_EOB); k++) { /* If MsgLost bit set. */ if (reg & PCH_IF_MCONT_MSGLOST) { dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n"); - pch_can_bit_clear(&priv->regs->if1_mcont, + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_MSGLOST); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, - &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, k); + &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); skb = alloc_can_err_skb(ndev, &cf); if (!skb) @@ -824,29 +775,30 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) return -ENOMEM; /* Get Received data */ - ide = ((ioread32(&priv->regs->if1_id2)) & PCH_ID2_XTD) >> 14; + ide = ((ioread32(&priv->regs->ifregs[0].id2)) & PCH_ID2_XTD) >> + 14; if (ide) { - id = (ioread32(&priv->regs->if1_id1) & 0xffff); - id |= (((ioread32(&priv->regs->if1_id2)) & + id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff); + id |= (((ioread32(&priv->regs->ifregs[0].id2)) & 0x1fff) << 16); cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; } else { - id = (((ioread32(&priv->regs->if1_id2)) & - (CAN_SFF_MASK << 2)) >> 2); + id = (((ioread32(&priv->regs->ifregs[0].id2)) & + (CAN_SFF_MASK << 2)) >> 2); cf->can_id = (id & CAN_SFF_MASK); } - rtr = (ioread32(&priv->regs->if1_id2) & PCH_ID2_DIR); + rtr = (ioread32(&priv->regs->ifregs[0].id2) & PCH_ID2_DIR); if (rtr) { cf->can_dlc = 0; cf->can_id |= CAN_RTR_FLAG; } else { - cf->can_dlc = ((ioread32(&priv->regs->if1_mcont)) & - 0x0f); + cf->can_dlc = ((ioread32(&priv->regs->ifregs[0].mcont)) + & 0x0f); } for (i = 0, j = 0; i < cf->can_dlc; j++) { - reg = ioread32(&priv->regs->if1_dataa1 + j*4); + reg = ioread32(&priv->regs->ifregs[0].dataa1 + j*4); cf->data[i++] = cpu_to_le32(reg & 0xff); if (i == cf->can_dlc) break; @@ -860,15 +812,16 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) if (k < PCH_FIFO_THRESH) { iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | - PCH_CMASK_ARB, &priv->regs->if1_cmask); + PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->ifregs[0].id2, + PCH_ID2_DIR); /* Clearing NewDat & IntPnd */ - pch_can_bit_clear(&priv->regs->if1_mcont, + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_INTPND); - pch_can_check_if_busy(&priv->regs->if1_creq, k); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); } else if (k > PCH_FIFO_THRESH) { pch_can_int_clr(priv, k); } else if (k == PCH_FIFO_THRESH) { @@ -878,9 +831,9 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) } RX_NEXT: /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); - pch_can_check_if_busy(&priv->regs->if1_creq, k + 1); - reg = ioread32(&priv->regs->if1_mcont); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k + 1); + reg = ioread32(&priv->regs->ifregs[0].mcont); } return rcv_pkts; @@ -910,8 +863,9 @@ INT_STAT: if (reg_stat & PCH_TX_OK) { spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, + iowrite32(PCH_CMASK_RX_TX_GET, + &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, ioread32(&priv->regs->intr)); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK); @@ -938,10 +892,11 @@ MSG_OBJ: can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1); spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, - &priv->regs->if2_cmask); - dlc = ioread32(&priv->regs->if2_mcont) & + &priv->regs->ifregs[1].cmask); + dlc = ioread32(&priv->regs->ifregs[1].mcont) & PCH_IF_MCONT_DLC; - pch_can_check_if_busy(&priv->regs->if2_creq, int_stat); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, + int_stat); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (dlc > 8) dlc = 8; @@ -996,8 +951,8 @@ static void pch_can_start(struct net_device *ndev) pch_set_bittiming(ndev); pch_can_set_optmode(priv); - pch_can_tx_enable_all(priv); - pch_can_rx_enable_all(priv); + pch_can_set_tx_all(priv, 1); + pch_can_set_rx_all(priv, 1); /* Setting the CAN to run mode. */ pch_can_set_run_mode(priv, PCH_CAN_RUN); @@ -1125,54 +1080,55 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the Msg Obj from the Msg RAM to the Interface register. */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); - pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); /* Setting the CMASK register. */ - pch_can_bit_set(&priv->regs->if2_cmask, PCH_CMASK_ALL); + pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); /* If ID extended is set. */ - pch_can_bit_clear(&priv->regs->if2_id1, 0xffff); - pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | PCH_ID2_XTD); + pch_can_bit_clear(&priv->regs->ifregs[1].id1, 0xffff); + pch_can_bit_clear(&priv->regs->ifregs[1].id2, 0x1fff | PCH_ID2_XTD); if (cf->can_id & CAN_EFF_FLAG) { - pch_can_bit_set(&priv->regs->if2_id1, cf->can_id & 0xffff); - pch_can_bit_set(&priv->regs->if2_id2, + pch_can_bit_set(&priv->regs->ifregs[1].id1, + cf->can_id & 0xffff); + pch_can_bit_set(&priv->regs->ifregs[1].id2, ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD); } else { - pch_can_bit_set(&priv->regs->if2_id1, 0); - pch_can_bit_set(&priv->regs->if2_id2, + pch_can_bit_set(&priv->regs->ifregs[1].id1, 0); + pch_can_bit_set(&priv->regs->ifregs[1].id2, (cf->can_id & CAN_SFF_MASK) << 2); } /* If remote frame has to be transmitted.. */ if (cf->can_id & CAN_RTR_FLAG) - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); for (i = 0, j = 0; i < cf->can_dlc; j++) { iowrite32(le32_to_cpu(cf->data[i++]), - (&priv->regs->if2_dataa1) + j*4); + (&priv->regs->ifregs[1].dataa1) + j*4); if (i == cf->can_dlc) break; iowrite32(le32_to_cpu(cf->data[i++] << 8), - (&priv->regs->if2_dataa1) + j*4); + (&priv->regs->ifregs[1].dataa1) + j*4); } can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_NUM - 1); /* Updating the size of the data. */ - pch_can_bit_clear(&priv->regs->if2_mcont, 0x0f); - pch_can_bit_set(&priv->regs->if2_mcont, cf->can_dlc); + pch_can_bit_clear(&priv->regs->ifregs[1].mcont, 0x0f); + pch_can_bit_set(&priv->regs->ifregs[1].mcont, cf->can_dlc); /* Clearing IntPend, NewDat & TxRqst */ - pch_can_bit_clear(&priv->regs->if2_mcont, + pch_can_bit_clear(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | PCH_IF_MCONT_TXRQXT); /* Setting NewDat, TxRqst bits */ - pch_can_bit_set(&priv->regs->if2_mcont, + pch_can_bit_set(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT); - pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -1234,25 +1190,25 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Tx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_get_tx_enable(priv, i + 1, - &(priv->tx_enable[i])); + priv->tx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1, + PCH_TX_IFREG); } /* Disable all Transmit buffers */ - pch_can_tx_disable_all(priv); + pch_can_set_tx_all(priv, 0); /* Save Rx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { - pch_can_get_rx_enable(priv, i + 1, - &(priv->rx_enable[i])); + priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1, + PCH_RX_IFREG); pch_can_get_rx_buffer_link(priv, i + 1, &(priv->rx_link[i])); } } /* Disable all Receive buffers */ - pch_can_rx_disable_all(priv); + pch_can_set_rx_all(priv, 0); retval = pci_save_state(pdev); if (retval) { dev_err(&pdev->dev, "pci_save_state failed.\n"); @@ -1301,10 +1257,9 @@ static int pch_can_resume(struct pci_dev *pdev) /* Enabling the transmit buffer. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { - pch_can_set_tx_enable(priv, i + 1, - priv->tx_enable[i]); - } + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) + pch_can_set_rxtx(priv, i, priv->tx_enable[i], + PCH_TX_IFREG); } /* Configuring the receive buffer and enabling them. */ @@ -1315,7 +1270,9 @@ static int pch_can_resume(struct pci_dev *pdev) priv->rx_link[i]); /* Restore buffer enables */ - pch_can_set_rx_enable(priv, i + 1, priv->rx_enable[i]); + pch_can_set_rxtx(priv, i, priv->rx_enable[i], + PCH_RX_IFREG); + } } -- cgit v1.2.3-59-g8ed1b From 15ffc8fddf72712cc45d51c64bd500760ec63c80 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Mon, 29 Nov 2010 18:15:02 +0000 Subject: can: EG20T PCH: Change Message Object Index For easy to readable, add Message Object index like below. PCH_RX_OBJ_START PCH_RX_OBJ_END PCH_TX_OBJ_START PCH_TX_OBJ_END Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 263 ++++++++++++++++++++-------------------------- 1 file changed, 116 insertions(+), 147 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index dae8ed19630e..982ff2d757a8 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -32,10 +32,6 @@ #include #include -#define PCH_MAX_MSG_OBJ 32 -#define PCH_MSG_OBJ_RX 0 /* The receive message object flag. */ -#define PCH_MSG_OBJ_TX 1 /* The transmit message object flag. */ - #define PCH_ENABLE 1 /* The enable flag */ #define PCH_DISABLE 0 /* The disable flag */ #define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */ @@ -107,9 +103,12 @@ /* Define the number of message object. * PCH CAN communications are done via Message RAM. * The Message RAM consists of 32 message objects. */ -#define PCH_RX_OBJ_NUM 26 /* 1~ PCH_RX_OBJ_NUM is Rx*/ -#define PCH_TX_OBJ_NUM 6 /* PCH_RX_OBJ_NUM is RX ~ Tx*/ -#define PCH_OBJ_NUM (PCH_TX_OBJ_NUM + PCH_RX_OBJ_NUM) +#define PCH_RX_OBJ_NUM 26 +#define PCH_TX_OBJ_NUM 6 +#define PCH_RX_OBJ_START 1 +#define PCH_RX_OBJ_END PCH_RX_OBJ_NUM +#define PCH_TX_OBJ_START (PCH_RX_OBJ_END + 1) +#define PCH_TX_OBJ_END (PCH_RX_OBJ_NUM + PCH_TX_OBJ_NUM) #define PCH_FIFO_THRESH 16 @@ -172,14 +171,14 @@ struct pch_can_priv { struct can_priv can; unsigned int can_num; struct pci_dev *dev; - unsigned int tx_enable[PCH_MAX_MSG_OBJ]; - unsigned int rx_enable[PCH_MAX_MSG_OBJ]; - unsigned int rx_link[PCH_MAX_MSG_OBJ]; + int tx_enable[PCH_TX_OBJ_END]; + int rx_enable[PCH_TX_OBJ_END]; + int rx_link[PCH_TX_OBJ_END]; unsigned int int_enables; unsigned int int_stat; struct net_device *ndev; spinlock_t msgif_reg_lock; /* Message Interface Registers Access Lock*/ - unsigned int msg_obj[PCH_MAX_MSG_OBJ]; + unsigned int msg_obj[PCH_TX_OBJ_END]; struct pch_can_regs __iomem *regs; struct napi_struct napi; unsigned int tx_obj; /* Point next Tx Obj index */ @@ -347,10 +346,8 @@ static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set) int i; /* Traversing to obtain the object configured as receivers. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) - pch_can_set_rxtx(priv, i + 1, set, PCH_RX_IFREG); - } + for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) + pch_can_set_rxtx(priv, i, set, PCH_RX_IFREG); } static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) @@ -358,10 +355,8 @@ static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) int i; /* Traversing to obtain the object configured as transmit object. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_rxtx(priv, i + 1, set, PCH_TX_IFREG); - } + for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) + pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG); } static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, @@ -381,9 +376,9 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { - enable = PCH_ENABLE; + enable = 1; } else { - enable = PCH_DISABLE; + enable = 0; } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); return enable; @@ -434,7 +429,7 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) { int i; - for (i = 0; i < PCH_RX_OBJ_NUM; i++) { + for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask); iowrite32(0xffff, &priv->regs->ifregs[0].mask1); iowrite32(0xffff, &priv->regs->ifregs[0].mask2); @@ -448,10 +443,10 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); } - for (i = i; i < PCH_OBJ_NUM; i++) { + for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[1].cmask); iowrite32(0xffff, &priv->regs->ifregs[1].mask1); iowrite32(0xffff, &priv->regs->ifregs[1].mask2); @@ -465,7 +460,7 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); } } @@ -476,64 +471,62 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) spin_lock_irqsave(&priv->msgif_reg_lock, flags); - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { - iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); + for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { + iowrite32(PCH_CMASK_RX_TX_GET, + &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); - iowrite32(0x0, &priv->regs->ifregs[0].id1); - iowrite32(0x0, &priv->regs->ifregs[0].id2); + iowrite32(0x0, &priv->regs->ifregs[0].id1); + iowrite32(0x0, &priv->regs->ifregs[0].id2); - pch_can_bit_set(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_UMASK); + pch_can_bit_set(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_UMASK); - /* Set FIFO mode set to 0 except last Rx Obj*/ - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + /* Set FIFO mode set to 0 except last Rx Obj*/ + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_EOB); + /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ + if (i == PCH_RX_OBJ_END) + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); - /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ - if (i == (PCH_RX_OBJ_NUM - 1)) - pch_can_bit_set(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_EOB); - - iowrite32(0, &priv->regs->ifregs[0].mask1); - pch_can_bit_clear(&priv->regs->ifregs[0].mask2, - 0x1fff | PCH_MASK2_MDIR_MXTD); - - /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1); - } else if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { - iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); + iowrite32(0, &priv->regs->ifregs[0].mask1); + pch_can_bit_clear(&priv->regs->ifregs[0].mask2, + 0x1fff | PCH_MASK2_MDIR_MXTD); - /* Resetting DIR bit for reception */ - iowrite32(0x0, &priv->regs->ifregs[1].id1); - iowrite32(0x0, &priv->regs->ifregs[1].id2); - pch_can_bit_set(&priv->regs->ifregs[1].id2, - PCH_ID2_DIR); + /* Setting CMASK for writing */ + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, + &priv->regs->ifregs[0].cmask); - /* Setting EOB bit for transmitter */ - iowrite32(PCH_IF_MCONT_EOB, - &priv->regs->ifregs[1].mcont); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); + } - pch_can_bit_set(&priv->regs->ifregs[1].mcont, - PCH_IF_MCONT_UMASK); + for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { + iowrite32(PCH_CMASK_RX_TX_GET, + &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); - iowrite32(0, &priv->regs->ifregs[1].mask1); - pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); + /* Resetting DIR bit for reception */ + iowrite32(0x0, &priv->regs->ifregs[1].id1); + iowrite32(0x0, &priv->regs->ifregs[1].id2); + pch_can_bit_set(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); - /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->ifregs[1].cmask); + /* Setting EOB bit for transmitter */ + iowrite32(PCH_IF_MCONT_EOB, &priv->regs->ifregs[1].mcont); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1); - } + pch_can_bit_set(&priv->regs->ifregs[1].mcont, + PCH_IF_MCONT_UMASK); + + iowrite32(0, &priv->regs->ifregs[1].mask1); + pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); + + /* Setting CMASK for writing */ + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | + PCH_CMASK_ARB | PCH_CMASK_CTRL, + &priv->regs->ifregs[1].cmask); + + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -577,7 +570,20 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) } /* Clear interrupt for transmit object */ - if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_TX) { + if ((mask >= PCH_RX_OBJ_START) && (mask <= PCH_RX_OBJ_END)) { + /* Setting CMASK for clearing the reception interrupts. */ + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, + &priv->regs->ifregs[0].cmask); + + /* Clearing the Dir bit. */ + pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); + + /* Clearing NewDat & IntPnd */ + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); + + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, mask); + } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) { /* Setting CMASK for clearing interrupts for frame transmission. */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, @@ -593,19 +599,6 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | PCH_IF_MCONT_TXRQXT); pch_can_check_if_busy(&priv->regs->ifregs[1].creq, mask); - } else if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_RX) { - /* Setting CMASK for clearing the reception interrupts. */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, - &priv->regs->ifregs[0].cmask); - - /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); - - /* Clearing NewDat & IntPnd */ - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); - - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, mask); } } @@ -793,8 +786,8 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) cf->can_dlc = 0; cf->can_id |= CAN_RTR_FLAG; } else { - cf->can_dlc = ((ioread32(&priv->regs->ifregs[0].mcont)) - & 0x0f); + cf->can_dlc = + ((ioread32(&priv->regs->ifregs[0].mcont)) & 0x0f); } for (i = 0, j = 0; i < cf->can_dlc; j++) { @@ -832,7 +825,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) RX_NEXT: /* Reading the messsage object from the Message RAM */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k + 1); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); reg = ioread32(&priv->regs->ifregs[0].mcont); } @@ -880,29 +873,27 @@ INT_STAT: } MSG_OBJ: - if ((int_stat >= 1) && (int_stat <= PCH_RX_OBJ_NUM)) { + if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { spin_lock_irqsave(&priv->msgif_reg_lock, flags); rcv_pkts = pch_can_rx_normal(ndev, int_stat); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (rcv_pkts < 0) return 0; - } else if ((int_stat > PCH_RX_OBJ_NUM) && (int_stat <= PCH_OBJ_NUM)) { - if (priv->msg_obj[int_stat - 1] == PCH_MSG_OBJ_TX) { - /* Handle transmission interrupt */ - can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1); - spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, - &priv->regs->ifregs[1].cmask); - dlc = ioread32(&priv->regs->ifregs[1].mcont) & - PCH_IF_MCONT_DLC; - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, - int_stat); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); - if (dlc > 8) - dlc = 8; - stats->tx_bytes += dlc; - stats->tx_packets++; - } + } else if ((int_stat >= PCH_TX_OBJ_START) && + (int_stat <= PCH_TX_OBJ_END)) { + /* Handle transmission interrupt */ + can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); + spin_lock_irqsave(&priv->msgif_reg_lock, flags); + iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, + &priv->regs->ifregs[1].cmask); + dlc = ioread32(&priv->regs->ifregs[1].mcont) & + PCH_IF_MCONT_DLC; + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, int_stat); + spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); + if (dlc > 8) + dlc = 8; + stats->tx_bytes += dlc; + stats->tx_packets++; } int_stat = pch_can_int_pending(priv); @@ -1064,12 +1055,12 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; - if (priv->tx_obj == (PCH_OBJ_NUM + 1)) { /* Point tail Obj */ + if (priv->tx_obj == PCH_TX_OBJ_END) { /* Point tail Obj */ while (pch_get_msg_obj_sts(ndev, (((1 << PCH_TX_OBJ_NUM)-1) << PCH_RX_OBJ_NUM))) udelay(500); - priv->tx_obj = PCH_RX_OBJ_NUM + 1; /* Point head of Tx Obj ID */ + priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj ID */ tx_buffer_avail = priv->tx_obj; /* Point Tail of Tx Obj */ } else { tx_buffer_avail = priv->tx_obj; @@ -1113,7 +1104,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) (&priv->regs->ifregs[1].dataa1) + j*4); } - can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_NUM - 1); + can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_END - 1); /* Updating the size of the data. */ pch_can_bit_clear(&priv->regs->ifregs[1].mcont, 0x0f); @@ -1188,23 +1179,16 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) pch_can_set_int_enables(priv, PCH_CAN_DISABLE); /* Save Tx buffer enable state */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - priv->tx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1, - PCH_TX_IFREG); - } + for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) + priv->tx_enable[i] = pch_can_get_rxtx_ir(priv, i, PCH_TX_IFREG); /* Disable all Transmit buffers */ pch_can_set_tx_all(priv, 0); /* Save Rx buffer enable state */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { - priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1, - PCH_RX_IFREG); - pch_can_get_rx_buffer_link(priv, i + 1, - &(priv->rx_link[i])); - } + for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { + priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i, PCH_RX_IFREG); + pch_can_get_rx_buffer_link(priv, i, &priv->rx_link[i]); } /* Disable all Receive buffers */ @@ -1256,24 +1240,16 @@ static int pch_can_resume(struct pci_dev *pdev) pch_can_set_optmode(priv); /* Enabling the transmit buffer. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_rxtx(priv, i, priv->tx_enable[i], - PCH_TX_IFREG); - } + for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) + pch_can_set_rxtx(priv, i, priv->tx_enable[i], PCH_TX_IFREG); /* Configuring the receive buffer and enabling them. */ - for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { - /* Restore buffer link */ - pch_can_set_rx_buffer_link(priv, i + 1, - priv->rx_link[i]); + for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { + /* Restore buffer link */ + pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i]); - /* Restore buffer enables */ - pch_can_set_rxtx(priv, i, priv->rx_enable[i], - PCH_RX_IFREG); - - } + /* Restore buffer enables */ + pch_can_set_rxtx(priv, i, priv->rx_enable[i], PCH_RX_IFREG); } /* Enable CAN Interrupts */ @@ -1306,7 +1282,6 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, struct net_device *ndev; struct pch_can_priv *priv; int rc; - int index; void __iomem *addr; rc = pci_enable_device(pdev); @@ -1328,7 +1303,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, goto probe_exit_ipmap; } - ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_NUM); + ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_END); if (!ndev) { rc = -ENOMEM; dev_err(&pdev->dev, "Failed alloc_candev\n"); @@ -1344,7 +1319,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, priv->can.do_get_berr_counter = pch_can_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_LOOPBACK; - priv->tx_obj = PCH_RX_OBJ_NUM + 1; /* Point head of Tx Obj */ + priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj */ ndev->irq = pdev->irq; ndev->flags |= IFF_ECHO; @@ -1352,15 +1327,9 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, ndev); SET_NETDEV_DEV(ndev, &pdev->dev); ndev->netdev_ops = &pch_can_netdev_ops; - priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ - for (index = 0; index < PCH_RX_OBJ_NUM;) - priv->msg_obj[index++] = PCH_MSG_OBJ_RX; - - for (index = index; index < PCH_OBJ_NUM;) - priv->msg_obj[index++] = PCH_MSG_OBJ_TX; - netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_NUM); + netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_END); rc = register_candev(ndev); if (rc) { -- cgit v1.2.3-59-g8ed1b From d68f6837c4972b0433e41f8bee4b2b8205610f31 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Mon, 29 Nov 2010 18:16:15 +0000 Subject: can: EG20T PCH: Enumerate LEC macros For easy to readable, LEC #define macros are replaced to enums. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 77 +++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 982ff2d757a8..2d4ab0fc9184 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -71,21 +71,12 @@ #define PCH_REC 0x00007f00 #define PCH_TEC 0x000000ff + #define PCH_TX_OK BIT(3) #define PCH_RX_OK BIT(4) #define PCH_EPASSIV BIT(5) #define PCH_EWARN BIT(6) #define PCH_BUS_OFF BIT(7) -#define PCH_LEC0 BIT(0) -#define PCH_LEC1 BIT(1) -#define PCH_LEC2 BIT(2) -#define PCH_LEC_ALL (PCH_LEC0 | PCH_LEC1 | PCH_LEC2) -#define PCH_STUF_ERR PCH_LEC0 -#define PCH_FORM_ERR PCH_LEC1 -#define PCH_ACK_ERR (PCH_LEC0 | PCH_LEC1) -#define PCH_BIT1_ERR PCH_LEC2 -#define PCH_BIT0_ERR (PCH_LEC0 | PCH_LEC2) -#define PCH_CRC_ERR (PCH_LEC1 | PCH_LEC2) /* bit position of certain controller bits. */ #define PCH_BIT_BRP 0 @@ -117,6 +108,16 @@ enum pch_ifreg { PCH_TX_IFREG, }; +enum pch_can_err { + PCH_STUF_ERR = 1, + PCH_FORM_ERR, + PCH_ACK_ERR, + PCH_BIT1_ERR, + PCH_BIT0_ERR, + PCH_CRC_ERR, + PCH_LEC_ALL, +}; + enum pch_can_mode { PCH_CAN_ENABLE, PCH_CAN_DISABLE, @@ -620,7 +621,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) struct sk_buff *skb; struct pch_can_priv *priv = netdev_priv(ndev); struct can_frame *cf; - u32 errc; + u32 errc, lec; struct net_device_stats *stats = &(priv->ndev->stats); enum can_state state = priv->can.state; @@ -665,33 +666,37 @@ static void pch_can_error(struct net_device *ndev, u32 status) "%s -> CAN controller is ERROR PASSIVE .\n", __func__); } - if (status & PCH_LEC_ALL) { + lec = status & PCH_LEC_ALL; + switch (lec) { + case PCH_STUF_ERR: + cf->data[2] |= CAN_ERR_PROT_STUFF; priv->can.can_stats.bus_error++; stats->rx_errors++; - switch (status & PCH_LEC_ALL) { - case PCH_STUF_ERR: - cf->data[2] |= CAN_ERR_PROT_STUFF; - break; - case PCH_FORM_ERR: - cf->data[2] |= CAN_ERR_PROT_FORM; - break; - case PCH_ACK_ERR: - cf->data[2] |= CAN_ERR_PROT_LOC_ACK | - CAN_ERR_PROT_LOC_ACK_DEL; - break; - case PCH_BIT1_ERR: - case PCH_BIT0_ERR: - cf->data[2] |= CAN_ERR_PROT_BIT; - break; - case PCH_CRC_ERR: - cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | - CAN_ERR_PROT_LOC_CRC_DEL; - break; - default: - iowrite32(status | PCH_LEC_ALL, &priv->regs->stat); - break; - } - + break; + case PCH_FORM_ERR: + cf->data[2] |= CAN_ERR_PROT_FORM; + priv->can.can_stats.bus_error++; + stats->rx_errors++; + break; + case PCH_ACK_ERR: + cf->can_id |= CAN_ERR_ACK; + priv->can.can_stats.bus_error++; + stats->rx_errors++; + break; + case PCH_BIT1_ERR: + case PCH_BIT0_ERR: + cf->data[2] |= CAN_ERR_PROT_BIT; + priv->can.can_stats.bus_error++; + stats->rx_errors++; + break; + case PCH_CRC_ERR: + cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | + CAN_ERR_PROT_LOC_CRC_DEL; + priv->can.can_stats.bus_error++; + stats->rx_errors++; + break; + case PCH_LEC_ALL: /* Written by CPU. No error status */ + break; } priv->can.state = state; -- cgit v1.2.3-59-g8ed1b From 2989042ca86b94bf4ffa9486921bb300ad44225f Mon Sep 17 00:00:00 2001 From: Tomoya Date: Mon, 29 Nov 2010 18:19:52 +0000 Subject: can: EG20T PCH: Delete unnecessary spin_lock Delete unnecessary spin_lock for accessing Message Object. Since all message objects are divided into tx/rx area completely, spin_lock processing is unnecessary. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 2d4ab0fc9184..a9b6a6525a65 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -71,7 +71,6 @@ #define PCH_REC 0x00007f00 #define PCH_TEC 0x000000ff - #define PCH_TX_OK BIT(3) #define PCH_RX_OK BIT(4) #define PCH_EPASSIV BIT(5) @@ -178,7 +177,6 @@ struct pch_can_priv { unsigned int int_enables; unsigned int int_stat; struct net_device *ndev; - spinlock_t msgif_reg_lock; /* Message Interface Registers Access Lock*/ unsigned int msg_obj[PCH_TX_OBJ_END]; struct pch_can_regs __iomem *regs; struct napi_struct napi; @@ -309,7 +307,6 @@ static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num) static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, u32 set, enum pch_ifreg dir) { - unsigned long flags; u32 ie; if (dir) @@ -317,7 +314,6 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, else ie = PCH_IF_MCONT_RXIE; - spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the receive buffer data from RAM to Interface1 registers */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); @@ -338,10 +334,8 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, } pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } - static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set) { int i; @@ -363,7 +357,6 @@ static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, enum pch_ifreg dir) { - unsigned long flags; u32 ie, enable; if (dir) @@ -371,7 +364,6 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, else ie = PCH_IF_MCONT_TXIE; - spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); @@ -381,7 +373,6 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, } else { enable = 0; } - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); return enable; } @@ -393,9 +384,6 @@ static int pch_can_int_pending(struct pch_can_priv *priv) static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num, u32 set) { - unsigned long flags; - - spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, @@ -407,15 +395,11 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num, u32 *link) { - unsigned long flags; - - spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); @@ -423,7 +407,6 @@ static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, *link = PCH_DISABLE; else *link = PCH_ENABLE; - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } static void pch_can_clear_buffers(struct pch_can_priv *priv) @@ -468,9 +451,6 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) { int i; - unsigned long flags; - - spin_lock_irqsave(&priv->msgif_reg_lock, flags); for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_GET, @@ -529,7 +509,6 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); } - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } static void pch_can_init(struct pch_can_priv *priv) @@ -845,7 +824,6 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) u32 int_stat; int rcv_pkts = 0; u32 reg_stat; - unsigned long flags; int_stat = pch_can_int_pending(priv); if (!int_stat) @@ -860,12 +838,10 @@ INT_STAT: } if (reg_stat & PCH_TX_OK) { - spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); pch_can_check_if_busy(&priv->regs->ifregs[1].creq, ioread32(&priv->regs->intr)); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK); } @@ -879,22 +855,18 @@ INT_STAT: MSG_OBJ: if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { - spin_lock_irqsave(&priv->msgif_reg_lock, flags); rcv_pkts = pch_can_rx_normal(ndev, int_stat); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (rcv_pkts < 0) return 0; } else if ((int_stat >= PCH_TX_OBJ_START) && (int_stat <= PCH_TX_OBJ_END)) { /* Handle transmission interrupt */ can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); - spin_lock_irqsave(&priv->msgif_reg_lock, flags); iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, &priv->regs->ifregs[1].cmask); dlc = ioread32(&priv->regs->ifregs[1].mcont) & PCH_IF_MCONT_DLC; pch_can_check_if_busy(&priv->regs->ifregs[1].creq, int_stat); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (dlc > 8) dlc = 8; stats->tx_bytes += dlc; @@ -1052,7 +1024,6 @@ static int pch_get_msg_obj_sts(struct net_device *ndev, u32 obj_id) static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) { int i, j; - unsigned long flags; struct pch_can_priv *priv = netdev_priv(ndev); struct can_frame *cf = (struct can_frame *)skb->data; int tx_buffer_avail = 0; @@ -1072,9 +1043,6 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) } priv->tx_obj++; - /* Attaining the lock. */ - spin_lock_irqsave(&priv->msgif_reg_lock, flags); - /* Reading the Msg Obj from the Msg RAM to the Interface register. */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); @@ -1126,8 +1094,6 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); - return NETDEV_TX_OK; } -- cgit v1.2.3-59-g8ed1b From a9527a3b621e507c85b639c183c3aa22afd4eb61 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 1 Dec 2010 18:04:43 +0000 Subject: net: snmp: fix the wrong ICMP_MIB_MAX value __ICMP_MIB_MAX is equal to the total number of icmp mib, So no need to add 1. This wastes 4/8 bytes memory. Change it to be same as ICMP6_MIB_MAX, TCP_MIB_MAX, UDP_MIB_MAX. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- include/net/snmp.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/net/snmp.h b/include/net/snmp.h index a0e61806d480..aebb55383c43 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -61,8 +61,7 @@ struct ipstats_mib { /* ICMP */ #define ICMP_MIB_DUMMY __ICMP_MIB_MAX -#define ICMP_MIB_MAX (__ICMP_MIB_MAX + 1) - +#define ICMP_MIB_MAX __ICMP_MIB_MAX struct icmp_mib { unsigned long mibs[ICMP_MIB_MAX]; }; -- cgit v1.2.3-59-g8ed1b From 97b1ce25e8fc27f74703537ec09d4996c7a6e38a Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 1 Dec 2010 18:04:50 +0000 Subject: tcp: use TCP_BASE_MSS to set basic mss value TCP_BASE_MSS is defined, but not used. commit 5d424d5a introduce this macro, so use it to initial sysctl_tcp_base_mss. commit 5d424d5a674f782d0659a3b66d951f412901faee Author: John Heffner Date: Mon Mar 20 17:53:41 2006 -0800 [TCP]: MTU probing Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5f29b2e20e23..749b6498588e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -55,7 +55,7 @@ int sysctl_tcp_workaround_signed_windows __read_mostly = 0; int sysctl_tcp_tso_win_divisor __read_mostly = 3; int sysctl_tcp_mtu_probing __read_mostly = 0; -int sysctl_tcp_base_mss __read_mostly = 512; +int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS; /* By default, RFC2861 behavior. */ int sysctl_tcp_slow_start_after_idle __read_mostly = 1; -- cgit v1.2.3-59-g8ed1b From b672083ed36a49c323737b7c7e1d5264a7c193af Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 1 Dec 2010 18:05:12 +0000 Subject: ipv6: use ND_REACHABLE_TIME and ND_RETRANS_TIMER instead of magic number ND_REACHABLE_TIME and ND_RETRANS_TIMER have defined since v2.6.12-rc2, but never been used. So use them instead of magic number. This patch also changes original code style to read comfortably . Thank YOSHIFUJI Hideaki for pointing it out. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 998d6d27e7cf..e18f84130203 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -141,18 +141,18 @@ struct neigh_table nd_tbl = { .proxy_redo = pndisc_redo, .id = "ndisc_cache", .parms = { - .tbl = &nd_tbl, - .base_reachable_time = 30 * HZ, - .retrans_time = 1 * HZ, - .gc_staletime = 60 * HZ, - .reachable_time = 30 * HZ, - .delay_probe_time = 5 * HZ, - .queue_len = 3, - .ucast_probes = 3, - .mcast_probes = 3, - .anycast_delay = 1 * HZ, - .proxy_delay = (8 * HZ) / 10, - .proxy_qlen = 64, + .tbl = &nd_tbl, + .base_reachable_time = ND_REACHABLE_TIME, + .retrans_time = ND_RETRANS_TIMER, + .gc_staletime = 60 * HZ, + .reachable_time = ND_REACHABLE_TIME, + .delay_probe_time = 5 * HZ, + .queue_len = 3, + .ucast_probes = 3, + .mcast_probes = 3, + .anycast_delay = 1 * HZ, + .proxy_delay = (8 * HZ) / 10, + .proxy_qlen = 64, }, .gc_interval = 30 * HZ, .gc_thresh1 = 128, -- cgit v1.2.3-59-g8ed1b From dca9b2404a6d6579828da2425c051462701efd3f Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 1 Dec 2010 18:05:17 +0000 Subject: net: kill unused macros from head file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These macros have been defined for several years since v2.6.12-rc2(tracing by git), but never be used. So remove them. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- include/net/addrconf.h | 2 -- include/net/ip6_route.h | 1 - include/net/ndisc.h | 3 --- include/net/snmp.h | 1 - include/net/sock.h | 3 --- include/net/tcp.h | 6 ------ 6 files changed, 16 deletions(-) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index a9441249306c..23710aa6a181 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -1,8 +1,6 @@ #ifndef _ADDRCONF_H #define _ADDRCONF_H -#define RETRANS_TIMER HZ - #define MAX_RTR_SOLICITATIONS 3 #define RTR_SOLICITATION_INTERVAL (4*HZ) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 67d154a3f31b..e06e0ca1e91b 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -3,7 +3,6 @@ #define IP6_RT_PRIO_USER 1024 #define IP6_RT_PRIO_ADDRCONF 256 -#define IP6_RT_PRIO_KERN 512 struct route_info { __u8 type; diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 895997bc2ead..e0e594f8e9d9 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -42,9 +42,6 @@ enum { #define ND_REACHABLE_TIME (30*HZ) #define ND_RETRANS_TIMER HZ -#define ND_MIN_RANDOM_FACTOR (1/2) -#define ND_MAX_RANDOM_FACTOR (3/2) - #ifdef __KERNEL__ #include diff --git a/include/net/snmp.h b/include/net/snmp.h index aebb55383c43..762e2abce889 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -60,7 +60,6 @@ struct ipstats_mib { }; /* ICMP */ -#define ICMP_MIB_DUMMY __ICMP_MIB_MAX #define ICMP_MIB_MAX __ICMP_MIB_MAX struct icmp_mib { unsigned long mibs[ICMP_MIB_MAX]; diff --git a/include/net/sock.h b/include/net/sock.h index 5557dfb3dd68..717cfbf649df 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -516,9 +516,6 @@ static __inline__ void sk_add_bind_node(struct sock *sk, #define sk_nulls_for_each_from(__sk, node) \ if (__sk && ({ node = &(__sk)->sk_nulls_node; 1; })) \ hlist_nulls_for_each_entry_from(__sk, node, sk_nulls_node) -#define sk_for_each_continue(__sk, node) \ - if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ - hlist_for_each_entry_continue(__sk, node, sk_node) #define sk_for_each_safe(__sk, node, tmp, list) \ hlist_for_each_entry_safe(__sk, node, tmp, list, sk_node) #define sk_for_each_bound(__sk, node, list) \ diff --git a/include/net/tcp.h b/include/net/tcp.h index 4097320caa25..3f227baee4be 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -100,12 +100,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a * connection: ~180sec is RFC minimum */ - -#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned - * socket. 7 is ~50sec-16min. - */ - - #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ #define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN -- cgit v1.2.3-59-g8ed1b From d265fef6ddf9042195aae551e1fde211c2a1588b Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:53 +0000 Subject: tipc: Remove obsolete native API files and exports As part of the removal of TIPC's native API support it is no longer necessary for TIPC to export symbols for routines that can be called by kernel-based applications, nor for it to have header files that kernel-based applications can include to access the declarations for those routines. This commit eliminates the exporting of symbols by TIPC and migrates the contents of each obsolete native API include file into its corresponding non-native API equivalent. The code which was migrated in this commit was migrated intact, in that there are no technical changes combined with the relocation. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/net/tipc/tipc.h | 186 ------------------------------------ include/net/tipc/tipc_bearer.h | 138 --------------------------- include/net/tipc/tipc_msg.h | 207 ----------------------------------------- include/net/tipc/tipc_port.h | 101 -------------------- net/tipc/bcast.c | 1 + net/tipc/bearer.h | 69 +++++++++++++- net/tipc/config.c | 2 +- net/tipc/core.c | 40 -------- net/tipc/core.h | 14 ++- net/tipc/eth_media.c | 6 +- net/tipc/msg.h | 168 +++++++++++++++++++++++++++++++-- net/tipc/port.h | 131 ++++++++++++++++++++++++++ net/tipc/socket.c | 3 +- net/tipc/subscr.c | 1 + net/tipc/user_reg.h | 5 + 15 files changed, 382 insertions(+), 690 deletions(-) delete mode 100644 include/net/tipc/tipc.h delete mode 100644 include/net/tipc/tipc_bearer.h delete mode 100644 include/net/tipc/tipc_msg.h delete mode 100644 include/net/tipc/tipc_port.h diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h deleted file mode 100644 index 1e0645e1eed2..000000000000 --- a/include/net/tipc/tipc.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * include/net/tipc/tipc.h: Main include file for TIPC users - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005,2010 Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_H_ -#define _NET_TIPC_H_ - -#ifdef __KERNEL__ - -#include -#include - -/* - * Native API - */ - -/* - * TIPC operating mode routines - */ - -#define TIPC_NOT_RUNNING 0 -#define TIPC_NODE_MODE 1 -#define TIPC_NET_MODE 2 - -typedef void (*tipc_mode_event)(void *usr_handle, int mode, u32 addr); - -int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); - -void tipc_detach(unsigned int userref); - -/* - * TIPC port manipulation routines - */ - -typedef void (*tipc_msg_err_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason, - struct tipc_portid const *attmpt_destid); - -typedef void (*tipc_named_msg_err_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason, - struct tipc_name_seq const *attmpt_dest); - -typedef void (*tipc_conn_shutdown_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason); - -typedef void (*tipc_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - unsigned int importance, - struct tipc_portid const *origin); - -typedef void (*tipc_named_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - unsigned int importance, - struct tipc_portid const *orig, - struct tipc_name_seq const *dest); - -typedef void (*tipc_conn_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size); - -typedef void (*tipc_continue_event) (void *usr_handle, - u32 portref); - -int tipc_createport(unsigned int tipc_user, - void *usr_handle, - unsigned int importance, - tipc_msg_err_event error_cb, - tipc_named_msg_err_event named_error_cb, - tipc_conn_shutdown_event conn_error_cb, - tipc_msg_event message_cb, - tipc_named_msg_event named_message_cb, - tipc_conn_msg_event conn_message_cb, - tipc_continue_event continue_event_cb, - u32 *portref); - -int tipc_deleteport(u32 portref); - -int tipc_ownidentity(u32 portref, struct tipc_portid *port); - -int tipc_portimportance(u32 portref, unsigned int *importance); -int tipc_set_portimportance(u32 portref, unsigned int importance); - -int tipc_portunreliable(u32 portref, unsigned int *isunreliable); -int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); - -int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); -int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); - -int tipc_publish(u32 portref, unsigned int scope, - struct tipc_name_seq const *name_seq); -int tipc_withdraw(u32 portref, unsigned int scope, - struct tipc_name_seq const *name_seq); - -int tipc_connect2port(u32 portref, struct tipc_portid const *port); - -int tipc_disconnect(u32 portref); - -int tipc_shutdown(u32 ref); - -/* - * TIPC messaging routines - */ - -#define TIPC_PORT_IMPORTANCE 100 /* send using current port setting */ - - -int tipc_send(u32 portref, - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send2name(u32 portref, - struct tipc_name const *name, - u32 domain, - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send2port(u32 portref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send_buf2port(u32 portref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_multicast(u32 portref, - struct tipc_name_seq const *seq, - u32 domain, /* currently unused */ - unsigned int section_count, - struct iovec const *msg); -#endif - -#endif diff --git a/include/net/tipc/tipc_bearer.h b/include/net/tipc/tipc_bearer.h deleted file mode 100644 index ee2f304e4919..000000000000 --- a/include/net/tipc/tipc_bearer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * include/net/tipc/tipc_bearer.h: Include file for privileged access to TIPC bearers - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_BEARER_H_ -#define _NET_TIPC_BEARER_H_ - -#ifdef __KERNEL__ - -#include -#include -#include - -/* - * Identifiers of supported TIPC media types - */ - -#define TIPC_MEDIA_TYPE_ETH 1 - -/* - * Destination address structure used by TIPC bearers when sending messages - * - * IMPORTANT: The fields of this structure MUST be stored using the specified - * byte order indicated below, as the structure is exchanged between nodes - * as part of a link setup process. - */ - -struct tipc_media_addr { - __be32 type; /* bearer type (network byte order) */ - union { - __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */ -#if 0 - /* Prototypes for other possible bearer types */ - - struct { - __u16 sin_family; - __u16 sin_port; - struct { - __u32 s_addr; - } sin_addr; - char pad[4]; - } addr_in; /* IP-based bearer */ - __u16 sock_descr; /* generic socket bearer */ -#endif - } dev_addr; -}; - -/** - * struct tipc_bearer - TIPC bearer info available to privileged users - * @usr_handle: pointer to additional user-defined information about bearer - * @mtu: max packet size bearer can support - * @blocked: non-zero if bearer is blocked - * @lock: spinlock for controlling access to bearer - * @addr: media-specific address associated with bearer - * @name: bearer name (format = media:interface) - * - * Note: TIPC initializes "name" and "lock" fields; user is responsible for - * initialization all other fields when a bearer is enabled. - */ - -struct tipc_bearer { - void *usr_handle; - u32 mtu; - int blocked; - spinlock_t lock; - struct tipc_media_addr addr; - char name[TIPC_MAX_BEARER_NAME]; -}; - -/* - * TIPC routines available to supported media types - */ - -int tipc_register_media(u32 media_type, - char *media_name, - int (*enable)(struct tipc_bearer *), - void (*disable)(struct tipc_bearer *), - int (*send_msg)(struct sk_buff *, - struct tipc_bearer *, - struct tipc_media_addr *), - char *(*addr2str)(struct tipc_media_addr *a, - char *str_buf, - int str_size), - struct tipc_media_addr *bcast_addr, - const u32 bearer_priority, - const u32 link_tolerance, /* [ms] */ - const u32 send_window_limit); - -void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr); - -int tipc_block_bearer(const char *name); -void tipc_continue(struct tipc_bearer *tb_ptr); - -int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority); -int tipc_disable_bearer(const char *name); - -/* - * Routines made available to TIPC by supported media types - */ - -int tipc_eth_media_start(void); -void tipc_eth_media_stop(void); - -#endif - -#endif diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h deleted file mode 100644 index ffe50b4e7b93..000000000000 --- a/include/net/tipc/tipc_msg.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * include/net/tipc/tipc_msg.h: Include file for privileged access to TIPC message headers - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_MSG_H_ -#define _NET_TIPC_MSG_H_ - -#ifdef __KERNEL__ - -struct tipc_msg { - __be32 hdr[15]; -}; - - -/* - TIPC user data message header format, version 2: - - - 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w0:|vers | user |hdr sz |n|d|s|-| message size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w2:| link level ack no | broadcast/link level seq no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w3:| previous node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w4:| originating port | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w5:| destination port | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w6:| originating node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w7:| destination node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w8:| name type / transport sequence number | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w9:| name instance/multicast lower bound | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - wA:| multicast upper bound | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / / - \ options \ - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -*/ - -#define TIPC_CONN_MSG 0 -#define TIPC_MCAST_MSG 1 -#define TIPC_NAMED_MSG 2 -#define TIPC_DIRECT_MSG 3 - - -static inline u32 msg_word(struct tipc_msg *m, u32 pos) -{ - return ntohl(m->hdr[pos]); -} - -static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask) -{ - return (msg_word(m, w) >> pos) & mask; -} - -static inline u32 msg_importance(struct tipc_msg *m) -{ - return msg_bits(m, 0, 25, 0xf); -} - -static inline u32 msg_hdr_sz(struct tipc_msg *m) -{ - return msg_bits(m, 0, 21, 0xf) << 2; -} - -static inline int msg_short(struct tipc_msg *m) -{ - return msg_hdr_sz(m) == 24; -} - -static inline u32 msg_size(struct tipc_msg *m) -{ - return msg_bits(m, 0, 0, 0x1ffff); -} - -static inline u32 msg_data_sz(struct tipc_msg *m) -{ - return msg_size(m) - msg_hdr_sz(m); -} - -static inline unchar *msg_data(struct tipc_msg *m) -{ - return ((unchar *)m) + msg_hdr_sz(m); -} - -static inline u32 msg_type(struct tipc_msg *m) -{ - return msg_bits(m, 1, 29, 0x7); -} - -static inline u32 msg_named(struct tipc_msg *m) -{ - return msg_type(m) == TIPC_NAMED_MSG; -} - -static inline u32 msg_mcast(struct tipc_msg *m) -{ - return msg_type(m) == TIPC_MCAST_MSG; -} - -static inline u32 msg_connected(struct tipc_msg *m) -{ - return msg_type(m) == TIPC_CONN_MSG; -} - -static inline u32 msg_errcode(struct tipc_msg *m) -{ - return msg_bits(m, 1, 25, 0xf); -} - -static inline u32 msg_prevnode(struct tipc_msg *m) -{ - return msg_word(m, 3); -} - -static inline u32 msg_origport(struct tipc_msg *m) -{ - return msg_word(m, 4); -} - -static inline u32 msg_destport(struct tipc_msg *m) -{ - return msg_word(m, 5); -} - -static inline u32 msg_mc_netid(struct tipc_msg *m) -{ - return msg_word(m, 5); -} - -static inline u32 msg_orignode(struct tipc_msg *m) -{ - if (likely(msg_short(m))) - return msg_prevnode(m); - return msg_word(m, 6); -} - -static inline u32 msg_destnode(struct tipc_msg *m) -{ - return msg_word(m, 7); -} - -static inline u32 msg_nametype(struct tipc_msg *m) -{ - return msg_word(m, 8); -} - -static inline u32 msg_nameinst(struct tipc_msg *m) -{ - return msg_word(m, 9); -} - -static inline u32 msg_namelower(struct tipc_msg *m) -{ - return msg_nameinst(m); -} - -static inline u32 msg_nameupper(struct tipc_msg *m) -{ - return msg_word(m, 10); -} - -#endif - -#endif diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h deleted file mode 100644 index 1893aaf49426..000000000000 --- a/include/net/tipc/tipc_port.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports - * - * Copyright (c) 1994-2007, Ericsson AB - * Copyright (c) 2005-2008, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_PORT_H_ -#define _NET_TIPC_PORT_H_ - -#ifdef __KERNEL__ - -#include -#include -#include - -#define TIPC_FLOW_CONTROL_WIN 512 - -/** - * struct tipc_port - native TIPC port info available to privileged users - * @usr_handle: pointer to additional user-defined information about port - * @lock: pointer to spinlock for controlling access to port - * @connected: non-zero if port is currently connected to a peer port - * @conn_type: TIPC type used when connection was established - * @conn_instance: TIPC instance used when connection was established - * @conn_unacked: number of unacknowledged messages received from peer port - * @published: non-zero if port has one or more associated names - * @congested: non-zero if cannot send because of link or port congestion - * @max_pkt: maximum packet size "hint" used when building messages sent by port - * @ref: unique reference to port in TIPC object registry - * @phdr: preformatted message header used when sending messages - */ - -struct tipc_port { - void *usr_handle; - spinlock_t *lock; - int connected; - u32 conn_type; - u32 conn_instance; - u32 conn_unacked; - int published; - u32 congested; - u32 max_pkt; - u32 ref; - struct tipc_msg phdr; -}; - - -struct tipc_port *tipc_createport_raw(void *usr_handle, - u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), - void (*wakeup)(struct tipc_port *), - const u32 importance); - -int tipc_reject_msg(struct sk_buff *buf, u32 err); - -int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode); - -void tipc_acknowledge(u32 port_ref,u32 ack); - -struct tipc_port *tipc_get_port(const u32 ref); - -/* - * The following routines require that the port be locked on entry - */ - -int tipc_disconnect_port(struct tipc_port *tp_ptr); - - -#endif - -#endif - diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 22a60fc98392..7d449f03c385 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -47,6 +47,7 @@ #include "name_distr.h" #include "bearer.h" #include "name_table.h" +#include "port.h" #include "bcast.h" #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index a850b389663e..49af7fae8b5a 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -43,6 +43,45 @@ #define MAX_BEARERS 8 #define MAX_MEDIA 4 +/* + * Identifiers of supported TIPC media types + */ +#define TIPC_MEDIA_TYPE_ETH 1 + +/* + * Destination address structure used by TIPC bearers when sending messages + * + * IMPORTANT: The fields of this structure MUST be stored using the specified + * byte order indicated below, as the structure is exchanged between nodes + * as part of a link setup process. + */ +struct tipc_media_addr { + __be32 type; /* bearer type (network byte order) */ + union { + __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */ + } dev_addr; +}; + +/** + * struct tipc_bearer - TIPC bearer info available to media code + * @usr_handle: pointer to additional media-specific information about bearer + * @mtu: max packet size bearer can support + * @blocked: non-zero if bearer is blocked + * @lock: spinlock for controlling access to bearer + * @addr: media-specific address associated with bearer + * @name: bearer name (format = media:interface) + * + * Note: TIPC initializes "name" and "lock" fields; media code is responsible + * for initialization all other fields when a bearer is enabled. + */ +struct tipc_bearer { + void *usr_handle; + u32 mtu; + int blocked; + spinlock_t lock; + struct tipc_media_addr addr; + char name[TIPC_MAX_BEARER_NAME]; +}; /** * struct media - TIPC media information available to internal users @@ -55,7 +94,7 @@ * @priority: default link (and bearer) priority * @tolerance: default time (in ms) before declaring link failure * @window: default window (in packets) before declaring link congestion - * @type_id: TIPC media identifier [defined in tipc_bearer.h] + * @type_id: TIPC media identifier * @name: media name */ @@ -116,6 +155,34 @@ struct link; extern struct bearer tipc_bearers[]; +/* + * TIPC routines available to supported media types + */ +int tipc_register_media(u32 media_type, + char *media_name, int (*enable)(struct tipc_bearer *), + void (*disable)(struct tipc_bearer *), + int (*send_msg)(struct sk_buff *, + struct tipc_bearer *, struct tipc_media_addr *), + char *(*addr2str)(struct tipc_media_addr *a, + char *str_buf, int str_size), + struct tipc_media_addr *bcast_addr, const u32 bearer_priority, + const u32 link_tolerance, /* [ms] */ + const u32 send_window_limit); + +void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr); + +int tipc_block_bearer(const char *name); +void tipc_continue(struct tipc_bearer *tb_ptr); + +int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority); +int tipc_disable_bearer(const char *name); + +/* + * Routines made available to TIPC by supported media types + */ +int tipc_eth_media_start(void); +void tipc_eth_media_stop(void); + void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); struct sk_buff *tipc_media_get_names(void); diff --git a/net/tipc/config.c b/net/tipc/config.c index 50a6133a3668..82267f3cd3b7 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -43,8 +43,8 @@ #include "addr.h" #include "name_table.h" #include "node.h" +#include "user_reg.h" #include "config.h" -#include "discover.h" struct subscr_data { char usr_handle[8]; diff --git a/net/tipc/core.c b/net/tipc/core.c index e2a09eb8efd4..785362f6a411 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -236,43 +236,3 @@ module_exit(tipc_exit); MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(TIPC_MOD_VER); - -/* Native TIPC API for kernel-space applications (see tipc.h) */ - -EXPORT_SYMBOL(tipc_attach); -EXPORT_SYMBOL(tipc_detach); -EXPORT_SYMBOL(tipc_createport); -EXPORT_SYMBOL(tipc_deleteport); -EXPORT_SYMBOL(tipc_ownidentity); -EXPORT_SYMBOL(tipc_portimportance); -EXPORT_SYMBOL(tipc_set_portimportance); -EXPORT_SYMBOL(tipc_portunreliable); -EXPORT_SYMBOL(tipc_set_portunreliable); -EXPORT_SYMBOL(tipc_portunreturnable); -EXPORT_SYMBOL(tipc_set_portunreturnable); -EXPORT_SYMBOL(tipc_publish); -EXPORT_SYMBOL(tipc_withdraw); -EXPORT_SYMBOL(tipc_connect2port); -EXPORT_SYMBOL(tipc_disconnect); -EXPORT_SYMBOL(tipc_shutdown); -EXPORT_SYMBOL(tipc_send); -EXPORT_SYMBOL(tipc_send2name); -EXPORT_SYMBOL(tipc_send2port); -EXPORT_SYMBOL(tipc_multicast); - -/* TIPC API for external bearers (see tipc_bearer.h) */ - -EXPORT_SYMBOL(tipc_block_bearer); -EXPORT_SYMBOL(tipc_continue); -EXPORT_SYMBOL(tipc_disable_bearer); -EXPORT_SYMBOL(tipc_enable_bearer); -EXPORT_SYMBOL(tipc_recv_msg); -EXPORT_SYMBOL(tipc_register_media); - -/* TIPC API for external APIs (see tipc_port.h) */ - -EXPORT_SYMBOL(tipc_createport_raw); -EXPORT_SYMBOL(tipc_reject_msg); -EXPORT_SYMBOL(tipc_send_buf_fast); -EXPORT_SYMBOL(tipc_acknowledge); - diff --git a/net/tipc/core.h b/net/tipc/core.h index e19389e57227..ca7e171c1043 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -39,10 +39,6 @@ #include #include -#include -#include -#include -#include #include #include #include @@ -62,6 +58,9 @@ #define TIPC_MOD_VER "2.0.0" +struct tipc_msg; /* msg.h */ +struct print_buf; /* dbg.h */ + /* * TIPC sanity test macros */ @@ -173,6 +172,13 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); #define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ +/* + * TIPC operating mode routines + */ +#define TIPC_NOT_RUNNING 0 +#define TIPC_NODE_MODE 1 +#define TIPC_NET_MODE 2 + /* * Global configuration variables */ diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 6e988ba485fd..ee683cc8f4b1 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -34,13 +34,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include #include #include #include +#include "core.h" +#include "bearer.h" + #define MAX_ETH_BEARERS 2 #define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI #define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 031aad18efce..aee53864d7a0 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -37,10 +37,51 @@ #ifndef _TIPC_MSG_H #define _TIPC_MSG_H -#include "core.h" +#include "bearer.h" #define TIPC_VERSION 2 +/* + * TIPC user data message header format, version 2: + * + * + * 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w0:|vers | user |hdr sz |n|d|s|-| message size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w2:| link level ack no | broadcast/link level seq no | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w3:| previous node | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w4:| originating port | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w5:| destination port | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w6:| originating node | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w7:| destination node | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w8:| name type / transport sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * w9:| name instance/multicast lower bound | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * wA:| multicast upper bound | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * / / + * \ options \ + * / / + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define TIPC_CONN_MSG 0 +#define TIPC_MCAST_MSG 1 +#define TIPC_NAMED_MSG 2 +#define TIPC_DIRECT_MSG 3 + + #define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ #define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ #define LONG_H_SIZE 40 /* Named messages */ @@ -52,20 +93,26 @@ #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) -/* - TIPC user data message header format, version 2 +struct tipc_msg { + __be32 hdr[15]; +}; - - Fundamental definitions available to privileged TIPC users - are located in tipc_msg.h. - - Remaining definitions available to TIPC internal users appear below. -*/ +static inline u32 msg_word(struct tipc_msg *m, u32 pos) +{ + return ntohl(m->hdr[pos]); +} static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) { m->hdr[w] = htonl(val); } +static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask) +{ + return (msg_word(m, w) >> pos) & mask; +} + static inline void msg_set_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask, u32 val) { @@ -112,16 +159,36 @@ static inline void msg_set_user(struct tipc_msg *m, u32 n) msg_set_bits(m, 0, 25, 0xf, n); } +static inline u32 msg_importance(struct tipc_msg *m) +{ + return msg_bits(m, 0, 25, 0xf); +} + static inline void msg_set_importance(struct tipc_msg *m, u32 i) { msg_set_user(m, i); } +static inline u32 msg_hdr_sz(struct tipc_msg *m) +{ + return msg_bits(m, 0, 21, 0xf) << 2; +} + static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) { msg_set_bits(m, 0, 21, 0xf, n>>2); } +static inline u32 msg_size(struct tipc_msg *m) +{ + return msg_bits(m, 0, 0, 0x1ffff); +} + +static inline u32 msg_data_sz(struct tipc_msg *m) +{ + return msg_size(m) - msg_hdr_sz(m); +} + static inline int msg_non_seq(struct tipc_msg *m) { return msg_bits(m, 0, 20, 1); @@ -162,11 +229,36 @@ static inline void msg_set_size(struct tipc_msg *m, u32 sz) * Word 1 */ +static inline u32 msg_type(struct tipc_msg *m) +{ + return msg_bits(m, 1, 29, 0x7); +} + static inline void msg_set_type(struct tipc_msg *m, u32 n) { msg_set_bits(m, 1, 29, 0x7, n); } +static inline u32 msg_named(struct tipc_msg *m) +{ + return msg_type(m) == TIPC_NAMED_MSG; +} + +static inline u32 msg_mcast(struct tipc_msg *m) +{ + return msg_type(m) == TIPC_MCAST_MSG; +} + +static inline u32 msg_connected(struct tipc_msg *m) +{ + return msg_type(m) == TIPC_CONN_MSG; +} + +static inline u32 msg_errcode(struct tipc_msg *m) +{ + return msg_bits(m, 1, 25, 0xf); +} + static inline void msg_set_errcode(struct tipc_msg *m, u32 err) { msg_set_bits(m, 1, 25, 0xf, err); @@ -257,31 +349,68 @@ static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode) */ +static inline u32 msg_prevnode(struct tipc_msg *m) +{ + return msg_word(m, 3); +} + static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) { msg_set_word(m, 3, a); } +static inline u32 msg_origport(struct tipc_msg *m) +{ + return msg_word(m, 4); +} + static inline void msg_set_origport(struct tipc_msg *m, u32 p) { msg_set_word(m, 4, p); } +static inline u32 msg_destport(struct tipc_msg *m) +{ + return msg_word(m, 5); +} + static inline void msg_set_destport(struct tipc_msg *m, u32 p) { msg_set_word(m, 5, p); } +static inline u32 msg_mc_netid(struct tipc_msg *m) +{ + return msg_word(m, 5); +} + static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) { msg_set_word(m, 5, p); } +static inline int msg_short(struct tipc_msg *m) +{ + return msg_hdr_sz(m) == 24; +} + +static inline u32 msg_orignode(struct tipc_msg *m) +{ + if (likely(msg_short(m))) + return msg_prevnode(m); + return msg_word(m, 6); +} + static inline void msg_set_orignode(struct tipc_msg *m, u32 a) { msg_set_word(m, 6, a); } +static inline u32 msg_destnode(struct tipc_msg *m) +{ + return msg_word(m, 7); +} + static inline void msg_set_destnode(struct tipc_msg *m, u32 a) { msg_set_word(m, 7, a); @@ -299,6 +428,11 @@ static inline u32 msg_routed(struct tipc_msg *m) return(msg_destnode(m) ^ msg_orignode(m)) >> 11; } +static inline u32 msg_nametype(struct tipc_msg *m) +{ + return msg_word(m, 8); +} + static inline void msg_set_nametype(struct tipc_msg *m, u32 n) { msg_set_word(m, 8, n); @@ -324,6 +458,16 @@ static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) msg_set_word(m, 8, n); } +static inline u32 msg_nameinst(struct tipc_msg *m) +{ + return msg_word(m, 9); +} + +static inline u32 msg_namelower(struct tipc_msg *m) +{ + return msg_nameinst(m); +} + static inline void msg_set_namelower(struct tipc_msg *m, u32 n) { msg_set_word(m, 9, n); @@ -334,11 +478,21 @@ static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) msg_set_namelower(m, n); } +static inline u32 msg_nameupper(struct tipc_msg *m) +{ + return msg_word(m, 10); +} + static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) { msg_set_word(m, 10, n); } +static inline unchar *msg_data(struct tipc_msg *m) +{ + return ((unchar *)m) + msg_hdr_sz(m); +} + static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) { return (struct tipc_msg *)msg_data(m); diff --git a/net/tipc/port.h b/net/tipc/port.h index 73bbf442b346..8b9d87a3efae 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -44,6 +44,39 @@ #include "dbg.h" #include "node_subscr.h" +#define TIPC_FLOW_CONTROL_WIN 512 + +typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size, int reason, + struct tipc_portid const *attmpt_destid); + +typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size, int reason, + struct tipc_name_seq const *attmpt_dest); + +typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size, int reason); + +typedef void (*tipc_msg_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size, unsigned int importance, + struct tipc_portid const *origin); + +typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size, unsigned int importance, + struct tipc_portid const *orig, + struct tipc_name_seq const *dest); + +typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref, + struct sk_buff **buf, unsigned char const *data, + unsigned int size); + +typedef void (*tipc_continue_event) (void *usr_handle, u32 portref); + /** * struct user_port - TIPC user port (used with native API) * @user_ref: id of user who created user port @@ -67,6 +100,34 @@ struct user_port { struct list_head uport_list; }; +/** + * struct tipc_port - TIPC port info available to socket API + * @usr_handle: pointer to additional user-defined information about port + * @lock: pointer to spinlock for controlling access to port + * @connected: non-zero if port is currently connected to a peer port + * @conn_type: TIPC type used when connection was established + * @conn_instance: TIPC instance used when connection was established + * @conn_unacked: number of unacknowledged messages received from peer port + * @published: non-zero if port has one or more associated names + * @congested: non-zero if cannot send because of link or port congestion + * @max_pkt: maximum packet size "hint" used when building messages sent by port + * @ref: unique reference to port in TIPC object registry + * @phdr: preformatted message header used when sending messages + */ +struct tipc_port { + void *usr_handle; + spinlock_t *lock; + int connected; + u32 conn_type; + u32 conn_instance; + u32 conn_unacked; + int published; + u32 congested; + u32 max_pkt; + u32 ref; + struct tipc_msg phdr; +}; + /** * struct port - TIPC port structure * @publ: TIPC port info available to privileged users @@ -109,6 +170,76 @@ struct port { extern spinlock_t tipc_port_list_lock; struct port_list; +/* + * TIPC port manipulation routines + */ +struct tipc_port *tipc_createport_raw(void *usr_handle, + u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), + void (*wakeup)(struct tipc_port *), const u32 importance); + +int tipc_reject_msg(struct sk_buff *buf, u32 err); + +int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode); + +void tipc_acknowledge(u32 port_ref, u32 ack); + +int tipc_createport(unsigned int tipc_user, void *usr_handle, + unsigned int importance, tipc_msg_err_event error_cb, + tipc_named_msg_err_event named_error_cb, + tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb, + tipc_named_msg_event named_msg_cb, + tipc_conn_msg_event conn_msg_cb, + tipc_continue_event continue_event_cb, u32 *portref); + +int tipc_deleteport(u32 portref); + +int tipc_ownidentity(u32 portref, struct tipc_portid *port); + +int tipc_portimportance(u32 portref, unsigned int *importance); +int tipc_set_portimportance(u32 portref, unsigned int importance); + +int tipc_portunreliable(u32 portref, unsigned int *isunreliable); +int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); + +int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); +int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); + +int tipc_publish(u32 portref, unsigned int scope, + struct tipc_name_seq const *name_seq); +int tipc_withdraw(u32 portref, unsigned int scope, + struct tipc_name_seq const *name_seq); + +int tipc_connect2port(u32 portref, struct tipc_portid const *port); + +int tipc_disconnect(u32 portref); + +int tipc_shutdown(u32 ref); + + +/* + * The following routines require that the port be locked on entry + */ +int tipc_disconnect_port(struct tipc_port *tp_ptr); + +/* + * TIPC messaging routines + */ +#define TIPC_PORT_IMPORTANCE 100 /* send using current port setting */ + +int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); + +int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, + unsigned int num_sect, struct iovec const *msg_sect); + +int tipc_send2port(u32 portref, struct tipc_portid const *dest, + unsigned int num_sect, struct iovec const *msg_sect); + +int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, + struct sk_buff *buf, unsigned int dsz); + +int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, u32 domain, + unsigned int section_count, struct iovec const *msg); + int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, int err); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e9f0d5004483..23a12e44347f 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -49,10 +49,9 @@ #include #include -#include -#include #include "core.h" +#include "port.h" #define SS_LISTENING -1 /* socket is listening */ #define SS_READY -2 /* socket is connectionless */ diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 33313961d010..a857e6ea857e 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -37,6 +37,7 @@ #include "core.h" #include "dbg.h" #include "name_table.h" +#include "user_reg.h" #include "port.h" #include "ref.h" #include "subscr.h" diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h index 81dc12e2882f..a05981fb9176 100644 --- a/net/tipc/user_reg.h +++ b/net/tipc/user_reg.h @@ -42,6 +42,11 @@ int tipc_reg_start(void); void tipc_reg_stop(void); +typedef void (*tipc_mode_event)(void *usr_handle, int mode, u32 addr); + +int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); +void tipc_detach(unsigned int userref); + int tipc_reg_add_port(struct user_port *up_ptr); int tipc_reg_remove_port(struct user_port *up_ptr); -- cgit v1.2.3-59-g8ed1b From c80262829769419e19527f972672e8df0480235a Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:54 +0000 Subject: tipc: Remove obsolete inclusions of header files Gets rid of #include statements that are no longer required as a result of the merging of obsolete native API header file content into other TIPC include files. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/addr.c | 2 -- net/tipc/bcast.c | 9 --------- net/tipc/bearer.c | 3 --- net/tipc/bearer.h | 1 - net/tipc/cluster.c | 6 ------ net/tipc/config.c | 5 ----- net/tipc/config.h | 1 - net/tipc/core.c | 1 - net/tipc/discover.c | 2 -- net/tipc/discover.h | 2 -- net/tipc/link.c | 8 -------- net/tipc/link.h | 1 - net/tipc/msg.c | 2 -- net/tipc/name_distr.c | 2 -- net/tipc/name_table.c | 5 ----- net/tipc/net.c | 5 ----- net/tipc/node.c | 6 ------ net/tipc/node_subscr.c | 2 -- net/tipc/port.c | 6 ------ net/tipc/port.h | 2 -- net/tipc/subscr.c | 3 --- net/tipc/zone.c | 3 --- 22 files changed, 77 deletions(-) diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 8a2e89bffde5..886715a75259 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -35,11 +35,9 @@ */ #include "core.h" -#include "dbg.h" #include "addr.h" #include "zone.h" #include "cluster.h" -#include "net.h" /** * tipc_addr_domain_valid - validates a network domain address diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 7d449f03c385..6d828d9eda42 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -36,18 +36,9 @@ */ #include "core.h" -#include "msg.h" -#include "dbg.h" #include "link.h" -#include "net.h" -#include "node.h" #include "port.h" -#include "addr.h" -#include "node_subscr.h" #include "name_distr.h" -#include "bearer.h" -#include "name_table.h" -#include "port.h" #include "bcast.h" #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 9927d1d56c4f..347f255b0de2 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -36,12 +36,9 @@ #include "core.h" #include "config.h" -#include "dbg.h" #include "bearer.h" -#include "link.h" #include "port.h" #include "discover.h" -#include "bcast.h" #define MAX_ADDR_STR 32 diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 49af7fae8b5a..8dc0e9268a28 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -37,7 +37,6 @@ #ifndef _TIPC_BEARER_H #define _TIPC_BEARER_H -#include "core.h" #include "bcast.h" #define MAX_BEARERS 8 diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 7fea14b98b97..ee251798d482 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -36,13 +36,7 @@ #include "core.h" #include "cluster.h" -#include "addr.h" -#include "node_subscr.h" #include "link.h" -#include "node.h" -#include "net.h" -#include "msg.h" -#include "bearer.h" static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, u32 lower, u32 upper); diff --git a/net/tipc/config.c b/net/tipc/config.c index 82267f3cd3b7..5bb369669729 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -35,14 +35,9 @@ */ #include "core.h" -#include "dbg.h" -#include "bearer.h" #include "port.h" #include "link.h" -#include "zone.h" -#include "addr.h" #include "name_table.h" -#include "node.h" #include "user_reg.h" #include "config.h" diff --git a/net/tipc/config.h b/net/tipc/config.h index 481e12ece715..443159a166fd 100644 --- a/net/tipc/config.h +++ b/net/tipc/config.h @@ -39,7 +39,6 @@ /* ---------------------------------------------------------------------- */ -#include "core.h" #include "link.h" struct sk_buff *tipc_cfg_reply_alloc(int payload_size); diff --git a/net/tipc/core.c b/net/tipc/core.c index 785362f6a411..f5d62c174de2 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -40,7 +40,6 @@ #include #include "core.h" -#include "dbg.h" #include "ref.h" #include "net.h" #include "user_reg.h" diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 4a7cd3719b78..f2ce36baf42e 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -35,9 +35,7 @@ */ #include "core.h" -#include "dbg.h" #include "link.h" -#include "zone.h" #include "discover.h" #include "port.h" #include "name_table.h" diff --git a/net/tipc/discover.h b/net/tipc/discover.h index f8e750636123..d2c3cffb79fc 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h @@ -37,8 +37,6 @@ #ifndef _TIPC_DISCOVER_H #define _TIPC_DISCOVER_H -#include "core.h" - struct link_req; struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, diff --git a/net/tipc/link.c b/net/tipc/link.c index b31992ccd5d3..aee6579438c7 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -35,19 +35,11 @@ */ #include "core.h" -#include "dbg.h" #include "link.h" -#include "net.h" -#include "node.h" #include "port.h" -#include "addr.h" -#include "node_subscr.h" #include "name_distr.h" -#include "bearer.h" -#include "name_table.h" #include "discover.h" #include "config.h" -#include "bcast.h" /* diff --git a/net/tipc/link.h b/net/tipc/link.h index f98bc613de67..c562888d25da 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -39,7 +39,6 @@ #include "dbg.h" #include "msg.h" -#include "bearer.h" #include "node.h" #define PUSH_FAILED 1 diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ecb532fb0351..ee6b4c68d4a4 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -36,9 +36,7 @@ #include "core.h" #include "addr.h" -#include "dbg.h" #include "msg.h" -#include "bearer.h" u32 tipc_msg_tot_importance(struct tipc_msg *m) { diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 7b907171f879..10ff48be3c01 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -36,9 +36,7 @@ #include "core.h" #include "cluster.h" -#include "dbg.h" #include "link.h" -#include "msg.h" #include "name_distr.h" #define ITEM_SIZE sizeof(struct distr_item) diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 3a8de4334da1..d5adb0456746 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -36,15 +36,10 @@ #include "core.h" #include "config.h" -#include "dbg.h" #include "name_table.h" #include "name_distr.h" -#include "addr.h" -#include "node_subscr.h" #include "subscr.h" #include "port.h" -#include "cluster.h" -#include "bcast.h" static int tipc_nametbl_size = 1024; /* must be a power of 2 */ diff --git a/net/tipc/net.c b/net/tipc/net.c index 1a621cfd6604..c2b4b86c2e6a 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -35,18 +35,13 @@ */ #include "core.h" -#include "bearer.h" #include "net.h" #include "zone.h" -#include "addr.h" #include "name_table.h" #include "name_distr.h" #include "subscr.h" #include "link.h" -#include "msg.h" #include "port.h" -#include "bcast.h" -#include "discover.h" #include "config.h" /* diff --git a/net/tipc/node.c b/net/tipc/node.c index b4d87eb2dc5d..bd959a855fd5 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -37,13 +37,7 @@ #include "core.h" #include "config.h" #include "node.h" -#include "cluster.h" -#include "net.h" -#include "addr.h" -#include "node_subscr.h" -#include "link.h" #include "port.h" -#include "bearer.h" #include "name_distr.h" void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str); diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c index 19194d476a9e..018a55332d91 100644 --- a/net/tipc/node_subscr.c +++ b/net/tipc/node_subscr.c @@ -35,10 +35,8 @@ */ #include "core.h" -#include "dbg.h" #include "node_subscr.h" #include "node.h" -#include "addr.h" /** * tipc_nodesub_subscribe - create "node down" subscription for specified node diff --git a/net/tipc/port.c b/net/tipc/port.c index 82092eaa1536..e822117b79ad 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -36,15 +36,9 @@ #include "core.h" #include "config.h" -#include "dbg.h" #include "port.h" -#include "addr.h" -#include "link.h" -#include "node.h" #include "name_table.h" #include "user_reg.h" -#include "msg.h" -#include "bcast.h" /* Connection management: */ #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ diff --git a/net/tipc/port.h b/net/tipc/port.h index 8b9d87a3efae..e038ce1ef8e8 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -37,11 +37,9 @@ #ifndef _TIPC_PORT_H #define _TIPC_PORT_H -#include "core.h" #include "ref.h" #include "net.h" #include "msg.h" -#include "dbg.h" #include "node_subscr.h" #define TIPC_FLOW_CONTROL_WIN 512 diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index a857e6ea857e..e7fb38ba577d 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -35,11 +35,8 @@ */ #include "core.h" -#include "dbg.h" #include "name_table.h" #include "user_reg.h" -#include "port.h" -#include "ref.h" #include "subscr.h" /** diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 83f8b5e91fc8..1b61ca8c48ef 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -36,9 +36,6 @@ #include "core.h" #include "zone.h" -#include "net.h" -#include "addr.h" -#include "node_subscr.h" #include "cluster.h" #include "node.h" -- cgit v1.2.3-59-g8ed1b From 8d71919d7afc4ade0d9de09e1d50fbf9168c368d Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:55 +0000 Subject: tipc: Delete unused configuration service structure definition Removes a structure definition that is no longer used by TIPC's configuration service. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/config.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 5bb369669729..2ee5a9a3cebf 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -41,13 +41,6 @@ #include "user_reg.h" #include "config.h" -struct subscr_data { - char usr_handle[8]; - u32 domain; - u32 port_ref; - struct list_head subd_list; -}; - struct manager { u32 user_ref; u32 port_ref; -- cgit v1.2.3-59-g8ed1b From 28cc937eac00805e8b9c6e7ed7d590567378187f Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:56 +0000 Subject: tipc: Eliminate useless return value when disabling a bearer Modifies bearer_disable() to return void since it always indicates success anyway. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bearer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 347f255b0de2..885da94be4ac 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -622,7 +622,7 @@ int tipc_block_bearer(const char *name) * Note: This routine assumes caller holds tipc_net_lock. */ -static int bearer_disable(struct bearer *b_ptr) +static void bearer_disable(struct bearer *b_ptr) { struct link *l_ptr; struct link *temp_l_ptr; @@ -638,7 +638,6 @@ static int bearer_disable(struct bearer *b_ptr) } spin_unlock_bh(&b_ptr->publ.lock); memset(b_ptr, 0, sizeof(struct bearer)); - return 0; } int tipc_disable_bearer(const char *name) @@ -651,8 +650,10 @@ int tipc_disable_bearer(const char *name) if (b_ptr == NULL) { warn("Attempt to disable unknown bearer <%s>\n", name); res = -EINVAL; - } else - res = bearer_disable(b_ptr); + } else { + bearer_disable(b_ptr); + res = 0; + } write_unlock_bh(&tipc_net_lock); return res; } -- cgit v1.2.3-59-g8ed1b From 528c771e87c3fa661bc6983b5bf0ba464d9f7c3a Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:57 +0000 Subject: tipc: Delete useless function prototypes Removes several function declarations that aren't used anywhere, either because they reference routines that no longer exist or because all users of the function reference it after it has already been defined. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bearer.h | 1 - net/tipc/cluster.c | 1 - net/tipc/node.c | 1 - net/tipc/port.h | 1 - 4 files changed, 4 deletions(-) diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 8dc0e9268a28..85f451d5aacf 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -192,7 +192,6 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); struct bearer *tipc_bearer_find_interface(const char *if_name); int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr); -int tipc_bearer_init(void); void tipc_bearer_stop(void); void tipc_bearer_lock_push(struct bearer *b_ptr); diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index ee251798d482..405be87157ba 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -40,7 +40,6 @@ static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, u32 lower, u32 upper); -static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest); struct tipc_node **tipc_local_nodes = NULL; struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}}; diff --git a/net/tipc/node.c b/net/tipc/node.c index bd959a855fd5..df71dfc3a9ae 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -40,7 +40,6 @@ #include "port.h" #include "name_distr.h" -void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str); static void node_lost_contact(struct tipc_node *n_ptr); static void node_established_contact(struct tipc_node *n_ptr); diff --git a/net/tipc/port.h b/net/tipc/port.h index e038ce1ef8e8..547cd6e00312 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -242,7 +242,6 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, int err); struct sk_buff *tipc_port_get_ports(void); -struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space); void tipc_port_recv_proto_msg(struct sk_buff *buf); void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); void tipc_port_reinit(void); -- cgit v1.2.3-59-g8ed1b From a5c2af9922a94a875c5f4b2dcd357a1c399b7ea6 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:58 +0000 Subject: tipc: Remove support for TIPC mode change callback Eliminates support for the callback routine invoked when TIPC changes its mode of operation from inactive to standalone or from standalone to networked. This callback was part of TIPC's obsolete native API and is not used by TIPC internally. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/config.c | 2 +- net/tipc/subscr.c | 2 +- net/tipc/user_reg.c | 50 ++------------------------------------------------ net/tipc/user_reg.h | 4 +--- 4 files changed, 5 insertions(+), 53 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 2ee5a9a3cebf..bdde39f0436b 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -560,7 +560,7 @@ int tipc_cfg_init(void) struct tipc_name_seq seq; int res; - res = tipc_attach(&mng.user_ref, NULL, NULL); + res = tipc_attach(&mng.user_ref); if (res) goto failed; diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index e7fb38ba577d..e13c89aeb6d2 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -549,7 +549,7 @@ int tipc_subscr_start(void) INIT_LIST_HEAD(&topsrv.subscriber_list); spin_lock_bh(&topsrv.lock); - res = tipc_attach(&topsrv.user_ref, NULL, NULL); + res = tipc_attach(&topsrv.user_ref); if (res) { spin_unlock_bh(&topsrv.lock); return res; diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c index 506928803162..2e2702e2049c 100644 --- a/net/tipc/user_reg.c +++ b/net/tipc/user_reg.c @@ -50,15 +50,11 @@ /** * struct tipc_user - registered TIPC user info * @next: index of next free registry entry (or -1 for an allocated entry) - * @callback: ptr to routine to call when TIPC mode changes (NULL if none) - * @usr_handle: user-defined value passed to callback routine * @ports: list of user ports owned by the user */ struct tipc_user { int next; - tipc_mode_event callback; - void *usr_handle; struct list_head ports; }; @@ -94,42 +90,13 @@ static int reg_init(void) return users ? 0 : -ENOMEM; } -/** - * reg_callback - inform TIPC user about current operating mode - */ - -static void reg_callback(struct tipc_user *user_ptr) -{ - tipc_mode_event cb; - void *arg; - - spin_lock_bh(®_lock); - cb = user_ptr->callback; - arg = user_ptr->usr_handle; - spin_unlock_bh(®_lock); - - if (cb) - cb(arg, tipc_mode, tipc_own_addr); -} - /** * tipc_reg_start - activate TIPC user registry */ int tipc_reg_start(void) { - u32 u; - int res; - - if ((res = reg_init())) - return res; - - for (u = 1; u <= MAX_USERID; u++) { - if (users[u].callback) - tipc_k_signal((Handler)reg_callback, - (unsigned long)&users[u]); - } - return 0; + return reg_init(); } /** @@ -138,15 +105,9 @@ int tipc_reg_start(void) void tipc_reg_stop(void) { - int id; - if (!users) return; - for (id = 1; id <= MAX_USERID; id++) { - if (users[id].callback) - reg_callback(&users[id]); - } kfree(users); users = NULL; } @@ -157,12 +118,10 @@ void tipc_reg_stop(void) * NOTE: This routine may be called when TIPC is inactive. */ -int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle) +int tipc_attach(u32 *userid) { struct tipc_user *user_ptr; - if ((tipc_mode == TIPC_NOT_RUNNING) && !cb) - return -ENOPROTOOPT; if (!users) reg_init(); @@ -177,13 +136,9 @@ int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle) user_ptr->next = -1; spin_unlock_bh(®_lock); - user_ptr->callback = cb; - user_ptr->usr_handle = usr_handle; INIT_LIST_HEAD(&user_ptr->ports); atomic_inc(&tipc_user_count); - if (cb && (tipc_mode != TIPC_NOT_RUNNING)) - tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); return 0; } @@ -207,7 +162,6 @@ void tipc_detach(u32 userid) } user_ptr = &users[userid]; - user_ptr->callback = NULL; INIT_LIST_HEAD(&ports_temp); list_splice(&user_ptr->ports, &ports_temp); user_ptr->next = next_free_user; diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h index a05981fb9176..109eed0d6de3 100644 --- a/net/tipc/user_reg.h +++ b/net/tipc/user_reg.h @@ -42,9 +42,7 @@ int tipc_reg_start(void); void tipc_reg_stop(void); -typedef void (*tipc_mode_event)(void *usr_handle, int mode, u32 addr); - -int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); +int tipc_attach(unsigned int *userref); void tipc_detach(unsigned int userref); int tipc_reg_add_port(struct user_port *up_ptr); -- cgit v1.2.3-59-g8ed1b From 38f232eae20cefed2e2379d77c54babb0de6d024 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:00:59 +0000 Subject: tipc: Remove unused domain argument from multicast send routine Eliminates an unused argument from tipc_multicast(), now that this routine can no longer be called by kernel-based applications. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/port.c | 2 +- net/tipc/port.h | 2 +- net/tipc/socket.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/net/tipc/port.c b/net/tipc/port.c index e822117b79ad..01dcfeea1ec4 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -88,7 +88,7 @@ static void port_incr_out_seqno(struct port *p_ptr) * tipc_multicast - send a multicast message to local and remote destinations */ -int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain, +int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 num_sect, struct iovec const *msg_sect) { struct tipc_msg *hdr; diff --git a/net/tipc/port.h b/net/tipc/port.h index 547cd6e00312..711b4a0fa443 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -235,7 +235,7 @@ int tipc_send2port(u32 portref, struct tipc_portid const *dest, int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, struct sk_buff *buf, unsigned int dsz); -int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, u32 domain, +int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, unsigned int section_count, struct iovec const *msg); int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 23a12e44347f..34f96eda5fa3 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -596,7 +596,6 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, break; res = tipc_multicast(tport->ref, &dest->addr.nameseq, - 0, m->msg_iovlen, m->msg_iov); } -- cgit v1.2.3-59-g8ed1b From 52fe7b725e0a1360d36c720ee87ab1e559df69db Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:01:00 +0000 Subject: tipc: Eliminate useless initialization when creating subscriber Removes initialization of a local variable that is always assigned a different value before it is referenced. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/subscr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index e13c89aeb6d2..23f43d03980c 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -542,7 +542,7 @@ static void subscr_named_msg_event(void *usr_handle, int tipc_subscr_start(void) { struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; - int res = -1; + int res; memset(&topsrv, 0, sizeof (topsrv)); spin_lock_init(&topsrv.lock); -- cgit v1.2.3-59-g8ed1b From 471450f7ec24ccd9ac24e6f05cd9358d40c09d03 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:01:01 +0000 Subject: tipc: Eliminate an unused symbolic constant in link code Removes a symbol that is not referenced anywhere by TIPC's link code. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/link.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index aee6579438c7..cf414cf05e72 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -48,12 +48,6 @@ #define INVALID_SESSION 0x10000 -/* - * Limit for deferred reception queue: - */ - -#define DEF_QUEUE_LIMIT 256u - /* * Link state events: */ -- cgit v1.2.3-59-g8ed1b From 12bae479ee414f45ad8fe93530f5b6ea241bde3f Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:01:02 +0000 Subject: tipc: Eliminate obsolete native API forwarding routines Moves the content of each native API message forwarding routine into the sole routine that calls it, since the forwarding routines no longer be called in isolation. Also removes code in each routine that altered the outgoing message's importance level since this is now no longer possible. The previous function mapping (parent function, and child API) was as follows: tipc_send2name \--tipc_forward2name tipc_send2port \--tipc_forward2port tipc_send_buf2port \--tipc_forward_buf2port After this commit, the children don't exist and their functionality is completely in the respective parent. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/port.c | 100 +++++++++----------------------------------------------- net/tipc/port.h | 2 -- 2 files changed, 15 insertions(+), 87 deletions(-) diff --git a/net/tipc/port.c b/net/tipc/port.c index 01dcfeea1ec4..73f232c1fe15 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -1265,16 +1265,11 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) } /** - * tipc_forward2name - forward message sections to port name + * tipc_send2name - send message sections to port name */ -static int tipc_forward2name(u32 ref, - struct tipc_name const *name, - u32 domain, - u32 num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, + unsigned int num_sect, struct iovec const *msg_sect) { struct port *p_ptr; struct tipc_msg *msg; @@ -1288,14 +1283,12 @@ static int tipc_forward2name(u32 ref, msg = &p_ptr->publ.phdr; msg_set_type(msg, TIPC_NAMED_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); + msg_set_orignode(msg, tipc_own_addr); + msg_set_origport(msg, ref); msg_set_hdr_sz(msg, LONG_H_SIZE); msg_set_nametype(msg, name->type); msg_set_nameinst(msg, name->instance); msg_set_lookup_scope(msg, tipc_addr_scope(domain)); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg,importance); destport = tipc_nametbl_translate(name->type, name->instance, &destnode); msg_set_destnode(msg, destnode); msg_set_destport(msg, destport); @@ -1319,33 +1312,11 @@ static int tipc_forward2name(u32 ref, } /** - * tipc_send2name - send message sections to port name - */ - -int tipc_send2name(u32 ref, - struct tipc_name const *name, - unsigned int domain, - unsigned int num_sect, - struct iovec const *msg_sect) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig, - TIPC_PORT_IMPORTANCE); -} - -/** - * tipc_forward2port - forward message sections to port identity + * tipc_send2port - send message sections to port identity */ -static int tipc_forward2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +int tipc_send2port(u32 ref, struct tipc_portid const *dest, + unsigned int num_sect, struct iovec const *msg_sect) { struct port *p_ptr; struct tipc_msg *msg; @@ -1357,13 +1328,11 @@ static int tipc_forward2port(u32 ref, msg = &p_ptr->publ.phdr; msg_set_type(msg, TIPC_DIRECT_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); + msg_set_orignode(msg, tipc_own_addr); + msg_set_origport(msg, ref); msg_set_destnode(msg, dest->node); msg_set_destport(msg, dest->ref); msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); p_ptr->sent++; if (dest->node == tipc_own_addr) return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); @@ -1378,31 +1347,11 @@ static int tipc_forward2port(u32 ref, } /** - * tipc_send2port - send message sections to port identity + * tipc_send_buf2port - send message buffer to port identity */ -int tipc_send2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig, - TIPC_PORT_IMPORTANCE); -} - -/** - * tipc_forward_buf2port - forward message buffer to port identity - */ -static int tipc_forward_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) +int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, + struct sk_buff *buf, unsigned int dsz) { struct port *p_ptr; struct tipc_msg *msg; @@ -1414,13 +1363,11 @@ static int tipc_forward_buf2port(u32 ref, msg = &p_ptr->publ.phdr; msg_set_type(msg, TIPC_DIRECT_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); + msg_set_orignode(msg, tipc_own_addr); + msg_set_origport(msg, ref); msg_set_destnode(msg, dest->node); msg_set_destport(msg, dest->ref); msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); msg_set_size(msg, DIR_MSG_H_SIZE + dsz); if (skb_cow(buf, DIR_MSG_H_SIZE)) return -ENOMEM; @@ -1439,20 +1386,3 @@ static int tipc_forward_buf2port(u32 ref, return -ELINKCONG; } -/** - * tipc_send_buf2port - send message buffer to port identity - */ - -int tipc_send_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward_buf2port(ref, dest, buf, dsz, &orig, - TIPC_PORT_IMPORTANCE); -} - diff --git a/net/tipc/port.h b/net/tipc/port.h index 711b4a0fa443..3f6c0aaa171d 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -222,8 +222,6 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr); /* * TIPC messaging routines */ -#define TIPC_PORT_IMPORTANCE 100 /* send using current port setting */ - int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, -- cgit v1.2.3-59-g8ed1b From b924dcf0038b8f83e65b44f679ad480d44f85aa6 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 30 Nov 2010 12:01:03 +0000 Subject: tipc: Delete tipc_ownidentity() Moves the content of the native API routine tipc_ownidentity() into the sole routine that calls it, since it can no longer be called in isolation. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/port.c | 7 ------- net/tipc/port.h | 2 -- net/tipc/socket.c | 3 ++- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/net/tipc/port.c b/net/tipc/port.c index 73f232c1fe15..7873283f4965 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -983,13 +983,6 @@ int tipc_createport(u32 user_ref, return 0; } -int tipc_ownidentity(u32 ref, struct tipc_portid *id) -{ - id->ref = ref; - id->node = tipc_own_addr; - return 0; -} - int tipc_portimportance(u32 ref, unsigned int *importance) { struct port *p_ptr; diff --git a/net/tipc/port.h b/net/tipc/port.h index 3f6c0aaa171d..3a807fcec2be 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -191,8 +191,6 @@ int tipc_createport(unsigned int tipc_user, void *usr_handle, int tipc_deleteport(u32 portref); -int tipc_ownidentity(u32 portref, struct tipc_portid *port); - int tipc_portimportance(u32 portref, unsigned int *importance); int tipc_set_portimportance(u32 portref, unsigned int importance); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 34f96eda5fa3..cd0bb77f2673 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -403,7 +403,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, addr->addr.id.ref = tsock->peer_name.ref; addr->addr.id.node = tsock->peer_name.node; } else { - tipc_ownidentity(tsock->p->ref, &addr->addr.id); + addr->addr.id.ref = tsock->p->ref; + addr->addr.id.node = tipc_own_addr; } *uaddr_len = sizeof(*addr); -- cgit v1.2.3-59-g8ed1b From f18ca364617d5e1fdd7300e025473496e397db4b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:46:09 +0000 Subject: sfc: Reduce log level for MCDI error response in efx_mcdi_rpc() Some errors are expected, e.g. when sending new commands to an MC running old firmware. Only the caller of efx_mcdi_rpc() can decide what is a real error. Therefore log the error responses with netif_dbg(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/mcdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 12cf910c2ce7..e389ac6c214f 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -381,7 +381,7 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, -rc); efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); } else - netif_err(efx, hw, efx->net_dev, + netif_dbg(efx, hw, efx->net_dev, "MC command 0x%x inlen %d failed rc=%d\n", cmd, (int)inlen, -rc); } -- cgit v1.2.3-59-g8ed1b From 4484cd7dedecf59aee0775c6658f95bdee65f277 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:46:14 +0000 Subject: sfc: Fix condition for no-op in set_phy_flash_cfg() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon_boards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index cfc6a5b5a477..cfc29d767588 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -325,7 +325,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev, new_mode = old_mode & ~PHY_MODE_SPECIAL; else new_mode = PHY_MODE_SPECIAL; - if (old_mode == new_mode) { + if (!((old_mode ^ new_mode) & PHY_MODE_SPECIAL)) { err = 0; } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { err = -EBUSY; -- cgit v1.2.3-59-g8ed1b From 71839f7d162f973f5931d30d1376a2dc5c0bed5a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:46:24 +0000 Subject: sfc: Distinguish critical and non-critical over-temperature conditions Set both the 'maximum' and critical temperature limits for LM87 hardware monitors on Falcon boards. Do not shut down a port until the critical temperature is reached, but warn as soon as the 'maximum' temperature is reached. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon_boards.c | 109 +++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index cfc29d767588..86180ee02ec0 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -30,17 +30,28 @@ #define FALCON_BOARD_SFN4112F 0x52 /* Board temperature is about 15°C above ambient when air flow is - * limited. */ + * limited. The maximum acceptable ambient temperature varies + * depending on the PHY specifications but the critical temperature + * above which we should shut down to avoid damage is 80°C. */ #define FALCON_BOARD_TEMP_BIAS 15 +#define FALCON_BOARD_TEMP_CRIT (80 + FALCON_BOARD_TEMP_BIAS) /* SFC4000 datasheet says: 'The maximum permitted junction temperature * is 125°C; the thermal design of the environment for the SFC4000 * should aim to keep this well below 100°C.' */ +#define FALCON_JUNC_TEMP_MIN 0 #define FALCON_JUNC_TEMP_MAX 90 +#define FALCON_JUNC_TEMP_CRIT 125 /***************************************************************************** * Support for LM87 sensor chip used on several boards */ +#define LM87_REG_TEMP_HW_INT_LOCK 0x13 +#define LM87_REG_TEMP_HW_EXT_LOCK 0x14 +#define LM87_REG_TEMP_HW_INT 0x17 +#define LM87_REG_TEMP_HW_EXT 0x18 +#define LM87_REG_TEMP_EXT1 0x26 +#define LM87_REG_TEMP_INT 0x27 #define LM87_REG_ALARMS1 0x41 #define LM87_REG_ALARMS2 0x42 #define LM87_IN_LIMITS(nr, _min, _max) \ @@ -57,6 +68,27 @@ #if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE) +static int efx_poke_lm87(struct i2c_client *client, const u8 *reg_values) +{ + while (*reg_values) { + u8 reg = *reg_values++; + u8 value = *reg_values++; + int rc = i2c_smbus_write_byte_data(client, reg, value); + if (rc) + return rc; + } + return 0; +} + +static const u8 falcon_lm87_common_regs[] = { + LM87_REG_TEMP_HW_INT_LOCK, FALCON_BOARD_TEMP_CRIT, + LM87_REG_TEMP_HW_INT, FALCON_BOARD_TEMP_CRIT, + LM87_TEMP_EXT1_LIMITS(FALCON_JUNC_TEMP_MIN, FALCON_JUNC_TEMP_MAX), + LM87_REG_TEMP_HW_EXT_LOCK, FALCON_JUNC_TEMP_CRIT, + LM87_REG_TEMP_HW_EXT, FALCON_JUNC_TEMP_CRIT, + 0 +}; + static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, const u8 *reg_values) { @@ -67,13 +99,12 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, if (!client) return -EIO; - while (*reg_values) { - u8 reg = *reg_values++; - u8 value = *reg_values++; - rc = i2c_smbus_write_byte_data(client, reg, value); - if (rc) - goto err; - } + rc = efx_poke_lm87(client, reg_values); + if (rc) + goto err; + rc = efx_poke_lm87(client, falcon_lm87_common_regs); + if (rc) + goto err; board->hwmon_client = client; return 0; @@ -91,36 +122,56 @@ static void efx_fini_lm87(struct efx_nic *efx) static int efx_check_lm87(struct efx_nic *efx, unsigned mask) { struct i2c_client *client = falcon_board(efx)->hwmon_client; - s32 alarms1, alarms2; + bool temp_crit, elec_fault, is_failure; + u16 alarms; + s32 reg; /* If link is up then do not monitor temperature */ if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) return 0; - alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); - alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); - if (alarms1 < 0) - return alarms1; - if (alarms2 < 0) - return alarms2; - alarms1 &= mask; - alarms2 &= mask >> 8; - if (alarms1 || alarms2) { + reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); + if (reg < 0) + return reg; + alarms = reg; + reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); + if (reg < 0) + return reg; + alarms |= reg << 8; + alarms &= mask; + + temp_crit = false; + if (alarms & LM87_ALARM_TEMP_INT) { + reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_INT); + if (reg < 0) + return reg; + if (reg > FALCON_BOARD_TEMP_CRIT) + temp_crit = true; + } + if (alarms & LM87_ALARM_TEMP_EXT1) { + reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_EXT1); + if (reg < 0) + return reg; + if (reg > FALCON_JUNC_TEMP_CRIT) + temp_crit = true; + } + elec_fault = alarms & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1); + is_failure = temp_crit || elec_fault; + + if (alarms) netif_err(efx, hw, efx->net_dev, - "LM87 detected a hardware failure (status %02x:%02x)" - "%s%s%s\n", - alarms1, alarms2, - (alarms1 & LM87_ALARM_TEMP_INT) ? + "LM87 detected a hardware %s (status %02x:%02x)" + "%s%s%s%s\n", + is_failure ? "failure" : "problem", + alarms & 0xff, alarms >> 8, + (alarms & LM87_ALARM_TEMP_INT) ? "; board is overheating" : "", - (alarms1 & LM87_ALARM_TEMP_EXT1) ? + (alarms & LM87_ALARM_TEMP_EXT1) ? "; controller is overheating" : "", - (alarms1 & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1) - || alarms2) ? - "; electrical fault" : ""); - return -ERANGE; - } + temp_crit ? "; reached critical temperature" : "", + elec_fault ? "; electrical fault" : ""); - return 0; + return is_failure ? -ERANGE : 0; } #else /* !CONFIG_SENSORS_LM87 */ -- cgit v1.2.3-59-g8ed1b From adc1d234116c22247e3886fb6e9bef450a0110f2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:46:31 +0000 Subject: sfc: Read-to-clear LM87 alarm/interrupt status at start of day We do not want to shut down the board based on a fault that has already been cleared. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon_boards.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 86180ee02ec0..6c20d4569d81 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -99,6 +99,10 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, if (!client) return -EIO; + /* Read-to-clear alarm/interrupt status */ + i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); + i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); + rc = efx_poke_lm87(client, reg_values); if (rc) goto err; -- cgit v1.2.3-59-g8ed1b From 3157183a90fdbd686f939d2f032b675f7e9983d6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:46:37 +0000 Subject: sfc: Clear RXIN_SEL when soft-resetting QT2025C When we enable PMA/PMD loopback this automatically sets RXIN_SEL (inverse polarity for RXIN). We need to clear that bit during the soft-reset sequence, as it is not done automatically. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/qt202x_phy.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 68813d1d85f3..ea3ae0089315 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -41,6 +41,8 @@ #define PCS_UC_STATUS_LBN 0 #define PCS_UC_STATUS_WIDTH 8 #define PCS_UC_STATUS_FW_SAVE 0x20 +#define PMA_PMD_MODE_REG 0xc301 +#define PMA_PMD_RXIN_SEL_LBN 6 #define PMA_PMD_FTX_CTRL2_REG 0xc309 #define PMA_PMD_FTX_STATIC_LBN 13 #define PMA_PMD_VEND1_REG 0xc001 @@ -282,6 +284,10 @@ static int qt2025c_select_phy_mode(struct efx_nic *efx) * slow) reload of the firmware image (the microcontroller's code * memory is not affected by the microcontroller reset). */ efx_mdio_write(efx, 1, 0xc317, 0x00ff); + /* PMA/PMD loopback sets RXIN to inverse polarity and the firmware + * restart doesn't reset it. We need to do that ourselves. */ + efx_mdio_set_flag(efx, 1, PMA_PMD_MODE_REG, + 1 << PMA_PMD_RXIN_SEL_LBN, false); efx_mdio_write(efx, 1, 0xc300, 0x0002); msleep(20); -- cgit v1.2.3-59-g8ed1b From 18e3ee2cf96adf072deeb291eed670f2c23bb2fc Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 2 Dec 2010 13:46:55 +0000 Subject: sfc: Fix event based MCDI completion and MC REBOOT/CMDDONE ordering issue The mcfw *never* sends CMDDONE when rebooting. Changing this so that it always sends CMDDONE *before* REBOOT is easy on Siena, but it's not obvious that we could guarantee to be able to implement this on future hardware. Given this, I'm less convinced that the protocol should be changed. To reiterate the failure mode: The driver sees this: issue command receive REBOOT event Was that reboot event sent before the command was issued, or in response to the command? If the former then there will be a subsequent CMDDONE event, if the latter, then there will be no CMDDONE event. Options to resolve this are: 1. REBOOT always completes an outstanding mcdi request, and we set the credits count to ignore a subsequent CMDDONE event with mismatching seqno. 2. REBOOT never completes an outstanding mcdi request. If there is no CMDDONE event then we rely on the mcdi timeout code to complete the outstanding request, incurring a 10s delay. I'd argue that (2) is tidier, but that incurring a 10s delay is a little needless. Let's go with (1). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/mcdi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index e389ac6c214f..b716e827b291 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -463,6 +463,7 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) if (mcdi->mode == MCDI_MODE_EVENTS) { mcdi->resprc = rc; mcdi->resplen = 0; + ++mcdi->credits; } } else /* Nobody was waiting for an MCDI request, so trigger a reset */ -- cgit v1.2.3-59-g8ed1b From 6c88b0b6dc886e49c0e6ee21d677c2e380bde688 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:01 +0000 Subject: sfc: Remove broken automatic fallback for invalid Falcon chip/board config If the Falcon board config is invalid, we cannot proceed - we do not have a valid board type to pass to falcon_probe_board(), and if we kluge that to work with an unknown board then other initialisation code will crash. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 57 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 267019bb2b15..b2c3381c3cdb 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1235,7 +1235,6 @@ static void falcon_remove_spi_devices(struct efx_nic *efx) static int falcon_probe_nvconfig(struct efx_nic *efx) { struct falcon_nvconfig *nvconfig; - int board_rev; int rc; nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL); @@ -1243,37 +1242,25 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) return -ENOMEM; rc = falcon_read_nvram(efx, nvconfig); - if (rc == -EINVAL) { - netif_err(efx, probe, efx->net_dev, - "NVRAM is invalid therefore using defaults\n"); - efx->phy_type = PHY_TYPE_NONE; - efx->mdio.prtad = MDIO_PRTAD_NONE; - board_rev = 0; - rc = 0; - } else if (rc) { + if (rc) goto fail1; - } else { - struct falcon_nvconfig_board_v2 *v2 = &nvconfig->board_v2; - struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3; - - efx->phy_type = v2->port0_phy_type; - efx->mdio.prtad = v2->port0_phy_addr; - board_rev = le16_to_cpu(v2->board_revision); - - if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { - rc = falcon_spi_device_init( - efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, - le32_to_cpu(v3->spi_device_type - [FFE_AB_SPI_DEVICE_FLASH])); - if (rc) - goto fail2; - rc = falcon_spi_device_init( - efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, - le32_to_cpu(v3->spi_device_type - [FFE_AB_SPI_DEVICE_EEPROM])); - if (rc) - goto fail2; - } + + efx->phy_type = nvconfig->board_v2.port0_phy_type; + efx->mdio.prtad = nvconfig->board_v2.port0_phy_addr; + + if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { + rc = falcon_spi_device_init( + efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, + le32_to_cpu(nvconfig->board_v3 + .spi_device_type[FFE_AB_SPI_DEVICE_FLASH])); + if (rc) + goto fail2; + rc = falcon_spi_device_init( + efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, + le32_to_cpu(nvconfig->board_v3 + .spi_device_type[FFE_AB_SPI_DEVICE_EEPROM])); + if (rc) + goto fail2; } /* Read the MAC addresses */ @@ -1282,7 +1269,8 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) netif_dbg(efx, probe, efx->net_dev, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad); - rc = falcon_probe_board(efx, board_rev); + rc = falcon_probe_board(efx, + le16_to_cpu(nvconfig->board_v2.board_revision)); if (rc) goto fail2; @@ -1419,8 +1407,11 @@ static int falcon_probe_nic(struct efx_nic *efx) /* Read in the non-volatile configuration */ rc = falcon_probe_nvconfig(efx); - if (rc) + if (rc) { + if (rc == -EINVAL) + netif_err(efx, probe, efx->net_dev, "NVRAM is invalid\n"); goto fail5; + } /* Initialise I2C adapter */ board = falcon_board(efx); -- cgit v1.2.3-59-g8ed1b From 6a8872c54d177abd900a0cf165b76ecb4803f052 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:10 +0000 Subject: sfc: Expose Falcon BootROM config through MTD, not ethtool The ethtool EEPROM interface is really meant for exposing chip configuration, not BootROM configuration. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 59 ------------------------------------ drivers/net/sfc/mtd.c | 77 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 82 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index edb9d16b8b47..00fb6743c8a6 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -17,7 +17,6 @@ #include "efx.h" #include "filter.h" #include "nic.h" -#include "spi.h" #include "mdio_10g.h" struct ethtool_string { @@ -629,61 +628,6 @@ static u32 efx_ethtool_get_link(struct net_device *net_dev) return efx->link_state.up; } -static int efx_ethtool_get_eeprom_len(struct net_device *net_dev) -{ - struct efx_nic *efx = netdev_priv(net_dev); - struct efx_spi_device *spi = efx->spi_eeprom; - - if (!spi) - return 0; - return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) - - min(spi->size, EFX_EEPROM_BOOTCONFIG_START); -} - -static int efx_ethtool_get_eeprom(struct net_device *net_dev, - struct ethtool_eeprom *eeprom, u8 *buf) -{ - struct efx_nic *efx = netdev_priv(net_dev); - struct efx_spi_device *spi = efx->spi_eeprom; - size_t len; - int rc; - - rc = mutex_lock_interruptible(&efx->spi_lock); - if (rc) - return rc; - rc = falcon_spi_read(efx, spi, - eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, - eeprom->len, &len, buf); - mutex_unlock(&efx->spi_lock); - - eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC; - eeprom->len = len; - return rc; -} - -static int efx_ethtool_set_eeprom(struct net_device *net_dev, - struct ethtool_eeprom *eeprom, u8 *buf) -{ - struct efx_nic *efx = netdev_priv(net_dev); - struct efx_spi_device *spi = efx->spi_eeprom; - size_t len; - int rc; - - if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC) - return -EINVAL; - - rc = mutex_lock_interruptible(&efx->spi_lock); - if (rc) - return rc; - rc = falcon_spi_write(efx, spi, - eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, - eeprom->len, &len, buf); - mutex_unlock(&efx->spi_lock); - - eeprom->len = len; - return rc; -} - static int efx_ethtool_get_coalesce(struct net_device *net_dev, struct ethtool_coalesce *coalesce) { @@ -1116,9 +1060,6 @@ const struct ethtool_ops efx_ethtool_ops = { .set_msglevel = efx_ethtool_set_msglevel, .nway_reset = efx_ethtool_nway_reset, .get_link = efx_ethtool_get_link, - .get_eeprom_len = efx_ethtool_get_eeprom_len, - .get_eeprom = efx_ethtool_get_eeprom, - .set_eeprom = efx_ethtool_set_eeprom, .get_coalesce = efx_ethtool_get_coalesce, .set_coalesce = efx_ethtool_set_coalesce, .get_ringparam = efx_ethtool_get_ringparam, diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index 02e54b4f701f..d44c74584e0f 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c @@ -387,35 +387,66 @@ static struct efx_mtd_ops falcon_mtd_ops = { static int falcon_mtd_probe(struct efx_nic *efx) { - struct efx_spi_device *spi = efx->spi_flash; + struct efx_spi_device *spi; struct efx_mtd *efx_mtd; - int rc; + int rc = -ENODEV; ASSERT_RTNL(); - if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START) - return -ENODEV; - - efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]), - GFP_KERNEL); - if (!efx_mtd) - return -ENOMEM; - - efx_mtd->spi = spi; - efx_mtd->name = "flash"; - efx_mtd->ops = &falcon_mtd_ops; + spi = efx->spi_flash; + if (spi && spi->size > FALCON_FLASH_BOOTCODE_START) { + efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]), + GFP_KERNEL); + if (!efx_mtd) + return -ENOMEM; + + efx_mtd->spi = spi; + efx_mtd->name = "flash"; + efx_mtd->ops = &falcon_mtd_ops; + + efx_mtd->n_parts = 1; + efx_mtd->part[0].mtd.type = MTD_NORFLASH; + efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH; + efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START; + efx_mtd->part[0].mtd.erasesize = spi->erase_size; + efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START; + efx_mtd->part[0].type_name = "sfc_flash_bootrom"; + + rc = efx_mtd_probe_device(efx, efx_mtd); + if (rc) { + kfree(efx_mtd); + return rc; + } + } - efx_mtd->n_parts = 1; - efx_mtd->part[0].mtd.type = MTD_NORFLASH; - efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH; - efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START; - efx_mtd->part[0].mtd.erasesize = spi->erase_size; - efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START; - efx_mtd->part[0].type_name = "sfc_flash_bootrom"; + spi = efx->spi_eeprom; + if (spi && spi->size > EFX_EEPROM_BOOTCONFIG_START) { + efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]), + GFP_KERNEL); + if (!efx_mtd) + return -ENOMEM; + + efx_mtd->spi = spi; + efx_mtd->name = "EEPROM"; + efx_mtd->ops = &falcon_mtd_ops; + + efx_mtd->n_parts = 1; + efx_mtd->part[0].mtd.type = MTD_RAM; + efx_mtd->part[0].mtd.flags = MTD_CAP_RAM; + efx_mtd->part[0].mtd.size = + min(spi->size, EFX_EEPROM_BOOTCONFIG_END) - + EFX_EEPROM_BOOTCONFIG_START; + efx_mtd->part[0].mtd.erasesize = spi->erase_size; + efx_mtd->part[0].offset = EFX_EEPROM_BOOTCONFIG_START; + efx_mtd->part[0].type_name = "sfc_bootconfig"; + + rc = efx_mtd_probe_device(efx, efx_mtd); + if (rc) { + kfree(efx_mtd); + return rc; + } + } - rc = efx_mtd_probe_device(efx, efx_mtd); - if (rc) - kfree(efx_mtd); return rc; } -- cgit v1.2.3-59-g8ed1b From 90b7a4ee610bf1d14120f5e0618ae2a3568394a5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:17 +0000 Subject: sfc: Remove unnecessary inclusion of various private header files Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 1 - drivers/net/sfc/ethtool.c | 1 - drivers/net/sfc/falcon.c | 1 - drivers/net/sfc/falcon_boards.c | 2 -- drivers/net/sfc/falcon_xmac.c | 1 - drivers/net/sfc/mcdi_phy.c | 1 - drivers/net/sfc/mdio_10g.c | 1 - drivers/net/sfc/tenxpress.c | 2 -- 8 files changed, 10 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e47976..b4580c4ea7ed 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -23,7 +23,6 @@ #include #include "net_driver.h" #include "efx.h" -#include "mdio_10g.h" #include "nic.h" #include "mcdi.h" diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 00fb6743c8a6..aae756bf47ee 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -17,7 +17,6 @@ #include "efx.h" #include "filter.h" #include "nic.h" -#include "mdio_10g.h" struct ethtool_string { char name[ETH_GSTRING_LEN]; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b2c3381c3cdb..fe150842d82b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -24,7 +24,6 @@ #include "nic.h" #include "regs.h" #include "io.h" -#include "mdio_10g.h" #include "phy.h" #include "workarounds.h" diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 6c20d4569d81..a6fc5ce88c88 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -13,8 +13,6 @@ #include "phy.h" #include "efx.h" #include "nic.h" -#include "regs.h" -#include "io.h" #include "workarounds.h" /* Macros for unpacking the board revision */ diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index b31f595ebb5b..e293e25d1348 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -16,7 +16,6 @@ #include "io.h" #include "mac.h" #include "mdio_10g.h" -#include "phy.h" #include "workarounds.h" /************************************************************************** diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index c992742446b1..0e97eed663c6 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -16,7 +16,6 @@ #include "phy.h" #include "mcdi.h" #include "mcdi_pcol.h" -#include "mdio_10g.h" #include "nic.h" #include "selftest.h" diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 98d946020429..56b0266b441f 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -15,7 +15,6 @@ #include "net_driver.h" #include "mdio_10g.h" #include "workarounds.h" -#include "nic.h" unsigned efx_mdio_id_oui(u32 id) { diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 1bc6c48c96ee..f102912eba91 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -15,9 +15,7 @@ #include "mdio_10g.h" #include "nic.h" #include "phy.h" -#include "regs.h" #include "workarounds.h" -#include "selftest.h" /* We expect these MMDs to be in the package. */ #define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ -- cgit v1.2.3-59-g8ed1b From 4de92180258ac661bbce0f0065c9c81633ac862b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:29 +0000 Subject: sfc: Move SPI state to struct falcon_nic_data We only have direct access to SPI on Falcon, so move all this state out of struct efx_nic. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 4 -- drivers/net/sfc/falcon.c | 91 +++++++++++++++++++------------------------- drivers/net/sfc/mtd.c | 29 ++++++++------ drivers/net/sfc/net_driver.h | 8 ---- drivers/net/sfc/nic.h | 7 ++++ drivers/net/sfc/spi.h | 5 +++ 6 files changed, 69 insertions(+), 75 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index b4580c4ea7ed..6aed6acdd2d6 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1961,7 +1961,6 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method) efx_stop_all(efx); mutex_lock(&efx->mac_lock); - mutex_lock(&efx->spi_lock); efx_fini_channels(efx); if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) @@ -2003,7 +2002,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) efx_init_channels(efx); efx_restore_filters(efx); - mutex_unlock(&efx->spi_lock); mutex_unlock(&efx->mac_lock); efx_start_all(efx); @@ -2013,7 +2011,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) fail: efx->port_initialized = false; - mutex_unlock(&efx->spi_lock); mutex_unlock(&efx->mac_lock); return rc; @@ -2202,7 +2199,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, memset(efx, 0, sizeof(*efx)); spin_lock_init(&efx->biu_lock); mutex_init(&efx->mdio_lock); - mutex_init(&efx->spi_lock); #ifdef CONFIG_SFC_MTD INIT_LIST_HEAD(&efx->mtd_list); #endif diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index fe150842d82b..ca59f7e02df4 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -254,7 +254,6 @@ int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, /* Input validation */ if (len > FALCON_SPI_MAX_LEN) return -EINVAL; - BUG_ON(!mutex_is_locked(&efx->spi_lock)); /* Check that previous command is not still running */ rc = falcon_spi_poll(efx); @@ -888,6 +887,7 @@ static void falcon_remove_port(struct efx_nic *efx) static int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) { + struct falcon_nic_data *nic_data = efx->nic_data; struct falcon_nvconfig *nvconfig; struct efx_spi_device *spi; void *region; @@ -895,8 +895,11 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) __le16 *word, *limit; u32 csum; - spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom; - if (!spi) + if (efx_spi_present(&nic_data->spi_flash)) + spi = &nic_data->spi_flash; + else if (efx_spi_present(&nic_data->spi_eeprom)) + spi = &nic_data->spi_eeprom; + else return -EINVAL; region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL); @@ -904,12 +907,13 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) return -ENOMEM; nvconfig = region + FALCON_NVCONFIG_OFFSET; - mutex_lock(&efx->spi_lock); + mutex_lock(&nic_data->spi_lock); rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region); - mutex_unlock(&efx->spi_lock); + mutex_unlock(&nic_data->spi_lock); if (rc) { netif_err(efx, hw, efx->net_dev, "Failed to read %s\n", - efx->spi_flash ? "flash" : "EEPROM"); + efx_spi_present(&nic_data->spi_flash) ? + "flash" : "EEPROM"); rc = -EIO; goto out; } @@ -1011,7 +1015,7 @@ static int falcon_b0_test_registers(struct efx_nic *efx) /* Resets NIC to known state. This routine must be called in process * context and is allowed to sleep. */ -static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) +static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t glb_ctl_reg_ker; @@ -1107,6 +1111,18 @@ fail5: return rc; } +static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) +{ + struct falcon_nic_data *nic_data = efx->nic_data; + int rc; + + mutex_lock(&nic_data->spi_lock); + rc = __falcon_reset_hw(efx, method); + mutex_unlock(&nic_data->spi_lock); + + return rc; +} + static void falcon_monitor(struct efx_nic *efx) { bool link_changed; @@ -1188,16 +1204,11 @@ static int falcon_reset_sram(struct efx_nic *efx) return -ETIMEDOUT; } -static int falcon_spi_device_init(struct efx_nic *efx, - struct efx_spi_device **spi_device_ret, +static void falcon_spi_device_init(struct efx_nic *efx, + struct efx_spi_device *spi_device, unsigned int device_id, u32 device_type) { - struct efx_spi_device *spi_device; - if (device_type != 0) { - spi_device = kzalloc(sizeof(*spi_device), GFP_KERNEL); - if (!spi_device) - return -ENOMEM; spi_device->device_id = device_id; spi_device->size = 1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_SIZE); @@ -1214,25 +1225,14 @@ static int falcon_spi_device_init(struct efx_nic *efx, 1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_BLOCK_SIZE); } else { - spi_device = NULL; + spi_device->size = 0; } - - kfree(*spi_device_ret); - *spi_device_ret = spi_device; - return 0; -} - -static void falcon_remove_spi_devices(struct efx_nic *efx) -{ - kfree(efx->spi_eeprom); - efx->spi_eeprom = NULL; - kfree(efx->spi_flash); - efx->spi_flash = NULL; } /* Extract non-volatile configuration */ static int falcon_probe_nvconfig(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; struct falcon_nvconfig *nvconfig; int rc; @@ -1242,24 +1242,20 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) rc = falcon_read_nvram(efx, nvconfig); if (rc) - goto fail1; + goto out; efx->phy_type = nvconfig->board_v2.port0_phy_type; efx->mdio.prtad = nvconfig->board_v2.port0_phy_addr; if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { - rc = falcon_spi_device_init( - efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, + falcon_spi_device_init( + efx, &nic_data->spi_flash, FFE_AB_SPI_DEVICE_FLASH, le32_to_cpu(nvconfig->board_v3 .spi_device_type[FFE_AB_SPI_DEVICE_FLASH])); - if (rc) - goto fail2; - rc = falcon_spi_device_init( - efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, + falcon_spi_device_init( + efx, &nic_data->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, le32_to_cpu(nvconfig->board_v3 .spi_device_type[FFE_AB_SPI_DEVICE_EEPROM])); - if (rc) - goto fail2; } /* Read the MAC addresses */ @@ -1270,15 +1266,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) rc = falcon_probe_board(efx, le16_to_cpu(nvconfig->board_v2.board_revision)); - if (rc) - goto fail2; - - kfree(nvconfig); - return 0; - - fail2: - falcon_remove_spi_devices(efx); - fail1: +out: kfree(nvconfig); return rc; } @@ -1286,6 +1274,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) /* Probe all SPI devices on the NIC */ static void falcon_probe_spi_devices(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; int boot_dev; @@ -1314,12 +1303,14 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); } + mutex_init(&nic_data->spi_lock); + if (boot_dev == FFE_AB_SPI_DEVICE_FLASH) - falcon_spi_device_init(efx, &efx->spi_flash, + falcon_spi_device_init(efx, &nic_data->spi_flash, FFE_AB_SPI_DEVICE_FLASH, default_flash_type); if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM) - falcon_spi_device_init(efx, &efx->spi_eeprom, + falcon_spi_device_init(efx, &nic_data->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, large_eeprom_type); } @@ -1384,7 +1375,7 @@ static int falcon_probe_nic(struct efx_nic *efx) } /* Now we can reset the NIC */ - rc = falcon_reset_hw(efx, RESET_TYPE_ALL); + rc = __falcon_reset_hw(efx, RESET_TYPE_ALL); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n"); goto fail3; @@ -1442,7 +1433,6 @@ static int falcon_probe_nic(struct efx_nic *efx) BUG_ON(i2c_del_adapter(&board->i2c_adap)); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: - falcon_remove_spi_devices(efx); efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: @@ -1596,10 +1586,9 @@ static void falcon_remove_nic(struct efx_nic *efx) BUG_ON(rc); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); - falcon_remove_spi_devices(efx); efx_nic_free_buffer(efx, &efx->irq_status); - falcon_reset_hw(efx, RESET_TYPE_ALL); + __falcon_reset_hw(efx, RESET_TYPE_ALL); /* Release the second function after the reset */ if (nic_data->pci_dev2) { diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index d44c74584e0f..d38627448c22 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c @@ -321,14 +321,15 @@ static int falcon_mtd_read(struct mtd_info *mtd, loff_t start, struct efx_mtd *efx_mtd = mtd->priv; const struct efx_spi_device *spi = efx_mtd->spi; struct efx_nic *efx = efx_mtd->efx; + struct falcon_nic_data *nic_data = efx->nic_data; int rc; - rc = mutex_lock_interruptible(&efx->spi_lock); + rc = mutex_lock_interruptible(&nic_data->spi_lock); if (rc) return rc; rc = falcon_spi_read(efx, spi, part->offset + start, len, retlen, buffer); - mutex_unlock(&efx->spi_lock); + mutex_unlock(&nic_data->spi_lock); return rc; } @@ -337,13 +338,14 @@ static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len) struct efx_mtd_partition *part = to_efx_mtd_partition(mtd); struct efx_mtd *efx_mtd = mtd->priv; struct efx_nic *efx = efx_mtd->efx; + struct falcon_nic_data *nic_data = efx->nic_data; int rc; - rc = mutex_lock_interruptible(&efx->spi_lock); + rc = mutex_lock_interruptible(&nic_data->spi_lock); if (rc) return rc; rc = efx_spi_erase(part, part->offset + start, len); - mutex_unlock(&efx->spi_lock); + mutex_unlock(&nic_data->spi_lock); return rc; } @@ -354,14 +356,15 @@ static int falcon_mtd_write(struct mtd_info *mtd, loff_t start, struct efx_mtd *efx_mtd = mtd->priv; const struct efx_spi_device *spi = efx_mtd->spi; struct efx_nic *efx = efx_mtd->efx; + struct falcon_nic_data *nic_data = efx->nic_data; int rc; - rc = mutex_lock_interruptible(&efx->spi_lock); + rc = mutex_lock_interruptible(&nic_data->spi_lock); if (rc) return rc; rc = falcon_spi_write(efx, spi, part->offset + start, len, retlen, buffer); - mutex_unlock(&efx->spi_lock); + mutex_unlock(&nic_data->spi_lock); return rc; } @@ -370,11 +373,12 @@ static int falcon_mtd_sync(struct mtd_info *mtd) struct efx_mtd_partition *part = to_efx_mtd_partition(mtd); struct efx_mtd *efx_mtd = mtd->priv; struct efx_nic *efx = efx_mtd->efx; + struct falcon_nic_data *nic_data = efx->nic_data; int rc; - mutex_lock(&efx->spi_lock); + mutex_lock(&nic_data->spi_lock); rc = efx_spi_slow_wait(part, true); - mutex_unlock(&efx->spi_lock); + mutex_unlock(&nic_data->spi_lock); return rc; } @@ -387,14 +391,15 @@ static struct efx_mtd_ops falcon_mtd_ops = { static int falcon_mtd_probe(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; struct efx_spi_device *spi; struct efx_mtd *efx_mtd; int rc = -ENODEV; ASSERT_RTNL(); - spi = efx->spi_flash; - if (spi && spi->size > FALCON_FLASH_BOOTCODE_START) { + spi = &nic_data->spi_flash; + if (efx_spi_present(spi) && spi->size > FALCON_FLASH_BOOTCODE_START) { efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]), GFP_KERNEL); if (!efx_mtd) @@ -419,8 +424,8 @@ static int falcon_mtd_probe(struct efx_nic *efx) } } - spi = efx->spi_eeprom; - if (spi && spi->size > EFX_EEPROM_BOOTCONFIG_START) { + spi = &nic_data->spi_eeprom; + if (efx_spi_present(spi) && spi->size > EFX_EEPROM_BOOTCONFIG_START) { efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]), GFP_KERNEL); if (!efx_mtd) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..e5ee2d53750e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -657,11 +657,6 @@ struct efx_filter_state; * to verify that an interrupt has occurred. * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 * @fatal_irq_level: IRQ level (bit number) used for serious errors - * @spi_flash: SPI flash device - * This field will be %NULL if no flash device is present (or for Siena). - * @spi_eeprom: SPI EEPROM device - * This field will be %NULL if no EEPROM device is present (or for Siena). - * @spi_lock: SPI bus lock * @mtd_list: List of MTDs attached to the NIC * @n_rx_nodesc_drop_cnt: RX no descriptor drop count * @nic_data: Hardware dependant state @@ -746,9 +741,6 @@ struct efx_nic { unsigned irq_zero_count; unsigned fatal_irq_level; - struct efx_spi_device *spi_flash; - struct efx_spi_device *spi_eeprom; - struct mutex spi_lock; #ifdef CONFIG_SFC_MTD struct list_head mtd_list; #endif diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 0438dc98722d..2a0fff324f1f 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -15,6 +15,7 @@ #include "net_driver.h" #include "efx.h" #include "mcdi.h" +#include "spi.h" /* * Falcon hardware control @@ -113,6 +114,9 @@ struct falcon_board { * @stats_pending: Is there a pending DMA of MAC statistics. * @stats_timer: A timer for regularly fetching MAC statistics. * @stats_dma_done: Pointer to the flag which indicates DMA completion. + * @spi_flash: SPI flash device + * @spi_eeprom: SPI EEPROM device + * @spi_lock: SPI bus lock */ struct falcon_nic_data { struct pci_dev *pci_dev2; @@ -121,6 +125,9 @@ struct falcon_nic_data { bool stats_pending; struct timer_list stats_timer; u32 *stats_dma_done; + struct efx_spi_device spi_flash; + struct efx_spi_device spi_eeprom; + struct mutex spi_lock; }; static inline struct falcon_board *falcon_board(struct efx_nic *efx) diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h index 8bf4fce0813a..879b7f6bde3d 100644 --- a/drivers/net/sfc/spi.h +++ b/drivers/net/sfc/spi.h @@ -61,6 +61,11 @@ struct efx_spi_device { unsigned int block_size; }; +static inline bool efx_spi_present(const struct efx_spi_device *spi) +{ + return spi->size != 0; +} + int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, unsigned int command, int address, const void* in, void *out, size_t len); -- cgit v1.2.3-59-g8ed1b From 4833f02a2972b7da4c8a15e1e329db0f984a75d9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:35 +0000 Subject: sfc: Move mdio_lock to struct falcon_nic_data We only have direct access to MDIO on Falcon, so move this out of struct efx_nic. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 1 - drivers/net/sfc/falcon.c | 11 +++++++---- drivers/net/sfc/net_driver.h | 2 -- drivers/net/sfc/nic.h | 2 ++ 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 6aed6acdd2d6..7e820d90e6ba 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2198,7 +2198,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, /* Initialise common structures */ memset(efx, 0, sizeof(*efx)); spin_lock_init(&efx->biu_lock); - mutex_init(&efx->mdio_lock); #ifdef CONFIG_SFC_MTD INIT_LIST_HEAD(&efx->mtd_list); #endif diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index ca59f7e02df4..af62899bb981 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -717,6 +717,7 @@ static int falcon_mdio_write(struct net_device *net_dev, int prtad, int devad, u16 addr, u16 value) { struct efx_nic *efx = netdev_priv(net_dev); + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t reg; int rc; @@ -724,7 +725,7 @@ static int falcon_mdio_write(struct net_device *net_dev, "writing MDIO %d register %d.%d with 0x%04x\n", prtad, devad, addr, value); - mutex_lock(&efx->mdio_lock); + mutex_lock(&nic_data->mdio_lock); /* Check MDIO not currently being accessed */ rc = falcon_gmii_wait(efx); @@ -760,7 +761,7 @@ static int falcon_mdio_write(struct net_device *net_dev, } out: - mutex_unlock(&efx->mdio_lock); + mutex_unlock(&nic_data->mdio_lock); return rc; } @@ -769,10 +770,11 @@ static int falcon_mdio_read(struct net_device *net_dev, int prtad, int devad, u16 addr) { struct efx_nic *efx = netdev_priv(net_dev); + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t reg; int rc; - mutex_lock(&efx->mdio_lock); + mutex_lock(&nic_data->mdio_lock); /* Check MDIO not currently being accessed */ rc = falcon_gmii_wait(efx); @@ -811,7 +813,7 @@ static int falcon_mdio_read(struct net_device *net_dev, } out: - mutex_unlock(&efx->mdio_lock); + mutex_unlock(&nic_data->mdio_lock); return rc; } @@ -839,6 +841,7 @@ static int falcon_probe_port(struct efx_nic *efx) } /* Fill out MDIO structure and loopback modes */ + mutex_init(&nic_data->mdio_lock); efx->mdio.mdio_read = falcon_mdio_read; efx->mdio.mdio_write = falcon_mdio_write; rc = efx->phy_op->probe(efx); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e5ee2d53750e..2ffc920d6ec0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -679,7 +679,6 @@ struct efx_filter_state; * @mac_op: MAC interface * @mac_address: Permanent MAC address * @phy_type: PHY type - * @mdio_lock: MDIO lock * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mdio: PHY MDIO interface @@ -766,7 +765,6 @@ struct efx_nic { unsigned char mac_address[ETH_ALEN]; unsigned int phy_type; - struct mutex mdio_lock; struct efx_phy_operations *phy_op; void *phy_data; struct mdio_if_info mdio; diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 2a0fff324f1f..980cf4b5a868 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -117,6 +117,7 @@ struct falcon_board { * @spi_flash: SPI flash device * @spi_eeprom: SPI EEPROM device * @spi_lock: SPI bus lock + * @mdio_lock: MDIO bus lock */ struct falcon_nic_data { struct pci_dev *pci_dev2; @@ -128,6 +129,7 @@ struct falcon_nic_data { struct efx_spi_device spi_flash; struct efx_spi_device spi_eeprom; struct mutex spi_lock; + struct mutex mdio_lock; }; static inline struct falcon_board *falcon_board(struct efx_nic *efx) -- cgit v1.2.3-59-g8ed1b From 40641ed93cd53561f7d53b5fd5ed656b35f3aabd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:45 +0000 Subject: sfc: Move Falcon global event handling to falcon.c Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 36 +++++++++++++++++++++++++++++++++ drivers/net/sfc/net_driver.h | 2 ++ drivers/net/sfc/nic.c | 48 +++++--------------------------------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index af62899bb981..fd5bf0b7e8a2 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -881,6 +881,40 @@ static void falcon_remove_port(struct efx_nic *efx) efx_nic_free_buffer(efx, &efx->stats_buffer); } +/* Global events are basically PHY events */ +static bool +falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event) +{ + struct efx_nic *efx = channel->efx; + + if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || + EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || + EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) + /* Ignored */ + return true; + + if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) && + EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { + efx->xmac_poll_required = true; + return true; + } + + if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ? + EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : + EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { + netif_err(efx, rx_err, efx->net_dev, + "channel %d seen global RX_RESET event. Resetting.\n", + channel->channel); + + atomic_inc(&efx->rx_reset); + efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? + RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); + return true; + } + + return false; +} + /************************************************************************** * * Falcon test code @@ -1702,6 +1736,7 @@ struct efx_nic_type falcon_a1_nic_type = { .reset = falcon_reset_hw, .probe_port = falcon_probe_port, .remove_port = falcon_remove_port, + .handle_global_event = falcon_handle_global_event, .prepare_flush = falcon_prepare_flush, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, @@ -1742,6 +1777,7 @@ struct efx_nic_type falcon_b0_nic_type = { .reset = falcon_reset_hw, .probe_port = falcon_probe_port, .remove_port = falcon_remove_port, + .handle_global_event = falcon_handle_global_event, .prepare_flush = falcon_prepare_flush, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2ffc920d6ec0..f9d53a01bbc5 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -819,6 +819,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * be called while the controller is uninitialised. * @probe_port: Probe the MAC and PHY * @remove_port: Free resources allocated by probe_port() + * @handle_global_event: Handle a "global" event (may be %NULL) * @prepare_flush: Prepare the hardware for flushing the DMA queues * @update_stats: Update statistics not provided by event handling * @start_stats: Start the regular fetching of statistics @@ -863,6 +864,7 @@ struct efx_nic_type { int (*reset)(struct efx_nic *efx, enum reset_type method); int (*probe_port)(struct efx_nic *efx); void (*remove_port)(struct efx_nic *efx); + bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *); void (*prepare_flush)(struct efx_nic *efx); void (*update_stats)(struct efx_nic *efx); void (*start_stats)(struct efx_nic *efx); diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a4244..9743cff15130 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -894,46 +894,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event) channel->channel, EFX_QWORD_VAL(*event)); } -/* Global events are basically PHY events */ -static void -efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event) -{ - struct efx_nic *efx = channel->efx; - bool handled = false; - - if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || - EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || - EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) { - /* Ignored */ - handled = true; - } - - if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) && - EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { - efx->xmac_poll_required = true; - handled = true; - } - - if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ? - EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : - EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { - netif_err(efx, rx_err, efx->net_dev, - "channel %d seen global RX_RESET event. Resetting.\n", - channel->channel); - - atomic_inc(&efx->rx_reset); - efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? - RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); - handled = true; - } - - if (!handled) - netif_err(efx, hw, efx->net_dev, - "channel %d unknown global event " - EFX_QWORD_FMT "\n", channel->channel, - EFX_QWORD_VAL(*event)); -} - static void efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event) { @@ -1050,15 +1010,17 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) case FSE_AZ_EV_CODE_DRV_GEN_EV: efx_handle_generated_event(channel, &event); break; - case FSE_AZ_EV_CODE_GLOBAL_EV: - efx_handle_global_event(channel, &event); - break; case FSE_AZ_EV_CODE_DRIVER_EV: efx_handle_driver_event(channel, &event); break; case FSE_CZ_EV_CODE_MCDI_EV: efx_mcdi_process_event(channel, &event); break; + case FSE_AZ_EV_CODE_GLOBAL_EV: + if (efx->type->handle_global_event && + efx->type->handle_global_event(channel, &event)) + break; + /* else fall through */ default: netif_err(channel->efx, hw, channel->efx->net_dev, "channel %d unknown event type %d (data " -- cgit v1.2.3-59-g8ed1b From cef68bde74f083d83c18ce870ed834e82ee0ae5a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:51 +0000 Subject: sfc: Move xmac_poll_required into struct falcon_nic_data Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 3 ++- drivers/net/sfc/falcon_boards.c | 3 ++- drivers/net/sfc/falcon_xmac.c | 13 +++++++++---- drivers/net/sfc/net_driver.h | 2 -- drivers/net/sfc/nic.h | 2 ++ 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index fd5bf0b7e8a2..07f684ed2d9b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -886,6 +886,7 @@ static bool falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event) { struct efx_nic *efx = channel->efx; + struct falcon_nic_data *nic_data = efx->nic_data; if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || @@ -895,7 +896,7 @@ falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event) if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) && EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { - efx->xmac_poll_required = true; + nic_data->xmac_poll_required = true; return true; } diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index a6fc5ce88c88..2dd16f0b3ced 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -415,10 +415,11 @@ static void sfe4001_fini(struct efx_nic *efx) static int sfe4001_check_hw(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; s32 status; /* If XAUI link is up then do not monitor */ - if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) + if (EFX_WORKAROUND_7884(efx) && !nic_data->xmac_poll_required) return 0; /* Check the powered status of the PHY. Lack of power implies that diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index e293e25d1348..b49e84394641 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -87,6 +87,7 @@ int falcon_reset_xaui(struct efx_nic *efx) static void falcon_ack_status_intr(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t reg; if ((efx_nic_rev(efx) != EFX_REV_FALCON_B0) || LOOPBACK_INTERNAL(efx)) @@ -98,7 +99,7 @@ static void falcon_ack_status_intr(struct efx_nic *efx) /* We can only use this interrupt to signal the negative edge of * xaui_align [we have to poll the positive edge]. */ - if (efx->xmac_poll_required) + if (nic_data->xmac_poll_required) return; efx_reado(efx, ®, FR_AB_XM_MGT_INT_MSK); @@ -276,12 +277,14 @@ static bool falcon_xmac_check_fault(struct efx_nic *efx) static int falcon_reconfigure_xmac(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; + falcon_reconfigure_xgxs_core(efx); falcon_reconfigure_xmac_core(efx); falcon_reconfigure_mac_wrapper(efx); - efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); + nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); falcon_ack_status_intr(efx); return 0; @@ -349,11 +352,13 @@ static void falcon_update_stats_xmac(struct efx_nic *efx) void falcon_poll_xmac(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; + if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || - !efx->xmac_poll_required) + !nic_data->xmac_poll_required) return; - efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); + nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); falcon_ack_status_intr(efx); } diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index f9d53a01bbc5..b7e8fe967826 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -684,7 +684,6 @@ struct efx_filter_state; * @mdio: PHY MDIO interface * @mdio_bus: PHY MDIO bus ID (only used by Siena) * @phy_mode: PHY operating mode. Serialised by @mac_lock. - * @xmac_poll_required: XMAC link state needs polling * @link_advertising: Autonegotiation advertising flags * @link_state: Current state of the link * @n_link_state_changes: Number of times the link has changed state @@ -771,7 +770,6 @@ struct efx_nic { unsigned int mdio_bus; enum efx_phy_mode phy_mode; - bool xmac_poll_required; u32 link_advertising; struct efx_link_state link_state; unsigned int n_link_state_changes; diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 980cf4b5a868..f107dc7d67c0 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -118,6 +118,7 @@ struct falcon_board { * @spi_eeprom: SPI EEPROM device * @spi_lock: SPI bus lock * @mdio_lock: MDIO bus lock + * @xmac_poll_required: XMAC link state needs polling */ struct falcon_nic_data { struct pci_dev *pci_dev2; @@ -130,6 +131,7 @@ struct falcon_nic_data { struct efx_spi_device spi_eeprom; struct mutex spi_lock; struct mutex mdio_lock; + bool xmac_poll_required; }; static inline struct falcon_board *falcon_board(struct efx_nic *efx) -- cgit v1.2.3-59-g8ed1b From 78d4189d6b000898db2d9a9d745468f1322cbc71 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:47:56 +0000 Subject: sfc: Update kernel-doc to match earlier move of Toeplitz hash key Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 1 + drivers/net/sfc/nic.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index b7e8fe967826..6dd5e6d65dfe 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -647,6 +647,7 @@ struct efx_filter_state; * @n_tx_channels: Number of channels used for TX * @rx_buffer_len: RX buffer length * @rx_buffer_order: Order (log2) of number of pages for each RX buffer + * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS * @int_error_count: Number of internal errors seen recently * @int_error_expire: Time at which error count will be expired diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index f107dc7d67c0..eb0586925b51 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -146,7 +146,6 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) * @fw_build: Firmware build number * @mcdi: Management-Controller-to-Driver Interface * @wol_filter_id: Wake-on-LAN packet filter id - * @ipv6_rss_key: Toeplitz hash key for IPv6 RSS */ struct siena_nic_data { u64 fw_version; -- cgit v1.2.3-59-g8ed1b From 4f3907e9a600a46d8c946469ce6636080310d12e Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 2 Dec 2010 13:48:14 +0000 Subject: sfc: When waking a stopped tx_queue, only lock that tx_queue Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/tx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 11726989fe2d..03194f7c0954 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -401,6 +401,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) { unsigned fill_level; struct efx_nic *efx = tx_queue->efx; + struct netdev_queue *queue; EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); @@ -417,12 +418,15 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) /* Do this under netif_tx_lock(), to avoid racing * with efx_xmit(). */ - netif_tx_lock(efx->net_dev); + queue = netdev_get_tx_queue( + efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES); + __netif_tx_lock(queue, smp_processor_id()); if (tx_queue->stopped) { tx_queue->stopped = 0; efx_wake_queue(tx_queue->channel); } - netif_tx_unlock(efx->net_dev); + __netif_tx_unlock(queue); } } } -- cgit v1.2.3-59-g8ed1b From 02ebc26865c2755720d2ede90a5ab27c45741823 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:48:20 +0000 Subject: sfc: Use current MAC address, not NVRAM MAC address, for WoL filter Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/siena.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 45236f58a258..b31598079c3d 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -562,7 +562,7 @@ static int siena_set_wol(struct efx_nic *efx, u32 type) if (nic_data->wol_filter_id != -1) efx_mcdi_wol_filter_remove(efx, nic_data->wol_filter_id); - rc = efx_mcdi_wol_filter_set_magic(efx, efx->mac_address, + rc = efx_mcdi_wol_filter_set_magic(efx, efx->net_dev->dev_addr, &nic_data->wol_filter_id); if (rc) goto fail; -- cgit v1.2.3-59-g8ed1b From 7e300bc8e6736d41e7b92978f415572ac60fd59b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 2 Dec 2010 13:48:28 +0000 Subject: sfc: Store MAC address from NVRAM in net_device::perm_addr For some reason we failed to make this change when perm_addr was introduced. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 8 +++++--- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/net_driver.h | 2 -- drivers/net/sfc/siena.c | 8 +------- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7e820d90e6ba..f3e4043d70ee 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -909,6 +909,7 @@ static void efx_mac_work(struct work_struct *data) static int efx_probe_port(struct efx_nic *efx) { + unsigned char *perm_addr; int rc; netif_dbg(efx, probe, efx->net_dev, "create port\n"); @@ -922,11 +923,12 @@ static int efx_probe_port(struct efx_nic *efx) return rc; /* Sanity check MAC address */ - if (is_valid_ether_addr(efx->mac_address)) { - memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); + perm_addr = efx->net_dev->perm_addr; + if (is_valid_ether_addr(perm_addr)) { + memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN); } else { netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n", - efx->mac_address); + perm_addr); if (!allow_bad_hwaddr) { rc = -EINVAL; goto err; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 07f684ed2d9b..70e4f7dcce81 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1297,7 +1297,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) } /* Read the MAC addresses */ - memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN); + memcpy(efx->net_dev->perm_addr, nvconfig->mac_address[0], ETH_ALEN); netif_dbg(efx, probe, efx->net_dev, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 6dd5e6d65dfe..0d19fbfc5c2c 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -678,7 +678,6 @@ struct efx_filter_state; * @stats_buffer: DMA buffer for statistics * @stats_lock: Statistics update lock. Serialises statistics fetches * @mac_op: MAC interface - * @mac_address: Permanent MAC address * @phy_type: PHY type * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) @@ -762,7 +761,6 @@ struct efx_nic { spinlock_t stats_lock; struct efx_mac_operations *mac_op; - unsigned char mac_address[ETH_ALEN]; unsigned int phy_type; struct efx_phy_operations *phy_op; diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index b31598079c3d..bf8456176443 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -194,13 +194,7 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) static int siena_probe_nvconfig(struct efx_nic *efx) { - int rc; - - rc = efx_mcdi_get_board_cfg(efx, efx->mac_address, NULL); - if (rc) - return rc; - - return 0; + return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL); } static int siena_probe_nic(struct efx_nic *efx) -- cgit v1.2.3-59-g8ed1b From 97319a270da37a5eab14a770f1417d8229245270 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 2 Dec 2010 20:41:23 +0000 Subject: qlcnic: Disable loopback support Loopback mode can not be supported in CNA mode. Removing it until FW is fixed. Signed-off-by: Sucheta Chakraborty Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 7 --- drivers/net/qlcnic/qlcnic_ethtool.c | 104 +----------------------------------- drivers/net/qlcnic/qlcnic_hw.c | 53 ------------------ drivers/net/qlcnic/qlcnic_init.c | 93 -------------------------------- drivers/net/qlcnic/qlcnic_main.c | 55 ------------------- 5 files changed, 1 insertion(+), 311 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9513a83b9537..1fd476d280f5 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -798,7 +798,6 @@ struct qlcnic_nic_intr_coalesce { #define QLCNIC_H2C_OPCODE_GET_NET_STATS 16 #define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V 17 #define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 18 -#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK 19 #define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE 20 #define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21 #define QLCNIC_C2C_OPCODE 22 @@ -1314,21 +1313,15 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring); -void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter); -int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); /* Functions from qlcnic_main.c */ -int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter); -void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter); int qlcnic_reset_context(struct qlcnic_adapter *); u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter, u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd); void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); int qlcnic_diag_alloc_res(struct net_device *netdev, int test); -int qlcnic_check_loopback_buff(unsigned char *data); netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); -void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); /* Management functions */ int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index c38929636488..2aa9d8b2bab3 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -101,8 +101,7 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = { static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_on_offline", "Link_Test_on_offline", - "Interrupt_Test_offline", - "Loopback_Test_offline" + "Interrupt_Test_offline" }; #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) @@ -643,104 +642,6 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset) } } -#define QLC_ILB_PKT_SIZE 64 -#define QLC_NUM_ILB_PKT 16 -#define QLC_ILB_MAX_RCV_LOOP 10 - -static void qlcnic_create_loopback_buff(unsigned char *data) -{ - unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00}; - memset(data, 0x4e, QLC_ILB_PKT_SIZE); - memset(data, 0xff, 12); - memcpy(data + 12, random_data, sizeof(random_data)); -} - -int qlcnic_check_loopback_buff(unsigned char *data) -{ - unsigned char buff[QLC_ILB_PKT_SIZE]; - qlcnic_create_loopback_buff(buff); - return memcmp(data, buff, QLC_ILB_PKT_SIZE); -} - -static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) -{ - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; - struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; - struct sk_buff *skb; - int i, loop, cnt = 0; - - for (i = 0; i < QLC_NUM_ILB_PKT; i++) { - skb = dev_alloc_skb(QLC_ILB_PKT_SIZE); - qlcnic_create_loopback_buff(skb->data); - skb_put(skb, QLC_ILB_PKT_SIZE); - - adapter->diag_cnt = 0; - qlcnic_xmit_frame(skb, adapter->netdev); - - loop = 0; - do { - msleep(1); - qlcnic_process_rcv_ring_diag(sds_ring); - } while (loop++ < QLC_ILB_MAX_RCV_LOOP && - !adapter->diag_cnt); - - dev_kfree_skb_any(skb); - - if (!adapter->diag_cnt) - dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" - " not recevied\n", i + 1); - else - cnt++; - } - if (cnt != i) { - dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); - return -1; - } - return 0; -} - -static int qlcnic_loopback_test(struct net_device *netdev) -{ - struct qlcnic_adapter *adapter = netdev_priv(netdev); - int max_sds_rings = adapter->max_sds_rings; - int ret; - - if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { - dev_warn(&adapter->pdev->dev, "Loopback test not supported" - "for non privilege function\n"); - return 0; - } - - if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) - return -EIO; - - if (qlcnic_request_quiscent_mode(adapter)) { - clear_bit(__QLCNIC_RESETTING, &adapter->state); - return -EIO; - } - - ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); - if (ret) - goto clear_it; - - ret = qlcnic_set_ilb_mode(adapter); - if (ret) - goto done; - - ret = qlcnic_do_ilb_test(adapter); - - qlcnic_clear_ilb_mode(adapter); - -done: - qlcnic_diag_free_res(netdev, max_sds_rings); - -clear_it: - qlcnic_clear_quiscent_mode(adapter); - adapter->max_sds_rings = max_sds_rings; - clear_bit(__QLCNIC_RESETTING, &adapter->state); - return ret; -} - static int qlcnic_irq_test(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); @@ -793,9 +694,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, if (data[2]) eth_test->flags |= ETH_TEST_FL_FAILED; - data[3] = qlcnic_loopback_test(dev); - if (data[3]) - eth_test->flags |= ETH_TEST_FL_FAILED; } } diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 7a47a2a7ee27..8630118dc4bb 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -1234,56 +1234,3 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) return rv; } - -static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag) -{ - struct qlcnic_nic_req req; - int rv; - u64 word; - - memset(&req, 0, sizeof(struct qlcnic_nic_req)); - req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); - - word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | - ((u64)adapter->portnum << 16); - req.req_hdr = cpu_to_le64(word); - req.words[0] = cpu_to_le64(flag); - - rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); - if (rv) - dev_err(&adapter->pdev->dev, - "%sting loopback mode failed.\n", - flag ? "Set" : "Reset"); - return rv; -} - -int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter) -{ - if (qlcnic_set_fw_loopback(adapter, 1)) - return -EIO; - - if (qlcnic_nic_set_promisc(adapter, - VPORT_MISS_MODE_ACCEPT_ALL)) { - qlcnic_set_fw_loopback(adapter, 0); - return -EIO; - } - - msleep(1000); - return 0; -} - -void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) -{ - int mode = VPORT_MISS_MODE_DROP; - struct net_device *netdev = adapter->netdev; - - qlcnic_set_fw_loopback(adapter, 0); - - if (netdev->flags & IFF_PROMISC) - mode = VPORT_MISS_MODE_ACCEPT_ALL; - else if (netdev->flags & IFF_ALLMULTI) - mode = VPORT_MISS_MODE_ACCEPT_MULTI; - - qlcnic_nic_set_promisc(adapter, mode); - msleep(1000); -} diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index c5ea2f4eb980..6d0ec6c7f225 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1690,99 +1690,6 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, spin_unlock(&rds_ring->lock); } -static void dump_skb(struct sk_buff *skb) -{ - int i; - unsigned char *data = skb->data; - - for (i = 0; i < skb->len; i++) { - printk("%02x ", data[i]); - if ((i & 0x0f) == 8) - printk("\n"); - } -} - -static struct qlcnic_rx_buffer * -qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, - struct qlcnic_host_sds_ring *sds_ring, - int ring, u64 sts_data0) -{ - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; - struct qlcnic_rx_buffer *buffer; - struct sk_buff *skb; - struct qlcnic_host_rds_ring *rds_ring; - int index, length, cksum, pkt_offset; - - if (unlikely(ring >= adapter->max_rds_rings)) - return NULL; - - rds_ring = &recv_ctx->rds_rings[ring]; - - index = qlcnic_get_sts_refhandle(sts_data0); - if (unlikely(index >= rds_ring->num_desc)) - return NULL; - - buffer = &rds_ring->rx_buf_arr[index]; - - length = qlcnic_get_sts_totallength(sts_data0); - cksum = qlcnic_get_sts_status(sts_data0); - pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0); - - skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum); - if (!skb) - return buffer; - - if (length > rds_ring->skb_size) - skb_put(skb, rds_ring->skb_size); - else - skb_put(skb, length); - - if (pkt_offset) - skb_pull(skb, pkt_offset); - - if (!qlcnic_check_loopback_buff(skb->data)) - adapter->diag_cnt++; - else - dump_skb(skb); - - dev_kfree_skb_any(skb); - adapter->stats.rx_pkts++; - adapter->stats.rxbytes += length; - - return buffer; -} - -void -qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) -{ - struct qlcnic_adapter *adapter = sds_ring->adapter; - struct status_desc *desc; - struct qlcnic_rx_buffer *rxbuf; - u64 sts_data0; - - int opcode, ring, desc_cnt; - u32 consumer = sds_ring->consumer; - - desc = &sds_ring->desc_head[consumer]; - sts_data0 = le64_to_cpu(desc->status_desc_data[0]); - - if (!(sts_data0 & STATUS_OWNER_HOST)) - return; - - desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0); - opcode = qlcnic_get_sts_opcode(sts_data0); - - ring = qlcnic_get_sts_type(sts_data0); - rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring, - ring, sts_data0); - - desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM); - consumer = get_next_index(consumer, sds_ring->num_desc); - - sds_ring->consumer = consumer; - writel(consumer, sds_ring->crb_sts_consumer); -} - void qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, u8 alt_mac, u8 *mac) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 899df5a81fda..08d4b37f246c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2859,61 +2859,6 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) qlcnic_api_unlock(adapter); } -/* Caller should held RESETTING bit. - * This should be call in sync with qlcnic_request_quiscent_mode. - */ -void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter) -{ - qlcnic_clr_drv_state(adapter); - qlcnic_api_lock(adapter); - QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); - qlcnic_api_unlock(adapter); -} - -/* Caller should held RESETTING bit. - */ -int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter) -{ - u8 timeo = adapter->dev_init_timeo / 2; - u32 state; - - if (qlcnic_api_lock(adapter)) - return -EIO; - - state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (state != QLCNIC_DEV_READY) - return -EIO; - - QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT); - qlcnic_api_unlock(adapter); - QLCDB(adapter, DRV, "NEED QUISCENT state set\n"); - qlcnic_idc_debug_info(adapter, 0); - - qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT); - - do { - msleep(2000); - state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (state == QLCNIC_DEV_QUISCENT) - return 0; - if (!qlcnic_check_drv_state(adapter)) { - if (qlcnic_api_lock(adapter)) - return -EIO; - QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, - QLCNIC_DEV_QUISCENT); - qlcnic_api_unlock(adapter); - QLCDB(adapter, DRV, "QUISCENT mode set\n"); - return 0; - } - } while (--timeo); - - dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x" - " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE), - QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE)); - qlcnic_clear_quiscent_mode(adapter); - return -EIO; -} - /*Transit to RESET state from READY state only */ static void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) -- cgit v1.2.3-59-g8ed1b From 091056b2ad04df09a3cb78a4c4ea098709b98eb3 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 2 Dec 2010 20:41:43 +0000 Subject: qlcnic: validate eswitch config values for PF Currently driver set default eswitch configuration values for PF function, instead of validating values sent by application. Signed-off-by: Amit Kumar Salecha Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 08d4b37f246c..4e8466b326af 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -3537,9 +3537,12 @@ validate_esw_config(struct qlcnic_adapter *adapter, case QLCNIC_PORT_DEFAULTS: if (QLC_DEV_GET_DRV(op_mode, pci_func) != QLCNIC_NON_PRIV_FUNC) { - esw_cfg[i].mac_anti_spoof = 0; - esw_cfg[i].mac_override = 1; - esw_cfg[i].promisc_mode = 1; + if (esw_cfg[i].mac_anti_spoof != 0) + return QL_STATUS_INVALID_PARAM; + if (esw_cfg[i].mac_override != 1) + return QL_STATUS_INVALID_PARAM; + if (esw_cfg[i].promisc_mode != 1) + return QL_STATUS_INVALID_PARAM; } break; case QLCNIC_ADD_VLAN: -- cgit v1.2.3-59-g8ed1b From 40839129f77903cbbb7f232e2e2ab08dfe4a4f8d Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 2 Dec 2010 20:41:56 +0000 Subject: qlcnic: LICENSE file for qlcnic Signed-off-by: Sritej Velaga Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- Documentation/networking/LICENSE.qlcnic | 327 ++++++++++++++++++++++++++++++++ drivers/net/qlcnic/qlcnic.h | 23 +-- drivers/net/qlcnic/qlcnic_ctx.c | 23 +-- drivers/net/qlcnic/qlcnic_ethtool.c | 23 +-- drivers/net/qlcnic/qlcnic_hdr.h | 23 +-- drivers/net/qlcnic/qlcnic_hw.c | 23 +-- drivers/net/qlcnic/qlcnic_init.c | 23 +-- drivers/net/qlcnic/qlcnic_main.c | 23 +-- 8 files changed, 348 insertions(+), 140 deletions(-) create mode 100644 Documentation/networking/LICENSE.qlcnic diff --git a/Documentation/networking/LICENSE.qlcnic b/Documentation/networking/LICENSE.qlcnic new file mode 100644 index 000000000000..29ad4b106420 --- /dev/null +++ b/Documentation/networking/LICENSE.qlcnic @@ -0,0 +1,327 @@ +Copyright (c) 2009-2010 QLogic Corporation +QLogic Linux qlcnic NIC Driver + +This program includes a device driver for Linux 2.6 that may be +distributed with QLogic hardware specific firmware binary file. +You may modify and redistribute the device driver code under the +GNU General Public License (a copy of which is attached hereto as +Exhibit A) published by the Free Software Foundation (version 2). + +You may redistribute the hardware specific firmware binary file +under the following terms: + + 1. Redistribution of source code (only if applicable), + must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistribution in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + + 3. The name of QLogic Corporation may not be used to + endorse or promote products derived from this software + without specific prior written permission + +REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE, +THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT +CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR +OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT, +TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN +ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN +COMBINATION WITH THIS PROGRAM. + + +EXHIBIT A + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 1fd476d280f5..952d40990669 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #ifndef _QLCNIC_H_ diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 29cbc2a6e79f..27631f23b3fd 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #include "qlcnic.h" diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 2aa9d8b2bab3..0eaf31bf8a0d 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #include diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 566e0e8437e4..19328e05b75d 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #ifndef __QLCNIC_HDR_H_ diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 8630118dc4bb..c9c4bf1458a8 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #include "qlcnic.h" diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 6d0ec6c7f225..9b9c7c39d3ee 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #include diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4e8466b326af..788850e2ba4e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1,25 +1,8 @@ /* - * Copyright (C) 2009 - QLogic 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". + * QLogic qlcnic NIC Driver + * Copyright (c) 2009-2010 QLogic Corporation * + * See LICENSE.qlcnic for copyright and licensing details. */ #include -- cgit v1.2.3-59-g8ed1b From e4d849b8113b0cf7b6ebfa9ee4c47bd514ea49d3 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Thu, 2 Dec 2010 20:42:08 +0000 Subject: qlcnic: Updated driver version to 5.0.13 Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 952d40990669..f267da42f243 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -34,8 +34,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 12 -#define QLCNIC_LINUX_VERSIONID "5.0.12" +#define _QLCNIC_LINUX_SUBVERSION 13 +#define QLCNIC_LINUX_VERSIONID "5.0.13" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3-59-g8ed1b From c6ecf39a10ceec3e97096e2a8d3eadcecd593422 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 03:31:51 +0000 Subject: ixgbe: fix link behavior for SFP+ when driver is brought down We have had several requests to have ifconfig down command disable the SFP+ laser and thus make link go down. Likewise on ifconfig up the laser would be enabled and link would come up. This patch enables that behavior. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 12 +++++++++--- drivers/net/ixgbe/ixgbe_main.c | 26 ++++++++++++++++++-------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index e34643eef162..8fa76785b45c 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -65,9 +65,9 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; - if (hw->phy.multispeed_fiber) { - /* Set up dual speed SFP+ support */ - mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; + + /* enable the laser control functions for SFP+ fiber */ + if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) { mac->ops.disable_tx_laser = &ixgbe_disable_tx_laser_multispeed_fiber; mac->ops.enable_tx_laser = @@ -77,6 +77,12 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) mac->ops.disable_tx_laser = NULL; mac->ops.enable_tx_laser = NULL; mac->ops.flap_tx_laser = NULL; + } + + if (hw->phy.multispeed_fiber) { + /* Set up dual speed SFP+ support */ + mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; + } else { if ((mac->ops.get_media_type(hw) == ixgbe_media_type_backplane) && (hw->phy.smart_speed == ixgbe_smart_speed_auto || diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 494cb57b700d..5861ece70207 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3793,8 +3793,11 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) else ixgbe_configure_msi_and_legacy(adapter); - /* enable the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.enable_tx_laser) + /* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */ + if (hw->mac.ops.enable_tx_laser && + ((hw->phy.multispeed_fiber) || + ((hw->phy.type == ixgbe_media_type_fiber) && + (hw->mac.type == ixgbe_mac_82599EB)))) hw->mac.ops.enable_tx_laser(hw); clear_bit(__IXGBE_DOWN, &adapter->state); @@ -4106,15 +4109,19 @@ void ixgbe_down(struct ixgbe_adapter *adapter) break; } - /* power down the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) - hw->mac.ops.disable_tx_laser(hw); - /* clear n-tuple filters that are cached */ ethtool_ntuple_flush(netdev); if (!pci_channel_offline(adapter->pdev)) ixgbe_reset(adapter); + + /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ + if (hw->mac.ops.disable_tx_laser && + ((hw->phy.multispeed_fiber) || + ((hw->phy.type == ixgbe_media_type_fiber) && + (hw->mac.type == ixgbe_mac_82599EB)))) + hw->mac.ops.disable_tx_laser(hw); + ixgbe_clean_all_tx_rings(adapter); ixgbe_clean_all_rx_rings(adapter); @@ -7197,8 +7204,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_eeprom; } - /* power down the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) + /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ + if (hw->mac.ops.disable_tx_laser && + ((hw->phy.multispeed_fiber) || + ((hw->phy.type == ixgbe_media_type_fiber) && + (hw->mac.type == ixgbe_mac_82599EB)))) hw->mac.ops.disable_tx_laser(hw); init_timer(&adapter->watchdog_timer); -- cgit v1.2.3-59-g8ed1b From 0b077feac00a8b7b0afbab3274b2e74b749bc917 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 03:32:13 +0000 Subject: ixgbe: add WOL support for SFP+ subdevice This patch will add wake on LAN support to the dev/sub_dev 10FB 11A9. This will also include ixgbe ethtool support for this device. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 11 +++++++++++ drivers/net/ixgbe/ixgbe_main.c | 15 ++++++++++----- drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f9b58394fbb6..ef3f9105a05d 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1879,7 +1879,16 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; int retval = 1; + /* WOL not supported except for the following */ switch(hw->device_id) { + case IXGBE_DEV_ID_82599_SFP: + /* Only this subdevice supports WOL */ + if (hw->subsystem_device_id != IXGBE_SUBDEV_ID_82599_SFP) { + wol->supported = 0; + break; + } + retval = 0; + break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ if (hw->subsystem_device_id == @@ -1887,6 +1896,8 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, wol->supported = 0; break; } + retval = 0; + break; case IXGBE_DEV_ID_82599_KX4: retval = 0; break; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5861ece70207..5f4c93d40a45 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7223,13 +7223,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_sw_init; switch (pdev->device) { + case IXGBE_DEV_ID_82599_SFP: + /* Only this subdevice supports WOL */ + if (pdev->subsystem_device == IXGBE_SUBDEV_ID_82599_SFP) + adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | + IXGBE_WUFC_MC | IXGBE_WUFC_BC); + break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ - if (pdev->subsystem_device == - IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) { - adapter->wol = 0; - break; - } + if (pdev->subsystem_device != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) + adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | + IXGBE_WUFC_MC | IXGBE_WUFC_BC); + break; case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | IXGBE_WUFC_MC | IXGBE_WUFC_BC); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 42c607339a62..9557ae64f951 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -54,6 +54,7 @@ #define IXGBE_DEV_ID_82599_T3_LOM 0x151C #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB +#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 -- cgit v1.2.3-59-g8ed1b From dbffcb210f45239ea530e0a71470e48abefe4210 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 03:32:34 +0000 Subject: ixgbe: add support for 82599 FCoE SKU Add both NIC and backplane support for FCoE enabled devices IDs. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 2 ++ drivers/net/ixgbe/ixgbe_main.c | 4 ++++ drivers/net/ixgbe/ixgbe_type.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 8fa76785b45c..385ccebb826c 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -319,11 +319,13 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: case IXGBE_DEV_ID_82599_XAUI_LOM: /* Default device ID is mezzanine card KX/KX4 */ media_type = ixgbe_media_type_backplane; break; case IXGBE_DEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: media_type = ixgbe_media_type_fiber; break; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5f4c93d40a45..c5c93408212d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -109,6 +109,10 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE), + board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE), + board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 9557ae64f951..35b60db5e776 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -54,6 +54,8 @@ #define IXGBE_DEV_ID_82599_T3_LOM 0x151C #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB +#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152a +#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529 #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC -- cgit v1.2.3-59-g8ed1b From 289700dbc40c78741f17e2304ed4ac0db3c3afd3 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 03:32:58 +0000 Subject: ixgbe: add support for new format of PBA numbers The new PBA format is stored as a string. This patch allows the driver to support both the old and new format. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_common.c | 94 +++++++++++++++++++++++++++++++++++++--- drivers/net/ixgbe/ixgbe_common.h | 3 +- drivers/net/ixgbe/ixgbe_main.c | 18 ++++---- drivers/net/ixgbe/ixgbe_type.h | 6 +++ 4 files changed, 105 insertions(+), 16 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 56052570cac5..cc11e422ce9b 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -196,30 +196,110 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) } /** - * ixgbe_read_pba_num_generic - Reads part number from EEPROM + * ixgbe_read_pba_string_generic - Reads part number string from EEPROM * @hw: pointer to hardware structure - * @pba_num: stores the part number from the EEPROM + * @pba_num: stores the part number string from the EEPROM + * @pba_num_size: part number string buffer length * - * Reads the part number from the EEPROM. + * Reads the part number string from the EEPROM. **/ -s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) +s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + u32 pba_num_size) { s32 ret_val; u16 data; + u16 pba_ptr; + u16 offset; + u16 length; + + if (pba_num == NULL) { + hw_dbg(hw, "PBA string buffer was null\n"); + return IXGBE_ERR_INVALID_ARGUMENT; + } ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); if (ret_val) { hw_dbg(hw, "NVM Read Error\n"); return ret_val; } - *pba_num = (u32)(data << 16); - ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); if (ret_val) { hw_dbg(hw, "NVM Read Error\n"); return ret_val; } - *pba_num |= data; + + /* + * if data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (data != IXGBE_PBANUM_PTR_GUARD) { + hw_dbg(hw, "NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + hw_dbg(hw, "PBA string buffer too small\n"); + return IXGBE_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (data >> 12) & 0xF; + pba_num[1] = (data >> 8) & 0xF; + pba_num[2] = (data >> 4) & 0xF; + pba_num[3] = data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + return 0; + } + + ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + + if (length == 0xFFFF || length == 0) { + hw_dbg(hw, "NVM PBA number section invalid length\n"); + return IXGBE_ERR_PBA_SECTION; + } + + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + hw_dbg(hw, "PBA string buffer too small\n"); + return IXGBE_ERR_NO_SPACE; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + pba_num[offset * 2] = (u8)(data >> 8); + pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); + } + pba_num[offset * 2] = '\0'; return 0; } diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 341ca514a281..e1f980a8a09d 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -35,7 +35,8 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw); s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw); -s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num); +s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + u32 pba_num_size); s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr); s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw); void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c5c93408212d..f97353cdb607 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6952,11 +6952,12 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; static int cards_found; int i, err, pci_using_dac; + u8 part_str[IXGBE_PBANUM_LENGTH]; unsigned int indices = num_possible_cpus(); #ifdef IXGBE_FCOE u16 device_caps; #endif - u32 part_num, eec; + u32 eec; /* Catch broken hardware that put the wrong VF device ID in * the PCIe SR-IOV capability. @@ -7262,16 +7263,17 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" : "Unknown"), netdev->dev_addr); - ixgbe_read_pba_num_generic(hw, &part_num); + + err = ixgbe_read_pba_string_generic(hw, part_str, IXGBE_PBANUM_LENGTH); + if (err) + strcpy(part_str, "Unknown"); if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) - e_dev_info("MAC: %d, PHY: %d, SFP+: %d, " - "PBA No: %06x-%03x\n", + e_dev_info("MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n", hw->mac.type, hw->phy.type, hw->phy.sfp_type, - (part_num >> 8), (part_num & 0xff)); + part_str); else - e_dev_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n", - hw->mac.type, hw->phy.type, - (part_num >> 8), (part_num & 0xff)); + e_dev_info("MAC: %d, PHY: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, part_str); if (hw->bus.width <= ixgbe_bus_width_pcie_x4) { e_dev_warn("PCI-Express bandwidth available for this card is " diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 35b60db5e776..ef816dd5a8f0 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1508,7 +1508,11 @@ #define IXGBE_EEPROM_WORD_SIZE_SHIFT 6 #define IXGBE_EEPROM_OPCODE_BITS 8 +/* Part Number String Length */ +#define IXGBE_PBANUM_LENGTH 11 + /* Checksum and EEPROM pointers */ +#define IXGBE_PBANUM_PTR_GUARD 0xFAFA #define IXGBE_EEPROM_CHECKSUM 0x3F #define IXGBE_EEPROM_SUM 0xBABA #define IXGBE_PCIE_ANALOG_PTR 0x03 @@ -2637,6 +2641,8 @@ struct ixgbe_info { #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 #define IXGBE_ERR_RAR_INDEX -27 +#define IXGBE_ERR_PBA_SECTION -31 +#define IXGBE_ERR_INVALID_ARGUMENT -32 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ -- cgit v1.2.3-59-g8ed1b From ca44ac386181ba710a9ab6db900d6c1e5451b366 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Mon, 29 Nov 2010 22:48:46 +0000 Subject: net: don't reallocate skb->head unless the current one hasn't the needed extra size or is shared skb head being allocated by kmalloc(), it might be larger than what actually requested because of discrete kmem caches sizes. Before reallocating a new skb head, check if the current one has the needed extra size. Do this check only if skb head is not shared. Signed-off-by: Changli Gao Cc: Eric Dumazet Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/skbuff.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 104f8444754a..8814a9a52f47 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -778,6 +778,28 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, size = SKB_DATA_ALIGN(size); + /* Check if we can avoid taking references on fragments if we own + * the last reference on skb->head. (see skb_release_data()) + */ + if (!skb->cloned) + fastpath = true; + else { + int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; + + fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; + } + + if (fastpath && + size + sizeof(struct skb_shared_info) <= ksize(skb->head)) { + memmove(skb->head + size, skb_shinfo(skb), + offsetof(struct skb_shared_info, + frags[skb_shinfo(skb)->nr_frags])); + memmove(skb->head + nhead, skb->head, + skb_tail_pointer(skb) - skb->head); + off = nhead; + goto adjust_others; + } + data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); if (!data) goto nodata; @@ -791,17 +813,6 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, skb_shinfo(skb), offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); - /* Check if we can avoid taking references on fragments if we own - * the last reference on skb->head. (see skb_release_data()) - */ - if (!skb->cloned) - fastpath = true; - else { - int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; - - fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; - } - if (fastpath) { kfree(skb->head); } else { @@ -816,6 +827,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, off = (data + nhead) - skb->head; skb->head = data; +adjust_others: skb->data += off; #ifdef NET_SKBUFF_DATA_USES_OFFSET skb->end = size; -- cgit v1.2.3-59-g8ed1b From df6bd743b6f06b066c1c3ba7f2853a6e8d61468c Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 14 Jun 2010 02:26:15 -0300 Subject: Bluetooth: Don't accept ConfigReq if we aren't in the BT_CONFIG state If such event happens we shall reply with a Command Reject, because we are not expecting any configure request. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c12eccfdfe01..c791fcda7b2d 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3124,8 +3124,14 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; - if (sk->sk_state == BT_DISCONN) + if (sk->sk_state != BT_CONFIG) { + struct l2cap_cmd_rej rej; + + rej.reason = cpu_to_le16(0x0002); + l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, + sizeof(rej), &rej); goto unlock; + } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); -- cgit v1.2.3-59-g8ed1b From 8fc2f9956127d2b85280c07e69aeb08b9bd85150 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:49 +0000 Subject: tg3: Raise the jumbo frame BD flag threshold The current transmit routines set the jumbo frame BD flag too aggressively. This can reduce performance for common cases. This patch raises the jumbo flag threshold to 1518, up from 1500. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index afb79db5327e..b8ae5e19ced5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5761,7 +5761,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping); if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) && - !mss && skb->len > ETH_DATA_LEN) + !mss && skb->len > VLAN_ETH_FRAME_LEN) base_flags |= TXD_FLAG_JMB_PKT; tg3_set_txd(tnapi, entry, mapping, len, base_flags, @@ -5995,7 +5995,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, #endif if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) && - !mss && skb->len > ETH_DATA_LEN) + !mss && skb->len > VLAN_ETH_FRAME_LEN) base_flags |= TXD_FLAG_JMB_PKT; len = skb_headlen(skb); -- cgit v1.2.3-59-g8ed1b From 3110f5f5545a645c50ef66b1f705d08dfd1df404 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:50 +0000 Subject: tg3: Move EEE definitions into mdio.h In commit 52b02d04c801fff51ca49ad033210846d1713253 entitled "tg3: Add EEE support", Ben Hutchings had commented that the EEE advertisement register will be in a standard location. This patch moves that definition into mdio.h and changes the code to use it. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 16 ++++++++-------- drivers/net/tg3.h | 3 --- include/linux/mdio.h | 5 +++++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b8ae5e19ced5..1e7a135de7b3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1781,7 +1782,8 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) tw32(TG3_CPMU_EEE_CTRL, eeectl); - tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val); + tg3_phy_cl45_read(tp, MDIO_MMD_AN, + TG3_CL45_D7_EEERES_STAT, &val); if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T || val == TG3_CL45_D7_EEERES_STAT_LP_100TX) @@ -2987,16 +2989,14 @@ static void tg3_phy_copper_begin(struct tg3 *tp) if (tp->link_config.autoneg == AUTONEG_ENABLE) { /* Advertise 100-BaseTX EEE ability */ if (tp->link_config.advertising & - (ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full)) - val |= TG3_CL45_D7_EEEADV_CAP_100TX; + ADVERTISED_100baseT_Full) + val |= MDIO_AN_EEE_ADV_100TX; /* Advertise 1000-BaseT EEE ability */ if (tp->link_config.advertising & - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full)) - val |= TG3_CL45_D7_EEEADV_CAP_1000T; + ADVERTISED_1000baseT_Full) + val |= MDIO_AN_EEE_ADV_1000T; } - tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, val); + tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); /* Turn off SM_DSP clock. */ val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 59b0e096149e..6e72c6bd2675 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2172,9 +2172,6 @@ #define MII_TG3_TEST1_CRC_EN 0x8000 /* Clause 45 expansion registers */ -#define TG3_CL45_D7_EEEADV_CAP 0x003c -#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002 -#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004 #define TG3_CL45_D7_EEERES_STAT 0x803e #define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002 #define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004 diff --git a/include/linux/mdio.h b/include/linux/mdio.h index c779b49a1fda..b1494aced217 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -55,6 +55,7 @@ #define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */ #define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */ #define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */ +#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */ /* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */ #define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */ @@ -235,6 +236,10 @@ #define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */ #define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */ +/* AN EEE Advertisement register. */ +#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */ +#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */ + /* LASI RX_ALARM control/status registers. */ #define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */ #define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */ -- cgit v1.2.3-59-g8ed1b From 699c019385fcb13498a5a3a8bd368f04f1d4a223 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:51 +0000 Subject: tg3: Fix 57765 EEE support EEE support in the 57765 internal phy will not enable after a phy reset unless it sees that EEE is supported in the MAC. This patch moves the code that programs the CPMU EEE registers to a place before the phy reset. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1e7a135de7b3..e4efb5203e22 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7809,6 +7809,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) tg3_abort_hw(tp, 1); + /* Enable MAC control of LPI */ + if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { + tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, + TG3_CPMU_EEE_LNKIDL_PCIE_NL0 | + TG3_CPMU_EEE_LNKIDL_UART_IDL); + + tw32_f(TG3_CPMU_EEE_CTRL, + TG3_CPMU_EEE_CTRL_EXIT_20_1_US); + + tw32_f(TG3_CPMU_EEE_MODE, + TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | + TG3_CPMU_EEEMD_LPI_IN_TX | + TG3_CPMU_EEEMD_LPI_IN_RX | + TG3_CPMU_EEEMD_EEE_ENABLE); + } + if (reset_phy) tg3_phy_reset(tp); @@ -7890,22 +7906,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(TG3_CPMU_LSPD_10MB_CLK, val); } - /* Enable MAC control of LPI */ - if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { - tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, - TG3_CPMU_EEE_LNKIDL_PCIE_NL0 | - TG3_CPMU_EEE_LNKIDL_UART_IDL); - - tw32_f(TG3_CPMU_EEE_CTRL, - TG3_CPMU_EEE_CTRL_EXIT_20_1_US); - - tw32_f(TG3_CPMU_EEE_MODE, - TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | - TG3_CPMU_EEEMD_LPI_IN_TX | - TG3_CPMU_EEEMD_LPI_IN_RX | - TG3_CPMU_EEEMD_EEE_ENABLE); - } - /* This works around an issue with Athlon chipsets on * B3 tigon3 silicon. This bit has no effect on any * other revision. But do not set this on PCI Express -- cgit v1.2.3-59-g8ed1b From a6b68dab169e2a51e59f43504f1279cbc2afcde8 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:52 +0000 Subject: tg3: Minor EEE code tweaks The first hunk of this patch makes sure that the driver checks for the appropriate preconditions before checking if EEE negotiation succeeded. More specifically the link needs to be full duplex for EEE to be enabled. The second and third hunks of this patch fix a bug where the eee advertisement register would be programmed with extra bits set. The fourth hunk of this patch makes sure the EEE capability flag is not set for 5718 A0 devices and that the device is not a serdes device. None of these modifications are strictly necessary. The driver / hardware still does the right thing. They are submitted primarily for correctness. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e4efb5203e22..81dafc26cdff 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1770,9 +1770,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) if (tp->link_config.autoneg == AUTONEG_ENABLE && current_link_up == 1 && - (tp->link_config.active_speed == SPEED_1000 || - (tp->link_config.active_speed == SPEED_100 && - tp->link_config.active_duplex == DUPLEX_FULL))) { + tp->link_config.active_duplex == DUPLEX_FULL && + (tp->link_config.active_speed == SPEED_100 || + tp->link_config.active_speed == SPEED_1000)) { u32 eeectl; if (tp->link_config.active_speed == SPEED_1000) @@ -2969,7 +2969,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) } if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { - u32 val = 0; + u32 val; tw32(TG3_CPMU_EEE_MODE, tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); @@ -2986,6 +2986,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | MII_TG3_DSP_CH34TP2_HIBW01); + val = 0; if (tp->link_config.autoneg == AUTONEG_ENABLE) { /* Advertise 100-BaseTX EEE ability */ if (tp->link_config.advertising & @@ -12569,9 +12570,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } } - if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)) + if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && + ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && + tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && + tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))) tp->phy_flags |= TG3_PHYFLG_EEE_CAP; if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && -- cgit v1.2.3-59-g8ed1b From a386b9011a4687470e6168e2f2a08c468f25f72f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:53 +0000 Subject: tg3: Relax EEE thresholds The hardware defaults to fairly aggressive EEE thresholds. While there appear to be no ill effects, this patch relaxes them, just as a precaution. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 25 ++++++++++++++++++++----- drivers/net/tg3.h | 20 +++++++++++++------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 81dafc26cdff..bb95c6ecda49 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7819,11 +7819,26 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32_f(TG3_CPMU_EEE_CTRL, TG3_CPMU_EEE_CTRL_EXIT_20_1_US); - tw32_f(TG3_CPMU_EEE_MODE, - TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | - TG3_CPMU_EEEMD_LPI_IN_TX | - TG3_CPMU_EEEMD_LPI_IN_RX | - TG3_CPMU_EEEMD_EEE_ENABLE); + val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | + TG3_CPMU_EEEMD_LPI_IN_TX | + TG3_CPMU_EEEMD_LPI_IN_RX | + TG3_CPMU_EEEMD_EEE_ENABLE; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) + val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN; + + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) + val |= TG3_CPMU_EEEMD_APE_TX_DET_EN; + + tw32_f(TG3_CPMU_EEE_MODE, val); + + tw32_f(TG3_CPMU_EEE_DBTMR1, + TG3_CPMU_DBTMR1_PCIEXIT_2047US | + TG3_CPMU_DBTMR1_LNKIDLE_2047US); + + tw32_f(TG3_CPMU_EEE_DBTMR2, + TG3_CPMU_DBTMR1_APE_TX_2047US | + TG3_CPMU_DBTMR2_TXIDXEQ_2047US); } if (reset_phy) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 6e72c6bd2675..d62c8d937c82 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1094,13 +1094,19 @@ /* 0x3664 --> 0x36b0 unused */ #define TG3_CPMU_EEE_MODE 0x000036b0 -#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008 -#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080 -#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100 -#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200 -#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 -/* 0x36b4 --> 0x36b8 unused */ - +#define TG3_CPMU_EEEMD_APE_TX_DET_EN 0x00000004 +#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008 +#define TG3_CPMU_EEEMD_SND_IDX_DET_EN 0x00000040 +#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080 +#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100 +#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200 +#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 +#define TG3_CPMU_EEE_DBTMR1 0x000036b4 +#define TG3_CPMU_DBTMR1_PCIEXIT_2047US 0x07ff0000 +#define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000070ff +#define TG3_CPMU_EEE_DBTMR2 0x000036b8 +#define TG3_CPMU_DBTMR1_APE_TX_2047US 0x07ff0000 +#define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000070ff #define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc #define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 #define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004 -- cgit v1.2.3-59-g8ed1b From 5ee493767352314893520ac40aec5bb07d0147e0 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 6 Dec 2010 08:28:54 +0000 Subject: tg3: Update version to 3.116 This patch updates the tg3 version to 3.116. Signed-off-by: Matt Carlson Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bb95c6ecda49..5faa87d86c66 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -70,10 +70,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 115 +#define TG3_MIN_NUM 116 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "October 14, 2010" +#define DRV_MODULE_RELDATE "December 3, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3-59-g8ed1b From c1ce5a74d113f221d40625bd3ad83df2db2695b7 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 1 Dec 2010 16:34:45 +0100 Subject: mac80211: Update last_tx_rate only for data frames The last_tx_rate field was also updated for non-data frames that are often sent with a lower rate (for example management frames at 1 Mbps). This is confusing when the data rate is actually much higher. Hence, only update the last_tx_rate field with tx rate information gathered from last data frames. If the rate control algorithm filled in txrc.reported_rate we don't need to verify this information. Cc: Johannes Berg Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/tx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2ba742656825..5d6b0759d18c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -666,10 +666,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) if (unlikely(info->control.rates[0].idx < 0)) return TX_DROP; - if (txrc.reported_rate.idx < 0) + if (txrc.reported_rate.idx < 0) { txrc.reported_rate = info->control.rates[0]; - - if (tx->sta) + if (tx->sta && ieee80211_is_data(hdr->frame_control)) + tx->sta->last_tx_rate = txrc.reported_rate; + } else if (tx->sta) tx->sta->last_tx_rate = txrc.reported_rate; if (unlikely(!info->control.rates[0].count)) -- cgit v1.2.3-59-g8ed1b From 9a10a870e09f1fd50fd024d55232b4b72cf4e387 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 1 Dec 2010 09:37:55 -0800 Subject: MAINTAINERS: Add ATH GENERIC UTILITIES This file pattern is not currently shown as maintained by atheros. Perhaps it should be? Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0094224ca79b..4d8bde32a26b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1080,6 +1080,12 @@ S: Supported F: Documentation/aoe/ F: drivers/block/aoe/ +ATHEROS ATH GENERIC UTILITIES +M: "Luis R. Rodriguez" +L: linux-wireless@vger.kernel.org +S: Supported +F: drivers/net/wireless/ath/* + ATHEROS ATH5K WIRELESS DRIVER M: Jiri Slaby M: Nick Kossifidis -- cgit v1.2.3-59-g8ed1b From 5dcc03fe29537edd7819f5b121bf3d779693f37b Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 2 Dec 2010 19:12:31 +0900 Subject: ath5k: Use EWMA factor of 1024 instead of 1000 This prepares the only place which uses the EWMA library so far for the performance improved implementation coming up, which requires factor and weight to be a power of two. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0a7071a6dd7a..5ece94708371 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2685,7 +2685,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ah->ah_cal_next_full = jiffies; ah->ah_cal_next_ani = jiffies; ah->ah_cal_next_nf = jiffies; - ewma_init(&ah->ah_beacon_rssi_avg, 1000, 8); + ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); /* * Change channels and update the h/w rate map if we're switching; -- cgit v1.2.3-59-g8ed1b From af5568843594fb71055debe36e521fa8072fcecc Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 2 Dec 2010 19:50:37 +0900 Subject: lib: Improve EWMA efficiency by using bitshifts Using bitshifts instead of division and multiplication should improve performance. That requires weight and factor to be powers of two, but i think this is something we can live with. Thanks to Peter Zijlstra for the improved formula! Signed-off-by: Bruno Randolf -- v2: use log2.h functions Signed-off-by: John W. Linville --- include/linux/average.h | 4 +--- lib/average.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/linux/average.h b/include/linux/average.h index 7706e40f95fa..c6028fd742c1 100644 --- a/include/linux/average.h +++ b/include/linux/average.h @@ -1,8 +1,6 @@ #ifndef _LINUX_AVERAGE_H #define _LINUX_AVERAGE_H -#include - /* Exponentially weighted moving average (EWMA) */ /* For more documentation see lib/average.c */ @@ -26,7 +24,7 @@ extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); */ static inline unsigned long ewma_read(const struct ewma *avg) { - return DIV_ROUND_CLOSEST(avg->internal, avg->factor); + return avg->internal >> avg->factor; } #endif /* _LINUX_AVERAGE_H */ diff --git a/lib/average.c b/lib/average.c index f1d1b4660c42..5576c2841496 100644 --- a/lib/average.c +++ b/lib/average.c @@ -8,6 +8,7 @@ #include #include #include +#include /** * DOC: Exponentially Weighted Moving Average (EWMA) @@ -24,18 +25,21 @@ * ewma_init() - Initialize EWMA parameters * @avg: Average structure * @factor: Factor to use for the scaled up internal value. The maximum value - * of averages can be ULONG_MAX/(factor*weight). + * of averages can be ULONG_MAX/(factor*weight). For performance reasons + * factor has to be a power of 2. * @weight: Exponential weight, or decay rate. This defines how fast the - * influence of older values decreases. Has to be bigger than 1. + * influence of older values decreases. For performance reasons weight has + * to be a power of 2. * * Initialize the EWMA parameters for a given struct ewma @avg. */ void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight) { - WARN_ON(weight <= 1 || factor == 0); + WARN_ON(!is_power_of_2(weight) || !is_power_of_2(factor)); + + avg->weight = ilog2(weight); + avg->factor = ilog2(factor); avg->internal = 0; - avg->weight = weight; - avg->factor = factor; } EXPORT_SYMBOL(ewma_init); @@ -49,9 +53,9 @@ EXPORT_SYMBOL(ewma_init); struct ewma *ewma_add(struct ewma *avg, unsigned long val) { avg->internal = avg->internal ? - (((avg->internal * (avg->weight - 1)) + - (val * avg->factor)) / avg->weight) : - (val * avg->factor); + (((avg->internal << avg->weight) - avg->internal) + + (val << avg->factor)) >> avg->weight : + (val << avg->factor); return avg; } EXPORT_SYMBOL(ewma_add); -- cgit v1.2.3-59-g8ed1b From 75706d0e9d19601534446982b70102bb9327169b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 21:01:07 +0100 Subject: mac80211: remove a redundant check ieee80211_is_nullfunc() implies ieee80211_is_data() Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 794807914940..f570801514f1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1067,8 +1067,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr) { - if (!ieee80211_is_data(hdr->frame_control) && - !ieee80211_is_nullfunc(hdr->frame_control)) + if (!ieee80211_is_data(hdr->frame_control)) return; ieee80211_sta_reset_conn_monitor(sdata); -- cgit v1.2.3-59-g8ed1b From 04ac3c0ee2c773c321ec472d892635a20556f34d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Dec 2010 21:01:08 +0100 Subject: mac80211: speed up AP probing using nullfunc frames If the nullfunc frame used to probe the AP was not acked, there is no point in waiting for the probe timeout, so advance to the next try (or disconnect) immediately. If we do reach the probe timeout without having received a tx status, the connection is probably really bad and worth disconnecting. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 +- net/mac80211/mlme.c | 93 +++++++++++++++++++++++++++++++++------------- net/mac80211/status.c | 18 ++++----- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 66b0b52b828d..e7c880725639 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -357,6 +357,7 @@ struct ieee80211_if_managed { unsigned long beacon_timeout; unsigned long probe_timeout; int probe_send_count; + bool nullfunc_failed; struct mutex mtx; struct cfg80211_bss *associated; @@ -1271,7 +1272,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr); void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr); + struct ieee80211_hdr *hdr, bool ack); void ieee80211_beacon_connection_loss_work(struct work_struct *work); void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f570801514f1..3a1dde3c7956 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1065,16 +1065,20 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) } void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr) + struct ieee80211_hdr *hdr, bool ack) { if (!ieee80211_is_data(hdr->frame_control)) return; - ieee80211_sta_reset_conn_monitor(sdata); + if (ack) + ieee80211_sta_reset_conn_monitor(sdata); if (ieee80211_is_nullfunc(hdr->frame_control) && sdata->u.mgd.probe_send_count > 0) { - sdata->u.mgd.probe_send_count = 0; + if (ack) + sdata->u.mgd.probe_send_count = 0; + else + sdata->u.mgd.nullfunc_failed = true; ieee80211_queue_work(&sdata->local->hw, &sdata->work); } } @@ -1101,9 +1105,10 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) * anymore. The timeout will be reset if the frame is ACKed by * the AP. */ - if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) + if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { + ifmgd->nullfunc_failed = false; ieee80211_send_nullfunc(sdata->local, sdata, 0); - else { + } else { ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); } @@ -1912,6 +1917,31 @@ static void ieee80211_sta_timer(unsigned long data) ieee80211_queue_work(&local->hw, &sdata->work); } +static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, + u8 *bssid) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | + IEEE80211_STA_BEACON_POLL); + + ieee80211_set_disassoc(sdata, true, true); + mutex_unlock(&ifmgd->mtx); + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); + /* + * must be outside lock due to cfg80211, + * but that's not a problem. + */ + ieee80211_send_deauth_disassoc(sdata, bssid, + IEEE80211_STYPE_DEAUTH, + WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, + NULL, true); + mutex_lock(&ifmgd->mtx); +} + void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; @@ -1936,11 +1966,38 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) /* ACK received for nullfunc probing frame */ if (!ifmgd->probe_send_count) ieee80211_reset_ap_probe(sdata); - - else if (time_is_after_jiffies(ifmgd->probe_timeout)) + else if (ifmgd->nullfunc_failed) { + if (ifmgd->probe_send_count < max_tries) { +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: No ack for nullfunc frame to" + " AP %pM, try %d\n", + sdata->name, bssid, + ifmgd->probe_send_count); +#endif + ieee80211_mgd_probe_ap_send(sdata); + } else { +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: No ack for nullfunc frame to" + " AP %pM, disconnecting.\n", + sdata->name, bssid, + ifmgd->probe_send_count); +#endif + ieee80211_sta_connection_lost(sdata, bssid); + } + } else if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); - - else if (ifmgd->probe_send_count < max_tries) { + else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: Failed to send nullfunc to AP %pM" + " after %dms, disconnecting.\n", + sdata->name, + bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); +#endif + ieee80211_sta_connection_lost(sdata, bssid); + } else if (ifmgd->probe_send_count < max_tries) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG wiphy_debug(local->hw.wiphy, "%s: No probe response from AP %pM" @@ -1955,27 +2012,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) * We actually lost the connection ... or did we? * Let's make sure! */ - ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | - IEEE80211_STA_BEACON_POLL); wiphy_debug(local->hw.wiphy, "%s: No probe response from AP %pM" " after %dms, disconnecting.\n", sdata->name, bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); - ieee80211_set_disassoc(sdata, true, true); - mutex_unlock(&ifmgd->mtx); - mutex_lock(&local->mtx); - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); - /* - * must be outside lock due to cfg80211, - * but that's not a problem. - */ - ieee80211_send_deauth_disassoc(sdata, bssid, - IEEE80211_STYPE_DEAUTH, - WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, - NULL, true); - mutex_lock(&ifmgd->mtx); + + ieee80211_sta_connection_lost(sdata, bssid); } } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 4958710a7d92..38a797217a91 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -155,10 +155,6 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) ieee80211_queue_work(&local->hw, &local->recalc_smps); } - - if ((sdata->vif.type == NL80211_IFTYPE_STATION) && - (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) - ieee80211_sta_tx_notify(sdata, (void *) skb->data); } /* @@ -186,6 +182,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) int retry_count = -1, i; int rates_idx = -1; bool send_to_cooked; + bool acked; for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { /* the HW cannot have attempted that rate */ @@ -211,8 +208,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) continue; - if (!(info->flags & IEEE80211_TX_STAT_ACK) && - test_sta_flags(sta, WLAN_STA_PS_STA)) { + acked = !!(info->flags & IEEE80211_TX_STAT_ACK); + if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) { /* * The STA is in power save mode, so assume * that this TX packet failed because of that. @@ -244,7 +241,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) rcu_read_unlock(); return; } else { - if (!(info->flags & IEEE80211_TX_STAT_ACK)) + if (!acked) sta->tx_retry_failed++; sta->tx_retry_count += retry_count; } @@ -253,10 +250,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if (ieee80211_vif_is_mesh(&sta->sdata->vif)) ieee80211s_update_metric(local, sta, skb); - if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && - (info->flags & IEEE80211_TX_STAT_ACK)) + if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) ieee80211_frame_acked(sta, skb); + if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && + (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) + ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { if (info->flags & IEEE80211_TX_STAT_ACK) { if (sta->lost_packets) -- cgit v1.2.3-59-g8ed1b From d84938c9be85f4738a350ef44210789fef915cb7 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 3 Dec 2010 06:03:00 +0200 Subject: ath5k: Always write tx powertable on hw * By skipping tx power table calibration we also skip setting tx power table on hw. Make sure we always write tx power table on hw since it gets cleared on reset. Signed-off-by: Nick Kossifidis Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index df5cd0fd69d6..f84afb420bd8 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -2742,10 +2742,12 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, /* Write PDADC values on hw */ static void -ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, - u8 pdcurves, u8 *pdg_to_idx) +ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) { + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u8 *pdadc_out = ah->ah_txpower.txp_pd_table; + u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode]; + u8 pdcurves = ee->ee_pd_gains[ee_mode]; u32 reg; u8 i; @@ -2992,7 +2994,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, ee->ee_pd_gains[ee_mode]); /* Write settings on hw */ - ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx); + ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); /* Set txp.offset, note that table_min * can be negative */ @@ -3114,12 +3116,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - /* Reset TX power values */ - memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); - ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; - ah->ah_txpower.txp_min_pwr = 0; - ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; - /* Initialize TX power table */ switch (ah->ah_radio) { case AR5K_RF5110: @@ -3146,11 +3142,24 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, * so there is no need to recalculate the powertable, we 'll * just use the cached one */ if (!fast) { + /* Reset TX power values */ + memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); + ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; + ah->ah_txpower.txp_min_pwr = 0; + ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; + + /* Calculate the powertable */ ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type); - if (ret) - return ret; - } + if (ret) + return ret; + /* Write cached table on hw */ + } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC) + ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); + else + ath5k_setup_pcdac_table(ah); + + /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); -- cgit v1.2.3-59-g8ed1b From 073285fd392f6dc901da7c698d46e1e2a7e26436 Mon Sep 17 00:00:00 2001 From: Alexey Orishko Date: Mon, 29 Nov 2010 23:23:27 +0000 Subject: usbnet: changes for upcoming cdc_ncm driver Changes: include/linux/usb/usbnet.h: - a new flag to indicate driver's capability to accumulate IP packets in Tx direction and extract several packets from single skb in Rx direction. drivers/net/usb/usbnet.c: - the procedure of counting packets in usbnet was updated due to the accumulating of IP packets in the driver - no short packets are sent if indicated by the flag in driver_info structure Signed-off-by: Alexey Orishko Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 45 +++++++++++++++++++++++++++++++-------------- include/linux/usb/usbnet.h | 6 ++++++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index c04d49e31f81..cff74b81a7d2 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -391,14 +391,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) goto error; // else network stack removes extra byte if we forced a short packet - if (skb->len) - usbnet_skb_return (dev, skb); - else { - netif_dbg(dev, rx_err, dev->net, "drop\n"); -error: - dev->net->stats.rx_errors++; - skb_queue_tail (&dev->done, skb); + if (skb->len) { + /* all data was already cloned from skb inside the driver */ + if (dev->driver_info->flags & FLAG_MULTI_PACKET) + dev_kfree_skb_any(skb); + else + usbnet_skb_return(dev, skb); + return; } + + netif_dbg(dev, rx_err, dev->net, "drop\n"); +error: + dev->net->stats.rx_errors++; + skb_queue_tail(&dev->done, skb); } /*-------------------------------------------------------------------------*/ @@ -971,7 +976,8 @@ static void tx_complete (struct urb *urb) struct usbnet *dev = entry->dev; if (urb->status == 0) { - dev->net->stats.tx_packets++; + if (!(dev->driver_info->flags & FLAG_MULTI_PACKET)) + dev->net->stats.tx_packets++; dev->net->stats.tx_bytes += entry->length; } else { dev->net->stats.tx_errors++; @@ -1044,8 +1050,13 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, if (info->tx_fixup) { skb = info->tx_fixup (dev, skb, GFP_ATOMIC); if (!skb) { - netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); - goto drop; + if (netif_msg_tx_err(dev)) { + netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); + goto drop; + } else { + /* cdc_ncm collected packet; waits for more */ + goto not_drop; + } } } length = skb->len; @@ -1067,13 +1078,18 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect * the ZLP here, but ignore the one-byte packet. + * NOTE2: CDC NCM specification is different from CDC ECM when + * handling ZLP/short packets, so cdc_ncm driver will make short + * packet itself if needed. */ if (length % dev->maxpacket == 0) { if (!(info->flags & FLAG_SEND_ZLP)) { - urb->transfer_buffer_length++; - if (skb_tailroom(skb)) { - skb->data[skb->len] = 0; - __skb_put(skb, 1); + if (!(info->flags & FLAG_MULTI_PACKET)) { + urb->transfer_buffer_length++; + if (skb_tailroom(skb)) { + skb->data[skb->len] = 0; + __skb_put(skb, 1); + } } } else urb->transfer_flags |= URB_ZERO_PACKET; @@ -1122,6 +1138,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval); drop: dev->net->stats.tx_dropped++; +not_drop: if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 7ae27a473818..44842c8d38c0 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -97,6 +97,12 @@ struct driver_info { #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ +/* + * Indicates to usbnet, that USB driver accumulates multiple IP packets. + * Affects statistic (counters) and short packet handling. + */ +#define FLAG_MULTI_PACKET 0x1000 + /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); -- cgit v1.2.3-59-g8ed1b From 900d495a189dc3ff5952b98a77d18e3018f8286c Mon Sep 17 00:00:00 2001 From: Alexey Orishko Date: Mon, 29 Nov 2010 23:23:28 +0000 Subject: USB CDC NCM host driver The patch provides USB CDC NCM host driver support in the Linux Kernel. Changes: drivers/net/usb/cdc_ncm.c: - initial submission of the CDC NCM host driver; - verified on Intel 32/64 bit, Intel Atom, ST-Ericsson U8500 (ARM) - throughput measured over 100 Mbits duplex; - driver supports 16-bit NTB format only, but it is more than enough for transfers up to 64K; - driver can handle up to 32 datagrams in received NTB; - timer is used to collect several packets in Tx direction drivers/net/usb/Kconfig: - a new entry to compile CDC NCM host driver drivers/net/usb/Makefile: - a new entry to compile CDC NCM host driver Signed-off-by: Alexey Orishko Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 19 + drivers/net/usb/Makefile | 1 + drivers/net/usb/cdc_ncm.c | 1213 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1233 insertions(+) create mode 100644 drivers/net/usb/cdc_ncm.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 52ffabe6db0e..6f600cced6e1 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -196,6 +196,25 @@ config USB_NET_CDC_EEM IEEE 802 "local assignment" bit is set in the address, a "usbX" name is used instead. +config USB_NET_CDC_NCM + tristate "CDC NCM support" + depends on USB_USBNET + default y + help + This driver provides support for CDC NCM (Network Control Model + Device USB Class Specification). The CDC NCM specification is + available from . + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module. + + This driver should work with at least the following devices: + * ST-Ericsson M700 LTE FDD/TDD Mobile Broadband Modem (ref. design) + * ST-Ericsson M5730 HSPA+ Mobile Broadband Modem (reference design) + * ST-Ericsson M570 HSPA+ Mobile Broadband Modem (reference design) + * ST-Ericsson M343 HSPA Mobile Broadband Modem (reference design) + * Ericsson F5521gw Mobile Broadband Module + config USB_NET_DM9601 tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" depends on USB_USBNET diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index a19b0259ae16..cac170301187 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -26,4 +26,5 @@ obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o +obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c new file mode 100644 index 000000000000..593c104ab199 --- /dev/null +++ b/drivers/net/usb/cdc_ncm.c @@ -0,0 +1,1213 @@ +/* + * cdc_ncm.c + * + * Copyright (C) ST-Ericsson 2010 + * Contact: Alexey Orishko + * Original author: Hans Petter Selasky + * + * USB Host Driver for Network Control Model (NCM) + * http://www.usb.org/developers/devclass_docs/NCM10.zip + * + * The NCM encoding, decoding and initialization logic + * derives from FreeBSD 8.x. if_cdce.c and if_cdcereg.h + * + * This software is available to you under a choice of one of two + * licenses. You may choose this file to be licensed under the terms + * of the GNU General Public License (GPL) Version 2 or the 2-clause + * BSD license listed below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "30-Nov-2010" + +/* CDC NCM subclass 3.2.1 */ +#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 + +/* Maximum NTB length */ +#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ +#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ + +/* Minimum value for MaxDatagramSize, ch. 6.2.9 */ +#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */ + +#define CDC_NCM_MIN_TX_PKT 512 /* bytes */ + +/* Default value for MaxDatagramSize */ +#define CDC_NCM_MAX_DATAGRAM_SIZE 2048 /* bytes */ + +/* + * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting + * the last NULL entry. Any additional datagrams in NTB would be discarded. + */ +#define CDC_NCM_DPT_DATAGRAMS_MAX 32 + +/* Restart the timer, if amount of datagrams is less than given value */ +#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 + +/* The following macro defines the minimum header space */ +#define CDC_NCM_MIN_HDR_SIZE \ + (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ + (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) + +struct connection_speed_change { + __le32 USBitRate; /* holds 3GPP downlink value, bits per second */ + __le32 DSBitRate; /* holds 3GPP uplink value, bits per second */ +} __attribute__ ((packed)); + +struct cdc_ncm_data { + struct usb_cdc_ncm_nth16 nth16; + struct usb_cdc_ncm_ndp16 ndp16; + struct usb_cdc_ncm_dpe16 dpe16[CDC_NCM_DPT_DATAGRAMS_MAX + 1]; +}; + +struct cdc_ncm_ctx { + struct cdc_ncm_data rx_ncm; + struct cdc_ncm_data tx_ncm; + struct usb_cdc_ncm_ntb_parameters ncm_parm; + struct timer_list tx_timer; + + const struct usb_cdc_ncm_desc *func_desc; + const struct usb_cdc_header_desc *header_desc; + const struct usb_cdc_union_desc *union_desc; + const struct usb_cdc_ether_desc *ether_desc; + + struct net_device *netdev; + struct usb_device *udev; + struct usb_host_endpoint *in_ep; + struct usb_host_endpoint *out_ep; + struct usb_host_endpoint *status_ep; + struct usb_interface *intf; + struct usb_interface *control; + struct usb_interface *data; + + struct sk_buff *tx_curr_skb; + struct sk_buff *tx_rem_skb; + + spinlock_t mtx; + + u32 tx_timer_pending; + u32 tx_curr_offset; + u32 tx_curr_last_offset; + u32 tx_curr_frame_num; + u32 rx_speed; + u32 tx_speed; + u32 rx_max; + u32 tx_max; + u32 max_datagram_size; + u16 tx_max_datagrams; + u16 tx_remainder; + u16 tx_modulus; + u16 tx_ndp_modulus; + u16 tx_seq; + u16 connected; + u8 data_claimed; + u8 control_claimed; +}; + +static void cdc_ncm_tx_timeout(unsigned long arg); +static const struct driver_info cdc_ncm_info; +static struct usb_driver cdc_ncm_driver; +static struct ethtool_ops cdc_ncm_ethtool_ops; + +static const struct usb_device_id cdc_devs[] = { + { USB_INTERFACE_INFO(USB_CLASS_COMM, + USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_ncm_info, + }, + { + }, +}; + +MODULE_DEVICE_TABLE(usb, cdc_devs); + +static void +cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) +{ + struct usbnet *dev = netdev_priv(net); + + strncpy(info->driver, dev->driver_name, sizeof(info->driver)); + strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); + strncpy(info->fw_version, dev->driver_info->description, + sizeof(info->fw_version)); + usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); +} + +static int +cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req, + void *data, u16 flags, u16 *actlen, u16 timeout) +{ + int err; + + err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ? + usb_rcvctrlpipe(ctx->udev, 0) : + usb_sndctrlpipe(ctx->udev, 0), + req->bNotificationType, req->bmRequestType, + req->wValue, + req->wIndex, data, + req->wLength, timeout); + + if (err < 0) { + if (actlen) + *actlen = 0; + return err; + } + + if (actlen) + *actlen = err; + + return 0; +} + +static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) +{ + struct usb_cdc_notification req; + u32 val; + __le16 max_datagram_size; + u8 flags; + u8 iface_no; + int err; + + iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; + + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm)); + + err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000); + if (err) { + pr_debug("failed GET_NTB_PARAMETERS\n"); + return 1; + } + + /* read correct set of parameters according to device mode */ + ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); + ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); + ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); + ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); + ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); + + if (ctx->func_desc != NULL) + flags = ctx->func_desc->bmNetworkCapabilities; + else + flags = 0; + + pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " + "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " + "wNdpOutAlignment=%u flags=0x%x\n", + ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, + ctx->tx_ndp_modulus, flags); + + /* max count of tx datagrams without terminating NULL entry */ + ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; + + /* verify maximum size of received NTB in bytes */ + if ((ctx->rx_max < + (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || + (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX)) { + pr_debug("Using default maximum receive length=%d\n", + CDC_NCM_NTB_MAX_SIZE_RX); + ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; + } + + /* verify maximum size of transmitted NTB in bytes */ + if ((ctx->tx_max < + (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || + (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) { + pr_debug("Using default maximum transmit length=%d\n", + CDC_NCM_NTB_MAX_SIZE_TX); + ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; + } + + /* + * verify that the structure alignment is: + * - power of two + * - not greater than the maximum transmit length + * - not less than four bytes + */ + val = ctx->tx_ndp_modulus; + + if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) || + (val != ((-val) & val)) || (val >= ctx->tx_max)) { + pr_debug("Using default alignment: 4 bytes\n"); + ctx->tx_ndp_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; + } + + /* + * verify that the payload alignment is: + * - power of two + * - not greater than the maximum transmit length + * - not less than four bytes + */ + val = ctx->tx_modulus; + + if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) || + (val != ((-val) & val)) || (val >= ctx->tx_max)) { + pr_debug("Using default transmit modulus: 4 bytes\n"); + ctx->tx_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; + } + + /* verify the payload remainder */ + if (ctx->tx_remainder >= ctx->tx_modulus) { + pr_debug("Using default transmit remainder: 0 bytes\n"); + ctx->tx_remainder = 0; + } + + /* adjust TX-remainder according to NCM specification. */ + ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) & + (ctx->tx_modulus - 1)); + + /* additional configuration */ + + /* set CRC Mode */ + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_CRC_MODE; + req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) + pr_debug("Setting CRC mode off failed\n"); + + /* set NTB format */ + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_NTB_FORMAT; + req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) + pr_debug("Setting NTB format to 16-bit failed\n"); + + /* set Max Datagram Size (MTU) */ + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(2); + + err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, 1000); + if (err) { + pr_debug(" GET_MAX_DATAGRAM_SIZE failed, using size=%u\n", + CDC_NCM_MIN_DATAGRAM_SIZE); + /* use default */ + ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; + } else { + ctx->max_datagram_size = le16_to_cpu(max_datagram_size); + + if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) + ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; + else if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) + ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; + } + + if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) + ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN; + + return 0; +} + +static void +cdc_ncm_find_endpoints(struct cdc_ncm_ctx *ctx, struct usb_interface *intf) +{ + struct usb_host_endpoint *e; + u8 ep; + + for (ep = 0; ep < intf->cur_altsetting->desc.bNumEndpoints; ep++) { + + e = intf->cur_altsetting->endpoint + ep; + switch (e->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_INT: + if (usb_endpoint_dir_in(&e->desc)) { + if (ctx->status_ep == NULL) + ctx->status_ep = e; + } + break; + + case USB_ENDPOINT_XFER_BULK: + if (usb_endpoint_dir_in(&e->desc)) { + if (ctx->in_ep == NULL) + ctx->in_ep = e; + } else { + if (ctx->out_ep == NULL) + ctx->out_ep = e; + } + break; + + default: + break; + } + } +} + +static void cdc_ncm_free(struct cdc_ncm_ctx *ctx) +{ + if (ctx == NULL) + return; + + del_timer_sync(&ctx->tx_timer); + + if (ctx->data_claimed) { + usb_set_intfdata(ctx->data, NULL); + usb_driver_release_interface(driver_of(ctx->intf), ctx->data); + } + + if (ctx->control_claimed) { + usb_set_intfdata(ctx->control, NULL); + usb_driver_release_interface(driver_of(ctx->intf), + ctx->control); + } + + if (ctx->tx_rem_skb != NULL) { + dev_kfree_skb_any(ctx->tx_rem_skb); + ctx->tx_rem_skb = NULL; + } + + if (ctx->tx_curr_skb != NULL) { + dev_kfree_skb_any(ctx->tx_curr_skb); + ctx->tx_curr_skb = NULL; + } + + kfree(ctx); +} + +static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) +{ + struct cdc_ncm_ctx *ctx; + struct usb_driver *driver; + u8 *buf; + int len; + int temp; + u8 iface_no; + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (ctx == NULL) + goto error; + + memset(ctx, 0, sizeof(*ctx)); + + init_timer(&ctx->tx_timer); + spin_lock_init(&ctx->mtx); + ctx->netdev = dev->net; + + /* store ctx pointer in device data field */ + dev->data[0] = (unsigned long)ctx; + + /* get some pointers */ + driver = driver_of(intf); + buf = intf->cur_altsetting->extra; + len = intf->cur_altsetting->extralen; + + ctx->udev = dev->udev; + ctx->intf = intf; + + /* parse through descriptors associated with control interface */ + while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) { + + if (buf[1] != USB_DT_CS_INTERFACE) + goto advance; + + switch (buf[2]) { + case USB_CDC_UNION_TYPE: + if (buf[0] < sizeof(*(ctx->union_desc))) + break; + + ctx->union_desc = + (const struct usb_cdc_union_desc *)buf; + + ctx->control = usb_ifnum_to_if(dev->udev, + ctx->union_desc->bMasterInterface0); + ctx->data = usb_ifnum_to_if(dev->udev, + ctx->union_desc->bSlaveInterface0); + break; + + case USB_CDC_ETHERNET_TYPE: + if (buf[0] < sizeof(*(ctx->ether_desc))) + break; + + ctx->ether_desc = + (const struct usb_cdc_ether_desc *)buf; + + dev->hard_mtu = + le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); + + if (dev->hard_mtu < + (CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN)) + dev->hard_mtu = + CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN; + + else if (dev->hard_mtu > + (CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN)) + dev->hard_mtu = + CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN; + break; + + case USB_CDC_NCM_TYPE: + if (buf[0] < sizeof(*(ctx->func_desc))) + break; + + ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf; + break; + + default: + break; + } +advance: + /* advance to next descriptor */ + temp = buf[0]; + buf += temp; + len -= temp; + } + + /* check if we got everything */ + if ((ctx->control == NULL) || (ctx->data == NULL) || + (ctx->ether_desc == NULL)) + goto error; + + /* claim interfaces, if any */ + if (ctx->data != intf) { + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; + ctx->data_claimed = 1; + } + + if (ctx->control != intf) { + temp = usb_driver_claim_interface(driver, ctx->control, dev); + if (temp) + goto error; + ctx->control_claimed = 1; + } + + iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; + + /* reset data interface */ + temp = usb_set_interface(dev->udev, iface_no, 0); + if (temp) + goto error; + + /* initialize data interface */ + if (cdc_ncm_setup(ctx)) + goto error; + + /* configure data interface */ + temp = usb_set_interface(dev->udev, iface_no, 1); + if (temp) + goto error; + + cdc_ncm_find_endpoints(ctx, ctx->data); + cdc_ncm_find_endpoints(ctx, ctx->control); + + if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) || + (ctx->status_ep == NULL)) + goto error; + + dev->net->ethtool_ops = &cdc_ncm_ethtool_ops; + + usb_set_intfdata(ctx->data, dev); + usb_set_intfdata(ctx->control, dev); + usb_set_intfdata(ctx->intf, dev); + + temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); + if (temp) + goto error; + + dev_info(&dev->udev->dev, "MAC-Address: " + "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + dev->net->dev_addr[0], dev->net->dev_addr[1], + dev->net->dev_addr[2], dev->net->dev_addr[3], + dev->net->dev_addr[4], dev->net->dev_addr[5]); + + dev->in = usb_rcvbulkpipe(dev->udev, + ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + dev->out = usb_sndbulkpipe(dev->udev, + ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + dev->status = ctx->status_ep; + dev->rx_urb_size = ctx->rx_max; + + /* + * We should get an event when network connection is "connected" or + * "disconnected". Set network connection in "disconnected" state + * (carrier is OFF) during attach, so the IP network stack does not + * start IPv6 negotiation and more. + */ + netif_carrier_off(dev->net); + ctx->tx_speed = ctx->rx_speed = 0; + return 0; + +error: + cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); + dev->data[0] = 0; + dev_info(&dev->udev->dev, "Descriptor failure\n"); + return -ENODEV; +} + +static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + struct usb_driver *driver; + + if (ctx == NULL) + return; /* no setup */ + + driver = driver_of(intf); + + usb_set_intfdata(ctx->data, NULL); + usb_set_intfdata(ctx->control, NULL); + usb_set_intfdata(ctx->intf, NULL); + + /* release interfaces, if any */ + if (ctx->data_claimed) { + usb_driver_release_interface(driver, ctx->data); + ctx->data_claimed = 0; + } + + if (ctx->control_claimed) { + usb_driver_release_interface(driver, ctx->control); + ctx->control_claimed = 0; + } + + cdc_ncm_free(ctx); +} + +static void cdc_ncm_zero_fill(u8 *ptr, u32 first, u32 end, u32 max) +{ + if (first >= max) + return; + if (first >= end) + return; + if (end > max) + end = max; + memset(ptr + first, 0, end - first); +} + +static struct sk_buff * +cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) +{ + struct sk_buff *skb_out; + u32 rem; + u32 offset; + u32 last_offset; + u16 n = 0; + u8 timeout = 0; + + /* if there is a remaining skb, it gets priority */ + if (skb != NULL) + swap(skb, ctx->tx_rem_skb); + else + timeout = 1; + + /* + * +----------------+ + * | skb_out | + * +----------------+ + * ^ offset + * ^ last_offset + */ + + /* check if we are resuming an OUT skb */ + if (ctx->tx_curr_skb != NULL) { + /* pop variables */ + skb_out = ctx->tx_curr_skb; + offset = ctx->tx_curr_offset; + last_offset = ctx->tx_curr_last_offset; + n = ctx->tx_curr_frame_num; + + } else { + /* reset variables */ + skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC); + if (skb_out == NULL) { + if (skb != NULL) { + dev_kfree_skb_any(skb); + ctx->netdev->stats.tx_dropped++; + } + goto exit_no_skb; + } + + /* make room for NTH and NDP */ + offset = ALIGN(sizeof(struct usb_cdc_ncm_nth16), + ctx->tx_ndp_modulus) + + sizeof(struct usb_cdc_ncm_ndp16) + + (ctx->tx_max_datagrams + 1) * + sizeof(struct usb_cdc_ncm_dpe16); + + /* store last valid offset before alignment */ + last_offset = offset; + /* align first Datagram offset correctly */ + offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder; + /* zero buffer till the first IP datagram */ + cdc_ncm_zero_fill(skb_out->data, 0, offset, offset); + n = 0; + ctx->tx_curr_frame_num = 0; + } + + for (; n < ctx->tx_max_datagrams; n++) { + /* check if end of transmit buffer is reached */ + if (offset >= ctx->tx_max) + break; + + /* compute maximum buffer size */ + rem = ctx->tx_max - offset; + + if (skb == NULL) { + skb = ctx->tx_rem_skb; + ctx->tx_rem_skb = NULL; + + /* check for end of skb */ + if (skb == NULL) + break; + } + + if (skb->len > rem) { + if (n == 0) { + /* won't fit, MTU problem? */ + dev_kfree_skb_any(skb); + skb = NULL; + ctx->netdev->stats.tx_dropped++; + } else { + /* no room for skb - store for later */ + if (ctx->tx_rem_skb != NULL) { + dev_kfree_skb_any(ctx->tx_rem_skb); + ctx->netdev->stats.tx_dropped++; + } + ctx->tx_rem_skb = skb; + skb = NULL; + + /* loop one more time */ + timeout = 1; + } + break; + } + + memcpy(((u8 *)skb_out->data) + offset, skb->data, skb->len); + + ctx->tx_ncm.dpe16[n].wDatagramLength = cpu_to_le16(skb->len); + ctx->tx_ncm.dpe16[n].wDatagramIndex = cpu_to_le16(offset); + + /* update offset */ + offset += skb->len; + + /* store last valid offset before alignment */ + last_offset = offset; + + /* align offset correctly */ + offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder; + + /* zero padding */ + cdc_ncm_zero_fill(skb_out->data, last_offset, offset, + ctx->tx_max); + dev_kfree_skb_any(skb); + skb = NULL; + } + + /* free up any dangling skb */ + if (skb != NULL) { + dev_kfree_skb_any(skb); + skb = NULL; + ctx->netdev->stats.tx_dropped++; + } + + ctx->tx_curr_frame_num = n; + + if (n == 0) { + /* wait for more frames */ + /* push variables */ + ctx->tx_curr_skb = skb_out; + ctx->tx_curr_offset = offset; + ctx->tx_curr_last_offset = last_offset; + goto exit_no_skb; + + } else if ((n < ctx->tx_max_datagrams) && (timeout == 0)) { + /* wait for more frames */ + /* push variables */ + ctx->tx_curr_skb = skb_out; + ctx->tx_curr_offset = offset; + ctx->tx_curr_last_offset = last_offset; + /* set the pending count */ + if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT) + ctx->tx_timer_pending = 2; + goto exit_no_skb; + + } else { + /* frame goes out */ + /* variables will be reset at next call */ + } + + /* check for overflow */ + if (last_offset > ctx->tx_max) + last_offset = ctx->tx_max; + + /* revert offset */ + offset = last_offset; + + /* + * If collected data size is less or equal CDC_NCM_MIN_TX_PKT bytes, + * we send buffers as it is. If we get more data, it would be more + * efficient for USB HS mobile device with DMA engine to receive a full + * size NTB, than canceling DMA transfer and receiving a short packet. + */ + if (offset > CDC_NCM_MIN_TX_PKT) + offset = ctx->tx_max; + + /* final zero padding */ + cdc_ncm_zero_fill(skb_out->data, last_offset, offset, ctx->tx_max); + + /* store last offset */ + last_offset = offset; + + if ((last_offset < ctx->tx_max) && ((last_offset % + le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) { + /* force short packet */ + *(((u8 *)skb_out->data) + last_offset) = 0; + last_offset++; + } + + /* zero the rest of the DPEs plus the last NULL entry */ + for (; n <= CDC_NCM_DPT_DATAGRAMS_MAX; n++) { + ctx->tx_ncm.dpe16[n].wDatagramLength = 0; + ctx->tx_ncm.dpe16[n].wDatagramIndex = 0; + } + + /* fill out 16-bit NTB header */ + ctx->tx_ncm.nth16.dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); + ctx->tx_ncm.nth16.wHeaderLength = + cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); + ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); + ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); + ctx->tx_ncm.nth16.wFpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), + ctx->tx_ndp_modulus); + + memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); + ctx->tx_seq++; + + /* fill out 16-bit NDP table */ + ctx->tx_ncm.ndp16.dwSignature = + cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN); + rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * + sizeof(struct usb_cdc_ncm_dpe16)); + ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); + ctx->tx_ncm.ndp16.wNextFpIndex = 0; /* reserved */ + + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex, + &(ctx->tx_ncm.ndp16), + sizeof(ctx->tx_ncm.ndp16)); + + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex + + sizeof(ctx->tx_ncm.ndp16), + &(ctx->tx_ncm.dpe16), + (ctx->tx_curr_frame_num + 1) * + sizeof(struct usb_cdc_ncm_dpe16)); + + /* set frame length */ + skb_put(skb_out, last_offset); + + /* return skb */ + ctx->tx_curr_skb = NULL; + return skb_out; + +exit_no_skb: + return NULL; +} + +static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) +{ + /* start timer, if not already started */ + if (timer_pending(&ctx->tx_timer) == 0) { + ctx->tx_timer.function = &cdc_ncm_tx_timeout; + ctx->tx_timer.data = (unsigned long)ctx; + ctx->tx_timer.expires = jiffies + ((HZ + 999) / 1000); + add_timer(&ctx->tx_timer); + } +} + +static void cdc_ncm_tx_timeout(unsigned long arg) +{ + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)arg; + u8 restart; + + spin_lock(&ctx->mtx); + if (ctx->tx_timer_pending != 0) { + ctx->tx_timer_pending--; + restart = 1; + } else + restart = 0; + + spin_unlock(&ctx->mtx); + + if (restart) + cdc_ncm_tx_timeout_start(ctx); + else if (ctx->netdev != NULL) + usbnet_start_xmit(NULL, ctx->netdev); +} + +static struct sk_buff * +cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) +{ + struct sk_buff *skb_out; + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + u8 need_timer = 0; + + /* + * The Ethernet API we are using does not support transmitting + * multiple Ethernet frames in a single call. This driver will + * accumulate multiple Ethernet frames and send out a larger + * USB frame when the USB buffer is full or when a single jiffies + * timeout happens. + */ + if (ctx == NULL) + goto error; + + spin_lock(&ctx->mtx); + skb_out = cdc_ncm_fill_tx_frame(ctx, skb); + if (ctx->tx_curr_skb != NULL) + need_timer = 1; + spin_unlock(&ctx->mtx); + + /* Start timer, if there is a remaining skb */ + if (need_timer) + cdc_ncm_tx_timeout_start(ctx); + + if (skb_out) + dev->net->stats.tx_packets += ctx->tx_curr_frame_num; + return skb_out; + +error: + if (skb != NULL) + dev_kfree_skb_any(skb); + + return NULL; +} + +static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) +{ + struct sk_buff *skb; + struct cdc_ncm_ctx *ctx; + int sumlen; + int actlen; + int temp; + int nframes; + int x; + int offset; + + ctx = (struct cdc_ncm_ctx *)dev->data[0]; + if (ctx == NULL) + goto error; + + actlen = skb_in->len; + sumlen = CDC_NCM_NTB_MAX_SIZE_RX; + + if (actlen < (sizeof(ctx->rx_ncm.nth16) + sizeof(ctx->rx_ncm.ndp16))) { + pr_debug("frame too short\n"); + goto error; + } + + memcpy(&(ctx->rx_ncm.nth16), ((u8 *)skb_in->data), + sizeof(ctx->rx_ncm.nth16)); + + if (le32_to_cpu(ctx->rx_ncm.nth16.dwSignature) != + USB_CDC_NCM_NTH16_SIGN) { + pr_debug("invalid NTH16 signature <%u>\n", + le32_to_cpu(ctx->rx_ncm.nth16.dwSignature)); + goto error; + } + + temp = le16_to_cpu(ctx->rx_ncm.nth16.wBlockLength); + if (temp > sumlen) { + pr_debug("unsupported NTB block length %u/%u\n", temp, sumlen); + goto error; + } + + temp = le16_to_cpu(ctx->rx_ncm.nth16.wFpIndex); + if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { + pr_debug("invalid DPT16 index\n"); + goto error; + } + + memcpy(&(ctx->rx_ncm.ndp16), ((u8 *)skb_in->data) + temp, + sizeof(ctx->rx_ncm.ndp16)); + + if (le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature) != + USB_CDC_NCM_NDP16_NOCRC_SIGN) { + pr_debug("invalid DPT16 signature <%u>\n", + le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); + goto error; + } + + if (le16_to_cpu(ctx->rx_ncm.ndp16.wLength) < + USB_CDC_NCM_NDP16_LENGTH_MIN) { + pr_debug("invalid DPT16 length <%u>\n", + le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); + goto error; + } + + nframes = ((le16_to_cpu(ctx->rx_ncm.ndp16.wLength) - + sizeof(struct usb_cdc_ncm_ndp16)) / + sizeof(struct usb_cdc_ncm_dpe16)); + nframes--; /* we process NDP entries except for the last one */ + + pr_debug("nframes = %u\n", nframes); + + temp += sizeof(ctx->rx_ncm.ndp16); + + if ((temp + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > actlen) { + pr_debug("Invalid nframes = %d\n", nframes); + goto error; + } + + if (nframes > CDC_NCM_DPT_DATAGRAMS_MAX) { + pr_debug("Truncating number of frames from %u to %u\n", + nframes, CDC_NCM_DPT_DATAGRAMS_MAX); + nframes = CDC_NCM_DPT_DATAGRAMS_MAX; + } + + memcpy(&(ctx->rx_ncm.dpe16), ((u8 *)skb_in->data) + temp, + nframes * (sizeof(struct usb_cdc_ncm_dpe16))); + + for (x = 0; x < nframes; x++) { + offset = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramIndex); + temp = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramLength); + + /* + * CDC NCM ch. 3.7 + * All entries after first NULL entry are to be ignored + */ + if ((offset == 0) || (temp == 0)) { + if (!x) + goto error; /* empty NTB */ + break; + } + + /* sanity checking */ + if (((offset + temp) > actlen) || + (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { + pr_debug("invalid frame detected (ignored)" + "offset[%u]=%u, length=%u, skb=%p\n", + x, offset, temp, skb); + if (!x) + goto error; + break; + + } else { + skb = skb_clone(skb_in, GFP_ATOMIC); + skb->len = temp; + skb->data = ((u8 *)skb_in->data) + offset; + skb_set_tail_pointer(skb, temp); + usbnet_skb_return(dev, skb); + } + } + return 1; +error: + return 0; +} + +static void +cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx, + struct connection_speed_change *data) +{ + uint32_t rx_speed = le32_to_cpu(data->USBitRate); + uint32_t tx_speed = le32_to_cpu(data->DSBitRate); + + /* + * Currently the USB-NET API does not support reporting the actual + * device speed. Do print it instead. + */ + if ((tx_speed != ctx->tx_speed) || (rx_speed != ctx->rx_speed)) { + ctx->tx_speed = tx_speed; + ctx->rx_speed = rx_speed; + + if ((tx_speed > 1000000) && (rx_speed > 1000000)) { + printk(KERN_INFO KBUILD_MODNAME + ": %s: %u mbit/s downlink " + "%u mbit/s uplink\n", + ctx->netdev->name, + (unsigned int)(rx_speed / 1000000U), + (unsigned int)(tx_speed / 1000000U)); + } else { + printk(KERN_INFO KBUILD_MODNAME + ": %s: %u kbit/s downlink " + "%u kbit/s uplink\n", + ctx->netdev->name, + (unsigned int)(rx_speed / 1000U), + (unsigned int)(tx_speed / 1000U)); + } + } +} + +static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) +{ + struct cdc_ncm_ctx *ctx; + struct usb_cdc_notification *event; + + ctx = (struct cdc_ncm_ctx *)dev->data[0]; + + if (urb->actual_length < sizeof(*event)) + return; + + /* test for split data in 8-byte chunks */ + if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { + cdc_ncm_speed_change(ctx, + (struct connection_speed_change *)urb->transfer_buffer); + return; + } + + event = urb->transfer_buffer; + + switch (event->bNotificationType) { + case USB_CDC_NOTIFY_NETWORK_CONNECTION: + /* + * According to the CDC NCM specification ch.7.1 + * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be + * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. + */ + ctx->connected = event->wValue; + + printk(KERN_INFO KBUILD_MODNAME ": %s: network connection:" + " %sconnected\n", + ctx->netdev->name, ctx->connected ? "" : "dis"); + + if (ctx->connected) + netif_carrier_on(dev->net); + else { + netif_carrier_off(dev->net); + ctx->tx_speed = ctx->rx_speed = 0; + } + break; + + case USB_CDC_NOTIFY_SPEED_CHANGE: + if (urb->actual_length < + (sizeof(*event) + sizeof(struct connection_speed_change))) + set_bit(EVENT_STS_SPLIT, &dev->flags); + else + cdc_ncm_speed_change(ctx, + (struct connection_speed_change *) &event[1]); + break; + + default: + dev_err(&dev->udev->dev, "NCM: unexpected " + "notification 0x%02x!\n", event->bNotificationType); + break; + } +} + +static int cdc_ncm_check_connect(struct usbnet *dev) +{ + struct cdc_ncm_ctx *ctx; + + ctx = (struct cdc_ncm_ctx *)dev->data[0]; + if (ctx == NULL) + return 1; /* disconnected */ + + return !ctx->connected; +} + +static int +cdc_ncm_probe(struct usb_interface *udev, const struct usb_device_id *prod) +{ + return usbnet_probe(udev, prod); +} + +static void cdc_ncm_disconnect(struct usb_interface *intf) +{ + struct usbnet *dev = usb_get_intfdata(intf); + + if (dev == NULL) + return; /* already disconnected */ + + usbnet_disconnect(intf); +} + +static int cdc_ncm_manage_power(struct usbnet *dev, int status) +{ + dev->intf->needs_remote_wakeup = status; + return 0; +} + +static const struct driver_info cdc_ncm_info = { + .description = "CDC NCM", + .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET, + .bind = cdc_ncm_bind, + .unbind = cdc_ncm_unbind, + .check_connect = cdc_ncm_check_connect, + .manage_power = cdc_ncm_manage_power, + .status = cdc_ncm_status, + .rx_fixup = cdc_ncm_rx_fixup, + .tx_fixup = cdc_ncm_tx_fixup, +}; + +static struct usb_driver cdc_ncm_driver = { + .name = "cdc_ncm", + .id_table = cdc_devs, + .probe = cdc_ncm_probe, + .disconnect = cdc_ncm_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .supports_autosuspend = 1, +}; + +static struct ethtool_ops cdc_ncm_ethtool_ops = { + .get_drvinfo = cdc_ncm_get_drvinfo, + .get_link = usbnet_get_link, + .get_msglevel = usbnet_get_msglevel, + .set_msglevel = usbnet_set_msglevel, + .get_settings = usbnet_get_settings, + .set_settings = usbnet_set_settings, + .nway_reset = usbnet_nway_reset, +}; + +static int __init cdc_ncm_init(void) +{ + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION "\n"); + return usb_register(&cdc_ncm_driver); +} + +module_init(cdc_ncm_init); + +static void __exit cdc_ncm_exit(void) +{ + usb_deregister(&cdc_ncm_driver); +} + +module_exit(cdc_ncm_exit); + +MODULE_AUTHOR("Hans Petter Selasky"); +MODULE_DESCRIPTION("USB CDC NCM host driver"); +MODULE_LICENSE("Dual BSD/GPL"); -- cgit v1.2.3-59-g8ed1b From 7903264402546f45f9bac8ad2bfdb00d00eb124a Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 30 Nov 2010 06:38:00 +0000 Subject: net: Fix too optimistic NETIF_F_HW_CSUM features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NETIF_F_HW_CSUM is a superset of NETIF_F_IP_CSUM+NETIF_F_IPV6_CSUM, but some drivers miss the difference. Fix this and also fix UFO dependency on checksumming offload as it makes the same mistake in assumptions. Signed-off-by: Michał Mirosław Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 ++++-- drivers/net/bnx2x/bnx2x_main.c | 4 ++-- drivers/net/jme.c | 16 +++++++++------- drivers/net/pch_gbe/pch_gbe_ethtool.c | 19 +------------------ drivers/net/pch_gbe/pch_gbe_main.c | 6 +++--- drivers/net/sc92031.c | 3 ++- drivers/net/stmmac/stmmac_ethtool.c | 12 +----------- drivers/net/stmmac/stmmac_main.c | 5 +++-- drivers/net/vxge/vxge-ethtool.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- net/core/dev.c | 7 +++++-- net/core/ethtool.c | 4 +++- 12 files changed, 35 insertions(+), 51 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 102567ee68c2..275428032ce2 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2583,10 +2583,12 @@ static void be_netdev_init(struct net_device *netdev) int i; netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_TSO6; - netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM; + netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (lancer_chip(adapter)) netdev->vlan_features |= NETIF_F_TSO6; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 1552fc3c1351..0068a1dbc064 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8957,7 +8957,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->netdev_ops = &bnx2x_netdev_ops; bnx2x_set_ethtool_ops(dev); dev->features |= NETIF_F_SG; - dev->features |= NETIF_F_HW_CSUM; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (bp->flags & USING_DAC_FLAG) dev->features |= NETIF_F_HIGHDMA; dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); @@ -8965,7 +8965,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); dev->vlan_features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_HW_CSUM; + dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (bp->flags & USING_DAC_FLAG) dev->vlan_features |= NETIF_F_HIGHDMA; dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); diff --git a/drivers/net/jme.c b/drivers/net/jme.c index c57d9a43ceca..2411e72ba572 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2076,12 +2076,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) } if (new_mtu > 1900) { - netdev->features &= ~(NETIF_F_HW_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6); + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO6); } else { if (test_bit(JME_FLAG_TXCSUM, &jme->flags)) - netdev->features |= NETIF_F_HW_CSUM; + netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (test_bit(JME_FLAG_TSO, &jme->flags)) netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; } @@ -2514,10 +2513,12 @@ jme_set_tx_csum(struct net_device *netdev, u32 on) if (on) { set_bit(JME_FLAG_TXCSUM, &jme->flags); if (netdev->mtu <= 1900) - netdev->features |= NETIF_F_HW_CSUM; + netdev->features |= + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; } else { clear_bit(JME_FLAG_TXCSUM, &jme->flags); - netdev->features &= ~NETIF_F_HW_CSUM; + netdev->features &= + ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); } return 0; @@ -2797,7 +2798,8 @@ jme_init_one(struct pci_dev *pdev, netdev->netdev_ops = &jme_netdev_ops; netdev->ethtool_ops = &jme_ethtool_ops; netdev->watchdog_timeo = TX_TIMEOUT; - netdev->features = NETIF_F_HW_CSUM | + netdev->features = NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c index c8cc32c0edc9..c8c873b31a89 100644 --- a/drivers/net/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -468,18 +468,6 @@ static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data) return 0; } -/** - * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off - * @netdev: Network interface device structure - * Returns - * true(1): Checksum On - * false(0): Checksum Off - */ -static u32 pch_gbe_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_HW_CSUM) != 0; -} - /** * pch_gbe_set_tx_csum - Turn transmit checksums on or off * @netdev: Network interface device structure @@ -493,11 +481,7 @@ static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data) struct pch_gbe_adapter *adapter = netdev_priv(netdev); adapter->tx_csum = data; - if (data) - netdev->features |= NETIF_F_HW_CSUM; - else - netdev->features &= ~NETIF_F_HW_CSUM; - return 0; + return ethtool_op_set_tx_ipv6_csum(netdev, data); } /** @@ -572,7 +556,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = { .set_pauseparam = pch_gbe_set_pauseparam, .get_rx_csum = pch_gbe_get_rx_csum, .set_rx_csum = pch_gbe_set_rx_csum, - .get_tx_csum = pch_gbe_get_tx_csum, .set_tx_csum = pch_gbe_set_tx_csum, .get_strings = pch_gbe_get_strings, .get_ethtool_stats = pch_gbe_get_ethtool_stats, diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index afb75066b14d..58e79033a8ee 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -2319,7 +2319,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; netif_napi_add(netdev, &adapter->napi, pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT); - netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO; + netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; pch_gbe_set_ethtool_ops(netdev); pch_gbe_mac_reset_hw(&adapter->hw); @@ -2358,9 +2358,9 @@ static int pch_gbe_probe(struct pci_dev *pdev, pch_gbe_check_options(adapter); if (adapter->tx_csum) - netdev->features |= NETIF_F_HW_CSUM; + netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; else - netdev->features &= ~NETIF_F_HW_CSUM; + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); /* initialize the wol settings based on the eeprom settings */ adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING; diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 417adf372828..76290a8c3c14 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -1449,7 +1449,8 @@ static int __devinit sc92031_probe(struct pci_dev *pdev, dev->irq = pdev->irq; /* faked with skb_copy_and_csum_dev */ - dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; + dev->features = NETIF_F_SG | NETIF_F_HIGHDMA | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; dev->netdev_ops = &sc92031_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index f2695fd180ca..fd719edc7f7c 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -197,16 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev, } } -static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) -{ - if (data) - netdev->features |= NETIF_F_HW_CSUM; - else - netdev->features &= ~NETIF_F_HW_CSUM; - - return 0; -} - static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); @@ -370,7 +360,7 @@ static struct ethtool_ops stmmac_ethtool_ops = { .get_link = ethtool_op_get_link, .get_rx_csum = stmmac_ethtool_get_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = stmmac_ethtool_set_tx_csum, + .set_tx_csum = ethtool_op_set_tx_ipv6_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_pauseparam = stmmac_get_pauseparam, diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 730a6fd79ee0..bfc2d1251502 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1494,7 +1494,8 @@ static int stmmac_probe(struct net_device *dev) dev->netdev_ops = &stmmac_netdev_ops; stmmac_set_ethtool_ops(dev); - dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA); + dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; dev->watchdog_timeo = msecs_to_jiffies(watchdog); #ifdef STMMAC_VLAN_TAG_USED /* Both mac100 and gmac support receive VLAN tag detection */ @@ -1525,7 +1526,7 @@ static int stmmac_probe(struct net_device *dev) DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n", dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", - (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); + (dev->features & NETIF_F_IP_CSUM) ? "on" : "off"); spin_lock_init(&priv->lock); diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index bc9bd1035706..1dd3a21b3a43 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -1177,7 +1177,7 @@ static const struct ethtool_ops vxge_ethtool_ops = { .get_rx_csum = vxge_get_rx_csum, .set_rx_csum = vxge_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, + .set_tx_csum = ethtool_op_set_tx_ipv6_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 8a84152e320a..4877b3b8a29e 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3368,7 +3368,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, ndev->features |= NETIF_F_SG; - ndev->features |= NETIF_F_HW_CSUM; + ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; vxge_debug_init(vxge_hw_device_trace_level_get(hldev), "%s : checksuming enabled", __func__); diff --git a/net/core/dev.c b/net/core/dev.c index cd2437495428..55ff66fabce4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5041,10 +5041,13 @@ unsigned long netdev_fix_features(unsigned long features, const char *name) } if (features & NETIF_F_UFO) { - if (!(features & NETIF_F_GEN_CSUM)) { + /* maybe split UFO into V4 and V6? */ + if (!((features & NETIF_F_GEN_CSUM) || + (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) + == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { if (name) printk(KERN_ERR "%s: Dropping NETIF_F_UFO " - "since no NETIF_F_HW_CSUM feature.\n", + "since no checksum offload features.\n", name); features &= ~NETIF_F_UFO; } diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 956a9f4971cb..d5bc28818883 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1171,7 +1171,9 @@ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) return -EFAULT; if (edata.data && !(dev->features & NETIF_F_SG)) return -EINVAL; - if (edata.data && !(dev->features & NETIF_F_HW_CSUM)) + if (edata.data && !((dev->features & NETIF_F_GEN_CSUM) || + (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) + == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) return -EINVAL; return dev->ethtool_ops->set_ufo(dev, edata.data); } -- cgit v1.2.3-59-g8ed1b From 539995d18649023199986424d140f1d620372ce5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 30 Nov 2010 08:18:44 +0000 Subject: ehea: Use the standard logging functions Remove ehea_error, ehea_info and ehea_debug macros. Use pr_fmt, pr_, netdev_ and netif_ as appropriate. Fix messages to use trailing "\n", some messages had an extra one as the old ehea_ macros added a trailing "\n". Coalesced long format strings. Uncompiled/untested. Signed-off-by: Joe Perches Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 13 -- drivers/net/ehea/ehea_ethtool.c | 18 +- drivers/net/ehea/ehea_main.c | 407 ++++++++++++++++++++-------------------- drivers/net/ehea/ehea_phyp.c | 40 ++-- drivers/net/ehea/ehea_qmr.c | 89 ++++----- 5 files changed, 274 insertions(+), 293 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 8e745e74828d..45e709f7609f 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -130,19 +130,6 @@ /* utility functions */ -#define ehea_info(fmt, args...) \ - printk(KERN_INFO DRV_NAME ": " fmt "\n", ## args) - -#define ehea_error(fmt, args...) \ - printk(KERN_ERR DRV_NAME ": Error in %s: " fmt "\n", __func__, ## args) - -#ifdef DEBUG -#define ehea_debug(fmt, args...) \ - printk(KERN_DEBUG DRV_NAME ": " fmt, ## args) -#else -#define ehea_debug(fmt, args...) do {} while (0) -#endif - void ehea_dump(void *adr, int len, char *msg); #define EHEA_BMASK(pos, length) (((pos) << 16) + (length)) diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 75b099ce49c9..273fedbb6d0e 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ehea.h" #include "ehea_phyp.h" @@ -118,10 +120,10 @@ doit: ret = ehea_set_portspeed(port, sp); if (!ret) - ehea_info("%s: Port speed successfully set: %dMbps " - "%s Duplex", - port->netdev->name, port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + netdev_info(dev, + "Port speed successfully set: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); out: return ret; } @@ -134,10 +136,10 @@ static int ehea_nway_reset(struct net_device *dev) ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); if (!ret) - ehea_info("%s: Port speed successfully set: %dMbps " - "%s Duplex", - port->netdev->name, port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + netdev_info(port->netdev, + "Port speed successfully set: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); return ret; } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index a84c389d3db7..f700c76d3e60 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -136,8 +138,8 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, - deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); + pr_info("%s adr=%p ofs=%04x %016llx %016llx\n", + msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } } @@ -337,7 +339,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) cb2 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb2) { - ehea_error("no mem for cb2"); + netdev_err(dev, "no mem for cb2\n"); goto out; } @@ -345,7 +347,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) port->logical_port_id, H_PORT_CB2, H_PORT_CB2_ALL, cb2); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + netdev_err(dev, "query_ehea_port failed\n"); goto out_herr; } @@ -461,8 +463,9 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, if (!skb) { q_skba->os_skbs = fill_wqes - i; if (q_skba->os_skbs == q_skba->len - 2) { - ehea_info("%s: rq%i ran dry - no mem for skb", - pr->port->netdev->name, rq_nr); + netdev_info(pr->port->netdev, + "rq%i ran dry - no mem for skb\n", + rq_nr); ret = -ENOMEM; } break; @@ -627,8 +630,8 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) { if (netif_msg_rx_err(pr->port)) { - ehea_error("Critical receive error for QP %d. " - "Resetting port.", pr->qp->init_attr.qp_nr); + pr_err("Critical receive error for QP %d. Resetting port.\n", + pr->qp->init_attr.qp_nr); ehea_dump(cqe, sizeof(*cqe), "CQE"); } ehea_schedule_port_reset(pr->port); @@ -730,8 +733,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb_arr_rq1_len, wqe_index); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("LL rq1: skb=NULL"); + netif_err(port, rx_err, dev, + "LL rq1: skb=NULL\n"); skb = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); @@ -746,8 +749,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq2, skb_arr_rq2_len, cqe); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("rq2: skb=NULL"); + netif_err(port, rx_err, dev, + "rq2: skb=NULL\n"); break; } ehea_fill_skb(dev, skb, cqe); @@ -757,8 +760,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq3, skb_arr_rq3_len, cqe); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("rq3: skb=NULL"); + netif_err(port, rx_err, dev, + "rq3: skb=NULL\n"); break; } ehea_fill_skb(dev, skb, cqe); @@ -830,7 +833,7 @@ static void check_sqs(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - ehea_error("HW/SW queues out of sync"); + pr_err("HW/SW queues out of sync\n"); ehea_schedule_port_reset(pr->port); return; } @@ -863,14 +866,14 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) } if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { - ehea_error("Bad send completion status=0x%04X", - cqe->status); + pr_err("Bad send completion status=0x%04X\n", + cqe->status); if (netif_msg_tx_err(pr->port)) ehea_dump(cqe, sizeof(*cqe), "Send CQE"); if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { - ehea_error("Resetting port"); + pr_err("Resetting port\n"); ehea_schedule_port_reset(pr->port); break; } @@ -988,8 +991,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_error("QP aff_err: entry=0x%llx, token=0x%x", - eqe->entry, qp_token); + pr_err("QP aff_err: entry=0x%llx, token=0x%x\n", + eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1007,7 +1010,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) } if (reset_port) { - ehea_error("Resetting port"); + pr_err("Resetting port\n"); ehea_schedule_port_reset(port); } @@ -1035,7 +1038,7 @@ int ehea_sense_port_attr(struct ehea_port *port) /* may be called via ehea_neq_tasklet() */ cb0 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb0) { - ehea_error("no mem for cb0"); + pr_err("no mem for cb0\n"); ret = -ENOMEM; goto out; } @@ -1127,7 +1130,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - ehea_error("no mem for cb4"); + pr_err("no mem for cb4\n"); ret = -ENOMEM; goto out; } @@ -1178,16 +1181,16 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) break; } } else { - ehea_error("Failed sensing port speed"); + pr_err("Failed sensing port speed\n"); ret = -EIO; } } else { if (hret == H_AUTHORITY) { - ehea_info("Hypervisor denied setting port speed"); + pr_info("Hypervisor denied setting port speed\n"); ret = -EPERM; } else { ret = -EIO; - ehea_error("Failed setting port speed"); + pr_err("Failed setting port speed\n"); } } if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP)) @@ -1204,80 +1207,78 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) u8 ec; u8 portnum; struct ehea_port *port; + struct net_device *dev; ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe); portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe); port = ehea_get_port(adapter, portnum); + dev = port->netdev; switch (ec) { case EHEA_EC_PORTSTATE_CHG: /* port state change */ if (!port) { - ehea_error("unknown portnum %x", portnum); + netdev_err(dev, "unknown portnum %x\n", portnum); break; } if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { - if (!netif_carrier_ok(port->netdev)) { + if (!netif_carrier_ok(dev)) { ret = ehea_sense_port_attr(port); if (ret) { - ehea_error("failed resensing port " - "attributes"); + netdev_err(dev, "failed resensing port attributes\n"); break; } - if (netif_msg_link(port)) - ehea_info("%s: Logical port up: %dMbps " - "%s Duplex", - port->netdev->name, - port->port_speed, - port->full_duplex == - 1 ? "Full" : "Half"); + netif_info(port, link, dev, + "Logical port up: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? + "Full" : "Half"); - netif_carrier_on(port->netdev); - netif_wake_queue(port->netdev); + netif_carrier_on(dev); + netif_wake_queue(dev); } } else - if (netif_carrier_ok(port->netdev)) { - if (netif_msg_link(port)) - ehea_info("%s: Logical port down", - port->netdev->name); - netif_carrier_off(port->netdev); - netif_stop_queue(port->netdev); + if (netif_carrier_ok(dev)) { + netif_info(port, link, dev, + "Logical port down\n"); + netif_carrier_off(dev); + netif_stop_queue(dev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) { port->phy_link = EHEA_PHY_LINK_UP; - if (netif_msg_link(port)) - ehea_info("%s: Physical port up", - port->netdev->name); + netif_info(port, link, dev, + "Physical port up\n"); if (prop_carrier_state) - netif_carrier_on(port->netdev); + netif_carrier_on(dev); } else { port->phy_link = EHEA_PHY_LINK_DOWN; - if (netif_msg_link(port)) - ehea_info("%s: Physical port down", - port->netdev->name); + netif_info(port, link, dev, + "Physical port down\n"); if (prop_carrier_state) - netif_carrier_off(port->netdev); + netif_carrier_off(dev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe)) - ehea_info("External switch port is primary port"); + netdev_info(dev, + "External switch port is primary port\n"); else - ehea_info("External switch port is backup port"); + netdev_info(dev, + "External switch port is backup port\n"); break; case EHEA_EC_ADAPTER_MALFUNC: - ehea_error("Adapter malfunction"); + netdev_err(dev, "Adapter malfunction\n"); break; case EHEA_EC_PORT_MALFUNC: - ehea_info("Port malfunction: Device: %s", port->netdev->name); - netif_carrier_off(port->netdev); - netif_stop_queue(port->netdev); + netdev_info(dev, "Port malfunction\n"); + netif_carrier_off(dev); + netif_stop_queue(dev); break; default: - ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); + netdev_err(dev, "unknown event code %x, eqe=0x%llX\n", ec, eqe); break; } } @@ -1289,13 +1290,13 @@ static void ehea_neq_tasklet(unsigned long data) u64 event_mask; eqe = ehea_poll_eq(adapter->neq); - ehea_debug("eqe=%p", eqe); + pr_debug("eqe=%p\n", eqe); while (eqe) { - ehea_debug("*eqe=%lx", eqe->entry); + pr_debug("*eqe=%lx\n", eqe->entry); ehea_parse_eqe(adapter, eqe->entry); eqe = ehea_poll_eq(adapter->neq); - ehea_debug("next eqe=%p", eqe); + pr_debug("next eqe=%p\n", eqe); } event_mask = EHEA_BMASK_SET(NELR_PORTSTATE_CHG, 1) @@ -1344,14 +1345,14 @@ static int ehea_reg_interrupts(struct net_device *dev) ehea_qp_aff_irq_handler, IRQF_DISABLED, port->int_aff_name, port); if (ret) { - ehea_error("failed registering irq for qp_aff_irq_handler:" - "ist=%X", port->qp_eq->attr.ist1); + netdev_err(dev, "failed registering irq for qp_aff_irq_handler:ist=%X\n", + port->qp_eq->attr.ist1); goto out_free_qpeq; } - if (netif_msg_ifup(port)) - ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " - "registered", port->qp_eq->attr.ist1); + netif_info(port, ifup, dev, + "irq_handle 0x%X for function qp_aff_irq_handler registered\n", + port->qp_eq->attr.ist1); for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { @@ -1363,14 +1364,13 @@ static int ehea_reg_interrupts(struct net_device *dev) IRQF_DISABLED, pr->int_send_name, pr); if (ret) { - ehea_error("failed registering irq for ehea_queue " - "port_res_nr:%d, ist=%X", i, - pr->eq->attr.ist1); + netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n", + i, pr->eq->attr.ist1); goto out_free_req; } - if (netif_msg_ifup(port)) - ehea_info("irq_handle 0x%X for function ehea_queue_int " - "%d registered", pr->eq->attr.ist1, i); + netif_info(port, ifup, dev, + "irq_handle 0x%X for function ehea_queue_int %d registered\n", + pr->eq->attr.ist1, i); } out: return ret; @@ -1401,16 +1401,16 @@ static void ehea_free_interrupts(struct net_device *dev) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { pr = &port->port_res[i]; ibmebus_free_irq(pr->eq->attr.ist1, pr); - if (netif_msg_intr(port)) - ehea_info("free send irq for res %d with handle 0x%X", - i, pr->eq->attr.ist1); + netif_info(port, intr, dev, + "free send irq for res %d with handle 0x%X\n", + i, pr->eq->attr.ist1); } /* associated events */ ibmebus_free_irq(port->qp_eq->attr.ist1, port); - if (netif_msg_intr(port)) - ehea_info("associated event interrupt for handle 0x%X freed", - port->qp_eq->attr.ist1); + netif_info(port, intr, dev, + "associated event interrupt for handle 0x%X freed\n", + port->qp_eq->attr.ist1); } static int ehea_configure_port(struct ehea_port *port) @@ -1479,7 +1479,7 @@ int ehea_gen_smrs(struct ehea_port_res *pr) out_free: ehea_rem_mr(&pr->send_mr); out: - ehea_error("Generating SMRS failed\n"); + pr_err("Generating SMRS failed\n"); return -EIO; } @@ -1534,7 +1534,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); if (!pr->eq) { - ehea_error("create_eq failed (eq)"); + pr_err("create_eq failed (eq)\n"); goto out_free; } @@ -1542,7 +1542,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->recv_cq) { - ehea_error("create_cq failed (cq_recv)"); + pr_err("create_cq failed (cq_recv)\n"); goto out_free; } @@ -1550,19 +1550,19 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->send_cq) { - ehea_error("create_cq failed (cq_send)"); + pr_err("create_cq failed (cq_send)\n"); goto out_free; } if (netif_msg_ifup(port)) - ehea_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d", - pr->send_cq->attr.act_nr_of_cqes, - pr->recv_cq->attr.act_nr_of_cqes); + pr_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d\n", + pr->send_cq->attr.act_nr_of_cqes, + pr->recv_cq->attr.act_nr_of_cqes); init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL); if (!init_attr) { ret = -ENOMEM; - ehea_error("no mem for ehea_qp_init_attr"); + pr_err("no mem for ehea_qp_init_attr\n"); goto out_free; } @@ -1587,18 +1587,18 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->qp = ehea_create_qp(adapter, adapter->pd, init_attr); if (!pr->qp) { - ehea_error("create_qp failed"); + pr_err("create_qp failed\n"); ret = -EIO; goto out_free; } if (netif_msg_ifup(port)) - ehea_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n " - "nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d", init_attr->qp_nr, - init_attr->act_nr_send_wqes, - init_attr->act_nr_rwqes_rq1, - init_attr->act_nr_rwqes_rq2, - init_attr->act_nr_rwqes_rq3); + pr_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d\n", + init_attr->qp_nr, + init_attr->act_nr_send_wqes, + init_attr->act_nr_rwqes_rq1, + init_attr->act_nr_rwqes_rq2, + init_attr->act_nr_rwqes_rq3); pr->sq_skba_size = init_attr->act_nr_send_wqes + 1; @@ -1749,7 +1749,7 @@ static void write_swqe2_TSO(struct sk_buff *skb, swqe->descriptors++; } } else - ehea_error("cannot handle fragmented headers"); + pr_err("cannot handle fragmented headers\n"); } static void write_swqe2_nonTSO(struct sk_buff *skb, @@ -1845,8 +1845,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - ehea_error("%sregistering bc address failed (tagged)", - hcallid == H_REG_BCMC ? "" : "de"); + pr_err("%sregistering bc address failed (tagged)\n", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; goto out_herr; } @@ -1857,8 +1857,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - ehea_error("%sregistering bc address failed (vlan)", - hcallid == H_REG_BCMC ? "" : "de"); + pr_err("%sregistering bc address failed (vlan)\n", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; } out_herr: @@ -1880,7 +1880,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) cb0 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb0) { - ehea_error("no mem for cb0"); + pr_err("no mem for cb0\n"); ret = -ENOMEM; goto out; } @@ -1928,11 +1928,11 @@ out: static void ehea_promiscuous_error(u64 hret, int enable) { if (hret == H_AUTHORITY) - ehea_info("Hypervisor denied %sabling promiscuous mode", - enable == 1 ? "en" : "dis"); + pr_info("Hypervisor denied %sabling promiscuous mode\n", + enable == 1 ? "en" : "dis"); else - ehea_error("failed %sabling promiscuous mode", - enable == 1 ? "en" : "dis"); + pr_err("failed %sabling promiscuous mode\n", + enable == 1 ? "en" : "dis"); } static void ehea_promiscuous(struct net_device *dev, int enable) @@ -1946,7 +1946,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) cb7 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb7) { - ehea_error("no mem for cb7"); + pr_err("no mem for cb7\n"); goto out; } @@ -2006,7 +2006,7 @@ static int ehea_drop_multicast_list(struct net_device *dev) hret = ehea_multicast_reg_helper(port, mc_entry->macaddr, H_DEREG_BCMC); if (hret) { - ehea_error("failed deregistering mcast MAC"); + pr_err("failed deregistering mcast MAC\n"); ret = -EIO; } @@ -2029,7 +2029,8 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 1; else - ehea_error("failed enabling IFF_ALLMULTI"); + netdev_err(dev, + "failed enabling IFF_ALLMULTI\n"); } } else if (!enable) { @@ -2038,7 +2039,8 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 0; else - ehea_error("failed disabling IFF_ALLMULTI"); + netdev_err(dev, + "failed disabling IFF_ALLMULTI\n"); } } @@ -2049,7 +2051,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); if (!ehea_mcl_entry) { - ehea_error("no mem for mcl_entry"); + pr_err("no mem for mcl_entry\n"); return; } @@ -2062,7 +2064,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) if (!hret) list_add(&ehea_mcl_entry->list, &port->mc_list->list); else { - ehea_error("failed registering mcast MAC"); + pr_err("failed registering mcast MAC\n"); kfree(ehea_mcl_entry); } } @@ -2095,9 +2097,8 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (netdev_mc_count(dev) > port->adapter->max_mc_mac) { - ehea_info("Mcast registration limit reached (0x%llx). " - "Use ALLMULTI!", - port->adapter->max_mc_mac); + pr_info("Mcast registration limit reached (0x%llx). Use ALLMULTI!\n", + port->adapter->max_mc_mac); goto out; } @@ -2303,10 +2304,10 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - if (netif_msg_tx_queued(port)) { - ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); + netif_info(port, tx_queued, dev, + "post swqe on QP %d\n", pr->qp->init_attr.qp_nr); + if (netif_msg_tx_queued(port)) ehea_dump(swqe, 512, "swqe"); - } if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { netif_stop_queue(dev); @@ -2342,14 +2343,14 @@ static void ehea_vlan_rx_register(struct net_device *dev, cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); free_page((unsigned long)cb1); out: @@ -2366,14 +2367,14 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + pr_err("query_ehea_port failed\n"); goto out; } @@ -2383,7 +2384,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); out: free_page((unsigned long)cb1); return; @@ -2401,14 +2402,14 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + pr_err("query_ehea_port failed\n"); goto out; } @@ -2418,7 +2419,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); out: free_page((unsigned long)cb1); } @@ -2440,7 +2441,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + pr_err("query_ehea_qp failed (1)\n"); goto out; } @@ -2449,14 +2450,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + pr_err("modify_ehea_qp failed (1)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + pr_err("query_ehea_qp failed (2)\n"); goto out; } @@ -2465,14 +2466,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (2)"); + pr_err("modify_ehea_qp failed (2)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (3)"); + pr_err("query_ehea_qp failed (3)\n"); goto out; } @@ -2481,14 +2482,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (3)"); + pr_err("modify_ehea_qp failed (3)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (4)"); + pr_err("query_ehea_qp failed (4)\n"); goto out; } @@ -2509,7 +2510,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps, EHEA_MAX_ENTRIES_EQ, 1); if (!port->qp_eq) { ret = -EINVAL; - ehea_error("ehea_create_eq failed (qp_eq)"); + pr_err("ehea_create_eq failed (qp_eq)\n"); goto out_kill_eq; } @@ -2590,27 +2591,27 @@ static int ehea_up(struct net_device *dev) ret = ehea_port_res_setup(port, port->num_def_qps, port->num_add_tx_qps); if (ret) { - ehea_error("port_res_failed"); + netdev_err(dev, "port_res_failed\n"); goto out; } /* Set default QP for this port */ ret = ehea_configure_port(port); if (ret) { - ehea_error("ehea_configure_port failed. ret:%d", ret); + netdev_err(dev, "ehea_configure_port failed. ret:%d\n", ret); goto out_clean_pr; } ret = ehea_reg_interrupts(dev); if (ret) { - ehea_error("reg_interrupts failed. ret:%d", ret); + netdev_err(dev, "reg_interrupts failed. ret:%d\n", ret); goto out_clean_pr; } for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { ret = ehea_activate_qp(port->adapter, port->port_res[i].qp); if (ret) { - ehea_error("activate_qp failed"); + netdev_err(dev, "activate_qp failed\n"); goto out_free_irqs; } } @@ -2618,7 +2619,7 @@ static int ehea_up(struct net_device *dev) for (i = 0; i < port->num_def_qps; i++) { ret = ehea_fill_port_res(&port->port_res[i]); if (ret) { - ehea_error("out_free_irqs"); + netdev_err(dev, "out_free_irqs\n"); goto out_free_irqs; } } @@ -2641,7 +2642,7 @@ out_clean_pr: ehea_clean_all_portres(port); out: if (ret) - ehea_info("Failed starting %s. ret=%i", dev->name, ret); + netdev_info(dev, "Failed starting. ret=%i\n", ret); ehea_update_bcmc_registrations(); ehea_update_firmware_handles(); @@ -2672,8 +2673,7 @@ static int ehea_open(struct net_device *dev) mutex_lock(&port->port_lock); - if (netif_msg_ifup(port)) - ehea_info("enabling port %s", dev->name); + netif_info(port, ifup, dev, "enabling port\n"); ret = ehea_up(dev); if (!ret) { @@ -2708,8 +2708,7 @@ static int ehea_down(struct net_device *dev) ret = ehea_clean_all_portres(port); if (ret) - ehea_info("Failed freeing resources for %s. ret=%i", - dev->name, ret); + netdev_info(dev, "Failed freeing resources. ret=%i\n", ret); ehea_update_firmware_handles(); @@ -2721,8 +2720,7 @@ static int ehea_stop(struct net_device *dev) int ret; struct ehea_port *port = netdev_priv(dev); - if (netif_msg_ifdown(port)) - ehea_info("disabling port %s", dev->name); + netif_info(port, ifdown, dev, "disabling port\n"); set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); cancel_work_sync(&port->reset_task); @@ -2763,7 +2761,7 @@ static void ehea_flush_sq(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - ehea_error("WARNING: sq not flushed completely"); + pr_err("WARNING: sq not flushed completely\n"); break; } } @@ -2799,7 +2797,7 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + pr_err("query_ehea_qp failed (1)\n"); goto out; } @@ -2811,7 +2809,7 @@ int ehea_stop_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + pr_err("modify_ehea_qp failed (1)\n"); goto out; } @@ -2819,14 +2817,14 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + pr_err("query_ehea_qp failed (2)\n"); goto out; } /* deregister shared memory regions */ dret = ehea_rem_smrs(pr); if (dret) { - ehea_error("unreg shared memory region failed"); + pr_err("unreg shared memory region failed\n"); goto out; } } @@ -2895,7 +2893,7 @@ int ehea_restart_qps(struct net_device *dev) ret = ehea_gen_smrs(pr); if (ret) { - ehea_error("creation of shared memory regions failed"); + netdev_err(dev, "creation of shared memory regions failed\n"); goto out; } @@ -2906,7 +2904,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + netdev_err(dev, "query_ehea_qp failed (1)\n"); goto out; } @@ -2918,7 +2916,7 @@ int ehea_restart_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + netdev_err(dev, "modify_ehea_qp failed (1)\n"); goto out; } @@ -2926,7 +2924,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + netdev_err(dev, "query_ehea_qp failed (2)\n"); goto out; } @@ -2963,8 +2961,7 @@ static void ehea_reset_port(struct work_struct *work) ehea_set_multicast_list(dev); - if (netif_msg_timer(port)) - ehea_info("Device %s resetted successfully", dev->name); + netif_info(port, timer, dev, "reset successful\n"); port_napi_enable(port); @@ -2979,7 +2976,7 @@ static void ehea_rereg_mrs(struct work_struct *work) int ret, i; struct ehea_adapter *adapter; - ehea_info("LPAR memory changed - re-initializing driver"); + pr_info("LPAR memory changed - re-initializing driver\n"); list_for_each_entry(adapter, &adapter_list, list) if (adapter->active_ports) { @@ -3011,8 +3008,7 @@ static void ehea_rereg_mrs(struct work_struct *work) /* Unregister old memory region */ ret = ehea_rem_mr(&adapter->mr); if (ret) { - ehea_error("unregister MR failed - driver" - " inoperable!"); + pr_err("unregister MR failed - driver inoperable!\n"); goto out; } } @@ -3024,8 +3020,7 @@ static void ehea_rereg_mrs(struct work_struct *work) /* Register new memory region */ ret = ehea_reg_kernel_mr(adapter, &adapter->mr); if (ret) { - ehea_error("register MR failed - driver" - " inoperable!"); + pr_err("register MR failed - driver inoperable!\n"); goto out; } @@ -3048,7 +3043,7 @@ static void ehea_rereg_mrs(struct work_struct *work) } } } - ehea_info("re-initializing driver complete"); + pr_info("re-initializing driver complete\n"); out: return; } @@ -3101,7 +3096,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo) /* (Try to) enable *jumbo frames */ cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - ehea_error("no mem for cb4"); + pr_err("no mem for cb4\n"); ret = -ENOMEM; goto out; } else { @@ -3163,13 +3158,13 @@ static struct device *ehea_register_port(struct ehea_port *port, ret = of_device_register(&port->ofdev); if (ret) { - ehea_error("failed to register device. ret=%d", ret); + pr_err("failed to register device. ret=%d\n", ret); goto out; } ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); if (ret) { - ehea_error("failed to register attributes, ret=%d", ret); + pr_err("failed to register attributes, ret=%d\n", ret); goto out_unreg_of_dev; } @@ -3219,7 +3214,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev = alloc_etherdev(sizeof(struct ehea_port)); if (!dev) { - ehea_error("no mem for net_device"); + pr_err("no mem for net_device\n"); ret = -ENOMEM; goto out_err; } @@ -3270,7 +3265,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = register_netdev(dev); if (ret) { - ehea_error("register_netdev failed. ret=%d", ret); + pr_err("register_netdev failed. ret=%d\n", ret); goto out_unreg_port; } @@ -3278,11 +3273,10 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = ehea_get_jumboframe_status(port, &jumbo); if (ret) - ehea_error("failed determining jumbo frame status for %s", - port->netdev->name); + netdev_err(dev, "failed determining jumbo frame status\n"); - ehea_info("%s: Jumbo frames are %sabled", dev->name, - jumbo == 1 ? "en" : "dis"); + netdev_info(dev, "Jumbo frames are %sabled\n", + jumbo == 1 ? "en" : "dis"); adapter->active_ports++; @@ -3298,8 +3292,8 @@ out_free_ethdev: free_netdev(dev); out_err: - ehea_error("setting up logical port with id=%d failed, ret=%d", - logical_port_id, ret); + pr_err("setting up logical port with id=%d failed, ret=%d\n", + logical_port_id, ret); return NULL; } @@ -3327,13 +3321,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", NULL); if (!dn_log_port_id) { - ehea_error("bad device node: eth_dn name=%s", - eth_dn->full_name); + pr_err("bad device node: eth_dn name=%s\n", + eth_dn->full_name); continue; } if (ehea_add_adapter_mr(adapter)) { - ehea_error("creating MR failed"); + pr_err("creating MR failed\n"); of_node_put(eth_dn); return -EIO; } @@ -3342,9 +3336,8 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) *dn_log_port_id, eth_dn); if (adapter->port[i]) - ehea_info("%s -> logical port id #%d", - adapter->port[i]->netdev->name, - *dn_log_port_id); + netdev_info(adapter->port[i]->netdev, + "logical port id #%d\n", *dn_log_port_id); else ehea_remove_adapter_mr(adapter); @@ -3389,21 +3382,20 @@ static ssize_t ehea_probe_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - ehea_info("adding port with logical port id=%d failed. port " - "already configured as %s.", logical_port_id, - port->netdev->name); + netdev_info(port->netdev, "adding port with logical port id=%d failed: port already configured\n", + logical_port_id); return -EINVAL; } eth_dn = ehea_get_eth_dn(adapter, logical_port_id); if (!eth_dn) { - ehea_info("no logical port with id %d found", logical_port_id); + pr_info("no logical port with id %d found\n", logical_port_id); return -EINVAL; } if (ehea_add_adapter_mr(adapter)) { - ehea_error("creating MR failed"); + pr_err("creating MR failed\n"); return -EIO; } @@ -3418,8 +3410,8 @@ static ssize_t ehea_probe_port(struct device *dev, break; } - ehea_info("added %s (logical port id=%d)", port->netdev->name, - logical_port_id); + netdev_info(port->netdev, "added: (logical port id=%d)\n", + logical_port_id); } else { ehea_remove_adapter_mr(adapter); return -EIO; @@ -3442,8 +3434,8 @@ static ssize_t ehea_remove_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - ehea_info("removed %s (logical port id=%d)", port->netdev->name, - logical_port_id); + netdev_info(port->netdev, "removed: (logical port id=%d)\n", + logical_port_id); ehea_shutdown_single_port(port); @@ -3453,8 +3445,8 @@ static ssize_t ehea_remove_port(struct device *dev, break; } } else { - ehea_error("removing port with logical port id=%d failed. port " - "not configured.", logical_port_id); + pr_err("removing port with logical port id=%d failed. port not configured.\n", + logical_port_id); return -EINVAL; } @@ -3491,7 +3483,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, int ret; if (!dev || !dev->dev.of_node) { - ehea_error("Invalid ibmebus device probed"); + pr_err("Invalid ibmebus device probed\n"); return -EINVAL; } @@ -3639,17 +3631,17 @@ static int ehea_mem_notifier(struct notifier_block *nb, switch (action) { case MEM_CANCEL_OFFLINE: - ehea_info("memory offlining canceled"); + pr_info("memory offlining canceled\n"); /* Readd canceled memory block */ case MEM_ONLINE: - ehea_info("memory is going online"); + pr_info("memory is going online\n"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; ehea_rereg_mrs(NULL); break; case MEM_GOING_OFFLINE: - ehea_info("memory is going offline"); + pr_info("memory is going offline\n"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; @@ -3675,7 +3667,7 @@ static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { if (action == SYS_RESTART) { - ehea_info("Reboot: freeing all eHEA resources"); + pr_info("Reboot: freeing all eHEA resources\n"); ibmebus_unregister_driver(&ehea_driver); } return NOTIFY_DONE; @@ -3691,22 +3683,22 @@ static int check_module_parm(void) if ((rq1_entries < EHEA_MIN_ENTRIES_QP) || (rq1_entries > EHEA_MAX_ENTRIES_RQ1)) { - ehea_info("Bad parameter: rq1_entries"); + pr_info("Bad parameter: rq1_entries\n"); ret = -EINVAL; } if ((rq2_entries < EHEA_MIN_ENTRIES_QP) || (rq2_entries > EHEA_MAX_ENTRIES_RQ2)) { - ehea_info("Bad parameter: rq2_entries"); + pr_info("Bad parameter: rq2_entries\n"); ret = -EINVAL; } if ((rq3_entries < EHEA_MIN_ENTRIES_QP) || (rq3_entries > EHEA_MAX_ENTRIES_RQ3)) { - ehea_info("Bad parameter: rq3_entries"); + pr_info("Bad parameter: rq3_entries\n"); ret = -EINVAL; } if ((sq_entries < EHEA_MIN_ENTRIES_QP) || (sq_entries > EHEA_MAX_ENTRIES_SQ)) { - ehea_info("Bad parameter: sq_entries"); + pr_info("Bad parameter: sq_entries\n"); ret = -EINVAL; } @@ -3726,8 +3718,7 @@ int __init ehea_module_init(void) { int ret; - printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", - DRV_VERSION); + pr_info("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION); INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); @@ -3747,27 +3738,27 @@ int __init ehea_module_init(void) ret = register_reboot_notifier(&ehea_reboot_nb); if (ret) - ehea_info("failed registering reboot notifier"); + pr_info("failed registering reboot notifier\n"); ret = register_memory_notifier(&ehea_mem_nb); if (ret) - ehea_info("failed registering memory remove notifier"); + pr_info("failed registering memory remove notifier\n"); ret = crash_shutdown_register(ehea_crash_handler); if (ret) - ehea_info("failed registering crash handler"); + pr_info("failed registering crash handler\n"); ret = ibmebus_register_driver(&ehea_driver); if (ret) { - ehea_error("failed registering eHEA device driver on ebus"); + pr_err("failed registering eHEA device driver on ebus\n"); goto out2; } ret = driver_create_file(&ehea_driver.driver, &driver_attr_capabilities); if (ret) { - ehea_error("failed to register capabilities attribute, ret=%d", - ret); + pr_err("failed to register capabilities attribute, ret=%d\n", + ret); goto out3; } @@ -3793,7 +3784,7 @@ static void __exit ehea_module_exit(void) unregister_reboot_notifier(&ehea_reboot_nb); ret = crash_shutdown_unregister(ehea_crash_handler); if (ret) - ehea_info("failed unregistering crash handler"); + pr_info("failed unregistering crash handler\n"); unregister_memory_notifier(&ehea_mem_nb); kfree(ehea_fw_handles.arr); kfree(ehea_bcmc_regs.arr); diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 8fe9dcaa7538..0506967b9044 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ehea_phyp.h" @@ -67,12 +69,11 @@ static long ehea_plpar_hcall_norets(unsigned long opcode, } if (ret < H_SUCCESS) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx ", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7); + pr_err("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx\n", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, arg6, arg7); return ret; } @@ -114,19 +115,18 @@ static long ehea_plpar_hcall9(unsigned long opcode, && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) && (arg3 == H_PORT_CB7_DUCQPN))))) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" - " arg9=%lx" - " out1=%lx out2=%lx out3=%lx out4=%lx" - " out5=%lx out6=%lx out7=%lx out8=%lx" - " out9=%lx", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9, - outs[0], outs[1], outs[2], outs[3], - outs[4], outs[5], outs[6], outs[7], - outs[8]); + pr_err("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" + " arg9=%lx" + " out1=%lx out2=%lx out3=%lx out4=%lx" + " out5=%lx out6=%lx out7=%lx out8=%lx" + " out9=%lx\n", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, + outs[0], outs[1], outs[2], outs[3], outs[4], + outs[5], outs[6], outs[7], outs[8]); return ret; } @@ -515,7 +515,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, const u64 log_pageaddr, const u64 count) { if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { - ehea_error("not on pageboundary"); + pr_err("not on pageboundary\n"); return H_PARAMETER; } diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 89128b6373e3..cd44bb8017d9 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "ehea.h" @@ -45,7 +47,7 @@ static void *hw_qpageit_get_inc(struct hw_queue *queue) queue->current_q_offset -= queue->pagesize; retvalue = NULL; } else if (((u64) retvalue) & (EHEA_PAGESIZE-1)) { - ehea_error("not on pageboundary"); + pr_err("not on pageboundary\n"); retvalue = NULL; } return retvalue; @@ -58,15 +60,15 @@ static int hw_queue_ctor(struct hw_queue *queue, const u32 nr_of_pages, int i, k; if ((pagesize > PAGE_SIZE) || (!pages_per_kpage)) { - ehea_error("pagesize conflict! kernel pagesize=%d, " - "ehea pagesize=%d", (int)PAGE_SIZE, (int)pagesize); + pr_err("pagesize conflict! kernel pagesize=%d, ehea pagesize=%d\n", + (int)PAGE_SIZE, (int)pagesize); return -EINVAL; } queue->queue_length = nr_of_pages * pagesize; queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL); if (!queue->queue_pages) { - ehea_error("no mem for queue_pages"); + pr_err("no mem for queue_pages\n"); return -ENOMEM; } @@ -130,7 +132,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq = kzalloc(sizeof(*cq), GFP_KERNEL); if (!cq) { - ehea_error("no mem for cq"); + pr_err("no mem for cq\n"); goto out_nomem; } @@ -147,7 +149,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_cq(adapter->handle, &cq->attr, &cq->fw_handle, &cq->epas); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_cq failed"); + pr_err("alloc_resource_cq failed\n"); goto out_freemem; } @@ -159,7 +161,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, for (counter = 0; counter < cq->attr.nr_pages; counter++) { vpage = hw_qpageit_get_inc(&cq->hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); goto out_kill_hwq; } @@ -168,9 +170,8 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, 0, EHEA_CQ_REGISTER_ORIG, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - ehea_error("register_rpage_cq failed ehea_cq=%p " - "hret=%llx counter=%i act_pages=%i", - cq, hret, counter, cq->attr.nr_pages); + pr_err("register_rpage_cq failed ehea_cq=%p hret=%llx counter=%i act_pages=%i\n", + cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -178,14 +179,14 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, vpage = hw_qpageit_get_inc(&cq->hw_queue); if ((hret != H_SUCCESS) || (vpage)) { - ehea_error("registration of pages not " - "complete hret=%llx\n", hret); + pr_err("registration of pages not complete hret=%llx\n", + hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { - ehea_error("CQ: registration of page failed " - "hret=%llx\n", hret); + pr_err("CQ: registration of page failed hret=%llx\n", + hret); goto out_kill_hwq; } } @@ -241,7 +242,7 @@ int ehea_destroy_cq(struct ehea_cq *cq) } if (hret != H_SUCCESS) { - ehea_error("destroy CQ failed"); + pr_err("destroy CQ failed\n"); return -EIO; } @@ -259,7 +260,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, eq = kzalloc(sizeof(*eq), GFP_KERNEL); if (!eq) { - ehea_error("no mem for eq"); + pr_err("no mem for eq\n"); return NULL; } @@ -272,21 +273,21 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_eq(adapter->handle, &eq->attr, &eq->fw_handle); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_eq failed"); + pr_err("alloc_resource_eq failed\n"); goto out_freemem; } ret = hw_queue_ctor(&eq->hw_queue, eq->attr.nr_pages, EHEA_PAGESIZE, sizeof(struct ehea_eqe)); if (ret) { - ehea_error("can't allocate eq pages"); + pr_err("can't allocate eq pages\n"); goto out_freeres; } for (i = 0; i < eq->attr.nr_pages; i++) { vpage = hw_qpageit_get_inc(&eq->hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); hret = H_RESOURCE; goto out_kill_hwq; } @@ -370,7 +371,7 @@ int ehea_destroy_eq(struct ehea_eq *eq) } if (hret != H_SUCCESS) { - ehea_error("destroy EQ failed"); + pr_err("destroy EQ failed\n"); return -EIO; } @@ -395,7 +396,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, for (cnt = 0; cnt < nr_pages; cnt++) { vpage = hw_qpageit_get_inc(hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); goto out_kill_hwq; } rpage = virt_to_abs(vpage); @@ -403,7 +404,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, 0, h_call_q_selector, qp->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - ehea_error("register_rpage_qp failed"); + pr_err("register_rpage_qp failed\n"); goto out_kill_hwq; } } @@ -432,7 +433,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, qp = kzalloc(sizeof(*qp), GFP_KERNEL); if (!qp) { - ehea_error("no mem for qp"); + pr_err("no mem for qp\n"); return NULL; } @@ -441,7 +442,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_qp(adapter->handle, init_attr, pd, &qp->fw_handle, &qp->epas); if (hret != H_SUCCESS) { - ehea_error("ehea_h_alloc_resource_qp failed"); + pr_err("ehea_h_alloc_resource_qp failed\n"); goto out_freemem; } @@ -455,7 +456,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_sq, adapter, 0); if (ret) { - ehea_error("can't register for sq ret=%x", ret); + pr_err("can't register for sq ret=%x\n", ret); goto out_freeres; } @@ -465,7 +466,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq1, adapter, 1); if (ret) { - ehea_error("can't register for rq1 ret=%x", ret); + pr_err("can't register for rq1 ret=%x\n", ret); goto out_kill_hwsq; } @@ -476,7 +477,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq2, adapter, 2); if (ret) { - ehea_error("can't register for rq2 ret=%x", ret); + pr_err("can't register for rq2 ret=%x\n", ret); goto out_kill_hwr1q; } } @@ -488,7 +489,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq3, adapter, 3); if (ret) { - ehea_error("can't register for rq3 ret=%x", ret); + pr_err("can't register for rq3 ret=%x\n", ret); goto out_kill_hwr2q; } } @@ -553,7 +554,7 @@ int ehea_destroy_qp(struct ehea_qp *qp) } if (hret != H_SUCCESS) { - ehea_error("destroy QP failed"); + pr_err("destroy QP failed\n"); return -EIO; } @@ -842,7 +843,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, (hret != H_PAGE_REGISTERED)) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("register_rpage_mr failed"); + pr_err("register_rpage_mr failed\n"); return hret; } } @@ -896,7 +897,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) pt = (void *)get_zeroed_page(GFP_KERNEL); if (!pt) { - ehea_error("no mem"); + pr_err("no mem\n"); ret = -ENOMEM; goto out; } @@ -906,14 +907,14 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) &mr->handle, &mr->lkey); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_mr failed"); + pr_err("alloc_resource_mr failed\n"); ret = -EIO; goto out; } if (!ehea_bmap) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("no busmap available"); + pr_err("no busmap available\n"); ret = -EIO; goto out; } @@ -929,7 +930,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) if (hret != H_SUCCESS) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("registering mr failed"); + pr_err("registering mr failed\n"); ret = -EIO; goto out; } @@ -952,7 +953,7 @@ int ehea_rem_mr(struct ehea_mr *mr) hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, FORCE_FREE); if (hret != H_SUCCESS) { - ehea_error("destroy MR failed"); + pr_err("destroy MR failed\n"); return -EIO; } @@ -987,14 +988,14 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == EHEA_AER_RESTYPE_QP) - ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " - "port=%llX", resource, data[6], data[12], data[22]); + pr_err("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, port=%llX\n", + resource, data[6], data[12], data[22]); else if (type == EHEA_AER_RESTYPE_CQ) - ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, - data[6]); + pr_err("CQ (resource=%llX) state: AER=0x%llX\n", + resource, data[6]); else if (type == EHEA_AER_RESTYPE_EQ) - ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, - data[6]); + pr_err("EQ (resource=%llX) state: AER=0x%llX\n", + resource, data[6]); ehea_dump(data, length, "error data"); } @@ -1008,7 +1009,7 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, rblock = (void *)get_zeroed_page(GFP_KERNEL); if (!rblock) { - ehea_error("Cannot allocate rblock memory."); + pr_err("Cannot allocate rblock memory\n"); goto out; } @@ -1020,9 +1021,9 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, *aerr = rblock[12]; print_error_data(rblock); } else if (ret == H_R_STATE) { - ehea_error("No error data available: %llX.", res_handle); + pr_err("No error data available: %llX\n", res_handle); } else - ehea_error("Error data could not be fetched: %llX", res_handle); + pr_err("Error data could not be fetched: %llX\n", res_handle); free_page((unsigned long)rblock); out: -- cgit v1.2.3-59-g8ed1b From da2033c282264bfba4e339b7cb3df62adb5c5fc8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 30 Nov 2010 21:45:56 +0000 Subject: filter: add SKF_AD_RXHASH and SKF_AD_CPU Add SKF_AD_RXHASH and SKF_AD_CPU to filter ancillary mechanism, to be able to build advanced filters. This can help spreading packets on several sockets with a fast selection, after RPS dispatch to N cpus for example, or to catch a percentage of flows in one queue. tcpdump -s 500 "cpu = 1" : [0] ld CPU [1] jeq #1 jt 2 jf 3 [2] ret #500 [3] ret #0 # take 12.5 % of flows (average) tcpdump -s 1000 "rxhash & 7 = 2" : [0] ld RXHASH [1] and #7 [2] jeq #2 jt 3 jf 4 [3] ret #1000 [4] ret #0 Signed-off-by: Eric Dumazet Cc: Rui Acked-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/filter.h | 4 +++- net/core/filter.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 447a775878fb..5334adaf4072 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -124,7 +124,9 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #define SKF_AD_MARK 20 #define SKF_AD_QUEUE 24 #define SKF_AD_HATYPE 28 -#define SKF_AD_MAX 32 +#define SKF_AD_RXHASH 32 +#define SKF_AD_CPU 36 +#define SKF_AD_MAX 40 #define SKF_NET_OFF (-0x100000) #define SKF_LL_OFF (-0x200000) diff --git a/net/core/filter.c b/net/core/filter.c index a44d27f9f0f0..054e286861d2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -375,6 +375,12 @@ load_b: return 0; A = skb->dev->type; continue; + case SKF_AD_RXHASH: + A = skb->rxhash; + continue; + case SKF_AD_CPU: + A = raw_smp_processor_id(); + continue; case SKF_AD_NLATTR: { struct nlattr *nla; -- cgit v1.2.3-59-g8ed1b From 06a9701f4b3e3381dea96fee1cc8a3bb41b0a1f1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 1 Dec 2010 01:37:42 +0000 Subject: __in_dev_get_rtnl() can use rtnl_dereference() If caller holds RTNL, we dont need a memory barrier (smp_read_barrier_depends) included in rcu_dereference(). Just use rtnl_dereference() to properly document the assertions. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 2b86eaf11773..ae8fdc54e0c0 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -222,7 +222,7 @@ static inline struct in_device *in_dev_get(const struct net_device *dev) static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev) { - return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held()); + return rtnl_dereference(dev->ip_ptr); } extern void in_dev_finish_destroy(struct in_device *idev); -- cgit v1.2.3-59-g8ed1b From f7fce74e387e0563e5a165704664aa5ee8b2f48b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 1 Dec 2010 06:03:06 +0000 Subject: net: kill an RCU warning in inet_fill_link_af() commits 9f0f7272 (ipv4: AF_INET link address family) and cf7afbfeb8c (rtnl: make link af-specific updates atomic) used incorrect __in_dev_get_rcu() in RTNL protected contexts, triggering PROVE_RCU warnings. Switch to __in_dev_get_rtnl(), wich is more appropriate, since we hold RTNL. Based on a report and initial patch from Amerigo Wang. Reported-by: Amerigo Wang Signed-off-by: Eric Dumazet Cc: Thomas Graf Reviewed-by: WANG Cong Signed-off-by: David S. Miller --- net/ipv4/devinet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index d9f71bae45c4..3b067704ab38 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1258,7 +1258,7 @@ errout: static size_t inet_get_link_af_size(const struct net_device *dev) { - struct in_device *in_dev = __in_dev_get_rcu(dev); + struct in_device *in_dev = __in_dev_get_rtnl(dev); if (!in_dev) return 0; @@ -1268,7 +1268,7 @@ static size_t inet_get_link_af_size(const struct net_device *dev) static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev) { - struct in_device *in_dev = __in_dev_get_rcu(dev); + struct in_device *in_dev = __in_dev_get_rtnl(dev); struct nlattr *nla; int i; @@ -1295,7 +1295,7 @@ static int inet_validate_link_af(const struct net_device *dev, struct nlattr *a, *tb[IFLA_INET_MAX+1]; int err, rem; - if (dev && !__in_dev_get_rcu(dev)) + if (dev && !__in_dev_get_rtnl(dev)) return -EAFNOSUPPORT; err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy); @@ -1319,7 +1319,7 @@ static int inet_validate_link_af(const struct net_device *dev, static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) { - struct in_device *in_dev = __in_dev_get_rcu(dev); + struct in_device *in_dev = __in_dev_get_rtnl(dev); struct nlattr *a, *tb[IFLA_INET_MAX+1]; int rem; -- cgit v1.2.3-59-g8ed1b From 0af55bb58f8fa7865004ac48d16affe125ac1b7f Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 1 Dec 2010 02:52:20 +0000 Subject: af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc() The following commit causes the pgv->buffer may point to the memory returned by vmalloc(). And we can't use virt_to_page() for the vmalloc address. This patch introduces a new inline function pgv_to_page(), which calls vmalloc_to_page() for the vmalloc address, and virt_to_page() for the __get_free_pages address. We used to increase page pointer to get the next page at the next page address, after Neil's patch, it is wrong, as the physical address may be not continuous. This patch also fixes this issue. commit 0e3125c755445664f00ad036e4fc2cd32fd52877 Author: Neil Horman Date: Tue Nov 16 10:26:47 2010 -0800 packet: Enhance AF_PACKET implementation to not require high order contiguous memory allocation (v4) Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/packet/af_packet.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 422705d62b5b..26fbeb140a6a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -224,6 +224,13 @@ struct packet_skb_cb { #define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) +static inline struct page *pgv_to_page(void *addr) +{ + if (is_vmalloc_addr(addr)) + return vmalloc_to_page(addr); + return virt_to_page(addr); +} + static void __packet_set_status(struct packet_sock *po, void *frame, int status) { union { @@ -236,11 +243,11 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status) switch (po->tp_version) { case TPACKET_V1: h.h1->tp_status = status; - flush_dcache_page(virt_to_page(&h.h1->tp_status)); + flush_dcache_page(pgv_to_page(&h.h1->tp_status)); break; case TPACKET_V2: h.h2->tp_status = status; - flush_dcache_page(virt_to_page(&h.h2->tp_status)); + flush_dcache_page(pgv_to_page(&h.h2->tp_status)); break; default: pr_err("TPACKET version not supported\n"); @@ -263,10 +270,10 @@ static int __packet_get_status(struct packet_sock *po, void *frame) h.raw = frame; switch (po->tp_version) { case TPACKET_V1: - flush_dcache_page(virt_to_page(&h.h1->tp_status)); + flush_dcache_page(pgv_to_page(&h.h1->tp_status)); return h.h1->tp_status; case TPACKET_V2: - flush_dcache_page(virt_to_page(&h.h2->tp_status)); + flush_dcache_page(pgv_to_page(&h.h2->tp_status)); return h.h2->tp_status; default: pr_err("TPACKET version not supported\n"); @@ -800,15 +807,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, __packet_set_status(po, h.raw, status); smp_mb(); { - struct page *p_start, *p_end; - u8 *h_end = h.raw + macoff + snaplen - 1; - - p_start = virt_to_page(h.raw); - p_end = virt_to_page(h_end); - while (p_start <= p_end) { - flush_dcache_page(p_start); - p_start++; - } + u8 *start, *end; + + end = (u8 *)PAGE_ALIGN((unsigned long)h.raw + macoff + snaplen); + for (start = h.raw; start < end; start += PAGE_SIZE) + flush_dcache_page(pgv_to_page(start)); } sk->sk_data_ready(sk, 0); @@ -915,7 +918,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, } err = -EFAULT; - page = virt_to_page(data); offset = offset_in_page(data); len_max = PAGE_SIZE - offset; len = ((to_write > len_max) ? len_max : to_write); @@ -934,11 +936,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, return -EFAULT; } + page = pgv_to_page(data); + data += len; flush_dcache_page(page); get_page(page); - skb_fill_page_desc(skb, - nr_frags, - page++, offset, len); + skb_fill_page_desc(skb, nr_frags, page, offset, len); to_write -= len; offset = 0; len_max = PAGE_SIZE; -- cgit v1.2.3-59-g8ed1b From c56b4d90123b77e29a91b9b96bb791f929139d8e Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 1 Dec 2010 02:52:57 +0000 Subject: af_packet: remove pgv.flags As we can check if an address is vmalloc address with is_vmalloc_addr(), we remove pgv.flags. Then we may get more pg_vecs. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/packet/af_packet.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 26fbeb140a6a..a11c731d2ee4 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -167,7 +167,6 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, #define PGV_FROM_VMALLOC 1 struct pgv { char *buffer; - unsigned char flags; }; struct packet_ring_buffer { @@ -2342,7 +2341,7 @@ static void free_pg_vec(struct pgv *pg_vec, unsigned int order, for (i = 0; i < len; i++) { if (likely(pg_vec[i].buffer)) { - if (pg_vec[i].flags & PGV_FROM_VMALLOC) + if (is_vmalloc_addr(pg_vec[i].buffer)) vfree(pg_vec[i].buffer); else free_pages((unsigned long)pg_vec[i].buffer, @@ -2353,8 +2352,7 @@ static void free_pg_vec(struct pgv *pg_vec, unsigned int order, kfree(pg_vec); } -static inline char *alloc_one_pg_vec_page(unsigned long order, - unsigned char *flags) +static inline char *alloc_one_pg_vec_page(unsigned long order) { char *buffer = NULL; gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | @@ -2368,7 +2366,6 @@ static inline char *alloc_one_pg_vec_page(unsigned long order, /* * __get_free_pages failed, fall back to vmalloc */ - *flags |= PGV_FROM_VMALLOC; buffer = vzalloc((1 << order) * PAGE_SIZE); if (buffer) @@ -2377,7 +2374,6 @@ static inline char *alloc_one_pg_vec_page(unsigned long order, /* * vmalloc failed, lets dig into swap here */ - *flags = 0; gfp_flags &= ~__GFP_NORETRY; buffer = (char *)__get_free_pages(gfp_flags, order); if (buffer) @@ -2400,8 +2396,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) goto out; for (i = 0; i < block_nr; i++) { - pg_vec[i].buffer = alloc_one_pg_vec_page(order, - &pg_vec[i].flags); + pg_vec[i].buffer = alloc_one_pg_vec_page(order); if (unlikely(!pg_vec[i].buffer)) goto out_free_pgvec; } @@ -2585,13 +2580,8 @@ static int packet_mmap(struct file *file, struct socket *sock, void *kaddr = rb->pg_vec[i].buffer; int pg_num; - for (pg_num = 0; pg_num < rb->pg_vec_pages; - pg_num++) { - if (rb->pg_vec[i].flags & PGV_FROM_VMALLOC) - page = vmalloc_to_page(kaddr); - else - page = virt_to_page(kaddr); - + for (pg_num = 0; pg_num < rb->pg_vec_pages; pg_num++) { + page = pgv_to_page(kaddr); err = vm_insert_page(vma, start, page); if (unlikely(err)) goto out; -- cgit v1.2.3-59-g8ed1b From 63657b9c319588cd35ed869e19cc6255dbef0d20 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 1 Dec 2010 01:02:28 +0000 Subject: be2net: Fix be_dev_family_check() return value check Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 275428032ce2..ea8cf690a072 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2901,7 +2901,7 @@ static int __devinit be_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, adapter); status = be_dev_family_check(adapter); - if (!status) + if (status) goto free_netdev; adapter->netdev = netdev; -- cgit v1.2.3-59-g8ed1b From 359a972fae84242efa26b86bf09c3ac3784405ba Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 1 Dec 2010 01:03:36 +0000 Subject: be2net: FW init cmd fix for lancer Lancer can use the same pattern as BE to indicate a driver load to the FW. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 3865b2bc65e6..31c5ddc08fc8 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -470,25 +470,14 @@ int be_cmd_fw_init(struct be_adapter *adapter) spin_lock(&adapter->mbox_lock); wrb = (u8 *)wrb_from_mbox(adapter); - if (lancer_chip(adapter)) { - *wrb++ = 0xFF; - *wrb++ = 0x34; - *wrb++ = 0x12; - *wrb++ = 0xFF; - *wrb++ = 0xFF; - *wrb++ = 0x78; - *wrb++ = 0x56; - *wrb = 0xFF; - } else { - *wrb++ = 0xFF; - *wrb++ = 0x12; - *wrb++ = 0x34; - *wrb++ = 0xFF; - *wrb++ = 0xFF; - *wrb++ = 0x56; - *wrb++ = 0x78; - *wrb = 0xFF; - } + *wrb++ = 0xFF; + *wrb++ = 0x12; + *wrb++ = 0x34; + *wrb++ = 0xFF; + *wrb++ = 0xFF; + *wrb++ = 0x56; + *wrb++ = 0x78; + *wrb = 0xFF; status = be_mbox_notify_wait(adapter); -- cgit v1.2.3-59-g8ed1b From 6464281161e46254ac39505ad41d21dbe7d1738f Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 1 Dec 2010 01:04:17 +0000 Subject: be2net: Handle out of buffer completions for lancer If Lancer chip does not have posted RX buffers, it posts an RX completion entry with the same frag_index as the last valid completion. The Error bit is also set. In BE, a flush completion is indicated with a zero value for num_rcvd in the completion. Such completions don't carry any data and are not processed. This patch refactors code to handle both cases with the same code. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 4 +++- drivers/net/benet/be_main.c | 55 ++++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index b61a1dfebcaf..9cab32328bba 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -220,7 +220,9 @@ struct be_rx_obj { struct be_rx_stats stats; u8 rss_id; bool rx_post_starved; /* Zero rx frags have been posted to BE */ - u32 cache_line_barrier[16]; + u16 last_frag_index; + u16 rsvd; + u32 cache_line_barrier[15]; }; struct be_vf_cfg { diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ea8cf690a072..0b35e4a8bf19 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -911,11 +911,17 @@ static void be_rx_compl_discard(struct be_adapter *adapter, rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxo, rxq_idx); - put_page(page_info->page); - memset(page_info, 0, sizeof(*page_info)); - index_inc(&rxq_idx, rxq->len); + /* Skip out-of-buffer compl(lancer) or flush compl(BE) */ + if (likely(rxq_idx != rxo->last_frag_index && num_rcvd != 0)) { + + rxo->last_frag_index = rxq_idx; + + for (i = 0; i < num_rcvd; i++) { + page_info = get_rx_page_info(adapter, rxo, rxq_idx); + put_page(page_info->page); + memset(page_info, 0, sizeof(*page_info)); + index_inc(&rxq_idx, rxq->len); + } } } @@ -1016,9 +1022,6 @@ static void be_rx_compl_process(struct be_adapter *adapter, u8 vtm; num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - /* Is it a flush compl that has no data */ - if (unlikely(num_rcvd == 0)) - return; skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); if (unlikely(!skb)) { @@ -1075,10 +1078,6 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, u8 pkt_type; num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - /* Is it a flush compl that has no data */ - if (unlikely(num_rcvd == 0)) - return; - pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); @@ -1349,7 +1348,7 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) while ((rxcp = be_rx_compl_get(rxo)) != NULL) { be_rx_compl_discard(adapter, rxo, rxcp); be_rx_compl_reset(rxcp); - be_cq_notify(adapter, rx_cq->id, true, 1); + be_cq_notify(adapter, rx_cq->id, false, 1); } /* Then free posted rx buffer that were not used */ @@ -1576,6 +1575,9 @@ static int be_rx_queues_create(struct be_adapter *adapter) adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { rxo->adapter = adapter; + /* Init last_frag_index so that the frag index in the first + * completion will never match */ + rxo->last_frag_index = 0xffff; rxo->rx_eq.max_eqd = BE_MAX_EQD; rxo->rx_eq.enable_aic = true; @@ -1697,10 +1699,9 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) return IRQ_HANDLED; } -static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo, - struct be_eth_rx_compl *rxcp) +static inline bool do_gro(struct be_rx_obj *rxo, + struct be_eth_rx_compl *rxcp, u8 err) { - int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); if (err) @@ -1717,6 +1718,8 @@ static int be_poll_rx(struct napi_struct *napi, int budget) struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u32 work_done; + u16 frag_index, num_rcvd; + u8 err; rxo->stats.rx_polls++; for (work_done = 0; work_done < budget; work_done++) { @@ -1724,10 +1727,22 @@ static int be_poll_rx(struct napi_struct *napi, int budget) if (!rxcp) break; - if (do_gro(adapter, rxo, rxcp)) - be_rx_compl_process_gro(adapter, rxo, rxcp); - else - be_rx_compl_process(adapter, rxo, rxcp); + err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); + frag_index = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, + rxcp); + num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, + rxcp); + + /* Skip out-of-buffer compl(lancer) or flush compl(BE) */ + if (likely(frag_index != rxo->last_frag_index && + num_rcvd != 0)) { + rxo->last_frag_index = frag_index; + + if (do_gro(rxo, rxcp, err)) + be_rx_compl_process_gro(adapter, rxo, rxcp); + else + be_rx_compl_process(adapter, rxo, rxcp); + } be_rx_compl_reset(rxcp); } -- cgit v1.2.3-59-g8ed1b From ae9c416d686db74f67d73c1bebf1e3a7e8b3c5b5 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 1 Dec 2010 20:07:31 +0000 Subject: net: arp: use assignment Only when dont_send is 0, arp_filter() is consulted, so we can simply assign the return value of arp_filter() to dont_send instead. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/ipv4/arp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7833f17b648a..10af759f2630 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -883,7 +883,7 @@ static int arp_process(struct sk_buff *skb) dont_send = arp_ignore(in_dev, sip, tip); if (!dont_send && IN_DEV_ARPFILTER(in_dev)) - dont_send |= arp_filter(sip, tip, dev); + dont_send = arp_filter(sip, tip, dev); if (!dont_send) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { -- cgit v1.2.3-59-g8ed1b From 2d5311e4e8272fd398fc1cf278f12fd6dee4074b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 1 Dec 2010 20:46:24 +0000 Subject: filter: add a security check at install time We added some security checks in commit 57fe93b374a6 (filter: make sure filters dont read uninitialized memory) to close a potential leak of kernel information to user. This added a potential extra cost at run time, while we can perform a check of the filter itself, to make sure a malicious user doesnt try to abuse us. This patch adds a check_loads() function, whole unique purpose is to make this check, allocating a temporary array of mask. We scan the filter and propagate a bitmask information, telling us if a load M(K) is allowed because a previous store M(K) is guaranteed. (So that sk_run_filter() can possibly not read unitialized memory) Note: this can uncover application bug, denying a filter attach, previously allowed. Signed-off-by: Eric Dumazet Cc: Dan Rosenberg Cc: Changli Gao Acked-by: Changli Gao Signed-off-by: David S. Miller --- net/core/filter.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 054e286861d2..ac4920a87be5 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -166,11 +166,9 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry u32 A = 0; /* Accumulator */ u32 X = 0; /* Index Register */ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ - unsigned long memvalid = 0; u32 tmp; int k; - BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG); /* * Process array of filter instructions. */ @@ -318,12 +316,10 @@ load_b: X = K; continue; case BPF_S_LD_MEM: - A = (memvalid & (1UL << K)) ? - mem[K] : 0; + A = mem[K]; continue; case BPF_S_LDX_MEM: - X = (memvalid & (1UL << K)) ? - mem[K] : 0; + X = mem[K]; continue; case BPF_S_MISC_TAX: X = A; @@ -336,11 +332,9 @@ load_b: case BPF_S_RET_A: return A; case BPF_S_ST: - memvalid |= 1UL << K; mem[K] = A; continue; case BPF_S_STX: - memvalid |= 1UL << K; mem[K] = X; continue; default: @@ -425,6 +419,66 @@ load_b: } EXPORT_SYMBOL(sk_run_filter); +/* + * Security : + * A BPF program is able to use 16 cells of memory to store intermediate + * values (check u32 mem[BPF_MEMWORDS] in sk_run_filter()) + * As we dont want to clear mem[] array for each packet going through + * sk_run_filter(), we check that filter loaded by user never try to read + * a cell if not previously written, and we check all branches to be sure + * a malicious user doesnt try to abuse us. + */ +static int check_load_and_stores(struct sock_filter *filter, int flen) +{ + u16 *masks, memvalid = 0; /* one bit per cell, 16 cells */ + int pc, ret = 0; + + BUILD_BUG_ON(BPF_MEMWORDS > 16); + masks = kmalloc(flen * sizeof(*masks), GFP_KERNEL); + if (!masks) + return -ENOMEM; + memset(masks, 0xff, flen * sizeof(*masks)); + + for (pc = 0; pc < flen; pc++) { + memvalid &= masks[pc]; + + switch (filter[pc].code) { + case BPF_S_ST: + case BPF_S_STX: + memvalid |= (1 << filter[pc].k); + break; + case BPF_S_LD_MEM: + case BPF_S_LDX_MEM: + if (!(memvalid & (1 << filter[pc].k))) { + ret = -EINVAL; + goto error; + } + break; + case BPF_S_JMP_JA: + /* a jump must set masks on target */ + masks[pc + 1 + filter[pc].k] &= memvalid; + memvalid = ~0; + break; + case BPF_S_JMP_JEQ_K: + case BPF_S_JMP_JEQ_X: + case BPF_S_JMP_JGE_K: + case BPF_S_JMP_JGE_X: + case BPF_S_JMP_JGT_K: + case BPF_S_JMP_JGT_X: + case BPF_S_JMP_JSET_X: + case BPF_S_JMP_JSET_K: + /* a jump must set masks on targets */ + masks[pc + 1 + filter[pc].jt] &= memvalid; + masks[pc + 1 + filter[pc].jf] &= memvalid; + memvalid = ~0; + break; + } + } +error: + kfree(masks); + return ret; +} + /** * sk_chk_filter - verify socket filter code * @filter: filter to verify @@ -553,7 +607,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) switch (filter[flen - 1].code) { case BPF_S_RET_K: case BPF_S_RET_A: - return 0; + return check_load_and_stores(filter, flen); } return -EINVAL; } -- cgit v1.2.3-59-g8ed1b From 19252ecb672d3f35959c576d1d26b9aca350f5bf Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 3 Dec 2010 06:05:19 +0200 Subject: ath5k: Always free tx buffers before reset * Always free tx buffers before reset, since we also empty hw queues. If we don't and a queue gets stuck, we'll never decrease txq_len and sw will keep thinking the queue is still stuck even after reset. Signed-off-by: Nick Kossifidis Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 5ece94708371..1522cf82c16c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2661,9 +2661,11 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, synchronize_irq(sc->irq); stop_tasklets(sc); + /* We are going to empty hw queues + * so we should also free any remaining + * tx buffers */ + ath5k_drain_tx_buffs(sc); if (chan) { - ath5k_drain_tx_buffs(sc); - sc->curchan = chan; sc->curband = &sc->sbands[chan->band]; } -- cgit v1.2.3-59-g8ed1b From 344b54b971bc5578281264fb6896e13b4120352b Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 3 Dec 2010 06:07:13 +0200 Subject: ath5k: Disable ANI during reset * Stop ANI durring reset to prevent false PHY error reports Signed-off-by: Nick Kossifidis Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1522cf82c16c..0592773ed81a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2653,7 +2653,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu) { struct ath5k_hw *ah = sc->ah; - int ret; + int ret, ani_mode; ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); @@ -2661,6 +2661,12 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, synchronize_irq(sc->irq); stop_tasklets(sc); + /* Save ani mode and disable ANI durring + * reset. If we don't we might get false + * PHY error interrupts. */ + ani_mode = ah->ah_sc->ani_state.ani_mode; + ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF); + /* We are going to empty hw queues * so we should also free any remaining * tx buffers */ @@ -2682,7 +2688,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, goto err; } - ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); + ath5k_ani_init(ah, ani_mode); ah->ah_cal_next_full = jiffies; ah->ah_cal_next_ani = jiffies; -- cgit v1.2.3-59-g8ed1b From f0e134a53ad95ba7a393b299ae56c9bdcaed8aec Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 3 Dec 2010 06:09:38 +0200 Subject: ath5k: Fix reporting of RX dma stop failure * Correctly report failure to stop RX DMA Signed-off-by: Nick Kossifidis Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 82541fec9f0e..0064be7ce5c9 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -72,7 +72,7 @@ static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) i--) udelay(100); - if (i) + if (!i) ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA, "failed to stop RX DMA !\n"); -- cgit v1.2.3-59-g8ed1b From b9e61f11f47035e3b4545b51fb547fef48eb3096 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 3 Dec 2010 06:12:39 +0200 Subject: ath5k: Include tx ack reporting on hw flags * Since we report tx acks to the protocol stack, add the needed flag to hw_flags. This way we'll also use the new AP probing mechanism. Signed-off-by: Nick Kossifidis Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0592773ed81a..380ff2f5f1d0 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2341,8 +2341,9 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) /* Initialize driver private data */ SET_IEEE80211_DEV(hw, sc->dev); hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | -- cgit v1.2.3-59-g8ed1b From 45904f21655cf4f0ae7d0fab5906fe51bf56ecf4 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Fri, 3 Dec 2010 09:20:40 +0100 Subject: nl80211/mac80211: define and allow configuring mesh element TTL The TTL in path selection information elements is different from the mesh ttl used in mesh data frames. Version 7.03 of the 11s draft calls this ttl 'Element TTL'. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/cfg80211.h | 2 ++ net/mac80211/cfg.c | 2 ++ net/mac80211/debugfs_netdev.c | 2 ++ net/mac80211/mesh.c | 1 + net/mac80211/mesh.h | 2 ++ net/mac80211/mesh_hwmp.c | 9 +++++---- net/mac80211/mesh_pathtbl.c | 7 ++++--- net/wireless/nl80211.c | 5 +++++ 9 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 5cfa579df476..9e541452d805 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1547,6 +1547,9 @@ enum nl80211_mntr_flags { * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh * point. * + * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a + * source mesh point for path selection elements. + * * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically * open peer links when we detect compatible mesh peers. * @@ -1593,6 +1596,7 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, NL80211_MESHCONF_HWMP_ROOTMODE, + NL80211_MESHCONF_ELEMENT_TTL, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6b2af7aeddd3..93a4b2068334 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -624,6 +624,8 @@ struct mesh_config { u16 dot11MeshMaxPeerLinks; u8 dot11MeshMaxRetries; u8 dot11MeshTTL; + /* ttl used in path selection information elements */ + u8 element_ttl; bool auto_open_plinks; /* HWMP parameters */ u8 dot11MeshHWMPmaxPREQretries; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index db134b500caa..ce6936890c26 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1024,6 +1024,8 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) conf->dot11MeshTTL = nconf->dot11MeshTTL; + if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) + conf->dot11MeshTTL = nconf->element_ttl; if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) conf->auto_open_plinks = nconf->auto_open_plinks; if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index cbdf36d7841c..2dabdf7680d0 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -251,6 +251,7 @@ IEEE80211_IF_FILE(dot11MeshConfirmTimeout, IEEE80211_IF_FILE(dot11MeshHoldingTimeout, u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); +IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); @@ -355,6 +356,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshConfirmTimeout); MESHPARAMS_ADD(dot11MeshHoldingTimeout); MESHPARAMS_ADD(dot11MeshTTL); + MESHPARAMS_ADD(element_ttl); MESHPARAMS_ADD(auto_open_plinks); MESHPARAMS_ADD(dot11MeshMaxPeerLinks); MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c8a4f19ed13b..78a36c79bdcc 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -668,6 +668,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; ifmsh->mshcfg.dot11MeshTTL = MESH_TTL; + ifmsh->mshcfg.element_ttl = MESH_DEFAULT_ELEMENT_TTL; ifmsh->mshcfg.auto_open_plinks = true; ifmsh->mshcfg.dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 58e741128968..182942eeac4d 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -216,6 +216,8 @@ struct mesh_rmc { #define PERR_RCODE_NO_ROUTE 12 #define PERR_RCODE_DEST_UNREACH 13 +#define MESH_DEFAULT_ELEMENT_TTL 31 + /* Public interfaces */ /* Various */ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 829e08a657d0..5bf64d7112b3 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -232,7 +232,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, *pos++ = WLAN_EID_PERR; *pos++ = ie_len; /* ttl */ - *pos++ = MESH_TTL; + *pos++ = ttl; /* number of destinations */ *pos++ = 1; /* @@ -522,7 +522,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, if (reply) { lifetime = PREQ_IE_LIFETIME(preq_elem); - ttl = ifmsh->mshcfg.dot11MeshTTL; + ttl = ifmsh->mshcfg.element_ttl; if (ttl != 0) { mhwmp_dbg("replying to the PREQ\n"); mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr, @@ -877,7 +877,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) sdata->u.mesh.last_sn_update = jiffies; } lifetime = default_lifetime(sdata); - ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; + ttl = sdata->u.mesh.mshcfg.element_ttl; if (ttl == 0) { sdata->u.mesh.mshstats.dropped_frames_ttl++; spin_unlock_bh(&mpath->state_lock); @@ -1013,5 +1013,6 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, cpu_to_le32(++ifmsh->sn), 0, NULL, 0, broadcast_addr, - 0, MESH_TTL, 0, 0, 0, sdata); + 0, sdata->u.mesh.mshcfg.element_ttl, + 0, 0, 0, sdata); } diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 349e466cf08b..8d65b47d9837 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -467,8 +467,8 @@ void mesh_plink_broken(struct sta_info *sta) mpath->flags &= ~MESH_PATH_ACTIVE; ++mpath->sn; spin_unlock_bh(&mpath->state_lock); - mesh_path_error_tx(MESH_TTL, mpath->dst, - cpu_to_le32(mpath->sn), + mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, + mpath->dst, cpu_to_le32(mpath->sn), cpu_to_le16(PERR_RCODE_DEST_UNREACH), bcast, sdata); } else @@ -614,7 +614,8 @@ void mesh_path_discard_frame(struct sk_buff *skb, mpath = mesh_path_lookup(da, sdata); if (mpath) sn = ++mpath->sn; - mesh_path_error_tx(MESH_TTL, skb->data, cpu_to_le32(sn), + mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data, + cpu_to_le32(sn), cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata); } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 960be4e650f0..0b90cab5da2f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2582,6 +2582,8 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, cur_params.dot11MeshMaxRetries); NLA_PUT_U8(msg, NL80211_MESHCONF_TTL, cur_params.dot11MeshTTL); + NLA_PUT_U8(msg, NL80211_MESHCONF_ELEMENT_TTL, + cur_params.element_ttl); NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, cur_params.auto_open_plinks); NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, @@ -2623,6 +2625,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 }, [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 }, [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, + [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, @@ -2670,6 +2673,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask, NL80211_MESHCONF_TTL, nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, + mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, -- cgit v1.2.3-59-g8ed1b From 09b174702601079c3a04806754be30ffbd70db4d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Dec 2010 09:20:41 +0100 Subject: mac80211: move mesh filter adjusting Logically, the filter adjusting belongs with starting/stopping mesh, not interface up/down, so move it there. Tested-by: Javier Cardona Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 18 +----------------- net/mac80211/mesh.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7aa85591dbe7..96e27f1e79fb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -197,11 +197,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) sdata->bss = &sdata->u.ap; break; case NL80211_IFTYPE_MESH_POINT: - if (!ieee80211_vif_is_mesh(&sdata->vif)) - break; - /* mesh ifaces must set allmulti to forward mcast traffic */ - atomic_inc(&local->iff_allmultis); - break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_ADHOC: @@ -274,9 +269,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) } if (ieee80211_vif_is_mesh(&sdata->vif)) { - local->fif_other_bss++; - ieee80211_configure_filter(local); - ieee80211_start_mesh(sdata); } else if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll++; @@ -504,16 +496,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_configure_filter(local); break; case NL80211_IFTYPE_MESH_POINT: - if (ieee80211_vif_is_mesh(&sdata->vif)) { - /* other_bss and allmulti are always set on mesh - * ifaces */ - local->fif_other_bss--; - atomic_dec(&local->iff_allmultis); - - ieee80211_configure_filter(local); - + if (ieee80211_vif_is_mesh(&sdata->vif)) ieee80211_stop_mesh(sdata); - } /* fall through */ default: flush_work(&sdata->work); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 78a36c79bdcc..0d3234875ac5 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -513,6 +513,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_local *local = sdata->local; + local->fif_other_bss++; + /* mesh ifaces must set allmulti to forward mcast traffic */ + atomic_inc(&local->iff_allmultis); + ieee80211_configure_filter(local); + set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); ieee80211_mesh_root_setup(ifmsh); ieee80211_queue_work(&local->hw, &sdata->work); @@ -524,6 +529,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) { + struct ieee80211_local *local = sdata->local; + del_timer_sync(&sdata->u.mesh.housekeeping_timer); del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); /* @@ -534,6 +541,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) * it no longer is. */ cancel_work_sync(&sdata->work); + + local->fif_other_bss--; + atomic_dec(&local->iff_allmultis); + ieee80211_configure_filter(local); } static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, -- cgit v1.2.3-59-g8ed1b From f9e10ce4cf86945eb5efcab31284c971877ed012 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Dec 2010 09:20:42 +0100 Subject: cfg80211: require add_virtual_intf to return new dev cfg80211 used to do all its bookkeeping in the notifier, but some new stuff will have to use local variables so make the callback return the netdev pointer. Tested-by: Javier Cardona Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 11 +++++++---- net/mac80211/cfg.c | 20 ++++++++++++-------- net/wireless/nl80211.c | 7 +++++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 93a4b2068334..902895dfbd49 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1033,7 +1033,8 @@ struct cfg80211_pmksa { * * @add_virtual_intf: create a new virtual interface with the given name, * must set the struct wireless_dev's iftype. Beware: You must create - * the new netdev in the wiphy's network namespace! + * the new netdev in the wiphy's network namespace! Returns the netdev, + * or an ERR_PTR. * * @del_virtual_intf: remove the virtual interface determined by ifindex. * @@ -1168,9 +1169,11 @@ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); int (*resume)(struct wiphy *wiphy); - int (*add_virtual_intf)(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params); + struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, + char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev); int (*change_virtual_intf)(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ce6936890c26..d34c7c3dd762 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -19,9 +19,10 @@ #include "rate.h" #include "mesh.h" -static int ieee80211_add_iface(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) +static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) { struct ieee80211_local *local = wiphy_priv(wiphy); struct net_device *dev; @@ -29,12 +30,15 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, int err; err = ieee80211_if_add(local, name, &dev, type, params); - if (err || type != NL80211_IFTYPE_MONITOR || !flags) - return err; + if (err) + return ERR_PTR(err); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata->u.mntr_flags = *flags; - return 0; + if (type == NL80211_IFTYPE_MONITOR && flags) { + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + sdata->u.mntr_flags = *flags; + } + + return dev; } static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0b90cab5da2f..cc2e5d6163de 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1368,6 +1368,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; + struct net_device *dev; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; u32 flags; @@ -1403,11 +1404,13 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, &flags); - err = rdev->ops->add_virtual_intf(&rdev->wiphy, + dev = rdev->ops->add_virtual_intf(&rdev->wiphy, nla_data(info->attrs[NL80211_ATTR_IFNAME]), type, err ? NULL : &flags, ¶ms); + if (IS_ERR(dev)) + return PTR_ERR(dev); - return err; + return 0; } static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) -- cgit v1.2.3-59-g8ed1b From bd90fdcc5fbd99a2a778999610420cf793bd1be2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Dec 2010 09:20:43 +0100 Subject: nl80211: refactor mesh parameter parsing I'm going to need this in a new place later. Tested-by: Javier Cardona Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 61 +++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cc2e5d6163de..c8d4d53fc450 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2613,14 +2613,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, return -ENOBUFS; } -#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ -do {\ - if (table[attr_num]) {\ - cfg.param = nla_fn(table[attr_num]); \ - mask |= (1 << (attr_num - 1)); \ - } \ -} while (0);\ - static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, @@ -2639,31 +2631,34 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, }; -static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) +static int nl80211_parse_mesh_params(struct genl_info *info, + struct mesh_config *cfg, + u32 *mask_out) { - u32 mask; - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - struct mesh_config cfg; struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; - struct nlattr *parent_attr; + u32 mask = 0; - parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS]; - if (!parent_attr) +#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ +do {\ + if (table[attr_num]) {\ + cfg->param = nla_fn(table[attr_num]); \ + mask |= (1 << (attr_num - 1)); \ + } \ +} while (0);\ + + + if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) return -EINVAL; if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, - parent_attr, nl80211_meshconf_params_policy)) + info->attrs[NL80211_ATTR_MESH_PARAMS], + nl80211_meshconf_params_policy)) return -EINVAL; - if (!rdev->ops->set_mesh_params) - return -EOPNOTSUPP; - /* This makes sure that there aren't more than 32 mesh config * parameters (otherwise our bitfield scheme would not work.) */ BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); /* Fill in the params struct */ - mask = 0; FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, @@ -2703,12 +2698,32 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8); + if (mask_out) + *mask_out = mask; + return 0; + +#undef FILL_IN_MESH_PARAM_IF_SET +} + +static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct mesh_config cfg; + u32 mask; + int err; + + if (!rdev->ops->set_mesh_params) + return -EOPNOTSUPP; + + err = nl80211_parse_mesh_params(info, &cfg, &mask); + if (err) + return err; + /* Apply changes */ return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); } -#undef FILL_IN_MESH_PARAM_IF_SET - static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; -- cgit v1.2.3-59-g8ed1b From 29cbe68c516a48a9a88b3226878570c6cbd83c02 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Dec 2010 09:20:44 +0100 Subject: cfg80211/mac80211: add mesh join/leave commands Instead of tying mesh activity to interface up, add join and leave commands for mesh. Since we must be backward compatible, let cfg80211 handle joining a mesh if a mesh ID was pre-configured when the device goes up. Note that this therefore must modify mac80211 as well since mac80211 needs to lose the logic to start the mesh on interface up. We now allow querying mesh parameters before the mesh is connected, which simply returns defaults. Setting them (internally renamed to "update") is only allowed while connected. Specify them with the new mesh join command instead where needed. In mac80211, beaconing must now also follow the mesh enabled/not enabled state, which is done by testing the mesh ID. Signed-off-by: Javier Cardona Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 8 +++ include/net/cfg80211.h | 38 +++++++++--- net/mac80211/cfg.c | 39 ++++++++++--- net/mac80211/ieee80211_i.h | 13 ----- net/mac80211/iface.c | 14 +---- net/mac80211/main.c | 3 +- net/mac80211/mesh.c | 26 ++------- net/mac80211/mesh.h | 25 -------- net/wireless/Makefile | 2 +- net/wireless/core.c | 15 ++++- net/wireless/core.h | 13 +++++ net/wireless/mesh.c | 140 +++++++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 137 +++++++++++++++++++++++++++++++++++++------- net/wireless/util.c | 1 + 14 files changed, 359 insertions(+), 115 deletions(-) create mode 100644 net/wireless/mesh.c diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 9e541452d805..410a06ea551b 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -394,6 +394,11 @@ * * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. * + * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial + * mesh config parameters may be given. + * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the + * network is determined by the network interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -500,6 +505,9 @@ enum nl80211_commands { NL80211_CMD_FRAME_WAIT_CANCEL, + NL80211_CMD_JOIN_MESH, + NL80211_CMD_LEAVE_MESH, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 902895dfbd49..788c3989a9e8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -258,13 +258,9 @@ struct ieee80211_supported_band { /** * struct vif_params - describes virtual interface parameters - * @mesh_id: mesh ID to use - * @mesh_id_len: length of the mesh ID * @use_4addr: use 4-address frames */ struct vif_params { - u8 *mesh_id; - int mesh_id_len; int use_4addr; }; @@ -615,6 +611,11 @@ struct bss_parameters { int ap_isolate; }; +/* + * struct mesh_config - 802.11s mesh configuration + * + * These parameters can be changed while the mesh is active. + */ struct mesh_config { /* Timeouts in ms */ /* Mesh plink management parameters */ @@ -637,6 +638,18 @@ struct mesh_config { u8 dot11MeshHWMPRootMode; }; +/** + * struct mesh_setup - 802.11s mesh setup configuration + * @mesh_id: the mesh ID + * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes + * + * These parameters are fixed when the mesh is created. + */ +struct mesh_setup { + const u8 *mesh_id; + u8 mesh_id_len; +}; + /** * struct ieee80211_txq_params - TX queue parameters * @queue: TX queue identifier (NL80211_TXQ_Q_*) @@ -1078,7 +1091,7 @@ struct cfg80211_pmksa { * * @get_mesh_params: Put the current mesh parameters into *params * - * @set_mesh_params: Set mesh parameters. + * @update_mesh_params: Update mesh parameters on a running mesh. * The mask is a bitfield which tells us which parameters to * set, and which to leave alone. * @@ -1229,9 +1242,14 @@ struct cfg80211_ops { int (*get_mesh_params)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); - int (*set_mesh_params)(struct wiphy *wiphy, - struct net_device *dev, - const struct mesh_config *nconf, u32 mask); + int (*update_mesh_params)(struct wiphy *wiphy, + struct net_device *dev, u32 mask, + const struct mesh_config *nconf); + int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, + const struct mesh_config *conf, + const struct mesh_setup *setup); + int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); + int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); @@ -1647,6 +1665,8 @@ struct cfg80211_cached_keys; * @bssid: (private) Used by the internal configuration code * @ssid: (private) Used by the internal configuration code * @ssid_len: (private) Used by the internal configuration code + * @mesh_id_len: (private) Used by the internal configuration code + * @mesh_id_up_len: (private) Used by the internal configuration code * @wext: (private) Used by the internal wireless extensions compat code * @use_4addr: indicates 4addr mode is used on this interface, must be * set by driver (if supported) on add_interface BEFORE registering the @@ -1676,7 +1696,7 @@ struct wireless_dev { /* currently used for IBSS and SME - might be rearranged later */ u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len; + u8 ssid_len, mesh_id_len, mesh_id_up_len; enum { CFG80211_SME_IDLE, CFG80211_SME_CONNECTING, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d34c7c3dd762..68329d713c02 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -60,11 +60,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, if (ret) return ret; - if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) - ieee80211_sdata_set_mesh_id(sdata, - params->mesh_id_len, - params->mesh_id); - if (type == NL80211_IFTYPE_AP_VLAN && params && params->use_4addr == 0) rcu_assign_pointer(sdata->u.vlan.sta, NULL); @@ -1003,9 +998,9 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) return (mask >> (parm-1)) & 0x1; } -static int ieee80211_set_mesh_params(struct wiphy *wiphy, - struct net_device *dev, - const struct mesh_config *nconf, u32 mask) +static int ieee80211_update_mesh_params(struct wiphy *wiphy, + struct net_device *dev, u32 mask, + const struct mesh_config *nconf) { struct mesh_config *conf; struct ieee80211_sub_if_data *sdata; @@ -1056,6 +1051,30 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, return 0; } +static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, + const struct mesh_config *conf, + const struct mesh_setup *setup) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + + memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); + ifmsh->mesh_id_len = setup->mesh_id_len; + memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); + + ieee80211_start_mesh(sdata); + + return 0; +} + +static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + ieee80211_stop_mesh(sdata); + + return 0; +} #endif static int ieee80211_change_bss(struct wiphy *wiphy, @@ -1760,8 +1779,10 @@ struct cfg80211_ops mac80211_config_ops = { .change_mpath = ieee80211_change_mpath, .get_mpath = ieee80211_get_mpath, .dump_mpath = ieee80211_dump_mpath, - .set_mesh_params = ieee80211_set_mesh_params, + .update_mesh_params = ieee80211_update_mesh_params, .get_mesh_params = ieee80211_get_mesh_params, + .join_mesh = ieee80211_join_mesh, + .leave_mesh = ieee80211_leave_mesh, #endif .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e7c880725639..72499fe5fc36 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -609,19 +609,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) return container_of(p, struct ieee80211_sub_if_data, vif); } -static inline void -ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, - u8 mesh_id_len, u8 *mesh_id) -{ -#ifdef CONFIG_MAC80211_MESH - struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - ifmsh->mesh_id_len = mesh_id_len; - memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); -#else - WARN_ON(1); -#endif -} - enum sdata_queue_type { IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, IEEE80211_SDATA_QUEUE_AGG_START = 1, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 96e27f1e79fb..f0f11bb794af 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -268,9 +268,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) goto err_stop; } - if (ieee80211_vif_is_mesh(&sdata->vif)) { - ieee80211_start_mesh(sdata); - } else if (sdata->vif.type == NL80211_IFTYPE_AP) { + if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll++; local->fif_probe_req++; @@ -495,10 +493,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_adjust_monitor_flags(sdata, -1); ieee80211_configure_filter(local); break; - case NL80211_IFTYPE_MESH_POINT: - if (ieee80211_vif_is_mesh(&sdata->vif)) - ieee80211_stop_mesh(sdata); - /* fall through */ default: flush_work(&sdata->work); /* @@ -1188,12 +1182,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, if (ret) goto fail; - if (ieee80211_vif_is_mesh(&sdata->vif) && - params && params->mesh_id_len) - ieee80211_sdata_set_mesh_id(sdata, - params->mesh_id_len, - params->mesh_id); - mutex_lock(&local->iflist_mtx); list_add_tail_rcu(&sdata->list, &local->interfaces); mutex_unlock(&local->iflist_mtx); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 107a0cbe52ac..2de69766c6aa 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -246,7 +246,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, !!sdata->u.ibss.presp; break; case NL80211_IFTYPE_MESH_POINT: - sdata->vif.bss_conf.enable_beacon = true; + sdata->vif.bss_conf.enable_beacon = + !!sdata->u.mesh.mesh_id_len; break; default: /* not reached */ diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 0d3234875ac5..63e1188d5062 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -530,6 +530,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + + ifmsh->mesh_id_len = 0; + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); + sta_info_flush(local, NULL); del_timer_sync(&sdata->u.mesh.housekeeping_timer); del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); @@ -674,27 +679,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ieee80211_mesh_housekeeping_timer, (unsigned long) sdata); - ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; - ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; - ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; - ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; - ifmsh->mshcfg.dot11MeshTTL = MESH_TTL; - ifmsh->mshcfg.element_ttl = MESH_DEFAULT_ELEMENT_TTL; - ifmsh->mshcfg.auto_open_plinks = true; - ifmsh->mshcfg.dot11MeshMaxPeerLinks = - MESH_MAX_ESTAB_PLINKS; - ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout = - MESH_PATH_TIMEOUT; - ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval = - MESH_PREQ_MIN_INT; - ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = - MESH_DIAM_TRAVERSAL_TIME; - ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries = - MESH_MAX_PREQ_RETRIES; - ifmsh->mshcfg.path_refresh_time = - MESH_PATH_REFRESH_TIME; - ifmsh->mshcfg.min_discovery_timeout = - MESH_MIN_DISCOVERY_TIMEOUT; ifmsh->accepting_plinks = true; ifmsh->preq_id = 0; ifmsh->sn = 0; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 182942eeac4d..039d7fa0af74 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -175,33 +175,10 @@ struct mesh_rmc { */ #define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2) -/* Default values, timeouts in ms */ -#define MESH_TTL 31 -#define MESH_MAX_RETR 3 -#define MESH_RET_T 100 -#define MESH_CONF_T 100 -#define MESH_HOLD_T 100 - -#define MESH_PATH_TIMEOUT 5000 -/* Minimum interval between two consecutive PREQs originated by the same - * interface - */ -#define MESH_PREQ_MIN_INT 10 -#define MESH_DIAM_TRAVERSAL_TIME 50 -/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before - * timing out. This way it will remain ACTIVE and no data frames will be - * unnecesarily held in the pending queue. - */ -#define MESH_PATH_REFRESH_TIME 1000 -#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ -#define MESH_MAX_PREQ_RETRIES 4 #define MESH_PATH_EXPIRE (600 * HZ) -/* Default maximum number of established plinks per interface */ -#define MESH_MAX_ESTAB_PLINKS 32 - /* Default maximum number of plinks per interface */ #define MESH_MAX_PLINKS 256 @@ -216,8 +193,6 @@ struct mesh_rmc { #define PERR_RCODE_NO_ROUTE 12 #define PERR_RCODE_DEST_UNREACH 13 -#define MESH_DEFAULT_ELEMENT_TTL 31 - /* Public interfaces */ /* Various */ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, diff --git a/net/wireless/Makefile b/net/wireless/Makefile index e77e508126fa..55a28ab21db9 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/net/wireless/core.c b/net/wireless/core.c index 630bcf0a2f04..79772fcc37bc 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -332,6 +332,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf); WARN_ON(ops->add_station && !ops->del_station); WARN_ON(ops->add_mpath && !ops->del_mpath); + WARN_ON(ops->join_mesh && !ops->leave_mesh); alloc_size = sizeof(*rdev) + sizeof_priv; @@ -752,6 +753,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, cfg80211_mlme_down(rdev, dev); wdev_unlock(wdev); break; + case NL80211_IFTYPE_MESH_POINT: + cfg80211_leave_mesh(rdev, dev); + break; default: break; } @@ -775,20 +779,27 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, } cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); -#ifdef CONFIG_CFG80211_WEXT wdev_lock(wdev); switch (wdev->iftype) { +#ifdef CONFIG_CFG80211_WEXT case NL80211_IFTYPE_ADHOC: cfg80211_ibss_wext_join(rdev, wdev); break; case NL80211_IFTYPE_STATION: cfg80211_mgd_wext_connect(rdev, wdev); break; +#endif + case NL80211_IFTYPE_MESH_POINT: + /* backward compat code ... */ + if (wdev->mesh_id_up_len) + __cfg80211_join_mesh(rdev, dev, wdev->ssid, + wdev->mesh_id_up_len, + &default_mesh_config); + break; default: break; } wdev_unlock(wdev); -#endif rdev->opencount++; mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); diff --git a/net/wireless/core.h b/net/wireless/core.h index ee80ad8dc655..743203bb61ac 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -285,6 +285,19 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); +/* mesh */ +extern const struct mesh_config default_mesh_config; +int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev, + const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_config *conf); +int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev, + const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_config *conf); +int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev); + /* MLME */ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, struct net_device *dev, diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c new file mode 100644 index 000000000000..e0b9747fe50a --- /dev/null +++ b/net/wireless/mesh.c @@ -0,0 +1,140 @@ +#include +#include +#include "core.h" + +/* Default values, timeouts in ms */ +#define MESH_TTL 31 +#define MESH_DEFAULT_ELEMENT_TTL 31 +#define MESH_MAX_RETR 3 +#define MESH_RET_T 100 +#define MESH_CONF_T 100 +#define MESH_HOLD_T 100 + +#define MESH_PATH_TIMEOUT 5000 + +/* + * Minimum interval between two consecutive PREQs originated by the same + * interface + */ +#define MESH_PREQ_MIN_INT 10 +#define MESH_DIAM_TRAVERSAL_TIME 50 + +/* + * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds + * before timing out. This way it will remain ACTIVE and no data frames + * will be unnecessarily held in the pending queue. + */ +#define MESH_PATH_REFRESH_TIME 1000 +#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) + +/* Default maximum number of established plinks per interface */ +#define MESH_MAX_ESTAB_PLINKS 32 + +#define MESH_MAX_PREQ_RETRIES 4 + + +const struct mesh_config default_mesh_config = { + .dot11MeshRetryTimeout = MESH_RET_T, + .dot11MeshConfirmTimeout = MESH_CONF_T, + .dot11MeshHoldingTimeout = MESH_HOLD_T, + .dot11MeshMaxRetries = MESH_MAX_RETR, + .dot11MeshTTL = MESH_TTL, + .element_ttl = MESH_DEFAULT_ELEMENT_TTL, + .auto_open_plinks = true, + .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, + .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, + .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, + .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, + .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, + .path_refresh_time = MESH_PATH_REFRESH_TIME, + .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, +}; + + +int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev, + const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_config *conf) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct mesh_setup setup = { + .mesh_id = mesh_id, + .mesh_id_len = mesh_id_len, + }; + int err; + + BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + + if (wdev->mesh_id_len) + return -EALREADY; + + if (!mesh_id_len) + return -EINVAL; + + if (!rdev->ops->join_mesh) + return -EOPNOTSUPP; + + err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); + if (!err) { + memcpy(wdev->ssid, mesh_id, mesh_id_len); + wdev->mesh_id_len = mesh_id_len; + } + + return err; +} + +int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev, + const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_config *conf) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); + wdev_unlock(wdev); + + return err; +} + +static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + + if (!rdev->ops->leave_mesh) + return -EOPNOTSUPP; + + if (!wdev->mesh_id_len) + return -ENOTCONN; + + err = rdev->ops->leave_mesh(&rdev->wiphy, dev); + if (!err) + wdev->mesh_id_len = 0; + return err; +} + +int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_leave_mesh(rdev, dev); + wdev_unlock(wdev); + + return err; +} diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c8d4d53fc450..56508d40c740 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -661,13 +661,14 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(add_beacon, NEW_BEACON); CMD(add_station, NEW_STATION); CMD(add_mpath, NEW_MPATH); - CMD(set_mesh_params, SET_MESH_PARAMS); + CMD(update_mesh_params, SET_MESH_PARAMS); CMD(change_bss, SET_BSS); CMD(auth, AUTHENTICATE); CMD(assoc, ASSOCIATE); CMD(deauth, DEAUTHENTICATE); CMD(disassoc, DISASSOCIATE); CMD(join_ibss, JOIN_IBSS); + CMD(join_mesh, JOIN_MESH); CMD(set_pmksa, SET_PMKSA); CMD(del_pmksa, DEL_PMKSA); CMD(flush_pmksa, FLUSH_PMKSA); @@ -1324,11 +1325,21 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_MESH_ID]) { + struct wireless_dev *wdev = dev->ieee80211_ptr; + if (ntype != NL80211_IFTYPE_MESH_POINT) return -EINVAL; - params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); - params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - change = true; + if (netif_running(dev)) + return -EBUSY; + + wdev_lock(wdev); + BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != + IEEE80211_MAX_MESH_ID_LEN); + wdev->mesh_id_up_len = + nla_len(info->attrs[NL80211_ATTR_MESH_ID]); + memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), + wdev->mesh_id_up_len); + wdev_unlock(wdev); } if (info->attrs[NL80211_ATTR_4ADDR]) { @@ -1388,12 +1399,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) !(rdev->wiphy.interface_modes & (1 << type))) return -EOPNOTSUPP; - if (type == NL80211_IFTYPE_MESH_POINT && - info->attrs[NL80211_ATTR_MESH_ID]) { - params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); - params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - } - if (info->attrs[NL80211_ATTR_4ADDR]) { params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); @@ -1410,6 +1415,20 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(dev)) return PTR_ERR(dev); + if (type == NL80211_IFTYPE_MESH_POINT && + info->attrs[NL80211_ATTR_MESH_ID]) { + struct wireless_dev *wdev = dev->ieee80211_ptr; + + wdev_lock(wdev); + BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != + IEEE80211_MAX_MESH_ID_LEN); + wdev->mesh_id_up_len = + nla_len(info->attrs[NL80211_ATTR_MESH_ID]); + memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), + wdev->mesh_id_up_len); + wdev_unlock(wdev); + } + return 0; } @@ -2543,21 +2562,32 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) } static int nl80211_get_mesh_params(struct sk_buff *skb, - struct genl_info *info) + struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct mesh_config cur_params; - int err; struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct mesh_config cur_params; + int err = 0; void *hdr; struct nlattr *pinfoattr; struct sk_buff *msg; + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + if (!rdev->ops->get_mesh_params) return -EOPNOTSUPP; - /* Get the mesh params */ - err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); + wdev_lock(wdev); + /* If not connected, get default parameters */ + if (!wdev->mesh_id_len) + memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); + else + err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, + &cur_params); + wdev_unlock(wdev); + if (err) return err; @@ -2705,23 +2735,37 @@ do {\ #undef FILL_IN_MESH_PARAM_IF_SET } -static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) +static int nl80211_update_mesh_params(struct sk_buff *skb, + struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; struct mesh_config cfg; u32 mask; int err; - if (!rdev->ops->set_mesh_params) + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + + if (!rdev->ops->update_mesh_params) return -EOPNOTSUPP; err = nl80211_parse_mesh_params(info, &cfg, &mask); if (err) return err; - /* Apply changes */ - return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); + wdev_lock(wdev); + if (!wdev->mesh_id_len) + err = -ENOLINK; + + if (!err) + err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, + mask, &cfg); + + wdev_unlock(wdev); + + return err; } static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) @@ -4505,6 +4549,41 @@ out: return err; } +static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct mesh_config cfg; + int err; + + /* start with default */ + memcpy(&cfg, &default_mesh_config, sizeof(cfg)); + + if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { + /* and parse parameters if given */ + err = nl80211_parse_mesh_params(info, &cfg, NULL); + if (err) + return err; + } + + if (!info->attrs[NL80211_ATTR_MESH_ID] || + !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) + return -EINVAL; + + return cfg80211_join_mesh(rdev, dev, + nla_data(info->attrs[NL80211_ATTR_MESH_ID]), + nla_len(info->attrs[NL80211_ATTR_MESH_ID]), + &cfg); +} + +static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + + return cfg80211_leave_mesh(rdev, dev); +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -4769,10 +4848,10 @@ static struct genl_ops nl80211_ops[] = { }, { .cmd = NL80211_CMD_SET_MESH_PARAMS, - .doit = nl80211_set_mesh_params, + .doit = nl80211_update_mesh_params, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4987,6 +5066,22 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_JOIN_MESH, + .doit = nl80211_join_mesh, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_LEAVE_MESH, + .doit = nl80211_leave_mesh, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { diff --git a/net/wireless/util.c b/net/wireless/util.c index fee020b15a4e..4de624ca4c63 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -792,6 +792,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (ntype != otype) { dev->ieee80211_ptr->use_4addr = false; + dev->ieee80211_ptr->mesh_id_up_len = 0; switch (otype) { case NL80211_IFTYPE_ADHOC: -- cgit v1.2.3-59-g8ed1b From abc471dc31be15f9fee5ec77f25d31b927d334b9 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Dec 2010 15:41:47 +0100 Subject: iwl3945: prevent too frequent firmware resets Similarly like on iwlagn, initialize reset duration on iwl3945 to prevent too frequent firmware resets. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8eb1393506bc..cc282aa2f43c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3861,6 +3861,13 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->iw_mode = NL80211_IFTYPE_STATION; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; + /* initialize force reset */ + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; + + priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; priv->tx_power_next = IWL_DEFAULT_TX_POWER; -- cgit v1.2.3-59-g8ed1b From 22de94de7de78b8de2fb1f2df5aa85b5556cfcfd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Dec 2010 15:41:48 +0100 Subject: iwlwifi: jiffies based tx queues watchdog This patch replace monitor/recover timer by watchdog based on time stamp. New code allow to discover hangs more precisely. Timeout values are currently doubled monitoring period values of previous timer. This have to be tuned based of firmware timing capabilities. Tested on 3945, 4965, 5300, 6300. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 3 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 4 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 4 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 21 ++---- drivers/net/wireless/iwlwifi/iwl-core.c | 111 ++++++++++++---------------- drivers/net/wireless/iwlwifi/iwl-core.h | 10 +-- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 +++--- drivers/net/wireless/iwlwifi/iwl-dev.h | 16 ++-- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 21 ++---- 13 files changed, 91 insertions(+), 138 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index fb3e3713bae4..3c983e426f25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -228,7 +228,6 @@ static struct iwl_lib_ops iwl1000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, @@ -262,7 +261,7 @@ static struct iwl_base_params iwl1000_base_params = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, .ucode_tracing = true, .sensitivity_calib_by_driver = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index cac9647da71c..a9b852be4509 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -325,6 +325,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, return; } + txq->time_stamp = jiffies; info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); ieee80211_tx_info_clear_status(info); @@ -2733,7 +2734,6 @@ static struct iwl_lib_ops iwl3945_lib = { .isr_ops = { .isr = iwl_isr_legacy, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl3945_good_plcp_health, .debugfs_ops = { @@ -2776,7 +2776,7 @@ static struct iwl_base_params iwl3945_base_params = { .led_compensation = 64, .broken_powersave = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .tx_power_by_driver = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6788ceb37686..3f1e5f1bf847 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2198,6 +2198,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, return; } + txq->time_stamp = jiffies; info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); @@ -2554,7 +2555,6 @@ static struct iwl_lib_ops iwl4965_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, }; @@ -2609,7 +2609,7 @@ static struct iwl_base_params iwl4965_base_params = { .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .wd_timeout = IWL_DEF_WD_TIMEOUT, .temperature_kelvin = true, .max_event_log_size = 512, .tx_power_by_driver = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index cf74edb82a70..8435e5a4e69d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -402,7 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, @@ -472,7 +471,6 @@ static struct iwl_lib_ops iwl5150_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, @@ -511,7 +509,7 @@ static struct iwl_base_params iwl5000_base_params = { .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, + .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, .sensitivity_calib_by_driver = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8018f38d5165..808942cc2991 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -339,7 +339,6 @@ static struct iwl_lib_ops iwl6000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, @@ -412,7 +411,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, @@ -482,7 +480,7 @@ static struct iwl_base_params iwl6000_base_params = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, .sensitivity_calib_by_driver = true, @@ -506,7 +504,7 @@ static struct iwl_base_params iwl6050_base_params = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, .ucode_tracing = true, .sensitivity_calib_by_driver = true, @@ -529,7 +527,7 @@ static struct iwl_base_params iwl6000_coex_base_params = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, + .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, .sensitivity_calib_by_driver = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 407f0bb8422a..d941910e7ef4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -405,6 +405,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, return; } + txq->time_stamp = jiffies; info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 32ab4a0215a0..d4075476670a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2654,13 +2654,8 @@ static void iwl_alive_start(struct iwl_priv *priv) /* After the ALIVE response, we can send host commands to the uCode */ set_bit(STATUS_ALIVE, &priv->status); - if (priv->cfg->ops->lib->recover_from_tx_stall) { - /* Enable timer to monitor the driver queues */ - mod_timer(&priv->monitor_recover, - jiffies + - msecs_to_jiffies( - priv->cfg->base_params->monitor_recover_period)); - } + /* Enable watchdog to monitor the driver tx queues */ + iwl_setup_watchdog(priv); if (iwl_is_rfkill(priv)) return; @@ -2755,8 +2750,7 @@ static void __iwl_down(struct iwl_priv *priv) /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); + del_timer_sync(&priv->watchdog); iwl_clear_ucode_stations(priv, NULL); iwl_dealloc_bcast_stations(priv); @@ -3742,12 +3736,9 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) priv->ucode_trace.data = (unsigned long)priv; priv->ucode_trace.function = iwl_bg_ucode_trace; - if (priv->cfg->ops->lib->recover_from_tx_stall) { - init_timer(&priv->monitor_recover); - priv->monitor_recover.data = (unsigned long)priv; - priv->monitor_recover.function = - priv->cfg->ops->lib->recover_from_tx_stall; - } + init_timer(&priv->watchdog); + priv->watchdog.data = (unsigned long)priv; + priv->watchdog.function = iwl_bg_watchdog; if (!priv->cfg->base_params->use_isr_legacy) tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c41f5a878210..d62b92518417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1894,77 +1894,58 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL(iwl_mac_change_interface); -/** - * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover - * - * During normal condition (no queue is stuck), the timer is continually set to - * execute every monitor_recover_period milliseconds after the last timer - * expired. When the queue read_ptr is at the same place, the timer is - * shorten to 100mSecs. This is - * 1) to reduce the chance that the read_ptr may wrap around (not stuck) - * 2) to detect the stuck queues quicker before the station and AP can - * disassociate each other. - * - * This function monitors all the tx queues and recover from it if any - * of the queues are stuck. - * 1. It first check the cmd queue for stuck conditions. If it is stuck, - * it will recover by resetting the firmware and return. - * 2. Then, it checks for station association. If it associates it will check - * other queues. If any queue is stuck, it will recover by resetting - * the firmware. - * Note: It the number of times the queue read_ptr to be at the same place to - * be MAX_REPEAT+1 in order to consider to be stuck. - */ /* - * The maximum number of times the read pointer of the tx queue at the - * same place without considering to be stuck. + * On every watchdog tick we check (latest) time stamp. If it does not + * change during timeout period and queue is not empty we reset firmware. */ -#define MAX_REPEAT (2) static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) { - struct iwl_tx_queue *txq; - struct iwl_queue *q; + struct iwl_tx_queue *txq = &priv->txq[cnt]; + struct iwl_queue *q = &txq->q; + unsigned long timeout; + int ret; - txq = &priv->txq[cnt]; - q = &txq->q; - /* queue is empty, skip */ - if (q->read_ptr == q->write_ptr) + if (q->read_ptr == q->write_ptr) { + txq->time_stamp = jiffies; return 0; + } - if (q->read_ptr == q->last_read_ptr) { - /* a queue has not been read from last time */ - if (q->repeat_same_read_ptr > MAX_REPEAT) { - IWL_ERR(priv, - "queue %d stuck %d time. Fw reload.\n", - q->id, q->repeat_same_read_ptr); - q->repeat_same_read_ptr = 0; - iwl_force_reset(priv, IWL_FW_RESET, false); - } else { - q->repeat_same_read_ptr++; - IWL_DEBUG_RADIO(priv, - "queue %d, not read %d time\n", - q->id, - q->repeat_same_read_ptr); - mod_timer(&priv->monitor_recover, - jiffies + msecs_to_jiffies( - IWL_ONE_HUNDRED_MSECS)); - return 1; - } - } else { - q->last_read_ptr = q->read_ptr; - q->repeat_same_read_ptr = 0; + timeout = txq->time_stamp + + msecs_to_jiffies(priv->cfg->base_params->wd_timeout); + + if (time_after(jiffies, timeout)) { + IWL_ERR(priv, "Queue %d stuck for %u ms.\n", + q->id, priv->cfg->base_params->wd_timeout); + ret = iwl_force_reset(priv, IWL_FW_RESET, false); + return (ret == -EAGAIN) ? 0 : 1; } + return 0; } -void iwl_bg_monitor_recover(unsigned long data) +/* + * Making watchdog tick be a quarter of timeout assure we will + * discover the queue hung between timeout and 1.25*timeout + */ +#define IWL_WD_TICK(timeout) ((timeout) / 4) + +/* + * Watchdog timer callback, we check each tx queue for stuck, if if hung + * we reset the firmware. If everything is fine just rearm the timer. + */ +void iwl_bg_watchdog(unsigned long data) { struct iwl_priv *priv = (struct iwl_priv *)data; int cnt; + unsigned long timeout; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; + timeout = priv->cfg->base_params->wd_timeout; + if (timeout == 0) + return; + /* monitor and check for stuck cmd queue */ if (iwl_check_stuck_queue(priv, priv->cmd_queue)) return; @@ -1979,17 +1960,23 @@ void iwl_bg_monitor_recover(unsigned long data) return; } } - if (priv->cfg->base_params->monitor_recover_period) { - /* - * Reschedule the timer to occur in - * priv->cfg->base_params->monitor_recover_period - */ - mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( - priv->cfg->base_params->monitor_recover_period)); - } + + mod_timer(&priv->watchdog, jiffies + + msecs_to_jiffies(IWL_WD_TICK(timeout))); } -EXPORT_SYMBOL(iwl_bg_monitor_recover); +EXPORT_SYMBOL(iwl_bg_watchdog); + +void iwl_setup_watchdog(struct iwl_priv *priv) +{ + unsigned int timeout = priv->cfg->base_params->wd_timeout; + if (timeout) + mod_timer(&priv->watchdog, + jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); + else + del_timer(&priv->watchdog); +} +EXPORT_SYMBOL(iwl_setup_watchdog); /* * extended beacon time format diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 808be731ecb7..568920ac982d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -210,8 +210,6 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; - /* recover from tx queue stall */ - void (*recover_from_tx_stall)(unsigned long data); /* check for plcp health */ bool (*check_plcp_health)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); @@ -280,7 +278,7 @@ struct iwl_mod_params { * @plcp_delta_threshold: plcp error rate threshold used to trigger * radio tuning when there is a high receiving plcp error rate * @chain_noise_scale: default chain noise scale used for gain computation - * @monitor_recover_period: default timer used to check stuck queues + * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging * @tx_power_by_driver: tx power calibration performed by driver @@ -315,8 +313,7 @@ struct iwl_base_params { const bool support_wimax_coexist; u8 plcp_delta_threshold; s32 chain_noise_scale; - /* timer period for monitor the driver queues */ - u32 monitor_recover_period; + unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; const bool tx_power_by_driver; @@ -546,6 +543,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); +void iwl_setup_watchdog(struct iwl_priv *priv); /***************************************************** * TX power ****************************************************/ @@ -625,7 +623,7 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) return pci_lnk_ctl; } -void iwl_bg_monitor_recover(unsigned long data); +void iwl_bg_watchdog(unsigned long data); u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 3cc58420d445..d36836376e6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1534,32 +1534,26 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, user_buf, count, ppos); } -static ssize_t iwl_dbgfs_monitor_period_write(struct file *file, +static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; char buf[8]; int buf_size; - int period; + int timeout; memset(buf, 0, sizeof(buf)); buf_size = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, buf_size)) return -EFAULT; - if (sscanf(buf, "%d", &period) != 1) + if (sscanf(buf, "%d", &timeout) != 1) return -EINVAL; - if (period < 0 || period > IWL_MAX_MONITORING_PERIOD) - priv->cfg->base_params->monitor_recover_period = - IWL_DEF_MONITORING_PERIOD; - else - priv->cfg->base_params->monitor_recover_period = period; + if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) + timeout = IWL_DEF_WD_TIMEOUT; - if (priv->cfg->base_params->monitor_recover_period) - mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( - priv->cfg->base_params->monitor_recover_period)); - else - del_timer_sync(&priv->monitor_recover); + priv->cfg->base_params->wd_timeout = timeout; + iwl_setup_watchdog(priv); return count; } @@ -1686,7 +1680,7 @@ DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); DEBUGFS_WRITE_FILE_OPS(txfifo_flush); DEBUGFS_READ_FILE_OPS(ucode_bt_stats); -DEBUGFS_WRITE_FILE_OPS(monitor_period); +DEBUGFS_WRITE_FILE_OPS(wd_timeout); DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); @@ -1763,7 +1757,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); - DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); if (priv->cfg->base_params->sensitivity_calib_by_driver) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ea81ced13756..836f1816b110 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -129,9 +129,6 @@ struct iwl_queue { int write_ptr; /* 1-st empty entry (index) host_w*/ int read_ptr; /* last used entry (index) host_r*/ /* use for monitoring and recovering the stuck queue */ - int last_read_ptr; /* storing the last read_ptr */ - /* number of time read_ptr and last_read_ptr are the same */ - u8 repeat_same_read_ptr; dma_addr_t dma_addr; /* physical addr for BD's */ int n_window; /* safe queue window */ u32 id; @@ -155,6 +152,7 @@ struct iwl_tx_info { * @meta: array of meta data for each command/tx buffer * @dma_addr_cmd: physical address of cmd/tx buffer array * @txb: array of per-TFD driver data + * @time_stamp: time (in jiffies) of last read_ptr change * @need_update: indicates need to update read/write index * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled * @@ -170,6 +168,7 @@ struct iwl_tx_queue { struct iwl_device_cmd **cmd; struct iwl_cmd_meta *meta; struct iwl_tx_info *txb; + unsigned long time_stamp; u8 need_update; u8 sched_retry; u8 active; @@ -1104,11 +1103,10 @@ struct iwl_event_log { #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) -/* timer constants use to monitor and recover stuck tx queues in mSecs */ -#define IWL_DEF_MONITORING_PERIOD (1000) -#define IWL_LONG_MONITORING_PERIOD (5000) -#define IWL_ONE_HUNDRED_MSECS (100) -#define IWL_MAX_MONITORING_PERIOD (60000) +/* TX queue watchdog timeouts in mSecs */ +#define IWL_DEF_WD_TIMEOUT (2000) +#define IWL_LONG_WD_TIMEOUT (10000) +#define IWL_MAX_WD_TIMEOUT (120000) /* BT Antenna Coupling Threshold (dB) */ #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) @@ -1544,7 +1542,7 @@ struct iwl_priv { struct work_struct run_time_calib_work; struct timer_list statistics_periodic; struct timer_list ucode_trace; - struct timer_list monitor_recover; + struct timer_list watchdog; bool hw_ready; struct iwl_event_log event_log; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 90659bcf5804..073b6ce6141c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -263,8 +263,6 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, q->high_mark = 2; q->write_ptr = q->read_ptr = 0; - q->last_read_ptr = 0; - q->repeat_same_read_ptr = 0; return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index cc282aa2f43c..371abbf60eac 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2509,13 +2509,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv) /* After the ALIVE response, we can send commands to 3945 uCode */ set_bit(STATUS_ALIVE, &priv->status); - if (priv->cfg->ops->lib->recover_from_tx_stall) { - /* Enable timer to monitor the driver queues */ - mod_timer(&priv->monitor_recover, - jiffies + - msecs_to_jiffies( - priv->cfg->base_params->monitor_recover_period)); - } + /* Enable watchdog to monitor the driver tx queues */ + iwl_setup_watchdog(priv); if (iwl_is_rfkill(priv)) return; @@ -2572,8 +2567,7 @@ static void __iwl3945_down(struct iwl_priv *priv) /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); + del_timer_sync(&priv->watchdog); /* Station information will now be cleared in device */ iwl_clear_ucode_stations(priv, NULL); @@ -3775,12 +3769,9 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) iwl3945_hw_setup_deferred_work(priv); - if (priv->cfg->ops->lib->recover_from_tx_stall) { - init_timer(&priv->monitor_recover); - priv->monitor_recover.data = (unsigned long)priv; - priv->monitor_recover.function = - priv->cfg->ops->lib->recover_from_tx_stall; - } + init_timer(&priv->watchdog); + priv->watchdog.data = (unsigned long)priv; + priv->watchdog.function = iwl_bg_watchdog; tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) iwl3945_irq_tasklet, (unsigned long)priv); -- cgit v1.2.3-59-g8ed1b From 8917a3c0b7d1557548f50bfe3f0e18e0354e38f6 Mon Sep 17 00:00:00 2001 From: David Shwatrz Date: Thu, 2 Dec 2010 09:01:55 +0000 Subject: Fix a typo in datagram.c and sctp/socket.c. Hi, This patch fixes a typo in net/core/datagram.c and in net/sctp/socket.c Regards, David Shwartz Signed-off-by: David Shwartz Signed-off-by: David S. Miller --- net/core/datagram.c | 2 +- net/sctp/socket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/datagram.c b/net/core/datagram.c index cd1e039c8755..18ac112ea7ae 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -177,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, * interrupt level will suddenly eat the receive_queue. * * Look at current nfs client by the way... - * However, this function was corrent in any case. 8) + * However, this function was correct in any case. 8) */ unsigned long cpu_flags; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6bd554323a34..842c7f3650b9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -6047,7 +6047,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, * will suddenly eat the receive_queue. * * Look at current nfs client by the way... - * However, this function was corrent in any case. 8) + * However, this function was correct in any case. 8) */ if (flags & MSG_PEEK) { spin_lock_bh(&sk->sk_receive_queue.lock); -- cgit v1.2.3-59-g8ed1b From a7f5a5fcd9f13afd3471a0de8c1fdaa8f989497c Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 13:23:30 +0000 Subject: ixgbe: fix for link failure on SFP+ DA cables This patch helps prevent FW/SW semaphore collision from leading to link establishment failure. The collision might mess up the PHY registers so we reset the PHY. However there are SFI/KR areas in the PHY that are not reset with a Reset_AN so we need to change LMS to reset it. Also wait until AN state machine is AN_GOOD Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 28 +++++++++++++++++++++++++--- drivers/net/ixgbe/ixgbe_type.h | 3 +++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 385ccebb826c..6827dddc383e 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -96,6 +96,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) { s32 ret_val = 0; + u32 reg_anlp1 = 0; + u32 i = 0; u16 list_offset, data_offset, data_value; if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { @@ -122,14 +124,34 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) IXGBE_WRITE_FLUSH(hw); hw->eeprom.ops.read(hw, ++data_offset, &data_value); } - /* Now restart DSP by setting Restart_AN */ - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, - (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART)); /* Release the semaphore */ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); /* Delay obtaining semaphore again to allow FW access */ msleep(hw->eeprom.semaphore_delay); + + /* Now restart DSP by setting Restart_AN and clearing LMS */ + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw, + IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) | + IXGBE_AUTOC_AN_RESTART)); + + /* Wait for AN to leave state 0 */ + for (i = 0; i < 10; i++) { + msleep(4); + reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1); + if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK) + break; + } + if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) { + hw_dbg(hw, "sfp module setup not complete\n"); + ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + goto setup_sfp_out; + } + + /* Restart DSP by setting Restart_AN and return to SFI mode */ + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw, + IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL | + IXGBE_AUTOC_AN_RESTART)); } setup_sfp_out: diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index ef816dd5a8f0..0f80893edabf 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1470,6 +1470,8 @@ #define IXGBE_ANLP1_PAUSE 0x0C00 #define IXGBE_ANLP1_SYM_PAUSE 0x0400 #define IXGBE_ANLP1_ASM_PAUSE 0x0800 +#define IXGBE_ANLP1_AN_STATE_MASK 0x000f0000 + /* SW Semaphore Register bitmasks */ #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ @@ -2641,6 +2643,7 @@ struct ixgbe_info { #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 #define IXGBE_ERR_RAR_INDEX -27 +#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 #define IXGBE_ERR_PBA_SECTION -31 #define IXGBE_ERR_INVALID_ARGUMENT -32 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF -- cgit v1.2.3-59-g8ed1b From 9f91170773d852e65e4fc36e1f8173ce614f62e1 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 13:24:05 +0000 Subject: ixgbe: fix enum type mismatch on disable laser Fixes a recent bug on the patch (c6ecf39a10ceec3e97096e2a8d3eadcecd593422) that disabled the laser on ifconfig down. Compilers were seeing a enum mismatch. Signed-off-by Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f97353cdb607..a12e86fccb06 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3800,7 +3800,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */ if (hw->mac.ops.enable_tx_laser && ((hw->phy.multispeed_fiber) || - ((hw->phy.type == ixgbe_media_type_fiber) && + ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && (hw->mac.type == ixgbe_mac_82599EB)))) hw->mac.ops.enable_tx_laser(hw); @@ -4122,7 +4122,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ if (hw->mac.ops.disable_tx_laser && ((hw->phy.multispeed_fiber) || - ((hw->phy.type == ixgbe_media_type_fiber) && + ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && (hw->mac.type == ixgbe_mac_82599EB)))) hw->mac.ops.disable_tx_laser(hw); @@ -7212,7 +7212,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ if (hw->mac.ops.disable_tx_laser && ((hw->phy.multispeed_fiber) || - ((hw->phy.type == ixgbe_media_type_fiber) && + ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && (hw->mac.type == ixgbe_mac_82599EB)))) hw->mac.ops.disable_tx_laser(hw); -- cgit v1.2.3-59-g8ed1b From e176bbc5893bef36a0909de31dea97865660a7c9 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 2 Dec 2010 07:20:05 +0000 Subject: net: am79c961a: Omit private ndo_get_stats function am79c961_getstats() just returns dev->stats so we can leave it out alltogether and let dev_get_stats() do the job. Signed-off-by: Tobias Klauser Acked-by: Russell King Signed-off-by: David S. Miller --- drivers/net/arm/am79c961a.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 62f21106efec..0c9217f48b72 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -340,14 +340,6 @@ am79c961_close(struct net_device *dev) return 0; } -/* - * Get the current statistics. - */ -static struct net_device_stats *am79c961_getstats (struct net_device *dev) -{ - return &dev->stats; -} - static void am79c961_mc_hash(char *addr, unsigned short *hash) { if (addr[0] & 0x01) { @@ -665,7 +657,6 @@ static const struct net_device_ops am79c961_netdev_ops = { .ndo_open = am79c961_open, .ndo_stop = am79c961_close, .ndo_start_xmit = am79c961_sendpacket, - .ndo_get_stats = am79c961_getstats, .ndo_set_multicast_list = am79c961_setmulticastlist, .ndo_tx_timeout = am79c961_timeout, .ndo_validate_addr = eth_validate_addr, -- cgit v1.2.3-59-g8ed1b From b27d50a9ff5cf2775b7a4daf571a0cc72d013b9c Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 2 Dec 2010 07:20:39 +0000 Subject: net: emaclite: Omit private ndo_get_stats function xemaclite_get_stats() just returns dev->stats so we can leave it out alltogether and let dev_get_stats() do the job. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/xilinx_emaclite.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 2de52d18152f..de6c3086d232 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1000,21 +1000,6 @@ static int xemaclite_close(struct net_device *dev) return 0; } -/** - * xemaclite_get_stats - Get the stats for the net_device - * @dev: Pointer to the network device - * - * This function returns the address of the 'net_device_stats' structure for the - * given network device. This structure holds usage statistics for the network - * device. - * - * Return: Pointer to the net_device_stats structure. - */ -static struct net_device_stats *xemaclite_get_stats(struct net_device *dev) -{ - return &dev->stats; -} - /** * xemaclite_send - Transmit a frame * @orig_skb: Pointer to the socket buffer to be transmitted @@ -1285,7 +1270,6 @@ static struct net_device_ops xemaclite_netdev_ops = { .ndo_start_xmit = xemaclite_send, .ndo_set_mac_address = xemaclite_set_mac_address, .ndo_tx_timeout = xemaclite_tx_timeout, - .ndo_get_stats = xemaclite_get_stats, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = xemaclite_poll_controller, #endif -- cgit v1.2.3-59-g8ed1b From 40fe7d88ab3eb711b307fab1b92aa6870914c975 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 2 Dec 2010 07:22:05 +0000 Subject: net: cris/eth_v10: Use net_device_stats from struct net_device_stats struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in struct net_local. Note: This patch was not even compile tested. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/cris/eth_v10.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 81475cc80e1c..80c2feeefec5 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -59,7 +59,6 @@ static struct sockaddr default_mac = { /* Information that need to be kept for each board. */ struct net_local { - struct net_device_stats stats; struct mii_if_info mii_if; /* Tx control lock. This protects the transmit buffer ring @@ -1059,7 +1058,7 @@ e100_tx_timeout(struct net_device *dev) /* remember we got an error */ - np->stats.tx_errors++; + dev->stats.tx_errors++; /* reset the TX DMA in case it has hung on something */ @@ -1157,7 +1156,7 @@ e100rxtx_interrupt(int irq, void *dev_id) * allocate a new buffer to put a packet in. */ e100_rx(dev); - np->stats.rx_packets++; + dev->stats.rx_packets++; /* restart/continue on the channel, for safety */ *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart); /* clear dma channel 1 eop/descr irq bits */ @@ -1173,8 +1172,8 @@ e100rxtx_interrupt(int irq, void *dev_id) /* Report any packets that have been sent */ while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST && (netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) { - np->stats.tx_bytes += myFirstTxDesc->skb->len; - np->stats.tx_packets++; + dev->stats.tx_bytes += myFirstTxDesc->skb->len; + dev->stats.tx_packets++; /* dma is ready with the transmission of the data in tx_skb, so now we can release the skb memory */ @@ -1197,7 +1196,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - struct net_local *np = netdev_priv(dev); unsigned long irqbits = *R_IRQ_MASK0_RD; /* check for underrun irq */ @@ -1205,13 +1203,13 @@ e100nw_interrupt(int irq, void *dev_id) SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); - np->stats.tx_errors++; + dev->stats.tx_errors++; D(printk("ethernet receiver underrun!\n")); } /* check for overrun irq */ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) { - update_rx_stats(&np->stats); /* this will ack the irq */ + update_rx_stats(&dev->stats); /* this will ack the irq */ D(printk("ethernet receiver overrun!\n")); } /* check for excessive collision irq */ @@ -1219,7 +1217,7 @@ e100nw_interrupt(int irq, void *dev_id) SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); - np->stats.tx_errors++; + dev->stats.tx_errors++; D(printk("ethernet excessive collisions!\n")); } return IRQ_HANDLED; @@ -1250,7 +1248,7 @@ e100_rx(struct net_device *dev) spin_unlock(&np->led_lock); length = myNextRxDesc->descr.hw_len - 4; - np->stats.rx_bytes += length; + dev->stats.rx_bytes += length; #ifdef ETHDEBUG printk("Got a packet of length %d:\n", length); @@ -1268,7 +1266,7 @@ e100_rx(struct net_device *dev) /* Small packet, copy data */ skb = dev_alloc_skb(length - ETHER_HEAD_LEN); if (!skb) { - np->stats.rx_errors++; + dev->stats.rx_errors++; printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); goto update_nextrxdesc; } @@ -1294,7 +1292,7 @@ e100_rx(struct net_device *dev) int align; struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); if (!new_skb) { - np->stats.rx_errors++; + dev->stats.rx_errors++; printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); goto update_nextrxdesc; } @@ -1333,8 +1331,6 @@ e100_rx(struct net_device *dev) static int e100_close(struct net_device *dev) { - struct net_local *np = netdev_priv(dev); - printk(KERN_INFO "Closing %s.\n", dev->name); netif_stop_queue(dev); @@ -1366,8 +1362,8 @@ e100_close(struct net_device *dev) /* Update the statistics here. */ - update_rx_stats(&np->stats); - update_tx_stats(&np->stats); + update_rx_stats(&dev->stats); + update_tx_stats(&dev->stats); /* Stop speed/duplex timers */ del_timer(&speed_timer); @@ -1545,11 +1541,11 @@ e100_get_stats(struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); - update_rx_stats(&lp->stats); - update_tx_stats(&lp->stats); + update_rx_stats(&dev->stats); + update_tx_stats(&dev->stats); spin_unlock_irqrestore(&lp->lock, flags); - return &lp->stats; + return &dev->stats; } /* -- cgit v1.2.3-59-g8ed1b From ab28c12a8e6fea875b6757052e211772f62fa771 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 6 Dec 2010 22:53:15 +0000 Subject: sfc: Reorder struct efx_nic to separate fields by volatility Place the regularly updated fields (locks, MAC stats, etc.) on a separate cache-line from fields which are mostly constant. This should reduce cache misses for access to the latter on the data path. Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0d19fbfc5c2c..60d63711d43f 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -625,10 +625,8 @@ struct efx_filter_state; * Work items do not hold and must not acquire RTNL. * @workqueue_name: Name of workqueue * @reset_work: Scheduled reset workitem - * @monitor_work: Hardware monitor workitem * @membase_phys: Memory BAR value as physical address * @membase: Memory BAR value - * @biu_lock: BIU (bus interface unit) lock * @interrupt_mode: Interrupt mode * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues * @irq_rx_moderation: IRQ moderation time for RX event queues @@ -652,14 +650,9 @@ struct efx_filter_state; * @int_error_count: Number of internal errors seen recently * @int_error_expire: Time at which error count will be expired * @irq_status: Interrupt status buffer - * @last_irq_cpu: Last CPU to handle interrupt. - * This register is written with the SMP processor ID whenever an - * interrupt is handled. It is used by efx_nic_test_interrupt() - * to verify that an interrupt has occurred. * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 * @fatal_irq_level: IRQ level (bit number) used for serious errors * @mtd_list: List of MTDs attached to the NIC - * @n_rx_nodesc_drop_cnt: RX no descriptor drop count * @nic_data: Hardware dependant state * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, * @port_inhibited, efx_monitor() and efx_reconfigure_port() @@ -672,11 +665,7 @@ struct efx_filter_state; * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock * @rx_checksum_enabled: RX checksumming enabled - * @mac_stats: MAC statistics. These include all statistics the MACs - * can provide. Generic code converts these into a standard - * &struct net_device_stats. * @stats_buffer: DMA buffer for statistics - * @stats_lock: Statistics update lock. Serialises statistics fetches * @mac_op: MAC interface * @phy_type: PHY type * @phy_op: PHY interface @@ -694,10 +683,23 @@ struct efx_filter_state; * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask * @loopback_selftest: Offline self-test private state + * @monitor_work: Hardware monitor workitem + * @biu_lock: BIU (bus interface unit) lock + * @last_irq_cpu: Last CPU to handle interrupt. + * This register is written with the SMP processor ID whenever an + * interrupt is handled. It is used by efx_nic_test_interrupt() + * to verify that an interrupt has occurred. + * @n_rx_nodesc_drop_cnt: RX no descriptor drop count + * @mac_stats: MAC statistics. These include all statistics the MACs + * can provide. Generic code converts these into a standard + * &struct net_device_stats. + * @stats_lock: Statistics update lock. Serialises statistics fetches * * This is stored in the private area of the &struct net_device. */ struct efx_nic { + /* The following fields should be written very rarely */ + char name[IFNAMSIZ]; struct pci_dev *pci_dev; const struct efx_nic_type *type; @@ -705,10 +707,9 @@ struct efx_nic { struct workqueue_struct *workqueue; char workqueue_name[16]; struct work_struct reset_work; - struct delayed_work monitor_work; resource_size_t membase_phys; void __iomem *membase; - spinlock_t biu_lock; + enum efx_int_mode interrupt_mode; bool irq_rx_adaptive; unsigned int irq_rx_moderation; @@ -735,7 +736,6 @@ struct efx_nic { unsigned long int_error_expire; struct efx_buffer irq_status; - volatile signed int last_irq_cpu; unsigned irq_zero_count; unsigned fatal_irq_level; @@ -743,8 +743,6 @@ struct efx_nic { struct list_head mtd_list; #endif - unsigned n_rx_nodesc_drop_cnt; - void *nic_data; struct mutex mac_lock; @@ -756,9 +754,7 @@ struct efx_nic { struct net_device *net_dev; bool rx_checksum_enabled; - struct efx_mac_stats mac_stats; struct efx_buffer stats_buffer; - spinlock_t stats_lock; struct efx_mac_operations *mac_op; @@ -784,6 +780,15 @@ struct efx_nic { void *loopback_selftest; struct efx_filter_state *filter_state; + + /* The following fields may be written more often */ + + struct delayed_work monitor_work ____cacheline_aligned_in_smp; + spinlock_t biu_lock; + volatile signed int last_irq_cpu; + unsigned n_rx_nodesc_drop_cnt; + struct efx_mac_stats mac_stats; + spinlock_t stats_lock; }; static inline int efx_dev_registered(struct efx_nic *efx) -- cgit v1.2.3-59-g8ed1b From 51c56f40ef41ca780ff001d59727eda03fa39374 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 10 Nov 2010 18:46:40 +0000 Subject: sfc: Use ACCESS_ONCE when copying efx_tx_queue::read_count Signed-off-by: Ben Hutchings --- drivers/net/sfc/tx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 03194f7c0954..fef22351ddbd 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -240,8 +240,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) * of read_count. */ smp_mb(); tx_queue->old_read_count = - *(volatile unsigned *) - &tx_queue->read_count; + ACCESS_ONCE(tx_queue->read_count); fill_level = (tx_queue->insert_count - tx_queue->old_read_count); q_space = efx->txq_entries - 1 - fill_level; @@ -764,7 +763,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, * stopped from the access of read_count. */ smp_mb(); tx_queue->old_read_count = - *(volatile unsigned *)&tx_queue->read_count; + ACCESS_ONCE(tx_queue->read_count); fill_level = (tx_queue->insert_count - tx_queue->old_read_count); q_space = efx->txq_entries - 1 - fill_level; -- cgit v1.2.3-59-g8ed1b From 9f2f6cd07a09bc0af1f2950189e426569561d1e6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 6 Dec 2010 22:55:00 +0000 Subject: sfc: Expand/correct comments on collector behaviour and function usage Document exactly which registers and functions have special behaviour, and why races on writes to descriptor pointers are safe. Signed-off-by: Ben Hutchings --- drivers/net/sfc/io.h | 98 ++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 85a99fe87437..0764e84ecc41 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -22,28 +22,39 @@ * * Notes on locking strategy: * - * Most NIC registers require 16-byte (or 8-byte, for SRAM) atomic writes - * which necessitates locking. - * Under normal operation few writes to NIC registers are made and these - * registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and TX_DESC_UPD_REG) are special - * cased to allow 4-byte (hence lockless) accesses. + * Most CSRs are 128-bit (oword) and therefore cannot be read or + * written atomically. Access from the host is buffered by the Bus + * Interface Unit (BIU). Whenever the host reads from the lowest + * address of such a register, or from the address of a different such + * register, the BIU latches the register's value. Subsequent reads + * from higher addresses of the same register will read the latched + * value. Whenever the host writes part of such a register, the BIU + * collects the written value and does not write to the underlying + * register until all 4 dwords have been written. A similar buffering + * scheme applies to host access to the NIC's 64-bit SRAM. * - * It *is* safe to write to these 4-byte registers in the middle of an - * access to an 8-byte or 16-byte register. We therefore use a - * spinlock to protect accesses to the larger registers, but no locks - * for the 4-byte registers. + * Access to different CSRs and 64-bit SRAM words must be serialised, + * since interleaved access can result in lost writes or lost + * information from read-to-clear fields. We use efx_nic::biu_lock + * for this. (We could use separate locks for read and write, but + * this is not normally a performance bottleneck.) * - * A write barrier is needed to ensure that DW3 is written after DW0/1/2 - * due to the way the 16byte registers are "collected" in the BIU. + * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are + * 128-bit but are special-cased in the BIU to avoid the need for + * locking in the host: * - * We also lock when carrying out reads, to ensure consistency of the - * data (made possible since the BIU reads all 128 bits into a cache). - * Reads are very rare, so this isn't a significant performance - * impact. (Most data transferred from NIC to host is DMAed directly - * into host memory). - * - * I/O BAR access uses locks for both reads and writes (but is only provided - * for testing purposes). + * - They are write-only. + * - The semantics of writing to these registers are such that + * replacing the low 96 bits with zero does not affect functionality. + * - If the host writes to the last dword address of such a register + * (i.e. the high 32 bits) the underlying register will always be + * written. If the collector does not hold values for the low 96 + * bits of the register, they will be written as zero. Writing to + * the last qword does not have this effect and must not be done. + * - If the host writes to the address of any other part of such a + * register while the collector already holds values for some other + * register, the write is discarded and the collector maintains its + * current state. */ #if BITS_PER_LONG == 64 @@ -72,7 +83,7 @@ static inline __le32 _efx_readd(struct efx_nic *efx, unsigned int reg) return (__force __le32)__raw_readl(efx->membase + reg); } -/* Writes to a normal 16-byte Efx register, locking as appropriate. */ +/* Write a normal 128-bit CSR, locking as appropriate. */ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, unsigned int reg) { @@ -98,8 +109,7 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, spin_unlock_irqrestore(&efx->biu_lock, flags); } -/* Write an 8-byte NIC SRAM entry through the supplied mapping, - * locking as appropriate. */ +/* Write 64-bit SRAM through the supplied mapping, locking as appropriate. */ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, efx_qword_t *value, unsigned int index) { @@ -122,29 +132,19 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, spin_unlock_irqrestore(&efx->biu_lock, flags); } -/* Write dword to NIC register that allows partial writes - * - * Some registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and - * TX_DESC_UPD_REG) can be written to as a single dword. This allows - * for lockless writes. - */ +/* Write a 32-bit CSR or the last dword of a special 128-bit CSR */ static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, unsigned int reg) { netif_vdbg(efx, hw, efx->net_dev, - "writing partial register %x with "EFX_DWORD_FMT"\n", + "writing register %x with "EFX_DWORD_FMT"\n", reg, EFX_DWORD_VAL(*value)); /* No lock required */ _efx_writed(efx, value->u32[0], reg); } -/* Read from a NIC register - * - * This reads an entire 16-byte register in one go, locking as - * appropriate. It is essential to read the first dword first, as this - * prompts the NIC to load the current value into the shadow register. - */ +/* Read a 128-bit CSR, locking as appropriate. */ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, unsigned int reg) { @@ -163,8 +163,7 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, EFX_OWORD_VAL(*value)); } -/* Read an 8-byte SRAM entry through supplied mapping, - * locking as appropriate. */ +/* Read 64-bit SRAM through the supplied mapping, locking as appropriate. */ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, efx_qword_t *value, unsigned int index) { @@ -186,7 +185,7 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, addr, EFX_QWORD_VAL(*value)); } -/* Read dword from register that allows partial writes (sic) */ +/* Read a 32-bit CSR or SRAM */ static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, unsigned int reg) { @@ -196,28 +195,28 @@ static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, reg, EFX_DWORD_VAL(*value)); } -/* Write to a register forming part of a table */ +/* Write a 128-bit CSR forming part of a table */ static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value, unsigned int reg, unsigned int index) { efx_writeo(efx, value, reg + index * sizeof(efx_oword_t)); } -/* Read to a register forming part of a table */ +/* Read a 128-bit CSR forming part of a table */ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value, unsigned int reg, unsigned int index) { efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); } -/* Write to a dword register forming part of a table */ +/* Write a 32-bit CSR forming part of a table, or 32-bit SRAM */ static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value, unsigned int reg, unsigned int index) { efx_writed(efx, value, reg + index * sizeof(efx_oword_t)); } -/* Read from a dword register forming part of a table */ +/* Read a 32-bit CSR forming part of a table, or 32-bit SRAM */ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, unsigned int reg, unsigned int index) { @@ -231,25 +230,26 @@ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, #define EFX_PAGED_REG(page, reg) \ ((page) * EFX_PAGE_BLOCK_SIZE + (reg)) -/* As for efx_writeo(), but for a page-mapped register. */ +/* Write the whole of RX_DESC_UPD or TX_DESC_UPD */ static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, unsigned int reg, unsigned int page) { efx_writeo(efx, value, EFX_PAGED_REG(page, reg)); } -/* As for efx_writed(), but for a page-mapped register. */ +/* Write a page-mapped 32-bit CSR (EVQ_RPTR or the high bits of + * RX_DESC_UPD or TX_DESC_UPD) + */ static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value, unsigned int reg, unsigned int page) { efx_writed(efx, value, EFX_PAGED_REG(page, reg)); } -/* Write dword to page-mapped register with an extra lock. - * - * As for efx_writed_page(), but for a register that suffers from - * SFC bug 3181. Take out a lock so the BIU collector cannot be - * confused. */ +/* Write TIMER_COMMAND. This is a page-mapped 32-bit CSR, but a bug + * in the BIU means that writes to TIMER_COMMAND[0] invalidate the + * collector register. + */ static inline void efx_writed_page_locked(struct efx_nic *efx, efx_dword_t *value, unsigned int reg, -- cgit v1.2.3-59-g8ed1b From 494bdf1b0fd58688d055f1b66c34b0844dcfc1fa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 6 Dec 2010 22:55:18 +0000 Subject: sfc: Remove redundant memory barriers between MMIOs Signed-off-by: Ben Hutchings --- drivers/net/sfc/io.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 0764e84ecc41..896b31e8606d 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -96,13 +96,11 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, spin_lock_irqsave(&efx->biu_lock, flags); #ifdef EFX_USE_QWORD_IO _efx_writeq(efx, value->u64[0], reg + 0); - wmb(); _efx_writeq(efx, value->u64[1], reg + 8); #else _efx_writed(efx, value->u32[0], reg + 0); _efx_writed(efx, value->u32[1], reg + 4); _efx_writed(efx, value->u32[2], reg + 8); - wmb(); _efx_writed(efx, value->u32[3], reg + 12); #endif mmiowb(); @@ -125,7 +123,6 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, __raw_writeq((__force u64)value->u64[0], membase + addr); #else __raw_writel((__force u32)value->u32[0], membase + addr); - wmb(); __raw_writel((__force u32)value->u32[1], membase + addr + 4); #endif mmiowb(); @@ -152,7 +149,6 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, spin_lock_irqsave(&efx->biu_lock, flags); value->u32[0] = _efx_readd(efx, reg + 0); - rmb(); value->u32[1] = _efx_readd(efx, reg + 4); value->u32[2] = _efx_readd(efx, reg + 8); value->u32[3] = _efx_readd(efx, reg + 12); @@ -175,7 +171,6 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, value->u64[0] = (__force __le64)__raw_readq(membase + addr); #else value->u32[0] = (__force __le32)__raw_readl(membase + addr); - rmb(); value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4); #endif spin_unlock_irqrestore(&efx->biu_lock, flags); -- cgit v1.2.3-59-g8ed1b From 1a29cc40115c011895143c5f8278dee49423d5df Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 6 Dec 2010 22:55:33 +0000 Subject: sfc: Add compile-time checks for correctness of paged register writes Signed-off-by: Ben Hutchings --- drivers/net/sfc/io.h | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 896b31e8606d..7f3adf29d6f6 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -226,29 +226,40 @@ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, ((page) * EFX_PAGE_BLOCK_SIZE + (reg)) /* Write the whole of RX_DESC_UPD or TX_DESC_UPD */ -static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, - unsigned int reg, unsigned int page) +static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, + unsigned int reg, unsigned int page) { efx_writeo(efx, value, EFX_PAGED_REG(page, reg)); } +#define efx_writeo_page(efx, value, reg, page) \ + _efx_writeo_page(efx, value, \ + reg + \ + BUILD_BUG_ON_ZERO((reg) != 0x830 && (reg) != 0xa10), \ + page) /* Write a page-mapped 32-bit CSR (EVQ_RPTR or the high bits of * RX_DESC_UPD or TX_DESC_UPD) */ -static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value, - unsigned int reg, unsigned int page) +static inline void _efx_writed_page(struct efx_nic *efx, efx_dword_t *value, + unsigned int reg, unsigned int page) { efx_writed(efx, value, EFX_PAGED_REG(page, reg)); } +#define efx_writed_page(efx, value, reg, page) \ + _efx_writed_page(efx, value, \ + reg + \ + BUILD_BUG_ON_ZERO((reg) != 0x400 && (reg) != 0x83c \ + && (reg) != 0xa1c), \ + page) /* Write TIMER_COMMAND. This is a page-mapped 32-bit CSR, but a bug * in the BIU means that writes to TIMER_COMMAND[0] invalidate the * collector register. */ -static inline void efx_writed_page_locked(struct efx_nic *efx, - efx_dword_t *value, - unsigned int reg, - unsigned int page) +static inline void _efx_writed_page_locked(struct efx_nic *efx, + efx_dword_t *value, + unsigned int reg, + unsigned int page) { unsigned long flags __attribute__ ((unused)); @@ -260,5 +271,9 @@ static inline void efx_writed_page_locked(struct efx_nic *efx, efx_writed(efx, value, EFX_PAGED_REG(page, reg)); } } +#define efx_writed_page_locked(efx, value, reg, page) \ + _efx_writed_page_locked(efx, value, \ + reg + BUILD_BUG_ON_ZERO((reg) != 0x420), \ + page) #endif /* EFX_IO_H */ -- cgit v1.2.3-59-g8ed1b From e506147271229d6c53b42c6a9897db67b5cfdb6d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 6 Dec 2010 22:58:41 +0000 Subject: sfc: Remove locking from implementation of efx_writeo_paged() It is not necessary to serialise writes to the paged 128-bit registers. However, if we don't then we must always write the last dword separately, not as part of a qword write. Signed-off-by: Ben Hutchings --- drivers/net/sfc/io.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 7f3adf29d6f6..6da4ae20a039 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -229,7 +229,20 @@ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, unsigned int reg, unsigned int page) { - efx_writeo(efx, value, EFX_PAGED_REG(page, reg)); + reg = EFX_PAGED_REG(page, reg); + + netif_vdbg(efx, hw, efx->net_dev, + "writing register %x with " EFX_OWORD_FMT "\n", reg, + EFX_OWORD_VAL(*value)); + +#ifdef EFX_USE_QWORD_IO + _efx_writeq(efx, value->u64[0], reg + 0); +#else + _efx_writed(efx, value->u32[0], reg + 0); + _efx_writed(efx, value->u32[1], reg + 4); +#endif + _efx_writed(efx, value->u32[2], reg + 8); + _efx_writed(efx, value->u32[3], reg + 12); } #define efx_writeo_page(efx, value, reg, page) \ _efx_writeo_page(efx, value, \ -- cgit v1.2.3-59-g8ed1b From cd38557d78554fd4318fe448f728a8d7ff1cbabb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 15 Nov 2010 23:53:11 +0000 Subject: sfc: Use TX push whenever adding descriptors to an empty queue Whenever we add DMA descriptors to a TX ring and update the ring pointer, the TX DMA engine must first read the new DMA descriptors and then start reading packet data. However, all released Solarflare 10G controllers have a 'TX push' feature that allows us to reduce latency by writing the first new DMA descriptor along with the pointer update. This is only useful when the queue is empty. The hardware should ignore the pushed descriptor if the queue is not empty, but this check is buggy, so we must do it in software. In order to tell whether a TX queue is empty, we need to compare the previous transmission count (write_count) and completion count (read_count). However, if we do that every time we update the ring pointer then read_count may ping-pong between the caches of two CPUs running the transmission and completion paths for the queue. Therefore, we split the check for an empty queue between the completion path and the transmission path: - Add an empty_read_count field representing a point at which the completion path saw the TX queue as empty. - Add an old_write_count field for use on the completion path. - On the completion path, whenever read_count reaches or passes old_write_count the TX queue may be empty. We then read write_count, set empty_read_count if read_count == write_count, and update old_write_count. - On the transmission path, we read empty_read_count. If it's set, we compare it with the value of write_count before the current set of descriptors was added. If they match, the queue really is empty and we can use TX push. Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 16 ++++++++++++++++ drivers/net/sfc/nic.c | 42 ++++++++++++++++++++++++++++++++++++++++-- drivers/net/sfc/tx.c | 12 ++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 60d63711d43f..270e217a53f9 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -142,6 +142,12 @@ struct efx_tx_buffer { * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. + * @old_write_count: The value of @write_count when last checked. + * This is here for performance reasons. The xmit path will + * only get the up-to-date value of @write_count if this + * variable indicates that the queue is empty. This is to + * avoid cache-line ping-pong between the xmit path and the + * completion path. * @stopped: Stopped count. * Set if this TX queue is currently stopping its port. * @insert_count: Current insert pointer @@ -163,6 +169,10 @@ struct efx_tx_buffer { * @tso_long_headers: Number of packets with headers too long for standard * blocks * @tso_packets: Number of packets via the TSO xmit path + * @pushes: Number of times the TX push feature has been used + * @empty_read_count: If the completion path has seen the queue as empty + * and the transmission path has not yet checked this, the value of + * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0. */ struct efx_tx_queue { /* Members which don't change on the fast path */ @@ -177,6 +187,7 @@ struct efx_tx_queue { /* Members used mainly on the completion path */ unsigned int read_count ____cacheline_aligned_in_smp; + unsigned int old_write_count; int stopped; /* Members used only on the xmit path */ @@ -187,6 +198,11 @@ struct efx_tx_queue { unsigned int tso_bursts; unsigned int tso_long_headers; unsigned int tso_packets; + unsigned int pushes; + + /* Members shared between paths and sometimes updated */ + unsigned int empty_read_count ____cacheline_aligned_in_smp; +#define EFX_EMPTY_COUNT_VALID 0x80000000 }; /** diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 9743cff15130..bda6b1bd072c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -362,6 +362,35 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue) FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); } +/* Write pointer and first descriptor for TX descriptor ring */ +static inline void efx_push_tx_desc(struct efx_tx_queue *tx_queue, + const efx_qword_t *txd) +{ + unsigned write_ptr; + efx_oword_t reg; + + BUILD_BUG_ON(FRF_AZ_TX_DESC_LBN != 0); + BUILD_BUG_ON(FR_AA_TX_DESC_UPD_KER != FR_BZ_TX_DESC_UPD_P0); + + write_ptr = tx_queue->write_count & tx_queue->ptr_mask; + EFX_POPULATE_OWORD_2(reg, FRF_AZ_TX_DESC_PUSH_CMD, true, + FRF_AZ_TX_DESC_WPTR, write_ptr); + reg.qword[0] = *txd; + efx_writeo_page(tx_queue->efx, ®, + FR_BZ_TX_DESC_UPD_P0, tx_queue->queue); +} + +static inline bool +efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count) +{ + unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count); + + if (empty_read_count == 0) + return false; + + tx_queue->empty_read_count = 0; + return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0; +} /* For each entry inserted into the software descriptor ring, create a * descriptor in the hardware TX descriptor ring (in host memory), and @@ -373,6 +402,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) struct efx_tx_buffer *buffer; efx_qword_t *txd; unsigned write_ptr; + unsigned old_write_count = tx_queue->write_count; BUG_ON(tx_queue->write_count == tx_queue->insert_count); @@ -391,7 +421,15 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) } while (tx_queue->write_count != tx_queue->insert_count); wmb(); /* Ensure descriptors are written before they are fetched */ - efx_notify_tx_desc(tx_queue); + + if (efx_may_push_tx_desc(tx_queue, old_write_count)) { + txd = efx_tx_desc(tx_queue, + old_write_count & tx_queue->ptr_mask); + efx_push_tx_desc(tx_queue, txd); + ++tx_queue->pushes; + } else { + efx_notify_tx_desc(tx_queue); + } } /* Allocate hardware resources for a TX queue */ @@ -1626,7 +1664,7 @@ void efx_nic_init_common(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 1); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1); /* Enable SW_EV to inherit in char driver - assume harmless here */ EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index fef22351ddbd..bdb92b4af683 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -428,6 +428,16 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) __netif_tx_unlock(queue); } } + + /* Check whether the hardware queue is now empty */ + if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) { + tx_queue->old_write_count = ACCESS_ONCE(tx_queue->write_count); + if (tx_queue->read_count == tx_queue->old_write_count) { + smp_mb(); + tx_queue->empty_read_count = + tx_queue->read_count | EFX_EMPTY_COUNT_VALID; + } + } } int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) @@ -473,8 +483,10 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) tx_queue->insert_count = 0; tx_queue->write_count = 0; + tx_queue->old_write_count = 0; tx_queue->read_count = 0; tx_queue->old_read_count = 0; + tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID; BUG_ON(tx_queue->stopped); /* Set up TX descriptor ring */ -- cgit v1.2.3-59-g8ed1b From cfa969e385a23e4c85f50e0ed5de25a2e18bf9d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Dec 2010 20:45:28 -0800 Subject: Revert "ehea: Use the standard logging functions" This reverts commit 539995d18649023199986424d140f1d620372ce5. As reported by Stephen Rothwell, this breaks the build. Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 13 ++ drivers/net/ehea/ehea_ethtool.c | 18 +- drivers/net/ehea/ehea_main.c | 407 ++++++++++++++++++++-------------------- drivers/net/ehea/ehea_phyp.c | 40 ++-- drivers/net/ehea/ehea_qmr.c | 89 +++++---- 5 files changed, 293 insertions(+), 274 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 45e709f7609f..8e745e74828d 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -130,6 +130,19 @@ /* utility functions */ +#define ehea_info(fmt, args...) \ + printk(KERN_INFO DRV_NAME ": " fmt "\n", ## args) + +#define ehea_error(fmt, args...) \ + printk(KERN_ERR DRV_NAME ": Error in %s: " fmt "\n", __func__, ## args) + +#ifdef DEBUG +#define ehea_debug(fmt, args...) \ + printk(KERN_DEBUG DRV_NAME ": " fmt, ## args) +#else +#define ehea_debug(fmt, args...) do {} while (0) +#endif + void ehea_dump(void *adr, int len, char *msg); #define EHEA_BMASK(pos, length) (((pos) << 16) + (length)) diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 273fedbb6d0e..75b099ce49c9 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -26,8 +26,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "ehea.h" #include "ehea_phyp.h" @@ -120,10 +118,10 @@ doit: ret = ehea_set_portspeed(port, sp); if (!ret) - netdev_info(dev, - "Port speed successfully set: %dMbps %s Duplex\n", - port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + ehea_info("%s: Port speed successfully set: %dMbps " + "%s Duplex", + port->netdev->name, port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); out: return ret; } @@ -136,10 +134,10 @@ static int ehea_nway_reset(struct net_device *dev) ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); if (!ret) - netdev_info(port->netdev, - "Port speed successfully set: %dMbps %s Duplex\n", - port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + ehea_info("%s: Port speed successfully set: %dMbps " + "%s Duplex", + port->netdev->name, port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); return ret; } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f700c76d3e60..a84c389d3db7 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -26,8 +26,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -138,8 +136,8 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - pr_info("%s adr=%p ofs=%04x %016llx %016llx\n", - msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); + printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, + deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } } @@ -339,7 +337,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) cb2 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb2) { - netdev_err(dev, "no mem for cb2\n"); + ehea_error("no mem for cb2"); goto out; } @@ -347,7 +345,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) port->logical_port_id, H_PORT_CB2, H_PORT_CB2_ALL, cb2); if (hret != H_SUCCESS) { - netdev_err(dev, "query_ehea_port failed\n"); + ehea_error("query_ehea_port failed"); goto out_herr; } @@ -463,9 +461,8 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, if (!skb) { q_skba->os_skbs = fill_wqes - i; if (q_skba->os_skbs == q_skba->len - 2) { - netdev_info(pr->port->netdev, - "rq%i ran dry - no mem for skb\n", - rq_nr); + ehea_info("%s: rq%i ran dry - no mem for skb", + pr->port->netdev->name, rq_nr); ret = -ENOMEM; } break; @@ -630,8 +627,8 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) { if (netif_msg_rx_err(pr->port)) { - pr_err("Critical receive error for QP %d. Resetting port.\n", - pr->qp->init_attr.qp_nr); + ehea_error("Critical receive error for QP %d. " + "Resetting port.", pr->qp->init_attr.qp_nr); ehea_dump(cqe, sizeof(*cqe), "CQE"); } ehea_schedule_port_reset(pr->port); @@ -733,8 +730,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb_arr_rq1_len, wqe_index); if (unlikely(!skb)) { - netif_err(port, rx_err, dev, - "LL rq1: skb=NULL\n"); + if (netif_msg_rx_err(port)) + ehea_error("LL rq1: skb=NULL"); skb = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); @@ -749,8 +746,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq2, skb_arr_rq2_len, cqe); if (unlikely(!skb)) { - netif_err(port, rx_err, dev, - "rq2: skb=NULL\n"); + if (netif_msg_rx_err(port)) + ehea_error("rq2: skb=NULL"); break; } ehea_fill_skb(dev, skb, cqe); @@ -760,8 +757,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq3, skb_arr_rq3_len, cqe); if (unlikely(!skb)) { - netif_err(port, rx_err, dev, - "rq3: skb=NULL\n"); + if (netif_msg_rx_err(port)) + ehea_error("rq3: skb=NULL"); break; } ehea_fill_skb(dev, skb, cqe); @@ -833,7 +830,7 @@ static void check_sqs(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - pr_err("HW/SW queues out of sync\n"); + ehea_error("HW/SW queues out of sync"); ehea_schedule_port_reset(pr->port); return; } @@ -866,14 +863,14 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) } if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { - pr_err("Bad send completion status=0x%04X\n", - cqe->status); + ehea_error("Bad send completion status=0x%04X", + cqe->status); if (netif_msg_tx_err(pr->port)) ehea_dump(cqe, sizeof(*cqe), "Send CQE"); if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { - pr_err("Resetting port\n"); + ehea_error("Resetting port"); ehea_schedule_port_reset(pr->port); break; } @@ -991,8 +988,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - pr_err("QP aff_err: entry=0x%llx, token=0x%x\n", - eqe->entry, qp_token); + ehea_error("QP aff_err: entry=0x%llx, token=0x%x", + eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1010,7 +1007,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) } if (reset_port) { - pr_err("Resetting port\n"); + ehea_error("Resetting port"); ehea_schedule_port_reset(port); } @@ -1038,7 +1035,7 @@ int ehea_sense_port_attr(struct ehea_port *port) /* may be called via ehea_neq_tasklet() */ cb0 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb0) { - pr_err("no mem for cb0\n"); + ehea_error("no mem for cb0"); ret = -ENOMEM; goto out; } @@ -1130,7 +1127,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - pr_err("no mem for cb4\n"); + ehea_error("no mem for cb4"); ret = -ENOMEM; goto out; } @@ -1181,16 +1178,16 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) break; } } else { - pr_err("Failed sensing port speed\n"); + ehea_error("Failed sensing port speed"); ret = -EIO; } } else { if (hret == H_AUTHORITY) { - pr_info("Hypervisor denied setting port speed\n"); + ehea_info("Hypervisor denied setting port speed"); ret = -EPERM; } else { ret = -EIO; - pr_err("Failed setting port speed\n"); + ehea_error("Failed setting port speed"); } } if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP)) @@ -1207,78 +1204,80 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) u8 ec; u8 portnum; struct ehea_port *port; - struct net_device *dev; ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe); portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe); port = ehea_get_port(adapter, portnum); - dev = port->netdev; switch (ec) { case EHEA_EC_PORTSTATE_CHG: /* port state change */ if (!port) { - netdev_err(dev, "unknown portnum %x\n", portnum); + ehea_error("unknown portnum %x", portnum); break; } if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { - if (!netif_carrier_ok(dev)) { + if (!netif_carrier_ok(port->netdev)) { ret = ehea_sense_port_attr(port); if (ret) { - netdev_err(dev, "failed resensing port attributes\n"); + ehea_error("failed resensing port " + "attributes"); break; } - netif_info(port, link, dev, - "Logical port up: %dMbps %s Duplex\n", - port->port_speed, - port->full_duplex == 1 ? - "Full" : "Half"); + if (netif_msg_link(port)) + ehea_info("%s: Logical port up: %dMbps " + "%s Duplex", + port->netdev->name, + port->port_speed, + port->full_duplex == + 1 ? "Full" : "Half"); - netif_carrier_on(dev); - netif_wake_queue(dev); + netif_carrier_on(port->netdev); + netif_wake_queue(port->netdev); } } else - if (netif_carrier_ok(dev)) { - netif_info(port, link, dev, - "Logical port down\n"); - netif_carrier_off(dev); - netif_stop_queue(dev); + if (netif_carrier_ok(port->netdev)) { + if (netif_msg_link(port)) + ehea_info("%s: Logical port down", + port->netdev->name); + netif_carrier_off(port->netdev); + netif_stop_queue(port->netdev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) { port->phy_link = EHEA_PHY_LINK_UP; - netif_info(port, link, dev, - "Physical port up\n"); + if (netif_msg_link(port)) + ehea_info("%s: Physical port up", + port->netdev->name); if (prop_carrier_state) - netif_carrier_on(dev); + netif_carrier_on(port->netdev); } else { port->phy_link = EHEA_PHY_LINK_DOWN; - netif_info(port, link, dev, - "Physical port down\n"); + if (netif_msg_link(port)) + ehea_info("%s: Physical port down", + port->netdev->name); if (prop_carrier_state) - netif_carrier_off(dev); + netif_carrier_off(port->netdev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe)) - netdev_info(dev, - "External switch port is primary port\n"); + ehea_info("External switch port is primary port"); else - netdev_info(dev, - "External switch port is backup port\n"); + ehea_info("External switch port is backup port"); break; case EHEA_EC_ADAPTER_MALFUNC: - netdev_err(dev, "Adapter malfunction\n"); + ehea_error("Adapter malfunction"); break; case EHEA_EC_PORT_MALFUNC: - netdev_info(dev, "Port malfunction\n"); - netif_carrier_off(dev); - netif_stop_queue(dev); + ehea_info("Port malfunction: Device: %s", port->netdev->name); + netif_carrier_off(port->netdev); + netif_stop_queue(port->netdev); break; default: - netdev_err(dev, "unknown event code %x, eqe=0x%llX\n", ec, eqe); + ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); break; } } @@ -1290,13 +1289,13 @@ static void ehea_neq_tasklet(unsigned long data) u64 event_mask; eqe = ehea_poll_eq(adapter->neq); - pr_debug("eqe=%p\n", eqe); + ehea_debug("eqe=%p", eqe); while (eqe) { - pr_debug("*eqe=%lx\n", eqe->entry); + ehea_debug("*eqe=%lx", eqe->entry); ehea_parse_eqe(adapter, eqe->entry); eqe = ehea_poll_eq(adapter->neq); - pr_debug("next eqe=%p\n", eqe); + ehea_debug("next eqe=%p", eqe); } event_mask = EHEA_BMASK_SET(NELR_PORTSTATE_CHG, 1) @@ -1345,14 +1344,14 @@ static int ehea_reg_interrupts(struct net_device *dev) ehea_qp_aff_irq_handler, IRQF_DISABLED, port->int_aff_name, port); if (ret) { - netdev_err(dev, "failed registering irq for qp_aff_irq_handler:ist=%X\n", - port->qp_eq->attr.ist1); + ehea_error("failed registering irq for qp_aff_irq_handler:" + "ist=%X", port->qp_eq->attr.ist1); goto out_free_qpeq; } - netif_info(port, ifup, dev, - "irq_handle 0x%X for function qp_aff_irq_handler registered\n", - port->qp_eq->attr.ist1); + if (netif_msg_ifup(port)) + ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " + "registered", port->qp_eq->attr.ist1); for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { @@ -1364,13 +1363,14 @@ static int ehea_reg_interrupts(struct net_device *dev) IRQF_DISABLED, pr->int_send_name, pr); if (ret) { - netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n", - i, pr->eq->attr.ist1); + ehea_error("failed registering irq for ehea_queue " + "port_res_nr:%d, ist=%X", i, + pr->eq->attr.ist1); goto out_free_req; } - netif_info(port, ifup, dev, - "irq_handle 0x%X for function ehea_queue_int %d registered\n", - pr->eq->attr.ist1, i); + if (netif_msg_ifup(port)) + ehea_info("irq_handle 0x%X for function ehea_queue_int " + "%d registered", pr->eq->attr.ist1, i); } out: return ret; @@ -1401,16 +1401,16 @@ static void ehea_free_interrupts(struct net_device *dev) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { pr = &port->port_res[i]; ibmebus_free_irq(pr->eq->attr.ist1, pr); - netif_info(port, intr, dev, - "free send irq for res %d with handle 0x%X\n", - i, pr->eq->attr.ist1); + if (netif_msg_intr(port)) + ehea_info("free send irq for res %d with handle 0x%X", + i, pr->eq->attr.ist1); } /* associated events */ ibmebus_free_irq(port->qp_eq->attr.ist1, port); - netif_info(port, intr, dev, - "associated event interrupt for handle 0x%X freed\n", - port->qp_eq->attr.ist1); + if (netif_msg_intr(port)) + ehea_info("associated event interrupt for handle 0x%X freed", + port->qp_eq->attr.ist1); } static int ehea_configure_port(struct ehea_port *port) @@ -1479,7 +1479,7 @@ int ehea_gen_smrs(struct ehea_port_res *pr) out_free: ehea_rem_mr(&pr->send_mr); out: - pr_err("Generating SMRS failed\n"); + ehea_error("Generating SMRS failed\n"); return -EIO; } @@ -1534,7 +1534,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); if (!pr->eq) { - pr_err("create_eq failed (eq)\n"); + ehea_error("create_eq failed (eq)"); goto out_free; } @@ -1542,7 +1542,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->recv_cq) { - pr_err("create_cq failed (cq_recv)\n"); + ehea_error("create_cq failed (cq_recv)"); goto out_free; } @@ -1550,19 +1550,19 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->send_cq) { - pr_err("create_cq failed (cq_send)\n"); + ehea_error("create_cq failed (cq_send)"); goto out_free; } if (netif_msg_ifup(port)) - pr_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d\n", - pr->send_cq->attr.act_nr_of_cqes, - pr->recv_cq->attr.act_nr_of_cqes); + ehea_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d", + pr->send_cq->attr.act_nr_of_cqes, + pr->recv_cq->attr.act_nr_of_cqes); init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL); if (!init_attr) { ret = -ENOMEM; - pr_err("no mem for ehea_qp_init_attr\n"); + ehea_error("no mem for ehea_qp_init_attr"); goto out_free; } @@ -1587,18 +1587,18 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->qp = ehea_create_qp(adapter, adapter->pd, init_attr); if (!pr->qp) { - pr_err("create_qp failed\n"); + ehea_error("create_qp failed"); ret = -EIO; goto out_free; } if (netif_msg_ifup(port)) - pr_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d\n", - init_attr->qp_nr, - init_attr->act_nr_send_wqes, - init_attr->act_nr_rwqes_rq1, - init_attr->act_nr_rwqes_rq2, - init_attr->act_nr_rwqes_rq3); + ehea_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n " + "nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d", init_attr->qp_nr, + init_attr->act_nr_send_wqes, + init_attr->act_nr_rwqes_rq1, + init_attr->act_nr_rwqes_rq2, + init_attr->act_nr_rwqes_rq3); pr->sq_skba_size = init_attr->act_nr_send_wqes + 1; @@ -1749,7 +1749,7 @@ static void write_swqe2_TSO(struct sk_buff *skb, swqe->descriptors++; } } else - pr_err("cannot handle fragmented headers\n"); + ehea_error("cannot handle fragmented headers"); } static void write_swqe2_nonTSO(struct sk_buff *skb, @@ -1845,8 +1845,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - pr_err("%sregistering bc address failed (tagged)\n", - hcallid == H_REG_BCMC ? "" : "de"); + ehea_error("%sregistering bc address failed (tagged)", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; goto out_herr; } @@ -1857,8 +1857,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - pr_err("%sregistering bc address failed (vlan)\n", - hcallid == H_REG_BCMC ? "" : "de"); + ehea_error("%sregistering bc address failed (vlan)", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; } out_herr: @@ -1880,7 +1880,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) cb0 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb0) { - pr_err("no mem for cb0\n"); + ehea_error("no mem for cb0"); ret = -ENOMEM; goto out; } @@ -1928,11 +1928,11 @@ out: static void ehea_promiscuous_error(u64 hret, int enable) { if (hret == H_AUTHORITY) - pr_info("Hypervisor denied %sabling promiscuous mode\n", - enable == 1 ? "en" : "dis"); + ehea_info("Hypervisor denied %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); else - pr_err("failed %sabling promiscuous mode\n", - enable == 1 ? "en" : "dis"); + ehea_error("failed %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); } static void ehea_promiscuous(struct net_device *dev, int enable) @@ -1946,7 +1946,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) cb7 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb7) { - pr_err("no mem for cb7\n"); + ehea_error("no mem for cb7"); goto out; } @@ -2006,7 +2006,7 @@ static int ehea_drop_multicast_list(struct net_device *dev) hret = ehea_multicast_reg_helper(port, mc_entry->macaddr, H_DEREG_BCMC); if (hret) { - pr_err("failed deregistering mcast MAC\n"); + ehea_error("failed deregistering mcast MAC"); ret = -EIO; } @@ -2029,8 +2029,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 1; else - netdev_err(dev, - "failed enabling IFF_ALLMULTI\n"); + ehea_error("failed enabling IFF_ALLMULTI"); } } else if (!enable) { @@ -2039,8 +2038,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 0; else - netdev_err(dev, - "failed disabling IFF_ALLMULTI\n"); + ehea_error("failed disabling IFF_ALLMULTI"); } } @@ -2051,7 +2049,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); if (!ehea_mcl_entry) { - pr_err("no mem for mcl_entry\n"); + ehea_error("no mem for mcl_entry"); return; } @@ -2064,7 +2062,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) if (!hret) list_add(&ehea_mcl_entry->list, &port->mc_list->list); else { - pr_err("failed registering mcast MAC\n"); + ehea_error("failed registering mcast MAC"); kfree(ehea_mcl_entry); } } @@ -2097,8 +2095,9 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (netdev_mc_count(dev) > port->adapter->max_mc_mac) { - pr_info("Mcast registration limit reached (0x%llx). Use ALLMULTI!\n", - port->adapter->max_mc_mac); + ehea_info("Mcast registration limit reached (0x%llx). " + "Use ALLMULTI!", + port->adapter->max_mc_mac); goto out; } @@ -2304,10 +2303,10 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - netif_info(port, tx_queued, dev, - "post swqe on QP %d\n", pr->qp->init_attr.qp_nr); - if (netif_msg_tx_queued(port)) + if (netif_msg_tx_queued(port)) { + ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); ehea_dump(swqe, 512, "swqe"); + } if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { netif_stop_queue(dev); @@ -2343,14 +2342,14 @@ static void ehea_vlan_rx_register(struct net_device *dev, cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - pr_err("no mem for cb1\n"); + ehea_error("no mem for cb1"); goto out; } hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - pr_err("modify_ehea_port failed\n"); + ehea_error("modify_ehea_port failed"); free_page((unsigned long)cb1); out: @@ -2367,14 +2366,14 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - pr_err("no mem for cb1\n"); + ehea_error("no mem for cb1"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - pr_err("query_ehea_port failed\n"); + ehea_error("query_ehea_port failed"); goto out; } @@ -2384,7 +2383,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - pr_err("modify_ehea_port failed\n"); + ehea_error("modify_ehea_port failed"); out: free_page((unsigned long)cb1); return; @@ -2402,14 +2401,14 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - pr_err("no mem for cb1\n"); + ehea_error("no mem for cb1"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - pr_err("query_ehea_port failed\n"); + ehea_error("query_ehea_port failed"); goto out; } @@ -2419,7 +2418,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - pr_err("modify_ehea_port failed\n"); + ehea_error("modify_ehea_port failed"); out: free_page((unsigned long)cb1); } @@ -2441,7 +2440,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (1)\n"); + ehea_error("query_ehea_qp failed (1)"); goto out; } @@ -2450,14 +2449,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - pr_err("modify_ehea_qp failed (1)\n"); + ehea_error("modify_ehea_qp failed (1)"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (2)\n"); + ehea_error("query_ehea_qp failed (2)"); goto out; } @@ -2466,14 +2465,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - pr_err("modify_ehea_qp failed (2)\n"); + ehea_error("modify_ehea_qp failed (2)"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (3)\n"); + ehea_error("query_ehea_qp failed (3)"); goto out; } @@ -2482,14 +2481,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - pr_err("modify_ehea_qp failed (3)\n"); + ehea_error("modify_ehea_qp failed (3)"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (4)\n"); + ehea_error("query_ehea_qp failed (4)"); goto out; } @@ -2510,7 +2509,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps, EHEA_MAX_ENTRIES_EQ, 1); if (!port->qp_eq) { ret = -EINVAL; - pr_err("ehea_create_eq failed (qp_eq)\n"); + ehea_error("ehea_create_eq failed (qp_eq)"); goto out_kill_eq; } @@ -2591,27 +2590,27 @@ static int ehea_up(struct net_device *dev) ret = ehea_port_res_setup(port, port->num_def_qps, port->num_add_tx_qps); if (ret) { - netdev_err(dev, "port_res_failed\n"); + ehea_error("port_res_failed"); goto out; } /* Set default QP for this port */ ret = ehea_configure_port(port); if (ret) { - netdev_err(dev, "ehea_configure_port failed. ret:%d\n", ret); + ehea_error("ehea_configure_port failed. ret:%d", ret); goto out_clean_pr; } ret = ehea_reg_interrupts(dev); if (ret) { - netdev_err(dev, "reg_interrupts failed. ret:%d\n", ret); + ehea_error("reg_interrupts failed. ret:%d", ret); goto out_clean_pr; } for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { ret = ehea_activate_qp(port->adapter, port->port_res[i].qp); if (ret) { - netdev_err(dev, "activate_qp failed\n"); + ehea_error("activate_qp failed"); goto out_free_irqs; } } @@ -2619,7 +2618,7 @@ static int ehea_up(struct net_device *dev) for (i = 0; i < port->num_def_qps; i++) { ret = ehea_fill_port_res(&port->port_res[i]); if (ret) { - netdev_err(dev, "out_free_irqs\n"); + ehea_error("out_free_irqs"); goto out_free_irqs; } } @@ -2642,7 +2641,7 @@ out_clean_pr: ehea_clean_all_portres(port); out: if (ret) - netdev_info(dev, "Failed starting. ret=%i\n", ret); + ehea_info("Failed starting %s. ret=%i", dev->name, ret); ehea_update_bcmc_registrations(); ehea_update_firmware_handles(); @@ -2673,7 +2672,8 @@ static int ehea_open(struct net_device *dev) mutex_lock(&port->port_lock); - netif_info(port, ifup, dev, "enabling port\n"); + if (netif_msg_ifup(port)) + ehea_info("enabling port %s", dev->name); ret = ehea_up(dev); if (!ret) { @@ -2708,7 +2708,8 @@ static int ehea_down(struct net_device *dev) ret = ehea_clean_all_portres(port); if (ret) - netdev_info(dev, "Failed freeing resources. ret=%i\n", ret); + ehea_info("Failed freeing resources for %s. ret=%i", + dev->name, ret); ehea_update_firmware_handles(); @@ -2720,7 +2721,8 @@ static int ehea_stop(struct net_device *dev) int ret; struct ehea_port *port = netdev_priv(dev); - netif_info(port, ifdown, dev, "disabling port\n"); + if (netif_msg_ifdown(port)) + ehea_info("disabling port %s", dev->name); set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); cancel_work_sync(&port->reset_task); @@ -2761,7 +2763,7 @@ static void ehea_flush_sq(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - pr_err("WARNING: sq not flushed completely\n"); + ehea_error("WARNING: sq not flushed completely"); break; } } @@ -2797,7 +2799,7 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (1)\n"); + ehea_error("query_ehea_qp failed (1)"); goto out; } @@ -2809,7 +2811,7 @@ int ehea_stop_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - pr_err("modify_ehea_qp failed (1)\n"); + ehea_error("modify_ehea_qp failed (1)"); goto out; } @@ -2817,14 +2819,14 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - pr_err("query_ehea_qp failed (2)\n"); + ehea_error("query_ehea_qp failed (2)"); goto out; } /* deregister shared memory regions */ dret = ehea_rem_smrs(pr); if (dret) { - pr_err("unreg shared memory region failed\n"); + ehea_error("unreg shared memory region failed"); goto out; } } @@ -2893,7 +2895,7 @@ int ehea_restart_qps(struct net_device *dev) ret = ehea_gen_smrs(pr); if (ret) { - netdev_err(dev, "creation of shared memory regions failed\n"); + ehea_error("creation of shared memory regions failed"); goto out; } @@ -2904,7 +2906,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - netdev_err(dev, "query_ehea_qp failed (1)\n"); + ehea_error("query_ehea_qp failed (1)"); goto out; } @@ -2916,7 +2918,7 @@ int ehea_restart_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - netdev_err(dev, "modify_ehea_qp failed (1)\n"); + ehea_error("modify_ehea_qp failed (1)"); goto out; } @@ -2924,7 +2926,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - netdev_err(dev, "query_ehea_qp failed (2)\n"); + ehea_error("query_ehea_qp failed (2)"); goto out; } @@ -2961,7 +2963,8 @@ static void ehea_reset_port(struct work_struct *work) ehea_set_multicast_list(dev); - netif_info(port, timer, dev, "reset successful\n"); + if (netif_msg_timer(port)) + ehea_info("Device %s resetted successfully", dev->name); port_napi_enable(port); @@ -2976,7 +2979,7 @@ static void ehea_rereg_mrs(struct work_struct *work) int ret, i; struct ehea_adapter *adapter; - pr_info("LPAR memory changed - re-initializing driver\n"); + ehea_info("LPAR memory changed - re-initializing driver"); list_for_each_entry(adapter, &adapter_list, list) if (adapter->active_ports) { @@ -3008,7 +3011,8 @@ static void ehea_rereg_mrs(struct work_struct *work) /* Unregister old memory region */ ret = ehea_rem_mr(&adapter->mr); if (ret) { - pr_err("unregister MR failed - driver inoperable!\n"); + ehea_error("unregister MR failed - driver" + " inoperable!"); goto out; } } @@ -3020,7 +3024,8 @@ static void ehea_rereg_mrs(struct work_struct *work) /* Register new memory region */ ret = ehea_reg_kernel_mr(adapter, &adapter->mr); if (ret) { - pr_err("register MR failed - driver inoperable!\n"); + ehea_error("register MR failed - driver" + " inoperable!"); goto out; } @@ -3043,7 +3048,7 @@ static void ehea_rereg_mrs(struct work_struct *work) } } } - pr_info("re-initializing driver complete\n"); + ehea_info("re-initializing driver complete"); out: return; } @@ -3096,7 +3101,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo) /* (Try to) enable *jumbo frames */ cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - pr_err("no mem for cb4\n"); + ehea_error("no mem for cb4"); ret = -ENOMEM; goto out; } else { @@ -3158,13 +3163,13 @@ static struct device *ehea_register_port(struct ehea_port *port, ret = of_device_register(&port->ofdev); if (ret) { - pr_err("failed to register device. ret=%d\n", ret); + ehea_error("failed to register device. ret=%d", ret); goto out; } ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); if (ret) { - pr_err("failed to register attributes, ret=%d\n", ret); + ehea_error("failed to register attributes, ret=%d", ret); goto out_unreg_of_dev; } @@ -3214,7 +3219,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev = alloc_etherdev(sizeof(struct ehea_port)); if (!dev) { - pr_err("no mem for net_device\n"); + ehea_error("no mem for net_device"); ret = -ENOMEM; goto out_err; } @@ -3265,7 +3270,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = register_netdev(dev); if (ret) { - pr_err("register_netdev failed. ret=%d\n", ret); + ehea_error("register_netdev failed. ret=%d", ret); goto out_unreg_port; } @@ -3273,10 +3278,11 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = ehea_get_jumboframe_status(port, &jumbo); if (ret) - netdev_err(dev, "failed determining jumbo frame status\n"); + ehea_error("failed determining jumbo frame status for %s", + port->netdev->name); - netdev_info(dev, "Jumbo frames are %sabled\n", - jumbo == 1 ? "en" : "dis"); + ehea_info("%s: Jumbo frames are %sabled", dev->name, + jumbo == 1 ? "en" : "dis"); adapter->active_ports++; @@ -3292,8 +3298,8 @@ out_free_ethdev: free_netdev(dev); out_err: - pr_err("setting up logical port with id=%d failed, ret=%d\n", - logical_port_id, ret); + ehea_error("setting up logical port with id=%d failed, ret=%d", + logical_port_id, ret); return NULL; } @@ -3321,13 +3327,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", NULL); if (!dn_log_port_id) { - pr_err("bad device node: eth_dn name=%s\n", - eth_dn->full_name); + ehea_error("bad device node: eth_dn name=%s", + eth_dn->full_name); continue; } if (ehea_add_adapter_mr(adapter)) { - pr_err("creating MR failed\n"); + ehea_error("creating MR failed"); of_node_put(eth_dn); return -EIO; } @@ -3336,8 +3342,9 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) *dn_log_port_id, eth_dn); if (adapter->port[i]) - netdev_info(adapter->port[i]->netdev, - "logical port id #%d\n", *dn_log_port_id); + ehea_info("%s -> logical port id #%d", + adapter->port[i]->netdev->name, + *dn_log_port_id); else ehea_remove_adapter_mr(adapter); @@ -3382,20 +3389,21 @@ static ssize_t ehea_probe_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - netdev_info(port->netdev, "adding port with logical port id=%d failed: port already configured\n", - logical_port_id); + ehea_info("adding port with logical port id=%d failed. port " + "already configured as %s.", logical_port_id, + port->netdev->name); return -EINVAL; } eth_dn = ehea_get_eth_dn(adapter, logical_port_id); if (!eth_dn) { - pr_info("no logical port with id %d found\n", logical_port_id); + ehea_info("no logical port with id %d found", logical_port_id); return -EINVAL; } if (ehea_add_adapter_mr(adapter)) { - pr_err("creating MR failed\n"); + ehea_error("creating MR failed"); return -EIO; } @@ -3410,8 +3418,8 @@ static ssize_t ehea_probe_port(struct device *dev, break; } - netdev_info(port->netdev, "added: (logical port id=%d)\n", - logical_port_id); + ehea_info("added %s (logical port id=%d)", port->netdev->name, + logical_port_id); } else { ehea_remove_adapter_mr(adapter); return -EIO; @@ -3434,8 +3442,8 @@ static ssize_t ehea_remove_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - netdev_info(port->netdev, "removed: (logical port id=%d)\n", - logical_port_id); + ehea_info("removed %s (logical port id=%d)", port->netdev->name, + logical_port_id); ehea_shutdown_single_port(port); @@ -3445,8 +3453,8 @@ static ssize_t ehea_remove_port(struct device *dev, break; } } else { - pr_err("removing port with logical port id=%d failed. port not configured.\n", - logical_port_id); + ehea_error("removing port with logical port id=%d failed. port " + "not configured.", logical_port_id); return -EINVAL; } @@ -3483,7 +3491,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, int ret; if (!dev || !dev->dev.of_node) { - pr_err("Invalid ibmebus device probed\n"); + ehea_error("Invalid ibmebus device probed"); return -EINVAL; } @@ -3631,17 +3639,17 @@ static int ehea_mem_notifier(struct notifier_block *nb, switch (action) { case MEM_CANCEL_OFFLINE: - pr_info("memory offlining canceled\n"); + ehea_info("memory offlining canceled"); /* Readd canceled memory block */ case MEM_ONLINE: - pr_info("memory is going online\n"); + ehea_info("memory is going online"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; ehea_rereg_mrs(NULL); break; case MEM_GOING_OFFLINE: - pr_info("memory is going offline\n"); + ehea_info("memory is going offline"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; @@ -3667,7 +3675,7 @@ static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { if (action == SYS_RESTART) { - pr_info("Reboot: freeing all eHEA resources\n"); + ehea_info("Reboot: freeing all eHEA resources"); ibmebus_unregister_driver(&ehea_driver); } return NOTIFY_DONE; @@ -3683,22 +3691,22 @@ static int check_module_parm(void) if ((rq1_entries < EHEA_MIN_ENTRIES_QP) || (rq1_entries > EHEA_MAX_ENTRIES_RQ1)) { - pr_info("Bad parameter: rq1_entries\n"); + ehea_info("Bad parameter: rq1_entries"); ret = -EINVAL; } if ((rq2_entries < EHEA_MIN_ENTRIES_QP) || (rq2_entries > EHEA_MAX_ENTRIES_RQ2)) { - pr_info("Bad parameter: rq2_entries\n"); + ehea_info("Bad parameter: rq2_entries"); ret = -EINVAL; } if ((rq3_entries < EHEA_MIN_ENTRIES_QP) || (rq3_entries > EHEA_MAX_ENTRIES_RQ3)) { - pr_info("Bad parameter: rq3_entries\n"); + ehea_info("Bad parameter: rq3_entries"); ret = -EINVAL; } if ((sq_entries < EHEA_MIN_ENTRIES_QP) || (sq_entries > EHEA_MAX_ENTRIES_SQ)) { - pr_info("Bad parameter: sq_entries\n"); + ehea_info("Bad parameter: sq_entries"); ret = -EINVAL; } @@ -3718,7 +3726,8 @@ int __init ehea_module_init(void) { int ret; - pr_info("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION); + printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", + DRV_VERSION); INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); @@ -3738,27 +3747,27 @@ int __init ehea_module_init(void) ret = register_reboot_notifier(&ehea_reboot_nb); if (ret) - pr_info("failed registering reboot notifier\n"); + ehea_info("failed registering reboot notifier"); ret = register_memory_notifier(&ehea_mem_nb); if (ret) - pr_info("failed registering memory remove notifier\n"); + ehea_info("failed registering memory remove notifier"); ret = crash_shutdown_register(ehea_crash_handler); if (ret) - pr_info("failed registering crash handler\n"); + ehea_info("failed registering crash handler"); ret = ibmebus_register_driver(&ehea_driver); if (ret) { - pr_err("failed registering eHEA device driver on ebus\n"); + ehea_error("failed registering eHEA device driver on ebus"); goto out2; } ret = driver_create_file(&ehea_driver.driver, &driver_attr_capabilities); if (ret) { - pr_err("failed to register capabilities attribute, ret=%d\n", - ret); + ehea_error("failed to register capabilities attribute, ret=%d", + ret); goto out3; } @@ -3784,7 +3793,7 @@ static void __exit ehea_module_exit(void) unregister_reboot_notifier(&ehea_reboot_nb); ret = crash_shutdown_unregister(ehea_crash_handler); if (ret) - pr_info("failed unregistering crash handler\n"); + ehea_info("failed unregistering crash handler"); unregister_memory_notifier(&ehea_mem_nb); kfree(ehea_fw_handles.arr); kfree(ehea_bcmc_regs.arr); diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 0506967b9044..8fe9dcaa7538 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -26,8 +26,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "ehea_phyp.h" @@ -69,11 +67,12 @@ static long ehea_plpar_hcall_norets(unsigned long opcode, } if (ret < H_SUCCESS) - pr_err("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx\n", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, arg6, arg7); + ehea_error("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx ", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, + arg6, arg7); return ret; } @@ -115,18 +114,19 @@ static long ehea_plpar_hcall9(unsigned long opcode, && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) && (arg3 == H_PORT_CB7_DUCQPN))))) - pr_err("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" - " arg9=%lx" - " out1=%lx out2=%lx out3=%lx out4=%lx" - " out5=%lx out6=%lx out7=%lx out8=%lx" - " out9=%lx\n", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9, - outs[0], outs[1], outs[2], outs[3], outs[4], - outs[5], outs[6], outs[7], outs[8]); + ehea_error("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" + " arg9=%lx" + " out1=%lx out2=%lx out3=%lx out4=%lx" + " out5=%lx out6=%lx out7=%lx out8=%lx" + " out9=%lx", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, + outs[0], outs[1], outs[2], outs[3], + outs[4], outs[5], outs[6], outs[7], + outs[8]); return ret; } @@ -515,7 +515,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, const u64 log_pageaddr, const u64 count) { if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { - pr_err("not on pageboundary\n"); + ehea_error("not on pageboundary"); return H_PARAMETER; } diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index cd44bb8017d9..89128b6373e3 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -26,8 +26,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include "ehea.h" @@ -47,7 +45,7 @@ static void *hw_qpageit_get_inc(struct hw_queue *queue) queue->current_q_offset -= queue->pagesize; retvalue = NULL; } else if (((u64) retvalue) & (EHEA_PAGESIZE-1)) { - pr_err("not on pageboundary\n"); + ehea_error("not on pageboundary"); retvalue = NULL; } return retvalue; @@ -60,15 +58,15 @@ static int hw_queue_ctor(struct hw_queue *queue, const u32 nr_of_pages, int i, k; if ((pagesize > PAGE_SIZE) || (!pages_per_kpage)) { - pr_err("pagesize conflict! kernel pagesize=%d, ehea pagesize=%d\n", - (int)PAGE_SIZE, (int)pagesize); + ehea_error("pagesize conflict! kernel pagesize=%d, " + "ehea pagesize=%d", (int)PAGE_SIZE, (int)pagesize); return -EINVAL; } queue->queue_length = nr_of_pages * pagesize; queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL); if (!queue->queue_pages) { - pr_err("no mem for queue_pages\n"); + ehea_error("no mem for queue_pages"); return -ENOMEM; } @@ -132,7 +130,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq = kzalloc(sizeof(*cq), GFP_KERNEL); if (!cq) { - pr_err("no mem for cq\n"); + ehea_error("no mem for cq"); goto out_nomem; } @@ -149,7 +147,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_cq(adapter->handle, &cq->attr, &cq->fw_handle, &cq->epas); if (hret != H_SUCCESS) { - pr_err("alloc_resource_cq failed\n"); + ehea_error("alloc_resource_cq failed"); goto out_freemem; } @@ -161,7 +159,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, for (counter = 0; counter < cq->attr.nr_pages; counter++) { vpage = hw_qpageit_get_inc(&cq->hw_queue); if (!vpage) { - pr_err("hw_qpageit_get_inc failed\n"); + ehea_error("hw_qpageit_get_inc failed"); goto out_kill_hwq; } @@ -170,8 +168,9 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, 0, EHEA_CQ_REGISTER_ORIG, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - pr_err("register_rpage_cq failed ehea_cq=%p hret=%llx counter=%i act_pages=%i\n", - cq, hret, counter, cq->attr.nr_pages); + ehea_error("register_rpage_cq failed ehea_cq=%p " + "hret=%llx counter=%i act_pages=%i", + cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -179,14 +178,14 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, vpage = hw_qpageit_get_inc(&cq->hw_queue); if ((hret != H_SUCCESS) || (vpage)) { - pr_err("registration of pages not complete hret=%llx\n", - hret); + ehea_error("registration of pages not " + "complete hret=%llx\n", hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { - pr_err("CQ: registration of page failed hret=%llx\n", - hret); + ehea_error("CQ: registration of page failed " + "hret=%llx\n", hret); goto out_kill_hwq; } } @@ -242,7 +241,7 @@ int ehea_destroy_cq(struct ehea_cq *cq) } if (hret != H_SUCCESS) { - pr_err("destroy CQ failed\n"); + ehea_error("destroy CQ failed"); return -EIO; } @@ -260,7 +259,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, eq = kzalloc(sizeof(*eq), GFP_KERNEL); if (!eq) { - pr_err("no mem for eq\n"); + ehea_error("no mem for eq"); return NULL; } @@ -273,21 +272,21 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_eq(adapter->handle, &eq->attr, &eq->fw_handle); if (hret != H_SUCCESS) { - pr_err("alloc_resource_eq failed\n"); + ehea_error("alloc_resource_eq failed"); goto out_freemem; } ret = hw_queue_ctor(&eq->hw_queue, eq->attr.nr_pages, EHEA_PAGESIZE, sizeof(struct ehea_eqe)); if (ret) { - pr_err("can't allocate eq pages\n"); + ehea_error("can't allocate eq pages"); goto out_freeres; } for (i = 0; i < eq->attr.nr_pages; i++) { vpage = hw_qpageit_get_inc(&eq->hw_queue); if (!vpage) { - pr_err("hw_qpageit_get_inc failed\n"); + ehea_error("hw_qpageit_get_inc failed"); hret = H_RESOURCE; goto out_kill_hwq; } @@ -371,7 +370,7 @@ int ehea_destroy_eq(struct ehea_eq *eq) } if (hret != H_SUCCESS) { - pr_err("destroy EQ failed\n"); + ehea_error("destroy EQ failed"); return -EIO; } @@ -396,7 +395,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, for (cnt = 0; cnt < nr_pages; cnt++) { vpage = hw_qpageit_get_inc(hw_queue); if (!vpage) { - pr_err("hw_qpageit_get_inc failed\n"); + ehea_error("hw_qpageit_get_inc failed"); goto out_kill_hwq; } rpage = virt_to_abs(vpage); @@ -404,7 +403,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, 0, h_call_q_selector, qp->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - pr_err("register_rpage_qp failed\n"); + ehea_error("register_rpage_qp failed"); goto out_kill_hwq; } } @@ -433,7 +432,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, qp = kzalloc(sizeof(*qp), GFP_KERNEL); if (!qp) { - pr_err("no mem for qp\n"); + ehea_error("no mem for qp"); return NULL; } @@ -442,7 +441,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_qp(adapter->handle, init_attr, pd, &qp->fw_handle, &qp->epas); if (hret != H_SUCCESS) { - pr_err("ehea_h_alloc_resource_qp failed\n"); + ehea_error("ehea_h_alloc_resource_qp failed"); goto out_freemem; } @@ -456,7 +455,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_sq, adapter, 0); if (ret) { - pr_err("can't register for sq ret=%x\n", ret); + ehea_error("can't register for sq ret=%x", ret); goto out_freeres; } @@ -466,7 +465,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq1, adapter, 1); if (ret) { - pr_err("can't register for rq1 ret=%x\n", ret); + ehea_error("can't register for rq1 ret=%x", ret); goto out_kill_hwsq; } @@ -477,7 +476,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq2, adapter, 2); if (ret) { - pr_err("can't register for rq2 ret=%x\n", ret); + ehea_error("can't register for rq2 ret=%x", ret); goto out_kill_hwr1q; } } @@ -489,7 +488,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq3, adapter, 3); if (ret) { - pr_err("can't register for rq3 ret=%x\n", ret); + ehea_error("can't register for rq3 ret=%x", ret); goto out_kill_hwr2q; } } @@ -554,7 +553,7 @@ int ehea_destroy_qp(struct ehea_qp *qp) } if (hret != H_SUCCESS) { - pr_err("destroy QP failed\n"); + ehea_error("destroy QP failed"); return -EIO; } @@ -843,7 +842,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, (hret != H_PAGE_REGISTERED)) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - pr_err("register_rpage_mr failed\n"); + ehea_error("register_rpage_mr failed"); return hret; } } @@ -897,7 +896,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) pt = (void *)get_zeroed_page(GFP_KERNEL); if (!pt) { - pr_err("no mem\n"); + ehea_error("no mem"); ret = -ENOMEM; goto out; } @@ -907,14 +906,14 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) &mr->handle, &mr->lkey); if (hret != H_SUCCESS) { - pr_err("alloc_resource_mr failed\n"); + ehea_error("alloc_resource_mr failed"); ret = -EIO; goto out; } if (!ehea_bmap) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - pr_err("no busmap available\n"); + ehea_error("no busmap available"); ret = -EIO; goto out; } @@ -930,7 +929,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) if (hret != H_SUCCESS) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - pr_err("registering mr failed\n"); + ehea_error("registering mr failed"); ret = -EIO; goto out; } @@ -953,7 +952,7 @@ int ehea_rem_mr(struct ehea_mr *mr) hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, FORCE_FREE); if (hret != H_SUCCESS) { - pr_err("destroy MR failed\n"); + ehea_error("destroy MR failed"); return -EIO; } @@ -988,14 +987,14 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == EHEA_AER_RESTYPE_QP) - pr_err("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, port=%llX\n", - resource, data[6], data[12], data[22]); + ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " + "port=%llX", resource, data[6], data[12], data[22]); else if (type == EHEA_AER_RESTYPE_CQ) - pr_err("CQ (resource=%llX) state: AER=0x%llX\n", - resource, data[6]); + ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, + data[6]); else if (type == EHEA_AER_RESTYPE_EQ) - pr_err("EQ (resource=%llX) state: AER=0x%llX\n", - resource, data[6]); + ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, + data[6]); ehea_dump(data, length, "error data"); } @@ -1009,7 +1008,7 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, rblock = (void *)get_zeroed_page(GFP_KERNEL); if (!rblock) { - pr_err("Cannot allocate rblock memory\n"); + ehea_error("Cannot allocate rblock memory."); goto out; } @@ -1021,9 +1020,9 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, *aerr = rblock[12]; print_error_data(rblock); } else if (ret == H_R_STATE) { - pr_err("No error data available: %llX\n", res_handle); + ehea_error("No error data available: %llX.", res_handle); } else - pr_err("Error data could not be fetched: %llX\n", res_handle); + ehea_error("Error data could not be fetched: %llX", res_handle); free_page((unsigned long)rblock); out: -- cgit v1.2.3-59-g8ed1b From 871a2c16c21b988688b4ab1a78eadd969765c0a3 Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Sat, 4 Dec 2010 13:38:01 +0100 Subject: dccp: Policy-based packet dequeueing infrastructure This patch adds a generic infrastructure for policy-based dequeueing of TX packets and provides two policies: * a simple FIFO policy (which is the default) and * a priority based policy (set via socket options). Both policies honour the tx_qlen sysctl for the maximum size of the write queue (can be overridden via socket options). The priority policy uses skb->priority internally to assign an u32 priority identifier, using the same ranking as SO_PRIORITY. The skb->priority field is set to 0 when the packet leaves DCCP. The priority is supplied as ancillary data using cmsg(3), the patch also provides the requisite parsing routines. Signed-off-by: Tomasz Grobelny Signed-off-by: Gerrit Renker --- Documentation/networking/dccp.txt | 20 ++++++ include/linux/dccp.h | 21 +++++++ net/dccp/Makefile | 4 +- net/dccp/dccp.h | 12 ++++ net/dccp/output.c | 7 +-- net/dccp/proto.c | 67 +++++++++++++++++++- net/dccp/qpolicy.c | 126 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 248 insertions(+), 9 deletions(-) create mode 100644 net/dccp/qpolicy.c diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index 271d524a4c8d..b395ca6a49f2 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -47,6 +47,26 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree Socket options ============== +DCCP_SOCKOPT_QPOLICY_ID sets the dequeuing policy for outgoing packets. It takes +a policy ID as argument and can only be set before the connection (i.e. changes +during an established connection are not supported). Currently, two policies are +defined: the "simple" policy (DCCPQ_POLICY_SIMPLE), which does nothing special, +and a priority-based variant (DCCPQ_POLICY_PRIO). The latter allows to pass an +u32 priority value as ancillary data to sendmsg(), where higher numbers indicate +a higher packet priority (similar to SO_PRIORITY). This ancillary data needs to +be formatted using a cmsg(3) message header filled in as follows: + cmsg->cmsg_level = SOL_DCCP; + cmsg->cmsg_type = DCCP_SCM_PRIORITY; + cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); /* or CMSG_LEN(4) */ + +DCCP_SOCKOPT_QPOLICY_TXQLEN sets the maximum length of the output queue. A zero +value is always interpreted as unbounded queue length. If different from zero, +the interpretation of this parameter depends on the current dequeuing policy +(see above): the "simple" policy will enforce a fixed queue size by returning +EAGAIN, whereas the "prio" policy enforces a fixed queue length by dropping the +lowest-priority packet first. The default value for this parameter is +initialised from /proc/sys/net/dccp/default/tx_qlen. + DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of service codes (RFC 4340, sec. 8.1.2); if this socket option is not set, the socket will fall back to 0 (which means that no meaningful service code diff --git a/include/linux/dccp.h b/include/linux/dccp.h index eed52bcd35d0..010e2d87ed75 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -197,6 +197,21 @@ enum dccp_feature_numbers { DCCPF_MAX_CCID_SPECIFIC = 255, }; +/* DCCP socket control message types for cmsg */ +enum dccp_cmsg_type { + DCCP_SCM_PRIORITY = 1, + DCCP_SCM_QPOLICY_MAX = 0xFFFF, + /* ^-- Up to here reserved exclusively for qpolicy parameters */ + DCCP_SCM_MAX +}; + +/* DCCP priorities for outgoing/queued packets */ +enum dccp_packet_dequeueing_policy { + DCCPQ_POLICY_SIMPLE, + DCCPQ_POLICY_PRIO, + DCCPQ_POLICY_MAX +}; + /* DCCP socket options */ #define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */ #define DCCP_SOCKOPT_SERVICE 2 @@ -210,6 +225,8 @@ enum dccp_feature_numbers { #define DCCP_SOCKOPT_CCID 13 #define DCCP_SOCKOPT_TX_CCID 14 #define DCCP_SOCKOPT_RX_CCID 15 +#define DCCP_SOCKOPT_QPOLICY_ID 16 +#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 @@ -458,6 +475,8 @@ struct dccp_ackvec; * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection) * @dccps_options_received - parsed set of retrieved options + * @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy + * @dccps_tx_qlen - maximum length of the TX queue * @dccps_role - role of this sock, one of %dccp_role * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending @@ -500,6 +519,8 @@ struct dccp_sock { struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; + __u8 dccps_qpolicy; + __u32 dccps_tx_qlen; enum dccp_role dccps_role:2; __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; diff --git a/net/dccp/Makefile b/net/dccp/Makefile index 2991efcc8dea..5c8362b037ed 100644 --- a/net/dccp/Makefile +++ b/net/dccp/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o -dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o - +dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o \ + qpolicy.o # # CCID algorithms to be used by dccp.ko # diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 19fafd597465..d008da91cec2 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -243,6 +243,18 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, extern void dccp_send_sync(struct sock *sk, const u64 seq, const enum dccp_pkt_type pkt_type); +/* + * TX Packet Dequeueing Interface + */ +extern void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb); +extern bool dccp_qpolicy_full(struct sock *sk); +extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); +extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); +extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); + +/* + * TX Packet Output and TX Timers + */ extern void dccp_write_xmit(struct sock *sk); extern void dccp_write_space(struct sock *sk); extern void dccp_flush_write_queue(struct sock *sk, long *time_budget); diff --git a/net/dccp/output.c b/net/dccp/output.c index d96dd9d362ae..784d30210543 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -242,7 +242,7 @@ static void dccp_xmit_packet(struct sock *sk) { int err, len; struct dccp_sock *dp = dccp_sk(sk); - struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue); + struct sk_buff *skb = dccp_qpolicy_pop(sk); if (unlikely(skb == NULL)) return; @@ -345,7 +345,7 @@ void dccp_write_xmit(struct sock *sk) struct dccp_sock *dp = dccp_sk(sk); struct sk_buff *skb; - while ((skb = skb_peek(&sk->sk_write_queue))) { + while ((skb = dccp_qpolicy_top(sk))) { int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); switch (ccid_packet_dequeue_eval(rc)) { @@ -359,8 +359,7 @@ void dccp_write_xmit(struct sock *sk) dccp_xmit_packet(sk); break; case CCID_PACKET_ERR: - skb_dequeue(&sk->sk_write_queue); - kfree_skb(skb); + dccp_qpolicy_drop(sk, skb); dccp_pr_debug("packet discarded due to err=%d\n", rc); } } diff --git a/net/dccp/proto.c b/net/dccp/proto.c index ef343d53fcea..d6a224982bb5 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -185,6 +185,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) dp->dccps_role = DCCP_ROLE_UNDEFINED; dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT; dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1; + dp->dccps_tx_qlen = sysctl_dccp_tx_qlen; dccp_init_xmit_timers(sk); @@ -532,6 +533,20 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, case DCCP_SOCKOPT_RECV_CSCOV: err = dccp_setsockopt_cscov(sk, val, true); break; + case DCCP_SOCKOPT_QPOLICY_ID: + if (sk->sk_state != DCCP_CLOSED) + err = -EISCONN; + else if (val < 0 || val >= DCCPQ_POLICY_MAX) + err = -EINVAL; + else + dp->dccps_qpolicy = val; + break; + case DCCP_SOCKOPT_QPOLICY_TXQLEN: + if (val < 0) + err = -EINVAL; + else + dp->dccps_tx_qlen = val; + break; default: err = -ENOPROTOOPT; break; @@ -639,6 +654,12 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, case DCCP_SOCKOPT_RECV_CSCOV: val = dp->dccps_pcrlen; break; + case DCCP_SOCKOPT_QPOLICY_ID: + val = dp->dccps_qpolicy; + break; + case DCCP_SOCKOPT_QPOLICY_TXQLEN: + val = dp->dccps_tx_qlen; + break; case 128 ... 191: return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, len, (u32 __user *)optval, optlen); @@ -681,6 +702,43 @@ int compat_dccp_getsockopt(struct sock *sk, int level, int optname, EXPORT_SYMBOL_GPL(compat_dccp_getsockopt); #endif +static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) +{ + struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg); + + /* + * Assign an (opaque) qpolicy priority value to skb->priority. + * + * We are overloading this skb field for use with the qpolicy subystem. + * The skb->priority is normally used for the SO_PRIORITY option, which + * is initialised from sk_priority. Since the assignment of sk_priority + * to skb->priority happens later (on layer 3), we overload this field + * for use with queueing priorities as long as the skb is on layer 4. + * The default priority value (if nothing is set) is 0. + */ + skb->priority = 0; + + for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { + + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + + if (cmsg->cmsg_level != SOL_DCCP) + continue; + + switch (cmsg->cmsg_type) { + case DCCP_SCM_PRIORITY: + if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) + return -EINVAL; + skb->priority = *(__u32 *)CMSG_DATA(cmsg); + break; + default: + return -EINVAL; + } + } + return 0; +} + int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { @@ -696,8 +754,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, lock_sock(sk); - if (sysctl_dccp_tx_qlen && - (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) { + if (dccp_qpolicy_full(sk)) { rc = -EAGAIN; goto out_release; } @@ -725,7 +782,11 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (rc != 0) goto out_discard; - skb_queue_tail(&sk->sk_write_queue, skb); + rc = dccp_msghdr_parse(msg, skb); + if (rc != 0) + goto out_discard; + + dccp_qpolicy_push(sk, skb); /* * The xmit_timer is set if the TX CCID is rate-based and will expire * when congestion control permits to release further packets into the diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c new file mode 100644 index 000000000000..4b0fd6b11f6d --- /dev/null +++ b/net/dccp/qpolicy.c @@ -0,0 +1,126 @@ +/* + * net/dccp/qpolicy.c + * + * Policy-based packet dequeueing interface for DCCP. + * + * Copyright (c) 2008 Tomasz Grobelny + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License v2 + * as published by the Free Software Foundation. + */ +#include "dccp.h" + +/* + * Simple Dequeueing Policy: + * If tx_qlen is different from 0, enqueue up to tx_qlen elements. + */ +static void qpolicy_simple_push(struct sock *sk, struct sk_buff *skb) +{ + skb_queue_tail(&sk->sk_write_queue, skb); +} + +static bool qpolicy_simple_full(struct sock *sk) +{ + return dccp_sk(sk)->dccps_tx_qlen && + sk->sk_write_queue.qlen >= dccp_sk(sk)->dccps_tx_qlen; +} + +static struct sk_buff *qpolicy_simple_top(struct sock *sk) +{ + return skb_peek(&sk->sk_write_queue); +} + +/* + * Priority-based Dequeueing Policy: + * If tx_qlen is different from 0 and the queue has reached its upper bound + * of tx_qlen elements, replace older packets lowest-priority-first. + */ +static struct sk_buff *qpolicy_prio_best_skb(struct sock *sk) +{ + struct sk_buff *skb, *best = NULL; + + skb_queue_walk(&sk->sk_write_queue, skb) + if (best == NULL || skb->priority > best->priority) + best = skb; + return best; +} + +static struct sk_buff *qpolicy_prio_worst_skb(struct sock *sk) +{ + struct sk_buff *skb, *worst = NULL; + + skb_queue_walk(&sk->sk_write_queue, skb) + if (worst == NULL || skb->priority < worst->priority) + worst = skb; + return worst; +} + +static bool qpolicy_prio_full(struct sock *sk) +{ + if (qpolicy_simple_full(sk)) + dccp_qpolicy_drop(sk, qpolicy_prio_worst_skb(sk)); + return false; +} + +/** + * struct dccp_qpolicy_operations - TX Packet Dequeueing Interface + * @push: add a new @skb to the write queue + * @full: indicates that no more packets will be admitted + * @top: peeks at whatever the queueing policy defines as its `top' + */ +static struct dccp_qpolicy_operations { + void (*push) (struct sock *sk, struct sk_buff *skb); + bool (*full) (struct sock *sk); + struct sk_buff* (*top) (struct sock *sk); + +} qpol_table[DCCPQ_POLICY_MAX] = { + [DCCPQ_POLICY_SIMPLE] = { + .push = qpolicy_simple_push, + .full = qpolicy_simple_full, + .top = qpolicy_simple_top, + }, + [DCCPQ_POLICY_PRIO] = { + .push = qpolicy_simple_push, + .full = qpolicy_prio_full, + .top = qpolicy_prio_best_skb, + }, +}; + +/* + * Externally visible interface + */ +void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb) +{ + qpol_table[dccp_sk(sk)->dccps_qpolicy].push(sk, skb); +} + +bool dccp_qpolicy_full(struct sock *sk) +{ + return qpol_table[dccp_sk(sk)->dccps_qpolicy].full(sk); +} + +void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb) +{ + if (skb != NULL) { + skb_unlink(skb, &sk->sk_write_queue); + kfree_skb(skb); + } +} + +struct sk_buff *dccp_qpolicy_top(struct sock *sk) +{ + return qpol_table[dccp_sk(sk)->dccps_qpolicy].top(sk); +} + +struct sk_buff *dccp_qpolicy_pop(struct sock *sk) +{ + struct sk_buff *skb = dccp_qpolicy_top(sk); + + if (skb != NULL) { + /* Clear any skb fields that we used internally */ + skb->priority = 0; + skb_unlink(skb, &sk->sk_write_queue); + } + return skb; +} -- cgit v1.2.3-59-g8ed1b From 04910265078f08a73208beab70ed2a3cce4a919f Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Sat, 4 Dec 2010 13:39:13 +0100 Subject: dccp qpolicy: Parameter checking of cmsg qpolicy parameters Ensure that cmsg->cmsg_type value is valid for qpolicy that is currently in use. Signed-off-by: Tomasz Grobelny Signed-off-by: Gerrit Renker --- net/dccp/dccp.h | 1 + net/dccp/proto.c | 4 ++++ net/dccp/qpolicy.c | 23 +++++++++++++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index d008da91cec2..48ad5d9da7cb 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -251,6 +251,7 @@ extern bool dccp_qpolicy_full(struct sock *sk); extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); +extern bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param); /* * TX Packet Output and TX Timers diff --git a/net/dccp/proto.c b/net/dccp/proto.c index d6a224982bb5..152975d942d9 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -726,6 +726,10 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) if (cmsg->cmsg_level != SOL_DCCP) continue; + if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX && + !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type)) + return -EINVAL; + switch (cmsg->cmsg_type) { case DCCP_SCM_PRIORITY: if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c index 4b0fd6b11f6d..63c30bfa4703 100644 --- a/net/dccp/qpolicy.c +++ b/net/dccp/qpolicy.c @@ -73,17 +73,20 @@ static struct dccp_qpolicy_operations { void (*push) (struct sock *sk, struct sk_buff *skb); bool (*full) (struct sock *sk); struct sk_buff* (*top) (struct sock *sk); + __be32 params; } qpol_table[DCCPQ_POLICY_MAX] = { [DCCPQ_POLICY_SIMPLE] = { - .push = qpolicy_simple_push, - .full = qpolicy_simple_full, - .top = qpolicy_simple_top, + .push = qpolicy_simple_push, + .full = qpolicy_simple_full, + .top = qpolicy_simple_top, + .params = 0, }, [DCCPQ_POLICY_PRIO] = { - .push = qpolicy_simple_push, - .full = qpolicy_prio_full, - .top = qpolicy_prio_best_skb, + .push = qpolicy_simple_push, + .full = qpolicy_prio_full, + .top = qpolicy_prio_best_skb, + .params = DCCP_SCM_PRIORITY, }, }; @@ -124,3 +127,11 @@ struct sk_buff *dccp_qpolicy_pop(struct sock *sk) } return skb; } + +bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param) +{ + /* check if exactly one bit is set */ + if (!param || (param & (param - 1))) + return false; + return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param; +} -- cgit v1.2.3-59-g8ed1b From ff2109f5f94ff75f45e0c8d2d1d56fefdf20733f Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 21 Nov 2010 15:03:12 +0000 Subject: Net: bluetooth: Makefile: Remove deprecated kbuild goal definitions Changed Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- net/bluetooth/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index d1e433f7d673..7ca1f46a471a 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ -bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o +bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o -- cgit v1.2.3-59-g8ed1b From ac33ac610dc613b2b1c938f8b61eef651ab72563 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 7 Dec 2010 18:29:52 +0000 Subject: sfc: Log start and end of ethtool self-test at INFO level Add message at start of self-test and increase log level of message at end of self-test, so that any other messages produced during the test are clearly associated with it. Signed-off-by: Ben Hutchings --- drivers/net/sfc/ethtool.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index aae756bf47ee..d51a6b1f4766 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -582,6 +582,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev, goto fail1; } + netif_info(efx, drv, efx->net_dev, "starting %sline testing\n", + (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); + /* We need rx buffers and interrupts. */ already_up = (efx->net_dev->flags & IFF_UP); if (!already_up) { @@ -600,9 +603,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev, if (!already_up) dev_close(efx->net_dev); - netif_dbg(efx, drv, efx->net_dev, "%s %sline self-tests\n", - rc == 0 ? "passed" : "failed", - (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); + netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n", + rc == 0 ? "passed" : "failed", + (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); fail2: fail1: -- cgit v1.2.3-59-g8ed1b From 8891681af928f1da795cd4bd59043e5e0fadd6c8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 7 Dec 2010 19:02:27 +0000 Subject: sfc: Remove filter table IDs from filter functions The separation between filter tables is largely an internal detail and it may be removed in future hardware. To prepare for that: - Merge table ID with filter index to make an opaque filter ID - Wrap efx_filter_table_clear() with a function that clears filters from both RX tables, which is all that the current caller requires Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.h | 5 ++--- drivers/net/sfc/ethtool.c | 8 ++------ drivers/net/sfc/filter.c | 40 ++++++++++++++++++++++++++++++---------- drivers/net/sfc/filter.h | 6 ------ 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 10a1bf40da96..003fdb35b4bb 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -74,9 +74,8 @@ extern int efx_filter_insert_filter(struct efx_nic *efx, bool replace); extern int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec); -extern void efx_filter_table_clear(struct efx_nic *efx, - enum efx_filter_table_id table_id, - enum efx_filter_priority priority); +extern void efx_filter_clear_rx(struct efx_nic *efx, + enum efx_filter_priority priority); /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index d51a6b1f4766..0f46c1a3171e 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -558,12 +558,8 @@ static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) if (rc) return rc; - if (!(data & ETH_FLAG_NTUPLE)) { - efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, - EFX_FILTER_PRI_MANUAL); - efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, - EFX_FILTER_PRI_MANUAL); - } + if (!(data & ETH_FLAG_NTUPLE)) + efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); return 0; } diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 44500b54fd5f..e96e6e852f16 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -26,6 +26,12 @@ */ #define FILTER_CTL_SRCH_MAX 200 +enum efx_filter_table_id { + EFX_FILTER_TABLE_RX_IP = 0, + EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_TABLE_COUNT, +}; + struct efx_filter_table { u32 offset; /* address of table relative to BAR */ unsigned size; /* number of entries */ @@ -206,6 +212,14 @@ found: return filter_idx; } +/* Construct/deconstruct external filter IDs */ + +static inline int +efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index) +{ + return table_id << 16 | index; +} + /** * efx_filter_insert_filter - add or replace a filter * @efx: NIC in which to insert the filter @@ -213,7 +227,7 @@ found: * @replace: Flag for whether the specified filter may replace a filter * with an identical match expression and equal or lower priority * - * On success, return the filter index within its table. + * On success, return the filter ID. * On failure, return a negative error code. */ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, @@ -273,6 +287,7 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, netif_vdbg(efx, hw, efx->net_dev, "%s: filter type %d index %d rxq %u set", __func__, spec->type, filter_idx, spec->dmaq_id); + rc = efx_filter_make_id(table_id, filter_idx); out: spin_unlock_bh(&state->lock); @@ -340,15 +355,9 @@ out: return rc; } -/** - * efx_filter_table_clear - remove filters from a table by priority - * @efx: NIC from which to remove the filters - * @table_id: Table from which to remove the filters - * @priority: Maximum priority to remove - */ -void efx_filter_table_clear(struct efx_nic *efx, - enum efx_filter_table_id table_id, - enum efx_filter_priority priority) +static void efx_filter_table_clear(struct efx_nic *efx, + enum efx_filter_table_id table_id, + enum efx_filter_priority priority) { struct efx_filter_state *state = efx->filter_state; struct efx_filter_table *table = &state->table[table_id]; @@ -365,6 +374,17 @@ void efx_filter_table_clear(struct efx_nic *efx, spin_unlock_bh(&state->lock); } +/** + * efx_filter_clear_rx - remove RX filters by priority + * @efx: NIC from which to remove the filters + * @priority: Maximum priority to remove + */ +void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority) +{ + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, priority); + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority); +} + /* Restore filter stater after reset */ void efx_restore_filters(struct efx_nic *efx) { diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h index a53319ded79c..d11e4aa78133 100644 --- a/drivers/net/sfc/filter.h +++ b/drivers/net/sfc/filter.h @@ -12,12 +12,6 @@ #include -enum efx_filter_table_id { - EFX_FILTER_TABLE_RX_IP = 0, - EFX_FILTER_TABLE_RX_MAC, - EFX_FILTER_TABLE_COUNT, -}; - /** * enum efx_filter_type - type of hardware filter * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple -- cgit v1.2.3-59-g8ed1b From c39d35ebffeea5996a6f8fd8430fae9acfb8aeaf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 7 Dec 2010 19:11:26 +0000 Subject: sfc: Generalise filter spec initialisation Move search_depth arrays into per-table state. Define initialisation function efx_filter_init_rx() which sets everything apart from the match fields. Define efx_filter_set_{ipv4_local,ipv4_full,eth_local}() to set the match fields. This allows some simplification of callers and later support for additional protocols and more flexible matching using multiple calls to these functions. Signed-off-by: Ben Hutchings --- drivers/net/sfc/ethtool.c | 82 ++++++++---------- drivers/net/sfc/filter.c | 214 ++++++++++++++++++++++++++++++++++++++-------- drivers/net/sfc/filter.h | 143 ++++++++----------------------- 3 files changed, 248 insertions(+), 191 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 0f46c1a3171e..5e50e57b0ae2 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "net_driver.h" #include "workarounds.h" #include "selftest.h" @@ -920,6 +921,7 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec; struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec; struct efx_filter_spec filter; + int rc; /* Range-check action */ if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR || @@ -929,9 +931,16 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, if (~ntuple->fs.data_mask) return -EINVAL; + efx_filter_init_rx(&filter, EFX_FILTER_PRI_MANUAL, 0, + (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) ? + 0xfff : ntuple->fs.action); + switch (ntuple->fs.flow_type) { case TCP_V4_FLOW: - case UDP_V4_FLOW: + case UDP_V4_FLOW: { + u8 proto = (ntuple->fs.flow_type == TCP_V4_FLOW ? + IPPROTO_TCP : IPPROTO_UDP); + /* Must match all of destination, */ if (ip_mask->ip4dst | ip_mask->pdst) return -EINVAL; @@ -943,7 +952,22 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, /* and nothing else */ if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask) return -EINVAL; + + if (!ip_mask->ip4src) + rc = efx_filter_set_ipv4_full(&filter, proto, + ip_entry->ip4dst, + ip_entry->pdst, + ip_entry->ip4src, + ip_entry->psrc); + else + rc = efx_filter_set_ipv4_local(&filter, proto, + ip_entry->ip4dst, + ip_entry->pdst); + if (rc) + return rc; break; + } + case ETHER_FLOW: /* Must match all of destination, */ if (!is_zero_ether_addr(mac_mask->h_dest)) @@ -956,58 +980,24 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, if (!is_broadcast_ether_addr(mac_mask->h_source) || mac_mask->h_proto != htons(0xffff)) return -EINVAL; + + rc = efx_filter_set_eth_local( + &filter, + (ntuple->fs.vlan_tag_mask == 0xf000) ? + ntuple->fs.vlan_tag : EFX_FILTER_VID_UNSPEC, + mac_entry->h_dest); + if (rc) + return rc; break; + default: return -EINVAL; } - filter.priority = EFX_FILTER_PRI_MANUAL; - filter.flags = 0; - - switch (ntuple->fs.flow_type) { - case TCP_V4_FLOW: - if (!ip_mask->ip4src) - efx_filter_set_rx_tcp_full(&filter, - htonl(ip_entry->ip4src), - htons(ip_entry->psrc), - htonl(ip_entry->ip4dst), - htons(ip_entry->pdst)); - else - efx_filter_set_rx_tcp_wild(&filter, - htonl(ip_entry->ip4dst), - htons(ip_entry->pdst)); - break; - case UDP_V4_FLOW: - if (!ip_mask->ip4src) - efx_filter_set_rx_udp_full(&filter, - htonl(ip_entry->ip4src), - htons(ip_entry->psrc), - htonl(ip_entry->ip4dst), - htons(ip_entry->pdst)); - else - efx_filter_set_rx_udp_wild(&filter, - htonl(ip_entry->ip4dst), - htons(ip_entry->pdst)); - break; - case ETHER_FLOW: - if (ntuple->fs.vlan_tag_mask == 0xf000) - efx_filter_set_rx_mac_full(&filter, - ntuple->fs.vlan_tag & 0xfff, - mac_entry->h_dest); - else - efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest); - break; - } - - if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) { + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) return efx_filter_remove_filter(efx, &filter); - } else { - if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) - filter.dmaq_id = 0xfff; - else - filter.dmaq_id = ntuple->fs.action; + else return efx_filter_insert_filter(efx, &filter, true); - } } static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index e96e6e852f16..d4722c41c4ce 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -7,6 +7,7 @@ * by the Free Software Foundation, incorporated herein by reference. */ +#include #include "efx.h" #include "filter.h" #include "io.h" @@ -33,18 +34,19 @@ enum efx_filter_table_id { }; struct efx_filter_table { + enum efx_filter_table_id id; u32 offset; /* address of table relative to BAR */ unsigned size; /* number of entries */ unsigned step; /* step between entries */ unsigned used; /* number currently used */ unsigned long *used_bitmap; struct efx_filter_spec *spec; + unsigned search_depth[EFX_FILTER_TYPE_COUNT]; }; struct efx_filter_state { spinlock_t lock; struct efx_filter_table table[EFX_FILTER_TABLE_COUNT]; - unsigned search_depth[EFX_FILTER_TYPE_COUNT]; }; /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit @@ -71,68 +73,203 @@ static u16 efx_filter_increment(u32 key) } static enum efx_filter_table_id -efx_filter_type_table_id(enum efx_filter_type type) +efx_filter_spec_table_id(const struct efx_filter_spec *spec) +{ + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2)); + EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC); + return spec->type >> 2; +} + +static struct efx_filter_table * +efx_filter_spec_table(struct efx_filter_state *state, + const struct efx_filter_spec *spec) { - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2)); - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2)); - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2)); - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2)); - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2)); - BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2)); - return type >> 2; + if (spec->type == EFX_FILTER_UNSPEC) + return NULL; + else + return &state->table[efx_filter_spec_table_id(spec)]; } -static void -efx_filter_table_reset_search_depth(struct efx_filter_state *state, - enum efx_filter_table_id table_id) +static void efx_filter_table_reset_search_depth(struct efx_filter_table *table) { - memset(state->search_depth + (table_id << 2), 0, - sizeof(state->search_depth[0]) << 2); + memset(table->search_depth, 0, sizeof(table->search_depth)); } static void efx_filter_push_rx_limits(struct efx_nic *efx) { struct efx_filter_state *state = efx->filter_state; + struct efx_filter_table *table; efx_oword_t filter_ctl; efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); + table = &state->table[EFX_FILTER_TABLE_RX_IP]; EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT, - state->search_depth[EFX_FILTER_RX_TCP_FULL] + + table->search_depth[EFX_FILTER_TCP_FULL] + FILTER_CTL_SRCH_FUDGE_FULL); EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT, - state->search_depth[EFX_FILTER_RX_TCP_WILD] + + table->search_depth[EFX_FILTER_TCP_WILD] + FILTER_CTL_SRCH_FUDGE_WILD); EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT, - state->search_depth[EFX_FILTER_RX_UDP_FULL] + + table->search_depth[EFX_FILTER_UDP_FULL] + FILTER_CTL_SRCH_FUDGE_FULL); EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT, - state->search_depth[EFX_FILTER_RX_UDP_WILD] + + table->search_depth[EFX_FILTER_UDP_WILD] + FILTER_CTL_SRCH_FUDGE_WILD); - if (state->table[EFX_FILTER_TABLE_RX_MAC].size) { + table = &state->table[EFX_FILTER_TABLE_RX_MAC]; + if (table->size) { EFX_SET_OWORD_FIELD( filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT, - state->search_depth[EFX_FILTER_RX_MAC_FULL] + + table->search_depth[EFX_FILTER_MAC_FULL] + FILTER_CTL_SRCH_FUDGE_FULL); EFX_SET_OWORD_FIELD( filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT, - state->search_depth[EFX_FILTER_RX_MAC_WILD] + + table->search_depth[EFX_FILTER_MAC_WILD] + FILTER_CTL_SRCH_FUDGE_WILD); } efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); } +static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec, + __be32 host1, __be16 port1, + __be32 host2, __be16 port2) +{ + spec->data[0] = ntohl(host1) << 16 | ntohs(port1); + spec->data[1] = ntohs(port2) << 16 | ntohl(host1) >> 16; + spec->data[2] = ntohl(host2); +} + +/** + * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port + * @spec: Specification to initialise + * @proto: Transport layer protocol number + * @host: Local host address (network byte order) + * @port: Local port (network byte order) + */ +int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto, + __be32 host, __be16 port) +{ + __be32 host1; + __be16 port1; + + EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX)); + + /* This cannot currently be combined with other filtering */ + if (spec->type != EFX_FILTER_UNSPEC) + return -EPROTONOSUPPORT; + + if (port == 0) + return -EINVAL; + + switch (proto) { + case IPPROTO_TCP: + spec->type = EFX_FILTER_TCP_WILD; + break; + case IPPROTO_UDP: + spec->type = EFX_FILTER_UDP_WILD; + break; + default: + return -EPROTONOSUPPORT; + } + + /* Filter is constructed in terms of source and destination, + * with the odd wrinkle that the ports are swapped in a UDP + * wildcard filter. We need to convert from local and remote + * (= zero for wildcard) addresses. + */ + host1 = 0; + if (proto != IPPROTO_UDP) { + port1 = 0; + } else { + port1 = port; + port = 0; + } + + __efx_filter_set_ipv4(spec, host1, port1, host, port); + return 0; +} + +/** + * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports + * @spec: Specification to initialise + * @proto: Transport layer protocol number + * @host: Local host address (network byte order) + * @port: Local port (network byte order) + * @rhost: Remote host address (network byte order) + * @rport: Remote port (network byte order) + */ +int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto, + __be32 host, __be16 port, + __be32 rhost, __be16 rport) +{ + EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX)); + + /* This cannot currently be combined with other filtering */ + if (spec->type != EFX_FILTER_UNSPEC) + return -EPROTONOSUPPORT; + + if (port == 0 || rport == 0) + return -EINVAL; + + switch (proto) { + case IPPROTO_TCP: + spec->type = EFX_FILTER_TCP_FULL; + break; + case IPPROTO_UDP: + spec->type = EFX_FILTER_UDP_FULL; + break; + default: + return -EPROTONOSUPPORT; + } + + __efx_filter_set_ipv4(spec, rhost, rport, host, port); + return 0; +} + +/** + * efx_filter_set_eth_local - specify local Ethernet address and optional VID + * @spec: Specification to initialise + * @vid: VLAN ID to match, or %EFX_FILTER_VID_UNSPEC + * @addr: Local Ethernet MAC address + */ +int efx_filter_set_eth_local(struct efx_filter_spec *spec, + u16 vid, const u8 *addr) +{ + EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX)); + + /* This cannot currently be combined with other filtering */ + if (spec->type != EFX_FILTER_UNSPEC) + return -EPROTONOSUPPORT; + + if (vid == EFX_FILTER_VID_UNSPEC) { + spec->type = EFX_FILTER_MAC_WILD; + spec->data[0] = 0; + } else { + spec->type = EFX_FILTER_MAC_FULL; + spec->data[0] = vid; + } + + spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; + spec->data[2] = addr[0] << 8 | addr[1]; + return 0; +} + /* Build a filter entry and return its n-tuple key. */ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) { u32 data3; - switch (efx_filter_type_table_id(spec->type)) { + switch (efx_filter_spec_table_id(spec)) { case EFX_FILTER_TABLE_RX_IP: { - bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL || - spec->type == EFX_FILTER_RX_UDP_WILD); + bool is_udp = (spec->type == EFX_FILTER_UDP_FULL || + spec->type == EFX_FILTER_UDP_WILD); EFX_POPULATE_OWORD_7( *filter, FRF_BZ_RSS_EN, @@ -149,7 +286,7 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) } case EFX_FILTER_TABLE_RX_MAC: { - bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD; + bool is_wild = spec->type == EFX_FILTER_MAC_WILD; EFX_POPULATE_OWORD_8( *filter, FRF_CZ_RMFT_RSS_EN, @@ -234,23 +371,21 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, bool replace) { struct efx_filter_state *state = efx->filter_state; - enum efx_filter_table_id table_id = - efx_filter_type_table_id(spec->type); - struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_table *table = efx_filter_spec_table(state, spec); struct efx_filter_spec *saved_spec; efx_oword_t filter; int filter_idx, depth; u32 key; int rc; - if (table->size == 0) + if (!table || table->size == 0) return -EINVAL; key = efx_filter_build(&filter, spec); netif_vdbg(efx, hw, efx->net_dev, "%s: type %d search_depth=%d", __func__, spec->type, - state->search_depth[spec->type]); + table->search_depth[spec->type]); spin_lock_bh(&state->lock); @@ -277,8 +412,8 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, } *saved_spec = *spec; - if (state->search_depth[spec->type] < depth) { - state->search_depth[spec->type] = depth; + if (table->search_depth[spec->type] < depth) { + table->search_depth[spec->type] = depth; efx_filter_push_rx_limits(efx); } @@ -287,7 +422,7 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, netif_vdbg(efx, hw, efx->net_dev, "%s: filter type %d index %d rxq %u set", __func__, spec->type, filter_idx, spec->dmaq_id); - rc = efx_filter_make_id(table_id, filter_idx); + rc = efx_filter_make_id(table->id, filter_idx); out: spin_unlock_bh(&state->lock); @@ -321,15 +456,16 @@ static void efx_filter_table_clear_entry(struct efx_nic *efx, int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec) { struct efx_filter_state *state = efx->filter_state; - enum efx_filter_table_id table_id = - efx_filter_type_table_id(spec->type); - struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_table *table = efx_filter_spec_table(state, spec); struct efx_filter_spec *saved_spec; efx_oword_t filter; int filter_idx, depth; u32 key; int rc; + if (!table) + return -EINVAL; + key = efx_filter_build(&filter, spec); spin_lock_bh(&state->lock); @@ -347,7 +483,7 @@ int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec) efx_filter_table_clear_entry(efx, table, filter_idx); if (table->used == 0) - efx_filter_table_reset_search_depth(state, table_id); + efx_filter_table_reset_search_depth(table); rc = 0; out: @@ -369,7 +505,7 @@ static void efx_filter_table_clear(struct efx_nic *efx, if (table->spec[filter_idx].priority <= priority) efx_filter_table_clear_entry(efx, table, filter_idx); if (table->used == 0) - efx_filter_table_reset_search_depth(state, table_id); + efx_filter_table_reset_search_depth(table); spin_unlock_bh(&state->lock); } @@ -427,6 +563,7 @@ int efx_probe_filters(struct efx_nic *efx) if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { table = &state->table[EFX_FILTER_TABLE_RX_IP]; + table->id = EFX_FILTER_TABLE_RX_IP; table->offset = FR_BZ_RX_FILTER_TBL0; table->size = FR_BZ_RX_FILTER_TBL0_ROWS; table->step = FR_BZ_RX_FILTER_TBL0_STEP; @@ -434,6 +571,7 @@ int efx_probe_filters(struct efx_nic *efx) if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) { table = &state->table[EFX_FILTER_TABLE_RX_MAC]; + table->id = EFX_FILTER_TABLE_RX_MAC; table->offset = FR_CZ_RX_MAC_FILTER_TBL0; table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS; table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP; diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h index d11e4aa78133..872f2132a496 100644 --- a/drivers/net/sfc/filter.h +++ b/drivers/net/sfc/filter.h @@ -14,23 +14,25 @@ /** * enum efx_filter_type - type of hardware filter - * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple - * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port) - * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple - * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port) - * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID - * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address + * @EFX_FILTER_TCP_FULL: Matching TCP/IPv4 4-tuple + * @EFX_FILTER_TCP_WILD: Matching TCP/IPv4 destination (host, port) + * @EFX_FILTER_UDP_FULL: Matching UDP/IPv4 4-tuple + * @EFX_FILTER_UDP_WILD: Matching UDP/IPv4 destination (host, port) + * @EFX_FILTER_MAC_FULL: Matching Ethernet destination MAC address, VID + * @EFX_FILTER_MAC_WILD: Matching Ethernet destination MAC address + * @EFX_FILTER_UNSPEC: Match type is unspecified * - * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types. + * Falcon NICs only support the TCP/IPv4 and UDP/IPv4 filter types. */ enum efx_filter_type { - EFX_FILTER_RX_TCP_FULL = 0, - EFX_FILTER_RX_TCP_WILD, - EFX_FILTER_RX_UDP_FULL, - EFX_FILTER_RX_UDP_WILD, - EFX_FILTER_RX_MAC_FULL = 4, - EFX_FILTER_RX_MAC_WILD, - EFX_FILTER_TYPE_COUNT, + EFX_FILTER_TCP_FULL = 0, + EFX_FILTER_TCP_WILD, + EFX_FILTER_UDP_FULL, + EFX_FILTER_UDP_WILD, + EFX_FILTER_MAC_FULL = 4, + EFX_FILTER_MAC_WILD, + EFX_FILTER_TYPE_COUNT, /* number of specific types */ + EFX_FILTER_UNSPEC = 0xf, }; /** @@ -57,13 +59,13 @@ enum efx_filter_priority { * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override * any IP filter that matches the same packet. By default, IP * filters take precedence. - * - * Currently, no flags are defined for TX filters. + * @EFX_FILTER_FLAG_RX: Filter is for RX */ enum efx_filter_flags { EFX_FILTER_FLAG_RX_RSS = 0x01, EFX_FILTER_FLAG_RX_SCATTER = 0x02, EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, + EFX_FILTER_FLAG_RX = 0x08, }; /** @@ -85,99 +87,26 @@ struct efx_filter_spec { u32 data[3]; }; -/** - * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match - * @spec: Specification to initialise - * @shost: Source host address (host byte order) - * @sport: Source port (host byte order) - * @dhost: Destination host address (host byte order) - * @dport: Destination port (host byte order) - */ -static inline void -efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec, - u32 shost, u16 sport, u32 dhost, u16 dport) -{ - spec->type = EFX_FILTER_RX_TCP_FULL; - spec->data[0] = sport | shost << 16; - spec->data[1] = dport << 16 | shost >> 16; - spec->data[2] = dhost; -} - -/** - * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match - * @spec: Specification to initialise - * @dhost: Destination host address (host byte order) - * @dport: Destination port (host byte order) - */ -static inline void -efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) -{ - spec->type = EFX_FILTER_RX_TCP_WILD; - spec->data[0] = 0; - spec->data[1] = dport << 16; - spec->data[2] = dhost; -} - -/** - * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match - * @spec: Specification to initialise - * @shost: Source host address (host byte order) - * @sport: Source port (host byte order) - * @dhost: Destination host address (host byte order) - * @dport: Destination port (host byte order) - */ -static inline void -efx_filter_set_rx_udp_full(struct efx_filter_spec *spec, - u32 shost, u16 sport, u32 dhost, u16 dport) -{ - spec->type = EFX_FILTER_RX_UDP_FULL; - spec->data[0] = sport | shost << 16; - spec->data[1] = dport << 16 | shost >> 16; - spec->data[2] = dhost; -} - -/** - * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match - * @spec: Specification to initialise - * @dhost: Destination host address (host byte order) - * @dport: Destination port (host byte order) - */ -static inline void -efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) -{ - spec->type = EFX_FILTER_RX_UDP_WILD; - spec->data[0] = dport; - spec->data[1] = 0; - spec->data[2] = dhost; -} - -/** - * efx_filter_set_rx_mac_full - specify RX filter with MAC full match - * @spec: Specification to initialise - * @vid: VLAN ID - * @addr: Destination MAC address - */ -static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec, - u16 vid, const u8 *addr) +static inline void efx_filter_init_rx(struct efx_filter_spec *spec, + enum efx_filter_priority priority, + enum efx_filter_flags flags, + unsigned rxq_id) { - spec->type = EFX_FILTER_RX_MAC_FULL; - spec->data[0] = vid; - spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; - spec->data[2] = addr[0] << 8 | addr[1]; + spec->type = EFX_FILTER_UNSPEC; + spec->priority = priority; + spec->flags = EFX_FILTER_FLAG_RX | flags; + spec->dmaq_id = rxq_id; } -/** - * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match - * @spec: Specification to initialise - * @addr: Destination MAC address - */ -static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec, - const u8 *addr) -{ - spec->type = EFX_FILTER_RX_MAC_WILD; - spec->data[0] = 0; - spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; - spec->data[2] = addr[0] << 8 | addr[1]; -} +extern int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto, + __be32 host, __be16 port); +extern int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto, + __be32 host, __be16 port, + __be32 rhost, __be16 rport); +extern int efx_filter_set_eth_local(struct efx_filter_spec *spec, + u16 vid, const u8 *addr); +enum { + EFX_FILTER_VID_UNSPEC = 0xffff, +}; #endif /* EFX_FILTER_H */ -- cgit v1.2.3-59-g8ed1b From 541a45a142df281c974d74eac2066138fc107b23 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 2 Dec 2010 19:12:43 +0900 Subject: nl80211/mac80211: Report signal average Extend nl80211 to report an exponential weighted moving average (EWMA) of the signal value. Since the signal value usually fluctuates between different packets, an average can be more useful than the value of the last packet. This uses the recently added generic EWMA library function. -- v2: fix ABI breakage and change factor to be a power of 2. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ include/net/cfg80211.h | 4 ++++ net/mac80211/Kconfig | 1 + net/mac80211/cfg.c | 3 ++- net/mac80211/rx.c | 1 + net/mac80211/sta_info.c | 2 ++ net/mac80211/sta_info.h | 3 +++ net/wireless/nl80211.c | 3 +++ 8 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 410a06ea551b..8e28053ea423 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1191,6 +1191,7 @@ enum nl80211_rate_info { * station) * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) + * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID, @@ -1206,6 +1207,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_PACKETS, NL80211_STA_INFO_TX_RETRIES, NL80211_STA_INFO_TX_FAILED, + NL80211_STA_INFO_SIGNAL_AVG, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 788c3989a9e8..8764c9a5bab7 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -420,6 +420,7 @@ struct station_parameters { * @STATION_INFO_TX_RETRIES: @tx_retries filled * @STATION_INFO_TX_FAILED: @tx_failed filled * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled + * @STATION_INFO_SIGNAL_AVG: @signal_avg filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -435,6 +436,7 @@ enum station_info_flags { STATION_INFO_TX_RETRIES = 1<<10, STATION_INFO_TX_FAILED = 1<<11, STATION_INFO_RX_DROP_MISC = 1<<12, + STATION_INFO_SIGNAL_AVG = 1<<13, }; /** @@ -481,6 +483,7 @@ struct rate_info { * @plid: mesh peer link id * @plink_state: mesh peer link state * @signal: signal strength of last received packet in dBm + * @signal_avg: signal strength average in dBm * @txrate: current unicast bitrate to this station * @rx_packets: packets received from this station * @tx_packets: packets transmitted to this station @@ -501,6 +504,7 @@ struct station_info { u16 plid; u8 plink_state; s8 signal; + s8 signal_avg; struct rate_info txrate; u32 rx_packets; u32 tx_packets; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 4d6f8653ec88..798d9b9462e2 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -6,6 +6,7 @@ config MAC80211 select CRYPTO_ARC4 select CRYPTO_AES select CRC32 + select AVERAGE ---help--- This option enables the hardware independent IEEE 802.11 networking stack. diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 68329d713c02..af9620406321 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -342,8 +342,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { - sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; sinfo->signal = (s8)sta->last_signal; + sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } sinfo->txrate.flags = 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6289525c0998..2fe8f5f86499 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1163,6 +1163,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->rx_fragments++; sta->rx_bytes += rx->skb->len; sta->last_signal = status->signal; + ewma_add(&sta->avg_signal, -status->signal); /* * Change STA power saving mode only at the end of a frame diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index eff58571fd7e..c426504ed1cf 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -244,6 +244,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->local = local; sta->sdata = sdata; + ewma_init(&sta->avg_signal, 1024, 8); + if (sta_prepare_rate_control(local, sta, gfp)) { kfree(sta); return NULL; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 05f11302443b..fdca52cf88de 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "key.h" /** @@ -223,6 +224,7 @@ enum plink_state { * @rx_fragments: number of received MPDUs * @rx_dropped: number of dropped MPDUs from this STA * @last_signal: signal of last received frame from this STA + * @avg_signal: moving average of signal of received frames from this STA * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) * @tx_filtered_count: number of frames the hardware filtered for this STA * @tx_retry_failed: number of frames that failed retry @@ -291,6 +293,7 @@ struct sta_info { unsigned long rx_fragments; unsigned long rx_dropped; int last_signal; + struct ewma avg_signal; __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; /* Updated from TX status path only, no locking requirements */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 56508d40c740..2cf03331d4a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1896,6 +1896,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_SIGNAL) NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, sinfo->signal); + if (sinfo->filled & STATION_INFO_SIGNAL_AVG) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, + sinfo->signal_avg); if (sinfo->filled & STATION_INFO_TX_BITRATE) { txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); if (!txrate) -- cgit v1.2.3-59-g8ed1b From 329b32fedc94fd9158f1635ac64f4ae6a00d374c Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Thu, 2 Dec 2010 18:19:21 +0000 Subject: orinoco: allow IW_AUTH_MFP to pass through The card doesn't support MFP, so silently accept DISABLED and OPTIONAL settings. This avoids the following failure in wpa_supplicant logs: State: SCANNING -> ASSOCIATING wpa_driver_wext_set_operstate: operstate 0->0 (DORMANT) netlink: Operstate: linkmode=-1, operstate=5 wpa_driver_wext_associate wpa_driver_wext_set_drop_unencrypted wpa_driver_wext_set_psk wpa_driver_wext_associate: assoc failed because set_auth_param(IW_AUTH_MFP) failed Association request to the driver failed Signed-off by: David Kilroy Reported by: Giacomo Comes Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/wext.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf97..8e65ffc4cb0a 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -893,6 +893,14 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, */ break; + case IW_AUTH_MFP: + /* Management Frame Protection not supported. + * Only fail if set to required. + */ + if (param->value == IW_AUTH_MFP_REQUIRED) + ret = -EINVAL; + break; + case IW_AUTH_KEY_MGMT: /* wl_lkm implies value 2 == PSK for Hermes I * which ties in with WEXT -- cgit v1.2.3-59-g8ed1b From 0ab82b04ac83a05bda3ef8499f415fc6fd6ee206 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Fri, 3 Dec 2010 02:16:23 +0200 Subject: mac80211: fix dynamic-ps/pm_qos magic numbers mac80211 uses pm_qos (/dev/network_latency) in order to determine the dynamic ps timeout (or disable the dynamic-ps at all in some cases). commit ff616381 added a comparison for the current network_latency against one high value (1900ms), and against the default value (2000sec, rather than the commented 2sec). however, the representation of 1900ms was incorrect: 1900ms = 1900000us ( != 1900000000 ) fix it by using USEC_TO_MSEC/SEC consts. Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3a1dde3c7956..59e2e06aa4e9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -625,11 +625,12 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) /* * Go to full PSM if the user configures a very low * latency requirement. - * The 2 second value is there for compatibility until - * the PM_QOS_NETWORK_LATENCY is configured with real - * values. + * The 2000 second value is there for compatibility + * until the PM_QOS_NETWORK_LATENCY is configured + * with real values. */ - if (latency > 1900000000 && latency != 2000000000) + if (latency > (1900 * USEC_PER_MSEC) && + latency != (2000 * USEC_PER_SEC)) timeout = 0; else timeout = 100; -- cgit v1.2.3-59-g8ed1b From 21a99f934949807dc0c9dc7642bbf0081b7582f9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 2 Dec 2010 19:12:35 -0800 Subject: ath: Add and use ath_printk and ath_ Add ath_printk and ath_ similar to dev_printk and dev_ from device.h This allows a more gradual rename of ath_print to to ath_dbg or perhaps ath_debug. This basically removes debug.h leaving only an #define ath_printk ath_dbg there and moving all the ATH_DBG_ enums to ath.h I do not think there's much purpose for struct ath_common * being passed to the ath_printk functions, but perhaps there might be. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 103 +++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/debug.c | 20 -------- drivers/net/wireless/ath/debug.h | 72 +-------------------------- drivers/net/wireless/ath/main.c | 20 ++++++++ 4 files changed, 124 insertions(+), 91 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 26bdbeee424f..c914f5213c61 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -186,4 +186,107 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); +extern __attribute__ ((format (printf, 3, 4))) int +ath_printk(const char *level, struct ath_common *common, const char *fmt, ...); + +#define ath_emerg(common, fmt, ...) \ + ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) +#define ath_alert(common, fmt, ...) \ + ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) +#define ath_crit(common, fmt, ...) \ + ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) +#define ath_err(common, fmt, ...) \ + ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) +#define ath_warn(common, fmt, ...) \ + ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) +#define ath_notice(common, fmt, ...) \ + ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) +#define ath_info(common, fmt, ...) \ + ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) + +/** + * enum ath_debug_level - atheros wireless debug level + * + * @ATH_DBG_RESET: reset processing + * @ATH_DBG_QUEUE: hardware queue management + * @ATH_DBG_EEPROM: eeprom processing + * @ATH_DBG_CALIBRATE: periodic calibration + * @ATH_DBG_INTERRUPT: interrupt processing + * @ATH_DBG_REGULATORY: regulatory processing + * @ATH_DBG_ANI: adaptive noise immunitive processing + * @ATH_DBG_XMIT: basic xmit operation + * @ATH_DBG_BEACON: beacon handling + * @ATH_DBG_CONFIG: configuration of the hardware + * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT + * @ATH_DBG_PS: power save processing + * @ATH_DBG_HWTIMER: hardware timer handling + * @ATH_DBG_BTCOEX: bluetooth coexistance + * @ATH_DBG_BSTUCK: stuck beacons + * @ATH_DBG_ANY: enable all debugging + * + * The debug level is used to control the amount and type of debugging output + * we want to see. Each driver has its own method for enabling debugging and + * modifying debug level states -- but this is typically done through a + * module parameter 'debug' along with a respective 'debug' debugfs file + * entry. + */ +enum ATH_DEBUG { + ATH_DBG_RESET = 0x00000001, + ATH_DBG_QUEUE = 0x00000002, + ATH_DBG_EEPROM = 0x00000004, + ATH_DBG_CALIBRATE = 0x00000008, + ATH_DBG_INTERRUPT = 0x00000010, + ATH_DBG_REGULATORY = 0x00000020, + ATH_DBG_ANI = 0x00000040, + ATH_DBG_XMIT = 0x00000080, + ATH_DBG_BEACON = 0x00000100, + ATH_DBG_CONFIG = 0x00000200, + ATH_DBG_FATAL = 0x00000400, + ATH_DBG_PS = 0x00000800, + ATH_DBG_HWTIMER = 0x00001000, + ATH_DBG_BTCOEX = 0x00002000, + ATH_DBG_WMI = 0x00004000, + ATH_DBG_BSTUCK = 0x00008000, + ATH_DBG_ANY = 0xffffffff +}; + +#define ATH_DBG_DEFAULT (ATH_DBG_FATAL) + +#ifdef CONFIG_ATH_DEBUG + +#define ath_dbg(common, dbg_mask, fmt, ...) \ +({ \ + int rtn; \ + if ((common)->debug_mask & dbg_mask) \ + rtn = ath_printk(KERN_DEBUG, common, fmt, \ + ##__VA_ARGS__); \ + else \ + rtn = 0; \ + \ + rtn; \ +}) +#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) + +#else + +static inline __attribute__ ((format (printf, 3, 4))) int +ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, + const char *fmt, ...) +{ + return 0; +} +#define ATH_DBG_WARN(foo, arg...) do {} while (0) + +#endif /* CONFIG_ATH_DEBUG */ + +/** Returns string describing opmode, or NULL if unknown mode. */ +#ifdef CONFIG_ATH_DEBUG +const char *ath_opmode_to_string(enum nl80211_iftype opmode); +#else +static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +{ + return "UNKNOWN"; +} +#endif + #endif /* ATH_H */ diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c index a9600ba8ceaa..5367b1086e09 100644 --- a/drivers/net/wireless/ath/debug.c +++ b/drivers/net/wireless/ath/debug.c @@ -15,26 +15,6 @@ */ #include "ath.h" -#include "debug.h" - -void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - - if (likely(!(common->debug_mask & dbg_mask))) - return; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - printk(KERN_DEBUG "ath: %pV", &vaf); - - va_end(args); -} -EXPORT_SYMBOL(ath_print); const char *ath_opmode_to_string(enum nl80211_iftype opmode) { diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index f207007ee391..cec951cdfac1 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -17,76 +17,6 @@ #ifndef ATH_DEBUG_H #define ATH_DEBUG_H -#include "ath.h" - -/** - * enum ath_debug_level - atheros wireless debug level - * - * @ATH_DBG_RESET: reset processing - * @ATH_DBG_QUEUE: hardware queue management - * @ATH_DBG_EEPROM: eeprom processing - * @ATH_DBG_CALIBRATE: periodic calibration - * @ATH_DBG_INTERRUPT: interrupt processing - * @ATH_DBG_REGULATORY: regulatory processing - * @ATH_DBG_ANI: adaptive noise immunitive processing - * @ATH_DBG_XMIT: basic xmit operation - * @ATH_DBG_BEACON: beacon handling - * @ATH_DBG_CONFIG: configuration of the hardware - * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT - * @ATH_DBG_PS: power save processing - * @ATH_DBG_HWTIMER: hardware timer handling - * @ATH_DBG_BTCOEX: bluetooth coexistance - * @ATH_DBG_BSTUCK: stuck beacons - * @ATH_DBG_ANY: enable all debugging - * - * The debug level is used to control the amount and type of debugging output - * we want to see. Each driver has its own method for enabling debugging and - * modifying debug level states -- but this is typically done through a - * module parameter 'debug' along with a respective 'debug' debugfs file - * entry. - */ -enum ATH_DEBUG { - ATH_DBG_RESET = 0x00000001, - ATH_DBG_QUEUE = 0x00000002, - ATH_DBG_EEPROM = 0x00000004, - ATH_DBG_CALIBRATE = 0x00000008, - ATH_DBG_INTERRUPT = 0x00000010, - ATH_DBG_REGULATORY = 0x00000020, - ATH_DBG_ANI = 0x00000040, - ATH_DBG_XMIT = 0x00000080, - ATH_DBG_BEACON = 0x00000100, - ATH_DBG_CONFIG = 0x00000200, - ATH_DBG_FATAL = 0x00000400, - ATH_DBG_PS = 0x00000800, - ATH_DBG_HWTIMER = 0x00001000, - ATH_DBG_BTCOEX = 0x00002000, - ATH_DBG_WMI = 0x00004000, - ATH_DBG_BSTUCK = 0x00008000, - ATH_DBG_ANY = 0xffffffff -}; - -#define ATH_DBG_DEFAULT (ATH_DBG_FATAL) - -#ifdef CONFIG_ATH_DEBUG -void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) - __attribute__ ((format (printf, 3, 4))); -#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) -#else -static inline void __attribute__ ((format (printf, 3, 4))) -ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) -{ -} -#define ATH_DBG_WARN(foo, arg) -#endif /* CONFIG_ATH_DEBUG */ - -/** Returns string describing opmode, or NULL if unknown mode. */ -#ifdef CONFIG_ATH_DEBUG -const char *ath_opmode_to_string(enum nl80211_iftype opmode); -#else -static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) -{ - return "UNKNOWN"; -} -#endif +#define ath_print ath_dbg #endif /* ATH_DEBUG_H */ diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index 487193f1de1a..c325202fdc5f 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c @@ -56,3 +56,23 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, return skb; } EXPORT_SYMBOL(ath_rxbuf_alloc); + +int ath_printk(const char *level, struct ath_common *common, + const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + int rtn; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + rtn = printk("%sath: %pV", level, &vaf); + + va_end(args); + + return rtn; +} +EXPORT_SYMBOL(ath_printk); -- cgit v1.2.3-59-g8ed1b From 3800276a40751539a920ef8e0537ef2e19126799 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 2 Dec 2010 19:12:36 -0800 Subject: ath: Convert ath_print(.., ATH_DBG_FATAL to ath_err So these errors are always emitted at KERN_ERR level. Remove ARRAY_SIZE casts, use printf type %zu Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 7 +-- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 12 ++-- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 6 +- drivers/net/wireless/ath/ath9k/beacon.c | 14 ++--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 13 ++--- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 13 ++--- drivers/net/wireless/ath/ath9k/eeprom_def.c | 14 ++--- drivers/net/wireless/ath/ath9k/gpio.c | 4 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 4 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 27 ++++----- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 59 +++++++++---------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 25 ++++---- drivers/net/wireless/ath/ath9k/hw.c | 78 +++++++++++-------------- drivers/net/wireless/ath/ath9k/init.c | 6 +- drivers/net/wireless/ath/ath9k/mac.c | 31 +++++----- drivers/net/wireless/ath/ath9k/main.c | 56 ++++++++---------- drivers/net/wireless/ath/ath9k/pci.c | 7 +-- drivers/net/wireless/ath/ath9k/rc.c | 4 +- drivers/net/wireless/ath/ath9k/recv.c | 15 +++-- drivers/net/wireless/ath/ath9k/xmit.c | 30 +++++----- drivers/net/wireless/ath/key.c | 15 ++--- 21 files changed, 186 insertions(+), 254 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 1a984b02e9e5..25a6e4417cdb 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -35,10 +35,9 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) pdata = (struct ath9k_platform_data *) pdev->dev.platform_data; if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { - ath_print(common, ATH_DBG_FATAL, - "%s: flash read failed, offset %08x " - "is out of range\n", - __func__, off); + ath_err(common, + "%s: flash read failed, offset %08x is out of range\n", + __func__, off); return false; } diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 06e34d293dc8..9af9f23af3c4 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -173,8 +173,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = ((freq - 704) * 2 - 3040) / 10; bModeSynth = 1; } else { - ath_print(common, ATH_DBG_FATAL, - "Invalid channel %u MHz\n", freq); + ath_err(common, "Invalid channel %u MHz\n", freq); return -EINVAL; } @@ -206,8 +205,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); aModeRefSel = ath9k_hw_reverse_bits(1, 2); } else { - ath_print(common, ATH_DBG_FATAL, - "Invalid channel %u MHz\n", freq); + ath_err(common, "Invalid channel %u MHz\n", freq); return -EINVAL; } @@ -448,8 +446,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) #define ATH_ALLOC_BANK(bank, size) do { \ bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ if (!bank) { \ - ath_print(common, ATH_DBG_FATAL, \ - "Cannot allocate RF banks\n"); \ + ath_err(common, "Cannot allocate RF banks\n"); \ return -ENOMEM; \ } \ } while (0); @@ -879,8 +876,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, /* Write analog registers */ if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "ar5416SetRfRegs failed\n"); + ath_err(ath9k_hw_common(ah), "ar5416SetRfRegs failed\n"); return -EIO; } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 48261b7252d0..7d5cb204f938 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -494,9 +494,9 @@ int ar9002_hw_rf_claim(struct ath_hw *ah) case AR_RAD2122_SREV_MAJOR: break; default: - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Radio Chip Rev 0x%02X not supported\n", - val & AR_RADIO_SREV_MAJOR); + ath_err(ath9k_hw_common(ah), + "Radio Chip Rev 0x%02X not supported\n", + val & AR_RADIO_SREV_MAJOR); return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 47bedd82e9a9..70019e93e739 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -46,8 +46,8 @@ int ath_beaconq_config(struct ath_softc *sc) } if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to update h/w beacon queue parameters\n"); + ath_err(common, + "Unable to update h/w beacon queue parameters\n"); return 0; } else { ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); @@ -189,8 +189,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(common, ATH_DBG_FATAL, - "dma_mapping_error on beaconing\n"); + ath_err(common, "dma_mapping_error on beaconing\n"); return NULL; } @@ -324,8 +323,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(common, ATH_DBG_FATAL, - "dma_mapping_error on beacon alloc\n"); + ath_err(common, "dma_mapping_error on beacon alloc\n"); return -ENOMEM; } @@ -469,8 +467,8 @@ void ath_beacon_tasklet(unsigned long data) * are still pending on the queue. */ if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) { - ath_print(common, ATH_DBG_FATAL, - "beacon queue %u did not stop?\n", sc->beacon.beaconq); + ath_err(common, "beacon queue %u did not stop?\n", + sc->beacon.beaconq); } /* NB: cabq traffic should already be queued and primed */ diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index c2481b3ac7e6..f74692da24db 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -69,8 +69,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) if (!ath9k_hw_use_flash(ah)) { if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { - ath_print(common, ATH_DBG_FATAL, - "Reading Magic # failed\n"); + ath_err(common, "Reading Magic # failed\n"); return false; } @@ -90,9 +89,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) eepdata++; } } else { - ath_print(common, ATH_DBG_FATAL, - "Invalid EEPROM Magic. " - "endianness mismatch.\n"); + ath_err(common, + "Invalid EEPROM Magic. endianness mismatch.\n"); return -EINVAL; } } @@ -163,9 +161,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { - ath_print(common, ATH_DBG_FATAL, - "Bad EEPROM checksum 0x%x or revision 0x%04x\n", - sum, ah->eep_ops->get_eeprom_ver(ah)); + ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", + sum, ah->eep_ops->get_eeprom_ver(ah)); return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index bcb9ed39c047..9308b684eaa2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -72,8 +72,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) if (!ath9k_hw_use_flash(ah)) { if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { - ath_print(common, ATH_DBG_FATAL, - "Reading Magic # failed\n"); + ath_err(common, "Reading Magic # failed\n"); return false; } @@ -93,9 +92,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) eepdata++; } } else { - ath_print(common, ATH_DBG_FATAL, - "Invalid EEPROM Magic. " - "Endianness mismatch.\n"); + ath_err(common, + "Invalid EEPROM Magic. Endianness mismatch.\n"); return -EINVAL; } } @@ -160,9 +158,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { - ath_print(common, ATH_DBG_FATAL, - "Bad EEPROM checksum 0x%x or revision 0x%04x\n", - sum, ah->eep_ops->get_eeprom_ver(ah)); + ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", + sum, ah->eep_ops->get_eeprom_ver(ah)); return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 45f70b2404a1..864a877bc05a 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -96,8 +96,8 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc, eep_data)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Unable to read eeprom region\n"); + ath_err(ath9k_hw_common(ah), + "Unable to read eeprom region\n"); return false; } eep_data++; @@ -117,7 +117,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) int i, addr, size; if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { - ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n"); + ath_err(common, "Reading Magic # failed\n"); return false; } @@ -139,9 +139,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) eepdata++; } } else { - ath_print(common, ATH_DBG_FATAL, - "Invalid EEPROM Magic. " - "Endianness mismatch.\n"); + ath_err(common, + "Invalid EEPROM Magic. Endianness mismatch.\n"); return -EINVAL; } } @@ -216,8 +215,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { - ath_print(common, ATH_DBG_FATAL, - "Bad EEPROM checksum 0x%x or revision 0x%04x\n", + ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", sum, ah->eep_ops->get_eeprom_ver(ah)); return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 6a1a482f9dc3..2b1b58306662 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -103,8 +103,8 @@ static int ath_register_led(struct ath_softc *sc, struct ath_led *led, ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); if (ret) - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Failed to register led:%s", led->name); + ath_err(ath9k_hw_common(sc->sc_ah), + "Failed to register led:%s", led->name); else led->registered = 1; return ret; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 1b72aa482ac7..dd9514e019ea 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -246,8 +246,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) qi.tqi_cwmax = qi_be.tqi_cwmax; if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Unable to update beacon queue %u!\n", qnum); + ath_err(ath9k_hw_common(ah), + "Unable to update beacon queue %u!\n", qnum); } else { ath9k_hw_resettxqueue(ah, priv->beaconq); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 071d0c974747..20b32f614c1f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -495,37 +495,31 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) priv->beaconq = ath9k_hw_beaconq_setup(priv->ah); if (priv->beaconq == -1) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup BEACON xmit queue\n"); + ath_err(common, "Unable to setup BEACON xmit queue\n"); goto err; } priv->cabq = ath9k_htc_cabq_setup(priv); if (priv->cabq == -1) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup CAB xmit queue\n"); + ath_err(common, "Unable to setup CAB xmit queue\n"); goto err; } if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); + ath_err(common, "Unable to setup xmit queue for BE traffic\n"); goto err; } if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); + ath_err(common, "Unable to setup xmit queue for BK traffic\n"); goto err; } if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); + ath_err(common, "Unable to setup xmit queue for VI traffic\n"); goto err; } if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); + ath_err(common, "Unable to setup xmit queue for VO traffic\n"); goto err; } @@ -670,16 +664,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ret = ath9k_hw_init(ah); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to initialize hardware; " - "initialization status: %d\n", ret); + ath_err(common, + "Unable to initialize hardware; initialization status: %d\n", + ret); goto err_hw; } ret = ath9k_htc_init_debug(ah); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to create debugfs files\n"); + ath_err(common, "Unable to create debugfs files\n"); goto err_debug; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8266ce1f02e3..a8007af4e149 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -152,9 +152,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, caldata = &priv->caldata[channel->hw_value]; ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset channel (%u Mhz) " - "reset status %d\n", channel->center_freq, ret); + ath_err(common, + "Unable to reset channel (%u Mhz) reset status %d\n", + channel->center_freq, ret); goto err; } @@ -263,8 +263,9 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { if (sta) - ath_print(common, ATH_DBG_FATAL, - "Unable to add station entry for: %pM\n", sta->addr); + ath_err(common, + "Unable to add station entry for: %pM\n", + sta->addr); return ret; } @@ -296,9 +297,9 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); if (ret) { if (sta) - ath_print(common, ATH_DBG_FATAL, - "Unable to remove station entry for: %pM\n", - sta->addr); + ath_err(common, + "Unable to remove station entry for: %pM\n", + sta->addr); return ret; } @@ -390,8 +391,8 @@ static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv, WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to initialize Rate information on target\n"); + ath_err(common, + "Unable to initialize Rate information on target\n"); } return ret; @@ -895,8 +896,8 @@ static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); if (ret) - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, - "Failed to register led:%s", led->name); + ath_err(ath9k_hw_common(priv->ah), + "Failed to register led:%s", led->name); else led->registered = 1; @@ -1024,9 +1025,9 @@ static void ath9k_htc_radio_enable(struct ieee80211_hw *hw) /* Reset the HW */ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d " - "(freq %u MHz)\n", ret, ah->curchan->channel); + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); } ath_update_txpow(priv); @@ -1087,9 +1088,9 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) /* Reset the HW */ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d " - "(freq %u MHz)\n", ret, ah->curchan->channel); + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); } /* Disable the PHY */ @@ -1175,9 +1176,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ath9k_hw_htc_resetinit(ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d " - "(freq %u MHz)\n", ret, curchan->center_freq); + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, curchan->center_freq); mutex_unlock(&priv->mutex); return ret; } @@ -1243,8 +1244,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) /* Remove monitor interface here */ if (ah->opmode == NL80211_IFTYPE_MONITOR) { if (ath9k_htc_remove_monitor_interface(priv)) - ath_print(common, ATH_DBG_FATAL, - "Unable to remove monitor interface\n"); + ath_err(common, "Unable to remove monitor interface\n"); else ath_print(common, ATH_DBG_CONFIG, "Monitor interface removed\n"); @@ -1298,7 +1298,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, hvif.opmode = cpu_to_be32(HTC_M_IBSS); break; default: - ath_print(common, ATH_DBG_FATAL, + ath_err(common, "Interface type %d not yet supported\n", vif->type); ret = -EOPNOTSUPP; goto out; @@ -1405,8 +1405,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) hw->conf.channel_type); if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { - ath_print(common, ATH_DBG_FATAL, - "Unable to set channel\n"); + ath_err(common, "Unable to set channel\n"); mutex_unlock(&priv->mutex); return -EINVAL; } @@ -1426,8 +1425,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { if (ath9k_htc_add_monitor_interface(priv)) - ath_print(common, ATH_DBG_FATAL, - "Failed to set monitor mode\n"); + ath_err(common, "Failed to set monitor mode\n"); else ath_print(common, ATH_DBG_CONFIG, "HW opmode set to Monitor mode\n"); @@ -1552,7 +1550,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, ret = ath_htc_txq_update(priv, qnum, &qi); if (ret) { - ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); + ath_err(common, "TXQ Update failed\n"); goto out; } @@ -1764,8 +1762,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, spin_unlock_bh(&priv->tx_lock); break; default: - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, - "Unknown AMPDU action\n"); + ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); } return ret; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 77958675b55f..5bef41f8c82b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -69,8 +69,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, qi.tqi_readyTime = qinfo->tqi_readyTime; if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Unable to update hardware queue %u!\n", qnum); + ath_err(ath9k_hw_common(ah), + "Unable to update hardware queue %u!\n", qnum); error = -EIO; } else { ath9k_hw_resettxqueue(ah, qnum); @@ -296,8 +296,7 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, (ep_id == priv->data_vo_ep)) { skb_pull(skb, sizeof(struct tx_frame_hdr)); } else { - ath_print(common, ATH_DBG_FATAL, - "Unsupported TX EPID: %d\n", ep_id); + ath_err(common, "Unsupported TX EPID: %d\n", ep_id); dev_kfree_skb_any(skb); return; } @@ -337,9 +336,8 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype) return false; if (qnum >= ARRAY_SIZE(priv->hwq_map)) { - ath_print(common, ATH_DBG_FATAL, - "qnum %u out of range, max %u!\n", - qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map)); + ath_err(common, "qnum %u out of range, max %zu!\n", + qnum, ARRAY_SIZE(priv->hwq_map)); ath9k_hw_releasetxqueue(ah, qnum); return false; } @@ -490,8 +488,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, __le16 fc; if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { - ath_print(common, ATH_DBG_FATAL, - "Corrupted RX frame, dropping\n"); + ath_err(common, "Corrupted RX frame, dropping\n"); goto rx_next; } @@ -499,10 +496,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, if (be16_to_cpu(rxstatus->rs_datalen) - (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) { - ath_print(common, ATH_DBG_FATAL, - "Corrupted RX data len, dropping " - "(dlen: %d, skblen: %d)\n", - rxstatus->rs_datalen, skb->len); + ath_err(common, + "Corrupted RX data len, dropping (dlen: %d, skblen: %d)\n", + rxstatus->rs_datalen, skb->len); goto rx_next; } @@ -728,8 +724,7 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv) for (i = 0; i < ATH9K_HTC_RXBUF; i++) { rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL); if (rxbuf == NULL) { - ath_print(common, ATH_DBG_FATAL, - "Unable to allocate RX buffers\n"); + ath_err(common, "Unable to allocate RX buffers\n"); goto err; } list_add_tail(&rxbuf->list, &priv->rx.rxbuf); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9b1ee7fc05c1..00ecbfa07df5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -211,8 +211,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah, } break; default: - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Unknown phy %u (rate ix %u)\n", phy, rateix); + ath_err(ath9k_hw_common(ah), + "Unknown phy %u (rate ix %u)\n", phy, rateix); txTime = 0; break; } @@ -331,11 +331,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) REG_WRITE(ah, addr, wrData); rdData = REG_READ(ah, addr); if (rdData != wrData) { - ath_print(common, ATH_DBG_FATAL, - "address test failed " - "addr: 0x%08x - wr:0x%08x != " - "rd:0x%08x\n", - addr, wrData, rdData); + ath_err(common, + "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", + addr, wrData, rdData); return false; } } @@ -344,11 +342,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) REG_WRITE(ah, addr, wrData); rdData = REG_READ(ah, addr); if (wrData != rdData) { - ath_print(common, ATH_DBG_FATAL, - "address test failed " - "addr: 0x%08x - wr:0x%08x != " - "rd:0x%08x\n", - addr, wrData, rdData); + ath_err(common, + "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", + addr, wrData, rdData); return false; } } @@ -476,9 +472,8 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ecode = ath9k_hw_rf_alloc_ext_banks(ah); if (ecode) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Failed allocating banks for " - "external radio\n"); + ath_err(ath9k_hw_common(ah), + "Failed allocating banks for external radio\n"); ath9k_hw_rf_free_ext_banks(ah); return ecode; } @@ -509,8 +504,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ah->hw_version.macVersion = AR_SREV_VERSION_9100; if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { - ath_print(common, ATH_DBG_FATAL, - "Couldn't reset chip\n"); + ath_err(common, "Couldn't reset chip\n"); return -EIO; } @@ -520,7 +514,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_attach_ops(ah); if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { - ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); + ath_err(common, "Couldn't wakeup chip\n"); return -EIO; } @@ -545,10 +539,9 @@ static int __ath9k_hw_init(struct ath_hw *ah) ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; if (!ath9k_hw_macversion_supported(ah)) { - ath_print(common, ATH_DBG_FATAL, - "Mac Chip Rev 0x%02x.%x is not supported by " - "this driver\n", ah->hw_version.macVersion, - ah->hw_version.macRev); + ath_err(common, + "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", + ah->hw_version.macVersion, ah->hw_version.macRev); return -EOPNOTSUPP; } @@ -594,8 +587,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) r = ath9k_hw_init_macaddr(ah); if (r) { - ath_print(common, ATH_DBG_FATAL, - "Failed to initialize MAC address\n"); + ath_err(common, "Failed to initialize MAC address\n"); return r; } @@ -633,17 +625,16 @@ int ath9k_hw_init(struct ath_hw *ah) default: if (common->bus_ops->ath_bus_type == ATH_USB) break; - ath_print(common, ATH_DBG_FATAL, - "Hardware device ID 0x%04x not supported\n", - ah->hw_version.devid); + ath_err(common, "Hardware device ID 0x%04x not supported\n", + ah->hw_version.devid); return -EOPNOTSUPP; } ret = __ath9k_hw_init(ah); if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to initialize hardware; " - "initialization status: %d\n", ret); + ath_err(common, + "Unable to initialize hardware; initialization status: %d\n", + ret); return ret; } @@ -1145,8 +1136,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, } if (!ath9k_hw_rfbus_req(ah)) { - ath_print(common, ATH_DBG_FATAL, - "Could not kill baseband RX\n"); + ath_err(common, "Could not kill baseband RX\n"); return false; } @@ -1154,8 +1144,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, r = ath9k_hw_rf_set_freq(ah, chan); if (r) { - ath_print(common, ATH_DBG_FATAL, - "Failed to set channel\n"); + ath_err(common, "Failed to set channel\n"); return false; } ath9k_hw_set_clockrate(ah); @@ -1287,7 +1276,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } if (!ath9k_hw_chip_reset(ah, chan)) { - ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n"); + ath_err(common, "Chip reset failed\n"); return -EINVAL; } @@ -1568,9 +1557,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) AR_RTC_FORCE_WAKE_EN); } if (i == 0) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Failed to wakeup in %uus\n", - POWER_UP_TIME / 20); + ath_err(ath9k_hw_common(ah), + "Failed to wakeup in %uus\n", + POWER_UP_TIME / 20); return false; } } @@ -1609,8 +1598,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) ath9k_set_power_network_sleep(ah, setChip); break; default: - ath_print(common, ATH_DBG_FATAL, - "Unknown power mode %u\n", mode); + ath_err(common, "Unknown power mode %u\n", mode); return false; } ah->power_mode = mode; @@ -1801,8 +1789,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) { - ath_print(common, ATH_DBG_FATAL, - "no band has been marked as supported in EEPROM.\n"); + ath_err(common, + "no band has been marked as supported in EEPROM\n"); return -EINVAL; } @@ -2348,9 +2336,9 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); if (timer == NULL) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "Failed to allocate memory" - "for hw timer[%d]\n", timer_index); + ath_err(ath9k_hw_common(ah), + "Failed to allocate memory for hw timer[%d]\n", + timer_index); return NULL; } diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 918308a28410..2b519b387a29 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -283,8 +283,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, /* ath_desc must be a multiple of DWORDs */ if ((desc_len % 4) != 0) { - ath_print(common, ATH_DBG_FATAL, - "ath_desc not DWORD aligned\n"); + ath_err(common, "ath_desc not DWORD aligned\n"); BUG_ON((desc_len % 4) != 0); error = -ENOMEM; goto fail; @@ -736,8 +735,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, error = ath9k_init_debug(ah); if (error) { - ath_print(common, ATH_DBG_FATAL, - "Unable to create debugfs files\n"); + ath_err(common, "Unable to create debugfs files\n"); goto error_world; } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index b04b37b1124b..b96e750d4c37 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -204,9 +204,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) wait = wait_time; while (ath9k_hw_numtxpending(ah, q)) { if ((--wait) == 0) { - ath_print(common, ATH_DBG_FATAL, - "Failed to stop TX DMA in 100 " - "msec after killing last frame\n"); + ath_err(common, + "Failed to stop TX DMA in 100 msec after killing last frame\n"); break; } udelay(ATH9K_TIME_QUANTUM); @@ -368,14 +367,12 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, ATH9K_TX_QUEUE_INACTIVE) break; if (q == pCap->total_queues) { - ath_print(common, ATH_DBG_FATAL, - "No available TX queue\n"); + ath_err(common, "No available TX queue\n"); return -1; } break; default: - ath_print(common, ATH_DBG_FATAL, - "Invalid TX queue type: %u\n", type); + ath_err(common, "Invalid TX queue type: %u\n", type); return -1; } @@ -383,8 +380,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, qi = &ah->txq[q]; if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_FATAL, - "TX queue: %u already active\n", q); + ath_err(common, "TX queue: %u already active\n", q); return -1; } memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); @@ -735,9 +731,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) AR_DIAG_RX_ABORT)); reg = REG_READ(ah, AR_OBS_BUS_1); - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "RX failed to go idle in 10 ms RXSM=0x%x\n", - reg); + ath_err(ath9k_hw_common(ah), + "RX failed to go idle in 10 ms RXSM=0x%x\n", + reg); return false; } @@ -791,12 +787,11 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah) } if (i == 0) { - ath_print(common, ATH_DBG_FATAL, - "DMA failed to stop in %d ms " - "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", - AH_RX_STOP_DMA_TIMEOUT / 1000, - REG_READ(ah, AR_CR), - REG_READ(ah, AR_DIAG_SW)); + ath_err(common, + "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", + AH_RX_STOP_DMA_TIMEOUT / 1000, + REG_READ(ah, AR_CR), + REG_READ(ah, AR_DIAG_SW)); return false; } else { return true; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f026a031713b..c7a7abfb2221 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -268,16 +268,14 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset channel (%u MHz), " - "reset status %d\n", - channel->center_freq, r); + ath_err(common, + "Unable to reset channel (%u MHz), reset status %d\n", + channel->center_freq, r); goto ps_restore; } if (ath_startrecv(sc) != 0) { - ath_print(common, ATH_DBG_FATAL, - "Unable to restart recv logic\n"); + ath_err(common, "Unable to restart recv logic\n"); r = -EIO; goto ps_restore; } @@ -892,16 +890,14 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset channel (%u MHz), " - "reset status %d\n", - channel->center_freq, r); + ath_err(common, + "Unable to reset channel (%u MHz), reset status %d\n", + channel->center_freq, r); } ath_update_txpow(sc); if (ath_startrecv(sc) != 0) { - ath_print(common, ATH_DBG_FATAL, - "Unable to restart recv logic\n"); + ath_err(common, "Unable to restart recv logic\n"); spin_unlock_bh(&sc->sc_pcu_lock); return; } @@ -955,10 +951,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Unable to reset channel (%u MHz), " - "reset status %d\n", - channel->center_freq, r); + ath_err(ath9k_hw_common(sc->sc_ah), + "Unable to reset channel (%u MHz), reset status %d\n", + channel->center_freq, r); } ath9k_hw_phy_disable(ah); @@ -993,12 +988,11 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d\n", r); + ath_err(common, + "Unable to reset hardware; reset status %d\n", r); if (ath_startrecv(sc) != 0) - ath_print(common, ATH_DBG_FATAL, - "Unable to start recv logic\n"); + ath_err(common, "Unable to start recv logic\n"); /* * We may be doing a reset in response to a request @@ -1116,10 +1110,9 @@ static int ath9k_start(struct ieee80211_hw *hw) spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d " - "(freq %u MHz)\n", r, - curchan->center_freq); + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + r, curchan->center_freq); spin_unlock_bh(&sc->sc_pcu_lock); goto mutex_unlock; } @@ -1138,8 +1131,7 @@ static int ath9k_start(struct ieee80211_hw *hw) * here except setup the interrupt mask. */ if (ath_startrecv(sc) != 0) { - ath_print(common, ATH_DBG_FATAL, - "Unable to start recv logic\n"); + ath_err(common, "Unable to start recv logic\n"); r = -EIO; spin_unlock_bh(&sc->sc_pcu_lock); goto mutex_unlock; @@ -1378,8 +1370,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ic_opmode = vif->type; break; default: - ath_print(common, ATH_DBG_FATAL, - "Interface type %d not yet supported\n", vif->type); + ath_err(common, "Interface type %d not yet supported\n", + vif->type); ret = -EOPNOTSUPP; goto out; } @@ -1650,8 +1642,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { - ath_print(common, ATH_DBG_FATAL, - "Unable to set channel\n"); + ath_err(common, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } @@ -1775,7 +1766,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, ret = ath_txq_update(sc, txq->axq_qnum, &qi); if (ret) - ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); + ath_err(common, "TXQ Update failed\n"); if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) if (queue == WME_AC_BE && !ret) @@ -2024,8 +2015,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ath9k_ps_restore(sc); break; default: - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Unknown AMPDU action\n"); + ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); } local_bh_enable(); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 09f69a9617f4..71339dab0860 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -59,10 +59,9 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) if (pdata) { if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { - ath_print(common, ATH_DBG_FATAL, - "%s: eeprom read failed, offset %08x " - "is out of range\n", - __func__, off); + ath_err(common, + "%s: eeprom read failed, offset %08x is out of range\n", + __func__, off); } *data = pdata->eeprom_data[off]; diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 3e6ea3bc3d89..d8dcaab18299 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1576,8 +1576,8 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); if (!rate_priv) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Unable to allocate private rc structure\n"); + ath_err(ath9k_hw_common(sc->sc_ah), + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 262c81595f6d..c477be06894e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -269,7 +269,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(common, ATH_DBG_FATAL, + ath_err(common, "dma_mapping_error() on RX init\n"); error = -ENOMEM; goto rx_init_fail; @@ -335,9 +335,9 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, "rx", nbufs, 1, 0); if (error != 0) { - ath_print(common, ATH_DBG_FATAL, - "failed to allocate rx descriptors: %d\n", - error); + ath_err(common, + "failed to allocate rx descriptors: %d\n", + error); goto err; } @@ -358,8 +358,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(common, ATH_DBG_FATAL, - "dma_mapping_error() on RX init\n"); + ath_err(common, + "dma_mapping_error() on RX init\n"); error = -ENOMEM; goto err; } @@ -1725,8 +1725,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(common, ATH_DBG_FATAL, - "dma_mapping_error() on RX\n"); + ath_err(common, "dma_mapping_error() on RX\n"); ath_rx_send_to_mac80211(hw, sc, skb, rxs); break; } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 821d3679c6ff..d26449c91d5f 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -985,9 +985,8 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) return NULL; } if (qnum >= ARRAY_SIZE(sc->tx.txq)) { - ath_print(common, ATH_DBG_FATAL, - "qnum %u out of range, max %u!\n", - qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq)); + ath_err(common, "qnum %u out of range, max %zu!\n", + qnum, ARRAY_SIZE(sc->tx.txq)); ath9k_hw_releasetxqueue(ah, qnum); return NULL; } @@ -1038,8 +1037,8 @@ int ath_txq_update(struct ath_softc *sc, int qnum, qi.tqi_readyTime = qinfo->tqi_readyTime; if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Unable to update hardware queue %u!\n", qnum); + ath_err(ath9k_hw_common(sc->sc_ah), + "Unable to update hardware queue %u!\n", qnum); error = -EIO; } else { ath9k_hw_resettxqueue(ah, qnum); @@ -1197,14 +1196,13 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) if (npend) { int r; - ath_print(common, ATH_DBG_FATAL, - "Failed to stop TX DMA. Resetting hardware!\n"); + ath_err(common, "Failed to stop TX DMA. Resetting hardware!\n"); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); if (r) - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d\n", - r); + ath_err(common, + "Unable to reset hardware; reset status %d\n", + r); } for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { @@ -1663,8 +1661,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "dma_mapping_error() on TX\n"); + ath_err(ath9k_hw_common(sc->sc_ah), + "dma_mapping_error() on TX\n"); ath_tx_return_buffer(sc, bf); return NULL; } @@ -2260,16 +2258,16 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, "tx", nbufs, 1, 1); if (error != 0) { - ath_print(common, ATH_DBG_FATAL, - "Failed to allocate tx descriptors: %d\n", error); + ath_err(common, + "Failed to allocate tx descriptors: %d\n", error); goto err; } error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, "beacon", ATH_BCBUF, 1, 1); if (error != 0) { - ath_print(common, ATH_DBG_FATAL, - "Failed to allocate beacon descriptors: %d\n", error); + ath_err(common, + "Failed to allocate beacon descriptors: %d\n", error); goto err; } diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 62e3dac8f92a..3a4769506ce3 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -37,8 +37,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) void *ah = common->ah; if (entry >= common->keymax) { - ath_print(common, ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); + ath_err(common, "keycache entry %u out of range\n", entry); return false; } @@ -75,8 +74,7 @@ static bool ath_hw_keysetmac(struct ath_common *common, void *ah = common->ah; if (entry >= common->keymax) { - ath_print(common, ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); + ath_err(common, "keycache entry %u out of range\n", entry); return false; } @@ -117,8 +115,7 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, u32 keyType; if (entry >= common->keymax) { - ath_print(common, ATH_DBG_FATAL, - "keycache entry %u out of range\n", entry); + ath_err(common, "keycache entry %u out of range\n", entry); return false; } @@ -159,8 +156,7 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, keyType = AR_KEYTABLE_TYPE_CLR; break; default: - ath_print(common, ATH_DBG_FATAL, - "cipher %u not supported\n", k->kv_type); + ath_err(common, "cipher %u not supported\n", k->kv_type); return false; } @@ -341,8 +337,7 @@ static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) { /* TX MIC entry failed. No need to proceed further */ - ath_print(common, ATH_DBG_FATAL, - "Setting TX MIC Key Failed\n"); + ath_err(common, "Setting TX MIC Key Failed\n"); return 0; } -- cgit v1.2.3-59-g8ed1b From 226afe68fdbd1aa3680158aca0a3631cbd019626 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 2 Dec 2010 19:12:37 -0800 Subject: ath: Convert ath_print to ath_dbg Remove ath/debug.h and the includes of these files. Coalesce long formats. Correct a few misspellings and missing "\n"s from these logging messages. Remove unnecessary trailing space before a newline. Remove ARRAY_SIZE casts, use printf type %zu Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 1 - drivers/net/wireless/ath/ath5k/debug.c | 1 - drivers/net/wireless/ath/ath9k/ani.c | 97 +++++------ drivers/net/wireless/ath/ath9k/ar5008_phy.c | 187 +++++++++----------- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 220 ++++++++++++------------ drivers/net/wireless/ath/ath9k/ar9002_mac.c | 20 +-- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 217 ++++++++++++----------- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 173 +++++++++---------- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 16 +- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 205 +++++++++++----------- drivers/net/wireless/ath/ath9k/beacon.c | 65 ++++--- drivers/net/wireless/ath/ath9k/calib.c | 59 ++++--- drivers/net/wireless/ath/ath9k/common.c | 4 +- drivers/net/wireless/ath/ath9k/common.h | 1 - drivers/net/wireless/ath/ath9k/eeprom.c | 4 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 61 ++++--- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 26 +-- drivers/net/wireless/ath/ath9k/eeprom_def.c | 53 +++--- drivers/net/wireless/ath/ath9k/gpio.c | 16 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 20 +-- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 15 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 36 ++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 133 +++++++------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 +- drivers/net/wireless/ath/ath9k/hw.c | 83 +++++---- drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 22 +-- drivers/net/wireless/ath/ath9k/mac.c | 86 ++++----- drivers/net/wireless/ath/ath9k/main.c | 129 +++++++------- drivers/net/wireless/ath/ath9k/rc.c | 14 +- drivers/net/wireless/ath/ath9k/recv.c | 33 ++-- drivers/net/wireless/ath/ath9k/virtual.c | 7 +- drivers/net/wireless/ath/ath9k/wmi.c | 12 +- drivers/net/wireless/ath/ath9k/xmit.c | 54 +++--- drivers/net/wireless/ath/debug.h | 22 --- drivers/net/wireless/ath/key.c | 13 +- 36 files changed, 1009 insertions(+), 1105 deletions(-) delete mode 100644 drivers/net/wireless/ath/debug.h diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 380ff2f5f1d0..950fc379c3b8 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -60,7 +60,6 @@ #include "reg.h" #include "debug.h" #include "ani.h" -#include "../debug.h" static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 5341dd2860d3..d2f84d76bb07 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -60,7 +60,6 @@ #include "base.h" #include "debug.h" -#include "../debug.h" static unsigned int ath5k_debug; module_param_named(debug, ath5k_debug, uint, 0); diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 29a045da184b..e2ffac3d4d8e 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -135,8 +135,8 @@ static void ath9k_ani_restart(struct ath_hw *ah) cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; } - ath_print(common, ATH_DBG_ANI, - "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); + ath_dbg(common, ATH_DBG_ANI, + "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); ENABLE_REGWRITE_BUFFER(ah); @@ -267,11 +267,11 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) aniState->noiseFloor = BEACON_RSSI(ah); - ath_print(common, ATH_DBG_ANI, - "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", - aniState->ofdmNoiseImmunityLevel, - immunityLevel, aniState->noiseFloor, - aniState->rssiThrLow, aniState->rssiThrHigh); + ath_dbg(common, ATH_DBG_ANI, + "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", + aniState->ofdmNoiseImmunityLevel, + immunityLevel, aniState->noiseFloor, + aniState->rssiThrLow, aniState->rssiThrHigh); aniState->ofdmNoiseImmunityLevel = immunityLevel; @@ -334,11 +334,11 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) const struct ani_cck_level_entry *entry_cck; aniState->noiseFloor = BEACON_RSSI(ah); - ath_print(common, ATH_DBG_ANI, - "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", - aniState->cckNoiseImmunityLevel, immunityLevel, - aniState->noiseFloor, aniState->rssiThrLow, - aniState->rssiThrHigh); + ath_dbg(common, ATH_DBG_ANI, + "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", + aniState->cckNoiseImmunityLevel, immunityLevel, + aniState->noiseFloor, aniState->rssiThrLow, + aniState->rssiThrHigh); if ((ah->opmode == NL80211_IFTYPE_STATION || ah->opmode == NL80211_IFTYPE_ADHOC) && @@ -478,8 +478,8 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) if (ah->opmode != NL80211_IFTYPE_STATION && ah->opmode != NL80211_IFTYPE_ADHOC) { - ath_print(common, ATH_DBG_ANI, - "Reset ANI state opmode %u\n", ah->opmode); + ath_dbg(common, ATH_DBG_ANI, + "Reset ANI state opmode %u\n", ah->opmode); ah->stats.ast_ani_reset++; if (ah->opmode == NL80211_IFTYPE_AP) { @@ -584,16 +584,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) ATH9K_ANI_OFDM_DEF_LEVEL || aniState->cckNoiseImmunityLevel != ATH9K_ANI_CCK_DEF_LEVEL) { - ath_print(common, ATH_DBG_ANI, - "Restore defaults: opmode %u " - "chan %d Mhz/0x%x is_scanning=%d " - "ofdm:%d cck:%d\n", - ah->opmode, - chan->channel, - chan->channelFlags, - is_scanning, - aniState->ofdmNoiseImmunityLevel, - aniState->cckNoiseImmunityLevel); + ath_dbg(common, ATH_DBG_ANI, + "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", + ah->opmode, + chan->channel, + chan->channelFlags, + is_scanning, + aniState->ofdmNoiseImmunityLevel, + aniState->cckNoiseImmunityLevel); ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); @@ -602,16 +600,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) /* * restore historical levels for this channel */ - ath_print(common, ATH_DBG_ANI, - "Restore history: opmode %u " - "chan %d Mhz/0x%x is_scanning=%d " - "ofdm:%d cck:%d\n", - ah->opmode, - chan->channel, - chan->channelFlags, - is_scanning, - aniState->ofdmNoiseImmunityLevel, - aniState->cckNoiseImmunityLevel); + ath_dbg(common, ATH_DBG_ANI, + "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", + ah->opmode, + chan->channel, + chan->channelFlags, + is_scanning, + aniState->ofdmNoiseImmunityLevel, + aniState->cckNoiseImmunityLevel); ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel); @@ -666,19 +662,17 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { if (phyCnt1 < ofdm_base) { - ath_print(common, ATH_DBG_ANI, - "phyCnt1 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt1, ofdm_base); + ath_dbg(common, ATH_DBG_ANI, + "phyCnt1 0x%x, resetting counter value to 0x%x\n", + phyCnt1, ofdm_base); REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); } if (phyCnt2 < cck_base) { - ath_print(common, ATH_DBG_ANI, - "phyCnt2 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt2, cck_base); + ath_dbg(common, ATH_DBG_ANI, + "phyCnt2 0x%x, resetting counter value to 0x%x\n", + phyCnt2, cck_base); REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); @@ -719,13 +713,12 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) cckPhyErrRate = aniState->cckPhyErrCount * 1000 / aniState->listenTime; - ath_print(common, ATH_DBG_ANI, - "listenTime=%d OFDM:%d errs=%d/s CCK:%d " - "errs=%d/s ofdm_turn=%d\n", - aniState->listenTime, - aniState->ofdmNoiseImmunityLevel, - ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, - cckPhyErrRate, aniState->ofdmsTurn); + ath_dbg(common, ATH_DBG_ANI, + "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n", + aniState->listenTime, + aniState->ofdmNoiseImmunityLevel, + ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, + cckPhyErrRate, aniState->ofdmsTurn); if (aniState->listenTime > 5 * ah->aniperiod) { if (ofdmPhyErrRate <= ah->config.ofdm_trig_low && @@ -755,7 +748,7 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n"); + ath_dbg(common, ATH_DBG_ANI, "Enable MIB counters\n"); ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -777,7 +770,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n"); + ath_dbg(common, ATH_DBG_ANI, "Disable MIB counters\n"); REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -852,7 +845,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); int i; - ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); + ath_dbg(common, ATH_DBG_ANI, "Initialize ANI\n"); if (use_new_ani(ah)) { ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 9af9f23af3c4..059330aac645 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -130,9 +130,8 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) /* pre-reverse this field */ tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); - ath_print(common, ATH_DBG_CONFIG, - "Force rf_pwd_icsyndiv to %1d on %4d\n", - new_bias, synth_freq); + ath_dbg(common, ATH_DBG_CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n", + new_bias, synth_freq); /* swizzle rf_pwd_icsyndiv */ ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); @@ -1054,10 +1053,9 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { - ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", - level, - (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); + ath_dbg(common, ATH_DBG_ANI, + "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(ah->totalSizeDesired)); return false; } @@ -1159,10 +1157,9 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(firstep)) { - ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(firstep)); + ath_dbg(common, ATH_DBG_ANI, + "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(firstep)); return false; } REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, @@ -1180,10 +1177,9 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(cycpwrThr1)) { - ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(cycpwrThr1)); + ath_dbg(common, ATH_DBG_ANI, + "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(cycpwrThr1)); return false; } REG_RMW_FIELD(ah, AR_PHY_TIMING5, @@ -1199,25 +1195,22 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, case ATH9K_ANI_PRESENT: break; default: - ath_print(common, ATH_DBG_ANI, - "invalid cmd %u\n", cmd); + ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); return false; } - ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); - ath_print(common, ATH_DBG_ANI, - "noiseImmunityLevel=%d, spurImmunityLevel=%d, " - "ofdmWeakSigDetectOff=%d\n", - aniState->noiseImmunityLevel, - aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff); - ath_print(common, ATH_DBG_ANI, - "cckWeakSigThreshold=%d, " - "firstepLevel=%d, listenTime=%d\n", - aniState->cckWeakSigThreshold, - aniState->firstepLevel, - aniState->listenTime); - ath_print(common, ATH_DBG_ANI, + ath_dbg(common, ATH_DBG_ANI, "ANI parameters:\n"); + ath_dbg(common, ATH_DBG_ANI, + "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n", + aniState->noiseImmunityLevel, + aniState->spurImmunityLevel, + !aniState->ofdmWeakSigDetectOff); + ath_dbg(common, ATH_DBG_ANI, + "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", + aniState->cckWeakSigThreshold, + aniState->firstepLevel, + aniState->listenTime); + ath_dbg(common, ATH_DBG_ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1302,12 +1295,12 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); if (!on != aniState->ofdmWeakSigDetectOff) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: ofdm weak signal: %s=>%s\n", - chan->channel, - !aniState->ofdmWeakSigDetectOff ? - "on" : "off", - on ? "on" : "off"); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: ofdm weak signal: %s=>%s\n", + chan->channel, + !aniState->ofdmWeakSigDetectOff ? + "on" : "off", + on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else @@ -1320,11 +1313,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(firstep_table)) { - ath_print(common, ATH_DBG_ANI, - "ATH9K_ANI_FIRSTEP_LEVEL: level " - "out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(firstep_table)); + ath_dbg(common, ATH_DBG_ANI, + "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", + level, ARRAY_SIZE(firstep_table)); return false; } @@ -1359,24 +1350,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); if (level != aniState->firstepLevel) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "firstep[level]=%d ini=%d\n", - chan->channel, - aniState->firstepLevel, - level, - ATH9K_ANI_FIRSTEP_LVL_NEW, - value, - aniState->iniDef.firstep); - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "firstep_low[level]=%d ini=%d\n", - chan->channel, - aniState->firstepLevel, - level, - ATH9K_ANI_FIRSTEP_LVL_NEW, - value2, - aniState->iniDef.firstepLow); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value, + aniState->iniDef.firstep); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value2, + aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) ah->stats.ast_ani_stepup++; else if (level < aniState->firstepLevel) @@ -1389,11 +1378,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(cycpwrThr1_table)) { - ath_print(common, ATH_DBG_ANI, - "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " - "out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(cycpwrThr1_table)); + ath_dbg(common, ATH_DBG_ANI, + "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", + level, ARRAY_SIZE(cycpwrThr1_table)); return false; } /* @@ -1427,24 +1414,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); if (level != aniState->spurImmunityLevel) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "cycpwrThr1[level]=%d ini=%d\n", - chan->channel, - aniState->spurImmunityLevel, - level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, - value, - aniState->iniDef.cycpwrThr1); - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "cycpwrThr1Ext[level]=%d ini=%d\n", - chan->channel, - aniState->spurImmunityLevel, - level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, - value2, - aniState->iniDef.cycpwrThr1Ext); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value, + aniState->iniDef.cycpwrThr1); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value2, + aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) ah->stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) @@ -1463,22 +1448,19 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, case ATH9K_ANI_PRESENT: break; default: - ath_print(common, ATH_DBG_ANI, - "invalid cmd %u\n", cmd); + ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); return false; } - ath_print(common, ATH_DBG_ANI, - "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d " - "ofdmErrs=%d cckErrs=%d\n", - aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff ? "on" : "off", - aniState->firstepLevel, - !aniState->mrcCCKOff ? "on" : "off", - aniState->listenTime, - aniState->ofdmPhyErrCount, - aniState->cckPhyErrCount); + ath_dbg(common, ATH_DBG_ANI, + "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", + aniState->spurImmunityLevel, + !aniState->ofdmWeakSigDetectOff ? "on" : "off", + aniState->firstepLevel, + !aniState->mrcCCKOff ? "on" : "off", + aniState->listenTime, + aniState->ofdmPhyErrCount, + aniState->cckPhyErrCount); return true; } @@ -1524,13 +1506,12 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) iniDef = &aniState->iniDef; - ath_print(common, ATH_DBG_ANI, - "ver %d.%d opmode %u chan %d Mhz/0x%x\n", - ah->hw_version.macVersion, - ah->hw_version.macRev, - ah->opmode, - chan->channel, - chan->channelFlags); + ath_dbg(common, ATH_DBG_ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", + ah->hw_version.macVersion, + ah->hw_version.macRev, + ah->opmode, + chan->channel, + chan->channelFlags); val = REG_READ(ah, AR_PHY_SFCORR); iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 15f62cd0cc38..01880aa13e36 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -39,18 +39,18 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah, switch (currCal->calData->calType) { case IQ_MISMATCH_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); - ath_print(common, ATH_DBG_CALIBRATE, - "starting IQ Mismatch Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "starting IQ Mismatch Calibration\n"); break; case ADC_GAIN_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); - ath_print(common, ATH_DBG_CALIBRATE, - "starting ADC Gain Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "starting ADC Gain Calibration\n"); break; case ADC_DC_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); - ath_print(common, ATH_DBG_CALIBRATE, - "starting ADC DC Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "starting ADC DC Calibration\n"); break; } @@ -107,11 +107,11 @@ static void ar9002_hw_iqcal_collect(struct ath_hw *ah) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); ah->totalIqCorrMeas[i] += (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); - ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", - ah->cal_samples, i, ah->totalPowerMeasI[i], - ah->totalPowerMeasQ[i], - ah->totalIqCorrMeas[i]); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", + ah->cal_samples, i, ah->totalPowerMeasI[i], + ah->totalPowerMeasQ[i], + ah->totalIqCorrMeas[i]); } } @@ -129,14 +129,13 @@ static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah) ah->totalAdcQEvenPhase[i] += REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); - ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " - "oddq=0x%08x; evenq=0x%08x;\n", - ah->cal_samples, i, - ah->totalAdcIOddPhase[i], - ah->totalAdcIEvenPhase[i], - ah->totalAdcQOddPhase[i], - ah->totalAdcQEvenPhase[i]); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", + ah->cal_samples, i, + ah->totalAdcIOddPhase[i], + ah->totalAdcIEvenPhase[i], + ah->totalAdcQOddPhase[i], + ah->totalAdcQEvenPhase[i]); } } @@ -154,14 +153,13 @@ static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah) ah->totalAdcDcOffsetQEvenPhase[i] += (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); - ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " - "oddq=0x%08x; evenq=0x%08x;\n", - ah->cal_samples, i, - ah->totalAdcDcOffsetIOddPhase[i], - ah->totalAdcDcOffsetIEvenPhase[i], - ah->totalAdcDcOffsetQOddPhase[i], - ah->totalAdcDcOffsetQEvenPhase[i]); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", + ah->cal_samples, i, + ah->totalAdcDcOffsetIOddPhase[i], + ah->totalAdcDcOffsetIEvenPhase[i], + ah->totalAdcDcOffsetQOddPhase[i], + ah->totalAdcDcOffsetQEvenPhase[i]); } } @@ -178,13 +176,13 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) powerMeasQ = ah->totalPowerMeasQ[i]; iqCorrMeas = ah->totalIqCorrMeas[i]; - ath_print(common, ATH_DBG_CALIBRATE, - "Starting IQ Cal and Correction for Chain %d\n", - i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Starting IQ Cal and Correction for Chain %d\n", + i); - ath_print(common, ATH_DBG_CALIBRATE, - "Orignal: Chn %diq_corr_meas = 0x%08x\n", - i, ah->totalIqCorrMeas[i]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Orignal: Chn %diq_corr_meas = 0x%08x\n", + i, ah->totalIqCorrMeas[i]); iqCorrNeg = 0; @@ -193,12 +191,12 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) iqCorrNeg = 1; } - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); - ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", - iqCorrNeg); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); + ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", + iqCorrNeg); iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; qCoffDenom = powerMeasQ / 64; @@ -207,14 +205,14 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) (qCoffDenom != 0)) { iCoff = iqCorrMeas / iCoffDenom; qCoff = powerMeasI / qCoffDenom - 64; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d iCoff = 0x%08x\n", i, iCoff); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d qCoff = 0x%08x\n", i, qCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d iCoff = 0x%08x\n", i, iCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d qCoff = 0x%08x\n", i, qCoff); iCoff = iCoff & 0x3f; - ath_print(common, ATH_DBG_CALIBRATE, - "New: Chn %d iCoff = 0x%08x\n", i, iCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "New: Chn %d iCoff = 0x%08x\n", i, iCoff); if (iqCorrNeg == 0x0) iCoff = 0x40 - iCoff; @@ -223,9 +221,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) else if (qCoff <= -16) qCoff = -16; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", - i, iCoff, qCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", + i, iCoff, qCoff); REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, @@ -233,9 +231,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff); - ath_print(common, ATH_DBG_CALIBRATE, - "IQ Cal and Correction done for Chain %d\n", - i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ Cal and Correction done for Chain %d\n", + i); } } @@ -255,21 +253,21 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) qOddMeasOffset = ah->totalAdcQOddPhase[i]; qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; - ath_print(common, ATH_DBG_CALIBRATE, - "Starting ADC Gain Cal for Chain %d\n", i); - - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_odd_i = 0x%08x\n", i, - iOddMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_even_i = 0x%08x\n", i, - iEvenMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_odd_q = 0x%08x\n", i, - qOddMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_even_q = 0x%08x\n", i, - qEvenMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Starting ADC Gain Cal for Chain %d\n", i); + + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_odd_i = 0x%08x\n", i, + iOddMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_even_i = 0x%08x\n", i, + iEvenMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_odd_q = 0x%08x\n", i, + qOddMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_even_q = 0x%08x\n", i, + qEvenMeasOffset); if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { iGainMismatch = @@ -279,20 +277,20 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) ((qOddMeasOffset * 32) / qEvenMeasOffset) & 0x3f; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d gain_mismatch_i = 0x%08x\n", i, - iGainMismatch); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d gain_mismatch_q = 0x%08x\n", i, - qGainMismatch); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d gain_mismatch_i = 0x%08x\n", i, + iGainMismatch); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d gain_mismatch_q = 0x%08x\n", i, + qGainMismatch); val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xfffff000; val |= (qGainMismatch) | (iGainMismatch << 6); REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); - ath_print(common, ATH_DBG_CALIBRATE, - "ADC Gain Cal done for Chain %d\n", i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "ADC Gain Cal done for Chain %d\n", i); } } @@ -317,41 +315,41 @@ static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; - ath_print(common, ATH_DBG_CALIBRATE, - "Starting ADC DC Offset Cal for Chain %d\n", i); - - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_odd_i = %d\n", i, - iOddMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_even_i = %d\n", i, - iEvenMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_odd_q = %d\n", i, - qOddMeasOffset); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_even_q = %d\n", i, - qEvenMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Starting ADC DC Offset Cal for Chain %d\n", i); + + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_odd_i = %d\n", i, + iOddMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_even_i = %d\n", i, + iEvenMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_odd_q = %d\n", i, + qOddMeasOffset); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_even_q = %d\n", i, + qEvenMeasOffset); iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / numSamples) & 0x1ff; qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / numSamples) & 0x1ff; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, - iDcMismatch); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, - qDcMismatch); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, + iDcMismatch); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, + qDcMismatch); val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xc0000fff; val |= (qDcMismatch << 12) | (iDcMismatch << 21); REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); - ath_print(common, ATH_DBG_CALIBRATE, - "ADC DC Offset Cal done for Chain %d\n", i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "ADC DC Offset Cal done for Chain %d\n", i); } REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), @@ -540,7 +538,7 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) { 0x7838, 0 }, }; - ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); /* PA CAL is not needed for high power solution */ if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == @@ -721,9 +719,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan) REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { - ath_print(common, ATH_DBG_CALIBRATE, "offset " - "calibration failed to complete in " - "1ms; noisy ??\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "offset calibration failed to complete in 1ms; noisy environment?\n"); return false; } REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); @@ -736,8 +733,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan) REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { - ath_print(common, ATH_DBG_CALIBRATE, "offset calibration " - "failed to complete in 1ms; noisy ??\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "offset calibration failed to complete in 1ms; noisy environment?\n"); return false; } @@ -829,9 +826,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { - ath_print(common, ATH_DBG_CALIBRATE, - "offset calibration failed to " - "complete in 1ms; noisy environment?\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "offset calibration failed to complete in 1ms; noisy environment?\n"); return false; } @@ -866,19 +862,19 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) INIT_CAL(&ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling ADC Gain Calibration.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling ADC Gain Calibration.\n"); INIT_CAL(&ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling ADC DC Calibration.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling ADC DC Calibration.\n"); } INIT_CAL(&ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling IQ Calibration.\n"); ah->cal_list_curr = ah->cal_list; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index f0268e5eab34..f3f9c589158e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -111,8 +111,8 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) } if (isr & AR_ISR_RXORN) { - ath_print(common, ATH_DBG_INTERRUPT, - "receive FIFO overrun interrupt\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, + "receive FIFO overrun interrupt\n"); } *masked |= mask2; @@ -147,25 +147,25 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) if (fatal_int) { if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { - ath_print(common, ATH_DBG_ANY, - "received PCI FATAL interrupt\n"); + ath_dbg(common, ATH_DBG_ANY, + "received PCI FATAL interrupt\n"); } if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { - ath_print(common, ATH_DBG_ANY, - "received PCI PERR interrupt\n"); + ath_dbg(common, ATH_DBG_ANY, + "received PCI PERR interrupt\n"); } *masked |= ATH9K_INT_FATAL; } if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { - ath_print(common, ATH_DBG_INTERRUPT, - "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, + "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); REG_WRITE(ah, AR_RC, 0); *masked |= ATH9K_INT_FATAL; } if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { - ath_print(common, ATH_DBG_INTERRUPT, - "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, + "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); } REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4c94c9ed5f81..16d20294c33c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -40,8 +40,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, currCal->calData->calCountMax); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); - ath_print(common, ATH_DBG_CALIBRATE, - "starting IQ Mismatch Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "starting IQ Mismatch Calibration\n"); /* Kick-off cal */ REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); @@ -52,8 +52,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1); - ath_print(common, ATH_DBG_CALIBRATE, - "starting Temperature Compensation Calibration\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "starting Temperature Compensation Calibration\n"); break; } } @@ -181,11 +181,11 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); ah->totalIqCorrMeas[i] += (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); - ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", - ah->cal_samples, i, ah->totalPowerMeasI[i], - ah->totalPowerMeasQ[i], - ah->totalIqCorrMeas[i]); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", + ah->cal_samples, i, ah->totalPowerMeasI[i], + ah->totalPowerMeasQ[i], + ah->totalIqCorrMeas[i]); } } @@ -207,13 +207,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) powerMeasQ = ah->totalPowerMeasQ[i]; iqCorrMeas = ah->totalIqCorrMeas[i]; - ath_print(common, ATH_DBG_CALIBRATE, - "Starting IQ Cal and Correction for Chain %d\n", - i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Starting IQ Cal and Correction for Chain %d\n", + i); - ath_print(common, ATH_DBG_CALIBRATE, - "Orignal: Chn %diq_corr_meas = 0x%08x\n", - i, ah->totalIqCorrMeas[i]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Orignal: Chn %diq_corr_meas = 0x%08x\n", + i, ah->totalIqCorrMeas[i]); iqCorrNeg = 0; @@ -222,12 +222,12 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) iqCorrNeg = 1; } - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); - ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", - iqCorrNeg); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); + ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", + iqCorrNeg); iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256; qCoffDenom = powerMeasQ / 64; @@ -235,10 +235,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) if ((iCoffDenom != 0) && (qCoffDenom != 0)) { iCoff = iqCorrMeas / iCoffDenom; qCoff = powerMeasI / qCoffDenom - 64; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d iCoff = 0x%08x\n", i, iCoff); - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d qCoff = 0x%08x\n", i, qCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d iCoff = 0x%08x\n", i, iCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d qCoff = 0x%08x\n", i, qCoff); /* Force bounds on iCoff */ if (iCoff >= 63) @@ -259,14 +259,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) iCoff = iCoff & 0x7f; qCoff = qCoff & 0x7f; - ath_print(common, ATH_DBG_CALIBRATE, - "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", - i, iCoff, qCoff); - ath_print(common, ATH_DBG_CALIBRATE, - "Register offset (0x%04x) " - "before update = 0x%x\n", - offset_array[i], - REG_READ(ah, offset_array[i])); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", + i, iCoff, qCoff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Register offset (0x%04x) before update = 0x%x\n", + offset_array[i], + REG_READ(ah, offset_array[i])); REG_RMW_FIELD(ah, offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, @@ -274,33 +273,29 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) REG_RMW_FIELD(ah, offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, qCoff); - ath_print(common, ATH_DBG_CALIBRATE, - "Register offset (0x%04x) QI COFF " - "(bitfields 0x%08x) after update = 0x%x\n", - offset_array[i], - AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, - REG_READ(ah, offset_array[i])); - ath_print(common, ATH_DBG_CALIBRATE, - "Register offset (0x%04x) QQ COFF " - "(bitfields 0x%08x) after update = 0x%x\n", - offset_array[i], - AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, - REG_READ(ah, offset_array[i])); - - ath_print(common, ATH_DBG_CALIBRATE, - "IQ Cal and Correction done for Chain %d\n", - i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n", + offset_array[i], + AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, + REG_READ(ah, offset_array[i])); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n", + offset_array[i], + AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, + REG_READ(ah, offset_array[i])); + + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ Cal and Correction done for Chain %d\n", i); } } REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); - ath_print(common, ATH_DBG_CALIBRATE, - "IQ Cal and Correction (offset 0x%04x) enabled " - "(bit position 0x%08x). New Value 0x%08x\n", - (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), - AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, - REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n", + (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), + AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, + REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); } static const struct ath9k_percal_data iq_cal_single_sample = { @@ -340,7 +335,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah, f2 = (f1 * f1 + f3 * f3) / result_shift; if (!f2) { - ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, "Divide by 0\n"); return false; } @@ -461,11 +456,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) || (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) { - ath_print(common, ATH_DBG_CALIBRATE, - "Divide by 0:\na0_d0=%d\n" - "a0_d1=%d\na2_d0=%d\na1_d1=%d\n", - i2_p_q2_a0_d0, i2_p_q2_a0_d1, - i2_p_q2_a1_d0, i2_p_q2_a1_d1); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Divide by 0:\n" + "a0_d0=%d\n" + "a0_d1=%d\n" + "a2_d0=%d\n" + "a1_d1=%d\n", + i2_p_q2_a0_d0, i2_p_q2_a0_d1, + i2_p_q2_a1_d0, i2_p_q2_a1_d1); return false; } @@ -498,9 +496,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); if ((mag1 == 0) || (mag2 == 0)) { - ath_print(common, ATH_DBG_CALIBRATE, - "Divide by 0: mag1=%d, mag2=%d\n", - mag1, mag2); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Divide by 0: mag1=%d, mag2=%d\n", + mag1, mag2); return false; } @@ -517,8 +515,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, mag_a0_d0, phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq)) { - ath_print(common, ATH_DBG_CALIBRATE, - "Call to ar9003_hw_solve_iq_cal() failed.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Call to ar9003_hw_solve_iq_cal() failed.\n"); return false; } @@ -527,14 +525,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, mag_rx = solved_eq[2]; phs_rx = solved_eq[3]; - ath_print(common, ATH_DBG_CALIBRATE, - "chain %d: mag mismatch=%d phase mismatch=%d\n", - chain_idx, mag_tx/res_scale, phs_tx/res_scale); + ath_dbg(common, ATH_DBG_CALIBRATE, + "chain %d: mag mismatch=%d phase mismatch=%d\n", + chain_idx, mag_tx/res_scale, phs_tx/res_scale); if (res_scale == mag_tx) { - ath_print(common, ATH_DBG_CALIBRATE, - "Divide by 0: mag_tx=%d, res_scale=%d\n", - mag_tx, res_scale); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Divide by 0: mag_tx=%d, res_scale=%d\n", + mag_tx, res_scale); return false; } @@ -545,9 +543,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, q_q_coff = (mag_corr_tx * 128 / res_scale); q_i_coff = (phs_corr_tx * 256 / res_scale); - ath_print(common, ATH_DBG_CALIBRATE, - "tx chain %d: mag corr=%d phase corr=%d\n", - chain_idx, q_q_coff, q_i_coff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "tx chain %d: mag corr=%d phase corr=%d\n", + chain_idx, q_q_coff, q_i_coff); if (q_i_coff < -63) q_i_coff = -63; @@ -560,14 +558,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; - ath_print(common, ATH_DBG_CALIBRATE, - "tx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[0]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "tx chain %d: iq corr coeff=%x\n", + chain_idx, iqc_coeff[0]); if (-mag_rx == res_scale) { - ath_print(common, ATH_DBG_CALIBRATE, - "Divide by 0: mag_rx=%d, res_scale=%d\n", - mag_rx, res_scale); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Divide by 0: mag_rx=%d, res_scale=%d\n", + mag_rx, res_scale); return false; } @@ -578,9 +576,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, q_q_coff = (mag_corr_rx * 128 / res_scale); q_i_coff = (phs_corr_rx * 256 / res_scale); - ath_print(common, ATH_DBG_CALIBRATE, - "rx chain %d: mag corr=%d phase corr=%d\n", - chain_idx, q_q_coff, q_i_coff); + ath_dbg(common, ATH_DBG_CALIBRATE, + "rx chain %d: mag corr=%d phase corr=%d\n", + chain_idx, q_q_coff, q_i_coff); if (q_i_coff < -63) q_i_coff = -63; @@ -593,9 +591,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; - ath_print(common, ATH_DBG_CALIBRATE, - "rx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[1]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "rx chain %d: iq corr coeff=%x\n", + chain_idx, iqc_coeff[1]); return true; } @@ -643,19 +641,19 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, AR_PHY_TX_IQCAL_START_DO_CAL, 0, AH_WAIT_TIMEOUT)) { - ath_print(common, ATH_DBG_CALIBRATE, - "Tx IQ Cal not complete.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Tx IQ Cal not complete.\n"); goto TX_IQ_CAL_FAILED; } for (i = 0; i < num_chains; i++) { - ath_print(common, ATH_DBG_CALIBRATE, - "Doing Tx IQ Cal for chain %d.\n", i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Doing Tx IQ Cal for chain %d.\n", i); if (REG_READ(ah, txiqcal_status[i]) & AR_PHY_TX_IQCAL_STATUS_FAILED) { - ath_print(common, ATH_DBG_CALIBRATE, - "Tx IQ Cal failed for chain %d.\n", i); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Tx IQ Cal failed for chain %d.\n", i); goto TX_IQ_CAL_FAILED; } @@ -677,20 +675,20 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) chan_info_tab[i] + offset); - ath_print(common, ATH_DBG_CALIBRATE, - "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", - idx, iq_res[idx], idx+1, iq_res[idx+1]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", + idx, iq_res[idx], idx+1, iq_res[idx+1]); } if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) { - ath_print(common, ATH_DBG_CALIBRATE, - "Failed in calculation of IQ correction.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Failed in calculation of IQ correction.\n"); goto TX_IQ_CAL_FAILED; } - ath_print(common, ATH_DBG_CALIBRATE, - "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n", - iqc_coeff[0], iqc_coeff[1]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n", + iqc_coeff[0], iqc_coeff[1]); REG_RMW_FIELD(ah, tx_corr_coeff[i], AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, @@ -711,7 +709,7 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) return; TX_IQ_CAL_FAILED: - ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); } static bool ar9003_hw_init_cal(struct ath_hw *ah, @@ -721,7 +719,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, int val; val = REG_READ(ah, AR_ENT_OTP); - ath_print(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); + ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); if (val & AR_ENT_OTP_CHAIN2_DISABLE) ar9003_hw_set_chain_masks(ah, 0x3, 0x3); @@ -746,9 +744,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, /* Poll for offset calibration complete */ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { - ath_print(common, ATH_DBG_CALIBRATE, - "offset calibration failed to " - "complete in 1ms; noisy environment?\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "offset calibration failed to complete in 1ms; noisy environment?\n"); return false; } @@ -764,15 +761,15 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, if (ah->supp_cals & IQ_MISMATCH_CAL) { INIT_CAL(&ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling IQ Calibration.\n"); } if (ah->supp_cals & TEMP_COMP_CAL) { INIT_CAL(&ah->tempCompCalData); INSERT_CAL(ah, &ah->tempCompCalData); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling Temperature Compensation Calibration.\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling Temperature Compensation Calibration.\n"); } /* Initialize current pointer to first element in list */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 872b1a3b21c6..59236ffd5171 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3072,8 +3072,8 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, int i; if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) { - ath_print(common, ATH_DBG_EEPROM, - "eeprom address not in range\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "eeprom address not in range\n"); return false; } @@ -3104,8 +3104,8 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, return true; error: - ath_print(common, ATH_DBG_EEPROM, - "unable to read eeprom region at offset %d\n", address); + ath_dbg(common, ATH_DBG_EEPROM, + "unable to read eeprom region at offset %d\n", address); return false; } @@ -3189,17 +3189,15 @@ static bool ar9300_uncompress_block(struct ath_hw *ah, length &= 0xff; if (length > 0 && spot >= 0 && spot+length <= mdataSize) { - ath_print(common, ATH_DBG_EEPROM, - "Restore at %d: spot=%d " - "offset=%d length=%d\n", - it, spot, offset, length); + ath_dbg(common, ATH_DBG_EEPROM, + "Restore at %d: spot=%d offset=%d length=%d\n", + it, spot, offset, length); memcpy(&mptr[spot], &block[it+2], length); spot += length; } else if (length > 0) { - ath_print(common, ATH_DBG_EEPROM, - "Bad restore at %d: spot=%d " - "offset=%d length=%d\n", - it, spot, offset, length); + ath_dbg(common, ATH_DBG_EEPROM, + "Bad restore at %d: spot=%d offset=%d length=%d\n", + it, spot, offset, length); return false; } } @@ -3220,14 +3218,15 @@ static int ar9300_compress_decision(struct ath_hw *ah, switch (code) { case _CompressNone: if (length != mdata_size) { - ath_print(common, ATH_DBG_EEPROM, - "EEPROM structure size mismatch" - "memory=%d eeprom=%d\n", mdata_size, length); + ath_dbg(common, ATH_DBG_EEPROM, + "EEPROM structure size mismatch memory=%d eeprom=%d\n", + mdata_size, length); return -1; } memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); - ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:" - " uncompressed, length %d\n", it, length); + ath_dbg(common, ATH_DBG_EEPROM, + "restored eeprom %d: uncompressed, length %d\n", + it, length); break; case _CompressBlock: if (reference == 0) { @@ -3235,22 +3234,22 @@ static int ar9300_compress_decision(struct ath_hw *ah, } else { eep = ar9003_eeprom_struct_find_by_id(reference); if (eep == NULL) { - ath_print(common, ATH_DBG_EEPROM, - "cant find reference eeprom" - "struct %d\n", reference); + ath_dbg(common, ATH_DBG_EEPROM, + "cant find reference eeprom struct %d\n", + reference); return -1; } memcpy(mptr, eep, mdata_size); } - ath_print(common, ATH_DBG_EEPROM, - "restore eeprom %d: block, reference %d," - " length %d\n", it, reference, length); + ath_dbg(common, ATH_DBG_EEPROM, + "restore eeprom %d: block, reference %d, length %d\n", + it, reference, length); ar9300_uncompress_block(ah, mptr, mdata_size, (u8 *) (word + COMP_HDR_LEN), length); break; default: - ath_print(common, ATH_DBG_EEPROM, "unknown compression" - " code %d\n", code); + ath_dbg(common, ATH_DBG_EEPROM, + "unknown compression code %d\n", code); return -1; } return 0; @@ -3321,26 +3320,26 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, read = ar9300_read_eeprom; cptr = AR9300_BASE_ADDR; - ath_print(common, ATH_DBG_EEPROM, + ath_dbg(common, ATH_DBG_EEPROM, "Trying EEPROM accesss at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; cptr = AR9300_BASE_ADDR_512; - ath_print(common, ATH_DBG_EEPROM, + ath_dbg(common, ATH_DBG_EEPROM, "Trying EEPROM accesss at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; read = ar9300_read_otp; cptr = AR9300_BASE_ADDR; - ath_print(common, ATH_DBG_EEPROM, + ath_dbg(common, ATH_DBG_EEPROM, "Trying OTP accesss at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; cptr = AR9300_BASE_ADDR_512; - ath_print(common, ATH_DBG_EEPROM, + ath_dbg(common, ATH_DBG_EEPROM, "Trying OTP accesss at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; @@ -3348,7 +3347,7 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, goto fail; found: - ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data"); + ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n"); for (it = 0; it < MSTATE; it++) { if (!read(ah, cptr, word, COMP_HDR_LEN)) @@ -3359,13 +3358,12 @@ found: ar9300_comp_hdr_unpack(word, &code, &reference, &length, &major, &minor); - ath_print(common, ATH_DBG_EEPROM, - "Found block at %x: code=%d ref=%d" - "length=%d major=%d minor=%d\n", cptr, code, - reference, length, major, minor); + ath_dbg(common, ATH_DBG_EEPROM, + "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", + cptr, code, reference, length, major, minor); if (length >= 1024) { - ath_print(common, ATH_DBG_EEPROM, - "Skipping bad header\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Skipping bad header\n"); cptr -= COMP_HDR_LEN; continue; } @@ -3375,14 +3373,14 @@ found: checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); mchecksum = word[COMP_HDR_LEN + osize] | (word[COMP_HDR_LEN + osize + 1] << 8); - ath_print(common, ATH_DBG_EEPROM, - "checksum %x %x\n", checksum, mchecksum); + ath_dbg(common, ATH_DBG_EEPROM, + "checksum %x %x\n", checksum, mchecksum); if (checksum == mchecksum) { ar9300_compress_decision(ah, it, code, reference, mptr, word, length, mdata_size); } else { - ath_print(common, ATH_DBG_EEPROM, - "skipping block with bad checksum\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "skipping block with bad checksum\n"); } cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); } @@ -4092,20 +4090,20 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, is2GHz) + ht40PowerIncForPdadc; while (i < ar9300RateSize) { - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); i++; } } @@ -4125,18 +4123,17 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, struct ath_common *common = ath9k_hw_common(ah); if (ichain >= AR9300_MAX_CHAINS) { - ath_print(common, ATH_DBG_EEPROM, - "Invalid chain index, must be less than %d\n", - AR9300_MAX_CHAINS); + ath_dbg(common, ATH_DBG_EEPROM, + "Invalid chain index, must be less than %d\n", + AR9300_MAX_CHAINS); return -1; } if (mode) { /* 5GHz */ if (ipier >= AR9300_NUM_5G_CAL_PIERS) { - ath_print(common, ATH_DBG_EEPROM, - "Invalid 5GHz cal pier index, must " - "be less than %d\n", - AR9300_NUM_5G_CAL_PIERS); + ath_dbg(common, ATH_DBG_EEPROM, + "Invalid 5GHz cal pier index, must be less than %d\n", + AR9300_NUM_5G_CAL_PIERS); return -1; } pCalPier = &(eep->calFreqPier5G[ipier]); @@ -4144,9 +4141,9 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, is2GHz = 0; } else { if (ipier >= AR9300_NUM_2G_CAL_PIERS) { - ath_print(common, ATH_DBG_EEPROM, - "Invalid 2GHz cal pier index, must " - "be less than %d\n", AR9300_NUM_2G_CAL_PIERS); + ath_dbg(common, ATH_DBG_EEPROM, + "Invalid 2GHz cal pier index, must be less than %d\n", + AR9300_NUM_2G_CAL_PIERS); return -1; } @@ -4296,11 +4293,11 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) /* interpolate */ for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { - ath_print(common, ATH_DBG_EEPROM, - "ch=%d f=%d low=%d %d h=%d %d\n", - ichain, frequency, lfrequency[ichain], - lcorrection[ichain], hfrequency[ichain], - hcorrection[ichain]); + ath_dbg(common, ATH_DBG_EEPROM, + "ch=%d f=%d low=%d %d h=%d %d\n", + ichain, frequency, lfrequency[ichain], + lcorrection[ichain], hfrequency[ichain], + hcorrection[ichain]); /* they're the same, so just pick one */ if (hfrequency[ichain] == lfrequency[ichain]) { correction[ichain] = lcorrection[ichain]; @@ -4352,9 +4349,9 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ar9003_hw_power_control_override(ah, frequency, correction, voltage, temperature); - ath_print(common, ATH_DBG_EEPROM, - "for frequency=%d, calibration correction = %d %d %d\n", - frequency, correction[0], correction[1], correction[2]); + ath_dbg(common, ATH_DBG_EEPROM, + "for frequency=%d, calibration correction = %d %d %d\n", + frequency, correction[0], correction[1], correction[2]); return 0; } @@ -4559,11 +4556,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, else freq = centers.ctl_center; - ath_print(common, ATH_DBG_REGULATORY, - "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " - "EXT_ADDITIVE %d\n", - ctlMode, numCtlModes, isHt40CtlMode, - (pCtlMode[ctlMode] & EXT_ADDITIVE)); + ath_dbg(common, ATH_DBG_REGULATORY, + "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n", + ctlMode, numCtlModes, isHt40CtlMode, + (pCtlMode[ctlMode] & EXT_ADDITIVE)); /* walk through each CTL index stored in EEPROM */ if (is2ghz) { @@ -4575,12 +4571,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, } for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { - ath_print(common, ATH_DBG_REGULATORY, - "LOOP-Ctlidx %d: cfgCtl 0x%2.2x " - "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " - "chan %dn", - i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], - chan->channel); + ath_dbg(common, ATH_DBG_REGULATORY, + "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n", + i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], + chan->channel); /* * compare test group from regulatory @@ -4619,11 +4613,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); - ath_print(common, ATH_DBG_REGULATORY, - "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d " - "sP %d minCtlPwr %d\n", - ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, - scaledPower, minCtlPower); + ath_dbg(common, ATH_DBG_REGULATORY, + "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n", + ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, + scaledPower, minCtlPower); /* Apply ctl mode to correct target power set */ switch (pCtlMode[ctlMode]) { @@ -4698,17 +4691,17 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, return; for (i = 0; i < ar9300RateSize; i++) { - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); i++; - ath_print(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); + ath_dbg(common, ATH_DBG_EEPROM, + "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); i++; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index f5896aa30005..bfba6a2b741d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -182,8 +182,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) } if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) - ath_print(common, ATH_DBG_INTERRUPT, - "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, + "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); @@ -249,8 +249,8 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || (MS(ads->ds_info, AR_TxRxDesc) != 1)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, - "Tx Descriptor error %x\n", ads->ds_info); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, + "Tx Descriptor error %x\n", ads->ds_info); memset(ads, 0, sizeof(*ads)); return -EIO; } @@ -658,10 +658,10 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah) memset((void *) ah->ts_ring, 0, ah->ts_size * sizeof(struct ar9003_txs)); - ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, - "TS Start 0x%x End 0x%x Virt %p, Size %d\n", - ah->ts_paddr_start, ah->ts_paddr_end, - ah->ts_ring, ah->ts_size); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, + "TS Start 0x%x End 0x%x Virt %p, Size %d\n", + ah->ts_paddr_start, ah->ts_paddr_end, + ah->ts_ring, ah->ts_size); REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start); REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index b34a9e91edd8..63b6d560c7f0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -824,12 +824,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); if (!on != aniState->ofdmWeakSigDetectOff) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: ofdm weak signal: %s=>%s\n", - chan->channel, - !aniState->ofdmWeakSigDetectOff ? - "on" : "off", - on ? "on" : "off"); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: ofdm weak signal: %s=>%s\n", + chan->channel, + !aniState->ofdmWeakSigDetectOff ? + "on" : "off", + on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else @@ -842,11 +842,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(firstep_table)) { - ath_print(common, ATH_DBG_ANI, - "ATH9K_ANI_FIRSTEP_LEVEL: level " - "out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(firstep_table)); + ath_dbg(common, ATH_DBG_ANI, + "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", + level, ARRAY_SIZE(firstep_table)); return false; } @@ -881,24 +879,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2); if (level != aniState->firstepLevel) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "firstep[level]=%d ini=%d\n", - chan->channel, - aniState->firstepLevel, - level, - ATH9K_ANI_FIRSTEP_LVL_NEW, - value, - aniState->iniDef.firstep); - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "firstep_low[level]=%d ini=%d\n", - chan->channel, - aniState->firstepLevel, - level, - ATH9K_ANI_FIRSTEP_LVL_NEW, - value2, - aniState->iniDef.firstepLow); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value, + aniState->iniDef.firstep); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value2, + aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) ah->stats.ast_ani_stepup++; else if (level < aniState->firstepLevel) @@ -911,11 +907,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, u32 level = param; if (level >= ARRAY_SIZE(cycpwrThr1_table)) { - ath_print(common, ATH_DBG_ANI, - "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " - "out of range (%u > %u)\n", - level, - (unsigned) ARRAY_SIZE(cycpwrThr1_table)); + ath_dbg(common, ATH_DBG_ANI, + "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", + level, ARRAY_SIZE(cycpwrThr1_table)); return false; } /* @@ -949,24 +943,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_EXT_CYCPWR_THR1, value2); if (level != aniState->spurImmunityLevel) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "cycpwrThr1[level]=%d ini=%d\n", - chan->channel, - aniState->spurImmunityLevel, - level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, - value, - aniState->iniDef.cycpwrThr1); - ath_print(common, ATH_DBG_ANI, - "** ch %d: level %d=>%d[def:%d] " - "cycpwrThr1Ext[level]=%d ini=%d\n", - chan->channel, - aniState->spurImmunityLevel, - level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, - value2, - aniState->iniDef.cycpwrThr1Ext); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value, + aniState->iniDef.cycpwrThr1); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value2, + aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) ah->stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) @@ -986,11 +978,11 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, AR_PHY_MRC_CCK_MUX_REG, is_on); if (!is_on != aniState->mrcCCKOff) { - ath_print(common, ATH_DBG_ANI, - "** ch %d: MRC CCK: %s=>%s\n", - chan->channel, - !aniState->mrcCCKOff ? "on" : "off", - is_on ? "on" : "off"); + ath_dbg(common, ATH_DBG_ANI, + "** ch %d: MRC CCK: %s=>%s\n", + chan->channel, + !aniState->mrcCCKOff ? "on" : "off", + is_on ? "on" : "off"); if (is_on) ah->stats.ast_ani_ccklow++; else @@ -1002,22 +994,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, case ATH9K_ANI_PRESENT: break; default: - ath_print(common, ATH_DBG_ANI, - "invalid cmd %u\n", cmd); + ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); return false; } - ath_print(common, ATH_DBG_ANI, - "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d " - "ofdmErrs=%d cckErrs=%d\n", - aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff ? "on" : "off", - aniState->firstepLevel, - !aniState->mrcCCKOff ? "on" : "off", - aniState->listenTime, - aniState->ofdmPhyErrCount, - aniState->cckPhyErrCount); + ath_dbg(common, ATH_DBG_ANI, + "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", + aniState->spurImmunityLevel, + !aniState->ofdmWeakSigDetectOff ? "on" : "off", + aniState->firstepLevel, + !aniState->mrcCCKOff ? "on" : "off", + aniState->listenTime, + aniState->ofdmPhyErrCount, + aniState->cckPhyErrCount); return true; } @@ -1074,13 +1063,13 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState = &ah->curchan->ani; iniDef = &aniState->iniDef; - ath_print(common, ATH_DBG_ANI, - "ver %d.%d opmode %u chan %d Mhz/0x%x\n", - ah->hw_version.macVersion, - ah->hw_version.macRev, - ah->opmode, - chan->channel, - chan->channelFlags); + ath_dbg(common, ATH_DBG_ANI, + "ver %d.%d opmode %u chan %d Mhz/0x%x\n", + ah->hw_version.macVersion, + ah->hw_version.macRev, + ah->opmode, + chan->channel, + chan->channelFlags); val = REG_READ(ah, AR_PHY_SFCORR); iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); @@ -1216,7 +1205,7 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE | AR_PHY_WATCHDOG_IDLE_ENABLE)); - ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n"); + ath_dbg(common, ATH_DBG_RESET, "Disabled BB Watchdog\n"); return; } @@ -1252,9 +1241,9 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) AR_PHY_WATCHDOG_IDLE_MASK | (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2))); - ath_print(common, ATH_DBG_RESET, - "Enabled BB Watchdog timeout (%u ms)\n", - idle_tmo_ms); + ath_dbg(common, ATH_DBG_RESET, + "Enabled BB Watchdog timeout (%u ms)\n", + idle_tmo_ms); } void ar9003_hw_bb_watchdog_read(struct ath_hw *ah) @@ -1282,37 +1271,35 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) return; status = ah->bb_watchdog_last_status; - ath_print(common, ATH_DBG_RESET, - "\n==== BB update: BB status=0x%08x ====\n", status); - ath_print(common, ATH_DBG_RESET, - "** BB state: wd=%u det=%u rdar=%u rOFDM=%d " - "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", - MS(status, AR_PHY_WATCHDOG_INFO), - MS(status, AR_PHY_WATCHDOG_DET_HANG), - MS(status, AR_PHY_WATCHDOG_RADAR_SM), - MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM), - MS(status, AR_PHY_WATCHDOG_RX_CCK_SM), - MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM), - MS(status, AR_PHY_WATCHDOG_TX_CCK_SM), - MS(status, AR_PHY_WATCHDOG_AGC_SM), - MS(status,AR_PHY_WATCHDOG_SRCH_SM)); - - ath_print(common, ATH_DBG_RESET, - "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", - REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), - REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); - ath_print(common, ATH_DBG_RESET, - "** BB mode: BB_gen_controls=0x%08x **\n", - REG_READ(ah, AR_PHY_GEN_CTRL)); + ath_dbg(common, ATH_DBG_RESET, + "\n==== BB update: BB status=0x%08x ====\n", status); + ath_dbg(common, ATH_DBG_RESET, + "** BB state: wd=%u det=%u rdar=%u rOFDM=%d rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", + MS(status, AR_PHY_WATCHDOG_INFO), + MS(status, AR_PHY_WATCHDOG_DET_HANG), + MS(status, AR_PHY_WATCHDOG_RADAR_SM), + MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM), + MS(status, AR_PHY_WATCHDOG_RX_CCK_SM), + MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM), + MS(status, AR_PHY_WATCHDOG_TX_CCK_SM), + MS(status, AR_PHY_WATCHDOG_AGC_SM), + MS(status, AR_PHY_WATCHDOG_SRCH_SM)); + + ath_dbg(common, ATH_DBG_RESET, + "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", + REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), + REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); + ath_dbg(common, ATH_DBG_RESET, + "** BB mode: BB_gen_controls=0x%08x **\n", + REG_READ(ah, AR_PHY_GEN_CTRL)); #define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles) if (common->cc_survey.cycles) - ath_print(common, ATH_DBG_RESET, - "** BB busy times: rx_clear=%d%%, " - "rx_frame=%d%%, tx_frame=%d%% **\n", - PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); + ath_dbg(common, ATH_DBG_RESET, + "** BB busy times: rx_clear=%d%%, rx_frame=%d%%, tx_frame=%d%% **\n", + PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); - ath_print(common, ATH_DBG_RESET, - "==== BB update: done ====\n\n"); + ath_dbg(common, ATH_DBG_RESET, + "==== BB update: done ====\n\n"); } EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 70019e93e739..5e108c086904 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -120,11 +120,11 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = sc->beacon.cabq; - ath_print(common, ATH_DBG_XMIT, - "transmitting CABQ packet, skb: %p\n", skb); + ath_dbg(common, ATH_DBG_XMIT, + "transmitting CABQ packet, skb: %p\n", skb); if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n"); + ath_dbg(common, ATH_DBG_XMIT, "CABQ TX failed\n"); dev_kfree_skb_any(skb); } } @@ -209,8 +209,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, if (skb && cabq_depth) { if (sc->nvifs > 1) { - ath_print(common, ATH_DBG_BEACON, - "Flushing previous cabq traffic\n"); + ath_dbg(common, ATH_DBG_BEACON, + "Flushing previous cabq traffic\n"); ath_draintxq(sc, cabq, false); } } @@ -282,7 +282,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) /* NB: the beacon data buffer must be 32-bit aligned. */ skb = ieee80211_beacon_get(sc->hw, vif); if (skb == NULL) { - ath_print(common, ATH_DBG_BEACON, "cannot get skb\n"); + ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n"); return -ENOMEM; } @@ -306,10 +306,9 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) tsfadjust = intval * avp->av_bslot / ATH_BCBUF; avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); - ath_print(common, ATH_DBG_BEACON, - "stagger beacons, bslot %d intval " - "%u tsfadjust %llu\n", - avp->av_bslot, intval, (unsigned long long)tsfadjust); + ath_dbg(common, ATH_DBG_BEACON, + "stagger beacons, bslot %d intval %u tsfadjust %llu\n", + avp->av_bslot, intval, (unsigned long long)tsfadjust); ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = avp->tsf_adjust; @@ -380,13 +379,13 @@ void ath_beacon_tasklet(unsigned long data) sc->beacon.bmisscnt++; if (sc->beacon.bmisscnt < BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BSTUCK, - "missed %u consecutive beacons\n", - sc->beacon.bmisscnt); + ath_dbg(common, ATH_DBG_BSTUCK, + "missed %u consecutive beacons\n", + sc->beacon.bmisscnt); ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BSTUCK, - "beacon is officially stuck\n"); + ath_dbg(common, ATH_DBG_BSTUCK, + "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; ath_reset(sc, true); } @@ -395,9 +394,9 @@ void ath_beacon_tasklet(unsigned long data) } if (sc->beacon.bmisscnt != 0) { - ath_print(common, ATH_DBG_BSTUCK, - "resume beacon xmit after %u misses\n", - sc->beacon.bmisscnt); + ath_dbg(common, ATH_DBG_BSTUCK, + "resume beacon xmit after %u misses\n", + sc->beacon.bmisscnt); sc->beacon.bmisscnt = 0; } @@ -423,9 +422,9 @@ void ath_beacon_tasklet(unsigned long data) vif = sc->beacon.bslot[slot]; aphy = sc->beacon.bslot_aphy[slot]; - ath_print(common, ATH_DBG_BEACON, - "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", - slot, tsf, tsftu, intval, vif); + ath_dbg(common, ATH_DBG_BEACON, + "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", + slot, tsf, tsftu, intval, vif); bfaddr = 0; if (vif) { @@ -554,8 +553,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc, /* No need to configure beacon if we are not associated */ if (!common->curaid) { - ath_print(common, ATH_DBG_BEACON, - "STA is not yet associated..skipping beacon config\n"); + ath_dbg(common, ATH_DBG_BEACON, + "STA is not yet associated..skipping beacon config\n"); return; } @@ -648,11 +647,11 @@ static void ath_beacon_config_sta(struct ath_softc *sc, /* TSF out of range threshold fixed at 1 second */ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; - ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); - ath_print(common, ATH_DBG_BEACON, - "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", - bs.bs_bmissthreshold, bs.bs_sleepduration, - bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); + ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); + ath_dbg(common, ATH_DBG_BEACON, + "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", + bs.bs_bmissthreshold, bs.bs_sleepduration, + bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); /* Set the computed STA beacon timers */ @@ -688,9 +687,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, nexttbtt += intval; } while (nexttbtt < tsftu); - ath_print(common, ATH_DBG_BEACON, - "IBSS nexttbtt %u intval %u (%u)\n", - nexttbtt, intval, conf->beacon_interval); + ath_dbg(common, ATH_DBG_BEACON, + "IBSS nexttbtt %u intval %u (%u)\n", + nexttbtt, intval, conf->beacon_interval); /* * In IBSS mode enable the beacon timers but only enable SWBA interrupts @@ -753,8 +752,8 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) ath_beacon_config_sta(sc, cur_conf); break; default: - ath_print(common, ATH_DBG_CONFIG, - "Unsupported beaconing mode\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Unsupported beaconing mode\n"); return; } diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 6d509484b5f6..b68a1acbddd0 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -97,12 +97,12 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, if (h[i].privNF > limit->max) { high_nf_mid = true; - ath_print(common, ATH_DBG_CALIBRATE, - "NFmid[%d] (%d) > MAX (%d), %s\n", - i, h[i].privNF, limit->max, - (cal->nfcal_interference ? - "not corrected (due to interference)" : - "correcting to MAX")); + ath_dbg(common, ATH_DBG_CALIBRATE, + "NFmid[%d] (%d) > MAX (%d), %s\n", + i, h[i].privNF, limit->max, + (cal->nfcal_interference ? + "not corrected (due to interference)" : + "correcting to MAX")); /* * Normally we limit the average noise floor by the @@ -180,18 +180,18 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) return true; if (currCal->calState != CAL_DONE) { - ath_print(common, ATH_DBG_CALIBRATE, - "Calibration state incorrect, %d\n", - currCal->calState); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Calibration state incorrect, %d\n", + currCal->calState); return true; } if (!(ah->supp_cals & currCal->calData->calType)) return true; - ath_print(common, ATH_DBG_CALIBRATE, - "Resetting Cal %d state for channel %u\n", - currCal->calData->calType, conf->channel->center_freq); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Resetting Cal %d state for channel %u\n", + currCal->calData->calType, conf->channel->center_freq); ah->caldata->CalValid &= ~currCal->calData->calType; currCal->calState = CAL_WAITING; @@ -279,9 +279,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) * noisefloor until the next calibration timer. */ if (j == 1000) { - ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " - "to load: AR_PHY_AGC_CONTROL=0x%x\n", - REG_READ(ah, AR_PHY_AGC_CONTROL)); + ath_dbg(common, ATH_DBG_ANY, + "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", + REG_READ(ah, AR_PHY_AGC_CONTROL)); return; } @@ -318,19 +318,19 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) if (!nf[i]) continue; - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [%s] [chain %d] is %d\n", - (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); + ath_dbg(common, ATH_DBG_CALIBRATE, + "NF calibrated [%s] [chain %d] is %d\n", + (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); if (nf[i] > ATH9K_NF_TOO_HIGH) { - ath_print(common, ATH_DBG_CALIBRATE, - "NF[%d] (%d) > MAX (%d), correcting to MAX", - i, nf[i], ATH9K_NF_TOO_HIGH); + ath_dbg(common, ATH_DBG_CALIBRATE, + "NF[%d] (%d) > MAX (%d), correcting to MAX\n", + i, nf[i], ATH9K_NF_TOO_HIGH); nf[i] = limit->max; } else if (nf[i] < limit->min) { - ath_print(common, ATH_DBG_CALIBRATE, - "NF[%d] (%d) < MIN (%d), correcting to NOM", - i, nf[i], limit->min); + ath_dbg(common, ATH_DBG_CALIBRATE, + "NF[%d] (%d) < MIN (%d), correcting to NOM\n", + i, nf[i], limit->min); nf[i] = limit->nominal; } } @@ -347,8 +347,8 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) chan->channelFlags &= (~CHANNEL_CW_INT); if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { - ath_print(common, ATH_DBG_CALIBRATE, - "NF did not complete in calibration window\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, + "NF did not complete in calibration window\n"); return false; } @@ -357,10 +357,9 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) nf = nfarray[0]; if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) && nf > nfThresh) { - ath_print(common, ATH_DBG_CALIBRATE, - "noise floor failed detected; " - "detected %d, threshold %d\n", - nf, nfThresh); + ath_dbg(common, ATH_DBG_CALIBRATE, + "noise floor failed detected; detected %d, threshold %d\n", + nf, nfThresh); chan->channelFlags |= CHANNEL_CW_INT; } diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 48b07c319a7f..df1998d48253 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -180,8 +180,8 @@ void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, AR_STOMP_NONE_WLAN_WGHT); break; default: - ath_print(common, ATH_DBG_BTCOEX, - "Invalid Stomptype\n"); + ath_dbg(common, ATH_DBG_BTCOEX, + "Invalid Stomptype\n"); break; } diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 4c04ee85ff0e..a126bddebb0a 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -17,7 +17,6 @@ #include #include "../ath.h" -#include "../debug.h" #include "hw.h" #include "hw-ops.h" diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 2bbf94d0191e..fda533cfd881 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -273,8 +273,8 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; break; default: - ath_print(common, ATH_DBG_EEPROM, - "Invalid chainmask configuration\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Invalid chainmask configuration\n"); break; } } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index f74692da24db..939fc7af86f8 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -37,14 +37,14 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) eep_start_loc = 64; if (!ath9k_hw_use_flash(ah)) { - ath_print(common, ATH_DBG_EEPROM, - "Reading from EEPROM, not flash\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Reading from EEPROM, not flash\n"); } for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { - ath_print(common, ATH_DBG_EEPROM, - "Unable to read eeprom region\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Unable to read eeprom region\n"); return false; } eep_data++; @@ -73,8 +73,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) return false; } - ath_print(common, ATH_DBG_EEPROM, - "Read Magic = 0x%04X\n", magic); + ath_dbg(common, ATH_DBG_EEPROM, + "Read Magic = 0x%04X\n", magic); if (magic != AR5416_EEPROM_MAGIC) { magic2 = swab16(magic); @@ -90,14 +90,14 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) } } else { ath_err(common, - "Invalid EEPROM Magic. endianness mismatch.\n"); + "Invalid EEPROM Magic. Endianness mismatch.\n"); return -EINVAL; } } } - ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", - need_swap ? "True" : "False"); + ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", + need_swap ? "True" : "False"); if (need_swap) el = swab16(ah->eeprom.map4k.baseEepHeader.length); @@ -118,8 +118,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) u32 integer; u16 word; - ath_print(common, ATH_DBG_EEPROM, - "EEPROM Endianness is not native.. Changing\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "EEPROM Endianness is not native.. Changing\n"); word = swab16(eep->baseEepHeader.length); eep->baseEepHeader.length = word; @@ -485,21 +485,20 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, ((pdadcValues[4 * j + 3] & 0xFF) << 24); REG_WRITE(ah, regOffset, reg32); - ath_print(common, ATH_DBG_EEPROM, - "PDADC (%d,%4x): %4.4x %8.8x\n", - i, regChainOffset, regOffset, - reg32); - ath_print(common, ATH_DBG_EEPROM, - "PDADC: Chain %d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d |\n", - i, 4 * j, pdadcValues[4 * j], - 4 * j + 1, pdadcValues[4 * j + 1], - 4 * j + 2, pdadcValues[4 * j + 2], - 4 * j + 3, - pdadcValues[4 * j + 3]); + ath_dbg(common, ATH_DBG_EEPROM, + "PDADC (%d,%4x): %4.4x %8.8x\n", + i, regChainOffset, regOffset, + reg32); + ath_dbg(common, ATH_DBG_EEPROM, + "PDADC: Chain %d | " + "PDADC %3d Value %3d | " + "PDADC %3d Value %3d | " + "PDADC %3d Value %3d | " + "PDADC %3d Value %3d |\n", + i, 4 * j, pdadcValues[4 * j], + 4 * j + 1, pdadcValues[4 * j + 1], + 4 * j + 2, pdadcValues[4 * j + 2], + 4 * j + 3, pdadcValues[4 * j + 3]); regOffset += 4; } @@ -1178,17 +1177,17 @@ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) u16 spur_val = AR_NO_SPUR; - ath_print(common, ATH_DBG_ANI, - "Getting spur idx %d is2Ghz. %d val %x\n", - i, is2GHz, ah->config.spurchans[i][is2GHz]); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur idx:%d is2Ghz:%d val:%x\n", + i, is2GHz, ah->config.spurchans[i][is2GHz]); switch (ah->config.spurmode) { case SPUR_DISABLE: break; case SPUR_ENABLE_IOCTL: spur_val = ah->config.spurchans[i][is2GHz]; - ath_print(common, ATH_DBG_ANI, - "Getting spur val from new loc. %d\n", spur_val); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur val from new loc. %d\n", spur_val); break; case SPUR_ENABLE_EEPROM: spur_val = EEP_MAP4K_SPURCHAN; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 9308b684eaa2..9ec4bc80f758 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -43,15 +43,15 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) eep_start_loc = AR9287_HTC_EEP_START_LOC; if (!ath9k_hw_use_flash(ah)) { - ath_print(common, ATH_DBG_EEPROM, - "Reading from EEPROM, not flash\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Reading from EEPROM, not flash\n"); } for (addr = 0; addr < NUM_EEP_WORDS; addr++) { if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { - ath_print(common, ATH_DBG_EEPROM, - "Unable to read eeprom region\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "Unable to read eeprom region\n"); return false; } eep_data++; @@ -76,8 +76,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) return false; } - ath_print(common, ATH_DBG_EEPROM, - "Read Magic = 0x%04X\n", magic); + ath_dbg(common, ATH_DBG_EEPROM, + "Read Magic = 0x%04X\n", magic); if (magic != AR5416_EEPROM_MAGIC) { magic2 = swab16(magic); @@ -99,8 +99,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) } } - ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", - need_swap ? "True" : "False"); + ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", + need_swap ? "True" : "False"); if (need_swap) el = swab16(ah->eeprom.map9287.baseEepHeader.length); @@ -1149,17 +1149,17 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, struct ath_common *common = ath9k_hw_common(ah); u16 spur_val = AR_NO_SPUR; - ath_print(common, ATH_DBG_ANI, - "Getting spur idx %d is2Ghz. %d val %x\n", - i, is2GHz, ah->config.spurchans[i][is2GHz]); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur idx:%d is2Ghz:%d val:%x\n", + i, is2GHz, ah->config.spurchans[i][is2GHz]); switch (ah->config.spurmode) { case SPUR_DISABLE: break; case SPUR_ENABLE_IOCTL: spur_val = ah->config.spurchans[i][is2GHz]; - ath_print(common, ATH_DBG_ANI, - "Getting spur val from new loc. %d\n", spur_val); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur val from new loc. %d\n", spur_val); break; case SPUR_ENABLE_EEPROM: spur_val = EEP_MAP9287_SPURCHAN; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 864a877bc05a..c2b4bba7410c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -122,8 +122,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) } if (!ath9k_hw_use_flash(ah)) { - ath_print(common, ATH_DBG_EEPROM, - "Read Magic = 0x%04X\n", magic); + ath_dbg(common, ATH_DBG_EEPROM, + "Read Magic = 0x%04X\n", magic); if (magic != AR5416_EEPROM_MAGIC) { magic2 = swab16(magic); @@ -146,8 +146,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) } } - ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", - need_swap ? "True" : "False"); + ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", + need_swap ? "True" : "False"); if (need_swap) el = swab16(ah->eeprom.def.baseEepHeader.length); @@ -168,8 +168,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) u32 integer, j; u16 word; - ath_print(common, ATH_DBG_EEPROM, - "EEPROM Endianness is not native.. Changing.\n"); + ath_dbg(common, ATH_DBG_EEPROM, + "EEPROM Endianness is not native.. Changing.\n"); word = swab16(eep->baseEepHeader.length); eep->baseEepHeader.length = word; @@ -964,20 +964,19 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, ((pdadcValues[4 * j + 3] & 0xFF) << 24); REG_WRITE(ah, regOffset, reg32); - ath_print(common, ATH_DBG_EEPROM, - "PDADC (%d,%4x): %4.4x %8.8x\n", - i, regChainOffset, regOffset, - reg32); - ath_print(common, ATH_DBG_EEPROM, - "PDADC: Chain %d | PDADC %3d " - "Value %3d | PDADC %3d Value %3d | " - "PDADC %3d Value %3d | PDADC %3d " - "Value %3d |\n", - i, 4 * j, pdadcValues[4 * j], - 4 * j + 1, pdadcValues[4 * j + 1], - 4 * j + 2, pdadcValues[4 * j + 2], - 4 * j + 3, - pdadcValues[4 * j + 3]); + ath_dbg(common, ATH_DBG_EEPROM, + "PDADC (%d,%4x): %4.4x %8.8x\n", + i, regChainOffset, regOffset, + reg32); + ath_dbg(common, ATH_DBG_EEPROM, + "PDADC: Chain %d | PDADC %3d " + "Value %3d | PDADC %3d Value %3d | " + "PDADC %3d Value %3d | PDADC %3d " + "Value %3d |\n", + i, 4 * j, pdadcValues[4 * j], + 4 * j + 1, pdadcValues[4 * j + 1], + 4 * j + 2, pdadcValues[4 * j + 2], + 4 * j + 3, pdadcValues[4 * j + 3]); regOffset += 4; } @@ -1317,8 +1316,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; break; default: - ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM, - "Invalid chainmask configuration\n"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_EEPROM, + "Invalid chainmask configuration\n"); break; } @@ -1459,17 +1458,17 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) u16 spur_val = AR_NO_SPUR; - ath_print(common, ATH_DBG_ANI, - "Getting spur idx %d is2Ghz. %d val %x\n", - i, is2GHz, ah->config.spurchans[i][is2GHz]); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur idx:%d is2Ghz:%d val:%x\n", + i, is2GHz, ah->config.spurchans[i][is2GHz]); switch (ah->config.spurmode) { case SPUR_DISABLE: break; case SPUR_ENABLE_IOCTL: spur_val = ah->config.spurchans[i][is2GHz]; - ath_print(common, ATH_DBG_ANI, - "Getting spur val from new loc. %d\n", spur_val); + ath_dbg(common, ATH_DBG_ANI, + "Getting spur val from new loc. %d\n", spur_val); break; case SPUR_ENABLE_EEPROM: spur_val = EEP_DEF_SPURCHAN; diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 2b1b58306662..133764069246 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -236,13 +236,13 @@ static void ath_detect_bt_priority(struct ath_softc *sc) sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); /* Detect if colocated bt started scanning */ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, - "BT scan detected"); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, + "BT scan detected\n"); sc->sc_flags |= (SC_OP_BT_SCAN | SC_OP_BT_PRIORITY_DETECTED); } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, - "BT priority traffic detected"); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, + "BT priority traffic detected\n"); sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; } @@ -331,8 +331,8 @@ static void ath_btcoex_no_stomp_timer(void *arg) struct ath_common *common = ath9k_hw_common(ah); bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; - ath_print(common, ATH_DBG_BTCOEX, - "no stomp timer running\n"); + ath_dbg(common, ATH_DBG_BTCOEX, + "no stomp timer running\n"); spin_lock_bh(&btcoex->btcoex_lock); @@ -378,8 +378,8 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) struct ath_btcoex *btcoex = &sc->btcoex; struct ath_hw *ah = sc->sc_ah; - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "Starting btcoex timers"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "Starting btcoex timers\n"); /* make sure duty cycle timer is also stopped when resuming */ if (btcoex->hw_timer_enabled) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index dd9514e019ea..87cc65a78a3f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -123,11 +123,11 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, /* TSF out of range threshold fixed at 1 second */ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; - ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); - ath_print(common, ATH_DBG_BEACON, - "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", - bs.bs_bmissthreshold, bs.bs_sleepduration, - bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); + ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); + ath_dbg(common, ATH_DBG_BEACON, + "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", + bs.bs_bmissthreshold, bs.bs_sleepduration, + bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); /* Set the computed STA beacon timers */ @@ -154,9 +154,9 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; - ath_print(common, ATH_DBG_BEACON, - "IBSS Beacon config, intval: %d, imask: 0x%x\n", - bss_conf->beacon_interval, imask); + ath_dbg(common, ATH_DBG_BEACON, + "IBSS Beacon config, intval: %d, imask: 0x%x\n", + bss_conf->beacon_interval, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); @@ -278,8 +278,8 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, ath9k_htc_beacon_config_adhoc(priv, cur_conf); break; default: - ath_print(common, ATH_DBG_CONFIG, - "Unsupported beaconing mode\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Unsupported beaconing mode\n"); return; } } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 50eec9a3b88c..283ff97ed446 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -20,13 +20,13 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); /* Detect if colocated bt started scanning */ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "BT scan detected"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT scan detected\n"); priv->op_flags |= (OP_BT_SCAN | OP_BT_PRIORITY_DETECTED); } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "BT priority traffic detected"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT priority traffic detected\n"); priv->op_flags |= OP_BT_PRIORITY_DETECTED; } @@ -83,8 +83,8 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) struct ath_common *common = ath9k_hw_common(ah); bool is_btscan = priv->op_flags & OP_BT_SCAN; - ath_print(common, ATH_DBG_BTCOEX, - "time slice work for bt and wlan\n"); + ath_dbg(common, ATH_DBG_BTCOEX, + "time slice work for bt and wlan\n"); if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); @@ -114,8 +114,7 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) struct ath_btcoex *btcoex = &priv->btcoex; struct ath_hw *ah = priv->ah; - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "Starting btcoex work"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "Starting btcoex work\n"); btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 20b32f614c1f..f89f6635abae 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -288,9 +288,9 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) (u8 *) &val, sizeof(val), 100); if (unlikely(r)) { - ath_print(common, ATH_DBG_WMI, - "REGISTER READ FAILED: (0x%04x, %d)\n", - reg_offset, r); + ath_dbg(common, ATH_DBG_WMI, + "REGISTER READ FAILED: (0x%04x, %d)\n", + reg_offset, r); return -EIO; } @@ -313,9 +313,9 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) (u8 *) &val, sizeof(val), 100); if (unlikely(r)) { - ath_print(common, ATH_DBG_WMI, - "REGISTER WRITE FAILED:(0x%04x, %d)\n", - reg_offset, r); + ath_dbg(common, ATH_DBG_WMI, + "REGISTER WRITE FAILED:(0x%04x, %d)\n", + reg_offset, r); } } @@ -345,9 +345,9 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset) (u8 *) &rsp_status, sizeof(rsp_status), 100); if (unlikely(r)) { - ath_print(common, ATH_DBG_WMI, - "REGISTER WRITE FAILED, multi len: %d\n", - priv->wmi->multi_write_idx); + ath_dbg(common, ATH_DBG_WMI, + "REGISTER WRITE FAILED, multi len: %d\n", + priv->wmi->multi_write_idx); } priv->wmi->multi_write_idx = 0; } @@ -395,9 +395,9 @@ static void ath9k_regwrite_flush(void *hw_priv) (u8 *) &rsp_status, sizeof(rsp_status), 100); if (unlikely(r)) { - ath_print(common, ATH_DBG_WMI, - "REGISTER WRITE FAILED, multi len: %d\n", - priv->wmi->multi_write_idx); + ath_dbg(common, ATH_DBG_WMI, + "REGISTER WRITE FAILED, multi len: %d\n", + priv->wmi->multi_write_idx); } priv->wmi->multi_write_idx = 0; } @@ -469,9 +469,9 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv, tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2); rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2); - ath_print(common, ATH_DBG_CONFIG, - "TX streams %d, RX streams: %d\n", - tx_streams, rx_streams); + ath_dbg(common, ATH_DBG_CONFIG, + "TX streams %d, RX streams: %d\n", + tx_streams, rx_streams); if (tx_streams != rx_streams) { ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; @@ -537,9 +537,9 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) /* Get the hardware key cache size. */ common->keymax = priv->ah->caps.keycache_size; if (common->keymax > ATH_KEYMAX) { - ath_print(common, ATH_DBG_ANY, - "Warning, using only %u entries in %u key cache\n", - ATH_KEYMAX, common->keymax); + ath_dbg(common, ATH_DBG_ANY, + "Warning, using only %u entries in %u key cache\n", + ATH_KEYMAX, common->keymax); common->keymax = ATH_KEYMAX; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index a8007af4e149..87731c2daae4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -143,11 +143,11 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); - ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", - priv->ah->curchan->channel, - channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), - fastcc); + ath_dbg(common, ATH_DBG_CONFIG, + "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", + priv->ah->curchan->channel, + channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), + fastcc); caldata = &priv->caldata[channel->hw_value]; ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); @@ -270,9 +270,9 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, } if (sta) - ath_print(common, ATH_DBG_CONFIG, - "Added a station entry for: %pM (idx: %d)\n", - sta->addr, tsta.sta_index); + ath_dbg(common, ATH_DBG_CONFIG, + "Added a station entry for: %pM (idx: %d)\n", + sta->addr, tsta.sta_index); priv->nstations++; return 0; @@ -304,9 +304,9 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, } if (sta) - ath_print(common, ATH_DBG_CONFIG, - "Removed a station entry for: %pM (idx: %d)\n", - sta->addr, sta_idx); + ath_dbg(common, ATH_DBG_CONFIG, + "Removed a station entry for: %pM (idx: %d)\n", + sta->addr, sta_idx); priv->nstations--; return 0; @@ -409,9 +409,9 @@ static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv, ath9k_htc_setup_rate(priv, sta, &trate); ret = ath9k_htc_send_rate_cmd(priv, &trate); if (!ret) - ath_print(common, ATH_DBG_CONFIG, - "Updated target sta: %pM, rate caps: 0x%X\n", - sta->addr, be32_to_cpu(trate.capflags)); + ath_dbg(common, ATH_DBG_CONFIG, + "Updated target sta: %pM, rate caps: 0x%X\n", + sta->addr, be32_to_cpu(trate.capflags)); } static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv, @@ -436,9 +436,9 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv, ret = ath9k_htc_send_rate_cmd(priv, &trate); if (!ret) - ath_print(common, ATH_DBG_CONFIG, - "Updated target sta: %pM, rate caps: 0x%X\n", - bss_conf->bssid, be32_to_cpu(trate.capflags)); + ath_dbg(common, ATH_DBG_CONFIG, + "Updated target sta: %pM, rate caps: 0x%X\n", + bss_conf->bssid, be32_to_cpu(trate.capflags)); } static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, @@ -465,14 +465,14 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); if (ret) - ath_print(common, ATH_DBG_CONFIG, - "Unable to %s TX aggregation for (%pM, %d)\n", - (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid); + ath_dbg(common, ATH_DBG_CONFIG, + "Unable to %s TX aggregation for (%pM, %d)\n", + (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid); else - ath_print(common, ATH_DBG_CONFIG, - "%s TX aggregation for (%pM, %d)\n", - (aggr.aggr_enable) ? "Starting" : "Stopping", - sta->addr, tid); + ath_dbg(common, ATH_DBG_CONFIG, + "%s TX aggregation for (%pM, %d)\n", + (aggr.aggr_enable) ? "Starting" : "Stopping", + sta->addr, tid); spin_lock_bh(&priv->tx_lock); ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; @@ -725,7 +725,7 @@ void ath9k_ani_work(struct work_struct *work) /* Long calibration runs independently of short calibration. */ if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { longcal = true; - ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); + ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); common->ani.longcal_timer = timestamp; } @@ -734,8 +734,8 @@ void ath9k_ani_work(struct work_struct *work) if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { shortcal = true; - ath_print(common, ATH_DBG_ANI, - "shortcal @%lu\n", jiffies); + ath_dbg(common, ATH_DBG_ANI, + "shortcal @%lu\n", jiffies); common->ani.shortcal_timer = timestamp; common->ani.resetcal_timer = timestamp; } @@ -1125,15 +1125,15 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ret = ath9k_htc_tx_start(priv, skb); if (ret != 0) { if (ret == -ENOMEM) { - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Stopping TX queues\n"); + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, + "Stopping TX queues\n"); ieee80211_stop_queues(hw); spin_lock_bh(&priv->tx_lock); priv->tx_queues_stop = true; spin_unlock_bh(&priv->tx_lock); } else { - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Tx failed"); + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, + "Tx failed\n"); } goto fail_tx; } @@ -1159,9 +1159,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); - ath_print(common, ATH_DBG_CONFIG, - "Starting driver with initial channel: %d MHz\n", - curchan->center_freq); + ath_dbg(common, ATH_DBG_CONFIG, + "Starting driver with initial channel: %d MHz\n", + curchan->center_freq); /* Ensure that HW is awake before flushing RX */ ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); @@ -1224,7 +1224,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); if (priv->op_flags & OP_INVALID) { - ath_print(common, ATH_DBG_ANY, "Device not present\n"); + ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); mutex_unlock(&priv->mutex); return; } @@ -1246,8 +1246,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) if (ath9k_htc_remove_monitor_interface(priv)) ath_err(common, "Unable to remove monitor interface\n"); else - ath_print(common, ATH_DBG_CONFIG, - "Monitor interface removed\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Monitor interface removed\n"); } if (ah->btcoex_hw.enabled) { @@ -1264,7 +1264,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) priv->op_flags |= OP_INVALID; - ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); mutex_unlock(&priv->mutex); } @@ -1304,8 +1304,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, goto out; } - ath_print(common, ATH_DBG_CONFIG, - "Attach a VIF of type: %d\n", vif->type); + ath_dbg(common, ATH_DBG_CONFIG, + "Attach a VIF of type: %d\n", vif->type); priv->ah->opmode = vif->type; @@ -1328,8 +1328,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ret = ath9k_htc_update_cap_target(priv); if (ret) - ath_print(common, ATH_DBG_CONFIG, "Failed to update" - " capability in target \n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Failed to update capability in target\n"); priv->vif = vif; out: @@ -1349,7 +1349,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, int ret = 0; u8 cmd_rsp; - ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); @@ -1386,8 +1386,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) mutex_unlock(&priv->htc_pm_lock); if (enable_radio) { - ath_print(common, ATH_DBG_CONFIG, - "not-idle: enabling radio\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "not-idle: enabling radio\n"); ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); ath9k_htc_radio_enable(hw); } @@ -1397,8 +1397,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; - ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", - curchan->center_freq); + ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", + curchan->center_freq); ath9k_cmn_update_ichannel(&priv->ah->channels[pos], hw->conf.channel, @@ -1427,8 +1427,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) if (ath9k_htc_add_monitor_interface(priv)) ath_err(common, "Failed to set monitor mode\n"); else - ath_print(common, ATH_DBG_CONFIG, - "HW opmode set to Monitor mode\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "HW opmode set to Monitor mode\n"); } } @@ -1440,8 +1440,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } mutex_unlock(&priv->htc_pm_lock); - ath_print(common, ATH_DBG_CONFIG, - "idle: disabling radio\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "idle: disabling radio\n"); ath9k_htc_radio_disable(hw); } @@ -1478,8 +1478,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, rfilt = ath9k_htc_calcrxfilter(priv); ath9k_hw_setrxfilter(priv->ah, rfilt); - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, - "Set HW RX filter: 0x%x\n", rfilt); + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, + "Set HW RX filter: 0x%x\n", rfilt); ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); @@ -1542,11 +1542,10 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, qnum = get_hw_qnum(queue, priv->hwq_map); - ath_print(common, ATH_DBG_CONFIG, - "Configure tx [queue/hwq] [%d/%d], " - "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - queue, qnum, params->aifs, params->cw_min, - params->cw_max, params->txop); + ath_dbg(common, ATH_DBG_CONFIG, + "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + queue, qnum, params->aifs, params->cw_min, + params->cw_max, params->txop); ret = ath_htc_txq_update(priv, qnum, &qi); if (ret) { @@ -1578,7 +1577,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, return -ENOSPC; mutex_lock(&priv->mutex); - ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); ath9k_htc_ps_wakeup(priv); switch (cmd) { @@ -1624,7 +1623,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { common->curaid = bss_conf->assoc ? bss_conf->aid : 0; - ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); if (bss_conf->assoc) { @@ -1641,9 +1640,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_hw_write_associd(ah); - ath_print(common, ATH_DBG_CONFIG, - "BSSID: %pM aid: 0x%x\n", - common->curbssid, common->curaid); + ath_dbg(common, ATH_DBG_CONFIG, + "BSSID: %pM aid: 0x%x\n", + common->curbssid, common->curaid); } if ((changed & BSS_CHANGED_BEACON_INT) || @@ -1661,8 +1660,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", + bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) priv->op_flags |= OP_PREAMBLE_SHORT; else @@ -1670,8 +1669,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", + bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && hw->conf.channel->band != IEEE80211_BAND_5GHZ) priv->op_flags |= OP_PROTECT_ENABLE; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 5bef41f8c82b..31fad82239b3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -270,8 +270,8 @@ void ath9k_tx_tasklet(unsigned long data) if (priv->tx_queues_stop) { priv->tx_queues_stop = false; spin_unlock_bh(&priv->tx_lock); - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Waking up TX queues\n"); + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, + "Waking up TX queues\n"); ieee80211_wake_queues(priv->hw); return; } @@ -681,8 +681,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, spin_unlock(&priv->rx.rxbuflock); if (rxbuf == NULL) { - ath_print(common, ATH_DBG_ANY, - "No free RX buffer\n"); + ath_dbg(common, ATH_DBG_ANY, + "No free RX buffer\n"); goto err; } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 00ecbfa07df5..9d3be0392a9b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -129,9 +129,9 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) udelay(AH_TIME_QUANTUM); } - ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, - "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", - timeout, reg, REG_READ(ah, reg), mask, val); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_ANY, + "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", + timeout, reg, REG_READ(ah, reg), mask, val); return false; } @@ -465,10 +465,10 @@ static int ath9k_hw_post_init(struct ath_hw *ah) if (ecode != 0) return ecode; - ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG, - "Eeprom VER: %d, REV: %d\n", - ah->eep_ops->get_eeprom_ver(ah), - ah->eep_ops->get_eeprom_rev(ah)); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CONFIG, + "Eeprom VER: %d, REV: %d\n", + ah->eep_ops->get_eeprom_ver(ah), + ah->eep_ops->get_eeprom_rev(ah)); ecode = ath9k_hw_rf_alloc_ext_banks(ah); if (ecode) { @@ -530,7 +530,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) } } - ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n", + ath_dbg(common, ATH_DBG_RESET, "serialize_regmode is %d\n", ah->config.serialize_regmode); if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) @@ -758,8 +758,8 @@ static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) { if (tu > 0xFFFF) { - ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, - "bad global tx timeout %u\n", tu); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, + "bad global tx timeout %u\n", tu); ah->globaltxtimeout = (u32) -1; return false; } else { @@ -776,8 +776,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) int slottime; int sifstime; - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", - ah->misc_mode); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", + ah->misc_mode); if (ah->misc_mode != 0) REG_WRITE(ah, AR_PCU_MISC, @@ -1020,8 +1020,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) REG_WRITE(ah, AR_RTC_RC, 0); if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, - "RTC stuck in MAC reset\n"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, + "RTC stuck in MAC reset\n"); return false; } @@ -1067,8 +1067,8 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) AR_RTC_STATUS_M, AR_RTC_STATUS_ON, AH_WAIT_TIMEOUT)) { - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, - "RTC not waking up\n"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, + "RTC not waking up\n"); return false; } @@ -1128,9 +1128,8 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { if (ath9k_hw_numtxpending(ah, qnum)) { - ath_print(common, ATH_DBG_QUEUE, - "Transmit frames pending on " - "queue %d\n", qnum); + ath_dbg(common, ATH_DBG_QUEUE, + "Transmit frames pending on queue %d\n", qnum); return false; } } @@ -1211,7 +1210,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ah->chip_fullsleep) { ath9k_hw_abortpcurecv(ah); if (!ath9k_hw_stopdmarecv(ah)) { - ath_print(common, ATH_DBG_XMIT, + ath_dbg(common, ATH_DBG_XMIT, "Failed to stop receive dma\n"); bChannelChange = false; } @@ -1423,13 +1422,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, u32 mask; mask = REG_READ(ah, AR_CFG); if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { - ath_print(common, ATH_DBG_RESET, + ath_dbg(common, ATH_DBG_RESET, "CFG Byte Swap Set 0x%x\n", mask); } else { mask = INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; REG_WRITE(ah, AR_CFG, mask); - ath_print(common, ATH_DBG_RESET, + ath_dbg(common, ATH_DBG_RESET, "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); } } else { @@ -1583,8 +1582,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) if (ah->power_mode == mode) return status; - ath_print(common, ATH_DBG_RESET, "%s -> %s\n", - modes[ah->power_mode], modes[mode]); + ath_dbg(common, ATH_DBG_RESET, "%s -> %s\n", + modes[ah->power_mode], modes[mode]); switch (mode) { case ATH9K_PM_AWAKE: @@ -1657,9 +1656,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) flags |= AR_TBTT_TIMER_EN; break; } - ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, - "%s: unsupported opmode: %d\n", - __func__, ah->opmode); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON, + "%s: unsupported opmode: %d\n", + __func__, ah->opmode); return; break; } @@ -1715,10 +1714,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, else nextTbtt = bs->bs_nexttbtt; - ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); - ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); - ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); - ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); + ath_dbg(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); + ath_dbg(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); + ath_dbg(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); + ath_dbg(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); ENABLE_REGWRITE_BUFFER(ah); @@ -1783,8 +1782,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) regulatory->current_rd += 5; else if (regulatory->current_rd == 0x41) regulatory->current_rd = 0x43; - ath_print(common, ATH_DBG_REGULATORY, - "regdomain mapped to 0x%x\n", regulatory->current_rd); + ath_dbg(common, ATH_DBG_REGULATORY, + "regdomain mapped to 0x%x\n", regulatory->current_rd); } eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); @@ -2245,8 +2244,8 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah) { if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, AH_TSF_WRITE_TIMEOUT)) - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, - "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, + "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); } @@ -2367,9 +2366,9 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, tsf = ath9k_hw_gettsf32(ah); - ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER, - "curent tsf %x period %x" - "timer_next %x\n", tsf, timer_period, timer_next); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, + "current tsf %x period %x timer_next %x\n", + tsf, timer_period, timer_next); /* * Pull timer_next forward if the current TSF already passed it @@ -2449,8 +2448,8 @@ void ath_gen_timer_isr(struct ath_hw *ah) index = rightmost_index(timer_table, &thresh_mask); timer = timer_table->timers[index]; BUG_ON(!timer); - ath_print(common, ATH_DBG_HWTIMER, - "TSF overflow for Gen timer %d\n", index); + ath_dbg(common, ATH_DBG_HWTIMER, + "TSF overflow for Gen timer %d\n", index); timer->overflow(timer->arg); } @@ -2458,8 +2457,8 @@ void ath_gen_timer_isr(struct ath_hw *ah) index = rightmost_index(timer_table, &trigger_mask); timer = timer_table->timers[index]; BUG_ON(!timer); - ath_print(common, ATH_DBG_HWTIMER, - "Gen timer[%d] trigger\n", index); + ath_dbg(common, ATH_DBG_HWTIMER, + "Gen timer[%d] trigger\n", index); timer->trigger(timer->arg); } } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5fcfa48a45df..ee0b1cfe9c5e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -30,7 +30,6 @@ #include "btcoex.h" #include "../regd.h" -#include "../debug.h" #define ATHEROS_VENDOR_ID 0x168c diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 2b519b387a29..5987ed1cd974 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -226,9 +226,9 @@ static void setup_ht_cap(struct ath_softc *sc, tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); - ath_print(common, ATH_DBG_CONFIG, - "TX streams %d, RX streams: %d\n", - tx_streams, rx_streams); + ath_dbg(common, ATH_DBG_CONFIG, + "TX streams %d, RX streams: %d\n", + tx_streams, rx_streams); if (tx_streams != rx_streams) { ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; @@ -271,8 +271,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct ath_buf *bf; int i, bsize, error, desc_len; - ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", - name, nbuf, ndesc); + ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", + name, nbuf, ndesc); INIT_LIST_HEAD(head); @@ -317,9 +317,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, goto fail; } ds = (u8 *) dd->dd_desc; - ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", - name, ds, (u32) dd->dd_desc_len, - ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); + ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", + name, ds, (u32) dd->dd_desc_len, + ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); /* allocate buffers */ bsize = sizeof(struct ath_buf) * nbuf; @@ -373,9 +373,9 @@ static void ath9k_init_crypto(struct ath_softc *sc) /* Get the hardware key cache size. */ common->keymax = sc->sc_ah->caps.keycache_size; if (common->keymax > ATH_KEYMAX) { - ath_print(common, ATH_DBG_ANY, - "Warning, using only %u entries in %u key cache\n", - ATH_KEYMAX, common->keymax); + ath_dbg(common, ATH_DBG_ANY, + "Warning, using only %u entries in %u key cache\n", + ATH_KEYMAX, common->keymax); common->keymax = ATH_KEYMAX; } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index b96e750d4c37..f05462ace4e8 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -20,11 +20,11 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, struct ath9k_tx_queue_info *qi) { - ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT, - "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", - ah->txok_interrupt_mask, ah->txerr_interrupt_mask, - ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, - ah->txurn_interrupt_mask); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_INTERRUPT, + "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", + ah->txok_interrupt_mask, ah->txerr_interrupt_mask, + ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, + ah->txurn_interrupt_mask); ENABLE_REGWRITE_BUFFER(ah); @@ -56,8 +56,8 @@ EXPORT_SYMBOL(ath9k_hw_puttxbuf); void ath9k_hw_txstart(struct ath_hw *ah, u32 q) { - ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE, - "Enable TXE on queue: %u\n", q); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE, + "Enable TXE on queue: %u\n", q); REG_WRITE(ah, AR_Q_TXE, 1 << q); } EXPORT_SYMBOL(ath9k_hw_txstart); @@ -154,15 +154,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; if (q >= pCap->total_queues) { - ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, " - "invalid queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Stopping TX DMA, invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, " - "inactive queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Stopping TX DMA, inactive queue: %u\n", q); return false; } @@ -175,9 +175,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) } if (ath9k_hw_numtxpending(ah, q)) { - ath_print(common, ATH_DBG_QUEUE, - "%s: Num of pending TX Frames %d on Q %d\n", - __func__, ath9k_hw_numtxpending(ah, q), q); + ath_dbg(common, ATH_DBG_QUEUE, + "%s: Num of pending TX Frames %d on Q %d\n", + __func__, ath9k_hw_numtxpending(ah, q), q); for (j = 0; j < 2; j++) { tsfLow = REG_READ(ah, AR_TSF_L32); @@ -191,9 +191,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) break; - ath_print(common, ATH_DBG_QUEUE, - "TSF has moved while trying to set " - "quiet time TSF: 0x%08x\n", tsfLow); + ath_dbg(common, ATH_DBG_QUEUE, + "TSF has moved while trying to set quiet time TSF: 0x%08x\n", + tsfLow); } REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); @@ -238,19 +238,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, " - "invalid queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Set TXQ properties, invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, " - "inactive queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Set TXQ properties, inactive queue: %u\n", q); return false; } - ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); qi->tqi_ver = qinfo->tqi_ver; qi->tqi_subtype = qinfo->tqi_subtype; @@ -309,15 +309,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, " - "invalid queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Get TXQ properties, invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, " - "inactive queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Get TXQ properties, inactive queue: %u\n", q); return false; } @@ -376,7 +376,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, return -1; } - ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); qi = &ah->txq[q]; if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { @@ -412,18 +412,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - ath_print(common, ATH_DBG_QUEUE, "Release TXQ, " - "invalid queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Release TXQ, invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_QUEUE, "Release TXQ, " - "inactive queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Release TXQ, inactive queue: %u\n", q); return false; } - ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; ah->txok_interrupt_mask &= ~(1 << q); @@ -446,19 +446,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) u32 cwMin, chanCwMin, value; if (q >= pCap->total_queues) { - ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, " - "invalid queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Reset TXQ, invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, " - "inactive queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, + "Reset TXQ, inactive queue: %u\n", q); return true; } - ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); + ath_dbg(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { if (chan && IS_CHAN_B(chan)) @@ -839,7 +839,7 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n"); REG_WRITE(ah, AR_IER, AR_IER_DISABLE); (void) REG_READ(ah, AR_IER); if (!AR_SREV_9100(ah)) { @@ -859,7 +859,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) if (!(ah->imask & ATH9K_INT_GLOBAL)) return; - ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); + ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); REG_WRITE(ah, AR_IER, AR_IER_ENABLE); if (!AR_SREV_9100(ah)) { REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, @@ -872,8 +872,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) REG_WRITE(ah, AR_INTR_SYNC_MASK, AR_INTR_SYNC_DEFAULT); } - ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", - REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); + ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", + REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); } EXPORT_SYMBOL(ath9k_hw_enable_interrupts); @@ -887,7 +887,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) if (!(ints & ATH9K_INT_GLOBAL)) ath9k_hw_enable_interrupts(ah); - ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); + ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); /* TODO: global int Ref count */ mask = ints & ATH9K_INT_COMMON; @@ -948,7 +948,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) mask2 |= AR_IMR_S2_CST; } - ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); + ath_dbg(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); REG_WRITE(ah, AR_IMR, mask); ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c7a7abfb2221..a59cfce3335a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -260,11 +260,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) caldata = &aphy->caldata; - ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", - sc->sc_ah->curchan->channel, - channel->center_freq, conf_is_ht40(conf), - fastcc); + ath_dbg(common, ATH_DBG_CONFIG, + "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", + sc->sc_ah->curchan->channel, + channel->center_freq, conf_is_ht40(conf), + fastcc); r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { @@ -387,10 +387,9 @@ void ath_paprd_calibrate(struct work_struct *work) msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); sc->paprd_pending = false; if (!time_left) { - ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "Timeout waiting for paprd training on " - "TX chain %d\n", - chain); + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "Timeout waiting for paprd training on TX chain %d\n", + chain); goto fail_paprd; } @@ -449,7 +448,7 @@ void ath_ani_calibrate(unsigned long data) /* Long calibration runs independently of short calibration. */ if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { longcal = true; - ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); + ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); common->ani.longcal_timer = timestamp; } @@ -457,8 +456,8 @@ void ath_ani_calibrate(unsigned long data) if (!common->ani.caldone) { if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { shortcal = true; - ath_print(common, ATH_DBG_ANI, - "shortcal @%lu\n", jiffies); + ath_dbg(common, ATH_DBG_ANI, + "shortcal @%lu\n", jiffies); common->ani.shortcal_timer = timestamp; common->ani.resetcal_timer = timestamp; } @@ -542,10 +541,10 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) common->rx_chainmask = 1; } - ath_print(common, ATH_DBG_CONFIG, - "tx chmask: %d, rx chmask: %d\n", - common->tx_chainmask, - common->rx_chainmask); + ath_dbg(common, ATH_DBG_CONFIG, + "tx chmask: %d, rx chmask: %d\n", + common->tx_chainmask, + common->rx_chainmask); } static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) @@ -641,8 +640,8 @@ void ath9k_tasklet(unsigned long data) * TSF sync does not look correct; remain awake to sync with * the next Beacon. */ - ath_print(common, ATH_DBG_PS, - "TSFOOR - Sync with next Beacon\n"); + ath_dbg(common, ATH_DBG_PS, + "TSFOOR - Sync with next Beacon\n"); sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; } @@ -840,9 +839,9 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ath_common *common = ath9k_hw_common(ah); if (bss_conf->assoc) { - ath_print(common, ATH_DBG_CONFIG, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); + ath_dbg(common, ATH_DBG_CONFIG, + "Bss Info ASSOC %d, bssid: %pM\n", + bss_conf->aid, common->curbssid); /* New association, store aid */ common->curaid = bss_conf->aid; @@ -865,7 +864,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); } else { - ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); common->curaid = 0; /* Stop ANI */ sc->sc_flags &= ~SC_OP_ANI_RUN; @@ -1064,9 +1063,9 @@ static int ath9k_start(struct ieee80211_hw *hw) struct ath9k_channel *init_channel; int r; - ath_print(common, ATH_DBG_CONFIG, - "Starting driver with initial channel: %d MHz\n", - curchan->center_freq); + ath_dbg(common, ATH_DBG_CONFIG, + "Starting driver with initial channel: %d MHz\n", + curchan->center_freq); mutex_lock(&sc->mutex); @@ -1196,9 +1195,9 @@ static int ath9k_tx(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { - ath_print(common, ATH_DBG_XMIT, - "ath9k: %s: TX in unexpected wiphy state " - "%d\n", wiphy_name(hw->wiphy), aphy->state); + ath_dbg(common, ATH_DBG_XMIT, + "ath9k: %s: TX in unexpected wiphy state %d\n", + wiphy_name(hw->wiphy), aphy->state); goto exit; } @@ -1210,8 +1209,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, if (ieee80211_is_data(hdr->frame_control) && !ieee80211_is_nullfunc(hdr->frame_control) && !ieee80211_has_pm(hdr->frame_control)) { - ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame " - "while in PS mode\n"); + ath_dbg(common, ATH_DBG_PS, + "Add PM=1 for a TX frame while in PS mode\n"); hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); } } @@ -1226,12 +1225,12 @@ static int ath9k_tx(struct ieee80211_hw *hw, if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) ath9k_hw_setrxabort(sc->sc_ah, 0); if (ieee80211_is_pspoll(hdr->frame_control)) { - ath_print(common, ATH_DBG_PS, - "Sending PS-Poll to pick a buffered frame\n"); + ath_dbg(common, ATH_DBG_PS, + "Sending PS-Poll to pick a buffered frame\n"); sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; } else { - ath_print(common, ATH_DBG_PS, - "Wake up to complete TX\n"); + ath_dbg(common, ATH_DBG_PS, + "Wake up to complete TX\n"); sc->ps_flags |= PS_WAIT_FOR_TX_ACK; } /* @@ -1245,10 +1244,10 @@ static int ath9k_tx(struct ieee80211_hw *hw, memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; - ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); + ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_print(common, ATH_DBG_XMIT, "TX failed\n"); + ath_dbg(common, ATH_DBG_XMIT, "TX failed\n"); goto exit; } @@ -1288,7 +1287,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) } if (sc->sc_flags & SC_OP_INVALID) { - ath_print(common, ATH_DBG_ANY, "Device not present\n"); + ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); mutex_unlock(&sc->mutex); return; } @@ -1337,7 +1336,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) mutex_unlock(&sc->mutex); - ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); } static int ath9k_add_interface(struct ieee80211_hw *hw, @@ -1376,8 +1375,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, goto out; } - ath_print(common, ATH_DBG_CONFIG, - "Attach a VIF of type: %d\n", ic_opmode); + ath_dbg(common, ATH_DBG_CONFIG, + "Attach a VIF of type: %d\n", ic_opmode); /* Set the VIF opmode */ avp->av_opmode = ic_opmode; @@ -1433,7 +1432,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, bool bs_valid = false; int i; - ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); mutex_lock(&sc->mutex); @@ -1548,8 +1547,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (enable_radio) { sc->ps_idle = false; ath_radio_enable(sc, hw); - ath_print(common, ATH_DBG_CONFIG, - "not-idle: enabling radio\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "not-idle: enabling radio\n"); } } @@ -1571,12 +1570,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { - ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is enabled\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Monitor mode is enabled\n"); sc->sc_ah->is_monitoring = true; } else { - ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is disabled\n"); + ath_dbg(common, ATH_DBG_CONFIG, + "Monitor mode is disabled\n"); sc->sc_ah->is_monitoring = false; } } @@ -1608,8 +1607,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) goto skip_chan_change; } - ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", - curchan->center_freq); + ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", + curchan->center_freq); /* XXX: remove me eventualy */ ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); @@ -1667,7 +1666,7 @@ skip_chan_change: spin_unlock_bh(&sc->wiphy_lock); if (disable_radio) { - ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); + ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); sc->ps_idle = true; ath_radio_disable(sc, hw); } @@ -1706,8 +1705,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ath9k_hw_setrxfilter(sc->sc_ah, rfilt); ath9k_ps_restore(sc); - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, - "Set HW RX filter: 0x%x\n", rfilt); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, + "Set HW RX filter: 0x%x\n", rfilt); } static int ath9k_sta_add(struct ieee80211_hw *hw, @@ -1758,11 +1757,10 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, qi.tqi_cwmax = params->cw_max; qi.tqi_burstTime = params->txop; - ath_print(common, ATH_DBG_CONFIG, - "Configure tx [queue/halq] [%d/%d], " - "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - queue, txq->axq_qnum, params->aifs, params->cw_min, - params->cw_max, params->txop); + ath_dbg(common, ATH_DBG_CONFIG, + "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + queue, txq->axq_qnum, params->aifs, params->cw_min, + params->cw_max, params->txop); ret = ath_txq_update(sc, txq->axq_qnum, &qi); if (ret) @@ -1793,7 +1791,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); - ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); switch (cmd) { case SET_KEY: @@ -1852,9 +1850,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_ADHOC) ath_update_chainmask(sc, 0); - ath_print(common, ATH_DBG_CONFIG, - "BSSID: %pM aid: 0x%x\n", - common->curbssid, common->curaid); + ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", + common->curbssid, common->curaid); /* need to reconfigure the beacon */ sc->sc_flags &= ~SC_OP_BEACONS ; @@ -1910,8 +1907,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", + bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) sc->sc_flags |= SC_OP_PREAMBLE_SHORT; else @@ -1919,8 +1916,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", + bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && hw->conf.channel->band != IEEE80211_BAND_5GHZ) sc->sc_flags |= SC_OP_PROTECT_ENABLE; @@ -1929,7 +1926,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ASSOC) { - ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); ath9k_bss_assoc_info(sc, hw, vif, bss_conf); } diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index d8dcaab18299..2061a755a026 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1184,7 +1184,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, return &ar5416_11na_ratetable; return &ar5416_11a_ratetable; default: - ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); + ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n"); return NULL; } } @@ -1259,9 +1259,9 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; ath_rc_priv->rate_table = rate_table; - ath_print(common, ATH_DBG_CONFIG, - "RC Initialized with capabilities: 0x%x\n", - ath_rc_priv->ht_cap); + ath_dbg(common, ATH_DBG_CONFIG, + "RC Initialized with capabilities: 0x%x\n", + ath_rc_priv->ht_cap); } static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, @@ -1463,9 +1463,9 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, oper_cw40, oper_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, - "Operating HT Bandwidth changed to: %d\n", - sc->hw->conf.channel_type); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, + "Operating HT Bandwidth changed to: %d\n", + sc->hw->conf.channel_type); } } } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c477be06894e..70f3fa69c9a4 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -165,7 +165,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, u32 nbuf = 0; if (list_empty(&sc->rx.rxbuf)) { - ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n"); + ath_dbg(common, ATH_DBG_QUEUE, "No free rx buf available\n"); return; } @@ -327,8 +327,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, min(common->cachelsz, (u16)64)); - ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", - common->cachelsz, common->rx_bufsize); + ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", + common->cachelsz, common->rx_bufsize); /* Initialize rx descriptors */ @@ -590,9 +590,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) if (sc->ps_flags & PS_BEACON_SYNC) { sc->ps_flags &= ~PS_BEACON_SYNC; - ath_print(common, ATH_DBG_PS, - "Reconfigure Beacon timers based on " - "timestamp from the AP\n"); + ath_dbg(common, ATH_DBG_PS, + "Reconfigure Beacon timers based on timestamp from the AP\n"); ath_beacon_config(sc, NULL); } @@ -604,8 +603,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) * a backup trigger for returning into NETWORK SLEEP state, * so we are waiting for it as well. */ - ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " - "buffered broadcast/multicast frame(s)\n"); + ath_dbg(common, ATH_DBG_PS, + "Received DTIM beacon indicating buffered broadcast/multicast frame(s)\n"); sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON; return; } @@ -617,8 +616,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) * been delivered. */ sc->ps_flags &= ~PS_WAIT_FOR_CAB; - ath_print(common, ATH_DBG_PS, - "PS wait for CAB frames timed out\n"); + ath_dbg(common, ATH_DBG_PS, + "PS wait for CAB frames timed out\n"); } } @@ -643,15 +642,14 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) * point. */ sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); - ath_print(common, ATH_DBG_PS, - "All PS CAB frames received, back to sleep\n"); + ath_dbg(common, ATH_DBG_PS, + "All PS CAB frames received, back to sleep\n"); } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && !is_multicast_ether_addr(hdr->addr1) && !ieee80211_has_morefrags(hdr->frame_control)) { sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; - ath_print(common, ATH_DBG_PS, - "Going back to sleep after having received " - "PS-Poll data (0x%lx)\n", + ath_dbg(common, ATH_DBG_PS, + "Going back to sleep after having received PS-Poll data (0x%lx)\n", sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | @@ -953,8 +951,9 @@ static int ath9k_process_rate(struct ath_common *common, * No valid hardware bitrate found -- we should not get here * because hardware has already validated this frame as OK. */ - ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " - "0x%02x using 1 Mbit\n", rx_stats->rs_rate); + ath_dbg(common, ATH_DBG_XMIT, + "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", + rx_stats->rs_rate); return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index d5442c3745cc..fbfbc8239971 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -656,10 +656,9 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) struct ath_softc *sc = aphy->sc; aphy->idle = idle; - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, - "Marking %s as %s\n", - wiphy_name(aphy->hw->wiphy), - idle ? "idle" : "not-idle"); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, + "Marking %s as %sidle\n", + wiphy_name(aphy->hw->wiphy), idle ? "" : "not-"); } /* Only bother starting a queue on an active virtual wiphy */ bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 93a8bda09c25..8f42ea78198c 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -125,7 +125,7 @@ void ath9k_wmi_tasklet(unsigned long data) struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath_common *common = ath9k_hw_common(priv->ah); - ath_print(common, ATH_DBG_WMI, "SWBA Event received\n"); + ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n"); ath9k_htc_swba(priv, priv->wmi->beacon_pending); @@ -286,9 +286,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); if (!time_left) { - ath_print(common, ATH_DBG_WMI, - "Timeout waiting for WMI command: %s\n", - wmi_cmd_to_name(cmd_id)); + ath_dbg(common, ATH_DBG_WMI, + "Timeout waiting for WMI command: %s\n", + wmi_cmd_to_name(cmd_id)); mutex_unlock(&wmi->op_mutex); return -ETIMEDOUT; } @@ -298,8 +298,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, return 0; out: - ath_print(common, ATH_DBG_WMI, - "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id)); + ath_dbg(common, ATH_DBG_WMI, + "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id)); mutex_unlock(&wmi->op_mutex); kfree_skb(skb); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d26449c91d5f..16d83d0c0959 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1285,8 +1285,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, bf = list_first_entry(head, struct ath_buf, list); - ath_print(common, ATH_DBG_QUEUE, - "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); + ath_dbg(common, ATH_DBG_QUEUE, + "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { if (txq->axq_depth >= ATH_TXFIFO_DEPTH) { @@ -1294,32 +1294,29 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, return; } if (!list_empty(&txq->txq_fifo[txq->txq_headidx])) - ath_print(common, ATH_DBG_XMIT, - "Initializing tx fifo %d which " - "is non-empty\n", - txq->txq_headidx); + ath_dbg(common, ATH_DBG_XMIT, + "Initializing tx fifo %d which is non-empty\n", + txq->txq_headidx); INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]); list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]); INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); - ath_print(common, ATH_DBG_XMIT, - "TXDP[%u] = %llx (%p)\n", - txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); + ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", + txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); } else { list_splice_tail_init(head, &txq->axq_q); if (txq->axq_link == NULL) { ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); - ath_print(common, ATH_DBG_XMIT, - "TXDP[%u] = %llx (%p)\n", - txq->axq_qnum, ito64(bf->bf_daddr), - bf->bf_desc); + ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", + txq->axq_qnum, ito64(bf->bf_daddr), + bf->bf_desc); } else { *txq->axq_link = bf->bf_daddr; - ath_print(common, ATH_DBG_XMIT, - "link[%u] (%p)=%llx (%p)\n", - txq->axq_qnum, txq->axq_link, - ito64(bf->bf_daddr), bf->bf_desc); + ath_dbg(common, ATH_DBG_XMIT, + "link[%u] (%p)=%llx (%p)\n", + txq->axq_qnum, txq->axq_link, + ito64(bf->bf_daddr), bf->bf_desc); } ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, &txq->axq_link); @@ -1646,7 +1643,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, bf = ath_tx_get_buffer(sc); if (!bf) { - ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); + ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n"); return NULL; } @@ -1809,7 +1806,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; int q, padpos, padsize; - ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); + ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); if (aphy) hw = aphy->hw; @@ -1835,9 +1832,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; - ath_print(common, ATH_DBG_PS, - "Going back to sleep after having " - "received TX status (0x%lx)\n", + ath_dbg(common, ATH_DBG_PS, + "Going back to sleep after having received TX status (0x%lx)\n", sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | @@ -1986,9 +1982,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) int status; int qnum; - ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", - txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), - txq->axq_link); + ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", + txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), + txq->axq_link); for (;;) { spin_lock_bh(&txq->axq_lock); @@ -2103,8 +2099,8 @@ static void ath_tx_complete_poll_work(struct work_struct *work) } if (needreset) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, - "tx hung, resetting the chip\n"); + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, + "tx hung, resetting the chip\n"); ath9k_ps_wakeup(sc); ath_reset(sc, true); ath9k_ps_restore(sc); @@ -2146,8 +2142,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) if (status == -EINPROGRESS) break; if (status == -EIO) { - ath_print(common, ATH_DBG_XMIT, - "Error processing tx status\n"); + ath_dbg(common, ATH_DBG_XMIT, + "Error processing tx status\n"); break; } diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h deleted file mode 100644 index cec951cdfac1..000000000000 --- a/drivers/net/wireless/ath/debug.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2008-2009 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef ATH_DEBUG_H -#define ATH_DEBUG_H - -#define ath_print ath_dbg - -#endif /* ATH_DEBUG_H */ diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 3a4769506ce3..29a2961af5fc 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -20,7 +20,6 @@ #include "ath.h" #include "reg.h" -#include "debug.h" #define REG_READ (common->ops->read) #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) @@ -125,8 +124,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, break; case ATH_CIPHER_AES_CCM: if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) { - ath_print(common, ATH_DBG_ANY, - "AES-CCM not supported by this mac rev\n"); + ath_dbg(common, ATH_DBG_ANY, + "AES-CCM not supported by this mac rev\n"); return false; } keyType = AR_KEYTABLE_TYPE_CCM; @@ -134,15 +133,15 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, case ATH_CIPHER_TKIP: keyType = AR_KEYTABLE_TYPE_TKIP; if (entry + 64 >= common->keymax) { - ath_print(common, ATH_DBG_ANY, - "entry %u inappropriate for TKIP\n", entry); + ath_dbg(common, ATH_DBG_ANY, + "entry %u inappropriate for TKIP\n", entry); return false; } break; case ATH_CIPHER_WEP: if (k->kv_len < WLAN_KEY_LEN_WEP40) { - ath_print(common, ATH_DBG_ANY, - "WEP key length %u too small\n", k->kv_len); + ath_dbg(common, ATH_DBG_ANY, + "WEP key length %u too small\n", k->kv_len); return false; } if (k->kv_len <= WLAN_KEY_LEN_WEP40) -- cgit v1.2.3-59-g8ed1b From a1cbc7a88985976267a851a2e1080578711b3b0d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 2 Dec 2010 19:12:38 -0800 Subject: ath: Fix ath_dbg access beyond array bound ar9300RateSize is not necessarily a power of 4. Change ar9003_hw_set_target_power_eeprom to print the targetPowerValT2 array one per line. ath9k_hw_ar9300_set_txpower repeated the output 4 times per line, change it to print the targetPowerValT2 value one per line. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 27 ++------------------------ 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 59236ffd5171..8c4961001b68 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4089,22 +4089,9 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, is2GHz) + ht40PowerIncForPdadc; - while (i < ar9300RateSize) { - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - + for (i = 0; i < ar9300RateSize; i++) { ath_dbg(common, ATH_DBG_EEPROM, "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); - i++; } } @@ -4692,17 +4679,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, for (i = 0; i < ar9300RateSize; i++) { ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); - i++; - ath_dbg(common, ATH_DBG_EEPROM, - "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); - i++; + "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); } /* -- cgit v1.2.3-59-g8ed1b From b7555ec7c604f2f00e432579dac29df5ce525433 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 7 Dec 2010 14:13:49 -0500 Subject: ath5k: remove MODULE_VERSION Since this is updated manually and sporadically, it is fairly useless anyway. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 950fc379c3b8..0c419b73f394 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -75,7 +75,6 @@ MODULE_AUTHOR("Nick Kossifidis"); MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); static int ath5k_init(struct ieee80211_hw *hw); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, -- cgit v1.2.3-59-g8ed1b From 3bbb780cca79dfe0200d33afb95a8990acde65b9 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:34 -0800 Subject: ath9k_hw: Define hw version macros for AR9485 AR9485 is a single chain and single band (2.4 Ghz) chip. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/reg.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index c2472edab5e0..0153ba14a2f8 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -787,6 +787,8 @@ #define AR_SREV_REVISION_9271_11 1 #define AR_SREV_VERSION_9300 0x1c0 #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ +#define AR_SREV_VERSION_9485 0x240 +#define AR_SREV_REVISION_9485_10 0 #define AR_SREV_5416(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ @@ -859,6 +861,12 @@ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) +#define AR_SREV_9485(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) +#define AR_SREV_9485_10(_ah) \ + (AR_SREV_9485(_ah) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) + #define AR_SREV_9285E_20(_ah) \ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) -- cgit v1.2.3-59-g8ed1b From d9c803e1864d563b07382eb1bb8979cd70b1001e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:35 -0800 Subject: ath9k_hw: Add initvals.h for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 943 +++++++++++++++++++++++ 1 file changed, 943 insertions(+) create mode 100644 drivers/net/wireless/ath/ath9k/ar9485_initvals.h diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h new file mode 100644 index 000000000000..70de3d89a7b5 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -0,0 +1,943 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9485_H +#define INITVALS_9485_H + +static const u32 ar9485Common_1_0[][2] = { + /* Addr allmodes */ + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; + +static const u32 ar9485_1_0_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10212e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, +}; + +static const u32 ar9485_1_0[][2] = { + /* Addr allmodes */ + {0x0000a580, 0x00000000}, + {0x0000a584, 0x00000000}, + {0x0000a588, 0x00000000}, + {0x0000a58c, 0x00000000}, + {0x0000a590, 0x00000000}, + {0x0000a594, 0x00000000}, + {0x0000a598, 0x00000000}, + {0x0000a59c, 0x00000000}, + {0x0000a5a0, 0x00000000}, + {0x0000a5a4, 0x00000000}, + {0x0000a5a8, 0x00000000}, + {0x0000a5ac, 0x00000000}, + {0x0000a5b0, 0x00000000}, + {0x0000a5b4, 0x00000000}, + {0x0000a5b8, 0x00000000}, + {0x0000a5bc, 0x00000000}, +}; + +static const u32 ar9485_1_0_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73800000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x00016048, 0x6c92426e}, + {0x0001604c, 0x000f0278}, + {0x00016050, 0x6db6db6c}, + {0x00016054, 0x6db60000}, + {0x00016080, 0x00080000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x14214514}, + {0x0001608c, 0x119f081e}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd28b3330}, + {0x000160a0, 0xc2108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92480040}, + {0x000160c0, 0x006db6db}, + {0x000160c4, 0x0186db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6fbe0}, + {0x000160d0, 0xf7dfcf3c}, + {0x00016100, 0x04cb0001}, + {0x00016104, 0xfff80015}, + {0x00016108, 0x00080010}, + {0x00016144, 0x01884080}, + {0x00016148, 0x00008040}, + {0x00016180, 0x08453333}, + {0x00016184, 0x18e82f01}, + {0x00016188, 0x00000000}, + {0x0001618c, 0x00000000}, + {0x00016240, 0x08400000}, + {0x00016244, 0x1bf90f00}, + {0x00016248, 0x00000000}, + {0x0001624c, 0x00000000}, + {0x00016280, 0x01000015}, + {0x00016284, 0x00d30000}, + {0x00016288, 0x00318000}, + {0x0001628c, 0x50000000}, + {0x00016290, 0x4b96210f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, + {0x00016c40, 0x1319c178}, + {0x00016c44, 0x10000000}, +}; + +static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, +}; + +static const u32 ar9485_1_0_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x52440bbe}, + {0x000098bc, 0x00000002}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009d1c, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x990bb515}, + {0x00009e28, 0x0a6f0000}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x80be4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a210, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d0011ce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a5c4, 0x3fad9d74}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, + {0x0000a760, 0x03020100}, + {0x0000a764, 0x09080504}, + {0x0000a768, 0x0d0c0b0a}, + {0x0000a76c, 0x13121110}, + {0x0000a770, 0x31301514}, + {0x0000a774, 0x35343332}, + {0x0000a778, 0x00000036}, + {0x0000a780, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, +}; + +static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, +}; + +static const u32 ar9485Common_rx_gain_1_0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10252e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10253e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9485_1_0_soc_preamble[][2] = { + /* Addr allmodes */ + {0x000040a4, 0x00a0c9c9}, + {0x00007048, 0x00000004}, +}; + +static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9485_1_0_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, + {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, +}; + +static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10213e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9485_1_0_radio_postamble[][2] = { + /* Addr allmodes */ + {0x0001609c, 0x0b283f31}, + {0x000160ac, 0x24611800}, + {0x000160b0, 0x03284f3e}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x10804008}, +}; + +static const u32 ar9485_1_0_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9ca00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xa248105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; +#endif -- cgit v1.2.3-59-g8ed1b From 3050c9146b2a4c98a916192fac2867c0023ec2b1 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:36 -0800 Subject: ath9k_hw: Enable hw initialization for AR9485 Also make it a supported mac Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 1 + drivers/net/wireless/ath/ath9k/hw.c | 1 + drivers/net/wireless/ath/ath9k/hw.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index c2a057156bfa..0e3e259df464 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -24,6 +24,7 @@ static bool ar9003_hw_macversion_supported(u32 macversion) { switch (macversion) { case AR_SREV_VERSION_9300: + case AR_SREV_VERSION_9485: return true; default: break; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9d3be0392a9b..2d4b3c273725 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -621,6 +621,7 @@ int ath9k_hw_init(struct ath_hw *ah) case AR9287_DEVID_PCIE: case AR2427_DEVID_PCIE: case AR9300_DEVID_PCIE: + case AR9300_DEVID_AR9485_PCIE: break; default: if (common->bus_ops->ath_bus_type == ATH_USB) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ee0b1cfe9c5e..0649ae6b33dd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -43,6 +43,7 @@ #define AR9287_DEVID_PCI 0x002d #define AR9287_DEVID_PCIE 0x002e #define AR9300_DEVID_PCIE 0x0030 +#define AR9300_DEVID_AR9485_PCIE 0x0032 #define AR5416_AR9100_DEVID 0x000b -- cgit v1.2.3-59-g8ed1b From c88457eb83fb6db7a3286a685ecc6e33a7aac49d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:37 -0800 Subject: ath9k_hw: Initialize mode registers for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 195 +++++++++++++++++++---------- 1 file changed, 129 insertions(+), 66 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 0e3e259df464..f01c2891f7c3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -17,6 +17,7 @@ #include "hw.h" #include "ar9003_mac.h" #include "ar9003_2p2_initvals.h" +#include "ar9485_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -39,72 +40,134 @@ static bool ar9003_hw_macversion_supported(u32 macversion) */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { - /* mac */ - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], - ar9300_2p2_mac_core, - ARRAY_SIZE(ar9300_2p2_mac_core), 2); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], - ar9300_2p2_mac_postamble, - ARRAY_SIZE(ar9300_2p2_mac_postamble), 5); - - /* bb */ - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], - ar9300_2p2_baseband_core, - ARRAY_SIZE(ar9300_2p2_baseband_core), 2); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], - ar9300_2p2_baseband_postamble, - ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5); - - /* radio */ - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], - ar9300_2p2_radio_core, - ARRAY_SIZE(ar9300_2p2_radio_core), 2); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], - ar9300_2p2_radio_postamble, - ARRAY_SIZE(ar9300_2p2_radio_postamble), 5); - - /* soc */ - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], - ar9300_2p2_soc_preamble, - ARRAY_SIZE(ar9300_2p2_soc_preamble), 2); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], - ar9300_2p2_soc_postamble, - ARRAY_SIZE(ar9300_2p2_soc_postamble), 5); - - /* rx/tx gain */ - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2); - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), - 5); - - /* Load PCIE SERDES settings from INI */ - - /* Awake Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, - ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), - 2); - - /* Sleep Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9300PciePhy_clkreq_enable_L1_2p2, - ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2), - 2); - - /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, - ar9300Modes_fast_clock_2p2, - ARRAY_SIZE(ar9300Modes_fast_clock_2p2), - 3); + if (AR_SREV_9485(ah)) { + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9485_1_0_mac_core, + ARRAY_SIZE(ar9485_1_0_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9485_1_0_mac_postamble, + ARRAY_SIZE(ar9485_1_0_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0, + ARRAY_SIZE(ar9485_1_0), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9485_1_0_baseband_core, + ARRAY_SIZE(ar9485_1_0_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9485_1_0_baseband_postamble, + ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9485_1_0_radio_core, + ARRAY_SIZE(ar9485_1_0_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9485_1_0_radio_postamble, + ARRAY_SIZE(ar9485_1_0_radio_postamble), 2); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9485_1_0_soc_preamble, + ARRAY_SIZE(ar9485_1_0_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_rx_gain_1_0, + ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_lowest_ob_db_tx_gain_1_0, + ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + 5); + + /* Load PCIE SERDES settings from INI */ + + /* Awake Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), + 2); + + /* Sleep Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1, + ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1), + 2); + } else { + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9300_2p2_mac_core, + ARRAY_SIZE(ar9300_2p2_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9300_2p2_mac_postamble, + ARRAY_SIZE(ar9300_2p2_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9300_2p2_baseband_core, + ARRAY_SIZE(ar9300_2p2_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9300_2p2_baseband_postamble, + ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9300_2p2_radio_core, + ARRAY_SIZE(ar9300_2p2_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9300_2p2_radio_postamble, + ARRAY_SIZE(ar9300_2p2_radio_postamble), 5); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9300_2p2_soc_preamble, + ARRAY_SIZE(ar9300_2p2_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9300_2p2_soc_postamble, + ARRAY_SIZE(ar9300_2p2_soc_postamble), 5); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); + + /* Load PCIE SERDES settings from INI */ + + /* Awake Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, + ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), + 2); + + /* Sleep Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9300PciePhy_clkreq_enable_L1_2p2, + ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2), + 2); + + /* Fast clock modal settings */ + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9300Modes_fast_clock_2p2, + ARRAY_SIZE(ar9300Modes_fast_clock_2p2), + 3); + } } static void ar9003_tx_gain_table_apply(struct ath_hw *ah) -- cgit v1.2.3-59-g8ed1b From ff48ba464e3503149657c60d46e8f4e9b4ed27fa Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:38 -0800 Subject: ath9k_hw: Initialize tx/rx gain table from initvals.h for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 82 ++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index f01c2891f7c3..21a5bfe354a0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -175,22 +175,52 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), - 5); + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_lowest_ob_db_tx_gain_1_0, + ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); break; case 1: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), - 5); + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_ob_db_tx_gain_1_0, + ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), + 5); break; case 2: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), - 5); + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_low_ob_db_tx_gain_1_0, + ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), + 5); + break; + case 3: + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_power_tx_gain_1_0, + ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_power_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2), + 5); break; } } @@ -200,16 +230,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), - 2); + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_rx_gain_1_0, + ARRAY_SIZE(ar9485Common_rx_gain_1_0), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), + 2); break; case 1: - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), - 2); + if (AR_SREV_9485(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_wo_xlna_rx_gain_1_0, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), + 2); break; } } -- cgit v1.2.3-59-g8ed1b From 60e0c3a782f9060327751492dac949210154759b Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:39 -0800 Subject: ath9k_hw: Eeeprom changes for AR9485 Calibration data are stored at 4k address (0xfff). The cal data for AR9485 is not compressed so its lengh can exceed 1024 limit, take care of that. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++++++-- drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 8c4961001b68..29b5a6d86f7e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3319,7 +3319,10 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, memcpy(mptr, &ar9300_default, mdata_size); read = ar9300_read_eeprom; - cptr = AR9300_BASE_ADDR; + if (AR_SREV_9485(ah)) + cptr = AR9300_BASE_ADDR_4K; + else + cptr = AR9300_BASE_ADDR; ath_dbg(common, ATH_DBG_EEPROM, "Trying EEPROM accesss at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) @@ -3361,7 +3364,8 @@ found: ath_dbg(common, ATH_DBG_EEPROM, "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", cptr, code, reference, length, major, minor); - if (length >= 1024) { + if ((!AR_SREV_9485(ah) && length >= 1024) || + (AR_SREV_9485(ah) && length >= (4 * 1024))) { ath_dbg(common, ATH_DBG_EEPROM, "Skipping bad header\n"); cptr -= COMP_HDR_LEN; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 9c1463307f0c..ce4d76203535 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -78,6 +78,7 @@ #define AR9300_EEPROM_SIZE (16*1024) #define FIXED_CCA_THRESHOLD 15 +#define AR9300_BASE_ADDR_4K 0xfff #define AR9300_BASE_ADDR 0x3ff #define AR9300_BASE_ADDR_512 0x1ff -- cgit v1.2.3-59-g8ed1b From 784ad50324ec531fa4ab22586fe305657cc6e307 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:40 -0800 Subject: ath9k_hw: Disable LDPC for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2d4b3c273725..66b4a2acafda 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1928,8 +1928,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) } if (AR_SREV_9300_20_OR_LATER(ah)) { - pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC | - ATH9K_HW_CAP_FASTCLOCK; + pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; + if (!AR_SREV_9485(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_LDPC; + pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; pCap->rx_status_len = sizeof(struct ar9003_rxs); -- cgit v1.2.3-59-g8ed1b From 7f1c7a6ac57ff0482219aa3f62eb9d0f8fe65867 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:41 -0800 Subject: ath9k: Disable TX STBC for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5987ed1cd974..bd451c243689 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -210,7 +210,9 @@ static void setup_ht_cap(struct ath_softc *sc, ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - if (AR_SREV_9300_20_OR_LATER(ah)) + if (AR_SREV_9485(ah)) + max_streams = 1; + else if (AR_SREV_9300_20_OR_LATER(ah)) max_streams = 3; else max_streams = 2; -- cgit v1.2.3-59-g8ed1b From 8060e169e02fe855f5533b5ef6af1f23ae2db0c4 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:42 -0800 Subject: ath9k: Enable extended synch for AR9485 to fix L0s recovery issue Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/hw.c | 5 +++++ drivers/net/wireless/ath/ath9k/hw.h | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 3 +++ drivers/net/wireless/ath/ath9k/pci.c | 12 ++++++++++++ 5 files changed, 23 insertions(+) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c914f5213c61..dd78ad13ea03 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -131,6 +131,7 @@ struct ath_bus_ops { void (*read_cachesize)(struct ath_common *common, int *csz); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); + void (*extn_synch_en)(struct ath_common *common); }; struct ath_common { diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 66b4a2acafda..49da1849c7fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1971,6 +1971,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) + if (AR_SREV_9485_10(ah)) { + pCap->pcie_lcr_extsync_en = true; + pCap->pcie_lcr_offset = 0x80; + } + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 0649ae6b33dd..76ae3296e3fc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -209,6 +209,8 @@ struct ath9k_hw_capabilities { u8 rx_status_len; u8 tx_desc_len; u8 txs_len; + u16 pcie_lcr_offset; + bool pcie_lcr_extsync_en; }; struct ath9k_ops_config { diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a59cfce3335a..3e0c8a1874b4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1179,6 +1179,9 @@ static int ath9k_start(struct ieee80211_hw *hw) pm_qos_update_request(&sc->pm_qos_req, 55); + if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) + common->bus_ops->extn_synch_en(common); + mutex_unlock: mutex_unlock(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 71339dab0860..38d2221241b8 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -103,11 +103,23 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); } +static void ath_pci_extn_synch_enable(struct ath_common *common) +{ + struct ath_softc *sc = (struct ath_softc *) common->priv; + struct pci_dev *pdev = to_pci_dev(sc->dev); + u8 lnkctl; + + pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl); + lnkctl |= PCI_EXP_LNKCTL_ES; + pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); +} + static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath_pci_read_cachesize, .eeprom_read = ath_pci_eeprom_read, .bt_coex_prep = ath_pci_bt_coex_prep, + .extn_synch_en = ath_pci_extn_synch_enable, }; static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -- cgit v1.2.3-59-g8ed1b From 47c80de62e9d6d262a829502d689a8b56add8d3d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:43 -0800 Subject: ath9k_hw: Find the maximum number of chains that hw supports Have it in ah->caps. This will be used during various calibrations. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 14 +++++++++++++- drivers/net/wireless/ath/ath9k/hw.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 49da1849c7fe..a2f85b75b7f8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1764,7 +1764,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; u16 capField = 0, eeval; - u8 ant_div_ctl1; + u8 ant_div_ctl1, tx_chainmask, rx_chainmask; eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); regulatory->current_rd = eeval; @@ -1976,6 +1976,18 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->pcie_lcr_offset = 0x80; } + tx_chainmask = pCap->tx_chainmask; + rx_chainmask = pCap->rx_chainmask; + while (tx_chainmask || rx_chainmask) { + if (tx_chainmask & BIT(0)) + pCap->max_txchains++; + if (rx_chainmask & BIT(0)) + pCap->max_rxchains++; + + tx_chainmask >>= 1; + rx_chainmask >>= 1; + } + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 76ae3296e3fc..fcfd63efe55a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -199,6 +199,8 @@ struct ath9k_hw_capabilities { u16 rts_aggr_limit; u8 tx_chainmask; u8 rx_chainmask; + u8 max_txchains; + u8 max_rxchains; u16 tx_triglevel_max; u16 reg_cap; u8 num_gpio_pins; -- cgit v1.2.3-59-g8ed1b From d09b17f73fd8f475f33d0b8311d7b5a0bed67c67 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:44 -0800 Subject: ath9k: Configure pll control for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 ++++++- drivers/net/wireless/ath/ath9k/reg.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a2f85b75b7f8..9f4398c88c85 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -667,7 +667,12 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) static void ath9k_hw_init_pll(struct ath_hw *ah, struct ath9k_channel *chan) { - u32 pll = ath9k_hw_compute_pll_control(ah, chan); + u32 pll; + + if (AR_SREV_9485(ah)) + REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); + + pll = ath9k_hw_compute_pll_control(ah, chan); REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 0153ba14a2f8..d3257f783a64 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1114,6 +1114,8 @@ enum { #define AR_RTC_PLL_CONTROL \ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) +#define AR_RTC_PLL_CONTROL2 0x703c + #define AR_RTC_PLL_DIV 0x0000001f #define AR_RTC_PLL_DIV_S 0 #define AR_RTC_PLL_DIV2 0x00000020 -- cgit v1.2.3-59-g8ed1b From 85dd0921e686ed2f0283cef358a91ecaa36ccc8f Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:45 -0800 Subject: ath9k_hw: Find chansel of AR_PHY_65NM_CH0_SYNTH7 for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 ++++- drivers/net/wireless/ath/ath9k/phy.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 63b6d560c7f0..bce1fdb1660a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -75,7 +75,10 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) freq = centers.synth_center; if (freq < 4800) { /* 2 GHz, fractional mode */ - channelSel = CHANSEL_2G(freq); + if (AR_SREV_9485(ah)) + channelSel = CHANSEL_2G_9485(freq); + else + channelSel = CHANSEL_2G(freq); /* Set to 2G mode */ bMode = 1; } else { diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 17969af842f6..5e3d7496986e 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -19,6 +19,7 @@ #define CHANSEL_DIV 15 #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) +#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV) #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) #define AR_PHY_BASE 0x9800 -- cgit v1.2.3-59-g8ed1b From 272ceba892208013a45847276a00ccae54e2b94a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:46 -0800 Subject: ath9k_hw: Add a helper function to get spur channel pointer from cal data for AR9003 family This helper function would be used for AR9485. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 10 ++++++++++ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 29b5a6d86f7e..372831dc94bd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4731,6 +4731,16 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ } +u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + + if (is_2ghz) + return eep->modalHeader2G.spurChans; + else + return eep->modalHeader5G.spurChans; +} + const struct eeprom_ops eep_ar9300_ops = { .check_eeprom = ath9k_hw_ar9300_check_eeprom, .get_eeprom = ath9k_hw_ar9300_get_eeprom, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index ce4d76203535..33503217dab3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -343,4 +343,5 @@ struct ar9300_eeprom { s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah); s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); +u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); #endif -- cgit v1.2.3-59-g8ed1b From d9a2545ac713e26ab8c8eee741d2da1626cebd6e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:47 -0800 Subject: ath9k: Read spur channel information from eeprom for AR9485 Also spur channel count and range is different for AR9485. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 35 ++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index bce1fdb1660a..da4a571304da 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -134,21 +134,50 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, static const u32 spur_freq[4] = { 2420, 2440, 2464, 2480 }; int cur_bb_spur, negative = 0, cck_spur_freq; int i; + int range, max_spur_cnts, synth_freq; + u8 *spur_fbin_ptr = NULL; /* * Need to verify range +/- 10 MHz in control channel, otherwise spur * is out-of-band and can be ignored. */ - for (i = 0; i < 4; i++) { + if (AR_SREV_9485(ah)) { + spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, + IS_CHAN_2GHZ(chan)); + if (spur_fbin_ptr[0] == 0) /* No spur */ + return; + max_spur_cnts = 5; + if (IS_CHAN_HT40(chan)) { + range = 19; + if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, + AR_PHY_GC_DYN2040_PRI_CH) == 0) + synth_freq = chan->channel + 10; + else + synth_freq = chan->channel - 10; + } else { + range = 10; + synth_freq = chan->channel; + } + } else { + range = 10; + max_spur_cnts = 4; + synth_freq = chan->channel; + } + + for (i = 0; i < max_spur_cnts; i++) { negative = 0; - cur_bb_spur = spur_freq[i] - chan->channel; + if (AR_SREV_9485(ah)) + cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], + IS_CHAN_2GHZ(chan)) - synth_freq; + else + cur_bb_spur = spur_freq[i] - synth_freq; if (cur_bb_spur < 0) { negative = 1; cur_bb_spur = -cur_bb_spur; } - if (cur_bb_spur < 10) { + if (cur_bb_spur < range) { cck_spur_freq = (int)((cur_bb_spur << 19) / 11); if (negative == 1) -- cgit v1.2.3-59-g8ed1b From 9936e65fae6d95c2acc2438c60a8f4908130530e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:48 -0800 Subject: ath9k_hw: Configure xpa bias level for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 12 +++++++++--- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 372831dc94bd..819b0a6cb83e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3450,9 +3450,15 @@ static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) { int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); - REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); - REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2); - REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); + + if (AR_SREV_9485(ah)) + REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); + else { + REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); + REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, + bias >> 2); + REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); + } } static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 3394dfe52b42..b7720819872b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -584,6 +584,10 @@ #define AR_PHY_65NM_CH2_RXTX1 0x16900 #define AR_PHY_65NM_CH2_RXTX2 0x16904 +#define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c) +#define AR_CH0_TOP2_XPABIASLVL 0xf000 +#define AR_CH0_TOP2_XPABIASLVL_S 12 + #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000 #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19 #define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000 -- cgit v1.2.3-59-g8ed1b From 47e84dfb411fcaa51e12d94ab82570ec3aa86e32 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:49 -0800 Subject: ath9k_hw: Read and configure antenna diversity control for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 24 ++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 10 ++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 819b0a6cb83e..45fe5c2ec3b9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3034,6 +3034,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, return !!(pBase->featureEnable & BIT(5)); case EEP_CHAIN_MASK_REDUCE: return (pBase->miscConfiguration >> 0x3) & 0x1; + case EEP_ANT_DIV_CTL1: + return le32_to_cpu(eep->base_ext1.ant_div_control); default: return 0; } @@ -3513,11 +3515,25 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); - value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); - REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); + if (!AR_SREV_9485(ah)) { + value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); + REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, + value); - value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); - REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); + value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); + REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, + value); + } + + if (AR_SREV_9485(ah)) { + value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); + REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL, + value); + REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE, + value >> 6); + REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE, + value >> 7); + } } static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index b7720819872b..6e0d4adc1a6b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -260,7 +260,13 @@ #define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c) #define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) #define AR_PHY_RESTART (AR_AGC_BASE + 0x24) + #define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28) +#define AR_ANT_DIV_CTRL_ALL 0x7e000000 +#define AR_ANT_DIV_CTRL_ALL_S 25 +#define AR_ANT_DIV_ENABLE 0x1000000 +#define AR_ANT_DIV_ENABLE_S 24 + #define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) #define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) #define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) @@ -271,7 +277,11 @@ #define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48) #define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180) #define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184) + #define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0) +#define AR_FAST_DIV_ENABLE 0x2000 +#define AR_FAST_DIV_ENABLE_S 13 + #define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4) #define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8) -- cgit v1.2.3-59-g8ed1b From ab09b5b4beda8b33a117bf6fbbb2b5aa8f566129 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 7 Dec 2010 02:20:39 -0800 Subject: ath9k_hw: Configure internal regulator for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 89 +++++++++++++++++++++----- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 8 +++ 2 files changed, 82 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 45fe5c2ec3b9..c02e43d5c9c9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3653,29 +3653,88 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) } } +static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) +{ + int timeout = 100; + + while (pmu_set != REG_READ(ah, pmu_reg)) { + if (timeout-- == 0) + return false; + REG_WRITE(ah, pmu_reg, pmu_set); + udelay(10); + } + + return true; +} + static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); if (internal_regulator) { - /* Internal regulator is ON. Write swreg register. */ - int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); - REG_WRITE(ah, AR_RTC_REG_CONTROL1, - REG_READ(ah, AR_RTC_REG_CONTROL1) & - (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); - REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); - /* Set REG_CONTROL1.SWREG_PROGRAM */ - REG_WRITE(ah, AR_RTC_REG_CONTROL1, - REG_READ(ah, - AR_RTC_REG_CONTROL1) | - AR_RTC_REG_CONTROL1_SWREG_PROGRAM); + if (AR_SREV_9485(ah)) { + int reg_pmu_set; + + reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM; + REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); + if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) + return; + + reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | + (7 << 14) | (6 << 17) | (1 << 20) | + (3 << 24) | (1 << 28); + + REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); + if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set)) + return; + + reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000) + | (4 << 26); + REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); + if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) + return; + + reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000) + | (1 << 21); + REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); + if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) + return; + } else { + /* Internal regulator is ON. Write swreg register. */ + int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); + REG_WRITE(ah, AR_RTC_REG_CONTROL1, + REG_READ(ah, AR_RTC_REG_CONTROL1) & + (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); + REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); + /* Set REG_CONTROL1.SWREG_PROGRAM */ + REG_WRITE(ah, AR_RTC_REG_CONTROL1, + REG_READ(ah, + AR_RTC_REG_CONTROL1) | + AR_RTC_REG_CONTROL1_SWREG_PROGRAM); + } } else { - REG_WRITE(ah, AR_RTC_SLEEP_CLK, - (REG_READ(ah, - AR_RTC_SLEEP_CLK) | - AR_RTC_FORCE_SWREG_PRD)); + if (AR_SREV_9485(ah)) { + REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0); + while (REG_READ_FIELD(ah, AR_PHY_PMU2, + AR_PHY_PMU2_PGM)) + udelay(10); + + REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1); + while (!REG_READ_FIELD(ah, AR_PHY_PMU1, + AR_PHY_PMU1_PWD)) + udelay(10); + REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1); + while (!REG_READ_FIELD(ah, AR_PHY_PMU2, + AR_PHY_PMU2_PGM)) + udelay(10); + } else + REG_WRITE(ah, AR_RTC_SLEEP_CLK, + (REG_READ(ah, + AR_RTC_SLEEP_CLK) | + AR_RTC_FORCE_SWREG_PRD)); } + } static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 6e0d4adc1a6b..8de3ffd5a92b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -598,6 +598,14 @@ #define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL_S 12 +#define AR_PHY_PMU1 0x16c40 +#define AR_PHY_PMU1_PWD 0x1 +#define AR_PHY_PMU1_PWD_S 0 + +#define AR_PHY_PMU2 0x16c44 +#define AR_PHY_PMU2_PGM 0x00200000 +#define AR_PHY_PMU2_PGM_S 21 + #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000 #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19 #define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000 -- cgit v1.2.3-59-g8ed1b From dd040f76cef0cc977b83e905a16b68d41322b735 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:52 -0800 Subject: ath9k_hw: Read and configure turnning caps to regulate freq accuracy Right now it is done for only AR9485, will be done for ar9003 also after proper testing. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_phy.h | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c02e43d5c9c9..76508f82f859 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3737,6 +3737,20 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) } +static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; + + if (eep->baseEepHeader.featureEnable & 0x40) { + tuning_caps_param &= 0x7f; + REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC, + tuning_caps_param); + REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC, + tuning_caps_param); + } +} + static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -3745,6 +3759,8 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ar9003_hw_drive_strength_apply(ah); ar9003_hw_atten_apply(ah, chan); ar9003_hw_internal_regulator_apply(ah); + if (AR_SREV_9485(ah)) + ar9003_hw_apply_tuning_caps(ah); } static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 8de3ffd5a92b..4c64eb1888a2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -598,6 +598,12 @@ #define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL_S 12 +#define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294) +#define AR_CH0_XTAL_CAPINDAC 0x7f000000 +#define AR_CH0_XTAL_CAPINDAC_S 24 +#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 +#define AR_CH0_XTAL_CAPOUTDAC_S 17 + #define AR_PHY_PMU1 0x16c40 #define AR_PHY_PMU1_PWD 0x1 #define AR_PHY_PMU1_PWD_S 0 -- cgit v1.2.3-59-g8ed1b From 5f139eba4174d9a3343efc7cfb8a0a9cb184c647 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:53 -0800 Subject: ath9k_hw: Configure power control only for the supported chains Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 76508f82f859..1f5aa51b9cef 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4260,23 +4260,27 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, REG_RMW(ah, AR_PHY_TPC_11_B0, (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), AR_PHY_TPC_OLPC_GAIN_DELTA); - REG_RMW(ah, AR_PHY_TPC_11_B1, - (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), - AR_PHY_TPC_OLPC_GAIN_DELTA); - REG_RMW(ah, AR_PHY_TPC_11_B2, - (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), - AR_PHY_TPC_OLPC_GAIN_DELTA); + if (ah->caps.tx_chainmask & BIT(1)) + REG_RMW(ah, AR_PHY_TPC_11_B1, + (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), + AR_PHY_TPC_OLPC_GAIN_DELTA); + if (ah->caps.tx_chainmask & BIT(2)) + REG_RMW(ah, AR_PHY_TPC_11_B2, + (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), + AR_PHY_TPC_OLPC_GAIN_DELTA); /* enable open loop power control on chip */ REG_RMW(ah, AR_PHY_TPC_6_B0, (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE); - REG_RMW(ah, AR_PHY_TPC_6_B1, - (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), - AR_PHY_TPC_6_ERROR_EST_MODE); - REG_RMW(ah, AR_PHY_TPC_6_B2, - (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), - AR_PHY_TPC_6_ERROR_EST_MODE); + if (ah->caps.tx_chainmask & BIT(1)) + REG_RMW(ah, AR_PHY_TPC_6_B1, + (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), + AR_PHY_TPC_6_ERROR_EST_MODE); + if (ah->caps.tx_chainmask & BIT(2)) + REG_RMW(ah, AR_PHY_TPC_6_B2, + (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), + AR_PHY_TPC_6_ERROR_EST_MODE); /* * enable temperature compensation -- cgit v1.2.3-59-g8ed1b From 6559e83ebd2cac06c54ebb2b7f635cf2e434f25c Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:54 -0800 Subject: ath9k_hw: Program appropriate chianmask for AR9485 before starting AGC/IQ cal Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 16d20294c33c..33a80b24538c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -721,7 +721,9 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, val = REG_READ(ah, AR_ENT_OTP); ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); - if (val & AR_ENT_OTP_CHAIN2_DISABLE) + if (AR_SREV_9485(ah)) + ar9003_hw_set_chain_masks(ah, 0x1, 0x1); + else if (val & AR_ENT_OTP_CHAIN2_DISABLE) ar9003_hw_set_chain_masks(ah, 0x3, 0x3); else /* -- cgit v1.2.3-59-g8ed1b From 31faff815bd9d87c370f799dff03948ed362d260 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:55 -0800 Subject: ath9k_hw: Define IQcal correction coefficient registers using index Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 10 +++++----- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 33a80b24538c..e8f7df8c8626 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -606,11 +606,6 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) AR_PHY_TX_IQCAL_STATUS_B1, AR_PHY_TX_IQCAL_STATUS_B2, }; - static const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = { - AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, - AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, - AR_PHY_TX_IQCAL_CORR_COEFF_01_B2, - }; static const u32 rx_corr[AR9300_MAX_CHAINS] = { AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_B1, @@ -621,11 +616,16 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) AR_PHY_CHAN_INFO_TAB_1, AR_PHY_CHAN_INFO_TAB_2, }; + u32 tx_corr_coeff[AR9300_MAX_CHAINS]; s32 iq_res[6]; s32 iqc_coeff[2]; s32 i, j; u32 num_chains = 0; + tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0); + tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0); + tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0); + for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (ah->txchainmask & (1 << i)) num_chains++; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 4c64eb1888a2..abb4ec172ed1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -549,7 +549,9 @@ #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ + (AR_SREV_9485(ah) ? \ + 0x3d0 : 0x450) + ((_i) << 2)) #define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0) #define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4) @@ -813,7 +815,7 @@ #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) /* * Channel 2 Register Map @@ -866,7 +868,7 @@ #define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) #define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240) #define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2)) #define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001 -- cgit v1.2.3-59-g8ed1b From 858b7e36e82cc03cb77b64f096b64446a24a346a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:56 -0800 Subject: ath9k_hw: Add IQ cal changes for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 242 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 16 +- 2 files changed, 255 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index e8f7df8c8626..7c3334bd396e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -18,6 +18,16 @@ #include "hw-ops.h" #include "ar9003_phy.h" +#define MPASS 3 +#define MAX_MEASUREMENT 8 +#define MAX_DIFFERENCE 10 + +struct coeff { + int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; + int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; + int iqc_coeff[2]; +}; + enum ar9003_cal_types { IQ_MISMATCH_CAL = BIT(0), TEMP_COMP_CAL = BIT(1), @@ -712,6 +722,229 @@ TX_IQ_CAL_FAILED: ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); } +static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) +{ + int diff[MPASS]; + + diff[0] = abs(mp_coeff[0] - mp_coeff[1]); + diff[1] = abs(mp_coeff[1] - mp_coeff[2]); + diff[2] = abs(mp_coeff[2] - mp_coeff[0]); + + if (diff[0] > MAX_MEASUREMENT && + diff[1] > MAX_MEASUREMENT && + diff[2] > MAX_MEASUREMENT) + return false; + + if (diff[0] <= diff[1] && diff[0] <= diff[2]) + *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2; + else if (diff[1] <= diff[2]) + *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2; + else + *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2; + + return true; +} + +static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, + u8 num_chains, + struct coeff *coeff) +{ + struct ath_common *common = ath9k_hw_common(ah); + int i, im, nmeasurement; + int magnitude, phase; + u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; + + memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); + for (i = 0; i < MAX_MEASUREMENT / 2; i++) { + tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] = + AR_PHY_TX_IQCAL_CORR_COEFF_B0(i); + if (!AR_SREV_9485(ah)) { + tx_corr_coeff[i * 2][1] = + tx_corr_coeff[(i * 2) + 1][1] = + AR_PHY_TX_IQCAL_CORR_COEFF_B1(i); + + tx_corr_coeff[i * 2][2] = + tx_corr_coeff[(i * 2) + 1][2] = + AR_PHY_TX_IQCAL_CORR_COEFF_B2(i); + } + } + + /* Load the average of 2 passes */ + for (i = 0; i < num_chains; i++) { + if (AR_SREV_9485(ah)) + nmeasurement = REG_READ_FIELD(ah, + AR_PHY_TX_IQCAL_STATUS_B0_9485, + AR_PHY_CALIBRATED_GAINS_0); + else + nmeasurement = REG_READ_FIELD(ah, + AR_PHY_TX_IQCAL_STATUS_B0, + AR_PHY_CALIBRATED_GAINS_0); + + if (nmeasurement > MAX_MEASUREMENT) + nmeasurement = MAX_MEASUREMENT; + + for (im = 0; im < nmeasurement; im++) { + /* + * Determine which 2 passes are closest and compute avg + * magnitude + */ + if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im], + &magnitude)) + goto disable_txiqcal; + + /* + * Determine which 2 passes are closest and compute avg + * phase + */ + if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im], + &phase)) + goto disable_txiqcal; + + coeff->iqc_coeff[0] = (magnitude & 0x7f) | + ((phase & 0x7f) << 7); + + if ((im % 2) == 0) + REG_RMW_FIELD(ah, tx_corr_coeff[im][i], + AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, + coeff->iqc_coeff[0]); + else + REG_RMW_FIELD(ah, tx_corr_coeff[im][i], + AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, + coeff->iqc_coeff[0]); + } + } + + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, + AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); + REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, + AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); + + return; + +disable_txiqcal: + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, + AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0); + REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, + AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0); + + ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); +} + +static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) +{ + u8 tx_gain_forced; + + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485, + AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT); + tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TXGAIN_FORCE); + if (tx_gain_forced) + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TXGAIN_FORCE, 0); + + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485, + AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1); +} + +static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + const u32 txiqcal_status[AR9300_MAX_CHAINS] = { + AR_PHY_TX_IQCAL_STATUS_B0_9485, + AR_PHY_TX_IQCAL_STATUS_B1, + AR_PHY_TX_IQCAL_STATUS_B2, + }; + const u_int32_t chan_info_tab[] = { + AR_PHY_CHAN_INFO_TAB_0, + AR_PHY_CHAN_INFO_TAB_1, + AR_PHY_CHAN_INFO_TAB_2, + }; + struct coeff coeff; + s32 iq_res[6]; + u8 num_chains = 0; + int i, ip, im, j; + int nmeasurement; + + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (ah->txchainmask & (1 << i)) + num_chains++; + } + + for (ip = 0; ip < MPASS; ip++) { + for (i = 0; i < num_chains; i++) { + nmeasurement = REG_READ_FIELD(ah, + AR_PHY_TX_IQCAL_STATUS_B0_9485, + AR_PHY_CALIBRATED_GAINS_0); + if (nmeasurement > MAX_MEASUREMENT) + nmeasurement = MAX_MEASUREMENT; + + for (im = 0; im < nmeasurement; im++) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Doing Tx IQ Cal for chain %d.\n", i); + + if (REG_READ(ah, txiqcal_status[i]) & + AR_PHY_TX_IQCAL_STATUS_FAILED) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Tx IQ Cal failed for chain %d.\n", i); + goto tx_iqcal_fail; + } + + for (j = 0; j < 3; j++) { + u32 idx = 2 * j, offset = 4 * (3 * im + j); + + REG_RMW_FIELD(ah, + AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_TAB_S2_READ, + 0); + + /* 32 bits */ + iq_res[idx] = REG_READ(ah, + chan_info_tab[i] + + offset); + + REG_RMW_FIELD(ah, + AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_TAB_S2_READ, + 1); + + /* 16 bits */ + iq_res[idx + 1] = 0xffff & REG_READ(ah, + chan_info_tab[i] + offset); + + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ RES[%d]=0x%x" + "IQ_RES[%d]=0x%x\n", + idx, iq_res[idx], idx + 1, + iq_res[idx + 1]); + } + + if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, + coeff.iqc_coeff)) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Failed in calculation of IQ correction.\n"); + goto tx_iqcal_fail; + } + + coeff.mag_coeff[i][im][ip] = + coeff.iqc_coeff[0] & 0x7f; + coeff.phs_coeff[i][im][ip] = + (coeff.iqc_coeff[0] >> 7) & 0x7f; + + if (coeff.mag_coeff[i][im][ip] > 63) + coeff.mag_coeff[i][im][ip] -= 128; + if (coeff.phs_coeff[i][im][ip] > 63) + coeff.phs_coeff[i][im][ip] -= 128; + } + } + } + ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); + + return; + +tx_iqcal_fail: + ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); + return; +} static bool ar9003_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -733,7 +966,11 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ar9003_hw_set_chain_masks(ah, 0x7, 0x7); /* Do Tx IQ Calibration */ - ar9003_hw_tx_iq_cal(ah); + if (AR_SREV_9485(ah)) + ar9003_hw_tx_iq_cal_run(ah); + else + ar9003_hw_tx_iq_cal(ah); + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); udelay(5); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); @@ -751,6 +988,9 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, return false; } + if (AR_SREV_9485(ah)) + ar9003_hw_tx_iq_cal_post_proc(ah); + /* Revert chainmasks to their original values before NF cal */ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index abb4ec172ed1..74e0da971439 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -546,6 +546,12 @@ #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) +#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4) +#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000 +#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31 +#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8) +#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0) + #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) @@ -713,6 +719,7 @@ #define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1 #define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001 #define AR_PHY_TXGAIN_FORCE 0x00000001 +#define AR_PHY_TXGAIN_FORCE_S 0 #define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00 #define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10 #define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000 @@ -755,8 +762,13 @@ #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 -#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff -#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 +#define AR_PHY_CALIBRATED_GAINS_0 0x3e +#define AR_PHY_CALIBRATED_GAINS_0_S 1 + +#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE 0x00003fff +#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE_S 0 +#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x0fffc000 +#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 14 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 -- cgit v1.2.3-59-g8ed1b From 7090ad1416d0311677c43728494c6028aa2436b6 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:57 -0800 Subject: ath9k_hw: Program appropriate register for temperature compensation cal for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 74e0da971439..00cd3e52ce52 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -586,7 +586,7 @@ #define AR_PHY_65NM_CH0_BIAS2 0x160c4 #define AR_PHY_65NM_CH0_BIAS4 0x160cc #define AR_PHY_65NM_CH0_RXTX4 0x1610c -#define AR_PHY_65NM_CH0_THERM 0x16290 +#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290) #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 -- cgit v1.2.3-59-g8ed1b From 11441fb8b700bd782ae72d3dd87453fc5bc2ff12 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:58 -0800 Subject: ath9k_hw: Setup paprd only for supported chains Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 37 +++++++++++++++++---------- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 16 +++++++++--- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 850bc9866c19..74cff4365c43 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -21,10 +21,12 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) { REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, - AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, - AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); + if (ah->caps.tx_chainmask & BIT(1)) + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); + if (ah->caps.tx_chainmask & BIT(2)) + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); } EXPORT_SYMBOL(ar9003_paprd_enable); @@ -57,7 +59,8 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); - for (i = 0; i < 3; i++) { + + for (i = 0; i < ah->caps.max_txchains; i++) { REG_RMW_FIELD(ah, ctrl0[i], AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); REG_RMW_FIELD(ah, ctrl1[i], @@ -102,8 +105,14 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, - AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); + if (AR_SREV_9485(ah)) + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, + -3); + else + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, + -6); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15); @@ -620,13 +629,15 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah, AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, training_power); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1, - AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, - training_power); + if (ah->caps.tx_chainmask & BIT(1)) + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1, + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, + training_power); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, - AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, - training_power); + if (ah->caps.tx_chainmask & BIT(2)) + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, + training_power); } EXPORT_SYMBOL(ar9003_paprd_populate_single_table); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 00cd3e52ce52..6f811c7ada05 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -987,7 +987,9 @@ #define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000 #define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17 -#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490) +#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + \ + (AR_SREV_9485(ah) ? \ + 0x580 : 0x490)) #define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001 #define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0 #define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e @@ -1003,11 +1005,15 @@ #define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000 #define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12 -#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494) +#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + \ + (AR_SREV_9485(ah) ? \ + 0x584 : 0x494)) #define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF #define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0 -#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498) +#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + \ + (AR_SREV_9485(ah) ? \ + 0x588 : 0x498)) #define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f #define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0 #define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0 @@ -1023,7 +1029,9 @@ #define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000 #define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29 -#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c) +#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + \ + (AR_SREV_9485(ah) ? \ + 0x58c : 0x49c)) #define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000 #define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16 #define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000 -- cgit v1.2.3-59-g8ed1b From a95f1600081211433c5ff6f3668061c821552e9f Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:27:59 -0800 Subject: ath9k_hw: Disable MRC CCK for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index e2ffac3d4d8e..2e31c775351f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -358,7 +358,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) entry_cck->fir_step_level); /* Skip MRC CCK for pre AR9003 families */ - if (!AR_SREV_9300_20_OR_LATER(ah)) + if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah)) return; if (aniState->mrcCCKOff == entry_cck->mrc_cck_on) -- cgit v1.2.3-59-g8ed1b From 1435894dcd263fdbdd5e1ea2a684289dff187c34 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Dec 2010 04:28:00 -0800 Subject: ath9k: Add device id of AR9485 to pci table Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 38d2221241b8..747b2871e48f 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -30,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ + { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ { 0 } }; -- cgit v1.2.3-59-g8ed1b From d7fd1b50a51be3fe6554fbab8953fa8a3ff4009b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 6 Dec 2010 13:13:07 -0800 Subject: ath9k: Make DMA warning in ath_stoprecv WARN_ON_ONCE. This decreases spammage in the log. A single line message will still be printed, so users can be aware that problem exists. Signed-off-by: Ben Greear Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 ++ drivers/net/wireless/ath/ath9k/recv.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index dd78ad13ea03..272dfef25453 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -267,6 +267,7 @@ enum ATH_DEBUG { rtn; \ }) #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) +#define ATH_DBG_WARN_ON_ONCE(foo) WARN_ON_ONCE(foo) #else @@ -277,6 +278,7 @@ ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, return 0; } #define ATH_DBG_WARN(foo, arg...) do {} while (0) +#define ATH_DBG_WARN_ON_ONCE(foo) do {} while (0) #endif /* CONFIG_ATH_DEBUG */ diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 70f3fa69c9a4..3f8b2e32f364 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -528,8 +528,12 @@ bool ath_stoprecv(struct ath_softc *sc) sc->rx.rxlink = NULL; spin_unlock_bh(&sc->rx.rxbuflock); - ATH_DBG_WARN(!stopped, "Could not stop RX, we could be " - "confusing the DMA engine when we start RX up\n"); + if (unlikely(!stopped)) { + ath_err(ath9k_hw_common(sc->sc_ah), + "Could not stop RX, we could be " + "confusing the DMA engine when we start RX up\n"); + ATH_DBG_WARN_ON_ONCE(!stopped); + } return stopped; } -- cgit v1.2.3-59-g8ed1b From 22d8d9f81b8b054df2f7f82daffcb71608f411e4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 7 Dec 2010 11:08:12 +0900 Subject: ath5k: Use capabilities information for the number of TX queues One thing I missed in my WME series: Older hardware does not have enough hardware queues to support WME. In this case we just set up one data queue. Use the capability information to decide how many queues to set up. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 65 +++++++++++++++++++++-------------- drivers/net/wireless/ath/ath5k/qcu.c | 4 +-- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0c419b73f394..bccea7450c38 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2797,33 +2797,46 @@ ath5k_init(struct ieee80211_hw *hw) goto err_bhal; } - /* This order matches mac80211's queue priority, so we can - * directly use the mac80211 queue number without any mapping */ - txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); - if (IS_ERR(txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); - if (IS_ERR(txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); - if (IS_ERR(txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); - if (IS_ERR(txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; + /* 5211 and 5212 usually support 10 queues but we better rely on the + * capability information */ + if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) { + /* This order matches mac80211's queue priority, so we can + * directly use the mac80211 queue number without any mapping */ + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + hw->queues = 4; + } else { + /* older hardware (5210) can only support one data queue */ + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + hw->queues = 1; } - hw->queues = 4; tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 1849eee8235c..2c9c9e793d4e 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -152,8 +152,8 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, /* * Get queue by type */ - /*5210 only has 2 queues*/ - if (ah->ah_version == AR5K_AR5210) { + /* 5210 only has 2 queues */ + if (ah->ah_capabilities.cap_queues.q_tx_num == 2) { switch (queue_type) { case AR5K_TX_QUEUE_DATA: queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; -- cgit v1.2.3-59-g8ed1b From c658e5db01117bf2a321a9a782754dd5b10e2f15 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 7 Dec 2010 04:40:18 +0100 Subject: mac80211: fix a compiler warning net/mac80211/mlme.c: In function 'ieee80211_sta_work': net/mac80211/mlme.c:1981: warning: too many arguments for format Introduced by commit 04ac3c0ee2c773c321ec472d892635a20556f34d ("mac80211: speed up AP probing using nullfunc frames"). Reported-by: Stephen Rothwell Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 59e2e06aa4e9..45fbb9e33746 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1982,8 +1982,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) wiphy_debug(local->hw.wiphy, "%s: No ack for nullfunc frame to" " AP %pM, disconnecting.\n", - sdata->name, bssid, - ifmgd->probe_send_count); + sdata->name, bssid); #endif ieee80211_sta_connection_lost(sdata, bssid); } -- cgit v1.2.3-59-g8ed1b From 0b5ead91cda63e0db964dadc77601233434f60cb Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 7 Dec 2010 16:31:38 +0530 Subject: ath9k_htc: Cleanup device identification ath.ko is a common module shared between ath5k, ar9170usb, ath9k and ath9k_htc. Adding driver specific data to the shared structure would impact all the drivers. Handling USB device recognition for devices specific to ath9k_htc can be handled within the driver itself. Also, AR7010 refers to the processor used in both AR9280/AR9287 based devices. Rename the device enumerations accordingly. While at it, check properly for the bus type when choosing the EEPROM base address for UB95. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 6 ----- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 ++--- drivers/net/wireless/ath/ath9k/hif_usb.c | 32 +++++++++++++-------------- drivers/net/wireless/ath/ath9k/hif_usb.h | 2 ++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 ++--- drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/reg.h | 8 ++++++- 7 files changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 272dfef25453..3eb95e268f03 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -104,11 +104,6 @@ enum ath_cipher { ATH_CIPHER_MIC = 127 }; -enum ath_drv_info { - AR7010_DEVICE = BIT(0), - AR9287_DEVICE = BIT(1), -}; - /** * struct ath_ops - Register read/write operations * @@ -153,7 +148,6 @@ struct ath_common { u8 rx_chainmask; u32 rx_bufsize; - u32 driver_info; u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 9ec4bc80f758..065402f2e402 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -37,10 +37,10 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) int addr, eep_start_loc; eep_data = (u16 *)eep; - if (!common->driver_info) - eep_start_loc = AR9287_EEP_START_LOC; - else + if (common->bus_ops->ath_bus_type == ATH_USB) eep_start_loc = AR9287_HTC_EEP_START_LOC; + else + eep_start_loc = AR9287_EEP_START_LOC; if (!ath9k_hw_use_flash(ah)) { ath_dbg(common, ATH_DBG_EEPROM, diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 8946e8ad1b85..cc1e5b3444a4 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -28,16 +28,7 @@ MODULE_FIRMWARE(FIRMWARE_AR9271); static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */ - { USB_DEVICE(0x0cf3, 0x7010), - .driver_info = AR7010_DEVICE }, - /* Atheros */ - { USB_DEVICE(0x0cf3, 0x7015), - .driver_info = AR7010_DEVICE | AR9287_DEVICE }, - /* Atheros */ { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */ - { USB_DEVICE(0x0846, 0x9018), - .driver_info = AR7010_DEVICE }, - /* Netgear WNDA3200 */ { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ @@ -46,13 +37,20 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ - { USB_DEVICE(0x083A, 0xA704), - .driver_info = AR7010_DEVICE }, - /* SMC Networks */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ + + { USB_DEVICE(0x0cf3, 0x7015), + .driver_info = AR9287_USB }, /* Atheros */ { USB_DEVICE(0x1668, 0x1200), - .driver_info = AR7010_DEVICE | AR9287_DEVICE }, - /* Verizon */ + .driver_info = AR9287_USB }, /* Verizon */ + + { USB_DEVICE(0x0cf3, 0x7010), + .driver_info = AR9280_USB }, /* Atheros */ + { USB_DEVICE(0x0846, 0x9018), + .driver_info = AR9280_USB }, /* Netgear WNDA3200 */ + { USB_DEVICE(0x083A, 0xA704), + .driver_info = AR9280_USB }, /* SMC Networks */ + { }, }; @@ -818,7 +816,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); - if (drv_info & AR7010_DEVICE) + if (IS_AR7010_DEVICE(drv_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; @@ -934,7 +932,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, /* Find out which firmware to load */ - if (id->driver_info & AR7010_DEVICE) + if (IS_AR7010_DEVICE(id->driver_info)) if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) hif_dev->fw_name = FIRMWARE_AR7010_1_1; else @@ -1034,7 +1032,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) if (hif_dev->firmware) { ret = ath9k_hif_usb_download_fw(hif_dev, - htc_handle->drv_priv->ah->common.driver_info); + htc_handle->drv_priv->ah->hw_version.usbdev); if (ret) goto fail_resume; } else { diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 2daf97b11c08..e4a5e2e79541 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -17,6 +17,8 @@ #ifndef HTC_USB_H #define HTC_USB_H +#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) + #define AR9271_FIRMWARE 0x501000 #define AR9271_FIRMWARE_TEXT 0x903000 #define AR7010_FIRMWARE_TEXT 0x906000 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f89f6635abae..680cd369f144 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -246,7 +246,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, * the HIF layer, shouldn't matter much. */ - if (drv_info & AR7010_DEVICE) + if (IS_AR7010_DEVICE(drv_info)) priv->htc->credits = 45; else priv->htc->credits = 33; @@ -630,6 +630,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ah->hw_version.devid = devid; ah->hw_version.subsysid = 0; /* FIXME */ + ah->hw_version.usbdev = drv_info; ah->ah_flags |= AH_USE_EEPROM; priv->ah = ah; @@ -640,7 +641,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common->hw = priv->hw; common->priv = priv; common->debug_mask = ath9k_debug; - common->driver_info = drv_info; spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); @@ -891,7 +891,7 @@ int ath9k_htc_resume(struct htc_target *htc_handle) return ret; ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid, - priv->ah->common.driver_info); + priv->ah->hw_version.usbdev); return ret; } #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index fcfd63efe55a..d83cc3b4685b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -446,6 +446,7 @@ struct ath9k_hw_version { u16 analog5GhzRev; u16 analog2GhzRev; u16 subsysid; + enum ath_usb_dev usbdev; }; /* Generic TSF timer definitions */ diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index d3257f783a64..4df5659c6c16 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -871,8 +871,14 @@ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) +enum ath_usb_dev { + AR9280_USB = 1, /* AR7010 + AR9280, UB94 */ + AR9287_USB = 2, /* AR7010 + AR9287, UB95 */ +}; + #define AR_DEVID_7010(_ah) \ - ((_ah)->common.driver_info & AR7010_DEVICE) + (((_ah)->hw_version.usbdev == AR9280_USB) || \ + ((_ah)->hw_version.usbdev == AR9287_USB)) #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 -- cgit v1.2.3-59-g8ed1b From 692d6b175b392512881ab374567e900fc825d487 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 7 Dec 2010 16:31:54 +0530 Subject: ath9k_htc: Add support for handling TX power configuration Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 87731c2daae4..fe82e5e30d82 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1411,6 +1411,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } + if (changed & IEEE80211_CONF_CHANGE_PS) { if (conf->flags & IEEE80211_CONF_PS) { ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); @@ -1422,6 +1423,11 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } + if (changed & IEEE80211_CONF_CHANGE_POWER) { + priv->txpowlimit = 2 * conf->power_level; + ath_update_txpow(priv); + } + if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { if (ath9k_htc_add_monitor_interface(priv)) -- cgit v1.2.3-59-g8ed1b From caa0a99acd2c4eb0a8d4e9caae397291e4cf743a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 7 Dec 2010 16:32:02 +0530 Subject: ath9k_htc: Fix panic on FW download failure Use the correct error condition exit in case firmware download fails for some reason. Not doing so results in a panic: usb 1-3: ath9k_htc: Transferred FW: ar9271.fw, size: 51280 usb 1-3: ath9k_htc: Firmware - ar9271.fw download failed usb 1-3: ath9k_htc: Target is unresponsive Failed to initialize the device INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. Pid: 2823, comm: insmod Tainted: G W 2.6.37-rc4-wl #11 Call Trace: [] __lock_acquire+0xe3e/0x1d00 [] ? restore_args+0x0/0x30 [] ? vprintk+0x321/0x500 [] lock_acquire+0xa0/0x190 [] ? usb_kill_anchored_urbs+0x1c/0x80 [usbcore] [] _raw_spin_lock_irq+0x48/0x60 [] ? usb_kill_anchored_urbs+0x1c/0x80 [usbcore] [] ? printk+0x3c/0x3f [] usb_kill_anchored_urbs+0x1c/0x80 [usbcore] [] ath9k_hif_usb_dealloc_urbs+0x18/0x40 [ath9k_htc] [] ath9k_hif_usb_probe+0x227/0x3d0 [ath9k_htc] [] usb_probe_interface+0x10c/0x210 [usbcore] [] driver_probe_device+0x96/0x1c0 [] __driver_attach+0xa3/0xb0 [] ? __driver_attach+0x0/0xb0 [] bus_for_each_dev+0x5e/0x90 [] driver_attach+0x19/0x20 [] bus_add_driver+0x168/0x320 [] driver_register+0x71/0x140 [] ? __raw_spin_lock_init+0x38/0x70 [] usb_register_driver+0xdc/0x190 [usbcore] [] ? ath9k_htc_init+0x0/0x4f [ath9k_htc] [] ath9k_hif_usb_init+0x1e/0x20 [ath9k_htc] [] ath9k_htc_init+0x2b/0x4f [ath9k_htc] [] do_one_initcall+0x3f/0x180 [] sys_init_module+0xbb/0x200 [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index cc1e5b3444a4..45d4b2403a52 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -885,9 +885,9 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) return 0; -err_fw_download: - ath9k_hif_usb_dealloc_urbs(hif_dev); err_urb: + ath9k_hif_usb_dealloc_urbs(hif_dev); +err_fw_download: release_firmware(hif_dev->firmware); err_fw_req: hif_dev->firmware = NULL; -- cgit v1.2.3-59-g8ed1b From aaef24b4c9f5db726e618977b74ffef924360de5 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 7 Dec 2010 20:40:58 +0530 Subject: ath9k: Properly use unlikely check macro AUTOSLEEP feature is enabled only for AR9271 and AR9003 version chipsets.So unlikely macro should be used only to check whether auto-sleep feature is enabled Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3f8b2e32f364..0eac27d56da7 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1745,10 +1745,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) } spin_lock_irqsave(&sc->sc_pm_lock, flags); - if (unlikely(ath9k_check_auto_sleep(sc) || - (sc->ps_flags & (PS_WAIT_FOR_BEACON | + + if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA)))) + PS_WAIT_FOR_PSPOLL_DATA)) || + unlikely(ath9k_check_auto_sleep(sc))) ath_rx_ps(sc, skb); spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -- cgit v1.2.3-59-g8ed1b From 0ce3bcfc84900a64347b0fe1140229bd81314008 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 7 Dec 2010 21:14:15 +0530 Subject: ath9k: Parse DTIM period from mac80211 With the current save power save implementation we assume a dtim period of 1.This value is assigned based on a sanity check in the driver eventhough we had not parsed it from mac80211.This patch obtains the actual DTIM period from AP by parsing it from mac80211.Yet for handling multicast traffic we may still have it as fixed rather than parsing it from mac80211 .This does not breaks power save or anything as the sleep duration is currently fixed in the driver.This patch may serve to improve power save in the future by using dtim period for sleep duration and using correct dtim period adhoc mode. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 ++- drivers/net/wireless/ath/ath9k/init.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 680cd369f144..93f3f615218b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -714,7 +714,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK; + IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_NEED_DTIM_PERIOD; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index bd451c243689..b2983ce19dfb 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -642,7 +642,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_REPORTS_TX_ACK_STATUS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_NEED_DTIM_PERIOD; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; -- cgit v1.2.3-59-g8ed1b From cae6b74d907e2abd22d496fe30417b088d3302cf Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 7 Dec 2010 21:23:16 +0530 Subject: ath9k: Remove dead code in recv.c The structure struct ieee80211_rx_status *rxs is no longer needed to be passed to ath_rx_send_to_mac80211 function Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 0eac27d56da7..c3129db7828f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -662,8 +662,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) } static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, - struct ath_softc *sc, struct sk_buff *skb, - struct ieee80211_rx_status *rxs) + struct ath_softc *sc, struct sk_buff *skb) { struct ieee80211_hdr *hdr; @@ -1621,7 +1620,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); /* - * The hw can techncically differ from common->hw when using ath9k + * The hw can technically differ from common->hw when using ath9k * virtual wiphy so to account for that we iterate over the active * wiphys and find the appropriate wiphy and therefore hw. */ @@ -1729,7 +1728,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; ath_err(common, "dma_mapping_error() on RX\n"); - ath_rx_send_to_mac80211(hw, sc, skb, rxs); + ath_rx_send_to_mac80211(hw, sc, skb); break; } @@ -1756,7 +1755,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) ath_ant_comb_scan(sc, &rs); - ath_rx_send_to_mac80211(hw, sc, skb, rxs); + ath_rx_send_to_mac80211(hw, sc, skb); requeue: if (edma) { -- cgit v1.2.3-59-g8ed1b From 7659a193f94c0003dd06e9e874d19bade1a8c952 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 7 Dec 2010 10:41:47 -0800 Subject: mac80211: Fix compilation error when mesh is disabled Wrap mesh sections inside CONFIG_MAC80211_MESH to fix compilation problems reported by Stephen Rothwell, Larry Finger and Bruno Randolf. Signed-off-by: John W. Linville --- net/mac80211/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2de69766c6aa..973fee9f7d69 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -245,10 +245,12 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.enable_beacon = !!sdata->u.ibss.presp; break; +#ifdef CONFIG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: sdata->vif.bss_conf.enable_beacon = !!sdata->u.mesh.mesh_id_len; break; +#endif default: /* not reached */ WARN_ON(1); -- cgit v1.2.3-59-g8ed1b From c02178d22b3ef2d18c38c96151600ee1c7ed94f0 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Dec 2010 00:21:05 +0200 Subject: Bluetooth: Add Bluetooth Management interface definitions Add initial definitions for the new Bluetooth Management interface to the bluetooth headers. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 4 ++++ include/net/bluetooth/hci_core.h | 1 + include/net/bluetooth/mgmt.h | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 include/net/bluetooth/mgmt.h diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index f3c5ed6d7bda..29a7a8ca0438 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -934,9 +934,13 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) struct sockaddr_hci { sa_family_t hci_family; unsigned short hci_dev; + unsigned short hci_channel; }; #define HCI_DEV_NONE 0xffff +#define HCI_CHANNEL_RAW 0 +#define HCI_CHANNEL_CONTROL 1 + struct hci_filter { unsigned long type_mask; unsigned long event_mask[2]; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 9c08625617a1..3e3435945980 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -668,6 +668,7 @@ struct hci_pinfo { struct hci_dev *hdev; struct hci_filter filter; __u32 cmsg_mask; + unsigned short channel; }; /* HCI security filter */ diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h new file mode 100644 index 000000000000..95974daa725e --- /dev/null +++ b/include/net/bluetooth/mgmt.h @@ -0,0 +1,46 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + + Copyright (C) 2010 Nokia Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + 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 OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +struct mgmt_hdr { + __le16 opcode; + __le16 len; +} __packed; +#define MGMT_HDR_SIZE 4 + +#define MGMT_EV_CMD_COMPLETE 0x0001 +struct mgmt_ev_cmd_complete { + __le16 opcode; + __u8 data[0]; +} __packed; + +#define MGMT_EV_CMD_STATUS 0x0002 +struct mgmt_ev_cmd_status { + __u8 status; + __le16 opcode; +} __packed; + +#define MGMT_EV_CONTROLLER_ERROR 0x0003 +struct mgmt_ev_controller_error { + __le16 index; + __u8 error_code; +} __packed; -- cgit v1.2.3-59-g8ed1b From 0381101fd6a73c7d6b545044dc1472d019fc64e3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Dec 2010 00:21:06 +0200 Subject: Bluetooth: Add initial Bluetooth Management interface callbacks Add initial code for handling Bluetooth Management interface messages. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Acked-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 3 ++ net/bluetooth/Makefile | 2 +- net/bluetooth/hci_sock.c | 39 +++++++++++++--- net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 net/bluetooth/mgmt.c diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3e3435945980..1992fac7e921 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -660,6 +660,9 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); /* ----- HCI Sockets ----- */ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); +/* Management interface */ +int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); + /* HCI info for socket */ #define hci_pi(sk) ((struct hci_pinfo *) sk) diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 7ca1f46a471a..250f954f0213 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ -bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o +bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b3753bad2a55..207be7abda9f 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -49,6 +49,8 @@ #include #include +static int enable_mgmt; + /* ----- HCI socket interface ----- */ static inline int hci_test_bit(int nr, void *addr) @@ -353,25 +355,35 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { - struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; + struct sockaddr_hci haddr; struct sock *sk = sock->sk; struct hci_dev *hdev = NULL; - int err = 0; + int len, err = 0; BT_DBG("sock %p sk %p", sock, sk); - if (!haddr || haddr->hci_family != AF_BLUETOOTH) + if (!addr) + return -EINVAL; + + memset(&haddr, 0, sizeof(haddr)); + len = min_t(unsigned int, sizeof(haddr), addr_len); + memcpy(&haddr, addr, len); + + if (haddr.hci_family != AF_BLUETOOTH) + return -EINVAL; + + if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt) return -EINVAL; lock_sock(sk); - if (hci_pi(sk)->hdev) { + if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) { err = -EALREADY; goto done; } - if (haddr->hci_dev != HCI_DEV_NONE) { - hdev = hci_dev_get(haddr->hci_dev); + if (haddr.hci_dev != HCI_DEV_NONE) { + hdev = hci_dev_get(haddr.hci_dev); if (!hdev) { err = -ENODEV; goto done; @@ -380,6 +392,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le atomic_inc(&hdev->promisc); } + hci_pi(sk)->channel = haddr.hci_channel; hci_pi(sk)->hdev = hdev; sk->sk_state = BT_BOUND; @@ -502,6 +515,17 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); + switch (hci_pi(sk)->channel) { + case HCI_CHANNEL_RAW: + break; + case HCI_CHANNEL_CONTROL: + err = mgmt_control(sk, msg, len); + goto done; + default: + err = -EINVAL; + goto done; + } + hdev = hci_pi(sk)->hdev; if (!hdev) { err = -EBADFD; @@ -831,3 +855,6 @@ void __exit hci_sock_cleanup(void) proto_unregister(&hci_sk_proto); } + +module_param(enable_mgmt, bool, 0644); +MODULE_PARM_DESC(enable_mgmt, "Enable Management interface"); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c new file mode 100644 index 000000000000..d15bf676c350 --- /dev/null +++ b/net/bluetooth/mgmt.c @@ -0,0 +1,99 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2010 Nokia Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + 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 OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* Bluetooth HCI Management interface */ + +#include +#include + +#include +#include +#include + +static void cmd_status(struct sock *sk, u16 cmd, u8 status) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + struct mgmt_ev_cmd_status *ev; + + BT_DBG("sock %p", sk); + + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); + if (!skb) + return; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); + hdr->len = cpu_to_le16(sizeof(*ev)); + + ev = (void *) skb_put(skb, sizeof(*ev)); + ev->status = status; + put_unaligned_le16(cmd, &ev->opcode); + + if (sock_queue_rcv_skb(sk, skb) < 0) + kfree_skb(skb); +} + +int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) +{ + unsigned char *buf; + struct mgmt_hdr *hdr; + u16 opcode, len; + int err; + + BT_DBG("got %zu bytes", msglen); + + if (msglen < sizeof(*hdr)) + return -EINVAL; + + buf = kmalloc(msglen, GFP_ATOMIC); + if (!buf) + return -ENOMEM; + + if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) { + err = -EFAULT; + goto done; + } + + hdr = (struct mgmt_hdr *) buf; + opcode = get_unaligned_le16(&hdr->opcode); + len = get_unaligned_le16(&hdr->len); + + if (len != msglen - sizeof(*hdr)) { + err = -EINVAL; + goto done; + } + + switch (opcode) { + default: + BT_DBG("Unknown op %u", opcode); + cmd_status(sk, opcode, 0x01); + break; + } + + err = msglen; + +done: + kfree(buf); + return err; +} -- cgit v1.2.3-59-g8ed1b From a40c406cbdd28dcca3483065bc2ba794cf5aaab7 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Dec 2010 00:21:07 +0200 Subject: Bluetooth: Make hci_send_to_sock usable for management control sockets In order to send data to management control sockets the function should: - skip checks intended for raw HCI data and stack internal events - make sure RAW HCI data or stack internal events don't go to management control sockets In order to accomplish this the patch adds a new member to the bluetooth skb private data to flag skb's that are destined for management control sockets. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/bluetooth.h | 1 + net/bluetooth/hci_sock.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index d81ea7997701..0c5e72503b77 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -144,6 +144,7 @@ struct bt_skb_cb { __u8 tx_seq; __u8 retries; __u8 sar; + unsigned short channel; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 207be7abda9f..f6c18abab797 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -104,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) if (skb->sk == sk) continue; + if (bt_cb(skb)->channel != hci_pi(sk)->channel) + continue; + + if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL) + goto clone; + /* Apply filter */ flt = &hci_pi(sk)->filter; @@ -127,12 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) continue; } +clone: nskb = skb_clone(skb, GFP_ATOMIC); if (!nskb) continue; /* Put type byte before the data */ - memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); + if (bt_cb(skb)->channel == HCI_CHANNEL_RAW) + memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); if (sock_queue_rcv_skb(sk, nskb)) kfree_skb(nskb); -- cgit v1.2.3-59-g8ed1b From 58e481f66e31e9976558f3e4f709baf9201052fe Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Dec 2010 02:45:08 +0000 Subject: atm: lanai: use kernel's '%pM' format option to print MAC Signed-off-by: Andy Shevchenko Cc: Chas Williams Cc: linux-atm-general@lists.sourceforge.net Signed-off-by: David S. Miller --- drivers/atm/lanai.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index cbe15a86c669..930051d941a7 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -2241,11 +2241,8 @@ static int __devinit lanai_dev_open(struct atm_dev *atmdev) memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN); lanai_timed_poll_start(lanai); printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%u " - "(%02X-%02X-%02X-%02X-%02X-%02X)\n", lanai->number, - (int) lanai->pci->revision, (unsigned long) lanai->base, - lanai->pci->irq, - atmdev->esi[0], atmdev->esi[1], atmdev->esi[2], - atmdev->esi[3], atmdev->esi[4], atmdev->esi[5]); + "(%pMF)\n", lanai->number, (int) lanai->pci->revision, + (unsigned long) lanai->base, lanai->pci->irq, atmdev->esi); printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), " "board_rev=%d\n", lanai->number, lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno, -- cgit v1.2.3-59-g8ed1b From a1044e36e457fb6dbdf90ce756d578b251d99b5e Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Thu, 2 Dec 2010 10:57:59 +0000 Subject: can: add slcan driver for serial/USB-serial CAN adapters This patch adds support for serial/USB-serial CAN adapters implementing the LAWICEL ASCII protocol for CAN frame transport over serial lines. The driver implements the SLCAN line discipline and is heavily based on the slip.c driver. Therefore the code style remains similar to slip.c to be able to apply changes of the SLIP driver to the SLCAN driver easily. For more details see the slcan Kconfig entry. Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- drivers/net/can/Kconfig | 21 ++ drivers/net/can/Makefile | 1 + drivers/net/can/slcan.c | 755 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 777 insertions(+) create mode 100644 drivers/net/can/slcan.c diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 080574b0fff0..d5a9db60ade9 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -12,6 +12,27 @@ config CAN_VCAN This driver can also be built as a module. If so, the module will be called vcan. +config CAN_SLCAN + tristate "Serial / USB serial CAN Adaptors (slcan)" + depends on CAN + default N + ---help--- + CAN driver for several 'low cost' CAN interfaces that are attached + via serial lines or via USB-to-serial adapters using the LAWICEL + ASCII protocol. The driver implements the tty linediscipline N_SLCAN. + + As only the sending and receiving of CAN frames is implemented, this + driver should work with the (serial/USB) CAN hardware from: + www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de + + Userspace tools to attach the SLCAN line discipline (slcan_attach, + slcand) can be found in the can-utils at the SocketCAN SVN, see + http://developer.berlios.de/projects/socketcan for details. + + The slcan driver supports up to 10 CAN netdevices by default which + can be changed by the 'maxdev=xx' module option. This driver can + also be built as a module. If so, the module will be called slcan. + config CAN_DEV tristate "Platform CAN drivers with Netlink support" depends on CAN diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 90af15a4f106..07ca159ba3f9 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_CAN_VCAN) += vcan.o +obj-$(CONFIG_CAN_SLCAN) += slcan.o obj-$(CONFIG_CAN_DEV) += can-dev.o can-dev-y := dev.o diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c new file mode 100644 index 000000000000..420e95ecc193 --- /dev/null +++ b/drivers/net/can/slcan.c @@ -0,0 +1,755 @@ +/* + * slcan.c - serial line CAN interface driver (using tty line discipline) + * + * This file is derived from linux/drivers/net/slip.c + * + * slip.c Authors : Laurence Culhane + * Fred N. van Kempen + * slcan.c Author : Oliver Hartkopp + * + * 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. You can also get it + * at http://www.gnu.org/licenses/gpl.html + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Send feedback to + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static __initdata const char banner[] = + KERN_INFO "slcan: serial line CAN interface driver\n"; + +MODULE_ALIAS_LDISC(N_SLCAN); +MODULE_DESCRIPTION("serial line CAN interface"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Oliver Hartkopp "); + +#define SLCAN_MAGIC 0x53CA + +static int maxdev = 10; /* MAX number of SLCAN channels; + This can be overridden with + insmod slcan.ko maxdev=nnn */ +module_param(maxdev, int, 0); +MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces"); + +/* maximum rx buffer len: extended CAN frame with timestamp */ +#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1) + +struct slcan { + int magic; + + /* Various fields. */ + struct tty_struct *tty; /* ptr to TTY structure */ + struct net_device *dev; /* easy for intr handling */ + spinlock_t lock; + + /* These are pointers to the malloc()ed frame buffers. */ + unsigned char rbuff[SLC_MTU]; /* receiver buffer */ + int rcount; /* received chars counter */ + unsigned char xbuff[SLC_MTU]; /* transmitter buffer */ + unsigned char *xhead; /* pointer to next XMIT byte */ + int xleft; /* bytes left in XMIT queue */ + + unsigned long flags; /* Flag values/ mode etc */ +#define SLF_INUSE 0 /* Channel in use */ +#define SLF_ERROR 1 /* Parity, etc. error */ + + unsigned char leased; + dev_t line; + pid_t pid; +}; + +static struct net_device **slcan_devs; + + /************************************************************************ + * SLCAN ENCAPSULATION FORMAT * + ************************************************************************/ + +/* + * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended + * frame format) a data length code (can_dlc) which can be from 0 to 8 + * and up to data bytes as payload. + * Additionally a CAN frame may become a remote transmission frame if the + * RTR-bit is set. This causes another ECU to send a CAN frame with the + * given can_id. + * + * The SLCAN ASCII representation of these different frame types is: + * * + * + * Extended frames (29 bit) are defined by capital characters in the type. + * RTR frames are defined as 'r' types - normal frames have 't' type: + * t => 11 bit data frame + * r => 11 bit RTR frame + * T => 29 bit data frame + * R => 29 bit RTR frame + * + * The is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64). + * The is a one byte ASCII number ('0' - '8') + * The section has at much ASCII Hex bytes as defined by the + * + * Examples: + * + * t1230 : can_id 0x123, can_dlc 0, no data + * t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33 + * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55 + * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request + * + */ + + /************************************************************************ + * STANDARD SLCAN DECAPSULATION * + ************************************************************************/ + +static int asc2nibble(char c) +{ + + if ((c >= '0') && (c <= '9')) + return c - '0'; + + if ((c >= 'A') && (c <= 'F')) + return c - 'A' + 10; + + if ((c >= 'a') && (c <= 'f')) + return c - 'a' + 10; + + return 16; /* error */ +} + +/* Send one completely decapsulated can_frame to the network layer */ +static void slc_bump(struct slcan *sl) +{ + struct sk_buff *skb; + struct can_frame cf; + int i, dlc_pos, tmp; + unsigned long ultmp; + char cmd = sl->rbuff[0]; + + if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R')) + return; + + if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */ + dlc_pos = 4; /* dlc position tiiid */ + else + dlc_pos = 9; /* dlc position Tiiiiiiiid */ + + if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9'))) + return; + + cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */ + + sl->rbuff[dlc_pos] = 0; /* terminate can_id string */ + + if (strict_strtoul(sl->rbuff+1, 16, &ultmp)) + return; + + cf.can_id = ultmp; + + if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */ + cf.can_id |= CAN_EFF_FLAG; + + if ((cmd | 0x20) == 'r') /* RTR frame */ + cf.can_id |= CAN_RTR_FLAG; + + *(u64 *) (&cf.data) = 0; /* clear payload */ + + for (i = 0, dlc_pos++; i < cf.can_dlc; i++) { + + tmp = asc2nibble(sl->rbuff[dlc_pos++]); + if (tmp > 0x0F) + return; + cf.data[i] = (tmp << 4); + tmp = asc2nibble(sl->rbuff[dlc_pos++]); + if (tmp > 0x0F) + return; + cf.data[i] |= tmp; + } + + + skb = dev_alloc_skb(sizeof(struct can_frame)); + if (!skb) + return; + + skb->dev = sl->dev; + skb->protocol = htons(ETH_P_CAN); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; + memcpy(skb_put(skb, sizeof(struct can_frame)), + &cf, sizeof(struct can_frame)); + netif_rx(skb); + + sl->dev->stats.rx_packets++; + sl->dev->stats.rx_bytes += cf.can_dlc; +} + +/* parse tty input stream */ +static void slcan_unesc(struct slcan *sl, unsigned char s) +{ + + if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */ + if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && + (sl->rcount > 4)) { + slc_bump(sl); + } + sl->rcount = 0; + } else { + if (!test_bit(SLF_ERROR, &sl->flags)) { + if (sl->rcount < SLC_MTU) { + sl->rbuff[sl->rcount++] = s; + return; + } else { + sl->dev->stats.rx_over_errors++; + set_bit(SLF_ERROR, &sl->flags); + } + } + } +} + + /************************************************************************ + * STANDARD SLCAN ENCAPSULATION * + ************************************************************************/ + +/* Encapsulate one can_frame and stuff into a TTY queue. */ +static void slc_encaps(struct slcan *sl, struct can_frame *cf) +{ + int actual, idx, i; + char cmd; + + if (cf->can_id & CAN_RTR_FLAG) + cmd = 'R'; /* becomes 'r' in standard frame format */ + else + cmd = 'T'; /* becomes 't' in standard frame format */ + + if (cf->can_id & CAN_EFF_FLAG) + sprintf(sl->xbuff, "%c%08X%d", cmd, + cf->can_id & CAN_EFF_MASK, cf->can_dlc); + else + sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20, + cf->can_id & CAN_SFF_MASK, cf->can_dlc); + + idx = strlen(sl->xbuff); + + for (i = 0; i < cf->can_dlc; i++) + sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]); + + strcat(sl->xbuff, "\r"); /* add terminating character */ + + /* Order of next two lines is *very* important. + * When we are sending a little amount of data, + * the transfer may be completed inside the ops->write() + * routine, because it's running with interrupts enabled. + * In this case we *never* got WRITE_WAKEUP event, + * if we did not request it before write operation. + * 14 Oct 1994 Dmitry Gorodchanin. + */ + set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); + actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); + sl->xleft = strlen(sl->xbuff) - actual; + sl->xhead = sl->xbuff + actual; + sl->dev->stats.tx_bytes += cf->can_dlc; +} + +/* + * Called by the driver when there's room for more data. If we have + * more packets to send, we send them here. + */ +static void slcan_write_wakeup(struct tty_struct *tty) +{ + int actual; + struct slcan *sl = (struct slcan *) tty->disc_data; + + /* First make sure we're connected. */ + if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) + return; + + if (sl->xleft <= 0) { + /* Now serial buffer is almost free & we can start + * transmission of another packet */ + sl->dev->stats.tx_packets++; + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + netif_wake_queue(sl->dev); + return; + } + + actual = tty->ops->write(tty, sl->xhead, sl->xleft); + sl->xleft -= actual; + sl->xhead += actual; +} + +/* Send a can_frame to a TTY queue. */ +static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct slcan *sl = netdev_priv(dev); + + if (skb->len != sizeof(struct can_frame)) + goto out; + + spin_lock(&sl->lock); + if (!netif_running(dev)) { + spin_unlock(&sl->lock); + printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name); + goto out; + } + if (sl->tty == NULL) { + spin_unlock(&sl->lock); + goto out; + } + + netif_stop_queue(sl->dev); + slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */ + spin_unlock(&sl->lock); + +out: + kfree_skb(skb); + return NETDEV_TX_OK; +} + + +/****************************************** + * Routines looking at netdevice side. + ******************************************/ + +/* Netdevice UP -> DOWN routine */ +static int slc_close(struct net_device *dev) +{ + struct slcan *sl = netdev_priv(dev); + + spin_lock_bh(&sl->lock); + if (sl->tty) { + /* TTY discipline is running. */ + clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); + } + netif_stop_queue(dev); + sl->rcount = 0; + sl->xleft = 0; + spin_unlock_bh(&sl->lock); + + return 0; +} + +/* Netdevice DOWN -> UP routine */ +static int slc_open(struct net_device *dev) +{ + struct slcan *sl = netdev_priv(dev); + + if (sl->tty == NULL) + return -ENODEV; + + sl->flags &= (1 << SLF_INUSE); + netif_start_queue(dev); + return 0; +} + +/* Hook the destructor so we can free slcan devs at the right point in time */ +static void slc_free_netdev(struct net_device *dev) +{ + int i = dev->base_addr; + free_netdev(dev); + slcan_devs[i] = NULL; +} + +static const struct net_device_ops slc_netdev_ops = { + .ndo_open = slc_open, + .ndo_stop = slc_close, + .ndo_start_xmit = slc_xmit, +}; + +static void slc_setup(struct net_device *dev) +{ + dev->netdev_ops = &slc_netdev_ops; + dev->destructor = slc_free_netdev; + + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->tx_queue_len = 10; + + dev->mtu = sizeof(struct can_frame); + dev->type = ARPHRD_CAN; + + /* New-style flags. */ + dev->flags = IFF_NOARP; + dev->features = NETIF_F_NO_CSUM; +} + +/****************************************** + Routines looking at TTY side. + ******************************************/ + +/* + * Handle the 'receiver data ready' interrupt. + * This function is called by the 'tty_io' module in the kernel when + * a block of SLCAN data has been received, which can now be decapsulated + * and sent on to some IP layer for further processing. This will not + * be re-entered while running but other ldisc functions may be called + * in parallel + */ + +static void slcan_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) +{ + struct slcan *sl = (struct slcan *) tty->disc_data; + + if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) + return; + + /* Read the characters out of the buffer */ + while (count--) { + if (fp && *fp++) { + if (!test_and_set_bit(SLF_ERROR, &sl->flags)) + sl->dev->stats.rx_errors++; + cp++; + continue; + } + slcan_unesc(sl, *cp++); + } +} + +/************************************ + * slcan_open helper routines. + ************************************/ + +/* Collect hanged up channels */ +static void slc_sync(void) +{ + int i; + struct net_device *dev; + struct slcan *sl; + + for (i = 0; i < maxdev; i++) { + dev = slcan_devs[i]; + if (dev == NULL) + break; + + sl = netdev_priv(dev); + if (sl->tty || sl->leased) + continue; + if (dev->flags & IFF_UP) + dev_close(dev); + } +} + +/* Find a free SLCAN channel, and link in this `tty' line. */ +static struct slcan *slc_alloc(dev_t line) +{ + int i; + struct net_device *dev = NULL; + struct slcan *sl; + + if (slcan_devs == NULL) + return NULL; /* Master array missing ! */ + + for (i = 0; i < maxdev; i++) { + dev = slcan_devs[i]; + if (dev == NULL) + break; + + } + + /* Sorry, too many, all slots in use */ + if (i >= maxdev) + return NULL; + + if (dev) { + sl = netdev_priv(dev); + if (test_bit(SLF_INUSE, &sl->flags)) { + unregister_netdevice(dev); + dev = NULL; + slcan_devs[i] = NULL; + } + } + + if (!dev) { + char name[IFNAMSIZ]; + sprintf(name, "slcan%d", i); + + dev = alloc_netdev(sizeof(*sl), name, slc_setup); + if (!dev) + return NULL; + dev->base_addr = i; + } + + sl = netdev_priv(dev); + + /* Initialize channel control data */ + sl->magic = SLCAN_MAGIC; + sl->dev = dev; + spin_lock_init(&sl->lock); + slcan_devs[i] = dev; + + return sl; +} + +/* + * Open the high-level part of the SLCAN channel. + * This function is called by the TTY module when the + * SLCAN line discipline is called for. Because we are + * sure the tty line exists, we only have to link it to + * a free SLCAN channel... + * + * Called in process context serialized from other ldisc calls. + */ + +static int slcan_open(struct tty_struct *tty) +{ + struct slcan *sl; + int err; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + + /* RTnetlink lock is misused here to serialize concurrent + opens of slcan channels. There are better ways, but it is + the simplest one. + */ + rtnl_lock(); + + /* Collect hanged up channels. */ + slc_sync(); + + sl = tty->disc_data; + + err = -EEXIST; + /* First make sure we're not already connected. */ + if (sl && sl->magic == SLCAN_MAGIC) + goto err_exit; + + /* OK. Find a free SLCAN channel to use. */ + err = -ENFILE; + sl = slc_alloc(tty_devnum(tty)); + if (sl == NULL) + goto err_exit; + + sl->tty = tty; + tty->disc_data = sl; + sl->line = tty_devnum(tty); + sl->pid = current->pid; + + if (!test_bit(SLF_INUSE, &sl->flags)) { + /* Perform the low-level SLCAN initialization. */ + sl->rcount = 0; + sl->xleft = 0; + + set_bit(SLF_INUSE, &sl->flags); + + err = register_netdevice(sl->dev); + if (err) + goto err_free_chan; + } + + /* Done. We have linked the TTY line to a channel. */ + rtnl_unlock(); + tty->receive_room = 65536; /* We don't flow control */ + return sl->dev->base_addr; + +err_free_chan: + sl->tty = NULL; + tty->disc_data = NULL; + clear_bit(SLF_INUSE, &sl->flags); + +err_exit: + rtnl_unlock(); + + /* Count references from TTY module */ + return err; +} + +/* + * Close down a SLCAN channel. + * This means flushing out any pending queues, and then returning. This + * call is serialized against other ldisc functions. + * + * We also use this method for a hangup event. + */ + +static void slcan_close(struct tty_struct *tty) +{ + struct slcan *sl = (struct slcan *) tty->disc_data; + + /* First make sure we're connected. */ + if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty) + return; + + tty->disc_data = NULL; + sl->tty = NULL; + if (!sl->leased) + sl->line = 0; + + /* Flush network side */ + unregister_netdev(sl->dev); + /* This will complete via sl_free_netdev */ +} + +static int slcan_hangup(struct tty_struct *tty) +{ + slcan_close(tty); + return 0; +} + +/* Perform I/O control on an active SLCAN channel. */ +static int slcan_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct slcan *sl = (struct slcan *) tty->disc_data; + unsigned int tmp; + + /* First make sure we're connected. */ + if (!sl || sl->magic != SLCAN_MAGIC) + return -EINVAL; + + switch (cmd) { + case SIOCGIFNAME: + tmp = strlen(sl->dev->name) + 1; + if (copy_to_user((void __user *)arg, sl->dev->name, tmp)) + return -EFAULT; + return 0; + + case SIOCSIFHWADDR: + return -EINVAL; + + default: + return tty_mode_ioctl(tty, file, cmd, arg); + } +} + +static struct tty_ldisc_ops slc_ldisc = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "slcan", + .open = slcan_open, + .close = slcan_close, + .hangup = slcan_hangup, + .ioctl = slcan_ioctl, + .receive_buf = slcan_receive_buf, + .write_wakeup = slcan_write_wakeup, +}; + +static int __init slcan_init(void) +{ + int status; + + if (maxdev < 4) + maxdev = 4; /* Sanity */ + + printk(banner); + printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev); + + slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); + if (!slcan_devs) { + printk(KERN_ERR "slcan: can't allocate slcan device array!\n"); + return -ENOMEM; + } + + /* Fill in our line protocol discipline, and register it */ + status = tty_register_ldisc(N_SLCAN, &slc_ldisc); + if (status) { + printk(KERN_ERR "slcan: can't register line discipline\n"); + kfree(slcan_devs); + } + return status; +} + +static void __exit slcan_exit(void) +{ + int i; + struct net_device *dev; + struct slcan *sl; + unsigned long timeout = jiffies + HZ; + int busy = 0; + + if (slcan_devs == NULL) + return; + + /* First of all: check for active disciplines and hangup them. + */ + do { + if (busy) + msleep_interruptible(100); + + busy = 0; + for (i = 0; i < maxdev; i++) { + dev = slcan_devs[i]; + if (!dev) + continue; + sl = netdev_priv(dev); + spin_lock_bh(&sl->lock); + if (sl->tty) { + busy++; + tty_hangup(sl->tty); + } + spin_unlock_bh(&sl->lock); + } + } while (busy && time_before(jiffies, timeout)); + + /* FIXME: hangup is async so we should wait when doing this second + phase */ + + for (i = 0; i < maxdev; i++) { + dev = slcan_devs[i]; + if (!dev) + continue; + slcan_devs[i] = NULL; + + sl = netdev_priv(dev); + if (sl->tty) { + printk(KERN_ERR "%s: tty discipline still running\n", + dev->name); + /* Intentionally leak the control block. */ + dev->destructor = NULL; + } + + unregister_netdev(dev); + } + + kfree(slcan_devs); + slcan_devs = NULL; + + i = tty_unregister_ldisc(N_SLCAN); + if (i) + printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i); +} + +module_init(slcan_init); +module_exit(slcan_exit); -- cgit v1.2.3-59-g8ed1b From aa9421041128abb4d269ee1dc502ff65fb3b7d69 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 4 Dec 2010 02:31:41 +0000 Subject: net: init ingress queue The dev field of ingress queue is forgot to initialized, then NULL pointer dereference happens in qdisc_alloc(). Move inits of tx queues to netif_alloc_netdev_queues(). Signed-off-by: Changli Gao Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 55ff66fabce4..ee605c0867e7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5112,11 +5112,21 @@ static int netif_alloc_rx_queues(struct net_device *dev) } #endif +static void netdev_init_one_queue(struct net_device *dev, + struct netdev_queue *queue, void *_unused) +{ + /* Initialize queue lock */ + spin_lock_init(&queue->_xmit_lock); + netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); + queue->xmit_lock_owner = -1; + netdev_queue_numa_node_write(queue, -1); + queue->dev = dev; +} + static int netif_alloc_netdev_queues(struct net_device *dev) { unsigned int count = dev->num_tx_queues; struct netdev_queue *tx; - int i; BUG_ON(count < 1); @@ -5128,27 +5138,10 @@ static int netif_alloc_netdev_queues(struct net_device *dev) } dev->_tx = tx; - for (i = 0; i < count; i++) { - netdev_queue_numa_node_write(&tx[i], -1); - tx[i].dev = dev; - } - return 0; -} - -static void netdev_init_one_queue(struct net_device *dev, - struct netdev_queue *queue, - void *_unused) -{ - /* Initialize queue lock */ - spin_lock_init(&queue->_xmit_lock); - netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); - queue->xmit_lock_owner = -1; -} - -static void netdev_init_queues(struct net_device *dev) -{ netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); spin_lock_init(&dev->tx_global_lock); + + return 0; } /** @@ -5187,8 +5180,6 @@ int register_netdevice(struct net_device *dev) dev->iflink = -1; - netdev_init_queues(dev); - /* Init, if this function is available */ if (dev->netdev_ops->ndo_init) { ret = dev->netdev_ops->ndo_init(dev); -- cgit v1.2.3-59-g8ed1b From 01b0c5cfb23f19837650aa53495ace6d0fd7d3f8 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Sat, 4 Dec 2010 15:22:46 +0000 Subject: net/9p/protocol.c: Remove duplicated macros. Use the macros already provided by kernel.h file. Signed-off-by: Thiago Farina Signed-off-by: David S. Miller --- net/9p/protocol.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 45c15f491401..798beac7f100 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -27,31 +27,16 @@ #include #include +#include #include #include #include +#include #include #include #include #include "protocol.h" -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef offset_of -#define offset_of(type, memb) \ - ((unsigned long)(&((type *)0)->memb)) -#endif -#ifndef container_of -#define container_of(obj, type, memb) \ - ((type *)(((char *)obj) - offset_of(type, memb))) -#endif - static int p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); @@ -104,7 +89,7 @@ EXPORT_SYMBOL(p9stat_free); static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size) { - size_t len = MIN(pdu->size - pdu->offset, size); + size_t len = min(pdu->size - pdu->offset, size); memcpy(data, &pdu->sdata[pdu->offset], len); pdu->offset += len; return size - len; @@ -112,7 +97,7 @@ static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size) static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size) { - size_t len = MIN(pdu->capacity - pdu->size, size); + size_t len = min(pdu->capacity - pdu->size, size); memcpy(&pdu->sdata[pdu->size], data, len); pdu->size += len; return size - len; @@ -121,7 +106,7 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size) static size_t pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) { - size_t len = MIN(pdu->capacity - pdu->size, size); + size_t len = min(pdu->capacity - pdu->size, size); if (copy_from_user(&pdu->sdata[pdu->size], udata, len)) len = 0; @@ -201,7 +186,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, if (errcode) break; - size = MAX(len, 0); + size = max_t(int16_t, len, 0); *sptr = kmalloc(size + 1, GFP_KERNEL); if (*sptr == NULL) { @@ -256,8 +241,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, p9pdu_readf(pdu, proto_version, "d", count); if (!errcode) { *count = - MIN(*count, - pdu->size - pdu->offset); + min_t(int32_t, *count, + pdu->size - pdu->offset); *data = &pdu->sdata[pdu->offset]; } } @@ -421,7 +406,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, const char *sptr = va_arg(ap, const char *); int16_t len = 0; if (sptr) - len = MIN(strlen(sptr), USHRT_MAX); + len = min_t(int16_t, strlen(sptr), USHRT_MAX); errcode = p9pdu_writef(pdu, proto_version, "w", len); -- cgit v1.2.3-59-g8ed1b From 941666c2e3e0f9f6a1cb5808d02352d445bd702c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 5 Dec 2010 01:23:53 +0000 Subject: net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit : > Hmm.. > > If somebody can explain why RTNL is held in arp_ioctl() (and therefore > in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so > that your patch can be applied. > > Right now it is not good, because RTNL wont be necessarly held when you > are going to call arp_invalidate() ? While doing this analysis, I found a refcount bug in llc, I'll send a patch for net-2.6 Meanwhile, here is the patch for net-next-2.6 Your patch then can be applied after mine. Thanks [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() dev_getbyhwaddr() was called under RTNL. Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use RCU locking instead of RTNL. Change arp_ioctl() to use RCU instead of RTNL locking. Note: this fix a dev refcount bug in llc Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 3 ++- net/core/dev.c | 17 +++++++---------- net/ieee802154/af_ieee802154.c | 6 +++--- net/ipv4/arp.c | 17 +++++++++-------- net/llc/af_llc.c | 11 ++++++----- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a9ac5dc26e3c..d31bc3c94717 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1360,7 +1360,8 @@ static inline struct net_device *first_net_device(struct net *net) extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); -extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr); +extern struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + const char *hwaddr); extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type); extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type); extern void dev_add_pack(struct packet_type *pt); diff --git a/net/core/dev.c b/net/core/dev.c index ee605c0867e7..822b15b8d11c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -743,34 +743,31 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex) EXPORT_SYMBOL(dev_get_by_index); /** - * dev_getbyhwaddr - find a device by its hardware address + * dev_getbyhwaddr_rcu - find a device by its hardware address * @net: the applicable net namespace * @type: media type of device * @ha: hardware address * * Search for an interface by MAC address. Returns NULL if the device - * is not found or a pointer to the device. The caller must hold the - * rtnl semaphore. The returned device has not had its ref count increased + * is not found or a pointer to the device. The caller must hold RCU + * The returned device has not had its ref count increased * and the caller must therefore be careful about locking * - * BUGS: - * If the API was consistent this would be __dev_get_by_hwaddr */ -struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha) +struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + const char *ha) { struct net_device *dev; - ASSERT_RTNL(); - - for_each_netdev(net, dev) + for_each_netdev_rcu(net, dev) if (dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len)) return dev; return NULL; } -EXPORT_SYMBOL(dev_getbyhwaddr); +EXPORT_SYMBOL(dev_getbyhwaddr_rcu); struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type) { diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index 93c91b633a56..6df6ecf49708 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c @@ -52,11 +52,11 @@ struct net_device *ieee802154_get_dev(struct net *net, switch (addr->addr_type) { case IEEE802154_ADDR_LONG: - rtnl_lock(); - dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr); + rcu_read_lock(); + dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr); if (dev) dev_hold(dev); - rtnl_unlock(); + rcu_read_unlock(); break; case IEEE802154_ADDR_SHORT: if (addr->pan_id == 0xffff || diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 10af759f2630..a2fc7b961dbc 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1017,13 +1017,14 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on) IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; return 0; } - if (__in_dev_get_rtnl(dev)) { - IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on); + if (__in_dev_get_rcu(dev)) { + IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on); return 0; } return -ENXIO; } +/* must be called with rcu_read_lock() */ static int arp_req_set_public(struct net *net, struct arpreq *r, struct net_device *dev) { @@ -1033,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, if (mask && mask != htonl(0xFFFFFFFF)) return -EINVAL; if (!dev && (r->arp_flags & ATF_COM)) { - dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, + dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family, r->arp_ha.sa_data); if (!dev) return -ENODEV; @@ -1225,10 +1226,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) if (!(r.arp_flags & ATF_NETMASK)) ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = htonl(0xFFFFFFFFUL); - rtnl_lock(); + rcu_read_lock(); if (r.arp_dev[0]) { err = -ENODEV; - dev = __dev_get_by_name(net, r.arp_dev); + dev = dev_get_by_name_rcu(net, r.arp_dev); if (dev == NULL) goto out; @@ -1252,12 +1253,12 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) break; case SIOCGARP: err = arp_req_get(&r, dev); - if (!err && copy_to_user(arg, &r, sizeof(r))) - err = -EFAULT; break; } out: - rtnl_unlock(); + rcu_read_unlock(); + if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) + err = -EFAULT; return err; } diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 582612998211..dfd3a648a551 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -316,9 +316,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) if (unlikely(addr->sllc_family != AF_LLC)) goto out; rc = -ENODEV; - rtnl_lock(); + rcu_read_lock(); if (sk->sk_bound_dev_if) { - llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); + llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); if (llc->dev) { if (!addr->sllc_arphrd) addr->sllc_arphrd = llc->dev->type; @@ -329,14 +329,15 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) !llc_mac_match(addr->sllc_mac, llc->dev->dev_addr)) { rc = -EINVAL; - dev_put(llc->dev); llc->dev = NULL; } } } else - llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, + llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, addr->sllc_mac); - rtnl_unlock(); + if (llc->dev) + dev_hold(llc->dev); + rcu_read_unlock(); if (!llc->dev) goto out; if (!addr->sllc_sap) { -- cgit v1.2.3-59-g8ed1b From 38f49e8801565674c424896c3dcb4228410b43a8 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Mon, 6 Dec 2010 00:59:40 +0000 Subject: via-rhine: hardware VLAN support This patch adds VLAN hardware support for Rhine chips. The driver uses up to 3 additional bytes of buffer space when extracting 802.1Q headers; PKT_BUF_SZ should still be sufficient. The initial code was provided by David Lv. I reworked it to use standard kernel facilities. Coding style clean up mostly follows via-velocity. Adapted to new interface for VLAN acceleration (per request of Jesse Gross). Signed-off-by: David Lv Signed-off-by: Roger Luethi drivers/net/via-rhine.c | 326 +++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 312 insertions(+), 14 deletions(-) Signed-off-by: David S. Miller --- drivers/net/via-rhine.c | 326 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 312 insertions(+), 14 deletions(-) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 4930f9dbc493..5e7f069eab53 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -30,8 +30,8 @@ */ #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.4.3" -#define DRV_RELDATE "2007-03-06" +#define DRV_VERSION "1.5.0" +#define DRV_RELDATE "2010-10-09" /* A few user-configurable values. @@ -100,6 +100,7 @@ static const int multicast_filter_limit = 32; #include #include #include +#include #include #include #include /* Processor type for cache alignment. */ @@ -133,6 +134,9 @@ MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)"); MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)"); +#define MCAM_SIZE 32 +#define VCAM_SIZE 32 + /* Theory of Operation @@ -279,15 +283,16 @@ MODULE_DEVICE_TABLE(pci, rhine_pci_tbl); /* Offsets to the device registers. */ enum register_offsets { StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08, - ChipCmd1=0x09, + ChipCmd1=0x09, TQWake=0x0A, IntrStatus=0x0C, IntrEnable=0x0E, MulticastFilter0=0x10, MulticastFilter1=0x14, RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54, - MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, + MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, PCIBusConfig1=0x6F, MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74, ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B, RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81, StickyHW=0x83, IntrStatus2=0x84, + CamMask=0x88, CamCon=0x92, CamAddr=0x93, WOLcrSet=0xA0, PwcfgSet=0xA1, WOLcgSet=0xA3, WOLcrClr=0xA4, WOLcrClr1=0xA6, WOLcgClr=0xA7, PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD, @@ -299,6 +304,40 @@ enum backoff_bits { BackCaptureEffect=0x04, BackRandom=0x08 }; +/* Bits in the TxConfig (TCR) register */ +enum tcr_bits { + TCR_PQEN=0x01, + TCR_LB0=0x02, /* loopback[0] */ + TCR_LB1=0x04, /* loopback[1] */ + TCR_OFSET=0x08, + TCR_RTGOPT=0x10, + TCR_RTFT0=0x20, + TCR_RTFT1=0x40, + TCR_RTSF=0x80, +}; + +/* Bits in the CamCon (CAMC) register */ +enum camcon_bits { + CAMC_CAMEN=0x01, + CAMC_VCAMSL=0x02, + CAMC_CAMWR=0x04, + CAMC_CAMRD=0x08, +}; + +/* Bits in the PCIBusConfig1 (BCR1) register */ +enum bcr1_bits { + BCR1_POT0=0x01, + BCR1_POT1=0x02, + BCR1_POT2=0x04, + BCR1_CTFT0=0x08, + BCR1_CTFT1=0x10, + BCR1_CTSF=0x20, + BCR1_TXQNOBK=0x40, /* for VT6105 */ + BCR1_VIDFR=0x80, /* for VT6105 */ + BCR1_MED0=0x40, /* for VT6102 */ + BCR1_MED1=0x80, /* for VT6102 */ +}; + #ifdef USE_MMIO /* Registers we check that mmio and reg are the same. */ static const int mmio_verify_registers[] = { @@ -356,6 +395,11 @@ enum desc_status_bits { DescOwn=0x80000000 }; +/* Bits in *_desc.*_length */ +enum desc_length_bits { + DescTag=0x00010000 +}; + /* Bits in ChipCmd. */ enum chip_cmd_bits { CmdInit=0x01, CmdStart=0x02, CmdStop=0x04, CmdRxOn=0x08, @@ -365,6 +409,9 @@ enum chip_cmd_bits { }; struct rhine_private { + /* Bit mask for configured VLAN ids */ + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; + /* Descriptor rings */ struct rx_desc *rx_ring; struct tx_desc *tx_ring; @@ -405,6 +452,23 @@ struct rhine_private { void __iomem *base; }; +#define BYTE_REG_BITS_ON(x, p) do { iowrite8((ioread8((p))|(x)), (p)); } while (0) +#define WORD_REG_BITS_ON(x, p) do { iowrite16((ioread16((p))|(x)), (p)); } while (0) +#define DWORD_REG_BITS_ON(x, p) do { iowrite32((ioread32((p))|(x)), (p)); } while (0) + +#define BYTE_REG_BITS_IS_ON(x, p) (ioread8((p)) & (x)) +#define WORD_REG_BITS_IS_ON(x, p) (ioread16((p)) & (x)) +#define DWORD_REG_BITS_IS_ON(x, p) (ioread32((p)) & (x)) + +#define BYTE_REG_BITS_OFF(x, p) do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0) +#define WORD_REG_BITS_OFF(x, p) do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0) +#define DWORD_REG_BITS_OFF(x, p) do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0) + +#define BYTE_REG_BITS_SET(x, m, p) do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0) +#define WORD_REG_BITS_SET(x, m, p) do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0) +#define DWORD_REG_BITS_SET(x, m, p) do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0) + + static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int rhine_open(struct net_device *dev); @@ -422,6 +486,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops netdev_ethtool_ops; static int rhine_close(struct net_device *dev); static void rhine_shutdown (struct pci_dev *pdev); +static void rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid); +static void rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid); +static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr); +static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr); +static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask); +static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask); +static void rhine_init_cam_filter(struct net_device *dev); +static void rhine_update_vcam(struct net_device *dev); #define RHINE_WAIT_FOR(condition) do { \ int i=1024; \ @@ -629,6 +701,8 @@ static const struct net_device_ops rhine_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = rhine_tx_timeout, + .ndo_vlan_rx_add_vid = rhine_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = rhine_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = rhine_poll, #endif @@ -795,6 +869,10 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; + if (pdev->revision >= VT6105M) + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; + /* dev->name not defined before register_netdev()! */ rc = register_netdev(dev); if (rc) @@ -1040,6 +1118,167 @@ static void rhine_set_carrier(struct mii_if_info *mii) netif_carrier_ok(mii->dev)); } +/** + * rhine_set_cam - set CAM multicast filters + * @ioaddr: register block of this Rhine + * @idx: multicast CAM index [0..MCAM_SIZE-1] + * @addr: multicast address (6 bytes) + * + * Load addresses into multicast filters. + */ +static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr) +{ + int i; + + iowrite8(CAMC_CAMEN, ioaddr + CamCon); + wmb(); + + /* Paranoid -- idx out of range should never happen */ + idx &= (MCAM_SIZE - 1); + + iowrite8((u8) idx, ioaddr + CamAddr); + + for (i = 0; i < 6; i++, addr++) + iowrite8(*addr, ioaddr + MulticastFilter0 + i); + udelay(10); + wmb(); + + iowrite8(CAMC_CAMWR | CAMC_CAMEN, ioaddr + CamCon); + udelay(10); + + iowrite8(0, ioaddr + CamCon); +} + +/** + * rhine_set_vlan_cam - set CAM VLAN filters + * @ioaddr: register block of this Rhine + * @idx: VLAN CAM index [0..VCAM_SIZE-1] + * @addr: VLAN ID (2 bytes) + * + * Load addresses into VLAN filters. + */ +static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr) +{ + iowrite8(CAMC_CAMEN | CAMC_VCAMSL, ioaddr + CamCon); + wmb(); + + /* Paranoid -- idx out of range should never happen */ + idx &= (VCAM_SIZE - 1); + + iowrite8((u8) idx, ioaddr + CamAddr); + + iowrite16(*((u16 *) addr), ioaddr + MulticastFilter0 + 6); + udelay(10); + wmb(); + + iowrite8(CAMC_CAMWR | CAMC_CAMEN, ioaddr + CamCon); + udelay(10); + + iowrite8(0, ioaddr + CamCon); +} + +/** + * rhine_set_cam_mask - set multicast CAM mask + * @ioaddr: register block of this Rhine + * @mask: multicast CAM mask + * + * Mask sets multicast filters active/inactive. + */ +static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask) +{ + iowrite8(CAMC_CAMEN, ioaddr + CamCon); + wmb(); + + /* write mask */ + iowrite32(mask, ioaddr + CamMask); + + /* disable CAMEN */ + iowrite8(0, ioaddr + CamCon); +} + +/** + * rhine_set_vlan_cam_mask - set VLAN CAM mask + * @ioaddr: register block of this Rhine + * @mask: VLAN CAM mask + * + * Mask sets VLAN filters active/inactive. + */ +static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask) +{ + iowrite8(CAMC_CAMEN | CAMC_VCAMSL, ioaddr + CamCon); + wmb(); + + /* write mask */ + iowrite32(mask, ioaddr + CamMask); + + /* disable CAMEN */ + iowrite8(0, ioaddr + CamCon); +} + +/** + * rhine_init_cam_filter - initialize CAM filters + * @dev: network device + * + * Initialize (disable) hardware VLAN and multicast support on this + * Rhine. + */ +static void rhine_init_cam_filter(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + void __iomem *ioaddr = rp->base; + + /* Disable all CAMs */ + rhine_set_vlan_cam_mask(ioaddr, 0); + rhine_set_cam_mask(ioaddr, 0); + + /* disable hardware VLAN support */ + BYTE_REG_BITS_ON(TCR_PQEN, ioaddr + TxConfig); + BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1); +} + +/** + * rhine_update_vcam - update VLAN CAM filters + * @rp: rhine_private data of this Rhine + * + * Update VLAN CAM filters to match configuration change. + */ +static void rhine_update_vcam(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + void __iomem *ioaddr = rp->base; + u16 vid; + u32 vCAMmask = 0; /* 32 vCAMs (6105M and better) */ + unsigned int i = 0; + + for_each_set_bit(vid, rp->active_vlans, VLAN_N_VID) { + rhine_set_vlan_cam(ioaddr, i, (u8 *)&vid); + vCAMmask |= 1 << i; + if (++i >= VCAM_SIZE) + break; + } + rhine_set_vlan_cam_mask(ioaddr, vCAMmask); +} + +static void rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) +{ + struct rhine_private *rp = netdev_priv(dev); + + spin_lock_irq(&rp->lock); + set_bit(vid, rp->active_vlans); + rhine_update_vcam(dev); + spin_unlock_irq(&rp->lock); +} + +static void rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct rhine_private *rp = netdev_priv(dev); + + spin_lock_irq(&rp->lock); + clear_bit(vid, rp->active_vlans); + rhine_update_vcam(dev); + spin_unlock_irq(&rp->lock); +} + static void init_registers(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); @@ -1061,6 +1300,9 @@ static void init_registers(struct net_device *dev) rhine_set_rx_mode(dev); + if (rp->pdev->revision >= VT6105M) + rhine_init_cam_filter(dev); + napi_enable(&rp->napi); /* Enable interrupts by setting the interrupt mask. */ @@ -1276,16 +1518,28 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, rp->tx_ring[entry].desc_length = cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + if (unlikely(vlan_tx_tag_present(skb))) { + rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + } + else + rp->tx_ring[entry].tx_status = 0; + /* lock eth irq */ spin_lock_irqsave(&rp->lock, flags); wmb(); - rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn); + rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn); wmb(); rp->cur_tx++; /* Non-x86 Todo: explicitly flush cache lines here. */ + if (vlan_tx_tag_present(skb)) + /* Tx queues are bits 7-0 (first Tx queue: bit 7) */ + BYTE_REG_BITS_ON(1 << 7, ioaddr + TQWake); + /* Wake the potentially-idle transmit channel */ iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand, ioaddr + ChipCmd1); @@ -1437,6 +1691,21 @@ static void rhine_tx(struct net_device *dev) spin_unlock(&rp->lock); } +/** + * rhine_get_vlan_tci - extract TCI from Rx data buffer + * @skb: pointer to sk_buff + * @data_size: used data area of the buffer including CRC + * + * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q + * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte + * aligned following the CRC. + */ +static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size) +{ + u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2; + return ntohs(*(u16 *)trailer); +} + /* Process up to limit frames from receive ring */ static int rhine_rx(struct net_device *dev, int limit) { @@ -1454,6 +1723,7 @@ static int rhine_rx(struct net_device *dev, int limit) for (count = 0; count < limit; ++count) { struct rx_desc *desc = rp->rx_head_desc; u32 desc_status = le32_to_cpu(desc->rx_status); + u32 desc_length = le32_to_cpu(desc->desc_length); int data_size = desc_status >> 16; if (desc_status & DescOwn) @@ -1498,6 +1768,7 @@ static int rhine_rx(struct net_device *dev, int limit) struct sk_buff *skb = NULL; /* Length should omit the CRC */ int pkt_len = data_size - 4; + u16 vlan_tci = 0; /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ @@ -1532,7 +1803,14 @@ static int rhine_rx(struct net_device *dev, int limit) rp->rx_buf_sz, PCI_DMA_FROMDEVICE); } + + if (unlikely(desc_length & DescTag)) + vlan_tci = rhine_get_vlan_tci(skb, data_size); + skb->protocol = eth_type_trans(skb, dev); + + if (unlikely(desc_length & DescTag)) + __vlan_hwaccel_put_tag(skb, vlan_tci); netif_receive_skb(skb); dev->stats.rx_bytes += pkt_len; dev->stats.rx_packets++; @@ -1596,6 +1874,11 @@ static void rhine_restart_tx(struct net_device *dev) { iowrite8(ioread8(ioaddr + ChipCmd) | CmdTxOn, ioaddr + ChipCmd); + + if (rp->tx_ring[entry].desc_length & cpu_to_le32(0x020000)) + /* Tx queues are bits 7-0 (first Tx queue: bit 7) */ + BYTE_REG_BITS_ON(1 << 7, ioaddr + TQWake); + iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand, ioaddr + ChipCmd1); IOSYNC; @@ -1631,7 +1914,7 @@ static void rhine_error(struct net_device *dev, int intr_status) } if (intr_status & IntrTxUnderrun) { if (rp->tx_thresh < 0xE0) - iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig); + BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig); if (debug > 1) printk(KERN_INFO "%s: Transmitter underrun, Tx " "threshold now %2.2x.\n", @@ -1646,7 +1929,7 @@ static void rhine_error(struct net_device *dev, int intr_status) (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace)) == 0) { if (rp->tx_thresh < 0xE0) { - iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig); + BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig); } if (debug > 1) printk(KERN_INFO "%s: Unspecified error. Tx " @@ -1688,7 +1971,8 @@ static void rhine_set_rx_mode(struct net_device *dev) struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; u32 mc_filter[2]; /* Multicast hash filter */ - u8 rx_mode; /* Note: 0x02=accept runt, 0x01=accept errs */ + u8 rx_mode = 0x0C; /* Note: 0x02=accept runt, 0x01=accept errs */ + struct netdev_hw_addr *ha; if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ rx_mode = 0x1C; @@ -1699,10 +1983,18 @@ static void rhine_set_rx_mode(struct net_device *dev) /* Too many to match, or accept all multicasts. */ iowrite32(0xffffffff, ioaddr + MulticastFilter0); iowrite32(0xffffffff, ioaddr + MulticastFilter1); - rx_mode = 0x0C; + } else if (rp->pdev->revision >= VT6105M) { + int i = 0; + u32 mCAMmask = 0; /* 32 mCAMs (6105M and better) */ + netdev_for_each_mc_addr(ha, dev) { + if (i == MCAM_SIZE) + break; + rhine_set_cam(ioaddr, i, ha->addr); + mCAMmask |= 1 << i; + i++; + } + rhine_set_cam_mask(ioaddr, mCAMmask); } else { - struct netdev_hw_addr *ha; - memset(mc_filter, 0, sizeof(mc_filter)); netdev_for_each_mc_addr(ha, dev) { int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; @@ -1711,9 +2003,15 @@ static void rhine_set_rx_mode(struct net_device *dev) } iowrite32(mc_filter[0], ioaddr + MulticastFilter0); iowrite32(mc_filter[1], ioaddr + MulticastFilter1); - rx_mode = 0x0C; } - iowrite8(rp->rx_thresh | rx_mode, ioaddr + RxConfig); + /* enable/disable VLAN receive filtering */ + if (rp->pdev->revision >= VT6105M) { + if (dev->flags & IFF_PROMISC) + BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1); + else + BYTE_REG_BITS_ON(BCR1_VIDFR, ioaddr + PCIBusConfig1); + } + BYTE_REG_BITS_ON(rx_mode, ioaddr + RxConfig); } static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -1966,7 +2264,7 @@ static int rhine_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; - if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev)) + if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev)) printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name); ret = pci_set_power_state(pdev, PCI_D0); -- cgit v1.2.3-59-g8ed1b From 62ab0812137ec4f9884dd7de346238841ac03283 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Dec 2010 20:50:09 +0000 Subject: filter: constify sk_run_filter() sk_run_filter() doesnt write on skb, change its prototype to reflect this. Fix two af_packet comments. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/filter.h | 2 +- net/core/filter.c | 7 ++++--- net/core/timestamping.c | 2 +- net/packet/af_packet.c | 31 ++++++++++++++++--------------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 5334adaf4072..45266b75409a 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -148,7 +148,7 @@ struct sk_buff; struct sock; extern int sk_filter(struct sock *sk, struct sk_buff *skb); -extern unsigned int sk_run_filter(struct sk_buff *skb, +extern unsigned int sk_run_filter(const struct sk_buff *skb, const struct sock_filter *filter); extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); diff --git a/net/core/filter.c b/net/core/filter.c index ac4920a87be5..25500f16a18a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -88,7 +88,7 @@ enum { }; /* No hurry in this branch */ -static void *__load_pointer(struct sk_buff *skb, int k) +static void *__load_pointer(const struct sk_buff *skb, int k) { u8 *ptr = NULL; @@ -102,7 +102,7 @@ static void *__load_pointer(struct sk_buff *skb, int k) return NULL; } -static inline void *load_pointer(struct sk_buff *skb, int k, +static inline void *load_pointer(const struct sk_buff *skb, int k, unsigned int size, void *buffer) { if (k >= 0) @@ -160,7 +160,8 @@ EXPORT_SYMBOL(sk_filter); * and last instruction guaranteed to be a RET, we dont need to check * flen. (We used to pass to this function the length of filter) */ -unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry) +unsigned int sk_run_filter(const struct sk_buff *skb, + const struct sock_filter *fentry) { void *ptr; u32 A = 0; /* Accumulator */ diff --git a/net/core/timestamping.c b/net/core/timestamping.c index dac7ed687f60..b124d28ff1c8 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c @@ -26,7 +26,7 @@ static struct sock_filter ptp_filter[] = { PTP_FILTER }; -static unsigned int classify(struct sk_buff *skb) +static unsigned int classify(const struct sk_buff *skb) { if (likely(skb->dev && skb->dev->phydev && diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a11c731d2ee4..17eafe5b48c6 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -517,7 +517,8 @@ out_free: return err; } -static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, +static inline unsigned int run_filter(const struct sk_buff *skb, + const struct sock *sk, unsigned int res) { struct sk_filter *filter; @@ -532,15 +533,15 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, } /* - This function makes lazy skb cloning in hope that most of packets - are discarded by BPF. - - Note tricky part: we DO mangle shared skb! skb->data, skb->len - and skb->cb are mangled. It works because (and until) packets - falling here are owned by current CPU. Output packets are cloned - by dev_queue_xmit_nit(), input packets are processed by net_bh - sequencially, so that if we return skb to original state on exit, - we will not harm anyone. + * This function makes lazy skb cloning in hope that most of packets + * are discarded by BPF. + * + * Note tricky part: we DO mangle shared skb! skb->data, skb->len + * and skb->cb are mangled. It works because (and until) packets + * falling here are owned by current CPU. Output packets are cloned + * by dev_queue_xmit_nit(), input packets are processed by net_bh + * sequencially, so that if we return skb to original state on exit, + * we will not harm anyone. */ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, @@ -566,11 +567,11 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, if (dev->header_ops) { /* The device has an explicit notion of ll header, - exported to higher levels. - - Otherwise, the device hides datails of it frame - structure, so that corresponding packet head - never delivered to user. + * exported to higher levels. + * + * Otherwise, the device hides details of its frame + * structure, so that corresponding packet head is + * never delivered to user. */ if (sk->sk_type != SOCK_DGRAM) skb_push(skb, skb->data - skb_mac_header(skb)); -- cgit v1.2.3-59-g8ed1b From 15c2d75f49189e1769c5e8f5f099d03d055c4910 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 7 Dec 2010 00:30:37 +0000 Subject: net: call dev_queue_xmit_nit() after skb_dst_drop() Avoid some atomic ops on dst refcount, calling dev_queue_xmit_nit() after skb_dst_drop() in dev_hard_start_xmit(). When queueing a packet into af_packet socket, we drop dst anyway. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 822b15b8d11c..d28b3a023bb2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2022,9 +2022,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, int rc = NETDEV_TX_OK; if (likely(!skb->next)) { - if (!list_empty(&ptype_all)) - dev_queue_xmit_nit(skb, dev); - /* * If device doesnt need skb->dst, release it right now while * its hot in this cpu cache @@ -2032,6 +2029,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (dev->priv_flags & IFF_XMIT_DST_RELEASE) skb_dst_drop(skb); + if (!list_empty(&ptype_all)) + dev_queue_xmit_nit(skb, dev); + skb_orphan_try(skb); if (vlan_tx_tag_present(skb) && -- cgit v1.2.3-59-g8ed1b From f6dafa95d1a48f73ab4a5b0f7dc0dcb72817e051 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 7 Dec 2010 04:26:16 +0000 Subject: af_packet: eliminate pgv_to_page on some arches Some arches don't need flush_dcache_page(), and don't implement it, so we can eliminate pgv_to_page() calls on those arches. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/packet/af_packet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 17eafe5b48c6..9292ec93eb52 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -223,7 +223,7 @@ struct packet_skb_cb { #define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) -static inline struct page *pgv_to_page(void *addr) +static inline __pure struct page *pgv_to_page(void *addr) { if (is_vmalloc_addr(addr)) return vmalloc_to_page(addr); @@ -806,6 +806,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, __packet_set_status(po, h.raw, status); smp_mb(); +#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1 { u8 *start, *end; @@ -813,6 +814,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, for (start = h.raw; start < end; start += PAGE_SIZE) flush_dcache_page(pgv_to_page(start)); } +#endif sk->sk_data_ready(sk, 0); -- cgit v1.2.3-59-g8ed1b From 920b8d913bd3d963d5c88bca160a272b71e0c95a Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 7 Dec 2010 05:05:18 +0000 Subject: af_packet: fix freeing pg_vec twice on error path It is introduced in: commit 0e3125c755445664f00ad036e4fc2cd32fd52877 Author: Neil Horman Date: Tue Nov 16 10:26:47 2010 -0800 packet: Enhance AF_PACKET implementation to not require high order contiguous memory allocation (v4) Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/packet/af_packet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9292ec93eb52..246a04a13234 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2409,7 +2409,6 @@ out: out_free_pgvec: free_pg_vec(pg_vec, order, block_nr); - kfree(pg_vec); pg_vec = NULL; goto out; } -- cgit v1.2.3-59-g8ed1b From f8bf5681cf15f77692c8ad8cb95d059ff7c622c9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 7 Dec 2010 04:49:06 +0000 Subject: isdn/hisax: fix compiler warning on hisax_pci_tbl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Annotate hisax_pci_tbl as '__used' to fix following warning: CC drivers/isdn/hisax/config.o drivers/isdn/hisax/config.c:1920: warning: ‘hisax_pci_tbl’ defined but not used Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- drivers/isdn/hisax/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index b133378d4dc9..c110f8679bab 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1917,7 +1917,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) #ifdef CONFIG_PCI #include -static struct pci_device_id hisax_pci_tbl[] __devinitdata = { +static struct pci_device_id hisax_pci_tbl[] __devinitdata __used = { #ifdef CONFIG_HISAX_FRITZPCI {PCI_VDEVICE(AVM, PCI_DEVICE_ID_AVM_A1) }, #endif -- cgit v1.2.3-59-g8ed1b From 50b12f597be354a5a224f05c65c54c0667e57aec Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 19 Nov 2010 12:40:25 +0100 Subject: cfg80211: Add new BSS attribute ht_opmode Add a new BSS attribute to allow hostapd to set the current HT opmode. Otherwise drivers won't be able to set up protection for HT rates in AP mode. Cc: Johannes Berg Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/cfg80211.h | 3 +++ net/wireless/nl80211.c | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 8e28053ea423..380421253d16 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -849,6 +849,8 @@ enum nl80211_commands { * flag isn't set, the frame will be rejected. This is also used as an * nl80211 capability flag. * + * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1025,6 +1027,8 @@ enum nl80211_attrs { NL80211_ATTR_OFFCHANNEL_TX_OK, + NL80211_ATTR_BSS_HT_OPMODE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8764c9a5bab7..0d5979924be3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -605,6 +605,8 @@ struct mpath_info { * (or NULL for no change) * @basic_rates_len: number of basic rates * @ap_isolate: do not forward packets between connected stations + * @ht_opmode: HT Operation mode + * (u16 = opmode, -1 = do not change) */ struct bss_parameters { int use_cts_prot; @@ -613,6 +615,7 @@ struct bss_parameters { u8 *basic_rates; u8 basic_rates_len; int ap_isolate; + int ht_opmode; }; /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2cf03331d4a2..c3f80e565365 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -121,6 +121,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 }, [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY, .len = NL80211_MAX_SUPP_RATES }, + [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, @@ -2462,6 +2463,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) params.use_short_preamble = -1; params.use_short_slot_time = -1; params.ap_isolate = -1; + params.ht_opmode = -1; if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) params.use_cts_prot = @@ -2480,6 +2482,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_AP_ISOLATE]) params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); + if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE]) + params.ht_opmode = + nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]); if (!rdev->ops->change_bss) return -EOPNOTSUPP; -- cgit v1.2.3-59-g8ed1b From 80d7e403c97b712e302ec37e9beceff1dbdc9402 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 19 Nov 2010 12:40:26 +0100 Subject: mac80211: Apply ht_opmode changes in ieee80211_change_bss Cc: Johannes Berg Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index af9620406321..c30b8b72eedb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1134,6 +1134,12 @@ static int ieee80211_change_bss(struct wiphy *wiphy, sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; } + if (params->ht_opmode >= 0) { + sdata->vif.bss_conf.ht_operation_mode = + (u16) params->ht_opmode; + changed |= BSS_CHANGED_HT; + } + ieee80211_bss_info_change_notify(sdata, changed); return 0; -- cgit v1.2.3-59-g8ed1b From a9927ba3c5f3c5f6b0e8fa7557452335edeaf5fa Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 6 Dec 2010 21:13:49 -0800 Subject: ath9k: Check for NULL sta in ath_tx_start It can be NULL according to docs, and logging showed it to be NULL in practice. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 16d83d0c0959..bce313e85cff 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1740,7 +1740,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, int frmlen = skb->len + FCS_LEN; int q; - txctl->an = (struct ath_node *)sta->drv_priv; + /* NOTE: sta can be NULL according to net/mac80211.h */ + if (sta) + txctl->an = (struct ath_node *)sta->drv_priv; + if (info->control.hw_key) frmlen += info->control.hw_key->icv_len; -- cgit v1.2.3-59-g8ed1b From 857581bdf1a3b36bfd42609d6f5433bd83397127 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 09:42:04 +0100 Subject: b43: N-PHY: update init tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_nphy.c | 212 ++++++++++++++++----------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index d60db078eae2..46f0a7a77529 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -28,41 +28,41 @@ #include "phy_n.h" static const u8 b43_ntab_adjustpower0[] = { - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, - 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, - 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, - 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, - 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, - 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const u8 b43_ntab_adjustpower1[] = { - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, - 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, - 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, - 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, - 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, - 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const u16 b43_ntab_bdi[] = { @@ -130,8 +130,8 @@ static const u32 b43_ntab_framestruct[] = { 0x09804506, 0x00100030, 0x09804507, 0x00100030, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x08004A0C, 0x00100008, 0x01000A0D, 0x00100028, - 0x0980450E, 0x00100038, 0x0980450F, 0x00100038, + 0x08004A0C, 0x00100004, 0x01000A0D, 0x00100024, + 0x0980450E, 0x00100034, 0x0980450F, 0x00100034, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000A04, 0x00100000, 0x11008A05, 0x00100020, @@ -202,13 +202,13 @@ static const u32 b43_ntab_framestruct[] = { 0x53028A06, 0x01900060, 0x53028A07, 0x01900060, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x4002140C, 0x000F4810, 0x6203140D, 0x00100050, - 0x53028A0E, 0x01900070, 0x53028A0F, 0x01900070, + 0x4002140C, 0x000F4808, 0x6203140D, 0x00100048, + 0x53028A0E, 0x01900068, 0x53028A0F, 0x01900068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028, - 0x1980C50E, 0x00100038, 0x2181050E, 0x00100038, - 0x2181050E, 0x00100038, 0x0180050C, 0x00100038, + 0x00000A0C, 0x00100004, 0x11008A0D, 0x00100024, + 0x1980C50E, 0x00100034, 0x2181050E, 0x00100034, + 0x2181050E, 0x00100034, 0x0180050C, 0x00100038, 0x1180850D, 0x00100038, 0x1181850D, 0x00100038, 0x2981450F, 0x01100038, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -238,9 +238,9 @@ static const u32 b43_ntab_framestruct[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x4002140C, 0x00100010, 0x0200140D, 0x00100050, - 0x0B004A0E, 0x01900070, 0x13008A0E, 0x01900070, - 0x13008A0E, 0x01900070, 0x43020A0C, 0x00100070, + 0x4002140C, 0x00100008, 0x0200140D, 0x00100048, + 0x0B004A0E, 0x01900068, 0x13008A0E, 0x01900068, + 0x13008A0E, 0x01900068, 0x43020A0C, 0x00100070, 0x1B00CA0D, 0x00100070, 0x1B014A0D, 0x00100070, 0x23010A0F, 0x01500070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -337,73 +337,73 @@ static const u32 b43_ntab_framestruct[] = { }; static const u32 b43_ntab_gainctl0[] = { - 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, - 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, - 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, - 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38, - 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336, - 0x006B0435, 0x006A0535, 0x00690634, 0x00680734, - 0x00670833, 0x00660933, 0x00650A32, 0x00640B32, - 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30, - 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E, - 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C, - 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A, - 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28, - 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326, - 0x004B0425, 0x004A0525, 0x00490624, 0x00480724, - 0x00470823, 0x00460923, 0x00450A22, 0x00440B22, - 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20, - 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E, - 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C, - 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A, - 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18, - 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316, - 0x002B0415, 0x002A0515, 0x00290614, 0x00280714, - 0x00270813, 0x00260913, 0x00250A12, 0x00240B12, - 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10, - 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E, - 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C, - 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A, - 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08, - 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306, - 0x000B0405, 0x000A0505, 0x00090604, 0x00080704, - 0x00070803, 0x00060903, 0x00050A02, 0x00040B02, - 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, + 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E, + 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42, + 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B, + 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34, + 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E, + 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38, + 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32, + 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44, + 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D, + 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36, + 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40, + 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39, + 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33, + 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D, + 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E, + 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38, + 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42, + 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B, + 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34, + 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44, + 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D, + 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36, + 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30, + 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B, + 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26, + 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22, + 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E, + 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B, + 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00, }; static const u32 b43_ntab_gainctl1[] = { - 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, - 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, - 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, - 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38, - 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336, - 0x006B0435, 0x006A0535, 0x00690634, 0x00680734, - 0x00670833, 0x00660933, 0x00650A32, 0x00640B32, - 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30, - 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E, - 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C, - 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A, - 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28, - 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326, - 0x004B0425, 0x004A0525, 0x00490624, 0x00480724, - 0x00470823, 0x00460923, 0x00450A22, 0x00440B22, - 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20, - 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E, - 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C, - 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A, - 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18, - 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316, - 0x002B0415, 0x002A0515, 0x00290614, 0x00280714, - 0x00270813, 0x00260913, 0x00250A12, 0x00240B12, - 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10, - 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E, - 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C, - 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A, - 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08, - 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306, - 0x000B0405, 0x000A0505, 0x00090604, 0x00080704, - 0x00070803, 0x00060903, 0x00050A02, 0x00040B02, - 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, + 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E, + 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42, + 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B, + 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34, + 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E, + 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38, + 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32, + 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44, + 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D, + 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36, + 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40, + 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39, + 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33, + 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D, + 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E, + 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38, + 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42, + 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B, + 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34, + 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44, + 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D, + 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36, + 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30, + 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B, + 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26, + 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22, + 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E, + 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B, + 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18, + 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00, }; static const u32 b43_ntab_intlevel[] = { -- cgit v1.2.3-59-g8ed1b From f00fe7f6d14ab7bbd4655f55eae71bbd73ef766d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 09:42:05 +0100 Subject: b43: N-PHY: reorder and optimize tables initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Order was changed in specs. For writing arrays we have designed bulk function which makes use of auto increment and do not write table address over and over. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_nphy.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 46f0a7a77529..df61c1610e39 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -1811,9 +1811,7 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, } #define ntab_upload(dev, offset, data) do { \ - unsigned int i; \ - for (i = 0; i < (offset##_SIZE); i++) \ - b43_ntab_write(dev, (offset) + i, (data)[i]); \ + b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \ } while (0) void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) @@ -1825,18 +1823,18 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn); ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel); ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot); - ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0); ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1); ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0); ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1); - ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest); ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs); - - /* Volatile tables */ ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10); ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11); + + /* Volatile tables */ + ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); + ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); -- cgit v1.2.3-59-g8ed1b From 755fd183b89bc8a302669b6f35cd98faee473f7a Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 09:42:06 +0100 Subject: b43: N-PHY: implement own maskset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This let us avoid double addressing while still having reg check. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 905f1d7bac20..f78f4e96defa 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3705,6 +3705,15 @@ static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) b43_write16(dev, B43_MMIO_PHY_DATA, value); } +static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, + u16 set) +{ + check_phyreg(dev, reg); + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, + (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); +} + static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) { /* Register 1 is a 32-bit register. */ @@ -3799,6 +3808,7 @@ const struct b43_phy_operations b43_phyops_n = { .init = b43_nphy_op_init, .phy_read = b43_nphy_op_read, .phy_write = b43_nphy_op_write, + .phy_maskset = b43_nphy_op_maskset, .radio_read = b43_nphy_op_radio_read, .radio_write = b43_nphy_op_radio_write, .software_rfkill = b43_nphy_op_software_rfkill, -- cgit v1.2.3-59-g8ed1b From 155180803c95c7b14b355f60431bef45116c151e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 09:42:07 +0100 Subject: b43: flush PHY writes when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.c | 5 +++++ drivers/net/wireless/b43/phy_common.h | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index fa7f83fc8db9..0a91fc3a2e03 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -231,6 +231,7 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) u16 b43_phy_read(struct b43_wldev *dev, u16 reg) { assert_mac_suspended(dev); + dev->phy.writes_counter = 0; return dev->phy.ops->phy_read(dev, reg); } @@ -238,6 +239,10 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) { assert_mac_suspended(dev); dev->phy.ops->phy_write(dev, reg, value); + if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) { + b43_read16(dev, B43_MMIO_PHY_VER); + dev->phy.writes_counter = 0; + } } void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 0e6194228845..2ed60e5484b6 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -39,6 +39,9 @@ struct b43_c32 { s32 i, q; }; #define B43_PHYVER_TYPE_SHIFT 8 #define B43_PHYVER_VERSION 0x00FF +/* PHY writes need to be flushed if we reach limit */ +#define B43_MAX_WRITES_IN_ROW 24 + /** * enum b43_interference_mitigation - Interference Mitigation mode * @@ -232,6 +235,9 @@ struct b43_phy { /* PHY revision number. */ u8 rev; + /* Count writes since last read */ + u8 writes_counter; + /* Radio versioning */ u16 radio_manuf; /* Radio manufacturer */ u16 radio_ver; /* Radio version */ -- cgit v1.2.3-59-g8ed1b From 2f886750118c1781d3b53268bf25519aef1d4d71 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 7 Dec 2010 11:27:01 -0800 Subject: mac80211: Show max number of probe tries in debug message. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- net/mac80211/work.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 2b5c3f267198..de43753076d2 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -458,8 +458,9 @@ ieee80211_direct_probe(struct ieee80211_work *wk) return WORK_ACT_TIMEOUT; } - printk(KERN_DEBUG "%s: direct probe to %pM (try %d)\n", - sdata->name, wk->filter_ta, wk->probe_auth.tries); + printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n", + sdata->name, wk->filter_ta, wk->probe_auth.tries, + IEEE80211_AUTH_MAX_TRIES); /* * Direct probe is sent to broadcast address as some APs -- cgit v1.2.3-59-g8ed1b From c7455cf988f06ba578cc6a680392426fce382ca1 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 21:55:57 +0100 Subject: b43: N-PHY: silence warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f78f4e96defa..d41da7f5584a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -258,7 +258,8 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) for (i = 0; i < 2; i++) { if (dev->phy.rev >= 3) { - /* TODO */ + /* FIXME: support 5GHz */ + txgain = b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; radio_gain = (txgain >> 16) & 0x1FFFF; } else { txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; @@ -613,6 +614,8 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write, } } +#if 0 +/* Ready but not used anywhere */ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */ static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) { @@ -694,6 +697,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1)); b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core)); } +#endif /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) @@ -3088,7 +3092,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, u8 rfctl[2]; u8 afectl_core; u16 tmp[6]; - u16 cur_hpf1, cur_hpf2, cur_lna; + u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna; u32 real, imag; enum ieee80211_band band; -- cgit v1.2.3-59-g8ed1b From abc1f7cd531f80a8468ab654f1dfd35d58bd2490 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 21:55:58 +0100 Subject: b43: set TMS to work with current band width for N-PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 6 ++++++ drivers/net/wireless/b43/phy_common.c | 7 +++++++ drivers/net/wireless/b43/phy_common.h | 2 ++ drivers/net/wireless/b43/phy_n.c | 7 ------- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index fa4880366586..670fd7b782e2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1150,6 +1150,12 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; + if (dev->phy.type == B43_PHYTYPE_N) { + if (b43_channel_type_is_40mhz(dev->phy.channel_type)) + flags |= B43_TMSLOW_PHYCLKSPEED_160MHZ; + else + flags |= B43_TMSLOW_PHYCLKSPEED_80MHZ; + } ssb_device_enable(dev->dev, flags); msleep(2); /* Wait for the PLL to turn on. */ diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 0a91fc3a2e03..412f1b64cc82 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -429,6 +429,13 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); } + +bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type) +{ + return (channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ struct b43_c32 b43_cordic(int theta) { diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 2ed60e5484b6..2401bee8b081 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -436,6 +436,8 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset); */ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); +bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type); + struct b43_c32 b43_cordic(int theta); #endif /* LINUX_B43_PHY_COMMON_H_ */ diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d41da7f5584a..35173419d139 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -88,13 +88,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); -static inline bool b43_channel_type_is_40mhz( - enum nl80211_channel_type channel_type) -{ - return (channel_type == NL80211_CHAN_HT40MINUS || - channel_type == NL80211_CHAN_HT40PLUS); -} - void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) {//TODO } -- cgit v1.2.3-59-g8ed1b From 82a52043c7801f83c7387deb45bf9323af04644b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 21:55:59 +0100 Subject: b43: fix split of N-PHY devices into supported and not (based on PHY rev) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43/phy_n.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 670fd7b782e2..4d97aac38df0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4054,7 +4054,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) break; #ifdef CONFIG_B43_NPHY case B43_PHYTYPE_N: - if (phy_rev > 4) + if (phy_rev > 2) unsupported = 1; break; #endif diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 35173419d139..61875c888278 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3515,7 +3515,6 @@ int b43_phy_initn(struct b43_wldev *dev) if (phy->rev >= 3) b43_nphy_spur_workaround(dev); - b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); return 0; } -- cgit v1.2.3-59-g8ed1b From 692d2c0fb36c02ad07d54641c26f48e644b27fbd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 7 Dec 2010 21:56:00 +0100 Subject: b43: rename config option for N-PHY, drop BROKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 13 +++++++------ drivers/net/wireless/b43/Makefile | 8 ++++---- drivers/net/wireless/b43/main.c | 4 ++-- drivers/net/wireless/b43/phy_common.c | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 0a00d42642cd..47033f6a1c2b 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -86,15 +86,16 @@ config B43_PIO select SSB_BLOCKIO default y -config B43_NPHY - bool "Pre IEEE 802.11n support (BROKEN)" - depends on B43 && EXPERIMENTAL && BROKEN +config B43_PHY_N + bool "Support for 802.11n (N-PHY) devices (EXPERIMENTAL)" + depends on B43 && EXPERIMENTAL ---help--- - Support for the IEEE 802.11n draft. + Support for the N-PHY. - THIS IS BROKEN AND DOES NOT WORK YET. + This enables support for devices with N-PHY revision up to 2. - SAY N. + Say N if you expect high stability and performance. Saying Y will not + affect other devices support and may provide support for basic needs. config B43_PHY_LP bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)" diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 69d4af09a6cb..cef334a8c669 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -1,12 +1,12 @@ b43-y += main.o b43-y += tables.o -b43-$(CONFIG_B43_NPHY) += tables_nphy.o -b43-$(CONFIG_B43_NPHY) += radio_2055.o -b43-$(CONFIG_B43_NPHY) += radio_2056.o +b43-$(CONFIG_B43_PHY_N) += tables_nphy.o +b43-$(CONFIG_B43_PHY_N) += radio_2055.o +b43-$(CONFIG_B43_PHY_N) += radio_2056.o b43-y += phy_common.o b43-y += phy_g.o b43-y += phy_a.o -b43-$(CONFIG_B43_NPHY) += phy_n.o +b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o b43-y += sysfs.o diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4d97aac38df0..9ae3f619e98d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4052,7 +4052,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (phy_rev > 9) unsupported = 1; break; -#ifdef CONFIG_B43_NPHY +#ifdef CONFIG_B43_PHY_N case B43_PHYTYPE_N: if (phy_rev > 2) unsupported = 1; @@ -5097,7 +5097,7 @@ static void b43_print_driverinfo(void) #ifdef CONFIG_B43_PCMCIA feat_pcmcia = "M"; #endif -#ifdef CONFIG_B43_NPHY +#ifdef CONFIG_B43_PHY_N feat_nphy = "N"; #endif #ifdef CONFIG_B43_LEDS diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 412f1b64cc82..b5c5ce94d3fd 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -50,7 +50,7 @@ int b43_phy_allocate(struct b43_wldev *dev) phy->ops = &b43_phyops_g; break; case B43_PHYTYPE_N: -#ifdef CONFIG_B43_NPHY +#ifdef CONFIG_B43_PHY_N phy->ops = &b43_phyops_n; #endif break; -- cgit v1.2.3-59-g8ed1b From b7e8941b2df518186d9f7679c007f6b619bb4e89 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 7 Dec 2010 13:43:03 -0800 Subject: cfg80211: add some element IDs in enum ieee80211_eid 1)WLAN_EID_BSS_COEX_2040 2)WLAN_EID_OVERLAP_BSS_SCAN_PARAM 3)WLAN_EID_EXT_CAPABILITY Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index ed5a03cbe184..351c0ab4e284 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1223,6 +1223,9 @@ enum ieee80211_eid { WLAN_EID_BSS_AC_ACCESS_DELAY = 68, WLAN_EID_RRM_ENABLED_CAPABILITIES = 70, WLAN_EID_MULTIPLE_BSSID = 71, + WLAN_EID_BSS_COEX_2040 = 72, + WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74, + WLAN_EID_EXT_CAPABILITY = 127, WLAN_EID_MOBILITY_DOMAIN = 54, WLAN_EID_FAST_BSS_TRANSITION = 55, -- cgit v1.2.3-59-g8ed1b From ff9f0b639f33c92a89b0799263ab625444be6ee1 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 7 Dec 2010 15:13:22 -0800 Subject: ath9k: skip ATH9K_INT_TIM_TIMER when we are idle We should not be idle when we get the ATH9K_INT_TIM_TIMER, otherwise its a sign of something broken in our design with our idle state machine and mac80211. Skip these and WARN once just in case this is triggerable. Cc: Paul Stewart Cc: Amod Bodas signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3e0c8a1874b4..41a312a3d401 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -765,6 +765,8 @@ irqreturn_t ath_isr(int irq, void *dev) if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) if (status & ATH9K_INT_TIM_TIMER) { + if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle)) + goto chip_reset; /* Clear RxAbort bit so that we can * receive frames */ ath9k_setpower(sc, ATH9K_PM_AWAKE); -- cgit v1.2.3-59-g8ed1b From 69f4aab1157d2a386e7ea4de77cc253629d1b4f2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 7 Dec 2010 15:13:23 -0800 Subject: ath9k_hw: warn if we cannot change the power to the chip Suspend requires the device to be in fullsleep otherwise upon resume the device becomes unresponsive. We need to ensure that when we want the device to go to sleep it yields to the request, otherwise we'll have a useless devices upon resume. Warn when changing the power fails as we need to look into these issues. Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9f4398c88c85..516227fa668e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1608,6 +1608,13 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) } ah->power_mode = mode; + /* + * XXX: If this warning never comes up after a while then + * simply keep the ATH_DBG_WARN_ON_ONCE() but make + * ath9k_hw_setpower() return type void. + */ + ATH_DBG_WARN_ON_ONCE(!status); + return status; } EXPORT_SYMBOL(ath9k_hw_setpower); -- cgit v1.2.3-59-g8ed1b From 84b3cdc38cd2882d7ac3c2ae4b6faf5c199874e3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Dec 2010 18:41:03 -0800 Subject: can: slcan: Add missing linux/sched.h include. drivers/net/can/slcan.c: In function 'slcan_open': drivers/net/can/slcan.c:568: error: dereferencing pointer to incomplete type Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/can/slcan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 420e95ecc193..b423965a78d1 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From bf5e0bd27f7cbaca4d52ae395bbf3715775efebd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 14 Nov 2010 17:33:25 +0200 Subject: vhost: remove unused include vhost.c does not need to know about sockets, don't include sock.h Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index a29d91c776b4..916cdbc279e0 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -30,8 +30,6 @@ #include #include -#include - #include "vhost.h" enum { -- cgit v1.2.3-59-g8ed1b From a290aec88a9c4747353ea7aa9b2569bd61297c3c Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 29 Nov 2010 13:48:40 +0800 Subject: vhost: fix typos in comment Signed-off-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 2 +- drivers/vhost/vhost.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index d10da280fa0f..14fc189ac0a8 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -452,7 +452,7 @@ static void handle_rx_mergeable(struct vhost_net *net) move_iovec_hdr(vq->iov, vq->hdr, vhost_hlen, in); else /* Copy the header for use in VIRTIO_NET_F_MRG_RXBUF: - * needed because sendmsg can modify msg_iov. */ + * needed because recvmsg can modify msg_iov. */ copy_iovec_hdr(vq->iov, vq->hdr, sock_hlen, in); msg.msg_iovlen = in; err = sock->ops->recvmsg(NULL, sock, &msg, diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 073d06ae091f..2af44b7b1f3f 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -102,7 +102,7 @@ struct vhost_virtqueue { * flush the vhost_work instead of synchronize_rcu. Therefore readers do * not need to call rcu_read_lock/rcu_read_unlock: the beginning of * vhost_work execution acts instead of rcu_read_lock() and the end of - * vhost_work execution acts instead of rcu_read_lock(). + * vhost_work execution acts instead of rcu_read_unlock(). * Writers use virtqueue mutex. */ void __rcu *private_data; /* Log write descriptors */ -- cgit v1.2.3-59-g8ed1b From 3bf9be40ff76b6df136f14a497167c116b2b3c53 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Nov 2010 10:19:07 +0200 Subject: vhost: correctly set bits of dirty pages Fix two bugs in dirty page logging: When counting pages we should increase address by 1 instead of VHOST_PAGE_SIZE. Make log_write() correctly process requests that cross pages with write_address not starting at page boundary. Reported-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 916cdbc279e0..4c256d15c249 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -885,6 +885,7 @@ static int log_write(void __user *log_base, int r; if (!write_length) return 0; + write_length += write_address % VHOST_PAGE_SIZE; write_address /= VHOST_PAGE_SIZE; for (;;) { u64 base = (u64)(unsigned long)log_base; @@ -898,7 +899,7 @@ static int log_write(void __user *log_base, if (write_length <= VHOST_PAGE_SIZE) break; write_length -= VHOST_PAGE_SIZE; - write_address += VHOST_PAGE_SIZE; + write_address += 1; } return r; } -- cgit v1.2.3-59-g8ed1b From b7ee1d01c5ff3bf2e51c8565ea00823cdbc2a9f3 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Tue, 7 Dec 2010 22:35:50 +0100 Subject: ath5k: Fix modinfo does not list alias -> pci-id lines The AHB bus support patchset moved the table "Known PCI ids" from base.c to pci.c - unfortunately, MODULE_DEVICE_TABLE() was not transferred. With this fix 'modinfo ath5k' lists the alias -> pci-id lines, again. The issue was introduced by: commit e5b046d86fac609f636d127a38de94a175c7e83b "ath5k: Move PCI bus functions to separate file." Signed-off-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 39f033128c5a..7f8c5b0e9d2a 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -45,6 +45,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ { 0 } }; +MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); /* return bus cachesize in 4B word units */ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) -- cgit v1.2.3-59-g8ed1b From 28831ee60b79bed50958c9cb0d2e76cdc98406f9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Nov 2010 10:22:10 +0200 Subject: vhost: better variable name in logging We really store a page offset in write_address, so rename it write_page to avoid confusion. Signed-off-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 4c256d15c249..38244f59cdd9 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -882,15 +882,15 @@ static int set_bit_to_user(int nr, void __user *addr) static int log_write(void __user *log_base, u64 write_address, u64 write_length) { + u64 write_page = write_address / VHOST_PAGE_SIZE; int r; if (!write_length) return 0; write_length += write_address % VHOST_PAGE_SIZE; - write_address /= VHOST_PAGE_SIZE; for (;;) { u64 base = (u64)(unsigned long)log_base; - u64 log = base + write_address / 8; - int bit = write_address % 8; + u64 log = base + write_page / 8; + int bit = write_page % 8; if ((u64)(unsigned long)log != log) return -EFAULT; r = set_bit_to_user(bit, (void __user *)(unsigned long)log); @@ -899,7 +899,7 @@ static int log_write(void __user *log_base, if (write_length <= VHOST_PAGE_SIZE) break; write_length -= VHOST_PAGE_SIZE; - write_address += 1; + write_page += 1; } return r; } -- cgit v1.2.3-59-g8ed1b From 71ccc212e5b28dfcc870b6db6589c2df264fdc6a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Nov 2010 19:09:01 +0200 Subject: vhost test module This adds a test module for vhost infrastructure. Intentionally not tied to kbuild to prevent people from installing and loading it accidentally. Signed-off-by: Michael S. Tsirkin --- drivers/vhost/test.c | 320 +++++++++++++++++++++++++++++++++++ drivers/vhost/test.h | 7 + tools/virtio/vhost_test/Makefile | 2 + tools/virtio/vhost_test/vhost_test.c | 1 + 4 files changed, 330 insertions(+) create mode 100644 drivers/vhost/test.c create mode 100644 drivers/vhost/test.h create mode 100644 tools/virtio/vhost_test/Makefile create mode 100644 tools/virtio/vhost_test/vhost_test.c diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c new file mode 100644 index 000000000000..099f30230d06 --- /dev/null +++ b/drivers/vhost/test.c @@ -0,0 +1,320 @@ +/* Copyright (C) 2009 Red Hat, Inc. + * Author: Michael S. Tsirkin + * + * This work is licensed under the terms of the GNU GPL, version 2. + * + * test virtio server in host kernel. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" +#include "vhost.c" + +/* Max number of bytes transferred before requeueing the job. + * Using this limit prevents one virtqueue from starving others. */ +#define VHOST_TEST_WEIGHT 0x80000 + +enum { + VHOST_TEST_VQ = 0, + VHOST_TEST_VQ_MAX = 1, +}; + +struct vhost_test { + struct vhost_dev dev; + struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX]; +}; + +/* Expects to be always run from workqueue - which acts as + * read-size critical section for our kind of RCU. */ +static void handle_vq(struct vhost_test *n) +{ + struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_TEST_VQ]; + unsigned out, in; + int head; + size_t len, total_len = 0; + void *private; + + private = rcu_dereference_check(vq->private_data, 1); + if (!private) + return; + + mutex_lock(&vq->mutex); + vhost_disable_notify(vq); + + for (;;) { + head = vhost_get_vq_desc(&n->dev, vq, vq->iov, + ARRAY_SIZE(vq->iov), + &out, &in, + NULL, NULL); + /* On error, stop handling until the next kick. */ + if (unlikely(head < 0)) + break; + /* Nothing new? Wait for eventfd to tell us they refilled. */ + if (head == vq->num) { + if (unlikely(vhost_enable_notify(vq))) { + vhost_disable_notify(vq); + continue; + } + break; + } + if (in) { + vq_err(vq, "Unexpected descriptor format for TX: " + "out %d, int %d\n", out, in); + break; + } + len = iov_length(vq->iov, out); + /* Sanity check */ + if (!len) { + vq_err(vq, "Unexpected 0 len for TX\n"); + break; + } + vhost_add_used_and_signal(&n->dev, vq, head, 0); + total_len += len; + if (unlikely(total_len >= VHOST_TEST_WEIGHT)) { + vhost_poll_queue(&vq->poll); + break; + } + } + + mutex_unlock(&vq->mutex); +} + +static void handle_vq_kick(struct vhost_work *work) +{ + struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, + poll.work); + struct vhost_test *n = container_of(vq->dev, struct vhost_test, dev); + + handle_vq(n); +} + +static int vhost_test_open(struct inode *inode, struct file *f) +{ + struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); + struct vhost_dev *dev; + int r; + + if (!n) + return -ENOMEM; + + dev = &n->dev; + n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; + r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX); + if (r < 0) { + kfree(n); + return r; + } + + f->private_data = n; + + return 0; +} + +static void *vhost_test_stop_vq(struct vhost_test *n, + struct vhost_virtqueue *vq) +{ + void *private; + + mutex_lock(&vq->mutex); + private = rcu_dereference_protected(vq->private_data, + lockdep_is_held(&vq->mutex)); + rcu_assign_pointer(vq->private_data, NULL); + mutex_unlock(&vq->mutex); + return private; +} + +static void vhost_test_stop(struct vhost_test *n, void **privatep) +{ + *privatep = vhost_test_stop_vq(n, n->vqs + VHOST_TEST_VQ); +} + +static void vhost_test_flush_vq(struct vhost_test *n, int index) +{ + vhost_poll_flush(&n->dev.vqs[index].poll); +} + +static void vhost_test_flush(struct vhost_test *n) +{ + vhost_test_flush_vq(n, VHOST_TEST_VQ); +} + +static int vhost_test_release(struct inode *inode, struct file *f) +{ + struct vhost_test *n = f->private_data; + void *private; + + vhost_test_stop(n, &private); + vhost_test_flush(n); + vhost_dev_cleanup(&n->dev); + /* We do an extra flush before freeing memory, + * since jobs can re-queue themselves. */ + vhost_test_flush(n); + kfree(n); + return 0; +} + +static long vhost_test_run(struct vhost_test *n, int test) +{ + void *priv, *oldpriv; + struct vhost_virtqueue *vq; + int r, index; + + if (test < 0 || test > 1) + return -EINVAL; + + mutex_lock(&n->dev.mutex); + r = vhost_dev_check_owner(&n->dev); + if (r) + goto err; + + for (index = 0; index < n->dev.nvqs; ++index) { + /* Verify that ring has been setup correctly. */ + if (!vhost_vq_access_ok(&n->vqs[index])) { + r = -EFAULT; + goto err; + } + } + + for (index = 0; index < n->dev.nvqs; ++index) { + vq = n->vqs + index; + mutex_lock(&vq->mutex); + priv = test ? n : NULL; + + /* start polling new socket */ + oldpriv = rcu_dereference_protected(vq->private_data, + lockdep_is_held(&vq->mutex)); + rcu_assign_pointer(vq->private_data, priv); + + mutex_unlock(&vq->mutex); + + if (oldpriv) { + vhost_test_flush_vq(n, index); + } + } + + mutex_unlock(&n->dev.mutex); + return 0; + +err: + mutex_unlock(&n->dev.mutex); + return r; +} + +static long vhost_test_reset_owner(struct vhost_test *n) +{ + void *priv = NULL; + long err; + mutex_lock(&n->dev.mutex); + err = vhost_dev_check_owner(&n->dev); + if (err) + goto done; + vhost_test_stop(n, &priv); + vhost_test_flush(n); + err = vhost_dev_reset_owner(&n->dev); +done: + mutex_unlock(&n->dev.mutex); + return err; +} + +static int vhost_test_set_features(struct vhost_test *n, u64 features) +{ + mutex_lock(&n->dev.mutex); + if ((features & (1 << VHOST_F_LOG_ALL)) && + !vhost_log_access_ok(&n->dev)) { + mutex_unlock(&n->dev.mutex); + return -EFAULT; + } + n->dev.acked_features = features; + smp_wmb(); + vhost_test_flush(n); + mutex_unlock(&n->dev.mutex); + return 0; +} + +static long vhost_test_ioctl(struct file *f, unsigned int ioctl, + unsigned long arg) +{ + struct vhost_test *n = f->private_data; + void __user *argp = (void __user *)arg; + u64 __user *featurep = argp; + int test; + u64 features; + int r; + switch (ioctl) { + case VHOST_TEST_RUN: + if (copy_from_user(&test, argp, sizeof test)) + return -EFAULT; + return vhost_test_run(n, test); + case VHOST_GET_FEATURES: + features = VHOST_FEATURES; + if (copy_to_user(featurep, &features, sizeof features)) + return -EFAULT; + return 0; + case VHOST_SET_FEATURES: + if (copy_from_user(&features, featurep, sizeof features)) + return -EFAULT; + if (features & ~VHOST_FEATURES) + return -EOPNOTSUPP; + return vhost_test_set_features(n, features); + case VHOST_RESET_OWNER: + return vhost_test_reset_owner(n); + default: + mutex_lock(&n->dev.mutex); + r = vhost_dev_ioctl(&n->dev, ioctl, arg); + vhost_test_flush(n); + mutex_unlock(&n->dev.mutex); + return r; + } +} + +#ifdef CONFIG_COMPAT +static long vhost_test_compat_ioctl(struct file *f, unsigned int ioctl, + unsigned long arg) +{ + return vhost_test_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); +} +#endif + +static const struct file_operations vhost_test_fops = { + .owner = THIS_MODULE, + .release = vhost_test_release, + .unlocked_ioctl = vhost_test_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = vhost_test_compat_ioctl, +#endif + .open = vhost_test_open, + .llseek = noop_llseek, +}; + +static struct miscdevice vhost_test_misc = { + MISC_DYNAMIC_MINOR, + "vhost-test", + &vhost_test_fops, +}; + +static int vhost_test_init(void) +{ + return misc_register(&vhost_test_misc); +} +module_init(vhost_test_init); + +static void vhost_test_exit(void) +{ + misc_deregister(&vhost_test_misc); +} +module_exit(vhost_test_exit); + +MODULE_VERSION("0.0.1"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Michael S. Tsirkin"); +MODULE_DESCRIPTION("Host kernel side for virtio simulator"); diff --git a/drivers/vhost/test.h b/drivers/vhost/test.h new file mode 100644 index 000000000000..1fef5df82153 --- /dev/null +++ b/drivers/vhost/test.h @@ -0,0 +1,7 @@ +#ifndef LINUX_VHOST_TEST_H +#define LINUX_VHOST_TEST_H + +/* Start a given test on the virtio null device. 0 stops all tests. */ +#define VHOST_TEST_RUN _IOW(VHOST_VIRTIO, 0x31, int) + +#endif diff --git a/tools/virtio/vhost_test/Makefile b/tools/virtio/vhost_test/Makefile new file mode 100644 index 000000000000..a1d35b81b314 --- /dev/null +++ b/tools/virtio/vhost_test/Makefile @@ -0,0 +1,2 @@ +obj-m += vhost_test.o +EXTRA_CFLAGS += -Idrivers/vhost diff --git a/tools/virtio/vhost_test/vhost_test.c b/tools/virtio/vhost_test/vhost_test.c new file mode 100644 index 000000000000..18735189e62b --- /dev/null +++ b/tools/virtio/vhost_test/vhost_test.c @@ -0,0 +1 @@ +#include "test.c" -- cgit v1.2.3-59-g8ed1b From 4e53f78e5b06c073a5c10814c72e98c1ca8a9f10 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Nov 2010 19:16:37 +0200 Subject: tools/virtio: virtio_test tool This is the userspace part of the tool: it includes a bunch of stubs for linux APIs, somewhat simular to linuxsched. This makes it possible to recompile the ring code in userspace. A small test example is implemented combining this with vhost_test module. Signed-off-by: Michael S. Tsirkin --- tools/virtio/Makefile | 12 +++ tools/virtio/linux/device.h | 2 + tools/virtio/linux/slab.h | 2 + tools/virtio/linux/virtio.h | 223 +++++++++++++++++++++++++++++++++++++++ tools/virtio/virtio_test.c | 248 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 487 insertions(+) create mode 100644 tools/virtio/Makefile create mode 100644 tools/virtio/linux/device.h create mode 100644 tools/virtio/linux/slab.h create mode 100644 tools/virtio/linux/virtio.h create mode 100644 tools/virtio/virtio_test.c diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile new file mode 100644 index 000000000000..d1d442ed106a --- /dev/null +++ b/tools/virtio/Makefile @@ -0,0 +1,12 @@ +all: test mod +test: virtio_test +virtio_test: virtio_ring.o virtio_test.o +CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -MMD +vpath %.c ../../drivers/virtio +mod: + ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test +.PHONY: all test mod clean +clean: + ${RM} *.o vhost_test/*.o vhost_test/.*.cmd \ + vhost_test/Module.symvers vhost_test/modules.order *.d +-include *.d diff --git a/tools/virtio/linux/device.h b/tools/virtio/linux/device.h new file mode 100644 index 000000000000..4ad7e1df0db5 --- /dev/null +++ b/tools/virtio/linux/device.h @@ -0,0 +1,2 @@ +#ifndef LINUX_DEVICE_H +#endif diff --git a/tools/virtio/linux/slab.h b/tools/virtio/linux/slab.h new file mode 100644 index 000000000000..81baeac8ae40 --- /dev/null +++ b/tools/virtio/linux/slab.h @@ -0,0 +1,2 @@ +#ifndef LINUX_SLAB_H +#endif diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h new file mode 100644 index 000000000000..669bcdd45805 --- /dev/null +++ b/tools/virtio/linux/virtio.h @@ -0,0 +1,223 @@ +#ifndef LINUX_VIRTIO_H +#define LINUX_VIRTIO_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +typedef unsigned long long dma_addr_t; + +struct scatterlist { + unsigned long page_link; + unsigned int offset; + unsigned int length; + dma_addr_t dma_address; +}; + +struct page { + unsigned long long dummy; +}; + +#define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond)) + +/* Physical == Virtual */ +#define virt_to_phys(p) ((unsigned long)p) +#define phys_to_virt(a) ((void *)(unsigned long)(a)) +/* Page address: Virtual / 4K */ +#define virt_to_page(p) ((struct page*)((virt_to_phys(p) / 4096) * \ + sizeof(struct page))) +#define offset_in_page(p) (((unsigned long)p) % 4096) +#define sg_phys(sg) ((sg->page_link & ~0x3) / sizeof(struct page) * 4096 + \ + sg->offset) +static inline void sg_mark_end(struct scatterlist *sg) +{ + /* + * Set termination bit, clear potential chain bit + */ + sg->page_link |= 0x02; + sg->page_link &= ~0x01; +} +static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) +{ + memset(sgl, 0, sizeof(*sgl) * nents); + sg_mark_end(&sgl[nents - 1]); +} +static inline void sg_assign_page(struct scatterlist *sg, struct page *page) +{ + unsigned long page_link = sg->page_link & 0x3; + + /* + * In order for the low bit stealing approach to work, pages + * must be aligned at a 32-bit boundary as a minimum. + */ + BUG_ON((unsigned long) page & 0x03); + sg->page_link = page_link | (unsigned long) page; +} + +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg_assign_page(sg, page); + sg->offset = offset; + sg->length = len; +} + +static inline void sg_set_buf(struct scatterlist *sg, const void *buf, + unsigned int buflen) +{ + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); +} + +static inline void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen) +{ + sg_init_table(sg, 1); + sg_set_buf(sg, buf, buflen); +} + +typedef __u16 u16; + +typedef enum { + GFP_KERNEL, + GFP_ATOMIC, +} gfp_t; +typedef enum { + IRQ_NONE, + IRQ_HANDLED +} irqreturn_t; + +static inline void *kmalloc(size_t s, gfp_t gfp) +{ + return malloc(s); +} + +static inline void kfree(void *p) +{ + free(p); +} + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define uninitialized_var(x) x = x + +# ifndef likely +# define likely(x) (__builtin_expect(!!(x), 1)) +# endif +# ifndef unlikely +# define unlikely(x) (__builtin_expect(!!(x), 0)) +# endif + +#define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__) +#ifdef DEBUG +#define pr_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__) +#else +#define pr_debug(format, ...) do {} while (0) +#endif +#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) +#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) + +/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */ +#define list_add_tail(a, b) do {} while (0) +#define list_del(a) do {} while (0) + +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BITS_PER_BYTE 8 +#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE) +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +/* TODO: Not atomic as it should be: + * we don't use this for anything important. */ +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p &= ~mask; +} + +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); +} + +/* The only feature we care to support */ +#define virtio_has_feature(dev, feature) \ + test_bit((feature), (dev)->features) +/* end of stubs */ + +struct virtio_device { + void *dev; + unsigned long features[1]; +}; + +struct virtqueue { + /* TODO: commented as list macros are empty stubs for now. + * Broken but enough for virtio_ring.c + * struct list_head list; */ + void (*callback)(struct virtqueue *vq); + const char *name; + struct virtio_device *vdev; + void *priv; +}; + +#define EXPORT_SYMBOL_GPL(__EXPORT_SYMBOL_GPL_name) \ + void __EXPORT_SYMBOL_GPL##__EXPORT_SYMBOL_GPL_name() { \ +} +#define MODULE_LICENSE(__MODULE_LICENSE_value) \ + const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value + +#define CONFIG_SMP + +#if defined(__i386__) || defined(__x86_64__) +#define barrier() asm volatile("" ::: "memory") +#define mb() __sync_synchronize() + +#define smp_mb() mb() +# define smp_rmb() barrier() +# define smp_wmb() barrier() +#else +#error Please fill in barrier macros +#endif + +/* Interfaces exported by virtio_ring. */ +int virtqueue_add_buf_gfp(struct virtqueue *vq, + struct scatterlist sg[], + unsigned int out_num, + unsigned int in_num, + void *data, + gfp_t gfp); + +static inline int virtqueue_add_buf(struct virtqueue *vq, + struct scatterlist sg[], + unsigned int out_num, + unsigned int in_num, + void *data) +{ + return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC); +} + +void virtqueue_kick(struct virtqueue *vq); + +void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); + +void virtqueue_disable_cb(struct virtqueue *vq); + +bool virtqueue_enable_cb(struct virtqueue *vq); + +void *virtqueue_detach_unused_buf(struct virtqueue *vq); +struct virtqueue *vring_new_virtqueue(unsigned int num, + unsigned int vring_align, + struct virtio_device *vdev, + void *pages, + void (*notify)(struct virtqueue *vq), + void (*callback)(struct virtqueue *vq), + const char *name); +void vring_del_virtqueue(struct virtqueue *vq); + +#endif diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c new file mode 100644 index 000000000000..df0c6d2c3860 --- /dev/null +++ b/tools/virtio/virtio_test.c @@ -0,0 +1,248 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../drivers/vhost/test.h" + +struct vq_info { + int kick; + int call; + int num; + int idx; + void *ring; + /* copy used for control */ + struct vring vring; + struct virtqueue *vq; +}; + +struct vdev_info { + struct virtio_device vdev; + int control; + struct pollfd fds[1]; + struct vq_info vqs[1]; + int nvqs; + void *buf; + size_t buf_size; + struct vhost_memory *mem; +}; + +void vq_notify(struct virtqueue *vq) +{ + struct vq_info *info = vq->priv; + unsigned long long v = 1; + int r; + r = write(info->kick, &v, sizeof v); + assert(r == sizeof v); +} + +void vq_callback(struct virtqueue *vq) +{ +} + + +void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) +{ + struct vhost_vring_state state = { .index = info->idx }; + struct vhost_vring_file file = { .index = info->idx }; + unsigned long long features = dev->vdev.features[0]; + struct vhost_vring_addr addr = { + .index = info->idx, + .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc, + .avail_user_addr = (uint64_t)(unsigned long)info->vring.avail, + .used_user_addr = (uint64_t)(unsigned long)info->vring.used, + }; + int r; + r = ioctl(dev->control, VHOST_SET_FEATURES, &features); + assert(r >= 0); + state.num = info->vring.num; + r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); + assert(r >= 0); + state.num = 0; + r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state); + assert(r >= 0); + r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr); + assert(r >= 0); + file.fd = info->kick; + r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file); + assert(r >= 0); + file.fd = info->call; + r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); + assert(r >= 0); +} + +static void vq_info_add(struct vdev_info *dev, int num) +{ + struct vq_info *info = &dev->vqs[dev->nvqs]; + int r; + info->idx = dev->nvqs; + info->kick = eventfd(0, EFD_NONBLOCK); + info->call = eventfd(0, EFD_NONBLOCK); + r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); + assert(r >= 0); + memset(info->ring, 0, vring_size(num, 4096)); + vring_init(&info->vring, num, info->ring, 4096); + info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev, info->ring, + vq_notify, vq_callback, "test"); + assert(info->vq); + info->vq->priv = info; + vhost_vq_setup(dev, info); + dev->fds[info->idx].fd = info->call; + dev->fds[info->idx].events = POLLIN; + dev->nvqs++; +} + +static void vdev_info_init(struct vdev_info* dev, unsigned long long features) +{ + int r; + memset(dev, 0, sizeof *dev); + dev->vdev.features[0] = features; + dev->vdev.features[1] = features >> 32; + dev->buf_size = 1024; + dev->buf = malloc(dev->buf_size); + assert(dev->buf); + dev->control = open("/dev/vhost-test", O_RDWR); + assert(dev->control >= 0); + r = ioctl(dev->control, VHOST_SET_OWNER, NULL); + assert(r >= 0); + dev->mem = malloc(offsetof(struct vhost_memory, regions) + + sizeof dev->mem->regions[0]); + assert(dev->mem); + memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + + sizeof dev->mem->regions[0]); + dev->mem->nregions = 1; + dev->mem->regions[0].guest_phys_addr = (long)dev->buf; + dev->mem->regions[0].userspace_addr = (long)dev->buf; + dev->mem->regions[0].memory_size = dev->buf_size; + r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); + assert(r >= 0); +} + +/* TODO: this is pretty bad: we get a cache line bounce + * for the wait queue on poll and another one on read, + * plus the read which is there just to clear the + * current state. */ +static void wait_for_interrupt(struct vdev_info *dev) +{ + int i; + unsigned long long val; + poll(dev->fds, dev->nvqs, -1); + for (i = 0; i < dev->nvqs; ++i) + if (dev->fds[i].revents & POLLIN) { + read(dev->fds[i].fd, &val, sizeof val); + } +} + +static void run_test(struct vdev_info *dev, struct vq_info *vq, int bufs) +{ + struct scatterlist sl; + long started = 0, completed = 0; + long completed_before; + int r, test = 1; + unsigned len; + long long spurious = 0; + r = ioctl(dev->control, VHOST_TEST_RUN, &test); + assert(r >= 0); + for (;;) { + virtqueue_disable_cb(vq->vq); + completed_before = completed; + do { + if (started < bufs) { + sg_init_one(&sl, dev->buf, dev->buf_size); + r = virtqueue_add_buf(vq->vq, &sl, 1, 0, + dev->buf + started); + if (likely(r >= 0)) { + ++started; + virtqueue_kick(vq->vq); + } + } else + r = -1; + + /* Flush out completed bufs if any */ + if (virtqueue_get_buf(vq->vq, &len)) { + ++completed; + r = 0; + } + + } while (r >= 0); + if (completed == completed_before) + ++spurious; + assert(completed <= bufs); + assert(started <= bufs); + if (completed == bufs) + break; + if (virtqueue_enable_cb(vq->vq)) { + wait_for_interrupt(dev); + } + } + test = 0; + r = ioctl(dev->control, VHOST_TEST_RUN, &test); + assert(r >= 0); + fprintf(stderr, "spurious wakeus: 0x%llx\n", spurious); +} + +const char optstring[] = "h"; +const struct option longopts[] = { + { + .name = "help", + .val = 'h', + }, + { + .name = "indirect", + .val = 'I', + }, + { + .name = "no-indirect", + .val = 'i', + }, + { + } +}; + +static void help() +{ + fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n"); +} + +int main(int argc, char **argv) +{ + struct vdev_info dev; + unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC; + int o; + + for (;;) { + o = getopt_long(argc, argv, optstring, longopts, NULL); + switch (o) { + case -1: + goto done; + case '?': + help(); + exit(2); + case 'h': + help(); + goto done; + case 'i': + features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC); + break; + default: + assert(0); + break; + } + } + +done: + vdev_info_init(&dev, features); + vq_info_add(&dev, 256); + run_test(&dev, &dev.vqs[0], 0x100000); + return 0; +} -- cgit v1.2.3-59-g8ed1b From b7613370db5ba66ad81e41cd3a5417fde4d5e03c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 9 Dec 2010 09:08:47 -0500 Subject: ath: fix build break with ATH_DBG_WARN_ON_ONCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description by Hauke: "If CONFIG_ATH_DEBUG=y is set ATH_DBG_WARN_ON_ONCE uses WARN_ON_ONCE and returns something, but if CONFIG_ATH_DEBUG is not set it does not return anything. Now ATH_DBG_WARN_ON_ONCE is used in the boolean expression in an if case and is not returning anything and causes a compile error. CC [M] /drivers/net/wireless/ath/ath9k/main.o /drivers/net/wireless/ath/ath9k/main.c: In function ‘ath_isr’: /drivers/net/wireless/ath/ath9k/main.c:769: error: expected expression before ‘do’ make[5]: *** [/drivers/net/wireless/ath/ath9k/main.o] Error 1 make[4]: *** [/drivers/net/wireless/ath/ath9k] Error 2" Reported-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 3eb95e268f03..e43210c8585c 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -272,7 +272,10 @@ ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, return 0; } #define ATH_DBG_WARN(foo, arg...) do {} while (0) -#define ATH_DBG_WARN_ON_ONCE(foo) do {} while (0) +#define ATH_DBG_WARN_ON_ONCE(foo) ({ \ + int __ret_warn_once = !!(foo); \ + unlikely(__ret_warn_once); \ +}) #endif /* CONFIG_ATH_DEBUG */ -- cgit v1.2.3-59-g8ed1b From defb3519a64141608725e2dac5a5aa9a3c644bae Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Dec 2010 21:16:57 -0800 Subject: net: Abstract away all dst_entry metrics accesses. Use helper functions to hide all direct accesses, especially writes, to dst_entry metrics values. This will allow us to: 1) More easily change how the metrics are stored. 2) Implement COW for metrics. In particular this will help us put metrics into the inetpeer cache if that is what we end up doing. We can make the _metrics member a pointer instead of an array, initially have it point at the read-only metrics in the FIB, and then on the first set grab an inetpeer entry and point the _metrics member there. Signed-off-by: David S. Miller Acked-by: Eric Dumazet --- include/net/dst.h | 26 ++++++++++++++++--- net/bridge/br_device.c | 2 +- net/bridge/br_netfilter.c | 2 +- net/decnet/dn_route.c | 13 +++++----- net/ipv4/ip_gre.c | 2 +- net/ipv4/route.c | 55 +++++++++++++++++++++------------------ net/ipv4/tcp_input.c | 22 +++++++++------- net/ipv6/ndisc.c | 5 ++-- net/ipv6/route.c | 66 ++++++++++++++++++++++++++--------------------- net/xfrm/xfrm_policy.c | 6 ++--- 10 files changed, 118 insertions(+), 81 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index a5bd72646d65..85dee3a57b9b 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -70,7 +70,7 @@ struct dst_entry { struct dst_ops *ops; - u32 metrics[RTAX_MAX]; + u32 _metrics[RTAX_MAX]; #ifdef CONFIG_NET_CLS_ROUTE __u32 tclassid; @@ -106,7 +106,27 @@ struct dst_entry { static inline u32 dst_metric(const struct dst_entry *dst, int metric) { - return dst->metrics[metric-1]; + return dst->_metrics[metric-1]; +} + +static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) +{ + dst->_metrics[metric-1] = val; +} + +static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics) +{ + memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32)); +} + +static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src) +{ + dst_import_metrics(dest, src->_metrics); +} + +static inline u32 *dst_metrics_ptr(struct dst_entry *dst) +{ + return dst->_metrics; } static inline u32 @@ -134,7 +154,7 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric, unsigned long rtt) { - dst->metrics[metric-1] = jiffies_to_msecs(rtt); + dst_metric_set(dst, metric, jiffies_to_msecs(rtt)); } static inline u32 diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 17cb0b633576..556443566e9c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -141,7 +141,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu) #ifdef CONFIG_BRIDGE_NETFILTER /* remember the MTU in the rtable for PMTU */ - br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu; + dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu); #endif return 0; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 6e1392093911..16f5c333596a 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -124,7 +124,7 @@ void br_netfilter_rtable_init(struct net_bridge *br) atomic_set(&rt->dst.__refcnt, 1); rt->dst.dev = br->dev; rt->dst.path = &rt->dst; - rt->dst.metrics[RTAX_MTU - 1] = 1500; + dst_metric_set(&rt->dst, RTAX_MTU, 1500); rt->dst.flags = DST_NOXFRM; rt->dst.ops = &fake_dst_ops; } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 8280e43c8861..e2e926841fe6 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -240,13 +240,13 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) { if (!(dst_metric_locked(dst, RTAX_MTU))) { - dst->metrics[RTAX_MTU-1] = mtu; + dst_metric_set(dst, RTAX_MTU, mtu); dst_set_expires(dst, dn_rt_mtu_expires); } if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; if (dst_metric(dst, RTAX_ADVMSS) > mss) - dst->metrics[RTAX_ADVMSS-1] = mss; + dst_metric_set(dst, RTAX_ADVMSS, mss); } } } @@ -806,8 +806,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) if (DN_FIB_RES_GW(*res) && DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) rt->rt_gateway = DN_FIB_RES_GW(*res); - memcpy(rt->dst.metrics, fi->fib_metrics, - sizeof(rt->dst.metrics)); + dst_import_metrics(&rt->dst, fi->fib_metrics); } rt->rt_type = res->type; @@ -820,11 +819,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) if (dst_metric(&rt->dst, RTAX_MTU) == 0 || dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) - rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu; + dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu); mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 || dst_metric(&rt->dst, RTAX_ADVMSS) > mss) - rt->dst.metrics[RTAX_ADVMSS-1] = mss; + dst_metric_set(&rt->dst, RTAX_ADVMSS, mss); return 0; } @@ -1502,7 +1501,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src); if (rt->rt_daddr != rt->rt_gateway) RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); - if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) + if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto rtattr_failure; expires = rt->dst.expires ? rt->dst.expires - jiffies : 0; if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 258c98d5fa79..ff4e7a4e33ed 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -818,7 +818,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev !ipv4_is_multicast(tunnel->parms.iph.daddr)) || rt6->rt6i_dst.plen == 128) { rt6->rt6i_flags |= RTF_MODIFIED; - skb_dst(skb)->metrics[RTAX_MTU-1] = mtu; + dst_metric_set(skb_dst(skb), RTAX_MTU, mtu); } } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3843c2dfde82..26ac396eaa5e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1686,11 +1686,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, if (mtu < dst_mtu(&rth->dst)) { dst_confirm(&rth->dst); if (mtu < ip_rt_min_pmtu) { + u32 lock = dst_metric(&rth->dst, + RTAX_LOCK); mtu = ip_rt_min_pmtu; - rth->dst.metrics[RTAX_LOCK-1] |= - (1 << RTAX_MTU); + lock |= (1 << RTAX_MTU); + dst_metric_set(&rth->dst, RTAX_LOCK, + lock); } - rth->dst.metrics[RTAX_MTU-1] = mtu; + dst_metric_set(&rth->dst, RTAX_MTU, mtu); dst_set_expires(&rth->dst, ip_rt_mtu_expires); } @@ -1708,10 +1711,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) if (dst_mtu(dst) > mtu && mtu >= 68 && !(dst_metric_locked(dst, RTAX_MTU))) { if (mtu < ip_rt_min_pmtu) { + u32 lock = dst_metric(dst, RTAX_LOCK); mtu = ip_rt_min_pmtu; - dst->metrics[RTAX_LOCK-1] |= (1 << RTAX_MTU); + dst_metric_set(dst, RTAX_LOCK, lock | (1 << RTAX_MTU)); } - dst->metrics[RTAX_MTU-1] = mtu; + dst_metric_set(dst, RTAX_MTU, mtu); dst_set_expires(dst, ip_rt_mtu_expires); call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } @@ -1796,36 +1800,37 @@ static void set_class_tag(struct rtable *rt, u32 tag) static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) { + struct dst_entry *dst = &rt->dst; struct fib_info *fi = res->fi; if (fi) { if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) rt->rt_gateway = FIB_RES_GW(*res); - memcpy(rt->dst.metrics, fi->fib_metrics, - sizeof(rt->dst.metrics)); + dst_import_metrics(dst, fi->fib_metrics); if (fi->fib_mtu == 0) { - rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu; - if (dst_metric_locked(&rt->dst, RTAX_MTU) && + dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); + if (dst_metric_locked(dst, RTAX_MTU) && rt->rt_gateway != rt->rt_dst && - rt->dst.dev->mtu > 576) - rt->dst.metrics[RTAX_MTU-1] = 576; + dst->dev->mtu > 576) + dst_metric_set(dst, RTAX_MTU, 576); } #ifdef CONFIG_NET_CLS_ROUTE - rt->dst.tclassid = FIB_RES_NH(*res).nh_tclassid; + dst->tclassid = FIB_RES_NH(*res).nh_tclassid; #endif } else - rt->dst.metrics[RTAX_MTU-1]= rt->dst.dev->mtu; - - if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0) - rt->dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl; - if (dst_mtu(&rt->dst) > IP_MAX_MTU) - rt->dst.metrics[RTAX_MTU-1] = IP_MAX_MTU; - if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0) - rt->dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->dst.dev->mtu - 40, - ip_rt_min_advmss); - if (dst_metric(&rt->dst, RTAX_ADVMSS) > 65535 - 40) - rt->dst.metrics[RTAX_ADVMSS-1] = 65535 - 40; + dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); + + if (dst_metric(dst, RTAX_HOPLIMIT) == 0) + dst_metric_set(dst, RTAX_HOPLIMIT, sysctl_ip_default_ttl); + if (dst_mtu(dst) > IP_MAX_MTU) + dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); + if (dst_metric(dst, RTAX_ADVMSS) == 0) + dst_metric_set(dst, RTAX_ADVMSS, + max_t(unsigned int, dst->dev->mtu - 40, + ip_rt_min_advmss)); + if (dst_metric(dst, RTAX_ADVMSS) > 65535 - 40) + dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); #ifdef CONFIG_NET_CLS_ROUTE #ifdef CONFIG_IP_MULTIPLE_TABLES @@ -2720,7 +2725,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi new->__use = 1; new->input = dst_discard; new->output = dst_discard; - memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); + dst_copy_metrics(new, &ort->dst); new->dev = ort->dst.dev; if (new->dev) @@ -2827,7 +2832,7 @@ static int rt_fill_info(struct net *net, if (rt->rt_dst != rt->rt_gateway) NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway); - if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) + if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto nla_put_failure; if (rt->fl.mark) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6d8ab1c4efc3..824e8c8a17ad 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -734,7 +734,7 @@ void tcp_update_metrics(struct sock *sk) * Reset our results. */ if (!(dst_metric_locked(dst, RTAX_RTT))) - dst->metrics[RTAX_RTT - 1] = 0; + dst_metric_set(dst, RTAX_RTT, 0); return; } @@ -776,34 +776,38 @@ void tcp_update_metrics(struct sock *sk) if (dst_metric(dst, RTAX_SSTHRESH) && !dst_metric_locked(dst, RTAX_SSTHRESH) && (tp->snd_cwnd >> 1) > dst_metric(dst, RTAX_SSTHRESH)) - dst->metrics[RTAX_SSTHRESH-1] = tp->snd_cwnd >> 1; + dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_cwnd >> 1); if (!dst_metric_locked(dst, RTAX_CWND) && tp->snd_cwnd > dst_metric(dst, RTAX_CWND)) - dst->metrics[RTAX_CWND - 1] = tp->snd_cwnd; + dst_metric_set(dst, RTAX_CWND, tp->snd_cwnd); } else if (tp->snd_cwnd > tp->snd_ssthresh && icsk->icsk_ca_state == TCP_CA_Open) { /* Cong. avoidance phase, cwnd is reliable. */ if (!dst_metric_locked(dst, RTAX_SSTHRESH)) - dst->metrics[RTAX_SSTHRESH-1] = - max(tp->snd_cwnd >> 1, tp->snd_ssthresh); + dst_metric_set(dst, RTAX_SSTHRESH, + max(tp->snd_cwnd >> 1, tp->snd_ssthresh)); if (!dst_metric_locked(dst, RTAX_CWND)) - dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1; + dst_metric_set(dst, RTAX_CWND, + (dst_metric(dst, RTAX_CWND) + + tp->snd_cwnd) >> 1); } else { /* Else slow start did not finish, cwnd is non-sense, ssthresh may be also invalid. */ if (!dst_metric_locked(dst, RTAX_CWND)) - dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1; + dst_metric_set(dst, RTAX_CWND, + (dst_metric(dst, RTAX_CWND) + + tp->snd_ssthresh) >> 1); if (dst_metric(dst, RTAX_SSTHRESH) && !dst_metric_locked(dst, RTAX_SSTHRESH) && tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH)) - dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh; + dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_ssthresh); } if (!dst_metric_locked(dst, RTAX_REORDERING)) { if (dst_metric(dst, RTAX_REORDERING) < tp->reordering && tp->reordering != sysctl_tcp_reordering) - dst->metrics[RTAX_REORDERING-1] = tp->reordering; + dst_metric_set(dst, RTAX_REORDERING, tp->reordering); } } } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index e18f84130203..2342545a5ee9 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1259,7 +1259,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) if (ra_msg->icmph.icmp6_hop_limit) { in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; if (rt) - rt->dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit; + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, + ra_msg->icmph.icmp6_hop_limit); } skip_defrtr: @@ -1377,7 +1378,7 @@ skip_linkparms: in6_dev->cnf.mtu6 = mtu; if (rt) - rt->dst.metrics[RTAX_MTU-1] = mtu; + dst_metric_set(&rt->dst, RTAX_MTU, mtu); rt6_mtu_change(skb->dev, mtu); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 026caef0326c..4aed0812b512 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -129,7 +129,6 @@ static struct rt6_info ip6_null_entry_template = { .__use = 1, .obsolete = -1, .error = -ENETUNREACH, - .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, .input = ip6_pkt_discard, .output = ip6_pkt_discard_out, }, @@ -150,7 +149,6 @@ static struct rt6_info ip6_prohibit_entry_template = { .__use = 1, .obsolete = -1, .error = -EACCES, - .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, .input = ip6_pkt_prohibit, .output = ip6_pkt_prohibit_out, }, @@ -166,7 +164,6 @@ static struct rt6_info ip6_blk_hole_entry_template = { .__use = 1, .obsolete = -1, .error = -EINVAL, - .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, .input = dst_discard, .output = dst_discard, }, @@ -844,7 +841,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl new->input = dst_discard; new->output = dst_discard; - memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); + dst_copy_metrics(new, &ort->dst); new->dev = ort->dst.dev; if (new->dev) dev_hold(new->dev); @@ -928,10 +925,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { rt6->rt6i_flags |= RTF_MODIFIED; if (mtu < IPV6_MIN_MTU) { + u32 features = dst_metric(dst, RTAX_FEATURES); mtu = IPV6_MIN_MTU; - dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; + features |= RTAX_FEATURE_ALLFRAG; + dst_metric_set(dst, RTAX_FEATURES, features); } - dst->metrics[RTAX_MTU-1] = mtu; + dst_metric_set(dst, RTAX_MTU, mtu); call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } } @@ -989,9 +988,9 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_idev = idev; rt->rt6i_nexthop = neigh; atomic_set(&rt->dst.__refcnt, 1); - rt->dst.metrics[RTAX_HOPLIMIT-1] = 255; - rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); - rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); + dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); + dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); rt->dst.output = ip6_output; #if 0 /* there's no chance to use these for ndisc */ @@ -1305,17 +1304,17 @@ install_route: goto out; } - rt->dst.metrics[type - 1] = nla_get_u32(nla); + dst_metric_set(&rt->dst, type, nla_get_u32(nla)); } } } if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0) - rt->dst.metrics[RTAX_HOPLIMIT-1] = -1; + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); if (!dst_mtu(&rt->dst)) - rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); + dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); if (!dst_metric(&rt->dst, RTAX_ADVMSS)) - rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); + dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); rt->dst.dev = dev; rt->rt6i_idev = idev; rt->rt6i_table = table; @@ -1541,9 +1540,9 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); nrt->rt6i_nexthop = neigh_clone(neigh); /* Reset pmtu, it may be better */ - nrt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); - nrt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dev_net(neigh->dev), - dst_mtu(&nrt->dst)); + dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); + dst_metric_set(&nrt->dst, RTAX_ADVMSS, ipv6_advmss(dev_net(neigh->dev), + dst_mtu(&nrt->dst))); if (ip6_ins_rt(nrt)) goto out; @@ -1602,9 +1601,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, would return automatically. */ if (rt->rt6i_flags & RTF_CACHE) { - rt->dst.metrics[RTAX_MTU-1] = pmtu; - if (allfrag) - rt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; + dst_metric_set(&rt->dst, RTAX_MTU, pmtu); + if (allfrag) { + u32 features = dst_metric(&rt->dst, RTAX_FEATURES); + features |= RTAX_FEATURE_ALLFRAG; + dst_metric_set(&rt->dst, RTAX_FEATURES, features); + } dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; goto out; @@ -1621,9 +1623,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, nrt = rt6_alloc_clone(rt, daddr); if (nrt) { - nrt->dst.metrics[RTAX_MTU-1] = pmtu; - if (allfrag) - nrt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; + dst_metric_set(&nrt->dst, RTAX_MTU, pmtu); + if (allfrag) { + u32 features = dst_metric(&nrt->dst, RTAX_FEATURES); + features |= RTAX_FEATURE_ALLFRAG; + dst_metric_set(&nrt->dst, RTAX_FEATURES, features); + } /* According to RFC 1981, detecting PMTU increase shouldn't be * happened within 5 mins, the recommended timer is 10 mins. @@ -1674,7 +1679,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; - memcpy(rt->dst.metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); + dst_copy_metrics(&rt->dst, &ort->dst); rt->dst.error = ort->dst.error; rt->dst.dev = ort->dst.dev; if (rt->dst.dev) @@ -1966,9 +1971,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->dst.output = ip6_output; rt->rt6i_dev = net->loopback_dev; rt->rt6i_idev = idev; - rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); - rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); - rt->dst.metrics[RTAX_HOPLIMIT-1] = -1; + dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); + dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); rt->dst.obsolete = -1; rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; @@ -2068,8 +2073,8 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) (dst_mtu(&rt->dst) >= arg->mtu || (dst_mtu(&rt->dst) < arg->mtu && dst_mtu(&rt->dst) == idev->cnf.mtu6))) { - rt->dst.metrics[RTAX_MTU-1] = arg->mtu; - rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, arg->mtu); + dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); + dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, arg->mtu)); } return 0; } @@ -2295,7 +2300,7 @@ static int rt6_fill_node(struct net *net, NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); } - if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) + if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto nla_put_failure; if (rt->dst.neighbour) @@ -2686,6 +2691,7 @@ static int __net_init ip6_route_net_init(struct net *net) net->ipv6.ip6_null_entry->dst.path = (struct dst_entry *)net->ipv6.ip6_null_entry; net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; + dst_metric_set(&net->ipv6.ip6_null_entry->dst, RTAX_HOPLIMIT, 255); #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, @@ -2696,6 +2702,7 @@ static int __net_init ip6_route_net_init(struct net *net) net->ipv6.ip6_prohibit_entry->dst.path = (struct dst_entry *)net->ipv6.ip6_prohibit_entry; net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops; + dst_metric_set(&net->ipv6.ip6_prohibit_entry->dst, RTAX_HOPLIMIT, 255); net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, sizeof(*net->ipv6.ip6_blk_hole_entry), @@ -2705,6 +2712,7 @@ static int __net_init ip6_route_net_init(struct net *net) net->ipv6.ip6_blk_hole_entry->dst.path = (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; + dst_metric_set(&net->ipv6.ip6_blk_hole_entry->dst, RTAX_HOPLIMIT, 255); #endif net->ipv6.sysctl.flush_delay = 0; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 044e77898512..6e50ccd8c532 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1433,7 +1433,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, } xdst->route = dst; - memcpy(&dst1->metrics, &dst->metrics, sizeof(dst->metrics)); + dst_copy_metrics(dst1, dst); if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { family = xfrm[i]->props.family; @@ -2271,7 +2271,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst) if (pmtu > route_mtu_cached) pmtu = route_mtu_cached; - dst->metrics[RTAX_MTU-1] = pmtu; + dst_metric_set(dst, RTAX_MTU, pmtu); } while ((dst = dst->next)); } @@ -2349,7 +2349,7 @@ static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, mtu = xfrm_state_mtu(dst->xfrm, mtu); if (mtu > last->route_mtu_cached) mtu = last->route_mtu_cached; - dst->metrics[RTAX_MTU-1] = mtu; + dst_metric_set(dst, RTAX_MTU, mtu); if (last == first) break; -- cgit v1.2.3-59-g8ed1b From 68835aba4d9b74e2f94106d13b6a4bddc447c4c8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 30 Nov 2010 19:04:07 +0000 Subject: net: optimize INET input path further Followup of commit b178bb3dfc30 (net: reorder struct sock fields) Optimize INET input path a bit further, by : 1) moving sk_refcnt close to sk_lock. This reduces number of dirtied cache lines by one on 64bit arches (and 64 bytes cache line size). 2) moving inet_daddr & inet_rcv_saddr at the beginning of sk (same cache line than hash / family / bound_dev_if / nulls_node) This reduces number of accessed cache lines in lookups by one, and dont increase size of inet and timewait socks. inet and tw sockets now share same place-holder for these fields. Before patch : offsetof(struct sock, sk_refcnt) = 0x10 offsetof(struct sock, sk_lock) = 0x40 offsetof(struct sock, sk_receive_queue) = 0x60 offsetof(struct inet_sock, inet_daddr) = 0x270 offsetof(struct inet_sock, inet_rcv_saddr) = 0x274 After patch : offsetof(struct sock, sk_refcnt) = 0x44 offsetof(struct sock, sk_lock) = 0x48 offsetof(struct sock, sk_receive_queue) = 0x68 offsetof(struct inet_sock, inet_daddr) = 0x0 offsetof(struct inet_sock, inet_rcv_saddr) = 0x4 compute_score() (udp or tcp) now use a single cache line per ignored item, instead of two. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inet_sock.h | 5 +++-- include/net/inet_timewait_sock.h | 20 +++++++------------- include/net/sock.h | 37 ++++++++++++++++++++++++------------- net/core/sock.c | 11 ++++++----- net/ipv4/inet_connection_sock.c | 7 +++---- net/ipv6/udp.c | 4 ++-- 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 8945f9fb192a..8181498fa96c 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -116,8 +116,9 @@ struct inet_sock { struct ipv6_pinfo *pinet6; #endif /* Socket demultiplex comparisons on incoming packets. */ - __be32 inet_daddr; - __be32 inet_rcv_saddr; +#define inet_daddr sk.__sk_common.skc_daddr +#define inet_rcv_saddr sk.__sk_common.skc_rcv_saddr + __be16 inet_dport; __u16 inet_num; __be32 inet_saddr; diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index a066fdd50da6..17404b5388a7 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -88,12 +88,6 @@ extern void inet_twdr_hangman(unsigned long data); extern void inet_twdr_twkill_work(struct work_struct *work); extern void inet_twdr_twcal_tick(unsigned long data); -#if (BITS_PER_LONG == 64) -#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 8 -#else -#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 4 -#endif - struct inet_bind_bucket; /* @@ -117,15 +111,15 @@ struct inet_timewait_sock { #define tw_hash __tw_common.skc_hash #define tw_prot __tw_common.skc_prot #define tw_net __tw_common.skc_net +#define tw_daddr __tw_common.skc_daddr +#define tw_rcv_saddr __tw_common.skc_rcv_saddr int tw_timeout; volatile unsigned char tw_substate; - /* 3 bits hole, try to pack */ unsigned char tw_rcv_wscale; + /* Socket demultiplex comparisons on incoming packets. */ - /* these five are in inet_sock */ + /* these three are in inet_sock */ __be16 tw_sport; - __be32 tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES))); - __be32 tw_rcv_saddr; __be16 tw_dport; __u16 tw_num; kmemcheck_bitfield_begin(flags); @@ -191,10 +185,10 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk) return (struct inet_timewait_sock *)sk; } -static inline __be32 inet_rcv_saddr(const struct sock *sk) +static inline __be32 sk_rcv_saddr(const struct sock *sk) { - return likely(sk->sk_state != TCP_TIME_WAIT) ? - inet_sk(sk)->inet_rcv_saddr : inet_twsk(sk)->tw_rcv_saddr; +/* both inet_sk() and inet_twsk() store rcv_saddr in skc_rcv_saddr */ + return sk->__sk_common.skc_rcv_saddr; } extern void inet_twsk_put(struct inet_timewait_sock *tw); diff --git a/include/net/sock.h b/include/net/sock.h index 3482004e5c29..82e86034702f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -105,10 +105,8 @@ struct net; /** * struct sock_common - minimal network layer representation of sockets - * @skc_node: main hash linkage for various protocol lookup tables - * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol - * @skc_refcnt: reference count - * @skc_tx_queue_mapping: tx queue number for this connection + * @skc_daddr: Foreign IPv4 addr + * @skc_rcv_saddr: Bound local IPv4 addr * @skc_hash: hash value used with various protocol lookup tables * @skc_u16hashes: two u16 hash values used by UDP lookup tables * @skc_family: network address family @@ -119,20 +117,20 @@ struct net; * @skc_portaddr_node: second hash linkage for UDP/UDP-Lite protocol * @skc_prot: protocol handlers inside a network family * @skc_net: reference to the network namespace of this socket + * @skc_node: main hash linkage for various protocol lookup tables + * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol + * @skc_tx_queue_mapping: tx queue number for this connection + * @skc_refcnt: reference count * * This is the minimal network layer representation of sockets, the header * for struct sock and struct inet_timewait_sock. */ struct sock_common { - /* - * first fields are not copied in sock_copy() + /* skc_daddr and skc_rcv_saddr must be grouped : + * cf INET_MATCH() and INET_TW_MATCH() */ - union { - struct hlist_node skc_node; - struct hlist_nulls_node skc_nulls_node; - }; - atomic_t skc_refcnt; - int skc_tx_queue_mapping; + __be32 skc_daddr; + __be32 skc_rcv_saddr; union { unsigned int skc_hash; @@ -150,6 +148,18 @@ struct sock_common { #ifdef CONFIG_NET_NS struct net *skc_net; #endif + /* + * fields between dontcopy_begin/dontcopy_end + * are not copied in sock_copy() + */ + int skc_dontcopy_begin[0]; + union { + struct hlist_node skc_node; + struct hlist_nulls_node skc_nulls_node; + }; + int skc_tx_queue_mapping; + atomic_t skc_refcnt; + int skc_dontcopy_end[0]; }; /** @@ -232,7 +242,8 @@ struct sock { #define sk_refcnt __sk_common.skc_refcnt #define sk_tx_queue_mapping __sk_common.skc_tx_queue_mapping -#define sk_copy_start __sk_common.skc_hash +#define sk_dontcopy_begin __sk_common.skc_dontcopy_begin +#define sk_dontcopy_end __sk_common.skc_dontcopy_end #define sk_hash __sk_common.skc_hash #define sk_family __sk_common.skc_family #define sk_state __sk_common.skc_state diff --git a/net/core/sock.c b/net/core/sock.c index fb6080111461..bcdb6ff6e621 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -992,17 +992,18 @@ static inline void sock_lock_init(struct sock *sk) /* * Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet, * even temporarly, because of RCU lookups. sk_node should also be left as is. + * We must not copy fields between sk_dontcopy_begin and sk_dontcopy_end */ static void sock_copy(struct sock *nsk, const struct sock *osk) { #ifdef CONFIG_SECURITY_NETWORK void *sptr = nsk->sk_security; #endif - BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) != - sizeof(osk->sk_node) + sizeof(osk->sk_refcnt) + - sizeof(osk->sk_tx_queue_mapping)); - memcpy(&nsk->sk_copy_start, &osk->sk_copy_start, - osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start)); + memcpy(nsk, osk, offsetof(struct sock, sk_dontcopy_begin)); + + memcpy(&nsk->sk_dontcopy_end, &osk->sk_dontcopy_end, + osk->sk_prot->obj_size - offsetof(struct sock, sk_dontcopy_end)); + #ifdef CONFIG_SECURITY_NETWORK nsk->sk_security = sptr; security_sk_clone(osk, nsk); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 06f5f8f482f0..25e318153f14 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -55,7 +55,6 @@ EXPORT_SYMBOL(inet_get_local_port_range); int inet_csk_bind_conflict(const struct sock *sk, const struct inet_bind_bucket *tb) { - const __be32 sk_rcv_saddr = inet_rcv_saddr(sk); struct sock *sk2; struct hlist_node *node; int reuse = sk->sk_reuse; @@ -75,9 +74,9 @@ int inet_csk_bind_conflict(const struct sock *sk, sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { if (!reuse || !sk2->sk_reuse || sk2->sk_state == TCP_LISTEN) { - const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); - if (!sk2_rcv_saddr || !sk_rcv_saddr || - sk2_rcv_saddr == sk_rcv_saddr) + const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); + if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) || + sk2_rcv_saddr == sk_rcv_saddr(sk)) break; } } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b541a4e009fb..7aad12770867 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -54,8 +54,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) { const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); - __be32 sk1_rcv_saddr = inet_sk(sk)->inet_rcv_saddr; - __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); + __be32 sk1_rcv_saddr = sk_rcv_saddr(sk); + __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); int sk_ipv6only = ipv6_only_sock(sk); int sk2_ipv6only = inet_v6_ipv6only(sk2); int addr_type = ipv6_addr_type(sk_rcv_saddr6); -- cgit v1.2.3-59-g8ed1b From 60d509c823cca21e77d537bd356785f7cfe8f0d1 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Fri, 3 Dec 2010 02:39:01 +0000 Subject: The new jhash implementation The current jhash.h implements the lookup2() hash function by Bob Jenkins. However, lookup2() is outdated as Bob wrote a new hash function called lookup3(). The patch replaces the lookup2() implementation of the 'jhash*' functions with that of lookup3(). You can read a longer comparison of the two and other hash functions at http://burtleburtle.net/bob/hash/doobs.html. Signed-off-by: Jozsef Kadlecsik Acked-by: Rusty Russell Signed-off-by: David S. Miller --- include/linux/jhash.h | 183 +++++++++++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 78 deletions(-) diff --git a/include/linux/jhash.h b/include/linux/jhash.h index ced1159fa4f2..47cb09edec1a 100644 --- a/include/linux/jhash.h +++ b/include/linux/jhash.h @@ -3,129 +3,156 @@ /* jhash.h: Jenkins hash support. * - * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) + * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net) * * http://burtleburtle.net/bob/hash/ * * These are the credits from Bob's sources: * - * lookup2.c, by Bob Jenkins, December 1996, Public Domain. - * hash(), hash2(), hash3, and mix() are externally useful functions. - * Routines to test the hash are included if SELF_TEST is defined. - * You can use this free for any purpose. It has no warranty. + * lookup3.c, by Bob Jenkins, May 2006, Public Domain. * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * These are functions for producing 32-bit hashes for hash table lookup. + * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() + * are externally useful functions. Routines to test the hash are included + * if SELF_TEST is defined. You can use this free for any purpose. It's in + * the public domain. It has no warranty. + * + * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) * * I've modified Bob's hash to be useful in the Linux kernel, and - * any bugs present are surely my fault. -DaveM + * any bugs present are my fault. + * Jozsef */ +#include +#include + +/* Best hash sizes are of power of two */ +#define jhash_size(n) ((u32)1<<(n)) +/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */ +#define jhash_mask(n) (jhash_size(n)-1) + +/* __jhash_mix -- mix 3 32-bit values reversibly. */ +#define __jhash_mix(a, b, c) \ +{ \ + a -= c; a ^= rol32(c, 4); c += b; \ + b -= a; b ^= rol32(a, 6); a += c; \ + c -= b; c ^= rol32(b, 8); b += a; \ + a -= c; a ^= rol32(c, 16); c += b; \ + b -= a; b ^= rol32(a, 19); a += c; \ + c -= b; c ^= rol32(b, 4); b += a; \ +} -/* NOTE: Arguments are modified. */ -#define __jhash_mix(a, b, c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ +/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */ +#define __jhash_final(a, b, c) \ +{ \ + c ^= b; c -= rol32(b, 14); \ + a ^= c; a -= rol32(c, 11); \ + b ^= a; b -= rol32(a, 25); \ + c ^= b; c -= rol32(b, 16); \ + a ^= c; a -= rol32(c, 4); \ + b ^= a; b -= rol32(a, 14); \ + c ^= b; c -= rol32(b, 24); \ } -/* The golden ration: an arbitrary value */ -#define JHASH_GOLDEN_RATIO 0x9e3779b9 +/* An arbitrary initial parameter */ +#define JHASH_INITVAL 0xdeadbeef -/* The most generic version, hashes an arbitrary sequence - * of bytes. No alignment or length assumptions are made about - * the input key. +/* jhash - hash an arbitrary key + * @k: sequence of bytes as key + * @length: the length of the key + * @initval: the previous hash, or an arbitray value + * + * The generic version, hashes an arbitrary sequence of bytes. + * No alignment or length assumptions are made about the input key. + * + * Returns the hash value of the key. The result depends on endianness. */ static inline u32 jhash(const void *key, u32 length, u32 initval) { - u32 a, b, c, len; + u32 a, b, c; const u8 *k = key; - len = length; - a = b = JHASH_GOLDEN_RATIO; - c = initval; - - while (len >= 12) { - a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24)); - b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24)); - c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24)); - - __jhash_mix(a,b,c); + /* Set up the internal state */ + a = b = c = JHASH_INITVAL + length + initval; + /* All but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) { + a += __get_unaligned_cpu32(k); + b += __get_unaligned_cpu32(k + 4); + c += __get_unaligned_cpu32(k + 8); + __jhash_mix(a, b, c); + length -= 12; k += 12; - len -= 12; } - - c += length; - switch (len) { - case 11: c += ((u32)k[10]<<24); - case 10: c += ((u32)k[9]<<16); - case 9 : c += ((u32)k[8]<<8); - case 8 : b += ((u32)k[7]<<24); - case 7 : b += ((u32)k[6]<<16); - case 6 : b += ((u32)k[5]<<8); - case 5 : b += k[4]; - case 4 : a += ((u32)k[3]<<24); - case 3 : a += ((u32)k[2]<<16); - case 2 : a += ((u32)k[1]<<8); - case 1 : a += k[0]; - }; - - __jhash_mix(a,b,c); + /* Last block: affect all 32 bits of (c) */ + /* All the case statements fall through */ + switch (length) { + case 12: c += (u32)k[11]<<24; + case 11: c += (u32)k[10]<<16; + case 10: c += (u32)k[9]<<8; + case 9: c += k[8]; + case 8: b += (u32)k[7]<<24; + case 7: b += (u32)k[6]<<16; + case 6: b += (u32)k[5]<<8; + case 5: b += k[4]; + case 4: a += (u32)k[3]<<24; + case 3: a += (u32)k[2]<<16; + case 2: a += (u32)k[1]<<8; + case 1: a += k[0]; + __jhash_final(a, b, c); + case 0: /* Nothing left to add */ + break; + } return c; } -/* A special optimized version that handles 1 or more of u32s. - * The length parameter here is the number of u32s in the key. +/* jhash2 - hash an array of u32's + * @k: the key which must be an array of u32's + * @length: the number of u32's in the key + * @initval: the previous hash, or an arbitray value + * + * Returns the hash value of the key. */ static inline u32 jhash2(const u32 *k, u32 length, u32 initval) { - u32 a, b, c, len; + u32 a, b, c; - a = b = JHASH_GOLDEN_RATIO; - c = initval; - len = length; + /* Set up the internal state */ + a = b = c = JHASH_INITVAL + (length<<2) + initval; - while (len >= 3) { + /* Handle most of the key */ + while (length > 3) { a += k[0]; b += k[1]; c += k[2]; __jhash_mix(a, b, c); - k += 3; len -= 3; + length -= 3; + k += 3; } - c += length * 4; - - switch (len) { - case 2 : b += k[1]; - case 1 : a += k[0]; - }; - - __jhash_mix(a,b,c); + /* Handle the last 3 u32's: all the case statements fall through */ + switch (length) { + case 3: c += k[2]; + case 2: b += k[1]; + case 1: a += k[0]; + __jhash_final(a, b, c); + case 0: /* Nothing left to add */ + break; + } return c; } -/* A special ultra-optimized versions that knows they are hashing exactly - * 3, 2 or 1 word(s). - * - * NOTE: In particular the "c += length; __jhash_mix(a,b,c);" normally - * done at the end is not done here. - */ +/* jhash_3words - hash exactly 3, 2 or 1 word(s) */ static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) { - a += JHASH_GOLDEN_RATIO; - b += JHASH_GOLDEN_RATIO; + a += JHASH_INITVAL; + b += JHASH_INITVAL; c += initval; - __jhash_mix(a, b, c); + __jhash_final(a, b, c); return c; } -- cgit v1.2.3-59-g8ed1b From 4bc65dd8d88671712d71592a83374cfb0b5fce7a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 7 Dec 2010 22:26:15 +0000 Subject: filter: use size of fetched data in __load_pointer() __load_pointer() checks data we fetch from skb is included in head portion, but assumes we fetch one byte, instead of up to four. This wont crash because we have extra bytes (struct skb_shared_info) after head, but this can read uninitialized bytes. Fix this using size of the data (1, 2, 4 bytes) in the test. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/filter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index e193e29d4671..e8a6ac411ffb 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -88,7 +88,7 @@ enum { }; /* No hurry in this branch */ -static void *__load_pointer(const struct sk_buff *skb, int k) +static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size) { u8 *ptr = NULL; @@ -97,7 +97,7 @@ static void *__load_pointer(const struct sk_buff *skb, int k) else if (k >= SKF_LL_OFF) ptr = skb_mac_header(skb) + k - SKF_LL_OFF; - if (ptr >= skb->head && ptr < skb_tail_pointer(skb)) + if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb)) return ptr; return NULL; } @@ -110,7 +110,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k, else { if (k >= SKF_AD_OFF) return NULL; - return __load_pointer(skb, k); + return __load_pointer(skb, k, size); } } -- cgit v1.2.3-59-g8ed1b From 2297a2da5a8507bf6596dc30ace3483c00bd85ed Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 8 Dec 2010 01:43:09 +0000 Subject: bnx2x: LSO code was broken on BE platforms Make the LSO code work on BE platforms: parsing_data field of a parsing BD (PBD) for 57712 was improperly composed which made FW read wrong values for TCP header's length and offset and, as a result, the corresponding PCI device was performing bad DMA reads triggering EEH. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index a4555edbe9ce..236c00c3f568 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1795,15 +1795,15 @@ exit_lbl: } #endif -static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, + u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << - ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + *parsing_data |= (skb_shinfo(skb)->gso_size << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & + ETH_TX_PARSE_BD_E2_LSO_MSS; if ((xmit_type & XMIT_GSO_V6) && (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) - pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; + *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; } /** @@ -1848,15 +1848,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, * @return header len */ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) + u32 *parsing_data, u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + *parsing_data |= ((tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; - pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - - skb->data) / 2) << - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; } @@ -1925,6 +1925,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; + u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -2046,8 +2047,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) - hlen = bnx2x_set_pbd_csum_e2(bp, - skb, pbd_e2, xmit_type); + hlen = bnx2x_set_pbd_csum_e2(bp, skb, + &pbd_e2_parsing_data, + xmit_type); } else { pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); @@ -2089,10 +2091,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); if (CHIP_IS_E2(bp)) - bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, + xmit_type); else bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } + + /* Set the PBD's parsing_data field if not zero + * (for the chips newer than 57711). + */ + if (pbd_e2_parsing_data) + pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); + tx_data_bd = (struct eth_tx_bd *)tx_start_bd; /* Handle fragmented skb */ -- cgit v1.2.3-59-g8ed1b From d245a1111251d77c804e9fe362e9f70aba856e1e Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 8 Dec 2010 01:43:17 +0000 Subject: bnx2x: Use dma_alloc_coherent() semantics for ILT memory allocation Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index cfc25cf064d3..abbdf6d5b84e 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1336,7 +1336,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_ILT_ZALLOC(x, y, size) \ do { \ - x = pci_alloc_consistent(bp->pdev, size, y); \ + x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ if (x) \ memset(x, 0, size); \ } while (0) @@ -1344,7 +1344,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_ILT_FREE(x, y, size) \ do { \ if (x) { \ - pci_free_consistent(bp->pdev, size, x, y); \ + dma_free_coherent(&bp->pdev->dev, size, x, y); \ x = NULL; \ y = 0; \ } \ -- cgit v1.2.3-59-g8ed1b From 5cd737c2e84bebf532f536f7addfdd75162bba04 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 8 Dec 2010 01:43:29 +0000 Subject: bnx2x: Fixed a compilation warning bnx2x_src_init_t2() is used only when BCM_CNIC is defined. So, to avoid a compilation warning, we won't define it unless BCM_CNIC is defined. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_init_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b61..66df29fcf751 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, /**************************************************************************** * SRC initializations ****************************************************************************/ - +#ifdef BCM_CNIC /* called during init func stage */ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, dma_addr_t t2_mapping, int src_cid_count) @@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, U64_HI((u64)t2_mapping + (src_cid_count-1) * sizeof(struct src_ent))); } - +#endif #endif /* BNX2X_INIT_OPS_H */ -- cgit v1.2.3-59-g8ed1b From f404c2fea37e02bec7c8b6edddf5edd22ca60505 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 8 Dec 2010 01:43:37 +0000 Subject: bnx2x: Update version number and a date. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index abbdf6d5b84e..7e4d682f0df1 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-6" -#define DRV_MODULE_RELDATE "2010/11/29" +#define DRV_MODULE_VERSION "1.60.00-7" +#define DRV_MODULE_RELDATE "2010/12/08" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE -- cgit v1.2.3-59-g8ed1b From b7ec19af63b467e30189984fb24e6157603608e3 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Fri, 10 Dec 2010 12:49:23 +0100 Subject: dccp: remove unused macros Remove macros which have been unused since the initial implementation (commit 7c657876b63cb1d8a2ec06f8fc6c37bb8412e66c, [DCCP]: Initial implementation from Tue Aug 9 20:14:34 2005 -0700). Signed-off-by: Shan Wei Acked-by: Gerrit Renker --- net/dccp/dccp.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 48ad5d9da7cb..45087052d894 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -93,9 +93,6 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); #define DCCP_FALLBACK_RTT (USEC_PER_SEC / 5) #define DCCP_SANE_RTT_MAX (3 * USEC_PER_SEC) -/* Maximal interval between probes for local resources. */ -#define DCCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ / 2U)) - /* sysctl variables for DCCP */ extern int sysctl_dccp_request_retries; extern int sysctl_dccp_retries1; @@ -203,12 +200,7 @@ struct dccp_mib { DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics); #define DCCP_INC_STATS(field) SNMP_INC_STATS(dccp_statistics, field) #define DCCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(dccp_statistics, field) -#define DCCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(dccp_statistics, field) #define DCCP_DEC_STATS(field) SNMP_DEC_STATS(dccp_statistics, field) -#define DCCP_ADD_STATS_BH(field, val) \ - SNMP_ADD_STATS_BH(dccp_statistics, field, val) -#define DCCP_ADD_STATS_USER(field, val) \ - SNMP_ADD_STATS_USER(dccp_statistics, field, val) /* * Checksumming routines -- cgit v1.2.3-59-g8ed1b From 6ecfd0c70c05531b2850649d0cec46833cd6c381 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Dec 2010 01:19:53 +0000 Subject: sfc: Remove unused field and comment on a previously removed field Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 76f2fb197f0a..294379faca4a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -179,7 +179,6 @@ struct efx_tx_queue { struct efx_nic *efx ____cacheline_aligned_in_smp; unsigned queue; struct efx_channel *channel; - struct efx_nic *nic; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; unsigned int ptr_mask; @@ -321,7 +320,6 @@ enum efx_rx_alloc_method { * @irq_moderation: IRQ moderation value (in hardware ticks) * @napi_dev: Net device used with NAPI * @napi_str: NAPI control structure - * @reset_work: Scheduled reset work thread * @work_pending: Is work pending via NAPI? * @eventq: Event queue buffer * @eventq_mask: Event queue pointer mask -- cgit v1.2.3-59-g8ed1b From c04bfc6b223662c42a77727342c1df7d39e686a2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Dec 2010 01:24:16 +0000 Subject: sfc: Remove ancient support for nesting of TX stop Long before this driver went into mainline, it had support for multiple TX queues per port, with lockless TX enabled. Since Linux did not know anything of this, filling up any hardware TX queue would stop the core TX queue and multiple hardware TX queues could fill up before the scheduler reacted. Thus it was necessary to keep a count of how many TX queues were stopped and to wake the core TX queue only when all had free space again. The driver also previously (ab)used the per-hardware-queue stopped flag as a counter to deal with various things that can inhibit TX, but it no longer does that. Remove the per-channel tx_stop_count, tx_stop_lock and per-hardware-queue stopped count and just use the networking core queue state directly. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 24 ++++++---- drivers/net/sfc/efx.h | 2 - drivers/net/sfc/net_driver.h | 11 +---- drivers/net/sfc/tx.c | 111 ++++++++----------------------------------- 4 files changed, 35 insertions(+), 113 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 2166c1d0a533..711449c6e675 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -461,9 +461,6 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) } } - spin_lock_init(&channel->tx_stop_lock); - atomic_set(&channel->tx_stop_count, 1); - rx_queue = &channel->rx_queue; rx_queue->efx = efx; setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, @@ -1406,11 +1403,11 @@ static void efx_start_all(struct efx_nic *efx) * restart the transmit interface early so the watchdog timer stops */ efx_start_port(efx); - efx_for_each_channel(channel, efx) { - if (efx_dev_registered(efx)) - efx_wake_queue(channel); + if (efx_dev_registered(efx)) + netif_tx_wake_all_queues(efx->net_dev); + + efx_for_each_channel(channel, efx) efx_start_channel(channel); - } if (efx->legacy_irq) efx->legacy_irq_enabled = true; @@ -1498,9 +1495,7 @@ static void efx_stop_all(struct efx_nic *efx) /* Stop the kernel transmit interface late, so the watchdog * timer isn't ticking over the flush */ if (efx_dev_registered(efx)) { - struct efx_channel *channel; - efx_for_each_channel(channel, efx) - efx_stop_queue(channel); + netif_tx_stop_all_queues(efx->net_dev); netif_tx_lock_bh(efx->net_dev); netif_tx_unlock_bh(efx->net_dev); } @@ -1896,6 +1891,7 @@ static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL); static int efx_register_netdev(struct efx_nic *efx) { struct net_device *net_dev = efx->net_dev; + struct efx_channel *channel; int rc; net_dev->watchdog_timeo = 5 * HZ; @@ -1918,6 +1914,14 @@ static int efx_register_netdev(struct efx_nic *efx) if (rc) goto fail_locked; + efx_for_each_channel(channel, efx) { + struct efx_tx_queue *tx_queue; + efx_for_each_channel_tx_queue(tx_queue, channel) { + tx_queue->core_txq = netdev_get_tx_queue( + efx->net_dev, tx_queue->queue / EFX_TXQ_TYPES); + } + } + /* Always start with carrier off; PHY events will detect the link */ netif_carrier_off(efx->net_dev); diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 003fdb35b4bb..d43a7e5212b1 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -36,8 +36,6 @@ efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev); extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); -extern void efx_stop_queue(struct efx_channel *channel); -extern void efx_wake_queue(struct efx_channel *channel); /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 294379faca4a..bdce66ddf93a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -136,6 +136,7 @@ struct efx_tx_buffer { * @efx: The associated Efx NIC * @queue: DMA queue number * @channel: The associated channel + * @core_txq: The networking core TX queue structure * @buffer: The software buffer ring * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. @@ -148,8 +149,6 @@ struct efx_tx_buffer { * variable indicates that the queue is empty. This is to * avoid cache-line ping-pong between the xmit path and the * completion path. - * @stopped: Stopped count. - * Set if this TX queue is currently stopping its port. * @insert_count: Current insert pointer * This is the number of buffers that have been added to the * software ring. @@ -179,6 +178,7 @@ struct efx_tx_queue { struct efx_nic *efx ____cacheline_aligned_in_smp; unsigned queue; struct efx_channel *channel; + struct netdev_queue *core_txq; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; unsigned int ptr_mask; @@ -187,7 +187,6 @@ struct efx_tx_queue { /* Members used mainly on the completion path */ unsigned int read_count ____cacheline_aligned_in_smp; unsigned int old_write_count; - int stopped; /* Members used only on the xmit path */ unsigned int insert_count ____cacheline_aligned_in_smp; @@ -340,8 +339,6 @@ enum efx_rx_alloc_method { * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun * @rx_queue: RX queue for this channel - * @tx_stop_count: Core TX queue stop count - * @tx_stop_lock: Core TX queue stop lock * @tx_queue: TX queues for this channel */ struct efx_channel { @@ -380,10 +377,6 @@ struct efx_channel { bool rx_pkt_csummed; struct efx_rx_queue rx_queue; - - atomic_t tx_stop_count; - spinlock_t tx_stop_lock; - struct efx_tx_queue tx_queue[2]; }; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index bdb92b4af683..2f5e9da657bf 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -30,50 +30,6 @@ */ #define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u) -/* We need to be able to nest calls to netif_tx_stop_queue(), partly - * because of the 2 hardware queues associated with each core queue, - * but also so that we can inhibit TX for reasons other than a full - * hardware queue. */ -void efx_stop_queue(struct efx_channel *channel) -{ - struct efx_nic *efx = channel->efx; - struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - - if (!tx_queue) - return; - - spin_lock_bh(&channel->tx_stop_lock); - netif_vdbg(efx, tx_queued, efx->net_dev, "stop TX queue\n"); - - atomic_inc(&channel->tx_stop_count); - netif_tx_stop_queue( - netdev_get_tx_queue(efx->net_dev, - tx_queue->queue / EFX_TXQ_TYPES)); - - spin_unlock_bh(&channel->tx_stop_lock); -} - -/* Decrement core TX queue stop count and wake it if the count is 0 */ -void efx_wake_queue(struct efx_channel *channel) -{ - struct efx_nic *efx = channel->efx; - struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - - if (!tx_queue) - return; - - local_bh_disable(); - if (atomic_dec_and_lock(&channel->tx_stop_count, - &channel->tx_stop_lock)) { - netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n"); - netif_tx_wake_queue( - netdev_get_tx_queue(efx->net_dev, - tx_queue->queue / EFX_TXQ_TYPES)); - spin_unlock(&channel->tx_stop_lock); - } - local_bh_enable(); -} - static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct efx_tx_buffer *buffer) { @@ -234,9 +190,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) * checked. Update the xmit path's * copy of read_count. */ - ++tx_queue->stopped; + netif_tx_stop_queue(tx_queue->core_txq); /* This memory barrier protects the - * change of stopped from the access + * change of queue state from the access * of read_count. */ smp_mb(); tx_queue->old_read_count = @@ -244,10 +200,12 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) fill_level = (tx_queue->insert_count - tx_queue->old_read_count); q_space = efx->txq_entries - 1 - fill_level; - if (unlikely(q_space-- <= 0)) - goto stop; + if (unlikely(q_space-- <= 0)) { + rc = NETDEV_TX_BUSY; + goto unwind; + } smp_mb(); - --tx_queue->stopped; + netif_tx_start_queue(tx_queue->core_txq); } insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; @@ -307,13 +265,6 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Mark the packet as transmitted, and free the SKB ourselves */ dev_kfree_skb_any(skb); - goto unwind; - - stop: - rc = NETDEV_TX_BUSY; - - if (tx_queue->stopped == 1) - efx_stop_queue(tx_queue->channel); unwind: /* Work backwards until we hit the original insert pointer value */ @@ -400,32 +351,21 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) { unsigned fill_level; struct efx_nic *efx = tx_queue->efx; - struct netdev_queue *queue; EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); efx_dequeue_buffers(tx_queue, index); /* See if we need to restart the netif queue. This barrier - * separates the update of read_count from the test of - * stopped. */ + * separates the update of read_count from the test of the + * queue state. */ smp_mb(); - if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) { + if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) && + likely(efx->port_enabled)) { fill_level = tx_queue->insert_count - tx_queue->read_count; if (fill_level < EFX_TXQ_THRESHOLD(efx)) { EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); - - /* Do this under netif_tx_lock(), to avoid racing - * with efx_xmit(). */ - queue = netdev_get_tx_queue( - efx->net_dev, - tx_queue->queue / EFX_TXQ_TYPES); - __netif_tx_lock(queue, smp_processor_id()); - if (tx_queue->stopped) { - tx_queue->stopped = 0; - efx_wake_queue(tx_queue->channel); - } - __netif_tx_unlock(queue); + netif_tx_wake_queue(tx_queue->core_txq); } } @@ -487,7 +427,6 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) tx_queue->read_count = 0; tx_queue->old_read_count = 0; tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID; - BUG_ON(tx_queue->stopped); /* Set up TX descriptor ring */ efx_nic_init_tx(tx_queue); @@ -523,12 +462,6 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) /* Free up TSO header cache */ efx_fini_tso(tx_queue); - - /* Release queue's stop on port, if any */ - if (tx_queue->stopped) { - tx_queue->stopped = 0; - efx_wake_queue(tx_queue->channel); - } } void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) @@ -770,9 +703,9 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, * since the xmit path last checked. Update * the xmit path's copy of read_count. */ - ++tx_queue->stopped; + netif_tx_stop_queue(tx_queue->core_txq); /* This memory barrier protects the change of - * stopped from the access of read_count. */ + * queue state from the access of read_count. */ smp_mb(); tx_queue->old_read_count = ACCESS_ONCE(tx_queue->read_count); @@ -784,7 +717,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, return 1; } smp_mb(); - --tx_queue->stopped; + netif_tx_start_queue(tx_queue->core_txq); } insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; @@ -1124,8 +1057,10 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, while (1) { rc = tso_fill_packet_with_fragment(tx_queue, skb, &state); - if (unlikely(rc)) - goto stop; + if (unlikely(rc)) { + rc2 = NETDEV_TX_BUSY; + goto unwind; + } /* Move onto the next fragment? */ if (state.in_len == 0) { @@ -1154,14 +1089,6 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, netif_err(efx, tx_err, efx->net_dev, "Out of memory for TSO headers, or PCI mapping error\n"); dev_kfree_skb_any(skb); - goto unwind; - - stop: - rc2 = NETDEV_TX_BUSY; - - /* Stop the queue if it wasn't stopped before. */ - if (tx_queue->stopped == 1) - efx_stop_queue(tx_queue->channel); unwind: /* Free the DMA mapping we were in the process of writing out */ -- cgit v1.2.3-59-g8ed1b From 4c0833bcd4d302fe783b9f8286a00ca2999d6200 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 10 Dec 2010 03:18:04 +0000 Subject: bridge: Fix return values of br_multicast_add_group/br_multicast_new_group If br_multicast_new_group returns NULL, we would return 0 (no error) to the caller of br_multicast_add_group, which is not what we want. Instead br_multicast_new_group should return ERR_PTR(-ENOMEM) in this case. Also propagate the error number returned by br_mdb_rehash properly. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- net/bridge/br_multicast.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 326e599f83fb..85a0398b221e 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -654,11 +654,13 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( struct net_bridge_mdb_htable *mdb; struct net_bridge_mdb_entry *mp; int hash; + int err; mdb = rcu_dereference_protected(br->mdb, 1); if (!mdb) { - if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0)) - return NULL; + err = br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0); + if (err) + return ERR_PTR(err); goto rehash; } @@ -680,7 +682,7 @@ rehash: mp = kzalloc(sizeof(*mp), GFP_ATOMIC); if (unlikely(!mp)) - goto out; + return ERR_PTR(-ENOMEM); mp->br = br; mp->addr = *group; @@ -713,7 +715,7 @@ static int br_multicast_add_group(struct net_bridge *br, mp = br_multicast_new_group(br, port, group); err = PTR_ERR(mp); - if (unlikely(IS_ERR(mp) || !mp)) + if (IS_ERR(mp)) goto err; if (!port) { -- cgit v1.2.3-59-g8ed1b From 457de4383ec6144df7d5a82cdfb110c825305a51 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 10 Dec 2010 13:16:09 -0800 Subject: ipv6: Fix 'release_it' logic in tcp_v6_get_peer() We accidently set it to "true" for the case where we are using a route bound peer. Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 319458558df9..fee076891646 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1877,7 +1877,7 @@ static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) if (!rt->rt6i_peer) rt6_bind_peer(rt, 1); peer = rt->rt6i_peer; - *release_it = true; + *release_it = false; } return peer; -- cgit v1.2.3-59-g8ed1b From c07224005dd3fe746246acadc9be652a588a4d7f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 9 Dec 2010 03:40:30 +0000 Subject: net/ipv6/udp.c: fix typo in flush_stack() skb1 should be passed as parameter to sk_rcvqueues_full() here. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/ipv6/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7aad12770867..26a8da3f2044 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -602,7 +602,7 @@ static void flush_stack(struct sock **stack, unsigned int count, sk = stack[i]; if (skb1) { - if (sk_rcvqueues_full(sk, skb)) { + if (sk_rcvqueues_full(sk, skb1)) { kfree_skb(skb1); goto drop; } -- cgit v1.2.3-59-g8ed1b From d0ddf30fdd2b98fb547ffa33bb79a7a96ef8d7dd Mon Sep 17 00:00:00 2001 From: Einar Lueck Date: Wed, 8 Dec 2010 02:57:58 +0000 Subject: qeth: support ipv6 query arp cache for HiperSockets Function qeth_l3_arp_query now queries for IPv6 addresses, too, if QETH_QARP_WITH_IPV6 is passed as parameter to the ioctl. HiperSockets and GuestLAN in HiperSockets mode provide corresponding entries. Signed-off-by: Einar Lueck Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- arch/s390/include/asm/qeth.h | 51 ++++++++-- drivers/s390/net/qeth_core_mpc.h | 2 +- drivers/s390/net/qeth_l3_main.c | 215 ++++++++++++++++++++++++++------------- 3 files changed, 185 insertions(+), 83 deletions(-) diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h index 06cbd1e8c943..90efda0b137d 100644 --- a/arch/s390/include/asm/qeth.h +++ b/arch/s390/include/asm/qeth.h @@ -28,39 +28,70 @@ struct qeth_arp_cache_entry { __u8 reserved2[32]; } __attribute__ ((packed)); +enum qeth_arp_ipaddrtype { + QETHARP_IP_ADDR_V4 = 1, + QETHARP_IP_ADDR_V6 = 2, +}; +struct qeth_arp_entrytype { + __u8 mac; + __u8 ip; +} __attribute__((packed)); + +#define QETH_QARP_MEDIASPECIFIC_BYTES 32 +#define QETH_QARP_MACADDRTYPE_BYTES 1 struct qeth_arp_qi_entry7 { - __u8 media_specific[32]; - __u8 macaddr_type; - __u8 ipaddr_type; + __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES]; + struct qeth_arp_entrytype type; __u8 macaddr[6]; __u8 ipaddr[4]; } __attribute__((packed)); +struct qeth_arp_qi_entry7_ipv6 { + __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES]; + struct qeth_arp_entrytype type; + __u8 macaddr[6]; + __u8 ipaddr[16]; +} __attribute__((packed)); + struct qeth_arp_qi_entry7_short { - __u8 macaddr_type; - __u8 ipaddr_type; + struct qeth_arp_entrytype type; __u8 macaddr[6]; __u8 ipaddr[4]; } __attribute__((packed)); +struct qeth_arp_qi_entry7_short_ipv6 { + struct qeth_arp_entrytype type; + __u8 macaddr[6]; + __u8 ipaddr[16]; +} __attribute__((packed)); + struct qeth_arp_qi_entry5 { - __u8 media_specific[32]; - __u8 macaddr_type; - __u8 ipaddr_type; + __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES]; + struct qeth_arp_entrytype type; __u8 ipaddr[4]; } __attribute__((packed)); +struct qeth_arp_qi_entry5_ipv6 { + __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES]; + struct qeth_arp_entrytype type; + __u8 ipaddr[16]; +} __attribute__((packed)); + struct qeth_arp_qi_entry5_short { - __u8 macaddr_type; - __u8 ipaddr_type; + struct qeth_arp_entrytype type; __u8 ipaddr[4]; } __attribute__((packed)); +struct qeth_arp_qi_entry5_short_ipv6 { + struct qeth_arp_entrytype type; + __u8 ipaddr[16]; +} __attribute__((packed)); /* * can be set by user if no "media specific information" is wanted * -> saves a lot of space in user space buffer */ #define QETH_QARP_STRIP_ENTRIES 0x8000 +#define QETH_QARP_WITH_IPV6 0x4000 #define QETH_QARP_REQUEST_MASK 0x00ff /* data sent to user space as result of query arp ioctl */ diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index e37dd8c4bf4e..07d588867b57 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -333,7 +333,7 @@ struct qeth_arp_query_data { __u16 request_bits; __u16 reply_bits; __u32 no_entries; - char data; + char data; /* only for replies */ } __attribute__((packed)); /* used as parameter for arp_query reply */ diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index a1abb37db000..a7590551e574 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -30,6 +30,7 @@ #include "qeth_l3.h" + static int qeth_l3_set_offline(struct ccwgroup_device *); static int qeth_l3_recover(void *); static int qeth_l3_stop(struct net_device *); @@ -2455,22 +2456,46 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) return rc; } -static void qeth_l3_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo, - struct qeth_arp_query_data *qdata, int entry_size, - int uentry_size) +static __u32 get_arp_entry_size(struct qeth_card *card, + struct qeth_arp_query_data *qdata, + struct qeth_arp_entrytype *type, __u8 strip_entries) { - char *entry_ptr; - char *uentry_ptr; - int i; + __u32 rc; + __u8 is_hsi; - entry_ptr = (char *)&qdata->data; - uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset); - for (i = 0; i < qdata->no_entries; ++i) { - /* strip off 32 bytes "media specific information" */ - memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32); - entry_ptr += entry_size; - uentry_ptr += uentry_size; + is_hsi = qdata->reply_bits == 5; + if (type->ip == QETHARP_IP_ADDR_V4) { + QETH_CARD_TEXT(card, 4, "arpev4"); + if (strip_entries) { + rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5_short) : + sizeof(struct qeth_arp_qi_entry7_short); + } else { + rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5) : + sizeof(struct qeth_arp_qi_entry7); + } + } else if (type->ip == QETHARP_IP_ADDR_V6) { + QETH_CARD_TEXT(card, 4, "arpev6"); + if (strip_entries) { + rc = is_hsi ? + sizeof(struct qeth_arp_qi_entry5_short_ipv6) : + sizeof(struct qeth_arp_qi_entry7_short_ipv6); + } else { + rc = is_hsi ? + sizeof(struct qeth_arp_qi_entry5_ipv6) : + sizeof(struct qeth_arp_qi_entry7_ipv6); + } + } else { + QETH_CARD_TEXT(card, 4, "arpinv"); + rc = 0; } + + return rc; +} + +static int arpentry_matches_prot(struct qeth_arp_entrytype *type, __u16 prot) +{ + return (type->ip == QETHARP_IP_ADDR_V4 && prot == QETH_PROT_IPV4) || + (type->ip == QETHARP_IP_ADDR_V6 && prot == QETH_PROT_IPV6); } static int qeth_l3_arp_query_cb(struct qeth_card *card, @@ -2479,72 +2504,77 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card, struct qeth_ipa_cmd *cmd; struct qeth_arp_query_data *qdata; struct qeth_arp_query_info *qinfo; - int entry_size; - int uentry_size; int i; + int e; + int entrybytes_done; + int stripped_bytes; + __u8 do_strip_entries; - QETH_CARD_TEXT(card, 4, "arpquecb"); + QETH_CARD_TEXT(card, 3, "arpquecb"); qinfo = (struct qeth_arp_query_info *) reply->param; cmd = (struct qeth_ipa_cmd *) data; + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.prot_version); if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 4, "qaer1%i", cmd->hdr.return_code); + QETH_CARD_TEXT(card, 4, "arpcberr"); + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code); return 0; } if (cmd->data.setassparms.hdr.return_code) { cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; - QETH_CARD_TEXT_(card, 4, "qaer2%i", cmd->hdr.return_code); + QETH_CARD_TEXT(card, 4, "setaperr"); + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code); return 0; } qdata = &cmd->data.setassparms.data.query_arp; - switch (qdata->reply_bits) { - case 5: - uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) - uentry_size = sizeof(struct qeth_arp_qi_entry5_short); - break; - case 7: - /* fall through to default */ - default: - /* tr is the same as eth -> entry7 */ - uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) - uentry_size = sizeof(struct qeth_arp_qi_entry7_short); - break; - } - /* check if there is enough room in userspace */ - if ((qinfo->udata_len - qinfo->udata_offset) < - qdata->no_entries * uentry_size){ - QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); - cmd->hdr.return_code = -ENOMEM; - goto out_error; - } - QETH_CARD_TEXT_(card, 4, "anore%i", - cmd->data.setassparms.hdr.number_of_replies); - QETH_CARD_TEXT_(card, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no); QETH_CARD_TEXT_(card, 4, "anoen%i", qdata->no_entries); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) { - /* strip off "media specific information" */ - qeth_l3_copy_arp_entries_stripped(qinfo, qdata, entry_size, - uentry_size); - } else - /*copy entries to user buffer*/ - memcpy(qinfo->udata + qinfo->udata_offset, - (char *)&qdata->data, qdata->no_entries*uentry_size); + do_strip_entries = (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) > 0; + stripped_bytes = do_strip_entries ? QETH_QARP_MEDIASPECIFIC_BYTES : 0; + entrybytes_done = 0; + for (e = 0; e < qdata->no_entries; ++e) { + char *cur_entry; + __u32 esize; + struct qeth_arp_entrytype *etype; + + cur_entry = &qdata->data + entrybytes_done; + etype = &((struct qeth_arp_qi_entry5 *) cur_entry)->type; + if (!arpentry_matches_prot(etype, cmd->hdr.prot_version)) { + QETH_CARD_TEXT(card, 4, "pmis"); + QETH_CARD_TEXT_(card, 4, "%i", etype->ip); + break; + } + esize = get_arp_entry_size(card, qdata, etype, + do_strip_entries); + QETH_CARD_TEXT_(card, 5, "esz%i", esize); + if (!esize) + break; + + if ((qinfo->udata_len - qinfo->udata_offset) < esize) { + QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); + cmd->hdr.return_code = -ENOMEM; + goto out_error; + } - qinfo->no_entries += qdata->no_entries; - qinfo->udata_offset += (qdata->no_entries*uentry_size); + memcpy(qinfo->udata + qinfo->udata_offset, + &qdata->data + entrybytes_done + stripped_bytes, + esize); + entrybytes_done += esize + stripped_bytes; + qinfo->udata_offset += esize; + ++qinfo->no_entries; + } /* check if all replies received ... */ if (cmd->data.setassparms.hdr.seq_no < cmd->data.setassparms.hdr.number_of_replies) return 1; + QETH_CARD_TEXT_(card, 4, "nove%i", qinfo->no_entries); memcpy(qinfo->udata, &qinfo->no_entries, 4); /* keep STRIP_ENTRIES flag so the user program can distinguish * stripped entries from normal ones */ if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES; memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET, &qdata->reply_bits, 2); + QETH_CARD_TEXT_(card, 4, "rc%i", 0); return 0; out_error: i = 0; @@ -2567,45 +2597,86 @@ static int qeth_l3_send_ipa_arp_cmd(struct qeth_card *card, reply_cb, reply_param); } -static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) +static int qeth_l3_query_arp_cache_info(struct qeth_card *card, + enum qeth_prot_versions prot, + struct qeth_arp_query_info *qinfo) { struct qeth_cmd_buffer *iob; - struct qeth_arp_query_info qinfo = {0, }; + struct qeth_ipa_cmd *cmd; int tmp; int rc; + QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot); + + iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_QUERY_INFO, + sizeof(struct qeth_arp_query_data) - sizeof(char), + prot); + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + cmd->data.setassparms.data.query_arp.request_bits = 0x000F; + cmd->data.setassparms.data.query_arp.reply_bits = 0; + cmd->data.setassparms.data.query_arp.no_entries = 0; + rc = qeth_l3_send_ipa_arp_cmd(card, iob, + QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN, + qeth_l3_arp_query_cb, (void *)qinfo); + if (rc) { + tmp = rc; + QETH_DBF_MESSAGE(2, + "Error while querying ARP cache on %s: %s " + "(0x%x/%d)\n", QETH_CARD_IFNAME(card), + qeth_l3_arp_get_error_cause(&rc), tmp, tmp); + } + + return rc; +} + +static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) +{ + struct qeth_arp_query_info qinfo = {0, }; + int rc; + QETH_CARD_TEXT(card, 3, "arpquery"); if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ IPA_ARP_PROCESSING)) { - return -EOPNOTSUPP; + QETH_CARD_TEXT(card, 3, "arpqnsup"); + rc = -EOPNOTSUPP; + goto out; } /* get size of userspace buffer and mask_bits -> 6 bytes */ - if (copy_from_user(&qinfo, udata, 6)) - return -EFAULT; + if (copy_from_user(&qinfo, udata, 6)) { + rc = -EFAULT; + goto out; + } qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL); - if (!qinfo.udata) - return -ENOMEM; + if (!qinfo.udata) { + rc = -ENOMEM; + goto out; + } qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET; - iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING, - IPA_CMD_ASS_ARP_QUERY_INFO, - sizeof(int), QETH_PROT_IPV4); - - rc = qeth_l3_send_ipa_arp_cmd(card, iob, - QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN, - qeth_l3_arp_query_cb, (void *)&qinfo); + rc = qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV4, &qinfo); if (rc) { - tmp = rc; - QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s " - "(0x%x/%d)\n", QETH_CARD_IFNAME(card), - qeth_l3_arp_get_error_cause(&rc), tmp, tmp); if (copy_to_user(udata, qinfo.udata, 4)) rc = -EFAULT; + goto free_and_out; } else { - if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) +#ifdef CONFIG_QETH_IPV6 + if (qinfo.mask_bits & QETH_QARP_WITH_IPV6) { + /* fails in case of GuestLAN QDIO mode */ + qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV6, + &qinfo); + } +#endif + if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) { + QETH_CARD_TEXT(card, 4, "qactf"); rc = -EFAULT; + goto free_and_out; + } + QETH_CARD_TEXT_(card, 4, "qacts"); } +free_and_out: kfree(qinfo.udata); +out: return rc; } -- cgit v1.2.3-59-g8ed1b From f154b79cd7db221240ab6e8e4d844d3a3f10b04c Mon Sep 17 00:00:00 2001 From: Einar Lueck Date: Wed, 8 Dec 2010 02:57:59 +0000 Subject: qeth: support VIPA add/del in offline mode Only work through the IP adddress to do list if the card is UP or SOFTSETUP. Enables to configure VIPA add/del in offline mode. Signed-off-by: Einar Lueck Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index a7590551e574..d5e40c3e4bc3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -456,8 +456,11 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "sdiplist"); QETH_CARD_HEX(card, 2, &card, sizeof(void *)); - if (card->options.sniffer) + if ((card->state != CARD_STATE_UP && + card->state != CARD_STATE_SOFTSETUP) || card->options.sniffer) { return; + } + spin_lock_irqsave(&card->ip_lock, flags); tbd_list = card->ip_tbd_list; card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); -- cgit v1.2.3-59-g8ed1b From 91d4576bfe87980b1b86305c29912d96b96ce98e Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Wed, 8 Dec 2010 02:58:00 +0000 Subject: qeth: l3 add vlan hdr in passthru frames OSA l3 mode is hw accelerated VLAN only for IPv4. Take care we add the vlan hdr to a passthru frame in the device driver. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index d5e40c3e4bc3..e227e465bfc4 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3115,7 +3115,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_pull(new_skb, ETH_HLEN); } - if (ipv == 6 && card->vlangrp && + if (ipv != 4 && card->vlangrp && vlan_tx_tag_present(new_skb)) { skb_push(new_skb, VLAN_HLEN); skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); -- cgit v1.2.3-59-g8ed1b From a6a5ff26975c87a97f88c6ea077c325ff20c4cf2 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Wed, 8 Dec 2010 02:58:01 +0000 Subject: qeth: buffer count imbalance The used buffers counter is not incremented in case of an error so the counter can become negative. Increment the used buffers counter before checking for errors. Signed-off-by: Jan Glauber Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e6b2df0e73f5..b7d9dc0adc62 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2840,6 +2840,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - queue->card->perf_stats.outbound_do_qdio_start_time; + atomic_add(count, &queue->used_buffers); if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ @@ -2853,7 +2854,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, qeth_schedule_recovery(queue->card); return; } - atomic_add(count, &queue->used_buffers); if (queue->card->options.performance_stats) queue->card->perf_stats.bufs_sent += count; } -- cgit v1.2.3-59-g8ed1b From e1f91505025db74c261962dc16d58f79b9b0c83c Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 3 Dec 2010 19:55:19 +0000 Subject: ifb: remove the useless debug stats These debug stats are not exported, and become useless. Signed-off-by: Changli Gao Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- drivers/net/ifb.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index fe337bd121aa..e4cd6632c7db 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -42,16 +42,6 @@ struct ifb_private { struct tasklet_struct ifb_tasklet; int tasklet_pending; - /* mostly debug stats leave in for now */ - unsigned long st_task_enter; /* tasklet entered */ - unsigned long st_txq_refl_try; /* transmit queue refill attempt */ - unsigned long st_rxq_enter; /* receive queue entered */ - unsigned long st_rx2tx_tran; /* receive to trasmit transfers */ - unsigned long st_rxq_notenter; /*receiveQ not entered, resched */ - unsigned long st_rx_frm_egr; /* received from egress path */ - unsigned long st_rx_frm_ing; /* received from ingress path */ - unsigned long st_rxq_check; - unsigned long st_rxq_rsch; struct sk_buff_head rq; struct sk_buff_head tq; }; @@ -73,19 +63,14 @@ static void ri_tasklet(unsigned long dev) struct sk_buff *skb; txq = netdev_get_tx_queue(_dev, 0); - dp->st_task_enter++; if ((skb = skb_peek(&dp->tq)) == NULL) { - dp->st_txq_refl_try++; if (__netif_tx_trylock(txq)) { - dp->st_rxq_enter++; while ((skb = skb_dequeue(&dp->rq)) != NULL) { skb_queue_tail(&dp->tq, skb); - dp->st_rx2tx_tran++; } __netif_tx_unlock(txq); } else { /* reschedule */ - dp->st_rxq_notenter++; goto resched; } } @@ -112,10 +97,8 @@ static void ri_tasklet(unsigned long dev) skb->skb_iif = _dev->ifindex; if (from & AT_EGRESS) { - dp->st_rx_frm_egr++; dev_queue_xmit(skb); } else if (from & AT_INGRESS) { - dp->st_rx_frm_ing++; skb_pull(skb, skb->dev->hard_header_len); netif_rx(skb); } else @@ -123,13 +106,11 @@ static void ri_tasklet(unsigned long dev) } if (__netif_tx_trylock(txq)) { - dp->st_rxq_check++; if ((skb = skb_peek(&dp->rq)) == NULL) { dp->tasklet_pending = 0; if (netif_queue_stopped(_dev)) netif_wake_queue(_dev); } else { - dp->st_rxq_rsch++; __netif_tx_unlock(txq); goto resched; } -- cgit v1.2.3-59-g8ed1b From c6350362cbb19882ba0eb3578cc1abc07e6ea204 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 3 Dec 2010 19:55:20 +0000 Subject: ifb: remove unused macro TX_TIMEOUT Signed-off-by: Changli Gao Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- drivers/net/ifb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index e4cd6632c7db..d58c4f74f01a 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -36,8 +36,6 @@ #include #include -#define TX_TIMEOUT (2*HZ) - #define TX_Q_LIMIT 32 struct ifb_private { struct tasklet_struct ifb_tasklet; -- cgit v1.2.3-59-g8ed1b From 957fca95e3521e471aac4c2e4cfbc21f399bdd84 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 4 Dec 2010 15:01:52 +0000 Subject: ifb: use the lockless variants of skb_queue rq and tq are both protected by tx queue lock, so we can simply use the lockless variants of skb_queue. skb_queue_splice_tail_init() is used instead of the open coded and slow one. Signed-off-by: Changli Gao Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- drivers/net/ifb.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index d58c4f74f01a..bfa03db66691 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -63,9 +63,7 @@ static void ri_tasklet(unsigned long dev) txq = netdev_get_tx_queue(_dev, 0); if ((skb = skb_peek(&dp->tq)) == NULL) { if (__netif_tx_trylock(txq)) { - while ((skb = skb_dequeue(&dp->rq)) != NULL) { - skb_queue_tail(&dp->tq, skb); - } + skb_queue_splice_tail_init(&dp->rq, &dp->tq); __netif_tx_unlock(txq); } else { /* reschedule */ @@ -163,7 +161,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); } - skb_queue_tail(&dp->rq, skb); + __skb_queue_tail(&dp->rq, skb); if (!dp->tasklet_pending) { dp->tasklet_pending = 1; tasklet_schedule(&dp->ifb_tasklet); @@ -178,8 +176,8 @@ static int ifb_close(struct net_device *dev) tasklet_kill(&dp->ifb_tasklet); netif_stop_queue(dev); - skb_queue_purge(&dp->rq); - skb_queue_purge(&dp->tq); + __skb_queue_purge(&dp->rq); + __skb_queue_purge(&dp->tq); return 0; } @@ -188,8 +186,8 @@ static int ifb_open(struct net_device *dev) struct ifb_private *dp = netdev_priv(dev); tasklet_init(&dp->ifb_tasklet, ri_tasklet, (unsigned long)dev); - skb_queue_head_init(&dp->rq); - skb_queue_head_init(&dp->tq); + __skb_queue_head_init(&dp->rq); + __skb_queue_head_init(&dp->tq); netif_start_queue(dev); return 0; -- cgit v1.2.3-59-g8ed1b From 35d2856b4693e8de5d616307b56cef296b839157 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 8 Dec 2010 04:37:49 +0000 Subject: xfrm: Add Traffic Flow Confidentiality padding XFRM attribute The XFRMA_TFCPAD attribute for XFRM state installation configures Traffic Flow Confidentiality by padding ESP packets to a specified length. Signed-off-by: Martin Willi Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/xfrm.h | 1 + include/net/xfrm.h | 1 + net/xfrm/xfrm_user.c | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index b971e3848493..930fdd2de79c 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -283,6 +283,7 @@ enum xfrm_attr_type_t { XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ XFRMA_MARK, /* struct xfrm_mark */ + XFRMA_TFCPAD, /* __u32 */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 7fa5b005893e..b9f385da758e 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -143,6 +143,7 @@ struct xfrm_state { struct xfrm_id id; struct xfrm_selector sel; struct xfrm_mark mark; + u32 tfcpad; u32 genid; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8bae6b22c846..8eb889510916 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -148,7 +148,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, !attrs[XFRMA_ALG_AUTH_TRUNC]) || attrs[XFRMA_ALG_AEAD] || attrs[XFRMA_ALG_CRYPT] || - attrs[XFRMA_ALG_COMP]) + attrs[XFRMA_ALG_COMP] || + attrs[XFRMA_TFCPAD]) goto out; break; @@ -165,6 +166,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, attrs[XFRMA_ALG_CRYPT]) && attrs[XFRMA_ALG_AEAD]) goto out; + if (attrs[XFRMA_TFCPAD] && + p->mode != XFRM_MODE_TUNNEL) + goto out; break; case IPPROTO_COMP: @@ -172,7 +176,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, attrs[XFRMA_ALG_AEAD] || attrs[XFRMA_ALG_AUTH] || attrs[XFRMA_ALG_AUTH_TRUNC] || - attrs[XFRMA_ALG_CRYPT]) + attrs[XFRMA_ALG_CRYPT] || + attrs[XFRMA_TFCPAD]) goto out; break; @@ -186,6 +191,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, attrs[XFRMA_ALG_CRYPT] || attrs[XFRMA_ENCAP] || attrs[XFRMA_SEC_CTX] || + attrs[XFRMA_TFCPAD] || !attrs[XFRMA_COADDR]) goto out; break; @@ -439,6 +445,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, goto error; } + if (attrs[XFRMA_TFCPAD]) + x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]); + if (attrs[XFRMA_COADDR]) { x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]), sizeof(*x->coaddr), GFP_KERNEL); @@ -688,6 +697,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x, if (x->encap) NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); + if (x->tfcpad) + NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad); + if (xfrm_mark_put(skb, &x->mark)) goto nla_put_failure; @@ -2122,6 +2134,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) }, + [XFRMA_TFCPAD] = { .type = NLA_U32 }, }; static struct xfrm_link { @@ -2301,6 +2314,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) l += nla_total_size(sizeof(*x->calg)); if (x->encap) l += nla_total_size(sizeof(*x->encap)); + if (x->tfcpad) + l += nla_total_size(sizeof(x->tfcpad)); if (x->security) l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) + x->security->ctx_len); -- cgit v1.2.3-59-g8ed1b From d979e20f2b9f8a50c8d5f889e0b5d78580440d1f Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 8 Dec 2010 04:37:50 +0000 Subject: xfrm: Traffic Flow Confidentiality for IPv4 ESP Add TFC padding to all packets smaller than the boundary configured on the xfrm state. If the boundary is larger than the PMTU, limit padding to the PMTU. Signed-off-by: Martin Willi Acked-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/esp4.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 14ca1f1c3fb0..e42a905180f0 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -23,6 +23,8 @@ struct esp_skb_cb { #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) +static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); + /* * Allocate an AEAD request structure with extra space for SG and IV. * @@ -117,25 +119,35 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) int blksize; int clen; int alen; + int plen; + int tfclen; int nfrags; /* skb is pure payload to encrypt */ err = -ENOMEM; - /* Round to block size */ - clen = skb->len; - esp = x->data; aead = esp->aead; alen = crypto_aead_authsize(aead); + tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); + u32 padto; + + padto = min(x->tfcpad, esp4_get_mtu(x, dst->child_mtu_cached)); + if (skb->len < padto) + tfclen = padto - skb->len; + } blksize = ALIGN(crypto_aead_blocksize(aead), 4); - clen = ALIGN(clen + 2, blksize); + clen = ALIGN(skb->len + 2 + tfclen, blksize); if (esp->padlen) clen = ALIGN(clen, esp->padlen); + plen = clen - skb->len - tfclen; - if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0) + err = skb_cow_data(skb, tfclen + plen + alen, &trailer); + if (err < 0) goto error; nfrags = err; @@ -150,13 +162,17 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) /* Fill padding... */ tail = skb_tail_pointer(trailer); + if (tfclen) { + memset(tail, 0, tfclen); + tail += tfclen; + } do { int i; - for (i=0; ilen - 2; i++) + for (i = 0; i < plen - 2; i++) tail[i] = i + 1; } while (0); - tail[clen - skb->len - 2] = (clen - skb->len) - 2; - tail[clen - skb->len - 1] = *skb_mac_header(skb); + tail[plen - 2] = plen - 2; + tail[plen - 1] = *skb_mac_header(skb); pskb_put(skb, trailer, clen - skb->len + alen); skb_push(skb, -skb_network_offset(skb)); -- cgit v1.2.3-59-g8ed1b From 040253c931e336360453c8d81f76d1b010b2b5e7 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 8 Dec 2010 04:37:51 +0000 Subject: xfrm: Traffic Flow Confidentiality for IPv6 ESP Add TFC padding to all packets smaller than the boundary configured on the xfrm state. If the boundary is larger than the PMTU, limit padding to the PMTU. Signed-off-by: Martin Willi Acked-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/esp6.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index ee9b93bdd6a2..1b5c9825743b 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -49,6 +49,8 @@ struct esp_skb_cb { #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) +static u32 esp6_get_mtu(struct xfrm_state *x, int mtu); + /* * Allocate an AEAD request structure with extra space for SG and IV. * @@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) int blksize; int clen; int alen; + int plen; + int tfclen; int nfrags; u8 *iv; u8 *tail; @@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) /* skb is pure payload to encrypt */ err = -ENOMEM; - /* Round to block size */ - clen = skb->len; - aead = esp->aead; alen = crypto_aead_authsize(aead); + tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); + u32 padto; + + padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached)); + if (skb->len < padto) + tfclen = padto - skb->len; + } blksize = ALIGN(crypto_aead_blocksize(aead), 4); - clen = ALIGN(clen + 2, blksize); + clen = ALIGN(skb->len + 2 + tfclen, blksize); if (esp->padlen) clen = ALIGN(clen, esp->padlen); + plen = clen - skb->len - tfclen; - if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0) + err = skb_cow_data(skb, tfclen + plen + alen, &trailer); + if (err < 0) goto error; nfrags = err; @@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) /* Fill padding... */ tail = skb_tail_pointer(trailer); + if (tfclen) { + memset(tail, 0, tfclen); + tail += tfclen; + } do { int i; - for (i=0; ilen - 2; i++) + for (i = 0; i < plen - 2; i++) tail[i] = i + 1; } while (0); - tail[clen-skb->len - 2] = (clen - skb->len) - 2; - tail[clen - skb->len - 1] = *skb_mac_header(skb); + tail[plen - 2] = plen - 2; + tail[plen - 1] = *skb_mac_header(skb); pskb_put(skb, trailer, clen - skb->len + alen); skb_push(skb, -skb_network_offset(skb)); -- cgit v1.2.3-59-g8ed1b From 0e51d67ebb8e109a0990a13dafa937fb469aa3fb Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 9 Dec 2010 04:50:22 +0000 Subject: stmmac: Remove redundant unlikely() IS_ERR() already implies unlikely(), so it can be omitted here. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c0dc78571c62..20f803df8681 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -949,7 +949,7 @@ static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb) skb, skb->len); segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO); - if (unlikely(IS_ERR(segs))) + if (IS_ERR(segs)) goto sw_tso_end; do { -- cgit v1.2.3-59-g8ed1b From 376d940ee91318cc6becefbb9454bb4454d7473f Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 9 Dec 2010 04:37:48 +0000 Subject: inet6: Remove redundant unlikely() IS_ERR() already implies unlikely(), so it can be omitted here. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 54e8e42f7a88..059a3de647db 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -810,7 +810,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features) } rcu_read_unlock(); - if (unlikely(IS_ERR(segs))) + if (IS_ERR(segs)) goto out; for (skb = segs; skb; skb = skb->next) { -- cgit v1.2.3-59-g8ed1b From 4afb7527ac8cc7bd8f03570e12f6eed0eca03363 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 6 Dec 2010 12:33:01 +0000 Subject: sfc: convert references to LRO to GRO This driver now uses Generic Receive Offload, not the older LRO. Change references to LRO in names and comments. Signed-off-by: Stephen Hemminger Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/rx.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 6d0959b5158e..3925fd621177 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -37,7 +37,7 @@ * This driver supports two methods for allocating and using RX buffers: * each RX buffer may be backed by an skb or by an order-n page. * - * When LRO is in use then the second method has a lower overhead, + * When GRO is in use then the second method has a lower overhead, * since we don't have to allocate then free skbs on reassembled frames. * * Values: @@ -50,25 +50,25 @@ * * - Since pushing and popping descriptors are separated by the rx_queue * size, so the watermarks should be ~rxd_size. - * - The performance win by using page-based allocation for LRO is less - * than the performance hit of using page-based allocation of non-LRO, + * - The performance win by using page-based allocation for GRO is less + * than the performance hit of using page-based allocation of non-GRO, * so the watermarks should reflect this. * * Per channel we maintain a single variable, updated by each channel: * - * rx_alloc_level += (lro_performed ? RX_ALLOC_FACTOR_LRO : + * rx_alloc_level += (gro_performed ? RX_ALLOC_FACTOR_GRO : * RX_ALLOC_FACTOR_SKB) * Per NAPI poll interval, we constrain rx_alloc_level to 0..MAX (which * limits the hysteresis), and update the allocation strategy: * - * rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_LRO ? + * rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_GRO ? * RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB) */ static int rx_alloc_method = RX_ALLOC_METHOD_AUTO; -#define RX_ALLOC_LEVEL_LRO 0x2000 +#define RX_ALLOC_LEVEL_GRO 0x2000 #define RX_ALLOC_LEVEL_MAX 0x3000 -#define RX_ALLOC_FACTOR_LRO 1 +#define RX_ALLOC_FACTOR_GRO 1 #define RX_ALLOC_FACTOR_SKB (-2) /* This is the percentage fill level below which new RX descriptors @@ -441,19 +441,19 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, efx_rx_queue_channel(rx_queue)->n_rx_overlength++; } -/* Pass a received packet up through the generic LRO stack +/* Pass a received packet up through the generic GRO stack * * Handles driverlink veto, and passes the fragment up via - * the appropriate LRO method + * the appropriate GRO method */ -static void efx_rx_packet_lro(struct efx_channel *channel, +static void efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, bool checksummed) { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; - /* Pass the skb/page into the LRO engine */ + /* Pass the skb/page into the GRO engine */ if (rx_buf->page) { struct efx_nic *efx = channel->efx; struct page *page = rx_buf->page; @@ -499,7 +499,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel, if (gro_result == GRO_NORMAL) { channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; } else if (gro_result != GRO_DROP) { - channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO; + channel->rx_alloc_level += RX_ALLOC_FACTOR_GRO; channel->irq_mod_score += 2; } } @@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel, } if (likely(checksummed || rx_buf->page)) { - efx_rx_packet_lro(channel, rx_buf, checksummed); + efx_rx_packet_gro(channel, rx_buf, checksummed); return; } @@ -628,7 +628,7 @@ void efx_rx_strategy(struct efx_channel *channel) { enum efx_rx_alloc_method method = rx_alloc_method; - /* Only makes sense to use page based allocation if LRO is enabled */ + /* Only makes sense to use page based allocation if GRO is enabled */ if (!(channel->efx->net_dev->features & NETIF_F_GRO)) { method = RX_ALLOC_METHOD_SKB; } else if (method == RX_ALLOC_METHOD_AUTO) { @@ -639,7 +639,7 @@ void efx_rx_strategy(struct efx_channel *channel) channel->rx_alloc_level = RX_ALLOC_LEVEL_MAX; /* Decide on the allocation method */ - method = ((channel->rx_alloc_level > RX_ALLOC_LEVEL_LRO) ? + method = ((channel->rx_alloc_level > RX_ALLOC_LEVEL_GRO) ? RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB); } -- cgit v1.2.3-59-g8ed1b From a8d764b9832d3cc86019f71916665dd2d337d7c2 Mon Sep 17 00:00:00 2001 From: Junchang Wang Date: Wed, 8 Dec 2010 16:55:16 +0000 Subject: pktgen: adding prefetchw() call We know for sure pktgen is going to write skb->data right after *_alloc_skb, causing unnecessary cache misses. Idea is to add a prefetchw() call to prefetch the first cache line indicated by skb->data. On systems with Adjacent Cache Line Prefetch, it's probably two cache lines are prefetched. With this patch, pktgen on Intel SR1625 server with two E5530 quad-core processors and a single ixgbe-based NIC went from 8.63Mpps to 9.03Mpps, with 4.6% improvement. Signed-off-by: Junchang Wang Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/pktgen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2953b2abc971..18fe20dacc60 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2660,6 +2660,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, sprintf(pkt_dev->result, "No memory"); return NULL; } + prefetchw(skb->data); skb_reserve(skb, datalen); @@ -3007,6 +3008,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, sprintf(pkt_dev->result, "No memory"); return NULL; } + prefetchw(skb->data); skb_reserve(skb, 16); -- cgit v1.2.3-59-g8ed1b From 319d7e847355ec7e03d3c865917b2b0e2e592fb8 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 8 Dec 2010 13:19:58 +0000 Subject: enic: Add ndo_set_rx_mode support for enic vnics Add ndo_set_rx_mode support to register unicast and multicast address filters for enic devices Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 4 +- drivers/net/enic/enic_main.c | 121 +++++++++++++++++++++++++++++++++++-------- drivers/net/enic/enic_res.h | 1 + 3 files changed, 102 insertions(+), 24 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 70672541364e..8f374c1e2caf 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.7" +#define DRV_VERSION "1.4.1.8" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -78,8 +78,10 @@ struct enic { spinlock_t devcmd_lock; u8 mac_addr[ETH_ALEN]; u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN]; + u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN]; unsigned int flags; unsigned int mc_count; + unsigned int uc_count; int csum_rx_enabled; u32 port_mtu; u32 rx_coalesce_usecs; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9f293fa24768..1931f156777c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1002,7 +1002,7 @@ static int enic_dev_packet_filter(struct enic *enic, int directed, return err; } -static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr) +static int enic_dev_add_addr(struct enic *enic, u8 *addr) { int err; @@ -1013,7 +1013,7 @@ static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr) return err; } -static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr) +static int enic_dev_del_addr(struct enic *enic, u8 *addr) { int err; @@ -1024,29 +1024,19 @@ static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr) return err; } -/* netif_tx_lock held, BHs disabled */ -static void enic_set_multicast_list(struct net_device *netdev) +static void enic_add_multicast_addr_list(struct enic *enic) { - struct enic *enic = netdev_priv(netdev); + struct net_device *netdev = enic->netdev; struct netdev_hw_addr *ha; - int directed = 1; - int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0; - int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0; - int promisc = (netdev->flags & IFF_PROMISC) ? 1 : 0; unsigned int mc_count = netdev_mc_count(netdev); - int allmulti = (netdev->flags & IFF_ALLMULTI) || - mc_count > ENIC_MULTICAST_PERFECT_FILTERS; - unsigned int flags = netdev->flags | (allmulti ? IFF_ALLMULTI : 0); u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN]; unsigned int i, j; - if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) + if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) { + netdev_warn(netdev, "Registering only %d out of %d " + "multicast addresses\n", + ENIC_MULTICAST_PERFECT_FILTERS, mc_count); mc_count = ENIC_MULTICAST_PERFECT_FILTERS; - - if (enic->flags != flags) { - enic->flags = flags; - enic_dev_packet_filter(enic, directed, - multicast, broadcast, promisc, allmulti); } /* Is there an easier way? Trying to minimize to @@ -1068,7 +1058,7 @@ static void enic_set_multicast_list(struct net_device *netdev) mc_addr[j]) == 0) break; if (j == mc_count) - enic_dev_del_multicast_addr(enic, enic->mc_addr[i]); + enic_dev_del_addr(enic, enic->mc_addr[i]); } for (i = 0; i < mc_count; i++) { @@ -1077,7 +1067,7 @@ static void enic_set_multicast_list(struct net_device *netdev) enic->mc_addr[j]) == 0) break; if (j == enic->mc_count) - enic_dev_add_multicast_addr(enic, mc_addr[i]); + enic_dev_add_addr(enic, mc_addr[i]); } /* Save the list to compare against next time @@ -1089,6 +1079,89 @@ static void enic_set_multicast_list(struct net_device *netdev) enic->mc_count = mc_count; } +static void enic_add_unicast_addr_list(struct enic *enic) +{ + struct net_device *netdev = enic->netdev; + struct netdev_hw_addr *ha; + unsigned int uc_count = netdev_uc_count(netdev); + u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN]; + unsigned int i, j; + + if (uc_count > ENIC_UNICAST_PERFECT_FILTERS) { + netdev_warn(netdev, "Registering only %d out of %d " + "unicast addresses\n", + ENIC_UNICAST_PERFECT_FILTERS, uc_count); + uc_count = ENIC_UNICAST_PERFECT_FILTERS; + } + + /* Is there an easier way? Trying to minimize to + * calls to add/del unicast addrs. We keep the + * addrs from the last call in enic->uc_addr and + * look for changes to add/del. + */ + + i = 0; + netdev_for_each_uc_addr(ha, netdev) { + if (i == uc_count) + break; + memcpy(uc_addr[i++], ha->addr, ETH_ALEN); + } + + for (i = 0; i < enic->uc_count; i++) { + for (j = 0; j < uc_count; j++) + if (compare_ether_addr(enic->uc_addr[i], + uc_addr[j]) == 0) + break; + if (j == uc_count) + enic_dev_del_addr(enic, enic->uc_addr[i]); + } + + for (i = 0; i < uc_count; i++) { + for (j = 0; j < enic->uc_count; j++) + if (compare_ether_addr(uc_addr[i], + enic->uc_addr[j]) == 0) + break; + if (j == enic->uc_count) + enic_dev_add_addr(enic, uc_addr[i]); + } + + /* Save the list to compare against next time + */ + + for (i = 0; i < uc_count; i++) + memcpy(enic->uc_addr[i], uc_addr[i], ETH_ALEN); + + enic->uc_count = uc_count; +} + +/* netif_tx_lock held, BHs disabled */ +static void enic_set_rx_mode(struct net_device *netdev) +{ + struct enic *enic = netdev_priv(netdev); + int directed = 1; + int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0; + int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0; + int promisc = (netdev->flags & IFF_PROMISC) || + netdev_uc_count(netdev) > ENIC_UNICAST_PERFECT_FILTERS; + int allmulti = (netdev->flags & IFF_ALLMULTI) || + netdev_mc_count(netdev) > ENIC_MULTICAST_PERFECT_FILTERS; + unsigned int flags = netdev->flags | + (allmulti ? IFF_ALLMULTI : 0) | + (promisc ? IFF_PROMISC : 0); + + if (enic->flags != flags) { + enic->flags = flags; + enic_dev_packet_filter(enic, directed, + multicast, broadcast, promisc, allmulti); + } + + if (!promisc) { + enic_add_unicast_addr_list(enic); + if (!allmulti) + enic_add_multicast_addr_list(enic); + } +} + /* rtnl lock is held */ static void enic_vlan_rx_register(struct net_device *netdev, struct vlan_group *vlan_group) @@ -1852,7 +1925,7 @@ static int enic_open(struct net_device *netdev) vnic_rq_enable(&enic->rq[i]); enic_dev_add_station_addr(enic); - enic_set_multicast_list(netdev); + enic_set_rx_mode(netdev); netif_wake_queue(netdev); @@ -2328,7 +2401,8 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_start_xmit = enic_hard_start_xmit, .ndo_get_stats = enic_get_stats, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = enic_set_multicast_list, + .ndo_set_rx_mode = enic_set_rx_mode, + .ndo_set_multicast_list = enic_set_rx_mode, .ndo_set_mac_address = enic_set_mac_address_dynamic, .ndo_change_mtu = enic_change_mtu, .ndo_vlan_rx_register = enic_vlan_rx_register, @@ -2349,7 +2423,8 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_get_stats = enic_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = enic_set_mac_address, - .ndo_set_multicast_list = enic_set_multicast_list, + .ndo_set_rx_mode = enic_set_rx_mode, + .ndo_set_multicast_list = enic_set_rx_mode, .ndo_change_mtu = enic_change_mtu, .ndo_vlan_rx_register = enic_vlan_rx_register, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 9a103d9ef9e2..25be2734c3fe 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -34,6 +34,7 @@ #define ENIC_MAX_MTU 9000 #define ENIC_MULTICAST_PERFECT_FILTERS 32 +#define ENIC_UNICAST_PERFECT_FILTERS 32 #define ENIC_NON_TSO_MAX_DESC 16 -- cgit v1.2.3-59-g8ed1b From 0b1c00fc3e9f8d658e0632da7e7ee57bed779ec7 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 8 Dec 2010 13:53:58 +0000 Subject: enic: Add ndo_set_vf_mac support for enic dynamic devices This patch implements the ndo_set_vf_mac netdev operation for enic dynamic devices. It treats the mac address set by IFLA_VF_MAC as a special case to use it in the port profile provisioning data. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 3 ++- drivers/net/enic/enic_main.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 8f374c1e2caf..bd473a9d739a 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.8" +#define DRV_VERSION "1.4.1.9" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -61,6 +61,7 @@ struct enic_port_profile { char name[PORT_PROFILE_MAX]; u8 instance_uuid[PORT_UUID_MAX]; u8 host_uuid[PORT_UUID_MAX]; + u8 vf_mac[ETH_ALEN]; }; /* Per-instance private data structure */ diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 1931f156777c..ddeffb5192ae 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1231,6 +1231,23 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error) return err; } +static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) +{ + struct enic *enic = netdev_priv(netdev); + + if (vf != PORT_SELF_VF) + return -EOPNOTSUPP; + + /* Ignore the vf argument for now. We can assume the request + * is coming on a vf. + */ + if (is_valid_ether_addr(mac)) { + memcpy(enic->pp.vf_mac, mac, ETH_ALEN); + return 0; + } else + return -EINVAL; +} + static int enic_set_port_profile(struct enic *enic, u8 *mac) { struct vic_provinfo *vp; @@ -2411,6 +2428,9 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_tx_timeout = enic_tx_timeout, .ndo_set_vf_port = enic_set_vf_port, .ndo_get_vf_port = enic_get_vf_port, +#ifdef IFLA_VF_MAX + .ndo_set_vf_mac = enic_set_vf_mac, +#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = enic_poll_controller, #endif -- cgit v1.2.3-59-g8ed1b From 29639059a0122d95b34b5475bd9fee3910b401a3 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 8 Dec 2010 13:54:03 +0000 Subject: enic: Use VF mac set by IFLA_VF_MAC in port profile provisioning data This patch adds support in enic 802.1Qbh port profile provisioning code to use the mac address set by IFLA_VF_MAC. For now we handle this mac as a special case for a VM mac address sent to us by libvirt. The VM mac address is sent to the switch along with the rest of the port profile provisioning data. This patch also adds calls to register and deregister the mac address during port profile association/deassociation. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 1 + drivers/net/enic/enic_main.c | 79 +++++++++++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index bd473a9d739a..577067eef652 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -62,6 +62,7 @@ struct enic_port_profile { u8 instance_uuid[PORT_UUID_MAX]; u8 host_uuid[PORT_UUID_MAX]; u8 vf_mac[ETH_ALEN]; + u8 mac_addr[ETH_ALEN]; }; /* Per-instance private data structure */ diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index ddeffb5192ae..21be989e6a14 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1278,9 +1278,14 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, strlen(enic->pp.name) + 1, enic->pp.name); - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, - ETH_ALEN, mac); + if (!is_zero_ether_addr(enic->pp.mac_addr)) + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, enic->pp.mac_addr); + else + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, mac); if (enic->pp.set & ENIC_SET_INSTANCE) { sprintf(uuid_str, "%pUB", enic->pp.instance_uuid); @@ -1300,16 +1305,18 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) vic_provinfo_free(vp); if (err) return err; + + enic->pp.set |= ENIC_SET_APPLIED; break; case PORT_REQUEST_DISASSOCIATE: + enic->pp.set &= ~ENIC_SET_APPLIED; break; default: return -EINVAL; } - enic->pp.set |= ENIC_SET_APPLIED; return 0; } @@ -1317,29 +1324,31 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, struct nlattr *port[]) { struct enic *enic = netdev_priv(netdev); + struct enic_port_profile new_pp; + int err = 0; - memset(&enic->pp, 0, sizeof(enic->pp)); + memset(&new_pp, 0, sizeof(new_pp)); if (port[IFLA_PORT_REQUEST]) { - enic->pp.set |= ENIC_SET_REQUEST; - enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); + new_pp.set |= ENIC_SET_REQUEST; + new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); } if (port[IFLA_PORT_PROFILE]) { - enic->pp.set |= ENIC_SET_NAME; - memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), + new_pp.set |= ENIC_SET_NAME; + memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]), PORT_PROFILE_MAX); } if (port[IFLA_PORT_INSTANCE_UUID]) { - enic->pp.set |= ENIC_SET_INSTANCE; - memcpy(enic->pp.instance_uuid, + new_pp.set |= ENIC_SET_INSTANCE; + memcpy(new_pp.instance_uuid, nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); } if (port[IFLA_PORT_HOST_UUID]) { - enic->pp.set |= ENIC_SET_HOST; - memcpy(enic->pp.host_uuid, + new_pp.set |= ENIC_SET_HOST; + memcpy(new_pp.host_uuid, nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); } @@ -1347,21 +1356,39 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, if (vf != PORT_SELF_VF) return -EOPNOTSUPP; - if (!(enic->pp.set & ENIC_SET_REQUEST)) + if (!(new_pp.set & ENIC_SET_REQUEST)) return -EOPNOTSUPP; - if (enic->pp.request == PORT_REQUEST_ASSOCIATE) { - - /* If the interface mac addr hasn't been assigned, - * assign a random mac addr before setting port- - * profile. - */ + if (new_pp.request == PORT_REQUEST_ASSOCIATE) { + /* Special case handling */ + if (!is_zero_ether_addr(enic->pp.vf_mac)) + memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN); if (is_zero_ether_addr(netdev->dev_addr)) random_ether_addr(netdev->dev_addr); + } else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) { + if (!is_zero_ether_addr(enic->pp.mac_addr)) + enic_dev_del_addr(enic, enic->pp.mac_addr); } - return enic_set_port_profile(enic, netdev->dev_addr); + memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile)); + + err = enic_set_port_profile(enic, netdev->dev_addr); + if (err) + goto set_port_profile_cleanup; + + if (!is_zero_ether_addr(enic->pp.mac_addr)) + enic_dev_add_addr(enic, enic->pp.mac_addr); + +set_port_profile_cleanup: + memset(enic->pp.vf_mac, 0, ETH_ALEN); + + if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) { + memset(netdev->dev_addr, 0, ETH_ALEN); + memset(enic->pp.mac_addr, 0, ETH_ALEN); + } + + return err; } static int enic_get_vf_port(struct net_device *netdev, int vf, @@ -1941,7 +1968,10 @@ static int enic_open(struct net_device *netdev) for (i = 0; i < enic->rq_count; i++) vnic_rq_enable(&enic->rq[i]); - enic_dev_add_station_addr(enic); + if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr)) + enic_dev_add_addr(enic, enic->pp.mac_addr); + else + enic_dev_add_station_addr(enic); enic_set_rx_mode(netdev); netif_wake_queue(netdev); @@ -1989,7 +2019,10 @@ static int enic_stop(struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev); - enic_dev_del_station_addr(enic); + if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr)) + enic_dev_del_addr(enic, enic->pp.mac_addr); + else + enic_dev_del_station_addr(enic); for (i = 0; i < enic->wq_count; i++) { err = vnic_wq_disable(&enic->wq[i]); -- cgit v1.2.3-59-g8ed1b From e596e6e4d578f2639416e620d367a3af34814a40 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 9 Dec 2010 12:08:35 +0000 Subject: ethtool: Report link-down while interface is down While an interface is down, many implementations of ethtool_ops::get_link, including the default, ethtool_op_get_link(), will report the last link state seen while the interface was up. In general the current physical link state is not available if the interface is down. Define ETHTOOL_GLINK to reflect whether the interface *and* any physical port have a working link, and consistently return 0 when the interface is down. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 4 +++- net/core/ethtool.c | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 6628a507fd3b..1908929204a9 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -691,7 +691,9 @@ struct ethtool_ops { #define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ #define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */ #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */ -#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */ +/* Get link status for host, i.e. whether the interface *and* the + * physical port (if there is one) are up (ethtool_value). */ +#define ETHTOOL_GLINK 0x0000000a #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ #define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */ #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d5bc28818883..17741782a345 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -891,6 +891,20 @@ static int ethtool_nway_reset(struct net_device *dev) return dev->ethtool_ops->nway_reset(dev); } +static int ethtool_get_link(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { .cmd = ETHTOOL_GLINK }; + + if (!dev->ethtool_ops->get_link) + return -EOPNOTSUPP; + + edata.data = netif_running(dev) && dev->ethtool_ops->get_link(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; @@ -1530,8 +1544,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) rc = ethtool_nway_reset(dev); break; case ETHTOOL_GLINK: - rc = ethtool_get_value(dev, useraddr, ethcmd, - dev->ethtool_ops->get_link); + rc = ethtool_get_link(dev, useraddr); break; case ETHTOOL_GEEPROM: rc = ethtool_get_eeprom(dev, useraddr); -- cgit v1.2.3-59-g8ed1b From ed4ba4b5b96742d29225308ccccbdb1810b63064 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 9 Dec 2010 12:10:25 +0000 Subject: netdev: Use default implementation of ethtool_ops::get_link where possible Various drivers are using implementations of ethtool_ops::get_link that are equivalent to the default ethtool_op_get_link(). Change them to use that instead. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/e1000e/ethtool.c | 16 +--------------- drivers/net/ibmveth.c | 7 +------ drivers/net/igbvf/ethtool.c | 7 +------ drivers/net/iseries_veth.c | 7 +------ drivers/net/mv643xx_eth.c | 7 +------ drivers/net/pxa168_eth.c | 7 +------ drivers/net/sfc/ethtool.c | 9 +-------- drivers/net/sunlance.c | 10 +--------- 8 files changed, 8 insertions(+), 62 deletions(-) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 8984d165a39b..3612900b3bfe 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -194,20 +194,6 @@ static int e1000_get_settings(struct net_device *netdev, return 0; } -static u32 e1000_get_link(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_hw *hw = &adapter->hw; - - /* - * Avoid touching hardware registers when possible, otherwise - * link negotiation can get messed up when user-level scripts - * are rapidly polling the driver to see if link is up. - */ - return netif_running(netdev) ? netif_carrier_ok(netdev) : - !!(er32(STATUS) & E1000_STATUS_LU); -} - static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) { struct e1000_mac_info *mac = &adapter->hw.mac; @@ -2024,7 +2010,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .get_msglevel = e1000_get_msglevel, .set_msglevel = e1000_set_msglevel, .nway_reset = e1000_nway_reset, - .get_link = e1000_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = e1000_get_eeprom_len, .get_eeprom = e1000_get_eeprom, .set_eeprom = e1000_set_eeprom, diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index c454b45ca7ec..5522d459654c 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -729,11 +729,6 @@ static void netdev_get_drvinfo(struct net_device *dev, sizeof(info->version) - 1); } -static u32 netdev_get_link(struct net_device *dev) -{ - return 1; -} - static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data) { struct ibmveth_adapter *adapter = netdev_priv(dev); @@ -918,7 +913,7 @@ static void ibmveth_get_ethtool_stats(struct net_device *dev, static const struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, .get_settings = netdev_get_settings, - .get_link = netdev_get_link, + .get_link = ethtool_op_get_link, .set_tx_csum = ibmveth_set_tx_csum, .get_rx_csum = ibmveth_get_rx_csum, .set_rx_csum = ibmveth_set_rx_csum, diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index abb3606928fb..ed6e3d910247 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -110,11 +110,6 @@ static int igbvf_get_settings(struct net_device *netdev, return 0; } -static u32 igbvf_get_link(struct net_device *netdev) -{ - return netif_carrier_ok(netdev); -} - static int igbvf_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -515,7 +510,7 @@ static const struct ethtool_ops igbvf_ethtool_ops = { .get_msglevel = igbvf_get_msglevel, .set_msglevel = igbvf_set_msglevel, .nway_reset = igbvf_nway_reset, - .get_link = igbvf_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = igbvf_get_eeprom_len, .get_eeprom = igbvf_get_eeprom, .set_eeprom = igbvf_set_eeprom, diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 38e15be6d513..63ac531f5996 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1009,15 +1009,10 @@ static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return 0; } -static u32 veth_get_link(struct net_device *dev) -{ - return 1; -} - static const struct ethtool_ops ops = { .get_drvinfo = veth_get_drvinfo, .get_settings = veth_get_settings, - .get_link = veth_get_link, + .get_link = ethtool_op_get_link, }; static const struct net_device_ops veth_netdev_ops = { diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index dd2b6a71c6d7..ce31e74a559b 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1514,11 +1514,6 @@ static int mv643xx_eth_nway_reset(struct net_device *dev) return genphy_restart_aneg(mp->phy); } -static u32 mv643xx_eth_get_link(struct net_device *dev) -{ - return !!netif_carrier_ok(dev); -} - static int mv643xx_eth_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { @@ -1658,7 +1653,7 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = { .set_settings = mv643xx_eth_set_settings, .get_drvinfo = mv643xx_eth_get_drvinfo, .nway_reset = mv643xx_eth_nway_reset, - .get_link = mv643xx_eth_get_link, + .get_link = ethtool_op_get_link, .get_coalesce = mv643xx_eth_get_coalesce, .set_coalesce = mv643xx_eth_set_coalesce, .get_ringparam = mv643xx_eth_get_ringparam, diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 18c0297743f1..04ed27d0b6be 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -1450,16 +1450,11 @@ static void pxa168_get_drvinfo(struct net_device *dev, strncpy(info->bus_info, "N/A", 32); } -static u32 pxa168_get_link(struct net_device *dev) -{ - return !!netif_carrier_ok(dev); -} - static const struct ethtool_ops pxa168_ethtool_ops = { .get_settings = pxa168_get_settings, .set_settings = pxa168_set_settings, .get_drvinfo = pxa168_get_drvinfo, - .get_link = pxa168_get_link, + .get_link = ethtool_op_get_link, }; static const struct net_device_ops pxa168_eth_netdev_ops = { diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 5e50e57b0ae2..0e8bb19ed60d 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -620,13 +620,6 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev) return mdio45_nway_restart(&efx->mdio); } -static u32 efx_ethtool_get_link(struct net_device *net_dev) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - return efx->link_state.up; -} - static int efx_ethtool_get_coalesce(struct net_device *net_dev, struct ethtool_coalesce *coalesce) { @@ -1047,7 +1040,7 @@ const struct ethtool_ops efx_ethtool_ops = { .get_msglevel = efx_ethtool_get_msglevel, .set_msglevel = efx_ethtool_set_msglevel, .nway_reset = efx_ethtool_nway_reset, - .get_link = efx_ethtool_get_link, + .get_link = ethtool_op_get_link, .get_coalesce = efx_ethtool_get_coalesce, .set_coalesce = efx_ethtool_set_coalesce, .get_ringparam = efx_ethtool_get_ringparam, diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 2cf84e5968b2..767e1e2b210d 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1295,17 +1295,9 @@ static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvin strcpy(info->version, "2.02"); } -static u32 sparc_lance_get_link(struct net_device *dev) -{ - /* We really do not keep track of this, but this - * is better than not reporting anything at all. - */ - return 1; -} - static const struct ethtool_ops sparc_lance_ethtool_ops = { .get_drvinfo = sparc_lance_get_drvinfo, - .get_link = sparc_lance_get_link, + .get_link = ethtool_op_get_link, }; static const struct net_device_ops sparc_lance_ops = { -- cgit v1.2.3-59-g8ed1b From c053fd96d0d3d18c721f880b8fdd0b925894d9c4 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 10 Dec 2010 16:02:20 -0800 Subject: af_packet: use swap() instead of the open coded macro XC() Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/packet/af_packet.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 246a04a13234..e79efaf06389 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2501,22 +2501,20 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, mutex_lock(&po->pg_vec_lock); if (closing || atomic_read(&po->mapped) == 0) { err = 0; -#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) spin_lock_bh(&rb_queue->lock); - pg_vec = XC(rb->pg_vec, pg_vec); + swap(rb->pg_vec, pg_vec); rb->frame_max = (req->tp_frame_nr - 1); rb->head = 0; rb->frame_size = req->tp_frame_size; spin_unlock_bh(&rb_queue->lock); - order = XC(rb->pg_vec_order, order); - req->tp_block_nr = XC(rb->pg_vec_len, req->tp_block_nr); + swap(rb->pg_vec_order, order); + swap(rb->pg_vec_len, req->tp_block_nr); rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE; po->prot_hook.func = (po->rx_ring.pg_vec) ? tpacket_rcv : packet_rcv; skb_queue_purge(rb_queue); -#undef XC if (atomic_read(&po->mapped)) pr_err("packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); -- cgit v1.2.3-59-g8ed1b From deef4b522b814593407cfd56216840c2b75e9f15 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 9 Dec 2010 17:38:11 +0000 Subject: bridge: Use consistent NF_DROP returns in nf_pre_routing The nf_pre_routing functions in bridging have collected two distinct ways of returning NF_DROP over the years, inline and via goto. There is no reason for preferring either one. So this patch arbitrarily picks the inline variant and converts the all the gotos. Also removes a redundant comment. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 16f5c333596a..4b5b66d07bba 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -562,26 +562,26 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, u32 pkt_len; if (skb->len < sizeof(struct ipv6hdr)) - goto inhdr_error; + return NF_DROP; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) - goto inhdr_error; + return NF_DROP; hdr = ipv6_hdr(skb); if (hdr->version != 6) - goto inhdr_error; + return NF_DROP; pkt_len = ntohs(hdr->payload_len); if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) { if (pkt_len + sizeof(struct ipv6hdr) > skb->len) - goto inhdr_error; + return NF_DROP; if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) - goto inhdr_error; + return NF_DROP; } if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) - goto inhdr_error; + return NF_DROP; nf_bridge_put(skb->nf_bridge); if (!nf_bridge_alloc(skb)) @@ -594,9 +594,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, br_nf_pre_routing_finish_ipv6); return NF_STOLEN; - -inhdr_error: - return NF_DROP; } /* Direct IPv6 traffic to br_nf_pre_routing_ipv6. @@ -615,11 +612,11 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, __u32 len = nf_bridge_encap_header_len(skb); if (unlikely(!pskb_may_pull(skb, len))) - goto out; + return NF_DROP; p = br_port_get_rcu(in); if (p == NULL) - goto out; + return NF_DROP; br = p->br; if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || @@ -641,8 +638,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, nf_bridge_pull_encap_header_rcsum(skb); if (br_parse_ip_options(skb)) - /* Drop invalid packet */ - goto out; + return NF_DROP; nf_bridge_put(skb->nf_bridge); if (!nf_bridge_alloc(skb)) @@ -656,9 +652,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, br_nf_pre_routing_finish); return NF_STOLEN; - -out: - return NF_DROP; } -- cgit v1.2.3-59-g8ed1b From 528f727279ae840db8a06c94f5e82cdaeb00da6f Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:02:56 +0000 Subject: vxge: code cleanup and reorganization Move function locations to remove the need for internal declarations and other misc clean-ups. Signed-off-by: Jon Mason Signed-off-by: Arpit Patel Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 3457 +++++++++++++++++++-------------------- drivers/net/vxge/vxge-config.h | 34 +- drivers/net/vxge/vxge-main.c | 474 +++--- drivers/net/vxge/vxge-main.h | 8 +- drivers/net/vxge/vxge-traffic.c | 1451 ++++++++-------- drivers/net/vxge/vxge-traffic.h | 21 +- 6 files changed, 2639 insertions(+), 2806 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index a0241fe72d8b..1169aa387cab 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -21,100 +21,15 @@ #include "vxge-config.h" #include "vxge-main.h" -static enum vxge_hw_status -__vxge_hw_fifo_delete( - struct __vxge_hw_vpath_handle *vpath_handle); - -static struct __vxge_hw_blockpool_entry * -__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *hldev, - u32 size); - -static void -__vxge_hw_blockpool_block_free(struct __vxge_hw_device *hldev, - struct __vxge_hw_blockpool_entry *entry); - -static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, - void *block_addr, - u32 length, - struct pci_dev *dma_h, - struct pci_dev *acc_handle); - -static enum vxge_hw_status -__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, - struct __vxge_hw_blockpool *blockpool, - u32 pool_size, - u32 pool_max); - -static void -__vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool); - -static void * -__vxge_hw_blockpool_malloc(struct __vxge_hw_device *hldev, - u32 size, - struct vxge_hw_mempool_dma *dma_object); - -static void -__vxge_hw_blockpool_free(struct __vxge_hw_device *hldev, - void *memblock, - u32 size, - struct vxge_hw_mempool_dma *dma_object); - -static void -__vxge_hw_channel_free( - struct __vxge_hw_channel *channel); - -static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp); - -static enum vxge_hw_status -__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config); - -static enum vxge_hw_status -__vxge_hw_device_register_poll( - void __iomem *reg, - u64 mask, u32 max_millis); - -static inline enum vxge_hw_status -__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr, - u64 mask, u32 max_millis) -{ - __vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr); - wmb(); - - __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr); - wmb(); - - return __vxge_hw_device_register_poll(addr, mask, max_millis); +#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \ + status = __vxge_hw_vpath_stats_access(vpath, \ + VXGE_HW_STATS_OP_READ, \ + offset, \ + &val64); \ + if (status != VXGE_HW_OK) \ + return status; \ } -static struct vxge_hw_mempool* -__vxge_hw_mempool_create(struct __vxge_hw_device *devh, u32 memblock_size, - u32 item_size, u32 private_size, u32 items_initial, - u32 items_max, struct vxge_hw_mempool_cbs *mp_callback, - void *userdata); - -static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool); - -static enum vxge_hw_status -__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_vpath_stats_hw_info *hw_stats); - -static enum vxge_hw_status -vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vpath_handle); - -static enum vxge_hw_status -__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg); - -static void -__vxge_hw_vp_terminate(struct __vxge_hw_device *devh, u32 vp_id); - -static enum vxge_hw_status -__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats); - -static enum vxge_hw_status -__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats); - static void vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg) { @@ -124,8 +39,6 @@ vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg) val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); writeq(val64, &vp_reg->rxmac_vcfg0); val64 = readq(&vp_reg->rxmac_vcfg0); - - return; } /* @@ -197,6 +110,50 @@ void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev) } } +/* + * __vxge_hw_device_register_poll + * Will poll certain register for specified amount of time. + * Will poll until masked bit is not cleared. + */ +static enum vxge_hw_status +__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis) +{ + u64 val64; + u32 i = 0; + enum vxge_hw_status ret = VXGE_HW_FAIL; + + udelay(10); + + do { + val64 = readq(reg); + if (!(val64 & mask)) + return VXGE_HW_OK; + udelay(100); + } while (++i <= 9); + + i = 0; + do { + val64 = readq(reg); + if (!(val64 & mask)) + return VXGE_HW_OK; + mdelay(1); + } while (++i <= max_millis); + + return ret; +} + +static inline enum vxge_hw_status +__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr, + u64 mask, u32 max_millis) +{ + __vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr); + wmb(); + __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr); + wmb(); + + return __vxge_hw_device_register_poll(addr, mask, max_millis); +} + static enum vxge_hw_status vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action, u32 fw_memo, u32 offset, u64 *data0, u64 *data1, @@ -445,77 +402,6 @@ vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, return status; } -/* - * __vxge_hw_channel_allocate - Allocate memory for channel - * This function allocates required memory for the channel and various arrays - * in the channel - */ -static struct __vxge_hw_channel * -__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, - enum __vxge_hw_channel_type type, - u32 length, u32 per_dtr_space, void *userdata) -{ - struct __vxge_hw_channel *channel; - struct __vxge_hw_device *hldev; - int size = 0; - u32 vp_id; - - hldev = vph->vpath->hldev; - vp_id = vph->vpath->vp_id; - - switch (type) { - case VXGE_HW_CHANNEL_TYPE_FIFO: - size = sizeof(struct __vxge_hw_fifo); - break; - case VXGE_HW_CHANNEL_TYPE_RING: - size = sizeof(struct __vxge_hw_ring); - break; - default: - break; - } - - channel = kzalloc(size, GFP_KERNEL); - if (channel == NULL) - goto exit0; - INIT_LIST_HEAD(&channel->item); - - channel->common_reg = hldev->common_reg; - channel->first_vp_id = hldev->first_vp_id; - channel->type = type; - channel->devh = hldev; - channel->vph = vph; - channel->userdata = userdata; - channel->per_dtr_space = per_dtr_space; - channel->length = length; - channel->vp_id = vp_id; - - channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); - if (channel->work_arr == NULL) - goto exit1; - - channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); - if (channel->free_arr == NULL) - goto exit1; - channel->free_ptr = length; - - channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); - if (channel->reserve_arr == NULL) - goto exit1; - channel->reserve_ptr = length; - channel->reserve_top = 0; - - channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); - if (channel->orig_arr == NULL) - goto exit1; - - return channel; -exit1: - __vxge_hw_channel_free(channel); - -exit0: - return NULL; -} - /* * __vxge_hw_channel_free - Free memory allocated for channel * This function deallocates memory from the channel and various arrays @@ -609,38 +495,6 @@ static void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) pci_save_state(hldev->pdev); } -/* - * __vxge_hw_device_register_poll - * Will poll certain register for specified amount of time. - * Will poll until masked bit is not cleared. - */ -static enum vxge_hw_status -__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis) -{ - u64 val64; - u32 i = 0; - enum vxge_hw_status ret = VXGE_HW_FAIL; - - udelay(10); - - do { - val64 = readq(reg); - if (!(val64 & mask)) - return VXGE_HW_OK; - udelay(100); - } while (++i <= 9); - - i = 0; - do { - val64 = readq(reg); - if (!(val64 & mask)) - return VXGE_HW_OK; - mdelay(1); - } while (++i <= max_millis); - - return ret; -} - /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset * in progress * This routine checks the vpath reset in progress register is turned zero @@ -655,6 +509,60 @@ __vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog) return status; } +/* + * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion. + * Set the swapper bits appropriately for the lagacy section. + */ +static enum vxge_hw_status +__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg) +{ + u64 val64; + enum vxge_hw_status status = VXGE_HW_OK; + + val64 = readq(&legacy_reg->toc_swapper_fb); + + wmb(); + + switch (val64) { + case VXGE_HW_SWAPPER_INITIAL_VALUE: + return status; + + case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED: + writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, + &legacy_reg->pifm_rd_swap_en); + writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, + &legacy_reg->pifm_rd_flip_en); + writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, + &legacy_reg->pifm_wr_swap_en); + writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, + &legacy_reg->pifm_wr_flip_en); + break; + + case VXGE_HW_SWAPPER_BYTE_SWAPPED: + writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, + &legacy_reg->pifm_rd_swap_en); + writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, + &legacy_reg->pifm_wr_swap_en); + break; + + case VXGE_HW_SWAPPER_BIT_FLIPPED: + writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, + &legacy_reg->pifm_rd_flip_en); + writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, + &legacy_reg->pifm_wr_flip_en); + break; + } + + wmb(); + + val64 = readq(&legacy_reg->toc_swapper_fb); + + if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE) + status = VXGE_HW_ERR_SWAPPER_CTRL; + + return status; +} + /* * __vxge_hw_device_toc_get * This routine sets the swapper and reads the toc pointer and returns the @@ -1132,7 +1040,6 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64); for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!((hw_info->vpath_mask) & vxge_mBIT(i))) continue; @@ -1196,9 +1103,221 @@ exit: } /* - * vxge_hw_device_initialize - Initialize Titan device. - * Initialize Titan device. Note that all the arguments of this public API - * are 'IN', including @hldev. Driver cooperates with + * __vxge_hw_blockpool_destroy - Deallocates the block pool + */ +static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) +{ + struct __vxge_hw_device *hldev; + struct list_head *p, *n; + u16 ret; + + if (blockpool == NULL) { + ret = 1; + goto exit; + } + + hldev = blockpool->hldev; + + list_for_each_safe(p, n, &blockpool->free_block_list) { + pci_unmap_single(hldev->pdev, + ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, + ((struct __vxge_hw_blockpool_entry *)p)->length, + PCI_DMA_BIDIRECTIONAL); + + vxge_os_dma_free(hldev->pdev, + ((struct __vxge_hw_blockpool_entry *)p)->memblock, + &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); + + list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); + kfree(p); + blockpool->pool_size--; + } + + list_for_each_safe(p, n, &blockpool->free_entry_list) { + list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); + kfree((void *)p); + } + ret = 0; +exit: + return; +} + +/* + * __vxge_hw_blockpool_create - Create block pool + */ +static enum vxge_hw_status +__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, + struct __vxge_hw_blockpool *blockpool, + u32 pool_size, + u32 pool_max) +{ + u32 i; + struct __vxge_hw_blockpool_entry *entry = NULL; + void *memblock; + dma_addr_t dma_addr; + struct pci_dev *dma_handle; + struct pci_dev *acc_handle; + enum vxge_hw_status status = VXGE_HW_OK; + + if (blockpool == NULL) { + status = VXGE_HW_FAIL; + goto blockpool_create_exit; + } + + blockpool->hldev = hldev; + blockpool->block_size = VXGE_HW_BLOCK_SIZE; + blockpool->pool_size = 0; + blockpool->pool_max = pool_max; + blockpool->req_out = 0; + + INIT_LIST_HEAD(&blockpool->free_block_list); + INIT_LIST_HEAD(&blockpool->free_entry_list); + + for (i = 0; i < pool_size + pool_max; i++) { + entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry), + GFP_KERNEL); + if (entry == NULL) { + __vxge_hw_blockpool_destroy(blockpool); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto blockpool_create_exit; + } + list_add(&entry->item, &blockpool->free_entry_list); + } + + for (i = 0; i < pool_size; i++) { + memblock = vxge_os_dma_malloc( + hldev->pdev, + VXGE_HW_BLOCK_SIZE, + &dma_handle, + &acc_handle); + if (memblock == NULL) { + __vxge_hw_blockpool_destroy(blockpool); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto blockpool_create_exit; + } + + dma_addr = pci_map_single(hldev->pdev, memblock, + VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL); + if (unlikely(pci_dma_mapping_error(hldev->pdev, + dma_addr))) { + vxge_os_dma_free(hldev->pdev, memblock, &acc_handle); + __vxge_hw_blockpool_destroy(blockpool); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto blockpool_create_exit; + } + + if (!list_empty(&blockpool->free_entry_list)) + entry = (struct __vxge_hw_blockpool_entry *) + list_first_entry(&blockpool->free_entry_list, + struct __vxge_hw_blockpool_entry, + item); + + if (entry == NULL) + entry = + kzalloc(sizeof(struct __vxge_hw_blockpool_entry), + GFP_KERNEL); + if (entry != NULL) { + list_del(&entry->item); + entry->length = VXGE_HW_BLOCK_SIZE; + entry->memblock = memblock; + entry->dma_addr = dma_addr; + entry->acc_handle = acc_handle; + entry->dma_handle = dma_handle; + list_add(&entry->item, + &blockpool->free_block_list); + blockpool->pool_size++; + } else { + __vxge_hw_blockpool_destroy(blockpool); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto blockpool_create_exit; + } + } + +blockpool_create_exit: + return status; +} + +/* + * __vxge_hw_device_fifo_config_check - Check fifo configuration. + * Check the fifo configuration + */ +static enum vxge_hw_status +__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config) +{ + if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) || + (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS)) + return VXGE_HW_BADCFG_FIFO_BLOCKS; + + return VXGE_HW_OK; +} + +/* + * __vxge_hw_device_vpath_config_check - Check vpath configuration. + * Check the vpath configuration + */ +static enum vxge_hw_status +__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config) +{ + enum vxge_hw_status status; + + if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) || + (vp_config->min_bandwidth > VXGE_HW_VPATH_BANDWIDTH_MAX)) + return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH; + + status = __vxge_hw_device_fifo_config_check(&vp_config->fifo); + if (status != VXGE_HW_OK) + return status; + + if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) && + ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) || + (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU))) + return VXGE_HW_BADCFG_VPATH_MTU; + + if ((vp_config->rpa_strip_vlan_tag != + VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) && + (vp_config->rpa_strip_vlan_tag != + VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) && + (vp_config->rpa_strip_vlan_tag != + VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE)) + return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG; + + return VXGE_HW_OK; +} + +/* + * __vxge_hw_device_config_check - Check device configuration. + * Check the device configuration + */ +static enum vxge_hw_status +__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config) +{ + u32 i; + enum vxge_hw_status status; + + if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) && + (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) && + (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) && + (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF)) + return VXGE_HW_BADCFG_INTR_MODE; + + if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) && + (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE)) + return VXGE_HW_BADCFG_RTS_MAC_EN; + + for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + status = __vxge_hw_device_vpath_config_check( + &new_config->vp_config[i]); + if (status != VXGE_HW_OK) + return status; + } + + return VXGE_HW_OK; +} + +/* + * vxge_hw_device_initialize - Initialize Titan device. + * Initialize Titan device. Note that all the arguments of this public API + * are 'IN', including @hldev. Driver cooperates with * OS to find new Titan device, locate its PCI and memory spaces. * * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW @@ -1303,40 +1422,276 @@ vxge_hw_device_terminate(struct __vxge_hw_device *hldev) } /* - * vxge_hw_device_stats_get - Get the device hw statistics. - * Returns the vpath h/w stats for the device. + * __vxge_hw_vpath_stats_access - Get the statistics from the given location + * and offset and perform an operation */ -enum vxge_hw_status -vxge_hw_device_stats_get(struct __vxge_hw_device *hldev, - struct vxge_hw_device_stats_hw_info *hw_stats) +static enum vxge_hw_status +__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath, + u32 operation, u32 offset, u64 *stat) { - u32 i; + u64 val64; enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg; - for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!(hldev->vpaths_deployed & vxge_mBIT(i)) || - (hldev->virtual_paths[i].vp_open == - VXGE_HW_VP_NOT_OPEN)) - continue; + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto vpath_stats_access_exit; + } - memcpy(hldev->virtual_paths[i].hw_stats_sav, - hldev->virtual_paths[i].hw_stats, - sizeof(struct vxge_hw_vpath_stats_hw_info)); + vp_reg = vpath->vp_reg; - status = __vxge_hw_vpath_stats_get( - &hldev->virtual_paths[i], - hldev->virtual_paths[i].hw_stats); - } + val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) | + VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE | + VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset); - memcpy(hw_stats, &hldev->stats.hw_dev_info_stats, - sizeof(struct vxge_hw_device_stats_hw_info)); + status = __vxge_hw_pio_mem_write64(val64, + &vp_reg->xmac_stats_access_cmd, + VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE, + vpath->hldev->config.device_poll_millis); + if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ)) + *stat = readq(&vp_reg->xmac_stats_access_data); + else + *stat = 0; +vpath_stats_access_exit: return status; } /* - * vxge_hw_driver_stats_get - Get the device sw statistics. - * Returns the vpath s/w stats for the device. + * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath + */ +static enum vxge_hw_status +__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats) +{ + u64 *val64; + int i; + u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET; + enum vxge_hw_status status = VXGE_HW_OK; + + val64 = (u64 *)vpath_tx_stats; + + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; + } + + for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) { + status = __vxge_hw_vpath_stats_access(vpath, + VXGE_HW_STATS_OP_READ, + offset, val64); + if (status != VXGE_HW_OK) + goto exit; + offset++; + val64++; + } +exit: + return status; +} + +/* + * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath + */ +static enum vxge_hw_status +__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats) +{ + u64 *val64; + enum vxge_hw_status status = VXGE_HW_OK; + int i; + u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET; + val64 = (u64 *) vpath_rx_stats; + + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; + } + for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) { + status = __vxge_hw_vpath_stats_access(vpath, + VXGE_HW_STATS_OP_READ, + offset >> 3, val64); + if (status != VXGE_HW_OK) + goto exit; + + offset += 8; + val64++; + } +exit: + return status; +} + +/* + * __vxge_hw_vpath_stats_get - Get the vpath hw statistics. + */ +static enum vxge_hw_status +__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_vpath_stats_hw_info *hw_stats) +{ + u64 val64; + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg; + + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; + } + vp_reg = vpath->vp_reg; + + val64 = readq(&vp_reg->vpath_debug_stats0); + hw_stats->ini_num_mwr_sent = + (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64); + + val64 = readq(&vp_reg->vpath_debug_stats1); + hw_stats->ini_num_mrd_sent = + (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64); + + val64 = readq(&vp_reg->vpath_debug_stats2); + hw_stats->ini_num_cpl_rcvd = + (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64); + + val64 = readq(&vp_reg->vpath_debug_stats3); + hw_stats->ini_num_mwr_byte_sent = + VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64); + + val64 = readq(&vp_reg->vpath_debug_stats4); + hw_stats->ini_num_cpl_byte_rcvd = + VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64); + + val64 = readq(&vp_reg->vpath_debug_stats5); + hw_stats->wrcrdtarb_xoff = + (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64); + + val64 = readq(&vp_reg->vpath_debug_stats6); + hw_stats->rdcrdtarb_xoff = + (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64); + + val64 = readq(&vp_reg->vpath_genstats_count01); + hw_stats->vpath_genstats_count0 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0( + val64); + + val64 = readq(&vp_reg->vpath_genstats_count01); + hw_stats->vpath_genstats_count1 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1( + val64); + + val64 = readq(&vp_reg->vpath_genstats_count23); + hw_stats->vpath_genstats_count2 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2( + val64); + + val64 = readq(&vp_reg->vpath_genstats_count01); + hw_stats->vpath_genstats_count3 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3( + val64); + + val64 = readq(&vp_reg->vpath_genstats_count4); + hw_stats->vpath_genstats_count4 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4( + val64); + + val64 = readq(&vp_reg->vpath_genstats_count5); + hw_stats->vpath_genstats_count5 = + (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5( + val64); + + status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats); + if (status != VXGE_HW_OK) + goto exit; + + status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats); + if (status != VXGE_HW_OK) + goto exit; + + VXGE_HW_VPATH_STATS_PIO_READ( + VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET); + + hw_stats->prog_event_vnum0 = + (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64); + + hw_stats->prog_event_vnum1 = + (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64); + + VXGE_HW_VPATH_STATS_PIO_READ( + VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET); + + hw_stats->prog_event_vnum2 = + (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64); + + hw_stats->prog_event_vnum3 = + (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64); + + val64 = readq(&vp_reg->rx_multi_cast_stats); + hw_stats->rx_multi_cast_frame_discard = + (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64); + + val64 = readq(&vp_reg->rx_frm_transferred); + hw_stats->rx_frm_transferred = + (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64); + + val64 = readq(&vp_reg->rxd_returned); + hw_stats->rxd_returned = + (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64); + + val64 = readq(&vp_reg->dbg_stats_rx_mpa); + hw_stats->rx_mpa_len_fail_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64); + hw_stats->rx_mpa_mrk_fail_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64); + hw_stats->rx_mpa_crc_fail_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64); + + val64 = readq(&vp_reg->dbg_stats_rx_fau); + hw_stats->rx_permitted_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64); + hw_stats->rx_vp_reset_discarded_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64); + hw_stats->rx_wol_frms = + (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64); + + val64 = readq(&vp_reg->tx_vp_reset_discarded_frms); + hw_stats->tx_vp_reset_discarded_frms = + (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS( + val64); +exit: + return status; +} + +/* + * vxge_hw_device_stats_get - Get the device hw statistics. + * Returns the vpath h/w stats for the device. + */ +enum vxge_hw_status +vxge_hw_device_stats_get(struct __vxge_hw_device *hldev, + struct vxge_hw_device_stats_hw_info *hw_stats) +{ + u32 i; + enum vxge_hw_status status = VXGE_HW_OK; + + for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!(hldev->vpaths_deployed & vxge_mBIT(i)) || + (hldev->virtual_paths[i].vp_open == + VXGE_HW_VP_NOT_OPEN)) + continue; + + memcpy(hldev->virtual_paths[i].hw_stats_sav, + hldev->virtual_paths[i].hw_stats, + sizeof(struct vxge_hw_vpath_stats_hw_info)); + + status = __vxge_hw_vpath_stats_get( + &hldev->virtual_paths[i], + hldev->virtual_paths[i].hw_stats); + } + + memcpy(hw_stats, &hldev->stats.hw_dev_info_stats, + sizeof(struct vxge_hw_device_stats_hw_info)); + + return status; +} + +/* + * vxge_hw_driver_stats_get - Get the device sw statistics. + * Returns the vpath s/w stats for the device. */ enum vxge_hw_status vxge_hw_driver_stats_get( struct __vxge_hw_device *hldev, @@ -1468,7 +1823,6 @@ vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev, status = vxge_hw_device_xmac_aggr_stats_get(hldev, 0, &xmac_stats->aggr_stats[0]); - if (status != VXGE_HW_OK) goto exit; @@ -1843,206 +2197,376 @@ exit: } /* - * __vxge_hw_ring_create - Create a Ring - * This function creates Ring and initializes it. + * __vxge_hw_channel_allocate - Allocate memory for channel + * This function allocates required memory for the channel and various arrays + * in the channel */ -static enum vxge_hw_status -__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, - struct vxge_hw_ring_attr *attr) +static struct __vxge_hw_channel * +__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, + enum __vxge_hw_channel_type type, + u32 length, u32 per_dtr_space, + void *userdata) { - enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_ring *ring; - u32 ring_length; - struct vxge_hw_ring_config *config; + struct __vxge_hw_channel *channel; struct __vxge_hw_device *hldev; + int size = 0; u32 vp_id; - struct vxge_hw_mempool_cbs ring_mp_callback; - if ((vp == NULL) || (attr == NULL)) { - status = VXGE_HW_FAIL; - goto exit; - } + hldev = vph->vpath->hldev; + vp_id = vph->vpath->vp_id; - hldev = vp->vpath->hldev; - vp_id = vp->vpath->vp_id; - - config = &hldev->config.vp_config[vp_id].ring; - - ring_length = config->ring_blocks * - vxge_hw_ring_rxds_per_block_get(config->buffer_mode); - - ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp, - VXGE_HW_CHANNEL_TYPE_RING, - ring_length, - attr->per_rxd_space, - attr->userdata); - - if (ring == NULL) { - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto exit; + switch (type) { + case VXGE_HW_CHANNEL_TYPE_FIFO: + size = sizeof(struct __vxge_hw_fifo); + break; + case VXGE_HW_CHANNEL_TYPE_RING: + size = sizeof(struct __vxge_hw_ring); + break; + default: + break; } - vp->vpath->ringh = ring; - ring->vp_id = vp_id; - ring->vp_reg = vp->vpath->vp_reg; - ring->common_reg = hldev->common_reg; - ring->stats = &vp->vpath->sw_stats->ring_stats; - ring->config = config; - ring->callback = attr->callback; - ring->rxd_init = attr->rxd_init; - ring->rxd_term = attr->rxd_term; - ring->buffer_mode = config->buffer_mode; - ring->rxds_limit = config->rxds_limit; - - ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode); - ring->rxd_priv_size = - sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space; - ring->per_rxd_space = attr->per_rxd_space; + channel = kzalloc(size, GFP_KERNEL); + if (channel == NULL) + goto exit0; + INIT_LIST_HEAD(&channel->item); - ring->rxd_priv_size = - ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) / - VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; + channel->common_reg = hldev->common_reg; + channel->first_vp_id = hldev->first_vp_id; + channel->type = type; + channel->devh = hldev; + channel->vph = vph; + channel->userdata = userdata; + channel->per_dtr_space = per_dtr_space; + channel->length = length; + channel->vp_id = vp_id; - /* how many RxDs can fit into one block. Depends on configured - * buffer_mode. */ - ring->rxds_per_block = - vxge_hw_ring_rxds_per_block_get(config->buffer_mode); + channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + if (channel->work_arr == NULL) + goto exit1; - /* calculate actual RxD block private size */ - ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block; - ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc; - ring->mempool = __vxge_hw_mempool_create(hldev, - VXGE_HW_BLOCK_SIZE, - VXGE_HW_BLOCK_SIZE, - ring->rxdblock_priv_size, - ring->config->ring_blocks, - ring->config->ring_blocks, - &ring_mp_callback, - ring); + channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + if (channel->free_arr == NULL) + goto exit1; + channel->free_ptr = length; - if (ring->mempool == NULL) { - __vxge_hw_ring_delete(vp); - return VXGE_HW_ERR_OUT_OF_MEMORY; - } + channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + if (channel->reserve_arr == NULL) + goto exit1; + channel->reserve_ptr = length; + channel->reserve_top = 0; - status = __vxge_hw_channel_initialize(&ring->channel); - if (status != VXGE_HW_OK) { - __vxge_hw_ring_delete(vp); - goto exit; - } + channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + if (channel->orig_arr == NULL) + goto exit1; - /* Note: - * Specifying rxd_init callback means two things: - * 1) rxds need to be initialized by driver at channel-open time; - * 2) rxds need to be posted at channel-open time - * (that's what the initial_replenish() below does) - * Currently we don't have a case when the 1) is done without the 2). - */ - if (ring->rxd_init) { - status = vxge_hw_ring_replenish(ring); - if (status != VXGE_HW_OK) { - __vxge_hw_ring_delete(vp); - goto exit; - } - } + return channel; +exit1: + __vxge_hw_channel_free(channel); - /* initial replenish will increment the counter in its post() routine, - * we have to reset it */ - ring->stats->common_stats.usage_cnt = 0; -exit: - return status; +exit0: + return NULL; } /* - * __vxge_hw_ring_abort - Returns the RxD - * This function terminates the RxDs of ring + * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async + * Adds a block to block pool */ -static enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring) +static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, + void *block_addr, + u32 length, + struct pci_dev *dma_h, + struct pci_dev *acc_handle) { - void *rxdh; - struct __vxge_hw_channel *channel; + struct __vxge_hw_blockpool *blockpool; + struct __vxge_hw_blockpool_entry *entry = NULL; + dma_addr_t dma_addr; + enum vxge_hw_status status = VXGE_HW_OK; + u32 req_out; - channel = &ring->channel; + blockpool = &devh->block_pool; - for (;;) { - vxge_hw_channel_dtr_try_complete(channel, &rxdh); + if (block_addr == NULL) { + blockpool->req_out--; + status = VXGE_HW_FAIL; + goto exit; + } - if (rxdh == NULL) - break; + dma_addr = pci_map_single(devh->pdev, block_addr, length, + PCI_DMA_BIDIRECTIONAL); - vxge_hw_channel_dtr_complete(channel); + if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) { + vxge_os_dma_free(devh->pdev, block_addr, &acc_handle); + blockpool->req_out--; + status = VXGE_HW_FAIL; + goto exit; + } - if (ring->rxd_term) - ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED, - channel->userdata); + if (!list_empty(&blockpool->free_entry_list)) + entry = (struct __vxge_hw_blockpool_entry *) + list_first_entry(&blockpool->free_entry_list, + struct __vxge_hw_blockpool_entry, + item); - vxge_hw_channel_dtr_free(channel, rxdh); - } + if (entry == NULL) + entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); + else + list_del(&entry->item); - return VXGE_HW_OK; -} + if (entry != NULL) { + entry->length = length; + entry->memblock = block_addr; + entry->dma_addr = dma_addr; + entry->acc_handle = acc_handle; + entry->dma_handle = dma_h; + list_add(&entry->item, &blockpool->free_block_list); + blockpool->pool_size++; + status = VXGE_HW_OK; + } else + status = VXGE_HW_ERR_OUT_OF_MEMORY; -/* - * __vxge_hw_ring_reset - Resets the ring - * This function resets the ring during vpath reset operation - */ -static enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_channel *channel; + blockpool->req_out--; - channel = &ring->channel; + req_out = blockpool->req_out; +exit: + return; +} - __vxge_hw_ring_abort(ring); +static inline void +vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh, unsigned long size) +{ + gfp_t flags; + void *vaddr; - status = __vxge_hw_channel_reset(channel); + if (in_interrupt()) + flags = GFP_ATOMIC | GFP_DMA; + else + flags = GFP_KERNEL | GFP_DMA; - if (status != VXGE_HW_OK) - goto exit; + vaddr = kmalloc((size), flags); - if (ring->rxd_init) { - status = vxge_hw_ring_replenish(ring); - if (status != VXGE_HW_OK) - goto exit; - } -exit: - return status; + vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev); } /* - * __vxge_hw_ring_delete - Removes the ring - * This function freeup the memory pool and removes the ring + * __vxge_hw_blockpool_blocks_add - Request additional blocks */ -static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp) +static +void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool) { - struct __vxge_hw_ring *ring = vp->vpath->ringh; - - __vxge_hw_ring_abort(ring); - - if (ring->mempool) - __vxge_hw_mempool_destroy(ring->mempool); + u32 nreq = 0, i; - vp->vpath->ringh = NULL; - __vxge_hw_channel_free(&ring->channel); + if ((blockpool->pool_size + blockpool->req_out) < + VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) { + nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE; + blockpool->req_out += nreq; + } - return VXGE_HW_OK; + for (i = 0; i < nreq; i++) + vxge_os_dma_malloc_async( + ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + blockpool->hldev, VXGE_HW_BLOCK_SIZE); } /* - * __vxge_hw_mempool_grow - * Will resize mempool up to %num_allocate value. + * __vxge_hw_blockpool_malloc - Allocate a memory block from pool + * Allocates a block of memory of given size, either from block pool + * or by calling vxge_os_dma_malloc() */ -static enum vxge_hw_status -__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, - u32 *num_allocated) +static void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, + struct vxge_hw_mempool_dma *dma_object) { - u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0; - u32 n_items = mempool->items_per_memblock; - u32 start_block_idx = mempool->memblocks_allocated; - u32 end_block_idx = mempool->memblocks_allocated + num_allocate; + struct __vxge_hw_blockpool_entry *entry = NULL; + struct __vxge_hw_blockpool *blockpool; + void *memblock = NULL; enum vxge_hw_status status = VXGE_HW_OK; - *num_allocated = 0; + blockpool = &devh->block_pool; + + if (size != blockpool->block_size) { + + memblock = vxge_os_dma_malloc(devh->pdev, size, + &dma_object->handle, + &dma_object->acc_handle); + + if (memblock == NULL) { + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto exit; + } + + dma_object->addr = pci_map_single(devh->pdev, memblock, size, + PCI_DMA_BIDIRECTIONAL); + + if (unlikely(pci_dma_mapping_error(devh->pdev, + dma_object->addr))) { + vxge_os_dma_free(devh->pdev, memblock, + &dma_object->acc_handle); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto exit; + } + + } else { + + if (!list_empty(&blockpool->free_block_list)) + entry = (struct __vxge_hw_blockpool_entry *) + list_first_entry(&blockpool->free_block_list, + struct __vxge_hw_blockpool_entry, + item); + + if (entry != NULL) { + list_del(&entry->item); + dma_object->addr = entry->dma_addr; + dma_object->handle = entry->dma_handle; + dma_object->acc_handle = entry->acc_handle; + memblock = entry->memblock; + + list_add(&entry->item, + &blockpool->free_entry_list); + blockpool->pool_size--; + } + + if (memblock != NULL) + __vxge_hw_blockpool_blocks_add(blockpool); + } +exit: + return memblock; +} + +/* + * __vxge_hw_blockpool_blocks_remove - Free additional blocks + */ +static void +__vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool) +{ + struct list_head *p, *n; + + list_for_each_safe(p, n, &blockpool->free_block_list) { + + if (blockpool->pool_size < blockpool->pool_max) + break; + + pci_unmap_single( + ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, + ((struct __vxge_hw_blockpool_entry *)p)->length, + PCI_DMA_BIDIRECTIONAL); + + vxge_os_dma_free( + ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + ((struct __vxge_hw_blockpool_entry *)p)->memblock, + &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); + + list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); + + list_add(p, &blockpool->free_entry_list); + + blockpool->pool_size--; + + } +} + +/* + * __vxge_hw_blockpool_free - Frees the memory allcoated with + * __vxge_hw_blockpool_malloc + */ +static void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, + void *memblock, u32 size, + struct vxge_hw_mempool_dma *dma_object) +{ + struct __vxge_hw_blockpool_entry *entry = NULL; + struct __vxge_hw_blockpool *blockpool; + enum vxge_hw_status status = VXGE_HW_OK; + + blockpool = &devh->block_pool; + + if (size != blockpool->block_size) { + pci_unmap_single(devh->pdev, dma_object->addr, size, + PCI_DMA_BIDIRECTIONAL); + vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle); + } else { + + if (!list_empty(&blockpool->free_entry_list)) + entry = (struct __vxge_hw_blockpool_entry *) + list_first_entry(&blockpool->free_entry_list, + struct __vxge_hw_blockpool_entry, + item); + + if (entry == NULL) + entry = vmalloc(sizeof( + struct __vxge_hw_blockpool_entry)); + else + list_del(&entry->item); + + if (entry != NULL) { + entry->length = size; + entry->memblock = memblock; + entry->dma_addr = dma_object->addr; + entry->acc_handle = dma_object->acc_handle; + entry->dma_handle = dma_object->handle; + list_add(&entry->item, + &blockpool->free_block_list); + blockpool->pool_size++; + status = VXGE_HW_OK; + } else + status = VXGE_HW_ERR_OUT_OF_MEMORY; + + if (status == VXGE_HW_OK) + __vxge_hw_blockpool_blocks_remove(blockpool); + } +} + +/* + * vxge_hw_mempool_destroy + */ +static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) +{ + u32 i, j; + struct __vxge_hw_device *devh = mempool->devh; + + for (i = 0; i < mempool->memblocks_allocated; i++) { + struct vxge_hw_mempool_dma *dma_object; + + vxge_assert(mempool->memblocks_arr[i]); + vxge_assert(mempool->memblocks_dma_arr + i); + + dma_object = mempool->memblocks_dma_arr + i; + + for (j = 0; j < mempool->items_per_memblock; j++) { + u32 index = i * mempool->items_per_memblock + j; + + /* to skip last partially filled(if any) memblock */ + if (index >= mempool->items_current) + break; + } + + vfree(mempool->memblocks_priv_arr[i]); + + __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i], + mempool->memblock_size, dma_object); + } + + vfree(mempool->items_arr); + vfree(mempool->memblocks_dma_arr); + vfree(mempool->memblocks_priv_arr); + vfree(mempool->memblocks_arr); + vfree(mempool); +} + +/* + * __vxge_hw_mempool_grow + * Will resize mempool up to %num_allocate value. + */ +static enum vxge_hw_status +__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, + u32 *num_allocated) +{ + u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0; + u32 n_items = mempool->items_per_memblock; + u32 start_block_idx = mempool->memblocks_allocated; + u32 end_block_idx = mempool->memblocks_allocated + num_allocate; + enum vxge_hw_status status = VXGE_HW_OK; + + *num_allocated = 0; if (end_block_idx > mempool->memblocks_max) { status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2118,16 +2642,15 @@ exit: * with size enough to hold %items_initial number of items. Memory is * DMA-able but client must map/unmap before interoperating with the device. */ -static struct vxge_hw_mempool* -__vxge_hw_mempool_create( - struct __vxge_hw_device *devh, - u32 memblock_size, - u32 item_size, - u32 items_priv_size, - u32 items_initial, - u32 items_max, - struct vxge_hw_mempool_cbs *mp_callback, - void *userdata) +static struct vxge_hw_mempool * +__vxge_hw_mempool_create(struct __vxge_hw_device *devh, + u32 memblock_size, + u32 item_size, + u32 items_priv_size, + u32 items_initial, + u32 items_max, + struct vxge_hw_mempool_cbs *mp_callback, + void *userdata) { enum vxge_hw_status status = VXGE_HW_OK; u32 memblocks_to_allocate; @@ -2185,7 +2708,6 @@ __vxge_hw_mempool_create( mempool->memblocks_dma_arr = vzalloc(sizeof(struct vxge_hw_mempool_dma) * mempool->memblocks_max); - if (mempool->memblocks_dma_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2222,122 +2744,188 @@ exit: } /* - * vxge_hw_mempool_destroy + * __vxge_hw_ring_abort - Returns the RxD + * This function terminates the RxDs of ring */ -static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) +static enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring) { - u32 i, j; - struct __vxge_hw_device *devh = mempool->devh; - - for (i = 0; i < mempool->memblocks_allocated; i++) { - struct vxge_hw_mempool_dma *dma_object; + void *rxdh; + struct __vxge_hw_channel *channel; - vxge_assert(mempool->memblocks_arr[i]); - vxge_assert(mempool->memblocks_dma_arr + i); + channel = &ring->channel; - dma_object = mempool->memblocks_dma_arr + i; + for (;;) { + vxge_hw_channel_dtr_try_complete(channel, &rxdh); - for (j = 0; j < mempool->items_per_memblock; j++) { - u32 index = i * mempool->items_per_memblock + j; + if (rxdh == NULL) + break; - /* to skip last partially filled(if any) memblock */ - if (index >= mempool->items_current) - break; - } + vxge_hw_channel_dtr_complete(channel); - vfree(mempool->memblocks_priv_arr[i]); + if (ring->rxd_term) + ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED, + channel->userdata); - __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i], - mempool->memblock_size, dma_object); + vxge_hw_channel_dtr_free(channel, rxdh); } - vfree(mempool->items_arr); + return VXGE_HW_OK; +} - vfree(mempool->memblocks_dma_arr); +/* + * __vxge_hw_ring_reset - Resets the ring + * This function resets the ring during vpath reset operation + */ +static enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_channel *channel; - vfree(mempool->memblocks_priv_arr); + channel = &ring->channel; - vfree(mempool->memblocks_arr); + __vxge_hw_ring_abort(ring); - vfree(mempool); + status = __vxge_hw_channel_reset(channel); + + if (status != VXGE_HW_OK) + goto exit; + + if (ring->rxd_init) { + status = vxge_hw_ring_replenish(ring); + if (status != VXGE_HW_OK) + goto exit; + } +exit: + return status; } /* - * __vxge_hw_device_fifo_config_check - Check fifo configuration. - * Check the fifo configuration + * __vxge_hw_ring_delete - Removes the ring + * This function freeup the memory pool and removes the ring */ static enum vxge_hw_status -__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config) +__vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp) { - if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) || - (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS)) - return VXGE_HW_BADCFG_FIFO_BLOCKS; + struct __vxge_hw_ring *ring = vp->vpath->ringh; - return VXGE_HW_OK; -} + __vxge_hw_ring_abort(ring); -/* - * __vxge_hw_device_vpath_config_check - Check vpath configuration. - * Check the vpath configuration - */ -static enum vxge_hw_status -__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config) -{ - enum vxge_hw_status status; - - if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) || - (vp_config->min_bandwidth > - VXGE_HW_VPATH_BANDWIDTH_MAX)) - return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH; - - status = __vxge_hw_device_fifo_config_check(&vp_config->fifo); - if (status != VXGE_HW_OK) - return status; - - if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) && - ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) || - (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU))) - return VXGE_HW_BADCFG_VPATH_MTU; + if (ring->mempool) + __vxge_hw_mempool_destroy(ring->mempool); - if ((vp_config->rpa_strip_vlan_tag != - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) && - (vp_config->rpa_strip_vlan_tag != - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) && - (vp_config->rpa_strip_vlan_tag != - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE)) - return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG; + vp->vpath->ringh = NULL; + __vxge_hw_channel_free(&ring->channel); return VXGE_HW_OK; } /* - * __vxge_hw_device_config_check - Check device configuration. - * Check the device configuration + * __vxge_hw_ring_create - Create a Ring + * This function creates Ring and initializes it. */ static enum vxge_hw_status -__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config) +__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, + struct vxge_hw_ring_attr *attr) { - u32 i; - enum vxge_hw_status status; + enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_ring *ring; + u32 ring_length; + struct vxge_hw_ring_config *config; + struct __vxge_hw_device *hldev; + u32 vp_id; + struct vxge_hw_mempool_cbs ring_mp_callback; - if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) && - (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) && - (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) && - (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF)) - return VXGE_HW_BADCFG_INTR_MODE; + if ((vp == NULL) || (attr == NULL)) { + status = VXGE_HW_FAIL; + goto exit; + } - if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) && - (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE)) - return VXGE_HW_BADCFG_RTS_MAC_EN; + hldev = vp->vpath->hldev; + vp_id = vp->vpath->vp_id; - for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - status = __vxge_hw_device_vpath_config_check( - &new_config->vp_config[i]); - if (status != VXGE_HW_OK) - return status; + config = &hldev->config.vp_config[vp_id].ring; + + ring_length = config->ring_blocks * + vxge_hw_ring_rxds_per_block_get(config->buffer_mode); + + ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp, + VXGE_HW_CHANNEL_TYPE_RING, + ring_length, + attr->per_rxd_space, + attr->userdata); + if (ring == NULL) { + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto exit; } - return VXGE_HW_OK; + vp->vpath->ringh = ring; + ring->vp_id = vp_id; + ring->vp_reg = vp->vpath->vp_reg; + ring->common_reg = hldev->common_reg; + ring->stats = &vp->vpath->sw_stats->ring_stats; + ring->config = config; + ring->callback = attr->callback; + ring->rxd_init = attr->rxd_init; + ring->rxd_term = attr->rxd_term; + ring->buffer_mode = config->buffer_mode; + ring->rxds_limit = config->rxds_limit; + + ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode); + ring->rxd_priv_size = + sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space; + ring->per_rxd_space = attr->per_rxd_space; + + ring->rxd_priv_size = + ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) / + VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; + + /* how many RxDs can fit into one block. Depends on configured + * buffer_mode. */ + ring->rxds_per_block = + vxge_hw_ring_rxds_per_block_get(config->buffer_mode); + + /* calculate actual RxD block private size */ + ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block; + ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc; + ring->mempool = __vxge_hw_mempool_create(hldev, + VXGE_HW_BLOCK_SIZE, + VXGE_HW_BLOCK_SIZE, + ring->rxdblock_priv_size, + ring->config->ring_blocks, + ring->config->ring_blocks, + &ring_mp_callback, + ring); + if (ring->mempool == NULL) { + __vxge_hw_ring_delete(vp); + return VXGE_HW_ERR_OUT_OF_MEMORY; + } + + status = __vxge_hw_channel_initialize(&ring->channel); + if (status != VXGE_HW_OK) { + __vxge_hw_ring_delete(vp); + goto exit; + } + + /* Note: + * Specifying rxd_init callback means two things: + * 1) rxds need to be initialized by driver at channel-open time; + * 2) rxds need to be posted at channel-open time + * (that's what the initial_replenish() below does) + * Currently we don't have a case when the 1) is done without the 2). + */ + if (ring->rxd_init) { + status = vxge_hw_ring_replenish(ring); + if (status != VXGE_HW_OK) { + __vxge_hw_ring_delete(vp); + goto exit; + } + } + + /* initial replenish will increment the counter in its post() routine, + * we have to reset it */ + ring->stats->common_stats.usage_cnt = 0; +exit: + return status; } /* @@ -2359,7 +2947,6 @@ vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config) device_config->rts_mac_en = VXGE_HW_RTS_MAC_DEFAULT; for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - device_config->vp_config[i].vp_id = i; device_config->vp_config[i].min_bandwidth = @@ -2498,61 +3085,6 @@ vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config) return VXGE_HW_OK; } -/* - * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion. - * Set the swapper bits appropriately for the lagacy section. - */ -static enum vxge_hw_status -__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg) -{ - u64 val64; - enum vxge_hw_status status = VXGE_HW_OK; - - val64 = readq(&legacy_reg->toc_swapper_fb); - - wmb(); - - switch (val64) { - - case VXGE_HW_SWAPPER_INITIAL_VALUE: - return status; - - case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED: - writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, - &legacy_reg->pifm_rd_swap_en); - writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, - &legacy_reg->pifm_rd_flip_en); - writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, - &legacy_reg->pifm_wr_swap_en); - writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, - &legacy_reg->pifm_wr_flip_en); - break; - - case VXGE_HW_SWAPPER_BYTE_SWAPPED: - writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, - &legacy_reg->pifm_rd_swap_en); - writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, - &legacy_reg->pifm_wr_swap_en); - break; - - case VXGE_HW_SWAPPER_BIT_FLIPPED: - writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, - &legacy_reg->pifm_rd_flip_en); - writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, - &legacy_reg->pifm_wr_flip_en); - break; - } - - wmb(); - - val64 = readq(&legacy_reg->toc_swapper_fb); - - if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE) - status = VXGE_HW_ERR_SWAPPER_CTRL; - - return status; -} - /* * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath. * Set the swapper bits appropriately for the vpath. @@ -2577,9 +3109,8 @@ __vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg) * Set the swapper bits appropriately for the vpath. */ static enum vxge_hw_status -__vxge_hw_kdfc_swapper_set( - struct vxge_hw_legacy_reg __iomem *legacy_reg, - struct vxge_hw_vpath_reg __iomem *vpath_reg) +__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg, + struct vxge_hw_vpath_reg __iomem *vpath_reg) { u64 val64; @@ -2829,57 +3360,120 @@ exit: } /* - * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD - * list callback - * This function is callback passed to __vxge_hw_mempool_create to create memory - * pool for TxD list + * __vxge_hw_fifo_abort - Returns the TxD + * This function terminates the TxDs of fifo */ -static void -__vxge_hw_fifo_mempool_item_alloc( - struct vxge_hw_mempool *mempoolh, - u32 memblock_index, struct vxge_hw_mempool_dma *dma_object, - u32 index, u32 is_last) +static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo) { - u32 memblock_item_idx; - struct __vxge_hw_fifo_txdl_priv *txdl_priv; - struct vxge_hw_fifo_txd *txdp = - (struct vxge_hw_fifo_txd *)mempoolh->items_arr[index]; - struct __vxge_hw_fifo *fifo = - (struct __vxge_hw_fifo *)mempoolh->userdata; - void *memblock = mempoolh->memblocks_arr[memblock_index]; + void *txdlh; - vxge_assert(txdp); + for (;;) { + vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh); - txdp->host_control = (u64) (size_t) - __vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp, - &memblock_item_idx); + if (txdlh == NULL) + break; - txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp); + vxge_hw_channel_dtr_complete(&fifo->channel); - vxge_assert(txdl_priv); + if (fifo->txdl_term) { + fifo->txdl_term(txdlh, + VXGE_HW_TXDL_STATE_POSTED, + fifo->channel.userdata); + } - fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp; + vxge_hw_channel_dtr_free(&fifo->channel, txdlh); + } - /* pre-format HW's TxDL's private */ - txdl_priv->dma_offset = (char *)txdp - (char *)memblock; - txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset; - txdl_priv->dma_handle = dma_object->handle; - txdl_priv->memblock = memblock; - txdl_priv->first_txdp = txdp; - txdl_priv->next_txdl_priv = NULL; - txdl_priv->alloc_frags = 0; + return VXGE_HW_OK; } /* - * __vxge_hw_fifo_create - Create a FIFO - * This function creates FIFO and initializes it. + * __vxge_hw_fifo_reset - Resets the fifo + * This function resets the fifo during vpath reset operation */ -static enum vxge_hw_status -__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, - struct vxge_hw_fifo_attr *attr) +static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) { enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_fifo *fifo; + + __vxge_hw_fifo_abort(fifo); + status = __vxge_hw_channel_reset(&fifo->channel); + + return status; +} + +/* + * __vxge_hw_fifo_delete - Removes the FIFO + * This function freeup the memory pool and removes the FIFO + */ +static enum vxge_hw_status +__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) +{ + struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; + + __vxge_hw_fifo_abort(fifo); + + if (fifo->mempool) + __vxge_hw_mempool_destroy(fifo->mempool); + + vp->vpath->fifoh = NULL; + + __vxge_hw_channel_free(&fifo->channel); + + return VXGE_HW_OK; +} + +/* + * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD + * list callback + * This function is callback passed to __vxge_hw_mempool_create to create memory + * pool for TxD list + */ +static void +__vxge_hw_fifo_mempool_item_alloc( + struct vxge_hw_mempool *mempoolh, + u32 memblock_index, struct vxge_hw_mempool_dma *dma_object, + u32 index, u32 is_last) +{ + u32 memblock_item_idx; + struct __vxge_hw_fifo_txdl_priv *txdl_priv; + struct vxge_hw_fifo_txd *txdp = + (struct vxge_hw_fifo_txd *)mempoolh->items_arr[index]; + struct __vxge_hw_fifo *fifo = + (struct __vxge_hw_fifo *)mempoolh->userdata; + void *memblock = mempoolh->memblocks_arr[memblock_index]; + + vxge_assert(txdp); + + txdp->host_control = (u64) (size_t) + __vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp, + &memblock_item_idx); + + txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp); + + vxge_assert(txdl_priv); + + fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp; + + /* pre-format HW's TxDL's private */ + txdl_priv->dma_offset = (char *)txdp - (char *)memblock; + txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset; + txdl_priv->dma_handle = dma_object->handle; + txdl_priv->memblock = memblock; + txdl_priv->first_txdp = txdp; + txdl_priv->next_txdl_priv = NULL; + txdl_priv->alloc_frags = 0; +} + +/* + * __vxge_hw_fifo_create - Create a FIFO + * This function creates FIFO and initializes it. + */ +static enum vxge_hw_status +__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, + struct vxge_hw_fifo_attr *attr) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_fifo *fifo; struct vxge_hw_fifo_config *config; u32 txdl_size, txdl_per_memblock; struct vxge_hw_mempool_cbs fifo_mp_callback; @@ -2992,69 +3586,6 @@ exit: return status; } -/* - * __vxge_hw_fifo_abort - Returns the TxD - * This function terminates the TxDs of fifo - */ -static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo) -{ - void *txdlh; - - for (;;) { - vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh); - - if (txdlh == NULL) - break; - - vxge_hw_channel_dtr_complete(&fifo->channel); - - if (fifo->txdl_term) { - fifo->txdl_term(txdlh, - VXGE_HW_TXDL_STATE_POSTED, - fifo->channel.userdata); - } - - vxge_hw_channel_dtr_free(&fifo->channel, txdlh); - } - - return VXGE_HW_OK; -} - -/* - * __vxge_hw_fifo_reset - Resets the fifo - * This function resets the fifo during vpath reset operation - */ -static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) -{ - enum vxge_hw_status status = VXGE_HW_OK; - - __vxge_hw_fifo_abort(fifo); - status = __vxge_hw_channel_reset(&fifo->channel); - - return status; -} - -/* - * __vxge_hw_fifo_delete - Removes the FIFO - * This function freeup the memory pool and removes the FIFO - */ -static enum vxge_hw_status -__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; - - __vxge_hw_fifo_abort(fifo); - - if (fifo->mempool) - __vxge_hw_mempool_destroy(fifo->mempool); - - vp->vpath->fifoh = NULL; - - __vxge_hw_channel_free(&fifo->channel); - - return VXGE_HW_OK; -} - /* * __vxge_hw_vpath_pci_read - Read the content of given address * in pci config space. @@ -3786,10 +4317,10 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) vp_reg = vpath->vp_reg; config = vpath->vp_config; - writeq((u64)0, &vp_reg->tim_dest_addr); - writeq((u64)0, &vp_reg->tim_vpath_map); - writeq((u64)0, &vp_reg->tim_bitmap); - writeq((u64)0, &vp_reg->tim_remap); + writeq(0, &vp_reg->tim_dest_addr); + writeq(0, &vp_reg->tim_vpath_map); + writeq(0, &vp_reg->tim_bitmap); + writeq(0, &vp_reg->tim_remap); if (config->ring.enable == VXGE_HW_RING_ENABLE) writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM( @@ -3902,1355 +4433,699 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) config->tti.ltimer_val); } - writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); - } - - if (config->ring.enable == VXGE_HW_RING_ENABLE) { - - val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); - - if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( - 0x3ffffff); - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( - config->rti.btimer_val); - } - - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN; - - if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) { - if (config->rti.timer_ac_en) - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; - else - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; - } - - if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) { - if (config->rti.timer_ci_en) - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; - else - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; - } - - if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f); - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A( - config->rti.urange_a); - } - - if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f); - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B( - config->rti.urange_b); - } - - if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f); - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C( - config->rti.urange_c); - } - - writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); - val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); - - if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff); - val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A( - config->rti.uec_a); - } - - if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff); - val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B( - config->rti.uec_b); - } - - if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff); - val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C( - config->rti.uec_c); - } - - if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff); - val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D( - config->rti.uec_d); - } - - writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); - val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); - - if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) { - if (config->rti.timer_ri_en) - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; - else - val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; - } - - if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( - 0x3ffffff); - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( - config->rti.rtimer_val); - } - - if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL( - config->rti.util_sel); - } - - if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { - val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( - 0x3ffffff); - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( - config->rti.ltimer_val); - } - - writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); - } - - val64 = 0; - writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]); - writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]); - writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]); - writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]); - writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]); - writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]); - - return status; -} - -void -vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id) -{ - struct __vxge_hw_virtualpath *vpath; - struct vxge_hw_vpath_reg __iomem *vp_reg; - struct vxge_hw_vp_config *config; - u64 val64; - - vpath = &hldev->virtual_paths[vp_id]; - vp_reg = vpath->vp_reg; - config = vpath->vp_config; - - if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) { - val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); - - if (config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) { - config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE; - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; - writeq(val64, - &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); - } - } -} -/* - * __vxge_hw_vpath_initialize - * This routine is the final phase of init which initializes the - * registers of the vpath using the configuration passed. - */ -static enum vxge_hw_status -__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id) -{ - u64 val64; - u32 val32; - enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_virtualpath *vpath; - struct vxge_hw_vpath_reg __iomem *vp_reg; - - vpath = &hldev->virtual_paths[vp_id]; - - if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { - status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; - goto exit; - } - vp_reg = vpath->vp_reg; - - status = __vxge_hw_vpath_swapper_set(vpath->vp_reg); - - if (status != VXGE_HW_OK) - goto exit; - - status = __vxge_hw_vpath_mac_configure(hldev, vp_id); - - if (status != VXGE_HW_OK) - goto exit; - - status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id); - - if (status != VXGE_HW_OK) - goto exit; - - status = __vxge_hw_vpath_tim_configure(hldev, vp_id); - - if (status != VXGE_HW_OK) - goto exit; - - val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl); - - /* Get MRRS value from device control */ - status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32); - - if (status == VXGE_HW_OK) { - val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12; - val64 &= - ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7)); - val64 |= - VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32); - - val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE; - } - - val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7)); - val64 |= - VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY( - VXGE_HW_MAX_PAYLOAD_SIZE_512); - - val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN; - writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl); - -exit: - return status; -} - -/* - * __vxge_hw_vp_initialize - Initialize Virtual Path structure - * This routine is the initial phase of init which resets the vpath and - * initializes the software support structures. - */ -static enum vxge_hw_status -__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, - struct vxge_hw_vp_config *config) -{ - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status = VXGE_HW_OK; - - if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { - status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; - goto exit; - } - - vpath = &hldev->virtual_paths[vp_id]; - - spin_lock_init(&hldev->virtual_paths[vp_id].lock); - vpath->vp_id = vp_id; - vpath->vp_open = VXGE_HW_VP_OPEN; - vpath->hldev = hldev; - vpath->vp_config = config; - vpath->vp_reg = hldev->vpath_reg[vp_id]; - vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id]; - - __vxge_hw_vpath_reset(hldev, vp_id); - - status = __vxge_hw_vpath_reset_check(vpath); - if (status != VXGE_HW_OK) { - memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); - goto exit; - } - - status = __vxge_hw_vpath_mgmt_read(hldev, vpath); - if (status != VXGE_HW_OK) { - memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); - goto exit; - } - - INIT_LIST_HEAD(&vpath->vpath_handles); - - vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id]; - - VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0, - hldev->tim_int_mask1, vp_id); - - status = __vxge_hw_vpath_initialize(hldev, vp_id); - if (status != VXGE_HW_OK) - __vxge_hw_vp_terminate(hldev, vp_id); -exit: - return status; -} - -/* - * __vxge_hw_vp_terminate - Terminate Virtual Path structure - * This routine closes all channels it opened and freeup memory - */ -static void -__vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id) -{ - struct __vxge_hw_virtualpath *vpath; - - vpath = &hldev->virtual_paths[vp_id]; - - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) - goto exit; - - VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0, - vpath->hldev->tim_int_mask1, vpath->vp_id); - hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL; - - memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); -exit: - return; -} - -/* - * vxge_hw_vpath_mtu_set - Set MTU. - * Set new MTU value. Example, to use jumbo frames: - * vxge_hw_vpath_mtu_set(my_device, 9600); - */ -enum vxge_hw_status -vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu) -{ - u64 val64; - enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_virtualpath *vpath; - - if (vp == NULL) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - vpath = vp->vpath; - - new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE; - - if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu)) - status = VXGE_HW_ERR_INVALID_MTU_SIZE; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - - val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); - val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu); - - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); - - vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE; - -exit: - return status; -} - -/* - * vxge_hw_vpath_open - Open a virtual path on a given adapter - * This function is used to open access to virtual path of an - * adapter for offload, GRO operations. This function returns - * synchronously. - */ -enum vxge_hw_status -vxge_hw_vpath_open(struct __vxge_hw_device *hldev, - struct vxge_hw_vpath_attr *attr, - struct __vxge_hw_vpath_handle **vpath_handle) -{ - struct __vxge_hw_virtualpath *vpath; - struct __vxge_hw_vpath_handle *vp; - enum vxge_hw_status status; - - vpath = &hldev->virtual_paths[attr->vp_id]; - - if (vpath->vp_open == VXGE_HW_VP_OPEN) { - status = VXGE_HW_ERR_INVALID_STATE; - goto vpath_open_exit1; - } - - status = __vxge_hw_vp_initialize(hldev, attr->vp_id, - &hldev->config.vp_config[attr->vp_id]); - - if (status != VXGE_HW_OK) - goto vpath_open_exit1; - - vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle)); - if (vp == NULL) { - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto vpath_open_exit2; - } - - vp->vpath = vpath; - - if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { - status = __vxge_hw_fifo_create(vp, &attr->fifo_attr); - if (status != VXGE_HW_OK) - goto vpath_open_exit6; - } - - if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) { - status = __vxge_hw_ring_create(vp, &attr->ring_attr); - if (status != VXGE_HW_OK) - goto vpath_open_exit7; - - __vxge_hw_vpath_prc_configure(hldev, attr->vp_id); - } - - vpath->fifoh->tx_intr_num = - (attr->vp_id * VXGE_HW_MAX_INTR_PER_VP) + - VXGE_HW_VPATH_INTR_TX; - - vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev, - VXGE_HW_BLOCK_SIZE); - - if (vpath->stats_block == NULL) { - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto vpath_open_exit8; - } - - vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath-> - stats_block->memblock; - memset(vpath->hw_stats, 0, - sizeof(struct vxge_hw_vpath_stats_hw_info)); - - hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] = - vpath->hw_stats; - - vpath->hw_stats_sav = - &hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id]; - memset(vpath->hw_stats_sav, 0, - sizeof(struct vxge_hw_vpath_stats_hw_info)); - - writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg); - - status = vxge_hw_vpath_stats_enable(vp); - if (status != VXGE_HW_OK) - goto vpath_open_exit8; - - list_add(&vp->item, &vpath->vpath_handles); - - hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id); - - *vpath_handle = vp; - - attr->fifo_attr.userdata = vpath->fifoh; - attr->ring_attr.userdata = vpath->ringh; - - return VXGE_HW_OK; - -vpath_open_exit8: - if (vpath->ringh != NULL) - __vxge_hw_ring_delete(vp); -vpath_open_exit7: - if (vpath->fifoh != NULL) - __vxge_hw_fifo_delete(vp); -vpath_open_exit6: - vfree(vp); -vpath_open_exit2: - __vxge_hw_vp_terminate(hldev, attr->vp_id); -vpath_open_exit1: - - return status; -} - -/** - * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath - * (vpath) open - * @vp: Handle got from previous vpath open - * - * This function is used to close access to virtual path opened - * earlier. - */ -void -vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_virtualpath *vpath = vp->vpath; - struct __vxge_hw_ring *ring = vpath->ringh; - struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev); - u64 new_count, val64, val164; - - if (vdev->titan1) { - new_count = readq(&vpath->vp_reg->rxdmem_size); - new_count &= 0x1fff; - } else - new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8; - - val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count); - - writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164), - &vpath->vp_reg->prc_rxd_doorbell); - readl(&vpath->vp_reg->prc_rxd_doorbell); - - val164 /= 2; - val64 = readq(&vpath->vp_reg->prc_cfg6); - val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64); - val64 &= 0x1ff; - - /* - * Each RxD is of 4 qwords - */ - new_count -= (val64 + 1); - val64 = min(val164, new_count) / 4; - - ring->rxds_limit = min(ring->rxds_limit, val64); - if (ring->rxds_limit < 4) - ring->rxds_limit = 4; -} - -/* - * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open - * This function is used to close access to virtual path opened - * earlier. - */ -enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_virtualpath *vpath = NULL; - struct __vxge_hw_device *devh = NULL; - u32 vp_id = vp->vpath->vp_id; - u32 is_empty = TRUE; - enum vxge_hw_status status = VXGE_HW_OK; - - vpath = vp->vpath; - devh = vpath->hldev; - - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto vpath_close_exit; - } - - list_del(&vp->item); - - if (!list_empty(&vpath->vpath_handles)) { - list_add(&vp->item, &vpath->vpath_handles); - is_empty = FALSE; - } - - if (!is_empty) { - status = VXGE_HW_FAIL; - goto vpath_close_exit; - } - - devh->vpaths_deployed &= ~vxge_mBIT(vp_id); - - if (vpath->ringh != NULL) - __vxge_hw_ring_delete(vp); - - if (vpath->fifoh != NULL) - __vxge_hw_fifo_delete(vp); - - if (vpath->stats_block != NULL) - __vxge_hw_blockpool_block_free(devh, vpath->stats_block); - - vfree(vp); - - __vxge_hw_vp_terminate(devh, vp_id); - - spin_lock(&vpath->lock); - vpath->vp_open = VXGE_HW_VP_NOT_OPEN; - spin_unlock(&vpath->lock); - -vpath_close_exit: - return status; -} - -/* - * vxge_hw_vpath_reset - Resets vpath - * This function is used to request a reset of vpath - */ -enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp) -{ - enum vxge_hw_status status; - u32 vp_id; - struct __vxge_hw_virtualpath *vpath = vp->vpath; - - vp_id = vpath->vp_id; - - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto exit; - } - - status = __vxge_hw_vpath_reset(vpath->hldev, vp_id); - if (status == VXGE_HW_OK) - vpath->sw_stats->soft_reset_cnt++; -exit: - return status; -} - -/* - * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize. - * This function poll's for the vpath reset completion and re initializes - * the vpath. - */ -enum vxge_hw_status -vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_virtualpath *vpath = NULL; - enum vxge_hw_status status; - struct __vxge_hw_device *hldev; - u32 vp_id; - - vp_id = vp->vpath->vp_id; - vpath = vp->vpath; - hldev = vpath->hldev; - - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto exit; - } - - status = __vxge_hw_vpath_reset_check(vpath); - if (status != VXGE_HW_OK) - goto exit; - - status = __vxge_hw_vpath_sw_reset(hldev, vp_id); - if (status != VXGE_HW_OK) - goto exit; - - status = __vxge_hw_vpath_initialize(hldev, vp_id); - if (status != VXGE_HW_OK) - goto exit; - - if (vpath->ringh != NULL) - __vxge_hw_vpath_prc_configure(hldev, vp_id); - - memset(vpath->hw_stats, 0, - sizeof(struct vxge_hw_vpath_stats_hw_info)); - - memset(vpath->hw_stats_sav, 0, - sizeof(struct vxge_hw_vpath_stats_hw_info)); - - writeq(vpath->stats_block->dma_addr, - &vpath->vp_reg->stats_cfg); - - status = vxge_hw_vpath_stats_enable(vp); + writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); + } -exit: - return status; -} + if (config->ring.enable == VXGE_HW_RING_ENABLE) { -/* - * vxge_hw_vpath_enable - Enable vpath. - * This routine clears the vpath reset thereby enabling a vpath - * to start forwarding frames and generating interrupts. - */ -void -vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_device *hldev; - u64 val64; + val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); - hldev = vp->vpath->hldev; + if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( + 0x3ffffff); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( + config->rti.btimer_val); + } - val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET( - 1 << (16 - vp->vpath->vp_id)); + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN; - __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), - &hldev->common_reg->cmn_rsthdlr_cfg1); -} + if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) { + if (config->rti.timer_ac_en) + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; + else + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; + } -/* - * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics. - * Enable the DMA vpath statistics. The function is to be called to re-enable - * the adapter to update stats into the host memory - */ -static enum vxge_hw_status -vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct __vxge_hw_virtualpath *vpath; + if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) { + if (config->rti.timer_ci_en) + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; + else + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; + } - vpath = vp->vpath; + if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A( + config->rti.urange_a); + } - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto exit; - } + if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B( + config->rti.urange_b); + } - memcpy(vpath->hw_stats_sav, vpath->hw_stats, - sizeof(struct vxge_hw_vpath_stats_hw_info)); + if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C( + config->rti.urange_c); + } - status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats); -exit: - return status; -} + writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); + val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); -/* - * __vxge_hw_vpath_stats_access - Get the statistics from the given location - * and offset and perform an operation - */ -static enum vxge_hw_status -__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath, - u32 operation, u32 offset, u64 *stat) -{ - u64 val64; - enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_hw_vpath_reg __iomem *vp_reg; + if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff); + val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A( + config->rti.uec_a); + } - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto vpath_stats_access_exit; - } + if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff); + val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B( + config->rti.uec_b); + } - vp_reg = vpath->vp_reg; + if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff); + val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C( + config->rti.uec_c); + } - val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) | - VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE | - VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset); + if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff); + val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D( + config->rti.uec_d); + } - status = __vxge_hw_pio_mem_write64(val64, - &vp_reg->xmac_stats_access_cmd, - VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE, - vpath->hldev->config.device_poll_millis); + writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); + val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); - if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ)) - *stat = readq(&vp_reg->xmac_stats_access_data); - else - *stat = 0; + if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) { + if (config->rti.timer_ri_en) + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; + else + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; + } -vpath_stats_access_exit: - return status; -} + if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( + 0x3ffffff); + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( + config->rti.rtimer_val); + } -/* - * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath - */ -static enum vxge_hw_status -__vxge_hw_vpath_xmac_tx_stats_get( - struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats) -{ - u64 *val64; - int i; - u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET; - enum vxge_hw_status status = VXGE_HW_OK; + if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL( + config->rti.util_sel); + } - val64 = (u64 *) vpath_tx_stats; + if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( + 0x3ffffff); + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( + config->rti.ltimer_val); + } - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto exit; + writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); } - for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) { - status = __vxge_hw_vpath_stats_access(vpath, - VXGE_HW_STATS_OP_READ, - offset, val64); - if (status != VXGE_HW_OK) - goto exit; - offset++; - val64++; - } -exit: + val64 = 0; + writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]); + writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]); + writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]); + writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]); + writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]); + writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]); + return status; } -/* - * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath - */ -static enum vxge_hw_status -__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats) +void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id) { - u64 *val64; - enum vxge_hw_status status = VXGE_HW_OK; - int i; - u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET; - val64 = (u64 *) vpath_rx_stats; + struct __vxge_hw_virtualpath *vpath; + struct vxge_hw_vpath_reg __iomem *vp_reg; + struct vxge_hw_vp_config *config; + u64 val64; - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; - goto exit; - } - for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) { - status = __vxge_hw_vpath_stats_access(vpath, - VXGE_HW_STATS_OP_READ, - offset >> 3, val64); - if (status != VXGE_HW_OK) - goto exit; + vpath = &hldev->virtual_paths[vp_id]; + vp_reg = vpath->vp_reg; + config = vpath->vp_config; - offset += 8; - val64++; + if (config->fifo.enable == VXGE_HW_FIFO_ENABLE && + config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) { + config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE; + val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; + writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); } -exit: - return status; } /* - * __vxge_hw_vpath_stats_get - Get the vpath hw statistics. + * __vxge_hw_vpath_initialize + * This routine is the final phase of init which initializes the + * registers of the vpath using the configuration passed. */ static enum vxge_hw_status -__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_vpath_stats_hw_info *hw_stats) +__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id) { u64 val64; + u32 val32; enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_virtualpath *vpath; struct vxge_hw_vpath_reg __iomem *vp_reg; - if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { - status = VXGE_HW_ERR_VPATH_NOT_OPEN; + vpath = &hldev->virtual_paths[vp_id]; + + if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { + status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; goto exit; } vp_reg = vpath->vp_reg; - val64 = readq(&vp_reg->vpath_debug_stats0); - hw_stats->ini_num_mwr_sent = - (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64); - - val64 = readq(&vp_reg->vpath_debug_stats1); - hw_stats->ini_num_mrd_sent = - (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64); + status = __vxge_hw_vpath_swapper_set(vpath->vp_reg); + if (status != VXGE_HW_OK) + goto exit; - val64 = readq(&vp_reg->vpath_debug_stats2); - hw_stats->ini_num_cpl_rcvd = - (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64); + status = __vxge_hw_vpath_mac_configure(hldev, vp_id); + if (status != VXGE_HW_OK) + goto exit; - val64 = readq(&vp_reg->vpath_debug_stats3); - hw_stats->ini_num_mwr_byte_sent = - VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64); + status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id); + if (status != VXGE_HW_OK) + goto exit; - val64 = readq(&vp_reg->vpath_debug_stats4); - hw_stats->ini_num_cpl_byte_rcvd = - VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64); + status = __vxge_hw_vpath_tim_configure(hldev, vp_id); + if (status != VXGE_HW_OK) + goto exit; - val64 = readq(&vp_reg->vpath_debug_stats5); - hw_stats->wrcrdtarb_xoff = - (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64); + val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl); - val64 = readq(&vp_reg->vpath_debug_stats6); - hw_stats->rdcrdtarb_xoff = - (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64); + /* Get MRRS value from device control */ + status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32); + if (status == VXGE_HW_OK) { + val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12; + val64 &= + ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7)); + val64 |= + VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32); - val64 = readq(&vp_reg->vpath_genstats_count01); - hw_stats->vpath_genstats_count0 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0( - val64); + val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE; + } - val64 = readq(&vp_reg->vpath_genstats_count01); - hw_stats->vpath_genstats_count1 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1( - val64); + val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7)); + val64 |= + VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY( + VXGE_HW_MAX_PAYLOAD_SIZE_512); - val64 = readq(&vp_reg->vpath_genstats_count23); - hw_stats->vpath_genstats_count2 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2( - val64); + val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN; + writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl); - val64 = readq(&vp_reg->vpath_genstats_count01); - hw_stats->vpath_genstats_count3 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3( - val64); +exit: + return status; +} - val64 = readq(&vp_reg->vpath_genstats_count4); - hw_stats->vpath_genstats_count4 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4( - val64); +/* + * __vxge_hw_vp_terminate - Terminate Virtual Path structure + * This routine closes all channels it opened and freeup memory + */ +static void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id) +{ + struct __vxge_hw_virtualpath *vpath; - val64 = readq(&vp_reg->vpath_genstats_count5); - hw_stats->vpath_genstats_count5 = - (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5( - val64); + vpath = &hldev->virtual_paths[vp_id]; - status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats); - if (status != VXGE_HW_OK) + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) goto exit; - status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats); - if (status != VXGE_HW_OK) - goto exit; + VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0, + vpath->hldev->tim_int_mask1, vpath->vp_id); + hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL; - VXGE_HW_VPATH_STATS_PIO_READ( - VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET); + memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); +exit: + return; +} - hw_stats->prog_event_vnum0 = - (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64); +/* + * __vxge_hw_vp_initialize - Initialize Virtual Path structure + * This routine is the initial phase of init which resets the vpath and + * initializes the software support structures. + */ +static enum vxge_hw_status +__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, + struct vxge_hw_vp_config *config) +{ + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - hw_stats->prog_event_vnum1 = - (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64); + if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { + status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; + goto exit; + } - VXGE_HW_VPATH_STATS_PIO_READ( - VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET); + vpath = &hldev->virtual_paths[vp_id]; - hw_stats->prog_event_vnum2 = - (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64); + spin_lock_init(&hldev->virtual_paths[vp_id].lock); + vpath->vp_id = vp_id; + vpath->vp_open = VXGE_HW_VP_OPEN; + vpath->hldev = hldev; + vpath->vp_config = config; + vpath->vp_reg = hldev->vpath_reg[vp_id]; + vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id]; - hw_stats->prog_event_vnum3 = - (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64); + __vxge_hw_vpath_reset(hldev, vp_id); - val64 = readq(&vp_reg->rx_multi_cast_stats); - hw_stats->rx_multi_cast_frame_discard = - (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64); + status = __vxge_hw_vpath_reset_check(vpath); + if (status != VXGE_HW_OK) { + memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); + goto exit; + } - val64 = readq(&vp_reg->rx_frm_transferred); - hw_stats->rx_frm_transferred = - (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64); + status = __vxge_hw_vpath_mgmt_read(hldev, vpath); + if (status != VXGE_HW_OK) { + memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); + goto exit; + } - val64 = readq(&vp_reg->rxd_returned); - hw_stats->rxd_returned = - (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64); + INIT_LIST_HEAD(&vpath->vpath_handles); - val64 = readq(&vp_reg->dbg_stats_rx_mpa); - hw_stats->rx_mpa_len_fail_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64); - hw_stats->rx_mpa_mrk_fail_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64); - hw_stats->rx_mpa_crc_fail_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64); + vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id]; - val64 = readq(&vp_reg->dbg_stats_rx_fau); - hw_stats->rx_permitted_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64); - hw_stats->rx_vp_reset_discarded_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64); - hw_stats->rx_wol_frms = - (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64); + VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0, + hldev->tim_int_mask1, vp_id); - val64 = readq(&vp_reg->tx_vp_reset_discarded_frms); - hw_stats->tx_vp_reset_discarded_frms = - (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS( - val64); + status = __vxge_hw_vpath_initialize(hldev, vp_id); + if (status != VXGE_HW_OK) + __vxge_hw_vp_terminate(hldev, vp_id); exit: return status; } - -static void vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh, - unsigned long size) +/* + * vxge_hw_vpath_mtu_set - Set MTU. + * Set new MTU value. Example, to use jumbo frames: + * vxge_hw_vpath_mtu_set(my_device, 9600); + */ +enum vxge_hw_status +vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu) { - gfp_t flags; - void *vaddr; + u64 val64; + enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_virtualpath *vpath; - if (in_interrupt()) - flags = GFP_ATOMIC | GFP_DMA; - else - flags = GFP_KERNEL | GFP_DMA; + if (vp == NULL) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; + } + vpath = vp->vpath; - vaddr = kmalloc((size), flags); + new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE; - vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev); -} + if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu)) + status = VXGE_HW_ERR_INVALID_MTU_SIZE; -static void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr, - struct pci_dev **p_dma_acch) -{ - unsigned long misaligned = *(unsigned long *)p_dma_acch; - u8 *tmp = (u8 *)vaddr; - tmp -= misaligned; - kfree((void *)tmp); + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); + + val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); + val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu); + + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + + vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE; + +exit: + return status; } /* - * __vxge_hw_blockpool_create - Create block pool + * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics. + * Enable the DMA vpath statistics. The function is to be called to re-enable + * the adapter to update stats into the host memory */ - static enum vxge_hw_status -__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, - struct __vxge_hw_blockpool *blockpool, - u32 pool_size, - u32 pool_max) +vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp) { - u32 i; - struct __vxge_hw_blockpool_entry *entry = NULL; - void *memblock; - dma_addr_t dma_addr; - struct pci_dev *dma_handle; - struct pci_dev *acc_handle; enum vxge_hw_status status = VXGE_HW_OK; + struct __vxge_hw_virtualpath *vpath; - if (blockpool == NULL) { - status = VXGE_HW_FAIL; - goto blockpool_create_exit; - } - - blockpool->hldev = hldev; - blockpool->block_size = VXGE_HW_BLOCK_SIZE; - blockpool->pool_size = 0; - blockpool->pool_max = pool_max; - blockpool->req_out = 0; - - INIT_LIST_HEAD(&blockpool->free_block_list); - INIT_LIST_HEAD(&blockpool->free_entry_list); + vpath = vp->vpath; - for (i = 0; i < pool_size + pool_max; i++) { - entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry), - GFP_KERNEL); - if (entry == NULL) { - __vxge_hw_blockpool_destroy(blockpool); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto blockpool_create_exit; - } - list_add(&entry->item, &blockpool->free_entry_list); + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; } - for (i = 0; i < pool_size; i++) { - - memblock = vxge_os_dma_malloc( - hldev->pdev, - VXGE_HW_BLOCK_SIZE, - &dma_handle, - &acc_handle); + memcpy(vpath->hw_stats_sav, vpath->hw_stats, + sizeof(struct vxge_hw_vpath_stats_hw_info)); - if (memblock == NULL) { - __vxge_hw_blockpool_destroy(blockpool); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto blockpool_create_exit; - } + status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats); +exit: + return status; +} - dma_addr = pci_map_single(hldev->pdev, memblock, - VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL); +/* + * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool + * This function allocates a block from block pool or from the system + */ +static struct __vxge_hw_blockpool_entry * +__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) +{ + struct __vxge_hw_blockpool_entry *entry = NULL; + struct __vxge_hw_blockpool *blockpool; - if (unlikely(pci_dma_mapping_error(hldev->pdev, - dma_addr))) { + blockpool = &devh->block_pool; - vxge_os_dma_free(hldev->pdev, memblock, &acc_handle); - __vxge_hw_blockpool_destroy(blockpool); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto blockpool_create_exit; - } + if (size == blockpool->block_size) { - if (!list_empty(&blockpool->free_entry_list)) + if (!list_empty(&blockpool->free_block_list)) entry = (struct __vxge_hw_blockpool_entry *) - list_first_entry(&blockpool->free_entry_list, + list_first_entry(&blockpool->free_block_list, struct __vxge_hw_blockpool_entry, item); - if (entry == NULL) - entry = - kzalloc(sizeof(struct __vxge_hw_blockpool_entry), - GFP_KERNEL); if (entry != NULL) { list_del(&entry->item); - entry->length = VXGE_HW_BLOCK_SIZE; - entry->memblock = memblock; - entry->dma_addr = dma_addr; - entry->acc_handle = acc_handle; - entry->dma_handle = dma_handle; - list_add(&entry->item, - &blockpool->free_block_list); - blockpool->pool_size++; - } else { - __vxge_hw_blockpool_destroy(blockpool); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto blockpool_create_exit; + blockpool->pool_size--; } } -blockpool_create_exit: - return status; + if (entry != NULL) + __vxge_hw_blockpool_blocks_add(blockpool); + + return entry; } /* - * __vxge_hw_blockpool_destroy - Deallocates the block pool + * vxge_hw_vpath_open - Open a virtual path on a given adapter + * This function is used to open access to virtual path of an + * adapter for offload, GRO operations. This function returns + * synchronously. */ - -static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) +enum vxge_hw_status +vxge_hw_vpath_open(struct __vxge_hw_device *hldev, + struct vxge_hw_vpath_attr *attr, + struct __vxge_hw_vpath_handle **vpath_handle) { + struct __vxge_hw_virtualpath *vpath; + struct __vxge_hw_vpath_handle *vp; + enum vxge_hw_status status; - struct __vxge_hw_device *hldev; - struct list_head *p, *n; - u16 ret; + vpath = &hldev->virtual_paths[attr->vp_id]; - if (blockpool == NULL) { - ret = 1; - goto exit; + if (vpath->vp_open == VXGE_HW_VP_OPEN) { + status = VXGE_HW_ERR_INVALID_STATE; + goto vpath_open_exit1; } - hldev = blockpool->hldev; - - list_for_each_safe(p, n, &blockpool->free_block_list) { + status = __vxge_hw_vp_initialize(hldev, attr->vp_id, + &hldev->config.vp_config[attr->vp_id]); + if (status != VXGE_HW_OK) + goto vpath_open_exit1; - pci_unmap_single(hldev->pdev, - ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, - ((struct __vxge_hw_blockpool_entry *)p)->length, - PCI_DMA_BIDIRECTIONAL); + vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle)); + if (vp == NULL) { + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto vpath_open_exit2; + } - vxge_os_dma_free(hldev->pdev, - ((struct __vxge_hw_blockpool_entry *)p)->memblock, - &((struct __vxge_hw_blockpool_entry *) p)->acc_handle); + vp->vpath = vpath; - list_del( - &((struct __vxge_hw_blockpool_entry *)p)->item); - kfree(p); - blockpool->pool_size--; + if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { + status = __vxge_hw_fifo_create(vp, &attr->fifo_attr); + if (status != VXGE_HW_OK) + goto vpath_open_exit6; } - list_for_each_safe(p, n, &blockpool->free_entry_list) { - list_del( - &((struct __vxge_hw_blockpool_entry *)p)->item); - kfree((void *)p); + if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) { + status = __vxge_hw_ring_create(vp, &attr->ring_attr); + if (status != VXGE_HW_OK) + goto vpath_open_exit7; + + __vxge_hw_vpath_prc_configure(hldev, attr->vp_id); } - ret = 0; -exit: - return; -} -/* - * __vxge_hw_blockpool_blocks_add - Request additional blocks - */ -static -void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool) -{ - u32 nreq = 0, i; + vpath->fifoh->tx_intr_num = + (attr->vp_id * VXGE_HW_MAX_INTR_PER_VP) + + VXGE_HW_VPATH_INTR_TX; - if ((blockpool->pool_size + blockpool->req_out) < - VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) { - nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE; - blockpool->req_out += nreq; + vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev, + VXGE_HW_BLOCK_SIZE); + if (vpath->stats_block == NULL) { + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto vpath_open_exit8; } - for (i = 0; i < nreq; i++) - vxge_os_dma_malloc_async( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, - blockpool->hldev, VXGE_HW_BLOCK_SIZE); -} + vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath-> + stats_block->memblock; + memset(vpath->hw_stats, 0, + sizeof(struct vxge_hw_vpath_stats_hw_info)); -/* - * __vxge_hw_blockpool_blocks_remove - Free additional blocks - */ -static -void __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool) -{ - struct list_head *p, *n; + hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] = + vpath->hw_stats; - list_for_each_safe(p, n, &blockpool->free_block_list) { + vpath->hw_stats_sav = + &hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id]; + memset(vpath->hw_stats_sav, 0, + sizeof(struct vxge_hw_vpath_stats_hw_info)); - if (blockpool->pool_size < blockpool->pool_max) - break; + writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg); - pci_unmap_single( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, - ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, - ((struct __vxge_hw_blockpool_entry *)p)->length, - PCI_DMA_BIDIRECTIONAL); + status = vxge_hw_vpath_stats_enable(vp); + if (status != VXGE_HW_OK) + goto vpath_open_exit8; - vxge_os_dma_free( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, - ((struct __vxge_hw_blockpool_entry *)p)->memblock, - &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); + list_add(&vp->item, &vpath->vpath_handles); - list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); + hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id); - list_add(p, &blockpool->free_entry_list); + *vpath_handle = vp; - blockpool->pool_size--; + attr->fifo_attr.userdata = vpath->fifoh; + attr->ring_attr.userdata = vpath->ringh; - } + return VXGE_HW_OK; + +vpath_open_exit8: + if (vpath->ringh != NULL) + __vxge_hw_ring_delete(vp); +vpath_open_exit7: + if (vpath->fifoh != NULL) + __vxge_hw_fifo_delete(vp); +vpath_open_exit6: + vfree(vp); +vpath_open_exit2: + __vxge_hw_vp_terminate(hldev, attr->vp_id); +vpath_open_exit1: + + return status; } -/* - * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async - * Adds a block to block pool +/** + * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath + * (vpath) open + * @vp: Handle got from previous vpath open + * + * This function is used to close access to virtual path opened + * earlier. */ -static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, - void *block_addr, - u32 length, - struct pci_dev *dma_h, - struct pci_dev *acc_handle) +void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_blockpool *blockpool; - struct __vxge_hw_blockpool_entry *entry = NULL; - dma_addr_t dma_addr; - enum vxge_hw_status status = VXGE_HW_OK; - u32 req_out; + struct __vxge_hw_virtualpath *vpath = vp->vpath; + struct __vxge_hw_ring *ring = vpath->ringh; + struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev); + u64 new_count, val64, val164; - blockpool = &devh->block_pool; + if (vdev->titan1) { + new_count = readq(&vpath->vp_reg->rxdmem_size); + new_count &= 0x1fff; + } else + new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8; - if (block_addr == NULL) { - blockpool->req_out--; - status = VXGE_HW_FAIL; - goto exit; - } + val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count); - dma_addr = pci_map_single(devh->pdev, block_addr, length, - PCI_DMA_BIDIRECTIONAL); + writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164), + &vpath->vp_reg->prc_rxd_doorbell); + readl(&vpath->vp_reg->prc_rxd_doorbell); - if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) { + val164 /= 2; + val64 = readq(&vpath->vp_reg->prc_cfg6); + val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64); + val64 &= 0x1ff; - vxge_os_dma_free(devh->pdev, block_addr, &acc_handle); - blockpool->req_out--; - status = VXGE_HW_FAIL; - goto exit; - } + /* + * Each RxD is of 4 qwords + */ + new_count -= (val64 + 1); + val64 = min(val164, new_count) / 4; + ring->rxds_limit = min(ring->rxds_limit, val64); + if (ring->rxds_limit < 4) + ring->rxds_limit = 4; +} - if (!list_empty(&blockpool->free_entry_list)) - entry = (struct __vxge_hw_blockpool_entry *) - list_first_entry(&blockpool->free_entry_list, - struct __vxge_hw_blockpool_entry, - item); +/* + * __vxge_hw_blockpool_block_free - Frees a block from block pool + * @devh: Hal device + * @entry: Entry of block to be freed + * + * This function frees a block from block pool + */ +static void +__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh, + struct __vxge_hw_blockpool_entry *entry) +{ + struct __vxge_hw_blockpool *blockpool; - if (entry == NULL) - entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); - else - list_del(&entry->item); + blockpool = &devh->block_pool; - if (entry != NULL) { - entry->length = length; - entry->memblock = block_addr; - entry->dma_addr = dma_addr; - entry->acc_handle = acc_handle; - entry->dma_handle = dma_h; + if (entry->length == blockpool->block_size) { list_add(&entry->item, &blockpool->free_block_list); blockpool->pool_size++; - status = VXGE_HW_OK; - } else - status = VXGE_HW_ERR_OUT_OF_MEMORY; - - blockpool->req_out--; + } - req_out = blockpool->req_out; -exit: - return; + __vxge_hw_blockpool_blocks_remove(blockpool); } /* - * __vxge_hw_blockpool_malloc - Allocate a memory block from pool - * Allocates a block of memory of given size, either from block pool - * or by calling vxge_os_dma_malloc() + * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open + * This function is used to close access to virtual path opened + * earlier. */ -static void * -__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, - struct vxge_hw_mempool_dma *dma_object) +enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_blockpool_entry *entry = NULL; - struct __vxge_hw_blockpool *blockpool; - void *memblock = NULL; + struct __vxge_hw_virtualpath *vpath = NULL; + struct __vxge_hw_device *devh = NULL; + u32 vp_id = vp->vpath->vp_id; + u32 is_empty = TRUE; enum vxge_hw_status status = VXGE_HW_OK; - blockpool = &devh->block_pool; + vpath = vp->vpath; + devh = vpath->hldev; - if (size != blockpool->block_size) { + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto vpath_close_exit; + } - memblock = vxge_os_dma_malloc(devh->pdev, size, - &dma_object->handle, - &dma_object->acc_handle); + list_del(&vp->item); - if (memblock == NULL) { - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto exit; - } + if (!list_empty(&vpath->vpath_handles)) { + list_add(&vp->item, &vpath->vpath_handles); + is_empty = FALSE; + } - dma_object->addr = pci_map_single(devh->pdev, memblock, size, - PCI_DMA_BIDIRECTIONAL); + if (!is_empty) { + status = VXGE_HW_FAIL; + goto vpath_close_exit; + } - if (unlikely(pci_dma_mapping_error(devh->pdev, - dma_object->addr))) { - vxge_os_dma_free(devh->pdev, memblock, - &dma_object->acc_handle); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto exit; - } + devh->vpaths_deployed &= ~vxge_mBIT(vp_id); - } else { + if (vpath->ringh != NULL) + __vxge_hw_ring_delete(vp); - if (!list_empty(&blockpool->free_block_list)) - entry = (struct __vxge_hw_blockpool_entry *) - list_first_entry(&blockpool->free_block_list, - struct __vxge_hw_blockpool_entry, - item); + if (vpath->fifoh != NULL) + __vxge_hw_fifo_delete(vp); - if (entry != NULL) { - list_del(&entry->item); - dma_object->addr = entry->dma_addr; - dma_object->handle = entry->dma_handle; - dma_object->acc_handle = entry->acc_handle; - memblock = entry->memblock; + if (vpath->stats_block != NULL) + __vxge_hw_blockpool_block_free(devh, vpath->stats_block); - list_add(&entry->item, - &blockpool->free_entry_list); - blockpool->pool_size--; - } + vfree(vp); - if (memblock != NULL) - __vxge_hw_blockpool_blocks_add(blockpool); - } -exit: - return memblock; + __vxge_hw_vp_terminate(devh, vp_id); + + spin_lock(&vpath->lock); + vpath->vp_open = VXGE_HW_VP_NOT_OPEN; + spin_unlock(&vpath->lock); + +vpath_close_exit: + return status; } /* - * __vxge_hw_blockpool_free - Frees the memory allcoated with - __vxge_hw_blockpool_malloc + * vxge_hw_vpath_reset - Resets vpath + * This function is used to request a reset of vpath */ -static void -__vxge_hw_blockpool_free(struct __vxge_hw_device *devh, - void *memblock, u32 size, - struct vxge_hw_mempool_dma *dma_object) +enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_blockpool_entry *entry = NULL; - struct __vxge_hw_blockpool *blockpool; - enum vxge_hw_status status = VXGE_HW_OK; - - blockpool = &devh->block_pool; - - if (size != blockpool->block_size) { - pci_unmap_single(devh->pdev, dma_object->addr, size, - PCI_DMA_BIDIRECTIONAL); - vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle); - } else { - - if (!list_empty(&blockpool->free_entry_list)) - entry = (struct __vxge_hw_blockpool_entry *) - list_first_entry(&blockpool->free_entry_list, - struct __vxge_hw_blockpool_entry, - item); - - if (entry == NULL) - entry = vmalloc(sizeof( - struct __vxge_hw_blockpool_entry)); - else - list_del(&entry->item); + enum vxge_hw_status status; + u32 vp_id; + struct __vxge_hw_virtualpath *vpath = vp->vpath; - if (entry != NULL) { - entry->length = size; - entry->memblock = memblock; - entry->dma_addr = dma_object->addr; - entry->acc_handle = dma_object->acc_handle; - entry->dma_handle = dma_object->handle; - list_add(&entry->item, - &blockpool->free_block_list); - blockpool->pool_size++; - status = VXGE_HW_OK; - } else - status = VXGE_HW_ERR_OUT_OF_MEMORY; + vp_id = vpath->vp_id; - if (status == VXGE_HW_OK) - __vxge_hw_blockpool_blocks_remove(blockpool); + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; } + + status = __vxge_hw_vpath_reset(vpath->hldev, vp_id); + if (status == VXGE_HW_OK) + vpath->sw_stats->soft_reset_cnt++; +exit: + return status; } /* - * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool - * This function allocates a block from block pool or from the system + * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize. + * This function poll's for the vpath reset completion and re initializes + * the vpath. */ -static struct __vxge_hw_blockpool_entry * -__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) +enum vxge_hw_status +vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_blockpool_entry *entry = NULL; - struct __vxge_hw_blockpool *blockpool; + struct __vxge_hw_virtualpath *vpath = NULL; + enum vxge_hw_status status; + struct __vxge_hw_device *hldev; + u32 vp_id; - blockpool = &devh->block_pool; + vp_id = vp->vpath->vp_id; + vpath = vp->vpath; + hldev = vpath->hldev; - if (size == blockpool->block_size) { + if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { + status = VXGE_HW_ERR_VPATH_NOT_OPEN; + goto exit; + } - if (!list_empty(&blockpool->free_block_list)) - entry = (struct __vxge_hw_blockpool_entry *) - list_first_entry(&blockpool->free_block_list, - struct __vxge_hw_blockpool_entry, - item); + status = __vxge_hw_vpath_reset_check(vpath); + if (status != VXGE_HW_OK) + goto exit; - if (entry != NULL) { - list_del(&entry->item); - blockpool->pool_size--; - } - } + status = __vxge_hw_vpath_sw_reset(hldev, vp_id); + if (status != VXGE_HW_OK) + goto exit; - if (entry != NULL) - __vxge_hw_blockpool_blocks_add(blockpool); + status = __vxge_hw_vpath_initialize(hldev, vp_id); + if (status != VXGE_HW_OK) + goto exit; - return entry; + if (vpath->ringh != NULL) + __vxge_hw_vpath_prc_configure(hldev, vp_id); + + memset(vpath->hw_stats, 0, + sizeof(struct vxge_hw_vpath_stats_hw_info)); + + memset(vpath->hw_stats_sav, 0, + sizeof(struct vxge_hw_vpath_stats_hw_info)); + + writeq(vpath->stats_block->dma_addr, + &vpath->vp_reg->stats_cfg); + + status = vxge_hw_vpath_stats_enable(vp); + +exit: + return status; } /* - * __vxge_hw_blockpool_block_free - Frees a block from block pool - * @devh: Hal device - * @entry: Entry of block to be freed - * - * This function frees a block from block pool + * vxge_hw_vpath_enable - Enable vpath. + * This routine clears the vpath reset thereby enabling a vpath + * to start forwarding frames and generating interrupts. */ -static void -__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh, - struct __vxge_hw_blockpool_entry *entry) +void +vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_blockpool *blockpool; + struct __vxge_hw_device *hldev; + u64 val64; - blockpool = &devh->block_pool; + hldev = vp->vpath->hldev; - if (entry->length == blockpool->block_size) { - list_add(&entry->item, &blockpool->free_block_list); - blockpool->pool_size++; - } + val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET( + 1 << (16 - vp->vpath->vp_id)); - __vxge_hw_blockpool_blocks_remove(blockpool); + __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), + &hldev->common_reg->cmn_rsthdlr_cfg1); } diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 5b2c8313426d..e249e288d160 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -314,9 +314,9 @@ struct vxge_hw_ring_config { #define VXGE_HW_RING_DEFAULT 1 u32 ring_blocks; -#define VXGE_HW_MIN_RING_BLOCKS 1 -#define VXGE_HW_MAX_RING_BLOCKS 128 -#define VXGE_HW_DEF_RING_BLOCKS 2 +#define VXGE_HW_MIN_RING_BLOCKS 1 +#define VXGE_HW_MAX_RING_BLOCKS 128 +#define VXGE_HW_DEF_RING_BLOCKS 2 u32 buffer_mode; #define VXGE_HW_RING_RXD_BUFFER_MODE_1 1 @@ -700,7 +700,7 @@ struct __vxge_hw_virtualpath { * * This structure is used to store the callback information. */ -struct __vxge_hw_vpath_handle{ +struct __vxge_hw_vpath_handle { struct list_head item; struct __vxge_hw_virtualpath *vpath; }; @@ -815,8 +815,8 @@ struct vxge_hw_device_hw_info { u8 serial_number[VXGE_HW_INFO_LEN]; u8 part_number[VXGE_HW_INFO_LEN]; u8 product_desc[VXGE_HW_INFO_LEN]; - u8 (mac_addrs)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN]; - u8 (mac_addr_masks)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN]; + u8 mac_addrs[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN]; + u8 mac_addr_masks[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN]; }; /** @@ -863,20 +863,10 @@ struct vxge_hw_device_attr { loc, \ offset, \ &val64); \ - \ if (status != VXGE_HW_OK) \ return status; \ } -#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \ - status = __vxge_hw_vpath_stats_access(vpath, \ - VXGE_HW_STATS_OP_READ, \ - offset, \ - &val64); \ - if (status != VXGE_HW_OK) \ - return status; \ -} - /* * struct __vxge_hw_ring - Ring channel. * @channel: Channel "base" of this ring, the common part of all HW @@ -1148,7 +1138,7 @@ struct __vxge_hw_non_offload_db_wrapper { * lookup to determine the transmit port. * 01: Send on physical Port1. * 10: Send on physical Port0. - * 11: Send on both ports. + * 11: Send on both ports. * Bits 18 to 21 - Reserved * Bits 22 to 23 - Gather_Code. This field is set by the host and * is used to describe how individual buffers comprise a frame. @@ -1927,6 +1917,15 @@ out: return vaddr; } +static inline void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr, + struct pci_dev **p_dma_acch) +{ + unsigned long misaligned = *(unsigned long *)p_dma_acch; + u8 *tmp = (u8 *)vaddr; + tmp -= misaligned; + kfree((void *)tmp); +} + /* * __vxge_hw_mempool_item_priv - will return pointer on per item private space */ @@ -1996,7 +1995,6 @@ enum vxge_hw_status vxge_hw_vpath_mtu_set( void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp); - #ifndef readq static inline u64 readq(void __iomem *addr) { diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 4877b3b8a29e..70c327910f09 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -84,15 +84,6 @@ module_param_array(bw_percentage, uint, NULL, 0); static struct vxge_drv_config *driver_config; -static enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev, - struct macInfo *mac); -static enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev, - struct macInfo *mac); -static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac); -static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); -static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); -static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); - static inline int is_vxge_card_up(struct vxgedev *vdev) { return test_bit(__VXGE_STATE_CARD_UP, &vdev->state); @@ -149,8 +140,7 @@ static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev) * This function is called during interrupt context to notify link up state * change. */ -static void -vxge_callback_link_up(struct __vxge_hw_device *hldev) +static void vxge_callback_link_up(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; struct vxgedev *vdev = netdev_priv(dev); @@ -173,8 +163,7 @@ vxge_callback_link_up(struct __vxge_hw_device *hldev) * This function is called during interrupt context to notify link down state * change. */ -static void -vxge_callback_link_down(struct __vxge_hw_device *hldev) +static void vxge_callback_link_down(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; struct vxgedev *vdev = netdev_priv(dev); @@ -196,7 +185,7 @@ vxge_callback_link_down(struct __vxge_hw_device *hldev) * * Allocate SKB. */ -static struct sk_buff* +static struct sk_buff * vxge_rx_alloc(void *dtrh, struct vxge_ring *ring, const int skb_size) { struct net_device *dev; @@ -414,7 +403,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, prefetch((char *)skb + L1_CACHE_BYTES); if (unlikely(t_code)) { - if (vxge_hw_ring_handle_tcode(ringh, dtr, t_code) != VXGE_HW_OK) { @@ -437,9 +425,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, } if (pkt_length > VXGE_LL_RX_COPY_THRESHOLD) { - if (vxge_rx_alloc(dtr, ring, data_size) != NULL) { - if (!vxge_rx_map(dtr, ring)) { skb_put(skb, pkt_length); @@ -678,6 +664,65 @@ static enum vxge_hw_status vxge_search_mac_addr_in_list( return FALSE; } +static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac) +{ + struct vxge_mac_addrs *new_mac_entry; + u8 *mac_address = NULL; + + if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT) + return TRUE; + + new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC); + if (!new_mac_entry) { + vxge_debug_mem(VXGE_ERR, + "%s: memory allocation failed", + VXGE_DRIVER_NAME); + return FALSE; + } + + list_add(&new_mac_entry->item, &vpath->mac_addr_list); + + /* Copy the new mac address to the list */ + mac_address = (u8 *)&new_mac_entry->macaddr; + memcpy(mac_address, mac->macaddr, ETH_ALEN); + + new_mac_entry->state = mac->state; + vpath->mac_addr_cnt++; + + /* Is this a multicast address */ + if (0x01 & mac->macaddr[0]) + vpath->mcast_addr_cnt++; + + return TRUE; +} + +/* Add a mac address to DA table */ +static enum vxge_hw_status +vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_vpath *vpath; + enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode; + + if (0x01 & mac->macaddr[0]) /* multicast address */ + duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE; + else + duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE; + + vpath = &vdev->vpaths[mac->vpath_no]; + status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr, + mac->macmask, duplicate_mode); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "DA config add entry failed for vpath:%d", + vpath->device_id); + } else + if (FALSE == vxge_mac_list_add(vpath, mac)) + status = -EPERM; + + return status; +} + static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) { struct macInfo mac_info; @@ -1023,6 +1068,50 @@ vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata) "%s:%d Exiting...", __func__, __LINE__); } +static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) +{ + struct list_head *entry, *next; + u64 del_mac = 0; + u8 *mac_address = (u8 *) (&del_mac); + + /* Copy the mac address to delete from the list */ + memcpy(mac_address, mac->macaddr, ETH_ALEN); + + list_for_each_safe(entry, next, &vpath->mac_addr_list) { + if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) { + list_del(entry); + kfree((struct vxge_mac_addrs *)entry); + vpath->mac_addr_cnt--; + + /* Is this a multicast address */ + if (0x01 & mac->macaddr[0]) + vpath->mcast_addr_cnt--; + return TRUE; + } + } + + return FALSE; +} + +/* delete a mac address from DA table */ +static enum vxge_hw_status +vxge_del_mac_addr(struct vxgedev *vdev, struct macInfo *mac) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_vpath *vpath; + + vpath = &vdev->vpaths[mac->vpath_no]; + status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr, + mac->macmask); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "DA config delete entry failed for vpath:%d", + vpath->device_id); + } else + vxge_mac_list_del(vpath, mac); + return status; +} + /** * vxge_set_multicast * @dev: pointer to the device structure @@ -1333,6 +1422,95 @@ static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) } } +/* list all mac addresses from DA table */ +static enum vxge_hw_status +vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath, struct macInfo *mac) +{ + enum vxge_hw_status status = VXGE_HW_OK; + unsigned char macmask[ETH_ALEN]; + unsigned char macaddr[ETH_ALEN]; + + status = vxge_hw_vpath_mac_addr_get(vpath->handle, + macaddr, macmask); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "DA config list entry failed for vpath:%d", + vpath->device_id); + return status; + } + + while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) { + status = vxge_hw_vpath_mac_addr_get_next(vpath->handle, + macaddr, macmask); + if (status != VXGE_HW_OK) + break; + } + + return status; +} + +/* Store all mac addresses from the list to the DA table */ +static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct macInfo mac_info; + u8 *mac_address = NULL; + struct list_head *entry, *next; + + memset(&mac_info, 0, sizeof(struct macInfo)); + + if (vpath->is_open) { + list_for_each_safe(entry, next, &vpath->mac_addr_list) { + mac_address = + (u8 *)& + ((struct vxge_mac_addrs *)entry)->macaddr; + memcpy(mac_info.macaddr, mac_address, ETH_ALEN); + ((struct vxge_mac_addrs *)entry)->state = + VXGE_LL_MAC_ADDR_IN_DA_TABLE; + /* does this mac address already exist in da table? */ + status = vxge_search_mac_addr_in_da_table(vpath, + &mac_info); + if (status != VXGE_HW_OK) { + /* Add this mac address to the DA table */ + status = vxge_hw_vpath_mac_addr_add( + vpath->handle, mac_info.macaddr, + mac_info.macmask, + VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "DA add entry failed for vpath:%d", + vpath->device_id); + ((struct vxge_mac_addrs *)entry)->state + = VXGE_LL_MAC_ADDR_IN_LIST; + } + } + } + } + + return status; +} + +/* Store all vlan ids from the list to the vid table */ +static enum vxge_hw_status +vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) +{ + enum vxge_hw_status status = VXGE_HW_OK; + struct vxgedev *vdev = vpath->vdev; + u16 vid; + + if (vdev->vlgrp && vpath->is_open) { + + for (vid = 0; vid < VLAN_N_VID; vid++) { + if (!vlan_group_get_device(vdev->vlgrp, vid)) + continue; + /* Add these vlan to the vid table */ + status = vxge_hw_vpath_vid_add(vpath->handle, vid); + } + } + + return status; +} + /* * vxge_reset_vpath * @vdev: pointer to vdev @@ -1745,7 +1923,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) vdev->config.rth_algorithm, &hash_types, vdev->config.rth_bkt_sz); - if (status != VXGE_HW_OK) { vxge_debug_init(VXGE_ERR, "RTH configuration failed for vpath:%d", @@ -1757,199 +1934,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) return status; } -static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac) -{ - struct vxge_mac_addrs *new_mac_entry; - u8 *mac_address = NULL; - - if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT) - return TRUE; - - new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC); - if (!new_mac_entry) { - vxge_debug_mem(VXGE_ERR, - "%s: memory allocation failed", - VXGE_DRIVER_NAME); - return FALSE; - } - - list_add(&new_mac_entry->item, &vpath->mac_addr_list); - - /* Copy the new mac address to the list */ - mac_address = (u8 *)&new_mac_entry->macaddr; - memcpy(mac_address, mac->macaddr, ETH_ALEN); - - new_mac_entry->state = mac->state; - vpath->mac_addr_cnt++; - - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) - vpath->mcast_addr_cnt++; - - return TRUE; -} - -/* Add a mac address to DA table */ -static enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev, - struct macInfo *mac) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_vpath *vpath; - enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode; - - if (0x01 & mac->macaddr[0]) /* multicast address */ - duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE; - else - duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE; - - vpath = &vdev->vpaths[mac->vpath_no]; - status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr, - mac->macmask, duplicate_mode); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "DA config add entry failed for vpath:%d", - vpath->device_id); - } else - if (FALSE == vxge_mac_list_add(vpath, mac)) - status = -EPERM; - - return status; -} - -static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) -{ - struct list_head *entry, *next; - u64 del_mac = 0; - u8 *mac_address = (u8 *)(&del_mac); - - /* Copy the mac address to delete from the list */ - memcpy(mac_address, mac->macaddr, ETH_ALEN); - - list_for_each_safe(entry, next, &vpath->mac_addr_list) { - if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) { - list_del(entry); - kfree((struct vxge_mac_addrs *)entry); - vpath->mac_addr_cnt--; - - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) - vpath->mcast_addr_cnt--; - return TRUE; - } - } - - return FALSE; -} -/* delete a mac address from DA table */ -static enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev, - struct macInfo *mac) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_vpath *vpath; - - vpath = &vdev->vpaths[mac->vpath_no]; - status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr, - mac->macmask); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "DA config delete entry failed for vpath:%d", - vpath->device_id); - } else - vxge_mac_list_del(vpath, mac); - return status; -} - -/* list all mac addresses from DA table */ -enum vxge_hw_status -static vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath, - struct macInfo *mac) -{ - enum vxge_hw_status status = VXGE_HW_OK; - unsigned char macmask[ETH_ALEN]; - unsigned char macaddr[ETH_ALEN]; - - status = vxge_hw_vpath_mac_addr_get(vpath->handle, - macaddr, macmask); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "DA config list entry failed for vpath:%d", - vpath->device_id); - return status; - } - - while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) { - - status = vxge_hw_vpath_mac_addr_get_next(vpath->handle, - macaddr, macmask); - if (status != VXGE_HW_OK) - break; - } - - return status; -} - -/* Store all vlan ids from the list to the vid table */ -static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct vxgedev *vdev = vpath->vdev; - u16 vid; - - if (vdev->vlgrp && vpath->is_open) { - - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(vdev->vlgrp, vid)) - continue; - /* Add these vlan to the vid table */ - status = vxge_hw_vpath_vid_add(vpath->handle, vid); - } - } - - return status; -} - -/* Store all mac addresses from the list to the DA table */ -static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath) -{ - enum vxge_hw_status status = VXGE_HW_OK; - struct macInfo mac_info; - u8 *mac_address = NULL; - struct list_head *entry, *next; - - memset(&mac_info, 0, sizeof(struct macInfo)); - - if (vpath->is_open) { - - list_for_each_safe(entry, next, &vpath->mac_addr_list) { - mac_address = - (u8 *)& - ((struct vxge_mac_addrs *)entry)->macaddr; - memcpy(mac_info.macaddr, mac_address, ETH_ALEN); - ((struct vxge_mac_addrs *)entry)->state = - VXGE_LL_MAC_ADDR_IN_DA_TABLE; - /* does this mac address already exist in da table? */ - status = vxge_search_mac_addr_in_da_table(vpath, - &mac_info); - if (status != VXGE_HW_OK) { - /* Add this mac address to the DA table */ - status = vxge_hw_vpath_mac_addr_add( - vpath->handle, mac_info.macaddr, - mac_info.macmask, - VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "DA add entry failed for vpath:%d", - vpath->device_id); - ((struct vxge_mac_addrs *)entry)->state - = VXGE_LL_MAC_ADDR_IN_LIST; - } - } - } - } - - return status; -} - /* reset vpaths */ enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) { @@ -2042,6 +2026,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vpath->ring.ndev = vdev->ndev; vpath->ring.pdev = vdev->pdev; + status = vxge_hw_vpath_open(vdev->devh, &attr, &vpath->handle); if (status == VXGE_HW_OK) { vpath->fifo.handle = @@ -2070,11 +2055,10 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vdev->stats.vpaths_open++; } else { vdev->stats.vpath_open_fail++; - vxge_debug_init(VXGE_ERR, - "%s: vpath: %d failed to open " - "with status: %d", - vdev->ndev->name, vpath->device_id, - status); + vxge_debug_init(VXGE_ERR, "%s: vpath: %d failed to " + "open with status: %d", + vdev->ndev->name, vpath->device_id, + status); vxge_close_vpaths(vdev, 0); return -EPERM; } @@ -2082,6 +2066,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vp_id = vpath->handle->vpath->vp_id; vdev->vpaths_deployed |= vxge_mBIT(vp_id); } + return VXGE_HW_OK; } @@ -2114,8 +2099,7 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) if (unlikely(!is_vxge_card_up(vdev))) return IRQ_HANDLED; - status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, - &reason); + status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, &reason); if (status == VXGE_HW_OK) { vxge_hw_device_mask_all(hldev); @@ -2568,8 +2552,7 @@ static void vxge_poll_vp_lockup(unsigned long data) * Return value: '0' on success and an appropriate (-)ve integer as * defined in errno.h file on failure. */ -static int -vxge_open(struct net_device *dev) +static int vxge_open(struct net_device *dev) { enum vxge_hw_status status; struct vxgedev *vdev; @@ -2578,6 +2561,7 @@ vxge_open(struct net_device *dev) int ret = 0; int i; u64 val64, function_mode; + vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); @@ -2830,7 +2814,6 @@ static int do_vxge_close(struct net_device *dev, int do_io) struct vxge_hw_mrpcim_reg, rts_mgr_cbasin_cfg), &val64); - if (status == VXGE_HW_OK) { val64 &= ~vpath_vector; status = vxge_hw_mgmt_reg_write(vdev->devh, @@ -2914,8 +2897,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) * Return value: '0' on success and an appropriate (-)ve integer as * defined in errno.h file on failure. */ -static int -vxge_close(struct net_device *dev) +static int vxge_close(struct net_device *dev) { do_vxge_close(dev, 1); return 0; @@ -2989,9 +2971,7 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes; net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors; net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast; - net_stats->rx_dropped += - vdev->vpaths[k].ring.stats.rx_dropped; - + net_stats->rx_dropped += vdev->vpaths[k].ring.stats.rx_dropped; net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms; net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes; net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors; @@ -3264,15 +3244,12 @@ static const struct net_device_ops vxge_netdev_ops = { .ndo_start_xmit = vxge_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = vxge_set_multicast, - .ndo_do_ioctl = vxge_ioctl, - .ndo_set_mac_address = vxge_set_mac_addr, .ndo_change_mtu = vxge_change_mtu, .ndo_vlan_rx_register = vxge_vlan_rx_register, .ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid, .ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid, - .ndo_tx_timeout = vxge_tx_watchdog, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = vxge_netpoll, @@ -3698,9 +3675,9 @@ static int __devinit vxge_config_vpaths( device_config->vp_config[i].tti.timer_ac_en = VXGE_HW_TIM_TIMER_AC_ENABLE; - /* For msi-x with napi (each vector - has a handler of its own) - - Set CI to OFF for all vpaths */ + /* For msi-x with napi (each vector has a handler of its own) - + * Set CI to OFF for all vpaths + */ device_config->vp_config[i].tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_DISABLE; @@ -3730,10 +3707,13 @@ static int __devinit vxge_config_vpaths( device_config->vp_config[i].ring.ring_blocks = VXGE_HW_DEF_RING_BLOCKS; + device_config->vp_config[i].ring.buffer_mode = VXGE_HW_RING_RXD_BUFFER_MODE_1; + device_config->vp_config[i].ring.rxds_limit = VXGE_HW_DEF_RING_RXDS_LIMIT; + device_config->vp_config[i].ring.scatter_mode = VXGE_HW_RING_SCATTER_MODE_A; @@ -3813,6 +3793,7 @@ static void __devinit vxge_device_config_init( device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX; break; } + /* Timer period between device poll */ device_config->device_poll_millis = VXGE_TIMER_DELAY; @@ -3824,16 +3805,10 @@ static void __devinit vxge_device_config_init( vxge_debug_ll_config(VXGE_TRACE, "%s : Device Config Params ", __func__); - vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_initial : %d", - device_config->dma_blockpool_initial); - vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_max : %d", - device_config->dma_blockpool_max); vxge_debug_ll_config(VXGE_TRACE, "intr_mode : %d", device_config->intr_mode); vxge_debug_ll_config(VXGE_TRACE, "device_poll_millis : %d", device_config->device_poll_millis); - vxge_debug_ll_config(VXGE_TRACE, "rts_mac_en : %d", - device_config->rts_mac_en); vxge_debug_ll_config(VXGE_TRACE, "rth_en : %d", device_config->rth_en); vxge_debug_ll_config(VXGE_TRACE, "rth_it_type : %d", @@ -4013,7 +3988,7 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) } pci_set_master(pdev); - vxge_reset(vdev); + do_vxge_reset(vdev, VXGE_LL_FULL_RESET); return PCI_ERS_RESULT_RECOVERED; } @@ -4244,9 +4219,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) attr.pdev = pdev; /* In SRIOV-17 mode, functions of the same adapter - * can be deployed on different buses */ - if ((!pdev->is_virtfn) && ((bus != pdev->bus->number) || - (device != PCI_SLOT(pdev->devfn)))) + * can be deployed on different buses + */ + if (((bus != pdev->bus->number) || (device != PCI_SLOT(pdev->devfn))) && + !pdev->is_virtfn) new_device = 1; bus = pdev->bus->number; @@ -4264,6 +4240,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) driver_config->config_dev_cnt = 0; driver_config->total_dev_cnt = 0; } + /* Now making the CPU based no of vpath calculation * applicable for individual functions as well. */ @@ -4286,11 +4263,11 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit0; } - ll_config = kzalloc(sizeof(*ll_config), GFP_KERNEL); + ll_config = kzalloc(sizeof(struct vxge_config), GFP_KERNEL); if (!ll_config) { ret = -ENOMEM; vxge_debug_init(VXGE_ERR, - "ll_config : malloc failed %s %d", + "device_config : malloc failed %s %d", __FILE__, __LINE__); goto _exit0; } @@ -4746,6 +4723,10 @@ vxge_starter(void) return -ENOMEM; ret = pci_register_driver(&vxge_driver); + if (ret) { + kfree(driver_config); + goto err; + } if (driver_config->config_dev_cnt && (driver_config->config_dev_cnt != driver_config->total_dev_cnt)) @@ -4753,10 +4734,7 @@ vxge_starter(void) "%s: Configured %d of %d devices", VXGE_DRIVER_NAME, driver_config->config_dev_cnt, driver_config->total_dev_cnt); - - if (ret) - kfree(driver_config); - +err: return ret; } diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 953cb0ded3e1..256d5b406a67 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -305,8 +305,8 @@ struct vxge_vpath { int is_configured; int is_open; struct vxgedev *vdev; - u8 (macaddr)[ETH_ALEN]; - u8 (macmask)[ETH_ALEN]; + u8 macaddr[ETH_ALEN]; + u8 macmask[ETH_ALEN]; #define VXGE_MAX_LEARN_MAC_ADDR_CNT 2048 /* mac addresses currently programmed into NIC */ @@ -420,10 +420,8 @@ struct vxge_tx_priv { mod_timer(&timer, (jiffies + exp)); \ } while (0); -extern void vxge_initialize_ethtool_ops(struct net_device *ndev); - +void vxge_initialize_ethtool_ops(struct net_device *ndev); enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); - int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override); /** diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 4bdb611a6842..42cc29843ac7 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -17,13 +17,6 @@ #include "vxge-config.h" #include "vxge-main.h" -static enum vxge_hw_status -__vxge_hw_device_handle_error(struct __vxge_hw_device *hldev, - u32 vp_id, enum vxge_hw_event type); -static enum vxge_hw_status -__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath, - u32 skip_alarms); - /* * vxge_hw_vpath_intr_enable - Enable vpath interrupts. * @vp: Virtual Path handle. @@ -418,151 +411,6 @@ void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev) val32 = readl(&hldev->common_reg->titan_general_int_status); } -/** - * vxge_hw_device_begin_irq - Begin IRQ processing. - * @hldev: HW device handle. - * @skip_alarms: Do not clear the alarms - * @reason: "Reason" for the interrupt, the value of Titan's - * general_int_status register. - * - * The function performs two actions, It first checks whether (shared IRQ) the - * interrupt was raised by the device. Next, it masks the device interrupts. - * - * Note: - * vxge_hw_device_begin_irq() does not flush MMIO writes through the - * bridge. Therefore, two back-to-back interrupts are potentially possible. - * - * Returns: 0, if the interrupt is not "ours" (note that in this case the - * device remain enabled). - * Otherwise, vxge_hw_device_begin_irq() returns 64bit general adapter - * status. - */ -enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev, - u32 skip_alarms, u64 *reason) -{ - u32 i; - u64 val64; - u64 adapter_status; - u64 vpath_mask; - enum vxge_hw_status ret = VXGE_HW_OK; - - val64 = readq(&hldev->common_reg->titan_general_int_status); - - if (unlikely(!val64)) { - /* not Titan interrupt */ - *reason = 0; - ret = VXGE_HW_ERR_WRONG_IRQ; - goto exit; - } - - if (unlikely(val64 == VXGE_HW_ALL_FOXES)) { - - adapter_status = readq(&hldev->common_reg->adapter_status); - - if (adapter_status == VXGE_HW_ALL_FOXES) { - - __vxge_hw_device_handle_error(hldev, - NULL_VPID, VXGE_HW_EVENT_SLOT_FREEZE); - *reason = 0; - ret = VXGE_HW_ERR_SLOT_FREEZE; - goto exit; - } - } - - hldev->stats.sw_dev_info_stats.total_intr_cnt++; - - *reason = val64; - - vpath_mask = hldev->vpaths_deployed >> - (64 - VXGE_HW_MAX_VIRTUAL_PATHS); - - if (val64 & - VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) { - hldev->stats.sw_dev_info_stats.traffic_intr_cnt++; - - return VXGE_HW_OK; - } - - hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt++; - - if (unlikely(val64 & - VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) { - - enum vxge_hw_status error_level = VXGE_HW_OK; - - hldev->stats.sw_dev_err_stats.vpath_alarms++; - - for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - - if (!(hldev->vpaths_deployed & vxge_mBIT(i))) - continue; - - ret = __vxge_hw_vpath_alarm_process( - &hldev->virtual_paths[i], skip_alarms); - - error_level = VXGE_HW_SET_LEVEL(ret, error_level); - - if (unlikely((ret == VXGE_HW_ERR_CRITICAL) || - (ret == VXGE_HW_ERR_SLOT_FREEZE))) - break; - } - - ret = error_level; - } -exit: - return ret; -} - -/* - * __vxge_hw_device_handle_link_up_ind - * @hldev: HW device handle. - * - * Link up indication handler. The function is invoked by HW when - * Titan indicates that the link is up for programmable amount of time. - */ -static enum vxge_hw_status -__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev) -{ - /* - * If the previous link state is not down, return. - */ - if (hldev->link_state == VXGE_HW_LINK_UP) - goto exit; - - hldev->link_state = VXGE_HW_LINK_UP; - - /* notify driver */ - if (hldev->uld_callbacks.link_up) - hldev->uld_callbacks.link_up(hldev); -exit: - return VXGE_HW_OK; -} - -/* - * __vxge_hw_device_handle_link_down_ind - * @hldev: HW device handle. - * - * Link down indication handler. The function is invoked by HW when - * Titan indicates that the link is down. - */ -static enum vxge_hw_status -__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev) -{ - /* - * If the previous link state is not down, return. - */ - if (hldev->link_state == VXGE_HW_LINK_DOWN) - goto exit; - - hldev->link_state = VXGE_HW_LINK_DOWN; - - /* notify driver */ - if (hldev->uld_callbacks.link_down) - hldev->uld_callbacks.link_down(hldev); -exit: - return VXGE_HW_OK; -} - /** * __vxge_hw_device_handle_error - Handle error * @hldev: HW device @@ -572,10 +420,8 @@ exit: * Handle error. */ static enum vxge_hw_status -__vxge_hw_device_handle_error( - struct __vxge_hw_device *hldev, - u32 vp_id, - enum vxge_hw_event type) +__vxge_hw_device_handle_error(struct __vxge_hw_device *hldev, u32 vp_id, + enum vxge_hw_event type) { switch (type) { case VXGE_HW_EVENT_UNKNOWN: @@ -615,95 +461,518 @@ out: return VXGE_HW_OK; } -/** - * vxge_hw_device_clear_tx_rx - Acknowledge (that is, clear) the - * condition that has caused the Tx and RX interrupt. - * @hldev: HW device. +/* + * __vxge_hw_device_handle_link_down_ind + * @hldev: HW device handle. * - * Acknowledge (that is, clear) the condition that has caused - * the Tx and Rx interrupt. - * See also: vxge_hw_device_begin_irq(), - * vxge_hw_device_mask_tx_rx(), vxge_hw_device_unmask_tx_rx(). + * Link down indication handler. The function is invoked by HW when + * Titan indicates that the link is down. */ -void vxge_hw_device_clear_tx_rx(struct __vxge_hw_device *hldev) +static enum vxge_hw_status +__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev) { + /* + * If the previous link state is not down, return. + */ + if (hldev->link_state == VXGE_HW_LINK_DOWN) + goto exit; - if ((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) || - (hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) { - writeq((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] | - hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX]), - &hldev->common_reg->tim_int_status0); - } + hldev->link_state = VXGE_HW_LINK_DOWN; - if ((hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) || - (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) { - __vxge_hw_pio_mem_write32_upper( - (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] | - hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX]), - &hldev->common_reg->tim_int_status1); - } + /* notify driver */ + if (hldev->uld_callbacks.link_down) + hldev->uld_callbacks.link_down(hldev); +exit: + return VXGE_HW_OK; } /* - * vxge_hw_channel_dtr_alloc - Allocate a dtr from the channel - * @channel: Channel - * @dtrh: Buffer to return the DTR pointer - * - * Allocates a dtr from the reserve array. If the reserve array is empty, - * it swaps the reserve and free arrays. + * __vxge_hw_device_handle_link_up_ind + * @hldev: HW device handle. * + * Link up indication handler. The function is invoked by HW when + * Titan indicates that the link is up for programmable amount of time. */ static enum vxge_hw_status -vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh) +__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev) { - void **tmp_arr; - - if (channel->reserve_ptr - channel->reserve_top > 0) { -_alloc_after_swap: - *dtrh = channel->reserve_arr[--channel->reserve_ptr]; - - return VXGE_HW_OK; - } - - /* switch between empty and full arrays */ - - /* the idea behind such a design is that by having free and reserved - * arrays separated we basically separated irq and non-irq parts. - * i.e. no additional lock need to be done when we free a resource */ - - if (channel->length - channel->free_ptr > 0) { - - tmp_arr = channel->reserve_arr; - channel->reserve_arr = channel->free_arr; - channel->free_arr = tmp_arr; - channel->reserve_ptr = channel->length; - channel->reserve_top = channel->free_ptr; - channel->free_ptr = channel->length; - - channel->stats->reserve_free_swaps_cnt++; - - goto _alloc_after_swap; - } + /* + * If the previous link state is not down, return. + */ + if (hldev->link_state == VXGE_HW_LINK_UP) + goto exit; - channel->stats->full_cnt++; + hldev->link_state = VXGE_HW_LINK_UP; - *dtrh = NULL; - return VXGE_HW_INF_OUT_OF_DESCRIPTORS; + /* notify driver */ + if (hldev->uld_callbacks.link_up) + hldev->uld_callbacks.link_up(hldev); +exit: + return VXGE_HW_OK; } /* - * vxge_hw_channel_dtr_post - Post a dtr to the channel - * @channelh: Channel - * @dtrh: DTR pointer + * __vxge_hw_vpath_alarm_process - Process Alarms. + * @vpath: Virtual Path. + * @skip_alarms: Do not clear the alarms * - * Posts a dtr to work array. + * Process vpath alarms. * */ -static void vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, - void *dtrh) +static enum vxge_hw_status +__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath, + u32 skip_alarms) { - vxge_assert(channel->work_arr[channel->post_index] == NULL); - + u64 val64; + u64 alarm_status; + u64 pic_status; + struct __vxge_hw_device *hldev = NULL; + enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN; + u64 mask64; + struct vxge_hw_vpath_stats_sw_info *sw_stats; + struct vxge_hw_vpath_reg __iomem *vp_reg; + + if (vpath == NULL) { + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, + alarm_event); + goto out2; + } + + hldev = vpath->hldev; + vp_reg = vpath->vp_reg; + alarm_status = readq(&vp_reg->vpath_general_int_status); + + if (alarm_status == VXGE_HW_ALL_FOXES) { + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE, + alarm_event); + goto out; + } + + sw_stats = vpath->sw_stats; + + if (alarm_status & ~( + VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT | + VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT | + VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT | + VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) { + sw_stats->error_stats.unknown_alarms++; + + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, + alarm_event); + goto out; + } + + if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) { + + val64 = readq(&vp_reg->xgmac_vp_int_status); + + if (val64 & + VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) { + + val64 = readq(&vp_reg->asic_ntwk_vp_err_reg); + + if (((val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) && + (!(val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) || + ((val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) && + (!(val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) + ))) { + sw_stats->error_stats.network_sustained_fault++; + + writeq( + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT, + &vp_reg->asic_ntwk_vp_err_mask); + + __vxge_hw_device_handle_link_down_ind(hldev); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_LINK_DOWN, alarm_event); + } + + if (((val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) && + (!(val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) || + ((val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) && + (!(val64 & + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) + ))) { + + sw_stats->error_stats.network_sustained_ok++; + + writeq( + VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK, + &vp_reg->asic_ntwk_vp_err_mask); + + __vxge_hw_device_handle_link_up_ind(hldev); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_LINK_UP, alarm_event); + } + + writeq(VXGE_HW_INTR_MASK_ALL, + &vp_reg->asic_ntwk_vp_err_reg); + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); + + if (skip_alarms) + return VXGE_HW_OK; + } + } + + if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) { + + pic_status = readq(&vp_reg->vpath_ppif_int_status); + + if (pic_status & + VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) { + + val64 = readq(&vp_reg->general_errors_reg); + mask64 = readq(&vp_reg->general_errors_mask); + + if ((val64 & + VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) & + ~mask64) { + sw_stats->error_stats.ini_serr_det++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_SERR, alarm_event); + } + + if ((val64 & + VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) & + ~mask64) { + sw_stats->error_stats.dblgen_fifo0_overflow++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, alarm_event); + } + + if ((val64 & + VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) & + ~mask64) + sw_stats->error_stats.statsb_pif_chain_error++; + + if ((val64 & + VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) & + ~mask64) + sw_stats->error_stats.statsb_drop_timeout++; + + if ((val64 & + VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) & + ~mask64) + sw_stats->error_stats.target_illegal_access++; + + if (!skip_alarms) { + writeq(VXGE_HW_INTR_MASK_ALL, + &vp_reg->general_errors_reg); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event); + } + } + + if (pic_status & + VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) { + + val64 = readq(&vp_reg->kdfcctl_errors_reg); + mask64 = readq(&vp_reg->kdfcctl_errors_mask); + + if ((val64 & + VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) & + ~mask64) { + sw_stats->error_stats.kdfcctl_fifo0_overwrite++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, + alarm_event); + } + + if ((val64 & + VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) & + ~mask64) { + sw_stats->error_stats.kdfcctl_fifo0_poison++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, + alarm_event); + } + + if ((val64 & + VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) & + ~mask64) { + sw_stats->error_stats.kdfcctl_fifo0_dma_error++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, + alarm_event); + } + + if (!skip_alarms) { + writeq(VXGE_HW_INTR_MASK_ALL, + &vp_reg->kdfcctl_errors_reg); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event); + } + } + + } + + if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) { + + val64 = readq(&vp_reg->wrdma_alarm_status); + + if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) { + + val64 = readq(&vp_reg->prc_alarm_reg); + mask64 = readq(&vp_reg->prc_alarm_mask); + + if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)& + ~mask64) + sw_stats->error_stats.prc_ring_bumps++; + + if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) & + ~mask64) { + sw_stats->error_stats.prc_rxdcm_sc_err++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, + alarm_event); + } + + if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT) + & ~mask64) { + sw_stats->error_stats.prc_rxdcm_sc_abort++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, + alarm_event); + } + + if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR) + & ~mask64) { + sw_stats->error_stats.prc_quanta_size_err++; + + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, + alarm_event); + } + + if (!skip_alarms) { + writeq(VXGE_HW_INTR_MASK_ALL, + &vp_reg->prc_alarm_reg); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event); + } + } + } +out: + hldev->stats.sw_dev_err_stats.vpath_alarms++; +out2: + if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) || + (alarm_event == VXGE_HW_EVENT_UNKNOWN)) + return VXGE_HW_OK; + + __vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event); + + if (alarm_event == VXGE_HW_EVENT_SERR) + return VXGE_HW_ERR_CRITICAL; + + return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ? + VXGE_HW_ERR_SLOT_FREEZE : + (alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO : + VXGE_HW_ERR_VPATH; +} + +/** + * vxge_hw_device_begin_irq - Begin IRQ processing. + * @hldev: HW device handle. + * @skip_alarms: Do not clear the alarms + * @reason: "Reason" for the interrupt, the value of Titan's + * general_int_status register. + * + * The function performs two actions, It first checks whether (shared IRQ) the + * interrupt was raised by the device. Next, it masks the device interrupts. + * + * Note: + * vxge_hw_device_begin_irq() does not flush MMIO writes through the + * bridge. Therefore, two back-to-back interrupts are potentially possible. + * + * Returns: 0, if the interrupt is not "ours" (note that in this case the + * device remain enabled). + * Otherwise, vxge_hw_device_begin_irq() returns 64bit general adapter + * status. + */ +enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev, + u32 skip_alarms, u64 *reason) +{ + u32 i; + u64 val64; + u64 adapter_status; + u64 vpath_mask; + enum vxge_hw_status ret = VXGE_HW_OK; + + val64 = readq(&hldev->common_reg->titan_general_int_status); + + if (unlikely(!val64)) { + /* not Titan interrupt */ + *reason = 0; + ret = VXGE_HW_ERR_WRONG_IRQ; + goto exit; + } + + if (unlikely(val64 == VXGE_HW_ALL_FOXES)) { + + adapter_status = readq(&hldev->common_reg->adapter_status); + + if (adapter_status == VXGE_HW_ALL_FOXES) { + + __vxge_hw_device_handle_error(hldev, + NULL_VPID, VXGE_HW_EVENT_SLOT_FREEZE); + *reason = 0; + ret = VXGE_HW_ERR_SLOT_FREEZE; + goto exit; + } + } + + hldev->stats.sw_dev_info_stats.total_intr_cnt++; + + *reason = val64; + + vpath_mask = hldev->vpaths_deployed >> + (64 - VXGE_HW_MAX_VIRTUAL_PATHS); + + if (val64 & + VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) { + hldev->stats.sw_dev_info_stats.traffic_intr_cnt++; + + return VXGE_HW_OK; + } + + hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt++; + + if (unlikely(val64 & + VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) { + + enum vxge_hw_status error_level = VXGE_HW_OK; + + hldev->stats.sw_dev_err_stats.vpath_alarms++; + + for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + + if (!(hldev->vpaths_deployed & vxge_mBIT(i))) + continue; + + ret = __vxge_hw_vpath_alarm_process( + &hldev->virtual_paths[i], skip_alarms); + + error_level = VXGE_HW_SET_LEVEL(ret, error_level); + + if (unlikely((ret == VXGE_HW_ERR_CRITICAL) || + (ret == VXGE_HW_ERR_SLOT_FREEZE))) + break; + } + + ret = error_level; + } +exit: + return ret; +} + +/** + * vxge_hw_device_clear_tx_rx - Acknowledge (that is, clear) the + * condition that has caused the Tx and RX interrupt. + * @hldev: HW device. + * + * Acknowledge (that is, clear) the condition that has caused + * the Tx and Rx interrupt. + * See also: vxge_hw_device_begin_irq(), + * vxge_hw_device_mask_tx_rx(), vxge_hw_device_unmask_tx_rx(). + */ +void vxge_hw_device_clear_tx_rx(struct __vxge_hw_device *hldev) +{ + + if ((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) || + (hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) { + writeq((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] | + hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX]), + &hldev->common_reg->tim_int_status0); + } + + if ((hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) || + (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) { + __vxge_hw_pio_mem_write32_upper( + (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] | + hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX]), + &hldev->common_reg->tim_int_status1); + } +} + +/* + * vxge_hw_channel_dtr_alloc - Allocate a dtr from the channel + * @channel: Channel + * @dtrh: Buffer to return the DTR pointer + * + * Allocates a dtr from the reserve array. If the reserve array is empty, + * it swaps the reserve and free arrays. + * + */ +static enum vxge_hw_status +vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh) +{ + void **tmp_arr; + + if (channel->reserve_ptr - channel->reserve_top > 0) { +_alloc_after_swap: + *dtrh = channel->reserve_arr[--channel->reserve_ptr]; + + return VXGE_HW_OK; + } + + /* switch between empty and full arrays */ + + /* the idea behind such a design is that by having free and reserved + * arrays separated we basically separated irq and non-irq parts. + * i.e. no additional lock need to be done when we free a resource */ + + if (channel->length - channel->free_ptr > 0) { + + tmp_arr = channel->reserve_arr; + channel->reserve_arr = channel->free_arr; + channel->free_arr = tmp_arr; + channel->reserve_ptr = channel->length; + channel->reserve_top = channel->free_ptr; + channel->free_ptr = channel->length; + + channel->stats->reserve_free_swaps_cnt++; + + goto _alloc_after_swap; + } + + channel->stats->full_cnt++; + + *dtrh = NULL; + return VXGE_HW_INF_OUT_OF_DESCRIPTORS; +} + +/* + * vxge_hw_channel_dtr_post - Post a dtr to the channel + * @channelh: Channel + * @dtrh: DTR pointer + * + * Posts a dtr to work array. + * + */ +static void +vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh) +{ + vxge_assert(channel->work_arr[channel->post_index] == NULL); + channel->work_arr[channel->post_index++] = dtrh; /* wrap-around */ @@ -911,10 +1180,6 @@ void vxge_hw_ring_rxd_post(struct __vxge_hw_ring *ring, void *rxdh) */ void vxge_hw_ring_rxd_post_post_wmb(struct __vxge_hw_ring *ring, void *rxdh) { - struct __vxge_hw_channel *channel; - - channel = &ring->channel; - wmb(); vxge_hw_ring_rxd_post_post(ring, rxdh); } @@ -1542,607 +1807,329 @@ vxge_hw_vpath_mac_addr_get_next( if (status != VXGE_HW_OK) goto exit; - data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1); - - data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2); - - for (i = ETH_ALEN; i > 0; i--) { - macaddr[i-1] = (u8)(data1 & 0xFF); - data1 >>= 8; - - macaddr_mask[i-1] = (u8)(data2 & 0xFF); - data2 >>= 8; - } - -exit: - return status; -} - -/** - * vxge_hw_vpath_mac_addr_delete - Delete the mac address entry for this vpath - * to MAC address table. - * @vp: Vpath handle. - * @macaddr: MAC address to be added for this vpath into the list - * @macaddr_mask: MAC address mask for macaddr - * - * Delete the given mac address and mac address mask into the list for this - * vpath. - * see also: vxge_hw_vpath_mac_addr_add, vxge_hw_vpath_mac_addr_get and - * vxge_hw_vpath_mac_addr_get_next - * - */ -enum vxge_hw_status -vxge_hw_vpath_mac_addr_delete( - struct __vxge_hw_vpath_handle *vp, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]) -{ - u32 i; - u64 data1 = 0ULL; - u64 data2 = 0ULL; - enum vxge_hw_status status = VXGE_HW_OK; - - if (vp == NULL) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - for (i = 0; i < ETH_ALEN; i++) { - data1 <<= 8; - data1 |= (u8)macaddr[i]; - - data2 <<= 8; - data2 |= (u8)macaddr_mask[i]; - } - - status = __vxge_hw_vpath_rts_table_set(vp, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA, - 0, - VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1), - VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2)); -exit: - return status; -} - -/** - * vxge_hw_vpath_vid_add - Add the vlan id entry for this vpath - * to vlan id table. - * @vp: Vpath handle. - * @vid: vlan id to be added for this vpath into the list - * - * Adds the given vlan id into the list for this vpath. - * see also: vxge_hw_vpath_vid_delete, vxge_hw_vpath_vid_get and - * vxge_hw_vpath_vid_get_next - * - */ -enum vxge_hw_status -vxge_hw_vpath_vid_add(struct __vxge_hw_vpath_handle *vp, u64 vid) -{ - enum vxge_hw_status status = VXGE_HW_OK; - - if (vp == NULL) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - status = __vxge_hw_vpath_rts_table_set(vp, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, - 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0); -exit: - return status; -} - -/** - * vxge_hw_vpath_vid_get - Get the first vid entry for this vpath - * from vlan id table. - * @vp: Vpath handle. - * @vid: Buffer to return vlan id - * - * Returns the first vlan id in the list for this vpath. - * see also: vxge_hw_vpath_vid_get_next - * - */ -enum vxge_hw_status -vxge_hw_vpath_vid_get(struct __vxge_hw_vpath_handle *vp, u64 *vid) -{ - u64 data; - enum vxge_hw_status status = VXGE_HW_OK; - - if (vp == NULL) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - status = __vxge_hw_vpath_rts_table_get(vp, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, - 0, vid, &data); - - *vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid); -exit: - return status; -} - -/** - * vxge_hw_vpath_vid_delete - Delete the vlan id entry for this vpath - * to vlan id table. - * @vp: Vpath handle. - * @vid: vlan id to be added for this vpath into the list - * - * Adds the given vlan id into the list for this vpath. - * see also: vxge_hw_vpath_vid_add, vxge_hw_vpath_vid_get and - * vxge_hw_vpath_vid_get_next - * - */ -enum vxge_hw_status -vxge_hw_vpath_vid_delete(struct __vxge_hw_vpath_handle *vp, u64 vid) -{ - enum vxge_hw_status status = VXGE_HW_OK; - - if (vp == NULL) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - status = __vxge_hw_vpath_rts_table_set(vp, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, - 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0); -exit: - return status; -} - -/** - * vxge_hw_vpath_promisc_enable - Enable promiscuous mode. - * @vp: Vpath handle. - * - * Enable promiscuous mode of Titan-e operation. - * - * See also: vxge_hw_vpath_promisc_disable(). - */ -enum vxge_hw_status vxge_hw_vpath_promisc_enable( - struct __vxge_hw_vpath_handle *vp) -{ - u64 val64; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status = VXGE_HW_OK; - - if ((vp == NULL) || (vp->vpath->ringh == NULL)) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - vpath = vp->vpath; - - /* Enable promiscous mode for function 0 only */ - if (!(vpath->hldev->access_rights & - VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) - return VXGE_HW_OK; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - - if (!(val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN)) { - - val64 |= VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN | - VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN | - VXGE_HW_RXMAC_VCFG0_BCAST_EN | - VXGE_HW_RXMAC_VCFG0_ALL_VID_EN; - - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); - } -exit: - return status; -} - -/** - * vxge_hw_vpath_promisc_disable - Disable promiscuous mode. - * @vp: Vpath handle. - * - * Disable promiscuous mode of Titan-e operation. - * - * See also: vxge_hw_vpath_promisc_enable(). - */ -enum vxge_hw_status vxge_hw_vpath_promisc_disable( - struct __vxge_hw_vpath_handle *vp) -{ - u64 val64; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status = VXGE_HW_OK; - - if ((vp == NULL) || (vp->vpath->ringh == NULL)) { - status = VXGE_HW_ERR_INVALID_HANDLE; - goto exit; - } - - vpath = vp->vpath; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); + data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1); - if (val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN) { + data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2); - val64 &= ~(VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN | - VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN | - VXGE_HW_RXMAC_VCFG0_ALL_VID_EN); + for (i = ETH_ALEN; i > 0; i--) { + macaddr[i-1] = (u8)(data1 & 0xFF); + data1 >>= 8; - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + macaddr_mask[i-1] = (u8)(data2 & 0xFF); + data2 >>= 8; } + exit: return status; } -/* - * vxge_hw_vpath_bcast_enable - Enable broadcast +/** + * vxge_hw_vpath_mac_addr_delete - Delete the mac address entry for this vpath + * to MAC address table. * @vp: Vpath handle. + * @macaddr: MAC address to be added for this vpath into the list + * @macaddr_mask: MAC address mask for macaddr + * + * Delete the given mac address and mac address mask into the list for this + * vpath. + * see also: vxge_hw_vpath_mac_addr_add, vxge_hw_vpath_mac_addr_get and + * vxge_hw_vpath_mac_addr_get_next * - * Enable receiving broadcasts. */ -enum vxge_hw_status vxge_hw_vpath_bcast_enable( - struct __vxge_hw_vpath_handle *vp) +enum vxge_hw_status +vxge_hw_vpath_mac_addr_delete( + struct __vxge_hw_vpath_handle *vp, + u8 (macaddr)[ETH_ALEN], + u8 (macaddr_mask)[ETH_ALEN]) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; + u32 i; + u64 data1 = 0ULL; + u64 data2 = 0ULL; enum vxge_hw_status status = VXGE_HW_OK; - if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - vpath = vp->vpath; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); + for (i = 0; i < ETH_ALEN; i++) { + data1 <<= 8; + data1 |= (u8)macaddr[i]; - if (!(val64 & VXGE_HW_RXMAC_VCFG0_BCAST_EN)) { - val64 |= VXGE_HW_RXMAC_VCFG0_BCAST_EN; - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + data2 <<= 8; + data2 |= (u8)macaddr_mask[i]; } + + status = __vxge_hw_vpath_rts_table_set(vp, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA, + 0, + VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1), + VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2)); exit: return status; } /** - * vxge_hw_vpath_mcast_enable - Enable multicast addresses. + * vxge_hw_vpath_vid_add - Add the vlan id entry for this vpath + * to vlan id table. * @vp: Vpath handle. + * @vid: vlan id to be added for this vpath into the list * - * Enable Titan-e multicast addresses. - * Returns: VXGE_HW_OK on success. + * Adds the given vlan id into the list for this vpath. + * see also: vxge_hw_vpath_vid_delete, vxge_hw_vpath_vid_get and + * vxge_hw_vpath_vid_get_next * */ -enum vxge_hw_status vxge_hw_vpath_mcast_enable( - struct __vxge_hw_vpath_handle *vp) +enum vxge_hw_status +vxge_hw_vpath_vid_add(struct __vxge_hw_vpath_handle *vp, u64 vid) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; enum vxge_hw_status status = VXGE_HW_OK; - if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - vpath = vp->vpath; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - - if (!(val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN)) { - val64 |= VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN; - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); - } + status = __vxge_hw_vpath_rts_table_set(vp, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, + 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0); exit: return status; } /** - * vxge_hw_vpath_mcast_disable - Disable multicast addresses. + * vxge_hw_vpath_vid_get - Get the first vid entry for this vpath + * from vlan id table. * @vp: Vpath handle. + * @vid: Buffer to return vlan id * - * Disable Titan-e multicast addresses. - * Returns: VXGE_HW_OK - success. - * VXGE_HW_ERR_INVALID_HANDLE - Invalid handle + * Returns the first vlan id in the list for this vpath. + * see also: vxge_hw_vpath_vid_get_next * */ enum vxge_hw_status -vxge_hw_vpath_mcast_disable(struct __vxge_hw_vpath_handle *vp) +vxge_hw_vpath_vid_get(struct __vxge_hw_vpath_handle *vp, u64 *vid) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; + u64 data; enum vxge_hw_status status = VXGE_HW_OK; - if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - vpath = vp->vpath; - - val64 = readq(&vpath->vp_reg->rxmac_vcfg0); + status = __vxge_hw_vpath_rts_table_get(vp, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, + 0, vid, &data); - if (val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN) { - val64 &= ~VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN; - writeq(val64, &vpath->vp_reg->rxmac_vcfg0); - } + *vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid); exit: return status; } -/* - * __vxge_hw_vpath_alarm_process - Process Alarms. - * @vpath: Virtual Path. - * @skip_alarms: Do not clear the alarms +/** + * vxge_hw_vpath_vid_delete - Delete the vlan id entry for this vpath + * to vlan id table. + * @vp: Vpath handle. + * @vid: vlan id to be added for this vpath into the list * - * Process vpath alarms. + * Adds the given vlan id into the list for this vpath. + * see also: vxge_hw_vpath_vid_add, vxge_hw_vpath_vid_get and + * vxge_hw_vpath_vid_get_next * */ -static enum vxge_hw_status -__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath, - u32 skip_alarms) +enum vxge_hw_status +vxge_hw_vpath_vid_delete(struct __vxge_hw_vpath_handle *vp, u64 vid) { - u64 val64; - u64 alarm_status; - u64 pic_status; - struct __vxge_hw_device *hldev = NULL; - enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN; - u64 mask64; - struct vxge_hw_vpath_stats_sw_info *sw_stats; - struct vxge_hw_vpath_reg __iomem *vp_reg; - - if (vpath == NULL) { - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, - alarm_event); - goto out2; - } - - hldev = vpath->hldev; - vp_reg = vpath->vp_reg; - alarm_status = readq(&vp_reg->vpath_general_int_status); - - if (alarm_status == VXGE_HW_ALL_FOXES) { - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE, - alarm_event); - goto out; - } - - sw_stats = vpath->sw_stats; - - if (alarm_status & ~( - VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT | - VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT | - VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT | - VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) { - sw_stats->error_stats.unknown_alarms++; - - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, - alarm_event); - goto out; - } - - if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) { - - val64 = readq(&vp_reg->xgmac_vp_int_status); - - if (val64 & - VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) { - - val64 = readq(&vp_reg->asic_ntwk_vp_err_reg); - - if (((val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) && - (!(val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) || - ((val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) && - (!(val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) - ))) { - sw_stats->error_stats.network_sustained_fault++; - - writeq( - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT, - &vp_reg->asic_ntwk_vp_err_mask); - - __vxge_hw_device_handle_link_down_ind(hldev); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_LINK_DOWN, alarm_event); - } - - if (((val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) && - (!(val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) || - ((val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) && - (!(val64 & - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) - ))) { - - sw_stats->error_stats.network_sustained_ok++; - - writeq( - VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK, - &vp_reg->asic_ntwk_vp_err_mask); - - __vxge_hw_device_handle_link_up_ind(hldev); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_LINK_UP, alarm_event); - } - - writeq(VXGE_HW_INTR_MASK_ALL, - &vp_reg->asic_ntwk_vp_err_reg); - - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); + enum vxge_hw_status status = VXGE_HW_OK; - if (skip_alarms) - return VXGE_HW_OK; - } + if (vp == NULL) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; } - if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) { - - pic_status = readq(&vp_reg->vpath_ppif_int_status); - - if (pic_status & - VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) { - - val64 = readq(&vp_reg->general_errors_reg); - mask64 = readq(&vp_reg->general_errors_mask); - - if ((val64 & - VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) & - ~mask64) { - sw_stats->error_stats.ini_serr_det++; - - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_SERR, alarm_event); - } - - if ((val64 & - VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) & - ~mask64) { - sw_stats->error_stats.dblgen_fifo0_overflow++; + status = __vxge_hw_vpath_rts_table_set(vp, + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID, + 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0); +exit: + return status; +} - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, alarm_event); - } +/** + * vxge_hw_vpath_promisc_enable - Enable promiscuous mode. + * @vp: Vpath handle. + * + * Enable promiscuous mode of Titan-e operation. + * + * See also: vxge_hw_vpath_promisc_disable(). + */ +enum vxge_hw_status vxge_hw_vpath_promisc_enable( + struct __vxge_hw_vpath_handle *vp) +{ + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - if ((val64 & - VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) & - ~mask64) - sw_stats->error_stats.statsb_pif_chain_error++; + if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; + } - if ((val64 & - VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) & - ~mask64) - sw_stats->error_stats.statsb_drop_timeout++; + vpath = vp->vpath; - if ((val64 & - VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) & - ~mask64) - sw_stats->error_stats.target_illegal_access++; + /* Enable promiscous mode for function 0 only */ + if (!(vpath->hldev->access_rights & + VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) + return VXGE_HW_OK; - if (!skip_alarms) { - writeq(VXGE_HW_INTR_MASK_ALL, - &vp_reg->general_errors_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, - alarm_event); - } - } + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - if (pic_status & - VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) { + if (!(val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN)) { - val64 = readq(&vp_reg->kdfcctl_errors_reg); - mask64 = readq(&vp_reg->kdfcctl_errors_mask); + val64 |= VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN | + VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN | + VXGE_HW_RXMAC_VCFG0_BCAST_EN | + VXGE_HW_RXMAC_VCFG0_ALL_VID_EN; - if ((val64 & - VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) & - ~mask64) { - sw_stats->error_stats.kdfcctl_fifo0_overwrite++; + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + } +exit: + return status; +} - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, - alarm_event); - } +/** + * vxge_hw_vpath_promisc_disable - Disable promiscuous mode. + * @vp: Vpath handle. + * + * Disable promiscuous mode of Titan-e operation. + * + * See also: vxge_hw_vpath_promisc_enable(). + */ +enum vxge_hw_status vxge_hw_vpath_promisc_disable( + struct __vxge_hw_vpath_handle *vp) +{ + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - if ((val64 & - VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) & - ~mask64) { - sw_stats->error_stats.kdfcctl_fifo0_poison++; + if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; + } - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, - alarm_event); - } + vpath = vp->vpath; - if ((val64 & - VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) & - ~mask64) { - sw_stats->error_stats.kdfcctl_fifo0_dma_error++; + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, - alarm_event); - } + if (val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN) { - if (!skip_alarms) { - writeq(VXGE_HW_INTR_MASK_ALL, - &vp_reg->kdfcctl_errors_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, - alarm_event); - } - } + val64 &= ~(VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN | + VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN | + VXGE_HW_RXMAC_VCFG0_ALL_VID_EN); + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); } +exit: + return status; +} - if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) { +/* + * vxge_hw_vpath_bcast_enable - Enable broadcast + * @vp: Vpath handle. + * + * Enable receiving broadcasts. + */ +enum vxge_hw_status vxge_hw_vpath_bcast_enable( + struct __vxge_hw_vpath_handle *vp) +{ + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - val64 = readq(&vp_reg->wrdma_alarm_status); + if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; + } - if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) { + vpath = vp->vpath; - val64 = readq(&vp_reg->prc_alarm_reg); - mask64 = readq(&vp_reg->prc_alarm_mask); + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)& - ~mask64) - sw_stats->error_stats.prc_ring_bumps++; + if (!(val64 & VXGE_HW_RXMAC_VCFG0_BCAST_EN)) { + val64 |= VXGE_HW_RXMAC_VCFG0_BCAST_EN; + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + } +exit: + return status; +} - if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) & - ~mask64) { - sw_stats->error_stats.prc_rxdcm_sc_err++; +/** + * vxge_hw_vpath_mcast_enable - Enable multicast addresses. + * @vp: Vpath handle. + * + * Enable Titan-e multicast addresses. + * Returns: VXGE_HW_OK on success. + * + */ +enum vxge_hw_status vxge_hw_vpath_mcast_enable( + struct __vxge_hw_vpath_handle *vp) +{ + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, - alarm_event); - } + if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; + } - if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT) - & ~mask64) { - sw_stats->error_stats.prc_rxdcm_sc_abort++; + vpath = vp->vpath; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, - alarm_event); - } + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR) - & ~mask64) { - sw_stats->error_stats.prc_quanta_size_err++; + if (!(val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN)) { + val64 |= VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN; + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + } +exit: + return status; +} - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, - alarm_event); - } +/** + * vxge_hw_vpath_mcast_disable - Disable multicast addresses. + * @vp: Vpath handle. + * + * Disable Titan-e multicast addresses. + * Returns: VXGE_HW_OK - success. + * VXGE_HW_ERR_INVALID_HANDLE - Invalid handle + * + */ +enum vxge_hw_status +vxge_hw_vpath_mcast_disable(struct __vxge_hw_vpath_handle *vp) +{ + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; - if (!skip_alarms) { - writeq(VXGE_HW_INTR_MASK_ALL, - &vp_reg->prc_alarm_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, - alarm_event); - } - } + if ((vp == NULL) || (vp->vpath->ringh == NULL)) { + status = VXGE_HW_ERR_INVALID_HANDLE; + goto exit; } -out: - hldev->stats.sw_dev_err_stats.vpath_alarms++; -out2: - if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) || - (alarm_event == VXGE_HW_EVENT_UNKNOWN)) - return VXGE_HW_OK; - __vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event); + vpath = vp->vpath; - if (alarm_event == VXGE_HW_EVENT_SERR) - return VXGE_HW_ERR_CRITICAL; + val64 = readq(&vpath->vp_reg->rxmac_vcfg0); - return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ? - VXGE_HW_ERR_SLOT_FREEZE : - (alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO : - VXGE_HW_ERR_VPATH; + if (val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN) { + val64 &= ~VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN; + writeq(val64, &vpath->vp_reg->rxmac_vcfg0); + } +exit: + return status; } /* diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 1fceee876228..8c3103fb6442 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -2081,10 +2081,6 @@ struct __vxge_hw_ring_rxd_priv { #endif }; -/* ========================= FIFO PRIVATE API ============================= */ - -struct vxge_hw_fifo_attr; - struct vxge_hw_mempool_cbs { void (*item_func_alloc)( struct vxge_hw_mempool *mempoolh, @@ -2158,27 +2154,27 @@ enum vxge_hw_vpath_mac_addr_add_mode { enum vxge_hw_status vxge_hw_vpath_mac_addr_add( struct __vxge_hw_vpath_handle *vpath_handle, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN], + u8 *macaddr, + u8 *macaddr_mask, enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode); enum vxge_hw_status vxge_hw_vpath_mac_addr_get( struct __vxge_hw_vpath_handle *vpath_handle, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]); + u8 *macaddr, + u8 *macaddr_mask); enum vxge_hw_status vxge_hw_vpath_mac_addr_get_next( struct __vxge_hw_vpath_handle *vpath_handle, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]); + u8 *macaddr, + u8 *macaddr_mask); enum vxge_hw_status vxge_hw_vpath_mac_addr_delete( struct __vxge_hw_vpath_handle *vpath_handle, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]); + u8 *macaddr, + u8 *macaddr_mask); enum vxge_hw_status vxge_hw_vpath_vid_add( @@ -2285,6 +2281,7 @@ vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh); int vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel); + void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id); -- cgit v1.2.3-59-g8ed1b From c92bf70dcb9d08f821e4c9f09f8fc328495ba998 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:02:57 +0000 Subject: vxge: fix crash of VF when unloading PF Calling pci_disable_sriov when unloading a SR-IOV physical function driver from a host when a guest is using a virtual function from that device can cause a host crash or VM crash. The crash is caused by the virtual config space no longer being present when PF is removed (due to the pci_disable_sriov). This can be avoided by not calling pci_disable_sriov to disable the PCI space when shutting down the PF. Each function in the X3100 operates independently and in this case will operate properly in the absence of the PF. Also, added improved logic in the detection of SR-IOV initialization. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 70c327910f09..9c68c60f27d8 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -4182,6 +4182,20 @@ static int vxge_probe_fw_update(struct vxgedev *vdev) return ret; } +static int __devinit is_sriov_initialized(struct pci_dev *pdev) +{ + int pos; + u16 ctrl; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (pos) { + pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &ctrl); + if (ctrl & PCI_SRIOV_CTRL_VFE) + return 1; + } + return 0; +} + /** * vxge_probe * @pdev : structure containing the PCI related information of the device. @@ -4370,14 +4384,13 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) num_vfs = vxge_get_num_vfs(function_mode) - 1; /* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */ - if (is_sriov(function_mode) && (max_config_dev > 1) && - (ll_config->intr_type != INTA) && - (is_privileged == VXGE_HW_OK)) { - ret = pci_enable_sriov(pdev, ((max_config_dev - 1) < num_vfs) - ? (max_config_dev - 1) : num_vfs); + if (is_sriov(function_mode) && !is_sriov_initialized(pdev) && + (ll_config->intr_type != INTA)) { + ret = pci_enable_sriov(pdev, num_vfs); if (ret) vxge_debug_ll_config(VXGE_ERR, "Failed in enabling SRIOV mode: %d\n", ret); + /* No need to fail out, as an error here is non-fatal */ } /* @@ -4673,8 +4686,6 @@ static void __devexit vxge_remove(struct pci_dev *pdev) iounmap(vdev->bar0); - pci_disable_sriov(pdev); - /* we are safe to free it now */ free_netdev(dev); -- cgit v1.2.3-59-g8ed1b From dc66daa9be40369ead5a4ee33c6bcfb44cb3c8ee Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:02:58 +0000 Subject: vxge: use pci_request_region() Only BAR0 is ever accessed, thus making the calls to pci_request_regions overkill. Change calls of pci_request_regions to pci_request_region to reduce the size of the mapped area. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 9c68c60f27d8..faebffb02d12 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -4325,7 +4325,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit1; } - if (pci_request_regions(pdev, VXGE_DRIVER_NAME)) { + if (pci_request_region(pdev, 0, VXGE_DRIVER_NAME)) { vxge_debug_init(VXGE_ERR, "%s : request regions failed", __func__); ret = -ENODEV; @@ -4638,7 +4638,7 @@ _exit4: _exit3: iounmap(attr.bar0); _exit2: - pci_release_regions(pdev); + pci_release_region(pdev, 0); _exit1: pci_disable_device(pdev); _exit0: @@ -4695,7 +4695,7 @@ static void __devexit vxge_remove(struct pci_dev *pdev) vxge_hw_device_terminate(hldev); pci_disable_device(pdev); - pci_release_regions(pdev); + pci_release_region(pdev, 0); pci_set_drvdata(pdev, NULL); vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__, __LINE__); -- cgit v1.2.3-59-g8ed1b From 2e41f6449c561e6e3f572e11d0f2240bd51104db Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:02:59 +0000 Subject: vxge: transmit timeout deadlock Use a workqueue to handle the device reset during a transmit timeout, as there can be a deadlock during bringup. Also, set the netif carrier off before the watchdog reset is started to prevent the timeout from reoccurring while still processing the first. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 19 ++++++++++++++----- drivers/net/vxge/vxge-main.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index faebffb02d12..3ec80684cd5f 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -1606,12 +1606,16 @@ static int do_vxge_reset(struct vxgedev *vdev, int event) } if (event == VXGE_LL_FULL_RESET) { + netif_carrier_off(vdev->ndev); + /* wait for all the vpath reset to complete */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { while (test_bit(vp_id, &vdev->vp_reset)) msleep(50); } + netif_carrier_on(vdev->ndev); + /* if execution mode is set to debug, don't reset the adapter */ if (unlikely(vdev->exec_mode)) { vxge_debug_init(VXGE_ERR, @@ -1765,9 +1769,14 @@ out: * * driver may reset the chip on events of serr, eccerr, etc */ -static int vxge_reset(struct vxgedev *vdev) +static void vxge_reset(struct work_struct *work) { - return do_vxge_reset(vdev, VXGE_LL_FULL_RESET); + struct vxgedev *vdev = container_of(work, struct vxgedev, reset_task); + + if (!netif_running(vdev->ndev)) + return; + + do_vxge_reset(vdev, VXGE_LL_FULL_RESET); } /** @@ -3111,8 +3120,7 @@ static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) * This function is triggered if the Tx Queue is stopped * for a pre-defined amount of time when the Interface is still up. */ -static void -vxge_tx_watchdog(struct net_device *dev) +static void vxge_tx_watchdog(struct net_device *dev) { struct vxgedev *vdev; @@ -3122,7 +3130,7 @@ vxge_tx_watchdog(struct net_device *dev) vdev->cric_err_event = VXGE_HW_EVENT_RESET_START; - vxge_reset(vdev); + schedule_work(&vdev->reset_task); vxge_debug_entryexit(VXGE_TRACE, "%s:%d Exiting...", __func__, __LINE__); } @@ -3324,6 +3332,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, ndev->netdev_ops = &vxge_netdev_ops; ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT; + INIT_WORK(&vdev->reset_task, vxge_reset); vxge_initialize_ethtool_ops(ndev); diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 256d5b406a67..5746fedc356f 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -395,6 +395,7 @@ struct vxgedev { u32 level_err; u32 level_trace; char fw_version[VXGE_HW_FW_STRLEN]; + struct work_struct reset_task; }; struct vxge_rx_priv { -- cgit v1.2.3-59-g8ed1b From 9c1638871671721e8f3693a0dfbb0e2e05b08742 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:03:00 +0000 Subject: vxge: hotplug stall When hot-unplugging a vxge adapter while running, the driver's remove routine prints warning and then stalls the calling thread. This is due to vxge_remove calling vxge_device_unregister to unregister the netdev before calling flush_scheduled_work clear any pending work. Swapping the order of these two functions resolves the issue. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 3ec80684cd5f..b771e4b2ca9e 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3439,11 +3439,11 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) strncpy(buf, dev->name, IFNAMSIZ); + flush_scheduled_work(); + /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); - flush_scheduled_work(); - vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", buf); vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, -- cgit v1.2.3-59-g8ed1b From b55e7b153f698bb027102759388d0c09542f68bd Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:03:01 +0000 Subject: vxge: independent interrupt moderation Configure the workload clock register and TIM register for independent interrupt moderation based on the individual vpath utilization instead of common link utilization. This greatly improves latency. Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 1169aa387cab..01c05f53e2f9 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -4422,8 +4422,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL( - config->tti.util_sel); + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id); } if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { @@ -4527,8 +4526,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); - val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL( - config->rti.util_sel); + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id); } if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { @@ -4549,6 +4547,11 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]); writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]); + val64 = VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(150); + val64 |= VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(0); + val64 |= VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(3); + writeq(val64, &vp_reg->tim_wrkld_clc); + return status; } -- cgit v1.2.3-59-g8ed1b From 5d52040d4d1eabb56a4d51b760ab8f74eabb9001 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 14:03:02 +0000 Subject: vxge: update driver version Update vxge driver version to 2.5.1 Signed-off-by: Jon Mason Signed-off-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index 9c93e0a17175..ad2f99b9bcf3 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h @@ -15,9 +15,9 @@ #define VXGE_VERSION_H #define VXGE_VERSION_MAJOR "2" -#define VXGE_VERSION_MINOR "0" -#define VXGE_VERSION_FIX "11" -#define VXGE_VERSION_BUILD "21932" +#define VXGE_VERSION_MINOR "5" +#define VXGE_VERSION_FIX "1" +#define VXGE_VERSION_BUILD "22082" #define VXGE_VERSION_FOR "k" #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) -- cgit v1.2.3-59-g8ed1b From 36accaed22347f4b09cbc3c9fe2c1163a3575ea1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 10 Dec 2010 02:40:09 +0000 Subject: isdn: return -EFAULT if copy_from_user() fails We should be returning -EFAULT here. Mostly this patch is to silence a smatch warning. The upper levels of this driver turn all non-zero return values from isar_load_firmware() into 1. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/hisax/isar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 1be4552d94b4..c9cd4d22b4a5 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -212,9 +212,9 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO); #endif - if ((ret = copy_from_user(&size, p, sizeof(int)))) { + if (copy_from_user(&size, p, sizeof(int))) { printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret); - return ret; + return -EFAULT; } p += sizeof(int); printk(KERN_DEBUG"isar_load_firmware size: %d\n", size); -- cgit v1.2.3-59-g8ed1b From 6c2c9d964e71770e7d6efc1a82f3621005d12185 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 10 Dec 2010 12:02:33 +0000 Subject: enic: Move enic port profile handling code to a new 802.1Qbh provisioning info type Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 33 +++++++++++++++++++++++---------- drivers/net/enic/vnic_vic.h | 31 +++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 577067eef652..a937f49d9db7 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.9" +#define DRV_VERSION "1.4.1.10" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 21be989e6a14..9befd54ce6e1 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1252,7 +1252,10 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) { struct vic_provinfo *vp; u8 oui[3] = VIC_PROVINFO_CISCO_OUI; + u16 os_type = VIC_GENERIC_PROV_OS_TYPE_LINUX; char uuid_str[38]; + char client_mac_str[18]; + u8 *client_mac; int err; err = enic_vnic_dev_deinit(enic); @@ -1270,37 +1273,47 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) return -EADDRNOTAVAIL; vp = vic_provinfo_alloc(GFP_KERNEL, oui, - VIC_PROVINFO_LINUX_TYPE); + VIC_PROVINFO_GENERIC_TYPE); if (!vp) return -ENOMEM; vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, + VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR, strlen(enic->pp.name) + 1, enic->pp.name); if (!is_zero_ether_addr(enic->pp.mac_addr)) - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, - ETH_ALEN, enic->pp.mac_addr); + client_mac = enic->pp.mac_addr; else - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, - ETH_ALEN, mac); + client_mac = mac; + + vic_provinfo_add_tlv(vp, + VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, client_mac); + + sprintf(client_mac_str, "%pM", client_mac); + vic_provinfo_add_tlv(vp, + VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR, + sizeof(client_mac_str), client_mac_str); if (enic->pp.set & ENIC_SET_INSTANCE) { sprintf(uuid_str, "%pUB", enic->pp.instance_uuid); vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, + VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR, sizeof(uuid_str), uuid_str); } if (enic->pp.set & ENIC_SET_HOST) { sprintf(uuid_str, "%pUB", enic->pp.host_uuid); vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_HOST_UUID_STR, + VIC_GENERIC_PROV_TLV_HOST_UUID_STR, sizeof(uuid_str), uuid_str); } + os_type = htons(os_type); + vic_provinfo_add_tlv(vp, + VIC_GENERIC_PROV_TLV_OS_TYPE, + sizeof(os_type), &os_type); + err = enic_dev_init_prov(enic, vp); vic_provinfo_free(vp); if (err) diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h index 7e46e5e8600f..f700f5d9e81d 100644 --- a/drivers/net/enic/vnic_vic.h +++ b/drivers/net/enic/vnic_vic.h @@ -24,14 +24,29 @@ /* Note: String field lengths include null char */ #define VIC_PROVINFO_CISCO_OUI { 0x00, 0x00, 0x0c } -#define VIC_PROVINFO_LINUX_TYPE 0x2 - -enum vic_linux_prov_tlv_type { - VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR = 0, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR = 1, /* u8[6] */ - VIC_LINUX_PROV_TLV_CLIENT_NAME_STR = 2, - VIC_LINUX_PROV_TLV_HOST_UUID_STR = 8, - VIC_LINUX_PROV_TLV_CLIENT_UUID_STR = 9, +#define VIC_PROVINFO_GENERIC_TYPE 0x4 + +enum vic_generic_prov_tlv_type { + VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR = 0, + VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR = 1, + VIC_GENERIC_PROV_TLV_CLIENT_NAME_STR = 2, + VIC_GENERIC_PROV_TLV_CLUSTER_PORT_NAME_STR = 3, + VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR = 4, + VIC_GENERIC_PROV_TLV_CLUSTER_UUID_STR = 5, + VIC_GENERIC_PROV_TLV_CLUSTER_NAME_STR = 7, + VIC_GENERIC_PROV_TLV_HOST_UUID_STR = 8, + VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR = 9, + VIC_GENERIC_PROV_TLV_INCARNATION_NUMBER = 10, + VIC_GENERIC_PROV_TLV_OS_TYPE = 11, + VIC_GENERIC_PROV_TLV_OS_VENDOR = 12, + VIC_GENERIC_PROV_TLV_CLIENT_TYPE = 15, +}; + +enum vic_generic_prov_os_type { + VIC_GENERIC_PROV_OS_TYPE_UNKNOWN = 0, + VIC_GENERIC_PROV_OS_TYPE_ESX = 1, + VIC_GENERIC_PROV_OS_TYPE_LINUX = 2, + VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3, }; struct vic_provinfo { -- cgit v1.2.3-59-g8ed1b From f073c7ca29a4a7e14060d9d3ddf09bfbb7cd9cc0 Mon Sep 17 00:00:00 2001 From: Taku Izumi Date: Thu, 9 Dec 2010 15:17:13 +0000 Subject: bonding: add the debugfs facility to the bonding driver This patch provides the debugfs facility to the bonding driver. The "bonding" directory is created in the debugfs root and directories of each bonding interface (like bond0, bond1...) are created in that. # mount -t debugfs none /sys/kernel/debug # ls /sys/kernel/debug/bonding bond0 bond1 Signed-off-by: Taku Izumi Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/Makefile | 2 +- drivers/net/bonding/bond_debugfs.c | 96 ++++++++++++++++++++++++++++++++++++++ drivers/net/bonding/bond_main.c | 10 +++- drivers/net/bonding/bonding.h | 9 ++++ 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 drivers/net/bonding/bond_debugfs.c diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 6f9c6faef24c..0e2737eac8b7 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_BONDING) += bonding.o -bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o +bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o bonding-objs += $(ipv6-y) diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c new file mode 100644 index 000000000000..ae1eb2fc3a47 --- /dev/null +++ b/drivers/net/bonding/bond_debugfs.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +#include "bonding.h" + +#ifdef CONFIG_DEBUG_FS + +#include +#include + +static struct dentry *bonding_debug_root; + +void bond_debug_register(struct bonding *bond) +{ + if (!bonding_debug_root) + return; + + bond->debug_dir = + debugfs_create_dir(bond->dev->name, bonding_debug_root); + + if (!bond->debug_dir) { + pr_warning("%s: Warning: failed to register to debugfs\n", + bond->dev->name); + return; + } +} + +void bond_debug_unregister(struct bonding *bond) +{ + if (!bonding_debug_root) + return; + + debugfs_remove_recursive(bond->debug_dir); +} + +void bond_debug_reregister(struct bonding *bond) +{ + struct dentry *d; + + if (!bonding_debug_root) + return; + + d = debugfs_rename(bonding_debug_root, bond->debug_dir, + bonding_debug_root, bond->dev->name); + if (d) { + bond->debug_dir = d; + } else { + pr_warning("%s: Warning: failed to reregister, " + "so just unregister old one\n", + bond->dev->name); + bond_debug_unregister(bond); + } +} + +void bond_create_debugfs(void) +{ + bonding_debug_root = debugfs_create_dir("bonding", NULL); + + if (!bonding_debug_root) { + pr_warning("Warning: Cannot create bonding directory" + " in debugfs\n"); + } +} + +void bond_destroy_debugfs(void) +{ + debugfs_remove_recursive(bonding_debug_root); + bonding_debug_root = NULL; +} + + +#else /* !CONFIG_DEBUG_FS */ + +void bond_debug_register(struct bonding *bond) +{ +} + +void bond_debug_unregister(struct bonding *bond) +{ +} + +void bond_debug_reregister(struct bonding *bond) +{ +} + +void bond_create_debugfs(void) +{ +} + +void bond_destroy_debugfs(void) +{ +} + +#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bb33b3b347fa..07011e42cec7 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3503,6 +3503,8 @@ static int bond_event_changename(struct bonding *bond) bond_remove_proc_entry(bond); bond_create_proc_entry(bond); + bond_debug_reregister(bond); + return NOTIFY_DONE; } @@ -4785,6 +4787,8 @@ static void bond_uninit(struct net_device *bond_dev) bond_remove_proc_entry(bond); + bond_debug_unregister(bond); + __hw_addr_flush(&bond->mc_list); list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) { @@ -5187,6 +5191,8 @@ static int bond_init(struct net_device *bond_dev) bond_prepare_sysfs_group(bond); + bond_debug_register(bond); + __hw_addr_init(&bond->mc_list); return 0; } @@ -5308,6 +5314,8 @@ static int __init bonding_init(void) if (res) goto err_link; + bond_create_debugfs(); + for (i = 0; i < max_bonds; i++) { res = bond_create(&init_net, NULL); if (res) @@ -5318,7 +5326,6 @@ static int __init bonding_init(void) if (res) goto err; - register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); bond_register_ipv6_notifier(); @@ -5342,6 +5349,7 @@ static void __exit bonding_exit(void) bond_unregister_ipv6_notifier(); bond_destroy_sysfs(); + bond_destroy_debugfs(); rtnl_link_unregister(&bond_link_ops); unregister_pernet_subsys(&bond_net_ops); diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index ad3ae46a4c01..03710f8f5c49 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -259,6 +259,10 @@ struct bonding { #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr master_ipv6; #endif +#ifdef CONFIG_DEBUG_FS + /* debugging suport via debugfs */ + struct dentry *debug_dir; +#endif /* CONFIG_DEBUG_FS */ }; /** @@ -380,6 +384,11 @@ void bond_select_active_slave(struct bonding *bond); void bond_change_active_slave(struct bonding *bond, struct slave *new_active); void bond_register_arp(struct bonding *); void bond_unregister_arp(struct bonding *); +void bond_create_debugfs(void); +void bond_destroy_debugfs(void); +void bond_debug_register(struct bonding *bond); +void bond_debug_unregister(struct bonding *bond); +void bond_debug_reregister(struct bonding *bond); struct bond_net { struct net * net; /* Associated network namespace */ -- cgit v1.2.3-59-g8ed1b From a5d62a149bb8f5359aff7ed7dce339752fbabfd9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 10 Dec 2010 16:49:24 -0800 Subject: isdn: Fix printed out copy_from_user() return value after previous change. Signed-off-by: David S. Miller --- drivers/isdn/hisax/isar.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index c9cd4d22b4a5..d4cce337add2 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -189,7 +189,7 @@ ISARVersion(struct IsdnCardState *cs, char *s) static int isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) { - int ret, size, cnt, debug; + int cfu_ret, ret, size, cnt, debug; u_char len, nom, noc; u_short sadr, left, *sp; u_char __user *p = buf; @@ -212,8 +212,9 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO); #endif - if (copy_from_user(&size, p, sizeof(int))) { - printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret); + cfu_ret = copy_from_user(&size, p, sizeof(int)); + if (cfu_ret) { + printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", cfu_ret); return -EFAULT; } p += sizeof(int); -- cgit v1.2.3-59-g8ed1b From 96c3c0330dea8856f02fc59e25c866d6d5eebed5 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 9 Dec 2010 23:42:00 -0800 Subject: Documentation/networking/e1000.txt: Update documentation Update Intel Wired LAN e1000 documentation. Signed-off-by: Jeff Kirsher --- Documentation/networking/e1000.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt index d9271e74e488..6cb13e9e1346 100644 --- a/Documentation/networking/e1000.txt +++ b/Documentation/networking/e1000.txt @@ -79,7 +79,7 @@ InterruptThrottleRate --------------------- (not supported on Intel(R) 82542, 82543 or 82544-based adapters) Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative, - 4=simplified balancing) + 4=simplified balancing) Default Value: 3 The driver can limit the amount of interrupts per second that the adapter @@ -124,8 +124,8 @@ InterruptThrottleRate is set to mode 1. In this mode, which operates the same as mode 3, the InterruptThrottleRate will be increased stepwise to 70000 for traffic in class "Lowest latency". -In simplified mode the interrupt rate is based on the ratio of Tx and -Rx traffic. If the bytes per second rate is approximately equal, the +In simplified mode the interrupt rate is based on the ratio of TX and +RX traffic. If the bytes per second rate is approximately equal, the interrupt rate will drop as low as 2000 interrupts per second. If the traffic is mostly transmit or mostly receive, the interrupt rate could be as high as 8000. @@ -245,7 +245,7 @@ NOTE: Depending on the available system resources, the request for a TxDescriptorStep ---------------- Valid Range: 1 (use every Tx Descriptor) - 4 (use every 4th Tx Descriptor) + 4 (use every 4th Tx Descriptor) Default Value: 1 (use every Tx Descriptor) @@ -312,7 +312,7 @@ Valid Range: 0-xxxxxxx (0=off) Default Value: 256 Usage: insmod e1000.ko copybreak=128 -Driver copies all packets below or equaling this size to a fresh Rx +Driver copies all packets below or equaling this size to a fresh RX buffer before handing it up the stack. This parameter is different than other parameters, in that it is a -- cgit v1.2.3-59-g8ed1b From 072ed34fa97374b390a2493fa281ec8a7888b312 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 9 Dec 2010 23:44:42 -0800 Subject: Documentation/networking/e1000e.txt: Update documentation Update Intel Wired LAN e1000e documentation. Signed-off-by: Jeff Kirsher --- Documentation/networking/e1000e.txt | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt index 6aa048badf32..81a66e69a127 100644 --- a/Documentation/networking/e1000e.txt +++ b/Documentation/networking/e1000e.txt @@ -1,5 +1,5 @@ Linux* Driver for Intel(R) Network Connection -=============================================================== +============================================= Intel Gigabit Linux driver. Copyright(c) 1999 - 2010 Intel Corporation. @@ -61,6 +61,12 @@ per second, even if more packets have come in. This reduces interrupt load on the system and can lower CPU utilization under heavy load, but will increase latency as packets are not processed as quickly. +The default behaviour of the driver previously assumed a static +InterruptThrottleRate value of 8000, providing a good fallback value for +all traffic types, but lacking in small packet performance and latency. +The hardware can handle many more small packets per second however, and +for this reason an adaptive interrupt moderation algorithm was implemented. + The driver has two adaptive modes (setting 1 or 3) in which it dynamically adjusts the InterruptThrottleRate value based on the traffic that it receives. After determining the type of incoming traffic in the last @@ -86,8 +92,8 @@ InterruptThrottleRate is set to mode 1. In this mode, which operates the same as mode 3, the InterruptThrottleRate will be increased stepwise to 70000 for traffic in class "Lowest latency". -In simplified mode the interrupt rate is based on the ratio of Tx and -Rx traffic. If the bytes per second rate is approximately equal the +In simplified mode the interrupt rate is based on the ratio of TX and +RX traffic. If the bytes per second rate is approximately equal, the interrupt rate will drop as low as 2000 interrupts per second. If the traffic is mostly transmit or mostly receive, the interrupt rate could be as high as 8000. @@ -177,7 +183,7 @@ Copybreak Valid Range: 0-xxxxxxx (0=off) Default Value: 256 -Driver copies all packets below or equaling this size to a fresh Rx +Driver copies all packets below or equaling this size to a fresh RX buffer before handing it up the stack. This parameter is different than other parameters, in that it is a @@ -223,17 +229,17 @@ loading or enabling the driver, try disabling this feature. WriteProtectNVM --------------- -Valid Range: 0-1 -Default Value: 1 (enabled) - -Set the hardware to ignore all write/erase cycles to the GbE region in the -ICHx NVM (non-volatile memory). This feature can be disabled by the -WriteProtectNVM module parameter (enabled by default) only after a hardware -reset, but the machine must be power cycled before trying to enable writes. - -Note: the kernel boot option iomem=relaxed may need to be set if the kernel -config option CONFIG_STRICT_DEVMEM=y, if the root user wants to write the -NVM from user space via ethtool. +Valid Range: 0,1 +Default Value: 1 + +If set to 1, configure the hardware to ignore all write/erase cycles to the +GbE region in the ICHx NVM (in order to prevent accidental corruption of the +NVM). This feature can be disabled by setting the parameter to 0 during initial +driver load. +NOTE: The machine must be power cycled (full off/on) when enabling NVM writes +via setting the parameter to zero. Once the NVM has been locked (via the +parameter at 1 when the driver loads) it cannot be unlocked except via power +cycle. Additional Configurations ========================= @@ -259,7 +265,6 @@ Additional Configurations - Some adapters limit Jumbo Frames sized packets to a maximum of 4096 bytes and some adapters do not support Jumbo Frames. - Ethtool ------- The driver utilizes the ethtool interface for driver configuration and @@ -283,8 +288,7 @@ Additional Configurations loaded when shutting down or rebooting the system. In most cases Wake On LAN is only supported on port A for multiple port - adapters. To verify if a port supports Wake on LAN run ethtool eth. - + adapters. To verify if a port supports Wake on Lan run Ethtool eth. Support ======= -- cgit v1.2.3-59-g8ed1b From 1ffd7246445038569f4c2f4b39bda1e71e68f1a2 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 9 Dec 2010 23:47:39 -0800 Subject: Documentation/networking/igb.txt: update documentation Update Intel Wired LAN igb documentation. v2- Updated the ethtool support link, removed the LRO section and anti-spoofing sections. Signed-off-by: Jeff Kirsher --- Documentation/networking/igb.txt | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt index ab2d71831892..4a5e29c19bd1 100644 --- a/Documentation/networking/igb.txt +++ b/Documentation/networking/igb.txt @@ -36,6 +36,7 @@ Default Value: 0 This parameter adds support for SR-IOV. It causes the driver to spawn up to max_vfs worth of virtual function. + Additional Configurations ========================= @@ -60,9 +61,10 @@ Additional Configurations Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. + diagnostics, as well as displaying statistical information. The latest + version of Ethtool can be found at: - http://sourceforge.net/projects/gkernel. + http://ftp.kernel.org/pub/software/network/ethtool/ Enabling Wake on LAN* (WoL) --------------------------- @@ -91,31 +93,6 @@ Additional Configurations REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not found, the system will fallback to MSI or to Legacy interrupts. - LRO - --- - Large Receive Offload (LRO) is a technique for increasing inbound throughput - of high-bandwidth network connections by reducing CPU overhead. It works by - aggregating multiple incoming packets from a single stream into a larger - buffer before they are passed higher up the networking stack, thus reducing - the number of packets that have to be processed. LRO combines multiple - Ethernet frames into a single receive in the stack, thereby potentially - decreasing CPU utilization for receives. - - NOTE: You need to have inet_lro enabled via either the CONFIG_INET_LRO or - CONFIG_INET_LRO_MODULE kernel config option. Additionally, if - CONFIG_INET_LRO_MODULE is used, the inet_lro module needs to be loaded - before the igb driver. - - You can verify that the driver is using LRO by looking at these counters in - Ethtool: - - lro_aggregated - count of total packets that were combined - lro_flushed - counts the number of packets flushed out of LRO - lro_no_desc - counts the number of times an LRO descriptor was not available - for the LRO packet - - NOTE: IPv6 and UDP are not supported by LRO. - Support ======= -- cgit v1.2.3-59-g8ed1b From f2be1429798785c6b7d4747ac1fda2c40b3f26eb Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 9 Dec 2010 23:49:34 -0800 Subject: Documentation/networking/igbvf.txt: Update documentation Update Intel Wired LAN igbvf documentation. Signed-off-by: Jeff Kirsher --- Documentation/networking/igbvf.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/igbvf.txt b/Documentation/networking/igbvf.txt index 056028138d9c..694817b17a9c 100644 --- a/Documentation/networking/igbvf.txt +++ b/Documentation/networking/igbvf.txt @@ -58,7 +58,9 @@ Additional Configurations Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. + diagnostics, as well as displaying statistical information. Ethtool + version 3.0 or later is required for this functionality, although we + strongly recommend downloading the latest version at: http://sourceforge.net/projects/gkernel. -- cgit v1.2.3-59-g8ed1b From 872857a84e18f4bf9b56b298309a977b2ce77b5b Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 9 Dec 2010 23:55:47 -0800 Subject: Documentation/networking/ixgbe.txt: Update ixgbe documentation Update Intel Wired LAN ixgbe documentation. Signed-off-by: Jeff Kirsher --- Documentation/networking/ixgbe.txt | 211 ++++++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 75 deletions(-) diff --git a/Documentation/networking/ixgbe.txt b/Documentation/networking/ixgbe.txt index eeb68685c788..9ade2806d82c 100644 --- a/Documentation/networking/ixgbe.txt +++ b/Documentation/networking/ixgbe.txt @@ -1,107 +1,126 @@ Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection ======================================================================== -March 10, 2009 - +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. Contents ======== -- In This Release - Identifying Your Adapter -- Building and Installation - Additional Configurations +- Performance Tuning +- Known Issues - Support +Identifying Your Adapter +======================== +The driver in this release is compatible with 82598 and 82599-based Intel +Network Connections. -In This Release -=============== +For more information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: -This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI -Express Intel(R) Network Connection. This driver includes support for -Itanium(R)2-based systems. + http://support.intel.com/support/network/sb/CS-012904.htm -For questions related to hardware requirements, refer to the documentation -supplied with your 10 Gigabit adapter. All hardware requirements listed apply -to use with Linux. +SFP+ Devices with Pluggable Optics +---------------------------------- -The following features are available in this kernel: - - Native VLANs - - Channel Bonding (teaming) - - SNMP - - Generic Receive Offload - - Data Center Bridging +82599-BASED ADAPTERS -Channel Bonding documentation can be found in the Linux kernel source: -/Documentation/networking/bonding.txt +NOTES: If your 82599-based Intel(R) Network Adapter came with Intel optics, or +is an Intel(R) Ethernet Server Adapter X520-2, then it only supports Intel +optics and/or the direct attach cables listed below. -Ethtool, lspci, and ifconfig can be used to display device and driver -specific information. +When 82599-based SFP+ devices are connected back to back, they should be set to +the same Speed setting via Ethtool. Results may vary if you mix speed settings. +82598-based adapters support all passive direct attach cables that comply +with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach +cables are not supported. +Supplier Type Part Numbers -Identifying Your Adapter -======================== +SR Modules +Intel DUAL RATE 1G/10G SFP+ SR (bailed) FTLX8571D3BCV-IT +Intel DUAL RATE 1G/10G SFP+ SR (bailed) AFBR-703SDDZ-IN1 +Intel DUAL RATE 1G/10G SFP+ SR (bailed) AFBR-703SDZ-IN2 +LR Modules +Intel DUAL RATE 1G/10G SFP+ LR (bailed) FTLX1471D3BCV-IT +Intel DUAL RATE 1G/10G SFP+ LR (bailed) AFCT-701SDDZ-IN1 +Intel DUAL RATE 1G/10G SFP+ LR (bailed) AFCT-701SDZ-IN2 -This driver supports devices based on the 82598 controller and the 82599 -controller. +The following is a list of 3rd party SFP+ modules and direct attach cables that +have received some testing. Not all modules are applicable to all devices. -For specific information on identifying which adapter you have, please visit: +Supplier Type Part Numbers - http://support.intel.com/support/network/sb/CS-008441.htm +Finisar SFP+ SR bailed, 10g single rate FTLX8571D3BCL +Avago SFP+ SR bailed, 10g single rate AFBR-700SDZ +Finisar SFP+ LR bailed, 10g single rate FTLX1471D3BCL +Finisar DUAL RATE 1G/10G SFP+ SR (No Bail) FTLX8571D3QCV-IT +Avago DUAL RATE 1G/10G SFP+ SR (No Bail) AFBR-703SDZ-IN1 +Finisar DUAL RATE 1G/10G SFP+ LR (No Bail) FTLX1471D3QCV-IT +Avago DUAL RATE 1G/10G SFP+ LR (No Bail) AFCT-701SDZ-IN1 +Finistar 1000BASE-T SFP FCLF8522P2BTL +Avago 1000BASE-T SFP ABCU-5710RZ -Building and Installation -========================= +82599-based adapters support all passive and active limiting direct attach +cables that comply with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. -select m for "Intel(R) 10GbE PCI Express adapters support" located at: - Location: - -> Device Drivers - -> Network device support (NETDEVICES [=y]) - -> Ethernet (10000 Mbit) (NETDEV_10000 [=y]) +Laser turns off for SFP+ when ifconfig down +------------------------------------------- +"ifconfig down" turns off the laser for 82599-based SFP+ fiber adapters. +"ifconfig up" turns on the later. -1. make modules & make modules_install -2. Load the module: +82598-BASED ADAPTERS -# modprobe ixgbe +NOTES for 82598-Based Adapters: +- Intel(R) Network Adapters that support removable optical modules only support + their original module type (i.e., the Intel(R) 10 Gigabit SR Dual Port + Express Module only supports SR optical modules). If you plug in a different + type of module, the driver will not load. +- Hot Swapping/hot plugging optical modules is not supported. +- Only single speed, 10 gigabit modules are supported. +- LAN on Motherboard (LOMs) may support DA, SR, or LR modules. Other module + types are not supported. Please see your system documentation for details. - The insmod command can be used if the full - path to the driver module is specified. For example: +The following is a list of 3rd party SFP+ modules and direct attach cables that +have received some testing. Not all modules are applicable to all devices. - insmod /lib/modules//kernel/drivers/net/ixgbe/ixgbe.ko +Supplier Type Part Numbers - With 2.6 based kernels also make sure that older ixgbe drivers are - removed from the kernel, before loading the new module: +Finisar SFP+ SR bailed, 10g single rate FTLX8571D3BCL +Avago SFP+ SR bailed, 10g single rate AFBR-700SDZ +Finisar SFP+ LR bailed, 10g single rate FTLX1471D3BCL - rmmod ixgbe; modprobe ixgbe +82598-based adapters support all passive direct attach cables that comply +with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach +cables are not supported. -3. Assign an IP address to the interface by entering the following, where - x is the interface number: - ifconfig ethx +Flow Control +------------ +Ethernet Flow Control (IEEE 802.3x) can be configured with ethtool to enable +receiving and transmitting pause frames for ixgbe. When TX is enabled, PAUSE +frames are generated when the receive packet buffer crosses a predefined +threshold. When rx is enabled, the transmit unit will halt for the time delay +specified when a PAUSE frame is received. -4. Verify that the interface works. Enter the following, where - is the IP address for another machine on the same subnet as the interface - that is being tested: +Flow Control is enabled by default. If you want to disable a flow control +capable link partner, use Ethtool: - ping + ethtool -A eth? autoneg off RX off TX off +NOTE: For 82598 backplane cards entering 1 gig mode, flow control default +behavior is changed to off. Flow control in 1 gig mode on these devices can +lead to Tx hangs. Additional Configurations ========================= - Viewing Link Messages - --------------------- - Link messages will not be displayed to the console if the distribution is - restricting system messages. In order to see network driver link messages on - your console, set dmesg to eight by entering the following: - - dmesg -n 8 - - NOTE: This setting is not saved across reboots. - - Jumbo Frames ------------ The driver supports Jumbo Frames for all adapters. Jumbo Frames support is @@ -123,13 +142,8 @@ Additional Configurations other protocols besides TCP. It's also safe to use with configurations that are problematic for LRO, namely bridging and iSCSI. - GRO is enabled by default in the driver. Future versions of ethtool will - support disabling and re-enabling GRO on the fly. - - Data Center Bridging, aka DCB ----------------------------- - DCB is a configuration Quality of Service implementation in hardware. It uses the VLAN priority tag (802.1p) to filter traffic. That means that there are 8 different priorities that traffic can be filtered into. @@ -163,24 +177,71 @@ Additional Configurations http://e1000.sf.net - Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. Ethtool - version 3.0 or later is required for this functionality. + diagnostics, as well as displaying statistical information. The latest + Ethtool version is required for this functionality. The latest release of ethtool can be found from http://sourceforge.net/projects/gkernel. - - NAPI + FCoE ---- + This release of the ixgbe driver contains new code to enable users to use + Fiber Channel over Ethernet (FCoE) and Data Center Bridging (DCB) + functionality that is supported by the 82598-based hardware. This code has + no default effect on the regular driver operation, and configuring DCB and + FCoE is outside the scope of this driver README. Refer to + http://www.open-fcoe.org/ for FCoE project information and contact + e1000-eedc@lists.sourceforge.net for DCB information. + + MAC and VLAN anti-spoofing feature + ---------------------------------- + When a malicious driver attempts to send a spoofed packet, it is dropped by + the hardware and not transmitted. An interrupt is sent to the PF driver + notifying it of the spoof attempt. + + When a spoofed packet is detected the PF driver will send the following + message to the system log (displayed by the "dmesg" command): + + Spoof event(s) detected on VF (n) + + Where n=the VF that attempted to do the spoofing. + + +Performance Tuning +================== + +An excellent article on performance tuning can be found at: + +http://www.redhat.com/promo/summit/2008/downloads/pdf/Thursday/Mark_Wagner.pdf + + +Known Issues +============ + + Enabling SR-IOV in a 32-bit Microsoft* Windows* Server 2008 Guest OS using + Intel (R) 82576-based GbE or Intel (R) 82599-based 10GbE controller under KVM + ----------------------------------------------------------------------------- + KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This + includes traditional PCIe devices, as well as SR-IOV-capable devices using + Intel 82576-based and 82599-based controllers. + + While direct assignment of a PCIe device or an SR-IOV Virtual Function (VF) + to a Linux-based VM running 2.6.32 or later kernel works fine, there is a + known issue with Microsoft Windows Server 2008 VM that results in a "yellow + bang" error. This problem is within the KVM VMM itself, not the Intel driver, + or the SR-IOV logic of the VMM, but rather that KVM emulates an older CPU + model for the guests, and this older CPU model does not support MSI-X + interrupts, which is a requirement for Intel SR-IOV. - NAPI (Rx polling mode) is supported in the ixgbe driver. NAPI is enabled - by default in the driver. + If you wish to use the Intel 82576 or 82599-based controllers in SR-IOV mode + with KVM and a Microsoft Windows Server 2008 guest try the following + workaround. The workaround is to tell KVM to emulate a different model of CPU + when using qemu to create the KVM guest: - See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI. + "-cpu qemu64,model=13" Support -- cgit v1.2.3-59-g8ed1b From dabee56860bc6b617c7ea481bb9b00fba41c9c48 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 10 Dec 2010 00:01:44 -0800 Subject: Documentation/networking/ixgbevf.txt: Update documentation Update Intel Wired LAN ixgbevf documentation. Signed-off-by: Jeff Kirsher --- Documentation/networking/ixgbevf.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/networking/ixgbevf.txt b/Documentation/networking/ixgbevf.txt index 21dd5d15b6b4..5a91a41fa946 100644 --- a/Documentation/networking/ixgbevf.txt +++ b/Documentation/networking/ixgbevf.txt @@ -35,10 +35,6 @@ Driver ID Guide at: Known Issues/Troubleshooting ============================ - Unloading Physical Function (PF) Driver Causes System Reboots When VM is - Running and VF is Loaded on the VM - ------------------------------------------------------------------------ - Do not unload the PF driver (ixgbe) while VFs are assigned to guests. Support ======= -- cgit v1.2.3-59-g8ed1b From fa795e6b9c59a14c80a475428df7e4cb97396f47 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 10 Dec 2010 00:09:08 -0800 Subject: MAINTAINERS: Update Intel Wired LAN info Update with Intel Wired Ethernet public git trees. Signed-off-by: Jeff Kirsher --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9206cb462913..4a77d0d300a5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3115,6 +3115,8 @@ M: Alex Duyck M: John Ronciak L: e1000-devel@lists.sourceforge.net W: http://e1000.sourceforge.net/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next-2.6.git S: Supported F: Documentation/networking/e100.txt F: Documentation/networking/e1000.txt -- cgit v1.2.3-59-g8ed1b From 19a0b67afd174c4db261d587b5c67704dcd53c17 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Thu, 11 Nov 2010 05:50:25 +0000 Subject: e1000: fix return value not set on error Dean noticed that 'err' wasn't being set when the "goto err_dma" statement is executed in the following hunk from the commit. It's value will be zero as a result of a successful call to e1000_init_hw_struct(). This patch changes the error condition to be correctly propagated. CC: stable@kernel.org Signed-off-by: Dean Nelson Signed-off-by: Jesse Brandeburg Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000/e1000_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 06c7d1c67517..491bf2a1babd 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -971,11 +971,13 @@ static int __devinit e1000_probe(struct pci_dev *pdev, */ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); pci_using_dac = 1; - } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); } else { - pr_err("No usable DMA config, aborting\n"); - goto err_dma; + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (err) { + pr_err("No usable DMA config, aborting\n"); + goto err_dma; + } + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); } netdev->netdev_ops = &e1000_netdev_ops; -- cgit v1.2.3-59-g8ed1b From 667445008db3f45a760c235d771be0c9671e59e5 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Wed, 1 Dec 2010 19:59:50 +0000 Subject: Intel Wired LAN drivers: Use static const Based on work by Joe Perches Using static const to decrease data and overall object size. CC: Joe Perches Signed-off-by: Jeff Kirsher Tested-by: Emil Tantilov --- drivers/net/e1000/e1000_hw.c | 20 ++++++++++---------- drivers/net/e1000/e1000_param.c | 13 +++++++------ drivers/net/e1000e/phy.c | 11 ++++++----- drivers/net/igb/e1000_phy.c | 11 ++++++----- drivers/net/ixgb/ixgb_param.c | 21 +++++++++++---------- drivers/net/ixgbe/ixgbe_ethtool.c | 24 ++++++++++++++---------- drivers/net/ixgbevf/ethtool.c | 18 +++++++++++------- 7 files changed, 65 insertions(+), 53 deletions(-) diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index c7e242b69a18..77d08e697b74 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -4892,11 +4892,11 @@ static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length, } else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */ u16 cur_agc_value; u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE; - u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = - { IGP01E1000_PHY_AGC_A, - IGP01E1000_PHY_AGC_B, - IGP01E1000_PHY_AGC_C, - IGP01E1000_PHY_AGC_D + static const u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = { + IGP01E1000_PHY_AGC_A, + IGP01E1000_PHY_AGC_B, + IGP01E1000_PHY_AGC_C, + IGP01E1000_PHY_AGC_D }; /* Read the AGC registers for all channels */ for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { @@ -5071,11 +5071,11 @@ static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up) { s32 ret_val; u16 phy_data, phy_saved_data, speed, duplex, i; - u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = - { IGP01E1000_PHY_AGC_PARAM_A, - IGP01E1000_PHY_AGC_PARAM_B, - IGP01E1000_PHY_AGC_PARAM_C, - IGP01E1000_PHY_AGC_PARAM_D + static const u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = { + IGP01E1000_PHY_AGC_PARAM_A, + IGP01E1000_PHY_AGC_PARAM_B, + IGP01E1000_PHY_AGC_PARAM_C, + IGP01E1000_PHY_AGC_PARAM_D }; u16 min_length, max_length; diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index 10d8d98bb797..1301eba8b57a 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -352,12 +352,13 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter) } { /* Flow Control */ - struct e1000_opt_list fc_list[] = - {{ E1000_FC_NONE, "Flow Control Disabled" }, - { E1000_FC_RX_PAUSE,"Flow Control Receive Only" }, - { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" }, - { E1000_FC_FULL, "Flow Control Enabled" }, - { E1000_FC_DEFAULT, "Flow Control Hardware Default" }}; + static const struct e1000_opt_list fc_list[] = { + { E1000_FC_NONE, "Flow Control Disabled" }, + { E1000_FC_RX_PAUSE, "Flow Control Receive Only" }, + { E1000_FC_TX_PAUSE, "Flow Control Transmit Only" }, + { E1000_FC_FULL, "Flow Control Enabled" }, + { E1000_FC_DEFAULT, "Flow Control Hardware Default" } + }; opt = (struct e1000_option) { .type = list_option, diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 3d3dc0c82355..6ad90ccb4bab 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -1840,11 +1840,12 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) u16 phy_data, i, agc_value = 0; u16 cur_agc_index, max_agc_index = 0; u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; - u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = - {IGP02E1000_PHY_AGC_A, - IGP02E1000_PHY_AGC_B, - IGP02E1000_PHY_AGC_C, - IGP02E1000_PHY_AGC_D}; + static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = { + IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D + }; /* Read the AGC registers for all channels */ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index ddd036a78999..6694bf3e5ad9 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -1757,11 +1757,12 @@ s32 igb_get_cable_length_igp_2(struct e1000_hw *hw) u16 phy_data, i, agc_value = 0; u16 cur_agc_index, max_agc_index = 0; u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; - u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = - {IGP02E1000_PHY_AGC_A, - IGP02E1000_PHY_AGC_B, - IGP02E1000_PHY_AGC_C, - IGP02E1000_PHY_AGC_D}; + static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = { + IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D + }; /* Read the AGC registers for all channels */ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c index 88a08f056241..dd7fbeb1f7d1 100644 --- a/drivers/net/ixgb/ixgb_param.c +++ b/drivers/net/ixgb/ixgb_param.c @@ -191,9 +191,9 @@ struct ixgb_option { } r; struct { /* list_option info */ int nr; - struct ixgb_opt_list { + const struct ixgb_opt_list { int i; - char *str; + const char *str; } *p; } l; } arg; @@ -226,7 +226,7 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) break; case list_option: { int i; - struct ixgb_opt_list *ent; + const struct ixgb_opt_list *ent; for (i = 0; i < opt->arg.l.nr; i++) { ent = &opt->arg.l.p[i]; @@ -322,14 +322,15 @@ ixgb_check_options(struct ixgb_adapter *adapter) } { /* Flow Control */ - struct ixgb_opt_list fc_list[] = - {{ ixgb_fc_none, "Flow Control Disabled" }, - { ixgb_fc_rx_pause,"Flow Control Receive Only" }, - { ixgb_fc_tx_pause,"Flow Control Transmit Only" }, - { ixgb_fc_full, "Flow Control Enabled" }, - { ixgb_fc_default, "Flow Control Hardware Default" }}; + static const struct ixgb_opt_list fc_list[] = { + { ixgb_fc_none, "Flow Control Disabled" }, + { ixgb_fc_rx_pause, "Flow Control Receive Only" }, + { ixgb_fc_tx_pause, "Flow Control Transmit Only" }, + { ixgb_fc_full, "Flow Control Enabled" }, + { ixgb_fc_default, "Flow Control Hardware Default" } + }; - const struct ixgb_option opt = { + static const struct ixgb_option opt = { .type = list_option, .name = "Flow Control", .err = "reading default settings from EEPROM", diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index ef3f9105a05d..90a740d77e5d 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1157,7 +1157,7 @@ struct ixgbe_reg_test { #define TABLE64_TEST_HI 6 /* default 82599 register test */ -static struct ixgbe_reg_test reg_test_82599[] = { +static const struct ixgbe_reg_test reg_test_82599[] = { { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1181,7 +1181,7 @@ static struct ixgbe_reg_test reg_test_82599[] = { }; /* default 82598 register test */ -static struct ixgbe_reg_test reg_test_82598[] = { +static const struct ixgbe_reg_test reg_test_82598[] = { { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1208,18 +1208,22 @@ static struct ixgbe_reg_test reg_test_82598[] = { { 0, 0, 0, 0 } }; +static const u32 register_test_patterns[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF +}; + #define REG_PATTERN_TEST(R, M, W) \ { \ u32 pat, val, before; \ - const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \ + for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \ before = readl(adapter->hw.hw_addr + R); \ - writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \ + writel((register_test_patterns[pat] & W), \ + (adapter->hw.hw_addr + R)); \ val = readl(adapter->hw.hw_addr + R); \ - if (val != (_test[pat] & W & M)) { \ - e_err(drv, "pattern test reg %04X failed: got " \ - "0x%08X expected 0x%08X\n", \ - R, val, (_test[pat] & W & M)); \ + if (val != (register_test_patterns[pat] & W & M)) { \ + e_err(drv, "pattern test reg %04X failed: got " \ + "0x%08X expected 0x%08X\n", \ + R, val, (register_test_patterns[pat] & W & M)); \ *data = R; \ writel(before, adapter->hw.hw_addr + R); \ return 1; \ @@ -1246,7 +1250,7 @@ static struct ixgbe_reg_test reg_test_82598[] = { static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) { - struct ixgbe_reg_test *test; + const struct ixgbe_reg_test *test; u32 value, before, after; u32 i, toggle; diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 4cc817acfb62..fa29b3c8c464 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -544,7 +544,7 @@ struct ixgbevf_reg_test { #define TABLE64_TEST_HI 6 /* default VF register test */ -static struct ixgbevf_reg_test reg_test_vf[] = { +static const struct ixgbevf_reg_test reg_test_vf[] = { { IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, { IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, { IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, @@ -557,19 +557,23 @@ static struct ixgbevf_reg_test reg_test_vf[] = { { 0, 0, 0, 0 } }; +static const u32 register_test_patterns[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF +}; + #define REG_PATTERN_TEST(R, M, W) \ { \ u32 pat, val, before; \ - const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \ + for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \ before = readl(adapter->hw.hw_addr + R); \ - writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \ + writel((register_test_patterns[pat] & W), \ + (adapter->hw.hw_addr + R)); \ val = readl(adapter->hw.hw_addr + R); \ - if (val != (_test[pat] & W & M)) { \ + if (val != (register_test_patterns[pat] & W & M)) { \ hw_dbg(&adapter->hw, \ "pattern test reg %04X failed: got " \ "0x%08X expected 0x%08X\n", \ - R, val, (_test[pat] & W & M)); \ + R, val, (register_test_patterns[pat] & W & M)); \ *data = R; \ writel(before, adapter->hw.hw_addr + R); \ return 1; \ @@ -596,7 +600,7 @@ static struct ixgbevf_reg_test reg_test_vf[] = { static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) { - struct ixgbevf_reg_test *test; + const struct ixgbevf_reg_test *test; u32 i; test = reg_test_vf; -- cgit v1.2.3-59-g8ed1b From ae54496f9e8d40c89e5668205c181dccfa9ecda1 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 4 Dec 2010 05:35:17 +0000 Subject: ixgb: Don't check for vlan group on transmit Based on a patch from Jesse Gross. Enable vlan tag insertion even when vlan group is not configured. For ixgb HW both CTRL0.VME and VLE bit in the Tx descriptor need to be set in order to enable HW acceleration. Introduced separate functions for enabling/disabling of vlan tag stripping similar to ixgbe. CC: Jesse Gross Signed-off-by: Emil Tantilov Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ixgb/ixgb_main.c | 51 ++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 211a1694667e..2e98506d12e3 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -98,6 +98,8 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int); static void ixgb_tx_timeout(struct net_device *dev); static void ixgb_tx_timeout_task(struct work_struct *work); +static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); +static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); static void ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid); @@ -1076,6 +1078,8 @@ ixgb_set_multi(struct net_device *netdev) if (netdev->flags & IFF_PROMISC) { rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE); + /* disable VLAN filtering */ + rctl &= ~IXGB_RCTL_CFIEN; rctl &= ~IXGB_RCTL_VFE; } else { if (netdev->flags & IFF_ALLMULTI) { @@ -1084,7 +1088,9 @@ ixgb_set_multi(struct net_device *netdev) } else { rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE); } + /* enable VLAN filtering */ rctl |= IXGB_RCTL_VFE; + rctl &= ~IXGB_RCTL_CFIEN; } if (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES) { @@ -1103,6 +1109,12 @@ ixgb_set_multi(struct net_device *netdev) ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0); } + + if (netdev->features & NETIF_F_HW_VLAN_RX) + ixgb_vlan_strip_enable(adapter); + else + ixgb_vlan_strip_disable(adapter); + } /** @@ -2150,33 +2162,30 @@ static void ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { struct ixgb_adapter *adapter = netdev_priv(netdev); - u32 ctrl, rctl; - ixgb_irq_disable(adapter); adapter->vlgrp = grp; +} - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); - ctrl |= IXGB_CTRL0_VME; - IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); - - /* enable VLAN receive filtering */ +static void +ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) +{ + u32 ctrl; - rctl = IXGB_READ_REG(&adapter->hw, RCTL); - rctl &= ~IXGB_RCTL_CFIEN; - IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); - } else { - /* disable VLAN tag insert/strip */ + /* enable VLAN tag insert/strip */ + ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); + ctrl |= IXGB_CTRL0_VME; + IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); +} - ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); - ctrl &= ~IXGB_CTRL0_VME; - IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); - } +static void +ixgb_vlan_strip_disable(struct ixgb_adapter *adapter) +{ + u32 ctrl; - /* don't enable interrupts unless we are UP */ - if (adapter->netdev->flags & IFF_UP) - ixgb_irq_enable(adapter); + /* disable VLAN tag insert/strip */ + ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); + ctrl &= ~IXGB_CTRL0_VME; + IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); } static void -- cgit v1.2.3-59-g8ed1b From 2b264909c660717a67da997a181a4a4f551ef9b6 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 9 Dec 2010 06:55:14 +0000 Subject: ixgbe: fix X540 phy id to correct value The existing PHY ID for X540 was from early production hardware and is no longer correct. This patch corrects that. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_phy.c | 2 +- drivers/net/ixgbe/ixgbe_type.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index c445fbce56ee..8f7123e8fc0a 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -115,7 +115,7 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; - case AQ1202_PHY_ID: + case X540_PHY_ID: phy_type = ixgbe_phy_aq; break; case QT2022_PHY_ID: diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 0f80893edabf..59f6d0afe0fe 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -999,7 +999,7 @@ /* PHY IDs*/ #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB -#define AQ1202_PHY_ID 0x03A1B440 +#define X540_PHY_ID 0x01540200 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 #define AQ_FW_REV 0x20 -- cgit v1.2.3-59-g8ed1b From d994653db465616a7bf27703e733170c47488cdf Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 9 Dec 2010 06:55:19 +0000 Subject: ixgbe: fix X540 to use it's own info struct This patch enables X540 hardware to use it's own set of support functions. This is useful as it has no need of SFP+ support. A couple minor bugs with the eeprom semaphore were also cleaned up. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 16 ++++++++-------- drivers/net/ixgbe/ixgbe_x540.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fdb35d040d23..f2694f2b127a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -118,7 +118,7 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), - board_82599 }, + board_X540 }, /* required last entry */ {0, } @@ -1897,6 +1897,13 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) switch (hw->mac.type) { case ixgbe_mac_82599EB: + ixgbe_check_sfp_event(adapter, eicr); + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { + adapter->interrupt_event = eicr; + schedule_work(&adapter->check_overtemp_task); + } + /* now fallthrough to handle Flow Director */ case ixgbe_mac_X540: /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { @@ -1912,12 +1919,6 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) schedule_work(&adapter->fdir_reinit_task); } } - ixgbe_check_sfp_event(adapter, eicr); - if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && - ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { - adapter->interrupt_event = eicr; - schedule_work(&adapter->check_overtemp_task); - } break; default: break; @@ -2508,7 +2509,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data) switch (hw->mac.type) { case ixgbe_mac_82599EB: - case ixgbe_mac_X540: ixgbe_check_sfp_event(adapter, eicr); if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 9649fa727e31..cf88515c0ef8 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -278,7 +278,7 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) { s32 status; - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) + if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0) status = ixgbe_read_eerd_generic(hw, offset, data); else status = IXGBE_ERR_SWFW_SYNC; @@ -311,7 +311,7 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START; - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) { + if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0) { status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); if (status != 0) { hw_dbg(hw, "Eeprom write EEWR timed out\n"); -- cgit v1.2.3-59-g8ed1b From 5136cad37b276e3e11c4f8ad0bcf9cb2eec0e5af Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 1 Dec 2010 05:47:05 +0000 Subject: ixgbe: fix ntuple support commit f62bbb5e62c6e4a91fb222d22bc46e8d4d7e59ef ixgbe: Update ixgbe to use new vlan accleration. removed ETH_FLAG_NTUPLE from the supported flags. This patch puts it back on to allow for setting ntuple via ethtool. CC: Jesse Gross Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 90a740d77e5d..f2245ac75034 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2202,7 +2202,7 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) need_reset = (data & ETH_FLAG_RXVLAN) != (netdev->features & NETIF_F_HW_VLAN_RX); - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); if (rc) return rc; -- cgit v1.2.3-59-g8ed1b From 9fe93afdd07aba52a018eb52784124579a80470e Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 3 Dec 2010 09:33:54 +0000 Subject: ixgbe: cleanup string function calls to use bound checking versions. Some minor cleanup to use string calls that use bound checks just to be extra safe. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 5 +++-- drivers/net/ixgbe/ixgbe_main.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f2245ac75034..23ff23e8b393 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -839,9 +839,10 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); char firmware_version[32]; - strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); + strncpy(drvinfo->driver, ixgbe_driver_name, + sizeof(drvinfo->driver) - 1); strncpy(drvinfo->version, ixgbe_driver_version, - sizeof(drvinfo->version)); + sizeof(drvinfo->version) - 1); snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", (adapter->eeprom_version & 0xF000) >> 12, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f2694f2b127a..8af0fc051696 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2338,14 +2338,14 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) handler = SET_HANDLER(q_vector); if (handler == &ixgbe_msix_clean_rx) { - sprintf(q_vector->name, "%s-%s-%d", - netdev->name, "rx", ri++); + snprintf(q_vector->name, sizeof(q_vector->name) - 1, + "%s-%s-%d", netdev->name, "rx", ri++); } else if (handler == &ixgbe_msix_clean_tx) { - sprintf(q_vector->name, "%s-%s-%d", - netdev->name, "tx", ti++); + snprintf(q_vector->name, sizeof(q_vector->name) - 1, + "%s-%s-%d", netdev->name, "tx", ti++); } else if (handler == &ixgbe_msix_clean_many) { - sprintf(q_vector->name, "%s-%s-%d", - netdev->name, "TxRx", ri++); + snprintf(q_vector->name, sizeof(q_vector->name) - 1, + "%s-%s-%d", netdev->name, "TxRx", ri++); ti++; } else { /* skip this unused q_vector */ @@ -7047,7 +7047,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->netdev_ops = &ixgbe_netdev_ops; ixgbe_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; - strcpy(netdev->name, pci_name(pdev)); + strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); adapter->bd_number = cards_found; @@ -7269,7 +7269,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, err = ixgbe_read_pba_string_generic(hw, part_str, IXGBE_PBANUM_LENGTH); if (err) - strcpy(part_str, "Unknown"); + strncpy(part_str, "Unknown", IXGBE_PBANUM_LENGTH); if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) e_dev_info("MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n", hw->mac.type, hw->phy.type, hw->phy.sfp_type, -- cgit v1.2.3-59-g8ed1b From 9633e63bb1d82c02950983d5d3317e6656b11c8e Mon Sep 17 00:00:00 2001 From: Holger Eitzenberger Date: Wed, 17 Nov 2010 15:43:52 +0000 Subject: e1000e: fix double initialization in blink path The kernel goes BUG() at the time 'ethtool -p eth0 3' comes back, which is due to adapter->led_blink_task initialized several times. At the time it is still running this results in a corrupted task_list of the associated workqueue. The fix is to move the workqueue initialization to the probe function instead. Signed-off-by: Holger Eitzenberger Reviewed-by: Jesse Brandeburg Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/e1000.h | 1 + drivers/net/e1000e/ethtool.c | 3 +-- drivers/net/e1000e/netdev.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index fdc67fead4ea..3d9366ffd16e 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -482,6 +482,7 @@ extern const char e1000e_driver_version[]; extern void e1000e_check_options(struct e1000_adapter *adapter); extern void e1000e_set_ethtool_ops(struct net_device *netdev); +extern void e1000e_led_blink_task(struct work_struct *work); extern int e1000e_up(struct e1000_adapter *adapter); extern void e1000e_down(struct e1000_adapter *adapter); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 3612900b3bfe..5c6bc6ac069c 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1846,7 +1846,7 @@ static int e1000_set_wol(struct net_device *netdev, /* bit defines for adapter->led_status */ #define E1000_LED_ON 0 -static void e1000e_led_blink_task(struct work_struct *work) +void e1000e_led_blink_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, led_blink_task); @@ -1878,7 +1878,6 @@ static int e1000_phys_id(struct net_device *netdev, u32 data) (hw->mac.type == e1000_pch2lan) || (hw->mac.type == e1000_82583) || (hw->mac.type == e1000_82574)) { - INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); if (!adapter->blink_timer.function) { init_timer(&adapter->blink_timer); adapter->blink_timer.function = diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0adcb79e6386..f8efbbbfddfb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5903,6 +5903,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang); + INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); /* Initialize link parameters. User can change them with ethtool */ adapter->hw.mac.autoneg = 1; -- cgit v1.2.3-59-g8ed1b From a82a14f4cdcfedb27eacec8eb4d9e47d42c10d43 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:20 +0000 Subject: e1000e: 82571-based mezzanine card can fail ethtool link test On certain 82571-based mezzanine NICs in some blade servers, the ethtool link test can fail due to the serdes_has_link flag not set correctly. Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 9333921010cc..6942e2f86eac 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1523,8 +1523,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; e_dbg("AN_UP -> AN_PROG\n"); + } else { + mac->serdes_has_link = true; } - break; + break; case e1000_serdes_link_forced_up: /* @@ -1543,6 +1545,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; e_dbg("FORCED_UP -> AN_PROG\n"); + } else { + mac->serdes_has_link = true; } break; @@ -1598,6 +1602,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); mac->serdes_link_state = e1000_serdes_link_autoneg_progress; + mac->serdes_has_link = false; e_dbg("DOWN -> AN_PROG\n"); break; } -- cgit v1.2.3-59-g8ed1b From ed5c2b0b78e5467f7948bef92b21f3c76823f392 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:25 +0000 Subject: e1000e: 82574/82583 performance improvement Increasing the transmit fifo by 4K (by decreasing the receive fifo size specified in .pba by the same amount) increases Tx performance. Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 6942e2f86eac..280d41fc2a2d 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -2005,7 +2005,7 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .flags2 = FLAG2_CHECK_PHY_HANG, - .pba = 36, + .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, @@ -2022,7 +2022,7 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .pba = 36, + .pba = 32, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, -- cgit v1.2.3-59-g8ed1b From cbd006cb7d4e7b76c6febf7f51e970bced132914 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:30 +0000 Subject: e1000e: 82577/8 must acquire h/w semaphore before workaround The workaround function e1000_configure_k1_pchlan() assumes the h/w semaphore is already acquired. This was originally missed when setting up the part for the ethtool loopback test. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 5c6bc6ac069c..c10dc694d733 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1249,6 +1249,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) u32 ctrl_reg = 0; u32 stat_reg = 0; u16 phy_reg = 0; + s32 ret_val = 0; hw->mac.autoneg = 0; @@ -1308,7 +1309,13 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) case e1000_phy_82577: case e1000_phy_82578: /* Workaround: K1 must be disabled for stable 1Gbps operation */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_err("Cannot setup 1Gbps loopback.\n"); + return ret_val; + } e1000_configure_k1_ich8lan(hw, false); + hw->phy.ops.release(hw); break; case e1000_phy_82579: /* Disable PHY energy detect power down */ -- cgit v1.2.3-59-g8ed1b From d9c76f99c2a79feb413e3e751362d59c0f5323f6 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:35 +0000 Subject: e1000e: 82571 Serdes can fail to get link When link partner is sending continuous Config symbols, the 82571 Serdes FIFO can overflow resulting in Invalid bit getting set. To resolve this, if Sync and Config bits are both 1 ignore the Invalid bit and restart auto-negotiation. Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 280d41fc2a2d..e57e4097ef1b 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -52,6 +52,7 @@ (ID_LED_DEF1_DEF2)) #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 +#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */ #define E1000_BASE1000T_STATUS 10 #define E1000_IDLE_ERROR_COUNT_MASK 0xFF #define E1000_RECEIVE_ERROR_COUNTER 21 @@ -1503,6 +1504,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) u32 rxcw; u32 ctrl; u32 status; + u32 txcw; + u32 i; s32 ret_val = 0; ctrl = er32(CTRL); @@ -1613,16 +1616,32 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e_dbg("ANYSTATE -> DOWN\n"); } else { /* - * We have sync, and can tolerate one invalid (IV) - * codeword before declaring link down, so reread - * to look again. + * Check several times, if Sync and Config + * both are consistently 1 then simply ignore + * the Invalid bit and restart Autoneg */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_IV) { - mac->serdes_link_state = e1000_serdes_link_down; + for (i = 0; i < AN_RETRY_COUNT; i++) { + udelay(10); + rxcw = er32(RXCW); + if ((rxcw & E1000_RXCW_IV) && + !((rxcw & E1000_RXCW_SYNCH) && + (rxcw & E1000_RXCW_C))) { + mac->serdes_has_link = false; + mac->serdes_link_state = + e1000_serdes_link_down; + e_dbg("ANYSTATE -> DOWN\n"); + break; + } + } + + if (i == AN_RETRY_COUNT) { + txcw = er32(TXCW); + txcw |= E1000_TXCW_ANE; + ew32(TXCW, txcw); + mac->serdes_link_state = + e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; - e_dbg("ANYSTATE -> DOWN\n"); + e_dbg("ANYSTATE -> AN_PROG\n"); } } } -- cgit v1.2.3-59-g8ed1b From ce54afd16d874ac07378a8bb55d26f7f5b613c0e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:41 +0000 Subject: e1000e: 82577/8/9 mis-configured OEM bits during S0->Sx The LPLU (Low Power Link Up) and Gigabit Disable bits (a.k.a. OEM bits) were being configured incorrectly when device goes to D3 state. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index e3374d9a2472..d7fc930d1aa5 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -3591,7 +3591,7 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) ew32(PHY_CTRL, phy_ctrl); if (hw->mac.type >= e1000_pchlan) { - e1000_oem_bits_config_ich8lan(hw, true); + e1000_oem_bits_config_ich8lan(hw, false); ret_val = hw->phy.ops.acquire(hw); if (ret_val) return; -- cgit v1.2.3-59-g8ed1b From 664dc878ed6f0476b875547547a49e06f7a4e73b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:46 +0000 Subject: e1000e: 82579 PHY incorrectly identified during init During init, reading the 2 PHY ID registers back-to-back in the default fast mode could return invalid data (all F's) and in slow mode could return data to the second read the data from the first read. To resolve the issue in fast mode, set to slow mode before any PHY accesses; to resolve the issue in slow mode, put in a delay for every 82579 PHY access. Since this PHY is currently only paired with the pch2lan MAC and the PHY type is not known before the first PHY access which can fail this way, check for this based on MAC-type. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 16 +++++++++++----- drivers/net/e1000e/phy.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index d7fc930d1aa5..5080372b0fd7 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -338,12 +338,17 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) } phy->id = e1000_phy_unknown; - ret_val = e1000e_get_phy_id(hw); - if (ret_val) - goto out; - if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { + switch (hw->mac.type) { + default: + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) + break; + /* fall-through */ + case e1000_pch2lan: /* - * In case the PHY needs to be in mdio slow mode (eg. 82577), + * In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ ret_val = e1000_set_mdio_slow_mode_hv(hw); @@ -352,6 +357,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) ret_val = e1000e_get_phy_id(hw); if (ret_val) goto out; + break; } phy->type = e1000e_get_phy_type_from_id(phy->id); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 6ad90ccb4bab..95da38693b77 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -226,6 +226,13 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) } *data = (u16) mdic; + /* + * Allow some time after each MDIC transaction to avoid + * reading duplicate data in the next MDIC transaction. + */ + if (hw->mac.type == e1000_pch2lan) + udelay(100); + return 0; } @@ -279,6 +286,13 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) return -E1000_ERR_PHY; } + /* + * Allow some time after each MDIC transaction to avoid + * reading duplicate data in the next MDIC transaction. + */ + if (hw->mac.type == e1000_pch2lan) + udelay(100); + return 0; } -- cgit v1.2.3-59-g8ed1b From 073287c037083497ebaaf75ead469b769f218615 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:01:51 +0000 Subject: e1000e: support new PBA format from EEPROM Provide support to e1000e for displaying the new format of the PBA found in the EEPROM. The unique PBA identifier is no longer restricted to hexadecimal numbers and must now be read and displayed as a string. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/defines.h | 8 ++- drivers/net/e1000e/e1000.h | 3 +- drivers/net/e1000e/lib.c | 135 ++++++++++++++++++++++++++++++++++++------- drivers/net/e1000e/netdev.c | 12 ++-- 4 files changed, 130 insertions(+), 28 deletions(-) diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 016ea383145a..7245dc2e0b7c 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -488,6 +488,9 @@ #define E1000_BLK_PHY_RESET 12 #define E1000_ERR_SWFW_SYNC 13 #define E1000_NOT_IMPLEMENTED 14 +#define E1000_ERR_INVALID_ARGUMENT 16 +#define E1000_ERR_NO_SPACE 17 +#define E1000_ERR_NVM_PBA_SECTION 18 /* Loop limit on how long we wait for auto-negotiation to complete */ #define FIBER_LINK_UP_LIMIT 50 @@ -650,13 +653,16 @@ /* Mask bits for fields in Word 0x03 of the EEPROM */ #define NVM_COMPAT_LOM 0x0800 +/* length of string needed to store PBA number */ +#define E1000_PBANUM_LENGTH 11 + /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ #define NVM_SUM 0xBABA /* PBA (printed board assembly) number words */ #define NVM_PBA_OFFSET_0 8 #define NVM_PBA_OFFSET_1 9 - +#define NVM_PBA_PTR_GUARD 0xFAFA #define NVM_WORD_SIZE_BASE_SHIFT 6 /* NVM Commands - SPI */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 3d9366ffd16e..2c913b8e9116 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -514,7 +514,8 @@ extern struct e1000_info e1000_pch_info; extern struct e1000_info e1000_pch2_info; extern struct e1000_info e1000_es2_info; -extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num); +extern s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size); extern s32 e1000e_commit_phy(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 0fd4eb5ac5fb..8377523c054a 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -2138,6 +2138,119 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) return 0; } +/** + * e1000_read_pba_string_generic - Read device part number + * @hw: pointer to the HW structure + * @pba_num: pointer to device part number + * @pba_num_size: size of part number buffer + * + * Reads the product board assembly (PBA) number from the EEPROM and stores + * the value in pba_num. + **/ +s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + s32 ret_val; + u16 nvm_data; + u16 pba_ptr; + u16 offset; + u16 length; + + if (pba_num == NULL) { + e_dbg("PBA string buffer was null\n"); + ret_val = E1000_ERR_INVALID_ARGUMENT; + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + /* + * if nvm_data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (nvm_data != NVM_PBA_PTR_GUARD) { + e_dbg("NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + e_dbg("PBA string buffer too small\n"); + return E1000_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (nvm_data >> 12) & 0xF; + pba_num[1] = (nvm_data >> 8) & 0xF; + pba_num[2] = (nvm_data >> 4) & 0xF; + pba_num[3] = nvm_data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + goto out; + } + + ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if (length == 0xFFFF || length == 0) { + e_dbg("NVM PBA number section invalid length\n"); + ret_val = E1000_ERR_NVM_PBA_SECTION; + goto out; + } + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + e_dbg("PBA string buffer too small\n"); + ret_val = E1000_ERR_NO_SPACE; + goto out; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + pba_num[offset * 2] = (u8)(nvm_data >> 8); + pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); + } + pba_num[offset * 2] = '\0'; + +out: + return ret_val; +} + /** * e1000_read_mac_addr_generic - Read device MAC address * @hw: pointer to the HW structure @@ -2579,25 +2692,3 @@ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) out: return ret_val; } - -s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num) -{ - s32 ret_val; - u16 nvm_data; - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - *pba_num = (u32)(nvm_data << 16); - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - *pba_num |= nvm_data; - - return 0; -} diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index f8efbbbfddfb..393b76d27536 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5626,7 +5626,8 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - u32 pba_num; + u32 ret_val; + u8 pba_str[E1000_PBANUM_LENGTH]; /* print bus type/speed/width info */ e_info("(PCI Express:2.5GB/s:%s) %pM\n", @@ -5637,9 +5638,12 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) netdev->dev_addr); e_info("Intel(R) PRO/%s Network Connection\n", (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000"); - e1000e_read_pba_num(hw, &pba_num); - e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n", - hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff)); + ret_val = e1000_read_pba_string_generic(hw, pba_str, + E1000_PBANUM_LENGTH); + if (ret_val) + strcpy(pba_str, "Unknown"); + e_info("MAC: %d, PHY: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, pba_str); } static void e1000_eeprom_checks(struct e1000_adapter *adapter) -- cgit v1.2.3-59-g8ed1b From 36b973df713e1395b79896de667ad7dbb1925fa7 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 07:42:43 +0000 Subject: e1000e: prevent null ptr dereference in e1000_tx_queue() tx_desc can be dereferenced as a null pointer when count is passed in as 0. Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 393b76d27536..4bf843ac7ea3 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4629,7 +4629,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, i = tx_ring->next_to_use; - while (count--) { + do { buffer_info = &tx_ring->buffer_info[i]; tx_desc = E1000_TX_DESC(*tx_ring, i); tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); @@ -4640,7 +4640,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, i++; if (i == tx_ring->count) i = 0; - } + } while (--count > 0); tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd); -- cgit v1.2.3-59-g8ed1b From e9262447233037e9336d5866628821156a17366f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 24 Nov 2010 06:02:06 +0000 Subject: e1000e: minor error message corrections Correct error messages when setting up Rx resources and when checking module parameters. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 2 +- drivers/net/e1000e/param.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4bf843ac7ea3..6e1f3a366a7a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2130,7 +2130,7 @@ err_pages: } err: vfree(rx_ring->buffer_info); - e_err("Unable to allocate memory for the transmit descriptor ring\n"); + e_err("Unable to allocate memory for the receive descriptor ring\n"); return err; } diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 3d36911f77f3..a9612b0e4bca 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -421,7 +421,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) static const struct e1000_option opt = { .type = enable_option, .name = "CRC Stripping", - .err = "defaulting to enabled", + .err = "defaulting to Enabled", .def = OPTION_ENABLED }; -- cgit v1.2.3-59-g8ed1b From 61c758166701c4f156c0aba10260f5729b1a6f43 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 9 Dec 2010 23:04:25 +0000 Subject: e1000e: static analysis tools complain of a possible null ptr p dereference Adding this default case resolves the issue. v2- Removed "break" in default case based on feedback Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index c10dc694d733..39349d6dcd0b 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1978,6 +1978,9 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, p = (char *) adapter + e1000_gstrings_stats[i].stat_offset; break; + default: + data[i] = 0; + continue; } data[i] = (e1000_gstrings_stats[i].sizeof_stat == -- cgit v1.2.3-59-g8ed1b From c920aa8b87bfec3dbd926ae777430e613e5088df Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 1 Dec 2010 08:45:24 +0000 Subject: e1000e: increment the driver version Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 6e1f3a366a7a..5530d0bdd11a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -54,7 +54,7 @@ #define DRV_EXTRAVERSION "-k2" -#define DRV_VERSION "1.2.7" DRV_EXTRAVERSION +#define DRV_VERSION "1.2.20" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.3-59-g8ed1b From 9835fd7321a67feba6432e63bf2cba43f5a56bd9 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Mon, 22 Nov 2010 17:17:21 +0000 Subject: igb: Add new function to read part number from EEPROM in string format New adapters will have part numbers stored in string format rather than simple hex format. This function will read part number formats in either hex or string. Signed-off-by: Carolyn Wyborny Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 7 ++++ drivers/net/igb/e1000_nvm.c | 93 ++++++++++++++++++++++++++++++++++++++--- drivers/net/igb/e1000_nvm.h | 2 + drivers/net/igb/igb_main.c | 11 ++--- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 62222796a8b3..6319ed902bc0 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -419,6 +419,9 @@ #define E1000_ERR_SWFW_SYNC 13 #define E1000_NOT_IMPLEMENTED 14 #define E1000_ERR_MBX 15 +#define E1000_ERR_INVALID_ARGUMENT 16 +#define E1000_ERR_NO_SPACE 17 +#define E1000_ERR_NVM_PBA_SECTION 18 /* Loop limit on how long we wait for auto-negotiation to complete */ #define COPPER_LINK_UP_LIMIT 10 @@ -580,11 +583,15 @@ /* Mask bits for fields in Word 0x1a of the NVM */ +/* length of string needed to store part num */ +#define E1000_PBANUM_LENGTH 11 + /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ #define NVM_SUM 0xBABA #define NVM_PBA_OFFSET_0 8 #define NVM_PBA_OFFSET_1 9 +#define NVM_PBA_PTR_GUARD 0xFAFA #define NVM_WORD_SIZE_BASE_SHIFT 6 /* NVM Commands - Microwire */ diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index d83b77fa4038..6b5cc2cc453d 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c @@ -445,31 +445,112 @@ out: } /** - * igb_read_part_num - Read device part number + * igb_read_part_string - Read device part number * @hw: pointer to the HW structure * @part_num: pointer to device part number + * @part_num_size: size of part number buffer * * Reads the product board assembly (PBA) number from the EEPROM and stores * the value in part_num. **/ -s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num) +s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size) { - s32 ret_val; + s32 ret_val; u16 nvm_data; + u16 pointer; + u16 offset; + u16 length; + + if (part_num == NULL) { + hw_dbg("PBA string buffer was null\n"); + ret_val = E1000_ERR_INVALID_ARGUMENT; + goto out; + } ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } - *part_num = (u32)(nvm_data << 16); - ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pointer); + if (ret_val) { + hw_dbg("NVM Read Error\n"); + goto out; + } + + /* + * if nvm_data is not ptr guard the PBA must be in legacy format which + * means pointer is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (nvm_data != NVM_PBA_PTR_GUARD) { + hw_dbg("NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (part_num_size < 11) { + hw_dbg("PBA string buffer too small\n"); + return E1000_ERR_NO_SPACE; + } + + /* extract hex string from data and pointer */ + part_num[0] = (nvm_data >> 12) & 0xF; + part_num[1] = (nvm_data >> 8) & 0xF; + part_num[2] = (nvm_data >> 4) & 0xF; + part_num[3] = nvm_data & 0xF; + part_num[4] = (pointer >> 12) & 0xF; + part_num[5] = (pointer >> 8) & 0xF; + part_num[6] = '-'; + part_num[7] = 0; + part_num[8] = (pointer >> 4) & 0xF; + part_num[9] = pointer & 0xF; + + /* put a null character on the end of our string */ + part_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (part_num[offset] < 0xA) + part_num[offset] += '0'; + else if (part_num[offset] < 0x10) + part_num[offset] += 'A' - 0xA; + } + + goto out; + } + + ret_val = hw->nvm.ops.read(hw, pointer, 1, &length); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } - *part_num |= nvm_data; + + if (length == 0xFFFF || length == 0) { + hw_dbg("NVM PBA number section invalid length\n"); + ret_val = E1000_ERR_NVM_PBA_SECTION; + goto out; + } + /* check if part_num buffer is big enough */ + if (part_num_size < (((u32)length * 2) - 1)) { + hw_dbg("PBA string buffer too small\n"); + ret_val = E1000_ERR_NO_SPACE; + goto out; + } + + /* trim pba length from start of string */ + pointer++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = hw->nvm.ops.read(hw, pointer + offset, 1, &nvm_data); + if (ret_val) { + hw_dbg("NVM Read Error\n"); + goto out; + } + part_num[offset * 2] = (u8)(nvm_data >> 8); + part_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); + } + part_num[offset * 2] = '\0'; out: return ret_val; diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h index 1041c34dcbe1..29c956a84bd0 100644 --- a/drivers/net/igb/e1000_nvm.h +++ b/drivers/net/igb/e1000_nvm.h @@ -32,6 +32,8 @@ s32 igb_acquire_nvm(struct e1000_hw *hw); void igb_release_nvm(struct e1000_hw *hw); s32 igb_read_mac_addr(struct e1000_hw *hw); s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num); +s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, + u32 part_num_size); s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 igb_validate_nvm_checksum(struct e1000_hw *hw); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 67ea262e482a..041f8e6f74f4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1729,12 +1729,13 @@ static int __devinit igb_probe(struct pci_dev *pdev, struct igb_adapter *adapter; struct e1000_hw *hw; u16 eeprom_data = 0; + s32 ret_val; static int global_quad_port_a; /* global quad port a indication */ const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; unsigned long mmio_start, mmio_len; int err, pci_using_dac; u16 eeprom_apme_mask = IGB_EEPROM_APME; - u32 part_num; + u8 part_str[E1000_PBANUM_LENGTH]; /* Catch broken hardware that put the wrong VF device ID in * the PCIe SR-IOV capability. @@ -2000,10 +2001,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, "unknown"), netdev->dev_addr); - igb_read_part_num(hw, &part_num); - dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name, - (part_num >> 8), (part_num & 0xff)); - + ret_val = igb_read_part_string(hw, part_str, E1000_PBANUM_LENGTH); + if (ret_val) + strcpy(part_str, "Unknown"); + dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str); dev_info(&pdev->dev, "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n", adapter->msix_entries ? "MSI-X" : -- cgit v1.2.3-59-g8ed1b From 1853e2e15dc95ff3430530941b5856581251ef70 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 15:40:01 +0000 Subject: s2io: rx_ring_sz bounds checking modparm rx_ring_sz can be set to be greater than the maximum allowable number of blocks. This results in an array overrun when probing the driver, and causes memory corruption. Also, the MAX_RX_DESC_1 multiply the max number of rings by max number of blocker per ring by 127, but the driver does the same calculation with 127+1. This results in the possibility of the value being set being larger than the maximum allowable value. Finally, clean-up the s2io_ethtool_gringparam code to be more intuitive. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 40 ++++++++++++++++++++++++---------------- drivers/net/s2io.h | 5 ++--- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 0f4219cb0be2..a6d3eaf44863 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5568,30 +5568,27 @@ static void s2io_ethtool_gringparam(struct net_device *dev, struct s2io_nic *sp = netdev_priv(dev); int i, tx_desc_count = 0, rx_desc_count = 0; - if (sp->rxd_mode == RXD_MODE_1) + if (sp->rxd_mode == RXD_MODE_1) { ering->rx_max_pending = MAX_RX_DESC_1; - else if (sp->rxd_mode == RXD_MODE_3B) + ering->rx_jumbo_max_pending = MAX_RX_DESC_1; + } else { ering->rx_max_pending = MAX_RX_DESC_2; + ering->rx_jumbo_max_pending = MAX_RX_DESC_2; + } + ering->rx_mini_max_pending = 0; ering->tx_max_pending = MAX_TX_DESC; - for (i = 0 ; i < sp->config.tx_fifo_num ; i++) - tx_desc_count += sp->config.tx_cfg[i].fifo_len; - DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds); - ering->tx_pending = tx_desc_count; - rx_desc_count = 0; - for (i = 0 ; i < sp->config.rx_ring_num ; i++) + for (i = 0; i < sp->config.rx_ring_num; i++) rx_desc_count += sp->config.rx_cfg[i].num_rxd; - ering->rx_pending = rx_desc_count; - - ering->rx_mini_max_pending = 0; - ering->rx_mini_pending = 0; - if (sp->rxd_mode == RXD_MODE_1) - ering->rx_jumbo_max_pending = MAX_RX_DESC_1; - else if (sp->rxd_mode == RXD_MODE_3B) - ering->rx_jumbo_max_pending = MAX_RX_DESC_2; ering->rx_jumbo_pending = rx_desc_count; + ering->rx_mini_pending = 0; + + for (i = 0; i < sp->config.tx_fifo_num; i++) + tx_desc_count += sp->config.tx_cfg[i].fifo_len; + ering->tx_pending = tx_desc_count; + DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds); } /** @@ -7692,6 +7689,8 @@ static void s2io_init_pci(struct s2io_nic *sp) static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, u8 *dev_multiq) { + int i; + if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) { DBG_PRINT(ERR_DBG, "Requested number of tx fifos " "(%d) not supported\n", tx_fifo_num); @@ -7750,6 +7749,15 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n"); rx_ring_mode = 1; } + + for (i = 0; i < MAX_RX_RINGS; i++) + if (rx_ring_sz[i] > MAX_RX_BLOCKS_PER_RING) { + DBG_PRINT(ERR_DBG, "Requested rx ring size not " + "supported\nDefaulting to %d\n", + MAX_RX_BLOCKS_PER_RING); + rx_ring_sz[i] = MAX_RX_BLOCKS_PER_RING; + } + return SUCCESS; } diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 00b8614efe48..1671443b3c0e 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -355,9 +355,8 @@ struct stat_block { #define FIFO_OTHER_MAX_NUM 1 -#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) -#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) -#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) +#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 128) +#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 86) #define MAX_TX_DESC (MAX_AVAILABLE_TXDS) /* FIFO mappings for all possible number of fifos configured */ -- cgit v1.2.3-59-g8ed1b From c0dbf37e78c5c1e3e6cfeb39de30518fdde33e83 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 15:40:02 +0000 Subject: s2io: make strings at tables const Put immutable data in read/only section. Signed-off-by: Stephen Hemminger Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 8 ++++---- drivers/net/s2io.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a6d3eaf44863..6a87b8c69b78 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -91,11 +91,11 @@ #define DRV_VERSION "2.0.26.27" /* S2io Driver name & version. */ -static char s2io_driver_name[] = "Neterion"; -static char s2io_driver_version[] = DRV_VERSION; +static const char s2io_driver_name[] = "Neterion"; +static const char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[2] = {32, 48}; -static int rxd_count[2] = {127, 85}; +static const int rxd_size[2] = {32, 48}; +static const int rxd_count[2] = {127, 85}; static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) { diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 1671443b3c0e..7d160306b651 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -360,7 +360,7 @@ struct stat_block { #define MAX_TX_DESC (MAX_AVAILABLE_TXDS) /* FIFO mappings for all possible number of fifos configured */ -static int fifo_map[][MAX_TX_FIFOS] = { +static const int fifo_map[][MAX_TX_FIFOS] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 1, 1, 1, 2, 2}, @@ -371,7 +371,7 @@ static int fifo_map[][MAX_TX_FIFOS] = { {0, 1, 2, 3, 4, 5, 6, 7}, }; -static u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7}; +static const u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7}; /* Maintains Per FIFO related information. */ struct tx_fifo_config { -- cgit v1.2.3-59-g8ed1b From 11410b62cf9bdaed5863696c7994286a900424c7 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 15:40:03 +0000 Subject: s2io: Update Driver Version Update Driver Version Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 6a87b8c69b78..80efc05d4d64 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -88,7 +88,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.27" +#define DRV_VERSION "2.0.26.28" /* S2io Driver name & version. */ static const char s2io_driver_name[] = "Neterion"; -- cgit v1.2.3-59-g8ed1b From 85a564983aff948b9ea8b6e734b3e80b5755d12a Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 10 Dec 2010 15:40:04 +0000 Subject: s2io: Using static const generally increases object text and decreases data size. It also generally decreases overall object size. text data bss dec hex filename 109387 389 24432 134208 20c40 drivers/net/s2io.o.old 109358 389 24432 134179 20c23 drivers/net/s2io.o.new Signed-off-by: Joe Perches Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 80efc05d4d64..9a1e32fb720b 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3598,10 +3598,12 @@ static int s2io_set_swapper(struct s2io_nic *sp) val64 = readq(&bar0->pif_rd_swapper_fb); if (val64 != 0x0123456789ABCDEFULL) { int i = 0; - u64 value[] = { 0xC30000C3C30000C3ULL, /* FE=1, SE=1 */ - 0x8100008181000081ULL, /* FE=1, SE=0 */ - 0x4200004242000042ULL, /* FE=0, SE=1 */ - 0}; /* FE=0, SE=0 */ + static const u64 value[] = { + 0xC30000C3C30000C3ULL, /* FE=1, SE=1 */ + 0x8100008181000081ULL, /* FE=1, SE=0 */ + 0x4200004242000042ULL, /* FE=0, SE=1 */ + 0 /* FE=0, SE=0 */ + }; while (i < 4) { writeq(value[i], &bar0->swapper_ctrl); @@ -3627,10 +3629,12 @@ static int s2io_set_swapper(struct s2io_nic *sp) if (val64 != valt) { int i = 0; - u64 value[] = { 0x00C3C30000C3C300ULL, /* FE=1, SE=1 */ - 0x0081810000818100ULL, /* FE=1, SE=0 */ - 0x0042420000424200ULL, /* FE=0, SE=1 */ - 0}; /* FE=0, SE=0 */ + static const u64 value[] = { + 0x00C3C30000C3C300ULL, /* FE=1, SE=1 */ + 0x0081810000818100ULL, /* FE=1, SE=0 */ + 0x0042420000424200ULL, /* FE=0, SE=1 */ + 0 /* FE=0, SE=0 */ + }; while (i < 4) { writeq((value[i] | valr), &bar0->swapper_ctrl); -- cgit v1.2.3-59-g8ed1b From ad1184c6cf067a13e8cb2a4e7ccc407f947027d0 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Sat, 11 Dec 2010 09:53:42 +0000 Subject: net: au1000_eth: remove unused global variable. The driver global au_macs[] is unused in the entire kernel tree, so remove it. Signed-off-by: Manuel Lauss Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 53eff9ba6e95..b9debcfb61a0 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -106,8 +106,6 @@ MODULE_VERSION(DRV_VERSION); * complete immediately. */ -struct au1000_private *au_macs[NUM_ETH_INTERFACES]; - /* * board-specific configurations * -- cgit v1.2.3-59-g8ed1b From 6e07ebd84eef00be9e169a6d15a0bc20b06578fa Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: drivers/net: remove unnecessary flush_scheduled_work() calls janz-ican3, sh_eth, skge and vxge don't use workqueue at all and there is no reason to flush the system_wq. Drop flush_scheduled_work() calls and references to workqueue. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: Wolfgang Grandegger Cc: Stephen Hemminger Cc: Ramkrishna Vepa Cc: Sivakumar Subramani Cc: Sreenivasa Honnur Cc: Jon Mason Cc: netdev@vger.kernel.org --- drivers/net/can/janz-ican3.c | 9 --------- drivers/net/sh_eth.c | 1 - drivers/net/sh_eth.h | 1 - drivers/net/skge.c | 2 -- drivers/net/vxge/vxge-main.c | 2 -- 5 files changed, 15 deletions(-) diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 6e533dcc36c0..b9a6d7a5a739 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1114,11 +1114,6 @@ static bool ican3_txok(struct ican3_dev *mod) /* * Recieve one CAN frame from the hardware * - * This works like the core of a NAPI function, but is intended to be called - * from workqueue context instead. This driver already needs a workqueue to - * process control messages, so we use the workqueue instead of using NAPI. - * This was done to simplify locking. - * * CONTEXT: must be called from user context */ static int ican3_recv_skb(struct ican3_dev *mod) @@ -1251,7 +1246,6 @@ static irqreturn_t ican3_irq(int irq, void *dev_id) * Reset an ICAN module to its power-on state * * CONTEXT: no network device registered - * LOCKING: work function disabled */ static int ican3_reset_module(struct ican3_dev *mod) { @@ -1262,9 +1256,6 @@ static int ican3_reset_module(struct ican3_dev *mod) /* disable interrupts so no more work is scheduled */ iowrite8(1 << mod->num, &mod->ctrl->int_disable); - /* flush any pending work */ - flush_scheduled_work(); - /* the first unallocated page in the DPM is #9 */ mod->free_page = DPM_FREE_START; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index b12660d72338..819c1750e2ab 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1552,7 +1552,6 @@ static int sh_eth_drv_remove(struct platform_device *pdev) sh_mdio_release(ndev); unregister_netdev(ndev); - flush_scheduled_work(); pm_runtime_disable(&pdev->dev); free_netdev(ndev); platform_set_drvdata(pdev, NULL); diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 8b47763958f2..efa64221eede 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 220e0398f1d5..8c1404b58382 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -4012,8 +4012,6 @@ static void __devexit skge_remove(struct pci_dev *pdev) if (!hw) return; - flush_scheduled_work(); - dev1 = hw->dev[1]; if (dev1) unregister_netdev(dev1); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index b771e4b2ca9e..537ad874f11c 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3439,8 +3439,6 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) strncpy(buf, dev->name, IFNAMSIZ); - flush_scheduled_work(); - /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); -- cgit v1.2.3-59-g8ed1b From 23f333a2bfafba80339315b724808982a9de57d9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: drivers/net: don't use flush_scheduled_work() flush_scheduled_work() is on its way out. This patch contains simple conversions to replace flush_scheduled_work() usage with direct cancels and flushes. Directly cancel the used works on driver detach and flush them in other cases. The conversions are mostly straight forward and the only dangers are, * Forgetting to cancel/flush one or more used works. * Cancelling when a work should be flushed (ie. the work must be executed once scheduled whether the driver is detaching or not). I've gone over the changes multiple times but it would be much appreciated if you can review with the above points in mind. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: Jay Cliburn Cc: Michael Chan Cc: Divy Le Ray Cc: e1000-devel@lists.sourceforge.net Cc: Vasanthy Kolluri Cc: Samuel Ortiz Cc: Lennert Buytenhek Cc: Andrew Gallatin Cc: Francois Romieu Cc: Ramkrishna Vepa Cc: Matt Carlson Cc: David Brownell Cc: Shreyas Bhatewara Cc: netdev@vger.kernel.org --- drivers/net/8139too.c | 3 ++- drivers/net/atlx/atl2.c | 4 ++-- drivers/net/bcm63xx_enet.c | 2 +- drivers/net/bnx2.c | 4 ++-- drivers/net/cassini.c | 4 ++-- drivers/net/cxgb3/cxgb3_main.c | 3 ++- drivers/net/e1000e/netdev.c | 6 +++--- drivers/net/enic/enic_main.c | 2 +- drivers/net/ibm_newemac/core.c | 2 +- drivers/net/irda/mcs7780.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 3 +-- drivers/net/mv643xx_eth.c | 2 +- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/pxa168_eth.c | 2 +- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 6 ++++-- drivers/net/sis190.c | 3 ++- drivers/net/tg3.c | 4 ++-- drivers/net/usb/sierra_net.c | 5 ++--- drivers/net/usb/usbnet.c | 3 +-- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- 23 files changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index f5166dccd8df..98517a373473 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -1092,10 +1092,11 @@ err_out: static void __devexit rtl8139_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); + struct rtl8139_private *tp = netdev_priv(dev); assert (dev != NULL); - flush_scheduled_work(); + cancel_delayed_work_sync(&tp->thread); unregister_netdev (dev); diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 35b14bec1207..4e6f4e95a5a0 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1504,8 +1504,8 @@ static void __devexit atl2_remove(struct pci_dev *pdev) del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_config_timer); - - flush_scheduled_work(); + cancel_work_sync(&adapter->reset_task); + cancel_work_sync(&adapter->link_chg_task); unregister_netdev(netdev); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index ecfef240a303..e94a966af418 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -1097,7 +1097,7 @@ static int bcm_enet_stop(struct net_device *dev) enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); /* make sure no mib update is scheduled */ - flush_scheduled_work(); + cancel_work_sync(&priv->mib_update_task); /* disable dma & mac */ bcm_enet_disable_dma(priv, priv->tx_chan); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 03209a37883e..5c811f3fa11a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -8393,7 +8393,7 @@ bnx2_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = netdev_priv(dev); - flush_scheduled_work(); + cancel_work_sync(&bp->reset_task); unregister_netdev(dev); @@ -8431,7 +8431,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) if (!netif_running(dev)) return 0; - flush_scheduled_work(); + cancel_work_sync(&bp->reset_task); bnx2_netif_stop(bp, true); netif_device_detach(dev); del_timer_sync(&bp->timer); diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index d6b6d6aa565a..a8a32bc9aae6 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -3880,7 +3880,7 @@ static int cas_change_mtu(struct net_device *dev, int new_mtu) schedule_work(&cp->reset_task); #endif - flush_scheduled_work(); + flush_work_sync(&cp->reset_task); return 0; } @@ -5177,7 +5177,7 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) vfree(cp->fw_data); mutex_lock(&cp->pm_mutex); - flush_scheduled_work(); + cancel_work_sync(&cp->reset_task); if (cp->hw_running) cas_shutdown(cp); mutex_unlock(&cp->pm_mutex); diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 386461750d0f..4d538a4e9d55 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1359,6 +1359,7 @@ out: static int offload_close(struct t3cdev *tdev) { struct adapter *adapter = tdev2adap(tdev); + struct t3c_data *td = T3C_DATA(tdev); if (!test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) return 0; @@ -1369,7 +1370,7 @@ static int offload_close(struct t3cdev *tdev) sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); /* Flush work scheduled while releasing TIDs */ - flush_scheduled_work(); + flush_work_sync(&td->tid_release_task); tdev->lldev = NULL; cxgb3_set_dummy_ops(tdev); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5530d0bdd11a..02d093d1dd5c 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -6028,8 +6028,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev) bool down = test_bit(__E1000_DOWN, &adapter->state); /* - * flush_scheduled work may reschedule our watchdog task, so - * explicitly disable watchdog tasks from being rescheduled + * The timers may be rescheduled, so explicitly disable them + * from being rescheduled. */ if (!down) set_bit(__E1000_DOWN, &adapter->state); @@ -6040,8 +6040,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev) cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->downshift_task); cancel_work_sync(&adapter->update_phy_task); + cancel_work_sync(&adapter->led_blink_task); cancel_work_sync(&adapter->print_hang_task); - flush_scheduled_work(); if (!(netdev->flags & IFF_UP)) e1000_power_down_phy(adapter); diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9befd54ce6e1..77d91381a74d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2834,7 +2834,7 @@ static void __devexit enic_remove(struct pci_dev *pdev) if (netdev) { struct enic *enic = netdev_priv(netdev); - flush_scheduled_work(); + cancel_work_sync(&enic->reset); unregister_netdev(netdev); enic_dev_deinit(enic); vnic_dev_close(enic->vdev); diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 06bb9b799458..8f11d29a5828 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2950,7 +2950,7 @@ static int __devexit emac_remove(struct platform_device *ofdev) unregister_netdev(dev->ndev); - flush_scheduled_work(); + cancel_work_sync(&dev->reset_work); if (emac_has_feature(dev, EMAC_FTR_HAS_TAH)) tah_detach(dev->tah_dev, dev->tah_port); diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 74b20f179cea..cc821de2c966 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -959,7 +959,7 @@ static void mcs_disconnect(struct usb_interface *intf) if (!mcs) return; - flush_scheduled_work(); + cancel_work_sync(&mcs->work); unregister_netdev(mcs->netdev); free_netdev(mcs->netdev); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 2e98506d12e3..b021798ef49f 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -527,7 +527,7 @@ ixgb_remove(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct ixgb_adapter *adapter = netdev_priv(netdev); - flush_scheduled_work(); + cancel_work_sync(&adapter->tx_timeout_task); unregister_netdev(netdev); diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 2216a3c8b12b..809e38ce8a13 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3484,10 +3484,9 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev) del_timer_sync(&adapter->watchdog_timer); + cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->watchdog_task); - flush_scheduled_work(); - if (adapter->netdev_registered) { unregister_netdev(netdev); adapter->netdev_registered = false; diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index ce31e74a559b..02076e16542a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2978,7 +2978,7 @@ static int mv643xx_eth_remove(struct platform_device *pdev) unregister_netdev(mp->dev); if (mp->phy != NULL) phy_detach(mp->phy); - flush_scheduled_work(); + cancel_work_sync(&mp->tx_timeout_task); free_netdev(mp->dev); platform_set_drvdata(pdev, NULL); diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 8524cc40ec57..1ce0207e62a9 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -4067,7 +4067,7 @@ static void myri10ge_remove(struct pci_dev *pdev) if (mgp == NULL) return; - flush_scheduled_work(); + cancel_work_sync(&mgp->watchdog_work); netdev = mgp->dev; unregister_netdev(netdev); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 781e368329f9..f64c42414bd7 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9917,7 +9917,7 @@ static int niu_suspend(struct pci_dev *pdev, pm_message_t state) if (!netif_running(dev)) return 0; - flush_scheduled_work(); + flush_work_sync(&np->reset_task); niu_netif_stop(np); del_timer_sync(&np->timer); diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 04ed27d0b6be..1b63c8aef121 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -1602,7 +1602,7 @@ static int pxa168_eth_remove(struct platform_device *pdev) mdiobus_unregister(pep->smi_bus); mdiobus_free(pep->smi_bus); unregister_netdev(dev); - flush_scheduled_work(); + cancel_work_sync(&pep->tx_timeout_task); free_netdev(dev); platform_set_drvdata(pdev, NULL); return 0; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4a..98d792c33877 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3240,7 +3240,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - flush_scheduled_work(); + cancel_delayed_work_sync(&tp->task); unregister_netdev(dev); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 9a1e32fb720b..39c17cecb8b9 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -8341,9 +8341,11 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) return; } - flush_scheduled_work(); - sp = netdev_priv(dev); + + cancel_work_sync(&sp->rst_timer_task); + cancel_work_sync(&sp->set_link_task); + unregister_netdev(dev); free_shared_mem(sp); diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index a5d6a6bd0c1a..3406ed870917 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1915,9 +1915,10 @@ err_release_board: static void __devexit sis190_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); + struct sis190_private *tp = netdev_priv(dev); sis190_mii_remove(dev); - flush_scheduled_work(); + cancel_work_sync(&tp->phy_task); unregister_netdev(dev); sis190_release_board(pdev); pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5faa87d86c66..57e19fb1324f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -15034,7 +15034,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) if (tp->fw) release_firmware(tp->fw); - flush_scheduled_work(); + cancel_work_sync(&tp->reset_task); if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { tg3_phy_fini(tp); @@ -15073,7 +15073,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) if (!netif_running(dev)) return 0; - flush_scheduled_work(); + flush_work_sync(&tp->reset_task); tg3_phy_stop(tp); tg3_netif_stop(tp); diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index d1ac15c95faf..ed1b43210584 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -802,10 +802,9 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf) dev_dbg(&dev->udev->dev, "%s", __func__); - /* Kill the timer then flush the work queue */ + /* kill the timer and work */ del_timer_sync(&priv->sync_timer); - - flush_scheduled_work(); + cancel_work_sync(&priv->sierra_net_kevent); /* tell modem we are going away */ status = sierra_net_send_cmd(dev, priv->shdwn_msg, diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index cff74b81a7d2..ed9a41643ff4 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1248,8 +1248,7 @@ void usbnet_disconnect (struct usb_interface *intf) net = dev->net; unregister_netdev (net); - /* we don't hold rtnl here ... */ - flush_scheduled_work (); + cancel_work_sync(&dev->kevent); if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 65860a998321..0169be7694a9 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -3069,7 +3069,7 @@ vmxnet3_remove_device(struct pci_dev *pdev) #endif num_rx_queues = 1; - flush_scheduled_work(); + cancel_work_sync(&adapter->work); unregister_netdev(netdev); -- cgit v1.2.3-59-g8ed1b From 3d6b892bcc4c810071e36d8aff25aa171f55f93d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: ehea: kill unused ehea_rereg_mr_task ehea_rereg_mr_task is not used. Remove it and drop @work parameter from ehea_rereg_mrs(). Signed-off-by: Tejun Heo Cc: Breno Leitao Cc: netdev@vger.kernel.org --- drivers/net/ehea/ehea.h | 2 -- drivers/net/ehea/ehea_main.c | 9 +++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 8e745e74828d..1f2a675649b7 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -515,6 +515,4 @@ void ehea_set_ethtool_ops(struct net_device *netdev); int ehea_sense_port_attr(struct ehea_port *port); int ehea_set_portspeed(struct ehea_port *port, u32 port_speed); -extern struct work_struct ehea_rereg_mr_task; - #endif /* __EHEA_H__ */ diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 69f61523fcc8..d51def112d35 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -101,7 +101,6 @@ MODULE_PARM_DESC(use_lro, " Large Receive Offload, 1: enable, 0: disable, " static int port_name_cnt; static LIST_HEAD(adapter_list); static unsigned long ehea_driver_flags; -struct work_struct ehea_rereg_mr_task; static DEFINE_MUTEX(dlpar_mem_lock); struct ehea_fw_handle_array ehea_fw_handles; struct ehea_bcmc_reg_array ehea_bcmc_regs; @@ -2984,7 +2983,7 @@ out: mutex_unlock(&dlpar_mem_lock); } -static void ehea_rereg_mrs(struct work_struct *work) +static void ehea_rereg_mrs(void) { int ret, i; struct ehea_adapter *adapter; @@ -3659,14 +3658,14 @@ static int ehea_mem_notifier(struct notifier_block *nb, set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; - ehea_rereg_mrs(NULL); + ehea_rereg_mrs(); break; case MEM_GOING_OFFLINE: ehea_info("memory is going offline"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; - ehea_rereg_mrs(NULL); + ehea_rereg_mrs(); break; default: break; @@ -3742,8 +3741,6 @@ int __init ehea_module_init(void) printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION); - - INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles)); memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); -- cgit v1.2.3-59-g8ed1b From f5c35cc191afd08d660e6db0fecc9f431dc8f273 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: ehea: don't use flush_scheduled_work() Directly cancel port->reset_task from ehea_shutdown_single_port() instead. As this cancels the work for each port on driver detach, flushing system_wq from ehea_remove() or ehea_module_exit() is no longer necessary. Signed-off-by: Tejun Heo Cc: Breno Leitao Cc: netdev@vger.kernel.org --- drivers/net/ehea/ehea_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d51def112d35..81e5b7b49e9e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3318,6 +3318,8 @@ out_err: static void ehea_shutdown_single_port(struct ehea_port *port) { struct ehea_adapter *adapter = port->adapter; + + cancel_work_sync(&port->reset_task); unregister_netdev(port->netdev); ehea_unregister_port(port); kfree(port->mc_list); @@ -3607,8 +3609,6 @@ static int __devexit ehea_remove(struct platform_device *dev) ehea_remove_device_sysfs(dev); - flush_scheduled_work(); - ibmebus_free_irq(adapter->neq->attr.ist1, adapter); tasklet_kill(&adapter->neq_tasklet); @@ -3797,7 +3797,6 @@ static void __exit ehea_module_exit(void) { int ret; - flush_scheduled_work(); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); unregister_reboot_notifier(&ehea_reboot_nb); -- cgit v1.2.3-59-g8ed1b From 9beb4896cec71e40738a7752072174fbf0d5b7b4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: iseries_veth: don't use flush_scheduled_work() flush_scheduled_work() is on its way out. Remove its usage from iseries_veth. * Cancelling a delayed work, queueing it for immediate execution if cancelled and then waiting for completion can be done by simply calling flush_delayed_work_sync(). * Explicitly cancel cnx->statemachine_wq on module unload. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: Santiago Leon Cc: netdev@vger.kernel.org --- drivers/net/iseries_veth.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 63ac531f5996..9ece1fd9889d 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -885,17 +885,8 @@ static void veth_stop_connection(struct veth_lpar_connection *cnx) veth_kick_statemachine(cnx); spin_unlock_irq(&cnx->lock); - /* There's a slim chance the reset code has just queued the - * statemachine to run in five seconds. If so we need to cancel - * that and requeue the work to run now. */ - if (cancel_delayed_work(&cnx->statemachine_wq)) { - spin_lock_irq(&cnx->lock); - veth_kick_statemachine(cnx); - spin_unlock_irq(&cnx->lock); - } - - /* Wait for the state machine to run. */ - flush_scheduled_work(); + /* ensure the statemachine runs now and waits for its completion */ + flush_delayed_work_sync(&cnx->statemachine_wq); } static void veth_destroy_connection(struct veth_lpar_connection *cnx) @@ -1653,15 +1644,14 @@ static void __exit veth_module_cleanup(void) /* Disconnect our "irq" to stop events coming from the Hypervisor. */ HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); - /* Make sure any work queued from Hypervisor callbacks is finished. */ - flush_scheduled_work(); - for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) { cnx = veth_cnx[i]; if (!cnx) continue; + /* Cancel work queued from Hypervisor callbacks */ + cancel_delayed_work_sync(&cnx->statemachine_wq); /* Remove the connection from sysfs */ kobject_del(&cnx->kobject); /* Drop the driver's reference to the connection */ -- cgit v1.2.3-59-g8ed1b From 760141a53e5d72d4cc1d8c6e2a0232a24bedb36b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: igb[v],ixgbe: don't use flush_scheduled_work() All three drivers use flush_scheduled_work() similarly during driver detach. Replace it with explicit cancels. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: e1000-devel@lists.sourceforge.net Cc: netdev@vger.kernel.org --- drivers/net/igb/igb_main.c | 9 ++++++--- drivers/net/igbvf/netdev.c | 7 ++++--- drivers/net/ixgbe/ixgbe_main.c | 11 +++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 041f8e6f74f4..62348fc60e53 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2050,13 +2050,16 @@ static void __devexit igb_remove(struct pci_dev *pdev) struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - /* flush_scheduled work may reschedule our watchdog task, so - * explicitly disable watchdog tasks from being rescheduled */ + /* + * The watchdog timer may be rescheduled, so explicitly + * disable watchdog from being rescheduled. + */ set_bit(__IGB_DOWN, &adapter->state); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); - flush_scheduled_work(); + cancel_work_sync(&adapter->reset_task); + cancel_work_sync(&adapter->watchdog_task); #ifdef CONFIG_IGB_DCA if (adapter->flags & IGB_FLAG_DCA_ENABLED) { diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 8dbde2397c10..4fb023bce785 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -2825,13 +2825,14 @@ static void __devexit igbvf_remove(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; /* - * flush_scheduled work may reschedule our watchdog task, so - * explicitly disable watchdog tasks from being rescheduled + * The watchdog timer may be rescheduled, so explicitly + * disable it from being rescheduled. */ set_bit(__IGBVF_DOWN, &adapter->state); del_timer_sync(&adapter->watchdog_timer); - flush_scheduled_work(); + cancel_work_sync(&adapter->reset_task); + cancel_work_sync(&adapter->watchdog_task); unregister_netdev(netdev); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 8af0fc051696..ca9036de49f9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7373,13 +7373,15 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) struct net_device *netdev = adapter->netdev; set_bit(__IXGBE_DOWN, &adapter->state); - /* clear the module not found bit to make sure the worker won't - * reschedule + + /* + * The timers may be rescheduled, so explicitly disable them + * from being rescheduled. */ clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); del_timer_sync(&adapter->watchdog_timer); - del_timer_sync(&adapter->sfp_timer); + cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->sfp_task); cancel_work_sync(&adapter->multispeed_fiber_task); @@ -7387,7 +7389,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) cancel_work_sync(&adapter->fdir_reinit_task); - flush_scheduled_work(); + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + cancel_work_sync(&adapter->check_overtemp_task); #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { -- cgit v1.2.3-59-g8ed1b From fe8998c5e3b173f3d5c450bbde6173e7fbe5158d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: sungem: update gp->reset_task flushing gp->reset_task_pending is always set right before reset_task is scheduled and as there is no synchronization between the setting and scheduling, busy looping on reset_task_pending before flushing reset_task doesn't really buy anything. Directly flush gp->reset_task on suspend and cancel on detach. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: netdev@vger.kernel.org --- drivers/net/sungem.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 4ceb3cf6a9a9..9e992ca4f543 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2380,10 +2380,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) */ mutex_unlock(&gp->pm_mutex); - /* Wait for a pending reset task to complete */ - while (gp->reset_task_pending) - yield(); - flush_scheduled_work(); + /* Wait for the pending reset task to complete */ + flush_work_sync(&gp->reset_task); /* Shut the PHY down eventually and setup WOL */ gem_stop_phy(gp, gp->asleep_wol); @@ -2928,10 +2926,8 @@ static void gem_remove_one(struct pci_dev *pdev) /* We shouldn't need any locking here */ gem_get_cell(gp); - /* Wait for a pending reset task to complete */ - while (gp->reset_task_pending) - yield(); - flush_scheduled_work(); + /* Cancel reset task */ + cancel_work_sync(&gp->reset_task); /* Shut the PHY down */ gem_stop_phy(gp, 0); -- cgit v1.2.3-59-g8ed1b From 781ba4567698be9db7ca94d827c4b38d8583c168 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:14 +0100 Subject: i2400m: drop i2400m_schedule_work() i2400m implements dynamic work allocation and queueing mechanism in i2400_schedule_work(); however, this is only used for reset and recovery which can be served equally well with preallocated per device works. Replace i2400m_schedule_work() with two work structs in struct i2400m. These works are explicitly canceled when the device is released making calls to flush_scheduled_work(), which is being deprecated, unnecessary. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: Inaky Perez-Gonzalez Cc: linux-wimax@intel.com Cc: netdev@vger.kernel.org --- drivers/net/wimax/i2400m/driver.c | 96 +++++++-------------------------------- drivers/net/wimax/i2400m/i2400m.h | 19 ++------ drivers/net/wimax/i2400m/sdio.c | 1 - drivers/net/wimax/i2400m/usb.c | 1 - 4 files changed, 21 insertions(+), 96 deletions(-) diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index cdedab46ba21..f0603327aafa 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -92,54 +92,6 @@ MODULE_PARM_DESC(barkers, "signal; values are appended to a list--setting one value " "as zero cleans the existing list and starts a new one."); -static -struct i2400m_work *__i2400m_work_setup( - struct i2400m *i2400m, void (*fn)(struct work_struct *), - gfp_t gfp_flags, const void *pl, size_t pl_size) -{ - struct i2400m_work *iw; - - iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags); - if (iw == NULL) - return NULL; - iw->i2400m = i2400m_get(i2400m); - iw->pl_size = pl_size; - memcpy(iw->pl, pl, pl_size); - INIT_WORK(&iw->ws, fn); - return iw; -} - - -/* - * Schedule i2400m's specific work on the system's queue. - * - * Used for a few cases where we really need it; otherwise, identical - * to i2400m_queue_work(). - * - * Returns < 0 errno code on error, 1 if ok. - * - * If it returns zero, something really bad happened, as it means the - * works struct was already queued, but we have just allocated it, so - * it should not happen. - */ -static int i2400m_schedule_work(struct i2400m *i2400m, - void (*fn)(struct work_struct *), gfp_t gfp_flags, - const void *pl, size_t pl_size) -{ - int result; - struct i2400m_work *iw; - - result = -ENOMEM; - iw = __i2400m_work_setup(i2400m, fn, gfp_flags, pl, pl_size); - if (iw != NULL) { - result = schedule_work(&iw->ws); - if (WARN_ON(result == 0)) - result = -ENXIO; - } - return result; -} - - /* * WiMAX stack operation: relay a message from user space * @@ -648,17 +600,11 @@ EXPORT_SYMBOL_GPL(i2400m_post_reset); static void __i2400m_dev_reset_handle(struct work_struct *ws) { - int result; - struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws); - const char *reason; - struct i2400m *i2400m = iw->i2400m; + struct i2400m *i2400m = container_of(ws, struct i2400m, reset_ws); + const char *reason = i2400m->reset_reason; struct device *dev = i2400m_dev(i2400m); struct i2400m_reset_ctx *ctx = i2400m->reset_ctx; - - if (WARN_ON(iw->pl_size != sizeof(reason))) - reason = "SW BUG: reason n/a"; - else - memcpy(&reason, iw->pl, sizeof(reason)); + int result; d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason); @@ -733,8 +679,6 @@ void __i2400m_dev_reset_handle(struct work_struct *ws) } } out: - i2400m_put(i2400m); - kfree(iw); d_fnend(3, dev, "(ws %p i2400m %p reason %s) = void\n", ws, i2400m, reason); } @@ -754,8 +698,8 @@ out: */ int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason) { - return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, - GFP_ATOMIC, &reason, sizeof(reason)); + i2400m->reset_reason = reason; + return schedule_work(&i2400m->reset_ws); } EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle); @@ -768,14 +712,9 @@ EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle); static void __i2400m_error_recovery(struct work_struct *ws) { - struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws); - struct i2400m *i2400m = iw->i2400m; + struct i2400m *i2400m = container_of(ws, struct i2400m, recovery_ws); i2400m_reset(i2400m, I2400M_RT_BUS); - - i2400m_put(i2400m); - kfree(iw); - return; } /* @@ -805,18 +744,10 @@ void __i2400m_error_recovery(struct work_struct *ws) */ void i2400m_error_recovery(struct i2400m *i2400m) { - struct device *dev = i2400m_dev(i2400m); - - if (atomic_add_return(1, &i2400m->error_recovery) == 1) { - if (i2400m_schedule_work(i2400m, __i2400m_error_recovery, - GFP_ATOMIC, NULL, 0) < 0) { - dev_err(dev, "run out of memory for " - "scheduling an error recovery ?\n"); - atomic_dec(&i2400m->error_recovery); - } - } else + if (atomic_add_return(1, &i2400m->error_recovery) == 1) + schedule_work(&i2400m->recovery_ws); + else atomic_dec(&i2400m->error_recovery); - return; } EXPORT_SYMBOL_GPL(i2400m_error_recovery); @@ -886,6 +817,10 @@ void i2400m_init(struct i2400m *i2400m) mutex_init(&i2400m->init_mutex); /* wake_tx_ws is initialized in i2400m_tx_setup() */ + + INIT_WORK(&i2400m->reset_ws, __i2400m_dev_reset_handle); + INIT_WORK(&i2400m->recovery_ws, __i2400m_error_recovery); + atomic_set(&i2400m->bus_reset_retries, 0); i2400m->alive = 0; @@ -1040,6 +975,9 @@ void i2400m_release(struct i2400m *i2400m) i2400m_dev_stop(i2400m); + cancel_work_sync(&i2400m->reset_ws); + cancel_work_sync(&i2400m->recovery_ws); + i2400m_debugfs_rm(i2400m); sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj, &i2400m_dev_attr_group); @@ -1083,8 +1021,6 @@ module_init(i2400m_driver_init); static void __exit i2400m_driver_exit(void) { - /* for scheds i2400m_dev_reset_handle() */ - flush_scheduled_work(); i2400m_barker_db_exit(); } module_exit(i2400m_driver_exit); diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 59ac7705e76e..17ecaa41a807 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -632,6 +632,11 @@ struct i2400m { struct work_struct wake_tx_ws; struct sk_buff *wake_tx_skb; + struct work_struct reset_ws; + const char *reset_reason; + + struct work_struct recovery_ws; + struct dentry *debugfs_dentry; const char *fw_name; /* name of the current firmware image */ unsigned long fw_version; /* version of the firmware interface */ @@ -896,20 +901,6 @@ struct device *i2400m_dev(struct i2400m *i2400m) return i2400m->wimax_dev.net_dev->dev.parent; } -/* - * Helper for scheduling simple work functions - * - * This struct can get any kind of payload attached (normally in the - * form of a struct where you pack the stuff you want to pass to the - * _work function). - */ -struct i2400m_work { - struct work_struct ws; - struct i2400m *i2400m; - size_t pl_size; - u8 pl[0]; -}; - extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, char *, size_t); extern int i2400m_msg_size_check(struct i2400m *, diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c index 9bfc26e1bc6b..be428cae28d8 100644 --- a/drivers/net/wimax/i2400m/sdio.c +++ b/drivers/net/wimax/i2400m/sdio.c @@ -590,7 +590,6 @@ module_init(i2400ms_driver_init); static void __exit i2400ms_driver_exit(void) { - flush_scheduled_work(); /* for the stuff we schedule */ sdio_unregister_driver(&i2400m_sdio_driver); } module_exit(i2400ms_driver_exit); diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index d3365ac85dde..10e3ab352175 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -780,7 +780,6 @@ module_init(i2400mu_driver_init); static void __exit i2400mu_driver_exit(void) { - flush_scheduled_work(); /* for the stuff we schedule from sysfs.c */ usb_deregister(&i2400mu_driver); } module_exit(i2400mu_driver_exit); -- cgit v1.2.3-59-g8ed1b From 1635953305694ece16d99078ca6d32f3d4e7eb36 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Dec 2010 16:45:15 +0100 Subject: hostap: don't use flush_scheduled_work() flush_scheduled_work() is on its way out. Drop flush_scheduled_work() from prism2_free_local_data() and replace it with explicit flushing of work items on the respective free functions. Work items in ap_data are flushed from hostap_free_data() and the ones in local_info from prism2_free_local_data(). Flush is used instead of cancel as some process and free items from queue. Signed-off-by: Tejun Heo Cc: "David S. Miller" Cc: Jes Sorensen Cc: netdev@vger.kernel.org --- drivers/net/wireless/hostap/hostap_ap.c | 3 +++ drivers/net/wireless/hostap/hostap_hw.c | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index dbb986946e1a..18d63f57777d 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -858,7 +858,10 @@ void hostap_free_data(struct ap_data *ap) return; } + flush_work_sync(&ap->add_sta_proc_queue); + #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT + flush_work_sync(&ap->wds_oper_queue); if (ap->crypt) ap->crypt->deinit(ap->crypt_priv); ap->crypt = ap->crypt_priv = NULL; diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index b7cb165d612b..a8bddd81b4d1 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -3317,7 +3317,13 @@ static void prism2_free_local_data(struct net_device *dev) unregister_netdev(local->dev); - flush_scheduled_work(); + flush_work_sync(&local->reset_queue); + flush_work_sync(&local->set_multicast_list_queue); + flush_work_sync(&local->set_tim_queue); +#ifndef PRISM2_NO_STATION_MODES + flush_work_sync(&local->info_queue); +#endif + flush_work_sync(&local->comms_qual_update); lib80211_crypt_info_free(&local->crypt_info); -- cgit v1.2.3-59-g8ed1b From abbf46ae0e4954584eac599bec73502c1c805e9e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:14:46 -0800 Subject: ipv6: Use ip6_dst_hoplimit() instead of direct dst_metric() calls. Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6t_REJECT.c | 2 +- net/ipv6/route.c | 1 + net/ipv6/xfrm6_mode_tunnel.c | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 2933396e0281..bf998feac14e 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -124,7 +124,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) skb_reset_network_header(nskb); ip6h = ipv6_hdr(nskb); ip6h->version = 6; - ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT); + ip6h->hop_limit = ip6_dst_hoplimit(dst); ip6h->nexthdr = IPPROTO_TCP; ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4aed0812b512..9b2d7bc7beda 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1119,6 +1119,7 @@ int ip6_dst_hoplimit(struct dst_entry *dst) } return hoplimit; } +EXPORT_SYMBOL(ip6_dst_hoplimit); /* * diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index b809812c8d30..645cb968d450 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) if (x->props.flags & XFRM_STATE_NOECN) dsfield &= ~INET_ECN_MASK; ipv6_change_dsfield(top_iph, 0, dsfield); - top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); + top_iph->hop_limit = ip6_dst_hoplimit(dst->child); ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); return 0; -- cgit v1.2.3-59-g8ed1b From 5170ae824ddf1988a63fb12cbedcff817634c444 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:35:57 -0800 Subject: net: Abstract RTAX_HOPLIMIT metric accesses behind helper. Signed-off-by: David S. Miller --- drivers/net/pptp.c | 2 +- include/net/dst.h | 15 ++++++++++++++- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/netfilter/ipt_REJECT.c | 2 +- net/ipv4/route.c | 2 +- net/ipv4/xfrm4_mode_tunnel.c | 2 +- net/ipv6/route.c | 4 ++-- 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 7556a9224f72..c83e168eef21 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -277,7 +277,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) iph->tos = 0; iph->daddr = rt->rt_dst; iph->saddr = rt->rt_src; - iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT); + iph->ttl = dst_metric_hoplimit(&rt->dst); iph->tot_len = htons(skb->len); skb_dst_drop(skb); diff --git a/include/net/dst.h b/include/net/dst.h index 85dee3a57b9b..9208b500aaaf 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -104,11 +104,24 @@ struct dst_entry { #ifdef __KERNEL__ static inline u32 -dst_metric(const struct dst_entry *dst, int metric) +dst_metric_raw(const struct dst_entry *dst, const int metric) { return dst->_metrics[metric-1]; } +static inline u32 +dst_metric(const struct dst_entry *dst, const int metric) +{ + WARN_ON_ONCE(metric == RTAX_HOPLIMIT); + return dst_metric_raw(dst, metric); +} + +static inline u32 +dst_metric_hoplimit(const struct dst_entry *dst) +{ + return dst_metric_raw(dst, RTAX_HOPLIMIT); +} + static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index ff4e7a4e33ed..46eb3dc37ec6 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -890,7 +890,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; #endif else - iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT); + iph->ttl = dst_metric_hoplimit(&rt->dst); } ((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 5090c7ff525e..ea28fa5f1992 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -130,7 +130,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) int ttl = inet->uc_ttl; if (ttl < 0) - ttl = dst_metric(dst, RTAX_HOPLIMIT); + ttl = dst_metric_hoplimit(dst); return ttl; } diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 43eec80c0e7c..f1309072c541 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -116,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) if (ip_route_me_harder(nskb, addr_type)) goto free_nskb; - niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT); + niph->ttl = dst_metric_hoplimit(skb_dst(nskb)); /* "Never happens" */ if (nskb->len > dst_mtu(skb_dst(nskb))) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 26ac396eaa5e..90b5a37555ab 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1821,7 +1821,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) } else dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); - if (dst_metric(dst, RTAX_HOPLIMIT) == 0) + if (dst_metric_raw(dst, RTAX_HOPLIMIT) == 0) dst_metric_set(dst, RTAX_HOPLIMIT, sysctl_ip_default_ttl); if (dst_mtu(dst) > IP_MAX_MTU) dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 6f368413eb0e..63b854e74d99 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -56,7 +56,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); ip_select_ident(top_iph, dst->child, NULL); - top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); + top_iph->ttl = dst_metric_hoplimit(dst->child); top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9b2d7bc7beda..d9405d1863b8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1104,7 +1104,7 @@ static int ipv6_get_mtu(struct net_device *dev) int ip6_dst_hoplimit(struct dst_entry *dst) { - int hoplimit = dst_metric(dst, RTAX_HOPLIMIT); + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); if (hoplimit < 0) { struct net_device *dev = dst->dev; struct inet6_dev *idev; @@ -1310,7 +1310,7 @@ install_route: } } - if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0) + if (dst_metric_raw(&rt->dst, RTAX_HOPLIMIT) == 0) dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); if (!dst_mtu(&rt->dst)) dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); -- cgit v1.2.3-59-g8ed1b From a02e4b7dae455151c423e2f69ef222c502a321fd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:39:02 -0800 Subject: ipv6: Demark default hoplimit as zero. This is for consistency with ipv4. Using "-1" makes no sense. It was made this way a long time ago merely to be consistent with how the ipv6 socket hoplimit "default" is stored. Signed-off-by: David S. Miller --- net/ipv6/route.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d9405d1863b8..98796b0dc2b7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1105,7 +1105,7 @@ static int ipv6_get_mtu(struct net_device *dev) int ip6_dst_hoplimit(struct dst_entry *dst) { int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); - if (hoplimit < 0) { + if (hoplimit == 0) { struct net_device *dev = dst->dev; struct inet6_dev *idev; @@ -1310,8 +1310,6 @@ install_route: } } - if (dst_metric_raw(&rt->dst, RTAX_HOPLIMIT) == 0) - dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); if (!dst_mtu(&rt->dst)) dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); if (!dst_metric(&rt->dst, RTAX_ADVMSS)) -- cgit v1.2.3-59-g8ed1b From 323e126f0c5995f779d7df7fd035f6e8fed8764d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:55:08 -0800 Subject: ipv4: Don't pre-seed hoplimit metric. Always go through a new ip4_dst_hoplimit() helper, just like ipv6. This allowed several simplifications: 1) The interim dst_metric_hoplimit() can go as it's no longer userd. 2) The sysctl_ip_default_ttl entry no longer needs to use ipv4_doint_and_flush, since the sysctl is not cached in routing cache metrics any longer. 3) ipv4_doint_and_flush no longer needs to be exported and therefore can be marked static. When ipv4_doint_and_flush_strategy was removed some time ago, the external declaration in ip.h was mistakenly left around so kill that off too. We have to move the sysctl_ip_default_ttl declaration into ipv4's route cache definition header net/route.h, because currently net/ip.h (where the declaration lives now) has a back dependency on net/route.h Signed-off-by: David S. Miller --- drivers/net/pptp.c | 2 +- include/net/dst.h | 6 ------ include/net/ip.h | 10 ---------- include/net/route.h | 11 +++++++++++ net/ipv4/devinet.c | 6 +++--- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_output.c | 3 ++- net/ipv4/netfilter/ipt_REJECT.c | 2 +- net/ipv4/route.c | 2 -- net/ipv4/sysctl_net_ipv4.c | 2 +- net/ipv4/xfrm4_mode_tunnel.c | 2 +- 11 files changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index c83e168eef21..164cfad6ce79 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -277,7 +277,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) iph->tos = 0; iph->daddr = rt->rt_dst; iph->saddr = rt->rt_src; - iph->ttl = dst_metric_hoplimit(&rt->dst); + iph->ttl = ip4_dst_hoplimit(&rt->dst); iph->tot_len = htons(skb->len); skb_dst_drop(skb); diff --git a/include/net/dst.h b/include/net/dst.h index 9208b500aaaf..755ac6c1aa03 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -116,12 +116,6 @@ dst_metric(const struct dst_entry *dst, const int metric) return dst_metric_raw(dst, metric); } -static inline u32 -dst_metric_hoplimit(const struct dst_entry *dst) -{ - return dst_metric_raw(dst, RTAX_HOPLIMIT); -} - static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; diff --git a/include/net/ip.h b/include/net/ip.h index 86e2b182a0c0..67fac78a186b 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -201,7 +201,6 @@ static inline int inet_is_reserved_local_port(int port) return test_bit(port, sysctl_local_reserved_ports); } -extern int sysctl_ip_default_ttl; extern int sysctl_ip_nonlocal_bind; extern struct ctl_path net_core_path[]; @@ -428,15 +427,6 @@ extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, u32 info); -/* sysctl helpers - any sysctl which holds a value that ends up being - * fed into the routing cache should use these handlers. - */ -int ipv4_doint_and_flush(ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos); -int ipv4_doint_and_flush_strategy(ctl_table *table, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen); #ifdef CONFIG_PROC_FS extern int ip_misc_proc_init(void); #endif diff --git a/include/net/route.h b/include/net/route.h index b8c1f7703fc6..27002362944a 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -231,4 +231,15 @@ static inline int inet_iif(const struct sk_buff *skb) return skb_rtable(skb)->rt_iif; } +extern int sysctl_ip_default_ttl; + +static inline int ip4_dst_hoplimit(const struct dst_entry *dst) +{ + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); + + if (hoplimit == 0) + hoplimit = sysctl_ip_default_ttl; + return hoplimit; +} + #endif /* _ROUTE_H */ diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 3b067704ab38..748cb5b337bd 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1430,9 +1430,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, return ret; } -int ipv4_doint_and_flush(ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) +static int ipv4_doint_and_flush(ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) { int *valp = ctl->data; int val = *valp; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 46eb3dc37ec6..eb68a0e34e49 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -890,7 +890,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; #endif else - iph->ttl = dst_metric_hoplimit(&rt->dst); + iph->ttl = ip4_dst_hoplimit(&rt->dst); } ((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ea28fa5f1992..04c7b3ba6b39 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -82,6 +82,7 @@ #include int sysctl_ip_default_ttl __read_mostly = IPDEFTTL; +EXPORT_SYMBOL(sysctl_ip_default_ttl); /* Generate a checksum for an outgoing IP datagram. */ __inline__ void ip_send_check(struct iphdr *iph) @@ -130,7 +131,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) int ttl = inet->uc_ttl; if (ttl < 0) - ttl = dst_metric_hoplimit(dst); + ttl = ip4_dst_hoplimit(dst); return ttl; } diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index f1309072c541..1ff79e557f96 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -116,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) if (ip_route_me_harder(nskb, addr_type)) goto free_nskb; - niph->ttl = dst_metric_hoplimit(skb_dst(nskb)); + niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); /* "Never happens" */ if (nskb->len > dst_mtu(skb_dst(nskb))) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 90b5a37555ab..770f70427f0b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1821,8 +1821,6 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) } else dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); - if (dst_metric_raw(dst, RTAX_HOPLIMIT) == 0) - dst_metric_set(dst, RTAX_HOPLIMIT, sysctl_ip_default_ttl); if (dst_mtu(dst) > IP_MAX_MTU) dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); if (dst_metric(dst, RTAX_ADVMSS) == 0) diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 1b4ec21497a4..e85ff5930607 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -155,7 +155,7 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_ip_default_ttl, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = ipv4_doint_and_flush, + .proc_handler = proc_dointvec, .extra2 = &init_net, }, { diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 63b854e74d99..534972e114ac 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -56,7 +56,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); ip_select_ident(top_iph, dst->child, NULL); - top_iph->ttl = dst_metric_hoplimit(dst->child); + top_iph->ttl = ip4_dst_hoplimit(dst->child); top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; -- cgit v1.2.3-59-g8ed1b From 8c4877a4128e7931077b024a891a4b284d8756a3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 10:05:14 -0800 Subject: ehea: Use the standard logging functions Remove ehea_error, ehea_info and ehea_debug macros. Use pr_fmt, pr_, netdev_ and netif_ as appropriate. Fix messages to use trailing "\n", some messages had an extra one as the old ehea_ macros added a trailing "\n". Coalesced long format strings. Signed-off-by: Joe Perches Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 13 -- drivers/net/ehea/ehea_ethtool.c | 18 +- drivers/net/ehea/ehea_main.c | 415 ++++++++++++++++++++-------------------- drivers/net/ehea/ehea_phyp.c | 40 ++-- drivers/net/ehea/ehea_qmr.c | 89 ++++----- 5 files changed, 278 insertions(+), 297 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 1f2a675649b7..a724a2d14506 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -130,19 +130,6 @@ /* utility functions */ -#define ehea_info(fmt, args...) \ - printk(KERN_INFO DRV_NAME ": " fmt "\n", ## args) - -#define ehea_error(fmt, args...) \ - printk(KERN_ERR DRV_NAME ": Error in %s: " fmt "\n", __func__, ## args) - -#ifdef DEBUG -#define ehea_debug(fmt, args...) \ - printk(KERN_DEBUG DRV_NAME ": " fmt, ## args) -#else -#define ehea_debug(fmt, args...) do {} while (0) -#endif - void ehea_dump(void *adr, int len, char *msg); #define EHEA_BMASK(pos, length) (((pos) << 16) + (length)) diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 1f37ee6b2a26..afebf2075779 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ehea.h" #include "ehea_phyp.h" @@ -118,10 +120,10 @@ doit: ret = ehea_set_portspeed(port, sp); if (!ret) - ehea_info("%s: Port speed successfully set: %dMbps " - "%s Duplex", - port->netdev->name, port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + netdev_info(dev, + "Port speed successfully set: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); out: return ret; } @@ -134,10 +136,10 @@ static int ehea_nway_reset(struct net_device *dev) ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); if (!ret) - ehea_info("%s: Port speed successfully set: %dMbps " - "%s Duplex", - port->netdev->name, port->port_speed, - port->full_duplex == 1 ? "Full" : "Half"); + netdev_info(port->netdev, + "Port speed successfully set: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? "Full" : "Half"); return ret; } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 81e5b7b49e9e..0dfef6d76445 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -135,8 +137,8 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, - deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); + pr_info("%s adr=%p ofs=%04x %016llx %016llx\n", + msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } } @@ -336,7 +338,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) cb2 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb2) { - ehea_error("no mem for cb2"); + netdev_err(dev, "no mem for cb2\n"); goto out; } @@ -344,7 +346,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) port->logical_port_id, H_PORT_CB2, H_PORT_CB2_ALL, cb2); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + netdev_err(dev, "query_ehea_port failed\n"); goto out_herr; } @@ -399,7 +401,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) skb_arr_rq1[index] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); if (!skb_arr_rq1[index]) { - ehea_info("Unable to allocate enough skb in the array\n"); + netdev_info(dev, "Unable to allocate enough skb in the array\n"); pr->rq1_skba.os_skbs = fill_wqes - i; break; } @@ -423,14 +425,14 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a) int i; if (nr_rq1a > pr->rq1_skba.len) { - ehea_error("NR_RQ1A bigger than skb array len\n"); + netdev_err(dev, "NR_RQ1A bigger than skb array len\n"); return; } for (i = 0; i < nr_rq1a; i++) { skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); if (!skb_arr_rq1[i]) { - ehea_info("No enough memory to allocate skb array\n"); + netdev_info(dev, "Not enough memory to allocate skb array\n"); break; } } @@ -468,8 +470,9 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, if (!skb) { q_skba->os_skbs = fill_wqes - i; if (q_skba->os_skbs == q_skba->len - 2) { - ehea_info("%s: rq%i ran dry - no mem for skb", - pr->port->netdev->name, rq_nr); + netdev_info(pr->port->netdev, + "rq%i ran dry - no mem for skb\n", + rq_nr); ret = -ENOMEM; } break; @@ -634,8 +637,8 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) { if (netif_msg_rx_err(pr->port)) { - ehea_error("Critical receive error for QP %d. " - "Resetting port.", pr->qp->init_attr.qp_nr); + pr_err("Critical receive error for QP %d. Resetting port.\n", + pr->qp->init_attr.qp_nr); ehea_dump(cqe, sizeof(*cqe), "CQE"); } ehea_schedule_port_reset(pr->port); @@ -737,13 +740,13 @@ static int ehea_proc_rwqes(struct net_device *dev, skb_arr_rq1_len, wqe_index); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("LL rq1: skb=NULL"); + netif_err(port, rx_err, dev, + "LL rq1: skb=NULL\n"); skb = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); if (!skb) { - ehea_info("Not enough memory to allocate skb\n"); + netdev_info(dev, "Not enough memory to allocate skb\n"); break; } } @@ -755,8 +758,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq2, skb_arr_rq2_len, cqe); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("rq2: skb=NULL"); + netif_err(port, rx_err, dev, + "rq2: skb=NULL\n"); break; } ehea_fill_skb(dev, skb, cqe); @@ -766,8 +769,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = get_skb_by_index(skb_arr_rq3, skb_arr_rq3_len, cqe); if (unlikely(!skb)) { - if (netif_msg_rx_err(port)) - ehea_error("rq3: skb=NULL"); + netif_err(port, rx_err, dev, + "rq3: skb=NULL\n"); break; } ehea_fill_skb(dev, skb, cqe); @@ -839,7 +842,7 @@ static void check_sqs(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - ehea_error("HW/SW queues out of sync"); + pr_err("HW/SW queues out of sync\n"); ehea_schedule_port_reset(pr->port); return; } @@ -872,14 +875,14 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) } if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { - ehea_error("Bad send completion status=0x%04X", - cqe->status); + pr_err("Bad send completion status=0x%04X\n", + cqe->status); if (netif_msg_tx_err(pr->port)) ehea_dump(cqe, sizeof(*cqe), "Send CQE"); if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { - ehea_error("Resetting port"); + pr_err("Resetting port\n"); ehea_schedule_port_reset(pr->port); break; } @@ -997,8 +1000,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_error("QP aff_err: entry=0x%llx, token=0x%x", - eqe->entry, qp_token); + pr_err("QP aff_err: entry=0x%llx, token=0x%x\n", + eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1016,7 +1019,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) } if (reset_port) { - ehea_error("Resetting port"); + pr_err("Resetting port\n"); ehea_schedule_port_reset(port); } @@ -1044,7 +1047,7 @@ int ehea_sense_port_attr(struct ehea_port *port) /* may be called via ehea_neq_tasklet() */ cb0 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb0) { - ehea_error("no mem for cb0"); + pr_err("no mem for cb0\n"); ret = -ENOMEM; goto out; } @@ -1136,7 +1139,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - ehea_error("no mem for cb4"); + pr_err("no mem for cb4\n"); ret = -ENOMEM; goto out; } @@ -1187,16 +1190,16 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) break; } } else { - ehea_error("Failed sensing port speed"); + pr_err("Failed sensing port speed\n"); ret = -EIO; } } else { if (hret == H_AUTHORITY) { - ehea_info("Hypervisor denied setting port speed"); + pr_info("Hypervisor denied setting port speed\n"); ret = -EPERM; } else { ret = -EIO; - ehea_error("Failed setting port speed"); + pr_err("Failed setting port speed\n"); } } if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP)) @@ -1213,80 +1216,78 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) u8 ec; u8 portnum; struct ehea_port *port; + struct net_device *dev; ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe); portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe); port = ehea_get_port(adapter, portnum); + dev = port->netdev; switch (ec) { case EHEA_EC_PORTSTATE_CHG: /* port state change */ if (!port) { - ehea_error("unknown portnum %x", portnum); + netdev_err(dev, "unknown portnum %x\n", portnum); break; } if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { - if (!netif_carrier_ok(port->netdev)) { + if (!netif_carrier_ok(dev)) { ret = ehea_sense_port_attr(port); if (ret) { - ehea_error("failed resensing port " - "attributes"); + netdev_err(dev, "failed resensing port attributes\n"); break; } - if (netif_msg_link(port)) - ehea_info("%s: Logical port up: %dMbps " - "%s Duplex", - port->netdev->name, - port->port_speed, - port->full_duplex == - 1 ? "Full" : "Half"); + netif_info(port, link, dev, + "Logical port up: %dMbps %s Duplex\n", + port->port_speed, + port->full_duplex == 1 ? + "Full" : "Half"); - netif_carrier_on(port->netdev); - netif_wake_queue(port->netdev); + netif_carrier_on(dev); + netif_wake_queue(dev); } } else - if (netif_carrier_ok(port->netdev)) { - if (netif_msg_link(port)) - ehea_info("%s: Logical port down", - port->netdev->name); - netif_carrier_off(port->netdev); - netif_stop_queue(port->netdev); + if (netif_carrier_ok(dev)) { + netif_info(port, link, dev, + "Logical port down\n"); + netif_carrier_off(dev); + netif_stop_queue(dev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) { port->phy_link = EHEA_PHY_LINK_UP; - if (netif_msg_link(port)) - ehea_info("%s: Physical port up", - port->netdev->name); + netif_info(port, link, dev, + "Physical port up\n"); if (prop_carrier_state) - netif_carrier_on(port->netdev); + netif_carrier_on(dev); } else { port->phy_link = EHEA_PHY_LINK_DOWN; - if (netif_msg_link(port)) - ehea_info("%s: Physical port down", - port->netdev->name); + netif_info(port, link, dev, + "Physical port down\n"); if (prop_carrier_state) - netif_carrier_off(port->netdev); + netif_carrier_off(dev); } if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe)) - ehea_info("External switch port is primary port"); + netdev_info(dev, + "External switch port is primary port\n"); else - ehea_info("External switch port is backup port"); + netdev_info(dev, + "External switch port is backup port\n"); break; case EHEA_EC_ADAPTER_MALFUNC: - ehea_error("Adapter malfunction"); + netdev_err(dev, "Adapter malfunction\n"); break; case EHEA_EC_PORT_MALFUNC: - ehea_info("Port malfunction: Device: %s", port->netdev->name); - netif_carrier_off(port->netdev); - netif_stop_queue(port->netdev); + netdev_info(dev, "Port malfunction\n"); + netif_carrier_off(dev); + netif_stop_queue(dev); break; default: - ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); + netdev_err(dev, "unknown event code %x, eqe=0x%llX\n", ec, eqe); break; } } @@ -1298,13 +1299,13 @@ static void ehea_neq_tasklet(unsigned long data) u64 event_mask; eqe = ehea_poll_eq(adapter->neq); - ehea_debug("eqe=%p", eqe); + pr_debug("eqe=%p\n", eqe); while (eqe) { - ehea_debug("*eqe=%lx", eqe->entry); + pr_debug("*eqe=%lx\n", (unsigned long) eqe->entry); ehea_parse_eqe(adapter, eqe->entry); eqe = ehea_poll_eq(adapter->neq); - ehea_debug("next eqe=%p", eqe); + pr_debug("next eqe=%p\n", eqe); } event_mask = EHEA_BMASK_SET(NELR_PORTSTATE_CHG, 1) @@ -1353,14 +1354,14 @@ static int ehea_reg_interrupts(struct net_device *dev) ehea_qp_aff_irq_handler, IRQF_DISABLED, port->int_aff_name, port); if (ret) { - ehea_error("failed registering irq for qp_aff_irq_handler:" - "ist=%X", port->qp_eq->attr.ist1); + netdev_err(dev, "failed registering irq for qp_aff_irq_handler:ist=%X\n", + port->qp_eq->attr.ist1); goto out_free_qpeq; } - if (netif_msg_ifup(port)) - ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " - "registered", port->qp_eq->attr.ist1); + netif_info(port, ifup, dev, + "irq_handle 0x%X for function qp_aff_irq_handler registered\n", + port->qp_eq->attr.ist1); for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { @@ -1372,14 +1373,13 @@ static int ehea_reg_interrupts(struct net_device *dev) IRQF_DISABLED, pr->int_send_name, pr); if (ret) { - ehea_error("failed registering irq for ehea_queue " - "port_res_nr:%d, ist=%X", i, - pr->eq->attr.ist1); + netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n", + i, pr->eq->attr.ist1); goto out_free_req; } - if (netif_msg_ifup(port)) - ehea_info("irq_handle 0x%X for function ehea_queue_int " - "%d registered", pr->eq->attr.ist1, i); + netif_info(port, ifup, dev, + "irq_handle 0x%X for function ehea_queue_int %d registered\n", + pr->eq->attr.ist1, i); } out: return ret; @@ -1410,16 +1410,16 @@ static void ehea_free_interrupts(struct net_device *dev) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { pr = &port->port_res[i]; ibmebus_free_irq(pr->eq->attr.ist1, pr); - if (netif_msg_intr(port)) - ehea_info("free send irq for res %d with handle 0x%X", - i, pr->eq->attr.ist1); + netif_info(port, intr, dev, + "free send irq for res %d with handle 0x%X\n", + i, pr->eq->attr.ist1); } /* associated events */ ibmebus_free_irq(port->qp_eq->attr.ist1, port); - if (netif_msg_intr(port)) - ehea_info("associated event interrupt for handle 0x%X freed", - port->qp_eq->attr.ist1); + netif_info(port, intr, dev, + "associated event interrupt for handle 0x%X freed\n", + port->qp_eq->attr.ist1); } static int ehea_configure_port(struct ehea_port *port) @@ -1488,7 +1488,7 @@ int ehea_gen_smrs(struct ehea_port_res *pr) out_free: ehea_rem_mr(&pr->send_mr); out: - ehea_error("Generating SMRS failed\n"); + pr_err("Generating SMRS failed\n"); return -EIO; } @@ -1543,7 +1543,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); if (!pr->eq) { - ehea_error("create_eq failed (eq)"); + pr_err("create_eq failed (eq)\n"); goto out_free; } @@ -1551,7 +1551,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->recv_cq) { - ehea_error("create_cq failed (cq_recv)"); + pr_err("create_cq failed (cq_recv)\n"); goto out_free; } @@ -1559,19 +1559,19 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->eq->fw_handle, port->logical_port_id); if (!pr->send_cq) { - ehea_error("create_cq failed (cq_send)"); + pr_err("create_cq failed (cq_send)\n"); goto out_free; } if (netif_msg_ifup(port)) - ehea_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d", - pr->send_cq->attr.act_nr_of_cqes, - pr->recv_cq->attr.act_nr_of_cqes); + pr_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d\n", + pr->send_cq->attr.act_nr_of_cqes, + pr->recv_cq->attr.act_nr_of_cqes); init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL); if (!init_attr) { ret = -ENOMEM; - ehea_error("no mem for ehea_qp_init_attr"); + pr_err("no mem for ehea_qp_init_attr\n"); goto out_free; } @@ -1596,18 +1596,18 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->qp = ehea_create_qp(adapter, adapter->pd, init_attr); if (!pr->qp) { - ehea_error("create_qp failed"); + pr_err("create_qp failed\n"); ret = -EIO; goto out_free; } if (netif_msg_ifup(port)) - ehea_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n " - "nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d", init_attr->qp_nr, - init_attr->act_nr_send_wqes, - init_attr->act_nr_rwqes_rq1, - init_attr->act_nr_rwqes_rq2, - init_attr->act_nr_rwqes_rq3); + pr_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d\n", + init_attr->qp_nr, + init_attr->act_nr_send_wqes, + init_attr->act_nr_rwqes_rq1, + init_attr->act_nr_rwqes_rq2, + init_attr->act_nr_rwqes_rq3); pr->sq_skba_size = init_attr->act_nr_send_wqes + 1; @@ -1758,7 +1758,7 @@ static void write_swqe2_TSO(struct sk_buff *skb, swqe->descriptors++; } } else - ehea_error("cannot handle fragmented headers"); + pr_err("cannot handle fragmented headers\n"); } static void write_swqe2_nonTSO(struct sk_buff *skb, @@ -1854,8 +1854,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - ehea_error("%sregistering bc address failed (tagged)", - hcallid == H_REG_BCMC ? "" : "de"); + pr_err("%sregistering bc address failed (tagged)\n", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; goto out_herr; } @@ -1866,8 +1866,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) port->logical_port_id, reg_type, port->mac_addr, 0, hcallid); if (hret != H_SUCCESS) { - ehea_error("%sregistering bc address failed (vlan)", - hcallid == H_REG_BCMC ? "" : "de"); + pr_err("%sregistering bc address failed (vlan)\n", + hcallid == H_REG_BCMC ? "" : "de"); ret = -EIO; } out_herr: @@ -1889,7 +1889,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) cb0 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb0) { - ehea_error("no mem for cb0"); + pr_err("no mem for cb0\n"); ret = -ENOMEM; goto out; } @@ -1937,11 +1937,11 @@ out: static void ehea_promiscuous_error(u64 hret, int enable) { if (hret == H_AUTHORITY) - ehea_info("Hypervisor denied %sabling promiscuous mode", - enable == 1 ? "en" : "dis"); + pr_info("Hypervisor denied %sabling promiscuous mode\n", + enable == 1 ? "en" : "dis"); else - ehea_error("failed %sabling promiscuous mode", - enable == 1 ? "en" : "dis"); + pr_err("failed %sabling promiscuous mode\n", + enable == 1 ? "en" : "dis"); } static void ehea_promiscuous(struct net_device *dev, int enable) @@ -1955,7 +1955,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) cb7 = (void *)get_zeroed_page(GFP_ATOMIC); if (!cb7) { - ehea_error("no mem for cb7"); + pr_err("no mem for cb7\n"); goto out; } @@ -2015,7 +2015,7 @@ static int ehea_drop_multicast_list(struct net_device *dev) hret = ehea_multicast_reg_helper(port, mc_entry->macaddr, H_DEREG_BCMC); if (hret) { - ehea_error("failed deregistering mcast MAC"); + pr_err("failed deregistering mcast MAC\n"); ret = -EIO; } @@ -2038,7 +2038,8 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 1; else - ehea_error("failed enabling IFF_ALLMULTI"); + netdev_err(dev, + "failed enabling IFF_ALLMULTI\n"); } } else if (!enable) { @@ -2047,7 +2048,8 @@ static void ehea_allmulti(struct net_device *dev, int enable) if (!hret) port->allmulti = 0; else - ehea_error("failed disabling IFF_ALLMULTI"); + netdev_err(dev, + "failed disabling IFF_ALLMULTI\n"); } } @@ -2058,7 +2060,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); if (!ehea_mcl_entry) { - ehea_error("no mem for mcl_entry"); + pr_err("no mem for mcl_entry\n"); return; } @@ -2071,7 +2073,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) if (!hret) list_add(&ehea_mcl_entry->list, &port->mc_list->list); else { - ehea_error("failed registering mcast MAC"); + pr_err("failed registering mcast MAC\n"); kfree(ehea_mcl_entry); } } @@ -2104,9 +2106,8 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (netdev_mc_count(dev) > port->adapter->max_mc_mac) { - ehea_info("Mcast registration limit reached (0x%llx). " - "Use ALLMULTI!", - port->adapter->max_mc_mac); + pr_info("Mcast registration limit reached (0x%llx). Use ALLMULTI!\n", + port->adapter->max_mc_mac); goto out; } @@ -2312,10 +2313,10 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - if (netif_msg_tx_queued(port)) { - ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); + netif_info(port, tx_queued, dev, + "post swqe on QP %d\n", pr->qp->init_attr.qp_nr); + if (netif_msg_tx_queued(port)) ehea_dump(swqe, 512, "swqe"); - } if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { netif_stop_queue(dev); @@ -2351,14 +2352,14 @@ static void ehea_vlan_rx_register(struct net_device *dev, cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); free_page((unsigned long)cb1); out: @@ -2375,14 +2376,14 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + pr_err("query_ehea_port failed\n"); goto out; } @@ -2392,7 +2393,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); out: free_page((unsigned long)cb1); return; @@ -2410,14 +2411,14 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { - ehea_error("no mem for cb1"); + pr_err("no mem for cb1\n"); goto out; } hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) { - ehea_error("query_ehea_port failed"); + pr_err("query_ehea_port failed\n"); goto out; } @@ -2427,7 +2428,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, H_PORT_CB1, H_PORT_CB1_ALL, cb1); if (hret != H_SUCCESS) - ehea_error("modify_ehea_port failed"); + pr_err("modify_ehea_port failed\n"); out: free_page((unsigned long)cb1); } @@ -2449,7 +2450,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + pr_err("query_ehea_qp failed (1)\n"); goto out; } @@ -2458,14 +2459,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + pr_err("modify_ehea_qp failed (1)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + pr_err("query_ehea_qp failed (2)\n"); goto out; } @@ -2474,14 +2475,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (2)"); + pr_err("modify_ehea_qp failed (2)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (3)"); + pr_err("query_ehea_qp failed (3)\n"); goto out; } @@ -2490,14 +2491,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (3)"); + pr_err("modify_ehea_qp failed (3)\n"); goto out; } hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (4)"); + pr_err("query_ehea_qp failed (4)\n"); goto out; } @@ -2518,7 +2519,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps, EHEA_MAX_ENTRIES_EQ, 1); if (!port->qp_eq) { ret = -EINVAL; - ehea_error("ehea_create_eq failed (qp_eq)"); + pr_err("ehea_create_eq failed (qp_eq)\n"); goto out_kill_eq; } @@ -2599,27 +2600,27 @@ static int ehea_up(struct net_device *dev) ret = ehea_port_res_setup(port, port->num_def_qps, port->num_add_tx_qps); if (ret) { - ehea_error("port_res_failed"); + netdev_err(dev, "port_res_failed\n"); goto out; } /* Set default QP for this port */ ret = ehea_configure_port(port); if (ret) { - ehea_error("ehea_configure_port failed. ret:%d", ret); + netdev_err(dev, "ehea_configure_port failed. ret:%d\n", ret); goto out_clean_pr; } ret = ehea_reg_interrupts(dev); if (ret) { - ehea_error("reg_interrupts failed. ret:%d", ret); + netdev_err(dev, "reg_interrupts failed. ret:%d\n", ret); goto out_clean_pr; } for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { ret = ehea_activate_qp(port->adapter, port->port_res[i].qp); if (ret) { - ehea_error("activate_qp failed"); + netdev_err(dev, "activate_qp failed\n"); goto out_free_irqs; } } @@ -2627,7 +2628,7 @@ static int ehea_up(struct net_device *dev) for (i = 0; i < port->num_def_qps; i++) { ret = ehea_fill_port_res(&port->port_res[i]); if (ret) { - ehea_error("out_free_irqs"); + netdev_err(dev, "out_free_irqs\n"); goto out_free_irqs; } } @@ -2650,7 +2651,7 @@ out_clean_pr: ehea_clean_all_portres(port); out: if (ret) - ehea_info("Failed starting %s. ret=%i", dev->name, ret); + netdev_info(dev, "Failed starting. ret=%i\n", ret); ehea_update_bcmc_registrations(); ehea_update_firmware_handles(); @@ -2681,8 +2682,7 @@ static int ehea_open(struct net_device *dev) mutex_lock(&port->port_lock); - if (netif_msg_ifup(port)) - ehea_info("enabling port %s", dev->name); + netif_info(port, ifup, dev, "enabling port\n"); ret = ehea_up(dev); if (!ret) { @@ -2717,8 +2717,7 @@ static int ehea_down(struct net_device *dev) ret = ehea_clean_all_portres(port); if (ret) - ehea_info("Failed freeing resources for %s. ret=%i", - dev->name, ret); + netdev_info(dev, "Failed freeing resources. ret=%i\n", ret); ehea_update_firmware_handles(); @@ -2730,8 +2729,7 @@ static int ehea_stop(struct net_device *dev) int ret; struct ehea_port *port = netdev_priv(dev); - if (netif_msg_ifdown(port)) - ehea_info("disabling port %s", dev->name); + netif_info(port, ifdown, dev, "disabling port\n"); set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); cancel_work_sync(&port->reset_task); @@ -2772,7 +2770,7 @@ static void ehea_flush_sq(struct ehea_port *port) msecs_to_jiffies(100)); if (!ret) { - ehea_error("WARNING: sq not flushed completely"); + pr_err("WARNING: sq not flushed completely\n"); break; } } @@ -2808,7 +2806,7 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + pr_err("query_ehea_qp failed (1)\n"); goto out; } @@ -2820,7 +2818,7 @@ int ehea_stop_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + pr_err("modify_ehea_qp failed (1)\n"); goto out; } @@ -2828,14 +2826,14 @@ int ehea_stop_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + pr_err("query_ehea_qp failed (2)\n"); goto out; } /* deregister shared memory regions */ dret = ehea_rem_smrs(pr); if (dret) { - ehea_error("unreg shared memory region failed"); + pr_err("unreg shared memory region failed\n"); goto out; } } @@ -2904,7 +2902,7 @@ int ehea_restart_qps(struct net_device *dev) ret = ehea_gen_smrs(pr); if (ret) { - ehea_error("creation of shared memory regions failed"); + netdev_err(dev, "creation of shared memory regions failed\n"); goto out; } @@ -2915,7 +2913,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (1)"); + netdev_err(dev, "query_ehea_qp failed (1)\n"); goto out; } @@ -2927,7 +2925,7 @@ int ehea_restart_qps(struct net_device *dev) 1), cb0, &dummy64, &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { - ehea_error("modify_ehea_qp failed (1)"); + netdev_err(dev, "modify_ehea_qp failed (1)\n"); goto out; } @@ -2935,7 +2933,7 @@ int ehea_restart_qps(struct net_device *dev) EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); if (hret != H_SUCCESS) { - ehea_error("query_ehea_qp failed (2)"); + netdev_err(dev, "query_ehea_qp failed (2)\n"); goto out; } @@ -2972,8 +2970,7 @@ static void ehea_reset_port(struct work_struct *work) ehea_set_multicast_list(dev); - if (netif_msg_timer(port)) - ehea_info("Device %s resetted successfully", dev->name); + netif_info(port, timer, dev, "reset successful\n"); port_napi_enable(port); @@ -2988,7 +2985,7 @@ static void ehea_rereg_mrs(void) int ret, i; struct ehea_adapter *adapter; - ehea_info("LPAR memory changed - re-initializing driver"); + pr_info("LPAR memory changed - re-initializing driver\n"); list_for_each_entry(adapter, &adapter_list, list) if (adapter->active_ports) { @@ -3020,8 +3017,7 @@ static void ehea_rereg_mrs(void) /* Unregister old memory region */ ret = ehea_rem_mr(&adapter->mr); if (ret) { - ehea_error("unregister MR failed - driver" - " inoperable!"); + pr_err("unregister MR failed - driver inoperable!\n"); goto out; } } @@ -3033,8 +3029,7 @@ static void ehea_rereg_mrs(void) /* Register new memory region */ ret = ehea_reg_kernel_mr(adapter, &adapter->mr); if (ret) { - ehea_error("register MR failed - driver" - " inoperable!"); + pr_err("register MR failed - driver inoperable!\n"); goto out; } @@ -3057,7 +3052,7 @@ static void ehea_rereg_mrs(void) } } } - ehea_info("re-initializing driver complete"); + pr_info("re-initializing driver complete\n"); out: return; } @@ -3110,7 +3105,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo) /* (Try to) enable *jumbo frames */ cb4 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb4) { - ehea_error("no mem for cb4"); + pr_err("no mem for cb4\n"); ret = -ENOMEM; goto out; } else { @@ -3172,13 +3167,13 @@ static struct device *ehea_register_port(struct ehea_port *port, ret = of_device_register(&port->ofdev); if (ret) { - ehea_error("failed to register device. ret=%d", ret); + pr_err("failed to register device. ret=%d\n", ret); goto out; } ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); if (ret) { - ehea_error("failed to register attributes, ret=%d", ret); + pr_err("failed to register attributes, ret=%d\n", ret); goto out_unreg_of_dev; } @@ -3228,7 +3223,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev = alloc_etherdev(sizeof(struct ehea_port)); if (!dev) { - ehea_error("no mem for net_device"); + pr_err("no mem for net_device\n"); ret = -ENOMEM; goto out_err; } @@ -3282,7 +3277,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = register_netdev(dev); if (ret) { - ehea_error("register_netdev failed. ret=%d", ret); + pr_err("register_netdev failed. ret=%d\n", ret); goto out_unreg_port; } @@ -3290,11 +3285,10 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, ret = ehea_get_jumboframe_status(port, &jumbo); if (ret) - ehea_error("failed determining jumbo frame status for %s", - port->netdev->name); + netdev_err(dev, "failed determining jumbo frame status\n"); - ehea_info("%s: Jumbo frames are %sabled", dev->name, - jumbo == 1 ? "en" : "dis"); + netdev_info(dev, "Jumbo frames are %sabled\n", + jumbo == 1 ? "en" : "dis"); adapter->active_ports++; @@ -3310,8 +3304,8 @@ out_free_ethdev: free_netdev(dev); out_err: - ehea_error("setting up logical port with id=%d failed, ret=%d", - logical_port_id, ret); + pr_err("setting up logical port with id=%d failed, ret=%d\n", + logical_port_id, ret); return NULL; } @@ -3341,13 +3335,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", NULL); if (!dn_log_port_id) { - ehea_error("bad device node: eth_dn name=%s", - eth_dn->full_name); + pr_err("bad device node: eth_dn name=%s\n", + eth_dn->full_name); continue; } if (ehea_add_adapter_mr(adapter)) { - ehea_error("creating MR failed"); + pr_err("creating MR failed\n"); of_node_put(eth_dn); return -EIO; } @@ -3356,9 +3350,8 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) *dn_log_port_id, eth_dn); if (adapter->port[i]) - ehea_info("%s -> logical port id #%d", - adapter->port[i]->netdev->name, - *dn_log_port_id); + netdev_info(adapter->port[i]->netdev, + "logical port id #%d\n", *dn_log_port_id); else ehea_remove_adapter_mr(adapter); @@ -3403,21 +3396,20 @@ static ssize_t ehea_probe_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - ehea_info("adding port with logical port id=%d failed. port " - "already configured as %s.", logical_port_id, - port->netdev->name); + netdev_info(port->netdev, "adding port with logical port id=%d failed: port already configured\n", + logical_port_id); return -EINVAL; } eth_dn = ehea_get_eth_dn(adapter, logical_port_id); if (!eth_dn) { - ehea_info("no logical port with id %d found", logical_port_id); + pr_info("no logical port with id %d found\n", logical_port_id); return -EINVAL; } if (ehea_add_adapter_mr(adapter)) { - ehea_error("creating MR failed"); + pr_err("creating MR failed\n"); return -EIO; } @@ -3432,8 +3424,8 @@ static ssize_t ehea_probe_port(struct device *dev, break; } - ehea_info("added %s (logical port id=%d)", port->netdev->name, - logical_port_id); + netdev_info(port->netdev, "added: (logical port id=%d)\n", + logical_port_id); } else { ehea_remove_adapter_mr(adapter); return -EIO; @@ -3456,8 +3448,8 @@ static ssize_t ehea_remove_port(struct device *dev, port = ehea_get_port(adapter, logical_port_id); if (port) { - ehea_info("removed %s (logical port id=%d)", port->netdev->name, - logical_port_id); + netdev_info(port->netdev, "removed: (logical port id=%d)\n", + logical_port_id); ehea_shutdown_single_port(port); @@ -3467,8 +3459,8 @@ static ssize_t ehea_remove_port(struct device *dev, break; } } else { - ehea_error("removing port with logical port id=%d failed. port " - "not configured.", logical_port_id); + pr_err("removing port with logical port id=%d failed. port not configured.\n", + logical_port_id); return -EINVAL; } @@ -3505,7 +3497,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, int ret; if (!dev || !dev->dev.of_node) { - ehea_error("Invalid ibmebus device probed"); + pr_err("Invalid ibmebus device probed\n"); return -EINVAL; } @@ -3651,17 +3643,17 @@ static int ehea_mem_notifier(struct notifier_block *nb, switch (action) { case MEM_CANCEL_OFFLINE: - ehea_info("memory offlining canceled"); + pr_info("memory offlining canceled"); /* Readd canceled memory block */ case MEM_ONLINE: - ehea_info("memory is going online"); + pr_info("memory is going online"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; ehea_rereg_mrs(); break; case MEM_GOING_OFFLINE: - ehea_info("memory is going offline"); + pr_info("memory is going offline"); set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) goto out_unlock; @@ -3687,7 +3679,7 @@ static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { if (action == SYS_RESTART) { - ehea_info("Reboot: freeing all eHEA resources"); + pr_info("Reboot: freeing all eHEA resources\n"); ibmebus_unregister_driver(&ehea_driver); } return NOTIFY_DONE; @@ -3703,22 +3695,22 @@ static int check_module_parm(void) if ((rq1_entries < EHEA_MIN_ENTRIES_QP) || (rq1_entries > EHEA_MAX_ENTRIES_RQ1)) { - ehea_info("Bad parameter: rq1_entries"); + pr_info("Bad parameter: rq1_entries\n"); ret = -EINVAL; } if ((rq2_entries < EHEA_MIN_ENTRIES_QP) || (rq2_entries > EHEA_MAX_ENTRIES_RQ2)) { - ehea_info("Bad parameter: rq2_entries"); + pr_info("Bad parameter: rq2_entries\n"); ret = -EINVAL; } if ((rq3_entries < EHEA_MIN_ENTRIES_QP) || (rq3_entries > EHEA_MAX_ENTRIES_RQ3)) { - ehea_info("Bad parameter: rq3_entries"); + pr_info("Bad parameter: rq3_entries\n"); ret = -EINVAL; } if ((sq_entries < EHEA_MIN_ENTRIES_QP) || (sq_entries > EHEA_MAX_ENTRIES_SQ)) { - ehea_info("Bad parameter: sq_entries"); + pr_info("Bad parameter: sq_entries\n"); ret = -EINVAL; } @@ -3738,8 +3730,7 @@ int __init ehea_module_init(void) { int ret; - printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", - DRV_VERSION); + pr_info("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION); memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles)); memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); @@ -3757,27 +3748,27 @@ int __init ehea_module_init(void) ret = register_reboot_notifier(&ehea_reboot_nb); if (ret) - ehea_info("failed registering reboot notifier"); + pr_info("failed registering reboot notifier\n"); ret = register_memory_notifier(&ehea_mem_nb); if (ret) - ehea_info("failed registering memory remove notifier"); + pr_info("failed registering memory remove notifier\n"); ret = crash_shutdown_register(ehea_crash_handler); if (ret) - ehea_info("failed registering crash handler"); + pr_info("failed registering crash handler\n"); ret = ibmebus_register_driver(&ehea_driver); if (ret) { - ehea_error("failed registering eHEA device driver on ebus"); + pr_err("failed registering eHEA device driver on ebus\n"); goto out2; } ret = driver_create_file(&ehea_driver.driver, &driver_attr_capabilities); if (ret) { - ehea_error("failed to register capabilities attribute, ret=%d", - ret); + pr_err("failed to register capabilities attribute, ret=%d\n", + ret); goto out3; } @@ -3802,7 +3793,7 @@ static void __exit ehea_module_exit(void) unregister_reboot_notifier(&ehea_reboot_nb); ret = crash_shutdown_unregister(ehea_crash_handler); if (ret) - ehea_info("failed unregistering crash handler"); + pr_info("failed unregistering crash handler\n"); unregister_memory_notifier(&ehea_mem_nb); kfree(ehea_fw_handles.arr); kfree(ehea_bcmc_regs.arr); diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 8fe9dcaa7538..0506967b9044 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ehea_phyp.h" @@ -67,12 +69,11 @@ static long ehea_plpar_hcall_norets(unsigned long opcode, } if (ret < H_SUCCESS) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx ", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7); + pr_err("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx\n", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, arg6, arg7); return ret; } @@ -114,19 +115,18 @@ static long ehea_plpar_hcall9(unsigned long opcode, && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) && (arg3 == H_PORT_CB7_DUCQPN))))) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" - " arg9=%lx" - " out1=%lx out2=%lx out3=%lx out4=%lx" - " out5=%lx out6=%lx out7=%lx out8=%lx" - " out9=%lx", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9, - outs[0], outs[1], outs[2], outs[3], - outs[4], outs[5], outs[6], outs[7], - outs[8]); + pr_err("opcode=%lx ret=%lx" + " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" + " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" + " arg9=%lx" + " out1=%lx out2=%lx out3=%lx out4=%lx" + " out5=%lx out6=%lx out7=%lx out8=%lx" + " out9=%lx\n", + opcode, ret, + arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, + outs[0], outs[1], outs[2], outs[3], outs[4], + outs[5], outs[6], outs[7], outs[8]); return ret; } @@ -515,7 +515,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, const u64 log_pageaddr, const u64 count) { if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { - ehea_error("not on pageboundary"); + pr_err("not on pageboundary\n"); return H_PARAMETER; } diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 89128b6373e3..cd44bb8017d9 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "ehea.h" @@ -45,7 +47,7 @@ static void *hw_qpageit_get_inc(struct hw_queue *queue) queue->current_q_offset -= queue->pagesize; retvalue = NULL; } else if (((u64) retvalue) & (EHEA_PAGESIZE-1)) { - ehea_error("not on pageboundary"); + pr_err("not on pageboundary\n"); retvalue = NULL; } return retvalue; @@ -58,15 +60,15 @@ static int hw_queue_ctor(struct hw_queue *queue, const u32 nr_of_pages, int i, k; if ((pagesize > PAGE_SIZE) || (!pages_per_kpage)) { - ehea_error("pagesize conflict! kernel pagesize=%d, " - "ehea pagesize=%d", (int)PAGE_SIZE, (int)pagesize); + pr_err("pagesize conflict! kernel pagesize=%d, ehea pagesize=%d\n", + (int)PAGE_SIZE, (int)pagesize); return -EINVAL; } queue->queue_length = nr_of_pages * pagesize; queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL); if (!queue->queue_pages) { - ehea_error("no mem for queue_pages"); + pr_err("no mem for queue_pages\n"); return -ENOMEM; } @@ -130,7 +132,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq = kzalloc(sizeof(*cq), GFP_KERNEL); if (!cq) { - ehea_error("no mem for cq"); + pr_err("no mem for cq\n"); goto out_nomem; } @@ -147,7 +149,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_cq(adapter->handle, &cq->attr, &cq->fw_handle, &cq->epas); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_cq failed"); + pr_err("alloc_resource_cq failed\n"); goto out_freemem; } @@ -159,7 +161,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, for (counter = 0; counter < cq->attr.nr_pages; counter++) { vpage = hw_qpageit_get_inc(&cq->hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); goto out_kill_hwq; } @@ -168,9 +170,8 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, 0, EHEA_CQ_REGISTER_ORIG, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - ehea_error("register_rpage_cq failed ehea_cq=%p " - "hret=%llx counter=%i act_pages=%i", - cq, hret, counter, cq->attr.nr_pages); + pr_err("register_rpage_cq failed ehea_cq=%p hret=%llx counter=%i act_pages=%i\n", + cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -178,14 +179,14 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, vpage = hw_qpageit_get_inc(&cq->hw_queue); if ((hret != H_SUCCESS) || (vpage)) { - ehea_error("registration of pages not " - "complete hret=%llx\n", hret); + pr_err("registration of pages not complete hret=%llx\n", + hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { - ehea_error("CQ: registration of page failed " - "hret=%llx\n", hret); + pr_err("CQ: registration of page failed hret=%llx\n", + hret); goto out_kill_hwq; } } @@ -241,7 +242,7 @@ int ehea_destroy_cq(struct ehea_cq *cq) } if (hret != H_SUCCESS) { - ehea_error("destroy CQ failed"); + pr_err("destroy CQ failed\n"); return -EIO; } @@ -259,7 +260,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, eq = kzalloc(sizeof(*eq), GFP_KERNEL); if (!eq) { - ehea_error("no mem for eq"); + pr_err("no mem for eq\n"); return NULL; } @@ -272,21 +273,21 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_eq(adapter->handle, &eq->attr, &eq->fw_handle); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_eq failed"); + pr_err("alloc_resource_eq failed\n"); goto out_freemem; } ret = hw_queue_ctor(&eq->hw_queue, eq->attr.nr_pages, EHEA_PAGESIZE, sizeof(struct ehea_eqe)); if (ret) { - ehea_error("can't allocate eq pages"); + pr_err("can't allocate eq pages\n"); goto out_freeres; } for (i = 0; i < eq->attr.nr_pages; i++) { vpage = hw_qpageit_get_inc(&eq->hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); hret = H_RESOURCE; goto out_kill_hwq; } @@ -370,7 +371,7 @@ int ehea_destroy_eq(struct ehea_eq *eq) } if (hret != H_SUCCESS) { - ehea_error("destroy EQ failed"); + pr_err("destroy EQ failed\n"); return -EIO; } @@ -395,7 +396,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, for (cnt = 0; cnt < nr_pages; cnt++) { vpage = hw_qpageit_get_inc(hw_queue); if (!vpage) { - ehea_error("hw_qpageit_get_inc failed"); + pr_err("hw_qpageit_get_inc failed\n"); goto out_kill_hwq; } rpage = virt_to_abs(vpage); @@ -403,7 +404,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, 0, h_call_q_selector, qp->fw_handle, rpage, 1); if (hret < H_SUCCESS) { - ehea_error("register_rpage_qp failed"); + pr_err("register_rpage_qp failed\n"); goto out_kill_hwq; } } @@ -432,7 +433,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, qp = kzalloc(sizeof(*qp), GFP_KERNEL); if (!qp) { - ehea_error("no mem for qp"); + pr_err("no mem for qp\n"); return NULL; } @@ -441,7 +442,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, hret = ehea_h_alloc_resource_qp(adapter->handle, init_attr, pd, &qp->fw_handle, &qp->epas); if (hret != H_SUCCESS) { - ehea_error("ehea_h_alloc_resource_qp failed"); + pr_err("ehea_h_alloc_resource_qp failed\n"); goto out_freemem; } @@ -455,7 +456,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_sq, adapter, 0); if (ret) { - ehea_error("can't register for sq ret=%x", ret); + pr_err("can't register for sq ret=%x\n", ret); goto out_freeres; } @@ -465,7 +466,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq1, adapter, 1); if (ret) { - ehea_error("can't register for rq1 ret=%x", ret); + pr_err("can't register for rq1 ret=%x\n", ret); goto out_kill_hwsq; } @@ -476,7 +477,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq2, adapter, 2); if (ret) { - ehea_error("can't register for rq2 ret=%x", ret); + pr_err("can't register for rq2 ret=%x\n", ret); goto out_kill_hwr1q; } } @@ -488,7 +489,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, init_attr->act_wqe_size_enc_rq3, adapter, 3); if (ret) { - ehea_error("can't register for rq3 ret=%x", ret); + pr_err("can't register for rq3 ret=%x\n", ret); goto out_kill_hwr2q; } } @@ -553,7 +554,7 @@ int ehea_destroy_qp(struct ehea_qp *qp) } if (hret != H_SUCCESS) { - ehea_error("destroy QP failed"); + pr_err("destroy QP failed\n"); return -EIO; } @@ -842,7 +843,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, (hret != H_PAGE_REGISTERED)) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("register_rpage_mr failed"); + pr_err("register_rpage_mr failed\n"); return hret; } } @@ -896,7 +897,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) pt = (void *)get_zeroed_page(GFP_KERNEL); if (!pt) { - ehea_error("no mem"); + pr_err("no mem\n"); ret = -ENOMEM; goto out; } @@ -906,14 +907,14 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) &mr->handle, &mr->lkey); if (hret != H_SUCCESS) { - ehea_error("alloc_resource_mr failed"); + pr_err("alloc_resource_mr failed\n"); ret = -EIO; goto out; } if (!ehea_bmap) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("no busmap available"); + pr_err("no busmap available\n"); ret = -EIO; goto out; } @@ -929,7 +930,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) if (hret != H_SUCCESS) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); - ehea_error("registering mr failed"); + pr_err("registering mr failed\n"); ret = -EIO; goto out; } @@ -952,7 +953,7 @@ int ehea_rem_mr(struct ehea_mr *mr) hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, FORCE_FREE); if (hret != H_SUCCESS) { - ehea_error("destroy MR failed"); + pr_err("destroy MR failed\n"); return -EIO; } @@ -987,14 +988,14 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == EHEA_AER_RESTYPE_QP) - ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " - "port=%llX", resource, data[6], data[12], data[22]); + pr_err("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, port=%llX\n", + resource, data[6], data[12], data[22]); else if (type == EHEA_AER_RESTYPE_CQ) - ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, - data[6]); + pr_err("CQ (resource=%llX) state: AER=0x%llX\n", + resource, data[6]); else if (type == EHEA_AER_RESTYPE_EQ) - ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, - data[6]); + pr_err("EQ (resource=%llX) state: AER=0x%llX\n", + resource, data[6]); ehea_dump(data, length, "error data"); } @@ -1008,7 +1009,7 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, rblock = (void *)get_zeroed_page(GFP_KERNEL); if (!rblock) { - ehea_error("Cannot allocate rblock memory."); + pr_err("Cannot allocate rblock memory\n"); goto out; } @@ -1020,9 +1021,9 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, *aerr = rblock[12]; print_error_data(rblock); } else if (ret == H_R_STATE) { - ehea_error("No error data available: %llX.", res_handle); + pr_err("No error data available: %llX\n", res_handle); } else - ehea_error("Error data could not be fetched: %llX", res_handle); + pr_err("Error data could not be fetched: %llX\n", res_handle); free_page((unsigned long)rblock); out: -- cgit v1.2.3-59-g8ed1b From 249fab773dd5f689318c969ed649c4db077cdfc3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 13 Dec 2010 12:16:14 -0800 Subject: net: add limits to ip_default_ttl ip_default_ttl should be between 1 and 255 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/sysctl_net_ipv4.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e85ff5930607..1a456652086b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -28,6 +28,8 @@ static int ip_local_port_range_min[] = { 1, 1 }; static int ip_local_port_range_max[] = { 65535, 65535 }; static int tcp_adv_win_scale_min = -31; static int tcp_adv_win_scale_max = 31; +static int ip_ttl_min = 1; +static int ip_ttl_max = 255; /* Update system visible IP port range */ static void set_local_port_range(int range[2]) @@ -155,8 +157,9 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_ip_default_ttl, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, - .extra2 = &init_net, + .proc_handler = proc_dointvec_minmax, + .extra1 = &ip_ttl_min, + .extra2 = &ip_ttl_max, }, { .procname = "ip_no_pmtu_disc", -- cgit v1.2.3-59-g8ed1b From c2731b814e2aaaa40072ee761b7373c052d86e37 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 7 Dec 2010 15:13:19 -0800 Subject: ath9k: Fix power save count imbalance on ath_radio_enable() Upon a failure we never call ath9k_ps_restore() on ath_radio_enable(), this will throw off the sc->ps_usecount. When the sc->ps_usecount is > 0 we never put the chip to full sleep. This drains battery, and will also make the chip fail upon resume with: ath: Starting driver with initial channel: 5745 MHz ath: timeout (100000 us) on reg 0x7000: 0xdeadbeef & 0x00000003 != 0x00000000 This would make the chip useless upon resume. I cannot prove this can happen but in theory it is so best to avoid this race completely and not have users complain about a broken device after resume. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index daa3c9feca66..ef298f41ab4a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -900,8 +900,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ath_update_txpow(sc); if (ath_startrecv(sc) != 0) { ath_err(common, "Unable to restart recv logic\n"); - spin_unlock_bh(&sc->sc_pcu_lock); - return; + goto out; } if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); /* restart beacons */ @@ -915,6 +914,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_set_gpio(ah, ah->led_pin, 0); ieee80211_wake_queues(hw); +out: spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); -- cgit v1.2.3-59-g8ed1b From a08e7ade9ddf4fe79576f953cc5c1725e944d26c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 7 Dec 2010 15:13:20 -0800 Subject: ath9k: fix assumptions for idle calls on suspend/resume mac80211 will notify drivers when to go idle and ath9k assumed that it would get further notifications for idle states after a device stop() config call but as per agreed semantics the idle state of the radio is left up to driver after mac80211 issues the stop() callback. The driver is resposnbile for ensuring the device remains idle after that even between suspend / resume calls. This fixes suspend/resume when you issue suspend and resume twice on ath9k when ath9k_stop() was already called. We need to put the radio to full sleep in order for resume to work correctly. What might seem fishy is we are turning the radio off after resume. The reason why we do this is because we know we should not have anything enabled after a mac80211 tells us to stop(), if we resume and never get a start() we won't get another stop() by mac80211 so to be safe always bring the 802.11 device with the radio disabled after resume, this ensures that if we suspend we already have the radio disabled and only a start() will ever trigger it on. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- drivers/net/wireless/ath/ath9k/pci.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ef298f41ab4a..ef87637e4245 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1333,8 +1333,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_ps_restore(sc); - /* Finally, put the chip in FULL SLEEP mode */ - ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); + sc->ps_idle = true; + ath_radio_disable(sc, hw); sc->sc_flags |= SC_OP_INVALID; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 747b2871e48f..7ca8499249ec 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -309,6 +309,9 @@ static int ath_pci_resume(struct device *device) AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + sc->ps_idle = true; + ath_radio_disable(sc, hw); + return 0; } -- cgit v1.2.3-59-g8ed1b From a7ffac9591a2a0ee74c431396ae475a8d0caa51e Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Dec 2010 13:59:24 +0900 Subject: cfg80211: Add antenna availability information Add a field to wiphy for the hardware to report the availble antennas for configuration. Only if this is set to something bigger than zero, will the anntenna configuration ops be executed. Allthough this could be a simple number of antennas, I defined it as a bitmap of antennas which are available for configuration, since it's more consistent with the rest of the antenna API and there could be cases where the hardware allows only configuration of certain antennas. As it does not make much of a difference in size or normal usage, I think it's better to be able to support this, in case the need arises. The antenna configuration is now also checked against the availabe antennas and rejected if it does not match. Signed-off-by: Bruno Randolf -- v3: always apply available antenna mask (for "all" antennas case). v2: reject antenna configurations which don't match the available antennas Signed-off-by: John W. Linville --- include/net/cfg80211.h | 5 +++++ net/wireless/nl80211.c | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0d5979924be3..4d5acb013636 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1468,6 +1468,9 @@ struct ieee80211_txrx_stypes { * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or * transmitted through nl80211, points to an array indexed by interface * type + * + * @available_antennas: bitmap of antennas which are available to configure. + * antenna configuration commands will be rejected unless this is set. */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1507,6 +1510,8 @@ struct wiphy { u8 max_num_pmkids; + u32 available_antennas; + /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't * know whether it points to a wiphy your driver has registered diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c3f80e565365..73a7f6d354c9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -548,7 +548,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); - if (dev->ops->get_antenna) { + if (dev->wiphy.available_antennas && dev->ops->get_antenna) { u32 tx_ant = 0, rx_ant = 0; int res; res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); @@ -1046,7 +1046,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { u32 tx_ant, rx_ant; - if (!rdev->ops->set_antenna) { + if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) { result = -EOPNOTSUPP; goto bad_res; } @@ -1054,6 +1054,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); + /* reject antenna configurations which don't match the + * available antenna mask, except for the "all" mask */ + if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas)) || + (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas))) { + result = -EINVAL; + goto bad_res; + } + + tx_ant = tx_ant & rdev->wiphy.available_antennas; + rx_ant = rx_ant & rdev->wiphy.available_antennas; + result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); if (result) goto bad_res; -- cgit v1.2.3-59-g8ed1b From 6b3b991dbdb66a65a2167abbd9503e519fa999f3 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 8 Dec 2010 19:38:55 +0530 Subject: ath9k: Add change_interface callback Add support to change interface type without bringing down the interface. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 90 +++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ef87637e4245..ca35aaa7aec6 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1428,13 +1428,78 @@ out: return ret; } +static void ath9k_reclaim_beacon(struct ath_softc *sc, + struct ieee80211_vif *vif) +{ + struct ath_vif *avp = (void *)vif->drv_priv; + + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + tasklet_kill(&sc->bcon_tasklet); + ath9k_ps_restore(sc); + + ath_beacon_return(sc, avp); + sc->sc_flags &= ~SC_OP_BEACONS; + + if (sc->nbcnvifs > 0) { + /* Re-enable beaconing */ + sc->sc_ah->imask |= ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_ps_restore(sc); + } +} + +static int ath9k_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype new_type, + bool p2p) +{ + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); + mutex_lock(&sc->mutex); + + switch (new_type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + if (sc->nbcnvifs >= ATH_BCBUF) { + ath_err(common, "No beacon slot available\n"); + return -ENOBUFS; + } + break; + case NL80211_IFTYPE_STATION: + /* Stop ANI */ + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); + if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) + ath9k_reclaim_beacon(sc, vif); + break; + default: + ath_err(common, "Interface type %d not yet supported\n", + vif->type); + mutex_unlock(&sc->mutex); + return -ENOTSUPP; + } + vif->type = new_type; + vif->p2p = p2p; + + mutex_unlock(&sc->mutex); + return 0; +} + static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_vif *avp = (void *)vif->drv_priv; ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); @@ -1447,26 +1512,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, /* Reclaim beacon resources */ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { - /* Disable SWBA interrupt */ - sc->sc_ah->imask &= ~ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - ath9k_ps_restore(sc); - tasklet_kill(&sc->bcon_tasklet); - } - - ath_beacon_return(sc, avp); - sc->sc_flags &= ~SC_OP_BEACONS; - - if (sc->nbcnvifs) { - /* Re-enable SWBA interrupt */ - sc->sc_ah->imask |= ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_ps_restore(sc); - } + (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) + ath9k_reclaim_beacon(sc, vif); sc->nvifs--; @@ -2111,6 +2158,7 @@ struct ieee80211_ops ath9k_ops = { .start = ath9k_start, .stop = ath9k_stop, .add_interface = ath9k_add_interface, + .change_interface = ath9k_change_interface, .remove_interface = ath9k_remove_interface, .config = ath9k_config, .configure_filter = ath9k_configure_filter, -- cgit v1.2.3-59-g8ed1b From 998d516d9546eba04dd99ae49a78acb0cf770478 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 8 Dec 2010 20:01:05 +0530 Subject: ath: Missed to clear key4 of micentry key4 of micentry is used, if ATH_CRYPT_CAP_MIC_COMBINED is set. But is not cleared on key cache reset. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/key.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 29a2961af5fc..5d465e5fcf24 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -58,6 +58,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) + REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); } -- cgit v1.2.3-59-g8ed1b From 01123e233193a544c85b622e1690f44532052c5b Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 9 Dec 2010 15:05:24 +0100 Subject: cfg80211: update information elements in cached BSS struct When a cached BSS struct is updated because a new beacon was received, the code replaces the cached information elements by the IEs from the new beacon. However it did not update the pub.information_elements and pub.len_information_elements fields leaving them either pointing to the old beacon IEs or in an inconsistent state where the data is replaced by the new beacon IEs but len_information_elements still has its value from the first beacon. Fix this by updating the information elements fields if they are pointing to beacon IEs. Signed-off-by: Sven Neumann Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/scan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 503ebb86ba18..ea427f418f64 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, if (res->pub.beacon_ies) { size_t used = dev->wiphy.bss_priv_size + sizeof(*res); size_t ielen = res->pub.len_beacon_ies; + bool information_elements_is_beacon_ies = + (found->pub.information_elements == + found->pub.beacon_ies); if (found->pub.beacon_ies && !found->beacon_ies_allocated && @@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, found->pub.len_beacon_ies = ielen; } } + + /* Override IEs if they were from a beacon before */ + if (information_elements_is_beacon_ies) { + found->pub.information_elements = + found->pub.beacon_ies; + found->pub.len_information_elements = + found->pub.len_beacon_ies; + } } kref_put(&res->ref, bss_release); -- cgit v1.2.3-59-g8ed1b From f33fdcf1b3a02fb92971a577d194ec6c579374af Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 9 Dec 2010 21:48:54 +0530 Subject: ath9k: clean up hardware code for beacon handling The registers TBTT_TIMER ,DMA_BEACON_ALERT ,NEXT_SWBA are need to be configured only for AP and IBSS mode. SWBA register is used for generating software interrupts so that beacon frames will be created by the software.DMA beacon alert register is to indicate the hardware to DMA the contents of beacon buffer to PCU buffer and TBTT to start transmitting the packet buffer to the base band. Clearly these things are not needed for station/monitor mode so remove configuring them. Cc: doug dahlby Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 516227fa668e..1beb89673b0c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1632,12 +1632,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) ENABLE_REGWRITE_BUFFER(ah); switch (ah->opmode) { - case NL80211_IFTYPE_STATION: - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); - REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); - flags |= AR_TBTT_TIMER_EN; - break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: REG_SET_BIT(ah, AR_TXCFG, @@ -1661,14 +1655,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; break; default: - if (ah->is_monitoring) { - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, - TU_TO_USEC(next_beacon)); - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); - REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); - flags |= AR_TBTT_TIMER_EN; - break; - } ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON, "%s: unsupported opmode: %d\n", __func__, ah->opmode); -- cgit v1.2.3-59-g8ed1b From 897bed8b4320774e56f282cdc1cceb4d77442797 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Dec 2010 19:49:00 +0100 Subject: mac80211: clean up RX key checks Using the default key for "any key set" isn't quite what we should do. It works, but with the upcoming changes it makes life unnecessarily complex, so do something better here and really check for "any key". Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2fe8f5f86499..052789ef4745 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -955,12 +955,31 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) * have been expected. */ struct ieee80211_key *key = NULL; + struct ieee80211_sub_if_data *sdata = rx->sdata; + int i; + if (ieee80211_is_mgmt(fc) && is_multicast_ether_addr(hdr->addr1) && (key = rcu_dereference(rx->sdata->default_mgmt_key))) rx->key = key; - else if ((key = rcu_dereference(rx->sdata->default_key))) - rx->key = key; + else { + if (rx->sta) { + for (i = 0; i < NUM_DEFAULT_KEYS; i++) { + key = rcu_dereference(rx->sta->gtk[i]); + if (key) + break; + } + } + if (!key) { + for (i = 0; i < NUM_DEFAULT_KEYS; i++) { + key = rcu_dereference(sdata->keys[i]); + if (key) + break; + } + } + if (key) + rx->key = key; + } return RX_CONTINUE; } else { u8 keyid; -- cgit v1.2.3-59-g8ed1b From dbd2fd656f2060abfd3a16257f8b51ec60f6d2ed Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Dec 2010 19:58:59 +0100 Subject: cfg80211/nl80211: separate unicast/multicast default TX keys Allow userspace to specify that a given key is default only for unicast and/or multicast transmissions. Only WEP keys are for both, WPA/RSN keys set here are GTKs for multicast only. For more future flexibility, allow to specify all combiations. Wireless extensions can only set both so use nl80211; WEP keys (connect keys) must be set as default for both (but 802.1X WEP is still possible). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 3 +- drivers/net/wireless/libertas/cfg.c | 3 +- drivers/net/wireless/rndis_wlan.c | 4 +- include/linux/nl80211.h | 27 ++++++ include/net/cfg80211.h | 5 +- net/mac80211/cfg.c | 3 +- net/wireless/nl80211.c | 125 +++++++++++++++++++++++---- net/wireless/util.c | 3 +- net/wireless/wext-compat.c | 8 +- 9 files changed, 152 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index c6c0eff9b5ed..5a4982271e96 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index) + u8 key_index, bool unicast, + bool multicast) { struct iwm_priv *iwm = ndev_to_iwm(ndev); diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index dee32d3681a5..300be1931826 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1422,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev, static int lbs_cfg_set_default_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index) + u8 key_index, bool unicast, + bool multicast) { struct lbs_private *priv = wiphy_priv(wiphy); diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 19f3d568f700..4a4f00591447 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -554,7 +554,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr); static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index); + u8 key_index, bool unicast, bool multicast); static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo); @@ -2381,7 +2381,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, } static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index) + u8 key_index, bool unicast, bool multicast) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 380421253d16..b8fa25d741ba 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -851,6 +851,10 @@ enum nl80211_commands { * * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) * + * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags + * attributes, specifying what a key should be set as default as. + * See &enum nl80211_key_default_types. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1029,6 +1033,8 @@ enum nl80211_attrs { NL80211_ATTR_BSS_HT_OPMODE, + NL80211_ATTR_KEY_DEFAULT_TYPES, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1774,6 +1780,23 @@ enum nl80211_wpa_versions { NL80211_WPA_VERSION_2 = 1 << 1, }; +/** + * enum nl80211_key_default_types - key default types + * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid + * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default + * unicast key + * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default + * multicast key + * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types + */ +enum nl80211_key_default_types { + __NL80211_KEY_DEFAULT_TYPE_INVALID, + NL80211_KEY_DEFAULT_TYPE_UNICAST, + NL80211_KEY_DEFAULT_TYPE_MULTICAST, + + NUM_NL80211_KEY_DEFAULT_TYPES +}; + /** * enum nl80211_key_attributes - key attributes * @__NL80211_KEY_INVALID: invalid @@ -1790,6 +1813,9 @@ enum nl80211_wpa_versions { * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not * specified the default depends on whether a MAC address was * given with the command using the key or not (u32) + * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags + * attributes, specifying what a key should be set as default as. + * See &enum nl80211_key_default_types. * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ @@ -1802,6 +1828,7 @@ enum nl80211_key_attributes { NL80211_KEY_DEFAULT, NL80211_KEY_DEFAULT_MGMT, NL80211_KEY_TYPE, + NL80211_KEY_DEFAULT_TYPES, /* keep last */ __NL80211_KEY_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4d5acb013636..22be7c625b70 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1211,7 +1211,7 @@ struct cfg80211_ops { u8 key_index, bool pairwise, const u8 *mac_addr); int (*set_default_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index); + u8 key_index, bool unicast, bool multicast); int (*set_default_mgmt_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -1393,6 +1393,8 @@ struct cfg80211_ops { * control port protocol ethertype. The device also honours the * control_port_no_encrypt flag. * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. + * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate + * unicast and multicast TX keys. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1404,6 +1406,7 @@ enum wiphy_flags { WIPHY_FLAG_4ADDR_STATION = BIT(6), WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), WIPHY_FLAG_IBSS_RSN = BIT(8), + WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), }; struct mac_address { diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c30b8b72eedb..12f7dc048d34 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -295,7 +295,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx) + u8 key_idx, bool uni, + bool multi) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 73a7f6d354c9..53f044370cde 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -171,6 +171,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, + [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, }; /* policy for the key attributes */ @@ -182,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, [NL80211_KEY_TYPE] = { .type = NLA_U32 }, + [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, +}; + +/* policy for the key default flags */ +static const struct nla_policy +nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = { + [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG }, + [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, }; /* ifidx get helper */ @@ -314,6 +323,7 @@ struct key_parse { int idx; int type; bool def, defmgmt; + bool def_uni, def_multi; }; static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) @@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) k->def = !!tb[NL80211_KEY_DEFAULT]; k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; + if (k->def) { + k->def_uni = true; + k->def_multi = true; + } + if (k->defmgmt) + k->def_multi = true; + if (tb[NL80211_KEY_IDX]) k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); @@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) return -EINVAL; } + if (tb[NL80211_KEY_DEFAULT_TYPES]) { + struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; + int err = nla_parse_nested(kdt, + NUM_NL80211_KEY_DEFAULT_TYPES - 1, + tb[NL80211_KEY_DEFAULT_TYPES], + nl80211_key_default_policy); + if (err) + return err; + + k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; + k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; + } + return 0; } @@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k) k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; + if (k->def) { + k->def_uni = true; + k->def_multi = true; + } + if (k->defmgmt) + k->def_multi = true; + if (info->attrs[NL80211_ATTR_KEY_TYPE]) { k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) return -EINVAL; } + if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) { + struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; + int err = nla_parse_nested( + kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1, + info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES], + nl80211_key_default_policy); + if (err) + return err; + + k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; + k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; + } + return 0; } @@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) if (k->def && k->defmgmt) return -EINVAL; + if (k->defmgmt) { + if (k->def_uni || !k->def_multi) + return -EINVAL; + } + if (k->idx != -1) { if (k->defmgmt) { if (k->idx < 4 || k->idx > 5) @@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, goto error; def = 1; result->def = parse.idx; + if (!parse.def_uni || !parse.def_multi) + goto error; } else if (parse.defmgmt) goto error; err = cfg80211_validate_key_settings(rdev, &parse.p, @@ -1586,8 +1643,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) struct key_parse key; int err; struct net_device *dev = info->user_ptr[1]; - int (*func)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index); err = nl80211_parse_key(info, &key); if (err) @@ -1600,27 +1655,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) if (!key.def && !key.defmgmt) return -EINVAL; - if (key.def) - func = rdev->ops->set_default_key; - else - func = rdev->ops->set_default_mgmt_key; + wdev_lock(dev->ieee80211_ptr); - if (!func) - return -EOPNOTSUPP; + if (key.def) { + if (!rdev->ops->set_default_key) { + err = -EOPNOTSUPP; + goto out; + } - wdev_lock(dev->ieee80211_ptr); - err = nl80211_key_allowed(dev->ieee80211_ptr); - if (!err) - err = func(&rdev->wiphy, dev, key.idx); + err = nl80211_key_allowed(dev->ieee80211_ptr); + if (err) + goto out; + + if (!(rdev->wiphy.flags & + WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) { + if (!key.def_uni || !key.def_multi) { + err = -EOPNOTSUPP; + goto out; + } + } + + err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, + key.def_uni, key.def_multi); + + if (err) + goto out; #ifdef CONFIG_CFG80211_WEXT - if (!err) { - if (func == rdev->ops->set_default_key) - dev->ieee80211_ptr->wext.default_key = key.idx; - else - dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; - } + dev->ieee80211_ptr->wext.default_key = key.idx; +#endif + } else { + if (key.def_uni || !key.def_multi) { + err = -EINVAL; + goto out; + } + + if (!rdev->ops->set_default_mgmt_key) { + err = -EOPNOTSUPP; + goto out; + } + + err = nl80211_key_allowed(dev->ieee80211_ptr); + if (err) + goto out; + + err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, + dev, key.idx); + if (err) + goto out; + +#ifdef CONFIG_CFG80211_WEXT + dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; #endif + } + + out: wdev_unlock(dev->ieee80211_ptr); return err; diff --git a/net/wireless/util.c b/net/wireless/util.c index 4de624ca4c63..7620ae2fcf18 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) continue; } if (wdev->connect_keys->def == i) - if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { + if (rdev->ops->set_default_key(wdev->wiphy, dev, + i, true, true)) { netdev_err(dev, "failed to set defkey %d\n", i); continue; } diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 12222ee6ebf2..3e5dbd4e4cd5 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, __cfg80211_leave_ibss(rdev, wdev->netdev, true); rejoin = true; } - err = rdev->ops->set_default_key(&rdev->wiphy, - dev, idx); + err = rdev->ops->set_default_key(&rdev->wiphy, dev, + idx, true, true); } if (!err) { wdev->wext.default_key = idx; @@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_device *dev, err = 0; wdev_lock(wdev); if (wdev->current_bss) - err = rdev->ops->set_default_key(&rdev->wiphy, - dev, idx); + err = rdev->ops->set_default_key(&rdev->wiphy, dev, + idx, true, true); if (!err) wdev->wext.default_key = idx; wdev_unlock(wdev); -- cgit v1.2.3-59-g8ed1b From f7e0104c1a4e77cc4f23d5969b0677bdc4f62c63 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Dec 2010 19:49:02 +0100 Subject: mac80211: support separate default keys Add support for split default keys (unicast and multicast) in mac80211. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 2 +- net/mac80211/debugfs_key.c | 37 +++++++++++++++++++++---------------- net/mac80211/debugfs_key.h | 8 ++------ net/mac80211/ieee80211_i.h | 5 +++-- net/mac80211/key.c | 45 ++++++++++++++++++++++++++------------------- net/mac80211/key.h | 3 ++- net/mac80211/main.c | 3 ++- net/mac80211/tx.c | 6 +++++- 8 files changed, 62 insertions(+), 47 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 12f7dc048d34..ea06f92801e9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -300,7 +300,7 @@ static int ieee80211_config_default_key(struct wiphy *wiphy, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - ieee80211_set_default_key(sdata, key_idx); + ieee80211_set_default_key(sdata, key_idx, uni, multi); return 0; } diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 5822a6ce7671..f7ef3477c24a 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -274,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key) debugfs_remove_recursive(key->debugfs.dir); key->debugfs.dir = NULL; } -void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) + +void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) { char buf[50]; struct ieee80211_key *key; @@ -282,25 +283,29 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) if (!sdata->debugfs.dir) return; - /* this is running under the key lock */ + lockdep_assert_held(&sdata->local->key_mtx); - key = sdata->default_key; - if (key) { + if (sdata->default_unicast_key) { + key = sdata->default_unicast_key; sprintf(buf, "../keys/%d", key->debugfs.cnt); - sdata->debugfs.default_key = - debugfs_create_symlink("default_key", + sdata->debugfs.default_unicast_key = + debugfs_create_symlink("default_unicast_key", sdata->debugfs.dir, buf); - } else - ieee80211_debugfs_key_remove_default(sdata); -} - -void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata) -{ - if (!sdata) - return; + } else { + debugfs_remove(sdata->debugfs.default_unicast_key); + sdata->debugfs.default_unicast_key = NULL; + } - debugfs_remove(sdata->debugfs.default_key); - sdata->debugfs.default_key = NULL; + if (sdata->default_multicast_key) { + key = sdata->default_multicast_key; + sprintf(buf, "../keys/%d", key->debugfs.cnt); + sdata->debugfs.default_multicast_key = + debugfs_create_symlink("default_multicast_key", + sdata->debugfs.dir, buf); + } else { + debugfs_remove(sdata->debugfs.default_multicast_key); + sdata->debugfs.default_multicast_key = NULL; + } } void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) diff --git a/net/mac80211/debugfs_key.h b/net/mac80211/debugfs_key.h index 54717b4e1371..32adc77e9c77 100644 --- a/net/mac80211/debugfs_key.h +++ b/net/mac80211/debugfs_key.h @@ -4,8 +4,7 @@ #ifdef CONFIG_MAC80211_DEBUGFS void ieee80211_debugfs_key_add(struct ieee80211_key *key); void ieee80211_debugfs_key_remove(struct ieee80211_key *key); -void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata); -void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata); +void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata); void ieee80211_debugfs_key_add_mgmt_default( struct ieee80211_sub_if_data *sdata); void ieee80211_debugfs_key_remove_mgmt_default( @@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key) {} static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) {} -static inline void ieee80211_debugfs_key_add_default( - struct ieee80211_sub_if_data *sdata) -{} -static inline void ieee80211_debugfs_key_remove_default( +static inline void ieee80211_debugfs_key_update_default( struct ieee80211_sub_if_data *sdata) {} static inline void ieee80211_debugfs_key_add_mgmt_default( diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 72499fe5fc36..ce58b2a676e2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -557,7 +557,7 @@ struct ieee80211_sub_if_data { unsigned int fragment_next; struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; - struct ieee80211_key *default_key; + struct ieee80211_key *default_unicast_key, *default_multicast_key; struct ieee80211_key *default_mgmt_key; u16 sequence_number; @@ -595,7 +595,8 @@ struct ieee80211_sub_if_data { struct { struct dentry *dir; struct dentry *subdir_stations; - struct dentry *default_key; + struct dentry *default_unicast_key; + struct dentry *default_multicast_key; struct dentry *default_mgmt_key; } debugfs; #endif diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 72df1ca7299b..84cf9196820f 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -178,7 +178,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) EXPORT_SYMBOL_GPL(ieee80211_key_removed); static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, - int idx) + int idx, bool uni, bool multi) { struct ieee80211_key *key = NULL; @@ -187,18 +187,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, if (idx >= 0 && idx < NUM_DEFAULT_KEYS) key = sdata->keys[idx]; - rcu_assign_pointer(sdata->default_key, key); + if (uni) + rcu_assign_pointer(sdata->default_unicast_key, key); + if (multi) + rcu_assign_pointer(sdata->default_multicast_key, key); - if (key) { - ieee80211_debugfs_key_remove_default(key->sdata); - ieee80211_debugfs_key_add_default(key->sdata); - } + ieee80211_debugfs_key_update_default(sdata); } -void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) +void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, + bool uni, bool multi) { mutex_lock(&sdata->local->key_mtx); - __ieee80211_set_default_key(sdata, idx); + __ieee80211_set_default_key(sdata, idx, uni, multi); mutex_unlock(&sdata->local->key_mtx); } @@ -215,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx) rcu_assign_pointer(sdata->default_mgmt_key, key); - if (key) { - ieee80211_debugfs_key_remove_mgmt_default(key->sdata); - ieee80211_debugfs_key_add_mgmt_default(key->sdata); - } + ieee80211_debugfs_key_update_default(sdata); } void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, @@ -236,7 +234,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, struct ieee80211_key *old, struct ieee80211_key *new) { - int idx, defkey, defmgmtkey; + int idx; + bool defunikey, defmultikey, defmgmtkey; if (new) list_add(&new->list, &sdata->key_list); @@ -257,17 +256,24 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, else idx = new->conf.keyidx; - defkey = old && sdata->default_key == old; + defunikey = old && sdata->default_unicast_key == old; + defmultikey = old && sdata->default_multicast_key == old; defmgmtkey = old && sdata->default_mgmt_key == old; - if (defkey && !new) - __ieee80211_set_default_key(sdata, -1); + if (defunikey && !new) + __ieee80211_set_default_key(sdata, -1, true, false); + if (defmultikey && !new) + __ieee80211_set_default_key(sdata, -1, false, true); if (defmgmtkey && !new) __ieee80211_set_default_mgmt_key(sdata, -1); rcu_assign_pointer(sdata->keys[idx], new); - if (defkey && new) - __ieee80211_set_default_key(sdata, new->conf.keyidx); + if (defunikey && new) + __ieee80211_set_default_key(sdata, new->conf.keyidx, + true, false); + if (defmultikey && new) + __ieee80211_set_default_key(sdata, new->conf.keyidx, + false, true); if (defmgmtkey && new) __ieee80211_set_default_mgmt_key(sdata, new->conf.keyidx); @@ -509,11 +515,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->local->key_mtx); - ieee80211_debugfs_key_remove_default(sdata); ieee80211_debugfs_key_remove_mgmt_default(sdata); list_for_each_entry_safe(key, tmp, &sdata->key_list, list) __ieee80211_key_free(key); + ieee80211_debugfs_key_update_default(sdata); + mutex_unlock(&sdata->local->key_mtx); } diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 0db1c0f5f697..8106aa1b7466 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -138,7 +138,8 @@ int __must_check ieee80211_key_link(struct ieee80211_key *key, struct sta_info *sta); void ieee80211_key_free(struct ieee80211_local *local, struct ieee80211_key *key); -void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); +void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, + bool uni, bool multi); void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx); void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 973fee9f7d69..ae656b6e3bc2 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -519,7 +519,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | - WIPHY_FLAG_4ADDR_STATION; + WIPHY_FLAG_4ADDR_STATION | + WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; wiphy->privid = mac80211_wiphy_privid; wiphy->bss_priv_size = sizeof(struct ieee80211_bss); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0ee56bb0ea7e..157bde993ef5 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -539,7 +539,11 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) ieee80211_is_robust_mgmt_frame(hdr) && (key = rcu_dereference(tx->sdata->default_mgmt_key))) tx->key = key; - else if ((key = rcu_dereference(tx->sdata->default_key))) + else if (is_multicast_ether_addr(hdr->addr1) && + (key = rcu_dereference(tx->sdata->default_multicast_key))) + tx->key = key; + else if (!is_multicast_ether_addr(hdr->addr1) && + (key = rcu_dereference(tx->sdata->default_unicast_key))) tx->key = key; else if (tx->sdata->drop_unencrypted && (tx->skb->protocol != tx->sdata->control_port_protocol) && -- cgit v1.2.3-59-g8ed1b From f61afc291a64d0362258f5a1ab45c828fe15ab04 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 9 Dec 2010 20:55:58 +0100 Subject: b43: N-PHY: use correct bit for controlling MAC and PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 61875c888278..e12f399f7615 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3278,9 +3278,9 @@ static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on) { u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); if (on) - tmslow |= SSB_TMSLOW_PHYCLK; + tmslow |= B43_TMSLOW_MACPHYCLKEN; else - tmslow &= ~SSB_TMSLOW_PHYCLK; + tmslow &= ~B43_TMSLOW_MACPHYCLKEN; ssb_write32(dev->dev, SSB_TMSLOW, tmslow); } -- cgit v1.2.3-59-g8ed1b From ea85ffd627b5da346b348d784fafec0ce4632d4d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 9 Dec 2010 20:55:59 +0100 Subject: b43: N-PHY: one more fix for order of tables initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I missed that part in previous reordering. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_nphy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index df61c1610e39..dc8ef09a8552 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -1835,12 +1835,12 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) /* Volatile tables */ ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); + ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); + ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); - ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); - ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); -- cgit v1.2.3-59-g8ed1b From d242b90adf4e1918ac86433dfbb32a1136515bdd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 9 Dec 2010 20:56:00 +0100 Subject: b43: N-PHY: use designed function and macro for writing tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e12f399f7615..a1aa5700b631 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1209,29 +1209,18 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); } - /* TODO: convert to b43_ntab_write? */ - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); + b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); + b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); + b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); + b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); if (dev->phy.rev < 2) { - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); + b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); + b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000); + b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); + b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); + b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800); + b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800); } b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); -- cgit v1.2.3-59-g8ed1b From 42ab135fe78025910bed8ff56e00a375f2b04db1 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 9 Dec 2010 20:56:01 +0100 Subject: b43: rename TMS defines, drop useless condition from core reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discussed we do not know band width at core reset time and it is not a good idea to reset whole just to change band. So just set unconditionally 20 MHz band width as default during core reset. As for defines PHY clock changed to band width in specs and it makes much more sens to call defines by band width which is self-explainable. Updated specs do not mention 0 value, but comparing to old ones you can notice lineral relation between PHY clock speed and band width. So it makes sense for 0x0 value to be 10 MHz band width. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 8 ++++---- drivers/net/wireless/b43/main.c | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 9aad2ca3c112..bd4cb75b6ca3 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -416,10 +416,10 @@ enum { /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ #define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ -#define B43_TMSLOW_PHYCLKSPEED 0x00C00000 /* PHY clock speed mask (N-PHY only) */ -#define B43_TMSLOW_PHYCLKSPEED_40MHZ 0x00000000 /* 40 MHz PHY */ -#define B43_TMSLOW_PHYCLKSPEED_80MHZ 0x00400000 /* 80 MHz PHY */ -#define B43_TMSLOW_PHYCLKSPEED_160MHZ 0x00800000 /* 160 MHz PHY */ +#define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */ +#define B43_TMSLOW_PHY_BANDWIDTH_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */ +#define B43_TMSLOW_PHY_BANDWIDTH_20MHZ 0x00400000 /* 20 MHz bandwidth, 80 MHz PHY */ +#define B43_TMSLOW_PHY_BANDWIDTH_40MHZ 0x00800000 /* 40 MHz bandwidth, 160 MHz PHY */ #define B43_TMSLOW_PLLREFSEL 0x00200000 /* PLL Frequency Reference Select (rev >= 5) */ #define B43_TMSLOW_MACPHYCLKEN 0x00100000 /* MAC PHY Clock Control Enable (rev >= 5) */ #define B43_TMSLOW_PHYRESET 0x00080000 /* PHY Reset */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9ae3f619e98d..1aec160e3d2f 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1150,12 +1150,8 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; - if (dev->phy.type == B43_PHYTYPE_N) { - if (b43_channel_type_is_40mhz(dev->phy.channel_type)) - flags |= B43_TMSLOW_PHYCLKSPEED_160MHZ; - else - flags |= B43_TMSLOW_PHYCLKSPEED_80MHZ; - } + if (dev->phy.type == B43_PHYTYPE_N) + flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ ssb_device_enable(dev->dev, flags); msleep(2); /* Wait for the PLL to turn on. */ -- cgit v1.2.3-59-g8ed1b From 91f44b02992f632ac6c070f985cd58d5acee4199 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 9 Dec 2010 13:15:45 -0800 Subject: mac80211 default tx_last_beacon false (congestion) The 802.11 spec states that the STA that generated the last Beacon frame shall be the STA that response to a probe request. This is important for congestion reduction when a probe request is received - only 1 node in an adhoc BSS will transmit a response. While mac80211 drivers should provide the tx_last_beacon function to report if they transmitted the last beacon many do not. As an attempt to reduce probe response congestion default this to 0 such that a node not implementing this capability does not contribute to unnecessary congestion. In a modern medium sized office environment I see upwards of 100 probe requests per second received at a given node from various hardware/OS/drivers doing zeroconf 'active probing' as opposed to passively listening for beacons. With a modest 10-node adhoc network consisting of drivers that do not implement this tx_last_beacon feature, I have seen this result in the simultaneous xmit of probe responses accumulating to 500 probe responses per second because of collisions which brings the adhoc network to its knees as well as causes needless congestion. Signed-off-by: John W. Linville --- net/mac80211/driver-ops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4244554d218a..af0c4398cceb 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -367,7 +367,7 @@ static inline void drv_reset_tsf(struct ieee80211_local *local) static inline int drv_tx_last_beacon(struct ieee80211_local *local) { - int ret = 1; + int ret = 0; /* default unsuported op for less congestion */ might_sleep(); -- cgit v1.2.3-59-g8ed1b From 44316cb1e97a1e7f76eb3f07e5b0ba91d72e9693 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 9 Dec 2010 18:24:41 -0800 Subject: ieee80211: add Parameter Set Count bitmask WMM IE QoS Info field lower 4 bits: Parameter Set Count Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 351c0ab4e284..7f2354534242 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -122,6 +122,7 @@ /* U-APSD queue for WMM IEs sent by AP */ #define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7) +#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f /* U-APSD queues for WMM IEs sent by STA */ #define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0) -- cgit v1.2.3-59-g8ed1b From 9abbfb27dd96361187bb3872b2c349a76f5e09e9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 10 Dec 2010 11:27:06 +0530 Subject: ath9k: Use power save wrappers for TSF get/set The HW has to be awake when accessing registers. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ca35aaa7aec6..5b4ef81318f5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1987,7 +1987,9 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) struct ath_softc *sc = aphy->sc; mutex_lock(&sc->mutex); + ath9k_ps_wakeup(sc); tsf = ath9k_hw_gettsf64(sc->sc_ah); + ath9k_ps_restore(sc); mutex_unlock(&sc->mutex); return tsf; @@ -1999,7 +2001,9 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) struct ath_softc *sc = aphy->sc; mutex_lock(&sc->mutex); + ath9k_ps_wakeup(sc); ath9k_hw_settsf64(sc->sc_ah, tsf); + ath9k_ps_restore(sc); mutex_unlock(&sc->mutex); } -- cgit v1.2.3-59-g8ed1b From 207aba6018a7b1757b5248ced2b280d20790c498 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 10 Dec 2010 17:10:44 +0100 Subject: mac80211: support IBSS RSN with SW crypto When software crypto is used, mac80211 will support IBSS RSN, it doesn't depend on the driver in that case. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ae656b6e3bc2..f7bdb7c78879 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -517,11 +517,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; + wiphy->privid = mac80211_wiphy_privid; + wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | WIPHY_FLAG_4ADDR_STATION | WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; - wiphy->privid = mac80211_wiphy_privid; + + if (!ops->set_key) + wiphy->flags |= WIPHY_FLAG_IBSS_RSN; wiphy->bss_priv_size = sizeof(struct ieee80211_bss); -- cgit v1.2.3-59-g8ed1b From 248a38d0ed754bf9f002e66f3d607e12ae6a673c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 10 Dec 2010 21:16:46 +0100 Subject: ath9k: fix sequence number assigment for non-AMPDU QoS data frames wireless-testing commit 04caf863750bc7e042d1e8d57e5ce9d6326ab435 ('ath9k: more tx setup cleanups') merged tx path code for HT vs non-HT frames, however it did not pass the tid pointer to ath_tx_send_normal, causing an inconsistency between AMPDU vs non-AMPDU sequence number handling. Fix this by always passing in the tid pointer for all QoS data frames. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 43c0109f202c..966236953e77 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1685,17 +1685,20 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct list_head bf_head; - struct ath_atx_tid *tid; + struct ath_atx_tid *tid = NULL; u8 tidno; spin_lock_bh(&txctl->txq->axq_lock); - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) { + if (ieee80211_is_data_qos(hdr->frame_control) && txctl->an) { tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(txctl->an, tidno); WARN_ON(tid->ac->txq != txctl->txq); + } + + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { /* * Try aggregation if it's a unicast data frame * and the destination is HT capable. @@ -1712,7 +1715,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, bf->bf_state.bfs_paprd); - ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); + ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); } spin_unlock_bh(&txctl->txq->axq_lock); -- cgit v1.2.3-59-g8ed1b From 040b74f741b20dbf07359716d5c540356a036ade Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:07 +0100 Subject: ath9k_hw: only use the PCIe disable register write sequence for AR5416 Newer chips do not need this, and maybe these register writes could have negative side effects on newer hardware. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1beb89673b0c..7c3d2de93652 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -284,11 +284,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) static void ath9k_hw_disablepcie(struct ath_hw *ah) { - if (AR_SREV_9100(ah)) + if (!AR_SREV_5416(ah)) return; - ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); @@ -300,8 +298,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); - - REGWRITE_BUFFER_FLUSH(ah); } /* This should work for all families including legacy */ -- cgit v1.2.3-59-g8ed1b From 4ddfcd7daf57247ff718b849a152d97a80b7ae4d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:08 +0100 Subject: ath9k_hw: clean up duplicate and unnused eeprom related defines AR*_MAX_RATE_POWER => MAX_RATE_POWER AR*_EEPROM_MODAL_SPURS => AR_EEPROM_MODAL_SPURS AR*_OPFLAGS_* => AR5416_OPFLAGS_* ... Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 22 +++++------ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 37 +----------------- drivers/net/wireless/ath/ath9k/eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom.h | 45 +++++---------------- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 36 ++++++++--------- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 54 +++++++++++++------------- drivers/net/wireless/ath/ath9k/eeprom_def.c | 18 ++++----- drivers/net/wireless/ath/ath9k/hw.h | 1 - 8 files changed, 77 insertions(+), 138 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 1f5aa51b9cef..2fc3260579a3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -72,7 +72,7 @@ static const struct ar9300_eeprom ar9300_default = { .regDmn = { LE16(0), LE16(0x1f) }, .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ .opCapFlags = { - .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, .eepMisc = 0, }, .rfSilent = 0, @@ -649,7 +649,7 @@ static const struct ar9300_eeprom ar9300_x113 = { .regDmn = { LE16(0), LE16(0x1f) }, .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ .opCapFlags = { - .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, .eepMisc = 0, }, .rfSilent = 0, @@ -1227,7 +1227,7 @@ static const struct ar9300_eeprom ar9300_h112 = { .regDmn = { LE16(0), LE16(0x1f) }, .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ .opCapFlags = { - .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, .eepMisc = 0, }, .rfSilent = 0, @@ -1805,7 +1805,7 @@ static const struct ar9300_eeprom ar9300_x112 = { .regDmn = { LE16(0), LE16(0x1f) }, .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ .opCapFlags = { - .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, .eepMisc = 0, }, .rfSilent = 0, @@ -2382,7 +2382,7 @@ static const struct ar9300_eeprom ar9300_h116 = { .regDmn = { LE16(0), LE16(0x1f) }, .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */ .opCapFlags = { - .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, .eepMisc = 0, }, .rfSilent = 0, @@ -2974,7 +2974,7 @@ static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id) static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) { - if (fbin == AR9300_BCHAN_UNUSED) + if (fbin == AR5416_BCHAN_UNUSED) return fbin; return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); @@ -4485,7 +4485,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); } - return AR9300_MAX_RATE_POWER; + return MAX_RATE_POWER; } /* @@ -4494,7 +4494,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, u16 freq, int idx, bool is2GHz) { - u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; u8 *ctl_freqbin = is2GHz ? &eep->ctl_freqbin_2G[idx][0] : &eep->ctl_freqbin_5G[idx][0]; @@ -4504,7 +4504,7 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, /* Get the edge power */ for (edge = 0; - (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED); + (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED); edge++) { /* * If there's an exact channel match or an inband flag set @@ -4542,9 +4542,9 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; - u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; static const u16 tpScaleReductionTable[5] = { - 0, 3, 6, 9, AR9300_MAX_RATE_POWER + 0, 3, 6, 9, MAX_RATE_POWER }; int i; int16_t twiceLargestAntenna; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 33503217dab3..620821ea6927 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -20,48 +20,17 @@ /* #define AR9300_NUM_CTLS 21 */ #define AR9300_NUM_CTLS_5G 9 #define AR9300_NUM_CTLS_2G 12 -#define AR9300_CTL_MODE_M 0xF #define AR9300_NUM_BAND_EDGES_5G 8 #define AR9300_NUM_BAND_EDGES_2G 4 -#define AR9300_NUM_PD_GAINS 4 -#define AR9300_PD_GAINS_IN_MASK 4 -#define AR9300_PD_GAIN_ICEPTS 5 -#define AR9300_EEPROM_MODAL_SPURS 5 -#define AR9300_MAX_RATE_POWER 63 -#define AR9300_NUM_PDADC_VALUES 128 -#define AR9300_NUM_RATES 16 -#define AR9300_BCHAN_UNUSED 0xFF -#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64 -#define AR9300_OPFLAGS_11A 0x01 -#define AR9300_OPFLAGS_11G 0x02 -#define AR9300_OPFLAGS_5G_HT40 0x04 -#define AR9300_OPFLAGS_2G_HT40 0x08 -#define AR9300_OPFLAGS_5G_HT20 0x10 -#define AR9300_OPFLAGS_2G_HT20 0x20 #define AR9300_EEPMISC_BIG_ENDIAN 0x01 #define AR9300_EEPMISC_WOW 0x02 #define AR9300_CUSTOMER_DATA_SIZE 20 -#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) #define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) #define AR9300_MAX_CHAINS 3 #define AR9300_ANT_16S 25 #define AR9300_FUTURE_MODAL_SZ 6 -#define AR9300_NUM_ANT_CHAIN_FIELDS 7 -#define AR9300_NUM_ANT_COMMON_FIELDS 4 -#define AR9300_SIZE_ANT_CHAIN_FIELD 3 -#define AR9300_SIZE_ANT_COMMON_FIELD 4 -#define AR9300_ANT_CHAIN_MASK 0x7 -#define AR9300_ANT_COMMON_MASK 0xf -#define AR9300_CHAIN_0_IDX 0 -#define AR9300_CHAIN_1_IDX 1 -#define AR9300_CHAIN_2_IDX 2 - -#define AR928X_NUM_ANT_CHAIN_FIELDS 6 -#define AR928X_SIZE_ANT_CHAIN_FIELD 2 -#define AR928X_ANT_CHAIN_MASK 0x3 - /* Delta from which to start power to pdadc table */ /* This offset is used in both open loop and closed loop power control * schemes. In open loop power control, it is not really needed, but for @@ -71,12 +40,8 @@ */ #define AR9300_PWR_TABLE_OFFSET 0 -/* enable flags for voltage and temp compensation */ -#define ENABLE_TEMP_COMPENSATION 0x01 -#define ENABLE_VOLT_COMPENSATION 0x02 /* byte addressable */ #define AR9300_EEPROM_SIZE (16*1024) -#define FIXED_CCA_THRESHOLD 15 #define AR9300_BASE_ADDR_4K 0xfff #define AR9300_BASE_ADDR 0x3ff @@ -226,7 +191,7 @@ struct ar9300_modal_eep_header { int8_t tempSlope; int8_t voltSlope; /* spur channels in usual fbin coding format */ - u8 spurChans[AR9300_EEPROM_MODAL_SPURS]; + u8 spurChans[AR_EEPROM_MODAL_SPURS]; /* 3 Check if the register is per chain */ int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; u8 ob[AR9300_MAX_CHAINS]; diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index fda533cfd881..3d99b6cdd2cb 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -234,7 +234,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah, u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, bool is2GHz, int num_band_edges) { - u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; int i; for (i = 0; (i < num_band_edges) && diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 8b9885b5243f..833dd0c3feba 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -17,6 +17,8 @@ #ifndef EEPROM_H #define EEPROM_H +#define AR_EEPROM_MODAL_SPURS 5 + #include "../ath.h" #include #include "ar9003_eeprom.h" @@ -149,8 +151,6 @@ #define AR5416_NUM_PD_GAINS 4 #define AR5416_PD_GAINS_IN_MASK 4 #define AR5416_PD_GAIN_ICEPTS 5 -#define AR5416_EEPROM_MODAL_SPURS 5 -#define AR5416_MAX_RATE_POWER 63 #define AR5416_NUM_PDADC_VALUES 128 #define AR5416_BCHAN_UNUSED 0xFF #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 @@ -175,8 +175,6 @@ #define AR5416_EEP4K_NUM_CTLS 12 #define AR5416_EEP4K_NUM_BAND_EDGES 4 #define AR5416_EEP4K_NUM_PD_GAINS 2 -#define AR5416_EEP4K_PD_GAINS_IN_MASK 4 -#define AR5416_EEP4K_PD_GAIN_ICEPTS 5 #define AR5416_EEP4K_MAX_CHAINS 1 #define AR9280_TX_GAIN_TABLE_SIZE 22 @@ -198,35 +196,12 @@ #define AR9287_NUM_2G_40_TARGET_POWERS 3 #define AR9287_NUM_CTLS 12 #define AR9287_NUM_BAND_EDGES 4 -#define AR9287_NUM_PD_GAINS 4 -#define AR9287_PD_GAINS_IN_MASK 4 #define AR9287_PD_GAIN_ICEPTS 1 -#define AR9287_EEPROM_MODAL_SPURS 5 -#define AR9287_MAX_RATE_POWER 63 -#define AR9287_NUM_PDADC_VALUES 128 -#define AR9287_NUM_RATES 16 -#define AR9287_BCHAN_UNUSED 0xFF -#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64 -#define AR9287_OPFLAGS_11A 0x01 -#define AR9287_OPFLAGS_11G 0x02 -#define AR9287_OPFLAGS_2G_HT40 0x08 -#define AR9287_OPFLAGS_2G_HT20 0x20 -#define AR9287_OPFLAGS_5G_HT40 0x04 -#define AR9287_OPFLAGS_5G_HT20 0x10 #define AR9287_EEPMISC_BIG_ENDIAN 0x01 #define AR9287_EEPMISC_WOW 0x02 #define AR9287_MAX_CHAINS 2 #define AR9287_ANT_16S 32 -#define AR9287_custdatasize 20 - -#define AR9287_NUM_ANT_CHAIN_FIELDS 6 -#define AR9287_NUM_ANT_COMMON_FIELDS 4 -#define AR9287_SIZE_ANT_CHAIN_FIELD 2 -#define AR9287_SIZE_ANT_COMMON_FIELD 4 -#define AR9287_ANT_CHAIN_MASK 0x3 -#define AR9287_ANT_COMMON_MASK 0xf -#define AR9287_CHAIN_0_IDX 0 -#define AR9287_CHAIN_1_IDX 1 + #define AR9287_DATA_SZ 32 #define AR9287_PWR_TABLE_OFFSET_DB -5 @@ -396,7 +371,7 @@ struct modal_eep_header { u16 xpaBiasLvlFreq[3]; u8 futureModal[6]; - struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; + struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; } __packed; struct calDataPerFreqOpLoop { @@ -464,7 +439,7 @@ struct modal_eep_4k_header { u8 db2_4:4, reserved:4; #endif u8 futureModal[4]; - struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; + struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; } __packed; struct base_eep_ar9287_header { @@ -522,7 +497,7 @@ struct modal_eep_ar9287_header { u8 ob_qam; u8 ob_pal_off; u8 futureModal[30]; - struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS]; + struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; } __packed; struct cal_data_per_freq { @@ -531,8 +506,8 @@ struct cal_data_per_freq { } __packed; struct cal_data_per_freq_4k { - u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; - u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; + u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; } __packed; struct cal_target_power_leg { @@ -558,8 +533,8 @@ struct cal_data_op_loop_ar9287 { } __packed; struct cal_data_per_freq_ar9287 { - u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; - u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; + u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; + u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; } __packed; union cal_data_per_freq_ar9287_u { diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 939fc7af86f8..6102309bc163 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -153,7 +153,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) eep->modalHeader.antCtrlChain[i] = integer; } - for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { word = swab16(eep->modalHeader.spurChans[i].spurChan); eep->modalHeader.spurChans[i].spurChan = word; } @@ -258,7 +258,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, struct chan_centers centers; #define PD_GAIN_BOUNDARY_DEFAULT 58; - memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); + memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { @@ -278,7 +278,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], pRawDataSet[idxL].vpdPdg[i], - AR5416_EEP4K_PD_GAIN_ICEPTS, + AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); } } else { @@ -291,17 +291,17 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, minPwrT4[i] = max(pPwrL[0], pPwrR[0]); maxPwrT4[i] = - min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1], - pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]); + min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], + pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, - AR5416_EEP4K_PD_GAIN_ICEPTS, + AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, - AR5416_EEP4K_PD_GAIN_ICEPTS, + AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { @@ -328,7 +328,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); pPdGainBoundaries[i] = - min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); + min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { minDelta = pPdGainBoundaries[0] - 23; @@ -380,7 +380,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, } } - while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) { + while (i < AR5416_PD_GAINS_IN_MASK) { pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT; i++; } @@ -404,7 +404,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, u8 *pCalBChans = NULL; u16 pdGainOverlap_t2; static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; - u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; + u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; u16 numPiers, i, j; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; @@ -426,12 +426,12 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, numXpdGain = 0; - for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) { - if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) { + for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { + if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) break; xpdGainValues[numXpdGain] = - (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i); + (u16)(AR5416_PD_GAINS_IN_MASK - i); numXpdGain++; } } @@ -528,7 +528,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, int i; int16_t twiceLargestAntenna; u16 twiceMinEdgePower; - u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; u16 numCtlModes; const u16 *pCtlMode; @@ -537,7 +537,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, struct cal_ctl_data_4k *rep; struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; static const u16 tpScaleReductionTable[5] = - { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; + { 0, 3, 6, 9, MAX_RATE_POWER }; struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 0, { 0, 0, 0, 0} }; @@ -613,7 +613,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, if (ah->eep_ops->get_eeprom_ver(ah) == 14 && ah->eep_ops->get_eeprom_rev(ah) <= 2) - twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + twiceMaxEdgePower = MAX_RATE_POWER; for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { @@ -752,8 +752,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); - if (ratesArray[i] > AR5416_MAX_RATE_POWER) - ratesArray[i] = AR5416_MAX_RATE_POWER; + if (ratesArray[i] > MAX_RATE_POWER) + ratesArray[i] = MAX_RATE_POWER; if (ratesArray[i] > regulatory->max_power_level) regulatory->max_power_level = ratesArray[i]; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 065402f2e402..4ba07da37457 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -150,7 +150,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) eep->modalHeader.antCtrlChain[i] = integer; } - for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) { + for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { word = swab16(eep->modalHeader.spurChans[i].spurChan); eep->modalHeader.spurChans[i].spurChan = word; } @@ -236,8 +236,8 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, int16_t ss; u16 idxL = 0, idxR = 0, numPiers; u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; - u8 minPwrT4[AR9287_NUM_PD_GAINS]; - u8 maxPwrT4[AR9287_NUM_PD_GAINS]; + u8 minPwrT4[AR5416_NUM_PD_GAINS]; + u8 maxPwrT4[AR5416_NUM_PD_GAINS]; int16_t vpdStep; int16_t tmpVal; u16 sizeCurrVpdTable, maxIndex, tgtIndex; @@ -251,11 +251,11 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); + memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { - if (bChans[numPiers] == AR9287_BCHAN_UNUSED) + if (bChans[numPiers] == AR5416_BCHAN_UNUSED) break; } @@ -314,7 +314,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4); - pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, + pPdGainBoundaries[i] = min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); @@ -334,7 +334,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { + while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); ss++; @@ -346,7 +346,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; - while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1))) + while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) pPDADCValues[k++] = vpdTableI[i][ss++]; vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - @@ -355,7 +355,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, if (tgtIndex > maxIndex) { while ((ss <= tgtIndex) && - (k < (AR9287_NUM_PDADC_VALUES - 1))) { + (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t) TMP_VAL_VPD_TABLE; pPDADCValues[k++] = (u8)((tmpVal > 255) ? 255 : tmpVal); @@ -364,12 +364,12 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, } } - while (i < AR9287_PD_GAINS_IN_MASK) { + while (i < AR5416_PD_GAINS_IN_MASK) { pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; i++; } - while (k < AR9287_NUM_PDADC_VALUES) { + while (k < AR5416_NUM_PDADC_VALUES) { pPDADCValues[k] = pPDADCValues[k-1]; k++; } @@ -389,7 +389,7 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { - if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED) + if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED) break; } @@ -455,11 +455,11 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; u8 *pCalBChans = NULL; u16 pdGainOverlap_t2; - u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; - u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; + u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; + u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; u16 numPiers = 0, i, j; u16 numXpdGain, xpdMask; - u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; + u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; u32 reg32, regOffset, regChainOffset, regval; int16_t modalIdx, diff = 0; struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; @@ -487,12 +487,12 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, numXpdGain = 0; /* Calculate the value of xpdgains from the xpdGain Mask */ - for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { - if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { - if (numXpdGain >= AR9287_NUM_PD_GAINS) + for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { + if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { + if (numXpdGain >= AR5416_NUM_PD_GAINS) break; xpdGainValues[numXpdGain] = - (u16)(AR9287_PD_GAINS_IN_MASK-i); + (u16)(AR5416_PD_GAINS_IN_MASK-i); numXpdGain++; } } @@ -561,13 +561,13 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, (int32_t)AR9287_PWR_TABLE_OFFSET_DB); diff *= 2; - for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++) + for (j = 0; j < ((u16)AR5416_NUM_PDADC_VALUES-diff); j++) pdadcValues[j] = pdadcValues[j+diff]; - for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); - j < AR9287_NUM_PDADC_VALUES; j++) + for (j = (u16)(AR5416_NUM_PDADC_VALUES-diff); + j < AR5416_NUM_PDADC_VALUES; j++) pdadcValues[j] = - pdadcValues[AR9287_NUM_PDADC_VALUES-diff]; + pdadcValues[AR5416_NUM_PDADC_VALUES-diff]; } if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { @@ -610,9 +610,9 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; static const u16 tpScaleReductionTable[5] = - { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; + { 0, 3, 6, 9, MAX_RATE_POWER }; int i; int16_t twiceLargestAntenna; struct cal_ctl_data_ar9287 *rep; @@ -877,8 +877,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); - if (ratesArray[i] > AR9287_MAX_RATE_POWER) - ratesArray[i] = AR9287_MAX_RATE_POWER; + if (ratesArray[i] > MAX_RATE_POWER) + ratesArray[i] = MAX_RATE_POWER; if (ratesArray[i] > regulatory->max_power_level) regulatory->max_power_level = ratesArray[i]; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 5bfa031545f4..da96a78f996d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -206,7 +206,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) pModal->antCtrlChain[i] = integer; } - for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { word = swab16(pModal->spurChans[i].spurChan); pModal->spurChans[i].spurChan = word; } @@ -616,7 +616,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, int16_t minDelta = 0; struct chan_centers centers; - memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); + memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { @@ -685,7 +685,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); pPdGainBoundaries[i] = - min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); + min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { minDelta = pPdGainBoundaries[0] - 23; @@ -782,7 +782,7 @@ static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, /* Because of a hardware limitation, ensure the gain boundary * is not larger than (63 - overlap) */ - gb_limit = (u16)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2); + gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2); for (k = 0; k < numXpdGain; k++) gb[k] = (u16)min(gb_limit, gb[k]); @@ -1001,9 +1001,9 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; - u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + u16 twiceMaxEdgePower = MAX_RATE_POWER; static const u16 tpScaleReductionTable[5] = - { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; + { 0, 3, 6, 9, MAX_RATE_POWER }; int i; int16_t twiceLargestAntenna; @@ -1148,7 +1148,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, if (ah->eep_ops->get_eeprom_ver(ah) == 14 && ah->eep_ops->get_eeprom_rev(ah) <= 2) - twiceMaxEdgePower = AR5416_MAX_RATE_POWER; + twiceMaxEdgePower = MAX_RATE_POWER; for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { if ((((cfgCtl & ~CTL_MODE_M) | @@ -1293,8 +1293,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, regulatory->max_power_level = 0; for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); - if (ratesArray[i] > AR5416_MAX_RATE_POWER) - ratesArray[i] = AR5416_MAX_RATE_POWER; + if (ratesArray[i] > MAX_RATE_POWER) + ratesArray[i] = MAX_RATE_POWER; if (ratesArray[i] > regulatory->max_power_level) regulatory->max_power_level = ratesArray[i]; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d83cc3b4685b..157e6bc2651a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -238,7 +238,6 @@ struct ath9k_ops_config { #define SPUR_DISABLE 0 #define SPUR_ENABLE_IOCTL 1 #define SPUR_ENABLE_EEPROM 2 -#define AR_EEPROM_MODAL_SPURS 5 #define AR_SPUR_5413_1 1640 #define AR_SPUR_5413_2 1200 #define AR_NO_SPUR 0x8000 -- cgit v1.2.3-59-g8ed1b From 115277a3bc0683d04da797268ddafdc3bf67ca33 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:09 +0100 Subject: ath9k_hw: merge ath9k_hw_get_gain_boundaries_pdadcs between eeprom_def.c and eeprom_4k.c Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.c | 190 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/eeprom.h | 8 ++ drivers/net/wireless/ath/ath9k/eeprom_4k.c | 169 +------------------------ drivers/net/wireless/ath/ath9k/eeprom_def.c | 164 +----------------------- 4 files changed, 200 insertions(+), 331 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 3d99b6cdd2cb..d54cfa4e8057 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -279,6 +279,196 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) } } +void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, + struct ath9k_channel *chan, + void *pRawDataSet, + u8 *bChans, u16 availPiers, + u16 tPdGainOverlap, + u16 *pPdGainBoundaries, u8 *pPDADCValues, + u16 numXpdGains) +{ + int i, j, k; + int16_t ss; + u16 idxL = 0, idxR = 0, numPiers; + static u8 vpdTableL[AR5416_NUM_PD_GAINS] + [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; + static u8 vpdTableR[AR5416_NUM_PD_GAINS] + [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; + static u8 vpdTableI[AR5416_NUM_PD_GAINS] + [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; + + u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; + u8 minPwrT4[AR5416_NUM_PD_GAINS]; + u8 maxPwrT4[AR5416_NUM_PD_GAINS]; + int16_t vpdStep; + int16_t tmpVal; + u16 sizeCurrVpdTable, maxIndex, tgtIndex; + bool match; + int16_t minDelta = 0; + struct chan_centers centers; + int pdgain_boundary_default; + struct cal_data_per_freq *data_def = pRawDataSet; + struct cal_data_per_freq_4k *data_4k = pRawDataSet; + bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah); + + memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); + ath9k_hw_get_channel_centers(ah, chan, ¢ers); + + for (numPiers = 0; numPiers < availPiers; numPiers++) { + if (bChans[numPiers] == AR5416_BCHAN_UNUSED) + break; + } + + match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, + IS_CHAN_2GHZ(chan)), + bChans, numPiers, &idxL, &idxR); + + if (match) { + if (eeprom_4k) { + for (i = 0; i < numXpdGains; i++) { + minPwrT4[i] = data_4k[idxL].pwrPdg[i][0]; + maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4]; + ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], + data_4k[idxL].pwrPdg[i], + data_4k[idxL].vpdPdg[i], + AR5416_PD_GAIN_ICEPTS, + vpdTableI[i]); + } + } else { + for (i = 0; i < numXpdGains; i++) { + minPwrT4[i] = data_def[idxL].pwrPdg[i][0]; + maxPwrT4[i] = data_def[idxL].pwrPdg[i][4]; + ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], + data_def[idxL].pwrPdg[i], + data_def[idxL].vpdPdg[i], + AR5416_PD_GAIN_ICEPTS, + vpdTableI[i]); + } + } + } else { + for (i = 0; i < numXpdGains; i++) { + if (eeprom_4k) { + pVpdL = data_4k[idxL].vpdPdg[i]; + pPwrL = data_4k[idxL].pwrPdg[i]; + pVpdR = data_4k[idxR].vpdPdg[i]; + pPwrR = data_4k[idxR].pwrPdg[i]; + } else { + pVpdL = data_def[idxL].vpdPdg[i]; + pPwrL = data_def[idxL].pwrPdg[i]; + pVpdR = data_def[idxR].vpdPdg[i]; + pPwrR = data_def[idxR].pwrPdg[i]; + } + + minPwrT4[i] = max(pPwrL[0], pPwrR[0]); + + maxPwrT4[i] = + min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], + pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); + + + ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], + pPwrL, pVpdL, + AR5416_PD_GAIN_ICEPTS, + vpdTableL[i]); + ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], + pPwrR, pVpdR, + AR5416_PD_GAIN_ICEPTS, + vpdTableR[i]); + + for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { + vpdTableI[i][j] = + (u8)(ath9k_hw_interpolate((u16) + FREQ2FBIN(centers. + synth_center, + IS_CHAN_2GHZ + (chan)), + bChans[idxL], bChans[idxR], + vpdTableL[i][j], vpdTableR[i][j])); + } + } + } + + k = 0; + + for (i = 0; i < numXpdGains; i++) { + if (i == (numXpdGains - 1)) + pPdGainBoundaries[i] = + (u16)(maxPwrT4[i] / 2); + else + pPdGainBoundaries[i] = + (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); + + pPdGainBoundaries[i] = + min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); + + if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { + minDelta = pPdGainBoundaries[0] - 23; + pPdGainBoundaries[0] = 23; + } else { + minDelta = 0; + } + + if (i == 0) { + if (AR_SREV_9280_20_OR_LATER(ah)) + ss = (int16_t)(0 - (minPwrT4[i] / 2)); + else + ss = 0; + } else { + ss = (int16_t)((pPdGainBoundaries[i - 1] - + (minPwrT4[i] / 2)) - + tPdGainOverlap + 1 + minDelta); + } + vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); + vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); + + while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { + tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); + pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); + ss++; + } + + sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); + tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - + (minPwrT4[i] / 2)); + maxIndex = (tgtIndex < sizeCurrVpdTable) ? + tgtIndex : sizeCurrVpdTable; + + while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { + pPDADCValues[k++] = vpdTableI[i][ss++]; + } + + vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - + vpdTableI[i][sizeCurrVpdTable - 2]); + vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); + + if (tgtIndex >= maxIndex) { + while ((ss <= tgtIndex) && + (k < (AR5416_NUM_PDADC_VALUES - 1))) { + tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + + (ss - maxIndex + 1) * vpdStep)); + pPDADCValues[k++] = (u8)((tmpVal > 255) ? + 255 : tmpVal); + ss++; + } + } + } + + if (eeprom_4k) + pdgain_boundary_default = 58; + else + pdgain_boundary_default = pPdGainBoundaries[i - 1]; + + while (i < AR5416_PD_GAINS_IN_MASK) { + pPdGainBoundaries[i] = pdgain_boundary_default; + i++; + } + + while (k < AR5416_NUM_PDADC_VALUES) { + pPDADCValues[k] = pPDADCValues[k - 1]; + k++; + } +} + int ath9k_hw_eeprom_init(struct ath_hw *ah) { int status; diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 833dd0c3feba..1f6b712898e6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -691,6 +691,14 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); int ath9k_hw_eeprom_init(struct ath_hw *ah); +void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, + struct ath9k_channel *chan, + void *pRawDataSet, + u8 *bChans, u16 availPiers, + u16 tPdGainOverlap, + u16 *pPdGainBoundaries, u8 *pPDADCValues, + u16 numXpdGains); + #define ar5416_get_ntxchains(_txchainmask) \ (((_txchainmask >> 2) & 1) + \ ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 6102309bc163..b0f744687900 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -227,173 +227,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, } } -static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, - struct ath9k_channel *chan, - struct cal_data_per_freq_4k *pRawDataSet, - u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, - u16 *pPdGainBoundaries, u8 *pPDADCValues, - u16 numXpdGains) -{ -#define TMP_VAL_VPD_TABLE \ - ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); - int i, j, k; - int16_t ss; - u16 idxL = 0, idxR = 0, numPiers; - static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - - u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; - u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; - u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; - int16_t vpdStep; - int16_t tmpVal; - u16 sizeCurrVpdTable, maxIndex, tgtIndex; - bool match; - int16_t minDelta = 0; - struct chan_centers centers; -#define PD_GAIN_BOUNDARY_DEFAULT 58; - - memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); - ath9k_hw_get_channel_centers(ah, chan, ¢ers); - - for (numPiers = 0; numPiers < availPiers; numPiers++) { - if (bChans[numPiers] == AR5416_BCHAN_UNUSED) - break; - } - - match = ath9k_hw_get_lower_upper_index( - (u8)FREQ2FBIN(centers.synth_center, - IS_CHAN_2GHZ(chan)), bChans, numPiers, - &idxL, &idxR); - - if (match) { - for (i = 0; i < numXpdGains; i++) { - minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; - maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pRawDataSet[idxL].pwrPdg[i], - pRawDataSet[idxL].vpdPdg[i], - AR5416_PD_GAIN_ICEPTS, - vpdTableI[i]); - } - } else { - for (i = 0; i < numXpdGains; i++) { - pVpdL = pRawDataSet[idxL].vpdPdg[i]; - pPwrL = pRawDataSet[idxL].pwrPdg[i]; - pVpdR = pRawDataSet[idxR].vpdPdg[i]; - pPwrR = pRawDataSet[idxR].pwrPdg[i]; - - minPwrT4[i] = max(pPwrL[0], pPwrR[0]); - - maxPwrT4[i] = - min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], - pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); - - - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrL, pVpdL, - AR5416_PD_GAIN_ICEPTS, - vpdTableL[i]); - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrR, pVpdR, - AR5416_PD_GAIN_ICEPTS, - vpdTableR[i]); - - for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { - vpdTableI[i][j] = - (u8)(ath9k_hw_interpolate((u16) - FREQ2FBIN(centers. - synth_center, - IS_CHAN_2GHZ - (chan)), - bChans[idxL], bChans[idxR], - vpdTableL[i][j], vpdTableR[i][j])); - } - } - } - - k = 0; - - for (i = 0; i < numXpdGains; i++) { - if (i == (numXpdGains - 1)) - pPdGainBoundaries[i] = - (u16)(maxPwrT4[i] / 2); - else - pPdGainBoundaries[i] = - (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); - - pPdGainBoundaries[i] = - min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); - - if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { - minDelta = pPdGainBoundaries[0] - 23; - pPdGainBoundaries[0] = 23; - } else { - minDelta = 0; - } - - if (i == 0) { - if (AR_SREV_9280_20_OR_LATER(ah)) - ss = (int16_t)(0 - (minPwrT4[i] / 2)); - else - ss = 0; - } else { - ss = (int16_t)((pPdGainBoundaries[i - 1] - - (minPwrT4[i] / 2)) - - tPdGainOverlap + 1 + minDelta); - } - vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); - pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); - ss++; - } - - sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); - tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - - (minPwrT4[i] / 2)); - maxIndex = (tgtIndex < sizeCurrVpdTable) ? - tgtIndex : sizeCurrVpdTable; - - while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) - pPDADCValues[k++] = vpdTableI[i][ss++]; - - vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - - vpdTableI[i][sizeCurrVpdTable - 2]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - if (tgtIndex >= maxIndex) { - while ((ss <= tgtIndex) && - (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t) TMP_VAL_VPD_TABLE; - pPDADCValues[k++] = (u8)((tmpVal > 255) ? - 255 : tmpVal); - ss++; - } - } - } - - while (i < AR5416_PD_GAINS_IN_MASK) { - pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT; - i++; - } - - while (k < AR5416_NUM_PDADC_VALUES) { - pPDADCValues[k] = pPDADCValues[k - 1]; - k++; - } - - return; -#undef TMP_VAL_VPD_TABLE -} - static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) @@ -455,7 +288,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, if (pEepData->baseEepHeader.txMask & (1 << i)) { pRawDataset = pEepData->calPierData2G[i]; - ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, + ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, gainBoundaries, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index da96a78f996d..ad3e234a673b 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -588,168 +588,6 @@ static void ath9k_hw_def_set_addac(struct ath_hw *ah, #undef XPA_LVL_FREQ } -static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, - struct ath9k_channel *chan, - struct cal_data_per_freq *pRawDataSet, - u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, - u16 *pPdGainBoundaries, u8 *pPDADCValues, - u16 numXpdGains) -{ - int i, j, k; - int16_t ss; - u16 idxL = 0, idxR = 0, numPiers; - static u8 vpdTableL[AR5416_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableR[AR5416_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableI[AR5416_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - - u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; - u8 minPwrT4[AR5416_NUM_PD_GAINS]; - u8 maxPwrT4[AR5416_NUM_PD_GAINS]; - int16_t vpdStep; - int16_t tmpVal; - u16 sizeCurrVpdTable, maxIndex, tgtIndex; - bool match; - int16_t minDelta = 0; - struct chan_centers centers; - - memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); - ath9k_hw_get_channel_centers(ah, chan, ¢ers); - - for (numPiers = 0; numPiers < availPiers; numPiers++) { - if (bChans[numPiers] == AR5416_BCHAN_UNUSED) - break; - } - - match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, - IS_CHAN_2GHZ(chan)), - bChans, numPiers, &idxL, &idxR); - - if (match) { - for (i = 0; i < numXpdGains; i++) { - minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; - maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pRawDataSet[idxL].pwrPdg[i], - pRawDataSet[idxL].vpdPdg[i], - AR5416_PD_GAIN_ICEPTS, - vpdTableI[i]); - } - } else { - for (i = 0; i < numXpdGains; i++) { - pVpdL = pRawDataSet[idxL].vpdPdg[i]; - pPwrL = pRawDataSet[idxL].pwrPdg[i]; - pVpdR = pRawDataSet[idxR].vpdPdg[i]; - pPwrR = pRawDataSet[idxR].pwrPdg[i]; - - minPwrT4[i] = max(pPwrL[0], pPwrR[0]); - - maxPwrT4[i] = - min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], - pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); - - - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrL, pVpdL, - AR5416_PD_GAIN_ICEPTS, - vpdTableL[i]); - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrR, pVpdR, - AR5416_PD_GAIN_ICEPTS, - vpdTableR[i]); - - for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { - vpdTableI[i][j] = - (u8)(ath9k_hw_interpolate((u16) - FREQ2FBIN(centers. - synth_center, - IS_CHAN_2GHZ - (chan)), - bChans[idxL], bChans[idxR], - vpdTableL[i][j], vpdTableR[i][j])); - } - } - } - - k = 0; - - for (i = 0; i < numXpdGains; i++) { - if (i == (numXpdGains - 1)) - pPdGainBoundaries[i] = - (u16)(maxPwrT4[i] / 2); - else - pPdGainBoundaries[i] = - (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); - - pPdGainBoundaries[i] = - min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); - - if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { - minDelta = pPdGainBoundaries[0] - 23; - pPdGainBoundaries[0] = 23; - } else { - minDelta = 0; - } - - if (i == 0) { - if (AR_SREV_9280_20_OR_LATER(ah)) - ss = (int16_t)(0 - (minPwrT4[i] / 2)); - else - ss = 0; - } else { - ss = (int16_t)((pPdGainBoundaries[i - 1] - - (minPwrT4[i] / 2)) - - tPdGainOverlap + 1 + minDelta); - } - vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); - pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); - ss++; - } - - sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); - tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - - (minPwrT4[i] / 2)); - maxIndex = (tgtIndex < sizeCurrVpdTable) ? - tgtIndex : sizeCurrVpdTable; - - while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { - pPDADCValues[k++] = vpdTableI[i][ss++]; - } - - vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - - vpdTableI[i][sizeCurrVpdTable - 2]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - if (tgtIndex >= maxIndex) { - while ((ss <= tgtIndex) && - (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + - (ss - maxIndex + 1) * vpdStep)); - pPDADCValues[k++] = (u8)((tmpVal > 255) ? - 255 : tmpVal); - ss++; - } - } - } - - while (i < AR5416_PD_GAINS_IN_MASK) { - pPdGainBoundaries[i] = pPdGainBoundaries[i - 1]; - i++; - } - - while (k < AR5416_NUM_PDADC_VALUES) { - pPDADCValues[k] = pPDADCValues[k - 1]; - k++; - } -} - static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, u16 *gb, u16 numXpdGain, @@ -916,7 +754,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, ath9k_olc_get_pdadcs(ah, pcdacIdx, txPower/2, pdadcValues); } else { - ath9k_hw_get_def_gain_boundaries_pdadcs(ah, + ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, -- cgit v1.2.3-59-g8ed1b From 940cd2c12ebff688cfdc14f21c4b0e5b845ad47f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:10 +0100 Subject: ath9k_hw: merge the ar9287 version of ath9k_hw_get_gain_boundaries_pdadcs Also add a comment about a potential array overrun that needs to be reviewed. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.c | 39 +++++-- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 159 +-------------------------- 2 files changed, 32 insertions(+), 166 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index d54cfa4e8057..d05163159572 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -309,7 +309,14 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, int pdgain_boundary_default; struct cal_data_per_freq *data_def = pRawDataSet; struct cal_data_per_freq_4k *data_4k = pRawDataSet; + struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet; bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah); + int intercepts; + + if (AR_SREV_9287(ah)) + intercepts = AR9287_PD_GAIN_ICEPTS; + else + intercepts = AR5416_PD_GAIN_ICEPTS; memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); @@ -324,14 +331,25 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, bChans, numPiers, &idxL, &idxR); if (match) { - if (eeprom_4k) { + if (AR_SREV_9287(ah)) { + /* FIXME: array overrun? */ + for (i = 0; i < numXpdGains; i++) { + minPwrT4[i] = data_9287[idxL].pwrPdg[i][0]; + maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4]; + ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], + data_9287[idxL].pwrPdg[i], + data_9287[idxL].vpdPdg[i], + intercepts, + vpdTableI[i]); + } + } else if (eeprom_4k) { for (i = 0; i < numXpdGains; i++) { minPwrT4[i] = data_4k[idxL].pwrPdg[i][0]; maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_4k[idxL].pwrPdg[i], data_4k[idxL].vpdPdg[i], - AR5416_PD_GAIN_ICEPTS, + intercepts, vpdTableI[i]); } } else { @@ -341,13 +359,18 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_def[idxL].pwrPdg[i], data_def[idxL].vpdPdg[i], - AR5416_PD_GAIN_ICEPTS, + intercepts, vpdTableI[i]); } } } else { for (i = 0; i < numXpdGains; i++) { - if (eeprom_4k) { + if (AR_SREV_9287(ah)) { + pVpdL = data_9287[idxL].vpdPdg[i]; + pPwrL = data_9287[idxL].pwrPdg[i]; + pVpdR = data_9287[idxR].vpdPdg[i]; + pPwrR = data_9287[idxR].pwrPdg[i]; + } else if (eeprom_4k) { pVpdL = data_4k[idxL].vpdPdg[i]; pPwrL = data_4k[idxL].pwrPdg[i]; pVpdR = data_4k[idxR].vpdPdg[i]; @@ -362,17 +385,17 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, minPwrT4[i] = max(pPwrL[0], pPwrR[0]); maxPwrT4[i] = - min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], - pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); + min(pPwrL[intercepts - 1], + pPwrR[intercepts - 1]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, - AR5416_PD_GAIN_ICEPTS, + intercepts, vpdTableL[i]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, - AR5416_PD_GAIN_ICEPTS, + intercepts, vpdTableR[i]); for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 4ba07da37457..868faf95ad2c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -220,163 +220,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah, } } -static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, - struct ath9k_channel *chan, - struct cal_data_per_freq_ar9287 *pRawDataSet, - u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, - u16 *pPdGainBoundaries, - u8 *pPDADCValues, - u16 numXpdGains) -{ -#define TMP_VAL_VPD_TABLE \ - ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); - - int i, j, k; - int16_t ss; - u16 idxL = 0, idxR = 0, numPiers; - u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; - u8 minPwrT4[AR5416_NUM_PD_GAINS]; - u8 maxPwrT4[AR5416_NUM_PD_GAINS]; - int16_t vpdStep; - int16_t tmpVal; - u16 sizeCurrVpdTable, maxIndex, tgtIndex; - bool match; - int16_t minDelta = 0; - struct chan_centers centers; - static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] - [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; - - memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); - ath9k_hw_get_channel_centers(ah, chan, ¢ers); - - for (numPiers = 0; numPiers < availPiers; numPiers++) { - if (bChans[numPiers] == AR5416_BCHAN_UNUSED) - break; - } - - match = ath9k_hw_get_lower_upper_index( - (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), - bChans, numPiers, &idxL, &idxR); - - if (match) { - for (i = 0; i < numXpdGains; i++) { - minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; - maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pRawDataSet[idxL].pwrPdg[i], - pRawDataSet[idxL].vpdPdg[i], - AR9287_PD_GAIN_ICEPTS, - vpdTableI[i]); - } - } else { - for (i = 0; i < numXpdGains; i++) { - pVpdL = pRawDataSet[idxL].vpdPdg[i]; - pPwrL = pRawDataSet[idxL].pwrPdg[i]; - pVpdR = pRawDataSet[idxR].vpdPdg[i]; - pPwrR = pRawDataSet[idxR].pwrPdg[i]; - - minPwrT4[i] = max(pPwrL[0], pPwrR[0]); - - maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], - pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); - - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrL, pVpdL, - AR9287_PD_GAIN_ICEPTS, - vpdTableL[i]); - ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrR, pVpdR, - AR9287_PD_GAIN_ICEPTS, - vpdTableR[i]); - - for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { - vpdTableI[i][j] = (u8)(ath9k_hw_interpolate( - (u16)FREQ2FBIN(centers. synth_center, - IS_CHAN_2GHZ(chan)), - bChans[idxL], bChans[idxR], - vpdTableL[i][j], vpdTableR[i][j])); - } - } - } - - k = 0; - - for (i = 0; i < numXpdGains; i++) { - if (i == (numXpdGains - 1)) - pPdGainBoundaries[i] = - (u16)(maxPwrT4[i] / 2); - else - pPdGainBoundaries[i] = - (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4); - - pPdGainBoundaries[i] = min((u16)MAX_RATE_POWER, - pPdGainBoundaries[i]); - - - minDelta = 0; - - if (i == 0) { - if (AR_SREV_9280_20_OR_LATER(ah)) - ss = (int16_t)(0 - (minPwrT4[i] / 2)); - else - ss = 0; - } else { - ss = (int16_t)((pPdGainBoundaries[i-1] - - (minPwrT4[i] / 2)) - - tPdGainOverlap + 1 + minDelta); - } - - vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); - pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); - ss++; - } - - sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); - tgtIndex = (u8)(pPdGainBoundaries[i] + - tPdGainOverlap - (minPwrT4[i] / 2)); - maxIndex = (tgtIndex < sizeCurrVpdTable) ? - tgtIndex : sizeCurrVpdTable; - - while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) - pPDADCValues[k++] = vpdTableI[i][ss++]; - - vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - - vpdTableI[i][sizeCurrVpdTable - 2]); - vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - - if (tgtIndex > maxIndex) { - while ((ss <= tgtIndex) && - (k < (AR5416_NUM_PDADC_VALUES - 1))) { - tmpVal = (int16_t) TMP_VAL_VPD_TABLE; - pPDADCValues[k++] = - (u8)((tmpVal > 255) ? 255 : tmpVal); - ss++; - } - } - } - - while (i < AR5416_PD_GAINS_IN_MASK) { - pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; - i++; - } - - while (k < AR5416_NUM_PDADC_VALUES) { - pPDADCValues[k] = pPDADCValues[k-1]; - k++; - } - -#undef TMP_VAL_VPD_TABLE -} - static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, @@ -525,7 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, (struct cal_data_per_freq_ar9287 *) pEepData->calPierData2G[i]; - ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan, + ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, -- cgit v1.2.3-59-g8ed1b From df3c8b2b10b47429d2f3fe79d00daa38a3381aad Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:11 +0100 Subject: ath9k_hw: remove antenna configuration eeprom ops and variables AR9280 based hardware with 3 antennas and slow antenna diversity has not been seen in the wild and ath9k does not support that form of antenna diversity, so remove the EEPROM ops for it. These EEPROM ops are currently only used for setting the AR_PHY_SWITCH_COM register, which is being done in the EEPROM specific file already. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 14 ----------- drivers/net/wireless/ath/ath9k/eeprom.h | 4 ---- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 20 +--------------- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 20 +--------------- drivers/net/wireless/ath/ath9k/eeprom_def.c | 33 +------------------------- drivers/net/wireless/ath/ath9k/hw.c | 5 ---- drivers/net/wireless/ath/ath9k/hw.h | 2 -- 7 files changed, 3 insertions(+), 95 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 2fc3260579a3..5ad37d05a85d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3427,18 +3427,6 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) return 0; } -static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, - enum ath9k_hal_freq_band freq_band) -{ - return 1; -} - -static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - return -EINVAL; -} - static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) { struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; @@ -4848,8 +4836,6 @@ const struct eeprom_ops eep_ar9300_ops = { .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, - .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, - .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, .set_board_values = ath9k_hw_ar9300_set_board_values, .set_addac = ath9k_hw_ar9300_set_addac, .set_txpower = ath9k_hw_ar9300_set_txpower, diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 1f6b712898e6..f6f09d1378f4 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -649,10 +649,6 @@ struct eeprom_ops { bool (*fill_eeprom)(struct ath_hw *hw); int (*get_eeprom_ver)(struct ath_hw *hw); int (*get_eeprom_rev)(struct ath_hw *hw); - u8 (*get_num_ant_config)(struct ath_hw *hw, - enum ath9k_hal_freq_band band); - u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, - struct ath9k_channel *chan); void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index b0f744687900..fbdff7e47952 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -770,8 +770,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, pModal = &eep->modalHeader; txRxAttenLocal = 23; - REG_WRITE(ah, AR_PHY_SWITCH_COM, - ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); + REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); /* Single chain for 4K EEPROM*/ ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); @@ -987,21 +986,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, } } -static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; - struct modal_eep_4k_header *pModal = &eep->modalHeader; - - return pModal->antCtrlCommon; -} - -static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, - enum ath9k_hal_freq_band freq_band) -{ - return 1; -} - static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) { #define EEP_MAP4K_SPURCHAN \ @@ -1038,8 +1022,6 @@ const struct eeprom_ops eep_4k_ops = { .fill_eeprom = ath9k_hw_4k_fill_eeprom, .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, - .get_num_ant_config = ath9k_hw_4k_get_num_ant_config, - .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg, .set_board_values = ath9k_hw_4k_set_board_values, .set_addac = ath9k_hw_4k_set_addac, .set_txpower = ath9k_hw_4k_set_txpower, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 868faf95ad2c..9b6bc8a953bc 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -866,8 +866,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); } - REG_WRITE(ah, AR_PHY_SWITCH_COM, - ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); + REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); for (i = 0; i < AR9287_MAX_CHAINS; i++) { regChainOffset = i * 0x1000; @@ -968,21 +967,6 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, pModal->xpaBiasLvl); } -static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah, - enum ath9k_hal_freq_band freq_band) -{ - return 1; -} - -static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ar9287_eeprom *eep = &ah->eeprom.map9287; - struct modal_eep_ar9287_header *pModal = &eep->modalHeader; - - return pModal->antCtrlCommon; -} - static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) { @@ -1020,8 +1004,6 @@ const struct eeprom_ops eep_ar9287_ops = { .fill_eeprom = ath9k_hw_ar9287_fill_eeprom, .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, - .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config, - .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg, .set_board_values = ath9k_hw_ar9287_set_board_values, .set_addac = ath9k_hw_ar9287_set_addac, .set_txpower = ath9k_hw_ar9287_set_txpower, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index ad3e234a673b..088f141f2006 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -374,8 +374,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; - REG_WRITE(ah, AR_PHY_SWITCH_COM, - ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); + REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff); for (i = 0; i < AR5416_MAX_CHAINS; i++) { if (AR_SREV_9280(ah)) { @@ -1264,34 +1263,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); } -static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, - enum ath9k_hal_freq_band freq_band) -{ - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - struct modal_eep_header *pModal = - &(eep->modalHeader[freq_band]); - struct base_eep_header *pBase = &eep->baseEepHeader; - u8 num_ant_config; - - num_ant_config = 1; - - if (pBase->version >= 0x0E0D && - (pModal->lna_ctl & LNA_CTL_USE_ANT1)) - num_ant_config += 1; - - return num_ant_config; -} - -static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - struct modal_eep_header *pModal = - &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); - - return pModal->antCtrlCommon; -} - static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) { #define EEP_DEF_SPURCHAN \ @@ -1328,8 +1299,6 @@ const struct eeprom_ops eep_def_ops = { .fill_eeprom = ath9k_hw_def_fill_eeprom, .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, - .get_num_ant_config = ath9k_hw_def_get_num_ant_config, - .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg, .set_board_values = ath9k_hw_def_set_board_values, .set_addac = ath9k_hw_def_set_addac, .set_txpower = ath9k_hw_def_set_txpower, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7c3d2de93652..36e0cab21bb0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1902,11 +1902,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) AR_SREV_5416(ah)) pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; - pCap->num_antcfg_5ghz = - ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); - pCap->num_antcfg_2ghz = - ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); - if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 157e6bc2651a..910d3c62a6df 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -204,8 +204,6 @@ struct ath9k_hw_capabilities { u16 tx_triglevel_max; u16 reg_cap; u8 num_gpio_pins; - u8 num_antcfg_2ghz; - u8 num_antcfg_5ghz; u8 rx_hp_qdepth; u8 rx_lp_qdepth; u8 rx_status_len; -- cgit v1.2.3-59-g8ed1b From 6da5a720bab3866ba23a37841f6a61d96e498a3f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:12 +0100 Subject: ath9k_hw: clean up SREV version checks There's no need to have separate callbacks for pre-AR9003 vs AR9003 SREV version checks, so just merge those into one function. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 19 ------------------- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 13 ------------- drivers/net/wireless/ath/ath9k/hw.c | 21 +++++++++++++-------- drivers/net/wireless/ath/ath9k/hw.h | 2 -- 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 7d5cb204f938..fdb5a835fdcf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -26,24 +26,6 @@ MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002"); /* General hardware code for the A5008/AR9001/AR9002 hadware families */ -static bool ar9002_hw_macversion_supported(u32 macversion) -{ - switch (macversion) { - case AR_SREV_VERSION_5416_PCI: - case AR_SREV_VERSION_5416_PCIE: - case AR_SREV_VERSION_9160: - case AR_SREV_VERSION_9100: - case AR_SREV_VERSION_9280: - case AR_SREV_VERSION_9285: - case AR_SREV_VERSION_9287: - case AR_SREV_VERSION_9271: - return true; - default: - break; - } - return false; -} - static void ar9002_hw_init_mode_regs(struct ath_hw *ah) { if (AR_SREV_9271(ah)) { @@ -565,7 +547,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; - priv_ops->macversion_supported = ar9002_hw_macversion_supported; ops->config_pci_powersave = ar9002_hw_configpcipowersave; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 21a5bfe354a0..6137634e46ca 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -21,18 +21,6 @@ /* General hardware code for the AR9003 hadware family */ -static bool ar9003_hw_macversion_supported(u32 macversion) -{ - switch (macversion) { - case AR_SREV_VERSION_9300: - case AR_SREV_VERSION_9485: - return true; - default: - break; - } - return false; -} - /* * The AR9003 family uses a new INI format (pre, core, post * arrays per subsystem). This provides support for the @@ -322,7 +310,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) priv_ops->init_mode_regs = ar9003_hw_init_mode_regs; priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; - priv_ops->macversion_supported = ar9003_hw_macversion_supported; ops->config_pci_powersave = ar9003_hw_configpcipowersave; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 36e0cab21bb0..a4389485e515 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -54,13 +54,6 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah) ath9k_hw_private_ops(ah)->init_mode_regs(ah); } -static bool ath9k_hw_macversion_supported(struct ath_hw *ah) -{ - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); - - return priv_ops->macversion_supported(ah->hw_version.macVersion); -} - static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -534,7 +527,19 @@ static int __ath9k_hw_init(struct ath_hw *ah) else ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; - if (!ath9k_hw_macversion_supported(ah)) { + switch (ah->hw_version.macVersion) { + case AR_SREV_VERSION_5416_PCI: + case AR_SREV_VERSION_5416_PCIE: + case AR_SREV_VERSION_9160: + case AR_SREV_VERSION_9100: + case AR_SREV_VERSION_9280: + case AR_SREV_VERSION_9285: + case AR_SREV_VERSION_9287: + case AR_SREV_VERSION_9271: + case AR_SREV_VERSION_9300: + case AR_SREV_VERSION_9485: + break; + default: ath_err(common, "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", ah->hw_version.macVersion, ah->hw_version.macRev); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 910d3c62a6df..e99b39514e8d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -532,7 +532,6 @@ struct ath_hw_radar_conf { * * @init_mode_regs: Initializes mode registers * @init_mode_gain_regs: Initialize TX/RX gain registers - * @macversion_supported: If this specific mac revision is supported * * @rf_set_freq: change frequency * @spur_mitigate_freq: spur mitigation @@ -554,7 +553,6 @@ struct ath_hw_private_ops { void (*init_mode_regs)(struct ath_hw *ah); void (*init_mode_gain_regs)(struct ath_hw *ah); - bool (*macversion_supported)(u32 macversion); void (*setup_calibration)(struct ath_hw *ah, struct ath9k_cal_list *currCal); -- cgit v1.2.3-59-g8ed1b From 5f65c309be7b9eae06136a5e7df43ea08b25d3f9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:13 +0100 Subject: ath9k_hw: remove ah->beacon_interval Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 3 --- drivers/net/wireless/ath/ath9k/hw.h | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a4389485e515..d0a0acd15d46 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -407,7 +407,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE | AR_STA_ID1_MCAST_KSRCH; - ah->beacon_interval = 100; ah->enable_32kHz_clock = DONT_USE_32KHZ; ah->slottime = (u32) -1; ah->globaltxtimeout = (u32) -1; @@ -1628,8 +1627,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) { int flags = 0; - ah->beacon_interval = beacon_period; - ENABLE_REGWRITE_BUFFER(ah); switch (ah->opmode) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e99b39514e8d..0db0ef69b4be 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -764,7 +764,6 @@ struct ath_hw { u8 txpower_limit; int16_t txpower_indexoffset; int coverage_class; - u32 beacon_interval; u32 slottime; u32 globaltxtimeout; -- cgit v1.2.3-59-g8ed1b From 62a957e99f6edced4a87f79cc49bfca42fe9a1a0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Dec 2010 00:51:14 +0100 Subject: ath9k_hw: remove ah->txpower_indexoffset Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 1 - drivers/net/wireless/ath/ath9k/ar9003_mac.c | 1 - drivers/net/wireless/ath/ath9k/hw.h | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index f3f9c589158e..399ab3bb299b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -283,7 +283,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, { struct ar5416_desc *ads = AR5416DESC(ds); - txPower += ah->txpower_indexoffset; if (txPower > 63) txPower = 63; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index bfba6a2b741d..b6e4ee48ef78 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -322,7 +322,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, if (txpower > ah->txpower_limit) txpower = ah->txpower_limit; - txpower += ah->txpower_indexoffset; if (txpower > 63) txpower = 63; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 0db0ef69b4be..c20e0476ee44 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -762,7 +762,6 @@ struct ath_hw { u32 *bank6Temp; u8 txpower_limit; - int16_t txpower_indexoffset; int coverage_class; u32 slottime; u32 globaltxtimeout; -- cgit v1.2.3-59-g8ed1b From 452d7dd816744efb5d0c22c2b038f2ffa5c7ec14 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 13 Dec 2010 07:39:32 +0530 Subject: ath9k_htc: Add Ubiquiti wifistation ext to supported devices Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index d0918bd23b8e..22b68b3c8566 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ + { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ { USB_DEVICE(0x0cf3, 0x7015), .driver_info = AR9287_USB }, /* Atheros */ -- cgit v1.2.3-59-g8ed1b From 4357c6bfc83d4e8b1f18588f640be27bf4b0d0f7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:50 +0100 Subject: ath9k_hw: initialize ah->slottime (u32) -1 is not particularly useful as a slottime default, so even though the ath9k_hw default should never get used, it's better to pick something sane here. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d0a0acd15d46..ce4891ea4889 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -408,7 +408,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) AR_STA_ID1_CRPT_MIC_ENABLE | AR_STA_ID1_MCAST_KSRCH; ah->enable_32kHz_clock = DONT_USE_32KHZ; - ah->slottime = (u32) -1; + ah->slottime = 20; ah->globaltxtimeout = (u32) -1; ah->power_mode = ATH9K_PM_UNDEFINED; } -- cgit v1.2.3-59-g8ed1b From caabf2bf228cd6b1c6197dbb25bddb4682d30c9d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:51 +0100 Subject: ath9k_hw: fix the slot time setting for long distance links Testing shows that adjusting the slot time based on the coverage class produces very high latencies and very low throughput on long distance links. Adjusting only the ACK timeout and leaving the slot time at the regular values - while technically not optimal for CSMA - works a lot better on long links (tested with 10 km distance) Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ce4891ea4889..0f373be9ef8c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -808,7 +808,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) acktimeout += 64 - sifstime - ah->slottime; - ath9k_hw_setslottime(ah, slottime); + ath9k_hw_setslottime(ah, ah->slottime); ath9k_hw_set_ack_timeout(ah, acktimeout); ath9k_hw_set_cts_timeout(ah, acktimeout); if (ah->globaltxtimeout != (u32) -1) -- cgit v1.2.3-59-g8ed1b From 7607cbe2ad6931400c5d15ced342ab329ab8f92c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:52 +0100 Subject: ath9k: fix PA predistortion thermal measurement handling To be able to measure the thermal values correctly for PAPRD, we need to send training frames before setting up the gain table for the measurement, and then again afterwards for the actual training. For further improvement, send training frames at MCS0 instead of 54 MBit/s legacy. That way we can use the No-ACK flag for the transmission, which speeds up PAPRD training in general, as the hardware won't have to retransmit and wait for ACK timeout (was previously set to 4 * 6 transmission attempts). Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 74 +++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5b4ef81318f5..d49dacbc96a7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -320,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc) ath9k_ps_restore(sc); } +static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) +{ + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_tx_control txctl; + int time_left; + + memset(&txctl, 0, sizeof(txctl)); + txctl.txq = sc->tx.txq_map[WME_AC_BE]; + + memset(tx_info, 0, sizeof(*tx_info)); + tx_info->band = hw->conf.channel->band; + tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; + tx_info->control.rates[0].idx = 0; + tx_info->control.rates[0].count = 1; + tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; + tx_info->control.rates[1].idx = -1; + + init_completion(&sc->paprd_complete); + sc->paprd_pending = true; + txctl.paprd = BIT(chain); + if (ath_tx_start(hw, skb, &txctl) != 0) + return false; + + time_left = wait_for_completion_timeout(&sc->paprd_complete, + msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); + sc->paprd_pending = false; + + if (!time_left) + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, + "Timeout waiting for paprd training on TX chain %d\n", + chain); + + return !!time_left; +} + void ath_paprd_calibrate(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); @@ -327,18 +363,12 @@ void ath_paprd_calibrate(struct work_struct *work) struct ath_hw *ah = sc->sc_ah; struct ieee80211_hdr *hdr; struct sk_buff *skb = NULL; - struct ieee80211_tx_info *tx_info; - int band = hw->conf.channel->band; - struct ieee80211_supported_band *sband = &sc->sbands[band]; - struct ath_tx_control txctl; struct ath9k_hw_cal_data *caldata = ah->caldata; struct ath_common *common = ath9k_hw_common(ah); int ftype; int chain_ok = 0; int chain; int len = 1800; - int time_left; - int i; if (!caldata) return; @@ -347,8 +377,6 @@ void ath_paprd_calibrate(struct work_struct *work) if (!skb) return; - tx_info = IEEE80211_SKB_CB(skb); - skb_put(skb, len); memset(skb->data, 0, len); hdr = (struct ieee80211_hdr *)skb->data; @@ -359,9 +387,6 @@ void ath_paprd_calibrate(struct work_struct *work) memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[WME_AC_BE]; - ath9k_ps_wakeup(sc); ar9003_paprd_init_table(ah); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { @@ -369,30 +394,19 @@ void ath_paprd_calibrate(struct work_struct *work) continue; chain_ok = 0; - memset(tx_info, 0, sizeof(*tx_info)); - tx_info->band = band; - for (i = 0; i < 4; i++) { - tx_info->control.rates[i].idx = sband->n_bitrates - 1; - tx_info->control.rates[i].count = 6; - } + ath_dbg(common, ATH_DBG_CALIBRATE, + "Sending PAPRD frame for thermal measurement " + "on chain %d\n", chain); + if (!ath_paprd_send_frame(sc, skb, chain)) + goto fail_paprd; - init_completion(&sc->paprd_complete); - sc->paprd_pending = true; ar9003_paprd_setup_gain_table(ah, chain); - txctl.paprd = BIT(chain); - if (ath_tx_start(hw, skb, &txctl) != 0) - break; - time_left = wait_for_completion_timeout(&sc->paprd_complete, - msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); - sc->paprd_pending = false; - if (!time_left) { - ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "Timeout waiting for paprd training on TX chain %d\n", - chain); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Sending PAPRD training frame on chain %d\n", chain); + if (!ath_paprd_send_frame(sc, skb, chain)) goto fail_paprd; - } if (!ar9003_paprd_is_done(ah)) break; -- cgit v1.2.3-59-g8ed1b From 1782352d4908c79d195b43e0c1b6b109e0d93d05 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:53 +0100 Subject: ath9k_hw: fix the PA predistortion rate mask The EEPROM PAPRD rate mask fields only contain mask values for actual rates in the low 25 bits. The upper bits are reserved for tx power scale values. Add the proper mask definitions and use them before writing the values to the register. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 6 ++++++ drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 620821ea6927..efb6a02be377 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -31,6 +31,12 @@ #define AR9300_ANT_16S 25 #define AR9300_FUTURE_MODAL_SZ 6 +#define AR9300_PAPRD_RATE_MASK 0x01ffffff +#define AR9300_PAPRD_SCALE_1 0x0e000000 +#define AR9300_PAPRD_SCALE_1_S 25 +#define AR9300_PAPRD_SCALE_2 0x70000000 +#define AR9300_PAPRD_SCALE_2_S 28 + /* Delta from which to start power to pdadc table */ /* This offset is used in both open loop and closed loop power control * schemes. In open loop power control, it is not really needed, but for diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 74cff4365c43..cdca4c3265b9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -52,8 +52,8 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) else hdr = &eep->modalHeader2G; - am_mask = le32_to_cpu(hdr->papdRateMaskHt20); - ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40); + am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK; + ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK; REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); -- cgit v1.2.3-59-g8ed1b From 1bf38661822049931a0ab8d2b43153b26cc919f6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:54 +0100 Subject: ath9k_hw: fix PA predistortion training power selection The EEPROM contains scale factors for the tx power, which define the range of allowable difference between target power and training power. If the difference is too big, PA predistortion cannot be used. For 2.4 GHz there is only one scale factor, for 5 GHz there are three, depending on the specific frequency range. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 13 ++++ drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 102 +++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 8 ++ drivers/net/wireless/ath/ath9k/hw.h | 2 + drivers/net/wireless/ath/ath9k/main.c | 4 +- 5 files changed, 112 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 5ad37d05a85d..4149ffb6d54a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4798,6 +4798,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, /* Write target power array to registers */ ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); ar9003_hw_calibration_apply(ah, chan->channel); + + if (IS_CHAN_2GHZ(chan)) { + if (IS_CHAN_HT40(chan)) + i = ALL_TARGET_HT40_0_8_16; + else + i = ALL_TARGET_HT20_0_8_16; + } else { + if (IS_CHAN_HT40(chan)) + i = ALL_TARGET_HT40_7; + else + i = ALL_TARGET_HT20_7; + } + ah->paprd_target_power = targetPowerValT2[i]; } static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index cdca4c3265b9..69f779237d28 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -30,8 +30,68 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) } EXPORT_SYMBOL(ar9003_paprd_enable); -static void ar9003_paprd_setup_single_table(struct ath_hw *ah) +static int ar9003_get_training_power_2g(struct ath_hw *ah) { + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G; + unsigned int power, scale, delta; + + scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1); + power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, + AR_PHY_POWERTX_RATE5_POWERTXHT20_0); + + delta = abs((int) ah->paprd_target_power - (int) power); + if (delta > scale) + return -1; + + if (delta < 4) + power -= 4 - delta; + + return power; +} + +static int get_streams(int mask) +{ + return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2)); +} + +static int ar9003_get_training_power_5g(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G; + struct ath9k_channel *chan = ah->curchan; + unsigned int power, scale, delta; + + if (chan->channel >= 5700) + scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), + AR9300_PAPRD_SCALE_1); + else if (chan->channel >= 5400) + scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), + AR9300_PAPRD_SCALE_2); + else + scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), + AR9300_PAPRD_SCALE_1); + + if (IS_CHAN_HT40(chan)) + power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8, + AR_PHY_POWERTX_RATE8_POWERTXHT40_5); + else + power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6, + AR_PHY_POWERTX_RATE6_POWERTXHT20_5); + + power += scale; + delta = abs((int) ah->paprd_target_power - (int) power); + if (delta > scale) + return -1; + + power += 2 * get_streams(common->tx_chainmask); + return power; +} + +static int ar9003_paprd_setup_single_table(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; struct ar9300_modal_eep_header *hdr; static const u32 ctrl0[3] = { @@ -45,6 +105,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_CTRL1_B2 }; u32 am_mask, ht40_mask; + int training_power; int i; if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) @@ -55,11 +116,25 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK; ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK; + if (IS_CHAN_2GHZ(ah->curchan)) + training_power = ar9003_get_training_power_2g(ah); + else + training_power = ar9003_get_training_power_5g(ah); + + if (training_power < 0) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "PAPRD target power delta out of range"); + return -ERANGE; + } + ah->paprd_training_power = training_power; + ath_dbg(common, ATH_DBG_CALIBRATE, + "Training power: %d, Target power: %d\n", + ah->paprd_training_power, ah->paprd_target_power); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); - for (i = 0; i < ah->caps.max_txchains; i++) { REG_RMW_FIELD(ah, ctrl0[i], AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); @@ -141,6 +216,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_PRE_POST_SCALING, 185706); REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, AR_PHY_PAPRD_PRE_POST_SCALING, 175487); + return 0; } static void ar9003_paprd_get_gain_table(struct ath_hw *ah) @@ -595,15 +671,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah, { u32 *paprd_table_val = caldata->pa_table[chain]; u32 small_signal_gain = caldata->small_signal_gain[chain]; - u32 training_power; + u32 training_power = ah->paprd_training_power; u32 reg = 0; int i; - training_power = - REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, - AR_PHY_POWERTX_RATE5_POWERTXHT20_0); - training_power -= 4; - if (chain == 0) reg = AR_PHY_PAPRD_MEM_TAB_B0; else if (chain == 1) @@ -643,14 +714,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table); int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) { - unsigned int i, desired_gain, gain_index; - unsigned int train_power; - - train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, - AR_PHY_POWERTX_RATE5_POWERTXHT20_0); - - train_power = train_power - 4; + unsigned int train_power = ah->paprd_training_power; desired_gain = ar9003_get_desired_gain(ah, chain, train_power); @@ -716,7 +781,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve); int ar9003_paprd_init_table(struct ath_hw *ah) { - ar9003_paprd_setup_single_table(ah); + int ret; + + ret = ar9003_paprd_setup_single_table(ah); + if (ret < 0) + return ret; + ar9003_paprd_get_gain_table(ah); return 0; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 6f811c7ada05..59bab6bd8a74 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -1090,6 +1090,14 @@ #define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F #define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 +#define AR_PHY_POWERTX_RATE6 (AR_SM_BASE + 0x1d4) +#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5 0x3F00 +#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S 8 + +#define AR_PHY_POWERTX_RATE8 (AR_SM_BASE + 0x1dc) +#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00 +#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8 + void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); #endif /* AR9003_PHY_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c20e0476ee44..97f22c428603 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -833,6 +833,8 @@ struct ath_hw { u32 bb_watchdog_last_status; u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ + unsigned int paprd_target_power; + unsigned int paprd_training_power; u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; /* diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d49dacbc96a7..c68205dea1fa 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -373,6 +373,9 @@ void ath_paprd_calibrate(struct work_struct *work) if (!caldata) return; + if (ar9003_paprd_init_table(ah) < 0) + return; + skb = alloc_skb(len, GFP_KERNEL); if (!skb) return; @@ -388,7 +391,6 @@ void ath_paprd_calibrate(struct work_struct *work) memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); ath9k_ps_wakeup(sc); - ar9003_paprd_init_table(ah); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { if (!(common->tx_chainmask & BIT(chain))) continue; -- cgit v1.2.3-59-g8ed1b From e172e0f8c25a513d253c07b1dc1d7e3c66a811ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:55 +0100 Subject: ath9k_hw: update AR9003 initvals for improved radar detection Reduces the likelihood of false pulse detects in the hardware Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index a14a5e43cf56..ec50ca1dcb3f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -638,6 +638,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = { {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f}, {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, @@ -680,7 +681,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = { {0x0000981c, 0x00020028}, {0x00009834, 0x6400a290}, {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, + {0x0000983c, 0x0d000600}, {0x00009880, 0x201fff00}, {0x00009884, 0x00001042}, {0x000098a4, 0x00200400}, @@ -722,7 +723,6 @@ static const u32 ar9300_2p2_baseband_core[][2] = { {0x0000a220, 0x00000000}, {0x0000a224, 0x00000000}, {0x0000a228, 0x10002310}, - {0x0000a22c, 0x01036a27}, {0x0000a23c, 0x00000000}, {0x0000a244, 0x0c000000}, {0x0000a2a0, 0x00000001}, -- cgit v1.2.3-59-g8ed1b From 7a7793ef078e56fa395f96567630032c44ab5951 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Dec 2010 08:40:56 +0100 Subject: ath9k_hw: update AR9003 initvals to improve carrier leak calibration/correction Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 100 ++++++++++----------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index ec50ca1dcb3f..81f9cf294dec 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -34,9 +34,9 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -56,21 +56,21 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -88,44 +88,44 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, + {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, + {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, -- cgit v1.2.3-59-g8ed1b From 38c8a566fcfe080c910bb6b348d40121df2b8e88 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Mon, 13 Dec 2010 12:31:27 +0100 Subject: rt2x00: Add rt2800 EEPROM definition Add and modify NIC Configuration and LED definition of EEPROM Signed-off-by: RA-Jay Hung Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 94 ++++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2800lib.c | 111 ++++++++++++++++---------------- 2 files changed, 119 insertions(+), 86 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index a81c4371835b..9dcbf87156b6 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1841,32 +1841,51 @@ struct mac_iveiv_entry { #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) /* - * EEPROM ANTENNA config + * EEPROM NIC Configuration 0 * RXPATH: 1: 1R, 2: 2R, 3: 3R - * TXPATH: 1: 1T, 2: 2T - */ -#define EEPROM_ANTENNA 0x001a -#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f) -#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0) -#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00) - -/* - * EEPROM NIC config - * CARDBUS_ACCEL: 0 - enable, 1 - disable - */ -#define EEPROM_NIC 0x001b -#define EEPROM_NIC_HW_RADIO FIELD16(0x0001) -#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002) -#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004) -#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008) -#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010) -#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020) -#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040) -#define EEPROM_NIC_WPS_PBC FIELD16(0x0080) -#define EEPROM_NIC_BW40M_BG FIELD16(0x0100) -#define EEPROM_NIC_BW40M_A FIELD16(0x0200) -#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800) -#define EEPROM_NIC_DAC_TEST FIELD16(0x8000) + * TXPATH: 1: 1T, 2: 2T, 3: 3T + * RF_TYPE: RFIC type + */ +#define EEPROM_NIC_CONF0 0x001a +#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f) +#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0) +#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00) + +/* + * EEPROM NIC Configuration 1 + * HW_RADIO: 0: disable, 1: enable + * EXTERNAL_TX_ALC: 0: disable, 1: enable + * EXTERNAL_LNA_2G: 0: disable, 1: enable + * EXTERNAL_LNA_5G: 0: disable, 1: enable + * CARDBUS_ACCEL: 0: enable, 1: disable + * BW40M_SB_2G: 0: disable, 1: enable + * BW40M_SB_5G: 0: disable, 1: enable + * WPS_PBC: 0: disable, 1: enable + * BW40M_2G: 0: enable, 1: disable + * BW40M_5G: 0: enable, 1: disable + * BROADBAND_EXT_LNA: 0: disable, 1: enable + * ANT_DIVERSITY: 00: Disable, 01: Diversity, + * 10: Main antenna, 11: Aux antenna + * INTERNAL_TX_ALC: 0: disable, 1: enable + * BT_COEXIST: 0: disable, 1: enable + * DAC_TEST: 0: disable, 1: enable + */ +#define EEPROM_NIC_CONF1 0x001b +#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) +#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) +#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004) +#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008) +#define EEPROM_NIC_CONF1_CARDBUS_ACCEL FIELD16(0x0010) +#define EEPROM_NIC_CONF1_BW40M_SB_2G FIELD16(0x0020) +#define EEPROM_NIC_CONF1_BW40M_SB_5G FIELD16(0x0040) +#define EEPROM_NIC_CONF1_WPS_PBC FIELD16(0x0080) +#define EEPROM_NIC_CONF1_BW40M_2G FIELD16(0x0100) +#define EEPROM_NIC_CONF1_BW40M_5G FIELD16(0x0200) +#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400) +#define EEPROM_NIC_CONF1_ANT_DIVERSITY FIELD16(0x1800) +#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) +#define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) +#define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) /* * EEPROM frequency @@ -1888,9 +1907,9 @@ struct mac_iveiv_entry { * POLARITY_GPIO_4: Polarity GPIO4 setting. * LED_MODE: Led mode. */ -#define EEPROM_LED1 0x001e -#define EEPROM_LED2 0x001f -#define EEPROM_LED3 0x0020 +#define EEPROM_LED_AG_CONF 0x001e +#define EEPROM_LED_ACT_CONF 0x001f +#define EEPROM_LED_POLARITY 0x0020 #define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001) #define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002) #define EEPROM_LED_POLARITY_ACT FIELD16(0x0004) @@ -1901,6 +1920,17 @@ struct mac_iveiv_entry { #define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080) #define EEPROM_LED_LED_MODE FIELD16(0x1f00) +/* + * EEPROM NIC Configuration 2 + * RX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream + * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream + * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved + */ +#define EEPROM_NIC_CONF2 0x0021 +#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) +#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) +#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) + /* * EEPROM LNA */ @@ -1951,7 +1981,7 @@ struct mac_iveiv_entry { /* * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. - * This is delta in 40MHZ. + * This is delta in 40MHZ. * VALUE: Tx Power dalta value (MAX=4) * TYPE: 1: Plus the delta value, 0: minus the delta value * TXPOWER: Enable: @@ -2007,9 +2037,9 @@ struct mac_iveiv_entry { #define MCU_CURRENT 0x36 #define MCU_LED 0x50 #define MCU_LED_STRENGTH 0x51 -#define MCU_LED_1 0x52 -#define MCU_LED_2 0x53 -#define MCU_LED_3 0x54 +#define MCU_LED_AG_CONF 0x52 +#define MCU_LED_ACT_CONF 0x53 +#define MCU_LED_LED_POLARITY 0x54 #define MCU_RADAR 0x60 #define MCU_BOOT_SIGNAL 0x72 #define MCU_BBP_SIGNAL 0x80 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 75631614aba3..9b592d9481b4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1930,8 +1930,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000002c); else @@ -2376,10 +2376,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3390)) { rt2800_bbp_read(rt2x00dev, 138, &value); - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) value |= 0x20; - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) value &= ~0x02; rt2800_bbp_write(rt2x00dev, 138, value); @@ -2591,8 +2591,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); else rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); @@ -2665,10 +2665,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3090)) { rt2800_bbp_read(rt2x00dev, 138, &bbp); - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); rt2800_bbp_write(rt2x00dev, 138, bbp); @@ -2767,16 +2767,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize LED control */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff, word & 0xff, (word >> 8) & 0xff); - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff, word & 0xff, (word >> 8) & 0xff); - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff, word & 0xff, (word >> 8) & 0xff); return 0; @@ -2870,38 +2870,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) EEPROM(rt2x00dev, "MAC: %pM\n", mac); } - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); if (word == 0xffff) { - rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); - rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); - rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); + rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); } else if (rt2x00_rt(rt2x00dev, RT2860) || rt2x00_rt(rt2x00dev, RT2872)) { /* * There is a max of 2 RX streams for RT28x0 series */ - if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) - rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); - rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); + if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2) + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); + rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); } - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word); if (word == 0xffff) { - rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); - rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); - rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); - rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); - rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); - rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); - rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); - rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); - rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); - rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); - rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0); - rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0); - rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); + rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); + rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); } @@ -2916,9 +2919,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) LED_MODE_TXRX_ACTIVITY); rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); + rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); + rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); + rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); } @@ -2982,12 +2985,12 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Read EEPROM word for configuration. */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); /* * Identify RF chipset. */ - value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); + value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); rt2800_register_read(rt2x00dev, MAC_CSR0, ®); rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), @@ -3023,9 +3026,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) * Identify default antenna configuration. */ rt2x00dev->default_ant.tx = - rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); rt2x00dev->default_ant.rx = - rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); /* * Read frequency offset and RF programming sequence. @@ -3036,17 +3039,17 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Read external LNA informations. */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); /* * Detect if this device has an hardware controlled radio. */ - if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO)) __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); /* @@ -3258,7 +3261,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); /* * Initialize hw_mode information. @@ -3302,11 +3305,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40; - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2) spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; spec->ht.cap |= - rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) << + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) << IEEE80211_HT_CAP_RX_STBC_SHIFT; spec->ht.ampdu_factor = 3; @@ -3314,10 +3317,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->ht.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED | IEEE80211_HT_MCS_TX_RX_DIFF | - ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << + ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) << IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); - switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { + switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) { case 3: spec->ht.mcs.rx_mask[2] = 0xff; case 2: -- cgit v1.2.3-59-g8ed1b From 977206d79fdc9fc1b153e0b52c56e0be59586f37 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 13 Dec 2010 12:31:58 +0100 Subject: rt2x00: Implement get_survey callback for rt2800 Implement the get_survey callback to allow user space to read statistics about the current channel condition. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 10 +++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 49 +++++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.h | 2 ++ drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + 5 files changed, 63 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9dcbf87156b6..03f9fa15e157 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -699,8 +699,18 @@ /* * CH_TIME_CFG: count as channel busy + * EIFS_BUSY: Count EIFS as channel busy + * NAV_BUSY: Count NAS as channel busy + * RX_BUSY: Count RX as channel busy + * TX_BUSY: Count TX as channel busy + * TMR_EN: Enable channel statistics timer */ #define CH_TIME_CFG 0x110c +#define CH_TIME_CFG_EIFS_BUSY FIELD32(0x00000010) +#define CH_TIME_CFG_NAV_BUSY FIELD32(0x00000008) +#define CH_TIME_CFG_RX_BUSY FIELD32(0x00000004) +#define CH_TIME_CFG_TX_BUSY FIELD32(0x00000002) +#define CH_TIME_CFG_TMR_EN FIELD32(0x00000001) /* * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9b592d9481b4..b7de1a504480 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1625,6 +1625,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, } msleep(1); + + /* + * Clear channel statistic counters + */ + rt2800_register_read(rt2x00dev, CH_IDLE_STA, ®); + rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®); + rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); } static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, @@ -2259,6 +2266,17 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg); + /* + * Set up channel statistics timer + */ + rt2800_register_read(rt2x00dev, CH_TIME_CFG, ®); + rt2x00_set_field32(®, CH_TIME_CFG_EIFS_BUSY, 1); + rt2x00_set_field32(®, CH_TIME_CFG_NAV_BUSY, 1); + rt2x00_set_field32(®, CH_TIME_CFG_RX_BUSY, 1); + rt2x00_set_field32(®, CH_TIME_CFG_TX_BUSY, 1); + rt2x00_set_field32(®, CH_TIME_CFG_TMR_EN, 1); + rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg); + return 0; } @@ -3539,6 +3557,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(rt2800_ampdu_action); +int rt2800_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + u32 idle, busy, busy_ext; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + + rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle); + rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy); + rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext); + + if (idle || busy) { + survey->filled = SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_EXT_BUSY; + + survey->channel_time = (idle + busy) / 1000; + survey->channel_time_busy = busy / 1000; + survey->channel_time_ext_busy = busy_ext / 1000; + } + + return 0; + +} +EXPORT_SYMBOL_GPL(rt2800_get_survey); + MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); MODULE_VERSION(DRV_VERSION); MODULE_DESCRIPTION("Ralink RT2800 library"); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 81cbc92e7857..e3c995a9dec4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -199,5 +199,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw); int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); +int rt2800_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey); #endif /* RT2800LIB_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b989b0d3ed49..f5abcc6e86b7 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -944,6 +944,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, .flush = rt2x00mac_flush, + .get_survey = rt2800_get_survey, }; static const struct rt2800_ops rt2800pci_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 935b76d3ce4f..042e47d92b6e 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -562,6 +562,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, .flush = rt2x00mac_flush, + .get_survey = rt2800_get_survey, }; static const struct rt2800_ops rt2800usb_rt2800_ops = { -- cgit v1.2.3-59-g8ed1b From 8d4ff3f3045e57f57634559c063bf70993a1d00a Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Mon, 13 Dec 2010 12:32:22 +0100 Subject: rt2x00: Add RF chip definition Add RF chip definition Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 03f9fa15e157..9ea09612c878 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -46,8 +46,11 @@ * RF2020 2.4G B/G * RF3021 2.4G 1T2R * RF3022 2.4G 2T2R - * RF3052 2.4G 2T2R - * RF3320 2.4G 1T1R + * RF3052 2.4G/5G 2T2R + * RF2853 2.4G/5G 3T3R + * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) + * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) + * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) */ #define RF2820 0x0001 #define RF2850 0x0002 @@ -58,7 +61,10 @@ #define RF3021 0x0007 #define RF3022 0x0008 #define RF3052 0x0009 +#define RF2853 0x000a #define RF3320 0x000b +#define RF3322 0x000c +#define RF3853 0x000d /* * Chipset revisions. -- cgit v1.2.3-59-g8ed1b From d7bb5f845f437662296adbfeaab8fbfce1c32289 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 13 Dec 2010 12:32:49 +0100 Subject: rt2x00: fix hang when unplugging USB device in use When an rt2x00 USB device is unplugged while in use, it reliably hangs the whole system. After some time the watchdog prints: BUG: soft lockup - CPU#0 stuck for 64s! [kworker/u:0:5] ... [] (usb_submit_urb+0x0/0x2ac) from [] (rt2x00usb_kick_rx_entry+0xb4/0xe8 [rt2x00usb]) [] (rt2x00usb_kick_rx_entry+0x0/0xe8 [rt2x00usb]) from [] (rt2x00usb_clear_entry+x28/0x2c [rt2x00usb]) [] (rt2x00usb_clear_entry+0x0/0x2c [rt2x00usb]) from [] (rt2x00lib_rxdone+0x2e0/0x2f8 [rt2x00lib]) [] (rt2x00lib_rxdone+0x0/0x2f8 [rt2x00lib]) from [] (rt2x00usb_work_rxdone+0x54/0x74 [rt2x00usb]) [] (rt2x00usb_work_rxdone+0x0/0x74 [rt2x00usb]) from [] (process_one_work+0x20c/0x35c) Clear the DEVICE_STATE_PRESENT flag when usb_submit_urb() returns -ENODEV to fix this. Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 9ac14598e2a0..3a6c83e3a9c6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -235,6 +235,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; u32 length; + int status; if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) return; @@ -251,7 +252,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) entry->skb->data, length, rt2x00usb_interrupt_txdone, entry); - if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); } @@ -435,6 +439,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) to_usb_device_intf(entry->queue->rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; int pipe; + int status; entry->flags = 0; @@ -445,7 +450,12 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) rt2x00usb_interrupt_rxdone, entry); set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, + &entry->queue->rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); } -- cgit v1.2.3-59-g8ed1b From a061a93b6eb8db8227b251666436da1e344771a0 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 13 Dec 2010 12:33:12 +0100 Subject: rt2x00: Ensure TX-ed frames are returned in the original state. Recent changes to the TX-done code of rt2x00 resulted in TX-ed frames not being returned to mac80211 in the original state, and therefore with insufficient headroom for re-transmissions. Fix this by reverting the changes done and by ensuring we remove the inserted L2pad by moving the header backwards instead of the data forwards. At the same time also make sure that the rt2x00queue_remove_l2pad will not move any memory when a frame has no data at all. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Cc: Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a3d79c7a21c6..35133d8558b5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -199,15 +199,18 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) { - unsigned int l2pad = L2PAD_SIZE(header_length); + /* + * L2 padding is only present if the skb contains more than just the + * IEEE 802.11 header. + */ + unsigned int l2pad = (skb->len > header_length) ? + L2PAD_SIZE(header_length) : 0; if (!l2pad) return; - memmove(skb->data + header_length, skb->data + header_length + l2pad, - skb->len - header_length - l2pad); - - skb_trim(skb, skb->len - l2pad); + memmove(skb->data + l2pad, skb->data, header_length); + skb_pull(skb, l2pad); } static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, -- cgit v1.2.3-59-g8ed1b From 89b25f60e08180d7e00e6239398b467142aaec01 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 13 Dec 2010 12:33:36 +0100 Subject: rt2x00: Don't frequently reset beacon interval in AdHoc mode Commit 0204464329c17ba6d293e1899f71223599a0e582 "Check for specific changed flags when updating the erp config" changed the way in which a new beacon interval gets handled. However, due to a bug in rt2800usb and rt2800pci the beacon interval was reset during each scan, thus causing problems in AdHoc mode. Fix this by not cleaning up the beacon interval when killing the beacon queue but just prevent the device from sending out beacons. Reported-by: Wolfgang Kufner Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2500pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2500usb.c | 12 ++++++++++-- drivers/net/wireless/rt2x00/rt2800pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2800usb.c | 12 ++++++++++-- drivers/net/wireless/rt2x00/rt61pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt73usb.c | 12 ++++++++++-- 7 files changed, 50 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 9ec6691adf0d..62786608951e 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1140,7 +1140,11 @@ static void rt2400pci_kill_tx_queue(struct data_queue *queue) u32 reg; if (queue->qid == QID_BEACON) { - rt2x00pci_register_write(rt2x00dev, CSR14, 0); + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); + rt2x00_set_field32(®, CSR14_TBCN, 0); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3e7f20346243..ce9212f28207 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1294,7 +1294,11 @@ static void rt2500pci_kill_tx_queue(struct data_queue *queue) u32 reg; if (queue->qid == QID_BEACON) { - rt2x00pci_register_write(rt2x00dev, CSR14, 0); + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); + rt2x00_set_field32(®, CSR14_TBCN, 0); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 8152fec31753..bbfa671f1152 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1205,8 +1205,16 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) static void rt2500usb_kill_tx_queue(struct data_queue *queue) { - if (queue->qid == QID_BEACON) - rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u16 reg; + + if (queue->qid == QID_BEACON) { + rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); + rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); + rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); + rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + } rt2x00usb_kill_tx_queue(queue); } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index f5abcc6e86b7..533a8fc1f7c1 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -588,7 +588,11 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue) u32 reg; if (queue->qid == QID_BEACON) { - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); return; } diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 042e47d92b6e..a150fccffba2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -391,8 +391,16 @@ static void rt2800usb_work_txdone(struct work_struct *work) static void rt2800usb_kill_tx_queue(struct data_queue *queue) { - if (queue->qid == QID_BEACON) - rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0); + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + if (queue->qid == QID_BEACON) { + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } rt2x00usb_kill_tx_queue(queue); } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 6b09b01f634f..6ad0c1c9ce4e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1944,7 +1944,11 @@ static void rt61pci_kill_tx_queue(struct data_queue *queue) u32 reg; if (queue->qid == QID_BEACON) { - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); return; } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6f04552f5819..3934dad709c6 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1581,8 +1581,16 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) static void rt73usb_kill_tx_queue(struct data_queue *queue) { - if (queue->qid == QID_BEACON) - rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + if (queue->qid == QID_BEACON) { + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + } rt2x00usb_kill_tx_queue(queue); } -- cgit v1.2.3-59-g8ed1b From 094a1d92fdb18c4455758b1c33e99d647c837ee9 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 13 Dec 2010 12:34:00 +0100 Subject: rt2x00: trivial: add missing \n on warnings Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2800usb.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 533a8fc1f7c1..49447222e40f 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -686,7 +686,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * this tx status. */ WARNING(rt2x00dev, "Got TX status report with " - "unexpected pid %u, dropping", qid); + "unexpected pid %u, dropping\n", qid); break; } @@ -697,7 +697,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * processing here and drop the tx status */ WARNING(rt2x00dev, "Got TX status for an unavailable " - "queue %u, dropping", qid); + "queue %u, dropping\n", qid); break; } @@ -707,7 +707,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * and drop the tx status. */ WARNING(rt2x00dev, "Got TX status for an empty " - "queue %u, dropping", qid); + "queue %u, dropping\n", qid); break; } diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index a150fccffba2..1dfa59da9272 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -253,7 +253,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { WARNING(rt2x00dev, "TX HW queue 0 timed out," - " invoke forced kick"); + " invoke forced kick\n"); rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); @@ -269,7 +269,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { WARNING(rt2x00dev, "TX HW queue 1 timed out," - " invoke forced kick"); + " invoke forced kick\n"); rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 829bf4be9bc3..7ad4b276156e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -745,7 +745,7 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) } if (!rt2x00queue_empty(queue)) - WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid); + WARNING(rt2x00dev, "Failed to flush queue %d\n", queue->qid); } ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 3a6c83e3a9c6..608200eaf0dc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -300,7 +300,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) unsigned short threshold = queue->threshold; WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," - " invoke forced forced reset", queue->qid); + " invoke forced forced reset\n", queue->qid); /* * Temporarily disable the TX queue, this will force mac80211 @@ -335,7 +335,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) { WARNING(queue->rt2x00dev, "TX queue %d status timed out," - " invoke forced tx handler", queue->qid); + " invoke forced tx handler\n", queue->qid); ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); } -- cgit v1.2.3-59-g8ed1b From 5450b7e2f0b47e52175b31399d8186a74ef3c46d Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:34:22 +0100 Subject: rt2x00: Introduce 3 queue commands in drivers (start, kick, stop). As part of the queue refactoring, we now introduce 3 queue commands: start, kick, stop. - Start: will enable a queue, for TX this will not mean anything, while for beacons and RX this will update the registers to enable the queue. - Kick: This will kick all pending frames to the hardware. This is needed for the TX queue to push all frames to the HW after the queue has been started - Stop: This will stop the queue in the hardware, and cancel any pending work (So this doesn't mean the queue is empty after a stop!). Move all code from the drivers into the appropriate functions, and link those calls to the old rt2x00lib callback functions (we will fix this later when we refactor the queue control inside rt2x00lib). Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 131 ++++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2500pci.c | 131 ++++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2500usb.c | 84 +++++++++++------ drivers/net/wireless/rt2x00/rt2800pci.c | 129 +++++++++++++++----------- drivers/net/wireless/rt2x00/rt2800usb.c | 84 +++++++++++------ drivers/net/wireless/rt2x00/rt2x00usb.c | 12 +-- drivers/net/wireless/rt2x00/rt2x00usb.h | 8 +- drivers/net/wireless/rt2x00/rt61pci.c | 154 ++++++++++++++++++++++---------- drivers/net/wireless/rt2x00/rt73usb.c | 84 +++++++++++------ 9 files changed, 530 insertions(+), 287 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 62786608951e..35d9a06a76af 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -632,6 +632,88 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev, rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); } +/* + * Queue handlers. + */ +static void rt2400pci_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); + rt2x00_set_field32(®, CSR14_TBCN, 1); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); + break; + default: + break; + } +} + +static void rt2400pci_kick_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_AC_BK: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_ATIM: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + default: + break; + } +} + +static void rt2400pci_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_ATIM: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_ABORT, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_RX: + rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); + rt2x00_set_field32(®, CSR14_TBCN, 0); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); + break; + default: + break; + } +} + /* * Initialization functions. */ @@ -878,17 +960,6 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); - rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF)); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); -} - static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { @@ -988,8 +1059,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + rt2400pci_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt2400pci_toggle_rx(rt2x00dev, state); + rt2400pci_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -1122,36 +1195,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2400pci_kick_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); -} - -static void rt2400pci_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2x00pci_register_read(rt2x00dev, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); - rt2x00_set_field32(®, CSR14_TBCN, 0); - rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); - } else { - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_ABORT, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); - } -} - /* * RX control handlers */ @@ -1631,8 +1674,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .link_tuner = rt2400pci_link_tuner, .write_tx_desc = rt2400pci_write_tx_desc, .write_beacon = rt2400pci_write_beacon, - .kick_tx_queue = rt2400pci_kick_tx_queue, - .kill_tx_queue = rt2400pci_kill_tx_queue, + .kick_tx_queue = rt2400pci_kick_queue, + .kill_tx_queue = rt2400pci_stop_queue, .fill_rxdone = rt2400pci_fill_rxdone, .config_filter = rt2400pci_config_filter, .config_intf = rt2400pci_config_intf, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index ce9212f28207..bee7ce14028d 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -722,6 +722,88 @@ dynamic_cca_tune: rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg); } +/* + * Queue handlers. + */ +static void rt2500pci_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); + rt2x00_set_field32(®, CSR14_TBCN, 1); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); + break; + default: + break; + } +} + +static void rt2500pci_kick_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_AC_BK: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_ATIM: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + default: + break; + } +} + +static void rt2500pci_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_ATIM: + rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00_set_field32(®, TXCSR0_ABORT, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + break; + case QID_RX: + rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); + rt2x00_set_field32(®, CSR14_TBCN, 0); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); + break; + default: + break; + } +} + /* * Initialization functions. */ @@ -1033,17 +1115,6 @@ static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); - rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF)); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); -} - static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { @@ -1143,8 +1214,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + rt2500pci_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt2500pci_toggle_rx(rt2x00dev, state); + rt2500pci_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -1276,36 +1349,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2500pci_kick_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); -} - -static void rt2500pci_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2x00pci_register_read(rt2x00dev, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); - rt2x00_set_field32(®, CSR14_TBCN, 0); - rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); - } else { - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_ABORT, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); - } -} - /* * RX control handlers */ @@ -1928,8 +1971,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .link_tuner = rt2500pci_link_tuner, .write_tx_desc = rt2500pci_write_tx_desc, .write_beacon = rt2500pci_write_beacon, - .kick_tx_queue = rt2500pci_kick_tx_queue, - .kill_tx_queue = rt2500pci_kill_tx_queue, + .kick_tx_queue = rt2500pci_kick_queue, + .kill_tx_queue = rt2500pci_stop_queue, .fill_rxdone = rt2500pci_fill_rxdone, .config_filter = rt2500pci_config_filter, .config_intf = rt2500pci_config_intf, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index bbfa671f1152..52bd0ed0872b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -738,6 +738,57 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev, qual->vgc_level = value; } +/* + * Queue handlers. + */ +static void rt2500usb_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u16 reg; + + switch (queue->qid) { + case QID_RX: + rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); + rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, 0); + rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); + break; + case QID_BEACON: + rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); + rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); + rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); + rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + break; + default: + break; + } +} + +static void rt2500usb_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u16 reg; + + switch (queue->qid) { + case QID_RX: + rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); + rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, 1); + rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); + break; + case QID_BEACON: + rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); + rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); + rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); + rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + break; + default: + break; + } + + rt2x00usb_stop_queue(queue); +} + /* * Initialization functions. */ @@ -931,17 +982,6 @@ static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u16 reg; - - rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); - rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, - (state == STATE_RADIO_RX_OFF)); - rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); -} - static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) { /* @@ -1018,8 +1058,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + rt2500usb_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt2500usb_toggle_rx(rt2x00dev, state); + rt2500usb_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -1203,22 +1245,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) return length; } -static void rt2500usb_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u16 reg; - - if (queue->qid == QID_BEACON) { - rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); - rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); - rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); - rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); - } - - rt2x00usb_kill_tx_queue(queue); -} - /* * RX control handlers */ @@ -1823,7 +1849,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2500usb_kill_tx_queue, + .kill_tx_queue = rt2500usb_stop_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_shared_key = rt2500usb_config_key, .config_pairwise_key = rt2500usb_config_key, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 49447222e40f..a7105974a2a1 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -185,6 +185,77 @@ static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) } #endif /* CONFIG_PCI */ +/* + * Queue handlers. + */ +static void rt2800pci_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + break; + default: + break; + }; +} + +static void rt2800pci_kick_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + struct queue_entry *entry; + + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VI: + case QID_AC_VO: + entry = rt2x00queue_get_entry(queue, Q_INDEX); + rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx); + break; + case QID_MGMT: + entry = rt2x00queue_get_entry(queue, Q_INDEX); + rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx); + break; + default: + break; + } +} + +static void rt2800pci_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + break; + default: + break; + } +} + /* * Firmware functions */ @@ -323,17 +394,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON)); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); -} - static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { @@ -478,8 +538,10 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: + rt2800pci_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt2800pci_toggle_rx(rt2x00dev, state); + rt2800pci_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -565,45 +627,6 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, skbdesc->desc_len = TXD_DESC_SIZE; } -/* - * TX data initialization - */ -static void rt2800pci_kick_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); - unsigned int qidx; - - if (queue->qid == QID_MGMT) - qidx = 5; - else - qidx = queue->qid; - - rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx); -} - -static void rt2800pci_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - return; - } - - rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO)); - rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); -} - /* * RX control handlers */ @@ -984,8 +1007,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, - .kick_tx_queue = rt2800pci_kick_tx_queue, - .kill_tx_queue = rt2800pci_kill_tx_queue, + .kick_tx_queue = rt2800pci_kick_queue, + .kill_tx_queue = rt2800pci_stop_queue, .fill_rxdone = rt2800pci_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 1dfa59da9272..ee51936d8d1b 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -49,6 +49,57 @@ static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); +/* + * Queue handlers. + */ +static void rt2800usb_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + break; + default: + break; + } +} + +static void rt2800usb_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + break; + default: + break; + } + + rt2x00usb_stop_queue(queue); +} + /* * Firmware functions */ @@ -107,17 +158,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, /* * Device state switch handlers. */ -static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON)); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); -} - static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; @@ -215,8 +255,10 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: + rt2800usb_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt2800usb_toggle_rx(rt2x00dev, state); + rt2800usb_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -389,22 +431,6 @@ static void rt2800usb_work_txdone(struct work_struct *work) } } -static void rt2800usb_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - } - - rt2x00usb_kill_tx_queue(queue); -} - /* * RX control handlers */ @@ -605,7 +631,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2800usb_kill_tx_queue, + .kill_tx_queue = rt2800usb_stop_queue, .fill_rxdone = rt2800usb_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 608200eaf0dc..12958a45e450 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -268,7 +268,7 @@ void rt2x00usb_kick_tx_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); -static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) +static void rt2x00usb_kill_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv = entry->priv_data; @@ -287,12 +287,12 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) usb_kill_urb(bcn_priv->guardian_urb); } -void rt2x00usb_kill_tx_queue(struct data_queue *queue) +void rt2x00usb_stop_queue(struct data_queue *queue) { rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, - rt2x00usb_kill_tx_entry); + rt2x00usb_kill_entry); } -EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); +EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { @@ -316,7 +316,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) * Kill all entries in the queue, afterwards we need to * wait a bit for all URBs to be cancelled. */ - rt2x00usb_kill_tx_queue(queue); + rt2x00usb_stop_queue(queue); /* * In case that a driver has overriden the txdone_work @@ -423,7 +423,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) REGISTER_TIMEOUT); /* - * The USB version of kill_tx_queue also works + * The USB version of also works * on the RX queue. */ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index c2d997f67b3e..656a35f421a3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -387,13 +387,13 @@ struct queue_entry_priv_usb_bcn { void rt2x00usb_kick_tx_queue(struct data_queue *queue); /** - * rt2x00usb_kill_tx_queue - Kill data queue - * @queue: Data queue to kill + * rt2x00usb_stop_queue - Stop data queue + * @queue: Data queue to stop * * This will walk through all entries of the queue and kill all - * previously kicked frames before they can be send. + * URB's which were send to the device. */ -void rt2x00usb_kill_tx_queue(struct data_queue *queue); +void rt2x00usb_stop_queue(struct data_queue *queue); /** * rt2x00usb_watchdog - Watchdog for USB communication diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 6ad0c1c9ce4e..044f500ff1ab 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1139,6 +1139,106 @@ dynamic_cca_tune: rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); } +/* + * Queue handlers. + */ +static void rt61pci_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + break; + default: + break; + } +} + +static void rt61pci_kick_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_BK: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_VI: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_VO: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + default: + break; + } +} + +static void rt61pci_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_AC_BE: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_BK: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_VI: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_AC_VO: + rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); + rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + break; + case QID_RX: + rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + break; + case QID_BEACON: + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + break; + default: + break; + } +} + /* * Firmware functions */ @@ -1616,17 +1716,6 @@ static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); - rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF)); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); -} - static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { @@ -1744,8 +1833,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + rt61pci_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt61pci_toggle_rx(rt2x00dev, state); + rt61pci_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -1925,41 +2016,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry, entry->skb = NULL; } -static void rt61pci_kick_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); -} - -static void rt61pci_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); - return; - } - - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO)); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); -} - /* * RX control handlers */ @@ -2846,8 +2902,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .link_tuner = rt61pci_link_tuner, .write_tx_desc = rt61pci_write_tx_desc, .write_beacon = rt61pci_write_beacon, - .kick_tx_queue = rt61pci_kick_tx_queue, - .kill_tx_queue = rt61pci_kill_tx_queue, + .kick_tx_queue = rt61pci_kick_queue, + .kill_tx_queue = rt61pci_stop_queue, .fill_rxdone = rt61pci_fill_rxdone, .config_shared_key = rt61pci_config_shared_key, .config_pairwise_key = rt61pci_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 3934dad709c6..e9b1e3d5f47c 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1030,6 +1030,57 @@ dynamic_cca_tune: max_t(u8, qual->vgc_level - 4, low_bound)); } +/* + * Queue handlers. + */ +static void rt73usb_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); + break; + case QID_BEACON: + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + break; + default: + break; + } +} + +static void rt73usb_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); + break; + case QID_BEACON: + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); + rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + break; + default: + break; + } + + rt2x00usb_stop_queue(queue); +} + /* * Firmware functions */ @@ -1324,17 +1375,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) /* * Device state switch handlers. */ -static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - - rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); - rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF)); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); -} - static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) { /* @@ -1402,8 +1442,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + rt73usb_start_queue(rt2x00dev->rx); + break; case STATE_RADIO_RX_OFF: - rt73usb_toggle_rx(rt2x00dev, state); + rt73usb_stop_queue(rt2x00dev->rx); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: @@ -1579,22 +1621,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) return length; } -static void rt73usb_kill_tx_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - if (queue->qid == QID_BEACON) { - rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); - } - - rt2x00usb_kill_tx_queue(queue); -} - /* * RX control handlers */ @@ -2290,7 +2316,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt73usb_kill_tx_queue, + .kill_tx_queue = rt73usb_stop_queue, .fill_rxdone = rt73usb_fill_rxdone, .config_shared_key = rt73usb_config_shared_key, .config_pairwise_key = rt73usb_config_pairwise_key, -- cgit v1.2.3-59-g8ed1b From dbba306f2ae574450a7a5133d6637fe6f5fafc72 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:34:54 +0100 Subject: rt2x00: Reorganize queue callback functions As part of the queue refactoring, change the queue callback function names to have 3 different actions: start, kick & stop. We can now also remove the STATE_RADIO_RX_ON/STATE_RADIO_RX_OFF device_state flags, and replace the usage with using the start_queue/stop_queue callback functions. This streamlines the RX queue handling to the similar approach as all other queues. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 11 +++-------- drivers/net/wireless/rt2x00/rt2500pci.c | 11 +++-------- drivers/net/wireless/rt2x00/rt2500usb.c | 11 +++-------- drivers/net/wireless/rt2x00/rt2800pci.c | 11 +++-------- drivers/net/wireless/rt2x00/rt2800usb.c | 11 +++-------- drivers/net/wireless/rt2x00/rt2x00.h | 9 +++++++-- drivers/net/wireless/rt2x00/rt2x00config.c | 6 ++---- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00reg.h | 2 -- drivers/net/wireless/rt2x00/rt2x00usb.c | 24 +++++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00usb.h | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 11 +++-------- drivers/net/wireless/rt2x00/rt73usb.c | 11 +++-------- 15 files changed, 55 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 35d9a06a76af..2fc6ca5e0968 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1058,12 +1058,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, case STATE_RADIO_OFF: rt2400pci_disable_radio(rt2x00dev); break; - case STATE_RADIO_RX_ON: - rt2400pci_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt2400pci_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -1672,10 +1666,11 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .link_stats = rt2400pci_link_stats, .reset_tuner = rt2400pci_reset_tuner, .link_tuner = rt2400pci_link_tuner, + .start_queue = rt2400pci_start_queue, + .kick_queue = rt2400pci_kick_queue, + .stop_queue = rt2400pci_stop_queue, .write_tx_desc = rt2400pci_write_tx_desc, .write_beacon = rt2400pci_write_beacon, - .kick_tx_queue = rt2400pci_kick_queue, - .kill_tx_queue = rt2400pci_stop_queue, .fill_rxdone = rt2400pci_fill_rxdone, .config_filter = rt2400pci_config_filter, .config_intf = rt2400pci_config_intf, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index bee7ce14028d..d67f91192338 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1213,12 +1213,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, case STATE_RADIO_OFF: rt2500pci_disable_radio(rt2x00dev); break; - case STATE_RADIO_RX_ON: - rt2500pci_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt2500pci_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -1969,10 +1963,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .link_stats = rt2500pci_link_stats, .reset_tuner = rt2500pci_reset_tuner, .link_tuner = rt2500pci_link_tuner, + .start_queue = rt2500pci_start_queue, + .kick_queue = rt2500pci_kick_queue, + .stop_queue = rt2500pci_stop_queue, .write_tx_desc = rt2500pci_write_tx_desc, .write_beacon = rt2500pci_write_beacon, - .kick_tx_queue = rt2500pci_kick_queue, - .kill_tx_queue = rt2500pci_stop_queue, .fill_rxdone = rt2500pci_fill_rxdone, .config_filter = rt2500pci_config_filter, .config_intf = rt2500pci_config_intf, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 52bd0ed0872b..a56b38f9bf29 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1057,12 +1057,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, case STATE_RADIO_OFF: rt2500usb_disable_radio(rt2x00dev); break; - case STATE_RADIO_RX_ON: - rt2500usb_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt2500usb_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -1845,11 +1839,12 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .link_stats = rt2500usb_link_stats, .reset_tuner = rt2500usb_reset_tuner, .watchdog = rt2x00usb_watchdog, + .start_queue = rt2500usb_start_queue, + .kick_queue = rt2x00usb_kick_queue, + .stop_queue = rt2500usb_stop_queue, .write_tx_desc = rt2500usb_write_tx_desc, .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, - .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2500usb_stop_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_shared_key = rt2500usb_config_key, .config_pairwise_key = rt2500usb_config_key, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index a7105974a2a1..15eef7212bb1 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -537,12 +537,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_disable_radio(rt2x00dev); rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; - case STATE_RADIO_RX_ON: - rt2800pci_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt2800pci_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -1004,11 +998,12 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, + .start_queue = rt2800pci_start_queue, + .kick_queue = rt2800pci_kick_queue, + .stop_queue = rt2800pci_stop_queue, .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, - .kick_tx_queue = rt2800pci_kick_queue, - .kill_tx_queue = rt2800pci_stop_queue, .fill_rxdone = rt2800pci_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ee51936d8d1b..60b550313688 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -254,12 +254,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_disable_radio(rt2x00dev); rt2800usb_set_state(rt2x00dev, STATE_SLEEP); break; - case STATE_RADIO_RX_ON: - rt2800usb_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt2800usb_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -626,12 +620,13 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, .watchdog = rt2800usb_watchdog, + .start_queue = rt2800usb_start_queue, + .kick_queue = rt2x00usb_kick_queue, + .stop_queue = rt2800usb_stop_queue, .write_tx_desc = rt2800usb_write_tx_desc, .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, - .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2800usb_stop_queue, .fill_rxdone = rt2800usb_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index e72117f3fdf5..b72f59ba4e1e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -567,7 +567,14 @@ struct rt2x00lib_ops { struct link_qual *qual); void (*link_tuner) (struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); + + /* + * Data queue handlers. + */ void (*watchdog) (struct rt2x00_dev *rt2x00dev); + void (*start_queue) (struct data_queue *queue); + void (*kick_queue) (struct data_queue *queue); + void (*stop_queue) (struct data_queue *queue); /* * TX control handlers @@ -579,8 +586,6 @@ struct rt2x00lib_ops { void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); int (*get_tx_data_len) (struct queue_entry *entry); - void (*kick_tx_queue) (struct data_queue *queue); - void (*kill_tx_queue) (struct data_queue *queue); /* * RX control handlers diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a238e908c854..d2f1f0ad2bc8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -146,8 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_RX_OFF); + rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); /* * Write new antenna setup to device and reset the link tuner. @@ -161,8 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_RX_ON); + rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index bd3afc92f434..2c5f246408e8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -68,7 +68,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Enable RX. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); rt2x00link_start_tuner(rt2x00dev); /* @@ -104,7 +104,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) * Disable RX. */ rt2x00link_stop_tuner(rt2x00dev); - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); /* * Disable radio. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 7ad4b276156e..6713f1ab1284 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) * if for any reason the link tuner must be reset, this will be * handled by rt2x00lib_config(). */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); /* * When we've just turned on the radio, we want to reprogram @@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); return 0; } @@ -727,7 +727,7 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) * any pending frames to be transmitted. */ tx_queue_for_each(rt2x00dev, queue) { - rt2x00dev->ops->lib->kick_tx_queue(queue); + rt2x00dev->ops->lib->kick_queue(queue); } /** diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 35133d8558b5..2af6cea0d2da 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -471,7 +471,7 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue, */ if (rt2x00queue_threshold(queue) || !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - queue->rt2x00dev->ops->lib->kick_tx_queue(queue); + queue->rt2x00dev->ops->lib->kick_queue(queue); } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, @@ -585,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, rt2x00queue_free_skb(intf->beacon); if (!enable_beacon) { - rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); + rt2x00dev->ops->lib->stop_queue(intf->beacon->queue); mutex_unlock(&intf->beacon_skb_mutex); return 0; } @@ -761,7 +761,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; txall_queue_for_each(rt2x00dev, queue) - rt2x00dev->ops->lib->kill_tx_queue(queue); + rt2x00dev->ops->lib->stop_queue(queue); } void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index ed71be95136d..e8259ae48ced 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -83,8 +83,6 @@ enum dev_state { */ STATE_RADIO_ON, STATE_RADIO_OFF, - STATE_RADIO_RX_ON, - STATE_RADIO_RX_OFF, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, STATE_RADIO_IRQ_ON_ISR, diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 12958a45e450..d4361dc0773e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -261,12 +261,22 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) } } -void rt2x00usb_kick_tx_queue(struct data_queue *queue) +void rt2x00usb_kick_queue(struct data_queue *queue) { - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, - rt2x00usb_kick_tx_entry); + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VI: + case QID_AC_VO: + if (!rt2x00queue_empty(queue)) + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kick_tx_entry); + break; + default: + break; + } } -EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); +EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); static void rt2x00usb_kill_entry(struct queue_entry *entry) { @@ -422,11 +432,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, REGISTER_TIMEOUT); - /* - * The USB version of also works - * on the RX queue. - */ - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); + rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); } EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 656a35f421a3..05a5424d9b76 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -378,13 +378,13 @@ struct queue_entry_priv_usb_bcn { }; /** - * rt2x00usb_kick_tx_queue - Kick data queue + * rt2x00usb_kick_queue - Kick data queue * @queue: Data queue to kick * * This will walk through all entries of the queue and push all pending * frames to the hardware as a single burst. */ -void rt2x00usb_kick_tx_queue(struct data_queue *queue); +void rt2x00usb_kick_queue(struct data_queue *queue); /** * rt2x00usb_stop_queue - Stop data queue diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 044f500ff1ab..7156b7881233 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1832,12 +1832,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, case STATE_RADIO_OFF: rt61pci_disable_radio(rt2x00dev); break; - case STATE_RADIO_RX_ON: - rt61pci_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt61pci_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -2900,10 +2894,11 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .link_stats = rt61pci_link_stats, .reset_tuner = rt61pci_reset_tuner, .link_tuner = rt61pci_link_tuner, + .start_queue = rt61pci_start_queue, + .kick_queue = rt61pci_kick_queue, + .stop_queue = rt61pci_stop_queue, .write_tx_desc = rt61pci_write_tx_desc, .write_beacon = rt61pci_write_beacon, - .kick_tx_queue = rt61pci_kick_queue, - .kill_tx_queue = rt61pci_stop_queue, .fill_rxdone = rt61pci_fill_rxdone, .config_shared_key = rt61pci_config_shared_key, .config_pairwise_key = rt61pci_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index e9b1e3d5f47c..f55e74ef02e0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1441,12 +1441,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, case STATE_RADIO_OFF: rt73usb_disable_radio(rt2x00dev); break; - case STATE_RADIO_RX_ON: - rt73usb_start_queue(rt2x00dev->rx); - break; - case STATE_RADIO_RX_OFF: - rt73usb_stop_queue(rt2x00dev->rx); - break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: @@ -2312,11 +2306,12 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .reset_tuner = rt73usb_reset_tuner, .link_tuner = rt73usb_link_tuner, .watchdog = rt2x00usb_watchdog, + .start_queue = rt73usb_start_queue, + .kick_queue = rt2x00usb_kick_queue, + .stop_queue = rt73usb_stop_queue, .write_tx_desc = rt73usb_write_tx_desc, .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, - .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt73usb_stop_queue, .fill_rxdone = rt73usb_fill_rxdone, .config_shared_key = rt73usb_config_shared_key, .config_pairwise_key = rt73usb_config_pairwise_key, -- cgit v1.2.3-59-g8ed1b From 0b7fde54f94979edc67bbf86b5adba702ebfefe8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:35:17 +0100 Subject: rt2x00: Protect queue control with mutex Add wrapper functions in rt2x00queue.c to start & stop queues. This control must be protected using a mutex. Queues can also be paused which will halt the flow of packets between the driver and mac80211. This doesn't require a mutex protection. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 52 ++++++++ drivers/net/wireless/rt2x00/rt2x00config.c | 4 +- drivers/net/wireless/rt2x00/rt2x00debug.c | 5 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 22 +--- drivers/net/wireless/rt2x00/rt2x00lib.h | 9 -- drivers/net/wireless/rt2x00/rt2x00mac.c | 8 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 130 ++++++++++++++++++-- drivers/net/wireless/rt2x00/rt2x00queue.h | 23 ++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 190 ++++++++++++++--------------- 9 files changed, 302 insertions(+), 141 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b72f59ba4e1e..ac7c3d80300e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1073,6 +1073,58 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index); +/** + * rt2x00queue_pause_queue - Pause a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will pause the data queue locally, preventing + * new frames to be added to the queue (while the hardware is + * still allowed to run). + */ +void rt2x00queue_pause_queue(struct data_queue *queue); + +/** + * rt2x00queue_unpause_queue - unpause a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will unpause the data queue locally, allowing + * new frames to be added to the queue again. + */ +void rt2x00queue_unpause_queue(struct data_queue *queue); + +/** + * rt2x00queue_start_queue - Start a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will start handling all pending frames in the queue. + */ +void rt2x00queue_start_queue(struct data_queue *queue); + +/** + * rt2x00queue_stop_queue - Halt a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will stop all pending frames in the queue. + */ +void rt2x00queue_stop_queue(struct data_queue *queue); + +/** + * rt2x00queue_start_queues - Start all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * This function will loop through all available queues to start them + */ +void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00queue_stop_queues - Halt all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * This function will loop through all available queues to stop + * any pending frames. + */ +void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); + /* * Debugfs handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index d2f1f0ad2bc8..70ca9379833b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -146,7 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); + rt2x00queue_stop_queue(rt2x00dev->rx); /* * Write new antenna setup to device and reset the link tuner. @@ -160,7 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); + rt2x00queue_start_queue(rt2x00dev->rx); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 64dfb1f6823e..c92db3264741 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -339,12 +339,13 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, return -ENOMEM; temp = data + - sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); + sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { spin_lock_irqsave(&queue->index_lock, irqflags); - temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, + temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n", + queue->qid, (unsigned int)queue->flags, queue->count, queue->limit, queue->length, queue->index[Q_INDEX], queue->index[Q_INDEX_DMA_DONE], diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 2c5f246408e8..e42816286ffc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -66,9 +66,9 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags); /* - * Enable RX. + * Enable queues. */ - rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); + rt2x00queue_start_queues(rt2x00dev); rt2x00link_start_tuner(rt2x00dev); /* @@ -76,11 +76,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) */ rt2x00link_start_watchdog(rt2x00dev); - /* - * Start the TX queues. - */ - ieee80211_wake_queues(rt2x00dev->hw); - return 0; } @@ -89,22 +84,16 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) if (!test_and_clear_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return; - /* - * Stop the TX queues in mac80211. - */ - ieee80211_stop_queues(rt2x00dev->hw); - rt2x00queue_stop_queues(rt2x00dev); - /* * Stop watchdog monitoring. */ rt2x00link_stop_watchdog(rt2x00dev); /* - * Disable RX. + * Stop all queues */ rt2x00link_stop_tuner(rt2x00dev); - rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); + rt2x00queue_stop_queues(rt2x00dev); /* * Disable radio. @@ -249,7 +238,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); unsigned int header_length, i; u8 rate_idx, rate_flags, retry_rates; u8 skbdesc_flags = skbdesc->flags; @@ -403,7 +391,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * is reenabled when the txdone handler has finished. */ if (!rt2x00queue_threshold(entry->queue)) - ieee80211_wake_queue(rt2x00dev->hw, qid); + rt2x00queue_unpause_queue(entry->queue); } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 2cf68f82674b..a105c500627b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -177,15 +177,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, */ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); -/** - * rt2x00queue_stop_queues - Halt all data queues - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * - * This function will loop through all available queues to stop - * any pending outgoing frames. - */ -void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); - /** * rt2x00queue_init_queues - Initialize all data queues * @rt2x00dev: Pointer to &struct rt2x00_dev. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 6713f1ab1284..c4abb204aeda 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -104,7 +104,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct rt2x00_dev *rt2x00dev = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); enum data_queue_qid qid = skb_get_queue_mapping(skb); - struct data_queue *queue; + struct data_queue *queue = NULL; /* * Mac80211 might be calling this function while we are trying @@ -153,7 +153,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto exit_fail; if (rt2x00queue_threshold(queue)) - ieee80211_stop_queue(rt2x00dev->hw, qid); + rt2x00queue_pause_queue(queue); return NETDEV_TX_OK; @@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) * if for any reason the link tuner must be reset, this will be * handled by rt2x00lib_config(). */ - rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); + rt2x00queue_stop_queue(rt2x00dev->rx); /* * When we've just turned on the radio, we want to reprogram @@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ - rt2x00dev->ops->lib->start_queue(rt2x00dev->rx); + rt2x00queue_start_queue(rt2x00dev->rx); return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 2af6cea0d2da..558965fb41b3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -585,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, rt2x00queue_free_skb(intf->beacon); if (!enable_beacon) { - rt2x00dev->ops->lib->stop_queue(intf->beacon->queue); + rt2x00queue_stop_queue(intf->beacon->queue); mutex_unlock(&intf->beacon_skb_mutex); return 0; } @@ -738,6 +738,125 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) spin_unlock_irqrestore(&queue->index_lock, irqflags); } +void rt2x00queue_pause_queue(struct data_queue *queue) +{ + if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || + !test_bit(QUEUE_STARTED, &queue->flags) || + test_and_set_bit(QUEUE_PAUSED, &queue->flags)) + return; + + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VI: + case QID_AC_VO: + /* + * For TX queues, we have to disable the queue + * inside mac80211. + */ + ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); + break; + default: + break; + } +} +EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); + +void rt2x00queue_unpause_queue(struct data_queue *queue) +{ + if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || + !test_bit(QUEUE_STARTED, &queue->flags) || + !test_and_clear_bit(QUEUE_PAUSED, &queue->flags)) + return; + + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VI: + case QID_AC_VO: + /* + * For TX queues, we have to enable the queue + * inside mac80211. + */ + ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); + break; + default: + break; + } +} +EXPORT_SYMBOL_GPL(rt2x00queue_unpause_queue); + +void rt2x00queue_start_queue(struct data_queue *queue) +{ + mutex_lock(&queue->status_lock); + + if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || + test_and_set_bit(QUEUE_STARTED, &queue->flags)) { + mutex_unlock(&queue->status_lock); + return; + } + + set_bit(QUEUE_PAUSED, &queue->flags); + + queue->rt2x00dev->ops->lib->start_queue(queue); + + rt2x00queue_unpause_queue(queue); + + mutex_unlock(&queue->status_lock); +} +EXPORT_SYMBOL_GPL(rt2x00queue_start_queue); + +void rt2x00queue_stop_queue(struct data_queue *queue) +{ + mutex_lock(&queue->status_lock); + + if (!test_and_clear_bit(QUEUE_STARTED, &queue->flags)) { + mutex_unlock(&queue->status_lock); + return; + } + + rt2x00queue_pause_queue(queue); + + queue->rt2x00dev->ops->lib->stop_queue(queue); + + mutex_unlock(&queue->status_lock); +} +EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); + +void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + /* + * rt2x00queue_start_queue will call ieee80211_wake_queue + * for each queue after is has been properly initialized. + */ + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_start_queue(queue); + + rt2x00queue_start_queue(rt2x00dev->rx); +} +EXPORT_SYMBOL_GPL(rt2x00queue_start_queues); + +void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + /* + * rt2x00queue_stop_queue will call ieee80211_stop_queue + * as well, but we are completely shutting doing everything + * now, so it is much safer to stop all TX queues at once, + * and use rt2x00queue_stop_queue for cleaning up. + */ + ieee80211_stop_queues(rt2x00dev->hw); + + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_stop_queue(queue); + + rt2x00queue_stop_queue(rt2x00dev->rx); +} +EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues); + static void rt2x00queue_reset(struct data_queue *queue) { unsigned long irqflags; @@ -756,14 +875,6 @@ static void rt2x00queue_reset(struct data_queue *queue) spin_unlock_irqrestore(&queue->index_lock, irqflags); } -void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - - txall_queue_for_each(rt2x00dev, queue) - rt2x00dev->ops->lib->stop_queue(queue); -} - void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; @@ -905,6 +1016,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { + mutex_init(&queue->status_lock); spin_lock_init(&queue->index_lock); queue->rt2x00dev = rt2x00dev; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 29b051ac6401..baa39b75430c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -391,6 +391,23 @@ enum queue_index { Q_INDEX_MAX, }; +/** + * enum data_queue_flags: Status flags for data queues + * + * @QUEUE_STARTED: The queue has been started. Fox RX queues this means the + * device might be DMA'ing skbuffers. TX queues will accept skbuffers to + * be transmitted and beacon queues will start beaconing the configured + * beacons. + * @QUEUE_PAUSED: The queue has been started but is currently paused. + * When this bit is set, the queue has been stopped in mac80211, + * preventing new frames to be enqueued. However, a few frames + * might still appear shortly after the pausing... + */ +enum data_queue_flags { + QUEUE_STARTED, + QUEUE_PAUSED, +}; + /** * struct data_queue: Data queue * @@ -398,6 +415,9 @@ enum queue_index { * @entries: Base address of the &struct queue_entry which are * part of this queue. * @qid: The queue identification, see &enum data_queue_qid. + * @flags: Entry flags, see &enum queue_entry_flags. + * @status_lock: The mutex for protecting the start/stop/flush + * handling on this queue. * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or * @index_crypt needs to be changed this lock should be grabbed to prevent * index corruption due to concurrency. @@ -421,8 +441,11 @@ struct data_queue { struct queue_entry *entries; enum data_queue_qid qid; + unsigned long flags; + struct mutex status_lock; spinlock_t index_lock; + unsigned int count; unsigned short limit; unsigned short threshold; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index d4361dc0773e..fca29ae57e71 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -261,6 +261,89 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) } } +/* + * RX data handlers. + */ +static void rt2x00usb_work_rxdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, rxdone_work); + struct queue_entry *entry; + struct skb_frame_desc *skbdesc; + u8 rxd[32]; + + while (!rt2x00queue_empty(rt2x00dev->rx)) { + entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; + + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = rxd; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(entry); + } +} + +static void rt2x00usb_interrupt_rxdone(struct urb *urb) +{ + struct queue_entry *entry = (struct queue_entry *)urb->context; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; + + /* + * Report the frame as DMA done + */ + rt2x00lib_dmadone(entry); + + /* + * Check if the received data is simply too small + * to be actually valid, or if the urb is signaling + * a problem. + */ + if (urb->actual_length < entry->queue->desc_size || urb->status) + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + + /* + * Schedule the delayed work for reading the RX status + * from the device. + */ + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); +} + +static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); + struct queue_entry_priv_usb *entry_priv = entry->priv_data; + int status; + + if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; + + usb_fill_bulk_urb(entry_priv->urb, usb_dev, + usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint), + entry->skb->data, entry->skb->len, + rt2x00usb_interrupt_rxdone, entry); + + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + } +} + void rt2x00usb_kick_queue(struct data_queue *queue) { switch (queue->qid) { @@ -272,6 +355,11 @@ void rt2x00usb_kick_queue(struct data_queue *queue) rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, rt2x00usb_kick_tx_entry); break; + case QID_RX: + if (!rt2x00queue_full(queue)) + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kick_rx_entry); + break; default: break; } @@ -307,7 +395,6 @@ EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - unsigned short threshold = queue->threshold; WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," " invoke forced forced reset\n", queue->qid); @@ -315,18 +402,8 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) /* * Temporarily disable the TX queue, this will force mac80211 * to use the other queues until this queue has been restored. - * - * Set the queue threshold to the queue limit. This prevents the - * queue from being enabled during the txdone handler. */ - queue->threshold = queue->limit; - ieee80211_stop_queue(rt2x00dev->hw, queue->qid); - - /* - * Kill all entries in the queue, afterwards we need to - * wait a bit for all URBs to be cancelled. - */ - rt2x00usb_stop_queue(queue); + rt2x00queue_stop_queue(queue); /* * In case that a driver has overriden the txdone_work @@ -338,8 +415,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) * The queue has been reset, and mac80211 is allowed to use the * queue again. */ - queue->threshold = threshold; - ieee80211_wake_queue(rt2x00dev->hw, queue->qid); + rt2x00queue_start_queue(queue); } static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) @@ -365,65 +441,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); -/* - * RX data handlers. - */ -static void rt2x00usb_work_rxdone(struct work_struct *work) -{ - struct rt2x00_dev *rt2x00dev = - container_of(work, struct rt2x00_dev, rxdone_work); - struct queue_entry *entry; - struct skb_frame_desc *skbdesc; - u8 rxd[32]; - - while (!rt2x00queue_empty(rt2x00dev->rx)) { - entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); - - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) - break; - - /* - * Fill in desc fields of the skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - skbdesc->desc = rxd; - skbdesc->desc_len = entry->queue->desc_size; - - /* - * Send the frame to rt2x00lib for further processing. - */ - rt2x00lib_rxdone(entry); - } -} - -static void rt2x00usb_interrupt_rxdone(struct urb *urb) -{ - struct queue_entry *entry = (struct queue_entry *)urb->context; - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - - if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) - return; - - /* - * Report the frame as DMA done - */ - rt2x00lib_dmadone(entry); - - /* - * Check if the received data is simply too small - * to be actually valid, or if the urb is signaling - * a problem. - */ - if (urb->actual_length < entry->queue->desc_size || urb->status) - set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); - - /* - * Schedule the delayed work for reading the RX status - * from the device. - */ - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); -} - /* * Radio handlers */ @@ -431,8 +448,6 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) { rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, REGISTER_TIMEOUT); - - rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx); } EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); @@ -441,31 +456,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); */ void rt2x00usb_clear_entry(struct queue_entry *entry) { - struct usb_device *usb_dev = - to_usb_device_intf(entry->queue->rt2x00dev->dev); - struct queue_entry_priv_usb *entry_priv = entry->priv_data; - int pipe; - int status; - entry->flags = 0; - if (entry->queue->qid == QID_RX) { - pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); - usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, - entry->skb->data, entry->skb->len, - rt2x00usb_interrupt_rxdone, entry); - - set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - - status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); - if (status) { - if (status == -ENODEV) - clear_bit(DEVICE_STATE_PRESENT, - &entry->queue->rt2x00dev->flags); - set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); - rt2x00lib_dmadone(entry); - } - } + if (entry->queue->qid == QID_RX) + rt2x00usb_kick_rx_entry(entry); } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); -- cgit v1.2.3-59-g8ed1b From 5be65609fec2e331c7d804471be3d59089a30d98 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:35:40 +0100 Subject: rt2x00: Add "flush" queue command Add a new command to the queue handlers: "flush", this moves the flush() callback from mac80211 into rt2x00queue and adds support for flushing the RX queue as well. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 3 +- drivers/net/wireless/rt2x00/rt2800usb.c | 3 +- drivers/net/wireless/rt2x00/rt2x00.h | 21 ++++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 1 + drivers/net/wireless/rt2x00/rt2x00mac.c | 32 +----------- drivers/net/wireless/rt2x00/rt2x00queue.c | 85 +++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 70 ++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00usb.h | 4 +- drivers/net/wireless/rt2x00/rt73usb.c | 3 +- 9 files changed, 161 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index a56b38f9bf29..6b3b1de46792 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -785,8 +785,6 @@ static void rt2500usb_stop_queue(struct data_queue *queue) default: break; } - - rt2x00usb_stop_queue(queue); } /* @@ -1842,6 +1840,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .start_queue = rt2500usb_start_queue, .kick_queue = rt2x00usb_kick_queue, .stop_queue = rt2500usb_stop_queue, + .flush_queue = rt2x00usb_flush_queue, .write_tx_desc = rt2500usb_write_tx_desc, .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 60b550313688..3e0205ddf7b4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -96,8 +96,6 @@ static void rt2800usb_stop_queue(struct data_queue *queue) default: break; } - - rt2x00usb_stop_queue(queue); } /* @@ -623,6 +621,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .start_queue = rt2800usb_start_queue, .kick_queue = rt2x00usb_kick_queue, .stop_queue = rt2800usb_stop_queue, + .flush_queue = rt2x00usb_flush_queue, .write_tx_desc = rt2800usb_write_tx_desc, .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index ac7c3d80300e..1d7b481ec357 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -575,6 +575,7 @@ struct rt2x00lib_ops { void (*start_queue) (struct data_queue *queue); void (*kick_queue) (struct data_queue *queue); void (*stop_queue) (struct data_queue *queue); + void (*flush_queue) (struct data_queue *queue); /* * TX control handlers @@ -1108,6 +1109,16 @@ void rt2x00queue_start_queue(struct data_queue *queue); */ void rt2x00queue_stop_queue(struct data_queue *queue); +/** + * rt2x00queue_flush_queue - Flush a data queue + * @queue: Pointer to &struct data_queue. + * @drop: True to drop all pending frames. + * + * This function will flush the queue. After this call + * the queue is guarenteed to be empty. + */ +void rt2x00queue_flush_queue(struct data_queue *queue, bool drop); + /** * rt2x00queue_start_queues - Start all data queues * @rt2x00dev: Pointer to &struct rt2x00_dev. @@ -1125,6 +1136,16 @@ void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev); */ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); +/** + * rt2x00queue_flush_queues - Flush all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @drop: True to drop all pending frames. + * + * This function will loop through all available queues to flush + * any pending frames. + */ +void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop); + /* * Debugfs handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e42816286ffc..9ef5a2468216 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -94,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) */ rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); + rt2x00queue_flush_queues(rt2x00dev, true); /* * Disable radio. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c4abb204aeda..4cac7ad60f47 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -718,36 +718,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) { struct rt2x00_dev *rt2x00dev = hw->priv; struct data_queue *queue; - unsigned int i = 0; - ieee80211_stop_queues(hw); - - /* - * Run over all queues to kick them, this will force - * any pending frames to be transmitted. - */ - tx_queue_for_each(rt2x00dev, queue) { - rt2x00dev->ops->lib->kick_queue(queue); - } - - /** - * All queues have been kicked, now wait for each queue - * to become empty. With a bit of luck, we only have to wait - * for the first queue to become empty, because while waiting - * for the that queue, the other queues will have transmitted - * all their frames as well (since they were already kicked). - */ - tx_queue_for_each(rt2x00dev, queue) { - for (i = 0; i < 10; i++) { - if (rt2x00queue_empty(queue)) - break; - msleep(100); - } - - if (!rt2x00queue_empty(queue)) - WARNING(rt2x00dev, "Failed to flush queue %d\n", queue->qid); - } - - ieee80211_wake_queues(hw); + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_flush_queue(queue, drop); } EXPORT_SYMBOL_GPL(rt2x00mac_flush); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 558965fb41b3..313a8faa5fa4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -780,6 +780,12 @@ void rt2x00queue_unpause_queue(struct data_queue *queue) */ ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); break; + case QID_RX: + /* + * For RX we need to kick the queue now in order to + * receive frames. + */ + queue->rt2x00dev->ops->lib->kick_queue(queue); default: break; } @@ -823,6 +829,74 @@ void rt2x00queue_stop_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); +void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) +{ + unsigned int i; + bool started; + bool tx_queue = + (queue->qid == QID_AC_BE) || + (queue->qid == QID_AC_BK) || + (queue->qid == QID_AC_VI) || + (queue->qid == QID_AC_VO); + + mutex_lock(&queue->status_lock); + + /* + * If the queue has been started, we must stop it temporarily + * to prevent any new frames to be queued on the device. If + * we are not dropping the pending frames, the queue must + * only be stopped in the software and not the hardware, + * otherwise the queue will never become empty on its own. + */ + started = test_bit(QUEUE_STARTED, &queue->flags); + if (started) { + /* + * Pause the queue + */ + rt2x00queue_pause_queue(queue); + + /* + * If we are not supposed to drop any pending + * frames, this means we must force a start (=kick) + * to the queue to make sure the hardware will + * start transmitting. + */ + if (!drop && tx_queue) + queue->rt2x00dev->ops->lib->kick_queue(queue); + } + + /* + * Check if driver supports flushing, we can only guarentee + * full support for flushing if the driver is able + * to cancel all pending frames (drop = true). + */ + if (drop && queue->rt2x00dev->ops->lib->flush_queue) + queue->rt2x00dev->ops->lib->flush_queue(queue); + + /* + * When we don't want to drop any frames, or when + * the driver doesn't fully flush the queue correcly, + * we must wait for the queue to become empty. + */ + for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++) + msleep(10); + + /* + * The queue flush has failed... + */ + if (unlikely(!rt2x00queue_empty(queue))) + WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid); + + /* + * Restore the queue to the previous status + */ + if (started) + rt2x00queue_unpause_queue(queue); + + mutex_unlock(&queue->status_lock); +} +EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); + void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; @@ -857,6 +931,17 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues); +void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop) +{ + struct data_queue *queue; + + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_flush_queue(queue, drop); + + rt2x00queue_flush_queue(rt2x00dev->rx, drop); +} +EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues); + static void rt2x00queue_reset(struct data_queue *queue) { unsigned long irqflags; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fca29ae57e71..cd80eec5ff51 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -366,7 +366,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); -static void rt2x00usb_kill_entry(struct queue_entry *entry) +static void rt2x00usb_flush_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv = entry->priv_data; @@ -385,37 +385,61 @@ static void rt2x00usb_kill_entry(struct queue_entry *entry) usb_kill_urb(bcn_priv->guardian_urb); } -void rt2x00usb_stop_queue(struct data_queue *queue) +void rt2x00usb_flush_queue(struct data_queue *queue) { + struct work_struct *completion; + unsigned int i; + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, - rt2x00usb_kill_entry); + rt2x00usb_flush_entry); + + /* + * Obtain the queue completion handler + */ + switch (queue->qid) { + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VI: + case QID_AC_VO: + completion = &queue->rt2x00dev->txdone_work; + break; + case QID_RX: + completion = &queue->rt2x00dev->rxdone_work; + break; + default: + return; + } + + for (i = 0; i < 20; i++) { + /* + * Check if the driver is already done, otherwise we + * have to sleep a little while to give the driver/hw + * the oppurtunity to complete interrupt process itself. + */ + if (rt2x00queue_empty(queue)) + break; + + /* + * Schedule the completion handler manually, when this + * worker function runs, it should cleanup the queue. + */ + ieee80211_queue_work(queue->rt2x00dev->hw, completion); + + /* + * Wait for a little while to give the driver + * the oppurtunity to recover itself. + */ + msleep(10); + } } -EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); +EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," " invoke forced forced reset\n", queue->qid); - /* - * Temporarily disable the TX queue, this will force mac80211 - * to use the other queues until this queue has been restored. - */ - rt2x00queue_stop_queue(queue); - - /* - * In case that a driver has overriden the txdone_work - * function, we invoke the TX done through there. - */ - rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); - - /* - * The queue has been reset, and mac80211 is allowed to use the - * queue again. - */ - rt2x00queue_start_queue(queue); + rt2x00queue_flush_queue(queue, true); } static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 05a5424d9b76..6aaf51fc7ad8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -387,13 +387,13 @@ struct queue_entry_priv_usb_bcn { void rt2x00usb_kick_queue(struct data_queue *queue); /** - * rt2x00usb_stop_queue - Stop data queue + * rt2x00usb_flush_queue - Flush data queue * @queue: Data queue to stop * * This will walk through all entries of the queue and kill all * URB's which were send to the device. */ -void rt2x00usb_stop_queue(struct data_queue *queue); +void rt2x00usb_flush_queue(struct data_queue *queue); /** * rt2x00usb_watchdog - Watchdog for USB communication diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f55e74ef02e0..0b3959bdd3eb 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1077,8 +1077,6 @@ static void rt73usb_stop_queue(struct data_queue *queue) default: break; } - - rt2x00usb_stop_queue(queue); } /* @@ -2309,6 +2307,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .start_queue = rt73usb_start_queue, .kick_queue = rt2x00usb_kick_queue, .stop_queue = rt73usb_stop_queue, + .flush_queue = rt2x00usb_flush_queue, .write_tx_desc = rt73usb_write_tx_desc, .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, -- cgit v1.2.3-59-g8ed1b From 64e7d72384c2ecef5a892b2243623af265dd83cc Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:36:00 +0100 Subject: rt2x00: Cleanup RX index counting Add the rt2x00_dmastart function to rt2x00lib which marks the queue_entry as "owned by device", and increased the Q_INDEX number. This cleanups up the index handling by rt2x00lib which at until so far used hackish approaches to keep the RX queue index numbering sane. The rt2x00pci.c changes are from Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00dev.c | 11 ++++++++--- drivers/net/wireless/rt2x00/rt2x00pci.c | 7 +++++++ drivers/net/wireless/rt2x00/rt2x00queue.c | 5 +---- drivers/net/wireless/rt2x00/rt2x00usb.c | 2 ++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 1d7b481ec357..28ea59ab2b06 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1171,6 +1171,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, */ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_dmastart(struct queue_entry *entry); void rt2x00lib_dmadone(struct queue_entry *entry); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9ef5a2468216..3d4c61fcf06f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -226,6 +226,13 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); +void rt2x00lib_dmastart(struct queue_entry *entry) +{ + set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + rt2x00queue_index_inc(entry->queue, Q_INDEX); +} +EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); + void rt2x00lib_dmadone(struct queue_entry *entry) { clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); @@ -555,10 +562,8 @@ submit_entry: entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && - test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); - } } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 868ca19b13ea..28e6ff1a6694 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -81,6 +81,13 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) skbdesc->desc = entry_priv->desc; skbdesc->desc_len = entry->queue->desc_size; + /* + * DMA is already done, notify rt2x00lib that + * it finished successfully. + */ + rt2x00lib_dmastart(entry); + rt2x00lib_dmadone(entry); + /* * Send the frame to rt2x00lib for further processing. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 313a8faa5fa4..52cc92d426f3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -968,11 +968,8 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) queue_for_each(rt2x00dev, queue) { rt2x00queue_reset(queue); - for (i = 0; i < queue->limit; i++) { + for (i = 0; i < queue->limit; i++) rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); - if (queue->qid == QID_RX) - rt2x00queue_index_inc(queue, Q_INDEX); - } } } diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index cd80eec5ff51..cd29ebc8a37b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -330,6 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + rt2x00lib_dmastart(entry); + usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint), entry->skb->data, entry->skb->len, -- cgit v1.2.3-59-g8ed1b From dba5dc1ae9764902f46d5225c9ff40e4f7b614c7 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:36:18 +0100 Subject: rt2x00: Introduce extra queue entry sanity flag Add a queue entry flag ENTRY_DATA_STATUS_PENDING, which can be used to indicate a queue entry has returned from the hardware and is waiting for status processing. Using this flag we can add some extra sanity checks to prevent queue corruption. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 1 + drivers/net/wireless/rt2x00/rt2x00queue.h | 6 +++++- drivers/net/wireless/rt2x00/rt2x00usb.c | 12 ++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 3d4c61fcf06f..fa74acdd271f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -235,6 +235,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); void rt2x00lib_dmadone(struct queue_entry *entry) { + set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags); clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index baa39b75430c..47659346070b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -340,12 +340,16 @@ struct txentry_desc { * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured * while transfering the data to the hardware. No TX status report will * be expected from the hardware. + * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and + * returned. It is now waiting for the status reporting before the + * entry can be reused again. */ enum queue_entry_flags { ENTRY_BCN_ASSIGNED, ENTRY_OWNER_DEVICE_DATA, ENTRY_DATA_PENDING, - ENTRY_DATA_IO_FAILED + ENTRY_DATA_IO_FAILED, + ENTRY_DATA_STATUS_PENDING, }; /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index cd29ebc8a37b..8a16b5106a33 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work) while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) break; rt2x00usb_work_txdone_entry(entry); @@ -237,7 +238,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) u32 length; int status; - if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) + if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || + test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return; /* @@ -275,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work) while (!rt2x00queue_empty(rt2x00dev->rx)) { entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) break; /* @@ -327,7 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) struct queue_entry_priv_usb *entry_priv = entry->priv_data; int status; - if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return; rt2x00lib_dmastart(entry); -- cgit v1.2.3-59-g8ed1b From f615e9a38a8e6239d35891a05f2ac1159088780a Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 13 Dec 2010 12:36:38 +0100 Subject: rt2x00: Fix WMM Queue naming The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected. This renames the queues using this mapping: QID_AC_BK -> QID_AC_VO (priority 0) QID_AC_BE -> QID_AC_VI (priority 1) QID_AC_VI -> QID_AC_BE (priority 2) QID_AC_VO -> QID_AC_BK (priority 3) Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 12 +++--- drivers/net/wireless/rt2x00/rt2500pci.c | 12 +++--- drivers/net/wireless/rt2x00/rt2800.h | 44 +++++++++++----------- drivers/net/wireless/rt2x00/rt2800pci.c | 4 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 18 ++++----- drivers/net/wireless/rt2x00/rt2x00queue.h | 12 +++--- drivers/net/wireless/rt2x00/rt2x00usb.c | 8 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 16 ++++---- drivers/net/wireless/rt2x00/rt61pci.h | 62 +++++++++++++++---------------- drivers/net/wireless/rt2x00/rt73usb.h | 36 +++++++++--------- 10 files changed, 112 insertions(+), 112 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 2fc6ca5e0968..54ca49ad3472 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -664,12 +664,12 @@ static void rt2400pci_kick_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: + case QID_AC_VO: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); break; - case QID_AC_BK: + case QID_AC_VI: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); @@ -690,8 +690,8 @@ static void rt2400pci_stop_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: - case QID_AC_BK: + case QID_AC_VO: + case QID_AC_VI: case QID_ATIM: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); @@ -1322,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance) * 4 - Priority ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) - rt2400pci_txdone(rt2x00dev, QID_AC_BE); + rt2400pci_txdone(rt2x00dev, QID_AC_VO); /* * 5 - Tx ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) - rt2400pci_txdone(rt2x00dev, QID_AC_BK); + rt2400pci_txdone(rt2x00dev, QID_AC_VI); /* Enable interrupts again. */ rt2x00dev->ops->lib->set_device_state(rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d67f91192338..a9ff26a27724 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -754,12 +754,12 @@ static void rt2500pci_kick_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: + case QID_AC_VO: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); break; - case QID_AC_BK: + case QID_AC_VI: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); @@ -780,8 +780,8 @@ static void rt2500pci_stop_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: - case QID_AC_BK: + case QID_AC_VO: + case QID_AC_VI: case QID_ATIM: rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); @@ -1455,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance) * 4 - Priority ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) - rt2500pci_txdone(rt2x00dev, QID_AC_BE); + rt2500pci_txdone(rt2x00dev, QID_AC_VO); /* * 5 - Tx ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) - rt2500pci_txdone(rt2x00dev, QID_AC_BK); + rt2500pci_txdone(rt2x00dev, QID_AC_VI); /* Enable interrupts again. */ rt2x00dev->ops->lib->set_device_state(rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9ea09612c878..4c55e8525cad 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -213,10 +213,10 @@ /* * WMM_AIFSN_CFG: Aifsn for each EDCA AC - * AIFSN0: AC_BE - * AIFSN1: AC_BK - * AIFSN2: AC_VI - * AIFSN3: AC_VO + * AIFSN0: AC_VO + * AIFSN1: AC_VI + * AIFSN2: AC_BE + * AIFSN3: AC_BK */ #define WMM_AIFSN_CFG 0x0214 #define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f) @@ -226,10 +226,10 @@ /* * WMM_CWMIN_CSR: CWmin for each EDCA AC - * CWMIN0: AC_BE - * CWMIN1: AC_BK - * CWMIN2: AC_VI - * CWMIN3: AC_VO + * CWMIN0: AC_VO + * CWMIN1: AC_VI + * CWMIN2: AC_BE + * CWMIN3: AC_BK */ #define WMM_CWMIN_CFG 0x0218 #define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f) @@ -239,10 +239,10 @@ /* * WMM_CWMAX_CSR: CWmax for each EDCA AC - * CWMAX0: AC_BE - * CWMAX1: AC_BK - * CWMAX2: AC_VI - * CWMAX3: AC_VO + * CWMAX0: AC_VO + * CWMAX1: AC_VI + * CWMAX2: AC_BE + * CWMAX3: AC_BK */ #define WMM_CWMAX_CFG 0x021c #define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f) @@ -251,18 +251,18 @@ #define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000) /* - * AC_TXOP0: AC_BK/AC_BE TXOP register - * AC0TXOP: AC_BK in unit of 32us - * AC1TXOP: AC_BE in unit of 32us + * AC_TXOP0: AC_VO/AC_VI TXOP register + * AC0TXOP: AC_VO in unit of 32us + * AC1TXOP: AC_VI in unit of 32us */ #define WMM_TXOP0_CFG 0x0220 #define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff) #define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000) /* - * AC_TXOP1: AC_VO/AC_VI TXOP register - * AC2TXOP: AC_VI in unit of 32us - * AC3TXOP: AC_VO in unit of 32us + * AC_TXOP1: AC_BE/AC_BK TXOP register + * AC2TXOP: AC_BE in unit of 32us + * AC3TXOP: AC_BK in unit of 32us */ #define WMM_TXOP1_CFG 0x0224 #define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff) @@ -288,7 +288,7 @@ #define MCU_CMD_CFG 0x022c /* - * AC_BK register offsets + * AC_VO register offsets */ #define TX_BASE_PTR0 0x0230 #define TX_MAX_CNT0 0x0234 @@ -296,7 +296,7 @@ #define TX_DTX_IDX0 0x023c /* - * AC_BE register offsets + * AC_VI register offsets */ #define TX_BASE_PTR1 0x0240 #define TX_MAX_CNT1 0x0244 @@ -304,7 +304,7 @@ #define TX_DTX_IDX1 0x024c /* - * AC_VI register offsets + * AC_BE register offsets */ #define TX_BASE_PTR2 0x0250 #define TX_MAX_CNT2 0x0254 @@ -312,7 +312,7 @@ #define TX_DTX_IDX2 0x025c /* - * AC_VO register offsets + * AC_BK register offsets */ #define TX_BASE_PTR3 0x0260 #define TX_MAX_CNT3 0x0264 diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 15eef7212bb1..baa1468a56a8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -217,10 +217,10 @@ static void rt2800pci_kick_queue(struct data_queue *queue) struct queue_entry *entry; switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: - case QID_AC_VI: - case QID_AC_VO: entry = rt2x00queue_get_entry(queue, Q_INDEX); rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx); break; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 52cc92d426f3..ca82b3a91697 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -746,10 +746,10 @@ void rt2x00queue_pause_queue(struct data_queue *queue) return; switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: - case QID_AC_VI: - case QID_AC_VO: /* * For TX queues, we have to disable the queue * inside mac80211. @@ -770,10 +770,10 @@ void rt2x00queue_unpause_queue(struct data_queue *queue) return; switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: - case QID_AC_VI: - case QID_AC_VO: /* * For TX queues, we have to enable the queue * inside mac80211. @@ -834,10 +834,10 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) unsigned int i; bool started; bool tx_queue = - (queue->qid == QID_AC_BE) || - (queue->qid == QID_AC_BK) || + (queue->qid == QID_AC_VO) || (queue->qid == QID_AC_VI) || - (queue->qid == QID_AC_VO); + (queue->qid == QID_AC_BE) || + (queue->qid == QID_AC_BK); mutex_lock(&queue->status_lock); @@ -1141,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) /* * Initialize queue parameters. * RX: qid = QID_RX - * TX: qid = QID_AC_BE + index + * TX: qid = QID_AC_VO + index * TX: cw_min: 2^5 = 32. * TX: cw_max: 2^10 = 1024. * BCN: qid = QID_BEACON @@ -1149,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) */ rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); - qid = QID_AC_BE; + qid = QID_AC_VO; tx_queue_for_each(rt2x00dev, queue) rt2x00queue_init(rt2x00dev, queue, qid++); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 47659346070b..fab8e2687f29 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -45,10 +45,10 @@ /** * enum data_queue_qid: Queue identification * + * @QID_AC_VO: AC VO queue + * @QID_AC_VI: AC VI queue * @QID_AC_BE: AC BE queue * @QID_AC_BK: AC BK queue - * @QID_AC_VI: AC VI queue - * @QID_AC_VO: AC VO queue * @QID_HCCA: HCCA queue * @QID_MGMT: MGMT queue (prio queue) * @QID_RX: RX queue @@ -57,10 +57,10 @@ * @QID_ATIM: Atim queue (value unspeficied, don't send it to device) */ enum data_queue_qid { - QID_AC_BE = 0, - QID_AC_BK = 1, - QID_AC_VI = 2, - QID_AC_VO = 3, + QID_AC_VO = 0, + QID_AC_VI = 1, + QID_AC_BE = 2, + QID_AC_BK = 3, QID_HCCA = 4, QID_MGMT = 13, QID_RX = 14, diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 8a16b5106a33..1a9937d5aff6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -353,10 +353,10 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) void rt2x00usb_kick_queue(struct data_queue *queue) { switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: - case QID_AC_VI: - case QID_AC_VO: if (!rt2x00queue_empty(queue)) rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, rt2x00usb_kick_tx_entry); @@ -403,10 +403,10 @@ void rt2x00usb_flush_queue(struct data_queue *queue) * Obtain the queue completion handler */ switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: - case QID_AC_VI: - case QID_AC_VO: completion = &queue->rt2x00dev->txdone_work; break; case QID_RX: diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 7156b7881233..9405b100a75a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1171,22 +1171,22 @@ static void rt61pci_kick_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: + case QID_AC_VO: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_BK: + case QID_AC_VI: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_VI: + case QID_AC_BE: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_VO: + case QID_AC_BK: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); @@ -1202,22 +1202,22 @@ static void rt61pci_stop_queue(struct data_queue *queue) u32 reg; switch (queue->qid) { - case QID_AC_BE: + case QID_AC_VO: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_BK: + case QID_AC_VI: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_VI: + case QID_AC_BE: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; - case QID_AC_VO: + case QID_AC_BK: rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index afc803b7959f..e3cd6db76b0e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -784,25 +784,25 @@ struct hw_pairwise_ta_entry { */ /* - * AC0_BASE_CSR: AC_BK base address. + * AC0_BASE_CSR: AC_VO base address. */ #define AC0_BASE_CSR 0x3400 #define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) /* - * AC1_BASE_CSR: AC_BE base address. + * AC1_BASE_CSR: AC_VI base address. */ #define AC1_BASE_CSR 0x3404 #define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) /* - * AC2_BASE_CSR: AC_VI base address. + * AC2_BASE_CSR: AC_BE base address. */ #define AC2_BASE_CSR 0x3408 #define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) /* - * AC3_BASE_CSR: AC_VO base address. + * AC3_BASE_CSR: AC_BK base address. */ #define AC3_BASE_CSR 0x340c #define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) @@ -814,7 +814,7 @@ struct hw_pairwise_ta_entry { #define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) /* - * TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO. + * TX_RING_CSR0: TX Ring size for AC_VO, AC_VI, AC_BE, AC_BK. */ #define TX_RING_CSR0 0x3418 #define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff) @@ -833,10 +833,10 @@ struct hw_pairwise_ta_entry { /* * AIFSN_CSR: AIFSN for each EDCA AC. - * AIFSN0: For AC_BK. - * AIFSN1: For AC_BE. - * AIFSN2: For AC_VI. - * AIFSN3: For AC_VO. + * AIFSN0: For AC_VO. + * AIFSN1: For AC_VI. + * AIFSN2: For AC_BE. + * AIFSN3: For AC_BK. */ #define AIFSN_CSR 0x3420 #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) @@ -846,10 +846,10 @@ struct hw_pairwise_ta_entry { /* * CWMIN_CSR: CWmin for each EDCA AC. - * CWMIN0: For AC_BK. - * CWMIN1: For AC_BE. - * CWMIN2: For AC_VI. - * CWMIN3: For AC_VO. + * CWMIN0: For AC_VO. + * CWMIN1: For AC_VI. + * CWMIN2: For AC_BE. + * CWMIN3: For AC_BK. */ #define CWMIN_CSR 0x3424 #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) @@ -859,10 +859,10 @@ struct hw_pairwise_ta_entry { /* * CWMAX_CSR: CWmax for each EDCA AC. - * CWMAX0: For AC_BK. - * CWMAX1: For AC_BE. - * CWMAX2: For AC_VI. - * CWMAX3: For AC_VO. + * CWMAX0: For AC_VO. + * CWMAX1: For AC_VI. + * CWMAX2: For AC_BE. + * CWMAX3: For AC_BK. */ #define CWMAX_CSR 0x3428 #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) @@ -883,14 +883,14 @@ struct hw_pairwise_ta_entry { /* * TX_CNTL_CSR: KICK/Abort TX. - * KICK_TX_AC0: For AC_BK. - * KICK_TX_AC1: For AC_BE. - * KICK_TX_AC2: For AC_VI. - * KICK_TX_AC3: For AC_VO. - * ABORT_TX_AC0: For AC_BK. - * ABORT_TX_AC1: For AC_BE. - * ABORT_TX_AC2: For AC_VI. - * ABORT_TX_AC3: For AC_VO. + * KICK_TX_AC0: For AC_VO. + * KICK_TX_AC1: For AC_VI. + * KICK_TX_AC2: For AC_BE. + * KICK_TX_AC3: For AC_BK. + * ABORT_TX_AC0: For AC_VO. + * ABORT_TX_AC1: For AC_VI. + * ABORT_TX_AC2: For AC_BE. + * ABORT_TX_AC3: For AC_BK. */ #define TX_CNTL_CSR 0x3430 #define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001) @@ -1010,18 +1010,18 @@ struct hw_pairwise_ta_entry { #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) /* - * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. - * AC0_TX_OP: For AC_BK, in unit of 32us. - * AC1_TX_OP: For AC_BE, in unit of 32us. + * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register. + * AC0_TX_OP: For AC_VO, in unit of 32us. + * AC1_TX_OP: For AC_VI, in unit of 32us. */ #define AC_TXOP_CSR0 0x3474 #define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) #define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) /* - * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. - * AC2_TX_OP: For AC_VI, in unit of 32us. - * AC3_TX_OP: For AC_VO, in unit of 32us. + * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register. + * AC2_TX_OP: For AC_BE, in unit of 32us. + * AC3_TX_OP: For AC_BK, in unit of 32us. */ #define AC_TXOP_CSR1 0x3478 #define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 1315ce5c992f..9f6b470414d3 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry { /* * AIFSN_CSR: AIFSN for each EDCA AC. - * AIFSN0: For AC_BK. - * AIFSN1: For AC_BE. - * AIFSN2: For AC_VI. - * AIFSN3: For AC_VO. + * AIFSN0: For AC_VO. + * AIFSN1: For AC_VI. + * AIFSN2: For AC_BE. + * AIFSN3: For AC_BK. */ #define AIFSN_CSR 0x0400 #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) @@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry { /* * CWMIN_CSR: CWmin for each EDCA AC. - * CWMIN0: For AC_BK. - * CWMIN1: For AC_BE. - * CWMIN2: For AC_VI. - * CWMIN3: For AC_VO. + * CWMIN0: For AC_VO. + * CWMIN1: For AC_VI. + * CWMIN2: For AC_BE. + * CWMIN3: For AC_BK. */ #define CWMIN_CSR 0x0404 #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) @@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry { /* * CWMAX_CSR: CWmax for each EDCA AC. - * CWMAX0: For AC_BK. - * CWMAX1: For AC_BE. - * CWMAX2: For AC_VI. - * CWMAX3: For AC_VO. + * CWMAX0: For AC_VO. + * CWMAX1: For AC_VI. + * CWMAX2: For AC_BE. + * CWMAX3: For AC_BK. */ #define CWMAX_CSR 0x0408 #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) @@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry { #define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000) /* - * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. - * AC0_TX_OP: For AC_BK, in unit of 32us. - * AC1_TX_OP: For AC_BE, in unit of 32us. + * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register. + * AC0_TX_OP: For AC_VO, in unit of 32us. + * AC1_TX_OP: For AC_VI, in unit of 32us. */ #define AC_TXOP_CSR0 0x040c #define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) #define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) /* - * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. - * AC2_TX_OP: For AC_VI, in unit of 32us. - * AC3_TX_OP: For AC_VO, in unit of 32us. + * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register. + * AC2_TX_OP: For AC_BE, in unit of 32us. + * AC3_TX_OP: For AC_BK, in unit of 32us. */ #define AC_TXOP_CSR1 0x0410 #define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) -- cgit v1.2.3-59-g8ed1b From e85b4c04646f7fa62ebf0afe11cd8dffde689da7 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 13 Dec 2010 12:38:49 +0100 Subject: rt2x00: remove stray semicolon The stray semicolon after DEBUG_PRINTK_MSG causes things like "if (...) WARNING(...); else {}" to fail with syntax error. Signed-off-by: Johannes Stezenbach Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 28ea59ab2b06..c254d5a62c7d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -66,7 +66,7 @@ #ifdef CONFIG_RT2X00_DEBUG #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args); + DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args) #else #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ do { } while (0) -- cgit v1.2.3-59-g8ed1b From 739fd9405416e22732e46a9226a8cac379bd57fc Mon Sep 17 00:00:00 2001 From: Wolfgang Kufner Date: Mon, 13 Dec 2010 12:39:12 +0100 Subject: rt2x00: Pad beacon to multiple of 32 bits. Pad beacon to a multiple of 32 bits in preparation for the change from memcpy_toio() to __iowrite32_copy() in register_multiwrite(). Signed-off-by: Wolfgang Kufner Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 9 ++++++--- drivers/net/wireless/rt2x00/rt61pci.c | 8 ++++++-- drivers/net/wireless/rt2x00/rt73usb.c | 9 ++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b7de1a504480..54917a281398 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -772,6 +772,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); unsigned int beacon_base; + unsigned int padding_len; u32 reg; /* @@ -806,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* - * Write entire beacon with TXWI to register. + * Write entire beacon with TXWI and padding to register. */ + padding_len = roundup(entry->skb->len, 4) - entry->skb->len; + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2800_register_multiwrite(rt2x00dev, beacon_base, - entry->skb->data, entry->skb->len); + rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, + entry->skb->len + padding_len); /* * Enable beaconing again. diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 9405b100a75a..8de44dd401e0 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1961,6 +1961,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_pci *entry_priv = entry->priv_data; unsigned int beacon_base; + unsigned int padding_len; u32 reg; /* @@ -1982,13 +1983,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry, rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* - * Write entire beacon with descriptor to register. + * Write entire beacon with descriptor and padding to register. */ + padding_len = roundup(entry->skb->len, 4) - entry->skb->len; + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, entry_priv->desc, TXINFO_SIZE); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, - entry->skb->data, entry->skb->len); + entry->skb->data, + entry->skb->len + padding_len); /* * Enable beaconing again. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 0b3959bdd3eb..0b4e8590cbb7 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1546,6 +1546,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; unsigned int beacon_base; + unsigned int padding_len; u32 reg; /* @@ -1573,11 +1574,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry, rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* - * Write entire beacon with descriptor to register. + * Write entire beacon with descriptor and padding to register. */ + padding_len = roundup(entry->skb->len, 4) - entry->skb->len; + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, - entry->skb->data, entry->skb->len); + rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, + entry->skb->len + padding_len); /* * Enable beaconing again. -- cgit v1.2.3-59-g8ed1b From 412b31334b831a8c2909afaca017c5a236ac2dd0 Mon Sep 17 00:00:00 2001 From: Wolfgang Kufner Date: Mon, 13 Dec 2010 12:39:39 +0100 Subject: rt2x00: Fix firmware loading regression on x86_64. Commit 6175ddf06b6172046a329e3abfd9c901a43efd2e changes the way memcpy_toio() works for x86_64, causing firmware loading to fail for some Ralink WLAN devices with the rt2800pci driver since linux 2.6.34. This causes the log message: "phy0 -> rt2800pci_load_firmware: Error - PBF system register not ready.". Fix this by using __iowrite32_copy instead of memcpy_toio(). Signed-off-by: Wolfgang Kufner Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index b854d62ff99b..746ce8fe8cf4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -64,7 +64,7 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, const void *value, const u32 length) { - memcpy_toio(rt2x00dev->csr.base + offset, value, length); + __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); } /** -- cgit v1.2.3-59-g8ed1b From 76d94b232940ca91e9b26c590cb7312ab88ff722 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:07 +0000 Subject: pch_can: Add flow control processing Currently, there is no flow control processing. Thus, Add flow control processing as when there is no empty of tx buffer, netif_stop_queue is called. When there is empty buffer, netif_wake_queue is called. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index a9b6a6525a65..f0f140492c07 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -102,6 +102,10 @@ #define PCH_FIFO_THRESH 16 +/* TxRqst2 show status of MsgObjNo.17~32 */ +#define PCH_TREQ2_TX_MASK (((1 << PCH_TX_OBJ_NUM) - 1) <<\ + (PCH_RX_OBJ_END - 16)) + enum pch_ifreg { PCH_RX_IFREG, PCH_TX_IFREG, @@ -871,6 +875,8 @@ MSG_OBJ: dlc = 8; stats->tx_bytes += dlc; stats->tx_packets++; + if (int_stat == PCH_TX_OBJ_END) + netif_wake_queue(ndev); } int_stat = pch_can_int_pending(priv); @@ -1009,18 +1015,6 @@ static int pch_close(struct net_device *ndev) return 0; } -static int pch_get_msg_obj_sts(struct net_device *ndev, u32 obj_id) -{ - u32 buffer_status = 0; - struct pch_can_priv *priv = netdev_priv(ndev); - - /* Getting the message object status. */ - buffer_status = (u32) pch_can_get_buffer_status(priv); - - return buffer_status & obj_id; -} - - static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) { int i, j; @@ -1031,17 +1025,16 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; - if (priv->tx_obj == PCH_TX_OBJ_END) { /* Point tail Obj */ - while (pch_get_msg_obj_sts(ndev, (((1 << PCH_TX_OBJ_NUM)-1) << - PCH_RX_OBJ_NUM))) - udelay(500); + if (priv->tx_obj == PCH_TX_OBJ_END) { + if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK) + netif_stop_queue(ndev); - priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj ID */ - tx_buffer_avail = priv->tx_obj; /* Point Tail of Tx Obj */ + tx_buffer_avail = priv->tx_obj; + priv->tx_obj = PCH_TX_OBJ_START; } else { tx_buffer_avail = priv->tx_obj; + priv->tx_obj++; } - priv->tx_obj++; /* Reading the Msg Obj from the Msg RAM to the Interface register. */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); -- cgit v1.2.3-59-g8ed1b From e489ccebf14657774fd877dc841b458703730586 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:08 +0000 Subject: pch_can: Divide poll function To easy to read/understand, divide poll function into two sub-functions. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 71 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index f0f140492c07..0b6d4f490296 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -819,72 +819,71 @@ RX_NEXT: return rcv_pkts; } -static int pch_can_rx_poll(struct napi_struct *napi, int quota) + +static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) { - struct net_device *ndev = napi->dev; struct pch_can_priv *priv = netdev_priv(ndev); struct net_device_stats *stats = &(priv->ndev->stats); u32 dlc; + + can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); + iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, + &priv->regs->ifregs[1].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, int_stat); + dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) & + PCH_IF_MCONT_DLC); + stats->tx_bytes += dlc; + stats->tx_packets++; + if (int_stat == PCH_TX_OBJ_END) + netif_wake_queue(ndev); +} + +static int pch_can_rx_poll(struct napi_struct *napi, int quota) +{ + struct net_device *ndev = napi->dev; + struct pch_can_priv *priv = netdev_priv(ndev); u32 int_stat; int rcv_pkts = 0; u32 reg_stat; int_stat = pch_can_int_pending(priv); if (!int_stat) - return 0; + goto end; -INT_STAT: - if (int_stat == PCH_STATUS_INT) { + if ((int_stat == PCH_STATUS_INT) && (quota > 0)) { reg_stat = ioread32(&priv->regs->stat); if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) { - if ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) + if (reg_stat & PCH_BUS_OFF || + (reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) { pch_can_error(ndev, reg_stat); + quota--; + } } - if (reg_stat & PCH_TX_OK) { - iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, - ioread32(&priv->regs->intr)); + if (reg_stat & PCH_TX_OK) pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK); - } if (reg_stat & PCH_RX_OK) pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK); int_stat = pch_can_int_pending(priv); - if (int_stat == PCH_STATUS_INT) - goto INT_STAT; } -MSG_OBJ: + if (quota == 0) + goto end; + if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { - rcv_pkts = pch_can_rx_normal(ndev, int_stat); - if (rcv_pkts < 0) - return 0; + rcv_pkts += pch_can_rx_normal(ndev, int_stat); + quota -= rcv_pkts; + if (quota < 0) + goto end; } else if ((int_stat >= PCH_TX_OBJ_START) && (int_stat <= PCH_TX_OBJ_END)) { /* Handle transmission interrupt */ - can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); - iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, - &priv->regs->ifregs[1].cmask); - dlc = ioread32(&priv->regs->ifregs[1].mcont) & - PCH_IF_MCONT_DLC; - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, int_stat); - if (dlc > 8) - dlc = 8; - stats->tx_bytes += dlc; - stats->tx_packets++; - if (int_stat == PCH_TX_OBJ_END) - netif_wake_queue(ndev); + pch_can_tx_complete(ndev, int_stat); } - int_stat = pch_can_int_pending(priv); - if (int_stat == PCH_STATUS_INT) - goto INT_STAT; - else if (int_stat >= 1 && int_stat <= 32) - goto MSG_OBJ; - +end: napi_complete(napi); pch_can_set_int_enables(priv, PCH_CAN_ALL); -- cgit v1.2.3-59-g8ed1b From 8ac9702b9d5d81b819fc7d6b4f6abad22af01f3c Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:09 +0000 Subject: pch_can: Fix endianness issue there is endianness issue both Tx and Rx. Currently, data is set like below. Register: MSB--LSB x x D0 D1 x x D2 D3 x x D4 D5 x x D6 D7 But Data to be sent must be set like below. Register: MSB--LSB x x D1 D0 x x D3 D2 x x D5 D4 x x D7 D6 (x means reserved area.) Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 0b6d4f490296..210957f093bb 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -138,10 +138,7 @@ struct pch_can_if_regs { u32 id1; u32 id2; u32 mcont; - u32 dataa1; - u32 dataa2; - u32 datab1; - u32 datab2; + u32 data[4]; u32 rsv[13]; }; @@ -424,10 +421,10 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->ifregs[0].id1); iowrite32(0x0, &priv->regs->ifregs[0].id2); iowrite32(0x0, &priv->regs->ifregs[0].mcont); - iowrite32(0x0, &priv->regs->ifregs[0].dataa1); - iowrite32(0x0, &priv->regs->ifregs[0].dataa2); - iowrite32(0x0, &priv->regs->ifregs[0].datab1); - iowrite32(0x0, &priv->regs->ifregs[0].datab2); + iowrite32(0x0, &priv->regs->ifregs[0].data[0]); + iowrite32(0x0, &priv->regs->ifregs[0].data[1]); + iowrite32(0x0, &priv->regs->ifregs[0].data[2]); + iowrite32(0x0, &priv->regs->ifregs[0].data[3]); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); @@ -441,10 +438,10 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->ifregs[1].id1); iowrite32(0x0, &priv->regs->ifregs[1].id2); iowrite32(0x0, &priv->regs->ifregs[1].mcont); - iowrite32(0x0, &priv->regs->ifregs[1].dataa1); - iowrite32(0x0, &priv->regs->ifregs[1].dataa2); - iowrite32(0x0, &priv->regs->ifregs[1].datab1); - iowrite32(0x0, &priv->regs->ifregs[1].datab2); + iowrite32(0x0, &priv->regs->ifregs[1].data[0]); + iowrite32(0x0, &priv->regs->ifregs[1].data[1]); + iowrite32(0x0, &priv->regs->ifregs[1].data[2]); + iowrite32(0x0, &priv->regs->ifregs[1].data[3]); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask); @@ -707,12 +704,13 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) canid_t id; u32 ide; u32 rtr; - int i, j, k; + int i, k; int rcv_pkts = 0; struct sk_buff *skb; struct can_frame *cf; struct pch_can_priv *priv = netdev_priv(ndev); struct net_device_stats *stats = &(priv->ndev->stats); + u16 data_reg; /* Reading the messsage object from the Message RAM */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); @@ -778,12 +776,10 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) ((ioread32(&priv->regs->ifregs[0].mcont)) & 0x0f); } - for (i = 0, j = 0; i < cf->can_dlc; j++) { - reg = ioread32(&priv->regs->ifregs[0].dataa1 + j*4); - cf->data[i++] = cpu_to_le32(reg & 0xff); - if (i == cf->can_dlc) - break; - cf->data[i++] = cpu_to_le32((reg >> 8) & 0xff); + for (i = 0; i < cf->can_dlc; i += 2) { + data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]); + cf->data[i] = data_reg; + cf->data[i + 1] = data_reg >> 8; } netif_receive_skb(skb); @@ -1016,10 +1012,10 @@ static int pch_close(struct net_device *ndev) static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) { - int i, j; struct pch_can_priv *priv = netdev_priv(ndev); struct can_frame *cf = (struct can_frame *)skb->data; int tx_buffer_avail = 0; + int i; if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; @@ -1060,13 +1056,10 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (cf->can_id & CAN_RTR_FLAG) pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); - for (i = 0, j = 0; i < cf->can_dlc; j++) { - iowrite32(le32_to_cpu(cf->data[i++]), - (&priv->regs->ifregs[1].dataa1) + j*4); - if (i == cf->can_dlc) - break; - iowrite32(le32_to_cpu(cf->data[i++] << 8), - (&priv->regs->ifregs[1].dataa1) + j*4); + /* Copy data to register */ + for (i = 0; i < cf->can_dlc; i += 2) { + iowrite16(cf->data[i] | (cf->data[i + 1] << 8), + &priv->regs->ifregs[1].data[i / 2]); } can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_END - 1); -- cgit v1.2.3-59-g8ed1b From 1d5b4b2778e8e40f42ae5d9556777583f3556d81 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:10 +0000 Subject: pch_can: Improve rx processing Replace complex "goto" to "do~while". For easy to read/understand, it divides a rx function into some functions. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 158 ++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 210957f093bb..d646fbcd546a 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -698,83 +698,110 @@ static irqreturn_t pch_can_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) +static void pch_fifo_thresh(struct pch_can_priv *priv, int obj_id) +{ + if (obj_id < PCH_FIFO_THRESH) { + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | + PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask); + + /* Clearing the Dir bit. */ + pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); + + /* Clearing NewDat & IntPnd */ + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_INTPND); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_id); + } else if (obj_id > PCH_FIFO_THRESH) { + pch_can_int_clr(priv, obj_id); + } else if (obj_id == PCH_FIFO_THRESH) { + int cnt; + for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++) + pch_can_int_clr(priv, cnt + 1); + } +} + +static void pch_can_rx_msg_lost(struct net_device *ndev, int obj_id) +{ + struct pch_can_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &(priv->ndev->stats); + struct sk_buff *skb; + struct can_frame *cf; + + netdev_dbg(priv->ndev, "Msg Obj is overwritten.\n"); + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_MSGLOST); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, + &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_id); + + skb = alloc_can_err_skb(ndev, &cf); + if (!skb) + return; + + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + stats->rx_over_errors++; + stats->rx_errors++; + + netif_receive_skb(skb); +} + +static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) { u32 reg; canid_t id; - u32 ide; - u32 rtr; - int i, k; int rcv_pkts = 0; struct sk_buff *skb; struct can_frame *cf; struct pch_can_priv *priv = netdev_priv(ndev); struct net_device_stats *stats = &(priv->ndev->stats); + int i; + u32 id2; u16 data_reg; - /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, int_stat); + do { + /* Reading the messsage object from the Message RAM */ + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_num); - /* Reading the MCONT register. */ - reg = ioread32(&priv->regs->ifregs[0].mcont); - reg &= 0xffff; + /* Reading the MCONT register. */ + reg = ioread32(&priv->regs->ifregs[0].mcont); + + if (reg & PCH_IF_MCONT_EOB) + break; - for (k = int_stat; !(reg & PCH_IF_MCONT_EOB); k++) { /* If MsgLost bit set. */ if (reg & PCH_IF_MCONT_MSGLOST) { - dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n"); - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_MSGLOST); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, - &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); - - skb = alloc_can_err_skb(ndev, &cf); - if (!skb) - return -ENOMEM; - - priv->can.can_stats.error_passive++; - priv->can.state = CAN_STATE_ERROR_PASSIVE; - cf->can_id |= CAN_ERR_CRTL; - cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; - cf->data[2] |= CAN_ERR_PROT_OVERLOAD; - stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; - - netif_receive_skb(skb); + pch_can_rx_msg_lost(ndev, obj_num); rcv_pkts++; - goto RX_NEXT; + quota--; + obj_num++; + continue; + } else if (!(reg & PCH_IF_MCONT_NEWDAT)) { + obj_num++; + continue; } - if (!(reg & PCH_IF_MCONT_NEWDAT)) - goto RX_NEXT; skb = alloc_can_skb(priv->ndev, &cf); if (!skb) return -ENOMEM; /* Get Received data */ - ide = ((ioread32(&priv->regs->ifregs[0].id2)) & PCH_ID2_XTD) >> - 14; - if (ide) { + id2 = ioread32(&priv->regs->ifregs[0].id2); + if (id2 & PCH_ID2_XTD) { id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff); - id |= (((ioread32(&priv->regs->ifregs[0].id2)) & - 0x1fff) << 16); - cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; + id |= (((id2) & 0x1fff) << 16); + cf->can_id = id | CAN_EFF_FLAG; } else { - id = (((ioread32(&priv->regs->ifregs[0].id2)) & - (CAN_SFF_MASK << 2)) >> 2); - cf->can_id = (id & CAN_SFF_MASK); + id = (id2 >> 2) & CAN_SFF_MASK; + cf->can_id = id; } - rtr = (ioread32(&priv->regs->ifregs[0].id2) & PCH_ID2_DIR); - if (rtr) { - cf->can_dlc = 0; + if (id2 & PCH_ID2_DIR) cf->can_id |= CAN_RTR_FLAG; - } else { - cf->can_dlc = - ((ioread32(&priv->regs->ifregs[0].mcont)) & 0x0f); - } + + cf->can_dlc = get_can_dlc((ioread32(&priv->regs-> + ifregs[0].mcont)) & 0xF); for (i = 0; i < cf->can_dlc; i += 2) { data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]); @@ -785,33 +812,12 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) netif_receive_skb(skb); rcv_pkts++; stats->rx_packets++; + quota--; stats->rx_bytes += cf->can_dlc; - if (k < PCH_FIFO_THRESH) { - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | - PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask); - - /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->ifregs[0].id2, - PCH_ID2_DIR); - - /* Clearing NewDat & IntPnd */ - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_INTPND); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); - } else if (k > PCH_FIFO_THRESH) { - pch_can_int_clr(priv, k); - } else if (k == PCH_FIFO_THRESH) { - int cnt; - for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++) - pch_can_int_clr(priv, cnt+1); - } -RX_NEXT: - /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k); - reg = ioread32(&priv->regs->ifregs[0].mcont); - } + pch_fifo_thresh(priv, obj_num); + obj_num++; + } while (quota > 0); return rcv_pkts; } @@ -869,7 +875,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) goto end; if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { - rcv_pkts += pch_can_rx_normal(ndev, int_stat); + rcv_pkts += pch_can_rx_normal(ndev, int_stat, quota); quota -= rcv_pkts; if (quota < 0) goto end; -- cgit v1.2.3-59-g8ed1b From 7f2bc50efeaeb1dff62ef7e128ae36499fbcf35d Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:11 +0000 Subject: pch_can: Fix warnings Currently, in case CONFIG_PM is disabled, compiler outputs warnings. Move six functions which are used only CONFIG_PM is enabled, into "#ifdef CONFIG_PM" area. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 146 +++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index d646fbcd546a..5fc99cb10df0 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -245,23 +245,6 @@ static void pch_can_set_optmode(struct pch_can_priv *priv) iowrite32(reg_val, &priv->regs->opt); } -static void pch_can_set_int_custom(struct pch_can_priv *priv) -{ - /* Clearing the IE, SIE and EIE bits of Can control register. */ - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); - - /* Appropriately setting them. */ - pch_can_bit_set(&priv->regs->cont, - ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1)); -} - -/* This function retrieves interrupt enabled for the CAN device. */ -static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables) -{ - /* Obtaining the status of IE, SIE and EIE interrupt bits. */ - *enables = ((ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1); -} - static void pch_can_set_int_enables(struct pch_can_priv *priv, enum pch_can_mode interrupt_no) { @@ -355,61 +338,11 @@ static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG); } -static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, - enum pch_ifreg dir) -{ - u32 ie, enable; - - if (dir) - ie = PCH_IF_MCONT_RXIE; - else - ie = PCH_IF_MCONT_TXIE; - - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); - - if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && - ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { - enable = 1; - } else { - enable = 0; - } - return enable; -} - static int pch_can_int_pending(struct pch_can_priv *priv) { return ioread32(&priv->regs->intr) & 0xffff; } -static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, - u32 buffer_num, u32 set) -{ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, - &priv->regs->ifregs[0].cmask); - if (set == PCH_ENABLE) - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_EOB); - else - pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); - - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); -} - -static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, - u32 buffer_num, u32 *link) -{ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); - - if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) - *link = PCH_DISABLE; - else - *link = PCH_ENABLE; -} - static void pch_can_clear_buffers(struct pch_can_priv *priv) { int i; @@ -583,12 +516,6 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) } } -static int pch_can_get_buffer_status(struct pch_can_priv *priv) -{ - return (ioread32(&priv->regs->treq1) & 0xffff) | - ((ioread32(&priv->regs->treq2) & 0xffff) << 16); -} - static void pch_can_reset(struct pch_can_priv *priv) { /* write to sw reset register */ @@ -1109,6 +1036,79 @@ static void __devexit pch_can_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM +static void pch_can_set_int_custom(struct pch_can_priv *priv) +{ + /* Clearing the IE, SIE and EIE bits of Can control register. */ + pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); + + /* Appropriately setting them. */ + pch_can_bit_set(&priv->regs->cont, + ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1)); +} + +/* This function retrieves interrupt enabled for the CAN device. */ +static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables) +{ + /* Obtaining the status of IE, SIE and EIE interrupt bits. */ + *enables = ((ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1); +} + +static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, + enum pch_ifreg dir) +{ + u32 ie, enable; + + if (dir) + ie = PCH_IF_MCONT_RXIE; + else + ie = PCH_IF_MCONT_TXIE; + + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); + + if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && + ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { + enable = 1; + } else { + enable = 0; + } + return enable; +} + +static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, + u32 buffer_num, u32 set) +{ + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, + &priv->regs->ifregs[0].cmask); + if (set == PCH_ENABLE) + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_EOB); + else + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); + + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); +} + +static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, + u32 buffer_num, u32 *link) +{ + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + + if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) + *link = PCH_DISABLE; + else + *link = PCH_ENABLE; +} + +static int pch_can_get_buffer_status(struct pch_can_priv *priv) +{ + return (ioread32(&priv->regs->treq1) & 0xffff) | + ((ioread32(&priv->regs->treq2) & 0xffff) << 16); +} + static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) { int i; /* Counter variable. */ -- cgit v1.2.3-59-g8ed1b From bd58cbc322e97550af5e12584324b7117180435d Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:12 +0000 Subject: pch_can: Rename function/macro name For easy to read/understand, Rename function/macro name. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 176 ++++++++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 99 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 5fc99cb10df0..dd9ce16635b3 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -32,8 +32,6 @@ #include #include -#define PCH_ENABLE 1 /* The enable flag */ -#define PCH_DISABLE 0 /* The disable flag */ #define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */ #define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */ #define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1)) @@ -78,11 +76,12 @@ #define PCH_BUS_OFF BIT(7) /* bit position of certain controller bits. */ -#define PCH_BIT_BRP 0 -#define PCH_BIT_SJW 6 -#define PCH_BIT_TSEG1 8 -#define PCH_BIT_TSEG2 12 -#define PCH_BIT_BRPE_BRPE 6 +#define PCH_BIT_BRP_SHIFT 0 +#define PCH_BIT_SJW_SHIFT 6 +#define PCH_BIT_TSEG1_SHIFT 8 +#define PCH_BIT_TSEG2_SHIFT 12 +#define PCH_BIT_BRPE_BRPE_SHIFT 6 + #define PCH_MSK_BITT_BRP 0x3f #define PCH_MSK_BRPE_BRPE 0x3c0 #define PCH_MSK_CTRL_IE_SIE_EIE 0x07 @@ -170,19 +169,16 @@ struct pch_can_regs { struct pch_can_priv { struct can_priv can; - unsigned int can_num; struct pci_dev *dev; - int tx_enable[PCH_TX_OBJ_END]; - int rx_enable[PCH_TX_OBJ_END]; - int rx_link[PCH_TX_OBJ_END]; - unsigned int int_enables; - unsigned int int_stat; + u32 tx_enable[PCH_TX_OBJ_END]; + u32 rx_enable[PCH_TX_OBJ_END]; + u32 rx_link[PCH_TX_OBJ_END]; + u32 int_enables; struct net_device *ndev; - unsigned int msg_obj[PCH_TX_OBJ_END]; struct pch_can_regs __iomem *regs; struct napi_struct napi; - unsigned int tx_obj; /* Point next Tx Obj index */ - unsigned int use_msi; + int tx_obj; /* Point next Tx Obj index */ + int use_msi; }; static struct can_bittiming_const pch_can_bittiming_const = { @@ -245,14 +241,27 @@ static void pch_can_set_optmode(struct pch_can_priv *priv) iowrite32(reg_val, &priv->regs->opt); } +static void pch_can_rw_msg_obj(void __iomem *creq_addr, u32 num) +{ + int counter = PCH_COUNTER_LIMIT; + u32 ifx_creq; + + iowrite32(num, creq_addr); + while (counter) { + ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY; + if (!ifx_creq) + break; + counter--; + udelay(1); + } + if (!counter) + pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__); +} + static void pch_can_set_int_enables(struct pch_can_priv *priv, enum pch_can_mode interrupt_no) { switch (interrupt_no) { - case PCH_CAN_ENABLE: - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE); - break; - case PCH_CAN_DISABLE: pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE); break; @@ -271,25 +280,8 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, } } -static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num) -{ - u32 counter = PCH_COUNTER_LIMIT; - u32 ifx_creq; - - iowrite32(num, creq_addr); - while (counter) { - ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY; - if (!ifx_creq) - break; - counter--; - udelay(1); - } - if (!counter) - pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__); -} - static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, - u32 set, enum pch_ifreg dir) + int set, enum pch_ifreg dir) { u32 ie; @@ -300,27 +292,27 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, /* Reading the receive buffer data from RAM to Interface1 registers */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[dir].cmask); - if (set == PCH_ENABLE) { + if (set) { /* Setting the MsgVal and RxIE bits */ pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie); pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); - } else if (set == PCH_DISABLE) { + } else { /* Resetting the MsgVal and RxIE bits */ pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie); pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); } - pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); } -static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set) +static void pch_can_set_rx_all(struct pch_can_priv *priv, int set) { int i; @@ -329,7 +321,7 @@ static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set) pch_can_set_rxtx(priv, i, set, PCH_RX_IFREG); } -static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) +static void pch_can_set_tx_all(struct pch_can_priv *priv, int set) { int i; @@ -338,16 +330,16 @@ static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set) pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG); } -static int pch_can_int_pending(struct pch_can_priv *priv) +static u32 pch_can_int_pending(struct pch_can_priv *priv) { return ioread32(&priv->regs->intr) & 0xffff; } -static void pch_can_clear_buffers(struct pch_can_priv *priv) +static void pch_can_clear_if_buffers(struct pch_can_priv *priv) { - int i; + int i; /* Msg Obj ID (1~32) */ - for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { + for (i = PCH_RX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask); iowrite32(0xffff, &priv->regs->ifregs[0].mask1); iowrite32(0xffff, &priv->regs->ifregs[0].mask2); @@ -361,24 +353,7 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); - } - - for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[1].cmask); - iowrite32(0xffff, &priv->regs->ifregs[1].mask1); - iowrite32(0xffff, &priv->regs->ifregs[1].mask2); - iowrite32(0x0, &priv->regs->ifregs[1].id1); - iowrite32(0x0, &priv->regs->ifregs[1].id2); - iowrite32(0x0, &priv->regs->ifregs[1].mcont); - iowrite32(0x0, &priv->regs->ifregs[1].data[0]); - iowrite32(0x0, &priv->regs->ifregs[1].data[1]); - iowrite32(0x0, &priv->regs->ifregs[1].data[2]); - iowrite32(0x0, &priv->regs->ifregs[1].data[3]); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); } } @@ -389,7 +364,7 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); iowrite32(0x0, &priv->regs->ifregs[0].id1); iowrite32(0x0, &priv->regs->ifregs[0].id2); @@ -403,6 +378,9 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ if (i == PCH_RX_OBJ_END) pch_can_bit_set(&priv->regs->ifregs[0].mcont, + PCH_IF_MCONT_EOB); + else + pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); iowrite32(0, &priv->regs->ifregs[0].mask1); @@ -414,13 +392,13 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); } for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); /* Resetting DIR bit for reception */ iowrite32(0x0, &priv->regs->ifregs[1].id1); @@ -441,7 +419,7 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); } } @@ -451,7 +429,7 @@ static void pch_can_init(struct pch_can_priv *priv) pch_can_set_run_mode(priv, PCH_CAN_STOP); /* Clearing all the message object buffers. */ - pch_can_clear_buffers(priv); + pch_can_clear_if_buffers(priv); /* Configuring the respective message object as either rx/tx object. */ pch_can_config_rx_tx_buffers(priv); @@ -496,7 +474,7 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, mask); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, mask); } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) { /* Setting CMASK for clearing interrupts for frame transmission. */ @@ -512,7 +490,7 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) pch_can_bit_clear(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | PCH_IF_MCONT_TXRQXT); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, mask); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, mask); } } @@ -637,7 +615,7 @@ static void pch_fifo_thresh(struct pch_can_priv *priv, int obj_id) /* Clearing NewDat & IntPnd */ pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_INTPND); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_id); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id); } else if (obj_id > PCH_FIFO_THRESH) { pch_can_int_clr(priv, obj_id); } else if (obj_id == PCH_FIFO_THRESH) { @@ -659,7 +637,7 @@ static void pch_can_rx_msg_lost(struct net_device *ndev, int obj_id) PCH_IF_MCONT_MSGLOST); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_id); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id); skb = alloc_can_err_skb(ndev, &cf); if (!skb) @@ -689,7 +667,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) do { /* Reading the messsage object from the Message RAM */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, obj_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num); /* Reading the MCONT register. */ reg = ioread32(&priv->regs->ifregs[0].mcont); @@ -758,7 +736,7 @@ static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, int_stat); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, int_stat); dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) & PCH_IF_MCONT_DLC); stats->tx_bytes += dlc; @@ -767,7 +745,7 @@ static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) netif_wake_queue(ndev); } -static int pch_can_rx_poll(struct napi_struct *napi, int quota) +static int pch_can_poll(struct napi_struct *napi, int quota) { struct net_device *ndev = napi->dev; struct pch_can_priv *priv = netdev_priv(ndev); @@ -832,10 +810,10 @@ static int pch_set_bittiming(struct net_device *ndev) brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1; canbit = brp & PCH_MSK_BITT_BRP; - canbit |= (bt->sjw - 1) << PCH_BIT_SJW; - canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1; - canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2; - bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE; + canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT; + canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT; + canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT; + bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT; iowrite32(canbit, &priv->regs->bitt); iowrite32(bepe, &priv->regs->brpe); pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE); @@ -947,7 +925,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) { struct pch_can_priv *priv = netdev_priv(ndev); struct can_frame *cf = (struct can_frame *)skb->data; - int tx_buffer_avail = 0; + int tx_obj_no; int i; if (can_dropped_invalid_skb(ndev, skb)) @@ -957,16 +935,16 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK) netif_stop_queue(ndev); - tx_buffer_avail = priv->tx_obj; + tx_obj_no = priv->tx_obj; priv->tx_obj = PCH_TX_OBJ_START; } else { - tx_buffer_avail = priv->tx_obj; + tx_obj_no = priv->tx_obj; priv->tx_obj++; } /* Reading the Msg Obj from the Msg RAM to the Interface register. */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no); /* Setting the CMASK register. */ pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); @@ -995,7 +973,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) &priv->regs->ifregs[1].data[i / 2]); } - can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_END - 1); + can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1); /* Updating the size of the data. */ pch_can_bit_clear(&priv->regs->ifregs[1].mcont, 0x0f); @@ -1010,7 +988,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) pch_can_bit_set(&priv->regs->ifregs[1].mcont, PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT); - pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail); + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no); return NETDEV_TX_OK; } @@ -1064,7 +1042,7 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, ie = PCH_IF_MCONT_TXIE; iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { @@ -1076,37 +1054,37 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, } static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, - u32 buffer_num, u32 set) + u32 buffer_num, int set) { iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); - if (set == PCH_ENABLE) + if (set) pch_can_bit_clear(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); else pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); } static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num, u32 *link) { iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); - pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num); + pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) - *link = PCH_DISABLE; + *link = 0; else - *link = PCH_ENABLE; + *link = 1; } static int pch_can_get_buffer_status(struct pch_can_priv *priv) { return (ioread32(&priv->regs->treq1) & 0xffff) | - ((ioread32(&priv->regs->treq2) & 0xffff) << 16); + (ioread32(&priv->regs->treq2) << 16); } static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) @@ -1114,7 +1092,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) int i; /* Counter variable. */ int retval; /* Return value. */ u32 buf_stat; /* Variable for reading the transmit buffer status. */ - u32 counter = 0xFFFFFF; + int counter = PCH_COUNTER_LIMIT; struct net_device *dev = pci_get_drvdata(pdev); struct pch_can_priv *priv = netdev_priv(dev); @@ -1291,7 +1269,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, ndev->netdev_ops = &pch_can_netdev_ops; priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ - netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_END); + netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END); rc = register_candev(ndev); if (rc) { -- cgit v1.2.3-59-g8ed1b From ca2b004e89484e89b1815157fae2d7f933c5af9e Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:13 +0000 Subject: pch_can: Change functions type Currently, these two functions spec(returned value) is unnatural. Thus, change the return value's spec Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index dd9ce16635b3..c6c0842aeb75 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1025,10 +1025,10 @@ static void pch_can_set_int_custom(struct pch_can_priv *priv) } /* This function retrieves interrupt enabled for the CAN device. */ -static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables) +static u32 pch_can_get_int_enables(struct pch_can_priv *priv) { /* Obtaining the status of IE, SIE and EIE interrupt bits. */ - *enables = ((ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1); + return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1; } static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, @@ -1069,16 +1069,18 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); } -static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, - u32 buffer_num, u32 *link) +static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num) { + u32 link; + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) - *link = 0; + link = 0; else - *link = 1; + link = 1; + return link; } static int pch_can_get_buffer_status(struct pch_can_priv *priv) @@ -1115,7 +1117,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) dev_err(&pdev->dev, "%s -> Transmission time out.\n", __func__); /* Save interrupt configuration and then disable them */ - pch_can_get_int_enables(priv, &(priv->int_enables)); + priv->int_enables = pch_can_get_int_enables(priv); pch_can_set_int_enables(priv, PCH_CAN_DISABLE); /* Save Tx buffer enable state */ @@ -1128,7 +1130,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Rx buffer enable state */ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i, PCH_RX_IFREG); - pch_can_get_rx_buffer_link(priv, i, &priv->rx_link[i]); + priv->rx_link[i] = pch_can_get_rx_buffer_link(priv, i); } /* Disable all Receive buffers */ -- cgit v1.2.3-59-g8ed1b From 44c9aa890a2587f48920485b7487bc6d516dbbdf Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:14 +0000 Subject: pch_can: Reduce register access For improve tx/rx speed, reduce register access. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 55 ++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c6c0842aeb75..0acc87755b24 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -372,9 +372,6 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_UMASK); - /* Set FIFO mode set to 0 except last Rx Obj*/ - pch_can_bit_clear(&priv->regs->ifregs[0].mcont, - PCH_IF_MCONT_EOB); /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ if (i == PCH_RX_OBJ_END) pch_can_bit_set(&priv->regs->ifregs[0].mcont, @@ -402,14 +399,11 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) /* Resetting DIR bit for reception */ iowrite32(0x0, &priv->regs->ifregs[1].id1); - iowrite32(0x0, &priv->regs->ifregs[1].id2); - pch_can_bit_set(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); + iowrite32(PCH_ID2_DIR, &priv->regs->ifregs[1].id2); /* Setting EOB bit for transmitter */ - iowrite32(PCH_IF_MCONT_EOB, &priv->regs->ifregs[1].mcont); - - pch_can_bit_set(&priv->regs->ifregs[1].mcont, - PCH_IF_MCONT_UMASK); + iowrite32(PCH_IF_MCONT_EOB | PCH_IF_MCONT_UMASK, + &priv->regs->ifregs[1].mcont); iowrite32(0, &priv->regs->ifregs[1].mask1); pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); @@ -524,12 +518,12 @@ static void pch_can_error(struct net_device *ndev, u32 status) dev_err(&ndev->dev, "%s -> Bus Off occurres.\n", __func__); } + errc = ioread32(&priv->regs->errc); /* Warning interrupt. */ if (status & PCH_EWARN) { state = CAN_STATE_ERROR_WARNING; priv->can.can_stats.error_warning++; cf->can_id |= CAN_ERR_CRTL; - errc = ioread32(&priv->regs->errc); if (((errc & PCH_REC) >> 8) > 96) cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; if ((errc & PCH_TEC) > 96) @@ -542,7 +536,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) priv->can.can_stats.error_passive++; state = CAN_STATE_ERROR_PASSIVE; cf->can_id |= CAN_ERR_CRTL; - errc = ioread32(&priv->regs->errc); if (((errc & PCH_REC) >> 8) > 127) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; if ((errc & PCH_TEC) > 127) @@ -927,6 +920,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) struct can_frame *cf = (struct can_frame *)skb->data; int tx_obj_no; int i; + u32 id2; if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; @@ -950,22 +944,23 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); /* If ID extended is set. */ - pch_can_bit_clear(&priv->regs->ifregs[1].id1, 0xffff); - pch_can_bit_clear(&priv->regs->ifregs[1].id2, 0x1fff | PCH_ID2_XTD); if (cf->can_id & CAN_EFF_FLAG) { - pch_can_bit_set(&priv->regs->ifregs[1].id1, - cf->can_id & 0xffff); - pch_can_bit_set(&priv->regs->ifregs[1].id2, - ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD); + iowrite32(cf->can_id & 0xffff, &priv->regs->ifregs[1].id1); + id2 = ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD; } else { - pch_can_bit_set(&priv->regs->ifregs[1].id1, 0); - pch_can_bit_set(&priv->regs->ifregs[1].id2, - (cf->can_id & CAN_SFF_MASK) << 2); + iowrite32(0, &priv->regs->ifregs[1].id1); + id2 = (cf->can_id & CAN_SFF_MASK) << 2; } + id2 |= PCH_ID_MSGVAL; + /* If remote frame has to be transmitted.. */ if (cf->can_id & CAN_RTR_FLAG) - pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); + id2 &= ~PCH_ID2_DIR; + else + id2 |= PCH_ID2_DIR; + + iowrite32(id2, &priv->regs->ifregs[1].id2); /* Copy data to register */ for (i = 0; i < cf->can_dlc; i += 2) { @@ -976,17 +971,8 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1); /* Updating the size of the data. */ - pch_can_bit_clear(&priv->regs->ifregs[1].mcont, 0x0f); - pch_can_bit_set(&priv->regs->ifregs[1].mcont, cf->can_dlc); - - /* Clearing IntPend, NewDat & TxRqst */ - pch_can_bit_clear(&priv->regs->ifregs[1].mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | - PCH_IF_MCONT_TXRQXT); - - /* Setting NewDat, TxRqst bits */ - pch_can_bit_set(&priv->regs->ifregs[1].mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT); + iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT | + PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont); pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no); @@ -1211,9 +1197,10 @@ static int pch_can_get_berr_counter(const struct net_device *dev, struct can_berr_counter *bec) { struct pch_can_priv *priv = netdev_priv(dev); + u32 errc = ioread32(&priv->regs->errc); - bec->txerr = ioread32(&priv->regs->errc) & PCH_TEC; - bec->rxerr = (ioread32(&priv->regs->errc) & PCH_REC) >> 8; + bec->txerr = errc & PCH_TEC; + bec->rxerr = (errc & PCH_REC) >> 8; return 0; } -- cgit v1.2.3-59-g8ed1b From e91530ea959295a31911488c62088d5c372032ea Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:15 +0000 Subject: pch_can: Change Copyright and module description Currently, Copyright and module description are not formal. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 0acc87755b24..293be5151f05 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 - 2010 Intel Corporation. - * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * * 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 @@ -1301,6 +1301,6 @@ static void __exit pch_can_pci_exit(void) } module_exit(pch_can_pci_exit); -MODULE_DESCRIPTION("Controller Area Network Driver"); +MODULE_DESCRIPTION("Intel EG20T PCH CAN(Controller Area Network) Driver"); MODULE_LICENSE("GPL v2"); MODULE_VERSION("0.94"); -- cgit v1.2.3-59-g8ed1b From 435b4efe93d4cec3aa0b36e8707df8d292d3641b Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:16 +0000 Subject: pch_can: Replace netdev_dbg instead of dev_dbg partly For easy to readable, use netdev_dbg instead of dev_dbg partly Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 293be5151f05..0093a01fefda 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -222,7 +222,7 @@ static void pch_can_set_run_mode(struct pch_can_priv *priv, break; default: - dev_err(&priv->ndev->dev, "%s -> Invalid Mode.\n", __func__); + netdev_err(priv->ndev, "%s -> Invalid Mode.\n", __func__); break; } } @@ -275,7 +275,7 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, break; default: - dev_err(&priv->ndev->dev, "Invalid interrupt number.\n"); + netdev_err(priv->ndev, "Invalid interrupt number.\n"); break; } } @@ -528,7 +528,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; if ((errc & PCH_TEC) > 96) cf->data[1] |= CAN_ERR_CRTL_TX_WARNING; - dev_warn(&ndev->dev, + netdev_dbg(ndev, "%s -> Error Counter is more than 96.\n", __func__); } /* Error passive interrupt. */ @@ -540,7 +540,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; if ((errc & PCH_TEC) > 127) cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; - dev_err(&ndev->dev, + netdev_dbg(ndev, "%s -> CAN controller is ERROR PASSIVE .\n", __func__); } @@ -859,10 +859,10 @@ static int pch_can_open(struct net_device *ndev) retval = pci_enable_msi(priv->dev); if (retval) { - dev_info(&ndev->dev, "PCH CAN opened without MSI\n"); + netdev_err(ndev, "PCH CAN opened without MSI\n"); priv->use_msi = 0; } else { - dev_info(&ndev->dev, "PCH CAN opened with MSI\n"); + netdev_err(ndev, "PCH CAN opened with MSI\n"); priv->use_msi = 1; } @@ -870,14 +870,14 @@ static int pch_can_open(struct net_device *ndev) retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED, ndev->name, ndev); if (retval) { - dev_err(&ndev->dev, "request_irq failed.\n"); + netdev_err(ndev, "request_irq failed.\n"); goto req_irq_err; } /* Open common can device */ retval = open_candev(ndev); if (retval) { - dev_err(ndev->dev.parent, "open_candev() failed %d\n", retval); + netdev_err(ndev, "open_candev() failed %d\n", retval); goto err_open_candev; } -- cgit v1.2.3-59-g8ed1b From 9388b166a323f8f7e35eb7a0d17b297ca695fa91 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:17 +0000 Subject: pch_can: Fix coding rule violation Fix coding rule violation. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 0093a01fefda..da8d37bd02b1 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -89,9 +89,11 @@ #define PCH_CAN_CLK 50000000 /* 50MHz */ -/* Define the number of message object. +/* + * Define the number of message object. * PCH CAN communications are done via Message RAM. - * The Message RAM consists of 32 message objects. */ + * The Message RAM consists of 32 message objects. + */ #define PCH_RX_OBJ_NUM 26 #define PCH_TX_OBJ_NUM 6 #define PCH_RX_OBJ_START 1 @@ -126,7 +128,7 @@ enum pch_can_mode { PCH_CAN_ALL, PCH_CAN_NONE, PCH_CAN_STOP, - PCH_CAN_RUN + PCH_CAN_RUN, }; struct pch_can_if_regs { @@ -290,21 +292,20 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, else ie = PCH_IF_MCONT_RXIE; - /* Reading the receive buffer data from RAM to Interface1 registers */ + /* Reading the receive buffer data from RAM to Interface1/2 registers */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); - /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */ + /* Setting the IF1/2MASK1 register to access MsgVal and RxIE bits */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, &priv->regs->ifregs[dir].cmask); if (set) { - /* Setting the MsgVal and RxIE bits */ + /* Setting the MsgVal and RxIE/TxIE bits */ pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie); pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); - } else { - /* Resetting the MsgVal and RxIE bits */ + /* Clearing the MsgVal and RxIE/TxIE bits */ pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie); pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); } @@ -362,8 +363,7 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) int i; for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { - iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->ifregs[0].cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); iowrite32(0x0, &priv->regs->ifregs[0].id1); @@ -385,16 +385,14 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) 0x1fff | PCH_MASK2_MDIR_MXTD); /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->ifregs[0].cmask); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | + PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); } for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { - iowrite32(PCH_CMASK_RX_TX_GET, - &priv->regs->ifregs[1].cmask); + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); /* Resetting DIR bit for reception */ @@ -409,9 +407,8 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, - &priv->regs->ifregs[1].cmask); + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | + PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); } @@ -470,8 +467,9 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, mask); } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) { - /* Setting CMASK for clearing interrupts for - frame transmission. */ + /* + * Setting CMASK for clearing interrupts for frame transmission. + */ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, &priv->regs->ifregs[1].cmask); @@ -590,7 +588,6 @@ static irqreturn_t pch_can_interrupt(int irq, void *dev_id) struct pch_can_priv *priv = netdev_priv(ndev); pch_can_set_int_enables(priv, PCH_CAN_NONE); - napi_schedule(&priv->napi); return IRQ_HANDLED; @@ -1031,11 +1028,11 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && - ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) { + ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) enable = 1; - } else { + else enable = 0; - } + return enable; } -- cgit v1.2.3-59-g8ed1b From 8714fcaca63203fe10331fe530ff48d3dd31de4e Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:18 +0000 Subject: pch_can: Delete unnecessary/redundant code Delete unnecessary/redundant code Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index da8d37bd02b1..354097872cbe 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -447,11 +447,6 @@ static void pch_can_release(struct pch_can_priv *priv) /* This function clears interrupt(s) from the CAN device. */ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) { - if (mask == PCH_STATUS_INT) { - ioread32(&priv->regs->stat); - return; - } - /* Clear interrupt for transmit object */ if ((mask >= PCH_RX_OBJ_START) && (mask <= PCH_RX_OBJ_END)) { /* Setting CMASK for clearing the reception interrupts. */ @@ -512,8 +507,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; can_bus_off(ndev); - pch_can_set_run_mode(priv, PCH_CAN_RUN); - dev_err(&ndev->dev, "%s -> Bus Off occurres.\n", __func__); } errc = ioread32(&priv->regs->errc); @@ -747,7 +740,7 @@ static int pch_can_poll(struct napi_struct *napi, int quota) if (!int_stat) goto end; - if ((int_stat == PCH_STATUS_INT) && (quota > 0)) { + if (int_stat == PCH_STATUS_INT) { reg_stat = ioread32(&priv->regs->stat); if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) { if (reg_stat & PCH_BUS_OFF || @@ -933,10 +926,6 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) priv->tx_obj++; } - /* Reading the Msg Obj from the Msg RAM to the Interface register. */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); - pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no); - /* Setting the CMASK register. */ pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); -- cgit v1.2.3-59-g8ed1b From 0e0805c4063d0611e282bb7fdebe2e223bfe7220 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:19 +0000 Subject: pch_can: Fix bit timing calculation issue Modify like use calculated value directly passed by CAN core module. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 354097872cbe..5a6a0df5141e 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -786,17 +786,15 @@ static int pch_set_bittiming(struct net_device *ndev) const struct can_bittiming *bt = &priv->can.bittiming; u32 canbit; u32 bepe; - u32 brp; /* Setting the CCE bit for accessing the Can Timing register. */ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE); - brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1; - canbit = brp & PCH_MSK_BITT_BRP; + canbit = (bt->brp - 1) & PCH_MSK_BITT_BRP; canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT; canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT; canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT; - bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT; + bepe = ((bt->brp - 1) & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT; iowrite32(canbit, &priv->regs->bitt); iowrite32(bepe, &priv->regs->brpe); pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE); -- cgit v1.2.3-59-g8ed1b From d06848be64e13d5d1d73e581fb185e815893d8b7 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:20 +0000 Subject: pch_can: Fix miss-setting status issue Modify miss-setting status issue at suspend. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 5a6a0df5141e..c500b6d65084 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1073,7 +1073,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) pch_can_set_run_mode(priv, PCH_CAN_STOP); /* Indicate that we are aboutto/in suspend */ - priv->can.state = CAN_STATE_SLEEPING; + priv->can.state = CAN_STATE_STOPPED; /* Waiting for all transmission to complete. */ while (counter) { -- cgit v1.2.3-59-g8ed1b From c755145649fa73bd197ac1a73d141047c61b543a Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:21 +0000 Subject: pch_can: Comment optimization Comment optimization Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c500b6d65084..a1fd3be69a81 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -292,7 +292,7 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, else ie = PCH_IF_MCONT_RXIE; - /* Reading the receive buffer data from RAM to Interface1/2 registers */ + /* Reading the Msg buffer from Message RAM to IF1/2 registers. */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); @@ -854,7 +854,7 @@ static int pch_can_open(struct net_device *ndev) priv->use_msi = 1; } - /* Regsitering the interrupt. */ + /* Regstering the interrupt. */ retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED, ndev->name, ndev); if (retval) { @@ -954,7 +954,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1); - /* Updating the size of the data. */ + /* Set the size of the data. Update if2_mcont */ iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT | PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont); @@ -1061,8 +1061,8 @@ static int pch_can_get_buffer_status(struct pch_can_priv *priv) static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) { - int i; /* Counter variable. */ - int retval; /* Return value. */ + int i; + int retval; u32 buf_stat; /* Variable for reading the transmit buffer status. */ int counter = PCH_COUNTER_LIMIT; @@ -1119,8 +1119,8 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) static int pch_can_resume(struct pci_dev *pdev) { - int i; /* Counter variable. */ - int retval; /* Return variable. */ + int i; + int retval; struct net_device *dev = pci_get_drvdata(pdev); struct pch_can_priv *priv = netdev_priv(dev); -- cgit v1.2.3-59-g8ed1b From a6f6d6b51b110e661ae5f862d60c27da4970bec6 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:22 +0000 Subject: pch_can: Move MSI processing to probe/remove processing Currently, in case this driver is integrated as module, and when this module is re-installed, no interrupts is to be occurred. For the above issue, move MSI processing to open/release processing. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index a1fd3be69a81..ace1fe790ce0 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -845,15 +845,6 @@ static int pch_can_open(struct net_device *ndev) struct pch_can_priv *priv = netdev_priv(ndev); int retval; - retval = pci_enable_msi(priv->dev); - if (retval) { - netdev_err(ndev, "PCH CAN opened without MSI\n"); - priv->use_msi = 0; - } else { - netdev_err(ndev, "PCH CAN opened with MSI\n"); - priv->use_msi = 1; - } - /* Regstering the interrupt. */ retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED, ndev->name, ndev); @@ -879,9 +870,6 @@ static int pch_can_open(struct net_device *ndev) err_open_candev: free_irq(priv->dev->irq, ndev); req_irq_err: - if (priv->use_msi) - pci_disable_msi(priv->dev); - pch_can_release(priv); return retval; @@ -895,8 +883,6 @@ static int pch_close(struct net_device *ndev) napi_disable(&priv->napi); pch_can_release(priv); free_irq(priv->dev->irq, ndev); - if (priv->use_msi) - pci_disable_msi(priv->dev); close_candev(ndev); priv->can.state = CAN_STATE_STOPPED; return 0; @@ -975,12 +961,14 @@ static void __devexit pch_can_remove(struct pci_dev *pdev) struct pch_can_priv *priv = netdev_priv(ndev); unregister_candev(priv->ndev); - free_candev(priv->ndev); pci_iounmap(pdev, priv->regs); + if (priv->use_msi) + pci_disable_msi(priv->dev); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); pch_can_reset(priv); + free_candev(priv->ndev); } #ifdef CONFIG_PM @@ -1244,6 +1232,15 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END); + rc = pci_enable_msi(priv->dev); + if (rc) { + netdev_err(ndev, "PCH CAN opened without MSI\n"); + priv->use_msi = 0; + } else { + netdev_err(ndev, "PCH CAN opened with MSI\n"); + priv->use_msi = 1; + } + rc = register_candev(ndev); if (rc) { dev_err(&pdev->dev, "Failed register_candev %d\n", rc); @@ -1253,6 +1250,8 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, return 0; probe_exit_reg_candev: + if (priv->use_msi) + pci_disable_msi(priv->dev); free_candev(ndev); probe_exit_alloc_candev: pci_iounmap(pdev, addr); -- cgit v1.2.3-59-g8ed1b From 3332bc5446e034566e8a56bf7a7cd479ca35bd6d Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:23 +0000 Subject: pch_can: Fix incorrect return processing Fix incorrect return processing. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index ace1fe790ce0..8efbe359ba2a 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -580,9 +580,11 @@ static irqreturn_t pch_can_interrupt(int irq, void *dev_id) struct net_device *ndev = (struct net_device *)dev_id; struct pch_can_priv *priv = netdev_priv(ndev); + if (!pch_can_int_pending(priv)) + return IRQ_NONE; + pch_can_set_int_enables(priv, PCH_CAN_NONE); napi_schedule(&priv->napi); - return IRQ_HANDLED; } @@ -671,8 +673,10 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) } skb = alloc_can_skb(priv->ndev, &cf); - if (!skb) - return -ENOMEM; + if (!skb) { + netdev_err(ndev, "alloc_can_skb Failed\n"); + return rcv_pkts; + } /* Get Received data */ id2 = ioread32(&priv->regs->ifregs[0].id2); @@ -733,8 +737,8 @@ static int pch_can_poll(struct napi_struct *napi, int quota) struct net_device *ndev = napi->dev; struct pch_can_priv *priv = netdev_priv(ndev); u32 int_stat; - int rcv_pkts = 0; u32 reg_stat; + int quota_save = quota; int_stat = pch_can_int_pending(priv); if (!int_stat) @@ -763,10 +767,7 @@ static int pch_can_poll(struct napi_struct *napi, int quota) goto end; if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { - rcv_pkts += pch_can_rx_normal(ndev, int_stat, quota); - quota -= rcv_pkts; - if (quota < 0) - goto end; + quota -= pch_can_rx_normal(ndev, int_stat, quota); } else if ((int_stat >= PCH_TX_OBJ_START) && (int_stat <= PCH_TX_OBJ_END)) { /* Handle transmission interrupt */ @@ -777,7 +778,7 @@ end: napi_complete(napi); pch_can_set_int_enables(priv, PCH_CAN_ALL); - return rcv_pkts; + return quota_save - quota; } static int pch_set_bittiming(struct net_device *ndev) -- cgit v1.2.3-59-g8ed1b From fea9294c5f2902c45613681ad995ca27899d2016 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:24 +0000 Subject: pch_can: Optimize "if" condition in rx/tx processing For reduce "if" condition, easy to read/understand the code, optimize "if" condition in rx/tx processing. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 8efbe359ba2a..dcd8f0032fd1 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -746,19 +746,16 @@ static int pch_can_poll(struct napi_struct *napi, int quota) if (int_stat == PCH_STATUS_INT) { reg_stat = ioread32(&priv->regs->stat); - if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) { - if (reg_stat & PCH_BUS_OFF || - (reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) { - pch_can_error(ndev, reg_stat); - quota--; - } - } - if (reg_stat & PCH_TX_OK) - pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK); + if ((reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) && + ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)) { + pch_can_error(ndev, reg_stat); + quota--; + } - if (reg_stat & PCH_RX_OK) - pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK); + if (reg_stat & (PCH_TX_OK | PCH_RX_OK)) + pch_can_bit_clear(&priv->regs->stat, + reg_stat & (PCH_TX_OK | PCH_RX_OK)); int_stat = pch_can_int_pending(priv); } @@ -900,14 +897,13 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; + tx_obj_no = priv->tx_obj; if (priv->tx_obj == PCH_TX_OBJ_END) { if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK) netif_stop_queue(ndev); - tx_obj_no = priv->tx_obj; priv->tx_obj = PCH_TX_OBJ_START; } else { - tx_obj_no = priv->tx_obj; priv->tx_obj++; } @@ -926,9 +922,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) id2 |= PCH_ID_MSGVAL; /* If remote frame has to be transmitted.. */ - if (cf->can_id & CAN_RTR_FLAG) - id2 &= ~PCH_ID2_DIR; - else + if (!(cf->can_id & CAN_RTR_FLAG)) id2 |= PCH_ID2_DIR; iowrite32(id2, &priv->regs->ifregs[1].id2); -- cgit v1.2.3-59-g8ed1b From 0c78ab76a05cd788af0383354ffe819e0617f6a0 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:25 +0000 Subject: pch_can: Add setting TEC/REC statistics processing Add setting TEC/REC statistics processing. Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index dcd8f0032fd1..4697b1cf94e8 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -568,6 +568,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) break; } + cf->data[6] = errc & PCH_TEC; + cf->data[7] = (errc & PCH_REC) >> 8; + priv->can.state = state; netif_rx(skb); -- cgit v1.2.3-59-g8ed1b From cfb7e5f187e787bb1430decea339fdea6a669f92 Mon Sep 17 00:00:00 2001 From: Tomoya Date: Sun, 12 Dec 2010 20:24:26 +0000 Subject: pch_can: Replace netif_rx to netif_receive_skb Since this driver is implemented as NAPI, netif_receive_skb must be used not netif_rx. Signed-off-by: Tomoya MORINAGA Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 4697b1cf94e8..8d45fdd0180d 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -572,7 +572,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->data[7] = (errc & PCH_REC) >> 8; priv->can.state = state; - netif_rx(skb); + netif_receive_skb(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; -- cgit v1.2.3-59-g8ed1b From cc6f02dd490dac4ad821d5077b934c9b37037cd0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 13 Dec 2010 12:50:49 -0800 Subject: net: change ip_default_ttl documentation Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2193a5d124c5..d99940dcfc44 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -11,7 +11,9 @@ ip_forward - BOOLEAN for routers) ip_default_ttl - INTEGER - default 64 + Default value of TTL field (Time To Live) for outgoing (but not + forwarded) IP packets. Should be between 1 and 255 inclusive. + Default: 64 (as recommended by RFC1700) ip_no_pmtu_disc - BOOLEAN Disable Path MTU Discovery. -- cgit v1.2.3-59-g8ed1b From 0dbaee3b37e118a96bb7b8eb0d9bbaeeb46264be Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Dec 2010 12:52:14 -0800 Subject: net: Abstract default ADVMSS behind an accessor. Make all RTAX_ADVMSS metric accesses go through a new helper function, dst_metric_advmss(). Leave the actual default metric as "zero" in the real metric slot, and compute the actual default value dynamically via a new dst_ops AF specific callback. For stacked IPSEC routes, we use the advmss of the path which preserves existing behavior. Unlike ipv4/ipv6, DecNET ties the advmss to the mtu and thus updates advmss on pmtu updates. This inconsistency in advmss handling results in more raw metric accesses than I wish we ended up with. Signed-off-by: David S. Miller --- drivers/scsi/cxgbi/libcxgbi.c | 2 +- include/net/dst.h | 14 +++++++++++++- include/net/dst_ops.h | 1 + net/decnet/af_decnet.c | 4 ++-- net/decnet/dn_route.c | 22 ++++++++++++++++------ net/ipv4/route.c | 24 +++++++++++++++++------- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_output.c | 14 +++++++++----- net/ipv6/route.c | 16 +++++++--------- net/ipv6/tcp_ipv6.c | 2 +- net/xfrm/xfrm_policy.c | 7 +++++++ 11 files changed, 75 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index be5661707dfa..d2ad3d676724 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -825,7 +825,7 @@ unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *csk, unsigned int pmtu) unsigned int idx; struct dst_entry *dst = csk->dst; - csk->advmss = dst_metric(dst, RTAX_ADVMSS); + csk->advmss = dst_metric_advmss(dst); if (csk->advmss > pmtu - 40) csk->advmss = pmtu - 40; diff --git a/include/net/dst.h b/include/net/dst.h index 755ac6c1aa03..03a1c3d52d80 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -112,10 +112,22 @@ dst_metric_raw(const struct dst_entry *dst, const int metric) static inline u32 dst_metric(const struct dst_entry *dst, const int metric) { - WARN_ON_ONCE(metric == RTAX_HOPLIMIT); + WARN_ON_ONCE(metric == RTAX_HOPLIMIT || + metric == RTAX_ADVMSS); return dst_metric_raw(dst, metric); } +static inline u32 +dst_metric_advmss(const struct dst_entry *dst) +{ + u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS); + + if (!advmss) + advmss = dst->ops->default_advmss(dst); + + return advmss; +} + static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index 51665b3461b8..15fb7af08c42 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -16,6 +16,7 @@ struct dst_ops { int (*gc)(struct dst_ops *ops); struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); + unsigned int (*default_advmss)(const struct dst_entry *); void (*destroy)(struct dst_entry *); void (*ifdown)(struct dst_entry *, struct net_device *dev, int how); diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 0065e7e14af4..2af15b15d1fa 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -829,7 +829,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) return -EINVAL; scp->state = DN_CC; - scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS); + scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk)); dn_send_conn_conf(sk, allocation); prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); @@ -958,7 +958,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, sk->sk_route_caps = sk->sk_dst_cache->dev->features; sock->state = SS_CONNECTING; scp->state = DN_CI; - scp->segsize_loc = dst_metric(sk->sk_dst_cache, RTAX_ADVMSS); + scp->segsize_loc = dst_metric_advmss(sk->sk_dst_cache); dn_nsp_send_conninit(sk, NSP_CI); err = -EINPROGRESS; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index e2e926841fe6..b8a5c0515be8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -110,6 +110,7 @@ static unsigned long dn_rt_deadline; static int dn_dst_gc(struct dst_ops *ops); static struct dst_entry *dn_dst_check(struct dst_entry *, __u32); +static unsigned int dn_dst_default_advmss(const struct dst_entry *dst); static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); static void dn_dst_link_failure(struct sk_buff *); static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); @@ -129,6 +130,7 @@ static struct dst_ops dn_dst_ops = { .gc_thresh = 128, .gc = dn_dst_gc, .check = dn_dst_check, + .default_advmss = dn_dst_default_advmss, .negative_advice = dn_dst_negative_advice, .link_failure = dn_dst_link_failure, .update_pmtu = dn_dst_update_pmtu, @@ -245,7 +247,8 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) } if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; - if (dst_metric(dst, RTAX_ADVMSS) > mss) + u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS); + if (!existing_mss || existing_mss > mss) dst_metric_set(dst, RTAX_ADVMSS, mss); } } @@ -795,12 +798,17 @@ static int dn_rt_bug(struct sk_buff *skb) return NET_RX_DROP; } +static unsigned int dn_dst_default_advmss(const struct dst_entry *dst) +{ + return dn_mss_from_pmtu(dst->dev, dst_mtu(dst)); +} + static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) { struct dn_fib_info *fi = res->fi; struct net_device *dev = rt->dst.dev; struct neighbour *n; - unsigned mss; + unsigned int metric; if (fi) { if (DN_FIB_RES_GW(*res) && @@ -820,10 +828,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) if (dst_metric(&rt->dst, RTAX_MTU) == 0 || dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu); - mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); - if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 || - dst_metric(&rt->dst, RTAX_ADVMSS) > mss) - dst_metric_set(&rt->dst, RTAX_ADVMSS, mss); + metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS); + if (metric) { + unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); + if (metric > mss) + dst_metric_set(&rt->dst, RTAX_ADVMSS, mss); + } return 0; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 770f70427f0b..80997333db0c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -139,6 +139,7 @@ static unsigned long expires_ljiffies; */ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); +static unsigned int ipv4_default_advmss(const struct dst_entry *dst); static void ipv4_dst_destroy(struct dst_entry *dst); static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); @@ -155,6 +156,7 @@ static struct dst_ops ipv4_dst_ops = { .protocol = cpu_to_be16(ETH_P_IP), .gc = rt_garbage_collect, .check = ipv4_dst_check, + .default_advmss = ipv4_default_advmss, .destroy = ipv4_dst_destroy, .ifdown = ipv4_dst_ifdown, .negative_advice = ipv4_negative_advice, @@ -383,8 +385,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) (__force u32)r->rt_gateway, r->rt_flags, atomic_read(&r->dst.__refcnt), r->dst.__use, 0, (__force u32)r->rt_src, - (dst_metric(&r->dst, RTAX_ADVMSS) ? - (int)dst_metric(&r->dst, RTAX_ADVMSS) + 40 : 0), + dst_metric_advmss(&r->dst) + 40, dst_metric(&r->dst, RTAX_WINDOW), (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + dst_metric(&r->dst, RTAX_RTTVAR)), @@ -1798,6 +1799,19 @@ static void set_class_tag(struct rtable *rt, u32 tag) } #endif +static unsigned int ipv4_default_advmss(const struct dst_entry *dst) +{ + unsigned int advmss = dst_metric_raw(dst, RTAX_ADVMSS); + + if (advmss == 0) { + advmss = max_t(unsigned int, dst->dev->mtu - 40, + ip_rt_min_advmss); + if (advmss > 65535 - 40) + advmss = 65535 - 40; + } + return advmss; +} + static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) { struct dst_entry *dst = &rt->dst; @@ -1823,11 +1837,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) if (dst_mtu(dst) > IP_MAX_MTU) dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); - if (dst_metric(dst, RTAX_ADVMSS) == 0) - dst_metric_set(dst, RTAX_ADVMSS, - max_t(unsigned int, dst->dev->mtu - 40, - ip_rt_min_advmss)); - if (dst_metric(dst, RTAX_ADVMSS) > 65535 - 40) + if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40) dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); #ifdef CONFIG_NET_CLS_ROUTE diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4fc3387aa994..f4011027543d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1436,7 +1436,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); - newtp->advmss = dst_metric(dst, RTAX_ADVMSS); + newtp->advmss = dst_metric_advmss(dst); if (tcp_sk(sk)->rx_opt.user_mss && tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 97041f24cd27..2d390669d406 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -119,9 +119,13 @@ static __u16 tcp_advertise_mss(struct sock *sk) struct dst_entry *dst = __sk_dst_get(sk); int mss = tp->advmss; - if (dst && dst_metric(dst, RTAX_ADVMSS) < mss) { - mss = dst_metric(dst, RTAX_ADVMSS); - tp->advmss = mss; + if (dst) { + unsigned int metric = dst_metric_advmss(dst); + + if (metric < mss) { + mss = metric; + tp->advmss = mss; + } } return (__u16)mss; @@ -2422,7 +2426,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, skb_dst_set(skb, dst_clone(dst)); - mss = dst_metric(dst, RTAX_ADVMSS); + mss = dst_metric_advmss(dst); if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) mss = tp->rx_opt.user_mss; @@ -2556,7 +2560,7 @@ static void tcp_connect_init(struct sock *sk) if (!tp->window_clamp) tp->window_clamp = dst_metric(dst, RTAX_WINDOW); - tp->advmss = dst_metric(dst, RTAX_ADVMSS); + tp->advmss = dst_metric_advmss(dst); if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss) tp->advmss = tp->rx_opt.user_mss; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 98796b0dc2b7..d9cb832be529 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -76,6 +76,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); +static unsigned int ip6_default_advmss(const struct dst_entry *dst); static struct dst_entry *ip6_negative_advice(struct dst_entry *); static void ip6_dst_destroy(struct dst_entry *); static void ip6_dst_ifdown(struct dst_entry *, @@ -103,6 +104,7 @@ static struct dst_ops ip6_dst_ops_template = { .gc = ip6_dst_gc, .gc_thresh = 1024, .check = ip6_dst_check, + .default_advmss = ip6_default_advmss, .destroy = ip6_dst_destroy, .ifdown = ip6_dst_ifdown, .negative_advice = ip6_negative_advice, @@ -937,8 +939,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) static int ipv6_get_mtu(struct net_device *dev); -static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu) +static unsigned int ip6_default_advmss(const struct dst_entry *dst) { + struct net_device *dev = dst->dev; + unsigned int mtu = dst_mtu(dst); + struct net *net = dev_net(dev); + mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) @@ -990,7 +996,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, atomic_set(&rt->dst.__refcnt, 1); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); - dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); rt->dst.output = ip6_output; #if 0 /* there's no chance to use these for ndisc */ @@ -1312,8 +1317,6 @@ install_route: if (!dst_mtu(&rt->dst)) dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); - if (!dst_metric(&rt->dst, RTAX_ADVMSS)) - dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); rt->dst.dev = dev; rt->rt6i_idev = idev; rt->rt6i_table = table; @@ -1540,8 +1543,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, nrt->rt6i_nexthop = neigh_clone(neigh); /* Reset pmtu, it may be better */ dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); - dst_metric_set(&nrt->dst, RTAX_ADVMSS, ipv6_advmss(dev_net(neigh->dev), - dst_mtu(&nrt->dst))); if (ip6_ins_rt(nrt)) goto out; @@ -1971,7 +1972,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->rt6i_dev = net->loopback_dev; rt->rt6i_idev = idev; dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); - dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); rt->dst.obsolete = -1; @@ -2041,7 +2041,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) { struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; struct inet6_dev *idev; - struct net *net = dev_net(arg->dev); /* In IPv6 pmtu discovery is not optional, so that RTAX_MTU lock cannot disable it. @@ -2073,7 +2072,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) (dst_mtu(&rt->dst) < arg->mtu && dst_mtu(&rt->dst) == idev->cnf.mtu6))) { dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); - dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, arg->mtu)); } return 0; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fee076891646..20aa95e37359 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1521,7 +1521,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); - newtp->advmss = dst_metric(dst, RTAX_ADVMSS); + newtp->advmss = dst_metric_advmss(dst); tcp_initialize_rcv_mss(newsk); newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6e50ccd8c532..36936c8ae961 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2361,6 +2361,11 @@ static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, return 1; } +static unsigned int xfrm_default_advmss(const struct dst_entry *dst) +{ + return dst_metric_advmss(dst->path); +} + int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) { struct net *net; @@ -2378,6 +2383,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) dst_ops->kmem_cachep = xfrm_dst_cache; if (likely(dst_ops->check == NULL)) dst_ops->check = xfrm_dst_check; + if (likely(dst_ops->default_advmss == NULL)) + dst_ops->default_advmss = xfrm_default_advmss; if (likely(dst_ops->negative_advice == NULL)) dst_ops->negative_advice = xfrm_negative_advice; if (likely(dst_ops->link_failure == NULL)) -- cgit v1.2.3-59-g8ed1b From 4fb33244d17b973f17cbc7cf8b7efd0875950474 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 29 Nov 2010 10:45:16 -0800 Subject: iwlagn: change led compensation for 6005 and 6030 devices For both 6005 and 6030 devices, change the led compensation to 57 Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 808942cc2991..10a536969eb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -511,7 +511,7 @@ static struct iwl_base_params iwl6050_base_params = { .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; -static struct iwl_base_params iwl6000_coex_base_params = { +static struct iwl_base_params iwl6000_g2_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -520,7 +520,7 @@ static struct iwl_base_params iwl6000_coex_base_params = { .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, - .led_compensation = 51, + .led_compensation = 57, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, .adv_thermal_throttle = true, @@ -559,7 +559,7 @@ struct iwl_cfg iwl6005_2agn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_g2_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -575,7 +575,7 @@ struct iwl_cfg iwl6005_2abg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_g2_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, @@ -590,7 +590,7 @@ struct iwl_cfg iwl6005_2bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_g2_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, @@ -605,7 +605,7 @@ struct iwl_cfg iwl6030_2agn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -625,7 +625,7 @@ struct iwl_cfg iwl6030_2abg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -644,7 +644,7 @@ struct iwl_cfg iwl6030_2bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -664,7 +664,7 @@ struct iwl_cfg iwl6030_2bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -683,7 +683,7 @@ struct iwl_cfg iwl1030_bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -703,7 +703,7 @@ struct iwl_cfg iwl1030_bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -833,7 +833,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -852,7 +852,7 @@ struct iwl_cfg iwl130_bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_coex_base_params, + .base_params = &iwl6000_g2_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, -- cgit v1.2.3-59-g8ed1b From a1da077bc36368eb7d6312e7e49260f0a3d92c77 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Thu, 2 Dec 2010 11:02:54 -0800 Subject: iwlwifi: clear dbg_fixed_rate during init This prevent bad fixed_rate keeps crashing uCode in an endless loop. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index f450adc72361..ee123482e1d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2873,6 +2873,8 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; + lq_sta->dbg_fixed_rate = 0; + rs_initialize_lq(priv, conf, sta, lq_sta); } -- cgit v1.2.3-59-g8ed1b From ae0b693c12cc78913085733d28e0e0e6020db6f4 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Thu, 2 Dec 2010 11:02:28 -0800 Subject: iwlagn: check ready in iwlagn_bss_info_changed() In function iwlagn_bss_info_changed(), we need to check if the driver is ready before doing real work. Also, the previously put WARN() is removed because the vif is not guaranteed to be valid. uCode restart routine will clear the vif. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 4865b82355d7..769479eb6ea9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -518,7 +518,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (WARN_ON(!ctx->vif)) { + if (unlikely(!iwl_is_ready(priv))) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + if (unlikely(!ctx->vif)) { + IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); mutex_unlock(&priv->mutex); return; } -- cgit v1.2.3-59-g8ed1b From 9decde95be8a77a16f5668544bee45d41a7ae665 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 13:24:36 -0800 Subject: iwlagn: fix debug variable access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compiler correctly warns: iwl-agn-tx.c: In function ‘iwlagn_tx_status_reply_compressed_ba’: iwl-agn-tx.c:1240: warning: ‘bitmap’ may be used uninitialized in this function Move the debug print to the branch that reads the bitmap, and move the variables too so it's more obvious where they are needed. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 72b1f262796c..24a11b8f73bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1237,7 +1237,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, int i, sh, ack; u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); - u64 bitmap, sent_bitmap; int successes = 0; struct ieee80211_tx_info *info; @@ -1278,6 +1277,8 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", ba_resp->txed, ba_resp->txed_2_done); } else { + u64 bitmap, sent_bitmap; + /* don't use 64-bit values for now */ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; @@ -1298,7 +1299,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, sent_bitmap >>= 1; ++i; } + + IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", + (unsigned long long)bitmap); } + info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; @@ -1313,8 +1318,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, } iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); - IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); - return 0; } -- cgit v1.2.3-59-g8ed1b From 17423ea8776362100b0a9a162cdd4b16b886a4a2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Dec 2010 11:51:39 -0800 Subject: iwlagn: rx antenna diversity For the new 1x1 devices, hw and uCode will support rx antenna diversity, but we need to indicate 1x1 device to AccessPoint to make sure it won't use MIMO. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 8 +++++++- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 +++++++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 3c983e426f25..94521d4417a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -147,7 +147,11 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); + if (priv->cfg->rx_with_siso_diversity) + priv->hw_params.rx_chains_num = 1; + else + priv->hw_params.rx_chains_num = + num_of_ant(priv->cfg->valid_rx_ant); priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; @@ -311,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, .led_mode = IWL_LED_RF_STATE, + .rx_with_siso_diversity = true, }; struct iwl_cfg iwl100_bg_cfg = { @@ -324,6 +329,7 @@ struct iwl_cfg iwl100_bg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .led_mode = IWL_LED_RF_STATE, + .rx_with_siso_diversity = true, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 10a536969eb6..8a789241704f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -182,7 +182,11 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); + if (priv->cfg->rx_with_siso_diversity) + priv->hw_params.rx_chains_num = 1; + else + priv->hw_params.rx_chains_num = + num_of_ant(priv->cfg->valid_rx_ant); priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; @@ -841,6 +845,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .rx_with_siso_diversity = true, }; struct iwl_cfg iwl130_bg_cfg = { @@ -859,6 +864,7 @@ struct iwl_cfg iwl130_bg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .rx_with_siso_diversity = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 568920ac982d..d0b86f5e28c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -364,6 +364,7 @@ struct iwl_ht_params { * @scan_antennas: available antenna for scan operation * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * @adv_pm: advance power management + * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -412,6 +413,7 @@ struct iwl_cfg { u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; enum iwl_led_mode led_mode; const bool adv_pm; + const bool rx_with_siso_diversity; }; /*************************** -- cgit v1.2.3-59-g8ed1b From e7362a0069f8448bb346d65f07d98b319f243e30 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 11:03:44 -0800 Subject: iwlagn: rename enhanced txpower fields Some fields we didn't previously use from the enhanced TX power structure will be needed in the next patch, so rename them to their correct names to be able to use them and change code reading them accordingly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index dbada761624d..7c1be8cc1730 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -460,7 +460,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) * always check for valid entry before process * the information */ - if (!enhanced_txpower->common || enhanced_txpower->reserved) + if (!(enhanced_txpower->flags || enhanced_txpower->channel) || + enhanced_txpower->delta_20_in_40) continue; for (element = 0; element < eeprom_section_count; element++) { diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 583916db46e4..c8566a4f8808 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -136,21 +136,23 @@ struct iwl_eeprom_channel { * Enhanced regulatory tx power portion of eeprom image can be broken down * into individual structures; each one is 8 bytes in size and contain the * following information - * @common: (desc + channel) not used by driver, should _NOT_ be "zero" + * @flags: entry flags + * @channel: channel number * @chain_a_max_pwr: chain a max power in 1/2 dBm * @chain_b_max_pwr: chain b max power in 1/2 dBm * @chain_c_max_pwr: chain c max power in 1/2 dBm - * @reserved: not used, should be "zero" + * @delta_20_in_40: 20-in-40 deltas (hi/lo) * @mimo2_max_pwr: mimo2 max power in 1/2 dBm * @mimo3_max_pwr: mimo3 max power in 1/2 dBm * */ struct iwl_eeprom_enhanced_txpwr { - __le16 common; + u8 flags; + u8 channel; s8 chain_a_max; s8 chain_b_max; s8 chain_c_max; - s8 reserved; + u8 delta_20_in_40; s8 mimo2_max; s8 mimo3_max; } __packed; -- cgit v1.2.3-59-g8ed1b From 8d6748ca73a0caffed4304a47a9cb4cd0aba361e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Dec 2010 09:30:14 -0800 Subject: iwlagn: implement layout-agnostic EEPROM reading The current EEPROM reading code has some layout assumptions that now turned out to be false with some newer versions of the EEPROM. Luckily, we can avoid all such assumptions by using data in the EEPROM itself, so implement using that. However, for risk mitigation purposes, keep the old reading code for current hardware for now. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 + drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++ drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 85 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-eeprom.h | 15 +++++ 6 files changed, 120 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 94521d4417a2..5100c1065bdd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -316,6 +316,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .ht_params = &iwl1000_ht_params, .led_mode = IWL_LED_RF_STATE, .rx_with_siso_diversity = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl100_bg_cfg = { @@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = { .base_params = &iwl1000_base_params, .led_mode = IWL_LED_RF_STATE, .rx_with_siso_diversity = true, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8a789241704f..db70a6bfaa55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -568,6 +568,7 @@ struct iwl_cfg iwl6005_2agn_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6005_2abg_cfg = { @@ -583,6 +584,7 @@ struct iwl_cfg iwl6005_2abg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6005_2bg_cfg = { @@ -598,6 +600,7 @@ struct iwl_cfg iwl6005_2bg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2agn_cfg = { @@ -618,6 +621,7 @@ struct iwl_cfg iwl6030_2agn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2abg_cfg = { @@ -637,6 +641,7 @@ struct iwl_cfg iwl6030_2abg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2bgn_cfg = { @@ -657,6 +662,7 @@ struct iwl_cfg iwl6030_2bgn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2bg_cfg = { @@ -676,6 +682,7 @@ struct iwl_cfg iwl6030_2bg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl1030_bgn_cfg = { @@ -696,6 +703,7 @@ struct iwl_cfg iwl1030_bgn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl1030_bg_cfg = { @@ -715,6 +723,7 @@ struct iwl_cfg iwl1030_bg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; /* @@ -797,6 +806,7 @@ struct iwl_cfg iwl6150_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -846,6 +856,7 @@ struct iwl_cfg iwl130_bgn_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .rx_with_siso_diversity = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl130_bg_cfg = { @@ -865,6 +876,7 @@ struct iwl_cfg iwl130_bg_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .rx_with_siso_diversity = true, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 7c1be8cc1730..cf9194baadac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -433,7 +433,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, /** * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info */ -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv) { int eeprom_section_count = 0; int section, element; @@ -494,3 +494,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) } } } + +static void +iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *txp, + s8 max_txpower_avg) +{ + int ch_idx; + bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; + enum ieee80211_band band; + + band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? + IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; + + for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { + struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; + + /* update matching channel or from common data only */ + if (txp->channel != 0 && ch_info->channel != txp->channel) + continue; + + /* update matching band only */ + if (band != ch_info->band) + continue; + + if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + + if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) + ch_info->ht40_max_power_avg = max_txpower_avg; + } +} + +#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) +#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) +#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) + +static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) +{ + struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + int idx, entries; + __le16 *txp_len; + s8 max_txp_avg, max_txp_avg_halfdbm; + + BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); + + /* the length is in 16-bit words, but we want entries */ + txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); + entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; + + txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + for (idx = 0; idx < entries; idx++) { + txp = &txp_array[idx]; + + /* skip invalid entries */ + if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) + continue; + + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, + &max_txp_avg_halfdbm); + + /* + * Update the user limit values values to the highest + * power supported by any channel + */ + if (max_txp_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txp_avg; + if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; + + iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); + } +} + +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + if (priv->cfg->use_new_eeprom_reading) + iwlcore_eeprom_enhanced_txpower_new(priv); + else + iwlcore_eeprom_enhanced_txpower_old(priv); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index d941910e7ef4..7c8010f7ce56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -568,6 +568,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) case INDIRECT_REGULATORY: offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); break; + case INDIRECT_TXP_LIMIT: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); + break; + case INDIRECT_TXP_LIMIT_SIZE: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); + break; case INDIRECT_CALIBRATION: offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d0b86f5e28c2..b877cbe12c3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -414,6 +414,7 @@ struct iwl_cfg { enum iwl_led_mode led_mode; const bool adv_pm; const bool rx_with_siso_diversity; + const bool use_new_eeprom_reading; /* temporary, remove later */ }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index c8566a4f8808..8994b5b23593 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -129,6 +129,17 @@ struct iwl_eeprom_channel { s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ } __packed; +enum iwl_eeprom_enhanced_txpwr_flags { + IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), + IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), + IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), + IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), + IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), + IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), + IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), +}; + /** * iwl_eeprom_enhanced_txpwr structure * This structure presents the enhanced regulatory tx power limit layout @@ -197,6 +208,8 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_LINK_CALIBRATION (2*0x67) #define EEPROM_LINK_PROCESS_ADJST (2*0x68) #define EEPROM_LINK_OTHERS (2*0x69) +#define EEPROM_LINK_TXP_LIMIT (2*0x6a) +#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) /* agn regulatory - indirect access */ #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ @@ -400,6 +413,8 @@ struct iwl_eeprom_calib_info { #define INDIRECT_CALIBRATION 0x00040000 #define INDIRECT_PROCESS_ADJST 0x00050000 #define INDIRECT_OTHERS 0x00060000 +#define INDIRECT_TXP_LIMIT 0x00070000 +#define INDIRECT_TXP_LIMIT_SIZE 0x00080000 #define INDIRECT_ADDRESS 0x00100000 /* General */ -- cgit v1.2.3-59-g8ed1b From c6fc108776e77e38e099d5b13c4f57a2172c6698 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Dec 2010 12:56:42 -0800 Subject: iwlagn: remove old EEPROM TX power reading This removes the old TX power reading code, it isn't necessary since the new code is able to read all the various EEPROM layouts due to relying on information contained in the EEPROM. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 - drivers/net/wireless/iwlwifi/iwl-6000.c | 12 -- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 264 +------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-eeprom.h | 53 ------ 5 files changed, 1 insertion(+), 331 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5100c1065bdd..94521d4417a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -316,7 +316,6 @@ struct iwl_cfg iwl100_bgn_cfg = { .ht_params = &iwl1000_ht_params, .led_mode = IWL_LED_RF_STATE, .rx_with_siso_diversity = true, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl100_bg_cfg = { @@ -331,7 +330,6 @@ struct iwl_cfg iwl100_bg_cfg = { .base_params = &iwl1000_base_params, .led_mode = IWL_LED_RF_STATE, .rx_with_siso_diversity = true, - .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index db70a6bfaa55..8a789241704f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -568,7 +568,6 @@ struct iwl_cfg iwl6005_2agn_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6005_2abg_cfg = { @@ -584,7 +583,6 @@ struct iwl_cfg iwl6005_2abg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6005_2bg_cfg = { @@ -600,7 +598,6 @@ struct iwl_cfg iwl6005_2bg_cfg = { .need_dc_calib = true, .need_temp_offset_calib = true, .led_mode = IWL_LED_RF_STATE, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2agn_cfg = { @@ -621,7 +618,6 @@ struct iwl_cfg iwl6030_2agn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2abg_cfg = { @@ -641,7 +637,6 @@ struct iwl_cfg iwl6030_2abg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2bgn_cfg = { @@ -662,7 +657,6 @@ struct iwl_cfg iwl6030_2bgn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6030_2bg_cfg = { @@ -682,7 +676,6 @@ struct iwl_cfg iwl6030_2bg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl1030_bgn_cfg = { @@ -703,7 +696,6 @@ struct iwl_cfg iwl1030_bgn_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl1030_bg_cfg = { @@ -723,7 +715,6 @@ struct iwl_cfg iwl1030_bg_cfg = { .adv_pm = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .use_new_eeprom_reading = true, }; /* @@ -806,7 +797,6 @@ struct iwl_cfg iwl6150_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -856,7 +846,6 @@ struct iwl_cfg iwl130_bgn_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .rx_with_siso_diversity = true, - .use_new_eeprom_reading = true, }; struct iwl_cfg iwl130_bg_cfg = { @@ -876,7 +865,6 @@ struct iwl_cfg iwl130_bg_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .rx_with_siso_diversity = true, - .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index cf9194baadac..3ea006d73988 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -75,109 +75,6 @@ #include "iwl-agn.h" #include "iwl-io.h" -/************************** EEPROM BANDS **************************** - * - * The iwl_eeprom_band definitions below provide the mapping from the - * EEPROM contents to the specific channel number supported for each - * band. - * - * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 - * definition below maps to physical channel 42 in the 5.2GHz spectrum. - * The specific geography and calibration information for that channel - * is contained in the eeprom map itself. - * - * During init, we copy the eeprom information and channel map - * information into priv->channel_info_24/52 and priv->channel_map_24/52 - * - * channel_map_24/52 provides the index in the channel_info array for a - * given channel. We have to have two separate maps as there is channel - * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and - * band_2 - * - * A value of 0xff stored in the channel_map indicates that the channel - * is not supported by the hardware at all. - * - * A value of 0xfe in the channel_map indicates that the channel is not - * valid for Tx with the current hardware. This means that - * while the system can tune and receive on a given channel, it may not - * be able to associate or transmit any frames on that - * channel. There is no corresponding channel information for that - * entry. - * - *********************************************************************/ - -/** - * struct iwl_txpwr_section: eeprom section information - * @offset: indirect address into eeprom image - * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section - * @band: band type for the section - * @is_common - true: common section, false: channel section - * @is_cck - true: cck section, false: not cck section - * @is_ht_40 - true: all channel in the section are HT40 channel, - * false: legacy or HT 20 MHz - * ignore if it is common section - * @iwl_eeprom_section_channel: channel array in the section, - * ignore if common section - */ -struct iwl_txpwr_section { - u32 offset; - u8 count; - enum ieee80211_band band; - bool is_common; - bool is_cck; - bool is_ht40; - u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; -}; - -/** - * section 1 - 3 are regulatory tx power apply to all channels based on - * modulation: CCK, OFDM - * Band: 2.4GHz, 5.2GHz - * section 4 - 10 are regulatory tx power apply to specified channels - * For example: - * 1L - Channel 1 Legacy - * 1HT - Channel 1 HT - * (1,+1) - Channel 1 HT40 "_above_" - * - * Section 1: all CCK channels - * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels - * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels - * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT - * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) - * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT - * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) - * Section 8: 2.4 GHz channel: 13L, 13HT - * Section 9: 2.4 GHz channel: 140L, 140HT - * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) - * - */ -static const struct iwl_txpwr_section enhinfo[] = { - { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, - { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, - { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, - { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, - false, false, false, - {1, 1, 2, 2, 10, 10, 11, 11 } }, - { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, - false, false, true, - { 1, 2, 6, 7, 9 } }, - { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, - false, false, false, - { 36, 64, 100, 36, 64, 100 } }, - { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, - false, false, true, - { 36, 60, 100 } }, - { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, - false, false, false, - { 13, 13 } }, - { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, - false, false, false, - { 140, 140 } }, - { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, - false, false, true, - { 132, 44 } }, -}; - /****************************************************************************** * * EEPROM related functions @@ -344,157 +241,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); } -/** - * iwl_update_common_txpower: update channel tx power - * update tx power per band based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_common_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - bool is_ht40 = false; - s8 max_txpower_avg; /* (dBm) */ - - /* it is common section, contain all type (Legacy, HT and HT40) - * based on the element in the section to determine - * is it HT 40 or not - */ - if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) - is_ht40 = true; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching band and update tx power if needed */ - if ((ch_info->band == enhinfo[section].band) && - (ch_info->max_power_avg < max_txpower_avg) && - (!is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = ch_info->curr_txpow = - max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((ch_info->band == enhinfo[section].band) && is_ht40 && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwl_update_channel_txpower: update channel tx power - * update channel tx power based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_channel_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - u8 channel; - s8 max_txpower_avg; /* (dBm) */ - - channel = enhinfo[section].iwl_eeprom_section_channel[element]; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching channel and update tx power if needed */ - if (ch_info->channel == channel) { - if ((ch_info->max_power_avg < max_txpower_avg) && - (!enhinfo[section].is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = max_txpower_avg; - ch_info->curr_txpow = max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((enhinfo[section].is_ht40) && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - break; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info - */ -static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv) -{ - int eeprom_section_count = 0; - int section, element; - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; - u32 offset; - s8 max_txpower_avg; /* (dBm) */ - s8 max_txpower_in_half_dbm; /* (half-dBm) */ - - /* Loop through all the sections - * adjust bands and channel's max tx power - * Set the tx_power_user_lmt to the highest power - * supported by any channels and chains - */ - for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { - eeprom_section_count = enhinfo[section].count; - offset = enhinfo[section].offset; - enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) - iwl_eeprom_query_addr(priv, offset); - - /* - * check for valid entry - - * different version of EEPROM might contain different set - * of enhanced tx power table - * always check for valid entry before process - * the information - */ - if (!(enhanced_txpower->flags || enhanced_txpower->channel) || - enhanced_txpower->delta_20_in_40) - continue; - - for (element = 0; element < eeprom_section_count; element++) { - if (enhinfo[section].is_common) - max_txpower_avg = - iwl_update_common_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - else - max_txpower_avg = - iwl_update_channel_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - - /* Update the tx_power_user_lmt to the highest power - * supported by any channel */ - if (max_txpower_avg > priv->tx_power_user_lmt) - priv->tx_power_user_lmt = max_txpower_avg; - - /* - * Update the tx_power_lmt_in_half_dbm to - * the highest power supported by any channel - */ - if (max_txpower_in_half_dbm > - priv->tx_power_lmt_in_half_dbm) - priv->tx_power_lmt_in_half_dbm = - max_txpower_in_half_dbm; - } - } -} - static void iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, struct iwl_eeprom_enhanced_txpwr *txp, @@ -533,7 +279,7 @@ iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) -static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) { struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; int idx, entries; @@ -569,11 +315,3 @@ static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); } } - -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) -{ - if (priv->cfg->use_new_eeprom_reading) - iwlcore_eeprom_enhanced_txpower_new(priv); - else - iwlcore_eeprom_enhanced_txpower_old(priv); -} diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b877cbe12c3a..d0b86f5e28c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -414,7 +414,6 @@ struct iwl_cfg { enum iwl_led_mode led_mode; const bool adv_pm; const bool rx_with_siso_diversity; - const bool use_new_eeprom_reading; /* temporary, remove later */ }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 8994b5b23593..9e6f31355eee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -231,59 +231,6 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ -/* 6000 and up regulatory tx power - indirect access */ -/* max. elements per section */ -#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8) -#define EEPROM_TXPOWER_COMMON_HT40_INDEX (2) - -/** - * Partition the enhanced tx power portion of eeprom image into - * 10 sections based on band, modulation, frequency and channel - * - * Section 1: all CCK channels - * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40 ) channels - * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels - * Section 4: 2.4 GHz 20MHz channels: 1, 2, 10, 11. Both Legacy and HT - * Section 5: 2.4 GHz 40MHz channels: 1, 2, 6, 7, 9, (_above_) - * Section 6: 5.2 GHz 20MHz channels: 36, 64, 100, both Legacy and HT - * Section 7: 5.2 GHz 40MHz channels: 36, 60, 100 (_above_) - * Section 8: 2.4 GHz channel 13, Both Legacy and HT - * Section 9: 2.4 GHz channel 140, Both Legacy and HT - * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_) - */ -/* 2.4 GHz band: CCK */ -#define EEPROM_LB_CCK_20_COMMON ((0xA8)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */ -/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ -#define EEPROM_LB_OFDM_COMMON ((0xB0)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ -/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ -#define EEPROM_HB_OFDM_COMMON ((0xC8)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ -/* 2.4GHz band channels: - * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */ -#define EEPROM_LB_OFDM_20_BAND ((0xE0)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */ -/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */ -#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */ -/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */ -#define EEPROM_HB_OFDM_20_BAND ((0x148)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */ -/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */ -#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ -/* 2.4 GHz band, channnel 13: Legacy, HT */ -#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ -/* 5.2 GHz band, channnel 140: Legacy, HT */ -#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ -/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */ -#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ - - /* 5050 Specific */ #define EEPROM_5050_TX_POWER_VERSION (4) #define EEPROM_5050_EEPROM_VERSION (0x21E) -- cgit v1.2.3-59-g8ed1b From fb4c32bba1e0941db5972e2b612cbfdf10522a43 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Dec 2010 10:33:34 -0800 Subject: iwlwifi: add new EEPROM debug log type Adding new debug type to log EEPROM related data Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 0b961a353ff6..ebdea3be3ef9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -120,6 +120,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) /* 0x000000F0 - 0x00000010 */ #define IWL_DL_MACDUMP (1 << 4) #define IWL_DL_HCMD_DUMP (1 << 5) +#define IWL_DL_EEPROM (1 << 6) #define IWL_DL_RADIO (1 << 7) /* 0x00000F00 - 0x00000100 */ #define IWL_DL_POWER (1 << 8) @@ -164,6 +165,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) #define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a) +#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) -- cgit v1.2.3-59-g8ed1b From d058ff8b9255b2a15bcb040cc9901baca66dc9c4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Dec 2010 10:33:35 -0800 Subject: iwlwifi: use IWL_DEBUG_EEPROM for EEPROM related info For logging EEPROM related info, instead of using IWL_DEBUG_INFO, use the dedicated logging (IWL_DEBUG_EEPROM) for easier debugging Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 3ea006d73988..77d92b71be81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -203,7 +203,7 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, { s8 max_txpower_avg = 0; /* (dBm) */ - IWL_DEBUG_INFO(priv, "%d - " + IWL_DEBUG_EEPROM(priv, "%d - " "chain_a: %d dB chain_b: %d dB " "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", element, diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 87cd10ff285d..358cfd7e5af1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -147,7 +147,7 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv) u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; int ret = 0; - IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp); + IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); switch (gp) { case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { @@ -354,7 +354,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, */ valid_addr = next_link_addr; next_link_addr = le16_to_cpu(link_value) * sizeof(u16); - IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", + IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n", usedblocks, next_link_addr); if (iwl_read_otp_word(priv, next_link_addr, &link_value)) return -EINVAL; @@ -374,7 +374,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, } while (usedblocks <= priv->cfg->base_params->max_ll_items); /* OTP has no valid blocks */ - IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); + IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n"); return -EINVAL; } @@ -414,7 +414,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) return -ENOENT; /* allocate eeprom */ sz = priv->cfg->base_params->eeprom_size; - IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz); + IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); priv->eeprom = kzalloc(sz, GFP_KERNEL); if (!priv->eeprom) { ret = -ENOMEM; @@ -492,7 +492,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) } } - IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n", + IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) ? "OTP" : "EEPROM", iwl_eeprom_query16(priv, EEPROM_VERSION)); @@ -594,7 +594,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, if (!is_channel_valid(ch_info)) return -1; - IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" + IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" " Ad-Hoc %ssupported\n", ch_info->channel, is_channel_a_band(ch_info) ? @@ -634,11 +634,11 @@ int iwl_init_channel_map(struct iwl_priv *priv) struct iwl_channel_info *ch_info; if (priv->channel_count) { - IWL_DEBUG_INFO(priv, "Channel map already initialized.\n"); + IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n"); return 0; } - IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n"); + IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); priv->channel_count = ARRAY_SIZE(iwl_eeprom_band_1) + @@ -647,7 +647,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) ARRAY_SIZE(iwl_eeprom_band_4) + ARRAY_SIZE(iwl_eeprom_band_5); - IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count); + IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", + priv->channel_count); priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * priv->channel_count, GFP_KERNEL); @@ -686,7 +687,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) IEEE80211_CHAN_NO_HT40; if (!(is_channel_valid(ch_info))) { - IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " + IWL_DEBUG_EEPROM(priv, + "Ch. %d Flags %x [%sGHz] - " "No traffic\n", ch_info->channel, ch_info->flags, @@ -702,7 +704,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; ch_info->min_power = 0; - IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" + IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] " + "%s%s%s%s%s%s(0x%02x %ddBm):" " Ad-Hoc %ssupported\n", ch_info->channel, is_channel_a_band(ch_info) ? -- cgit v1.2.3-59-g8ed1b From 33c68770a8605d84aea35c2cd90009edfc4b161a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Dec 2010 10:33:36 -0800 Subject: iwlagn: More detail tx power logging For enhanced tx power table in EEPROM, add more detail logging to help debugging Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 40 ++++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 77d92b71be81..97906dd442e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -203,15 +203,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, { s8 max_txpower_avg = 0; /* (dBm) */ - IWL_DEBUG_EEPROM(priv, "%d - " - "chain_a: %d dB chain_b: %d dB " - "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", - element, - enhanced_txpower[element].chain_a_max >> 1, - enhanced_txpower[element].chain_b_max >> 1, - enhanced_txpower[element].chain_c_max >> 1, - enhanced_txpower[element].mimo2_max >> 1, - enhanced_txpower[element].mimo3_max >> 1); /* Take the highest tx power from any valid chains */ if ((priv->cfg->valid_tx_ant & ANT_A) && (enhanced_txpower[element].chain_a_max > max_txpower_avg)) @@ -279,6 +270,9 @@ iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) +#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ + ? # x " " : "") + void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) { struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; @@ -293,13 +287,39 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + for (idx = 0; idx < entries; idx++) { txp = &txp_array[idx]; - /* skip invalid entries */ if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) continue; + IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", + (txp->channel && (txp->flags & + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? + "Common " : (txp->channel) ? + "Channel" : "Common", + (txp->channel), + TXP_CHECK_AND_PRINT(VALID), + TXP_CHECK_AND_PRINT(BAND_52G), + TXP_CHECK_AND_PRINT(OFDM), + TXP_CHECK_AND_PRINT(40MHZ), + TXP_CHECK_AND_PRINT(HT_AP), + TXP_CHECK_AND_PRINT(RES1), + TXP_CHECK_AND_PRINT(RES2), + TXP_CHECK_AND_PRINT(COMMON_TYPE), + txp->flags); + IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " + "chain_B: 0X%02x chain_C: 0X%02x\n", + txp->chain_a_max, txp->chain_b_max, + txp->chain_c_max); + IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " + "MIMO3: 0x%02x High 20_on_40: 0x%02x " + "Low 20_on_40: 0x%02x\n", + txp->mimo2_max, txp->mimo3_max, + ((txp->delta_20_in_40 & 0xf0) >> 4), + (txp->delta_20_in_40 & 0x0f)); + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, &max_txp_avg_halfdbm); -- cgit v1.2.3-59-g8ed1b From 50619ac9ba48f5ab0c6bcfa10f5d50e4115cdca8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 7 Dec 2010 08:06:31 -0800 Subject: iwlwifi: do not reload fw if WiMAX own the RF For WiFi/WiMAX combo devices, if WiMAX own the RF, WiFi driver try to access RF and fail. This is the W/A to To avoid WiFi keep reloading firmware and try to access RF again. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-5000.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-6000.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-core.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-prph.h | 2 +- 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8435e5a4e69d..34af9e0cfa43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -593,6 +593,7 @@ struct iwl_cfg iwl5350_agn_cfg = { .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -608,6 +609,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .ht_params = &iwl5000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, }; struct iwl_cfg iwl5150_abg_cfg = { @@ -622,6 +624,7 @@ struct iwl_cfg iwl5150_abg_cfg = { .base_params = &iwl5000_base_params, .need_dc_calib = true, .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8a789241704f..fe5f6d0a6539 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -782,6 +782,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, }; struct iwl_cfg iwl6150_bgn_cfg = { @@ -797,6 +798,7 @@ struct iwl_cfg iwl6150_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .led_mode = IWL_LED_RF_STATE, + .internal_wimax_coex = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -811,6 +813,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .base_params = &iwl6050_base_params, .need_dc_calib = true, .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, }; struct iwl_cfg iwl6000_3agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d62b92518417..06cdc60ff87f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -957,6 +957,22 @@ void iwl_irq_handle_error(struct iwl_priv *priv) /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ + if (priv->cfg->internal_wimax_coex && + (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) & + APMS_CLK_VAL_MRB_FUNC_MODE) || + (iwl_read_prph(priv, APMG_PS_CTRL_REG) & + APMG_PS_CTRL_VAL_RESET_REQ))) { + wake_up_interruptible(&priv->wait_command_queue); + /* + *Keep the restart process from trying to send host + * commands by clearing the INIT status bit + */ + clear_bit(STATUS_READY, &priv->status); + IWL_ERR(priv, "RF is used by WiMAX\n"); + return; + } + IWL_ERR(priv, "Loaded firmware version: %s\n", priv->hw->wiphy->fw_version); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d0b86f5e28c2..f80685ad2674 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -365,6 +365,7 @@ struct iwl_ht_params { * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * @adv_pm: advance power management * @rx_with_siso_diversity: 1x1 device with rx antenna diversity + * @internal_wimax_coex: internal wifi/wimax combo device * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -414,6 +415,7 @@ struct iwl_cfg { enum iwl_led_mode led_mode; const bool adv_pm; const bool rx_with_siso_diversity; + const bool internal_wimax_coex; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 5469655646ae..86f5123bccda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -83,10 +83,10 @@ #define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058) #define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C) +#define APMS_CLK_VAL_MRB_FUNC_MODE (0x00000001) #define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) #define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) - #define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000) #define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) #define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) -- cgit v1.2.3-59-g8ed1b From f21dd005df95e0fc6a578342c61b5333ce2abc2b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Dec 2010 15:34:52 -0800 Subject: iwlwifi: keep track of bt coex enable/disable stage For debugging purpose, keep track of the bt coex enable/disable state. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 5 files changed, 13 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index a358d4334a1a..a6dbd8983dac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -856,6 +856,9 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, if (!iwl_is_alive(priv)) return -EAGAIN; + if (!priv->bt_enable_flag) + return -EINVAL; + /* make request to uCode to retrieve statistics information */ mutex_lock(&priv->mutex); ret = iwl_send_statistics_request(priv, CMD_SYNC, false); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 7c8010f7ce56..4bc82fcf1652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1845,6 +1845,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); } + priv->bt_enable_flag = bt_cmd.flags; if (priv->bt_full_concurrent) memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup, sizeof(iwlagn_concurrent_lookup)); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 06cdc60ff87f..efbde1f1a8bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1223,6 +1223,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) else bt_cmd.flags = BT_COEX_ENABLE; + priv->bt_enable_flag = bt_cmd.flags; IWL_DEBUG_INFO(priv, "BT coex %s\n", (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d36836376e6b..6fe80b5e7a15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1567,6 +1567,13 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, const size_t bufsz = sizeof(buf); ssize_t ret; + if (!priv->bt_enable_flag) { + pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n"); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + return ret; + } + pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n", + priv->bt_enable_flag); pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", priv->bt_full_concurrent ? "full concurrency" : "3-wire"); pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 836f1816b110..8dda67850af4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1468,6 +1468,7 @@ struct iwl_priv { }; /* bt coex */ + u8 bt_enable_flag; u8 bt_status; u8 bt_traffic_load, last_bt_traffic_load; bool bt_ch_announce; -- cgit v1.2.3-59-g8ed1b From 65af8dea26aa89ae4a810bdaa05545a8e670b636 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Dec 2010 07:51:50 -0800 Subject: iwlagn: code clean up to remove duplicate code Multiple devices use almost the same .cfg with minor differences. Use macro and remove the duplication. By doing this, reduce the chance for mistake while modify .cfg parameters Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 65 +++---- drivers/net/wireless/iwlwifi/iwl-5000.c | 89 ++++----- drivers/net/wireless/iwlwifi/iwl-6000.c | 319 ++++++++++---------------------- 3 files changed, 151 insertions(+), 322 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 94521d4417a2..ba78bc8a259f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -276,60 +276,49 @@ static struct iwl_ht_params iwl1000_ht_params = { .use_rts_for_aggregation = true, /* use rts/cts protection */ }; +#define IWL_DEVICE_1000 \ + .fw_name_pre = IWL1000_FW_PRE, \ + .ucode_api_max = IWL1000_UCODE_API_MAX, \ + .ucode_api_min = IWL1000_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .ops = &iwl1000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl1000_base_params, \ + .led_mode = IWL_LED_BLINK + struct iwl_cfg iwl1000_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", - .fw_name_pre = IWL1000_FW_PRE, - .ucode_api_max = IWL1000_UCODE_API_MAX, - .ucode_api_min = IWL1000_UCODE_API_MIN, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .ops = &iwl1000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl1000_base_params, + IWL_DEVICE_1000, .ht_params = &iwl1000_ht_params, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl1000_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", - .fw_name_pre = IWL1000_FW_PRE, - .ucode_api_max = IWL1000_UCODE_API_MAX, - .ucode_api_min = IWL1000_UCODE_API_MIN, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .ops = &iwl1000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl1000_base_params, - .led_mode = IWL_LED_BLINK, + IWL_DEVICE_1000, }; +#define IWL_DEVICE_100 \ + .fw_name_pre = IWL100_FW_PRE, \ + .ucode_api_max = IWL100_UCODE_API_MAX, \ + .ucode_api_min = IWL100_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .ops = &iwl1000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl1000_base_params, \ + .led_mode = IWL_LED_RF_STATE, \ + .rx_with_siso_diversity = true + struct iwl_cfg iwl100_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", - .fw_name_pre = IWL100_FW_PRE, - .ucode_api_max = IWL100_UCODE_API_MAX, - .ucode_api_min = IWL100_UCODE_API_MIN, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .ops = &iwl1000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl1000_base_params, + IWL_DEVICE_100, .ht_params = &iwl1000_ht_params, - .led_mode = IWL_LED_RF_STATE, - .rx_with_siso_diversity = true, }; struct iwl_cfg iwl100_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BG", - .fw_name_pre = IWL100_FW_PRE, - .ucode_api_max = IWL100_UCODE_API_MAX, - .ucode_api_min = IWL100_UCODE_API_MIN, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .ops = &iwl1000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl1000_base_params, - .led_mode = IWL_LED_RF_STATE, - .rx_with_siso_diversity = true, + IWL_DEVICE_100, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 34af9e0cfa43..79ab0a6b1386 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -520,65 +520,44 @@ static struct iwl_ht_params iwl5000_ht_params = { .use_rts_for_aggregation = true, /* use rts/cts protection */ }; +#define IWL_DEVICE_5000 \ + .fw_name_pre = IWL5000_FW_PRE, \ + .ucode_api_max = IWL5000_UCODE_API_MAX, \ + .ucode_api_min = IWL5000_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ + .ops = &iwl5000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl5000_base_params, \ + .led_mode = IWL_LED_BLINK + struct iwl_cfg iwl5300_agn_cfg = { .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .ops = &iwl5000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, + IWL_DEVICE_5000, .ht_params = &iwl5000_ht_params, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_bgn_cfg = { .name = "Intel(R) WiFi Link 5100 BGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, + IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .ops = &iwl5000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_abg_cfg = { .name = "Intel(R) WiFi Link 5100 ABG", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, + IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .ops = &iwl5000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_agn_cfg = { .name = "Intel(R) WiFi Link 5100 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, + IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .ops = &iwl5000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -596,35 +575,29 @@ struct iwl_cfg iwl5350_agn_cfg = { .internal_wimax_coex = true, }; +#define IWL_DEVICE_5150 \ + .fw_name_pre = IWL5150_FW_PRE, \ + .ucode_api_max = IWL5150_UCODE_API_MAX, \ + .ucode_api_min = IWL5150_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ + .ops = &iwl5150_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl5000_base_params, \ + .need_dc_calib = true, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + struct iwl_cfg iwl5150_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", - .fw_name_pre = IWL5150_FW_PRE, - .ucode_api_max = IWL5150_UCODE_API_MAX, - .ucode_api_min = IWL5150_UCODE_API_MIN, - .eeprom_ver = EEPROM_5050_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .ops = &iwl5150_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, + IWL_DEVICE_5150, .ht_params = &iwl5000_ht_params, - .need_dc_calib = true, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, + }; struct iwl_cfg iwl5150_abg_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", - .fw_name_pre = IWL5150_FW_PRE, - .ucode_api_max = IWL5150_UCODE_API_MAX, - .ucode_api_min = IWL5150_UCODE_API_MIN, - .eeprom_ver = EEPROM_5050_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .ops = &iwl5150_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl5000_base_params, - .need_dc_calib = true, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, + IWL_DEVICE_5150, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index fe5f6d0a6539..f4bec3201ef9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -554,235 +554,156 @@ static struct iwl_bt_params iwl6000_bt_params = { .bt_sco_disable = true, }; +#define IWL_DEVICE_6005 \ + .fw_name_pre = IWL6000G2A_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ + .ops = &iwl6000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl6000_g2_base_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE + struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, + IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6005_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, + IWL_DEVICE_6005, }; struct iwl_cfg iwl6005_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, -}; + IWL_DEVICE_6005, +}; + +#define IWL_DEVICE_6030 \ + .fw_name_pre = IWL6000G2B_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ + .ops = &iwl6000g2b_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + /* \ + *Due to bluetooth, we transmit 2.4 GHz probes \ + * only on antenna A \ + */ \ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, + IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6030_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + IWL_DEVICE_6030, }; struct iwl_cfg iwl6030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, + IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6030_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + IWL_DEVICE_6030, }; struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, + IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl1030_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, - .need_dc_calib = true, - .need_temp_offset_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + IWL_DEVICE_6030, +}; + +struct iwl_cfg iwl130_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, + .rx_with_siso_diversity = true, +}; + +struct iwl_cfg iwl130_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BG", + IWL_DEVICE_6030, + .rx_with_siso_diversity = true, }; /* * "i": Internal configuration, use internal Power Amplifier */ +#define IWL_DEVICE_6000i \ + .fw_name_pre = IWL6000_FW_PRE, \ + .ucode_api_max = IWL6000_UCODE_API_MAX, \ + .ucode_api_min = IWL6000_UCODE_API_MIN, \ + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ + .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ + .ops = &iwl6000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl6000_base_params, \ + .pa_type = IWL_PA_INTERNAL, \ + .led_mode = IWL_LED_BLINK + struct iwl_cfg iwl6000i_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", - .fw_name_pre = IWL6000_FW_PRE, - .ucode_api_max = IWL6000_UCODE_API_MAX, - .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, /* .cfg overwrite */ - .valid_rx_ant = ANT_BC, /* .cfg overwrite */ - .eeprom_ver = EEPROM_6000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + IWL_DEVICE_6000i, .ht_params = &iwl6000_ht_params, - .pa_type = IWL_PA_INTERNAL, - .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000i_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", - .fw_name_pre = IWL6000_FW_PRE, - .ucode_api_max = IWL6000_UCODE_API_MAX, - .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, /* .cfg overwrite */ - .valid_rx_ant = ANT_BC, /* .cfg overwrite */ - .eeprom_ver = EEPROM_6000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, - .pa_type = IWL_PA_INTERNAL, - .led_mode = IWL_LED_BLINK, + IWL_DEVICE_6000i, }; struct iwl_cfg iwl6000i_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", - .fw_name_pre = IWL6000_FW_PRE, - .ucode_api_max = IWL6000_UCODE_API_MAX, - .ucode_api_min = IWL6000_UCODE_API_MIN, - .valid_tx_ant = ANT_BC, /* .cfg overwrite */ - .valid_rx_ant = ANT_BC, /* .cfg overwrite */ - .eeprom_ver = EEPROM_6000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .ops = &iwl6000_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, - .pa_type = IWL_PA_INTERNAL, - .led_mode = IWL_LED_BLINK, -}; + IWL_DEVICE_6000i, +}; + +#define IWL_DEVICE_6050 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .ops = &iwl6050_ops, \ + .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl6050_base_params, \ + .need_dc_calib = true, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true struct iwl_cfg iwl6050_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", - .fw_name_pre = IWL6050_FW_PRE, - .ucode_api_max = IWL6050_UCODE_API_MAX, - .ucode_api_min = IWL6050_UCODE_API_MIN, - .ops = &iwl6050_ops, - .eeprom_ver = EEPROM_6050_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6050_base_params, + IWL_DEVICE_6050, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, +}; + +struct iwl_cfg iwl6050_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", + IWL_DEVICE_6050, }; struct iwl_cfg iwl6150_bgn_cfg = { @@ -801,21 +722,6 @@ struct iwl_cfg iwl6150_bgn_cfg = { .internal_wimax_coex = true, }; -struct iwl_cfg iwl6050_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", - .fw_name_pre = IWL6050_FW_PRE, - .ucode_api_max = IWL6050_UCODE_API_MAX, - .ucode_api_min = IWL6050_UCODE_API_MIN, - .eeprom_ver = EEPROM_6050_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .ops = &iwl6050_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6050_base_params, - .need_dc_calib = true, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, -}; - struct iwl_cfg iwl6000_3agn_cfg = { .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", .fw_name_pre = IWL6000_FW_PRE, @@ -831,45 +737,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { .led_mode = IWL_LED_BLINK, }; -struct iwl_cfg iwl130_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, - .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .rx_with_siso_diversity = true, -}; - -struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BG", - .fw_name_pre = IWL6000G2B_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .ops = &iwl6000g2b_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_g2_base_params, - .bt_params = &iwl6000_bt_params, - .need_dc_calib = true, - .led_mode = IWL_LED_RF_STATE, - .adv_pm = true, - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .rx_with_siso_diversity = true, -}; - MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -- cgit v1.2.3-59-g8ed1b From d33e455337ea2c71d09d7f4367d6ad6dd32b6965 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 14 Dec 2010 13:01:14 -0800 Subject: net: Abstract default MTU metric calculation behind an accessor. Like RTAX_ADVMSS, make the default calculation go through a dst_ops method rather than caching the computation in the routing cache entries. Now dst metrics are pretty much left as-is when new entries are created, thus optimizing metric sharing becomes a real possibility. Signed-off-by: David S. Miller --- include/net/dst.h | 15 ++++++++------- include/net/dst_ops.h | 1 + net/decnet/dn_route.c | 10 ++++++++-- net/ipv4/route.c | 29 ++++++++++++++++++++--------- net/ipv6/route.c | 37 ++++++++++++++++--------------------- net/xfrm/xfrm_policy.c | 7 +++++++ 6 files changed, 60 insertions(+), 39 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 03a1c3d52d80..93b0310317be 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -113,7 +113,8 @@ static inline u32 dst_metric(const struct dst_entry *dst, const int metric) { WARN_ON_ONCE(metric == RTAX_HOPLIMIT || - metric == RTAX_ADVMSS); + metric == RTAX_ADVMSS || + metric == RTAX_MTU); return dst_metric_raw(dst, metric); } @@ -156,11 +157,11 @@ dst_feature(const struct dst_entry *dst, u32 feature) static inline u32 dst_mtu(const struct dst_entry *dst) { - u32 mtu = dst_metric(dst, RTAX_MTU); - /* - * Alexey put it here, so ask him about it :) - */ - barrier(); + u32 mtu = dst_metric_raw(dst, RTAX_MTU); + + if (!mtu) + mtu = dst->ops->default_mtu(dst); + return mtu; } @@ -186,7 +187,7 @@ dst_allfrag(const struct dst_entry *dst) } static inline int -dst_metric_locked(struct dst_entry *dst, int metric) +dst_metric_locked(const struct dst_entry *dst, int metric) { return dst_metric(dst, RTAX_LOCK) & (1<dev, dst_mtu(dst)); } +static unsigned int dn_dst_default_mtu(const struct dst_entry *dst) +{ + return dst->dev->mtu; +} + static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) { struct dn_fib_info *fi = res->fi; @@ -825,8 +832,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) rt->dst.neighbour = n; } - if (dst_metric(&rt->dst, RTAX_MTU) == 0 || - dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) + if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu); metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS); if (metric) { diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80997333db0c..ae520963540f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -140,6 +140,7 @@ static unsigned long expires_ljiffies; static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ipv4_default_advmss(const struct dst_entry *dst); +static unsigned int ipv4_default_mtu(const struct dst_entry *dst); static void ipv4_dst_destroy(struct dst_entry *dst); static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); @@ -157,6 +158,7 @@ static struct dst_ops ipv4_dst_ops = { .gc = rt_garbage_collect, .check = ipv4_dst_check, .default_advmss = ipv4_default_advmss, + .default_mtu = ipv4_default_mtu, .destroy = ipv4_dst_destroy, .ifdown = ipv4_dst_ifdown, .negative_advice = ipv4_negative_advice, @@ -1812,6 +1814,23 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst) return advmss; } +static unsigned int ipv4_default_mtu(const struct dst_entry *dst) +{ + unsigned int mtu = dst->dev->mtu; + + if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { + const struct rtable *rt = (const struct rtable *) dst; + + if (rt->rt_gateway != rt->rt_dst && mtu > 576) + mtu = 576; + } + + if (mtu > IP_MAX_MTU) + mtu = IP_MAX_MTU; + + return mtu; +} + static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) { struct dst_entry *dst = &rt->dst; @@ -1822,18 +1841,10 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) rt->rt_gateway = FIB_RES_GW(*res); dst_import_metrics(dst, fi->fib_metrics); - if (fi->fib_mtu == 0) { - dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); - if (dst_metric_locked(dst, RTAX_MTU) && - rt->rt_gateway != rt->rt_dst && - dst->dev->mtu > 576) - dst_metric_set(dst, RTAX_MTU, 576); - } #ifdef CONFIG_NET_CLS_ROUTE dst->tclassid = FIB_RES_NH(*res).nh_tclassid; #endif - } else - dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); + } if (dst_mtu(dst) > IP_MAX_MTU) dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d9cb832be529..e7efb269a6e9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -77,6 +77,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); +static unsigned int ip6_default_mtu(const struct dst_entry *dst); static struct dst_entry *ip6_negative_advice(struct dst_entry *); static void ip6_dst_destroy(struct dst_entry *); static void ip6_dst_ifdown(struct dst_entry *, @@ -105,6 +106,7 @@ static struct dst_ops ip6_dst_ops_template = { .gc_thresh = 1024, .check = ip6_dst_check, .default_advmss = ip6_default_advmss, + .default_mtu = ip6_default_mtu, .destroy = ip6_dst_destroy, .ifdown = ip6_dst_ifdown, .negative_advice = ip6_negative_advice, @@ -937,8 +939,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } } -static int ipv6_get_mtu(struct net_device *dev); - static unsigned int ip6_default_advmss(const struct dst_entry *dst) { struct net_device *dev = dst->dev; @@ -961,6 +961,20 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) return mtu; } +static unsigned int ip6_default_mtu(const struct dst_entry *dst) +{ + unsigned int mtu = IPV6_MIN_MTU; + struct inet6_dev *idev; + + rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + if (idev) + mtu = idev->cnf.mtu6; + rcu_read_unlock(); + + return mtu; +} + static struct dst_entry *icmp6_dst_gc_list; static DEFINE_SPINLOCK(icmp6_dst_lock); @@ -995,7 +1009,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_nexthop = neigh; atomic_set(&rt->dst.__refcnt, 1); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); rt->dst.output = ip6_output; #if 0 /* there's no chance to use these for ndisc */ @@ -1094,19 +1107,6 @@ out: Remove it only when all the things will work! */ -static int ipv6_get_mtu(struct net_device *dev) -{ - int mtu = IPV6_MIN_MTU; - struct inet6_dev *idev; - - rcu_read_lock(); - idev = __in6_dev_get(dev); - if (idev) - mtu = idev->cnf.mtu6; - rcu_read_unlock(); - return mtu; -} - int ip6_dst_hoplimit(struct dst_entry *dst) { int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); @@ -1315,8 +1315,6 @@ install_route: } } - if (!dst_mtu(&rt->dst)) - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); rt->dst.dev = dev; rt->rt6i_idev = idev; rt->rt6i_table = table; @@ -1541,8 +1539,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); nrt->rt6i_nexthop = neigh_clone(neigh); - /* Reset pmtu, it may be better */ - dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); if (ip6_ins_rt(nrt)) goto out; @@ -1971,7 +1967,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->dst.output = ip6_output; rt->rt6i_dev = net->loopback_dev; rt->rt6i_idev = idev; - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); rt->dst.obsolete = -1; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 36936c8ae961..8b3ef404c794 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2366,6 +2366,11 @@ static unsigned int xfrm_default_advmss(const struct dst_entry *dst) return dst_metric_advmss(dst->path); } +static unsigned int xfrm_default_mtu(const struct dst_entry *dst) +{ + return dst_mtu(dst->path); +} + int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) { struct net *net; @@ -2385,6 +2390,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) dst_ops->check = xfrm_dst_check; if (likely(dst_ops->default_advmss == NULL)) dst_ops->default_advmss = xfrm_default_advmss; + if (likely(dst_ops->default_mtu == NULL)) + dst_ops->default_mtu = xfrm_default_mtu; if (likely(dst_ops->negative_advice == NULL)) dst_ops->negative_advice = xfrm_negative_advice; if (likely(dst_ops->link_failure == NULL)) -- cgit v1.2.3-59-g8ed1b From fb6a6819fad0d71b47577a51709440a9f8441f0a Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 3 Dec 2010 17:05:40 +0200 Subject: wl12xx: disable 11a channels when wl->enable_11a is known Disabling the 11a channels when not supported in the reg_notify function was not working as it should, because when the driver is initiailizing (and registering itself with mac80211), it would get the reg notification too early. At that point the driver wouldn't have received the NVS yet, so it wouldn't know whether 11a was supported. To fix this, we disable 11a channels when we read the NVS instead. Also, it is easier (and still safe) to set n_channels to zero instead of setting the disabled flag on every 11a channel. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index dc3a09319d12..0b79c49cd877 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -338,7 +338,6 @@ out: static int wl1271_reg_notify(struct wiphy *wiphy, struct regulatory_request *request) { - struct wl1271 *wl = wiphy_to_ieee80211_hw(wiphy)->priv; struct ieee80211_supported_band *band; struct ieee80211_channel *ch; int i; @@ -349,11 +348,6 @@ static int wl1271_reg_notify(struct wiphy *wiphy, if (ch->flags & IEEE80211_CHAN_DISABLED) continue; - if (!wl->enable_11a) { - ch->flags |= IEEE80211_CHAN_DISABLED; - continue; - } - if (ch->flags & IEEE80211_CHAN_RADAR) ch->flags |= IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; @@ -1071,6 +1065,16 @@ power_off: strncpy(wiphy->fw_version, wl->chip.fw_ver, sizeof(wiphy->fw_version)); + /* + * Now we know if 11a is supported (info from the NVS), so disable + * 11a channels if not supported + */ + if (!wl->enable_11a) + wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels = 0; + + wl1271_debug(DEBUG_MAC80211, "11a is %ssupported", + wl->enable_11a ? "" : "not "); + out: mutex_unlock(&wl->mutex); -- cgit v1.2.3-59-g8ed1b From b69eb80bf7a6922fef8056d42b06124a7de31501 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 1 Dec 2010 11:58:54 +0200 Subject: wl1271_sdio_test: Add module for sdio RX/TX testing This module enables individually generating RX and TX traffic over the SDIO bus on which the WL1271 chipset is connected. This is required to perform RF interference testing. The module takes 2 module parameters 'rx' and 'tx'. To generate RX traffic: modprobe wl1271_sdio_test rx=1 To generate TX traffic: modprobe wl1271_sdio_test tx=1 To generate both RX & TX traffic, set both rx and tx to 1. You can change the testing configuration at runtime by changing the rx & tx values at /sys/modules/wl1271_sdio_test/ To stop testing simply unload the module. Signed-off-by: Roger Quadros Reviewed-by: Carlos Chinea Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 8 + drivers/net/wireless/wl12xx/Makefile | 2 + drivers/net/wireless/wl12xx/wl1271_sdio_test.c | 510 +++++++++++++++++++++++++ 3 files changed, 520 insertions(+) create mode 100644 drivers/net/wireless/wl12xx/wl1271_sdio_test.c diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index d2adeb1f72b7..085bc44d814b 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -52,6 +52,14 @@ config WL12XX_SDIO If you choose to build a module, it'll be called wl12xx_sdio. Say N if unsure. +config WL1271_SDIO_TEST + tristate "TI wl1271 SDIO testing support" + depends on WL1271 && MMC + ---help--- + This module adds support for the SDIO bus testing with the + TI wl1271 chipset. Select this if your platform is using + the SDIO bus. + config WL12XX_PLATFORM_DATA bool depends on WL12XX_SDIO != n || WL1251_SDIO != n diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 005a758174d9..187678503887 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -9,5 +9,7 @@ obj-$(CONFIG_WL12XX) += wl12xx.o obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o +obj-$(CONFIG_WL1271_SDIO_TEST) += wl1271_sdio_test.o + # small builtin driver bit obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio_test.c b/drivers/net/wireless/wl12xx/wl1271_sdio_test.c new file mode 100644 index 000000000000..42d13144f645 --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl1271_sdio_test.c @@ -0,0 +1,510 @@ +/* + * wl1271_sdio_test.c - SDIO testing driver for wl1271 + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Roger Quadros + * + * wl1271 read/write routines taken from wl1271_sdio.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wl1271.h" +#include "wl1271_io.h" +#include "wl1271_boot.h" + +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI 0x0097 +#endif + +#ifndef SDIO_DEVICE_ID_TI_WL1271 +#define SDIO_DEVICE_ID_TI_WL1271 0x4076 +#endif + +static bool rx, tx; + +module_param(rx, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(rx, "Perform rx test. Default (0). " + "This test continuously reads data from the SDIO device.\n"); + +module_param(tx, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(tx, "Perform tx test. Default (0). " + "This test continuously writes data to the SDIO device.\n"); + +struct wl1271_test { + struct wl1271 wl; + struct task_struct *test_task; +}; + +static const struct sdio_device_id wl1271_devices[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, + {} +}; + +static inline struct sdio_func *wl_to_func(struct wl1271 *wl) +{ + return wl->if_priv; +} + +static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) +{ + return &(wl_to_func(wl)->dev); +} + +static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret = 0; + struct sdio_func *func = wl_to_func(wl); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + if (fixed) + ret = sdio_readsb(func, buf, addr, len); + else + ret = sdio_memcpy_fromio(func, buf, addr, len); + + wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + } + + if (ret) + wl1271_error("sdio read failed (%d)", ret); +} + +static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret = 0; + struct sdio_func *func = wl_to_func(wl); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + + if (fixed) + ret = sdio_writesb(func, addr, buf, len); + else + ret = sdio_memcpy_toio(func, addr, buf, len); + } + if (ret) + wl1271_error("sdio write failed (%d)", ret); + +} + +static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +{ + struct sdio_func *func = wl_to_func(wl); + + /* Let the SDIO stack handle wlan_enable control, so we + * keep host claimed while wlan is in use to keep wl1271 + * alive. + */ + if (enable) { + sdio_claim_power(func); + sdio_claim_host(func); + sdio_enable_func(func); + } else { + sdio_disable_func(func); + sdio_release_host(func); + sdio_release_power(func); + } + + return 0; +} + +static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) +{ +} + +static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) +{ +} + + +static struct wl1271_if_operations sdio_ops = { + .read = wl1271_sdio_raw_read, + .write = wl1271_sdio_raw_write, + .power = wl1271_sdio_set_power, + .dev = wl1271_sdio_wl_to_dev, + .enable_irq = wl1271_sdio_enable_interrupts, + .disable_irq = wl1271_sdio_disable_interrupts, +}; + +static void wl1271_fw_wakeup(struct wl1271 *wl) +{ + u32 elp_reg; + + elp_reg = ELPCTRL_WAKE_UP; + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); +} + +static int wl1271_fetch_firmware(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get firmware: %d", ret); + return ret; + } + + if (fw->size % 4) { + wl1271_error("firmware size is not multiple of 32 bits: %zu", + fw->size); + ret = -EILSEQ; + goto out; + } + + wl->fw_len = fw->size; + wl->fw = vmalloc(wl->fw_len); + + if (!wl->fw) { + wl1271_error("could not allocate memory for the firmware"); + ret = -ENOMEM; + goto out; + } + + memcpy(wl->fw, fw->data, wl->fw_len); + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1271_fetch_nvs(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get nvs file: %d", ret); + return ret; + } + + wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); + + if (!wl->nvs) { + wl1271_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; + goto out; + } + + wl->nvs_len = fw->size; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1271_chip_wakeup(struct wl1271 *wl) +{ + struct wl1271_partition_set partition; + int ret; + + msleep(WL1271_PRE_POWER_ON_SLEEP); + ret = wl1271_power_on(wl); + if (ret) + return ret; + + msleep(WL1271_POWER_ON_SLEEP); + + /* We don't need a real memory partition here, because we only want + * to use the registers at this point. */ + memset(&partition, 0, sizeof(partition)); + partition.reg.start = REGISTERS_BASE; + partition.reg.size = REGISTERS_DOWN_SIZE; + wl1271_set_partition(wl, &partition); + + /* ELP module wake up */ + wl1271_fw_wakeup(wl); + + /* whal_FwCtrl_BootSm() */ + + /* 0. read chip id from CHIP_ID */ + wl->chip.id = wl1271_read32(wl, CHIP_ID_B); + + /* 1. check if chip id is valid */ + + switch (wl->chip.id) { + case CHIP_ID_1271_PG10: + wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", + wl->chip.id); + break; + case CHIP_ID_1271_PG20: + wl1271_notice("chip id 0x%x (1271 PG20)", + wl->chip.id); + break; + default: + wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); + return -ENODEV; + } + + return ret; +} + +static struct wl1271_partition_set part_down = { + .mem = { + .start = 0x00000000, + .size = 0x000177c0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x00008800 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + }, +}; + +static int tester(void *data) +{ + struct wl1271 *wl = data; + struct sdio_func *func = wl_to_func(wl); + struct device *pdev = &func->dev; + int ret = 0; + bool rx_started = 0; + bool tx_started = 0; + uint8_t *tx_buf, *rx_buf; + int test_size = PAGE_SIZE; + u32 addr = 0; + struct wl1271_partition_set partition; + + /* We assume chip is powered up and firmware fetched */ + + memcpy(&partition, &part_down, sizeof(partition)); + partition.mem.start = addr; + wl1271_set_partition(wl, &partition); + + tx_buf = kmalloc(test_size, GFP_KERNEL); + rx_buf = kmalloc(test_size, GFP_KERNEL); + if (!tx_buf || !rx_buf) { + dev_err(pdev, + "Could not allocate memory. Test will not run.\n"); + ret = -ENOMEM; + goto free; + } + + memset(tx_buf, 0x5a, test_size); + + /* write something in data area so we can read it back */ + wl1271_write(wl, addr, tx_buf, test_size, false); + + while (!kthread_should_stop()) { + if (rx && !rx_started) { + dev_info(pdev, "starting rx test\n"); + rx_started = 1; + } else if (!rx && rx_started) { + dev_info(pdev, "stopping rx test\n"); + rx_started = 0; + } + + if (tx && !tx_started) { + dev_info(pdev, "starting tx test\n"); + tx_started = 1; + } else if (!tx && tx_started) { + dev_info(pdev, "stopping tx test\n"); + tx_started = 0; + } + + if (rx_started) + wl1271_read(wl, addr, rx_buf, test_size, false); + + if (tx_started) + wl1271_write(wl, addr, tx_buf, test_size, false); + + if (!rx_started && !tx_started) + msleep(100); + } + +free: + kfree(tx_buf); + kfree(rx_buf); + return ret; +} + +static int __devinit wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + const struct wl12xx_platform_data *wlan_data; + struct wl1271 *wl; + struct wl1271_test *wl_test; + int ret = 0; + + /* wl1271 has 2 sdio functions we handle just the wlan part */ + if (func->num != 0x02) + return -ENODEV; + + wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL); + if (!wl_test) { + dev_err(&func->dev, "Could not allocate memory\n"); + return -ENOMEM; + } + + wl = &wl_test->wl; + + wl->if_priv = func; + wl->if_ops = &sdio_ops; + + /* Grab access to FN0 for ELP reg. */ + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + + wlan_data = wl12xx_get_platform_data(); + if (IS_ERR(wlan_data)) { + ret = PTR_ERR(wlan_data); + dev_err(&func->dev, "missing wlan platform data: %d\n", ret); + goto out_free; + } + + wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; + + sdio_set_drvdata(func, wl_test); + + + /* power up the device */ + ret = wl1271_chip_wakeup(wl); + if (ret) { + dev_err(&func->dev, "could not wake up chip\n"); + goto out_free; + } + + if (wl->fw == NULL) { + ret = wl1271_fetch_firmware(wl); + if (ret < 0) { + dev_err(&func->dev, "firmware fetch error\n"); + goto out_off; + } + } + + /* fetch NVS */ + if (wl->nvs == NULL) { + ret = wl1271_fetch_nvs(wl); + if (ret < 0) { + dev_err(&func->dev, "NVS fetch error\n"); + goto out_off; + } + } + + ret = wl1271_load_firmware(wl); + if (ret < 0) { + dev_err(&func->dev, "firmware load error: %d\n", ret); + goto out_free; + } + + dev_info(&func->dev, "initialized\n"); + + /* I/O testing will be done in the tester thread */ + + wl_test->test_task = kthread_run(tester, wl, "sdio_tester"); + if (IS_ERR(wl_test->test_task)) { + dev_err(&func->dev, "unable to create kernel thread\n"); + ret = PTR_ERR(wl_test->test_task); + goto out_free; + } + + return 0; + +out_off: + /* power off the chip */ + wl1271_power_off(wl); + +out_free: + kfree(wl_test); + return ret; +} + +static void __devexit wl1271_remove(struct sdio_func *func) +{ + struct wl1271_test *wl_test = sdio_get_drvdata(func); + + /* stop the I/O test thread */ + kthread_stop(wl_test->test_task); + + /* power off the chip */ + wl1271_power_off(&wl_test->wl); + + vfree(wl_test->wl.fw); + wl_test->wl.fw = NULL; + kfree(wl_test->wl.nvs); + wl_test->wl.nvs = NULL; + + kfree(wl_test); +} + +static struct sdio_driver wl1271_sdio_driver = { + .name = "wl1271_sdio_test", + .id_table = wl1271_devices, + .probe = wl1271_probe, + .remove = __devexit_p(wl1271_remove), +}; + +static int __init wl1271_init(void) +{ + int ret; + + ret = sdio_register_driver(&wl1271_sdio_driver); + if (ret < 0) + pr_err("failed to register sdio driver: %d\n", ret); + + return ret; +} +module_init(wl1271_init); + +static void __exit wl1271_exit(void) +{ + sdio_unregister_driver(&wl1271_sdio_driver); +} +module_exit(wl1271_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Roger Quadros "); + -- cgit v1.2.3-59-g8ed1b From c5312772156bb5f9b2e95e4c91526d578426a069 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 9 Dec 2010 11:31:27 +0200 Subject: wl12xx: add auto-arp support The auto-arp feature of wl12xx allows the firmware to automatically response to arp requests asking for its ip. in order to use it, we configure the arp response template and enable the corresponding bit in wl1271_acx_arp_filter (along with passing its ip) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 4 +-- drivers/net/wireless/wl12xx/acx.h | 9 +++++-- drivers/net/wireless/wl12xx/cmd.c | 41 ++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/cmd.h | 2 ++ drivers/net/wireless/wl12xx/init.c | 7 +++++ drivers/net/wireless/wl12xx/main.c | 24 ++++++++++++++--- drivers/net/wireless/wl12xx/wl12xx_80211.h | 14 ++++++++++ 7 files changed, 93 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 7cbaeb6d2a37..cc4068d2b4a8 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1041,7 +1041,7 @@ out: return ret; } -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address) { struct wl1271_acx_arp_filter *acx; int ret; @@ -1057,7 +1057,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) acx->version = ACX_IPV4_VERSION; acx->enable = enable; - if (enable == true) + if (enable) memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 75a6306ff554..9cbc3f40c8dd 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -868,10 +868,15 @@ struct wl1271_acx_bet_enable { #define ACX_IPV4_VERSION 4 #define ACX_IPV6_VERSION 6 #define ACX_IPV4_ADDR_SIZE 4 + +/* bitmap of enabled arp_filter features */ +#define ACX_ARP_FILTER_ARP_FILTERING BIT(0) +#define ACX_ARP_FILTER_AUTO_ARP BIT(1) + struct wl1271_acx_arp_filter { struct acx_header header; u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */ - u8 enable; /* 1 to enable ARP filtering, 0 to disable */ + u8 enable; /* bitmap of enabled ARP filtering features */ u8 padding[2]; u8 address[16]; /* The configured device IP address - all ARP requests directed to this IP address will pass @@ -1168,7 +1173,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl); int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); int wl1271_acx_smart_reflex(struct wl1271 *wl); int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address); int wl1271_acx_pm_config(struct wl1271 *wl); int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 8e438e27e496..0106628aa5a2 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -639,6 +639,47 @@ out: return skb; } +int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr) +{ + int ret; + struct wl12xx_arp_rsp_template tmpl; + struct ieee80211_hdr_3addr *hdr; + struct arphdr *arp_hdr; + + memset(&tmpl, 0, sizeof(tmpl)); + + /* mac80211 header */ + hdr = &tmpl.hdr; + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_DATA | + IEEE80211_FCTL_TODS); + memcpy(hdr->addr1, wl->vif->bss_conf.bssid, ETH_ALEN); + memcpy(hdr->addr2, wl->vif->addr, ETH_ALEN); + memset(hdr->addr3, 0xff, ETH_ALEN); + + /* llc layer */ + memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header)); + tmpl.llc_type = htons(ETH_P_ARP); + + /* arp header */ + arp_hdr = &tmpl.arp_hdr; + arp_hdr->ar_hrd = htons(ARPHRD_ETHER); + arp_hdr->ar_pro = htons(ETH_P_IP); + arp_hdr->ar_hln = ETH_ALEN; + arp_hdr->ar_pln = 4; + arp_hdr->ar_op = htons(ARPOP_REPLY); + + /* arp payload */ + memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN); + tmpl.sender_ip = ip_addr; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, + &tmpl, sizeof(tmpl), 0, + wl->basic_rate); + + return ret; +} + int wl1271_build_qos_null_data(struct wl1271 *wl) { struct ieee80211_qos_hdr template; diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 111d112544fc..2a1d9db7ceb8 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -51,6 +51,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, const u8 *ie, size_t ie_len, u8 band); struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, struct sk_buff *skb); +int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr); int wl1271_build_qos_null_data(struct wl1271 *wl); int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); @@ -124,6 +125,7 @@ enum cmd_templ { CMD_TEMPL_CTS, /* * For CTS-to-self (FastCTS) mechanism * for BT/WLAN coexistence (SoftGemini). */ + CMD_TEMPL_ARP_RSP, CMD_TEMPL_MAX = 0xff }; diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 7949d346aadb..0392e37f0d66 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -102,6 +102,13 @@ int wl1271_init_templates_config(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL, + sizeof + (struct wl12xx_arp_rsp_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, WL1271_CMD_TEMPL_MAX_SIZE, i, diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 0b79c49cd877..f7d7cad730a2 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2110,10 +2110,26 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, __be32 addr = bss_conf->arp_addr_list[0]; WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); - if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled) - ret = wl1271_acx_arp_ip_filter(wl, true, addr); - else - ret = wl1271_acx_arp_ip_filter(wl, false, addr); + if (bss_conf->arp_addr_cnt == 1 && + bss_conf->arp_filter_enabled) { + /* + * The template should have been configured only upon + * association. however, it seems that the correct ip + * isn't being set (when sending), so we have to + * reconfigure the template upon every ip change. + */ + ret = wl1271_cmd_build_arp_rsp(wl, addr); + if (ret < 0) { + wl1271_warning("build arp rsp failed: %d", ret); + goto out_sleep; + } + + ret = wl1271_acx_arp_ip_filter(wl, + (ACX_ARP_FILTER_ARP_FILTERING | + ACX_ARP_FILTER_AUTO_ARP), + addr); + } else + ret = wl1271_acx_arp_ip_filter(wl, 0, addr); if (ret < 0) goto out_sleep; diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 184628027213..8ee0d3a8fa6e 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -2,6 +2,7 @@ #define __WL12XX_80211_H__ #include /* ETH_ALEN */ +#include /* RATES */ #define IEEE80211_CCK_RATE_1MB 0x02 @@ -140,6 +141,19 @@ struct wl12xx_probe_req_template { struct wl12xx_ie_rates ext_rates; } __packed; +struct wl12xx_arp_rsp_template { + struct ieee80211_hdr_3addr hdr; + + u8 llc_hdr[sizeof(rfc1042_header)]; + u16 llc_type; + + struct arphdr arp_hdr; + u8 sender_hw[ETH_ALEN]; + u32 sender_ip; + u8 target_hw[ETH_ALEN]; + u32 target_ip; +} __packed; + struct wl12xx_probe_resp_template { struct ieee80211_header header; -- cgit v1.2.3-59-g8ed1b From ea559b460509b241cc1a3f36eebe0b2b634b3cf2 Mon Sep 17 00:00:00 2001 From: Guy Eilam Date: Thu, 9 Dec 2010 16:54:59 +0200 Subject: wl1271: fixed problem with WPS IEs in probe requests Inclusion of a WPS IE in probe requests caused a problem in the driver due to the maximum size of the probe request template and the max_scan_ie_len values at initialization. Increased the size of probe request template to the maximum size allowed by the firmware. Struct wl12xx_probe_req_template, which was only used for calculating the max size of the probe request template, is no longer used and needed. max_scan_ie_len is used for validating the size of additional IEs in scan requests. Initialized the max_scan_ie_len field to the maximum size of the probe request template minus the ieee80211 header size. Signed-off-by: Guy Eilam Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/init.c | 6 ++---- drivers/net/wireless/wl12xx/main.c | 7 +++++++ drivers/net/wireless/wl12xx/wl12xx_80211.h | 7 ------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 0392e37f0d66..785a5304bfc4 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -53,18 +53,16 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl) int wl1271_init_templates_config(struct wl1271 *wl) { int ret, i; - size_t size; /* send empty templates for fw memory reservation */ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, - sizeof(struct wl12xx_probe_req_template), + WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - size = sizeof(struct wl12xx_probe_req_template); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - NULL, size, 0, + NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f7d7cad730a2..0865585c8a75 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2666,6 +2666,13 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); wl->hw->wiphy->max_scan_ssids = 1; + /* + * Maximum length of elements in scanning probe request templates + * should be the maximum length possible for a template, without + * the IEEE80211 header of the template + */ + wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - + sizeof(struct ieee80211_header); wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 8ee0d3a8fa6e..be21032f4dc1 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -134,13 +134,6 @@ struct wl12xx_qos_null_data_template { __le16 qos_ctl; } __packed; -struct wl12xx_probe_req_template { - struct ieee80211_header header; - struct wl12xx_ie_ssid ssid; - struct wl12xx_ie_rates rates; - struct wl12xx_ie_rates ext_rates; -} __packed; - struct wl12xx_arp_rsp_template { struct ieee80211_hdr_3addr hdr; -- cgit v1.2.3-59-g8ed1b From 17c1755c24d83f9fd0509b64c76cc43fc60cc642 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 12 Dec 2010 12:15:35 +0200 Subject: wl12xx: allow runtime changing of debug_level Currently, the debug level is set in compilation time (by the DEBUG_LEVEL const). This method has the advantage of compiling only the relevant messages, while optimizing out the unused ones. In order to allow runtime control over the debug_level, while optimizing out messages when debug messages are not needed, we combine some methods: 1. use dynamic_debug (pr_debug) rather then printk. 2. add debug_level module param in order to set debug level during insmod. 3. add debug_level sysfs file in order to allow dynamic control over the debug level. Since patches for pr_debug_hex_dump() implementation haven't been applied yet, we are still temporarly using print_hex_dump(). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 5 +++++ drivers/net/wireless/wl12xx/main.c | 5 +++++ drivers/net/wireless/wl12xx/wl12xx.h | 19 ++++++++++--------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 8106a6c8a1ba..c2cd58074372 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -401,6 +401,11 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl) DEBUGFS_ADD(gpio_power, wl->rootdir); + entry = debugfs_create_x32("debug_level", 0600, wl->rootdir, + &wl12xx_debug_level); + if (!entry || IS_ERR(entry)) + goto err; + return 0; err: diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 0865585c8a75..8c50d3b3fabb 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2833,6 +2833,11 @@ int wl1271_free_hw(struct wl1271 *wl) } EXPORT_SYMBOL_GPL(wl1271_free_hw); +u32 wl12xx_debug_level; +EXPORT_SYMBOL_GPL(wl12xx_debug_level); +module_param_named(debug_level, wl12xx_debug_level, uint, DEBUG_NONE); +MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index e904c72e8c8f..07c2297b89a2 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -60,31 +60,32 @@ enum { DEBUG_ALL = ~0, }; -#define DEBUG_LEVEL (DEBUG_NONE) +extern u32 wl12xx_debug_level; #define DEBUG_DUMP_LIMIT 1024 #define wl1271_error(fmt, arg...) \ - printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) + pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg) #define wl1271_warning(fmt, arg...) \ - printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) + pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg) #define wl1271_notice(fmt, arg...) \ - printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) + pr_info(DRIVER_PREFIX fmt "\n", ##arg) #define wl1271_info(fmt, arg...) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) + pr_info(DRIVER_PREFIX fmt "\n", ##arg) #define wl1271_debug(level, fmt, arg...) \ do { \ - if (level & DEBUG_LEVEL) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ + if (level & wl12xx_debug_level) \ + pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \ } while (0) +/* TODO: use pr_debug_hex_dump when it will be available */ #define wl1271_dump(level, prefix, buf, len) \ do { \ - if (level & DEBUG_LEVEL) \ + if (level & wl12xx_debug_level) \ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ DUMP_PREFIX_OFFSET, 16, 1, \ buf, \ @@ -94,7 +95,7 @@ enum { #define wl1271_dump_ascii(level, prefix, buf, len) \ do { \ - if (level & DEBUG_LEVEL) \ + if (level & wl12xx_debug_level) \ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ DUMP_PREFIX_OFFSET, 16, 1, \ buf, \ -- cgit v1.2.3-59-g8ed1b From 6742f554db14da94172da9eb1875a1aa944a827f Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 13 Dec 2010 09:52:37 +0200 Subject: wl12xx: Change TX queue to be per AC With the current single-queue implementation traffic priorization is not working correctly - when using multiple BE streams and one, say VI stream, the VI stream will share bandwidth almost equally with the BE streams. To fix the issue, implement per AC queues, which are emptied in priority order to the firmware. To keep it relatively simple, maintain a global buffer count and global queue stop/wake instead of per-AC. With these changes, priorization appears to work just fine. Signed-off-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 2 +- drivers/net/wireless/wl12xx/main.c | 12 ++++--- drivers/net/wireless/wl12xx/tx.c | 60 ++++++++++++++++++++++++++++------- drivers/net/wireless/wl12xx/wl12xx.h | 3 +- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index c2cd58074372..ec6077760157 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -225,7 +225,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, char buf[20]; int res; - queue_len = skb_queue_len(&wl->tx_queue); + queue_len = wl->tx_queue_count; res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); return simple_read_from_buffer(userbuf, count, ppos, buf, res); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8c50d3b3fabb..062247ef3ad2 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -570,7 +570,7 @@ static void wl1271_irq_work(struct work_struct *work) /* Check if any tx blocks were freed */ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - !skb_queue_empty(&wl->tx_queue)) { + wl->tx_queue_count) { /* * In order to avoid starvation of the TX path, * call the work function directly. @@ -891,6 +891,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = txinfo->control.sta; unsigned long flags; + int q; /* * peek into the rates configured in the STA entry. @@ -918,10 +919,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); } #endif + wl->tx_queue_count++; spin_unlock_irqrestore(&wl->wl_lock, flags); /* queue the packet */ - skb_queue_tail(&wl->tx_queue, skb); + q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + skb_queue_tail(&wl->tx_queue[q], skb); /* * The chip specific setup must run before the first TX packet - @@ -935,7 +938,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) { wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); spin_lock_irqsave(&wl->wl_lock, flags); @@ -2719,7 +2722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->hw = hw; wl->plat_dev = plat_dev; - skb_queue_head_init(&wl->tx_queue); + for (i = 0; i < NUM_TX_QUEUES; i++) + skb_queue_head_init(&wl->tx_queue[i]); INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index d332b3f6d0fa..b44c75cd8c1e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -125,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, /* queue (we use same identifiers for tid's and ac's */ ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); desc->tid = ac; - desc->aid = TX_HW_DEFAULT_AID; desc->reserved = 0; @@ -228,7 +227,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl) unsigned long flags; if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { + wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) { /* firmware buffer has space, restart queues */ spin_lock_irqsave(&wl->wl_lock, flags); ieee80211_wake_queues(wl->hw); @@ -237,6 +236,43 @@ static void handle_tx_low_watermark(struct wl1271 *wl) } } +static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) +{ + struct sk_buff *skb = NULL; + unsigned long flags; + + skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]); + if (skb) + goto out; + skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]); + if (skb) + goto out; + skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]); + if (skb) + goto out; + skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]); + +out: + if (skb) { + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count--; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + + return skb; +} + +static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) +{ + unsigned long flags; + int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + + skb_queue_head(&wl->tx_queue[q], skb); + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count++; + spin_unlock_irqrestore(&wl->wl_lock, flags); +} + void wl1271_tx_work_locked(struct wl1271 *wl) { struct sk_buff *skb; @@ -270,7 +306,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) wl1271_acx_rate_policies(wl); } - while ((skb = skb_dequeue(&wl->tx_queue))) { + while ((skb = wl1271_skb_dequeue(wl))) { if (!woken_up) { ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) @@ -284,9 +320,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl) * Aggregation buffer is full. * Flush buffer and try again. */ - skb_queue_head(&wl->tx_queue, skb); + wl1271_skb_queue_head(wl, skb); wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); + buf_offset, true); sent_packets = true; buf_offset = 0; continue; @@ -295,7 +331,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) * Firmware buffer is full. * Queue back last skb, and stop aggregating. */ - skb_queue_head(&wl->tx_queue, skb); + wl1271_skb_queue_head(wl, skb); /* No work left, avoid scheduling redundant tx work */ set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); goto out_ack; @@ -440,10 +476,13 @@ void wl1271_tx_reset(struct wl1271 *wl) struct sk_buff *skb; /* TX failure */ - while ((skb = skb_dequeue(&wl->tx_queue))) { - wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); - ieee80211_tx_status(wl->hw, skb); + for (i = 0; i < NUM_TX_QUEUES; i++) { + while ((skb = skb_dequeue(&wl->tx_queue[i]))) { + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + ieee80211_tx_status(wl->hw, skb); + } } + wl->tx_queue_count = 0; /* * Make sure the driver is at a consistent state, in case this @@ -472,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl) mutex_lock(&wl->mutex); wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", wl->tx_frames_cnt); - if ((wl->tx_frames_cnt == 0) && - skb_queue_empty(&wl->tx_queue)) { + if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) { mutex_unlock(&wl->mutex); return; } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 07c2297b89a2..ce3d31f98c55 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -292,7 +292,8 @@ struct wl1271 { int session_counter; /* Frames scheduled for transmission, not handled yet */ - struct sk_buff_head tx_queue; + struct sk_buff_head tx_queue[NUM_TX_QUEUES]; + int tx_queue_count; struct work_struct tx_work; -- cgit v1.2.3-59-g8ed1b From 248daa084cee4b212ff4408e9c9b05b3bdc0da0d Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 15 Dec 2010 16:10:12 +0200 Subject: wl12xx_sdio_test: rename files to match current style Change some file names and Kconfig settings so that this new module matches the new way of using wl12xx instead of wl1271. Also fix SDIO power enabling and disabling to match the latest way of doing it. Cc: Roger Quadros Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 12 +- drivers/net/wireless/wl12xx/Makefile | 3 +- drivers/net/wireless/wl12xx/sdio_test.c | 520 +++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_sdio_test.c | 510 ------------------------ 4 files changed, 529 insertions(+), 516 deletions(-) create mode 100644 drivers/net/wireless/wl12xx/sdio_test.c delete mode 100644 drivers/net/wireless/wl12xx/wl1271_sdio_test.c diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 085bc44d814b..0e65bce457d6 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -52,13 +52,15 @@ config WL12XX_SDIO If you choose to build a module, it'll be called wl12xx_sdio. Say N if unsure. -config WL1271_SDIO_TEST - tristate "TI wl1271 SDIO testing support" - depends on WL1271 && MMC +config WL12XX_SDIO_TEST + tristate "TI wl12xx SDIO testing support" + depends on WL12XX && MMC + default n ---help--- This module adds support for the SDIO bus testing with the - TI wl1271 chipset. Select this if your platform is using - the SDIO bus. + TI wl12xx chipsets. You probably don't want this unless you are + testing a new hardware platform. Select this if you want to test the + SDIO bus which is connected to the wl12xx chip. config WL12XX_PLATFORM_DATA bool diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 187678503887..521c0414e52e 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -3,13 +3,14 @@ wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \ wl12xx_spi-objs = spi.o wl12xx_sdio-objs = sdio.o +wl12xx_sdio_test-objs = sdio_test.o wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_WL12XX) += wl12xx.o obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o -obj-$(CONFIG_WL1271_SDIO_TEST) += wl1271_sdio_test.o +obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o # small builtin driver bit obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c new file mode 100644 index 000000000000..9fcbd3dd8490 --- /dev/null +++ b/drivers/net/wireless/wl12xx/sdio_test.c @@ -0,0 +1,520 @@ +/* + * SDIO testing driver for wl12xx + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Roger Quadros + * + * wl12xx read/write routines taken from the main module + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wl12xx.h" +#include "io.h" +#include "boot.h" + +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI 0x0097 +#endif + +#ifndef SDIO_DEVICE_ID_TI_WL1271 +#define SDIO_DEVICE_ID_TI_WL1271 0x4076 +#endif + +static bool rx, tx; + +module_param(rx, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(rx, "Perform rx test. Default (0). " + "This test continuously reads data from the SDIO device.\n"); + +module_param(tx, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(tx, "Perform tx test. Default (0). " + "This test continuously writes data to the SDIO device.\n"); + +struct wl1271_test { + struct wl1271 wl; + struct task_struct *test_task; +}; + +static const struct sdio_device_id wl1271_devices[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, + {} +}; + +static inline struct sdio_func *wl_to_func(struct wl1271 *wl) +{ + return wl->if_priv; +} + +static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) +{ + return &(wl_to_func(wl)->dev); +} + +static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret = 0; + struct sdio_func *func = wl_to_func(wl); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + if (fixed) + ret = sdio_readsb(func, buf, addr, len); + else + ret = sdio_memcpy_fromio(func, buf, addr, len); + + wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + } + + if (ret) + wl1271_error("sdio read failed (%d)", ret); +} + +static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) +{ + int ret = 0; + struct sdio_func *func = wl_to_func(wl); + + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { + sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); + wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", + addr, ((u8 *)buf)[0]); + } else { + wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", + addr, len); + wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); + + if (fixed) + ret = sdio_writesb(func, addr, buf, len); + else + ret = sdio_memcpy_toio(func, addr, buf, len); + } + if (ret) + wl1271_error("sdio write failed (%d)", ret); + +} + +static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +{ + struct sdio_func *func = wl_to_func(wl); + int ret; + + /* Let the SDIO stack handle wlan_enable control, so we + * keep host claimed while wlan is in use to keep wl1271 + * alive. + */ + if (enable) { + /* Power up the card */ + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + } else { + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + /* Power down the card */ + ret = pm_runtime_put_sync(&func->dev); + } + +out: + return ret; +} + +static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) +{ +} + +static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) +{ +} + + +static struct wl1271_if_operations sdio_ops = { + .read = wl1271_sdio_raw_read, + .write = wl1271_sdio_raw_write, + .power = wl1271_sdio_set_power, + .dev = wl1271_sdio_wl_to_dev, + .enable_irq = wl1271_sdio_enable_interrupts, + .disable_irq = wl1271_sdio_disable_interrupts, +}; + +static void wl1271_fw_wakeup(struct wl1271 *wl) +{ + u32 elp_reg; + + elp_reg = ELPCTRL_WAKE_UP; + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); +} + +static int wl1271_fetch_firmware(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get firmware: %d", ret); + return ret; + } + + if (fw->size % 4) { + wl1271_error("firmware size is not multiple of 32 bits: %zu", + fw->size); + ret = -EILSEQ; + goto out; + } + + wl->fw_len = fw->size; + wl->fw = vmalloc(wl->fw_len); + + if (!wl->fw) { + wl1271_error("could not allocate memory for the firmware"); + ret = -ENOMEM; + goto out; + } + + memcpy(wl->fw, fw->data, wl->fw_len); + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1271_fetch_nvs(struct wl1271 *wl) +{ + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); + + if (ret < 0) { + wl1271_error("could not get nvs file: %d", ret); + return ret; + } + + wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); + + if (!wl->nvs) { + wl1271_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; + goto out; + } + + wl->nvs_len = fw->size; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1271_chip_wakeup(struct wl1271 *wl) +{ + struct wl1271_partition_set partition; + int ret; + + msleep(WL1271_PRE_POWER_ON_SLEEP); + ret = wl1271_power_on(wl); + if (ret) + return ret; + + msleep(WL1271_POWER_ON_SLEEP); + + /* We don't need a real memory partition here, because we only want + * to use the registers at this point. */ + memset(&partition, 0, sizeof(partition)); + partition.reg.start = REGISTERS_BASE; + partition.reg.size = REGISTERS_DOWN_SIZE; + wl1271_set_partition(wl, &partition); + + /* ELP module wake up */ + wl1271_fw_wakeup(wl); + + /* whal_FwCtrl_BootSm() */ + + /* 0. read chip id from CHIP_ID */ + wl->chip.id = wl1271_read32(wl, CHIP_ID_B); + + /* 1. check if chip id is valid */ + + switch (wl->chip.id) { + case CHIP_ID_1271_PG10: + wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", + wl->chip.id); + break; + case CHIP_ID_1271_PG20: + wl1271_notice("chip id 0x%x (1271 PG20)", + wl->chip.id); + break; + default: + wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); + return -ENODEV; + } + + return ret; +} + +static struct wl1271_partition_set part_down = { + .mem = { + .start = 0x00000000, + .size = 0x000177c0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x00008800 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + }, +}; + +static int tester(void *data) +{ + struct wl1271 *wl = data; + struct sdio_func *func = wl_to_func(wl); + struct device *pdev = &func->dev; + int ret = 0; + bool rx_started = 0; + bool tx_started = 0; + uint8_t *tx_buf, *rx_buf; + int test_size = PAGE_SIZE; + u32 addr = 0; + struct wl1271_partition_set partition; + + /* We assume chip is powered up and firmware fetched */ + + memcpy(&partition, &part_down, sizeof(partition)); + partition.mem.start = addr; + wl1271_set_partition(wl, &partition); + + tx_buf = kmalloc(test_size, GFP_KERNEL); + rx_buf = kmalloc(test_size, GFP_KERNEL); + if (!tx_buf || !rx_buf) { + dev_err(pdev, + "Could not allocate memory. Test will not run.\n"); + ret = -ENOMEM; + goto free; + } + + memset(tx_buf, 0x5a, test_size); + + /* write something in data area so we can read it back */ + wl1271_write(wl, addr, tx_buf, test_size, false); + + while (!kthread_should_stop()) { + if (rx && !rx_started) { + dev_info(pdev, "starting rx test\n"); + rx_started = 1; + } else if (!rx && rx_started) { + dev_info(pdev, "stopping rx test\n"); + rx_started = 0; + } + + if (tx && !tx_started) { + dev_info(pdev, "starting tx test\n"); + tx_started = 1; + } else if (!tx && tx_started) { + dev_info(pdev, "stopping tx test\n"); + tx_started = 0; + } + + if (rx_started) + wl1271_read(wl, addr, rx_buf, test_size, false); + + if (tx_started) + wl1271_write(wl, addr, tx_buf, test_size, false); + + if (!rx_started && !tx_started) + msleep(100); + } + +free: + kfree(tx_buf); + kfree(rx_buf); + return ret; +} + +static int __devinit wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + const struct wl12xx_platform_data *wlan_data; + struct wl1271 *wl; + struct wl1271_test *wl_test; + int ret = 0; + + /* wl1271 has 2 sdio functions we handle just the wlan part */ + if (func->num != 0x02) + return -ENODEV; + + wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL); + if (!wl_test) { + dev_err(&func->dev, "Could not allocate memory\n"); + return -ENOMEM; + } + + wl = &wl_test->wl; + + wl->if_priv = func; + wl->if_ops = &sdio_ops; + + /* Grab access to FN0 for ELP reg. */ + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + + wlan_data = wl12xx_get_platform_data(); + if (IS_ERR(wlan_data)) { + ret = PTR_ERR(wlan_data); + dev_err(&func->dev, "missing wlan platform data: %d\n", ret); + goto out_free; + } + + wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; + + sdio_set_drvdata(func, wl_test); + + + /* power up the device */ + ret = wl1271_chip_wakeup(wl); + if (ret) { + dev_err(&func->dev, "could not wake up chip\n"); + goto out_free; + } + + if (wl->fw == NULL) { + ret = wl1271_fetch_firmware(wl); + if (ret < 0) { + dev_err(&func->dev, "firmware fetch error\n"); + goto out_off; + } + } + + /* fetch NVS */ + if (wl->nvs == NULL) { + ret = wl1271_fetch_nvs(wl); + if (ret < 0) { + dev_err(&func->dev, "NVS fetch error\n"); + goto out_off; + } + } + + ret = wl1271_load_firmware(wl); + if (ret < 0) { + dev_err(&func->dev, "firmware load error: %d\n", ret); + goto out_free; + } + + dev_info(&func->dev, "initialized\n"); + + /* I/O testing will be done in the tester thread */ + + wl_test->test_task = kthread_run(tester, wl, "sdio_tester"); + if (IS_ERR(wl_test->test_task)) { + dev_err(&func->dev, "unable to create kernel thread\n"); + ret = PTR_ERR(wl_test->test_task); + goto out_free; + } + + return 0; + +out_off: + /* power off the chip */ + wl1271_power_off(wl); + +out_free: + kfree(wl_test); + return ret; +} + +static void __devexit wl1271_remove(struct sdio_func *func) +{ + struct wl1271_test *wl_test = sdio_get_drvdata(func); + + /* stop the I/O test thread */ + kthread_stop(wl_test->test_task); + + /* power off the chip */ + wl1271_power_off(&wl_test->wl); + + vfree(wl_test->wl.fw); + wl_test->wl.fw = NULL; + kfree(wl_test->wl.nvs); + wl_test->wl.nvs = NULL; + + kfree(wl_test); +} + +static struct sdio_driver wl1271_sdio_driver = { + .name = "wl12xx_sdio_test", + .id_table = wl1271_devices, + .probe = wl1271_probe, + .remove = __devexit_p(wl1271_remove), +}; + +static int __init wl1271_init(void) +{ + int ret; + + ret = sdio_register_driver(&wl1271_sdio_driver); + if (ret < 0) + pr_err("failed to register sdio driver: %d\n", ret); + + return ret; +} +module_init(wl1271_init); + +static void __exit wl1271_exit(void) +{ + sdio_unregister_driver(&wl1271_sdio_driver); +} +module_exit(wl1271_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Roger Quadros "); + diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio_test.c b/drivers/net/wireless/wl12xx/wl1271_sdio_test.c deleted file mode 100644 index 42d13144f645..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_sdio_test.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * wl1271_sdio_test.c - SDIO testing driver for wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Roger Quadros - * - * wl1271 read/write routines taken from wl1271_sdio.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wl1271.h" -#include "wl1271_io.h" -#include "wl1271_boot.h" - -#ifndef SDIO_VENDOR_ID_TI -#define SDIO_VENDOR_ID_TI 0x0097 -#endif - -#ifndef SDIO_DEVICE_ID_TI_WL1271 -#define SDIO_DEVICE_ID_TI_WL1271 0x4076 -#endif - -static bool rx, tx; - -module_param(rx, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(rx, "Perform rx test. Default (0). " - "This test continuously reads data from the SDIO device.\n"); - -module_param(tx, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(tx, "Perform tx test. Default (0). " - "This test continuously writes data to the SDIO device.\n"); - -struct wl1271_test { - struct wl1271 wl; - struct task_struct *test_task; -}; - -static const struct sdio_device_id wl1271_devices[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, - {} -}; - -static inline struct sdio_func *wl_to_func(struct wl1271 *wl) -{ - return wl->if_priv; -} - -static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) -{ - return &(wl_to_func(wl)->dev); -} - -static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret = 0; - struct sdio_func *func = wl_to_func(wl); - - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { - ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); - wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", - addr, ((u8 *)buf)[0]); - } else { - if (fixed) - ret = sdio_readsb(func, buf, addr, len); - else - ret = sdio_memcpy_fromio(func, buf, addr, len); - - wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - } - - if (ret) - wl1271_error("sdio read failed (%d)", ret); -} - -static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret = 0; - struct sdio_func *func = wl_to_func(wl); - - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { - sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); - wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", - addr, ((u8 *)buf)[0]); - } else { - wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - - if (fixed) - ret = sdio_writesb(func, addr, buf, len); - else - ret = sdio_memcpy_toio(func, addr, buf, len); - } - if (ret) - wl1271_error("sdio write failed (%d)", ret); - -} - -static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) -{ - struct sdio_func *func = wl_to_func(wl); - - /* Let the SDIO stack handle wlan_enable control, so we - * keep host claimed while wlan is in use to keep wl1271 - * alive. - */ - if (enable) { - sdio_claim_power(func); - sdio_claim_host(func); - sdio_enable_func(func); - } else { - sdio_disable_func(func); - sdio_release_host(func); - sdio_release_power(func); - } - - return 0; -} - -static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) -{ -} - - -static struct wl1271_if_operations sdio_ops = { - .read = wl1271_sdio_raw_read, - .write = wl1271_sdio_raw_write, - .power = wl1271_sdio_set_power, - .dev = wl1271_sdio_wl_to_dev, - .enable_irq = wl1271_sdio_enable_interrupts, - .disable_irq = wl1271_sdio_disable_interrupts, -}; - -static void wl1271_fw_wakeup(struct wl1271 *wl) -{ - u32 elp_reg; - - elp_reg = ELPCTRL_WAKE_UP; - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); -} - -static int wl1271_fetch_firmware(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get firmware: %d", ret); - return ret; - } - - if (fw->size % 4) { - wl1271_error("firmware size is not multiple of 32 bits: %zu", - fw->size); - ret = -EILSEQ; - goto out; - } - - wl->fw_len = fw->size; - wl->fw = vmalloc(wl->fw_len); - - if (!wl->fw) { - wl1271_error("could not allocate memory for the firmware"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->fw, fw->data, wl->fw_len); - - ret = 0; - -out: - release_firmware(fw); - - return ret; -} - -static int wl1271_fetch_nvs(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get nvs file: %d", ret); - return ret; - } - - wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); - - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - wl->nvs_len = fw->size; - -out: - release_firmware(fw); - - return ret; -} - -static int wl1271_chip_wakeup(struct wl1271 *wl) -{ - struct wl1271_partition_set partition; - int ret; - - msleep(WL1271_PRE_POWER_ON_SLEEP); - ret = wl1271_power_on(wl); - if (ret) - return ret; - - msleep(WL1271_POWER_ON_SLEEP); - - /* We don't need a real memory partition here, because we only want - * to use the registers at this point. */ - memset(&partition, 0, sizeof(partition)); - partition.reg.start = REGISTERS_BASE; - partition.reg.size = REGISTERS_DOWN_SIZE; - wl1271_set_partition(wl, &partition); - - /* ELP module wake up */ - wl1271_fw_wakeup(wl); - - /* whal_FwCtrl_BootSm() */ - - /* 0. read chip id from CHIP_ID */ - wl->chip.id = wl1271_read32(wl, CHIP_ID_B); - - /* 1. check if chip id is valid */ - - switch (wl->chip.id) { - case CHIP_ID_1271_PG10: - wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", - wl->chip.id); - break; - case CHIP_ID_1271_PG20: - wl1271_notice("chip id 0x%x (1271 PG20)", - wl->chip.id); - break; - default: - wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); - return -ENODEV; - } - - return ret; -} - -static struct wl1271_partition_set part_down = { - .mem = { - .start = 0x00000000, - .size = 0x000177c0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x00008800 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - }, -}; - -static int tester(void *data) -{ - struct wl1271 *wl = data; - struct sdio_func *func = wl_to_func(wl); - struct device *pdev = &func->dev; - int ret = 0; - bool rx_started = 0; - bool tx_started = 0; - uint8_t *tx_buf, *rx_buf; - int test_size = PAGE_SIZE; - u32 addr = 0; - struct wl1271_partition_set partition; - - /* We assume chip is powered up and firmware fetched */ - - memcpy(&partition, &part_down, sizeof(partition)); - partition.mem.start = addr; - wl1271_set_partition(wl, &partition); - - tx_buf = kmalloc(test_size, GFP_KERNEL); - rx_buf = kmalloc(test_size, GFP_KERNEL); - if (!tx_buf || !rx_buf) { - dev_err(pdev, - "Could not allocate memory. Test will not run.\n"); - ret = -ENOMEM; - goto free; - } - - memset(tx_buf, 0x5a, test_size); - - /* write something in data area so we can read it back */ - wl1271_write(wl, addr, tx_buf, test_size, false); - - while (!kthread_should_stop()) { - if (rx && !rx_started) { - dev_info(pdev, "starting rx test\n"); - rx_started = 1; - } else if (!rx && rx_started) { - dev_info(pdev, "stopping rx test\n"); - rx_started = 0; - } - - if (tx && !tx_started) { - dev_info(pdev, "starting tx test\n"); - tx_started = 1; - } else if (!tx && tx_started) { - dev_info(pdev, "stopping tx test\n"); - tx_started = 0; - } - - if (rx_started) - wl1271_read(wl, addr, rx_buf, test_size, false); - - if (tx_started) - wl1271_write(wl, addr, tx_buf, test_size, false); - - if (!rx_started && !tx_started) - msleep(100); - } - -free: - kfree(tx_buf); - kfree(rx_buf); - return ret; -} - -static int __devinit wl1271_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - const struct wl12xx_platform_data *wlan_data; - struct wl1271 *wl; - struct wl1271_test *wl_test; - int ret = 0; - - /* wl1271 has 2 sdio functions we handle just the wlan part */ - if (func->num != 0x02) - return -ENODEV; - - wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL); - if (!wl_test) { - dev_err(&func->dev, "Could not allocate memory\n"); - return -ENOMEM; - } - - wl = &wl_test->wl; - - wl->if_priv = func; - wl->if_ops = &sdio_ops; - - /* Grab access to FN0 for ELP reg. */ - func->card->quirks |= MMC_QUIRK_LENIENT_FN0; - - wlan_data = wl12xx_get_platform_data(); - if (IS_ERR(wlan_data)) { - ret = PTR_ERR(wlan_data); - dev_err(&func->dev, "missing wlan platform data: %d\n", ret); - goto out_free; - } - - wl->irq = wlan_data->irq; - wl->ref_clock = wlan_data->board_ref_clock; - - sdio_set_drvdata(func, wl_test); - - - /* power up the device */ - ret = wl1271_chip_wakeup(wl); - if (ret) { - dev_err(&func->dev, "could not wake up chip\n"); - goto out_free; - } - - if (wl->fw == NULL) { - ret = wl1271_fetch_firmware(wl); - if (ret < 0) { - dev_err(&func->dev, "firmware fetch error\n"); - goto out_off; - } - } - - /* fetch NVS */ - if (wl->nvs == NULL) { - ret = wl1271_fetch_nvs(wl); - if (ret < 0) { - dev_err(&func->dev, "NVS fetch error\n"); - goto out_off; - } - } - - ret = wl1271_load_firmware(wl); - if (ret < 0) { - dev_err(&func->dev, "firmware load error: %d\n", ret); - goto out_free; - } - - dev_info(&func->dev, "initialized\n"); - - /* I/O testing will be done in the tester thread */ - - wl_test->test_task = kthread_run(tester, wl, "sdio_tester"); - if (IS_ERR(wl_test->test_task)) { - dev_err(&func->dev, "unable to create kernel thread\n"); - ret = PTR_ERR(wl_test->test_task); - goto out_free; - } - - return 0; - -out_off: - /* power off the chip */ - wl1271_power_off(wl); - -out_free: - kfree(wl_test); - return ret; -} - -static void __devexit wl1271_remove(struct sdio_func *func) -{ - struct wl1271_test *wl_test = sdio_get_drvdata(func); - - /* stop the I/O test thread */ - kthread_stop(wl_test->test_task); - - /* power off the chip */ - wl1271_power_off(&wl_test->wl); - - vfree(wl_test->wl.fw); - wl_test->wl.fw = NULL; - kfree(wl_test->wl.nvs); - wl_test->wl.nvs = NULL; - - kfree(wl_test); -} - -static struct sdio_driver wl1271_sdio_driver = { - .name = "wl1271_sdio_test", - .id_table = wl1271_devices, - .probe = wl1271_probe, - .remove = __devexit_p(wl1271_remove), -}; - -static int __init wl1271_init(void) -{ - int ret; - - ret = sdio_register_driver(&wl1271_sdio_driver); - if (ret < 0) - pr_err("failed to register sdio driver: %d\n", ret); - - return ret; -} -module_init(wl1271_init); - -static void __exit wl1271_exit(void) -{ - sdio_unregister_driver(&wl1271_sdio_driver); -} -module_exit(wl1271_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Roger Quadros "); - -- cgit v1.2.3-59-g8ed1b From 0c8173385e549f95cd80c3fff5aab87b4f881d8d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 8 Dec 2010 11:12:31 -0600 Subject: rtl8192ce: Add new driver Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/rtlwifi/Kconfig | 15 + drivers/net/wireless/rtlwifi/Makefile | 13 + drivers/net/wireless/rtlwifi/base.c | 958 +++++++ drivers/net/wireless/rtlwifi/base.h | 120 + drivers/net/wireless/rtlwifi/cam.c | 291 +++ drivers/net/wireless/rtlwifi/cam.h | 53 + drivers/net/wireless/rtlwifi/core.c | 1029 ++++++++ drivers/net/wireless/rtlwifi/core.h | 42 + drivers/net/wireless/rtlwifi/debug.c | 50 + drivers/net/wireless/rtlwifi/debug.h | 212 ++ drivers/net/wireless/rtlwifi/efuse.c | 1189 +++++++++ drivers/net/wireless/rtlwifi/efuse.h | 124 + drivers/net/wireless/rtlwifi/pci.c | 1933 ++++++++++++++ drivers/net/wireless/rtlwifi/pci.h | 302 +++ drivers/net/wireless/rtlwifi/ps.c | 492 ++++ drivers/net/wireless/rtlwifi/ps.h | 43 + drivers/net/wireless/rtlwifi/rc.c | 329 +++ drivers/net/wireless/rtlwifi/rc.h | 40 + drivers/net/wireless/rtlwifi/regd.c | 400 +++ drivers/net/wireless/rtlwifi/regd.h | 61 + drivers/net/wireless/rtlwifi/rtl8192ce/Makefile | 12 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h | 257 ++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c | 1473 +++++++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h | 196 ++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c | 804 ++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h | 98 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c | 2173 ++++++++++++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h | 57 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c | 144 ++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h | 41 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c | 2676 ++++++++++++++++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h | 237 ++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h | 2065 +++++++++++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c | 523 ++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h | 44 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c | 280 ++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h | 37 + .../wireless/rtlwifi/rtl8192ce/rtl8192c-table.c | 1224 +++++++++ .../wireless/rtlwifi/rtl8192ce/rtl8192c-table.h | 58 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c | 1031 ++++++++ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h | 714 ++++++ drivers/net/wireless/rtlwifi/wifi.h | 1532 +++++++++++ 44 files changed, 23374 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/Kconfig create mode 100644 drivers/net/wireless/rtlwifi/Makefile create mode 100644 drivers/net/wireless/rtlwifi/base.c create mode 100644 drivers/net/wireless/rtlwifi/base.h create mode 100644 drivers/net/wireless/rtlwifi/cam.c create mode 100644 drivers/net/wireless/rtlwifi/cam.h create mode 100644 drivers/net/wireless/rtlwifi/core.c create mode 100644 drivers/net/wireless/rtlwifi/core.h create mode 100644 drivers/net/wireless/rtlwifi/debug.c create mode 100644 drivers/net/wireless/rtlwifi/debug.h create mode 100644 drivers/net/wireless/rtlwifi/efuse.c create mode 100644 drivers/net/wireless/rtlwifi/efuse.h create mode 100644 drivers/net/wireless/rtlwifi/pci.c create mode 100644 drivers/net/wireless/rtlwifi/pci.h create mode 100644 drivers/net/wireless/rtlwifi/ps.c create mode 100644 drivers/net/wireless/rtlwifi/ps.h create mode 100644 drivers/net/wireless/rtlwifi/rc.c create mode 100644 drivers/net/wireless/rtlwifi/rc.h create mode 100644 drivers/net/wireless/rtlwifi/regd.c create mode 100644 drivers/net/wireless/rtlwifi/regd.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/Makefile create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h create mode 100644 drivers/net/wireless/rtlwifi/wifi.h diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 4de4410cd38e..b4338f389394 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/rt2x00/Kconfig" +source "drivers/net/wireless/rtlwifi/Kconfig" source "drivers/net/wireless/wl1251/Kconfig" source "drivers/net/wireless/wl12xx/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 06f8ca26c5c1..9760561a27a5 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/ obj-$(CONFIG_ZD1211RW) += zd1211rw/ obj-$(CONFIG_RTL8180) += rtl818x/ obj-$(CONFIG_RTL8187) += rtl818x/ +obj-$(CONFIG_RTL8192CE) += rtlwifi/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig new file mode 100644 index 000000000000..d712026eb763 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -0,0 +1,15 @@ +config RTL8192CE + tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter" + depends on MAC80211 && EXPERIMENTAL + select FW_LOADER + select RTLWIFI + ---help--- + This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be calledrtl8192ce. + +config RTLWIFI + tristate + depends on RTL8192CE + default m diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile new file mode 100644 index 000000000000..2a7a4384f8ee --- /dev/null +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -0,0 +1,13 @@ +obj-$(CONFIG_RTLWIFI) += rtlwifi.o +rtlwifi-objs := \ + base.o \ + cam.o \ + core.o \ + debug.o \ + efuse.o \ + pci.o \ + ps.o \ + rc.o \ + regd.o + +obj-$(CONFIG_RTL8192CE) += rtl8192ce/ diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c new file mode 100644 index 000000000000..9e860ff30b52 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/base.c @@ -0,0 +1,958 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include +#include "wifi.h" +#include "rc.h" +#include "base.h" +#include "efuse.h" +#include "cam.h" +#include "ps.h" +#include "regd.h" + +/* + *NOTICE!!!: This file will be very big, we hsould + *keep it clear under follwing roles: + * + *This file include follwing part, so, if you add new + *functions into this file, please check which part it + *should includes. or check if you should add new part + *for this file: + * + *1) mac80211 init functions + *2) tx information functions + *3) functions called by core.c + *4) wq & timer callback functions + *5) frame process functions + *6) sysfs functions + *7) ... + */ + +/********************************************************* + * + * mac80211 init functions + * + *********************************************************/ +static struct ieee80211_channel rtl_channeltable[] = { + {.center_freq = 2412, .hw_value = 1,}, + {.center_freq = 2417, .hw_value = 2,}, + {.center_freq = 2422, .hw_value = 3,}, + {.center_freq = 2427, .hw_value = 4,}, + {.center_freq = 2432, .hw_value = 5,}, + {.center_freq = 2437, .hw_value = 6,}, + {.center_freq = 2442, .hw_value = 7,}, + {.center_freq = 2447, .hw_value = 8,}, + {.center_freq = 2452, .hw_value = 9,}, + {.center_freq = 2457, .hw_value = 10,}, + {.center_freq = 2462, .hw_value = 11,}, + {.center_freq = 2467, .hw_value = 12,}, + {.center_freq = 2472, .hw_value = 13,}, + {.center_freq = 2484, .hw_value = 14,}, +}; + +static struct ieee80211_rate rtl_ratetable[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static const struct ieee80211_supported_band rtl_band_2ghz = { + .band = IEEE80211_BAND_2GHZ, + + .channels = rtl_channeltable, + .n_channels = ARRAY_SIZE(rtl_channeltable), + + .bitrates = rtl_ratetable, + .n_bitrates = ARRAY_SIZE(rtl_ratetable), + + .ht_cap = {0}, +}; + +static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, + struct ieee80211_sta_ht_cap *ht_cap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + ht_cap->ht_supported = true; + ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + + /* + *Maximum length of AMPDU that the STA can receive. + *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + */ + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + + /*Minimum MPDU start spacing , */ + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + /* + *hw->wiphy->bands[IEEE80211_BAND_2GHZ] + *base on ant_num + *rx_mask: RX mask + *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7 + *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15 + *if rx_ant >=3 rx_mask[2]=0xff; + *if BW_40 rx_mask[4]=0x01; + *highest supported RX rate + */ + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n")); + + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; + } else if (get_rf_type(rtlphy) == RF_1T1R) { + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); + + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0x00; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; + } +} + +static void _rtl_init_mac80211(struct ieee80211_hw *hw) +{ + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_supported_band *sband; + + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); + + /* + * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] + * to default value(1T1R) + */ + memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + + /* <5> set hw caps */ + hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/ + /*IEEE80211_HW_SUPPORTS_PS | */ + /*IEEE80211_HW_PS_NULLFUNC_STACK | */ + /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ + IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; + + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + + hw->wiphy->rts_threshold = 2347; + + hw->queues = AC_MAX; + hw->extra_tx_headroom = RTL_TX_HEADER_SIZE; + + /* TODO: Correct this value for our hw */ + /* TODO: define these hard code value */ + hw->channel_change_time = 100; + hw->max_listen_interval = 5; + hw->max_rate_tries = 4; + /* hw->max_rates = 1; */ + + /* <6> mac address */ + if (is_valid_ether_addr(rtlefuse->dev_addr)) { + SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr); + } else { + u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 }; + get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1); + SET_IEEE80211_PERM_ADDR(hw, rtlmac); + } + +} + +static void _rtl_init_deferred_work(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* <1> timer */ + init_timer(&rtlpriv->works.watchdog_timer); + setup_timer(&rtlpriv->works.watchdog_timer, + rtl_watch_dog_timer_callback, (unsigned long)hw); + + /* <2> work queue */ + rtlpriv->works.hw = hw; + rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name); + INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, + (void *)rtl_watchdog_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, + (void *)rtl_ips_nic_off_wq_callback); + +} + +void rtl_deinit_deferred_work(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + del_timer_sync(&rtlpriv->works.watchdog_timer); + + cancel_delayed_work(&rtlpriv->works.watchdog_wq); + cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); +} + +void rtl_init_rfkill(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + bool radio_state; + bool blocked; + u8 valid = 0; + + /*set init state to rf on */ + rtlpriv->rfkill.rfkill_state = 1; + + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + + if (valid) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + (KERN_INFO "wireless switch is %s\n", + rtlpriv->rfkill.rfkill_state ? "on" : "off")); + + rtlpriv->rfkill.rfkill_state = radio_state; + + blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; + wiphy_rfkill_set_hw_state(hw->wiphy, blocked); + } + + wiphy_rfkill_start_polling(hw->wiphy); +} + +void rtl_deinit_rfkill(struct ieee80211_hw *hw) +{ + wiphy_rfkill_stop_polling(hw->wiphy); +} + +int rtl_init_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + /* <1> init mac80211 */ + _rtl_init_mac80211(hw); + rtlmac->hw = hw; + + /* <2> rate control register */ + if (rtl_rate_control_register()) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("rtl: Unable to register rtl_rc," + "use default RC !!\n")); + } else { + hw->rate_control_algorithm = "rtl_rc"; + } + + /* + * <3> init CRDA must come after init + * mac80211 hw in _rtl_init_mac80211. + */ + if (rtl_regd_init(hw, rtl_reg_notifier)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n")); + return 1; + } else { + /* CRDA regd hint must after init CRDA */ + if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("regulatory_hint fail\n")); + } + } + + /* <4> locks */ + sema_init(&rtlpriv->locks.ips_sem, 1); + sema_init(&rtlpriv->locks.conf_sem, 1); + spin_lock_init(&rtlpriv->locks.irq_th_lock); + spin_lock_init(&rtlpriv->locks.h2c_lock); + spin_lock_init(&rtlpriv->locks.rf_ps_lock); + spin_lock_init(&rtlpriv->locks.rf_lock); + spin_lock_init(&rtlpriv->locks.lps_lock); + + rtlmac->link_state = MAC80211_NOLINK; + + /* <5> init deferred work */ + _rtl_init_deferred_work(hw); + + return 0; +} + +void rtl_deinit_core(struct ieee80211_hw *hw) +{ + /*RC*/ + rtl_rate_control_unregister(); +} + +void rtl_init_rx_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER, + (u8 *) (&mac->rx_mgt_filter)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER, + (u8 *) (&mac->rx_ctrl_filter)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER, + (u8 *) (&mac->rx_data_filter)); +} + +/********************************************************* + * + * tx information functions + * + *********************************************************/ +static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rate_flag = info->control.rates[0].flags; + + tcb_desc->use_shortpreamble = false; + + /* 1M can only use Long Preamble. 11B spec */ + if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]) + return; + else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + tcb_desc->use_shortpreamble = true; + + return; +} + +static void _rtl_query_shortgi(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 rate_flag = info->control.rates[0].flags; + + tcb_desc->use_shortgi = false; + + if (!mac->ht_enable) + return; + + if (!mac->sgi_40 && !mac->sgi_20) + return; + + if ((mac->bw_40 == true) && mac->sgi_40) + tcb_desc->use_shortgi = true; + else if ((mac->bw_40 == false) && mac->sgi_20) + tcb_desc->use_shortgi = true; + + if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) + tcb_desc->use_shortgi = false; + +} + +static void _rtl_query_protection_mode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rate_flag = info->control.rates[0].flags; + + /* Common Settings */ + tcb_desc->b_rts_stbc = false; + tcb_desc->b_cts_enable = false; + tcb_desc->rts_sc = 0; + tcb_desc->b_rts_bw = false; + tcb_desc->b_rts_use_shortpreamble = false; + tcb_desc->b_rts_use_shortgi = false; + + if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { + /* Use CTS-to-SELF in protection mode. */ + tcb_desc->b_rts_enable = true; + tcb_desc->b_cts_enable = true; + tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; + } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { + /* Use RTS-CTS in protection mode. */ + tcb_desc->b_rts_enable = true; + tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; + } + +} + +static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { + if (mac->opmode == NL80211_IFTYPE_STATION) + tcb_desc->ratr_index = 0; + else if (mac->opmode == NL80211_IFTYPE_ADHOC) { + if (tcb_desc->b_multicast || tcb_desc->b_broadcast) { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; + tcb_desc->use_driver_rate = 1; + } else { + /* TODO */ + } + } + } + + if (rtlpriv->dm.b_useramask) { + /* TODO we will differentiate adhoc and station futrue */ + tcb_desc->mac_id = 0; + + if ((mac->mode == WIRELESS_MODE_N_24G) || + (mac->mode == WIRELESS_MODE_N_5G)) { + tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; + } else if (mac->mode & WIRELESS_MODE_G) { + tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; + } else if (mac->mode & WIRELESS_MODE_B) { + tcb_desc->ratr_index = RATR_INX_WIRELESS_B; + } + } + +} + +static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + tcb_desc->b_packet_bw = false; + + if (!mac->bw_40 || !mac->ht_enable) + return; + + if (tcb_desc->b_multicast || tcb_desc->b_broadcast) + return; + + /*use legency rate, shall use 20MHz */ + if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]) + return; + + tcb_desc->b_packet_bw = true; +} + +static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 hw_rate; + + if (get_rf_type(rtlphy) == RF_2T2R) + hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]; + else + hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]; + + return hw_rate; +} + +void rtl_get_tcb_desc(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + struct ieee80211_rate *txrate; + u16 fc = le16_to_cpu(hdr->frame_control); + + memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + + if (ieee80211_is_data(fc)) { + txrate = ieee80211_get_tx_rate(hw, info); + tcb_desc->hw_rate = txrate->hw_value; + + /* + *we set data rate RTL_RC_CCK_RATE1M + *in rtl_rc.c if skb is special data or + *mgt which need low data rate. + */ + + /* + *So tcb_desc->hw_rate is just used for + *special data and mgt frames + */ + if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) { + tcb_desc->use_driver_rate = true; + tcb_desc->ratr_index = 7; + + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; + tcb_desc->disable_ratefallback = 1; + } else { + /* + *because hw will nerver use hw_rate + *when tcb_desc->use_driver_rate = false + *so we never set highest N rate here, + *and N rate will all be controled by FW + *when tcb_desc->use_driver_rate = false + */ + if (rtlmac->ht_enable) { + tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw); + } else { + if (rtlmac->mode == WIRELESS_MODE_B) { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]; + } else { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]; + } + } + } + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) + tcb_desc->b_multicast = 1; + else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + tcb_desc->b_broadcast = 1; + + _rtl_txrate_selectmode(hw, tcb_desc); + _rtl_query_bandwidth_mode(hw, tcb_desc); + _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); + _rtl_query_shortgi(hw, tcb_desc, info); + _rtl_query_protection_mode(hw, tcb_desc, info); + } else { + tcb_desc->use_driver_rate = true; + tcb_desc->ratr_index = 7; + tcb_desc->disable_ratefallback = 1; + tcb_desc->mac_id = 0; + + tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; + } +} +EXPORT_SYMBOL(rtl_get_tcb_desc); + +bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + + if (ieee80211_is_auth(fc)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + rtl_ips_nic_on(hw); + + mac->link_state = MAC80211_LINKING; + } + + return true; +} + +bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 fc = le16_to_cpu(hdr->frame_control); + u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); + u8 category; + + if (!ieee80211_is_action(fc)) + return true; + + category = *act; + act++; + switch (category) { + case ACT_CAT_BA: + switch (*act) { + case ACT_ADDBAREQ: + if (mac->act_scanning) + return false; + + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + ("%s ACT_ADDBAREQ From :" MAC_FMT "\n", + is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2))); + break; + case ACT_ADDBARSP: + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + ("%s ACT_ADDBARSP From :" MAC_FMT "\n", + is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2))); + break; + case ACT_DELBA: + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + ("ACT_ADDBADEL From :" MAC_FMT "\n", + MAC_ARG(hdr->addr2))); + break; + } + break; + default: + break; + } + + return true; +} + +/*should call before software enc*/ +u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u16 fc = le16_to_cpu(hdr->frame_control); + u16 ether_type; + u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); + const struct iphdr *ip; + + if (!ieee80211_is_data(fc)) + goto end; + + if (ieee80211_is_nullfunc(fc)) + return true; + + ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + + SNAP_SIZE + PROTOC_TYPE_SIZE); + ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); + ether_type = ntohs(ether_type); + + if (ETH_P_IP == ether_type) { + if (IPPROTO_UDP == ip->protocol) { + struct udphdr *udp = (struct udphdr *)((u8 *) ip + + (ip->ihl << 2)); + if (((((u8 *) udp)[1] == 68) && + (((u8 *) udp)[3] == 67)) || + ((((u8 *) udp)[1] == 67) && + (((u8 *) udp)[3] == 68))) { + /* + * 68 : UDP BOOTP client + * 67 : UDP BOOTP server + */ + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), + DBG_DMESG, ("dhcp %s !!\n", + (is_tx) ? "Tx" : "Rx")); + + if (is_tx) { + rtl_lps_leave(hw); + ppsc->last_delaylps_stamp_jiffies = + jiffies; + } + + return true; + } + } + } else if (ETH_P_ARP == ether_type) { + if (is_tx) { + rtl_lps_leave(hw); + ppsc->last_delaylps_stamp_jiffies = jiffies; + } + + return true; + } else if (ETH_P_PAE == ether_type) { + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx")); + + if (is_tx) { + rtl_lps_leave(hw); + ppsc->last_delaylps_stamp_jiffies = jiffies; + } + + return true; + } else if (0x86DD == ether_type) { + return true; + } + +end: + return false; +} + +/********************************************************* + * + * functions called by core.c + * + *********************************************************/ +int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tid_data *tid_data; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, + ("on ra = %pM tid = %d\n", ra, tid)); + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Start AGG when state is not RTL_AGG_OFF !\n")); + return -ENXIO; + } + + tid_data = &mac->tids[tid]; + *ssn = SEQ_TO_SN(tid_data->seq_number); + + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, + ("HW queue is empty tid:%d\n", tid)); + tid_data->agg.agg_state = RTL_AGG_ON; + + ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid); + + return 0; +} + +int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid) +{ + int ssn = -1; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_tid_data *tid_data; + + if (!ra) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + return -EINVAL; + } + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + if (mac->tids[tid].agg.agg_state != RTL_AGG_ON) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Stopping AGG while state not ON or starting\n")); + + tid_data = &mac->tids[tid]; + ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; + + mac->tids[tid].agg.agg_state = RTL_AGG_OFF; + + ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid); + + return 0; +} + +/********************************************************* + * + * wq & timer callback functions + * + *********************************************************/ +void rtl_watchdog_wq_callback(void *data) +{ + struct rtl_works *rtlworks = container_of_dwork_rtl(data, + struct rtl_works, + watchdog_wq); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + bool b_busytraffic = false; + bool b_higher_busytraffic = false; + bool b_higher_busyrxtraffic = false; + bool b_higher_busytxtraffic = false; + + u8 idx = 0; + u32 rx_cnt_inp4eriod = 0; + u32 tx_cnt_inp4eriod = 0; + u32 aver_rx_cnt_inperiod = 0; + u32 aver_tx_cnt_inperiod = 0; + + bool benter_ps = false; + + if (is_hal_stop(rtlhal)) + return; + + /* <1> Determine if action frame is allowed */ + if (mac->link_state > MAC80211_NOLINK) { + if (mac->cnt_after_linked < 20) + mac->cnt_after_linked++; + } else { + mac->cnt_after_linked = 0; + } + + /* <2> DM */ + rtlpriv->cfg->ops->dm_watchdog(hw); + + /* + *<3> to check if traffic busy, if + * busytraffic we don't change channel + */ + if (mac->link_state >= MAC80211_LINKED) { + + /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */ + for (idx = 0; idx <= 2; idx++) { + rtlpriv->link_info.num_rx_in4period[idx] = + rtlpriv->link_info.num_rx_in4period[idx + 1]; + rtlpriv->link_info.num_tx_in4period[idx] = + rtlpriv->link_info.num_tx_in4period[idx + 1]; + } + rtlpriv->link_info.num_rx_in4period[3] = + rtlpriv->link_info.num_rx_inperiod; + rtlpriv->link_info.num_tx_in4period[3] = + rtlpriv->link_info.num_tx_inperiod; + for (idx = 0; idx <= 3; idx++) { + rx_cnt_inp4eriod += + rtlpriv->link_info.num_rx_in4period[idx]; + tx_cnt_inp4eriod += + rtlpriv->link_info.num_tx_in4period[idx]; + } + aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4; + aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4; + + /* (2) check traffic busy */ + if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) + b_busytraffic = true; + + /* Higher Tx/Rx data. */ + if (aver_rx_cnt_inperiod > 4000 || + aver_tx_cnt_inperiod > 4000) { + b_higher_busytraffic = true; + + /* Extremely high Rx data. */ + if (aver_rx_cnt_inperiod > 5000) + b_higher_busyrxtraffic = true; + else + b_higher_busytxtraffic = false; + } + + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + (rtlpriv->link_info.num_rx_inperiod > 2)) + benter_ps = false; + else + benter_ps = true; + + /* LeisurePS only work in infra mode. */ + if (benter_ps) + rtl_lps_enter(hw); + else + rtl_lps_leave(hw); + } + + rtlpriv->link_info.num_rx_inperiod = 0; + rtlpriv->link_info.num_tx_inperiod = 0; + + rtlpriv->link_info.b_busytraffic = b_busytraffic; + rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic; + rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic; + +} + +void rtl_watch_dog_timer_callback(unsigned long data) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.watchdog_wq, 0); + + mod_timer(&rtlpriv->works.watchdog_timer, + jiffies + MSECS(RTL_WATCH_DOG_TIME)); +} + +/********************************************************* + * + * sysfs functions + * + *********************************************************/ +static ssize_t rtl_show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct ieee80211_hw *hw = dev_get_drvdata(d); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel); +} + +static ssize_t rtl_store_debug_level(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ieee80211_hw *hw = dev_get_drvdata(d); + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret) { + printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf); + } else { + rtlpriv->dbg.global_debuglevel = val; + printk(KERN_DEBUG "debuglevel:%x\n", + rtlpriv->dbg.global_debuglevel); + } + + return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + rtl_show_debug_level, rtl_store_debug_level); + +static struct attribute *rtl_sysfs_entries[] = { + + &dev_attr_debug_level.attr, + + NULL +}; + +/* + * "name" is folder name witch will be + * put in device directory like : + * sys/devices/pci0000:00/0000:00:1c.4/ + * 0000:06:00.0/rtl_sysfs + */ +struct attribute_group rtl_attribute_group = { + .name = "rtlsysfs", + .attrs = rtl_sysfs_entries, +}; + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +static int __init rtl_core_module_init(void) +{ + return 0; +} + +static void __exit rtl_core_module_exit(void) +{ +} + +module_init(rtl_core_module_init); +module_exit(rtl_core_module_exit); diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h new file mode 100644 index 000000000000..3de5a14745f1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/base.h @@ -0,0 +1,120 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + *****************************************************************************/ + +#ifndef __RTL_BASE_H__ +#define __RTL_BASE_H__ + +#define RTL_DUMMY_OFFSET 0 +#define RTL_DUMMY_UNIT 8 +#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) +#define RTL_TX_DESC_SIZE 32 +#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE) + +#define HT_AMSDU_SIZE_4K 3839 +#define HT_AMSDU_SIZE_8K 7935 + +#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ +#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ + +#define RTL_RATE_COUNT_LEGACY 12 +#define RTL_CHANNEL_COUNT 14 + +#define FRAME_OFFSET_FRAME_CONTROL 0 +#define FRAME_OFFSET_DURATION 2 +#define FRAME_OFFSET_ADDRESS1 4 +#define FRAME_OFFSET_ADDRESS2 10 +#define FRAME_OFFSET_ADDRESS3 16 +#define FRAME_OFFSET_SEQUENCE 22 +#define FRAME_OFFSET_ADDRESS4 24 + +#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \ + WRITEEF2BYTE(_hdr, _val) +#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \ + WRITEEF1BYTE(_hdr, _val) +#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \ + SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) +#define SET_80211_HDR_TO_DS(_hdr, _val) \ + SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) + +#define SET_80211_PS_POLL_AID(_hdr, _val) \ + WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val) +#define SET_80211_PS_POLL_BSSID(_hdr, _val) \ + CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val)) +#define SET_80211_PS_POLL_TA(_hdr, _val) \ + CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val)) + +#define SET_80211_HDR_DURATION(_hdr, _val) \ + WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val) +#define SET_80211_HDR_ADDRESS1(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val)) +#define SET_80211_HDR_ADDRESS2(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) +#define SET_80211_HDR_ADDRESS3(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) +#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \ + WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) + +#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \ + WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) +#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ + WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) +#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ + WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) +#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \ + READEF2BYTE(((u8 *)(__phdr)) + 34) +#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ + WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) +#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ + SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ + (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val)))) + +int rtl_init_core(struct ieee80211_hw *hw); +void rtl_deinit_core(struct ieee80211_hw *hw); +void rtl_init_rx_config(struct ieee80211_hw *hw); +void rtl_init_rfkill(struct ieee80211_hw *hw); +void rtl_deinit_rfkill(struct ieee80211_hw *hw); + +void rtl_watch_dog_timer_callback(unsigned long data); +void rtl_deinit_deferred_work(struct ieee80211_hw *hw); + +bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); +bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); +u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); + +void rtl_watch_dog_timer_callback(unsigned long data); +int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, + u16 tid, u16 *ssn); +int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid); +void rtl_watchdog_wq_callback(void *data); + +void rtl_get_tcb_desc(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); + +extern struct attribute_group rtl_attribute_group; +#endif diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c new file mode 100644 index 000000000000..52c9c1367cac --- /dev/null +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ + +#include "wifi.h" +#include "cam.h" + +void rtl_cam_reset_sec_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->sec.use_defaultkey = false; + rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION; + rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION; + memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN); + memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE); + rtlpriv->sec.pairwise_key = NULL; +} + +static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, + u8 *mac_addr, u8 *key_cont_128, u16 us_config) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 target_command; + u32 target_content = 0; + u8 entry_i; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", + key_cont_128[0], key_cont_128[1], + key_cont_128[2], key_cont_128[3], + key_cont_128[4], key_cont_128[5])); + + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + target_command = entry_i + CAM_CONTENT_COUNT * entry_no; + target_command = target_command | BIT(31) | BIT(16); + + if (entry_i == 0) { + target_content = (u32) (*(mac_addr + 0)) << 16 | + (u32) (*(mac_addr + 1)) << 24 | (u32) us_config; + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): " + "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("The Key ID is %d\n", entry_no)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): " + "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command)); + + } else if (entry_i == 1) { + + target_content = (u32) (*(mac_addr + 5)) << 24 | + (u32) (*(mac_addr + 4)) << 16 | + (u32) (*(mac_addr + 3)) << 8 | + (u32) (*(mac_addr + 2)); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): WRITE A4: %x\n", + target_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): WRITE A0: %x\n", + target_command)); + + } else { + + target_content = + (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) << + 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2)) + << 16 | + (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8 + | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0)); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + udelay(100); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): WRITE A4: %x\n", + target_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_program_entry(): WRITE A0: %x\n", + target_command)); + } + } + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("after set key, usconfig:%x\n", us_config)); +} + +u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content) +{ + u32 us_config; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, " + "ulUseDK=%x MacAddr" MAC_FMT "\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, MAC_ARG(mac_addr))); + + if (ul_key_id == TOTAL_CAM_ENTRY) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("<=== ulKeyId exceed!\n")); + return 0; + } + + if (ul_default_key == 1) { + us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2); + } else { + us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id; + } + + rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, + (u8 *) key_content, us_config); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n")); + + return 1; + +} +EXPORT_SYMBOL(rtl_cam_add_one_entry); + +int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, + u8 *mac_addr, u32 ul_key_id) +{ + u32 ul_command; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id)); + + ul_command = ul_key_id * CAM_CONTENT_COUNT; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command)); + + return 0; + +} +EXPORT_SYMBOL(rtl_cam_delete_one_entry); + +void rtl_cam_reset_all_entry(struct ieee80211_hw *hw) +{ + u32 ul_command; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + ul_command = BIT(31) | BIT(30); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); +} +EXPORT_SYMBOL(rtl_cam_reset_all_entry); + +void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 ul_command; + u32 ul_content; + u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case WEP40_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40]; + break; + case WEP104_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104]; + break; + case TKIP_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP]; + break; + case AESCCMP_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + break; + default: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + } + + ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2); + + ul_content |= BIT(15); + ul_command = CAM_CONTENT_COUNT * uc_index; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command)); +} +EXPORT_SYMBOL(rtl_cam_mark_invalid); + +void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 ul_command; + u32 ul_content; + u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + u8 entry_i; + + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case WEP40_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40]; + break; + case WEP104_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104]; + break; + case TKIP_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP]; + break; + case AESCCMP_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + break; + default: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + } + + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + + if (entry_i == 0) { + ul_content = + (uc_index & 0x03) | ((u16) (ul_encalgo) << 2); + ul_content |= BIT(15); + + } else { + ul_content = 0; + } + + ul_command = CAM_CONTENT_COUNT * uc_index + entry_i; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("rtl_cam_empty_entry(): WRITE A4: %x\n", + ul_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("rtl_cam_empty_entry(): WRITE A0: %x\n", + ul_command)); + } + +} +EXPORT_SYMBOL(rtl_cam_empty_entry); diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h new file mode 100644 index 000000000000..dd82f057d53d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ + +#ifndef __RTL_CAM_H_ +#define __RTL_CAM_H_ + +#define TOTAL_CAM_ENTRY 32 +#define CAM_CONTENT_COUNT 8 + +#define CFG_DEFAULT_KEY BIT(5) +#define CFG_VALID BIT(15) + +#define PAIRWISE_KEYIDX 0 +#define CAM_PAIRWISE_KEY_POSITION 4 + +#define CAM_CONFIG_USEDK 1 +#define CAM_CONFIG_NO_USEDK 0 + +extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); +extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content); +int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id); +void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); +void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); +void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c new file mode 100644 index 000000000000..81b290ff8a94 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/core.c @@ -0,0 +1,1029 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + *****************************************************************************/ + +#include "wifi.h" +#include "core.h" +#include "cam.h" +#include "base.h" +#include "ps.h" + +/*mutex for start & stop is must here. */ +static int rtl_op_start(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (!is_hal_stop(rtlhal)) + return 0; + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + return 0; + down(&rtlpriv->locks.conf_sem); + err = rtlpriv->intf_ops->adapter_start(hw); + if (err) + goto out; + rtl_watch_dog_timer_callback((unsigned long)hw); +out: + up(&rtlpriv->locks.conf_sem); + return err; +} + +static void rtl_op_stop(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) + return; + + if (unlikely(ppsc->rfpwr_state == ERFOFF)) { + rtl_ips_nic_on(hw); + mdelay(1); + } + + down(&rtlpriv->locks.conf_sem); + + mac->link_state = MAC80211_NOLINK; + memset(mac->bssid, 0, 6); + + /*reset sec info */ + rtl_cam_reset_sec_info(hw); + + rtl_deinit_deferred_work(hw); + rtlpriv->intf_ops->adapter_stop(hw); + + up(&rtlpriv->locks.conf_sem); +} + +static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) + goto err_free; + + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + goto err_free; + + + rtlpriv->intf_ops->adapter_tx(hw, skb); + + return NETDEV_TX_OK; + +err_free: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +static int rtl_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + int err = 0; + + if (mac->vif) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); + return -EOPNOTSUPP; + } + + rtl_ips_nic_on(hw); + + down(&rtlpriv->locks.conf_sem); + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (mac->beacon_enabled == 1) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("NL80211_IFTYPE_STATION\n")); + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS]); + } + break; + case NL80211_IFTYPE_ADHOC: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("NL80211_IFTYPE_ADHOC\n")); + + mac->link_state = MAC80211_LINKED; + rtlpriv->cfg->ops->set_bcn_reg(hw); + break; + case NL80211_IFTYPE_AP: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("NL80211_IFTYPE_AP\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("operation mode %d is not support!\n", vif->type)); + err = -EOPNOTSUPP; + goto out; + } + + mac->vif = vif; + mac->opmode = vif->type; + rtlpriv->cfg->ops->set_network_type(hw, vif->type); + memcpy(mac->mac_addr, vif->addr, ETH_ALEN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + +out: + up(&rtlpriv->locks.conf_sem); + return err; +} + +static void rtl_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + down(&rtlpriv->locks.conf_sem); + + /* Free beacon resources */ + if ((mac->opmode == NL80211_IFTYPE_AP) || + (mac->opmode == NL80211_IFTYPE_ADHOC) || + (mac->opmode == NL80211_IFTYPE_MESH_POINT)) { + if (mac->beacon_enabled == 1) { + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS]); + } + } + + /* + *Note: We assume NL80211_IFTYPE_UNSPECIFIED as + *NO LINK for our hardware. + */ + mac->vif = NULL; + mac->link_state = MAC80211_NOLINK; + memset(mac->bssid, 0, 6); + mac->opmode = NL80211_IFTYPE_UNSPECIFIED; + rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); + + up(&rtlpriv->locks.conf_sem); +} + + +static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct ieee80211_conf *conf = &hw->conf; + + down(&rtlpriv->locks.conf_sem); + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); + } + + /*For IPS */ + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + if (hw->conf.flags & IEEE80211_CONF_IDLE) + rtl_ips_nic_off(hw); + else + rtl_ips_nic_on(hw); + } else { + /* + *although rfoff may not cause by ips, but we will + *check the reason in set_rf_power_state function + */ + if (unlikely(ppsc->rfpwr_state == ERFOFF)) + rtl_ips_nic_on(hw); + } + + /*For LPS */ + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) + rtl_lps_enter(hw); + else + rtl_lps_leave(hw); + } + + if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count)); + mac->retry_long = hw->conf.long_frame_max_tx_count; + mac->retry_short = hw->conf.long_frame_max_tx_count; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + (u8 *) (&hw->conf. + long_frame_max_tx_count)); + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + struct ieee80211_channel *channel = hw->conf.channel; + u8 wide_chan = (u8) channel->hw_value; + + /* + *because we should back channel to + *current_network.chan in in scanning, + *So if set_chan == current_network.chan + *we should set it. + *because mac80211 tell us wrong bw40 + *info for cisco1253 bw20, so we modify + *it here based on UPPER & LOWER + */ + switch (hw->conf.channel_type) { + case NL80211_CHAN_HT20: + case NL80211_CHAN_NO_HT: + /* SC */ + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_DONT_CARE; + rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; + mac->bw_40 = false; + break; + case NL80211_CHAN_HT40MINUS: + /* SC */ + mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_20_40; + mac->bw_40 = true; + + /*wide channel */ + wide_chan -= 2; + + break; + case NL80211_CHAN_HT40PLUS: + /* SC */ + mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_20_40; + mac->bw_40 = true; + + /*wide channel */ + wide_chan += 2; + + break; + default: + mac->bw_40 = false; + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not processed\n")); + break; + } + + if (wide_chan <= 0) + wide_chan = 1; + rtlphy->current_channel = wide_chan; + + rtlpriv->cfg->ops->set_channel_access(hw); + rtlpriv->cfg->ops->switch_channel(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, + hw->conf.channel_type); + } + + up(&rtlpriv->locks.conf_sem); + + return 0; +} + +static void rtl_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, u64 multicast) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + *new_flags &= RTL_SUPPORTED_FILTERS; + if (!changed_flags) + return; + + /*TODO: we disable broadcase now, so enable here */ + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | + rtlpriv->cfg->maps[MAC_RCR_AB]; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Enable receive multicast frame.\n")); + } else { + mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | + rtlpriv->cfg->maps[MAC_RCR_AB]); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Disable receive multicast frame.\n")); + } + } + + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Enable receive FCS error frame.\n")); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Disable receive FCS error frame.\n")); + } + } + + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + /* + *TODO: BIT(5) is probe response BIT(8) is beacon + *TODO: Use define for BIT(5) and BIT(8) + */ + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) + mac->rx_mgt_filter |= (BIT(5) | BIT(8)); + else + mac->rx_mgt_filter &= ~(BIT(5) | BIT(8)); + } + + if (changed_flags & FIF_CONTROL) { + if (*new_flags & FIF_CONTROL) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; + mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER; + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Enable receive control frame.\n")); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; + mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Disable receive control frame.\n")); + } + } + + if (changed_flags & FIF_OTHER_BSS) { + if (*new_flags & FIF_OTHER_BSS) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Enable receive other BSS's frame.\n")); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("Disable receive other BSS's frame.\n")); + } + } + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, + (u8 *) (&mac->rx_mgt_filter)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, + (u8 *) (&mac->rx_ctrl_filter)); +} + +static int _rtl_get_hal_qnum(u16 queue) +{ + int qnum; + + switch (queue) { + case 0: + qnum = AC3_VO; + break; + case 1: + qnum = AC2_VI; + break; + case 2: + qnum = AC0_BE; + break; + case 3: + qnum = AC1_BK; + break; + default: + qnum = AC0_BE; + break; + } + return qnum; +} + +/* + *for mac80211 VO=0, VI=1, BE=2, BK=3 + *for rtl819x BE=0, BK=1, VI=2, VO=3 + */ +static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *param) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + int aci; + + if (queue >= AC_MAX) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("queue number %d is incorrect!\n", queue)); + return -EINVAL; + } + + aci = _rtl_get_hal_qnum(queue); + mac->ac[aci].aifs = param->aifs; + mac->ac[aci].cw_min = param->cw_min; + mac->ac[aci].cw_max = param->cw_max; + mac->ac[aci].tx_op = param->txop; + memcpy(&mac->edca_param[aci], param, sizeof(*param)); + rtlpriv->cfg->ops->set_qos(hw, aci); + return 0; +} + +static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, u32 changed) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + down(&rtlpriv->locks.conf_sem); + + if ((vif->type == NL80211_IFTYPE_ADHOC) || + (vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_MESH_POINT)) { + + if ((changed & BSS_CHANGED_BEACON) || + (changed & BSS_CHANGED_BEACON_ENABLED && + bss_conf->enable_beacon)) { + + if (mac->beacon_enabled == 0) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + ("BSS_CHANGED_BEACON_ENABLED\n")); + + /*start hw beacon interrupt. */ + /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ + mac->beacon_enabled = 1; + rtlpriv->cfg->ops->update_interrupt_mask(hw, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS], + 0); + } + } else { + if (mac->beacon_enabled == 1) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + ("ADHOC DISABLE BEACON\n")); + + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS]); + } + } + + if (changed & BSS_CHANGED_BEACON_INT) { + RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, + ("BSS_CHANGED_BEACON_INT\n")); + mac->beacon_interval = bss_conf->beacon_int; + rtlpriv->cfg->ops->set_bcn_intv(hw); + } + } + + /*TODO: reference to enum ieee80211_bss_change */ + if (changed & BSS_CHANGED_ASSOC) { + if (bss_conf->assoc) { + mac->link_state = MAC80211_LINKED; + mac->cnt_after_linked = 0; + mac->assoc_id = bss_conf->aid; + memcpy(mac->bssid, bss_conf->bssid, 6); + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + ("BSS_CHANGED_ASSOC\n")); + } else { + if (mac->link_state == MAC80211_LINKED) + rtl_lps_leave(hw); + + mac->link_state = MAC80211_NOLINK; + memset(mac->bssid, 0, 6); + + /* reset sec info */ + rtl_cam_reset_sec_info(hw); + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + ("BSS_CHANGED_UN_ASSOC\n")); + } + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("BSS_CHANGED_ERP_CTS_PROT\n")); + mac->use_cts_protect = bss_conf->use_cts_prot; + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble)); + + mac->short_preamble = bss_conf->use_short_preamble; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, + (u8 *) (&mac->short_preamble)); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("BSS_CHANGED_ERP_SLOT\n")); + + if (bss_conf->use_short_slot) + mac->slot_time = RTL_SLOT_TIME_9; + else + mac->slot_time = RTL_SLOT_TIME_20; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *) (&mac->slot_time)); + } + + if (changed & BSS_CHANGED_HT) { + struct ieee80211_sta *sta = NULL; + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("BSS_CHANGED_HT\n")); + + sta = ieee80211_find_sta(mac->vif, mac->bssid); + + if (sta) { + if (sta->ht_cap.ampdu_density > + mac->current_ampdu_density) + mac->current_ampdu_density = + sta->ht_cap.ampdu_density; + if (sta->ht_cap.ampdu_factor < + mac->current_ampdu_factor) + mac->current_ampdu_factor = + sta->ht_cap.ampdu_factor; + } + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, + (u8 *) (&mac->max_mss_density)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, + &mac->current_ampdu_factor); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, + &mac->current_ampdu_density); + } + + if (changed & BSS_CHANGED_BSSID) { + struct ieee80211_sta *sta = NULL; + u32 basic_rates; + u8 i; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, + (u8 *) bss_conf->bssid); + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); + + memcpy(mac->bssid, bss_conf->bssid, 6); + if (is_valid_ether_addr(bss_conf->bssid)) { + switch (vif->type) { + case NL80211_IFTYPE_UNSPECIFIED: + break; + case NL80211_IFTYPE_ADHOC: + break; + case NL80211_IFTYPE_STATION: + break; + case NL80211_IFTYPE_AP: + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + rtlpriv->cfg->ops->set_network_type(hw, vif->type); + } else + rtlpriv->cfg->ops->set_network_type(hw, + NL80211_IFTYPE_UNSPECIFIED); + + memset(mac->mcs, 0, 16); + mac->ht_enable = false; + mac->sgi_40 = false; + mac->sgi_20 = false; + + if (!bss_conf->use_short_slot) + mac->mode = WIRELESS_MODE_B; + else + mac->mode = WIRELESS_MODE_G; + + sta = ieee80211_find_sta(mac->vif, mac->bssid); + + if (sta) { + if (sta->ht_cap.ht_supported) { + mac->mode = WIRELESS_MODE_N_24G; + mac->ht_enable = true; + } + + if (mac->ht_enable) { + u16 ht_cap = sta->ht_cap.cap; + memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16); + + for (i = 0; i < 16; i++) + RT_TRACE(rtlpriv, COMP_MAC80211, + DBG_LOUD, ("%x ", + mac->mcs[i])); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, + ("\n")); + + if (ht_cap & IEEE80211_HT_CAP_SGI_40) + mac->sgi_40 = true; + + if (ht_cap & IEEE80211_HT_CAP_SGI_20) + mac->sgi_20 = true; + + /* + * for cisco 1252 bw20 it's wrong + * if (ht_cap & + * IEEE80211_HT_CAP_SUP_WIDTH_20_40) { + * mac->bw_40 = true; + * } + */ + } + } + + /*mac80211 just give us CCK rates any time + *So we add G rate in basic rates when + not in B mode*/ + if (changed & BSS_CHANGED_BASIC_RATES) { + if (mac->mode == WIRELESS_MODE_B) + basic_rates = bss_conf->basic_rates | 0x00f; + else + basic_rates = bss_conf->basic_rates | 0xff0; + + if (!vif) + goto out; + + mac->basic_rates = basic_rates; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *) (&basic_rates)); + + if (rtlpriv->dm.b_useramask) + rtlpriv->cfg->ops->update_rate_mask(hw, 0); + else + rtlpriv->cfg->ops->update_rate_table(hw); + + } + } + + /* + * For FW LPS: + * To tell firmware we have connected + * to an AP. For 92SE/CE power save v2. + */ + if (changed & BSS_CHANGED_ASSOC) { + if (bss_conf->assoc) { + if (ppsc->b_fwctrl_lps) { + u8 mstatus = RT_MEDIA_CONNECT; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *) (&mstatus)); + ppsc->report_linked = true; + } + } else { + if (ppsc->b_fwctrl_lps) { + u8 mstatus = RT_MEDIA_DISCONNECT; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)(&mstatus)); + ppsc->report_linked = false; + } + } + } + +out: + up(&rtlpriv->locks.conf_sem); +} + +static u64 rtl_op_get_tsf(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u64 tsf; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf)); + return tsf; +} + +static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;; + + mac->tsf = tsf; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss)); +} + +static void rtl_op_reset_tsf(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp = 0; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp)); +} + +static void rtl_op_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + switch (cmd) { + case STA_NOTIFY_SLEEP: + break; + case STA_NOTIFY_AWAKE: + break; + default: + break; + } +} + +static int rtl_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 * ssn) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (action) { + case IEEE80211_AMPDU_TX_START: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); + return rtl_tx_agg_start(hw, sta->addr, tid, ssn); + break; + case IEEE80211_AMPDU_TX_STOP: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); + return rtl_tx_agg_stop(hw, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); + break; + case IEEE80211_AMPDU_RX_START: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); + break; + case IEEE80211_AMPDU_RX_STOP: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, + ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("IEEE80211_AMPDU_ERR!!!!:\n")); + return -EOPNOTSUPP; + } + return 0; +} + +static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + mac->act_scanning = true; + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + + if (mac->link_state == MAC80211_LINKED) { + rtl_lps_leave(hw); + mac->link_state = MAC80211_LINKED_SCANNING; + } else + rtl_ips_nic_on(hw); + + rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); + rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); +} + +static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + + rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); + mac->act_scanning = false; + if (mac->link_state == MAC80211_LINKED_SCANNING) { + mac->link_state = MAC80211_LINKED; + + /* fix fwlps issue */ + rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); + + if (rtlpriv->dm.b_useramask) + rtlpriv->cfg->ops->update_rate_mask(hw, 0); + else + rtlpriv->cfg->ops->update_rate_table(hw); + + } + +} + +static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 key_type = NO_ENCRYPTION; + u8 key_idx; + bool group_key = false; + bool wep_only = false; + int err = 0; + u8 mac_addr[ETH_ALEN]; + u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 zero_addr[ETH_ALEN] = { 0 }; + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("not open hw encryption\n")); + return -ENOSPC; /*User disabled HW-crypto */ + } + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr)); + rtlpriv->sec.being_setkey = true; + rtl_ips_nic_on(hw); + down(&rtlpriv->locks.conf_sem); + /* <1> get encryption alg */ + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + key_type = WEP40_ENCRYPTION; + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); + rtlpriv->sec.use_defaultkey = true; + break; + case WLAN_CIPHER_SUITE_WEP104: + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("alg:WEP104\n")); + key_type = WEP104_ENCRYPTION; + rtlpriv->sec.use_defaultkey = true; + break; + case WLAN_CIPHER_SUITE_TKIP: + key_type = TKIP_ENCRYPTION; + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); + if (mac->opmode == NL80211_IFTYPE_ADHOC) + rtlpriv->sec.use_defaultkey = true; + break; + case WLAN_CIPHER_SUITE_CCMP: + key_type = AESCCMP_ENCRYPTION; + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); + if (mac->opmode == NL80211_IFTYPE_ADHOC) + rtlpriv->sec.use_defaultkey = true; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("alg_err:%x!!!!:\n", key->cipher)); + goto out_unlock; + } + /* <2> get key_idx */ + key_idx = (u8) (key->keyidx); + if (key_idx > 3) + goto out_unlock; + /* <3> if pairwise key enable_hw_sec */ + group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); + if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || + rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { + if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION && + (key_type == WEP40_ENCRYPTION || + key_type == WEP104_ENCRYPTION)) + wep_only = true; + rtlpriv->sec.pairwise_enc_algorithm = key_type; + rtlpriv->cfg->ops->enable_hw_sec(hw); + } + /* <4> set key based on cmd */ + switch (cmd) { + case SET_KEY: + if (wep_only) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set WEP(group/pairwise) key\n")); + /* Pairwise key with an assigned MAC address. */ + rtlpriv->sec.pairwise_enc_algorithm = key_type; + rtlpriv->sec.group_enc_algorithm = key_type; + /*set local buf about wep key. */ + memcpy(rtlpriv->sec.key_buf[key_idx], + key->key, key->keylen); + rtlpriv->sec.key_len[key_idx] = key->keylen; + memcpy(mac_addr, zero_addr, ETH_ALEN); + } else if (group_key) { /* group key */ + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set group key\n")); + /* group key */ + rtlpriv->sec.group_enc_algorithm = key_type; + /*set local buf about group key. */ + memcpy(rtlpriv->sec.key_buf[key_idx], + key->key, key->keylen); + rtlpriv->sec.key_len[key_idx] = key->keylen; + memcpy(mac_addr, bcast_addr, ETH_ALEN); + } else { /* pairwise key */ + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set pairwise key\n")); + if (!sta) { + RT_ASSERT(false, ("pairwise key withnot" + "mac_addr\n")); + err = -EOPNOTSUPP; + goto out_unlock; + } + /* Pairwise key with an assigned MAC address. */ + rtlpriv->sec.pairwise_enc_algorithm = key_type; + /*set local buf about pairwise key. */ + memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX], + key->key, key->keylen); + rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen; + rtlpriv->sec.pairwise_key = + rtlpriv->sec.key_buf[PAIRWISE_KEYIDX]; + memcpy(mac_addr, sta->addr, ETH_ALEN); + } + rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr, + group_key, key_type, wep_only, + false); + /* <5> tell mac80211 do something: */ + /*must use sw generate IV, or can not work !!!!. */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + key->hw_key_idx = key_idx; + if (key_type == TKIP_ENCRYPTION) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + case DISABLE_KEY: + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("disable key delete one entry\n")); + /*set local buf about wep key. */ + memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); + rtlpriv->sec.key_len[key_idx] = 0; + memcpy(mac_addr, zero_addr, ETH_ALEN); + /* + *mac80211 will delete entrys one by one, + *so don't use rtl_cam_reset_all_entry + *or clear all entry here. + */ + rtl_cam_delete_one_entry(hw, mac_addr, key_idx); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("cmd_err:%x!!!!:\n", cmd)); + } +out_unlock: + up(&rtlpriv->locks.conf_sem); + rtlpriv->sec.being_setkey = false; + return err; +} + +static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + bool radio_state; + bool blocked; + u8 valid = 0; + + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + return; + + down(&rtlpriv->locks.conf_sem); + + /*if Radio On return true here */ + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + + if (valid) { + if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) { + rtlpriv->rfkill.rfkill_state = radio_state; + + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + (KERN_INFO "wireless radio switch turned %s\n", + radio_state ? "on" : "off")); + + blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; + wiphy_rfkill_set_hw_state(hw->wiphy, blocked); + } + } + + up(&rtlpriv->locks.conf_sem); +} + +const struct ieee80211_ops rtl_ops = { + .start = rtl_op_start, + .stop = rtl_op_stop, + .tx = rtl_op_tx, + .add_interface = rtl_op_add_interface, + .remove_interface = rtl_op_remove_interface, + .config = rtl_op_config, + .configure_filter = rtl_op_configure_filter, + .set_key = rtl_op_set_key, + .conf_tx = rtl_op_conf_tx, + .bss_info_changed = rtl_op_bss_info_changed, + .get_tsf = rtl_op_get_tsf, + .set_tsf = rtl_op_set_tsf, + .reset_tsf = rtl_op_reset_tsf, + .sta_notify = rtl_op_sta_notify, + .ampdu_action = rtl_op_ampdu_action, + .sw_scan_start = rtl_op_sw_scan_start, + .sw_scan_complete = rtl_op_sw_scan_complete, + .rfkill_poll = rtl_op_rfkill_poll, +}; diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h new file mode 100644 index 000000000000..0ef31c3c6196 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/core.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * Tmis program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * Tmis 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 + * tmis program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Tme full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + *****************************************************************************/ + +#ifndef __RTL_CORE_H__ +#define __RTL_CORE_H__ + +#define RTL_SUPPORTED_FILTERS \ + (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | FIF_CONTROL | \ + FIF_OTHER_BSS | \ + FIF_FCSFAIL | \ + FIF_BCN_PRBRESP_PROMISC) + +#define RTL_SUPPORTED_CTRL_FILTER 0xFF + +extern const struct ieee80211_ops rtl_ops; +#endif diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c new file mode 100644 index 000000000000..5fa73852cb66 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * Tmis program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * Tmis 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 + * tmis program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Tme full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + *****************************************************************************/ + +#include "wifi.h" + +void rtl_dbgp_flag_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 i; + + rtlpriv->dbg.global_debuglevel = DBG_EMERG; + + rtlpriv->dbg.global_debugcomponents = + COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND | + COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC | + COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC | + COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS | + COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD | + COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN; + + for (i = 0; i < DBGP_TYPE_MAX; i++) + rtlpriv->dbg.dbgp_type[i] = 0; + + /*Init Debug flag enable condition */ +} diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h new file mode 100644 index 000000000000..08bdec2ceda4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * Tmis program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * Tmis 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 + * tmis program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Tme full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + *****************************************************************************/ + +#ifndef __RTL_DEBUG_H__ +#define __RTL_DEBUG_H__ + +/*-------------------------------------------------------------- + Debug level +--------------------------------------------------------------*/ +/* + *Fatal bug. + *For example, Tx/Rx/IO locked up, + *memory access violation, + *resource allocation failed, + *unexpected HW behavior, HW BUG + *and so on. + */ +#define DBG_EMERG 0 + +/* + *Abnormal, rare, or unexpeted cases. + *For example, Packet/IO Ctl canceled, + *device suprisely unremoved and so on. + */ +#define DBG_WARNING 2 + +/* + *Normal case driver developer should + *open, we can see link status like + *assoc/AddBA/DHCP/adapter start and + *so on basic and useful infromations. + */ +#define DBG_DMESG 3 + +/* + *Normal case with useful information + *about current SW or HW state. + *For example, Tx/Rx descriptor to fill, + *Tx/Rx descriptor completed status, + *SW protocol state change, dynamic + *mechanism state change and so on. + */ +#define DBG_LOUD 4 + +/* + *Normal case with detail execution + *flow or information. + */ +#define DBG_TRACE 5 + +/*-------------------------------------------------------------- + Define the rt_trace components +--------------------------------------------------------------*/ +#define COMP_ERR BIT(0) +#define COMP_FW BIT(1) +#define COMP_INIT BIT(2) /*For init/deinit */ +#define COMP_RECV BIT(3) /*For Rx. */ +#define COMP_SEND BIT(4) /*For Tx. */ +#define COMP_MLME BIT(5) /*For MLME. */ +#define COMP_SCAN BIT(6) /*For Scan. */ +#define COMP_INTR BIT(7) /*For interrupt Related. */ +#define COMP_LED BIT(8) /*For LED. */ +#define COMP_SEC BIT(9) /*For sec. */ +#define COMP_BEACON BIT(10) /*For beacon. */ +#define COMP_RATE BIT(11) /*For rate. */ +#define COMP_RXDESC BIT(12) /*For rx desc. */ +#define COMP_DIG BIT(13) /*For DIG */ +#define COMP_TXAGC BIT(14) /*For Tx power */ +#define COMP_HIPWR BIT(15) /*For High Power Mechanism */ +#define COMP_POWER BIT(16) /*For lps/ips/aspm. */ +#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */ +#define COMP_BB_POWERSAVING BIT(18) +#define COMP_SWAS BIT(19) /*For SW Antenna Switch */ +#define COMP_RF BIT(20) /*For RF. */ +#define COMP_TURBO BIT(21) /*For EDCA TURBO. */ +#define COMP_RATR BIT(22) +#define COMP_CMD BIT(23) +#define COMP_EFUSE BIT(24) +#define COMP_QOS BIT(25) +#define COMP_MAC80211 BIT(26) +#define COMP_REGD BIT(27) +#define COMP_CHAN BIT(28) + +/*-------------------------------------------------------------- + Define the rt_print components +--------------------------------------------------------------*/ +/* Define EEPROM and EFUSE check module bit*/ +#define EEPROM_W BIT(0) +#define EFUSE_PG BIT(1) +#define EFUSE_READ_ALL BIT(2) + +/* Define init check for module bit*/ +#define INIT_EEPROM BIT(0) +#define INIT_TxPower BIT(1) +#define INIT_IQK BIT(2) +#define INIT_RF BIT(3) + +/* Define PHY-BB/RF/MAC check module bit */ +#define PHY_BBR BIT(0) +#define PHY_BBW BIT(1) +#define PHY_RFR BIT(2) +#define PHY_RFW BIT(3) +#define PHY_MACR BIT(4) +#define PHY_MACW BIT(5) +#define PHY_ALLR BIT(6) +#define PHY_ALLW BIT(7) +#define PHY_TXPWR BIT(8) +#define PHY_PWRDIFF BIT(9) + +enum dbgp_flag_e { + FQOS = 0, + FTX = 1, + FRX = 2, + FSEC = 3, + FMGNT = 4, + FMLME = 5, + FRESOURCE = 6, + FBEACON = 7, + FISR = 8, + FPHY = 9, + FMP = 10, + FEEPROM = 11, + FPWR = 12, + FDM = 13, + FDBGCtrl = 14, + FC2H = 15, + FBT = 16, + FINIT = 17, + FIOCTL = 18, + DBGP_TYPE_MAX +}; + +#define RT_ASSERT(_exp, fmt) \ + do { \ + if (!(_exp)) { \ + printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \ + __func__); \ + printk fmt; \ + } \ + } while (0); + +#define RT_TRACE(rtlpriv, comp, level, fmt)\ + do { \ + if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ + ((level) <= rtlpriv->dbg.global_debuglevel))) {\ + printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \ + __func__, in_interrupt(), in_atomic()); \ + printk fmt; \ + } \ + } while (0); + +#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ + do { \ + if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + printk printstr; \ + } \ + } while (0); + +#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ + _hexdatalen) \ + do {\ + if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\ + (_level <= rtlpriv->dbg.global_debuglevel))) { \ + int __i; \ + u8* ptr = (u8 *)_hexdata; \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + printk("In process \"%s\" (pid %i):", current->comm,\ + current->pid); \ + printk(_titlestring); \ + for (__i = 0; __i < (int)_hexdatalen; __i++) { \ + printk("%02X%s", ptr[__i], (((__i + 1) % 4)\ + == 0) ? " " : " ");\ + if (((__i + 1) % 16) == 0) \ + printk("\n"); \ + } \ + printk(KERN_DEBUG "\n"); \ + } \ + } while (0); + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) \ + ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2],\ + ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5] + +void rtl_dbgp_flag_init(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c new file mode 100644 index 000000000000..b8433f3a9bc2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -0,0 +1,1189 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * Tmis program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * Tmis 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 + * tmis program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Tme full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "efuse.h" + +static const u8 MAX_PGPKT_SIZE = 9; +static const u8 PGPKT_DATA_SIZE = 8; +static const int EFUSE_MAX_SIZE = 512; + +static const u8 EFUSE_OOB_PROTECT_BYTES = 15; + +static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = { + {0, 0, 0, 2}, + {0, 1, 0, 2}, + {0, 2, 0, 2}, + {1, 0, 0, 1}, + {1, 0, 1, 1}, + {1, 1, 0, 1}, + {1, 1, 1, 3}, + {1, 3, 0, 17}, + {3, 3, 1, 48}, + {10, 0, 0, 6}, + {10, 3, 0, 1}, + {10, 3, 1, 1}, + {11, 0, 0, 28} +}; + +static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, + u8 *pbuf); +static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, + u8 *value); +static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, + u16 *value); +static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset, + u32 *value); +static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset, + u8 value); +static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset, + u16 value); +static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, + u32 value); +static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, + u8 *data); +static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, + u8 data); +static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); +static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, + u8 *data); +static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, + u8 word_en, u8 *data); +static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, + u8 *targetdata); +static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, + u16 efuse_addr, u8 word_en, u8 *data); +static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, + u8 pwrstate); +static u16 efuse_get_current_size(struct ieee80211_hw *hw); +static u8 efuse_calculate_word_cnts(u8 word_en); + +void efuse_initialize(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bytetemp; + u8 temp; + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1); + temp = bytetemp | 0x20; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp); + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1); + temp = bytetemp & 0xFE; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp); + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3); + temp = bytetemp | 0x80; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp); + + rtl_write_byte(rtlpriv, 0x2F8, 0x3); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); + +} + +u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 data; + u8 bytetemp; + u8 temp; + u32 k = 0; + + if (address < EFUSE_REAL_CONTENT_LEN) { + temp = address & 0xFF; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + temp); + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + temp = bytetemp & 0x7F; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, + temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + while (!(bytetemp & 0x80)) { + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg-> + maps[EFUSE_CTRL] + 3); + k++; + if (k == 1000) { + k = 0; + break; + } + } + data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + return data; + } else + return 0xFF; + +} +EXPORT_SYMBOL(efuse_read_1byte); + +void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bytetemp; + u8 temp; + u32 k = 0; + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("Addr=%x Data =%x\n", address, value)); + + if (address < EFUSE_REAL_CONTENT_LEN) { + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); + + temp = address & 0xFF; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + temp); + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + + temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + temp = bytetemp | 0x80; + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + + while (bytetemp & 0x80) { + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg-> + maps[EFUSE_CTRL] + 3); + k++; + if (k == 100) { + k = 0; + break; + } + } + } + +} + +static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 value32; + u8 readbyte; + u16 retry; + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + (_offset & 0xff)); + readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); + + readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, + (readbyte & 0x7f)); + + retry = 0; + value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) { + value32 = rtl_read_dword(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL]); + retry++; + } + + udelay(50); + value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + + *pbuf = (u8) (value32 & 0xff); +} + +void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 efuse_tbl[EFUSE_MAP_LEN]; + u8 rtemp8[1]; + u16 efuse_addr = 0; + u8 offset, wren; + u16 i; + u16 j; + u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; + u16 efuse_utilized = 0; + u8 efuse_usage; + + if ((_offset + _size_byte) > EFUSE_MAP_LEN) { + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("read_efuse(): Invalid offset(%#x) with read " + "bytes(%#x)!!\n", _offset, _size_byte)); + return; + } + + for (i = 0; i < EFUSE_MAX_SECTION; i++) + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + efuse_word[i][j] = 0xFFFF; + + read_efuse_byte(hw, efuse_addr, rtemp8); + if (*rtemp8 != 0xFF) { + efuse_utilized++; + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + ("Addr=%d\n", efuse_addr)); + efuse_addr++; + } + + while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) { + offset = ((*rtemp8 >> 4) & 0x0f); + + if (offset < EFUSE_MAX_SECTION) { + wren = (*rtemp8 & 0x0f); + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + ("offset-%d Worden=%x\n", offset, wren)); + + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + if (!(wren & 0x01)) { + RTPRINT(rtlpriv, FEEPROM, + EFUSE_READ_ALL, ("Addr=%d\n", + efuse_addr)); + + read_efuse_byte(hw, efuse_addr, rtemp8); + efuse_addr++; + efuse_utilized++; + efuse_word[offset][i] = (*rtemp8 & 0xff); + + if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) + break; + + RTPRINT(rtlpriv, FEEPROM, + EFUSE_READ_ALL, ("Addr=%d\n", + efuse_addr)); + + read_efuse_byte(hw, efuse_addr, rtemp8); + efuse_addr++; + efuse_utilized++; + efuse_word[offset][i] |= + (((u16)*rtemp8 << 8) & 0xff00); + + if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) + break; + } + + wren >>= 1; + } + } + + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + ("Addr=%d\n", efuse_addr)); + read_efuse_byte(hw, efuse_addr, rtemp8); + if (*rtemp8 != 0xFF && (efuse_addr < 512)) { + efuse_utilized++; + efuse_addr++; + } + } + + for (i = 0; i < EFUSE_MAX_SECTION; i++) { + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { + efuse_tbl[(i * 8) + (j * 2)] = + (efuse_word[i][j] & 0xff); + efuse_tbl[(i * 8) + ((j * 2) + 1)] = + ((efuse_word[i][j] >> 8) & 0xff); + } + } + + for (i = 0; i < _size_byte; i++) + pbuf[i] = efuse_tbl[_offset + i]; + + rtlefuse->efuse_usedbytes = efuse_utilized; + efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN); + rtlefuse->efuse_usedpercentage = efuse_usage; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, + (u8 *)&efuse_utilized); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, + (u8 *)&efuse_usage); +} + +bool efuse_shadow_update_chk(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 section_idx, i, Base; + u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used; + bool bwordchanged, bresult = true; + + for (section_idx = 0; section_idx < 16; section_idx++) { + Base = section_idx * 8; + bwordchanged = false; + + for (i = 0; i < 8; i = i + 2) { + if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) || + (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i + + 1])) { + words_need++; + bwordchanged = true; + } + } + + if (bwordchanged == true) + hdr_num++; + } + + totalbytes = hdr_num + words_need * 2; + efuse_used = rtlefuse->efuse_usedbytes; + + if ((totalbytes + efuse_used) >= + (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) + bresult = false; + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("efuse_shadow_update_chk(): totalbytes(%#x), " + "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + totalbytes, hdr_num, words_need, efuse_used)); + + return bresult; +} + +void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value) +{ + if (type == 1) + efuse_shadow_read_1byte(hw, offset, (u8 *) value); + else if (type == 2) + efuse_shadow_read_2byte(hw, offset, (u16 *) value); + else if (type == 4) + efuse_shadow_read_4byte(hw, offset, (u32 *) value); + +} + +void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, + u32 value) +{ + if (type == 1) + efuse_shadow_write_1byte(hw, offset, (u8) value); + else if (type == 2) + efuse_shadow_write_2byte(hw, offset, (u16) value); + else if (type == 4) + efuse_shadow_write_4byte(hw, offset, (u32) value); + +} + +bool efuse_shadow_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u16 i, offset, base; + u8 word_en = 0x0F; + u8 first_pg = false; + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n")); + + if (!efuse_shadow_update_chk(hw)) { + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("<---efuse out of capacity!!\n")); + return false; + } + efuse_power_switch(hw, true, true); + + for (offset = 0; offset < 16; offset++) { + + word_en = 0x0F; + base = offset * 8; + + for (i = 0; i < 8; i++) { + if (first_pg == true) { + + word_en &= ~(BIT(i / 2)); + + rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; + } else { + + if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) { + word_en &= ~(BIT(i / 2)); + + rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; + } + } + } + + if (word_en != 0x0F) { + u8 tmpdata[8]; + memcpy((void *)tmpdata, + (void *)(&rtlefuse-> + efuse_map[EFUSE_MODIFY_MAP][base]), 8); + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, + ("U-efuse\n"), tmpdata, 8); + + if (!efuse_pg_packet_write(hw, (u8) offset, word_en, + tmpdata)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("PG section(%#x) fail!!\n", offset)); + break; + } + } + + } + + efuse_power_switch(hw, true, false); + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + + memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n")); + return true; +} + +void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + if (rtlefuse->autoload_failflag == true) { + memset((void *)(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), 128, + 0xFF); + } else + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + + memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + +} +EXPORT_SYMBOL(rtl_efuse_shadow_map_update); + +void efuse_force_write_vendor_Id(struct ieee80211_hw *hw) +{ + u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF }; + + efuse_power_switch(hw, true, true); + + efuse_pg_packet_write(hw, 1, 0xD, tmpdata); + + efuse_power_switch(hw, true, false); + +} + +void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx) +{ +} + +static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, + u16 offset, u8 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; +} + +static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, + u16 offset, u16 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; + +} + +static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, + u16 offset, u32 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24; +} + +static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, + u16 offset, u8 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value; +} + +static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, + u16 offset, u16 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF; + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8; + +} + +static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, + u16 offset, u32 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = + (u8) (value & 0x000000FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = + (u8) ((value >> 8) & 0x0000FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] = + (u8) ((value >> 16) & 0x00FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] = + (u8) ((value >> 24) & 0xFF); + +} + +static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmpidx = 0; + int bresult; + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + (u8) (addr & 0xff)); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + ((u8) ((addr >> 8) & 0x03)) | + (rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2) & + 0xFC)); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); + + while (!(0x80 & rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) + && (tmpidx < 100)) { + tmpidx++; + } + + if (tmpidx < 100) { + *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + bresult = true; + } else { + *data = 0xff; + bresult = false; + } + return bresult; +} + +static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmpidx = 0; + bool bresult; + + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("Addr = %x Data=%x\n", addr, data)); + + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + (rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + + 2) & 0xFC) | (u8) ((addr >> 8) & 0x03)); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2); + + while ((0x80 & rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) + && (tmpidx < 100)) { + tmpidx++; + } + + if (tmpidx < 100) + bresult = true; + else + bresult = false; + + return bresult; +} + +static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) +{ + efuse_power_switch(hw, false, true); + read_efuse(hw, 0, 128, efuse); + efuse_power_switch(hw, false, false); +} + +static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, + u8 efuse_data, u8 offset, u8 *tmpdata, + u8 *readstate) +{ + bool bdataempty = true; + u8 hoffset; + u8 tmpidx; + u8 hworden; + u8 word_cnts; + + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + word_cnts = efuse_calculate_word_cnts(hworden); + + if (hoffset == offset) { + for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { + if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx, + &efuse_data)) { + tmpdata[tmpidx] = efuse_data; + if (efuse_data != 0xff) + bdataempty = true; + } + } + + if (bdataempty == true) + *readstate = PG_STATE_DATA; + else { + *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; + *readstate = PG_STATE_HEADER; + } + + } else { + *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; + *readstate = PG_STATE_HEADER; + } +} + +static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) +{ + u8 readstate = PG_STATE_HEADER; + + bool bcontinual = true; + + u8 efuse_data, word_cnts = 0; + u16 efuse_addr = 0; + u8 hworden; + u8 tmpdata[8]; + + if (data == NULL) + return false; + if (offset > 15) + return false; + + memset((void *)data, PGPKT_DATA_SIZE * sizeof(u8), 0xff); + memset((void *)tmpdata, PGPKT_DATA_SIZE * sizeof(u8), 0xff); + + while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) { + if (readstate & PG_STATE_HEADER) { + if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) + && (efuse_data != 0xFF)) + efuse_read_data_case1(hw, &efuse_addr, + efuse_data, + offset, tmpdata, + &readstate); + else + bcontinual = false; + } else if (readstate & PG_STATE_DATA) { + efuse_word_enable_data_read(hworden, tmpdata, data); + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + readstate = PG_STATE_HEADER; + } + + } + + if ((data[0] == 0xff) && (data[1] == 0xff) && + (data[2] == 0xff) && (data[3] == 0xff) && + (data[4] == 0xff) && (data[5] == 0xff) && + (data[6] == 0xff) && (data[7] == 0xff)) + return false; + else + return true; + +} + +static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, + u8 efuse_data, u8 offset, int *bcontinual, + u8 *write_state, struct pgpkt_struct target_pkt, + int *repeat_times, int *bresult, u8 word_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct tmp_pkt; + int bdataempty = true; + u8 originaldata[8 * sizeof(u8)]; + u8 badworden = 0x0F; + u8 match_word_en, tmp_word_en; + u8 tmpindex; + u8 tmp_header = efuse_data; + u8 tmp_word_cnts; + + tmp_pkt.offset = (tmp_header >> 4) & 0x0F; + tmp_pkt.word_en = tmp_header & 0x0F; + tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); + + if (tmp_pkt.offset != target_pkt.offset) { + efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; + *write_state = PG_STATE_HEADER; + } else { + for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { + u16 address = *efuse_addr + 1 + tmpindex; + if (efuse_one_byte_read(hw, address, + &efuse_data) && (efuse_data != 0xFF)) + bdataempty = false; + } + + if (bdataempty == false) { + efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; + *write_state = PG_STATE_HEADER; + } else { + match_word_en = 0x0F; + if (!((target_pkt.word_en & BIT(0)) | + (tmp_pkt.word_en & BIT(0)))) + match_word_en &= (~BIT(0)); + + if (!((target_pkt.word_en & BIT(1)) | + (tmp_pkt.word_en & BIT(1)))) + match_word_en &= (~BIT(1)); + + if (!((target_pkt.word_en & BIT(2)) | + (tmp_pkt.word_en & BIT(2)))) + match_word_en &= (~BIT(2)); + + if (!((target_pkt.word_en & BIT(3)) | + (tmp_pkt.word_en & BIT(3)))) + match_word_en &= (~BIT(3)); + + if ((match_word_en & 0x0F) != 0x0F) { + badworden = efuse_word_enable_data_write( + hw, *efuse_addr + 1, + tmp_pkt.word_en, + target_pkt.data); + + if (0x0F != (badworden & 0x0F)) { + u8 reorg_offset = offset; + u8 reorg_worden = badworden; + efuse_pg_packet_write(hw, reorg_offset, + reorg_worden, + originaldata); + } + + tmp_word_en = 0x0F; + if ((target_pkt.word_en & BIT(0)) ^ + (match_word_en & BIT(0))) + tmp_word_en &= (~BIT(0)); + + if ((target_pkt.word_en & BIT(1)) ^ + (match_word_en & BIT(1))) + tmp_word_en &= (~BIT(1)); + + if ((target_pkt.word_en & BIT(2)) ^ + (match_word_en & BIT(2))) + tmp_word_en &= (~BIT(2)); + + if ((target_pkt.word_en & BIT(3)) ^ + (match_word_en & BIT(3))) + tmp_word_en &= (~BIT(3)); + + if ((tmp_word_en & 0x0F) != 0x0F) { + *efuse_addr = efuse_get_current_size(hw); + target_pkt.offset = offset; + target_pkt.word_en = tmp_word_en; + } else + *bcontinual = false; + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *bcontinual = false; + *bresult = false; + } + } else { + *efuse_addr += (2 * tmp_word_cnts) + 1; + target_pkt.offset = offset; + target_pkt.word_en = word_en; + *write_state = PG_STATE_HEADER; + } + } + } + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n")); +} + +static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, + int *bcontinual, u8 *write_state, + struct pgpkt_struct target_pkt, + int *repeat_times, int *bresult) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct tmp_pkt; + u8 pg_header; + u8 tmp_header; + u8 originaldata[8 * sizeof(u8)]; + u8 tmp_word_cnts; + u8 badworden = 0x0F; + + pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en; + efuse_one_byte_write(hw, *efuse_addr, pg_header); + efuse_one_byte_read(hw, *efuse_addr, &tmp_header); + + if (tmp_header == pg_header) + *write_state = PG_STATE_DATA; + else if (tmp_header == 0xFF) { + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *bcontinual = false; + *bresult = false; + } + } else { + tmp_pkt.offset = (tmp_header >> 4) & 0x0F; + tmp_pkt.word_en = tmp_header & 0x0F; + + tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); + + memset((void *)originaldata, 8 * sizeof(u8), 0xff); + + if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) { + badworden = efuse_word_enable_data_write(hw, + *efuse_addr + 1, tmp_pkt.word_en, + originaldata); + + if (0x0F != (badworden & 0x0F)) { + u8 reorg_offset = tmp_pkt.offset; + u8 reorg_worden = badworden; + efuse_pg_packet_write(hw, reorg_offset, + reorg_worden, + originaldata); + *efuse_addr = efuse_get_current_size(hw); + } else + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + + 1; + } else + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; + + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *bcontinual = false; + *bresult = false; + } + + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + ("efuse PG_STATE_HEADER-2\n")); + } +} + +static int efuse_pg_packet_write(struct ieee80211_hw *hw, + u8 offset, u8 word_en, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct target_pkt; + u8 write_state = PG_STATE_HEADER; + int bcontinual = true, bdataempty = true, bresult = true; + u16 efuse_addr = 0; + u8 efuse_data; + u8 target_word_cnts = 0; + u8 badworden = 0x0F; + static int repeat_times; + + if (efuse_get_current_size(hw) >= + (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + ("efuse_pg_packet_write error\n")); + return false; + } + + target_pkt.offset = offset; + target_pkt.word_en = word_en; + + memset((void *)target_pkt.data, 8 * sizeof(u8), 0xFF); + + efuse_word_enable_data_read(word_en, data, target_pkt.data); + target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); + + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); + + while (bcontinual && (efuse_addr < + (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { + + if (write_state == PG_STATE_HEADER) { + bdataempty = true; + badworden = 0x0F; + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + ("efuse PG_STATE_HEADER\n")); + + if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && + (efuse_data != 0xFF)) + efuse_write_data_case1(hw, &efuse_addr, + efuse_data, offset, + &bcontinual, + &write_state, target_pkt, + &repeat_times, &bresult, + word_en); + else + efuse_write_data_case2(hw, &efuse_addr, + &bcontinual, + &write_state, + target_pkt, + &repeat_times, + &bresult); + + } else if (write_state == PG_STATE_DATA) { + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + ("efuse PG_STATE_DATA\n")); + badworden = 0x0f; + badworden = + efuse_word_enable_data_write(hw, efuse_addr + 1, + target_pkt.word_en, + target_pkt.data); + + if ((badworden & 0x0F) == 0x0F) { + bcontinual = false; + } else { + efuse_addr = + efuse_addr + (2 * target_word_cnts) + 1; + + target_pkt.offset = offset; + target_pkt.word_en = badworden; + target_word_cnts = + efuse_calculate_word_cnts(target_pkt. + word_en); + write_state = PG_STATE_HEADER; + repeat_times++; + if (repeat_times > EFUSE_REPEAT_THRESHOLD_) { + bcontinual = false; + bresult = false; + } + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + ("efuse PG_STATE_HEADER-3\n")); + } + } + } + + if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); + } + + return true; +} + +static void efuse_word_enable_data_read(u8 word_en, + u8 *sourdata, u8 *targetdata) +{ + if (!(word_en & BIT(0))) { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + + if (!(word_en & BIT(1))) { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + + if (!(word_en & BIT(2))) { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + + if (!(word_en & BIT(3))) { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + +static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, + u16 efuse_addr, u8 word_en, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 tmpaddr; + u16 start_addr = efuse_addr; + u8 badworden = 0x0F; + u8 tmpdata[8]; + + memset((void *)tmpdata, PGPKT_DATA_SIZE, 0xff); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, + ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); + + if (!(word_en & BIT(0))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[0]); + efuse_one_byte_write(hw, start_addr++, data[1]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]); + if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) + badworden &= (~BIT(0)); + } + + if (!(word_en & BIT(1))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[2]); + efuse_one_byte_write(hw, start_addr++, data[3]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]); + if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) + badworden &= (~BIT(1)); + } + + if (!(word_en & BIT(2))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[4]); + efuse_one_byte_write(hw, start_addr++, data[5]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]); + if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) + badworden &= (~BIT(2)); + } + + if (!(word_en & BIT(3))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[6]); + efuse_one_byte_write(hw, start_addr++, data[7]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]); + if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) + badworden &= (~BIT(3)); + } + + return badworden; +} + +static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tempval; + u16 tmpV16; + + if (pwrstate == true) { + tmpV16 = rtl_read_word(rtlpriv, + rtlpriv->cfg->maps[SYS_ISO_CTRL]); + if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { + tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V]; + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_ISO_CTRL], + tmpV16); + } + + tmpV16 = rtl_read_word(rtlpriv, + rtlpriv->cfg->maps[SYS_FUNC_EN]); + if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) { + tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR]; + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16); + } + + tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]); + if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) || + (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) { + tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] | + rtlpriv->cfg->maps[EFUSE_ANA8M]); + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_CLK], tmpV16); + } + } + + if (pwrstate == true) { + if (bwrite == true) { + tempval = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + + 3); + tempval &= 0x0F; + tempval |= (VOLTAGE_V25 << 4); + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + 3, + (tempval | 0x80)); + } + + } else { + if (bwrite == true) { + tempval = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + + 3); + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + 3, + (tempval & 0x7F)); + } + + } + +} + +static u16 efuse_get_current_size(struct ieee80211_hw *hw) +{ + int bcontinual = true; + u16 efuse_addr = 0; + u8 hoffset, hworden; + u8 efuse_data, word_cnts; + + while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) + && (efuse_addr < EFUSE_MAX_SIZE)) { + if (efuse_data != 0xFF) { + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + word_cnts = efuse_calculate_word_cnts(hworden); + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + } else { + bcontinual = false; + } + } + + return efuse_addr; +} + +static u8 efuse_calculate_word_cnts(u8 word_en) +{ + u8 word_cnts = 0; + if (!(word_en & BIT(0))) + word_cnts++; + if (!(word_en & BIT(1))) + word_cnts++; + if (!(word_en & BIT(2))) + word_cnts++; + if (!(word_en & BIT(3))) + word_cnts++; + return word_cnts; +} + +void efuse_reset_loader(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 tmp_u2b; + + tmp_u2b = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN]); + rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], + (tmp_u2b & ~(BIT(12)))); + udelay(10000); + rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], + (tmp_u2b | BIT(12))); + udelay(10000); +} + +bool efuse_program_map(struct ieee80211_hw *hw, char *p_filename, u8 tabletype) +{ + return true; +} diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h new file mode 100644 index 000000000000..2d39a4df181b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_EFUSE_H_ +#define __RTL_EFUSE_H_ + +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_MAP_LEN 128 +#define EFUSE_MAX_SECTION 16 +#define EFUSE_MAX_WORD_UNIT 4 + +#define EFUSE_INIT_MAP 0 +#define EFUSE_MODIFY_MAP 1 + +#define PG_STATE_HEADER 0x01 +#define PG_STATE_WORD_0 0x02 +#define PG_STATE_WORD_1 0x04 +#define PG_STATE_WORD_2 0x08 +#define PG_STATE_WORD_3 0x10 +#define PG_STATE_DATA 0x20 + +#define PG_SWBYTE_H 0x01 +#define PG_SWBYTE_L 0x02 + +#define _POWERON_DELAY_ +#define _PRE_EXECUTE_READ_CMD_ + +#define EFUSE_REPEAT_THRESHOLD_ 3 + +struct efuse_map { + u8 offset; + u8 word_start; + u8 byte_start; + u8 byte_cnts; +}; + +struct pgpkt_struct { + u8 offset; + u8 word_en; + u8 data[8]; +}; + +enum efuse_data_item { + EFUSE_CHIP_ID = 0, + EFUSE_LDO_SETTING, + EFUSE_CLK_SETTING, + EFUSE_SDIO_SETTING, + EFUSE_CCCR, + EFUSE_SDIO_MODE, + EFUSE_OCR, + EFUSE_F0CIS, + EFUSE_F1CIS, + EFUSE_MAC_ADDR, + EFUSE_EEPROM_VER, + EFUSE_CHAN_PLAN, + EFUSE_TXPW_TAB +}; + +enum { + VOLTAGE_V25 = 0x03, + LDOE25_SHIFT = 28, +}; + +struct efuse_priv { + u8 id[2]; + u8 ldo_setting[2]; + u8 clk_setting[2]; + u8 cccr; + u8 sdio_mode; + u8 ocr[3]; + u8 cis0[17]; + u8 cis1[48]; + u8 mac_addr[6]; + u8 eeprom_verno; + u8 channel_plan; + u8 tx_power_b[14]; + u8 tx_power_g[14]; +}; + +extern void efuse_initialize(struct ieee80211_hw *hw); +extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); +extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); +extern void read_efuse(struct ieee80211_hw *hw, u16 _offset, + u16 _size_byte, u8 *pbuf); +extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value); +extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 value); +extern bool efuse_shadow_update(struct ieee80211_hw *hw); +extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); +extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); +extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); +extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); +extern bool efuse_program_map(struct ieee80211_hw *hw, + char *p_filename, u8 tabletype); +extern void efuse_reset_loader(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c new file mode 100644 index 000000000000..bf3b5748ee19 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -0,0 +1,1933 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "core.h" +#include "wifi.h" +#include "pci.h" +#include "base.h" +#include "ps.h" + +static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { + INTEL_VENDOR_ID, + ATI_VENDOR_ID, + AMD_VENDOR_ID, + SIS_VENDOR_ID +}; + +/* Update PCI dependent default settings*/ +static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + + ppsc->reg_rfps_level = 0; + ppsc->b_support_aspm = 0; + + /*Update PCI ASPM setting */ + ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm; + switch (rtlpci->const_pci_aspm) { + case 0: + /*No ASPM */ + break; + + case 1: + /*ASPM dynamically enabled/disable. */ + ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM; + break; + + case 2: + /*ASPM with Clock Req dynamically enabled/disable. */ + ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 3: + /* + * Always enable ASPM and Clock Req + * from initialization to halt. + * */ + ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM); + ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 4: + /* + * Always enable ASPM without Clock Req + * from initialization to halt. + * */ + ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM; + break; + } + + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + + /*Update Radio OFF setting */ + switch (rtlpci->const_hwsw_rfoff_d3) { + case 1: + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + break; + + case 2: + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + break; + + case 3: + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3; + break; + } + + /*Set HW definition to determine if it supports ASPM. */ + switch (rtlpci->const_support_pciaspm) { + case 0:{ + /*Not support ASPM. */ + bool b_support_aspm = false; + ppsc->b_support_aspm = b_support_aspm; + break; + } + case 1:{ + /*Support ASPM. */ + bool b_support_aspm = true; + bool b_support_backdoor = true; + ppsc->b_support_aspm = b_support_aspm; + + /*if(priv->oem_id == RT_CID_TOSHIBA && + !priv->ndis_adapter.amd_l1_patch) + b_support_backdoor = false; */ + + ppsc->b_support_backdoor = b_support_backdoor; + + break; + } + case 2: + /*ASPM value set by chipset. */ + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { + bool b_support_aspm = true; + ppsc->b_support_aspm = b_support_aspm; + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +static bool _rtl_pci_platform_switch_device_pci_aspm( + struct ieee80211_hw *hw, + u8 value) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + bool bresult = false; + + value |= 0x40; + + pci_write_config_byte(rtlpci->pdev, 0x80, value); + + return bresult; +} + +/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ +static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 buffer; + bool bresult = false; + + buffer = value; + + pci_write_config_byte(rtlpci->pdev, 0x81, value); + bresult = true; + + return bresult; +} + +/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ +static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; + u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + /*Retrieve original configuration settings. */ + u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; + u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. + pcibridge_linkctrlreg; + u16 aspmlevel = 0; + + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("PCI(Bridge) UNKNOWN.\n")); + + return; + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + _rtl_pci_switch_clk_req(hw, 0x0); + } + + if (1) { + /*for promising device will in L0 state after an I/O. */ + u8 tmp_u1b; + pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b); + } + + /*Set corresponding value. */ + aspmlevel |= BIT(0) | BIT(1); + linkctrl_reg &= ~aspmlevel; + pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); + + _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); + udelay(50); + + /*4 Disable Pci Bridge ASPM */ + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + (num4bytes << 2)); + rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg); + + udelay(50); + +} + +/* + *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for + *power saving We should follow the sequence to enable + *RTL8192SE first then enable Pci Bridge ASPM + *or the system will show bluescreen. + */ +static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_busnum = pcipriv->ndis_adapter.pcibridge_busnum; + u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum; + u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum; + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; + u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + u16 aspmlevel; + u8 u_pcibridge_aspmsetting; + u8 u_device_aspmsetting; + + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("PCI(Bridge) UNKNOWN.\n")); + return; + } + + /*4 Enable Pci Bridge ASPM */ + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + (num4bytes << 2)); + + u_pcibridge_aspmsetting = + pcipriv->ndis_adapter.pcibridge_linkctrlreg | + rtlpci->const_hostpci_aspm_setting; + + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) + u_pcibridge_aspmsetting &= ~BIT(0); + + rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PlatformEnableASPM():PciBridge busnumber[%x], " + "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), + u_pcibridge_aspmsetting)); + + udelay(50); + + /*Get ASPM level (with/without Clock Req) */ + aspmlevel = rtlpci->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; + + /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/ + /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */ + + u_device_aspmsetting |= aspmlevel; + + _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & + RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + } + udelay(200); +} + +static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; + + bool status = false; + u8 offset_e0; + unsigned offset_e4; + + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + 0xE0); + rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0); + + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + 0xE0); + rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0); + + if (offset_e0 == 0xA0) { + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + 0xE4); + rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4); + if (offset_e4 & BIT(23)) + status = true; + } + + return status; +} + +static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; + u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; + u8 linkctrl_reg; + u8 num4bBytes; + + num4bBytes = (capabilityoffset + 0x10) / 4; + + /*Read Link Control Register */ + rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, + pcicfg_addrport + (num4bBytes << 2)); + rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg); + + pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; +} + +static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + + u8 tmp; + int pos; + u8 linkctrl_reg; + + /*Link Control Register */ + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); + pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg)); + + pci_read_config_byte(pdev, 0x98, &tmp); + tmp |= BIT(4); + pci_write_config_byte(pdev, 0x98, tmp); + + tmp = 0x17; + pci_write_config_byte(pdev, 0x70f, tmp); +} + +static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + _rtl_pci_update_default_setting(hw); + + if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) { + /*Always enable ASPM & Clock Req. */ + rtl_pci_enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM); + } + +} + +static void rtl_pci_init_aspm(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /*close ASPM for AMD defaultly */ + rtlpci->const_amdpci_aspm = 0; + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set defult to RTL8192CE:3 RTL8192E:2 + * */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = 1; + + _rtl_pci_initialize_adapter_common(hw); +} + +static void _rtl_pci_io_handler_init(struct device *dev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->io.dev = dev; + + rtlpriv->io.write8_async = pci_write8_async; + rtlpriv->io.write16_async = pci_write16_async; + rtlpriv->io.write32_async = pci_write32_async; + + rtlpriv->io.read8_sync = pci_read8_sync; + rtlpriv->io.read16_sync = pci_read16_sync; + rtlpriv->io.read32_sync = pci_read32_sync; + +} + +static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw) +{ +} + +static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + + u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true, + HW_DESC_OWN); + + /* + *beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return; + ring->idx = (ring->idx + 1) % ring->entries; + + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(rtlpci->pdev, + le32_to_cpu(rtlpriv->cfg->ops-> + get_desc((u8 *) entry, true, + HW_DESC_TXBUFF_ADDR)), + skb->len, PCI_DMA_TODEVICE); + + RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, + ("new ring->idx:%d, " + "free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *) (skb->data + 22))); + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + info->flags |= IEEE80211_TX_STAT_ACK; + /*info->status.rates[0].count = 1; */ + + ieee80211_tx_status_irqsafe(hw, skb); + + if ((ring->entries - skb_queue_len(&ring->queue)) + == 2) { + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + ("more desc left, wake" + "skb_queue@%d,ring->idx = %d," + "skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue))); + + ieee80211_wake_queue(hw, + skb_get_queue_mapping + (skb)); + } + + skb = NULL; + } + + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + (rtlpriv->link_info.num_rx_inperiod > 2)) { + rtl_lps_leave(hw); + } +} + +static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int rx_queue_idx = RTL_PCI_RX_MPDU_QUEUE; + + struct ieee80211_rx_status rx_status = { 0 }; + unsigned int count = rtlpci->rxringcount; + u8 own; + u8 tmp_one; + u32 bufferaddress; + bool unicast = false; + + struct rtl_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + }; + + /*RX NORMAL PKT */ + while (count--) { + /*rx descriptor */ + struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[ + rtlpci->rx_ring[rx_queue_idx].idx]; + /*rx pkt */ + struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ + rtlpci->rx_ring[rx_queue_idx].idx]; + + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, + false, HW_DESC_OWN); + + if (own) { + /*wait data to be filled by hardware */ + return; + } else { + struct ieee80211_hdr *hdr; + u16 fc; + struct sk_buff *new_skb = NULL; + + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, + &rx_status, + (u8 *) pdesc, skb); + + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + + skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, + false, + HW_DESC_RXPKT_LEN)); + skb_reserve(skb, + stats.rx_drvinfo_size + stats.rx_bufshift); + + /* + *NOTICE This can not be use for mac80211, + *this is done in mac80211 code, + *if you done here sec DHCP will fail + *skb_trim(skb, skb->len - 4); + */ + + hdr = (struct ieee80211_hdr *)(skb->data); + fc = le16_to_cpu(hdr->frame_control); + + if (!stats.b_crc) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, + sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) + ;/*TODO*/ + else { + if (is_multicast_ether_addr(hdr->addr1)) + ;/*TODO*/ + else { + unicast = true; + rtlpriv->stats.rxbytesunicast += + skb->len; + } + } + + rtl_is_special_data(hw, skb, false); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_RX); + + if (unicast) + rtlpriv->link_info. + num_rx_inperiod++; + } + + if (unlikely(!rtl_action_proc(hw, skb, false))) + dev_kfree_skb_any(skb); + else + ieee80211_rx_irqsafe(hw, skb); + } else { + dev_kfree_skb_any(skb); + } + + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + (rtlpriv->link_info.num_rx_inperiod > 2)) { + rtl_lps_leave(hw); + } + + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), + DBG_DMESG, + ("can't alloc skb for rx\n")); + goto done; + } + skb = new_skb; + /*skb->dev = dev; */ + + rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> + rx_ring + [rx_queue_idx]. + idx] = skb; + *((dma_addr_t *) skb->cb) = + pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + + } +done: + bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb)); + tmp_one = 1; + rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, + HW_DESC_RXBUFF_ADDR, + (u8 *)&bufferaddress); + rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, + (u8 *)&tmp_one); + rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, + HW_DESC_RXPKT_LEN, + (u8 *)&rtlpci->rxbuffersize); + + if (rtlpci->rx_ring[rx_queue_idx].idx == + rtlpci->rxringcount - 1) + rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, + HW_DESC_RXERO, + (u8 *)&tmp_one); + + rtlpci->rx_ring[rx_queue_idx].idx = + (rtlpci->rx_ring[rx_queue_idx].idx + 1) % + rtlpci->rxringcount; + } + +} + +void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int prio; + + for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) { + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u8 own; + + /* + *beacon packet will only use the first + *descriptor defautly, and the own may not + *be cleared by the hardware, and + *beacon will free in prepare beacon + */ + if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE || + prio == HCCA_QUEUE) + break; + + own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry, + true, + HW_DESC_OWN); + + if (own) + break; + + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(rtlpci->pdev, + le32_to_cpu(rtlpriv->cfg->ops-> + get_desc((u8 *) entry, + true, + HW_DESC_TXBUFF_ADDR)), + skb->len, PCI_DMA_TODEVICE); + + ring->idx = (ring->idx + 1) % ring->entries; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + info->flags |= IEEE80211_TX_STAT_ACK; + /*info->status.rates[0].count = 1; */ + + ieee80211_tx_status_irqsafe(hw, skb); + + if ((ring->entries - skb_queue_len(&ring->queue)) + == 2 && prio != BEACON_QUEUE) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("more desc left, wake " + "skb_queue@%d,ring->idx = %d," + "skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue))); + + ieee80211_wake_queue(hw, + skb_get_queue_mapping + (skb)); + } + + skb = NULL; + } + } +} + +static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) +{ + struct ieee80211_hw *hw = dev_id; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + unsigned long flags; + u32 inta = 0; + u32 intb = 0; + + if (rtlpci->irq_enabled == 0) + return IRQ_HANDLED; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + /*read ISR: 4/8bytes */ + rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb); + + /*Shared IRQ or HW disappared */ + if (!inta || inta == 0xffff) + goto done; + + /*<1> beacon related */ + if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("beacon ok interrupt!\n")); + } + + if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("beacon err interrupt!\n")); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("beacon interrupt!\n")); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("prepare beacon for interrupt!\n")); + tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); + } + + /*<3> Tx related */ + if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n")); + + if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("Manage ok interrupt!\n")); + _rtl_pci_tx_isr(hw, MGNT_QUEUE); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("HIGH_QUEUE ok interrupt!\n")); + _rtl_pci_tx_isr(hw, HIGH_QUEUE); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("BK Tx OK interrupt!\n")); + _rtl_pci_tx_isr(hw, BK_QUEUE); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("BE TX OK interrupt!\n")); + _rtl_pci_tx_isr(hw, BE_QUEUE); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("VI TX OK interrupt!\n")); + _rtl_pci_tx_isr(hw, VI_QUEUE); + } + + if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + ("Vo TX OK interrupt!\n")); + _rtl_pci_tx_isr(hw, VO_QUEUE); + } + + /*<2> Rx related */ + if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); + tasklet_schedule(&rtlpriv->works.irq_tasklet); + } + + if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("rx descriptor unavailable!\n")); + tasklet_schedule(&rtlpriv->works.irq_tasklet); + } + + if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); + tasklet_schedule(&rtlpriv->works.irq_tasklet); + } + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return IRQ_HANDLED; + +done: + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return IRQ_HANDLED; +} + +static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) +{ + _rtl_pci_rx_interrupt(hw); +} + +static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct ieee80211_hdr *hdr = NULL; + struct ieee80211_tx_info *info = NULL; + struct sk_buff *pskb = NULL; + struct rtl_tx_desc *pdesc = NULL; + unsigned int queue_index; + u8 temp_one = 1; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + /*NB: the beacon data buffer must be 32-bit aligned. */ + pskb = ieee80211_beacon_get(hw, mac->vif); + if (pskb == NULL) + return; + hdr = (struct ieee80211_hdr *)(pskb->data); + info = IEEE80211_SKB_CB(pskb); + + queue_index = BEACON_QUEUE; + + pdesc = &ring->desc[0]; + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, + info, pskb, queue_index); + + __skb_queue_tail(&ring->queue, pskb); + + rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, + (u8 *)&temp_one); + + return; +} + +static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 i; + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + rtlpci->txringcount[i] = RT_TXDESC_NUM; + + /* + *we just alloc 2 desc for beacon queue, + *because we just need first desc in hw beacon. + */ + rtlpci->txringcount[BEACON_QUEUE] = 2; + + /* + *BE queue need more descriptor for performance + *consideration or, No more tx desc will happen, + *and may cause mac80211 mem leakage. + */ + rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE; + + rtlpci->rxbuffersize = 9100; /*2048/1024; */ + rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT; /*64; */ +} + +static void _rtl_pci_init_struct(struct ieee80211_hw *hw, + struct pci_dev *pdev) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtlpci->up_first_time = true; + rtlpci->being_init_adapter = false; + + rtlhal->hw = hw; + rtlpci->pdev = pdev; + + ppsc->b_inactiveps = false; + ppsc->b_leisure_ps = true; + ppsc->b_fwctrl_lps = true; + ppsc->b_reg_fwctrl_lps = 3; + ppsc->reg_max_lps_awakeintvl = 5; + + if (ppsc->b_reg_fwctrl_lps == 1) + ppsc->fwctrl_psmode = FW_PS_MIN_MODE; + else if (ppsc->b_reg_fwctrl_lps == 2) + ppsc->fwctrl_psmode = FW_PS_MAX_MODE; + else if (ppsc->b_reg_fwctrl_lps == 3) + ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; + + /*Tx/Rx related var */ + _rtl_pci_init_trx_var(hw); + + /*IBSS*/ mac->beacon_interval = 100; + + /*AMPDU*/ mac->min_space_cfg = 0; + mac->max_mss_density = 0; + /*set sane AMPDU defaults */ + mac->current_ampdu_density = 7; + mac->current_ampdu_factor = 3; + + /*QOS*/ rtlpci->acm_method = eAcmWay2_SW; + + /*task */ + tasklet_init(&rtlpriv->works.irq_tasklet, + (void (*)(unsigned long))_rtl_pci_irq_tasklet, + (unsigned long)hw); + tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, + (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, + (unsigned long)hw); +} + +static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, + unsigned int prio, unsigned int entries) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_desc *ring; + dma_addr_t dma; + u32 nextdescaddress; + int i; + + ring = pci_alloc_consistent(rtlpci->pdev, + sizeof(*ring) * entries, &dma); + + if (!ring || (unsigned long)ring & 0xFF) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Cannot allocate TX ring (prio = %d)\n", prio)); + return -ENOMEM; + } + + memset(ring, 0, sizeof(*ring) * entries); + rtlpci->tx_ring[prio].desc = ring; + rtlpci->tx_ring[prio].dma = dma; + rtlpci->tx_ring[prio].idx = 0; + rtlpci->tx_ring[prio].entries = entries; + skb_queue_head_init(&rtlpci->tx_ring[prio].queue); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("queue:%d, ring_addr:%p\n", prio, ring)); + + for (i = 0; i < entries; i++) { + nextdescaddress = cpu_to_le32((u32) dma + + ((i + 1) % entries) * + sizeof(*ring)); + + rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), + true, HW_DESC_TX_NEXTDESC_ADDR, + (u8 *)&nextdescaddress); + } + + return 0; +} + +static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_rx_desc *entry = NULL; + int i, rx_queue_idx; + u8 tmp_one = 1; + + /* + *rx_queue_idx 0:RX_MPDU_QUEUE + *rx_queue_idx 1:RX_CMD_QUEUE + */ + for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE; + rx_queue_idx++) { + rtlpci->rx_ring[rx_queue_idx].desc = + pci_alloc_consistent(rtlpci->pdev, + sizeof(*rtlpci->rx_ring[rx_queue_idx]. + desc) * rtlpci->rxringcount, + &rtlpci->rx_ring[rx_queue_idx].dma); + + if (!rtlpci->rx_ring[rx_queue_idx].desc || + (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Cannot allocate RX ring\n")); + return -ENOMEM; + } + + memset(rtlpci->rx_ring[rx_queue_idx].desc, 0, + sizeof(*rtlpci->rx_ring[rx_queue_idx].desc) * + rtlpci->rxringcount); + + rtlpci->rx_ring[rx_queue_idx].idx = 0; + + for (i = 0; i < rtlpci->rxringcount; i++) { + struct sk_buff *skb = + dev_alloc_skb(rtlpci->rxbuffersize); + u32 bufferaddress; + entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; + if (!skb) + return 0; + + /*skb->dev = dev; */ + + rtlpci->rx_ring[rx_queue_idx].rx_buf[i] = skb; + + /* + *just set skb->cb to mapping addr + *for pci_unmap_single use + */ + *((dma_addr_t *) skb->cb) = + pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + + bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); + rtlpriv->cfg->ops->set_desc((u8 *)entry, false, + HW_DESC_RXBUFF_ADDR, + (u8 *)&bufferaddress); + rtlpriv->cfg->ops->set_desc((u8 *)entry, false, + HW_DESC_RXPKT_LEN, + (u8 *)&rtlpci-> + rxbuffersize); + rtlpriv->cfg->ops->set_desc((u8 *) entry, false, + HW_DESC_RXOWN, + (u8 *)&tmp_one); + } + + rtlpriv->cfg->ops->set_desc((u8 *) entry, false, + HW_DESC_RXERO, (u8 *)&tmp_one); + } + return 0; +} + +static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, + unsigned int prio) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + pci_unmap_single(rtlpci->pdev, + le32_to_cpu(rtlpriv->cfg-> + ops->get_desc((u8 *) entry, true, + HW_DESC_TXBUFF_ADDR)), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + pci_free_consistent(rtlpci->pdev, + sizeof(*ring->desc) * ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; +} + +static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) +{ + int i, rx_queue_idx; + + /*rx_queue_idx 0:RX_MPDU_QUEUE */ + /*rx_queue_idx 1:RX_CMD_QUEUE */ + for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE; + rx_queue_idx++) { + for (i = 0; i < rtlpci->rxringcount; i++) { + struct sk_buff *skb = + rtlpci->rx_ring[rx_queue_idx].rx_buf[i]; + if (!skb) + continue; + + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + kfree_skb(skb); + } + + pci_free_consistent(rtlpci->pdev, + sizeof(*rtlpci->rx_ring[rx_queue_idx]. + desc) * rtlpci->rxringcount, + rtlpci->rx_ring[rx_queue_idx].desc, + rtlpci->rx_ring[rx_queue_idx].dma); + rtlpci->rx_ring[rx_queue_idx].desc = NULL; + } +} + +static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int ret; + int i; + + ret = _rtl_pci_init_rx_ring(hw); + if (ret) + return ret; + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { + ret = _rtl_pci_init_tx_ring(hw, i, + rtlpci->txringcount[i]); + if (ret) + goto err_free_rings; + } + + return 0; + +err_free_rings: + _rtl_pci_free_rx_ring(rtlpci); + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + if (rtlpci->tx_ring[i].desc) + _rtl_pci_free_tx_ring(hw, i); + + return 1; +} + +static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 i; + + /*free rx rings */ + _rtl_pci_free_rx_ring(rtlpci); + + /*free tx rings */ + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + _rtl_pci_free_tx_ring(hw, i); + + return 0; +} + +int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int i, rx_queue_idx; + unsigned long flags; + u8 tmp_one = 1; + + /*rx_queue_idx 0:RX_MPDU_QUEUE */ + /*rx_queue_idx 1:RX_CMD_QUEUE */ + for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE; + rx_queue_idx++) { + /* + *force the rx_ring[RX_MPDU_QUEUE/ + *RX_CMD_QUEUE].idx to the first one + */ + if (rtlpci->rx_ring[rx_queue_idx].desc) { + struct rtl_rx_desc *entry = NULL; + + for (i = 0; i < rtlpci->rxringcount; i++) { + entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; + rtlpriv->cfg->ops->set_desc((u8 *) entry, + false, + HW_DESC_RXOWN, + (u8 *)&tmp_one); + } + rtlpci->rx_ring[rx_queue_idx].idx = 0; + } + } + + /* + *after reset, release previous pending packet, + *and force the tx idx to the first one + */ + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { + if (rtlpci->tx_ring[i].desc) { + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i]; + + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = + &ring->desc[ring->idx]; + struct sk_buff *skb = + __skb_dequeue(&ring->queue); + + pci_unmap_single(rtlpci->pdev, + le32_to_cpu(rtlpriv->cfg->ops-> + get_desc((u8 *) + entry, + true, + HW_DESC_TXBUFF_ADDR)), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + ring->idx = 0; + } + } + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + return 0; +} + +unsigned int _rtl_mac_to_hwqueue(u16 fc, + unsigned int mac80211_queue_index) +{ + unsigned int hw_queue_index; + + if (unlikely(ieee80211_is_beacon(fc))) { + hw_queue_index = BEACON_QUEUE; + goto out; + } + + if (ieee80211_is_mgmt(fc)) { + hw_queue_index = MGNT_QUEUE; + goto out; + } + + switch (mac80211_queue_index) { + case 0: + hw_queue_index = VO_QUEUE; + break; + case 1: + hw_queue_index = VI_QUEUE; + break; + case 2: + hw_queue_index = BE_QUEUE;; + break; + case 3: + hw_queue_index = BK_QUEUE; + break; + default: + hw_queue_index = BE_QUEUE; + RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index)); + break; + } + +out: + return hw_queue_index; +} + +int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 idx; + unsigned int queue_index, hw_queue; + unsigned long flags; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + u8 *pda_addr = hdr->addr1; + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + /*ssn */ + u8 *qc = NULL; + u8 tid = 0; + u16 seq_number = 0; + u8 own; + u8 temp_one = 1; + + if (ieee80211_is_mgmt(fc)) + rtl_tx_mgmt_proc(hw, skb); + rtl_action_proc(hw, skb, true); + + queue_index = skb_get_queue_mapping(skb); + hw_queue = _rtl_mac_to_hwqueue(fc, queue_index); + + if (is_multicast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesmulticast += skb->len; + else if (is_broadcast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesbroadcast += skb->len; + else + rtlpriv->stats.txbytesunicast += skb->len; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + ring = &rtlpci->tx_ring[hw_queue]; + if (hw_queue != BEACON_QUEUE) + idx = (ring->idx + skb_queue_len(&ring->queue)) % + ring->entries; + else + idx = 0; + + pdesc = &ring->desc[idx]; + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, + true, HW_DESC_OWN); + + if ((own == 1) && (hw_queue != BEACON_QUEUE)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("No more TX desc@%d, ring->idx = %d," + "idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue))); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return skb->len; + } + + /* + *if(ieee80211_is_nullfunc(fc)) { + * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + * return 1; + *} + */ + + if (ieee80211_is_data_qos(fc)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + + seq_number = mac->tids[tid].seq_number; + seq_number &= IEEE80211_SCTL_SEQ; + /* + *hdr->seq_ctrl = hdr->seq_ctrl & + *cpu_to_le16(IEEE80211_SCTL_FRAG); + *hdr->seq_ctrl |= cpu_to_le16(seq_number); + */ + + seq_number += 1; + } + + if (ieee80211_is_data(fc)) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); + + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, + info, skb, hw_queue); + + __skb_queue_tail(&ring->queue, skb); + + rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, + HW_DESC_OWN, (u8 *)&temp_one); + + if (!ieee80211_has_morefrags(hdr->frame_control)) { + if (qc) + mac->tids[tid].seq_number = seq_number; + } + + if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && + hw_queue != BEACON_QUEUE) { + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + ("less desc left, stop skb_queue@%d, " + "ring->idx = %d," + "idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue))); + + ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); + } + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, hw_queue); + + return 0; +} + +void rtl_pci_deinit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + _rtl_pci_deinit_trx_ring(hw); + + synchronize_irq(rtlpci->pdev->irq); + tasklet_kill(&rtlpriv->works.irq_tasklet); + + flush_workqueue(rtlpriv->works.rtl_wq); + destroy_workqueue(rtlpriv->works.rtl_wq); + +} + +int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + _rtl_pci_init_struct(hw, pdev); + + err = _rtl_pci_init_trx_ring(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("tx ring initialization failed")); + return err; + } + + return 1; +} + +int rtl_pci_start(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + int err; + + rtl_pci_reset_trx_ring(hw); + + rtlpci->driver_is_goingto_unload = false; + err = rtlpriv->cfg->ops->hw_init(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Failed to config hardware!\n")); + return err; + } + + rtlpriv->cfg->ops->enable_interrupt(hw); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n")); + + rtl_init_rx_config(hw); + + /*should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); + + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + rtlpci->up_first_time = false; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + return 0; +} + +void rtl_pci_stop(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flags; + u8 RFInProgressTimeOut = 0; + + /* + *should before disable interrrupt&adapter + *and will do it immediately. + */ + set_hal_stop(rtlhal); + + rtlpriv->cfg->ops->disable_interrupt(hw); + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + while (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + if (RFInProgressTimeOut > 100) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + break; + } + mdelay(1); + RFInProgressTimeOut++; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + } + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + + rtlpci->driver_is_goingto_unload = true; + rtlpriv->cfg->ops->hw_disable(hw); + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + + rtl_pci_enable_aspm(hw); +} + +static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct pci_dev *bridge_pdev = pdev->bus->self; + u16 venderid; + u16 deviceid; + u8 revisionid; + u16 irqline; + u8 tmp; + + venderid = pdev->vendor; + deviceid = pdev->device; + pci_read_config_byte(pdev, 0x8, &revisionid); + pci_read_config_word(pdev, 0x3C, &irqline); + + if (deviceid == RTL_PCI_8192_DID || + deviceid == RTL_PCI_0044_DID || + deviceid == RTL_PCI_0047_DID || + deviceid == RTL_PCI_8192SE_DID || + deviceid == RTL_PCI_8174_DID || + deviceid == RTL_PCI_8173_DID || + deviceid == RTL_PCI_8172_DID || + deviceid == RTL_PCI_8171_DID) { + switch (revisionid) { + case RTL_PCI_REVISION_ID_8192PCIE: + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("8192 PCI-E is found - " + "vid/did=%x/%x\n", venderid, deviceid)); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; + break; + case RTL_PCI_REVISION_ID_8192SE: + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("8192SE is found - " + "vid/did=%x/%x\n", venderid, deviceid)); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Err: Unknown device - " + "vid/did=%x/%x\n", venderid, deviceid)); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; + break; + + } + } else if (deviceid == RTL_PCI_8192CET_DID || + deviceid == RTL_PCI_8192CE_DID || + deviceid == RTL_PCI_8191CE_DID || + deviceid == RTL_PCI_8188CE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("8192C PCI-E is found - " + "vid/did=%x/%x\n", venderid, deviceid)); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Err: Unknown device -" + " vid/did=%x/%x\n", venderid, deviceid)); + + rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; + } + + /*find bus info */ + pcipriv->ndis_adapter.busnumber = pdev->bus->number; + pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); + pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); + + /*find bridge info */ + pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { + pcipriv->ndis_adapter.pcibridge_vendor = tmp; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Pci Bridge Vendor is found index: %d\n", + tmp)); + break; + } + } + + if (pcipriv->ndis_adapter.pcibridge_vendor != + PCI_BRIDGE_VENDOR_UNKNOWN) { + pcipriv->ndis_adapter.pcibridge_busnum = + bridge_pdev->bus->number; + pcipriv->ndis_adapter.pcibridge_devnum = + PCI_SLOT(bridge_pdev->devfn); + pcipriv->ndis_adapter.pcibridge_funcnum = + PCI_FUNC(bridge_pdev->devfn); + pcipriv->ndis_adapter.pcibridge_pciehdr_offset = + bridge_pdev->pcie_cap; + pcipriv->ndis_adapter.pcicfg_addrport = + (pcipriv->ndis_adapter.pcibridge_busnum << 16) | + (pcipriv->ndis_adapter.pcibridge_devnum << 11) | + (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31); + pcipriv->ndis_adapter.num4bytes = + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; + + rtl_pci_get_linkcontrol_field(hw); + + if (pcipriv->ndis_adapter.pcibridge_vendor == + PCI_BRIDGE_VENDOR_AMD) { + pcipriv->ndis_adapter.amd_l1_patch = + rtl_pci_get_amd_l1_patch(hw); + } + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("pcidev busnumber:devnumber:funcnumber:" + "vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("pci_bridge busnumber:devnumber:funcnumber:vendor:" + "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch)); + + rtl_pci_parse_configuration(pdev, hw); + + return true; +} + +int __devinit rtl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct ieee80211_hw *hw = NULL; + + struct rtl_priv *rtlpriv = NULL; + struct rtl_pci_priv *pcipriv = NULL; + struct rtl_pci *rtlpci; + unsigned long pmem_start, pmem_len, pmem_flags; + int err; + + err = pci_enable_device(pdev); + if (err) { + RT_ASSERT(false, + ("%s : Cannot enable new PCI device\n", + pci_name(pdev))); + return err; + } + + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { + RT_ASSERT(false, ("Unable to obtain 32bit DMA " + "for consistent allocations\n")); + pci_disable_device(pdev); + return -ENOMEM; + } + } + + pci_set_master(pdev); + + hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) + + sizeof(struct rtl_priv), &rtl_ops); + if (!hw) { + RT_ASSERT(false, + ("%s : ieee80211 alloc failed\n", pci_name(pdev))); + err = -ENOMEM; + goto fail1; + } + + SET_IEEE80211_DEV(hw, &pdev->dev); + pci_set_drvdata(pdev, hw); + + rtlpriv = hw->priv; + pcipriv = (void *)rtlpriv->priv; + pcipriv->dev.pdev = pdev; + + /* + *init dbgp flags before all + *other functions, because we will + *use it in other funtions like + *RT_TRACE/RT_PRINT/RTL_PRINT_DATA + *you can not use these macro + *before this + */ + rtl_dbgp_flag_init(hw); + + /* MEM map */ + err = pci_request_regions(pdev, KBUILD_MODNAME); + if (err) { + RT_ASSERT(false, ("Can't obtain PCI resources\n")); + return err; + } + + pmem_start = pci_resource_start(pdev, 2); + pmem_len = pci_resource_len(pdev, 2); + pmem_flags = pci_resource_flags(pdev, 2); + + /*shared mem start */ + rtlpriv->io.pci_mem_start = + (unsigned long)pci_iomap(pdev, 2, pmem_len); + if (rtlpriv->io.pci_mem_start == 0) { + RT_ASSERT(false, ("Can't map PCI mem\n")); + goto fail2; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("mem mapped space: start: 0x%08lx len:%08lx " + "flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start)); + + /* Disable Clk Request */ + pci_write_config_byte(pdev, 0x81, 0); + /* leave D3 mode */ + pci_write_config_byte(pdev, 0x44, 0); + pci_write_config_byte(pdev, 0x04, 0x06); + pci_write_config_byte(pdev, 0x04, 0x07); + + /* init cfg & intf_ops */ + rtlpriv->rtlhal.interface = INTF_PCI; + rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); + rtlpriv->intf_ops = &rtl_pci_ops; + + /* find adapter */ + _rtl_pci_find_adapter(pdev, hw); + + /* Init IO handler */ + _rtl_pci_io_handler_init(&pdev->dev, hw); + + /*like read eeprom and so on */ + rtlpriv->cfg->ops->read_eeprom_info(hw); + + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't init_sw_vars.\n")); + goto fail3; + } + + rtlpriv->cfg->ops->init_sw_leds(hw); + + /*aspm */ + rtl_pci_init_aspm(hw); + + /* Init mac80211 sw */ + err = rtl_init_core(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't allocate sw for mac80211.\n")); + goto fail3; + } + + /* Init PCI sw */ + err = !rtl_pci_init(hw, pdev); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to init PCI.\n")); + goto fail3; + } + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't register mac80211 hw.\n")); + goto fail3; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + + err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("failed to create sysfs device attributes\n")); + goto fail3; + } + + /*init rfkill */ + rtl_init_rfkill(hw); + + rtlpci = rtl_pcidev(pcipriv); + err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, + IRQF_SHARED, KBUILD_MODNAME, hw); + if (err) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy))); + goto fail3; + } else { + rtlpci->irq_alloc = 1; + } + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + +fail3: + pci_set_drvdata(pdev, NULL); + rtl_deinit_core(hw); + _rtl_pci_io_handler_release(hw); + ieee80211_free_hw(hw); + + if (rtlpriv->io.pci_mem_start != 0) + pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); + +fail2: + pci_release_regions(pdev); + +fail1: + + pci_disable_device(pdev); + + return -ENODEV; + +} +EXPORT_SYMBOL(rtl_pci_probe); + +void rtl_pci_disconnect(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + + clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); + + /*ieee80211_unregister_hw will call ops_stop */ + if (rtlmac->mac80211_registered == 1) { + ieee80211_unregister_hw(hw); + rtlmac->mac80211_registered = 0; + } else { + rtl_deinit_deferred_work(hw); + rtlpriv->intf_ops->adapter_stop(hw); + } + + /*deinit rfkill */ + rtl_deinit_rfkill(hw); + + rtl_pci_deinit(hw); + rtl_deinit_core(hw); + rtlpriv->cfg->ops->deinit_sw_leds(hw); + _rtl_pci_io_handler_release(hw); + rtlpriv->cfg->ops->deinit_sw_vars(hw); + + if (rtlpci->irq_alloc) { + free_irq(rtlpci->pdev->irq, hw); + rtlpci->irq_alloc = 0; + } + + if (rtlpriv->io.pci_mem_start != 0) { + pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); + pci_release_regions(pdev); + } + + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtl_pci_disconnect); + +/*************************************** +kernel pci power state define: +PCI_D0 ((pci_power_t __force) 0) +PCI_D1 ((pci_power_t __force) 1) +PCI_D2 ((pci_power_t __force) 2) +PCI_D3hot ((pci_power_t __force) 3) +PCI_D3cold ((pci_power_t __force) 4) +PCI_UNKNOWN ((pci_power_t __force) 5) + +This function is called when system +goes into suspend state mac80211 will +call rtl_mac_stop() from the mac80211 +suspend function first, So there is +no need to call hw_disable here. +****************************************/ +int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} +EXPORT_SYMBOL(rtl_pci_suspend); + +int rtl_pci_resume(struct pci_dev *pdev) +{ + int ret; + + pci_set_power_state(pdev, PCI_D0); + ret = pci_enable_device(pdev); + if (ret) { + RT_ASSERT(false, ("ERR: <======\n")); + return ret; + } + + pci_restore_state(pdev); + + return 0; +} +EXPORT_SYMBOL(rtl_pci_resume); + +struct rtl_intf_ops rtl_pci_ops = { + .adapter_start = rtl_pci_start, + .adapter_stop = rtl_pci_stop, + .adapter_tx = rtl_pci_tx, + .reset_trx_ring = rtl_pci_reset_trx_ring, + + .disable_aspm = rtl_pci_disable_aspm, + .enable_aspm = rtl_pci_enable_aspm, +}; diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h new file mode 100644 index 000000000000..cdde8583ad31 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_PCI_H__ +#define __RTL_PCI_H__ + +#include +/* +1: MSDU packet queue, +2: Rx Command Queue +*/ +#define RTL_PCI_RX_MPDU_QUEUE 0 +#define RTL_PCI_RX_CMD_QUEUE 1 +#define RTL_PCI_MAX_RX_QUEUE 2 + +#define RTL_PCI_MAX_RX_COUNT 64 +#define RTL_PCI_MAX_TX_QUEUE_COUNT 9 + +#define RT_TXDESC_NUM 128 +#define RT_TXDESC_NUM_BE_QUEUE 256 + +#define BK_QUEUE 0 +#define BE_QUEUE 1 +#define VI_QUEUE 2 +#define VO_QUEUE 3 +#define BEACON_QUEUE 4 +#define TXCMD_QUEUE 5 +#define MGNT_QUEUE 6 +#define HIGH_QUEUE 7 +#define HCCA_QUEUE 8 + +#define RTL_PCI_DEVICE(vend, dev, cfg) \ + .vendor = (vend), \ + .device = (dev), \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID,\ + .driver_data = (kernel_ulong_t)&(cfg) + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define PCI_MAX_BRIDGE_NUMBER 255 +#define PCI_MAX_DEVICES 32 +#define PCI_MAX_FUNCTION 8 + +#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */ +#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */ + +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 +#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 +#define PCI_CAP_ID_EXP 0x10 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */ +#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */ +#define RTL_PCI_8174_DID 0x8174 /*8192 SE */ +#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ +#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ +#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ +#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ +#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ +#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ +#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */ +#define RTL_PCI_700F_DID 0x700F +#define RTL_PCI_701F_DID 0x701F +#define RTL_PCI_DLINK_DID 0x3304 +#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */ +#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */ +#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */ +#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */ +#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */ +#define RTL_PCI_8192DE_DID 0x092D /*8192ce */ +#define RTL_PCI_8192DU_DID 0x092D /*8192ce */ + +/*8192 support 16 pages of IO registers*/ +#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 +#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000 + +#define RTL_PCI_REVISION_ID_8190PCI 0x00 +#define RTL_PCI_REVISION_ID_8192PCIE 0x01 +#define RTL_PCI_REVISION_ID_8192SE 0x10 +#define RTL_PCI_REVISION_ID_8192CE 0x1 +#define RTL_PCI_REVISION_ID_8192DE 0x0 + +#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */ + PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/ + PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/ + PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/ + PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/ + PCI_BRIDGE_VENDOR_MAX, +}; + +struct rtl_rx_desc { + u32 dword[8]; +} __attribute__ ((packed)); + +struct rtl_tx_desc { + u32 dword[16]; +} __attribute__ ((packed)); + +struct rtl_tx_cmd_desc { + u32 dword[16]; +} __attribute__ ((packed)); + +struct rtl8192_tx_ring { + struct rtl_tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; +}; + +struct rtl8192_rx_ring { + struct rtl_rx_desc *desc; + dma_addr_t dma; + unsigned int idx; + struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT]; +}; + +struct rtl_pci { + struct pci_dev *pdev; + + bool driver_is_goingto_unload; + bool up_first_time; + bool being_init_adapter; + bool irq_enabled; + + /*Tx */ + struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT]; + int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT]; + u32 transmit_config; + + /*Rx */ + struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE]; + int rxringcount; + u16 rxbuffersize; + u32 receive_config; + + /*irq */ + u8 irq_alloc; + u32 irq_mask[2]; + + /*Bcn control register setting */ + u32 reg_bcn_ctrl_val; + + /*ASPM*/ u8 const_pci_aspm; + u8 const_amdpci_aspm; + u8 const_hwsw_rfoff_d3; + u8 const_support_pciaspm; + /*pci-e bridge */ + u8 const_hostpci_aspm_setting; + /*pci-e device */ + u8 const_devicepci_aspm_setting; + /*If it supports ASPM, Offset[560h] = 0x40, + otherwise Offset[560h] = 0x00. */ + bool b_support_aspm; + bool b_support_backdoor; + + /*QOS & EDCA */ + enum acm_method acm_method; +}; + +struct mp_adapter { + u8 linkctrl_reg; + + u8 busnumber; + u8 devnumber; + u8 funcnumber; + + u8 pcibridge_busnum; + u8 pcibridge_devnum; + u8 pcibridge_funcnum; + + u8 pcibridge_vendor; + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + + u32 pcicfg_addrport; + u8 num4bytes; + + u8 pcibridge_pciehdr_offset; + u8 pcibridge_linkctrlreg; + + bool amd_l1_patch; +}; + +struct rtl_pci_priv { + struct rtl_pci dev; + struct mp_adapter ndis_adapter; + struct rtl_led_ctl ledctl; +}; + +#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv)) +#define rtl_pcidev(pcipriv) (&((pcipriv)->dev)) + +int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw); + +extern struct rtl_intf_ops rtl_pci_ops; + +int __devinit rtl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +void rtl_pci_disconnect(struct pci_dev *pdev); +int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state); +int rtl_pci_resume(struct pci_dev *pdev); + +static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return readw((u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return readl((u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) +{ + writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write16_async(struct rtl_priv *rtlpriv, + u32 addr, u16 val) +{ + writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write32_async(struct rtl_priv *rtlpriv, + u32 addr, u32 val) +{ + writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr); +} + +static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) +{ + outl(val, port); +} + +static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val) +{ + outb(val, port); +} + +static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval) +{ + *pval = inb(port); +} + +static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval) +{ + *pval = inw(port); +} + +static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval) +{ + *pval = inl(port); +} + +#endif diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c new file mode 100644 index 000000000000..fd77cd508f50 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -0,0 +1,492 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "ps.h" + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool init_status = true; + + /*<1> reset trx ring */ + if (rtlhal->interface == INTF_PCI) + rtlpriv->intf_ops->reset_trx_ring(hw); + + if (is_hal_stop(rtlhal)) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Driver is already down!\n")); + + /*<2> Enable Adapter */ + rtlpriv->cfg->ops->hw_init(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + /*init_status = false; */ + + /*<3> Enable Interrupt */ + rtlpriv->cfg->ops->enable_interrupt(hw); + + /* */ + rtl_watch_dog_timer_callback((unsigned long)hw); + + return init_status; +} +EXPORT_SYMBOL(rtl_ps_enable_nic); + +bool rtl_ps_disable_nic(struct ieee80211_hw *hw) +{ + bool status = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /*<1> Stop all timer */ + rtl_deinit_deferred_work(hw); + + /*<2> Disable Interrupt */ + rtlpriv->cfg->ops->disable_interrupt(hw); + + /*<3> Disable Adapter */ + rtlpriv->cfg->ops->hw_disable(hw); + + return status; +} +EXPORT_SYMBOL(rtl_ps_disable_nic); + +bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, + enum rf_pwrstate state_toset, + u32 changesource, bool protect_or_not) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + bool b_actionallowed = false; + u16 rfwait_cnt = 0; + unsigned long flag; + + /*protect_or_not = true; */ + + if (protect_or_not) + goto no_protect; + + /* + *Only one thread can change + *the RF state at one time, and others + *should wait to be executed. + */ + while (true) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, + flag); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("RF Change in progress!" + "Wait to set..state_toset(%d).\n", + state_toset)); + + /* Set RF after the previous action is done. */ + while (ppsc->rfchange_inprogress) { + rfwait_cnt++; + mdelay(1); + + /* + *Wait too long, return false to avoid + *to be stuck here. + */ + if (rfwait_cnt > 100) + return false; + } + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, + flag); + break; + } + } + +no_protect: + rtstate = ppsc->rfpwr_state; + + switch (state_toset) { + case ERFON: + ppsc->rfoff_reason &= (~changesource); + + if ((changesource == RF_CHANGE_BY_HW) && + (ppsc->b_hwradiooff == true)) { + ppsc->b_hwradiooff = false; + } + + if (!ppsc->rfoff_reason) { + ppsc->rfoff_reason = 0; + b_actionallowed = true; + } + + break; + + case ERFOFF: + + if ((changesource == RF_CHANGE_BY_HW) + && (ppsc->b_hwradiooff == false)) { + ppsc->b_hwradiooff = true; + } + + ppsc->rfoff_reason |= changesource; + b_actionallowed = true; + break; + + case ERFSLEEP: + ppsc->rfoff_reason |= changesource; + b_actionallowed = true; + break; + + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + if (b_actionallowed) + rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); + + if (!protect_or_not) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + return b_actionallowed; +} +EXPORT_SYMBOL(rtl_ps_set_rf_state); + +static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + ppsc->b_swrf_processing = true; + + if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, + RF_CHANGE_BY_IPS, false); + + if (ppsc->inactive_pwrstate == ERFOFF && + rtlhal->interface == INTF_PCI) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + ppsc->b_swrf_processing = false; +} + +void rtl_ips_nic_off_wq_callback(void *data) +{ + struct rtl_works *rtlworks = + container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + if (mac->opmode != NL80211_IFTYPE_STATION) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("not station return\n")); + return; + } + + if (is_hal_stop(rtlhal)) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (ppsc->b_inactiveps) { + rtstate = ppsc->rfpwr_state; + + /* + *Do not enter IPS in the following conditions: + *(1) RF is already OFF or Sleep + *(2) b_swrf_processing (indicates the IPS is still under going) + *(3) Connectted (only disconnected can trigger IPS) + *(4) IBSS (send Beacon) + *(5) AP mode (send Beacon) + *(6) monitor mode (rcv packet) + */ + + if (rtstate == ERFON && + !ppsc->b_swrf_processing && + (mac->link_state == MAC80211_NOLINK) && + !mac->act_scanning) { + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("IPSEnter(): Turn off RF.\n")); + + ppsc->inactive_pwrstate = ERFOFF; + ppsc->b_in_powersavemode = true; + + /*rtl_pci_reset_trx_ring(hw); */ + _rtl_ps_inactive_ps(hw); + } + } +} + +void rtl_ips_nic_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* + *because when link with ap, mac80211 will ask us + *to disable nic quickly after scan before linking, + *this will cause link failed, so we delay 100ms here + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ips_nic_off_wq, MSECS(100)); +} + +void rtl_ips_nic_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + down(&rtlpriv->locks.ips_sem); + + if (ppsc->b_inactiveps) { + rtstate = ppsc->rfpwr_state; + + if (rtstate != ERFON && + !ppsc->b_swrf_processing && + ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { + + ppsc->inactive_pwrstate = ERFON; + ppsc->b_in_powersavemode = false; + + _rtl_ps_inactive_ps(hw); + } + } + + up(&rtlpriv->locks.ips_sem); +} + +/*for FW LPS*/ + +/* + *Determine if we can set Fw into PS mode + *in current condition.Return TRUE if it + *can enter PS mode. + */ +static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u32 ps_timediff; + + ps_timediff = jiffies_to_msecs(jiffies - + ppsc->last_delaylps_stamp_jiffies); + + if (ps_timediff < 2000) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Delay enter Fw LPS for DHCP, ARP," + " or EAPOL exchanging state.\n")); + return false; + } + + if (mac->link_state != MAC80211_LINKED) + return false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return false; + + return true; +} + +/* Change current and default preamble mode.*/ +static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rpwm_val, fw_pwrmode; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->dot11_psmode == rt_psmode) + return; + + /* Update power save mode configured. */ + ppsc->dot11_psmode = rt_psmode; + + /* + * + *1. Enter PS mode + * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode + * cmd to set Fw into PS mode. + *2. Leave PS mode + * Send H2C fw_pwrmode cmd to Fw to set Fw into Active + * mode and set RPWM to turn RF on. + */ + + if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) && + ppsc->report_linked) { + bool b_fw_current_inps; + if (ppsc->dot11_psmode == EACTIVE) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE)); + + rpwm_val = 0x0C; /* RF on */ + fw_pwrmode = FW_PS_ACTIVE_MODE; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *) (&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *) (&fw_pwrmode)); + b_fw_current_inps = false; + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inps)); + + } else { + if (rtl_get_fwlps_doze(hw)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode)); + + rpwm_val = 0x02; /* RF off */ + b_fw_current_inps = true; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *) (&ppsc->fwctrl_psmode)); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + (u8 *) (&rpwm_val)); + } else { + /* Reset the power save related parameters. */ + ppsc->dot11_psmode = EACTIVE; + } + } + } +} + +/*Enter the leisure power save mode.*/ +void rtl_lps_enter(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long flag; + + if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps)) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->link_info.b_busytraffic) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if (mac->cnt_after_linked < 5) + return; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + + if (ppsc->b_leisure_ps) { + /* Idle for a while if we connect to AP a while ago. */ + if (mac->cnt_after_linked >= 2) { + if (ppsc->dot11_psmode == EACTIVE) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Enter 802.11 power save mode...\n")); + + rtl_lps_set_psmode(hw, EAUTOPS); + } + } + } + spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); +} + +/*Leave the leisure power save mode.*/ +void rtl_lps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flag; + + spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + + if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) { + if (ppsc->dot11_psmode != EACTIVE) { + + /*FIX ME */ + rtlpriv->cfg->ops->enable_interrupt(hw); + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM); + } + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Busy Traffic,Leave 802.11 power save..\n")); + + rtl_lps_set_psmode(hw, EACTIVE); + } + } + spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); +} diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h new file mode 100644 index 000000000000..ae56da801a23 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __REALTEK_RTL_PCI_PS_H__ +#define __REALTEK_RTL_PCI_PS_H__ + +bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, + enum rf_pwrstate state_toset, u32 changesource, + bool protect_or_not); +bool rtl_ps_enable_nic(struct ieee80211_hw *hw); +bool rtl_ps_disable_nic(struct ieee80211_hw *hw); +void rtl_ips_nic_off(struct ieee80211_hw *hw); +void rtl_ips_nic_on(struct ieee80211_hw *hw); +void rtl_ips_nic_off_wq_callback(void *data); +void rtl_lps_enter(struct ieee80211_hw *hw); +void rtl_lps_leave(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c new file mode 100644 index 000000000000..904b8fd01f6d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -0,0 +1,329 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "rc.h" + +/* + *Finds the highest rate index we can use + *if skb is special data like DHCP/EAPOL, we set should + *it to lowest rate CCK_1M, otherwise we set rate to + *CCK11M or OFDM_54M based on wireless mode. + */ +static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, + struct sk_buff *skb, bool not_data) +{ + struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + + /* + *mgt use 1M, although we have check it + *before this function use rate_control_send_low, + *we still check it here + */ + if (not_data) + return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; + + /* + *this rate is no use for true rate, firmware + *will control rate at all it just used for + *1.show in iwconfig in B/G mode + *2.in rtl_get_tcb_desc when we check rate is + * 1M we will not use FW rate but user rate. + */ + if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) { + return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; + } else { + if (rtlmac->mode == WIRELESS_MODE_B) + return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]; + else + return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]; + } +} + +static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, + struct ieee80211_tx_rate *rate, + struct ieee80211_tx_rate_control *txrc, + u8 tries, u8 rix, int rtsctsenable, + bool not_data) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + rate->count = tries; + rate->idx = (rix > 0x2) ? rix : 0x2; + + if (!not_data) { + if (txrc->short_preamble) + rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; + if (mac->bw_40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (mac->sgi_20 || mac->sgi_40) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + if (mac->ht_enable) + rate->flags |= IEEE80211_TX_RC_MCS; + } +} + +static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, + void *priv_sta, struct ieee80211_tx_rate_control *txrc) +{ + struct rtl_priv *rtlpriv = ppriv; + struct sk_buff *skb = txrc->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rates = tx_info->control.rates; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + u8 try_per_rate, i, rix; + bool not_data = !ieee80211_is_data(fc); + + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data); + + try_per_rate = 1; + _rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc, + try_per_rate, rix, 1, not_data); + + if (!not_data) { + for (i = 1; i < 4; i++) + _rtl_rc_rate_set_series(rtlpriv, &rates[i], + txrc, i, (rix - i), 1, + not_data); + } +} + +static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->act_scanning) + return false; + + if (mac->cnt_after_linked < 3) + return false; + + if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF) + return true; + + return false; +} + +/*mac80211 Rate Control callbacks*/ +static void rtl_tx_status(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct ieee80211_hdr *hdr; + __le16 fc; + + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; + + if (!priv_sta || !ieee80211_is_data(fc)) + return; + + if (rtl_is_special_data(mac->hw, skb, true)) + return; + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) + || is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + return; + + /* Check if aggregation has to be enabled for this tid */ + if (conf_is_ht(&mac->hw->conf) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 *qc, tid; + + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + + if (_rtl_tx_aggr_check(rtlpriv, tid)) + ieee80211_start_tx_ba_session(sta, tid); + } + } +} + +static void rtl_rate_init(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 is_ht = conf_is_ht(&mac->hw->conf); + + if ((mac->opmode == NL80211_IFTYPE_STATION) || + (mac->opmode == NL80211_IFTYPE_MESH_POINT) || + (mac->opmode == NL80211_IFTYPE_ADHOC)) { + + switch (sband->band) { + case IEEE80211_BAND_2GHZ: + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_G; + if (is_ht) + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + case IEEE80211_BAND_5GHZ: + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_A; + if (is_ht) + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Invalid band\n")); + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + } + + RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG, + ("Choosing rate table index: %d\n", + rtlpriv->rate_priv->cur_ratetab_idx)); + + } + +} + +static void rtl_rate_update(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + u32 changed, + enum nl80211_channel_type oper_chan_type) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + bool oper_cw40 = false, oper_sgi40; + bool local_cw40 = mac->bw_40; + bool local_sgi40 = mac->sgi_40; + u8 is_ht = conf_is_ht(&mac->hw->conf); + + if (changed & IEEE80211_RC_HT_CHANGED) { + if (mac->opmode != NL80211_IFTYPE_STATION) + return; + + if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || + rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) + oper_cw40 = true; + + oper_sgi40 = mac->sgi_40; + + if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { + switch (sband->band) { + case IEEE80211_BAND_2GHZ: + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_G; + if (is_ht) + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + case IEEE80211_BAND_5GHZ: + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_A; + if (is_ht) + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Invalid band\n")); + rtlpriv->rate_priv->cur_ratetab_idx = + RATR_INX_WIRELESS_NGB; + break; + } + } + } +} + +static void *rtl_rate_alloc(struct ieee80211_hw *hw, + struct dentry *debugfsdir) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + return rtlpriv; +} + +static void rtl_rate_free(void *rtlpriv) +{ + return; +} + +static void *rtl_rate_alloc_sta(void *ppriv, + struct ieee80211_sta *sta, gfp_t gfp) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_rate_priv *rate_priv; + + rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp); + if (!rate_priv) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Unable to allocate private rc structure\n")); + return NULL; + } + + rtlpriv->rate_priv = rate_priv; + + return rate_priv; +} + +static void rtl_rate_free_sta(void *rtlpriv, + struct ieee80211_sta *sta, void *priv_sta) +{ + struct rtl_rate_priv *rate_priv = priv_sta; + kfree(rate_priv); +} + +static struct rate_control_ops rtl_rate_ops = { + .module = NULL, + .name = "rtl_rc", + .alloc = rtl_rate_alloc, + .free = rtl_rate_free, + .alloc_sta = rtl_rate_alloc_sta, + .free_sta = rtl_rate_free_sta, + .rate_init = rtl_rate_init, + .rate_update = rtl_rate_update, + .tx_status = rtl_tx_status, + .get_rate = rtl_get_rate, +}; + +int rtl_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rtl_rate_ops); +} + +void rtl_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rtl_rate_ops); +} diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h new file mode 100644 index 000000000000..b4667c035f0b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rc.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_RC_H__ +#define __RTL_RC_H__ + +struct rtl_rate_priv { + u8 cur_ratetab_idx; + u8 ht_cap; +}; + +int rtl_rate_control_register(void); +void rtl_rate_control_unregister(void); +#endif diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c new file mode 100644 index 000000000000..3336ca999dfd --- /dev/null +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -0,0 +1,400 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "regd.h" + +static struct country_code_to_enum_rd allCountries[] = { + {COUNTRY_CODE_FCC, "US"}, + {COUNTRY_CODE_IC, "US"}, + {COUNTRY_CODE_ETSI, "EC"}, + {COUNTRY_CODE_SPAIN, "EC"}, + {COUNTRY_CODE_FRANCE, "EC"}, + {COUNTRY_CODE_MKK, "JP"}, + {COUNTRY_CODE_MKK1, "JP"}, + {COUNTRY_CODE_ISRAEL, "EC"}, + {COUNTRY_CODE_TELEC, "JP"}, + {COUNTRY_CODE_MIC, "JP"}, + {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, + {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, + {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, +}; + +/* + *Only these channels all allow active + *scan on all world regulatory domains + */ +#define RTL819x_2GHZ_CH01_11 \ + REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) + +/* + *We enable active scan on these a case + *by case basis by regulatory domain + */ +#define RTL819x_2GHZ_CH12_13 \ + REG_RULE(2467-10, 2472+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) + +#define RTL819x_2GHZ_CH14 \ + REG_RULE(2484-10, 2484+10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_OFDM) + +static const struct ieee80211_regdomain rtl_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_global = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_world = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + } +}; + +static bool _rtl_is_radar_freq(u16 center_freq) +{ + return (center_freq >= 5260 && center_freq <= 5700); +} + +static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + u32 bandwidth = 0; + int r; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (_rtl_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + r = freq_reg_info(wiphy, ch->center_freq, + bandwidth, ®_rule); + if (r) + continue; + + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule-> + flags & NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + u32 bandwidth = 0; + int r; + + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + + /* + *If no country IE has been received always enable active scan + *on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + *If a country IE has been recieved check its rule for this + *channel first before enabling active scan. The passive scan + *would have been enforced by the initial processing of our + *custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +/* + *Always apply Radar/DFS rules on + *freq range 5260 MHz - 5700 MHz + */ +static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!_rtl_is_radar_freq(ch->center_freq)) + continue; + + /* + *We always enable radar detection/DFS on this + *frequency range. Additionally we also apply on + *this frequency range: + *- If STA mode does not yet have DFS supports disable + * active scanning + *- If adhoc mode does not support DFS yet then disable + * adhoc in the frequency. + *- If AP mode does not yet support radar detection/DFS + *do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct rtl_regulatory *reg) +{ + _rtl_reg_apply_beaconing_flags(wiphy, initiator); + _rtl_reg_apply_active_scan_flags(wiphy, initiator); + return; +} + +static void _rtl_dump_channel_map(struct wiphy *wiphy) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + if (!wiphy->bands[band]) + continue; + sband = wiphy->bands[band]; + for (i = 0; i < sband->n_channels; i++) + ch = &sband->channels[i]; + } +} + +static int _rtl_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct rtl_regulatory *reg) +{ + /* We always apply this */ + _rtl_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); + break; + } + + _rtl_dump_channel_map(wiphy); + + return 0; +} + +static const struct ieee80211_regdomain *_rtl_regdomain_select( + struct rtl_regulatory *reg) +{ + switch (reg->country_code) { + case COUNTRY_CODE_FCC: + case COUNTRY_CODE_IC: + return &rtl_regdom_11; + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: + case COUNTRY_CODE_TELEC_NETGEAR: + return &rtl_regdom_world; + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_TELEC: + case COUNTRY_CODE_MIC: + return &rtl_regdom_global; + case COUNTRY_CODE_GLOBAL_DOMAIN: + return &rtl_regdom_global; + case COUNTRY_CODE_WORLD_WIDE_13: + return &rtl_regdom_world; + default: + return &rtl_regdom_world; + } +} + +static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, + struct wiphy *wiphy, + int (*reg_notifier) (struct wiphy *wiphy, + struct regulatory_request * + request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; + wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; + regd = _rtl_regdomain_select(reg); + wiphy_apply_custom_regulatory(wiphy, regd); + _rtl_reg_apply_radar_flags(wiphy); + _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { + if (allCountries[i].countrycode == countrycode) + return &allCountries[i]; + } + return NULL; +} + +int rtl_regd_init(struct ieee80211_hw *hw, + int (*reg_notifier) (struct wiphy *wiphy, + struct regulatory_request *request)) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct wiphy *wiphy = hw->wiphy; + struct country_code_to_enum_rd *country = NULL; + + if (wiphy == NULL || &rtlpriv->regd == NULL) + return -EINVAL; + + /* force the channel plan to world wide 13 */ + rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; + + RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, + (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", + rtlpriv->regd.country_code)); + + if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { + RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, + (KERN_DEBUG "rtl: EEPROM indicates invalid contry code" + "world wide 13 should be used\n")); + + rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; + } + + country = _rtl_regd_find_country(rtlpriv->regd.country_code); + + if (country) { + rtlpriv->regd.alpha2[0] = country->isoName[0]; + rtlpriv->regd.alpha2[1] = country->isoName[1]; + } else { + rtlpriv->regd.alpha2[0] = '0'; + rtlpriv->regd.alpha2[1] = '0'; + } + + RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, + (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1])); + + _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); + + return 0; +} + +int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n")); + + return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); +} diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h new file mode 100644 index 000000000000..4cdbc4ae76d4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/regd.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_REGD_H__ +#define __RTL_REGD_H__ + +struct country_code_to_enum_rd { + u16 countrycode; + const char *isoName; +}; + +enum country_code_type_t { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + + /*add new channel plan above this line */ + COUNTRY_CODE_MAX +}; + +int rtl_regd_init(struct ieee80211_hw *hw, + int (*reg_notifier) (struct wiphy *wiphy, + struct regulatory_request *request)); +int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile new file mode 100644 index 000000000000..f3d7682ff08c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile @@ -0,0 +1,12 @@ +rtl8192ce-objs := \ + rtl8192c-dm.o \ + rtl8192c-fw.o \ + rtl8192c-hw.o \ + rtl8192c-led.o \ + rtl8192c-phy.o \ + rtl8192c-rf.o \ + rtl8192c-sw.o \ + rtl8192c-table.o \ + rtl8192c-trx.o + +obj-$(CONFIG_RTL8192CE) += rtl8192ce.o diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h new file mode 100644 index 000000000000..83cd64895292 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h @@ -0,0 +1,257 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_DEF_H__ +#define __RTL92C_DEF_H__ + +#define HAL_RETRY_LIMIT_INFRA 48 +#define HAL_RETRY_LIMIT_AP_ADHOC 7 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +#define RESET_DELAY_8185 20 + +#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1 + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 + +#define MAX_LINES_HWCONFIG_TXT 1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT 256 + +#define SW_THREE_WIRE 0 +#define HW_THREE_WIRE 2 + +#define BT_DEMO_BOARD 0 +#define BT_QA_BOARD 1 +#define BT_FPGA 2 + +#define RX_SMOOTH_FACTOR 20 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define MAX_H2C_QUEUE_NUM 10 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 +#define AC2QUEUEID(_AC) (_AC) + +#define C2H_RX_CMD_HDR_LEN 8 +#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 0, 16) +#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 16, 8) +#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 24, 7) +#define GET_C2H_CMD_CONTINUE(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 31, 1) +#define GET_C2H_CMD_CONTENT(__prxhdr) \ + ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN) + +#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16) +#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) +#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) + +#define CHIP_VER_B BIT(4) +#define CHIP_92C_BITMASK BIT(0) +#define CHIP_92C_1T2R 0x03 +#define CHIP_92C 0x01 +#define CHIP_88C 0x00 + +enum version_8192c { + VERSION_A_CHIP_92C = 0x01, + VERSION_A_CHIP_88C = 0x00, + VERSION_B_CHIP_92C = 0x11, + VERSION_B_CHIP_88C = 0x10, + VERSION_UNKNOWN = 0x88, +}; + +#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) +#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false) + +enum rtl819x_loopback_e { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum hal_fw_c2h_cmd_id { + HAL_FW_C2H_CMD_Read_MACREG = 0, + HAL_FW_C2H_CMD_Read_BBREG = 1, + HAL_FW_C2H_CMD_Read_RFREG = 2, + HAL_FW_C2H_CMD_Read_EEPROM = 3, + HAL_FW_C2H_CMD_Read_EFUSE = 4, + HAL_FW_C2H_CMD_Read_CAM = 5, + HAL_FW_C2H_CMD_Get_BasicRate = 6, + HAL_FW_C2H_CMD_Get_DataRate = 7, + HAL_FW_C2H_CMD_Survey = 8, + HAL_FW_C2H_CMD_SurveyDone = 9, + HAL_FW_C2H_CMD_JoinBss = 10, + HAL_FW_C2H_CMD_AddSTA = 11, + HAL_FW_C2H_CMD_DelSTA = 12, + HAL_FW_C2H_CMD_AtimDone = 13, + HAL_FW_C2H_CMD_TX_Report = 14, + HAL_FW_C2H_CMD_CCX_Report = 15, + HAL_FW_C2H_CMD_DTM_Report = 16, + HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, + HAL_FW_C2H_CMD_C2HLBK = 18, + HAL_FW_C2H_CMD_C2HDBG = 19, + HAL_FW_C2H_CMD_C2HFEEDBACK = 20, + HAL_FW_C2H_CMD_MAX +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc92c_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, + DESC92C_RATEMCS15_SG = 0x1c, + DESC92C_RATEMCS32 = 0x20, +}; + +struct phy_sts_cck_8192s_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c new file mode 100644 index 000000000000..4896899394a8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c @@ -0,0 +1,1473 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../base.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-dm.h" +#include "rtl8192c-fw.h" + +struct dig_t dm_digtable; +static struct ps_t dm_pstable; + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, + 0x788001e2, + 0x71c001c7, + 0x6b8001ae, + 0x65400195, + 0x5fc0017f, + 0x5a400169, + 0x55400155, + 0x50800142, + 0x4c000130, + 0x47c0011f, + 0x43c0010f, + 0x40000100, + 0x3c8000f2, + 0x390000e4, + 0x35c000d7, + 0x32c000cb, + 0x300000c0, + 0x2d4000b5, + 0x2ac000ab, + 0x288000a2, + 0x26000098, + 0x24000090, + 0x22000088, + 0x20000080, + 0x1e400079, + 0x1c800072, + 0x1b00006c, + 0x19800066, + 0x18000060, + 0x16c0005b, + 0x15800056, + 0x14400051, + 0x1300004c, + 0x12000048, + 0x11000044, + 0x10000040, +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} +}; + +static void rtl92c_dm_diginit(struct ieee80211_hw *hw) +{ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0x0; + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; +} + +static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long rssi_val_min = 0; + + if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + else + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || + dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + } + + return (u8) rssi_val_min; +} + +static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " + "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value_igi = dm_digtable.cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = 0x32; + + dm_digtable.cur_igvalue = value_igi; + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { + if ((dm_digtable.backoff_val - 2) < + dm_digtable.backoff_val_range_min) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_min; + else + dm_digtable.backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { + if ((dm_digtable.backoff_val + 2) > + dm_digtable.backoff_val_range_max) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_max; + else + dm_digtable.backoff_val += 2; + } + + if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > + dm_digtable.rx_gain_range_max) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; + else if ((dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val; + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 binitialized; /* initialized to false */ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + bool b_multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + b_multi_sta = true; + + if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != + DIG_STA_DISCONNECT)) { + binitialized = false; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (binitialized == false) { + binitialized = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable.rssi_lowthresh) && + (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable.dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable.rssi_highthresh) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("curmultista_connectstate = " + "%x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage)); +} + +static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("presta_connectstate = %x," + " cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate)); + + if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate + || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT + || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + + if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { + dm_digtable.rssi_val_min = + rtl92c_dm_initial_gain_min_pwdb(hw); + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable.rssi_val_min = 0; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0; + rtl92c_dm_write_dig(hw); + } +} + +static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); + + if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (dm_digtable.rssi_val_min <= 25) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } else { + if (dm_digtable.rssi_val_min <= 20) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } + } else { + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { + if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) + dm_digtable.cur_cck_fa_state = + CCK_FA_STAGE_High; + else + dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; + + if (dm_digtable.pre_cck_fa_state != + dm_digtable.cur_cck_fa_state) { + if (dm_digtable.cur_cck_fa_state == + CCK_FA_STAGE_Low) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0xcd); + + dm_digtable.pre_cck_fa_state = + dm_digtable.cur_cck_fa_state; + } + + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd7); + } else { + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd3); + } + dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); +} + +static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (mac->act_scanning == true) + return; + + if ((mac->link_state > MAC80211_NOLINK) && + (mac->link_state < MAC80211_LINKED)) + dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; + else if (mac->link_state >= MAC80211_LINKED) + dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + else + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + + rtl92c_dm_initial_gain_sta(hw); + rtl92c_dm_initial_gain_multi_sta(hw); + rtl92c_dm_cck_packet_detection_thresh(hw); + + dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; + +} + +static void rtl92c_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.b_dm_initialgain_enable == false) + return; + if (dm_digtable.dig_enable_flag == false) + return; + + rtl92c_dm_ctrl_initgain_by_twoport(hw); + +} + +static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.bdynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (!rtlpriv->dm.bdynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Not connected to any\n")); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_NORMAL\n")); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel)); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +void rtl92c_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("cur_igvalue = 0x%x, " + "pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val)); + + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + + dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + } +} + +static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + u8 h2c_parameter[3] = { 0 }; + + return; + + if (tmpentry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; + } else { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; + } + + if (tmpentry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; + } else { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; + } + + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); + h2c_parameter[0] = 0; + + rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +} + +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.bis_any_nonbepkts = false; + rtlpriv->dm.bis_cur_rdlstate = false; +} + +static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + goto dm_checkedcaturbo_exit; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.bcurrent_turbo_edca = false; + return; + } + + if (!mac->ht_enable) { /*FIX MERGE */ + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((!rtlpriv->dm.bis_any_nonbepkts) && + (!rtlpriv->dm.b_disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.bis_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.bis_cur_rdlstate = false; + } + } + rtlpriv->dm.bcurrent_turbo_edca = true; + } else { + if (rtlpriv->dm.bcurrent_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&tmp)); + rtlpriv->dm.bcurrent_turbo_edca = false; + } + } + +dm_checkedcaturbo_exit: + rtlpriv->dm.bis_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw + *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk; + long ele_a, ele_d, temp_cck, val_x, value32; + long val_y, ele_c; + u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; + int i; + bool is2t = IS_92C_SERIAL(rtlhal->version); + u8 txpwr_level[2] = {0, 0}; + u8 ofdm_min_index = 6, rf; + + rtlpriv->dm.btxpower_trackingInit = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter)); + + rtl92c_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Initial pathA ele_d reg0x%x = 0x%lx, " + "ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0])); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial pathB ele_d reg0x%x = " + "0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1])); + break; + } + } + } + + temp_cck = + rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.b_cck_inch14) { + if (memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } else { + if (memcmp((void *)&temp_cck, + (void *) + &cckswing_table_ch1ch13[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x delta 0x%x " + "delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk)); + + if (delta_lck > 1) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92c_phy_lc_calibrate(hw); + } + + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] -= delta; + rtlpriv->dm.cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] += delta; + rtlpriv->dm.cck_index += delta; + } + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index)); + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i] + + 1; + cck_index = rtlpriv->dm.cck_index + 1; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i]; + cck_index = rtlpriv->dm.cck_index; + } + + for (i = 0; i < rf; i++) { + if (txpwr_level[i] >= 0 && + txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse-> + eeprom_thermalmeter) { + ofdm_index[i] += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 + && thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > + rtlefuse->eeprom_thermalmeter + && delta > 5) { + ofdm_index[i] -= 1; + } + } + + if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse->eeprom_thermalmeter) { + cck_index += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 && + thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > rtlefuse->eeprom_thermalmeter + && delta > 5) { + cck_index -= 1; + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) + ofdm_index[i] = OFDM_TABLE_SIZE - 1; + + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], cck_index)); + } + } + + if (rtlpriv->dm.txpower_track_control && delta != 0) { + ele_d = + (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->reg_e94; + val_y = rtlphy->reg_e9c; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(29), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31) | BIT(29), 0x00); + } + + if (!rtlpriv->dm.b_cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[cck_index] + [7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[cck_index] + [7]); + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & + 0xFFC00000) >> 22; + + val_x = rtlphy->reg_eb4; + val_y = rtlphy->reg_ebc; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & + 0x00003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(25), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index + [1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27) | BIT(25), 0x00); + } + + } + } + + if (delta_iqk > 3) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92c_phy_iq_calibrate(hw, false); + } + + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + +} + +static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.btxpower_tracking = true; + rtlpriv->dm.btxpower_trackingInit = false; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("pMgntInfo->btxpower_tracking = %d\n", + rtlpriv->dm.btxpower_tracking)); +} + +static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) +{ + rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl92c_dm_check_txpower_tracking_thermal_meter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static u8 tm_trigger; + + if (!rtlpriv->dm.btxpower_tracking) + return; + + if (!tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, + 0x60); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Trigger 92S Thermal Meter!!\n")); + tm_trigger = 1; + return; + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Schedule TxPowerTracking direct call!!\n")); + rtl92c_dm_txpower_tracking_directcall(hw); + tm_trigger = 0; + } +} + +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_check_txpower_tracking_thermal_meter(hw); +} + +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.b_useramask = true; + else + rtlpriv->dm.b_useramask = false; + +} + +static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + + if (is_hal_stop(rtlhal)) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver is going to unload\n")); + return; + } + + if (!rtlpriv->dm.b_useramask) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver does not control rate adaptive mask\n")); + return; + } + + if (mac->link_state == MAC80211_LINKED) { + + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state)); + + rtlpriv->cfg->ops->update_rate_mask(hw, + p_ra->ratr_state); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + dm_pstable.pre_ccastate = CCA_MAX; + dm_pstable.cur_ccasate = CCA_MAX; + dm_pstable.pre_rfstate = RF_MAX; + dm_pstable.cur_rfstate = RF_MAX; + dm_pstable.rssi_val_min = 0; +} + +static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_ccastate == CCA_2R) { + if (dm_pstable.rssi_val_min >= 35) + dm_pstable.cur_ccasate = CCA_1R; + else + dm_pstable.cur_ccasate = CCA_2R; + } else { + if (dm_pstable.rssi_val_min <= 30) + dm_pstable.cur_ccasate = CCA_2R; + else + dm_pstable.cur_ccasate = CCA_1R; + } + } else { + dm_pstable.cur_ccasate = CCA_MAX; + } + + if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { + if (dm_pstable.cur_ccasate == CCA_1R) { + if (get_rf_type(rtlphy) == RF_2T2R) { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x13); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x23); + rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); + } + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, + 0x33); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); + } + dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; + } + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", + (dm_pstable.cur_ccasate == + 0) ? "1RCCA" : "2RCCA")); +} + +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + static u8 initialize; + static u32 reg_874, reg_c70, reg_85c, reg_a74; + + if (initialize == 0) { + reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; + + initialize = 1; + } + + if (!bforce_in_normal) { + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_rfstate == RF_NORMAL) { + if (dm_pstable.rssi_val_min >= 30) + dm_pstable.cur_rfstate = RF_SAVE; + else + dm_pstable.cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable.rssi_val_min <= 25) + dm_pstable.cur_rfstate = RF_NORMAL; + else + dm_pstable.cur_rfstate = RF_SAVE; + } + } else { + dm_pstable.cur_rfstate = RF_MAX; + } + } else { + dm_pstable.cur_rfstate = RF_NORMAL; + } + + if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { + if (dm_pstable.cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + } + + dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; + } +} + +static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + dm_pstable.rssi_val_min = 0; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("Not connected to any\n")); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + + if (IS_92C_SERIAL(rtlhal->version)) + rtl92c_dm_1r_cca(hw); +} + +void rtl92c_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl92c_dm_diginit(hw); + rtl92c_dm_init_dynamic_txpower(hw); + rtl92c_dm_init_edca_turbo(hw); + rtl92c_dm_init_rate_adaptive_mask(hw); + rtl92c_dm_initialize_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); +} + +void rtl92c_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_fw_current_inpsmode = false; + bool b_fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *) (&b_fw_ps_awake)); + + if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && + b_fw_ps_awake) + && (!ppsc->rfchange_inprogress)) { + rtl92c_dm_pwdb_monitor(hw); + rtl92c_dm_dig(hw); + rtl92c_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_bb_powersaving(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_dm_refresh_rate_adaptive_mask(hw); + rtl92c_dm_check_edca_turbo(hw); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h new file mode 100644 index 000000000000..463439e4074c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_DM_H__ +#define __RTL92C_DM_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX 0x3e +#define DM_DIG_MIN 0x1e + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RXPATHSELECTION_SS_TH_lOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVal 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + long rssi_val_min; +}; + +struct dig_t { + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + u8 cursta_connectctate; + u8 presta_connectstate; + u8 curmultista_connectstate; + u8 pre_igvalue; + u8 cur_igvalue; + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 rssi_val_min; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; +}; + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum tag_cck_packet_detection_threshold_type_definition { + CCK_PD_STAGE_LowRssi = 0, + CCK_PD_STAGE_HighRssi = 1, + CCK_FA_STAGE_Low = 2, + CCK_FA_STAGE_High = 3, + CCK_PD_STAGE_MAX = 4, +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum dm_dig_ext_port_alg_e { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_connect_e { + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MULTISTA_DISCONNECT = 3, + DIG_MULTISTA_CONNECT = 4, + DIG_CONNECT_MAX +}; + +extern struct dig_t dm_digtable; +void rtl92c_dm_init(struct ieee80211_hw *hw); +void rtl92c_dm_watchdog(struct ieee80211_hw *hw); +void rtl92c_dm_write_dig(struct ieee80211_hw *hw); +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c new file mode 100644 index 000000000000..80ee6ff9d2b8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c @@ -0,0 +1,804 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-fw.h" +#include "rtl8192c-table.h" + +static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { + u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (enable) + value32 |= MCUFWDL_EN; + else + value32 &= ~MCUFWDL_EN; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { + u8 tmp; + if (enable) { + + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } + } +} + +static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, + const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 blockSize = sizeof(u32); + u8 *bufferPtr = (u8 *) buffer; + u32 *pu4BytePtr = (u32 *) buffer; + u32 i, offset, blockCount, remainSize; + + blockCount = size / blockSize; + remainSize = size % blockSize; + + for (i = 0; i < blockCount; i++) { + offset = i * blockSize; + rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), + *(pu4BytePtr + i)); + } + + if (remainSize) { + offset = blockCount * blockSize; + bufferPtr += offset; + for (i = 0; i < remainSize; i++) { + rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + + offset + i), *(bufferPtr + i)); + } + } +} + +static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, + u32 page, const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8) (page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + _rtl92c_fw_block_write(hw, buffer, size); +} + +static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8) (fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} + +static void _rtl92c_write_fw(struct ieee80211_hw *hw, + enum version_8192c version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_version_b; + u8 *bufferPtr = (u8 *) buffer; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + + is_version_b = IS_CHIP_VER_B(version); + if (is_version_b) { + u32 pageNums, remainSize; + u32 page, offset; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) + _rtl92c_fill_dummy(bufferPtr, &size); + + pageNums = size / FW_8192C_PAGE_SIZE; + remainSize = size % FW_8192C_PAGE_SIZE; + + if (pageNums > 4) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Page numbers should not greater then 4\n")); + } + + for (page = 0; page < pageNums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remainSize) { + offset = pageNums * FW_8192C_PAGE_SIZE; + page = pageNums; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + remainSize); + } + } else { + _rtl92c_fw_block_write(hw, buffer, size); + } +} + +static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_ChkSum_rpt))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", + value32)); + goto exit; + } + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Polling FW ready success!!" + " REG_MCUFWDL:0x%08x .\n", + value32)); + err = 0; + goto exit; + } + + mdelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + +exit: + return err; +} + +int rtl92c_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl92c_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192c version = rtlhal->version; + + const struct firmware *firmware = NULL; + + err = request_firmware(&firmware, rtlpriv->cfg->fw_name, + rtlpriv->io.dev); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to request firmware!\n")); + return 1; + } + + if (firmware->size > 0x4000) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is too big!\n")); + release_firmware(firmware); + return 1; + } + + memcpy(rtlhal->pfirmware, firmware->data, firmware->size); + fwsize = firmware->size; + release_firmware(firmware); + + pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; + pfwdata = (u8 *) rtlhal->pfirmware; + + if (IS_FW_HEADER_EXIST(pfwheader)) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + pfwheader->version, pfwheader->signature, + (uint)sizeof(struct rtl92c_firmware_header))); + + pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); + fwsize = fwsize - sizeof(struct rtl92c_firmware_header); + } + + _rtl92c_enable_fw_download(hw, true); + _rtl92c_write_fw(hw, version, pfwdata, fwsize); + _rtl92c_enable_fw_download(hw, false); + + err = _rtl92c_fw_free_to_go(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is not ready to run!\n")); + } else { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Firmware is ready to run!\n")); + } + + return 0; +} + +static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr, val_mcutst_1; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); + + if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) + result = true; + return result; +} + +static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg, box_extreg; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->b_h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("H2C set in progress! Wait to set.." + "element_id(%d).\n", element_id)); + + while (rtlhal->b_h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wait 100 us (%d times)...\n", + h2c_waitcounter)); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->b_h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Write H2C fail because no trigger " + "for FW INT!\n")); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating too long for FW read " + "clear HMEBox(%d)!\n", boxnum)); + break; + } + + udelay(10); + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating for FW read clear HMEBox(%d)!!! " + "0x1BF = %2x\n", boxnum, u1b_tmp)); + } + + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write H2C register BOX[%d] fail!!!!! " + "Fw do not read.\n", boxnum)); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id)); + + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 1); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 2); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 2); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum)); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->b_h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); +} + +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (rtlhal->bfw_ready == false) { + RT_ASSERT(false, ("return H2C cmd because of Fw " + "download fail!!!\n")); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); + _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + + return; +} + +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + u8 delay = 100; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) { + RT_ASSERT(false, ("8051 reset fail.\n")); + break; + } + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } +} + +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = {0}; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); + +} + +static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 own; + unsigned long flags; + struct sk_buff *pskb = NULL; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + pdesc = &ring->desc[0]; + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + + return true; +} + +#define BEACON_PG 0 /*->1*/ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5*/ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1RsvdPageLoc[3] = {0}; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); + + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); + + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1RsvdPageLoc, 3); + + + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + + rtstatus = _rtl92c_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Set RSVD page location to Fw.\n")); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", + u1RsvdPageLoc, 3); + rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1RsvdPageLoc), u1RsvdPageLoc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set RSVD page location to Fw FAIL!!!!!!.\n")); +} + +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = {0}; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h new file mode 100644 index 000000000000..3db33bd14666 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_SIZE 0x3000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x3FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 100 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ + (_pfwhdr->signature&0xFFF0) == 0x88C0) + +struct rtl92c_firmware_header { + u16 signature; + u8 category; + u8 function; + u16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + u16 ramcodeSize; + u16 rsvd2; + u32 svnindex; + u32 rsvd3; + u32 rsvd4; + u32 rsvd5; +}; + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + MAX_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) + +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c new file mode 100644 index 000000000000..c649f6555752 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c @@ -0,0 +1,2173 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-dm.h" +#include "rtl8192c-fw.h" +#include "rtl8192c-led.h" +#include "rtl8192c-hw.h" + +#define LLT_CONFIG 5 + +static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *) (val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfState; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *) (&rfState)); + if (rfState == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->b_fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *) (val)) = tsf; + + break; + } + case HW_VAR_MGT_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); + break; + case HW_VAR_CTRL_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); + break; + case HW_VAR_DATA_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (b_rate_cfg >> 8)&0xff); + while (b_rate_cfg > 0x1) { + b_rate_cfg = (b_rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *) val)); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("HW_VAR_SLOT_TIME %x\n", val[0])); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&e_aci)); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool) (*(u8 *) val); + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *((u8 *) val); + if (min_spacing_to_set <= 7) { + sec_min_space = 0; + + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg)); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *) val); + mac->min_space_cfg |= (density_to_set << 3); + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg)); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + + factor_toset = *((u8 *) val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + + } + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset)); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *) val); + u32 u4b_ac_param = 0; + + u4b_ac_param |= (u32) mac->ac[e_aci].aifs; + u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min + & 0xF) << AC_PARAM_ECW_MIN_OFFSET; + u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max & + 0xF) << AC_PARAM_ECW_MAX_OFFSET; + u4b_ac_param |= (u32) mac->ac[e_aci].tx_op + << AC_PARAM_TXOP_LIMIT_OFFSET; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("queue:%x, ac_param:%x\n", e_aci, + u4b_ac_param)); + + switch (e_aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, + u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, + u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, + u4b_ac_param); + break; + default: + RT_ASSERT(false, + ("SetHwReg8185(): invalid aci: %d !\n", + e_aci)); + break; + } + + if (rtlpci->acm_method != eAcmWay2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + (u8 *) (&e_aci)); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *) val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= AcmHw_BeqEn; + break; + case AC2_VI: + acm_ctrl |= AcmHw_ViqEn; + break; + case AC3_VO: + acm_ctrl |= AcmHw_VoqEn; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("HW_VAR_ACM_CTRL acm set " + "failed: eACI is %d\n", acm)); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~AcmHw_BeqEn); + break; + case AC2_VI: + acm_ctrl &= (~AcmHw_ViqEn); + break; + case AC3_VO: + acm_ctrl &= (~AcmHw_BeqEn); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } + + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " + "Write 0x%X\n", acm_ctrl)); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *) (val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *) val); + break; + case HW_VAR_IO_CMD: + rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + (*(u8 *) val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *) val) | BIT(7))); + } + + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = (*(u8 *) val); + + if ((psmode != FW_PS_ACTIVE_MODE) && + (!IS_92C_SERIAL(rtlhal->version))) { + rtl92c_dm_rf_saving(hw, true); + } + + rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->b_fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *) val); + u8 tmp_regcr, tmp_reg422; + bool b_recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = + rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + b_recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + + rtl92c_set_fw_rsvdpagepkt(hw, 0); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) { + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + } + + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + + break; + } + case HW_VAR_AID:{ + u16 u2btmp; + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *) (val))[0]; + + /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? + 1 : 0;*/ + + if (btype_ibss == true) + _rtl92ce_stop_tx_beacon(hw); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32)&0xffffffff)); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss == true) + _rtl92ce_resume_tx_beacon(hw); + + break; + + } + case HW_VAR_MGT_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val); + break; + case HW_VAR_CTRL_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val); + break; + case HW_VAR_DATA_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + break; + } +} + +static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to polling write LLT done at " + "address %d!\n", address)); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxPage; + bool status; + +#if LLT_CONFIG == 1 + maxPage = 255; + txpktbuf_bndy = 252; +#elif LLT_CONFIG == 2 + maxPage = 127; + txpktbuf_bndy = 124; +#elif LLT_CONFIG == 3 + maxPage = 255; + txpktbuf_bndy = 174; +#elif LLT_CONFIG == 4 + maxPage = 255; + txpktbuf_bndy = 246; +#elif LLT_CONFIG == 5 + maxPage = 255; + txpktbuf_bndy = 246; +#endif + +#if LLT_CONFIG == 1 + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c); + rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c); +#elif LLT_CONFIG == 2 + rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010); +#elif LLT_CONFIG == 3 + rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484); +#elif LLT_CONFIG == 4 + rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c); +#elif LLT_CONFIG == 5 + rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29); +#endif + + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl92ce_llt_write(hw, i, i + 1); + if (true != status) + return status; + } + + status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (true != status) + return status; + + for (i = txpktbuf_bndy; i < maxPage; i++) { + status = _rtl92ce_llt_write(hw, i, (i + 1)); + if (true != status) + return status; + } + + status = _rtl92ce_llt_write(hw, maxPage, txpktbuf_bndy); + if (true != status) + return status; + + return true; +} + +static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + + if (rtlpci->up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92ce_sw_led_on(hw, pLed0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92ce_sw_led_on(hw, pLed0); + else + rtl92ce_sw_led_off(hw, pLed0); + +} + +static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); + udelay(2); + + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + udelay(2); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(2); + + retry = 0; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), + bytetmp)); + + while ((bytetmp & BIT(0)) && retry < 1000) { + retry++; + udelay(50); + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, + 0xEC), + bytetmp)); + udelay(50); + } + + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); + + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); + udelay(2); + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (_rtl92ce_llt_table_init(hw) == false) + return false;; + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77); + else + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && (bytetmp & BIT(7))); + + _rtl92ce_gen_refresh_led_state(hw); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true;; +} + +static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_bw_opmode; + u32 reg_ratr, reg_prsr; + + reg_bw_opmode = BW_OPMODE_20MHZ; + reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); + + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); + + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + +} + +static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + + if (ppsc->b_support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm)); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " + "hw encryption\n")); + return; + } + + sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TxUseDK; + sec_reg_value |= SCR_RxUseDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The SECR-value %x\n", sec_reg_value)); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); + +} + +int rtl92ce_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + static bool iqk_initialized; /* initialized to false */ + bool rtstatus = true; + bool is92c; + int err; + u8 tmp_u1b; + + rtlpci->being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl92ce_init_mac(hw); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + err = 1; + return err; + } + + err = rtl92c_download_fw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Failed to download FW. Init HW " + "without FW now..\n")); + err = 1; + rtlhal->bfw_ready = false; + return err; + } else { + rtlhal->bfw_ready = true; + } + + rtlhal->last_hmeboxnum = 0; + rtl92c_phy_mac_config(hw); + rtl92c_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl92c_phy_rf_config(hw); + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + _rtl92ce_hw_configure(hw); + rtl_cam_reset_all_entry(hw); + rtl92ce_enable_hw_security_config(hw); + ppsc->rfpwr_state = ERFON; + tmp_u1b = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&(~BIT(3)); + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, tmp_u1b); + tmp_u1b = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + ppsc->rfoff_reason |= (tmp_u1b & BIT(3)) ? 0 : RF_CHANGE_BY_HW; + if (ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtl_ps_set_rf_state(hw, ERFOFF, ppsc->rfoff_reason, true); + else { + ppsc->rfpwr_state = ERFON; + ppsc->rfoff_reason = 0; + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); + } + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl92ce_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + if (ppsc->rfpwr_state == ERFON) { + rtl92c_phy_set_rfpath_switch(hw, 1); + if (iqk_initialized) + rtl92c_phy_iq_calibrate(hw, true); + else { + rtl92c_phy_iq_calibrate(hw, false); + iqk_initialized = true; + } + + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_phy_lc_calibrate(hw); + } + + is92c = IS_92C_SERIAL(rtlhal->version); + tmp_u1b = efuse_read_1byte(hw, 0x1FA); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); + } + + if (!(tmp_u1b & BIT(1)) && is92c) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); + } + + if (!(tmp_u1b & BIT(4))) { + tmp_u1b = rtl_read_byte(rtlpriv, 0x16); + tmp_u1b &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); + udelay(10); + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); + } + rtl92c_dm_init(hw); + rtlpci->being_init_adapter = false; + return err; +} + +static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8192c version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : + VERSION_A_CHIP_88C; + } else { + version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C : + VERSION_B_CHIP_88C; + } + + switch (version) { + case VERSION_B_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + break; + case VERSION_B_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_B_CHIP_88C.\n")); + break; + case VERSION_A_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_A_CHIP_92C.\n")); + break; + case VERSION_A_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_A_CHIP_88C.\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Chip Version ID: Unknown. Bug?\n")); + break; + } + + switch (version & 0x3) { + case CHIP_88C: + rtlphy->rf_type = RF_1T1R; + break; + case CHIP_92C: + rtlphy->rf_type = RF_2T2R; + break; + case CHIP_92C_1T2R: + rtlphy->rf_type = RF_1T2R; + break; + default: + rtlphy->rf_type = RF_1T1R; + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("ERROR RF_Type is set!!")); + break; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R")); + + return version; +} + +static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + bt_msr &= 0xfc; + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + _rtl92ce_stop_tx_beacon(hw); + _rtl92ce_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { + _rtl92ce_resume_tx_beacon(hw); + _rtl92ce_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set HW_VAR_MEDIA_STATUS: " + "No such media status(%x).\n", type)); + } + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to NO LINK!\n")); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to Ad Hoc!\n")); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to STA!\n")); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to AP!\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Network type %d not support!\n", type)); + return 1; + break; + + } + + rtl_write_byte(rtlpriv, (MSR), bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & 0xfc) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); + u8 filterout_non_associated_bssid = false; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + filterout_non_associated_bssid = true; + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_AP: + default: + break; + } + + if (filterout_non_associated_bssid == true) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *) (®_rcr)); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (filterout_non_associated_bssid == false) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *) (®_rcr)); + } +} + +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + if (_rtl92ce_set_media_status(hw, type)) + return -EOPNOTSUPP; + _rtl92ce_set_check_bssid(hw, type); + return 0; +} + +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + u32 u4b_ac_param; + + rtl92c_dm_init_edca_turbo(hw); + + u4b_ac_param = (u32) mac->ac[aci].aifs; + u4b_ac_param |= + ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; + u4b_ac_param |= + ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; + u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET; + RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, + ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", + aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min, + mac->ac[aci].cw_max, mac->ac[aci].tx_op)); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); + break; + default: + RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + break; + } +} + +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + rtlpci->irq_enabled = false; +} + +static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + rtlpriv->intf_ops->enable_aspm(hw); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready) + rtl92c_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | + (u1b_tmp << 8)); + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); +} + +void rtl92ce_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92ce_set_media_status(hw, opmode); + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl92ce_poweroff_adapter(hw); +} + +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, *p_inta); + + /* + * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); + */ +} + +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, + ("beacon_interval:%d\n", bcn_interval)); + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92ce_disable_interrupt(hw); + rtl92ce_enable_interrupt(hw); +} + +static u8 _rtl92c_get_chnl_group(u8 chnl) +{ + u8 group; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + return group; +} + +static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + + i]; + } else { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, + i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [i])); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; + + if ((rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) + > 0) { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path] + [index] - + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [index]; + } else { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; + } + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " + "[0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf0) >> 4); + } + + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i])); + } + } + + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + + index = _rtl92c_get_chnl_group((u8) i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + + if (!autoload_fail) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + + if (!autoload_fail) { + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; + } else { + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; + } + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B])); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->b_apk_thermalmeterignore = true; + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); +} + +static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u16 i, usvalue; + u8 hwinfo[HWSET_MAX_SIZE]; + u16 eeprom_id; + + if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { + rtl_efuse_shadow_map_update(hw); + + memcpy((void *)hwinfo, + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + HWSET_MAX_SIZE); + } else if (rtlefuse->epromtype == EEPROM_93C46) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("RTL819X Not boot from eeprom, check it !!")); + } + + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + hwinfo, HWSET_MAX_SIZE); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8190_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag == true) + return; + + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr))); + + _rtl92ce_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + + rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; + rtlefuse->b_txpwr_fromeprom = true; + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) + rtlhal->oem_id = RT_CID_819x_HP; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819x_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + + } + } + +} + +static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (rtlhal->oem_id) { + case RT_CID_819x_HP: + pcipriv->ledctl.bled_opendrain = true; + break; + case RT_CID_819x_Lenovo: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819x_Acer: + case RT_CID_WHQL: + default: + break; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); +} + +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92ce_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.brfpath_rxenable[0] = true; + else + rtlpriv->dm.brfpath_rxenable[0] = + rtlpriv->dm.brfpath_rxenable[1] = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", + rtlhal->version)); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + rtlefuse->epromtype = EEPROM_93C46; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + _rtl92ce_read_adapter_info(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + } + + _rtl92ce_hal_customized_behavior(hw); +} + +void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + u32 ratr_value = (u32) mac->basic_rates; + u8 *p_mcsrate = mac->mcs; + u8 ratr_index = 0; + u8 b_nmode = mac->ht_enable; + u8 mimo_ps = 1; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 b_curtxbw_40mhz = mac->bw_40; + u8 b_curshortgi_40mhz = mac->sgi_40; + u8 b_curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + + ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + b_nmode = 1; + if (mimo_ps == 0) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + ratr_value &= 0x0FFFFFFF; + + if (b_nmode && ((b_curtxbw_40mhz && + b_curshortgi_40mhz) || (!b_curtxbw_40mhz && + b_curshortgi_20mhz))) { + + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); +} + +void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 ratr_bitmap = (u32) mac->basic_rates; + u8 *p_mcsrate = mac->mcs; + u8 ratr_index; + u8 b_curtxbw_40mhz = mac->bw_40; + u8 b_curshortgi_40mhz = mac->sgi_40; + u8 b_curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + bool b_shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + u8 mimops = 1; + + ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (mimops == 0) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (b_curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (b_curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + + if ((b_curtxbw_40mhz && b_curshortgi_40mhz) || + (!b_curtxbw_40mhz && b_curshortgi_20mhz)) { + + if (macid == 0) + b_shortgi = true; + else if (macid == 1) + b_shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("ratr_bitmap :%x\n", ratr_bitmap)); + *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | + (ratr_index << 28)); + rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " + "ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4])); + rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); +} + +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; + u8 u1tmp; + bool b_actuallyset = false; + unsigned long flag; + + if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) + return false; + + if (ppsc->b_swrf_processing) + return false; + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + cur_rfstate = ppsc->rfpwr_state; + + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG)&~(BIT(3))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; + + if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio ON, RF ON\n")); + + e_rfpowerstate_toset = ERFON; + ppsc->b_hwradiooff = false; + b_actuallyset = true; + } else if ((ppsc->b_hwradiooff == false) + && (e_rfpowerstate_toset == ERFOFF)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + + e_rfpowerstate_toset = ERFOFF; + ppsc->b_hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + if (e_rfpowerstate_toset == ERFON) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + + if (e_rfpowerstate_toset == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + *valid = 1; + return !ppsc->b_hwradiooff; + +} + +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + key_index = PAIRWISE_KEYIDX; + entry_id = CAM_PAIRWISE_KEY_POSITION; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("delete one entry\n")); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1])); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("add one entry\n")); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwiase Key content :", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set Pairwiase key\n")); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec. + key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set group key\n")); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h new file mode 100644 index 000000000000..305c819c8c78 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_HW_H__ +#define __RTL92CE_HW_H__ + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb); +int rtl92ce_hw_init(struct ieee80211_hw *hw); +void rtl92ce_card_disable(struct ieee80211_hw *hw); +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); +void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c new file mode 100644 index 000000000000..609108421570 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-led.h" + +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->b_ledon = true; +} + +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + u8 ledcfg; + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (pcipriv->ledctl.bled_opendrain == true) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->b_ledon = false; +} + +void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) +{ +} + +void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) +{ +} + +void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92ce_sw_led_on(hw, pLed0); + break; + case LED_CTL_POWER_OFF: + rtl92ce_sw_led_off(hw, pLed0); + break; + default: + break; + } +} + +void rtl92ce_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", + ledaction)); + _rtl92ce_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h new file mode 100644 index 000000000000..10da3018f4b7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); +void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); +void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c new file mode 100644 index 000000000000..13d7b387a96a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c @@ -0,0 +1,2676 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-rf.h" +#include "rtl8192c-dm.h" +#include "rtl8192c-table.h" + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, u32 para1, + u32 para2, u32 msdelay); +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath); +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x)\n", regaddr, + bitmask)); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " + "Addr[0x%x]=0x%x\n", bitmask, + regaddr, originalvalue)); + + return returnvalue; + +} + +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + +} + +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask)); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, regaddr); + } else { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } + + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), rfpath(%#x), " + "bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value)); + + return readback_value; +} + +void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + + _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x), data(%#x), " + "rfpath(%#x)\n", regaddr, + bitmask, data, rfpath)); +} + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + RT_ASSERT(false, ("deprecated!\n")); + return 0; +} + +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + RT_ASSERT(false, ("deprecated!\n")); +} + +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0x3f; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + mdelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + mdelay(1); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + mdelay(1); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, + BLSSIREADBACKDATA); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, + retvalue)); + return retvalue; +} + +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + return; + } + offset &= 0x3f; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, + data_and_addr)); +} + +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + return i; +} + +static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); + rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); + rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); + rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); +} + +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is92c = IS_92C_SERIAL(rtlhal->version); + bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + + if (is92c) + rtl_write_byte(rtlpriv, 0x14, 0x71); + return rtstatus; +} + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regvaldw; + u8 b_reg_hwparafile = 1; + + _rtl92c_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTn | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92c_phy_rf6052_config(hw); +} + +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + return false; + } + if (rtlphy->rf_type == RF_1T2R) { + _rtl92c_phy_bb_config_1t(hw); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + } + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + return false; + } + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + return false; + } + rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + return true; +} + +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = RTL8192CEMAC_2T_ARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Img:RTL8192CEMAC_2T_ARRAY\n")); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) +{ +} + +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + agctab_arraylen = AGCTAB_2TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_2TARRAY; + phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_2TARRAY; + } else { + agctab_arraylen = AGCTAB_1TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_1TARRAY; + phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_1TARRAY; + } + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + if (phy_regarray_table[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table[i] == 0xfb) + udelay(50); + else if (phy_regarray_table[i] == 0xfa) + udelay(5); + else if (phy_regarray_table[i] == 0xf9) + udelay(1); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The phy_regarray_table[0] is %x" + " Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1])); + } + rtl92c_phy_config_bb_external_pa(hw); + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The agctab_array_table[0] is " + "%x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1])); + } + } + return true; +} + +static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][0])); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][1])); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][6])); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][7])); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][2])); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][3])); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][4])); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][5])); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][8])); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][9])); + } + + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][14])); + } + + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][15])); + } + + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][10])); + } + + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][11])); + } + + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][12])); + } + + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][13])); + + rtlphy->pwrgroup_cnt++; + } +} + +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH; + phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + if (phy_regarray_table_pg[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table_pg[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table_pg[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table_pg[i] == 0xfb) + udelay(50); + else if (phy_regarray_table_pg[i] == 0xfa) + udelay(5); + else if (phy_regarray_table_pg[i] == 0xf9) + udelay(1); + + _rtl92c_store_pwrIndex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("configtype != BaseBand_Config_PHY_REG\n")); + } + return true; +} + +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + return true; +} + +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + + int i; + bool rtstatus = true; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + radioa_arraylen = RADIOA_2TARRAYLENGTH; + radioa_array_table = RTL8192CERADIOA_2TARRAY; + radiob_arraylen = RADIOB_2TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_2TARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + } else { + radioa_arraylen = RADIOA_1TARRAYLENGTH; + radioa_array_table = RTL8192CE_RADIOA_1TARRAY; + radiob_arraylen = RADIOB_1TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_1TARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + rtstatus = true; + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + if (radioa_array_table[i] == 0xfe) + mdelay(50); + else if (radioa_array_table[i] == 0xfd) + mdelay(5); + else if (radioa_array_table[i] == 0xfc) + mdelay(1); + else if (radioa_array_table[i] == 0xfb) + udelay(50); + else if (radioa_array_table[i] == 0xfa) + udelay(5); + else if (radioa_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + udelay(1); + } + } + _rtl92c_phy_config_rf_external_pa(hw, rfpath); + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + if (radiob_array_table[i] == 0xfe) { + mdelay(50); + } else if (radiob_array_table[i] == 0xfd) + mdelay(5); + else if (radiob_array_table[i] == 0xfc) + mdelay(1); + else if (radiob_array_table[i] == 0xfb) + udelay(50); + else if (radiob_array_table[i] == 0xfa) + udelay(5); + else if (radiob_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + udelay(1); + } + } + break; + case RF90_PATH_C: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + case RF90_PATH_D: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + return true; +} + +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->default_initialgain[0] = + (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default initial gain (c50=0x%x, " + "c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3])); + + rtlphy->framesync = (u8) rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync)); +} + +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVEB_HSPI_READBACK; + +} + +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx + + rtlefuse->legacy_ht_txpowerdiff; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (get_rf_type(rtlphy) == RF_2T2R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (rtlefuse->b_txpwr_fromeprom == false) + return; + _rtl92c_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0]); + _rtl92c_ccxpower_index_check(hw, + channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} + +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 idx; + u8 rf_path; + + u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_B, + power_indbm); + u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_N_24G, + power_indbm); + if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) + ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; + else + ofdmtxpwridx = 0; + RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, + ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx)); + for (idx = 0; idx < 14; idx++) { + for (rf_path = 0; rf_path < 2; rf_path++) { + rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; + rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = + ofdmtxpwridx; + rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = + ofdmtxpwridx; + } + } + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + return true; +} + +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) +{ +} + +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) +{ + u8 txpwridx; + long offset; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + + if ((power_indbm - offset) > 0) + txpwridx = (u8) ((power_indbm - offset) * 2); + else + txpwridx = 0; + + if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) + txpwridx = MAX_TXPWR_IDX_NMODE_92S; + + return txpwridx; +} + +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Unknown Scan Backup operation.\n")); + break; + } + } +} + +void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz")) + + if (is_hal_stop(rtlhal)) + return; + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) + rtl92c_phy_set_bw_mode_callback(hw); + else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("FALSE driver sleep or unload\n")); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 delay; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("switch to channel%d\n", rtlphy->current_channel)); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92c_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else + rtlphy->sw_chnl_inprogress = false; + break; + } while (true); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + RT_ASSERT((rtlphy->current_channel <= 14), + ("WIRELESS_MODE_G but channel>14")); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92c_phy_sw_chnl_callback(hw); + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false schdule workitem\n")); + rtlphy->sw_chnl_inprogress = false; + } else { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false driver sleep or" + " unload\n")); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + RT_ASSERT((channel >= 1 && channel <= 14), + ("illegal channel for Zebra: %d\n", channel)); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92c_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16) currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8) currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) +{ + return true; +} + +static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, + config_pathb ? 0x28160202 : 0x28160502); + + if (config_pathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); + } + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) + return; + else if (b_iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) + return; + else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *addareg, bool is_patha_on, bool is2t) +{ + u32 pathOn; + u32 i; + + pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (false == is2t) { + pathOn = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); +} + +static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_write_byte(rtlpriv, macreg[0], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8) (macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} + +static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else if (!(simularity_bitmap & 0xF0) && is2t) { + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } + +} + +static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + const u32 retrycount = 2; + + u32 bbvalue; + + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); + + _rtl92c_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } + _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + if (!rtlphy->b_rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, true); + if (t == 0) { + rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); + rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); + rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x03) { + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) + result[t][0] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & 0x3FF0000) >> + 16; + result[t][1] = + (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; + + } + + if (is2t) { + _rtl92c_phy_path_a_standby(hw); + _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92c_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); + rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + if (t != 0) { + if (!rtlphy->b_rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, false); + _rtl92c_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } +} + +static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, + char delta, bool is2t) +{ + /* This routine is deliberately dummied out for later fixes */ +#if 0 + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + u32 reg_d[PATH_NUM]; + u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; + + u32 bb_backup[APK_BB_REG_NUM]; + u32 bb_reg[APK_BB_REG_NUM] = { + 0x904, 0xc04, 0x800, 0xc08, 0x874 + }; + u32 bb_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 + }; + u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 + }; + + u32 afe_backup[APK_AFE_REG_NUM]; + u32 afe_reg[APK_AFE_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, + 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, + 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, + 0xeec + }; + + u32 mac_backup[IQK_MAC_REG_NUM]; + u32 mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; + + u32 afe_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4 + }; + + u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; + + u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; + + u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; + + u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; + + const char apk_delta_mapping[APK_BB_REG_NUM][13] = { + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + const u32 apk_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + const u32 apk_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; + + long bb_offset, delta_v, delta_offset; + + if (!is2t) + pathbound = 1; + + for (index = 0; index < PATH_NUM; index++) { + apk_offset[index] = apk_normal_offset[index]; + apk_value[index] = apk_normal_value[index]; + afe_on_off[index] = 0x6fdb25a4; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + for (path = 0; path < pathbound; path++) { + apk_rf_init_value[path][index] = + apk_normal_rf_init_value[path][index]; + apk_rf_value_0[path][index] = + apk_normal_rf_value_0[path][index]; + } + bb_ap_mode[index] = bb_normal_ap_mode[index]; + + apkbound = 6; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); + } + + _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); + + _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + if (path == RF90_PATH_A) { + offset = 0xb00; + for (index = 0; index < 11; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb00; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } else if (path == RF90_PATH_B) { + offset = 0xb70; + for (index = 0; index < 10; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + index = 11; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb60; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } + + reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, + 0xd, MASKDWORD); + + for (index = 0; index < APK_AFE_REG_NUM; index++) + rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, + afe_on_off[path]); + + if (path == RF90_PATH_A) { + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, + bb_ap_mode[index]); + } + } + + _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); + + if (path == 0) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); + } else { + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, + 0x10000); + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20103); + } + + delta_offset = ((delta + 14) / 2); + if (delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index != 1) + continue; + + tmpreg = apk_rf_init_value[path][index]; + + if (!rtlefuse->b_apk_thermalmeterignore) { + bb_offset = (tmpreg & 0xF0000) >> 16; + + if (!(tmpreg & BIT(15))) + bb_offset = -bb_offset; + + delta_v = + apk_delta_mapping[index][delta_offset]; + + bb_offset += delta_v; + + if (bb_offset < 0) { + tmpreg = tmpreg & (~BIT(15)); + bb_offset = -bb_offset; + } else { + tmpreg = tmpreg | BIT(15); + } + + tmpreg = + (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); + } + + rtl_set_rfreg(hw, (enum radio_path)path, 0xc, + MASKDWORD, 0x8992e); + rtl_set_rfreg(hw, (enum radio_path)path, 0x0, + MASKDWORD, apk_rf_value_0[path][index]); + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, tmpreg); + + i = 0; + do { + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[0]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(3); + + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[1]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(20); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + + if (path == RF90_PATH_A) + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0x03E00000); + else + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0xF8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset " + "0xbd8[25:21] %x\n", tmpreg)); + + i++; + + } while (tmpreg > apkbound && i < 4); + + apk_result[path][index] = tmpreg; + } + } + + _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); + } + + _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, reg_d[path]); + + if (path == RF90_PATH_B) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20101); + } + + if (apk_result[path][1] > 6) + apk_result[path][1] = 6; + } + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (apk_result[path][1] << 5) | + apk_result[path][1])); + + if (path == RF90_PATH_A) + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x00 << 5) | 0x05)); + else + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x02 << 5) | 0x05)); + + rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, + ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | + 0x08)); + + } + + rtlphy->b_apk_done = true; +#endif +} + +static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) { + rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); + rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); + else + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); + + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, + reg_ecc, reg_tmp = 0; + bool is12simular, is13simular, is23simular; + bool b_start_conttx = false, b_singletone = false; + u32 iqk_bb_reg[10] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + _rtl92c_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); + return; + } + if (b_start_conttx || b_singletone) + return; + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + b_pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_iq_calibrate(hw, result, i, true); + else + _rtl92c_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92c_phy_simularity_compare(hw, + result, 1, + 2); + if (is23simular) + final_candidate = 1; + else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; + rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + reg_eac = result[final_candidate][3]; + rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; + rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; + reg_ec4 = result[final_candidate][6]; + reg_ecc = result[final_candidate][7]; + b_patha_ok = b_pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ + _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (IS_92C_SERIAL(rtlhal->version)) { + if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ + _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, + result, + final_candidate, + (reg_ec4 == 0)); + } + _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); +} + +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_start_conttx = false, b_singletone = false; + + if (b_start_conttx || b_singletone) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_lc_calibrate(hw, true); + else + _rtl92c_phy_lc_calibrate(hw, false); +} + +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->b_apk_done) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_ap_calibrate(hw, delta, true); + else + _rtl92c_phy_ap_calibrate(hw, delta, false); +} + +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_set_rfpath_switch(hw, bmain, true); + else + _rtl92c_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool b_postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress)); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Resume DM after scan.\n")); + b_postprocessing = true; + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Pause DM before scan.\n")); + b_postprocessing = true; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } while (false); + if (b_postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92c_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + return true; +} + +void rtl92c_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress)); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92c_dm_write_dig(hw); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; + dm_digtable.cur_igvalue = 0x17; + rtl92c_dm_write_dig(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("<---(%#x)\n", rtlphy->current_io_type)); +} + +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + u32 u4b_tmp; + u8 delay = 5; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4b_tmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Switch RF timeout !!!.\n")); + return; + } + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + ppsc->set_rfpowerstate_inprogress = true; + switch (rfpwr_state) { + case ERFON:{ + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 InitializeCount = 0; + do { + InitializeCount++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic enable\n")); + rtstatus = rtl_ps_enable_nic(hw); + } while ((rtstatus != true) + && (InitializeCount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies))); + ppsc->last_awake_jiffies = jiffies; + rtl92ce_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + } + case ERFOFF:{ + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] " + "=%d before doze!\n", (i + 1), + queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\nERFOFF: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic disable\n")); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + } + case ERFSLEEP:{ + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] =%d before " + "doze!\n", (i + 1), queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\n ERFSLEEP: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies))); + ppsc->last_sleep_jiffies = jiffies; + _rtl92ce_phy_set_rf_sleep(hw); + break; + } + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + ppsc->set_rfpowerstate_inprogress = false; + return bresult; +} + +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h new file mode 100644 index 000000000000..ca4daee6e9a8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h @@ -0,0 +1,237 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define AntennaDiversityValue 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF90_PATH_MAX 2 +#define CHANNEL_MAX_NUMBER 14 +#define CHANNEL_GROUP_MAX 3 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 +#define CHANNEL_MAX_NUMBER 14 +#define CHANNEL_GROUP_MAX 3 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, + u16 beaconinterval); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, + u32 rfpath); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h new file mode 100644 index 000000000000..875d51465225 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h @@ -0,0 +1,2065 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_REG_H__ +#define __RTL92C_REG_H__ + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_C2HEVT_CLEAR 0x01BF +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_USTIME_TSF 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \ + | RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_C2HCMD BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +#define HWSET_MAX_SIZE 128 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x12 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8192_EEPROM_ID 0x8129 + +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_VID 0x0A +#define EEPROM_DID 0x0C +#define EEPROM_SVID 0x0E +#define EEPROM_SMID 0x10 + +#define EEPROM_MAC_ADDR 0x16 + +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F +#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 + +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 +#define EEPROM_XTAL_K 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_CHANNEL_PLAN 0x7D +#define EEPROM_VERSION 0x7E +#define EEPROM_CUSTOMER_ID 0x7F + +#define EEPROM_PWRDIFF 0x54 + +#define EEPROM_TXPOWERCCK 0x5A +#define EEPROM_TXPOWERHT40_1S 0x60 +#define EEPROM_TXPOWERHT40_2SDIFF 0x66 +#define EEPROM_TXPOWERHT20DIFF 0x69 +#define EEPROM_TXPOWER_OFDMDIFF 0x6C + +#define EEPROM_TXPWR_GROUP 0x6F + +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 + +#define EEPROM_CHANNELPLAN 0x75 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define Timer_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EnBT BIT(5) +#define EnUart BIT(8) +#define Uart_910 BIT(9) +#define EnPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EnSIC BIT(12) +#define SIC_23 BIT(13) +#define EnHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TxUseDK BIT(0) +#define SCR_RxUseDK BIT(1) +#define SCR_TxEncEnable BIT(2) +#define SCR_RxDecEnable BIT(3) +#define SCR_SKByA2 BIT(4) +#define SCR_NoSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32Er 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define rFPGA0_XAB_RFPARAMETER 0x878 +#define rFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LT F 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_Offset) \ + ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define bCCKRxRFSettle 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c new file mode 100644 index 000000000000..a2d58df5d3a0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c @@ -0,0 +1,523 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-rf.h" +#include "rtl8192c-dm.h" + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", bandwidth)); + break; + } +} + +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning == true) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32)); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + if (mac->mode == WIRELESS_MODE_B) + tmpval = tmpval & 0xff00ffff; + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32)); +} + +static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerBase0, powerBase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerBase0 = powerlevel[i] + legacy_pwrdiff; + + powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | + (powerBase0 << 8) | powerBase0; + *(ofdmbase + i) = powerBase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerBase1 = powerlevel[i]; + powerBase1 = (powerBase1 << 24) | + (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; + + *(mcsbase + i) = powerBase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + } +} + +static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerBase0, + u32 *powerBase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup, pwr_diff_limit[4]; + u32 writeVal, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 1: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + writeVal = ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, 40MHz, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + } else { + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->pwrgroup_cnt == 4) + chnlgroup++; + } + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerBase0[rf] : + powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, 20MHz, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + } + break; + case 2: + writeVal = + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Better regulatory, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 40MHz " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf][channel - + 1])); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 20MHz " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf][channel - + 1])); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> + (i * 8)); + + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht40[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht20[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit)); + + writeVal = customer_limit + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer, writeVal rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + default: + chnlgroup = 0; + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance, writeVal " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeVal = writeVal - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeVal = writeVal - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeVal; + } +} + +static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pValue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeVal; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeVal = pValue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8) ((writeVal & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Set 0x%x = %08x\n", regoffset, writeVal)); + + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + + writeVal = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + + for (i = 0; i < 3; i++) { + writeVal = (writeVal > 6) ? (writeVal - 6) : 0; + rtl_write_byte(rtlpriv, (u32) (regoffset + i), + (u8) writeVal); + } + } + } +} + +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeVal[2], powerBase0[2], powerBase1[2]; + u8 index; + + rtl92c_phy_get_power_base(hw, ppowerlevel, + channel, &powerBase0[0], &powerBase1[0]); + + for (index = 0; index < 6; index++) { + _rtl92c_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerBase0[0], + &powerBase1[0], + &writeVal[0]); + + _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]); + } +} + +bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl92c_phy_rf6052_config_parafile(hw); +} + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue; + u8 rfpath; + bool rtstatus; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio[%d] Fail!!", rfpath)); + return false; + } + + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + return rtstatus; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h new file mode 100644 index 000000000000..d3014f99bb7b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_RF_H__ +#define __RTL92C_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 + +extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c new file mode 100644 index 000000000000..3cdca006be2a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c @@ -0,0 +1,280 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-dm.h" +#include "rtl8192c-hw.h" +#include "rtl8192c-sw.h" +#include "rtl8192c-trx.h" +#include "rtl8192c-led.h" + +int rtl92c_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtlpriv->dm.b_dm_initialgain_enable = 1; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.b_disable_framebursting = 0;; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + rtlpci->receive_config = (RCR_APPFCS | + RCR_AMF | + RCR_ADF | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0); + + rtlpci->irq_mask[0] = + (u32) (IMR_ROK | + IMR_VODOK | + IMR_VIDOK | + IMR_BEDOK | + IMR_BKDOK | + IMR_MGNTDOK | + IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0); + + rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); + + rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000); + if (!rtlpriv->rtlhal.pfirmware) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't alloc buffer for fw.\n")); + return 1; + } + + return 0; +} + +void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +static struct rtl_hal_ops rtl8192ce_hal_ops = { + .init_sw_vars = rtl92c_init_sw_vars, + .deinit_sw_vars = rtl92c_deinit_sw_vars, + .read_eeprom_info = rtl92ce_read_eeprom_info, + .interrupt_recognized = rtl92ce_interrupt_recognized, + .hw_init = rtl92ce_hw_init, + .hw_disable = rtl92ce_card_disable, + .enable_interrupt = rtl92ce_enable_interrupt, + .disable_interrupt = rtl92ce_disable_interrupt, + .set_network_type = rtl92ce_set_network_type, + .set_qos = rtl92ce_set_qos, + .set_bcn_reg = rtl92ce_set_beacon_related_registers, + .set_bcn_intv = rtl92ce_set_beacon_interval, + .update_interrupt_mask = rtl92ce_update_interrupt_mask, + .get_hw_reg = rtl92ce_get_hw_reg, + .set_hw_reg = rtl92ce_set_hw_reg, + .update_rate_table = rtl92ce_update_hal_rate_table, + .update_rate_mask = rtl92ce_update_hal_rate_mask, + .fill_tx_desc = rtl92ce_tx_fill_desc, + .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, + .query_rx_desc = rtl92ce_rx_query_desc, + .set_channel_access = rtl92ce_update_channel_access_setting, + .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking, + .set_bw_mode = rtl92c_phy_set_bw_mode, + .switch_channel = rtl92c_phy_sw_chnl, + .dm_watchdog = rtl92c_dm_watchdog, + .scan_operation_backup = rtl92c_phy_scan_operation_backup, + .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .led_control = rtl92ce_led_control, + .set_desc = rtl92ce_set_desc, + .get_desc = rtl92ce_get_desc, + .tx_polling = rtl92ce_tx_polling, + .enable_hw_sec = rtl92ce_enable_hw_security_config, + .set_key = rtl92ce_set_key, + .init_sw_leds = rtl92ce_init_sw_leds, + .deinit_sw_leds = rtl92ce_deinit_sw_leds, + .get_bbreg = rtl92c_phy_query_bb_reg, + .set_bbreg = rtl92c_phy_set_bb_reg, + .get_rfreg = rtl92c_phy_query_rf_reg, + .set_rfreg = rtl92c_phy_set_rf_reg, +}; + +static struct rtl_mod_params rtl92ce_mod_params = { + .sw_crypto = 0, +}; + +static struct rtl_hal_cfg rtl92ce_hal_cfg = { + .name = "rtl92c_pci", + .fw_name = "rtlwifi/rtl8192cfw.bin", + .ops = &rtl8192ce_hal_ops, + .mod_params = &rtl92ce_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BcnInt] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); + +module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); +MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); + +static struct pci_driver rtl92ce_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92ce_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + +#ifdef CONFIG_PM + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, +#endif + +}; + +static int __init rtl92ce_module_init(void) +{ + int ret; + + ret = pci_register_driver(&rtl92ce_driver); + if (ret) + RT_ASSERT(false, (": No device found\n")); + + return ret; +} + +static void __exit rtl92ce_module_exit(void) +{ + pci_unregister_driver(&rtl92ce_driver); +} + +module_init(rtl92ce_module_init); +module_exit(rtl92ce_module_exit); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h new file mode 100644 index 000000000000..de1198c38d4e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_SW_H__ +#define __RTL92CE_SW_H__ + +int rtl92c_init_sw_vars(struct ieee80211_hw *hw); +void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); +void rtl92c_init_var_map(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c new file mode 100644 index 000000000000..2a9bbbe691a4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c @@ -0,0 +1,1224 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Created on 2010/ 5/18, 1:41 + * + * Larry Finger + * + *****************************************************************************/ + +#include "rtl8192c-table.h" + + +u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x2b2b2b27, + 0x870, 0x07000700, + 0x874, 0x22184000, + 0x878, 0x08080808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c1b25a4, + 0xe78, 0x0c1b25a4, + 0xe7c, 0x0c1b25a4, + 0xe80, 0x0c1b25a4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c1b25a4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000700, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x0a0c0c0c, + 0xe04, 0xffffffff, 0x02040608, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0e, + 0xe14, 0xffffffff, 0x02040608, + 0xe18, 0xffffffff, 0x0a0c0d0e, + 0xe1c, 0xffffffff, 0x02040608, + 0x830, 0xffffffff, 0x0a0c0c0c, + 0x834, 0xffffffff, 0x02040608, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0a0c0d0e, + 0x848, 0xffffffff, 0x02040608, + 0x84c, 0xffffffff, 0x0a0c0d0e, + 0x868, 0xffffffff, 0x02040608, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x06060606, + 0xe1c, 0xffffffff, 0x00020406, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x06060606, + 0x868, 0xffffffff, 0x00020406, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, +}; + +u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = { + 0x0, +}; + +u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000088, + 0x461, 0x00000088, + 0x462, 0x00000006, + 0x463, 0x00000003, + 0x4c8, 0x00000004, + 0x4c9, 0x00000008, + 0x4cc, 0x00000002, + 0x4cd, 0x00000028, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000020, + 0x547, 0x00000000, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h new file mode 100644 index 000000000000..3a6e8b6aeee0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Created on 2010/ 5/18, 1:41 + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_TABLE__H_ +#define __RTL92CE_TABLE__H_ + +#include + +#define PHY_REG_2TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH]; +#define PHY_REG_1TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH]; +#define PHY_REG_ARRAY_PGLENGTH 192 +extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH]; +#define RADIOA_2TARRAYLENGTH 282 +extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH]; +#define RADIOB_2TARRAYLENGTH 78 +extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH]; +#define RADIOA_1TARRAYLENGTH 282 +extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH]; +#define RADIOB_1TARRAYLENGTH 1 +extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 162 +extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_2TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH]; +#define AGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c new file mode 100644 index 000000000000..cf35418c8afe --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c @@ -0,0 +1,1031 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "rtl8192c-reg.h" +#include "rtl8192c-def.h" +#include "rtl8192c-phy.h" +#include "rtl8192c-trx.h" +#include "rtl8192c-led.h" + +static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc, + unsigned int + skb_queue) +{ + enum rtl_desc_qsel qsel; + + if (unlikely(ieee80211_is_beacon(fc))) { + qsel = QSLT_BEACON; + return qsel; + } + + if (ieee80211_is_mgmt(fc)) { + qsel = QSLT_MGNT; + return qsel; + } + + switch (skb_queue) { + case VO_QUEUE: + qsel = QSLT_VO; + break; + case VI_QUEUE: + qsel = QSLT_VI; + break; + case BE_QUEUE: + qsel = QSLT_BE; + break; + case BK_QUEUE: + qsel = QSLT_BK; + break; + default: + qsel = QSLT_BE; + RT_ASSERT(false, ("BE queue, skb_queue:%d," + " set qsel = 0x%X\n", skb_queue, QSLT_BE)); + break; + } + return qsel; +} + +static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) +{ + int rate_idx; + + if (first_ampdu) { + if (false == isht) { + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 0; + break; + } + } else { + rate_idx = 11; + } + + return rate_idx; + } + + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 11; + break; + } + return rate_idx; +} + +static u8 _rtl92c_query_rxpwrpercentage(char antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +static u8 _rtl92c_evm_db_to_percentage(char value) +{ + char ret_val; + ret_val = value; + + if (ret_val >= 0) + ret_val = 0; + + if (ret_val <= -33) + ret_val = -33; + + ret_val = 0 - ret_val; + ret_val *= 3; + + if (ret_val == 99) + ret_val = 100; + + return ret_val; +} + +static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw, + long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} + +static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, + bool b_packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_sts_cck_8192s_t *cck_buf; + s8 rx_pwr_all, rx_pwr[4]; + u8 rf_rx_num, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi; + bool is_cck_rate; + + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); + pstats->b_packet_matchbssid = bpacket_match_bssid; + pstats->b_packet_toself = bpacket_toself; + pstats->b_is_cck = is_cck_rate; + pstats->b_packet_beacon = b_packet_beacon; + pstats->b_is_cck = is_cck_rate; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; + + if (is_cck_rate) { + u8 report, cck_highpwr; + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + + cck_highpwr = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + + if (bpacket_match_bssid) { + u8 sq; + if (pstats->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstats->signalquality = sq; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; + } + } else { + rtlpriv->dm.brfpath_rxenable[0] = + rtlpriv->dm.brfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + if (rtlpriv->dm.brfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = + ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; + rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + if (bpacket_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + + if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 && + pdesc->rxmcs <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (bpacket_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); + } + } + } + + if (is_cck_rate) + pstats->signalstrength = + (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = + (u8) (_rtl92ce_signal_scale_mapping + (hw, total_rssi /= rf_rx_num)); +} + +static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + u32 last_rssi, tmpval; + + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + rtlpriv->stats.rssi_calculate_cnt++; + + if (rtlpriv->stats.ui_rssi.total_num++ >= + PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = + PHY_RSSI_SLID_WIN_MAX; + last_rssi = + rtlpriv->stats.ui_rssi.elements[rtlpriv-> + stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + + rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. + index++] = + pstats->signalstrength; + + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = + _rtl92ce_translate_todbm(hw, (u8) tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + } + + if (!pstats->b_is_cck && pstats->b_packet_toself) { + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + + if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) + continue; + + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + + } + + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + + } + } +} + +static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + + rtlpriv->stats.recv_signal_power = + (rtlpriv->stats.recv_signal_power * 5 + + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + return; + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + } + + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; + } else { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + _rtl92ce_update_rxsignalstatistics(hw, pstats); + } +} + +static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, n_spatialstream, tmpval; + + if (pstats->signalquality != 0) { + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = + rtlpriv->stats. + ui_link_quality.elements[rtlpriv-> + stats.ui_link_quality. + index]; + rtlpriv->stats.ui_link_quality.total_val -= + last_evm; + } + + rtlpriv->stats.ui_link_quality.total_val += + pstats->signalquality; + rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats. + ui_link_quality. + index++] = + pstats->signalquality; + + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + + for (n_spatialstream = 0; n_spatialstream < 2; + n_spatialstream++) { + if (pstats-> + rx_mimo_signalquality[n_spatialstream] != + -1) { + if (rtlpriv->stats. + rx_evm_percentage[n_spatialstream] + == 0) { + rtlpriv->stats. + rx_evm_percentage + [n_spatialstream] = + pstats->rx_mimo_signalquality + [n_spatialstream]; + } + + rtlpriv->stats. + rx_evm_percentage[n_spatialstream] = + ((rtlpriv-> + stats.rx_evm_percentage + [n_spatialstream] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats-> + rx_mimo_signalquality + [n_spatialstream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } + } + } else { + ; + } +} + +static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + + if (!pcurrent_stats->b_packet_matchbssid && + !pcurrent_stats->b_packet_beacon) + return; + + _rtl92ce_process_ui_rssi(hw, pcurrent_stats); + _rtl92ce_process_pwdb(hw, pcurrent_stats); + _rtl92ce_process_ui_link_quality(hw, pcurrent_stats); +} + +static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + u16 fc, type; + bool b_packet_matchbssid, b_packet_toself, b_packet_beacon; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_control); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + psaddr = hdr->addr2; + + b_packet_matchbssid = + ((IEEE80211_FTYPE_CTL != type) && + (!compare_ether_addr(mac->bssid, + (fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && + (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv)); + + b_packet_toself = b_packet_matchbssid && + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(fc)) + b_packet_beacon = true; + + _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + b_packet_matchbssid, b_packet_toself, + b_packet_beacon); + + _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb) +{ + struct rx_fwinfo_92c *p_drvinfo; + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + + u32 phystatus = GET_RX_DESC_PHYST(pdesc); + stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); + stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); + stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc); + stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc); + stats->b_hwerror = (stats->b_crc | stats->b_icv); + stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); + stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); + stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); + stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); + stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) + && (GET_RX_DESC_FAGGR(pdesc) == 1)); + stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); + stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); + + rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + + if (GET_RX_DESC_CRC32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (!GET_RX_DESC_SWDEC(pdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + + if (GET_RX_DESC_BW(pdesc)) + rx_status->flag |= RX_FLAG_40MHZ; + + if (GET_RX_DESC_RXHT(pdesc)) + rx_status->flag |= RX_FLAG_HT; + + rx_status->flag |= RX_FLAG_TSFT; + + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + + rx_status->rate_idx = _rtl92ce_rate_mapping((bool) + GET_RX_DESC_RXHT(pdesc), + (u8) + GET_RX_DESC_RXMCS(pdesc), + (bool) + GET_RX_DESC_PAGGR(pdesc)); + + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + + stats->rx_bufshift); + + _rtl92ce_translate_rx_signal_stuff(hw, + skb, stats, pdesc, + p_drvinfo); + } + + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ + + return true; +} + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, struct sk_buff *skb, + unsigned int queue_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_defaultadapter = true; + + struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); + + u8 *pdesc = (u8 *) pdesc_tx; + struct rtl_tcb_desc tcb_desc; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u16 seq_number; + u16 fc = le16_to_cpu(hdr->frame_control); + u8 rate_flag = info->control.rates[0].flags; + + enum rtl_desc_qsel fw_qsel = + _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), + queue_index); + + bool b_firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + + bool b_lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, + skb->data, skb->len, + PCI_DMA_TODEVICE); + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + rtl_get_tcb_desc(hw, info, skb, &tcb_desc); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); + + if (b_firstseg) { + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + + SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); + + if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) + SET_TX_DESC_DATA_SHORTGI(pdesc, 1); + + if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && + info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_BREAK(pdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); + } + SET_TX_DESC_SEQ(pdesc, seq_number); + + SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable && + !tcb_desc. + b_cts_enable) ? 1 : 0)); + SET_TX_DESC_HW_RTS_ENABLE(pdesc, + ((tcb_desc.b_rts_enable + || tcb_desc.b_cts_enable) ? 1 : 0)); + SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0)); + SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0)); + + SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); + SET_TX_DESC_RTS_BW(pdesc, 0); + SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); + SET_TX_DESC_RTS_SHORT(pdesc, + ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? + (tcb_desc.b_rts_use_shortpreamble ? 1 : 0) + : (tcb_desc.b_rts_use_shortgi ? 1 : 0))); + + if (mac->bw_40) { + if (tcb_desc.b_packet_bw) { + SET_TX_DESC_DATA_BW(pdesc, 1); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { + SET_TX_DESC_TX_SUB_CARRIER(pdesc, + mac->cur_40_prime_sc); + } + } + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); + } + + SET_TX_DESC_LINIP(pdesc, 0); + SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); + + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); + } + + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pdesc, 0x0); + break; + + } + } + + SET_TX_DESC_PKT_ID(pdesc, 0); + SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); + + SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); + SET_TX_DESC_DISABLE_FB(pdesc, 0); + SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("Enable RDG function.\n")); + SET_TX_DESC_RDG_ENABLE(pdesc, 1); + SET_TX_DESC_HTC(pdesc, 1); + } + } + } + + SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0)); + SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0)); + + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); + + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + + if (rtlpriv->dm.b_useramask) { + SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); + SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); + } else { + SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); + SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); + } + + if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps && + ppsc->b_fwctrl_lps) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + + if (!b_defaultadapter) + SET_TX_DESC_QOS(pdesc, 1); + } + + SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1)); + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + SET_TX_DESC_BMC(pdesc, 1); + } + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); +} + +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, + u8 *pdesc, bool b_firstseg, + bool b_lastseg, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, + skb->data, skb->len, + PCI_DMA_TODEVICE); + + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); + + if (b_firstseg) + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + + SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); + + SET_TX_DESC_SEQ(pdesc, 0); + + SET_TX_DESC_LINIP(pdesc, 0); + + SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); + + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); + + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + + SET_TX_DESC_OWN(pdesc, 1); + + SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + + SET_TX_DESC_OFFSET(pdesc, 0x20); + + SET_TX_DESC_USE_RATE(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", + pdesc, TX_DESC_SIZE); +} + +void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +{ + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + SET_TX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d" + " not process\n", desc_name)); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + SET_RX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); + break; + case HW_DESC_RXPKT_LEN: + SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); + break; + case HW_DESC_RXERO: + SET_RX_DESC_EOR(pdesc, 1); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } +} + +u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) +{ + u32 ret = 0; + + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_TX_DESC_OWN(p_desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d " + "not process\n", desc_name)); + break; + } + } else { + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_RX_DESC_OWN(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = GET_RX_DESC_PKT_LEN(pdesc); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } + return ret; +} + +void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h new file mode 100644 index 000000000000..91e13c33351e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h @@ -0,0 +1,714 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_TRX_H__ +#define __RTL92CE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) +#define SET_TX_DESC_OFFSET(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) +#define SET_TX_DESC_BMC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) +#define SET_TX_DESC_HTC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) +#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) +#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) +#define SET_TX_DESC_LINIP(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) +#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) +#define SET_TX_DESC_GF(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_TX_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_TX_DESC_PKT_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 0, 16) +#define GET_TX_DESC_OFFSET(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 16, 8) +#define GET_TX_DESC_BMC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 24, 1) +#define GET_TX_DESC_HTC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 25, 1) +#define GET_TX_DESC_LAST_SEG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_TX_DESC_FIRST_SEG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_TX_DESC_LINIP(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_TX_DESC_NO_ACM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_TX_DESC_GF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_TX_DESC_OWN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_TX_DESC_MACID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) +#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) +#define SET_TX_DESC_BK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) +#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) +#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) +#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) +#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) +#define SET_TX_DESC_PIFS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) +#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) +#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) +#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) +#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) +#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) + +#define GET_TX_DESC_MACID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) +#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) +#define GET_TX_DESC_AGG_BREAK(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) +#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) +#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) +#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) +#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) +#define GET_TX_DESC_PIFS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) +#define GET_TX_DESC_RATE_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) +#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) +#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) +#define GET_TX_DESC_SEC_TYPE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) +#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) + +#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) +#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) +#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) +#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) +#define SET_TX_DESC_RAW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) +#define SET_TX_DESC_CCX(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) +#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) +#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) +#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) +#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) +#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) +#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) + +#define GET_TX_DESC_RTS_RC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) +#define GET_TX_DESC_DATA_RC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) +#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) +#define GET_TX_DESC_MORE_FRAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) +#define GET_TX_DESC_RAW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) +#define GET_TX_DESC_CCX(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) +#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) +#define GET_TX_DESC_ANTSEL_A(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) +#define GET_TX_DESC_ANTSEL_B(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) +#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) +#define GET_TX_DESC_TX_ANTL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) +#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) + +#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) +#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) +#define SET_TX_DESC_SEQ(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) +#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) + +#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) +#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) +#define GET_TX_DESC_SEQ(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) +#define GET_TX_DESC_PKT_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) + +#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) +#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) +#define SET_TX_DESC_QOS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) +#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) +#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) +#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) +#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) +#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) +#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) +#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) +#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) +#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) +#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) +#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) +#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) +#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) +#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) +#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) +#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) +#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) +#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) + +#define GET_TX_DESC_RTS_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) +#define GET_TX_DESC_AP_DCFE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) +#define GET_TX_DESC_QOS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) +#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) +#define GET_TX_DESC_USE_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) +#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) +#define GET_TX_DESC_DISABLE_FB(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) +#define GET_TX_DESC_CTS2SELF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) +#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) +#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) +#define GET_TX_DESC_PORT_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) +#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) +#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) +#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) +#define GET_TX_DESC_TX_STBC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) +#define GET_TX_DESC_DATA_SHORT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) +#define GET_TX_DESC_DATA_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) +#define GET_TX_DESC_RTS_SHORT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) +#define GET_TX_DESC_RTS_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) +#define GET_TX_DESC_RTS_SC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) +#define GET_TX_DESC_RTS_STBC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) + +#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) +#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) +#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) +#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) + +#define GET_TX_DESC_TX_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) +#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) +#define GET_TX_DESC_CCX_TAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) +#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) +#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) +#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) +#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) +#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) + +#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) +#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) +#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) +#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) +#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) +#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) +#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) +#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) + +#define GET_TX_DESC_TXAGC_A(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) +#define GET_TX_DESC_TXAGC_B(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) +#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) +#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) +#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) +#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) +#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) +#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) +#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) +#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) +#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) +#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) + +#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) +#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) +#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) +#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) +#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) +#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) + +#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) +#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) + +#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) +#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) + +#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) +#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) + +#define GET_RX_DESC_PKT_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 0, 14) +#define GET_RX_DESC_CRC32(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 14, 1) +#define GET_RX_DESC_ICV(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 15, 1) +#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 16, 4) +#define GET_RX_DESC_SECURITY(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 20, 3) +#define GET_RX_DESC_QOS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 23, 1) +#define GET_RX_DESC_SHIFT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 24, 2) +#define GET_RX_DESC_PHYST(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_RX_DESC_SWDEC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_RX_DESC_LS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_RX_DESC_FS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_RX_DESC_EOR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_RX_DESC_OWN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) +#define SET_RX_DESC_EOR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_RX_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_RX_DESC_MACID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) +#define GET_RX_DESC_TID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) +#define GET_RX_DESC_HWRSVD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) +#define GET_RX_DESC_PAGGR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) +#define GET_RX_DESC_FAGGR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) +#define GET_RX_DESC_A1_FIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) +#define GET_RX_DESC_A2_FIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) +#define GET_RX_DESC_PAM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) +#define GET_RX_DESC_PWR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) +#define GET_RX_DESC_MD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) +#define GET_RX_DESC_MF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) +#define GET_RX_DESC_TYPE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) +#define GET_RX_DESC_MC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) +#define GET_RX_DESC_BC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) +#define GET_RX_DESC_SEQ(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) +#define GET_RX_DESC_FRAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) +#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) +#define GET_RX_DESC_NEXT_IND(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) +#define GET_RX_DESC_RSVD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) + +#define GET_RX_DESC_RXMCS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) +#define GET_RX_DESC_RXHT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) +#define GET_RX_DESC_SPLCP(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) +#define GET_RX_DESC_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) +#define GET_RX_DESC_HTC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) +#define GET_RX_DESC_HWPC_ERR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) +#define GET_RX_DESC_HWPC_IND(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) +#define GET_RX_DESC_IV0(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) + +#define GET_RX_DESC_IV1(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) +#define GET_RX_DESC_TSFL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) + +#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) +#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) + +#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) +#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ +do { \ + if (_size > TX_DESC_NEXT_DESC_OFFSET) \ + memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ + else \ + memset((void *)__pdesc, 0, _size); \ +} while (0); + +#define RX_HAL_IS_CCK_RATE(_pdesc)\ + (_pdesc->rxmcs == DESC92C_RATE1M || \ + _pdesc->rxmcs == DESC92C_RATE2M || \ + _pdesc->rxmcs == DESC92C_RATE5_5M || \ + _pdesc->rxmcs == DESC92C_RATE11M) + +struct rx_fwinfo_92c { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + char rxevm[2]; + char rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __attribute__ ((packed)); + +struct tx_desc_92c { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __attribute__ ((packed)); + +struct rx_desc_92c { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __attribute__ ((packed)); + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + u8 *pdesc, struct ieee80211_tx_info *info, + struct sk_buff *skb, unsigned int qsel); +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); +void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + bool b_firstseg, bool b_lastseg, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h new file mode 100644 index 000000000000..0dd6824b1942 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -0,0 +1,1532 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_WIFI_H__ +#define __RTL_WIFI_H__ + +#include +#include +#include +#include +#include +#include "debug.h" + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT(28) +#define RF_CHANGE_BY_PS BIT(29) +#define RF_CHANGE_BY_HW BIT(30) +#define RF_CHANGE_BY_SW BIT(31) + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +/* QoS related. */ +/*aci: 0x00 Best Effort*/ +/*aci: 0x01 Background*/ +/*aci: 0x10 Video*/ +/*aci: 0x11 Voice*/ +/*Max: define total number.*/ +#define AC0_BE 0 +#define AC1_BK 1 +#define AC2_VI 2 +#define AC3_VO 3 +#define AC_MAX 4 +#define QOS_QUEUE_NUM 4 +#define RTL_MAC80211_NUM_QUEUE 5 + +#define QBSS_LOAD_SIZE 5 +#define MAX_WMMELE_LENGTH 64 + +/*slot time for 11g. */ +#define RTL_SLOT_TIME_9 9 +#define RTL_SLOT_TIME_20 20 + +/*related with tcp/ip. */ +/*if_ehther.h*/ +#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */ +#define ETH_P_IP 0x0800 /*Internet Protocol packet */ +#define ETH_P_ARP 0x0806 /*Address Resolution packet */ +#define SNAP_SIZE 6 +#define PROTOC_TYPE_SIZE 2 + +/*related with 802.11 frame*/ +#define MAC80211_3ADDR_LEN 24 +#define MAC80211_4ADDR_LEN 30 + +enum intf_type { + INTF_PCI = 0, + INTF_USB = 1, +}; + +enum radio_path { + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, +}; + +enum rt_eeprom_type { + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}; + +enum rtl_status { + RTL_STATUS_INTERFACE_START = 0, +}; + +enum hardware_type { + HARDWARE_TYPE_RTL8192E, + HARDWARE_TYPE_RTL8192U, + HARDWARE_TYPE_RTL8192SE, + HARDWARE_TYPE_RTL8192SU, + HARDWARE_TYPE_RTL8192CE, + HARDWARE_TYPE_RTL8192CU, + HARDWARE_TYPE_RTL8192DE, + HARDWARE_TYPE_RTL8192DU, + + /*keep it last*/ + HARDWARE_TYPE_NUM +}; + +enum scan_operation_backup_opt { + SCAN_OPT_BACKUP = 0, + SCAN_OPT_RESTORE, + SCAN_OPT_MAX +}; + +/*RF state.*/ +enum rf_pwrstate { + ERFON, + ERFSLEEP, + ERFOFF +}; + +struct bb_reg_def { + u32 rfintfs; + u32 rfintfi; + u32 rfintfo; + u32 rfintfe; + u32 rf3wire_offset; + u32 rflssi_select; + u32 rftxgain_stage; + u32 rfhssi_para1; + u32 rfhssi_para2; + u32 rfswitch_control; + u32 rfagc_control1; + u32 rfagc_control2; + u32 rfrxiq_imbalance; + u32 rfrx_afe; + u32 rftxiq_imbalance; + u32 rftx_afe; + u32 rflssi_readback; + u32 rflssi_readbackpi; +}; + +enum io_type { + IO_CMD_PAUSE_DM_BY_SCAN = 0, + IO_CMD_RESUME_DM_BY_SCAN = 1, +}; + +enum hw_variables { + HW_VAR_ETHER_ADDR, + HW_VAR_MULTICAST_REG, + HW_VAR_BASIC_RATE, + HW_VAR_BSSID, + HW_VAR_MEDIA_STATUS, + HW_VAR_SECURITY_CONF, + HW_VAR_BEACON_INTERVAL, + HW_VAR_ATIM_WINDOW, + HW_VAR_LISTEN_INTERVAL, + HW_VAR_CS_COUNTER, + HW_VAR_DEFAULTKEY0, + HW_VAR_DEFAULTKEY1, + HW_VAR_DEFAULTKEY2, + HW_VAR_DEFAULTKEY3, + HW_VAR_SIFS, + HW_VAR_DIFS, + HW_VAR_EIFS, + HW_VAR_SLOT_TIME, + HW_VAR_ACK_PREAMBLE, + HW_VAR_CW_CONFIG, + HW_VAR_CW_VALUES, + HW_VAR_RATE_FALLBACK_CONTROL, + HW_VAR_CONTENTION_WINDOW, + HW_VAR_RETRY_COUNT, + HW_VAR_TR_SWITCH, + HW_VAR_COMMAND, + HW_VAR_WPA_CONFIG, + HW_VAR_AMPDU_MIN_SPACE, + HW_VAR_SHORTGI_DENSITY, + HW_VAR_AMPDU_FACTOR, + HW_VAR_MCS_RATE_AVAILABLE, + HW_VAR_AC_PARAM, + HW_VAR_ACM_CTRL, + HW_VAR_DIS_Req_Qsize, + HW_VAR_CCX_CHNL_LOAD, + HW_VAR_CCX_NOISE_HISTOGRAM, + HW_VAR_CCX_CLM_NHM, + HW_VAR_TxOPLimit, + HW_VAR_TURBO_MODE, + HW_VAR_RF_STATE, + HW_VAR_RF_OFF_BY_HW, + HW_VAR_BUS_SPEED, + HW_VAR_SET_DEV_POWER, + + HW_VAR_RCR, + HW_VAR_RATR_0, + HW_VAR_RRSR, + HW_VAR_CPU_RST, + HW_VAR_CECHK_BSSID, + HW_VAR_LBK_MODE, + HW_VAR_AES_11N_FIX, + HW_VAR_USB_RX_AGGR, + HW_VAR_USER_CONTROL_TURBO_MODE, + HW_VAR_RETRY_LIMIT, + HW_VAR_INIT_TX_RATE, + HW_VAR_TX_RATE_REG, + HW_VAR_EFUSE_USAGE, + HW_VAR_EFUSE_BYTES, + HW_VAR_AUTOLOAD_STATUS, + HW_VAR_RF_2R_DISABLE, + HW_VAR_SET_RPWM, + HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_FW_JOINBSSRPT, + HW_VAR_FW_PSMODE_STATUS, + HW_VAR_1X1_RECV_COMBINE, + HW_VAR_STOP_SEND_BEACON, + HW_VAR_TSF_TIMER, + HW_VAR_IO_CMD, + + HW_VAR_RF_RECOVERY, + HW_VAR_H2C_FW_UPDATE_GTK, + HW_VAR_WF_MASK, + HW_VAR_WF_CRC, + HW_VAR_WF_IS_MAC_ADDR, + HW_VAR_H2C_FW_OFFLOAD, + HW_VAR_RESET_WFCRC, + + HW_VAR_HANDLE_FW_C2H, + HW_VAR_DL_FW_RSVD_PAGE, + HW_VAR_AID, + HW_VAR_HW_SEQ_ENABLE, + HW_VAR_CORRECT_TSF, + HW_VAR_BCN_VALID, + HW_VAR_FWLPS_RF_ON, + HW_VAR_DUAL_TSF_RST, + HW_VAR_SWITCH_EPHY_WoWLAN, + HW_VAR_INT_MIGRATION, + HW_VAR_INT_AC, + HW_VAR_RF_TIMING, + + HW_VAR_MRC, + + HW_VAR_MGT_FILTER, + HW_VAR_CTRL_FILTER, + HW_VAR_DATA_FILTER, +}; + +enum _RT_MEDIA_STATUS { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +}; + +enum rt_oem_id { + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_819x_ALPHA = 15, + RT_CID_819x_Sitecom = 16, + RT_CID_CCX = 17, + RT_CID_819x_Lenovo = 18, + RT_CID_819x_QMI = 19, + RT_CID_819x_Edimax_Belkin = 20, + RT_CID_819x_Sercomm_Belkin = 21, + RT_CID_819x_CAMEO1 = 22, + RT_CID_819x_MSI = 23, + RT_CID_819x_Acer = 24, + RT_CID_819x_HP = 27, + RT_CID_819x_CLEVO = 28, + RT_CID_819x_Arcadyan_Belkin = 29, + RT_CID_819x_SAMSUNG = 30, + RT_CID_819x_WNC_COREGA = 31, + RT_CID_819x_Foxcoon = 32, + RT_CID_819x_DELL = 33, +}; + +enum hw_descs { + HW_DESC_OWN, + HW_DESC_RXOWN, + HW_DESC_TX_NEXTDESC_ADDR, + HW_DESC_TXBUFF_ADDR, + HW_DESC_RXBUFF_ADDR, + HW_DESC_RXPKT_LEN, + HW_DESC_RXERO, +}; + +enum prime_sc { + PRIME_CHNL_OFFSET_DONT_CARE = 0, + PRIME_CHNL_OFFSET_LOWER = 1, + PRIME_CHNL_OFFSET_UPPER = 2, +}; + +enum rf_type { + RF_1T1R = 0, + RF_1T2R = 1, + RF_2T2R = 2, +}; + +enum ht_channel_width { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, +}; + +/* Ref: 802.11i sepc D10.0 7.3.2.25.1 +Cipher Suites Encryption Algorithms */ +enum rt_enc_alg { + NO_ENCRYPTION = 0, + WEP40_ENCRYPTION = 1, + TKIP_ENCRYPTION = 2, + RSERVED_ENCRYPTION = 3, + AESCCMP_ENCRYPTION = 4, + WEP104_ENCRYPTION = 5, +}; + +enum rtl_hal_state { + _HAL_STATE_STOP = 0, + _HAL_STATE_START = 1, +}; + +enum rtl_var_map { + /*reg map */ + SYS_ISO_CTRL = 0, + SYS_FUNC_EN, + SYS_CLK, + MAC_RCR_AM, + MAC_RCR_AB, + MAC_RCR_ACRC32, + MAC_RCR_ACF, + MAC_RCR_AAP, + + /*efuse map */ + EFUSE_TEST, + EFUSE_CTRL, + EFUSE_CLK, + EFUSE_CLK_CTRL, + EFUSE_PWC_EV12V, + EFUSE_FEN_ELDR, + EFUSE_LOADER_CLK_EN, + EFUSE_ANA8M, + EFUSE_HWSET_MAX_SIZE, + + /*CAM map */ + RWCAM, + WCAMI, + RCAMO, + CAMDBG, + SECR, + SEC_CAM_NONE, + SEC_CAM_WEP40, + SEC_CAM_TKIP, + SEC_CAM_AES, + SEC_CAM_WEP104, + + /*IMR map */ + RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */ + RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */ + RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */ + RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */ + RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */ + RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */ + RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrup 8 */ + RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrup 7 */ + RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrup 6 */ + RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrup 5 */ + RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrup 4 */ + RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrup 3 */ + RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrup 2 */ + RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrup 1 */ + RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */ + RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */ + RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */ + RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */ + RTL_IMR_BcnInt, /*Beacon DMA Interrupt 0 */ + RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ + RTL_IMR_RDU, /*Receive Descriptor Unavailable */ + RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ + RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ + RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ + RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */ + RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ + RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ + RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */ + RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */ + RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ + RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ + RTL_IMR_ROK, /*Receive DMA OK Interrupt */ + RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt|RTL_IMR_TBDOK|RTL_IMR_TBDER)*/ + + /*CCK Rates, TxHT = 0 */ + RTL_RC_CCK_RATE1M, + RTL_RC_CCK_RATE2M, + RTL_RC_CCK_RATE5_5M, + RTL_RC_CCK_RATE11M, + + /*OFDM Rates, TxHT = 0 */ + RTL_RC_OFDM_RATE6M, + RTL_RC_OFDM_RATE9M, + RTL_RC_OFDM_RATE12M, + RTL_RC_OFDM_RATE18M, + RTL_RC_OFDM_RATE24M, + RTL_RC_OFDM_RATE36M, + RTL_RC_OFDM_RATE48M, + RTL_RC_OFDM_RATE54M, + + RTL_RC_HT_RATEMCS7, + RTL_RC_HT_RATEMCS15, + + /*keep it last */ + RTL_VAR_MAP_MAX, +}; + +/*Firmware PS mode for control LPS.*/ +enum _fw_ps_mode { + FW_PS_ACTIVE_MODE = 0, + FW_PS_MIN_MODE = 1, + FW_PS_MAX_MODE = 2, + FW_PS_DTIM_MODE = 3, + FW_PS_VOIP_MODE = 4, + FW_PS_UAPSD_WMM_MODE = 5, + FW_PS_UAPSD_MODE = 6, + FW_PS_IBSS_MODE = 7, + FW_PS_WWLAN_MODE = 8, + FW_PS_PM_Radio_Off = 9, + FW_PS_PM_Card_Disable = 10, +}; + +enum rt_psmode { + EACTIVE, /*Active/Continuous access. */ + EMAXPS, /*Max power save mode. */ + EFASTPS, /*Fast power save mode. */ + EAUTOPS, /*Auto power save mode. */ +}; + +/*LED related.*/ +enum led_ctl_mode { + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, +}; + +enum rtl_led_pin { + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}; + +/*QoS related.*/ +/*acm implementation method.*/ +enum acm_method { + eAcmWay0_SwAndHw = 0, + eAcmWay1_HW = 1, + eAcmWay2_SW = 2, +}; + +/*aci/aifsn Field. +Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/ +union aci_aifsn { + u8 char_data; + + struct { + u8 aifsn:4; + u8 acm:1; + u8 aci:2; + u8 reserved:1; + } f; /* Field */ +}; + +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20 +}; + +enum ratr_table_mode { + RATR_INX_WIRELESS_NGB = 0, + RATR_INX_WIRELESS_NG = 1, + RATR_INX_WIRELESS_NB = 2, + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_A = 8, +}; + +enum rtl_link_state { + MAC80211_NOLINK = 0, + MAC80211_LINKING = 1, + MAC80211_LINKED = 2, + MAC80211_LINKED_SCANNING = 3, +}; + +enum act_category { + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +}; + +enum ba_action { + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +}; + +struct octet_string { + u8 *octet; + u16 length; +}; + +struct rtl_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __attribute__ ((packed)); + +struct rtl_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); + +struct rtl_probe_rsp { + struct rtl_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /*SSID, supported rates, FH params, DS params, + CF params, IBSS params, TIM (if beacon), RSN */ + struct rtl_info_element info_element[0]; +} __attribute__ ((packed)); + +/*LED related.*/ +/*ledpin Identify how to implement this SW led.*/ +struct rtl_led { + void *hw; + enum rtl_led_pin ledpin; + bool b_ledon; +}; + +struct rtl_led_ctl { + bool bled_opendrain; + struct rtl_led sw_led0; + struct rtl_led sw_led1; +}; + +struct rtl_qos_parameters { + __le16 cw_min; + __le16 cw_max; + u8 aifs; + u8 flag; + __le16 tx_op; +} __attribute__ ((packed)); + +struct rt_smooth_data { + u32 elements[100]; /*array to store values */ + u32 index; /*index to current array to store */ + u32 total_num; /*num of valid elements */ + u32 total_val; /*sum of valid elements */ +}; + +struct false_alarm_statistics { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_ofdm_fail; + u32 cnt_cck_fail; + u32 cnt_all; +}; + +struct init_gain { + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +}; + +struct wireless_stats { + unsigned long txbytesunicast; + unsigned long txbytesmulticast; + unsigned long txbytesbroadcast; + unsigned long rxbytesunicast; + + long rx_snr_db[4]; + /*Correct smoothed ss in Dbm, only used + in driver to report real power now. */ + long recv_signal_power; + long signal_quality; + long last_sigstrength_inpercent; + + u32 rssi_calculate_cnt; + + /*Transformed, in dbm. Beautified signal + strength for UI, not correct. */ + long signal_strength; + + u8 rx_rssi_percentage[4]; + u8 rx_evm_percentage[2]; + + struct rt_smooth_data ui_rssi; + struct rt_smooth_data ui_link_quality; +}; + +struct rate_adaptive { + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40m; + u32 low_rssi_thresh_for_ra40M; + u8 low2high_rssi_thresh_for_ra20m; + u32 low_rssi_thresh_for_ra20M; + u32 upper_rssi_threshold_ratr; + u32 middleupper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 middlelow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 ultralow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40m; + u32 low_rssi_threshold_ratr_20m; + u8 ping_rssi_enable; + u32 ping_rssi_ratr; + u32 ping_rssi_thresh_for_ra; + u32 last_ratr; + u8 pre_ratr_state; +}; + +struct regd_pair_mapping { + u16 reg_dmnenum; + u16 reg_5ghz_ctl; + u16 reg_2ghz_ctl; +}; + +struct rtl_regulatory { + char alpha2[2]; + u16 country_code; + u16 max_power_level; + u32 tp_scale; + u16 current_rd; + u16 current_rd_ext; + int16_t power_limit; + struct regd_pair_mapping *regpair; +}; + +struct rtl_rfkill { + bool rfkill_state; /*0 is off, 1 is on */ +}; + +struct rtl_phy { + struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ + struct init_gain initgain_backup; + enum io_type current_io_type; + + u8 rf_mode; + u8 rf_type; + u8 current_chan_bw; + u8 set_bwmode_inprogress; + u8 sw_chnl_inprogress; + u8 sw_chnl_stage; + u8 sw_chnl_step; + u8 current_channel; + u8 h2c_box_num; + u8 set_io_inprogress; + + /*record for power tracking*/ + s32 reg_e94; + s32 reg_e9c; + s32 reg_ea4; + s32 reg_eac; + s32 reg_eb4; + s32 reg_ebc; + s32 reg_ec4; + s32 reg_ecc; + u8 rfpienable; + u8 reserve_0; + u16 reserve_1; + u32 reg_c04, reg_c08, reg_874; + u32 adda_backup[16]; + u32 iqk_mac_backup[IQK_MAC_REG_NUM]; + u32 iqk_bb_backup[10]; + + bool b_rfpi_enable; + + u8 pwrgroup_cnt; + u8 bcck_high_power; + /* 3 groups of pwr diff by rates*/ + u32 mcs_txpwrlevel_origoffset[4][16]; + u8 default_initialgain[4]; + + /*the current Tx power level*/ + u8 cur_cck_txpwridx; + u8 cur_ofdm24g_txpwridx; + + u32 rfreg_chnlval[2]; + bool b_apk_done; + + /*fsync*/ + u8 framesync; + u32 framesync_c34; + + u8 num_total_rfpath; +}; + +#define MAX_TID_COUNT 9 +#define RTL_AGG_OFF 0 +#define RTL_AGG_ON 1 +#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 +#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3 + +struct rtl_ht_agg { + u16 txq_id; + u16 wait_for_ba; + u16 start_idx; + u64 bitmap; + u32 rate_n_flags; + u8 agg_state; +}; + +struct rtl_tid_data { + u16 seq_number; + struct rtl_ht_agg agg; +}; + +struct rtl_priv; +struct rtl_io { + struct device *dev; + + /*PCI MEM map */ + unsigned long pci_mem_end; /*shared mem end */ + unsigned long pci_mem_start; /*shared mem start */ + + /*PCI IO map */ + unsigned long pci_base_addr; /*device I/O address */ + + void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val); + void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val); + void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val); + + u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); + u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); + u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); + +}; + +struct rtl_mac { + u8 mac_addr[ETH_ALEN]; + u8 mac80211_registered; + u8 beacon_enabled; + + u32 tx_ss_num; + u32 rx_ss_num; + + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + enum nl80211_iftype opmode; + + /*Probe Beacon management */ + struct rtl_tid_data tids[MAX_TID_COUNT]; + enum rtl_link_state link_state; + + int n_channels; + int n_bitrates; + + /*filters */ + u32 rx_conf; + u16 rx_mgt_filter; + u16 rx_ctrl_filter; + u16 rx_data_filter; + + bool act_scanning; + u8 cnt_after_linked; + + /*RDG*/ bool rdg_en; + + /*AP*/ u8 bssid[6]; + u8 mcs[16]; /*16 bytes mcs for HT rates.*/ + u32 basic_rates; /*b/g rates*/ + u8 ht_enable; + u8 sgi_40; + u8 sgi_20; + u8 bw_40; + u8 mode; /*wireless mode*/ + u8 slot_time; + u8 short_preamble; + u8 use_cts_protect; + u8 cur_40_prime_sc; + u8 cur_40_prime_sc_bk; + u64 tsf; + u8 retry_short; + u8 retry_long; + u16 assoc_id; + + /*IBSS*/ int beacon_interval; + + /*AMPDU*/ u8 min_space_cfg; /*For Min spacing configurations */ + u8 max_mss_density; + u8 current_ampdu_factor; + u8 current_ampdu_density; + + /*QOS & EDCA */ + struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; + struct rtl_qos_parameters ac[AC_MAX]; +}; + +struct rtl_hal { + struct ieee80211_hw *hw; + + enum intf_type interface; + u16 hw_type; /*92c or 92d or 92s and so on */ + u8 oem_id; + u8 version; /*version of chip */ + u8 state; /*stop 0, start 1 */ + + /*firmware */ + u8 *pfirmware; + bool b_h2c_setinprogress; + u8 last_hmeboxnum; + bool bfw_ready; + /*Reserve page start offset except beacon in TxQ. */ + u8 fw_rsvdpage_startoffset; +}; + +struct rtl_security { + /*default 0 */ + bool use_sw_sec; + + bool being_setkey; + bool use_defaultkey; + /*Encryption Algorithm for Unicast Packet */ + enum rt_enc_alg pairwise_enc_algorithm; + /*Encryption Algorithm for Brocast/Multicast */ + enum rt_enc_alg group_enc_algorithm; + + /*local Key buffer, indx 0 is for + pairwise key 1-4 is for agoup key. */ + u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; + u8 key_len[KEY_BUF_SIZE]; + + /*The pointer of Pairwise Key, + it always points to KeyBuf[4] */ + u8 *pairwise_key; +}; + +struct rtl_dm { + /*PHY status for DM */ + long entry_min_undecoratedsmoothed_pwdb; + long undecorated_smoothed_pwdb; /*out dm */ + long entry_max_undecoratedsmoothed_pwdb; + bool b_dm_initialgain_enable; + bool bdynamic_txpower_enable; + bool bcurrent_turbo_edca; + bool bis_any_nonbepkts; /*out dm */ + bool bis_cur_rdlstate; + bool btxpower_trackingInit; + bool b_disable_framebursting; + bool b_cck_inch14; + bool btxpower_tracking; + bool b_useramask; + bool brfpath_rxenable[4]; + + u8 thermalvalue_iqk; + u8 thermalvalue_lck; + u8 thermalvalue; + u8 last_dtp_lvl; + u8 dynamic_txhighpower_lvl; /*Tx high power level */ + u8 dm_flag; /*Indicate if each dynamic mechanism's status. */ + u8 dm_type; + u8 txpower_track_control; + + char ofdm_index[2]; + char cck_index; +}; + +#define EFUSE_MAX_LOGICAL_SIZE 128 + +struct rtl_efuse { + bool bautoLoad_ok; + bool bootfromefuse; + u16 max_physical_size; + u8 contents[EFUSE_MAX_LOGICAL_SIZE]; + + u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; + u16 efuse_usedbytes; + u8 efuse_usedpercentage; + + u8 autoload_failflag; + + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u16 eeprom_svid; + u16 eeprom_smid; + u8 eeprom_oemid; + u16 eeprom_channelplan; + u8 eeprom_version; + + u8 dev_addr[6]; + + bool b_txpwr_fromeprom; + u8 eeprom_tssi[2]; + u8 eeprom_pwrlimit_ht20[3]; + u8 eeprom_pwrlimit_ht40[3]; + u8 eeprom_chnlarea_txpwr_cck[2][3]; + u8 eeprom_chnlarea_txpwr_ht40_1s[2][3]; + u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][3]; + u8 txpwrlevel_cck[2][14]; + u8 txpwrlevel_ht40_1s[2][14]; /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_2s[2][14]; /*For HT 40MHZ pwr */ + + /*For power group */ + u8 pwrgroup_ht20[2][14]; + u8 pwrgroup_ht40[2][14]; + + char txpwr_ht20diff[2][14]; /*HT 20<->40 Pwr diff */ + u8 txpwr_legacyhtdiff[2][14]; /*For HT<->legacy pwr diff */ + + u8 eeprom_regulatory; + u8 eeprom_thermalmeter; + /*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */ + u8 thermalmeter[2]; + + u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ + bool b_apk_thermalmeterignore; +}; + +struct rtl_ps_ctl { + bool set_rfpowerstate_inprogress; + bool b_in_powersavemode; + bool rfchange_inprogress; + bool b_swrf_processing; + bool b_hwradiooff; + + u32 last_sleep_jiffies; + u32 last_awake_jiffies; + u32 last_delaylps_stamp_jiffies; + + /* + * just for PCIE ASPM + * If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + * */ + bool b_support_aspm; + bool b_support_backdoor; + + /*for LPS */ + enum rt_psmode dot11_psmode; /*Power save mode configured. */ + bool b_leisure_ps; + bool b_fwctrl_lps; + u8 fwctrl_psmode; + /*For Fw control LPS mode */ + u8 b_reg_fwctrl_lps; + /*Record Fw PS mode status. */ + bool b_fw_current_inpsmode; + u8 reg_max_lps_awakeintvl; + bool report_linked; + + /*for IPS */ + bool b_inactiveps; + + u32 rfoff_reason; + + /*RF OFF Level */ + u32 cur_ps_level; + u32 reg_rfps_level; + + /*just for PCIE ASPM */ + u8 const_amdpci_aspm; + + enum rf_pwrstate inactive_pwrstate; + enum rf_pwrstate rfpwr_state; /*cur power state */ +}; + +struct rtl_stats { + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u16 rate; /*in 100 kbps */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 length; + u8 signalquality; /*in 0-100 index. */ + /* + * Real power in dBm for this packet, + * no beautification and aggregation. + * */ + s32 recvsignalpower; + s8 rxpower; /*in dBm Translate from PWdB */ + u8 signalstrength; /*in 0-100 index. */ + u16 b_hwerror:1; + u16 b_crc:1; + u16 b_icv:1; + u16 b_shortpreamble:1; + u16 antenna:1; + u16 decrypted:1; + u16 wakeup:1; + u32 timestamp_low; + u32 timestamp_high; + + u8 rx_drvinfo_size; + u8 rx_bufshift; + bool b_isampdu; + bool rx_is40Mhzpacket; + u32 rx_pwdb_all; + u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ + s8 rx_mimo_signalquality[2]; + bool b_packet_matchbssid; + bool b_is_cck; + bool b_packet_toself; + bool b_packet_beacon; /*for rssi */ + char cck_adc_pwdb[4]; /*for rx path selection */ +}; + +struct rt_link_detect { + u32 num_tx_in4period[4]; + u32 num_rx_in4period[4]; + + u32 num_tx_inperiod; + u32 num_rx_inperiod; + + bool b_busytraffic; + bool b_higher_busytraffic; + bool b_higher_busyrxtraffic; +}; + +struct rtl_tcb_desc { + u8 b_packet_bw:1; + u8 b_multicast:1; + u8 b_broadcast:1; + + u8 b_rts_stbc:1; + u8 b_rts_enable:1; + u8 b_cts_enable:1; + u8 b_rts_use_shortpreamble:1; + u8 b_rts_use_shortgi:1; + u8 rts_sc:1; + u8 b_rts_bw:1; + u8 rts_rate; + + u8 use_shortgi:1; + u8 use_shortpreamble:1; + u8 use_driver_rate:1; + u8 disable_ratefallback:1; + + u8 ratr_index; + u8 mac_id; + u8 hw_rate; +}; + +struct rtl_hal_ops { + int (*init_sw_vars) (struct ieee80211_hw *hw); + void (*deinit_sw_vars) (struct ieee80211_hw *hw); + void (*read_eeprom_info) (struct ieee80211_hw *hw); + void (*interrupt_recognized) (struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb); + int (*hw_init) (struct ieee80211_hw *hw); + void (*hw_disable) (struct ieee80211_hw *hw); + void (*enable_interrupt) (struct ieee80211_hw *hw); + void (*disable_interrupt) (struct ieee80211_hw *hw); + int (*set_network_type) (struct ieee80211_hw *hw, + enum nl80211_iftype type); + void (*set_bw_mode) (struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); + u8(*switch_channel) (struct ieee80211_hw *hw); + void (*set_qos) (struct ieee80211_hw *hw, int aci); + void (*set_bcn_reg) (struct ieee80211_hw *hw); + void (*set_bcn_intv) (struct ieee80211_hw *hw); + void (*update_interrupt_mask) (struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); + void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*update_rate_table) (struct ieee80211_hw *hw); + void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); + void (*fill_tx_desc) (struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, + struct sk_buff *skb, unsigned int queue_index); + void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, + bool b_firstseg, bool b_lastseg, + struct sk_buff *skb); + bool(*query_rx_desc) (struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); + void (*set_channel_access) (struct ieee80211_hw *hw); + bool(*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid); + void (*dm_watchdog) (struct ieee80211_hw *hw); + void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation); + bool(*set_rf_power_state) (struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + void (*led_control) (struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); + u32(*get_desc) (u8 *pdesc, bool istx, u8 desc_name); + void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); + void (*enable_hw_sec) (struct ieee80211_hw *hw); + void (*set_key) (struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + void (*init_sw_leds) (struct ieee80211_hw *hw); + void (*deinit_sw_leds) (struct ieee80211_hw *hw); + u32(*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); + void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); + u32(*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); + void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +}; + +struct rtl_intf_ops { + /*com */ + int (*adapter_start) (struct ieee80211_hw *hw); + void (*adapter_stop) (struct ieee80211_hw *hw); + + int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); + int (*reset_trx_ring) (struct ieee80211_hw *hw); + + /*pci */ + void (*disable_aspm) (struct ieee80211_hw *hw); + void (*enable_aspm) (struct ieee80211_hw *hw); + + /*usb */ +}; + +struct rtl_mod_params { + /* default: 0 = using hardware encryption */ + int sw_crypto; +}; + +struct rtl_hal_cfg { + char *name; + char *fw_name; + struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + + /*this map used for some registers or vars + defined int HAL but used in MAIN */ + u32 maps[RTL_VAR_MAP_MAX]; + +}; + +struct rtl_locks { + /*sem */ + struct semaphore ips_sem; + struct semaphore conf_sem; + + /*spin lock */ + spinlock_t irq_th_lock; + spinlock_t h2c_lock; + spinlock_t rf_ps_lock; + spinlock_t rf_lock; + spinlock_t lps_lock; +}; + +struct rtl_works { + struct ieee80211_hw *hw; + + /*timer */ + struct timer_list watchdog_timer; + + /*task */ + struct tasklet_struct irq_tasklet; + struct tasklet_struct irq_prepare_bcn_tasklet; + + /*work queue */ + struct workqueue_struct *rtl_wq; + struct delayed_work watchdog_wq; + struct delayed_work ips_nic_off_wq; +}; + +struct rtl_debug { + u32 dbgp_type[DBGP_TYPE_MAX]; + u32 global_debuglevel; + u64 global_debugcomponents; +}; + +struct rtl_priv { + struct rtl_locks locks; + struct rtl_works works; + struct rtl_mac mac80211; + struct rtl_hal rtlhal; + struct rtl_regulatory regd; + struct rtl_rfkill rfkill; + struct rtl_io io; + struct rtl_phy phy; + struct rtl_dm dm; + struct rtl_security sec; + struct rtl_efuse efuse; + + struct rtl_ps_ctl psc; + struct rate_adaptive ra; + struct wireless_stats stats; + struct rt_link_detect link_info; + struct false_alarm_statistics falsealm_cnt; + + struct rtl_rate_priv *rate_priv; + + struct rtl_debug dbg; + + /* + *hal_cfg : for diff cards + *intf_ops : for diff interrface usb/pcie + */ + struct rtl_hal_cfg *cfg; + struct rtl_intf_ops *intf_ops; + + /*this var will be set by set_bit, + and was used to indicate status of + interface or hardware */ + unsigned long status; + + /*This must be the last item so + that it points to the data allocated + beyond this structure like: + rtl_pci_priv or rtl_usb_priv */ + u8 priv[0]; +}; + +#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211)) +#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal)) +#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) +#define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) + +/**************************************** + mem access macro define start + Call endian free function when + 1. Read/write packet content. + 2. Before write integer to IO. + 3. After read integer from IO. +****************************************/ +/* Convert little data endian to host */ +#define EF1BYTE(_val) \ + ((u8)(_val)) +#define EF2BYTE(_val) \ + (le16_to_cpu(_val)) +#define EF4BYTE(_val) \ + (le32_to_cpu(_val)) + +/* Read data from memory */ +#define READEF1BYTE(_ptr) \ + EF1BYTE(*((u8 *)(_ptr))) +#define READEF2BYTE(_ptr) \ + EF2BYTE(*((u16 *)(_ptr))) +#define READEF4BYTE(_ptr) \ + EF4BYTE(*((u32 *)(_ptr))) + +/* Write data to memory */ +#define WRITEEF1BYTE(_ptr, _val) \ + (*((u8 *)(_ptr))) = EF1BYTE(_val) +#define WRITEEF2BYTE(_ptr, _val) \ + (*((u16 *)(_ptr))) = EF2BYTE(_val) +#define WRITEEF4BYTE(_ptr, _val) \ + (*((u32 *)(_ptr))) = EF4BYTE(_val) + +/*Example: +BIT_LEN_MASK_32(0) => 0x00000000 +BIT_LEN_MASK_32(1) => 0x00000001 +BIT_LEN_MASK_32(2) => 0x00000003 +BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/ +#define BIT_LEN_MASK_32(__bitlen) \ + (0xFFFFFFFF >> (32 - (__bitlen))) +#define BIT_LEN_MASK_16(__bitlen) \ + (0xFFFF >> (16 - (__bitlen))) +#define BIT_LEN_MASK_8(__bitlen) \ + (0xFF >> (8 - (__bitlen))) + +/*Example: +BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/ +#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_16(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) + +/*Description: +Return 4-byte value in host byte ordering from +4-byte pointer in little-endian system.*/ +#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ + (EF4BYTE(*((u32 *)(__pstart)))) +#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ + (EF2BYTE(*((u16 *)(__pstart)))) +#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ + (EF1BYTE(*((u8 *)(__pstart)))) + +/*Description: +Translate subfield (continuous bits in little-endian) of 4-byte +value to host byte ordering.*/ +#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_32(__bitlen) \ + ) +#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_16(__bitlen) \ + ) +#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_8(__bitlen) \ + ) + +/*Description: +Mask subfield (continuous bits in little-endian) of 4-byte value +and return the result in 4-byte value in host byte ordering.*/ +#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ + ) + +/*Description: +Set subfield of little-endian 4-byte value to specified value. */ +#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ + *((u32 *)(__pstart)) = EF4BYTE \ + ( \ + LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ + ); +#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ + *((u16 *)(__pstart)) = EF2BYTE \ + ( \ + LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ + ); +#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ + *((u8 *)(__pstart)) = EF1BYTE \ + ( \ + LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ + ); + +/**************************************** + mem access macro define end +****************************************/ + +#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) +#define RTL_WATCH_DOG_TIME 2000 +#define MSECS(t) msecs_to_jiffies(t) +#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */ +/*NIC halt, re-initialize hw parameters*/ +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */ +#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ +/*Always enable ASPM and Clock Req in initialization.*/ +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) +/*When LPS is on, disable 2R if no packet is received or transmittd.*/ +#define RT_RF_LPS_DISALBE_2R BIT(30) +#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ +#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \ + ((ppsc->cur_ps_level & _ps_flg) ? true : false) +#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level &= (~(_ps_flg))) +#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level |= _ps_flg) + +#define container_of_dwork_rtl(x, y, z) \ + container_of(container_of(x, struct delayed_work, work), y, z) + +#define FILL_OCTET_STRING(_os, _octet, _len) \ + (_os).octet = (u8 *)(_octet); \ + (_os).length = (_len); + +#define CP_MACADDR(des, src) \ + ((des)[0] = (src)[0], (des)[1] = (src)[1],\ + (des)[2] = (src)[2], (des)[3] = (src)[3],\ + (des)[4] = (src)[4], (des)[5] = (src)[5]) + +static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read8_sync(rtlpriv, addr); +} + +static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read16_sync(rtlpriv, addr); +} + +static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read32_sync(rtlpriv, addr); +} + +static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) +{ + rtlpriv->io.write8_async(rtlpriv, addr, val8); +} + +static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) +{ + rtlpriv->io.write16_async(rtlpriv, addr, val16); +} + +static inline void rtl_write_dword(struct rtl_priv *rtlpriv, + u32 addr, u32 val32) +{ + rtlpriv->io.write32_async(rtlpriv, addr, val32); +} + +static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask) +{ + return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_bbreg(hw, + regaddr, + bitmask); +} + +static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_bbreg(hw, + regaddr, bitmask, + data); + +} + +static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask) +{ + return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_rfreg(hw, + rfpath, + regaddr, + bitmask); +} + +static inline void rtl_set_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data) +{ + ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_rfreg(hw, + rfpath, regaddr, + bitmask, data); +} + +static inline bool is_hal_stop(struct rtl_hal *rtlhal) +{ + return (_HAL_STATE_STOP == rtlhal->state); +} + +static inline void set_hal_start(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_START; +} + +static inline void set_hal_stop(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_STOP; +} + +static inline u8 get_rf_type(struct rtl_phy *rtlphy) +{ + return rtlphy->rf_type; +} + +#endif -- cgit v1.2.3-59-g8ed1b From 4dc3530df7c0428b41c00399a7ee8c929406d181 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 14 Dec 2010 13:18:28 +0530 Subject: ath9k: Make PM-QOS value as user configurable This patch allows the pm-qos value to be user configurable by making it as a module parameter.This will help our customers to configure the pm-qos value according to the effect in throughput due to the DMA latency problem which was observed in Intel Pinetrail platforms. The tested value of '55' will be filled as the default pm-qos-value incase the user does not specifies pm-qos value as a module parameter. example usage: sudo modprobe ath9k pmqos=65 Cc: Senthilkumar Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ drivers/net/wireless/ath/ath9k/init.c | 4 ++++ drivers/net/wireless/ath/ath9k/main.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9b5501f90010..b0b1216dae0a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -57,6 +57,8 @@ struct ath_node; #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define ATH9K_PM_QOS_DEFAULT_VALUE 55 + #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) @@ -663,6 +665,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) extern struct ieee80211_ops ath9k_ops; extern int modparam_nohwcrypt; extern int led_blink; +extern int ath9k_pm_qos_value; irqreturn_t ath_isr(int irq, void *dev); int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b2983ce19dfb..12387950b449 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -41,6 +41,10 @@ static int ath9k_btcoex_enable; module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); +int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; +module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); + /* We use the hw_value as an index into our private channel structure */ #define CHAN2G(_freq, _idx) { \ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c68205dea1fa..36f4f5afe738 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1196,7 +1196,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } - pm_qos_update_request(&sc->pm_qos_req, 55); + pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) common->bus_ops->extn_synch_en(common); -- cgit v1.2.3-59-g8ed1b From 14a085e77063090fb12ad391d0f4d46e593be225 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 14 Dec 2010 07:38:58 -0800 Subject: iwlagn: fix witespace damage patch "iwlagn: check ready in iwlagn_bss_info_changed()" introduce whitespace, fix it please merge with the previous patch Reported by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 769479eb6ea9..6d140bd53291 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -519,8 +519,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (unlikely(!iwl_is_ready(priv))) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); return; } -- cgit v1.2.3-59-g8ed1b From a293911d4fd5e8593dbf478399a77f990d466269 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Dec 2010 17:54:28 +0100 Subject: nl80211: advertise maximum remain-on-channel duration With the upcoming hardware offload implementation, some devices will have a different maximum duration for the remain-on-channel command. Advertise the maximum duration in mac80211, and make mac80211 set it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 5 +++++ include/net/cfg80211.h | 5 +++++ net/mac80211/main.c | 2 ++ net/wireless/nl80211.c | 7 ++++++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index b8fa25d741ba..1cee56b3a79a 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -773,6 +773,9 @@ enum nl80211_commands { * cache, a wiphy attribute. * * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. + * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that + * specifies the maximum duration that can be requested with the + * remain-on-channel operation, in milliseconds, u32. * * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. * @@ -1035,6 +1038,8 @@ enum nl80211_attrs { NL80211_ATTR_KEY_DEFAULT_TYPES, + NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 22be7c625b70..f45e15f12446 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1474,6 +1474,9 @@ struct ieee80211_txrx_stypes { * * @available_antennas: bitmap of antennas which are available to configure. * antenna configuration commands will be rejected unless this is set. + * + * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation + * may request, if implemented. */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1511,6 +1514,8 @@ struct wiphy { char fw_version[ETHTOOL_BUSINFO_LEN]; u32 hw_version; + u16 max_remain_on_channel_duration; + u8 max_num_pmkids; u32 available_antennas; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f7bdb7c78879..d87eb005690f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -745,6 +745,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } } + local->hw.wiphy->max_remain_on_channel_duration = 5000; + result = wiphy_register(local->hw.wiphy); if (result < 0) goto fail_wiphy_register; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 53f044370cde..594a6ac8b9d2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -755,6 +755,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_cmds); + if (dev->ops->remain_on_channel) + NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, + dev->wiphy.max_remain_on_channel_duration); + /* for now at least assume all drivers have it */ if (dev->ops->mgmt_tx) NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); @@ -4228,7 +4232,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, * We should be on that channel for at least one jiffie, * and more than 5 seconds seems excessive. */ - if (!duration || !msecs_to_jiffies(duration) || duration > 5000) + if (!duration || !msecs_to_jiffies(duration) || + duration > rdev->wiphy.max_remain_on_channel_duration) return -EINVAL; if (!rdev->ops->remain_on_channel) -- cgit v1.2.3-59-g8ed1b From bd2ce6e43f65127bc723e7fcc044758cf8113260 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 15 Dec 2010 07:47:10 +0530 Subject: mac80211: Add timeout to BA session start API Allow drivers or rate control algorithms to specify BlockAck session timeout when initiating an ADDBA transaction. This is useful in cases where maintaining persistent BA sessions does not incur any overhead. The current timeout value of 5000 TUs is retained for all non ath9k/ath9k_htc drivers. Signed-off-by: Sujith Manoharan Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- include/net/mac80211.h | 4 +++- net/mac80211/agg-tx.c | 7 +++++-- net/mac80211/debugfs_sta.c | 2 +- net/mac80211/rc80211_minstrel_ht.c | 2 +- net/mac80211/sta_info.h | 2 ++ 9 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 31fad82239b3..33f36029fa4f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -251,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data) ista = (struct ath9k_htc_sta *)sta->drv_priv; if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { - ieee80211_start_tx_ba_session(sta, tid); + ieee80211_start_tx_ba_session(sta, tid, 0); spin_lock_bh(&priv->tx_lock); ista->tid_state[tid] = AGGR_PROGRESS; spin_unlock_bh(&priv->tx_lock); diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 2061a755a026..896d12986b1e 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1373,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, an = (struct ath_node *)sta->drv_priv; if(ath_tx_aggr_check(sc, an, tid)) - ieee80211_start_tx_ba_session(sta, tid); + ieee80211_start_tx_ba_session(sta, tid, 0); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index ee123482e1d5..5083dba122ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, if (load > IWL_AGG_LOAD_THRESHOLD) { IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); - ret = ieee80211_start_tx_ba_session(sta, tid); + ret = ieee80211_start_tx_ba_session(sta, tid, 5000); if (ret == -EAGAIN) { /* * driver and mac80211 is out of sync diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 904b8fd01f6d..91634107434a 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -169,7 +169,7 @@ static void rtl_tx_status(void *ppriv, tid = qc[0] & 0xf; if (_rtl_tx_aggr_check(rtlpriv, tid)) - ieee80211_start_tx_ba_session(sta, tid); + ieee80211_start_tx_ba_session(sta, tid, 5000); } } } diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e411cf87fb41..69ded1ee49ce 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2435,6 +2435,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, * ieee80211_start_tx_ba_session - Start a tx Block Ack session. * @sta: the station for which to start a BA session * @tid: the TID to BA on. + * @timeout: session timeout value (in TUs) * * Return: success if addBA request was sent, failure otherwise * @@ -2442,7 +2443,8 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, * the need to start aggregation on a certain RA/TID, the session level * will be managed by the mac80211. */ -int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); +int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid, + u16 timeout); /** * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index d4679b265ba8..9cc472c6a6a5 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) /* send AddBA request */ ieee80211_send_addba_request(sdata, sta->sta.addr, tid, tid_tx->dialog_token, start_seq_num, - 0x40, 5000); + 0x40, tid_tx->timeout); } -int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) +int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, + u16 timeout) { struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) skb_queue_head_init(&tid_tx->pending); __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); + tid_tx->timeout = timeout; + /* Tx timer */ tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired; tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid]; diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 8bb5af85f469..c04a1396cf8d 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -189,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu if (tx) { if (start) - ret = ieee80211_start_tx_ba_session(&sta->sta, tid); + ret = ieee80211_start_tx_ba_session(&sta->sta, tid, 5000); else ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); } else { diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 4ad7a362fcc1..165a4518bb48 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -374,7 +374,7 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) return; - ieee80211_start_tx_ba_session(pubsta, tid); + ieee80211_start_tx_ba_session(pubsta, tid, 5000); } static void diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index fdca52cf88de..bbdd2a86a94b 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -78,6 +78,7 @@ enum ieee80211_sta_info_flags { * @addba_resp_timer: timer for peer's response to addba request * @pending: pending frames queue -- use sta's spinlock to protect * @dialog_token: dialog token for aggregation session + * @timeout: session timeout value to be filled in ADDBA requests * @state: session state (see above) * @stop_initiator: initiator of a session stop * @tx_stop: TX DelBA frame when stopping @@ -96,6 +97,7 @@ struct tid_ampdu_tx { struct timer_list addba_resp_timer; struct sk_buff_head pending; unsigned long state; + u16 timeout; u8 dialog_token; u8 stop_initiator; bool tx_stop; -- cgit v1.2.3-59-g8ed1b From 64c6e50c0732b793e4bd5fd2954b7bef088f83f8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 15 Dec 2010 07:47:23 +0530 Subject: ath9k_htc: Remove PCI specific configuration This is not required for USB devices. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 20ea75a44e52..dd17909bd903 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1170,9 +1170,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); - /* Reset SERDES registers */ - ath9k_hw_configpcipowersave(ah, 0, 0); - ath9k_hw_htc_resetinit(ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { @@ -1258,7 +1255,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ath9k_hw_phy_disable(ah); ath9k_hw_disable(ah); - ath9k_hw_configpcipowersave(ah, 1, 1); ath9k_htc_ps_restore(priv); ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); -- cgit v1.2.3-59-g8ed1b From 2b7e6bce41b6b944bd4302cf0914e2a6f4bc704b Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 15 Dec 2010 13:02:46 +0530 Subject: ath9k: Add comments for making pm-qos as modparam PM-QOS value can be user specified via module parameter. This patch adds few comments regarding this in the driver code. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 36f4f5afe738..4d647169439c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1196,6 +1196,10 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } + /* User has the option to provide pm-qos value as a module + * parameter rather than using the default value of + * 'ATH9K_PM_QOS_DEFAULT_VALUE'. + */ pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) -- cgit v1.2.3-59-g8ed1b From 38cd6b4f52a75926fd81fc85f53f5067dcd809f7 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 15 Dec 2010 14:27:28 +0800 Subject: wireless:mac80211: kill unuse macro MESH_CFG_CMP_LEN in mesh.h Commit 00d3f14c has removed the references of this macro, but left it only. So remove this definition. commit 00d3f14cf9f12c21428121026a5e1d5f65926447 Author: Johannes Berg Date: Tue Feb 10 21:26:00 2009 +0100 mac80211: use cfg80211s BSS infrastructure Remove all the code from mac80211 to keep track of BSSes and use the cfg80211-provided code completely. Signed-off-by: Shan Wei Signed-off-by: John W. Linville --- net/mac80211/mesh.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 039d7fa0af74..5b828fa8c541 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -164,17 +164,6 @@ struct mesh_rmc { }; -/* - * MESH_CFG_COMP_LEN Includes: - * - Active path selection protocol ID. - * - Active path selection metric ID. - * - Congestion control mode identifier. - * - Channel precedence. - * Does not include mesh capabilities, which may vary across nodes in the same - * mesh - */ -#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2) - #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ #define MESH_PATH_EXPIRE (600 * HZ) -- cgit v1.2.3-59-g8ed1b From e137478b56fd79c397b5c5c74fc08c049a42835a Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 16 Dec 2010 09:20:16 -0500 Subject: rtlwifi: convert to __packed notation Use "__packed" instead of "__attribute__ ((packed))"... Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.h | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h | 6 +++--- drivers/net/wireless/rtlwifi/wifi.h | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index cdde8583ad31..d36a66939958 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -131,15 +131,15 @@ enum pci_bridge_vendor { struct rtl_rx_desc { u32 dword[8]; -} __attribute__ ((packed)); +} __packed; struct rtl_tx_desc { u32 dword[16]; -} __attribute__ ((packed)); +} __packed; struct rtl_tx_cmd_desc { u32 dword[16]; -} __attribute__ ((packed)); +} __packed; struct rtl8192_tx_ring { struct rtl_tx_desc *desc; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h index 91e13c33351e..53d0e0a5af5c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h @@ -535,7 +535,7 @@ struct rx_fwinfo_92c { u8 sgi_en:1; u8 rxsc:2; u8 reserve:4; -} __attribute__ ((packed)); +} __packed; struct tx_desc_92c { u32 pktsize:16; @@ -637,7 +637,7 @@ struct tx_desc_92c { u32 nextdescaddress64; u32 reserve_pass_pcie_mm_limit[4]; -} __attribute__ ((packed)); +} __packed; struct rx_desc_92c { u32 length:14; @@ -695,7 +695,7 @@ struct rx_desc_92c { u32 bufferaddress; u32 bufferaddress64; -} __attribute__ ((packed)); +} __packed; void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 0dd6824b1942..3844dc94bdbf 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -551,13 +551,13 @@ struct rtl_hdr_3addr { u8 addr3[ETH_ALEN]; __le16 seq_ctl; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct rtl_info_element { u8 id; u8 len; u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct rtl_probe_rsp { struct rtl_hdr_3addr header; @@ -567,7 +567,7 @@ struct rtl_probe_rsp { /*SSID, supported rates, FH params, DS params, CF params, IBSS params, TIM (if beacon), RSN */ struct rtl_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; /*LED related.*/ /*ledpin Identify how to implement this SW led.*/ @@ -589,7 +589,7 @@ struct rtl_qos_parameters { u8 aifs; u8 flag; __le16 tx_op; -} __attribute__ ((packed)); +} __packed; struct rt_smooth_data { u32 elements[100]; /*array to store values */ -- cgit v1.2.3-59-g8ed1b From 7d5f01ad536afebde9a1c81d985f8d0eaf2a9ab6 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Thu, 16 Dec 2010 12:46:23 +0100 Subject: iwlwifi: Fix error: struct iwl_lq_sta has no member named dbg_fixed_rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While compiling linux-next (next-20101216) I fell over this breakage: ... drivers/net/wireless/iwlwifi/iwl-agn-rs.c: In function ‘iwl_rs_rate_init’: drivers/net/wireless/iwlwifi/iwl-agn-rs.c:2876:8: error: ‘struct iwl_lq_sta’ has no member named ‘dbg_fixed_rate’ dbg_fixed_rate is only used when CONFIG_MAC80211_DEBUGFS is set: [ drivers/net/wireless/iwlwifi/iwl-agn-rs.h ] ... #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *rs_sta_dbgfs_scale_table_file; struct dentry *rs_sta_dbgfs_stats_table_file; struct dentry *rs_sta_dbgfs_rate_scale_data_file; struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; u32 dbg_fixed_rate; #endif The issue was introduced by commit a1da077bc36368eb7d6312e7e49260f0a3d92c77: "iwlwifi: clear dbg_fixed_rate during init" Signed-off-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 5083dba122ca..75fcd30a7c13 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2873,7 +2873,9 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; +#ifdef CONFIG_MAC80211_DEBUGFS lq_sta->dbg_fixed_rate = 0; +#endif rs_initialize_lq(priv, conf, sta, lq_sta); } -- cgit v1.2.3-59-g8ed1b From cf4e594ea7e55555e81647b74a3a8e8b2826a529 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 16 Dec 2010 00:52:40 +0200 Subject: nl80211: Add notification for dropped Deauth/Disassoc Add a new notification to indicate that a received, unprotected Deauthentication or Disassociation frame was dropped due to management frame protection being in use. This notification is needed to allow user space (e.g., wpa_supplicant) to implement SA Query procedure to recover from association state mismatch between an AP and STA. This is needed to avoid getting stuck in non-working state when MFP (IEEE 802.11w) is used and a protected Deauthentication or Disassociation frame is dropped for any reason. After that, the station would silently discard any unprotected Deauthentication or Disassociation frame that could be indicating that the AP does not have association for the STA (when the Reason Code would be 6 or 7). IEEE Std 802.11w-2009, 11.13 describes this recovery mechanism. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 10 ++++++++++ include/net/cfg80211.h | 26 ++++++++++++++++++++++++++ net/mac80211/rx.c | 22 ++++++++++++++++++++-- net/wireless/mlme.c | 22 ++++++++++++++++++++++ net/wireless/nl80211.c | 16 ++++++++++++++++ net/wireless/nl80211.h | 6 ++++++ 6 files changed, 100 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 1cee56b3a79a..7483a89cee8f 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -399,6 +399,13 @@ * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the * network is determined by the network interface. * + * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame + * notification. This event is used to indicate that an unprotected + * deauthentication frame was dropped when MFP is in use. + * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame + * notification. This event is used to indicate that an unprotected + * disassociation frame was dropped when MFP is in use. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -508,6 +515,9 @@ enum nl80211_commands { NL80211_CMD_JOIN_MESH, NL80211_CMD_LEAVE_MESH, + NL80211_CMD_UNPROT_DEAUTHENTICATE, + NL80211_CMD_UNPROT_DISASSOCIATE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f45e15f12446..3d1c09b777e8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2359,6 +2359,32 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); +/** + * cfg80211_send_unprot_deauth - notification of unprotected deauthentication + * @dev: network device + * @buf: deauthentication frame (header + body) + * @len: length of the frame data + * + * This function is called whenever a received Deauthentication frame has been + * dropped in station mode because of MFP being used but the Deauthentication + * frame was not protected. This function may sleep. + */ +void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, + size_t len); + +/** + * cfg80211_send_unprot_disassoc - notification of unprotected disassociation + * @dev: network device + * @buf: disassociation frame (header + body) + * @len: length of the frame data + * + * This function is called whenever a received Disassociation frame has been + * dropped in station mode because of MFP being used but the Disassociation + * frame was not protected. This function may sleep. + */ +void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, + size_t len); + /** * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) * @dev: network device diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 052789ef4745..4573ce1e1d15 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1540,12 +1540,30 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { if (unlikely(!ieee80211_has_protected(fc) && ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && - rx->key)) + rx->key)) { + if (ieee80211_is_deauth(fc)) + cfg80211_send_unprot_deauth(rx->sdata->dev, + rx->skb->data, + rx->skb->len); + else if (ieee80211_is_disassoc(fc)) + cfg80211_send_unprot_disassoc(rx->sdata->dev, + rx->skb->data, + rx->skb->len); return -EACCES; + } /* BIP does not use Protected field, so need to check MMIE */ if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && - ieee80211_get_mmie_keyidx(rx->skb) < 0)) + ieee80211_get_mmie_keyidx(rx->skb) < 0)) { + if (ieee80211_is_deauth(fc)) + cfg80211_send_unprot_deauth(rx->sdata->dev, + rx->skb->data, + rx->skb->len); + else if (ieee80211_is_disassoc(fc)) + cfg80211_send_unprot_disassoc(rx->sdata->dev, + rx->skb->data, + rx->skb->len); return -EACCES; + } /* * When using MFP, Action frames are not allowed prior to * having configured keys. diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index d7680f2a4c5b..aa5df8865ff7 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) } EXPORT_SYMBOL(cfg80211_send_disassoc); +void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, + size_t len) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC); +} +EXPORT_SYMBOL(cfg80211_send_unprot_deauth); + +void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, + size_t len) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC); +} +EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); + static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) { int i; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 594a6ac8b9d2..aefce54d47e2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5473,6 +5473,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, NL80211_CMD_DISASSOCIATE, gfp); } +void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *buf, + size_t len, gfp_t gfp) +{ + nl80211_send_mlme_event(rdev, netdev, buf, len, + NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp); +} + +void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *buf, + size_t len, gfp_t gfp) +{ + nl80211_send_mlme_event(rdev, netdev, buf, len, + NL80211_CMD_UNPROT_DISASSOCIATE, gfp); +} + static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, struct net_device *netdev, int cmd, const u8 *addr, gfp_t gfp) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 16c2f7190768..e3f7fa886966 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev, void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *buf, size_t len, gfp_t gfp); +void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *buf, size_t len, gfp_t gfp); +void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *buf, size_t len, gfp_t gfp); void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, gfp_t gfp); -- cgit v1.2.3-59-g8ed1b From 7e68b746681289c00e8fd818fdd0144c6896d425 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:47 -0800 Subject: ath9k_hw: Remove delay during regwrite of analog shift registers This is not needed for AR9003. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index da4a571304da..07b44cec7739 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -578,10 +578,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah, u32 reg = INI_RA(iniArr, i, 0); u32 val = INI_RA(iniArr, i, column); - if (reg >= 0x16000 && reg < 0x17000) - ath9k_hw_analog_shift_regwrite(ah, reg, val); - else - REG_WRITE(ah, reg, val); + REG_WRITE(ah, reg, val); DO_DELAY(regWrites); } -- cgit v1.2.3-59-g8ed1b From d8a8440e3f1f0cdd23074c6d2d8cbbde204a4374 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:48 -0800 Subject: ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal() Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 7c3334bd396e..75a1c6e5195c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -616,11 +616,6 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) AR_PHY_TX_IQCAL_STATUS_B1, AR_PHY_TX_IQCAL_STATUS_B2, }; - static const u32 rx_corr[AR9300_MAX_CHAINS] = { - AR_PHY_RX_IQCAL_CORR_B0, - AR_PHY_RX_IQCAL_CORR_B1, - AR_PHY_RX_IQCAL_CORR_B2, - }; static const u_int32_t chan_info_tab[] = { AR_PHY_CHAN_INFO_TAB_0, AR_PHY_CHAN_INFO_TAB_1, @@ -703,18 +698,10 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) REG_RMW_FIELD(ah, tx_corr_coeff[i], AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, iqc_coeff[0]); - REG_RMW_FIELD(ah, rx_corr[i], - AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF, - iqc_coeff[1] >> 7); - REG_RMW_FIELD(ah, rx_corr[i], - AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF, - iqc_coeff[1]); } REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); - REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, - AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); return; -- cgit v1.2.3-59-g8ed1b From 895ad7eb21ed228444169dbbff44f3dccfc7e006 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:49 -0800 Subject: ath9k_hw: Move get_streams() to hw.h This helper can be used in multiple places. Also make it inline returning u8. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 5 ----- drivers/net/wireless/ath/ath9k/hw.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 69f779237d28..4c744793b4b6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -50,11 +50,6 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah) return power; } -static int get_streams(int mask) -{ - return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2)); -} - static int ar9003_get_training_power_5g(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 97f22c428603..fb64ab841dc1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -868,6 +868,11 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah) return &ah->ops; } +static inline u8 get_streams(int mask) +{ + return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2)); +} + /* Initialization, Detach, Reset */ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); -- cgit v1.2.3-59-g8ed1b From 0b2084bc578128be866d6fc9926ed887c3432bb1 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:50 -0800 Subject: ath9k_hw: Tx IQ cal changes for AR9003 Add multiple Tx IQ cal support to improve EVM accross different power levels. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 212 +++++++++++++------------- 1 file changed, 108 insertions(+), 104 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 75a1c6e5195c..4a4cd88429c0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -608,107 +608,6 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, return true; } -static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { - AR_PHY_TX_IQCAL_STATUS_B0, - AR_PHY_TX_IQCAL_STATUS_B1, - AR_PHY_TX_IQCAL_STATUS_B2, - }; - static const u_int32_t chan_info_tab[] = { - AR_PHY_CHAN_INFO_TAB_0, - AR_PHY_CHAN_INFO_TAB_1, - AR_PHY_CHAN_INFO_TAB_2, - }; - u32 tx_corr_coeff[AR9300_MAX_CHAINS]; - s32 iq_res[6]; - s32 iqc_coeff[2]; - s32 i, j; - u32 num_chains = 0; - - tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0); - tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0); - tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0); - - for (i = 0; i < AR9300_MAX_CHAINS; i++) { - if (ah->txchainmask & (1 << i)) - num_chains++; - } - - REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, - AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, - DELPT); - REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, - AR_PHY_TX_IQCAL_START_DO_CAL, - AR_PHY_TX_IQCAL_START_DO_CAL); - - if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, - AR_PHY_TX_IQCAL_START_DO_CAL, - 0, AH_WAIT_TIMEOUT)) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "Tx IQ Cal not complete.\n"); - goto TX_IQ_CAL_FAILED; - } - - for (i = 0; i < num_chains; i++) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "Doing Tx IQ Cal for chain %d.\n", i); - - if (REG_READ(ah, txiqcal_status[i]) & - AR_PHY_TX_IQCAL_STATUS_FAILED) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "Tx IQ Cal failed for chain %d.\n", i); - goto TX_IQ_CAL_FAILED; - } - - for (j = 0; j < 3; j++) { - u_int8_t idx = 2 * j, - offset = 4 * j; - - REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, - AR_PHY_CHAN_INFO_TAB_S2_READ, 0); - - /* 32 bits */ - iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset); - - REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, - AR_PHY_CHAN_INFO_TAB_S2_READ, 1); - - /* 16 bits */ - iq_res[idx+1] = 0xffff & REG_READ(ah, - chan_info_tab[i] + - offset); - - ath_dbg(common, ATH_DBG_CALIBRATE, - "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", - idx, iq_res[idx], idx+1, iq_res[idx+1]); - } - - if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "Failed in calculation of IQ correction.\n"); - goto TX_IQ_CAL_FAILED; - } - - ath_dbg(common, ATH_DBG_CALIBRATE, - "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n", - iqc_coeff[0], iqc_coeff[1]); - - REG_RMW_FIELD(ah, tx_corr_coeff[i], - AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, - iqc_coeff[0]); - } - - REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, - AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); - - return; - -TX_IQ_CAL_FAILED: - ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); -} - static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) { int diff[MPASS]; @@ -717,9 +616,9 @@ static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) diff[1] = abs(mp_coeff[1] - mp_coeff[2]); diff[2] = abs(mp_coeff[2] - mp_coeff[0]); - if (diff[0] > MAX_MEASUREMENT && - diff[1] > MAX_MEASUREMENT && - diff[2] > MAX_MEASUREMENT) + if (diff[0] > MAX_DIFFERENCE && + diff[1] > MAX_DIFFERENCE && + diff[2] > MAX_DIFFERENCE) return false; if (diff[0] <= diff[1] && diff[0] <= diff[2]) @@ -817,6 +716,111 @@ disable_txiqcal: ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); } +static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { + AR_PHY_TX_IQCAL_STATUS_B0, + AR_PHY_TX_IQCAL_STATUS_B1, + AR_PHY_TX_IQCAL_STATUS_B2, + }; + static const u32 chan_info_tab[] = { + AR_PHY_CHAN_INFO_TAB_0, + AR_PHY_CHAN_INFO_TAB_1, + AR_PHY_CHAN_INFO_TAB_2, + }; + struct coeff coeff; + s32 iq_res[6]; + s32 i, j, ip, im, nmeasurement; + u8 nchains = get_streams(common->tx_chainmask); + + for (ip = 0; ip < MPASS; ip++) { + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, + AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, + DELPT); + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, + AR_PHY_TX_IQCAL_START_DO_CAL, + AR_PHY_TX_IQCAL_START_DO_CAL); + + if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, + AR_PHY_TX_IQCAL_START_DO_CAL, + 0, AH_WAIT_TIMEOUT)) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Tx IQ Cal not complete.\n"); + goto TX_IQ_CAL_FAILED; + } + + nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, + AR_PHY_CALIBRATED_GAINS_0); + if (nmeasurement > MAX_MEASUREMENT) + nmeasurement = MAX_MEASUREMENT; + + for (i = 0; i < nchains; i++) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Doing Tx IQ Cal for chain %d.\n", i); + for (im = 0; im < nmeasurement; im++) { + if (REG_READ(ah, txiqcal_status[i]) & + AR_PHY_TX_IQCAL_STATUS_FAILED) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Tx IQ Cal failed for chain %d.\n", i); + goto TX_IQ_CAL_FAILED; + } + + for (j = 0; j < 3; j++) { + u8 idx = 2 * j, + offset = 4 * (3 * im + j); + + REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_TAB_S2_READ, + 0); + + /* 32 bits */ + iq_res[idx] = REG_READ(ah, + chan_info_tab[i] + + offset); + + REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_TAB_S2_READ, + 1); + + /* 16 bits */ + iq_res[idx+1] = 0xffff & REG_READ(ah, + chan_info_tab[i] + + offset); + + ath_dbg(common, ATH_DBG_CALIBRATE, + "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", + idx, iq_res[idx], idx+1, iq_res[idx+1]); + } + + if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, + coeff.iqc_coeff)) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "Failed in calculation of IQ correction.\n"); + goto TX_IQ_CAL_FAILED; + } + coeff.mag_coeff[i][im][ip] = + coeff.iqc_coeff[0] & 0x7f; + coeff.phs_coeff[i][im][ip] = + (coeff.iqc_coeff[0] >> 7) & 0x7f; + + if (coeff.mag_coeff[i][im][ip] > 63) + coeff.mag_coeff[i][im][ip] -= 128; + if (coeff.phs_coeff[i][im][ip] > 63) + coeff.phs_coeff[i][im][ip] -= 128; + + } + } + } + + ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff); + + return; + +TX_IQ_CAL_FAILED: + ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); +} + static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) { u8 tx_gain_forced; -- cgit v1.2.3-59-g8ed1b From 8698bca6b53d1f6641850b270de9c953078ed1ce Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:51 -0800 Subject: ath9k_hw: Add a helper to get paprd scale factor Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 21 +++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 4149ffb6d54a..9fa5793abd27 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4843,6 +4843,27 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz) return eep->modalHeader5G.spurChans; } +unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + + if (IS_CHAN_2GHZ(chan)) + return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20), + AR9300_PAPRD_SCALE_1); + else { + if (chan->channel >= 5700) + return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), + AR9300_PAPRD_SCALE_1); + else if (chan->channel >= 5400) + return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), + AR9300_PAPRD_SCALE_2); + else + return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), + AR9300_PAPRD_SCALE_1); + } +} + const struct eeprom_ops eep_ar9300_ops = { .check_eeprom = ath9k_hw_ar9300_check_eeprom, .get_eeprom = ath9k_hw_ar9300_get_eeprom, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index efb6a02be377..afb0b5ee1865 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -315,4 +315,7 @@ s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah); s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); + +unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, + struct ath9k_channel *chan); #endif -- cgit v1.2.3-59-g8ed1b From 7072bf62fb7abe5a91389d6271da520f29c79326 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:52 -0800 Subject: ath9k_hw: Disable PAPRD for rates with low Tx power When the drop in Tx power for a particular mcs rate exceeds the paprd scale factor, paprd may not work properly. Disable paprd for any such rates. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 39 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 20 ++++--------- drivers/net/wireless/ath/ath9k/hw.h | 1 + 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 9fa5793abd27..0e9ea35f2fb4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4751,16 +4751,53 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; u8 targetPowerValT2[ar9300RateSize]; - unsigned int i = 0; + u8 target_power_val_t2_eep[ar9300RateSize]; + unsigned int i = 0, paprd_scale_factor = 0; + u8 pwr_idx, min_pwridx; ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); + + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { + if (IS_CHAN_2GHZ(chan)) + ah->paprd_ratemask = (IS_CHAN_HT40(chan) ? + le32_to_cpu(eep->modalHeader2G.papdRateMaskHt40) : + le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20)) + & AR9300_PAPRD_RATE_MASK; + else + ah->paprd_ratemask = (IS_CHAN_HT40(chan) ? + le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40) : + le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)) + & AR9300_PAPRD_RATE_MASK; + + memcpy(target_power_val_t2_eep, targetPowerValT2, + sizeof(targetPowerValT2)); + } + ar9003_hw_set_power_per_rate_table(ah, chan, targetPowerValT2, cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit); + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { + paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); + min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 : + ALL_TARGET_HT20_0_8_16; + + for (i = 0; i < ar9300RateSize; i++) { + if ((ah->paprd_ratemask & (1 << i)) && + (abs(targetPowerValT2[i] - + target_power_val_t2_eep[i]) > + paprd_scale_factor)) { + ah->paprd_ratemask &= ~(1 << i); + ath_dbg(common, ATH_DBG_EEPROM, + "paprd disabled for mcs %d\n", i); + } + } + } + regulatory->max_power_level = 0; for (i = 0; i < ar9300RateSize; i++) { if (targetPowerValT2[i] > regulatory->max_power_level) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 4c744793b4b6..26cf31cca3ac 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -87,8 +87,6 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) static int ar9003_paprd_setup_single_table(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - struct ar9300_modal_eep_header *hdr; static const u32 ctrl0[3] = { AR_PHY_PAPRD_CTRL0_B0, AR_PHY_PAPRD_CTRL0_B1, @@ -99,18 +97,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_CTRL1_B1, AR_PHY_PAPRD_CTRL1_B2 }; - u32 am_mask, ht40_mask; int training_power; int i; - if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) - hdr = &eep->modalHeader5G; - else - hdr = &eep->modalHeader2G; - - am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK; - ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK; - if (IS_CHAN_2GHZ(ah->curchan)) training_power = ar9003_get_training_power_2g(ah); else @@ -126,9 +115,12 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) "Training power: %d, Target power: %d\n", ah->paprd_training_power, ah->paprd_target_power); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); - REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, + ah->paprd_ratemask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, + ah->paprd_ratemask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, + AR_PHY_PAPRD_HT40_MASK); for (i = 0; i < ah->caps.max_txchains; i++) { REG_RMW_FIELD(ah, ctrl0[i], diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index fb64ab841dc1..3a6101ba9837 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -835,6 +835,7 @@ struct ath_hw { unsigned int paprd_target_power; unsigned int paprd_training_power; + unsigned int paprd_ratemask; u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; /* -- cgit v1.2.3-59-g8ed1b From 45ef6a0bcc9cd8f13004789ec6decb52e1d3045c Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 15 Dec 2010 07:30:53 -0800 Subject: ath9k_hw: Configure appropriate Tx power when PAPRD fails Target Tx power available in eeprom is for PAPRD. If PAPRD fails, paprd scale factor needs to be detected from this target tx power. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 34 ++++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 14 +++++++++++ drivers/net/wireless/ath/ath9k/hw.c | 2 ++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 2 +- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 0e9ea35f2fb4..f80ec7497d0f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4743,6 +4743,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, } /* end ctl mode checking */ } +static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx) +{ + u8 mod_idx = mcs_idx % 8; + + if (mod_idx <= 3) + return mod_idx ? (base_pwridx + 1) : base_pwridx; + else + return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2; +} + static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, @@ -4755,7 +4765,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, u8 targetPowerValT2[ar9300RateSize]; u8 target_power_val_t2_eep[ar9300RateSize]; unsigned int i = 0, paprd_scale_factor = 0; - u8 pwr_idx, min_pwridx; + u8 pwr_idx, min_pwridx = 0; ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); @@ -4771,6 +4781,24 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)) & AR9300_PAPRD_RATE_MASK; + paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); + min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 : + ALL_TARGET_HT20_0_8_16; + + if (!ah->paprd_table_write_done) { + memcpy(target_power_val_t2_eep, targetPowerValT2, + sizeof(targetPowerValT2)); + for (i = 0; i < 24; i++) { + pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx); + if (ah->paprd_ratemask & (1 << i)) { + if (targetPowerValT2[pwr_idx] && + targetPowerValT2[pwr_idx] == + target_power_val_t2_eep[pwr_idx]) + targetPowerValT2[pwr_idx] -= + paprd_scale_factor; + } + } + } memcpy(target_power_val_t2_eep, targetPowerValT2, sizeof(targetPowerValT2)); } @@ -4782,10 +4810,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, powerLimit); if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { - paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); - min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 : - ALL_TARGET_HT20_0_8_16; - for (i = 0; i < ar9300RateSize; i++) { if ((ah->paprd_ratemask & (1 << i)) && (abs(targetPowerValT2[i] - diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 26cf31cca3ac..79554c524b68 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -19,6 +19,20 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) { + struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); + struct ath9k_channel *chan = ah->curchan; + + if (val) { + ah->paprd_table_write_done = true; + + ah->eep_ops->set_txpower(ah, chan, + ath9k_regd_get_ctl(regulatory, chan), + chan->chan->max_antenna_gain * 2, + chan->chan->max_power * 2, + min((u32) MAX_RATE_POWER, + (u32) regulatory->power_limit), false); + } + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); if (ah->caps.tx_chainmask & BIT(1)) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0f373be9ef8c..ddda76fcd180 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1272,6 +1272,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_mark_phy_inactive(ah); + ah->paprd_table_write_done = false; + /* Only required on the first reset */ if (AR_SREV_9271(ah) && ah->htc_reset_init) { REG_WRITE(ah, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 3a6101ba9837..21e37d157d3a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -836,6 +836,7 @@ struct ath_hw { unsigned int paprd_target_power; unsigned int paprd_training_power; unsigned int paprd_ratemask; + bool paprd_table_write_done; u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; /* diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4d647169439c..cb53fbb951f1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -533,7 +533,7 @@ set_timer: if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { if (!ah->caldata->paprd_done) ieee80211_queue_work(sc->hw, &sc->paprd_work); - else + else if (!ah->paprd_table_write_done) ath_paprd_activate(sc); } } -- cgit v1.2.3-59-g8ed1b From 2784fe915cd25adf23ea28534019308d8a144721 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 15 Dec 2010 19:24:11 -0800 Subject: cfg80211: fix null pointer dereference with a custom regulatory request Once we moved the core regulatory request to the queue and let the scheduler process it last_request will have been left NULL until the schedular decides to process the first request. When this happens and we are loading a driver with a custom regulatory request like all Atheros drivers we end up with a NULL pointer dereference. We fix this by checking if the request was a custom one. BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 IP: [] freq_reg_info_regd.clone.2+0x27/0x130 [cfg80211] PGD 71f91067 PUD 712b2067 PMD 0 Oops: 0000 [#1] PREEMPT SMP last sysfs file: /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-1/firmware/2-1/loading CPU 0 Modules linked in: ath9k_htc(+) ath9k_common ath9k_hw ath Pid: 3094, comm: insmod Tainted: G W 2.6.37-rc5-wl #16 INVALID/28427ZQ RIP: 0010:[] [] freq_reg_info_regd.clone.2+0x27/0x130 [cfg80211] RSP: 0018:ffff88007045db78 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffffffffa047d9a0 RCX: ffff88007045dbd0 RDX: 0000000000004e20 RSI: 000000000024cde0 RDI: ffff8800700483e0 RBP: ffff88007045db98 R08: ffffffffa02f5b40 R09: 0000000000000001 R10: 000000000000000e R11: 0000000000000001 R12: 0000000000000000 R13: ffff88007004e3b0 R14: 0000000000000000 R15: ffff880070048340 FS: 00007f635a707700(0000) GS:ffff880077400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000004 CR3: 00000000708a9000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process insmod (pid: 3094, threadinfo ffff88007045c000, task ffff8800713e3ec0) Stack: ffffffffa047d9a0 0000000000000000 ffff88007004e3b0 0000000000000000 ffff88007045dc08 ffffffffa016e147 000000007045dc08 0000000000000002 ffff8800700483e0 ffffffffa02f5b40 ffff88007045dbd8 0000000000000000 Call Trace: [] wiphy_apply_custom_regulatory+0x137/0x1d0 [cfg80211] [] ? ath9k_reg_notifier+0x0/0x50 [ath9k_htc] [] ath_regd_init+0x347/0x430 [ath] [] ath9k_htc_probe_device+0x6c5/0x960 [ath9k_htc] [] ath9k_htc_hw_init+0xc/0x30 [ath9k_htc] [] ath9k_hif_usb_probe+0x216/0x3b0 [ath9k_htc] [] usb_probe_interface+0x10c/0x210 [usbcore] [] driver_probe_device+0x96/0x1c0 [] __driver_attach+0xa3/0xb0 [] ? __driver_attach+0x0/0xb0 [] bus_for_each_dev+0x5e/0x90 [] driver_attach+0x19/0x20 [] bus_add_driver+0x168/0x320 [] driver_register+0x71/0x140 [] ? __raw_spin_lock_init+0x38/0x70 [] usb_register_driver+0xdc/0x190 [usbcore] [] ? ath9k_htc_init+0x0/0x4f [ath9k_htc] [] ath9k_hif_usb_init+0x1e/0x20 [ath9k_htc] [] ath9k_htc_init+0x2b/0x4f [ath9k_htc] [] do_one_initcall+0x3f/0x180 [] sys_init_module+0xbb/0x200 [] system_call_fastpath+0x16/0x1b Code: RIP [] freq_reg_info_regd.clone.2+0x27/0x130 [cfg80211] RSP CR2: 0000000000000004 ---[ end trace 79e4193601c8b713 ]--- Reported-by: Sujith Manoharan Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 +++- net/wireless/reg.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3d1c09b777e8..6dc665a727c2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1419,7 +1419,9 @@ struct ieee80211_txrx_stypes { /** * struct wiphy - wireless hardware description - * @reg_notifier: the driver's regulatory notification callback + * @reg_notifier: the driver's regulatory notification callback, + * note that if your driver uses wiphy_apply_custom_regulatory() + * the reg_notifier's request can be passed as NULL * @regd: the driver's regulatory domain, if one was requested via * the regulatory_hint() API. This can be used by the driver * on the reg_notifier() if it chooses to ignore future diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 5ed615f94e0c..99d41831d76e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -661,7 +661,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy, * Follow the driver's regulatory domain, if present, unless a country * IE has been processed or a user wants to help complaince further */ - if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && + if (!custom_regd && + last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && last_request->initiator != NL80211_REGDOM_SET_BY_USER && wiphy->regd) regd = wiphy->regd; -- cgit v1.2.3-59-g8ed1b From 931299cf87701962ea1811dc216f48f3f7a4ebc8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 15 Dec 2010 19:24:12 -0800 Subject: ath: fix NULL pointer dereference on reg_notifier() The reg_notifier() was recently updated as being capable of having the request passed as NULL, fix ath to follow this API change. Without this we end up oopsing: BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 IP: [] ath_reg_notifier_apply+0x5b/0xa0 [ath] PGD b4c4c067 PUD b4c4d067 PMD 0 Oops: 0000 [#1] SMP DEBUG_PAGEALLOC last sysfs file: /sys/devices/pci0000:00/0000:00:1b.0/uevent CPU 1 Modules linked in: Pid: 436, comm: modprobe Not tainted 2.6.37-rc5-wl+ #36 6460DWU/6460DWU RIP: 0010:[] [] ath_reg_notifier_apply+0x5b/0xa0 [ath] RSP: 0018:ffff8800b6f6baa8 EFLAGS: 00010246 RAX: ffff8800b527b254 RBX: ffff8800b532c180 RCX: 0000000000000018 RDX: ffff8800b530c108 RSI: 0000000000000000 RDI: ffff8800b532c180 RBP: ffff8800b6f6baa8 R08: ffff8800b532f268 R09: 0000000000000235 R10: 00000000000016ad R11: 0000000000000018 R12: 0000000000000000 R13: 0000000000000016 R14: ffff8800b532f268 R15: 0000000000000011 FS: 00007f0c53104700(0000) GS:ffff8800bed00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000004 CR3: 00000000b6531000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process modprobe (pid: 436, threadinfo ffff8800b6f6a000, task ffff8800b404dc40) Stack: ffff8800b6f6bac8 ffffffffa03ea651 ffff8800b532c180 ffff8800b527b254 ffff8800b6f6bb38 ffffffffa01835ca ffffffffa019ed00 00000000a019ed80 0000000000000002 ffff880000000002 ffffffffa0366140 0000000010aee572 Call Trace: [] ath9k_reg_notifier+0x41/0x50 [ath9k] [] wiphy_update_regulatory+0x4ba/0x5a0 [cfg80211] [] ? ieee80211_register_hw+0xa0/0x5b0 [mac80211] [] ? ieee80211_register_hw+0xa0/0x5b0 [mac80211] [] wiphy_register+0x1d4/0x360 [cfg80211] [] ? __kmalloc+0x108/0x1c0 [] ieee80211_register_hw+0x183/0x5b0 [mac80211] [] ath9k_init_device+0x66b/0x850 [ath9k] [] ath_pci_probe+0x2f6/0x3c0 [ath9k] [] ? default_spin_lock_flags+0x9/0x10 [] local_pci_probe+0x5f/0xd0 [] pci_device_probe+0x101/0x120 [] ? driver_sysfs_add+0x7a/0xb0 [] driver_probe_device+0x96/0x1c0 [] __driver_attach+0x9b/0xa0 [] ? __driver_attach+0x0/0xa0 [] bus_for_each_dev+0x68/0x90 [] driver_attach+0x1e/0x20 [] bus_add_driver+0xe9/0x290 [] ? ath9k_init+0x0/0x4d [ath9k] [] driver_register+0x80/0x150 [] ? ath9k_init+0x0/0x4d [ath9k] [] ? ath9k_init+0x0/0x4d [ath9k] [] __pci_register_driver+0x56/0xd0 [] ath_pci_init+0x23/0x30 [ath9k] [] ath9k_init+0x2b/0x4d [ath9k] [] do_one_initcall+0x43/0x190 [] sys_init_module+0xbb/0x200 [] system_call_fastpath+0x16/0x1b Code: RIP [] ath_reg_notifier_apply+0x5b/0xa0 [ath] RSP CR2: 0000000000000004 ---[ end trace 6d03d3c7eda9f06b ]--- Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 3f4244f56ce5..2b14775e6bc6 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -342,6 +342,14 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, /* We always apply this */ ath_reg_apply_radar_flags(wiphy); + /* + * This would happen when we have sent a custom regulatory request + * a world regulatory domain and the scheduler hasn't yet processed + * any pending requests in the queue. + */ + if (!request) + return 0; + switch (request->initiator) { case NL80211_REGDOM_SET_BY_DRIVER: case NL80211_REGDOM_SET_BY_CORE: -- cgit v1.2.3-59-g8ed1b From 4aea248dd7a67097d683a97f94a0aeaf0d248f3f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 15 Dec 2010 22:55:34 -0600 Subject: rtl8192ce: Fix build on powerpc After merge of the rtl8192ce driver, a powerpc build fails with: drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c: In function 'rtl92c_init_sw_vars': drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c:76: error: implicit declaration of function 'vmalloc' drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c:76: warning: cast to pointer from integer of different size drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c: In function 'rtl92c_deinit_sw_vars': drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c:91: error: implicit declaration of function 'vfree' The problem is fixed by explicitly including the appropriate header. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c index 3cdca006be2a..4c76ad6401be 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c @@ -27,6 +27,8 @@ * *****************************************************************************/ +#include + #include "../wifi.h" #include "../core.h" #include "../pci.h" -- cgit v1.2.3-59-g8ed1b From f15a4bb2637253680f09f0161d51e22446b6478f Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 16 Dec 2010 16:22:20 +0900 Subject: ath5k: Fix survey The old survey implementation was broken and returned nonsense data. Clear cycle counters and survey data on reset. Since the cycle counters easily overflow it's better to keep a local version of collected survey data (in ms resolution, instead of clockrate) and update this every time survey is retrieved. If survey is retrieved often enough to avoid cycle counter overflows this works fine, otherwise we could update survey more often, like ath9k does. Still only the survey for the current channel is kept. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 35 +++++++++++++++++++++++------------ drivers/net/wireless/ath/ath5k/base.h | 2 ++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4e3b97c3d7c2..b3c7241a62a5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2654,6 +2654,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu) { struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); int ret, ani_mode; ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); @@ -2696,6 +2697,14 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ah->ah_cal_next_nf = jiffies; ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); + /* clear survey data and cycle counters */ + memset(&sc->survey, 0, sizeof(sc->survey)); + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + memset(&common->cc_ani, 0, sizeof(common->cc_ani)); + spin_unlock(&common->cc_lock); + /* * Change channels and update the h/w rate map if we're switching; * e.g. 11a to 11b/g. @@ -3362,25 +3371,27 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = sc->ah->ah_noise_floor; - spin_lock_bh(&common->cc_lock); ath_hw_cycle_counters_update(common); if (cc->cycles > 0) { - survey->filled |= SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_RX | - SURVEY_INFO_CHANNEL_TIME_TX; - survey->channel_time += cc->cycles / div; - survey->channel_time_busy += cc->rx_busy / div; - survey->channel_time_rx += cc->rx_frame / div; - survey->channel_time_tx += cc->tx_frame / div; + sc->survey.channel_time += cc->cycles / div; + sc->survey.channel_time_busy += cc->rx_busy / div; + sc->survey.channel_time_rx += cc->rx_frame / div; + sc->survey.channel_time_tx += cc->tx_frame / div; } memset(cc, 0, sizeof(*cc)); spin_unlock_bh(&common->cc_lock); + memcpy(survey, &sc->survey, sizeof(*survey)); + + survey->channel = conf->channel; + survey->noise = sc->ah->ah_noise_floor; + survey->filled = SURVEY_INFO_NOISE_DBM | + SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + return 0; } diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index aa6c32aafb59..6d511476e4d2 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -258,6 +258,8 @@ struct ath5k_softc { struct tasklet_struct ani_tasklet; /* ANI calibration */ struct delayed_work tx_complete_work; + + struct survey_info survey; /* collected survey info */ }; #define ath5k_hw_hasbssidmask(_ah) \ -- cgit v1.2.3-59-g8ed1b From 3cf0c8ad94ba1ba241b970cd19c11a4f3cea93c2 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 16 Dec 2010 09:13:21 -0600 Subject: rtl8192ce: Update MAINTAINERS Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4d8bde32a26b..43ab5fa42a73 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5044,6 +5044,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g S: Maintained F: drivers/net/wireless/rtl818x/rtl8187* +RTL8192CE WIRELESS DRIVER +M: Larry Finger +M: Chaoming Li +L: linux-wireless@vger.kernel.org +W: http://linuxwireless.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git +S: Maintained +F: drivers/net/wireless/rtlwifi/ +F: drivers/net/wireless/rtl8192ce/ + S3 SAVAGE FRAMEBUFFER DRIVER M: Antonino Daplas L: linux-fbdev@vger.kernel.org -- cgit v1.2.3-59-g8ed1b From 8a09d6d80c90c02f2f8c89f69c702cab0c8d9b42 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 16 Dec 2010 11:13:57 -0600 Subject: rtlwifi: Switch locking from semaphores to mutexes Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 4 ++-- drivers/net/wireless/rtlwifi/core.c | 32 ++++++++++++++++---------------- drivers/net/wireless/rtlwifi/ps.c | 4 ++-- drivers/net/wireless/rtlwifi/wifi.h | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 9e860ff30b52..87530eaa88bd 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -309,8 +309,8 @@ int rtl_init_core(struct ieee80211_hw *hw) } /* <4> locks */ - sema_init(&rtlpriv->locks.ips_sem, 1); - sema_init(&rtlpriv->locks.conf_sem, 1); + mutex_init(&rtlpriv->locks.ips_mutex); + mutex_init(&rtlpriv->locks.conf_mutex); spin_lock_init(&rtlpriv->locks.irq_th_lock); spin_lock_init(&rtlpriv->locks.h2c_lock); spin_lock_init(&rtlpriv->locks.rf_ps_lock); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 81b290ff8a94..d6a924a05654 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -43,13 +43,13 @@ static int rtl_op_start(struct ieee80211_hw *hw) return 0; if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) return 0; - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); err = rtlpriv->intf_ops->adapter_start(hw); if (err) goto out; rtl_watch_dog_timer_callback((unsigned long)hw); out: - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); return err; } @@ -68,7 +68,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) mdelay(1); } - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); mac->link_state = MAC80211_NOLINK; memset(mac->bssid, 0, 6); @@ -79,7 +79,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) rtl_deinit_deferred_work(hw); rtlpriv->intf_ops->adapter_stop(hw); - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); } static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -119,7 +119,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, rtl_ips_nic_on(hw); - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); switch (vif->type) { case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { @@ -156,7 +156,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); out: - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); return err; } @@ -166,7 +166,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); /* Free beacon resources */ if ((mac->opmode == NL80211_IFTYPE_AP) || @@ -190,7 +190,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, mac->opmode = NL80211_IFTYPE_UNSPECIFIED; rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); } @@ -202,7 +202,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct ieee80211_conf *conf = &hw->conf; - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); @@ -303,7 +303,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) hw->conf.channel_type); } - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); return 0; } @@ -450,7 +450,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); if ((vif->type == NL80211_IFTYPE_ADHOC) || (vif->type == NL80211_IFTYPE_AP) || @@ -700,7 +700,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } out: - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); } static u64 rtl_op_get_tsf(struct ieee80211_hw *hw) @@ -852,7 +852,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, sta ? sta->addr : bcast_addr)); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); /* <1> get encryption alg */ switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: @@ -970,7 +970,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ("cmd_err:%x!!!!:\n", cmd)); } out_unlock: - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); rtlpriv->sec.being_setkey = false; return err; } @@ -986,7 +986,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) return; - down(&rtlpriv->locks.conf_sem); + mutex_lock(&rtlpriv->locks.conf_mutex); /*if Radio On return true here */ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); @@ -1004,7 +1004,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) } } - up(&rtlpriv->locks.conf_sem); + mutex_unlock(&rtlpriv->locks.conf_mutex); } const struct ieee80211_ops rtl_ops = { diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index fd77cd508f50..22c293e5b88c 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -287,7 +287,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); enum rf_pwrstate rtstate; - down(&rtlpriv->locks.ips_sem); + mutex_lock(&rtlpriv->locks.ips_mutex); if (ppsc->b_inactiveps) { rtstate = ppsc->rfpwr_state; @@ -303,7 +303,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) } } - up(&rtlpriv->locks.ips_sem); + mutex_unlock(&rtlpriv->locks.ips_mutex); } /*for FW LPS*/ diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 3844dc94bdbf..77d5fa370bdc 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1193,8 +1193,8 @@ struct rtl_hal_cfg { struct rtl_locks { /*sem */ - struct semaphore ips_sem; - struct semaphore conf_sem; + struct mutex ips_mutex; + struct mutex conf_mutex; /*spin lock */ spinlock_t irq_th_lock; -- cgit v1.2.3-59-g8ed1b From a3d22a68d752ccc1a01bb0a64dd70b7a98bf9e23 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 06:27:10 +0000 Subject: bnx2x: Take the distribution range definition out of skb_tx_hash() Move the calcualation of the Tx hash for a given hash range into a separate function and define the skb_tx_hash(), which calculates a Tx hash for a [0; dev->real_num_tx_queues - 1] hash values range, using this function (__skb_tx_hash()). Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- include/linux/netdevice.h | 10 ++++++++++ include/linux/skbuff.h | 5 +++-- net/core/dev.c | 15 ++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d31bc3c94717..445e6825f8eb 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1747,6 +1747,16 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index) __netif_schedule(txq->qdisc); } +/* + * Returns a Tx hash for the given packet when dev->real_num_tx_queues is used + * as a distribution range limit for the returned value. + */ +static inline u16 skb_tx_hash(const struct net_device *dev, + const struct sk_buff *skb) +{ + return __skb_tx_hash(dev, skb, dev->real_num_tx_queues); +} + /** * netif_is_multiqueue - test if device has multiple transmit queues * @dev: network device diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 19f37a6ee6c4..4c4bec6316d9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2165,8 +2165,9 @@ static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) return skb->queue_mapping != 0; } -extern u16 skb_tx_hash(const struct net_device *dev, - const struct sk_buff *skb); +extern u16 __skb_tx_hash(const struct net_device *dev, + const struct sk_buff *skb, + unsigned int num_tx_queues); #ifdef CONFIG_XFRM static inline struct sec_path *skb_sec_path(struct sk_buff *skb) diff --git a/net/core/dev.c b/net/core/dev.c index d28b3a023bb2..b25dd087f06a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2112,14 +2112,19 @@ out: static u32 hashrnd __read_mostly; -u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) +/* + * Returns a Tx hash based on the given packet descriptor a Tx queues' number + * to be used as a distribution range. + */ +u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, + unsigned int num_tx_queues) { u32 hash; if (skb_rx_queue_recorded(skb)) { hash = skb_get_rx_queue(skb); - while (unlikely(hash >= dev->real_num_tx_queues)) - hash -= dev->real_num_tx_queues; + while (unlikely(hash >= num_tx_queues)) + hash -= num_tx_queues; return hash; } @@ -2129,9 +2134,9 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) hash = (__force u16) skb->protocol ^ skb->rxhash; hash = jhash_1word(hash, hashrnd); - return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); + return (u16) (((u64) hash * num_tx_queues) >> 32); } -EXPORT_SYMBOL(skb_tx_hash); +EXPORT_SYMBOL(__skb_tx_hash); static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) { -- cgit v1.2.3-59-g8ed1b From ec6ba945211b1c1f97d3d19fe60f166c9a92241d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:01 +0000 Subject: bnx2x: add FCoE ring Includes new driver structures and FW/HW configuration for FCoE ring Signed-off-by: Vladislav Zolotarov Signed-off-by: Shmulik Ravid-Rabinovitz Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 118 ++++++++++++-- drivers/net/bnx2x/bnx2x_cmn.c | 81 ++++++++-- drivers/net/bnx2x/bnx2x_cmn.h | 53 ++++++- drivers/net/bnx2x/bnx2x_ethtool.c | 290 +++++++++++++++++++---------------- drivers/net/bnx2x/bnx2x_main.c | 315 ++++++++++++++++++++++++++++++-------- drivers/net/bnx2x/bnx2x_stats.c | 13 +- drivers/net/bnx2x/bnx2x_stats.h | 2 - 7 files changed, 631 insertions(+), 241 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 7e4d682f0df1..475725c566d7 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -13,6 +13,8 @@ #ifndef BNX2X_H #define BNX2X_H +#include +#include /* compilation time flags */ @@ -199,10 +201,25 @@ void bnx2x_panic_dump(struct bnx2x *bp); /* EQ completions */ #define HC_SP_INDEX_EQ_CONS 7 +/* FCoE L2 connection completions */ +#define HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS 6 +#define HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS 4 /* iSCSI L2 */ #define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 #define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 +/* Special clients parameters */ + +/* SB indices */ +/* FCoE L2 */ +#define BNX2X_FCOE_L2_RX_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS]) + +#define BNX2X_FCOE_L2_TX_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS]) + /** * CIDs and CLIDs: * CLIDs below is a CLID for func 0, then the CLID for other @@ -215,12 +232,19 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define BNX2X_ISCSI_ETH_CL_ID 17 #define BNX2X_ISCSI_ETH_CID 17 +/* FCoE L2 */ +#define BNX2X_FCOE_ETH_CL_ID 18 +#define BNX2X_FCOE_ETH_CID 18 + /** Additional rings budgeting */ #ifdef BCM_CNIC #define CNIC_CONTEXT_USE 1 +#define FCOE_CONTEXT_USE 1 #else #define CNIC_CONTEXT_USE 0 +#define FCOE_CONTEXT_USE 0 #endif /* BCM_CNIC */ +#define NONE_ETH_CONTEXT_USE (FCOE_CONTEXT_USE) #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR @@ -401,6 +425,17 @@ struct bnx2x_fastpath { }; #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) +#ifdef BCM_CNIC +/* FCoE L2 `fastpath' is right after the eth entries */ +#define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) +#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX]) +#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) +#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX) +#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX) +#else +#define IS_FCOE_FP(fp) false +#define IS_FCOE_IDX(idx) false +#endif /* MC hsi */ @@ -669,7 +704,9 @@ struct bnx2x_port { enum { CAM_ETH_LINE = 0, CAM_ISCSI_ETH_LINE, - CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE + CAM_FIP_ETH_LINE, + CAM_FIP_MCAST_LINE, + CAM_MAX_PF_LINE = CAM_FIP_MCAST_LINE }; /* number of MACs per function in NIG memory - used for SI mode */ #define NIG_LLH_FUNC_MEM_SIZE 16 @@ -714,6 +751,14 @@ enum { */ #define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) +/* + * The number of FP-SB allocated by the driver == max number of regular L2 + * queues + 1 for the CNIC which also consumes an FP-SB + */ +#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE) +#define NUM_IGU_SB_REQUIRED(cid_cnt) \ + (FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE) + union cdu_context { struct eth_context eth; char pad[1024]; @@ -726,7 +771,8 @@ union cdu_context { #ifdef BCM_CNIC #define CNIC_ISCSI_CID_MAX 256 -#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_FCOE_CID_MAX 2048 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX) #define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) #endif @@ -922,6 +968,10 @@ struct bnx2x { #define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) #define MF_FUNC_DIS 0x1000 +#define FCOE_MACS_SET 0x2000 +#define NO_FCOE_FLAG 0x4000 + +#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) int pf_num; /* absolute PF number */ int pfid; /* per-path PF number */ @@ -1069,7 +1119,8 @@ struct bnx2x { u16 cnic_kwq_pending; u16 cnic_spq_pending; struct mutex cnic_mutex; - u8 iscsi_mac[6]; + u8 iscsi_mac[ETH_ALEN]; + u8 fip_mac[ETH_ALEN]; #endif int dmae_ready; @@ -1159,10 +1210,17 @@ struct bnx2x { #define RSS_IPV6_TCP_CAP 0x0008 #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) +#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE) + +/* ethtool statistics are displayed for all regular ethernet queues and the + * fcoe L2 queue if not disabled + */ +#define BNX2X_NUM_STAT_QUEUES(bp) (NO_FCOE(bp) ? BNX2X_NUM_ETH_QUEUES(bp) : \ + (BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE)) + #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) #define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) -#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) #define RSS_IPV4_CAP_MASK \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY @@ -1255,6 +1313,7 @@ struct bnx2x_client_ramrod_params { u16 cl_id; u32 cid; u8 poll; +#define CLIENT_IS_FCOE 0x01 #define CLIENT_IS_LEADING_RSS 0x02 u8 flags; }; @@ -1287,11 +1346,54 @@ struct bnx2x_func_init_params { u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ }; +#define for_each_eth_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + +#define for_each_nondefault_eth_queue(bp, var) \ + for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + +#define for_each_napi_queue(bp, var) \ + for (var = 0; \ + var < BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE; var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else + #define for_each_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else + +#define for_each_rx_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_rx_queue(bp, var)) \ + continue; \ + else + +#define for_each_tx_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_tx_queue(bp, var)) \ + continue; \ + else + #define for_each_nondefault_queue(bp, var) \ - for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) + for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else +/* skip rx queue + * if FCOE l2 support is diabled and this is the fcoe L2 queue + */ +#define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) + +/* skip tx queue + * if FCOE l2 support is diabled and this is the fcoe L2 queue + */ +#define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) + +#define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) #define WAIT_RAMROD_POLL 0x01 #define WAIT_RAMROD_COMMON 0x02 @@ -1615,10 +1717,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ (T_ETH_MAC_COMMAND_INVALIDATE)) -#define CAM_INVALIDATE(x) \ - (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) - - /* Number of u32 elements in MC hash array */ #define MC_HASH_SIZE 8 #define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 236c00c3f568..fa12365faec2 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -827,7 +827,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; if (!fp->disable_tpa) { @@ -880,7 +880,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) } } - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; fp->rx_bd_cons = 0; @@ -911,7 +911,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; u16 bd_cons = fp->tx_bd_cons; @@ -929,7 +929,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) { int i, j; - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; for (i = 0; i < NUM_RX_BD; i++) { @@ -970,7 +970,7 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " "state %x\n", i, bp->msix_table[i + offset].vector, bnx2x_fp(bp, i, state)); @@ -1004,14 +1004,14 @@ int bnx2x_enable_msix(struct bnx2x *bp) bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); msix_vec++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " "(fastpath #%u)\n", msix_vec, msix_vec, i); msix_vec++; } - req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_CONTEXT_USE + 1; rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); @@ -1067,7 +1067,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", bp->dev->name, i); @@ -1084,7 +1084,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) fp->state = BNX2X_FP_STATE_IRQ; } - i = BNX2X_NUM_QUEUES(bp); + i = BNX2X_NUM_ETH_QUEUES(bp); offset = 1 + CNIC_CONTEXT_USE; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", @@ -1131,7 +1131,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) napi_enable(&bnx2x_fp(bp, i, napi)); } @@ -1139,7 +1139,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) napi_disable(&bnx2x_fp(bp, i, napi)); } @@ -1181,7 +1181,22 @@ void bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues = 1; break; } + + /* Add special queues */ + bp->num_queues += NONE_ETH_CONTEXT_USE; +} + +#ifdef BCM_CNIC +static inline void bnx2x_set_fcoe_eth_macs(struct bnx2x *bp) +{ + if (!NO_FCOE(bp)) { + if (!IS_MF_SD(bp)) + bnx2x_set_fip_eth_mac_addr(bp, 1); + bnx2x_set_all_enode_macs(bp, 1); + bp->flags |= FCOE_MACS_SET; + } } +#endif static void bnx2x_release_firmware(struct bnx2x *bp) { @@ -1191,6 +1206,20 @@ static void bnx2x_release_firmware(struct bnx2x *bp) release_firmware(bp->firmware); } +static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) +{ + int rc, num = bp->num_queues; + +#ifdef BCM_CNIC + if (NO_FCOE(bp)) + num -= FCOE_CONTEXT_USE; + +#endif + netif_set_real_num_tx_queues(bp->dev, num); + rc = netif_set_real_num_rx_queues(bp->dev, num); + return rc; +} + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { @@ -1217,10 +1246,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bnx2x_alloc_mem(bp)) return -ENOMEM; - netif_set_real_num_tx_queues(bp->dev, bp->num_queues); - rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues); + rc = bnx2x_set_real_num_queues(bp); if (rc) { - BNX2X_ERR("Unable to update real_num_rx_queues\n"); + BNX2X_ERR("Unable to set real_num_queues\n"); goto load_error0; } @@ -1228,6 +1256,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); +#ifdef BCM_CNIC + /* We don't want TPA on FCoE L2 ring */ + bnx2x_fcoe(bp, disable_tpa) = 1; +#endif bnx2x_napi_enable(bp); /* Send LOAD_REQUEST command to MCP @@ -1358,6 +1390,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Now when Clients are configured we are ready to work */ bp->state = BNX2X_STATE_OPEN; +#ifdef BCM_CNIC + bnx2x_set_fcoe_eth_macs(bp); +#endif + bnx2x_set_eth_mac(bp, 1); if (bp->port.pmf) @@ -1416,7 +1452,7 @@ load_error3: /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); /* Release IRQs */ @@ -1487,7 +1523,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); bnx2x_free_mem(bp); @@ -1591,6 +1627,17 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { +#ifdef BCM_CNIC + /* No need to update SB for FCoE L2 ring as long as + * it's connected to the default SB and the SB + * has been updated when NAPI was scheduled. + */ + if (IS_FCOE_FP(fp)) { + napi_complete(napi); + break; + } +#endif + bnx2x_update_fpsb_idx(fp); /* bnx2x_has_rx_work() reads the status block, * thus we need to ensure that status block indices @@ -2255,7 +2302,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) bp->fp = fp; /* msix table */ - tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl), + tbl = kzalloc((FP_SB_COUNT(bp->l2_cid_count) + 1) * sizeof(*tbl), GFP_KERNEL); if (!tbl) goto alloc_err; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index cb8f2a040a18..4bb011358ed9 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -242,6 +242,30 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); */ void bnx2x_set_eth_mac(struct bnx2x *bp, int set); +#ifdef BCM_CNIC +/** + * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH + * MAC(s). This function will wait until the ramdord completion + * returns. + * + * @param bp driver handle + * @param set set or clear the CAM entry + * + * @return 0 if cussess, -ENODEV if ramrod doesn't return. + */ +int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set); + +/** + * Set/Clear ALL_ENODE mcast MAC. + * + * @param bp + * @param set + * + * @return int + */ +int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set); +#endif + /** * Set MAC filtering configurations. * @@ -695,7 +719,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) int i; /* Add NAPI objects */ - for_each_queue(bp, i) + for_each_napi_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), bnx2x_poll, BNX2X_NAPI_WEIGHT); } @@ -704,7 +728,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) netif_napi_del(&bnx2x_fp(bp, i, napi)); } @@ -870,7 +894,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i, j; - for_each_queue(bp, j) { + for_each_tx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; for (i = 1; i <= NUM_TX_RINGS; i++) { @@ -949,7 +973,30 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) } } +#ifdef BCM_CNIC +static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) +{ + bnx2x_fcoe(bp, cl_id) = BNX2X_FCOE_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; + bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID; + bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; + bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; + bnx2x_fcoe(bp, bp) = bp; + bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; + bnx2x_fcoe(bp, index) = FCOE_IDX; + bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; + bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX; + /* qZone id equals to FW (per path) client id */ + bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fcoe(bp, cl_id) + + BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : + ETH_MAX_RX_CLIENTS_E1H); + /* init shortcut */ + bnx2x_fcoe(bp, ustorm_rx_prods_offset) = CHIP_IS_E2(bp) ? + USTORM_RX_PRODS_E2_OFFSET(bnx2x_fcoe(bp, cl_qzone_id)) : + USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), bnx2x_fcoe_fp(bp)->cl_id); +} +#endif static inline void __storm_memset_struct(struct bnx2x *bp, u32 addr, size_t size, u32 *data) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index bd94827e5e57..99c672d894ca 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,6 +25,143 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" +/* Note: in the format strings below %s is replaced by the queue-name which is + * either its index or 'fcoe' for the fcoe queue. Make sure the format string + * length does not exceed ETH_GSTRING_LEN - MAX_QUEUE_NAME_LEN + 2 + */ +#define MAX_QUEUE_NAME_LEN 4 +static const struct { + long offset; + int size; + char string[ETH_GSTRING_LEN]; +} bnx2x_q_stats_arr[] = { +/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%s]: rx_bytes" }, + { Q_STATS_OFFSET32(error_bytes_received_hi), + 8, "[%s]: rx_error_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_received_hi), + 8, "[%s]: rx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_received_hi), + 8, "[%s]: rx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, "[%s]: rx_bcast_packets" }, + { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%s]: rx_discards" }, + { Q_STATS_OFFSET32(rx_err_discard_pkt), + 4, "[%s]: rx_phy_ip_err_discards"}, + { Q_STATS_OFFSET32(rx_skb_alloc_failed), + 4, "[%s]: rx_skb_alloc_discard" }, + { Q_STATS_OFFSET32(hw_csum_err), 4, "[%s]: rx_csum_offload_errors" }, + +/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, "[%s]: tx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, "[%s]: tx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, "[%s]: tx_bcast_packets" } +}; + +#define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr) + +static const struct { + long offset; + int size; + u32 flags; +#define STATS_FLAGS_PORT 1 +#define STATS_FLAGS_FUNC 2 +#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) + char string[ETH_GSTRING_LEN]; +} bnx2x_stats_arr[] = { +/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bytes" }, + { STATS_OFFSET32(error_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, + { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), + 8, STATS_FLAGS_PORT, "rx_crc_errors" }, + { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), + 8, STATS_FLAGS_PORT, "rx_align_errors" }, + { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, + { STATS_OFFSET32(etherstatsoverrsizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, +/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), + 8, STATS_FLAGS_PORT, "rx_fragments" }, + { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), + 8, STATS_FLAGS_PORT, "rx_jabbers" }, + { STATS_OFFSET32(no_buff_discard_hi), + 8, STATS_FLAGS_BOTH, "rx_discards" }, + { STATS_OFFSET32(mac_filter_discard), + 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, + { STATS_OFFSET32(xxoverflow_discard), + 4, STATS_FLAGS_PORT, "rx_fw_discards" }, + { STATS_OFFSET32(brb_drop_hi), + 8, STATS_FLAGS_PORT, "rx_brb_discard" }, + { STATS_OFFSET32(brb_truncate_hi), + 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, + { STATS_OFFSET32(pause_frames_received_hi), + 8, STATS_FLAGS_PORT, "rx_pause_frames" }, + { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), + 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, + { STATS_OFFSET32(nig_timer_max), + 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, +/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), + 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, + { STATS_OFFSET32(rx_skb_alloc_failed), + 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, + { STATS_OFFSET32(hw_csum_err), + 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, + + { STATS_OFFSET32(total_bytes_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bytes" }, + { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), + 8, STATS_FLAGS_PORT, "tx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, + { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), + 8, STATS_FLAGS_PORT, "tx_mac_errors" }, + { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), + 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, +/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_single_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), + 8, STATS_FLAGS_PORT, "tx_deferred" }, + { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_late_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), + 8, STATS_FLAGS_PORT, "tx_total_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), + 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), + 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), + 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), + 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, +/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), + 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, + { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, + { STATS_OFFSET32(etherstatspktsover1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, + { STATS_OFFSET32(pause_frames_sent_hi), + 8, STATS_FLAGS_PORT, "tx_pause_frames" } +}; + +#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) + static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); @@ -1318,7 +1455,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) save_val = REG_RD(bp, offset); - REG_WR(bp, offset, (wr_val & mask)); + REG_WR(bp, offset, wr_val & mask); val = REG_RD(bp, offset); @@ -1689,7 +1826,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) config->hdr.client_id = bp->fp->cl_id; config->hdr.reserved1 = 0; - bp->set_mac_pending++; + bp->set_mac_pending = 1; smp_wmb(); rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), @@ -1787,134 +1924,6 @@ static void bnx2x_self_test(struct net_device *dev, #endif } -static const struct { - long offset; - int size; - u8 string[ETH_GSTRING_LEN]; -} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = { -/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" }, - { Q_STATS_OFFSET32(error_bytes_received_hi), - 8, "[%d]: rx_error_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_received_hi), - 8, "[%d]: rx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_received_hi), - 8, "[%d]: rx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, "[%d]: rx_bcast_packets" }, - { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" }, - { Q_STATS_OFFSET32(rx_err_discard_pkt), - 4, "[%d]: rx_phy_ip_err_discards"}, - { Q_STATS_OFFSET32(rx_skb_alloc_failed), - 4, "[%d]: rx_skb_alloc_discard" }, - { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" }, - -/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, "[%d]: tx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, "[%d]: tx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, "[%d]: tx_bcast_packets" } -}; - -static const struct { - long offset; - int size; - u32 flags; -#define STATS_FLAGS_PORT 1 -#define STATS_FLAGS_FUNC 2 -#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) - u8 string[ETH_GSTRING_LEN]; -} bnx2x_stats_arr[BNX2X_NUM_STATS] = { -/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bytes" }, - { STATS_OFFSET32(error_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, - { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), - 8, STATS_FLAGS_PORT, "rx_crc_errors" }, - { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), - 8, STATS_FLAGS_PORT, "rx_align_errors" }, - { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, - { STATS_OFFSET32(etherstatsoverrsizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, -/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), - 8, STATS_FLAGS_PORT, "rx_fragments" }, - { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), - 8, STATS_FLAGS_PORT, "rx_jabbers" }, - { STATS_OFFSET32(no_buff_discard_hi), - 8, STATS_FLAGS_BOTH, "rx_discards" }, - { STATS_OFFSET32(mac_filter_discard), - 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, - { STATS_OFFSET32(xxoverflow_discard), - 4, STATS_FLAGS_PORT, "rx_fw_discards" }, - { STATS_OFFSET32(brb_drop_hi), - 8, STATS_FLAGS_PORT, "rx_brb_discard" }, - { STATS_OFFSET32(brb_truncate_hi), - 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, - { STATS_OFFSET32(pause_frames_received_hi), - 8, STATS_FLAGS_PORT, "rx_pause_frames" }, - { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), - 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, - { STATS_OFFSET32(nig_timer_max), - 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, -/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), - 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, - { STATS_OFFSET32(rx_skb_alloc_failed), - 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, - { STATS_OFFSET32(hw_csum_err), - 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, - - { STATS_OFFSET32(total_bytes_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bytes" }, - { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), - 8, STATS_FLAGS_PORT, "tx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, - { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), - 8, STATS_FLAGS_PORT, "tx_mac_errors" }, - { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), - 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, -/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_single_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), - 8, STATS_FLAGS_PORT, "tx_deferred" }, - { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_late_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), - 8, STATS_FLAGS_PORT, "tx_total_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), - 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), - 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), - 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), - 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, -/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), - 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, - { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, - { STATS_OFFSET32(etherstatspktsover1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, - { STATS_OFFSET32(pause_frames_sent_hi), - 8, STATS_FLAGS_PORT, "tx_pause_frames" } -}; - #define IS_PORT_STAT(i) \ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) @@ -1929,7 +1938,8 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) switch (stringset) { case ETH_SS_STATS: if (is_multi(bp)) { - num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; + num_stats = BNX2X_NUM_STAT_QUEUES(bp) * + BNX2X_NUM_Q_STATS; if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; } else { @@ -1955,15 +1965,25 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) { struct bnx2x *bp = netdev_priv(dev); int i, j, k; + char queue_name[MAX_QUEUE_NAME_LEN+1]; switch (stringset) { case ETH_SS_STATS: if (is_multi(bp)) { k = 0; - for_each_queue(bp, i) { + for_each_napi_queue(bp, i) { + memset(queue_name, 0, sizeof(queue_name)); + + if (IS_FCOE_IDX(i)) + sprintf(queue_name, "fcoe"); + else + sprintf(queue_name, "%d", i); + for (j = 0; j < BNX2X_NUM_Q_STATS; j++) - sprintf(buf + (k + j)*ETH_GSTRING_LEN, - bnx2x_q_stats_arr[j].string, i); + snprintf(buf + (k + j)*ETH_GSTRING_LEN, + ETH_GSTRING_LEN, + bnx2x_q_stats_arr[j].string, + queue_name); k += BNX2X_NUM_Q_STATS; } if (IS_MF_MODE_STAT(bp)) @@ -1997,7 +2017,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, if (is_multi(bp)) { k = 0; - for_each_queue(bp, i) { + for_each_napi_queue(bp, i) { hw_stats = (u32 *)&bp->fp[i].eth_q_stats; for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { if (bnx2x_q_stats_arr[j].size == 0) { diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 0068a1dbc064..e6e2746e8bfe 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -121,6 +121,10 @@ MODULE_PARM_DESC(debug, " Default debug msglevel"); static struct workqueue_struct *bnx2x_wq; +#ifdef BCM_CNIC +static u8 ALL_ENODE_MACS[] = {0x01, 0x10, 0x18, 0x01, 0x00, 0x01}; +#endif + enum bnx2x_board_type { BCM57710 = 0, BCM57711 = 1, @@ -921,7 +925,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) sp_sb_data.p_func.vf_valid); - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int loop; struct hc_status_block_data_e2 sb_data_e2; @@ -961,6 +965,10 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* host sb data */ +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp)) + continue; +#endif BNX2X_ERR(" run indexes ("); for (j = 0; j < HC_SB_MAX_SM; j++) pr_cont("0x%x%s", @@ -1029,7 +1037,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) #ifdef BNX2X_STOP_ON_ERROR /* Rings */ /* Rx */ - for_each_queue(bp, i) { + for_each_rx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10); @@ -1063,7 +1071,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) } /* Tx */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10); @@ -1298,7 +1306,7 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) + for_each_eth_queue(bp, i) synchronize_irq(bp->msix_table[i + offset].vector); } else synchronize_irq(bp->pdev->irq); @@ -1420,7 +1428,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); @@ -2253,6 +2261,15 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) return rc; } +static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp) +{ +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp) && IS_MF(bp)) + return false; +#endif + return true; +} + /* must be called under rtnl_lock */ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) { @@ -2411,7 +2428,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, if (!fp->disable_tpa) flags |= QUEUE_FLG_TPA; - flags |= QUEUE_FLG_STATS; + flags = stat_counter_valid(bp, fp) ? + (flags | QUEUE_FLG_STATS) : (flags & ~QUEUE_FLG_STATS); return flags; } @@ -2471,7 +2489,10 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; rxq_init->fw_sb_id = fp->fw_sb_id; - rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + if (IS_FCOE_FP(fp)) + rxq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS; + else + rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; rxq_init->cid = HW_CID(bp, fp->cid); @@ -2491,6 +2512,12 @@ static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; txq_init->fw_sb_id = fp->fw_sb_id; + + if (IS_FCOE_FP(fp)) { + txq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS; + txq_init->traffic_type = LLFC_TRAFFIC_TYPE_FCOE; + } + txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; } @@ -3689,8 +3716,11 @@ static void bnx2x_eq_int(struct bnx2x *bp) #ifdef BCM_CNIC if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) goto next_spqe; + if (cid == BNX2X_FCOE_ETH_CID) + bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; + else #endif - bnx2x_fp(bp, cid, state) = + bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; goto next_spqe; @@ -3766,7 +3796,13 @@ static void bnx2x_sp_task(struct work_struct *work) /* SP events: STAT_QUERY and others */ if (status & BNX2X_DEF_SB_IDX) { +#ifdef BCM_CNIC + struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); + if ((!NO_FCOE(bp)) && + (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) + napi_schedule(&bnx2x_fcoe(bp, napi)); +#endif /* Handle EQ completions */ bnx2x_eq_int(bp); @@ -4149,7 +4185,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, bp->rx_ticks, bp->tx_ticks); } @@ -4197,13 +4233,16 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + (i % bp->num_queues)); + bp->fp->cl_id + (i % (bp->num_queues - + NONE_ETH_CONTEXT_USE))); } void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { int mode = bp->rx_mode; + int port = BP_PORT(bp); u16 cl_id; + u32 def_q_filters = 0; /* All but management unicast packets should pass to the host as well */ u32 llh_mask = @@ -4214,30 +4253,42 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) switch (mode) { case BNX2X_RX_MODE_NONE: /* no Rx */ - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + def_q_filters = BNX2X_ACCEPT_NONE; +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + } +#endif break; case BNX2X_RX_MODE_NORMAL: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_MULTICAST); + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif break; case BNX2X_RX_MODE_ALLMULTI: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST); + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif break; case BNX2X_RX_MODE_PROMISC: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE); - + def_q_filters |= BNX2X_PROMISCUOUS_MODE; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif /* pass management unicast packets as well */ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; break; @@ -4247,20 +4298,24 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) break; } + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); + REG_WR(bp, - BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK, - llh_mask); + (port ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask); DP(NETIF_MSG_IFUP, "rx mode %d\n" "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" - "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode, + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n" + "unmatched_ucast 0x%x\n", mode, bp->mac_filters.ucast_drop_all, bp->mac_filters.mcast_drop_all, bp->mac_filters.bcast_drop_all, bp->mac_filters.ucast_accept_all, bp->mac_filters.mcast_accept_all, - bp->mac_filters.bcast_accept_all + bp->mac_filters.bcast_accept_all, + bp->mac_filters.unmatched_unicast ); storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); @@ -4369,9 +4424,11 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) { int i; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) bnx2x_init_fp_sb(bp, i); #ifdef BCM_CNIC + if (!NO_FCOE(bp)) + bnx2x_init_fcoe_fp(bp); bnx2x_init_sb(bp, bp->cnic_sb_mapping, BNX2X_VF_ID_INVALID, false, @@ -5877,6 +5934,15 @@ void bnx2x_free_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { +#ifdef BCM_CNIC + /* FCoE client uses default status block */ + if (IS_FCOE_IDX(i)) { + union host_hc_status_block *sb = + &bnx2x_fp(bp, i, status_blk); + memset(sb, 0, sizeof(union host_hc_status_block)); + bnx2x_fp(bp, i, status_blk_mapping) = 0; + } else { +#endif /* status blocks */ if (CHIP_IS_E2(bp)) BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), @@ -5886,9 +5952,12 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), bnx2x_fp(bp, i, status_blk_mapping), sizeof(struct host_hc_status_block_e1x)); +#ifdef BCM_CNIC + } +#endif } /* Rx */ - for_each_queue(bp, i) { + for_each_rx_queue(bp, i) { /* fastpath rx rings: rx_buf rx_desc rx_comp */ BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); @@ -5908,7 +5977,7 @@ void bnx2x_free_mem(struct bnx2x *bp) BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); } /* Tx */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { /* fastpath tx rings: tx_buf tx_desc */ BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); @@ -5992,15 +6061,20 @@ int bnx2x_alloc_mem(struct bnx2x *bp) union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); bnx2x_fp(bp, i, bp) = bp; /* status blocks */ - if (CHIP_IS_E2(bp)) - BNX2X_PCI_ALLOC(sb->e2_sb, - &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e2)); - else - BNX2X_PCI_ALLOC(sb->e1x_sb, - &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e1x)); - +#ifdef BCM_CNIC + if (!IS_FCOE_IDX(i)) { +#endif + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(sb->e2_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(sb->e1x_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e1x)); +#ifdef BCM_CNIC + } +#endif set_sb_shortcuts(bp, i); } /* Rx */ @@ -6410,7 +6484,8 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) { u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); - u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID; + u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; u32 cl_bit_vec = (1 << iscsi_l2_cl_id); /* Send a SET_MAC ramrod */ @@ -6418,6 +6493,50 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) cam_offset, 0); bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); + + return 0; +} + +/** + * Set FCoE L2 MAC(s) at the next enties in the CAM after the + * ETH MAC(s). This function will wait until the ramdord + * completion returns. + * + * @param bp driver handle + * @param set set or clear the CAM entry + * + * @return 0 if cussess, -ENODEV if ramrod doesn't return. + */ +int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set) +{ + u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); + /** + * CAM allocation for E1H + * eth unicasts: by func number + * iscsi: by func number + * fip unicast: by func number + * fip multicast: by func number + */ + bnx2x_set_mac_addr_gen(bp, set, bp->fip_mac, + cl_bit_vec, bnx2x_e1h_cam_offset(bp, CAM_FIP_ETH_LINE), 0); + + return 0; +} + +int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) +{ + u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); + + /** + * CAM allocation for E1H + * eth unicasts: by func number + * iscsi: by func number + * fip unicast: by func number + * fip multicast: by func number + */ + bnx2x_set_mac_addr_gen(bp, set, ALL_ENODE_MACS, cl_bit_vec, + bnx2x_e1h_cam_offset(bp, CAM_FIP_MCAST_LINE), 0); + return 0; } #endif @@ -6435,6 +6554,8 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp, data->general.statistics_counter_id = params->rxq_params.stat_id; data->general.statistics_en_flg = (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.is_fcoe_flg = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0; data->general.activate_flg = activate; data->general.sp_client_id = params->rxq_params.spcl_id; @@ -6503,7 +6624,9 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp, data->fc.safc_group_num = params->txq_params.cos; data->fc.safc_group_en_flg = (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; - data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW; + data->fc.traffic_type = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? + LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; } static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) @@ -6602,7 +6725,7 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) bnx2x_enable_msi(bp); /* falling through... */ case INT_MODE_INTx: - bp->num_queues = 1; + bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; default: @@ -6625,8 +6748,8 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) "enable MSI-X (%d), " "set number of queues to %d\n", bp->num_queues, - 1); - bp->num_queues = 1; + 1 + NONE_ETH_CONTEXT_USE); + bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; if (!(bp->flags & DISABLE_MSI_FLAG)) bnx2x_enable_msi(bp); @@ -6747,7 +6870,9 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct bnx2x_client_init_params params = { {0} }; int rc; - bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, + /* reset IGU state skip FCoE L2 queue */ + if (!IS_FCOE_FP(fp)) + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); params.ramrod_params.pstate = &fp->state; @@ -6755,6 +6880,12 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, params.ramrod_params.index = fp->index; params.ramrod_params.cid = fp->cid; +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp)) + params.ramrod_params.flags |= CLIENT_IS_FCOE; + +#endif + if (is_leading) params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; @@ -6839,7 +6970,7 @@ static void bnx2x_reset_func(struct bnx2x *bp) REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0); /* FP SBs */ - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; REG_WR8(bp, BAR_CSTRORM_INTMEM + @@ -6959,6 +7090,20 @@ static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) } } +#ifdef BCM_CNIC +static inline void bnx2x_del_fcoe_eth_macs(struct bnx2x *bp) +{ + if (bp->flags & FCOE_MACS_SET) { + if (!IS_MF_SD(bp)) + bnx2x_set_fip_eth_mac_addr(bp, 0); + + bnx2x_set_all_enode_macs(bp, 0); + + bp->flags &= ~FCOE_MACS_SET; + } +} +#endif + void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { int port = BP_PORT(bp); @@ -6966,7 +7111,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) int i, cnt, rc; /* Wait until tx fastpath tasks complete */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; cnt = 1000; @@ -7006,13 +7151,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) } #ifdef BCM_CNIC - /* Clear iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { - bnx2x_set_iscsi_eth_mac_addr(bp, 0); - bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; - } - mutex_unlock(&bp->cnic_mutex); + bnx2x_del_fcoe_eth_macs(bp); #endif if (unload_mode == UNLOAD_NORMAL) @@ -7865,7 +8004,7 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) bp->igu_sb_cnt = 0; if (CHIP_INT_MODE_IS_BC(bp)) { bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, - bp->l2_cid_count); + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * FP_SB_MAX_E1x; @@ -7896,7 +8035,8 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) } } } - bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count); + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); if (bp->igu_sb_cnt == 0) BNX2X_ERR("CAM configuration error\n"); } @@ -8312,6 +8452,17 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); +#ifdef BCM_CNIC + /* Inform the upper layers about FCoE MAC */ + if (!CHIP_IS_E1x(bp)) { + if (IS_MF_SD(bp)) + memcpy(bp->fip_mac, bp->dev->dev_addr, + sizeof(bp->fip_mac)); + else + memcpy(bp->fip_mac, bp->iscsi_mac, + sizeof(bp->fip_mac)); + } +#endif } static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) @@ -8328,7 +8479,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->igu_dsb_id = DEF_SB_IGU_ID; bp->igu_base_sb = 0; - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); } else { bp->common.int_block = INT_BLOCK_IGU; val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); @@ -9263,7 +9415,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return -ENODEV; } - cid_count += CNIC_CONTEXT_USE; + cid_count += NONE_ETH_CONTEXT_USE + CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); @@ -9292,6 +9444,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* calc qm_cid_count */ bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); +#ifdef BCM_CNIC + /* disable FCOE L2 queue for E1x*/ + if (CHIP_IS_E1x(bp)) + bp->flags |= NO_FCOE_FLAG; + +#endif + /* Configure interupt mode: try to enable MSI-X/MSI if * needed, set bp->num_queues appropriately. */ @@ -9306,6 +9465,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + /* Add storage MAC address */ + rtnl_lock(); + dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + } +#endif + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," @@ -9349,6 +9517,15 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) } bp = netdev_priv(dev); +#ifdef BCM_CNIC + /* Delete storage MAC address */ + if (!NO_FCOE(bp)) { + rtnl_lock(); + dev_addr_del(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + } +#endif + unregister_netdev(dev); /* Delete all NAPI objects */ @@ -9398,7 +9575,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); bnx2x_free_mem(bp); @@ -9625,7 +9802,8 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) break; else atomic_dec(&bp->spq_left); - } else if (type == ISCSI_CONNECTION_TYPE) { + } else if ((type == ISCSI_CONNECTION_TYPE) || + (type == FCOE_CONNECTION_TYPE)) { if (bp->cnic_spq_pending >= bp->cnic_eth_dev.max_kwqe_pending) break; @@ -9772,6 +9950,9 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_START_L2_CMD: { u32 cli = ctl->data.ring.client_id; + /* Clear FCoE FIP and ALL ENODE MACs addresses first */ + bnx2x_del_fcoe_eth_macs(bp); + /* Set iSCSI MAC address */ bnx2x_set_iscsi_eth_mac_addr(bp, 1); @@ -9893,10 +10074,6 @@ static int bnx2x_unregister_cnic(struct net_device *dev) struct cnic_eth_dev *cp = &bp->cnic_eth_dev; mutex_lock(&bp->cnic_mutex); - if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { - bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_set_iscsi_eth_mac_addr(bp, 0); - } cp->drv_state = 0; rcu_assign_pointer(bp->cnic_ops, NULL); mutex_unlock(&bp->cnic_mutex); @@ -9927,7 +10104,9 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID; + cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID; + cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 4733c835dad9..6e4d9b144cc4 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -160,7 +160,7 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) ramrod_data.drv_counter = bp->stats_counter++; ramrod_data.collect_port = bp->port.pmf ? 1 : 0; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, @@ -766,7 +766,7 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) estats->no_buff_discard_hi = 0; estats->no_buff_discard_lo = 0; - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int cl_id = fp->cl_id; struct tstorm_per_client_stats *tclient = @@ -996,7 +996,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); tmp = estats->mac_discard; - for_each_queue(bp, i) + for_each_rx_queue(bp, i) tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); nstats->rx_dropped = tmp; @@ -1087,7 +1087,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) bp->dev->name, estats->brb_drop_lo, estats->brb_truncate_lo); - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; @@ -1101,7 +1101,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) fp->rx_calls, fp->rx_pkt); } - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; struct netdev_queue *txq = @@ -1381,7 +1381,8 @@ void bnx2x_stats_init(struct bnx2x *bp) memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); } - for_each_queue(bp, i) { + /* FW stats are currently collected for ETH clients only */ + for_each_eth_queue(bp, i) { /* Set initial stats counter in the stats ramrod data to -1 */ int cl_id = bp->fp[i].cl_id; diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index afd15efa429a..596798c47452 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -53,7 +53,6 @@ struct bnx2x_eth_q_stats { u32 hw_csum_err; }; -#define BNX2X_NUM_Q_STATS 13 #define Q_STATS_OFFSET32(stat_name) \ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) @@ -225,7 +224,6 @@ struct bnx2x_eth_stats { u32 nig_timer_max; }; -#define BNX2X_NUM_STATS 43 #define STATS_OFFSET32(stat_name) \ (offsetof(struct bnx2x_eth_stats, stat_name) / 4) -- cgit v1.2.3-59-g8ed1b From 8307fa3e86a83924dd7f8310ce1e051f34986fe8 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:09 +0000 Subject: bnx2x: add a select queue callback This callback required to allow FCoE traffic to be sent on separate priority queue from other L2 traffic, which is managed by PFC in HW. Signed-off-by: Vladislav Zolotarov Signed-off-by: Shmulik Ravid-Rabinovitz Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 29 +++++++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 3 +++ drivers/net/bnx2x/bnx2x_main.c | 1 + 3 files changed, 33 insertions(+) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index fa12365faec2..10eef5434386 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1167,6 +1167,35 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) netif_tx_disable(bp->dev); } +u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) +{ +#ifdef BCM_CNIC + struct bnx2x *bp = netdev_priv(dev); + if (NO_FCOE(bp)) + return skb_tx_hash(dev, skb); + else { + struct ethhdr *hdr = (struct ethhdr *)skb->data; + u16 ether_type = ntohs(hdr->h_proto); + + /* Skip VLAN tag if present */ + if (ether_type == ETH_P_8021Q) { + struct vlan_ethhdr *vhdr = + (struct vlan_ethhdr *)skb->data; + + ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); + } + + /* If ethertype is FCoE or FIP - use FCoE ring */ + if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP)) + return bnx2x_fcoe(bp, index); + } +#endif + /* Select a none-FCoE queue: if FCoE is enabled, exclude FCoE L2 ring + */ + return __skb_tx_hash(dev, skb, + dev->real_num_tx_queues - FCOE_CONTEXT_USE); +} + void bnx2x_set_num_queues(struct bnx2x *bp) { switch (bp->multi_mode) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 4bb011358ed9..258f0c04716b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -343,6 +343,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode); /* hard_xmit callback */ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); +/* select_queue callback */ +u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); + int bnx2x_change_mac_addr(struct net_device *dev, void *p); /* NAPI poll Rx part */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index e6e2746e8bfe..563b2cb8e544 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8977,6 +8977,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_open = bnx2x_open, .ndo_stop = bnx2x_close, .ndo_start_xmit = bnx2x_start_xmit, + .ndo_select_queue = bnx2x_select_queue, .ndo_set_multicast_list = bnx2x_set_rx_mode, .ndo_set_mac_address = bnx2x_change_mac_addr, .ndo_validate_addr = eth_validate_addr, -- cgit v1.2.3-59-g8ed1b From e4901dde12d92b70dd13fa8b3bbc9df7a6129aab Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:18 +0000 Subject: bnx2x: add DCB support Adding DCB initialization and handling on 57712 FW/HW Signed-off-by: Dmitry Kravkov Signed-off-by: Shmulik Ravid-Rabinovitz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/Makefile | 2 +- drivers/net/bnx2x/bnx2x.h | 15 + drivers/net/bnx2x/bnx2x_cmn.c | 2 + drivers/net/bnx2x/bnx2x_cmn.h | 7 + drivers/net/bnx2x/bnx2x_dcb.c | 1491 ++++++++++++++++++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_dcb.h | 193 ++++++ drivers/net/bnx2x/bnx2x_hsi.h | 281 +++++++- drivers/net/bnx2x/bnx2x_link.h | 40 ++ drivers/net/bnx2x/bnx2x_main.c | 24 +- 9 files changed, 2050 insertions(+), 5 deletions(-) create mode 100644 drivers/net/bnx2x/bnx2x_dcb.c create mode 100644 drivers/net/bnx2x/bnx2x_dcb.h diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile index 084afce89ae9..bb83a2961273 100644 --- a/drivers/net/bnx2x/Makefile +++ b/drivers/net/bnx2x/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_BNX2X) += bnx2x.o -bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o +bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 475725c566d7..66b3b6055cef 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -50,6 +50,7 @@ #include "bnx2x_fw_defs.h" #include "bnx2x_hsi.h" #include "bnx2x_link.h" +#include "bnx2x_dcb.h" #include "bnx2x_stats.h" /* error/debug prints */ @@ -820,6 +821,8 @@ struct bnx2x_slowpath { u32 wb_comp; u32 wb_data[4]; + /* pfc configuration for DCBX ramrod */ + struct flow_control_configuration pfc_config; }; #define bnx2x_sp(bp, var) (&bp->slowpath->var) @@ -1180,6 +1183,18 @@ struct bnx2x { char fw_ver[32]; const struct firmware *firmware; + /* LLDP params */ + struct bnx2x_config_lldp_params lldp_config_params; + + /* DCBX params */ + struct bnx2x_config_dcbx_params dcbx_config_params; + + struct bnx2x_dcbx_port_params dcbx_port_params; + int dcb_version; + + /* DCBX Negotation results */ + struct dcbx_features dcbx_local_feat; + u32 dcbx_error; }; /** diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 10eef5434386..710ce5d04c53 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1371,6 +1371,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } + bnx2x_dcbx_init(bp); + bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; rc = bnx2x_func_start(bp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 258f0c04716b..03eb4d68e6bb 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -323,6 +323,13 @@ int bnx2x_func_start(struct bnx2x *bp); */ void bnx2x_ilt_set_info(struct bnx2x *bp); +/** + * Inintialize dcbx protocol + * + * @param bp + */ +void bnx2x_dcbx_init(struct bnx2x *bp); + /** * Set power state to the requested value. Currently only D0 and * D3hot are supported. diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c new file mode 100644 index 000000000000..0b86480379ff --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -0,0 +1,1491 @@ +/* bnx2x_dcb.c: Broadcom Everest network driver. + * + * Copyright 2009-2010 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein + * Written by: Dmitry Kravkov + * + */ +#include +#include +#include + +#include "bnx2x.h" +#include "bnx2x_cmn.h" +#include "bnx2x_dcb.h" + + +/* forward declarations of dcbx related functions */ +static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); +static void bnx2x_pfc_set_pfc(struct bnx2x *bp); +static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); +static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); +static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, + u32 *set_configuration_ets_pg, + u32 *pri_pg_tbl); +static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp, + u32 *pg_pri_orginal_spread, + struct pg_help_data *help_data); +static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + u32 *pg_pri_orginal_spread); +static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + struct dcbx_ets_feature *ets); +static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp); + + +static void bnx2x_pfc_set(struct bnx2x *bp) +{ + struct bnx2x_nig_brb_pfc_port_params pfc_params = {0}; + u32 pri_bit, val = 0; + u8 pri; + + /* Tx COS configuration */ + if (bp->dcbx_port_params.ets.cos_params[0].pauseable) + pfc_params.rx_cos0_priority_mask = + bp->dcbx_port_params.ets.cos_params[0].pri_bitmask; + if (bp->dcbx_port_params.ets.cos_params[1].pauseable) + pfc_params.rx_cos1_priority_mask = + bp->dcbx_port_params.ets.cos_params[1].pri_bitmask; + + + /** + * Rx COS configuration + * Changing PFC RX configuration . + * In RX COS0 will always be configured to lossy and COS1 to lossless + */ + for (pri = 0 ; pri < MAX_PFC_PRIORITIES ; pri++) { + pri_bit = 1 << pri; + + if (pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp)) + val |= 1 << (pri * 4); + } + + pfc_params.pkt_priority_to_cos = val; + + /* RX COS0 */ + pfc_params.llfc_low_priority_classes = 0; + /* RX COS1 */ + pfc_params.llfc_high_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp); + + /* BRB configuration */ + pfc_params.cos0_pauseable = false; + pfc_params.cos1_pauseable = true; + + bnx2x_acquire_phy_lock(bp); + bp->link_params.feature_config_flags |= FEATURE_CONFIG_PFC_ENABLED; + bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &pfc_params); + bnx2x_release_phy_lock(bp); +} + +static void bnx2x_pfc_clear(struct bnx2x *bp) +{ + struct bnx2x_nig_brb_pfc_port_params nig_params = {0}; + nig_params.pause_enable = 1; +#ifdef BNX2X_SAFC + if (bp->flags & SAFC_TX_FLAG) { + u32 high = 0, low = 0; + int i; + + for (i = 0; i < BNX2X_MAX_PRIORITY; i++) { + if (bp->pri_map[i] == 1) + high |= (1 << i); + if (bp->pri_map[i] == 0) + low |= (1 << i); + } + + nig_params.llfc_low_priority_classes = high; + nig_params.llfc_low_priority_classes = low; + + nig_params.pause_enable = 0; + nig_params.llfc_enable = 1; + nig_params.llfc_out_en = 1; + } +#endif /* BNX2X_SAFC */ + bnx2x_acquire_phy_lock(bp); + bp->link_params.feature_config_flags &= ~FEATURE_CONFIG_PFC_ENABLED; + bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &nig_params); + bnx2x_release_phy_lock(bp); +} + +static void bnx2x_dump_dcbx_drv_param(struct bnx2x *bp, + struct dcbx_features *features, + u32 error) +{ + u8 i = 0; + DP(NETIF_MSG_LINK, "local_mib.error %x\n", error); + + /* PG */ + DP(NETIF_MSG_LINK, + "local_mib.features.ets.enabled %x\n", features->ets.enabled); + for (i = 0; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) + DP(NETIF_MSG_LINK, + "local_mib.features.ets.pg_bw_tbl[%d] %d\n", i, + DCBX_PG_BW_GET(features->ets.pg_bw_tbl, i)); + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) + DP(NETIF_MSG_LINK, + "local_mib.features.ets.pri_pg_tbl[%d] %d\n", i, + DCBX_PRI_PG_GET(features->ets.pri_pg_tbl, i)); + + /* pfc */ + DP(NETIF_MSG_LINK, "dcbx_features.pfc.pri_en_bitmap %x\n", + features->pfc.pri_en_bitmap); + DP(NETIF_MSG_LINK, "dcbx_features.pfc.pfc_caps %x\n", + features->pfc.pfc_caps); + DP(NETIF_MSG_LINK, "dcbx_features.pfc.enabled %x\n", + features->pfc.enabled); + + DP(NETIF_MSG_LINK, "dcbx_features.app.default_pri %x\n", + features->app.default_pri); + DP(NETIF_MSG_LINK, "dcbx_features.app.tc_supported %x\n", + features->app.tc_supported); + DP(NETIF_MSG_LINK, "dcbx_features.app.enabled %x\n", + features->app.enabled); + for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].app_id %x\n", + i, features->app.app_pri_tbl[i].app_id); + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].pri_bitmap %x\n", + i, features->app.app_pri_tbl[i].pri_bitmap); + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].appBitfield %x\n", + i, features->app.app_pri_tbl[i].appBitfield); + } +} + +static void bnx2x_dcbx_get_ap_priority(struct bnx2x *bp, + u8 pri_bitmap, + u8 llfc_traf_type) +{ + u32 pri = MAX_PFC_PRIORITIES; + u32 index = MAX_PFC_PRIORITIES - 1; + u32 pri_mask; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + /* Choose the highest priority */ + while ((MAX_PFC_PRIORITIES == pri) && (0 != index)) { + pri_mask = 1 << index; + if (GET_FLAGS(pri_bitmap, pri_mask)) + pri = index ; + index--; + } + + if (pri < MAX_PFC_PRIORITIES) + ttp[llfc_traf_type] = max_t(u32, ttp[llfc_traf_type], pri); +} + +static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, + struct dcbx_app_priority_feature *app, + u32 error) { + u8 index; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n"); + + if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) { + + bp->dcbx_port_params.app.enabled = true; + + for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++) + ttp[index] = 0; + + if (app->default_pri < MAX_PFC_PRIORITIES) + ttp[LLFC_TRAFFIC_TYPE_NW] = app->default_pri; + + for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) { + struct dcbx_app_priority_entry *entry = + app->app_pri_tbl; + + if (GET_FLAGS(entry[index].appBitfield, + DCBX_APP_SF_ETH_TYPE) && + ETH_TYPE_FCOE == entry[index].app_id) + bnx2x_dcbx_get_ap_priority(bp, + entry[index].pri_bitmap, + LLFC_TRAFFIC_TYPE_FCOE); + + if (GET_FLAGS(entry[index].appBitfield, + DCBX_APP_SF_PORT) && + TCP_PORT_ISCSI == entry[index].app_id) + bnx2x_dcbx_get_ap_priority(bp, + entry[index].pri_bitmap, + LLFC_TRAFFIC_TYPE_ISCSI); + } + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_DISABLED\n"); + bp->dcbx_port_params.app.enabled = false; + for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++) + ttp[index] = INVALID_TRAFFIC_TYPE_PRIORITY; + } +} + +static void bnx2x_dcbx_get_ets_feature(struct bnx2x *bp, + struct dcbx_ets_feature *ets, + u32 error) { + int i = 0; + u32 pg_pri_orginal_spread[DCBX_MAX_NUM_PG_BW_ENTRIES] = {0}; + struct pg_help_data pg_help_data; + struct bnx2x_dcbx_cos_params *cos_params = + bp->dcbx_port_params.ets.cos_params; + + memset(&pg_help_data, 0, sizeof(struct pg_help_data)); + + + if (GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ERROR\n"); + + + /* Clean up old settings of ets on COS */ + for (i = 0; i < E2_NUM_OF_COS ; i++) { + + cos_params[i].pauseable = false; + cos_params[i].strict = BNX2X_DCBX_COS_NOT_STRICT; + cos_params[i].bw_tbl = DCBX_INVALID_COS_BW; + cos_params[i].pri_bitmask = DCBX_PFC_PRI_GET_NON_PAUSE(bp, 0); + } + + if (bp->dcbx_port_params.app.enabled && + !GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR) && + ets->enabled) { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ENABLE\n"); + bp->dcbx_port_params.ets.enabled = true; + + bnx2x_dcbx_get_ets_pri_pg_tbl(bp, + pg_pri_orginal_spread, + ets->pri_pg_tbl); + + bnx2x_dcbx_get_num_pg_traf_type(bp, + pg_pri_orginal_spread, + &pg_help_data); + + bnx2x_dcbx_fill_cos_params(bp, &pg_help_data, + ets, pg_pri_orginal_spread); + + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_DISABLED\n"); + bp->dcbx_port_params.ets.enabled = false; + ets->pri_pg_tbl[0] = 0; + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES ; i++) + DCBX_PG_BW_SET(ets->pg_bw_tbl, i, 1); + } +} + +static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp, + struct dcbx_pfc_feature *pfc, u32 error) +{ + + if (GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n"); + + if (bp->dcbx_port_params.app.enabled && + !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) && + pfc->enabled) { + bp->dcbx_port_params.pfc.enabled = true; + bp->dcbx_port_params.pfc.priority_non_pauseable_mask = + ~(pfc->pri_en_bitmap); + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_DISABLED\n"); + bp->dcbx_port_params.pfc.enabled = false; + bp->dcbx_port_params.pfc.priority_non_pauseable_mask = 0; + } +} + +static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp, + struct dcbx_features *features, + u32 error) +{ + bnx2x_dcbx_get_ap_feature(bp, &features->app, error); + + bnx2x_dcbx_get_pfc_feature(bp, &features->pfc, error); + + bnx2x_dcbx_get_ets_feature(bp, &features->ets, error); +} + +#define DCBX_LOCAL_MIB_MAX_TRY_READ (100) +static int bnx2x_dcbx_read_mib(struct bnx2x *bp, + u32 *base_mib_addr, + u32 offset, + int read_mib_type) +{ + int max_try_read = 0, i; + u32 *buff, mib_size, prefix_seq_num, suffix_seq_num; + struct lldp_remote_mib *remote_mib ; + struct lldp_local_mib *local_mib; + + + switch (read_mib_type) { + case DCBX_READ_LOCAL_MIB: + mib_size = sizeof(struct lldp_local_mib); + break; + case DCBX_READ_REMOTE_MIB: + mib_size = sizeof(struct lldp_remote_mib); + break; + default: + return 1; /*error*/ + } + + offset += BP_PORT(bp) * mib_size; + + do { + buff = base_mib_addr; + for (i = 0; i < mib_size; i += 4, buff++) + *buff = REG_RD(bp, offset + i); + + max_try_read++; + + switch (read_mib_type) { + case DCBX_READ_LOCAL_MIB: + local_mib = (struct lldp_local_mib *) base_mib_addr; + prefix_seq_num = local_mib->prefix_seq_num; + suffix_seq_num = local_mib->suffix_seq_num; + break; + case DCBX_READ_REMOTE_MIB: + remote_mib = (struct lldp_remote_mib *) base_mib_addr; + prefix_seq_num = remote_mib->prefix_seq_num; + suffix_seq_num = remote_mib->suffix_seq_num; + break; + default: + return 1; /*error*/ + } + } while ((prefix_seq_num != suffix_seq_num) && + (max_try_read < DCBX_LOCAL_MIB_MAX_TRY_READ)); + + if (max_try_read >= DCBX_LOCAL_MIB_MAX_TRY_READ) { + BNX2X_ERR("MIB could not be read\n"); + return 1; + } + + return 0; +} + +static void bnx2x_pfc_set_pfc(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) { + if (BP_PORT(bp)) { + BNX2X_ERR("4 port mode is not supported"); + return; + } + + if (bp->dcbx_port_params.pfc.enabled) + + /* 1. Fills up common PFC structures if required.*/ + /* 2. Configure NIG, MAC and BRB via the elink: + * elink must first check if BMAC is not in reset + * and only then configures the BMAC + * Or, configure EMAC. + */ + bnx2x_pfc_set(bp); + + else + bnx2x_pfc_clear(bp); + } +} + +static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) +{ + DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n"); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, + 0 /* connectionless */, + 0 /* dataHi is zero */, + 0 /* dataLo is zero */, + 1 /* common */); +} + +static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) +{ + bnx2x_pfc_fw_struct_e2(bp); + DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, + 0, /* connectionless */ + U64_HI(bnx2x_sp_mapping(bp, pfc_config)), + U64_LO(bnx2x_sp_mapping(bp, pfc_config)), + 1 /* commmon */); +} + +static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) +{ + struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); + u8 status = 0; + + bnx2x_ets_disabled(&bp->link_params); + + if (!ets->enabled) + return; + + if ((ets->num_of_cos == 0) || (ets->num_of_cos > E2_NUM_OF_COS)) { + BNX2X_ERR("illegal num of cos= %x", ets->num_of_cos); + return; + } + + /* valid COS entries */ + if (ets->num_of_cos == 1) /* no ETS */ + return; + + /* sanity */ + if (((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[0].strict) && + (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) || + ((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[1].strict) && + (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) { + BNX2X_ERR("all COS should have at least bw_limit or strict" + "ets->cos_params[0].strict= %x" + "ets->cos_params[0].bw_tbl= %x" + "ets->cos_params[1].strict= %x" + "ets->cos_params[1].bw_tbl= %x", + ets->cos_params[0].strict, + ets->cos_params[0].bw_tbl, + ets->cos_params[1].strict, + ets->cos_params[1].bw_tbl); + return; + } + /* If we join a group and there is bw_tbl and strict then bw rules */ + if ((DCBX_INVALID_COS_BW != ets->cos_params[0].bw_tbl) && + (DCBX_INVALID_COS_BW != ets->cos_params[1].bw_tbl)) { + u32 bw_tbl_0 = ets->cos_params[0].bw_tbl; + u32 bw_tbl_1 = ets->cos_params[1].bw_tbl; + /* Do not allow 0-100 configuration + * since PBF does not support it + * force 1-99 instead + */ + if (bw_tbl_0 == 0) { + bw_tbl_0 = 1; + bw_tbl_1 = 99; + } else if (bw_tbl_1 == 0) { + bw_tbl_1 = 1; + bw_tbl_0 = 99; + } + + bnx2x_ets_bw_limit(&bp->link_params, bw_tbl_0, bw_tbl_1); + } else { + if (ets->cos_params[0].strict == BNX2X_DCBX_COS_HIGH_STRICT) + status = bnx2x_ets_strict(&bp->link_params, 0); + else if (ets->cos_params[1].strict + == BNX2X_DCBX_COS_HIGH_STRICT) + status = bnx2x_ets_strict(&bp->link_params, 1); + + if (status) + BNX2X_ERR("update_ets_params failed\n"); + } +} + +static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp) +{ + struct lldp_local_mib local_mib = {0}; + u32 dcbx_neg_res_offset = SHMEM2_RD(bp, dcbx_neg_res_offset); + int rc; + + DP(NETIF_MSG_LINK, "dcbx_neg_res_offset 0x%x\n", dcbx_neg_res_offset); + + if (SHMEM_DCBX_NEG_RES_NONE == dcbx_neg_res_offset) { + BNX2X_ERR("FW doesn't support dcbx_neg_res_offset\n"); + return -EINVAL; + } + rc = bnx2x_dcbx_read_mib(bp, (u32 *)&local_mib, dcbx_neg_res_offset, + DCBX_READ_LOCAL_MIB); + + if (rc) { + BNX2X_ERR("Faild to read local mib from FW\n"); + return rc; + } + + /* save features and error */ + bp->dcbx_local_feat = local_mib.features; + bp->dcbx_error = local_mib.error; + return 0; +} + +void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) +{ + switch (state) { + case BNX2X_DCBX_STATE_NEG_RECEIVED: + { + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n"); + + /* Read neg results if dcbx is in the FW */ + if (bnx2x_dcbx_read_shmem_neg_results(bp)) + return; + + bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + + bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { + bnx2x_dcbx_stop_hw_tx(bp); + return; + } + /* fall through */ + } + case BNX2X_DCBX_STATE_TX_PAUSED: + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n"); + bnx2x_pfc_set_pfc(bp); + + bnx2x_dcbx_update_ets_params(bp); + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { + bnx2x_dcbx_resume_hw_tx(bp); + return; + } + /* fall through */ + case BNX2X_DCBX_STATE_TX_RELEASED: + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) + bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0); + + return; + default: + BNX2X_ERR("Unknown DCBX_STATE\n"); + } +} + + +#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\ + sizeof(struct lldp_dcbx_stat)) + +/* calculate struct offset in array according to chip information */ +#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params)) + +#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \ + BP_PORT(bp)*sizeof(struct lldp_admin_mib)) + +static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp, + u32 dcbx_lldp_params_offset) +{ + struct lldp_params lldp_params = {0}; + u32 i = 0, *buff = NULL; + u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp); + + DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset); + + if ((bp->lldp_config_params.overwrite_settings == + BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) { + /* Read the data first */ + buff = (u32 *)&lldp_params; + for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) + *buff = REG_RD(bp, (offset + i)); + + lldp_params.msg_tx_hold = + (u8)bp->lldp_config_params.msg_tx_hold; + lldp_params.msg_fast_tx_interval = + (u8)bp->lldp_config_params.msg_fast_tx; + lldp_params.tx_crd_max = + (u8)bp->lldp_config_params.tx_credit_max; + lldp_params.msg_tx_interval = + (u8)bp->lldp_config_params.msg_tx_interval; + lldp_params.tx_fast = + (u8)bp->lldp_config_params.tx_fast; + + /* Write the data.*/ + buff = (u32 *)&lldp_params; + for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) + REG_WR(bp, (offset + i) , *buff); + + + } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + bp->lldp_config_params.overwrite_settings) + bp->lldp_config_params.overwrite_settings = + BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; +} + +static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, + u32 dcbx_lldp_params_offset) +{ + struct lldp_admin_mib admin_mib; + u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0; + u32 *buff; + u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp); + + /*shortcuts*/ + struct dcbx_features *af = &admin_mib.features; + struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params; + + memset(&admin_mib, 0, sizeof(struct lldp_admin_mib)); + buff = (u32 *)&admin_mib; + /* Read the data first */ + for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) + *buff = REG_RD(bp, (offset + i)); + + + if (BNX2X_DCBX_CONFIG_INV_VALUE != dp->admin_dcbx_enable) { + if (dp->admin_dcbx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); + } + + if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + dp->overwrite_settings)) { + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK); + admin_mib.ver_cfg_flags |= + (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & + DCBX_CEE_VERSION_MASK; + + af->ets.enabled = (u8)dp->admin_ets_enable; + + af->pfc.enabled = (u8)dp->admin_pfc_enable; + + /* FOR IEEE dp->admin_tc_supported_tx_enable */ + if (dp->admin_ets_configuration_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_ETS_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_ETS_CONFIG_TX_ENABLED); + /* For IEEE admin_ets_recommendation_tx_enable */ + if (dp->admin_pfc_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_PFC_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_PFC_CONFIG_TX_ENABLED); + + if (dp->admin_application_priority_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_APP_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_APP_CONFIG_TX_ENABLED); + + if (dp->admin_ets_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING); + /* For IEEE admin_ets_reco_valid */ + if (dp->admin_pfc_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING); + + if (dp->admin_app_priority_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING); + + for (i = 0 ; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) { + DCBX_PG_BW_SET(af->ets.pg_bw_tbl, i, + (u8)dp->admin_configuration_bw_precentage[i]); + + DP(NETIF_MSG_LINK, "pg_bw_tbl[%d] = %02x\n", + i, DCBX_PG_BW_GET(af->ets.pg_bw_tbl, i)); + } + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) { + DCBX_PRI_PG_SET(af->ets.pri_pg_tbl, i, + (u8)dp->admin_configuration_ets_pg[i]); + + DP(NETIF_MSG_LINK, "pri_pg_tbl[%d] = %02x\n", + i, DCBX_PRI_PG_GET(af->ets.pri_pg_tbl, i)); + } + + /*For IEEE admin_recommendation_bw_precentage + *For IEEE admin_recommendation_ets_pg */ + af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap; + for (i = 0; i < 4; i++) { + if (dp->admin_priority_app_table[i].valid) { + struct bnx2x_admin_priority_app_table *table = + dp->admin_priority_app_table; + if ((ETH_TYPE_FCOE == table[i].app_id) && + (TRAFFIC_TYPE_ETH == table[i].traffic_type)) + traf_type = FCOE_APP_IDX; + else if ((TCP_PORT_ISCSI == table[i].app_id) && + (TRAFFIC_TYPE_PORT == table[i].traffic_type)) + traf_type = ISCSI_APP_IDX; + else + traf_type = other_traf_type++; + + af->app.app_pri_tbl[traf_type].app_id = + table[i].app_id; + + af->app.app_pri_tbl[traf_type].pri_bitmap = + (u8)(1 << table[i].priority); + + af->app.app_pri_tbl[traf_type].appBitfield = + (DCBX_APP_ENTRY_VALID); + + af->app.app_pri_tbl[traf_type].appBitfield |= + (TRAFFIC_TYPE_ETH == table[i].traffic_type) ? + DCBX_APP_SF_ETH_TYPE : DCBX_APP_SF_PORT; + } + } + + af->app.default_pri = (u8)dp->admin_default_priority; + + } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + dp->overwrite_settings) + dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; + + /* Write the data. */ + buff = (u32 *)&admin_mib; + for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) + REG_WR(bp, (offset + i), *buff); +} + +/* default */ +void bnx2x_dcbx_init_params(struct bnx2x *bp) +{ + bp->dcbx_config_params.admin_dcbx_version = 0x0; /* 0 - CEE; 1 - IEEE */ + bp->dcbx_config_params.dcb_enable = 1; + bp->dcbx_config_params.admin_dcbx_enable = 1; + bp->dcbx_config_params.admin_ets_willing = 1; + bp->dcbx_config_params.admin_pfc_willing = 1; + bp->dcbx_config_params.overwrite_settings = 1; + bp->dcbx_config_params.admin_ets_enable = 1; + bp->dcbx_config_params.admin_pfc_enable = 1; + bp->dcbx_config_params.admin_tc_supported_tx_enable = 1; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; + bp->dcbx_config_params.admin_pfc_tx_enable = 1; + bp->dcbx_config_params.admin_application_priority_tx_enable = 1; + bp->dcbx_config_params.admin_ets_reco_valid = 1; + bp->dcbx_config_params.admin_app_priority_willing = 1; + bp->dcbx_config_params.admin_configuration_bw_precentage[0] = 00; + bp->dcbx_config_params.admin_configuration_bw_precentage[1] = 50; + bp->dcbx_config_params.admin_configuration_bw_precentage[2] = 50; + bp->dcbx_config_params.admin_configuration_bw_precentage[3] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[4] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[5] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[6] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[7] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[0] = 1; + bp->dcbx_config_params.admin_configuration_ets_pg[1] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[2] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[3] = 2; + bp->dcbx_config_params.admin_configuration_ets_pg[4] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[5] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[6] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[7] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[0] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[1] = 1; + bp->dcbx_config_params.admin_recommendation_bw_precentage[2] = 2; + bp->dcbx_config_params.admin_recommendation_bw_precentage[3] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[4] = 7; + bp->dcbx_config_params.admin_recommendation_bw_precentage[5] = 5; + bp->dcbx_config_params.admin_recommendation_bw_precentage[6] = 6; + bp->dcbx_config_params.admin_recommendation_bw_precentage[7] = 7; + bp->dcbx_config_params.admin_recommendation_ets_pg[0] = 0; + bp->dcbx_config_params.admin_recommendation_ets_pg[1] = 1; + bp->dcbx_config_params.admin_recommendation_ets_pg[2] = 2; + bp->dcbx_config_params.admin_recommendation_ets_pg[3] = 3; + bp->dcbx_config_params.admin_recommendation_ets_pg[4] = 4; + bp->dcbx_config_params.admin_recommendation_ets_pg[5] = 5; + bp->dcbx_config_params.admin_recommendation_ets_pg[6] = 6; + bp->dcbx_config_params.admin_recommendation_ets_pg[7] = 7; + bp->dcbx_config_params.admin_pfc_bitmap = 0x8; /* FCoE(3) enable */ + bp->dcbx_config_params.admin_priority_app_table[0].valid = 1; + bp->dcbx_config_params.admin_priority_app_table[1].valid = 1; + bp->dcbx_config_params.admin_priority_app_table[2].valid = 0; + bp->dcbx_config_params.admin_priority_app_table[3].valid = 0; + bp->dcbx_config_params.admin_priority_app_table[0].priority = 3; + bp->dcbx_config_params.admin_priority_app_table[1].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[2].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[3].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[0].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[1].traffic_type = 1; + bp->dcbx_config_params.admin_priority_app_table[2].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[3].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[0].app_id = 0x8906; + bp->dcbx_config_params.admin_priority_app_table[1].app_id = 3260; + bp->dcbx_config_params.admin_priority_app_table[2].app_id = 0; + bp->dcbx_config_params.admin_priority_app_table[3].app_id = 0; + bp->dcbx_config_params.admin_default_priority = + bp->dcbx_config_params.admin_priority_app_table[1].priority; +} + +void bnx2x_dcbx_init(struct bnx2x *bp) +{ + u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; + /* validate: + * chip of good for dcbx version, + * dcb is wanted + * the function is pmf + * shmem2 contains DCBX support fields + */ + DP(NETIF_MSG_LINK, "dcb_enable %d bp->port.pmf %d\n", + bp->dcbx_config_params.dcb_enable, bp->port.pmf); + + if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp) && + bp->dcbx_config_params.dcb_enable && + bp->port.pmf && + SHMEM2_HAS(bp, dcbx_lldp_params_offset)) { + dcbx_lldp_params_offset = SHMEM2_RD(bp, + dcbx_lldp_params_offset); + DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", + dcbx_lldp_params_offset); + if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { + bnx2x_dcbx_lldp_updated_params(bp, + dcbx_lldp_params_offset); + + bnx2x_dcbx_admin_mib_updated_params(bp, + dcbx_lldp_params_offset); + + /* set default configuration BC has */ + bnx2x_dcbx_set_params(bp, + BNX2X_DCBX_STATE_NEG_RECEIVED); + + bnx2x_fw_command(bp, + DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0); + } + } +} + +void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp) +{ + struct priority_cos pricos[MAX_PFC_TRAFFIC_TYPES]; + u32 i = 0, addr; + memset(pricos, 0, sizeof(pricos)); + /* Default initialization */ + for (i = 0; i < MAX_PFC_TRAFFIC_TYPES; i++) + pricos[i].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; + + /* Store per port struct to internal memory */ + addr = BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, + traffic_type_to_priority_cos); + __storm_memset_struct(bp, addr, sizeof(pricos), (u32 *)pricos); + + + /* LLFC disabled.*/ + REG_WR8(bp , BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, llfc_mode), + LLFC_MODE_NONE); + + /* DCBX disabled.*/ + REG_WR8(bp , BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, dcb_enabled), + DCB_DISABLED); +} + +static void +bnx2x_dcbx_print_cos_params(struct bnx2x *bp, + struct flow_control_configuration *pfc_fw_cfg) +{ + u8 pri = 0; + u8 cos = 0; + + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->dcb_version %x\n", pfc_fw_cfg->dcb_version); + DP(NETIF_MSG_LINK, + "pdev->params.dcbx_port_params.pfc." + "priority_non_pauseable_mask %x\n", + bp->dcbx_port_params.pfc.priority_non_pauseable_mask); + + for (cos = 0 ; cos < bp->dcbx_port_params.ets.num_of_cos ; cos++) { + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].pri_bitmask %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].bw_tbl %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].bw_tbl); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].strict %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].strict); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].pauseable %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].pauseable); + } + + for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) { + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->traffic_type_to_priority_cos[%d]." + "priority %x\n", pri, + pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority); + + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n", + pri, pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos); + } +} + +/* fills help_data according to pg_info */ +static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp, + u32 *pg_pri_orginal_spread, + struct pg_help_data *help_data) +{ + bool pg_found = false; + u32 i, traf_type, add_traf_type, add_pg; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + struct pg_entry_help_data *data = help_data->data; /*shotcut*/ + + /* Set to invalid */ + for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) + data[i].pg = DCBX_ILLEGAL_PG; + + for (add_traf_type = 0; + add_traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; add_traf_type++) { + pg_found = false; + if (ttp[add_traf_type] < MAX_PFC_PRIORITIES) { + add_pg = (u8)pg_pri_orginal_spread[ttp[add_traf_type]]; + for (traf_type = 0; + traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; + traf_type++) { + if (data[traf_type].pg == add_pg) { + if (!(data[traf_type].pg_priority & + (1 << ttp[add_traf_type]))) + data[traf_type]. + num_of_dif_pri++; + data[traf_type].pg_priority |= + (1 << ttp[add_traf_type]); + pg_found = true; + break; + } + } + if (false == pg_found) { + data[help_data->num_of_pg].pg = add_pg; + data[help_data->num_of_pg].pg_priority = + (1 << ttp[add_traf_type]); + data[help_data->num_of_pg].num_of_dif_pri = 1; + help_data->num_of_pg++; + } + } + DP(NETIF_MSG_LINK, + "add_traf_type %d pg_found %s num_of_pg %d\n", + add_traf_type, (false == pg_found) ? "NO" : "YES", + help_data->num_of_pg); + } +} + + +/******************************************************************************* + * Description: single priority group + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 pri_join_mask) +{ + /* Only one priority than only one COS */ + cos_data->data[0].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + cos_data->data[0].pri_join_mask = pri_join_mask; + cos_data->data[0].cos_bw = 100; + cos_data->num_of_cos = 1; +} + +/******************************************************************************* + * Description: updating the cos bw + * + * Return: + ******************************************************************************/ +static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp, + struct cos_entry_help_data *data, + u8 pg_bw) +{ + if (data->cos_bw == DCBX_INVALID_COS_BW) + data->cos_bw = pg_bw; + else + data->cos_bw += pg_bw; +} + +/******************************************************************************* + * Description: single priority group + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + struct dcbx_ets_feature *ets) +{ + u32 pri_tested = 0; + u8 i = 0; + u8 entry = 0; + u8 pg_entry = 0; + u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX; + + cos_data->data[0].pausable = true; + cos_data->data[1].pausable = false; + cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0; + + for (i = 0 ; i < num_of_pri ; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + + if (pri_tested & DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) { + cos_data->data[1].pri_join_mask |= pri_tested; + entry = 1; + } else { + cos_data->data[0].pri_join_mask |= pri_tested; + entry = 0; + } + pg_entry = (u8)pg_pri_orginal_spread[bp->dcbx_port_params. + app.traffic_type_priority[i]]; + /* There can be only one strict pg */ + if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) + bnx2x_dcbx_add_to_cos_bw(bp, &cos_data->data[entry], + DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry)); + else + /* If we join a group and one is strict + * than the bw rulls */ + cos_data->data[entry].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + if ((0 == cos_data->data[0].pri_join_mask) && + (0 == cos_data->data[1].pri_join_mask)) + BNX2X_ERR("dcbx error: Both groups must have priorities\n"); +} + + +#ifndef POWER_OF_2 +#define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1)))) +#endif + +static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct cos_help_data *cos_data, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u32 pri_tested = 0; + u32 pri_mask_without_pri = 0; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + /*debug*/ + if (num_of_dif_pri == 1) { + bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, pri_join_mask); + return; + } + /* single priority group */ + if (pg_help_data->data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) { + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and + * the non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pauseable.*/ + cos_data->data[1].pausable = false; + + if (2 == num_of_dif_pri) { + cos_data->data[0].cos_bw = 50; + cos_data->data[1].cos_bw = 50; + } + + if (3 == num_of_dif_pri) { + if (POWER_OF_2(DCBX_PFC_PRI_GET_PAUSE(bp, + pri_join_mask))) { + cos_data->data[0].cos_bw = 33; + cos_data->data[1].cos_bw = 67; + } else { + cos_data->data[0].cos_bw = 67; + cos_data->data[1].cos_bw = 33; + } + } + + } else if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask)) { + /* If there are only pauseable priorities, + * then one/two priorities go to the first queue + * and one priority goes to the second queue. + */ + if (2 == num_of_dif_pri) { + cos_data->data[0].cos_bw = 50; + cos_data->data[1].cos_bw = 50; + } else { + cos_data->data[0].cos_bw = 67; + cos_data->data[1].cos_bw = 33; + } + cos_data->data[1].pausable = true; + cos_data->data[0].pausable = true; + /* All priorities except FCOE */ + cos_data->data[0].pri_join_mask = (pri_join_mask & + ((u8)~(1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]))); + /* Only FCOE priority.*/ + cos_data->data[1].pri_join_mask = + (1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]); + } else + /* If there are only non-pauseable priorities, + * they will all go to the same queue. + */ + bnx2x_dcbx_ets_disabled_entry_data(bp, + cos_data, pri_join_mask); + } else { + /* priority group which is not BW limited (PG#15):*/ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + /* If there are both pauseable and non-pauseable + * priorities, the pauseable priorities go to the first + * queue and the non-pauseable priorities + * go to the second queue. + */ + if (DCBX_PFC_PRI_GET_PAUSE(bp, pri_join_mask) > + DCBX_PFC_PRI_GET_NON_PAUSE(bp, pri_join_mask)) { + cos_data->data[0].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + cos_data->data[1].strict = + BNX2X_DCBX_COS_LOW_STRICT; + } else { + cos_data->data[0].strict = + BNX2X_DCBX_COS_LOW_STRICT; + cos_data->data[1].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pause-able.*/ + cos_data->data[1].pausable = false; + } else { + /* If there are only pauseable priorities or + * only non-pauseable,* the lower priorities go + * to the first queue and the higherpriorities go + * to the second queue. + */ + cos_data->data[0].pausable = + cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + + for (i = 0 ; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + /* Remove priority tested */ + pri_mask_without_pri = + (pri_join_mask & ((u8)(~pri_tested))); + if (pri_mask_without_pri < pri_tested) + break; + } + + if (i == LLFC_DRIVER_TRAFFIC_TYPE_MAX) + BNX2X_ERR("Invalid value for pri_join_mask -" + " could not find a priority\n"); + + cos_data->data[0].pri_join_mask = pri_mask_without_pri; + cos_data->data[1].pri_join_mask = pri_tested; + /* Both queues are strict priority, + * and that with the highest priority + * gets the highest strict priority in the arbiter. + */ + cos_data->data[0].strict = BNX2X_DCBX_COS_LOW_STRICT; + cos_data->data[1].strict = BNX2X_DCBX_COS_HIGH_STRICT; + } + } +} + +static void bnx2x_dcbx_two_pg_to_cos_params( + struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct dcbx_ets_feature *ets, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u8 pg[E2_NUM_OF_COS] = {0}; + + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and + * the non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, + pg_help_data->data[0].pg_priority) || + IS_DCBX_PFC_PRI_MIX_PAUSE(bp, + pg_help_data->data[1].pg_priority)) { + /* If one PG contains both pauseable and + * non-pauseable priorities then ETS is disabled. + */ + bnx2x_dcbx_separate_pauseable_from_non(bp, cos_data, + pg_pri_orginal_spread, ets); + bp->dcbx_port_params.ets.enabled = false; + return; + } + + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pauseable. */ + cos_data->data[1].pausable = false; + if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, + pg_help_data->data[0].pg_priority)) { + /* 0 is pauseable */ + cos_data->data[0].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[0] = pg_help_data->data[0].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[1] = pg_help_data->data[1].pg; + } else {/* 1 is pauseable */ + cos_data->data[0].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[0] = pg_help_data->data[1].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[1] = pg_help_data->data[0].pg; + } + } else { + /* If there are only pauseable priorities or + * only non-pauseable, each PG goes to a queue. + */ + cos_data->data[0].pausable = cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + cos_data->data[0].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[0] = pg_help_data->data[0].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[1] = pg_help_data->data[1].pg; + } + + /* There can be only one strict pg */ + for (i = 0 ; i < E2_NUM_OF_COS; i++) { + if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES) + cos_data->data[i].cos_bw = + DCBX_PG_BW_GET(ets->pg_bw_tbl, pg[i]); + else + cos_data->data[i].strict = BNX2X_DCBX_COS_HIGH_STRICT; + } +} + +/******************************************************************************* + * Description: Still + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_three_pg_to_cos_params( + struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct dcbx_ets_feature *ets, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u32 pri_tested = 0; + u8 entry = 0; + u8 pg_entry = 0; + bool b_found_strict = false; + u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX; + + cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0; + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and the + * non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) + bnx2x_dcbx_separate_pauseable_from_non(bp, + cos_data, pg_pri_orginal_spread, ets); + else { + /* If two BW-limited PG-s were combined to one queue, + * the BW is their sum. + * + * If there are only pauseable priorities or only non-pauseable, + * and there are both BW-limited and non-BW-limited PG-s, + * the BW-limited PG/s go to one queue and the non-BW-limited + * PG/s go to the second queue. + * + * If there are only pauseable priorities or only non-pauseable + * and all are BW limited, then two priorities go to the first + * queue and one priority goes to the second queue. + * + * We will join this two cases: + * if one is BW limited it will go to the secoend queue + * otherwise the last priority will get it + */ + + cos_data->data[0].pausable = cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + + for (i = 0 ; i < num_of_pri; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + pg_entry = (u8)pg_pri_orginal_spread[bp-> + dcbx_port_params.app.traffic_type_priority[i]]; + + if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) { + entry = 0; + + if (i == (num_of_pri-1) && + false == b_found_strict) + /* last entry will be handled separately + * If no priority is strict than last + * enty goes to last queue.*/ + entry = 1; + cos_data->data[entry].pri_join_mask |= + pri_tested; + bnx2x_dcbx_add_to_cos_bw(bp, + &cos_data->data[entry], + DCBX_PG_BW_GET(ets->pg_bw_tbl, + pg_entry)); + } else { + b_found_strict = true; + cos_data->data[1].pri_join_mask |= pri_tested; + /* If we join a group and one is strict + * than the bw rulls */ + cos_data->data[1].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + } + } +} + + +static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + u32 *pg_pri_orginal_spread) +{ + struct cos_help_data cos_data ; + u8 i = 0; + u32 pri_join_mask = 0; + u8 num_of_dif_pri = 0; + + memset(&cos_data, 0, sizeof(cos_data)); + /* Validate the pg value */ + for (i = 0; i < help_data->num_of_pg ; i++) { + if (DCBX_STRICT_PRIORITY != help_data->data[i].pg && + DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg) + BNX2X_ERR("Invalid pg[%d] data %x\n", i, + help_data->data[i].pg); + pri_join_mask |= help_data->data[i].pg_priority; + num_of_dif_pri += help_data->data[i].num_of_dif_pri; + } + + /* default settings */ + cos_data.num_of_cos = 2; + for (i = 0; i < E2_NUM_OF_COS ; i++) { + cos_data.data[i].pri_join_mask = pri_join_mask; + cos_data.data[i].pausable = false; + cos_data.data[i].strict = BNX2X_DCBX_COS_NOT_STRICT; + cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW; + } + + switch (help_data->num_of_pg) { + case 1: + + bxn2x_dcbx_single_pg_to_cos_params( + bp, + help_data, + &cos_data, + pri_join_mask, + num_of_dif_pri); + break; + case 2: + bnx2x_dcbx_two_pg_to_cos_params( + bp, + help_data, + ets, + &cos_data, + pg_pri_orginal_spread, + pri_join_mask, + num_of_dif_pri); + break; + + case 3: + bnx2x_dcbx_three_pg_to_cos_params( + bp, + help_data, + ets, + &cos_data, + pg_pri_orginal_spread, + pri_join_mask, + num_of_dif_pri); + + break; + default: + BNX2X_ERR("Wrong pg_help_data.num_of_pg\n"); + bnx2x_dcbx_ets_disabled_entry_data(bp, + &cos_data, pri_join_mask); + } + + for (i = 0; i < cos_data.num_of_cos ; i++) { + struct bnx2x_dcbx_cos_params *params = + &bp->dcbx_port_params.ets.cos_params[i]; + + params->pauseable = cos_data.data[i].pausable; + params->strict = cos_data.data[i].strict; + params->bw_tbl = cos_data.data[i].cos_bw; + if (params->pauseable) { + params->pri_bitmask = + DCBX_PFC_PRI_GET_PAUSE(bp, + cos_data.data[i].pri_join_mask); + DP(NETIF_MSG_LINK, "COS %d PAUSABLE prijoinmask 0x%x\n", + i, cos_data.data[i].pri_join_mask); + } else { + params->pri_bitmask = + DCBX_PFC_PRI_GET_NON_PAUSE(bp, + cos_data.data[i].pri_join_mask); + DP(NETIF_MSG_LINK, "COS %d NONPAUSABLE prijoinmask " + "0x%x\n", + i, cos_data.data[i].pri_join_mask); + } + } + + bp->dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ; +} + +static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, + u32 *set_configuration_ets_pg, + u32 *pri_pg_tbl) +{ + int i; + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) { + set_configuration_ets_pg[i] = DCBX_PRI_PG_GET(pri_pg_tbl, i); + + DP(NETIF_MSG_LINK, "set_configuration_ets_pg[%d] = 0x%x\n", + i, set_configuration_ets_pg[i]); + } +} + +/******************************************************************************* + * Description: Fill pfc_config struct that will be sent in DCBX start ramrod + * + * Return: + ******************************************************************************/ +static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) +{ + struct flow_control_configuration *pfc_fw_cfg = 0; + u16 pri_bit = 0; + u8 cos = 0, pri = 0; + struct priority_cos *tt2cos; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + pfc_fw_cfg = (struct flow_control_configuration *) + bnx2x_sp(bp, pfc_config); + memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration)); + + /*shortcut*/ + tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos; + + /* Fw version should be incremented each update */ + pfc_fw_cfg->dcb_version = ++bp->dcb_version; + pfc_fw_cfg->dcb_enabled = DCB_ENABLED; + + /* Default initialization */ + for (pri = 0; pri < MAX_PFC_TRAFFIC_TYPES ; pri++) { + tt2cos[pri].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; + tt2cos[pri].cos = 0; + } + + /* Fill priority parameters */ + for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) { + tt2cos[pri].priority = ttp[pri]; + pri_bit = 1 << tt2cos[pri].priority; + + /* Fill COS parameters based on COS calculated to + * make it more generally for future use */ + for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++) + if (bp->dcbx_port_params.ets.cos_params[cos]. + pri_bitmask & pri_bit) + tt2cos[pri].cos = cos; + } + bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg); +} diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h new file mode 100644 index 000000000000..8dea56b511f5 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -0,0 +1,193 @@ +/* bnx2x_dcb.h: Broadcom Everest network driver. + * + * Copyright 2009-2010 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein + * Written by: Dmitry Kravkov + * + */ +#ifndef BNX2X_DCB_H +#define BNX2X_DCB_H + +#include "bnx2x_hsi.h" + +#define LLFC_DRIVER_TRAFFIC_TYPE_MAX 3 /* NW, iSCSI, FCoE */ +struct bnx2x_dcbx_app_params { + u32 enabled; + u32 traffic_type_priority[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; +}; + +#define E2_NUM_OF_COS 2 +#define BNX2X_DCBX_COS_NOT_STRICT 0 +#define BNX2X_DCBX_COS_LOW_STRICT 1 +#define BNX2X_DCBX_COS_HIGH_STRICT 2 + +struct bnx2x_dcbx_cos_params { + u32 bw_tbl; + u32 pri_bitmask; + u8 strict; + u8 pauseable; +}; + +struct bnx2x_dcbx_pg_params { + u32 enabled; + u8 num_of_cos; /* valid COS entries */ + struct bnx2x_dcbx_cos_params cos_params[E2_NUM_OF_COS]; +}; + +struct bnx2x_dcbx_pfc_params { + u32 enabled; + u32 priority_non_pauseable_mask; +}; + +struct bnx2x_dcbx_port_params { + u32 dcbx_enabled; + struct bnx2x_dcbx_pfc_params pfc; + struct bnx2x_dcbx_pg_params ets; + struct bnx2x_dcbx_app_params app; +}; + +#define BNX2X_DCBX_CONFIG_INV_VALUE (0xFFFFFFFF) +#define BNX2X_DCBX_OVERWRITE_SETTINGS_DISABLE 0 +#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1 +#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE) + +/******************************************************************************* + * LLDP protocol configuration parameters. + ******************************************************************************/ +struct bnx2x_config_lldp_params { + u32 overwrite_settings; + u32 msg_tx_hold; + u32 msg_fast_tx; + u32 tx_credit_max; + u32 msg_tx_interval; + u32 tx_fast; +}; + +struct bnx2x_admin_priority_app_table { + u32 valid; + u32 priority; +#define INVALID_TRAFFIC_TYPE_PRIORITY (0xFFFFFFFF) + u32 traffic_type; +#define TRAFFIC_TYPE_ETH 0 +#define TRAFFIC_TYPE_PORT 1 + u32 app_id; +}; + +/******************************************************************************* + * DCBX protocol configuration parameters. + ******************************************************************************/ +struct bnx2x_config_dcbx_params { + u32 dcb_enable; + u32 admin_dcbx_enable; + u32 overwrite_settings; + u32 admin_dcbx_version; + u32 admin_ets_enable; + u32 admin_pfc_enable; + u32 admin_tc_supported_tx_enable; + u32 admin_ets_configuration_tx_enable; + u32 admin_ets_recommendation_tx_enable; + u32 admin_pfc_tx_enable; + u32 admin_application_priority_tx_enable; + u32 admin_ets_willing; + u32 admin_ets_reco_valid; + u32 admin_pfc_willing; + u32 admin_app_priority_willing; + u32 admin_configuration_bw_precentage[8]; + u32 admin_configuration_ets_pg[8]; + u32 admin_recommendation_bw_precentage[8]; + u32 admin_recommendation_ets_pg[8]; + u32 admin_pfc_bitmap; + struct bnx2x_admin_priority_app_table admin_priority_app_table[4]; + u32 admin_default_priority; +}; + +#define GET_FLAGS(flags, bits) ((flags) & (bits)) +#define SET_FLAGS(flags, bits) ((flags) |= (bits)) +#define RESET_FLAGS(flags, bits) ((flags) &= ~(bits)) + +enum { + DCBX_READ_LOCAL_MIB, + DCBX_READ_REMOTE_MIB +}; + +#define ETH_TYPE_FCOE (0x8906) +#define TCP_PORT_ISCSI (0xCBC) + +#define PFC_VALUE_FRAME_SIZE (512) +#define PFC_QUANTA_IN_NANOSEC_FROM_SPEED_MEGA(mega_speed) \ + ((1000 * PFC_VALUE_FRAME_SIZE)/(mega_speed)) + +#define PFC_BRB1_REG_HIGH_LLFC_LOW_THRESHOLD 130 +#define PFC_BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD 170 + + + +struct cos_entry_help_data { + u32 pri_join_mask; + u32 cos_bw; + u8 strict; + bool pausable; +}; + +struct cos_help_data { + struct cos_entry_help_data data[E2_NUM_OF_COS]; + u8 num_of_cos; +}; + +#define DCBX_ILLEGAL_PG (0xFF) +#define DCBX_PFC_PRI_MASK (0xFF) +#define DCBX_STRICT_PRIORITY (15) +#define DCBX_INVALID_COS_BW (0xFFFFFFFF) +#define DCBX_PFC_PRI_NON_PAUSE_MASK(bp) \ + ((bp)->dcbx_port_params.pfc.priority_non_pauseable_mask) +#define DCBX_PFC_PRI_PAUSE_MASK(bp) \ + ((u8)~DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) +#define DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri) \ + ((pg_pri) & (DCBX_PFC_PRI_PAUSE_MASK(bp))) +#define DCBX_PFC_PRI_GET_NON_PAUSE(bp, pg_pri) \ + (DCBX_PFC_PRI_NON_PAUSE_MASK(bp) & (pg_pri)) +#define IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pg_pri) \ + (pg_pri == DCBX_PFC_PRI_GET_PAUSE((bp), (pg_pri))) +#define IS_DCBX_PFC_PRI_ONLY_NON_PAUSE(bp, pg_pri)\ + ((pg_pri) == DCBX_PFC_PRI_GET_NON_PAUSE((bp), (pg_pri))) +#define IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pg_pri) \ + (!(IS_DCBX_PFC_PRI_ONLY_NON_PAUSE((bp), (pg_pri)) || \ + IS_DCBX_PFC_PRI_ONLY_PAUSE((bp), (pg_pri)))) + + +struct pg_entry_help_data { + u8 num_of_dif_pri; + u8 pg; + u32 pg_priority; +}; + +struct pg_help_data { + struct pg_entry_help_data data[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; + u8 num_of_pg; +}; + +/* forward DCB/PFC related declarations */ +struct bnx2x; +void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp); +void bnx2x_dcbx_update(struct work_struct *work); +void bnx2x_dcbx_init_params(struct bnx2x *bp); + +enum { + BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1, + BNX2X_DCBX_STATE_TX_PAUSED = 0x2, + BNX2X_DCBX_STATE_TX_RELEASED = 0x4 +}; +void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); + +#endif /* BNX2X_DCB_H */ diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 6555c477f893..ed90ec831fe0 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -684,7 +684,7 @@ struct shm_dev_info { /* size */ #define E1VN_MAX 1 #define E1HVN_MAX 4 - +#define E2_VF_MAX 64 /* This value (in milliseconds) determines the frequency of the driver * issuing the PULSE message code. The firmware monitors this periodic * pulse to determine when to switch to an OS-absent mode. */ @@ -820,6 +820,8 @@ struct drv_func_mb { #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 +#define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 +#define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 #define REQ_BC_VER_4_SET_MF_BW 0x00060202 #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 @@ -905,6 +907,8 @@ struct drv_func_mb { #define DRV_STATUS_DCC_RESERVED1 0x00000800 #define DRV_STATUS_DCC_SET_PROTOCOL 0x00001000 #define DRV_STATUS_DCC_SET_PRIORITY 0x00002000 +#define DRV_STATUS_DCBX_EVENT_MASK 0x000f0000 +#define DRV_STATUS_DCBX_NEGOTIATION_RESULTS 0x00010000 u32 virt_mac_upper; #define VIRT_MAC_SIGN_MASK 0xffff0000 @@ -1089,6 +1093,251 @@ struct fw_flr_mb { struct fw_flr_ack ack; }; +/**** SUPPORT FOR SHMEM ARRRAYS *** + * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to + * define arrays with storage types smaller then unsigned dwords. + * The macros below add generic support for SHMEM arrays with numeric elements + * that can span 2,4,8 or 16 bits. The array underlying type is a 32 bit dword + * array with individual bit-filed elements accessed using shifts and masks. + * + */ + +/* eb is the bitwidth of a single element */ +#define SHMEM_ARRAY_MASK(eb) ((1<<(eb))-1) +#define SHMEM_ARRAY_ENTRY(i, eb) ((i)/(32/(eb))) + +/* the bit-position macro allows the used to flip the order of the arrays + * elements on a per byte or word boundary. + * + * example: an array with 8 entries each 4 bit wide. This array will fit into + * a single dword. The diagrmas below show the array order of the nibbles. + * + * SHMEM_ARRAY_BITPOS(i, 4, 4) defines the stadard ordering: + * + * | | | | + * 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + * | | | | + * + * SHMEM_ARRAY_BITPOS(i, 4, 8) defines a flip ordering per byte: + * + * | | | | + * 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | + * | | | | + * + * SHMEM_ARRAY_BITPOS(i, 4, 16) defines a flip ordering per word: + * + * | | | | + * 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | + * | | | | + */ +#define SHMEM_ARRAY_BITPOS(i, eb, fb) \ + ((((32/(fb)) - 1 - ((i)/((fb)/(eb))) % (32/(fb))) * (fb)) + \ + (((i)%((fb)/(eb))) * (eb))) + +#define SHMEM_ARRAY_GET(a, i, eb, fb) \ + ((a[SHMEM_ARRAY_ENTRY(i, eb)] >> SHMEM_ARRAY_BITPOS(i, eb, fb)) & \ + SHMEM_ARRAY_MASK(eb)) + +#define SHMEM_ARRAY_SET(a, i, eb, fb, val) \ +do { \ + a[SHMEM_ARRAY_ENTRY(i, eb)] &= ~(SHMEM_ARRAY_MASK(eb) << \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ + a[SHMEM_ARRAY_ENTRY(i, eb)] |= (((val) & SHMEM_ARRAY_MASK(eb)) << \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ +} while (0) + + +/****START OF DCBX STRUCTURES DECLARATIONS****/ +#define DCBX_MAX_NUM_PRI_PG_ENTRIES 8 +#define DCBX_PRI_PG_BITWIDTH 4 +#define DCBX_PRI_PG_FBITS 8 +#define DCBX_PRI_PG_GET(a, i) \ + SHMEM_ARRAY_GET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS) +#define DCBX_PRI_PG_SET(a, i, val) \ + SHMEM_ARRAY_SET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS, val) +#define DCBX_MAX_NUM_PG_BW_ENTRIES 8 +#define DCBX_BW_PG_BITWIDTH 8 +#define DCBX_PG_BW_GET(a, i) \ + SHMEM_ARRAY_GET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH) +#define DCBX_PG_BW_SET(a, i, val) \ + SHMEM_ARRAY_SET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH, val) +#define DCBX_STRICT_PRI_PG 15 +#define DCBX_MAX_APP_PROTOCOL 16 +#define FCOE_APP_IDX 0 +#define ISCSI_APP_IDX 1 +#define PREDEFINED_APP_IDX_MAX 2 + +struct dcbx_ets_feature { + u32 enabled; + u32 pg_bw_tbl[2]; + u32 pri_pg_tbl[1]; +}; + +struct dcbx_pfc_feature { +#ifdef __BIG_ENDIAN + u8 pri_en_bitmap; +#define DCBX_PFC_PRI_0 0x01 +#define DCBX_PFC_PRI_1 0x02 +#define DCBX_PFC_PRI_2 0x04 +#define DCBX_PFC_PRI_3 0x08 +#define DCBX_PFC_PRI_4 0x10 +#define DCBX_PFC_PRI_5 0x20 +#define DCBX_PFC_PRI_6 0x40 +#define DCBX_PFC_PRI_7 0x80 + u8 pfc_caps; + u8 reserved; + u8 enabled; +#elif defined(__LITTLE_ENDIAN) + u8 enabled; + u8 reserved; + u8 pfc_caps; + u8 pri_en_bitmap; +#define DCBX_PFC_PRI_0 0x01 +#define DCBX_PFC_PRI_1 0x02 +#define DCBX_PFC_PRI_2 0x04 +#define DCBX_PFC_PRI_3 0x08 +#define DCBX_PFC_PRI_4 0x10 +#define DCBX_PFC_PRI_5 0x20 +#define DCBX_PFC_PRI_6 0x40 +#define DCBX_PFC_PRI_7 0x80 +#endif +}; + +struct dcbx_app_priority_entry { +#ifdef __BIG_ENDIAN + u16 app_id; + u8 pri_bitmap; + u8 appBitfield; +#define DCBX_APP_ENTRY_VALID 0x01 +#define DCBX_APP_ENTRY_SF_MASK 0x30 +#define DCBX_APP_ENTRY_SF_SHIFT 4 +#define DCBX_APP_SF_ETH_TYPE 0x10 +#define DCBX_APP_SF_PORT 0x20 +#elif defined(__LITTLE_ENDIAN) + u8 appBitfield; +#define DCBX_APP_ENTRY_VALID 0x01 +#define DCBX_APP_ENTRY_SF_MASK 0x30 +#define DCBX_APP_ENTRY_SF_SHIFT 4 +#define DCBX_APP_SF_ETH_TYPE 0x10 +#define DCBX_APP_SF_PORT 0x20 + u8 pri_bitmap; + u16 app_id; +#endif +}; + +struct dcbx_app_priority_feature { +#ifdef __BIG_ENDIAN + u8 reserved; + u8 default_pri; + u8 tc_supported; + u8 enabled; +#elif defined(__LITTLE_ENDIAN) + u8 enabled; + u8 tc_supported; + u8 default_pri; + u8 reserved; +#endif + struct dcbx_app_priority_entry app_pri_tbl[DCBX_MAX_APP_PROTOCOL]; +}; + +struct dcbx_features { + struct dcbx_ets_feature ets; + struct dcbx_pfc_feature pfc; + struct dcbx_app_priority_feature app; +}; + +struct lldp_params { +#ifdef __BIG_ENDIAN + u8 msg_fast_tx_interval; + u8 msg_tx_hold; + u8 msg_tx_interval; + u8 admin_status; +#define LLDP_TX_ONLY 0x01 +#define LLDP_RX_ONLY 0x02 +#define LLDP_TX_RX 0x03 +#define LLDP_DISABLED 0x04 + u8 reserved1; + u8 tx_fast; + u8 tx_crd_max; + u8 tx_crd; +#elif defined(__LITTLE_ENDIAN) + u8 admin_status; +#define LLDP_TX_ONLY 0x01 +#define LLDP_RX_ONLY 0x02 +#define LLDP_TX_RX 0x03 +#define LLDP_DISABLED 0x04 + u8 msg_tx_interval; + u8 msg_tx_hold; + u8 msg_fast_tx_interval; + u8 tx_crd; + u8 tx_crd_max; + u8 tx_fast; + u8 reserved1; +#endif +#define REM_CHASSIS_ID_STAT_LEN 4 +#define REM_PORT_ID_STAT_LEN 4 + u32 peer_chassis_id[REM_CHASSIS_ID_STAT_LEN]; + u32 peer_port_id[REM_PORT_ID_STAT_LEN]; +}; + +struct lldp_dcbx_stat { +#define LOCAL_CHASSIS_ID_STAT_LEN 2 +#define LOCAL_PORT_ID_STAT_LEN 2 + u32 local_chassis_id[LOCAL_CHASSIS_ID_STAT_LEN]; + u32 local_port_id[LOCAL_PORT_ID_STAT_LEN]; + u32 num_tx_dcbx_pkts; + u32 num_rx_dcbx_pkts; +}; + +struct lldp_admin_mib { + u32 ver_cfg_flags; +#define DCBX_ETS_CONFIG_TX_ENABLED 0x00000001 +#define DCBX_PFC_CONFIG_TX_ENABLED 0x00000002 +#define DCBX_APP_CONFIG_TX_ENABLED 0x00000004 +#define DCBX_ETS_RECO_TX_ENABLED 0x00000008 +#define DCBX_ETS_RECO_VALID 0x00000010 +#define DCBX_ETS_WILLING 0x00000020 +#define DCBX_PFC_WILLING 0x00000040 +#define DCBX_APP_WILLING 0x00000080 +#define DCBX_VERSION_CEE 0x00000100 +#define DCBX_VERSION_IEEE 0x00000200 +#define DCBX_DCBX_ENABLED 0x00000400 +#define DCBX_CEE_VERSION_MASK 0x0000f000 +#define DCBX_CEE_VERSION_SHIFT 12 +#define DCBX_CEE_MAX_VERSION_MASK 0x000f0000 +#define DCBX_CEE_MAX_VERSION_SHIFT 16 + struct dcbx_features features; +}; + +struct lldp_remote_mib { + u32 prefix_seq_num; + u32 flags; +#define DCBX_ETS_TLV_RX 0x00000001 +#define DCBX_PFC_TLV_RX 0x00000002 +#define DCBX_APP_TLV_RX 0x00000004 +#define DCBX_ETS_RX_ERROR 0x00000010 +#define DCBX_PFC_RX_ERROR 0x00000020 +#define DCBX_APP_RX_ERROR 0x00000040 +#define DCBX_ETS_REM_WILLING 0x00000100 +#define DCBX_PFC_REM_WILLING 0x00000200 +#define DCBX_APP_REM_WILLING 0x00000400 +#define DCBX_REMOTE_ETS_RECO_VALID 0x00001000 + struct dcbx_features features; + u32 suffix_seq_num; +}; + +struct lldp_local_mib { + u32 prefix_seq_num; + u32 error; +#define DCBX_LOCAL_ETS_ERROR 0x00000001 +#define DCBX_LOCAL_PFC_ERROR 0x00000002 +#define DCBX_LOCAL_APP_ERROR 0x00000004 +#define DCBX_LOCAL_PFC_MISMATCH 0x00000010 +#define DCBX_LOCAL_APP_MISMATCH 0x00000020 + struct dcbx_features features; + u32 suffix_seq_num; +}; +/***END OF DCBX STRUCTURES DECLARATIONS***/ struct shmem2_region { @@ -1112,7 +1361,12 @@ struct shmem2_region { #define SHMEM_MF_CFG_ADDR_NONE 0x00000000 struct fw_flr_mb flr_mb; - u32 reserved[3]; + u32 dcbx_lldp_params_offset; +#define SHMEM_LLDP_DCBX_PARAMS_NONE 0x00000000 + u32 dcbx_neg_res_offset; +#define SHMEM_DCBX_NEG_RES_NONE 0x00000000 + u32 dcbx_remote_mib_offset; +#define SHMEM_DCBX_REMOTE_MIB_NONE 0x00000000 /* * The other shmemX_base_addr holds the other path's shmem address * required for example in case of common phy init, or for path1 to know @@ -1121,6 +1375,10 @@ struct shmem2_region { */ u32 other_shmem_base_addr; u32 other_shmem2_base_addr; + u32 reserved1[E2_VF_MAX / 32]; + u32 reserved2[E2_FUNC_MAX][E2_VF_MAX / 32]; + u32 dcbx_lldp_dcbx_stat_offset; +#define SHMEM_LLDP_DCBX_STAT_NONE 0x00000000 }; @@ -3022,6 +3280,25 @@ struct fairness_vars_per_vn { }; +/* + * The data for flow control configuration + */ +struct flow_control_configuration { + struct priority_cos + traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 dcb_version; + u8 dcb_enabled; +#elif defined(__LITTLE_ENDIAN) + u8 dcb_enabled; + u8 dcb_version; + u16 reserved1; +#endif + u32 reserved2; +}; + + /* * FW version stored in the Xstorm RAM */ diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 171abf8097ee..149f84258d8b 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -216,6 +216,7 @@ struct link_params { u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) +#define FEATURE_CONFIG_PFC_ENABLED (1<<1) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) /* Will be populated during common init */ @@ -332,4 +333,43 @@ u8 bnx2x_phy_probe(struct link_params *params); u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 port); +/* PFC port configuration params */ +struct bnx2x_nig_brb_pfc_port_params { + /* NIG */ + u32 pause_enable; + u32 llfc_out_en; + u32 llfc_enable; + u32 pkt_priority_to_cos; + u32 rx_cos0_priority_mask; + u32 rx_cos1_priority_mask; + u32 llfc_high_priority_classes; + u32 llfc_low_priority_classes; + /* BRB */ + u32 cos0_pauseable; + u32 cos1_pauseable; +}; + +/** + * Used to update the PFC attributes in EMAC, BMAC, NIG and BRB + * when link is already up + */ +void bnx2x_update_pfc(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params); + + +/* Used to configure the ETS to disable */ +void bnx2x_ets_disabled(struct link_params *params); + +/* Used to configure the ETS to BW limited */ +void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, + const u32 cos1_bw); + +/* Used to configure the ETS to strict */ +u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); + +/* Read pfc statistic*/ +void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 563b2cb8e544..bdc3fc26b31a 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -55,6 +55,7 @@ #include "bnx2x_init.h" #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" +#include "bnx2x_dcb.h" #include #include "bnx2x_fw_file_hdr.h" @@ -3105,6 +3106,11 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) bnx2x_pmf_update(bp); + if (bp->port.pmf && + (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS)) + /* start dcbx state machine */ + bnx2x_dcbx_set_params(bp, + BNX2X_DCBX_STATE_NEG_RECEIVED); } else if (attn & BNX2X_MC_ASSERT_BITS) { BNX2X_ERR("MC assert!\n"); @@ -3724,6 +3730,15 @@ static void bnx2x_eq_int(struct bnx2x *bp) BNX2X_FP_STATE_CLOSED; goto next_spqe; + + case EVENT_RING_OPCODE_STOP_TRAFFIC: + DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); + goto next_spqe; + case EVENT_RING_OPCODE_START_TRAFFIC: + DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); + goto next_spqe; } switch (opcode | bp->state) { @@ -4363,6 +4378,7 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) static void bnx2x_init_internal_port(struct bnx2x *bp) { /* port */ + bnx2x_dcb_init_intmem_pfc(bp); } static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) @@ -5488,8 +5504,10 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) * - SF mode: bits 3-7 are masked. only bits 0-2 are in use * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF * bits 4-7 are used for "per vn group attention" */ - REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_MF(bp) ? 0xF7 : 0x7)); + val = IS_MF(bp) ? 0xF7 : 0x7; + /* Enable DCBX attention for all but E1 */ + val |= CHIP_IS_E1(bp) ? 0 : 0x10; + REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val); bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); @@ -8775,6 +8793,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2x_timer; + bnx2x_dcbx_init_params(bp); + return rc; } -- cgit v1.2.3-59-g8ed1b From bcab15c5d780bafb38311f00fcb263d03d2b00f1 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:25 +0000 Subject: bnx2x: Add DCB/PFC support - link layer Add appropriate HW DCB/PFC configuration Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 665 ++++++++++++++++++++++++++++++++++++++--- drivers/net/bnx2x/bnx2x_link.h | 16 + drivers/net/bnx2x/bnx2x_reg.h | 47 +++ 3 files changed, 689 insertions(+), 39 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 38aeffef2a83..97cbee2927fc 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -164,7 +164,8 @@ #define EDC_MODE_PASSIVE_DAC 0x0055 - +#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000) +#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000) /**********************************************************/ /* INTERFACE */ /**********************************************************/ @@ -205,6 +206,273 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) return val; } +/******************************************************************/ +/* ETS section */ +/******************************************************************/ +void bnx2x_ets_disabled(struct link_params *params) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + + DP(NETIF_MSG_LINK, "ETS disabled configuration\n"); + + /** + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) + * 3bits client num. + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000 + */ + + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - + * COS0 entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); + /* defines which entries (clients) are subjected to WFQ arbitration */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); + /** + * For strict priority entries defines the number of consecutive + * slots for the highest priority. + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /** + * mapping between the CREDIT_WEIGHT registers and actual client + * numbers + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0); + REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0); + /* ETS mode disable */ + REG_WR(bp, PBF_REG_ETS_ENABLED, 0); + /** + * If ETS mode is enabled (there is no strict priority) defines a WFQ + * weight for COS0/COS1. + */ + REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710); + REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710); + /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */ + REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680); + REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680); + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); +} + +void bnx2x_ets_bw_limit_common(const struct link_params *params) +{ + /* ETS disabled configuration */ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); + /** + * defines which entries (clients) are subjected to WFQ arbitration + * COS0 0x8 + * COS1 0x10 + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18); + /** + * mapping between the ARB_CREDIT_WEIGHT registers and actual + * client numbers (WEIGHT_0 does not actually have to represent + * client 0) + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010 + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + + /* ETS mode enabled*/ + REG_WR(bp, PBF_REG_ETS_ENABLED, 1); + + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0 + * entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); + + /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/ + REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); +} + +void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, + const u32 cos1_bw) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + const u32 total_bw = cos0_bw + cos1_bw; + u32 cos0_credit_weight = 0; + u32 cos1_credit_weight = 0; + + DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); + + if ((0 == total_bw) || + (0 == cos0_bw) || + (0 == cos1_bw)) { + DP(NETIF_MSG_LINK, + "bnx2x_ets_bw_limit: Total BW can't be zero\n"); + return; + } + + cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ + total_bw; + cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ + total_bw; + + bnx2x_ets_bw_limit_common(params); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight); + + REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight); + REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight); +} + +u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + u32 val = 0; + + if ((1 < strict_cos) && (NULL == params)) + return -EINVAL; + + DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n"); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, + * 3 - COS0 entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F); + /** + * For strict priority entries defines the number of consecutive slots + * for the highest priority. + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /* ETS mode disable */ + REG_WR(bp, PBF_REG_ETS_ENABLED, 0); + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100); + + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos); + + /** + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) + * 3bits client num. + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000 + * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000 + */ + val = (0 == strict_cos) ? 0x2318 : 0x22E0; + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val); + + return 0; +} +/******************************************************************/ +/* ETS section */ +/******************************************************************/ + +static void bnx2x_bmac2_get_pfc_stat(struct link_params *params, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + + DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n"); + + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP, + pfc_frames_sent, 2); + + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP, + pfc_frames_received, 2); + +} +static void bnx2x_emac_get_pfc_stat(struct link_params *params, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 val_xon = 0; + u32 val_xoff = 0; + + DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n"); + + /* PFC received frames */ + val_xoff = REG_RD(bp, emac_base + + EMAC_REG_RX_PFC_STATS_XOFF_RCVD); + val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT; + val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD); + val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT; + + pfc_frames_received[0] = val_xon + val_xoff; + + /* PFC received sent */ + val_xoff = REG_RD(bp, emac_base + + EMAC_REG_RX_PFC_STATS_XOFF_SENT); + val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT; + val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT); + val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT; + + pfc_frames_sent[0] = val_xon + val_xoff; +} + +void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 val = 0; + DP(NETIF_MSG_LINK, "pfc statistic\n"); + + if (!vars->link_up) + return; + + val = REG_RD(bp, MISC_REG_RESET_REG_2); + if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + == 0) { + DP(NETIF_MSG_LINK, "About to read stats from EMAC\n"); + bnx2x_emac_get_pfc_stat(params, pfc_frames_sent, + pfc_frames_received); + } else { + DP(NETIF_MSG_LINK, "About to read stats from BMAC\n"); + bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent, + pfc_frames_received); + } +} +/******************************************************************/ +/* MAC/PBF section */ +/******************************************************************/ static void bnx2x_emac_init(struct link_params *params, struct link_vars *vars) { @@ -315,24 +583,55 @@ static u8 bnx2x_emac_enable(struct link_params *params, /* pause enable/disable */ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, EMAC_RX_MODE_FLOW_EN); - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - bnx2x_bits_en(bp, emac_base + - EMAC_REG_EMAC_RX_MODE, - EMAC_RX_MODE_FLOW_EN); bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, - (EMAC_TX_MODE_EXT_PAUSE_EN | - EMAC_TX_MODE_FLOW_EN)); - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - bnx2x_bits_en(bp, emac_base + - EMAC_REG_EMAC_TX_MODE, - (EMAC_TX_MODE_EXT_PAUSE_EN | - EMAC_TX_MODE_FLOW_EN)); + (EMAC_TX_MODE_EXT_PAUSE_EN | + EMAC_TX_MODE_FLOW_EN)); + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) { + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + bnx2x_bits_en(bp, emac_base + + EMAC_REG_EMAC_RX_MODE, + EMAC_RX_MODE_FLOW_EN); + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + bnx2x_bits_en(bp, emac_base + + EMAC_REG_EMAC_TX_MODE, + (EMAC_TX_MODE_EXT_PAUSE_EN | + EMAC_TX_MODE_FLOW_EN)); + } else + bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, + EMAC_TX_MODE_FLOW_EN); } /* KEEP_VLAN_TAG, promiscuous */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; + + /** + * Setting this bit causes MAC control frames (except for pause + * frames) to be passed on for processing. This setting has no + * affect on the operation of the pause frames. This bit effects + * all packets regardless of RX Parser packet sorting logic. + * Turn the PFC off to make sure we are in Xon state before + * enabling it. + */ + EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0); + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { + DP(NETIF_MSG_LINK, "PFC is enabled\n"); + /* Enable PFC again */ + EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, + EMAC_REG_RX_PFC_MODE_RX_EN | + EMAC_REG_RX_PFC_MODE_TX_EN | + EMAC_REG_RX_PFC_MODE_PRIORITIES); + + EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM, + ((0x0101 << + EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) | + (0x00ff << + EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT))); + val |= EMAC_RX_MODE_KEEP_MAC_CONTROL; + } EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); /* Set Loopback */ @@ -362,7 +661,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, /* enable the NIG in/out to the emac */ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); val = 0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val = 1; REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); @@ -383,9 +684,38 @@ static u8 bnx2x_emac_enable(struct link_params *params, return 0; } -static void bnx2x_update_bmac2(struct link_params *params, - struct link_vars *vars, - u8 is_lb) +static void bnx2x_update_pfc_bmac1(struct link_params *params, + struct link_vars *vars) +{ + u32 wb_data[2]; + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + + u32 val = 0x14; + if ((!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) + /* Enable BigMAC to react on received Pause packets */ + val |= (1<<5); + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2); + + /* tx control */ + val = 0xc0; + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) + val |= 0x800000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2); +} + +static void bnx2x_update_pfc_bmac2(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { /* * Set rx control: Strip CRC and enable BigMAC to relay @@ -397,7 +727,9 @@ static void bnx2x_update_bmac2(struct link_params *params, NIG_REG_INGRESS_BMAC0_MEM; u32 val = 0x14; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + if ((!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) /* Enable BigMAC to react on received Pause packets */ val |= (1<<5); wb_data[0] = val; @@ -408,14 +740,47 @@ static void bnx2x_update_bmac2(struct link_params *params, /* Tx control */ val = 0xc0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val |= 0x800000; wb_data[0] = val; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2); + + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { + DP(NETIF_MSG_LINK, "PFC is enabled\n"); + /* Enable PFC RX & TX & STATS and set 8 COS */ + wb_data[0] = 0x0; + wb_data[0] |= (1<<0); /* RX */ + wb_data[0] |= (1<<1); /* TX */ + wb_data[0] |= (1<<2); /* Force initial Xon */ + wb_data[0] |= (1<<3); /* 8 cos */ + wb_data[0] |= (1<<5); /* STATS */ + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, + wb_data, 2); + /* Clear the force Xon */ + wb_data[0] &= ~(1<<2); + } else { + DP(NETIF_MSG_LINK, "PFC is disabled\n"); + /* disable PFC RX & TX & STATS and set 8 COS */ + wb_data[0] = 0x8; + wb_data[1] = 0; + } + + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2); + /** + * Set Time (based unit is 512 bit time) between automatic + * re-sending of PP packets amd enable automatic re-send of + * Per-Priroity Packet as long as pp_gen is asserted and + * pp_disable is low. + */ val = 0x8000; + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) + val |= (1<<16); /* enable automatic re-send */ + wb_data[0] = val; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, @@ -427,6 +792,9 @@ static void bnx2x_update_bmac2(struct link_params *params, val |= 0x4; /* Local loopback */ DP(NETIF_MSG_LINK, "enable bmac loopback\n"); } + /* When PFC enabled, Pass pause frames towards the NIG. */ + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) + val |= ((1<<6)|(1<<5)); wb_data[0] = val; wb_data[1] = 0; @@ -434,6 +802,239 @@ static void bnx2x_update_bmac2(struct link_params *params, wb_data, 2); } +static void bnx2x_update_pfc_brb(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params) +{ + struct bnx2x *bp = params->bp; + int set_pfc = params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED; + + /* default - pause configuration */ + u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; + u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; + u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; + u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; + + if (set_pfc && pfc_params) + /* First COS */ + if (!pfc_params->cos0_pauseable) { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; + } + /* The number of free blocks below which the pause signal to class 0 + of MAC #n is asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th); + /* The number of free blocks above which the pause signal to class 0 + of MAC #n is de-asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th); + /* The number of free blocks below which the full signal to class 0 + of MAC #n is asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th); + /* The number of free blocks above which the full signal to class 0 + of MAC #n is de-asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th); + + if (set_pfc && pfc_params) { + /* Second COS */ + if (pfc_params->cos1_pauseable) { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; + } else { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; + } + /** + * The number of free blocks below which the pause signal to + * class 1 of MAC #n is asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th); + /** + * The number of free blocks above which the pause signal to + * class 1 of MAC #n is de-asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th); + /** + * The number of free blocks below which the full signal to + * class 1 of MAC #n is asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th); + /** + * The number of free blocks above which the full signal to + * class 1 of MAC #n is de-asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th); + } +} + +static void bnx2x_update_pfc_nig(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *nig_params) +{ + u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0; + u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0; + u32 pkt_priority_to_cos = 0; + u32 val; + struct bnx2x *bp = params->bp; + int port = params->port; + int set_pfc = params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED; + DP(NETIF_MSG_LINK, "updating pfc nig parameters\n"); + + /** + * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set + * MAC control frames (that are not pause packets) + * will be forwarded to the XCM. + */ + xcm_mask = REG_RD(bp, + port ? NIG_REG_LLH1_XCM_MASK : + NIG_REG_LLH0_XCM_MASK); + /** + * nig params will override non PFC params, since it's possible to + * do transition from PFC to SAFC + */ + if (set_pfc) { + pause_enable = 0; + llfc_out_en = 0; + llfc_enable = 0; + ppp_enable = 1; + xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : + NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); + xcm0_out_en = 0; + p0_hwpfc_enable = 1; + } else { + if (nig_params) { + llfc_out_en = nig_params->llfc_out_en; + llfc_enable = nig_params->llfc_enable; + pause_enable = nig_params->pause_enable; + } else /*defaul non PFC mode - PAUSE */ + pause_enable = 1; + + xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : + NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); + xcm0_out_en = 1; + } + + REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 : + NIG_REG_LLFC_OUT_EN_0, llfc_out_en); + REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 : + NIG_REG_LLFC_ENABLE_0, llfc_enable); + REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 : + NIG_REG_PAUSE_ENABLE_0, pause_enable); + + REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 : + NIG_REG_PPP_ENABLE_0, ppp_enable); + + REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK : + NIG_REG_LLH0_XCM_MASK, xcm_mask); + + REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7); + + /* output enable for RX_XCM # IF */ + REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en); + + /* HW PFC TX enable */ + REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable); + + /* 0x2 = BMAC, 0x1= EMAC */ + switch (vars->mac_type) { + case MAC_TYPE_EMAC: + val = 1; + break; + case MAC_TYPE_BMAC: + val = 0; + break; + default: + val = 0; + break; + } + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val); + + if (nig_params) { + pkt_priority_to_cos = nig_params->pkt_priority_to_cos; + + REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK : + NIG_REG_P0_RX_COS0_PRIORITY_MASK, + nig_params->rx_cos0_priority_mask); + + REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK : + NIG_REG_P0_RX_COS1_PRIORITY_MASK, + nig_params->rx_cos1_priority_mask); + + REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 : + NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0, + nig_params->llfc_high_priority_classes); + + REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 : + NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0, + nig_params->llfc_low_priority_classes); + } + REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS : + NIG_REG_P0_PKT_PRIORITY_TO_COS, + pkt_priority_to_cos); +} + + +void bnx2x_update_pfc(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params) +{ + /** + * The PFC and pause are orthogonal to one another, meaning when + * PFC is enabled, the pause are disabled, and when PFC is + * disabled, pause are set according to the pause result. + */ + u32 val; + struct bnx2x *bp = params->bp; + + /* update NIG params */ + bnx2x_update_pfc_nig(params, vars, pfc_params); + + /* update BRB params */ + bnx2x_update_pfc_brb(params, vars, pfc_params); + + if (!vars->link_up) + return; + + val = REG_RD(bp, MISC_REG_RESET_REG_2); + if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + == 0) { + DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); + bnx2x_emac_enable(params, vars, 0); + return; + } + + DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); + if (CHIP_IS_E2(bp)) + bnx2x_update_pfc_bmac2(params, vars, 0); + else + bnx2x_update_pfc_bmac1(params, vars); + + val = 0; + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) + val = 1; + REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); +} static u8 bnx2x_bmac1_enable(struct link_params *params, struct link_vars *vars, @@ -465,15 +1066,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2); - /* tx control */ - val = 0xc0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - val |= 0x800000; - wb_data[0] = val; - wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, - wb_data, 2); - /* mac control */ val = 0x3; if (is_lb) { @@ -491,14 +1083,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2); - /* rx control set to don't strip crc */ - val = 0x14; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - val |= 0x20; - wb_data[0] = val; - wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, - wb_data, 2); + bnx2x_update_pfc_bmac1(params, vars); /* set tx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; @@ -595,7 +1180,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2); udelay(30); - bnx2x_update_bmac2(params, vars, is_lb); + bnx2x_update_pfc_bmac2(params, vars, is_lb); return 0; } @@ -627,7 +1212,9 @@ static u8 bnx2x_bmac_enable(struct link_params *params, REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); val = 0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val = 1; REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 149f84258d8b..bedab1a942c4 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -65,6 +65,22 @@ #define FW_PARAM_MDIO_CTRL_OFFSET 16 #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) + +#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE 170 +#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE 0 + +#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE 250 +#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE 0 + +#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE 10 +#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE 90 + +#define PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE 50 +#define PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE 250 + +#define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170 +#define PFC_BRB_FULL_LB_XON_THRESHOLD 250 + /***********************************************************/ /* Structs */ /***********************************************************/ diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 64bdda189e5a..bfd875b72906 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1615,6 +1615,8 @@ #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) +#define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0) +#define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) @@ -1744,12 +1746,16 @@ ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same port */ #define NIG_REG_LLFC_ENABLE_0 0x16208 +#define NIG_REG_LLFC_ENABLE_1 0x1620c /* [RW 16] classes are high-priority for port0 */ #define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058 +#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 0x1605c /* [RW 16] classes are low-priority for port0 */ #define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060 +#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 0x16064 /* [RW 1] Output enable of message to LLFC BMAC IF for port0 */ #define NIG_REG_LLFC_OUT_EN_0 0x160c8 +#define NIG_REG_LLFC_OUT_EN_1 0x160cc #define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c #define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154 #define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244 @@ -1912,11 +1918,17 @@ ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ #define NIG_REG_PAUSE_ENABLE_0 0x160c0 +#define NIG_REG_PAUSE_ENABLE_1 0x160c4 /* [RW 1] Input enable for RX PBF LP IF */ #define NIG_REG_PBF_LB_IN_EN 0x100b4 /* [RW 1] Value of this register will be transmitted to port swap when ~nig_registers_strap_override.strap_override =1 */ #define NIG_REG_PORT_SWAP 0x10394 +/* [RW 1] PPP enable for port0. This register may get 1 only when + * ~safc_enable.safc_enable = 0 and pause_enable.pause_enable =0 for the + * same port */ +#define NIG_REG_PPP_ENABLE_0 0x160b0 +#define NIG_REG_PPP_ENABLE_1 0x160b4 /* [RW 1] output enable for RX parser descriptor IF */ #define NIG_REG_PRS_EOP_OUT_EN 0x10104 /* [RW 1] Input enable for RX parser request IF */ @@ -1983,6 +1995,14 @@ #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 +/* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter. */ +#define PBF_REG_COS0_UPPER_BOUND 0x15c05c +/* [RW 31] The weight of COS0 in the ETS command arbiter. */ +#define PBF_REG_COS0_WEIGHT 0x15c054 +/* [RW 31] The upper bound of the weight of COS1 in the ETS command arbiter. */ +#define PBF_REG_COS1_UPPER_BOUND 0x15c060 +/* [RW 31] The weight of COS1 in the ETS command arbiter. */ +#define PBF_REG_COS1_WEIGHT 0x15c058 /* [RW 1] Disable processing further tasks from port 0 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c @@ -1993,9 +2013,16 @@ current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c #define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 1] Indicates that ETS is performed between the COSes in the command + * arbiter. If reset strict priority w/ anti-starvation will be performed + * w/o WFQ. */ +#define PBF_REG_ETS_ENABLED 0x15c050 /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 +/* [RW 1] Indicates which COS is conncted to the highest priority in the + * command arbiter. */ +#define PBF_REG_HIGH_PRIORITY_COS_NUM 0x15c04c #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after @@ -2021,6 +2048,10 @@ #define PBF_REG_MAC_LB_ENABLE 0x140040 /* [RW 6] Bit-map indicating which headers must appear in the packet */ #define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 +/* [RW 16] The number of strict priority arbitration slots between 2 RR + * arbitration slots. A value of 0 means no strict priority cycles; i.e. the + * strict-priority w/ anti-starvation arbiter is a RR arbiter. */ +#define PBF_REG_NUM_STRICT_ARB_SLOTS 0x15c064 /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause not suppoterd. */ #define PBF_REG_P0_ARB_THRSH 0x1400e4 @@ -4975,7 +5006,23 @@ #define EMAC_REG_EMAC_TX_MODE 0xbc #define EMAC_REG_EMAC_TX_STAT_AC 0x280 #define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22 +#define EMAC_REG_RX_PFC_MODE 0x320 +#define EMAC_REG_RX_PFC_MODE_PRIORITIES (1L<<2) +#define EMAC_REG_RX_PFC_MODE_RX_EN (1L<<1) +#define EMAC_REG_RX_PFC_MODE_TX_EN (1L<<0) +#define EMAC_REG_RX_PFC_PARAM 0x324 +#define EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT 0 +#define EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT 16 +#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD 0x328 +#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XOFF_SENT 0x330 +#define EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XON_RCVD 0x32c +#define EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XON_SENT 0x334 +#define EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT (0xffff<<0) #define EMAC_RX_MODE_FLOW_EN (1L<<2) +#define EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) #define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) #define EMAC_RX_MODE_PROMISCUOUS (1L<<8) #define EMAC_RX_MODE_RESET (1L<<0) -- cgit v1.2.3-59-g8ed1b From 40392d4e49c29bf5e939803d804dc8c7b600f297 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 22:28:42 +0200 Subject: bnx2x: add FW 6.2.5 files Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex | 9483 ++++++++++++++++++ firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex | 13181 ++++++++++++++++++++++++ firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex | 15456 +++++++++++++++++++++++++++++ 3 files changed, 38120 insertions(+) create mode 100644 firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex diff --git a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex new file mode 100644 index 000000000000..1b535827a742 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex @@ -0,0 +1,9483 @@ +:1000000000003BB0000000680000070C00003C202E +:1000100000001AF8000043300000007C00005E3051 +:1000200000007A2C00005EB0000000B00000D8E0B4 +:10003000000080200000D99800000088000159C00D +:100040000000398800015A5000000090000193E040 +:100050000000ABFC0001947800000FFC0002407827 +:100060000000000400025078020400480000000F65 +:100070000204005400000045020400580000000083 +:100080000204005C0000000602040070000000048E +:1000900002040078000000000204007C1217000037 +:1000A00002040080221700000204008432170000BE +:1000B00006040088000000050204009C12150000E0 +:1000C000020400A022150000020400A43215000062 +:1000D000060400A800000004020400B8021000009A +:1000E000020400BC00100000020400C01010000058 +:1000F000020400C420100000020400C830100000F8 +:10010000060400CC00000004020400DC0010000023 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000060400EC00000004A1 +:100130000104012400000000010401280000000067 +:100140000104012C00000000010401300000000047 +:1001500002040004000000FF02040008000000FF89 +:100160000204000C000000FF02040010000000FF69 +:1001700002040014000000FF02040018000000FF49 +:100180000204001C000000FF02040020000000FF29 +:10019000020400240000003E0204002800000000C9 +:1001A0000204002C0000003F020400300000003F69 +:1001B000020400340000003F020400380000000088 +:1001C0000204003C0000003F020400400000003F29 +:1001D000020400440000003F020420080000021155 +:1001E0000204200C0000020002042010000002049F +:1001F00002042014000002190204201C0000FFFF6A +:10020000020420200000FFFF020420240000FFFF62 +:10021000020420280000FFFF0604203800000080B0 +:100220000204223807FFFFFF0204223C0000003FC7 +:100230000204224007FFFFFF020422440000000FD7 +:1002400001042248000000000104224C00000000CC +:1002500001042250000000000104225400000000AC +:1002600001042258000000000104225C000000008C +:10027000010422600000000001042264000000006C +:1002800001042268000000000104226C000000004C +:10029000010422700000000001042274000000002C +:1002A00001042278000000000104227C000000000C +:1002B000020424BC000000010C042000000003E83C +:1002C0000A042000000000010B0420000000000AC6 +:1002D0000605400000000D0002050044000000205B +:1002E00002050048000000320205009002150020BF +:1002F000020500940215002002050098000000305D +:100300000205009C08100000020500A00000003358 +:10031000020500A400000030020500A80000003122 +:10032000020500AC00000002020500B0000000055C +:10033000020500B400000006020500B8000000023B +:10034000020500BC00000002020500C00000000021 +:10035000020500C400000005020500C800000002FC +:10036000020500CC00000002020500D000000002DF +:10037000020500D400000001020501140000000184 +:100380000205011C0000000102050120000000021E +:1003900002050204000000010205020C00000040FA +:1003A00002050210000000400205021C00000020AF +:1003B00002050220000000130205022400000020B4 +:1003C000060502400000000A04050280002000002B +:1003D000020500500000000702050054000000075D +:1003E00002050058000000000205005C0000000843 +:1003F0000605006000000004020500D800000006A9 +:10040000020500E00000000D020500E40000002DE0 +:10041000020500E800000000020500EC00000020DA +:10042000020500F000000000020500F400000020BA +:10043000020500F800000000020500FC000000209A +:100440000205000400000001020500080000000190 +:100450000205000C00000001020500100000000170 +:100460000205001400000001020500180000000150 +:100470000205001C00000001020500200000000130 +:100480000205002400000001020500280000000110 +:100490000205002C000000010205003000000001F0 +:1004A00002050034000000010205003800000001D0 +:1004B0000205003C000000010205004000000001B0 +:1004C0000406100002000020020600DC000000010B +:1004D000010600D80000000004060200000302200C +:1004E000020600DC0000000002060068000000B800 +:1004F0000206007800000114010600B800000000A8 +:10050000010600C8000000000206006C000000B8F0 +:100510000206007C00000114010600BC000000007F +:10052000010600CC0000000007180400007B00005A +:100530000818076000140223071C00002A040000AA +:10054000071C800032110A82071D00001E0C1707CD +:10055000081D4550575602250118000000000000F4 +:10056000011800040000000001180008000000004D +:100570000118000C0000000001180010000000002D +:100580000118001400000000021800200000000103 +:1005900002180024000000020218002800000003D6 +:1005A0000218002C000000000218003000000004B7 +:1005B000021800340000000102180038000000009A +:1005C0000218003C00000001021800400000000476 +:1005D000021800440000000002180048000000015A +:1005E0000218004C00000003021800500000000038 +:1005F0000218005400000001021800580000000416 +:100600000218005C000000000218006000000001F9 +:1006100002180064000000030218006800000000D7 +:100620000218006C000000010218007000000004B5 +:100630000218007400000000021800780000000496 +:100640000218007C00000003061800800000000271 +:10065000021800A400003FFF021800A8000003FFDA +:1006600002180224000000000218023400000000FA +:100670000218024C00000000021802E4000000FF13 +:100680000618100000000400021B8BC000000001CF +:10069000021B800000000034021B80400000001894 +:1006A000021B80800000000C021B80C000000020A4 +:1006B0000C1B83000007A1200A1B830000000138E7 +:1006C0000B1B8300000013880A1B834000000000FE +:1006D0000C1B8340000001F40B1B8340000000054D +:1006E000021B83800007A120021B83C0000001F4CD +:1006F000061A100000000273041A19CC0001022728 +:10070000061A2008000000C8061A20000000000297 +:10071000041A499800040228061A2E280000000234 +:10072000061A2E2000000002061A0800000000022F +:10073000061A080800000004061A08180000000243 +:10074000041A08B00002022C061A2FD0000000067E +:10075000041A2FE80002022E041A2FC000040230EF +:10076000041A300000010234061A300400000003AD +:10077000041A301000010235061A3014000000037C +:10078000041A302000010236061A3024000000034B +:10079000041A303000010237061A3034000000031A +:1007A000041A304000010238061A304400000003E9 +:1007B000041A305000010239061A305400000003B8 +:1007C000041A30600001023A061A30640000000387 +:1007D000041A30700001023B061A30740000000356 +:1007E000041A30800001023C061A30840000000325 +:1007F000041A30900001023D061A309400000003F4 +:10080000041A30A00001023E061A30A400000003C2 +:10081000041A30B00001023F061A30B40000000391 +:10082000041A30C000010240061A30C40000000360 +:10083000041A30D000010241061A30D4000000032F +:10084000041A30E000010242061A30E400000003FE +:10085000041A30F000010243061A30F400000003CD +:10086000041A310000010244061A3104000000039A +:10087000041A311000010245061A31140000000369 +:10088000041A312000010246061A31240000000338 +:10089000041A313000010247061A31340000000307 +:1008A000041A314000010248061A314400000003D6 +:1008B000041A315000010249061A315400000003A5 +:1008C000041A31600001024A061A31640000000374 +:1008D000041A31700001024B061A31740000000343 +:1008E000041A31800001024C061A31840000000312 +:1008F000041A31900001024D061A319400000003E1 +:10090000041A31A00001024E061A31A400000003AF +:10091000041A31B00001024F061A31B4000000037E +:10092000041A31C000010250061A31C4000000034D +:10093000041A31D000010251061A31D4000000031C +:10094000041A31E000010252061A31E400000003EB +:10095000041A31F000010253061A31F400000003BA +:10096000041A320000010254061A32040000000387 +:10097000041A321000010255061A32140000000356 +:10098000041A322000010256061A32240000000325 +:10099000041A323000010257061A323400000003F4 +:1009A000041A324000010258061A324400000003C3 +:1009B000041A325000010259061A32540000000392 +:1009C000041A32600001025A061A32640000000361 +:1009D000041A32700001025B061A32740000000330 +:1009E000041A32800001025C061A328400000003FF +:1009F000041A32900001025D061A329400000003CE +:100A0000041A32A00001025E061A32A4000000039C +:100A1000041A32B00001025F061A32B4000000036B +:100A2000041A32C000010260061A32C4000000033A +:100A3000041A32D000010261061A32D40000000309 +:100A4000041A32E000010262061A32E400000003D8 +:100A5000041A32F000010263061A32F400000003A7 +:100A6000041A330000010264061A33040000000374 +:100A7000041A331000010265061A33140000000343 +:100A8000041A332000010266061A33240000000312 +:100A9000041A333000010267061A333400000003E1 +:100AA000041A334000010268061A334400000003B0 +:100AB000041A335000010269061A3354000000037F +:100AC000041A33600001026A061A3364000000034E +:100AD000041A33700001026B061A3374000000031D +:100AE000041A33800001026C061A338400000003EC +:100AF000041A33900001026D061A339400000003BB +:100B0000041A33A00001026E061A33A40000000389 +:100B1000041A33B00001026F061A33B40000000358 +:100B2000041A33C000010270061A33C40000000327 +:100B3000041A33D000010271061A33D400000003F6 +:100B4000041A33E000010272061A33E400000003C5 +:100B5000041A33F000010273061A33F40000000394 +:100B6000041A340000010274061A34040000000361 +:100B7000041A341000010275061A34140000000330 +:100B8000041A342000010276061A342400000003FF +:100B9000041A343000010277061A343400000003CE +:100BA000041A344000010278061A3444000000039D +:100BB000041A345000010279061A3454000000036C +:100BC000041A34600001027A061A3464000000033B +:100BD000041A34700001027B061A3474000000030A +:100BE000041A34800001027C061A348400000003D9 +:100BF000041A34900001027D061A349400000003A8 +:100C0000041A34A00001027E061A34A40000000376 +:100C1000041A34B00001027F061A34B40000000345 +:100C2000041A34C000010280061A34C40000000314 +:100C3000041A34D000010281061A34D400000003E3 +:100C4000041A34E000010282061A34E400000003B2 +:100C5000041A34F000010283061A34F40000000381 +:100C6000041A350000010284061A3504000000034E +:100C7000041A351000010285061A3514000000031D +:100C8000041A352000010286061A352400000003EC +:100C9000041A353000010287061A353400000003BB +:100CA000041A354000010288061A3544000000038A +:100CB000041A355000010289061A35540000000359 +:100CC000041A35600001028A061A35640000000328 +:100CD000041A35700001028B061A357400000003F7 +:100CE000041A35800001028C061A358400000003C6 +:100CF000041A35900001028D061A35940000000395 +:100D0000041A35A00001028E061A35A40000000363 +:100D1000041A35B00001028F061A35B40000000332 +:100D2000041A35C000010290061A35C40000000301 +:100D3000041A35D000010291061A35D400000003D0 +:100D4000041A35E000010292061A35E4000000039F +:100D5000041A35F000010293061A35F4000000036E +:100D6000041A360000010294061A3604000000033B +:100D7000041A361000010295061A3614000000030A +:100D8000041A362000010296061A362400000003D9 +:100D9000041A363000010297061A363400000003A8 +:100DA000041A364000010298061A36440000000377 +:100DB000041A365000010299061A36540000000346 +:100DC000041A36600001029A061A36640000000315 +:100DD000041A36700001029B061A367400000003E4 +:100DE000041A36800001029C061A368400000003B3 +:100DF000041A36900001029D061A36940000000382 +:100E0000041A36A00001029E061A36A40000000350 +:100E1000041A36B00001029F061A36B4000000031F +:100E2000041A36C0000102A0061A36C400000003EE +:100E3000041A36D0000102A1061A36D400000003BD +:100E4000041A36E0000102A2061A36E4000000038C +:100E5000041A36F0000102A3061A36F4000000035B +:100E6000041A3700000102A4061A37040000000328 +:100E7000041A3710000102A5061A371400000003F7 +:100E8000041A3720000102A6061A372400000003C6 +:100E9000041A3730000102A7061A37340000000395 +:100EA000041A3740000102A8061A37440000000364 +:100EB000041A3750000102A9061A37540000000333 +:100EC000041A3760000102AA061A37640000000302 +:100ED000041A3770000102AB061A377400000003D1 +:100EE000041A3780000102AC061A378400000003A0 +:100EF000041A3790000102AD061A3794000000036F +:100F0000041A37A0000102AE061A37A4000000033D +:100F1000041A37B0000102AF061A37B4000000030C +:100F2000041A37C0000102B0061A37C400000003DB +:100F3000041A37D0000102B1061A37D400000003AA +:100F4000041A37E0000102B2061A37E40000000379 +:100F5000041A37F0000102B3061A37F40000000348 +:100F6000041A3800000102B4061A38040000000315 +:100F7000041A3810000102B5061A381400000003E4 +:100F8000041A3820000102B6061A382400000003B3 +:100F9000041A3830000102B7061A38340000000382 +:100FA000041A3840000102B8061A38440000000351 +:100FB000041A3850000102B9061A38540000000320 +:100FC000041A3860000102BA061A386400000003EF +:100FD000041A3870000102BB061A387400000003BE +:100FE000041A3880000102BC061A3884000000038D +:100FF000041A3890000102BD061A3894000000035C +:10100000041A38A0000102BE061A38A4000000032A +:10101000041A38B0000102BF061A38B400000003F9 +:10102000041A38C0000102C0061A38C400000003C8 +:10103000041A38D0000102C1061A38D40000000397 +:10104000041A38E0000102C2061A38E40000000366 +:10105000041A38F0000102C3061A38F40000000335 +:10106000041A3900000102C4061A39040000000302 +:10107000041A3910000102C5061A391400000003D1 +:10108000041A3920000102C6061A392400000003A0 +:10109000041A3930000102C7061A3934000000036F +:1010A000041A3940000102C8061A3944000000033E +:1010B000041A3950000102C9061A3954000000030D +:1010C000041A3960000102CA061A396400000003DC +:1010D000041A3970000102CB061A397400000003AB +:1010E000041A3980000102CC061A3984000000037A +:1010F000041A3990000102CD061A39940000000349 +:10110000041A39A0000102CE061A39A40000000317 +:10111000041A39B0000102CF061A39B400000003E6 +:10112000041A39C0000102D0061A39C400000003B5 +:10113000041A39D0000102D1061A39D40000000384 +:10114000041A39E0000102D2061A39E40000000353 +:10115000041A39F0000102D3061A39F40000000322 +:10116000041A3A00000102D4061A3A0400000003EF +:10117000041A3A10000102D5061A3A1400000003BE +:10118000041A3A20000102D6061A3A24000000038D +:10119000041A3A30000102D7061A3A34000000035C +:1011A000041A3A40000102D8061A3A44000000032B +:1011B000041A3A50000102D9061A3A5400000003FA +:1011C000041A3A60000102DA061A3A6400000003C9 +:1011D000041A3A70000102DB061A3A740000000398 +:1011E000041A3A80000102DC061A3A840000000367 +:1011F000041A3A90000102DD061A3A940000000336 +:10120000041A3AA0000102DE061A3AA40000000304 +:10121000041A3AB0000102DF061A3AB400000003D3 +:10122000041A3AC0000102E0061A3AC400000003A2 +:10123000041A3AD0000102E1061A3AD40000000371 +:10124000041A3AE0000102E2061A3AE40000000340 +:10125000041A3AF0000102E3061A3AF4000000030F +:10126000041A3B00000102E4061A3B0400000003DC +:10127000041A3B10000102E5061A3B1400000003AB +:10128000041A3B20000102E6061A3B24000000037A +:10129000041A3B30000102E7061A3B340000000349 +:1012A000041A3B40000102E8061A3B440000000318 +:1012B000041A3B50000102E9061A3B5400000003E7 +:1012C000041A3B60000102EA061A3B6400000003B6 +:1012D000041A3B70000102EB061A3B740000000385 +:1012E000041A3B80000102EC061A3B840000000354 +:1012F000041A3B90000102ED061A3B940000000323 +:10130000041A3BA0000102EE061A3BA400000003F1 +:10131000041A3BB0000102EF061A3BB400000003C0 +:10132000041A3BC0000102F0061A3BC4000000038F +:10133000041A3BD0000102F1061A3BD4000000035E +:10134000041A3BE0000102F2061A3BE4000000032D +:10135000041A3BF0000102F3061A3BF400000003FC +:10136000041A3C00000102F4061A3C0400000003C9 +:10137000041A3C10000102F5061A3C140000000398 +:10138000041A3C20000102F6061A3C240000000367 +:10139000041A3C30000102F7061A3C340000000336 +:1013A000041A3C40000102F8061A3C440000000305 +:1013B000041A3C50000102F9061A3C5400000003D4 +:1013C000041A3C60000102FA061A3C6400000003A3 +:1013D000041A3C70000102FB061A3C740000000372 +:1013E000041A3C80000102FC061A3C840000000341 +:1013F000041A3C90000102FD061A3C940000000310 +:10140000041A3CA0000102FE061A3CA400000003DE +:10141000041A3CB0000102FF061A3CB400000003AD +:10142000041A3CC000010300061A3CC4000000037B +:10143000041A3CD000010301061A3CD4000000034A +:10144000041A3CE000010302061A3CE40000000319 +:10145000041A3CF000010303061A3CF400000003E8 +:10146000041A3D0000010304061A3D0400000003B5 +:10147000041A3D1000010305061A3D140000000384 +:10148000041A3D2000010306061A3D240000000353 +:10149000041A3D3000010307061A3D340000000322 +:1014A000041A3D4000010308061A3D4400000003F1 +:1014B000041A3D5000010309061A3D5400000003C0 +:1014C000041A3D600001030A061A3D64000000038F +:1014D000041A3D700001030B061A3D74000000035E +:1014E000041A3D800001030C061A3D84000000032D +:1014F000041A3D900001030D061A3D9400000003FC +:10150000041A3DA00001030E061A3DA400000003CA +:10151000041A3DB00001030F061A3DB40000000399 +:10152000041A3DC000010310061A3DC40000000368 +:10153000041A3DD000010311061A3DD40000000337 +:10154000041A3DE000010312061A3DE40000000306 +:10155000041A3DF000010313061A3DF400000003D5 +:10156000041A3E0000010314061A3E0400000003A2 +:10157000041A3E1000010315061A3E140000000371 +:10158000041A3E2000010316061A3E240000000340 +:10159000041A3E3000010317061A3E34000000030F +:1015A000041A3E4000010318061A3E4400000003DE +:1015B000041A3E5000010319061A3E5400000003AD +:1015C000041A3E600001031A061A3E64000000037C +:1015D000041A3E700001031B061A3E74000000034B +:1015E000041A3E800001031C061A3E84000000031A +:1015F000041A3E900001031D061A3E9400000003E9 +:10160000041A3EA00001031E061A3EA400000003B7 +:10161000041A3EB00001031F061A3EB40000000386 +:10162000041A3EC000010320061A3EC40000000355 +:10163000041A3ED000010321061A3ED40000000324 +:10164000041A3EE000010322061A3EE400000003F3 +:10165000041A3EF000010323061A3EF400000003C2 +:10166000041A3F0000010324061A3F04000000038F +:10167000041A3F1000010325061A3F14000000035E +:10168000041A3F2000010326061A3F24000000032D +:10169000041A3F3000010327061A3F3400000003FC +:1016A000041A3F4000010328061A3F4400000003CB +:1016B000041A3F5000010329061A3F54000000039A +:1016C000041A3F600001032A061A3F640000000369 +:1016D000041A3F700001032B061A3F740000000338 +:1016E000041A3F800001032C061A3F840000000307 +:1016F000041A3F900001032D061A3F9400000003D6 +:10170000041A3FA00001032E061A3FA400000003A4 +:10171000041A3FB00001032F061A3FB40000000373 +:10172000041A3FC000010330061A3FC40000000342 +:10173000041A3FD000010331061A3FD40000000311 +:10174000041A3FE000010332061A3FE400000007DC +:10175000041A4CB000080333061A400000000124AC +:10176000021A492000000000061A2500000000109F +:10177000061A258000000012061A09C00000004861 +:10178000061A080000000002061A082000000012D5 +:10179000041A2FB00002033B041A4CF00002033D70 +:1017A000061A500000000004061A449000000124AC +:1017B000021A492400000000061A2540000000100B +:1017C000061A25C800000012061A0AE000000048A8 +:1017D000061A081000000002061A0868000000122D +:1017E000041A2FB80002033F041A4CF80002034108 +:1017F000061A5010000000040200A468000AFFDC72 +:101800000200A280000000010200A294071D29111D +:101810000200A298000000000200A29C009C042488 +:101820000200A2A0000000000200A2A40000020921 +:101830000200A4FCFF000000020100B4000000014F +:10184000020100B800000001020100DC00000001FC +:10185000020101000000000102010104000000017A +:101860000201007C0030000002010084000000281A +:101870000201008C000000000201013000000004A1 +:101880000201025C000000010201032800000000C8 +:101890000201055400000030020100C400000001F4 +:1018A000020100CC00000001020100F8000000016C +:1018B000020100F000000001020100800030000081 +:1018C00002010088000000280201009000000000D2 +:1018D0000201013400000004020102DC00000001EA +:1018E0000201032C0000000002010564000000302A +:1018F000020100C800000001020100D00000000148 +:10190000020100FC00000001020100F400000001DF +:10191000020C100000000028020C200800000A1130 +:10192000020C200C00000A00020C201000000A0427 +:10193000020C201C0000FFFF020C20200000FFFF13 +:10194000020C20240000FFFF020C20280000FFFFF3 +:10195000020C203800000020020C203C0000002176 +:10196000020C204000000022020C20440000002352 +:10197000020C204800000024020C204C000000252E +:10198000020C205000000026020C2054000000270A +:10199000020C205800000028020C205C00000029E6 +:1019A000020C20600000002A020C20640000002BC2 +:1019B000020C20680000002C020C206C0000002D9E +:1019C000020C20700000002E020C20740000002F7A +:1019D000020C207800000010060C207C0000004F54 +:1019E000020C21B800000001020C21BC0000000123 +:1019F000020C21C000000001020C21C40000000103 +:101A0000020C21C800000001020C21CC00000001E2 +:101A1000020C21D000000001020C21D400000001C2 +:101A2000020C21D800000001020C21DC00000001A2 +:101A3000020C21E000000001020C21E40000000182 +:101A4000020C21E800000001020C21EC0000000162 +:101A5000020C21F000000001020C21F40000000142 +:101A6000020C21F800000001060C21FC0000000F10 +:101A7000020C223807FFFFFF020C223C0000003F4F +:101A8000020C224007FFFFFF020C22440000000F5F +:101A9000010C224800000000010C224C0000000054 +:101AA000010C225000000000010C22540000000034 +:101AB000010C225800000000010C225C0000000014 +:101AC000010C226000000000010C226400000000F4 +:101AD000010C226800000000010C226C00000000D4 +:101AE000010C227000000000010C227400000000B4 +:101AF000010C227800000000010C227C0000000094 +:101B0000020C24BC000000010C0C2000000003E8C3 +:101B10000A0C2000000000010B0C20000000000A4D +:101B2000020C400800000562020C400C0000055148 +:101B3000020C401000000555020C40140000057214 +:101B4000020C401C0000FFFF020C40200000FFFFC1 +:101B5000020C40240000FFFF020C40280000FFFFA1 +:101B6000020C403800000046020C403C0000000C13 +:101B7000060C40400000005E020C41B8000000016D +:101B8000060C41BC0000001F020C423807FFFFFF9B +:101B9000020C423C0000003F020C424007FFFFFFE6 +:101BA000020C42440000000F010C424800000000FB +:101BB000010C424C00000000010C425000000000EB +:101BC000010C425400000000010C425800000000CB +:101BD000010C425C00000000010C426000000000AB +:101BE000010C426400000000010C4268000000008B +:101BF000010C426C00000000010C4270000000006B +:101C0000010C427400000000010C4278000000004A +:101C1000010C427C00000000010C4280000000002A +:101C2000020C44C0000000010C0C4000000003E85E +:101C30000A0C4000000000010B0C40000000000AEC +:101C4000060D400000000A00020D004400000032B2 +:101C5000020D008C02150020020D009002150020DC +:101C6000020D009408100000020D009800000033DF +:101C7000020D009C00000002020D00A00000000008 +:101C8000020D00A400000005020D00A800000005E0 +:101C9000060D00AC00000002020D00B400000002BE +:101CA000020D00B800000003020D00BC000000029D +:101CB000020D00C000000001020D00C8000000027B +:101CC000020D00CC00000002020D015C00000001CA +:101CD000020D016400000001020D01680000000215 +:101CE000020D020400000001020D020C00000020A1 +:101CF000020D021000000040020D0214000000401E +:101D0000020D022000000003020D02240000001852 +:101D1000060D028000000012040D030000180343AA +:101D2000060D03600000000C020D004C00000001D5 +:101D3000020D005000000002020D005400000000DF +:101D4000020D005800000008060D005C00000004B1 +:101D5000020D00C400000004020D0114000000097F +:101D6000020D011800000029020D011C0000000AEC +:101D7000020D01200000002A020D012400000000D5 +:101D8000020D012800000020020D012C00000000BF +:101D9000020D013000000020020D0134000000009F +:101DA000020D013800000020020D013C000000007F +:101DB000020D014000000020020D0144000000005F +:101DC000020D014800000020020D00040000000187 +:101DD000020D000800000001020D000C00000001CF +:101DE000020D001000000001020D001400000001AF +:101DF000020D001800000001020D001C000000018F +:101E0000020D002000000001020D0024000000016E +:101E1000020D002800000001020D002C000000014E +:101E2000020D003000000001020D0034000000012E +:101E3000020D003800000001020D003C000000010E +:101E4000060E200000000800020E004C00000032C8 +:101E5000020E009402150020020E009802150020C8 +:101E6000020E009C00000030020E00A008100000CE +:101E7000020E00A400000033020E00A80000003093 +:101E8000020E00AC00000031020E00B000000002A3 +:101E9000020E00B400000004020E00B800000000B2 +:101EA000020E00BC00000002020E00C00000000292 +:101EB000020E00C400000000020E00C80000000274 +:101EC000020E00CC00000007020E00D0000000024D +:101ED000020E00D400000002020E00D80000000133 +:101EE000020E014400000001020E014C000000013E +:101EF000020E015000000002020E02040000000168 +:101F0000020E020C00000040020E02100000004011 +:101F1000020E021C00000004020E0220000000203D +:101F2000020E02240000000E020E02280000001B18 +:101F3000060E030000000012040E0280001B035B6B +:101F4000060E02EC00000005020E00540000000C1A +:101F5000020E00580000000C020E005C00000000A1 +:101F6000020E006000000010060E00640000000475 +:101F7000020E00DC00000003020E01100000000F42 +:101F8000020E01140000002F020E011800000000D4 +:101F9000020E011C00000020020E000400000001DF +:101FA000020E000800000001020E000C00000001FB +:101FB000020E001000000001020E001400000001DB +:101FC000020E001800000001020E001C00000001BB +:101FD000020E002000000001020E0024000000019B +:101FE000020E002800000001020E002C000000017B +:101FF000020E003000000001020E0034000000015B +:10200000020E003800000001020E003C000000013A +:10201000020E004000000001020E0044000000011A +:102020000730040000AF0000083007680013037693 +:1020300007340000331C00000734800032780CC8DD +:10204000073500001A801967083539B058CA037877 +:10205000013000000000000001300004000000001A +:1020600001300008000000000130000C00000000FA +:1020700001300010000000000130001400000000DA +:1020800002300020000000010230002400000002A5 +:1020900002300028000000030230002C0000000085 +:1020A0000230003000000004023000340000000163 +:1020B00002300038000000000230003C0000000147 +:1020C0000230004000000004023000440000000024 +:1020D00002300048000000010230004C0000000304 +:1020E00002300050000000000230005400000001E7 +:1020F00002300058000000040230005C00000000C4 +:1021000002300060000000010230006400000003A3 +:1021100002300068000000000230006C0000000186 +:102120000230007000000004023000740000000063 +:1021300002300078000000040230007C0000000340 +:102140000630008000000002023000A400003FFFC3 +:10215000023000A8000003FF02300224000000004B +:1021600002300234000000000230024C0000000087 +:10217000023002E40000FFFF0630200000000800EB +:1021800002338BC000000001023380000000001AFF +:10219000023380400000004E0233808000000010B7 +:1021A000023380C0000000200C3383000007A12010 +:1021B0000A338300000001380B33830000001388CA +:1021C0000A338340000000000C338340000001F418 +:1021D0000B33834000000005023383800007A120F9 +:1021E000023383C0000001F406322A88000000C2D6 +:1021F00006322008000000C806322000000000025D +:10220000063223E80000004004322E580004037A0E +:10221000063250A000000004063250B80000000250 +:102220000632508000000006043250980002037EFF +:10223000063250000000002006323000000004008A +:1022400006321C0000000004043218300002038033 +:10225000063224E8000000B402322DB00000000075 +:1022600006324000000000B40632300000000020BA +:10227000063231000000002006323200000000204B +:102280000632330000000020063234000000002037 +:102290000632350000000020063236000000002023 +:1022A000063237000000002006323800000000200F +:1022B000063239000000002006323A0000000020FB +:1022C00006323B000000002006323C0000000020E7 +:1022D00006323D000000002006323E0000000020D3 +:1022E00006323F000000002006321C1000000002F1 +:1022F000063245A000000024063227B8000000B4D2 +:1023000002322DB400000000063242D0000000B4BA +:1023100006323080000000200632318000000020AC +:102320000632328000000020063233800000002098 +:102330000632348000000020063235800000002084 +:102340000632368000000020063237800000002070 +:10235000063238800000002006323980000000205C +:1023600006323A800000002006323B800000002048 +:1023700006323C800000002006323D800000002034 +:1023800006323E800000002006323F800000002020 +:1023900006321C20000000020632463000000024F5 +:1023A0000720040000870000082007800010038237 +:1023B000072400003165000007248000081D0C5A26 +:1023C00008248EB06C9003840120000000000000FF +:1023D00001200004000000000120000800000000AF +:1023E0000120000C0000000001200010000000008F +:1023F0000120001400000000022000200000000165 +:102400000220002400000002022000280000000337 +:102410000220002C00000000022000300000000418 +:1024200002200034000000010220003800000000FB +:102430000220003C000000010220004000000004D7 +:1024400002200044000000000220004800000001BB +:102450000220004C00000003022000500000000099 +:102460000220005400000001022000580000000477 +:102470000220005C0000000002200060000000015B +:102480000220006400000003022000680000000039 +:102490000220006C00000001022000700000000417 +:1024A00002200074000000000220007800000004F8 +:1024B0000220007C000000030620008000000002D3 +:1024C000022000A400003FFF022000A8000003FF3C +:1024D000022002240000000002200234000000005C +:1024E0000220024C00000000022002E40000FFFF76 +:1024F000062020000000080002238BC0000000011D +:10250000022380000000001002238040000000121F +:102510000223808000000030022380C00000000EF3 +:102520000C2383000007A1200A2383000000013848 +:102530000B238300000013880A238340000000005F +:102540000C238340000001F40B23834000000005AE +:10255000022383800007A120022383C0000001F42E +:10256000062250000000004206222008000000C899 +:10257000062220000000000206224000000000C6E3 +:1025800004224318000503860622432C0000000B9A +:10259000042243580005038B0622436C0000000B05 +:1025A0000422439800050390062243AC0000000B70 +:1025B000042243D800050395062243EC0000000BDB +:1025C000042244180005039A0622442C0000000B44 +:1025D000042244580005039F0622446C0000000BAF +:1025E00004224498000503A4062244AC0000000B1A +:1025F000042244D8000503A9062244EC0000000B85 +:1026000004224518000503AE0622452C0000000BED +:1026100004224558000503B30622456C0000000B58 +:1026200004224598000503B8062245AC0000000BC3 +:10263000042245D8000503BD062245EC0000000B2E +:1026400004224618000503C20622462C0000000B97 +:1026500004224658000503C70622466C0000000B02 +:1026600004224698000503CC062246AC0000000B6D +:10267000042246D8000503D1062246EC0000000BD8 +:1026800004224718000503D60622472C0000000B41 +:1026900004224758000503DB0622476C0000000BAC +:1026A00004224798000503E0062247AC0000000B17 +:1026B000042247D8000503E5062247EC0000000B82 +:1026C00004224818000503EA0622482C0000000BEB +:1026D00004224858000503EF0622486C0000000B56 +:1026E00004224898000503F4062248AC0000000BC1 +:1026F000042248D8000503F9062248EC0000000B2C +:1027000004224918000503FE0622492C0000000B94 +:1027100004224958000504030622496C0000000BFE +:102720000422499800050408062249AC0000000B69 +:10273000042249D80005040D062249EC0000000BD4 +:1027400004224A180005041206224A2C0000000B3D +:1027500004224A580005041706224A6C0000000BA8 +:1027600004224A980005041C06224AAC0000000B13 +:1027700004224AD80005042106224AEC0000000584 +:1027800006224B000000001704224B5C00010426C7 +:1027900006224B600000000304224B6C000104275A +:1027A000062238000000004006223000000002002F +:1027B000042251C00004042806221000000000C0BA +:1027C000062215C00000024004221EC80008042C86 +:1027D0000622390000000008022251180000000003 +:1027E000062251D00000000606221300000000025D +:1027F00006221410000000300622392000000008D4 +:102800000222511C00000000062251E800000006D0 +:102810000622130800000002062214D00000003037 +:102820000216100000000028021700080000000235 +:102830000217002C000000030217003C00000004F7 +:1028400002170044000000000217004800000002C8 +:102850000217004C0000009002170050000000908A +:102860000217005400800090021700580810000062 +:10287000021700600000008A021700640000008058 +:1028800002170068000000810217006C0000008041 +:10289000021700700000000602170078000007D041 +:1028A0000217007C0000076C02170038007C10043F +:1028B000021700040000000F06164024000000026A +:1028C000021640700000001C0216420800000001C1 +:1028D0000216421000000001021642200000000112 +:1028E00002164228000000010216423000000001DA +:1028F000021642380000000102164260000000018A +:102900000C16401C0003D0900A16401C0000009CCE +:102910000B16401C000009C40216403000000008DD +:10292000021640340000000C02164038000000106F +:102930000216404400000020021640000000000182 +:10294000021640D8000000010216400800000001F5 +:102950000216400C000000010216401000000001A9 +:10296000021642400000000002164248000000002B +:1029700006164270000000020216425000000000DD +:1029800002164258000000000616428000000002B5 +:1029900002166008000006140216600C0000060013 +:1029A00002166010000006040216601C0000FFFF03 +:1029B000021660200000FFFF021660240000FFFFE7 +:1029C000021660280000FFFF021660380000002099 +:1029D0000216603C00000020061660400000000265 +:1029E00002166048000000230216604C000000241C +:1029F00002166050000000250216605400000026F8 +:102A000002166058000000270216605C00000029D2 +:102A1000021660600000002A021660640000002BAD +:102A2000021660680000002C0216606C0000002D89 +:102A30000616607000000012021660B80000000167 +:102A4000021660BC00000001061660C00000003ED7 +:102A5000021661B800000001061661BC0000001FEC +:102A60000216623807FFFFFF0216623C0000003FBB +:102A70000216624007FFFFFF021662440000000FCB +:102A800001166248000000000116624C00000000C0 +:102A900001166250000000000116625400000000A0 +:102AA00001166258000000000116625C0000000080 +:102AB0000116626000000000011662640000000060 +:102AC00001166268000000000116626C0000000040 +:102AD0000116627000000000011662740000000020 +:102AE00001166278000000000116627C0000000000 +:102AF000021664BC000000010C166000000003E830 +:102B00000A166000000000010B1660000000000AB9 +:102B100002168040000000060216804400000005F6 +:102B2000021680480000000A0216804C00000005D2 +:102B30000216805400000002021680CC000000043F +:102B4000021680D000000004021680D400000004A9 +:102B5000021680D800000004021680DC0000000489 +:102B6000021680E000000004021680E40000000469 +:102B7000021680E800000004021688040000000429 +:102B8000021680300000007C021680340000003DF8 +:102B9000021680380000003F0216803C0000009CB6 +:102BA000021680F000000007061680F40000000501 +:102BB0000216880C010101010216810800000000C4 +:102BC0000216810C000000040216811000000004AF +:102BD0000216811400000002021688100801200469 +:102BE00002168118000000050216811C0000000575 +:102BF0000216812000000005021681240000000555 +:102C00000216882C200810010216812800000008F6 +:102C10000216812C00000006021681300000000719 +:102C200002168134000000000216883001010120E4 +:102C300006168138000000040216883401010101E3 +:102C400006168148000000040216883801010101BF +:102C500006168158000000040216883C010101019B +:102C6000061681680000000302168174000000014E +:102C7000021688400101010102168178000000015E +:102C80000216817C00000001021681800000000114 +:102C9000021681840000000102168844010101012E +:102CA00002168188000000010216818C00000004D9 +:102CB00002168190000000040216819400000002B8 +:102CC00002168848080120040216819800000005B9 +:102CD0000216819C00000005021681A0000000057C +:102CE000021681A4000000050216881420081001B5 +:102CF000021681A800000008021681AC0000000640 +:102D0000021681B000000007021681B40000000125 +:102D10000216881801010120021681B80000000186 +:102D2000021681BC00000001021681C000000001F3 +:102D3000021681C4000000010216881C0101010175 +:102D4000021681C800000001021681CC00000001BB +:102D5000021681D000000001021681D4000000019B +:102D60000216882001010101021681D8000000012D +:102D7000021681DC00000001021681E00000000163 +:102D8000021681E4000000010216882401010101FD +:102D9000021681E800000001021681EC000000012B +:102DA000021681F0000000010216882801010101CD +:102DB00002168240FFFF003F061682440000000218 +:102DC0000216824CFFFF003F0216825000000100F5 +:102DD000021682540000010006168258000000020C +:102DE00002168260000000C002168264000000C06B +:102DF0000216826800001E000216826C00001E008F +:102E0000021682700000400002168274000040002A +:102E100002168278000080000216827C000080008A +:102E2000021682800000200002168284000020002A +:102E30000616828800000007021682A40000000126 +:102E4000061682A80000000A021681F400000C0891 +:102E5000021681F800000040021681FC000001000B +:102E600002168200000000200216820400000017F3 +:102E700002168208000000800216820C0000020088 +:102E8000021682100000000002168218FFFF01FFE8 +:102E900002168214FFFF01FF0216823C000000139D +:102EA000021680900000013F021680600000014081 +:102EB00002168064000001400616806800000002CF +:102EC00002168070000000C0061680740000000723 +:102ED0000216809C00000048021680A000000048F6 +:102EE000061680A400000002021680AC0000004814 +:102EF000061680B00000000702168238000080002D +:102F000002168234000025E40216809400007FFF40 +:102F100002168220000000070216821C0000000733 +:102F2000021682280000000002168224FFFFFFFF25 +:102F300002168230000000000216822CFFFFFFFF05 +:102F4000021680EC000000FF0214000000000001E7 +:102F50000214000C000000010214004000000001F7 +:102F60000214004400007FFF0214000C0000000067 +:102F700002140000000000000214006C00000000B9 +:102F800002140004000000010214003000000001DF +:102F900002140004000000000214005C00000000A5 +:102FA00002140008000000010214003400000001B7 +:102FB000021400080000000002140060000000007D +:102FC00006028000000020000202005800000032CB +:102FD000020200A003150020020200A40315002035 +:102FE000020200A801000030020200AC081000003C +:102FF000020200B000000033020200B40000003002 +:10300000020200B800000031020200BC0000000310 +:10301000020200C000000006020200C4000000031B +:10302000020200C800000003020200CC00000002FF +:10303000020200D000000000020200D400000002E2 +:10304000020200DC00000000020200E000000006B6 +:10305000020200E400000004020200E80000000296 +:10306000020200EC00000002020200F00000000179 +:10307000020200FC00000006020201200000000025 +:103080000202013400000002020201B0000000014F +:103090000202020C00000001020202140000000102 +:1030A00002020218000000020202040400000001F3 +:1030B0000202040C00000040020204100000004064 +:1030C0000202041C00000004020204200000002090 +:1030D0000202042400000002020204280000001F73 +:1030E00006020500000000120402048000200434DF +:1030F000020200600000000F0202006400000007EE +:1031000002020068000000000202006C0000000ED5 +:103110000602007000000004020200F40000000437 +:103120000202000400000001020200080000000189 +:103130000202000C00000001020200100000000169 +:103140000202001400000001020200180000000149 +:103150000202001C00000001020200200000000129 +:103160000202002400000001020200280000000109 +:103170000202002C000000010202003000000001E9 +:1031800002020034000000010202003800000001C9 +:103190000202003C000000010202004000000001A9 +:1031A0000202004400000001020200480000000189 +:1031B0000202004C00000001020200500000000169 +:1031C00002020108000000C802020118000000020B +:1031D000020201C400000000020201CC0000000055 +:1031E000020201D400000002020201DC0000000221 +:1031F000020201E4000000FF020201EC000000FFF7 +:103200000202010C000000C80202011C00000002C2 +:10321000020201C800000000020201D0000000000C +:10322000020201D800000002020201E000000002D8 +:10323000020201E8000000FF020201F0000000FFAE +:1032400007280400008D00000828076800130454B4 +:10325000072C000034090000072C800038990D036A +:10326000072D0000390C1B2A072D80000641296E0E +:10327000082D8AB04EAA0456012800000000000064 +:1032800001280004000000000128000800000000E0 +:103290000128000C000000000128001000000000C0 +:1032A0000128001400000000022800200000000196 +:1032B0000228002400000002022800280000000369 +:1032C0000228002C0000000002280030000000044A +:1032D000022800340000000102280038000000002D +:1032E0000228003C00000001022800400000000409 +:1032F00002280044000000000228004800000001ED +:103300000228004C000000030228005000000000CA +:1033100002280054000000010228005800000004A8 +:103320000228005C0000000002280060000000018C +:10333000022800640000000302280068000000006A +:103340000228006C00000001022800700000000448 +:103350000228007400000000022800780000000429 +:103360000228007C00000003062800800000000204 +:10337000022800A400003FFF022800A8000003FF6D +:10338000022802240000000002280234000000008D +:103390000228024C00000000022802E40000FFFFA7 +:1033A0000628200000000800022B8BC0000000014E +:1033B000022B800000000000022B8040000000185B +:1033C000022B80800000000C022B80C000000066F1 +:1033D0000C2B83000007A1200A2B8300000001387A +:1033E0000B2B8300000013880A2B83400000000091 +:1033F0000C2B8340000001F40B2B834000000005E0 +:10340000022B83800007A120022B83C0000001F45F +:10341000062A3D4800000004042A3D5800020458D2 +:10342000062A3D6000000006062A30000000004821 +:10343000062A2008000000C8062A2000000000021A +:10344000062A31280000008E062A33680000000397 +:10345000042A33740001045A062A3A780000000254 +:10346000042A3A800002045B042A3A700002045DD8 +:10347000042A3E280002045F042A3EB000040461CE +:10348000042A250000020465062A25080000010020 +:10349000062A297000000004042A29600004046739 +:1034A000042A2F480002046B062A3378000000D853 +:1034B000022A3A3800000000062A3A88000000324A +:1034C000042A3D880010046D062A502000000002E6 +:1034D000062A503000000002062A500000000002B8 +:1034E000062A501000000002022A50B80000000115 +:1034F000062A50480000000E042A3D780002047D90 +:10350000062A3C1800000026022A50400000000055 +:10351000062A36D8000000D8022A3A3C00000000F3 +:10352000062A3B5000000032042A3DC80010047FE8 +:10353000062A502800000002062A50380000000227 +:10354000062A500800000002062A50180000000257 +:10355000022A50BC00000001062A50800000000E24 +:10356000042A3D800002048F062A3CB00000002699 +:10357000022A504400000000021010080000000160 +:103580000210101000000264021010000003D000AE +:10359000021010040000003D091018000200049100 +:1035A00009101100001006910610114000000008DB +:1035B00009101160000806A1061011800000000229 +:1035C00009101188000606A9061011A000000018B5 +:1035D000021010100000000006102400000000E09F +:1035E0000210201C0000000002102020000000013A +:1035F000021020C0000000010210200400000001A1 +:10360000021020080000000109103C00000506AF70 +:1036100009103C20000506B409103800000506B961 +:1036200002104028000000100210404400003FFF3C +:103630000210405800280000021040840084924A82 +:1036400006104C000000010002104058000000006D +:103650000610806800000004021080000000108046 +:1036600006108028000000020210803800000010C0 +:10367000021080400000FFFF021080440000FFFFA6 +:1036800002108050000000000210810000000000C5 +:10369000061081200000000202108008000002B520 +:1036A0000210801000000000061082000000004A96 +:1036B000021081080001FFFF061081400000000297 +:1036C0000210800000001A80061090000000002404 +:1036D000061091200000004A061093700000004A76 +:1036E000061095C00000004A0210800400001080FF +:1036F00006108030000000020210803C0000001024 +:10370000021080480000FFFF0210804C0000FFFF05 +:10371000021080540000000002108104000000002C +:1037200006108128000000020210800C000002B583 +:103730000210801400000000061084000000004AFF +:103740000210810C0001FFFF0610814800000002FA +:103750000210800400001A800610909000000024DF +:10376000061092480000004A061094980000004A93 +:10377000061096E80000004A0212049000E383401D +:103780000212051400003C10021205200000000285 +:1037900002120494FFFFFFFF02120498FFFFFFFFD5 +:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5 +:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95 +:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75 +:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D +:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D +:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D +:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4 +:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC +:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C +:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C +:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C +:1038500002120500FFFFFFFF02120504FFFFFFFF3A +:1038600002120508FFFFFFFF0212050CFFFFFFFF1A +:1038700002120510FFFFFFFF021204D4FFFF3330D6 +:10388000021204D8FFFF3340021204B4F0003000EB +:1038900002120390000000080212039C00000008BE +:1038A000061203A000000002021203BC0000000484 +:1038B000021203C400000004021203D00000000042 +:1038C000021203DC000000000212036C0000000181 +:1038D000021203680000003F021201BC0000004019 +:1038E000021201C000001808021201C400000803FF +:1038F000021201C800000803021201CC00000040BF +:10390000021201D000000003021201D400000803DB +:10391000021201D800000803021201DC00000803B3 +:10392000021201E000010003021201E4000008039A +:10393000021201E800000803021201EC000000037B +:10394000021201F000000003021201F40000000363 +:10395000021201F800000003021201FC0000000343 +:103960000212020000000003021202040000000321 +:1039700002120208000000030212020C0000000301 +:1039800002120210000000030212021400000003E1 +:1039900002120218000000030212021C00000003C1 +:1039A00002120220000000030212022400000003A1 +:1039B00002120228000024030212022C0000002F31 +:1039C0000212023000000009021202340000001945 +:1039D00002120238000001840212023C000001833E +:1039E0000212024000000306021202440000001905 +:1039F00002120248000000060212024C00000306F8 +:103A000002120250000003060212025400000306D4 +:103A10000212025800000C860212025C000003062B +:103A20000212026000000306021202640000000697 +:103A300002120268000000060212026C000000067A +:103A4000021202700000000602120274000000065A +:103A500002120278000000060212027C000000063A +:103A6000021202800000000602120284000000061A +:103A700002120288000000060212028C00000006FA +:103A800002120290000000060212029400000006DA +:103A900002120298000000060212029C00000006BA +:103AA000021202A000000306021202A4000000138A +:103AB000021202A800000006021202B00000100468 +:103AC000021202B400001004021203240010644029 +:103AD0000212032800106440021201B0000000012D +:103AE0000600A000000000160200A06CBF5C0000F1 +:103AF0000200A070FFF51FEF0200A0740000FFFF9E +:103B00000200A078F00003E00200A07C00000000AA +:103B10000200A0800000A0000600A08400000005B4 +:103B20000200A0980FE000000600A09C0000001416 +:103B30000200A0EC555400000200A0F05555555568 +:103B40000200A0F4000055550200A0F8F0000000AB +:103B50000200A0FC555400000200A1005555555527 +:103B60000200A104000055550200A108F000000069 +:103B70000600A22C000000040200A0600000030761 +:103B80000200A10CBF5C00000200A110FFF51FEFB6 +:103B90000200A1140000FFFF0200A118F00003E0E2 +:103BA0000200A11C000000000200A1200000A000F3 +:103BB0000600A124000000050200A1380FE000006B +:103BC0000600A13C000000140200A18C5554000026 +:103BD0000200A190555555550200A194000055557D +:103BE0000200A198F00000000200A19C55540000C2 +:103BF0000200A1A0555555550200A1A4000055553D +:103C00000200A1A8F00000000600A23C0000000491 +:103C10000200A06400000307000000000000000094 +:103C20000000002E00000000000000000000000066 +:103C30000000000000000000000000000000000084 +:103C40000000000000000000000000000000000074 +:103C50000000000000000000000000000000000064 +:103C60000000000000000000000000000000000054 +:103C70000000000000000000002E004D00000000C9 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA00000000000004D008B00000000000000003C +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD000008B009000900094009400980000000079 +:103CE00000000000000000000000000000000000D4 +:103CF000000000000000000000000000009802DE4C +:103D000002DE02E802E802F200000000000000000B +:103D100000000000000000000000000000000000A3 +:103D20000000000000000000000000000000000093 +:103D30000000000000000000000000000000000083 +:103D40000000000000000000000000000000000073 +:103D50000000000000000000000000000000000063 +:103D60000000000000000000000000000000000053 +:103D70000000000000000000000000000000000043 +:103D80000000000000000000000000000000000033 +:103D90000000000000000000000000000000000023 +:103DA0000000000000000000000000000000000013 +:103DB0000000000000000000000000000000000003 +:103DC00000000000000000000000000000000000F3 +:103DD000000000000000000002F202FA00000000F3 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E000000000000000000000000000000000000B2 +:103E100000000000000000000000000000000000A2 +:103E20000000000000000000000000000000000092 +:103E300002FA02FF02FF030A030A03150000000052 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E60000000000000000000000000000000000052 +:103E70000000000000000000000000000000000042 +:103E80000000000000000000031503160000000001 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB000000000000316035700000000000000008F +:103EC00000000000000000000000000000000000F2 +:103ED00000000000000000000000000000000000E2 +:103EE0000357037B000000000000000000000000FA +:103EF00000000000000000000000000000000000C2 +:103F0000000000000000000000000000037B03BB75 +:103F100000000000000000000000000000000000A1 +:103F20000000000000000000000000000000000091 +:103F3000000000000000000003BB03F700000000C9 +:103F40000000000000000000000000000000000071 +:103F50000000000000000000000000000000000061 +:103F60000000000003F7043D043D045204520467BE +:103F70000000000000000000000000000000000041 +:103F80000000000000000000000000000000000031 +:103F9000046704ED04ED04F204F204F700000000ED +:103FA0000000000000000000000000000000000011 +:103FB00000000000000000000000000004F704F80A +:103FC00000000000000000000000000000000000F1 +:103FD00000000000000000000000000000000000E1 +:103FE000000000000000000004F8050A00000000C6 +:103FF00000000000000000000000000000000000C1 +:1040000000000000000000000000000000000000B0 +:1040100000000000050A051F051F052205220525D1 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:1040400005250555000000000000000000000000EC +:104050000000000000000000000000000000000060 +:10406000000000000000000000000000055505DC15 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:10409000000000000000000005DC05E305E305E783 +:1040A00005E705EB00000000000000000000000034 +:1040B0000000000000000000000000000000000000 +:1040C0000000000005EB062B062B06330633063BEB +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F000063B068806880695069506A20000000085 +:1041000000000000000000000000000000000000AF +:1041100000000000000000000000000006A206AE43 +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000006AE06B40000000001 +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:104170000000000006B406B70000000000000000C8 +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A00006B706BD0000000000000000000000008F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000006BD06BE68 +:1041D00006BE06D006D006E2000000000000000087 +:1041E00000000000000000000000000000000000CF +:1041F000000000000000000006E2074F0000000081 +:1042000000000000000000000000000000000000AE +:10421000000000000000000000000000000000009E +:1042200000000000074F0750075007630763077639 +:10423000000000000000000000000000000000007E +:10424000000000000000000000000000000000006E +:10425000000000000000000000000000000000005E +:10426000000000000000000000000000000000004E +:10427000000000000000000000000000000000003E +:10428000000000000000000000000000000000002E +:10429000000000000000000000000000000000001E +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:1043300000010000000204C00003098000040E40D8 +:1043400000051300000617C000071C80000821406C +:1043500000092600000A2AC0000B2F80000C344000 +:10436000000D3900000E3DC0000F42800010474094 +:1043700000114C00001250C00013558000145A4028 +:1043800000155F00001663C00017688000186D40BC +:1043900000197200001A76C0001B7B80001C804050 +:1043A000001D8500001E89C0001F8E800000934004 +:1043B00000002000000040000000600000008000BD +:1043C0000000A0000000C0000000E00000010000AC +:1043D0000001200000014000000160000001800099 +:1043E0000001A0000001C0000001E0000002000088 +:1043F0000002200000024000000260000002800075 +:104400000002A0000002C0000002E0000003000063 +:104410000003200000034000000360000003800050 +:104420000003A0000003C0000003E000000400003F +:10443000000420000004400000046000000480002C +:104440000004A0000004C0000004E000000500001B +:104450000005200000054000000560000005800008 +:104460000005A0000005C0000005E00000060000F7 +:1044700000062000000640000006600000068000E4 +:104480000006A0000006C0000006E00000070000D3 +:1044900000072000000740000007600000078000C0 +:1044A0000007A0000007C0000007E00000080000AF +:1044B000000820000008400000086000000880009C +:1044C0000008A0000008C0000008E000000900008B +:1044D0000009200000094000000960000009800078 +:1044E0000009A0000009C0000009E000000A000067 +:1044F000000A2000000A4000000A6000000A800054 +:10450000000AA000000AC000000AE000000B000042 +:10451000000B2000000B4000000B6000000B80002F +:10452000000BA000000BC000000BE000000C00001E +:10453000000C2000000C4000000C6000000C80000B +:10454000000CA000000CC000000CE000000D0000FA +:10455000000D2000000D4000000D6000000D8000E7 +:10456000000DA000000DC000000DE000000E0000D6 +:10457000000E2000000E4000000E6000000E8000C3 +:10458000000EA000000EC000000EE000000F0000B2 +:10459000000F2000000F4000000F6000000F80009F +:1045A000000FA000000FC000000FE000001000008E +:1045B000001020000010400000106000001080007B +:1045C0000010A0000010C0000010E000001100006A +:1045D0000011200000114000001160000011800057 +:1045E0000011A0000011C0000011E0000012000046 +:1045F0000012200000124000001260000012800033 +:104600000012A0000012C0000012E0000013000021 +:10461000001320000013400000136000001380000E +:104620000013A0000013C0000013E00000140000FD +:1046300000142000001440000014600000148000EA +:104640000014A0000014C0000014E00000150000D9 +:1046500000152000001540000015600000158000C6 +:104660000015A0000015C0000015E00000160000B5 +:1046700000162000001640000016600000168000A2 +:104680000016A0000016C0000016E0000017000091 +:10469000001720000017400000176000001780007E +:1046A0000017A0000017C0000017E000001800006D +:1046B000001820000018400000186000001880005A +:1046C0000018A0000018C0000018E0000019000049 +:1046D0000019200000194000001960000019800036 +:1046E0000019A0000019C0000019E000001A000025 +:1046F000001A2000001A4000001A6000001A800012 +:10470000001AA000001AC000001AE000001B000000 +:10471000001B2000001B4000001B6000001B8000ED +:10472000001BA000001BC000001BE000001C0000DC +:10473000001C2000001C4000001C6000001C8000C9 +:10474000001CA000001CC000001CE000001D0000B8 +:10475000001D2000001D4000001D6000001D8000A5 +:10476000001DA000001DC000001DE000001E000094 +:10477000001E2000001E4000001E6000001E800081 +:10478000001EA000001EC000001EE000001F000070 +:10479000001F2000001F4000001F6000001F80005D +:1047A000001FA000001FC000001FE000002000004C +:1047B0000020200000204000002060000020800039 +:1047C0000020A0000020C0000020E0000021000028 +:1047D0000021200000214000002160000021800015 +:1047E0000021A0000021C0000021E0000022000004 +:1047F00000222000002240000022600000228000F1 +:104800000022A0000022C0000022E00000230000DF +:1048100000232000002340000023600000238000CC +:104820000023A0000023C0000023E00000240000BB +:1048300000242000002440000024600000248000A8 +:104840000024A0000024C0000024E0000025000097 +:104850000025200000254000002560000025800084 +:104860000025A0000025C0000025E0000026000073 +:104870000026200000264000002660000026800060 +:104880000026A0000026C0000026E000002700004F +:10489000002720000027400000276000002780003C +:1048A0000027A0000027C0000027E000002800002B +:1048B0000028200000284000002860000028800018 +:1048C0000028A0000028C0000028E0000029000007 +:1048D00000292000002940000029600000298000F4 +:1048E0000029A0000029C0000029E000002A0000E3 +:1048F000002A2000002A4000002A6000002A8000D0 +:10490000002AA000002AC000002AE000002B0000BE +:10491000002B2000002B4000002B6000002B8000AB +:10492000002BA000002BC000002BE000002C00009A +:10493000002C2000002C4000002C6000002C800087 +:10494000002CA000002CC000002CE000002D000076 +:10495000002D2000002D4000002D6000002D800063 +:10496000002DA000002DC000002DE000002E000052 +:10497000002E2000002E4000002E6000002E80003F +:10498000002EA000002EC000002EE000002F00002E +:10499000002F2000002F4000002F6000002F80001B +:1049A000002FA000002FC000002FE000003000000A +:1049B00000302000003040000030600000308000F7 +:1049C0000030A0000030C0000030E00000310000E6 +:1049D00000312000003140000031600000318000D3 +:1049E0000031A0000031C0000031E00000320000C2 +:1049F00000322000003240000032600000328000AF +:104A00000032A0000032C0000032E000003300009D +:104A1000003320000033400000336000003380008A +:104A20000033A0000033C0000033E0000034000079 +:104A30000034200000344000003460000034800066 +:104A40000034A0000034C0000034E0000035000055 +:104A50000035200000354000003560000035800042 +:104A60000035A0000035C0000035E0000036000031 +:104A7000003620000036400000366000003680001E +:104A80000036A0000036C0000036E000003700000D +:104A900000372000003740000037600000378000FA +:104AA0000037A0000037C0000037E00000380000E9 +:104AB00000382000003840000038600000388000D6 +:104AC0000038A0000038C0000038E00000390000C5 +:104AD00000392000003940000039600000398000B2 +:104AE0000039A0000039C0000039E000003A0000A1 +:104AF000003A2000003A4000003A6000003A80008E +:104B0000003AA000003AC000003AE000003B00007C +:104B1000003B2000003B4000003B6000003B800069 +:104B2000003BA000003BC000003BE000003C000058 +:104B3000003C2000003C4000003C6000003C800045 +:104B4000003CA000003CC000003CE000003D000034 +:104B5000003D2000003D4000003D6000003D800021 +:104B6000003DA000003DC000003DE000003E000010 +:104B7000003E2000003E4000003E6000003E8000FD +:104B8000003EA000003EC000003EE000003F0000EC +:104B9000003F2000003F4000003F6000003F8000D9 +:104BA000003FA000003FC000003FE000003FE001E8 +:104BB00000000000000001FF0000020000007FF87C +:104BC00000007FF80000016A0000150000000001ED +:104BD0000000FF00000000000000FF0000000000D7 +:104BE00000000000140AFF000000000100000000A7 +:104BF00000201001000000000100860000000100FC +:104C00000000860200008604000086060000860878 +:104C10000000860A0000860C0000860E0000861048 +:104C20000000861200008614000086160000861818 +:104C30000000861A0000861C0000861E00008620E8 +:104C400000008622000086240000862600008628B8 +:104C50000000862A0000862C0000862E0000863088 +:104C60000000863200008634000086360000863858 +:104C70000000863A0000863C0000863E0000864028 +:104C800000008642000086440000864600008648F8 +:104C90000000864A0000864C0000864E00008650C8 +:104CA0000000865200008654000086560000865898 +:104CB0000000865A0000865C0000865E0000866068 +:104CC0000000866200008664000086660000866838 +:104CD0000000866A0000866C0000866E0000867008 +:104CE00000008672000086740000867600008678D8 +:104CF0000000867A0000867C0000867E00008680A8 +:104D00000000868200008684000086860000868877 +:104D10000000868A0000868C0000868E0000869047 +:104D20000000869200008694000086960000869817 +:104D30000000869A0000869C0000869E000086A0E7 +:104D4000000086A2000086A4000086A6000086A8B7 +:104D5000000086AA000086AC000086AE000086B087 +:104D6000000086B2000086B4000086B6000086B857 +:104D7000000086BA000086BC000086BE000086C027 +:104D8000000086C2000086C4000086C6000086C8F7 +:104D9000000086CA000086CC000086CE000086D0C7 +:104DA000000086D2000086D4000086D6000086D897 +:104DB000000086DA000086DC000086DE000086E067 +:104DC000000086E2000086E4000086E6000086E837 +:104DD000000086EA000086EC000086EE000086F007 +:104DE000000086F2000086F4000086F6000086F8D7 +:104DF000000086FA000086FC000086FE00008700A6 +:104E00000000870200008704000087060000870872 +:104E10000000870A0000870C0000870E0000871042 +:104E20000000871200008714000087160000871812 +:104E30000000871A0000871C0000871E00008720E2 +:104E400000008722000087240000872600008728B2 +:104E50000000872A0000872C0000872E0000873082 +:104E60000000873200008734000087360000873852 +:104E70000000873A0000873C0000873E0000874022 +:104E800000008742000087440000874600008748F2 +:104E90000000874A0000874C0000874E00008750C2 +:104EA0000000875200008754000087560000875892 +:104EB0000000875A0000875C0000875E0000876062 +:104EC0000000876200008764000087660000876832 +:104ED0000000876A0000876C0000876E0000877002 +:104EE00000008772000087740000877600008778D2 +:104EF0000000877A0000877C0000877E00008780A2 +:104F00000000878200008784000087860000878871 +:104F10000000878A0000878C0000878E0000879041 +:104F20000000879200008794000087960000879811 +:104F30000000879A0000879C0000879E000087A0E1 +:104F4000000087A2000087A4000087A6000087A8B1 +:104F5000000087AA000087AC000087AE000087B081 +:104F6000000087B2000087B4000087B6000087B851 +:104F7000000087BA000087BC000087BE000087C021 +:104F8000000087C2000087C4000087C6000087C8F1 +:104F9000000087CA000087CC000087CE000087D0C1 +:104FA000000087D2000087D4000087D6000087D891 +:104FB000000087DA000087DC000087DE000087E061 +:104FC000000087E2000087E4000087E6000087E831 +:104FD000000087EA000087EC000087EE000087F001 +:104FE000000087F2000087F4000087F6000087F8D1 +:104FF000000087FA000087FC000087FEFFFFFFFF2C +:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399 +:1050200000BEBC20000000000000000500000003DE +:1050300000BEBC20000000000000000500002000B1 +:10504000000040C000006180000082400000A3001A +:105050000000C3C00000E4800001054000012600FC +:10506000000146C000016780000188400001A900DE +:105070000001C9C00001EA8000020B4000022C00C0 +:1050800000024CC000026D8000028E400002AF00A2 +:105090000002CFC00002F08000001140000080003C +:1050A000000103800001870000020A8000028E00D8 +:1050B00000031180000395000004188000049C0088 +:1050C00000051F800005A300000626800006AA0038 +:1050D00000072D800007B100000834800008B800E8 +:1050E00000093B800009BF00000A4280000AC60098 +:1050F000000B4980000BCD00000C5080000CD40048 +:10510000000D578000005B0000007FF800007FF872 +:1051100000000166000015000000FF000000000014 +:105120000000FF0000000000000019000000000067 +:1051300000000000FFFFFFFF00007FF800007FF885 +:1051400000000361000015000000FF000FFFFFFFDB +:105150000000FF000FFFFFFF000000FF0000FF0046 +:105160000FFFFFFF0000FF000FFFFFFF000000FF29 +:105170000000FF000FFFFFFF0000FF000FFFFFFF19 +:10518000000000FF0000FF000FFFFFFF0000FF0016 +:105190000FFFFFFF000000FF0000FF000FFFFFFFF9 +:1051A0000000FF000FFFFFFF000000FF0000FF00F6 +:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9 +:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9 +:1051D000000000FF0000FF000FFFFFFF0000FF00C6 +:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9 +:1051F0000000FF000FFFFFFF000000FF0000FF00A6 +:105200000FFFFFFF0000FF000FFFFFFF000000FF88 +:105210000000FF000FFFFFFF0000FF000FFFFFFF78 +:10522000000000FF0000FF000FFFFFFF0000FF0075 +:105230000FFFFFFF000000FF0000FF000FFFFFFF58 +:105240000000FF000FFFFFFF000000FF0000FF0055 +:105250000FFFFFFF0000FF000FFFFFFF000000FF38 +:105260000000FF000FFFFFFF0000FF000FFFFFFF28 +:10527000000000FF0000FF000FFFFFFF0000FF0025 +:105280000FFFFFFF000000FF0000FF000FFFFFFF08 +:105290000000FF000FFFFFFF000000FF0000FF0005 +:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8 +:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8 +:1052C000000000FF0000FF000FFFFFFF0000FF00D5 +:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8 +:1052E0000000FF000FFFFFFF000000FF0000FF00B5 +:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98 +:105300000000FF000FFFFFFF0000FF000FFFFFFF87 +:10531000000000FF0000FF000FFFFFFF0000FF0084 +:105320000FFFFFFF000000FF0000FF000FFFFFFF67 +:105330000000FF000FFFFFFF000000FF0000FF0064 +:105340000FFFFFFF0000FF000FFFFFFF000000FF47 +:105350000000FF000FFFFFFF0000FF000FFFFFFF37 +:10536000000000FF0000FF000FFFFFFF0000FF0034 +:105370000FFFFFFF000000FF0000FF000FFFFFFF17 +:105380000000FF000FFFFFFF000000FF0000FF0014 +:105390000FFFFFFF0000FF000FFFFFFF000000FFF7 +:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7 +:1053B000000000FF0000FF000FFFFFFF0000FF00E4 +:1053C0000FFFFFFF000000FF000000FF000000FFD4 +:1053D0000000FF00000000000000FF0000000000CF +:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1054000000001000000020800000310000004180FA +:1054100000005200000062800000730000008380E2 +:10542000000094000000A4800000B5000000C580CA +:105430000000D6000000E6800000F70000010780B1 +:105440000001180000012880000139000001498096 +:1054500000015A0000016A8000017B0000018B807E +:1054600000019C000001AC800001BD000001CD8066 +:105470000001DE000001EE8000000F0000000000CF +:1054800000007FF800007FF80000021D00001500FA +:1054900010000000000028AD00010001FFFFFFFF29 +:1054A000FFFFFFFF00050206CCCCCCC17058103CBA +:1054B000000000000000FF00000000000000FF00EE +:1054C000000000000000000000000001CCCC020140 +:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1 +:1054E000FFFFFFFF0000FFFF000000000000FFFFC4 +:1054F000000000000000FFFF000000000000FFFFB0 +:10550000000000000000FFFF000000000000FFFF9F +:10551000000000000000FFFF000000000000FFFF8F +:1055200000000000000E0000011600D60000FFFF82 +:10553000000000000000FFFF000000000000FFFF6F +:10554000000000000000FFFF000000000000FFFF5F +:10555000000000000000FFFF000000000000FFFF4F +:10556000000000000000FFFF0000000000720000CB +:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B +:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F +:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1 +:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E +:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C +:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D +:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2 +:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6 +:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00 +:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6 +:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7 +:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE +:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19 +:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E +:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC +:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E +:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D +:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E +:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F +:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D +:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B +:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C +:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1 +:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5 +:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF +:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5 +:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6 +:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD +:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19 +:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D +:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B +:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D +:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1 +:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91 +:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1 +:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70 +:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1 +:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F +:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91 +:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D +:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71 +:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08 +:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50 +:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0 +:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30 +:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0 +:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10 +:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70 +:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA +:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C +:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D +:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B +:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29 +:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A +:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF +:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3 +:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD +:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3 +:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90 +:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE +:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2 +:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE +:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8 +:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B +:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB +:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B +:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D +:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A +:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28 +:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19 +:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE +:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2 +:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC +:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2 +:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3 +:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA +:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82 +:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD +:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8 +:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A +:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE +:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E +:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE +:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D +:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE +:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C +:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E +:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A +:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E +:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05 +:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D +:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD +:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D +:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD +:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D +:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D +:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED +:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D +:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD +:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C +:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD +:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B +:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D +:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29 +:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D +:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04 +:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C +:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC +:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C +:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC +:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C +:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C +:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC +:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C +:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC +:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B +:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC +:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A +:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C +:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28 +:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C +:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03 +:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B +:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB +:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B +:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB +:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B +:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B +:105D7000CDCDCDCD000C0000000700C00002813069 +:105D8000000B81580002021000010230000F024097 +:105D900000010330000C0000000800C00002814038 +:105DA000000B81680002022000010240000702503F +:105DB000000202C000100000000801000002818003 +:105DC000000B81A80002026000018280000E829810 +:105DD0000008038000028000000B8028000200E021 +:105DE000000101000000811000000118CCCCCCCCD7 +:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3 +:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E2000CCCCCCCC00002000000000000000000022 +:105E30001F8B080000000000000BFB51CFC0F003D7 +:105E40008ABB5819180238107C7AE0A58C94E9DFD7 +:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346 +:105E6000D8F7241818182419184E893130EC9244A8 +:105E700088E702D5084A3130DC858A0500D967A554 +:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6 +:105E900089A3C93F86CA6F5480D03FD5B19BBB0947 +:105EA0002A0F00FE694F6760030000000000000039 +:105EB0001F8B080000000000000BED7D0B7854D50F +:105EC000B9E8DACFD933994C7642422610700703ED +:105ED000040D30208FA85427E1D1E0E5E8F0462EEC +:105EE000CA80AF0892448D356D39373B6412020287 +:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3 +:105F0000DC206A73DAD37B9152A52DB6413D281669 +:105F100068F49403BDD796BBFE7FAD3DD97B672661 +:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C +:105F3000FAFF7FEDA8A242D44B08B9083FD712B2AE +:105F40004E2084E4F55EADFB448B56935C42AA82FE +:105F5000AAB1953E5B2F858DC669F4FE2562E809DE +:105F600002F7C7CD21930851E0BD0242A6C2FFA6A9 +:105F70001322E7B40E8FFAE93D6955165CADF1AC1A +:105F80006B954C883E159E6F1B97EA7972FE84D202 +:105F9000D3AD11FCB9388690FAE337CE7FC56AD30A +:105FA000FF4692CCDC9397D35F6692991725423EC9 +:105FB0002A5C94D569A41FEF83862E5D1E4BC8F919 +:105FC0008615F35F19DBF7F97A89D4B697F6BD7FAA +:105FD00015D1102F4433D5C8C4DE75AF27A4D39391 +:105FE00043C8E6C24D6CBDB9145957D2FB6DFFA230 +:105FF000CB25BD70AE9769BFA97DD7438889E35A89 +:10600000E324DF4F7439DE77BF971C8FBF4F64FAEC +:106010006F0621D885AE7FBA10BD16EE7B0A1799A0 +:1060200023687BFD33E5245A9A1EFE24BD3E21FCE5 +:10603000D67B69E9C8FB7DB4BFA985D0F74EAAF12C +:10604000EBAFA27CF4DEF7A5D026E0A33DE3E7901A +:1060500000BD4F181F59743AB5BF69782AFE4847EA +:10606000A7BF275EE43F8BBFAAC455599DE493F3B5 +:10607000D71DC05F1936FE6A5FDCEF789F94BF6260 +:106080006EFEE2F838DDCED64F760F6374E1F4721F +:10609000D3272D5D3EE97B7DF9690BE0D5D3BED8D2 +:1060A0001C4152F01387D7A2D7A78577203E222420 +:1060B0008E74262422C1FCBDF7D935A3CC1080CF25 +:1060C00068F330AC23C8A622C15B5BEE16299C01A5 +:1060D00092681D5744DBDD6B1600DC81E3F34F81D2 +:1060E0003C34872AB4D974BDFA34E3A179F49A51C7 +:1060F000AA0BB09EAD44042540C7AB36CB4B815EA6 +:1061000004DB4F9BB7844DC0030913329C90FBF80E +:106110009A08110D99B655F8754CAA75A8A493E183 +:1061200043B8E8E9FB7EBAF5ABBDEF918B45F0FFD4 +:106130007B08AC6FA0F74894BD67D27F80EF1CD777 +:1061400038FA1CDAB6F17D80D8DAF4F951F805F1A5 +:106150007DF717325F36D9A719543FA825A29E8034 +:10616000FEC4C896693BA3922A22781E24072945BB +:1061700006A44B332195EDC08FA49D2C9CD80BDF3A +:106180002922E07A0A6EDFB9A685AAAE7365FE10F1 +:10619000F079502764584EDFF56C6BA08C3CDED64E +:1061A0000E3D87FC1FA37C3486BE6F86983DDC5A6B +:1061B000F2B21EB5C977862070BE74F30731E419B8 +:1061C0002066C02AF45A2286BD814FCF1FB20B8FA2 +:1061D00083E50F7FD4461F32747A05B9DF3058FE4D +:1061E000F8B4F35974ED2B578D165D3542E9B0A51F +:1061F00078514AFF233D5DF711E89F5142C289144F +:10620000EF8D12042E07A643DFE095D2474A92F79E +:106210005E07BDA4FC192BF6F6830F29D7890F6BF7 +:106220005C6FBD64BC4B5522917511C653613CCA6D +:10623000A75B820F9B84CAC339E06D8A0F293EA5F4 +:1062400013DAA498201FD29F4E81B6BDC170622B75 +:10625000F24102E962C1E73144077EE55C9FA34D4C +:106260005698821D7E6FBD8A70A8E823D071743A5B +:10627000204585EC279DC0B716BF021B5CBC14DA15 +:106280005F77F041AB3195A4A283C5AF8056C6AF0E +:106290005F1F9C7E71CFB7C409EFA0DFF3CBC64967 +:1062A0009B1D4AFF9E4C4E5AF4A148AC82016C7C67 +:1062B000B059210784C98434152E23517A77333C91 +:1062C000A276AC05AE05E01F4E45BD40DA0419E0EC +:1062D000B4EC2A09E660BFE98281E3895A2DEA1508 +:1062E000C91F66F6953F4F0F179B7FB8110FEB1430 +:1062F000BFF9241E16297DA8AE0C7512D09B610231 +:106300007C40428C2F24EEA75BEFC7383F7BC951FE +:106310007C9F6A5753477BE694E3B9127D48C7D9FF +:106320005242121EA4535C83B65C2213D81750FD50 +:10633000E42FA0FDB32CF697168400FE2C6E5FC9E7 +:106340002CCEDF02D56714CFFE694EF9F6B9E45FB3 +:10635000E6F6B88F3E4BB39FB0AE6EFFED3181FBDA +:106360006F19C48FF4E6EF137F6A7FD5F2DB2CBC84 +:10637000E68904F1497EAA249E28E26BA3ED7BDE28 +:10638000CA4EC0BACD8AC89A668A07F36D21D40472 +:10639000F494C33D59F4F9C92725DC2FE52DABBF93 +:1063A00004E6DBDE608E2DB6F983DBE55A0DF04D99 +:1063B000F942B3DB8B1B48F405C1B6FFF2045BC6A0 +:1063C000160F43FE7BBBBB044C8580FCE7F5C78200 +:1063D000AF825CF2FB49FCD8DB52DF766E3EE1F621 +:1063E000F286F2309DB71574D7087C6C0A149ED6DD +:1063F00002D6FE49E3F072B09FAD99ACFD51E33B8C +:10640000E146E48BA816A1F7EA09C74B17C50BD2E2 +:10641000DFC8B7DB57F7D5BDFE1DB2EE033EDBEBA1 +:10642000CFB9AE04EC67991802B4EF8D1DD1D7D85F +:10643000F0F14D4FC51B808F91242110A05F2C17C8 +:10644000E5C7F2E780F1A05DC0E5A9901CC67EA378 +:10645000233DE50ADC5AA1BF0CD796E073D9284F3B +:10646000648E7E12E55F122E5E3E78794FB7DE8035 +:106470004022A9FCF9FBA51C94ABC034BA6E875E20 +:106480002FD4911FF9B85F031A81FEC8A6304D06BC +:106490003D125F114931DE4F0411FB69600FAEA060 +:1064A00068285C56F66F74BD9A169EF22A85CB93C7 +:1064B000EB0F990836B3130697014FBC5103FC92BA +:1064C000A31201F9D70AC391DB804F49242CD0FBDA +:1064D0005A301CDA6AF45D9F4A987DC8A1D78B4C6C +:1064E000BE09F4BF274FC7FE04EC85B5AE31009757 +:1064F0008A707D06F4CE15A70F4CE711A4BD1C8C45 +:10650000593A7A7FD6744EF7BE9BBE0181C9D7FD3A +:106510004DE7C32695A796E3822881528C17235D09 +:10652000344E97F34A5403BF71CB5745B28FB61F11 +:10653000ADEFDF4F89819FE2B1D94D9DD16FE45D11 +:10654000FA5460A174EFEDBA4BAC4CA4E0A74A91A9 +:10655000E9FD2D773D1C1F0BF47CC5B9DF53568533 +:10656000D12FA5FBBE4AA087F59EB798D927B29F29 +:10657000AE87F657B83F723E6F511649318F75DDC1 +:10658000E382BF90E23995DCDC2771FF6A271BDFCD +:10659000F277CE17F43FBE859F0B9522395C8A6453 +:1065A000F59152BE188AF7C2A4DF9D876D0F7F94C4 +:1065B000A8157D04EC5E6167395C15D2D3087CBAFE +:1065C0004B2455A9E05B2B89085F61986E3DA8DEDE +:1065D0002F3445D04CE45EC9C0FBF9AB6A0F2A9456 +:1065E0002EADA34808CCCC25301EE8D5835EB49FE1 +:1065F0006A2E4978A99E7EADE82B26D865BD908489 +:106600000116BD16F69CF43F6A5F0DFA5CD9183589 +:1066100011AE6004F708878A9621BD5BA87FE76109 +:106620000B71F0538B297602DFC6E9F8E00FC68DB7 +:106630000A94D773416AF9E1E7630ABFB5DFB8147A +:10664000E242949400E70419E1A423317AEA0C2F82 +:106650002377CF229DD4EEB466EF427930AF242861 +:10666000AF32396C0A6067E48429527863554C1F55 +:1066700028B971C16EC7F690E88376BE91F54EF4E5 +:10668000FF5AFF2CAD4885D76A91E9B7FBB83E3C6D +:10669000AFB4CF477FA399CA4751DFFE614E876FE2 +:1066A000C7163D381EF519B34BD6F32EC170C43151 +:1066B000475E50713D6EBF661EF76B5A0AA95F8335 +:1066C000F24E16801F93C1F9A305B0479F7BB249D4 +:1066D000C2A47064803F43FD1252CAFC128DFE03B7 +:1066E000FD97BFC2E9CF785C7E4B3A7FE66B42E410 +:1066F00007A8EFA8AA02F8770BF1F9E300DF057409 +:106700003F69F45D7717DF4FCE95B615B550B81ECB +:10671000CB151DFC309ACBCB63C43C71913E8F17D7 +:106720008A06C01DAF17711DE70CE6B79377BD0E43 +:106730003BD16C2ED2884DFFECE0F2B4AD4173C872 +:10674000ADFBEA57E3D1480ABDA573FA64CC0A63EE +:10675000FCC31F4A20FD619DA9FCF4074A2BB4FE2F +:10676000F49F5CA2AE41FC15569C92E15AE6DE2FE6 +:10677000A51ED77D25763F534ADF6FB0D72D144F26 +:106780006F2B0E7FBC53827D9749D0FFF386A8A95B +:106790000AC0551F0EF07B4354DCE0DA5D5E09F75A +:1067A0008D59110DE4C8B2CFDE50642BDCCFFA92C4 +:1067B000BC05E8E52D174589D24F934D9263939B15 +:1067C000A970D3C6DF99545DDAF1A145BF52097EA5 +:1067D0002A2914C9580AC7E68F1B343B9DBAE836EC +:1067E00084ED5B9D7C13AFEF5FCF7E5ABEF8B96836 +:1067F000C5439CF4C21F7B3C84D33949FF3E718D55 +:10680000FF1CF4D638FD0C4ABF4D06D093E90BBAF5 +:10681000F142FF21AE996168C70D43346D7AEC6394 +:106820003107F1205F90512FED5ED312067AE974A3 +:106830000C202DBD8653D9ED2E4145B9A27AE32A0D +:10684000693A2A6401E29F73A58D48EFC728BD41CC +:106850008F3D466ABB2EE6F6CABF1655D18FEF6A4A +:1068600034CB1B8B87A237297CD4AF237B98FF7254 +:1068700089E5BFFC3DE59341F82BE7A9D1E0F6D8C7 +:106880000B7C25775396A670156E6476137CB51C29 +:10689000DA36A8DDEB147AF9D1C3E7514A1387C77A +:1068A00023BD9DF6E9B1C297050FD8B76266DF54E4 +:1068B000B3330C7A26504CED1341FBB31AF033A2DC +:1068C000245E0EED91BBE7E13ABE0D7EA81FEC0BF6 +:1068D000417C7C534C349A9466BE70A4539460FF00 +:1068E0004C707F67D1CF3D2FB57A484F5FB6B81750 +:1068F000E814A83D0CCBB4DBBD6A29AFD71E8E28A7 +:10690000E94475EBF617D2FA097F96F87E6C666358 +:1069100098B647C1AFD49FDC293EDE08FBB188277B +:106920005C8F7477ED239271281EEF5E5B6609958C +:10693000B1FC37749E3BBB140A00013F40B2C781D3 +:10694000EE04BB44F5CD5A6ED76E2591003C3C4316 +:10695000448CAF9D21470257D8F870A7A4B2795A4A +:1069600095B7217E6FC5776F8BB3B6A57FEED8ED57 +:106970006CDF4E160D87F8EDED3B155CFF9DAE7D8F +:106980006B4CD271DC3B486D0BE0A15921E827AC80 +:10699000D5890CF1D80D3FFCCE0CD8277C9BDB951C +:1069A0000F287F1936FDB3CE9F50613FFB4EC715B0 +:1069B000CBAE26F07EA26504ECCBB3494A3B7A4BC2 +:1069C000AB13BE81E077C34BC8A67EE190DB849415 +:1069D000F1C3A724C11137ACD70293206872DECB74 +:1069E000AE6605D31FE66FBD8926F0132583F7AF8A +:1069F0009DCCF21CB533E13AD07B3FE3FEE850DF9B +:106A00003B9CE6BD0D5AB70AFC5F239B9582D81BC1 +:106A1000AFD294DAF04890E303E59D2389A35FEBBE +:106A200020FB558AFDF473C37B4AD74C71725FB863 +:106A30006F20D1B740EECE8BD16A8C1370B83D80F9 +:106A40006709AE32D213E3274530AFBF55C882384D +:106A50004A07FA275E4376D0BBC6D203542F41DCE7 +:106A600027A3C4F9DC1D57E949D2B513E50B43A2AE +:106A7000744901CDDF2981BF58269F4EF6A7F355F3 +:106A8000C3BA266327D42F755CBF5413E3C159D30F +:106A900050BE305E57377F8C0970D4E51921D30082 +:106AA000351A0AE3182EBEAAB92090846DFF5D2323 +:106AB000F7A8204735547FDBEFDF1364F1E4747AE5 +:106AC0005B219AE12F01BF56443C493A6DDBD6FD6C +:106AD000515CA86C67FBAAAC25FDEC8BEF09B27882 +:106AE000F1DA2D63B358DCC5A9AFCE72FBF0936722 +:106AF0001E57BB41CF3C7DE27A58E7FAFF29118D42 +:106B0000CE7BF6994CD2897623A182DD58D721A578 +:106B1000B4878434B1FCF9F732915EEB9EF324160E +:106B2000D0F7D7BDF0CE2442E13BBBA9E7B591E059 +:106B30004F3F2DB0B8B8D93D6931BDBF4E26AB53DC +:106B4000C55926C86C1F72FA47192B407E85B6833B +:106B500037E3B8EDCB15B0AB563F4356905F693F76 +:106B6000B4DBE6534262AC900A3E968F38FD94C087 +:106B7000E03BA0E0FE6F5DDB5E354AE1A869FB10FB +:106B8000F5C5ECEF3D1B003CD41C901C7E5C4D9B7E +:106B9000D4E99984D713708538AB3003F884F34B6C +:106BA000C7068CAF56B73FF0A11480F79D7A8BE2F1 +:106BB00025D409787D530A2D80F60FFE316050549C +:106BC0007D70F88900E0958EBB46CD8238BE93BFBC +:106BD00061FC0B397DC7A39C8EF9DE9AF62D6C3EC5 +:106BE000975EFC007E29E81B878DC8CE3C3A691B66 +:106BF0005C9E77FDB3E71E35E97CA79FFBFDA326CE +:106C000085FBAEBFFCFBA35F07B9FC67AF0E7ABD87 +:106C1000E6E95F06888D0FD7C92C7E707614DD42B9 +:106C2000D17E677FE549804370F6A5F7461B74BDAA +:106C300067BFFFA7E106ED5FF7D2DC7C587FDDF38D +:106C4000B3F3FBF363804F131E3B5C091CDF38205A +:106C50003067E1457E75D1E550C7A1D100E7996362 +:106C60001EDC9FD5D07BF553814E1BD0CE427B23BB +:106C7000C56FF5339B3F04FDD017CFE64811835F06 +:106C8000540D0681CEEFCC437A911EB48FEEFE35C3 +:106C900047291D27A7A7DB39F2B10A7AAEE6992D5D +:106CA0006C3E17DDCEC02F57F6A5DB6617DDCE9103 +:106CB000BB1E2B80C46BC730471EC1BAF6C6CF239C +:106CC00059917EF48325FF03E115F32C14AEA572D0 +:106CD000F81B32C8D1731949BA2E00BA3E7B6E3404 +:106CE000A17CF1BED27333D8839E973CFA3E7A7F63 +:106CF000DD4B6FA25C9D7DFE75D5403B46FC02F5E9 +:106D00002BCF92E4CF61F033AB99CF496AF6677627 +:106D10007A02BDF4A94E2CAC340278FF04DE4F3069 +:106D20007EAF4E1C5C22A4A0D7EBF218A6FF13790D +:106D300088970DFB7FA312BF938E4219D0F1C43CFC +:106D4000B89F8E8ED6FA7558FF4C1B3DF7333975B8 +:106D5000F7AFA6F208F62E49D784F02649219767A7 +:106D6000F77A64B07767C1AF4A993765FECC50F3C4 +:106D70002B3F939DF557C9FC0AC7437AFE60F23D4D +:106D8000D0FA868ABF1FC9068EEBC6E3E98F53EBA4 +:106D9000FBF7B8BEA82666E5884BFBFA2132899836 +:106DA000238B7AE13D0D1B54CA7FA79F96301ED4DA +:106DB000D27E08F5B65B4F54A7896F5E90999F50BD +:106DC0007DE0E024D067A75FFE11F267F53327541A +:106DD0008817BFD6F603B5BBB4571EC01E246CF689 +:106DE000E0F4770F4E627A808E9F824E8AC2C6AFE1 +:106DF00079D1397ECD331F3AC65F6FB6A37F30D0CD +:106E00003C1FC8E1E5B0DE0F0E2B04F4E807ED529D +:106E1000652ABFF6036E0F2D3CB5BC3EEF379007D9 +:106E20009B76C46780DDECD814CEDF0EFEDA1185C8 +:106E300080DE2672F8F71EDAEE78DD67407EBAE370 +:106E4000C832C9B0ED437FE8C2E7CCA3E6EC4C3AC8 +:106E5000DECCEEC8347051DD7AA3EC38DD57D9F8BA +:106E6000A0EEF5CA7CD0F7B00F35C6C37CA120ECEC +:106E700073A5C0BC4A96BF16756F4A7BCDC653FC3E +:106E8000118C5729BA988C91C1B82349A211E2AB51 +:106E9000C4EF77E727229A3D0FB5E2F041D862E6CA +:106EA0002E7EB100C60990987E12FD4F12BAD88F7F +:106EB000FFE5CE4758F84CCA5F9AFC44867E73F0D3 +:106EC00020E93B5EDF3C4C5483F8768B7F6D6B9101 +:106ED0002D0FD312EC938799AB503CB40A2465BCB8 +:106EE00076BC52315FC9C3DD7134D5F39B1426578C +:106EF000D792EE7BD7009C1196CF99E5C2D79738F1 +:106F0000BEFE79325D3855A1E5E05951FCCE5E12E6 +:106F10008E29F4FEDC553D97BF8CDD793EC71C2FD2 +:106F20005ECC183CFE869AB78B7816DDAE0C226FCD +:106F3000972E7FDC0B87C9F7E3398E3CC6A1B7EEED +:106F4000D7BA31CF50DB5A648BFB0DEFF49230E6A9 +:106F5000F10CF40F8777DEF9CDDB20EE9C5B18F2A5 +:106F600092BEE3C817AEC6B89195CF970BC39D10DC +:106F7000EF9775A35CC279968721BFB0D960F9827B +:106F8000CDC1FEE37A339468B382F1A86B705C5193 +:106F9000E3F507835CE737160710CF018A67907720 +:106FA000DCFFC0FA8E0B3C6FDE6D4A903F3C918D4A +:106FB000F982804C4A201E705EF08536613EC19990 +:106FC000374FC7BFDB6513F3E6AD469FBCF97714B7 +:106FD0005BBE414B9337D7FC4B306FAE119BBF5B11 +:106FE000D4DBAF57EE5C7973180BE332DB67435C9D +:106FF000A6399B38F2E6CD20F85711F29C72F56C59 +:10700000AC3BF3F2E7E6ACD9617B9B1C7F19DB3C20 +:10701000FEF4C7E6739BA07FEE48528B756A7284BC +:107020002CB5E9C1F71416A7DDA0847FA8D8EB8E94 +:10703000383F58F99F436FBD877C05D73114AFCDDA +:1070400094AF3CC857A7885DAF5A578B7F9A8DFE87 +:10705000F942BD3005E366C976D044BE0804A3E119 +:10706000708AF7267998DC5BF306CAA81EA5F2A6FB +:107070001811CC47A93ADDF01A83873F1D5C169F93 +:10708000361B63581D944EB07E2FFD3AA6B13826AC +:1070900044B8285CBB6EBC3DD49F9F63AD73861221 +:1070A0003E69C77BEE25A9EB77AB55B6EEE6C82A5D +:1070B000965FAF72E653217D6D8FB34E17A2FFAE80 +:1070C000609C90E553452DC2F323A6151F0F26E3C0 +:1070D000E106D419DE65823E5456B59B025C7359B5 +:1070E0003E25578B7EACD8EC83AC7733B975E5077A +:1070F000E74AA787845FAB2E6E6B838E7EFA9686F7 +:1071000020B6373718786D6908E37D371D9B8D975A +:1071100083B7605D9A0FE3B2E9C67FB02184E3C410 +:107120001ACAD8783C6F4E486613F0952A5AF23244 +:107130000CDB7E893F370B9A40FEB60BECF9352D00 +:1071400097A2BC59FCB3C3E83F2E2D2566201F0C27 +:1071500075FCBEFCFA135C67F32C3FEAD781E42888 +:10716000AB93CD3BD87994A4BD60F3EC98A5E13CFA +:107170003B72079827CEE619187E86AF6D074F61E0 +:107180001D8242F9015494A28753D7E97179EB3BF0 +:107190008E07F57C7390D585A9C5FE3028FF6683E0 +:1071A000E71B0B59BE512D195E01F7D5D065582745 +:1071B000AE96FA319FA7160FBF05DADB0E6ED12B04 +:1071C000C07E148A21AF0176BB9BC8B9283618BF90 +:1071D000558B4B6E83FE3AC83185639487EDB7D4E7 +:1071E000E2ABEE80F70F4E79CD68A2FD9B0B7D21BF +:1071F0000FC85BB7ECE0FF41EB8942671E8DC854B6 +:107200005F50FDB56DCAED25289F9AAD4E3245BD44 +:10721000A04D6F6C506D7A4325734CC0433ABD430B +:10722000EDEF7D6A5EDF71ACF73728917A15F54294 +:107230008438EBDD53E7B32D7A809B05F948399804 +:10724000ACD35B5030BC37BF6DD5E9B9F3DA71FA16 +:107250002F555EDB5D7FFE59D5E9ED5493757AA31A +:10726000A04EEFC70A0975425EFE9752689FD197FC +:10727000EFDCE3B9CF5B50FF47837D4E3AB9FC9911 +:10728000EACC9F16445D74BFD5EB98EF159097D26A +:1072900081F5CBC82AE738A36A9D75B597D4E7383E +:1072A000DA45E60847FF4B5BC7389E8F8D5FE6786F +:1072B0003E7EF754477B42E22A47FFCBDB2A1CED98 +:1072C00089EDD739FA4F3EB0C8D19ED2B9D2D1FF9D +:1072D0008AAEB58EE7D30FAF733C9F79EC1E47FBA8 +:1072E000CAEEAF39FAD753774805B9CDE575C8B9B5 +:1072F000F9A23D4FDB9A47ED12DDE7EFC8A30C83FF +:10730000F16F56D7A5B2C7C9BCA1FB3DD950C33A4E +:10731000E6FDC7CD812B91EBD09ECAC6F00A03EFE4 +:10732000CF98075732CD595FAB1AAC3E19F671CEE4 +:107330007A01679DB12A6DC33C9DE7F897BB8449EC +:107340007DE9AA163AE560B075CA8AE17A6F88725B +:1073500071DE928B51542E30FEF6B184E75AE6640A +:10736000A27F61DB4F211EADFDD4351A89818B6967 +:10737000C945F9AA9E91AF62376B1FE51187521775 +:1073800067C95FC0A6F761BF62E999E6B2C1E95774 +:10739000297185C39F745F9B02EBD2E9C7028FCD31 +:1073A000BF77EBC7194AA4109E6B72D824B6780D2C +:1073B000A9551C700F16CE4F6A07EEA20C4752E873 +:1073C0007195D462DD55CB8A300601481D71F0E914 +:1073D000CEC5FFA30CC6A57EE10CE73A995FE8F69F +:1073E000A7A97E437F7A07F5A7D1DEB9F423D55349 +:1073F00026AFFF32981FC1F4A17B9D9F971FFD6FA1 +:10740000E0ACF643AF4051A812F787792281FD61C5 +:10741000F3AC4810E27356DDBCF55EABE7521C27B7 +:1074200096AB8A10BF8C75CDC5787D9316D5589EC6 +:10743000388AE334658B7AAA3AB13A0FCB176BF5E9 +:107440000F8CDDDF4FDC45534934553C6DA787E594 +:107450008362FADA2EB0A39979AA017BEED683A7CC +:1074600022104792CB641DF6EB8402F38E2DBF47AA +:107470004814E34C5A5044BBABD5EFC0F90782F730 +:10748000668FC0CF7D6CE9175EAF9A3AEE920EDE42 +:107490002D00EFB481E1F502BC4530FF369CBFC63C +:1074A00063A4C4BF42C295B3816E27BE1CC1742BB6 +:1074B000651B908F1D656C5F4E0D8183BFAD7D0E8A +:1074C000E5EF873D7958BF8A7C6D9D73B8D1A3E302 +:1074D0003C165D49610EC63502D1D8D862CA6F9993 +:1074E00051B69FEFD54F8C8F329530817896EC173F +:1074F000313FA8F27888D5EF0F1C9F4DB3BA915E4B +:107500009BAF94C926A1B7CE3A5648D735B9775D17 +:10751000FFC793CDF893CFEB234BB2B02E457A261D +:10752000D89FDEF6717CB9F5F7F73C5C7F179002C7 +:10753000A6BF4B9743BE3BDD386E3FA69EC77987FB +:107540005E5FCFCF17F8EFE982389315E723C16963 +:1075500029E3F2BD7865F9CA5EFA2E373A29FDE4CF +:10756000E953314F6E9D57A0EACC592FCCE96BD12E +:10757000D58AA393208B1F5974F626F1B9A75F7C97 +:107580007A415EAEE88BCF5F7978BEE1BF183E5F8F +:10759000019F865E3333D9F97472E8AB04F35285E8 +:1075A0004E39B4DEB3F8DDBDFE3FFD17E5276BFDB8 +:1075B000163FA4EF6FA6DCD758F9D54CCE6F1A9CB6 +:1075C000B2A28AE7D5B2B75B2F85FD6BD08FFBBE29 +:1075D000CCB2189EEF5588A9835EC8B4F635FCBCC2 +:1075E0009155AFE42B75FA659A6BFFA2F2BAA83EEB +:1075F000E76DB9FFE63E4795C4AF8B5E93B534F9AE +:10760000B1419E3FDAC5F3750575F146D80F17DC19 +:10761000CAEAFDF7286435D4578EA832455F2EE4B8 +:107620006F8ABE9F41D75FF0E2438D238124B71A52 +:1076300045E0663CA3190E3B5C7057BCDCC79E4F0F +:1076400081719ED298DE2DA88CE339E7A6E7C76743 +:10765000819FF0CA5BCB75880F7C945B8CFBA73352 +:107660002F78C2A0FFCFE4902AAC0B7B61E66BE0E1 +:10767000C7FFBEA12B47B6F1C999EFBE3E43A14457 +:107680003AF3DCEB33642456C231FF868BBF98019A +:10769000709B15A4A416F277BA4A60DC1A8DE5CB6C +:1076A000AC7A9F5DC3D516B8FED49BCDE289F9E2D2 +:1076B0000E68D743400CFC061ECFBFFAB4B11CEADB +:1076C0002FB3BB1401EAF11E124CD34FAFE74F3C6E +:1076D00024809FA576D6429885DE0F1D02949B6379 +:1076E000D9BEE47C112929A27ADF77B8763CFAD397 +:1076F000AE7A278BFFE5D904F37D3D376A09B0D711 +:10770000DB65E31BABC07EAF92B11E67BB7C18E5A7 +:10771000C24DC7E3DE31CEFA5C1E8F3EF4D61DF1BA +:1077200072FAFE3D5344E457FF8929592485FC6EC3 +:107730006F28C3F903056F579603581FD3BB337ADD +:10774000F7497E999859D4442A45A2A950BCF8CB50 +:107750000879DBC6772D2209EBF4F90B0D04C7E994 +:1077600068D0F0DAD6A08F2DA61B836F3504F1BA4E +:10777000B3C1C0EBC30D25F8FCC1869043EE61BEDA +:10778000B74B783B85BFF2795D1F68A0F3DAE0D88C +:1077900035914A3DA5D72E9E8F7AA0746AD6DA7E9F +:1077A000E2607B1ABA86CD19CB9105F5A675FADE93 +:1077B000ADFDC0BFA75158BD08FC9ABBE5C83ED47B +:1077C0008FD1824536FD48FDB6024259F1DE961151 +:1077D00073E614A03CA2BC4C3B1C457FBC20181790 +:1077E000208E587094DDB7CE5B20BDA8A0FD307709 +:1077F0008EA080DE2C25ED00965A1A2515B4FFCCFC +:10780000BC25E5709F4C74DE9FA132F986712BE890 +:1078100075B616F991361DBED3B1DB7C96AEE78FF7 +:107820001D1E03F23C0FBEFC2715F605B15FA91A19 +:10783000F831052F9EC0BA8798D0AD4265EC71AD86 +:107840007A8E4CF50C6E0631BE4A150BE59318E89E +:10785000588C7FF6C4E6F8E1BC4BF494BDFF2E5F74 +:10786000F46E7E7224AC05291F25F317EB6361BA11 +:10787000E97C81E72F8E6BEB626621B469FF29AC4E +:107880001DA3EFBF901D1D296643D14555ACEB4BA1 +:10789000D0B6FA57C5A0DEF64DAE77883F5A04F24F +:1078A000966CEBB49D696BCBAC4D3476B5D6BBE131 +:1078B000D09F5E033D57FDA2D00EA051BDC7F07F03 +:1078C000E021ACBB6D6BE8D2630AA7BF45072A92E3 +:1078D000138204EBE9D484901843F5C704FE7D8A33 +:1078E000826961A311F46B420981DE0CF998DF38DB +:1078F0002141C7B1C9D58434DF41C1BC2FD0711B30 +:10790000AB1B76F3D7B35E961FA827E656C88391C4 +:1079100067141DF3913C4E79DAB2737CBF7A979766 +:1079200035954DA6EF32D03F6B648C83AD2F8A978F +:10793000AB749EF53F2A0A51CB0A7925AC6B589F50 +:10794000DD3E7C2ACB4B39DA0FF13ADA60B6990D7D +:10795000E707AA0F3C341AEA02AA49FCE6AF01BCC9 +:10796000FFCAF28FA70E5E9975356D6FA06D88BF47 +:107970006EE8785D8DD27EC338DCD51D53AE83F5BD +:10798000556F138958C4E4333C9EE2391CBF4CA6A2 +:107990007C72CDD69173BD94CE4F8D09EB22E583D9 +:1079A00095BE71CD1AB4557D02C8CD4ADFC466E0DC +:1079B000ABF513F9F71AC8C457C332AF97A27C319D +:1079C0006C4B430CEA13F6AFACBC0ECCEC7091C917 +:1079D0002D6544CC1F4AD931CC5BFCA1999D7781A0 +:1079E00094FE464A87629974C9F4BA4B65F4335BD6 +:1079F000648C17D3FBADCA54A04B3C8CE72B5A992F +:107A0000DE1FFBA207E3CEC5B5E13BD12FD04B7102 +:107A10009F329A247F302F7D09FC46C719AF93729D +:107A20003887F0632F8B1716AF58B61EDE93329748 +:107A3000F8705F2EB17350E4DB2C4EBD4B4CB46B31 +:107A400020E78162A4EFAE00E30BF3E152E48BFD8B +:107A500062C56577435C5258B3F55F80AED9C50403 +:107A6000E80AF7EFA1F7F7737A4AD9211DE8B79F23 +:107A7000D33396104DA88FB1EEBF20ACBD13E46D8B +:107A80009DF7F9391AC5EB704F383E8CD2E14EEFB5 +:107A9000F3B16001D2618C46F17EE7968E98368A0A +:107AA0008ED3181EA1DBDAE3FF4CBD11CC4F76A0BC +:107AB0003CCBD90FAF0379A7CF5FD1E83A9FCAE19A +:107AC000FA823F2F1E93D41F61426D8DD4D8AB4FE5 +:107AD000346A1F8A6DFDE7507DF0E4A3AC8EFD7A19 +:107AE0003A1FC83B5D07E67F7B26C809A8CFF25145 +:107AF00058C06FF14D1C83F57974DD04FC929E89AA +:107B000032DA592B8EED9920627C09FA033FF84650 +:107B1000B1FE545022A037E54219F7ABB2B4273C6E +:107B2000C180F031CBEB0AFA423CB7EA2DB1E571E6 +:107B3000496F1D30B68BF033378EF6584F7781483A +:107B4000FDCADCE30B85D174BC3BBCDCDFCEA5FEFB +:107B500036BDBFDECBF4D2FD11F3CB10E220467769 +:107B600001EA2712990AD7FC9B8AF3A3FDD8A5BE88 +:107B70007E7537FA0F3BFCA9CF694EF7B1FD7C93B8 +:107B8000FF880EFC564FA8FC835CE88CDF2CFD615F +:107B90009D4F70D7135BFA44C9666BAC9B5F910F26 +:107BA0007A40E6F549B21ED2A1BEB23C731AFA7D04 +:107BB0004F7A99DE930E5E79039CD350FF95E5854D +:107BC000F678A3184FEA2920EDC0AF72304CECF9DB +:107BD0005F4B1FB43468787D62EAB80A909327A699 +:107BE0000EAFD0A90C1C9AF4E32EC8339DDBC3E47E +:107BF000F7DCE1DBF0FCE33993C59B80AD302ED997 +:107C0000F9089ED77D5C8E3C8875B5501F4141DADE +:107C100096EDACDF2AE67831B97E6A56D8F3CD0D01 +:107C20002C7EAC5EB81CE35A2AD7E39EE8AD786E92 +:107C3000C3436D199CAFD48869B2EF1D303C688591 +:107C4000CEEF61A81726E1FBA697C58FAC7A117716 +:107C50005D8805CF0C0E4FDF73194E7A58FB2F8BC2 +:107C60000ED6FB7542385FEF876F6A2E4824618B12 +:107C70007FF4D677AB78FF2CD4C567411D4F347E97 +:107C80007511C84102F7475E7F1D21FCFB4AC8A75A +:107C900041B9C75E879EE1AA8BEF232F86B3EDAE75 +:107CA0008B580FCCC1EBF8B09E5526DF1428BDCF02 +:107CB00064FC7606F8B535543D681020924D1DE6FB +:107CC0003FCBFD7DF9C5BBC3230D1B9F0B86639F77 +:107CD000507D6021C6116AF6FBB1DEBF1AF4DF6485 +:107CE00038376076791CE705C29D509FA71C60E37A +:107CF0003D09F0D0FB7FD4AB0A60DDC761FF93077D +:107D0000F6242AB1432F87110F316FF818D1993E0D +:107D100093294FC4B22D7D561D830DC32E9538FC7B +:107D2000A55D3EDEF655C762A5BDF51FC7B5FF8749 +:107D3000FACDAAEF38AEFD07FA43BBD47827E83B6B +:107D4000F3058F01F68BBE8FE777CD952568076227 +:107D5000456404E0E1956C15F55CEC79CF3ED07399 +:107D6000B3B5E89B9A6DDF7026FB8DD1B0FF4A3129 +:107D70009EE9186FD4D0C6A3F377005EADE7AF6479 +:107D8000EFC2738BF43D03F386858747AFA1EDE126 +:107D90002F78F0DC90B5DF74F3653E97AF16D77996 +:107DA0004015E4CD0FFAB616E5CC1374E6C12CB934 +:107DB000532F4C70E4039E043B4BE9A7CA51085172 +:107DC000D2E7A5F8DCE47CD6C2EB11D2CF93936660 +:107DD0009E2B509ED3CF3383CB3BE1722CEBC9EF6C +:107DE000C2F4736ED09D2771EB29EB6AE9A96F711C +:107DF000FE9449F40A1F9D675DA27D9E0FDF8E4EA3 +:107E0000023FF8038D9D832A697BE86530CFDFF45C +:107E100084EFF74EC7735FFFE4CD1BBA3CACF4119F +:107E20005E97D9470F31FFEA56E6AFD6CD9F8AFE5F +:107E30005DDDF631BAFD9CA2FB5A7521C3A1878690 +:107E4000790DFEBD3D13F551D585003EFFECE6F3FF +:107E50003ACEAFF49DCF8FCFADF9EE72E9D943930F +:107E60007EBA0BCEB9D77D5F113DB679EABECFEBB6 +:107E7000FFBD54EF3AE53D0CF22E1791647D17E8F3 +:107E8000876DAAD50E37CF99057EAD4D3F9481FF02 +:107E9000D5FB3E7CE76E9B8FF7372B53F7CF70F502 +:107EA0001F638DBF10FBBBE149EA1FD88FD1FEF2E3 +:107EB0009F3D167CA8BF1E125DE3E558F3DF88E303 +:107EC000597EF7456DEDABA60C7C1A2F87FD53CF7D +:107ED0006DC480EF4F3C2E877C213BDF6A8C5FAB0B +:107EE0002E5CEAA0772FDEC739EEBFD71074D4EB33 +:107EF000DE11ADC33AED8B3CFE54453D737C6FCF34 +:107F000048479DEEDFE0F8A4705C9D068E6BBE6076 +:107F1000388A1CF2D90B47B1E3FE278563A1C6F46A +:107F2000D7727E9DABB373B3730D21D4446FCDA5CF +:107F3000F7BD94D7BF4CAF1ABDCE9589E9C7EFA264 +:107F400026587FDA86FDFD0D7FBEF7DD6B315115BA +:107F500074D41548BCCEDBAD77E09C37AB77D31C2F +:107F6000DF87B3AE3E89D56BBAEF7FE86378F9C699 +:107F7000E5D504FC69EAABA73CB7B6CB2FF0EF7DA3 +:107F80000645479C9BB7AD3ADFCF0A2E3983CDF724 +:107F90008DCBAF2710D79573537FDFEEA09FC1DF46 +:107FA000A285B14E3CA6F7FF5D9A4F0ACFF0243C64 +:107FB000D7209EA43478AAB5E0D1595EB025F8F94F +:107FC000C0539261D1AD7FFC6CE570930B97201F7D +:107FD000499C4E2DB07F4BD1DFCA7FB4689F2FFCE8 +:107FE000E141D2F7B98C2F86BE8B0649DF622E079E +:107FF0002DFAE70BCFAD8384E73A8BDF8261A4D7FC +:10800000E705CF570609CF318B5EC6E78B9FD62495 +:10801000FFF70FCF5F38DCF9192C0ED252C2CE9386 +:10802000F8A4C88345C2C072E12B76EEB3B5429F77 +:10803000B3CEE65D67DD57BA75FE9AAF339D3CADB2 +:1080400054127940BF630D2C1EF006DF9FFCBAAAC4 +:108050002913E3F3AE795A82FB32FB8BDBFCF72A60 +:10806000E7B9DC81E4785206CBFFDC1875BEB77C3B +:108070004586AB8ECCC47E16FED28DF7D782B73044 +:1080800024310781378AAFACA27EF60D9F35BED270 +:10809000C9DD50F115D38786AF81E4FD2B43C4972A +:1080A00025AF7FADF8CA077C4DFF1B7F0D165F8B98 +:1080B000FE268F43C2D7AD439547EED7FEB5E26BA0 +:1080C000B0F2E8DEB7D1FD5DA8BFEF0B7CD6F87348 +:1080D000CFFF69F1688DB732CD3E2F1D3E0782C3B9 +:1080E000BA7EE81B245EDDFBCF2F1AAFAEF93F3519 +:1080F0005EF97843C6EB007058577990F26DF975C8 +:108100006D6AEAEF888ECB64DF711B2FD41E990F46 +:10811000F9E3BF93303F7D64CF9C0DF67AA071994F +:10812000CCDF3E52397B03C44FCF4532B0F6ECA8CA +:1081300018FAF934C82B2F62EFB9C73FC2F1E5C96D +:10814000CCB6E2BF7940D7A391C5FDCA23A9B4AD8F +:108150000BF34636FA4A7DF17D8418DBA7411E6297 +:10816000416A382C3AA79B77A8F43D1A797C48FAE3 +:1081700067A0F5FE877FCC20F54F02FBE592E4DF98 +:10818000DDB90CF0D926B27AB8E370AB00BEEB468D +:10819000B0D3F215F97B814E7767B2FC61876A6CC8 +:1081A00080FC8967F182073229DD8E2ECD16ECE73F +:1081B0002FE764B2FDD78C55A9F75D0B391FF4BECC +:1081C0002F90F129F83BCCFB2D5DC5BE3F46E4F076 +:1081D000A845B673A7EB5DCFFBD0233380701C4D51 +:1081E00073EE7F017F7FF992FEDF27B5ECFB3E94B3 +:1081F000EF46D9CFBD26F98CCBC7197F746926BD50 +:10820000BE2144BF731FF0D1043F3B37249322A803 +:10821000BFB2C6C99549A74AF1FEAE628C82BC6660 +:108220008A716ECE9C9E7E9C7478B5D663CD03A277 +:1082300008DFE999ABB138E2B43021B3207EE80918 +:10824000DDCDF2878C0F72781DE2CCDA8C4423EC02 +:108250007B65BA4E1BBC1DFF77F67F83E71D474445 +:108260001DCFB7BBF030907E68CA64F9E45C29BAD0 +:10827000C90B7993D542CAEFD86DCC647FEF6852B1 +:1082800066B25E0AE719B733AAC0F72F96C92CFF6A +:10829000454874D442DBFC9338BFB9DFCB9558BD59 +:1082A000117993C973DBBE75A352C9CF2FB89C4E09 +:1082B000CA2C71D4392E89DCAD807C2E59B0503156 +:1082C000FCF0DCC0F1977238DAD4E8A829FE5E3CF5 +:1082D000A5D5431C3F1DC7A24DF0DD8FD5F502D6B5 +:1082E00009946E647CB77AE3417103BDEEE5F2B7A1 +:1082F0001068601BEFBB9CAE6DFB7CA301FEB664F7 +:10830000FE860E4CE1B87937C17CC893DB4FB7408D +:108310003EA45B203C7F726325D43574F3FAB69794 +:10832000E9F346C0DF9C3C94EF711B3FAC03FDDCDE +:10833000A1123C2FF3BB2D9E049C27B0F825A92742 +:10834000369E6F80FAE147D4CE89C037794DB5F7B4 +:10835000A5CA9FBEC4E9F0477F242B951F685D2DF9 +:108360007D6EF55B241B4AAAFE8B2B5D768DC33D8B +:10837000CCD37986A4C86326F930D1BF9FF64BAE23 +:10838000C77FE1CAF32E39963ACEF82BCEBF6D895E +:108390008AF568B74C0F9E43B1E0B1F0956B323C63 +:1083A0002D5B2239F4EDEA05192EBF87E1F5068F22 +:1083B000F128ACE3917D3F9D88E7A85CF6C1274595 +:1083C00055787E07E954404FBC2F19787DA3C1F939 +:1083D000775EDE20D1EDD3C17ED64B29E5EA8F9CB6 +:1083E0007FDE5871CB52843F26E900FF8955C3AE2A +:1083F0002F03FDB24209C177D34FC4EECDBCCDB639 +:10840000FEA45FE382EBD755B7F46BB796AF70D29B +:10841000AD4D657E81791D93C33B298FCE42FEEA27 +:10842000DE3E93CE7F249133652BEB4EE0EF4C2D57 +:10843000E6BFBF2F4677CCA4FAE694C8F224E657ED +:1084400098DE58B233D20CA9D353F557BCD44DFBA8 +:1084500079038CEF7E5BDFBF7D74F3D3B89D4E7FD5 +:108460006FC631A2C2FBD1BAD4F6E0DB7A06FF7B3D +:1084700062A1D1A05F6EDA98BADFFF0266A6F09C17 +:10848000FA8B54952A3E7995CEE05D1D49FDFE5547 +:108490007A267B0E7629059ECF0532B89ED3478378 +:1084A0009E5E9D06DE0F030184F79DE6FB6F823A18 +:1084B00090F75DDF817F27C0F8E26080F1F7A97D4A +:1084C0002B953CA0538BA0033FBC9D1D9A00FCB68E +:1084D000267602CFBB1CE0787ED3179912980EF255 +:1084E000B2686E1EA54BC72A12128CF4FAFFCA009E +:1084F000F31B7279BC96DABF77C1FED157DF45FF17 +:10850000430E8FBE71222B81823AF053A2B90EEB3B +:108510000CF7F9585D29094DB7FBF15FE6709CDA5D +:108520003F347A2F8DB8FCA03EFE5FBC1AE7DD9F7A +:10853000A1435DCA914AA9F35A0AE4C9FD19F87D1D +:108540005CB75CA49B7FA87EE0A9FD43F303075AB8 +:10855000F78640D1A0FCC073958FEC980672A4C634 +:1085600027A5D2BF969E3ECAE3EF6EFEB1AE5FE591 +:108570007CF47EA27FB8EED8ED84E7A65A273C961D +:10858000BCBC9F68F2AD013C91CE8976BF94CC997A +:108590003E809D65F9A974706E77E909E03CA0C33F +:1085A0009D5CDFFCB6FE91809D0EEEF59F12F9FEFC +:1085B000E05156973B36B2A622CFE8E5CF6F7D4E0D +:1085C0007C69D919F738FFD9F9D0B27303F1616E1C +:1085D0009A3CCE2438E84CDF5F23EB2AE4EB2705F6 +:1085E0000CD626FA3C38AA45CA78DD283146C3F9AC +:1085F000AF53FB7CF8F7A1CCAD9EC4582A02EFEF35 +:10860000BB7A827D3DBFE27CBA7A49367E7EE27DCE +:1086100031343F1FEBCE24FC8EDB1BC772E641FBDF +:1086200091C32268687253DD1A09D6F74680ED3B84 +:10863000576F7C1DFDC1A1F2F9EA5AA7FDBF8AAFB1 +:1086400023E967C93DD3807FD2E1E1358E87A591CB +:108650008573413FDFB251407DFB1318872EE4162E +:10866000398C7A9BC4987D241AC50735212760115F +:10867000808F7FE0DFAD9223AAFD9CDC6DDBEE9F57 +:108680000BFEA15B5E5664313EAEC86276E14D5F83 +:10869000F40FA0EF2DFDFCB6507B309F76D918D09B +:1086A000ADEF04A39C5AEBD9C8E1A27EDAB3F8FD82 +:1086B00062BE3ED2E3E237315EFD63C07F85867ED7 +:1086C00081CF43F53ED4453FEEC33A2A4BAE2C7FD3 +:1086D000C7FDFE3239EAF01B33B38A1CFEBBDB0F49 +:1086E000F99BBD48DDFF8AAC2FD65E5C9BF5D9D8DF +:1086F0008B619CCFDC762329D72DEC3CC889631F86 +:10870000CD4D25D7914F08875B9EDFDFE763DF4DB7 +:10871000BE2613F54EEF7E2A3F01FB65B75CC07E97 +:108720000ABEFBF1C8BE9F4D84BADE13DBEFBF2942 +:10873000153D67E9CC6F22DDF98E78DEDA00C1FAEB +:108740006F42E77BC236BEF55E525E06885F2E5BE7 +:108750007925EE27DF5879F5E835A57DF7157DFAFF +:108760000BD17F580AF336F2FDF40E4FD5BE54FB01 +:10877000408ED7BE7162A77FBF746379336CA9370F +:10878000655CF3A5688AF993FB9A8DA9E3710F7272 +:108790003D95DCD798745F43F1D1BD4A0A944DEB07 +:1087A000DDD7749B9FCFBEE677A4E7E73351FE5336 +:1087B000C3F73D8BBFD4E88E2B297CA7E8FEC70406 +:1087C000F911E97BC02FDF4ABD5F7B9CBFF7BB8DF2 +:1087D00043D457C79CFB9974F2F7BDCF48FEDAD457 +:1087E0009E51A0077EB7F7E3B7EE87F5ECF521BE03 +:1087F000DDE3447489EF2F7CC8B7967DEE5099FE77 +:10880000FFDDDF8DC0BF9BED960F42E2D75F459F36 +:108810001FDF274E81EF2CB6EDCBA84AB5CF59AF5D +:108820000B3CBEE48CF710EEDF2DE5FCA6EF7BBA27 +:10883000D61E8F7E93EB2B2B0EF0BFB3989D5DB2AF +:1088400060A10AF19EDB92F126829B15FDB2C2BDAA +:10885000F0FD8B5FF2F35CE6DACC94E7E37EC3F1E4 +:108860003B501C62C52A679C60C982FEEDCDC9449D +:10887000EABA2C8B9FD3CD3754FBD296185A5E6C34 +:10888000A0758ED007675F9692DA2F41BC631909F5 +:1088900029705D426A27FE98A2F2E4EEC508CF2F48 +:1088A000ADBF7FFCF1BD13ED7ECCFF0710F667274F +:1088B00000800000000000001F8B08000000000086 +:1088C000000BDD7D0B7854459670DDBEFD4AD24924 +:1088D0003A9DEEBC091D020818620742001FD02114 +:1088E0004482B2DA810041519A87184948A2E2CA0B +:1088F000FEBA438720467466C2AA8CBFE3B80D82D5 +:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17 +:10891000B3E846C7415E4322A32BB3CB0CFF39A774 +:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7 +:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8 +:108940005F4D628CFDABB579BCD3C1D859FC9B1E81 +:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC +:1089600036558563D4FB53AA8931E8E85FE1C14AF3 +:10897000190B2D50C33B94C1F5B2705CACB7785E57 +:108980006A30463FF2B9A04665113BA3BFB3F06F12 +:10899000CD9C245DF922A753F4D39A182C62EC885D +:1089A0001CF7513EEE91307F2FFBBB488C7B247C23 +:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3 +:1089C000B48AB9619C70A2734701C3FF8CD8264456 +:1089D000DBEF759A08AEEC48A689653076876C1B8C +:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05 +:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE +:108A000064C68E6E4BF4133CA6258747C13C2BED04 +:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A +:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2 +:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF +:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52 +:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36 +:108A600005A77359243D5A5E52ABF8C34583C77DB1 +:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB +:108A8000CD1D31D655EEB453FDF981728B07E0B997 +:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6 +:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA +:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209 +:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7 +:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51 +:108AE000D36D91DF33155E9C807ECA2E605C437D22 +:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2 +:108B000026F83F1800FA89F93D99BE7FC0DA1B7735 +:108B1000137F27F9762018B62FFF09A09DAD9C7D05 +:108B2000C75BF09A25A614D0FA16070E5412BB9D07 +:108B300079B018F1FE6DD5833F2985A91DB5065B77 +:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366 +:108B50001FA13CBD08FB639C6E67C2FF65333646B0 +:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93 +:108B700056CCD853D6C0FA64783FFAEEAFD73094CB +:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E +:108B90008EAD9BA05E6A0A97938CF9F203E335725F +:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B +:108BB000370E409EE6377786A34D4965ACCBEABDBC +:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB +:108BD000C10193A9A580BA35239DCEE343B0826B32 +:108BE0000AEE1F578AF2C7E24F80A954431B36157D +:108BF000E868862384FD957E38E719C4CF83B536AF +:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92 +:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1 +:108C20009E5E585FD25AE8270747B8B7AAC2CCD889 +:108C3000D3F89F97323E6180C55C45965F6C9B0977 +:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3 +:108C5000D312C872A6C1D236DFD7661FC658468661 +:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451 +:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED +:108C80005499015EEE4239FE2B6DFECB613D57DDFE +:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0 +:108CA000AA8A9130FFCB65F95FEC385F77926C0F41 +:108CB000F39DC298654474FEE62C18DF25CB9F54C3 +:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884 +:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE +:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837 +:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79 +:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8 +:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD +:108D20005E643CEAB181F218288FD794B378B96BAE +:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D +:108D4000CB03801BE993D483CCBF33865E1997E6AF +:108D5000A07EF627B290DD15E5B76B8187A7005F8F +:108D6000323B9FA7EC6790FE48E3729F85AE75216A +:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1 +:108D8000907658C43C0FF5876AA2F97A5465493544 +:108D9000F49791C8829DF0F4A4332A437B7FA723E4 +:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1 +:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B +:108DC000925B8B34F02CE2EB003AA07630CC33D3BC +:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A +:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C +:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90 +:108E000002EE15F7CEF919D66BE8B1301BD45BD35F +:108E1000599EC9CEA1171B4E5FC6C213356573C4D8 +:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2 +:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F +:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B +:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906 +:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828 +:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E +:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205 +:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA +:108EA000A7F5562BCE6D0583E775BF9C97D0A79984 +:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440 +:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B +:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D +:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA +:108EF000FBACB8CE86387CFB802B85DA651E8CA453 +:108F000078A1DE19617774754C4CB80CF9628E89C2 +:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6 +:108F2000CC8132C85B2FE26140FE46ECF668FD1F43 +:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C +:108F4000FEC4EE346EBF4D09B29876CBDFB9927590 +:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32 +:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97 +:108F70009C52CE23A7AA859CE2EFF783998FF53206 +:108F80003222E315D089CBDE9D380AFD99DBB2543D +:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9 +:108FA0006F944E6A98DDEB40B883D17416F5FE9C41 +:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5 +:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5 +:108FD0003FA127AEB5459E658583F95C9661FEABE2 +:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884 +:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7 +:109000002F62233E3691739AD9660B33DE24847E19 +:109010006A660713FC1A313568E8C0EECAA3792CDA +:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1 +:10903000437A213209F934C1C57476DE623590A7CE +:10904000A0DD9A69F3A19C013C111CF62730730244 +:109050008CFB363C116F95EAAD7B2D6EA403C5D712 +:109060004AD0DF2AFC5616417D73EDF424B25BD959 +:1090700099DB4756033C3C499C6EA11FBBE8C74E99 +:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF +:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B +:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7 +:1090B0008E880958A825E4997D27D4AF4CE26B1E11 +:1090C000E9E27A707F41484DC1FE46C13AE0D55B86 +:1090D00089C1A26647141F60E304117F1956783ACC +:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0 +:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77 +:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26 +:1091100030A44333E37696DF25E8A482C3ABE2DED6 +:10912000C5A9A837BFED999FCA8AA272F41E25E887 +:10913000F441FD7B2C819F52BCE35F5486FE883551 +:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B +:1091500043BD9F087FC772FA62F2B317BAB83C4B9F +:10916000C9AA21798E30F4A29FC2FA434E0DFE5255 +:10917000A798747E83E57431B5BF70BBA1248EDDE2 +:1091800050AAB31BE4B846FBE1D37559347FD9FE2E +:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA +:1091A000BA38513CBBE32E011FB4134231E765D5F9 +:1091B000BDFF14FCC49076FC237CFCE8B849C06871 +:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2 +:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F +:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839 +:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED +:1092000062A25751A2FA66B0BE127AC62017CF6783 +:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7 +:10922000A18FD1FF237665D9E541753CCACD2A854A +:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F +:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E +:10925000438A8AF28EF7D728E8A1E0D807562FC8AC +:10926000DFFF1276D017E9FEB791AE3624A614A31D +:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99 +:109280005D9C3ECA17AD6935C37B4B87E2B4318D17 +:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20 +:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3 +:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1 +:1092C0006EA92CC5FA7EF326107D391D0AC583735D +:1092D0009A01004007393EDEBFC31756961745D79F +:1092E000D966AA2E42BDD09691E443BD30D61D3C2E +:1092F0008CF4DF70281241304D3ED46346FBAEC281 +:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84 +:10931000ED067A070B59D0F9362E6F55F60E437CC1 +:10932000A0EC80F132D68F21BD24EB67B8849EC8B3 +:1093300060C117C8AE626D8CF0C5681D19EB47930C +:109340007D2FF119B5A3C64E403BAAF0818879194B +:10935000B4DBFD58ECF8BC45E81158074BF744D78F +:10936000118F2FA41E93F52C71FC6849EF4955B15C +:10937000ED53D000F4BD7C91FB3A5C77C3062BB370 +:109380002951F857B803E9389F9C8EAD0AC246D2DE +:10939000D706D7D34A2EACEFF65B985365F1E7DBDF +:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB +:1093B000FA54FA1317A773FD73A73B3002C76DDC8D +:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7 +:1093D0002FA58EFB290DB5F630AEB37C9199F057D1 +:1093E000BFC11A4679D4B0B33362427BFA6EE6430A +:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78 +:10940000E53684159C4F0610610FF979112BEA6738 +:10941000235DA33D8C76C95B099CDF4F943B420AD8 +:10942000C0EF8425D880F54E6427F942055178BFF6 +:10943000DD39EB1D05583AF9055B049F6DA66D59A2 +:1094400076A8D736CEEA433AAA700767A5037C5CB4 +:10945000E64017B64F7327FB5AA0ADD7C626907EBD +:109460001E221C261BE861F2DD9C4FFE263D45DADC +:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD +:109480001B189FEF3E977F01D1ABD345E3E63444F1 +:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56 +:1094A000CAF57A2167CA176D577EABA1837A3064FB +:1094B000905E72766E55D00F84EF2D956EAACF6CAC +:1094C000286776F2FD887AF87E9346AEC875C49018 +:1094D0002FB7217C1D877ADEE4F22542F427E76B63 +:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3 +:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE +:109500006E57306EE04EE276A39C9FACF745FA8C26 +:10951000F5389FC9553D0487D5B566C29B9C4FA5BC +:10952000353012FDAF76D1DFBE859F597BA1FCD0CF +:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7 +:109540005CE8972AC663AFE62609DBF2D201D22394 +:109550005777F138C1EAAE4EF37247944E0B8EED59 +:10956000BB11E96C75878D2528883FBE5E239D82DF +:109570007C21BA67212BED67817C0C913C65C1028F +:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB +:1095900046E56602D17BC1B109FBEC00CFD53EC5E3 +:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8 +:1095B00064FF46F8FD5AC8D518787E3E3D861E9158 +:1095C0007AB5E0F1190C9F127F660177D9EF9E748E +:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2 +:1095E00036B4D8C3C8D76FA75DF98E520C707259C4 +:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D +:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1 +:10961000E4F2A421E4203FB12158B382F61FDC0913 +:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9 +:10963000AFD50BDFAFEEE07C10855B5847B720E776 +:1096400008EFFB5C723F2258807005FFBD05E30CFC +:10965000D27F4F591C08257B07F36BBAF0DF27092F +:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3 +:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7 +:10968000FF41D04B7D6907F143FD97CDC4478E2A3A +:109690002E4F1C87F47290B11F8BF53F40FD54266E +:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335 +:1096B0003F4F45BC74AAB42FC5CE80555F06704D90 +:1096C000103010F52C6E1EF73EF1142002F9D2DC9A +:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7 +:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7 +:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131 +:109700004FBF27C1877143B70A962DD0434BC71B64 +:109710002997E1BED833974C40B999E7E67C79ECBC +:1097200045752DC267FD3F3C3F0DBFD7879574B48B +:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26 +:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451 +:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F +:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5 +:109770004FA4F39A141FAEA32168E6FBB692BE8DE8 +:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D +:1097900091F4FC85D8575A56E1684379F6C5A6E49A +:1097A000BA58F144BF582FC65C488ED52A144F6B67 +:1097B00003AAC1B8465B229B82CFA4A2883517C6F4 +:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9 +:1097D000268ABF61F016EC7F2275C6C683183C0C42 +:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA +:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B +:1098000026E234509FF44ED99AD8F1D02AB743D0EB +:109810002DD79B395DD5795E921336DF288D5D3A61 +:10982000EC60F32610432CA7AEE74A5CC75563965D +:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8 +:10984000B3456ECE4F194EE6BE14C6AF3433B703E0 +:109850009F8C7D642139B283FA05FB83EC2AEFEB00 +:109860000B77A03DB2C512CC9E84FDB409BDB59D59 +:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3 +:10988000A87D88B79FB5BD4589CE1728351FF51629 +:10989000F657EA403D13AA25FC78ADB4AE635825CF +:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6 +:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E +:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5 +:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14 +:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF +:1098F000122BD2EDF1757EF65B30401BC53EEB16A8 +:10990000A57725C5795E497062FCEEA4D037F50FC6 +:109910007C7E18F74747ECCA26BFFEE42B09B5D872 +:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A +:10993000007630916A23D8A9DC0E5EB119FDB3D54B +:1099400075CC87FCDF68A09FC65D07885EA41D5CA0 +:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01 +:10996000EC51AC9F3633DC6225FA2A2943FADAB788 +:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0 +:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6 +:10999000004980DB76B27BD918ABD0732BC85E6EE2 +:1099A000CCBADE477C669407AFB490DDD5E84DA411 +:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94 +:1099C000BE2C8CFBCABF17F093703C69E9B911E15A +:1099D00071F2252044F87EF54C4EAF69333B488E3A +:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F +:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F +:109A00007C80E33722F82922F440C46DD5C75B9CE3 +:109A1000A162D4BBBF17F8273182F25DC893D52B62 +:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0 +:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D +:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B +:109A5000401708B79CBA00D1C155EE9B7D6A01ED55 +:109A60001F909FD8DF6265B1E23C47851CF5A407D3 +:109A70004A31DEECC94C263BC7A3969B12B05D89E8 +:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D +:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C +:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679 +:109AB0003F44EE5F4838845B126BB5F2B34FC02170 +:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57 +:109AD000B227B85FDF4AE31F74F3784625AC0FED79 +:109AE000364F61600DD7A7C9BE58F0B853E079DF93 +:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643 +:109B0000F48CC141F4B7832B080F0CF080FCC082A9 +:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3 +:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145 +:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9 +:109B4000F58E46B80D559E9CB400FF23FF001C9077 +:109B50007F24BF24EFE67CB2A9C55B8EDF37553288 +:109B600067AB461F19FD259C27FA9D52AE8F7507DE +:109B70000A3D1807304536621E8594C38DBBEF1B26 +:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED +:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663 +:109BA000718878FDD0F222325097A3BCD996144622 +:109BB0007925E344C67EC778145D3C46FA2DB8BFCC +:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550 +:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31 +:109BE000398ED4A346FCCBFD115C4F7551FC7AED48 +:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06 +:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836 +:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533 +:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C +:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82 +:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8 +:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785 +:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D +:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D +:109C8000B588978B9FBA4ED76E86D9692E01B88E4C +:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A +:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24 +:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB +:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B +:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368 +:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5 +:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F +:109D0000037F84058D7DDC2BF84896178452B91E9D +:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C +:109D200070B9361AE640F019225F7F26F070281EBF +:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3 +:109D4000D45B4BCC1186F4FF9058CF169117FAC80C +:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A +:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F +:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A +:109D800090CF6B10BE5819D93981F498F1D2A52122 +:109D9000754878626A5E4C7D19B71F75F139F3C852 +:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF +:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6 +:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794 +:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7 +:109DE0009DF562B41934ED0F1AF8B826981AD36E9F +:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB +:109E000006D7779FC49133576798A43F6FA1FDC0D1 +:109E1000417CF7932B62C1777F8657C7C78B820639 +:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31 +:109E3000B1DDC3195C6EBDF8FF297F7E725332F924 +:109E40000F08378F66FD9FDC94541B2B2EF35A06A8 +:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD +:109E60007C9F77A413E343320F203EBD9A298E4492 +:109E7000305407C315F0E1B51642FFE68171226642 +:109E80001CC7678AEA59CCA9619A731EEA607A8076 +:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE +:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0 +:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21 +:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F +:109ED0002EF790E2526BED29C50CFCBAEF12F83365 +:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD +:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902 +:109F0000B99F383EC3FF119613C53EB035D3BA1181 +:109F10009FCCC9D7718958C74693371FD7F1A5E29F +:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028 +:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B +:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4 +:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853 +:109F6000C6F730F54D688743FB6B59F018CEEFA864 +:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031 +:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7 +:109F9000921E0BC59B2F612AC9F37A337B00F926E9 +:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F +:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4 +:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE +:109FD00060CB407ECC6246F931D08F363FE6F88CBC +:109FE000D8F3708B79584E27C5E93785DE1F1F716E +:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20 +:10A000007831FEF138F9496307FACF66A1746D3BE8 +:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8 +:10A020001BD2389DECCD72BA9742D74B59AF05E998 +:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59 +:10A040002BF96E04D6337F8176B609242DDAD94BED +:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21 +:10A06000CA6234DFC4716328AFEF14F3A63ACF217C +:10A070003717DB55BB59B3DE4371EC865B05FC0E2D +:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5 +:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB +:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714 +:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A +:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9 +:10A0D0003D07D065F6274D80E72121778C70D99D0B +:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F +:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D +:10A100007203E372EFE1CC11222F3CCD8CF270315F +:10A11000EF82DDE07C8BF693249C07C14FC0DD0805 +:10A12000C700F3DE8879DBE783674796FF6184CB5E +:10A13000D203895694FF37DAFBF7A38FDADB63FA91 +:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF +:10A1500033658A8FE751B09964EF28A15CF5ECC5AF +:10A1600043B77736A604C7207F7C29F2AEA53EDA36 +:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700 +:10A18000231DBD66E374F408F404E5A63D63B7A29D +:10A190009E79302B5887F5641E1FF3F78FC63C84D9 +:10A1A0000B8513FC59908ECE07A7273219E1E75093 +:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C +:10A1C00043C253EE5BC8F9D565713A944F093763C2 +:10A1D000FE505D9649D4E3F9880F660508CE7DC32D +:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2 +:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5 +:10A20000879A5FBD9C5F71ECF965660D0D7E01D686 +:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326 +:10A220002157EC79960D799E41CB0FA16F257DB317 +:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7 +:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291 +:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D +:10A26000BF42D011C0AB82E035A79FE2188746C736 +:10A27000960B15C6FA6D7C9C78E70BAECE528674B1 +:10A28000BE80950629FE576E774454C0C36D021FE9 +:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9 +:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB +:10A2B0004259738CF5043DC11BB3347E50FD53EFFE +:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C +:10A2D0006417E41757639F988FE00A903E40FD8013 +:10A2E0007A67E3EEA925884CB433309FA73F3991B4 +:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A +:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24 +:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5 +:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F +:10A3300006F01F07CF1D1E7F3BF6D720CED1283257 +:10A340008F6F205E61761EB647E13D54BC248A784B +:10A350001AD80D8F211D586D821F9983CE874BBB54 +:10A360008519EC1B3686FBB73764BDF7478CF76C55 +:10A370004CE12CBBF14709E4072E519C565C37D8C1 +:10A380001F9FFE1CEA0759E4D3BBC83F9476469250 +:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3 +:10A3A000996172D0FEE63E585F36C88D1956FE2C74 +:10A3B0009F055405FDCD50F3BA7B615EDFB2338952 +:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3 +:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2 +:10A3E00065737E7D31C2E57217C1A5F8959999DA3A +:10A3F00078CB40BC43AC635E682997A7063927E554 +:10A4000099C9CEEF11617EE6756650DC88C33DA424 +:10A41000303394AF90657452A07CB9409282ED6164 +:10A42000DD5788275B16CC423983693C381E787F1C +:10A4300059F86C9DEAF3E273BA1230F3798479DE4D +:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9 +:10A450001C8F9793457943CDA91B6FF20E8E633005 +:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1 +:10A4700051CA4F154F63BCE33B532884F9D977AADF +:10A48000619A6F128B447A303E61071098288EF0E3 +:10A4900007E403F06E1A719E09CE5391BB18E6399A +:10A4A000FA152CA71BF491C7B186F29E3D01B3416A +:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB +:10A4C000488904B2CEA69F3F5E638CD35866701451 +:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610 +:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9 +:10A4F000A837DA506FD82D7E8287D41FABBB6E652C +:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E +:10A510003C05796F436D117B1F5AB2A6EC1134CE06 +:10A52000FC7782373440B9E63D363E02F54AA6074D +:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB +:10A54000F51C50A99F26712E963167FD4EE87FEBD2 +:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7 +:10A56000BC9141747A06D607F87F02CB30EFA6156E +:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F +:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F +:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC +:10A5A000D74E827915F64C24321E09F531BF093396 +:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2 +:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD +:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8 +:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE +:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6 +:10A60000D91CD98B7C7D9978968827F2B51DE0B846 +:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF +:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391 +:10A63000E9485F4F6617123D5D6EF715260089B435 +:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0 +:10A65000DAFC81FB7A82050B806F160615718E3E3F +:10A6600058B058138F95797D0B6CE047C7DA77CED9 +:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED +:10A680007D655336E557F07C67E0FBDBB22745E597 +:10A69000088C4BF928F398DF82EB9A27F856F2FDE5 +:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE +:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB +:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847 +:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D +:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0 +:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0 +:10A70000F4535EE3026B782F9EFF59B00AD608F52A +:10A71000DF10E722DEC4731113A274947C5D4284BF +:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0 +:10A73000176A4B49F669F37336B53457623D99276A +:10A7400024CFB52C88B31FFC9C906B5B149EAF1577 +:10A750005A6427787B5476507B4EDF5318A03CB95F +:10A76000A66C2F8DB345C41130AF74223CC3608EEC +:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A +:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3 +:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39 +:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733 +:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4 +:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71 +:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8 +:10A7E000762BF65767D05BAB1C6F5A913F576DB70E +:10A7F00044E99161BEA1AF10055DC3CE41710F92D6 +:10A800003F522E19E9988DD4CB9F12296F412E709B +:10A810007DB598EB39F6A482F19FBEE423AAF09FA0 +:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3 +:10A830000FE89F29582EA6FA5406F93906F3472F38 +:10A840006389445F83EC0431AFD28179737B48CA5A +:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF +:10A8600084F7F0C0F33231EE9D267F5144413CB174 +:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD +:10A88000F54D61ED241727EF7F93E424E0F92CCAFE +:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5 +:10A8A00034CBF19019E1342BCB888F9019E13ADB4E +:10A8B0003B084F744EC01F074F7E2947985E8E1489 +:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3 +:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266 +:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE +:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96 +:10A90000D264D27351BDC8F15F264A97225D69F0C7 +:10A910007FC5AE84880AF45622DA5F8AF43021AA11 +:10A9200017232687D70AE36E547C6D6A0CBC67B880 +:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C +:10A9400043784DB177B49A619E87ADBE9FA3BF5245 +:10A95000CEBC84F772837EA970D498913F2BEC46CD +:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F +:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73 +:10A98000897723BE25DF7726382B1C18D7ADE3F94E +:10A99000C413DF1FD98AE58CD50574CEA533CDF756 +:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370 +:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3 +:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0 +:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A +:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011 +:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB +:10AA00009BDFB227927C1276DA34B1CEE98FF175F2 +:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E +:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9 +:10AA3000F00DF43982E79B6E83211ECBE17686CC44 +:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B +:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE +:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348 +:10AA7000497BCDCB60DC92B37FB832967FFD8418E2 +:10AA8000F788C87F97EFEBC20526F43F3A9178E844 +:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990 +:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8 +:10AAB000EE3DB9A68745525306CF7F96994578DE7D +:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2 +:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65 +:10AAE0000BECCD64172E12F2FD1616A638C52D06F6 +:10AAF000FEAE777CF399C984F1303D1FAF86E970D3 +:10AB0000BDD0FFF82700FFBA47929DA8E75777E826 +:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC +:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22 +:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B +:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9 +:10AB50003F8744EDA943B3C3480F25827F251F9744 +:10AB6000087D3E485F5719FD9887883F268A928462 +:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11 +:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2 +:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08 +:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7 +:10ABB00037E22B9E5D3F80AF04B09792D08F67C481 +:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4 +:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA +:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF +:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A +:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632 +:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7 +:10AC2000B83897C7B9978867B9781E1179D8475C43 +:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4 +:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A +:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44 +:10AC6000719657B85E6834F75A31BFE41A77702A84 +:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0 +:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0 +:10AC90007AFB6EED25F93050AEEE25FEBF2637402B +:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8 +:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A +:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4 +:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554 +:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4 +:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021 +:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F +:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520 +:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C +:10AD3000B3D502BEF1D683E707BC1AF981E707BC99 +:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18 +:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7 +:10AD60006A63CEB0979F27D0B6C7F304DA329E2726 +:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5 +:10AD800078AE40DBFEE677276621DD7425F03C32A5 +:10AD900016F2F714015C5608B8E079036D7FC753CB +:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA +:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292 +:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A +:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0 +:10ADE0003957E421E6B01C6D9C264A070E5F04D754 +:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5 +:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3 +:10AE100090E0D5D343D2183D3D24FBF4F4903A455D +:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C +:10AE3000FF207C27E0CD9018578275629CF72F0584 +:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737 +:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42 +:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF +:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2 +:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99 +:10AE90001617DE1B685C2FDA514C134F32EA7FA580 +:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC +:10AEB000455EFCDEE1B7E579681C662FD3C57B6390 +:10AEC000DA73721E122E727C1B6B56B3909EC718DB +:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE +:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0 +:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C +:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F +:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A +:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3 +:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71 +:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520 +:10AF500040196CEF37B01EEACF68DF0FA293F3E819 +:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4 +:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169 +:10AF800066B8C08F51310FC36B8D9527C5F0721510 +:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF +:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA +:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA +:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160 +:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C +:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC +:10AFF000D882F5871DEC3DACA03C7378293FE4E492 +:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF +:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005 +:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4 +:10B030004B851F307978E0216C57FA615E0ACED7D4 +:10B0400032A283EEC5EABF83DBC16E95CD44F881A1 +:10B05000DEE37ADF61A67D077752484D413B6E29DA +:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8 +:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4 +:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A +:10B090002037D8F8BE7CC15F27450A81DF5EB7F252 +:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC +:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA +:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13 +:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164 +:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45 +:10B0F000E0A1D103F78379302FA431C19FBA10E3C7 +:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94 +:10B1100011F6C34991F7B966F68C4CF42FE2E54B72 +:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7 +:10B13000335F42F72E05CE55EFD53FAB31E1795A5B +:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9 +:10B1500079A53C939D235FBA11EF23D7E4D7A09F35 +:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6 +:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D +:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F +:10B1900099378CCBA7711E7300F7252F8EF07B3F5C +:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB +:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5 +:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B +:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4 +:10B1E000E190E00A06D11E91F715E37DC63CCF231E +:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05 +:10B20000A4DC39FA884A72E7E807821F99DFA19423 +:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225 +:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A +:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72 +:10B24000FDB16FD903A4E7563C60D467012BCAD97E +:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5 +:10B26000BD6BB47F670C13F66F192BBB90734E8FB9 +:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14 +:10B2800097D3C36D3BFE60C59F048AD7EF319017FB +:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69 +:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F +:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A +:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A +:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F +:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6 +:10B2F00089DF4368B7F1FDB9F0D353F7613878645B +:10B30000C7E619E86738BBF746302ED166E2FBAFD7 +:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2 +:10B32000790FFD6D2AF0973835FD33612F350A5CB2 +:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478 +:10B34000C5BFC6314E3732BF847E1B43132F3A012F +:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE +:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A +:10B370003D03E3FD529F5E8FF96D18071676EF22AD +:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904 +:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6 +:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417 +:10B3B0003E99CCEFCB51FA476327C73006521ACDDE +:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC +:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5 +:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2 +:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9 +:10B400009B4FF200E49702BA73CFB04FAE31E3FD29 +:10B410002039604741F9F82F0E5F83BFCFD238A2A1 +:10B420007725DE179EFEF8595E1ED77B18CBC31E0C +:10B430004FBC96CA137A57AA509EF278D6B5D41E3E +:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF +:10B45000F5D23D418DBB2F3269E38325F95C4E1F48 +:10B460004BE0F58E15B0257311DE637A476B7F379D +:10B47000C1932FED526E97C975CA762C2B76FFEFCC +:10B480000B3D708BB8DF677A126B4BE0FB1521B474 +:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC +:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC +:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E +:10B4C000578278037C9905BECCDC0FDC4A78C67EB7 +:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44 +:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA +:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6 +:10B5000019C043A642FDB70AF8E5F1FA17BADED32F +:10B510003FD07A3578F263DEF19BBBC6129EA60C53 +:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA +:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D +:10B5400044E407796F1B0B4D2367BD41488B817B1A +:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742 +:10B5600014EB736AEFA51BE0C38FFAF36B34F75249 +:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B +:10B58000BE88878F71F97F617CC8791AE0390067BE +:10B59000C3FC243C918FA95D919E9FE43C87E59B71 +:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51 +:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216 +:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F +:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829 +:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8 +:10B5F000F97934AC56C53A0F181278907654A3D026 +:10B6000037C79EBEFF1A84C77FECB038518F363DD6 +:10B61000658BD8280E720BD95150FE9C97EFFD1AFE +:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF +:10B630009AF08C0B8BE43278366EB7F8226E1E4F80 +:10B6400084615813EBDF88F333B6C7799C06BC37A7 +:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742 +:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14 +:10B670004BB8B0B087EC9AD65FFEACF87307DEA784 +:10B68000F94F294A91565FAE27389DEA58FEF7BB1D +:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C +:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB +:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2 +:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F +:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476 +:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60 +:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF +:10B70000E81E8565160C6E5FB7757F0AD21FC209E9 +:10B71000FD4B89A701BC0DC257E49ADDA5548FE209 +:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB +:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4 +:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756 +:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76 +:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE +:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3 +:10B78000B3E18F64B0AF30111DF3083F50459EEF19 +:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A +:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C +:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62 +:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3 +:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B +:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14 +:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99 +:10B800004B048F163786F7D628240F6CBAFB9F0699 +:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745 +:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D +:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A +:10B84000E619D2BD320D96F0938F22FF02BFA29F60 +:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C +:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0 +:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE +:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA +:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E +:10B8A000292F195E41A581A3849FA4C755CFACA6BB +:10B8B0007106E856D2A5A4DB01BA1C945FA983A344 +:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA +:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03 +:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07 +:10B8F0004C8DBEEF4F10790381FE94348D5DF47949 +:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74 +:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65 +:10B9200068599882F18CBEEE42FA3DA19BDE057FFC +:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642 +:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3 +:10B950007EA0310E7233E641611EF263FAF7AB301E +:10B960003E827832D05310E9297B303DAD1C2EF653 +:10B970005F4B58896EFF55C8B54AB5E8A7689FF474 +:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B +:10B99000843C44A7F5C12332CF8AE85AD29DD17F97 +:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B +:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8 +:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7 +:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD +:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033 +:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA +:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD +:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9 +:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0 +:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF +:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4 +:10BA500018F9D553BD7FBA36E48805170E873E80A6 +:10BA600003AE0BE042F775C78347D7707E0FFFFF29 +:10BA70003E787C4DFE4243F764E2A3285C14FEFB53 +:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F +:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5 +:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949 +:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50 +:10BAC00007ABA359F3008000000000001F8B0800A3 +:10BAD00000000000000BCD3C0B7814D5B9FFECCC76 +:10BAE0003E926CC22604084260F2244A1E0B791072 +:10BAF0001EA99B842008E206A4A2222EF8E015923B +:10BB000008B6C66ACD622202F5B6516CAF6DD16F30 +:10BB10004141DADA6B8A41B1025D10115AAAAB8257 +:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30 +:10BB30004CB233243CFCAEDFD7E423C733E7CC3927 +:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1 +:10BB5000B1056806280648526D00FD004E6CFDFADE +:10BB600090944CAD5D853480BAED710045D8FE31BE +:10BB70002600124064DBA9129F13E01BFAB912A041 +:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443 +:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F +:10BBA000433EC0B6D606BE565C2F120F3337213C3B +:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2 +:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB +:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3 +:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625 +:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D +:10BC00005095E1EBC67B870DF208DFBDB3697E641A +:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91 +:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8 +:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280 +:10BC40007A0F42D01F4006F123272F9C0209D4AE61 +:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C +:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE +:10BC7000B70EAD71AFE215EE042801F881435BAF5A +:10BC8000FF948912AED7B40CE1C2759AFA595C4D93 +:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3 +:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E +:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0 +:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02 +:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00 +:10BCE000A1138083DE57E8BF08FFE45521D2430546 +:10BCF000147F58E0237D23113DDD290E5CCFDAE768 +:10BD00000EF72A899FAB4A89F69E85FE2C31D01703 +:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9 +:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB +:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE +:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A +:10BD500020A71ED7A992C785FDB8FE89D238B79D06 +:10BD6000F44582A03412DBF2FE15807874A4DA1454 +:10BD70006ACB3A11A72878AF3CED00250ABF72487C +:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E +:10BD9000F4BCCA956698FF464C423E14D07B1326ED +:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2 +:10BDB000C245241C1D7B675510BD26A9230CF3B674 +:10BDC000A059217DEEAC9203EB901ED552B07F3E80 +:10BDD000D26D72CE68237C128C273C6B2C285A388B +:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C +:10BDF0004DC357A0F40518DB70169442B4E3C15646 +:10BE0000C3FB857BB618E627EC03391EDB11FBD597 +:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F +:10BE2000D85B89E840C991FA57A86D70203DF0F9B8 +:10BE3000A918D122BF58CEFD8762024D08EF294BC9 +:10BE4000C04774B85B0EE4501B3BE88E7C48073853 +:10BE50009AF2B0DC87E0075FA78A7230FA8B401352 +:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3 +:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6 +:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7 +:10BE900059E596345CBF39C5D3B283EC66C587B328 +:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4 +:10BEB000511EE5F8F10EB2EBB19532E30557590387 +:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE +:10BED000AFD7A409FB10FB175025843FB6AF4FCE58 +:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0 +:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6 +:10BF0000A6580259B864C241F76E2BF657E7EC7792 +:10BF10009119689B72D82F235DDA0E86CA24D4A5A6 +:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B +:10BF30008FE558C8CE2C41B347766647D93339E4EC +:10BF400027965C7EC500E8C1BEE96DC26909D4C20E +:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2 +:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302 +:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB +:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00 +:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9 +:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62 +:10BFB000DAD0781CDF4836518C0701E57A954D1BA5 +:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D +:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA +:10BFE0004F3BFBE55513AC01BB7431748DBB005D59 +:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5 +:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2 +:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3 +:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08 +:10C03000F59F39CD24378A276E24EE53E7FA8AED2F +:10C0400041959CDB87E29D2E3A923CE39E3FB5747E +:10C05000F7C93E2474D3D59389E3ABA2E8EC709082 +:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA +:10C070003527428B05F5E1A46BC3F7491E4E6EB41C +:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4 +:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0 +:10C0A00086F54E8E7B37290FDF3B99AC24117D1628 +:10C0B000866D4CB79B1508DAD15EB625DF5659CE92 +:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743 +:10C0D0007D8278499E31F237C37BE71779D04F7460 +:10C0E000FB8874AE2334937A9783E6724780E2CC60 +:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F +:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18 +:10C110007C86CAF640513C2C0FCA691B8FD7349CD1 +:10C12000643B8EE0A491DE742C13F6AEC50AB754BE +:10C13000635BF3BFF22DD538BF06430CF617B0D3BF +:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8 +:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D +:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF +:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262 +:10C180009FE63A40FD0FD31EA95606623F5EC8C126 +:10C190006FD26AABFDB9245F4EA6CB891571AC1F77 +:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E +:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C +:10C1C000D344FCDA1F79538AFF5E45BD77201D9268 +:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2 +:10C1E000E6BD181394901F8B9F78C546FE68AEACD1 +:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B +:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4 +:10C2100062A3F1F9A01C26BF614161A6B866A173B3 +:10C22000978DE2B2854F5B0F87A3FCEA22081F229D +:10C230003DAD79D67A381CE57F81DE8F92AFC3168B +:10C240000187A2D163AE1C9A6D13701D20B816270A +:10C25000617C2F93BB08F5F7715C5493C379494A0D +:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48 +:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD +:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7 +:10C290002D128FEBF6A27B3C5ED025D733C2827085 +:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC +:10C2B000716B7C71135F74FA233D0B157C6FD7593A +:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3 +:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F +:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3 +:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965 +:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E +:10C31000A11EE0541A5E32E0A3842A28898071E9C4 +:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED +:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5 +:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133 +:10C3500070392C30C4C9958E3B0DFD2AD73D86F926 +:10C3600057A52C338C4F52571AC627E73C62E85F1B +:10C37000E3FEA5298E5F6B8AE37F63181F170E719A +:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E +:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29 +:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF +:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9 +:10C3C0007764F87E928EF47BC312688A473A8D6A4E +:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D +:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6 +:10C3F00030250C1E8A7BD03DF7245F2DE916964729 +:10C4000032FB807A37D301D664D4B79933257713BA +:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D +:10C420004AD09EC0A0791D08E70C0126D8699CFC63 +:10C4300077725F85E2D6EBE821C22B7B64F81E3E63 +:10C440009F51FA97339437DFE86CB5929CDCB0E7E4 +:10C450008163F7E23834FB8B493FBAE206FFFB9673 +:10C460004B891B5A28AE443A462477C843F14EA262 +:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC +:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E +:10C490002E25382C81FCFD239534BF66BFCA74D18C +:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802 +:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7 +:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF +:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B +:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB +:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714 +:10C500008B50E50092BF17D3451D071CE59C478063 +:10C5100022DA8B95939A9497453C65920FB35CE829 +:10C52000F200683724A4D78DE867C93FDC04FEBC5D +:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4 +:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75 +:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0 +:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3 +:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6 +:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9 +:10C5900014072CD826333F30CF540622DFE6697CBF +:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3 +:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89 +:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED +:10C5D0003119F1C99FC49142C128A207C2EF0E923E +:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E +:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0 +:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01 +:10C61000FF96938D44B8975738029468478A5D0A0D +:10C62000ED1F913C723CF1E323702F43FA956F7D2F +:10C63000ED20E947B9C3C9E708884447343F47EFCD +:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1 +:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2 +:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4 +:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7 +:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA +:10C69000CA7268D7F2497B8A053C517474D97C1BF5 +:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908 +:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1 +:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5 +:10C6D000EC318ED4DB3A8B38371859A91652FE4705 +:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8 +:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691 +:10C70000EF5FB7ADD83537AA0EB226433F5F505C16 +:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147 +:10C72000DA540C7324D4A13C2920E20810F1C42C63 +:10C7300008713B1B3AB9F5A124513B17DCDCDE063E +:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE +:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF +:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711 +:10C77000CA1F93DD8E8C40FB807046368B73B148A8 +:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D +:10C79000EE37B85EB84FE6BAA5D97E5429228F0786 +:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56 +:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347 +:10C7C000E52F535D223F9CEA80E4D364DBCE9ECC10 +:10C7D0009D8186602AC5A328CFA3923C7F227AFB45 +:10C7E0001F1A97C8E70F647F8622FF3E12E736B014 +:10C7F000400A64213DB6B4897EDEED898CDF4D10A0 +:10C80000643EDE0C612BE17F0B00DBDD39A0727B27 +:10C810002B78989FB8725C3EDAA1DBDB9491AB1069 +:10C82000CF82A4CE74D2CFBCD1EF254908573EC5E4 +:10C83000BF4EAECDACA03845C7C39229F0B82CD3BB +:10C84000F336C15790145AB59AE2C2CD16A0B8F08B +:10C85000D3D1F7DC01517EB524ABE220CD7B4E1263 +:10C86000E785FE6D76515783CEFEDEA878FCEBCCD3 +:10C87000CA43A4F7FF20D838FF5DC5E748D52E414D +:10C880007B18DF8F6980EF0DF1E6F5A49F7EB68FF0 +:10C8900005444B5127F44329EFCBFDAF9EFAA2BAD2 +:10C8A00059E0E3A778AC24CB17A1FD0A6C680A090C +:10C8B000FE27EC81751C37D50FA1FAC5BC27ED16F4 +:10C8C000F2E3EFA11DA673D30F1A1DDC7E88F90DCC +:10C8D000B57FC3FC86DA8F30BFA1F6EF98DF507BBF +:10C8E000FBE9112844003FCCF4FC6FC679F0E8DD89 +:10C8F000CE083C2212CCECE9BCEF5486C83FF2DBF8 +:10C900003E7E208EE4608BEC2639CDDBAC701DE2E0 +:10C91000F8D65101392D9AAEBEB84C84237FCBDBBB +:10C920008F8E2DA2F7149784F38F6F39D99FF3263A +:10C93000137C5DF4D86613F4D0E07D2E31B48ADE2A +:10C940007F6E733A41887604841C123F7BA8A30152 +:10C950002C633EBE9E21E2A76BED9D45D1E79B4037 +:10C960002103D52B353F53259F4D08E76A75DBD151 +:10C9700024D7996FD07EFE3D420F91AF86BA44A571 +:10C9800026877A9BB7CDE6257D7A6EDB3BD32623BF +:10C990001DA68E99542CABDDF30B33FBF1BE79A3AE +:10C9A000CFFC6A7532CFE7738B1B606D950BE7DDAB +:10C9B000E4D8F12A91E066D7475589D8BF2545DAF2 +:10C9C0004DED1C356D4212D90108F03EB7E694EFEB +:10C9D00026119BE2AEB6915F2E27A58AB2BB958E3B +:10C9E000383A49EDEA57B9FA1AFA57A50C32CC9FF2 +:10C9F000A46618C627E70C378CEBFB4E71171AE6B6 +:10CA000091BE52DC8C7830DF61BDCCE732799BBFC0 +:10CA1000787F11E37F4311E11F41FAD930B03852DA +:10CA2000BAF217ABC96C6CDE99C0E7B4A6F8B4666D +:10CA3000DB53BB3D6AEFF1E997B0B5C7B8AEB69727 +:10CA4000B8EE62E353B41F8F92FD2878E13A3E7747 +:10CA50007F6EF499CB54C4CB9789712BD93D53DCAD +:10CA60001AD1E256B3FC74C9A9A40AB9D92B03C5DB +:10CA7000417AFC6A961F800734FF2FDA4BD5F3A961 +:10CA80006F097FF50FD2F7BED172ADB5A67A44819A +:10CA90000DFD0AD509FF2AC33A7A7016E1D0E99F45 +:10CAA000D12DF770DBDA570716F1737F3C6E59AB67 +:10CAB000D5277E95A99DF3D7EC78756072F738DCA1 +:10CAC000F591613EDC27ED36F49BD38CFD87CB7767 +:10CAD00047BFDF9B1D9AB7E64E9B8FEAD28F893AFC +:10CAE000A5795C87A76A678C87ECA5B2D5CEF9508B +:10CAF000ADCBC3F513A597FA896E176E90A1BE272B +:10CB0000FBB65E5B77CACE1890BFC5BAEFA1AC107A +:10CB10003CFE17859F79AF8F07BC51FBB4668AB87E +:10CB2000EF5862CB8FBFC279C75E023791FE58A221 +:10CB3000B0B7F96D9F5A2CE4276285BCE4BBC2965E +:10CB400024BAEF323FCE4FE7C9750BE2FD746E5445 +:10CB500090DEF98E0359BFE569DFA30E94BBF72D74 +:10CB60001683DF8990ADC3FE8E4CDF34F23B9377A2 +:10CB7000C6042DDF029F1D9920FC5A85D0F7D924C9 +:10CB800037FAB9189A9ABA07C1704E46F853FFCCD3 +:10CB9000D3B7BEF518C5BD7B85FEE3B0D39C8FDE51 +:10CBA00014958FC21AA1BF0EFCA53867E1AE161B03 +:10CBB000E549DF95DEB7673ABBF57BD8B9FAACEB50 +:10CBC0007BDD01A1EF27B67EF916D9F513E8EFA2B8 +:10CBD000F5BDCB2F6A7A5EF7B8CCFAA83F3FBE55B9 +:10CBE0009E18E881BEAF697200AE6CC3B9D992B22B +:10CBF00053D3C8AF2DD9A6F079606FFEBA6E85F118 +:10CC00009CECB9EDF6F9E21C59E011D1FDE9B62F23 +:10CC100093CA7345BB8CCF6B5B34BB23E218F4A380 +:10CC2000D664F2A3D512D7DF0E6C1BC0F7330E48C3 +:10CC3000105447F212D739906FD3C572F4DC49F122 +:10CC400018A4E428B4CF348D9FD3B5BAD08C6D33FB +:10CC5000B2885FEFB4CD3DE021F4B232587EAE072A +:10CC60003FC7830712BDA9744F616A9390EF038990 +:10CC70009D1D54473A501627D17914AEDF1C1DEF85 +:10CC80001DB07A53EB192FFD7CF20AF99BB84BC803 +:10CC900083357B88FCF44B229F63F957063ECC72A8 +:10CCA000B50002BB3DB86FAD3BC871E9221079BD3C +:10CCB000399EAF1DF7998DFC8239FF2CDFB2E3203E +:10CCC0009D7B9C538730C9EB85EA0EE6BCB7B7FA6B +:10CCD000C1A8246F615654DDCF1C9F77C5A17A1C73 +:10CCE000B53E8ECF855E29FBEFE38BB07FD7FA3858 +:10CCF00017E5D9479FB4FBC92E1F5D670F48387EE3 +:10CD000034A9B39DF28EA39BF2DCB802CCB3A8BFCA +:10CD10007B96FCFA6FAD2C1700C67B0D4BCAEEE676 +:10CD2000FB7F4BD6C74B740F0752C4B89EF3C9CFD5 +:10CD3000C4735CB0E0F9817CCEA9FB17D20F3A979F +:10CD40003EF2448C8782FCA37BA6F7A17A5F87E53D +:10CD50000F7C9E0FF27D87E8BC7ED186F891143F50 +:10CD6000402E30DFE6AFBB9CCF377FAEF86610FEBB +:10CD700095CF5C3380EE952D78BB1F103E91ADCFE3 +:10CD8000F3F95F779CDE737C77626B461FC8EDA674 +:10CD9000935E075CF1F4322FF1BD5852C5390DD4C2 +:10CDA0007B06915C6CA9065A77A42CEE8D76AE8C2E +:10CDB000E3B8D42C773559220EACD1EB0D7DC1915F +:10CDC00042FAE303A64364E5F075741ED69C95A46D +:10CDD000F9E9CEEC6951F712ABE4F6DA97493ED7A0 +:10CDE000D8B90ED211D3F33958435622CF9FE7302A +:10CDF0009E9BD7369C31F67331BFC3F74736A98562 +:10CE00007762BB54A3FFEA54EFBD59F8FEC2D64780 +:10CE10005ED8C77459F3C3F769DF3D4E517FD927F8 +:10CE2000E8678EFFE739449D03602DEFAF3FFFF4C5 +:10CE30008977F97CF5D3CDC3B3C5B971E8935FA702 +:10CE4000F179F1A17BB1DDB4E72DE68B19DE73CE6C +:10CE5000FD2489F1AD213CFAD2F9AEF71182131904 +:10CE6000C179DBDC55794C3FFDFC2D72B4E7FC4405 +:10CE700087535F5F874F5F5F9FF76496C863666BFA +:10CE8000F9C1315BE8389FA3BF305CA2FA5ED7F3EB +:10CE9000A4507E6294BC7C57F5F41BB57AC841CB94 +:10CEA000B21FD8E89E5CEB6AAB2FDAEE5D621DBD67 +:10CEB0002B0EF480EAEA2F5C09FB2D444EE94FE784 +:10CEC0007D5A9F9401FBE334F0248287EE0D6A2D96 +:10CED0002CF4A5709D9CD693E91A6280FB4DE56EFB +:10CEE00095DA2B25AF22EE7D0558FE2740FD60C266 +:10CEF000C3E208F3B9987ECF6546E2F26BD270BF09 +:10CF0000E67EB09CE29866ABD00BFF9C38CEDF7417 +:10CF10003AE97E065CB906FFD2EC0255C175662A75 +:10CF2000B0C29A24E60D453A1FD833F7558A13DE6E +:10CF300055EAFBD1BEEF391FCB932C14DF05E22954 +:10CF4000477CFFADDF16FF15E77E009E3227CACF74 +:10CF500075AF39D8EE9BEB11B7838FFBF3206CFDD7 +:10CF600002DFFBDBE87FADDF09DD78FD6DCC579B91 +:10CF7000293FB829F181627A5FBF8769BEEF77D414 +:10CF8000E5E47B81E67B7FD782EF33B25BA72CBEE3 +:10CF90005A51FFA81F45FE3792680309E747FA690F +:10CFA000F438064C8F88557BFF7395FB459523B964 +:10CFB0001E09A754B6C7634DFEA668B845E461DFF5 +:10CFC00088F9659D8AC1DF141568759BAF558E4B36 +:10CFD000AF3CAD9CD71F3D942DEC59515F4B7D4F1D +:10CFE000F1A19A2DF4A70982B2C047C40963BBE43A +:10CFF000CA2313FF6AB57E2DF93394A74882C34F25 +:10D00000171DC76E15F2355609EEA016AD2B34501C +:10D010005CB105FD9D0E079D11A60C673918A3CBC9 +:10D0200027AE350BE72D97EA396F71503C83ED2A17 +:10D0300029C4707C0F3AB9F5687EBC02DCDC8E072F +:10D040002FB7289FDC4E84166EAF86566EA74048D9 +:10D05000F8FD2B824DECCFE03E179F5B4C9A67A109 +:10D0600078A3E8FA9EF3850A8D4EBDD30115AEE490 +:10D07000D2E9300150EF327AA0C7E01CB61F667AC1 +:10D0800098F5B30CC232EB2719860CAA13A8ACA7EB +:10D0900095E0E17ED545D2A134EC53B84E63A64766 +:10D0A00065CF723159A3C7BFB281E543E7D3FDD93C +:10D0B0002A3FD7F9857A9542F26FE6A3FEBC28AEE7 +:10D0C000E2245D4DBF237BF874BA57555458B19490 +:10D0D0004CF2DD1BC64CA77B5545632B9EA723CF87 +:10D0E0007BB2C7897E4145A1D58D598B54367D3C95 +:10D0F000CEF769F79261A688AFEFD2E216DFB21FD2 +:10D10000B85DA827BE54A79BF07360704FF759E431 +:10D110000C713E38646270A715E71D527C73B2290A +:10D120003E70041354A4FB5DCBAAF8DEDA4336311B +:10D13000DF6E1775581D2F7CEE8FC1FEA64DC3976D +:10D140004AE9BDEF8FEBD6D2BABE65597ED257DF22 +:10D1500066C92D3859316026EA6747C80A540FD589 +:10D16000F7C94EF52DCDE673DD6CAE930DD2E29985 +:10D170008E4DC387135FEECFD6EE6125A71512DD66 +:10D1800096A57AEFA7F99178215FF76B7CE8ADDD82 +:10D1900090EDB92FBBF8DCE7917F2000F8FECFB20D +:10D1A0007D0FD07A757167D9BF1F1FF1F6F2705AE3 +:10D1B000B79C4AC8A459887793070236F603DA7DEC +:10D1C00075EDBC2A723BAE837428F2FA9AC8A48D1E +:10D1D0009AD55942F613D7FD2F5ED7161E3202DFBD +:10D1E0007B6CFA219B90B3C142CE343BB46DFBDE25 +:10D1F0007B0789AE17A2F4AA6EFB99AF3E40FAD521 +:10D200009D70BA697AB73EFD7229E793E034D80D74 +:10D210005DCFC66CB1735C3D76EBE5B7D3BCB2B7FE +:10D22000DB3308AF2BDBC37C0E16D9F6EE2001876B +:10D230009E6F9C92BE8DDFA5735ACEE3368B73DA58 +:10D240002552FD2BF1D4FFBDE4F623FC9F6A7E43FB +:10D25000CF8BE76B782DDEBB7E39D545E6AFB97550 +:10D260000ADFE30988BC41C55FD2FF2F611F9F8F92 +:10D270002FDA68CE273A6DC4FFC5ADA6FB40940FE8 +:10D28000D3BD8768FBDE433EBC3D5B3BA74D855469 +:10D29000C6439ED5C7D783BD33E7BB8F83E755967B +:10D2A0004FF0CAB47FB1D2733DE1B9EEEF69581FB8 +:10D2B000E6697B139D9C9CEFDAC47DE12796BA5DFD +:10D2C000D4D7F4732DCA4A29C5D19DBF64F9D7DFDD +:10D2D000D3F575C10A712F1BD6F465992BD860F769 +:10D2E000105F0B360CE0FC02F3208EFBD66EB0AF65 +:10D2F000A07ED383B17EB980EAC99D97515DA529EF +:10D30000467CE744EE91EE8916A48B3AC719DDAE50 +:10D310006B7E5DBF6FDB95FFC467F3BDE6AEF1B01A +:10D3200062C8379AB4F8B988E0A338B0DE2AF2A709 +:10D330001801FF8E37BF1F4771EC66C51B4775E9A3 +:10D3400013FBD3FB400F74D3DB62742F709E73C644 +:10D35000E277A7649C8F5F458F6BF7D335F9FC6349 +:10D36000A307FE6EEDE6878E5795FC6CA58DEA1C33 +:10D37000B7818BEA1E4BF63ED544DFDB2C59095CA6 +:10D380005138417F285F3862E173F0317B0B53489D +:10D390001EDB347B47E7C26A945C95505108E7175F +:10D3A0000F86007D7F14A3C6821A9517C7E524193E +:10D3B000FAF1EECB0CEFF7294D378C83DF13CA2D32 +:10D3C000E98E5F133D5718E63F943081BFC7290BA4 +:10D3D000DDC175A5BE13471AC6ED28D774CF01BEAF +:10D3E00010F14F29FEB25F857A99E01C1B06F815F3 +:10D3F000CADD980E637C541A6EE13C3066BF62C889 +:10D40000EBED17A8335D3E4CD3ABC13058D8073392 +:10D41000BD8DF72196EC95398E5B928A81675AEF24 +:10D42000F4D6F54FA77B3FAF91EE03661AE93CD0E7 +:10D4300067A4F3A0F9463AA7D61BE93CB4C148D784 +:10D4400034BF918E192BC618E667B55418FAC31E5F +:10D45000BFDA30FFF2C034437FF8C61B0DF3F35A36 +:10D46000E71AC60BB62C3C2FDF47049718C6CD7CB5 +:10D470002FDCF323931C2A4CE762EDFB2C9DFF7EEF +:10D48000FC25FE8F056F9FA044E5407F13E9E3FF75 +:10D4900017FF170CD3CE1174FE5FA45DBD4AF3C312 +:10D4A000E6EFBCA6C6097BF3FA9E13FB3DD87F438B +:10D4B0002DB4A650DCA4C5075EFD3CC294F7E97903 +:10D4C000CAB5A592E99C3EC6704E7FA17B6DC5A1F1 +:10D4D000A0A13F62BFF83E6AE441F72BD4167FEC6F +:10D4E00091A3BF871AFD05BBE573F24EFD7E9C9E9E +:10D4F0003741F3939C87CED2E127252839B7BEA8C0 +:10D50000E7A7E6BC55CF57CFFDDE4AC42577CBBD94 +:10D51000E5B1227FD5F3D6EF8387BF2BBB6AB06F0F +:10D52000ED30B4FFB2A5B32F8DEBF92C1196CE8D53 +:10D53000234458FE6EE69DE99E5CFE1E95EBDE0BD5 +:10D54000A5B7A7D33D7F04DF152E11E51FFA796932 +:10D5500098EF77B4DE61C9B5BC10DF7D7DCC674341 +:10D5600068BDFF1926E237BB8C1442FF3360960773 +:10D57000E8F9A824CF7334DF7C3FDBDC9AEF0DB5EC +:10D580003506B9555C6EBEB763AE0F862D2AC79DB2 +:10D59000FE1F497C4FE733026E7477BC726285953B +:10D5A000E315D0F2F19B35FAEB758B591A3E877172 +:10D5B00089F9E87F6FDEF21AF365514A8756EFA8C2 +:10D5C000E7F8FAD6C1CE917C0FCD53E816752EBD83 +:10D5D0008E31E892BE2FB910FE8B528E1AEA48F0B7 +:10D5E0006CDF8B3ADFEEC65BAC7F78A5A8471E5E8A +:10D5F00099CAF5EFEEF58F733DE9E6FA370D7A71CA +:10D600004BC37B063D98E3FFC8301E4EEEB452FD7F +:10D6100030FCC2C0093721FD8E6DB6F3F7D0280764 +:10D620001DC4577DFDF0CAE1E3F9BBCA0BE2F9194D +:10D63000C3D1DE1862FEEA781E6A3CC8FD706398AA +:10D640005B339E7A9D426F6D3B2187EEE7774AB14F +:10D650006EAA0B9BEB17775BD44F480F1ECA49D7B6 +:10D66000E2B5FA022FF34FD42BDAB5EF4BDBB5EF6F +:10D670004BDBB5EF45DBB5EF43DBB5EF402356E7BA +:10D680000AAA6BB44BE2DECF2CC9F3E41CDC2F6D8D +:10D69000B0CF994371FFC2CE7C05F7A92B08CF9676 +:10D6A00090CF79FD7C7DE8B984E9C240FE9EC8CF69 +:10D6B000F7C38E58FCF9F4FDCDE48D59D7511E788F +:10D6C00024D67F9C2291CA9CB4EB28EF3B62137A4C +:10D6D000387D63EC75A4771FE362849FFF2549D4EE +:10D6E000959C611B7D3F3535D93728A758DCFBE277 +:10D6F000EF66F039C9A55EE78C58451C18D1E2C128 +:10D70000F41C710E989123E256BD2D239EE3F3E99C +:10D71000D4B27E3E9CCDDF9BACB103C5AFB83F7F9A +:10D720005FA3DF33317F7F33F24F76FE4E42AF8708 +:10D7300096E4A4F13AF45D0EE965F24FE2D86E4149 +:10D74000383484BEE3E98277BFF8AEF218D591A3EE +:10D75000EACF2539A20E03B781E13BA0C57B0F1F9D +:10D76000A23CEBFD61BE3144D7B916B584F8BA3896 +:10D770006107D7BBA6E4A8BC2FC2CBF8A2FD6926DF +:10D780003E2D7684B93E76A17A786FF81FBB3DF4C2 +:10D790008B5CAEFFAAF9FC1D9EB62FC23185E8AFA7 +:10D7A000E3ADC3D1BDCEF9E55FAFEBEAFD4F9F78A6 +:10D7B000285BABCBDFE2EDC19FDEAAD1A5DDDA733A +:10D7C0001DFD7E8DBFE7F0671800D5EDEDB1E823B4 +:10D7D000B0ADD7E874EC06C487EB139E11C4DFC567 +:10D7E000D39CFCFDB9BE3EAEE3FBC379F6599DEA7E +:10D7F0005D48F82FAC1775777D3C2209BEFA578A31 +:10D800003AE8E2EDEF1DA2FF0FC28267F20A39BFCC +:10D81000D7DE37D319E9CBDF45CD95C5B915D2F79A +:10D820006EE2B3B9DEFE6DE91A4915E7AB91B56753 +:10D8300086D03DB2C5746F8DBE0FD3EA57D066ACAB +:10D840004B21BDFC54AF38F73C0AF85CCBAEF91164 +:10D85000BBFEFE60C5F0FE31A7F7A7449F1734BB9F +:10D8600081F30316DCBF4DCF934D7594B690A87726 +:10D87000B6A5D8384EA67887FC931EEFDCF5A6A88F +:10D8800077DE9526E268828FF82B1DDCCD714297FA +:10D89000FF97DC2AD1CF69F505687FF02D65FF255C +:10D8A0000F45FED2F9C59FAFD6EA01C21F166BFE27 +:10D8B000AF98D6A10027B70FFBC5226D5F8C1FB9AB +:10D8C000EE361A7C4D0218AD6EB672B7A18EF07F9F +:10D8D000947817F25045000000000000000000009E +:10D8E0001F8B080000000000000BFB51CFC0F003AD +:10D8F0000917B1A1F26FA0F1533951F9BF5951F98C +:10D9000097D0F884B02E1303C30A46D2F420E39DC7 +:10D9100040FD0780F838109F6322DF1C103E2CCC9E +:10D92000C0F04D8C81610E906E03D2E781F83B1000 +:10D93000DF05F2C5441818548178A12803430C90E0 +:10D940005E0EC44522107D4780749D2879766AF268 +:10D9500050E6E6514C195E2D8DCA2F5701A647554A +:10D960000686B76A10FE622479267506860A1508AF +:10D97000DB408E81A10BA866B63476730D81F2DD93 +:10D9800040792175081F00B5882CEC680300000061 +:10D9900000000000000000001F8B080000000000D5 +:10D9A000000BCD7D097855D5B5F03EC39D879C24ED +:10D9B000377033C9490C1835C04D0C838878120371 +:10D9C000064DF106D1C6FEB45ED0DA481922F26ADD +:10D9D000B4B6B94012C2A441B4A568E98D554B79DB +:10D9E000B646C53EDAA7F482F8446B6BB4D4E1695D +:10D9F000FF469EB5D65FF9E280536DF9D75A7B9FFB +:10DA0000E49C939B04B5EF7D0F87C33E670F6BAF1C +:10DA1000BDE6BDF6BE6ED9C5D804C64EE09FF3186C +:10DA2000BB5A628CE50D3D9937D6C4228C356B6E9E +:10DA30007D530963DF546287F56A783F5E8EDDA30C +:10DA4000E3FB49752CCC9882F5F3198BE1FFA0DD3F +:10DA5000FAE0BA718920BC531667E1D3ECDF7C365B +:10DA6000AB8C6955F87DCBA44CDFCD274BB906FABA +:10DA7000BD8CFE9C2865ACF59597261F32CBF05FD8 +:10DA8000010B455E0FC05F66B0192714C6DE0D2E70 +:10DA9000CC4AB391FB7BB3ADFB4C7522631FB6BD83 +:10DAA00038F9D0C4E1DFBFA9B096DE8AE1EF673074 +:10DAB00018741AE223E98E4F1E9AF7E03C8380A483 +:10DAC000B3A13D63694F0E3C776F3B532D1F82D34B +:10DAD000390FC6921CBF9FB39D27529B2E8052A523 +:10DAE00094984D70A9F0CF74C6A82AACCBB2DD8D46 +:10DAF0008CE072C0DB11F9E7C03BE27A897AEF066D +:10DB0000D7753268B7DEC5E9A53D4F8EAD63C3E971 +:10DB1000C55C0F138F27BB1E37301F8D63D251B3E7 +:10DB2000BC78D4751F8B8EAE443A3AF3BF9F8E9269 +:10DB3000FF7BE9A883FAF95F46478C75737CB17E59 +:10DB400015C71F7ACF9F91C5BD12D21914FB10EED5 +:10DB5000623E142B6EEDBC569E02628AC59E3C0D41 +:10DB6000E45671FF9206847BFC2BF3FF8ACFCE45EF +:10DB7000B5F573617EF94DBDCF5E00CF483C2525DC +:10DB800060BDB63319850AF4B73C5903F36BC7CEB1 +:10DB90006631766F728991C4F93283B1718CFD8BD5 +:10DBA000981363B2AE4239447FCD340F374B737C48 +:10DBB00048273CC3DB8F34FF10B633EB94E0FF57AC +:10DBC000339CDF58EDD81A3E5E12FE417C170E8D55 +:10DBD0004FFDE4375BCA0CF163FFDE877F21FC5EFB +:10DBE000FB3F325E01ABF2A17C0835C85A0AEBB3A9 +:10DBF000DE6C15CA91E52A4B838C28A8EE965CFA58 +:10DC0000D8EBD2C9587D2F5F1FA9313404DF9F990B +:10DC100044F473CA8DAFF56C00923BBE381823FAFA +:10DC2000D018CBCD193E9FDBDB90902DE545B5524A +:10DC300082C68B3D5906ED938BB8DEDBDEB030DB60 +:10DC40002AAF3C9224F0E6A40FA6ABD391AD387D69 +:10DC5000A80DB2E19BF2C5E943FD9CF491B7C6D291 +:10DC60008E7DF6F58A9876C149D2C7171DCF5CD74D +:10DC7000E17CB556AC6B998F01DFDE5ABF30A39DB6 +:10DC800031F2BA5611BF471A9891CAD02E7F703D13 +:10DC900093C39FB03ECAE0F25E675B2F65FCF4A6BB +:10DCA0009E51F0A144ECF335FBF5B52AFA6BB9505F +:10DCB000543519FB73637F40671BA3B72619F0C364 +:10DCC00071A46DC087D25D99C6322B63B17B040409 +:10DCD00032947D5123B589E82045EB62C2E7D165D6 +:10DCE0001BFED588DF56664D49C90ABFAFD54D70BA +:10DCF000B8713CA07745830E01156A90A57D61AC93 +:10DD0000C1E1473238712A96BF6DA3832EBD8A6563 +:10DD10005A07935E11AD9C5EBF7D72F2C539DE225B +:10DD20003BBC27DD2EA8EAAF5BF4D0C8ED54F6BAB1 +:10DD3000B93E80C4ABB0836943EBB4C1C5F6495367 +:10DD4000415F175DC612F076037E3A9BE894EC992A +:10DD50000D45551AD215DB2DA908A7A947593487B7 +:10DD6000EA554A3AF5237B5B18D65382063DCDEF40 +:10DD700023C325E82F691C28837EBF24D6F74B4296 +:10DD8000AFB16AD76BFD26DCA467D5A132CCE3ED39 +:10DD90001BE07F4027C94A29758F34FC7B03EA4585 +:10DDA000904B0DF8DE2257760CF24194D6AB417CB5 +:10DDB0007BECE117269D05F4D11753188AAD750F3A +:10DDC0007B8C3AE8FFD973A5944712F0029C0B04B0 +:10DDD0009C4F1BB9C548A77D751EA2E305177C188B +:10DDE00041323EB6EFF76A267A5930DB350407FC3C +:10DDF000B7CA3A3FF8EF2783EB5244E39870ADA8D7 +:10DE000052088EBED9520AC739F4C7BFDC7C0EC097 +:10DE1000F974B514F3E8046F88C1787DC67B91511D +:10DE2000FD0E737C9D69884FE7F8E67A840B19E153 +:10DE300095FD09F00AE3256B07FAD7239E8F4AB1B7 +:10DE4000F5305ED69CD609384E892C13BC1B677BF7 +:10DE50006505E887BD384E467C06059F67B9BBBDA2 +:10DE6000A7029C9D13657617BCDA5836BA3C6B77CF +:10DE7000C833558B1B12B4D7935A95320A5FA40C42 +:10DE8000B93E93BC7B4AE27AB223B9502BC3E91D59 +:10DE9000B2DB81A897E216BD0AF6E25312CCDF1579 +:10DEA000E1749C5D17E77662DF38925F01B11E591D +:10DEB000531666B10C76F088F3808132D9CDD93211 +:10DEC000878FBDC2FB57CDFE7346EF7F83E8FFA36C +:10DED0006689F5217C6ADC8BEBCF8C4AA267BFA0F8 +:10DEE0004FB62687CAA6DCF594C7BB4A601D3D51D4 +:10DEF00099E93ACE2F49EBBC19D6B80840F1D7C101 +:10DF000077A8BAF9EF0AD925D9F2F16412E0D87CE2 +:10DF1000E01AA6839DEA8FA61895275FED45FC6C55 +:10DF200006A5C0C7EF65387E00C816E56B00E4ABF8 +:10DF30008EF255EF4DCB5056EB59CC804F212D260C +:10DF4000F981640E464BD7AAF0BE7D3123FA65688D +:10DF50004558F0DB1E7DCE5000AECE2646764D678E +:10DF6000A496E6D75E51EB2D417BA741A5F7EC5374 +:10DF7000C0876987803CF4973303C7DB9CCF52414D +:10DF8000E4A5BA3CA247B7C6E7AFEF2863E9B3E020 +:10DF90007BF6F403387EF23B2C36910F49724D35F7 +:10DFA000E9424D2425F4EF5AB5D8A60C74B7832561 +:10DFB000B2E469363A25BDEBC45B969B5D88F8ED0B +:10DFC000AC04FA2F19DE4F11F20FD05B2AB6F0E243 +:10DFD000D20CE394C83AD18759D63F7213FC23D5AB +:10DFE0001FAA0776662E766D4888175617A1F9E5A1 +:10DFF000B0C13F069673C57CC7B116AA179DD97DDF +:10E0000000F9ACC0E8AD415CDC1EBAEC595A377679 +:10E01000A786F10880B6EC44EE909C30825C4EBC42 +:10E020001B93493E86E4B4664007215F5F9494B534 +:10E03000CEC88FC8C22600F0A6B6EEC9E85F8659E2 +:10E040004CC2EFA1989AB4CA9F2C06659BFDC78E5F +:10E05000944D27D2E27CC1B403C8325A79CB69D837 +:10E06000DF7600C8077EF2965082F4C587BEF014B2 +:10E070001CEC43399E95E6EDCBD1EEBE5EF1C73682 +:10E08000213DC4B87EF0C23F28FFB266AA36799C13 +:10E090006DD8CBB90EBD314F09D27CB3BFC4843E1D +:10E0A000301A268E1B820F206B44BAD956A7321C19 +:10E0B0002F18E4709970E62A9FA66546701C4538B3 +:10E0C000003D0447B89C91BF07F01C75C073D40194 +:10E0D000CF512B3CAD5E3E5FA7DFBF54167E3FF8AD +:10E0E000BDA8078FB3B78C7A2418A398F44A58E3D5 +:10E0F0007583DE3E32AA34A6D1FA3BFD7E589F7767 +:10E100006DFA61A628EB60D797127CF6EFAC88E831 +:10E1100084CA0A1BF45F97CE34F1A37FF965E0BB94 +:10E120006B0EBB18F215F0AF82DF5DE2EB35C28FEC +:10E130005D8AFA1FF4F6552C1E46F8DE6632D9CBFE +:10E140006FB3E7C26759E4E276D92DF4382CA8956D +:10E150007F592C8A7EB51AECEC53C2840693CEA468 +:10E1600013B46E31467E7790D35B9279D7927DD18E +:10E17000C5F5A3E9F77DBDDBAEAFBFB1C35EBE9A07 +:10E180002D1C87F475F56D2E96827EAFB1DA1FB027 +:10E190003E37CA1AC1F70DD6D2A905C9CE6AC279CF +:10E1A0002CD5988A7EDA8A7FFBE1F425309F9D4248 +:10E1B0008FBE09725DB7E88D659194DBA8183EBFEC +:10E1C000F5526CC139D2C8F3DBE0EA5B80F64172EC +:10E1D000AB8BFC3AE6F4D7F62AE4AF59DA11BC5718 +:10E1E00076D9E737D6FC9DF3058F85E6BB6CF71231 +:10E1F000D29B23CDC7BD5B325219F4DB03A63E147C +:10E20000F2C5A46F93AF93B58CDB7BFFD7975A0F02 +:10E21000E3FD01E523AD7FCB541E47699981CFB162 +:10E22000DAFDE7E76CF7A7CFD9EE3521C79DED56AC +:10E2300078FBDDB89EABD464BD240FD9D15E578B7B +:10E240005108A870EDAB49A32966A9D77592F50EC0 +:10E250004BA52755AF5E1EA5BF63C2CE78E2BE1F99 +:10E26000BBFB91FFF6BCBA00F5FB37FF5D615E9822 +:10E27000D7B1FB422C8DF4A9A6DC68AF2C03BA4AB7 +:10E2800051393DFD128B5D05144BFD7FF3FE10D916 +:10E2900007CB1EF4A41AA0FDB25FFCD71406783891 +:10E2A000B66EE03F0A915EF748DCFF4BF64FB904CB +:10E2B000DE2F53D915F10C74222B9C5FDEFA65A07A +:10E2C00009ED3E69F781AF51BFBD5F76A15C36EBCA +:10E2D0007D8CFB007954CFC0EFC99F4AA989128772 +:10E2E000AF71F270BFFBAD9F4A1CBE7DAE940FE1D3 +:10E2F000DBDDE34E40BD55BBDF21BA3DFFFE9F8510 +:10E30000110FABF629367F77D56E25ED9942CF57A1 +:10E31000F1899A51027E5B29F875E5DE15A407564E +:10E32000F66E7E07F975D53E974DAE035E6269C401 +:10E33000EB0B4AAC01CB0FFD24AC03AADE8CEE093B +:10E340006B15D4EF1237D0D5C533EDEDB0FF8F721A +:10E3500086F7C7D800C53557F56EE4E331AE6F4C8C +:10E360003E7D13FF923F5C6F9CAED8F71D8EB3A726 +:10E37000A7531C72776E463FCED41726BF7EF36735 +:10E38000C7772561DCB71EFC7FBB9200FFF27FBC24 +:10E39000B7EBDB302FB6DFA7A11C5AB5E70F6166DC +:10E3A000C17B9DC2FDB0633FFDC9BD3B815F8EBD9A +:10E3B000E421BBEED8A37F394587791F7BE0E37169 +:10E3C0006877AE7974EE78A4AF350F9F3F9E8DE2EB +:10E3D0003F20BDA63CD6754DD1BAEAFB240CC23015 +:10E3E000F688783AD6E7B1BD4A1A43B76FBFE84915 +:10E3F00079003FABE05D6B15AED70AD24358BE093A +:10E40000F0BCF2BE0DEF285332E13B592847F10929 +:10E410006C13C5F5BEE4E273ABF1E98AE9481F6C01 +:10E4200080E4BFB3DDAA23B0AE53475EC7E3EC532D +:10E4300037E27FD57D1BF9B88E757C1BFF7276069F +:10E44000FD3F6C1D97FF68277EDC9B4BEB3ED23A6D +:10E45000AE78F8D251FD33531E8C85DF6689C33503 +:10E460005531562BC8570FFEEBBD3B237C7D1B005F +:10E4700021C77E76FC140C2EBFE11AF81ACAC98196 +:10E48000473DDA5DD066D9A32F109F1D7BF859B7A1 +:10E490004E72920525D07BC7D8E09F3ED4832B25B2 +:10E4A0005E58757728ED090FADD3CA5463BD1EA61B +:10E4B000F7AFD2FB14A7FF95A9038BA40CEBB647CB +:10E4C00029E5723995477859A1F7B9B5A07D3DA5E1 +:10E4D00099B88EAFCE43BA1B691DCDF96B38FF19C1 +:10E4E00096F5BC9BF3ED48FC79ACC7A34A5943EBC6 +:10E4F0007B4CD807AB52D20B2C03DF32B68EC33B1A +:10E50000C2FEA3F974D2C3DD0E7A30DB9BF31E8BFF +:10E51000AFC79ECF67C3D76D8A6EA31B136F6F7D86 +:10E520009A59DEA7859C58C992F505A70ED7572A98 +:10E530008B270B4B86E0EDEC55488EBFB55B213B3E +:10E54000DD2917568EE08FFF4EE1F6C7CA7D07A67C +:10E55000A0FC7AEBE02F051D723A5F79DFABEEA4E9 +:10E5600090FF29ABFCC7FE32ACC78B02EE558F641F +:10E57000EE6FD57DEF64ECEF4DD5F832C2FF669FAC +:10E580008B25A18B377B958CF18D838ACB16C7EDBC +:10E590000C4D7F310BE39B61BF8EF35EBFCE7821C4 +:10E5A0008976C8732E4676A01A7BC303DFD787FC13 +:10E5B000B4EFBD3E7C35D32D7ABADD8127351A27DD +:10E5C0003F588DC4AB79EC3565F3475D9A6C839BFE +:10E5D000A9C9228CA7FCAEE42F2AF6FB0CDA7FA790 +:10E5E0000DD57F46651DB9D0DF3386145BCB32C4B1 +:10E5F000A71CFDC7672B4CB7D299512E5BE3ABE14B +:10E600008337505CA295B5A4314EC48A58EF3D962D +:10E610007EEF6CD3581AC667F5E5B235BEEA696974 +:10E62000313C0047D11AAD144DB391C62F6E91ED18 +:10E63000716D31FE6A114F60BBF7ECD903FDD6E373 +:10E64000B752F46378BC0ADC29B263CE1772F0D7F4 +:10E65000C20E3E28C50FA19F65E8DB54947352D9C2 +:10E660003615ED89F99F76AB4B2DF438BF6C6D11E3 +:10E67000D2CBE1BF2B4D99E86A91CAE96A6DC98690 +:10E68000226C7FD8777D117742A334CF0231CF43FC +:10E69000C5DF08F643BF074ABEB16512C0551F5516 +:10E6A00018C65BEA234BB654C2FC0B8E28311F946C +:10E6B0000B9A936A62F2F07176A1BC07FCDD857853 +:10E6C00004F8EF6E8B52F9DE369D9EBBDBCAE9B9CA +:10E6D000A72D46DFEF6B9B49E5DEB67A7A3ED8166A +:10E6E000A7F7E11BFD09A4DFBD6D4DF4FE176D0911 +:10E6F0007AD6AA9CDFE60B7C58E64DFB608BDAC32A +:10E70000EB308E62E2CF89EF3AA0B81CDA37907412 +:10E71000C4F77895CB15275E5B5B836497EE929880 +:10E720000D9FD3556E47C6051CBFF6262E54E1F942 +:10E730006E7D5905D93D2C1E4339BD4B8ADF5209E8 +:10E74000FCF244F18CA855EE66051371356FA87C78 +:10E750004A178FCFCC50B97CAA676B0F65017CC676 +:10E76000A74C473A33E779B0462F42B978702DC0AD +:10E770005381DF65566EA133B3BF59023E16CC2CD0 +:10E78000A787E896F37F7456F9368C1383E3199BB9 +:10E79000A893D56D6BB74D35E3DE3AD1B14927C0AB +:10E7A0003F4F1447A81BEE2F3697F0EF3E4EE7ADD4 +:10E7B000FDEF507C2B3A8ED9E28D1DCD32F9393BDD +:10E7C0005FE171E9E3CDA5DB2641FD1AC01BFAED3F +:10E7D00039F3CBB21216BADE22E869A7379EA58DAF +:10E7E000A2BF3A453DB3FCBC2FF15D5C97EF4FF8FB +:10E7F000793ED2F34E57EA72948FADAF78F475300C +:10E80000A57F04E249FC1E2F82F700D2F1FA351EE3 +:10E810009A5A90EF3FB4DEA46F3BCDC2E7A1989D1A +:10E82000AF77B58E1E9736E1DE85708F129735E192 +:10E8300036D7E378FDA2816FB0E17870F69B337F25 +:10E84000D1A8E3DF897CE7213CECB2D25B518B4657 +:10E85000FB0C667B73BECEF6CEF90EE52B9CDCFE80 +:10E860004CAF8BE5E27A3EF0B7531E7A86E192C751 +:10E8700015946357A8895E84673A6BA1325307F2F7 +:10E88000915F5EF473FADFD9796F3EF1919A2A4174 +:10E89000BD70B2E375B078BC06F5564C8E59E5B93B +:10E8A000F97C5C35E304698A1FD116330C29076EA5 +:10E8B0008A66C2F360FF45EA5BD6FDA42D8C713FEA +:10E8C0003DEDA57D0E0C8868502E39CCAA36417FCF +:10E8D0007B843CA951B95F78D661BD47E1F123A59E +:10E8E0003164C1A388A79A71AC0E7613D3A0A95B3B +:10E8F000AD3C80D54D3E6C74279E477CB9A33AED64 +:10E90000BFBB2209E22B26E2DFC5224E3F57C419C6 +:10E91000EF69E571C65616BFF034E4EB230A23FF16 +:10E920003871AA8D7F9DF33C20E8EADF85FEFBA5C8 +:10E9300090DB65EA01290BFA0FBD913E1886E7BF0F +:10E940000939FEB090E307B7FD4709E6137424DCEC +:10E9500031C469B8DA9F96C00EBD79FA1BFA3550FA +:10E96000BFA37B523BE267C31A1E977F08E53EB404 +:10E970007B40C8FD704BE7B5B46F27E44B91992FEE +:10E9800020E4499190278F6D7B7EC9069C5FC24B26 +:10E99000E3B4B2F49318D7676B64B253C2BDDFBB64 +:10E9A0000EFBB9BFCDE0FD76EFF917B4EF7FE84D70 +:10E9B00057FD06E3FFB3DDB124CAA9D4449B9C0AEA +:10E9C000F7EEBB1EEB857B9FBA81F261041E3C8F84 +:10E9D000C07CA14AD6AD87D321A857D89F46B31B88 +:10E9E000D6B567FEE9D05F59834CE1EAFBA4F8F99C +:10E9F00021A48746BE0F9D55B9682DD6EF5EFE5CFB +:10EA000012DB8F7BBA45C265CFF997BB6A107FF7DF +:10EA100014BDF6640D3C27B94A880E82AFE8F93F71 +:10EA200061D87F3C7A8D3E321D3EB67C354339E657 +:10EA3000B94DA67DFA7B6E5BCDBE61CDBB58AE668F +:10EA40008C8F4D7279F87ED66D0BFB50CE9AFB57AA +:10EA5000852BEABCC4FF4F33DBFEACB98F65B6AF84 +:10EA60009412935C79B45FC1F7B544FB02056D3C29 +:10EA7000285E27733E88A77DD67C93E0B5723C1351 +:10EA80003C335C2AC1D31EABDBFD1F309E3AE33220 +:10EA9000D2CBACDB0E87B31DC03183C3C1E133E100 +:10EAA0002806932008E3DF3AFFF97C84EFA3FA41BC +:10EAB0007DE347FFBFE376393D01D6676BBB4CFB77 +:10EAC000F707AB0F7A118F5BAA6BFDDCFEE1749741 +:10EAD00023F8E8EE7A99F8F67835DFEF679F9EA085 +:10EAE000FD3097F89E9377D04B7B18492358331D00 +:10EAF000D30FCC3F96FC02C04D55D26F939F726BE3 +:10EB00008E2DDFA0981538F2564A87EAA3FF5D7F65 +:10EB10004442BD1412FBD165E6FEB6F24A0CE77F13 +:10EB200087A917DBBCF4EC6939E8D301AEC75B8079 +:10EB30004E685EF6BC144F33A37915B4F07DB62D44 +:10EB40005ADF0137948B6E07D4EB68CFF5927C6166 +:10EB5000DD3C5FC0DCEF98B8DC9EB752E4C8B71963 +:10EB6000969FF519FDCC6B5DF67CC3E36CCBE94455 +:10EB70000F7DA5B675E9391BDC9AA9C3FDCDC17E11 +:10EB8000853FC5A25CCEE5F8F81837DFA834A3BDF1 +:10EB900014BEB02ADBBA3FDAE9E276D2A13F7A1896 +:10EBA000C6E337D479298E63EEA39BEBBD1593AEF4 +:10EBB00030DFA1FD5E1FD2CBCE48293D1F9BF594CF +:10EBC000AF9FE890E70378C49CD6CD7A6A7E33E0A5 +:10EBD000F5877932E9988EA2E7F2717FF1D63A2F64 +:10EBE000EDF78703FDBD8F4139F87D770CF7B7EF5F +:10EBF000A9493759FDD7FB5DDCDEDAE112FA6A8BF1 +:10EC00007DFF19F86007F2812718A7FD4BD92BF279 +:10EC1000261C7E8E898FF0C17CB964327F964E1E91 +:10EC2000B2CFEF1474B353C8FB2D42DE3BFB29690E +:10EC3000D60EBAD1EE5FAE552919F87242ABDD4E51 +:10EC4000286EB1E7D51436DBE93E142B70D8156970 +:10EC5000D263A63EDEE00B9E8A745F05FA92DB0764 +:10EC60009A6CDD6F77EAE33DAAB1CF45F6EEC9D9DC +:10EC700009E140BC05F1EDB4730F097CFF4D310E85 +:10EC8000227E036AFC908BF240E324679C76C330BB +:10EC90003819C0397954387FEBFA0CF6D358FB0396 +:10ECA0001FCAF11DCF00C873B298C8BB08911CEEF3 +:10ECB00008717FA5C3C5FD8477C5BCFECBA550BF39 +:10ECC0000382BEE604584BE67C321E2F7A1F0D13DA +:10ECD000AC373E73FE2E5A2CF4BD30F3F7F75D7C53 +:10ECE0009F6DCE84D1C7F900C781E7EF54E31D972C +:10ECF000651FE75197F19ECB12A7F8C8A5717E302A +:10ED0000D743E4E79AF6D33ED5F8D8DADE7CE6CCF2 +:10ED100057693FF738F3C714C0CFFE7CB697811C04 +:10ED2000D92F097CFED147794026BE07ED6B941F91 +:10ED3000A8075E09A4309E62AE83B90F332847440A +:10ED4000FD33DC5C9E00DD04DC347E9CEF17B234C6 +:10ED5000C9870241373B7D8B6FA983E7CDB3DE7C4A +:10ED600011F315DE7ED8A7235C5BAB8F86AD729363 +:10ED700035DBE9C77CEFFAA890F6E9BF2525F2DD7F +:10ED800016BBDE15197063FBFD924EFE5CF20F0A96 +:10ED9000D923FBA5D4E964A8A88CF633F65F134DFC +:10EDA0006DB2EC7738EDFC1C5FFF1DAB70DECD6003 +:10EDB0002FB10CF12961A70FDA1D517BFBB89B091C +:10EDC0003B1BA60B7C5D29E61D530D05E198C61281 +:10EDD000F49CC1747A823F50E586FA67B1817CE485 +:10EDE000A3758153CEE176C67F1BDE8CFF8D781B29 +:10EDF000A25BBBDE36F71DF2041E42AC85F6DF1FB8 +:10EE00006F5ABA71228CE72E0A923D9CD7D47EAD00 +:10EE10001CC66CBF3E0DFDCD3CB11FCE1671FD6C06 +:10EE2000EE4FE734D8F5B9537F7B84BDE11941AF8C +:10EE30003BE5E6487A7DB9DBAED707E3C723C83F99 +:10EE400067FC786CF9A7DF525782791AC60B756890 +:10EE5000D7CD5629DE193E955D11B7D0C3FF751386 +:10EE6000D1C193E7CD6C027E4D9DC6F99CA19F1048 +:10EE7000000584FB09C5720AF36D362453F5987FAB +:10EE8000B6419DA859D7B1A698DBB35B6BFDCD56B3 +:10EE9000BBF6753F8FA75E1BA8790AE9AA2298AA3C +:10EEA0002577CF0047701CCFBBC4753B5363FDB8BB +:10EEB0000FEB615C6F034778B95EA9D35EA7FCCC0A +:10EEC000043B11184D2FD8F331F7A8A9757EC4471C +:10EED00084C75F423B244ACE517A8D34E6724D0D91 +:10EEE0002CBCD3CDF557398E73603A98BB50FF8355 +:10EEF000036EB2737A43852ADA93FBE5A53F423B62 +:10EF000070E0250FC3FD94DEBF9F41E71A7A43E707 +:10EF1000CC433AE8951878B6307FE01F9EFCC302D8 +:10EF200018B70F9F6F308C5B0E3CCE6277C1F8AE86 +:10EF3000E84371CADB6546409E09ED7CAC0BF35794 +:10EF4000629FF8DF3B0FE8EEC160D5F6A96C280E92 +:10EF500060FAFFE7F9130F219C1DE3FEB319F9AC2A +:10EF60000BE054C80E33A20877559E4CFCC7F282C2 +:10EF7000A989F0BEE670A40EF3D16AD44A94340095 +:10EF8000075FEFE77D8947B19F3AADB12E1BEA5786 +:10EF90001FD1C95E9917BDF61096A7BFC2CB1D6ED3 +:10EFA00046F620F22FB3F05FCD47A7D0FC0E0B3909 +:10EFB000DE1E35FA0C6994F5D054C7790E7B1E8B92 +:10EFC000950EB4E9363A48B8AC743013E860B2959F +:10EFD0000E0CE9B3D0C1F784BC1D9B5F389F5CAFBA +:10EFE00070BE194EF72DDE9C8AE1FC618EBBA93AFA +:10EFF0002782FBAB261F68336ED2B0EC59E28E231A +:10F00000DF997C61F2C33FBC2E820BF8E2421F3CC9 +:10F010001705F5B999F802FD382BFD5F32029F2CD8 +:10F0200060038730E77E81CA925920427E77F61BC3 +:10F0300065A758E8DE89A705B32576D4228F4E9CB4 +:10F04000E0650B1EB5C13C68E5E4F1FD9CAA774480 +:10F050002C7CD709F6331A855D728CE59520DF2D5F +:10F060000D7AA6E1F98607A214DFF7C49B296F6D1C +:10F07000C65B81AB810E3F1827EB38F90E7DE9FDA9 +:10F08000C4BF2F0618DA6D5BA72F9B80FEC907D778 +:10F090002426609C7323E0FF281937A9F132E5424A +:10F0A000F58FE7FB657A943F1351FE9E89EF295156 +:10F0B0003644BD7EAA07EB6C9387DBBD9CBEB77B55 +:10F0C000B95DB8D1DDED45FE1A28F1D27EAA59EF1F +:10F0D0003C85DB6DB33C229EFCE97A1DFDFB591E8D +:10F0E000DE6E7B5B2AFEDA448473373D731B520C61 +:10F0F000F703FCE5491DE3F1DE752C91C9EEBBDD9C +:10F10000CBFD7FEFC11FD03E526E598CFCCE480321 +:10F11000F46759AF05809A2C901F00AE8174DCA172 +:10F12000FBC90E5B10A9FDAB3A65F8FAE29FA39606 +:10F1300075F2FE4349F472FF8CFC8B35C29FAB2BFA +:10F14000F5125F74B4BA7B702A8B3CD9DCDE8DD4A7 +:10F150008E9A3F8B7E5312D639057E133E717F23E4 +:10F16000791ADFDFC032EE6FE013F737F089FB1B4F +:10F17000F81DF737B0FCF33683CAB8CF8165DCE7FA +:10F18000C032EE6F6019F737F0B9AFAD999EBF6A24 +:10F190006BA1EF8FB4B552F93C0FB7B3597932BABE +:10F1A00010F0DC7583DBC07DEBCD627D1E334A73CE +:10F1B00063B08EBE08F73B7D4FDFCA703EBE288F1E +:10F1C0001775466F6557C2B36B5AA80B0359DEFB20 +:10F1D00083F4F4A9DB19C60D7649C9668CD0ADF667 +:10F1E000FCE27C15F47359F4DADA1C28B77A1E595C +:10F1F0008F793B93F4B5B1A5DA50590F552D7BC0EB +:10F20000529E50D1A3FAA1FE7736EC5F8F7C8A70B4 +:10F21000A0F1B6C173E0FCB5B0E4E95246E73706A9 +:10F220004ADC29A4B3AB70BD2622FCDCAEBF88AD9E +:10F230008FA29F3C417757217F40FD34A7CB93ABF2 +:10F24000BF1937A9A60D6F375A3DB9FAA4EA31653F +:10F2500094FEF0BB344A3F1D6CBD8667C936232F30 +:10F26000633E912F407E5A978BF365978F3FDFF473 +:10F2700072BFECD7DEDA8BBCF0BC48F069972F5E2A +:10F280008F71CE81C932C50B7A5DD00526E5B69661 +:10F29000FCBE14C6FDD6532AC3B8F35D1E6EDF4C08 +:10F2A0009C10E2FAF2DB5ED297174CF8597B0E9471 +:10F2B00027FE381643FDB799C5FC4827C92D3C6E7B +:10F2C000FAAFD5A7E63442F533A73D9C43713FC161 +:10F2D000DF293C6F04E5B51D574FC038C707CF7213 +:10F2E000B9F480A0B71E575F0BADE7B420D90D8CE1 +:10F2F00075935DB036AAD2BEBC9CCF9F6E97F615B3 +:10F30000ACE706C59B0478DC7F9FE125FFFB238FDC +:10F3100038A7D647F682DB97D0B2E17D7752267EBA +:10F320005FAFF953988ABF395845E76693152AE5C8 +:10F330005D6FAEE0F1B940E8B214DA09B71CF071C4 +:10F34000F910F452FE55AA62EFE1DA083E650DF9B4 +:10F350003D652CAC27BC6BB246795CF037FADE1CFD +:10F36000A13CEDCD4CAC4BB34C7E60C7B84F7E3367 +:10F3700015F7BBBFAEC5C4D921CA8324D346C67313 +:10F38000BC03070308CF57CD7347FDEB0250BF7D89 +:10F39000A916C37598A2D5D6637CB043ABF5225F9E +:10F3A0000526D77997901C1ACC53A6F36DED15DC82 +:10F3B0005EC5EFC897AC9D1DC2F32C85429605B281 +:10F3C000AB24B4733A1A286C8479BCB6BCCBF69CD7 +:10F3D0000B29AF5D599043707630C38BF5930D2A9E +:10F3E000E9A5C2A0378D765CA11937C494638B1F41 +:10F3F00091BBDC9EB79CDFACDACE758C4FD8CB7955 +:10F40000C22FC873E4377FEA31F755EC7872CE37F4 +:10F4100037725736C29B8B0795F5E1F3D91EA96A5F +:10F42000C479166A7E823BAAADAB41F9359EB5AC74 +:10F4300045BAFBCCF03AE09C52D1DE87EB3E455713 +:10F44000E91CC35436B00EFBDD2CE8BCABC4AE27C0 +:10F45000EFF228627FB7B6DA3B8DC7B99296F14BCF +:10F46000927E96B48C776A578EAD3CB1BBC056FF86 +:10F47000B41DA5B6EFA7A7CEB07D3F737795AD3C81 +:10F48000B97796ADFED47DB5B67265FA425BFDB331 +:10F490000E2FB495A7F57DC5567FC68B4B6DDFCF7C +:10F4A000EE5F66FB7ECE1BAB6DE573076EB4D537A2 +:10F4B000ED66A75E9CE2FD7CF6B207CF79D9E282C9 +:10F4C000767BDC694F7BFFB15E5F87722DEC26FA9D +:10F4D00056518F4379F50DDC9FF1CE89E92857CA43 +:10F4E000845D931534CE41395A13F6923E5083BC55 +:10F4F0009E1A9C4776C7293B401E9D8556201BFCC3 +:10F500001E40B9DC968C97B986E0F669DD7466A179 +:10F51000265C4F7175B3BDAA192C11C2F1746ECF60 +:10F5200080B788F57C3AB4B7CC63BF2CD311EF0118 +:10F53000F0BBEEB2F85D23F9594EBFEA64FDA85363 +:10F5400064E6C7678F146FC16745CBB3B5985E0794 +:10F55000FED5158887ADEE78730FF4BBB5D4CFF721 +:10F56000C1847FD555D24B7C3150A2927E61AA5E78 +:10F57000B1D012DFDAE4E57A25E0BD83FC3BB57457 +:10F58000E6611DF1BE56A5B8C36689C74792B00EA5 +:10F59000A8D776CD7AE39DEFC07B6FA9B7D00BF2E9 +:10F5A00028F698DBC0FDCFED02AFA55A652D585C5B +:10F5B000605F341EC4E7241DEC0C7896976F3B887F +:10F5C000CF9BBC3CBFEE8CD803B5284BBC73B8FDB9 +:10F5D000A74C71A7D6E1FA691C8E91E84CCDD9C130 +:10F5E000F7A9CAD4D791DED0DA3E210FD1810FE935 +:10F5F00040A227D18F2F1224BDE1C38D1C2CAB520A +:10F600002A00DF23658684791735E11DB4EFE64BC8 +:10F61000DBED55F03737215E230DF6F50E787711C7 +:10F620007CED128FBF7665EB4FD702FC5D79A53973 +:10F63000183BC1F844A345DE6C17FAF42B3ED9D42D +:10F64000FF246FE85CD7B4217B07E87F877C2AC260 +:10F65000D7CD506EF96EEA6648EF3E0D5613EDEDCC +:10F66000EF2689FE4D7BF73AC15B75A54DB4DFF5FA +:10F670005EA48AEC5B5FEBCF33E2CFD7AF30E3AC75 +:10F6800091F11A9EB493F43D2B75EB6857B4EA6E72 +:10F69000A327833CA8F2703B6623E67D203C22EF43 +:10F6A000A34BE0C3DC6F7BCFCC8712FBBCD76533A9 +:10F6B000DBBEDF757955E347B3C77DE0F7252CF056 +:10F6C0006E8471102F1D9F36D6C769FF8FF1736A44 +:10F6D0007FAFE8A1F3C0C27FA91276D22C0A9A01AB +:10F6E000DFB819F909E763FCE22CF4362FAA47BE0C +:10F6F00034E31DAF7973A85E2CC99416B2575CA68B +:10F70000DE924F4C259875B719A7249397EB35F8DF +:10F71000F7009EAB38B5CB7E5E6962B7BD7CDA0E72 +:10F720007BF9F494BD0C56F311B40B1A19C7CF9999 +:10F73000BBEDDF1BCD385F1D3F67E185914F70FD4D +:10F740006B3BD7CA84FE37E3A9C5BDE91A14AF45A0 +:10F750006BEC7AB540E8F90287FEAC0A29E4E7D7FA +:10F760001C8E1C42FBD18CBF3CEFD36DF96F661C25 +:10F77000C529CFFDAF6C63F085FCE58487C7171200 +:10F78000E0DFB41689B845317FBA14FD99C564A786 +:10F79000B59C86F2E9D7DEC4075E325AECE720DE7C +:10F7A000AD571F97743E4EC232CEF5E5C90BF8F443 +:10F7B00053945762C6314C3FFD1F01E322E4AFCDA5 +:10F7C000B1E75A1EC338D24B1E86FDCC559E3EDC97 +:10F7D00006E5D5C52AE5416A3396FFC88F7140FC1E +:10F7E0000EE59A127D3CD1FF932EF2D737087A3678 +:10F7F000CFE798718F5C9FD03F3EC9DC87F08B3C90 +:10F80000573FDAB967EE06D96CD3733C9E66C6CD16 +:10F8100026F7DABFF732295783F59BDA9492B95D60 +:10F8200065046B2C71F533C47A4D599CBE753194C7 +:10F83000EF63A92ABC2FA252D045EC90FD3CD838EA +:10F8400026D1B981714794580AEA4F79C4FEBDC2E6 +:10F85000715EEC0CE7F931479C37A4B07796C0781D +:10F860005BF41609E5E796C560C343B9C227F28782 +:10F8700027B149487F7395602C8DF8FD83427AC388 +:10F88000F3EA692F2C417DFE2CCF4FD14ED5B7D551 +:10F890004159FB8D42FA490BB0CACAE0505CF87B73 +:10F8A0002762ACDD351467DA03EB5A3611FD6B2F96 +:10F8B00043BDF273585F2CF7823F8EE507C11FC727 +:10F8C000E75EF0C7F1FD2FC01FC7F23EF0C7F1F9A8 +:10F8D0002BF0C7F1FD23E08F63F9DA404D8D2FCF78 +:10F8E0001EA7B2C6ED86E254FD9219A74251F2BEA0 +:10F8F0009BD3FF60BC2AC1E35563F76398FD503C7E +:10F9000070583F222EF8F60DFF792F9E9F5E316DC5 +:10F910005D179E83F5BACCB818CF7F30F39A4DFEB1 +:10F920005BB1F75ADA0F76E71F69C1F5D85B1DA402 +:10F930003B86DCAE8486F2D1E97F997E97D3FE3593 +:10F940009F4E7DE4473BE02CB493BA29EEB3C9C582 +:10F95000CAE95CACE48F215F38E390261F3FEB2BB4 +:10F96000CD789E69303F56C4673C2CE5C578995BDD +:10F9700012F314F99B24C2A08BCDC8CF967CE36010 +:10F98000459AE21CC1A041F697047619D9695A221A +:10F990008A71A8CE11F26177093E5D9BEFA67B24A8 +:10F9A0003AF3F9FE7F5D512C8AEDD7E74F8F5AF37A +:10F9B00063CDFCDD43A1E9DE7E4B7FAB43A5A3EA2B +:10F9C0002905F4AA3E8A5E553C3C7F7DFDC1B3BD4E +:10F9D0009897BC29B8B40FEDAB4DD1089D5F3F900F +:10F9E0003F9DEC8FC1FAD19994BFAC04B9DDAA4414 +:10F9F000BD64B7AA38FF8AA1FA66BD1B857C06F6EE +:10FA0000A3F85C20D84BF53C6A9CE21F9E08A3FD3E +:10FA10002A8F97E70B04C1BFF6DAE2A6421FFBB8B4 +:10FA20007CDBA427E2D86E5354D5511C6D2AAF223B +:10FA30003CAF17785E9F67EAFD18D91B0F0A39683B +:10FA4000F6B35EF8EBEB9BDD6477C55BB38DBA5C18 +:10FA5000CAC7FC09F2DFA6E05D5ECC6F77E7578F7F +:10FA6000DAEFA363F6FB6A6DDD59D4EF83187F7676 +:10FA700087966AD8AF6B84BCFBA7447F9FD7BE0430 +:10FA8000CC69B4DFC54C7D9B8A5AF7899D4F3FDA1C +:10FA900089670D6FB742EF9F8779BF2A4BD6FB95D9 +:10FAA000E1E71656EEE3F7506D55FBC8DED9FAA92B +:10FAB00094F1FC43B6DFD43F837EB8CD5E2914FCBD +:10FAC0005428BEEB68AF94A05F69B72FCE3A6C2F75 +:10FAD0004FEBB39767BCE8B4578C3FA0BDB248C8A2 +:10FAE000BB3E90CF3C6962404539104FA66A10EE8C +:10FAF00046D6BB16F7295D22CEBC48E8AB8BCDFDC0 +:10FB0000477F36C15FD8ECB7F989E67D1A45A2FF79 +:10FB1000E2BA43D7B6A3708D9BF68F4EFE65F1FC1B +:10FB2000076B484C3AECA046C37E1EF562879DE306 +:10FB3000B4876AD41ECAB72C70C41FCC7D4A9C27D8 +:10FB40009ECB758EFF59C735FBDB097A0BED15F39C +:10FB50009E02BAC70BDA17AB692916A4FC2DCAF3AB +:10FB60002B5CC38C9E0C743CD3CFE5DA30BC25CF24 +:10FB700023BC9D2FDE1504F93D2805754A4A2FE167 +:10FB8000F95F284F162E87F990BD7C82F6A1CDFA39 +:10FB900039D9BD942FB6B341E2FE6392911D62AE96 +:10FBA000F3CE203F3FD378AE9492B17D4B298D4F59 +:10FBB00070950EAD2FE0E928C713CF2FBBA4DE7ED2 +:10FBC000CEA7D1616F98F470B1E3FDCB3E7E4EDAE3 +:10FBD000E483B7CF7E71D22900C70A29591F504E3E +:10FBE0005E4F5AF8C37502F910FF3E8EA642FC71B3 +:10FBF000D0FB9046F901D9FD773020C9063F4BD69E +:10FC0000CD06BDE81F385382F225FEC91D5DE7E22F +:10FC100071C5817F45A3CCE3A99A5B5F3C54F6FB99 +:10FC2000E7503922C601D722C9D7DB726F01C0FB6A +:10FC300003911FB0D960DB14CCAD94B56DB192A126 +:10FC40007639D84E1AA55D9C6D5333B40B9AED00EE +:10FC50005D9DE63D1FA5F8E4DF65018F757C15F11C +:10FC6000A6E9413AC7334FD530EFE18BC2316EACD4 +:10FC70007927D836D7A9C3DB01D86B4DF8E5CCF08E +:10FC8000A7F0BB757CD728F0FFB3F131567F6EF13A +:10FC9000FD33C307D5D78D1B79BE08978BEECBD02C +:10FCA00083B2A59F5B0E7C4CF16BF57246E77454F2 +:10FCB00097A1C580CE2BB4DBC80F57B3EB34B40388 +:10FCC000364219ED808DBDDD14A7AE28BBB50B897A +:10FCD000BE22ED67280F26332DFB3EE877B2A662E1 +:10FCE000260E53CF3D2463DC9B7D89D13991AC0333 +:10FCF0007E7EAF45C9AC1FA37F949DEDA5385020F3 +:10FD00007BFA8FB9B1CBE3C126FC819A23B51827C2 +:10FD1000571B590C59519552AC0699EC7446FB107F +:10FD20007E63EFF578DE12141FE927BAEB01F5AA1E +:10FD3000888B8FE724C3BADC5A23FA09C9A7548AEF +:10FD4000BF8F47D31488B2A222671BC25391800E83 +:10FD500024849FC7B52627E4581AFAAF7A87B76379 +:10FD6000BFE5E703C097687A3838845753AE8C17DD +:10FD7000F1F2E8627B3C990DC09CA17DD56F17DE46 +:10FD800083F18471C3E437F7AFCD7B74B2DE61F1E8 +:10FD900087695FD3AE37FCE2BE0ABFE31E8492A040 +:10FDA000CB768FC130BFE1BB71D2031E16F3BAC947 +:10FDB000BE584C7683E98FECC48A18FF2F66FC5E30 +:10FDC0002B67FBE9BC3D8B72FFC4E30733AF0ABE70 +:10FDD0002FF31BA46F3D50063C4A6EE6CD87F70516 +:10FDE000328F8BAC95988AE5A1F1D2B44FBF418A8E +:10FDF00075C5A421FF77BD16A3FC01B626C7662FE3 +:10FE00009B79A8ABAF29199F03CFACA1F3401AD2BD +:10FE1000E3EABC32B29FC3B9FDFF07E5EBFB9B36BB +:10FE2000CFF5A2FCC4FC8559F05FA0B32309F2D63C +:10FE3000F35121D32D7699476DA13898E7A3536CE0 +:10FE4000EFD36DF6F3834650AEC371C607747E2EB2 +:10FE50008369EDD8AE86D9CF097A3ECAB7D9E943CE +:10FE6000FD17D9DEA7C19EB1DE4F3172FF01A69703 +:10FE70005BFB3F7584FE2739FAD732F63FD46FAE6D +:10FE8000ADDF0E95C74793113FADBBD31E981AA89F +:10FE90002D0A4C1B257E1FE0F1C70DD1168ADFD736 +:10FEA000326078A093F33E3DAAF0F36C8CEC3656AA +:10FEB000648FDFD70AFA958122907ECF53EDF782C7 +:10FEC000CD61CE7BC2ECF6D073C82830AE1CAAEE52 +:10FED000A338FEC7411DFDAF91ECE5BE3646F1E308 +:10FEE0003981FEEB709FFA82CD77BA3A668AFCD7E9 +:10FEF00002C62EDDFCC05CB4EFFBC479BD8E884C1D +:10FF00007889D78EA7F337663F71379B88F2302EFA +:10FF1000F3FC04FA03E3F7E515DCB52903FE9CE7DF +:10FF20003B1B0D295E66A19B3E19F06A1DEFFCC2CA +:10FF30001EC5328FB8874DA3F1849D3B38DEB8CF04 +:10FF400037DEB322EE648ED738CF3EBF46B746F3D6 +:10FF50006B14FC6B8EF72CCE2F037EC71C4FE67400 +:10FF60003338DE05F6F9357A349A5FA3B8E777704F +:10FF7000BC719F6FBC0DAE9604DA6DDB24CEFFDD45 +:10FF8000815F75E0BABED7B03A4AFA40D8C5176368 +:10FF900003A877B1CAC75B50E44DADB58CB713E485 +:10FFA0008021F2DC0D0FE66F68544EB545E97917F4 +:10FFB000D8D906E56F94D3F77BDB6254DEDD369348 +:10FFC0009E663FE533F9BD33A7CF9632DADB870370 +:10FFD000DCCFDA96AF5D7E15EAA51A3F3F0F39F305 +:10FFE0001C6658EC5F30880FFA70FFE5325689BA0C +:10FFF0006DD20E0E77A46E5C0AD7CF5F79A8AF0DD5 +:020000021000EC +:10000000CA1E974B477D0ABC10CFE4A73E16E07E80 +:10001000B8C7CDE53D9BC5EF315C20F40A531A24E7 +:1000200017E2E3E26CDAEF5FB8C8086980B745927F +:10003000F48732A1A7F0DCCAA562A99C767E0435BC +:1000400006F41B319414DE4F7469D1E126D4CBF150 +:10005000D025E41FC4A1610EF473A9D09335AF7A03 +:1000600018E63BB0B96E8263D122BB3DBFCD97D6B7 +:10007000D03ED9561961B83E0B1BECDF3D6ECE87E2 +:1000800071C7BD050BC6B8C780EED2CA9047EA8CCF +:100090004F3E1AB0C7218FB38A5BEAF0635164D434 +:1000A0007B0CD6609BBC21FD369C8E393CAFFB9906 +:1000B000F0DBF6513CCC84AF404D4928AF0B9BF7A9 +:1000C000D9F29A00B1640C9B7178A6DC57897E88BE +:1000D000733E3BA5FBF247BBB7A480A9AFF7978B54 +:1000E0007B3DA5E1F37E2520F26F07E73DFB9932CA +:1000F00096897F78DC75C16125B6561FC28B8987CA +:10010000FF693EEA12787FE6FCF7ABB9FF5664BBA5 +:100110003FD3BC17F892C1B2CA540B3D5FBCCC4D63 +:10012000F60C33062A90EE8E9C1BE0F7B899F64B3E +:10013000FA2519ED972FDEBF516CCBDB14FD8EB481 +:100140005ECE3C42CB39D0A13C77CC2F91F83E56C5 +:1001500001E6B985F9FBA3763BD396E7B6FEC04F1F +:10016000258CF3DD81F978967DEB42F0E7516E1630 +:100170002DB7E7D539E132F3AA06CFD1CE5EA4DDA3 +:10018000A7D3BD89DD78114DD78E649C59F223CD5C +:10019000F381A63FED3C17A804F9FD795171DEC249 +:1001A000190FBE5E4E6A2512E6A3A6BC35F09C92DE +:1001B00093A8C2A3EAD72BC97A7CAF8C9FD58C7841 +:1001C00058DCFAED18C6EFB4DCCC71E9C5427F9F6C +:1001D0001BE4F18E575CE9628C632FCDA93D373863 +:1001E0002D43FDD6EF527F7346B88FFEB220A7BFD6 +:1001F0003B843E777EBF588CF3E51532DD6FE163BB +:10020000A1945482FBC6DD33E93CDECA9DB14CE7C4 +:10021000DE9E0A2716042D71075F193F7FCD58EF28 +:10022000D988AF8D7FBBB3F77E4065CEDF82244790 +:100230007314DEAFA5FD6599DAEFFFF8793AB7BC24 +:100240001FCFA9A09DCCEE9887FEDCD6C1324B4AC9 +:10025000181FCC16E5642BFF3E58AE9A578365A451 +:100260004120B29782733B915EB64A4C10E33C5EEC +:10027000DFC5EBFF427C9F73E15B3FBE05E5FD748C +:1002800037F9815B853D62C2F77290E7CDBC3C06D1 +:100290003E5BC5F720E233F299F0D99A091F2FE7A8 +:1002A0001837E0BAFB30930240F0FDCDBB06F3886F +:1002B0007FD0C66257C11CEE88EDFDE92D8CDA2790 +:1002C000ADF461B6BF28C7581B24788ED2FC4265B6 +:1002D00041746FD8C6198CFAC900C7C64CFD98EB9B +:1002E0007A308BCBB10FD1769E86EBCAED3FC5D36A +:1002F00017C5FD7FADFA7BD76920473A4BBA9B32D1 +:10030000D1F7F7437C9F3A7B8478F5CF053DBEA4B7 +:10031000C57F8070B46BB7D2FDAA6E89DB0D1B67F9 +:10032000F633C9D2EEB7218E6F80BB07EBBBCFE6A9 +:10033000F79E8600EF986016AAE6F06FD48F30CC57 +:10034000EB0E458F505E68A8BA9FF89D8E2A1470F8 +:10035000BA427FCD2BECB39F07BF320FEFDBC85102 +:100360004CBA7BAB13E946192A131DF5E4F0F6BF2E +:100370000FBDD5990491BB0BEC17BC872359C0F373 +:10038000469CF3FBA5807747D8D88BEB320C9F9E19 +:10039000FE1FDF02EDB74EE4E76DE6C87D4D572244 +:1003A0005D5E1824FB0BDE3759EFBF795DE0EBF59E +:1003B00020B79FB67EECA5EFCEF518895E7F27DAD1 +:1003C0007F0E7AFD5D263A017A7D06E765A1D7F7B3 +:1003D00059667A7D7E047A7D21135E9C6585193B82 +:1003E000707F56FD64DE6EEC4FBD68F68EFBE1A9B2 +:1003F0007C725392563326D9CE979AE3544A893F5A +:10040000072DF2DDBC9FFB9B41DEFFB07E674CDF1A +:100410008172EC24FA1DC0F938FBDD1FE4F0CEB97F +:100420003098C8746FD1CE10CF1BBF5BCC6B24BE8D +:10043000792AC4FDD991F8E681D020DFB050DED80A +:100440007CF3AAA80FEBE0C5FA63F3CD6DF4F49545 +:1004500071BEA163C8B386F30D4BBE487CD259C2AE +:10046000F9227FEB9F3B31CE31C847C90FEC7C941A +:10047000FCC0C6477FD9FA01D577B60F8F704F956C +:100480003EC8FFF109380FE34CAD9D9FB3E927BD8E +:10049000DDC3060E7828CF96E7B5FA9349839B0D06 +:1004A0007D0CEF3D2C1778D8853E18FA39D3459C42 +:1004B00049ED630B43C3F939549DAEB6DE23F06BAF +:1004C00031FE47A1F8D4D0341CAFFF74B4BF465AF4 +:1004D000A76A517F5BB6511DCA40D763E9A1CB43E0 +:1004E000FCBCEBE502EE9CBF795BD0FE74F2FB9C9A +:1004F00095BFFAEBBDA3F4739968BF20F4B9F97FF7 +:10050000412833FF5F1CB2F37F35DEBF9981FF2F97 +:10051000CBD41EF8FFCBA10CFCFF05F8FDCA50069A +:100520007E9F1DE2FD8F85EF7B05BEEFFD82F86E9D +:1005300017ED6F0A7D6EFBE0A65066FBE03BA169FC +:100540002785EFF611F0DD1122781E24F8437A900A +:10055000E2D85D33D85EA934231C5BADFD7875DE2F +:100560000FE0FD7D09E87ECE275DB14CF7CE40BBA4 +:10057000DBACF09BEDAA439A99BC7D2DFAE7775C42 +:1005800014A4783FE8C71DFF643AB83B94413ECFBE +:1005900091B91CFA20F820D9815FA0FFDE4CFD2F15 +:1005A000137436965DF098A00F98F7BF85A60D9747 +:1005B0007F3DE27752768413FB4384AFFEF928AF88 +:1005C00076DD9823613CAAC8484BE827EC15FA660B +:1005D0007248E7E71944BB5D6A5AC27C965D2D9A62 +:1005E00084E78D2CFD1D0E4D1BB93F271C00DF6FCE +:1005F0004224EF8CA7B15DF5901DF899ECA44BB2A5 +:100600008D2321D23FF1E7496E9F6697DBE63CE4FC +:100610007837E5BDF86666FE1D97BD41D594FF7F2E +:10062000B2CAFF17429AF9BB52D4DF67D53F00DF49 +:100630001B02BE3733C1E7C4CB58708E177A1EFA3F +:100640007B3F939E72F667FAADE63AB9512759E2BD +:100650003A5278D0EE656194DF1D329D435A20E412 +:10066000C98299D9C26ED7FCD8FF1D224E7EC7F22F +:100670005B6B70BFBBE726AD125150D0CCF59EBE70 +:10068000FC148A7F0644BF4EF807DBBB7B4FC77B59 +:10069000C761DC2C1CF7BCD92C8D7E6316DA0D14D7 +:1006A0008FD0E877BC723CDD518C9F6E94BA9B96DC +:1006B000A25E9D1FE4E74AA28BC6B8BF6D9D8D6EFA +:1006C00059B47A8CFA6BA9BE16E8A6FB2F4EBABEB7 +:1006D000A7BB29537E492C2C9B76D199A3E2351ACE +:1006E000A1B89689DFE1E3F0F5AB89B74888EF5010 +:1006F000B5A4E1D1AB10D009DA4B72591FE5337DB7 +:10070000A99AD30B03BF64F4FB333ACDF59E13CE05 +:10071000FBE27099F5461E4FD4739C57C07D2F8A1B +:10072000CF06B91CA38A507EF7706EC6B8BFF9DC3D +:10073000D0A615A92E6BFF29BE3F33983F1D8BA273 +:10074000BDD5CA383DB2A897EC30BAA7DDB29E4BF2 +:10075000C3DC7FFC4156FCAB61E2EF18DD4BC834D3 +:10076000EDA4E603EDAEA2762AB40B9D7CBB919F6F +:10077000E6EFD7C5F4B8E51E34935FC727920CEFB8 +:1007800099F157304D82F58F84CC7D424E07B705E5 +:10079000CD729236C9E365DD3C2F5F37E984CB1516 +:1007A0002DD06BC8958C6DBF79FE05D1D3A1BFB29A +:1007B0004414AFD487F213788F5A8EC2CBC0684FDF +:1007C0001C227DA19D21C5404FB5CF7DE27031E354 +:1007D00047A5E8F7D5E63E81F9843D66192FA428A0 +:1007E00087B27FB06C78A3502E1D2C27B1BC4BE88C +:1007F000C9ED37CF7DA23D4872EC662B7FD4083A15 +:10080000FC67D35F8FDEAEE13983645425BB6AA3F6 +:10081000831E7E157613FEA76A8914F2C5829B0695 +:10082000543CBAE22D8984901F2644DF4FE2FD79C3 +:1008300013668B34D5327E4F434F740DF1650FAE86 +:100840000BE36909189F1C5A9F54E6F5294FD1FA0A +:10085000F875FE5DC632F9DB3CFE1628E7FCAC7984 +:10086000787CEF2141AF07C33C7E7450C8D7AC6899 +:100870003BF953DE7A99E2C759F5B24D6FD02FE0BC +:10088000517DD5466F2FE724F6872D7A01962F5E8E +:100890000EF3F09F1EC9C1FD979A72750DFADB3FEA +:1008A00012F61FACD30F495E5446FC0992DBF1C728 +:1008B00033AE9BC0CB58EBF67C5B2256E71A79DD52 +:1008C0002EBB9CE7D33BDFBF28E4EAB1A63F7F0FF6 +:1008D000D965857780EEF3EE2A5B4B715833EEEAEB +:1008E000D95B932ED487F201D705C2B3E95C8A6342 +:1008F000DCE73FFDBE46E7443EF664DC4FFA87C0C6 +:10090000F391B6266A070B4CBFBF72054E85E7B15F +:10091000D9CEF199E711BEC638312C8A2FF912CA07 +:10092000A1A54D0ADDDB7005B3E7537CCDCCFB6A96 +:1009300035F3E378DE578265CF43365C9274FC7EF4 +:10094000048BCDC373F4C37E5742EC6F7DDD9137CA +:10095000F1E5A625B13A51EF3DFA7F8AF0B748E7B5 +:10096000F277518CDFDF7369FCF2589D653FFA85A1 +:10097000BF2B19F3262FCA32F1118FD54D1C8E8F44 +:10098000A571C9ADE963E3E564F1B044AD9C97A7F7 +:100990000FC78373FE80B1AD88E7AF039ED1EE1C15 +:1009A000091F508FD6E385CB15FA3D99794A830B01 +:1009B000F741AE6C94688F09F01B1679710D732D99 +:1009C000F03AF1E8C4D7958F323A3770E5ED218AD5 +:1009D000B73D67E2277D1EED5F98FB2796791EE500 +:1009E000F95B1ACD73E1CCCAC7F1DE84443B485BA6 +:1009F0003E5FDB3EE05216CFC2730B30EFA323AC59 +:100A0000BB6D3FD0099F137E9FD02BCE7D31A6A614 +:100A10002B500F1A59625F700A8B89FDB12C4AC79F +:100A20002DCB2C6F9DF7CD997476456BE3E0B8D84C +:100A3000BFC41283650DCF6B3DA96CBD14FEBE3AD9 +:100A4000CA7FD7307E796E077E5BC0CCDF1B3268F1 +:100A5000BFE90A81BF46F0F8F0B7D0CE03E184FBCE +:100A60007A0B0C9F1EB4CCF3DD6EA95E9CA3CA5A10 +:100A70003419DB250F285386C3BB3ACA7FBF10E861 +:100A8000F07D2B1DFA26F27B659D7831F175659618 +:100A9000D8379CC2A67C16BCBC848A731AEDD7904A +:100AA0009D3B2079E93CBCB98F037F4DBA4174B6B8 +:100AB0006695083B80CFDBBCBF8BB116B2EF178BBE +:100AC000F358AFB858D30341BEAF5365915B37E4D9 +:100AD000D4B46659EC6E735FC7BC2FCAA4E7AF7974 +:100AE000836985D3A1ED3EA8A13CA604E53129592F +:100AF000CB75C447177E3A9BEC9EF5D8BF12E0FB3E +:100B000055BE271FEABA541F5ABF4D573DDC3D0D55 +:100B1000CAFEAFFF3E499DEA3984B79058B71AB173 +:100B20006E267CFE0AFEDEB27E3C7E562EE26762B8 +:100B30001D47D213E63A9AEB867614D2AFAF5CFD2E +:100B400024D3EFF0B143D503C8A789A84A39740963 +:100B5000E9B50EBA678BE9BB70FFFD8A5697EDF7D2 +:100B60009712784E1FEB6FF409BF2446ED97E6F31A +:100B7000F6AC9CDB8D83749F84F6963C20E60D8F4B +:100B8000C375EB87B6982706FD8D437DCFBA2CE35E +:100B9000940E1F77C4FE1CED94C17D93582C669172 +:100BA000D70F65713DF96EB4BA57CE107F319F4BA8 +:100BB000BDB945AA253FEC68BEB729D3BDA4667F61 +:100BC00083F7C60DDA896F3F71A868C84EDCEC7AEE +:100BD000C36E27B237BE909DF872D61B4FB4033C4C +:100BE0001FFED143FAEADD7A3FAD436EEBF9ECBF6D +:100BF000F0BCAD8ABFED47F63DDD7BE36D2DA4F97A +:100C0000482A600E7F1F4C8F4988EFD7F0925E8C88 +:100C1000DFE92C1D02E072D59884F8BA55F8A3409C +:100C200067A75BEF677D2D8BDB5BE6381E2F4BE202 +:100C30003963B35FA083B59457DAC0488F98FBB08F +:100C4000263F9BFD0C64D9FDE093E0DF814CFCFB6B +:100C5000B4DCF2A7EFA0FDFA9442F9A05F8DDE406C +:100C6000EF2F6BBD929E97B75E43CF4FC478DF9254 +:100C7000129F64C17AF535FDFEABD703BDAEDAEB4A +:100C8000A173652BBEF5D79B913FBDADB0EED8EEFD +:100C9000EB57DE3E0DBEBB27CA64BF7615F37C0E54 +:100CA000F75A89C7FB75773DC650FE3F378B9AA828 +:100CB00000800000000000001F8B08000000000002 +:100CC000000BE57D097C54D5B9F8B973EF2C496662 +:100CD00026933D210B37842548C049202128D60979 +:100CE0005B632510C40525C0844008109280568798 +:100CF0004A654200A3468D75C3A5BC8162ABADFABF +:100D00008252A56DA4137101A518ABB5B820417826 +:100D10004ADD12411EA3D5FACEF79D73927B6F6612 +:100D200042687DBF7FFFBF177FEDC7B9E7DCB37CAB +:100D3000FBF9CE77EEAC7096E4BA0A09F90EFE2EF6 +:100D4000266485731A9649AAD3448A085963A3FF77 +:100D500056093973F8E6D4C5898444DBED6EFA840C +:100D6000581AB3EF34D132D92F9347289063C8A2D1 +:100D7000F23C0AAD0C0E712984240134218C074801 +:100D8000FBB585244212A09DDBDD60A765C54F5CE5 +:100D900000430A3EB74852795B5EDF7C0414FDD9FC +:100DA000423221E3613CE3FB167C7E8B6A2985F7A6 +:100DB000E504360FF17E0E7F3F87CFC7168A61F3B9 +:100DC0004830F6E364CF65D2D066EF3F8FF5B1537C +:100DD00047B992004F9E5C80847499CB1D842CB4DB +:100DE000BF72481A47A1CD1E9429243EF3A75DB9CE +:100DF00004FFBE1B06FF5FE1FA700C2112E992BEF0 +:100E0000A343CFFA460A0EA5F88B2A91031BB229F9 +:100E1000945C651326D066256637E0B37378A263C9 +:100E20009866FC0B5C12E2EF75C5E58079964F97EA +:100E3000CB0379D87DD2E5D0CFF4AAA25BD97036A6 +:100E4000924CC822F66FF2BABAA37918ADF7FBCD6F +:100E5000EE11948E8B6CFE00CC6F1151FC5D366CE4 +:100E6000227D2721549522FE1E9DEFA269B227CA3A +:100E7000A96B47BEA3F3241BC90BC369FF0B253E17 +:100E8000809F96E97BEFF3E29169A7AE80657411CC +:100E90009765186DBFB0AB722619875576E0A7A588 +:100EA000BCDD229FF9786FBFF47F957E7D797171EB +:100EB000FE4B940C142F81D209C067A34DC867550F +:100EC000CDFA764BDFBBE46FC409FD2AC77BF10D79 +:100ED000F32477313A4F6F72A9144FE7BB542CCFEC +:100EE0009A766C1AA1E5D9845C01FDCE9E26BB8260 +:100EF000B4758BCF443C74E2073D7240A26B3B98C3 +:100F0000DBB5FF62C05BB1597D04D69A4B6E9F9BE7 +:100F100008F5E35D80E772789686ED098176A9B6DB +:100F2000C008FAACD373CC5EA5E1BB83C5C7467BD2 +:100F300029BDB69A484D387E22A411E9FAC24FA2C3 +:100F4000B19F23F748012B9DFF74F99B3F4DA4F3FC +:100F5000A9FAA9D96D55715926A0EB4C3793474290 +:100F60003CF6E9149F0B092B1F23E545413A7E55BA +:100F7000FEE1122BEDA76A9384722AF04FF1FD81F6 +:100F8000166FDE86F2D8A08A78D73DA79D59809F3C +:100F9000299E3F8880E70FB478F6BDF7F6D817345E +:100FA000ED5A5C8E44E07352400ABEA3A8394D2628 +:100FB000C78E27FDD72DE099F587C6BE3082907B7E +:100FC00088E76E2E4F4AF9584A278578C2E9815240 +:100FD000279383E9F2A7489F93C5B20AF83AE8FB42 +:100FE000D84E398C1CFC462E053C130FED6C52DF9D +:100FF0007B8FB92C48FFAD16E2013C6F1D620B34AC +:10100000D2AE3A7E725E4A17D247BD7F32D0F1151A +:101010003379448D3C5F874F26C3296396F9248436 +:10102000827E437D514419DFD76E28093FFFDF835D +:101030001CD37924AD2326958E1BE7279E4018BE2E +:1010400010ED56D97A662804DB07E3E8FCEA54532E +:1010500040A2EBCD97183FDBCC0D9E74DA54699F0C +:10106000E34F27300F19E7A1D2F929747ED9BE18B2 +:101070002C0FF32520CCF1C5211CEE4BC7FA11BE75 +:101080001C84237DD9F87C946F0C96737DE3118EBC +:10109000F6E5233CCF7721C231BEA9D82ECF5782A7 +:1010A00070ACEF527C3ECE3717E1F9BE3908DDBE99 +:1010B000F9589FEFAB4258E0ABC4E7E37D2BB13C5E +:1010C000C1772D960B7DAB1116F96E4438D1D784BC +:1010D000B0D8D788ED26F96EC3F205BEBB115EE825 +:1010E000BB0BE164DF43580F0A08F010CDE5F13681 +:1010F00075898B4A0A70B80A7C1C49EEBEE2F6A8D4 +:10110000D2E5390AF64EB4B3988857DB5EB43BCDCE +:10111000611CD0354C7F3D5C3F7FEEFEE0BE51A4AC +:101120008F6ECDA98DE544EEA397755749309DFE8E +:10113000B36EF71C027A81E426EAF8B4BF7E60EB56 +:10114000EBE2FA6BABD2E991817F1B88DB4F1F95F5 +:101150004D785D827EB6A94A69200CBF8D8E33E33F +:101160007BE7BBBC248ECE2F26FBF80BA04F66FB83 +:101170005D7F9A02FC9297F8CA14DADFD08D2618A8 +:1011800081AA1257C714AA77D46904F5E2362A72E5 +:10119000B0DE6DD17A7B9A1DC7EC28216DFB86A14C +:1011A0003C0D2F60F6A7EB12902FCB4F86915BB3CF +:1011B00041DE829242FBF3AF21E4116133A0FDE6F0 +:1011C000C5BF84FABEFE2C4C8E9AC9F3363A91EC18 +:1011D00056754A1485395B3CCF47D1574604BC53FA +:1011E000A26979D4A3FEE7018E6E0B4C89A170CC65 +:1011F000EEE0F3D49C92B1C1AE29765A3E7F1FD95E +:101200000B68CDEF54A73A6879FC21CF5ECA06A4DB +:10121000B0CB3BD5A9C27C024D4E3A9FADEF1377C0 +:10122000232D177FDA2AC7120DFD2DC4BB53431798 +:10123000C784CE6909F49F19D7B9F265785FE98A46 +:101240008ACBEB4F9F6DB06E5827B5238FD0756555 +:101250007882924BC327657192A0437E1CD8A175FA +:101260003D0AAC73DBC67807D22FDA550243F64C41 +:1012700027AEED2AF0B18278B26C1A86F22EF88E83 +:10128000E277F41C87166F92D06B356D7991F15B24 +:10129000F66F86DFF7383F47C2AF0D7865D2D9E5E4 +:1012A00078615CAF1C5F03788DD4AE298EC9A7111D +:1012B000CFDB4C641FB555745CCAA74CAE889F3613 +:1012C000BD89F3F7D9F0EAFB37C3EB157103E3955A +:1012D000A889A82729BF8E263991F50DF417CE7E4F +:1012E000DDCEF94DA3E72CE02F36BBA89ECB89AC11 +:1012F000E7AE8E3B8BFEE27AC6C2F5B818EF413EF0 +:10130000DE2BCEF22DA0BFEC9B4C7E90B312E240C0 +:10131000B920A9899C4F5CD1C02733655709E81BC8 +:10132000328AA01F1D9317F0C33E65A85F2D90A1C0 +:10133000192865C0E390DCC0ADB4EB6CEA67289473 +:10134000FEB4AB20409BEA322DA6EB8E15F2E6AA46 +:101350004CD5CA9BB0F77DF228F8227EDBADD98C44 +:101360005FE750FFE56DCE6F7DFD48D86EF3DA2163 +:10137000DB6ED5E8C16DA9A95816ED23F1EF19C1AF +:10138000BF1B37102FC8C7E4F07EC31B7132E7DBE9 +:101390001E0FF0B9FF07C405FE4CDCC60F503FC559 +:1013A00051FD24A17E62E367F8A27FE9A7E53FC76C +:1013B00025737DEE8ABED2F1FF8E9F7F45110BF320 +:1013C000183AD9D521D3FAA1D40EA920A793E9DCE4 +:1013D0002700BE2C487795303AAA934900FC5E8AD4 +:1013E000B7A009F4AFC911003B63B1B47A409E893C +:1013F000250ED7FF8AD37B346E00B970C5A8F9409B +:10140000D493715F95DA29FF6DCE764543B99B96EB +:101410005B52E9B8F15D84979BED283FF46F085269 +:101420003148F706601F45D96383F6C37ACB7E281F +:101430006F059FE402DAFF5D67F66DA488991BE7EC +:10144000E989637C7D12F8DA338A6E5073FAF8F911 +:101450006CFE8090CF3E7972E50B79AACC437DF883 +:101460000DF42FFA8BE4DF3CC3F5A7237E60FF4623 +:10147000F0FD39FB377CBE7F07F92F8C2CFF51FB29 +:10148000DFD8B28396D7A4CAEA71EADF3986BCD521 +:10149000A9D0B28DFA9BC768D964EB54A05D1995A9 +:1014A000503BC5B7873A79B0FFB04D6065F883FD12 +:1014B000C7C956A994E96B35F6F2B103E13180F35F +:1014C00059936AC1F1A2460C8F05B97272BE228A85 +:1014D00014003BEE2C76298BB1BF2E7219EDEF3C38 +:1014E0008E2721D7A0B79ECA03BD14AFC07EDD6A88 +:1014F000237E477C5FFF508E2DE8D34F84EFE3AE11 +:10150000E57BA6D60DEED8E120A707591CA5F52648 +:101510002697651924B001F48487A82EDA3E8A88BC +:101520003F2AB8B46CE6A5995F4BC443E77FE06BF4 +:1015300019A1349C041D74BF57E69682B00FB4986D +:101540006C01B0A525436CC40265A7296005F9F8B4 +:1015500040C2755A0A6202A0FCA60D298EEDA2EBCC +:10156000387560AFDD1B86FE57792BDDD3C647C6C5 +:10157000636FBB052FBA008F0FA91B5DE047FA53BD +:10158000158C3BDC024D357AFDEA786637A93F348D +:10159000379EC2594B7A365A80DED989E80F91E1DD +:1015A000F1C8B769A9BB6E29019355CBFCD321249F +:1015B000D0A8F5AB047FBD1BEF5D104FE143DC8E7F +:1015C00050B1EC1C09F1AAD189F1E09796D40F69CA +:1015D000077FF781F5C4BDC48CFAA01CDA7B12DA50 +:1015E000F2817F1F72EF7AEC4EC0A795EE8B418F90 +:1015F0008F3F6C5729BD2A0AF726C17AFE6498BF2F +:101600008015BE9B102FC67DF0AA78BA0F068538CC +:101610008E8C837DF029F7DCD820F2564258F9AE43 +:10162000F0DD88FD88FDF07BE660A62BAC1CEAF1BE +:101630002DC6AF90D8BE969825A6FFB81DA5FA6511 +:101640003DE097BE8676D36395B683BD39E51EEF40 +:1016500006BB1D49DF88F9503C8E287784A997483E +:1016600079383DF1403CB3D71566BA5FA0F5D2EAB0 +:10167000C206985785C32E01DF89769BE2993D13F8 +:10168000FC2CE25572EC3785407F880F865BFF2289 +:10169000A27CA98D476D02594B62F87287F15722DF +:1016A000E1EB90B9B50CE67568A94C1A693FA7BC87 +:1016B00013534898F7057C07F886D2A53E818DD74D +:1016C0004BCFE1E1F177687D8D7B9AB98F9EFDEA82 +:1016D0002BA3E681FD9E0778D48CFB0AC7DF3181FE +:1016E0001FAB5775D17ACBE27B5D642CE8A92F0B39 +:1016F000FD0E888BF5FCB611E8FD5307C62BE655A9 +:101700009E2E6C1CABC167314123B968EF032E9547 +:101710003E9F37626392DF1E198FC7381E6F8307A3 +:1017200093301EF322F2CD20E331242F1EF98DECED +:101730008D7207211EF917D90D7E038CEB45FDC96B +:10174000E2C9D7B9D8BCA20C7EDE3C5F9D4EBFC4B7 +:1017500084241248D09495368CCFC684147C6E9421 +:10176000B75F19E44DE03F123D05FE8DCF9FE7784E +:101770003F54B95C85B8A1253ABC1F9C96C0E824AB +:10178000CA6FADF7EAC6FBEBB7B26EBF2CE07F7352 +:10179000FA9EF24E4A8178D53C8B7FC460E45CE0CF +:1017A000E7AD6FEE7741BF515F59C3CA5F37B74F9F +:1017B000D49E365FA16AECE9D5F246C07B8CC2F5B7 +:1017C0009B41EE3C6057293E2F06BB4AA718731673 +:1017D000BBBA88F83B208E6C1C5FD853237F09FB73 +:1017E0006AA49BE08384041E37E4F41371C348F2B7 +:1017F00025E4EA5DE0DBC2FEF837C2AB2C7ABF47D6 +:10180000C013BDF488227EAA1FAF2D91034442FE6F +:1018100040FB78E85E09FDCD60A515ED72556514B5 +:10182000C667ABF265ACAFBA5D46FB19A4FAA196E8 +:10183000CEE74F5C4F18E3B32544724FD3AC7BD651 +:1018400084285DF9EAA577FF693DC4978BCD2A8C82 +:10185000775065F166BF4746FF95F6E10E427CFA88 +:101860009E8BDC60CF043F1CF4C8286FFE376537C1 +:101870000CDBC9E3D1079BF30332D059F2F68EA3F8 +:10188000E640FF552AD0E1EDD42D2ED07751DFDE92 +:101890005F5E8EFB47AF9A8F76933AAB74DE515CF6 +:1018A0004EA70E29BE12ECF891163381B8D191756E +:1018B000A7509EBBD637B8A78DE88B2F8BF8B031D9 +:1018C000CE6C8C2FF78B2B1BE2C9821F8C7C725540 +:1018D00004FE10FA2A127F503DB630E19FD06342D9 +:1018E0007FBCC3D73975C896DB1B291E6296C88892 +:1018F00007C1976F7F73F3CF410F4751FED800FCAC +:10190000FCEDAF5E847D08592E858D23FF07E737F8 +:10191000BA4F744FCBEDA3CBD5DEE5BD6510FFF913 +:1019200035AB7BCBB07EA35D89ACD706D65BD9093E +:101930002C0E6EB43B4679F8BEEDCEBCCA7B73E18B +:10194000FD79954B03006F1962AB01FD6BD4134613 +:101950003B21E6639C674C482681F1DA79ABD8AE2F +:10196000CF4E58B0DE67738E0367FD4C14837E70D4 +:1019700002C12F7D3F2AD084E3359C5F8EF36F98A0 +:1019800008D047DC5D7E585F6A34C60F5A33587BF7 +:10199000F99268E68F4F88C775CAC221FF320ECB15 +:1019A0004D7C0DE3E2BD4F02BF35794C5170AE3036 +:1019B000D5A1EC87904BEB1413B1923E3C09FF9DEF +:1019C000406480AE17EB24D877E6DB2C39E89F3EE5 +:1019D000930074B889EE0B29BF1F3820EFDA4697C1 +:1019E00078C03D3E369C7F2EE082D4B5A817AEF479 +:1019F00055213CFCE3BF6681BC5E2F793B605E9D58 +:101A0000F3AA6E2FA4F3A9DF2DE3B9D282EBDF1E78 +:101A1000C9F669FAF349D969CB85384A9314ED06BA +:101A20003D22F0D8E1B0A07E693ACCF460D3518970 +:101A300097D93EE2055E7FEA3D07EE3304DEE97AA0 +:101A40003A613D9EBBE3703D629FF12FACE75DE8DC +:101A50002FF27A325CE80F005FC97DF3971D0AAE62 +:101A6000AB9B44BB61FE3E1E0F22EF45A1DF2CE87D +:101A70005BCFF94FD0B78ED3B7BBFDF41D17D2F6AD +:101A8000AD9E783C65903309AEB7FBBD18E40FB14D +:101A90005ECA07DD80EFBDEDCC4EB4BEEF60F872DC +:101AA00014E5C2FC847FED4A607EB271DD157C9F37 +:101AB000FE7502D34BE0DF429C6271FC94AF130AC7 +:101AC000C3B4E77E2DC5F3B780971217F93240FAF9 +:101AD000F02CC611E38AF7A212F5F255C1E30AEF22 +:101AE00099C93C8CD3D2710B34F35B1B5F12959870 +:101AF000D47FDC7F818E898903F2A59E8EF58ABD15 +:101B0000598A25BDFB620CA5A9FDE5DC2867527B3F +:101B1000C757703E6F94FF33A60622D17E6F90BDEB +:101B200087E2296CF2922E6B4E7F79389B1EA1F4CE +:101B3000CE4B4CEAAF4F064BE78989FDE83C31714B +:101B4000003A0F8B2F9F04F5B0FEF402DCE75D082E +:101B500065D0139661381EF2654F1C096CA78D1273 +:101B6000781C45CC07E21251F4BD1F256623FD25E4 +:101B700085F8CDB49C90EB9640EF0F820F7EA49D2C +:101B8000DFF7C007570CCC0741F44B56717AAF1200 +:101B90007916BB06CEB31804DDAA60DC3326778F36 +:101BA00037FBDCE956D79F6E7503D3CDBB1AEA9B92 +:101BB0002CE44BF4C38B2B5361BC579C9EE3B1F4D4 +:101BC000F99E46AE4FB229DD68FD8B8932EAAB9FA4 +:101BD00091F3500FFFC064C2F97753FDBB3D3B1C2E +:101BE000DFFB9578FAFE99CB089EC7D1F5F9195F0E +:101BF000FA25787EC3226282E7A96A23319D831E7B +:101C0000BA8DEB09CD3A6F4B0C6397357AE80EA885 +:101C1000A7FC781DF0A34D752903E9A107CF5D0F3F +:101C20003DF83DEBA14706E6BF73E6AB27C3E903EA +:101C3000C1C7625F10295F88CA23498FEF3F2E21F9 +:101C40006E3C0F2B71DA98DDDD29A19D6D3A9AEF7C +:101C5000C5B2C3864A41D8E193BB58BD3C25BC3FC1 +:101C6000F86C623CF2EFAAB6D56E459707E2477A68 +:101C7000DCE939E91A4EF5E20CD98EEB4B2863F119 +:101C800043B17EAA67674E4FE67153BA9E844C8675 +:101C90008704EA0FC0399A93EF0F628B159DDF2FEF +:101CA000F076835C2E41DC3B2E9140DA0DF5EBD7CC +:101CB0008D82F3FB388FBE7D1269F942C64108CA96 +:101CC000433CB5DF10C74A2835B4837DC83868AFB8 +:101CD000799EDD7F3F713491EF272C2415EC0A911A +:101CE0002B06E41BCD7EE244E220F6139F278AF305 +:101CF00071BDFD6A8B2261E302EB92B8DFFD651CCA +:101D0000FABF32B75BD3BAB2313F658D43C5788134 +:101D10002CBB6D33B3FBBF1FE7311155B3BE84D26B +:101D200068A26AF60F49E5F1BA72CABC21BAF6692F +:101D3000DE61BAFAF49AF374F5990D05BAF250DF40 +:101D400005BAF6D95400B4E59CE61FE9DA8F68BD00 +:101D50004C571EB5E51A5DFBD181C5BAFA318FAE7D +:101D6000D0D58F6D5BA32B9FBFFB27BAF64D3CEE02 +:101D70006BC4CBC5494C3F37294CEF34DA0B301ECE +:101D8000D964D7C723D338FE4B6227E7421CBCE98E +:101D900083FC5CC0F70BCE0B302E1E892F8C7A2C67 +:101DA00092FE343E2FE6E37DFEBCC5047250B79729 +:101DB000CAEBF9B46C7F6733ACA9398F9DA72A842D +:101DC000E5F788F315F17EEFF98AE266F155A79DF4 +:101DD000DC1A862FD292F4EF093D29F82812DE048E +:101DE0003F9E0D6F9EEF096FEF49649E761E15FCB6 +:101DF0003CDBF8DEDA24133F0FF65E93C4FC9D094A +:101E0000D1E889BB501ECF55FF8B7950FDBF3409F7 +:101E1000F7136F2CB801F4FF2EAB1BF6649FCF7B3A +:101E2000A3FA7E15DA57B3F626772ED02552FC7B1F +:101E30006D52BFF8770D8B7F47EBF0B64CC8BB21D6 +:101E40000ED7E4FC1AE3DF4D1677EE60E2DFCBA09D +:101E50000F383FE474EEA52F8F9F47DA07F908D9B2 +:101E60002FC1BEC7AEA870CE75B67D2DDDCFE6C240 +:101E7000796A2BEC9B34FB1CBABFE5FB9B28B40BA7 +:101E8000D4EEDD9184EB22FB55FAFC0CDDF7DEAAE3 +:101E90004251D83F8FCE2FB712B7CD22233DEFC18D +:101EA000F76E22D745C9102F0B1E989CFD2FD9F332 +:101EB000FF481A707F68B4AB673D9743BB5346D762 +:101EC000BF218CDF653C87EBF5BFC14F93F03C0E23 +:101ED000F1B489DA45388FEB4862F679D361B64FB1 +:101EE000DE74744E2ACA4D52D180E77083D5371DF7 +:101EF00049FDFCB58EA401FC35B1FE357CDF3B5DB0 +:101F0000CE6B8378E3C99005F12613961F59BFCF96 +:101F10004C02484F96672CE8680E6DEE04FB6C2669 +:101F2000C6BC623516D66DDE27A37E2289ACDE4F95 +:101F30006C8DE0E7C416EBED569C476FB7124AE391 +:101F40000D764C6FB752E6E9ED569A576FB7D26BE4 +:101F50000A0C764C6FB786FAA618EC98DE6EE5345C +:101F60005F66B0637ABB356A8BDE6E8D0EE8EDD6A8 +:101F70009847D718EC98DE6E9DBF7B83AE3E3F78C6 +:101F8000ABAE7EFCBE9FE9CA859D0FEADA2FDBFF70 +:101F900034E6DF4C3CB45DD76E52D7AF75ED28C246 +:101FA0003B214F7B099284900B4F3CA5AB5FC2FD58 +:101FB000B48B7A7EAFEB87B4B27C6B3FFD0FE8F554 +:101FC00011F15AC0395148CF4BE994AE7501C91D82 +:101FD000A4CD96EFDE5904F3F8E4FD4BF6413FCB78 +:101FE000B6E8F3B49707F4E57A322C16F4433DE5EE +:101FF0008B00E5939590BFADD16B2B498313F321F3 +:1020000006C967CBF6CF2598F7E9F774427EBA5830 +:10201000A7E0370FE737313FB1DE95D4EF0BAA7D4C +:10202000EBF4D0FFD83EB2CB027C5BBD5B220F4A03 +:10203000FDD753D37ED7E6F430EB32AEC3E877BAA0 +:1020400093F5E754D3653BC6F54FBE29BB597C5089 +:102050002F876BF6B378FE9A27248CAF19F121FCF9 +:10206000D2487891FD6C9F509F4802018DFCA91CBD +:102070001FD654BDFC9D847FC07C1E960390171410 +:10208000A5461BF9AD2848FAE33926572FA7463C49 +:102090003BDC43C2F2954AFF83795413762E65E404 +:1020A0002B23DEEB76DF6501BD78AE785F64C0BBC5 +:1020B000383F28A1ABB584C9831378A5FBF2A5C925 +:1020C0004991F7ADAB9325FDF9F2D9F7ADAB93BFCD +:1020D000DFB8C9BAE401F6ADDD102FA37EA5315EED +:1020E000D63F3EB6F72BC989716816FFF2BA6D2C40 +:1020F0005FC5602773537576B277DFFB8114680282 +:1021000039767A6E83F9D43A3D2D007FE4F4DCAE63 +:102110005D6F13C50BDECFA1766A6718FFF0E5642B +:10212000E11795635C6453096B6F6CB7335941BC1D +:10213000772415A5A2DF79349FD94F47D1807EE758 +:102140009DFC3CE736382F1CD197C7733B3F57A106 +:1021500062E701BA6D3297A76AF37CEF498EC3F14B +:102160009C939EEA847CE72697C925A9E03F9BF0D3 +:102170005C74A3C75EBA2B8FBD97A87B8FDD3B92A3 +:1021800001DFE0CFDB95AFB57CFB32C525F41B69E1 +:102190009D2F27337FD74C3C36D0BBE23CD7FC4148 +:1021A000BE0DF4AD22B95DE1F238CD3C4F6A0A3F75 +:1021B000CF955DEC7CB757CECF922755E7F4BE9410 +:1021C000ACF117C4B9EE954ECFCB404F9FE2B7822A +:1021D0007FE9B385DFFFFE89D3F156BE3EEA682270 +:1021E0001FE1F8F2A0E2276F25635CCE8FF98A37F2 +:1021F000C8EE13109F1B6CBCEA6872BFB8DC512D8F +:102200001F1AE58FFA9FC763E17C22768882DB097B +:10221000C59D0BFCDF0CFF9E84F1D513F07EBFFC47 +:1022200053359EE7D3AA03E6D38A7EE6C679BA93EE +:1022300059DEDF17003DA35C1B654D3FCEB3F44371 +:10224000F194DB601F14FEFEC1F0E73EC18209E796 +:1022500016D78C4AE9E73F46A50CE03F9E393C2A59 +:1022600016CE9345DCCAD8CEE64BC8D0DE8F698E39 +:10227000D38FBFB9809513F9B8CB6319DFE7F2B2FA +:10228000C80314716BDB4CE281FB0E3FE3F9D9A26A +:102290009FDC1407B68F8B9F929B5208E76912EE62 +:1022A0002B37C749BAFDE5F1E4925C58CF30DE7FA9 +:1022B0006E0AE3D36DC3587CC69807F9196FFF59AE +:1022C000F214849460A3019F16590E8BC7B1296C38 +:1022D000FEC76359BF227E56752FBBDF25E26622FB +:1022E0000E483D83B762A85E39D6622610D75A2AB7 +:1022F000DB37031FF6DE9FE3E7EA2EFA1FD8CBCACF +:10230000BC72CC3FFA57EF6F013E63E2FBDBCBE9D7 +:1023100029BDF6D27D8EF7B86632FC0CEEBCBD2B23 +:102320009AF16D8FC38EF16C63BB6A4E9F161EA728 +:10233000007D0D76235E260DE1EC4735C7FB99C382 +:10234000560FFA31A5D198CF21CE3F14CA9FB1F1D3 +:102350009806EE0768F3A567C07DA2DEF30F95E04F +:102360007B09763BBEA7A824E8802BA18A5B82FC70 +:10237000B22E4BD7A61498EF45921BEE0FA454B87B +:102380003A5212E11EA18A62B6399B388BA13EDF18 +:1023900084F57197BB369B21EF5A2570924DCC7412 +:1023A0001C071DE78E946C5C7F8B7F6E470A6D1750 +:1023B000ABF6906179A0475C3352418EE7B1FC7572 +:1023C000E3FAD6A730BCD937D17D03E0430D9F0790 +:1023D000BE3E85E501513D7313D0A34425BBD8BD56 +:1023E0002896870A69D6982FE866F9D231906F94BB +:1023F000C3F40CD4DF15377523C88F902F99E31BD6 +:10240000F85E9B0F7F07C77782413E053EE9008D4E +:10241000900FA1CC24C8D7B32BC2CFF7314EE77AA7 +:1024200067F93D30EEECC98D98E74EBEF9EE3BB949 +:10243000089C5E2627F47D027188A844A67FA354D9 +:1024400015F531714998676A53DD35508EB25FE0FA +:1024500092C1EE59F979E1121351A8BC4DE5FD780E +:10246000E611E9C35C166765FA55211F0AB9903970 +:10247000728AC07EB23FEA17B5C4D0F54CB51FC012 +:1024800073C4A8E10D2570AFE0C545AC8F9F45C86A +:10249000DB3FCEF558BCEC4D35814F4F8EBDFA4237 +:1024A00006D2F93CB8A179DBA6C3AFEEBB88C7CF93 +:1024B000215FDC7FF8554FDE3F9F5FFED2FD875FD7 +:1024C00085FCF27F9EFFDD12E8F1E394B160DE4609 +:1024D000FE17FAEC90EC3D7423C5FF1594A97C051A +:1024E00000155281F466F94397733CFBBFA678B69A +:1024F000F5E1F98AF6FD88BF43663A6F3ABE790A7C +:1025000043B5F927B13C1F2380FD5F696B9D0EFE2B +:102510004DB7A5671C8CDBFDDC5F33FD549F1CFEB3 +:10252000E92907A1FC7744E971C0F313EBDE707869 +:10253000E87A0FAF93F1FE1BDE4BD6E4039DE07CFF +:10254000353DB5FC08F0D5A2F5DF1669FD6CE24B10 +:1025500042BBBB3C20C31DDF5EFDB7F2D118CE7479 +:10256000ACBCAA2D415716F6789535FC3DF1CC54FC +:1025700046F7E58F6FB3403EFCF454EF1730FE0989 +:102580009E6F70629703F757623E8B1FCFB7C07E76 +:10259000F248BB950481EF954E33C1389567A64448 +:1025A000F9D6CBF9D038CF97F6C4607F4BEF953191 +:1025B0008E5449C7F251BC7ADB97B3FDAD611D4B18 +:1025C0000FAB33405F2DBD45227E95B55F47E9E6F1 +:1025D000F5DD8CE72BC6751AEDCB69B2CE027AC455 +:1025E000685F961077F364B05BADFAE7CBDA6FC340 +:1025F0007E979DE53C262195DB9B2232F1BB1C8812 +:10260000330FC37CC148F6E6C47A26941FAFB721C6 +:10261000FC74BD0BE11150A614CF2B7777BC948EC0 +:1026200062DD590476286AFF54DB35A4CF7F56B6A5 +:10263000CD0D3EA4025FEAF3212B389E85FFBC8CB2 +:10264000DF33389BFF5C01EB1C201FB26290F990D6 +:1026500027F78DB7C1F3C2547E3E3591E203ED6F8B +:10266000DE6B2A39BBFD8D849748EFAD82EF1C8469 +:10267000C1B3909B23DC8E2CD93167F3103A81A62D +:10268000E73ECAEA42BE647108714E25A76EEE8429 +:10269000F5CBC410FFF3933789867F8DFCB98CB8D6 +:1026A00099DDB1B3F76C3C2ED1CB97EDB7235E0526 +:1026B0001FC18D02532AC060AAA9B8FF7703FA7D13 +:1026C0001FA0555FFEDCDC95057A6399215EF0B9A9 +:1026D000147EFFF5C3D4616CFDAA6706E4452C2582 +:1026E000E59B595CBD159F9F505A5FBA11E479076D +:1026F00093A755CF3EF10CE8A915FF79AF13F4D499 +:10270000DF94D66418AFF6914D4ED0EB2714BF136B +:10271000DEFF5B400E7B5F777BAA24F2E2ED901731 +:1027200056872C0602E69F057AF2BF1F31BB208E2A +:102730005AFFA83568A5F8A8DBC5F048CB4759F97A +:1027400066C457FD6EBD1CAEF8D5BDC92AEEE7FDC7 +:10275000E91C7FE9A0AAEB7698317FB4EE4DD90D44 +:10276000C3D4931E5C9FF17D984788D2ADBE4DAE19 +:10277000B4C4F6AFA71E8F05E4AC7E17A353BDC14A +:10278000CFACE17AD9C8EF3F1372CFF99CE205E3F1 +:1027900061229F9504987E6E7AECFE7147E9BC3EFB +:1027A000DDF1AA53CAEBE377025997145F27DBAA3E +:1027B00016419E41243EFF9CCB45AFDEE77646DDC9 +:1027C0004D2706BE7F3B83B5E6A0F3428A8FDA6DC4 +:1027D00066B79F3EAE7D42F6D8C14F7ADB8ADF777F +:1027E00058F9C48B6F5D40E7B772A73971265B86D5 +:1027F0001DF4B3A0533DF077411F5D563CFDA2058B +:10280000F220E1F9BAF83EFAACDCD96181BC4A2386 +:102810001EA7B67558987C19E8D4767406D8E5A634 +:10282000C7CE58800FFEB64722E0421ADFAFD9F676 +:10283000A213F407E009EC87A0572FFDFAD12D3839 +:10284000EBF713B09D0BCE6922D1EF5A984B12F2E1 +:10285000F793BFA7E3D7BC6375C3FA6B9EBCD609D9 +:10286000EBF84869607CFEF34DC9608F6BCCFE6469 +:102870001742F6BC66EB8F91FF96BDFEE364827A49 +:10288000D39306F24BD79906EB5BFAF015B8BE6A04 +:10289000E245FEABF9B95C0E7EE269859486F3F3FE +:1028A000D3D3989C7CB4DD8A9B828F2C847D87E374 +:1028B000CF32CBE323ABD10FF9315F2BD5C4583ED8 +:1028C0006D6374EA4E357139637AAC9EB7AADF71D5 +:1028D00033EAB18F333D2920EF140FFA78EAEBD3B6 +:1028E00053B8FEC3EFA5E07B94EFA6C27368DF691F +:1028F000F6448DD3BDC7F35AD9F8D7F1F1E9BCA39B +:10290000212EF751B27EFF2AE02569220E463A8930 +:1029100096BF22C9FD8E5B90AFBE7C93E995BAC08D +:102920009C52ACEF340753A03ED071B9847A81FA3F +:1029300017E1E47A8799CBB5BE9ECE5391B4F8DD0A +:10294000C3EEC555DF43DB69FC903EBEB1F43DCF1D +:10295000EE934F915FB1CCE09F0968D40B49697A3F +:10296000FB27DE270F2785BD87D5A70FFC88B75A21 +:1029700073E0970F821CBF6DC57B86B54F98F17BC6 +:10298000399F3CBEF7AD6B28BF7FD226E457AF67B7 +:102990008DF25BF3D415249CFC7E92584EC2CA2F54 +:1029A0007D1E567E1359FEFEFFB69E5D1641CF5E1C +:1029B0009CA6D7B3D49F88BD90163FFEF5CAA1B898 +:1029C000CF32E055E0D3A8370FA5AA885FA3DEA4D5 +:1029D0007F6F120D1E05FE045FAEF8CD2A1CA7976F +:1029E0007F057F0AFEEDE54FE37AF57834D62B704C +:1029F000E7A8B08FEEE60D747F0DE7AECFC978EE95 +:102A0000DAADF638E3212ECBF36EBA5DBC1CC7CA33 +:102A10003D4996CDA03FC4F39E289687D05DDEE366 +:102A20008CD3F8F547DB6527E4D57705C2E74B6023 +:102A3000264512DC128D54DFC8BF5B63CFF2C1BEE6 +:102A4000AC959DF72C69BCCA09FE74777BCEEC79F6 +:102A5000E0C7EF97D1A7EA8EE6F9557E8F9246F14F +:102A60005AC5964C4E10FF7DE06757B5AF9C099B49 +:102A7000C6252D7A7C54DB2FC7F3ACEA7BCC7D7C5A +:102A800041C0DF0958C0CFAA7958FF7C05E4550141 +:102A90007D0C7CE4053E0A730FA359F0513EC967D3 +:102AA000FB647E5EC5F5DA74396FF63CC85FDCC73F +:102AB000EE499C6C97C96658EFE3FCFCCA9F84FC06 +:102AC0005947F9581BE7FC14F86C5464FBFDE96F97 +:102AD0000F17DD489BD43EF3EEB88728FCF499B776 +:102AE00047FE01CACFFE35EB5DD2BFFDD43D5F2D61 +:102AF000C43CCA3D5602FBA2EE3D2F67DD08E5DF70 +:102B00005BDDA8FF37B0FDB17F8F03ED7A7726F349 +:102B1000FF9A9E3B33AE0BEDD346A4D7D369EC9E10 +:102B2000EAC9F6BFBF2F413E5D3B5D15D85DBEEFE4 +:102B3000AAFF7D14EEAFBB9F3BA3DB57FEABEBA917 +:102B4000E3F795BA1D641EDC2FEE8E63F73BEBFFB7 +:102B500030E917705F71D5AE0E4B15AD9FFAC76F98 +:102B6000C781BEE97E8AF913D4BFDD0A2EF59E0720 +:102B70000EB49829FD3E079F6F0821573D682F83AB +:102B80007B18FDF1C2F0D04DF100EBA278A9013D18 +:102B900019091F7FF9B7C5C7170B61FCDAF689045D +:102BA000E2E97D78913CECB903F32EE8FAD9F33DE4 +:102BB00067C6817F74B6F59E4A63F765FEAFAC3792 +:102BC0006EC8BFEB7A19BF3F90A6E23C8D7CDF9FB9 +:102BD000AF9FBD1ECB4F3ADC38DF41CA7BFE90FF72 +:102BE0005BFC3DFBDF76BD67A3F77E4E6F870BCEA8 +:102BF00053BA9FFB368B9CC3BAEBFE3F5D77AF9F0A +:102C00006372DB26D0F9BD430257944891F3381F15 +:102C10001AA2DF47CCE27EC4ACC46AF41F667958BE +:102C20007CA58914EC837B6A7E8F8CE70E984C43DD +:102C3000F1D079797E00F3B614FF88FB208FEBCAC0 +:102C4000556EF69D2FFDFE6A56726929F86F071BB7 +:102C5000E9BC68BB830E93AB892E61B647467F8F74 +:102C600042F4F3FE32E552CC0B995DACDF675C6356 +:102C7000D8375C354F5F7F25D99E04F97757D698B2 +:102C8000315FE80A43FBB5435CB8CEAB48C32616B8 +:102C90009F39373CBDCAF1D41F0F03E3AD1F9EF827 +:102CA0007E127379D4FE78B37AD9FED24A2BB8BF9C +:102CB000C5F3E4D60C0A9F84EF3BAD7C68815FAB23 +:102CC000877DAF53D32FE245E0FD5CF12DE864C46E +:102CD000BBC0AFC09B910E5BE14C42E38FF74191CB +:102CE00047E225DA7CCB59BD7EA31DF1F8DA0E76DA +:102CF0005FE1B5E2AA967C283F2EA1BF767AF278F2 +:102D000062A3EB3D6826BBD9FD2F8FEA2AEACB6789 +:102D1000918A5FC67305C827D4EE4B219F50BB2E06 +:102D2000C827D496219F50DB1EF209B5F5904FA815 +:102D3000AD877C426D19F209B5ED219F505B867C11 +:102D4000426D7BC827D496219F50DB1EF209B5F552 +:102D5000904FA8AD877C426D19F209B5ED219F50C7 +:102D60005B0FF984DA7AC827D496219F50DB1EF2D4 +:102D700008B5F59047A8AD87BC416D19F205B5EDD2 +:102D80002F0E3DAF2B97905775EDA7DADED095A7A4 +:102D9000BBDED5B5FF61EA315DFD25EA27BA7A4190 +:102DA000FF4B734FE99EC39985BF08F631ECAFCC5A +:102DB000FD775D3F0A29C738B3853420B441FC96BE +:102DC000C268D286D04EC51CE0F491DE11E9C0AFD6 +:102DD0005BFD9B81B90E4E3A9305FAFFB5C9735955 +:102DE000FC819F13CC867FAA948963BEC9807DAD88 +:102DF00038F7748664121C4FF930242174856248B8 +:102E00003081F261280A617C28019F2784E2102624 +:102E100086D2F17952280D61722807614A281B6118 +:102E20006A680CC2B4D068844342E3F1BDF4503EFA +:102E3000C28CD085F83C3334096156682A3E1F1A8B +:102E40002A41A8862E45981DBA04E1B0D05C6C9743 +:102E5000139A837078683E3E1F11BA1AE1C8501564 +:102E6000C251A14A84B9A19508478796233C2F7483 +:102E70002DBE3726B41A615EE8467C3E36B416E1B4 +:102E8000B85013C2F3438D08DDA1DBB05D7EE816B8 +:102E90008405A1BBF1F9F8D05D0827841EC2E7853F +:102EA000A1071016857E817062681BC2E2D06F1088 +:102EB0004E0A3D86F082D0D3F8DE85A19D08278793 +:102EC000FE80CF2F0AFD0EE10F427BF1F9C5A10E66 +:102ED000849ED0ABF8BC24B41FE194D01BF87C6A6C +:102EE000E87584D342EFE2F3E9A1B711CE081D43A0 +:102EF000F8C3D05184A5A14F105E12FA1BC21F85E2 +:102F00004EE17B9786BE403833F4777C5E16FA0A32 +:102F100061EF7E7F72A47B895ED37710D7B2C70F33 +:102F2000EA3B5F846CD19D4BDD1FE3443D397B1D43 +:102F3000CB23D95C726A1AFAB5ABAD2AFFBEA641A3 +:102F4000AF7E6307FF6113D4A4B13E200F7001E789 +:102F5000DFD78AF72681BFB4B9A0AB16E221B767E5 +:102F6000775500BC339DC5573773787B3A3BCFAC60 +:102F700018E9C272C5EA11787E451207B78ED78666 +:102F8000B0F744FBBA4C5EB6F764E1BD8041F6335E +:102F9000D87667CB8FBA2EDDBB1DE5BCDFFDBC410B +:102FA000BFFFEBF4C27FE9FDA7067AFF08A7972BC6 +:102FB000A3FC199CA7E21907F55336A4C989B49F4D +:102FC000CA16C90576B26A63FE0CA05F01F1603CC7 +:102FD000714184BCAE7739FD16379809C41517AB1B +:102FE00004E3B98B77B13C5F88839651BEA8E17C3E +:102FF000B1EA969D1670416B1A96B1FCA3008B3313 +:10300000D9E87FC0CF2B5AE660FED1CA47F5F1A7B9 +:103010005A88EBC8708EAC7F5ECFE34CC678A53182 +:10302000BEF4663A8FFBBA59DE11913370BDA7E941 +:103030007A219FC37BBDC306FA9FE201CF49C4FA40 +:1030400045BC52E081F4BFCF8079A127F78DC03C09 +:10305000B593AA9A02EDBC549C3AED90FFE09D080E +:10306000CF29FE309FA4A73106F3918E527DAE4248 +:10307000E293CB3B11BE9FD6F54E26E1DF6FD49F86 +:103080001BD85A30FFBAD24C07A6ED2A1F49C0FB05 +:103090008FB4BF71BB211EF98819F381FC644D2ADE +:1030A00029EE7FAE50BEC98CFCB178771CCB0FF3F4 +:1030B0007BDE847C7D418FA31B7366405ED1E2E69C +:1030C000EC7C0CBBED36A39F27CE4B059DFAE74564 +:1030D00097C7C2F7115734BF8EF4A4F4D2D5D7B630 +:1030E0007C81F70728BD8E47A0D7F181E8159DC1E7 +:1030F000E3816E912796177B1554AE4B4039ADD8BE +:10310000101CD1A0E147639C9E64D8F1BEA3C827E0 +:103110002E1DC2E841147732D0F5544B21D2CB4852 +:10312000A7D27F54213DC83B0EFCDEEE821CB2E8E4 +:1031300032FA7C118F5B2E68BA04FDE79C0CE6D74F +:10314000BFB61E722D09797DBD8D78A8F3FCC67AB5 +:103150001796FFB23E15CB7F5DAF227C7B7D2EC2E2 +:10316000E31696CF23E4893200E6D58DCE60723423 +:103170003A43ECABAE4B85B874E93FDE2884FC9E45 +:10318000247FD2ACE999E877EBF234E65DAECFC3A9 +:10319000E832F33CAF5B24377C476571F985BAF6BA +:1031A00024777C5F19EC07CF1B59DC1C87DF6FBBD2 +:1031B0007A6682AEFD95CDE9BA7249868AFA754E75 +:1031C000698EEEF935156374E54AFEBB09C4166DC8 +:1031D000D29E4F51CAB23C6F176BFB65C3C4941BA0 +:1031E000E8F85F1E3063BD911EC72D7EDC8FFBB7F4 +:1031F0005BDD60874EC03D325A3EF11719F5DD099F +:1032000033F1BBA8EA3E21918D0089C2E4E9F421A3 +:10321000264FA5FF9009ECC3C9AFAD787E57B545E1 +:10322000227EB843D543314FC7BDEE312BAE7BC9AB +:10323000169978F1BE92DA06E7D6D73D32CA0DE785 +:10324000960B728299706FAFE7B751EEEDB4B6AAE4 +:103250008BBD7F82EEAFE3202F492AC0F383CFCA14 +:103260005AAB4D906F201F480239FDEC2919E32914 +:10327000CB57FFA5C8057AEDA5B6B78AE938C75B75 +:10328000651CF79347ADDB6494774F0A7CD7B56F25 +:10329000DD018C33BC945ABE2283F2C1C7D5817143 +:1032A000A877D6B1F8767FFCD0F502BD815F357A7C +:1032B000ACCF6EB17332AA7CD2403F5499DD786EA8 +:1032C0007ABCC58CE77954FFE3F9FFF1D60413D338 +:1032D0003F4F21DF2D56548B76DCC52DB287FD2E56 +:1032E000846A81F992BB642F99086596AFE06F9666 +:1032F000BCECBC464FDF6B574FC4FBC5C6FC290175 +:103300003FA732E5D59C03AD788E9DCF92095D8AAB +:10331000367F5CC457482AEB5F7CC7A776D8FD7719 +:103320004CA6F0A4877D72F0F40E07EAC74F4DCF8C +:1033300017DD40E12765FE0F154A9706D97B5F062A +:10334000E4EF985AB64A782E72EC0E388FFFF809DF +:10335000B31BC590E76BADF8F5F2A103E507C10C0F +:10336000D8F97230594A85AFF212CCDF984FDA782B +:103370007C20C0CEFF6112143FAE5A768E75ACD061 +:10338000712BDCC3AD32DCDB3DC6EF2D3C96C1FCBE +:1033900021619F3FE2E52A13934FB2877D7F11F2AF +:1033A0005E866BECA9D0A7BB3386A1DEE8B5ABA4E3 +:1033B0000DF54A35FF3E70EDA356764F47252E900A +:1033C000C7E584CB1FC8337D6F85E589FB809D975A +:1033D000914EB4731F9B03D59DD9F0FEB68DF1F8C5 +:1033E000BED91D00F9E576C0461507E88F6584CD86 +:1033F0006F55AB14086AE214E2F73808D8058DBEA1 +:10340000E96F0FF4766029B7774B8921DFA7556FF5 +:1034100097CA631CB8AE15AD3CEFB9775E32F98E32 +:10342000E2ACDA1B786916CE5B7207C2CC6319E98D +:1034300009C27780573DCEEE0319E7655CC760E7A8 +:1034400059ED9E330DBE27DC3BAE61DE02DF042E5C +:103450002869E820F05EED67F8AC6E97905EFFC5D6 +:10346000FD2A71CF4ED07D19299F057A6DD93D7403 +:103470005F98DDC707BDF67A6700FDA54F48ABD35F +:103480004EF9BF76CBCE2B27C17B0FBF6E01FEAEB0 +:10349000880F8E30C5C14FD2DC7847E94561ECBB5F +:1034A000C19E7F5FF8213CCE84EF517C2CDD2163EF +:1034B0005E83A61D3FDFF7337EF613CC23AA795334 +:1034C0007637D1A735F0733E05E73E5F819FFFED6C +:1034D000791BFD989CCC81FD18A37EE9E7C718EC09 +:1034E00027DC9B007BD993C4F2C0BF543CB1F1A848 +:1034F000970D7A37A900BF3B2AF46E35B77B629CE3 +:10350000A560EF68F9C32D4F3B21FEF05FF73C9DAE +:103510008C7914605FF2FAECCBF5556CBCEB9F8DA7 +:10352000C2BCA5CFCA3AC781DF57F1F3979DDAEF46 +:103530009AAE48F59664827EE6F67095BC2DCB0572 +:10354000F6D0173EAFA2DFFE2BD23A1D6759A74334 +:10355000BFCEC5B04ECD7D902ABECE0F9AD9FA8E81 +:10356000B5B0F52EE9B74E3F9E835CFF0BABDB8F0A +:103570007E4610EDF8899D3281FB67BD7E86C1EEE7 +:103580009F26AD5B011FABD6FCF57D85F2C5F291A0 +:10359000143F940F2AEEB2A29D5FFE5B76FEF9B156 +:1035A00054928207F02F049D6BE9F315D43F00FF7E +:1035B000A26F1EBD767F39E0B1D7EE0F127F753C4A +:1035C0000E55D7FE32FE5E94E461F99075E23B3011 +:1035D000BB0DDF81514107B07BF236A0530651D9B4 +:1035E0003E511F4FFDEF115F2C5C83FCDF3352FB1C +:1035F000BDDEFAE8A019F27D7B764AE817ADBAAED7 +:10360000C4594220BF95C5C1366732FB25793C9825 +:10361000F762A5748DA6E3DD92A9B2E7AA8BE575E2 +:103620003F4CF0BB3362BEC6E7101FB781FDB39BB2 +:10363000D0FE19D7BF3B93F9CBAB6413FAD3B516C1 +:10364000E65777F3EF3EDCC7EBEFCB64FEF5C399AB +:103650002C9EDF0D7E249C4F5F64C5DFEB21641A36 +:10366000C6C915C2F84F117873299FF7CA37FACB2C +:103670003D1980A785A4D30CF49C553C47857B035A +:10368000EF27DBF03B4AF4AF1CFA99CFFB396866B1 +:10369000F704DE8731E8BAE6F378F2FBF019503A26 +:1036A000FEFB6916F463FDCF59D14FB8399AC5FBBB +:1036B0004862AC027C7E0DD7530B265B3D703E30DA +:1036C0007FF2CDE500697F7E42F15561EBD9944FE1 +:1036D000C76934313BDF184FF0BE24D9D85508F8FC +:1036E0003B9FBAC590274F57BFEBBB8481F8487FFB +:1036F0004FA116E20A1710C660C5885F5DB9D6C231 +:10370000EA0F661E99754F06217F866C26B03380BE +:1037100023E08BCA58DCE7CE863CFE78800AF2DBD9 +:10372000650AF19B186CB6E37788585EBF3807B915 +:10373000A2980463E9FA82FBF5F728AE0A9A82A3FD +:10374000E07C47097600FE4C36D5ECA2E394974A1C +:103750000580F7DA0D839BEFD1CC8F67DD33999627 +:10376000E17B5730CFB512E6F3CCA7420F7CBA50BD +:10377000212FC8058C7EC087F5F1AA1FDBAD667CC2 +:103780002EEE6F08BAE4D3EEB5F89DCFE747FB699C +:1037900076C2FB96F07193CF32C53E8FF9692BB993 +:1037A000DCAE147CF7B85E5E63B354F63D35F007CB +:1037B00029DEE6731889EFED59AC7F7B16E3FB1029 +:1037C00097C7C18EB7CA4A82B8EEE7AC484731EE18 +:1037D0006C0EA3B358FEB29887E0DF6AD280F93747 +:1037E000D53C1E63A29A04F3745B7F81F9FDC63C4D +:1037F00021EA2061DED98A1DC6E79A788EACD34BC8 +:1038000018E7942C3D4B607ED20FA2DCC0EFF32D65 +:103810006D180F30B633B74A28E7E666EA4F49FC21 +:103820007C8B96AD2D12FEBEC3FC8C9EB1F8BD7292 +:10383000EE575773BA52ED3D03EE0155833F85E7CE +:103840005FFC3B515B981FA970FF77718BDECF98AF +:10385000BF51E36732A0BB576F35E4879BB9BF7197 +:10386000C4D23316F4BDF19EFD11139BBF3F996086 +:103870007EA4B867AF707F52F0537A9659773E2690 +:10388000EE7356809E62DF3B30E453D9F1BB2B15BB +:1038900012FF5E258F2B9EA4FE267E57E67014DA5B +:1038A0002D1167EC2E71F84DB1F0394B565E107B3F +:1038B000FD2CF0332B9C1605E01953178E7383DC17 +:1038C000E9C8CEEE8BE36E2E19BF05F286E66CCD0D +:1038D0009D6DCBC4530E7E1F69EC6B90CF7BF93787 +:1038E00074FE581E37DB43F747DD2FF62CB4511515 +:1038F000BD2CEBFCD90AB5E7DDF7F66C85F2DAAC46 +:103900006256BEBD270BBE21BC76EB64566E14FD1D +:103910004D9E0D79F0DD0FB0F295B4DE0F7E2EBF17 +:1039200007547181847A762DB73F227E54617A9E46 +:10393000C129EC773ECED66E4356F9DACC24F8DEB8 +:10394000E771FC3D8116D5B316ECF5FA0C6F6516E0 +:10395000ECA3E6487E0BDC8B7F333092DBAFB0BF4D +:103960007BB13693E5096F1C5A8EEF0B7CD17E56E6 +:1039700064159E7B3FF1FDFBB9F69F99CF91A16C39 +:103980007D9A7ED6FD33FD4C51F5F311FE99F8CEAC +:10399000DCBE6CCF16E877E54D6C3F4C8EDB75F7DF +:1039A000FF4F353C3B12ECFEA9C7AD09C0872B9FEA +:1039B000FC5D5635F87FDC1FFAA4E36D0BE47DD780 +:1039C00085D87771EA43EC3B3975BB3A2C33F2204A +:1039D0008FB5C3325533BFDABEDFB9522ED3F831BB +:1039E0003FCF12F9DAEC771D573EF937FC9EE04ADB +:1039F00053DB8790E74B2E607134E33A37F1F7DE03 +:103A00008773FF30F1825F70FDFB558E673BAC73AF +:103A10006316C1F67284EF767DCAFBAB88667ABC0A +:103A2000AAC8615329BE0BDFF43641DE69F5C3D95C +:103A300005329DC7F68C298F037F448E6FF6B0F850 +:103A4000663B8B6F56C4775E478D14F9686BC59DD6 +:103A500036BACFBBF47ED27BDF0FE286A556213F7C +:103A6000D7CE9E96C1E265507E256BD59D203FFB4B +:103A7000F8EFB32D9838361AE4BC2B3BC6E4A2F21B +:103A8000FF747AE547308F05132F9A01CF4BAC8E28 +:103A900091952C3E8EFCF1747AF9F3500FED21EEE6 +:103AA000E1B50493AEA2EBF0BE2263DEB4775C8C8A +:103AB00037DC3D9520B7571F65313F6D9F89CEB3E9 +:103AC000A06F1E627CEA985DD70971AB0D69F9E0C1 +:103AD00047BB324A3ECC4AEA1BDF95E17D03CA620E +:103AE0007CBADC71F07CB0F3E8E4F4F810E846FB53 +:103AF000299F2CC397127AF5FA65D36274E5CB67D8 +:103B000026108F366E7A79BAAE3CAF2247D7FE9A2E +:103B1000256374F565D6CE090DE7E0EFD73B1EC5EA +:103B2000FCDEC3EDA7DF9A0F7EEC0ED92DD1F52C6C +:103B30007FEE91B720FFFA24FC0449018B8BB1EF93 +:103B400035F2F318C5A3E8CE63F63F6D01BF5D13F0 +:103B5000E737DCCB3B80717CE3798CC817FF67CFFC +:103B6000632C43F9BEB8F7F73C3F7D89AE8C4CDD42 +:103B7000DD81F469DACFF2989BA8DF02DF13FBE165 +:103B80002E6B00BEE1FED9EF8E5A54CDB94C7DA804 +:103B9000117F5777EAEEA3786EF3AB2CA6B7EBDA7A +:103BA000BFB0C03DA91FB6AF46799E41F5572CE581 +:103BB0009BCE0E327617C493B31D9887B3B2F91219 +:103BC0008C53C786E623AC6DBD04FB5B159A8BE571 +:103BD0003AFE7BBEFBA23B67801DDEF74C1CEE0766 +:103BE0005F9383231F827EAC0ED40F65E90B368072 +:103BF0009FB02FDA9F772D1DAFEC3F7F8879E87556 +:103C0000BB248C9B96C9649F04F9F7A128ECAF4CA8 +:103C1000FEF384D5F4F9A553995D2D031F87D6CB08 +:103C2000458E5BF17BD2117E27AD6028D32BE62E2B +:103C300036EFE9A139D89FA82F1E3A4CF7DD18734B +:103C4000D20E65B1BD6F3DE62E09E18F426310D6FD +:103C5000EF9AA340FEF92BB9BF48043CD1F6F87D9A +:103C6000B0FEFA78622C09A3B704B4723D3C1FF48D +:103C7000309CD3677B660D4D82DF23EC526CA047EE +:103C8000ED3617F82FB38AF3D56ACDBAE4E7AFC69D +:103C90007B10D6C41E33F803F329D4EAED4511ECAA +:103CA000CCE5434DDC7F6EC4F50A7B448EFF18CF14 +:103CB000B517F2F88090A792A1261D5E3A25261727 +:103CC000FEDFB27381D26C6F35CCB7B384CC7B0A84 +:103CD000F5686716DC47FFBEE64FE96B03FA3B95D4 +:103CE0002E02718C95BDF367F27CB6F95FCDE7FFCC +:103CF0009A4C7CC017AF5D7C71A787CEABE3C6F151 +:103D0000E3C12E88F1D60D65F987C4D5F30DE61B06 +:103D1000EE895121AE5F06671E13FAFC79C847840D +:103D2000F861FD1EEB76F8406ABD93EEEFED90175B +:103D3000181504BEEDF8639402F663EC70EFBAA1B7 +:103D4000982F386A1A7CC7C7D36E5508FA419E9FD0 +:103D5000C2F348F33D9BFE12F268E4336F33933FA6 +:103D60002F97C34ACEB78BB91C562AEE58388F59B5 +:103D70007440C67B918BD7496377417C4075E03DA9 +:103D80007D218742DECCC097E3813F195FD686E272 +:103D9000B87C67F37E991C94C92CDFAE6C4C1CEE8A +:103DA0009FEB4209D84EC8AB90D3CDD9DEC761DDB9 +:103DB000654D54BEE938DE0D6913405EFAF8C4E281 +:103DC000027EA27C925AADE183A68EAF14E013F37B +:103DD0006409F9C44AE1540D1F95F7FA27AE19C9D1 +:103DE000741EB33666E3F79445FDCEA1C24F191C8D +:103DF000BF6FE5FCB5D81E1C017EADB921CA0DDF31 +:103E0000913F99A8A21E5B738B843F4EB8C65C3E5F +:103E100015FC8B350F4818DF03BF03F44FD1A10603 +:103E20008BF61CE4EAD0383CAF9E1B1A8E707B8662 +:103E3000F78F8087CAD0951C8FE3C29EF77DD9701B +:103E400033C6D5BE0C58DDEC3B63FAF85DA1C78DD7 +:103E5000E77FE60366B24D85B89B57C6F3BD4CE2DB +:103E6000BA5B62F13B88E789F89B38A71371382B5E +:103E70007C0F5763474F2BAD59B00FE9178F2B615C +:103E800076FFD31D66766FABE3CF45265AFF71B63A +:103E900007E3722FA57ADF86F5ACB82CF0A49996CB +:103EA00057DEFEB413E2E5029F6D4A7004EC97DA28 +:103EB000281E213ED8D622970698BF133347935F1A +:103EC0001189AF578472103FC2DE08FDFDECFA5431 +:103ED000DC940A3D7E363B24F87B159783552007FA +:103EE000446B6FE694C3EF9A915C09EFB9F6D91B66 +:103EF000260F424F537E47B929CBC9C4B8BAD0DB8D +:103F0000467BB4576EBBFB02B0BBAA3746A5EB9B02 +:103F1000F29BBF3FFD0EADAA7DEAB16940A7923189 +:103F20001281734CA39EFC1F2B97089D00800000FC +:103F3000000000001F8B080000000000000BB55BB4 +:103F40000B7854D5B55E67CE9C9949322F9210C23A +:103F500023F1CCE441A8018747243CFC3C10082015 +:103F60000627F8155153994404C4BC40B9A642BF72 +:103F700039210902A53654ABD4A29D50B0D4AA8DE4 +:103F80008035AD3C06411A8AD569B5B7F416E828E4 +:103F90005CDE60C05AF116E5AEB5F7399939930485 +:103FA000B5FD3A7E7E9B75F6DA7BAFBDD6BFD65E99 +:103FB0006B9F9359C523E5058500D7E8772B80F8DB +:103FC000E667923C1CC0BAA21C143BC0BDD896D870 +:103FD00063FD1280D28E3440D43CDB117BEE964DD3 +:103FE00000FDE979234011C02C9DEFC432800C8084 +:103FF000FBDCC07F0DC83410E08B1B38FF742BCC6A +:10400000F3E3FA608E64C7CF37DD33D92B63FF50FB +:1040100059E0F3AD889A6DE9C867B7B9B77890FEF3 +:1040200017E52E13C126A40238CD51482DA4F94D11 +:104030006C7E0095C9F36572F7D7F6F9AE080DED01 +:1040400038FEDD5B6F8D2828D7DEE5A3478B726CC9 +:10405000BDF1B285F195A5E1D831005DBBACA14DB4 +:104060002837E07C02F27FB46B58682D6EED18742F +:104070005D05A4D59D2932EDAB6E770AE3AF4B7693 +:104080008504ECAF7376E5FB519E923D4961188142 +:10409000EBEC493203AEFB59CEFDE3E5227A3E74E8 +:1040A0008AE044A1775ACD807C2BB39509A4B7BE92 +:1040B000E4D7E54B6CF5FD97960BAACB0530B3C45E +:1040C000A19AB05D7C25076034C043AB67B0F6F5BC +:1040D00060262A1960EA957200DC5BCD953BD9F326 +:1040E000DA2B298C9EF9DD4829ED075E17600BCA93 +:1040F0005F36F85B2B01E5EB4C86E13B705F9DDEA4 +:104100002C5F137657B7CE60FC65BF9C369DF65585 +:10411000BB0399695C8110CA233D9DB09B48FE8713 +:104120006D5CFC8FEBFF3C46C6F11F8F718C046405 +:10413000DD27B63F395E60F6EC247B4EFEC53FB707 +:10414000FF0FF249574450501EEB1581B57F940381 +:10415000D5A427E40340BEEA6D03C704EC5F054F16 +:10416000BF9664C4A3547D49223C59B12D89EB9F6D +:10417000A7E124518F4BBAF1F4D5FC609EC6FF65D0 +:10418000786AFECFE3A9B90F3CB5FC3B78BA8E1D27 +:104190007DE089E16CE6218E0FC871F8B600C30B93 +:1041A00093BBD392156A42BE7BC9AE84AF6B504FAE +:1041B000FA9C47F64D8BE1F5979EC0CF494EDDCE78 +:1041C0009DC96AE192C2AF62E7BB81E2C6BDE9F573 +:1041D000A0E0F379D8C6C70D2BD9AFB0E7FE5EF9E2 +:1041E0009AF16EE357B4F31EB233E1C78D761CC368 +:1041F000EC27935D13ED4E7625BBD7EDB66EBA9ED8 +:104200005D87E7067E477A49B42BB8934D7073BC3F +:104210005DAC77126E3E0E9B81FCAB2FBB4A1BB888 +:10422000DE75BA256C9E1E62E701A4950F6778398A +:10423000F4EFE0A5ACA4FDEFB67E0067E4257E3385 +:10424000F2CF29C6AE41D4BFB45531537CC17F8E65 +:1042500067332A6063FAD4E8872353508E994F76E8 +:10426000F7ABD43F75A24B1B0F0A6EAB9BFFB45C40 +:104270001F59C7E46EE5FA0E44CDFEE171F418A4AF +:104280001D71747102BD91F3D339E266F384D87362 +:10429000C29F308A687D3ECD0FA0ABB41FDA6FD6C7 +:1042A0000EC1BD16ED7DCFC48F2C649FB292E88104 +:1042B000C1B8DFABF2637E7B123EA73888F2DA3DED +:1042C0002B5B55B3361EF558ADA9D1DA2E2822DA6C +:1042D000A9BA5808793D3DF568F7E8B8D4D7C5A321 +:1042E000D5381E2C63BEDE78C2091BEF65E3C3D64A +:1042F000AFB1FE5D134109F512270779B43879157E +:10430000697D7ED4DD9DB8BF502FFEE6D5E68D9841 +:104310004C3580FAFA86E7E9565B16DA17383E0A1A +:104320003D3FF4AB1C87A024ECF77AF2BA3DC6F30C +:104330009F7EB2717CF87AFACAE8315EC3C7222345 +:104340005E5C66FFFE8F510E57BAE056D1FEB5FE99 +:10435000A475E022FBEBF80EF99521B8BF24E8C65E +:10436000AB11DF6DFE29A8975AD0FB7FDA4AF1CA5C +:104370006FEAE6E778DF29748F2F40FCB8808F2F33 +:10438000F56C6A550B993D583FA3CDD7C17B7B0295 +:104390003D31C13F347C33FFA4B88DFAC9EB256EA3 +:1043A000DCAFD9ED82007329EE4526F37C2FE2E5E0 +:1043B0006D9387E7770F697A7C586B23C9717A18F8 +:1043C00012B333FEC25060D837D3D3DDE9DABED59D +:1043D000BDFEDB715F9154182E204EBED3B6ABB537 +:1043E000F996D8F860DB5E8693EEF9D43D113ADF9A +:1043F000EFD6F4D4D4168E683812C8EF6A1820109D +:10440000073B0455C47DD6100E7AD967594FBF516A +:1044100013C62BD275C6DFD973BC92301EA4F4AF7D +:10442000335EB3D3ED09769C9E60C7290974854E2F +:10443000870CF14C8F73551DEB5B32508E87B60A9B +:10444000744C50BCB608230136780EF9EDE308AF82 +:10445000B2341863FE46CFEF23B66100E514CF18DF +:104460007EDF695572514EF27746BFEB576E22FCE4 +:10447000D4B76422FF264FA4D586ACF734AF972873 +:10448000A779C1F3C75633CE7BF7985F1EA0F9CC4E +:10449000C2FB91DB3DD7C16B6BC23E3626D06A02B0 +:1044A000FF535F12DF9B13C6AF48E85F97406F482A +:1044B000A0571BC757CE17989F54A2FD48715FE6BF +:1044C000373B3DDDF942F77926D8599E64C0FDCCD3 +:1044D000264E1FF07CE85F6D8FA3DB8EFBC9DF7576 +:1044E0001C4BC07FF7A6834AE787D4473CDBD11734 +:1044F0008E0A12CF3BDEFF37FAE740CA3BC1702E6F +:10450000EF138DF45E51F7B74B91470AE9A14E774F +:10451000F90348CF7CC6B82FAC0BB5FE8BFE29E85B +:10452000FF33BFAFF75FF453DCD3F7A9F3977E7E79 +:104530004DA4F58EB45DF06FC6FE8AC9E1BC7A94D5 +:10454000B32295B778CE88748ED5D9B83F95EE1240 +:10455000FD74CE542487F39616C6ED13DAF3699FE3 +:104560007B978BCC3E6A13AF47AAC067012C85F6B8 +:10457000BA5C0D2F20FFBEE562039D6BC71AD232D5 +:10458000A89E18EEE579DB3ED70D190F20BD3765E3 +:104590009E4546BEBD8F4F65ED9BA2B2AA0B71FC36 +:1045A0007F9ECFFDF661D4EF62FAF947DB157F23DA +:1045B000FAC5671E99E93390EACEE8A07C75AD0490 +:1045C0005B6492C7F73CC3CDF7AC23D7A21C958D93 +:1045D000376650FE56F5C3F2D281C857D522F9048A +:1045E000C6072348EEC0DAA916EA9FDFACB5EA3465 +:1045F000D6EEF962FBA111C8DFB546F46D42E6DDE7 +:1046000057BCCE2A94EB78128FC31F9ECF75929C15 +:10461000EBBD01C98B72543A1DC9021D1E6ED939FA +:104620001BE77D2247B1788B62FC7BBE10E751BE51 +:10463000F9C6F9AA0CB29FDBCBF1BAFB4A55465535 +:10464000DC79BFE08299E9798F457E84F2CB3DC960 +:1046500059822A303DA795A3BFCCD7F26BC44BC378 +:10466000F65ECEFDCF3D22D3CB096B031C4710EF86 +:10467000FD6EFF8924A73EAEE8FD409383F03C44E5 +:104680001E159F47F7CB9E3C84F611C359DA1F08CD +:10469000372C8F467AA8D7BD5E455CC13ECCFF491A +:1046A0008E74A594CE0158810C18C720B33D3FFEEF +:1046B0003E2296A7AED4E201E73BAA3A58DD7AF44F +:1046C000A5A410D53347D5BF3AC01ECFCFFD64A1F6 +:1046D000D3A1D2617CCAE130935E8F998327BF8DCD +:1046E000E3163C27B138BAE0B9FE2BBA281EA03D2C +:1046F000F3A0E7BAAA5762F3F4E927E02937F8896B +:104700002A972BF6BEFD6492572EBF9E9F2CD4F2A3 +:10471000F6D2E7243FE17C6191C30C18AF273FF745 +:10472000D616C2E3C22549A3AC28F8C2E7ACCCBE7A +:1047300051874375637FC0E930F7A3B8EEE5712474 +:10474000DA98C4EA1431C3C2E29EB8AA4826FD949E +:104750008860B6E1B9223A7DB29FD3CD6EACDB5A08 +:104760001CC532D9F73B5EEE0FDDFDAEB9B7095877 +:10477000D75CC67DA4E1B8330D4F3E3D16E53B0B3B +:10478000A1396351EF97C9D0B8CEE51D6248A57332 +:10479000C2AC98CB30EE2D02EEEF3507B75B26E1C9 +:1047A0003F17D52FBC9DEAA30743D28751ADF6B979 +:1047B00086FF7F026F5B28BF7D68ABF1397A8C85FD +:1047C000FCAAA6DDF8BC0ED65D1247506BFE305A2F +:1047D000A03DC7751B8EFC65F8FE38BE5AAF23FDA1 +:1047E0002496E0300A46A166719D42D75D04BB065F +:1047F00091C92BAE4C0A911EC56C7E3E4C03219490 +:10480000448070E3BE71DD4F838787EF4740888F18 +:104810008D667A3911443C0D457D386D8C5F7C4C3A +:104820000C5971DD923450FA913E9F2E0770307D05 +:10483000AA6EA4A7A5D79B293E9DD3E24BA500FE57 +:1048400076E6F7BE6CAA8F173C97C4ECB7F0F90771 +:10485000FFFB4763C85E65E9F17EB446C31DCE0722 +:10486000B6D4D83CA71ABF934DF294FC04EB4AAAE5 +:1048700037C5C0D377B37899E26371CB1DFDDE589D +:10488000C24963CAC8B540381998ED2D8C8D5FB800 +:1048900072793E1F8FF5AA93E25512DB4FF50E2B6E +:1048A000C349E51A5161E76396859D8F1F3627310D +:1048B000BA7A4831F3B34A1304681F980B66B2B84A +:1048C000CE550ED57650B6DB29CEAF8B884E661FFF +:1048D00055B39B85ECB3D99BC6FC771EE918CFADC9 +:1048E000FD84B322361FBF7FDA2D84B6B0F8542F73 +:1048F00093FF57980416E712FDF1352FCF5B2BB3CA +:104900007DF7D1B89A27ACBE951E2E83A8CB8378AD +:10491000AA314516FC98E6FD9595DD6BD4E13E92F3 +:104920009CACBE50B6A1FC7566305BE85E4AE6F111 +:104930004C97A74E2E9F4638C5FEC366ECAF71F06C +:10494000785CD38FDFF780C316DA12BF1EC99CC311 +:10495000C7C94EF2B3710C2FE4F726ECFF08787F3D +:1049600089B3588EE2F34E13ACA67B129267D888B7 +:10497000B875911E3882F0B8C4EC75901DD2E6CCA3 +:10498000A5F55E16595C42677AA298F2BF97C5D129 +:1049900054C756AED957BA81E85747BA4984CA575F +:1049A000DE63E7D3431ACEA294F7D37985F4ABD86C +:1049B0001ED5E24240E4F73847498FFD637AD5FBC4 +:1049C0006BD648CC1E352D1C0F358D7F66F3D6383F +:1049D0002219648F9AD7A49B09D72735B9AB1AB38C +:1049E000261E467C54492EB7808FAAD5320BD1D5CE +:1049F000AD02A3F5F56AD6FC29C354C8E7A3D6AA2D +:104A0000E128366FFF6C3ACFCEBD94965D1967F7FB +:104A100073CDAF3B653BF94D38CF4DF7304B927CB2 +:104A20009B989F727B9C6BCEDB44F734F3DD118740 +:104A300080FDF31FC949A573EE983B6CA1FE63EDA1 +:104A40001E13D18ADB3D9168C57C13A3CF61086F2B +:104A50002FD4C08B76AA15386EAA5FDA67F1E27A96 +:104A600029395C3F175E7E2F9FEE0B6AB223F974E3 +:104A7000FE22AEF207935D5E14589E50FB92A8246E +:104A80008D88E1AA967085FEBF58C355ED8ED71F5D +:104A9000253FAD253C8DEA894BAC2BF7B3E7DBDA3C +:104AA0004A818FDF4FB8D3CF7BA49B25BA57B36819 +:104AB00034AE43B43D87EB1FFBA7F07EB5909D233A +:104AC00010B5503E5C27F23C01FD2993F288BA0EE6 +:104AD00049ED8E97B42EF517C6FAFBC2CDF01C93A4 +:104AE00066672B3B8F86E770FF8BAE79CD49B8B8F0 +:104AF000F0F2BE03E3A9BEDA26B829DEF7F0434D93 +:104B00006F75A42727DB27CB8BEA482FCE989EBA58 +:104B1000FD4DC3451D703DE87AA9336B7AD2FBB5D4 +:104B2000F123343D5483A6D71D43B9BF6BFEAD9F1F +:104B300023FAFE02A97CBC8EAF79DAFE266A6D35B7 +:104B4000E2C657C8F0A5586ED6EA7EECBAF06A1BEA +:104B5000BB37D2EDA9CBFDA8B63EC669A55F6ACC2E +:104B6000CE51132CEAED9E7AB6862BC9CEE3CA0746 +:104B70008D83EF6B40FD2D7E49F431E551CD15B7A6 +:104B8000AED51475B0BCF431D14DFB2AF945F96DA1 +:104B9000B46F1D77D256C1DC3186EA8C7E4CFFBAE9 +:104BA0007C2503FCB7F5E3B80B933CBA9C1F086166 +:104BB000662FF555C1CDF3DCA885EE0F753F4D94FA +:104BC000779E666FD1298C176E22797C32F937E097 +:104BD00039C8E4B11F5ECED6538F2EF78C88AD73E3 +:104BE0004C759889EF18F038A0E3F203ED3EE283AC +:104BF00096D7591EACAFB34CD34BDC3A8186F49EAA +:104C0000EBE8FC351ABFEE179DA91CFF25CD7F668A +:104C10007C7A9CA51FDDC3E9FAD4F516E79706FD5B +:104C2000E8FEA5FB936ED77FD5AF60457F96AF3E7C +:104C3000AEED9BF94846EC5C207CD27967B5202E1E +:104C4000ED867393E535D3865CB2047A79AEEB29B1 +:104C5000F179AC9E726793FEA7D9334D94074073E8 +:104C6000E6FEDCB8BCEC38DD77513CED0FFC7D0690 +:104C70008694F8F35CCFD7F4F31A7FEBBA7189E32B +:104C8000EBD29533D4BF68CC927CCA232EE578D979 +:104C9000BA67A1DD3209E7AB3E1D2975CAB17AE5D5 +:104CA00096BF874517DD07EEF018EA85EAF3FB9912 +:104CB0007FD7406415D5B7956BDE2B1B4B76FF393C +:104CC000E6E3C837BFD5C3CEBD339BEF1F4DA56C00 +:104CD000654B1EA31FDCF200A7D7F07CAEB2A5E89F +:104CE00005BA8F3F9EA49412BEBBD60B6EAAB72600 +:104CF0006C295A710FF64F70DCD08FE43EBAF97808 +:104D0000D978AA1B1A44E62FCAE627E750BFD2215A +:104D1000FA68ABF3C1BDE21EC2B7D9C5FCED987607 +:104D20004E34491C676F6B71627F0E3F2FF76B38F3 +:104D30002C696ACA37D1BA6D783EE1FE2B2C727BA2 +:104D400098EABE5D037C9B485F58A666228E4E0B98 +:104D50003CFF5E64011BE1EAA0145946F21F5CE6C9 +:104D600018D9480288576FAEE2753A8B2F5837B181 +:104D700075757DE9EB1FD2D6D5E7D1C775523E4593 +:104D8000E78726EF99E69FCFA13CE1CCD6BC5488BB +:104D9000D3FB19DA17EAFB418C8BDB7AA9FF0EE70C +:104DA000E8F7AB21D62ED2EE0D0F4AAD43E8FD2D2C +:104DB000E6F127E2F3F2536D4936C223E6F1C6E786 +:104DC000123F4F308F373C47BF3961CCF7B5FA4EB1 +:104DD000AC70057A89437A9B98E79FCBB1A79FBCBB +:104DE000117AE4F9BADF258ED7F3FAEE7B9623F633 +:104DF00084F731635D709DF5CF07D13058FBFD948A +:104E00007C17C74F49F97C7B84EAC956ABDB8AFA29 +:104E10003D417E45EF015F13799E68035F18717114 +:104E2000E24FA37DE4870B8E70BF5BD02E84E81524 +:104E3000FBFEF58F8BC4FFC0460106087175D65383 +:104E4000EBE790DB5DF605560D44FECB5B059FCA94 +:104E50002454EC09F5D5818172DFF5D5BF5B57E9A4 +:104E6000F74C897A1F94ABD5573EF019F5CEEBF38A +:104E70003D089FE2513DF57E3E186075D4C5E022A5 +:104E8000D68E6B6F2B198CF27F247CF0C404F21F3A +:104E9000878BDD939C0FD6B39780173B465F9D852C +:104EA000FA79C3EE7253DCB8186C60CFBBF1A2E1A3 +:104EB000F3961D7BC5C1C0F8774E40FEDD7617BD69 +:104EC000D6E8E57D1BB72F40327F3FAAD5DB0F2FF9 +:104ED000193B809EEBFB3DFB6D6E675DFEB35BEFA8 +:104EE00077527EBAF7C7693BC7917D535C6E82D11A +:104EF000C20D220446633EBC81C7A1D336D70B74D2 +:104F00005F7A7AE39D19540F3E2075597C38AF6F54 +:104F100057B993EE41FED71C75BAA945FE30C96159 +:104F20000E8914FFC64F07F61E707CD80CB287BDE1 +:104F3000A267381977DE1C0A237D8EDE0FD2B97D79 +:104F40003599BFA7D7DEFB3DF06B7E9FD67D7FA254 +:104F5000DD234CD0F6FB5FB9A91CE7DAF39262FEC1 +:104F6000FCD4C6EDB368BE339B2537C97B71B3C48F +:104F7000E65F8C75BC0971781AF146F16BF1FBA202 +:104F80008F207D662BAF9317236EE9BEB86689A488 +:104F9000585C3DF158A2F3ED14587DADE372B112A7 +:104FA0002A657AD7F069C3FFAEE191D10FDA579144 +:104FB0003E1271FAAFD6FD35B9BDD7FD8938D0F5AF +:104FC000A5E321864F60B8D4ED9EDA3E72D26036FA +:104FD00040657A54274301E5054D162830130E4CE1 +:104FE000C93EF2F3069B7304DD337D9AC4DB474D63 +:104FF000EEB7A85EFED4244B02B6D15C0F1BFFA80F +:10500000E89B4AB4941E65F70362894931D179D788 +:105010006465F12231DEACC9E571382B8FC79B2D59 +:10502000B96E9E3F423DCB1FF416379845F949793A +:105030004AEA2732B23CBD79C66C33EEAF7C42EA15 +:10504000B21CCC2C9FDF7CC76C7AAF5B3E3AF53547 +:105050002FD2A1DC59BCFFA6D42209E9C646FFEC39 +:1050600029D8BF2B57792AB728B68E3E2F3E7F8688 +:105070009EFF7640E0D9DCFE749ED95753BCFF48B2 +:10508000E8AA358931FE3F0870EC0D21464725C856 +:10509000A67C7A4B2EB07DF4D59EC9557E9ADBCB8B +:1050A000F32A8016D26395FADBC394AFE1CF6F4346 +:1050B000BCDDA1E1ADCA660F132E60B574BE1B172F +:1050C0005E8A4B2E33F9F72CCDDC7798C37B69FCD5 +:1050D0003068769FB4B15470E3B5B4BEE33C3A2671 +:1050E0009CD4E7C3FD7D24E17ED1AE8282B6469793 +:1050F0001250C91518DF849DBFFD8CE66D52219AB0 +:10510000C4EC50E1A6F3488080E91AB63529880737 +:10511000D4D3D2D72EEC27F83FA8E75399FCFB8CC9 +:10512000651A1EEF8828CFB4A150A782909E8BB637 +:10513000BE006F5E34E3BA674C8183A4976AD3DB09 +:10514000D94B65F2DB2627E52F175E117DB7E3B853 +:105150006A2D6F87AB62F8567CDEE919B6696D1C63 +:105160008EFE98CBF394F39E70F6728A1F1E5E77C4 +:10517000C2D57DD9CB917FBA7746119D4B4F81F235 +:105180007E6EDCFBC559E6DEBFBFF8FD209E77C012 +:10519000667EBE5ACDA03A52590B4ED4C70C94A588 +:1051A0001869096991BD8F0F313B129F93F214F971 +:1051B000FE4CFEBE06FCE48FBA1D75FBF4B01B8AE4 +:1051C0004CF9B9C90612F9CB30D8E826FFD6ED372D +:1051D00055B4B378B3F4357E1FB7548836A711FDA4 +:1051E000329E97A42FCD2F7B9E9B5B2C648A451B00 +:1051F000EF67F1498F4B32FE47F8F94FDD4B0A79E3 +:105200000E9EAF8C849184AB2FCB77F4B884F6B12B +:10521000E57D1DFB908A70BF0BB5B5A78A15B299C5 +:10522000F4D2DFE6A3B8BCF4B91C76DEC1BA1FB075 +:10523000FB0F9D0F36A6317CAEF288CC8E651D83A8 +:1052400041C6470F760820E339777B471AA39D575D +:105250000632BAEC67032653FEDFFDDEF267431920 +:105260007DE685436302FC7EC54672F84197A3B094 +:105270009DF2A1CB769403EDE0B7AF66F7857EE8AB +:10528000AE63846B02D18812F2274552B95D6C8DF2 +:10529000CCAFB57D2D75733B2E3DC8CFDDA593F802 +:1052A000FB3DB33ACC4578903A450821FDCD836269 +:1052B0005118599BB4B86CCD34811C678F243919AF +:1052C000E4B8FA0D54254275D25C0D272905A9864C +:1052D000FEC785804472CDB52F60B871F80619E617 +:1052E0008B649776327D04787EABE309C4F36692D3 +:1052F000F3938902A4212EBE3917FBE3E695265EBF +:105300009A22B0D69817A35E4E5C0F4F33F3B4F3D6 +:105310006E180C63784AD00FFA07CB3F2FE3394E53 +:1053200069136617CF4C447A4EA7042199E59BCCAC +:105330007F2E2B29ECFEBE45D3938E3BFF50702869 +:1053400038AFABD8A8B77E8A516F69D38D7AEAEFB0 +:1053500037EA65C05CAFA17F60E01B86FEC18B466B +:1053600019E8ACFAF106FE1B1A261B688F7A9B819E +:105370003F67F56C039DD77A8F817FE8862A43FFCC +:10538000B0D06243FF8D5B971AE8E1ED8F19F86F9B +:10539000EA5869E81F195E6BE81FDDF903035D1425 +:1053A00079D6C03FF6F02643FFB8E88B86FE09A702 +:1053B000B719E85BBA7E63E0BFF5CA9B067A121C98 +:1053C00032F097D8DE33D053DD7F35F04FCB3C6ED3 +:1053D000E89F219F33F4CF2CF8D84097F9FE69E07D +:1053E000DF3828F02CC59FB9A6754755A0F82C7F4B +:1053F0007F22E2F9AE74B32F4C4C5FB36EDBA4C7CF +:10540000410DB79F80FD3E93F7CBE3E0E35A5E305A +:1054100055BC1DE8BEF772BBC070DDD7F9ECC27C8D +:10542000D71CB78F7E8A0D0BF0189D36DD6DA0FB63 +:10543000FB330DFC03E6CA86FE81810243FFE04593 +:105440003E039D555F6CE0BFA14131D01E75BA810E +:105450003F67B5DF40E7B5CE35F00FDD1030F40F14 +:105460000B2D32F4DFB8B5DE400F6F6F30F0DFD4B4 +:10547000A11AFA4786571BFA4777B61AE8A2C80658 +:1054800003FFD8C32143FFB8E85643FF84D3ED069A +:10549000FA96AE0E03FFAD57C2067A121C34F0978F +:1054A000D8FE60A0A7BAFF62E09F96F981A17F862F +:1054B0007CC6D05F7D0EE147F9F31B027BFF35B35D +:1054C000E092A15F4AC73C9DEEA721D9270A3DF390 +:1054D000743D7F2BF37D6658E751533DFB2EEE5311 +:1054E00013CFEB6CF9FC7E0BF3779B8DC5593CA178 +:1054F00086B3AB9646CA4F5DAAC07047A94605BBA6 +:105500002F4C67E72A3B1A65FA0E0DF31B24524D08 +:105510001E0FD50F29B13C74C8B5D15F3D0FCDC862 +:10552000078EFFFC404A7E11D563AF96527DF22074 +:10553000A8AB480E3C5F5DF49EE99D24E3BD91DE7F +:10554000CEB0A1FEE2D63B98D43A64D475FC768600 +:10555000ED3CE3EF9E57BB5712707F4BE3E67F02B3 +:10556000EB26339690AD41F42FF4D31F04DD8C7EEF +:105570002A98C9E8A783326B37040B58FB6CD0C755 +:10558000FA37068B19FD7C50617428389DB59B82D3 +:105590007EF67C73702EA35F080658BB35B888B5BD +:1055A0002F06EB59FF4BC10646BF125459DB1E5C58 +:1055B000CD9E6F0BB6327A477003A37F150CB1B640 +:1055C00023B895B5BF09B6B3FE9DC10E46EF0E8652 +:1055D000191D0E7632FACD6084D1FB8387197D20A8 +:1055E00018656D67F0346B7F17EC62FD6F07AF30A5 +:1055F000FABC76DF5F926F7CAFA6D30053181EF41F +:10560000BC7616D52D048E62E9A2A16E49A81F12A0 +:10561000ED71565B479A8CC736E53983F23735C54D +:10562000E5FB7768EB3D9E0C6A12C6BF462AE61181 +:105630008A8DA9106A62EF5779DEBD50C325A4F3A5 +:105640007C7B8126D742CD1F8A089F050C9F6F7FE8 +:105650009D3A49AF93834302F3F2B15D9C6552D901 +:105660003D813D944F79FFA621812AC2EDE5FA07DD +:105670000EB0F5DCBE7C5AA4CC1AEE7F17DDFF1C01 +:1056800014D97D695FEBD5697FBFD067FFEE3343E7 +:10569000E81C9AFE85C8EED3DF911C73E97EE49185 +:1056A0007CFE1EE3917C93A11D96E57F98E43C95DA +:1056B00057FFC2C3C852B124CF4579EB1D545AA33A +:1056C000DF97832CB1EF6341798B3E99FC262676D8 +:1056D00044DF052A6BB70F0EACA0F177630141746C +:1056E00060BC35BBB7FD24CAB34AB3D3AA7C93A12F +:1056F0002DCDF2B7D07C27F214833CCBB364EDEF11 +:1057000064BA9E27B9FEB1EBD2492127A66FFD5E90 +:1057100062D524EDFBA92582FE9E9AE78336D0F35D +:1057200041D65FB18CDFCF7C0BEB327A5F79448B53 +:105730008797EB25162F2B84641FE5D397EB970DE6 +:10574000A5FD24C6CD0A1C67C27115C0BF87A83845 +:1057500092C2F085F301BD77ABC0CC9DEABFDA2CD5 +:10576000FDDE236AEFCFE551E83DECBC9DD636AABD +:105770005311279B591C1B27AA16AC93DF3185F2C6 +:105780000591E1C322A0BC0BD3111FBDE4053A0E65 +:105790006AB5BF8FD19F23BE5EA1F92EFE7A6C0140 +:1057A0007B6FB27B9C4CFA6B32A13DE8BEE6772260 +:1057B000FF4E82AED8E93B0E57611BFBCE9F92088D +:1057C000B2D738077B1FB2578486577B899FEF6A11 +:1057D000387A27539A1E62F31ADFF3756A76ECD48F +:1057E000EC5BF6E6C1AC4771DEDA4E89D53B30267C +:1057F0005AE8EFE5FBA6BA86430373E3F651D7F107 +:1058000001FF2E0AA285F1DF439DD2D6D7F1245A9B +:105810001C81367BBC7CDDB87E47C3F549CAEB678B +:105820005965D75D38348AAA09631BF8899B7D576F +:10583000A77F5F371FFCAC5D8870201CFBD5F5ACE3 +:10584000FE5D0CEDEC796DF1FDD944D741D7944C58 +:10585000AA5F5637BE9589D2DDD9BA7E2ADD3FCF01 +:105860000E55BE456DF966E124D5DDE8177FA3F539 +:10587000A3427D0B95A4F7BC34A985EE796789DC3A +:105880000E7088DB0171A488A93DF7877E7052F302 +:105890000326BFEE07152B397EF4BFC7E8F68BE26F +:1058A00087FE3698DE7D98BBD8772175BBADA9847D +:1058B000AFC554798AF179A17E3EF3BCE021CC0BCF +:1058C00088EFACC4ED7FF66812FBBB97B302E263CE +:1058D000544FDCEB79E6A7267EEFF6A8885B14A987 +:1058E0005E7E92E969912D3482F484E7330C255C65 +:1058F0001F6F5F3592EEFB2687B2295F955EB4FA83 +:105900009A3C86380FD75262F7784F48FC5E2D518B +:10591000DE1E794BF181CF289FB05A40A5F749E8A8 +:10592000FFDCEF8F71F93F3505326F1679BEC2EAA1 +:10593000E8217E56FF4386CDB756E8B97EB3B66EF2 +:10594000E7E7BC9E56B3807D8F932887E0E6EB2681 +:10595000CA634DE672E8E74E4F79B81D74790A863E +:105960007AF8FD7DB6C2F6DD68EAC7E2D747626025 +:10597000E8503A2FB5FB31BD8EEDF49C62711DAE3F +:10598000360DE1DFF786FB3A4FCF77D7CFDED879F8 +:10599000A7DF33C1C4DEEF05FD36B744769B0D3E6D +:1059A00016F787C1115D3FEC9EE9FF019ECDEE1811 +:1059B000B0390000000000000000000000000000FE +:1059C0001F8B080000000000000B7BC4CEC0F0A3BA +:1059D0001E822538106C62711D0B03C30756D2F569 +:1059E000C17025507F0910E703711610A7027102DC +:1059F000104703711810BF069AFD0C881F02F11D95 +:105A000020BE0EC49780F82C109F40B277191B035C +:105A1000C35A36D2EDFF83E4E78940763910CF24AC +:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2 +:105A30005479051E047BB92065766D03EA0700E9F9 +:105A4000CD424A800300000000000000000000007A +:105A50001F8B080000000000000BD57D0B7854D58B +:105A6000B5F03E8F79253393C9839040C493970452 +:105A700009382421F2AA1E0842A4D406F42A5AAEF8 +:105A80000EC823869044B02DB7729B21092F411B6D +:105A9000152D5AB483458B0A36F268D106EEF028EC +:105AA000C65BB4D1A282D536D45B450B4944116F95 +:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370 +:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5 +:105AD000D9C6E42B19FB027FA09CA330C60644CA9A +:105AE00051775EBB687B09FCFE99DDFFB8166967DC +:105AF00094173389B1D1F09E653056CAD8954EF8C7 +:105B000015DA95BD70EA0F97A531B69F29CC018FA4 +:105B1000C26A59EAB7A09FFD9F333FBE975F706787 +:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2 +:105B300057881526E373DD49BF433FB99BEAE0FB75 +:105B4000B39FBAE97B2B1C46C93E9759587CF34555 +:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69 +:105B6000D780F7D0DBEF11BC075480578B33BE13BF +:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D +:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7 +:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82 +:105BA00083CA46153E01381AB7B0501050EF2E8404 +:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64 +:105BC000FA2988D455B766AA37BA2739036E1C1F3D +:105BD000E6EEC0F19D5402984733001F978A79BAC8 +:105BE000B4E02C06EB91E7B66B2180E352F782E933 +:105BF0006C24B6CB27BCD9055E9764367420BC1FD5 +:105C0000433B06F31DE69EF23EF332F69FD94FF07A +:105C1000796C606C203C5FFDEF751D12F4B732D3D8 +:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B +:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9 +:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A +:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63 +:105C600029E03C3525D2AF314EBFFD023954C0B7D3 +:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85 +:105C80002A0B65F3E769C01779FC57D6E49B94109B +:105C9000288C8587458F93135997BC34FB1C19E8D2 +:105CA000292FE3FA4512D25573D4FAE63066F0CDC7 +:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7 +:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03 +:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5 +:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1 +:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A +:105D0000B5A364A901F19CC7F921CF1676E662BF5D +:105D1000CD39A382D88FFF55E287BCFC4B3405C632 +:105D20001D9627F861F4834E94873DF35F96AEE7A6 +:105D300015339664A103DF79D2816F42DF74F07569 +:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32 +:105D5000963CBBA664C7C295797138A3C21D4B6F30 +:105D6000797982CEFC7DD399B57CB03EC4DE011A30 +:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA +:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A +:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C +:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035 +:105DB000D575DCCAEE928CF6CF0675C0778A683F3F +:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620 +:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4 +:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9 +:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2 +:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF +:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1 +:105E20006F64157912AC43E6F48A0C06EB6FAF6829 +:105E30000EE296DB039FC077647E0F12BCAE0CFEB1 +:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B +:105E5000731441AFF20B594B8F00BD2A49763FE9CD +:105E60001BD701D364C278B32A980670C969150C90 +:105E7000E58192A6BE1BCD0706FD019C6309CEC934 +:105E800015B37A8133180DA701477F701B70F44E4C +:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C +:105EA000F9515D48453C4157ECF35B8336789E3AA7 +:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128 +:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501 +:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC +:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B +:105EF0006DF75B49A2F1274D19F36DC6C7630E908C +:105F00005FC9385E5164BCE469301E76A636C71D91 +:105F10002F65328CE7FCFAF069E547035E7B0CBC29 +:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6 +:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E +:105F4000F94865E12B015F775CE524FDDE9073FF86 +:105F50006C7CA5E2A7B07E77BC547CE24A192B404A +:105F6000D72322E3D74A1AED57BDD1776FF3810DBE +:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63 +:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6 +:105F900037571E291BC8A05FDB9AE14C8749256350 +:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F +:105FB0006F02A56BB7B782F4A29512A3EFD783DE69 +:105FC00016023DA6E4950DCE3958F7EF70CEC1719B +:105FD0006D8CF4E992570EF9CA80CE5D23524629A2 +:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B +:105FF0007FF0BC02DB2788F6BDC1959007F044AD69 +:106000007FA2BD395011477FD76599F0F390D0BB7F +:10601000EE46BD0B047262424B00F56A57BA5D7BD7 +:106020004C8AFDEE265912F306BD0DEDEC115332EC +:1060300051CF3A30E389157684AF90915C77E5854E +:106040007419EAEE02CEDB0F59F67D37AE21E95D19 +:106050009952994ADF99EA77F7E831D913516FF3EA +:1060600016F0F7650D574C6C8C7ECFFC1371FF3525 +:10607000DE071A4AE97DA6B3E2D804183F13E468A4 +:1060800023E02B536D96EA685DD3E2EA8F1BE63B73 +:10609000678500860D331ECC9E1F673F81D534F186 +:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104 +:1060B000820E41BEB978D31EF9E61ACAE55B4241A9 +:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE +:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D +:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03 +:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413 +:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA +:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951 +:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB +:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF +:10614000EC79EBEAF7D1CE4EED9843F676536151F8 +:10615000DB246897E4F7CD984274CA08CF6BB1335B +:10616000E2BBAA1513615E8D8CF3DD66F996895C3E +:106170003FD069BDBF2B70062BAEA950477665395D +:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5 +:10619000F94EF8FF9690DFB4BFEFD8743BF9118346 +:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F +:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029 +:1061C0000AB63CD987F67A12F325AB2867278342B3 +:1061D00000A2D897D61D94B5FED7A589B1F29642F4 +:1061E0004E7733A2F4DC0E99EBC969332767AF848D +:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1 +:10620000E1283FC7BAC2C7887F1B819E72802F8258 +:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36 +:106220007D304D2D15FA1FE047C99375D7C8AF4E85 +:106230001FCA97A48FC4E951DFB10B5FAF24E5C239 +:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9 +:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7 +:106260004F84E2F49FA64871FD39567D9EB1A5A6E4 +:10627000F5520696CEDADCD7BAA599F161F4EB5A5D +:10628000A668FF85C24BF5915FDC29FA5BABDD1791 +:10629000C4FDF32CEEED800FA5795418F53D96C79B +:1062A000FC8FF326A487B8343D443A24CADDD208D3 +:1062B0007CF62CD9349E9A9660C2379B05DA761408 +:1062C000FCAE657682C389E3C1388A0F3A94D0FF69 +:1062D000CFC22E2FF548FDE1505FE462FD4E131D45 +:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E +:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA +:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1 +:10631000CAC6F64849200F32AE67010DEAF80A36C0 +:10632000EB35588E453A2CF2915EB05552114E62C3 +:10633000690DFF737DBE10955BE84F7606084F8AA6 +:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88 +:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77 +:10636000578747A51138ACFD162A811F2A0390ECE8 +:10637000383CF801FA09584701F9B5F305CECE3D8E +:10638000303389F5C15F0F59F8EB2189C3C92ACE93 +:10639000CFCE380763B6637B359040F1B29305C426 +:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5 +:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE +:1063C000DFBF59D831C6F3738A4C70EC137CFF845D +:1063D000B32281FCE7076F9C360CF82BE7A8E24755 +:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343 +:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D +:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6 +:106410001D2F9B85FD79AEF1772B48CF095F49FC95 +:106420009923E448CE3C2E0F72AB594843FEFDFC45 +:106430000B164D1F6099109E32AB558DFC4D4C775D +:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5 +:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6 +:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1 +:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44 +:1064800012FFF9EB105219D19D51D72456116FFF0D +:10649000FB44D0A9B6E210B743C0F87B272A1E01FF +:1064A000EB99829BC04F83F74D44BB35B886F9F317 +:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE +:1064C000DFB117E5D50466925F71E4864DC5EFD262 +:1064D000B8DC080567F2F27385E265F9EB5908E369 +:1064E0005B9337D4ED47BF5E6635B79B33D7042542 +:1064F0003BD473EA981F87C9AD64BCFD6C16D27992 +:10650000BCE66806D0CD104137430C7A5966A69791 +:10651000C17596B8D01A737D20D2057C37D0422F32 +:10652000D67E723446F1B8BCF5328F17CD32C77DB6 +:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5 +:10654000F6AFB24001E265F70FDDFF590013FCD949 +:10655000FA49A98817902749244F2AE2DB3D31F4F4 +:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766 +:10657000CE0538D67A7446E307B349AE2B225E794E +:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5 +:1065900019970C8C96F78AF02319F546E147B28ECD +:1065A0003755E57AF07B4C9F8A7818E50864605C83 +:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF +:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00 +:1065D0003377CA79E1A3440DDCA442199C04660414 +:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161 +:1065F0002E8879053DED02D06E84A9DD3C9C0FB458 +:10660000D34DED2A62DADD26FA63A671F598716B37 +:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777 +:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9 +:10663000A6719979DC9EF7A576E33DF9630FE44FE7 +:10664000217A39943FA57C2E8CB3F4451B97115BBE +:10665000793E874157FB45BB26A4AB42CC5B6163C7 +:10666000AA294F85E7AD34BA673A0351CF7BE8CA10 +:106670003DD317FFF95C537B758D8BE9C5F49CDA2C +:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C +:10669000AE69D05590630354537D4D86786FBBA689 +:1066A000810262223E02B2F29B8551FCDD33FE3F45 +:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1 +:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7 +:1066D000F7FFE6F95559E65765995F95697EF69596 +:1066E00055938279FF97E6B7CC32BF6596F92D3383 +:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A +:10670000F35F27FD7FAD88E326ACD41B56E07BE02A +:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9 +:10672000548DE482D323935C60F9F6507E36876BF8 +:1067300026C885E7541F97DF02CED72CF50F2D759D +:10674000F8E56FB86FFA9861475AE47C3FFBDACA04 +:106750004CBE9FACF2F8E5E87D4D15B83938A094F1 +:10676000E44FA38FCB9FFD03843C4A837D8DFC4483 +:106770001924AF6C425EDD57CFF3D89A457E506343 +:106780005A11E1A759D80B2C9465DA370F4C9CD2DB +:10679000867EAB334779DEE23A1BD7C756D6339DA8 +:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F +:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C +:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56 +:1067D000503E20F4C52BD264F2576CAE872D339F08 +:1067E000F4482A1FA9F78D5561BC9FD46750FD233B +:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8 +:1068000069429A4AFB2F53C34A5249E4B981D78F50 +:10681000A44957E077E33264DECE196AF4C66F57B5 +:1068200086EDC664A8040F7307156F5ADC76E5364B +:10683000C04BA95BF4E70B347AE2F7F72D6C57E411 +:1068400016FDA5698DEEF8FDCDC47147FA381E58C6 +:1068500046474362FC763760BB429F986F56584E5E +:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8 +:10687000476D69DA66292A3E141A50C164A0F39460 +:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024 +:10689000679B1BDE17624E138F478DBF0EDEA33E34 +:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50 +:1068B000A397AF613D793C98BC646B32D79365CEAA +:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767 +:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723 +:1068E000A27D4A0A9FB76B8A338471B147BE7B4948 +:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01 +:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2 +:106910002D977B7264516E25371792FC1CE5A820D9 +:10692000B9336A60A98EFCACACE770FD87EDAE862A +:10693000863C822B88F2C680EB278BCD700DAE3162 +:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1 +:10695000E083F1F5E8F11FFD37F3F8437E601EFF99 +:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765 +:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28 +:1069800051FA78922D70C426F45D255AEFAC0B981D +:10699000F45368F78A681754A2F5D840C0A49F4200 +:1069A000BBD76D42DF35B5AB8869F707D11F338D93 +:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB +:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B +:1069D0004BB463A67199795CF82950A19FEFB30479 +:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0 +:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08 +:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F +:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C +:106A2000BB8399D746BD1F28BE5F23E2D469F6D247 +:106A300046942BBEC1D03E8EBF22538C6BBC67697F +:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729 +:106A5000BB588C9B151FAE35D97CDC45386E213E6A +:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC +:106A70000578593DD9292B49F07E3DF76F1A7EF6EE +:106A8000647B9D13F3761B2F92D963D82EAB6F3F97 +:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401 +:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759 +:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C +:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0 +:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB +:106AE000939E959C3293F4ABE486AB9DBE38DFADAC +:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC +:106B0000614DBEC7F83E94093209E33F693BC2C8F4 +:106B10003F674BF8790A3523149428CEC1E7896A78 +:106B200025FE24AAE1A00CED076D54593895B1FB60 +:106B3000E5C08D881F575E33F9C7549F2E219ECE26 +:106B4000D94257D379025017E3E57FCCB3733FF0B6 +:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E +:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421 +:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679 +:106B80007C35F85FC4B7E78E61E247BBE10F308F19 +:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643 +:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB +:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48 +:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14 +:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C +:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294 +:106BF0005F3D528A7943CD769EAFF301D08B16C5A7 +:106C00005755EE901DEDF97776155F3F9EE1F7A1A0 +:106C10005583509E26B3B8E78C6E5D6386AF3FF810 +:106C2000ADF032D640F0F60687BA558AEBBF7AD47B +:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF +:106C4000297F74917CDF27E80836C0CBB89CAFBBA6 +:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF +:106C6000AE5C92237126872DA00F86EF6C7B268663 +:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E +:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791 +:106C9000201F2EFAB5C29CD0AE739B8785715F50C2 +:106CA0004376942755BB94B871598AFCC3FC17FDF1 +:106CB000C24372A26A8723341DBEAFFAE53B231993 +:106CC000E0A1B3A1FBF060DC479F92787C34D8311F +:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0 +:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E +:106CF000C7C4BE04EDB87FED4929941F477E18F143 +:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016 +:106D1000386AB77E487454F68BED5EC443ED1EC5E9 +:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA +:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222 +:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D +:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3 +:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA +:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27 +:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367 +:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9 +:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02 +:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78 +:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9 +:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9 +:106DE00091C7A4ED9150D902435E94967539B84B82 +:106DF000612E80F3F4314708F39A6BE1D9B2225C3B +:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7 +:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2 +:106E2000946069A338492DEB26F969FDAEF628ACCC +:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2 +:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88 +:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6 +:106E6000BDC99003FDE1B752E270791C7A8503F940 +:106E700069C7D34F3C9CC6D7773A20A473FBD9216E +:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D +:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E +:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57 +:106EB000C83AD58466946B5E7A7E829E8738DDD729 +:106EC00084F65F27C559B7D58E1C2E8F433C696F5A +:106ED000F1963FD899DBBC9ED2185CC71353F0796A +:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA +:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D +:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4 +:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20 +:106F2000AF539FC797EF8F382401475DF9A0DCD896 +:106F3000FD496515C1C1D911784F8973B3A79E5218 +:106F4000424178BEAAE520C969AB5CA8E9454F7EFD +:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55 +:106F6000093BDA4787B7EEB4771446E81EE57F742D +:106F70005EE4A967F68F24398DFDC7599F5F0B79B1 +:106F800057DB6AEEBF76DB87A6FE17055BECE417DE +:106F9000ED679C0F54FD069CEF07ED368679F71FD1 +:106FA000B428E5F1F49B90C366CA835AE5293D866F +:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607 +:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93 +:106FD000EB991625B79B2DF8F4A5F926625CCD3701 +:106FE000B9A224DA7E32E04FD66513FC7778CA075F +:106FF000E27909B4C3344C3250FDE45756BC53CA4D +:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B +:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436 +:10702000BF7AEF641EC735E67FEF456C1303B97B6B +:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB +:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3 +:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4 +:10706000533E8F1DC7CD45FB2944CF135998EA8A5B +:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D +:10708000F8D401CFEF2B4F9138DC61CAD74816E313 +:10709000C88959997DF13F9BAC9E8AF6FB38D8266A +:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21 +:1070B0000912EE3738BFC178AE479C9FF7F5CC5721 +:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5 +:1070D00054056F0D68263FC720D64265166BA73250 +:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6 +:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE +:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0 +:10711000865F26106D7735B26A9ABB2B8D1F63315F +:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2 +:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B +:10714000CAFA0A935D6D2D9B0738E76C66043FF71A +:1071500053494E7E7E59679A2F9AFE605C67697428 +:107160003EA3AE937D2FDEDB607AF8D28178546245 +:10717000E96F06D2DF68A4BF0ED14937F9296E57EF +:107180000257E37C33F2EA24FE3C2071BF97AEE065 +:107190007CD345FF72627566A08F79B259401F514A +:1071A000792D1B84FDA8AA4C4D284278368975B7E5 +:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4 +:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2 +:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592 +:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E +:1071F000830FE2E8C3D67DF77667FC3C2436267E13 +:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C +:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413 +:10722000CFAD59E8A86B47D2489487C8BF78CF45FF +:10723000A2782E6DDBBF1FF5A6262FD3935348CE21 +:10724000694A2E9E971AE594A05CBCEBC3977F8D8C +:10725000FEF55685E1D6DCE536E2937A322E5622EB +:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C +:107270006EFAFECC3689CE4F296CF88FF1FC436D47 +:107280009B8D85E0FD19C6FB3FB389EB030B5F8443 +:1072900051F03CA8181FF7A5E8FD23B53C8169D142 +:1072A000793C41BD1DCFFFCF13F8185091627AFF92 +:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A +:1072C00091B27C2825E1093F8606FF90FE8CF99F4C +:1072D000930376BE4F542485499F01FB17ED86909A +:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B +:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC +:107300007DE066EE5EF0EA0F97507C94F86AC98BD8 +:107310003C2F6CC976294479CC1D439318E159213F +:10732000BFD17BACEE41D83922F46BC19B23C38C17 +:10733000679766C673628119AF1EBF198F563C27C7 +:107340008DC931B55FA454DB89C8049E0BE01FE2F0 +:1073500019E420CDA306E611D662F159D97AEF2AB5 +:10736000F46FF48B470BFE4E59F07796B5EEE76F4E +:107370005985339D589BE69DA986897FACFC66E0C4 +:1073800029CBD73E919EF93DE42FCE109D48F3F8CE +:1073900077839C2D9C798AFCC46F467E7062CF7E79 +:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA +:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA +:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29 +:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940 +:1073E0004F51F735A8B7D7CEE7798E372770FFEB27 +:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50 +:10740000554212FA8B7CFA8B57A2DED56AD3685F9D +:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195 +:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D +:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3 +:10744000E77424C7C5CE6EB2A35777D455E0BC0C01 +:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B +:1074600073F7297E1E738A32FB9B23A03EF6359567 +:10747000CB4DA64F9F93CE5328701D3760BE24F28C +:10748000C17FC9A106C24FF3EF314ED5F81795A1C0 +:10749000FE5852B780F69F5F7BA7B46159AAB71414 +:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28 +:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C +:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55 +:1074D000623FF2B2F40BC98BFD91AC4F73917F9474 +:1074E0009FE3F2ABF1EDA74713B87D037891504EBF +:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE +:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D +:10751000F6A105EED00A98C781055517A35DF4C9F9 +:10752000BF052E8E17A788D8072C49A63D4F4F625E +:1075300063902F9AF8F932D69C19EFFCBCC10F0664 +:107540007F187C91B9202110CF7FF98E8BCF6FD21D +:107550008202CA83EDDC27518CA7B301E0EA038FD6 +:1075600041D63018E1A9DDF311F9179CADF1FDD03A +:10757000F5784803E9B621B8623CE0EB7BC0D44122 +:10758000E4077B7376BCFE836C03F99B16B834E288 +:10759000B74E27B7A399DA9C39D3837C5276F52A64 +:1075A00080F361E03F24F9876C7E823BB89831F22A +:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4 +:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B +:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046 +:1075E0004F5982FE23FC9E55A69130F407BCBE790C +:1075F000B0FF5FB607F01D27BFCBD077520220FB4C +:10760000009E14B74CE756D0DE427BA296193F414C +:10761000523E0DFEC34366783ECB90B752AB14F694 +:1076200080DC2C71BAC3E84F49A98479633C8A395C +:10763000797FED667D14252FCA5D94013C599EDB50 +:107640003B861C36E477533297834DF7AAA146094F +:10765000D3DF3B5CE83FCED6B549985A95A26A94F1 +:10766000E7705125F3075148E63E92DCA3F78C679B +:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2 +:10768000F135B2ADFB00AA4F7E174BC5F59E22F433 +:107690009BB1A7B93C32F2FA6B85BD619547CF012A +:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884 +:1076B000A10553681F2D6A2D3E88F939456F717EEB +:1076C0006442FE80F54678296D0B2A880FABDCE911 +:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52 +:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2 +:1076F000C2C0ABB4083D152DF31F7444D18F21A730 +:1077000022F414223AB48E2331674FDD978BF2E5D1 +:1077100088827E90AE893C3EB942F051F2C7A1AB5F +:1077200071FE1B5AA7BA90EE77B4953991AD966465 +:10773000F0735EEAFEEB824C904F745CD7C69C1AE5 +:107740009E291F0F2B8FF8507C508F9AD79966492E +:107750009C73D492AE8B733F82512EC9E0E7B8760A +:10776000B4E524713B334CEBDE43F7C20F61F08587 +:1077700041EF56FA36F8A19171BF84A13F28528B90 +:10778000B00BCD7E8146C3CF1174519CF80EA10F72 +:1077900036BA2F5937017E6D0A4FF2615CE20E4F07 +:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB +:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669 +:1077C000860F03AFE310AFD297C7EBA7B8BEA36392 +:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17 +:1077E000057EDD4176173FB761D097212F4A976E0E +:1077F000CC24E26837DFEB65C891317BEA0EA28AC0 +:1078000068951397B5B26B114F63C32AC3A32EFDBE +:10781000C98D8FF1974C3A7F716302F0DFA817662C +:107820002DDA068F466A2C753A0035B25D2539C6C9 +:10783000DACF2F0ED512FE381DFD8B865E1A8357C8 +:10784000A1971AFB8B11075A9710A8C4F1A53DC048 +:10785000375ECC3FE5F6EE5A57605102B44F0498BC +:107860001330D7AE209CCDED53335FF6C687891613 +:107870003E6B01BCD03904D8E7F2A558388CF1F33F +:107880001292399C406DA8BF6495323E580DBFCF0F +:107890002E6B240BE03E8CC736719E6B85FE759770 +:1078A000A55CEBAA68C079D9541674147D79B80D1B +:1078B000BFE0BA043D88F87096EB348FC13EE647CE +:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA +:1078D000379EFB99AE4D44BA189CC7E83CEC60D487 +:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A +:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F +:10790000E8DAFBC64518977CFBDF3FF260DCE94F05 +:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C +:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6 +:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0 +:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC +:107950000E9E27659DFFFBC28EBA6DDB66FB600D38 +:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819 +:10797000E66E1B65473CFCA9D521E2F0ED368E7F13 +:107980007D3AC6CF026229AC701EDE9748FDCD7FDE +:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC +:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44 +:1079B0001CE821B06C35C5D9ACF39C13B4C6339721 +:1079C000939D6ECDF398C7B47513B2E3E47BB4F224 +:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5 +:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3 +:1079F000775279AADE47E553091A8F67EFD97F9846 +:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56 +:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4 +:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97 +:107A3000C858780DB93D1BEF958DC28321C7ADF8AD +:107A400038D3969B887421255AE3C05F0D2FBD7DE6 +:107A5000B758899F3768F0CF53C21F306FCB8C5512 +:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B +:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A +:107A800005F05186883F66A0DD67A5B7FEF2893A0A +:107A90006D1D43500E58E9AB536271EF154D4DE427 +:107AA000FEF2799A3E05ED50D85E56F1381D973FAB +:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB +:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF +:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF +:107AE0000B1325E10F37E72BB035C16B906F3F7952 +:107AF000DCE6433F43ED56078F83EFE278833A8F0E +:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1 +:107B1000D862A3FC13F497E130BDC5717BE2C22D9E +:107B20007DC7B76B77AD8B9B7762E40758E9F606A4 +:107B30000BBD025EC88E09023CE4161771EBC62726 +:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745 +:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52 +:107B600043286E1E43B52DEC453BBC7AB38DECBA71 +:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB +:107B80007100DFA2676D69D3F934285FC158A79EE1 +:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E +:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95 +:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2 +:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09 +:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27 +:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE +:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2 +:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62 +:107C1000F8CA77D3F9791E3D93FB6D829938BFF985 +:107C20009BFE85E6B7800588FE2A1F512AD05F7229 +:107C30005665E5CFC6E1933F093E79EF310706511E +:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA +:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B +:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED +:107C70001F7FE5AA81428ED13D31869E5386CFB1CA +:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91 +:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0 +:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99 +:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C +:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA +:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B +:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255 +:107CF0009477547DDC41F643F5765B05E2E3AFDB38 +:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612 +:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86 +:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6 +:107D30000792302FF783A7165D4C7E060B5E0DB9B8 +:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0 +:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1 +:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3 +:107D7000084E620578AF5EA39D15A0FF392827F84D +:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D +:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14 +:107DA000C797B8B95CD98BB40065B59BE3AD49C43E +:107DB00057C012A4BC7FF429123F257B899F6CF029 +:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE +:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF +:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391 +:107DF0006CF494C950AF31E6392FC9E4DF50E51374 +:107E00000F62DC457D9EDF17B70EF8DA591489F74B +:107E1000263A58D05584F7344209F555D9BF5F85C5 +:107E200046E00647E01A37C9A3491AE2F594CF495C +:107E3000F932773C7715E56756BBB9DF78F8CEF1B4 +:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05 +:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3 +:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4 +:107E7000EA9EF53ABFB251E43528899C0E9424B9A4 +:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8 +:107E9000F0317EDF53F7105C5F4539F347D41BBBED +:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE +:107EB000A81739872C45A27E53DAF65D2CBFED0951 +:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44 +:107ED0009F26E95C8F96806866031E1A75A6D97383 +:107EE0009145CDF9168A52D41DA6713DA671591639 +:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9 +:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D +:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF +:107F20003BB356D21ADD50DFF91623B9DC99E015C0 +:107F3000F907FCDE19C32F31F6A5B965B864257BB6 +:107F400016F13C0EE18732E2E86759AB829389F182 +:107F5000535BE4E178B69EE4647FF1B19FBB457C5E +:107F60006C101B7481F1B167DCE7111FBBC86DE8B1 +:107F7000F322DE2EF6FF334772285F485531278FF4 +:107F800031BBA6508A88F1DD2E8BFC35E878C451D0 +:107F9000DFAD88971147D92DDC5EEA253FE224A3A7 +:107FA000BCE6511D05941F61B3E6471C9329E1A966 +:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F +:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F +:107FD00094D914776047F8FA19717CA6142A08E737 +:107FE000D930D86008E751F3DF01B93C2DA8505AC9 +:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305 +:1080000020DEE7F7AA8D6223290FC226F2207EC95F +:1080100002F747E7411878EC2FCFC49A5762CD2377 +:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29 +:10803000978D33B5CF868D30BA9EBB669AA97D7E6B +:10804000F34C537DE8C69B4CED8785E69ADE0FDF47 +:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D +:1080600058F7CBF6FC202E5D18EB6EE46961BA116F +:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751 +:1080800083B42F5FE8FAE77B843E7481FC3E0A8963 +:108090000DE3443AD713BB6CEE35A81727036C28C1 +:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022 +:1080B0008EBEAFE86371BF1F20F2239B64719E7474 +:1080C0009293F4817B64F996E87BE4AFF0703972A7 +:1080D0008587FB557E02FB26EE9383135990F64F5E +:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649 +:1080F0004FC078664781968C2205EADF88C8FD9BD1 +:108100001C5A23C60346295C8E837C9FE6198DFB8F +:10811000CE721BD77F8236C4F360270B7A8B68DF61 +:10812000A3B866324B939614A2E9D5B3BF685F003B +:10813000311CAC1A9E8476D0CB383406699D09B4C4 +:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7 +:108150008E67E6E5D2F3E33703D701FF1CB79BED4B +:10816000A2FEFC53959BEFF7A0FFFF780133E519C2 +:10817000547BB81D55ED5178BC3CF49774444BD7F3 +:10818000FCCF2E41A06BA5F65528A2576FBCBD822F +:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C +:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E +:1081B000E9E179D7778AF1AE87C20778BB1EEFF481 +:1081C000C6F2850953901FE0795882FAB7DB40F573 +:1081D00003BA9F11C8B6213CBF67FED7764B98AF54 +:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA +:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5 +:108200001B12EDEB309E139F57CC1EBC12B70E63B2 +:10821000BCD759E0F46BB0DE33999FFA35FA672C7E +:10822000C1240777542EFA536A0ECA3F99FC1F4B9C +:10823000F63A48FE75559DDBFE20BCBF6570C7450C +:10824000A85FBC59F5D92588971B372A4C83F50FB1 +:108250002504EEF344E1EDF8BC8F3CF81EF484C72E +:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14 +:108270004D9E893FF6E03E39E6FCE23D654F0D2319 +:108280007BDBA0AFDB047D2D797228E9834B3CE6D4 +:108290007B53963C9E4BE7894A2516D78EC47B3F7D +:1082A000302F7D07D0159E23DCF729CF1FDF7924DF +:1082B000A598CEA3B2C07684CF68BFF3E59B865362 +:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53 +:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE +:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4 +:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8 +:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91 +:108310001045F667601E774BAB928878F3A2C16276 +:10832000C817D009BD78FFA2B83FDD09F6D9702182 +:108330007FDA3D1F4F69E27108935E5772A8CAA4A5 +:10834000CF55C03F94F7976F0A34E23D8DBDEA7573 +:108350006199ECE12FABDFBDF325E57DA787F37FC6 +:108360004B0197DF2DE18410B71B5831EA7BCFE03A +:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318 +:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826 +:108390009DF6E87F872EE57F674E9C032E11E7A2AE +:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990 +:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076 +:1083C00027C799DF2F517E027D8FF572FBC4B987D5 +:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC +:1083E00089FD66F1E13787D8619D4ECB47BC1847C0 +:1083F000A8DEBDC38B66F2658981242FC64B8EBF74 +:108400005AEAA37CABCD43D0AE6D09F3F8C408950E +:1084100005D538F735D76E2CA64BBF6B36A652392B +:108420000CFD09F0A836CCE7D9B9A731259EBD5D72 +:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4 +:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417 +:108450003F185FC5E7209164BCEFE86961AF757EA6 +:10846000AA503BA3DF117B262A3E58CBC270F301F2 +:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C +:1084800057BB6F2AB7E39279DC737B42F71FC5397C +:1084900036FABB042E5F334B81FEB7DBF9FE380C96 +:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9 +:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789 +:1084C000ABED096119F376BA81261F23B822703209 +:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71 +:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D +:1084F0004FF307A558B86A47829E0BFC764F038B53 +:10850000FC7D04CC634B88D49DC013DB739890072B +:10851000C3564FCE8AAE83401A13F97EF63DC35739 +:10852000374D203B27A8A05D0FA52705E7C9F737E2 +:10853000BCBF604011C703FA89139DFC7D4F7B27A8 +:10854000BFB24475F376FE245FE23489F5DC676AD6 +:10855000F89DEE90C2EF5E89FEADF081911AC05297 +:10856000FDC2F344B78BE4D6074768782E31B000DC +:10857000E9F5576FC90CEF47FAE049179D432E788C +:108580006E33F9ABADFDAD3ED6701FE665773D2786 +:10859000699807DA65EBA6B8514DEB7B745E71EA1A +:1085A0009E13746E4B490AD47947635EC48A32C401 +:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350 +:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8 +:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF +:1085E000CC8D3E87156407C81FD6C00E517EA1F101 +:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9 +:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC +:10861000585B86A0DC6D013DACAF7CC65A0BDFF425 +:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22 +:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3 +:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2 +:10865000F3DA0C3A9F9480FCF42C233966F0632102 +:10866000F2A384F742713F4A21D239F29FBD7D1AAD +:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A +:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D +:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F +:1086A0002FC307A89F16FADB75ACC4729FEB294C49 +:1086B000D21810918F7FF3703E6D29D092FC309FBD +:1086C000444531F141D43EC9EB621F957F74D3EA32 +:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A +:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3 +:1086F0005CFE0B3A3920F4E043F51954C7FD428380 +:10870000751A0D25DE0754AAD7E19F2F6163CA9B16 +:108710000F6239AEA2A50C8F4C4D98D57E909F610B +:10872000D38723FDED3A70F570CADF3DEE6098A265 +:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809 +:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10 +:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48 +:10876000AA56E3BD803725E9C7911E97FB02C79142 +:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF +:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451 +:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B +:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54 +:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25 +:1087C0003292EECB30D9994C592ED33DEFAD12F900 +:1087D000272A2D7A48356B5E3518F78DD6CD769CD5 +:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E +:1087F000D05F72592EEA2F403FE49FE87E4DF13F53 +:10880000C628BFA70DF37B9E96397E405E121F1AC5 +:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7 +:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D +:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3 +:10884000A333F2872C68954288C74A43AF13E729C0 +:1088500060DB25BD6E2C0B35E2FD720BB74A740E42 +:1088600063D156B3FFBE7AE32B87D13C5CDC62391F +:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8 +:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC +:10889000AAE8DF68372189D34D8D986F754809891B +:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE +:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44 +:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6 +:1088D000E6F755021F55167CD404240B5C5CDF8E32 +:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570 +:1088F000B3298FE81F0D9F759DAE33D6E95276A937 +:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53 +:10891000F92E67DA72C87F60D087B59F29427F9EA3 +:10892000BA91EB99A7F794258E40BBE888EA97A007 +:108930009FE2973EF6E2798FA2BD0AC3B860576BFB +:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE +:108950008DE2978AE85E90A2978A1273298F424B24 +:10896000457C403FB4EF761DC9FB7D21CACFB6C917 +:108970002588E615478A12513FD8C9B83F427AA9DF +:1089800024B5236A1F599CC4FD03AB32DEB907F539 +:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9 +:1089A000F5AF807AF54B731BF09E8AEA27253FAA24 +:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12 +:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D +:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B +:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE +:1089F000F31494B3A79EDF69A77383DB2596011355 +:108A0000399C71F019BADFE397AF50BE42D9AE5727 +:108A1000283FA137797F3AA4B030D9DDCD742FCC6F +:108A2000E2CD46BD83CE415408BDA966CB09AA5705 +:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA +:108A4000A1661BCF6F80F7247FAA307EAA45E87C01 +:108A50002EE3743057C89F458CDF33B4A8999FA389 +:108A600033EE4532E87CFEB639948716936F86F66E +:108A700025C5219A89BE63EF1BE2F46DBD77C84A14 +:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7 +:108A90002521B110E6F3C98B0AE5DDF741E7B49F64 +:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F +:108AB000D41E3963477D754AEB87B40ED35BF74FFD +:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63 +:108AD000E0726B5AAB23847EEA6FB196265CDFAE00 +:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43 +:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5 +:108B00009737D35A84BCD964C66F97AD4525BA1937 +:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E +:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93 +:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989 +:108B40007E360DE809E3216DE18642947B067EAC1A +:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F +:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47 +:108B700010D7B5C75EC93B38529323F60AD8299F50 +:108B8000250DE076CB28E8FA852C85A5A545EC9542 +:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E +:108BA000BE80CA484ED56E7384D0CEF81F84BFB83D +:108BB000BB008000000000001F8B080000000000C8 +:108BC000000B8D576D6C53E7153EF7C31F8913FBE0 +:108BD0009A78662C34BB31F9202584DB109A40D773 +:108BE000F626A51D83141C58296AABE2B65BD90A88 +:108BF0004E5085281295B889A9D6956942DA7E54D7 +:108C0000EA56DD226D621BAB4C096A9892C8A1A19D +:108C100025E990A0401BD0D659FC60EB9490C0345D +:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4 +:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E +:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89 +:108C500020EA20F2449A60FB242343B0ABAF7B139D +:108C6000254423558B4209CCBBA1EAF335B46FF1FF +:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F +:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA +:108C9000A2C981E98AE760576832FE71FFF796A89A +:108CA000D877EA928F6295D8D8322FD0FD442F9290 +:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC +:108CC00039B5C0AF878C0CD6755E540C4B47FF0985 +:108CD0000F513351F7277F1A9E1721BAF6AE64F869 +:108CE0007467FDAB8D683F6FEF9F87F9377F27195A +:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA +:108D0000EB96F89FBEB217F39247FCFA1B687553B7 +:108D10004F39616E0FED1736493FBBAE04E1AF2FFF +:108D2000E5655CC82E581F23DA7E78A6BF24A9F912 +:108D300036F2DBF397D68EE182F1355A69E46A00A8 +:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F +:108D50002481DBDBDF2AC4E734C058C0FD4526216F +:108D6000CFC973257611E6FD731FC66A89C6F7C1A0 +:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B +:108D800019FFC452A23F0CBE7F2FF30109883A6C31 +:108D90003F8C798B0BE24E23A88238119791C17ECC +:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA +:108DB00014F0637A9FD9315C8D72492745BD64698F +:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77 +:108DD000299717A44E45E388F3590D45043FBBFB83 +:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4 +:108DF00066EDE0F19B9501B218B72FAD766EEF8E60 +:108E000029F406DABB3F79A9960AF6278E13F5ED09 +:108E1000F24C4599B75DE764115FD7B91BD12AB40D +:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834 +:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC +:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C +:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98 +:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535 +:108E7000375BF5F34F83078D23AA15429EC7C68A39 +:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5 +:108E9000C16DB5C47E138965719CC39B833F5EC65B +:108EA0003890D423E2B2383EC435D17731AAA33FFB +:108EB000397031CAE3C9E32B7E6161FEF2338DEB79 +:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B +:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9 +:108EE000B7635EF24C5B93C4DB9C692A63FD592E29 +:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE +:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46 +:108F1000CE63479F6216F228B7EE90A60A3FBF6560 +:108F2000FE804FDD69C914FC38EAD81D7DC7447E38 +:108F3000DB3D6951EFEE231E67FC8F8E253A28D664 +:108F40005934CF623C3EE62ED461ADD75E480871FD +:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67 +:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9 +:108F700077AF678D3D87BF2AF6873C8265B4353E63 +:108F8000C77838ECF067AD971273C5F379EE3C11F2 +:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3 +:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF +:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202 +:108FC00080B4C39CA9731B29EEA145F0B36666FF6C +:108FD00013AC970D6C55E1E76E3AF829EBE0127C83 +:108FE000A9A11AD641524A021278F3EFD31E4D11AD +:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2 +:1090000034F48F6D77DD670D59E0313A74E9DDB0E6 +:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E +:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6 +:10903000D7E786E6D421E91FF782ACD4453B5F979A +:109040009147BDE2F0CFE74998E5C8C3D3D79A2945 +:10905000673DAD838A22BF8947259B751E7156F8EF +:109060000A747E628124C6776F966C0B5F87EA3E36 +:1090700013F7763273D6CB7CAAE97DEE35716E2D6F +:10908000BA40D17C1D37F89DFBF276FD72F9F2A053 +:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E +:1090A000869699F5ABA5B38F95238E274DC9B0E76A +:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9 +:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07 +:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77 +:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85 +:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E +:10910000E874849633AF7EAF69CEB9F5D80B590FAA +:10911000A81E8F9995FF5F77BB4F7CD4C075B93679 +:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B +:109130004B0AF925BBFC528595A48DEEFD38936F43 +:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437 +:1091500082FBF3F8F9607581DF897E45CC27355BAA +:10916000F34469619CAF893827D28E3FA26CCDA6AB +:10917000A585E32997B759C1DB9F2CDE19E7739CBE +:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B +:10919000202E6BD067FF06E3939EA98A70C1B9F8B1 +:1091A000A18B737346127C5C4996C27E9BE1F119D8 +:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D +:1091C0001E37AB9921A941CCB354F072159D15F30C +:1091D0001EA229614D82C0C3B691216C8B3FB38E14 +:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C +:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378 +:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F +:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88 +:10922000745816E77730ABDBAC5F4699BBEE0BACFE +:1092300043BBD974CE295F35CF34E6F3BD138755D0 +:10924000F017E2792ABDEE113866C47E0F73E0C8CC +:10925000BB957495DBA970A5C3679A7A96F779A434 +:10926000DF27DE39B2DF1278FC34ECD433003C83E4 +:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45 +:10928000BE5023CF77EE31B4690CFD01BFB38E68B9 +:10929000B5C6784999A87C2BF0F5719D8C92883BD6 +:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D +:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D +:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6 +:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01 +:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD +:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F +:1093000097A523D5C2896AAF60BF399E07C86C6133 +:109310009C25B75E7BFC8EBFE922C7F299643E07AD +:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71 +:10933000C84E61BF69392EC8F88A62F805DF6389B3 +:10934000B16658B5CDD47796F0931D7904F279A41F +:10935000781FDCC7F4033C1041865D9A934FAA4402 +:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F +:109370006B914D95B3E33BE94B9CE4FCA665636CB4 +:1093800054DCA33B9B59EF18A7EFE47092F3386DC0 +:10939000B163A9AC2E7019619DBECF67DF93C1BACE +:1093A000A77C7635C79FC303051224D55C9C73F850 +:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147 +:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF +:1093D000EBB00E00000000000000000000000000E4 +:1093E0001F8B080000000000000B7BCBC7C0F0A360 +:1093F0001E81FDD0F8E8B89D17BF3CA9588601C171 +:10940000CEE7626008E160600805E2FD407C00880C +:10941000E53919182280381288A703F93380B8007B +:1094200088D3816A9B99191876B131301C04E213F4 +:10943000407C9E8D74FB3F88333054C820F8C78031 +:10944000EC2372D4F5E3281EBC38CF0095BF4E1331 +:1094500095BF4D9B81E13D929AF59AA499AF6CC856 +:10946000C0A002C4003A4CE95968030000000000A3 +:1094700000000000000000001F8B0800000000003A +:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B +:10949000494218421E3B2140800487102250B0935D +:1094A00014142DB5113D2D7ABC3A8447906740AB1A +:1094B000E9114F3624840001068A3572224E103499 +:1094C0005AA841F1D1536C878716ADED8DD656DB86 +:1094D000FA88A8A0A89C5445A7E7D472D7FFAFB5D7 +:1094E00093BD273301DBDE73EFF7DD9B7E75F1EF74 +:1094F000F5FED7FF5AFFFAD71A45B411F9EB849C51 +:10950000873F9AE68A849021FD2921B2D6E3809490 +:10951000E8E7475860725EBA18F82FA3ADB0CEDB0B +:10952000FD1742B208F91ECFA37F21806770C018D3 +:109530008F9192A04262C5FDEDCC200CD644819C57 +:1095400017E0AB35DFE8A7DEE11B4FD208F9C2C94F +:1095500052BD8A6695D3F44D67B4B1801087101E52 +:10956000C1C65377497529A69742DA2890B95D9EFE +:1095700024E320EB08994493FDC34452D13FFEC439 +:109580007246DAD44048CCDE0FCB3209256BB78265 +:109590008E1FDA7D5F0857E0783C44067C281C1F4C +:1095A00036122484CEEB88FFF2C03C3AFED6694ADC +:1095B000D00E193B874165E233F038371F610787CA +:1095C0002B89C6F11D6B1941EB398322D944A1A621 +:1095D000822A07292164EB94CF03613A1EA71C213C +:1095E0002AA49EE4E3BB9A88BC9DBBC8C5CC3B7152 +:1095F0003D6458A349088A302F63BCDB6C745C99C6 +:10960000743D2689641F85B794CF4983F118F3729E +:10961000A4E8A719F03A9A90CD0D0E4C9B26CF499D +:1096200023508FF4CE85F5DD3A254BDC24F4973FAB +:1096300032E539470F9D6F23AFD7AA1D7540796377 +:109640009D13F1B695E32744041CF7E652D7DC6876 +:10965000C9C07184880FF3B73A692598879744F792 +:1096600015400B3D6DF329EC9BAC966DD206D2CB29 +:109670008C523918A3E3F4783C413BCDF704587D74 +:10968000C7EB4254C3FA21CF305ADE65ACFF64B158 +:109690001F9FF4FF3E524D08E5475F4EEF6BD08FA2 +:1096A000FD757B3044BFBBFFFCE96BF369BBE46D28 +:1096B00021B80FFA25AB2CEB45F632BCDA54FA6F21 +:1096C0009AEF9AB668364CC1FDE5E3D580B78D4573 +:1096D000AB5D6B61AD8AD9FAA9F47FE70B69FB9AA0 +:1096E00062E9DF665EDF02204D2BEC1E39E7DB23EB +:1096F000B4D4F4E1EEF19158062D2CDD88EB9DAA4F +:109700005CFDEB132E3B6EEAB78D78334FB9E93F22 +:109710002E2597229F5FA0FE170DC1CB8EDB70DE3A +:10972000A259DEA42ABF9ED3471F9D1550FA28C117 +:10973000F50C5C53DAFFFD25A00BE007BD12E51820 +:10974000F2229D6FF374D22BD1F5681AA968EB2829 +:109750001EECAA12137CACCF5EA02FF807AD6A2FC7 +:109760006AEE16C603F03D8B1C6C19FAAFC1D82007 +:10977000E34B5C87AF8ABF18E06F5C3FFEECA43A16 +:109780002D06EB5D1D40FC78F938364CBF5D8BD162 +:10979000F96CC8FE61E86D62C2E3A58CCFFAC6938E +:1097A0001325E6FE0DFEBA4408BD08F89194E06B5F +:1097B000618A0F325509EE4B322F596072A51FCFC7 +:1097C0000E99187802FA3DAC07AEF1E290AA1D2678 +:1097D0003CDB03CFFD19F0276792987B3C7E6F92AC +:1097E000D3A9FCCA24BA3B0D5B9101FE332940FE8C +:1097F000A4F9339432900B9707C3B49F661BEF4FC5 +:109800005D6B59D73FF375EDCFD703FF64C9B761DF +:109810007BCD5E2E37D4461CDF80FA7E563F71BE6C +:109820007F02393A09CAA99C7E1A03A06F1CC39A09 +:10983000671D01BC8FAEEB9A0F735409E2C190FF14 +:109840005401122847F5C39FA19E43AB46BCDB736E +:1098500042248C78B3EAD3947239418F0EA02795B5 +:10986000C2461B85F0DF1C15F98D24EA6F9E8672B7 +:109870002F4A0F3626F0156D2AA99E291598BC256A +:109880007A26CE5F36E880DB0736031D3B193FABF7 +:10989000BC5F05C643E5A19344B17137A57480BD93 +:1098A000A40EE173A1B298007423938D20E7EC21FC +:1098B00091E80503FBDFCAF549AA796C9D925C0F1C +:1098C000E40A4C0F489E3ABE1E37AAC067821E2685 +:1098D000E781DF4884EBBF20AEF786867AF20E9DE3 +:1098E0008CEBE89544A3F423E7D48542B49E04BCF2 +:1098F000484534F194B3540E6A66FAEA5B47B216EF +:10990000DBB351B4C03C6D1EC73C321E52F51A4C3D +:109910008BC72E04FEB0A55D5E0FA61CA59B4A0159 +:10992000FA7724A72BE2A14C3A0561AD3A697F7C16 +:10993000BD79B994F4D5471FC67C35A5DA3B906E46 +:109940005CE5AA00AC40C16E18CF503E9AA1E1E69A +:1099500055E27858B7C8AC51747D86F6CC43FDE427 +:109960007DFDCA0F605EEB4BCA4E8009971654AF5F +:10997000B99CAEA7AB980880EF8DD0D85468E1842D +:109980005E097A1DFE994DC8FF109E09E91E463EEC +:10999000567B53D464439E8883DA2FC279FBC0FA86 +:1099A00029E53331F10FEAF1D517672FDDC8FAD376 +:1099B000E9FF80EFFC09FA342D646A97007EACFD64 +:1099C0006C00BA41FCAEFA6FE94F253B1C1AD81D5A +:1099D00045A21AA57DA711D54F653171CD9009E833 +:1099E0001335A75787E5BDD0BAAC276416CA51CA4C +:1099F000B7663A6FE7722050D354D04CDB3D57EE38 +:109A000009821C184AC56646FAC0F96C4EB0B337D5 +:109A100097EC41F9D848E9A810ECFD1211EDA18DA1 +:109A2000458FA9667DF53343DE0CA00FA2C915282A +:109A30003A08A1F8918AC49073FCDF4F1F8976D24F +:109A4000C5D287FB46EB7A7CD5F5FA659FFD7D7123 +:109A5000F4F1F7F667AC6B2AB945D715EDEF166D43 +:109A6000CEA0F6CBC075DD81EBEA2A22A16472B8E4 +:109A70005B10ACFAC99C9AF507B9D5B25EB64BBF7C +:109A800033F78141F0619B6B9DAFD1AEB35ED2DE07 +:109A9000053B5656511F19FB878DDA0E1DECF973E5 +:109AA0003984D97B91553101ECA022827610342083 +:109AB00052D8A985A29B0446FFB02E867D63A3E6FB +:109AC00098B93F497559FB9FAB0BE6F13BEB151C71 +:109AD0008703FA03BEF4D00669BB520E8939D1FE62 +:109AE00064EB075DB17DFC9D17450706BD025A1961 +:109AF000BD5AEB3507CA48B2F51BD0DF75D6F1A6C3 +:109B0000944B89F53CB276CA648FA4AE2793532652 +:109B1000BB66789FFF4237ECB9A7056A173606BEC9 +:109B2000A3E3B8E13F54BFB6404AF59934AC8A8408 +:109B300035D0931AE3132D9DE9DF4EC1B20F37BE26 +:109B4000A71E07EB2FBE90D222C83559B3D8CB89B8 +:109B5000696343E06B32254A77FD0353E589D48876 +:109B60005D1B9A5B4DCB6F6CE89C0ADF8D723345B1 +:109B700063FF4DD5A6C93E96092DE7C0AFE4FC446E +:109B8000F8A812CDA4DF1DA40BF3E957BE7E04D7BD +:109B900001ED2ADA649DA861BB0A791ACB414350D2 +:109BA0008E4AF1A972316B0EE0CDB65008C7254739 +:109BB0001CAB29DF6D767258E3B09FC32A870B3840 +:109BC0004CF504C06E85C23475DA222AC22E0E17F7 +:109BD00070389DC37E0E177258D881F06685B5B770 +:109BE000498EB2F65D1CD6389CCE6195C3851C2685 +:109BF0007B58FF7606BB6C51D6BE9BC3051CCEE0DE +:109C0000B09FC323382CEC4138D5FAB98A3A199E53 +:109C1000FAE442573F8CCA83E3B50F8E25C08C5EB1 +:109C200032044687F16F19741344F9483C79C86FC0 +:109C3000E31C6CBD1BF797A15F82703F8AE9FB09AB +:109C4000D0C7E73AC5E060FCF5432E4F77829D4BC5 +:109C5000D3ED0D2AA6DB1A0268F76E69D0B85FA5AE +:109C600018BF6F6C0822BCA16132A6EB1B42F8BD85 +:109C7000B16116C29D0DD5983ED83017D3BD0D6188 +:109C80004CF7342CC672D1863A8477537B17D2F6C0 +:109C9000061DD35D0D2D98DFD61041F891FD65CFDF +:109CA00017513D7D2E2CA29E4F35FEA173AD7E90A7 +:109CB00021D556B9983E23DD92AF4ECBB6FA4DCAA8 +:109CC0000B2DB0A764AC0576159559DA73E44CB545 +:109CD000E42B99551658F65C6581C744E758E0D1E6 +:109CE0006D3758DA1B19A9B1E48F685962C92FD0B2 +:109CF000575BE0FCFA7FB194CFAD5B67C9DFE60C40 +:109D00003F235279357CF1264BB961E11DD67DDDCB +:109D1000ECCC8B925BE4333DCBECCF4894F7521EF6 +:109D20000985506F31FDD208740B7EAF5C12DD27C0 +:109D300080FFEA8A13B0EFB01731BD33607F99D04E +:109D40009EE279F0359DF653E93B11E831F11909AE +:109D500098EA51B97F5264FBE64D77B17D75EB5DB2 +:109D6000C9F7D728D9E93C5ABF4CEEBFED11256E93 +:109D700007E9967D4AEB5D0296FF7BDB37F213DB4A +:109D8000EDEF8FD25C85D90E891A7E51A267F5EF6F +:109D9000776D3DFEF9B0EF31F6B912E7F3CAB9C1FC +:109DA000B79B289FAC5709FA0DD77BAA08D815E7AF +:109DB00054C6F7646F1EEEC78DF203C767B22B500F +:109DC000FEB8AC7E5ACF1C942FEB3307B7CB94B8B8 +:109DD00084FE3B292E9018D53B8A5C3DAB808E4B90 +:109DE00079450AAE25A87F92EEEF09D981789012C5 +:109DF000EC9BA60509726F462ECEDB66C8B7CC2A4F +:109E0000FCDEA40E3E2E3B8C0BC6C3C7658BBB315C +:109E100095E24E1CEF947806C293E37E4C2F8D0F93 +:109E2000C7B4223E0CD349F1119896C70B309D1848 +:109E30001F87F5CAE263309D109F88DF83F1099880 +:109E40005E12FF1A7E1F1F9F826969FC1BF8BD24EA +:109E50005E89E9B8F837F1FBD8F895988E895F8B61 +:109E6000DF8BE3D7603A3AFECF988E8A5F8FE9C8DE +:109E7000F87C4C8BE2F3301D115F8AF50AE3B76082 +:109E80005A10BF15BF6BF15598E6C7EFC4342FFECB +:109E90007D4C73E38D98E6C4D7623A3CBE19EB65FE +:109EA000C737623A2CFE03FC1E886FC7342B7E2F07 +:109EB000A6FEF80398AFC63B304D8BFF08BFFBE210 +:109EC0000F63EA8D3F8EDF3DF18398BAE33FC5EF24 +:109ED000AEF84F3075C68FE17747FC08A6175A27B2 +:109EE00025C72AC7A54C97059EFC6EBA853E2A5EFB +:109EF000B7CAF1F2570A2DF9652F5AE578F078992B +:109F0000051E7F78AAA57CC9A12A0B3C76BF558E79 +:109F100017EFB5CAF151ED56395EB4D32AC70B5BC2 +:109F2000AD725C6BB2CAF1BC3556399E739B558ECF +:109F3000672FB3CAEFC002ABFCCE22BBACFBEF195C +:109F40007BAC7A6DDA2396F63CE58F25EC57A22898 +:109F5000675C25FF6EA9E7283A9A209F7526A7120D +:109F6000FCE5801299F2F71DC415349FAB18693ACD +:109F7000970719C07734CDE47C3704F88EA6E9DF63 +:109F80005C86E74C5F7CABE5174DB4B1F4E184F936 +:109F900005F44855887E6F1EC661FA45003897A0C3 +:109FA0009F80E8672AC12FD65CC0E07F934E55EAB8 +:109FB000CC7FCBF2C95996EF64F0238DBF5A0BF9D1 +:109FC000E969D1EC204D1FB12597D38F49ECBCED49 +:109FD000AC18EA90E87CFFA3B2E776F0A3FDD51EAB +:109FE000DE27D1EFCB1CE17C704D7F6C0B3F2483CF +:109FF0005C24A107E17B1A093D24A1BCB6FA451BEC +:10A00000C1E0A6ED7C2656EF87FC8CAB17A35FCA98 +:10A010009877B377F0F14425A6979AFD04F78DFA67 +:10A0200011859F2311765E0329D583F7B87D21C85A +:10A03000DF7044D963A7EB60CBC99A4FC6B36216F1 +:10A04000FD116B5E057AD8017A680448F92E4C3D03 +:10A05000A49B9D1B915E4C55A20A901AF3EF9B772F +:10A060002E9B37C5C72F24DC1FD461F975EEAB27B3 +:10A07000C37C283E4EC0778A8FE7A521A9F141E035 +:10A0800064818E3FCFA0A2FD82C5FFF8BE10FE8D79 +:10A0900064F263E6D507713F794052111F06FEE86E +:10A0A000DF6DE9863F86D5FB23F69BD09ECCCFC5DE +:10A0B0007E23F1FEB93E34E8384324E1647ADD388A +:10A0C000F7219D795FC99F2D28CC2E49ECC72657D3 +:10A0D000E379EA00B99799B0AFCF0CC3A250FD491C +:10A0E000F56592714D57B87F4ACEBFA8F32BC35F79 +:10A0F00042F6E77DA5F32EA004286F901C399E87B9 +:10A100007090EBDF02B0EBA83D72EC8DA762CBA99B +:10A110001CD85044752DFA2DACF6DC869888E7EBF8 +:10A12000057E2A706863F5DC0E90B93D68F42B3724 +:10A1300059FD299B6D7C7F7BD88AC7024AD0FF4E90 +:10A14000B7DCC493CFC6C7CF2D8D76F6F48DDF3A3A +:10A150008E074AA83964C2676129251D18478C8D6E +:10A1600023B17FC2CF170CFE913DDC6FA2E663BB2B +:10A1700046BF89FD1069369E27A5C2EF807EBEE2EC +:10A18000795D859CFCBC93AE0FE2696C8AF535CE97 +:10A19000EB0CF8D81BB578FEDDDC59837654738060 +:10A1A0009FB3FF85B60AED1092D45EDCCBF1BB897C +:10A1B000EF17F746AA1C582F33DFB24E45DB67B8BE +:10A1C000000F4D6A553AA4FB76B27223EFBECE154E +:10A1D00066765B3AA49B8AD977D798BD0E567E8F58 +:10A1E0000AE9E612F6DD5D7AC8C1CA333F2DA9A798 +:10A1F0007FA673A022B55A14CA41FF92904C619772 +:10A200001A25E04776AB5D981AE3CE8E88E2185A9D +:10A2100025BB33947E25F8DDEA4870241BAA03D6BB +:10A2200039CA972FC7C8AFA7F9B4BD313B8F564283 +:10A230003DE7CEBD95576AFDE577F3FEC774465BF3 +:10A240000AA17C8EB5BD76DE9EB3B3EB04F89B29E4 +:10A250008EB13D237F17CFB7437E26521BD6974B37 +:10A26000DE8DC1798681E740B1D8087022BF1BED31 +:10A27000B4F171043BA3912AE867AE751C3F34C862 +:10A28000B29384A21E933CE0F9119EBF01F6FDB487 +:10A290003FB993F9518DFCADC63823AC7E23F70B43 +:10A2A00018781DC3E591413FA9E898E8A265FF46EB +:10A2B000EA5D56B8CE64DF01BC38DB9A1F2EB4C20B +:10A2C00073C75AE15099159E3CD5D2DE177D7E9416 +:10A2D000A813FD25DC8F62F85E76A935B8CFE9F7C3 +:10A2E000D3455C588EEF3B7278B987EB98BFA5D108 +:10A2F000C3F985FB5D9C5C2E3617B17D499F5DC11E +:10A30000F1DDC5FD1A8F36B4B1F8940BD8C3EDBC9E +:10A31000DE2E7EFED8C6FD323F04FCDB61BD985FB9 +:10A3200026C2FD325BC12F43D356F0CBD8813F9973 +:10A330005FA605FC32343DC0FD323F02BF0C851FD5 +:10A3400006BF0C4D1FE27E997DDC2FF300F86528D7 +:10A350007C7042F75CF0B775807F86C2F773FF8C24 +:10A360009FCBE58333A3D9E00F7B6466F27DB1DF39 +:10A37000C6FCEEB960A850FAB884048FA1BF9B8ACE +:10A3800061F0774FAC0B362A9960B732BC4D0C07A1 +:10A390001B6DE560B73238DFC6F428E80BD01FE448 +:10A3A00030F327503ECB047C6FE1745976222CCCDD +:10A3B000A3E3F8A3CCF5A2460218B7C0F902F24114 +:10A3C0009EBC21845E972741BB04C795BFB7AE0AE8 +:10A3D000C468F1D3D5475DB4DCA8AEE03A707D1611 +:10A3E00095A8E05920CE224D84F5395819443FDA1A +:10A3F00096DF4AC13DD06626B1D0031D1BCABD31D0 +:10A40000063CCD4A0F97C477A3FDDB5C37270DE9E7 +:10A41000492383EEC7FD21EB3E286DB2D59FD5BC05 +:10A4200097B5938A6E8ADBADF6C4A89DD67D54732A +:10A43000D19C41FDCF45ADD6FE0B9B12EA7B06AF0A +:10A440009F1FBF1AEDFB54F43D4EAC49B34DEA8754 +:10A450003DF1CBB07CA27D2703A150BB4D3EAE6049 +:10A4600048957C5C0D815D2B1FD7781AE4DF431C77 +:10A47000AE66B0CAE220A83D986B1B82EB9370BE1B +:10A480001D2270FE7C109501FDBFBE705D88D2DC80 +:10A49000C17F22B8DF78435E55A55378D76C8728F3 +:10A4A0005D02F4C6E21914BE5E194A746301D0C39A +:10A4B000C322017A78A473703E1E10E7E009A17FE1 +:10A4C000A6A0492D03F59DAADECE2671563449BBC0 +:10A4D00053395F91E324D16E9E0AF35DDF34474523 +:10A4E0003D725D10F7074463E337E45C46FAE0EB46 +:10A4F000B7ABC17ABE964D92DBA16B6C9CDF8A999B +:10A500007C34E83FE3C1C1DBDFC0DB8F770916FF96 +:10A51000CE90EBAA2B6D99B8DF097A408E7E293157 +:10A520003FD961169F66F05363D10E179437FACF67 +:10A53000CE89C1F684341F99C2E226287E713F7805 +:10A5400084CAF11294E368F73917D785989F3C8243 +:10A55000F10DCEBAA00EED481E462FB0DFE4E57136 +:10A560003C1BF78A1872D13897D9AD869C37E8A082 +:10A5700031C0FDEB7365E667FB0B9D9FB11F81FD4D +:10A58000A15A87E77BCD93D87C6C992C0EC4561CBE +:10A590008BC1D959B377D15A98AFBED0D0D73CEE42 +:10A5A00082B0B82B231E0FF003E7E0056DE3518E58 +:10A5B0001878FCB610AE073EB265EA4218E7D185BE +:10A5C000ED1B784BC4FB77B93C1D9EC20F97A6309C +:10A5D000B99EA1A85781BCDD7284D277927DBD93CC +:10A5E00097EB88CDD90636A2C1AF46FE0149C37E9E +:10A5F0000CB820AEB0B8BE9875FFF1FFBA1DFFA829 +:10A60000CD1A77F7FFEDF8FFDBED789A0F7648F873 +:10A6100002763CB7F3F7F6D16F829D5E2C1FC130F6 +:10A62000BA047B3EAB7846AC0AF23BBBBAD18E9FF4 +:10A630003CB81D4F12EC77C3AE37EC77C39E37ECB6 +:10A640007532D09EE7FAEF1BEB4232C48911D47FFA +:10A65000E39ABFB14E87FE13FC1E12157366FF45C9 +:10A660002FF0F910133F78AC76C3C5CB0719F53F2F +:10A6700009E65AE46B46F6E0768E11EFFD45AE61D1 +:10A68000AF87D83968513131DB634D548EFBE87C9C +:10A69000DAE7B2F329C2E578B6E197290EFB47A3C2 +:10A6A0007CB7CADDF6C5353A9EA394133C7FF4E42B +:10A6B0007485E07C3C6B6E04ED492A7F8B1593FC1E +:10A6C0002D68AB4039A773FB32119F20EF0265D094 +:10A6D0004F829C21C19745C8CF85B36BE087A88086 +:10A6E000FA03E234C60F226F2E325EC3889FC8A3DE +:10A6F0007F206736C86C7CE4696BFC3951297D5436 +:10A70000F4DBCDE4FDF98239EECFB06312EB51B941 +:10A71000A026937B6F08E16F2983D047A23F8A244C +:10A72000C8692A8844E8BF60F62CF433F5F9A564BB +:10A73000ABDC9603463CCB7FAFFCAE55FEC6B8F310 +:10A74000AFE8B7DBC8E5F3007E4E68472CE9223D51 +:10A7500049FAF79458F1EE2AB2DAF302085B881F3F +:10A76000CEB19E93CB9EECE4E7003C3EB366B2B123 +:10A770006CDA77FF48F9E4961336BC4762E81DC3EC +:10A780002F7B0BC469D2F5A981B84D4ACF0B48B5D0 +:10A790000F323F2622C6837D4C5EF64D34ADD37D0D +:10A7A0008AC2FA69B19D847B42463CE2C20883FBBF +:10A7B000F0DF668517913959701EB168A70D38888A +:10A7C000DC42E4933DC6F8297F6F51587C752DA972 +:10A7D0006B0639B69EC773D7A84486F8C1E54FDD2E +:10A7E00057318FC27BB9FFF60CC5BF66B28397782D +:10A7F000A20A9C2BBC7368E277BE46A07EB4391BCC +:10A80000E208A9BD0A718489789FDF621DDF85C6D1 +:10A810009F385EE35E51AA71C89D4228D9FEE0319F +:10A82000C51AEF76A1FB4EBF53347EDE6CBDEF74CC +:10A83000A17A7F543492EC9ED485EAF5FC8DFDBD5F +:10A8400097A2DE72478F027260A51C9E2514F6C780 +:10A850006B29B6EAD0708A0AF9E90931385A32957B +:10A860006BB9C8722760637111E5668983B4779606 +:10A87000F3F12FF63FA0007F7EFCC8DB57C379CDF4 +:10A88000D29F4AC441E77576BF97C470DF11554027 +:10A890007F2D392431FF9B1CABB8D6247F315296D3 +:10A8A000E27BE9A35E8CAF58F2983D3A9BD65FF20B +:10A8B000E43BE309C5C3D975BDCF0D87FDC42302B1 +:10A8C0008B27D47BC65F4BBF2F91C9CDD549E4A060 +:10A8D000646774FED14FDC73818E84CE233761BBF5 +:10A8E0005DDFB5D94D76FF7F2A36A31C9E33E90F75 +:10A8F0000BD191021B9FF99E8411C7F9D1C3021B92 +:10A90000DFD3B6A813C6D7D9A18469B9959D7F4274 +:10A91000BAFDC6A3077C8087954F4B16F9B2B25398 +:10A920008AD9C763FAB61DCFAF421E81CA911528D6 +:10A9300062687A6839C67DAFE8DAFC27C907F5ADE9 +:10A94000FC43F1128C015E5F9582B3017EFC211FF6 +:10A95000EC07CF74EFF3015E69BBF3144A57977DA0 +:10A9600066E233C2DA8FA70F6C8F5A380AD0D7CA83 +:10A97000AE8DACBF04FE3C03FF1836502F8CB55B88 +:10A98000EDFA73E4C50ADC877766248D93EFD30B69 +:10A990009C5F971E38B75BA7FD7EF4D887BB753ADE +:10A9A000FE657FFD74F79D6057FECCA9829C59F926 +:10A9B000C86F7DC484F79976C6EF671F7EE8C15DD6 +:10A9C000945FCEFEDE8EFBD1B3CF9CCED3E8BCCF5E +:10A9D0001EFC739646CBDFF6CCCCA18087DB9EF8BD +:10A9E000C6D0C1F6E740AF51BB795DA3B8AEDAD3AC +:10A9F000020BCA3FCCD384F53976E8581E8CF3E3BA +:10AA0000D7EC780F7125FD565F06EBB51CE53EC00F +:10AA10006B289E57ECDFF027697C327CEBC345B88E +:10AA2000F34628DB0460BDAFFDF6F472486D410DBE +:10AA3000DA23BD28B713EBAD7C85AEEB25A9D7F1A2 +:10AA40001CF98B02F85FB97F23EB37611D3F867FCE +:10AA50004C19B88EF3ED56FD7E8E2CBB1F6DFD4359 +:10AA60001949E3A68C755CFEC43F0D6A0718F2E035 +:10AA700042F85DCCE3FF82F6D0AD76E0ABC7DC7A7E +:10AA800080AD6F7436CD3B7BE05C1E186BEFDB7ADC +:10AA90006F0239D9FB8C5D85FDFA92675E453E3BBE +:10AAA000FBC44B8A86729278046A279C257D7FDDE1 +:10AAB0006037AC60B63059B9D71BB3FBFAD76945DC +:10AAC000F49A599A0FBFBF8DDFA38CFE57448F5C59 +:10AAD000272459B703F6422697A343102FCB49B733 +:10AAE000A29658D753980CEBF8F6E54077A9D6D143 +:10AAF00098BF0AF3BFD4B49E7B19DF26965F41F955 +:10AB000013FC837DEB1A155E2549F8F46C875D868E +:10AB100038DFB329CED9FBEEEF7E45FBEF217B8AF0 +:10AB2000FD3BC7C385F8FC42F3FBAAF8BB1B82BF01 +:10AB3000260DC4E3477F492EFF8FD999FF6C050985 +:10AB4000CFCA9606EA2F8984F4E105FDE36DEE9203 +:10AB500050AE7FD42945A16AA29C5891C24FF89269 +:10AB6000D1CFD347C6833CFBE8E84F385D32BA5FAC +:10AB7000B1FF6D45E7FA206AD60729FC547FE4ED62 +:10AB8000AD3C9CBCBD95FBFF94B4BD3372E8BB30BB +:10AB9000FE33DD36A2D326CE744949FDABCFDA6D44 +:10ABA000D638716FC56B69B49EE47369D075E3BA2A +:10ABB000D0ABB09FD35FB611BC4F2B07DFB7D3FC30 +:10ABC00046AF4BDB44F1D5E85B847E48A3BDA604C9 +:10ABD0003CC9816A1DFC1C72667539B391A396FD50 +:10ABE000B04D152DE3A67A3607F4D09B134EDB60EB +:10ABF0009E6F25D8836FC9A479286DEF2D5D08AEAF +:10AC0000D592D1B7B5FDF01A896866FD67EF7D135F +:10AC1000C6437EEE2470BE22FDCCA9833C59B9DB2D +:10AC200019B5D3F91C7BE28B07016F67EFB713BB34 +:10AC3000295EBC56656D9C7EE28BDDFF45F34F437C +:10AC400065DA7FED6E5A1EECF0FD6E0CDAFF8FC7F1 +:10AC5000D2C6132A9F6B7F7EE7D5205F6A41A6D2BA +:10AC6000F2B58F0E45BBEED410069F3A901B85754A +:10AC700059F6F8332B408F2CFDB19B80ABE0D813F5 +:10AC8000AFDE04F0D99F7B31BEF1ECCF4F5F067C85 +:10AC900040ED67CDACC76F31BF3340DB5D0A30CBD1 +:10ACA00017CE735907FB92A59052B9B1F4E934BCA1 +:10ACB000BF632A87F556DA7B6F0FA27F45CF1671E7 +:10ACC0008F13CB063E5CDA69ED4F73303FE84AA53F +:10ACD00077112B1FC966FCDA8DF54A1D9C4E797ED3 +:10ACE000627DA3FC384761423BACFE0A3BA94B4660 +:10ACF000FF931D4CDF2FEDFC72B4B53D9D7F4FECF3 +:10AD0000877DFF9EC0EE9790834E8C235AA6C44643 +:10AD1000A5537E7D52218B816F97F962A3FCB4BF4E +:10AD20009F7239B9CC4561FA3D9B8F03CA034C1C15 +:10AD30003D3F86F55DFE949300BD2FFFB917CF5FB1 +:10AD4000963FF9C5A97FA3DF3F7AC28DFE92E53F0A +:10AD5000BF03D77BB93D7613F8517A0FDAC91E5A73 +:10AD6000FEA383CFE7811DF2912D96973EC8FE7C0E +:10AD700079979D5F6AB0CE83EE0B8AEBE878F4EDAD +:10AD80002CFEAC9EB8826B21AE041C0740C7AF3BC3 +:10AD9000D939213FB75DCDFD499F2CD0D270FC251C +:10ADA000CCAFB59AFB0F567F4B1BEA378D03E243BE +:10ADB000C94442EE50EA46839C95E2DF241A85E5B9 +:10ADC000F8084C8D7292CAFCD05226F3B7D9328360 +:10ADD000A4B604EAB17822E2B9AA8FCFFE275DE2D9 +:10ADE000D5F76A43A1BD790E664F6F7386563870EA +:10ADF0003FE3C17BA1384F2A10F427D8BCBE10D83E +:10AE0000BC12C7FB854DB7833CEF3FCF66E727F504 +:10AE1000B2F6AA06F33FC1E5D280F9333EFB444DBA +:10AE2000473E33E6B1B9414579B2B12180E9868622 +:10AE300062A2615C7F106189E3C35EA21309EEC95F +:10AE40006A6CAC764F7508FC56D026F83B254F1837 +:10AE5000E9CB1EA8C3BDBFC3C3FC94924727B51E50 +:10AE6000F487219EE0BC05F0A470586E9B8D78A5F8 +:10AE7000F5F1FB7267F86EC08B2367AC454E2999DC +:10AE800065167800DE0CBA38F0DF8D3F82F8023F9D +:10AE90008DC6EF4500DEE05E04C0FF07F0F70CC38F +:10AEA000DF542AA3CCF8ABB2C029F1772FC55F6677 +:10AEB0003F5F25E2A19EC7A519FC948A7FE15E0948 +:10AEC0005C1AD8D1D086A9F13D3D855ECF7532B9E7 +:10AED000564FC2782E4654E65721993AC931F99314 +:10AEE0004840C7FB4C782F1AF23DCC8F68ACAFA41A +:10AEF000CAA7ACF24F7B15E673C70B3611E4955425 +:10AF0000FF0079C7748E26CDAE766A88E720FA7581 +:10AF10001BB97E5DDFB79E56FED8DCA061BA85F313 +:10AF2000C936CE27DB61DDC13F1714714D5B671158 +:10AF3000D49F775398EDEF6396732B7FB02B06F178 +:10AF40000E2893344C6328BF5EB34747D27AEE1283 +:10AF500012027AF1BFF6FD28CE957405C01FEAE70C +:10AF6000F823870BFDD7B377106C4C4F1189A511CF +:10AF70001BEC9F12F1DB183CEA807D77AAF1640597 +:10AF8000757B1EED2FEB753BCAEFCC1BBB5EABA1F7 +:10AF9000F3F0B4BA713F991564F4E80986855AD381 +:10AFA000FA65A5B0FBEE735EE976D2F5F4401C2E8F +:10AFB000A5C71D6D239C781E64EB0A801CDCEC6722 +:10AFC0007A469B4B7BBBB4BFDEE70E667FF9CAAD0A +:10AFD000FC6FC863755A99858E0D799B3EC34AEF05 +:10AFE00086BCEDE993B7D5B9309E8C783BF26322ED +:10AFF000FD37DA145DA0764A23D89260DFBD2DB00C +:10B0000078DB817200E3513EE929D803EF05ACE318 +:10B0100071D03AE517D43BDCFF699CB71F20D52DD2 +:10B02000F07E4B0BA52302EFCC50FA2118AF538CC6 +:10B030006984D20FE393C9981AF439139C2726FF29 +:10B04000B954F49CC8EE6188A073884CF7811EF057 +:10B05000331D99E200BB50B6054F80FCEAF58A5DCE +:10B060001097B0DE33C70171D482BF1CD7FD736F58 +:10B070004DFE60E729F01208D08DEA09929325FD74 +:10B08000F77525B58CC07EF280A71BCFFBCA9DA2A9 +:10B09000C59EDCE60C5FE534C1A5D03B5FB7AFE3EE +:10B0A000FC93DFFBFD0EE77792A39322137F1BF146 +:10B0B000A144D349B189CFD78DBC9CC039E740FEAC +:10B0C0004E21C7F6FD63E458637E14D7CD9628372A +:10B0D00032A97CF760AA8B2A8CFF50D33F4F403AAD +:10B0E0005B0AF8209E3D7DF6CBD70B078E33516E61 +:10B0F000F5EB230DFD55541FDD3319E4600A7D7413 +:10B10000E48DD1DF86F8A9779E9704B3BF6E717C7A +:10B1100023EA83DAF814A2D1F1D6B4FD00D3456D49 +:10B120001D48F7EF47D7FB303EA685EDE7DE8FDA07 +:10B13000A25201D2ED7909FCFA84B5FF7E7B2396F9 +:10B1400023E07D31F5FB7E3BAB4FCA35B4A73FE131 +:10B1500073ACD9660FC139CDFB6DB4DE20F8AC817C +:10B16000CD5012FB14DF0180987F52371AE49CC146 +:10B17000EF7728542E011EDEB427F5B32F77CEDCEF +:10B180000E7CBDDC196A839478D22FEA3D8A77441D +:10B190006AF722BEC3BE6B2C7E56E6C77C87DBC532 +:10B1A000C49122DFC7EBABC9F397B77EF8DC5D141F +:10B1B0006A2E095713D3FE5A226C7FBDE2E94AFE7C +:10B1C0002E081B4F12FA64F66CAB1DE5D002EE0F91 +:10B1D00032E8B59F5EC23E7E2FD4424FB7C4B7E37C +:10B1E0007A0B9B4BEF9942F1F729A523F0CB099BF2 +:10B1F000A70F053E5ABBE96BDB6EA4ED7FF6A28478 +:10B20000DF17C79D58FE83BB82F7DC08F6FAAF6CE8 +:10B2100018DFF4D98999780EFB81CDEA47A871B17E +:10B22000FDCD5B4E962E8A6FB6D8C78B5AE62BE0C3 +:10B230007F5C14DF8ADF17C1A10CDECFF8F078A5A0 +:10B240000CE73504CF47DFDA787AC63AD46765E889 +:10B25000C7AADD624F7A9FE42DA766913BB53DAD4D +:10B26000D82EA1F65166166FCF243F6AE370F90419 +:10B27000D6472770DF601197237DE36BB759E4C889 +:10B2800007CEE47E92FFE89BDFD7908F06CEEF32A9 +:10B29000C65F46BF3D8CEFFAE773CF9464F3E99F36 +:10B2A000C7342CFF813F79FF591CCFA71A16931082 +:10B2B000954335765ACE03FDDFDA3C19F6D9EDFE1B +:10B2C00074C134AFDAB6A524643EA76C9FA7D498A6 +:10B2D000DAED5F07DBB39545FDEB90E52233611DA9 +:10B2E000EE73568B2EDA5FCDE6E9E3C3B8CF66F294 +:10B2F000E41D5B300FE4EAE9B65B93F277962B61CD +:10B300007DDAF8FA50BBB7DCB43EC6BA24D63FF5B6 +:10B3100046EDE777811FE05E66D4A4C2D780752B27 +:10B32000488EB7A08BE9975354CF86116FDA93AF4D +:10B33000015D6F71631C676AFC8D23E1C1F097C2E8 +:10B340007EA5F6CE18D710E897201E6ADB181D5C84 +:10B35000086FFDFD723AA84C3E9F9BFAE8A09EE85C +:10B3600094614F2A17A2833B89EE18641E7D7430C6 +:10B37000E659333FDEB449433A781FEC94D103D702 +:10B38000FFA4A2FBA6C239D02609CF994EBAF4ACCD +:10B390001B183C01E4F3495FE4EAA9E5FDF02DFB4D +:10B3A00046FAE699FA3DDD72AB2F999FF5A654F463 +:10B3B00053A493928AFF7DF4F38E2D79FCF2726789 +:10B3C000650DF0018924F7E71AA921BFA5344FDFE5 +:10B3D000BE13F4E9494FE1E7519AFBA833BC1CE8DE +:10B3E000E20E511B3F4FE8DF7F0EB03F1B664D7FE3 +:10B3F0007724F80BABA7BF6B437B08DB23605716A2 +:10B40000F0B808F46F0C437D90785EBAC35590F4A1 +:10B410003C767D43DD4468973874A29AE3E008B334 +:10B42000A3FE9330BF97311FC51656E15E9A229056 +:10B430006AA0739B1C6E817BBCB640E604DD84D79A +:10B44000888BF9BF9CC78FB714D0FACEF75E5461D2 +:10B45000D076DA0FF8D71C39F22766FFB42D93C5E2 +:10B46000279222D3F742884FA0B0659F4FC73BC8B1 +:10B470003EF5A702C383EEB5333F0FD125D07BD76E +:10B480003B89F187F6F7EF8D3810B989E5FB8DEC34 +:10B490002696CFFD972B6B987F32715DAF3FBCA195 +:10B4A0001BEC99EB0F0FC3FB74D77B46BF07E70B71 +:10B4B0003F051F3ED0BB9FE9E5C47A8F733EFDE791 +:10B4C0000E51B7D175396EEB3DEA86F17E8FBDBF67 +:10B4D00078C36F8FDBDC34FDC32B276D104F7433C3 +:10B4E00004E8D079CD239AC28CE028D69F4FBABC0D +:10B4F0000CEE1A32C76B6E8F6E55A1BD55EC9CF7E2 +:10B5000086DFBE3213D4276D6F3DA437BF48146861 +:10B510007FDE21AD995DBFE3ED1DA6ED89FDEDF563 +:10B52000E391DF2B941D88977E3C39106F069EF0C7 +:10B5300002478505CF686F1878EEC35BDADCABC8CD +:10B54000F8D4FC72BD67D47BEC7E221B57229E3F51 +:10B55000832CCA6FCFB8422F03DFEC75857E03E9D9 +:10B5600032476F9E5C88F70F5F05BE5C2185F3B3A1 +:10B5700046E0BDC4D143E05D98EEE4E7AB897CFAD8 +:10B5800026F00BC475F338CB9BF8FC8E7DFFB41707 +:10B59000E3289F78350FD2E552CF96EF02BFFD52D8 +:10B5A00042FBFB9343A3078D477B93FB3BCEBA8CB7 +:10B5B0007759D8FC6EE676DCCD87DC517847F3E628 +:10B5C0007AC962FFDE5CCFE23888DC3DFE3A8B1D33 +:10B5D000D9C4E31D06B603FBCEC4768CF91DCDCBD2 +:10B5E0001E07FBC3FB27291AF81F8EBCF8C9EF6B97 +:10B5F00029ECCA75E0B9EC163FA7DF4A11D7FD7EEA +:10B600007FC85D0A7EA74DE9419DCE73D3B3A44B9D +:10B61000A4F8393AE6F628C4216E9D2EA2CF6A5BC3 +:10B62000FC814815D42B61EF15A9DC1EDDD67DB257 +:10B630000DE8F1F46B76F4F73BBD128E6393AD3AEF +:10B640000FECF7F73A94A4EFE39DF7C82C8E58E877 +:10B65000C178B7F924E200B971A87BCE50188F2FBA +:10B66000485420FFD3ED92C8EC64C3CF1193999F47 +:10B670005D97191CE2A9EA34C7AB6D9C3503E32939 +:10B6800016B4BE84F7297DE5C9DF87BAC4CDEED9EB +:10B690007ABBD3AF04FC7A6788F8B69137D82B40D1 +:10B6A000BDFCEE2A05EB478441EBE7AF51AF04BC8C +:10B6B000427D90FFF917597FB49BC53B6DE7FBE4D2 +:10B6C0000E5BB079066DA7638B5F80F530CA85DCB1 +:10B6D000CC9E393DC3F0DFB0B8F6BC22D509EFA44B +:10B6E000E48590B989B73C82F1B77BA01CF36F2247 +:10B6F0001E3AC63C1983F3E34DA01B609D6D8C9EE2 +:10B70000366D11D09F49F1970DFAE2BDBBEDDF8494 +:10B7100079E4B7082AECBD699A74DCF51E07A3F337 +:10B72000D67B701F08EE516837AFFD37382E6F8A11 +:10B73000F9EEF130FA78EF02F491E1667E9BBCFA03 +:10B740006EBE4F8AE13B8911C013C0A172F63EA1C3 +:10B750001CD2CC7128FDFCC3F661749E2138DFAA8F +:10B7600099AC44C10F20B674E07BC0F32376720518 +:10B770009D5FABD01D027ED12789FC1DAED09B8082 +:10B78000A7ADDB87623CDB06319487FE9D7F55F0D9 +:10B790007CEC68E8937BE13DDDDD9315E48BA32130 +:10B7A00076BFF5FE35851DB00FF7D657E13BBF518B +:10B7B0005541C9D2584E5E180DE7836B4455A0E53C +:10B7C00023D5C63D0315EF314C903EBDB218CECF08 +:10B7D0008689E04B22A705F63EC8FA35552AACEB20 +:10B7E0007A355330EF5BEE7033FDF2B2BFFA0E37AD +:10B7F000C563E0AE1D2A35E3297F668C037FA1DE99 +:10B80000A268C63D7178572483AF4B46B7185BE4F6 +:10B8100043D8B3986E91B74D637ECA1F5C1566FE20 +:10B82000453893AC40FF22FF0BE0BA667268D358EC +:10B8300017023BD72DC2F2D04E166D27A35C8C5554 +:10B84000D076F7F843BB519FCC74209E88DCD3069A +:10B85000788ACECC0E425CEB8E29A35E82FB551912 +:10B86000277AE7801E8DE6BAFED001726ABDA2017A +:10B870009F67AC3975237CF7077F782BA4194DBFE0 +:10B88000BB13F481BFE74F0DF87D9662F1EF65BC05 +:10B89000FEC197909F51AD58FC84BDFEEA5D809734 +:10B8A000DD2591488DC6BE87B2FAE771606DF72C31 +:10B8B00078F7FAF43562700FCFC779ED54A39B186F +:10B8C000DECA41AF1978DB206A5DF02EB37EB50386 +:10B8D000E9A38874A3BC1A06A7C8234CF4FAFAC6D5 +:10B8E00055102791389E1F73BE853F785F12D60A88 +:10B8F000E25194612CAEFE60597700ECF82DFEE425 +:10B90000F109673DACBE3DC53DF5331E460F201223 +:10B91000DBCA300D9542EA217A1AA4398E10C4C7C9 +:10B920001E14B53F229DEF9034581F286FA3EB776C +:10B93000E48533E81F3C12F90DA6CF7B8A8DF662B1 +:10B9400059F03E6EF9493C1FD9AA321AA96D61F22D +:10B95000A236D0E380F38ADA12A2EEE1F4A61B78D5 +:10B96000067F17D75735D731BC6696103C6F059FB9 +:10B9700018BC579605E528FE325BD6AEC27524DDAD +:10B98000FA085A6E2BB40BEBD32412D66E8F03F940 +:10B990003722E17923E5F75FC379624DEB503C6FC5 +:10B9A000876BEAD05E3AEF379DB7D741DB01FFDF07 +:10B9B000E91609EFB140D80BC0DA1A4ACB489FBD4F +:10B9C00095C5B45DAD5C5537197460C831CA1A0BA2 +:10B9D000A8BE00BC2DD0F555407F271DEA0B300EC8 +:10B9E000F74EBB06F35FB0F3A93BC06E71077A5AFE +:10B9F000403ED44E66E34D6FA5DFD1BED17E0DE54E +:10BA00006B5BED1AEB8FE3AF9CD319C7C3423EEEDD +:10BA100085ED6CDCAEDC6804E8B3760DC52BE485FF +:10BA200019DD834BF3BC887C7502E6EFD5B3B0DD3E +:10BA3000217313F82281FE8C79D5F079D5AC61F3AE +:10BA4000229C9FE8B062D06E4D399BE702C2EA8B20 +:10BA5000F09DB6BF90CFA7467F12D3852D764BFBC6 +:10BA6000BB8BF776E37DB612451310CFEC9DCC3C33 +:10BA70003EAFBC26D65F5EC993882F526F1A2FFA4D +:10BA8000454D30E5ABD3CF53C6A276AE90E74062CA +:10BA90003AF97D05CF518A765AE7757AE3E8075A75 +:10BAA000C1FF79B782E71507C5E09BF9B80F553498 +:10BAB000267F82BF990D727A615310E4F8814A861D +:10BAC000FFD3DF2251A0879127AAD301DF234F8420 +:10BAD000795A87E7D81421429FDCA3E3A35BA7161A +:10BAE00001E4657CC48F16831CA0EB0CF660AE7974 +:10BAF000DC747C192D59551087943939BD4AC1A77A +:10BB00007F13F24FEC9A03EFD8661EDF752BF433E8 +:10BB10008C98E643F3477947B0FB57C7692E94AB3F +:10BB20003F7517AC472B7F8F7E248C2C1DD3E39061 +:10BB30006650FEDE9C0EE394C98CB27E79B0EFEEC7 +:10BB40008A092057F0EE4819A6315236506E98CA2D +:10BB50008FE1E5752149B952AF66D997EFBBFBF28A +:10BB600031B07FDF0A76621ABCE7A77E0AF1317A2C +:10BB70005044BC6FB5C51C2599F05EB848C07ED94D +:10BB800056FC3B11F86EEB211204FAC8A8FEABDD9F +:10BB9000BC8EB51E3FCE5B56C866E0FFA3634ECD9C +:10BBA00082758A1E11F13D89AA5F7876B9C11EFAA5 +:10BBB0003D8B3FE978BE0EF5F7ED794AD2F79AC989 +:10BBC00005ECC4C4F2E923E7A01F2F7FE7767C17BA +:10BBD000B676961CBC8296CEDC595909768C564DA9 +:10BBE000A96B281D77FB84B5C084DA6C765EA5CD81 +:10BBF00062DFB5192CDDDCB07822ECDB239DB2B31B +:10BC0000888E77EC46F66EDDE6924F1C616A979659 +:10BC1000573EE6F816FDFE6E39D582F4FBBBD33EE7 +:10BC200071C2F9CCFDE5551980CF432D56BB8EC0AE +:10BC3000A36A741F546A8F84BC745CADBF25884F9F +:10BC4000C91E6BABA1B0F494072C9C01FB9B8DAD7E +:10BC50001D73814E17146378F280F97ECEF5C9FC0E +:10BC6000FADE59705FA94027EC1C35720F0AE58592 +:10BC70005C6414E8DD2874BC3BD9FE2422879E0353 +:10BC8000B91C29092B50C59067AD236B1E0479F6AA +:10BC900025B7EB48DD62BC0789FC2F813DD45B9959 +:10BCA0006CDF749DDB857475BAFDDA57C13FBDA0AA +:10BCB0009ED9FBF9ED9F0AB81ED4EE1B46DBCF2FB1 +:10BCC000C7A72AC98235114729AC4F9148340DC600 +:10BCD000D345609F10A1FAC78C07A3DDBFB5FE76E0 +:10BCE0008F1DEB5F079BE749FDF3F1F0F9E405E9F0 +:10BCF0007C92E8E939BCDFEFDDF7E9912980FF3577 +:10BD00006C8B941F795B7098C691AF5FDC38AE8501 +:10BD1000F6283E1FF1B07B0BDEF21EBC679428DFD5 +:10BD2000C19C07BEDDED3E3B81EDEFADF27400CC72 +:10BD3000E92AF17B5E82BC2AB577E13DD0D603ECDF +:10BD40005D74D87943BE40448DBD171B35DE2FAFDF +:10BD5000837263BD1E15E8A075CCEFCA003F5BB8C7 +:10BD6000BDB0B084E07E75614E37DA0BF39BB8BD91 +:10BD700020079B41C8BADBFD6493C97E405309B6D6 +:10BD8000D04DDC5E30F43FD7DBB581EE16D4AB4D41 +:10BD9000EC7E6A9F9DA133BD9A1F607ABDB685F681 +:10BDA000A37162AE30DB254C8F6B3BB9FDC0F570E3 +:10BDB00006EF37B385E9AB0CB0237C107EA0A35E01 +:10BDC000C6B3BCAC7EBB654809D39719AD0751AF6C +:10BDD0007583D36508C80DA62F735F7A45073405B0 +:10BDE000E8E7362AA77FEA667234A052FB2CBDDF53 +:10BDF0003EDB20F27326C2EC438CADA7E37C9CB7FC +:10BE0000677CDFCBC777F078FA3741BEEE8B144EF4 +:10BE1000904C7C6BDCDBCA2B67E7F479F5EC9CDAA1 +:10BE20001B5CF4A0643A7F68F1B077AE5A0CBAAAF2 +:10BE30008F05A05DBC4788725C41BFDA4678170A5F +:10BE4000E885EFAF6E70F3778D38FDA4D227861C9E +:10BE5000F29290AF84E2F7DDE88328AF75BA5F8293 +:10BE6000B9BD1B69CC5E02FC1EB9A61CC6BF75CA53 +:10BE7000E71877919F62BF78DED8677E45B9EE9D5F +:10BE8000F50ADB87768B49EFC94CF3CA389F2E99A8 +:10BE9000B8019FCE087BA7D03959495AFE122F937B +:10BEA0009B2E2F7BA760EB9407F15E634AFD2C135A +:10BEB0005D4AA24F0D7DDB0AEB3C9590999E1B9A43 +:10BEC0007594FBD16A09E52BC17D6784FF5E8C5EAA +:10BED000ACA0DFB0D51671C07A6C2BE7EBAA3A3A6A +:10BEE000E05EFA575E178A0F58E78D21312A14C099 +:10BEF0003A47D552E6D7C177394ED3FDBBF99CE21C +:10BF00004A2FF36775C99A08F189F92D8CBEB64E90 +:10BF100051701C9B266475480566F9CBF0749D9B97 +:10BF2000D1D7A629CF217D5DECF816D5DF39F55D97 +:10BF3000D339E2A97B1F2A043CF7BFCB121AF4FEC7 +:10BF4000C2A2FA97A6EE4D723ED0970FFB280FECD7 +:10BF500003A33798CF59E6F1F55DE0B5FAEF40BE9F +:10BF6000DA707311CD06FFD281E9511FFAEF97B154 +:10BF7000F3DA5BF879ED99BDD7E2BB07A570973688 +:10BF8000C9BA7FD0607D07E2837D0F6533BF46D499 +:10BF9000625FDDF2E04FC6B2776574FE7B1A44CB78 +:10BFA000AC60EF5FA39E7E2EA8DBA5FE77CD8C77DD +:10BFB000D82EF65DB7746A86E1BE8B54639A45EA63 +:10BFC000300D9008A6D9A40BD31CD8E7C2FB6BA4F4 +:10BFD00017538DA82231C9FD421244B88854632AF0 +:10BFE000C3BA65F49F4BC89D0E8CBF80F30BE07BFA +:10BFF000E39CC238DFAFF6D644BC49CE2B567B4318 +:10C00000DBBDA8576228B7E773117EE2C763BBE0C8 +:10C010007ECFEA2DEC7E8921D7715F43DBFF513A59 +:10C02000D303FA0E01E5D73AF7D597211E5B6D1FB2 +:10C0300099CF1B88C35104BF1B63B43B9FFB17E61A +:10C0400073FD07EE6D76FF2E88F77FE6839FC19420 +:10C050004FFAF2D97D6AA31DD13D6DD460E77BA66E +:10C06000FA188F5C9360FF5F506F27C00B12EBFFD5 +:10C07000850E28ABDF0FF7A3CBB43C76CEC4F436E5 +:10C0800025240DEBB5D8DFC67D586466C88C9713A0 +:10C090009CFE0D7DB220C1AF9F982E90395F24B4D5 +:10C0A00043359F1FEECDE0DB2626BE36DEBF357E54 +:10C0B0005FEB96505819C6AA05601D553EEE0869FB +:10C0C000AF1A46D3F70136F9F35FF4857FE735C53C +:10C0D00043A9A13AD1FCFED222CE8733A5D64A90FD +:10C0E0006FA7C32408FB875B48DD56B0C7C82B1277 +:10C0F000CAB7E174DCF0BB3FB970A0918EB0AED08E +:10C10000F4E306762FE754C2FBD51FF277914ADBA2 +:10C11000EEB81AE8E00C7FB7DAE07FA3DFD22EF7A3 +:10C120003CD0FBA55DD36BA15C69A71D7FE7A9F897 +:10C13000D0C66AF00BC13B2D2EDA4F0EEDCF910E1B +:10C140007284A0BEFDB0D5155D47C7F9619B8472AE +:10C15000F95C8988EF8DC07397121F5F5A3AB4F368 +:10C160005F37811D7286CB11E3DDC70F2B35DC1FD6 +:10C170003F7B608300F7123E9CA7E1BC3F1CD69535 +:10C18000974EF193E363F7738AF6DB6385741C4B78 +:10C190001EF97D610DC8BFC2C89264E7CC437C4CD8 +:10C1A000FE7DF804C178B80F9DFC778D1C5D3EB311 +:10C1B0009F35CD2758E4D6875EFEFB48391728C740 +:10C1C000E3CB89A7CBC7F8BECB07E751F7B87F8C85 +:10C1D000F7D74E3DC1CE299EBDB7360FFC51C37D6A +:10C1E0001A3BF73EF038C68DC33C601F4DC7A7C150 +:10C1F000F8EE71BF7906FC0FB41EDECF30EA9D3A2F +:10C2000050CBCAB7D1F23EC43BF195013D30BC934F +:10C21000FD4C4E18F6E3D26816FEEE427FBE88F95A +:10C22000304427C57FE9FE6BF05CABD497CEE8596C +:10C23000ED1A3B07C71FC983791C981ECE033FDE4A +:10C2400029E377A0E4481EE0A1DA1B2EF599E6FF6A +:10C25000C1DB4FA17C2F16EBDEBA0BE8F231F63BC7 +:10C260002477BCBE5D34CB8F69F0837893607E2BDE +:10C270007C701E75AAEFBD9C088BF739CCDE635D20 +:10C28000CA79EF5407DD3F517C7CB0FF07987FAA45 +:10C29000EF3D9B2E8C27FB60FFB174486B783C3FD1 +:10C2A000895E8BFC45F1D2E248A2AFFAEE4545D952 +:10C2B0007DB7B3027F87F43E036F75CA1CCB791537 +:10C2C000E3EF9CF682E3682F4793DF934BD4F78923 +:10C2D000EFCA5EE81EF049CEA7EFF277D1567BC3D6 +:10C2E000D7FB505F58F548CDE6E57980E71AB8539B +:10C2F00087710ED3AF80FD36DE3761EFCAC6104FAF +:10C300007DEFC64EBC02E21C4FF9195CE79BBD41B4 +:10C31000E77864EFD256B2FA052CBF95E7FFCA5B07 +:10C32000BD98F54F04F6BB46363FFC3E8521FF52D3 +:10C33000CFDFFAFB14F7834C1E82EDADF60DC16C16 +:10C3400081CDE7EF6BCF90377F773B8E7F6C3B865D +:10C350001C06BE84903D120C8EFD47E0EF6FAD4F82 +:10C36000E6E65BE4F917F78E688673A0730182F145 +:10C37000CFF6D6B504F4D2C29DDB93FEBE5D1FCCD2 +:10C38000E349941194CF4CFC1CF3313B3DC6E521AD +:10C39000FCC1F9CC2842F87B1794A6B230E406F72A +:10C3A0007FA3F97BEFC52482F6D558D2856909E9C8 +:10C3B000C6743CE9C5148F494780AB2F28F1777BC1 +:10C3C0002B60F2CB1CE1FB2154F7AFF6F033404F6A +:10C3D000F07EAF20815DB4622A8CFFA84F357E07C6 +:10C3E0009424FCAE5AFFEF816860D7CC0E0C66D760 +:10C3F0001055FEA82F7EA390BDFFCBF821D5EFC42A +:10C4000025FCFE24BF476CE06139E9C2388867DB50 +:10C4100057BF3086E27FC97E2FEA8351ED4DF83B4E +:10C42000604B487716DC2F1DC5DF93206DEC1D0F88 +:10C43000E39D88316D76CBBB1ECB137E876829FFC9 +:10C44000DDB0A509DF8DFB9B9BE143923882C4FBE5 +:10C450009FA77D29DE612D49FE7B3089F73FF77765 +:10C460008918DFB31AE285847EB937666F9DDD4A8D +:10C470005F5D971599DE7B6A14826C3FED7585F6DA +:10C480000903FB19AB323BEE8020248D23BB268DA4 +:10C49000EF174913B98AB6D3B84C5661BFD918758E +:10C4A000E13968A3CAF685C3BD550ED8A713BFA846 +:10C4B000C2FD94CBA569185FAE2C9727C2B9E7F1EE +:10C4C0003D4BBAE1FE426340463FED703F3B0725DE +:10C4D000C3447C1FA0497DCC3F1FD6C9C3CE19736E +:10C4E0005582BF637AA4E37611E046BA6D190AFD5E +:10C4F00008E16EBC77334C26FCFC75F6044A7FF9E4 +:10C500009C1E64D28AF78F672C7FD7097A3D9FAF34 +:10C51000FB94B4029C87CCD77377FD493FD0E9F3F5 +:10C520001DCD2F5F4EDBB345658C6B2DFEB2F10F39 +:10C5300097D3FE7A3B148C6735F090B746B6DC9FF4 +:10C54000CDB9CD0A2B09F7886562CAA7F038DE3F5E +:10C550003CB81A33C755658698B350F5E0FDE04BFB +:10C56000D304661773B814608A924E5BA4CA45C799 +:10C57000D9F986807E87A31D8BF2314EFF27E17C9F +:10C58000A06F831E12D7EF4BB087908F7427BF1F09 +:10C59000EC84C3BA44FA696A2023C11FED881E7770 +:10C5A0008D83753C61C3F7A4D673FB5BF6B0F87757 +:10C5B000835E12D3F50974B7FECB6B91EE7A29DD59 +:10C5C000257B17CEA827AB1ADA09B61C1204F6B0E1 +:10C5D000657667ABB4DEB8A794A087A2ECF2474BB0 +:10C5E000D2C09E1977EC7AF65E1FC517BEF758AF1A +:10C5F0008C847DBFBD3E73A49C01E53C488F9F7831 +:10C60000D8F98F5CEF0E427E6347454033D1757396 +:10C61000833A521E09EFA53A46C2EF2335A7F89D8B +:10C62000E65CBF580DFE2585EFFF97A4B1F12E49BA +:10C6300073637A0B87EF93F53930FEFB28FD40BC1E +:10C64000C091DB18FDAE1EE6C07BCFAB9F1F3174DF +:10C65000B038A0071B0223016FEDB7D5A0DFA3728E +:10C66000D571E715C0E75E870AF428F946DD330D7A +:10C67000E8FD051BDEFB6AF45668F34DED49BEC9C3 +:10C68000E85792443D1B36450D697FB8421E06F4BB +:10C69000A2EF024DB461DB11067BF56C81E66FDB26 +:10C6A000F62C8387E8BB049A7FCFB6E7199CAB676B +:10C6B000C32F80DCBFED570C1EA9EF02F8A16D2F30 +:10C6C00031186C0B6AC73CBAEDB75780EFA7D1168B +:10C6D0009C0BFE9D1FD3F197D8E0BD5A961EE478BF +:10C6E00031F21F83EF14DF87789A98FF24AFF77435 +:10C6F0008AFC7FE7F98753B4FF335E2F96A2FE5181 +:10C700005EEF788AFACFF17A2752E4BFC0F35F4C2C +:10C71000D1FEAF79BDEE14F55FE6F55E4951FF77C6 +:10C72000BCDE6B29F2FFC0F35F4F68FF4D5EBE8732 +:10C730007FCFF1B6FC41A77497D3C15EF82CF6B653 +:10C74000A0FDDE5E578EF4DF3889D91906BDE740BB +:10C75000BC26C85B95C5558D52D93EEE9769CCDE97 +:10C76000A85C55B40DE86EF5AF24D4A7548FE0EF64 +:10C77000F0EAAB58DCCBEAE7D97D90D5AB647C27F7 +:10C78000CDA047A3BE31FEDD7C7C4D7CBCC7D20A68 +:10C79000F9794B60E46C73BCA76A851D949F206493 +:10C7A000A72993E997E255558ED1A03FA87E01B9FC +:10C7B000B9DEA3C4E01EFD7A55C6FCA6CC2A15F24C +:10C7C000755546FDB33EB3CA311FFD39E9E89FC830 +:10C7D000E7717B4DAA8CF7F865FF0CCCBFFCD1D973 +:10C7E0002AC8D126D2EBAF84F9AD91F1BCF6485DF1 +:10C7F000157ECFF77FE607F9FCAC9FE1FDB8F7396E +:10C8000027BCE72A7F4F447D81F8A3FD16AE11A314 +:10C810001A2D725C5D2D02FC4013D357F4CF3BA15F +:10C8200082C771D0BFCEDB2B5E80F89DC62D721003 +:10C83000CE73E04F36E98322FE7BA54355B66F34B5 +:10C84000F4D57DDC8FAB071C188757249380F977CC +:10C850002C87AAFC3C8DBF63362262D54F052DD6AE +:10C86000776CF213F453A2BECAADA3F2D154DE1E0C +:10C87000502DB0A0B2F72CFE17044CD03900800028 +:10C88000000000001F8B080000000000000BDD7D91 +:10C890000B7854D5D5E83E67CE3C3349669299640F +:10C8A00026CF49801020C0044204449D848011B1E9 +:10C8B0000E0F15D4E2846780BCA0A858E9C7840491 +:10C8C0000C1435FE46047EA003A28516ECD0A2020D +:10C8D000063B2022FEC53658DB8B8FDA11B9883C27 +:10C8E000C747953ED4BBD7DA7B27734E12C5B6F740 +:10C8F000FFEF77D3CF1EF6D98FB3F65A6BAFB5F6ED +:10C900005A6BEF215EE2FD5A47C8E23D8B6FB410CF +:10C9100042C6FFA228395A44C85253D210924CC87A +:10C92000D7F07703214DCBC3D7F7D513B269B9A997 +:10C930009F429F4D5F0E9F464A0889255A7CDB2403 +:10C9400042562DB7F553FA75B51F68A32F9D846C19 +:10C9500056829389833E430A69CC23E4D0129940DE +:10C9600079B1DB1432D2268B5FFBFD4DFDA1BC48B3 +:10C97000F6124F577FEDF399E5AE7EF0FDDF50984C +:10C98000605C7D40EA777A38FDB71270F91309E9E7 +:10C99000D3AA9C8A9A08FE7D4DFFCB6BA1E5C2AE5F +:10C9A000B25EEFB7D9AC84E492B876141E4553D684 +:10C9B0003BDFB4078A607C05C7D7C291DD40E71F23 +:10C9C00037AED165539557490D85A40F7D52580157 +:10C9D0003F41A71C7A9ACE336BE983A34FA71292EB +:10C9E00079D4D20C7825AD4F129246880EBE4DE711 +:10C9F000AD483E0FA17468CE2BF64AF479EC590B82 +:10CA0000C353B615F16490BCE937D3A751F6DB6088 +:10CA10007CFAE783F11FCAB66C5D9307C58009F005 +:10CA200090B5830E98418BC19CD53E85D289A29B3F +:10CA30008C86FA375A7C745E3BA4CE722594C3214F +:10CA4000036B4F4804FE6F8F2CF17AE2535C84EC49 +:10CA500096245E5F54599145DB2BB6418A9790B975 +:10CA6000AD435BF4D741BD2CFAFBC8483A3FF81EF2 +:10CA70002F035E7E7E84D707AF6BA9E84BC737884C +:10CA8000EF9320B4DF23CBAC1C2C6D81F17797F3AF +:10CA9000FE41CF6ADF1884E7669D9D9025B6B216E9 +:10CAA000ABBB0BDE95F61B5B1AE9FC2E7AA2497430 +:10CAB0001AA476EBE93442875A352DE0073C12E29E +:10CAC00025FEC1849C9528724774D14FBFB72C981E +:10CAD000495F5D3EFAB7A422FAACD7458F2650FCD9 +:10CAE000D5EE0B98F4F914CF7A5F3033AFAB5FED2E +:10CAF000DE492440F9A6BEBD189F3DF43BA6C8FF01 +:10CB0000543F93E12ABE7731F246DD2E5A55AB0BE6 +:10CB1000B458FB607BC2E8DFF3FC44FF8BBBDEB89C +:10CB20001DBE77C9134D9B007C19A178E9A19F68B0 +:10CB30005FB7AF8C00DF5FB1F89A6CF4FD5D76B63D +:10CB4000CE88D2E085F66153ABCD4BEBCDFA56BF24 +:10CB500097B6A7A40CC923BB9EAB6C7D713CED7B43 +:10CB6000EDFA099B48EA44CAD7C11AC5FB34817261 +:10CB70003061082DAFAD55863752905614FF71586D +:10CB800011949FB312232D37D51C7115C13AF21A97 +:10CB900008152F64EDA8B01BD67173AD61DA76E08D +:10CBA000DFC862D79CA2AEF157DAF508F7EA57E87A +:10CBB0003A1B4A9FFAB05D82FEFD1402EBD06CA7CF +:10CBC00074A665B33B8504F3A09D752DACC7D5FA5B +:10CBD000406539B473CBE469FA5D73BFA995E51478 +:10CBE0000E975396740847C5C9B9B4BEC96600C943 +:10CBF00046DEB0CFDC0578FAB9E26D8075F873AB2C +:10CC0000D516A4155436FA60DD2AFD1C21281B75A3 +:10CC1000A4214CE1CB2C26FEB0B50BCE376094118D +:10CC2000F03420BC6BCDE14965741CCB62D916A4ED +:10CC3000DF5B5DBBAE633CFDCE7FD63E7FA291BE87 +:10CC40005F93A61080C3EA50228624CAC7B7501843 +:10CC500029DCBB1BFD36909F31A742B6D17A4B5FD2 +:10CC600003F1C4C9416B112DC7C9A75487E233D35F +:10CC7000FE317BE0651BFDEEF0D7DF34417FD70846 +:10CC80005986651356189D934AD4E3D8C6A8C74958 +:10CC9000A950D73B26AAEBD3A6AAEB5D77ABCB195D +:10CCA000B3D5E58982DFA8CCB196D279B02A628962 +:10CCB0007EBC9C24217EDE02FC5B0A642FE0C75C04 +:10CCC000BBFDEC5C5A9F09F284C24F8690D0D3948E +:10CCD0009E87737EE889523C1B531A3CF6A2EEF8FD +:10CCE000C8CC36DD0CF4B2F6556C84B6B7BEFBD1B9 +:10CCF0009730BE95C4B5CB03FCF84E037DE1CF451C +:10CD0000E149847F7800DF0D7FFE11E8BD133A2FE3 +:10CD1000E03BB356C1EF3F3CD513D2E5B1E684B654 +:10CD20004FE2ED934C6B3B7443E8F3DDD58B7449D4 +:10CD3000DDF19A461A245897943F505F902A82FA60 +:10CD4000E221995403DFD0E54A603C1B74A072E6EF +:10CD5000C61403F2CDDFB97EA59C26437D9A8D8D46 +:10CD60006970CF36C37A5E7994F1FF4A031BA773CB +:10CD70003C0F7E145510C849A35DC6F1C438EB6C56 +:10CD8000BC0D2F3BEDACBCE748CACDB02ED74D4D06 +:10CD900019067C62944900C64BCE32F906D0F99947 +:10CDA0005F3304253A68B2428EE853687B0BB9C7FB +:10CDB0004FE1D870CC12D4D1F7E639FF61A34826F1 +:10CDC000857606F79E15DEDF831C8855298847B3D4 +:10CDD000B3D536AC88CD2148E14B817F50F958D688 +:10CDE000AFCD06F43497B5A2FE3617B7B6029E361D +:10CDF0004C94D19E48992D233F9BB3C327FAD2F779 +:10CE0000FA39B20DC64BA18ADD4007793CABD5EFAC +:10CE1000877129CEE552C62A302ECE907E2795E323 +:10CE2000D5E1D87BBF44C74985F186B0F680273B62 +:10CE3000C793D7EE41B81D7CDCD4BEB4FD10364E8E +:10CE40007369D738828E1B2A4908E013DF15E37413 +:10CE50008E4F7C12C855FD6F28DE289DA41C13023E +:10CE6000B772010919F3003FFE86ADB8AEAD641B81 +:10CE7000AC17475639F051C6B18D93E521D0CF821A +:10CE8000DFD1CF2121E0E30C8598AE4F01FBC58FA8 +:10CE900078D4AE57F791D629748D74D245BB7EDD18 +:10CEA0000A69D1A5745FC76E87A3BC60480FEB59B0 +:10CEB000B35EDCC762F702D36BD7F596844BC580AF +:10CEC0001712DF5EF7ED659D2E7C623C102B9DEA0C +:10CED000098AFA1CCDF708F9CA086589C89EAFFB14 +:10CEE00080DCB7F3F540F5155DAC7B86D9C65A6199 +:10CEF0009D2E22C85FE52FACBDF33774BCCFFB1964 +:10CF00006CA057B28FB576807E24FB02FD810E9B0C +:10CF100094C04F1268FDA693E904E4F66A339906BB +:10CF2000FCAD703ED7EA97957CDD7840CFB9FEF92D +:10CF3000A7B007C37DD306D9E8DA5BF9D8E1632649 +:10CF4000E77FA39D45FAA39D9575A4A3D10ADF6F42 +:10CF50002D6F3151FC9A5F67ED9B6939A800FE6A1D +:10CF600072611D1ECE9E8B7852DE3612E0D3C13A1E +:10CF70005F08CAE41D3301F9BBE3B9BBAB3D207FB9 +:10CF8000D22678400EADE3EBBDCD2EF5882FC5E05F +:10CF90000B803DA17DFF08E017E9E93F5B45E938DB +:10CFA000F8290359432B0BE5992D79B02E5653F9E7 +:10CFB0004B6B67EA3C753F96BAE8F30B73D9763B47 +:10CFC000EC3B969B48C048E775452201BA38B31D33 +:10CFD0006F9481FCC9211109F46C4E03357881AF3F +:10CFE000965848208EDFB3AE28D8FE1766DF763B12 +:10CFF00097FF262A07F4EC9FE4E7297E52E560328A +:10D000000AEC17FD2ECBFB203788A3C2D7B9DFC8A7 +:10D0100007FEA57A9F7E6F0F9FBF9EE2503F8CFE5A +:10D02000679523C621DDDB3FCFF1A398AC11909724 +:10D030008AF5F849942F36E5427C3B5388E91B5228 +:10D040004342FD2486172CFFC086E54C2A7F8DC302 +:10D05000D0EE0F1A01CE24B6FF203E9FC79106EBFB +:10D06000852092B34CA4C544DB21B7D3F5E6261D39 +:10D0700066B49B8F100FAC078A31FB9904145904D6 +:10D08000F0BA8990CAF875209E0536462765A90E24 +:10D09000F74B835E36233CFA061232833D04B051CF +:10D0A0007C2B4B484881FDD65203B62BB079B09FFC +:10D0B0008134A03DBBFBCBF732404E5B8E527B6C84 +:10D0C00028D059463965B1A8D71F218D88A7D39C90 +:10D0D0003F362FB7219D3BF7678137399DA38DA040 +:10D0E0002F7296A4A8E82BDA655DC92481E1F1E3EB +:10D0F0008670DCACBE47245204F53958BF79B9E7D5 +:10D100005BC6CFEF657C37F251EFE36761FDE6C8A0 +:10D110009BF6EF51546C8A1DB1FB3D5DF6B516CF01 +:10D12000594BD47279E83E7559E0C5ACF7392651B0 +:10D130009C9BEF95BD5BE978D79C54B7ABCCFB03C8 +:10D14000EE6FBBDA471C53A03DDD7F6FA56FAF3D8F +:10D15000AB6EEF2F7BC50EEBB8AB3D83EF862BEAB2 +:10D16000765AFA68E1A570396F8B836BACC9A8AAAF +:10D170009F56D50D2EE71D7170DDE852B70F34F6BE +:10D180000CD7CD85C66F844BB4BB75E4D5B5D3CE73 +:10D19000634AA5B117BCB3F6774CBBBA71EFAAFED0 +:10D1A000E676F72CD57E2788FC7EB3E4BB26853E49 +:10D1B00067C22BB017AD16B47BB5FCB29DEBA7EBE5 +:10D1C000C19EA34F7FA2EF7AE83706D61D2D1B76AE +:10D1D000FEF14E902FC79E1D980E723D13F41CE277 +:10D1E00093F915F6D4B8D0AF3095AF53AA4F9A4102 +:10D1F0005EECD941FB2531B8E2EDA7D41AB6AFB049 +:10D200009118AE67612FA5109BC4F6E3CCDEE9ED63 +:10D210003BDAF11BED0CEE594BC7920FE83A7CDE7E +:10D22000602B53607FB645427B6056854F9748F927 +:10D2300063748B847EA3590FFC6038C89551A73D59 +:10D24000FBA2F4FDAC90DD0B9FADEB20BE10E5AB77 +:10D2500074DDA2E21FD1E71387A9FDC3CB8B80DF6A +:10D26000AC3E0FEC37AA00223ACE057D43B10DE467 +:10D27000E6F7AD3E909B55537D6FE17CFF41AD12CB +:10D28000DA6E0E9B3A79A16D92C143ED8CAABB3D3B +:10D2900023C1EEA90A9B7DF83411C542E75145ED43 +:10D2A0003178A61B886286A78598E059BA82D95F33 +:10D2B0004923FD862AFAFDAAF69FFE05FACD5322E0 +:10D2C00087983D19C27957B5BFF657B0D7E6F8FC35 +:10D2D000069017837618984DCAF96170585D0679E3 +:10D2E000105F2E8EA8CBC38FA9CB7F4A61F83D205B +:10D2F0008506017D0E500507FBE2E06E23EA8BC335 +:10D30000078D489F85E72D5BC1FF3476A115E5FAAF +:10D31000F99F99D11F75400E3F0BE5E0B309B8AFF7 +:10D320003EF4F68152899617FC225186FA17BFD433 +:10D33000219E613A7AFA7EE1B303B6AEA1EF170EF1 +:10D340000F97DAE8FBE70712D201F54A6808CCEF3D +:10D35000F9AF74387E6CA731B48DF2C3F9FD3F7D0F +:10D36000F641FAFDF33B3353244A976B411FD076C5 +:10D37000A39F3259609F31FAFCAE3E202F16EE304B +:10D38000AAE6B53545E2FB194F12F05B6FFEC453B8 +:10D39000AB7F8AFD0BCF9E447E3BA00FCA1698FF41 +:10D3A0006AC65FDAF63B52D87A127040BF3C4A9F99 +:10D3B000CB1F59EE013F5AFFF56AFC0E08A9CB615D +:10D3C0000ED74C12F73E0FC6CB5FE5023B752B41E3 +:10D3D0007BA6F0ECBB77E6811D6D64F683168EFDAF +:10D3E0001C8E9FFD8C8EC3E4838ED9CF74C6743D92 +:10D3F0002EE47CFCA2C4EC57FAB72493F2ED425021 +:10D40000FCF95DEF176AE010E3DFCBC777F07D75BD +:10D41000EC751DD2E3DCF2EAE1A7FB7587E7CCF2FD +:10D42000860115FAAEF2DCF58B8EBA69BF9A3D4ED5 +:10D43000DC278AF7353B5F4EBB8BBEBFB043F18222 +:10D44000E95A33FD99474643BB9DBA30C00BF53EC0 +:10D450003ADF0BE15792A0DDDC4DF661BA383ACCE9 +:10D460005B7FEF808A3879F85DD78358BF357C7F42 +:10D47000FBC2C88EF199C0DFEB252F345B18BE6D5F +:10D48000CA2D60AB6CD279FBD1FA5285F875C370A6 +:10D49000EB3D159E357B9E3B9A41EBEB0F8E28852D +:10D4A00079AD91FD370F06FEDFA2473F96162F9FFD +:10D4B000707AD3FE1199F65F73BBB53A64C5718F6C +:10D4C00040F970E1361DF8D993CE52F9C4DE9F942D +:10D4D000E99A3CDBBE7208F8130FE8AD2DC0E707F0 +:10D4E00012191D82BB7528E74984CD6334F71B2FC1 +:10D4F000FC539B41A1CFB367572495B17584F205C6 +:10D5000084B283CEAFFAA9C1B8EEE6AD57AF13D15E +:10D510004EC03B3FA4AED7F2474AAA5857A4309E0C +:10D52000CFB4ED5227060DB0AE6A9652791C67FF54 +:10D53000D49C6E3580DDA4FD0E588044D05587FC08 +:10D54000493C385F339B2F35594D74BEE7E05FCCC3 +:10D55000EF2DC1BE7C818453240B07920A0FC5E7CF +:10D56000C2C9A4129E07A4C8233A2ECFD0FFBE3B47 +:10D5700001E5D9055BF499FF04FEDB95ED0DD2AA18 +:10D580000CEE97BBE08924A5D0E7655817C07F361D +:10D59000565ED04EE5395DDFE72F1A50AE37865F15 +:10D5A0004E027A5D78D62CCB942EE7F7A496833F73 +:10D5B000E742F8374930AF73E1D472F0CBF5266F0C +:10D5C000B4724AE8F3F7E19FA3A89D96EA1B960A76 +:10D5D000FB9DE65430C6497A6A4371430FEB5FF412 +:10D5E00073181A8A3D2037BE6FF5C2FABC21D5C325 +:10D5F000F486C4C6833F1FADFFE458EA36A0FFB1EE +:10D600004305C9A0E73F219E6490BFB739FDE5A956 +:10D61000B4BDABBCC3A703FFDF04E26DA27D3ED067 +:10D6200079EFB3513CCF2654EFC0B32460407F491B +:10D63000B313E19AA5908842F97416E8C5215846BB +:10D640003CCFDA24859A281CB3D7AAE739B7CDD8BE +:10D65000455FFADF7C4205232CA04D71EDE8F8F31D +:10D6600041FF51FC2D309148021D77C17675BF8571 +:10D670002482F0D4ECFADAD8131EFFC2F1789BD3DF +:10D680007757AA4A7EE9517E2D24FEEBE1BB0BB908 +:10D690009E9D633C8470D43FF0C080D9D46EB8BCEA +:10D6A000F4C101B353C10FC8FA91F512F2DFC20AF7 +:10D6B00012C9A6702D6C972283C10E7893D1478C26 +:10D6C0004FB6B07677723B650EC507E8FDD1BBA4B7 +:10D6D0006022DDC7CC31D12D18C80F3E2FA84FA630 +:10D6E000E56AD28AF3A9255184E37E4E3F8848013A +:10D6F0003EFFF226A3DBE8EAAD3A00EAD8A1528C5D +:10D70000CB7D4ABC483F6A4F10734A77FE007CFBD2 +:10D71000E2F053BD495D26DBE3CAF9804F5A8EC360 +:10D7200073DDDEAF8DBE1EF0FB44A73E090D9834BD +:10D730009874B357DFE3F87FE2B6B96E58FF8F8273 +:10D74000FD96C1071809F292087F44C444C7B70C7C +:10D75000272AFF04B58BB0DCF6F86B37ADCF226417 +:10D760009D3E807EFE593AFF5108497DE60CAC078C +:10D77000BACE927D390ACA015F01EE5397327A3CE4 +:10D7800039AC6140430FFB5301FF3A291C91411E04 +:10D79000EC67FA3DB124A60FC4ADAF5F72F9967C79 +:10D7A000387A3413F8E63909FDE91B24D22C513CB0 +:10D7B000BB2859400F6C90DE3F0A7A63C34D1ED2DE +:10D7C00044EB4BF64E5AF40AEE712D5E884FD4EEC0 +:10D7D0002DD3D55A71FECCCE4C68D82AD3FAF47B1F +:10D7E0000A87C1FAA0F3BE67327DFF02A7B7DBCA82 +:10D7F000F8C1B52298B718FCA987FD8B5E81753DED +:10D80000D8827EAB748AABC4147CB680FDE8228DCE +:10D8100012B45BE594901EABAAC8B45F1621D7285A +:10D82000C929EC79923E258534831F365DA1F628FF +:10D830007BDF0CDF792289C1E59475F74C027B7898 +:10D84000182BA72C937CDB90F91F437CA51B492543 +:10D85000CC1BDE83FD4CC1F0EDC1FA10C29D3EB67B +:10D86000A118E048EFC39E0E43240BC6392EF8A43E +:10D87000DD2D839C5EC2F5ED923D65E929B4FFF193 +:10D880000B2605E4E77197B0FF2256B0FF48DF4250 +:10D89000D69EEBB525C563D381EF1D39EA7697F5A2 +:10D8A000BEE4E1A01F4EE8304EF399D5976CA7ED8A +:10D8B000AE35B07968E97F96D3B5FE8A444271FBF4 +:10D8C000FDFA699FA35D5D7F4551BDBFB0DC444259 +:10D8D00071FBFD9AEAC3E3A15D2DE95805FC581BD5 +:10D8E0004E20A1B8F571ADA5E7EF8A75517F454788 +:10D8F00082C391EDB3C02F795C1F5B3507F8F0A0B0 +:10D9000084FEA37ABA8F0EC6C375259504537B8215 +:10D91000334DFD9ECE4755DEF705B62323A349F0D0 +:10D920009D4BB668929DCF0FDA097D77392407F5B4 +:10D9300043312EC8F41EF875ACCCAE9D04F455628C +:10D94000499313BBC615F5305E4ADC3C2F4D33902E +:10D9500008D22586DF05BC05FB13B2B1FD63830742 +:10D96000F47FFB21C49BE09778FC05E3E3444D1D65 +:10D970001199CA8A7C876D4DD100CA7A87855C4827 +:10D9800059037EC9349DAC921309259D7203C5D4F9 +:10D990001310B5423993BAA6624C7C99B5EFEAEF01 +:10D9A00098007ECF9222D6BFC8E1FCAF157DE17D05 +:10D9B0002B93BB4A2CC79F18573669CA565A1E1C50 +:10D9C00057B669EA1D9A7A97A69CC5DA5F488CE437 +:10D9D000E8BC54DF3BDC13142A2F2FB82333E80EA6 +:10D9E00096AC6DCA9C5041E5586D09D3C775ED9250 +:10D9F000177D751C7F755E66275ABD51C3AC22C06A +:10DA000043C751902B35FB249B44D78135BC2782DB +:10DA100065E8E789EB1796B05F4DF87DECD7EBF83A +:10DA20008532AEF33585A758BBF087A8F757355731 +:10DA3000613C5DC48B75C4EFCB94BAE2C542BE5E57 +:10DA400072FB5E96195FDBE2F74FF5306E9C9F46E6 +:10DA5000B47F6770FB1FC0AC4858F27123D8AF7F0A +:10DA6000AAFD7004D873EF40935120AF4303E0BB8D +:10DA70001B496000E8C9EFD7F63B24D376EFE9A352 +:10DA80009B2126769FA318F1F75E62345BA2326673 +:10DA900069DBB5ACEC8C6E067CFEB66D0C2B674773 +:10DAA000B3655A5EE698C7CAFDA29BA1BCBD6DF2E4 +:10DAB0000485E2FBBDC1D16C1DED9F1F9C32A1828C +:10DAC000D63F6DEB793DD73A981C11F0FD57BEAFAC +:10DAD000DA01F3A961FA6733B5374D545ECE587059 +:10DAE0006EF7D3140F337E988072ECE90B53263017 +:10DAF0007B3CE8574AC1DFCAFE503FA29C57D03E4C +:10DB000071834E4CE9A247624E8707F5C7C0863D38 +:10DB10006067A4CF2842FDE14DF5FD0EBE2B9EF7B8 +:10DB200067B0E7EF1C3626B77532C69FD31F4C444B +:10DB30007BEC51339B0F5D37485F2BA7C70A07F378 +:10DB40004BAF70303FEAF4D47138CEDB926F8389EB +:10DB5000E2FD6D3D099A41CECEB7A0FD7CD7562A95 +:10DB60003792C18FCFE06E7BCC1D82F8F95D12F148 +:10DB7000835C11F2A3CDEE73A7C4ED43DA8A69D9B1 +:10DB8000DAB5EF6C9BE4735B1CF04C9321CE22E47E +:10DB9000525B1EEB27F4517A13FB4EFAA303B6C176 +:10DBA0003C1214E62F9A33AD605B23DA03937FE7D0 +:10DBB000007BD9E77383DFE1F4FC7C19FC48823EEB +:10DBC000E7F37D9BA0FE4EEE87177412F4FC1D9FB9 +:10DBD000F72C1DB527E87C8F3B03381EB52F8670C8 +:10DBE0007F15DA17BF03DD1E875FA24447C0FBFF26 +:10DBF0008FF07408E8FEAFE2A976299517F255C8B0 +:10DC00000B8EBF7552449FCEE405EE9FE13DE89D2B +:10DC1000CDA9813FC0F8E2FB331EAC457B52C095D5 +:10DC200070FF0B957790EEEB4C6BEFFD19E81567E5 +:10DC3000977A85DF917FE7BDB74D186778CF10469B +:10DC4000B9F91EDDFF34827CE171F2D21F2E3C0E49 +:10DC5000FB3F31EE38A70EC75B2DF9DC30BFD59402 +:10DC6000EE26807F9201ED7FA157DBECA10D90A7FE +:10DC7000D0765B16E6295C262C1F24B83401DB5DC8 +:10DC80002B9F22E0C78C8DB2619C9AF209D6B74DCA +:10DC90002FC07C11CA0F4133D4537E82BCBAB66206 +:10DCA0003A21186FFA40AC87FD31EE6BA79B70BC30 +:10DCB0001EF884F985FBB37C88B63CCE87F3F391DC +:10DCC0000FD39A98FF9128BE2193E2F47C9E93F99A +:10DCD0007D124AA2CFFD2FE0F9B566B46741C76255 +:10DCE0000CA7351DC7A3F4B738991F00F96CF623AC +:10DCF000893CFFCC5B0A787D2891F1E526338B2F98 +:10DD00006DA2F633CA45CEBF22EF2DC0EDBC68B57B +:10DD10009C04F682CBD9E95FF0C17E1FFDDBB47EA7 +:10DD200066547A1FF66B3383BA8811F65F2DE37C55 +:10DD3000D1B8FD0BFC417CEE1E2E57C97A827EBF06 +:10DD40007BA05F128C6F498278E43DD01FFCABCB87 +:10DD5000C6A9E26E039D6C7D0BF8B4727FA093C9D7 +:10DD6000490AB72FFE3B627CED7874FF39C8E9445D +:10DD70003C4792611FD1A8433A6AE18CAE677EEAC4 +:10DD8000E8FA5CE43B315E6F70FE5917BB57A27A2C +:10DD900070EE58B62F17FB9E397CDF4C96A9F775AD +:10DDA000E057E92CEBBA97B5FB4488A7ABDB33BB54 +:10DDB00025A12866C0388B4752C12FF0D51B1E26DF +:10DDC0007D47BC09BDF7A499CAD314D87E4BC8B708 +:10DDD000EB1F48403DE6308406005FDDEDF460BB9C +:10DDE0008D90D7827A95ED973F3D2EFC1CEA7D728F +:10DDF000BD25B605F0556F61EBE8D2C1445C07A4C0 +:10DE00006F7406E4855D3E6024C0BF7552B400D6D1 +:10DE1000F525C95785ED1A133CB09E3E903B10DFA7 +:10DE2000F580410A577DF0EF988F54BF4FBD6FBE0C +:10DE300044FFABA6FC7E498E96C238421EC0FA470C +:10DE4000BBA89AC569EA6412847DD5B5F2CCF9A85D +:10DE5000FFA767906DF8FEFD02D84709394FDB1D1B +:10DE6000915218DBC07AA9E1F8AB934F61BB1AC895 +:10DE70002B023CC2FE0AFC615019E7C7AD5B7B1E5A +:10DE8000F39AEAF6AAE95CD3C507D2D712F48BE37A +:10DE90000B5CC741A41BDAD9B0EE2B589C39919783 +:10DEA000132A3B30CFA99EFB3B9C87A3E3419E24D2 +:10DEB0009684C94CFAAC3FCBEC8CD1ED5B5F867D90 +:10DEC000B4BDB2231BD8BF9EFB03059D059CA3DAFE +:10DED0001F43FF86B04FE2F6990326ABFC0C2BB034 +:10DEE0001FEC5BE17B5178E506F233BDB68EEBB5F6 +:10DEF00004D80083FE6BED8FFA0FF413C825B1EF41 +:10DF0000053905F2E13367F94F418EAD4D2BDFC680 +:10DF1000E419E52FB0E761B334AA773F9EC08F685C +:10DF200007FBDF6FF2D3FD92F3ABC3C0E52E617E3A +:10DF3000B9C5AF39855F0EE36F8B254F3AF0EB190A +:10DF40005D00FD6FF34810FD42F3C1EF459F357C46 +:10DF50009DCFE5FEA4B9DC8F047EDDF83821F857AB +:10DF6000E3CB0B08E35FB2C3D8953F037E9F0A1251 +:10DF700049A4E3D5825F0A9E6175BF3A12637CBFF4 +:10DF8000EF6BA32A0ED9C6E67D0FA7BFBD22A4035F +:10DF9000F9B0C1CCFC51426E8C5EC6FC56C9C37C44 +:10DFA000792B81CF5FD3A33FE37F73BA093CDDE6D2 +:10DFB0002CDF05F8B7C03E0DDAAD34A2BC3C4DF500 +:10DFC000F01EEE47990CFBCFE5810190FF4D145BED +:10DFD0004EFCFE543CD71C305703FFFC89EB31F15B +:10DFE000FE31A79EF9E15730FE8D3526A0BD4DC507 +:10DFF000C610E0AFD27CA10FC910F06BBDAF677E39 +:10E00000E0BADBAD01182F2A3339738ECBB3734ED0 +:10E01000967F27CA9DFB3BCE3F22BE077E9E78FFA0 +:10E02000FAC79DED1FE37624C1F9AE9BCFF3B73B52 +:10E03000F95846799450E447B97BAD5C8EF228F6E6 +:10E0400091D50378A93C5F331FE6F1C9340B8138C1 +:10E05000DB6CEEEF95D2EC0887F0EF7E5BFCAB72E9 +:10E06000CD009493A23DC472A1BFD64F7C80CBB1AA +:10E070000384C11B6C3632BF3C87FFC0D98121E0CD +:10E08000636AD70641CEC5F69899BEA37628C8D74D +:10E09000037BFB87603EEFEB99BD10A4F297F50F71 +:10E0A0006C003FC8815F3ABD90D753BFE0DC10B031 +:10E0B0001F0F9CFDD9AF7E0BEF0F1ABDB0DF3BC029 +:10E0C000FDF235864801DACB3C9FB1262952007E0D +:10E0D0009F1739BD6A2CB44CDF579802D96923BA0F +:10E0E000E267D00FDE9F0A31BBFC14617C105CCB71 +:10E0F000E29C14BF6E8023B63A1DE36F302FA0C39D +:10E1000007070723DCEBF4BCFDC3CC7E3BC5CBA7E4 +:10E11000F617637EDF65BF01F371EB1F65F6E22C36 +:10E12000D9B36529C8CA9712D0CF38A7ED04C64322 +:10E13000EA1F993711EAEB172CFB1EF9863801E824 +:10E140009578FFF62512CBC17D70757E3842BF7B76 +:10E15000A97D809785FB5C185CAAE3799FA7297E3F +:10E1600001EED8413DE2FF6AC747876129D36FE8D6 +:10E170000F8F8FC7A03E50C767BEAD7C491F2D785B +:10E18000807E3F9812B835CDC9C41DD0BDFE25375D +:10E19000CABB0F1EFE2207ED8956164F38ADF7CDCC +:10E1A000807562AF881866C6D95FF3D2F8BEC3C85F +:10E1B000ED462A07E3D7BDA82F2D57AF33F19C9B1F +:10E1C000C6ECC9441EFFEF5E2FF25EA718417F32F6 +:10E1D00097128CEBC17173795C6EF4D9D821C8A306 +:10E1E000AA091763DC2F775904D725C57704ECFFFC +:10E1F000D31B12993CA1D38471E68E2468B7CED587 +:10E20000B17C86B9466A07333D8EEDCF6C48473CFA +:10E2100094AE60F65FEC3909E5A2884F5611D6FF3F +:10E2200085E6F7833ADABE6A87544C452BA96A2EF5 +:10E23000C37C87059BF290FEA3B9FC9D65F4156C29 +:10E24000007E7B2111F98D7E0FEDED1AC8E91A864B +:10E2500072C900FAB07A8744D690F878AA860F423D +:10E26000EA78CCE83093DFA037489C9D26F410E88C +:10E270000BA2B11FD57C11E4712A469FC701AF23C1 +:10E28000BAE43F62EC1BF420B5A3DB601D9796B3A4 +:10E29000F516DB23219E6B49038B1F713DD4090FBB +:10E2A000D76367744C6FCE353E86CF9D697908C7BA +:10E2B0000288B360DC206600B9D81B5FECEC852FC8 +:10E2C000043FFC8CCFA3E62C895C47BF57B38C443A +:10E2D0006A87B067E210D4CB4C3F9B987E86A7E557 +:10E2E0002AF4B4563F6BF5B1560FA71B98BE157CA8 +:10E2F00010EF97077B64F4B2908EF95FB36C90C710 +:10E3000027E8323DD57730C3D9656FD59F34993C26 +:10E3100043A1EC27F956F02B95556681DF9ACA6F19 +:10E32000587709144F5BE9FBCDDC2E1F91C5E6EF52 +:10E33000E2F93A7AC54F8AAD40A70EDC47C79C0484 +:10E34000F7B502BF9B1369BF61D08FADC7CEFE2664 +:10E35000D26C89EB5F7EC08CFAE4F3FD89985F4252 +:10E36000F543AE9D8E97F60EB5CF69F9D28144D4B0 +:10E37000EF97B8BC77087F055985F4FD13A7739014 +:10E38000946782DF9748133241440ABBB1D6DE9BC3 +:10E390009F9ED7E775DCCEF8CC887AF6737BF43E87 +:10E3A000285378301FF80F5C2ED4EF1D5BFC20E45F +:10E3B00001F8AD5E86D54031D80D46DD92DBC11F38 +:10E3C000345EB72CF6009D476DB615F38C2B72DFCB +:10E3D000FDE3745AFE68AF9E1881EE4F4F498E40A0 +:10E3E00037C5E7EA493FCF0FE955E7D816EE509712 +:10E3F0006BC3EA723D893BE74651B0F4DDE2EB8F37 +:10E40000C4F1C95769898E338308C8142FE44913AE +:10E41000DDDDC9811EE4A5787EB1DC7BFD113DE622 +:10E4200099E9D3591E8D01EC9A99C00F3DF46B4FB9 +:10E4300063768DD1D87016F2D58D2F1ABD8DB4D7D5 +:10E4400089B44012F4AF936347819EC6DC0B43400E +:10E450000F96E7FE03E3679FFF8878013F9F9BCB02 +:10E46000D0BEF97C83D903FBB2B61C2BF357BC2476 +:10E47000852466BF4F1C510AF1529C03A95F7FD3CC +:10E4800047EC700531C9485FBA7B71819CF1E17E30 +:10E49000EACC248B6D05ED57BD9EE9DB1AD29104C1 +:10E4A00072604A3AA79F6E97C144FF99D7EC1BD080 +:10E4B00048E15DE8B7E0B91AE54BC50FFCF5100C73 +:10E4C0001967FF0F4C67F2A0D6143594C1F7FF31DE +:10E4D000BBD299DFE5DF32E8997F4BD9571CC9A43D +:10E4E0005DE72D9D85FB9CCEF8F30696CF34EF813A +:10E4F0002A7CFFF20623CEEFCC4109F9FCCC66362C +:10E50000FF79EBCD1EC8BBBEC1CEF6B3F368BF9E8C +:10E51000E77FE34730AF0F37DDEF05FFFC87847DF2 +:10E520002768637EA80F6D2C4E0E6D619C0FF7F669 +:10E53000413BA67AFDFC899867B659E7053B821CEA +:10E540004C44FFCEBCCDF7FE7614F88F26DF59027F +:10E5500078B8C1BE240DFC25B49D3FC4EC6296BFC3 +:10E560009B32F2195887377C39B6E306B09736D319 +:10E570007592C7F2E3C14E3FB2F946B44BE74DB2D4 +:10E58000D8615E9E4D4F8F07FDF1E1A40C19E7B3F2 +:10E590005B2236C0837D691ABC9F2729FE9EF8E95D +:10E5A000A334E6672BCBB57A23D0EF0F3AE413BA46 +:10E5B000AE6E07FD59BB598F76EF91C96FFF71BAE7 +:10E5C000A36B5DCDD3B5DE3E3ACEEEA9DF748BE012 +:10E5D00013122985FD14C389767D19739715003CA4 +:10E5E000DA75366F4543018B577DB7F54636B1F581 +:10E5F00056932E91AFE5EFB4DE7E90EEBCFAF54671 +:10E60000B25254FBA8EE722D88ED84BFDFE425BE24 +:10E61000A7AD18D7F549E0974B57B07E533ADBCFFB +:10E62000287F5DBCE3755817E9819500472EF115E9 +:10E63000031F7962B672382B64E5761CD9C4EC6688 +:10E64000B0EF81DEEB9CE49935717E87F5E9EC3C17 +:10E650001B5DFF8FC03897DEFAC751A04F5DCE8596 +:10E66000212CDEF919C607ADED2CAE6CF5C630DEF7 +:10E67000AE77F891FF845CAFF732BDA39DD79FD3EF +:10E68000D9F98B7A470CC739E062EB50F8DB372EAB +:10E69000B5A09F74A32364667E852001BD3471A458 +:10E6A0008EC5C5B89D750BF73F9A4A5E26100F239D +:10E6B0006358DED7EB252F2BA9B4FCDB91E3BC78A4 +:10E6C000DEAEE4A9967C98F7183DAFEF138479FF8E +:10E6D000CE5786F58B5D3A0FACEB89252C7F915494 +:10E6E00027A1BFE4F5920F1CB3E3E0F71393C74AE9 +:10E6F000F96432DDE4C4E7DB7D6F8CD9638DE3AF71 +:10E700004F5AA54A66EF7A92A70E66FE10D4C3252B +:10E710006A7C2C7619F0BB6BD3CAF6039E6FB89E49 +:10E72000D1E3DC6E6308E4DF397E7E458BBF63E9AD +:10E73000DCCF7A77A12A3EEF308473403F9E97D496 +:10E74000FD16B4E8303E3EBF452221FABD733B5F63 +:10E75000C80139FED1D32FE4CC8C8347DB4F3CDF9B +:10E760004857FB01B57EDDDEFCB9A2DDE5F524608E +:10E77000EAD3D5FE72F5DFD09F3BB39DFB837DBE10 +:10E78000BE0ED807F1F6DAF1FECEF943DA27A1BFC3 +:10E7900043F8334F1D7B0A22279DF433B7E7C9F1B5 +:10E7A000F98AE2399AD36D0AD08D4EC5DCC2CABD52 +:10E7B000D1ABB7F5F8643A8343D0ED544B9F64C0B6 +:10E7C000A3A1CEAA10768EAC10ECF4CDC4E285F5F0 +:10E7D00064C87059417E8973F85F98D9D361A14F9D +:10E7E0006AAF65671462BFFB653FE6C57D21B7E28E +:10E7F00039C2FB750D986FFD15FF5E96CDBF672E74 +:10E80000EE4FC2987F4D5AD4F84D6B62FA2356658D +:10E81000403D25F07CEDCCFB709FDA037DD603DF15 +:10E82000648C64EFAE71E571BF4614E304E691C4F5 +:10E8300006FBF9A651418447D0A79E352752BB84D9 +:10E840007632E4B524A4603C34C89FC49A423AE3CB +:10E8500003097C5F4B34F1002AB682D04EC00962B6 +:10E860000CF2631EB5875B0B4A309E8AF6278C0B31 +:10E87000EF671629E84F87768661DFCE6F9D7CC9EA +:10E88000F30C278AF7D5961EE30F13E1BC0E6D9F9C +:10E890004DF520D87FC4AB579DD7D944ED66D88FAE +:10E8A00089F8AE4E0E17BB701FD21105FF88A1D498 +:10E8B000E401BD9AA00B1702DDB4F15EDA2E8FE5FC +:10E8C0001964D941AF88F338754BC7FA21DFBDD33E +:10E8D000CE38C8F647750F94E1FBB1EDCC7F5EDF13 +:10E8E00062C4F384F5FB248C57D5F90D2113FA315A +:10E8F0003C8D40AF20B5C360DFD86667F9516D37F6 +:10E90000D9BC4112EFBF8E6E7910FDD7568CD3FD66 +:10E91000B3F1CBCB89140143E3E253C926A647B830 +:10E920007F3B8DF393A0BF58CF22DE9958E4CF03ED +:10E930008BFBD7EB66FFC6E2FC2E7921D73E0C7924 +:10E940001FBDE7851CBD05F2464C60CDF37A008BF8 +:10E95000EACDCEF375660FC6B53AEBE15E04D33E61 +:10E9600089F7FFC12DE3FA62FE283F5F77DD5AC8C1 +:10E97000637ED44C54DF8B874FD18CAFA7E35B3DD4 +:10E98000A2FD3D378F5330BECBCB2FFDD847E17F63 +:10E9900054AF1E0F59509C0734757DAF3233E1E1FF +:10E9A000B563BAF437D5E7CB5DCE2E3DFED0DB1391 +:10E9B0005B877A607D7D8AF9B8421FD73B589E8875 +:10E9C000566EAD7149C2FE1D0F2A76D5B42ABC47DA +:10E9D000A033BEDB3EC907F72988F86EFD323FE65B +:10E9E000E582FE77A1FEBF70E61001FBF21CDAFFA4 +:10E9F000F55714E60FA2768444F9D0D45E867E4F94 +:10EA0000483705BD29E8BF80EB25B0D581BFEB377E +:10EA1000DDF1B40EEC6597EF491C97EF03B5F08676 +:10EA20005DCC5EAF2F2CDF00F2806C9708E8ED35EF +:10EA3000859FA09D51B77FDC88F8BCF2F9FB9E60F2 +:10EA400079C93BF43DCE3FECD2A17CABDBFF1CFA95 +:10EA500033CF85D871966A25B47A34F855AA65B053 +:10EA6000B44849A86A3AEAFF69741EE03704BD0356 +:10EA700076CA8E2941C873AFA7FF01CA36FAE7A24A +:10EA8000BDBF719AC90AF19AFAC2998B703DD82C10 +:10EA90003E98BF16CECEF8F00316F437AED9A7AF26 +:10EAA00004BBA994DA49BFA2F066A74CA8F452B9F6 +:10EAB00094A9DB53FC032BC4D57BD6C35333981ED8 +:10EAC0006E96FCC15B4B300F92C4E7E9E4EE63F64F +:10EAD000D8AB2E66BF89F7AF42E223C5E79860C77F +:10EAE00058E0B997946802D8C5F5C4F731EC73893A +:10EAF000DFEA8171E02606B0B31CCB3DE8CF3539A3 +:10EB0000A23F1E8A769382FB0CB18FB8B49FF9BFE7 +:10EB100046B9036F021D4B75D1C76F05BCFD989DAB +:10EB2000F3250A93373953ACC3C05F6576441FAFF2 +:10EB3000F4607E0DFA1F92AF6B463ABCE42036C0FB +:10EB4000CFD8609522C5E9192137C6769EA771A056 +:10EB50009FB49C8B977E945A674CC8A2CD5FA776D2 +:10EB6000D905C7FE31558197C25E904D01DCCF5467 +:10EB70004CA3FB43E0CB55B1A332F8E51D1D682F34 +:10EB8000D68625FC4E6DE12F31FF6D21CFB3EACC47 +:10EB90007752A298FF75C995C0F56333E34BD281D4 +:10EBA000FB5FB28BE19FEA4DCC0BEBB2DB1BB19D5F +:10EBB00018CFC0E309B5DC5F431185F57F7589780F +:10EBC000C20AEEAF12796CECBB44F194C6FB17D6C7 +:10EBD0004DA29A04E1F22401BCBF30FB65376D7F82 +:10EBE000AA5A66FEEC9684101C0E5D2775F8C0EFDD +:10EBF000182CEEF91C4CBA5BE279B2B1F1E8EFDF08 +:10EC0000DF5B9E2CCB8BDD306220E69597ECFB78AA +:10EC10003CF007A924B81EA9BCB8AA3CD92C375B84 +:10EC200047FFCFE4C97A25DF36FA1CECB6ABF364B4 +:10EC3000BD8C5E227EA9CD8FBDE48E282C9F2DBA7F +:10EC4000E569D0BBFB8C98273771DFAB27C17F39D3 +:10EC5000D144C218CFD5D80FAFA54E29053A5DBE15 +:10EC60007866CB4A02F9D5CF7B59DE9DDA1EE8CD16 +:10EC7000FEC79846DC3EB1D2FDEFB5FF85BCAEE7DE +:10EC8000FBA9F352EC910298DF419DADA77331B718 +:10EC900089EFF796E7D1DE739E8738775519CD5304 +:10ECA000C5A7EEE91CEFBBC5BB66820FBA87789794 +:10ECB000C2F3B71489890E926D50C5BB147B416FA6 +:10ECC000F1AE08D63FD71FEB1FEA16EF627905CDEC +:10ECD00007D33D60DFD73863CF3CE381F10C384E7A +:10ECE000F3FE8410E4B93773FCD75C7DBCEB41774D +:10ECF0000FF1AEADDC7EFBA0508E18285EB7120679 +:10ED00007FB05DC4BD64DCC7C61ECE16F063FDE5F2 +:10ED10008707A1BF68968867BDC4FC68B378DCEA42 +:10ED200083C90598E7D51B9E67B5A8E3020F039E2C +:10ED30009DE8E7437FFC7DFF3109FD5373C18FDF01 +:10ED4000A7EB1C04E1FE3C4F0B3BDFEED921853CD9 +:10ED50002CAE6292D136B4C9F07E2115A31B41F4CA +:10ED60000629D75C435F4B146BB4DED34CCBD4E89D +:10ED700057562B41176DB7F56402FACF1E72781003 +:10ED8000DE879A597C39B8560AF563E3E2BD61C162 +:10ED900066D907E3EC7633BFD32B6EA6FF3C9AFB14 +:10EDA000089AF53C4ECCBFD748E4083C65893D1F26 +:10EDB000B229953DD90F62BC667D83A90CF09DCD2B +:10EDC000EE27F9DCE09B86FEE59402BC87A839B10A +:10EDD000A1A592D5E39AFDDC1CF363FD750A3348C7 +:10EDE000892705E07DCACDEC1B2D9EE7B4AACBDABE +:10EDF000F88EF6DCD52C12E8EFEED3FD5CD2536E24 +:10EE0000A6FF3E5F93C7E9E2C57849B3DEF3461E2D +:10EE1000F0FB6A76CF506316C39B9CCD9EF9F60A31 +:10EE2000BC0F8ED8B91D4718FCF9D73924580FCD1F +:10EE300076C6B7FF2ADC5A785F771730FCDAD97AC2 +:10EE40006D5E2D8518BE18DC57EB1739FF6F968B5A +:10EE50001F48DE672279D80FE542F0613DAEBB5313 +:10EE60002494C9F2266D283767F27DEE675CCF6D7A +:10EE7000ACCE4F8238E8ACB3ABF0BEA0B153AC0817 +:10EE80007FDD4B66DCC7D52E8BE6003F6BF108D0EB +:10EE90002A429ED2FA990EC2EE996951C7F5B4F191 +:10EEA000DA608A5F8678505D79B400E2464FC81F09 +:10EEB000EC7995C935D4AB75CB62CF809F796A4A1E +:10EEC000C09C41F173E181B7C74B1EEC8EF2EDF2AD +:10EED000C1FE78BE7066B3FABC1659AB8E1B929613 +:10EEE00014762EAD4DFD1ECE27A9FA758B2332BBAD +:10EEF000669D213000ECCE1BAE67791217E7CB047C +:10EF0000E879D14C787C5EC8596F41BC1E28E07608 +:10EF10006F77BAD27680679E172ADAD7025D293DCD +:10EF20006B385D2F3E774D01D0F5C29E6B0A80AEE7 +:10EF3000EBF4AD3E58179F390303011FA7C7F9D162 +:10EF40002E1479B057CB6FA332FE67F5F078819716 +:10EF5000EFA887E12FDE5FF2D23F58BE6AB09D9DD9 +:10EF60004FEDF2D39DC37BB62E5F912590C3BD8D2F +:10EF70007792EF935C261204FBABB43C8AFD4AFF08 +:10EF80002613B00385FDAB857F3AC7DF820CDF4BCC +:10EF90002EC023F7EB56F3B14DA14F999DBD5D42B5 +:10EFA000BFADC9134C1A8DFBAA39C37528577E858E +:10EFB000E72048BB6483FDC9FCED8D587F69DF2CD9 +:10EFC000AC974D9108ECC36A693D94578D51E73574 +:10EFD000EBF71647E2F7BD148E03B09F4970C40CDF +:10EFE000C09F7560575310EB14E6DFAE7310F4AB9F +:10EFF00094EC53EF1345DC76A39FDDE3B2B15DC221 +:10F00000FB9CD20C81BC2CA0AB267E7B7F866F1D27 +:10F01000AC571147BFCDE97B2083E597E5009E8281 +:10F02000190C9F51BD38AFA73E4F78ECD0ED680763 +:10F03000FD85F8937BCE370BA9E2EB73F979CFB955 +:10F04000FCBC27C8E788463EC7976BE2F2CD223D5D +:10F05000E50DC4E59BC5F78BCF378BA8E41A5BFFA2 +:10F06000E9BAC518D7AEA77CBE7458171FD610FED4 +:10F07000B73EF6019E6BD961447F5A0DCF33ADAFD9 +:10F080003E85FB947A3827C3D623CBC7E6F71CD43A +:10F09000D0FD1FE6DB86D5F9A8BB7B951BFF77FC6F +:10F0A000E4FB843CE0EB51CC4BCCA3A65D62EB4788 +:10F0B00003A776DFABF5778B7DEBD5CAA5E3FFC35E +:10F0C00072E9AD7F935CEA1637E81B4BF2FE1BE258 +:10F0D000061F795AD3C095D822317E1DAFB3FA5896 +:10F0E0005C52C7F216B4F15ACF788C430A3FADE9AF +:10F0F000795D68451EB6C7386CEDC144CC23A8F6CF +:10F1000054A39DAD8D4F2E207BC60309FE428EE396 +:10F1100079AC7F351F806476E603E47DC77C0063AD +:10F12000E677884FBE6CFD343510C727E545D460BF +:10F130002FEA3D5FCB99C9F82E81E78D989420B1D5 +:10F14000C7F5EFAD5F7626CB037B99E7193D9A981B +:10F1500080E7F65D0676FEC025B37CA8332E7F6E71 +:10F16000E608D0038C8E3FD97F0781FCC29FE8C39D +:10F17000788E3E586BF582FE127E2631FE83DCCF00 +:10F1800072B5EBA724F3DFBB7EBE4D6E5C2FBE775E +:10F19000B5F1B5F5140771EB4ABB0E7AEBD79B5C62 +:10F1A000B935D33F2113E5966F08C629AE521E2507 +:10F1B0009450790DFA79AFD103FB05133F2743D65D +:10F1C000BA55FBED598F66A3DEBA6866FB07719EE0 +:10F1D00047CC7F66AFF8FEE7ECBBE34EFF6C98CF01 +:10F1E000E9321F9E07782891E995D84E9617A43DDD +:10F1F000D7A2D527E25C86F8DE7DFF667EF8AEF208 +:10F20000B4497CFF5F94A754BFA27FA5D7386CB7E1 +:10F21000FE419E9FD9E1E3F1293CE720E0AAEF609F +:10F22000F9748F674A2A7FF37D5CFE9FCCF4B501A9 +:10F230001D2EBC653241DCB3A484C9CF3ABF15E3AF +:10F24000067561964753B78CE03E5F9C5FCD4B0FD0 +:10F250006C0139F5D0DB56BC77B46EDFD6967CCC2A +:10F260002F08A05D77E92DF6FE445A601B8C5FBF26 +:10F270002CAA8A4F947EFDE9AACA128417F7E90ED8 +:10F28000A3FA5CD0914CB6FF16CF439DF8A5FB12B4 +:10F29000DAEF4235CBDFAE77F86C659857C0FCDF0C +:10F2A000099E0EF45BD7ED452541309914EA1FCC39 +:10F2B00042BEA9DB5B568CF70884CDC578FFCC3BFA +:10F2C00056DC5F5D782023A463FEF2FD006F624987 +:10F2D000E826B02F73E977C0FF7D61CF4DC5E80FF9 +:10F2E000D4AC3BB1DE3ACF83DE650A35495DEB71C4 +:10F2F0009D9EE947A1D77682318B79153C2FB07D51 +:10F30000129963ED2A5B1DEA7CC90519E376023C7C +:10F310003B33591E8988A3E799E8EE33BF3B1FE6CC +:10F32000F138FA249EFF4082A6AEBC87FC6F8FA303 +:10F330000BF84459C4D113AE30FB36DF6640BE48EB +:10F340006C61728350BE00FB7A4CAC632C9CC3EAA8 +:10F35000DB161903F84A06F463FE69F4C743215E1D +:10F3600091AA8C8178C596A5C30E9B1CE03FEAB894 +:10F370000E48E369B595C3D6322FDD7F06F59ED2E0 +:10F380005008FC5FFE073DCB535C9D80FABE2DA765 +:10F3900006F3142FBD6D549DBFD13E8364850BFCD5 +:10F3A00044F92DBFC77841E25EA9C7FCD37E60F463 +:10F3B0008F60EDC1EF94D8D2111C097E9487257619 +:10F3C0007723855E72C1FE5F91C1EE98B58F9DE394 +:10F3D0009ED56A2F37A13C9558BC658C03E5A4B235 +:10F3E000FA6619F6674A23C17BD2B2B2D839817E58 +:10F3F0006D3619E8FEEB2F753DC6D112B2985E85C9 +:10F40000BC374057AD31761442FD22FE27F2DDC4F1 +:10F410007EA853BEF2FBC4853ED2DAB1DDEC57AE16 +:10F420008F3AED780D1FF7D64FF0B7E0E75FEB09A5 +:10F43000DA61BF964C78BE4BF075B3C8DFFF92F926 +:10F440007173793ECDA9357F1FC2EE0F14F1931071 +:10F45000CB83D247576522BEA2D70761DE7BED7210 +:10F460005D11FABFEA709CD5ECBEB3DC963E2B462C +:10F4700096C0D3460005A70E2CCC857519A47CD068 +:10F48000AF073E3897C9F29694D5094837E531BCA5 +:10F49000D99928F634A49BF204A3CF69CEE7227E43 +:10F4A0002BFC94273303A3B39C71E7B2965AD8B9C7 +:10F4B0002C7EDE3771E9DBBBE1BCD316EE2F3EFCC0 +:10F4C000D220FCDD85CF572B12F88D3EB757E5C211 +:10F4D0007E6F1CA76BA2D2416CD678FE3C8CF9B231 +:10F4E000F90759DE9FC2EF4F52563BB6023EBDA907 +:10F4F00001CC0BBEAE39823F59F092ED34C6E5A87F +:10F500005D84E79FCFED97845DA4D28762BFA6DDBF +:10F51000874DCFFAEFB5936667A9F71557BDBF22A0 +:10F52000EA7D66677BB16FD4EE2334FD7BB37F88C1 +:10F530002FA8CA8BB99FE7450BFD9EC165A3C8974D +:10F54000E93CBF4C42663807910CB9AF4CAF63DE63 +:10F55000D07AC9E2053B499B2FD499C7431AFAB325 +:10F560003C9286A1EC5E8A866BE029F289CC904FB2 +:10F57000129FB79AC8F281CC904F42DF37F57ADEFE +:10F58000D9D308DF6FFB914D9C77667EF64AC2E3C4 +:10F590000CDBF03C74ECB62C3C5F33B692F9EF52C6 +:10F5A000FC0619F8F2F9AF743E90BB31BA6EC1BED9 +:10F5B0004AE9EB7383BD65A6F590A7D279DEB98AD7 +:10F5C000F478DE59E43389F86E46FF7512E89FCE71 +:10F5D0003C93FAAE73D0F0DDB6451EF40F77E63DEE +:10F5E0007D9FE03CCB859C31A9E997E463ED92A631 +:10F5F00019D0CE4893033B318EB7B1C38CFE8AAC91 +:10F600007CE4ABA69121BC3F37A5A815FDAF2B53D9 +:10F610007DBBB24674F18F808FAC67F3BF0CE7BC43 +:10F62000A4AEEF5E9EFFB71CB0A7CADB8D8C0F3572 +:10F63000706CECBC6F857E873E0F6531FA7B35F6CA +:10F64000AD781E12FCCEE5B0F87E6FF314FCF86DB9 +:10F6500076BB96BF82E59C3EEF99432C5F49CD5F18 +:10F660008797570E3F4D65C991E57E7C5E364B61AD +:10F670001DE4159963334002FE38BBFE7B700FC753 +:10F68000E5C4580EDCE3F178CE6DB7C23D1D979D01 +:10F69000B1F7A0FC4CF643ACDC2FB605EEF568CF15 +:10F6A0004E6465F85606216F6D926E0D5AF11EADCF +:10F6B000551DA09F4A34F9299AFB07208F12EF4B62 +:10F6C000B0327AA6F33C5652C1ED77882CD17293B2 +:10F6D000BBD80BF90756E2D9DB01F55946764F0145 +:10F6E0006179534DFDF2589E03E77792C5FDCF2413 +:10F6F0001A04FE6DCAB363FF4E79BDD7C8E34EEC62 +:10F70000FB279E63E7CB447E2E21B66CB07BAC1EFC +:10F71000A22A8BFB3B8862CB86F3FA4DC2AFC7CBE4 +:10F72000EF5A027FCF8AB38B4E8CBBBF087FFFE3BB +:10F73000F907FBC27C6F34A8EF4F16CF65394CFE3A +:10F740005EE6F70CB659024A362D9F4C98311EAE34 +:10F750006E9D965A66B0A39DB65307F2C8C9F9C20A +:10F760003E95C167AFF04BF0BB1BE29E3F67404147 +:10F770007F0009B4E9407F3A4FFB310FB0C614CB8C +:10F7800051F2C1AB1FB065431CB0EAFDFB300E98CF +:10F7900071E23DC8DB38A16F1D9B04FA228FDF03A5 +:10F7A00041377E415A3E9A998BFBBECE7B41FB4945 +:10F7B000281F264E65E7562790B082FE171B3B4751 +:10F7C00035BE24CFDB44BF3791E77D8C3FE94F0244 +:10F7D0003FC0F83BA20A8BB7C494F83C0BF1242E2F +:10F7E000BD277E1DDCE4892B13B84F585DBEC5AB29 +:10F7F0002EDF3AF2CBFEF1E564E21B04F37C518A82 +:10F80000E239E4E0286263F362F9843FE3FBB64146 +:10F810002E62CA857C478714847DC1A01732308E42 +:10F82000F2C24882E5B41DA66DA6F8F93F26B338AA +:10F830002DF7738BDF0D823AD0ABCFBF9586F84A98 +:10F84000B3CA284FC1030EFC569A69B2807CD771A7 +:10F85000392FCE6D8F4B32E17DAF4D8BD8EF0D68D8 +:10F86000EFBB6CD2DB0E011D9B3EA273A0DFD99EC5 +:10F870006888C849402F420C8E2E792CF807C6BBE9 +:10F880001EF87E04FB5D27CAE57DE3EF1B6F723235 +:10F89000589B7EA4F0F81CFB7D89C2CEDF9BA0CBD9 +:10F8A0008EB6079B92E03A61F1B16C314FA2F8A09D +:10F8B000BD9B88323B9F95C6CBE29E4D42CA14BC8D +:10F8C000674712ED1AB1FC246F27B5BFFA57E08FD6 +:10F8D000BE49743EF4D994CDE4C453F289F5C827E7 +:10F8E000D68007F8C49BD0F379A1BA6CB66EC62552 +:10F8F0008D7441DE4093DBEB02BB4AE0A7F33D1F72 +:10F9000057D48BEF79537B1EB7898F1BE6E78DB5F4 +:10F91000F53FCA66765BE7F87A3AAEF51BBEEB5464 +:10F920007FB7ABBEB77EECBD688F3F07550AEB8C47 +:10F93000E16D02CF732585EAFC1432D26B62F25E70 +:10F940009D8F72A3B4CC0DEBF326536D7B94F67FA1 +:10F9500095F3C98D72E0338837BC3AA3E008ACCF89 +:10F960004AB8D09E8E733389AC0266B95C16F889AA +:10F97000BD0FCA8B75208FEA7481FE29B47C51DFDC +:10F98000DA77511EAEAF27B34774874FF061279CDB +:10F9900094FF80EE82FFB4700B3E20DF0B6342DFEA +:10F9A0006612C1A78BB03C6AAABF58BEB427BB6B16 +:10F9B0005E9439C79B1AFA827E7FB53188F2E7469A +:10F9C000FBE39837B63337B00BD6FDB4A11FE33D48 +:10F9D00039C45585F6168577F7FF24BC745DB9E107 +:10F9E000BDB00385BDD72D7FF823832A7F58C0A7DC +:10F9F0005DC7028E7AC2EE3F1ADBBE15EDBBFAA9D7 +:10FA0000562F9CF3A887BCD8128C7F619EF101BE53 +:10FA10002F0B4A2CDFB79BBDD87B9E31BB0FA0D6E6 +:10FA2000C6EEC111F729DD9B2FEEC9617053F9C5F0 +:10FA3000EFC9C1725B9507F77F9D76E31C6687DE91 +:10FA4000506069867B07BBDF97C3FC7BE405A38717 +:10FA5000DB89A8BFDB12D9772E9A595E7B9C1C27C5 +:10FA6000525AD73D5EEBF4CC1EBC949DC7E278B2EF +:10FA7000B714E8B111E256BAEE7EC8CF9C818F81EF +:10FA80004FE614F972E0273D6619989F91F2D5A6CA +:10FA90000E02E9710DDBE17ECB9B48C39B721FE434 +:10FAA000AB2F807FA60DFA98DD7BD9C55757185F1D +:10FAB0000551087EDB3A7D2D3520E58CC03CEF7783 +:10FAC000EA4A20CE6844FC8BFC43EDFA8D83E7B410 +:10FAD0009EC1E3807B75293CE61C677778AE86BFC4 +:10FAE000E3F9289D303EEE8DCF21CF3F7158179F0F +:10FAF0002793800BE0EFE4F755DE165D9F1EE0D6FE +:10FB00005991EEB74F67F198FA0466A7425CC69D1B +:10FB100006FE27F6FDDB5733FEB8DD6C447E99D434 +:10FB20005E8BF11752C1E2295EFA3F80671AF18DB0 +:10FB3000839FE698629B84E736A74E54C75BA699DD +:10FB40006EC4F8CE6D84F9D36E9FAA57FDEEA0C0A7 +:10FB5000C334B2F663C8E798A6F9BD412D5EB4F18F +:10FB60001A818FA691DFBCEEAFCD4974609CD8435B +:10FB7000FA7FC7B84E790ECB9FBBAAB8CE117D0CC9 +:10FB8000CFEBBFE29CB769115D17FDFFB308EFE94A +:10FB90001E97367FFB63B4FCD38D03B1FC4ADA5D5C +:10FBA0004B4E40FD96022C57C81FCFC07BD34BA7AE +:10FBB0004F80FBCD8F98D9382E4BA00D7EAFC2352C +:10FBC000247F186CC92A0C316C77F3D0DAE19007E6 +:10FBD000536161E5E3C5FF6B1896F37979D88B0320 +:10FBE000A17C44FA78464F71A1418552047E97AAC0 +:10FBF0002285B59F386C6706F8092ACA597990B7EB +:10FC00006C751FA8973F99D1933E6EE0F6B1B0B7DF +:10FC1000FC7CBDBFE07BBF19CE87F9AD9217CE0546 +:10FC2000F847BECFEEC732B13C02BFAF5881FB13DD +:10FC3000CB7DCCBF37D6DAE806F9F7BD80A104FC4E +:10FC4000B8366B5E33FCBE40F2C8B21140EFB1D49F +:10FC50000C03FD47D7D5125C57D77C9C93847688DC +:10FC60007A5D09BE9D24D653857ADD5079F04346EE +:10FC700047F57AA0E32E87F7D3AE55EBA54EF9AE44 +:10FC800059B75A7EEC55EF13B51CECD44FABC2C834 +:10FC90009759849DFFD90C7CCAD66F2BC061903BCD +:10FCA0003CF03E57F20EC4C48A5EEC07011F983D3B +:10FCB000645877B8E04F11F62283C0664B83EFB2E9 +:10FCC0007ADACF073F2226E0A2DF0F217E56317875 +:10FCD000364B0DFC7729985D2EF6BD7562BEFBD4C0 +:10FCE000F32DB5B073EC2E42E50EFAEE8B077E13C2 +:10FCF000DCF55CCF4E35F91F36D239DC669F857452 +:10FD0000BE83049F03FBA6C312F825D05B27070F11 +:10FD10004625F85D091FC693291D7F9513672F0897 +:10FD2000B8B4F8A8EB45AE6AE1D6E2A18B3E1D68F7 +:10FD30009FB9F9EFCF75CE4B339F267EFF7CACD8B1 +:10FD4000A8CA133D5EC5F260055CC72552887A5289 +:10FD5000B2601CB5D3EFA4956FBD9C6713FA59C070 +:10FD6000793F3F4FF585CCE4DEFDBA08C2995BD9F7 +:10FD700061063C7E92C3FC2E02FEA691416C679008 +:10FD8000A51EE3C49FE4C8C25FA6A2B7B8D74CC4FF +:10FD9000B9045E1D064F16E67B6AF039D364EC3970 +:10FDA000AEAA8DBFF6D24EA2F8CB4CE98E67112FCA +:10FDB000BB45EB87BB89F9A76EE17EB8B1950CFF17 +:10FDC000294B1371DF965272422183BBEE5D16F40C +:10FDD00078C711F82A07E316D111E027787DC44FC0 +:10FDE000314E24EE37D4E2C792DB337E7A5B0FBD0F +:10FDF000C1FFAEC56FCDA5E35C943AF01EB4BFBBA6 +:10FE00006C7CDC401EAC17BB2DAF0CFC0B54AE7EE3 +:10FE1000FD356C36A10AE8E70C38729DB03EFCE374 +:10FE200020F73AA532A067FE7982FEE1C57C9F38B3 +:10FE30008EEBF74F76B1F3F315BE014F8E01FBF356 +:10FE4000989E843C90C7CDF0F3C9261DEAF579AFA2 +:10FE50000D77817DFE01E7B7FEEB65D5EFD30D0889 +:10FE60005954F76C0CDA91A22A0F0E67A8DA0FDD4D +:10FE700097AFAA2F8E0C54D50F3F364C551ED1315B +:10FE80005AD5FE9A93E5AAF2A8E80455FB6BCF4E2B +:10FE90005695AF8BDDA9BE2724E8EB284C83FBF9F0 +:10FEA000193E6EB83253D5FE7CD2F863B0EE66AF21 +:10FEB0006579DB6564A1AAFF425D0DE64393566652 +:10FEC000C734D0FF213D75772B982746EDF754C0F6 +:10FED000DB7AB59D53DDFED82A90B5DDEEA7D0D8EC +:10FEE000335AFBA5BFA30AAE7726B7E6F2BC936BE5 +:10FEF000C835FCF74AB474C5F3FE9FBCA9C37DC4E2 +:10FF0000E2D7987DBF7837CB872B20FD92F11CD8A4 +:10FF1000311D094970EF41C3BA3152971DA3C58BFA +:10FF2000D1A5A6B3D9A3A67342A19ACE895E359D69 +:10FF30009347AAE96CF7A9E99C5AA9A6B3D3AFA63F +:10FF400073FA34359DDD01359D33ABD574CE6E50DB +:10FF5000D33977A99AAE79C105AA7A2137FBB42C97 +:10FF600056BD6F92C2A5545292D9FE6ABCEFA15FF2 +:10FF7000EB0F7BE40F41FF20FD1F5BCF0D985F3F30 +:10FF800097D21FF2EBFF42D61E855094960FEAF6E9 +:10FF90003D8671B5EFCA078F6AE97F95F629D58747 +:10FFA0004F803CA176CC7A900FD3FAF37D87BF6760 +:10FFB0003B46C8AD78BB217E5FDD9B3CEBA627F9B5 +:10FFC0003EBB573DA9D967BF05D94D688FAF45BF27 +:10FFD000D674CED79FC2AB51E0577D16F5FF5B14A8 +:10FFE000909114AEB7006EFA9DB72C83D00F7217A4 +:10FFF00089E8F19E6BC8DCD4E17D9998875945ED7D +:020000022000DC +:100000007278CEE2F6C11CEE27F9CA183890CBFC04 +:1000100023B969F0DDAC0E76EEEB78EA55DD0BF135 +:100020007BF827F8DD73FD87619C0A9367C913F499 +:10003000D561EE7F221359FE2751FC83E3EF61EC7B +:100040001A87C54D5F940201DC67BB4D5ED8670F10 +:10005000CA242637E83757281FE25427347A652008 +:10006000E791DD19E1C576C4572805E304DFF1BB4C +:100070007FCAF59D047E10EDBF6DBE06437811F377 +:1000800027B0DF4B7993D3E5A9DB8D11D897093ED3 +:100090003A9930E3A8D383FEF033C86F77DCB40A13 +:1000A000CAD2E154CF620ADFE5AA28EEEF29FECFDB +:1000B00001DE6A4C14FF748A17B303FD938119FCA7 +:1000C000A9DC49E91FDCD3792401CF58897DFF5D84 +:1000D0004BE05318E7B0DC91E3057C281D786E8F68 +:1000E00058D1B821170D3DFB03051ECA13B2EFC648 +:1000F0007B788D462FEC2FCA2546D7D3A9F7CC8025 +:10010000D8E21CD99F16D1A9E0963C00B7AD2AD7FA +:100110004DF9F1FF00AA42FBD90080000000000069 +:100120001F8B080000000000000BE57D0B7854D504 +:10013000B5F03E7366CE4C924932492024848499AE +:10014000843C20214C82202AE2F0088D1A30BC1415 +:1001500030E2E401843C2080DEC6963603E1A5420D +:100160001B2C2A2ACA8040D102068B801AEC206AF6 +:10017000F16A356DB5A55AB90950E54D0C3E68EBED +:10018000ADFF5A6BEF9D9973480AF6DEFB7DFDBE0D +:100190003FDEDECD3EFBBDD6DA6BAFD7DE73DEE2EF +:1001A000CD8C561963B6DE8CDD00A9D999531CC9D4 +:1001B000D8B7F8774B3065CCC718546954E09FBD69 +:1001C00020F723C5BFCDC5F81FE4F7FB62FC0F4144 +:1001D000DE6ABAF4C114C8770C36B9B740D1C6701C +:1001E000E83A9FB1F7B11EF4FFB405F2B1F47D35E2 +:1001F0007E4F08E7ED131E33F91BA17DF198971789 +:10020000B2EB187B76BEDDADC258A5CCA931985FA4 +:1002100039F3682C8DB1BF8CFEFBC1362763FD9D81 +:10022000DEBECE618CDD1B674AF980E6E1CD9E041F +:10023000F36623E3184BBC72FEC67530B6C6C4869F +:100240003336D9C197301BD705EDA6308F05C79936 +:10025000C6BC161CF77717340F8B82D404E530DF49 +:10026000BB988FBECF607E4AEF6601AA7F0F6BA35B +:10027000FC6F237293EB617E931ECF4C67D0E662D6 +:1002800069DB702CFF87D5EB76C2B83536EFBDBD84 +:10029000E0FBF964EF677D10EEEB39DCAF36DF4948 +:1002A0000A87DFC5FEC52370DDE36CCEEBF2521981 +:1002B0007BDDC42A9BED5036AE37CD9F991DE99367 +:1002C0000777D7CF32C6A05D6B67542E1B82798F1C +:1002D0003D11D6FF3D81C2EF79AA8B709D05AA9D85 +:1002E000F502F8B73A55BF15C62C1C5DDA17D705CD +:1002F0007F913EC0D3448FCA10CFBF5E0A5FA0DE9D +:10030000AFF3543FD2C4C40DE34F63FBA2D1539665 +:1003100047C3FAC77FD3765D00D2C27E96E36D599C +:100320007C8C6FE17F5FB28DE36220BD2D618F9980 +:10033000C1FC6F1BA02F2FCA81BC2D989FC8CCC1B8 +:100340007218F710C201E8A7FECF79A3DE0869C7CB +:1003500058935A0CEB2E7146F6FA3402B283D8A0A9 +:100360006F71DE6A49B4D7DE337CBF6E708F7A035B +:1003700068F276C553EE24BA706A48FF6566E6698E +:10038000EEA6DDAE7445D00F60379EB13BC45C3B3A +:100390008B2E691761BD4F3ABDF3B19F4513FE32F5 +:1003A0000BD7C7CCEC3743016EF3DF03B841F9F14B +:1003B00006807C2663271B6CCC6365ECD30607E5BF +:1003C0004F3524507AA6C149E9B9862C2ABFD0E01E +:1003D000A6FC2167F1F7B1DFB2D59F9BBD398CAD8B +:1003E0000A9378E4F3582CE87855F2F03FBA61BCF0 +:1003F00055EF5A285FD9DC341EC1B138F9F8B2087C +:10040000F8BEF839C58DDFAB5B3C9A1DE633FB0DBA +:10041000EF4A249FB9EFB64D04F0B1DACB0AF3E20C +:10042000161A50BC02C71BF6E1C97884DF670D239A +:10043000683EA71B3C341F4F4BFB5B71D0FE6C43E7 +:1004400021E53F72163F8CF53DEC730DEB4FD8D98B +:100450006E4E82F2028FE2C1FD3DCAC3FC7EC0DF58 +:10046000068BD78B74B321D1E6C6FD3E7AF0E4A7A4 +:10047000EF83713FE9EF7D14E97A5A6C79411C7C76 +:100480009F38A2D48CF5EEFA8631CC4BFABEFABE78 +:10049000E6F0A8157839FF9A42703ABF2FFB8E9B81 +:1004A000A0BFD78EA84C8579755E36D1BC3A8F86B1 +:1004B000FB9912ACB7E82595E87AD160CDCF5C986E +:1004C000CFEEC372709DD019AC3F4B71B27AA0BF12 +:1004D000B3BBBE9F807890E39F8D6DFEEA23E47BE3 +:1004E0009F70BEC758F3A74F225FEC97E07E08725B +:1004F000172C6C3AED5356173119E86BBEC6BC3C4D +:10050000EFCDC6FCD970766F31E487EF4E1A83FBCE +:1005100008C7736606F95AC6EEC7537FE80C8EB754 +:10052000A379F6474F42FEBCDFE4B34443CA9A2F97 +:10053000BC827C79ABDDBD8DE13CCDE138CF872D30 +:100540007C5EBE6DE1EE6D4EECCF4F7C00CA352C6B +:10055000AF79F189BEB88E5701062320FFEABA08A9 +:10056000E277AF5ADCC7EAB1DDD3BCBF9FFFE481BD +:10057000E307305D5B9BFF00A4BF73C612BC2B1E5C +:10058000993708DB6727017A803FFE62BF1208CBEC +:10059000656CF0FA43CB1261BC211BDB4D7D21CD94 +:1005A000DBAA34629A9D5C784485FE8F3A9D348F35 +:1005B000A13B5D6A126ED7BEFE8F6E4923C02988AB +:1005C000BF41027F39EB3F1FD317D25D7D9B17C51B +:1005D00040F920A5F9CC5217D2F91FF2BD04BF266D +:1005E000EAE7A59629BFBF9BE13A7C89369C77A9AB +:1005F000E6A6F309966B81FCF9BD699B1F8235EE77 +:1006000033F936D3F95566736F43BC17FB9E407CB4 +:10061000D7427D1FE46BF37C51374279ED2703DC31 +:1006200040512CF999EF15223CE6EF7D747C5FA8D0 +:10063000777E24730309B0CA972E8DC7762C993123 +:100640006409E7F736C6CF84760FE78C1986F45530 +:10065000AC36D3386C011FE77171EEB136004EBC79 +:100660002055A8F7307CC6EFB12D31879258103F46 +:100670000B5A96BACCD0FE3AAFCDADE2BE71F912AC +:10068000EBECC17314CEBFBFE17E4BD444BF8E29C7 +:1006900029C5DFE1FCD3C47926FB7B5C63BE30E86F +:1006A0002719BE2B783E6BFCDCDE067CA53E3F782E +:1006B0006EC3B8E1AE61D4DE837C38090EE93C98A4 +:1006C00067D2E3563A07AE75FC8B16FB6A05E876EF +:1006D0004138E76363C4F93B3DAEF1601BACF760A2 +:1006E000B837DE05F5668B739F99DD4EE4EF5BC38B +:1006F0003D7D70FC1A5B470AAE01CED524CCCF57A6 +:10070000BDFDE3D3E85CD5C933579B476BB8C785BC +:10071000EDAFB5BE91DF2EFED2C4F2800E163F6A59 +:10072000257ED1887C19D6D51839DC867C83BD61BD +:10073000AA790BCED99B79CBAEFE1647E6135F693B +:1007400064AC5B78BD06FBDF0BFC2600E78417F882 +:10075000C0A8CB1D2AA7F7D6C3D1D7219F659E4835 +:10076000A09F5B2E9B9837E41C34F603F8F2201C04 +:1007700047B308E60D39573D2C46C37DCBECB1FF9E +:10078000DABAC5FC470AFC8DEC3C1AC1EC080FF83C +:100790006EEF795D07C5BA7E85EB82747B7AF16472 +:1007A00084FFCD5F38CCB8BE9BCD935250AE8179DB +:1007B0004FC7798FFAC2A49FF737E1BAFCB5CEFFD5 +:1007C0007E85F94CB81F3FD7FCB81F5BF078043822 +:1007D000B6CCCBF1E3BEDFA7F1BC2F4A23B9B625D7 +:1007E00092F9908FB44C8AF7FB5CC80F19977B7B0A +:1007F000335E1E26DACF88A7F67DAD0052E4077778 +:10080000878BFEEBDE198CE54B93888F345AFCAB5B +:1008100053B1FF1FA9C4878F0ABEBD3E2670B70A19 +:10082000FDAEFF3C9EE13847592069018E53194EB9 +:100830007CF72693E9DE4976ACE7498C0578EFFB37 +:10084000874AE7C4FA3CC8DB896F4F6F86EFEB2716 +:100850007912C3B19F49F1269A8FCAEAE8BB8BB7D8 +:10086000FBC8C2EBCD14F8FA93C00FEC6BDAF7DEDD +:10087000891166A4DB4DAEB247683F304FA202F348 +:100880007DB2229D21DF9C5975AB8BE8A5E971E211 +:100890005FD3050E647FD8C0361CE566FE3763F66D +:1008A000B630C4E7B4CAB0763859D9D1CA65914ECA +:1008B000683FCDAB06ACC04FD9D4024F975C978A46 +:1008C000E37A68DCDAE681692743E8B9CC0A7C027E +:1008D000FA7F21CCFB04CDEB401E951F00A1E65B07 +:1008E000D84FC72BD277E3BE621571427F0994239C +:1008F0001E5EEBB0919CDA133D3422FC87083A452A +:10090000BC2CE17807798DF28DD307913EB3C9C233 +:10091000E9C6B7278CF05A38D94678EE9C1EBED966 +:100920000AE5F70ABED5383DDCA340BDC697AC7ECC +:10093000938BF424AAE73B1849FDD6683C5FF36229 +:100940003AD1D33ECDFFDC762C7F2D8CE8A1268AD0 +:100950008F5BF34A92A0378F6B058E7BD04A745021 +:1009600013EE8CA6F2FF8C233A1967F3BE82F000D7 +:10097000BAAB4339A2460B64C4007C8F09BA3A066D +:100980006D107FBEBA489A376D79C87B1B93B7202C +:100990003EBD1A2F673F50A9FC98838F7F6C0D1FB7 +:1009A000BFE4A7D5EF32C0DBB1E2F189B3611EC766 +:1009B000EA22486EFC73BD1AD0A250EFE9782C03EE +:1009C000EA5D587262F806987FDBB28F53903E4A18 +:1009D00096D51661BB92AA2513F1DCEC695F96D41B +:1009E000C0E60FD9C7275C9EDFE17ABE75793FC4A8 +:1009F0007DBF20A76D0ECACF17B4D66750FF888D74 +:100A0000F31EC5EF175FFE6C3B97AB3B32F03C9893 +:100A10006FE6F421CFD50582FE56A57A8FD1391124 +:100A20001E9885E747444E2BE7774BAE8DCF9F69E5 +:100A3000D9B64F8171AAC35BE653AAFA73B19FB3CB +:100A40004A204A4923F879713F9D7304A210EE5E53 +:100A50001397E7AA77E8D7857F66985735FE03DABC +:100A60005537AB9E30C435F36B38FF6AA605EBBB38 +:100A70008278827E084FCCFEE7593F04F8573D3715 +:100A8000301FF587EA98033FB989EA413BB94FD453 +:100A90002BF3723D57CE87AFEF9CA0FF7392FEA75A +:100AA0006B529FA7F12FBCDC87C63F3BC99F81F0EB +:100AB000BFA0887ACF59793DA00633CEF3054E4FBB +:100AC0008F597CA670B20B30A2E7EAB8E6E10817AE +:100AD000C987600E3E13D43FBB3B89EA4BBEC58A33 +:100AE00019C376D5BB13B770F94CE8B33851A85F7A +:100AF000F50BDE3FE6711F9E793E498CC7E5692301 +:100B0000FE8CEB4D4E35D17A1F93FC3B52EE737742 +:100B1000C224807FE6064D57FF42A476AF07FA1D38 +:100B2000E8D77F97FD0F4C55483EEB6FC05B5FB534 +:100B3000E39015F7D3B38CF6AB715EEE54AE373E4F +:100B4000FF7C179E548E371003257D38B91C6E41EB +:100B500038FFA90B1FF725015FAD4618A406E1B3C6 +:100B60002FCF9B84FCFF02E6F15C88817C0ECA419A +:100B70001CDE322FE16CA4B3657F9A93D406EDEFAF +:100B800046F810BF77F7417AEC925F2CA08FE4A073 +:100B90003E5A39F4643AEAA97503E128E85ACF9C31 +:100BA0000D7936DC4F7337E6D9CA42F0D0B863E826 +:100BB0001127C0F9DC0EB31BD972A3D9FF1394A778 +:100BC0001B77A8CD3E46E53684EF39FBEBEF61BDE0 +:100BD000391B63F2515E96EDE76EB87F604508DC25 +:100BE000B377E8F130B8599F1F72409F9F8DBC6169 +:100BF000D8776F9717D0E7871ED1E75907600BF0BA +:100C0000A0DA389EF68F701F71029EFAFB55377E70 +:100C1000EA6F9F3C6502CA171B55773A94F75F52FB +:100C20007CFB60C89FDA38DB8D68AE547DF37F08AB +:100C300038ACFC78FC113C0FCFB2E63F4C003CCC0A +:100C40006959A7999DB86E3DDDEE33097A7D9EDB2B +:100C5000D9E6F9F5E557EEEBA5028F2C2B949E8C87 +:100C6000788771EFF4C0846AEA170F3D094766651B +:100C700011103AC0EC86E6751ACA6D571FC7C7E552 +:100C800041BBC789F0281DC1CB6EAC1FCB4E0C8574 +:100C90007FACF9ED789C77E9C30AC90DA5BFCC7C80 +:100CA00003CF81F63D336EA3F4CE425ABFB4E7CDF5 +:100CB0006D51029190778C701E688376B3FD8A1B0C +:100CC000E75DB6DC1AE467F0BF8A358679AC0F2998 +:100CD00087F9CF3D70E8AF0AF45FB951DF6E1EF0BF +:100CE00059E45F555BBFB5867E977AE38D2D9B55A2 +:100CF0005CF76C397FDF2886EBBA915765BD847C41 +:100D0000731233706E4CEB5DBC2315DBADE7ED80E9 +:100D10005D96E27A6BED9A13D75B6B63810898C797 +:100D20009148CDE380EF973644921D6D8E15E4C94E +:100D30007C4A59583EB6734763BB4FDFE7F6B4DAD7 +:100D4000388EEFDA4D0AE951B568FCC4FCB33C3F7C +:100D50008F05681D48279ED0F5F9F579D6C4F5AF03 +:100D60001A73E010C2A38AB571FD09F0E891F0038F +:100D700078D5C03A8FC6A2BC6568CFDC5E1C77818F +:100D80009DCB4F0B0E7C6B0D2D977AA0D453A57D78 +:100D900077534671388EB342F13C618379AE10F2DD +:100DA000B56F5D18D1EFCCCDFCBC01393603E1B293 +:100DB0007E5DA21BE58C99209787E1BE99174EF5C1 +:100DC00040DE25BB4C07C8D55B5C58BF3980E7C601 +:100DD000FA475D244783FC4B70E9581BE6DFA2A06D +:100DE0001CCCE598F5EB32490E7F559E536BB9DC70 +:100DF000D58D5C4CE5AC0F97E33FC2A584C8C15FBD +:100E0000F4F67E9ADA3BB8AE8A659E443C772A2691 +:100E10006B26B457B1CAB86B921FB60939B203D664 +:100E20008FEB38A914BF650A9147BF16E7C8F031A8 +:100E30009EEDA29E1BEB5598263D740B8EF798C92C +:100E400089E375C1DBE3C9C0799C5C17968F743662 +:100E50007C0CB7171DCBE3FC3DE23AE6F1E3799A4F +:100E6000C6FB6569265D9A100EF407FD9C2CE0F622 +:100E7000EAC8EB8AC94E076735F179E33AECA29FDD +:100E80000AADF83F6FEE663E123E6C1C97174E2E71 +:100E900054B6F079017E213FFC9130B2EF9D14E70A +:100EA0008F8433D0CD30B2D30B7EB54ED0CB3A0B3E +:100EB000A703DF3CAE3F05E985113DAC177AD64C60 +:100EC000815FB696CBB5402F1CCE6B1305BD30F6B7 +:100ED00037A487022797B3AF515F02BC0F48EB7D61 +:100EE000A5DE24F1CDCCFE61FFCC2F52BB7FD73ED7 +:100EF0001F9C9F552F3C1AC5A0DE697353BC1BDA9B +:100F0000D76C5B11E581F494D917E580F14FFBD5DF +:100F1000427F37F02E4D9376658F5D01FE331FFFC4 +:100F2000E94479E7E189B8BEAFB6591CC81216EC9E +:100F3000B092FE347FEF3C92B321DFCEF3AB3E574D +:100F4000317F406F3FAFFAF9A3F14E82B72FC994BA +:100F500080692089413A7FABC51D40BBF407AA1BBD +:100F60008601B9B96325CECFD81EE77119F0BDA0AF +:100F7000592DD5A2AF2C5F20F8CB82BD0F7F8E7686 +:100F8000BD05067B7DA5F05B18EDF593D2227B7D38 +:100F90009A0DFFB89E5D8F7210C0C51DC07D0BF30A +:100FA000492732E1F6DEC6E71ECF6D477961EB3B9C +:100FB000514A4ED05E2FFD199DCDE59B5E71F6BC6A +:100FC0001F2F08BB6D105F9C6F390F28C80340416D +:100FD000E7698D25107513C0A366B385F84CCDAEB7 +:100FE00067B73F8974F6272B9DE7D5BBDEFCC38D21 +:100FF00028EFEEB1F42AE2CBB02BF1413C2D707218 +:101000003B99C44BD52FDFD49C83F9F725B141FC24 +:1010100054EF39A4B1C157C2716CF321ADCDDE0DCF +:101020009E9ADBC7939DE8B9AF35DC07A75F53589D +:101030001FD795ED2B37BF1985F218C209CF258927 +:10104000AF2EFC19EA43FF135FB98EEA3950AFE8BF +:10105000097FF97876A05EBE3F92C5C0F8951F590A +:10106000FD4588D7DD8BA3701D9F99EB389D3FBD53 +:10107000221EE5BA4A8B2FDE4129FF5EF9CCFD44E2 +:101080007F7395BA78470ED177A28964065F22AE46 +:101090006FF6C669B4BE39CC4BF457F9B45AEC8735 +:1010A000F44B332BDCD3CD3EF958F0A5CFB600522C +:1010B000617D9FA1DD06F9C6EF54A1E72EA4F3FBE5 +:1010C0007EB156C61651FE4B21B7ED4E33497B9685 +:1010D0002D545F5CB075552BE2E74CB2A70FCE13D1 +:1010E000E0E013F052BE857ED5DF16F4E1F8614EE4 +:1010F000F370D10ECED1B1F81DEBB75A3C68F70EA4 +:101100006927F4393EFE7D627C987738EAAB9FC54B +:1011100073B9DDB8BEB001920FB056164A5F3DED0F +:10112000FBAD0F125D7DF101E72BF3FD930AA9BC26 +:10113000D512E883E5FE435315E20B5616E86E5FC1 +:101140006FB5887DAD2F87799A9550F8BEC6E5D0EA +:101150003920770542F671906EB4E0775AF7236232 +:101160001D6DE44F937EB8B9821F18D76DE40F1F31 +:101170001AF8836CCF3676EF070AF2051F8D5B03F2 +:10118000E709CA19357FB2D2B951B3CB528CF039C5 +:10119000BBF3F01F66A21EDA2CF7B19EDF1AF771BF +:1011A000E58BC3BADDC767D7E475BF8FE17BB7FBBB +:1011B000788D42FCED7FCA6FE1A423BB414FFB75E4 +:1011C0006E0FFCF6DB34E11715F0FC92E544DF848A +:1011D000858ED2FE841F035C253C8DFCF3F1342701 +:1011E000C1D7C83FE1EF03160247093F499F8C79F9 +:1011F000699C2E3A96742AE9B88B4E8DEBD5C3D1F3 +:10120000587E18F913CCA7F8650BB79FB528246F43 +:1012100043BBB792AEA37DEAA1E38F35BD95D42B36 +:1012200034EF37E49B0DF53D867CB1A1BED790AF7E +:10123000D3D5AF397058E3FA414057CF5A7F3BE9D5 +:101240001957CA117EEEF7D9FBB9E643BAE8D7A120 +:10125000215FB42C63BE4894770FAA24EF5E7476A6 +:1012600044A15CB2228CCB6D171D221FC3F31DBDA0 +:10127000B595C817E5F78E306E27B958DC111513F0 +:10128000A2A7B7B7A851688F6DF3B3C2EEEC28647C +:101290001905B8B6B19ECAB9FC56A0DA53EAD11EF8 +:1012A000DAA4BA814C58C5D2BBA228EEA125ED8E96 +:1012B000E9F07DF6DB2A850F5C0CE77605E6F3980E +:1012C00031EEA09CA3909D62BEC746C2BACA5B78AD +:1012D000FC41C51A3D7EE7D8A746079CC877F47144 +:1012E000027351AF4B437D4FFFBD8AAD217AAB32C4 +:1012F000EC0BAFB0D31AF745D900B12FF2589EB01E +:10130000C7909F6391E0D7056ACE1DD301FE178F6A +:10131000A8CC0AF9CE1695ADC4F5EE54C8DF830EFD +:1013200001DC6FF3615FE27C247CCEE1BEC9EC5945 +:101330002E39F7D227C37F8874B2EFE3DCA7203DB4 +:10134000B7EF4F19AF627EFF1F533E6657D61FFBA4 +:10135000DA5F67211FBEF89A95217D5F7CEDD72962 +:101360006817BCF88A95F4E58BCBACDCDEFC5AA49C +:101370001FFD911793B99CDB78F0EBDC363A779739 +:1013800013BED60ED0B8DCD4F2F76368AFEE6C8132 +:1013900055A13CF15A04ED9F05AF84913FFCE2C199 +:1013A000AF8787C64DFC4FD723FDDD1723D9F41730 +:1013B000916E855CBFE0D51B9E457F6EEDDE435A86 +:1013C00039948FFDD57FE722FFBCF82297932E58E2 +:1013D000DA9E415BE386AD373C624944FB1C74D620 +:1013E00017D0B5ED81C9B84FAE840B87C3458003D4 +:1013F000AE0BE052897CBF2778BCF06F0B8FCF67B4 +:10140000717E763D43FF6F102E0AF723B444FA6DC8 +:101410000AAD9F7F7FEDEB5CE437575BEF6F70BDEC +:10142000BDFFFF59EFD97F5BFC727A5F3CC049F387 +:1014300033D2FD9574BDFF3F28BF3BD24DF3BDC6EF +:10144000FD1E91FEEFBAFEFF1B7C0FFCB75DEFD5D2 +:10145000F0FDB6C077A403FD8A170FFE770AFB0ED6 +:10146000EB2E4CFF77DDD7FF7CDD525E1FA3BA8FDA +:10147000E441FD7758F3076E17491FDDCA1DF707D2 +:10148000E3EF483F1ACBF8393DD6564DF2E6D87E09 +:101490006B492E6E64F9E487F0F553C91F43C117F9 +:1014A00000875F27E4F9C99F640EF45B0CF93149AA +:1014B000B5149F65D41BC7864F284479F4F0529821 +:1014C00017F47338D2E4405FF1B87E6AC09A4B6972 +:1014D0003BA66FA5DC7E04E5967176BDFE74BB412C +:1014E0001FBAD5A92F2F642FF642FF59618E85F9B7 +:1014F000613EE3B17E88DE3825DD41F0BA95352DB9 +:1015000077D8BF3B9CB6A5733DF94A38FC73B85DEC +:101510000127A1279B457D23DCCCF6875AB19D99F5 +:1015200081DECBD74BFAB2D47BAF064F26F469B33A +:10153000185AC2D7DC8FFB4943FA25B848B87F5701 +:10154000784B3C19E12EE12BE166C4433D1AA37AA6 +:1015500007E1DFCF9C67C67D77B390E3C7996378D7 +:10156000BE5FAB5A4CFBD1CFE9FC0BB719E593D169 +:10157000F6188AD764CEE418D46751C4FC3609E45F +:10158000CE1131C315586F9299F9ACA06FA20F8D8F +:10159000ECA80F9AFDCB5C380EB7D7269BB95D1A25 +:1015A00076B72F3C9FEA7B34C897FE6C2EF340FD44 +:1015B000D224E656787D161D4BE1684CC5B82C4800 +:1015C000B15D6934EFB7B40FF32FE3F824BC0CC05E +:1015D0003495FAF5986279FBA87C6AEF33F1F61E30 +:1015E00033C67BA571FB7AC70A2BE91FA5AB9233E3 +:1015F000907F148DD1DB8D9333B89D59A6AB33F812 +:101600007E574DEE04948BCB960F247D480D2FAE64 +:101610007D09EDFDBB23881E4B57DE336118CE6F6D +:10162000779C1BA77766E29EE1BCFE8CFB3F84EFB4 +:10163000DE1D61F47D6786F7683AF4774671CE7AED +:10164000093E944D3BAC25C010DEE649E7D1FE379C +:10165000D1B7E73DF4334E9CAA52FD898CC73DB209 +:10166000E511E48F9EE0FBDC9C00FD4D006503CBA3 +:10167000DBC31C290B61FEA5C2DE7B52EC17359C37 +:10168000795FB4E3BC923352E1FB04D67D1C706AEF +:1016900086A83F46D988FEA1FE63B93D5ED6C77EC7 +:1016A000B0DF2C018F8BE9DCEE24F30057AA5FB189 +:1016B000DADA9E867ACF6A4B2013D25959632EE12B +:1016C0003A8B52D9F80D08F70754B685E6DB514A34 +:1016D00076EEC82C27E2C10B244DF1854D2E27DA7A +:1016E000BDDA473707D03FD0FE84CBDDE8242C534A +:1016F0003C8ED4B3DA470706A05DBE238FFB198E5C +:1017000039DA22513F2CB7DB283E47C6F5CC76F0BC +:101710007DDEBFB16DEDF5A8773EAABAB7407EF683 +:10172000A3DCEFF217BBCDAFA0BEB69EEF53B6461B +:101730001FC7C31C6EB2F794378DD650BFACB07BB9 +:10174000345C6776A6372603F7D13700BFE118C7A8 +:10175000C96833943695529C891A05FB0EF789D9CE +:1017600019857AAF310E688188FB91F917C2BC7D6B +:1017700033004E65D1CEDD482FC7EBD3C8EE3943D9 +:10178000D05D11C631A27FC2DC9688F379078DB88F +:10179000307E51AC23C34EF41CC6100EED16470626 +:1017A000D277FB8A3013FAD98A9671BA867D66336E +:1017B00043FB07CD2C1CFD06A7D279BF254BCDC519 +:1017C0009B21DFCFC6CC91B148577944D79BB3BC9E +:1017D00017D3A1FF533F6223901ECAD7AC23FF8AC1 +:1017E000A40B666E1D1707E39CDAE6CA47BE29E91B +:1017F0006873D6983C844B173D4C55880E203D9419 +:1018000046F430793896178D090C589483FA680D90 +:10181000F3E0F99EC0DC282774B20EF23F76DA3589 +:1018200027DAB9243F917C03F0EAB1C507E9603BB0 +:101830009CF7660B633B1A6C943EDFE06066E071D8 +:101840003B1B1228BFBBC149697343167D7FB1C1E1 +:101850004DF9BD0D2328BFAFC143F9030D8594BEDB +:10186000D2504CDF255F02B8101F927C45F2A37264 +:10187000BBD68EFE48C9978C74330BC03B2A9FDAC7 +:1018800013DF93FC0ED761CA0FF22389DF54A5D86A +:1018900097E0423ED63603F15FA09EDBB51FF5F21E +:1018A0004ABB9BF474C6F95E27D02BC2254563075B +:1018B000D0EEDAB8D0D3BECA1584FFDD950A3387DF +:1018C000D0D53D7561CC1C726EDC5B1FA3CB97D469 +:1018D000FFFECD3ED0FF1DBDBC55487FC77EFCE955 +:1018E000D37F84EF9B7E7C261DF10DF3D8F6388ED6 +:1018F000BB24BC6B1EB1985F6E217F547F6907814A +:101900003FC44B19E3FB6DD38FFF46FBBBBDDEEA43 +:101910004479F823C413C0F5CF024F65F556825FB2 +:10192000E98A13BBF6E33E5FA2119F2B5B2EF6E123 +:101930006A8067887FF77822237B0448D314AF7EC0 +:10194000FC475A2002FA3FAEF0FDAB805050827146 +:101950007FAB7F7D14F7BF527F84FCE75E9B3D40E9 +:101960007280CF722EB43FA5FE2DAAC7DAFAC5A0A9 +:10197000BD84CEB15BD0EFE8D19CB06EA469C45BEE +:1019800059D6EB2C11FD264D8A03B74C85F85EB174 +:101990005AE1FE49B33B612AC87D8F64A884C7F72A +:1019A000D2CDB42F733298885F68A2F349D26BC549 +:1019B0001A6887FBA2294F9B13C287CBC4F7F22C6E +:1019C00013A5F2FB16D16FDFD579D3519EE88BE5D5 +:1019D0003998E64F47F8F6B58F372B21F8DF986135 +:1019E00016F3E0E3E7E06683FF7B282B559B9D839E +:1019F000F8E1E7971CA72C2B7F25C67196AD198DB2 +:101A0000DC97355ADC09BDA0DEB6AE7E1C5C5EB04C +:101A1000F178E59A1ECE0F693F3B85FFBC81D64D1C +:101A200076DDAADDBFD88D71FC551F5B09BF55431C +:101A300044FC548E7FF8143234EAEDD5E37EF1494C +:101A400014F91FF6F2B84A48B93D754925B7BFBA2F +:101A5000615F75E3FF7963F7C751DDDAA9F7AAD7AC +:101A600064A75EA07C1385F2835C4FC1C12FE3693C +:101A70001ECA65F2FF2C38B822BEBB7B37467B7589 +:101A8000973D5BD8ED8CE5467BDDD10CBD1D1B047D +:101A900044BAC725ED754CCD8946FBFE97E29E47BB +:101AA0004F7A8DB46F2FD8009DC4C1FE343BA3D1B3 +:101AB0005F75B10779DA99C9CFFBF3C21E7E71A7B2 +:101AC0004A7ACEC59D91B49FE6EFFCD95BE83F9C76 +:101AD000BF55A169D4B256821BC093D942CF318C75 +:101AE000378BBB72DE9DFEF4683C47AA7F11598795 +:101AF0007436AF59F16C83F974DA9CD1BD43E6F3C7 +:101B00008DA0B36A6BF37082B39C3FF2C5DEC17ADD +:101B1000F35A7E46F663A87781E4A0172218BFFF28 +:101B2000D1F11ECEF3ECC6A16EF4FBCD6BDE339F7C +:101B3000E4889D110E1481CE883861D98F2D938F42 +:101B400067CBE472CB59E10F3ABB5B257E86F3C4C9 +:101B5000FD7546D1C7E345897651026E2FE2FEEE50 +:101B60001DAC3FAFB93D6A00D4FFECC0EF294DC8B2 +:101B7000E47C609EBD3517CFDFCFF646903FEBB3D8 +:101B8000BD4F8D7F15C63BDF3CBA17EE07D97F46A8 +:101B9000A685EA9FDFA81622BC989FC7BDD4227CE9 +:101BA0008786CE336EB3CF15BAEF78DCCFD9BDBF01 +:101BB0008C32E504F1596BF3DA125371FF9416235A +:101BC000DF38A538A99E65EF681FDE635AD092C73B +:101BD000909E69DF2552FDD5A6907A9AC54D4CD1CD +:101BE0007C60922789E02CEE21897879BC5747F7F1 +:101BF0008A26D9C83F316B88F3AEBB914FBE63E1F3 +:101C000078E9E77C1CE5B759EFC751DCD42297F39C +:101C10002E9CFFE2DFAA14EF3B6BA8E003096DC323 +:101C2000306EB166B5C23CB0CE7617971B6AFC2AFF +:101C3000F342BE2FD0830F4031313355F0D34006ED +:101C4000DE077CB2D2E4D1E0FC3BA6319F8A76A3CA +:101C500017793C734D2A8F1B7E12E91ED29AD84009 +:101C6000461CF4774EE0B366722003E3246A5E4CB0 +:101C7000A43889731AF75BE277F493D6E4437BA820 +:101C8000D74BC4C362FB9810FAA929733BB19E1AC3 +:101C9000EB76E6D971BE8E0B24C7BE14C9508E35C3 +:101CA000ED8FE4714E3F0FDB620DC15399A0B75E1B +:101CB000028F6C268F877C4CC4633FB62DD18FFA80 +:101CC0009BACFF98C53B03E180EB40F97D9ED69429 +:101CD00081F2AD9CEFBCA8269AE73941DFF3C29BA5 +:101CE00078BCB4C6E329B13EE6DB2D8CE2B83B9E5E +:101CF000B3523CC999C4D67D38FE99E706325C7F61 +:101D0000BBCB3FE7009583FC0878AB7ADE1AC0F5C1 +:101D10009C7E8EDB9B4F5BB83C767A528213F156E9 +:101D20003879C32CB2C76CB52A88F7D30AD312B05E +:101D30007C5B6FB70FDB37D4539C7415B009BC8F35 +:101D4000036921DEAB39BD6D20C5879D7E5BC51B58 +:101D500051F87D357EF7B2A6593F4078ECE0FAD3D2 +:101D600099E7FF3E30F41E9A4CABB6EAE3E0249DBF +:101D7000C8F246B12F1B059C5765F273AB36A2F92A +:101D8000B1545A27873BE089F43E38F8239FBA0EB6 +:101D9000E320D215E41B4F025D3D8576851D5CBFB7 +:101DA0003AB3D34271E155FB233D1477B6EA7A1377 +:101DB000C541A85C0EAF3201F82855A8DFAAC95961 +:101DC00074DF17E04D7A6CC736558CC3981DD7BDAC +:101DD0009DC7F916A1AC48E583A9FCB4C89FDE37BE +:101DE00098E43AE8DF83F795AA7EF0430EC7299579 +:101DF000EF32B263D888BFD674F9714646E379579B +:101E0000BBEAA668BC07C8DE5719CA2746385D3248 +:101E1000BBFB205FFD83E05FD5FB9ED6901F548BFC +:101E2000FB21D5CF2BDC9F0CFB0CEF4956AFBCE957 +:101E300071A2CFF72C2C1DD673AEF96751A1F8080B +:101E400008BED6555F7353FD6AA88FFD54AF7C273B +:101E50008AE6B3DD427126463C5E73FBE7D56B6ACA +:101E6000DF451FCDDC8E72C5FA59EB7F7C0CFD7F00 +:101E7000B133CCEDA3AFCD74AFECACA5790EAEFF12 +:101E8000ECAE30E2476763387FF80CF8A72F13E712 +:101E900071FB4F292EEB7753E83EDC5CBFBE5F3908 +:101EA000EE9BC8B7319E24CE1D8D717DB5EF73FEBC +:101EB0000678B983DABF6FA1F6C6756C15FCBE6BE8 +:101EC0007FEE8A207A38DB97E3E5ECEE4C3A8FDA46 +:101ED00063389DC37C53F0FEDCD95D9979742F0D76 +:101EE000851BA0872AA1DF9E8D694E718494B75B04 +:101EF000849E16809A4837D806E4BEAA7A2E575593 +:101F0000DBD6507C08C6D50ECFA734608DBD323EDF +:101F100016E895F4C77E597C7F311C2F5EC46F9301 +:101F2000BCD3AC21FFF60AB9B066A731BE9697FFC5 +:101F30005DEC4F9C6D2F19CF8B74E85328CEA47A9B +:101F4000F9C27948E7D575EBEEC67D26E75F6D6689 +:101F500085A887B52B2ACDA33D8CDD3B19CF8DD02D +:101F60007142E4362DABCB9ECA1CF124AFD2391698 +:101F70009EE5E474832726DE135DAEACA1715C524E +:101F80009FE5EB927002706818D7D73E5A94F7B06D +:101F90006E394FE3BAE57C52B2B89DA4DDE5FCE9A9 +:101FA00048C4F36F54BA4F7BE99BA1D1B1DDC8653A +:101FB000C1735D0BC6B7C2FCB391F6D0EE92C9ED0A +:101FC000A8D5183F0BF3CCD8A88FEBCEDAAACF0F49 +:101FD000DAA9CFE7ECD5E7735BF479F71BFA7C1C41 +:101FE0008EDB9BEBD9787F17F56C4C51CF765AB9C5 +:101FF0009E8D79D4B331453D1BBFA39E8D79D4B35B +:10200000318F7A36E625BC51DFC63CEADB585E22CA +:10201000E05423E224110F48EFECE530DD7D9F8B87 +:1020200007F93D0EA003BE6F6668B46F9EC41AA484 +:102030007770BB52DF293627C6FBFA62BDE3B38651 +:10204000E17D8FD695898837731BC59D2E7885C70E +:102050009DD6E487D9D1BED1B6E2B39518CE393535 +:10206000D67B7B566FBCCFD9B11DE15B5B7F98EE11 +:10207000BDB72D75BE7F0BC71FD95958652CC94DEB +:10208000A578CEC5F68C4763DC375BA38FF336C6E5 +:102090007D1BE3BD8D7420E5BD4D968E44E4EB279A +:1020A0009EB3ADC1F99F0813F74FA6DB0CFE7E214E +:1020B000A7AD55B6E0795D9315CBFD4947403EEF9E +:1020C000E69C9569F9E5A1248777E5D72826BA1714 +:1020D00097104FE7D06231A714A5A37D15F2B97907 +:1020E000263A372F815C86E35DFA4025F921738318 +:1020F00049B79E81FE701D7D65EF8835DC6BE8ABCE +:10210000AB3FE440AAE15EC3207D1CFDD4A587500F +:10211000BF9FB266A8AE5E45F14D06388A790BF9CD +:10212000B502CE0F0FACEFC9251B5210BF8BE77560 +:10213000B6AF42F9F4A530BA175689FF0FF86225F9 +:10214000F489F7192BF78AFBC0F5FA73B85C9C4346 +:102150009566E673C406E9B0D2C13C31D07EDEA0FC +:10216000D6DC00EA156FFF7EB82315F58AD17D9085 +:102170001FA5583C14075BB3273D6629F4BB22CD4D +:10218000FB14D2DDC9A6C33F29C1F3700FD7F74EA8 +:10219000ACF96514C589097A4BB138C211EF9B9B24 +:1021A000787C1CDAC7D4D8205D6C6E8A0B1F600F58 +:1021B000AE374807DF109E003FDC8E53F93AF93DF9 +:1021C0003A9BC57A472B3E94A7E5FA168973850D8D +:1021D000E0FDDC27F227857E21D7796EE0A15C2720 +:1021E000DEBF683890A2223F37EDDC9E08A9DBEA0B +:1021F000DD87FBAE7273FA1F47C238551FF2F5FC3C +:1022000065FDD8A81B50FEDC657117417E55D3B320 +:102210001AEAD95566BF46F195CF6DD630BEF87B28 +:102220003B36D3F7393B4A299E722EAB23FDF394FC +:102230007C7740C0A3728CB2D101F34E1AC8E5BEC0 +:10224000CA70EEBF03F9E84D7CF7E3D20E250FE329 +:1022500078A616EFD14AE1FBFB82CF18F749E7BB1E +:10226000530A7A133CF87D8D0F1968F16957EE8B8C +:1022700029975DB42FA65ECE26BD6C5A6020D77F0D +:10228000730CFAEFBBFCDD85CE16BE0F2AB540AF4E +:1022900029B84F5EB3909C5B0BE7CD887CD4AB191B +:1022A000BB11D2E291AA8E5E178C8BD0D1F374163B +:1022B000B24FA0BF3B316824243FB5284D57FFAE35 +:1022C000A9D906FACF0F96131FB95177BFAE7689F9 +:1022D000CFA9909C3946FF9DF13841C66ED3B5AF6A +:1022E000659383F590BEB77239B8766FCC16B4F7A4 +:1022F000559AB8FE34DDCBBFCF3FC0BFB3E94CB772 +:102300000FFBA7B9FFC8CF450BF905A43D7D3AFEE9 +:10231000BB1BF8C349DE753F1CEFC5A33D42777F69 +:102320005AF80371DE88875A6137AACDE276A35A3C +:102330005FAB86EF0E00FCCD71B154CF1687F191E3 +:102340004D0AD915315D42F192FA382CEC0FE318A1 +:10235000E71F514B719F18CB2BF1DD1FC4EF2B3CB6 +:10236000AE74EE06631CE41AF247CE477B5008DEDB +:10237000EE1EE814F28A7F655F845F919247F72230 +:10238000771ED230CE6EEAD4983CDC3746FA927C87 +:102390001DF633E9DF9DEF1E26FAEAAC3413FD5E2D +:1023A0000D0EF33DDC8E6AA4BB39AC55C37BE273E2 +:1023B000F62A6ED447B11EC2A32FD2A3011E71B15B +:1023C00057C241C2A70B5E7B8D716E1C4E730F28E6 +:1023D000FE40377032CEBB27B8C9F5CCF17AC7239F +:1023E0005F90EB9A8BF3C7FE61FED8BFF443B01148 +:1023F000C6FD9946F6A9F9C53C3ED6480F932F7302 +:10240000BBCB9D97CD944E2DD2EF476C87FB62DA04 +:10241000E5782AFFAEF4321FE6C9EF3F5D1B9DC889 +:102420007548BE1BDC0FFCDEC0D5DE0532DA1DE7C9 +:102430000E14F1C8C3D8305D3CB2E0ABC6F6C67826 +:1024400064290718CF97D24813C54D76DA5349BE91 +:10245000907CD62BCE0FEF8A2FA99E17EAF1D9C414 +:10246000EBCE1BAFB0FF2D8A4CA5F7185296C6C510 +:10247000239E4AC31C147F5FBA54A5B8E752A8E74D +:102480000C914F562E4F4BC1F3E2F88399CFF84091 +:102490006E3FFE40AFF81130CE8915965E3667B0BC +:1024A000DEF115052918A771629D75BABF1B78ADBD +:1024B0001BC8CF87DA1F1FA5F3ECBCE9DDA8E9D064 +:1024C000BE66C54B5118E65FBD829FE303D3BC4D8A +:1024D000037BE379BE79BB03E1E7D89C8B76DF4DC4 +:1024E000701C607B293F54AD28E883F245CD3F0E38 +:1024F0003FE3C07BD64B2DF1287F9EFE00CE438567 +:10250000CE33921B4E854117E44F8B243BC2298565 +:1025100079D0AF74CE74E8AB55A817E635670420C0 +:102520005D68F56E1A88F2FF8A67496EA97A686954 +:1025300086AA62BFE9D1DDD94D64BA5D9CDB28BFB4 +:10254000638AF23BC6C9A0FC8E7994DF3145F91D40 +:10255000BF2FD8A097FF5E10FE42694FEEDFD891E3 +:1025600087FE3BDF18965547E7AD3D0BE5F5C54ABD +:10257000B81BF9D162949530FF4918E9B16C6B2210 +:102580003F6F059EEB6DDC6FF4B5B89F7B7307C89A +:102590006421F479CB651B0BBD373B9AC5E8F26328 +:1025A0006D89BAFA050E97AEFC7B090375E5B73A5B +:1025B000F374F9DBB36ED0D59FE01EADCBDF31E213 +:1025C000565DFD499E49BAFC94C219BAFAD38A4BAA +:1025D00075E5774D9FA72B9FE15DA8CBDF5DF98067 +:1025E000AEFE3D754B75E55F9B4023057A6941BDA5 +:1025F000CB8AEFA7D828FDBEEA3023DF58FC9B74B6 +:102600003BE27BE458535D77F6FD53421E4ACFF61A +:102610009C407A4916EFE3248B776EBE1AC8F19975 +:10262000C480AA48DF6D4D44FA35D633968F8C7836 +:10263000FD92137058FC7CF43433F08991D7BF3E7F +:10264000340DF20F3E3F9EE76F7AFD97A9905FF73A +:10265000FCC3D3CCC0A7460E79FD129627FCE276C8 +:102660009E9FC248F4787AD0DFA7FA70FEB7A4AE76 +:1026700071733B49B7F7CC658A70C0FBDA08074C29 +:102680000340BF98BE0EF48BE91B40BF15C09FDE10 +:1026900002FAC5F408E89FF8FD3F41FFC4F45DD09D +:1026A0003F317D0FF44E4C5B41EFC4F4770DD329DD +:1026B000FDA0C14BEDFED05049E9D1863AFAFE515A +:1026C000433DA57F6EF0D1F7D841D28E1160BAFBA1 +:1026D00001E867447FE201CBB9503FB0F4574AFFAD +:1026E00064631D6B8B407ED1668EF9D416F43BF685 +:1026F0006C0730B34F43E4B168E6491E44E3F77317 +:1027000090DF487CFF557F6FEA20E03B1FBAA6A40C +:102710000F55F1DCAA7B13DDB21F8AFBF5C67EBF25 +:1027200012F4F1D7419E4C6C27FDEBD2BFDD15377B +:1027300013E27F3785C4EBD05F48DC8DF483CB3860 +:102740009F9B6DFC9EB1F473CB781ED95FC1178C33 +:10275000F8C3A8D566925F22CD2C80FDCBB89D51E1 +:10276000B6E63C8C63185563A77BB57DE0BB964FFE +:10277000F53C2AA45BFF0AF573837EF53E62FE50AA +:102780004EF32FF8C24B76D85122AE00DBDB78B97E +:102790000FDB8F42DBC27594127F7A1AEFEDE607EA +:1027A000FDFC583F82D70F607F03FE06E34505F727 +:1027B0004D726C731EF2EBE4F976BA17BA7174803D +:1027C000DEB322A313C0658AD49F6C222FFD793B10 +:1027D000FA901D69ACD8EBC39CDE1988CF62ABE3DD +:1027E0009308DA6769C9689F9C24E4E77F82B75938 +:1027F000D84EC253E245E251E223247E8AF0D01340 +:102800005E8DF834E251E2AFE08B205E10AE57E20D +:102810002D8857B4E7FEBBE0ED3A337FBFCC5A6357 +:10282000A377D1AE86C77B3BD8F868A8F295D3FBD7 +:1028300015F2CFD2CBCEB7305FCE468F47D4CAF297 +:102840006F7B28F77ED161890EC1F7CD02DF19AE0B +:10285000EEEBCB7AF23D06D97F410FF5DF0993719C +:10286000171E7BDEF060FCE3E2020EFF42974AF0A7 +:102870001F9B3397E46466E772A613FE43BE34FEE3 +:102880009B627AD7F24BB6133DB76C7C2FBD7C5A56 +:1028900068F05BDF26E4D2DB0C72A951AE7C71904C +:1028A000F067BB98EB3BBE57F932E76BD7FA5E2572 +:1028B0007FEF749CD8674982CED29C2A1B8974C44E +:1028C000BC744EBE81EF9DE6E2BBA03ECADFCAFCEF +:1028D00094DECE0274BE4E00468CF93B18A37BE416 +:1028E00087232696E0DDB8B143C70EC0EF21EFB2D3 +:1028F000BD87F39BAF7AFFCB11F22EDBEBE39C7429 +:10290000BFF2755B1AC95FB80F2D21F6C0B7E17C25 +:102910001A00E7C76138BF307D13CEAF01B0DE5F6C +:10292000C3F985F9DBB296326C37DEA98FDB91ED06 +:102930006F778C05C5A467F8DD9EFB723F84EF3B83 +:102940003199E3D07EFE4ECCF5E370BDEFC4F43197 +:10295000F1D4AA513A78FF80EEE443B90F82E38DB7 +:10296000A7F18CF095F034C251C2F75F80E7E5EE35 +:10297000E0F995909F3B6DBF8F4A4845FF5D947885 +:10298000C7F237B92AE44FE3D412315EF5269AE74D +:10299000A8FA1B987928F96D7210AE35360E2FA360 +:1029A000DD8A6DED630A8DDF3DA379C3B2619CCFF3 +:1029B00036AA746FFCFC8B61648F3AE5E7F6B6DBF0 +:1029C000156F5436CCAF4675AEC1F747D93BFC9D69 +:1029D00033F6CDE194C991DF814EB7F2FBF635B6FF +:1029E000F1DDE251EA53D12E0FED7326DE8B9472A6 +:1029F000453F2B7F9740BE5FD8939C313C9CF3C1F1 +:102A00007E56CEB7255EA11DE593A09FE1C0E7925B +:102A10007E1A4EFA45636F4F06AE4FDA113AFB4508 +:102A2000F891DF8E0A64D3BB5C8547548A277E5DAC +:102A3000C4777D2FBBCE9E0A789A94EE756793BEBD +:102A4000F98D8A7CE65D58671CDA1F8E0CB593FE03 +:102A5000F81DF5D011D9825FE4B25CDD7D35497790 +:102A6000AA9DE2773A3FE0F7F116BDCDE33617F5C0 +:102A70005629FEDF1817378A65FC14ED8D637B59E4 +:102A8000DC7E6790BFC87780AC0926E60C91B3C3A3 +:102A90009CE1CC19329F88AC585D3ED2DD57573F40 +:102AA0007A44AAAE3CC63348571E5798AFCBF72E90 +:102AB000BE5157BFCFF431BA7CA2F7365DFDA4CA30 +:102AC000C9FA3CEE3B807B72DD4C5DBBFEF565BA1E +:102AD0007A2E5F95AE9CF93CAD59F1C8C7F95FDA23 +:102AE000EA45BAF2A7A20A79FCB87D0EDD534C6F15 +:102AF000FA81AE3F89DFA4388E5FE6E4E7830FFEFC +:102B000023BF85C0734182FEDC18EB18FD8683521B +:102B1000BD5D23E92A71500FFCAB7450CBF474D027 +:102B20008BC7F114BC3DD489728C11FFE88F085D0E +:102B300027FA2342E182FE88D03CFA2342EBA33FEE +:102B400022B41CFD11A1E5438FE8F13FAC558FFF86 +:102B5000EB8F8EF9A778BAA14D4F0F463CDD744A32 +:102B60004F1FA3BCE10497B1208F21BD4B3C4D8783 +:102B7000FFE89C67C5D16837B88579E85EC0FF1665 +:102B8000BE5EC816F62381AF2FD99A61F8CEE5C58F +:102B900052CEC77B3AE79FEBEF7909F9EE09E4F3F0 +:102BA000C3AEB403C87852DF188E4FDFB130E2579E +:102BB0005F9BDA22F1FCF8BEDA4676F944D6F126BC +:102BC000BE3FE3E8E53D84FCA80F460F40F993F3D0 +:102BD000EECCC3736ED6AFAC2928D7CCEACFDF13C7 +:102BE00064396DF44E8B9CCFAC241E7FF476B6E036 +:102BF000D36E1E87F46E36B7FF44BA1D14075D9A74 +:102C000023DEA131B3945983910EDF0DCB443A5B9F +:102C1000CFED5C6D1627C5B5F8801ED14F89F23611 +:102C2000CAC3C9421E6DFC93CDC6E98EE9CEF781B9 +:102C30007E9B2E0E377B8743971FDC9CA0AB3FE427 +:102C40008053579E17C8D2950F3DE2D6E587B58EC3 +:102C5000D0D5BFFEA84797BFA1AD5057FFA653C51B +:102C6000BA7C12EB7802E1A9E6A4123CFA2BC20E60 +:102C7000E0E47899F5FD78BA4F23F5081997ED153A +:102C8000746CD447FA6B5E8AF36E4C646EBA0F6252 +:102C900013FA20D3EB295E11572DE579E6D3C755FA +:102CA000CB78EA2E7D46E82F529F0889A7F6E0FCF4 +:102CB000653C7517DEC5FB9246FA74E408BF906167 +:102CC0001DFD357EFFABF1018DEEB1C8F919E73579 +:102CD00043C4036EB375FFFE504A0EB71B6C4E2DF6 +:102CE0008ECF817ACFC0F144F0BC623C779B0FE07D +:102CF000DBF823CDBDCC79F5F1660DE1EB29C17789 +:102D00005573E89D4EBAB726C7CD15E3F6CA55BA36 +:102D10005DDFAC681EDFC5A235BA77D1F3781CAE93 +:102D2000091A5B4EEF24897B08F7AC695E9B094565 +:102D3000255A9385BFABEFB7A09DA8680CC88179D1 +:102D4000C027B6ED5B6F07F9E7997A33D97D86E541 +:102D500024DFE91B10BC57D21FF434A49322C43FD4 +:102D6000F4FBFC601EEF7C670E5F5F81FA4DD77D40 +:102D700000AB8ECF73FDAF1BBA237A94EBF8BFBACA +:102D80001F20E9D70827A95F33717E0D10F392F059 +:102D9000EBB29F08F8C9FB19CE8596E22D76BAE70B +:102DA00051887165127F070773BA5C2DE081F59039 +:102DB0001FF554AF40CD89463B782773463BAE6242 +:102DC0000FFE3FBA3741F0EFE9BE574F7CE20AFEF3 +:102DD000D0C3FDAF9EE893FEBEC33DB0103EC1E33D +:102DE0007D043EFC034CE4575F15A9DFC7FB73B8B5 +:102DF000DDA544EC2738B7ED797A3EC1D0AEDFB817 +:102E000042157C624ED7EF4FE0F7D92B2C245F336D +:102E100056FC18C619FC65BD85E262477918C931B0 +:102E2000651B15FF6605CFD1910938FF529FFE3C07 +:102E3000BE85B957A2FFA37CB5FEFB5C3BFF9D8A14 +:102E4000D9C6775384BE3EF72AFAFA8E1C718EBB20 +:102E5000999BE42EE1FFAF146D8C7257A79FFBCDB9 +:102E600050DF56B9DD89E2C6E4F9EE44FF4DC87B78 +:102E70002000CFF02C3CC7979BBB8DE7EB82670F00 +:102E8000F10AE7EC225EC1CEE3333AF78671FFA682 +:102E9000F42B89FAE77C97A81CEB636FE7F378DCE7 +:102EA00085F42719FD559D7613F95B3AF746927F15 +:102EB0001EFD38D14007674C7BE247B882F3F3B67A +:102EC000A93A3F8831F52E7D89F4C58169DEDF217D +:102ED0005F3F6B76DBDC907FD0FE3ABD1F5524EC64 +:102EE0005EC6F976E95D23F9FB2E9D3E2ECF761660 +:102EF000F27738802F32DC47320E6112032D15D263 +:102F0000D2C00D349FEFEACF9972398FFB312FDF9A +:102F100044EDBDAB6FA07CFFE56B17E23D98698D7A +:102F2000732DE8C26E7B62494138346D4BF62F0B2E +:102F300047BC8D56BAB5CB5F12786B33C4D7CBB4D0 +:102F40005CF0237C438EF3251187B454A17DB048F7 +:102F500061322E89F8B8CC5F6A12F9029E5FBC829A +:102F6000E7DBC4FBFADB851D05D78D29AE1BF5FE1B +:102F70009DC2CE82EBC614D78DDF916F611EF9160C +:102F8000E6916F611EF916A6C8B7F07B192B4EC9E2 +:102F900053B91F6A5CE8BEBB6C63E342F60BFAA14F +:102FA00042F3E8870AAD8F7EA8D072F4438596A3DA +:102FB0001F2A348F7EA8D0FAE8870ACDB311B7064E +:102FC000F3C8E73C9374F92920E78F0BD9DFE88732 +:102FD0000AED1FFD50BAFEBC0B75EDEF66F5BAF6B3 +:102FE000E8870AAD7F6FBDA2F353DD2BDE392DDFFD +:102FF00010C7E9C759EC1E0C74F05F11FFB8DF92DF +:103000008A786E99C7F5B27037C7735321C7BB89E9 +:10301000713C77CC203C2FD178BE80C7271BE907B5 +:10302000FD3DE32CDCDF8329FA7B30457F0FA6E8EA +:10303000EF1997CEFD3D98A2BF07BFA3BF0753F47A +:10304000F7608AFE1E4CD1DF8329FA7B30457F0F63 +:10305000B6437F0FA6E8EFC1EFE8EFC114FD3DF8DE +:10306000FD18FA9D2CC179A11C3F40A73F021DEA23 +:10307000F447872E8F727C687D94E343CB518E0F8B +:103080002D47393E348F727C687D94E343F3753964 +:103090004EDA5F28CF87B643793E343FB8C9F7266A +:1030A000DACE266CBCF006A66D91CA330AB08C85C8 +:1030B000BBF6DE897EB9B63025250638A74579E509 +:1030C000CE7190F78AF8BF5CD661427C7BC57BEA03 +:1030D000DE00A378CBC17F4DA4F217C4BD7EFA03F6 +:1030E000BCE7ED65F4BB24D25F2CDBBB9943C55430 +:1030F000D60FE6BBAF671C5FD623FE19320FBC01AB +:103100008CF12A794BECF918EFB9DDA4509CC4F688 +:10311000653C4ED84857DB045FDA6EDAF33ADE03DB +:10312000E92855E83E7086991DB1E4239CEAF2F146 +:10313000FC5D3B3846ACABEE46BC6F22E72DED9B09 +:10314000C027E8FEDCC88ED6B1D1D08FD7379A7EA3 +:1031500027A548E37203B6437D32DBA778B684D057 +:10316000F7E38339DFF4FAF8F83FDF3491B70BE780 +:10317000ED7EBE298AE03871B942F1522377320FD1 +:10318000DECFF58B7967EF0CA8385EE9723E9EECD6 +:10319000B774630ADD5B2C656DE312C847A230E4A7 +:1031A000DB126EB0BE37707DA0361C41FBF4B5DE7D +:1031B000FBB9F9BA98028CA3632D8CDEB19C70DD4B +:1031C0006F75EB25B40FA77EE95CCBF429F45EF0B4 +:1031D00044DFD265A86E4CF02D7CB337D6DFCADC55 +:1031E0002E271D45742F56CE6790678F098E459602 +:1031F000C35A4D610AE29B1D8E0BA11FD8F95311D2 +:10320000DF796E0BBDDF3BC9ECB0D0FB113DC49F35 +:103210005CB2CBF81383BC608833695C723405ED13 +:10322000C98B224D64FF5DF412FF3D00EF0685F867 +:103230009A94834A459CDAA5E56FF6BE0BE1BEC7BA +:1032400042FDC9F893DA347F8A09E3EAFB6ECE8D3A +:1032500055490EF8FD6094037CBFBC7304D65BC176 +:10326000DFB1BCB47C5A74807AE2FE9A0A01AF0ADC +:1032700011C7548A0F7AABC1DFD392F73B5813972B +:10328000F7A43DA7F43743DF42FC963E2DDE955E62 +:103290005D4AF7B28D7144F3965B28EE689E412E2D +:1032A000AC167261F555E4C2B3830D72A1FCBD1476 +:1032B000D186A9FDFE80717BF25E628985EFFF9267 +:1032C0003D8CECB0254BC79AE81DE49738DD942C73 +:1032D000E5F24DC9CB1EBA5F28E5C5F7851C33F969 +:1032E0007212C1FDF7426E9986F19500DFA2B630E9 +:1032F00011879548E95D9779BCE5643BE7036D0765 +:10330000F93B109D3E2B97A7DE60FC1D33035D4EFD +:1033100032FB4D78E1CE3D12E812F213500E82FEE0 +:10332000A6A35C148774EE2AA0F8BD4285EEBD18F2 +:10333000E9BCC852F726C687166D636E1F0BA573CE +:10334000A05FECCFA7D0FB005EA1D74AFA35D2FB35 +:10335000AC08618FB2737B53975D0265547CA4DB2C +:10336000177517CA8DB3D0B7D797130CC69D45E60E +:10337000F0F2F4DD51772D4725A7073B85FA038D41 +:10338000E0E195EF20F46037407B01F2C97BEECBA2 +:10339000D3CA42F8E49743C6140CE91DC47759D741 +:1033A0007DBF1C7A1774D183E9F47B383DC9C3E52E +:1033B0000057DC17B3A2DBEEC75F661B97CB3CE37D +:1033C00046E0EF0B32F9087900E308678AFCC2DCBB +:1033D000EBFF88BAEDAC089EF7ECEE7717C685D404 +:1033E000DADAC623D92DC8F116E23DC6207F2AF6C7 +:1033F0002429C89FF202A813CEC810E78FC11EB1BE +:1034000030D7C9D769B04B94E770BE2D7F17E5F868 +:1034100083FB77E37925E77FBC87DF6198976BFAB9 +:103420005FBD0761BCFFF0FDBEDE99B9D0FF63262A +:103430007E9FBFAFDAC4847D88FCC2925F30F10EFC +:103440004610EF1E7A47B7F141C5116A9FF2AE569A +:10345000F83DFA1EEC382CABE3896DD06E568346EE +:10346000BFE3B72983D3CF26A01FFABD14ADF54D16 +:103470009B2B08C78FEB1FB1D0EFD2B0403ABEBF35 +:1034800033B32ECC8DFCF8CB21C575B9C3F0F7480A +:10349000DCC4870A30861CCFF35EC58B713DB56BEB +:1034A0000E3D83EF092C6871D1EF95941EC85B899E +:1034B000EF9C7C39C45B8FE5A57607BDA7317F798A +:1034C0000C9D5FB3FA887BA1AC83FC6C12FE4DC2ED +:1034D0007E75AB9B89DFDB12F71D80414ED2D5EBA9 +:1034E000DE8E27ED84463B83F17D899EEC0BD29ED8 +:1034F00080F6032DC4CE28ED1396ACE333506E282E +:10350000D1F4F712657A2857E8B9420F9CDD756E41 +:10351000E58CEF83F2F13AC541EF4DDA9D77DD009E +:10352000F98A23168CEC6445B14E0DDF1FE800FCD0 +:10353000627C7419EC57E43325224EAB62C30DB4A0 +:10354000DF2AFC9076F30EA74CEF5E7738F965A47E +:103550009F8087FC96150E8F161BB2EFCB9B14DD58 +:10356000BB0332BF2797DBE34A602B23FCEEB9CFC6 +:10357000A5E1DB3E25204660FCDFA15CA7CE7F0CE9 +:10358000F5281EA42895BDC5DF818779BBF878F999 +:1035900021FD9735F17BD3320FF549FE793537920E +:1035A000F057EA8075BB3075D03C010E04A78EB58C +:1035B000D09F93C6217C9407FC16D4B74B300E05E0 +:1035C000F2331D7E0B8E53B69CBF63E25DC3C7F121 +:1035D000AE8ED106A37C647668C9083FF13BAD305E +:1035E0003F92232B002E781F0BEFBBE1D962844F53 +:1035F000A9986F45530CBDA310FCBECE82F898D19C +:10360000C3BB08E705DD962D1F4DF7D72BCC1EBA9F +:10361000E7E015F0FDCBC2B087D03F3063FDE31685 +:1036200017E43F11F47B5EECBBA2D4403ABD57B423 +:1036300030CC8DF39CE168A2F575C1F7518087828B +:10364000EFDC14137C812E7C18B757B15E8FCFE06E +:103650007C387C2BD697D27E9B63F66A8ED0796CB1 +:1036600038948EF7AA66C0FEC6772598C34BF72517 +:103670003F7DF4AE145A27CC13E11AE9768EC7F7D2 +:1036800087804EF83D18B11E79AF5B8E6719C2EF87 +:103690009D5A8670FB59CFFBD243724D23E017ED44 +:1036A000DE3DED4B0D19378CAB55F0DF9130EE530D +:1036B000B93FE5BE94FB54EEDF672CC5810425C8F5 +:1036C00067E09CAD7BB11B38150CE1789829F00AB6 +:1036D000707D23F49E57EE10BE9F4B52F5FB1DFBF1 +:1036E000C37EFB0EE1782F191348C77799647D39A3 +:1036F0006E492C6F87748FF4D6578C87F517517DE0 +:10370000938E5F9477F18B9D2BE2915FEC51B81F04 +:1037100074EDE1E4EFA3FCBA8BCBAF676BB6CDC71A +:10372000F39299FD29A1EFFBCF063907F9C41C716B +:103730003E5704BAE7173B33BCD94342F673C5CFB3 +:1037400076657839BF0920BFF9F3AE573FBCD11970 +:103750003C4FE57ACA56FFD6526A0F859F22DE1D7E +:10376000E9A4FB78E576CD89F1CEE5CB4B89FFB2B4 +:1037700004900B9590F833035D942E57E81E597909 +:10378000FD70BFFABFC8A7CBD74CA2770F24DEE4E9 +:10379000FB2CF27C95F39F28F0356908DF87330511 +:1037A0007DCFAC1CAD25F622B91BC32CD90CF17D05 +:1037B0004685FE7B17DEBAFCD7392B71BFE0FD22B0 +:1037C000D24FD658B8BD6F27B73F9E5DB4FFBD3B03 +:1037D000A1DE99C736A730558F379453E70879751E +:1037E000AEB0FF7583B73294DB647EEE268EB7F2FF +:1037F000DDBFF904DF132B4915FC6E2D7F07A0AC4C +:10380000790FE171C6EA751617CA75435CBAF736C7 +:10381000CAEBF21C68579EB97AB305F9C4A2211C01 +:103820008EC6FD5022E284259CF15C5242FC1BB204 +:103830003EF2477CFFFEBE85615118CF23C7794A0F +:10384000D07D795D4C2C8E575E57FA13D487E4797E +:10385000605CE78930BE5FCAA03FDCB72746BB5338 +:1038600016E504E55963FD47041D3E65E1BF53932A +:1038700014D1FC1CC5352C087723FF1830A0CD8F40 +:10388000E3227DE3BC3513FF5D9B01356D9FE33C77 +:1038900040D4A6B81A4CF17D2C14BDE321BFC5C499 +:1038A000EF6FA5AA3C3D20E003E5012C67BDDAE8F7 +:1038B000F73542E26675F4ABB1ADF4FB895A2F4699 +:1038C000EF9B497A95FD487A95F4DCD3FA9AAF716B +:1038D0007D275C1C9E9AF8DD946B5E9F95FF8EAEF3 +:1038E0005C979C1FC8F01E7ADFE38783C9DE736292 +:1038F000A93B05E3267B5EEFFA82F86ED66B5CA7E8 +:10390000DC373216BECB9FD5C4FD0E271438DFA09E +:10391000DD89856114DF26D7F55DEDE11F0C899502 +:10392000EFF947A29C59121EBC2F8FF03B56CF7F58 +:103930005F577E9772817C674EF2EF9375E2DC648D +:103940006D6B717FB3FA347AFFE458D389487C8F6A +:10395000E5C4683E3FD9EE3E0BBF9FCC223527DE43 +:10396000138BB8EFB7057DD03FB4DE95A740BB7B86 +:10397000EA871EC3F7C7EF59DE87F4FBD976E74A1B +:103980003C1767FB5CE40F8E589FF729BEA3377B7B +:103990007936FD6EEF7D0A2B267D52E8097358D7E4 +:1039A0001FE90973055F9B8BFC12EF4BD51FA677B0 +:1039B000F3E6B8C3F2F07C9FBB81EB094526B61A4B +:1039C000FD89FD1B8BC7231FEB7842E1BFFBBC5178 +:1039D000FF0E577666F1453C1F8CEFDEDD6769F61A +:1039E000E03A18C82368779A6D2FE672BDE09FC74A +:1039F000D6B7D3EF6522BCE9F7720CF69BFE1ABF6F +:103A000047DC1169227B1CE0FD7DFC3D327C6FDDD3 +:103A10004AE78DDE7ED3FFC723E8F7DAE43DA10A4B +:103A2000E177FA7F89106A7A0080000000000000C8 +:103A30001F8B080000000000000BCD567D4C535733 +:103A4000143FF7BE7E53E8E31B44B08060B7157C9B +:103A500005257126FA066A4C66B4B8A13451A851FE +:103A6000192A65CC2C019739AB9DCE68B6B10415E7 +:103A7000892C8529FB675B4A249B666C6924CE6C84 +:103A8000928CC83F266CA4240BA299A16359906420 +:103A9000D39D735F9B1A3F92FDB9F7CF79F7DEF3A1 +:103AA00075CFEF77CE7B506FE29005D06C02F1ECD2 +:103AB000ED7B2D0BAC28BB25B05702F4D0E62A8055 +:103AC000135D35591127C09E4FD69FF597011430CD +:103AD000708750EF375DA4165600CCF465A71D65BE +:103AE00078EE0B94029EEFE9FBA080E44C9FB93E78 +:103AF000887AEBE4DA75A919004D17525D921DE042 +:103B0000113D6BD18F82469900FB7D35D95004D091 +:103B1000F270E453B918E31702C8E8F7AF5052D077 +:103B20008F2A2D47AE14481C40317A7395950007B3 +:103B3000F8F0B655E8E71E0B0EE40A7D7BB66C4D37 +:103B4000F87D524E1F01B01B017CEFDD167EEEF3B7 +:103B5000D1CD1EB46FF15D4E213F07CE8C57C9B851 +:103B6000FF42B1B744C924BF7D03B28477EFEE2B87 +:103B700077E33D4A1510796E4A736FF3605ED11F8B +:103B800025A5DFFEFC78CD5730E9CAC47A67D06638 +:103B900000AC9F370C0699A40C86349433127484BD +:103BA000506E2A82C6ADD6C4FEAA585D666C9D05CD +:103BB0006EDCDF3770AEC08EF26EB2B6DE31B0FDB5 +:103BC000274841FD8B4603E1E5D5814141BBDD7EC0 +:103BD000A6065142731A406E227E8D92048075DBD8 +:103BE000D78D49A527F6018262FFAE0E36521E4BD5 +:103BF0000251D75B282774E1BD84EB449B59F11730 +:103C0000124E7691CF44A7B481F6FD6F332861B48C +:103C1000BE9CBC14E337D8A08DEC935784C21C71B2 +:103C2000F60DA556481AA504BF5A656DB15EB26E71 +:103C3000C8C3F383834C36A2CB8357AF6F006D0D9F +:103C4000C09E5FCFFD0F5683FDB1BCF70F0D1AEC80 +:103C500018AFE50BBC2FC66F090DFEB008FDB45EB2 +:103C6000D955A9C5ED04A8C23CE815E3B40E6975A1 +:103C7000F10D4D19763B137E7639D24EE421B64DC7 +:103C8000A135DBCFA0DE2EC2ED6580C3E515F5477B +:103C9000979294C5BD41172D7027039C72DC327832 +:103CA000C9CFFB317F8E5B278AC47D6BD3E1313E68 +:103CB000BCA1E8855DDC1EEB21ECC23ECB49580E71 +:103CC000A0B65A7524033E6B0AC90B6DDCA1C3BABA +:103CD000AACCA24858EF0E534A39D800E6CD9A1C18 +:103CE000B668B29DBB079B30C5793E6606E47DBBD6 +:103CF000D4C948AE75B631AC34C819DEC3C4DF1CB4 +:103D0000083110850833CA7BF6BB3B95147FCD92F2 +:103D1000C89F8029E9995ABF0EF9715C9105FEE0B0 +:103D20008C5412CF33AF4123F1AB570F27CD15740D +:103D30006F376C2D232FF84EB82FF0E025CC6F98FD +:103D4000853F23FFF1FB5E25BEA21FB7D17A9261AA +:103D50009E06BBF723CA630BD397B93861209590B1 +:103D6000FF59BD760E9DE75413F2A25AA305E473E2 +:103D7000F00352D6B028C74ABC66AA0A1D18FF989D +:103D8000F3DA6EE2C7E9A8098C183710AB4775D48F +:103D900032C5502F7FD1460EE5A86FCF801D687FBA +:103DA000CDC9FD46CCF3349882A40FA6F56AC4A110 +:103DB000C57884F3C5C0CDAAD01FBEB1C050E649B6 +:103DC0007F8CD8503FAF9D2901D469989BEEFD1997 +:103DD000E50E08BAA8AE5B32BC9FD3BC999CDB3819 +:103DE000E5457C4FCB2113F5193D8FE73F7C6821DA +:103DF000258D27F29A8D4E7FF9CD0A922685A15DF9 +:103E0000F5B01436963F9DCF6C8E5D4771502FCC28 +:103E100049DFCA838C91FEC86DCAAFDA640D4B29A5 +:103E200064A7FF3D624AD8C1587EEAF44B20207E49 +:103E300094079015D0705B13EBC3382E37152E7096 +:103E4000B919C3275E3F913CF6C74193D61FDF5B8C +:103E50000776127FE2FDFA666C7FEE41918DE6CB2C +:103E6000DC70B10D9CCFEFCF719CAFB00CE75CA1C3 +:103E70003A4EB8E3A39AD07F5DAC3E8837905F2975 +:103E8000E6B72E56A73A2BD7EAF2FA137589F12432 +:103E9000CE8378DE719CE3F8C13B63D76D8502B7B2 +:103EA000B28F41E0F52BC59F5C183D8E6D058B24CC +:103EB00075CA5BF87FC42B6C5E86BC8E9EE14A3F60 +:103EC000F19F0A5F21A4CAF17EE000310F1A248B12 +:103ED00072EA19F3C04BF36039CD834ED1E7F33C5E +:103EE0007A9D339A076D629D03D1A33A5C4FF248E5 +:103EF00032E51B3123EB5116BA8AC43CCAA38E2E7D +:103F0000D670A2BEEE3D94DC7F0AF5034C3D6F42B5 +:103F1000FB803ED6EFFBACC14BB83F1BE47E3DC6F9 +:103F2000EB4A0D9E6FC2FDAEBAC58A1FEB340B3152 +:103F3000BD668B980BAB3917EBA8272BD85F48FAD7 +:103F4000D8D778CF2ECF8BE23BFEF543744EF72EB9 +:103F500001EDDC05A5DD745EEB10FEBE8DCF990F83 +:103F60009385BFAE5A35D722CEB338D91F4FF7E667 +:103F7000B93209574D0F7F04845E4F8F9A4B78F406 +:103F80006C3508BDB3CCEDD94B7ECAACCA25F41B49 +:103F9000F158BE1AD0E00833DC9FECD0EE1BE7AF3F +:103FA000A7549B834BFC53E7E93FC45F0D8E36E477 +:103FB000FD24F17079021FA6221669099CE27CF4A7 +:103FC000EB11AF0C0DAF63EC69BC326278B10EE45B +:103FD0006D0AE11612F59FE71A0EED124492F04EAB +:103FE0001257728C282732BC55DA3DC772E9BCC122 +:103FF0001859D9E9243CA139F48C3E7CC5A5F53982 +:10400000D0571479DE18E379639C8FEF3EC1C7C89F +:10401000E2D4E9A4181FD1FE178BBB86E2DD67E36B +:1040200055B439FA8F54FFAC389B5CDA7FC99CD108 +:10403000FB2AE9C3C56C2EE688ACF5F5A8EB4E3E2D +:104040007D67E0EF91C5F4DDE94D776F263DF3D252 +:10405000A8C14BF5CC8DEAE93E939E7BF9F43FD3A2 +:10406000D87143F4CD7FCDF35F8E8A94E2B00A001D +:104070000000000000000000000000180000000028 +:1040800000000000000000400000000000000000F0 +:1040900000000028000000000000000000000010E8 +:1040A00000000000000000000000002000000000F0 +:1040B00000000000000000100000000000000000F0 +:1040C00000000008000000000000000000000000E8 +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000000000000000000000000000C0 +:1041000000000000000000000000000000000000AF +:10411000000000000000000000000000000000009F +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000000000000000000006F +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:10417000000000000000000000000000000000003F +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A000000000000000000000000000000000000F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000000000000EF +:1041D00000000000000000000000000000000000DF +:1041E00000003328001000000000000800003330F9 +:1041F0000010000000000002000033280010000042 +:104200000000001000003A780000000000000008E4 +:10421000800000000000000000000000800000009E +:10422000000000000000000080000000000000000E +:104230000000000000003120000000000000000825 +:10424000000033600001000400000001000033683A +:1042500000000000000000020000337000000000B9 +:10426000000000080000337400000000000000029D +:1042700000003A70000000000000000800003A4012 +:10428000000800000000000800003D880040000019 +:104290000000004000003A50000800000000000844 +:1042A00000003A60000800000000000800003A88A2 +:1042B00000C800000000009800003C1800980000B2 +:1042C0000000002800003C58009800000000002872 +:1042D00000003378036000300000036000003EB04F +:1042E000000800000000000100003EB100080000CE +:1042F0000000000100002008001000000000001075 +:104300000000200000000000000000088000000005 +:10431000000000000000000080000000000000001D +:10432000000000000000000000000000000000008D +:10433000000000000000000000000000000000007D +:1043400000000000000000008000000000000000ED +:1043500000000000800000000000000000000000DD +:10436000800000000000000000000000800000004D +:1043700000000000000000008000000000000000BD +:1043800000000000800000000000000000000000AD +:10439000800000000000000000000000800000001D +:1043A000000000000000000080000000000000008D +:1043B000000000008000000000000000000000007D +:1043C00080000000000000000000000080000000ED +:1043D000000000000000000080000000000000005D +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000800000000000000000000000800000008C +:1044300000000000000000008000000000000000FC +:10444000000000000000000000000000000000006C +:10445000800000000000000000000000800000005C +:1044600000000000000000008000000000000000CC +:10447000000000000000000000000000000000003C +:10448000000000000000000000000000000000002C +:10449000000000000000000000000000000000001C +:1044A000000000000000000000000000000000000C +:1044B000000000000000000000000000000012C822 +:1044C00000800000000000800000000100000000EB +:1044D0000000000000004000049000000000049074 +:1044E000000019C800000000000000080000494852 +:1044F0000008000000000008000049280008000033 +:104500000000000800004938000800000000000812 +:104510000000200800100000000000100000200033 +:10452000000000000000000800004010049000405F +:104530000000004000004998000800000000000151 +:104540000000499900080000000000018000000000 +:1045500000000000000000008000000000000000DB +:1045600000000000800000000000000000000000CB +:10457000800000000000000000000000800000003B +:1045800000000000000000008000000000000000AB +:10459000000000008000000000000000000000009B +:1045A000800000000000000000000000800000000B +:1045B000000000000000000080000000000000007B +:1045C000000000008000000000000000000000006B +:1045D00080000000000000000000000080000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000008000000000000000000000000A +:1046300080000000000000000000000000000000FA +:1046400000000000000000008000000000000000EA +:1046500000000000800000000000000000000000DA +:10466000800000000000000000000000800000004A +:1046700000000000000000000000400000180000E2 +:10468000000000180000430000400000000000404F +:104690000000430000400002000000010000430150 +:1046A0000040000200000000000030000040000058 +:1046B000000000408000000000000000000000003A +:1046C000000030000008004000000004000030043A +:1046D000000800400000000400004B00002800001B +:1046E0000000002800004B500010000000000010E7 +:1046F000000038000080000000000080000038004A +:1047000000080080000000020000390000200000C6 +:104710000000002000002008001000000000001031 +:104720000000200000000000000000080000510808 +:1047300000080000000000080000512000080000F0 +:1047400000000008000051300008000000000008D0 +:10475000000051C00008000000000001000051C12D +:1047600000080000000000010000394000100004B3 +:1047700000000004000051D00030001800000010BC +:10478000000051D800300018000000028000000036 +:104790000000000000000000800000000000000099 +:1047A0000000000080000000000000000000000089 +:1047B00080000000000000000000000080000000F9 +:1047C0000000000000000000800000000000000069 +:1047D0000000000080000000000000000000000059 +:1047E00080000000000000000000000080000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000800000000000000008 +:1048300000000000800000000000000000000000F8 +:10484000000000000000000000000000000023E85D +:104850000080000000000080000000010000000057 +:104860000000000000002008001000000000001000 +:1048700000002000000000000000000800002DA043 +:10488000000800000000000800002DB8000800002B +:1048900000000008000024E802D00028000002D038 +:1048A00000002E58000800000000000100002E59F2 +:1048B000000800000000000100002D90000800002A +:1048C0000000000880000000000000000000000060 +:1048D00080000000000000000000000080000000D8 +:1048E0000000000000000000800000000000000048 +:1048F0000000000080000000000000000000000038 +:1049000080000000000000000000000080000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:1049400000000000000000008000000000000000E7 +:1049500000000000800000000000000000000000D7 +:1049600000000000000000000000000080000000C7 +:1049700000000000000000008000000000000000B7 +:1049800000000000800000000000000000000000A7 +:104990008000000000000000000000000000250072 +:1049A0000040000000000008000025080040000052 +:1049B00000000028000009C00120001000000008CD +:1049C00080000000000000000000000080000000E7 +:1049D00000000000000000000000402002D000287D +:1049E000000000080000300000000000000010007F +:1049F000000050990000000000000001000050B0CD +:104A00000000000000000002000045A00090000827 +:104A1000000000088000000000000000000000000E +:104A2000000029600008000000000001000029616A +:104A300000080000000000010000297000080004C8 +:104A400000000002000029780008000400000004B3 +:104A500000002FB0000800000000000400002FB488 +:104A6000000800000000000400002FC0000000004B +:104A70000000000800002FC800000000000000082F +:104A80000000300000000000000000100000504056 +:104A900000010001000000010000500000000000C3 +:104AA00000000020000008080010000000000004C2 +:104AB0000000080C0010000000000001000008B712 +:104AC0000000000000000001000008B60000000027 +:104AD0000000000100001000003000180000000479 +:104AE000000010040030001800000004000010084E +:104AF00000300018000000020000100A003000180A +:104B0000000000020000100C00300018000000013E +:104B10000000100D00300018000000010000100E11 +:104B200000300018000000010000101000300018D4 +:104B30000000000400001014003000180000000401 +:104B40000000300001000080000800040000300474 +:104B500001000080000800040000000A00000000BE +:104B6000000000000000306801000080000000012B +:104B70000000306901000080000000010000306C7E +:104B800001000080000000020000306E0100008083 +:104B900000000002000030700100008000000004EE +:104BA0000000307401000080000000040000306646 +:104BB000010000800000000200003064010000805D +:104BC00000000001000030600100008000000002D1 +:104BD0000000306201000080000000020000305040 +:104BE000010000800000000400003054010000803B +:104BF00000000004000030580100008000000004A4 +:104C00000000305C01000080000000040000307CE7 +:104C100001000080000000010000307D01000080E4 +:104C20000000000100001C1800100000000000043B +:104C300000001C30001000000000000400001C38C0 +:104C400000100000000000048000000000000000D0 +:104C500000000000800000000000000000000000D4 +:104C60008000000000000000000000008000000044 +:104C7000000000000000000000004C1000080000D0 +:104C80000000000200004C120008000000000002BA +:104C900000004C14000800000000000400004C203C +:104CA000000800000000000800004C300040000830 +:104CB0000000000800004C00000800000000000296 +:104CC00000004C02000800000000000100004C043D +:104CD000000800000000000200004CD000080000A6 +:104CE0000000000800004CE0000800000000000484 +:104CF00000004CE4000800000000000100004CF03F +:104D0000000800000000000200004CF40008000051 +:104D10000000000200004D00000800000000000438 +:104D200000005000001000000000000400005004CB +:104D300000100000000000040000500800100000F7 +:104D40000000000400001400000800000000000241 +:104D5000000014020008000000000001000014041C +:104D6000000800000000000200001410000800000D +:104D700000000002000014140008000000000002FF +:104D8000000014160008000000000002000019B81E +:104D900000080000000000080000142000080000C7 +:104DA00000000002000014240008000000000002BF +:104DB000000019C8000800000000000800002C10C6 +:104DC000000800000000000100002C110008000095 +:104DD0000000000100002C1200080000000000018B +:104DE00000002C13000800000000000100002C004F +:104DF000000800000000000200002C020008000073 +:104E00000000000100002C04000800000000000267 +:104E100000002C30000800000000000200002C32CE +:104E2000000800000000000200002C340008000010 +:104E30000000000200002C2000080000000000011B +:104E400000002C21000800000000000100002C22BE +:104E5000000800000000000100002C2300080000F2 +:104E60000000000100002C240008000000000001E8 +:104E700000002C25000800000000000100002C2686 +:104E800000080000000000010000140000080000FD +:104E900000000002000014020008000000000001F1 +:104EA00000001404000800000000000200001412BA +:104EB00000C00018000000020000141000C000181C +:104EC000000000020000141C00C0001800000008D0 +:104ED0000000141400C0001800000008000014278F +:104EE00000C00018000000010000142400C00018D9 +:104EF000000000020000142600C00018000000019D +:104F0000000015900008000000000008000015A037 +:104F10000008000000000008000015B000080000B4 +:104F200000000008800000000000000000000000F9 +:104F30008000000000000000000000008000000071 +:104F400000000000000000008000000000000000E1 +:104F500000000000800000000000000000000000D1 +:104F60008000000000000000000000008000000041 +:104F700000000000000000008000000000000000B1 +:104F800000000000800000000000000000000000A1 +:104F90008000000000000000000000008000000011 +:104FA0000000000000000000800000000000000081 +:104FB0000000000080000000000000000000000071 +:104FC00080000000000000000000000080000000E1 +:104FD0000000000000000000800000000000000051 +:104FE0000000000080000000000000000000000041 +:104FF00080000000000000000000000080000000B1 +:105000000000000000000000800000000000000020 +:105010000000000080000000000000000000000010 +:105020008000000000000000000000008000000080 +:1050300000000000000000008000000000000000F0 +:1050400000000000800000000000000000000000E0 +:1050500080000000000000000000000000000000D0 +:1050600000000000000000008000000000000000C0 +:105070000000000000000000060205000000000023 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex new file mode 100644 index 000000000000..5f04df69e7c3 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex @@ -0,0 +1,13181 @@ +:1000000000004F48000000680000070C00004FB8D7 +:1000100000001ED4000056C800000094000075A027 +:1000200000009F4C00007638000000CC00011588CD +:100030000000DC4C00011658000000940001F2A8FA +:10004000000040000001F340000000A4000233481B +:100050000000F38C000233F000000FFC0003278047 +:100060000000000400033780020400480000000F75 +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040004000000FF02040008000000FF79 +:100170000204000C000000FF02040010000000FF59 +:10018000020400140000007F02040018000000FFB9 +:100190000204001C000000FF02040020000000FF19 +:1001A000020400240000003E0204002800000000B9 +:1001B0000204002C0000003F020400300000003F59 +:1001C000020400340000003F020400380000003F39 +:1001D0000204003C0000003F020400400000003F19 +:1001E000020400440000003F020404CC00000001AF +:1001F00002042008000002110204200C000002008A +:10020000020420100000020402042014000002195D +:100210000204201C0000FFFF020420200000FFFF5A +:10022000020420240000FFFF020420280000FFFF3A +:1002300002042038000000200604203C0000001FBB +:10024000020420B800000001060420BC0000005F8A +:100250000204223807FFFFFF0204223C0000003F97 +:100260000204224007FFFFFF020422440000000FA7 +:1002700001042248000000000104224C000000009C +:10028000010422500000000001042254000000007C +:1002900001042258000000000104225C000000005C +:1002A000010422600000000001042264000000003C +:1002B00001042268000000000104226C000000001C +:1002C00001042270000000000104227400000000FC +:1002D00001042278000000000104227C00000000DC +:1002E0000C042000000003E80A04200000000001C4 +:1002F0000B0420000000000A0605400000000D006D +:100300000205004400000020020500480000003201 +:10031000020500900215002002050094021500203D +:1003200002050098000000300205009C0810000043 +:10033000020500A000000033020500A40000003008 +:10034000020500A800000031020500AC0000000218 +:10035000020500B000000005020500B40000000620 +:10036000020500B800000002020500BC0000000207 +:10037000020500C000000000020500C400000005E6 +:10038000020500C800000002020500CC00000002C7 +:10039000020500D000000002020500D400000001A8 +:1003A00002050114000000010205011C000000010B +:1003B0000205012000000002020502040000000105 +:1003C0000205020C0000004002050210000000407F +:1003D0000205021C0000002002050220000000139C +:1003E0000205022400000020060502400000000A69 +:1003F00004050280002000000205005000000007F4 +:10040000020500540000000702050058000000002B +:100410000205005C00000008020500600000000109 +:100420000605006400000003020500D80000000675 +:1004300002050004000000010205000800000001A0 +:100440000205000C00000001020500100000000180 +:100450000205001400000001020500180000000160 +:100460000205001C00000001020500200000000140 +:100470000205002400000001020500280000000120 +:100480000205002C00000001020500300000000100 +:1004900002050034000000010205003800000001E0 +:1004A0000205003C000000010205004000000001C0 +:1004B000020500E00000000D020500E80000000059 +:1004C000020500F000000000020500F80000000036 +:1004D000020500E40000002D020500EC00000020F1 +:1004E000020500F400000020020500FC00000020CE +:1004F000020500E00000001D020500E800000010F9 +:10050000020500F000000010020500F800000010D5 +:10051000020500E40000003D020500EC0000003090 +:10052000020500F400000030020500FC000000306D +:10053000020500E00000004D020500E80000004058 +:10054000020500F000000040020500F80000004035 +:10055000020500E40000006D020500EC00000060F0 +:10056000020500F400000060020500FC00000060CD +:10057000020500E00000005D020500E800000050F8 +:10058000020500F000000050020500F800000050D5 +:10059000020500E40000007D020500EC0000007090 +:1005A000020500F400000070020500FC000000706D +:1005B0000406100002000020020600DC000000011A +:1005C000010600D80000000004060200000302201B +:1005D000020600DC00000000010600B80000000078 +:1005E000010600C8000000000206016C00000000C7 +:1005F000010600BC00000000010600CC0000000065 +:1006000002060170000000000718040000910000BD +:10061000081807D800050223071C00002BF700006C +:10062000071C80002DD10AFE071D00002F461673FF +:10063000071D800016342245081DB13049DA022515 +:100640000118000000000000011800040000000074 +:1006500001180008000000000118000C0000000054 +:100660000118001000000000011800140000000034 +:1006700002180020000000010218002400000002FF +:1006800002180028000000030218002C00000000DF +:1006900002180030000000040218003400000001BD +:1006A00002180038000000000218003C00000001A1 +:1006B000021800400000000402180044000000007E +:1006C00002180048000000010218004C000000035E +:1006D0000218005000000000021800540000000141 +:1006E00002180058000000040218005C000000001E +:1006F00002180060000000010218006400000003FE +:1007000002180068000000000218006C00000001E0 +:1007100002180070000000040218007400000000BD +:1007200002180078000000040218007C000000039A +:100730000618008000000002021800A400003FFF1D +:10074000021800A8000003FF0218022400000000A5 +:1007500002180234000000000218024C00000000E1 +:10076000021802E4000000FF061810000000040058 +:10077000021B8BC000000001021B8000000000343F +:10078000021B804000000018021B80800000000C4B +:10079000021B80C0000000200C1B83000007A1206A +:1007A0000A1B8300000001380B1B83000000138824 +:1007B0000A1B8340000000000C1B8340000001F472 +:1007C0000B1B834000000005021B83800007A12053 +:1007D000021B83C0000001F4021B14800000000112 +:1007E0000A1B148000000000061A1000000003B36A +:1007F000041A1ECC00010227061A1ED000000008B1 +:10080000061A2008000000C8061A20000000000296 +:10081000041AAF4000100228061A3718000000041E +:10082000061A371000000002061A500000000002ED +:10083000061A500800000004061A501800000004B0 +:10084000061A502800000004061A50380000000460 +:10085000061A504800000004061A50580000000410 +:10086000061A506800000004061A507800000002C2 +:10087000041A52C000020238061A40500000000656 +:10088000041A40680002023A041A40400004023C84 +:10089000041A800000010240061A800400000003D0 +:1008A000041A801000010241061A8014000000039F +:1008B000041A802000010242061A8024000000036E +:1008C000041A803000010243061A8034000000033D +:1008D000041A804000010244061A8044000000030C +:1008E000041A805000010245061A805400000003DB +:1008F000041A806000010246061A806400000003AA +:10090000041A807000010247061A80740000000378 +:10091000041A808000010248061A80840000000347 +:10092000041A809000010249061A80940000000316 +:10093000041A80A00001024A061A80A400000003E5 +:10094000041A80B00001024B061A80B400000003B4 +:10095000041A80C00001024C061A80C40000000383 +:10096000041A80D00001024D061A80D40000000352 +:10097000041A80E00001024E061A80E40000000321 +:10098000041A80F00001024F061A80F400000003F0 +:10099000041A810000010250061A810400000003BD +:1009A000041A811000010251061A8114000000038C +:1009B000041A812000010252061A8124000000035B +:1009C000041A813000010253061A8134000000032A +:1009D000041A814000010254061A814400000003F9 +:1009E000041A815000010255061A815400000003C8 +:1009F000041A816000010256061A81640000000397 +:100A0000041A817000010257061A81740000000365 +:100A1000041A818000010258061A81840000000334 +:100A2000041A819000010259061A81940000000303 +:100A3000041A81A00001025A061A81A400000003D2 +:100A4000041A81B00001025B061A81B400000003A1 +:100A5000041A81C00001025C061A81C40000000370 +:100A6000041A81D00001025D061A81D4000000033F +:100A7000041A81E00001025E061A81E4000000030E +:100A8000041A81F00001025F061A81F400000003DD +:100A9000041A820000010260061A820400000003AA +:100AA000041A821000010261061A82140000000379 +:100AB000041A822000010262061A82240000000348 +:100AC000041A823000010263061A82340000000317 +:100AD000041A824000010264061A824400000003E6 +:100AE000041A825000010265061A825400000003B5 +:100AF000041A826000010266061A82640000000384 +:100B0000041A827000010267061A82740000000352 +:100B1000041A828000010268061A82840000000321 +:100B2000041A829000010269061A829400000003F0 +:100B3000041A82A00001026A061A82A400000003BF +:100B4000041A82B00001026B061A82B4000000038E +:100B5000041A82C00001026C061A82C4000000035D +:100B6000041A82D00001026D061A82D4000000032C +:100B7000041A82E00001026E061A82E400000003FB +:100B8000041A82F00001026F061A82F400000003CA +:100B9000041A830000010270061A83040000000397 +:100BA000041A831000010271061A83140000000366 +:100BB000041A832000010272061A83240000000335 +:100BC000041A833000010273061A83340000000304 +:100BD000041A834000010274061A834400000003D3 +:100BE000041A835000010275061A835400000003A2 +:100BF000041A836000010276061A83640000000371 +:100C0000041A837000010277061A8374000000033F +:100C1000041A838000010278061A8384000000030E +:100C2000041A839000010279061A839400000003DD +:100C3000041A83A00001027A061A83A400000003AC +:100C4000041A83B00001027B061A83B4000000037B +:100C5000041A83C00001027C061A83C4000000034A +:100C6000041A83D00001027D061A83D40000000319 +:100C7000041A83E00001027E061A83E400000003E8 +:100C8000041A83F00001027F061A83F400000003B7 +:100C9000041A840000010280061A84040000000384 +:100CA000041A841000010281061A84140000000353 +:100CB000041A842000010282061A84240000000322 +:100CC000041A843000010283061A843400000003F1 +:100CD000041A844000010284061A844400000003C0 +:100CE000041A845000010285061A8454000000038F +:100CF000041A846000010286061A8464000000035E +:100D0000041A847000010287061A8474000000032C +:100D1000041A848000010288061A848400000003FB +:100D2000041A849000010289061A849400000003CA +:100D3000041A84A00001028A061A84A40000000399 +:100D4000041A84B00001028B061A84B40000000368 +:100D5000041A84C00001028C061A84C40000000337 +:100D6000041A84D00001028D061A84D40000000306 +:100D7000041A84E00001028E061A84E400000003D5 +:100D8000041A84F00001028F061A84F400000003A4 +:100D9000041A850000010290061A85040000000371 +:100DA000041A851000010291061A85140000000340 +:100DB000041A852000010292061A8524000000030F +:100DC000041A853000010293061A853400000003DE +:100DD000041A854000010294061A854400000003AD +:100DE000041A855000010295061A8554000000037C +:100DF000041A856000010296061A8564000000034B +:100E0000041A857000010297061A85740000000319 +:100E1000041A858000010298061A858400000003E8 +:100E2000041A859000010299061A859400000003B7 +:100E3000041A85A00001029A061A85A40000000386 +:100E4000041A85B00001029B061A85B40000000355 +:100E5000041A85C00001029C061A85C40000000324 +:100E6000041A85D00001029D061A85D400000003F3 +:100E7000041A85E00001029E061A85E400000003C2 +:100E8000041A85F00001029F061A85F40000000391 +:100E9000041A8600000102A0061A8604000000035E +:100EA000041A8610000102A1061A8614000000032D +:100EB000041A8620000102A2061A862400000003FC +:100EC000041A8630000102A3061A863400000003CB +:100ED000041A8640000102A4061A8644000000039A +:100EE000041A8650000102A5061A86540000000369 +:100EF000041A8660000102A6061A86640000000338 +:100F0000041A8670000102A7061A86740000000306 +:100F1000041A8680000102A8061A868400000003D5 +:100F2000041A8690000102A9061A869400000003A4 +:100F3000041A86A0000102AA061A86A40000000373 +:100F4000041A86B0000102AB061A86B40000000342 +:100F5000041A86C0000102AC061A86C40000000311 +:100F6000041A86D0000102AD061A86D400000003E0 +:100F7000041A86E0000102AE061A86E400000003AF +:100F8000041A86F0000102AF061A86F4000000037E +:100F9000041A8700000102B0061A8704000000034B +:100FA000041A8710000102B1061A8714000000031A +:100FB000041A8720000102B2061A872400000003E9 +:100FC000041A8730000102B3061A873400000003B8 +:100FD000041A8740000102B4061A87440000000387 +:100FE000041A8750000102B5061A87540000000356 +:100FF000041A8760000102B6061A87640000000325 +:10100000041A8770000102B7061A877400000003F3 +:10101000041A8780000102B8061A878400000003C2 +:10102000041A8790000102B9061A87940000000391 +:10103000041A87A0000102BA061A87A40000000360 +:10104000041A87B0000102BB061A87B4000000032F +:10105000041A87C0000102BC061A87C400000003FE +:10106000041A87D0000102BD061A87D400000003CD +:10107000041A87E0000102BE061A87E4000000039C +:10108000041A87F0000102BF061A87F4000000036B +:10109000041A8800000102C0061A88040000000338 +:1010A000041A8810000102C1061A88140000000307 +:1010B000041A8820000102C2061A882400000003D6 +:1010C000041A8830000102C3061A883400000003A5 +:1010D000041A8840000102C4061A88440000000374 +:1010E000041A8850000102C5061A88540000000343 +:1010F000041A8860000102C6061A88640000000312 +:10110000041A8870000102C7061A887400000003E0 +:10111000041A8880000102C8061A888400000003AF +:10112000041A8890000102C9061A8894000000037E +:10113000041A88A0000102CA061A88A4000000034D +:10114000041A88B0000102CB061A88B4000000031C +:10115000041A88C0000102CC061A88C400000003EB +:10116000041A88D0000102CD061A88D400000003BA +:10117000041A88E0000102CE061A88E40000000389 +:10118000041A88F0000102CF061A88F40000000358 +:10119000041A8900000102D0061A89040000000325 +:1011A000041A8910000102D1061A891400000003F4 +:1011B000041A8920000102D2061A892400000003C3 +:1011C000041A8930000102D3061A89340000000392 +:1011D000041A8940000102D4061A89440000000361 +:1011E000041A8950000102D5061A89540000000330 +:1011F000041A8960000102D6061A896400000003FF +:10120000041A8970000102D7061A897400000003CD +:10121000041A8980000102D8061A8984000000039C +:10122000041A8990000102D9061A8994000000036B +:10123000041A89A0000102DA061A89A4000000033A +:10124000041A89B0000102DB061A89B40000000309 +:10125000041A89C0000102DC061A89C400000003D8 +:10126000041A89D0000102DD061A89D400000003A7 +:10127000041A89E0000102DE061A89E40000000376 +:10128000041A89F0000102DF061A89F40000000345 +:10129000041A8A00000102E0061A8A040000000312 +:1012A000041A8A10000102E1061A8A1400000003E1 +:1012B000041A8A20000102E2061A8A2400000003B0 +:1012C000041A8A30000102E3061A8A34000000037F +:1012D000041A8A40000102E4061A8A44000000034E +:1012E000041A8A50000102E5061A8A54000000031D +:1012F000041A8A60000102E6061A8A6400000003EC +:10130000041A8A70000102E7061A8A7400000003BA +:10131000041A8A80000102E8061A8A840000000389 +:10132000041A8A90000102E9061A8A940000000358 +:10133000041A8AA0000102EA061A8AA40000000327 +:10134000041A8AB0000102EB061A8AB400000003F6 +:10135000041A8AC0000102EC061A8AC400000003C5 +:10136000041A8AD0000102ED061A8AD40000000394 +:10137000041A8AE0000102EE061A8AE40000000363 +:10138000041A8AF0000102EF061A8AF40000000332 +:10139000041A8B00000102F0061A8B0400000003FF +:1013A000041A8B10000102F1061A8B1400000003CE +:1013B000041A8B20000102F2061A8B24000000039D +:1013C000041A8B30000102F3061A8B34000000036C +:1013D000041A8B40000102F4061A8B44000000033B +:1013E000041A8B50000102F5061A8B54000000030A +:1013F000041A8B60000102F6061A8B6400000003D9 +:10140000041A8B70000102F7061A8B7400000003A7 +:10141000041A8B80000102F8061A8B840000000376 +:10142000041A8B90000102F9061A8B940000000345 +:10143000041A8BA0000102FA061A8BA40000000314 +:10144000041A8BB0000102FB061A8BB400000003E3 +:10145000041A8BC0000102FC061A8BC400000003B2 +:10146000041A8BD0000102FD061A8BD40000000381 +:10147000041A8BE0000102FE061A8BE40000000350 +:10148000041A8BF0000102FF061A8BF4000000031F +:10149000041A8C0000010300061A8C0400000003EB +:1014A000041A8C1000010301061A8C1400000003BA +:1014B000041A8C2000010302061A8C240000000389 +:1014C000041A8C3000010303061A8C340000000358 +:1014D000041A8C4000010304061A8C440000000327 +:1014E000041A8C5000010305061A8C5400000003F6 +:1014F000041A8C6000010306061A8C6400000003C5 +:10150000041A8C7000010307061A8C740000000393 +:10151000041A8C8000010308061A8C840000000362 +:10152000041A8C9000010309061A8C940000000331 +:10153000041A8CA00001030A061A8CA40000000300 +:10154000041A8CB00001030B061A8CB400000003CF +:10155000041A8CC00001030C061A8CC4000000039E +:10156000041A8CD00001030D061A8CD4000000036D +:10157000041A8CE00001030E061A8CE4000000033C +:10158000041A8CF00001030F061A8CF4000000030B +:10159000041A8D0000010310061A8D0400000003D8 +:1015A000041A8D1000010311061A8D1400000003A7 +:1015B000041A8D2000010312061A8D240000000376 +:1015C000041A8D3000010313061A8D340000000345 +:1015D000041A8D4000010314061A8D440000000314 +:1015E000041A8D5000010315061A8D5400000003E3 +:1015F000041A8D6000010316061A8D6400000003B2 +:10160000041A8D7000010317061A8D740000000380 +:10161000041A8D8000010318061A8D84000000034F +:10162000041A8D9000010319061A8D94000000031E +:10163000041A8DA00001031A061A8DA400000003ED +:10164000041A8DB00001031B061A8DB400000003BC +:10165000041A8DC00001031C061A8DC4000000038B +:10166000041A8DD00001031D061A8DD4000000035A +:10167000041A8DE00001031E061A8DE40000000329 +:10168000041A8DF00001031F061A8DF400000003F8 +:10169000041A8E0000010320061A8E0400000003C5 +:1016A000041A8E1000010321061A8E140000000394 +:1016B000041A8E2000010322061A8E240000000363 +:1016C000041A8E3000010323061A8E340000000332 +:1016D000041A8E4000010324061A8E440000000301 +:1016E000041A8E5000010325061A8E5400000003D0 +:1016F000041A8E6000010326061A8E64000000039F +:10170000041A8E7000010327061A8E74000000036D +:10171000041A8E8000010328061A8E84000000033C +:10172000041A8E9000010329061A8E94000000030B +:10173000041A8EA00001032A061A8EA400000003DA +:10174000041A8EB00001032B061A8EB400000003A9 +:10175000041A8EC00001032C061A8EC40000000378 +:10176000041A8ED00001032D061A8ED40000000347 +:10177000041A8EE00001032E061A8EE40000000316 +:10178000041A8EF00001032F061A8EF400000003E5 +:10179000041A8F0000010330061A8F0400000003B2 +:1017A000041A8F1000010331061A8F140000000381 +:1017B000041A8F2000010332061A8F240000000350 +:1017C000041A8F3000010333061A8F34000000031F +:1017D000041A8F4000010334061A8F4400000003EE +:1017E000041A8F5000010335061A8F5400000003BD +:1017F000041A8F6000010336061A8F64000000038C +:10180000041A8F7000010337061A8F74000000035A +:10181000041A8F8000010338061A8F840000000329 +:10182000041A8F9000010339061A8F9400000003F8 +:10183000041A8FA00001033A061A8FA400000003C7 +:10184000041A8FB00001033B061A8FB40000000396 +:10185000041A8FC00001033C061A8FC40000000365 +:10186000041A8FD00001033D061A8FD40000000334 +:10187000041A8FE00001033E061A8FE400000007FF +:10188000041A62C00020033F061AD0000000007254 +:10189000061AD24800000010061AD6B00000002038 +:1018A000061AD47000000090061AD46800000002E6 +:1018B000061AA000000001C4061A30000000001043 +:1018C000061A308000000010061A310000000010D7 +:1018D000061A318000000010061A330000000012C2 +:1018E000061A339000000070061AD4580000000257 +:1018F000061AD34800000002061AD3580000002040 +:10190000061AA710000001C4061A3040000000109B +:10191000061A30C000000010061A31400000001006 +:10192000061A31C000000010061A334800000012E9 +:10193000061A355000000070061AD460000000023C +:10194000061AD35000000002061AD3D80000002067 +:10195000021AAE2000000000061A5000000000022B +:10196000061A508000000012041A40000002035FB3 +:10197000041A63C000020361061A7000000000042C +:10198000061A320000000008021AAE24000000000F +:10199000061A501000000002061A50C8000000127B +:1019A000041A400800020363041A63C800020365B6 +:1019B000061A701000000004061A32200000000809 +:1019C000021AAE2800000000061A50200000000293 +:1019D000061A511000000012041A4010000203679A +:1019E000041A63D000020369061A70200000000484 +:1019F000061A324000000008021AAE2C0000000057 +:101A0000061A503000000002061A51580000001259 +:101A1000041A40180002036B041A63D80002036D15 +:101A2000061A703000000004061A32600000000838 +:101A3000021AAE3000000000061A504000000002FA +:101A4000061A51A000000012041A40200002036F81 +:101A5000041A63E000020371061A704000000004DB +:101A6000061A328000000008021AAE34000000009E +:101A7000061A505000000002061A51E80000001239 +:101A8000041A402800020373041A63E80002037575 +:101A9000061A705000000004061A32A00000000868 +:101AA000021AAE3800000000061A50600000000262 +:101AB000061A523000000012041A40300002037768 +:101AC000041A63F000020379061A70600000000433 +:101AD000061A32C000000008021AAE3C00000000E6 +:101AE000061A507000000002061A52780000001218 +:101AF000041A40380002037B041A63F80002037DD5 +:101B0000061A707000000004061A32E00000000897 +:101B10000200A468000B01C80200A294071D29114D +:101B20000200A298000000000200A29C009C042475 +:101B30000200A2A0000000000200A2A4000002090E +:101B40000200A270000000000200A2740000000069 +:101B50000200A270000000000200A2740000000059 +:101B60000200A270000000000200A2740000000049 +:101B70000200A270000000000200A2740000000039 +:101B8000020160A000000001020160A400000262E6 +:101B9000020160A800000002020160AC0000001811 +:101BA0000201620400000001020100B40000000113 +:101BB000020100B800000001020100DC0000000189 +:101BC0000201010000000001020101040000000107 +:101BD0000201007C003000000201008400000028A7 +:101BE0000201008C0000000002010130000000042E +:101BF0000201025C00000001020103280000000055 +:101C0000020160580000FFFF020160700000000741 +:101C10000201608000000001020105540000003054 +:101C2000020100C400000001020100CC000000011C +:101C3000020100F800000001020100F000000001B4 +:101C4000020100800030000002010088000000282E +:101C500002010090000000000201013400000004B5 +:101C6000020102DC000000010201032C0000000060 +:101C70000201605C0000FFFF0201607400000007C9 +:101C800002016084000000010201056400000030D0 +:101C9000020100C800000001020100D000000001A4 +:101CA000020100FC00000001020100F4000000013C +:101CB000020C100000000028020C20080000021195 +:101CC000020C200C00000200020C20100000020494 +:101CD000020C201C0000FFFF020C20200000FFFF70 +:101CE000020C20240000FFFF020C20280000FFFF50 +:101CF000020C203800000020020C203C00000021D3 +:101D0000020C204000000022020C204400000023AE +:101D1000020C204800000024020C204C000000258A +:101D2000020C205000000026020C20540000002766 +:101D3000020C205800000028020C205C0000002942 +:101D4000020C20600000002A020C20640000002B1E +:101D5000020C20680000002C020C206C0000002DFA +:101D6000020C20700000002E020C20740000002FD6 +:101D7000020C207800000010060C207C00000007F8 +:101D8000020C209800000011020C209C00000012A0 +:101D9000020C20A000000013060C20A40000001D6F +:101DA000020C211800000001020C211C000000019F +:101DB000020C212000000001060C21240000001D5F +:101DC000020C219800000001060C219C0000000775 +:101DD000020C21B800000001020C21BC000000012F +:101DE000020C21C000000001020C21C4000000010F +:101DF000020C21C800000001020C21CC00000001EF +:101E0000020C21D000000001020C21D400000001CE +:101E1000020C21D800000001020C21DC00000001AE +:101E2000020C21E000000001020C21E4000000018E +:101E3000020C21E800000001020C21EC000000016E +:101E4000020C21F000000001020C21F4000000014E +:101E5000020C21F800000001060C21FC0000000724 +:101E6000020C221800000001060C221C00000007D2 +:101E7000020C223807FFFFFF020C223C0000003F4B +:101E8000020C224007FFFFFF020C22440000000F5B +:101E9000010C224800000000010C224C0000000050 +:101EA000010C225000000000010C22540000000030 +:101EB000010C225800000000010C225C0000000010 +:101EC000010C226000000000010C226400000000F0 +:101ED000010C226800000000010C226C00000000D0 +:101EE000010C227000000000010C227400000000B0 +:101EF000010C227800000000010C227C0000000090 +:101F00000C0C2000000003E80A0C20000000000177 +:101F10000B0C20000000000A020C40080000101109 +:101F2000020C400C00001000020C401000001004D5 +:101F3000020C401400001021020C401C0000FFFFA6 +:101F4000020C40200000FFFF020C40240000FFFFB5 +:101F5000020C40280000FFFF020C40380000004641 +:101F6000020C403C00000010060C40400000000243 +:101F7000020C404800000018020C404C000000F029 +:101F8000060C40500000001F020C40CC0000000175 +:101F9000060C40D00000003A020C41B800000001DD +:101FA000060C41BC00000003020C41C80000000107 +:101FB000020C41CC00000001060C41D00000001AC8 +:101FC000020C423807FFFFFF020C423C0000003FBA +:101FD000020C424007FFFFFF020C42440000000FCA +:101FE000010C424800000000010C424C00000000BF +:101FF000010C425000000000010C4254000000009F +:10200000010C425800000000010C425C000000007E +:10201000010C426000000000010C4264000000005E +:10202000010C426800000000010C426C000000003E +:10203000010C427000000000010C4274000000001E +:10204000010C427800000000010C427C00000000FE +:10205000010C4280000000000C0C4000000003E86E +:102060000A0C4000000000010B0C40000000000AB8 +:10207000060D400000000A00020D0044000000327E +:10208000020D008C02150020020D009002150020A8 +:10209000020D009408100000020D009800000033AB +:1020A000020D009C00000002020D00A000000000D4 +:1020B000020D00A400000005020D00A800000005AC +:1020C000060D00AC00000002020D00B4000000028A +:1020D000020D00B800000003020D00BC0000000269 +:1020E000020D00C000000001020D00C80000000247 +:1020F000020D00CC00000002020D015C0000000196 +:10210000020D016400000001020D016800000002E0 +:10211000020D020400000001020D020C000000206C +:10212000020D021000000040020D021400000040E9 +:10213000020D022000000003020D0224000000181E +:10214000060D028000000012040D03000018037F3A +:10215000060D03600000000C020D004C00000001A1 +:10216000020D005000000002020D005400000000AB +:10217000020D005800000008060D005C000000047D +:10218000020D00C400000004020D00040000000164 +:10219000020D000800000001020D000C000000010B +:1021A000020D001000000001020D001400000001EB +:1021B000020D001800000001020D001C00000001CB +:1021C000020D002000000001020D002400000001AB +:1021D000020D002800000001020D002C000000018B +:1021E000020D003000000001020D0034000000016B +:1021F000020D003800000001020D003C000000014B +:10220000020D011400000009020D011C0000000A6B +:10221000020D012400000000020D012C000000004E +:10222000020D013400000000020D013C0000000B13 +:10223000020D014400000000020D011800000029F9 +:10224000020D01200000002A020D012800000020DC +:10225000020D013000000020020D013800000020B6 +:10226000020D01400000002B020D0148000000207B +:10227000020D011400000019020D011C0000001ADB +:10228000020D012400000010020D012C00000010BE +:10229000020D013400000010020D013C0000001B83 +:1022A000020D014400000010020D01180000003969 +:1022B000020D01200000003A020D0128000000304C +:1022C000020D013000000030020D01380000003026 +:1022D000020D01400000003B020D014800000030EB +:1022E000020D011400000049020D011C0000004A0B +:1022F000020D012400000040020D012C00000040EE +:10230000020D013400000040020D013C0000004BB2 +:10231000020D014400000040020D01180000006998 +:10232000020D01200000006A020D0128000000607B +:10233000020D013000000060020D01380000006055 +:10234000020D01400000006B020D0148000000601A +:10235000020D011400000059020D011C0000005A7A +:10236000020D012400000050020D012C000000505D +:10237000020D013400000050020D013C0000005B22 +:10238000020D014400000050020D01180000007908 +:10239000020D01200000007A020D012800000070EB +:1023A000020D013000000070020D013800000070C5 +:1023B000020D01400000007B020D0148000000708A +:1023C000060E200000000800020E004C0000003243 +:1023D000020E009402150020020E00980215002043 +:1023E000020E009C00000030020E00A00810000049 +:1023F000020E00A400000033020E00A8000000300E +:10240000020E00AC00000031020E00B0000000021D +:10241000020E00B400000004020E00B8000000002C +:10242000020E00BC00000002020E00C0000000020C +:10243000020E00C400000000020E00C800000002EE +:10244000020E00CC00000007020E00D000000002C7 +:10245000020E00D400000002020E00D800000001AD +:10246000020E014400000001020E014C00000001B8 +:10247000020E015000000002020E020400000001E2 +:10248000020E020C00000040020E0210000000408C +:10249000020E021C00000004020E022000000020B8 +:1024A000020E02240000000E020E02280000001B93 +:1024B000060E030000000012040E0280001B0397AA +:1024C000060E02EC00000005020E00540000000C95 +:1024D000020E00580000000C020E005C000000001C +:1024E000020E006000000010020E006400000010E8 +:1024F000060E006800000003020E00DC000000036E +:10250000020E000400000001020E0008000000019D +:10251000020E000C00000001020E0010000000017D +:10252000020E001400000001020E0018000000015D +:10253000020E001C00000001020E0020000000013D +:10254000020E002400000001020E0028000000011D +:10255000020E002C00000001020E003000000001FD +:10256000020E003400000001020E003800000001DD +:10257000020E003C00000001020E004000000001BD +:10258000020E004400000001020E01100000000FC6 +:10259000020E011800000000020E012000000000E1 +:1025A000020E012800000000020E01140000002F9E +:1025B000020E011C00000020020E01240000000099 +:1025C000020E012C00000000020E01100000001F8E +:1025D000020E011800000010020E01200000000091 +:1025E000020E012800000000020E01140000003F4E +:1025F000020E011C00000030020E01240000000049 +:10260000020E012C00000000020E01100000004F1D +:10261000020E011800000040020E01200000000020 +:10262000020E012800000000020E01140000006FDD +:10263000020E011C00000060020E012400000000D8 +:10264000020E012C00000000020E01100000005FCD +:10265000020E011800000050020E012000000000D0 +:10266000020E012800000000020E01140000007F8D +:10267000020E011C00000070020E01240000000088 +:10268000020E012C000000000730040000C9000009 +:10269000083007D8000503B20734000033320000C9 +:1026A0000734800030A70CCD07350000353518F70A +:1026B000073580002A6226450736000018D330DE31 +:1026C00008364660373403B40130000000000000D3 +:1026D000013000040000000001300008000000008C +:1026E0000130000C0000000001300010000000006C +:1026F0000130001400000000023000200000000142 +:102700000230002400000002023000280000000314 +:102710000230002C000000000230003000000004F5 +:1027200002300034000000010230003800000000D8 +:102730000230003C000000010230004000000004B4 +:102740000230004400000000023000480000000198 +:102750000230004C00000003023000500000000076 +:102760000230005400000001023000580000000454 +:102770000230005C00000000023000600000000138 +:102780000230006400000003023000680000000016 +:102790000230006C000000010230007000000004F4 +:1027A00002300074000000000230007800000004D5 +:1027B0000230007C000000030630008000000002B0 +:1027C000023000A400003FFF023000A8000003FF19 +:1027D0000230022400000000023002340000000039 +:1027E0000230024C00000000023002E40000FFFF53 +:1027F000063020000000080002338BC000000001FA +:10280000023380000000001A023380400000004EB6 +:102810000233808000000010023380C000000020DE +:102820000C3383000007A1200A3383000000013825 +:102830000B338300000013880A338340000000003C +:102840000C338340000001F40B338340000000058B +:10285000023383800007A120023383C0000001F40B +:1028600002331480000000010A33148000000000CD +:10287000063280000000010206322008000000C875 +:10288000063220000000000204328EA0001003B6C1 +:1028900006323EB00000000606323ED800000002BC +:1028A00006323E800000000A04323EA8000203C641 +:1028B00006323E00000000200632500000000400F6 +:1028C0000632400000000004043274C0000203C855 +:1028D00006324110000000020632D0000000003035 +:1028E0000632DD40000000440632DA00000000D06D +:1028F0000632DEA0000000020632E0000000080000 +:1029000006328450000001180632100000000188D1 +:102910000632500000000020063251000000002066 +:102920000632520000000020063253000000002052 +:10293000063254000000002006325500000000203E +:10294000063256000000002006325700000000202A +:102950000632580000000020063259000000002016 +:1029600006325A000000002006325B000000002002 +:1029700006325C000000002006325D0000000020EE +:1029800006325E000000002006325F0000000020DA +:1029900006328DF00000000204328E00000203CAED +:1029A00006328E08000000020632DE9000000002AF +:1029B00006321C4000000038063288B000000118C2 +:1029C00006321620000001880632508000000020E8 +:1029D00006325180000000200632528000000020A4 +:1029E0000632538000000020063254800000002090 +:1029F000063255800000002006325680000000207C +:102A00000632578000000020063258800000002067 +:102A1000063259800000002006325A800000002053 +:102A200006325B800000002006325C80000000203F +:102A300006325D800000002006325E80000000202B +:102A400006325F800000002006328DF80000000290 +:102A500004328E10000203CC06328E1800000002F1 +:102A60000632DE980000000206321D200000003809 +:102A700002328D50000000000632401000000002BB +:102A800002328D5400000000063240200000000297 +:102A900002328D5800000000063240300000000273 +:102AA00002328D5C0000000006324040000000024F +:102AB00002328D600000000006324050000000022B +:102AC00002328D6400000000063240600000000207 +:102AD00002328D68000000000632407000000002E3 +:102AE00002328D6C000000000632408000000002BF +:102AF000072004000091000008200780001003CE8A +:102B0000072400002AF300000724800015090ABDED +:102B10000824A9F0692803D001200000000000006B +:102B20000120000400000000012000080000000057 +:102B30000120000C00000000012000100000000037 +:102B4000012000140000000002200020000000010D +:102B500002200024000000020220002800000003E0 +:102B60000220002C000000000220003000000004C1 +:102B700002200034000000010220003800000000A4 +:102B80000220003C00000001022000400000000480 +:102B90000220004400000000022000480000000164 +:102BA0000220004C00000003022000500000000042 +:102BB0000220005400000001022000580000000420 +:102BC0000220005C00000000022000600000000104 +:102BD00002200064000000030220006800000000E2 +:102BE0000220006C000000010220007000000004C0 +:102BF00002200074000000000220007800000004A1 +:102C00000220007C0000000306200080000000027B +:102C1000022000A400003FFF022000A8000003FFE4 +:102C20000220022400000000022002340000000004 +:102C30000220024C00000000022002E40000FFFF1E +:102C4000062020000000080002238BC000000001C5 +:102C500002238000000000100223804000000012C8 +:102C60000223808000000030022380C00000000E9C +:102C70000C2383000007A1200A23830000000138F1 +:102C80000B238300000013880A2383400000000008 +:102C90000C238340000001F40B2383400000000557 +:102CA000022383800007A120022383C0000001F4D7 +:102CB00002231480000000010A2314800000000099 +:102CC000062210000000004206222008000000C872 +:102CD00006222000000000020622B000000000C60C +:102CE0000422B318000503D20622B32C0000000B07 +:102CF0000422B358000503D70622B36C0000000B72 +:102D00000422B398000503DC0622B3AC0000000BDC +:102D10000422B3D8000503E10622B3EC0000000B47 +:102D20000422B418000503E60622B42C0000000BB0 +:102D30000422B458000503EB0622B46C0000000B1B +:102D40000422B498000503F00622B4AC0000000B86 +:102D50000422B4D8000503F50622B4EC0000000BF1 +:102D60000422B518000503FA0622B52C0000000B5A +:102D70000422B558000503FF0622B56C0000000BC5 +:102D80000422B598000504040622B5AC0000000B2F +:102D90000422B5D8000504090622B5EC0000000B9A +:102DA0000422B6180005040E0622B62C0000000B03 +:102DB0000422B658000504130622B66C0000000B6E +:102DC0000422B698000504180622B6AC0000000BD9 +:102DD0000422B6D80005041D0622B6EC0000000B44 +:102DE0000422B718000504220622B72C0000000BAD +:102DF0000422B758000504270622B76C0000000B18 +:102E00000422B7980005042C0622B7AC0000000B82 +:102E10000422B7D8000504310622B7EC0000000BED +:102E20000422B818000504360622B82C0000000B56 +:102E30000422B8580005043B0622B86C0000000BC1 +:102E40000422B898000504400622B8AC0000000B2C +:102E50000422B8D8000504450622B8EC0000000B97 +:102E60000422B9180005044A0622B92C0000000B00 +:102E70000422B9580005044F0622B96C0000000B6B +:102E80000422B998000504540622B9AC0000000BD6 +:102E90000422B9D8000504590622B9EC0000000B41 +:102EA0000422BA180005045E0622BA2C0000000BAA +:102EB0000422BA58000504630622BA6C0000000B15 +:102EC0000422BA98000504680622BAAC0000000B80 +:102ED0000422BAD80005046D0622BAEC00000005F1 +:102EE0000622BB00000000530422BC4C0001047207 +:102EF0000622BC50000000030422BC5C00010473E5 +:102F00000622BC60000000030422BC6C00010474B3 +:102F10000622BC70000000030422BC7C0001047582 +:102F20000622BC80000000030422BC8C0001047651 +:102F30000622BC90000000030422BC9C0001047720 +:102F40000622BCA0000000030422BCAC00010478EF +:102F50000622BCB0000000030422BCBC00010479BE +:102F60000622880000000100062280000000020006 +:102F7000042212700010047A06223000000000C003 +:102F800006226700000001000622900000000400F5 +:102F900004226B080020048A022212C0FFFFFFFFF8 +:102FA000062211E800000002062212C800000009F3 +:102FB000062212EC0000000906228C000000000826 +:102FC0000222114800000000062213200000000623 +:102FD000062233000000000206226040000000309C +:102FE00006228C20000000080222114C0000000084 +:102FF00006221338000000060622330800000002F3 +:10300000062261000000003006228C40000000080B +:10301000022211500000000006221350000000069A +:103020000622331000000002062261C000000030BA +:1030300006228C60000000080222115400000000EB +:103040000622136800000006062233180000000262 +:10305000062262800000003006228C8000000008FA +:103060000222115800000000062213800000000612 +:1030700006223320000000020622634000000030D8 +:1030800006228CA0000000080222115C0000000053 +:1030900006221398000000060622332800000002D2 +:1030A000062264000000003006228CC000000008E8 +:1030B0000222116000000000062213B0000000068A +:1030C0000622333000000002062264C000000030F7 +:1030D00006228CE0000000080222116400000000BB +:1030E000062213C800000006062233380000000242 +:1030F0000622658000000030021610000000002843 +:1031000002170008000000020217002C0000000354 +:103110000217003C000000040217004800000002F3 +:103120000217004C000000900217005000000090B1 +:103130000217005400800090021700580810000089 +:10314000021700600000008A02170064000000807F +:1031500002170068000000810217006C0000008068 +:10316000021700700000000602170078000007D068 +:103170000217007C0000076C02170038007C100466 +:10318000021700040000000F061640240000000291 +:10319000021640700000001C0216420800000001E8 +:1031A0000216421000000001021642200000000139 +:1031B0000216422800000001021642300000000101 +:1031C00002164238000000010216426000000002B0 +:1031D0000C16401C0003D0900A16401C0000009CF6 +:1031E0000B16401C000009C4021640300000000805 +:1031F000021640340000000C021640380000001097 +:1032000002164044000000200216400000000001A9 +:10321000021640D80000000102164008000000011C +:103220000216400C000000010216401000000001D0 +:103230000216424000000000021642480000000052 +:103240000616427000000002021642500000000004 +:1032500002164258000000000616428000000002DC +:1032600002166008000012240216600C0000121002 +:1032700002166010000012140216601C0000FFFF0E +:10328000021660200000FFFF021660240000FFFF0E +:10329000021660280000FFFF0216603800000020C0 +:1032A0000216603C0000002006166040000000028C +:1032B00002166048000000230216604C0000002443 +:1032C000021660500000002502166054000000261F +:1032D00002166058000000270216605C00000029FA +:1032E000021660600000002A021660640000002BD5 +:1032F000021660680000002C0216606C0000002DB1 +:1033000002166070000000EC0216607400000011EC +:1033100002166078000000120616607C0000000FA4 +:10332000021660B800000001021660BC0000000137 +:10333000061660C00000000C021660F000000001DC +:10334000061660F400000031021661B800000001AA +:10335000061661BC0000000D021661F000000001BD +:10336000061661F4000000110216623807FFFFFF25 +:103370000216623C0000003F0216624007FFFFFF9A +:10338000021662440000000F0116624800000000AF +:103390000116624C0000000001166250000000009F +:1033A000011662540000000001166258000000007F +:1033B0000116625C0000000001166260000000005F +:1033C000011662640000000001166268000000003F +:1033D0000116626C0000000001166270000000001F +:1033E00001166274000000000116627800000000FF +:1033F0000116627C000000000C166000000003E86B +:103400000A166000000000010B1660000000000AB0 +:1034100002168040000000060216804400000005ED +:10342000021680480000000A0216804C00000005C9 +:103430000216805400000002021680CC0000000436 +:10344000021680D000000004021680D400000004A0 +:10345000021680D800000004021680DC0000000480 +:10346000021680E000000004021680E40000000460 +:10347000021680E800000004021688040000000420 +:10348000021680300000007C021680340000003DEF +:10349000021680380000003F0216803C0000009CAD +:1034A000021680F000000007061680F400000005F8 +:1034B0000216880C010101010216810800000000BB +:1034C0000216810C000000040216811000000004A6 +:1034D0000216811400000002021688100801200460 +:1034E00002168118000000050216811C000000056C +:1034F000021681200000000502168124000000054C +:103500000216882C200810010216812800000008ED +:103510000216812C00000006021681300000000710 +:1035200002168134000000000216883001010120DB +:1035300006168138000000040216883401010101DA +:1035400002168148000000000216814C00000004B1 +:10355000021681500000000402168154000000028F +:103560000216883808012004021681580000000560 +:103570000216815C00000005021681600000000553 +:1035800002168164000000050216883C2008100124 +:1035900002168168000000080216816C0000000617 +:1035A00002168170000000070216817400000001FD +:1035B00002168840010101200216817800000001F6 +:1035C0000216817C000000010216818000000001CB +:1035D00002168184000000010216884401010101E5 +:1035E00002168188000000010216818C0000000490 +:1035F000021681900000000402168194000000026F +:10360000021688480801200402168198000000056F +:103610000216819C00000005021681A00000000532 +:10362000021681A40000000502168814200810016B +:10363000021681A800000008021681AC00000006F6 +:10364000021681B000000007021681B400000001DC +:103650000216881801010120021681B8000000013D +:10366000021681BC00000001021681C000000001AA +:10367000021681C4000000010216881C010101012C +:10368000021681C800000001021681CC000000046F +:10369000021681D000000004021681D4000000024E +:1036A0000216882008012004021681D800000005B7 +:1036B000021681DC00000005021681E00000000512 +:1036C000021681E40000000502168824200810017B +:1036D000021681E800000008021681EC00000006D6 +:1036E000021681F0000000070216E40C0000000042 +:1036F00002168828010101200616E41000000004CB +:103700000216E000010101010216E42000000000A1 +:103710000216E424000000040216E428000000045D +:103720000216E42C000000020216E0040801200446 +:103730000216E430000000050216E4340000000523 +:103740000216E438000000050216E43C0000000503 +:103750000216E008200810010216E44000000008EC +:103760000216E444000000060216E44800000007C8 +:103770000216E44C000000000216E00C01010120DA +:103780000616E450000000040216E01001010101D9 +:103790000216E460000000000216E4640000000469 +:1037A0000216E468000000040216E46C0000000247 +:1037B0000216E014080120040216E470000000055F +:1037C0000216E474000000050216E478000000050B +:1037D0000216E47C000000050216E0182008100123 +:1037E0000216E480000000080216E48400000006CF +:1037F0000216E488000000070216E48C00000001B5 +:103800000216E01C010101200216E49000000001F4 +:103810000216E494000000010216E4980000000182 +:103820000216E49C000000010216E02001010101E3 +:103830000216E4A0000000010216E4A40000000447 +:103840000216E4A8000000040216E4AC0000000226 +:103850000216E024080120040216E4B0000000056E +:103860000216E4B4000000050216E4B800000005EA +:103870000216E4BC000000050216E0282008100132 +:103880000216E4C0000000080216E4C400000006AE +:103890000216E4C8000000070216E4CC0000000194 +:1038A0000216E02C010101200216E4D00000000104 +:1038B0000216E4D4000000010216E4D80000000162 +:1038C0000216E4DC000000010216E03001010101F3 +:1038D0000216E4E0000000010216E4E40000000427 +:1038E0000216E4E8000000040216E4EC0000000206 +:1038F0000216E034080120040216E4F0000000057E +:103900000216E4F4000000050216E4F800000005C9 +:103910000216E4FC000000050216E0382008100141 +:103920000216E500000000080216E504000000068B +:103930000216E508000000070216E03C0101012024 +:1039400002168240003F003F021682440000000041 +:103950000216E524003F003F0216E52800000000A3 +:1039600002168248000000000216824C003F003F11 +:103970000216E52C000000000216E530003F003F73 +:10398000021682500100010002168254010001005B +:103990000216E534010001000216E53801000100BD +:1039A00006168258000000020216E53C00000000E6 +:1039B0000216E540000000000216826000C000C050 +:1039C0000216826400C000C00216E54400C000C0B8 +:1039D0000216E54800C000C0021682681E001E00E4 +:1039E0000216826C1E001E000216E54C1E001E0010 +:1039F0000216E5501E001E000216827040004000B4 +:103A000002168274400040000216E5544000400057 +:103A10000216E558400040000216827880008000BF +:103A20000216827C800080000216E55C8000800027 +:103A30000216E560800080000216828020002000CF +:103A400002168284200020000216E5642000200077 +:103A50000216E56820002000061682880000000299 +:103A60000216E56C000000000216E5700000000080 +:103A700002168290000000000216829400000000EE +:103A80000216E574000000000216E5780000000050 +:103A900002168298000000000216829C00000000BE +:103AA0000216E57C000000000216E5800000000020 +:103AB000021682A000000000021682A4000000018D +:103AC000061682A80000000A021681F400000C0805 +:103AD000021681F800000040021681FC000001007F +:103AE0000216820000000020021682040000001767 +:103AF00002168208000000800216820C00000200FC +:103B000002168210000000000216821801FF01FF59 +:103B10000216821401FF01FF0216E51001FF01FFEA +:103B20000216E50C01FF01FF0216823C00000013A3 +:103B3000021680900000013F0216806000000140E4 +:103B40000216806400000140061680680000000232 +:103B500002168070000000C0061680740000000786 +:103B60000216809C00000048021680A00000004859 +:103B7000061680A400000002021680AC0000004877 +:103B8000061680B000000007021682380000800090 +:103B900002168234000025E40216809400007FFFA4 +:103BA00002168220000F000F0216821C000F000F69 +:103BB0000216E518000F000F0216E514000F000FA3 +:103BC000021682280000000002168224FFFFFFFF79 +:103BD0000216E520000000000216E51CFFFFFFFFB3 +:103BE0000216E6BC000000000216E6C0000000025B +:103BF0000216E6C4000000010216E6C80000000339 +:103C00000216E6CC000000040216E6D00000000612 +:103C10000216E6D4000000050216E6D800000007F0 +:103C2000021680EC000000FF0214000000000001FA +:103C30000214000C0000000102140040000000010A +:103C40000214004400007FFF0214000C000000007A +:103C500002140000000000000214006C00000000CC +:103C600002140004000000010214003000000001F2 +:103C700002140004000000000214005C00000000B8 +:103C800002140008000000010214003400000001CA +:103C90000214000800000000021400600000000090 +:103CA00006028000000020000202005800000032DE +:103CB000020200A003150020020200A40315002048 +:103CC000020200A801000030020200AC081000004F +:103CD000020200B000000033020200B40000003015 +:103CE000020200B800000031020200BC0000000324 +:103CF000020200C000000006020200C4000000032F +:103D0000020200C800000003020200CC0000000212 +:103D1000020200D000000000020200D400000002F5 +:103D2000020200DC00000000020200E000000006C9 +:103D3000020200E400000004020200E800000002A9 +:103D4000020200EC00000002020200F0000000018C +:103D5000020200FC00000006020201200000000038 +:103D60000202013400000002020201B00000000162 +:103D70000202020C00000001020202140000000115 +:103D80000202021800000002020204040000000106 +:103D90000202040C00000040020204100000004077 +:103DA0000202041C000000040202042000000020A3 +:103DB0000202042400000002020204280000002085 +:103DC000060205000000001204020480002004AA7C +:103DD000020200600000000F020200640000000701 +:103DE00002020068000000000202006C0000000EE9 +:103DF000020200700000000E0602007400000003C2 +:103E0000020200F4000000040202000400000001AD +:103E100002020008000000010202000C0000000184 +:103E20000202001000000001020200140000000164 +:103E300002020018000000010202001C0000000144 +:103E40000202002000000001020200240000000124 +:103E500002020028000000010202002C0000000104 +:103E600002020030000000010202003400000001E4 +:103E700002020038000000010202003C00000001C4 +:103E800002020040000000010202004400000001A4 +:103E900002020048000000010202004C0000000184 +:103EA000020200500000000102020108000000C8E8 +:103EB0000202011800000002020201C4000000001A +:103EC000020201CC00000000020201D40000000246 +:103ED000020201DC00000002020201E4000000FF17 +:103EE000020201EC000000FF0202010000000000DD +:103EF0000202010C000000C80202011C00000002C6 +:103F0000020201C800000000020201D0000000000F +:103F1000020201D800000002020201E000000002DB +:103F2000020201E8000000FF020201F0000000FFB1 +:103F3000020201040000000002020108000000C8A3 +:103F40000202011800000002020201C40000000089 +:103F5000020201CC00000000020201D400000002B5 +:103F6000020201DC00000002020201E4000000FF86 +:103F7000020201EC000000FF02020100000000004C +:103F80000202010C000000C80202011C0000000235 +:103F9000020201C800000000020201D0000000007F +:103FA000020201D800000002020201E0000000024B +:103FB000020201E8000000FF020201F0000000FF21 +:103FC000020201040000000002020108000000C813 +:103FD0000202011800000002020201C400000000F9 +:103FE000020201CC00000000020201D40000000225 +:103FF000020201DC00000002020201E4000000FFF6 +:10400000020201EC000000FF0202010000000000BB +:104010000202010C000000C80202011C00000002A4 +:10402000020201C800000000020201D000000000EE +:10403000020201D800000002020201E000000002BA +:10404000020201E8000000FF020201F0000000FF90 +:10405000020201040000000002020108000000C882 +:104060000202011800000002020201C40000000068 +:10407000020201CC00000000020201D40000000294 +:10408000020201DC00000002020201E4000000FF65 +:10409000020201EC000000FF02020100000000002B +:1040A0000202010C000000C80202011C0000000214 +:1040B000020201C800000000020201D0000000005E +:1040C000020201D800000002020201E0000000022A +:1040D000020201E8000000FF020201F0000000FF00 +:1040E00002020104000000000728040000A00000F4 +:1040F000082807B8000904CA072C000034DA0000B9 +:10410000072C800038F80D37072D000037B91B76D3 +:10411000072D800031782965072E00001C7A35C4F0 +:10412000082E48E036E404CC01280000000000001E +:104130000128000400000000012800080000000021 +:104140000128000C00000000012800100000000001 +:1041500001280014000000000228002000000001D7 +:1041600002280024000000020228002800000003AA +:104170000228002C0000000002280030000000048B +:10418000022800340000000102280038000000006E +:104190000228003C0000000102280040000000044A +:1041A000022800440000000002280048000000012E +:1041B0000228004C0000000302280050000000000C +:1041C00002280054000000010228005800000004EA +:1041D0000228005C000000000228006000000001CE +:1041E00002280064000000030228006800000000AC +:1041F0000228006C0000000102280070000000048A +:10420000022800740000000002280078000000046A +:104210000228007C00000003062800800000000245 +:10422000022800A400003FFF022800A8000003FFAE +:1042300002280224000000000228023400000000CE +:104240000228024C00000000022802E40000FFFFE8 +:104250000628200000000800022B8BC0000000018F +:10426000022B800000000000022B8040000000189C +:10427000022B80800000000C022B80C00000006632 +:104280000C2B83000007A1200A2B830000000138BB +:104290000B2B8300000013880A2B834000000000D2 +:1042A0000C2B8340000001F40B2B83400000000521 +:1042B000022B83800007A120022B83C0000001F4A1 +:1042C000022B1480000000010A2B14800000000063 +:1042D000062A9AF800000004042A9B08000204CE73 +:1042E000062A9B1000000006062A90800000004865 +:1042F000062A2008000000C8062A2000000000024C +:10430000062A91A800000086062A900000000020DE +:10431000062A93C800000003042A93D4000104D0A5 +:10432000062A9DA800000002042A9498000404D1E3 +:10433000042A9D58000104D5062A9D5C0000001146 +:10434000042ACB20001004D6042A3000000204E620 +:10435000062A300800000100062A40400000001034 +:10436000042A4000001004E8042A8408000204F82B +:10437000062A9DA000000002062AB000000000509E +:10438000062ABB7000000070062AB150000000022F +:10439000062ABB6000000004062AD00000000800C6 +:1043A000062AC00000000150062A94A8000000322E +:1043B000062A502000000002062A503000000002A9 +:1043C000062A500000000002062A501000000002D9 +:1043D000022A520800000001042A9B28000204FA65 +:1043E000062A963800000022042A96C0000104FC28 +:1043F000062A96C400000003062A976800000022DF +:10440000042A97F0000104FD062A97F40000000337 +:10441000062A989800000022042A9920000104FE30 +:10442000062A992400000003062A99C800000022E9 +:10443000042A9A50000104FF062A9A54000000033F +:10444000062AB14000000002062AC54000000150C3 +:10445000062A957000000032062A5028000000024B +:10446000062A503800000002062A50080000000208 +:10447000062A501800000002022A520C0000000117 +:10448000042A9B3000020500062A96D00000002274 +:10449000042A975800010502062A975C00000003D1 +:1044A000062A980000000022042A988800010503CB +:1044B000062A988C00000003062A9930000000228A +:1044C000042A99B800010504062A99BC00000003DB +:1044D000062A9A6000000022042A9AE800010505D5 +:1044E000062A9AEC00000003062AB14800000002E8 +:1044F000022ACA8000000000042A9B38001005062A +:10450000062A50480000000E022ACA84000000005B +:10451000042A9B7800100516062A50800000000E21 +:10452000022ACA8800000000042A9BB80010052651 +:10453000062A50B80000000E022ACA8C00000000B3 +:10454000042A9BF800100536062A50F00000000EE1 +:10455000022ACA9000000000042A9C380010054678 +:10456000062A51280000000E022ACA94000000000A +:10457000042A9C7800100556062A51600000000E9F +:10458000022ACA9800000000042A9CB800100566A0 +:10459000062A51980000000E022ACA9C0000000062 +:1045A000042A9CF800100576062A51D00000000E5F +:1045B000021010080000000102101050000000015D +:1045C000021010000003D000021010040000003D93 +:1045D0000910180002000586091011000010078656 +:1045E0000610114000000008091011600010079625 +:1045F000061011A00000001806102400000000E0C2 +:104600000210201C00000000021020200000000109 +:10461000021020C00000000202102004000000016F +:10462000021020080000000109103C00000507A648 +:1046300009103800000507AB09103820000507B045 +:1046400006104C000000010002104028000000107D +:104650000210404400003FFF0210405800280000B4 +:10466000021040840084924A02104058000000006A +:104670000210800000001080021080AC00000000DA +:1046800002108038000000100210810000000000BD +:10469000061081200000000202108008000002B510 +:1046A0000210801000000000061082000000004A86 +:1046B000021081080001FFFF061081400000000287 +:1046C0000210800000001A800610900000000024F4 +:1046D000061091200000004A061093700000004A66 +:1046E000061095C00000004A0210800400001080EF +:1046F000021080B0000000010210803C0000001099 +:104700000210810400000000061081280000000251 +:104710000210800C000002B502108014000000009E +:10472000061084000000004A0210810C0001FFFF07 +:1047300006108148000000020210800400001A8068 +:104740000610909000000024061092480000004AD5 +:10475000061094980000004A061096E80000004AEF +:104760000210800000001080021080AC00000002E7 +:1047700002108038000000100210810000000000CC +:10478000061081200000000202108008000002B51F +:104790000210801000000000061082000000004A95 +:1047A000021081080001FFFF061081400000000296 +:1047B0000210800000001A80061090000000002403 +:1047C000061091200000004A061093700000004A75 +:1047D000061095C00000004A0210800400001080FE +:1047E000021080B0000000030210803C00000010A6 +:1047F0000210810400000000061081280000000261 +:104800000210800C000002B50210801400000000AD +:10481000061084000000004A0210810C0001FFFF16 +:1048200006108148000000020210800400001A8077 +:104830000610909000000024061092480000004AE4 +:10484000061094980000004A061096E80000004AFE +:104850000210800000001080021080AC00000004F4 +:1048600002108038000000100210810000000000DB +:10487000061081200000000202108008000002B52E +:104880000210801000000000061082000000004AA4 +:10489000021081080001FFFF0610814000000002A5 +:1048A0000210800000001A80061090000000002412 +:1048B000061091200000004A061093700000004A84 +:1048C000061095C00000004A02108004000010800D +:1048D000021080B0000000050210803C00000010B3 +:1048E0000210810400000000061081280000000270 +:1048F0000210800C000002B50210801400000000BD +:10490000061084000000004A0210810C0001FFFF25 +:1049100006108148000000020210800400001A8086 +:104920000610909000000024061092480000004AF3 +:10493000061094980000004A061096E80000004A0D +:104940000210800000001080021080AC0000000601 +:1049500002108038000000100210810000000000EA +:10496000061081200000000202108008000002B53D +:104970000210801000000000061082000000004AB3 +:10498000021081080001FFFF0610814000000002B4 +:104990000210800000001A80061090000000002421 +:1049A000061091200000004A061093700000004A93 +:1049B000061095C00000004A02108004000010801C +:1049C000021080B0000000070210803C00000010C0 +:1049D000021081040000000006108128000000027F +:1049E0000210800C000002B50210801400000000CC +:1049F000061084000000004A0210810C0001FFFF35 +:104A000006108148000000020210800400001A8095 +:104A10000610909000000024061092480000004A02 +:104A2000061094980000004A061096E80000004A1C +:104A3000021205B0000000010212049000E383405E +:104A40000212051400003C100212066C0000000166 +:104A5000021206700000000002120494FFFFFFFF24 +:104A600002120498FFFFFFFF0212049CFFFFFFFFEA +:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA +:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA +:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82 +:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A +:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A +:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 +:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 +:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 +:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 +:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 +:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 +:104B200002120504FFFFFFFF02120508FFFFFFFF4F +:104B30000212050CFFFFFFFF02120510FFFFFFFF2F +:104B4000021204D4FF809000021204B4F00050005E +:104B5000021204B8F00010000212039000000008D6 +:104B60000212039C00000008021203A000000008CB +:104B7000021203A400000002021203BC00000004A1 +:104B8000021203C000000005021203C4000000046A +:104B9000021203D0000000000212036C00000001AA +:104BA000021203680000003F021201BC0000004036 +:104BB000021201C000001808021201C4000008031C +:104BC000021201C800000803021201CC00000040DC +:104BD000021201D000000003021201D400000803F9 +:104BE000021201D800000803021201DC00000803D1 +:104BF000021201E000010003021201E400000803B8 +:104C0000021201E800000803021201EC0000000398 +:104C1000021201F000000003021201F40000000380 +:104C2000021201F800000003021201FC0000000360 +:104C3000021202000000000302120204000000033E +:104C400002120208000000030212020C000000031E +:104C500002120210000000030212021400000003FE +:104C600002120218000000030212021C00000003DE +:104C700002120220000000030212022400000003BE +:104C800002120228000024030212022C0000002F4E +:104C90000212023000000009021202340000001962 +:104CA00002120238000001840212023C000001835B +:104CB0000212024000000306021202440000001922 +:104CC00002120248000000060212024C0000030615 +:104CD00002120250000003060212025400000306F2 +:104CE0000212025800000C860212025C0000030649 +:104CF00002120260000003060212026400000006B5 +:104D000002120268000000060212026C0000000697 +:104D10000212027000000006021202740000000677 +:104D200002120278000000060212027C0000000657 +:104D30000212028000000006021202840000000637 +:104D400002120288000000060212028C0000000617 +:104D500002120290000000060212029400000006F7 +:104D600002120298000000060212029C00000006D7 +:104D7000021202A000000306021202A400000013A7 +:104D8000021202A800000006021202B00000100485 +:104D9000021202B400001004021203240010644046 +:104DA0000212032800106440021205B40000000142 +:104DB000021201B0000000010600A0000000000C7B +:104DC0000200A050000000000200A05400000000FB +:104DD0000200A0EC555400000200A0F055555555B6 +:104DE0000200A0F4000055550200A0F8F0000000F9 +:104DF0000200A0FC555400000200A1005555555575 +:104E00000200A104000055550200A108F0000000B6 +:104E10000200A18C555400000200A1905555555533 +:104E20000200A194000055550200A198F000000076 +:104E30000200A19C000000000200A1A000010000EF +:104E40000200A1A4000050140200A1A8000000006C +:104E50000200A45C00000C000200A61C000000037D +:104E60000200A06CFF5C00000200A070FFF55FFF75 +:104E70000200A0740000FFFF0200A078F00003E031 +:104E80000200A07C000000000200A0800000A00042 +:104E90000600A084000000050200A0980FE00000BA +:104EA0000600A09C000000070200A0B8000004005B +:104EB0000600A0BC000000030200A0C80000100013 +:104EC0000600A0CC000000030200A0D800004000B3 +:104ED0000600A0DC000000030200A0E800010000C2 +:104EE0000600A22C000000040200A10CFF5C0000E0 +:104EF0000200A110FFF55FFF0200A1140000FFFFF8 +:104F00000200A118F00003E00200A11C0000000054 +:104F10000200A1200000A0000600A124000000055E +:104F20000200A1380FE000000600A13C00000007CD +:104F30000200A158000008000600A15C0000000368 +:104F40000200A168000020000600A16C0000000320 +:104F50000200A178000080000600A17C0000000390 +:104F60000200A188000200000600A23C000000042C +:104F70000200A030000000000200A0340000000089 +:104F80000200A038000000000200A03C0000000069 +:104F90000200A040000000000200A0440000000049 +:104FA0000200A048000000000200A04C0000000029 +:104FB00000000000000000000000003000000000C1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE0000000000000300031000000000000000060 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:10501000003100520000000000000000000000000D +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000052008995 +:1050400000000000000000000089008D008D00912C +:1050500000910095009500990099009D009D00A188 +:1050600000A100A500A500A900A900AE00AE00B1F6 +:1050700000B100B4000000000000000000000000CB +:105080000000000000000000000000000000000020 +:105090000000000000B40309030903130313031DF8 +:1050A000031D03240324032B032B03320332033990 +:1050B00003390340034003470347034E034E0355A0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:105170000355035B0000000000000000035B035CBC +:10518000035C035D035D035E035E035F035F036017 +:1051900003600361036103620362036300000000B4 +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000363036D036D037B1B +:1051D000037B0389000000000000000000000000C5 +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:105220000389038A00000000000000000000000065 +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000038A03D6F8 +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000003D604010000000050 +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000040104330000000000000000C2 +:1052B0000433043A043A0441044104480448044FC6 +:1052C000044F04560456045D045D04640464046BD6 +:1052D000046B04A4000000000000000004A404A863 +:1052E00004A804AC04AC04B004B004B404B404B81E +:1052F00004B804BC04BC04C004C004C404C4051342 +:105300000513052A052A05410541054305430545C1 +:1053100005450547054705490549054B054B054D1D +:10532000054D054F054F0551055105E805E805E90F +:1053300005E905EA05EA05EF05EF05F405F405F9C9 +:1053400005F905FE05FE0603060306080608060D18 +:10535000060D0612061206130000000000000000F1 +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:1053800006130624000000000000000000000000DA +:10539000000000000000000000000000000000000D +:1053A0000000000000000000000000000624063994 +:1053B0000639063C063C063F0000000000000000E5 +:1053C00000000000000000000000000000000000DD +:1053D0000000000000000000063F0675000000000D +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:1054000000000000067507780000000000000000A2 +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:105430000778077F077F078307830787000000003F +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000078707C8EF +:10546000000000000000000007C807D107D107DADC +:1054700007DA07E307E307EC07EC07F507F507FE94 +:1054800007FE080708070810081008670867087C67 +:10549000087C089108910894089408970897089A3E +:1054A000089A089D089D08A008A008A308A308A6BC +:1054B00008A608A908A908B2000000000000000022 +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00008B208B800000000000000000000000042 +:1054F00000000000000000000000000000000000AC +:1055000000000000000000000000000008B808BB18 +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000008BB08C100000000DF +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:1055700008C108D008D008DF08DF08EE08EE08FDF3 +:1055800008FD090C090C091B091B092A092A0939FC +:10559000093909AA00000000000000000000000016 +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000009AA09BF70 +:1055C00009BF09D009D009E109E109E209E209E3CB +:1055D00009E309E409E409E509E509E609E609E75B +:1055E00009E709E809E809E90000000000000000F7 +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C000000000000000000000010000000204C013 +:1056D0000003098000040E4000051300000617C0F7 +:1056E00000071C800008214000092600000A2AC08B +:1056F000000B2F80000C3440000D3900000E3DC01F +:10570000000F42800010474000114C00001250C0B2 +:105710000013558000145A4000155F00001663C046 +:105720000017688000186D4000197200001A76C0DA +:10573000001B7B80001C8040001D8500001E89C06E +:10574000001F8E80000093400000200000004000F9 +:1057500000006000000080000000A0000000C00009 +:105760000000E000000100000001200000014000F6 +:1057700000016000000180000001A0000001C000E5 +:105780000001E000000200000002200000024000D2 +:1057900000026000000280000002A0000002C000C1 +:1057A0000002E000000300000003200000034000AE +:1057B00000036000000380000003A0000003C0009D +:1057C0000003E0000004000000042000000440008A +:1057D00000046000000480000004A0000004C00079 +:1057E0000004E00000050000000520000005400066 +:1057F00000056000000580000005A0000005C00055 +:105800000005E00000060000000620000006400041 +:1058100000066000000680000006A0000006C00030 +:105820000006E0000007000000072000000740001D +:1058300000076000000780000007A0000007C0000C +:105840000007E000000800000008200000084000F9 +:1058500000086000000880000008A0000008C000E8 +:105860000008E000000900000009200000094000D5 +:1058700000096000000980000009A0000009C000C4 +:105880000009E000000A0000000A2000000A4000B1 +:10589000000A6000000A8000000AA000000AC000A0 +:1058A000000AE000000B0000000B2000000B40008D +:1058B000000B6000000B8000000BA000000BC0007C +:1058C000000BE000000C0000000C2000000C400069 +:1058D000000C6000000C8000000CA000000CC00058 +:1058E000000CE000000D0000000D2000000D400045 +:1058F000000D6000000D8000000DA000000DC00034 +:10590000000DE000000E0000000E2000000E400020 +:10591000000E6000000E8000000EA000000EC0000F +:10592000000EE000000F0000000F2000000F4000FC +:10593000000F6000000F8000000FA000000FC000EB +:10594000000FE000001000000010200000104000D8 +:1059500000106000001080000010A0000010C000C7 +:105960000010E000001100000011200000114000B4 +:1059700000116000001180000011A0000011C000A3 +:105980000011E00000120000001220000012400090 +:1059900000126000001280000012A0000012C0007F +:1059A0000012E0000013000000132000001340006C +:1059B00000136000001380000013A0000013C0005B +:1059C0000013E00000140000001420000014400048 +:1059D00000146000001480000014A0000014C00037 +:1059E0000014E00000150000001520000015400024 +:1059F00000156000001580000015A0000015C00013 +:105A00000015E000001600000016200000164000FF +:105A100000166000001680000016A0000016C000EE +:105A20000016E000001700000017200000174000DB +:105A300000176000001780000017A0000017C000CA +:105A40000017E000001800000018200000184000B7 +:105A500000186000001880000018A0000018C000A6 +:105A60000018E00000190000001920000019400093 +:105A700000196000001980000019A0000019C00082 +:105A80000019E000001A0000001A2000001A40006F +:105A9000001A6000001A8000001AA000001AC0005E +:105AA000001AE000001B0000001B2000001B40004B +:105AB000001B6000001B8000001BA000001BC0003A +:105AC000001BE000001C0000001C2000001C400027 +:105AD000001C6000001C8000001CA000001CC00016 +:105AE000001CE000001D0000001D2000001D400003 +:105AF000001D6000001D8000001DA000001DC000F2 +:105B0000001DE000001E0000001E2000001E4000DE +:105B1000001E6000001E8000001EA000001EC000CD +:105B2000001EE000001F0000001F2000001F4000BA +:105B3000001F6000001F8000001FA000001FC000A9 +:105B4000001FE00000200000002020000020400096 +:105B500000206000002080000020A0000020C00085 +:105B60000020E00000210000002120000021400072 +:105B700000216000002180000021A0000021C00061 +:105B80000021E0000022000000222000002240004E +:105B900000226000002280000022A0000022C0003D +:105BA0000022E0000023000000232000002340002A +:105BB00000236000002380000023A0000023C00019 +:105BC0000023E00000240000002420000024400006 +:105BD00000246000002480000024A0000024C000F5 +:105BE0000024E000002500000025200000254000E2 +:105BF00000256000002580000025A0000025C000D1 +:105C00000025E000002600000026200000264000BD +:105C100000266000002680000026A0000026C000AC +:105C20000026E00000270000002720000027400099 +:105C300000276000002780000027A0000027C00088 +:105C40000027E00000280000002820000028400075 +:105C500000286000002880000028A0000028C00064 +:105C60000028E00000290000002920000029400051 +:105C700000296000002980000029A0000029C00040 +:105C80000029E000002A0000002A2000002A40002D +:105C9000002A6000002A8000002AA000002AC0001C +:105CA000002AE000002B0000002B2000002B400009 +:105CB000002B6000002B8000002BA000002BC000F8 +:105CC000002BE000002C0000002C2000002C4000E5 +:105CD000002C6000002C8000002CA000002CC000D4 +:105CE000002CE000002D0000002D2000002D4000C1 +:105CF000002D6000002D8000002DA000002DC000B0 +:105D0000002DE000002E0000002E2000002E40009C +:105D1000002E6000002E8000002EA000002EC0008B +:105D2000002EE000002F0000002F2000002F400078 +:105D3000002F6000002F8000002FA000002FC00067 +:105D4000002FE00000300000003020000030400054 +:105D500000306000003080000030A0000030C00043 +:105D60000030E00000310000003120000031400030 +:105D700000316000003180000031A0000031C0001F +:105D80000031E0000032000000322000003240000C +:105D900000326000003280000032A0000032C000FB +:105DA0000032E000003300000033200000334000E8 +:105DB00000336000003380000033A0000033C000D7 +:105DC0000033E000003400000034200000344000C4 +:105DD00000346000003480000034A0000034C000B3 +:105DE0000034E000003500000035200000354000A0 +:105DF00000356000003580000035A0000035C0008F +:105E00000035E0000036000000362000003640007B +:105E100000366000003680000036A0000036C0006A +:105E20000036E00000370000003720000037400057 +:105E300000376000003780000037A0000037C00046 +:105E40000037E00000380000003820000038400033 +:105E500000386000003880000038A0000038C00022 +:105E60000038E0000039000000392000003940000F +:105E700000396000003980000039A0000039C000FE +:105E80000039E000003A0000003A2000003A4000EB +:105E9000003A6000003A8000003AA000003AC000DA +:105EA000003AE000003B0000003B2000003B4000C7 +:105EB000003B6000003B8000003BA000003BC000B6 +:105EC000003BE000003C0000003C2000003C4000A3 +:105ED000003C6000003C8000003CA000003CC00092 +:105EE000003CE000003D0000003D2000003D40007F +:105EF000003D6000003D8000003DA000003DC0006E +:105F0000003DE000003E0000003E2000003E40005A +:105F1000003E6000003E8000003EA000003EC00049 +:105F2000003EE000003F0000003F2000003F400036 +:105F3000003F6000003F8000003FA000003FC00025 +:105F4000003FE000003FE00100000000000001FF12 +:105F50000000020000007FF800007FF80000014010 +:105F600000003500000000010000FF0000000000FC +:105F70000000FF00000000000000FF000000000023 +:105F80000000FF00000000000000FF000000000013 +:105F90000000FF00000000000000FF000000000003 +:105FA0000000FF000000000000000000140AFF00D5 +:105FB00000000001000000000020100100000000AF +:105FC0000100900000000100000090020000900419 +:105FD00000009006000090080000900A0000900C5D +:105FE0000000900E0000901000009012000090142D +:105FF00000009016000090180000901A0000901CFD +:106000000000901E000090200000902200009024CC +:1060100000009026000090280000902A0000902C9C +:106020000000902E0000903000009032000090346C +:1060300000009036000090380000903A0000903C3C +:106040000000903E0000904000009042000090440C +:1060500000009046000090480000904A0000904CDC +:106060000000904E000090500000905200009054AC +:1060700000009056000090580000905A0000905C7C +:106080000000905E0000906000009062000090644C +:1060900000009066000090680000906A0000906C1C +:1060A0000000906E000090700000907200009074EC +:1060B00000009076000090780000907A0000907CBC +:1060C0000000907E0000908000009082000090848C +:1060D00000009086000090880000908A0000908C5C +:1060E0000000908E0000909000009092000090942C +:1060F00000009096000090980000909A0000909CFC +:106100000000909E000090A0000090A2000090A4CB +:10611000000090A6000090A8000090AA000090AC9B +:10612000000090AE000090B0000090B2000090B46B +:10613000000090B6000090B8000090BA000090BC3B +:10614000000090BE000090C0000090C2000090C40B +:10615000000090C6000090C8000090CA000090CCDB +:10616000000090CE000090D0000090D2000090D4AB +:10617000000090D6000090D8000090DA000090DC7B +:10618000000090DE000090E0000090E2000090E44B +:10619000000090E6000090E8000090EA000090EC1B +:1061A000000090EE000090F0000090F2000090F4EB +:1061B000000090F6000090F8000090FA000090FCBB +:1061C000000090FE00009100000091020000910488 +:1061D00000009106000091080000910A0000910C57 +:1061E0000000910E00009110000091120000911427 +:1061F00000009116000091180000911A0000911CF7 +:106200000000911E000091200000912200009124C6 +:1062100000009126000091280000912A0000912C96 +:106220000000912E00009130000091320000913466 +:1062300000009136000091380000913A0000913C36 +:106240000000913E00009140000091420000914406 +:1062500000009146000091480000914A0000914CD6 +:106260000000914E000091500000915200009154A6 +:1062700000009156000091580000915A0000915C76 +:106280000000915E00009160000091620000916446 +:1062900000009166000091680000916A0000916C16 +:1062A0000000916E000091700000917200009174E6 +:1062B00000009176000091780000917A0000917CB6 +:1062C0000000917E00009180000091820000918486 +:1062D00000009186000091880000918A0000918C56 +:1062E0000000918E00009190000091920000919426 +:1062F00000009196000091980000919A0000919CF6 +:106300000000919E000091A0000091A2000091A4C5 +:10631000000091A6000091A8000091AA000091AC95 +:10632000000091AE000091B0000091B2000091B465 +:10633000000091B6000091B8000091BA000091BC35 +:10634000000091BE000091C0000091C2000091C405 +:10635000000091C6000091C8000091CA000091CCD5 +:10636000000091CE000091D0000091D2000091D4A5 +:10637000000091D6000091D8000091DA000091DC75 +:10638000000091DE000091E0000091E2000091E445 +:10639000000091E6000091E8000091EA000091EC15 +:1063A000000091EE000091F0000091F2000091F4E5 +:1063B000000091F6000091F8000091FA000091FCB5 +:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A +:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:10644000FFFFFFFF0000000300BEBC2000000000B3 +:10645000000000050000000300BEBC20000000009A +:10646000000000050000000300BEBC20000000008A +:10647000000000050000000300BEBC20000000007A +:10648000000000050000000300BEBC20000000006A +:10649000000000050000000300BEBC20000000005A +:1064A000000000050000000300BEBC20000000004A +:1064B000000000050000000300BEBC20000000003A +:1064C0000000000500002000000040C000006180C6 +:1064D000000082400000A3000000C3C00000E48070 +:1064E0000001054000012600000146C00001678050 +:1064F000000188400001A9000001C9C00001EA8034 +:1065000000020B4000022C0000024CC000026D8013 +:1065100000028E400002AF000002CFC00002F080F7 +:10652000000011400000800000010380000187008E +:1065300000020A8000028E00000311800003950013 +:106540000004188000049C0000051F800005A300C3 +:10655000000626800006AA0000072D800007B10073 +:10656000000834800008B80000093B800009BF0023 +:10657000000A4280000AC600000B4980000BCD00D3 +:10658000000C5080000CD400000D578000005B0010 +:1065900000007FF800007FF8000000D50000150023 +:1065A0000000FF00000000000000FF0000000000ED +:1065B0000000FF00000000000000FF0000000000DD +:1065C0000000FF00000000000000FF0000000000CD +:1065D0000000FF00000000000000FF0000000000BD +:1065E000000019000000000000000000FFFFFFFF96 +:1065F0000000000003938700000000000393870061 +:1066000000007FF800007FF80000068E00003500D3 +:106610000000FF000FFFFFFF0000FF000FFFFFFF64 +:10662000000000FF0000FF000FFFFFFF0000FF0061 +:106630000FFFFFFF000000FF0000FF000FFFFFFF44 +:106640000000FF000FFFFFFF000000FF0000FF0041 +:106650000FFFFFFF0000FF000FFFFFFF000000FF24 +:106660000000FF000FFFFFFF0000FF000FFFFFFF14 +:10667000000000FF0000FF000FFFFFFF0000FF0011 +:106680000FFFFFFF000000FF0000FF000FFFFFFFF4 +:106690000000FF000FFFFFFF000000FF0000FF00F1 +:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4 +:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4 +:1066C000000000FF0000FF000FFFFFFF0000FF00C1 +:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4 +:1066E0000000FF000FFFFFFF000000FF0000FF00A1 +:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84 +:106700000000FF000FFFFFFF0000FF000FFFFFFF73 +:10671000000000FF0000FF000FFFFFFF0000FF0070 +:106720000FFFFFFF000000FF0000FF000FFFFFFF53 +:106730000000FF000FFFFFFF000000FF0000FF0050 +:106740000FFFFFFF0000FF000FFFFFFF000000FF33 +:106750000000FF000FFFFFFF0000FF000FFFFFFF23 +:10676000000000FF0000FF000FFFFFFF0000FF0020 +:106770000FFFFFFF000000FF0000FF000FFFFFFF03 +:106780000000FF000FFFFFFF000000FF0000FF0000 +:106790000FFFFFFF0000FF000FFFFFFF000000FFE3 +:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3 +:1067B000000000FF0000FF000FFFFFFF0000FF00D0 +:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3 +:1067D0000000FF000FFFFFFF000000FF0000FF00B0 +:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93 +:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83 +:10680000000000FF0000FF000FFFFFFF0000FF007F +:106810000FFFFFFF000000FF0000FF000FFFFFFF62 +:106820000000FF000FFFFFFF000000FF0000FF005F +:106830000FFFFFFF0000FF000FFFFFFF000000FF42 +:106840000000FF000FFFFFFF0000FF000FFFFFFF32 +:10685000000000FF0000FF000FFFFFFF0000FF002F +:106860000FFFFFFF000000FF0000FF000FFFFFFF12 +:106870000000FF000FFFFFFF000000FF0000FF000F +:106880000FFFFFFF0000FF000FFFFFFF000000FFF2 +:10689000000000FF000000FF000000FF000000FFFC +:1068A000000000FF000000FF000000FF000000FFEC +:1068B0000000FF00000000000000FF0000000000DA +:1068C0000000FF00000000000000FF0000000000CA +:1068D0000000FF00000000000000FF0000000000BA +:1068E0000000FF00000000000000FF0000000000AA +:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:106970000000100000002080000031000000418075 +:10698000000052000000628000007300000083805D +:10699000000094000000A4800000B5000000C58045 +:1069A0000000D6000000E6800000F700000107802C +:1069B0000001180000012880000139000001498011 +:1069C00000015A0000016A8000017B0000018B80F9 +:1069D00000019C000001AC800001BD000001CD80E1 +:1069E0000001DE000001EE800001FF0000000F80CA +:1069F00000007FF800007FF800000344000035002D +:106A000010000000000028AD000100010005020692 +:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41 +:106A20000000FF00000000000000FF000000000068 +:106A30000000FF00000000000000FF000000000058 +:106A40000000FF00000000000000FF000000000048 +:106A50000000FF00000000000000FF000000000038 +:106A60000000000000000001CCCC0201CCCCCCCC5A +:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80 +:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70 +:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60 +:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F +:106AB000000E0000011600D6002625A0002625A005 +:106AC000002625A0002625A000720000012300F367 +:106AD000002625A0002625A0002625A0002625A00A +:106AE0000000FFFF000000000000FFFF00000000AA +:106AF0000000FFFF000000000000FFFF000000009A +:106B00000000FFFF000000000000FFFF0000000089 +:106B10000000FFFF000000000000FFFF0000000079 +:106B20000000FFFF000000000000FFFF0000000069 +:106B30000000FFFF000000000000FFFF0000000059 +:106B40000000FFFF000000000000FFFF0000000049 +:106B50000000FFFF000000000000FFFF0000000039 +:106B60000000FFFF000000000000FFFF0000000029 +:106B70000000FFFF000000000000FFFF0000000019 +:106B80000000FFFF000000000000FFFF0000000009 +:106B90000000FFFF000000000000FFFF00000000F9 +:106BA0000000FFFF000000000000FFFF00000000E9 +:106BB0000000FFFF000000000000FFFF00000000D9 +:106BC0000000FFFF000000000000FFFF00000000C9 +:106BD0000000FFFF000000000000FFFF00000000B9 +:106BE0000000FFFF000000000000FFFF00000000A9 +:106BF0000000FFFF000000000000FFFF0000000099 +:106C00000000FFFF000000000000FFFF0000000088 +:106C10000000FFFF000000000000FFFF0000000078 +:106C20000000FFFF000000000000FFFF0000000068 +:106C30000000FFFF000000000000FFFF0000000058 +:106C40000000FFFF000000000000FFFF0000000048 +:106C50000000FFFF000000000000FFFF0000000038 +:106C60000000FFFF000000000000FFFF0000000028 +:106C70000000FFFF000000000000FFFF0000000018 +:106C80000000FFFF000000000000FFFF0000000008 +:106C90000000FFFF000000000000FFFF00000000F8 +:106CA0000000FFFF000000000000FFFF00000000E8 +:106CB0000000FFFF000000000000FFFF00000000D8 +:106CC0000000FFFF000000000000FFFF00000000C8 +:106CD0000000FFFF000000000000FFFF00000000B8 +:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329 +:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66 +:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB +:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44 +:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316 +:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23 +:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC +:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC +:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA +:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD +:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2 +:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5 +:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304 +:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85 +:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7 +:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45 +:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328 +:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65 +:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389 +:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43 +:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315 +:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22 +:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB +:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB +:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9 +:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC +:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1 +:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4 +:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304 +:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84 +:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386 +:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44 +:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC +:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98 +:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB +:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76 +:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B +:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55 +:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B +:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33 +:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B +:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F +:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B +:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7 +:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B +:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7 +:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB +:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77 +:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5 +:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63 +:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387 +:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41 +:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313 +:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20 +:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9 +:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9 +:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7 +:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA +:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B +:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5 +:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD +:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5 +:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3 +:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42 +:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4 +:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62 +:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367 +:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40 +:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312 +:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F +:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396 +:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C +:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6 +:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9 +:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE +:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1 +:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320 +:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81 +:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9 +:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75 +:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9 +:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95 +:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8 +:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73 +:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398 +:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52 +:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378 +:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30 +:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358 +:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C +:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338 +:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4 +:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318 +:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4 +:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8 +:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74 +:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8 +:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94 +:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7 +:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72 +:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397 +:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51 +:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377 +:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F +:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357 +:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B +:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337 +:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3 +:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317 +:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3 +:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7 +:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73 +:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7 +:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93 +:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6 +:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71 +:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396 +:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50 +:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376 +:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E +:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356 +:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A +:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336 +:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2 +:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316 +:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2 +:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6 +:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72 +:1074E000000C0000000700C000028130000B815832 +:1074F0000002021000010230000F024000010330C0 +:10750000000C0000000800C000028140000B8168F0 +:10751000000202200001024000070250000202C0E7 +:10752000001000000008010000028180000B81A80B +:107530000002026000018280000E82980008038031 +:107540000010000000010100000281100009013854 +:10755000000201C8000101E8000E01F8000002D895 +:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B +:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B +:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B +:10759000CCCCCCCCCCCCCCCC040020000000000067 +:1075A0001F8B080000000000000BFB51CFC0F00350 +:1075B0008AB7B13130ECE644F0E98159181818F86F +:1075C00099C8D7BF1168C04E20BE01C4075948D71B +:1075D0007F551AC15E26C9C0700A8827883330B427 +:1075E0004A21C4ED651818EE01F92BA16272403DE5 +:1075F00073A4C977F3281E3CB8D014951F620CA160 +:107600005F9840E82234F950A8BCB81E842E36C5D5 +:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512 +:1076200040E5C7A2A90F81F2017EE9B234D8030078 +:1076300000000000000000001F8B08000000000098 +:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421 +:10765000278470123EEEC400C1063C4280A0A83BC5 +:10766000FC1A7DD41E1025E5A11C446B004922A6FE +:10767000D78C96D76CC8870450E3E751BD457BA0F3 +:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242 +:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F +:1076A00073AEB592BD77CEC9C74F47EF788D43769D +:1076B000D6DEEB3BFF6BCEB95634D943F22E27E42E +:1076C0001CFCD0A7291142A6F73DC92D5932C92368 +:1076D000E41B3E823F1FF923534816210D3EF6BCA2 +:1076E0003D10D905CF2D8D84A426C2F771491221F2 +:1076F000244848899A0B2D02B1870BE15977617CA8 +:10770000323E67C23387C8848C84F218FDBD20EBFB +:10771000FB9C42FF399AA880F114F68AA8A43C96F3 +:10772000C2F6DF226446DF3C48DD57F578B86FDEED +:10773000EEA7A26B24C5EB9E837F94E5598950E6A2 +:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7 +:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A +:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2 +:10777000E5258436333B4BE93344CC5DA5FDDBCDB9 +:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7 +:107790004B9241C0214938E0D61C5AEC33D3F42730 +:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777 +:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF +:1077C0006A6287CF70E7159844C821C0876A128221 +:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020 +:1077E000EB1B229E822572DFF8000723E0A02F6F9B +:1077F00034C7496F6EBA067820BE3A387CE20AE395 +:1078000007AB0F8FF4199A1D93803568F110E02DA6 +:107810009F30F8E557B7DE2A4F2194D53A0F4EA096 +:10782000F0CBEF5EB99040F9E8152780DF9ACBA640 +:1078300056CEA5F5B2CB63AF2CA04D423143027AB0 +:10784000DD0A9D15407F5FB32A68B909FAA365CBAD +:10785000BACAB4106EA6036E1472864ACB1EF8B56F +:10786000280DFC482F1EA473DEFEED33C1CF436C00 +:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5 +:10788000BE46101B5FD37EB22B35075EB25CE33C75 +:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C +:1078A000A5B29EA478CA26B16CB58CE263A14A4009 +:1078B0008EE5E4EA1290C360786926A412F89F4A24 +:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5 +:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05 +:1078E000786DE5B2E74802C7EB3C5844E76595C9B7 +:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695 +:107900000F62A833B83CA0F0514A65D31FF9ECF4DC +:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF +:1079200059C71378EDCF571B055E7D847EDF52B2B9 +:1079300078407DD51FAF4F92046D172A2566324DD2 +:10794000BBFFB4EB0BF7D326DFDD72541935A36A06 +:10795000E74078CB75AE57F4EB6F508C7747D0A2E9 +:10796000AAA37CD5B81E688FDE63114A776740F6FC +:107970005078281D17A5A04C8A49EC61D64D4AA223 +:10798000657FD44C6E413A48225EC4FCBC86EC90C4 +:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483 +:1079A000182F17EC02DA2105851A2229A05B41AFB6 +:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF +:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049 +:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8 +:1079E00028102F13761DC7D3660FD92B5D48E5C12C +:1079F000986BC152209BE1D32C6A87C0932A9FCDFC +:107A000063A6EA4057648FA4C23C71488A4742F596 +:107A10001DD40B4A06F623FBEA90FE9490894FF1A1 +:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83 +:107A3000748E6B15D3D80874318DC9A7EAE88479A0 +:107A4000A0EF3C129BD7B7A57C5C879AD39687762C +:107A50005906FBAE5AA52A7F2A7CDF3661207E229A +:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8 +:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9 +:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913 +:107A9000C7F8D26769601F8875AF0576A720DD1625 +:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F +:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373 +:107AC000BDBB5D6F7F425E507B18E85CD041504A81 +:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2 +:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0 +:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1 +:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14 +:107B100079E9E823139E7E21F9711C415FD5F2F2C9 +:107B200001E96130FA7ACA4D5F9D577F21F475C82B +:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9 +:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6 +:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2 +:107B6000EA74FC51D48E91407F9491588ACE53A7E9 +:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A +:107B80006BD85E21294B477BDB6967CC57E84BDA22 +:107B90004F7309497A715F64FA504F95A884E93FA1 +:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA +:107BB000FD359BEB5F89DA5B747DA132E7BE37E070 +:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824 +:107BD0004842A88FC4FE38037FF6EE8B395C476AB3 +:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA +:107BF0004A49E62F20256037AF970A62A00FE83E7A +:107C0000AF278B7E7FEF070AEA878668DD8A1658E2 +:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17 +:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C +:107C3000E91D7F549B563C0D8653DFEEA6F090293C +:107C40002081FF02A1FBA22F18003FF6BE174EF6BF +:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67 +:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8 +:107C700077DBFDACBC63D3AC8D169447F2FA561596 +:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF +:107C9000BE6EF324ABE269F8FB365976D85F4DC669 +:107CA00082F2FF43D7E1F79917BD40E1498112B352 +:107CB0000CD26B97150ABF41C7DD952500FFD7147D +:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E +:107CD000424B0DF4850CF528DE1E96605FC7EC3133 +:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42 +:107CF000F659519F3DD68B2717DEEE557BFC80B79A +:107D0000EF8DF9F01713693FD642390664F3BD0DC4 +:107D100045D92B6D787CCC37A70AF0489A73D12EC1 +:107D20008992DE1F13CA62DF5C403A2BC0781C4385 +:107D3000251FA1743A2EDE53012830AAF4E7708F74 +:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9 +:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041 +:107D60003C185149D73B809FE09B549F30FB2CE14E +:107D700003FF56A67132CDF333C073934CC71D4D2C +:107D80009208A7C1E09A099EADD127B3515E7FCE7C +:107D900070CDD4DE0DCF1112E397956A39F2CB5036 +:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6 +:107DB000BFDA416269F0EB379CFE210DF625B67201 +:107DC000BD6C307D1072FB89189EDD7A6101D70B86 +:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF +:107DE000909F6192B4E8F720F707915226FF7DF447 +:107DF0003FE0B751554E7DA00D511FBC2BC55F9084 +:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C +:107E1000A337B445133638D4CB4CDF097D962C16E6 +:107E2000FA8C20FCCEE37348920E3FE8C307362C51 +:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A +:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C +:107E5000307918317B52E0F34342CEE32E434ED6C5 +:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448 +:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C +:107E8000EE2C64F0B76611A4D390B1E08402FA58E6 +:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459 +:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74 +:107EB000855C4AA1EB50371003EC09D5A4223102AE +:107EC0004F3D0FE8453563217C765754C2F3BCD94A +:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042 +:107EE0005EF526595624C6073936789B4AA1633F6A +:107EF00097ADBBFCA589D62AD4EF8646C617F69F58 +:107F000077BDAC72B9E7A417412703C8BBCF441FA4 +:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE +:107F2000F9AB9CF875973F6FBCFA014F141FE751EE +:107F30003C017D9E379BD123B547D17E7AC0D76166 +:107F400002BC1F2836644BEA6B175672989FF92CB7 +:107F5000DD6851BBE7FE95DB4D68975F4C6580841B +:107F6000CFB4FEA37A59C376542E542ACC6E97C050 +:107F70001E9FAF6CAB82F63B295E81DF77027F43A9 +:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200 +:107F90000246ACBE14F1EBE7FCFE912751097EC806 +:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9 +:107FB000FC0D609F8CA9D3A702D833B5DB5E275791 +:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9 +:107FD000473CCB4DA048D897542B36FA0E97317FAB +:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E +:107FF0003F96C753DCF55E56B8BFCE60F03244FF03 +:108000001B07EE5FC0E76C9BC2E323D40043221E34 +:1080100049ECFA5BB9F15005BCA75CB709F0B55D56 +:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88 +:10803000552647C79AFA16C0F7D866192C05F2B824 +:1080400062E0FB51CBEBF67B281EDA0B492C64E097 +:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963 +:10806000D07AF9A52469D0F6EDFB1FA8D068394273 +:108070003754600AFBCA193E7D252406A690C72204 +:1080800029997D4F424C5229EFB140951E183F036C +:10809000F75F77E69298D7E8931B82AEEE6CBEC787 +:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F +:1080B000630A27E14F54205E163761BCF6596CDE27 +:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB +:1080D000CEC35A4762E3B15E8C60FC860A54F05707 +:1080E0003655337BD78D8FF524F1B832DD4EAF870F +:1080F000906EDA3F51F8BEE0C58D60E78F835F690F +:10810000F9974D7FDC381CBB45C40F85DDB245EDCA +:1081100044BEB728CF815E12768CBFB813C7FDBFAF +:108120009CDE87DABFBFC4E96F75DB356E7BA65E68 +:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B +:108140004FA3077E03FA9AB6DF115DFCAB89465F49 +:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52 +:10816000F7608F6632BE1A2BE4D037285F0D107F80 +:10817000147CF511151287804FD40EA42F6296201F +:108180005F097E51BA3BDACFA7F460D4CBE0B906E1 +:10819000FE2239B45C48E93D65B38784BC504B3B53 +:1081A000E313A5FE74F7A021231ECF94317F7596AB +:1081B000D56D4293606927C6F5285DFD17D095AA55 +:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9 +:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A +:1081E000F87D31363F579CBDFE5703C6D9FD319708 +:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B +:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3 +:10821000BB1C70E9070F65476CA0F9F9859FFE53F9 +:10822000C60550870D010E6E385EA23AFD879F3756 +:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD +:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C +:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4 +:10826000AA8DDE47971E4A413BB73ECAA4870693B4 +:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580 +:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB +:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0 +:1082A000E897F998AECE16575BCDF78137F07DE4AD +:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA +:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64 +:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A +:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F +:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10 +:10830000671E9CB19296BFCBED91F7A95C366C715C +:10831000D035A1A406F87DA76BDAB59710689F6CDD +:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26 +:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E +:1083400022E40DC757A6BC2A914FF50B20205ADF17 +:108350009A43D8BEF3AD60B209E535CBA71AACFDA0 +:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A +:10837000D6966BC5C12F24E28235A4CE1C4D7F5505 +:10838000F72DB246135BBDE810EB150F5C2FD3BC85 +:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B +:1083A0005D49D440FF5EC083024F15F18D7E608A27 +:1083B000DF5A35D4266541BE5317EE03FD86EAA089 +:1083C000875AF805E45A09936BC112E777B77FF82B +:1083D0004355C4E153C87F188236C07E08A514F007 +:1083E000DF94AB277BEBD3F16A605D1742298E7275 +:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E +:108400009F8F71F5FA9106FA77551233B10F17DD88 +:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1 +:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81 +:1084300092CCFC483A2DDBD6FDA70E89E7AF185940 +:108440004B06F0DFAD8F327FF00DEDE3B398DFD058 +:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8 +:108460003D7615C07BEDBF2AC407F91B8F85490AED +:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130 +:10848000CFC7C388AF354F7A930B69FB354FBF33E6 +:1084900085D0F99DDED4F3E268B09B1F95581E820B +:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9 +:1084B00073F2D96015F0B7B467FFF5D86FE7528F44 +:1084C000D7B6DF2EF678906F693D66973F2225C7B5 +:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF +:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764 +:1084F000118043ED5EC5A1076AF72829EF147C1EA1 +:108500008327C48DA41940279C5EBAD661BCA8A657 +:1085100073EB07E0C7A8DDEB946B142EB114C0F524 +:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1 +:10853000802BED77A59605FAC649DFD0FFD99CFEC2 +:10854000FD11D283F1BADACE76365ED7577E0F7A36 +:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F +:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1 +:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190 +:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0 +:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B +:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4 +:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B +:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B +:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B +:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E +:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782 +:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5 +:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F +:10862000B3FAE3EF0E17FECE905BBE970F798D5D28 +:10863000231C7152F1EC8B0FC6B3E203C80B210F60 +:1086400006836FB5C4E6B5CC633EE801BE7A32D886 +:108650008BDF8580DF1F9E1947287D1CF7F45C0F98 +:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3 +:10867000F12B9A81F9992424E5F13C31F67308E451 +:10868000700DDBCB91DADDE19437D287A79AE4A2B3 +:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE +:1086A000BCBDE1296276407224C265DDEEDF69CC93 +:1086B000BEECC3A7540EF83CB600DE67C2A758BF95 +:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0 +:1086D000F5C36F527A039EA7777A55D07BA7C1FE68 +:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615 +:1086F000F1630E87CCF461713B60E0F50D177E3FAE +:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC +:10871000625516D8EC139F87DA27905F46E2D6E8B9 +:10872000C2BEF99E847D04A5BF938F2A18AF69ED60 +:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D +:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F +:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3 +:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92 +:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46 +:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416 +:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39 +:1087A00070C0003DDAB5C91C7507D86B873D04E47D +:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40 +:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97 +:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89 +:1087E000E52890FBCD60CF4F84F16251F07F289156 +:1087F00005952C7F50D6FD69F537EBCF138A63BE04 +:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3 +:10881000FEE8059AD817D0716D7290DAAA55E9F082 +:10882000364B637648A6EF976ACCDF93E97BC52089 +:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19 +:108840005733C9030FEFA74C331CEB05782FB2E564 +:10885000C58F26C98D90274A4221773C3AEEB3C78F +:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F +:10887000BF87763C899D1BC08E75C79FDD7989991E +:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2 +:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5 +:1088A0006DC9808725DA9C7FD280BE649248F77DAF +:1088B0000BA79BCB49F7532B619E3116BF9FED82CF +:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B +:1088D000DFB94BCC661081F397F7ACDD0F7C26E255 +:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9 +:1088F000B521E445103D27AD5EE89B87C5F755518E +:10890000DC2779389F1D78F3661FC82D95242A0B24 +:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32 +:10892000E906DADB79A9D50FDC0471757D0CC62365 +:1089300094B397A0FFD0DDAF128D59980F16322A4D +:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F +:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0 +:10896000EC77AE8E207C7D14BE201F1164B02E9E4D +:108970003775F7D511D433FE839E9DF0DD1F6279E4 +:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F +:10899000EB3109E328827E5B0BEBCE03393E401EB0 +:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51 +:1089B000368FCA2A9807F6586B361179559644E7D0 +:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45 +:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F +:1089E000E78E26759DE8CF33C93536391BF1AA08C5 +:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8 +:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD +:108A1000ECFA483C051DB5160F1CBF53CF5E847E93 +:108A20007C51F6E949D34C537FBE8FD91F827E7D9E +:108A3000B924097AC967241EB809E83937140B32FA +:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A +:108A5000CEE804B95ED071FFF95FC6E75F64615C80 +:108A60002244309E96791D65B88E559A19F6DAE043 +:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10 +:108A8000DA198715791AA27E504A1478411EE6B287 +:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C +:108AA0000212509777E2D146554F62FD127FE27C69 +:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF +:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB +:108AD0008FD3992CAF28033DB5150F1C87EA688CFE +:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8 +:108AF0006E0946F73F6802BE092B822F7E88E53B50 +:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC +:108B10007DB49A01E4FFC1D6A72767205E873B4E4C +:108B2000FFF5B271DBCC10EE77075BB79E62E30E08 +:108B3000751C115FEB5B9F0FC769350619A7838D05 +:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED +:108B50007BDFEC1E9248D37F16E79F036F7A515E4E +:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF +:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA +:108B8000A1553CB1D04AD62E61C239DBC83C82F136 +:108B9000674F49DE2A78DF403AE273400F97CB2CCB +:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4 +:108BB0009E928B6F86FAFBA7BF9E68023895333A68 +:108BC0002007F31D706C358AC4B99D01F9DE53EEA0 +:108BD0008C5B109F33FF93A84B306E4EE54287D7D6 +:108BE000665752BD781FF23329B3C0DEDBFEB56B8A +:108BF00063767EFE672DFE1D565FE46B093E4F9F38 +:108C000037D79A2BF2E6123EA50CCE29F5E6532F64 +:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B +:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6 +:108C300058C8A7FE8987C4529017F36B250679316F +:108C40006EFA70F7E73E07D06B8F64E0E7F7013804 +:108C500036B9979F70E1ED463FC6E7C478CF837C75 +:108C60002A1D9C4F47573BFB195BE73C9F755E8372 +:108C7000335E55681538EA9FDF56E4F83EBEE302DE +:108C8000C7F789F74F759427252F76D4FFD29E39E1 +:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F +:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5 +:108CB000477956F7371DF51BA87902F92C7040004B +:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B +:108CD0009ED48FF166968BDC9767E06EA7146BA627 +:108CE0004EF9573126CCD331CFF046E423A5386F67 +:108CF0008E81EF672C00BF132963E7B444FCDA537D +:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7 +:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A +:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3 +:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73 +:108D40005CE623CD0053C11715CB7B46BF80D5C44D +:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084 +:108D60007A45494E73E421B89F54FE95F9609F1EE1 +:108D70005986F2A8775FD02B1FE333E1BB478DA163 +:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F +:108D9000421FCF05A597D711C80BA372E9CEABAF81 +:108DA000C23818A9278EF3807955711FE83D6A975C +:108DB0007DC567DB3F47CA997DF6F766A78660BD2C +:108DC00036F927EC5501D7118575718CEB85650255 +:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A +:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9 +:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D +:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9 +:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051 +:108E20006640FE44EBFE598B305F77A1AAC3BE9625 +:108E3000D04DDC3BB6B8222171F46769B932EA45FE +:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4 +:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2 +:108E6000F39560FC108EBFC9C7F0E886BF87986D88 +:108E7000F368BD96635FEE28468A61F97AF72E9C07 +:108E80008A744A05B5837EC53E82D2EFC340BF6275 +:108E9000FF2ECEB3DEE263790902AFC460FE881113 +:108EA0000915F7BD3909B6FFED931F8C8E723C3161 +:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09 +:108EC000C77B690CF1D5FE15956C027A2BA6EB8158 +:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36 +:108EE000E1FB40952CC9C27B529485D174F6672F63 +:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4 +:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1 +:108F10001D08CFF631F7A11D2DFC63245A3688BFFA +:108F200087C54BFBF0BCD448513CAA574C45A75FC2 +:108F30007B31C7739D2B9F97E359E057F8ED493478 +:108F400017F95AE05B017802AE94D9D181F495C249 +:108F5000F9C60DCF53FF4DE17904D600743B96AEB0 +:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8 +:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E +:108F80000D737AF371BDF942F9DB6D709E44CD65C6 +:108F9000FBDD7079F3AD329CC320960EFEB5B03880 +:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD +:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B +:108FC0003F7D1E261993DEEFEA8EC789F886C88397 +:108FD00015710084035DBF67961C47F95746CC9D09 +:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9 +:108FF0003FB6A02C5501E5823A12033D71F1F143D1 +:1090000024413BBD20C0E47E41595202BF47C149C3 +:109010009617B89DC72B0BEA93D24ADB38969FE987 +:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32 +:109030003B14BDA1A302C62D67F9E461BA5F84BCED +:10904000B1F0116F12EDADB26E027E54AA05AC30D4 +:10905000FD7EBC914CBD713CE47DF9F079B251C705 +:10906000E781B1DAFECB69BDF5850103FA6D290A06 +:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7 +:1090800062FDB66F9B685734EF3F817EC3A0392DD8 +:10909000C6FCA8A642CA613E874CF0731035662C08 +:1090A00086EF077E83F5142DF11B0BEC93651AEE0A +:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2 +:1090C0000BC98A4569E0BD82EB1D4A518A96D79744 +:1090D00087A495A7942CF02797914EC873F7B424D2 +:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2 +:1090F0005A8F810F5D2B67E745043E3C7E127F222D +:1091000004F552D2AD74DC89011DC7293892C4BC64 +:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7 +:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A +:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0 +:10914000C451605F3664C8A356748AA7114C3E812F +:109150003F62FD78635476C8DE0F8387F2DCB30C80 +:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837 +:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE +:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2 +:10919000174FFDE895191EDADFA9275F99A1227301 +:1091A000251D76ECBA73AFCE003BC19A434AEAE87C +:1091B000B356D708F45BEB63EB107972DBF3B4566C +:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736 +:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED +:1091E0001B1088175ADE7110CF7AD38BF4F75121F8 +:1091F0002929BC10FC820AB6EB594D92904FA1A5CB +:10920000EA803D89FFE52401BE09BEA6EF475AE387 +:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826 +:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D +:10923000F19DE560075EA7E23C6819CF1BB9F1B369 +:109240003C58E488E3E5F0F884C06B263AD9DA4864 +:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B +:1092600018C5F2DE46039F4F3796E0B3AB3186DF79 +:10927000F73496E353E4F5E1D65E417B3A5E017A3A +:10928000E81AE687D30DD9847C852C95F8E0BE26B4 +:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6 +:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1 +:1092B000249047D62CE66708437FB47DEE1242DE49 +:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770 +:1092D00077FD884A1790D3BF1D958B58EEEB373D2D +:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6 +:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4 +:1093000064815CDF3E8B183A85E35D866C79B2FA46 +:10931000EAEF683C98376F3CD74120A7EAF59D5BA0 +:109320006CFB9831165911B7D1CB5D756AE52EB437 +:109330003312F98B2763BE31F76BEF9E678EC17EC8 +:10934000B13C21F0E23C8BEB159033979D657AA8F8 +:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C +:109360009F803C057959962073E83C4397B2F8F703 +:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81 +:10938000A24909CA3FF2C7670620EF3DE7FED42E87 +:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2 +:1093A000341FF077C1BE6398B7A4C8DD1AEC789774 +:1093B0000526CF57C19E8589607C802A6A8A6725E9 +:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD +:1093D00012B7B21D33317D51CA0F7ED1FE82168085 +:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF +:1093F0006DBF35BB332A6743D2D4C4968397425995 +:10940000D49FD862CD26E41AAE0F48285108FCDE5E +:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F +:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D +:10943000BB60EF4E94AF054982FBFE82A49484A3E7 +:109440009D7B1A0FEACDC2B926F04245C3A428BBC2 +:109450005F484B7A62B0BD9CC4EF0F1174F17490F9 +:10946000E9C74949DADE1E9776DD273289DF57835F +:10947000200579B98D9D0776D37929EFAF81585BA7 +:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3 +:10949000736EE10E3CCF262B7001C8BF952AFA816E +:1094A000D7162637521B8AAC7DB630462D56D2E2EF +:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F +:1094C000E7A3D956369CD7ADD97BF738C8EFA92189 +:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9 +:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E +:1094F000BA2EBA12D657B34D267221E34B73229D72 +:10950000AED971019CAC7B7EEB5BF3FD630979A462 +:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F +:10952000803EBA833D2D405F6B67C99C9E7A5E305A +:10953000559EFF5800E35CDE027196DDCB2AAF0436 +:10954000732B4F66FC4B0912E3DA4A76B30FECF942 +:109550003FB6C8683F838B7403857BB14A0EAAF47B +:10956000B95DA3F8043E6B55511ED2F76D1EC44B76 +:1095700007DE3342DAD83D2DE3F77957829D5D5CF3 +:1095800067AE467B5B2F453FC038D2FB837912E73D +:1095900011267F27EAA442A5F566050B117FC55564 +:1095A000D7AE85764A784900F83D4F495AD8FF77BB +:1095B000991CDE2E273B7D2097234588DFED114641 +:1095C00017D63DA54817BBE53917805DD422ADDC21 +:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6 +:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE +:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1 +:1096000046503C1CDF52DF129D857828F2D1EFC70F +:1096100003F52D3E8A97DD1BCD02DD569EF8099598 +:10962000EA48B4F52DE66CF09FDCB7069410FDFE19 +:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3 +:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D +:109650001E5210AFFF4EC7033941D76101DDF74CF1 +:1096600052D12E08D0B904683930B908F36DE9BA7F +:109670004900EC86C92AEA7911C7D126C96837435F +:109680007DA087407E11E6CF51791D87733E4A94B5 +:10969000C5751465874979980479FEBEA42FC2FB6D +:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C +:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76 +:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98 +:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091 +:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3 +:1096F00064FE41EFD862BC57A38150FE07BE08F15B +:10970000FBF2B8FCF0707BC17D4E40C8134F365B56 +:10971000637DFBDC5139A1BE73704AC8F4813CD82B +:10972000AF4FCD027B743C9753CDA9595F05BB4524 +:10973000E5F260879F9DCBEDC9269DBB08D8BF3160 +:1097400062CF4B10F2605BA30F9F0F5F3601E39770 +:109750000F5F963707E215072E7E1FF7BF6776303B +:10976000FE3D73E805B84B899CB1A8B6311859A1E4 +:109770005F3E752FDE17F27D357E17E6CB43BE0EBA +:109780009DD25DD9CE3CCC47395CCE0578DE808752 +:109790007D17F778A867BF847EE06D7C3DBEC43C32 +:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D +:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6 +:1097C000623EFB8219EE3376E143F835041E44FB1A +:1097D0007AC91CA50F4037B5671592B4E585F49D8D +:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B +:1097F0003E48A29DE80F353BEE712551B5C77EBEB0 +:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1 +:10981000E57DBACD1579B998A7AE9207C0AE3D15D2 +:109820007C6B06F8E36AA998005739512D3C4F7AB2 +:109830009AEF4BD47DB7E2791E313FE18F13E59A61 +:10984000BD8BD04F57BB3B84E7796A924C0EAEF389 +:109850005907BDB23DEFD64C41BEAD672FEB6F3C13 +:10986000E080D2C7877A753EAC3FD870FE4C38672F +:109870009227D79D370EE0A3323CC07EF9C9109ED7 +:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B +:1098900006782A8158376167164D95DA474AAFDC5A +:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC +:1098B0007329EA67948BCB023F437BA8C52FCACF9D +:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8 +:1098D000A75BCB4A507F2845A400E0360F1C2D2003 +:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD +:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5 +:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4 +:109910007A8BDABA24EF692F9E33DCE171DADBE26D +:10992000F920E7CB36D7BD1DBE44B3099B73C19F59 +:10993000EE7B9605BFAA672739F2A4C607593C5BA0 +:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7 +:109950003C4E4E86719C71BBFEE3CCE07282F07D82 +:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED +:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB +:1099800060FC3905F87335A7D3923D773F076AFD30 +:10999000319FF967D837ACF2991704A70F9F7FBAA8 +:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90 +:1099B00028D7DF51A45B69E245E2597D36E8905F24 +:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA +:1099D0007EC779B6FEE385F0BB18EF16977C3E7024 +:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A +:1099F000E780FC545E3BF9DD047E570B496F9E22E5 +:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4 +:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76 +:109A200022D17F2ED677CF47C81F28839DA67EE2FE +:109A300015F343F975B7ECEA2F478C3F06FB13F695 +:109A4000FAB703E35F843B25EECA4E568C66FE1DD3 +:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23 +:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3 +:109A7000443D9ED3F87680D16535B5E8B1DD8ED111 +:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D +:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D +:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2 +:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B +:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF +:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4 +:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09 +:109AF0008A60FE7A28817182FDF90BA260A77FE758 +:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD +:109B1000F70869CFC1FE91F74BCE7E59B69F47D962 +:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607 +:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE +:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3 +:109B500016F7D10CFB7960F1DC1F9E118575366517 +:109B60002F88023D3767CF70AC47C9B09E5561065C +:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908 +:109B8000E9EF176B17788A2690CEBEA8759DFA1B51 +:109B9000AF6B14C7577588F90D361B8C8F824AFC42 +:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B +:109BB000DF727865E2DF659EE44898D79146B67F0C +:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8 +:109BD0002B3C909FE37F563BCFA70F26375A422C52 +:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21 +:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF +:109C00007478701B8C0FAAE1929BE983C34DD05BE3 +:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3 +:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD +:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7 +:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA +:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD +:109C60003C5F9363FF5E067187C5AC5DBF7972F898 +:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8 +:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB +:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64 +:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2 +:109CB000E492DEBF977101C0738FCCF2398EC2ABD4 +:109CC0007CB89F8C60A5A555A376029ECA223CEF66 +:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977 +:109CE00096BC367879230CCF3396A7B70B73233CF9 +:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F +:109D0000978AA8E6D8C5B67375535CDFDDEDC74604 +:109D100022F8FD351E6F777FCFE2ED972E19B83D03 +:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468 +:109D300034429FAF4B8907BF01743429C4E21E2A05 +:109D4000298478BDE8275725298DC2FD5D8F3116FE +:109D5000FCB469FA291CA89F4C7015EB11E3002B89 +:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6 +:109D70006E65870D191DE4F0FC999975C1E446B034 +:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564 +:109D90007D53617F380C261F1670BAC955129BFC83 +:109DA000E01F5B21A5BDDFECF208FB3B251F847B98 +:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F +:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442 +:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0 +:109DE000C4919FB4247EAB07F873C9C2451E2304F7 +:109DF000DF99BCBC86CF638F96187B51A80F4E1994 +:109E0000E510874FD7914413DCEFB0A241C238521E +:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD +:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41 +:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B +:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8 +:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28 +:109E6000D2089E97FB8F762FFE7D0B412FBD72622D +:109E7000C3478D907477AF969A0C7433B2A9EE1BDA +:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F +:109E90002EEA2D560D4FBAFA57573AE59898F7081B +:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332 +:109EB00002EFBDF83E927E5FB423C2E2777B9273DD +:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C +:109ED000DA258A43DEAE5818749D476270FDAAD712 +:109EE0007808D671EFAE9726E3DF5174E987809248 +:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0 +:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E +:109F10009FD7AB565D83F36F567498FFB1E523AEC0 +:109F20002A07F952E5C17B828F35DF16BEC9B67E9E +:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9 +:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6 +:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2 +:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5 +:109F7000B9B1E4BE780BC4794F344CFB6937ADF707 +:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF +:109F90008C234483F689FAF4FAE0FAEC2093AF6A52 +:109FA0006C1CC897EB36A4AFB709922B69BD137F21 +:109FB00055AAD3E56D7EA2333E59114FDFFE133D06 +:109FC000CCBE835E4A03E7BD59412EE7F47120A75A +:109FD0005764986F575604EBBDD372FB7510EF3B77 +:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7 +:109FF00046029E5A251DE8E1EDECD824A0B795CD88 +:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43 +:10A010009E3F92E2A56B3989494666F9FF31E79F79 +:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0 +:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D +:10A04000760558DE11894DB7DF2F13E0F338B17B69 +:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B +:10A060001DE28F872B95D4E57492EFED0EE23DAFA4 +:10A070006EBEC834FE70EDC013BB8767070EB6EE28 +:10A080005856E190ECC03395F7DE59067CA4754C28 +:10A0900049277F859C7E8DFBADDCF4239EB3393E42 +:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A +:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C +:10A0C000E859E6FFCD34CF389FA790134079104F61 +:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738 +:10A0E000070FB1BCADF1F19573461A7DF4795D1699 +:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80 +:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8 +:10A11000C4653E8818AC4CF40570448694F373CB48 +:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75 +:10A130006EC7F15D974CB2AF6707C7FF8A25D97824 +:10A140005DCA713976C528CC2F50F0BEAED78FE4EA +:10A150002C80F2BD876490D0E4BAFA950AACEF8106 +:10A160002C9677BE62C32B680F0E97CE57D439F565 +:10A17000FF277C1DBD7696DA5306F493090EED5940 +:10A180003EB6CF892F9A0FF279D50609E5ED962CC8 +:10A1900003DFAF524D94DBA499E947E2A3F0A02A74 +:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9 +:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010 +:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD +:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77 +:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4 +:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5 +:10A200009B637C25EC1D77FB6BD584C36E3C94551A +:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E +:10A2200064FDD3E98BFF0779B222080080000000AB +:10A230001F8B080000000000000BDD3D0B7854D59B +:10A2400099E7CE9DB9994966924932933738930080 +:10A250000625780321449E370991A0A803040C1A0F +:10A260007044D4282144C54ABFD2CD0D893120DAAB +:10A27000505DB4D67587885DB6D235586AD1D2762E +:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B +:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD +:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591 +:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194 +:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2 +:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D +:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1 +:10A2F000DF9234287F097FE60EFFDEF0804CA2C596 +:10A30000B179AF867518CAC77A923502F3CDF14498 +:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F +:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67 +:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2 +:10A3400038F37B6D844CA3130402369245C86D7CB0 +:10A35000EFAB528906E3133ADFA386F145BFC3ADE5 +:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11 +:10A37000702CECFBF09533C75E3329D62F111C9659 +:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4 +:10A3900071E0A673B85AE7873F76BA8F25FCFF971E +:10A3A0006EACBCC34341B22965CEEC709CF90F93EF +:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA +:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023 +:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF +:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57 +:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE +:10A40000257CCF85747DC72F96559DAEE7B88DF618 +:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA +:10A420007249AD793D4B8F249BE9D2461A7BE3EC10 +:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B +:10A44000DFDE71EACDDB613F3B9211DED67132D3A4 +:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C +:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38 +:10A470003DB6D22DB46A574F4A6324CE7A27A7330C +:10A480003AF0C97AF279B43D7983E103C80DF866F0 +:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD +:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1 +:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4 +:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC +:10A4D000B27844F8D637C82678D62D34C3D74A9FE9 +:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA +:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B +:10A50000919E11F9E0AA46335D9C6E9F6F7A830895 +:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69 +:10A52000CB88EA806F1D6929799A82F2E8034B7023 +:10A530003DAF13520B729E9CBAB56451496CFC1727 +:10A54000393D7F5677EBA5202EDF505A4ABC71D695 +:10A55000F33A8793C0F7EB09E019E572F70DC033C2 +:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8 +:10A570006E643C9FF07A113E6F34B427C33E8F89DE +:10A58000791F64F3825E33E2E3C457D45B56FE1D49 +:10A5900020FA4D48C791642FE8111F9087418F74AE +:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64 +:10A5B000B36B0E233ECABD01849B28D72D34AFF365 +:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35 +:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4 +:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB +:10A5F00018E137278DB53FBE7364F8CD4963EB3C56 +:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B +:10A610008CE32FFB229F443363E5ABEB252D1287A0 +:10A62000CF36789551C17D83058E577F3116C7F798 +:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343 +:10A64000785EBB5152253A84239DC9DD6B85BCB32E +:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2 +:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C +:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77 +:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889 +:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E +:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E +:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C +:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649 +:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3 +:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756 +:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5 +:10A70000B5352054C8B79202463BD5B7E1F356326F +:10A7100019EC87D0260FFD7DC2C64FD6835E262456 +:10A7200082FDDF75A83722BC09B373FB7BDC3BB627 +:10A73000D076AF825C80F1893A3654629013762FDE +:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB +:10A75000C8E3FA1657B9BBA434B07702D7C17E0656 +:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC +:10A770006D411C16ED15611F072F0BDE755E19C8A4 +:10A780001F87E6A24B5904CECB85948EAADC3A8C67 +:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8 +:10A7A0009B322D2FBE3829007E47795FE1011F1DA6 +:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA +:10A7C000D071F26079C76AABC711F243986C066129 +:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703 +:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771 +:10A7F0009DDA13E91F743967139295A5F5CD5509B4 +:10A8000071677C540BE5BD0F8AF13EEED20A08F960 +:10A81000992D1C9468FDD48CA405760A2F5F91981D +:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68 +:10A83000490BECB0EE06317FE90258DFD259A25C39 +:10A84000EE82B22F85F787F55650F955185BBF3D5C +:10A8500087CE9F21DACF58308FF63D5CD9526DA755 +:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7 +:10A870001319F50B52287EF6124AA7B4FC64C6954C +:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA +:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608 +:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8 +:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594 +:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F +:10A8D000994CEEED4D8E5FAF64307B80C20DF54933 +:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7 +:10A8F000CC88F1DBE594872B285F12275BA71867CC +:10A9000098FEC8607287E89767803C5D0843D0ADC9 +:10A9100017A912FABBA42525321E688744ED4B40C7 +:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A +:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11 +:10A94000290AED84F16AB2734BDB83B171E8BA3B3B +:10A950009C534CEBB6576440FDE2D29B2719E0397B +:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364 +:10A970000AC17EFFA945EE96F72D7610DAEECA4C95 +:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F +:10A990004EB53464B03B031C1ED5772EBC1FDA3590 +:10A9A000F53948126DB77E4F653619412F367D3126 +:10A9B0009344A61ACAF6A80272A7E98B39F87BF568 +:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C +:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E +:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9 +:10A9F0009E82F54370B773B82BF1D7395FD02985A4 +:10AA0000B7CD405F4B39BD51E9877194FECB26F538 +:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953 +:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8 +:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70 +:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6 +:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E +:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099 +:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22 +:10AA80000D3EC7627D79DF330AECB32901DF8632E0 +:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6 +:10AAA00054D74CE08B853602220CF60DF66AB9902D +:10AAB000B764D70B5576FAFB5099CADB00E06148C2 +:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD +:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA +:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7 +:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859 +:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4 +:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5 +:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A +:10AB3000D171EB9C018C93093AA923CE801BE04E86 +:10AB40008DA62F41EF2F746119FE805DF269B7C4A5 +:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A +:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C +:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B +:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88 +:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB +:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3 +:10ABB0004007BFCE286076ED15B4F202CA94CE6A83 +:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B +:10ABD00062B2F31AE4508104766B76920A7286E2CE +:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E +:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1 +:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309 +:10AC10005B3A8E938FE3443AE172EF376327F68015 +:10AC20007E12F253E0819C92713C517F505A54E065 +:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE +:10AC4000BF793EB597A6D7F6466D5E902AB72FB866 +:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51 +:10AC6000722A8C379EEE83FE7428393CA9C51DC319 +:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2 +:10AC80009091E163DF06FECD4A65ED87E93D5EAF59 +:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C +:10ACA000AC42A37D1522408776C2EC2C19748F1F0D +:10ACB000F519C2ABFACE8634D09B9FF52D4D239368 +:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0 +:10ACD000555E9709D8CB7738185D2AE9616F06FD74 +:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA +:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D +:10AD00000196018AF73432A87B0D784CABB099FCE0 +:10AD100007C71793B1FF99DB0FA509EC873293FDA5 +:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582 +:10AD30001043FB9564E00E186FE5FA7C53BC289134 +:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F +:10AD500045DD38FF31367F6CDE14CA70B179E54CC1 +:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9 +:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E +:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D +:10AD9000C0FDEA035CDFA41D117663724092627A03 +:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13 +:10ADB000806178CEFCAAF6655102FA98F00FB12FA7 +:10ADC000CB6785E512909FB512194F3FD3E799F5F0 +:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD +:10ADE000EDFCF04D1995DF62D447920C728F8DD730 +:10ADF000CCE92178E2552540E57094DB43BB7CDA51 +:10AE00005D40171DC9A993414F74248F8D405C622A +:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7 +:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D +:10AE3000BD41D256533EBE9FCB89261FDB4F932F79 +:10AE4000AA8CA3F3E735B17514F41E90EC0679577C +:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26 +:10AE6000111269AB2983F69A1DCE41F27A258C0F17 +:10AE7000E7B55040507AC853D9F86E35225D3B296A +:10AE8000B6DF2EDBA249A027BAB25254D013277DD9 +:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF +:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D +:10AEB000BE6E0BDD1372175F570F93BF32799E0082 +:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD +:10AED000C822E127D0CE225D04F146701F599B267F +:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F +:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F +:10AF000023117F08BD26DA3912F8D582EE536AE3A1 +:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0 +:10AF20004931F8BBFCA12320B7F27A7748001B2BEC +:10AF30009D7564FC50CAA7FBBCF546E29549E275D5 +:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D +:10AF5000677CC2E305B3FDA163008FE67DDB14C00F +:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA +:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9 +:10AF800069F79EA80DECEC8D4405FE6FEADD732891 +:10AF90008FC227BF499B260762E3E5374524584FF8 +:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4 +:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B +:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0 +:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D +:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0 +:10AFF0001EB58DF60D249129A8AF470987E916BA29 +:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A +:10B01000117614CAAB430EB68F0EC2D6DB99A915B2 +:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD +:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723 +:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5 +:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2 +:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14 +:10B070006572268AF427D66BC5E73C1FB3EF2EA274 +:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07 +:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8 +:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C +:10B0B000DB116F623D354A681CF865CBF878CF5CD0 +:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC +:10B0D00042F72BCA5288DBE9FF2E439CF61266A288 +:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614 +:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6 +:10B10000007F01E4532B9D523983744F7405CFB9EE +:10B11000A89CD451AE927010FC1421873B397F1348 +:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D +:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D +:10B14000394C4821F86B627C2BFCFE99DBED71F0E9 +:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736 +:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5 +:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91 +:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC +:10B190007574D93615B7303D76870FF1974A987C8C +:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F +:10B1B000C673099F4B857309127E5659EA89D1835C +:10B1C00015BF81270E28015A7F492FE38318DC9889 +:10B1D000BE12744BE51CE2BD33539C5F868300575F +:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20 +:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8 +:10B200006BF4836ECA7901BF825FA8FF68E2AB2747 +:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C +:10B2200035EFB7201FB96B993C71F79BE52021776B +:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60 +:10B24000769278DD37482DFF097932640FCFDF38E9 +:10B2500045ADFC720A571787016FF76B1FF3B73EB6 +:10B26000DC4511017C696F5146B2874F372E89BE8C +:10B270002601BED770587FB8BBFAC23F409C7157B9 +:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8 +:10B290007ADAD71E42FA19F4BB54882752F1592B97 +:10B2A000517A68EBFD55EA4C382F7BEC8229203728 +:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7 +:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA +:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225 +:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA +:10B2F0000E2C3FF36F8FFFE22F60778452556877F3 +:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9 +:10B31000E7B982BEAD726BCF01E453412F9780DE57 +:10B320000538D533F923E8F95D7EDEB4AADADD0508 +:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF +:10B3400063F512C6D9BA28D540BCA32B9954C0378F +:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A +:10B3600043FB25FB5C640BC6E520A84BFD0124755F +:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D +:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9 +:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897 +:10B3A00071D254BF9BD32DD39B797B171504504E7C +:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9 +:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08 +:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A +:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F +:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80 +:10B40000C6E9E27A6B275B37EDEF8573543A9E7796 +:10B41000C6141CA7CF9181FD75D67FFECE3629B606 +:10B420005E4AA963416FC178656ED0337A3DE227E9 +:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6 +:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F +:10B4500056786EE4F53FF36BF825BB324D7A2591B3 +:10B46000BDF2CC151F33FDFBB37750DE34031DC393 +:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE +:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1 +:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB +:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26 +:10B4B0009F72D5C338076D3684E7C19EF377B44BCE +:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F +:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B +:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB +:10B4F000C7EC5142ED51689F3E2FD2A6207D959614 +:10B50000037D3D73C52F3A418F37CF235E187FFBF4 +:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2 +:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6 +:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B +:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A +:10B55000217D5E12991981F8D9471C7E028E1F3B0E +:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3 +:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142 +:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0 +:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4 +:10B5A00039FEE2D52783DEFD88E31FC508C8772E64 +:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5 +:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5 +:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6 +:10B5E0002E47295D00DCF21A43480717FB6E5021F5 +:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED +:10B60000FA3343651087F6677BD0CEF1CB953617BA +:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2 +:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756 +:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3 +:10B6400064F043C4B9868043A42DB9DE283F7FC28D +:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38 +:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7 +:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5 +:10B680002E5F590A7E65739D5B057EBBEF67D22AEC +:10B69000A467081682DF1D5E8D7820140FC00F246A +:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4 +:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A +:10B6C00034E61D0A3920E44BB3323001E858F04328 +:10B6D000F39C810900B7D1CA938F1D94FF817F2805 +:10B6E0001C807F04BF789E667CB2A52D5009F55B57 +:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89 +:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A +:10B71000374F8897FF26E4B0D3CEE49B339212696B +:10B7200037D0179CF979A6E017F3795236C48F8F7A +:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2 +:10B74000605EBB881759C7FDD82F99E232C26F815E +:10B750007307689F93C5F827258BF3679688CF46B4 +:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E +:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1 +:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06 +:10B790003FF839D770FCB2714878A2292FAECBB6EA +:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB +:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6 +:10B7C000C451AB9CC15219E765712CCF1CF209E83A +:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92 +:10B7E000CE2372C319A6727E639EA9FD989642531A +:10B7F000FD391BCE33D507F529A67251D70C53FB63 +:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57 +:10B81000D2D65B0F78397FD795A67E5576AFBD948B +:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055 +:10B83000292B8878ADB29BF3882FD8678607A4CBD5 +:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0 +:10B850001E10FD83C3E9813807D4501C3F53D0B973 +:10B86000285BCFB584FC3853FA4BB44E417F89EA4C +:10B8700013C1ED3B9CFF055C1C4370A95747828BAD +:10B88000E3747021142E9EAF0E17EB789B529A3101 +:10B890004FF8352818ECE38156F37D98657A1AD372 +:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED +:10B8B000C9E1F2218509E261947CFD16C7437F222C +:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF +:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359 +:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836 +:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714 +:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7 +:10B910005BD7307C9172B473429971E3A5D7E8F29A +:10B92000A8F044E482B8FA32E13872C388F9E51B22 +:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD +:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED +:10B95000D013399539211E5F87795EE563DB57DDAA +:10B96000A54F4A0CAF189DC587539DF3E33C70D695 +:10B970002783CD60E82FEE9F88725D382DAEDD9075 +:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA +:10B99000FD5636D377BF4B2067D2793D5DA703CFE5 +:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF +:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15 +:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF +:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774 +:10B9E00069CF66E7A1D43A27C10C34F575056CC55B +:10B9F000621260E7BEE3BC101F12790189E9D58E9F +:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F +:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB +:10BA2000D303EDAF2B98D7339007EB3B537A22F239 +:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B +:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31 +:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787 +:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008 +:10BA700064DFDB93537BE0FBB96B6C84A4527E8163 +:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA +:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B +:10BAA0004339999F0B27F37361255BE98432D18A6F +:10BAB000715F17F07D75DA0263615FEF4BEA44F066 +:10BAC0005BBCB6880ADF54122D61F9799130F86BAE +:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA +:10BAE000D19494C117C701FFFFD286F7A21FF7B206 +:10BAF000753EFE403E9EB350818FF26232FC4EB7DF +:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC +:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB +:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E +:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B +:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991 +:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22 +:10BB60001B317FC661C99F71D84304CE851D43F93F +:10BB7000330D04F367E838C6FC990FAAE2AFA39F20 +:10BB8000CB73C7172909C64DC5DF3F281C799F8E87 +:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9 +:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A +:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC +:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186 +:10BBD000F1A41051F7E0FD1EBB637040F06121B489 +:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF +:10BBF00020B71669E63281F60639BC1862D8741F80 +:10BC0000C9E71563FEDFA72490E61D418E3638E5AF +:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A +:10BC200030C766CA631ADE9FE703F07B68B77A47BE +:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4 +:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE +:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A +:10BC6000A19939D82F30C1785F60AF5D4B9942BF41 +:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945 +:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B +:10BC90003BCF02C1E7A4726F0561726F454E21CFA1 +:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE +:10BCB0000F831F87BB158E21125809F9DDA783E773 +:10BCC000865C6D450E9DF79A57921590FF2B9D83CC +:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B +:10BCE000E03CAEF8C967E837B542657915641EDAFD +:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742 +:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25 +:10BD100029B97E8CC36B9940473F4F6274F4001D74 +:10BD20008996D7FD6222DE87BF2A37AC423B91E776 +:10BD300047B4C109909770A670A27F1C4047A783A3 +:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F +:10BD500003EFA195FDFDF843C0539C6388F5A9B995 +:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3 +:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7 +:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3 +:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1 +:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A +:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713 +:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B +:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8 +:10BDE00073706526E07D1EDF771689A6C3F9E62FFE +:10BDF00092F03C60989EE4FC41E195920BFA64E17C +:10BE000020C635FA27C4970B29B98CEE86DA77B1AC +:10BE10007912DD43C8CC9546750F819485311E5843 +:10BE2000E97447658A875B383E94FC9B54B00F2BBE +:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51 +:10BE4000CF7BC73912CBED35F213E52D71F63321D7 +:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B +:10BE6000808DDDA31EB499FCE46C72467EF27E17D1 +:10BE7000E397F73242A80F403F80DEE97CFAC252D6 +:10BE80004026D81990DF33E8494639DA9E37A3387F +:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB +:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57 +:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43 +:10BEC000CE59E978FF00E0373736DE10FE13E0F98F +:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92 +:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC +:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB +:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD +:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994 +:10BF2000FB3089BEF92DF40F859D91227F9932FA5D +:10BF3000750AFFF97479D6CF803D46D7536573E310 +:10BF400079E733747FB9546E5429EC5B399F5215ED +:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F +:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2 +:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4 +:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17 +:10BF900025FA354C9E5AE49C906736277B6F84685F +:10BFA00024E0CDC2381283BB2EE1FB57B345199C68 +:10BFB000145A9EC59124417FBAEFD9FC4B56857324 +:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074 +:10BFD0003B570AD9D93A222C0F91B414407B9B735A +:10BFE0004086F945BC02579205E3887959D9C3CBFD +:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D +:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8 +:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10 +:10C02000A40330BCC42B41F9FB52F8E7C017479575 +:10C030006E12A4BF9FFCF9E704DF65831B6245F025 +:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055 +:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD +:10C060007C9979FA784EA2388EA38AA17EF0466632 +:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC +:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C +:10C09000027DE274688857A157D6EEBD9900DE9AFA +:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13 +:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8 +:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6 +:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF +:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53 +:10C0F00016D852F56027E40B0D6E265EC82F194640 +:10C10000BFA7283F507A7804CA74DDEB5687FFE555 +:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C +:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636 +:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01 +:10C14000AEA2BEA948DEE3687BC883824C04D69EBB +:10C15000D8E2B51F07ED0370AECFF043F2147C3F79 +:10C160008970F937DDC2873363FC80F5A5BCBC8ECE +:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA +:10C18000FE5089F8C3F8790689FD8171AB63F3A08D +:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD +:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F +:10C1B0007ED23710B50D666908B4C37865242403B0 +:10C1C0009CCBBD9BDB617D1736BC9209F475735E19 +:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3 +:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154 +:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A +:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8 +:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8 +:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE +:10C230009610CD01FB5AC2F957F0FF52ED56B46784 +:10C240009786CC76E9EF25866F7DB98476E215F581 +:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5 +:10C260009590E78B41BF831CAEA5FADC603737DCC5 +:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F +:10C280008769E6F761D6ED6B736401BDF3FB30EBB4 +:10C29000F6BFD369CC0314701A7E1F6610F31F9784 +:10C2A000299103704F68D94D748FB4FDAFF8FD89A3 +:10C2B00067E1FEC494181D79AE7445597E9D867958 +:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD +:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43 +:10C2E000706EFCCD3C663F6F97585E97BEDC89F060 +:10C2F000F6CBE488F19EBFBF2884F97433F202388C +:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E +:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4 +:10C320008FE6CF0C95DE3229366EDD7E96BF57172D +:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F +:10C34000DF3D408FC3F556B819E8CF51155A7E1D11 +:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A +:10C3600057857B781D95A14535586FC77B8259F558 +:10C37000249A44EBCB5E527A20CFAF91742B304E8F +:10C38000A3458FDDE47E56013EBD69A72346970491 +:10C39000F213D52210784DBB87C545500E09F964BC +:10C3A000A56732CE2C874A85DCA5F281E5F73530CA +:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD +:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0 +:10C3D000E0C749F0FB64EC87652A4F8B21EF742698 +:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3 +:10C3F00056561002EF2358F143E7433A17E77D7092 +:10C40000B402E70833F9FC9FDBB449D120E08B4448 +:10C410006C14CE9D520BEA1D27E481D2EF16298CB5 +:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5 +:10C4300001DE6739FB52000F4715D509F5359030FD +:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F +:10C4500001BE0B02C3F085F70BB404F8D2845C2153 +:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF +:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C +:10C4800078B47979271DCCAF984106AEDF2D0DA782 +:10C49000938F0F6E90730CF424E8F4699EA72FFD20 +:10C4A00092E7FD967950FFC5F425A383725E9A0149 +:10C4B000F465A083D9FB5C5199EEB394F79F01F426 +:10C4C0003025A62FA33677402904BCAB5DB23CDCF7 +:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D +:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5 +:10C4F000920410FF9516BD53EDAEB3039D543BADB2 +:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23 +:10C51000BD320AFB94E27F42FE08E78D89F07F413D +:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF +:10C5300086787023CB4B9EFAF2B8762867AD0DE271 +:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C +:10C5500058B49ED6D3F29E60A81ACAEB3648284734 +:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD +:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C +:10C580005743795D17EBFF478F5307BFBCFC48A4A7 +:10C590001D7E9FB895AD43D87D7339BDED919EF852 +:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A +:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4 +:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A +:10C5D000F9544E10C43BA5D34296B7DA43A75893FB +:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832 +:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81 +:10C6000091207E007B44FD9B203F757E510BEAD339 +:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4 +:10C620005F7E4B3EB3938EF13C7AF17B63246803CB +:10C63000FF640F100FBE03147D19EC963DF0BE9100 +:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5 +:10C650002D761D94C05809DF55B9AC8F44D352874D +:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4 +:10C670001DBF54888F59E351AFD4713C09B9B194AF +:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF +:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3 +:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F +:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C +:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D +:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926 +:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246 +:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B +:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4 +:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5 +:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF +:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD +:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B +:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A +:10C76000437873517B2A05FC7DC2ECE23C32AA3C43 +:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E +:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055 +:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC +:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3 +:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F +:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8 +:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD +:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936 +:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4 +:10C8000050595A300DDA694A2EC4679E62FAA2D98D +:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4 +:10C820008C1318509650789FE4E7FE27F97B402739 +:10C830005DEC2BD6152858540AFD4EDE3C80726301 +:10C84000A8BC6800E542A02084F39E5C2AEA79F93E +:10C850006E5626DCAFACE47C8271E33871E2E171A4 +:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1 +:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D +:10C88000547D02D0C3D78DE39E1CD387FBDA523987 +:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C +:10C8A000F866AF996F66178CEE3CC51A671F053F97 +:10C8B000CD2F18C10E7A12F4972386875B787E53AA +:10C8C0008DDC540D71A54F5713BC677BCB0B32D257 +:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C +:10C8E000A71030C815B8A71030F875704FC158861A +:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104 +:10C90000582E25D7B6439C6E5D17F14602ECDE82A9 +:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD +:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228 +:10C930008FCBA3B06D17CB536B7751F8031DEA5A19 +:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2 +:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF +:10C96000C9E316FA17E0783D09A5813F37850C1E0B +:10C9700082784773445261DE1B1E30CBEDA1F74C29 +:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7 +:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0 +:10C9A000C6A38752726E1AC6799E97218641FE48A9 +:10C9B0005AB6CF920CE703167824E598E9C21530F1 +:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65 +:10C9D0009D37227C336BCD74B2466E42BE1770AE6B +:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8 +:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613 +:10CA000055BB03585DE72C8FD93165CFB7E021B016 +:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A +:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27 +:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084 +:10CA40006CBFD43283F70BADFB057B8B18E25256DB +:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669 +:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F +:10CA700014378E6BF7897508B888F993488B9C0337 +:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4 +:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8 +:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB +:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990 +:10CAC0005B9C36523EE61DADE67B30741BDA88F780 +:10CAD0008A00645970EE4420A842B65E7A6800DE8F +:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7 +:10CAF000535FCA00D7A1783E61F78415DE4F29E85D +:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B +:10CB10007C5ED0133943F5BF319EEBFFA3BE775146 +:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E +:10CB3000704DBAE838D8272E62D837EA4343598E69 +:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C +:10CB5000DEDF7518CBD157DE7718D71F617905F660 +:10CB60001081FC5BC547EB8DFA65880E2943951B48 +:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4 +:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E +:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16 +:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95 +:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F +:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8 +:10CBD0000874103518A0262BFD19FCF92295609ECB +:10CBE00006E17E4921F74BB66D6DA90717EA115D85 +:10CBF00009603C88FAF739B47E2261F58F742DC63E +:10CC0000386BDB980979F05E95BBEBA2E3707F6F20 +:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A +:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90 +:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B +:10CC40007B918524AA427CA5F06E5B159C9BD9C183 +:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729 +:10CC600034347E10E0A698C6775BEACFF41EEAFE65 +:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25 +:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6 +:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF +:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B +:10CCB000A26A04E34248278FE8F1E9E411E2AD8279 +:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC +:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5 +:10CCE00080155F644A94AEF591AD8519C67C54B247 +:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67 +:10CD000015F0F5E9D7C497E20B45D37C10CF240189 +:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31 +:10CD200000CEC12EF69E9AC093186F6B2B89CE331E +:10CD3000F87F4135AA019C6BE44955907FBEA30C56 +:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B +:10CD500054EFA3782921E4BF372F4B2BA6F53D4193 +:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8 +:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94 +:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7 +:10CD9000F97703892641FBE473581E679A667ECFB4 +:10CDA000C651619607148C7D39E5106FE1F4CEDF32 +:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1 +:10CDC0008B9198DAC67C03E5594F9B82F077707996 +:10CDD000453632BAD0E95FA0A7740B1D7954331DD4 +:10CDE00039E402CCC3157C25D623E66F1B93956CE2 +:10CDF000C775D9F13D6C87554E58D6E7866020C57A +:10CE00009DDB4722115AEFD0197F10B91F7F774C55 +:10CE1000272433F815D6F935E553E89CBF8D7CF20D +:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD +:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF +:10CE4000975356B879FAB46AA0E78BE49734C88F41 +:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E +:10CE60005586674A2F6A942EFDEE3BDC98173CB539 +:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2 +:10CE80008209E06AE5D74470FD96806B39856BD1E5 +:10CE900099C355D1997C4E9FC5DE593C384661FFF8 +:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06 +:10CEB0006D1A9537749DB51A83B7779690E36678A7 +:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB +:10CED000ED2420017CFF5B033BA27B9A9037830407 +:10CEE000F096A631BA1570EE9ECDE05CA871387749 +:10CEF00071B8494402385BE9D52A9FD3BE269C7796 +:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF +:10CF10008EC1D5E11E8C829CED0ADA715F07820A10 +:10CF2000D67795B0FAFB5356E680BEEDF277E60071 +:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC +:10CF4000D8BD831A792BBE43DA1950103F9E407C1E +:10CF5000F995362BECC47926D9898C7078488D07E1 +:10CF6000076799629297F98D66F8A658E0EBFA9AEE +:10CF7000F2E1B5AF291FEE216CFD778E17EF347407 +:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE +:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1 +:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0 +:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474 +:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA +:10CFD000B35A82F1F14D297F25F1E055D465D67F12 +:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27 +:10CFF000EFB67954F66EDBFF0164680340008000F1 +:10D00000000000001F8B080000000000000BDD7D09 +:10D010000B7854C5D9F09C3D6737BBC966B3B9924C +:10D0200040124E42081B0861810483829E84406343 +:10D030004D71435151A88D40314248285E1A7FF509 +:10D04000C94282841834A0585A2F2C378BB56AB441 +:10D0500051A922DD2052FAD5964551F152BFF55221 +:10D060002F40258A177C3E5BFF79DF99D93DE76425 +:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B +:10D08000EFBC332184906FE8BF04CF0412F410FC8E +:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0 +:10D0A0005677A5E139F1F7115F22562D248390546C +:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F +:10D0C000B450266D4F80469590D5566F968F3E4F43 +:10D0D000A85954435C84AC6A2124388A90F6163BE4 +:10D0E000962B726CDE601A2177BE2C7BE3E82B3620 +:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A +:10D10000479FBB9711924F88423F20D1BA5233E3D9 +:10D110002352425F98B3849049D1F9ACA9B1788386 +:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40 +:10D13000DF37F4FD6FE0E782681947583BAE13BE56 +:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F +:10D150009A98F63E2CF61C72CE37322DE579497539 +:10D160004E5A96A71092D5FF7B5FB69047F78E4434 +:10D170008012920E653D01782A7CCCD5C9B3ECC4EF +:10D180001985B378BECACDE01B27D1CAE4FEE3B649 +:10D19000015CE3A2758510AD1BF0915D1AB3BF2849 +:10D1A0002906082923A4B32578F03D6BF4B9730A46 +:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080 +:10D1C000B869BF442F7D5F0717A77666DFA73FA525 +:10D1D0006974BD2E4E37E477920278B5F37A8254A3 +:10D1E00037572D037CF9081941FB956BA4AE987D48 +:10D1F0004F13EF49502AE41D41DF79AC74D3760612 +:10D20000522869BBDDD8AE6620BC705C25FABEF63C +:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7 +:10D22000E0A77ECF558B80635F1A859BCCD71B030D +:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60 +:10D2400066D55C5E8A115291A676035FB6694EE49C +:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2 +:10D26000C88F6D43F71D5E08709DB9FFC36D08350B +:10D270002D5425E04BDB133DD5A12A9DBC11F88A26 +:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0 +:10D29000CE21362253BC384656D9EB9C51FCD8E0FF +:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4 +:10D2B0001B564778D0C5DBB26FFDB904449119E91C +:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D +:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E +:10D2E000D66FBA5C93791585CB9A17987C241E2645 +:10D2F000176C7686CF354463EDD98A97BE41D664E4 +:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3 +:10D310005F6F07F9A198E447BACF62D00743E6C42C +:10D320001BE4FE9A825928CF069A67569DF1FD614B +:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD +:10D3400046EBAB943A3BC8915B33D74B753AFA1E28 +:10D350005254F73AD0ABA8DB3267E27B7139A53182 +:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A +:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03 +:10D380006D716319C167C13506BCACCEA2F29A8E2D +:10D3900007B0D77FFF29B5EE73985F14CF96287C2E +:10D3A00080698B175B805FC5386D59F90EC0DBFA59 +:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0 +:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05 +:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D +:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0 +:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613 +:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747 +:10D4100098FACF37B52F36B52F37D5FF8FB17F2983 +:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68 +:10D43000A1E7237CE536F2E30F722AB43C66671855 +:10D44000F02BE8F374F1B39ACAB810F093A23A50F3 +:10D4500099962F267A7A589F998FFAA38D4E0BF5BD +:10D4600037B75F52041D5773FB70CE12031DF5E6EC +:10D47000143AC07E24CE34944BA7A20B89A418DBA7 +:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24 +:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC +:10D4A00085931AB1A7E9C728DF6D49238138AAEF10 +:10D4B000B6F82D58FF3C937E08EC952AC687237852 +:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD +:10D4D00001728A96B7B56462B97AAD256B218C5713 +:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9 +:10D4F000B13B340BAD279E94497022B5174AAE2834 +:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA +:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE +:10D52000B86A81E275405BB177859286FDFCE03692 +:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B +:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B +:10D550008215C3EB7E05701ADE492C1AADAB7E55E1 +:10D5600002B9F6469E8AF276EB1F28438E800FF5AD +:10D5700065819EFD62AD6D25CC73603C11D952FE74 +:10D58000ED4B310EDA9943F1B906F4AC2A484274F6 +:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6 +:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976 +:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E +:10D5C000976A0D1D77082D8B7909B4760EC09F9749 +:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40 +:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C +:10D5F000EDD3C37965FDED532AE886029D6FB27ABB +:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD +:10D610007F8D2DB01DF84351875EAAB3BB026B32DC +:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E +:10D63000707ED3E5637E99D2EF263F413B6B137139 +:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C +:10D650001DD02959C8F4667E549EAD50E8389B61B0 +:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F +:10D67000DFB180DD3C96042DB0BE312480A5872C1F +:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3 +:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF +:10D6A000E9A9715772652CFBC0966FE17E26A957D8 +:10D6B00026713F87C1D9965FD61FFE56B20CE17E18 +:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B +:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852 +:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D +:10D6F0003F39DF8DFDAE08764F8761C679C395400F +:10D700000B63AB7BF700C98CD136839B413CE53F73 +:10D71000DF93AAC23CEA86C23885A17005908FB318 +:10D72000FE603003E773BE05E86204CC87D3472D63 +:10D73000D2978A7422F00DF4504BEB573430F850E6 +:10D740008310DB89E236CC7FCB2A4A27CEFE749247 +:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA +:10D76000022EB37ABC560817F87EE75E053ED0CC91 +:10D7700040DF5E077DDE9E5B770EACB374A3AF1512 +:10D78000E8CFB92BE4877E024ECE29214DC27EDA46 +:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6 +:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6 +:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F +:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07 +:10D7D0002541D7E27901891D67B8323FE2CF66CA99 +:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D +:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B +:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891 +:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B +:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9 +:10D83000737DD7C278576CEC7EDE81EFF9AE473E40 +:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F +:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5 +:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26 +:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338 +:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38 +:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4 +:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB +:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D +:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638 +:10D8D0001615E57B678B07CB8E162F8F879663B95E +:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF +:10D8F0004289148BAEF2FC467B7F78B311EFA9D539 +:10D9000046FF3B596F2FD37F49E5F986F644EF6810 +:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1 +:10D92000837D2BE0385D9E87F1620A4FB4AB853D65 +:10D930002BDA09A9C378AED5E467769AECD80E80C5 +:10D9400023C297C1B10BE088F02DE7F0AC667E13DF +:10D95000F77BE285DF53B47ECE7C8C8B1094572B03 +:10D96000726CA89F3BF298BDDD8F7E3275F293F208 +:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB +:10D98000694139B9256D8F672BD6E3BD4C9FFABB32 +:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6 +:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E +:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE +:10D9C00063586764FEA536368E44241827A5D866AA +:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737 +:10D9E000939D23E214663CB96B8CFA6675117BBF7C +:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67 +:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8 +:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA +:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5 +:10DA30003B8207115FE47E98885B8BF114C2C6C3FA +:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D +:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD +:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5 +:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE +:10DA80001B32993DA0BC13F600934BE8E7FAD74D43 +:10DA90000C69608F1711EF76025E306B17F444F457 +:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D +:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F +:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843 +:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144 +:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB +:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56 +:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7 +:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64 +:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127 +:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF +:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5 +:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D +:10DB6000F830E227A9DC889F44AF113F099ED126F7 +:10DB70007C18F1935EA022FCE2328D78EAC737A7C9 +:10DB8000F057D2609C187672765DA802F6B886CE01 +:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6 +:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242 +:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185 +:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE +:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB +:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED +:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD +:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8 +:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B +:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046 +:10DC3000B8DDB1F7ED4529F42995836807D2890449 +:10DC4000B6533A8D5388929802EBD5705D56B06307 +:10DC500065586F17D6E34937964E1262FBD7DC1F23 +:10DC60003DAF200FC7731337FAAB29C48BA5E06310 +:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC +:10DC800075666FEE009F46A3509884AC82F090EECC +:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E +:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38 +:10DCB00059F98B78D71628BF74E4062068A58DA87B +:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85 +:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B +:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE +:10DCF000E44968778AD20CD77D1EED06989F627F33 +:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D +:10DD100053FADF96D0BE22C50C4F4E9578F2C64519 +:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4 +:10DD3000FBFB970933C349F4FDAD07A99D0779346F +:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D +:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC +:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990 +:10DD7000260C7663E22445853D8E2239580DF32525 +:10DD80004D16027C714F83713FB7B3B008E122EAB0 +:10DD9000C3F87E2E2955FA227936D48EDF58C0F387 +:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76 +:10DDB0004AD3A8DE4A82B820E5145A96760631F98D +:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87 +:10DDD000AE81F13ACB7D0960976F3834EBA2B17414 +:10DDE000DEA1B0E205100447A5E0BA439ABC368133 +:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C +:10DE0000CC23013F85C7D6863D7619ECDE90858C04 +:10DE1000443B973A5C93B82854215ECBF8FE965168 +:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48 +:10DE3000AD6671E71972F6F3306EA8D386F849E73C +:10DE4000F94712A945FB39659ECE5EA6FF123B99A4 +:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9 +:10DE6000F68DEEA96671671709E2F767C8BB1C1645 +:10DE7000FABCA75A71033D2599EC73278C4749AE2C +:10DE800067231BCF359E8D9768CA83B28B79B9E91A +:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950 +:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3 +:10DEB000B67AD558F9139D2D2454A5CBB7700E1002 +:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953 +:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95 +:10DEE000D75FBF3ABCED518063F36D2F221D72BF27 +:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A +:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326 +:10DF10008083C27398A265FD0CF835247B57A83026 +:10DF200088E6CC9A44D85615ADAFBD92120E950F27 +:10DF3000E9F334D95F0CF190174822C5F7064D522A +:10DF400059FE9BF43CF0534E95847E58CE219F039E +:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55 +:10DF60002A148C375457555C0EEDC30E317A715D0F +:10DF7000C7F047E114ACA2FC30E2108B279492B0BA +:10DF80003748DB877989350DF4C73C0A60985F27ED +:10DF9000C70F8F0F949686FC00D444AF118F6E1379 +:10DFA0001ECD78758DA47804FD52448A985FC7EC25 +:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D +:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96 +:10DFD000A1ECA1F62394895AC545A574BEA1743A53 +:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A +:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C +:10E00000519BE4A552D9505F9BA6887D3C3FE8D444 +:10E01000C42C0BDFE79971A746EB9D990ADFD76304 +:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550 +:10E03000F01387F5092377AEF71744DBEF28A475B3 +:10E04000DA7E80DB73B54B2DBE2D31E877D948469B +:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440 +:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95 +:10E070005775F191C3853CAEEEAB60713612FDF978 +:10E080007A12CFB322F0BC330476C4ADAF5EE90D93 +:10E090009281E5AE355339A2A7938B051D8C2423BD +:10E0A000D19F27530E54009D754D54801E4A391F31 +:10E0B000106EC761889FD2CF539FDEFD174D053F7D +:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8 +:10E0D00022E83391F7434895FB7DBA2EC97FA90505 +:10E0E000ECB681ED1485BCAF83476FED8C24D00373 +:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58 +:10E10000679A0F858C5DF163FC669FA7AE11E6658B +:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA +:10E120003CB809C683C4BEC986CE09F17114189DD6 +:10E13000545F807CDE109A8579159DDE0983C6AF19 +:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8 +:10E15000697910F88DEAC12738DFE4943FF6DAB523 +:10E16000067E396AE297A3267E397A0A7EB9E04EA6 +:10E1700068EFC9540CF51CE0175D7D6B845F583D5A +:10E18000CA2F47915FEE79D986F58D238F1AF865EE +:10E190004521AD67EBF865BAECDB12C30E78E53BC1 +:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39 +:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE +:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9 +:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53 +:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5 +:10E1F000F520D397423F97713CFE8DC731CA424C00 +:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D +:10E2100082BE9E22912E1596BAAC76A414B59BE8C8 +:10E22000F7D06EBACFCBF266C92166EFD8E97F404E +:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3 +:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E +:10E25000D870A812ED90CFB36D83EE5775F2F546E6 +:10E26000ECA9525F45AC78587DA184F0BEC9A3C526 +:10E270001796813EBE0AF5AED0E766BDDC53F59237 +:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC +:10E29000E1F501E50C3907E546442FF37A442FF305 +:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3 +:10E2B00077FA757A7B19D4B34FAD9717707970B62A +:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07 +:10E2D000A929FC0EE54C2DC899A453CB995A90332B +:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08 +:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC +:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29 +:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E +:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC +:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3 +:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C +:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516 +:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5 +:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18 +:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8 +:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725 +:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11 +:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40 +:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07 +:10E3D0005EA28F9D877157EBCE4791E879295C0F3C +:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC +:10E3F000D26E63713BF3F3FF2E90D83936A9D60164 +:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B +:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA +:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04 +:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81 +:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A +:10E45000BA2362BFD0F7549D9F44EB400E113F0991 +:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD +:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B +:10E480009770416CFB85D671DFCD91680FACCC03E2 +:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711 +:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997 +:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C +:10E4C00049E102965F2DE86BABEAC578726735C10A +:10E4D000F8636768656A09AD3FD1602112AD5FFFDF +:10E4E000328B0B6F2827013847BB219B603DE465C9 +:10E4F00074304376FE08E2E03D55D47F52216EF73A +:10E50000E35A80EDBA8499B73928BDD4962B04FC20 +:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7 +:10E52000ABA62A64E519C4AD13E562897224E54FF0 +:10E530003519F876A078B439FE4CE417BC802F73F7 +:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60 +:10E5500034CD8278EEA9E871C12815F599594F9903 +:10E56000F958D0D340F4E7043B69A2AECECFE186A0 +:10E57000F93EB513ECA48951BAE8AD9D94142BFF74 +:10E580004A9409CD7F78457F1E2F41E9C6F1129A42 +:10E5900077E1F3BB206F00D6A778519E3E5849E53E +:10E5A000708CF9ED6E597608E4E7AE96662C2F5024 +:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71 +:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC +:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1 +:10E5E000241D5F474753FBE87774F83EEF43BFA114 +:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C +:10E600003D2560686F2AA83B067CE92ADD6178EE2B +:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3 +:10E6200049329CBBA0AFC8706E88F2F190662A5E3A +:10E6300069FDFE441EE7E866FBE49924F283740951 +:10E64000A964601FF426B23CC8D62CF67EEB8DACD4 +:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4 +:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE +:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB +:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638 +:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46 +:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD +:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199 +:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657 +:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545 +:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4 +:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757 +:10E70000F3FB0988827ED1307714AE01913F22431A +:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0 +:10E720005F934D787ECD4CF427051E364139AEFF00 +:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A +:10E740006FA66F15F112C7E95BBA99E5456499E8C0 +:10E7500046E45D08BA14F919225F43E46FD8785E85 +:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7 +:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660 +:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0 +:10E790005F17E556F875321DC21BAE027BB5A85C4B +:10E7A0006B85F37C29A504CFE994964B58161D621E +:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774 +:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3 +:10E7D000E6CDF3906772FA5E3D5966F9D155129312 +:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27 +:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72 +:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF +:10E81000883B4585F98535E0C7153977EF817C88D8 +:10E82000272E647BB6171F62F6C28FCBAFC6FB469E +:10E830005C5FCB188F754F49F406E0433556A6FF51 +:10E84000453E74B9D15EA835D90B179FE2FE8F14EF +:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2 +:10E86000F78030F950CAC77496BB1D10BF2E3A64AA +:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74 +:10E88000D0F3A82F723886B89CF81BCF93ECE172B6 +:10E89000E2752E270E839CA0E52B3C4FF210CF9300 +:10E8A000349F97D8D152FD92DEDE319745927F1684 +:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB +:10E8C000C7B802E9676FF2DD15401CEB350BDA952E +:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB +:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0 +:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D +:10E9000003E97988D78EFBFB649E93BCABCB53B9EC +:10E91000DDD7350BE6FFE03605CFE7887113BD7410 +:10E920003E3A3A499BB22713E6DF39359809F64C4F +:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603 +:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD +:10E9500064B867C20CFF01ED0EC80818FCBC95B383 +:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96 +:10E970009EE6FD17099C0EB3161207FADD408F8341 +:10E98000E0D9650D21DED62EB454C73A5F5B54C47E +:10E99000F0BDB6F453B48B4971EC7924959BE9959D +:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483 +:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8 +:10E9C0006A074948EF28973E2BB5313BC1242FFAFF +:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8 +:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898 +:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B +:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D +:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF +:10EA20000C043F33BC167EC7F032B7FFA888C74737 +:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A +:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6 +:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE +:10EA6000A93980B4594F8F820819B9555A66B07FB9 +:10EA70003A24EFE167302ED4970AFDA6933A852118 +:10EA80003980EBFA93146E05857529D15641D94822 +:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C +:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC +:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB +:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909 +:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4 +:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758 +:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73 +:10EB00003923A5AE11E07115516DAC647683589729 +:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1 +:10EB2000F959D7E0EB1378FF4711C175DC5EA46299 +:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E +:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB +:10EB500016609C4CC075603A35C6C976C121D77421 +:10EB600084DFCB7AF811A5AE04C615EBF96759E836 +:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B +:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF +:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6 +:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE +:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9 +:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C +:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C +:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6 +:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146 +:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD +:10EC10009619890B9347D0F28238E277D0F13224EB +:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1 +:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845 +:10EC40005B371DBE932CE37C8E503B51A172ACE22E +:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C +:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228 +:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED +:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58 +:10EC9000D13CE82F5CC7FD8537E3991FF466A18856 +:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199 +:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98 +:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1 +:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8 +:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E +:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B +:10ED000058E09EF36B0F9FC74070694C568842E1F4 +:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A +:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90 +:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA +:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C +:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9 +:10ED6000BC9BDB418D2793893F55FF9CF17774FC59 +:10ED7000346CFF2D87DB6FF75BAA63E577358F6611 +:10ED800070199DAEF8201F684C90689B637C57F407 +:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C +:10EDA000D1627D6F3187A3986F4F4A78910FE9B395 +:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC +:10EDC000FC309C0BE37F7C61EC733B02CF9394653A +:10EDD000682FBF9052F734C8B77997D10AA58F2111 +:10EDE000F38216763EC53F28BEA370964960E26066 +:10EDF00070B661BB18EFA317393F523F1CF2D4AF76 +:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796 +:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661 +:10EE20006D9FB60FD4C15599D4064D61CF6F86B290 +:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2 +:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E +:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835 +:10EE60007E36DB799B47F3F8FE2432E94CFCF24610 +:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6 +:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E +:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8 +:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196 +:10EEB000D345704F0C99C3EC8638387C407F8D9BCE +:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A +:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6 +:10EEE000E807D5305EFA43091AC0ADA3421B0FF202 +:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96 +:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742 +:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28 +:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E +:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28 +:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF +:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C +:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF +:10EF70006530632EE8DB0715A647F9FCD2FE9855ED +:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317 +:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8 +:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE +:10EFB000EF2EB126837D036B898577519AED20C1B1 +:10EFC000878D0F24FA21EEFAB1D45708831CB13291 +:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51 +:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC +:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314 +:10F0000008E2B930715F999BF813E9779A760FD9C6 +:10F01000027646DA086DFC723ADEC7D6702ECA0B4D +:10F020002ADF24AA5B73C7ACB944A17CD53894DA33 +:10F030005DB47ED14377B37A7E789185D6AF7DE893 +:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F +:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9 +:10F060003F74E012F0FF8F2433FB8178C35702FD19 +:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28 +:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731 +:10F09000083B96D971629DE23D92197BFCB1639861 +:10F0A0001EBD661AEB7741026977B0F3757EB0C773 +:10F0B000F6EE1A8570491993C2E145C7298D8E2352 +:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9 +:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744 +:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E +:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7 +:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB +:10F11000403ABA2081D98BA494C28FCAB38D1C6E99 +:10F12000EBC624333F32828721128EDFCAE197CDAE +:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565 +:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1 +:10F1500072CA78308F9411F8DE6A07B1E373B22572 +:10F16000F25E1E7DEF82697D13811F96727B98F897 +:10F17000CFC7BC86062E2D96B6876C10975EDACD6B +:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA +:10F19000CDD61730D02739D4973B3BB13FDD46E081 +:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B +:10F1B0001D671B1F629E267846E06C9A9F8027F091 +:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8 +:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60 +:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064 +:10F1F000541607EFA9F583FE6BDA558171AAA54F66 +:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16 +:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5 +:10F220002820C7CC5B7F9BCB01617735727D73E46F +:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3 +:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6 +:10F250009D46FB69F16F3664A8484FFE6116DC04D9 +:10F260000B0E83CDB0C66D56DC4F693C247BE9673D +:10F270004813E9BB15E6677E1FE67192E2BDA95B04 +:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2 +:10F290004D3D177E00764593299FA27E003BECC52D +:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED +:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F +:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F +:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB +:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57 +:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4 +:10F30000B41A367D27EC730B3C41CE06D829022F68 +:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A +:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA +:10F33000DB33C004697DF04B1BD0F747BB25BCF71E +:10F34000DEFC7EFDE6E75D40870027F04305BE2238 +:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC +:10F3600001476548E78F3C0D7194D7E3BC0087FAED +:10F3700047AE75C17A3E5096317ABF6F5506DC971D +:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2 +:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E +:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F +:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B +:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6 +:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9 +:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F +:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21 +:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F +:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2 +:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9 +:10F43000D7678718FF34066AABB13D640D0E81F6BD +:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75 +:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1 +:10F46000AE38C37E7D947E8CF745097E157ED6D559 +:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE +:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61 +:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626 +:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0 +:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB +:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9 +:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA +:10F4E000111D3C051C057D2E7E68297E2742C782A2 +:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD +:10F50000FE837525F563C0CE7D560E6CA1533B4E30 +:10F51000E7722B85FFF1DFE561BED12AEE071C778C +:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2 +:10F5300060F6D2715F9F2B596737BDBD4B76819DB9 +:10F54000170E90EA58F1242AB1711E6132503BDB4C +:10F55000173BCEE3A1C779BC73BAECCC6D8638708B +:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC +:10F57000FF7EF66799DDEBE9D714C89358C0404089 +:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6 +:10F5900045CE6DB8BFF039B9194B73FC6431C4590D +:10F5A00080DEEF353DDF7511D2D762137DD5017D49 +:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC +:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7 +:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B +:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C +:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3 +:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25 +:10F610003B0EE7737CF79F726F82FAD37198877500 +:10F620007C651CE645F9772706E03CDFF11C16B740 +:10F630006B7DF6CB12CCBF206D88C793C536668F25 +:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6 +:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E +:10F660003F5D4FA38DC5338F2792398F033D2733DD +:10F67000FFAEE999C95B215F6E694FAF0DF607A632 +:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD +:10F690001DCA639BEEB652787F0C3622F5C3378DB8 +:10F6A000EDBE14FCF0FE706170384EE100EBA2700C +:10F6B000A907793A103C868EB521FD7FFFE0F1095C +:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45 +:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57 +:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD +:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12 +:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837 +:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F +:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3 +:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1 +:10F7400035809DF2EE5849E4EFA01F22F277E4B431 +:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2 +:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8 +:10F770005B8737783B7004A37F2667D454439CA5EE +:10F7800075059D171DA735DDE26E55E19A764B3064 +:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04 +:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50 +:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30 +:10F7C0000298B779A6704A2D191C4E66F808B8F54C +:10F7D0008313F747C57DFC4A5A4708F85021D49F48 +:10F7E00064EB413F14FE8E14ECD7589316793BD846 +:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB +:10F800005F2AE0AC1B0FD76F86F399C257E0C54162 +:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA +:10F820001DEE1717F0157033E3E17DA0519D1D1FEC +:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3 +:10F84000E5F204B4978F49242851FFED5845462529 +:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0 +:10F860003DF237F4A05E41920DF5633985F8FE3420 +:10F870007B96E1BD0390B74DFDF66359E576DC0F4D +:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79 +:10F8900003FD9B1F641619C699F9CEB17BAFA2E593 +:10F8A0004EEE57F74DB5623CFED89FE755021C2F30 +:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B +:10F8C0009EC986EF36BCBDA710E2103FF256189EC7 +:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A +:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B +:10F8F000761BC699B87FA7A1BF37E49E0626E3848E +:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE +:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751 +:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF +:10F9300039E081327ED8A21258D747999D326C4B5C +:10F94000DF23D55D5E0276D6678156A85FF075B776 +:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E +:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7 +:10F970009DC8DB31F371D1C48A25307E5BA6D6D514 +:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296 +:10F9900089BEDB619F5EE425C54F935972FB0FACB6 +:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E +:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70 +:10F9C000B323774898D722BEB7A09CE5DBDF5E2241 +:10F9D000EE3771A7FF642CBC9FC8F205209606EF96 +:10F9E000D558D04E711DF6EE83FBC8EEF41C728321 +:10F9F00078E8A979C70FFB223D874353258A9721D1 +:10FA00009D15270A587F02F1CD1E4F55C258D46F5D +:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB +:10FA2000D14306CB2F779D9488AACB33B08E5371E8 +:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411 +:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A +:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2 +:10FA60003CC84FC20BD19470E64F629CC33BB2A31B +:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2 +:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D +:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644 +:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD +:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC +:10FAC000CC9F38355C134E01571783EBD7542B640A +:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86 +:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81 +:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D +:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5 +:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82 +:10FB2000A2759013AE285C35B82BB84307673BAD80 +:10FB3000D772B8FECF23F597B5017E17DA912EAEB6 +:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E +:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59 +:10FB600067C2DF71197BD082F1BD37297D68401FE4 +:10FB7000C1F1087731DE8929AFA6C0F98913694A36 +:10FB80000AC06771D88670FB894282707F6A4FDA3B +:10FB9000C26915C81F2AB677F371264FD4FE518269 +:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB +:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115 +:10FBC0000C7A62797221E663355549A8879B9A3F82 +:10FBD00043B88BF1959332517579533D104D4CD705 +:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2 +:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1 +:10FC000013F72DDB419F34903DB6E53A7948BA3F72 +:10FC100089C8FF71147777D6BC180F72B656725F19 +:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0 +:10FC30007F8EF71156CF715F02FBFD631F4D9A0354 +:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78 +:10FC5000F7CB509F316E06AB27323A4879347F8E0E +:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E +:10FC7000C600977EEDB284795198B841E9E79F6B51 +:10FC800086B17B710B4298A735721C8BAF67A4B00D +:10FC90003FC92BF277D346100DF657D39E72B07B37 +:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A +:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A +:10FCC000F84908EB5737EFC679754C70F3FB72FBB8 +:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64 +:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3 +:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916 +:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E +:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F +:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922 +:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9 +:10FD400073395C9376B2FD6F735EEC5CD05700172D +:10FD5000BECFBC74D60B53002F029F1724906ECCDD +:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1 +:10FD70008B451702FE84E5DBC53379D1F78403EDAB +:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781 +:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7 +:10FDA0005EB798F799D359C8763A7426E44C23A9DC +:10FDB000F3605C96CB150167314F01AF9E01F25D98 +:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C +:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD +:10FDE000BA849C35AF4FC85BB14E2177C57AA75214 +:10FDF0004182F210EE7E90C07FA833D8C3157062A6 +:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3 +:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB +:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B +:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8 +:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740 +:10FE500078F1F97FB59463F9428B8665A8C587A5CB +:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E +:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1 +:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C +:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE +:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27 +:10FEB00073ECEC5EDB397324CC4F9C43D879055A44 +:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26 +:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1 +:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE +:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0 +:10FF00008C9D8710F786BC6E3913BBE12B386300DC +:10FF100079A09297FDDD9464C5ABF70744F9D771DA +:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1 +:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58 +:10FF4000FF0B270420E00080000000001F8B08004A +:10FF500000000000000BB55A0B74146596BED5D591 +:10FF6000AF904EE88400411E76886020AF4E271D7A +:10FF7000C26B2812C01762A3B2038A52A0189E490E +:10FF80000CCC8AA37BBAB11904D6B39B193DAEAE93 +:10FF9000E869705076D6738890B8194D980695C761 +:10FFA000ACA3514141B3D820F258133A121470381F +:10FFB00087BDF7FE5574572701F4ACC9C9B9F9AB31 +:10FFC000FEFAFFFFBEEFFDAA961D70B98300505DDB +:10FFD000B63A0F0A904E918EDA902E5BF50398FB9D +:10FFE000E178D5393017034C95DF08A696009C3D83 +:10FFF000046E1BCE1FD3AE9EDAE1C27F2E5D9660EB +:020000021000EC +:1000000000C04A3BFE8FE3B2CEBA8ABEF86F51B849 +:100010001ECC740D7F2EE35FF1BE2630E7C4C6E32D +:100020002ED4BF4BF376FA55305B009AFDB3998618 +:10003000FD8BC03C0260B7BF86C7EFF957F1788FE0 +:100040003FC0749F7F1DD3BFFAEBF8FE07FE177801 +:10005000FCA13FC4B4D5BF95AF37B89D00FD01CE1C +:10006000B5560C54F3F06834F6E286F6C999BE141E +:10007000A4664167D3813C48ED60C9C8403A5B62E1 +:1000800079E0F500A4330DAB787F59E63B2C0FFCEB +:10009000F1D991DF59A0FD64F4334329C0BD20F8A4 +:1000A0009F55F6DF17A5541AA83912CAEBBECC3EED +:1000B000B04102B81F02F9F391CEAEACB38C97E811 +:1000C000FE14E709948714F8C274391765423F9308 +:1000D000BA533C289CD0E526032C71ACB1C2700009 +:1000E00094D2B108CAD704125CCE02580C612BD04E +:1000F000FD3F5A8E45E2E4BC14200BB2F1FC6F5870 +:1001000078BE7E1DE8F9B875E50A19CAD2496E2E87 +:1001100096DB7288F07A36F951778D83F6ABB3D2DD +:100120003A89FB2E71BC67C5410FFBB6F2F3D7DAF3 +:1001300057D75315C07C9ABF2653A9DB85EB2EEF0A +:10014000D3F6A06CEA411E4E73E795F5500EFF32D0 +:100150004AE8554E9962571D64A70E30A11EA3218F +:100160003964C3751665D5A5D2BA6898A980D71722 +:10017000B7C8AC0F302BE641A8B74A4D6FED10FE63 +:100180008CF45239A1723AA0FE166D34F2B3C471E8 +:100190009CE5FE3D34F7C86F153CF39D9CDA9DDF6E +:1001A000AA09B79CA4F5AA34B9F1753CD7AA366957 +:1001B000DB7B71F356B853324E249363C118920B14 +:1001C000F2E10E93BF1D90D9DF7AB38F337E607B4F +:1001D0003FEF876DEFA1FD9FB984176E0078D23D88 +:1001E000ED85C0845F4E6FFD8A7DEBDDE44F6827AF +:1001F000E447BA1ED7A20D019E7B6DB93D1440792C +:1002000046BD4E33ED1F9542C154D2CB4570AF462B +:10021000794F6EDE7B88FC64B2DD1126B92113EDC7 +:10022000F17A9DD42E2E4F3C1E0AA6E0FCF16D0102 +:1002300099DC76EC0135E8C0F1980F14D434C699F6 +:10024000F77C32E97DBBBF89E550EFAF671AF39FBA +:100250009BD8CF60105ECBBE7E3F8387ED268A6B36 +:100260002BB43305D3A0CE8401ABCB314D4E413EF0 +:10027000BAC2E0A6EB45075C413A57719B22A7E260 +:10028000B9BCC7D5209D7B2DAA41B1519C0CC87D1E +:10029000F1BACD0C611BC6115BA6099438B98E3D2D +:1002A000170A521CD4E35A7392B0E74997EA658A59 +:1002B0005B4EABBA7513CA13DE4E726F71753FF7A2 +:1002C0003B6E13CBFDEB74DF3B6EA4E0708DF4E569 +:1002D00093FDB4BFF612D94F43B2DB86CF25C66972 +:1002E0003D2EEAEBE872D3E558EDECE2B8BF6C5571 +:1002F00017C7BDC47DAB4DA0D6A3DC3D15AEE25AF9 +:100300005CA77D35CC9B89E33A0BD2BCEEF33FF181 +:10031000947F48F632559ED0AAD0B99CA6ABDA7528 +:10032000F5AAEF78FF5EEF6BFB57B7789D0B1CB11A +:10033000EB8E2249C479303B4FD863FABC5EBD4F87 +:10034000EC9C6DC85B932EA886BC3519236DFCFD13 +:100350000AFBA386F154E7E386F9B764AE36DCBF47 +:10036000CDB5DE70FF8E9CDF1BC677BA5F34CCBF85 +:10037000AB6C93E1FE4CE53F0CF767C8A048E8730F +:10038000F952C8427E3607EA99CE8556A60F422713 +:1003900053152D89E80270337D187C4C977B54B936 +:1003A00008ED266AE91C407EDFF1D6DFF3C82E3A5D +:1003B0007E35DE99E58AE5653D4FFFD47CDCC78A52 +:1003C0007AEAC11E061409BBD5E37DAFFA4988F766 +:1003D000D1228C2778CE686332C799684A9F9024CF +:1003E000C5E2095AA489F2B1EEB77A7C299EEBFEE8 +:1003F0006805F9D107328C70758F3753CD581A784C +:10040000E8BA3BE781FCD8FE41132C223BDB8AF49F +:100410004DE4A3EFDC88D915C74F01F181F6367999 +:10042000CE1488E0F5194E5042387F861D322E508A +:100430002CBCD495370B03C48C0BA828B4E71FD36E +:1004400095429277E0E909692772B5B87423EAEF1B +:10045000A889F981C5526804CAA3A9418CF317A6DB +:10046000317FF74398F5F800442CC4FF3C008ED34D +:10047000F3C1C5F42150589FB8727201C6A7850D0B +:1004800066CF06E4B330BD7338F967FED8C3E9120E +:100490009E0B4B3B85F82934C13AAA6F743E6A35EE +:1004A0003E3614291574BEC2F4D60DCFE2FE9D8DE2 +:1004B00026D88CEB9C1CFBF82310978FB77ACA6F59 +:1004C000A579DB245028AF065A6CA12D59B47FE7DB +:1004D00000CA07FABCE59E8A1945B8EEAC22607DD9 +:1004E00043EB5F80F433D329640F53FAB30CF0B9B4 +:1004F00061BEFC9EFC33C0CF15922C6F0071A18CA5 +:10050000F7E5F1236FBE317B4D1EF313A03A6EABBE +:10051000479DC7E7B7622CA0F3BF6C0B6DE67AABC3 +:10052000669884E7AC7CC566A2FC7F18E333DC0CDC +:10053000F0A5DFCEF47FFC4EA65FF933991EF5BB24 +:10054000987EEDCF61BAF0023280FA3B59A4541183 +:100550003FBDF1D17B9C117C4425985DEFE87EBFC7 +:1005600052F3878286E34F25931D34C96EB2D3FCC4 +:1005700046344C3CF799E63121392B5EAEEA13C480 +:100580006741D3A77F185F42CF999D12CE3FD3D446 +:100590003580FC37F17C57E4D16215F2D0CEBB2D0B +:1005A000AD75033DBFAD71389D10E308083B247D58 +:1005B0004A3DF1B19AEDE4574522DFDF65EB2C713E +:1005C0003A62FC01951898676AB53C3355BE944A67 +:1005D0007E3193D61D4B767DD347B45F609FF04349 +:1005E000D4EB3C5F9C3FEDD0E4A0D3FC16AB8FFC7A +:1005F000695BCB6777DF81729831EE36AFEC8ACDDD +:100600007F9584E025FBBEF8EFCF66F07C276D3543 +:1006100007364D75E2BCFBEDBBDE27113CE03C3AF2 +:10062000350DC7F332A53D44E7BBB2A6A5531C80E8 +:10063000103FFF50CEE43D6462D3DD33AD544F4CE8 +:1006400026A78A8BBB15768C378638DFCF30BE2540 +:1006500073B061FE6DAE6CC3FD3B72720DF7F57D3C +:10066000A7BB8B0DF3C85FA9DE463E58EFB0450E21 +:100670008D90C80ECE7DB194F99F5342FC47517EB8 +:10068000562C1C4E95AD7FFE590A1B8DBB53C93F9E +:1006900013EBDA652DAFEE515CBDD7B555E0EB1B22 +:1006A000967AAF677BAB07AFB7AEC538F2078A2340 +:1006B000856FDDEB0CE239B68DBD78830BF9FBB8A5 +:1006C000A8E77A37AAD5BB897674C55E2597B09F0F +:1006D000FD32503DA4D7BD897604F094560708FA40 +:1006E00053FD7DC627226F7D437EDF2FDEBE351A88 +:1006F0002A32E499422BE617D44FE7DF64D84C172F +:100700002EE139743D64C7EC1F1EDEF4FEA012BE5C +:100710001EA0BAB68AF202AE9FEC91C4BACB76BDE7 +:100720003F2823761F561E35CC8727A53D86F19A94 +:100730002CE3F899C97BE29FEF2D1E556E7CD4AA5D +:10074000629CAE7C4EE27C95785F3FCFD4DD490A57 +:10075000C54D73B38DFBA92AA7028A83AA26CC2391 +:100760003DE4753D3ECC91A1A6A73837405B77FAB2 +:10077000EE24907FC6BA87D156E83C81FF12F9E695 +:10078000705F057C71FB647944FDD79156F74F3F4C +:10079000E0BC8E3F839B44DF9126E26E41C34993C8 +:1007A00089F25F1F612F05CE88291D69745172007F +:1007B000D09FAA17A7044C85787F78E7677654FD09 +:1007C00028CFA017EDA8B72F4C2643FE8952CCC3E3 +:1007D000B1677BE61CCA3F77EC4E0A9B7E063F1E44 +:1007E000AA399016960BBF7F90EC46ECA300FA470F +:1007F000F5EF40DF57A13841FCD378A967C8E1E79E +:1008000070DDEAFD220EE06D47623F7B7F5C3F0BAF +:100810001B85FFDAF197EA9D2A084D73106E10468A +:10082000FF875FCEFF67781C195CE7909FDFDCDDF8 +:10083000AF75BFAF3E28FCFE6CF3F79F509C3F8B1B +:10084000F92FDEEF75B9E9FE5EFD82CC7EA95F3F30 +:10085000D32CDF1AEA41CE65BA5F296EF6D75AA7C4 +:10086000D8B776E2F9BB29CFD5B6A086A4EEFBE8CF +:10087000B47A9D0CAEB87DB6EDB42D0A39627C44D5 +:10088000F5FCDAF27DFAE43C415753FE853A2DFE41 +:1008900088BA06F3AA2583F2EA4CC9BD05C9C196F8 +:1008A00081E524BF8312845D1E5EE25E3B9EEF1EE7 +:1008B000B11C5D77507D06993966DAE76E4DAFF76A +:1008C00068F8D2AC96592328DE7FD6B0E0A042511A +:1008D000CE93CDFBFD1A025C1F1E4CF30D5D4175DE +:1008E0006850D8F9C1B4CE76C2A30E4E4C9682128F +:1008F000AFBF26BEFE3B68F10DAD61BE345C4A1948 +:100900002D5F4EFE09FDB21617519F0149F477EC99 +:1009100007E641CF30CEB018427B14DCB7CA1DE6E3 +:100920003A7529085C20B1BEAF9AF0AD95F24362EA +:100930003F3AB969D721A9A0071C23C16EAF855BD7 +:1009400024F6C1BDE10F3FA6FBB678E2F0C3C47A3E +:10095000FD4A5DAAD7555B92439BF13CEF4EFCB735 +:10096000334B71BC724BB293FAEED3AFD802149FE3 +:100970004F6FB68524BC7F3ABDB38DFA90D3DBF3BD +:10098000DDB802549A5CFFF906E5F93F59D82E000C +:10099000DCC23FAED8E9634728DED56E499180EAD4 +:1009A0006B55DCD77B40F9F514AE1316EF1814B273 +:1009B00049B13C43FEE1C2D2E2D4CB490A15FDA7BE +:1009C000F7DDD397F0AB76D39BC3180F939F3CF220 +:1009D000383EB7F4B5140FD5139007ACB7459B4715 +:1009E0006DA2FAF8258BBA97F8AF78FDCE8159B48D +:1009F000FEA7FD81F88936EF1840F551AC6EEFB9CE +:100A0000DE3BDB9CDD17F26272D2F1C4757F5CEDD8 +:100A100023BD274B2EBE6E861A6530D945D34CA018 +:100A2000753DB2A4905F76AE4FE63A35D1EE8E7842 +:100A3000449FB24CC71FFA813D93FC47059643740F +:100A40007DEEE60D28A71F3CE95ABEEE1C79777EA5 +:100A5000BC7DB655BD43F6B9D1C6B8487B92B16EE0 +:100A6000D0E9FF7AD2789F4AFB39030E51B5EAA24A +:100A7000719C87FD1E3EEF09BA8A1F45BA42937FDB +:100A8000D7685F87079F5F52FFFBB73E60B96CFC7A +:100A9000C72F68DF7D0E81C77C20E497D80F54DA1A +:100AA00005EE01B089CFAB5F3FF9F2E70564872718 +:100AB0001B7347921E17C8AD275E423ECFA4B41EDB +:100AC0007902E9F67D9FB05E12CF9B88DFB44B12AE +:100AD000F3BB8CF8C0EBF77A7D72717F7667EEE33B +:100AE000166CC867F94D95F3FA921EA3A77BE957D8 +:100AF000B473EAEBEBE7D3D7D7E7398B85BE3ED4A7 +:100B0000F0F70E6BEB19D26FC75BB912E18357AEEA +:100B1000A7B716A4C5D9CB2F85CBDFA7E123874C78 +:100B2000AB7F63457B6CAF7FD6A2C6C7BD9F88C72E +:100B30005FA907157039078854C2790B9933E37898 +:100B4000A23E2667C0F104ED78129D07FD72A24611 +:100B500061899AC9783BAD873409423C0E4E76BB19 +:100B6000884E927C8C7BE87DC334A819427C98EC3B +:100B700011C609D7103E8975CBACB4B57766E17E56 +:100B80006BFAC35AAA67D658845F04E627733FA757 +:100B9000CB49CF33E0CC33E497354E7099719DD972 +:100BA0006658674917F36E44391FDCB7E07DC25DB4 +:100BB0003F37D7F4A77D0F3B9ECB974C54E7855228 +:100BC000A867FCE2933F79FF8673BF046522D515C1 +:100BD000F7EEB573DC4FC4271682CAE34A8858CEB5 +:100BE000E1735F8DFD71CB6E88F1F5D5B81F1AA941 +:100BF0004FB83FED292F3D1F28871CCA4BE7935262 +:100C00000B889F5576411FEB93BA99E869A723405B +:100C1000B8ECF9A46121CAA72F49EA8364CFF81C74 +:100C2000F7B18123C921CA778FC96A15E3D0695604 +:100C300090707EB4BF26970E60B9442DDAFCEF5C4D +:100C40003C2EA9F0304E09E75D1C97C727E49D9222 +:100C50005C93E8CF2E8BF9133BCD86BC5352A8E1B1 +:100C6000397F77719D3AE982F9AA79E952B1E8773B +:100C70004BFA996A7AAA179FD5EE07212C0B9C474D +:100C8000D40BE3AFD89722931EABB47115E535B4FE +:100C9000AB68AA3D2023BFE39B859D8D37877711E5 +:100CA000C5280BABA8BE68C2BCA79F03E30A64E6D5 +:100CB000B23D8CD3ED14D79A8BF3D64A35DCC7D826 +:100CC000A9AE41BA416AE573FC0A3A992A5A3E2F05 +:100CD0000737D329E0638A76CAF456A8637A3BD4EF +:100CE000339D0EAD22FF8F0E0739AFC1934EEE0735 +:100CF0006FAB3451DD51F2EB9EFB87462D9EF42EF7 +:100D00000774BCD29F2E876980FE97DD833C86E402 +:100D1000701C499447A29F4E8488CC7E4A01229B36 +:100D2000F00317FB6B05283C9E7A9D72288BA86602 +:100D3000C66F12E551D1B35DECD4ECA2966CAD7FD9 +:100D40004C4F5DC52E1EEBFA42FFCAA43A34518FB8 +:100D5000FAF592E4F22E1786E22F761C9F63C6BC4A +:100D600054525CBE221BC7EDC5DFCF31633E2B1949 +:100D70005FBE63388ECFECF8418C0BCB8B2D6EECC5 +:100D800062569F9F3305E7ABE49F8544D10F299EB0 +:100D9000A9A23F5EA9D531EAEADFB89DE82FEA5063 +:100DA000879BF8B463B19F847294B3C57BC761B766 +:100DB00086775B70DE718B7A90FC77B93D9CEA4256 +:100DC000F9AF5C3D752085CEA7AD62BECD26705AC9 +:100DD0009D3FBC1E48C2F1F6EDB92BA4E1D73E07FA +:100DE000AEFF35ADAFAE1E1120FF551B25B7D06C41 +:100DF000F9C0D928C3F6560B106EAAEFF7D468F5E0 +:100E000014E747979BE3F760ADCE69DF9E9B4B7A73 +:100E1000EA2A163818646415931C8F8EF675D1FC77 +:100E2000688AB0B72ECAE5DEDEE9E012E53B9A9F9C +:100E3000783DFA0D1E009F3797A8E7E97E75F225E9 +:100E4000CEFB678A3E5D1BC98AD9AD844A9B8BFC69 +:100E500007150859393F4C705EA95329DE2DC4751A +:100E6000501E253E3548216ECCDCCE528AABB8AE42 +:100E7000A904F7A9B6468615E173CFDD73C42AEC41 +:100E80006E88B03B2D2EB5ECDCFFC46031F4419C84 +:100E90009F55EFBCF8C39728BFEAB30E374D8FF9C3 +:100EA000D78B2BB8DF0487218EE87E37AEC9C6F515 +:100EB000F6F8E6510B69DEC44FDBB289AF496D111C +:100EC0007E8F166DF97CB03887DE879C977E4E3E0C +:100ED0003EA9E58993769117E8BD30F77B8DE2BD99 +:100EE00070AD8673D6B648A100C71FD13F2FD2F888 +:100EF0005BBEBF710FE1278B363E349DED2824FA8F +:100F00000A17FE525C587248F4CD4BB71AFB8D6A33 +:100F1000EA9B693E84AD640FCBEB13EE6FACE0BE91 +:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B +:100F3000E4B97DD51EE261625F5C05CA8412AE7BB6 +:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A +:100F500052DB9BE4E460B958B99FA87D7985DB49F1 +:100F600063CD6F3799A8A7C689EF7D04F1CFE97EDD +:100F7000BC789DC47D076CECC73658F89A4D217E2D +:100F80000B5F1BC87D08F64B5C1F6E7ACDB68EC614 +:100F9000C1DFF509C885844377DE40384C3009EB62 +:100FA0004D81E783E4611C867191474BB4B8AFD59E +:100FB00001102E32F4F3412DFFD7A68C1C889D73AF +:100FC0006CDEBE4186FE24A8D5DB25744EAA1BB775 +:100FD000DE20EE27093E767DFC0FC954F7369A7D58 +:100FE000C9846B9F3D309CFB98DEE4EEC53404570A +:100FF000794FE9FD7C7AF6D5F456F28259C84BB3A5 +:10100000DBB7FD0A7C6D89E945E76FAAFC4685954B +:10101000709187C1493849EDFE578376EA0BD703B3 +:1010200023106741D8F3D953267EEF5E0A39FF3A81 +:1010300001C7DE536677089F6FD0E222BD7F76C579 +:10104000D9994DC37F935C7DC015D74727E7A41B73 +:10105000C629EE1B0CCFF52D1B6EB88FF2DE4CEBC4 +:10106000434069CD2B8DD5BD69CA68C3734FA74E68 +:10107000DBC77EDFFA08E352FD6EF518CF2337CBCE +:10108000140FE09CA897CAF097FC6D0C0482A48F03 +:1010900071EDC63AAA2C52C77D63D201B30107B0E5 +:1010A0005D0397DA44FE457172080C11712351DE1D +:1010B000C6EF2F6AF7CB5CEFD50EC54235AB27796B +:1010C000DF6490B7EE8FBADCFBFB8C721F38DB2835 +:1010D000EF41AA51DE831719E53DB4C628EF1B572F +:1010E00019E59A1530CA317BDD38C3FC1175E586E8 +:1010F000F1CD2FDC6E983F2A74B7619CBBF53EC3DF +:10110000FCFCFA0586FB854D4BAE4BFF45E15AC30F +:10111000BC44FD17EFFBED55F51FC05FA17F607D5F +:1011200094A13EC2AEFF3F3B38A6C759DD0EAE3399 +:10113000CEBE4D3ECB78C2844880ECA02C99ED64A5 +:1011400046B2883B1FEE3B7B40C1F147AE624B2667 +:10115000D5595AFDE0D3E290DECF24F68D7795493C +:1011600009EFFB930CEFFBAFF55D9DB7356C1817DE +:101170001D00FE6EC673C8FD2E51EF7185E1AED223 +:101180005335EF121D7B8ED376B77E55FF3E2FB1C0 +:10119000DF826507F8BDE25CFDBD0C394569777CEF +:1011A00052EFC7F43E37B1FFD5FBDEEE7D9AA86360 +:1011B000BAF71BEE4C33D7D12AD7D57B259571CE04 +:1011C0004DA3D4C15E2F3501D8279BA84F8E04852F +:1011D0003015A0F7D051FA9F8A90C0B3F7111E1FA7 +:1011E0004D03C6CF15A9EEBE401E1FDF192915F00D +:1011F00011FD147BD5115ED4EB31C9B9B698F089D5 +:1012000071DF0EA37A24C72BEA3C9B8C92C2BC34BC +:1012100070AE0274FDC7746594D71BC34B7AB39B41 +:10122000C4EF931AFC61A666A79BBF5F4AC417234D +:101230002617D7A781DF4AFCDDCFB774B8B1B13A22 +:10124000E6EC3A0BD731A0F5F30F68F2D7718FB9FE +:101250001A3FC770894598971F68DACB7A599AD98F +:10126000AEE125355C8F3F34C4E1E1EFE19462B734 +:10127000C0C9741C64B0FC53EAAE6BF1BF34F3B464 +:1012800001878237FA5DD7FBF218DF62FD63EB0559 +:101290009E796CFD50C6CF63EB9F613CEA819A8FCB +:1012A0000DFE316FD561833FCC0F1C35DC8F64742C +:1012B0005A087F8CBC3568DAFD28BF8E465B29E969 +:1012C00003EDE011D2ABBE7E647DEE14DAF7DA7C7A +:1012D0007ECBE768F3B7B27E753E8FF80FF138E248 +:1012E0008F247C9F26F8D4710E9D5A77438E99DE09 +:1012F000274A7DDC842BF7867FE87E662A1DCEEBAD +:101300009C37B94E089CA8660CD57F6D930794D383 +:10131000B9DB865ACD828E14E3416576319E762BF9 +:10132000D1A8C5B18E709136497C4F3457525E9921 +:101330008FFB3E314A7D9AFCA17A496701F95F75BE +:1013400061E44109D7EFEAAF6E20F948D85E0C4A54 +:10135000673EF8BBB353A6408184AEB2C7FBF57DB0 +:10136000D4279EEA13384315CACEC623626C15FEF5 +:10137000F8A1771FFBDF715C8CF80CFC5912F89414 +:1013800023629D89EB64F4579FA77DE97B327ABF86 +:1013900047D7C93E75BC346A11756254AB175FF606 +:1013A0008A7AF69504DA44352EE18F44395E3F336C +:1013B00092F0F4B31B6D40F52DEEAF984A62DFAFAB +:1013C0000C405EA88E7DDF2AFA4CCF5F6C618A5399 +:1013D0003AAEFAA6378BD7CBC8167869C63F63DC1E +:1013E000223F8CB40E9B991277DE03C0387607E15A +:1013F000D17138F69B5ED1AFC3C322EE75AC1FCC62 +:1014000078FBF2FDC78E50FCBAD7AB36925C1798CA +:101410005CA5FC7D56EA2EC6CDF67A5DBC2F9E9764 +:10142000F9C538B486F4B4DC1E619CED5AB87A6F05 +:10143000FC772C6C7D3E8F71645701D98DBE2F9E39 +:1014400063AF370EFFD6CF115BE7EA7EA0E3C3FAA6 +:10145000F8E4CB4F8FD4F0FD79BE1EF2EB114D2E88 +:101460006D969EF1F88B5EF11EAF9B7E6E0620FCA2 +:10147000DFD607733FD26FBD82FF8E39C80FE31BE3 +:101480004A11E977F9DD0E37C9595F1FD751DFBC23 +:10149000CA3E5DA37DDF10FF4B6A047EAFDF8F4A3B +:1014A00042AF81F5024F5DBEF3F091277097C5AF53 +:1014B000E717533ED09F4F9433CA77247F7F278B03 +:1014C000F75F28DFB3B47E226EFF73E51A1D2ADEB4 +:1014D000D346375D1C46DFA72DA7EFE10AC83E04BF +:1014E000FE050D465C0BE515207CA3FB7B2DE0F78C +:1014F00063362D9FD8F4E787980DCFD7A7F8924A87 +:10150000F1FC6F697103E7874CF43DB7169F1AB47D +:10151000BE3B117F696815B86943A695EB68AA7F41 +:10152000E8BE5EFFACFC58E0A62BB3449D4DE7241B +:101530003D4B87F670BD7005179730DFA31CD3AD08 +:10154000EA9052F2277505E733F946D433BD0FF917 +:10155000EBED1A8E20F2A357CB875E5A87CE95D734 +:1015600097F36489B62FF6178CDF8D0555AB1F34C2 +:10157000FC6DFD1E03FEF07FDDF5EC49303100000F +:1015800000000000000000001F8B080000000000A9 +:10159000000BFB51CFC0F0030947B0A3F20FA0F13D +:1015A00067B2A1F2D3B850F9875950F9FE68FAD161 +:1015B000713B13030323137E35F8B0083303830C08 +:1015C00010AB00B10E33F9E680B0BE2803438104AE +:1015D00003033B90FE23CEC0E00E641702B11790C8 +:1015E000DF02C45381581C287E16484B8931303C99 +:1015F0001185E8B300B23F8B9167A7192F656E1E66 +:10160000C594611359543EAF1A03839B3A03439F19 +:101610000684AF8D24BF1428C6A70661EF976760C4 +:10162000D004F29564B19B7B0028AF0594DFA681BE +:10163000DFFECD3AA87C0733547E269A7CA30B2A82 +:101640005FC30D95AFE30EA101C062BAC4D8030019 +:1016500000000000000000001F8B080000000000D8 +:10166000000BCD7D0B7C54D599F8B98F99B933997E +:1016700099DC241398BCE02604081A7012C243C4F3 +:10168000701322468D6182687197BA23AD36A240ED +:1016900040D6C647CDE41D5E1AC4EE22B874E213EC +:1016A00094D6D462FFB4AB7402B8D2966A54ACB488 +:1016B000B5DD485D6BFD2BBFA0A2D4D2B2E7FBCE57 +:1016C000B9997B6F2601B4DD5FE3E3E6DC7B1EDFC7 +:1016D000F9CEF73EDF39718A0EA2CE23E40CFCD09E +:1016E000E71B84FE64269E84741332039E03727883 +:1016F0002A3CA3FC3D7B0696F60AA4008BFD6426DB +:10170000217984FDE43576AC16A7113296847E3AB1 +:10171000399F96076EAC217E5A7EEB8A3FC2B36337 +:101720007165F5651A21594B7A5FBD9C3E03E198BE +:10173000102926640B1109C986FE0AA3155E42DA38 +:10174000A0B339848C8966E9D16228E8B440C8BF67 +:101750002A7C20226A322DFBF0D7C43C8C27214EF4 +:10176000122FC28AC219D7F0F6F6FAC6D307ED8C4B +:101770003AF9F0FF3504E677B676642D1B2F4AFF61 +:101780003943F19293181FFBC9AA379509E0C7FAAC +:101790005D1FC2FBEAFF93F1B249A95B2BA3F3AD36 +:1017A00011D518D427BD69322D076E93495CA0DF8F +:1017B000CBBA058776F675E920A4BAD78BF815EA77 +:1017C0007C09F8AE2502CE67DC5DEFF474060839BB +:1017D000B9D41B42FA5009C9481F3E9F6F371112F6 +:1017E0007799CA8B2B85088E17FA69216D1F5D2C9E +:1017F000861E07786A16A5C17BA3DE37F938C3E9D0 +:10180000836832C5A3CCE943AE1175F7B42F4F1FDF +:10181000F217A48FCCB5A676E4FCD70BF13EE3DC3F +:10182000E9E3CB8E67ACEB70BE6A4638C6DD55E89F +:101830002674FD1FA85E941A49526FE4752D457EEB +:101840000FD4103D96A4DD3A584F9C67D4226FF018 +:1018500049D7471A5ADEDB2DEB258D9DB9A46714B5 +:101860007C4801EB7C8D7E9D8D92F64E062DCAAA9A +:1018700008FDC9BCBF0E75599400DD026D537C484C +:10188000DD257142F9830449E8710E8148CB4E553C +:101890008FAD17A014C37531E0530A45CB788E5C29 +:1018A0008F653DC892A86086DFD9E844386460132C +:1018B0002EEFC228DC18DC30C4990950BEDBB2FE22 +:1018C000B297C4DD54AEAE2B2C25E67530E854102B +:1018D0000C3ABDFBDCE48A7DBCC55638CFB99D57B8 +:1018E000D6DE35DA148CD64E26EF1A78A2C87B1DC8 +:1018F0007E31AD7BA783EC152E22A435B7230A6F6A +:101900003BE17F17237D82D0229DB9A52AD013D930 +:1019100029C800A7DB208F603AD6EB211AD2535496 +:10192000B883403DC91B463C19DF47868BD35D54C5 +:10193000EF2BA4FD5ECDBBBD9AEB3352E67867C0BA +:1019400080BB00E79128D3797C7827FD1FA58F689D +:1019500089107B5C18FEBD06F421954735F0DE2426 +:101960004F5C82559ED5F06F079E7B73D2744A8F71 +:10197000FD218980B86A79CEA557D1FE5FBD548814 +:10198000B9040E2FAD5FCBE13CAC67E4017DF657A7 +:10199000B9907E6B2FFF2C00E47B7CEFEB72327EE4 +:1019A000AD9DEB48C041FF5B659E1FFD6F0C8C81B8 +:1019B0007C59857464C0B5A2544238FAE70A3118DC +:1019C000E7E06FFF70DF2514CEC36542C8A521BCD8 +:1019D0003E42C7EBD73F0E8C26278831BE4654C007 +:1019E000A77DFCA1F550424B802FEB55A7B69E8EEC +:1019F00077AB143A047A8C8C65FAA15E9D5405EBA2 +:101A000023098C3EE60B59D8AED5DB3206D75D5A9A +:101A10009A545ED55345A196C2F78D93468533E619 +:101A2000181C30D175E35BF9F71D34C13955F00549 +:101A3000DE4DA1BFCC22B3609D3FF22E4A8D939123 +:101A4000FB7BBF4969961D847CD6A4DD77D031FC31 +:101A5000FBAD1269E82D1EFEFE4A41E1F8883AC14D +:101A60003E33E63D344F6F00E9FB5610BF94D46F10 +:101A7000DDE96E96CDF2C7368F21FC7EC1764A60D5 +:101A80004D345B037E8B2C14A01F99FE3333C18F22 +:101A9000B7EEAE637C6783B73DF0B781F76C7CFC33 +:101AA00091B7A503ECD55607A397B64C31D442861F +:101AB000D38BB11E061ECF753D360A6EE40F838EA2 +:101AC000EAC5A5A3AEFBD9E8E80EA0A30BFFFE7400 +:101AD000B405E868C63F241D6DFD47A4A344F97210 +:101AE000B41716F2BEFA067EFF20C8E75FEA12CAF4 +:101AF000BD5FCE65F2FF97112617FB4964D30CD06A +:101B00000747249453FD7AAB0FE1A52631CC03FDA2 +:101B10002E4A7FAF83BD3499CAF526059F74F679A6 +:101B20008BE8F7572FFB2C17F4D7AB746DC1FE264B +:101B30006450D769FB5786CAD40087B29B95079B30 +:101B40004F45C13EEF1758F927CDA7F4288EB7B1FE +:101B5000E3728ACF85F02B8563F15C418F25A18BE1 +:101B60009F094E86972A62D1AB745D7E26507A51CA +:101B7000C2ABD1AE26244CD03F2CA47682C9BE681D +:101B800004050672B9CA85FACFDEFF2BDC2EB4DB62 +:101B9000718BE79638405FB8C227E401FA5C1816EB +:101BA000B00CF8574D708BBAA0831E08CF753D025C +:101BB000FA2F2C13879A845F17EA2E8BDD7582EB40 +:101BC000318A9725CC6F51F3EAA626EA9F30F4AF0D +:101BD0006D3E23D185310FA37CCDDC13073360DE4E +:101BE000D54268223454D4BC1B7CE6FE530CFBC6A1 +:101BF0000778FBE5926B52191D4450AF1AF4F4D3E9 +:101C0000B7BFE180F993C51948978B6B248B3DB919 +:101C1000A82AC552BE6EEE35A3DAE12462C28389DA +:101C2000EEFD3904E994FC37B553289D462B072374 +:101C300068B71C13B4565A4E2D6F1C0FFDDE2DA62F +:101C4000637DA1BC71F200DA5B0B90FE53789FA913 +:101C5000CE863F14805C9D28924734B04747F70BEF +:101C6000DA399D1B6547201215E87A6A51B5541A76 +:101C700005DF315DAC4EE6374C10D9BAB54717A930 +:101C80008500D041ABDC48AB6A40FBCFA84FE97878 +:101C9000829809E346F1FD101D77D179D1761E6651 +:101CA0008B90D40B16A59251E6D1665B7F2AFEF588 +:101CB0006472F6560E1FD9CBFA3764526A3AED3F7A +:101CC000497DE3D9C9FB3F1512493FC0298715E477 +:101CD00087A24A62EE87E8255876F2A22B1856F2C0 +:101CE000293E5DC5224C83B4173FA2CB1AE0218A5E +:101CF000EBBD81AE6DAE892F37FC45423FFF56B13B +:101D0000A019E4C686BE5B8846F1E109C60896A71D +:101D1000DEAC009E365027AB1FC6977B09C0919260 +:101D20004B7FA7E3A4A824A6D1FE64AD372ED2B280 +:101D30005C4D423AFDE453438287CA89FDC1826605 +:101D400099BE6F5B4A503E12901E26FA690BBEA6E2 +:101D50004B403F4B4808006E0B2CC37976142FEB99 +:101D6000CAA7EF4FD6C8183F20A729BC865F4FFDF2 +:101D70000C4F11D161BC0D5924E6453B5847FC3A44 +:101D800055B67EDAD642129F4EBFA7CDEC83F1A3A3 +:101D9000DF228C2F09936B32972744A6F407E33791 +:101DA000AAA1F549E84F21915BC419A67556C3E86D +:101DB000C7DAF196EA2457027EDB4A281F24917B7A +:101DC000778822D2412CB46861419271EE16359425 +:101DD0004F46593BE544F847AA9FA82793780674D5 +:101DE000AD0B8017120EE0FCD2C9D08F0EE50C3E71 +:101DF000DF31A401EB056777F701BF65EBBD158007 +:101E00008B6FFBAE7B15D78D3CAC821D4BA12D3C5F +:101E100093919017A073607E1F8544F43B7C625CB5 +:101E2000D569073E777F109D5F8D605C2E159A50B7 +:101E300080D737296D6097F8494880EFBE901C35F0 +:101E4000DBF5A984962DF11472A4702661221FBFC0 +:101E5000AB7DC03A6A51C34500CC16BFFE5FE03788 +:101E60006DF445D00FFBCCED9F06837DD3E37F045B +:101E70009E9FB9C7C5D03F0B317F4BA1FF80BC4BA4 +:101E80009D2D5BFC9B34DD5ACEB0F9610B242FCE27 +:101E900033ED6AC2FD2BBD66E298045C14A23AA041 +:101EA00097CD553201FFDFEB65F018F06548F7CCB0 +:101EB00042FD18928F011C142D08C749723A0E4B2F +:101EC000EC2F22183FA5701DB3C175CC06D7313356 +:101ED0005C8D0A9BAFDD5E8C5692A2060ADC0B225B +:101EE000F73FA8DD0476E349F2815E0D8413BE124C +:101EF000F5AC5F656DBC4A3F062B54A2221DD8EDA0 +:101F000046BA4E1F59FCAFD9BCAC1101E641E1B451 +:101F10007E27B9482F5896C8505C78D96C035FDA91 +:101F2000577E43F9EF96430E02FC45F95882EF0EB7 +:101F3000FEF5161E1F5E06FE35C5DFD749D80FF029 +:101F40007D48448C437D485EF34F37C9C9E322B7CF +:101F50004F6089CD7C4C424190E3B2B7A35FF2233E +:101F60001A0C7A13CEE03A86989CF732BA8B12A5F7 +:101F700019F56117F33F8D78EA4DDD567FF81B5B4D +:101F8000ADE59BC9A231102FBDF9410789D17E6F04 +:101F900031FBF7749DDE105584EF1BA4A103EC9276 +:101FA0004E07B33796A94486F8E78AFFF71F336FC9 +:101FB000A4F33909F26006D8EF147C931E591E88E9 +:101FC00039F5E2E1F36B1542B5970823CFAFD3D1D2 +:101FD0005F0BFE77749303ED4C628F83EE91300EAE +:101FE0006A6A87F07EADCB3ABFB3CDDF3E5F421E5B +:101FF000C0F92EDF7923DAE723CDC7B933B9BDE9BC +:1020000095044BDCC7E06B83DEEDFC5D26692CAEEE +:1020100043D520DA2BBF4B89B5E2FA36CC82F53DA9 +:102020005BFB8BA17DE6176F5FFE25C79F7F96F652 +:102030002B94C105B0DEEB02DD61E04F238EB5923B +:1020400044F51CFAABE3F9D55130DD86EA05CFB192 +:102050005E2EAD279D43BDC2D1FB3BCEED92977660 +:102060003FEA043BF5C3A7DEAE053BE0D6FF94880C +:1020700042E9E1F86E1F89A3BD1273827DB39CD241 +:102080005D0CCBF199D798EC614AD1B80EB73EE31D +:10209000433B62F9B3AE580D6DBFFC87BF9F462826 +:1020A0001E8EB70CFE570ED0F353028BBB4607A60D +:1020B0005D43DF2F97C9BF8493D0D18D12E3A70F63 +:1020C0007E94B204EC446167DF0DD86FEF571C2E8D +:1020D000933E5E2239705C5A0FFD88E82E213651FE +:1020E00060F099FD0123DEFDC12E81C1B7D71173C8 +:1020F000037C3B7B9C115A6FD5CE1348D7F39FF9D5 +:10210000AE1FF0B06AAFD54E5FB5538ABBA6E1F300 +:102110006D7882061566023E193FAFDCB302F5C644 +:10212000CADE0D27809F57ED7558E43FC54B280E3A +:10213000787D530AD540F9074FFA358AAAF7FB1F75 +:10214000F7035E69BF373A295D2D9C6D6D07FD9FD2 +:102150004A1FDE1FF50CD16F5ED5BB8E8DB7E7EA47 +:102160003F80BC5D45989E32F8F97DF8256BB89E9E +:10217000592759E35B27C9E199B80FB83323A9FF61 +:102180006CE81583AF6FFDEEC91D513AFE07CFFE17 +:10219000FF1D513A8FDBFEFAF18EBBE9FCC83EB75A +:1021A0000AF26AD5536FF88909FF8F496C3FE0F84E +:1021B000AE279FD846F9E4F8AF5C68071E7FE10FB1 +:1021C000E3343AFFE3DFFFD318B053D7BE70D958DA +:1021D000C0C7DAE7E68F1DCD5E07BA8DB9CCEB1B21 +:1021E000C3FEB5BD026C8210F23C7FDAD6E9C01E98 +:1021F000290E21820F8FBA622E8A9F55F45D6329C2 +:10220000ACDB0AD45750BE87E27BE5EECE13D2B4E6 +:1022100064788FE6884178C6734810D6FD9A859712 +:1022200096C1D311D2804EC820EA097BBB5547E83E +:10223000FA5E34F27A527BC209F85FB57B1D1BB798 +:1022400097AEA77FF87A7E08BF5C3C7C3D0F48D6EE +:1022500038D34972DB77B6C1C73D19B8FE23ADE765 +:102260008AE7AE1DD5BF33E4C3D9F05C2F30B8EE9A +:1022700097F4D725E0C7679F7E625B80AD730D45FD +:10228000CCF1EF9E1C079BBCEF39066F003939F883 +:10229000824B05BB7AF90B6F22DF1D7FEE55A786B7 +:1022A000FBD3C42B503D799C0CFDF483DE5C29B03C +:1022B000C2AAC77C71973FB15E2B6375D59A1FDFA9 +:1022C000BF8DEF638C1F56C6FA160B49D6CF2B175E +:1022D00030FD14CB44BCACD0FA9DAAD7BAAEC26CC8 +:1022E00058CFB71700FD8DB49EC6FC5598FF2CD370 +:1022F000BA3EC6F878247E3DDEE39285D4E1EB7CDD +:102300009CDB15AB62C29BC9D69D901616DF1B21C4 +:10231000EE6D3CED74E194AD7C6EB437E67F363EF5 +:102320003FFBBCCE0F6F27B9BEB6E3EF83D3C9F531 +:1023300040812C70BDD55D9D6DD2776E07D563F958 +:102340006077364473F213F076F44A28DF3FD829D9 +:10235000A1BD6F97132B47F0EB43C6387BFBA681DB +:102360003CFB60FF8F383D327A5FB9FB6D6794EBC1 +:102370008598592F407F49D6630EEF6FD5F3C9FB7F +:102380005BB5FB44D2FEDE97F5AF00FCEFF73B48B0 +:102390009476F17EAF94344E52283B2C7656876F5C +:1023A000E6D154DA4EF27B3498776B8BFE6614ECF0 +:1023B00091D71C04ED4739F49E8B7E6FF57970BF81 +:1023C000A5D57F33D14CFABBCD86273918463F5A65 +:1023D0000E84CBD85E68CCE2CF3A54D1023791A3B9 +:1023E000B9B0CFF972FE1F64E817E2699A292EF49A +:1023F0008A4CDA219EF68A2E849A4992B896ADFFCD +:10240000F05C8968663AD3C78BE6F8A27FFF9D1817 +:10241000D768240D718837915CD2FBB8A9DF879B00 +:102420003416770D8F17CDF13F574383EEA270E43A +:10243000AE550BC07F1B69FCBC06EBBEAF31FE1A6C +:102440001E8F203B9F7AEA295A1E0FDF44A0C3B09B +:102450008E709C66FBCAF3B93C7C89DBCFFB0572AE +:1024600010ECB0EA7B2232C83B217823C64517E442 +:10247000DE282F33D1E382E0892CD0ABDFF98BB497 +:1024800024199DEEE574D5FCAD27B2A0FD36F757B3 +:102490007299331B46F87278BCEB60E6E55E88EF14 +:1024A000F5DDB2E0F0243ADF6C552210AFC92615F5 +:1024B000DE120A67CE1129E44EB20EC673078FEB07 +:1024C0003DD2A4A2FC7FAC2988E527385E7736157B +:1024D000E1F3A9A6107EDFDD341BCBBD4DD5F87C22 +:1024E000B6298CEFFD77FDB8CF0978B997F442BCD7 +:1024F000664FD312FCFEC3A6083E1FE7F3590078CF +:10250000F15AE68FF198BD6DF35A201E63E0D18E2B +:10251000F779247AD085FBF9820678BF5366F2C535 +:102520008EDF71AE5E01E44BE36D04EDD71D3C6EB2 +:102530006CCCF72199D99B7B383C3F7447BE27C3AD +:102540007E53756131DA45241C02F9BD4308A79614 +:10255000D02A2F66CE0A9AE570B62FB24736ED2BF9 +:102560008CEB62F19E6D329357E3B5137D69140FC6 +:10257000D5B98206E10463BEFB2BB45C9093FB05E6 +:1025800001D7BB3A57224526BA37FAFB0F59E4FB6D +:102590001BC9E576828E993C48BF422E02BFF624C5 +:1025A000F18424CAEFFBB2C81E42ED8F7D40972014 +:1025B000177E9B827162C3BFD9C8D73B1D8802F2C8 +:1025C00025DEF2C540FE8CE4F774F0FA1F71B856B0 +:1025D000C8E1D765DC57E6F15712C73826A41C01BD +:1025E0003D6E732FBDBF8A3EEF9BF3FE51880F7E79 +:1025F000F89C5B03B836951DF39BF148EAE50FCCD8 +:10260000FBF143F2E6540EC6C5FE8744DE96CD725A +:102610002830E884F6FB046D33EC5F47DF9090FFD1 +:10262000F609B12918C79209FA05FB6E09627E877F +:10263000D1CE17B2F277BA7B60FB2A9877BD3314FC +:102640004DC217BF4ED12CFB46AEA0B57D1074E62F +:102650000C56D6287D96F07987645D02386690081E +:102660003E67110D9F598EC8E7308FE9A4370BCA1A +:102670002D29E32E61FB077F37BC298E7F40BC19D3 +:10268000F41A9C53847090BBC4D0440DBD490B9D7B +:102690002F74081CBF0ACAF3ECA1FDA98697F202A9 +:1026A000D80D8B93A8292807B3DD0C7F8D03273025 +:1026B000BE1B1C472C71F7F67A11F960DB5B6C5F6F +:1026C000EF647DC1E649B47E05D1EEAFCA1F3E0F6F +:1026D000833FB629E1D464FB53C6D3E00BA3BC7996 +:1026E000FC0D04E4D0BF8FBF01F38EB2DF726BE04C +:1026F0007754FC6E5733C8C5F6B7597EC5514F6441 +:10270000AE634642CEB4DFD2301EFC20B72F5C0E43 +:10271000EFC3B9B1EB41DE9DAC5EEBC2A97B59DEE4 +:102720004BE33DDAE6C9DAC8EBB3A371F4FD1B63F2 +:102730005E3B605EA3EC5F18F332D6EB64F5E2C15A +:102740009B35903385A99124ED86E4C9158B471DEF +:102750007F07D72B74FE4BCDF439AE51C5FC16A3C1 +:10276000BD315F7B7BFB7C13FBC0E79617D4EB206E +:102770001940EFDFFFF3B81FBC82A2312C819EA667 +:10278000FCB912E099491AB04CE4DE2CB06F0C7A17 +:10279000DED6F14416EA0539968FF95DE7385E3BDF +:1027A00009872B80DF4262C86CAF18CFD6213A8FE1 +:1027B000635CD5C5E58098724F30199E87FACFB516 +:1027C000F2FF4642989C8F2B28E72150A8D272FE38 +:1027D0002152BA9EF6570F49A1749C0A99C543A687 +:1027E0001FD27A24165795EA7C263CF2FD0623BEBA +:1027F000DB4EEE21AA067E45491F5437F8F480339C +:10280000F2A003F2F0821AE67B3A021181EDC7B121 +:10281000FDA1226E975C262D55C02E692461E5022C +:10282000E0DB23126179788CAF5DC63E18E7631751 +:10283000E763CAC1589EC4BF3FCFE96B2FD8276852 +:102840004F303ADAC3ED93AAC1C1033EDAAEA8BF56 +:10285000BB12A6F32CD82B2EB04F42F8FD7B60AFF5 +:10286000D0F281B47FBFF2028A979DBA18025CEF62 +:102870006ED2193F34D5E3F74612F5AC06B9F4B081 +:10288000A8029C9D0FB7487E5ADEA50818BF78B8ED +:10289000A901EBFB4F7BE2E06FEE52E202D8232767 +:1028A00043241405B8A97B04F39AC4E751F14E3FC1 +:1028B0006E973F11FBE8F7F7D37A5B667B709FCC8E +:1028C000E0AF498D83EA95C0578F1FD35603FC3381 +:1028D000D6E8507F63A800F7299EA4F88275DAB97C +:1028E000F5A3ADFDF4BB5FEE5C0D7EF0E4BC456886 +:1028F0000FF9957FBF1DCA7EF5E97FC5A7F2A36FCB +:1029000082BE9E1C132DFBE77EE5E777C2F7CA81E6 +:1029100050552AED67CA91FEAE2BE8B33DB456047C +:10292000124F4DFF23EE6BEC17D4AF77435CED46AF +:1029300027D2AB7E546F0676749459F320330F4739 +:10294000206D818C3D48F14E00EFBA0CFDBEE7C80A +:10295000473A0BFAB3AAFCB4FCC463C77E7A05FD00 +:102960007E60EB1A948BAE8765B4C726FFC75AF218 +:102970000D939C703D2627CD2B7DCFE1627CF4F03A +:10298000E2EE291A234FE0BF298F572928270E5B33 +:10299000F31C8C7DE11E1279CF81F4CCEC135965C8 +:1029A000FBC8B0E705FB8964BBC8F8241CF198F3A9 +:1029B0009F8B1E12C3C9E2DCA71C32CEAB2D56552D +:1029C00004EB209FB903F7C948B7757C633C3AFE16 +:1029D00029B37C935506571EA87EBA9E7DCEDF6430 +:1029E00001FCA71A0C3D15473D75B0448C8FA7F02C +:1029F0003DF0A01883A4CC03D54C6F6D9259BEE076 +:102A0000265E7EEC348909F9093E9ACCF9EDB1874E +:102A10004566CFC508EA3972FA0CDA175EFE3DBD8D +:102A2000E43505F727A2BAB762266605F21F13BD83 +:102A3000501C5D14F558E4ACD8986E59FF3C6AB14F +:102A400058F3A90B12F52590E34714A0DF93D46F38 +:102A500005FA9DC7F789AA8C3C4CE9F47498FF7677 +:102A600043CF1A7933B63CE9C71B9679205EF8A2AA +:102A7000413FF50D3AFA3FAA0BC733F6098B6E0BAF +:102A800047417F3A72ADF9D315B6FCE879B6F2F951 +:102A9000C6574A9DF638EAC62948079A1FE55521C8 +:102AA000C7F3E31753773E75789C65A85F1E4720F0 +:102AB000DD7E5CBF424E40F7DD25D5835FE07FA021 +:102AC00034CD9C5F70B993D9DD077FEB2260E7EFCF +:102AD000AA52309E69E4753AF8B8B54E0DEBED7A1E +:102AE000F00E05DA77060ADC80AF0373967B30FFC1 +:102AF00083E7A71A72B765CEF22B6F01799829A2E6 +:102B0000EE69CF6DC9867DF907AA14CC3FF5A70CF5 +:102B1000F41EA065EF93CED023F4FBAE8AF81273B7 +:102B2000DCE60E27D35FD73BF93ED0466BFE06E5C9 +:102B300083EB9D901FE66DC07D4B51E179BC36FF64 +:102B4000DEC0877FFFF562BE8F3D0B7CE08F32FADF +:102B50008871FAD8C1FDD38741FEBB806E98FCDF37 +:102B6000C8FD537BBF13EBC3FB9D6087DDA6964278 +:102B700028CABEBE13BAACF6447ED42AE7C6DBE947 +:102B8000BE21DB523FA7BEC0F2DD17BAC0669FC4AC +:102B9000995E236C7D3ADDDE0920B74BA9DE6576B0 +:102BA000862A86CDFB2A36BD5EEFD09B9CE761DF8F +:102BB000F853C20DB03E767B7A035F9FAFCAFA3AF4 +:102BC000E70CF4DF36C093DAC73C5FDD6A7F0C8325 +:102BD000935038A78E0AE783E703E7D9F6D9ECFBD1 +:102BE0006BDF94C25B5FA1CFF254960FD9EE63FE08 +:102BF0007C3BC45169F9C79C0E9F764AD8FF5E3E64 +:102C0000DFF2145A3F097F1BF1D5E721F106EA8D67 +:102C10004D9E670916107ECF49FEFD7927DBCF2E2A +:102C20001F3FFA38FB601CFADCE8D07FE434C5F1C2 +:102C3000DA9CFA7F9ACB7127DB7F1E5A179E476971 +:102C4000D8637738F43E73FDC4D32A378D7D904C1A +:102C5000BE9E3EC2F8EFC525CBD64DA4FCECCCF50C +:102C6000A2FD93B9A46DB5E887FCA37E15FC814C49 +:102C7000BE8F4F1633396AECABA7D758E5AAFDBC17 +:102C8000958BE7C5BBECE76CB87CB5D3E348F2F5B0 +:102C9000774EEBBEC650FC7A04BAB2C7AF1BE15701 +:102CA0006667723B389CBA68EAC8F4F872D3E0A64B +:102CB000831313E557E0FC4C523A60FB89FEFD7F1D +:102CC000AC595C06FB762C9ED6DF142F7F676242E0 +:102CD0007E85E7A6BD0871CF70551ACA9BDAE0A7BA +:102CE0009B0E527FBC4EEF2B7FC734CF7E95423B6D +:102CF00061143ED11D9F9BF9EB4981D14F3B1FEFE2 +:102D00007E8E4FBB1DDD29465DD0EF2764401792B4 +:102D1000F8B5E679B721DE06BC406723CD3BE46217 +:102D20007CE59FDD1082389DEB8C847CE01A6FD8A7 +:102D30002D21B45BA6BBD2D8B90F6F01EEE3513F92 +:102D40007DB00FD6C1CBF2FB0DFDF8B1114FE57A86 +:102D5000EFF63456DED0C4E2C7AE0317BFA9D17672 +:102D6000BEC30EE2A6EFD751B90E71C02E6AC7C31B +:102D7000777FD90081387A2BAD1F31F9DDADA14ABB +:102D800015EC84B6E25245A3DFA5A9655896F34B2E +:102D9000D54A3AE605AE6FCFCF843878A18879B5A9 +:102DA000C5B4DC4C4DBA54978AF37BB9E81D2FD8D3 +:102DB00067A9E09CCF48ACA7A32CA24B141E475098 +:102DC000AD845C8C21BDCDE98CBE7F04E2254F0A29 +:102DD00091992E3AFF97F9F9AB4E6743D11AF07BE0 +:102DE000E4A80BE2078D0ADB87007A689B9E807B54 +:102DF0001EC7AF938F3BE407F1F5FC441E88426A7F +:102E00006BA748EA93ADCF152E26E7DA545D1D95E2 +:102E10009E54F9734BFEF45CC64FCE00A5A724F177 +:102E200047BBBC26AE709D2B3391AF441756453E31 +:102E300025CCDE33CEF7BCE3D4AF75D1797CCBCBD8 +:102E4000E5586E3AD2297D5FE9F942729FC567F66F +:102E5000CF2D7BB50AFC927E07C68BFC13C8BF84BE +:102E60004DF2F6900B836EF4C9ECA4F5943E629398 +:102E7000595C8200DDA450450CFB907962EC917C9A +:102E800080B7A77A02EDAF539E482DF3443F1579E2 +:102E9000CCFEDF54E9A937FB01EFA5B0FD97B5DE05 +:102EA0008A67010FC5DE5825BACF909D39869D9F50 +:102EB000023ABE502503820872304C98DE0C294C31 +:102EC000BF56A9705E4A201172266534FD683D57D1 +:102ED000F5941C6BF1003E022CDEE5DB2A6032A08B +:102EE000D4ABC73DB44EA977519B8BE98B2218A771 +:102EF0006FA6877869FD4FFB9C681FF6FA7264C065 +:102F0000EB3E71D97720FE34F82B17E637F6FEE555 +:102F100002CCBFEFF55DB200E476AF400E51654FD5 +:102F20002A4EE5F064439202FB7CFEF93A817D8EE5 +:102F3000C1174908F2831DC19F97BF331D279E22E9 +:102F4000CEA6EDDCA4CB4DDB853EF77C3C8FD2D505 +:102F5000B3DED22D1791445CC588A754A444B603B0 +:102F60009CED637E5D0F7CD345E194D07ED58300DC +:102F70007769A688F14792E98D4D8478D9A14015EB +:102F8000E48F56C825981AEB9FCFD6FBA827F238B6 +:102F9000F453A5D655417CBDEC888672764170F518 +:102FA0004128CF7C8B95DB9D8C5F205E444C72B7B3 +:102FB000E2D4389C5F2FA793B6A0DEAF0BA3F28DAF +:102FC000EDDC81355FCE4C0790E76EA28388C34C61 +:102FD00007B3291D4C35D3812E9C0F1DDC8BCAFAFB +:102FE0008BF08FFE66959088DB0DE783D54A7AF1EA +:102FF000707E31E0585F961E00396AF0853AEB1E0C +:1030000094ABAE1B9D61F0D70D3E31F8E353B7038F +:10301000F990F2C9551EFA5CECD52E4BC627E08715 +:1030200098F9E19A11F8A6960C1E0CD046B5328993 +:10303000A65251F2F2C5EF158E33F1811D6FB573B3 +:103040000572CC22CF58D9845775E87CA374EEF86A +:103050007F4DD6DA03263EECA07E0818CB5D628851 +:10306000805E29F52EFB14E852AEF97E10FC4187F4 +:103070002B5C8F79B3B33E48B999D2E5A763440D71 +:1030800026DFAE2D7B06F9F9680A01FB64D3CCE597 +:1030900018F7FDF496C878D013EB28FE8FA15E8E4A +:1030A0008D15310773602CDB6FD782EC1909B2F7ED +:1030B000847F8FF1B2CEEB0D603DBACE16F9B8DE4B +:1030C000CDF6BBD6BB99BE59E7EC5680DF06F315AB +:1030D000D59CEF3C4F62766C89C2F79F4EB76A1061 +:1030E0001F2951989ED9D2D48BF6C7BAA6BDF8CC69 +:1030F000A88911C8A7F2144535D8F756FE3A5F7073 +:10310000001F5FC0F667E17DB3C9FECA51181CCA33 +:103110005FA508F0A7D212D5D24D7256118548325C +:103120003B7AA39BC55F941682DF95FD0FE17E7607 +:10313000466148B809CA2DDD2404F1F3387B1F2805 +:10314000D485AF9BFA0DD4F45AF45C2D5D82D45231 +:10315000B49EF0BC4BBBE6C1FDAFDA40E51FE569AC +:10316000C3E9087E8E99E8C180DFD8875DCBFDEF8B +:10317000AA0205F9AFBDD1D903AAF92A85D9459F7D +:10318000042A473D2F00FBAFD472433F179EB00F78 +:103190001B9DCCF661A10CFBB0F0847D5878C23E3B +:1031A0002C7C877D58287FAF49C732ECC74219F67F +:1031B00063A393D9FE2B9461FF159E7B9BEAF1F9E3 +:1031C000E3A606FCFE7C532396E7B9987F438AA2C8 +:1031D00041B097BBEE74EA9067D3C2D7EB805E90A4 +:1031E00011A2EBEA0EB03881FBF00378DED91D1492 +:1031F000316ED7117C807C8D3EBB66F8BA20EEA183 +:103200003CE3C5A75BDE42C01EDB2144EB4988904E +:103210005BBA4AAA646A2714065757A6D3F2AAAE25 +:10322000596D907738496B0E2D531365CD57BAFC05 +:10323000FBA6F2F8E21ED913023CCF6903790070B5 +:10324000C0A6D9BD5D73AB9A0BA9DF54400D159094 +:103250006BF9CE18D0F3D761BD2602FCCCBEBB8A79 +:10326000B40621AE315E7396021FD2FA7146FFE7B3 +:1032700056BF45D1F0BDBDDD68F5C4B273AA47A401 +:1032800051FA83EFC228FDB49356B59FC2BE0164C4 +:1032900006D8476EB6CFDBE560FCDFE566CFB7DD6D +:1032A0008C7F7FE8AEAC74D367A59BF177973B5CCE +:1032B0000DE74D06A78A18DFE975D02EE0F04163CF +:1032C000FEEB702EE88E9FC904F60F1EE27430717B +:1032D000BC8FE9E9BB15D4D3978FFF6E5B3A2D4FB6 +:1032E0007C341402BDBB81843C4027D18D22E6A1F1 +:1032F0003C5D3621BD8E56BF70C673E9A07F3E553A +:1033000098FC89717FA3B9FDE6F11097FAF4552670 +:10331000FF7672B9D3E3E86FC0F59CE1457B853A4F +:103320000C688F340765CC1F12B3D8D3E950FF095E +:10333000EA39A9C28F52789C7F99A560FCE3948BEF +:10334000DF6FD18F768AD31D51D3E8FBEEA888FCBE +:10335000DEAA7A6260576FF096E2B9D268B18CE764 +:103360004B3614B3F8698AEFBA18D827F7F7B9992A +:103370007CF02A983F1A2BDE73A832004F51057E4D +:103380008FE98BAA11EFAAA8621E2AFD0DBFD707ED +:10339000F03CCA06C2D7A55EC4F374ED633EFFF9E4 +:1033A00045909773931AE2770E609E379A5C22ECF1 +:1033B000070DEE4F0178BE6ADC5730D09242EBB772 +:1033C0002D5343B00ED3D4CA6AC82368572BD1CF2C +:1033D00049995AA5DC887268E83C06DE8BD1562CE8 +:1033E000631E117C07BE246DE4209C87CFE1B22CC4 +:1033F00025AD5400FBAABD06C37C705EC19257DEAA +:10340000967E259E43926AD311CE76A22B503F5AC8 +:1034100023A3FECBF12A71B037728C782E1CB13009 +:10342000C51B326EB39ED3C8AA972DE7C2C746AC60 +:10343000E54C1E3FC8B49DE7F85831F6C7AC78B2EA +:10344000CF3723F0481AC09B010779B5E1F3D912B1 +:1034500028AD8379E6A81E843BA8B65480FC1A4B9D +:103460001A9A81EECE1B5E1B9CD38ADBFA61DDA724 +:103470006932D1E8F81791C116E87703A7F3AE7C5B +:10348000AB3E7E48910C7EBC10F8717CA348A2A68E +:10349000F1210E19358D37A12BDD529ED89D6DA9D6 +:1034A0003F796B81E5FB94D80596EF17EE2CB59428 +:1034B000A7F6CEB1D4BF686FA5A55C12BFD2527F6C +:1034C000FAA14596F28CFE7FB2D49F757499E5FB04 +:1034D000C503CB2DDF2F796F8DA57CE9E05D96FAD2 +:1034E00086BD6ED78B13B9DD72BE76BA0BEE89B08E +:1034F000C465AD7E80DD8E57FEDAAAB5805CF33BF5 +:1035000091BE65D0E3B4BCE64EE64729E5210DE463 +:103510004A0E97A3D93EBDD40DFBA97E05F581ECDB +:1035200065F564EF02B43FC66DA5F2683A589B6436 +:10353000E87B0AC8E5A66879A129DEE456BBF16CF0 +:103540005685BF1AF7378CF6B2AA93880FC6D3D820 +:10355000F96AEAA5423DB746DB9BE6B54F14F10890 +:10356000F420F5F71E31F97B23F977767FEE5CFDC9 +:10357000B77122F1E0B90221DC00CFE286572B219E +:103580001D98FA75D701FD6E7286EB7B68BF9B0AAA +:103590003C6C1F94FB755DF9BDC81783F932EA17BF +:1035A000226BC5E6785C33D74329CAD3E85752BCAF +:1035B000A3BC35F0BE411888B582DCB9D383F27064 +:1035C000DC7FBB5E03FE520A941C85BE0F1D70EAB1 +:1035D000B0BFB485E3B5402DA984905261B06E3F71 +:1035E0003C2769D4CEA0CFA2A2CDFBE179BB9BE55D +:1035F000035F10FA7E25C812A59CD97FF23467AC10 +:1036000085F623A9148E247E85F194FC5BD9FE45B2 +:10361000A1FC2ED01B58F567E8142AD215CCF77000 +:10362000031D08F844FA7107BCA837DC70B815CA46 +:10363000B21083FD3FB04F611FAE227D2BAEBB6148 +:10364000B7823D1B617E6E33D057A0C6BADE29CA51 +:10365000F7104F6D028B7B77A569872BE9B85D99D1 +:1036600005E9106385B8489D49DEACE7FAF49F3D53 +:1036700022CF7363F2E6CFD0E78C84BD43E97FAB02 +:103680003801E0EB2620B7DCF77413A077B74A5770 +:1036900013EDFAA816467DCAECDDDB394C55054B17 +:1036A000707FFFE34029DAB7EEC67D49F1E71E904F +:1036B000883E7D64BCFA276D437D4F0A9C1AD8155D +:1036C0008D9A53EF49220FA6703F64DD38E33C2BFF +:1036D000CBEFE9E2F830E2A14371461E4F33E28CB2 +:1036E000463FB767968E1DCD1E7753FF32628277B5 +:1036F0001D1D07F0D27EBAAE1AF12013761EF72FE9 +:10370000C53DEB719F95F9495338BE4B387EC7399B +:1037100009FA09F3216E92015EED55D5C097469CDA +:10372000E537606CD17AA12891585CCD61E82DF124 +:10373000CC4508B3E634F2C3D0E4657A8DFEDB07EE +:10374000E7C6267459CF654EECB696276FB596A797 +:10375000C4AC656A351F01BB006C348C5BECB47E75 +:10376000AF33F603AAD83932858E7C86E95FCBBDAC +:103770003884EB7F238F2DAF375E01E23577AD556F +:10378000AF66733D9F6DD39FA53E09E30915870280 +:1037900007C17E34E23E473D9A259FCC88DFD8E5BD +:1037A000B9E7ADCD847E41BF3CE262710C880F7FEA +:1037B00096C7E325B93C5E328EC74BF258BCC42194 +:1037C00069AF2C1530FFF3B81B8D97868B589C86FC +:1037D0009DE7FAA85A7E51D0D87811D378DF2C8A89 +:1037E0005ECED010CB827A46DCC4880BB87D7A25B9 +:1037F000F0EF86D06B0D07289D54FECA45A09FCBE5 +:10380000A4C3879A40BEE5C998B7ADCEBAED3B1EBA +:103810008843C2775AAECCD7C6221FFCD481F1812F +:103820004E4ED7C6394423CE92E2617691CB63D80F +:1038300047510FCFCBF780BD7BE14E2AA32DFA8EE7 +:10384000C5F38CB8DDD45EEBF75E2264A8B0EFBFA1 +:10385000242632FB4AF75698F21A2FE0EB366D69B0 +:10386000FC81A5B4BC9BC44AE1BEB9124E1FA18322 +:10387000D6F3AF638880E79FC61C9142315A7FDA46 +:10388000F3D6EFC5B6F3B117D8CFCBDAF6857C12F5 +:103890003971231D6FA3D620801CDDB894DAF2B4F1 +:1038A0005CE8E1FB4593C824A0C3CB246F280EF845 +:1038B0007D43C2FD2DD7DB93DFBC11F4FAAB2CEFB7 +:1038C000489DA06D8638B2FA7309F5949A424A4A27 +:1038D000BC897DA47F3B1322B02F62C4B59EA2EBAE +:1038E0000A7A6537F5CB0B1DE067AB58EEA57E393C +:1038F000949FA57E393CF750BF1CDEFF90FAE5503F +:10390000DE4BFD7278FE98FAE5F0FE79EA9743798E +:10391000ADB7A212E262FDB43ED08BA7648F3281B4 +:10392000C2DBA93854A00FBB1CAAA8B85D594C49EA +:10393000EA2B9D4FE3FE45E5652C4FBA72FDD3B8E7 +:103940007F618EAF99E38F89F8DA8060C4D720E475 +:10395000F93BBECF3014678BB038DBD9FBD18D7EFD +:1039600030AE39AC1F1EDFFCF0CE5F3FD14A3FAD19 +:1039700098F14097A700CE6D34F0789E9117A35927 +:10398000F2EE57EC69C6BC1867D6910658D73D656C +:103990005ECC17713A222AC85BBB3F67F871767B11 +:1039A000DA78DAF59B8FDB1546DC749383609E74BE +:1039B00054A0F604D8174DB1F2771C23C7535FF714 +:1039C000F0F34336B930743E80C77D5C60CDD27968 +:1039D0003A058E0F9EB78EA2B180C5F5CC71554FBA +:1039E000610C0FA57BBC3ADA7502B5F7D0FE532304 +:1039F0004188A375C0798024F38B7998FE6BCE72D1 +:103A0000A2BDD191C5F240AA72434168DF9A353315 +:103A1000683E1F609C5F38E89BA90C98FA5BE32B1B +:103A20001855FF49545F6BA3E86BC9C5CEEFB4EEE0 +:103A3000BF588173195DDE65FDE047770503187F88 +:103A4000EFCB9A49064CFD4BC1D9787E43F2327BCD +:103A5000580A2A680FCB30FFE2447DA3DE3D1E46A4 +:103A600027949D31BEE8F676633D971CC67B235CA8 +:103A7000015099F4A9B2FD384FA1481493BC30C647 +:103A8000FD570F93975DC51115E22C5D4159837366 +:103A9000205D5A29E2B995E3B935CFB0274268C70E +:103AA000ECE17836FA69E57180D67A27DA73E1C6F7 +:103AB00034B52A03F37577C1BE5697B745817D4962 +:103AC0006756D9A8FDFE84CBEB91FB2D1953351D0C +:103AD000FBDD03FD3A7DCB54E8D731C2B9A3C31C4B +:103AE000CE2F6AB7DAF7F128B441733E8AFDE9E3D5 +:103AF000F6A7BDDD8AE20127ACFBBAC7ACE7941D8F +:103B0000849DDB5AB97735F2F926B91FEDA84DA788 +:103B100085A4E7BF325204CE6F43FEBDC50ECAE195 +:103B2000FC94C3BF03A981BE28895BED96E987ACED +:103B3000E519FDD6F2ACA3763B487F03ECA0C55C4B +:103B4000EEF55379CF92610665C047381AAB00B8DD +:103B5000EB486F33E44938789C7C31D77F0BB97ED2 +:103B600074A7B0786F4EBDC7E27F127ECF5F2EEF95 +:103B70003FAFEAE0EA3610B261C3AED2D06FCDBB40 +:103B8000E2D90A149736FBAA4EB79EE35F68B39F4B +:103B9000EC765685DC83F9B8D9B6B886B19F0BF3BD +:103BA00084FB0CECE39FEFB8467F908705F2CDB81D +:103BB000E705EF15A6EDF3E4B810A278CA6E60E74A +:103BC0007072D612BD27091DCF49617C310C6FD1AF +:103BD0007988B7F9FC5DB697DDCF955D25C5343A98 +:103BE0007E767D2FDA038B6EA3F3413BFC0CE6C19E +:103BF00018F5D3D37AF13CD2B61A81E7E712B46B49 +:103C00008C75DEE665E707EB2E156222B46F28C0DF +:103C1000F111AE82C4FA523C1D637862F986D75422 +:103C20005BCF39D6D9EC17831E16DADEFFD6C3F682 +:103C3000C50D3EF8F0E2A393C651385608DDD529EC +:103C400013CE5D5F9AF8C37106F8107E1FC3525FF2 +:103C5000308F57F9818AE73DD206B6134A92B529CB +:103C6000245A3517E4CFE085022D5F9BF2BDF6AEF6 +:103C70004BE1F8F6E0D360E4B95C3FB8AC3A2F51C1 +:103C8000F6787E82E5001F07B616D97A9BEE7DA1F5 +:103C9000A8DBCEF3E337E864B304B9B5A2BA39942C +:103CA0009F68970EED8451DA85C96639493BAFD1DB +:103CB0008EA2AB03EE75E2F3F2F0EF2287C73CBEB3 +:103CC0000C7853352F9E635C20AB9097F165E1181B +:103CD00073B67947C866C784E1ED28D8CD06FC6283 +:103CE00072F863F0DD3CBE6314F8FFD6F8385B7FF2 +:103CF0004EFEFDBCE1A3D55BC68C3C5F80CB81F75B +:103D00000D695ED1D4CFFD7D7FC2B8B87C3D09413D +:103D1000C84B76E82AECE715AB0FA27F2FA755A971 +:103D20006007ACA365B003D6F57663FCBBB8F08141 +:103D30002E20FAE2B887803C984AD4B4DDB4DFA9DB +:103D4000AA0C27AB887CE94111E2E9E46A82792375 +:103D5000A97D1E763F50FE9C47C1DF4A4B53703F02 +:103D600023256DE6A3CCE865716603FE948A23954E +:103D7000107F97EB484800B88418A900269B427032 +:103D80007FC3A3EFF9269C032032D34F78470EE878 +:103D9000551E6F1FCB48867439D53ACC5FF9998C84 +:103DA00071ACB170051825CAE2E2F4CD004F718400 +:103DB000762000FC2C5E36352286E2B4FFD213ACAE +:103DC0001DF9053B3F427D9325CF79137835E4CA31 +:103DD000581E870F2EB5C6A9C9209D336D5FFA8B7B +:103DE000458F439C62CC30F9CDFC760F8733F504C8 +:103DF0000943FF811AABDEF0F0FC6D8FEDFE988B6E +:103E00007C0EEBBDCF76FFE1DE30EA011709294ECB +:103E1000B42F96A2DD60F825DBA022D8E37984DDFB +:103E2000B76B6F3F93B52741E6A7B83C44514AE9C9 +:103E3000F7E51E1DF30D5DB44CF12838899245DF7E +:103E4000678B2CDED22C1019CA89F1E29867E052F8 +:103E5000AE6A03FB65BF321DEF4533FCEA5635847D +:103E60007910A4A8D262371BF95E6B4A0AC6C2F762 +:103E7000D43143712715E8724D6621DAD1FE8C8169 +:103E80007F0639FB598A6F81027215F230E6C0B5A0 +:103E9000B4AE8E2895BBAE53394433D9672EB901E1 +:103EA000E36CAE53E32CEFE34DD673D4BA57AC8238 +:103EB00071B2BD1A3BBF43D436685741ACE7A55D2C +:103EC000A7B22CF67AA2FF5CCBFB38B56BCCF7FB24 +:103ED0008CDC7F0AD18ACCFD4F18A1FF49B6FED5F4 +:103EE000A4FD27FACDB0F4DB2EB3F86B34E0497AA9 +:103EF000DF64A9B772BC77C6C8FB03255E16D7EC92 +:103F00000C36E0FE4025A18C4FE965DEE963123BEB +:103F1000C74BD07E23B9D6FD814A4EC722A50C3CA3 +:103F200017205BEF2D2E27F67B8CAD76D111086E16 +:103F3000517A177D65FDB84FF0272F9EF31BC96E90 +:103F4000EE6F22189F2E4F19B81DF6C1AFF48E7375 +:103F5000B607319F19FDF925DEE90BF8BD9F2CAF9F +:103F60003920225EC29563F19C96D14FD8492682B2 +:103F70005C0C8B2C0F027FE8F8FD99D98FAC4F8237 +:103F80003FFB39F73A5D282F34CDAB1FF20ACDE362 +:103F9000CDCFE9914CF308BBC80C1C8FDBBB43E3CE +:103FA0008DF962E3BDCAE359C678750BACF3AB7308 +:103FB000AA38BF3ACEC7C678AFC2FC92E0F7ACE3EE +:103FC000F1BCC9A1F12EB7CEAFCEA5E2FCEAF83D17 +:103FD000BB43E38DF962E319719D4E674303D0E162 +:103FE00048F11D23AE734DE72E4B5C874477CDAF70 +:103FF000282464B3C0E4C7F68DF33AC0FFFBB8666B +:104000004D11EA156E5FE37DAA541F2F9419BCB5BC +:10401000B9DE58B3098FDBA81CD127C3390985C085 +:1040200081323837A1E3398A203E1FA1F6BA8EF9D2 +:104030002545F8FD89A610967736CDC6A7D14FD174 +:104040006C76EFD794B94252BBFD752FB3DB37675F +:10405000A9D77F1DF45B8587E5FBCEBE84E8263BB0 +:104060009A1AD6FBDDB03F741D29011D39692B83D7 +:104070003B50352606EBEF2939D8DF047150D9A122 +:1040800061BEAB96FCEF18BCEC65FEBCCBC5DA9309 +:104090004BD8FDA7B55C3F11A906F38F6A17A6613F +:1040A0003EC2A2C5BA4FA5785B2C086F14727D077B +:1040B000E79EAEE54B6DF71702A079E87A05742903 +:1040C00006F7C35D9B7B788940FB0DFBAE413F2328 +:1040D0004C1BA6D37EAEE5FAB6E26D17817804B923 +:1040E000CC89F26BF162AB5FB0D91D57C1CED95C00 +:1040F0001220CDB4DDA21AEB77978BF155D876FF5D +:104100004BED59EE8331F26DEDF8B1C74D0F79F9F2 +:1041100079251E1F3D498AEFC7335F3C2FD7DEDE6E +:1041200088833679997CEB7432F9309C0F183CEF18 +:104130007139B8ADE928C6D10CF8B2E59800F23E65 +:10414000A7FEA825EF9D22168D6A639F8048BB4B72 +:10415000500FDBE6B34DD89D35DA7D50D9447E77DC +:10416000A088FFDD0261F8BCFFE0B5C6854F92B9BB +:10417000AF149264FCC3E2C1B587A450B396C08B60 +:104180008187FF6B3EDA0278A7CF57E67F52C6FCE5 +:10419000C05CCBDF0730CE6F5D335496896CA2E7ED +:1041A00085CB9D3AF357078B812E8F5C9A12627FE5 +:1041B000E782DB41F15F8960077DF9FEF53C4B5EEC +:1041C00033EF77A4F5B2E7539ACE1B27EE3F80FC7E +:1041D00097E65010ED814C91003F65433E9E9F7DD8 +:1041E0003F66B55B2DF978AD7DBB04881B6E87FCFF +:1041F00044D339BB9CFA5EA11DECBBE6188B43C4CB +:10420000693D0A776E7D5C682B4EE47DD9E57AEED8 +:104210006DD67CC1F6B98BD5DD1AE4D55476C3C50D +:104220005FEBB6B23897517F28DEC5CF9F3A48037F +:1042300081F3179297C59B83FC5E8EB3E5EF7E26D4 +:1042400046D5FC7CC8DB8D291574FE0F65442A7C9D +:10425000B4DFAE4069430FD0A71CC23CEFA58D77F9 +:1042600087214EA866248F832FE5F6418D8FC5D315 +:10427000DE72C4F3206EFE8B8CCA1ADF8C24F51B11 +:10428000EFC5FECA47B86FFE261FA3CFED62727955 +:1042900070031FE72B2B44BC47C84D7C783ED55D8F +:1042A000D83D1BF0B17DE5B650B27396D3D5C85753 +:1042B0007DA638ABBB90DD034048EFC530CF757F9E +:1042C0007EB8F7193AEFF43F7B51CEA64BAC5F5363 +:1042D000FB9BCCF331DAEFFBD32FF1FCFC3E7EAF3E +:1042E0003A89165C0E71F64D4619B600A09C3654FC +:1042F000BE1CFCCA44F9C70BE0EF266D021AA5C428 +:10430000F7DEA6C3A887370984EBE95F2CC0FEF867 +:104310003DEE2FF2EFE5577EF0E8FDA00F663AD1B3 +:10432000DFDCC4ED1D03BEF77DEC9CC2FB1C5F23EC +:10433000E1B393E3DB0BF80C9C173E3B93E1634145 +:1043400040EF023CBB21138482E0FEB3B216F2AD13 +:104350001F6A22E1AFD3396C0FEDD905678A68FB7C +:10436000FB93ADC70F33F46E1FC2730CE7E72BF45A +:10437000860015EB6611EC27091C5B475BD7A96922 +:104380004CCEC11D63F04CE7F6A5E4EA0F42FE8275 +:104390005AF66FB7AB54CE74E4F72F4916277EC296 +:1043A000CFECFEB411E2E22F70FC55A5877702DC5A +:1043B0006DEA03E8EF39051286FAEB660F10C1D4F7 +:1043C000EE2D3F5B0F0A772FC0EDBC98DD4FEDA3BC +:1043D000788704395F19837F9D768440FEBB2F78F0 +:1043E00004F35A7D6503C8EF280AB3195D813FA81D +:1043F00070FBED854D6F2F00BA48970C3ABCBD138A +:10440000E84C4A9491EE7AD259FB63F7DDDE09FE5F +:10441000E20E276D037230DB89F68D7D7E8738BC16 +:1044200082AA1F80F90DC3A76BE051B86F60D34417 +:10443000764F4BB9D8BFE46B4097577AD13EA3EF84 +:104440009798CFDB9FE4F83AE963F6D5A63F29F8C1 +:10445000DDBE1E23D1EB6FBF38BDFE76047AFD9D15 +:104460008D5E3F21C9E9F57F46A0D777E1BD1D2FBD +:10447000F6B244F4ADB0AF2C7FBE6027F4275F35B1 +:1044800077EB33F4297DBE318AAB19122CE79913EF +:10449000F23EF209F46FDC2B60FC7DA2BB7C23F4BE +:1044A0003B6BE6569063E7D0EF19C087BDDF5FF046 +:1044B0007ECBAFF44692DD93B0CBCFF2E37FE067E3 +:1044C000F546E29B5FF9597ECA487C13F70FF14D20 +:1044D000AA3FF3EC7C33C8EBD37518EB9F712E7CAD +:1044E000F3203EDD858C6F70FE7386F30D2111E4A1 +:1044F000938E7CC61745FE159DD15C131F917BAD35 +:104500007C44EEB5F0D1A7FE7B918FECEDFD23DC72 +:104510000778D110FF87A7C13CF40BD536763E69EA +:1045200000CFE1F690C13E17E609B3BC5C4F34AA58 +:1045300033F3A09FC0BDB3B378FB1DE0A3811F344C +:1045400093C7B3E47EB2C8379C9F7D65F132F3FD1B +:104550002E2FF3F6AED47039E0BD870C4C01FB6C06 +:10456000A4759ACFEB9F4ED7E7FB93D0F9D9F450BF +:10457000BD9FE9A17ADE4FFA9F9506B04FEDFC5E34 +:10458000BEF2C77F7C62947E6EE2EBFF55DECF17F2 +:10459000E0FFAFFA93F02FE5FF1B601D4CFC5F2698 +:1045A0001424E5FF9BFC49E407E5FF9BFD7F5B7E50 +:1045B0005FE34FC2975701BF659E1DDFCF717C3F00 +:1045C000F725F1BD85E37B83FF0BCBDB0DC9F04500 +:1045D000F1BDF11CF1BD65047C3FE8C7F57F16E134 +:1045E000F7695E8C9777CD227BA09F24703C6CEEA0 +:1045F00047D1583F94A73E1128DD977FDE154A76B4 +:10460000FF116DF768B276F3FDAA917CBE1AFC87A4 +:10461000ED5779715F81EAC72793F1C797A0831F90 +:10462000F893C8FD7291C921C77D1777421CEF4BE3 +:10463000F4FF9364FDDFC9E5FAD9EC82D7385DD089 +:1046400079FF977FC670F9D7C3CF270B6AE4177E2F +:104650008CDB0F5C01F26AC75DE902C4BB72F5B87E +:10466000007E025EEA43E1980B97F8CC48B4DB2168 +:10467000C705B83F6747832AC07929537F6FFA334C +:1046800047EECF0E0785EFD77E9477FA6FE0399F1C +:10469000CFEF7CEDA47DE9FAEFFD4C6EFF0F3CF50A +:1046A000C956B96DCC430C77B33CDBD9C9FF7EE565 +:1046B000019FCCF558F8B859FEBF3B4457ACBFF347 +:1046C000D53F14BECF387C7FC27E6DF0D9F17236F3 +:1046D0003827819E67FD49A999C3F594BD3FC3CF93 +:1046E00036D609AEC530C77DD4D421FD9D0AFD79EB +:1046F000DB453C4755CBE549EDEC346EB7AB1EE8E6 +:104700007F3B8FC36FBFED810AD857EFB9472D01AB +:104710001464D733BDA7DD360EE3ABD9BC5F3BFCD9 +:1047200043ED9DBD53E0EF42D071C7C1B8F3E692AF +:1047300038F88DA9603760BC42C5BF5F9CEEEA0EB9 +:10474000427C769DD0BD6419E8D52BBCEC5C4C70E6 +:10475000F159EEC56CB1D02D09969DA57E33D65783 +:1047600053BAF1FE9473AEEFEA4E6A67CD4B150D66 +:104770007F62CEA8780D0630EE65E077F8386CFDE4 +:104780002AC20D02E0DB5726A8907AE7A37402F64E +:104790009258D88F79535797317A21D42F19FDFE2B +:1047A000950E03AEABFF167019F5461E8FD7B39D5D +:1047B000B718FA3B635E26C7B0222D7F742823E921 +:1047C000BE82F1EC6C5275B80AF92355C37B193BD4 +:1047D00087F2BE43C145BEBF7FBDC4BC626CDFC9AA +:1047E000567FE8FE91A082F61FFEFD0E131D75A4F4 +:1047F00032BF554A0BDF9D8AF23784F73FD2F2B7BA +:10480000B0ACD0B20FCB4DB03E441D2A37E3F720F9 +:10481000AB4F54F59CF04EDB75613B79A89FF5D802 +:10482000AF7768DC8D580E0C95EFC3FAB9ACFEB9C2 +:104830008E33ECFE957E09E7FF89ACA7C2BEE97511 +:104840008D5FC3F8D2F58DB7E0B3AB49AD80389D2D +:10485000710FC975D77F4D057FFAFA9BB6E0BEBED2 +:10486000D1FF42F03B80FF35B91AEC2567BE187EB8 +:10487000CC9BE0BF041C6D58AE95D97DFE0B679FA5 +:10488000D8D4668ADF29F077D121BF4633DD834152 +:1048900012F2F04941DF9D7A1EF43C7C9E841CA4F8 +:1048A000F4FB89B73016457AAE5493F18D31DF9120 +:1048B000FA37E63B92BC31F066BC5F57C8FF8EAE5C +:1048C0002D7EE99E5885F93F0B050EA78FDF0BC99A +:1048D000EBD5D2719E2D46BAD0806E6BB97F67D76B +:1048E0000FC6B84F0A91D7013F1027BEA774387E74 +:1048F000CF156F46FF63235102F772798A09EE8B59 +:10490000057CC6BE3A936B0F7A8D7214934BC285A9 +:10491000DD28E7DC9A21F7989E54537A75B184FA22 +:1049200041A97FBD3C3805F2402341F8133EB4FC59 +:1049300012DCCF9C2EB132217F7DE920DA3FEA05DF +:104940007093A3227FFED2A13CC28E2E62DCE6F3DE +:1049500097209ED733542671385FD0E3192AEB4A4B +:1049600090960B86CA5128EFE076DFE9D4CF5F6AD4 +:10497000437D16FE0CF8C790AB155CAEFEADE4E9C6 +:10498000FF02CED174B20080000000001F8B08002F +:1049900000000000000BE57D0B7854D5B5F03E73A8 +:1049A000E695642699BC27BC721240A23C9C040286 +:1049B00041B14E78355E790CF51524C824E1119E7D +:1049C00001A432ADB60C24202868AC2FEA833B2822 +:1049D000F66AAFF682C55BFE16F907410B2D62AC95 +:1049E000A8F840C3A3151F2511B44CAD2D77ADB564 +:1049F000F7CE9C733203C1B6FFDFFFFBC3D72EF7A0 +:104A000039FBECC75A6BAFB5F65A6BEF612CCC583B +:104A10002E639BB566CFE8618C85BD565F7F8DB1F7 +:104A2000750CFE0A183B877F5733D6D76367AC9C5B +:104A3000B1473283291EA83FE98E0EAB13EA398BAA +:104A400072DC41176385DE2FC295F07DE128C63404 +:104A5000FCB65F166323A15DEF32C59E037010F3B1 +:104A6000288CDEADF240FD1C3763AD009935C2D80D +:104A700020C61E70C9328C0760A024C2DAE079AA71 +:104A8000C6DF5BB00CCF55075BBC15CA6925CC1FD0 +:104A900081B2C7C1660400F6F258681E033DAA80C1 +:104AA0000A8D37C3DBCC34A8EFACB2F82300331047 +:104AB000BAE2F362AC99EA0DF4580932818FF13908 +:104AC000C1011E286F66AC6A2B8E8B450325308F83 +:104AD000D44B73B2EE825265897519832EFF7D0522 +:104AE0000BCCB43136D413B0637D57694E6A701065 +:104AF00095875079B525CC002F95CC1D518AE27849 +:104B00008191A706DCF171C4C7C3FB7F6B453030D0 +:104B1000D6D6F5BD84374E5503FA79485889788042 +:104B20007E4F55FFFE219CCE4267879D15033DFBBE +:104B3000DD17602ACE47A3F7CEED53A23DE1FDA2DB +:104B40001D4B188E77555AFA28A4A3B9DFB7BE7E3D +:104B5000D81380F7297F7604B626E86F0EE219C6CF +:104B60007B6845357D07CD6BD63CC666E0548A1917 +:104B700011B4CD899029E71C34BD43FDE0FD2D8C97 +:104B800033C3F581DA890CF05A57AD32B508BFEB63 +:104B9000ACCFCE41F996B6DA096C081442B613F8D8 +:104BA000DC09FFCE41BB419639DE038F6BC3FC3974 +:104BB000D587FFCD62BEF1B9F05DFD5AD3F3F7AFF3 +:104BC000F998A5E37BEB89B69278FB3755D706C6F3 +:104BD0008A7A67E8FF23849FEB35E647BA5DEF4B9F +:104BE0008B84618A3704A606C696C4DB7BFBAFEADA +:104BF0000CC48B191FDB05DF1D5A11088CEDDF1566 +:104C00001F7501C5EED12E8C97EEE2A1D65A3A3E21 +:104C100057EB8A07F3FC01631B10CFB300CF771566 +:104C200025C707D4237ABC3D15EAC154C6AB136C23 +:104C300016C043FD14853914C26F3AEB8BF5FC1393 +:104C4000C6E9C66BC6A3195FF52F325F14DAAD7FD4 +:104C5000D0ED030E67BF93F88902D286833CE155FD +:104C6000F5F33C86E3F7C03F9CE7772A4A5FCE81A5 +:104C700071049B151FE3F33DA69F5F1D0B64441554 +:104C80009AF7B124743FA69FA7797CE6F1A7A0B05C +:104C900002F9177ABFE89EBDBA7ACC1A1D1418CC57 +:104CA000D8331E77CE1FD2A03C84F9CEC1BAFA9277 +:104CB0008DCA188AEFFBE5D0FA36F3C5D915DA3D6F +:104CC0007B6DFA75CEF96C46684A67BFD8BEC28262 +:104CD0009D650FE0393055DD7003FCF75BFBB25783 +:104CE000E3B3A55E553B918DF882F912BDFC8C496A +:104CF000FE6208C3BB55C0DF14E6D45CD0CED5201D +:104D0000A4CEC15C26F95334976E1EA75B942A94F7 +:104D1000A340BC8CEB07C7E76B1EF752AF9DFA03AD +:104D20007EFC42CF8F66BCBC55DD3703E5C88138B9 +:104D30005E865C0C5E46E3620639E2C9665105E8B0 +:104D4000DCA138234FC0986A42B707C60E45BCB0F5 +:104D5000B01D44E7514F11D593F3B631F9B798A17F +:104D60003CADB1B320CEEB7D1BABDEE64218ED5D72 +:104D7000A6935B27B22B8FA25C96E59AD00FA97DF4 +:104D80006044E243C9CFB7385D5195F3E1679D7C3C +:104D900043F2ACC6F387814427760EE6A9662CD091 +:104DA00070DE6A5AFA1096C1D85AAC02F354330333 +:104DB0007F443DA9A6F58920FFA54E7D722DA7E36E +:104DC000FD5537EAE89832EBE7616A5CCB32E03FA9 +:104DD0004DD0AF52D02FA5C469A61FC3751A2E613E +:104DE00091A7148102289FEEE78FE0BA4DA63724E1 +:104DF0003D534AAC5FB5E9F99AB5103F4A3AB2BDA6 +:104E0000C33A70BD06BD567617BD2F21FC043D1276 +:104E10003F1D36D4273342B6D3FA76820533232B8F +:104E2000F1BB750E1F3EABB36879580FF0E4413DFE +:104E3000CE4A7C3E5C3F2C0CDF497E42BCA231A1B5 +:104E40006BBF0DE6505086ED81F4C4EFD6EAFA2927 +:104E5000EEDA6FE7BA32B76BFA4E55C17E203BC22D +:104E6000E7F3E9E4779F4C6E3F9CF60EDB6A294E30 +:104E70008EBF3A67B6DF9A1D2F1F2B70564712E878 +:104E800001D99ED4E7596AD06BC1B9B127F7ED1D9E +:104E9000857AD87319483276F7EAC7F7EDEBCD90EB +:104EA0004518EB81D51FDFE77791DDC1CBC898307E +:104EB000FECDA99D65BFD30BE5E2CE7218CB9BA0BA +:104EC0003B7605C8EBFB1EDFD70CDF9F3DE220FDE4 +:104ED00075BA2A35828B273B34861D87715BC1CC1E +:104EE000C90056031046E80CF5A4F92856C01CE08A +:104EF0003B5BF32988EFC9991AF183556351370C4D +:104F00002EDBEA53105F3FB2B30621372E9DA2B3CA +:104F10005F266772BB43F6E370B2704A59BC5DC648 +:104F20007C2B518F582730D22BB0CEC96E93EB5BC0 +:104F3000B6332D93EBCFCEF579E1F53C2D33C17A25 +:104F40003E6059FCE10FD09EFD8DCA9E82A94CF7B0 +:104F50007E8F9EDF18AA2738353497E0AC4C6EBFA1 +:104F6000FC9E056765026CAD7E63FA72E0DFC6EDFC +:104F70000E1FAAE585B77D7C4FB9867802BAE37724 +:104F8000B3EA1F2C87F7F6FE16B267D7F666D5C8C8 +:104F90004FF6950AD947EB347BD576800F6454DE03 +:104FA0008FEDC9713D903196CAAC4AB3209F2F75E1 +:104FB000723E3F7BE44E6F1DDA952E17AD17FBCA8C +:104FC000A27B2D5066FB61DC0CE507233B4375702B +:104FD000B83A93DBA9AB05BE7F20F8CC1943227306 +:104FE000BE5E0CFD3BAD618676B63366A5E7760501 +:104FF000C697804F657BCE182CD2A1D89FF97B3BFA +:105000003DC779E1F76A3633D83DF7E0F7B908E5EF +:1050100038D2F838B2CDEDA4F3E762FD99C771D26A +:1050200033E647889F0732FCF767921DDE664379B7 +:105030007E8BEB37879521DD91C76D0ACAE3495F07 +:105040002BD142C05F4AA51A5955847ACD337118C5 +:10505000F001ABB4F9109FADFD72DCC5BAFE9F1232 +:10506000F47FDDEA71E33803E3C0AE26FE66B9D70C +:10507000633BE3EA8773F90706974ECFBEAE6D59DF +:105080005B8CF2376CA3FDD20C673882E3D3D96D09 +:10509000CA392E9735EBF0B8FD3763ACEA4F49EFCC +:1050A0006ADFC136642FD97F529687A10CDF7D203D +:1050B0008A1F8E3D73034EA38D79ECC57A7B1077E2 +:1050C0004BC3D1BEE17F334246BBCF6C17D655945C +:1050D000BE026400BC44AA86219F5D6A213EEBAEFD +:1050E000BDCCD87D9CCEE39A3CB8AF7A04E504EE03 +:1050F00007C71E1F4B72034C2B6C77F258D51385D4 +:10510000DAEB4316E687811FF4AB1105E676B0A40F +:105110006DFFD588B70A9B467AAB846DB82E07DF42 +:105120000FF5209E03C20E81FA5CBF799D91FEF0BF +:10513000ACD57FDC55AFE3BB8315C72FC5FD0AC8CF +:10514000BD8644FCC4D84AE2EBBDDF4FA5763E7C69 +:1051500040893860FCE3D4AF5F1D81F6EC0F6C3EF4 +:105160008746D3B2205D27F898D8B8FA5DE3747605 +:10517000C07116184E7665E9914A07DAAFAB155A39 +:10518000A712FF3342467B33B818EC32ADAB7D0A31 +:105190008DD9919FBB6B9F9AEDABB399C2AE2A6339 +:1051A000657ABB2A999E92769595F9FF467287B5E6 +:1051B0005951EF4E820789E4C04D195CEE8E533F82 +:1051C00023FA9CAE5035C4D7C1D0272EDC8F1FFCEC +:1051D0005AE5FB607FAEC18ECBC9E27E814D763051 +:1051E000C8E0BB4D3D9C9195D0D4EEEF5F96DF4675 +:1051F000F4D11E1E8574FC8D8DE470B2F1BA432A81 +:10520000EB078C3931A41094F42B0CA530AB4E3F36 +:1052100014B2C4E3EF9FC5C79F7B07B368D06F6626 +:1052200098F913ED8F653DD8178FB732AA1FCD843B +:10523000F12DEA6721FE94FBE3145BD8DF13E66FE0 +:10524000DBB9248CFBE442181F8E4383F1A1BE2CF2 +:105250000AA551B938944DB06F289360BF504F7A6A +:10526000DF3FD497E025A1227A3E203490CA25A1C1 +:10527000A1042F0D9512BC2C7425C181A037B1DE7D +:10528000A05025C1C1A16BE9F990D075042F0F4D35 +:1052900021E80B4DA3F7A5A17A8265A15A7A3E3485 +:1052A000349FCAC342B752B93CB484E0F0D0ED0495 +:1052B00047849A0856845652BD91A1BBA97C45E803 +:1052C0007E825786EE23382AF428BD97764BAA585B +:1052D0008F776B333DE8EF000ED7908F93ADBB997E +:1052E000595C2F1DC8F44FC82A8FD7B35B408FBBC2 +:1052F000BAD60B6671BD9189744DD0DE3441AF537F +:10530000BE630F0D6071BAADF39EDF9FC14A12EF0D +:1053100037E2F281CFEFDA2C2EBF36595BFD2AF24D +:10532000EF62E60BC3A389C35E5750BE6CD6AC5583 +:1053300089ECBB07B26CF4DD2399C1F95900D38A1B +:105340004EEC45793239EC797534F2CBA09CDF8C88 +:1053500086F60A9B2DB4DDD7986737FAD7B4B18C9F +:10536000E4A2F42B815D67D0A7EB055E18DBBAAF32 +:1053700098D653BF32AE7FDAAEC1F565FF7E31ED10 +:10538000DF37D9A38A15ED9BA5A0C374F6FFA63518 +:10539000753FC1F7F1F6EC34CEC2B5EC2534B18BD4 +:1053A0005AB4D12900FB6EF4BF94029FF48F0447D6 +:1053B000A74279C0D3E197105EBA35323A0DE0C00A +:1053C0001DD19750DC0C8EB68D7641F9F27D6C0FB5 +:1053D0002EFFD2566D8C1BCA430FFBF7001BB0F299 +:1053E000B6E098740DC713694A87F16CFA000C3D5A +:1053F00028577CD6A2C276284E7FB0E3D07E937425 +:10540000710F6B1D9B0DFFD96B99A754C5EFAD6D47 +:10541000299983BAD26733CE1BE7097AE4299857D2 +:105420002F7F54F1E8F864479622E9F018F29BF4D4 +:105430004B6E6ECE22BFE4E6544F2576D9318E797D +:105440009ED0908FAD8427FBEA62F2C749BE03FC71 +:105450001AECD9F582EF3675DABB89F1BB43C8BFC8 +:105460007F15FC7E5BF07332FC3A9157465E781DE7 +:10547000EF17EB12D6F1CBC8DFC9EA9D12F837E37C +:1054800079B385ED035D05FD029FF275C5D08FF6FA +:10549000B1E0EF0BE1F5F8BF18DF462F8057A6E526 +:1054A000909C047EBD14FD63C9E48D5DEC67CCEF78 +:1054B000635DE51CF7DB7A40CEF54D2EE7F666F12D +:1054C000E749E597903376937FC796CDFB1BEA09B2 +:1054D000A8D989FCD4DE1C839F7A82EAA94479C3C7 +:1054E0000630B2A3D30645C2B84F290C6B652A56C5 +:1054F00043A18C78EC5142FE8722B033AC407F68E8 +:105500002A8AD0A9792C75E87F97EBCD53EBD5AFDC +:1055100037A9EFE3EB51F245D6E6BBB85F529B02E9 +:10552000F6CB5831EE783BDC0FB2E67B3D36DFA59B +:1055300093839BBD5E2ACBFAC9F8B72E5BF06FF35D +:105540002AC2A7735462BBE15BD9AAE0DB0E3FF22B +:1055500079F85BCC83F64C66F331924F99209F1417 +:10556000924FBCFF5EA1D49F84A17C55769EF00330 +:1055700078526F74FFDFE3E72CB4A9703D8DF2EC35 +:1055800056314E037A48C3753A0AC63E0CF1652778 +:10559000BA6B8CD3511BC52268F702DEA2B86F0F1D +:1055A0005BDCE467B2DB5BFCB89E993D93E63FD4DD +:1055B000139C907D9E75E149D34A91A8D3EFFFD902 +:1055C000352EE0BF35459E542CDF0CE5F515D06F28 +:1055D000561B13E575AE91DFDCEF313DFBB9FDCD18 +:1055E000D0DFAE2CFF341C0FF0F57484FE011E2BAF +:1055F000F9ABBDDDB307E4FA8CAF274FA95C4FB51B +:1056000083481ECEC176657BC9EC9BA26C2EE74217 +:105610000226B36F24DF5FB47D23C63B3BFBFCEB6C +:10562000FFAD7DF76FDCC274FEC61E0FB55A35F4B0 +:1056300067703F8DC5D94AEDB985BFD18FFE46E071 +:1056400003673F5EC6BF44FEE2E4788CD078A49F37 +:1056500051FA13D3055F31AB12413D9E5EE1B1D6E5 +:10566000517B6DEC3BD0DE83024F725DA3DC7A7E12 +:1056700010CAA52C2BEED7D19FE4CE8AB78FE58C2C +:10568000B2B87C62621F77AB1873CB2A5F06BA9CF4 +:10569000C307B91FA5E5877C5D4EECC522AB504E14 +:1056A000F899E681FA294CFEF90DFEE4095F29CC50 +:1056B0000FE33FF0954A50E9C7A26ED8EF4DF429A9 +:1056C00051DC07DA2DCE08EAD2CA1E4E86F14D7B98 +:1056D000BA2582F111FB3185E6692F4B8BA0F01BB7 +:1056E000DBA32203E398670EEC710513D0FFA660DD +:1056F000ADC1FF65C66367BDE92F7B108F8F5E204C +:105700004EBB37BB334EBB0BF974D2CC8E66BB1687 +:105710008FD3CAF8638177FBBA4A54590BB87DDA44 +:10572000834556EAED2A5D1C741FB6F3683C0EDA19 +:105730007A893E0EDAD86327DABB3FEE8C83067F88 +:1057400085FAC49FBDB514F9F751DFF667EE457CC5 +:105750003A44BC62E81197867EFAF23DB9389F5709 +:105760004DE39750FAF1CCFBE0C3D9C6F8C219DF7C +:10577000751951E2ADEC84EB5BFA17E57E18FD87F5 +:105780009E84EBD0886FD97F8DC2F7B5CCA670F917 +:1057900027F428C8974F480E4418E94DBF437902B3 +:1057A000F5CD19DF501FC53D93C81B391EC063FFDF +:1057B00044F15FE82F619CD59AC3F5588D8DFB4D60 +:1057C0009525E58B715C356E97E2D0F9FB3B84BE85 +:1057D00033C785D48CAFCB83C2EF9D68FEE6F84E0D +:1057E00087D017882FBD9FFC42F83A6C6BA1F8E177 +:1057F000E1592A5B09ED9C098EC86709BE97F05DE7 +:10580000E49BFE0073787F9DF44C122F3ABCA2817A +:10581000E2CCE6785AE7FBDA946AD4DFD588475DB4 +:10582000BFE5395CCF4F129039829A07DEDBEB1E61 +:10583000F4308C7FF5FFA23CEC46BF58C70B18BF75 +:10584000603F7093BFA2BAF6CBF2958375F8AC6057 +:105850003C3EBBE7C71E0D9E57F76FCE0DBB92E3D4 +:105860007112B60578BA1B1F8C247F8C2F87FB37EB +:10587000BBE58F6183785C88ED49A1F869CA9BAA72 +:105880000FED06EC97EB01EE4F5E26E226E6385E62 +:1058900075689141BEA4C51416D1C52FD2AC5BC9A1 +:1058A0003F9B16B3D273F37ACBCA81F53630BEDE96 +:1058B00024FE93D153E2DFFC7CB0C0FBE1DAB91ADD +:1058C000FA0DEDA989EDE066514F96CDF908C9E2D0 +:1058D000EEB5627D9C098ECC477F55B53DDCBF3B64 +:1058E000EB5CE2E742790E37E7F0FD907BEA1B22A2 +:1058F0008EA736636B52AFA659CF1F8FF59BE2B1CF +:1059000069C3BAC4F3FE29F1D81F9AE8D7DD78EC51 +:1059100078B11E2F94877293DD68F748789DA0E3D5 +:1059200099600A0B837CBCB552A53814F007E9C70F +:10593000C30F2A646F466B1DA497EB6B53C83F5B84 +:105940005FAAD2FBFA0D2AE9CF28C88705201F5E7F +:105950001572C2EC9FAD648A217E3E69588AA13CD3 +:1059600075D6FDAFAE40FF72854DC3FE0E6ADCDF1B +:105970001CF6AB64BF421BBE28FAA71FB8CA87FA41 +:105980004CF2C341BF4AEB2D7C48F561B7ADC21F55 +:105990007D706D6904F35498128FD36B7DB1FD7ADD +:1059A0008A03BFE3DD4871CE94BF3E1C08D0FE31B0 +:1059B000A89592DEE4F1D314B14EC7F4A8B811F55E +:1059C000F887EB6D0CFD461FDE7186D673DB8AC54A +:1059D000941721FDCBD23F6CF6339BFDCB5DFCCA07 +:1059E000267F72B27C86977212C7EBA5BC4AC61F8F +:1059F00020B6F67F133926E5C7BB629E637A6CDC5E +:105A0000B012F0903653253C48BE7CE7EB3B1F4775 +:105A1000399C02FCB18A213EFFE365DC87B0B94ABC +:105A2000423F72AA94EB983F5112A7CBD4E0DCCE50 +:105A3000322EFF690D4B0C791F66BD925CAE9D5FE7 +:105A40006EADCFE1FE0AB3DE31AF877FB4DEA9AE23 +:105A50007DB004BFAFAE9D1541B8AE87B301E5AFD1 +:105A6000593E98F5C47526391BD70F2A8B0CD58F54 +:105A70005BA37A713D61A7F7675378BE43C8C9E15C +:105A8000F2D4F427109E4DE1F90E61340AD14EFD97 +:105A9000202DD244FBF2C523904F42CCD716C679B5 +:105AA0007A53C98FD0D28BD753AF49E576F9DE4A06 +:105AB0009AAF2A0DF3E64A5A374D622E3FCE0EF6C4 +:105AC000C885F134F92D29185F18E3B6EE47D74B96 +:105AD000CB680B73B038BEE27921CCA3C0F7F44E8B +:105AE000C1FD67A9D3DE97ECD4E25CE4CB1FC2FE14 +:105AF00010F8FEC00175FB6698EA01DFD08C447691 +:105B0000BA84E638F291EFBEDD07D7EDEF59703079 +:105B1000B6D75A5DBF01E3C38D3B548A2F4DBFED0D +:105B20009D4BC8EE36C529D5746709FA539A94542B +:105B30001FCA1389C7DD6E3BC999A62369B49F6844 +:105B40003AAA88B29BE4A1C4FB5EA857300C7395B7 +:105B5000DC243725FE615E57217E241D2A59F4C0BE +:105B6000A8A2BF6B5E55E79F572F0FC90FE43335CF +:105B70003E0FD56DA5F9B5B3541F8E2F24FC43EC11 +:105B8000FD34DAFF493A370A7E94745E24E8DCBEBD +:105B9000F3CB7BAE84FA2DFE2C8A3AA8BD19E1A185 +:105BA000FD7D37F189C4839C37F0C574FDBCF7ECEB +:105BB0001C7A3888DFA7A7521C5FDADD32EFC03CC1 +:105BC000FF1AB17F6FC8553AED5EF45FBC9A3DBADB +:105BD00021B73C417D61EF02BEE763BF951EF645EC +:105BE00084C5F779C9F21B96E72A179BDFB05CDF03 +:105BF0007F677EC337A7E7AA8BA167A3D5B556C930 +:105C000088E35BEE9B69496B5DD7BF79FD497A28D4 +:105C10003B77FF19E3F866B9B05C5DCC14E867CD5B +:105C200060BE2ED91D4CA3FC20D37AB990BC01FADA +:105C30003F8E74482677BA4BFFA7BBD2FFE9F3D15A +:105C40007F4376E0A7F81EBBEA5946FBC267B18CDA +:105C5000F2C45E4CFD11DF766432CA6793F931728B +:105C60003C324FE65798B49AABCBC329F129A82709 +:105C7000BAC11FBFFA07F3C72BE7E78F28ADD3855B +:105C800082FE0B655EC6F6F3E76574837E6F26A21F +:105C9000DF72D5D7112CEA3EFDDABAD2AFEDFCF4B3 +:105CA0000B1E277D62675F90FD5E51EB457E19EA12 +:105CB000F14FC6B8F9AE9542EE1401FDE0FDCB39C7 +:105CC0002AC9B51FB1CB486E7FCB62A1F1B683BCA8 +:105CD0007E42E9D63CCF90DE61616B16B4BBFC3AE4 +:105CE00046F13DAFB652C172BE067A5AEBFE7CFF5A +:105CF000D675BE7FBB80BC52F272893F97217F3A36 +:105D0000358FF57CF2CA9D67B413BAC18FEEBCDC47 +:105D10007F283F7AF32E42AF7603FFC5D85E323933 +:105D2000D1DD3C5058A7AC6756D7FE19F3515CAD96 +:105D300032DDC9F5F63645E8F1D22095DD4E121672 +:105D40007B859E3FBD9DBF574727B62B07E6651154 +:105D5000FE176E5D12B01AF249C2F4FC5EFF694F85 +:105D60003F15F3B45D349FEC89DC0F29E72FF3B4C2 +:105D7000D3C57CB27BF379671FE179ED125FE962ED +:105D8000BF91516135EC2324DE96AB0105FDE89906 +:105D9000390CD324609F3048413F57A6DF585FE25B +:105DA0003B97ADFF5CC594AF2AE3FB5CDCCF0CC135 +:105DB000F7BAE709F6AF409F12CC1FBB314FEC4F4B +:105DC000ECCC8BFA88A935E7E523DDFE647A5E37F3 +:105DD000F627F57932DE6ED47B5B5358423FC3E73A +:105DE000623D80BD42FE6655E8B9B16D4594EFB2A3 +:105DF000D4AD91FF41557DCE09455DBFCFF4C3F2CF +:105E0000D6E123BB2A9569BA79E706B20CE5FCEA2C +:105E10001E86FA05C162C3FB9E0D9719DEF75E5C14 +:105E200066281786AE30D42F02C4EACB7DD7FE9BFE +:105E3000A17EFF96EF18CA0336DE6CA87F69A4CE58 +:105E4000F07EE0D3F30CEF076F5D6A285FBEE3FBE3 +:105E500086FA4DC28F6CC6CBF63C6E173559B91C0D +:105E60005AE92A23FF6693CBE8DFBC47D4ABCC18B2 +:105E700055827EF5A663A52588EFBDE957909F3D25 +:105E8000195F98E55A32796A7EFE9CA0F7A997ECD3 +:105E900016E4EB457B60DD5E0E65D7BB6B704EEBA9 +:105EA00006F1F8AC8DF17C2119AF91DF77C66BACB0 +:105EB0003EEEAF4D77B1BB12F0C53D795A427FAA95 +:105EC000E4A3647893FC7821BCBD20EAFDBD787B17 +:105ED0005FE1F9AE7A7DB02DC1B84E897505FAE65D +:105EE000B53C6E0F0D4B254BDE43EBF162F5811C8B +:105EF00007E8837751BF98F3744F55BF31FB610DAD +:105F0000EBCFE6F52DBE12A44B327FFAA9BC2EFED4 +:105F1000F406EE4F4F35E0ED7DB9DE4D7EBDA6F4C3 +:105F2000AFC89FDE64F79574C79FFE3E7C8BFDBDB6 +:105F30008074CED5D157F8E393EDA3428CEDC7F32F +:105F400010CC65D5F4FBA664FB6329CF617F5C822E +:105F500071DA16DC7F2909F5A035BF9CF6CFA40FB6 +:105F60005A400F3AC84FC0F66B505E3EC6C2EED2E2 +:105F7000E2F396F6BC83F99C7695E89A9A8F78F9C5 +:105F8000215B96A2FE43F699B9F917A1E7D985E3FB +:105F90007D64A74D84F9AFD2EDAF257ECCF13D896C +:105FA0009F893E1EBF5B0DFA11E37BBB73B99E5EFA +:105FB0000DFB6FC4A3273BE0ED83F63C3C7F02C999 +:105FC000913B9CD68FC4AB39CED75DB933229FF3BA +:105FD000A3CE8E1B919FC03F133FAFC2E7BF54ECCF +:105FE0009FC7A983B6A21FF374CC4E785319CFBBB9 +:105FF0006CDC676311A223CF5F9674B4C5D6B4A2DC +:106000007EB63173BEB29681F3B7EDE3E7C4580EA6 +:106010007F1F66CE9568F7645418F557A6DFA8BFB2 +:10602000B2ABB24CFACCA8BFF2AB8DFAAB2068D4BD +:106030005F3D1BCA4CFACCA8BF0A43A34DFACCA8BB +:10604000BFFAAEFD8E499F19F5D7808D46FD756963 +:10605000C4A8BF063EBDD4A4CF8CFAEBF21DAB0C96 +:10606000EF4BA37719DE0FDDF72343B9BCF51143DE +:10607000FD39FB7F4E793D230E3F61A837B2EDA776 +:10608000867A80F056CCFF9E492461ECCA93CF1BE0 +:10609000DECF14F6DA551DBF34B4C35A781E771814 +:1060A000FE21BD3E62413B1A2956D6F14A4FA0EB74 +:1060B000A288E28B42B5B93BB60DC7717CFAC135F7 +:1060C000FBB09D391B8DF9DF7323C672232BCE40A5 +:1060D000B9D0087C11013E998F79E13AF9369F2DAC +:1060E00016E702BBC76773F65FC7289F34EC6FC51E +:1060F000BC77394FC96F7EC16F727C72BEF3C1FE2F +:106100008B6AF179FAE11FDF6FB6D9916F67EF50B3 +:10611000D8234AD7F934ECBC6F4DCF04F332CFC348 +:106120006C87FE24DF183F19A7BA285E70FA90EA40 +:10613000E3FE46E33A5CBA9FC709963EA790BFCEFE +:106140008C0F699F26C38B1AE6FB86C61C1689E84E +:10615000D69F26F0E1F01AD7DF69FC0F1CCF636AE7 +:1061600004F38D52B45433BF0D8FB2AE784E2B3141 +:10617000AE53339EDDBE1E09F94A837F388ED9E2C5 +:10618000FCA199AFCC785FB4E33E3BCAC38BC5FB9F +:106190009BF989E312A0ED86D913E4D749BCC2BEAE +:1061A000FD3DD423C9F6B31FE55FF47EF6A3FC7F63 +:1061B000EC7EF6F4F9F45C3BFADBC0BE34FBD9CCE0 +:1061C0007A58D9B9E7CF4A3AF9B5DB1CB8EE823E26 +:1061D00027CF8331E9C99212839EECDCF71E536806 +:1061E000DFBB2DC3AF78613CAF64F82D08A766F81C +:1061F00055AF6EBE4D80173AF7037A6A5B023BF1EA +:106200006AAFB48F02E437595DC9EB9BEB0DF0F236 +:106210007342BB73877BC9FE3C5AEA25FBD33DFC26 +:10622000BCF6E7BD224E7437C621FBC7F383368820 +:10623000780D2C3B3FD26DB52DE0D5E70FA77A3313 +:10624000499FA68F7CBE15F3A89B3C168FA221E424 +:10625000F9DCCD2E6BD516F15D8EE13B3E4E15F18E +:106260000D78B5BAAC5FE9F9F66A2FE3E7AF92CCE7 +:10627000F36A2F8F13DB587003DA43323E6C3B56C0 +:10628000E94479D7C4FC1E2E277D1E7DFE878DF143 +:1062900078F068111F96CF55CF37CBC3FA6D46F013 +:1062A0005BDE047958CB32FC57237D43D6B003ED37 +:1062B000CE9033F1BE789C57C4EDC47CC10025BE9E +:1062C000A271A8171FFF017B3380FD2E57C39427AF +:1062D000D9E41E5E127475DFCF35CDDBC53E9AE67C +:1062E0003D8F7D04F6E9643C47E6CFE861A56D8704 +:1062F000D55782F85E8BFF3D92FCB475889F2E794E +:10630000AFE21C2EECE3CE9BC72BDBD995E59FEBD0 +:10631000E5F986F3B13DFF004FB3AA6B27FD02ED0F +:10632000483F4737FC56DFF326F05B2D577D27515A +:10633000BF77178FCDDE2EFEC266EF79FC85678FA3 +:106340000CC8C078B6F47799EBC97391B2BC36D358 +:10635000D8FF9A325EBE57D0EF77E27E8A27C538E3 +:106360009CA6F3A2CE098CEEE990E74C653B4F7AF0 +:10637000DD54FF8EECD14FE278D71429B40F5D9332 +:10638000A918F6A3B7782B9F447A3C2EFA7B52F0DB +:10639000EFE662EECF31E761CE11F5E7784713C43F +:1063A00073AD28C7ECAA9A108F4F7BF9F8274343A7 +:1063B000941F27FC6EF50F2A62FF64BC1701D6F903 +:1063C0005B69207F8EAFB7D1B9D759AA6B0DF26345 +:1063D000B27B0E6A070528FFE9EF3D3F86F84CCBFC +:1063E000EAAA57A3DE4E7BC67791E7C87ECDF1D3EC +:1063F000BD787F5B2AE7D30EB78BFCE6E67A4705CC +:10640000FDD70BBF06CA75D42F592A5B9C48CF1CF9 +:106410001572F59B9F6BE6F77964BB5CF49DF95CA4 +:10642000739BBD6D753E8EF72AC587E717F26B3CEF +:10643000BBF373F01CA3463EBE35452CBD02DF976F +:106440005AE87DE6F59E3536CCFBD61866EE331B52 +:10645000F4E3867E520A781C677DF8BADDF9502F86 +:1064600043EB60C583E8BCF7782FAEDB6A9E3F6FD5 +:106470009EDF57021FAED5B0BF407C6889F3D0BF06 +:1064800012780079F367A447A5C6B6F373593C0F99 +:1064900016D992F2157D3C5F3B0DF39DFA7279831C +:1064A000EFBFCE1A730EBF93EB4B15F8369FE74E36 +:1064B00029B8B8F3DC936B128FB75F01E787C31974 +:1064C000818C02E877F2A895DC1FF6F5B973EA70C3 +:1064D000348EF93A81EF19FA2B5272B81C4ED1342E +:1064E00092CBCCA3509EAB53F3356039C57585472D +:1064F000453BD9C1E3926CA685E1FD2A63443BFE8E +:106500006AA6FCA184FB65B99CB5B23F48FE57055D +:106510007286A39EE57F603FAD4F83F98C711DA00D +:10652000F8644ABFC59578AEE1E519BC8D1F2539E1 +:106530003720CFBB779EEB0F470E18CEF5DB1E3D05 +:106540006038D7CF1E3DF0F79CEBAF2C78F4C03FFE +:10655000F35CBF946787D5E0E1DB01FF370053852B +:10656000CA105A590DD1DB4B78BB5EE039FC15E0FF +:10657000D919C7F30D3BF713FE0EDB60DCD0BF6DFE +:106580003447B5EDFB199126928B11EAF74667CB9C +:1065900038DC77B6DB3B8660BFED2FBEDD3B0CF20F +:1065A000E4C80FCEB819F0DF87D60E373E3F79C763 +:1065B0001B6EC4D7913B54B2D7E85CB42E1FA95EC2 +:1065C000F0D54B05819B91AF66ACF8EB70BD3DCE2D +:1065D00042B9A47FE746544ABD92F26FFED3698266 +:1065E000E97879E1D66C4359EAE5858EC4E7D41F92 +:1065F00011EB62EEB39BED3D35EC3FB800FB3F295C +:10660000F21B4E6E77D33E4C8EA7EED9523BEE3B3B +:106610003FDCE96051F203B7DA18F9B3FC13943C9C +:10662000BCC788FF99C7F9CAAE346A6FD6832AF906 +:106630009D6AA1AF10E035B8732EDF079BE631EB02 +:1066400088361EE5D5AC750A0B6BBCFE1D787F46FF +:10665000E84E8AC398E769D62F7392DC9F3367E7C9 +:10666000DDF4FD4CE6BF1BEDD9592DE6F7D77C8450 +:106670004C3EE702F19C7B0B84DE19CE469CEB4B33 +:10668000F1A38CC1DA85F5CEC9157C917EB2C249E1 +:10669000F0B3151E823717703E9EBF63F72B3D691E +:1066A00099B70E47BDF4D6BEFAB49BB5B8DD3D7CB4 +:1066B000F3AD7B1EA5AAC6FCCC1A81F711222F735D +:1066C0008E38F7507EF8FC799935888F215DC72B7D +:1066D000EDEC1A93DF57DADD667C9CDE37260DF988 +:1066E000E3F902B1CF1D017851FF7EBC24FB6EA1FE +:1066F000CAEF4D333F97EBE866C1D733B74C59D358 +:1067000003FA6F7AF1A33E6DC4A7DC7F512EF055DA +:10671000EE5AD38AF32F6726BF61981D623A7E0630 +:106720007E5251EF98F956F2133BC4BF770ABF4629 +:1067300027BFEEDC40F8957C85271D2C68C381E5DA +:1067400062A9B8F03D57B35A8CE553B6B63E284F10 +:10675000E698FC0DA794C4FBB7BD05C51C0F9A7F36 +:106760003CE65FCC628135DC3FCFEFC739696D799C +:10677000E5765CE75BF83A5BF88BE7FE1BE5D7BC98 +:10678000FF7A301DE5D7C7D6963CEC6FC153ABD32B +:10679000FD28C7ACE174FCFEE3889AF01C71510F30 +:1067A00045E6EBBB304F6D11B11AFC6F667812CA2B +:1067B000CF3F3D65F3A01FB6F16947D401F858B447 +:1067C0009DE311CA4779F94EC257E30EE3BA9CF72D +:1067D0001F0FE669E40F08F714F8EB89227CD11645 +:1067E0001BE5B52E3AA4FAB09B46D641F3337F8F12 +:1067F000E38801DD1AB7AAB5F68CAEEFC112B2E399 +:106800007A6BDCCEE9D9B89DD3ABD164873608B9B1 +:106810006DE6FFCC1E46BE07FC905F4DE6DBB2087E +:1068200097DF4DCF3C3CE4288CEFB32DBF4D57068E +:10683000C5F99F615628E0EDF4D6FA19F6F3DCD7D6 +:10684000734AAC934EBD20F490B60306960FC59DD7 +:106850001C2EB045D3AF04BC2CD86CF385E1F1827B +:10686000E754BF0BEDA8771C74FFC4FCE75E7EEB1A +:106870000A18DFFC6DB69C097C1A2E94DF925E8D9F +:10688000C8E76571FACCFBF9CB76CCD3C4E7776463 +:10689000C5E9347FDB6E3BE67D9AF13966EB6E3BF2 +:1068A0005F6F267A6D3D3A1EF576D33367EDC80FDC +:1068B0001FEF52587E51D7EF1B36BF9C8E7206F1E8 +:1068C00084FA45D2AD938E5DE8179DF4CB6154CF29 +:1068D00083719E0BD1F1733C83504EFCFEB35FC2BB +:1068E000381ADE75F8100F0D3FBB351DE7F39175B3 +:1068F00031E7FBC757E7A1DE6EB085F33C04F9F33F +:10690000864DDF257E9CF3FA77F97D4ECC5F80EBD8 +:1069100019E65B80F39CF5D80D34CFD92C48FCD810 +:10692000F038BFDFF04B2BAB4AB41F784CAC9B8FD9 +:106930009E70D0E6E1233BE3F785FC4E15F7612D11 +:10694000217BE5BB62CE20A1A9FCA553D0AB878CEF +:10695000FB73F9D6286A356EB993E4DB27BDFDF9E0 +:10696000B8FE010F46FFECEBE3F2855CA47B5DE82B +:106970003BE0BF31F81CEBB7DAFC29430CDF89FCA4 +:106980005BDEFF32D13F8C3B15FD7C1FE519F7B96B +:1069900012FEB687F4ABB156A6E7B3647260CB3A89 +:1069A000E2AF2F0E7139B32832A58ADEB7DAA2F929 +:1069B000F83EB2FB7A85E404D82189D6F9169B58B3 +:1069C000E7C6F7304EABA2C7EF2E7E7E4FF2CBEC80 +:1069D00007A0BE6E5DC7F9C71E7F5E145FAF327F32 +:1069E000638EC99E93D02C271E32C909F93D7B2C9A +:1069F00037E1F988B87C0813FE16D8223F7904D70E +:106A0000F53B0E3A17B9E0391BDDEFF3E9B37BDE56 +:106A1000BA19F8FFD3AD723D1BE5AF793D373C7F26 +:106A2000034BB49E3FCD09B084EB199E275CCF3950 +:106A3000FCBCC1FF29F93B2789FCDDDD43D8633A63 +:106A4000BBE34A287EF2D3F985B43F33E157E2D560 +:106A50002C4FABD158C8ED2A4FE1EF10D3E153E2F0 +:106A600051F2E9BCFF5C48FD74F2B3E457C9CF9D15 +:106A7000FC6A9EB7119FE6F7CDB877CA8DD3DFB613 +:106A80000AF6E518AF7D51A5FCBC76AD233D0BFAA7 +:106A90005D2DF27BDA3DA29CC9CB1DB9F635284F9E +:106AA000E4F38E149EEFD01EE848CFD4ED078EEEAF +:106AB00054D3F13C405B24715E06656CE4E2E9D698 +:106AC00064EF57D27A684FE5FEBEF654EEE71BA797 +:106AD000BAFA84707FD7C2E34B3357DE948EFBFB48 +:106AE000F69D7D2757E37E60BFCA738EC27E6B0121 +:106AF000E0B79E4F9D9D64E18746A1FDBE73FE04F5 +:106B00006C67E67A235E66BBB6D8B19D2FD91D04AB +:106B1000673F608BF309FC6F1EE66B219F3F667A2F +:106B2000BEF35AE2AB7926BE0A225F25384FE2EA6D +:106B300029F8AA9495F2FDB6888F09B9374E1D340D +:106B4000B91AF329F7F1F31EA777AA6C0DCEF759FE +:106B5000112F0BE712BF2E02FED6FB4D3F43BE1B8B +:106B6000905CCF7FF6C291E1B7439505FFFDDE90C3 +:106B700047017EF6DFEF5CF22B2CFFE2ED3EEFB13A +:106B8000AEF5C7ECFAF32D94D7B9CB41F79AB6EF2F +:106B9000FA759FDBB1FC4B07DD2FDABE8AEFB3C37A +:106BA000BBDCA4FFDB7B737BB1E9C5B343DA487F71 +:106BB000F17B8347F4E4E73E4EEFFCCB070AE6F3B4 +:106BC000ED8459A17C14FBB7C65FA6D03EBDFDC5C0 +:106BD000B386FDE9DF3B9F45E2DC55BB9B55E339BE +:106BE000E9F64C7E4EB5F157239FC473970BB7EF70 +:106BF000B6D7C3FB31FFFBAF43500EB53FCFED0E11 +:106C0000B08737311F63A31FBD67830DE8770A6D17 +:106C1000445833EF3D7A7062785022BC703CB40324 +:106C20001E705E809706949FC9F031B5273F7FFCA8 +:106C3000AF878FCF6FC1FE17EC1C41F70CC7F1A2D5 +:106C4000F8F97337E57BC0FCF9F35D6787A01D7524 +:106C5000A1F92EFFFF6CBE0FFECBCE97F37BEF9E0C +:106C60005C1F99F9BE2B5FFFE2362AFFCCEDA3F142 +:106C70007673BDBFF02FBBDEFF39F47EE35F76BED7 +:106C800017A2F77E416FB707E332ED2FFEB50FBBBA +:106C900088799FFE7F74DE9D768FC5E71C06E37BB7 +:106CA00097456EA85492E78F16F632EE33E43DDC3A +:106CB000937266931D31C9CFFD314DAC6C1F9EB3ED +:106CC0000BFB558A5F50F20EE0A1F5FAD208E58978 +:106CD00059C3FD1FC2BCB11B17FAF87D65C6FDD7AD +:106CE000A4BCAA2AB4E70EAE847141BD836E8BA703 +:106CF00009A630D9AF92FD0790ECBE37475F4B79BC +:106D000028932B8CFB909B4DFB899BAA8DEF6F6486 +:106D10004FE462BEDF8D0D36CA4FBAC154FFAF3D9E +:106D20003D44D79BD8E2D5DC9F7371789A2CF0D480 +:106D3000150FE7C75B173C89FD26E50E695DF1E697 +:106D400008F2FDA7035E087B4BE4E52DED163E99A6 +:106D5000D8973A44D712BF0E3FBF7754D72EE1459C +:106D6000E2FD62F12DE964C6BBC4AFC49B990EC5B8 +:106D700078DE53679FC7A1F15E6D26ECC6499D760C +:106D8000A38BF0F8DA167E5EE2B58AFAF5A5587E96 +:106D900096DF07FFE5A8A1CC09F33D68633B282EE9 +:106DA000E4F76B9EE1F1FC19A5E2D7149FC0FC4506 +:106DB000FD7E15F317F5F3C2FC457D19F317F5F5C4 +:106DC000317F51FF1EF317F5EF317F515FC6FC4550 +:106DD0007D7DCC5FD497317F515F1FF317F565CC74 +:106DE0005FD4D7C7FC45FD7BCC5FD4BFC7FC457DD6 +:106DF00019F317F5F5317F51FF1EF317F5EF317FCA +:106E0000515FC6FC457D7DCC5BD4BFC7BC45FD7BD7 +:106E1000CC53D497313F515FFFEAD84B867225FBA4 +:106E2000ADA1FE18E71B86F238CF7B86FADFF61E8F +:106E300037BCBF46FBD4F05ED2FFDA923386E71848 +:106E4000FB080FC77D0CFF9BE8FB8BA11D2B0B5094 +:106E50009CD4CE161374A2BF17602ADB4AD005CB90 +:106E60001CE18901C1677A21BF6E0AAF41E63A3859 +:106E7000F26C1F94FFAF8DBA8EFB25447C6132FE0D +:106E8000A7064C9CF6752FDCE7CAF8697A4C65D1E9 +:106E9000A1C0873185A02796C6A2D9C087B1148228 +:106EA00059B16C7A9E1DCB249813EB49CF736305BF +:106EB00004F3627D09E6C78A087A63030916C42EC3 +:106EC00025D8233694BEEB192B25D82B76253DEFFC +:106ED0001D1B49B04F6C0C3D2F8C5512D462D7123C +:106EE0002C8A5D43B038761DD5EB1B9B42B05F6C9E +:106EF0001A3DEF1F9B4AF092583DC101B15A8225BD +:106F0000B1F9042F8DCD257859EC56FA6E606C09D5 +:106F1000C141B1DBE9F9E0D8F7080E893511BC3C75 +:106F2000B692A02F7637D52B8DAD235816BB9F9EDA +:106F30000F8DDD477058EC517A5E1EFB31C1E1B117 +:106F400027098E886D265811FB4F822363CF10BC12 +:106F500022F673FAEECAD83682A362BFA2E757C5FB +:106F6000FE17C16FC5F6D0F3AB63BB09FA63BFA5CB +:106F7000E795B1FD0447C7DEA0E76362AF131C1BB2 +:106F80007B8F9E8F8BBD43707CEC38C16FC78E1298 +:106F9000AC8A7D4AF09AD8C704FF2D7686BEBB36F0 +:106FA000F639C109B1BFD0F389B13F13ECDCFF8FD3 +:106FB0004AFABB029673B87F766575EBBEB2FBD218 +:106FC000D2492E4EBA83CBC587D34EED253939D25F +:106FD000A13948F86D34C4BBE8472460DFB77BE4CF +:106FE00047BDD0DE595379FCFD5B519F2D7130A117 +:106FF000CF4C72F76B97F07732CC479C2EF8FAB5EE +:107000008A3DB96847AD296B5B807E930D456D3530 +:1070100008F37A73BFAC5BC09CDE3C5FE12F03B822 +:10702000FEAD59D29FFFBE404EF7E6775D2FFE9D25 +:10703000ACFF751F0FD717AE8E3E745EAF9BED741D +:10704000B7DE85F2B062BD8297F5CE3DDFF9C16E45 +:10705000B733B477827CAE6FD0CEA8EEB4F3A1A0E4 +:10706000FB63BD037E1C3FB3FA87E0FBD1AB0A5440 +:10707000FC5D95DAF58A07F9A5BEB9743CD2B58CEA +:10708000F9C92F393D493ED96C41D7BAC53686FE7C +:10709000C93A8D917FB86E3BCF43467FEA44E09773 +:1070A00006C12F0BD77D4E7EA786C57378DE53842D +:1070B000FBA7E4EFD8CC6FD9FC0ABAF5BE64072869 +:1070C0003F7EFED346FF55A3F04F2DDC6A7ABEF813 +:1070D000DB09FD9E66BFD48CDEC22FE5E3794F4C01 +:1070E000ED45F3FE12E68DF924C1DBDC4ED41B80A6 +:1070F0000F8AC3483C48BFA7C407EB7AEE82F25719 +:107100004FEFEB4F7972A7352D1FEB05D3F9EF59F0 +:1071100029D6E0087C0E78A47C968E9569940F752C +:1071200014F4808689579EE008BC3FAEEDDDDE4C4E +:10713000DC5F698C4738D7539E782D8C01F3526AF7 +:107140009FCAA6739BD0DE901DE8D77CCA46F9483B +:1071500061B6D4CB2ABAC62B02AB6DC417753B32CD +:10716000797E5AD87F08CF1548BA1C6DEE3B1EF3C6 +:107170009AEAD6169592BB6E878DEC43199795F4D3 +:10718000EA9ABFCDF3051A59640DA62E01BD4E240F +:10719000A457CB6EA22BD0ED4412BA9D381FDD1E32 +:1071A00032D10DFDD437E1CB3BB2693DD7AC8AF685 +:1071B0005FACE34FB3FF9FCDBC82EE3D91F9CF555D +:1071C0003DE4EF8CF9F290BE67D69713DDCCF4AABC +:1071D000FA5B3DD185BDEBA67B87A7F76533BE0380 +:1071E000CF6708BFE7F4A66BC8FEFEAFDE7C5FF09A +:1071F000DA0ACCFD64ECF5154EE607E3FB8D151EAF +:107200002ABFB9C24BE5B7576804DF595142F08431 +:107210009DE715C9F5058C40F97D2FF4E671A91796 +:107220007ACBB8F0322FFAB9ABFEF64639E619E55B +:1072300086DF9B34EE2AB2DB0DF922D5D71BF34152 +:10724000DA6C22DF6C9DE2C3FB64EA02571AEAB3F0 +:1072500092A1F132EA1F91BF52B73693EEB19B3A39 +:1072600021DB50FFC6B53D0DE5577B6B34BE29557C +:107270007D0DCF6FAE196828D78ADF8F605A05ADB4 +:107280001B19FF02CDCDE9E2E175BF583C227F39E1 +:10729000F4FFC5011BBD37D3E3843D4CFBF9F0136C +:1072A0000E1FC6F74EE2F937289F7C53A5FCA29328 +:1072B0003616F680883FA9B06684CCCAD7D59787A2 +:1072C000F9BAAAFA9BCA701FCF7EEAA0F860FD4601 +:1072D0008585F16E860EC03CF4BBEC1907CD7BE6CC +:1072E000469505E97C95B615E3E4CB9E1AE0C3F814 +:1072F000E8F4BED1DE78DEB0E385141F9EFBAA6FF2 +:10730000E3DF9F84FD7926E6472965148FF8E3C4FF +:1073100096D916CCB7530FE4E27AFDE3F3FC77CDB0 +:10732000E62E7973B807F03CEF95AD6F55403F27D7 +:107330005A54EAF7D3A71D9B555AF7FE7CBCDF369B +:107340003EEF08F929C6F708FC09E5FB27B32343FC +:1073500048FEDCC1FDE35DF103F3457A23BFEAE4B7 +:10736000595CBFF1F81B08A1029413F5361FC565DF +:107370004FACB751BC10F401E51B9C68C9B670391D +:10738000F43CF15D9D55B3EBFBAD5BAFFAF9EF63F8 +:1073900068761C2FBB4F0DB21158E6F911E1B54AC2 +:1073A00090C77F8CF4BD75C9083A176DCEE392F093 +:1073B00014ACA9A02EAE34EF451EFF65C3DAACFABB +:1073C0003C77E99F61C10AC37D460B8A1FBE6714E3 +:1073D000C0D37E7EF5E2975BDC24273FB3BC347CD0 +:1073E00039C04F2786FF6005BABCAE068BFB60DE56 +:1073F0009065FD2685E22AC7EFC1B8FF27CFD97C6B +:10740000B40C45DED8BC9FCEA5F854727B81797947 +:10741000FC3A9AA778F1766246F922D3D856E15F12 +:1074200088F03C031C04E0C7B380C7C58E97BBEF50 +:10743000C2F3C3F5A6F3C6C7C5398BF23E8A415FD6 +:107440002F13E57A0B5F9F6C17BF8752FE5E9C94EB +:10745000E352DE4A793DAE4F317D27E52C635B492F +:10746000BECC16F7252F78DAC1CF1769CC83789C6C +:10747000CBC9C456F5D1E8BB79F6E71E42B69EC328 +:107480005A49EF7D628BCC6E2DC2EF373767D1F74B +:10749000365F04D77144FE1E9D95E4C81CC6C7B96B +:1074A000B045894475FE0EF9FB240CF5844EEE744C +:1074B000D10B267D304BE8BF59CC946FD462D453A6 +:1074C000813437CD6B5E8BC8C3EE1C97CACE61BCCE +:1074D0002B187965128D5BF145128C630EEB88E2F7 +:1074E000BDC80B9FE5E798CCE332CFA3BBE39CED8F +:1074F0009B3216EF57EEECD7346E896F8607AB746C +:107500007490789F1DE6F89CBD53217AFD5ED85B90 +:10751000F27CA099FE73586012CAB9390FC03EB30D +:1075200028CE0F920FE66E8BD079C04F594BBA0B15 +:10753000D6C3828DDB6E1C09DFCF79EC753BF27B05 +:107540004D56B4BF25137FAA67F4BD55BD13E87D22 +:10755000939EFF47E18909BF157D077899B545A539 +:107560003C0A5D3D914710267C3584F9EF09361CB5 +:10757000527D4DF0B4017FE6A8ECE2C72BF1F6CFC7 +:107580001EB7D9AED9D6E7FC768D59DE74B16B4CF7 +:10759000FA14CF73A0FEECC8E5F9E95F58FD19595C +:1075A00024A74D7238B78CEE63957278B6D083B24B +:1075B0009F59A8FFA0FC878D3F4F477FC6EF1FF85C +:1075C000791EE56BA0BE1914D737B7D5F3FE6EFB55 +:1075D000450AE54BFD7162EB10B4076B1EFF75BAEF +:1075E000FEBED79305C1D7FAE078857E5CA86EEE23 +:1075F00083BF6B28E5EC05F76DC9E6E9BEC03CDD4D +:10760000C679D6E13C75E754EAC53C8FADE5F33B5E +:10761000BE9ECF776697798629AE72DB930E5F9810 +:10762000EC8E28E9F593DB5486FBAC4EBBC36407B4 +:107630007CC95A36213E162E7DFB032BF0C5DC4B50 +:10764000003FC00735F73948EFCF7D81C7533F5121 +:107650002AF329A0BF379AFE3D783E0FEC05B437D8 +:10766000E2E3E8B403CE221E3BED806EE26F91F0C0 +:107670006B2DDAF96BFA1D2DC5CFF33117C97B6D70 +:107680007698EEB5D15006F073FE4EA4532FF37DDD +:107690005CDC3FFBA7FE9FDFB294F8BFE312FD392D +:1076A000B6C6D4A80DF3903BB62964272D5C569935 +:1076B0005EC9F07C1BF7ABE51472BB56F1FB29BF2A +:1076C000C601744D85FEF20B35FE5CF3F07CF3C70A +:1076D00018DDA323C76B7E8EFE7627EA439785F4D9 +:1076E000A179FEE30BB9DE5CA85AC8BE5E60E776FE +:1076F00076BBB8BFA29F1847BF426E6F5F56C8FDEA +:107700000AED685762BCFB2A07FD8E116363C9EF5F +:107710006E659CFFAC126F1EEBA9CEF54DF673475C +:107720002FC4D32DAC957E177152C5140DCF337C69 +:1077300090E7A47BA2E02F80ED4C13ED1CB4F1F395 +:107740000B1F601F30AF69C23FFD015E8F0AFD7FD6 +:10775000506027BB36FCA283EC863B53B9FF90E513 +:107760006458713DDC2CE4D4F4510E3FCAF569A392 +:10777000EE0C2084F6C20CF055E3EC585D0AFDAC2B +:10778000B4707DBF328B71BF40735B39E2EF7230F2 +:1077900093317F1F66BFFD5CF6F9F8C8787E620101 +:1077A000FA19AE609CC12A08BF86F2023B7F5F5384 +:1077B000F893C90FF462EC779835857A0671847C6A +:1077C000519B41FBDFC978BE200BA195F8ED3B56DC +:1077D00016B670B8D645F72A790DBF0B7B43058BDB +:1077E00066C0FCA2FB8DE73B6E8A5AA203305E6442 +:1077F0008DEE46FC599C9ACD03FD04AA9432C4FB3D +:107800008255DD1B6F63E1361AEF02BCCF0BC7F95F +:107810003D85F285A6C1A2473EBDC5CAF6AA659CB4 +:107820007EC8878D595A98EA2DE17C2ECF9548BAAB +:107830009442F37AFC4E13E38376D6A6E3F7F6C4BC +:107840007E95DB0BE5BE8FDB6BF3C5BA9D2FF9EEA2 +:1078500059E37A7D1CD70DF02DDAB248F76902267C +:10786000E3FB4744FB8F08BE5F5328E37FDDEB6FEC +:10787000A1834569DE2F3A888EB2DFC9026E2CE4FF +:10788000F9D3721C927F67B3C594CF335BF8692C30 +:107890002049283FB8E549EE1732E51D81A144F99A +:1078A0006DF3B6989FEBFC3CAA412E91DF54B17763 +:1078B000CCC4F129DF4AF121BF4FB36F25FF80B956 +:1078C0009E0D7F3F15E36E6BC1AE5244BC0CCA8E59 +:1078D000F50AFDEEC5B45E1D83519F83B41E4FE7CC +:1078E0004285BD3D5BD0D721EEB79A8DF615C6D542 +:1078F000D0BE427C6DE476A555D8C375EB8DF6C637 +:10790000B4669DDDC981E17E0087294FDD26EC8EBE +:107910000FED1D8351EE9BEF0BF8D0C2E711CE6344 +:10792000FC5ECD1CFEDE2AEC4BC9573F2DB419E29C +:107930006DF2DC690DCA2B7E6F83294FCB45F7C7EB +:10794000D428FCFE4EE9877C5FC0D36087D27D39A6 +:1079500047D2280E6EF64FB657BAC3169D9F727A5D +:10796000C66D93103F35E9762BC2F73BEF156BA33D +:10797000FE8F788AC9FE5953397423E6271D2BFCE4 +:107980007CB2B3374553C479A83FBD86F9F4D77F9D +:107990000DF3A1F2D9C97ED847B5BFDC718B134472 +:1079A00077ECDFCF4EB6829E6F7FB0631396532382 +:1079B0002C6005FDD8BEA1A30FDEB99CAAD902F4A4 +:1079C0007EA56CCF16C0F6DA7FCCCB1F15DA027815 +:1079D0009F6E8D38B754738542F2D721D697F43312 +:1079E000D5585EE27034FF5D940BD5CBD6028EC2C3 +:1079F00072BC0FF504FDFE429F62BFA310EAA5F51D +:107A0000099E46386F8A12B6E379FF43914B845E34 +:107A10004BF83B218E42EE6FCD2B0AD0F7D28F0E62 +:107A2000EDFCE59BB4B3458CEB7F0053DFF7AB0077 +:107A3000800000001F8B080000000000000BE57DA7 +:107A400009785445B670DDBEBD656FB260622076C0 +:107A50001212020668208100419B84252C810E2889 +:107A60004689DA2C02622091D131333A7F77D844AB +:107A70007434A84F19079D169161E6A92FA32C41D4 +:107A8000B60EA0823ADA282A3AC04445058D4E4403 +:107A90007813FF87FA9F73AA2ADD75495866E6BDF9 +:107AA000EF7DDF1F3EBECAB955B7EEA9B39F537530 +:107AB0006FAA6ECF49F0E6331693E1353B53185B5E +:107AC00050A1F9AD0318638702B99E38C62633E684 +:107AD0006E8C65EC27FCB93ADCDAAE303106E36F28 +:107AE000CFF4D8AE2864AC2A3C4FDC3F32CF21C360 +:107AF0003C376970EF30F8CF5C4EBCFF866C771F67 +:107B000027F4DFF67F9817E761A34798D810C67E61 +:107B10006667F4F35DEDD65C7B01B4CFD99258264D +:107B20008C7B615BC65C9887D5C1E4698C7DD5FC94 +:107B3000A1D509F32C6AD7993B89B19A768DDA459C +:107B40009B9AAD63615C0DB4A511F8550B7C196B64 +:107B5000314F8D0B5FEFEF047C0BF1FA6AC2FBB67D +:107B6000174E9ABD30EE3653E3E74F24C3E5E19A52 +:107B7000EB59E7B9EBECEEE4EB3CC6585963FEB9C0 +:107B8000FD054E8DFA7F9DE31E8CF44B8139F03953 +:107B9000BA89AFD738FE57028FAA6876B307FA675B +:107BA0000F89B33B81DE8587BC4BE3008FB96B3314 +:107BB00007E93047FF8C929148373667B842AFB239 +:107BC000CB190BE1FACC6DDD19B4DFED284C6080E8 +:107BD000575562E80E3610C8E6CC69B08F646CE287 +:107BE000E330E672BAC5CDE0DE329B848B3DA38BD9 +:107BF00001FE51277846A0B0C10FF3EC477C609E90 +:107C00001B87F68B66FD817A993126470263237BB9 +:107C1000CEACC375DD3874E458BC3ECA16973B93AE +:107C2000E8CB483E46F6F44C433C713C837578AD56 +:107C3000C194EB601DDED775971FD6E1ED1FE30DF4 +:107C40007442B70A41D73AA783E8B1DF04780E0A35 +:107C5000E3219FCF98E38E10CC777C49DAC0553072 +:107C6000DFDA9EA3EE427CE4F3D7F6F4CE897C3EC5 +:107C70002CB73F5EBF583C660A3CEE42BE41EB2942 +:107C8000063913B4FE09FE4F1D1DA3C0D74C4A622E +:107C9000EEBC303CFD9A7405AEACCA56C6DF30E788 +:107CA0004AA5BFDC162AA88D0DCBB7111FD932E625 +:107CB000277C6AE236C63340F1E88E33EFCF003DD1 +:107CC000F9DB7ADDA501AEB7EE7CF6FD1130EA14E2 +:107CD0002C3809E876CA0D00ACF7D4263DE0CF4435 +:107CE000F9709BCBBB33361FA782F10B0FBC641D11 +:107CF00005BFCEAF9D3709F9786BC0F2494B049EA2 +:107D000067D8592BCB027DD8A85EAF610F7CABF74B +:107D1000472868F5F483791A0DFDB5E3BE60F138A4 +:107D2000CEFC498B5C273CBFEE48E683FB22D6BDE8 +:107D3000C61997FCF995F0CB2036E8271D9FD7FA96 +:107D40002AAC90953635139F961ED05D28A24B7BAA +:107D50006A4C83758EDB640B44816A7DBDED63AB39 +:107D600013E8F5779FF3C17D16D4FF7AC692F0BE73 +:107D70008FAD2D70BDC8E9243A2DDAF1AD9501DF44 +:107D8000C7EDB89DF47A2CD8B104909F5033EBB76F +:107D900009E6F767C6B99E85F96F5B399EB1C18C5C +:107DA00025B4CFA0B6BA613CCDB7B07D1AC18BDA8D +:107DB0006308DE1F1D1ACB008FFD5BBAB1A580C71B +:107DC000DB7A30F7B7388F2D8EEC4479FA8D4B7013 +:107DD000DDFBA3FDF93F83E795FFC7B832A4EBA213 +:107DE0004D9A1BE5AC5C67FBB544C4378AE62BD7DC +:107DF000DF29B81DAE4F2C8DF39B12A89F31E8D719 +:107E000087C4AD6200EB56B0179DC8E73E615F2C9A +:107E10002D1CEF31ED15349FEC7FDD9945FD12B639 +:107E2000A4AC37CF8A0DAFC7D2A2513BA1FD4A6A9D +:107E30006B3655989DF09CD7F39E49463AC1F85849 +:107E40006FA776796802EBC47E75D87F618F67A0D3 +:107E50003D86799BB3DC2DA88793EF6931DBD19EFA +:107E6000C6DA1DCF821C4C2E1AE89C1BB12E7DCF8A +:107E7000F5CC0972644B6EB3B861FE19D046DAEFE7 +:107E80009BBBF0379F0B3D65AC9EEC85F44BACC7BC +:107E90003D0CF1BEC9C1F1967AF5AE182FEF0F690E +:107EA0005C3FFC9B6D8167E1F78FB2BCED68474298 +:107EB000A358E58B644F43191571FF3AFC81BF76D7 +:107EC000E47FBCB98525C2FD3F74E0CFF5FA42F8E6 +:107ED0007F25FCC4DB3AAB43B978FBEAAB436EC009 +:107EE000ABF9EEC183D13FC8E7C5675AF9BC8EB67E +:107EF000B328AF35BB629CAB607DE5C01B84DB76ED +:107F0000DA02EB32E93AD392B1B5ADD3A0BF26BEC7 +:107F10002D17FD4FE9EEA820CA6DF3EE2833FA9134 +:107F20003D39DEF8CC14BCDE7BB406F2EDDE613305 +:107F3000A31C2439DD0978BD2B7C2F64C7A43E1A0D +:107F4000E5CCBB92EB9F57E8E14C21B7B3841ECE42 +:107F500034BB12EE02BC6F7E536768C767DDA3F5C2 +:107F6000DB5480362DCE9513A18752DF2C289783C2 +:107F7000513EB95C56B77713FA9D29E6E57A500E63 +:107F80000E1AE9537E65B700EAF7A2F6241A27F520 +:107F900055EA696AB6F7AA4CE043F952D06F788E79 +:107FA00077495A01EA4B584EAC0E94279093D4B9B6 +:107FB0001172B0B4F97B33CA89A5582339B1415B3A +:107FC0001A21479E8E38C531B63BE0317959A669F2 +:107FD000150BF79766CA78E5E2E4DD95C9E56B56BF +:107FE0006C30C704F3596AA35C4B00AF53C94EB25F +:107FF000638BEF030048B0D8E229C53863F16F34D2 +:1080000017DA5F8C3FD0FE0C395C6BF546E0777D6C +:108010007B7FE6043A4D6BEF456DFF0C6F05F27FF9 +:1080200066FB7441C7FED432679189819FB9C3CE84 +:10803000FDCCE9DA7B6FC2E79D0ED85CF83CB0D08E +:108040009CDF02DF42B7EBB2BB10BF372DEC6918E3 +:108050007F22CAABA35E9EE8C91C8F008AB3D700FB +:108060009F61DE1316E677003FE700EC45B81B730F +:10807000771B847A07EB8CF02B67CC0D192C1BF83F +:10808000BBF88363663085B7E686FA07E1B955A386 +:10809000B8FF6F5D6F21FF5FDDFCCE1013F47F9999 +:1080A000E9BE8C81ED1D7BB9F7365CCF82A98117C3 +:1080B0002C00DFF6EB97E28739C3F46C340773CCFE +:1080C000707F23D0D10F78353EA0970578DC13530D +:1080D000D1EFC272BDA03D9BE823FD8DB4DF5B7D77 +:1080E000A9B088B01DBF901F92F2BD50E8C142D424 +:1080F0000316E96F2A3CA3500EF334570E8BF43766 +:108100005C1FA49D067927BD29CFEEE95ACAC27625 +:10811000DBE88FF6EA8D8F0C87F5FAB2BC4FA2DC54 +:1081200097FCFB7FBDF4117455BFF887D1C8A751E8 +:10813000576A4CD72EC64E7E6F213B794F05233BA5 +:10814000096DA49DB47411A7AFBB44B96F10720F31 +:10815000F12DC58D68C723E7FB28AB6413F2795B6B +:10816000A6C6E7FB17E16DB4EFDB3AF0BE38FBFEC5 +:10817000FBCC8BB3EF6FA27D2F3CD79E33980FEDD6 +:10818000F9DF76F609A0BD3FC6C0FEA37FDB11E391 +:108190007C56D87BF207D10981F3D9FB5FE7CC7E0F +:1081A000B30B7BFF67E4FF3F6BEFA57C19F5C1A81C +:1081B0000746B99F783FC45FC8A7AD1A43FB1A8E24 +:1081C000B718C9F1FE2C2EC7526F22E22FF2F3A08E +:1081D0000F819CCC73F5F2BBDA0F0A9C986F16C422 +:1081E0000D645A58DEA5BE487937FA913959DE1F19 +:1081F000C90F083DA97ED1E807BA92A76D16CC5FDA +:108200002DD5DF723F006DA41FE82ADED1B32E2DDD +:10821000DEF9F622E5A97B168F17FE1BE5A97B5632 +:1082200061A7F27459D63F113F9C878FE467A49CE5 +:108230004D7C83CB07CBE6F13EC80BE1BDDFDA33E3 +:10824000B03413ED1EB787137F62B548CF9B453D11 +:1082500041CAEBA86CEF88AC083E637C8F71FBC50C +:10826000C68533926B991BAEDF0C6DA4DDB021FF88 +:108270003A89EFDD599766EFFA0BB9B8109F2BB228 +:10828000FEE5716155677C656EEEFFC37CB14D43C1 +:10829000B9F92E6866A85F5DF1D5B286D35DC2CB11 +:1082A0008366E95F93D0BF82BCDC98F54FD89FF21C +:1082B000D2C6D37608FDEECE1A5E611E06797A111B +:1082C00013F58F11ABDD66B42FF0EB709A91EA23B2 +:1082D0006FEB122E3E381AF098F84847BF1FFBC7C5 +:1082E000142774D453309590E37F9935ECE00384E0 +:1082F0007703E7A3B7C5ECE9170117001C170117AF +:1083000019E0B57C3CFA1107CD13E0F61EE6D7065E +:10831000212CE7137AC0DAC676C3787193E6C07A67 +:10832000C80DC57FB3227FCA4B5B5E4D87F53E9873 +:10833000555A110B21C00D680701DFA7B226AEF612 +:108340009BC5FDDDA93E463FB646CDAD039FAA8B3A +:10835000B44056E6B9747C2A4BF567F86356EF676C +:10836000D6824BBB1FF948F767D1FD41DB253CFFA7 +:10837000BA62E60E7462279F9376F22CC0727EA0DA +:10838000DDB4469E871BC76F12E34326D34206F433 +:10839000DA9175F36AAC978D615C3E7665DD54E1E8 +:1083A000CFE7E8BA0DEB3D1FBEEB3A59AF53BD3FE7 +:1083B000783E7A6D3CE77E211FF3557949307BF694 +:1083C0007D077824246B0E8C6B1779A21EC0F8BD34 +:1083D000BC54CAF7AD15EE62585F1453EA7F61F9D9 +:1083E0005E50311AD6B788C9FEEAD5E8973CA68E0A +:1083F000F15CDE77681DF7E781FC50290EEE3F9CAB +:1084000075DB6AA40FF083FA09369F47DE1B0D70F7 +:10841000B1413F847C937EA2DD06FAE4746237CEDC +:1084200008BE7DADB14AB47BA1121EEF85B2789B28 +:1084300092CDEB243F083A5AB2791B8A8EA0438F23 +:10844000309FE127887944C4BA894ED7278B75FBC2 +:1084500057554CEA05F727B27E1AC849C2332B5646 +:108460002FEB19BEBFDB33AB484E3AE6F3AF3C8887 +:1084700074BC5ED029E599FB0E0A39D250EF1692F2 +:1084800040801C6CD2FC3AAC7321CA4127EBFCEB58 +:10849000B972E437DCEFB69CE7FECFCEBDDF6DB836 +:1084A0009F59922FE57EC1A749063E9619F838DA02 +:1084B00000574938A0D83369E76635AD5EDE3D190F +:1084C000EB8D1ABA09B4D7566D20637DB31FAD8802 +:1084D0001D86F2EAB4A483CDEF9FFDD8413BC8725C +:1084E00005DA3392DFC7C97E4F437D27784D857B00 +:1084F00000CA4FEDF254185F90FD9BD576D0AF1BAC +:1085000096ADB6604C5394FDDBD56698F7FA82FFC2 +:108510007815E7336B4F1E9C94791E796D30AC63F0 +:10852000AD01F61BC63F7A01FBBECC70FF3D86FE57 +:10853000070CF01A03BC52BD7FE61C8DF46426F0D4 +:108540000F097721BD999CDD111776F8332D96E23E +:108550002445EE272EE57065F6BF57AC8C8D809FC5 +:1085600079AE22528E2D8CFFCC48667EF41F962E5B +:10857000ECD9D86CB5DED5B19E3CA3BFE3FD7FC579 +:108580005FD3689F45F1CB7B75156ED6A5BEBD7CCC +:10859000F08E58BC28E16D1558BFE872DFC3BFB537 +:1085A00002F73D263E24FBB756B823D629C78FFDD8 +:1085B000E1271D9FB7E8992D15EBA1BFAA24988349 +:1085C000F5FAAA44DE829FD1D18FD5887AC7D89D8B +:1085D000BA07FD4C55743067717EC43A59632EAEAC +:1085E000B3F96E9DF8E35FCAF39159CC65C57A453E +:1085F000734242DD0618BFF76EBD0EFDDAB1BAA4B4 +:10860000EE984FECCEE6F9DEDE842BBADF02707313 +:10861000CCCD56ACD736DF3B86DA3DBA7B451BC89E +:10862000F103D9AF56C4F6C1FE04A2CFCA679A2B94 +:10863000EAC15EDD9FEDA4FBBD898EEE4D18AFAEA5 +:10864000B230AC5733E67A8AE4E6D7B681AB008F16 +:1086500099F557D2FED1AC7FAB189B06E3662DB7D8 +:10866000D0BE02FCF447BCBDABC658B17FCE32D100 +:10867000FAC751BBFBC797DEE80FE3DBEED35DEB38 +:1086800060F0AEF6ACF85980D7A751DC0E7FD2DA95 +:108690002B1EF1ECD5CBFB7836CA6B7C5CB486CE56 +:1086A000C3E18C9F0AF366E6B8D7E075397EF78F91 +:1086B0003AED836D6F9DD51DF9B74EC8CDAEF65915 +:1086C000DD6745F8FBB95F9B89CEBBADCE3B30BEC5 +:1086D000DC1DDD53C3BA0CD03909EBB673447C0DF5 +:1086E000F252F752277EFFA16C9DE872DC56C73E1E +:1086F00005216EBE3FA518F194F7C9FD374B0FE772 +:10870000A0C838FA775794BC909D122967470E622B +:108710007C4F7134C0DBB23F5CED07BFC2F642FC58 +:108720008F7824BBC7A25CB17B92F83E686A636E07 +:10873000643D221CA72E11F6808F3BEA8FA3BCF567 +:10874000E8735101CC678EFAFF1217597F977A327E +:108750002F3ECE8FCEF88BB83833D2F598D9F7F9B3 +:108760002F70DFF0490BD9D1B94FA6DCD386F600C4 +:10877000F889F520E373937A59689EAEF707BF54E2 +:10878000F5C47FF2BC7AF26EF6C98AF5F95DEBC9E1 +:108790003C11B78F7DD2E241399F571867C67DBA29 +:1087A00092275F7916E571DEED51836C80F8BC2766 +:1087B0006DC4DF96B838BF03F711E3E3CCDDA03D0D +:1087C00021EC574B7D14E5297A772BD93D7D45A1C6 +:1087D00013E953AA33B31DFC8A1EEF727A38BC0C1E +:1087E000EB86CBE38A9CC85F472FAE0F1DFD099532 +:1087F00013B4FEE17DB393758F3C361457CD02D38D +:108800008766FEF3FB6835CC9380F5C7FFAE7D34F9 +:10881000AD575CF2E7908A87F7D1F213AE43F1AB24 +:10882000D3096F7D495400E9A967703F318E69B45F +:108830008FC61CB0FE7EE17D34FD9783893EC77DE7 +:108840002057BD812EF1761AAFFF520FD8E0B9A59F +:1088500049BCDEAA3F56C1705F0DE8EA77003C2EA6 +:10886000B996F6D77E25ECCC4C8D791A49FF5D1967 +:108870009827CF7D328AF838EFA95BDFFF4D01F2F0 +:10888000AD3C39529F7A08F983F9983D313CCF17B6 +:10889000F5BFCA407C4A7F07F925E69DBAF7B1EBE0 +:1088A000C96EC6D07E1B73B4FC7A28CA4B7DCC40FF +:1088B000AC93CF7B322D232B3F7CFFBC2577E7F297 +:1088C000FB216F8D47BB1545EBA9DE6423799979B0 +:1088D0009FEE263FD9D34A7EF29365510457F7287D +:1088E000227D9B69E2FB6F1013A6927DE72467D57A +:1088F000B1CCFD522CDAFB07423AE78F5FF0CD8A0C +:10890000FC19DA2B899E7F33D218FCD77542DE66BC +:108910009AB81CB15D1AED373156EB443B5065D225 +:10892000C8DE19F5B2AC178F5F6766B86EC2FB166A +:108930003E68732DC9E438E8121FC89B169A42732B +:10894000711F926DB1517DA306D61115CFCF3DBCDD +:1089500008F8D79899D98AF52927B76B129F1A6713 +:10896000C5389457E83F6C86FE8571DC2E2FECC627 +:10897000EB3E2CCE1E7836F279887336BFCF198F36 +:10898000FA368CE405F5DF04FD7F63BCBF34BEC856 +:10899000D9924FFBF72BB15E82F8F4E91FF15C80AE +:1089A000D3FAA33CDE6ECE8A433E244DAFC4E73DEE +:1089B000AF937D02A57AB008E3C0E7F5C198CFCEAA +:1089C000BC6FEFD83508FF69A0035198F9C2BBE42A +:1089D000A76E1372D682F13FFA2D80FF046D6D2FC2 +:1089E0006E1FBC3AAFE7D4F6E2755E4957D9BFF0C7 +:1089F0003E0BF163E1722E0F0BEB3FA07917C6859A +:108A0000BA233F166EB60C41B9FE85C07B567DCFAA +:108A1000E2C3201FB32C090E0D2E55FBCBAD08571A +:108A2000376804CBE72DBCEFBDEEA67C3E1FB63603 +:108A30002147E1795332D0AF7DF55C52C6CC08BEF8 +:108A40007FB56C6B3CEE6B7F1A15CC71603DE6F622 +:108A500028D73AD253CE8FAF96E5ACC37ACD1C4718 +:108A6000280EF7C3E7DC919D88FEEE982368C5FECB +:108A7000638D992684DD0E4731C26EF30082BF12EA +:108A8000E754E807F8B448E37253FDDC5E6B163C2C +:108A9000EF29419FAF9F7F3717EB060B3342B9E8B1 +:108AA0008741AE72D3912F7FD4285E58F49CEE8E0E +:108AB000EA1F96AB452857A0FF0B845C2DDAB4F56E +:108AC0002ED4D345284F83CE954BC82FF7D1F51719 +:108AD0009F1ECBF8FDFB50EEA4DF07789905EB6BEA +:108AE0005601C37310FE1DD23F85FA47F37E7F3EC9 +:108AF000F913D662C5B8B846E7F102703615E389B6 +:108B00009A268BBF25C23E2EC2FEFC707F57721381 +:108B1000EC25F6CBEA6DE4978242FF5AEEDB1C8F20 +:108B200072F1F5F37B5F1D8E79D68B9A03EDFE39DA +:108B30007A28E85683748AA775527C548374890F07 +:108B4000D3A943DF845CD4304E0749971AB3A0936E +:108B5000EC17F7370B39AC6682AE9B7A737D17FA48 +:108B60000D12437E44AECF9BA89E1F3825E4FE6DB8 +:108B7000B1CE6A901B573EC997DB3A44E4FFD0F56B +:108B8000F59F9EA6FA91E4A7C43B3A873F1FECB439 +:108B9000BB5B6298CF2D2636BFB37AF56742AE2C09 +:108BA000B1DCAE7C5C9F7E531DD06FC173BA8B88E5 +:108BB00087B957C4736DA696388A4F7FA93B705DFD +:108BC000A5FF5E3101D72DE5CEB2513337E13E210D +:108BD000EB46F497F8955EE699D08DCB5D10F19158 +:108BE000787EAC05895FFE3F690E1EEFB658B18EE8 +:108BF00028F5D488EF2981AF1EAF0DD706203E2E71 +:108C000027EA37033F48F8C41EBE9B9EE73F7A77AA +:108C100066FFF0738EF9E3CC38EE18E37640CAE5D0 +:108C2000C7A22EF1F1F2AD140FCBE7D873B85C45B3 +:108C30003CC75B977CEE733AE2BC1C8E97D48BFDED +:108C4000895CFE4B977D40E3A49DC51FACC7497A64 +:108C50004ABA45E8A5421FA95F529F245FFF51BD54 +:108C600062F7A450DC7AAF5837E948F7B05F40F9B3 +:108C7000447F67B3F27370117E93E29A713DBEB583 +:108C80007A3BB92EE964BC1ECEAB1C1948FF71B10A +:108C9000A9B45FCE96A5EEEB15119F7D8A752FB412 +:108CA000A77FD003644F196865843F97715BFDED22 +:108CB000E31CA350BE9ED3E8DC91F4DFF0F34087C1 +:108CC0009CC27CF30B6ECFC57862794E16F767C9EC +:108CD000EE93787FF589D0D87867387F19793AA8EC +:108CE00027607D7053A6923F54B7EE233D5FC84284 +:108CF0002B30DF9D79DFBBE54391FF7FB0D0F98555 +:108D0000390D99E4FF4EAE9F3D1853DB99CB7308A4 +:108D1000BEF5D95B387C1F8FEB662E2FDC80F5F912 +:108D20004FA3DC6351CEDB566B0ECCBF463C5B7869 +:108D3000CF0DD03F22EE8A6E88EFD1F59F960FC7F8 +:108D40003CA24E27BD71AF7F643AF6BB9B74172ED1 +:108D5000710E73DC7303CAB93981F44E9E6B5C6A81 +:108D6000E1F2E6CDE176A33287DB8D4A21BFA54B48 +:108D700097E6E2B982B6A7C14FE1FEBAD5D918C4C9 +:108D80003C70E765AE75F09C1A485B53419E4E6897 +:108D90003C1E9F6F657694AF0396D09D88FF813B04 +:108DA000E306D62302FAD921A81F6E9177411E450A +:108DB000CF95F492CFBF59E8819C47DEB71FE32AD5 +:108DC000F42302DF93CBFE301DE385931B7312590E +:108DD00004DD4FE2BA80DEB7827D7CB1937CB03A8D +:108DE00047D6B902FC39A28E78C0D2D003F77321DE +:108DF000AE3F1E199F7FF174941DE512E27AF5BA19 +:108E000085FB1588E795EBA03F0ADC91EFE9550952 +:108E1000DE4EEC916C8DF1BE2F27B6D3785FEA9FC2 +:108E2000F17E19DF77D45D7A5DDAB9AE561F300670 +:108E3000146228066780EFE8981F5EC2F397731BE1 +:108E40006C0E1BD0F738EA17EE0B6ED679BC68E7CC +:108E5000FA767CE7C000D615E61E61AE20C0730F1F +:108E6000E92E278CDFB7FA5E3ADF71CB5A8D5DA60B +:108E700045E45D8FAE9E8EEA76CAE55D9106E34FCE +:108E80006DE4E751A03BD6906FBD9AE6EC3ADFFA6D +:108E900057E559B2FE64A4FF7FE4887CCBC55C2A09 +:108EA000FD79DEBE1BC4A868D0B9F46FF57929AF8F +:108EB000FAC6379FDA618D4F97A6C33AFEA67DFCAE +:108EC000E008D4A3B804AA9FB4FA6A6973F09BA619 +:108ED000C16727039DB6C72638D07E7CE3ABA3EBE2 +:108EE0001D7223E474E4A6663D9DD1F81D2360FC49 +:108EF000AED804DCEEE8641F8EF3D978FEE667B7DF +:108F00000FBD0CAFCBF57EF90BCE6F89FF971B67BA +:108F1000C763BCDAFCDBA41DC390CF31090E1485F6 +:108F200079E21CCEE76BB83D3A614FD88075D41317 +:108F30006BA775C7FCF0164B9BD505F3BA7656C4E4 +:108F4000637DE433734BBC035B181F443CCC011DB1 +:108F5000EDE0F03246FB83C38366E6CCA4AD7B92A2 +:108F60009F61ADE600E6CD5FE1BE21FAF1B3D17CB1 +:108F7000FF5EEC07DEB28DD7D93AEA2AA2BE3042B4 +:108F8000AC37363751EE03D1F5D2227EFD8BB52FAB +:108F90004DC6F94EAEB73810DF6FD65B68FE059050 +:108FA000DF9B401E4F6CE4E70516EC803C3913ED67 +:108FB0008846F2BB00E4D78EF277BBC56D4D3857BB +:108FC0002E4B37F2FC7A41A346F9B694CF05EEC09A +:108FD00058A2BB90533BFCFB095C4737D6B802E96B +:108FE000D195BCFEA3F5003DB7F37A80511E24DD78 +:108FF000A45C84E594917C4AFE27360E1C954E377E +:10900000F8899EFE129687F1C2522BCBC3F3507E95 +:1090100053B40BF5FEEF51F1FDB10E5567E7ED5D71 +:10902000D1F1EBB0FD7B544600F1FEBBC9F10AE67D +:1090300059BFCCCD24B9BD4B775A34F8755A72CB91 +:10904000687203A526B709FDE0521BD911A31D7252 +:10905000E672FFB32D97D1FDC5B9FC9CB885D552FA +:109060007C215B88077A62FC52119378068F92F715 +:10907000CB4D996606B9AE1891786736449E85B98E +:10908000E9D370FFB76270E2E62C80876E48E3FD9B +:1090900003120B2D00D76B3DA68D86FE6B72DD573C +:1090A000E6463C47CE0BD7FBE3F59234EFC0DC1429 +:1090B000F473B12BD10FFC4D6B5B64D2C3E30F6A29 +:1090C000ECD8762D0CB7585806C6DBC5887F4AD732 +:1090D000EDD25CF770FE5CF5FA2C0839B02E31CB7E +:1090E000FFDA618DEC19F3D8819F5384FCCDB2C7B0 +:1090F00006C9CEADB4B476C84716DAA90433F27DFA +:10910000B260FB1473B019EFEFC396393EB753A8A2 +:10911000B8F6A7A4AEED3F282AFB5CCE07EBFB9B7D +:1091200005D60B7CD5DCC06B50310D885C05F64E46 +:10913000DBF1DAF738EF523F6B89223E5439F07C8D +:10914000B7C6BCA69FA05D18037231005B900718DC +:10915000B778F3D7FB502D6E957196B788E2C53B73 +:109160001C7C3DCC3B9CE4F54E21AF5FF82075079D +:10917000F99C120AC5E351D8D6C9C15CB40F65BACF +:109180007736F2E18BB54B7B2C06F9F9FA459B6BF0 +:10919000128C3F1178291EFD6AB588F7D9593D78A0 +:1091A00035F4EFCFECB36E55847C55E772BFDF9A90 +:1091B00019CCB81BED4C26CF57D9D9BD1977C3F8B8 +:1091C000B2ACF185AB880AEE45B911FB9393CD9D06 +:1091D0009FDFA8E8C1E323B69EFB639B99F9E312E6 +:1091E000A965F140A7F1804B119E4B0558A7FDFCE6 +:1091F000003D1FC7C5635CE39C9DCAF77B9807EDE4 +:1092000096E4AFE4DB39FC049431AE37D99905D745 +:10921000DB87AD75A0FE4BBE7E21F4F10B3BD7C3BF +:10922000317A2CD9A9C59B795D6FB1C6EDEDE29D70 +:109230001AAF6F9EE36F37AF409B3C7FED6CB26718 +:10924000D28E39E11FCAD702872721E8FC07FCEE3E +:10925000DAD28BB2674FE68AF70406B281287F170D +:109260008A97A41D03F6ACBF247E21C960DDF304F8 +:109270008E63F42AA719E9926277A13D5FFC6436F8 +:10928000F94976620D8B1CC7D62691FCAEC8D489ED +:10929000AFE54DE9CC09976E6DD2E89CECA4A6240D +:1092A00082E3DBD3082EFFFD6525B8EE8E7DD0DF8F +:1092B000F726F8E486370ABCBC4E63C7F93D4CE29A +:1092C00091DF88FEE7542CE00174F6C4AEA4BAA383 +:1092D0008775E443DA4F1AC22035A8776E8B9FF367 +:1092E000C75E4FFA2FD6B558E8D5E203DC5F2F1ED4 +:1092F000C5F70BCDFE3E09C87FCB7E9D0500BEF6AF +:10930000805E1884A14B853DB7A59A9833826F5132 +:10931000CE68E68CE00FF3BB43986F550A79B937F6 +:109320008ADBFD98BC44655C65EC5C929F50C6D8B6 +:10933000FDB8DE38D7E5CABCCCCBE3632957D345AB +:10934000DD7C326B5B867EF2DA4AE88F98CF52FC86 +:109350002DF90D4BB11A57035D8E9F4F9EBE90FEA7 +:10936000B10FEB43F264A00FE807F9FB5387F8FB5A +:109370002710953C5E0CF0F4FD161680FEE5822E5B +:1093800018B762FE73CA1D477A23E52E847E0FEC60 +:109390005C42914AB76E6E956E49652A7D523C2AB1 +:1093A0003D2EABCC52FAD3BC7D95FEF4F98314B8B4 +:1093B00067ED7065FC1575250A9CE99FA08CCF5E52 +:1093C000395581731A6E50C6F75E334BE9EF135867 +:1093D000A0F45FB971B102F76BFCA5327E40D312E5 +:1093E000A57F607095D23F78FFC30A5C187A421956 +:1093F0003FF4F03AA57F58CB1F95FE11275E54E04D +:10940000916D2F2BE3AF6EDFA3C0A3D81BCAF85218 +:10941000FBBB0A3CC6F11765FCB8D44F95FEF1CEF4 +:10942000AF94FE8979DF29F07211E794BBFE4BB946 +:109430002FC496E5A01C3B7B788B7A53DDE784191B +:10944000F5EFF08D1A4BC2FC67FF3407E9FD25E606 +:1094500081EEDEAA1C9F61B137E179F60BD9C50C0C +:10946000114F8CD127D17B55A71A79BDC3E8D76599 +:109470003C97006ED91CF1DC6E6E3B24F46138A978 +:10948000CCA1C0299E5465FC65954EA53FCD9BA7F8 +:10949000F4A7CF772970CFDA2265FC15756E05CE5B +:1094A000F49729E3B3577A1438A7A15219DF7B8DBB +:1094B00057E9EF1398AFF45FB9B15681FB35D62960 +:1094C000E30734F995FE81C1954AFFE0FD0D0A5C82 +:1094D000185AA38C1F7A38A0F40F6BD9A8F48F38D0 +:1094E000D1A8C023DB9A94F157B7071578143BA095 +:1094F0008C2FB51F54E0318E0F95F1E3523F56FA91 +:10950000C73B4F2AFDD55FB982B42FB59DBFEF2A67 +:10951000E3B98979DF2AE32CC910EF63FD9B45BBD2 +:10952000F0BC7F5771BE8C03CB5DDF2BCFFDBB89B9 +:10953000C7E7BFEFCDDF4FBB4BE771E252BF87CE2E +:10954000E725E28157D09304BF46F287295615D507 +:10955000239369DF825CA613CFBB411C0440A22980 +:109560003313F39098701CDBE3A7C1171FC76E86F7 +:109570001C07F138DEDBFBC7DE8598B7FD692CE6FA +:1095800039B732FF0AC403FC6E02EE63BD15A5D6DF +:10959000A3643BDE0E748C78DE81A8861E83CEA386 +:1095A000BFE3EDAD34BE635E51AFD2607D8B23E689 +:1095B0007F10F22F33E869830FF40C12ED877D0ED4 +:1095C000821FF5A512FC98CF49ED1A5F1EB54FF822 +:1095D0005CD4BFD65744F0533E37C1015F19B5EB99 +:1095E0007C1EBABEDE5749F0069F97DA8DBEF9D4CD +:1095F000FED1574BFDCFF9EA087EC1E7A7B6D1B738 +:1096000092AEBFE86B2078936F0DC15B7C016A9BC3 +:109610007C1BA97DD9D748FD3B7C4D04EFF20509A1 +:109620000EFAF613BCC71722789FEF30C1AFFA5A73 +:10963000A8DDEF3B41EDEBBE36EA7FD3D74E70ABF2 +:10964000D84FF8A4B7A6BCAF2761C646933CC8F86C +:109650007732E63D281C45966F94BCC7907F18F979 +:10966000F1A5788EA504C25F8C7F2ECF5DB7342222 +:109670002FF8463CEFDE68E68F027DA837F1BA404E +:109680007D22A3F7C39888CFE709B964C93C2E9F10 +:109690002BF09A27F4A010E5338FE4F3CD4BC9B338 +:1096A00064BE1D93E1FD91E4B3A7C94F758758FED1 +:1096B0001E7EFF0CAF9607FDA76A6F79959EE77037 +:1096C000E5E243CA6DC194EBB09E7440A73A6C5773 +:1096D000CFAB11EF4974D9BFEB640FF447653FEA94 +:1096E00054AF7FCB125789F596A43C5E874DCA33A1 +:1096F00029EDD60C4F621EEEDBE7D46EF899167E8C +:10970000FF7F0AA6E6A0E715CC69A173B8CCFD0AD5 +:10971000BE7A732D047C085FC7FCD48EECE94DC77C +:10972000F55C0F0906C2DEE1B68CCED663C42747CE +:10973000E09323F090EDA10C4F2FC4E7788E5BC12E +:1097400027EA0AA73857DFF614E2F59F3BBFFD5C16 +:10975000CB0ED35BD637568C12E7B46ED7E43E38C7 +:109760008F13ED4CC689D45F7527AFF7487F79A476 +:10977000A3E5F6F054AD85EC669516EDC278FB5482 +:10978000ED9D0370BFF046C8F770FF54DAD12A8010 +:109790004D0057317EEEA2EA481CC999D1BEC27D68 +:1097A0000CF7FBAA2004C0FCF16C06AFA7BCE5F9DE +:1097B000D682F3B2E4367A6F15E4660CAE7FC13020 +:1097C0009DBEDFF0962990ABE9242F560DF09F97B0 +:1097D0000CF2D249BC20E56291782F475E07799B55 +:1097E00082FCF966DBD03CDAA7D935CC89F45C6A17 +:1097F000E2EFD5F95FD7F9B90C2CE5E3B99184FC18 +:10980000A7E9FD020C2E907FC3E2E8FD82669DD59C +:10981000FDA9137B5A2BF8F856AAA52C40F3AAFBF6 +:109820008AB7E6F1FACFAD795C2FCBF71CE889EF68 +:109830000D2EDA6FA1BC8815B4E47B3A3957555325 +:1098400077FFCF7B45C8794DD3C7FC3C166BC98FDA +:109850003C87B552CC2BE54BB7C6799F8E8DC4AFF4 +:1098600043CE6B849C7F8E71FF649B33E13AB8B525 +:1098700005481384D6FB3B079DE793E7FAE6300FD4 +:10988000B5F380DD28D71EFF6A7AAF7E016BA4EBAB +:109890008B8A6667205CC3DA46A7C27CD7AEAC7FF2 +:1098A0002515B09BD6B07A0CD6B9A70666BE826DD8 +:1098B000C57AED73BF93F4C48FCF6FD16A975F0EF3 +:1098C000CFBBE1B951CBB18E3C59E77C606F703EA4 +:1098D000803CB9F5C473D7077A71AFD00BC25FEA89 +:1098E00045D512E6D692C3EF8174E849D16D7F4D1C +:1098F000C73D16731B9D43A9D9654BC4FAC902C65F +:10990000FD76B80EC4FDB5D4832F2D9CEF5F3EAF1E +:10991000D17B365F6A8CBEE7D055DC20E34FD03F69 +:10992000AE77C762B8FCEBA2AE97E14D1D941DF671 +:10993000CF5F9A0243E2B3C97F3F83EBB194781FB4 +:109940001888E7F55ED05C4B01972FBB0532F839DC +:10995000810E3FC07E8A09D7091FB4F0BA9D31DE5F +:1099600095EBE80A4F9B95F9713F4B2B7AF57B8C71 +:1099700043CEC5D79B3A04E8B214598475C9128FF7 +:10998000B3333C9689E7EFFF81E7E3FE9E8CCE057B +:1099900019E9A939F873BAAAAFDAA2393ED24F4908 +:1099A0003CCFC58BF3EBADBC4C5E6714F831E6C819 +:1099B00073C0F3CDE66817EA6B85D9FB67D473599A +:1099C0007F9379F1FECC2FC81FB0B34B7BF0F3C768 +:1099D000C1AEFC706B473E9E15F693B28EC58A3BB6 +:1099E000AF477AEC0EB25F53998BFC451F7644D299 +:1099F0008BEA583AEE10529DD74BEBB0A1BD86369C +:109A00000AEB28E42F0324AF318817AD2B841511FE +:109A1000B63A269EE830FC30233B3D1CD700EBDDF8 +:109A2000F9310BE079AAE633D34BE3A07FE7D766A1 +:109A3000CA831E8F79211DBF23B1F3E4FBE958EFE0 +:109A4000A93FB385E021AD634FF2FAD9911938DF10 +:109A5000F6D356A78DE280DB890EB24EB99D311741 +:109A6000EE83167D184BEF19171E6A8C21BA89BA3E +:109A70005AB15877F1695E0FD985C030C803DAACA6 +:109A80002C18112F5B1C2A5CC422E04C7C24C011D2 +:109A9000758E4BCD1FED7D445D6D281B1A595763A4 +:109AA000ED899DBE4F65DC472CD038DE9FE679BA44 +:109AB000F5A13ADB549DD3FB471DE975756C200D6C +:109AC000E3DBE65B37A461BCFB78CC8F44C7277E21 +:109AD000B0A6215D1B46FD27F99106B83784F9AF82 +:109AE0003910C5A8FEB590EA6B570B3FFBC4D94FA0 +:109AF000582AD0B3A18891FF64C20FCBFE86B3A7CA +:109B0000E6233FCF14DB9D681772453DB4FEAAFFE4 +:109B10009BDA12418F9D10570781C1DB21AE0E42A7 +:109B2000ECBF0DE26A84F1BD536C37435C8D6D0070 +:109B3000E26A6C9F82B81AC7615C8DED131057639F +:109B4000BB06E26A6C1F83B81AC73D0A7135B60FAF +:109B5000435C8DD71BCECE2A257C0E337ABF7E493F +:109B60004CBC09ED2BE01F8D75A1B7DD83A2911EC2 +:109B7000579D3629FC2D6E8D56E0E1C713C3FC4579 +:109B8000FE1FB95CE91F72284BE9CFF4F755E02BB3 +:109B9000EA062930D68722EF4F9F5FA2C069DE090F +:109BA000CAF8CB2AA72A708AE706657C52D92CA569 +:109BB000FFA178031F03D526958FFCFB0A678A63F4 +:109BC000E97C655772FAB0E08B841FF9855ED9593C +:109BD000DD766E1FB95FCFF381CB056E8BFA384906 +:109BE0003EF71D1DFA87DC02E487896F9BBADB62B2 +:109BF0007A015F721F31313C5748270E003F87B80A +:109C0000EF9192533128977BCBAD51C89FDDEE92F7 +:109C1000688497945BD322E5A821D33B88DE53F078 +:109C2000F2F5C9FB1F2A997ADE7DF48751FE7A9FEF +:109C3000A77FC2822CD48773E8C8E6D37E6D988E46 +:109C400053E9FB4ECC3B5FC1DFA8170C37E9D3F0DB +:109C5000B976959EEEACFB900E4F3C6AA673581DEC +:109C6000F389FBE57C63F4B3312DF9E7E2BFDBCD8B +:109C7000C743FC1B8574816729F825BA9CA3903ED5 +:109C8000BF11FAF66F42DF1E177CC53C1661E6E095 +:109C9000F749BE35CC7F787C2EEA4D11C76BDD3598 +:109CA0000F6B686E9298ABDE1141D747051E4F8946 +:109CB00075ADC579014EB9C6AD21FD32EA3C1AEA4F +:109CC000DB15F7B410FC84D0EF1EB56D74BDE71D35 +:109CD000416A2F9F1FA2FE31FA73B48E0E3AB85418 +:109CE0003A1AF91410EB91F386EF7FF100CADB19F1 +:109CF00037C73FDE1FEB467F11EF77B878EB14AD27 +:109D0000CB85763FDEEF16706D3EC2DBC4BAE2FD56 +:109D10007E8203625D0DF3930F6C70869FC79C3546 +:109D2000A6487FD3953C6D15F4DF2CE864BC6F9B8F +:109D3000A576B0A313BD92ADF4A745474C06BB135F +:109D4000ADE8FD01FC85FB8177C80FF83DBAD8BFAF +:109D5000223A4EEBC897AA489E56C7DCF406E6DBCB +:109D6000D71CD219F7B7935F417BF9EE781BF9D373 +:109D7000E6F1E37A46CA5D9358C75641F7617EF72C +:109D8000D13B60FC448F8DEAF14399BBE79D30DF06 +:109D90008449BA2B08F31DEAF0279E187EDE81FB6A +:109DA00093A9620D7B264DBB1F9FFFEE21B00BCE0A +:109DB000309EB27F73D9B489FD908F21CEC7AEE8B3 +:109DC000F39AE0D72B02AFBD825FCD42BE770B7F07 +:109DD000B253F893EDE84F6CC8E722B11EEE4F3650 +:109DE0000B7F12427F02ED5BC29FBC89FE04DA82C8 +:109DF000F1D9A3C96EDA35E14F2041A1F3048B9468 +:109E00007549BCCA7AE80ABFC626C728FC1A1D9B3A +:109E1000A4F49798D315D87D364B81AF3ADDD7E0BF +:109E2000A754BF32FCF870839F2A51E0218726286F +:109E3000F757B8A729FD538A6628FDE5AED94A3FF2 +:109E400013FB6185FC775618BD56A73C57EC3BC900 +:109E500078EADD329DF66D86BDA7BB22F5B690751A +:109E6000EC9399709F0CC217A759CE97A5F4531C79 +:109E700075C8E249C7F37BF5152087D0161F8238D5 +:109E80008D8A8F20D710F7167AC6511C08F1D26040 +:109E9000E2431BDF6F92FB56C30CFB4F13F2D5FD61 +:109EA000A9C20BEC4F8DE8DB455CD62BE9A2E23270 +:109EB000D02F8ABF1E8FB9692FCACDB60F214EC5CC +:109EC00038F7C39F53FC25E3B6AD9FFD9CE2DBADA5 +:109ED0001DFAE255F4A550E8ED9643594D2DA06FBB +:109EE0009B5335972035E94B91D497166137CB6A50 +:109EF000E8FA1071DF568B2706E3BFCD8797887984 +:109F000023EC08C5EB117604F34896A8F6A7A687BC +:109F1000FBB338B322C733D6D730DF20033CDC3065 +:109F2000BEC4004F308C9F6A806F308C9FA5F43781 +:109F3000C1BACF176F6F16F6418E2B347B7457273B +:109F4000F676C821D5BE324F8D72EEA1F9E85CB22B +:109F50009B5B8EAC10749CAFF0678F7CCE21A0739E +:109F6000FEB9F79798FD31FD410E4A0E9B5DF5CE87 +:109F700030FF249F18E6C311F395DA7545FF9A0E5A +:109F800073FE76B5CE5DC23EEF107EE66543FCA65D +:109F9000FF70FADD29203F5B5A4C945F6D393435F0 +:109FA00009E7DB7D760EE1DB74D844EF91ADFFE38A +:109FB000A46BF17D45899FC4A7F0BD2531B8CF7A48 +:109FC000A6C544F6AFD0E24972744277A37C7535DA +:109FD000AF945B08A092902EBBC10FD1B961614FC5 +:109FE000255DF61C7D8CE8BEEDF0E224A4FBD5EDEA +:109FF00026852E23DBD4787DC48944051EFA318F53 +:10A0000007C1EF2AF4BD10DE46BDC09D1115BE5C30 +:10A010001D7F91F1C076C1A76D824FDBA35C959D3A +:10A02000ED6B6C3B669D1FF95D854FFBF2BAD1A7C6 +:10A030007D79FD6D33F011EDEC99E326B2B3231C6D +:10A040008D7A6D27FC286E3519FC841A375C6ABE40 +:10A050007AACAFD8EF34D8C5AEEE9776B1447E3F38 +:10A0600025744DA7E763C37C10E72A0DF49471F4BF +:10A0700085F926CFA31BF8D7C5FDE179FCC67CFA8C +:10A08000BFFA62FDA5A582FCCDEA98B7843D7F8B1F +:10A09000ECF93BDF0B7BFE7D778A930E8EBFAC27FE +:10A0A000EAD1C10E3BCEE222EDB83C0F196A7D2702 +:10A0B0002632CEF70879DCE97E77E200E4672FFDEF +:10A0C0007F34DE794BC43B6F62BCD31BF78178BC15 +:10A0D00073C03D9BC73BA91A7D2F6649CC55666F5F +:10A0E0002772FABF3DCE9952A4C639E52E35CE91DE +:10A0F000FB07BB1D1A9DC39A98A7C63DBBF117ACC1 +:10A1000033D9B500BEC7B5DD3DEDBC763828F4FBCC +:10A1100080E0CF6BC20EBF22F2861D487FE24B99D2 +:10A12000E00BAF57149F76C5BA9CC89FF93C2FCB64 +:10A13000ABA17C7AA4F4EFBE5A1A7FF0CCACD3F872 +:10A140007EFF6E470CD55976233EB0848316EF69A7 +:10A15000FC7EC56EB7E65CD2495E3FA24DB50332C8 +:10A160004E9072B9BBF51392CB5DEDE7F7A7D27EA7 +:10A17000C971AFB1974A913E57B5328679C385EC24 +:10A180008FD12F5EE839C6F123CC8D7A677EC7F870 +:10A190001C4F7B50C7F3CF3BDB4249B85DE7091E3C +:10A1A000D0F13DF0E2B620E1BBCFAD39F44C1A5707 +:10A1B0008AE7A25F3BFBCE44BCBEEBB4D964A37D6F +:10A1C0002607E96DB1D0CF37CF9A625D445F9DF627 +:10A1D00039826D9FDC8FFAEAB7EBF4BEC8EEB38329 +:10A1E0009223E9B6EA4A9DECC9F6D13613D697B761 +:10A1F0009F368BF3D6418A1F76B467C562BBDD0DEF +:10A20000FA43F62244F47FEC4A07DDB713E6E3761F +:10A21000C249784839089E369575F6BD9DC7AEE4AB +:10A22000EFD18F38FBD718A4CFABA7F7C4A0BDDA06 +:10A23000D5C69F33E29E9618CC33DF6837C5F1BA96 +:10A24000CAE064BCDE3CE6DED841B8AE3613DFBF00 +:10A2500011718D7CDEEED1F3A89EBFBB8DE761BB93 +:10A260004FF3FAD1F6003FB7C6841D93E3B79F9E24 +:10A270003AB11FD60F02161A3F820556C4C3B8570B +:10A2800052B65E49E76BFCD52CD2EE953AD438A78E +:10A29000A4CDE09FBCD5A407920F07BF9D7A4D05C2 +:10A2A0009DAFE77672BC59B52FBB4E2F499E8ACF22 +:10A2B0008FE5CF67017EBFCCCFF0C71CF1DD95FAEB +:10A2C00031D74D2BC7F936F373662362557B767011 +:10A2D000D4ECDF2EC4F3FF9B62C8CF6EC7F5E3FC5E +:10A2E0008718D5CF76973D521A8F75EB56E6E271F7 +:10A2F0009C6AD74BCF6CDA1B0FE3DF59AF117DC7D8 +:10A30000E5A9EBDDE9CEFE35E6C1675A397D653D4D +:10A3100049EAE59ED6C41BC93E8D86BB818EEF946B +:10A32000BD4475EC5B03EA3C4337C628782F6C4983 +:10A3300034E46F6A7D1CE24D591F882D1F12CEDF59 +:10A340000ADB797D7DE80F53070701DFE2D1FCFCD2 +:10A35000BCB12E3EDE6C53E32C435DBCD0581737A6 +:10A36000FA73118F0D11FB1AE7C43FC2CFC97AC32C +:10A37000364B7086E712E2876166485DE85CAF376E +:10A38000A900E8FFB2882F87591B7E9606AAB2550E +:10A39000F78F6011710173F859F290707E3BFCB831 +:10A3A0009A0F141D51E512F2C7CF319F5C897B9A39 +:10A3B000A4077E7E2EE222E38CD531FD9B5A80AF2E +:10A3C000430F31B1DFF17FF6A25C357D26F73320F4 +:10A3D000F4E88EFBF38CE2EDE6CFAC24775BC6703D +:10A3E0003F25E314B94F730D6B5956AAE1B96CFBC5 +:10A3F000F216A0E7A68373D317C1FCEF7D44DB9D63 +:10A400006C4BA1FC3E7D83925F0E9575A823267F41 +:10A410005201C6EB3645AF657FD3912531F87D916A +:10A42000332113C969F38756867F1FA069878DF68C +:10A43000739A0E5B69BF65DB0EAE27B2EE2CE3FCB0 +:10A44000D7853DDF2FE2DE5745DCB24FC42D7B447C +:10A45000DC121471CB2E11B7EC1071CBCBC26F6E26 +:10A460003A22F4EF9E9800FF8E2DAFCB4A3C6FEE60 +:10A47000DD72D40C0BAEF968C89A20437FAEEAC9EE +:10A4800078A7AA27E35255FB31C691AE8C2FB5674A +:10A490002BFDA3D8954AFFD5ED830CF9C870433E38 +:10A4A0005262884726AA7A792822DFA5FC5ACD77FE +:10A4B000AF8DCC7733914F3C0FDCD6F230F171DBAE +:10A4C000F1AC84C8B8EC65A137DB8E73FFFCF28970 +:10A4D00053719DC56D27043FBE14FC6815718A2712 +:10A4E000CD7D7D7E0AE615A7AC78EEA32B7996F795 +:10A4F000CBFB4E043E8D8FF47F9F51D21886BFDE7A +:10A50000F2975CAA9F5CA47E2C8DE3E7DC366BD1CE +:10A51000F4FEFD85DE6BA9CBCF12E7926A07F07DD2 +:10A52000D1DAA1D86EB078D2F1FDA7CD9A6706DA5C +:10A5300071FF6FAC9DFE3D095FBE3CD7C49AD03F12 +:10A54000F023C9F0F39C6646F98A12E0D3CCEB43C2 +:10A55000FAD8315F87417AAC87E1BA36595813FA95 +:10A5600079E6664E4777C655089E73AA9F77398E5F +:10A57000D7427CFF18DC2B7DEF038F66E177B7B005 +:10A58000C57D329B9DBF7760C9F7DE9F5FC8BF67FF +:10A590009B3008E72DC9E6FBA841B2DF33C4BCA657 +:10A5A000981D3DC99F7665570D792EAB56DF473113 +:10A5B000CA4B93B0B32F677A6674F61D8C67F3F9B4 +:10A5C000B9906D5F4CD6F1B905F67837FF2EA45BD4 +:10A5D000C7F7C05EFE7242CCCC4EE42CD87FE6B307 +:10A5E000F911725010AAD5C5DFA930A9F52D531065 +:10A5F000F97D26D64A7A3D1C179C78EE7C234EA81E +:10A6000071DEB01635FF0FEFEF376878DEAC439E92 +:10A610009021C8FF83FC7B1A179227E3BEFD07F940 +:10A62000F2BCA4F72F788E584F88A5F3359B0EDA2D +:10A63000D7611C69ACF7BDFD1EB7E346FC9BDF9BF1 +:10A640009E8EF1D7E691D7A5A31E6F41034FDFF38E +:10A650005934DD1D09E3FA63D1DE33FE9D2D7FF50C +:10A66000743C2FB365BC8417F2F1A3F8F8F79F7B15 +:10A67000EB31FC1ED8961B453F7B808F97B0BF66A1 +:10A68000FA28ECB79808AE781EC6437F7B5FF707C1 +:10A69000246FF9EEC328A71B5077001ED5D7FD11F4 +:10A6A0005EFF00650CAEBFDDC77D24128EEFE33E7A +:10A6B00016096FEEF02F6DB191FBC7520EDF3E3CD5 +:10A6C00055F81DCEF72932AF29BEB83AFF9F859CB9 +:10A6D000BE21ECD501E13F5E13FEE315F41F940F9C +:10A6E00073FFD12CF68D770BFFB153E4BDE1BCCBEA +:10A6F00023E28B4A910FF33CAC606429CF7B1DB2FF +:10A70000CE9F61EE2C1F9A5CA0C68993F255BF3292 +:10A71000A1579222A7653DD20D7972B6214F56FD01 +:10A720004A8979B0214F1E6EC893D5BCB7B87582DF +:10A73000214F9EAA8CFF20DF29F6916E30E4CBB327 +:10A740009471613EAAFB36617ECDEE948F5B8A6781 +:10A75000DFFFBF8B8F9DEFD7FCFFC7C77F501F6305 +:10A760004DCAFE8DB17D53F8FFD785DFD82FE2802B +:10A7700057459D639F88E7F6201F7B635CE7127156 +:10A780001D3FC721EB202F8B3A549338C7B145ECBE +:10A79000BB6D1275A8A5C5DFF1731C6799E0E35B7B +:10A7A0009DF2B1DCA5C67913F3543E8E772619E2EB +:10A7B0003E35CE1BE350E3BC52BBCAC7516CB0213F +:10A7C000EE53F938B2ADC410F74D30F829F51C0737 +:10A7D000C405ABFA15E27B09EA798EC2907A9EC372 +:10A7E000E8DFE5FB8A326EE888137CEA3EF326F464 +:10A7F000A1B85F9466E5DFDB307B2FC7B843D2EBAF +:10A80000B7FDB83FDFF2979B889E85E8CF3BF1DF2D +:10A810001BFAF1B868433F5E97C0F723A30761793D +:10A82000D3CFE39F84490E7EAE8A85F0FB53E78940 +:10A830009B36F44B09C74B66472DC33842B799FC8A +:10A84000F8FD5DA6DBE9DCDDDB5DC451C7FA65CA56 +:10A85000EF9F6A38EF5FC4BC5AF16B14579DEAE76B +:10A860006EA4F94B5D6D5817DFFCA1D5558FF21C16 +:10A87000C5BF83628CB75EEF97CBFF7E8FA01F9E14 +:10A88000FFFF39FA4BFC502CF9DF16D57F6220010F +:10A89000F36C88E6F09BFD3E9E8EDF1794FEFAFD7A +:10A8A000E74F913FCD8DBD7C36E6CBDA1A7F22DFB4 +:10A8B000AF0C927E19E3B62EE35F439C7624CFFD66 +:10A8C00006AEEB1BE19773F1935283BABE7F43B49C +:10A8D000E736FE3D18B78ECF957492FDFB04DF5F1F +:10A8E00017F375D045CA157E9F2631E23D5803FE09 +:10A8F000925E2B0EEE0DE111C64B5D8F5C4727F289 +:10A90000E3B940DCFD4D67F2C326B9C47BBA9DC7ED +:10A910007D16114746F27F38AD2B20D7CFC60CC22B +:10A92000F75FE47BEBDC1ECA7766121D0D8E4CD000 +:10A93000A39B0EE974CE81897D7073073F8B35F43C +:10A9400033E6B11A4B8AA8BB1AF7138DF503E3B9A6 +:10A95000B2E2D6CB15F8AAD3EAB932F7D9BEE7F5F9 +:10A960002BA3634718FC52A9C16F4D34F8B5690693 +:10A97000BFA7D6C5CDCC2CBF3324F6EB35277E7FC1 +:10A98000C7CC2914D92FBE03C4E9BDAC0BFD95E794 +:10A99000674FF57312DD3BF4632D7372FEF995F783 +:10A9A0004CF4582FF1F9A121D28FB928EFB50687C1 +:10A9B000D1F73CAD2EF5EF33047CF68F46E7E07B14 +:10A9C000368CDAA77C8E8F46D3FB38A9D43EE17350 +:10A9D000D2F535BE3C6A1FF3B9E8FAA3BE226A1F5E +:10A9E000F6B9A96DF09551FB80CF43E356F92A09DA +:10A9F0005EE9F3529B05E10DFEBD812C3F7301C65C +:10AA00002C7B253C2F82CE997EC023828E57D43951 +:10AA100014B8676DAA323E7DBE53E94FF3E629FDB7 +:10AA20009755BA1438C553A48C4F2A732B703777B7 +:10AA300099323ECEE551E098BC4A657C94D3ABF4A4 +:10AA4000EFB96A7842CB79F4B9C1E73E8A7458E528 +:10AA5000F31CE5742A3BCAE95349ED2DFDBB117F78 +:10AA60001DE64637FA6D47BE83E1F976AB9DBFF729 +:10AA7000DDCDECD0BA45CCDFCD0DF329F8C27C4A50 +:10AA80003E17E0E789F33C4755BC2B95FB4007C9CF +:10AA90004FCA38668CDE230EF3B1FB2D8E3F0F06B6 +:10AAA0003CEE1BA3337C6FE5E0E8695417C12D4CE5 +:10AAB000D6891DFD4CC4A731FDED942F4E7954A3CA +:10AAC000FC0E56528E75C4B987B25D917F0F4AB69F +:10AAD0006FFF8A7F6F2866CF3627D6C5A614CF4C66 +:10AAE0008A8AC8FFA604BF1F9D46F30D1C12057875 +:10AAF0004C5933D33A3B3FBC3E396EEEA36A3C1A05 +:10AB000096FF805DC4E3B44E699F5639D6D1F555A2 +:10AB100079E7DFB73929D6F58588D73E13F1DAA76B +:10AB200022EEFE58C4DDC744DC7D44C4DD1F89B875 +:10AB3000FBB088BBDF17F1DA2111AFBD23E2EE15C0 +:10AB400022EE5E95B78EFEAED5998D1AD3CF73BE29 +:10AB500074C17A759DF3D7AAFB86731F55E3EE394E +:10AB60000FA8F1DAAC656ADC7D739D1AAFDD58ABD6 +:10AB7000C66B33E6ABF6F17A6FA9025F57A9D6E54B +:10AB8000AEF5A8FB86924FD3CA543B694B55E3B54B +:10AB9000AED6BB35385EC7BF4382CCFC34C21F463D +:10ABA0007C0F5E39EF58E07097E27E4D21F32CC5A3 +:10ABB000FD9C91A6D0BBB8DFC4DED7E93B904D78B1 +:10ABC000C730D0D73343264D7146F81DBF4AD7AAA8 +:10ABD000236A7DE4863BD438B8A25ACD67AC656A57 +:10ABE0001CECEEA1EEC74E33F81D26FCA195FFCE5E +:10ABF000467BCEEF874C31D5F4BED2A5FA232B335A +:10AC00009E1FE3FE889E9BA5F4933F320FE0E7244E +:10AC10008688F714EAA386BE89FB777B3EE4EF17AC +:10AC200000D943BDE0FEAB18A7B7D53E8EBE1FB717 +:10AC3000D3C2DF1BD89D16EB5A025D579DE5EF0787 +:10AC4000B076339D1FF3E27B235938AF7A7EAC3068 +:10AC50006456CE97590DFD97A14F3C2F3EFC1CDD4D +:10AC6000FF1C3EE21CC7003680CE47B474FEBE41D6 +:10AC7000471C679053697F0A823C3E2AE8323EAA0D +:10AC8000A2EF8C99DF67F49EBDCDD476E2197C3FAC +:10AC9000EA735E871DC5D4BCED9A496ADE36C6717B +:10ACA000FEBC6DBC5395D78979AA1D2877A976E09B +:10ACB0009CB8A6859F43EC2AAEF10CC892EFE91030 +:10ACC0007DA272F6C5F07D4C2E3F23C43A1FB27AA6 +:10ACD000E8FD95653D19F16984839F57ACC77D1BDD +:10ACE0003CFFF71E7FEFC5CC3C4903B03D3E569C70 +:10ACF0005F9CE4A2F95A39BF8AE0DF4F59E79E4FC3 +:10AD0000B485CCCA7737CC2C82BFD03F07E5AB30B7 +:10AD10002C47FF7BF012E728A59CC5265E60FFCE7E +:10AD2000AFC481B21D1572EBB88E571C7C1FF59510 +:10AD3000506D08BF13F95D2AAF53DCDB63AA997F1E +:10AD4000B7C51D3B06F83256ACBF48EC936DF1B168 +:10AD500010C6739B7C766AE5FEE78AD4C549E8375E +:10AD6000B76478D3F15CE096946ECB18D8E9CD96B1 +:10AD70006E3D3A7B8FA0D93294FCEC96E63433C614 +:10AD8000A1A3CC0E33DE37AAC72C1DEBB1E3F07DB7 +:10AD900093648419EDD36DF20543A3E95CA897CEC3 +:10ADA00011C13A4A318E1DED98497FEFB1F93DFC52 +:10ADB0009B4A181F77ABC2FBF6A5F0F3D736073FC7 +:10ADC000DF3A36791EF1ABC0C5BFDF57D023D615A9 +:10ADD000C0E952F9777CE6C33FCE17EE2740EF95E6 +:10ADE000EFFB0C651130F2CB00AF31F2C7702E7162 +:10ADF000C561717EAEA5F37D9BBF8AB8628BA83B0F +:10AE00001C1171C54722AE3828E28A15863AD0BB9C +:10AE100022AED827EA40AF8A7ADE7E51CF7B5DC46E +:10AE200015F2FCB5948BD495CC694B60ECAD999C34 +:10AE3000CE692BB54019ACA3740E8753EBF8FEE82E +:10AE400015DE064F4901F65B5CE3601DA9950D63B5 +:10AE5000701D69556DF49E52A5D7EA746BF87ED2C9 +:10AE600013F45E947C2FEC164E1A76D39CB1647F5B +:10AE70006FF18A73C77A6B21C9D7A316FA4E92FC79 +:10AE80007E5CE51CF57B4AB30CF4BDC9005B356EF6 +:10AE9000475E93741FCC0647D23D4D8C8DBA459CBE +:10AEA000E7C597AE3AD1973582EE922ECD574D88B1 +:10AEB000E3EBE0FBA13631CFA1E21BE2709EF77A13 +:10AEC000F0F9A60A7D30CEB74ACE27DEA78916FC58 +:10AED0007FA8EFF9CF9DBEED63CA39D3B7057F3A9E +:10AEE000E62DB9DF82DFD3AE0CDED713F525FC5E8D +:10AEF0008D3B8EBFBF32E9CF99C0A755E23D0469B3 +:10AF000057AF13FA6B7CDE7BBEF3BFBFF35EC90C99 +:10AF10000B7E0FFDDAE02FF8DF0336D7A6469EF74B +:10AF20007D0FF1035B79EFB53FA3BF2319CAE0F2B0 +:10AF300060BBC6E6C4EF0C5ED1C3BD1CE998DAC3A2 +:10AF40003546D447C99FD9043EA698B55A0A8E1FE4 +:10AF5000AE91DED65F3581CEFF5D770D3F27F1FFE5 +:10AF60000010785941008000000000001F8B08008D +:10AF700000000000000BED7D0B5854D7B9E8DA3320 +:10AF80007B1EC0A0838A1912B003A819531F230F78 +:10AF9000051C70A39812436410548C8803A2D0D669 +:10AFA0001892A6B7F4D4731804110951D3A63DDA48 +:10AFB000F818CDA3BDB9DE9698DCA64D73CE21C698 +:10AFC000A4696F12B1471BED6D0DBE92F46BBF1EED +:10AFD0006DD236A7ED77BCFFFFAFB566F6DE0C6825 +:10AFE00052D3263D852FD9AEBDDEFF63FDCFB5B967 +:10AFF00072057EE633E6606A78C8C7F0C77245819D +:10B00000FF4798579D83EFF18DA19E5DC9C4FFB79F +:10B01000B26032BC0F7EEA176C266335ACD53F00B8 +:10B02000EF7BF3B454F774A8AEB35D187232E683C5 +:10B03000DF2B59D047CC239F354CA57A39DE920AB5 +:10B04000682FC767349FA17E6B0FF33AC642E14F6A +:10B05000B0BA89D05FD46D55234E9CAF37F839A76D +:10B06000E6622C2BDDD2E080F554666C5ECD264086 +:10B07000832A877B0AF60F2CFA796E1E3C7DEBBD86 +:10B08000B83D6CD70CED4E4DEBCEF04E8FAD6BEB6B +:10B090003656128279B666FC0FCFFA646CF7BBF6AF +:10B0A00010B6B3B1DA7E18BF77C12FD3335DB1F6D6 +:10B0B0008766954EF3E7C380E5A98CA53136D51E8A +:10B0C000CAF24F1FBE5FC6C28C41938E9244C660C7 +:10B0D0001DE71B948803D655DB07F01B83F5975AB1 +:10B0E000F07D439FC3DB8B0B649AEB0ED8E77ABEEF +:10B0F0004DD630A52B7F009EEBFB9A2BA8FD2EDBB7 +:10B10000398497137E11BE19ADEAB928BCB03DD37E +:10B1100095711E53D98E73C07A17F89327BCF949DD +:10B12000F8772ECBBD62E5F847F8D68AB6090DD57B +:10B130006319E2D303C02C1CBEAF95EF59D9C07878 +:10B140004604C3F263EF4F37652786B01FD28D5395 +:10B15000D0D52CF8BF9779ED7310FF9CAE6A045DD3 +:10B1600079197B9EE82A6C0B47D709FB62F7D962F5 +:10B17000749765188FE17A97EBCBD45F3B3919D67A +:10B18000BF9AD15C6C75A085C3EB3E4E8F4E78297B +:10B19000C689D11B8C1334D11FE16BA258278CB305 +:10B1A000ACACECFFFC1060F6E8CEAC3B104FCBFE35 +:10B1B000D1CAAC305F3534C37275AD12894079792C +:10B1C000E056E287E5FAF1E17D4D8DED821E3F6F9D +:10B1D0006CCAA671D694F371D826DDFCB4BE9D046A +:10B1E000CF20635BDC3A7A7B33934D6600C7E77709 +:10B1F00037EFC3FE171F7430A423867DE720DE39A6 +:10B200005C4F02ED22FDBFB54D891C84755FD8ED02 +:10B21000A075BEB94E8930C43F733F3E00EFBBFD01 +:10B22000294497171342FBBE08F58D5B93FC61D848 +:10B230006FCFB8D68D4198F7624AA81EC769DCFA6D +:10B24000494B18DAF724869D59386EA3D57F10A68E +:10B2500058A9024CC7C113FE7D133C1B7A74F883B6 +:10B26000FF8EF9151A7F898585FA5DC3E9C7319B81 +:10B27000D723C01DBAF52FC9B2D07A4F3DE4A0F54F +:10B2800026CCF6123C1A0A12B484318847A6A93992 +:10B29000B09E746D12AEF38202FC09F4767E9912B0 +:10B2A00046F83095E3C57ED38D07909F1E15FBBCF5 +:10B2B000F0C0DC4948CFE75378FD394F6204F77599 +:10B2C000CECBCB618F2BF218F2861AF22D4FE6FB14 +:10B2D00050800E1AC5BA1ABD162D01F0DBF8D08ABF +:10B2E000CF229E1B3D7DF7E0F36472385981FE6FDB +:10B2F000EDB6328437C2C39983F545CD586F86CBFE +:10B30000257F16ED07E1371EE0F6E6AECEE410EC41 +:10B3100083B959C83E310687869DCF7C419949FC47 +:10B320001CE6FCCEF94461BAF318E877A5D71E2EC7 +:10B330008771D8D1C944B72BDD9C6EED855B52B3C4 +:10B34000783357943EBC54EEC3F3BD51941B906EBA +:10B3500001AE2B915F66223CC6CD1980F7B54D46F4 +:10B36000BADD3261F303D5B0CF7505366685FA755F +:10B370001ED5C037556D463E827D1BCA636633DAE3 +:10B3800077CF38419FDD9C3E81D2270567C4E862B4 +:10B3900097DF42ED7075B651E06F86EBC70D0EE793 +:10B3A000905E41DE9CCFF0EE2B24B900F4C3D7C5EC +:10B3B000AC3A7E68E87110DD33200F8413D0A7BD4E +:10B3C0006A468C5E247C1A7675103D3608BA6BECA2 +:10B3D00003FA19A3A32313BC70CFAA9C273B46678B +:10B3E000541F87CEBEE767C44792FF1A58B09E59D4 +:10B3F00087F3B57C129E8B109F9FA90DA7E3286150 +:10B40000EABFA3A4682CD1BBC007173DF4E344BC3A +:10B41000254BFC84D9093CCF5DA2D2DDA69C2E032E +:10B42000796315E7AC5D1B8C0CC0FB94362BBD47D4 +:10B43000F9A2427B9C9621C29F9BFBEDA9504E1026 +:10B440006597C0ABD5EA4A43782533A3DE338E999E +:10B45000E4899FE355CAD99D369686E7718238DF25 +:10B460009B17652BD86EA7A2907E602F33D281D513 +:10B470002407BCB32DE2BC0BCB738FE4ADDDC9F761 +:10B480009B906621BEF86D3A085425060FBBD8FF85 +:10B49000B8016FFF00D4D77B9CFE0894C73337C92F +:10B4A0008752986940376F4D45121BD0E179917BE7 +:10B4B000BCA1FC29CF4D86F6B779B30DF5B7FB3E9D +:10B4C00069A8BFC39F6B28DB994EAEE33A8738DC8F +:10B4D000ED02CEBA7A299707118FD5621F3BEC2176 +:10B4E0004F10CEE16ACF7A92CF1D259FF10CC13E5D +:10B4F0001C1ECE7F76D42761DC84294D6ED2238436 +:10B500007C2E805FC443270E9216A333BB09CE6600 +:10B51000FE33EB930DB385DE730BBB85F41ED7B8FA +:10B52000B8FA8D597F031961417A4D14F85A647540 +:10B5300091DCD85A03FA9C82FAE552AE2FF9EE2636 +:10B54000BC06453B16B690DEBA5CEC5FEA5FAFB571 +:10B5500033367033C06301D7B396175CAA41FA340F +:10B56000CFDF2BDAC97262C1014D8B234FDB057D22 +:10B57000250578FD722753510EC9FAB090B7CB85D7 +:10B58000DC5E027C8C745B894F9DDEDA27C6E98B1A +:10B59000D22B1BCCD1F3E9214545382488E2011692 +:10B5A000EA9B9D8A700E5323AB2BC888BFFF04D043 +:10B5B0009D437A0CFD94CE6EDAFB79A05F474DB2C5 +:10B5C0001F6D0B87D6F0D857017E8935497E8B37A2 +:10B5D00046EF64774079828FD37B6DBAD34FD561C4 +:10B5E000EDC4E43931BDAC46E877A9AC95F8609874 +:10B5F0001DE3E47439B21DC3CF1F399F439CFFCCB8 +:10B60000BAC94F7417E4E7BE057E91EE96D51AE9E4 +:10B610006A4568743AFB96A4B3B96C2ED159680395 +:10B62000D18543B4D93109E885C389E82351C2578C +:10B63000E8DB36950DA880A763887F58A4CBC69217 +:10B64000719F83DA0BC417833E66D3D3413060D534 +:10B65000223A3C0E16B24437C897411BCB7810DA19 +:10B660008DD1562C76C3FE064B1DC90D74A8460C11 +:10B670007AFB3118F7AC8B8DA8EF9BF9612AFC039C +:10B68000E5C0D68C373DB89EAD3646E73D0B5FAA88 +:10B69000D5A0BC5D96D92F6A4B61DCED09B2FCEEFA +:10B6A0002EAC7F3C91972F3FF9A75D241F805E1140 +:10B6B0001F49021F49527F9FAE832BE0C13921876A +:10B6C000CE19A709DE66BD5ECA09F3396C9EF74D37 +:10B6D000139E46DAF7B0F50269DE323A5FFCC76CBA +:10B6E0009297AD06BE183ECE00E9EFABC4BE2D4921 +:10B6F000CF6584E2D89151F86FB0FD4A6F2F009C5E +:10B70000BFABA0DEAB41EF398C8B0E18472978E92F +:10B710003F51FE2BBBC2E3108E56688072DEC642DC +:10B72000B41EC9AF0948075684FB00D583FC1D52DF +:10B73000B271903A37C24581F6571029D77A4E96A2 +:10B7400073B9B6529C7F9538258C57D9C34AD13EE0 +:10B750004F58B7F6E03694739A03350A787FA914E8 +:10B76000D707F59A839E9734C41BD0B341EE3C5F54 +:10B77000F287B71F817EDD8356BF03C6ED0E3CCB3B +:10B7800050EF7E673AF3E3A6BBB021ACAF3EE45E78 +:10B7900064F722DF0C9CEA9AC2D8D9763658661B29 +:10B7A000BEDEC12309762F6C36144E99F9348CD342 +:10B7B00053E070A33EF7C626AB1DF134B8B9218C17 +:10B7C000C0389D16EE57E07D8F1A6268DFDB377553 +:10B7D0002E42BE3B6D0BFBC7C1B36773F82EB4435B +:10B7E000346F457926ACFF608F5A1E89733E6FC84F +:10B7F0005188DF5E7BFED3B4FF6369767F028C3BAA +:10B8000084FE0DC0DF31DBCE0C3F8EDBF1950C1CCE +:10B81000FFD8BAADFE23B0AE631D0EB4A4D8B1DD1F +:10B82000CE5A1CF75871B367BD6E7CE74DF6567C57 +:10B830003F78A3DD9E4DFBB99CECC1FD6CCA1D8F0A +:10B84000B4D99D669FB416EBD73733DCAFDDB3D3E5 +:10B8500086FB73AA6C179E2F9FF05C7A752EDA4BCD +:10B860005ECB9C4F41FBCFFB43B7E6001E57B69D16 +:10B870005D8472C95E96B2059FDD629DF2BC92F84E +:10B880001D4A6B74E239D6DDB496FB613C9606C264 +:10B89000639A2588E75177609D73EA74FEBE79CC80 +:10B8A00070B874A3DF6516AE73BD67FD0C6CF7BB93 +:10B8B000F610B41B2A76D4C68363630E9763CECE8C +:10B8C000E6AC365877F76EA71BE1D3AD847635002A +:10B8D0005CC3992EFF63DEE1FDBE25FA49FA003C08 +:10B8E000111F6E387CC3EEB08AFA2AC723C0C5691F +:10B8F000D3C9CD43B34A9B111E51789BE74DEB262C +:10B9000079D1AD70BEFED6E159BBC3509EE90FDDC3 +:10B910008DFD8EF500AFCDA27D4E427D7F24FE19B8 +:10B9200012F5DD1DB0EF38FC3FD46465378FE5CFED +:10B930001BE03975B3759212073E43C56BB3D04F08 +:10B94000750CEA2D30CED06E277FC2FB2CA4AF1130 +:10B95000E873560E97F7BE99C12D39687F4DF7935E +:10B960009FEFE5D9C1AD39A407B47AB0FC31A0DFAF +:10B970007D1F11FA65EC46A4D7E9BBC3609232F78C +:10B980003883DE3AD2F91964432A9EC71D257F68A1 +:10B99000417BA07786DDEBD0F905A51EBDC4C7E5C8 +:10B9A0005B70CA853C38B959F5F4F564DF80BE4C4C +:10B9B000FE4137FCC6F30F06D11FA893874B4C6599 +:10B9C000A99FBE94037211CF7DA127A77B7706178D +:10B9D000A0FDF18AD51F01B86560072857552811C9 +:10B9E000D4D73B4A9E203D9E093D6E8958E74FDBE8 +:10B9F0009DAC6C0A8BDA732BC5FBA496B38FA27D2A +:10BA00009D84FE4FF4D7B638BCE47F41E4C3FCD537 +:10BA1000627FD2AE233D12F6B3B245F841D9835CC2 +:10BA2000DE5803F9480FB00F835D1264263BA4C9AA +:10BA300066B0E75699F407B3DD506DD21B76A0EEE1 +:10BA4000847AA1DAEF447A7A777ACEB12C2F5587AF +:10BA500007A47E0FED420527B60CE9CE9F1342FEE8 +:10BA6000FCB85D3B8DF2684BF011E710FAADD5885C +:10BA700013E5496FF9E79291EE7AEBACE5486F83F5 +:10BA8000EDE5D4EEB5F6203DAF08B951E1D77E4FD4 +:10BA90007C29F4B3EAF2D2D35D3ABC5669B79DEE85 +:10BAA000D2ADBFB2A0CA5096F4556965ADFD71CE56 +:10BAB0009759B9D2EFA231833E6A3DE40FC5392FC1 +:10BAC000E43391A9EFEAE1989C2BE846E853F74F5D +:10BAD0005F3076347D46EE53C247EE5FD68FB4DEDC +:10BAE000DFE55C9FF566BFCFF59AD719C5D308EDA2 +:10BAF0002BF1108373E077873B56A25CA8F0877226 +:10BB000073010FD565CA96F140273F16FECA1F077D +:10BB100092236158CF8B3EEEFF4C6CE17665625903 +:10BB2000D5223C9FDE2FBEEF2C50883F6B024A444B +:10BB3000837FDE2AECD59FFA18C51F805F5F4D8694 +:10BB4000F2EBC536EE47665AC51D7362766A621D12 +:10BB50008F4FECB033FF00F69BE6F26F86F7CB25F4 +:10BB6000FFD51AE310353536C33953698A3B249A19 +:10BB7000CE99A512EE7300EED931B88F647F8C4454 +:10BB8000274CBD94877E31337C369AE063B6772AA2 +:10BB90009F33F1C735DA3D077BF25E9C807A469988 +:10BBA000E29F82F8C32AE897A83D49E1905EC94721 +:10BBB000C2DE93F1AA1D4BABC9DE7B0DF581B1143A +:10BBC0006F9A84FE6A39BEB4F366FAB5FB725347C6 +:10BBD0005EC709D16F6B557C3DE104EA09B3F8F308 +:10BBE00006784E5DBA30239E9E70A250E809508FB1 +:10BBF000FAC189DDE5FC5968D4135879EE55E0D2D5 +:10BC000041FB4D989237361EDF1D9B157A30570742 +:10BC1000F7245F2B2BD3C17DFD6CEDCBB8DF2AE180 +:10BC20008790F3817C3FAAD7C3CCF33D95E316F60A +:10BC3000C6789217F27935FCA9EE56867476BF4D18 +:10BC4000AB457DCFEC4F3A9CCBF5C49E2CAD05EBBC +:10BC5000992BE72AE376487FB56FF6441E7E20BF16 +:10BC60008FC91E94F6D301ACCC8FD985AA9BDB85F6 +:10BC700089E9978EBAA1AA3937F40CC2A3F85224E5 +:10BC80006C01BE735428A43F39D219E93DD76C87A3 +:10BC90005D63BB1E646AA0E7AD8DDC1F5F3A5BA5E8 +:10BCA0007262C87A90CE05931F2751BB4C76D8128A +:10BCB000D00384DF86F4A953429F0AB256B2F75CE0 +:10BCC000B68813FD1566BF4D6DBA65602AC8F5DAF2 +:10BCD000824B35DE99D4DFE0F7A9F5661D4D15F5E9 +:10BCE0006E782E09723FD072F403E1F835919E2CE4 +:10BCF0008CC3F955BFC6B89D87FAC58AB55F98F160 +:10BD000035EFF5F30349FF92D417A53E03F2A5677B +:10BD10003CE265A1E225DBDFE42732FB85A45FC6B8 +:10BD2000EC3F32FB8BDECBCD247C48FD4BFA7F7E93 +:10BD30009F6BD4C3FE0BD803DBF516C2910AFCDD62 +:10BD40006B63193BA773FF0EEA4BC74A7FE046FDC2 +:10BD5000E2BF4CFDAEF57CEB8673E83C9EAB2F2436 +:10BD6000D850DF0E7A42E44F5CA218F9242D4FF828 +:10BD70001BF35C7C1E1147EE6E6F93FDC3286F8230 +:10BD8000E9F64882121B8715E45F133F8D9DADA530 +:10BD9000E6E5933D72431ED2B31FEC9119688F08FC +:10BDA000BE2F48A5FD302D959DD7C78DC5BAA3EBF5 +:10BDB0007082DD32E3FDCF3F218F19E6B91ADC76C0 +:10BDC000941439EDE88F001C5B395DB9A3FEFB2CA0 +:10BDD000F4EB6CF0EAF58A7A8C5BE4A2DEC9E31A34 +:10BDE000F2BDCE7FAE22FD26A687B4609C73F5CE51 +:10BDF000BC689C8CE2A751FFBB8F51BC488EA3321C +:10BE00004F07F101F2AA5C8F358E9F5EACB749F007 +:10BE10000100DCE9009259BBD3CA785E02E713192E +:10BE20008F500B83E599B0DFB5DB148A1BB370ED3F +:10BE300051D4EFD7897ABBF0BF99E348EB441C8615 +:10BE40005937909ED6F49031BED6D8672C9BF572A8 +:10BE5000E9EF576191B8EE7F403C713844ACA3C321 +:10BE6000E100EDF36F140E920E2B723FEBC1BC9606 +:10BE7000EE84D0AE068C6BEF75923F846C48E497ED +:10BE800001F885FD6CDB53F008EE675B9E95E0D70B +:10BE9000ADF03C97A3695F730EE9E86D9BE0F35B3F +:10BEA000F2BCDCEF82E7128844963E81F848E6B5A2 +:10BEB0001C4BE37AA53DC0F5C643938F2CE5715723 +:10BEC0009EDFE20BC4F25B4A013E33047C7C539A52 +:10BED000FC03F09C116826784C7FDA68AFDEEE3305 +:10BEE000EA953EB3BD6A2AEFCD8B9FD7128BB3097B +:10BEF000BFBB58BF99AFBED9CEE32D4F80DD8ACFEF +:10BF000043ED6E7A7EABDD43CFFE762FE96987DBAA +:10BF10007DF49470BFDF16ACC7B896F4434AFFF8BF +:10BF2000F7F3B8FDC6027C1D95622F8BACE9C908FA +:10BF3000E7E301AE178E74BE54971BFDA0CB82C6FB +:10BF4000F8DE8A5A637CEFEE99DA73785E26CDF4D8 +:10BF5000D842BA78D43AB1FF1D5FE3F12639FEF139 +:10BF60007FE47897E58B62FFAF0ABA483A9266F3AE +:10BF700002B2AA1EAABA15FDF6CC9D734DFAE0498D +:10BF8000C197499BDD36F40B550DACB4E338EB7625 +:10BF9000C138AE6B1F676BC6C40C637CE1EE3BB16E +:10BFA000FFF1687C61E39DA5507F5CC417DE7EBA1B +:10BFB000F5EB6117D2ABF673941FD63CED0CC2E3E0 +:10BFC0006D719E437908DFCB32FCBC9C3271543FCB +:10BFD000FEDB79F9C3FDF8D6854A6BBCBC96CB79FC +:10BFE000513FDAAF496E39A37EB44BBCCCE5919A90 +:10BFF000CFE7EFFC296BC1713A9F652D87E3E8F32A +:10C000007FCC53E478EFE591FD2FE560F00FF1C6AA +:10C01000B33AAA2621BC2FDA785E8C793C35DF2E24 +:10C02000C7B3E463FFF4E8FAD47CDD783B00068311 +:10C030008827D59D4C714D7617C53F251D25D5BB4D +:10C04000EFC0BC05302C199E2F49DF71DF91877E30 +:10C050009C9F64FB1F6323E3F51782BEDE12FC7511 +:10C0600011F90BF8E8BCE0AFB3C85FF03C23F8EB84 +:10C0700067ED7E2AFFB4BD80CAA7DA352AFFA4BDCA +:10C080009C9E27DA83F4FEC7EDB554EE6E0FD1F314 +:10C0900078D923B7E2B9F3DB6F2A248F475ACF67E9 +:10C0A0001EB51AF8A7654F9281DFD63F34DE506E79 +:10C0B000EA33C6CF1BBBB20DE5356DC6F8F9EA56BB +:10C0C00063FC7C55CB3CC37C2B430B4DFC7CBB8978 +:10C0D000DFAB0D652D9FEB89D5E5AB0CFD1C9E46B6 +:10C0E00043BBA4A52C140FFFE5F99C3E8F94148D3F +:10C0F0001D1AC5CF616FBBFDE7A89F44CB6A88A11D +:10C100003E6F6F5B42EFEF4FE0E79DB95F7D3E3FD3 +:10C11000EFBACB9A820B18EA458BAD7ABDE7D3B361 +:10C12000424BF375F6A0DDC3EDB17726D7583D40FD +:10C13000474BCB2EBF7803D051689091DDA381BAD5 +:10C14000E7013DB8A0F5C1853740B9267C8FC17E97 +:10C150002C6A79F205605F16283BDE3901FAFB672D +:10C1600087EA71FC12CFA517B0FF828AD92A92F50F +:10C17000FD298CF4D18B19F6C8C138F4706FBE62FA +:10C18000885FBDDF73DA1CA7CFF2B152F42367F9E1 +:10C190002E95A25C83B286F1AF43B342F7229FC1D2 +:10C1A0007B0DE5E4FD33D667E1793252DCE86B02C2 +:10C1B0005FD29F20D7B5A384AFE7B8882F0C99E250 +:10C1C0000B3A7FC23FE58FE24FB828FA0D7D35BEAE +:10C1D0003FE1A2883B5C947187AF55C78D3B5C5CA7 +:10C1E00024FC09508F7E848BBB6BF973D1E87107F7 +:10C1F000B93F388F1EA2F3271A77107ABEF09B1F23 +:10C200009BA5FD33D6AF9FADEDC2E76F6668BB114E +:10C21000CFC775F14FF7445DFCB3EC0786F8E753E1 +:10C2200039A103F93C6ECDD0AEEA0CB3A1846C8C7D +:10C23000C70637C6A3E3FF9D2FF5EB813F2B3EAB2F +:10C240008BA35AAE7C925D731CE09ADB15F0BC1494 +:10C25000B37E9384101917D3FB9EC80B1D417875CC +:10C26000A57CC7CBF3AF2CB1F30385DF08FA907937 +:10C270003E391ECA2B945B278063F09CD99E72A91D +:10C280000EED94410137F3F3DFF3DD029EEE0988F2 +:10C29000DF27F2823F267C3FDDEFA5BC36F1FE5A58 +:10C2A000D7F1B83DF873D463BB1BADDE835C6F2759 +:10C2B000BFC5CD819448AF2E1EFC6B3C2FF3D1FF40 +:10C2C0003834D90EF8EE0CBDE0C27CF037F6A898F1 +:10C2D00011C3BE911CB621FE6B7DFC7C5BE0097D29 +:10C2E0006268143E077A186FF1D03A2C96023E2B02 +:10C2F0007F86157C9ADB0FEE7937D50BE37D632FB4 +:10C300008F7FDDBCB7C9D9A81B3F6B0E3F77BA91B1 +:10C3100066F2303EA9443051BD3670F9D5B9185F88 +:10C32000F15AC8CFF1C6A6DF9E5C817E47CD4A7E1A +:10C33000C73736BD43E5535E4B2EA2EF0DCF6F4E90 +:10C3400062FB9BFF71DD446EB77078ACD994FB78CB +:10C350006F26C5C59439008753DA3BC9D9D363F139 +:10C36000B3350A0BC6D363D2E670BC2DD65AEFC4E0 +:10C37000752D0E3918E6399F6AD8FA732C7FA354AD +:10C38000F15AD1AEF7F1796AF7A8944F0BF0D98042 +:10C39000E557FC490CE75D107A52C5F6BF9BA1B08A +:10C3A0001B94EB0857ED9D54E4C33790FEE2ACFFBD +:10C3B000D7F2DC147C345505BECF41F81F75E9FD7A +:10C3C00094929EBE94A765CF21BF5FA825487AEEC0 +:10C3D000D2ABE8A79B799EF6372FA9187B487CB48F +:10C3E000F546F42F0D5BE708EBCB9BC3E5E46F0448 +:10C3F0005FDCBC577DF536A4E74D36CA43B8252F20 +:10C400003807F115B5B7AEF3B921F3D7060BF87DB0 +:10C410000450A7691E58AF4F8575242889FE30E760 +:10C420002BF2CF39C5F907EDB4B1D06E0DEB1F403B +:10C430003F1F53B59D56F41F16DAC83E5EB1DA961B +:10C440008C7889C5CBFC067BC3FC3C8FF131CAD309 +:10C4500070D27310EC6C8C97E00F68E250A90ABDA3 +:10C460007FC6C31AFCF37191577A6FC16D0F8703B2 +:10C4700060675878795DC16D376D862D9D9FD47A40 +:10C480007219ECABF741C5DFE1C5E7815D8D78BF7F +:10C49000A24DF19743D3FA8169F518626CEE719061 +:10C4A0008E7F6EDB176E457A7DC7C3DC48CF2BD2FB +:10C4B000383DAF3DC12216287FAAEF418A7B064F47 +:10C4C000A894B726E3B267D2785CF6CBED03B46EDE +:10C4D000B46B17CDE12636FE8CF3C33AD08F5AA643 +:10C4E00052BC743C7377E3F992A86596727DDA6D5D +:10C4F000A7384F05635F473F4F1BB79B0B455EA4B3 +:10C500008C63B10BDCBE6D815F9427E3CB8DF6713C +:10C51000BEC9FE95F2CD1C6F01FA0FE3FB8E3946C2 +:10C52000FB7824BFBD7C3E0D7A04EEEF3B228EFBF0 +:10C530005DD0D7319EF92CE8EBF87C0EF4757CFFCA +:10C54000AFA0AFE37300F4757C1E017D1D9F4741D2 +:10C550005FC7E74BA0AFE3F365D0D7B1DF8F405F94 +:10C56000C7E72BA0AFE3FBA78BF9F9D73DC51ED9D1 +:10C570000CEBEDB6B19F215D854B455C58C4C9B647 +:10C58000A54CA5F3DDF927A072D0A70695D06710BA +:10C590001FE10C27B51B4CBEF4C7FFC0F2B64CB26E +:10C5A0004398EAFDEE10F4EBFA62A6BF178A3D76D7 +:10C5B00046F2FEEC71E656409F796B993213FDA866 +:10C5C000E7EF50FAB13C788742FAC45464BD9CD876 +:10C5D000395AF4AEF7209E679DC94CD0E3237BB552 +:10C5E00074E88F6B237A1D5B8F76E97C872CBBEA1E +:10C5F00035A0CFC63645D8A9EE7D48BFDB14D93F5C +:10C600006D2FB6EF92FD45F98445F6FFCC1EB4B709 +:10C610004F46E76B5885E39DCC92F54D75583E1B10 +:10C62000CDAB2B5E8DED07A3E3E7EEC5F2F90C3938 +:10C63000FEFA5554B6C9F2E3D4FE7C2A6F7F4B71E3 +:10C64000EA7EB49BAFF7789D217EFEC139A6E9E36F +:10C65000399B8AACE67C70F2BBC938BF25C935E589 +:10C660005AFCA5BA383FF94B613E1BF2D9E74B5350 +:10C6700026A1DC3D9BE18F6BA72C2C1AC17FAA2938 +:10C680003CDFDECD42981F9F28DE27F6F13C7ABBC7 +:10C690004F1D96477F2DFE4499F720FD89B54DA388 +:10C6A000FB136B4B8DFEC435A27E247FE21A933FB1 +:10C6B00071E526531C22F4FEFC89756CC086761841 +:10C6C000D314E2A33A77FF8B13D1DEBFE0257F229C +:10C6D000F3BE4CFE56797F02FF6F9983F7CD78F950 +:10C6E000ADBB140FDA15BD772913F179E62EE546B7 +:10C6F000E4AF0B77296EE4B7CB73F93D98FCB7FD37 +:10C700002F7BF1BCF558FC1C1CC17FC15045B029E2 +:10C71000C5DB0BE39CBD4B1987FD57DF9769477A53 +:10C7200000BD53D023DB83FC624D520CE5BC499223 +:10C730001EF73E8CFC317FBCE497657B905F4BED30 +:10C74000B27F3B95578614D1FEDE3DDA64E0AF053B +:10C75000B2FD843AAC5F962DC7DB4FE3CF4F92E535 +:10C76000AF12FFF544C7FB5F34DFEB2821A9FC00C3 +:10C770008D575A25E5D9742A77D7C9F15BF7625EE0 +:10C78000EC2A8BEC7F1BF1FF5A26CAA8BFC37EFFA1 +:10C790009F381FD6CDFDE32AE4A73BA3F57F7C1885 +:10C7A000F9AD4E949B9F79620FD6FFCDEFEF2F3CF2 +:10C7B0009FB9BC9A0D2EBA212FC617E673A5AE906D +:10C7C000EB9D052D4FA2F86275AD07ACC88FB1B8CF +:10C7D0005A5A4D10E9DB69A5FCB9A087DD1A2F9FD5 +:10C7E000FF0F73F9F9F485B92E83BC1E39BE167F8D +:10C7F0009C86423E4ECF0216D7CE3D346BC1E6B981 +:10C80000F931BD0155443B3C4BE06981E77B334244 +:10C810003D588FB20BFD30D2AFBD44E41377947C0A +:10C820003DB800EF2F15DAFCC21D3EA88FF7AAE233 +:10C830009EEBAA053CCF2BD4EB207BADA647E49121 +:10C84000585D148F506FB21FA0B89988A78630EF3B +:10C85000388BF2BA46BDDFA19AE2A89D62BFA5B3AC +:10C86000DFA538F5DA5778BEB08C63D78B75AD4548 +:10C87000B90CEB6E6C522216E8D7888207E3BA3EF9 +:10C8800016F166C6E2CA2BCBD4013BDE0B13F7339D +:10C8900098D087A3F1F01A6F3FE6C7A85A825FC30A +:10C8A00079D84090F2E2305E94C9A2F1672947AA94 +:10C8B0009A6FB80BE3D43AB94571EA44364C6E909E +:10C8C0005C88E63589387A343F47C801199F6E1075 +:10C8D000FB5A1E9503154B50CF4DBC5FC4A945FCB8 +:10C8E00059C6A9AB4CF7DA1A030BC7903FD7AFFA7A +:10C8F00029AD26DD789F29D18487A945FC5EA58CCA +:10C9000053BF32D7186FBEDFC648EEF66419E9AEE2 +:10C91000A488DB3D9F2C927EC8C48104D4BF999328 +:10C92000EC905EF4E78CE5F6085DE632F975D4B676 +:10C9300055E47FC47A05E850F1BDF49F2897B15CB7 +:10C9400004ED55BCDF82F87059C81E95FE1F545384 +:10C9500016E5901FE8DC5CCC0369ABA771E47DF6BB +:10C96000C713E3F3C7AFE74A3DA1DF86ED56795E13 +:10C970003A85F3FDD97E20618745F5182FCF7F4991 +:10C980009DEB9571091BBFEFC76C4B6790BFE4BD72 +:10C99000B9E41FEBF7E23AE4B9B4EC7B4FD1397656 +:10C9A000ED7170DEAFA1F0DF5685278C1CC7981A99 +:10C9B000E078F2CD0C3A3064CE26C8B883E6C49055 +:10C9C0007854CEE2460A0C72B6AEE5BF819C8DE982 +:10C9D000FDDE3A1CEFE3B67EA0A70584D772EE7F9A +:10C9E000FBB8ADFF07F9DA4AA4C30F7B9EEFE5075A +:10C9F0009B719EAD8A56EBA27B31CCAF8C1E2FDC97 +:10CA000088EDCDF1C2ABF931FEEEB718DD6FB1ABF9 +:10CA1000E0A3E9B7F832C00ECF6BE0A743C44F01E3 +:10CA2000CE4F7FEBE71FECF747B8DFAD4A7F24D14D +:10CA30007AFDFD064FE4855EC7F1A7A63B1B509F1C +:10CA40008179BCC87F517F08AEBBC0E00FD9D3F25B +:10CA500021F843609F6F115ECB385EFF06F0A6148D +:10CA6000E27E34AE47FC0DD2654621E2B09FEFEF87 +:10CA7000AF30FF0C9AFF10A797287C849EA4834FA9 +:10CA80005DCB5F073EA5B4BEEFF2F57D0CF0B98239 +:10CA9000E8D5CFD77B35FB7BC35CAEB742BF7AEA24 +:10CAA00097C7E960A3D0ABC12E5F78833766978FB5 +:10CAB0009DAD3516F2F87353A121CF545B87E55134 +:10CAC000ECE64F17A68E6A37DF8DF51F17BB798FFF +:10CAD000805B2C6E13A17B7120C129BE5C2FDAF61E +:10CAE000B6552F9E867935007F2C3B703F56DD7EF4 +:10CAF00032546E6F9BEEABC9EF1DC87DA9D6BAB19B +:10CB000003DE183C5F1BD36AC7FB50CD5A4A37DEA1 +:10CB1000BB5DD87599F206ED9AC38B76E1273CDEB2 +:10CB20006E8CCB566B7CFFF61637DDEF93F7DDE4AA +:10CB30003D94E681692FD9F1DE1CD82F69307E65DE +:10CB400099ED9C7EDF0ED3BD14D5546EFB59E6F6ED +:10CB5000A3BAF6DF284C36E437837E534EDFE9E88C +:10CB600052DC22CF97F2329AC5181D25772E46FF48 +:10CB700025E8715E84C3C29D0F0E623CCDDE65A5C3 +:10CB8000D8F9EFDBBDDB8F024B25ECB592BFE1B7E7 +:10CB90006D0AFFDE47058FE3AF15717C66F23348FF +:10CBA0007FB88463C2033CFFC35E70B68CEE37D699 +:10CBB000AD1BCCE7B443FE0695AF8CC9EF6F5409AB +:10CBC000BAAA0F5CEEC27ECB3D1643FE90D91FA1E0 +:10CBD00032739E3CCFE354359EC7A9FA789E7C22DF +:10CBE000D3E87B1D895BAA099F551ACFE304254929 +:10CBF0007C778BE3A532700FE5F998FD088E02A3D0 +:10CC00001FC24C97667C9C36E1E33195DF4FEA3ECC +:10CC100061F587E175F7434D3DE83F0F3F64213FE4 +:10CC2000C605991F028B447FFE0A16852FE9CBDDCE +:10CC3000AD3C5F40E265C54E9E3742AD0C7EFB7455 +:10CC4000A6FF8EC70AE157B893F5D37D87D56CC888 +:10CC5000867CB0065DE956F4C778E9B99685B730A9 +:10CC6000825FA82713E67BAC75BC1FFDDA0337DAB9 +:10CC700052DEF4713B229EFE1A8BD7AAEC4D9D9F8B +:10CC8000FFEF7EADF7EBD7B286E97EA9C71E99A26A +:10CC90005CDDAFF5238C4BE8FC5A17768AEF6D8884 +:10CCA000FB1683B6D6493B5DD8CE4BE7E5983D2BC6 +:10CCB00016231D1CDBFB03B7B8FFBA69E2E8DF856A +:10CCC000C8298A934F7A7C2EE379209943748FFA8E +:10CCD0008CCD98971BF51305ECC22F139A57941A15 +:10CCE000D38F993B9AC7595C44FE237E5F5BFA99C8 +:10CCF0009A73430BF07DF125410F154A4481FD568F +:10CD0000BA9417156F6C7E66CEA3FF7B3C8CCB0963 +:10CD1000840FE63325F0BCDAC14C567B380E7E26F4 +:10CD20001773393A383B3EFE643DE827F716A57283 +:10CD3000FB690CF72BFCCA3EBA5FE18BF1E846E2D7 +:10CD4000F7D07CED4B1CEFBC9C9413EAC0F69DA180 +:10CD500020E5EBBCD567F57620FC075A5F2B80F207 +:10CD6000927FB2BA311EFE61C7F952E7665E539CEC +:10CD7000EFB280EF99685EF7A67AD4077BA57D268F +:10CD8000F4C755E3746538928B4EF0F6DF7B76EE90 +:10CD9000BEB03AB2BE79F773757BF1FEADD437A160 +:10CDA000BC1ACBB23F0B574C2A057D766D8B8C2776 +:10CDB00056EC43FD363A5F78F93EB4872ED88CE3C3 +:10CDC0004B7DF5FF3EBB681F8E1794F38717ED432D +:10CDD000FDF7ACA93D7D9F12C67BFDD9526ADFC825 +:10CDE000E4F8A5B4DFA85F31BC7135F63F6997E57B +:10CDF000CF523EC1F64C3EDEB1E736EE45BFD147DD +:10CE00006D3D1FF6F8EFB7FD487AFF191BCF1F0CD9 +:10CE1000839EF65826A651F65B39F369762BD07FB0 +:10CE200091A6D079F45BF48343FFA0CB22E8EE1FF8 +:10CE3000F6A24EBFAA44EEF320E5818C44771B0294 +:10CE4000CF3C6CF4173FB3CAB06EB6B11EFBCB75C6 +:10CE50009FC0F6B0EE551B3FEDC175AE92FE8D70D2 +:10CE6000E75EDC5F778AEC376DDF68F38602DBF71D +:10CE7000E2BCABA2F37C85FAAF4A94E37DDD98BFB8 +:10CE800012DE4FFE8FD8BAD61BE0F9FC73FB099E69 +:10CE90004177640B9E0F410FA3F3F8CE960ECAEFB5 +:10CEA0008EF2117B2083F8C8132DEF35F2D17DB4BB +:10CEB000EEEBBD2E384FD3E7E1F9E7E376E2F5DF9D +:10CEC000379C93B8EF3E2E87241DD5B9653F803F30 +:10CED000C893B55E39EEDDF52DD3AFC7BCDCDE0DF2 +:10CEE000FE8A917E2BF90938C9C43FD7365EA7EB7D +:10CEF0005ECAA36806B91E2F1F7BE35C45FA336F39 +:10CF000025781648FB9949BD63F13C9D5F8E79A356 +:10CF10007A47C53C32408C7A4737E659CDA27C2E01 +:10CF2000929B1AD4787479403717F3F85AA7C893AC +:10CF3000CCDBCCD6EBEDEDFF399FAFE71BF3B9DCD3 +:10CF400094DFB73DBF41A13CB1CEBEEC3178DFEDFF +:10CF50005CBA773BCAB5C14C0B7DA7E08CF8BEE646 +:10CF6000E0171D19F7C1FB53194E3FCAAB53293BBC +:10CF7000E93B6AE7FC56419FDF7903F959E7570C13 +:10CF8000A35C917EC396EF77911FF0B4979773FFE0 +:10CF9000ED9937F01C633EF3FDCE00E931F65BE11D +:10CFA00018C1BEE2FB9C45A2BE6ADB535FADC63131 +:10CFB00084FE22E5A7F9BE27FED8F4FA578F95EB39 +:10CFC0005F1EDECEC3863AAE58705C5E768EF05D34 +:10CFD000D85A797FD9A44F5599EE2733F11D54A91A +:10CFE0008F174D68F4A31D57B4C1A81F9DEB79A1FD +:10CFF000AF00ED5ABFD58DC7E4ED3E63BDD4C31677 +:10D00000F73C42F628E885867964FEEDEDACBF8BEF +:10D01000EE857B5F3E6A9D18B35B3ADD55A4A7346D +:10D02000FBA004FB39F9A5D2E47CD40FFAACF84597 +:10D03000589E7BAFDB07B4B35926D039ED57147D2A +:10D040005ED0E6FDC6BC205E8EF9E3DBF61BF2E89F +:10D05000C277AFC172D4CFC956EE473E8AFAC5D85F +:10D0600052AA3FAF0A3F186BD88FE759CCAF779AD7 +:10D07000F83AEA27634BF6233D05A3E7DF0ECAFB28 +:10D080005BEE16EB613F23F9D1A97179F2DCF7135E +:10D09000CEE0F781DE6F7BE0CF67893F83FCBC3356 +:10D0A000D7179D88748E117A1DE68B9BF93C39C089 +:10D0B000F3EFCAB4D95DA95EEEBF72007EB4D5D6D7 +:10D0C000D5E83788E5AB14D277D2D68E905F725B05 +:10D0D00080F3EF2BF346CF53592BF254461AA7A9EE +:10D0E00084E7030C2AEE1A2E97AD0CE572E983D97A +:10D0F0002E8C4DC976A525FC1C786F86761ACF1B21 +:10D10000B33FED02FAD388CFB8DF63A9A01D75271E +:10D11000FF5EBDFC9EC9F914977F33BC5FDA27FC24 +:10D1200015E57F9EFFEC57F38CDF151D29FF2120AD +:10D13000D69F57727DF21F1E4FD43484D710B4454A +:10D14000FFE0B07C0891E720F32012033CEF4EE6AD +:10D150004374865B097ED7FD9E8B38FF814EC706E0 +:10D16000904E6BB91C917476749E97D3DFDB7EA2D0 +:10D170003F4977D03E358072A486B72F7A9B7FF7E0 +:10D1800042EA17C9CF0DEDED984C72E8A6805E0E0D +:10D19000B9A2F722330271E4D0F185DA27023AFB13 +:10D1A00008FA670752E3F69F1288633FFB66067D25 +:10D1B000346EF43EA7360DCBFFDDF320589F39EFD8 +:10D1C000849F17E6BC13A90F36FDEB2F5663DEC90B +:10D1D00095055A15C713876F54AF1CE27A4E4C9FC2 +:10D1E000F4733BECFAEB8B8D34BFC8A7F910C6DFA4 +:10D1F000A81F5FEA4FF0FE9E802E8FE7A366BFC197 +:10D20000FAB6047471930FD0FF01DA9F88D7FC053A +:10D21000D6FB30AD57E8FD1F41787E3B90FA915E1A +:10D22000DF0BB4BE0A713ECF63F2DC7E89DE0FA352 +:10D23000836BA6FFD702BAB8B96EDCE3FAF946B23F +:10D24000CFA1DD4FA87FC530FE39AD1F7794FE67B3 +:10D25000689E68BB68FFB37AFABC0E7CFE4B3D7ECD +:10D260003F8473E4F7B4DFC97CFC378BA270FC0306 +:10D27000CD2BDEFFDD4F76553AF71623BC5A393DEC +:10D280005D837E3DB598FB6743DC3F1B96709F2610 +:10D29000DE0FE17DD2A5F3385DDD92179C5E9C1F09 +:10D2A000B36FA3F6087B781FAE376A8FE040D30DCB +:10D2B000727E9FDEDE58F82F07F7E17AAD0B79FB1F +:10D2C0008262F71A94B3E632E82345B49F585EE6CB +:10D2D0003C2C5F6D5C8CFFE33ACDF17F5DFDA2627B +:10D2E00063FE02E9AFA0B7391D80E3D7EBAC131A98 +:10D2F000A15C59CCF557D03FE2DEEBAE2C8EFA1193 +:10D300002A8B75F918278256BA1F18D553C209649B +:10D310004FC5F4A843FB8CF736BE4DE51281DFC63E +:10D32000E2C3F5629D77D23E26887D5CBD7D88DABA +:10D330007B78FB38F54DB4CE74BE4EE67AF9825553 +:10D34000170F434EB3609C17FF05E74CA96D593189 +:10D350007E23EA488FE2B542B9718FC4EFF7F7191F +:10D36000ED43CE7F2B05BD6F2E3E528FF85BF9AE9D +:10D370005CAF8DECC5BC681ED311E29FD3C21FE128 +:10D380002E81F6E9B4BE365ABF97AFEF4318BF8B74 +:10D39000C6671C3EB52C6C9B384A9E459FC03FF427 +:10D3A000BB9FFA39F9BA6A430AE9EBC126E068C0C3 +:10D3B00073FD0916D7CFF49562BBECFF15EAEF12A7 +:10D3C00076AC3FFE7DD9DDB1B8C96E6AEFE6F359A0 +:10D3D00041FE23DE02A1E30BF13B10B5E27BE3B596 +:10D3E000652A7D6FA1B6E0D252E107A1F8A68C8331 +:10D3F000973E3099E29B896509DC5E741AFF8E4581 +:10D4000070AD83BE2727BF5B2BF332AA98F1FB7266 +:10D4100071E25B067F8BF48B44BF27674D27FBD6F9 +:10D42000BE5FFCFD27D3F7E312DB18F9B71C5DFCE8 +:10D430001EB8394ED5B0A9F5B542CCFB506D149746 +:10D4400035C733CD7F0F63BE93696372281FE5F93B +:10D45000E2D4581ECA5B7BB25DC88766FBF9AD910A +:10D46000ECE73D46FB7950DACFDAF5B19F4F141B5C +:10D47000EF0FECCF0DFE84F0AC6A74BE1D29295A63 +:10D480008A7E8477441EC5D987262C417F54B88F65 +:10D49000DF573827E2FC32DE7FB690B9DCF8DCE2F9 +:10D4A00020789E5D9712C123784C5773057E5750A4 +:10D4B000DAD10879F47F558A7D9AEDEDC402C0E790 +:10D4C0002C6233B2B3CFBADD1417A8EC11DF97107A +:10D4D000F902D2CEAE14F7F8D796F17BD5E8B14376 +:10D4E0007A90DF0FAC1476B8B4C7077EC8147D1EDF +:10D4F000C052E627FAAD01C2C0E772F13DC55A3706 +:10D50000DB828BFACD8CD01FE99CDAC3E9846D579E +:10D51000E9EF5C9DED7B90CED591EE313884BF81F3 +:10D52000E4D8C40FC5CE7795E8CE8F6B386FC6515F +:10D530007B95F37117DEFF4D8D7D5742DE9BDF9E9D +:10D54000C2FD283797703F93F929BF1BF17EE5078D +:10D55000C8CFAC128447CC9ECF2EB936F9398DFA9C +:10D5600089EF56A4611C889F4BD34BB85EE01DC366 +:10D5700083B83DF6D1F300724B4689E7B2ABE711B1 +:10D58000CCC3F9CCFD2F0B7DA43937A495F0783F9F +:10D59000D1AD39DE2FDB9D44FF549CF3F673255C3F +:10D5A0007E9702895A7286DFE77FBD5D3B833ADE54 +:10D5B000C9F6727A9E52C3C998BFF59AB8CF0F8A3E +:10D5C00016E533C9BC28396E6D5DE9990BBAF3AC29 +:10D5D00072D1A39467D6E93BF8B202EB3C27F2BDC7 +:10D5E0000693BD74CE858FF3EF4B2DAFB9EDCC050F +:10D5F000DDF9615E2FE6458581D5379470BFE60B76 +:10D60000A58E81F979F8BD26CE874D7D67E93E4C20 +:10D610007D5B030BCDA0BC2915F17B6A1EFFFE428A +:10D620006581958575EB1A3B5B5B57C2FD3ECD442A +:10D63000A7B1BCC0167C5F6AD3C6E0DF9F94FE49E9 +:10D64000192F282DF915C5DD065318CD1FF4B00884 +:10D65000C6DD176AF7D88730EEE2F1927FA4A1C445 +:10D660004BEB6CEC3940EB490C5CA6F594AA00EF4F +:10D6700071C3E12DF9A25BC05BB76F82F748FC5B19 +:10D68000B9484D46F8BE86F882763D826F8EA997DE +:10D690005CEE38788FF62B2835C0DBE12937E0AD1A +:10D6A00053FBDC18DC8FC473A3A87BABC7FA2AE258 +:10D6B000F15DC023233CC6CF83388EF8BA99B17F81 +:10D6C0002FE1DF9993F8AAEFE2DFBDAEEF2AA5EFD5 +:10D6D000C5D517DC664FA33880D28FF725D796358E +:10D6E00030D4F7ED5A0A7DDF4EE26F6919E04FB78B +:10D6F0005EE0C77D253ABDF303F8D71F27BC0B3D7D +:10D70000F8C3F6FFC37C4F97C4D1CBFF52F187E13A +:10D71000DFF3E1E7EECF84DC303FE5B93B627E33F7 +:10D720005BB2A6E503AC43F20DF26D8782F9938AF2 +:10D730000DE92C88FC8BF7D70A7EB105E3A1CD1E3D +:10D74000D68F67E16EE423809BBD3CD38EFCD3B8BB +:10D750002793E802ED7F82A738A75F8E9DD367E904 +:10D760007D0BA78BBF76DC07D6F30EADA74EDC2F63 +:10D77000F888C5A56E2A0F3AE6A37F563B40F2E52E +:10D78000E83CB7944F19FCBB4DEF2F0E5AA4F1BCE7 +:10D7900031190F8D13FFF42A1F20FE698EAB8E14F2 +:10D7A0000F8D13FF34E8EB23C53F99294E6A8E7F16 +:10D7B0002EEEC9A6F8F3629F85BE532DF57E19F7AC +:10D7C0007CA5E72995BE8B345D612999C3E3A33B12 +:10D7D000857F8CA156A7DBFFA90CFEFDEBDE34276D +:10D7E000FDDD55FCC17C2C094F900F4E07CCDBB5FD +:10D7F00088E76556651E36C3D52EEC926B82AB8CDE +:10D80000AFDB7B94C866240D0F8BE6FFD97578B625 +:10D81000FBBE437864EA800BBFC7DDE81F4FF964A5 +:10D82000663C14F5F0BF4B59E49E437F9752E2BF2C +:10D83000C8333C6F5095EB8B9337F817C7A777B376 +:10D84000336B147CCA38F64878BC252FB811F946DA +:10D850007EBF49BE3F95C1E17B7E1A137FFFD4880E +:10D860004F80BF46F7FA7DECC06665383D14897C71 +:10D87000CC225FF81ECA834FACF060DC2C0ADFF4C8 +:10D88000EF127C3B5BBDDBD13E3A5E66A37C9538F4 +:10D89000F4407FDFF66AF4300CEF7D1F0C7FAB0A9B +:10D8A0001F5B9819873E3E305EAF824FBBF5504FED +:10D8B00081371E9FBED0477CEAB7BA11AF129F12C4 +:10D8C000BFC3F1C9F50B89EF53F9DA37E7E7EBF19D +:10D8D000AC3D81788EF16F98DB312CFE776F0E8B2B +:10D8E0007C1618E749ECF7D4FCE8384FE1B8D59F2F +:10D8F00088FFF74E0E9772B95BC7FA5F9C8876DF98 +:10D900000526F235FD2F7BD14FD3961D375FF3E40B +:10D91000FD0AFF3B3D1E76C022CE578BCEDE3D8BEF +:10D92000799B60DF9EC6BC4D78FE707E26EDB717F2 +:10D93000F337C7823E2EF23BEB706C9C07F4598C98 +:10D94000CB3335C4F05EFA207E9F65167E9FA5839B +:10D95000E46E2C0FE31D531E062F5705A4BC714522 +:10D9600028EF261AFFF4840CF14F363362947705C2 +:10D970002143FC53E4E948F9B6595B100A1BE29FC6 +:10D98000E534FE993AD97E47A474BA3EFE591DD1BA +:10D99000F4F1CDF01D54AE8B968354967EE8C70605 +:10D9A0001E08A11FDA3733F44BC493BC370F02486B +:10D9B000C3BF436775B90FA21D0EF601D3F247D658 +:10D9C000AB3F2ACFFF0F526BA57D00800000000007 +:10D9D0001F8B080000000000000BE53C0D7454D5BF +:10D9E00099F7CD7BF39364422621E200415F02E880 +:10D9F000D442187E020109BCF94932B62003048DD5 +:10DA000005E903722C746D1B6CA9B4AB9B81C4989F +:10DA10000485D0B2DB9F6DB72342CFB1DAB371EB8F +:10DA2000A944A41DA4555A2AC6363962976AA0296A +:10DA3000075ADBA295D5EEE929FB7DDFBD77E6CD60 +:10DA4000CB84A0D03DF674389E97FBEE77EFFDBEF9 +:10DA5000EF7EFFF73E972F54185BC0E0E74D1A1A90 +:10DA6000630361F87302B6FDA651C6D8AAC9B25DB8 +:10DA70009934A631B6B840B6AB4D6321631D2E264E +:10DA8000C6B30403F8579893DADB8DB09998C2585F +:10DA900068B92AE06334FF6B6B24FCAE6408E65B74 +:10DAA000ED10EDC4CAA4E165EC634CB697527B4D12 +:10DAB000BA1DA7F69D8CAFBF3FF5B09980F1DF99F5 +:10DAC000139F605C03EFA23D7A7CFADF1FFEA7156F +:10DAD00089CF6413FB3FE8F802BF6346154ECFF9C8 +:10DAE000FD7780EF5A928F031CDF0F207EF7103FE7 +:10DAF0009FE0F87D00F069237C7A009FC2BFFD7A29 +:10DB00002F5419BB71BDBF011DDFA47D9FC6E9B8AD +:10DB10000CF84789EE20DF077BFF84908F31EC9F64 +:10DB2000C3E77BD529E428D164A2DC9F725AF60DA5 +:10DB3000DA0BFAE57A5BF49066C57F0BE9C9EA1265 +:10DB40003EFE77A97BCD4459A60D3F03F75D8EFFBE +:10DB50003DF6678DFF3C8DEF72A6E1693D97E85772 +:10DB60000E6F237C33F42608BECF06DF28E82B3A5D +:10DB7000DC914C58F8C1120F127FD27629F130D9BE +:10DB8000A501976CEF20BDD959CEE71F7FF8E1249E +:10DB9000E20FFC3B46FC9EC2F9F78FCE8F3F184246 +:10DBA0005E029C1F520EBF33C7F823CAD9070D5F10 +:10DBB000D83F35744D46FEFF1FD62BA6F5843EBDDB +:10DBC000D7F1697D147E9F2D49F3776208DE8F0FB0 +:10DBD000EBD45FBDF1C9C8B5F0E79AE6475413E747 +:10DBE000051856CA587C9025B7C39A37B3A4CAC043 +:10DBF00087C58326F34DB3E835FB0AE1E1F23A44E9 +:10DC0000FB5B64FF562F92727D2289F145066FEF10 +:10DC10003ADCA734DEEC9B59782F3CEC7D44D01DD8 +:10DC20000C59F4E46ACFEF0F035F2CF150BA2DF8D2 +:10DC3000B3FAD35F9B847C585D21E7FD7612E779C8 +:10DC4000B558CEFB24ADBB3ABDCE0F783B5FC2FFCB +:10DC500094E033780D985978257E417197C4EBB1E3 +:10DC6000C303B45F2E5FF2817173E0D9A40413B0D3 +:10DC70001F1FDBB84D35AD7681F5E821F06F77B029 +:10DC8000749BE42A63077A68DDAB8DD7E690E08F5A +:10DC9000D0D3349E832C986056FC0EF0FDB9CAEBAD +:10DCA0005BECC23D28B7579FEF29E7B516BE4B3D49 +:10DCB00058E34BEBB7C13CC0775DCEF36373A3F77A +:10DCC000CAD705397FD86A4FAE9C8EBE5AA2E30DE3 +:10DCD000BE2F19FBF392996D7F2E1BBF4742167F13 +:10DCE000FE9EC787B2F5CC627F1E47BA5BBD252E6C +:10DCF00094EF757E662401BF8BF85B9C798E0F2BA9 +:10DD0000649FD2FA59CDC7AFDCC59A7BA60D87BFF9 +:10DD100036EC20B8D667D8C61E982FE43ADF14B781 +:10DD2000C0A542BCFF5048A127D07788F8BF95E333 +:10DD3000772CA4D37A21A6310374AA61E5A4329486 +:10DD400083D65FF2F9983FC8561466E63B2BE693FC +:10DD5000EB1C5E5ED868A5E327629D63214E07FA3F +:10DD60007FE2E77D9C0EB5E86E3FCEAF16C8FCF2B1 +:10DD700077C4D776A76827DE22BF3690B6437F24C4 +:10DD8000795FE59672F90EE9BF8CD7DF0AFD6F3235 +:10DD9000B110F167CC31CB3AEE0F6407471B37283F +:10DDA000FD459BD8AF447ABF4E21DEA38D57234A51 +:10DDB00033F1C9C3520AF80FD5EBDBDB05A4042A03 +:10DDC0008D7338FEE84CE3B797330FF0E93CEDCBA9 +:10DDD000E7B2F3114BFFDBA1AC7CE0FCDD719C07EB +:10DDE0005676C3BEBDB2462D5D0F7CFB2BEE4F15A4 +:10DDF000E507B15CF2F5D7CCBEFC359415CF470AE8 +:10DE0000AB408FD8784770AA3E7C9C37AC4839131A +:10DE1000FBA43D8274B4A7F58DB77716F3FEBCE77B +:10DE20009CEB843E1584719DA7047F99AF14D76342 +:10DE3000D38EA6D4B9E05F59FA6738A0BD1EFF8221 +:10DE4000F50722A79C28076B3B14239943EE87E92B +:10DE5000498798FFA1F4FE8D0F5F43F39A6CAEF0F3 +:10DE60001FF01BF8C4369AB7B14921FDB3EBCBE4E0 +:10DE700030E7DFE4709A4F93097F43C8EF9CF85472 +:10DE80006C032873CFCACCBF56E01D72C60F5D0B62 +:10DE900072D0DEA6E8688FD66D5DD7510E6DA639BB +:10DEA0008353E17103720AC6B5FB2BBC68075E148D +:10DEB000EBE17C2ED847F425FE1282631A3CE7C6BC +:10DEC000361FC1E1EF4E37AB909EEAF8EE0892B5EF +:10DED000A0F1C923F8BC15CC34C629DB167D3D1E44 +:10DEE00086FDEB9BEF0CA2A84174D63705F06A10B3 +:10DEF000786946FD393606B228170BA6E6A05FF70B +:10DF000006B7C3FB86A64F2C61950013770E0D7ADA +:10DF10009018935DACC079B5A1C100E7D945B07147 +:10DF2000CBB73A336DC40DFB3D99FE95D773FBB467 +:10DF30003A0CFCB4C8DD0F057D3F14FCDC0538F459 +:10DF40004DA3090A19EA0DDBE840FEAD1373F5B5E0 +:10DF5000ADFCC88700BF0B0116C4B61BE95333F4F0 +:10DF60009D9AA471FA98E15D3A0ED615FB7ABC052C +:10DF70006CDD8D306D1BD009F468EA9AA294458E51 +:10DF80008F8F315910E3B640E20106721231773BB0 +:10DF900007018FEB9BDEDC8871DF5AD3ADD7038A94 +:10DFA000776CF4D5625CBBD2147C59E23C8D747BF7 +:10DFB000E01FF2C5953AF76317F279A1C2C6C3FC18 +:10DFC000CBA2BC5FF2C5CDB4D356BE68B6F6D6932D +:10DFD000E53B7F6481FF4CB8B0F4CC87E18FD96C0E +:10DFE000F645A0130CC852C4E74287E253CB09CCD4 +:10DFF000C1804E9787EFE3FE8ECD2FA29EAEF56BCC +:10E0000041878EF831E25FA358E39D167DE78F20AC +:10E01000568D6CDDDD8D727747BFCADC00D7BE66DA +:10E020003FCE843F0FCEA709B970147CA34F0338AD +:10E03000ED8B2AC3F5241F81DFBEB9F0FEF4008CFE +:10E0400007D03BAA814FB0EEAD865BD7012E7FE1B2 +:10E050009B6DC8A77CD69C1A0BEDDBFC0E96F26478 +:10E06000E802BA13822F8E8B0AADA56B725D4756FC +:10E070003FF125FF0B11C6D076278CBE2900B75C77 +:10E08000CA6D07DFCFE506DF0FB9AF2CCAE555EE45 +:10E090004BBE4D5EDDD5CE8C7CE69057FB3E246DAD +:10E0A000FBB05FE37A72AA5FA5F8E8D49ED25BABBF +:10E0B000811F893D0ED263C8D30E2845F0474A61BF +:10E0C0001AF0FF76812FFD006E7F7371B2AB3CB307 +:10E0D0001FB7079EFFB352C938D4B88C3D6298C4AD +:10E0E00042FB36D1BAFDAB8912D4D38FB11E27EAD9 +:10E0F000F59D6CD089F2FF714C0555B48F4117BE68 +:10E100006FF4F85CC8C7FD7B9E2B443B929AE02CD1 +:10E110003E13205561563B697F2227CE48BA01380D +:10E1200025EDA7C7F4935DF6C293ECB4C1B05D5C76 +:10E130001BF59839FCC8E1D9E60B6807655BF33538 +:10E1400033C4E35BB3E33F217B29C6EB95C64FB1F4 +:10E15000FDBD59C6317C7E1BE33DF00FE7C3F7518F +:10E160005EF2EE74E338DA35BB1D3B8D764CCFC8DA +:10E17000C30A9B3C483B7602ED1874AD407D05BE5A +:10E18000B1D895D9B153520E6E6237217F809E5F10 +:10E19000931FD1801EE0CB6BB8EF331856DF52AC23 +:10E1A00084C8D47D809F22F0C3F70AD87765EB0B33 +:10E1B0007F56C6F0F6028053C4BE621A598B7EE3C6 +:10E1C0003F821ECF64B417E609A4DBCE1770CC4E95 +:10E1D000CACBFCCF9F40B971143C3BC9CCE107D3FB +:10E1E000FB7AB7F38D345DA84710C9231D0A331D90 +:10E1F00017911E1F2031FE5272912039685FAA10BC +:10E200007DEDE5AC11ED791B76CD07795FAAF4A021 +:10E21000BC3F1E29E1F1D2141E17761527FD415E81 +:10E220006721781608B295D333F33E1E5109FEA636 +:10E230003946013A2E88FB285E92F1AA84F345788C +:10E240005C3936C2E38C4065BC841C5D6990F80E75 +:10E2500071D4586A7B5349C7385117E13FDD618952 +:10E260002306262619C621F946EEB8E1BA48DAAFE8 +:10E270005F17413AF648BF6E5C8FEDC5637D0D6850 +:10E28000E75C80F7DEF28CBFFEFED2FB5558967D30 +:10E2900038524EF85537ED6E1D07FB1D0A4DF662DC +:10E2A000D894AA49FA318EE81A0F7CC8A12F5B23B3 +:10E2B000DC0FCEB94EC0097E49BFEF81F0DB09EB20 +:10E2C000609AEFC038A08CC70177462A689C8C07FB +:10E2D000003EE102B8D00D26CDD33E35F77A770A5D +:10E2E0007E66FC6DB008ED3563CDE42FE2C29FBCC5 +:10E2F000D262BC36044239D012A327D8FFBE2818F8 +:10E30000B8135AA23098837FCB6AF779D06FB706DB +:10E31000D67B0631FE3322346FE39AD06B43167BF3 +:10E32000DB55C626611C705BC32DAF0D59F4ADAF34 +:10E3300090E38B7E26E1CECCBB0AE504F03D127261 +:10E34000A7160343F3FD2CE956E8E9D4510F223A0E +:10E35000F5C78D75CCC47CBCFA9446F5AF62968641 +:10E36000DF065B13093027E215F727198ECB8736B6 +:10E37000C2C717BE49F0CBAA5596B0E009F6672D83 +:10E38000C9812D5EDA850206F3B6CF5792DB61DED6 +:10E3900006FF5DE47FB62DCAA7F7B06ED20DEF6F12 +:10E3A0009DDA447E4BC657EDD16890FCD315C65319 +:10E3B0008767C7EF41BC5CFEB45DFD1CC97FC6AE7C +:10E3C0006E8970BBFA797C2FEDC7DE23AF90FD809C +:10E3D0001C84F8DC05FCFEAF1CFBB84DE84157314E +:10E3E00097437BFFD784BCBE3B3DDE8AF31BE0D363 +:10E3F000FCB3DE7FBCD92EE34DC1C72BE50FF0E3A4 +:10E40000DF2216BB0CFCF84AA46A381FE0D786F658 +:10E410004295D6E2094543F9CF13CD479899C47187 +:10E420001ED64C40AA37CED0DF0D9F27C570DC6AC0 +:10E4300041DF7BB5C7FF09E10DB76BC61311CA0BEE +:10E44000B93C4BBB0C7AC9FDEFFBB4DBFD0EB0A7AA +:10E45000804F07BE9A9FE93F24F6B9B7CA3C84EBC8 +:10E46000DE50E65987FC7F5031FC5E15EB9E66233B +:10E47000DA11A6CFCA1A377C9D6D34CF4085B91109 +:10E48000F59AE92B4681DF2ED6D5B9BFD0391DB01C +:10E49000EE57F32767DAA3D1F5FD88F173C4BBD536 +:10E4A0008CFF0AF5EEA580434F28F4243DECAACE5C +:10E4B0004B2AD02E9865BECAF711EC284CDD157892 +:10E4C0008BE2A2654B148AD396792083CB6127CF48 +:10E4D000087FB34CE7FDECA4E1B7D63B8AA38EECF2 +:10E4E000BC1744C2B0D62FA28EF5589797FE0CEBFE +:10E4F00026B9F4EDBCD027D5FD6619DAD5979CB9BD +:10E50000EDF65B1117C12951519710FE6F959BE7EE +:10E5100057EC67809FC5BFF65685FF47D8AF84622A +:10E52000F18B0313CF93BDA31ECBFB65A2EEC4FA00 +:10E53000B3E79174964459D6BA20AF8E28AF63A83A +:10E54000514BFF2A95F1BA475F36BF001F4F94E247 +:10E550003F3634023EFB72E273221B9F9228DF9704 +:10E56000DE2AA304E703FF3C16D7EF0883FCE5E0AF +:10E57000EF1333C2D762BFC6121D15E5978C5BAF90 +:10E580004338D9B6C4AD7A34DBBE9647B97DAD8881 +:10E59000927DCDBD6EA5E0DB95DA87F7ABF73B6CDE +:10E5A000FA2E9F5D834F1554021E6E77E2B3A4AF1F +:10E5B000D32E4FBF3F7E5DDF44A4F390904FB4ED68 +:10E5C000186F183A8F473E1DE5721CBA214970CF6B +:10E5D0008C107FA4E1803158971B290E99FF3EE3F0 +:10E5E00090AE850305384FEBDB7B0B308F7F6628C1 +:10E5F0009C330E3954D64D78DAE390DE11E290BBAD +:10E60000A23C5E3DF21B17C5153567B99FAF39DBDC +:10E61000ADEA209F7747B9DD9E3FD4A79A202735E2 +:10E620001887C03CBD220E41F86D20BA91B7BB558A +:10E63000C46BFED93E1A57036D8C43E68F108700DA +:10E64000162ACADD819AAE5FE0BED9E97DA1D2DC8F +:10E6500012B5E45BD5837D744E22C77505B6179855 +:10E66000B4CFD972737836B7BF99715CDEED702381 +:10E67000C957ADEA0D607DA093E507910FEFE48DDA +:10E68000A964453CAFC1B8B8134181EECE9305C92A +:10E6900004E6D51EDE7F6FFE98BDF894F6C723F41E +:10E6A000E29DBCEB92220F328A60FCBDAA915A0C0B +:10E6B000FEA073CA977C9C9ECDA4475B046FC2BB2F +:10E6C00035CAA76FF6F37D90F1D78BAB148A0F6133 +:10E6D0009A254B017E9E98DF3587E78775AA97E0DC +:10E6E0007604781C7973E23CD52FE60FBA741DDAF4 +:10E6F000F306EFE2F9A2FAECD1028CF73FAC311548 +:10E70000DEAF6A8BB7927C9E74513DC3807FA89F19 +:10E7100055FD3DC4B7822157569D231F2C59CA125F +:10E72000B7B86C6DA6AE29CA6587E4D35E87783228 +:10E730002AF2CF4A36E322F0E502BBAF0369734FFA +:10E740000D1F79940D1F2FEB0B9B66184FA37C4C6C +:10E75000710E7EF769E057EF1B2EAA5BF4EED9F33A +:10E76000D14AA02FD1AD515D57E6334059C972CC83 +:10E7700067910754973EBE1EE5F260A16C8341038A +:10E78000BC0FA6CFEB37AD372CED63D1074EA3DF1F +:10E790003B788D843FC7C7CB7662703DDED7383873 +:10E7A0009EB72F44D54713B4BF831AE5D15B7FEDE5 +:10E7B000CD651F8FD772FD92ED5BAB3773791D6509 +:10E7C0001CD8F557ADFA21C7E52D35774C077E1CCF +:10E7D0001C72D0F910E459298C0F36CD305F47F800 +:10E7E000074F70BE1E7CE31E1FEE937BECE0E772CA +:10E7F000D9F9DF0B7F94CEF36672FB016E4E43BFF7 +:10E80000B56BD133C72A619DE3F3A7CE528104E0F3 +:10E810008507E36539DE5D5B91A587B756BFACAE72 +:10E8200047FBF3C6E9865CFA5E1535FF944D0F3F52 +:10E83000176DEDD688FF25CFD7EFC57B3FA99AEEA0 +:10E840003E0DF6B7F7F70E86794AEF7491878F84FD +:10E850005710F02AB92CBCF6CCCB216F8097ABF6C1 +:10E860009AE178BD54CB883F2F541A9EDAAAE178FA +:10E870003251C75C20EC7DDEB92F51DDB177D0413C +:10E88000C5930B437B55143D59FFEE3A518111104E +:10E890005BBCE4948A2265DEA766E9DDBC13F95906 +:10E8A000ED3B9BC766B5576F9C98D143F86F457495 +:10E8B0007256DBEDBF29AB1D62B3B3DA0D4B6ECEE2 +:10E8C0009AAFD617C96AD7FB3F9A057F8BBE32AB8A +:10E8D000FDD1C0EA2CF8A5C10D59FD35BEDD0F6094 +:10E8E000F9283E6DA63696913CCE44BE16F41B2404 +:10E8F0008F0F9EB8C7877291AA894F42791B28EC67 +:10E900002BC3FAF58BCEDCF9DA7DB5AAF4DF65E826 +:10E91000EF0DC6F335091FAA18CCAACB6FA8E5FEE8 +:10E92000796DAD92B34E60F7C7D20F4BBF6C5FDF0E +:10E93000EE77EDFE76D987F67A78BD9FFBFD5542DE +:10E940000E5A033FF762BEFE6203AF237495C5A95A +:10E950006E3020FCF39155B74FC273B5FC8039D6A9 +:10E960005D9EF1D7914092FD1AEB3CBE249B3C1D6D +:10E97000FB936CC374AA4B6B9169FCFD0DE2FD5DCA +:10E98000F8043F5D67E19BDDFF863C337F5CC4326A +:10E99000F14AC3BB46B408F0FB48D3935A293C2341 +:10E9A000DEC39AD50E1DAFF96DE9087EFA93B53630 +:10E9B0007DC271BD432B2EE9075E6FE175F7EFB79E +:10E9C00078580AE83BD9E2A3E72F5BFCF4FEE51692 +:10E9D0009D9EED2D017AA65A82D4FF8B966A7AFE0F +:10E9E000A8C5A0E7F32D317A1E6D8913DC4F5B1AA1 +:10E9F000E9F9B31693DEEF147AFA41C1C708C8BA31 +:10EA000042FC884321BE36E055DD05670DD56AE737 +:10EA100081AFFF9A8BAFEFD79FA46A7A26A29C8121 +:10EA2000BFCAA94F3DB532AE4FEF37E125E361CC08 +:10EA30005F504E649D0EF07B0CF173637DAEE4CAB3 +:10EA4000F13BA870BC0E16F3FA0DCEB3BC10EDF975 +:10EA5000D7E361B2E7D7CC247BEE675AB63D2F1FD0 +:10EA600066CFD791DEB1A35827C5FA229D53D8EAC5 +:10EA70002045753A8D93759045EFF23AC868F403D6 +:10EA8000DD47D16E49BB7DB974DBE93D3CDB7809DC +:10EA9000E791FE7998FF30EF26FF512D7496696F4C +:10EAA000539C5820E8D9757A4511DA173722C8F3F4 +:10EAB000748355E33E33791F60EFC6B2E1F3BE5E67 +:10EAC000D343FE7C473ACE7993E298E1FE2B9B0F2D +:10EAD000180B59FD3BF0E15CB65FE47CA8559F1D27 +:10EAE000DC0EFEF9E020E375B239FCBC4EFAC183BE +:10EAF00067791DE382A624196C5D983577CF83E78B +:10EB000081FB59691CCF9B263982FB01B4E0B95EB9 +:10EB1000DD0370A141736C1EF457A7F2685C78C9DD +:10EB2000CC24B61BE26F927D0A6BD97E1223D4B43B +:10EB3000DFA1225889AD3D2103AFE2FE5664DA30F1 +:10EB4000EF27669B5A1DD0B5E27C33D3617E7719DF +:10EB500073D2FD90E1FEFD6EC55267D358B003E954 +:10EB6000D0BEB0839FEBD9E44DF249D6DB641EFEE4 +:10EB700008337C7539E2873671EE623F6F796BBA84 +:10EB8000E94778C5F73C9DB7B08D8CDF8F70407E2C +:10EB900082FC1BE34AEE2F1F2E77DF9B75CBA43A36 +:10EBA000AA532494AB93B7772B94B78BBC89E99F76 +:10EBB0007158F3189937D9F3A387849DDD897616A8 +:10EBC0009E0F3919E55BED4A7E70AF92C997C06F11 +:10EBD000CE40BA16D589F317D63C8F9FD3DD9F95CB +:10EBE0002F8D88B7C84B9CE97D2FF39D29C8ECBBBE +:10EBF000D7D5EDC77B8E9D33BFD1B81EF936D34331 +:10EC0000E79C4C4BE96877ECF4305F8295CECDEC15 +:10EC1000B7CAB433589FED806006CF7B1FC62F0163 +:10EC200060BEC2A0232BEE29AACE8EDB6EAF9376F8 +:10EC3000F6EAD0810240E7DB124F1617E7993CFE57 +:10EC4000F488F76D3AB7170CED9DE57CBDCD6B7878 +:10EC50007C96FD7F10F7C73D323E6A799B0FEBE053 +:10EC6000DD5E07E97787AE759643BBC3ABF1F84627 +:10EC700077C4729D43EDAA5304DD1C2F9FC04B0D3A +:10EC8000ADA03868A4F5BA84BCC876FE34D3207D24 +:10EC9000D48371CC935BBDA50AD64765FFA63A45E0 +:10ECA000C84B37F1A153C455F9819E9403E56CFC20 +:10ECB0005DB3916D1E8893CEC07BCFB41E8AABBC72 +:10ECC000135C662EBCBF2CE6EB74066394F7173A10 +:10ECD00018E6FD9DE5B9FDE83FD7F138B3559F151E +:10ECE00047F804F065AA321CEE53420E1E70821CD7 +:10ECF000C2FA9D536FA37B629D9318D9EF8AFAE9FC +:10ED00008F6EF3E69043FD33B47F4E1F93E7EF59C8 +:10ED1000F7255AF586C675B0AEF6320BA2CDB0EB2C +:10ED20009B73FC8AC67578DFA23A3F88F0B5EACFBC +:10ED300012C8C7F620A37A8756DCE441BC1F2CD347 +:10ED4000E87E449AAF33CCC7D07E8C26DF767C60D9 +:10ED50003D92BB91F6D78E1F85F2B32E015F6C36C4 +:10ED6000C673CCF7CBB45E65CB977314F91A8D9E3E +:10ED70002CFF5A96F1AF3FA9DBBC01EFA93DCC783F +:10ED8000FFB1BA30E5FBF6F6D5D2F356ADBB11F7BD +:10ED9000A5758A8BE4CF3EBEB39CE3D5F57C8D5838 +:10EDA000D7A7A0FCEFAC2EC943FBEE45436DE16B4A +:10EDB000AAD23C5567F1DFC5D1661EB7D731925F45 +:10EDC000AF1EF74D01B9F0F6AB2053C077C75FDE39 +:10EDD0003DA5BF7F3EB26E83E4964C3B975BF61732 +:10EDE000E04B9110EB31ECA13E7E5F640BC1497E9C +:10EDF000EDBAFE0FC1D425F8366661767DEABDD640 +:10EE00009F94FAC252E2731ECB433E5F60F729E43F +:10EE1000BFA306E99D2F6D57F9BD9552D90472B075 +:10EE20004D22A764EA520CCF3D50BF4C46F10D4134 +:10EE30008E13475E44B78FC64D14D34CC00B352A92 +:10EE4000CA3FB7BB17D81B7C7D1886F756948483BE +:10EE5000FCECF528D70057CECC3F9FCA719F679234 +:10EE6000AFE9C90DF09C582FEA69829ED1F821F1D3 +:10EE7000FE5BC9AD8C0FEC755459677D1AEBACCABB +:10EE8000E87554A69D27BEC9F8D75E5705BF5680C2 +:10EE90007C7FE7068D7511DF79BC90C9F34D8FF546 +:10EEA000FE9DF497EDBE1559F5F97923D0FBD428D2 +:10EEB0007EB1AB1FEC26C6D1FEED549F3F7072FDB4 +:10EEC00051CCE32FF85D3AB3D8FFF6C2ECF3033927 +:10EED000EFF67A51871F5FC770BCD66732BCB7E7C1 +:10EEE000F207C92FB42AB9CF1DBAEA1DE2BCD1E698 +:10EEF000276CE733FF9DE74DBA2A58DA7FA8C23E58 +:10EF00004BFFCA34F0A2E3ACE3B91D95FC3820E214 +:10EF1000D1AEE736D13D03E6B7D47D2B72AC6F8F0F +:10EF20001B0D43F7CDCDC4B1CA208F5FE5FAED22AA +:10EF3000EF6E3DC9F7235FDC37B2D30BF1EF17EB70 +:10EF400081DE8280C356DFCAB637F678D8ED618994 +:10EF50007C8BFD8378B8A59EE284EC7876428CF1B8 +:10EF60007B41C526C3FA4FC46FAA58AF99DBDFAC0B +:10EF700032A07BDEC94BEF47633D8F17DA03EBE32B +:10EF80009837C9FAF3AE451F21FB0A7EB4BBDE6297 +:10EF900077E57D87F75A8F92F23A57EC637A7DFBDB +:10EFA000BD94855BF8B9D1C97B8EA13C1E00794424 +:10EFB0003FDF5E98D8311DE3939755B65F1F5EBF64 +:10EFC000B2D325EB506363FCDE8ACBDF7E64B1C332 +:10EFD000C29FC1665527FE180CCF8934714E64AFAD +:10EFE0003BB9DD4633FAEF548DD168AD3B4BBE35AE +:10EFF0000A797EBDA699CEB19E1EE1DC58C2E1E73A +:10F00000659887CB3A56D90CF359E4EFDCD86615EE +:10F01000CD48757C33DDBF2CF81746F923CB5792CA +:10F02000FB61A9E7163D43F9E59FFC8CEA6C2ECC09 +:10F030002F4B319FE4F9A5CC5BA59DA8559FE8A86F +:10F04000C07B1DFD1ADDD32B786E9307E3DE50FFE6 +:10F0500006CAF10C655501EEA3BCB724F1BCD2FC85 +:10F06000B40AF353CBF94AC66EC47E8572D0D5126A +:10F07000FF5514E4A3B7C5A0767B4B233DABB4A4E6 +:10F0800081F4540528E3630B86A0DF8247555F2C8B +:10F09000ABDD5569FE86EB553CEBBDDB0FF359E468 +:10F0A00002F2E3730837F724E7A76B8942F711965A +:10F0B0000DB207B86EFFC3D8A182D8D5B143BED870 +:10F0C00025ED103F67750D8A73569BBE3D5EAF936D +:10F0D0001EA4F50ECF5BC9CF25683C9D19CE077ADB +:10F0E000C67C92DBADCCBD0EFA9E3124BEB3BEF120 +:10F0F00068CD3E8C67DB5F95FDCBF719967E9688D1 +:10F100003661EDEF3026C71067761E2D6DA2EFB089 +:10F11000C5773491C6E2B20196B9EF68E7D74331BB +:10F1200047D67D9A10E3F534D9BF3926F24320073C +:10F13000EB76F2BE443EDE97C811BFFF9398EF5EB8 +:10F14000E453157E1FC2EF2B2CB67D1F62C42EFD2B +:10F150007D4842F48FF63DC81D319E5F98623DFCAC +:10F16000FE3F86F8C6F97718EBC57E2DE84FB68EC0 +:10F17000C120D1CF72CE138F713FFF428CDF7771E8 +:10F18000F90D0DF705E65B4172D0C8EF67CAFE05C1 +:10F1900067D3FDB7D17A0DBC7FC15993EA48F2BB62 +:10F1A000BC78ECC67DDBB4CCBD9C76AC4778F1FB7B +:10F1B000147EDFE9DF059DF6A7FC3EE5369FB8DF4C +:10F1C000C326EFC3DA66ABC1BFC7BC2576D35042B6 +:10F1D000A3F5EFA2F5C5F738D5825E78BF89DEDBEF +:10F1E000FEBF024DB1B27DE23B9E4F115DCD1CEFE3 +:10F1F000F4FF2721319BE44BC257C7663509F8CF8E +:10F2000012FC460E9F431E843C56119E9731DFFD33 +:10F2100084DF1A8EDF87627AD6F75F526E016E3B0B +:10F22000C189EF83FAE31B3C68CFD3DFFD27A6ED4E +:10F2300033A65C169F76D03CA65C8FF3497573BDF0 +:10F2400090F22FE5E1BB621F66C61429575FA6F155 +:10F250004D578DFE6F123F6DDF238D4647A032BEA6 +:10F260008FF0F0A7EF23EF8FE5D6CFF7848FFC7EEA +:10F27000CCAE17CF0AFA61DDEFD13A6541BA9704F7 +:10F28000EB3E7535D685797F407CF0A4E7FD21B54E +:10F29000AF705E56567A59F74AFE0FED913B6F609C +:10F2A00046000000000000001F8B08000000000066 +:10F2B000000B93E46660F8510FC181486C62F11A4B +:10F2C0007606866816068699AC0C0C15402CC74944 +:10F2D0009AFEE540FD8B80782E10CF00E2C940DC1D +:10F2E00007C49D40DC02C49240F34480981F88B953 +:10F2F000809815881980F8370703C3370E8439378B +:10F3000080620F48B41B84AD7810EC3340FF6F046B +:10F31000E2AB6484C3281E1E389D9F81A15A00C1A0 +:10F3200017104495CFE047B0B94429B34B1AA81F32 +:10F3300000656D40B4800300000000000000000084 +:10F340001F8B080000000000000BE57D0B7854D5F2 +:10F35000B5F03A8F79666672124298842027103091 +:10F36000680A4380088AF51022624BED48A9622F93 +:10F37000B5038D80104854ACDC4ABF0C4C8020286B +:10F38000415141910E0816156D44AC58D13B20B542 +:10F39000B4B56D6CB9D55AED0DB5AD2F0C8852FDD5 +:10F3A000FBEBE5EEB5F63E9973CECC24E0EBB7F778 +:10F3B0000F9FEEECB35F6BAFD75E7BEDB577DCB242 +:10F3C0000B0A07029CC49F0B006E7103C098743A2D +:10F3D000F2C66FCC7F6834FBFDFFBA23DBF5743DCA +:10F3E000331D0812D50330008A012EF0B25F59BDDB +:10F3F000893F3FF2A7114500FB40010FFB945227C4 +:10F40000F6F91AEB67DF8710C172F9E781B2CE0017 +:10F41000B68B53BB2F036F972AD7CBB42ACC808CE3 +:10F42000DF0D2FFDCEFA19BCA989B53FF14180DA75 +:10F430003BE13053F850869468737210F6ABBED738 +:10F440005929F2E5C00607016F1D404D1ADE03AFD2 +:10F45000BC46F0EE5719BC7A96F1BD0CFEA234FC06 +:10F46000FBE01BF950C5E1376AD2F09F2E3C34FF18 +:10F47000BE002B9BF5272B5C003737C39315430049 +:10F4800056377B29BFBC59A37CA2394CF9952A6B0E +:10F49000C2F0B0721B24E3AC7D6834AB6FF6C7FEDC +:10F4A0000B54796D7977116BEF4DE7D540D896F70E +:10F4B00096E9B63C03E75098CDFB2C319FE5CD0C87 +:10F4C000071E1CDF0BC69958FE6DC28B4FE02D1135 +:10F4D0001C7AF9208697D6E715466900976E4C4747 +:10F4E000F82A026E3DC958E3ACC0EC29309C8D1B54 +:10F4F0008A01B07A89DB016E65700F0B4C7A03428A +:10F5000000F7B1FE5B59FF4AA8F5450F2B5F55EE9A +:10F51000D615C4CB0EF52F9D6C0C2FFB87783B7353 +:10F5200003CFA7E7C5F296790E034B396BFFCB8269 +:10F530003B5E94181C890AB7EE91D2E374D3A59769 +:10F54000FE87B4D9F3CEFE2B74A316F9D4EC77085A +:10F55000449769812F6EBF6731DCF6294CF76B8EBB +:10F56000D36BBF8CFC51D676C80648A6CA33C7A950 +:10F57000D02393E3ACBC62830AC972FEBD88C94341 +:10F5800005FF155696D5FA635599F080759C41692B +:10F59000BA54E8EE9932E38B8A8ACBE64B8C6FA0A3 +:10F5A000CD42E7419C41515ED6366BC48F37375709 +:10F5B00052BAAD596B27F9F94899DE5E9529877FD4 +:10F5C000453DC5DADDE202E2C3F876486E97B0BF8A +:10F5D000E8F4992CBF666471F54D3AE6A7CBA817FD +:10F5E0004CFE5E23E9C4DF71C6DFA8FF9CF271B355 +:10F5F000CBF80AF6B76AA42C2D433C57707EAF7047 +:10F60000A5BC83B1DFB64123E3D84FE4779D58AF63 +:10F6100062C8505D61E30EABE0FCFFCB31777851FF +:10F620000F76CF7F71717BC528807C071F68A7C8C4 +:10F6300007DAF89EF9C01CE7D39687CF8EBFDA7A37 +:10F64000E4AF35915BDF40BDB1AD82EB0D275C25AA +:10F650000353E1682093DF2A2A189F219D223DF35E +:10F660009933BDBD3909AF321EBAAD394C7CB7AE46 +:10F6700059A774B5E04317F25409CB0B3E84A2D1CD +:10F6800094CFB95EC1525A8FFA4E4B428CC1791B4E +:10F69000F2E7B9F87DB96194B1E695661E5232D3AE +:10F6A000FDEBB0BC94F20694217F9AE58FC40DD691 +:10F6B000BE50D49F243D124F3024DDE6E3F9C952F9 +:10F6C00097112FB3B65F6D18E3D3F5593E555B61C3 +:10F6D000ED8FF55F6585E719AA6FF6572F1D36E2A6 +:10F6E0002CBFCEC7FB6B955EFC5CFABF496A0BE38F +:10F6F00042B3CAD1CF4D663EDE661855E971CA974E +:10F700003E6CC4ADE5F0B0ADBC66695B3CCEF07656 +:10F710002744074B8CBE2553A26160F4F7459371D3 +:10F720005C6AD3F0717CA7E77707C1EBAFE0E555E2 +:10F73000D2EF8D84853E13A4DFC4117ED3BE510465 +:10F74000BFCA3F2FBBEE39C6AF4ABE3B4276461119 +:10F75000CB8C63E34D8B81CEE090C331407DA084A0 +:10F76000D5BF5BE5C0E43F06E75882B32E3A3D07BC +:10F770009C712B9C261CBDC16DC2919B4FF9F84E0C +:10F780007EAABD64EC6FC73316F775B82268E7F53B +:10F79000413C313D001FDE66B8D8F73E5319EE7587 +:10F7A000A2DB74189CD96FD19452485AD6F14F9B62 +:10F7B000AE83313F86F0F61D694C9ABE2C3FD38A4A +:10F7C000C7B1A29E93FFCCF9B933E6F75DDBFC40ED +:10F7D0006D0B4783BDCF6F9D2F323D1AC8ACF74BE1 +:10F7E00089DBD1B593C67E1DF878E061FAAB00C71E +:10F7F000AB4E8F57F015361E76A626B38E5758C7D8 +:10F80000C6F37E76F874CAA309AF2F03DEDB6CF073 +:10F81000DEE462729B85FE9F35BCA72A7F7EA67FB1 +:10F8200049FE2A7B96BF4FBBBF02FC95F1D3BB2A92 +:10F83000A42E60F85A74A1371997D27AEEF3C657FE +:10F840001F2C62F45BF4EB51872F9031C3F8FA4B15 +:10F85000E9F1174A3AC19D8BBF73CD072069EBE7E9 +:10F86000FFD57C72E1F5B3D643A7AA5F97FDC14FE0 +:10F87000FBBBE5159044795A7EF042DA672E7F6E25 +:10F88000623F60FDB85ACF06834DAA40D819CBD14C +:10F89000CEC0FEEB4ECDCEB8A919DA5B98D1F558A3 +:10F8A000284A76D17209A8FD1A66B72599FD32FA61 +:10F8B000F96DDE9901B2AB285DEE02B263463F7F7F +:10F8C000409BC8A6E01F523812797FB9CFFC7E68F2 +:10F8D00032DAB9AB2BD877C61ACB83BC3FF63D8A58 +:10F8E000F5F386F0EFB9E0CAAB64F058F0EE732799 +:10F8F00063D9F4E3976599F0B351D85D37A3DDC5BB +:10F9000014B2CFDF1643BBDA5FECD6B74A99EDA647 +:10F91000CBDCEE5F3FE427717469AC42FB8DCD7F99 +:10F92000FFA5F7416715AE836D868CED23DC35B0FE +:10F93000D1B1DE07D086A375332C4D646BA6DF9161 +:10F94000BFD9AC1FD727A0BD16AAE4E513969D3FEB +:10F9500021612D87111370DD35CBAF5C3686CA4B24 +:10F96000BCD117C7B3F14B98FE4C303C95A86D52F3 +:10F9700013D1333BBFACBFCA3B3DC960587FE91DC3 +:10F98000E55765C113A322D1D9CC97D6DBE56BA38C +:10F99000C0DBCD028F6194718B5EF3F1AADD7ACD6D +:10F9A0007726D76BFECAB6A588E7D27A88A09DBD18 +:10F9B0009EE12F6619DF5769D76F25AA7D5E9FD517 +:10F9C0007CEE04E30AB96FEEFE9DF27527C4666211 +:10F9D000FD12B18EFB2B9352ACAAF7F93BE79B6B60 +:10F9E000DE5F15F864E32CCC36CEE7859792001BDA +:10F9F00067F4A73F8EBFDEAE274F15EFD0B0CDC066 +:10FA00007D359A9AB86FF6415D2445FBB91BC90F45 +:10FA100077BD801D621B35B46B120059F5995AE110 +:10FA20004EFBD3F07FCA8CFC6C7431D3C52FBF530F +:10FA300070C0523F29078BFE9EC77E3907CE39A979 +:10FA4000A4DB83F0F7A9261C8142DBBCDE6F3E56A7 +:10FA50007000FD72DAD47CE861BCED4C8FA6987C16 +:10FA6000DDDBEC851493AF2DCD1AE57FC8E40DD313 +:10FA70007B98FC617A37DB2F62F9C6E608E5EF6C0C +:10FA80001E4BE9EDCD067DBFAD7932E5D73547296F +:10FA9000BFB6793AE5BBF1F9211BAF46F02B9BC706 +:10FAA000908A645C463FED6888303061257EB7C03F +:10FAB0007FB33CE16919FD9ED37DE4DF0808FF8632 +:10FAC0009FD17730B63BA4C076C83DAF04CE8BC182 +:10FAD000F11545E6FE53B592E4C56FCACB7A20BF57 +:10FAE0008A2FC2D62DA672D582BA42E4775F847F70 +:10FAF0000F54AA4974C1048160C40D7C727B39958E +:10FB0000A77CC3A90B15FB1B21F8A3352053BD35DA +:10FB10003B787F4E3E1951BD4B6614036F50E5F59F +:10FB2000927CBDAC1A752B7D6FD5641A77CD06DE3D +:10FB3000DE57C9F8C6C2B7616510CD6367E8406992 +:10FB4000391BEFC7C1FD8306B3741DDBDAE0FA751C +:10FB5000EF9AAD85332D7E24AFC2EDF360DDD6A9DB +:10FB600015AC1E1BD6C0719535FEE4D672A28782F5 +:10FB7000F09DE5E3F007BD7CDE4A0324715D32CBE6 +:10FB8000CF2EE03004B58811ADB27C178A27A827A4 +:10FB900097F9B15D2B44B6EAE9F24AB39D616F571C +:10FBA00069B68BB7EFA7764B583B48970F2B10F0F1 +:10FBB000C0485BBB61269CB04CA676717BBBA1A202 +:10FBC0009D39FF61DB3A24AB9C0DDDD02971B9B1C1 +:10FBD000D32517FF8C0021B7FBE3D249C4473BCFA5 +:10FBE0004B92B7F52423D5D93BEC723D2CE990F329 +:10FBF0000D6E9B1F3D8AB2CBE8B156D06B53537646 +:10FC00007AAD558F1D44FB44D9A1DAF069D269ADB4 +:10FC100057D0B1C94E47934E6B3541C7A8838E026A +:10FC2000EF6B4D7ACDC84EAFB539E8B5D6A457CCF9 +:10FC3000DECEA4D7DA1CF45A6BD26B5A767A39E945 +:10FC4000316C5B8CD69D34DD2294FFACE8E1D40BA3 +:10FC5000CFC93A7D97D71BDA04D40FF52ADF275591 +:10FC6000A600F7035056D88BDD1A17F64913E0BAF1 +:10FC7000700BFE6AB1CBEF75F3FC9589C313D00E00 +:10FC80000F75DBE1FB27A03F6C9328BF2E7182CA62 +:10FC90001F97A33185FA4BF2F11DF8F24493B0811E +:10FCA0008154AE6A175730BE285F2347E21639F0F9 +:10FCB00080892710E737A7C6FF005CFF2078270759 +:10FCC0009F129CD72B84CF24CD3B034EB6BFDCC004 +:10FCD000F635A582BF4B9B189CF0E9C309F57CBDA6 +:10FCE000E85E9F859DE482ECFD54AC916D7A765080 +:10FCF0008BDF96D79714DAF2672C2AB5F15559C3E2 +:10FD0000205BBEB4FE2C5B3E3CA3DA962F9E76AE03 +:10FD1000ADBFA229B5B6F20C7E11F96DCA4B4B6D81 +:10FD2000FC121F5A8BFBB64DA27C4762682DEEDB9E +:10FD30007A2BFFFA55AAE165F8578BDCB4FE300A3E +:10FD4000127E4C7CE56B1077A3BC16059217B1723E +:10FD5000BF66C4C91FA019807684ACC528EF0ADB32 +:10FD6000D7A7AFA1A1C4F8F4EBEB54E8A57FE3E378 +:10FD7000F4DFDBBC9CFC62AEEF4A115F4FD7B1ED04 +:10FD80009284E7224C3FE23AEE62668E2F847C2119 +:10FD9000F887F133EA154D9584FC9E9E9C0D6CB559 +:10FDA000EB9B01717BBEFF62FB7C4E95BF3F2FF941 +:10FDB000ED0D7F6B2112574E017F115512E7D5A72C +:10FDC00027FFE11976FC144F733BE4C4A1CF3F67D2 +:10FDD000FCB598EB0568B5B8FE065AB80FE5DE35F8 +:10FDE000FBB55816FC99FCB2AEAEDA6FB543206293 +:10FDF00099D7A0F4389457B2E5BF687C929C40F63E +:10FE0000F15C36FF72B46372CC5FD07BEDF8FDBE5F +:10FE10007FA5F9A7E9FC83D36A1FEE86B74CA3FD43 +:10FE20009A9977ECCB32DBC7B9BE89F964AB9E6493 +:10FE30003F952AE3B310F82388E7F77DA1E190CF3F +:10FE4000F6875E9E7ED6FBB67BEBF87E26FE725E64 +:10FE50007208E253C471DCF2F2979244F7F132DC9B +:10FE600081E5553295DFE00F6D45B8BEA9C46E50EF +:10FE7000FB22BC6724F1BC18D44E6DEA972CF31416 +:10FE8000769139FF5CF6D1B296EBECEB194CABB541 +:10FE9000F2E39D2D2BA99CD91D2D2AD1EB8B621F3E +:10FEA000E58473A3FA05B68FCCF30167FB7F15FBDE +:10FEB000E8A0DAB0CC6E1FEDE17410E5CFB5ECA987 +:10FEC0003D9572D33EF207DC621FEFB05F2A997D49 +:10FED00084E7470161BF5426C95EF15526B9FD523A +:10FEE00069DA33F6F5EA1A3440C7A4EDA31EFA37EF +:10FEF0003E4EFFBDCD2BD7FAEE0B98F6511BB78FB8 +:10FF000018EE31CE44A9E47E0EC5B1BE8F76E55819 +:10FF1000DFFFD7D847D9E5B737FCAD85366E1FF57B +:10FF200082BF69B9F0F72F6E1FED50E1FF33FB2858 +:10FF3000179FFCEFB68FD274FE74EC1CA75D63DADA +:10FF4000119FB57D63DA27CC8EA954516E999D859A +:10FF500076CCFB72BBF70E369F1B944E2F2E8AB7C2 +:10FF60000A795DAC46D7B968FDEE247FFF06D4E779 +:10FF70007D859EC5F601119FA74600ED9DC56A6C63 +:10FF800083CB720EA1043AB558E08B870766E7D998 +:10FF9000E72FF062E261B7AB40D0BBE99C289FD766 +:10FFA000A38407E8E4768CDAE9C5F449B1BEDD9BA9 +:10FFB000810F20BB5119AB27511FB0F64FBAFADAA7 +:10FFC000F0E2B5E185AD437C3C50A236BB91A7FE83 +:10FFD000D19A84FE7296ED40FEA5F3721DFDC26DAE +:10FFE000938732F8FBC4565C83F198C1972F7E0348 +:10FFF000E31AFB74CEA4F8C696AAEA83B5AC5E7E7B +:020000022000DC +:1000000044BB74928EEB2A905F71157646EB2624E2 +:100010002604C4394E29C06F969F10EBA60176BB0B +:100020005CD655D39F3428B7BCB01FE9A427B37D55 +:100030002EF97059E59AE4F3DA53934FA1F7E3EC04 +:100040001FEA8B02473FF9867D5D088225CFCA3FB4 +:10005000107CCC2C94CF653C0D6EF5EA8C3F5C1582 +:10006000B286F191F9A01520FFF9EB5448A1FFA544 +:10007000E8581C5DB0BDD1A505FDE87C3F0A975A44 +:10008000F613413797D7F0AC96F215ACDF13A3798E +:10009000FC7D1F8DFD579D399FD542BEBAF3555B40 +:1000A000E9DC34C1F86910DFDFD03D825515BB347F +:1000B000AB9E1EE1966CF7082CFB365DAD11F63455 +:1000C000C38F52211B68077C52FE503E267FE44DB1 +:1000D000B1DB09A74BAFF1E25EC5A9F2C7271DCF7F +:1000E000A46BA65C2D1574ADF7A2DDBF223CB5C78D +:1000F00073D44CBADE4A74F5578091CCD2FF04B762 +:1001000094357ED6B93F72DAEB4ABF9AE95B7AA2A0 +:100110005B91D3AEE5FDFA162BFA5F5179A91AADC2 +:10012000035ED1DF2AFDD638EACF13A813193E9417 +:10013000B6912971FE18D9CEAB50FC874F37489F36 +:10014000D279774D1A3E77997DBFA616F9ED76E103 +:10015000F4B86485DFB7D84D7078713CD4D31AD029 +:10016000B9A71AE0FEBD8CFDA3C36E5859569D3544 +:10017000CE40FDB4F6ABD3ECF09E72BB80AAFFDD9F +:100180006C93454FA7DBA9F0778B3DB506F9DD42AF +:10019000FF152ED823B1753811BE0C623ACB6351CE +:1001A00009402BA6E3900FABB97DB743A2F36012D1 +:1001B000691DFFE3E74457B875EA47F6C6084F4A9A +:1001C000C000AAAF9FDA39D2FB0378DCD220096CD9 +:1001D000F51F74BBA95C8528609CE2FBAF5C14A68C +:1001E0007E0DF6A9260D87B3DF2BDCB107DDD84ED7 +:1001F000E3F060035AC7C772BF40D8CBDBBD3F7383 +:100200002AC571E5826F43333F5FEFCE8BB82C6810 +:100210003DB5B8AEF7D9981D55C4FF7EDCD7421B5B +:10022000B787060A9A6D595248DFB7B4F42CE777BE +:100230000939DF8CF69187EE55D8E47E9B8837DB51 +:100240002E81ED9EC5100F8FCF7A4BC8FD166FDC47 +:1002500047F7159E59E51B8AF12E8794888FE1A1F7 +:10026000E22AA330D6031E86B4D9E5ED74E33B5EE3 +:1002700076678FEFC8D5DE8CEBF8A47821DBAC1461 +:10028000F1303B41FB96D405249F25826F4AD8FE6E +:1002900005F5D0C0382475ACFBE149B0F207FBD9B5 +:1002A0008F7E8AD27A3616D22B26D3B974E9EDEE38 +:1002B000A44CF2AEDD84EDC387141E6B0846606665 +:1002C0000DB12AB50F2BCF4D40511B2CEC33586389 +:1002D000BF7751B6C47E5FAAD4714F228CF65D08F9 +:1002E000FDAE967AE59F9C1E210FA3C7D99F3F3D87 +:1002F000B6A9865FB3B4AF9020DA9EA5BF0A0FB748 +:100300003B2AD6ADE77160F50178D5B25FDC2E19D6 +:1003100085B8186C6EDBBA14CFD9E2F51019C2F0AB +:10032000DDBF01642B1F8FF2E4513F2E30E26732B4 +:10033000BC2DFFF6659D4F215DC7834D8F65D11F95 +:10034000A33C4C5E5C455C7F6C6B9BCAD30F155A1B +:100350003FC24B20B98C8158178B2D7521FDE702C8 +:10036000C5A187EB9BF6617C754903447018C6579D +:10037000C45FE1E99034885FE05098F1C7003E1512 +:1003800018807C81EBCF224E5F932F4A1BECF76DD8 +:10039000C2F5F67CB1B0FB8B9DF7B71CFD94E8FC71 +:1003A0001E94BE4406BCF707D3ECF76DC2D079FFAC +:1003B0008F10BE0381480AF935EE18C7D1BF0AB1C4 +:1003C000CB3C0C9F8F7D7FCA2FCF64F57FB8A4B63E +:1003D0000FE2658B379A4FF78A5AB3C79D65F0AB2A +:1003E0006977E4A89FD6A3715B5CB3335D31A4F851 +:1003F000BA590C8E55410348AFC5AF20FDAE08F980 +:100400007DA6E4322FC6932E0F54537CD83ECCB336 +:10041000747978683F6BBC9822E277CD7C42E853D0 +:10042000E778D77BB81EFD3B18D7231E467A62615A +:100430009CB72B5CFCE84C9DCE0B8D649676733C90 +:100440007E6E5FEAEA3FADF8670BB8467208705AF5 +:10045000FE85599E582BF267BC966D2790FF074189 +:100460003281F46F6A137EF7EE7A378B7A71BC773C +:10047000D95D2FD606D67D27AB772BCE87D5336CAB +:10048000F5A219F5EE14F5C036AE9131EE26133E05 +:10049000B0F617C9E86F8BE88FECC1EE7A7A467F29 +:1004A000F789FE0C5B3D2DA3DE83267CB671C13E31 +:1004B0006E77F959EE6482F4368FA7DF3F6412F14C +:1004C000CB81219326CF62E35CF70B97D01157D2F3 +:1004D000BA6DF2D53E51AF05F9AA8AE2F05A1BF087 +:1004E0001EB0B8279C084CF5C62CDFBBF92A305546 +:1004F000CBFE7D96ADBEDAEA0363147DA7FA2D1F0D +:10050000293CBE395E5087FEB89545B28877FE5BC0 +:10051000C250991EEBABDAF2AD615E3EDCFBB74434 +:100520001CEF14897B304C573E596591EFEEF13F3B +:100530002FF8C579461AFE77134685157E9E37E15A +:1005400037F3DE125E5EDDFAEE44BC5865DE03185A +:10055000DCDAA785FC175FD8F9492DF6F9F17C7A2A +:100560007E3C6FCE6F74AB54F7AF35BFFC163BFFCC +:10057000F17C7A7E3C6FCEAFA635FFB4E6E7AC8760 +:10058000F79550CFAF1A725F18D79D55B890B27ECD +:10059000C7B6BE9058CAF237F535ED6D9DF4FB48ED +:1005A00030CEF28EE9BDDDAF30F8AD2FC6ADF2F33F +:1005B0006018E216E7C16D61F473BEE6D1441C1DFC +:1005C0008753F1DAF30331DF379D67BFFC13D7613F +:1005D0000C53E4FB49879EEF655D5B5EC2D79315C4 +:1005E000C1886C5DD7CC38E867FAD690FE49685C64 +:1005F000FFECEB2BF451115BD7B83F8FEABB84BE05 +:10060000BAB599BF17D026EEC3268AAA093F6DE670 +:100610007DD8F8249B7EDB3F61D241F45F1D3FC44F +:10062000DF8978C2CBD7BDE5CDD0CEDF3DF0D2BDDE +:10063000EEA759BF3156612FB3F730FD29B3F7301C +:10064000DDD31CA6F427CD3AA5BBD8B8983EDC1C58 +:1006500081181B7F67F3584AEF14FBABDB85DFF78C +:10066000CB4532F92DB634334BD985FE5F2FA5F734 +:10067000346B6BD421E8FF0D53FEB834758E97F6BA +:10068000AF9D897C06E763BFABA07BE2E38B545A46 +:100690007F414D29F9A3D3DF4DBC1E976A1BB0DD06 +:1006A000B96199D7F32613A1ECF5AEC17A63C32AD9 +:1006B000C10381B8122ACA5AEF7BC85F3501D19FA6 +:1006C000164B04B3F77723F6571D10FD15E9894043 +:1006D000F6FEE2D8DF708DE301C29DCBF2B2D75BAC +:1006E0008EF5AA3431DFB2949C977DDC9BB05E61BD +:1006F000611BDDDFB96006903DEA2AD2B790CF4298 +:10070000D44BF68D82CCF8BCB04F5B13D63B3F1672 +:1007100081416C7C3D140199F1B32BC0CAABF02E22 +:1007200039EB87A5E74D63E5AC5E12CBBF6429C703 +:10073000F62C1D375DB4CFB7979BE3B95AA1FBFEEA +:10074000345E1A77B5D8F3053297CF075AAFA8436E +:10075000B92F10E74FBFC63C1BD7B5044C7DC4EB87 +:10076000FB79F95366FD102F7F45E40B0BF9BC7D37 +:1007700093BC142F7CCFF5434B6655A5E73BE07B3C +:1007800095C36659E677CFF7CE2D991548CF67C048 +:100790000DE387CDEA61DFD367B2DCFD2609EAAD60 +:1007A00082B62AD29F233D51B20F47F6AB31509EFD +:1007B00095351CAEB7BDE52DCB54822B4EF73405D5 +:1007C0005C772FB0C3D57FA11DAEBB17DAE1EADF9E +:1007D000D8335C4F78B95ECB051F1BDFB08EBFF9F5 +:1007E000DFEDE39FF17DFBF89BBF6F1FFF8C1B3F8D +:1007F000F1F8292B5D365D631FBFEC5AFBF89BAE09 +:10080000B58F5F76DD271BFFD3B2C7CFF7C6FEE9F2 +:1008100015F6AE62B53B9B6236FB94D53B29EAF1F7 +:1008200073F46E7B3C66B34F593DD527EC5D5BBDE1 +:1008300068463D9F4FD8BBB6718D8C7143A2BF9463 +:100840006CED2F92D15F1F518FEEADA4EDF18CFEB8 +:10085000C2625CC3564FCBA837C084CF362ED8C7F0 +:100860000511077603C6814942DE59FDC533D83EDE +:10087000BB1CF7A15109F7FB5A1F1879807D87C16E +:10088000FCDDA382498B07E27A2E4D5A7C26AE7F8F +:10089000AD0560DBB74DF2713FC2189F42A99607C4 +:1008A0004DE4BFF336955C6AB9F7BA59D4EB2E0F15 +:1008B00034957CC3527E9168DF2AEE0DD6F97E4BCB +:1008C000F688D69FD5CFE237BBD8EC4F944351A4DE +:1008D000C36070DF79C5D43156FDBCD9E7A2F96B8E +:1008E00003C5B865D9E16A2DE7E3DE83E306F0BB13 +:1008F000697F349510BE359E9ADF6F0FCE96FE8AC3 +:1009000058DDE6A575DD2DD6F50277D38FCA191C03 +:10091000890132E0FD8695653DFB735A9AEDE70B40 +:10092000AA163570DF573A57AB46F1C8D5EEAEC9B7 +:10093000F2E46CE70FF5623E2D736BDBF0BE0E1C2C +:10094000B0FB71198383F53EF215EE58BD2F9B1F46 +:10095000B7C56BB36F0A8A7BBEFF65DE93EA9E075D +:10096000EB281BDD56FBC4F9C821AFCDDE2A289445 +:1009700069DF79A28A9F1B40BC84FC84DD782DADA1 +:10098000F55AC75FE518CF07530D5C077099427998 +:100990007157F07755FC456D5AB98EFE830E3A0FAC +:1009A0000471DFCDECB7253C95F6E327C43D5835FF +:1009B000DC3681FB1D057C9AD055629CD20D2AA4A1 +:1009C000FAB0B15DB1D5BE3156BAC5E95ED0FBAE65 +:1009D000E4C5F4DE5339A3BF9439FF3B7CDC5F7C74 +:1009E000973EF5B7E559E87B373A8B2DFD967EE0CB +:1009F00086D4A8DCF5D3F5385CDD7C1B66FC8AF276 +:100A0000AF0BBE751B3FF4658BB730F58338079F7E +:100A10003516C48F7EF99FD83CAE3EE8E2EF2E88B3 +:100A2000FB36E6F9D0D5C26F3A4BF85DEB211AC21E +:100A3000C2B741A67B496FC3EF42A32CF47FD2E734 +:100A4000E670B5BAC8DF659EFB5ED5E6B2F9C3E6CF +:100A50006CB0E767C3D462D45BB3D7BBC8BF76B50D +:100A6000C34FFBA098EF1C685A8176BC796F7B96C8 +:100A7000062ABECBB3E0F17B6AF07ED47E1FBFBFF7 +:100A8000F726E31BDD226FF3024937DE037875F7A3 +:100A9000A8CBCE036C9F5C518AFAB600B2BEFBF6BF +:100AA000DD563B7CBDC1EF841760598F70A83BA415 +:100AB000ACFEAD0E9F794ECCE9952BCEC38CBB38E6 +:100AC0002EF8A8DB0FF3E73CE187E1F117BDB57F16 +:100AD000BF97F60BBC9D6E949F46B569B224A7CF15 +:100AE000A73CAE98D19FCDD3B56742AA3FD8EAB50F +:100AF000F65CEFD824207DD914453E32EB2D045608 +:100B00000FE572EFA5715BBD0A566F70EE7A5D421C +:100B1000AFFE7CE7BD6EF447BEFDC0E14B502EE753 +:100B20003FA980978DDBB5330829DAC726DDB89F4A +:100B30009BB75BC97A9E4B1103ACFFF93F0ED27A8B +:100B4000396F97273985B59FF793578703C343D7E5 +:100B5000B263CFF6C775F701899FABC63B87E3BA8F +:100B6000364F85EF44B3F4D7D7CFF9F0C81379D314 +:100B700091CED28E7D5752BFED97BB3C167D11F0C2 +:100B8000BBCC7ADC1F77BF941C92459F98E76047E7 +:100B9000EE97387C7B5C491FC2B7638B3BC6E0682D +:100BA000DCF10EF1D5C41F3F14423C34EE516C7E93 +:100BB000E2C61D4ACA339CD2C31EBA8F6A04A41A65 +:100BC000C427D78F0B772F20FFF9C2F6D5EF282146 +:100BD0006C6FE76F8697480AF1FA82129982F9479B +:100BE0007F14D219AADEECD81E42BCB27E67BAF3DB +:100BF000F11CD8EEF7C6FE3F28CCEC0FE0981BF9AD +:100C0000ABB17D151F6FF7D75E43FDD2E890A337D8 +:100C1000F19792CC7397F3FD8E73B01D7D4EC9BED4 +:100C20009CFFD089CD7136EE915D6F6D8E33F81BD0 +:100C3000FEFBDDCD37A21DF4B44F433DD0F8C07F9D +:100C400086C0B26E5EEEE7F2D875FF8FEEBB8BC941 +:100C500047D71F3DB47E743DF5DA193A9B77D72309 +:100C6000FFA75867F5173D7521F90B163D36B15FA3 +:100C70004FEB27F26BD2FA2E99B87FAEEF61E3F417 +:100C800063D9BD2275D0E799DD0AF8189C6FBFE8DB +:100C9000A17B528DECDBE26AA4D702D2CB985FC273 +:100CA000F0BC70E7CA7794E1D9F01DEF2FE3A503FC +:100CB000606218467A7FE3EBE78FC6D445E72B8D59 +:100CC000708CF4AAB35DE32146D711B9E978023EEE +:100CD0007463DC4AE3CE557CDC7646C750261DDFC4 +:100CE000C65FC665D2F17B0E3A9E80861FE2F92070 +:100CF000ECEE93F55CD83C3F5BF0D8377BB4B74C57 +:100D0000BDD01B9EE74A1CAE5ABFB1C28FF2B5EBF5 +:100D1000C1FBEE2AE2749EC210D3F5D08933F052A3 +:100D2000F7EBAE6357A27E3CF69447C3F57EDE53E5 +:100D30002F90BC753DF6BC5B27FB1B0212B337BA84 +:100D4000A0FBA703ED8F8512CF346E0BA63CA13418 +:100D5000BD16262F9DAC87E8FB61FA9EE472B03089 +:100D6000B96F9A94857E4FFBF97D6E48F625BC2CB1 +:100D7000D8F627379D835BE82A8D457A1E9E84DF4F +:100D800073D1D39CBF86F33FC742D76D5C7E73C9D6 +:100D900069D7168F8A710D4E3A77B9F83EA131297D +:100DA000BD908DEEE63A78BAE7AA4F38E55BCCBB4A +:100DB00037F9EE7D3EA787AF1D7EDDC63726DE8E76 +:100DC0007C985DEF1FF24B028EA6C9A58333D741F5 +:100DD00015A2F1FEE569788FD0DB642C7D40A1F788 +:100DE0004E57B43F43FADBA92716E6B0B3FF26F40B +:100DF000D3C23DFB86A33E3BB2FF09E2C7853B0F52 +:100E0000BB717FF3EC8E47DD9D5569FEC775C1FA56 +:100E1000BEC59187F70D27FD8DFD67A1CF71D17FED +:100E2000E35E7BFF8D3BDFB1F53F3FDEEE26FF6AE1 +:100E30002FE3BCA91A97E37CDFEC7001BE9BF4663C +:100E4000BB32399B1DF4825817BBE36A82352FA24F +:100E50007F522974EBA8FF5A961A2FE0BB89F1E75D +:100E60005DFCDD4AD578D1C3E43351E0D671DFDBD8 +:100E700012BC0C748B1E6F73E0532BD226E07E40A5 +:100E8000AB8B8EB6EEBF4CF80B0CD906FFA2E0E49C +:100E90007EF8DE15EEE3747C27568D70FF7568D200 +:100EA00064BAF7A8C99A2FEBBACDFB43BF1DF2BFB6 +:100EB0004B9341B7F0D7C889979D8D2E3B1574DBB6 +:100EC0007E605D1D3F0F36E7BF6E006CC2C723D644 +:100ED000493CDE3F7E318F3334ED3B70DCFF72DA0C +:100EE0007B60183AEA2352473A1FDFB0DC734EC7E3 +:100EF000F1822E533C738436012AC42808C38B71B7 +:100F0000B68371DFD54E6980A9374CC7E70DE2FC87 +:100F10000DC7287FEBE4BF50DC63515E74645E5FF5 +:100F2000CC178A771452B4CF13CF06809C5756D271 +:100F3000933E803AF588D59FE4814DB49F4177E692 +:100F4000C93E69BC98F17666BFEB7CE3255C8F7087 +:100F50009EFDF19D367CE4A8989F1FF0791B94EFCD +:100F60006BE61DE3604DAD462CC1249A31C935189E +:100F7000CFF7DB249C5F29B4535A061D94167A35AB +:100F80004925F85E267F970C7F8193790EF84EC134 +:100F90008E77DADF3728FA4B3146C784D8E76C2DD5 +:100FA000B0C7237D3B8FEB996BF26433FE3966DD6E +:100FB000B725A08170E02BE2CF9375CB415EECAA00 +:100FC0003C0B9F29810E1E5FE6D82F5FA82CA1F352 +:100FD000FD95E19EE3BA968BF8F05CE56D7DBD333F +:100FE000B700C1CFFD609297C7791BA06B567EC436 +:100FF000589E1A6BDCA4617B4FC7857CA8209EE3BA +:1010000094FA50AE589A877CC5E8B05AF061103A0D +:101010004527C7C8FFB1D91D4B201FF6AB88493CF7 +:1010200098282A71BF9AA158F940CE9B51D253DC1F +:10103000164C637C62899BD92AE8A2AAA0FAAB115C +:101040009E4D82FE4EFEB4C7C19A765D40E43C22BE +:101050001EEF67A37F47EF8CA945018A7F098C6E3D +:10106000B906DF6F55A14943BD1A30E35BC47D0F5C +:10107000735FED7CF7C5E3888F7589FD7B46BCB84F +:10108000588FE97E5C16BBD9B91E3F98973DCE09B3 +:10109000C6668F4B34EDB48FCBFFE6FEB3C1DBF1F8 +:1010A0002C01A11914D7A90ABFC584691AF9DB8FCD +:1010B000EE94F87B1B0E7E3ABA2B7F387F6C47A3E9 +:1010C000F7CBF3C47769E7BE7D685FB584C0282895 +:1010D00024FDA72B0CFF2BA4915E89A50B76BFF3F3 +:1010E0009B27D18FBF57017CD7ED289B6307CE5339 +:1010F000350A906879B0C646E78F3BAFCC734C2E6B +:101100007FD76AA6FC05A8DDF19D12DD1753E0EC40 +:101110003BF1BDABC6832E48B2F2E3C0FB3DBE89B6 +:10112000DB0D737EF1680D9304D820E0C1F5CBBAD6 +:10113000CEF499EC07DDC22761735D881B1DF8DED4 +:1011400073BDC04FDF68A1AD9E39BFB7664D3E4845 +:10115000FE9F187FFFB9DFF4525BFF20FC233AFBB0 +:10116000877C99E16790636EA075259A9F223B88E2 +:10117000EDA771FF91942208B7D39FB2708F44EB13 +:10118000D9D56C3DC3F7D8AE4E3AF6A38E782A1364 +:10119000FF4EBE9503C28E0C4020079E23A9D1743A +:1011A0003E4B7277ED2F14B2C7AE7D484A523C7564 +:1011B000E799F9407857C82FF51A34DDC1569834AD +:1011C0007F3BF0E709DBF1EED3ED78CFABB4E3374B +:1011D00018B1E3D189E7FCB1836CF5E72B0D6E62A2 +:1011E0003E81EF4AF60FF1CDF424CD63219B474AAF +:1011F000CFC4E7DCBDEB56A0BFA4573C3AF07796CE +:10120000037F2760EF3E5E0A516FB125FE534D917B +:101210005C39E5D0C45399D63181BE4582E4A70E2E +:101220008B4EA47ADEAED4DBCE85AA3A427268C673 +:1012300029E775AFABAFC249965E77E981C3B320AA +:10124000B7DCB5377B23F52E3C1F8748FD103C2FBC +:10125000D728DD84F547F4B4DE1A349E0B221AA693 +:10126000B7887393A355FC5DA4F6D47BC568FFDDF6 +:10127000527DEC12B4FB1BAF8228EAFF6490AFBF33 +:10128000BB455A17E471D637456530D05FB0574932 +:101290004AE887D28C5F5C8076DB5E974EEB9F7668 +:1012A000EC37FF46E5A3343CC72891DB46E2B8ACF7 +:1012B0003EF9FB8FEE7D35F45D8B7DD4B5E7B661ED +:1012C000B83E6D94616EB67D407D808FDF55F99795 +:1012D0006264CB05DE63B42F5FD969F7B3B9777366 +:1012E0003FDCC23D97923D7A60367F8FF3B123FC9D +:1012F0005EEA2465C657BFC4F2E3FE53BC6304C66E +:101300009499C53C9403E999F0313C333CAE17F114 +:101310009B8D7F95297E73DCF920A1BC8EFB23D0A9 +:101320003DD4D14DB369BD7A3234E920A6757B2511 +:10133000F21F351EE1EBDB980EBB9FE89C3AA61727 +:1013400058FF357BB97FABA6939F0F9CF3A2BDDE00 +:10135000B84E7BFEBC5EF8775940AC5B21283E9DC1 +:10136000F8DCBD2E6355809FA7D1BDB2889A7DFF62 +:10137000D519E47618C307CDFFE831882C63F3381C +:101380005A5F3A01EF291D7D8F9F371CFD50999CB4 +:101390006D7FB539C0F965A39B9F1F6F9C1D482EBB +:1013A00065F3D83F7BDE40DC57FDE3DF6303B59E8A +:1013B000EC12A622645A138D7C188BF2D1C2EFBBBB +:1013C000415B49B6F7934DB930E5C4948F92D9FE8D +:1013D0005836BFE8A020DFFFD5CEAE94307EBBEB01 +:1013E0006989CE98BA9631B87AC0631C96F5477869 +:1013F0001AF7BC4B7E0AEFDEECFEEEA703219A7FC4 +:10140000D7B2F8D2F318BEBEC7843B8EF2E06E2B83 +:10141000CFD67F1CD693FF6A7B80F3739797EFC379 +:10142000416D2B991A44399978F10A06E75D4CFE13 +:1014300070FDDEE88A10DCF10540EFFF81B85F58EF +:1014400076096CB9C9B25F3B18987008E97D28C06D +:10145000E38FFAC42212C21DF9E8FD10F67FF403EF +:101460000FD1AF54F88BCC764703E21C2E68FC8674 +:10147000F8656E1129C5482C14A91F0530620FC3E9 +:10148000B7457FA7E916A7710A634C0732780A03AC +:10149000323F0F63FB34DC7F3482F913A7FD8A29C6 +:1014A0007F78E94DB5C4DD4B7BA55490E9CFD1DE03 +:1014B000400AFD328573657C8387D9A35EDE5F8732 +:1014C000DD6E450D8CFA177500509EEF8F4C7D6CCC +:1014D000EAF19602AEFF5AD6A9A41F37A99D3EF4A1 +:1014E0004B971B7AADCAC62D54758AB7183097CB67 +:1014F0007BDEE07B0ABAEDA2F3001EF948C9EA1FC1 +:10150000393368E22BF60FC4D7F083C7F6A37915F9 +:10151000F1411FA4F72461F78C7B5BBC8B28EE198B +:101520003476DF23B0EBA38D3E61C740DBEFF1DC07 +:10153000FE89BFAA747FA05BFFCC9E44EB2928558F +:10154000CF207F9DF72BB13D10FA87EDF6082FE7EE +:101550003C174B201C4E7D3316985E927AD73B4E3B +:101560003A3323BC3B5FC69032EA2093334B7BA7D0 +:101570009EEA1714EBACD05327607CBF0BF5343FC9 +:10158000552F8E3CE3B1F08FA9A7D2FC9424BC3A2E +:10159000C791C0DB9DD706A37E794E413FCAD109D2 +:1015A000FCEFFCA4841C15BC97BC18F961FDDE8B14 +:1015B0007CC8F7BB0E4EF4A2585D1BE6F7CED47D77 +:1015C000D3E220D8C77AAEEC02AF1EA8447CC88410 +:1015D00007456379CBF8C7DB2471EF52CF9F96E5BF +:1015E0007D6C33BD36CCEF95ED3A38289FEF4753ED +:1015F00044F76EBE17FE0B532E4C7E77F2B7290FC1 +:1016000009D64AB6D8118AD42EF68F763F4242D8F0 +:101610001109F3FD997809D9878B847D98080C5DB1 +:101620008D7FE6A02555ABE1B9C7A2E0208AAF5E69 +:10163000D497E3CF890F336DFC80D98B9638F84669 +:10164000F518F9C71A3F70DBBE9BF8CD851713BF9D +:10165000E7227EA58F8FDF73829CCE4E3C7FD2F92E +:10166000975D3B36EB7DBE7F95F99F07B1273BC960 +:101670001FCBEF9398FC66EA8F9AEB5A13797A5A4C +:101680005F98F7414CBD63EA97731ADA9EC9CBA203 +:101690003F9C7A23E2D2BEBB86E12FF2B300BD7736 +:1016A000E2D423EFE12F25E477BB3BC8E07DE4D90A +:1016B0003765F49B3CF6533677561ED957C7FD82E3 +:1016C0001DA776DE65DAADA6BDEAAC67DAABE6BA91 +:1016D000639E37FD3A187B00C797F630790A617C24 +:1016E0002CDF271F0CC41EC2EF790C663FC60256C2 +:1016F000A6CAF97ED62EAFB9E433CF217FED299566 +:10170000D6BF385BFF8648997098E3D707C5BB0200 +:101710008CEBD0AE29AB013ED842FE6E40D970882A +:10172000E1FA8CD74B719EBF1276D97362BD31D36B +:101730008381E80184DFA542DC53FDF1E136FD8BB6 +:10174000BF0E1AFBB13FEF6483E6D15F8308DAFB7B +:10175000FDD57629C2E0286CD0A56E678FB9AEB3EF +:10176000FEFA4FD1E9DD8FFE78A700EBA37D9485CB +:101770003E7F0EF2B8A605DECE67D1846F9CD234D0 +:1017800039D4C3F97AFA3D8488F073D9E3408E3EA8 +:10179000F5C2003CFF7CE507EF06F15CEBBFD463CC +:1017A0004184F3F525BF0FE27D885796F0FDC7957C +:1017B0000E3BE784C0DFB450F44890A5DF69FEA873 +:1017C000C6F60EC9627E3E737552C14D6937BFCFF2 +:1017D000DF9147BE3D33BFA0BD8F2D6FF2E9020FF1 +:1017E0008FDB72CEBF2AC4E368AEDEB9C5DD5FC74A +:1017F000F163FF8DE3BF2EECB8D77707C9FF61C255 +:10180000336BE74837E2E1BFF67AC4B97F878BE3F1 +:10181000DF9882E77331410A279CCF3E9D47FD5DEB +:1018200075BB4276C74C36D662C6DFB1BD57D33ED4 +:10183000DC398FAB5ED127F563F4BB6A9544F62A99 +:10184000D65FC2F821B678259DE339E73933EE88B3 +:101850001F11768533CE64CE5E7EFE5E0FFAEAF10E +:10186000E559E24EF65E4CE76E737AD9F7948784B9 +:101870003D5103E760DCFC09A85A5BA5F7BEEF7990 +:10188000BD192888ECCD662FA5479A359E0AFD39EB +:101890007FCFBE6789CFD48E1A94FB5D075FCDFBE7 +:1018A000969ED6E35FDEF2EE3377B3FC28E07E1E31 +:1018B000D3DF3E43E0FD02A1CFE7087B61D4073DC3 +:1018C000EBF319888FE199F09A7A7C06FEBD410B03 +:1018D0001E4CBDEEC4C7F18383F3903FEA42CEF3C2 +:1018E000E64F86975CED1628D9E3194D393A12E494 +:1018F0007C5DBFEDD215A56CFCC453AF9DD1C9F57D +:10190000C421D413269F0234B9518E9DFC68F2493C +:1019100037DFEDBD99F064F20793ABB038E70CE325 +:10192000FED0C97FBDC53775B93ACF40BDE0E4B33D +:101930002EC7BD6833BD2CC4FDEFF5BA3109F7AB36 +:101940006CB959C1CF03B93E7A5D6D7BF64694D729 +:101950006D5C5E163CFED04F500FCDFBF1ED21D4F7 +:10196000436FA86DC5385EC3F6E5213C577F5D8D9A +:1019700087B0FD1B49256BFCE3CE9064BEA7618B4D +:101980009380D6F82528C7FFD8EED2F01CAC71871B +:10199000879FBBEFE67863797EDEBE3B7B9CC4BC51 +:1019A0001FDD5EACF3B85B7BBCC43617F92FD0BF2C +:1019B00086C3E43A2FEE3E7F6EEFF93CBD71B788E7 +:1019C000B3D97D71D67809332EC1C9C79B1CFCCB16 +:1019D000F0437EBF38838BDCEDE29C3C71FF9DC3FE +:1019E0000F33F88E6CFB5548AAB2FAE3F979FCF193 +:1019F000F6EFFED02BE7E6DF2EC1EF697B229935AB +:101A00007EA2C1950AE1BEAA618B8BF6810D0F29DA +:101A1000F45E1DFCD143EBF9FC877EF68773197CDD +:101A2000F31F71154DE1D3A03809935EDD712C824F +:101A30003EF31EFD193F5FD6453C8BA0D3FC47F615 +:101A4000B9312EC789CF89EDFBDC9D8E3808A257AE +:101A5000FBE149749FF0FEF7DDB8CEBEF1B404FDA2 +:101A6000CA33DBCFDDF2B310EA0BC413C50108BAE9 +:101A7000E58E5B4A5DF2D3D1548FFC76BDD17109FE +:101A8000CAE218E2F7877FCAE098FB9287E2A7E6EE +:101A90003E7C1DC519BDA63671BEBF677931AEBF8C +:101AA000735DF1628D52FE7DEEE6EB891FE73C7FB0 +:101AB0007DB1B88F54C2FD3DF1129CE7559BBE49E4 +:101AC000F39C0D31E2C7B9F72851F4B39C5061F291 +:101AD0002359E466683E979BD7B67AF0311D784D5E +:101AE000F839E3BF53C4DF8B749E57F177634E8898 +:101AF000FDF73F43DDE78D5EEB7EAC71DBCA0EA4E4 +:101B0000D39B038C7E1AC513A87181377A7F5D79C8 +:101B1000FEC27E42BFD17B37A61D3411BF63FD0ECE +:101B200017BD7B6369677BB76691189FC1ED9746C8 +:101B3000B0B438BB1FF49BF9921907CFE36F4C3E4A +:101B4000CBA507B6F17896F70E713D83713954DE57 +:101B5000E14AF5B3C5E3786CEFA2A4E34C5C42CE56 +:101B6000EDE50C4E8A97E9C6EFD312FD3D08935F71 +:101B700066AFF7D8E3F3BAF9C7F96E8F3D7E668E8C +:101B8000C32E33D38CF53FDF715EB7E9D4E2671A19 +:101B90005C498A7F6AF8A387F6270D0FB9A2889758 +:101BA000B7763EF3876F31BE7FABDD9463BBDE75E6 +:101BB000CAF1DC5D63209B1CBF158840563966DF87 +:101BC000B3CA71207DAEA1C367AF77E7E4D0BB5F36 +:101BD00075E093D90DF91847FCE603F30792BFC2ED +:101BE000815F53DF3AF5E8AB219DF09C19EFC7D731 +:101BF000FD743C26C7A3C99FF31E5C40E374F3B198 +:101C0000C9A7261FE7881B73E2D3599E8FBEB33145 +:101C1000997E91782D54E2DF694AB881BFF726FB9F +:101C200023C8BFBD9D77FE36BFDC7CFF6D04DF1788 +:101C3000F2F3CE4840C3BF5881F7E5946CE7EC91CE +:101C4000897256FBFF07F9DC4E42B72CA68FE7736B +:101C5000FCB52851E1C86BA77B0C74B68A7016845A +:101C600048CE5C224E85F54CF7D12379F2BB3AEB96 +:101C7000E3AEB5072E52D13F3B4ABE6E30CBEF5A92 +:101C8000FBE2452AA377E43CF9D1412CBF7BED1F51 +:101C900079F90879948BB1EA8EF84B17D5B1FC42EB +:101CA00031EF85A69FA4658CCD4FA2CA87EFC0F304 +:101CB0001CF5A7FCEF11AD6672EFAD4E9F33E779CF +:101CC00020EE63F93C374B597E45F9EF57E026F299 +:101CD00057FED8867CC257AD8E783EA279297E67A2 +:101CE000D11317521CE9E3F9DC1F7DF6A3E7D1DF1E +:101CF00075FC0CE1B83FBF6F6E385A5CBC9F23BBCC +:101D0000CE9E88783E7B20FAD4D2F4A85675FAEE9F +:101D100063688F73BB3F8CF75B12056EEAE771C196 +:101D200067A79A9A712F4A1EE70B255F6E7A84A5E2 +:101D30004F0B7EF88F7CCD5C8768DF7DF4A97E5BDE +:101D4000F9BB31C7CE407A2BCAF13FA3BD79ECDB9A +:101D500079F4F7475EF273BCBDE4E778BB3C7F8D56 +:101D6000EB2CF6BDDA7BC675C8F42F493BAFC774C0 +:101D70008B16FB25A707A4B0DF6F5DA9F07E034D8E +:101D8000417C374E32B81D2E31669AC1F0913040F9 +:101D9000770F4611B6C77F284AF5B1148D1FB48D51 +:101DA0000F656CDD64727EF9384E2F865B5A475F93 +:101DB00018CBF3267CD39383129D3AC1F327846713 +:101DC000A4273900F753DF626615E77BFBBEBECB65 +:101DD000CFCF37BBB0FDF074FC40E3DF64DACF3621 +:101DE000E21C58FED12320FE5E217F5FC7F47B8C6E +:101DF000FBF5B5E4FF1EBD673E8F3311FE2EF33CAD +:101E0000BFE6003F9F73FAB7CE8335A44FC739F4BE +:101E1000E8797BBE4AFAB5B7F3B97F987AB5144A28 +:101E20004FF37CEEA3FC53389FFB1F7622B26E006B +:101E3000800000001F8B080000000000000BB55A56 +:101E4000097454559AFE5FBDDA92AA54AA2A45082D +:101E500004E34B0224210B45122004D42220D0316C +:101E60004A801681F64881B298AD98B4DB699D43EB +:101E70008520D2DAA319756CCE69BAE785D611250B +:101E8000E92924D1E05432C52204254E9045A01DF5 +:101E90003BED7423DA64313D824BF761FEFFDEFBDC +:101EA000A82541E93E67C8E1DCBAEFDD77DF7FBFF7 +:101EB000FFFBB77BDFBA4409600CD03F1D2403D47D +:101EC0009BF19702307C3C2311F200F47A00D9098F +:101ED00060546428C1F62AFDBB0DA06D338E338596 +:101EE000FB6F252A6C9EFC53F6FBC1462DAC868207 +:101EF0008879ED7CDEDB652B4031CE7F1154533A7F +:101F0000C0B4BEEC9FCFC1BEA1DB002ABD979EA08E +:101F1000FB6775AA1F459B71ECD74521BCB435CE34 +:101F2000560053F195293A50CC6C5EB88AFFE39481 +:101F30007850B2C37D4BB633AA2FC7DB764122FE61 +:101F4000F07B7A53508E227E0B12DCE3A3E679DB22 +:101F5000B6A89BE42EB2AFAF20B9134B32A2E681F4 +:101F6000E3FA4FFAB09F8D7F573300A643656208AE +:101F7000E52F844A8F84F2BA3F027708E59F718A81 +:101F80008FD39E7387FCB217712CF928FA7A2944F3 +:101F9000F4719EC73EFAC27138429EE9F604D70535 +:101FA0000BFE180FE3AFCAA3E2E80E114EA7643789 +:101FB000AA01EA8FE12017B69F810A88DB342848FE +:101FC0000486AB0C2AF6DF04EF0B73B0BDB279C800 +:101FD000717852184F87271ACFA445D1788EA98CD3 +:101FE000C673EC8A68DCC679A3714ADD3825EAFE3F +:101FF0004D9B0AA3FA373F561A353EDD5F16D5CF03 +:10200000DC5E1E357E52D3D2A87ED68E5551E37348 +:10201000D4B551F7737757DD90FEF303F551E362C2 +:10202000F53FB5E32751F396CAF7CA9011E6811F31 +:10203000FF880785A462D23FEA210423F53FD3E558 +:1020400027C6FFCDFA7F98F49F1BA17FF9DE44AF2E +:10205000356C6FB1ADA6D79FD05AC7905E714E1444 +:10206000EE0AE919AF0D1AACDB256C1DC89D7BF19A +:10207000FA63667EFD5181CF95B83495D6EF081E80 +:10208000FD5AC216D5C2ECD0FFB1456D44DE3C2AE4 +:102090002B0DC4AB17E54A09509E54549D2E13795D +:1020A000A4838D01E4F7B33ADDEACA08F99EB3735D +:1020B000BFF29C5DC7DA5F18D156F1BDA916F09B3F +:1020C0000BD973B436FAE7015CB72D8981822F2CC6 +:1020D000DF3E7F0EDE77F4652B0E0033F56F01389F +:1020E0001FCFE53D1FCFE55C65521AFBC87FC8EAEC +:1020F0002492A7D9EEDD69C7F79C979E30E09BC17B +:10210000E0F21BC8EE52CDE0B7E1FB1A0DB0BA12F7 +:10211000FB0E7049F5D826C24E3BE18B62285791E1 +:102120001487AA7213FBF0FAFB24D138B231B70E30 +:102130006600ACD4FCE1C61CE60F87718DBDA450CF +:10214000BD9208D80E3F90C9AE9FBB0FAD10EDE910 +:102150009C91E3A1E17051F8C9CF379B597B69B3DA +:102160003DCA6F6E6C7E2141C179CE65C3A2400429 +:102170007E5D84DF746A6586DF80FAC7648267707B +:10218000DDB79349689FD4BBCD8A439EDAF10F95A2 +:10219000807A30B62DF1A34E60A55161E3B5797C0C +:1021A000C1B940381063E9FA3D1FC22692EF9E6F15 +:1021B000B18D785F8FDDC0DED743EFC376393676D9 +:1021C000C46D39EAC541EDD1390BC82EF07A48C249 +:1021D000FEE26E30903D2CF1A61B489E93E03EDD62 +:1021E0008EF29CB52BECF91F42A581E43A735F6D2A +:1021F000028DBB369F360F0AEBC078F2A1C36F4841 +:1022000046BF35748BE4DEA5B0F799E97AE5BDA940 +:102210004F5A95F0FBCE80B7FF34EA7B29B8D9BC82 +:10222000DAFC6879517EF18D8DD5BF4BCA207FA82D +:102230000333F9C34E13F3878355575A5FC2FBAB81 +:1022400053FB6E32E273E7ABBE9D4CB8ACDC21832E +:1022500082FAFF24C1FB07FBF4301EE71EF873026D +:10226000DD5F65525F7909ED00F698DCAF003DB7A0 +:10227000873DA78D1BB0CFFD8C78072508D4ACEB2C +:10228000DBA786FFBCD773C612CF347E3D28F85536 +:10229000FF5AD658E2537DC2357EF1FE2B996389F1 +:1022A0005F3324CECBD879BB905F4A16AE1B79A59D +:1022B00020AFBABE2A4B223FB1EFB8B388E4D48333 +:1022C000F76AE4BAF6BDBF2A97EEC359D70DC94BDA +:1022D000B6E94739EF012E678FB08F15C1A422D21E +:1022E0003BDA9DC581E356FDC76BFDBF257C3AF700 +:1022F000BCF2388D29BE313C34FFB4379EC7231061 +:1023000071CE2D70C13897AD47510721DE4DF9C20E +:10231000F5FCD65EF20BC8AB2B3A747C99E4AF2A7D +:1023200081FC8205DC0AB5E865DE9B8D7A6C3CA0F9 +:1023300083A7B16B23A7A6F99F12ECCB3AEE7FB02F +:102340006F4EC13822FCD324C7BF2EDACAECC76354 +:102350005D3383B9442657F1E1AA0A7A2FF4A21F0C +:1023600047592BF18FE2C16CD874280EE59CB1035C +:10237000F3031C37F32CBFAFF9F55921DD1A6322A3 +:102380008DFBD917B28D208A8E03B30F977F4AF346 +:10239000CE8688E746890FB31C7F5F7C98EFE0FE0E +:1023A0002190CDFD7B2014AFFAD3D9B44595F9C85F +:1023B00017278F1F2D8839D9B1511AC836A31F5E30 +:1023C000E468DEBE7D02D26122C785FA8DF45B2906 +:1023D000623CBE96371E9EC2FC21FC05A522BCECC9 +:1023E00042E618798AD1EE78307647E59DA123DF61 +:1023F000D8FA701DAD4EE5BF485F4398D7905F880F +:10240000D3F7191DA3ACEF4DF2AFC8FFE71C3A2676 +:10241000AFB943F2A8F87EB3E20109D71067B74F0E +:1024200093A5F0F832078F4BB547CEA719515FFD42 +:10243000BAE3B63C9CBFA6FD0D1B2E1F7E6CF3AE0F +:1024400073E03CD5E73E9841A10B199E5699403860 +:102450006524923DE5EBC1AF2F1C29876F072E063F +:10246000295FB72389B5391D125B9F2FC4D739D097 +:10247000D1E88CF41BD79EFBCFCEF1A4B73D6360AF +:1024800005F9E3FC60D106E231C962405DBCFE554E +:102490002E9BEF09473ACFAFF5A0A7EB00AA6E2914 +:1024A0000EDA63C0E770DE81AF64364E9B37BF63E0 +:1024B000AE6C471EE5859A0E525E18173429A4E7C4 +:1024C000B89781E3128C637ED1D7B510287F1D7435 +:1024D000805BC2FBADF1431F132F863A4DCA2E8994 +:1024E000F06B0227CEDF6AE4F133070DE10D6BF8E4 +:1024F000BAF6BEB8E0CF81FC15F2C3A3D27D7D133E +:10250000DC628DC43D81C9FF4B07E7576B7C486790 +:1025100025BF8F9CDCC5E40ACB09ECBD9A9C39AC85 +:102520000E68350E5D78DCC5E4B2131F7280CB09EE +:10253000C12CE5157ADEEE61EB88B32B6EBF345209 +:102540002E5F01E6C56877CF6E816B764E76EF8B96 +:102550000FF7CD6813AD1920FCC229968784FBE8DC +:10256000B04AC2CFBFF1CF67B66F9DC3EA23BF8C1D +:102570007CB0609BE0A47572FBC2B2C933A690E345 +:10258000E0469C2C667EFFDA78E4BB95FA563ECE98 +:102590009D68B7944BCC6E80ECA64EF89987A4D07A +:1025A00085DB50B55F860E1628284BCDD1B7196F45 +:1025B000AB75C197F2F17E59BC3748FEF7AD8F7409 +:1025C00060C3F57FFE5A9C5A817864EF6F4EF658CF +:1025D00047CEF7D4D92DCFA792BEF74B0A228D79DB +:1025E000E1501AC95717FCD4E8C17661C7EF8D14C2 +:1025F0009F5639BD47C80E4A3A1AE6117EB3A0A9C4 +:10260000D16E657ED14B3C0DA470FF317C6AF2AE79 +:102610008608BC2F3978DE0243DE9BC96E82C23E3B +:10262000BB28FFC1B65DE461ED0756662AF9E1E714 +:10263000FC70301570CE2D70389570D6AE0FAAFA9A +:1026400045C4A7DC33E6D59E08BE5D10F67E41BCCE +:10265000EF1F9DDE8F0887EA039F186DB82EDF1FDE +:102660000269149F0298A7D9BFC32FFA62ECC6A7CC +:102670001F32D278DF45607E04F5BA3511F5B4E734 +:102680004CC7943556263F24E2BADBCF9998DF6CCD +:102690004FE7F6D770FA7201F9ADCB9DD537135ECF +:1026A000EF3B0C1ACFCBE2C99EF602F3639A3DE6EC +:1026B000913DA2E879C4F362EAE7B0F95A8DBDE52D +:1026C000CCFEDA7540F6873C67BC479EDB29FFC825 +:1026D000B323EFD9F359CC9E5B7B31E061DF8F7E72 +:1026E0007C12EB972DA37E6BEF7C3BB3671D425BA7 +:1026F0004876193AC8E609604C23D549501999A77C +:1027000096396C4C5ECD3F563AB8FF0F642B896EFC +:102710005C8F4596A3EC20225EF2BE88A72B9F37E4 +:10272000FCF4C509644D222E88BCAC4BE4C1E02DFD +:1027300062FEFEC72296D5BF53BAB805D75BDF232A +:1027400073FF2F787250E4C98737A7B03EC50B05D9 +:10275000F5341D5B0FFAD3199E4DF3D0C6A064511A +:10276000D3216A4B2B03F3107198B3A2F790819B8E +:10277000732EF1AFEDE00F72F5C4F77326884311A5 +:10278000DBBE19FAF875C4E1912EC47F94B884CBEE +:1027900061FC4304181FAFC79B41A9EFAED96E4C33 +:1027A000F99F1FFB037D1CDA0F1103F1C87B7ECC60 +:1027B0004FFD2850BBD333D58938FE36C93BD58968 +:1027C000380E9EF826997C7AFBA94F6CE4EFDB8CDF +:1027D0009E5CE2595B06D60BA3F0738293F3A7D8F5 +:1027E000149DA76BED5227E7FF643F3C43FCA96BA8 +:1027F00093ED2AEABBBF4DF618318FBAE0F126EB14 +:1028000011D28BE05F3E9BE2BBA87FD771D8611DE0 +:10281000E52F1867D6BF6888AA4B6BC4BE4616F46E +:102820006D4B459C7C2F4BACAEDD18938FD450FE86 +:102830005240F545B391D653F572CC3C94C714D0B1 +:10284000B8EFAE73973AC53E472664521E833C628A +:10285000F5F4D069D9BD8B62A01EBA4DC8DF3D3AF0 +:102860008E13FA4D668F5A3E637279E691DDCFD3AF +:10287000E28AA85B875A2595D9CF6EF4F3D82FBD8D +:10288000A83403C7E154CA0C5A0FE765A99E8F2FDD +:102890000DA633FB2BF1603D8FEB5E8FF5BC4AEB51 +:1028A000D6F23CD5C0D68FE197E579B3406DB4E15F +:1028B000B80DBB25B6EF53BDDB1095E7F9043E35E7 +:1028C0003B4E1CA172B23610735FE0E38BC1E70D83 +:1028D000FA316B244E8F3A45BE97066991F91E7402 +:1028E0003B47AD0B347CB43CFB4F069E5F7C20E63F +:1028F000D7C6FD8B93D7E7751E60FB4735AAACAAF8 +:102900003C1FB4AE41BEDC2FF872BFE08B0FF8B8AD +:10291000DADD921AA278F533AE7733FE112EEB0290 +:102920006B16A42A23795525F0D8D86260F92FC0F8 +:102930002623D9E7C69D31E3042E5531B8D479A5B5 +:1029400018F9783EFEB7CA576DE0FB35D5C82FBFE2 +:10295000F2FF276FACFEFE5DD3DF149812A5BF45D2 +:102960004937A4BFD83C79EF9129167A7EB83B83CA +:10297000ED4368BC899D6781C8B317EEE0F9687FB5 +:10298000C73C4B3ED553C7F56E09E729EAF95F5BB3 +:102990003EE251D82943054E31182C7AC68FEBDC24 +:1029A000D73D719982F1A1B047CFE24B514FA14A77 +:1029B000754D614FA1253381194F12D50B380F8BFF +:1029C000CF83C7279ECC233FDB3DBF98606F385E27 +:1029D00068A13C621FF07D0DA9A738A92F22DE74E3 +:1029E0003BF9BEC6B694FF7996F2FC857B0D6ECAA4 +:1029F00047161A86DE9FEDA2F7EBDD0DD8AFE95939 +:102A0000BB258EF4FE9AE4A674FC486FBDEB47A488 +:102A1000DFA0C16E62F23E7C90EEFB5B24F7241CCB +:102A2000EFEBBC3DB715FB85CD456E82597B5FA1B1 +:102A30004379A182F2C5711656C72FBCC9C0E2EE18 +:102A4000A5F1965F53BE54E5695E40FEF8D2DBFB0C +:102A50008CE40F065B2548C1851C4939F41B3FAE49 +:102A6000F3D29B278C9494CF6B3B61ECFB8E7CA2C2 +:102A70005F9521C4EAF72623D541B5CD5ABFCF488B +:102A80007AAA14F955DDCBBF67FD2AAA13F07D554C +:102A90003B6555C19F873ADF3212DE752D128C4D92 +:102AA0008FB8FFB2C4EE6BBC5F0B9C076B857FAA2F +:102AB00016FB90D5B40F89D7613BF7371AEF1FD8B3 +:102AC000BDE40885EF754DD17EE841C1F30D549703 +:102AD000B2FADB6B24BD6ED811334EF0FCC1EFE1CE +:102AE000B93549F8F31CC8219E5F9ECBE3C9E513B5 +:102AF000F1963C5CD7E563B21BE03BF9CEE2EF71A7 +:102B0000912F0C87742C9E69E3063AFECCE28DEF80 +:102B1000F8B091F2DB05C12F983E2A8207E613DE5A +:102B20007782B786F0BB3368B193FD57F4717F505D +:102B30001E34A9B40F7E2704B6929E07BB5EDDEA61 +:102B400024DEFC1BE70D087FB741E0BA41E0BA0183 +:102B50001D7E12BAD8AABC032F61BA0FE5C0FD5082 +:102B60007940F8A19DD13863E4B98FF4551734C189 +:102B7000D378FF0EE18FEE68E1FE28364ED6897DD0 +:102B800080C171B98BD97E2BD6BB94C7D5B444E331 +:102B90005F27F605EA62E2F0CD497CDFEEFBEAFF53 +:102BA000583DCD8DD153C510E74F39C53D5C7F777A +:102BB000684B1EEDDB6978C5EAA95BC94C1CAD9E6C +:102BC000D5DAF745DEAFF517237129DF0CD89BACBA +:102BD0009175FCAB493CFE54CD92FDA4E76BF5CE5C +:102BE000C443058A2E5CEF609DB332690CAF7BA6AF +:102BF000E1D44727C8E07285EB9DA7525EA828A4C0 +:102C00007CA585FB9181129C2F91F27960FECBD738 +:102C10006252A94EF1217F589D43BCC1B63228DDD6 +:102C20004EBCC1FA611DCDBF84B68E1187251D3CF7 +:102C3000EF5932FF0BC6B76313F97A87F5CAD8D1BB +:102C4000EA09AD8EA8FB8AE7A9DAF53AB47B1A5FE8 +:102C50001794585DDC76F0EBB474F49F839D57D2E3 +:102C6000D660FBA258BF96A70E619E9A21F214CAA5 +:102C70009FD77395C1064C871F431EAE17710EA4D4 +:102C8000ADCC4EEA28D925BEB54B7C1F673F5E9878 +:102C900089FEF7837896C70C9CE1E743F4FC139810 +:102CA000470DAC0D1C76E2F8CBAD128B7FEB31C734 +:102CB000BDB570A4BDD70A5E36C01651976D656D5F +:102CC00079F6DE4F1E277FD46256C8BF0E74341AC1 +:102CD000D9FEB21AF17CC6C87CA856F0B7F67BF6CE +:102CE000B55E4D127152F012D7C1F2DBC163B2DD95 +:102CF0002431FC7E353E122791FFB41D8C637A1E71 +:102D00003C615529CFFF5CF0EF92D8776F2891197D +:102D10002EBA59BCCDED7A2B83F44A7AF0D23E4AD2 +:102D2000D75B533C6C9F4F65F654BD5BA6C3BEB0EA +:102D3000FC010BDB0BD5FA1ABE3E812FCA35D9E850 +:102D40000ACBD5AEEFB3B947B11B493AC8F4A69345 +:102D5000A2EB5CDF7EB9528DB0275CCF6AF26FFBCD +:102D6000053F403F944C7EB9334961F23504B99E2A +:102D7000759DBCC5F72FE7FB3606F6FE11F7CBFCB9 +:102D80003574FF72BA05184FBEF25750FF910C9977 +:102D9000F9A9473EA8CA8288F783C4EB719F6128CE +:102DA00099D5C327744C3EDF89E1E48956F283CD7F +:102DB000F3ED79E4DFB87F389261D948FCF6D37B34 +:102DC000C786E75998C4E33CD07A53289B7991CFC2 +:102DD0002BD6BB0596321CB6089E75897C14EBA6D3 +:102DE00033648FB175D3F5F2DD88FA8D3D7F79AE0E +:102DF00072F247C883C2637A3FD5EBFBCE723FD1F4 +:102E0000D0B9E1775407FBCE9B80FCC4235D1BB295 +:102E1000280E83D73B95F2BBCB5D0F4E65FB97D257 +:102E20001626979FE44BA1BCE97432E543B59DA7F4 +:102E300093595C6F9FFE02E5499817DD41D7315FDA +:102E400061FC2BEC2966FCDB77BC3829930407B7BF +:102E500085E6AD3DA6AF247C6A8F15BF5741F94B7F +:102E60004F19CB93B4BCA888EA71CA938E4D8CCA13 +:102E700093FA057E8307E2D8FE8704199C3F303120 +:102E80008A3F356DEFB07CA2A643F644F2E8DA73D0 +:102E90002E3DE38DC1A5B0F91A029287F1632F6F21 +:102EA0006B3AF6B1F5551B024CDF0D2D067EBF9532 +:102EB000B7004DEC793F38FD84C77B7409F5506E3F +:102EC0005427D0FEFABBE9BCBE88D5C77617DF4FC2 +:102ED00078F79CF766E2CBBB73BD59F651E2861FCB +:102EE000CA78DD2D09BCDB0C2CAF8C1DB7CDC5F726 +:102EF0007B6C491075DEA8B5F52ECE9F7223DFA737 +:102F00008ABD7FAB8BD7CDF8EF191DF2E26485C186 +:102F1000FEB4A827C6A1BFBD4BF8DB65771A58DE03 +:102F200071529C33DDA5F9DD121EBFB5FDFE253BB8 +:102F3000E1492CFFE14BC863E7604B3CD17EEF6E6B +:102F4000915F2D5B14735DE453777F4F3E35C3254E +:102F5000FCE16498CCEB06AB85F645BFEC36D86552 +:102F600026B73AB1327FE43A357F73449C0F75A39C +:102F70001FA4B621E743B64FF5EE8173BF71303F12 +:102F80001A07197CDF91EDD7D75E67BFBEE19A9D26 +:102F9000FE308A779A9EFA29CFCF1BA9A7A502EF08 +:102FA0005AF325233BB7844DDB7572F89CD264F04D +:102FB0007A52711D868EB9213ABF6CC831B17CA995 +:102FC000FF7649257F8F72A69922FC7DFF389E7F70 +:102FD0003DB25C62FBC207723E6471BC36D46B24A6 +:102FE0005E4D6E5BF324B35F3F9CA27A49D3E762E8 +:102FF000338F9FD7F4A8AD976E2AB43EA79FFB6589 +:10300000176B693CC5CBBB447C5C5C12ADBF2CE844 +:103010005D40FB23F77824962F5D4FEF4B574C7B99 +:1030200087DCDF8DEAFF9F5CDE875D64EFBDC3CB8D +:10303000697FF7DD9C4FD328BED65D87CF7E81AFF9 +:10304000CFC2CFC57C167E1EE6CE521AFB101FBD26 +:10305000C3BBD945FB4FBABFD8A600CDD3F7AB7AD7 +:1030600089F4030CFFEBD9D13631EF36979DDB8B1A +:103070008B9F0FC5519FECD9A04E203F0179377629 +:10308000CED7B0FF6801E969E0C0B10263843E2F8A +:10309000D5A33FA0F8D2792859B146F24D27F8A61A +:1030A00067AD242D1571339A7F97887FA4FFBD8764 +:1030B000EEA2BAB0BF6D994B5222E26AFB49DBA483 +:1030C0008879FB83321B8FF5D8E4BB1322E57C9211 +:1030D000C9D91FE0F301F44D5E961F79BF919F1B84 +:1030E00099FB188F9FCADEC4CEDD351EEB81F3B885 +:1030F000AE6309B03825D61D30E20FAA33BA4C2A88 +:103100009D53D07EBB23C24E8E0A9C67627140FCE9 +:103110009C057E99E69D8933DE4B7D3D84E84C6EAF +:103120003684647EDE3D0188D73304AF67EA430707 +:10313000A402368E9D4B95422F1B772B0CB1D603E4 +:10314000763DB565E0666D89397407B993BC4080FA +:103150007D97144AD63B2E98D951298CA6BFF0FAF8 +:10316000F57041E3290EC6A487EDE3C78E1B1676E2 +:10317000EFA6DA82F4DC0F6C1FEE16E893E925B3B4 +:10318000F5B088BE27BB450FE6789477EF611DB395 +:10319000E7AE3E45257FE64E12CF7D86CF617FA606 +:1031A00087DB2D8520FA6E455B6F2C0EA5381FED51 +:1031B0000BCED463E5CB700CB1F7DD4682E3BAE702 +:1031C00082A2A7FE1F5DE9623F85D769F3449DA6F1 +:1031D00033FB191E7F12F191CE736C384F69930443 +:1031E00067E97C2693AF579BBF14B3C1C4421ACF83 +:1031F000E31B6D859F75F2731E1B3B9F9B6F27BC66 +:10320000A450B2EEAAE5C6711D4C0626B7EDFEA18C +:1032100081C78BC3E75DEEE0D1B3F45D8EE4F1B01E +:10322000EF7ADC666B88F27364C7A5C8BCFBAA6B37 +:10323000ED5FC9DE25C5CEF0022F28947F8C0D7F6F +:10324000EF025793C2DFD3108C1793C3E7FBDAF773 +:1032500035BBD5A58A0EF5B2C26576935E0ACD69F7 +:1032600045540F36DBBD7F75B1EF6C5A26B1C9F4FA +:10327000EAF4CA8430DF2DE02921BCB5737D49E82A +:10328000EF7AE7F664ABC4730BBA7DFA2EE819B493 +:1032900017B373B4EF8FF8793E5AA142DF1DC11303 +:1032A000F314FA2E609BC3EC7E5AA2141FD7670951 +:1032B000AFAFD1CCBF276834F3EF0260EB74B67FB9 +:1032C000F690388F68B4EAB2A9DE6A84783795F44C +:1032D0009ABC0F25703E3EF4DF16763E1A2BF7D7C8 +:1032E000F1DE9C31D3C3F23F2ABBCF62EE1385E7F8 +:1032F0001C0D4F5D18CF156A46639FC2F09B46CFE9 +:103300004F33A937D1BEC82A13FF7E49C30D15CA52 +:10331000486D17FAD0F0B393BE691D1ED4B7C69797 +:103320008C307ECFC473DC0CF4E544267B56217FC1 +:103330001D8BCBFF01AF6B7F8EF0290000000000DA +:1033400000000000000000001F8B080000000000CB +:10335000000BFBCACFC0F0A31E8143D1F8E8389D13 +:103360000F534C941182D7B3E0D78B0D5B3122D829 +:10337000FEDC0C0CCA9C0C0C2A40DC07C4FD40FC93 +:103380001E880DB818180C81380DC84E07627B20B6 +:1033900076E386E869666760E806E2C9403C9B9D83 +:1033A00074FB39241918A6C822F84F806C4505D241 +:1033B000CD19C54313F31BA1F235B451F9C1BAC0FD +:1033C000F481A446539B34F34F01F59E36C22DAFD2 +:1033D0006E8ECA97B344E52F3343E55F7487D00000 +:1033E00093DDE134B803000000000000000000009D +:1033F0001F8B080000000000000BC57D0D7C54C52C +:10340000B5F8DCBB77EF7E6F361F840D24E1260410 +:103410001230C125060C56DA4D0405451A502BA86A +:103420004F970009C857502A69C57F2E49080102E5 +:103430002C186B50C4E553ACD006053F5EAD5D1053 +:103440002DFA7C362A2AEDB318104129D014A56C28 +:10345000DFD3F29F73666EF6DECD6EC0E7FBBF7FF3 +:10346000FAABC3DC993B77E67CCF39676665D14C14 +:10347000D206107209FE7E44C81813216444B42495 +:1034800015AA404612F2532BC13FAD5F6CD9584785 +:1034900048D842486426211D4EDA51AAB192425AB8 +:1034A000DE7EB348D2094982F715429A849A4303D3 +:1034B0004B0851B344B29D3E5A9E393929E04C3CE9 +:1034C000EE2E3EEEAFEAAC58B6D779B07CBECE8BCE +:1034D000E5DE3A8584F30979B1AE00CB97EB7CF851 +:1034E000FC5FEB4AB17CB5CE8FE56B75E3B00CD7D2 +:1034F000556079A06E0A9607EB02F8DE9B75B3B0B3 +:103500003C545783CFDFAEABC5F29D3A159FBF5BEE +:10351000D78C65475D10CBF7EBDAB03C5C17C27E09 +:103520001FD5EDC4F2485D3B3EFF53DDCB587E52C4 +:1035300017C6F24E924C481F42EEB8E382751A5DF0 +:103540006FFE538BDE1F9F46C8DA11A20FC095FF96 +:10355000D4096FA030BAEEB5DF9AA6B4C781CB4FBD +:103560008880E3AC75116C5FBBFF8F44292264CD6A +:10357000884EAF4AEBE3F977866C3F6C9D5618EDA9 +:10358000173BCEE7C4C4C631D376DA6FF006D65FF8 +:103590006B1F0FDF19116DDFD1F6BE75BA53DFCE89 +:1035A000DE7F66E3FB56C0DFEA8844C28877951069 +:1035B0005ADA95AEB63E14CFB6231662C9A1F857B3 +:1035C000DA49271D67CDA85F84C5125837EDA6C01C +:1035D0003A3F20028583EA22480F0A8C716DF43B42 +:1035E000D71211E791FFD461F69DDB2F60F9DA3F26 +:1035F0006442E87B6BEE10420E3AFE9AD1E7BD7E44 +:10360000A037F55913D01B92AB02FFE9F456D0B1A5 +:10361000D78EFEC8AB5238ADFEF68329D381FE8625 +:10362000131F7C6FF5FE578802ED455D08BF06BE8F +:10363000EED553A70DF01426A64B4A49442CA5CB32 +:1036400075127F280E7CFF058040E163F284704D87 +:1036500076DA2F1E1EFE85C8D86FB5ABE243808B8D +:103660007A87D9B79DCEFB065F989C7446E70DF527 +:10367000CF68DDF97598985C30EF2FBD26BA7E478C +:10368000A97C8D8DCEC6D9D57504DE775E5FE587C2 +:10369000B5AF19DEE9ADA2FDAD051DB85EE223BEF2 +:1036A00041745C7B814AA617021C4C88D7D8F94C20 +:1036B0000778F7013CFDDD0B38D1E8F0C3DB3FB004 +:1036C00056EAFA3FA3D187C0E88BB484AD935CD1AE +:1036D000F6A7B4761BA31F6235B66F88A1639299D3 +:1036E000A0DD4C018DF81243DB0584BB757251CF10 +:1036F00079B784DF423E70FAC2D6409C75513EB124 +:1037000082DC492A117D00AF35A329BF1446D77941 +:1037100039BE6BE670595D32D905E35F4E6E15B563 +:103720008B245CC06526FDFFD52FDBE9CCA3F5E13A +:10373000E11443FD9A43FD0CFD4774E41ADAAF3DF2 +:1037400032D4D03EAAB3D850FFC117D719FA8FEEA2 +:103750002A37D47F14B9D9D0BF8CDC66A8DF60BD0E +:10376000DBD07FAC67BAA1FD26EF1C43FB78E541B7 +:1037700043FD9682870DFD6FF53518DA7F5CBACA76 +:10378000D03EC9FFA8A17EDBB8270DFDEFA8D86AFF +:1037900068BF73CA7386F6A981170CF579F6C05114 +:1037A000C0CFDDB37E6378EF5F6A5E37D43F2464B9 +:1037B0005C3CFC1281C9194A419E9357F1FE54C4E6 +:1037C0007980E6808EFB303A2DD89C404EF2F66729 +:1037D000B7BD6F9D6990936646C719AC7D67E8FDDC +:1037E000F8EF67713E211DD6C92E7D3B9BD755FF53 +:1037F000A0F215DA25F53BC95797C787FD35B94AB9 +:10380000E99B90EB287CD5FEAA8ADFA3E351796976 +:10381000624B26B584C929421EC4E79ADE27992443 +:103820006CA2E336B83237AF0498D0B1A534A817EC +:103830006E81BAA8F849671CB89A3CB2014FB1F042 +:1038400025CE144ACCBDC95915E1A78E2505127C99 +:103850005FB0FB96D2F54A24D04FA0CF2F8A012F1C +:103860004C7EB149FD7D2027DA7FE968FA4FE87F79 +:103870004C08D5637F05E1D85044FCA037D40C39FF +:10388000B43D07E1690179A2BD471F289D6CBEEADE +:10389000A581863A9BEF65EBDFE41BEBDAB83F3797 +:1038A000C293C219EAF7F14A8F75FBE428DD9AA0AA +:1038B0001FAB2BA2402EA11C34B66BDFB968730F6F +:1038C0002349148F56562EB6BBB74079D1961D2288 +:1038D0006E420AC54039C04D2D67F0518F3A420DF6 +:1038E000385ECDB5154500DFF8F60221F58C3F3E78 +:1038F000192FEAD791086F0D60B7E5EBE820D38761 +:10390000729CAE1AF55B6CFF3B05998DEFA4A8A2E3 +:10391000E35B08A3B12453E04E6104ACB68248389F +:103920004F1FA9407C8D2360975A3578066762DD6A +:10393000C9EDCCFDAE91470214CFABFDB20FC6AAC4 +:1039400014148E079F17F480A554242B696DB5F2CB +:10395000BE15F8A33947CE00B96E916A8887D62D77 +:1039600079940FE2E89105DD72E211722576712CEF +:103970009E0AE8EB6C1E04E1A8CD3F98D561CD0509 +:10398000BA1C4DED623AD5B5D7F7AE5F9671F8AE79 +:1039900002BB98966B94C94904F9964C05FA6ECE11 +:1039A0004917914F399CBAE192F39115F874057F4C +:1039B0007FB5EF7DB4D357687A3C068ECDC38F2395 +:1039C0007CA6094C1FAF2AB24F09C581CB34C18DEB +:1039D000EDCDC05369685F31FE8AA117DAE2ADA46C +:1039E000ED56C553BC928E3FA6489A0A74E12A252B +:1039F0008A05F9D7EFCCA0DFB7F3DE92221AE4876D +:103A00002B8DD1ADF51321A4D0FE4E2FFB9EC549C1 +:103A1000427E7C7FA1012FF6D2C004328CDA49FFAE +:103A200030E17B748ECC8E383C1EF9D1EC61EB24F6 +:103A3000050C4F1EFABF4BB9743C4536E88DA565A1 +:103A4000B22F4CBFB3D8ED447A32EBF14ABFEBF85A +:103A5000F6850A187F79E603F6A574FC8B654DCBD5 +:103A6000812D4D9F8CFF12F8CE14DB3F6BF21F06A9 +:103A7000C6E103AD7474BA49381506B8A7573A7051 +:103A80007FB2F9ED83BA79BE2AB8D250BE5E4BAE92 +:103A900045B97099F72FD685DE3E3808E1215E09D9 +:103AA0003D2F8BE1EBA61C4D6FA9DE493ABBEC82A2 +:103AB000C0F41A51CB10CE12E7E7A6D1A40BECD676 +:103AC0003539B2524FBB48A572184807FEBAE8F71D +:103AD000C1362320AF95A60EF6FCA706B9B9A2EF12 +:103AE000445FB817B8497931FAE632EBAF05F8E927 +:103AF000FA9F00F839A2F0B3908AA430D04B709CA2 +:103B0000611FBBBCEC21254CFFB9BCDF2FFCC78873 +:103B10000E8E3FA27CA8E30F4B6688E8BFAFC9C5F5 +:103B2000DB447F17C86193EC4339457265DC8FC471 +:103B3000CEAF4064F2260A67AB4474FC4126841081 +:103B4000EEF4AFC29ACEE147FF6CDE37FF01F0A37F +:103B50003A3AEC1886CF1BA5623A9F34A23AAEA639 +:103B6000EF4B44827A9698837C4BDBC7C829C0BF51 +:103B700037FA400E36F17D1FF16CF6EAEDF22C912A +:103B8000E135DA1EF2DE616867F64E9366D77BB6E2 +:103B90001AE8A2FBFD641277FFD14764767696E8B7 +:103BA000E1F4B315F76F2BD22644000DB68C1B7DC4 +:103BB00095C0AF1E8270D0F484A617A8BEC812FBB1 +:103BC00044C793F32A8880ED46FD9B505EC7E85DAD +:103BD0005B81510E10BD3D930BFFCDF420BD90587D +:103BE0007DCFCB8A9BAF88AF7AE84B127FBF384935 +:103BF000647298A869B87E8DAF08B727CC1A5D109B +:103C000046AF6EFE5D19E63310F01CC2C11D745B39 +:103C1000057517A9C1FA85D2E230C0C922753613DD +:103C2000AE1FD59C38FB28EE8749B48EB5A3E3EBD5 +:103C30008732D18DF834396B4800E9F81EB403059A +:103C400035402EA13D18E47AD5E7053C2EAFAB25D3 +:103C50009FD1C5D80F8CC7FDB994E9F7C3FEDE0428 +:103C6000449041FFEF2C61A5E453F4F4D98D47B2A1 +:103C700014C73353B0C03ACD4EEB34D00366A767B8 +:103C800012960543670A5026DD582B225BC5A727ED +:103C90006D3C4A57B344182F2D80FC2C792AB02450 +:103CA000CE34B45F697FA522EE3C381DF07E09E971 +:103CB000AE9B6E343828328C174B4F361FDD308860 +:103CC00058ED80F9A6F3F9A6DFD3B41040EC24AA8E +:103CD000753085517AE734D47B4EAE7F1A0B8A9BC0 +:103CE000CB693F772149BE9196B6BC2E9C3FEE6BC7 +:103CF000FBC178772F2D43FF07C17A637D4519DB20 +:103D00001FF863EC565191343ACBEDD5DE112E59A4 +:103D10007ABE9F68FDB1FA949007AECCBE9AC2F805 +:103D200051A5FF037EF4101D7FD271DCD71BF581F6 +:103D300033E63BBF025822BC17FEAF7C2F89D45B11 +:103D4000154A0A6645F484289E286A92611F65F325 +:103D5000D3FD1DB4A775FA45E5F27869847D6C2121 +:103D6000A3173DFDBFCEE56BDF7B171D5B46C7BDCF +:103D7000E073FAA0573A15A7A9C53DD7B33246EE6E +:103D8000AC2C588F74D140E92817F6070522EAA514 +:103D900066658B47EF57F95C93433DE88328D2482B +:103DA000BE9FA4F03129A2DFE6FEFEF4116B3F5D59 +:103DB000297DD8A718F1F15DF175FE3BD2C7F7FD5B +:103DC0009E86D744F28CE215EDF1CBF99F7AE2B5ED +:103DD0001EE5AE4D89EFAFBCD88D4FB56769F0A732 +:103DE0001AFD02D6BB9BDAE2D92D5A69BD2776FFB0 +:103DF000CFC6B5D59A941360DF4A1EC33E6885B21C +:103E00005E057BFE02D8E5601F06CBD03F4CF298E2 +:103E1000BF160610815F147F88ED6F4244AF07E53F +:103E20004CA3DFCD946637EAEF29AAA09FBFAD5619 +:103E3000C67958E17B69E8CF0DC1774D1E12B6B93E +:103E4000A3F40A9F62FE8087AF880E347A05339808 +:103E5000D1ABF1BDE599C5241EFE7A7CEF76E37CFB +:103E600013CAA5D8F79C92725267A7247E4F2227C7 +:103E700075F64EB916F7E178A276DECB42129507B9 +:103E8000DE9F9000856F133465807C22A8CF9ABC9A +:103E9000C52817C84E2166DFAE30FA5152B0BF6850 +:103EA000657A53AB279E0FFB6E348EA4E0BE36516D +:103EB000FF86BAD2C724AA8C1CB5AFB74A148F8D1F +:103EC0004BFD532A707F7BA8551A14ED37CFA4ED14 +:103ED000DBA9FA1C19A56789D07E0837915CBA0660 +:103EE0001E7A883212A0C9E99B74603B7DCAF148F2 +:103EF00084EEFD0C1DB20DD689FE8923D80F06BABB +:103F000084FEA64E56A72F427D95D9EFC779494129 +:103F1000EB03145EAB6CBCAEF07A32AF7B783D87BE +:103F2000D7C97AAC3B645A07FE35073D58B7F37AD8 +:103F30000EAFA7F07A32AFE7F2BAB01EEBAB643641 +:103F4000DE4A29C4C6B7F3BAC2EB29BCEEE1F55C80 +:103F50005E275BD8F72DAC6E3787D8F80E5ECFE1C1 +:103F6000F5545E4FE6F581BC2E6CC17A42799947D3 +:103F7000E16F900F1DD13A2A110ED7EE7A674C3BB4 +:103F8000A3975481703B2C940176D3FED9BFC8000F +:103F90007FE88663D77A613FD670AB464F3E949FE9 +:103FA00024F3169463197CAC86195BD00FD1304B87 +:103FB000C6FD27E1FE99687BF12185B65F08883E42 +:103FC000A09B2792E3FBC97E51C7E295ADDC4E5E14 +:103FD000C7E3956B215E09FE161EAF5C05F14A0B27 +:103FE000D0A90FEBCB215E990FFB6B16AF6C8078DD +:103FF00025AD3F07F14A5A3E0BF14A5A3EC3E395BD +:10400000DB79BC722BC42B69B919E295B47C9AC7D1 +:104010002B9FE2F1CA2779BCB26D46F15B7930FF84 +:10402000B96CFE89F0D1778A517EF6A930C62D523F +:10403000C6A418DA3DD71BE316EE925C43DD59683F +:104040008C5BD8F38A0DE35933AF33B4CB69E58683 +:10405000BAE434C62D0A774D36D4876EBBCB502FC9 +:10406000D85869187F70EBFD86F6BC96070CEDB941 +:104070008D3F37D49525F586FE4F9A7291BEB217C3 +:10408000AD34F4CB9CBBDED06F9EDD7FDA04F26EE4 +:1040900042DA15C937F2B59AAE9797B1FAC1944D85 +:1040A000FC7ED4734C1FA18F16FC6A59CC7F65FD32 +:1040B000E4A643B07FB1E4313D15EBAF8A1D4F76E6 +:1040C000EE38A2D2EF94B90F793B75FC48BCBAF731 +:1040D000E85293242627573EC2F6E72D8FC4DFA768 +:1040E000A326A0EB68F9363E1FB82493418F68FBE6 +:1040F0009A964704ECFF7DC7D7DA63C78D7E8FD2CF +:10410000DE48FD7E38C4E7437584CE5E3077264FA7 +:1041100027A8E7D97ED9C4FD3B65134B8F35527E66 +:1041200059E6213E0BAD2F7396FB995D42AD73C0EE +:10413000C5925B715FAFF5D7E6D5E89CCCE40BD1B7 +:10414000F92D514ED90D7E856569BDDB6F72C48432 +:10415000FE3F53442061AA9764A9625C0E9D8F7C48 +:10416000D8E45B4A503FC5F50F10B29EC59DBD46D1 +:10417000BF69E38C18F9C7F332CC7CFE0D69E5F812 +:10418000BCD1D3FBBC2C302F980F9F9739E2C0D203 +:1041900014B1E17C474552B15E1A49C6F2DA487F54 +:1041A0002C474632B01C11198865492407CB6B2275 +:1041B00057E17BC59121580E8F5C83CF7D91E158EB +:1041C0005E1DF9013E1F1619856551E4067C5E18D7 +:1041D00029C3F2AAC82DF87C68643C964322B7E153 +:1041E000F382C8242CF323776339383215CB4191FD +:1041F000E958E645A66139303207DFCB8DCCC632AF +:1042000027F2203E57220BB11C107918CBECC8CFF7 +:10421000B0CC8A34609919598A65FFC82A7CAF5F8F +:10422000640596199147F1B937B20ECBF4C8062C44 +:1042300093235BB1DD13D98C6552E4397CEE8E3C5F +:104240008BA52BF2023E7746F660E988FC069FDBE1 +:1042500023AF60698BBC8ECFAD91FD585E0E4F973A +:10426000B3834B4F18E3CF233F31CAF192C3C6F853 +:1042700073F13B4639EE3B688C3F0F7BD5187F2EA0 +:10428000DC6B8C3F0FDD6594E305DB8C727CF0C644 +:10429000BB0CFDF35A2B0DEDB92DF71BE574A351A3 +:1042A0008E672FF9B9A17FE6A27A437BBFB92B0DA8 +:1042B000EDDE1946F99D4E9E30ECD33C63B618F501 +:1042C000DAF5BF34EEDB4A9E8FD9D78450BED80BC7 +:1042D000FFD5F09E35EF408C5C56997C8AF1B70390 +:1042E0004820BEB998D87DB0AF89C5670A9707A99D +:1042F000C077B44CE37CD707F88E9629B7CCF5028B +:104300003DA44E2C9D0676CCC5638202BE3261620E +:104310006D3EC47B52FA138CFB1275C80D7E5A6F2A +:10432000CAE075FA44807A1661FE06B2B41CFC6CD1 +:104330004D39ACFE56E39272C88B6932F376B5B153 +:104340001CDFB7B1FA91C619F5D09E92E4EBE7A352 +:10435000EF6D35C797D79F4A2CBED75FF2FF41A2BA +:10436000EBFF6B59E743E097FB776BE003893E9FD8 +:104370006B0D0C80D0DA5973E019501DB982FF30F3 +:10438000F42B12FC1F4A28B78D7ED609A038E9F31A +:104390001CC9FF4768D7D6DFE4EA7D1EEF72BDD4A3 +:1043A000944C709FA93E26F3BC1282FA52F36B3DE7 +:1043B000EE70A3BC5FFE98BC05E252E6CCF4E9E0E7 +:1043C0004F833F83FE686D5A087E762BE8A18120DB +:1043D000E5DBB174920E2CDDA40B4B0F64120C8C38 +:1043E000AEBB7BBD596CBD140E5F4BB88FA8C1FE30 +:1043F000F58E89A5B01E0A870B1C0E7F97FA2486BE +:1044000003FDABF08E642E51B4277609067F6692C9 +:104410002940CC3C8E0ACE998C193EDC8FFD49F2A6 +:10442000203D6AF0A37F8B524646F301E87B56732A +:104430009F9EE369E320C0E0FB5C1F6AF45C9B4045 +:104440003F697E6EA2DEFA9DE24DBF97C5B8DF31AF +:10445000493E8CD7C6BE27398DF2CFEC0C601E8446 +:104460002CC58FEBCA161EAFDA38F18AE2DB3BB8F7 +:104470009D4F1A6FBDA2FE5BB475534A80FE591A58 +:10448000D76FBC15E96E107F3F0BEC3A4A4FAFFF78 +:10449000B9BABE05E80F62D2F1FC07AD22DA835942 +:1044A0000BA9E0C989C23BB390DA83C3A2DFCD5C1C +:1044B00064F4BF8465165F21AD57067F2DAF338B43 +:1044C00012FCBFA6F49C07D93691AD87C751A50D44 +:1044D00015CD362A7F0639593DB3B5F7F9101EB709 +:1044E000C8E47495E9E47E979DC6717B7CD7F4CED1 +:1044F000F078795E09BFF31DE38033CDF1E3A814B2 +:104500005F88EF81DA3C6AE91F9DD7603E7F6D3C92 +:104510002D1EA8D5293EAD607737B554A29DD5E4B0 +:1045200065FA9B7C43471F892C4FE2EDCB421CFE72 +:104530009BF87E32A49663FE23D965A45365A964D3 +:104540000FA0FD26A640B9B991F5CB59966607385C +:10455000357A5252A0DC542BD6DB28DD34AAC40FA6 +:10456000CBCAFED9091B6B3F9E0C654E5BD75BF92E +:10457000147F391ED127D1F964A8E7DFBA09CA161A +:10458000BF3507FC704B24CC23CC6E23F602DA2F08 +:104590007B2EC17E0444209DCF931A1ED556611CEC +:1045A000FD67664BD7521BBE47FC8374FD3670F027 +:1045B000E5353E50066C9AD7E2993C0EE2F385C48D +:1045C000378844FB3DCEC773403B8C3386E5316A68 +:1045D000EDEB78BBA5F6BC9A0F654BE7BA9BA05FE5 +:1045E000AB719CB5BCDF20ADBDC4D8BE5A23AB2592 +:1045F000CF87611C534BD77B37C17CDA58BF6EB96C +:10460000C5FBAFE2FD63E5C560788FFB2BF5F35C7E +:1046100011835F4D7E84C03F900FF865FE018B755E +:10462000EB53E08FD4FA2D17D8FE4889C9337DC5E6 +:10463000CCE46197CCFCB61A3D25A26F3257B71F68 +:1046400080B8E50CBBB17E4F8A611F48C6F433B613 +:104650005F9F6B6C2F196AAC17161BEB79D719EAA1 +:1046600017BBFD2F411BE68573FFCB60FE8D0D6DE3 +:1046700095988712F5FBF9EDFA7D4A26EFB7ADA6BE +:1046800018F9A7C1C9F987FB691CBCBDA9B0D2AE96 +:104690008FBF6BFCD30C7E100BF85958DEF68EB62C +:1046A000DEE1B589E37B23CFAF7982E3A98DE3E92E +:1046B00017DC8F13E47E9C353CEFBC85E79DAFE4AF +:1046C0007E9C469E77FE02F7E3ECE17E9C6DDC8FDC +:1046D000F36BEEC7D9CDF3CE9FE37E9C15C3BBA68B +:1046E00082FFEC59EECF7986FB73C670F9BD62ACE0 +:1046F000AF1FF8F7B68E8DBF7F1EC3E9E2C7E0C8D3 +:10470000EC037ADB536F06BAF4B13CEB9C5A8F682A +:1047100029013B97D165CE2C8F2897809DCBEA93BA +:10472000B8BE05BD827933993C6F26936A9D74EEBD +:10473000FF85AEAA4AC01FDF778A6738B842DD32EC +:10474000D7A30AF1EAE3067DD58000712DC9E44FB5 +:104750009247C0F86C5EF9C1AE0390A7E8EBE82879 +:1047600007740E3BD45E0FFD0A0B83109120E6B454 +:104770009008726945990FFD6F4F7F68F26D813126 +:10478000D388812EE81C519FE5F1FD2CB9DE481736 +:1047900096C826B49B9B6A587E06ED1377FFAE95AC +:1047A000C97EA3FD90546AF483350527F7EA97F68E +:1047B000BD6A7C7FD85EE3FEABA9D09827125B165A +:1047C000EE1263FC5C31EF3B7BFF7E7E6422AE37F2 +:1047D000119DDF66AA2C97757912CEC80F711F1133 +:1047E0006B0F4A60E70DC4BC1A3FD8BF529EC70F7B +:1047F000FE12294FE1A58F3FF7F37A05D6A9DDF820 +:1048000063189FE2C560379A480063222B8610BE6A +:104810001FF967BD9F2AFF157710DC4F789AEC3798 +:10482000A84083FE99881F99E32755AE7906FC1F9F +:104830004FAF1609E07F6B4BEFFCDB239FC2E9C74C +:104840003852D6224F31E8BD44EFB52E12C7C58B82 +:104850008FCDE774BD6CD1640FEA8D8397CD179827 +:104860000FEBD7F205FADCCEF305CE8C37F8955373 +:10487000AB7AC7E3062EBFB47A06896FBFEEE1FCC0 +:104880004E9C2CDF44A3FBD461BD8FDF7D6E2724BB +:10489000920EE00B2980F2B3CFED01CC8B27145F91 +:1048A0007A3E69FA76FADBC087EA3A96A748FB892E +:1048B0007A3B4C9B4786275C2640FFFDA3307F63F5 +:1048C000B0332042DCBA693FE1DF69477BDC31A3CA +:1048D000C6CFFC65ED04FCF68E1A9F0ADF077C61EB +:1048E0001E5246777FD40FAB8222A67E349430BB13 +:1048F0005793FF1A9D34788B0F417CFD4289847158 +:104900006F6A5F5DBAA4ED67E87F06B7313A68EA7F +:1049100043F0DC8D54A086811E897F1CC20DC81F08 +:10492000FE9A5C3FF1E3B99422A6FF4D70DE03FAD4 +:10493000491D7ECC830E787C90BF98D5360CF94CFF +:10494000F2D40880DF87C4C06E3D5F999C2CFFAB1A +:1049500029C1B982162E67FB25C0EB87BC3D55EEF9 +:10496000180F72F8E9C728FDC7C9CBF903D70B4F59 +:10497000B54EFE438112E55FADFD4F60A4E9E695BB +:104980001591597E61DB77DB078C35139E7F647C44 +:10499000CF2C5518F6615966E3F7E434A33FF2CA09 +:1049A000E729A15C2285371BF09CDAAF77F9A9F1E2 +:1049B000FFC5AC18BB23AF00E9396A7794233D6C7F +:1049C000F412462F9C9E343DE2EAF4ABE2C09EF422 +:1049D000B13178C00676B246671667C80F7E038786 +:1049E000378CE9823A7AF82BD04356DB4884B7AB50 +:1049F00044C5E7FBB8FECBADED2AF3C7598766DFA8 +:104A0000C1BECB5B0C5F88D9FF908A20D8D559599D +:104A100010C303B5CCFC0B999997DB6F5D59FC5A19 +:104A20008B2767D33FD8FFBCA2E1FD8B18BF9587CA +:104A3000AA785D3CB5EF17D30531A7271E62DF6B5F +:104A4000F4947BE2C96FC91448B7E8F01FBB8F8F9D +:104A5000DD6F13BE7F94BBAB8B500E5B268CC3F80F +:104A600048F7BE7BE3445CB785E34F6ED1E2FBB110 +:104A7000FBCAB9BEDEFDAADF6F5FE9B318F34BAF27 +:104A8000383FF73BFA25B672BB35767F113B8ED89F +:104A90001610E39DDBC86F33C23DAFC568FF0CE362 +:104AA000FC9DA31AFDC8036AFBC5F777F27CB5CA63 +:104AB000520D4FCA9DFF41E977F62133E6E16BFBCA +:104AC00060CDEF349BE7AD55F23CB619A4C20D8D15 +:104AD000678988E777CE92F7DDD7E8F8A6CAC2CE15 +:104AE000D19166F371387FA1E567CD0CB2BA369FDC +:104AF000EA3663BD8A4C4E07BF6B55AB99403ED634 +:104B00006C221DEFD4E64FE9F8271696875A4D6AB6 +:104B10009A40BE2DE379AF951E22A5A61032EFA5CF +:104B2000A746C2799E7916267F4F53F82B3A7D7D92 +:104B3000BF3324037F7FB6F79A9FFC80C0FBA1A6FA +:104B40007EA03F93E39F8398DE6C9CDFE5E61F3BEE +:104B50005FED9C46A279483B85B8F93F0F6BFEAFED +:104B60002B3C47B215826223129F23B9DCFB3B2DFD +:104B70008C7EFEBBEFEFFE9EEF3F7F99F9CFB376C1 +:104B8000DD8879DE6935152057B57C96F924E00774 +:104B900057BAE9D5496A7F45D7CF7B85FD32693F52 +:104BA000D315F4CBEB7DBC739CCF7FBF6BAB0CFC00 +:104BB0007BF697C726823F70CE6F4CC44AE9E0DC93 +:104BC0002E173F2F169241EFDDBFD7E40F613D3C1A +:104BD000F2365DBE206616D2F1E7FCDA85FEC4FB34 +:104BE0009FB78426D0F7EF7FF1B36184C2E15C7D8B +:104BF000D79BFDC10EFAA5C0F2AFD4CE61B7D1E705 +:104C0000F74BE4BE8A387AAB83F3C199571C5380C3 +:104C1000CE849DFBEFC571DBEF345B74718DDF5B80 +:104C2000CC087FDA8F9DC77A56080D12D8FCF4F9AC +:104C3000E25ADEDB99670536BF97CD211BCC6FE7C3 +:104C4000663940FB2DD8F937A4EB1B7EBDDB0D7018 +:104C500058F0B2C9207F16EC34852DC3B03C6641B4 +:104C6000FFBDDF298C047812D457F3F7CE9B00F4F4 +:104C700030BF7DD5DF4C6E78DFC85F142E78EE63D1 +:104C8000CEC726DF04A8BFF08C1BECD9D31DDBDD1B +:104C900000573AEE3499D2D50FBFD6F12161E347E0 +:104CA000527A8E071E1BA0AF05ED2BD8F7F6DE7AE1 +:104CB0000AE4DB82183E3E0DFFC8E8A93F2216A396 +:104CC0005FF202796724D81D64676ADCFCE26EFD3E +:104CD000C1F97ACEEE0B9BE03CF199E7FFB209EC0B +:104CE000FBB9FFFC6AD3C3E01778CDE60179B4E0E5 +:104CF000971FBA890EFEA95666CF9F7BF6991D4F66 +:104D0000503E39F7470BDA3BE77E7B2A5BA1EB3F4E +:104D1000B7E71FE970EE76D16FC7F605782CDA7722 +:104D200043DFDEF61B40B7218B1EBF21C4AFF2323A +:104D3000FD4E5F020758581983A7D7F7BE9E0DF3A3 +:104D40003C7BC482E76F16D067B5C580B779A81FD2 +:104D5000A0BE84C27BFEAEE57F330D8B0777B5BF67 +:104D600008678548B83FF102DE6FFBF1E81228CDF5 +:104D70003E05C6235D28DF63DF5B7098E2F7EAC477 +:104D8000F8BC40BE9101FE0B76AD60DF6DA7F874F4 +:104D9000F7C4E759F8C7A89EF82CB6C6E273EED35D +:104DA0004F40E3DED4B879241A3EE7EDBBA357BBEE +:104DB00041930F9783F32C9E37F54F8BBFDC0A7C12 +:104DC000F6BC43F5323C8726D0B673BB2F64134A3A +:104DD000275F98BBEE0539D9F55B8B670B7D7EFFAE +:104DE0006F3F46BE3BB7EF3D5961E74F9C02B52B85 +:104DF000CE91EEBF0EB033E6F3D8DA826DAEB0C519 +:104E00001DC5D7FCD0A4718A1B9F1FC3E721C60F05 +:104E1000F343FB6F17E2E06F893597E9A7501F84D2 +:104E2000CB3CD221C3F97C3D5E8552C0E7B11B81EA +:104E3000FE12E1535BBF07D67FAD0EAFDB181FC775 +:104E4000F69F4FF915E4700FFC86848FA13CB7D90B +:104E500022417EE4391E6F8CC57B14FEFCFCE47796 +:104E6000B4171FB226884370385C8EDF2FB7BEEFB1 +:104E70000ABF195605C78D85E3996FE2EB83F55C90 +:104E80007ECC2735E3FAE9F499C54CF5590ED87B69 +:104E9000156A7F213ADFA67613CAF9333B4D21D03C +:104EA00017B1F2627E827D72C8CAEC97F92FEF1FAC +:104EB0000672EDCC8157385D32BA9FBFEB98AC7269 +:104EC000FD10D2EB870471CA5FF2F116BC1A7FBCE9 +:104ED00005BBFE1677BCD392FF4E98FFE90E335107 +:104EE000E910A7DB4D71FD49AD56B331CFD635F290 +:104EF00048127DCFE4B62BB0EE867AFFC72AD825BC +:104F0000EF9BD1CF4224DF17163C6F6D575652B836 +:104F100035B8ABD0AFA28DD7180327C95BA10A253E +:104F200070FEABA284D9D46CDE5ABBD9231AE64DED +:104F3000F56E26E8A5A3C34F99619D9FC6D88F9FA4 +:104F40004AA4A92F1DEF5355F02D55E2ED178DE31F +:104F500007969888A2D78796AEA3301FF23B1B0115 +:104F60003FB2E9359B0AF264C1265B08E29BAFEFD2 +:104F7000BBB803E076EE690B8F77B23CDB6ABE5FAD +:104F80003BB5EFE2A6FFA2EDA7E065FAFDEA4DB45E +:104F90003FD8EDBB1C98F4FCD7E79386112AA7AB4A +:104FA0007FF7F044902FD5B0C7A2FDAB7FDD37D49B +:104FB00040C73BD987D54FEECE0A015EE6BEF0DB97 +:104FC000F9A04FE6FCCA4180245FDFF7F1BD503FF6 +:104FD000F73B17E67B9DFBDDA91F021F507B5BD1D2 +:104FE000EBF5D9FAF3DE74DC395067EDC2255D1EAE +:104FF000C11C2829BDCF7939C90FFB715D3F7C6F7A +:1050000081A5EB21744011B59F887BA2703FE0C35E +:10501000393B8DDFFBAB95D9530BE4AE2AD63FD895 +:105020008FF16B07BEF78D46A7BC3DF67DADFF7FC8 +:105030005A7363C661EFCFB7909A78F46FB1B171CC +:10504000E7ECFC36DF381EA3D79EDF61CF7F2AB0A6 +:10505000FC7CB2C786E77FE7CAE1C129945F5F9411 +:10506000C92CE0DBB9EEF0E064FABDDF707939D726 +:105070004EEBF4793F3E0FE80F7562EDFC15E077DB +:10508000DE4B3602F43EEF772EF42BCF7BF1E2C9F4 +:1050900027E9F333FB1C98C73AEF778B11DFF32C2A +:1050A000E17BC18FD3B5C782FEB1337BDECA067BFD +:1050B000E48C399C9DD28B9F685EBB853B2F8CEB2B +:1050C000A0FB82821A27F839595E4E2D61F70ED463 +:1050D00042E207D0F12736160FE1F1A907B8BFE881 +:1050E000FC0C2509E77FFD2DEC398F5F3F70ABD2BB +:1050F0003759370FC89B23D7D07D895C930F72D661 +:1051000014B98528B42E450662A9F533C1FD0DE01A +:105110000F4D2368BF9BD37CA49A968B534800CF36 +:10512000FF386FEEE6B33F50143FB041E90BE3F9AF +:105130006C4CBECCB3FB47DB306FC478EF82BA8FC8 +:10514000ADEB22BF4F2176BE17CDAA05E479346EB0 +:10515000C7F2066B25E563F0FF92435C2EF5583FDE +:10516000E3B3F39E14E4336D1DABEA3C284F56D4F1 +:1051700079B15C5E574014CC77F661DDC4E16129FA +:105180005409F8578107E1CFE2ACF0C37D16302611 +:10519000C4534DCE00D297C55B83BE022B8F8B9A32 +:1051A0009C2AA976429E078393C959817092795DA2 +:1051B0006A9B8070A5EFE3F3B1F6C00CDB08C83F33 +:1051C0001E6A9053725AB1A1DE036E1A5DECFEDFC7 +:1051D000861F4178ADA8B36209F9E20037C8178786 +:1051E000FAFF07F8B530F85D47141DFF40FEB662C0 +:1051F000E0A704F0DB40E19716E5AB5838D4F23C69 +:105200001D8D9F12F12FE4DB4310667D5D1B96DA46 +:10521000F394047AFDAC8DD923B524B014E3A11E18 +:10522000E68721692AC9D4F99F8857C5732078DE9B +:1052300014DA336F41FFA5865F93473A69947FCABA +:10524000C7B09EC56F9B459057A6DAADE4335D1C91 +:10525000DF34A1C2A6209C7D02C4351AB87E5DD67B +:105260008D4F237FACAA53B05CCDF9642DE79375C5 +:1052700080775A6FF0B1FC9F967104F5E763B4CE66 +:10528000F6FB61A2F78B27FBDAC3668A7F94490A93 +:1052900096EC1E8E2396D020FA9EA390603C23F9B4 +:1052A000C8CF42B856D28EE7AD93B57B605ECD4D88 +:1052B0009E8A712062667A8A98581934C33E2A16EB +:1052C000BE0DBE0378BF44A2F9941D9D2DC0F72EDC +:1052D0004E65B1B3B47BDA8FC07D10CE16073BA705 +:1052E000E8AB19908DF2D582F4EAF405846A1D1EAC +:1052F000D313D87F4BECE3FF03E8F113C84BA4F8BA +:105300005DDF3610F35A5699DBBD200F57F1F31AC3 +:10531000CA140A05DDFD626F7039E92E31CA014DEC +:105320002E7BAE2F36D0B3267753C618E95E93BBDB +:10533000BFEE96BB156741EEA64636225FC6F24128 +:1053400083595685ABF13E1AE67F3A26B0FB327A96 +:10535000CA038CBF9FEFCCD902E7B135FE895DBF90 +:10536000D43C1EBFD36D0F26C87FECCFEF6568A677 +:10537000F446F2215F414144ACA174066590D21914 +:10538000E3A7522C353AAE274C86A87B45364FEE24 +:10539000AFD5CEE2D45B8BFD80C765ED8C87B2ECD8 +:1053A0008CCF96A589A0BB8844F7934EFA48DA3F84 +:1053B000CA0AF6A56466F1FC2E97D80EF1DC65CE1C +:1053C000C956C82B15924B907EFEEEAA1CD05B7C72 +:1053D00007EE5F03FAF3387DE438EDB78CDFEB645A +:1053E000F21413D897EE7676603E94D32E1AE249E3 +:1053F000F3EC815CBBAE5E045FE77887617727B82A +:105400001F6A185F0FC954499E4E4E74DF97A4A8B7 +:10541000A440272FEA07DD88F731F5941309E4E16A +:10542000F6FF1979D83020847835C7CA9F343FDE1B +:1054300001454B15AE56A0D6F9B2BB87239DDE6061 +:10544000877D88734BB71DF4A3DC9EF38C957F5149 +:10545000BDA6A01F8CEAB5C74B419E26D46B35F77D +:10546000211DB7F457808EF7AF79F869A87FB6C6CB +:1054700082F7BE5445561085CEB73A320ACB596DE5 +:105480008F6259D9B6993211214B5757AF990AFDFE +:105490003798D0FF733274CDB95A5A3FD96241FB65 +:1054A000FDE4C6070780FD77B2C5A198C0DEDF38EE +:1054B000C2D8DECCEE7F39D9660E9918FD5E324136 +:1054C0003C8270F90E5E20DD7C49898276FCF99879 +:1054D000784BE55A8B5F7027867F655B7C7B12CFAC +:1054E0006F63726E4D3EC8D7B2A33F1B00F4A1C9D3 +:1054F00099C52954EE01FC8E5A48BCB8C058FBD857 +:105500000580A7B176FF6286AF2BBB37EB3391DA0C +:10551000DD88A7807B92C1EFCBFCAA9F71BB9C5812 +:1055200013B4BBF9FB9EF8EDF35AFEF2E62304F246 +:10553000548D7E6D13F8AB05D88F4F62790F5A1CCE +:10554000A8275D337BBAC582726506F74769741E6A +:10555000A5B3809B9FDB33D0E1ECC83A947BC2AA11 +:10556000A2C74751F87D45E90FE8435835BA2FC027 +:1055700077E9CA1FACBD878EFFF53B267C3E2B62C8 +:10558000C3FE5F3EE27BFC1ED82FFCBB19F349BE75 +:105590003E3416E3C95F9A8D7E8C32079397AF71C4 +:1055A000FEAF8AAC32D8E755CDD365F0835645D6E9 +:1055B000E0F32A0822619EFC5D6F9449105F2298F7 +:1055C000E7F29AFDCEB1F5A84F8BD18F56BDDA1216 +:1055D00037CFFF35BB629057D59D2D382EA1F65998 +:1055E0005A3A1F4F2777AA23A9C81FC4A312C8FF7E +:1055F000AEE2F2A77B7E1BCD06F9F3A52DBE9FE69A +:105600005D3B5B6755E407C8773DD7F7437C5EA5F4 +:105610007DB793F169743D8F8F8AB79EE83AAEC724 +:10562000FE5F26C7FFFE050EDF9375B3889FCAAFE6 +:105630004A0BEDE784EF3FD8540AFBFC8DC9298261 +:105640006E5DD56D73885FB7AEEA8DD364FDFD9452 +:10565000513C2C32E0E1C2CA05888725F68A63A056 +:10566000072A578D1E16C07DFE0A84F367665F36D3 +:10567000C8E3536D0FBAE3E5175F88C54F1BC70F2B +:10568000B5BB4B74F8D1F012FBFEC93F57FFFD11BB +:1056900090531B5C06B9125BF6C05B4E7CB825715B +:1056A000FA3C49F57700E1A6BC7804E87AB503F343 +:1056B000E412C3EF2A12E80D7E09EC676A67591DF0 +:1056C00023E0BB04E150DDC6E8E072708B7E97D327 +:1056D0004159FCF58C766874504B54CAB0C7E5CB81 +:1056E000D1C1C344B5F6B28E6E3A687BA32C2F4A63 +:1056F00007A31DC1B1F5B4DF1760FFE4F7C4FF7164 +:1057000059755F07F6CE4A13C6BD8EDBD5F4BB587C +:105710007D38C8E7E3EEE0C4EB4AA2F5D9DB07B970 +:10572000F5F73A9E6AA6708803BFD18E04F493A75A +:1057300092C291FFEFE8E73373FC3CD1B1F6B2328D +:10574000C02709C6F7276BA526BF4D49CEEE7D2F92 +:10575000E8D1E3CEDCBF8768EB1A7BE056076D6FBC +:105760004C7E08F5FCF1E302EAE1A57F5E9C0F7236 +:10577000B887FD5B1779E2C420F45B3E79C28CF6F2 +:10578000148E4BA8FD037A00CFD7E03EA03FFA5914 +:1057900012C5731F84CB7F4744E3BA5AFC76595D28 +:1057A000C7A3303EB1AAC4A39DD757A064F6D87F43 +:1057B000C23C74FE79D91CF0C0B92159201540F7BC +:1057C0006629D00CF986666FDA705507E7850E9664 +:1057D00097633B78B03987BE6F9BF9070FF8F92CB8 +:1057E000F43B505A33A5F37A7FB939AD9DDD7794F8 +:1057F000A77B9E0BE7A269DDE077A0F3ED65DFFCF8 +:105800001BA1FB9E35BCDF78AA76D117808ED2CD46 +:105810001FB5FC15A991B5276BCD8DAC9DFB51171C +:1058200054323FE9EBD392107EDABAA6BEBA1CEF2F +:105830005B9BFA6A069E739AEACCFF1CE0F91BC8D0 +:10584000FB01BA4F66FA39962E1EE5F2E7EECDA2BD +:105850006AA6E31D34771D70005FFC54C07DF55DC2 +:105860001F1E3403C9FFE9F07133DC97701FA4EAEF +:10587000D0F54C238ACC8CE810BE3F9DB4BB58BDFC +:10588000BD0FDC7F1A1D8F6E9961BC852CFE7CD705 +:105890008787C7821AA5E32D83F2BE77880CE34F72 +:1058A000DBAB34B163517CBC57E9786274BC6EF8F1 +:1058B00049568447143E568497061FB85E04DBA3FE +:1058C000F0457B45836F03C08DC26F6AD2949BC93C +:1058D000B0C4FC32D539F873765E8CCD2716BE5F26 +:1058E0004313E5B7A71CFE3DC07F8D0EFFF3C03FFD +:1058F00073AD5DD9522E9E077B119ECF370506A44E +:105900000FC47362F97D200FAD237E9C37964F8FB5 +:1059100002BF5C0D25E50B98073FB7722F5FE7EBE1 +:105920003F3BE5C2F328FB3ECE86729EA973F59DF0 +:10593000C06FFF6642FBF3FCDEFC5EF3EB8E72BFD2 +:10594000CBBB0E7E9E88AFF33E6ECFDDB7D7118204 +:105950007B10EFAB3575EFAF80AEEFAB65F9274449 +:10596000EA1876BBC19E6CE4F1909EE3C07E21767E +:105970001C6D9D07B2FB5D05FBCBA747C8B88FD850 +:10598000FFCEF93F56D3BA3DCB8AFB84D5C99C7E66 +:10599000CBD8BEF5E964BFA308FC5F2B537C2A5D1E +:1059A000E7CA3748BB48E17460C843A1F212B81790 +:1059B0005A44DFD9DAC8D66039BC57C8EE9DF170B9 +:1059C000BB746DC7F136A0C753472C1877F8D2C502 +:1059D000CE13AE345764831DFFF96639EEFD679F21 +:1059E000BA249CEF66A153003A9F4E825690177BD3 +:1059F0003B26F785F9B87DC403E47F6AA34964F7C1 +:105A0000A369FE96B0C4FCFDAAC4EA7E5E7A6CFA75 +:105A1000FBC6568C1B83791E335ADEC3BC5A7709EA +:105A2000F3DBC5CE23C9C9E6EBEA48C17C52D718DF +:105A300011F3B15DBE2E01DE1BD0512EE3FB41A15F +:105A4000D7F7072CF18C07B8C2FB20E7075CE1FB16 +:105A50001627CBD35AC7F7D99BCDBEA631749CCDA0 +:105A6000AB9305C087D64F7132B9726A8CE6470A8C +:105A7000A21F293BCF63837B2CB2FDC8DCC4551227 +:105A8000C4FBBEB7403FE66745386C1EF26218E2C1 +:105A9000D82BC1BF027836337A5AB95A40BF2A850B +:105AA0005F3FD0139F3F66B905D631A059F0C0DEE5 +:105AB0009D9671E73DC5656574DEF238EE0BC14D0C +:105AC0000BE3666FFC00E7E54AB0DE7A17BB27FF01 +:105AD000F3CBD0C7570E766F62766D07BF1F2F8C42 +:105AE000F7E005B57BBEFC25EC7E13C9AFE8F36398 +:105AF000A2FCB394D321F1439CADB2540E811F415B +:105B00006CDE3C05D63D3D682137D1F5B5081D7EDC +:105B1000E0177584C8EF53F21F0538AD59D717F356 +:105B2000F0968BFE6CD0C3EAFF91314E77C07F7E3A +:105B300003DC1FBFA95446BE380070A7F5A797E441 +:105B40006E8638A5ABB6BC6D3A1D2FE49151B234C8 +:105B50009490B7F3214EB944F408B47FB042CBDF40 +:105B6000F6E0799EE1A6AFC617401C2F43449FD2B2 +:105B70002981DDDBB06C49B907F0BACC9326E8F790 +:105B80002F77723A389A5271A793C2C7FBC87A0F1F +:105B900035E3287FA65E057E44B55956B6B3782115 +:105BA000DEF790CAF192DA2186ABDC5877CE4A81D3 +:105BB000FB7499BFF4D19B03CCCF09B1D191E8E735 +:105BC000E47F5EC46B1AAFAD1C6AC74A6B7D15F6E5 +:105BD0008771D2E938A9256278241D774BB27F13EB +:105BE000FAEDC65A114E44EA6C033885C6F6C3BCBA +:105BF000F0F5A306BF07E758520F754D063D1ACAC8 +:105C0000B2FF6933C8A965B2027C9EBAE4E43D786C +:105C1000F99BEF170F4299DAF8D1C320A7933BFF06 +:105C20005687CFC7C906FF62EA275F7E0BEDA9152D +:105C3000B2C14FF94D4AC5CF012E9B0A8341BC1713 +:105C400013309A1E5DC7EEA51DE3E0BEE3539344F7 +:105C5000DF16DE8EEB6AF5845632B895805ED0E0B2 +:105C6000B65C54DAC3B0AE8956A48F3CD281F22A16 +:105C700003A2D903A37849FD64C542C8D7889DCF44 +:105C80001AA7D07DFF06DC1308B882FC1839630C14 +:105C90009E43DC53DCE1057B7E7582FB73DE75B1D0 +:105CA000F72D22F3B3C6B6BFED62F40022B1AD18F2 +:105CB0004B7F11944EA226419969C5FBE6F688CA2E +:105CC0007F209DAF3729801FE86FA6F8DBFFF669BC +:105CD000F42FEE0F7E80E5B3AE02FC1E6D0FA7D34E +:105CE000F7D794B0FB8ED778188D5437337951EDB0 +:105CF000EDB442DCA4BA9078B6707A53353883BFDD +:105D00008CEBABCADB195CD30A09C67DC11704F75B +:105D10004DA5433F0ABFB4E6A50B118FA4431D4810 +:105D2000FBAD8171013F8D2CAF9F904E2BF26FD058 +:105D300084714FCAEFEF825FABB2A52FC6FDE1F8C9 +:105D4000308C97C2BF9BC2C7DB4CC701FFE1A9667D +:105D500013D982F2AD03EF675796505A46FAEC2AF0 +:105D600083F39A4A89C7B352A3034D8E51D6984103 +:105D7000F505C06D86AA2E04FA3B6EF5BC0DF370D6 +:105D8000B45A1458FF8CD6971683FDE2F07636830A +:105D90007CA82E65F34D69A1CFD1CE51DE85FED50D +:105DA0002D16857D8FC3AF84D31987C34C3EEF99E1 +:105DB0001BD9BCED59A120D067F5120A57680B30EA +:105DC000BA0797E82511F9EA10ACDFA5A6E3B87D7C +:105DD000A6C4F0450CFD69EBAAE4EBAA5CC2D6456B +:105DE000383FD1698561DCCA12B6CE1984BD2FC295 +:105DF000733AFE4CBE9E4AF5452C67365B0CE36F4A +:105E00002AD8D601F3C92994153C3742D87D87D9C1 +:105E10007C5DD98DEC7BD9852F22BC48AD6EBEE868 +:105E200057D5D5295F9D7A8B3216B573856C2B12A9 +:105E3000D3F19FC918CFC96B35AEEBD48AFCAD70D6 +:105E40001EFCB3C7648C7BEF117D4707E07E545680 +:105E500098FCF17D3001E4F4CC461FC8F1DD650CFF +:105E6000FEA76E2521A08741872A5200DE830E05FA +:105E7000785983F1740A10A15BEED1F9D12D53B397 +:105E800000F23232F0B95920074AD9399F2CFDBCB3 +:105E9000E9FC529BD3CB211F2AAD34A55CC6AB5D78 +:105EA00063DA0F3D315984F6834F3C08DFC920BACD +:105EB000F5D076D93D909D6B39485BA15FEDC94720 +:105EC000001F2DFC1EF24130B3142C0F42994AF9E9 +:105ED0007B550ACC53226374F7586E7F6C249E0363 +:105EE000C794A7622CC324CE3D97BAFE43787F5552 +:105EF00088D3CFE5560CFBF3ED8FDD3804F6F16B5C +:105F0000C04E4C8273BC9EAF204F47F58908F735D1 +:105F1000E6B0B590D69753BB11EC97B5051F89C075 +:105F2000776BF6121FD0476AC53F2D7A3CDEE462DC +:105F3000BFCF23C96415F0FF812127C7019E42FB13 +:105F4000A9DD49FB97FFDEF98403ECA13FB23C9841 +:105F5000CD6FD5A0FE7E285B8E7B1F2FB98C9D1840 +:105F6000DB3F65D064F4E70D685D370EEEF7AC1EDD +:105F700027F96EA2BDD35ACBCAC08E512A2875F517 +:105F8000A5F3DE387C2930A13281C5CB9471ECB900 +:105F9000328695ABEA0E3D0AFBF6E04EC99647E71E +:105FA0003B7405BB576C55E1796B80DAA52565CF4D +:105FB0005B6FA5CF4F94502D489F9FB8FEBC0DE25C +:105FC0003B4F9794A7023CF7361BED3A02975DD101 +:105FD000FD509125E877D179B57C48109E264BB8C5 +:105FE000AD92D64D2F39C1C2E9B1CF59D1B2790A9C +:105FF000D0E98C0219DDF6B1EBFD88EB93E9B55DD4 +:10600000E3E07EFD1C9530FF7EF07114CA33B9C801 +:10601000C8513B50E8B85AD9FE2428F9DF04B91C0E +:106020002C0CC8F08A26CF5A0655EE0079F6676E1A +:10603000D7919A5978BE0CF9DF04F6505759BC7DB8 +:106040005389D38EFD4F6DBCED63F053CFA865F639 +:10605000FE808D5F09880F6AF765D0F10794E055DF +:106060008364C692A0B508F09327124581F9B41352 +:10607000D82704A9FED1C3411BF7BFFBFE429705F9 +:10608000F9B0046C67DD7A9C7C3DD93EBA9E387AC3 +:10609000BA987FF7A74F7DB57F14C07F09DB220D2B +:1060A000081E13ACBA790C50AF6C1ED7C07860BF15 +:1060B000BAD8F9535749279E938A95EF60CE03DFEC +:1060C0006E729C1BCEF6F74679DAA3CEE92AF679F2 +:1060D000768CBC2AB2B4DF8CF8DDCDEEBD868C5850 +:1060E000681788A8B07B3F43DAFDD435D06FA8CBC2 +:1060F000E9013A6819F25131C06735B717661612CF +:10610000DCAFCECCEC407B617A23B717245F130859 +:1061100059C7C664B252673FA0A9045BE8466E2F18 +:1061200068FA9FEBED6A6F4733EA55B00F747AB5A2 +:1061300052657A758097E9F5EA66FA1D8513F3488A +:10614000BD5DC2F4B8D2CAED07AE8753F977D39AD2 +:1061500099BE4A053BC20D69102AEA658C61A547C4 +:10616000ED963E854C5FA6B6EC41BDD60E87B64790 +:1061700080DC60FA32EBBDC32A80C94B1FB75139AE +:10618000FD246FF77AA87D9612B5CF968B3CDE443E +:10619000987D8839FF749E8F427F9DDDB88DCF6FCB +:1061A000CFC1945B40BE6E0FE6E2F9728D6FD1FBFA +:1061B00049EBD9252C7F25BB96C5C95DBEAA1D26F6 +:1061C0005D1C62968BDD3B344BA3ABDAB017C60D7A +:1061D000C2FB28C7D9FD3F2BE0BE1EA017BEBFBA29 +:1061E000CEC9FD1A9C7E12E9134D0EB988DF5D48B9 +:1061F000E17B22B403E5B54AF74BB0B613C1867E06 +:10620000F703BF072795C0FCD78CFA3BE67F0C4805 +:10621000B05FFC54DB677E47B9EE1A7798ED433BDD +:10622000C4B8E77B32DDCCFFD02E1107C0D3166493 +:10623000F7C8D94AE5B8FD93DCCCCE3ECDE1B666D1 +:10624000D40E3CA799503F4B4435C5D1A79ABE6D9B +:10625000013C5F47FBBBDE6E52719F1EAA30A17CE2 +:1062600025B8EF0C924EDC47AA0532FA0D5BCC4103 +:106270002BE0636D09C7ABC7BA19CEFB7E67BC5074 +:1062800078009E57F8C5909003780E798A985F073A +:10629000EF413845F7EFFA78C510B7C8E1A4E00F31 +:1062A000F30D6866F4B566948CF358393C7DB329D8 +:1062B000472F7F052E3FD939B195A3DE44FABAD2D4 +:1062C000F955D53EF7D4095D3CF1E486677201CEFD +:1062D000BA7B307A3D4F5155FBB7D66D71E204DD84 +:1062E000EDB08F72C23E30749721AEC9F13BC62D1E +:1062F0001AFC6E205FCDB8B908F503FFD2EED121AC +:1063000037BC4796B0B8ED6C1EB73DBDED363C5777 +:106310005E44C9CA1C07EF5FD619CFDF7FB9FD996C +:106320007ECCAF1132E409CFDEF1CA50437CD84FA6 +:1063300094B491EC1E63D4D36FFA548B297A0F81F5 +:10634000763FD695DEB79542CD30DC77910A2CD3D7 +:10635000490D965E12C4B21F6967E766619F3B10E4 +:10636000F44217960AF1884427F773890FEB79A452 +:10637000024B09F0961A8D4B483BAD98BF01F10BCB +:10638000E0FB44E7CE7CEECA856EE4EF9AABD9EF32 +:1063900018B178C564B7FF0137E2218CF27B3A1758 +:1063A000E5877E35B41DCE1F3DB09A9D7BD1E43B81 +:1063B000EE6FE8779E4B61FA405D2FA01CAB774CE7 +:1063C000FC21C2B3C57C461F6F20566B1EFC3E8865 +:1063D00036EE74EE6798CEF520B8BBD9F9411F9E12 +:1063E0004F9A0EFE065D3BE96E67F7D968E3888E2B +:1063F000EB07F716EFD3BD8FF9D19531FB80CBEAD0 +:10640000EF98FA8CD8F7BFA1134A8FFAE39EFBA14D +:10641000928DF4CAF537252805DF6BB61CC3FD58ED +:1064200070AC5F0F9767391F687A65464CBE476C42 +:106430003943E2FC11330ED580C970AE17EF96D008 +:10644000F1B7763FA9F6BB5AB3FD013983BDE60526 +:106450003C7AF8BC83646379062DBF80BACEBF7FD7 +:106460003829F0925BB71FF1F86B44FDBD377339E3 +:106470003F8E35B594819C3B15203ED847CC2635C0 +:10648000EE1F803FFFB009E55C7F3A6FB918EF1D42 +:1064900053C514ACABF07B2F67EBD839A193FC7ECE +:1064A0009A1DFC7E9ABFF07B858BDA164F043A3832 +:1064B000CDEFA529D8BBA202FC3E45ED8E69A0F721 +:1064C0008BDA4757437BD14E0BFB1D1F2E27B47928 +:1064D000C1B96C3BFD4E26FD9E3505E40941BD7BEF +:1064E000B6C51E82DFFF39DB6E62F7AA168A789F77 +:1064F00003DC8B66E2F34B4A81EFFDD7BD608F9CD6 +:10650000E6F2E48C3B99E14B5205350DD252880FEF +:10651000EC9A758EF9780EB2CA19DAF1441AE4874A +:106520005B7DF5F4FBFBF7BC940DCF1F77CCC7F276 +:106530002F1B3ECE06B97576DFC7723CBA9D278504 +:1065400065F04FCDD92B88103F296B9F26437CA443 +:106550006AD77EF42BCFF304B07D6EDB1EAC8FD9EF +:10656000F51EC64F06262938AFB31901F4F3E6B578 +:1065700059C2F07B1CBB7383F7C78DDB27313DB35A +:10658000CEF11A8EFFB8E3B537112E1B2C78FE63BF +:10659000FF86DFE3B867F6BDC4E74B305FF0ACAD14 +:1065A000FDE8CF417FEDE1E731AD1D6EBD3F584ABB +:1065B000120CF2F5AC8BC7BD322FD38FE70B1267ED +:1065C000879BC9A50E37C4CDAADA191CFE620ECB73 +:1065D0006047CE691714F83DBDB25D9BF13CE09C6D +:1065E000BD563C2F3107E00170A3F042B8B4EDC7AF +:1065F000F9E7025CFAC03A3EC07CFCBCBD142EC375 +:10660000A2EB9EE30C20BF6AEBA57060EBDE7D3948 +:106610003C058C786A7B4F06BFCCDCBD02C26FEEB6 +:106620002E368FAABD6C5E63764D43FC9FD947140E +:10663000F0B79CDCF3F16958CFD97D56BCCF579B9E +:1066400017A553E22E06FE61744AF632B9AAD9DDC7 +:10665000F342E9F8BB03DDEDBBD8EF9202C86C94BE +:106660005E8BF64EC2B86009102FF0BFA77D28FBE5 +:106670007DC16036C075F7E87036CCFB8CF6FB4800 +:1066800052301BF0E273074A9274F8F8F2D84BA824 +:10669000170BC49A4F1F013E7E5E44BB68F127EB87 +:1066A0000CF7ADDC003F483502E0F6AE1BE1D67DCD +:1066B0008F4B90E54B9100F26315E7C7B39BE9BEA2 +:1066C00093AEFFCBB617B0FD6C8631BFEA2F6DAF2E +:1066D000A700DC2AF9790C12BA0DE511854BB33508 +:1066E0008E9EEF3ED71662E715CF09FC5ECDA7342C +:1066F000B8D5C8930D713E260F3337E61CC47D46CE +:1067000028FE39C7583B29F6BED444F900C7B93C26 +:106710003BC1EF3FD0F4EE6477605A529FC4E7BDAF +:106720002B57CDCB067857C2D948BC0775FF4DE033 +:10673000AFC07343EC9ED430C0E7A4760F2A79E94A +:1067400026C8333D99CCEAB5491DCBC1AE3DA9DD84 +:10675000ABAABEC1DECF61EDADD04EFBFFCA5D512D +:1067600093C4EC7B81FDBE8F39197EA741D31B8971 +:10677000E160FC9D8667E85A012E74BC9FE37812A5 +:106780001DAFE8FB8FA7C9E9EF3D8EF57F761C4D65 +:106790007F017F42EA23F1F986FE4FC0EFBFFB3E47 +:1067A00009CE34F0D5C50D039B208E7681DF23639F +:1067B00069594A409FCF6C5D17F7F7DFBAEB3C2F62 +:1067C000471E48F94DC7D78792985D7E88CB69F8F8 +:1067D00083F89676CF24FCB5A463EA12EE9FF3F912 +:1067E0003DE6052488F6E950D28E6521E9C072188D +:1067F000E9C212C3CC03C155EA33F1FB6847C2E2D8 +:10680000E75A034FDB44CC3B7803E410DC4B2B9876 +:10681000C09E9C7F1DCCFFED240F8757D8F07B2BAB +:1068200044FF7B180AD88313BCBDD983C4239DE9D8 +:10683000CE7BC9C57B6DDF4BC2F525FA1DB5853111 +:10684000F7DEB073E11A1CE69176CC237963E3039B +:106850006F0FA1F0BF7F970BEDE4C11B1B17823CAC +:10686000BF9F74A4C339E1C1FC1E11D266FCFDA612 +:10687000216D16E3EF08C7FC5ECF1CB88704CFEF8D +:10688000199F6BE770F11EC838F918B1E778FF9AC5 +:1068900014FFDE175218FFF75062CFF1EE6A17317E +:1068A0003FEA01C8BBD2ED2F866CABB118E94BF9BA +:1068B000B73CB3AE2EF8983FC265F76F177A7EE704 +:1068C000FF020F2194E60080000000001F8B0800EB +:1068D00000000000000BDD7D0B7854D5B5F03E3391 +:1068E000679E99849964924CDE131E2128E004432C +:1068F0008C68EB49881811EDF0A845DBE20404022E +:10690000249940D1E22D2D131220206AD08840090D +:106910000EF828D64727BDA888813B20225AED0DC6 +:10692000D5B6D45A3A20554484F145B9BDF57AD745 +:106930005A7BEFCC83A460AFDFBDFFF7A79F3DEC90 +:10694000B3DF6BAFF75AFBCCE50E85B14CC69E5654 +:1069500094DBBC2319FB12FFAE893D6FB1EB181B12 +:10696000CBE0AF8D4D2C67ACB541B5AF81526BD04C +:10697000AAE99DF0B4EB824A316379A9D5E6F950D2 +:10698000660E9D7D989BB109FAAB0FBAA1BDB151BE +:10699000BDDC04E5FDDBE6F71AB0BF4B6526983297 +:1069A000CF01E34299E5E882C3A0DC66FFA5631648 +:1069B000CC5F6283F7304E819D05DD30EEDEAD7732 +:1069C000EAB0DCDACC5836CEA3F87ADDD44F658F46 +:1069D000E1B29836A92C8BB122FC27CCA3B2B51F0B +:1069E000EBD318AB693C6E89D8E07DA46E121BCD49 +:1069F0005895BD98F6A9BE73FD0758DEB2E498C35A +:106A000007F3BDBA75E56F26C0788620AC0B8628E3 +:106A1000FDA2F5ED09305F74AB916D633138142E32 +:106A2000558F45CC3421FB12FECB5F9C5836322863 +:106A3000978A7231AE23AE1ECA978BF9199BCEC2CC +:106A400059582FD6EBD418837532BBCDF9DEA58CFF +:106A50005D6357D8978363E5B1A2BCDDD0516D85E6 +:106A6000756EFF93E26981EA7D5BE714E1FECEBEBD +:106A7000E02BB2C33E9698D346B341E79F9FC1EE49 +:106A800016E717B0E85CF80C5B982BD67EC4A3CD54 +:106A9000261F8CD3B68C798E0F63CC1CDC6FBD1493 +:106AA000CFF1A0C10345B64261D34350AFDA981687 +:106AB00082792E17F892FC5CB1CCFDABA186D8BCD4 +:106AC0002BBE983A1DCF379A6AD5B629E7AF4BF659 +:106AD00053EDEE009EAF219F7952603E83B337D7CE +:106AE0000EFD2E7DDEE8B101C826FC62E4A008CCD4 +:106AF0007BE94BB730772A8717AE575D62F41CCF1E +:106B000060CCB4C4E9512FC77636C2C74F6CC6A05B +:106B100009E1BFE4EE0EAC6FDD5AE172C7E1F5CAE0 +:106B200065768F0AEBDCBCCCEC5161832BC5FE9201 +:106B3000D757E0D07983D0CFA8633EAC5F04E7801D +:106B4000705C644FA1E74251EE52035370FD5D80CB +:106B50003F2D88AF8B39FE2ECA310711CF17BD3AB2 +:106B6000249BF54357F2F9F832976728AC63F3E2B8 +:106B7000992E065DAB16EEB75C07FB5F946AB623F1 +:106B80003EEAD34A1EBA1AF1FD350343BA6A4DAD47 +:106B900070CF8A1B4F9F56E94278E875815C666723 +:106BA0006C957D46AD9A83F812D8C43C8CDDD771C4 +:106BB0002D2FA7067215A87FA8E37A5ECE0C6C5223 +:106BC000A0FEE18E1B79B92090AB83F2CF3A26F379 +:106BD000F2B0C0262CFFA2E3DBBC3C0AD690CBD897 +:106BE000F31DB7D40660FE568367BA07E67D06D666 +:106BF0003F12D61F12CF17ECFC5C65FD2FF13DC094 +:106C00007B877826D73F27FAED1CA07E97A8EF193F +:106C100060FC3DA25F7880FEFB44BFFD03F43F2093 +:106C2000FA1D1CA0FE3551FFFA00E3FF5AF4EB1DDC +:106C3000A0FF6F44BFB706E8FF3BD1EFF000F56F50 +:106C40008BFA7792C63F22DA47C4FBFCD4F6B7032F +:106C50008077F9C0B7F0AF34B53D1DF16E7373396D +:106C6000E17FEB58C0F391317CCF579817CBA31D30 +:106C70002A8D371AF9313CDF14E3572D1C7A1FE2B5 +:106C8000DDA237F41EC4C356C573D807E30716EA5E +:106C90003CC87717BDAAE778BE500DB238FA7E33EC +:106CA00069FD5BC4FADAC47A7F651F4C7453B4C4BF +:106CB000E59924F925D2BD3DB16C067AD260FE3645 +:106CC00027972FA50BABCDC3517E807C41BEB9C2A7 +:106CD000660C9B60FE157695EADB9CD576AC0FD8EA +:106CE00055923F2B9CD5E659C8576DC0EC2A603EA3 +:106CF0003B1FBBCDAED606917F386AA87EC22F2639 +:106D0000D9918FB6B1A8A30AF7B714E40AF4DFDB70 +:106D10005C4DEF8B1C9F39903F1F4AE7FBDA9F7A4F +:106D2000C0520CEDD43B74242F4AEC2AC9B1C14B9C +:106D300075413734D96F5FA4C3F2236D5C5EC15FC8 +:106D40006A19CC3F944FCFB6DF59F15A29CAB37BA9 +:106D5000548FDBCDDFA971F26028CAAB349C373D7C +:106D6000415E7595330DC70DB8CCC1C760DCA12A53 +:106D70007365A4C7E05EE4D073F9A29FE441B9361D +:106D8000A423513E15B7C7C92786F232513E25CB01 +:106D9000AB8266E08F71FD4D2E7B42D9E24825F92A +:106DA000043CC6F3254CBDA87BD1755616E3D7C964 +:106DB000F2A855C807C9775BBFB83C413E48BE9CA6 +:106DC0002C1F2ECC5FDFBC7E38E121702BF785F9BC +:106DD000EC9B8807807F069F42F283A93E9737F598 +:106DE000C2F03218BC76BBEDC2703364BE457A8502 +:106DF000C1A7D2F8E7C9950BC055B6339A1FE93A37 +:106E00000E72EDB3777E58CA806456026CE8FC338C +:106E100075C1C760DFF94B9EECC2F1F30E58DB1071 +:106E2000CE46D7ACAE36DC4FC7438C013EE9CD1C15 +:106E30009F8C39D576ECAFEA3457FA10283FF1BB76 +:106E40005B15C0277D46B387C1B91D7CE6B5F41B31 +:106E5000107E6F1888CE4D3AAF9D0DA1E510BEADE6 +:106E60002AB06E5D4378EC33239CF2B79B490EB099 +:106E7000C0A3AB3540EA56380E360EEBA7AFD6604E +:106E8000DFDB95BEF2F5580E058DBC3DB068FCBF4A +:106E90006E9D22EA99A6BA48EF14F5BFACADB91AB7 +:106EA000DAABF64B55903B8BD63DDB6E28C07A9D16 +:106EB000ECAFB14AD82FCE27CA2A9CCF93FB457D91 +:106EC000E0A5F61A20A26EA39C9F05B07DB74EC721 +:106ED000CB819E761CFFE96AD13FF0F86A2D9FD6E0 +:106EE0007383DE0145C72BEDB62B63EB5D97FE4642 +:106EF0007B0BECEF2377240DB6C11AB71ECF42F9F6 +:106F0000BC6A7AB317E18688EF05993848EF263CCA +:106F1000ED3BB71D930379507BE6C0DFD246429527 +:106F20005F1F399002F06BDCD96C36407F93C11B38 +:106F3000C82B8EF56BDC5147FA8CBFA78C9EFDF4F5 +:106F40003BA80EFEA7FA998D1731DF47E1DF343DEC +:106F500005558DFAE6769B9EDA337EFEFDEF4FF601 +:106F6000FFE8A9DFDC8CF39D7647B22642EB556142 +:106F7000804B3FFD64FBA69D93E9793845BBCF016B +:106F8000EFE702EF227EA5367BB07DC8DC61F7001B +:106F9000A02D860E2FCA0D007D5057197BDEEF18ED +:106FA0004AED93DF27D357C8CC3226211F6F5049B3 +:106FB0004E85CC8194D1505E0B76480B2C6979D9E3 +:106FC000EFC68CC4F2B3368676496BC37ED748A42D +:106FD0002B8F91A1BEBBF6CA500ED2795BA371FA7A +:106FE000A388BFE145AED971FAD6BA7403AD63F593 +:106FF000CB407797C1D3107228D87F18C80D05F9F8 +:10700000A2CF8C768E25279D058AB19D6D2DD2E766 +:107010006A83AFB61ADBE5E848BE58864DABAD864D +:1070200075B832758A9ED65173780ECA37BB112552 +:10703000283B923E7327C2E949D5D38C74F8A4CD7E +:10704000660F4005F0480DF99F3ACC19C4B249CFFC +:107050009A518EE795813C8FD3638F08FE79C46186 +:10706000247EB7D6129A5C05E35817E9EC01986FB5 +:1070700075E3FADE0930CF4F1B9F3BD402EFD76494 +:10708000A90CD76173AA6123C81FC38DB04658F7F6 +:10709000D32D5E3BF2D768A6CAB641BD75A891B99B +:1070A000E3F8956D2494E3F8648653D52CD0FFEF74 +:1070B000E9BE7F77C0BC97BFF19619FBBBC6EA74E7 +:1070C000483621959F735A79E238F6AB13C749AF1A +:1070D00049AC774E4AACCF9A9658EFFA5E6239F7D0 +:1070E000F6C4F274896FC0736C208FADBC8A5923CB +:1070F0001F2F43790BF0F903C2DF5AA2F3207C2C37 +:107100008D8F9E9803F579C84FD01E1ACD48EEEEAC +:107110002BFC1737EA05A6F466B763E4F9F0C82B31 +:1071200030DF80E7651BAADA19B4B7BDF3C11738A1 +:10713000BE8DC5B52B46F8685147262FBB603DA9CB +:10714000F80F37C2BBF9CF3F46B97848EF4178E72F +:1071500035AA34FF3DD3DC413DD7275CA8CFA489B5 +:10716000F669E6B5BD7AE0E769EFAC5E88766F3226 +:107170005CB358B3827409F8C1EDED3A46F26395F9 +:107180008ED523DEA08D80E3917A04FC626A86911D +:10719000E0644A5784DDA8EAB03E4BE84FC69CDB6A +:1071A0002D48C72B0E70FC5F61E4E3F48DE7A64920 +:1071B00011E519F2C98C745DC238EBEDA28D286718 +:1071C0003A78B97B7FFA0D4897EBA7A58F413C3100 +:1071D000A1DD05E30DCA376B23607F96578D01054E +:1071E000061DA4B2FD0638CB6E2BBBCD0BEBD878B9 +:1071F000D01AD0C37BCBECFBEDA8A7958B75772F6E +:10720000F7BC897C205AA7121C2D991DF63123F951 +:107210001E02B03E4407948B55C33A49CFB3547510 +:10722000907CB7947574209C364ED291BE917EBBF3 +:107230008EF0D952103A3414FD04B375761C2F1D0C +:1072400004BF11067920BFC38B7E130630D755705B +:1072500054C1716987304F8680ABD3B9E3870A8CFC +:107260009381E38DE6ED114E0E01A7ABD3DD0477DC +:10727000A718376328B41FCDC769AB888D23CF719A +:10728000632D0BE2FAE4BC729CBEF199A6205F3537 +:10729000FC0AE006E7A4149A69712BE633B28FBBAF +:1072A000977B9BB7125DDBC8CF91EBCCAF463CCA56 +:1072B0003DB8698A6E34F6B3D23C86D92C88789C66 +:1072C000AB32F337D351BFF1121C93E935677FC757 +:1072D00054D453E5B924D36F8ECADAF5E9E7D371F4 +:1072E0008ED3595D32BA1F7A4EA2979C83D13B1040 +:1072F000E993E97A4BCAE932840B8B6FAFBF7059BF +:10730000AF0F1D423F0FCB063901A02F4C9A8FB112 +:10731000FF326159613AF7974390EF3B84FF06E4EF +:1073200015106BF718FB781BD2E94246F855FDFCA7 +:10733000DA5B7F05E39D1D66B4A35C2938D8D18B49 +:10734000F291EDF40DC773D8ACFA1E4E81FACD87D9 +:10735000B319F2EDD5166E8FA902CF93E5CB3A4162 +:10736000376E9473AE7FFE29F5C3D0D0AC4BED40A1 +:107370007BEBEEAF7DD59CF9BFA867B1A749CFCA1B +:10738000DFDFDB62C3F9D71D6C37037C2D6FF0F6AE +:107390001D500EA808BF06F267ED2B98437052DF10 +:1073A0003631C4D3517A2D8865F6470B43FEBBFDB9 +:1073B000D9EFD5BB91FF644D74231FDA26E83D2831 +:1073C000ECB3E4FDAB46CD87FA44F2FB4DE93A71EC +:1073D0009EDE1375708EA31E31B2355059AA9BD90B +:1073E0008EF65D7435F05FA89DA97737DD1D67DFE8 +:1073F000DE6BAD0AA5A35DB2CCCC7CA030E79F5379 +:10740000980F88B3C0F99B2AE43F852CACA09C2D33 +:107410006C068517F16AB195F9E2F03DFF9C4AEDE3 +:10742000EFB56AA1F4B1FCBD19F88081FF933D99D5 +:10743000EE65754ECEA3507F313C653D8A7C833925 +:107440006BB43E7B6430E22FC87D986FB7D8B7012C +:1074500060681803FFD97461D3E8F3DBEF1370524F +:10746000CDB630F24BD5F6FA61E22F76F5547C3B7F +:10747000B4BB89893530F2CB225CA8FC033B95F381 +:1074800080FF9AC690DE1F40FB3B90C6ED11A669B7 +:107490006E6716D20B2320E79B59BB19DA11B6038E +:1074A000BDE5B05E0BE9CDFB991BE9013D6CEFA595 +:1074B00010CB6208D7CD8CD5C6D3817C4ABF84BAA5 +:1074C000444FF6D4A52F59683D866616B4A03E8475 +:1074D0006B0378AB8B59502D8EF905473BDCD4CF2D +:1074E000C89A499F7DFA8B23B9C8A7AD07401FBB37 +:1074F0000CCF59477CCA6A4DA43FC65A084E5181E9 +:107500001F5DCBEC74CE7DF69BEF2D71CE91169462 +:1075100017858BD313CE57B6CB3F97C77C97C78FB2 +:107520001BA471F387EE57D02F937FAE90EABB96E2 +:10753000B92F30FEE001C6CF213C1A78FC7CAAEFBF +:107540000ABFE5B80940B139BADFE175C7F4EB64A9 +:1075500038E72F4EE4CB97ED4C2C4BB8580C9A7370 +:1075600032C0DC7287CEB315C6BBE27062BBDAE212 +:10757000DF92FD1B6B1F764EC5F6609F6F85B75778 +:107580009D486CEFAD7AD981741C6BCFD777CDB99C +:10759000C476C9E793BC5E5857E6B7E3D635DE6CD0 +:1075A0004AA89F5E77DEBA32BF13B7AEEB5C89EDB7 +:1075B0007D2DFDAFEB8652D33F5C976CF7ADCA8B48 +:1075C0006B97BC8FA9B5A601E0CEDB7F67FAC58DAE +:1075D000FBDDFA7FDCEEB625C9F30408DF17E9B45A +:1075E000F119503F135FA1BE68B392DE7B9E9D25CB +:1075F000E4D344543CA09F274D9B88FD6A25DD09B8 +:107600003FC3C1672EC946BE9E27FCE84CF815BA99 +:107610001B5CE457F089F6204FDA905F746F877E29 +:10762000697C5DF1FA534603B72BEC2C4AF42CF538 +:10763000A5746657B83DCEF59D81E6491EFF1E54E0 +:107640000061BDB3968C67EF021D3E67B457A96811 +:107650009F6D51481F9855A3E953013FC6B52BE4D0 +:10766000579A75D79B0FA03FE6CAE3EE9D11783F6E +:107670002BE8F0E0B44DBD4CC33841B67E61D98FE4 +:10768000E1F9E03E4671342C2F447CB3696EB43787 +:10769000EA704530CE294373991DF9E6F76D1AF269 +:1076A000CDBA69DA1F68BF7F07AD04DACDE65B6744 +:1076B000CF774E3662BCA3EE7BEE4AD47BEA42160D +:1076C0008D9E66A65A611F75A08FE133DBC8540BEF +:1076D0003EADCC8CCF8AE55CFF4AABF41AEB60FE82 +:1076E000BA9E9F7D8EFDE6AAE1BD5C9F0CD2BEEBEB +:1076F0007A5EFD0FD4D7666B5E23F28B4BB71BB956 +:107700004E2AF0615428B18CFC20BE5C164E2C5FD2 +:107710007E30B1FC710687EF38E1C7DAB7DB447C15 +:107720007BC18756D23F7781C0433B39F0B489E4AF +:10773000C7F805363AAF0F4F5AB7A25F6FEFDB5667 +:107740006A3FFF490B6FAF0B3D83E5C03329646788 +:107750002FC80855A4C3BA5FFC424FF0C66D19701C +:10776000FC67466C5D83F597872A302EF6DC258C06 +:10777000F562BD1A1C8DFB7CEEBFB8DF3AFA842996 +:10778000B80DC6FDF0859F3DF3239CF789BC7405B9 +:10779000CEE72A940BD06EDC23662BDA1BE33E7C0B +:1077A0006A08F28D05DB4D09FB7B264311FA833B0A +:1077B0000DF16E20BFE3B1D53FA3FEA5270E13DE6A +:1077C000ED32047418C70BACE678B6CBC2FDA4BB8F +:1077D0002C85413CA7DD199CAEAED26DFB6913EA46 +:1077E000976F703D64A0F14B5DB3BA6AFAF133F65E +:1077F000D5C3BCC570CE673EB0DE86FEB8E11B12B5 +:10780000CF694430B1FC7206D71366B2B8F7C5B879 +:107810009EC12B5DB89EAD8CD6537AE29D5B8B5199 +:107820001F37713D2479DE5F6770F9F9F39FC33824 +:107830009CCFE8B91E0E1003BA5E20E8E14585EB47 +:10784000C1F0B7380FF07F012A108363EF1724AD22 +:10785000438EDF22E0F4A9396D1BCA73A791E3FDC3 +:10786000C965071FC038A66CF7DE324DAB89F32B14 +:10787000CFD9B0F0400E9C7F437726D999F27DC3D3 +:10788000132F657D17DE9FDAAE7A50F56DB8E5F1FE +:107890007BC761BB27F4215C27D66B30FEA9D0CB18 +:1078A00069D86ECE66C718F497C8FE73375CABD53F +:1078B000C4F1D3AF4A4F92FE1B847DFC7C65EF84FC +:1078C0003C80F7820D8A079B2D087D7BEA8DA8EB13 +:1078D0006CD67B30BE51A132AF7E0C99EED3F0D97D +:1078E000D0FDEC815CA8F7EF1E5B81FB5AA3F3DEB1 +:1078F000300AE9658B81FC60C9E7637472FC85FE20 +:10790000611DF45F73B3AD1EE32230EE7E2CEF2BCE +:10791000DDA6473F7EDA09E06FFCFD611DF0CC1368 +:107920003D2B4683CD02786C6B47FAD8858E0B9C35 +:10793000E7693DC90916E6FB1827FCCF0BFED469A1 +:1079400054E179E2C4F2B42A4E7F744EC8D49DB09B +:10795000BFFA474611BDCEDD90485FB29D5CEFBCDB +:1079600060627D325E9438A5BF8295C6E35772BBD4 +:107970008C490123D263C312E0E77174D370BCC396 +:10798000887A57F23CA8413279AE7AC24BE6A6FD1E +:107990005AF87E41E535C37E4FE2BFB8DF5C41BB9C +:1079A0007EBE425B640B2E61356E80E78229AC1689 +:1079B0009F921F9EAA0C8DC6F6BB0C91C77F4A7C76 +:1079C0003095F8C1297B380DFD4AB9C2AF77CA1D81 +:1079D0004E433E7746C4EDB01ECBF37B401E005DA8 +:1079E0007FF89191E4424BE8A5343CAF53CF5874F3 +:1079F0003A38970FBB33AAD11F742AF4AB34DCD7C3 +:107A0000C9504635FAF506E213C9FC4DEA0347F1C1 +:107A10009F5782DEE3D4263811BE1864C8017993DB +:107A2000D15CD6DC0FDDCB7E4E637319E66944BFB3 +:107A30006FF3209F9DEA74D3FB3A858F877F18DF11 +:107A4000FBE460C6363CFF837B4B06A19EF00973C6 +:107A50000F42BEBD20CB7B33CEE7AAEEA5B8BE6BEE +:107A600022F3B4429F77F59E3BED00B7DB19C82D9A +:107A70007C96FB8CE46F69CBA475CD525958053CBC +:107A80009D8572753495498F99B55909B6C23A6E7C +:107A90005F9BB8CF399DA6D8F9C27FF31830442434 +:107AA000A0CD71ED60FC79283F017EF3CD2C9C02C6 +:107AB000E3CE7F34B1DF0216A6F5343CF5A5A93F2D +:107AC000387E2EE0B8204BF33BA1AC4C31D3BA7ECC +:107AD000F0B442F2CD29FC8CD1070705311EB64027 +:107AE000C8EBD9A6BDB41EFF5D75DAED8037679689 +:107AF000CCD26ECFE0292364976D50080F17D4B015 +:107B00007001AC6F418F121E85FAC45BFC9CE4B817 +:107B10006C0B6F77ABD07766035C507F18F79412CD +:107B20004805FE39DB0CA61CF211B13FAC1F04E581 +:107B30007AD641FB6A64115AC75A3C47EECFA3F587 +:107B40007FFE163FBF71F55BF5B8A8837B2B28FE3F +:107B5000F729F3D039825EC22CE9E7E309C25D8BD5 +:107B60008353FDE6C4327B34AE3C18E10AE5387835 +:107B700037EDF8D2A4F503E707FBE44970C4E451FC +:107B8000EC3CBDF788388707BF3D2707F9C07DA8C3 +:107B9000BFE68A012A916F32E9D7089B617CEBE549 +:107BA0002CC1CF01FA15959F704E9BB8219FB1F55E +:107BB000061FC50B66E9BD0730B49592ED7B1AF13F +:107BC00076964E2B54891F682564EF2EE1E7F1D09D +:107BD00098E611CDFDD8B972FDEB95505887FCE0C1 +:107BE00005AE1FA496470DBE383A7B45F0B941FB60 +:107BF0002207F2105F9E55C82FBF51616D0AC0D990 +:107C000005C782F260A372F400CA8F8DD7BB592BCF +:107C1000D497EF98BCF065B295AD94D7D3B8A34A8A +:107C2000DF68A3FD737D35A579AB0EEAB36F2B1D1D +:107C3000837402FBBE6D0ABC7F5DD06D8E8DE383C5 +:107C40006B79A07811FA65F77917BE8CF43DCA4AB2 +:107C5000FEAF6C80556A3A3DDB510F75B11605DBFE +:107C6000ADCC5478DE411D9BFECB918435EAA074E7 +:107C7000FE3C0C4F45656DE8CFCD5641AFE5EFDBDF +:107C8000709E07D3F8BA3275FADB26A35E3D86975D +:107C9000D3972ADA3642FE75B4AE6C13ABC57DE3DA +:107CA0007BD4C361195A37D507094ED9E39BCB70F2 +:107CB0001DD943F8D3690CE7E338AFF7E1894F8763 +:107CC000FC7AB190BB8BB75667237F7DFD945945F5 +:107CD0003EFABA4BEA8F611BEA8F6C68296F2FE47A +:107CE000DBE2B2F1D988F7CEC2C476670CDAA0CB5A +:107CF000514E1CD253BCE7339B36C801EDAE32B2B5 +:107D00007EF3ECBE10E7EA3FA7B0609CDFC03FFD0A +:107D10002CE9E7FE736AC2FB53CBCC2C18E737681B +:107D2000A8DF3701DB35B2DE95888F8DA114168C64 +:107D3000A38FABACFDCF2BE9C27F4ECF02FDCE6B44 +:107D40004C7C7F2E830532FA6B9795F81EF6915086 +:107D5000DEF9D7BE7DE07B561949433FEA2494877C +:107D6000503E13D4050CC0875E37703977DA1E4950 +:107D70009083A7DD112E07D14F64E37AFA643C6744 +:107D8000359A362535368FACC7FEE971FB3D3DDDB2 +:107D9000C8C2743E515A07C22F309CB14D3D1F1BC3 +:107DA000313FA6A1672FC14FE24D3C1C03F171A7E3 +:107DB000D6DEB00E784665E64FD78C1C0128B84F4A +:107DC000F287AE35E8E7CCD2EB12F8454A791FFFCF +:107DD0002076F52046C188DF6C59837ED25899B74A +:107DE0008FF57F78620D8C573E92F7AFCE0CBEB602 +:107DF0009C92443A38FF55A385DED4B8B239A96CB9 +:107E000083F2A8B8B23DA9DE9954EF4A2AE7F3F607 +:107E1000A752C3857A0F6337663E3A5105BE792A69 +:107E2000273C03F3C6D6B63E3EB106F859633997F0 +:107E3000CF4D3D8A877C7F027E4D1EAE37DA3C11E6 +:107E400023E6ABA594F71E40FED2B053B12B400FF2 +:107E5000B6507798CAD8CF1DD72FA450BF86D0511F +:107E6000EA37E0F8A53AA2F735A5C778BBD0FBA45E +:107E700007AC6A5B48F179197FD6339F96A7C4E2B5 +:107E8000CF92CF9ECED15E223EBB5BB1237DF6E189 +:107E9000298E1BE7F791EDFF38AAE7B7A866A42C57 +:107EA000FEB805F5D93F35BE3F16F5BB3F0A79B29E +:107EB0005E098EC0793731DF089497DF6F1CB657A3 +:107EC00007ED8E18225D18635B9BD93311F3E88EA2 +:107ED000A4460A300FEFDE070F103C8F6446BA103D +:107EE0009EC71F7C85D717440A30EFEEFECC4F7833 +:107EF0007958A40BCBBB1EFC132F8F8A14E8A1FF6B +:107F0000E0C0918935D0FF317BFF74DD9AC9F57BE4 +:107F1000B9BE2B866A3FC9447BB581CBA12EB089FF +:107F2000CCC03767CC3FF9F463008719FF9242FC5D +:107F3000ECB153532772FD3CE0552BD07FCBFF486B +:107F40004E12BF57C96ECE41D9981E3B8FD4C25E28 +:107F500037C9914B9ABB51DFC89E3192E4488D538B +:107F6000FB0BCE2B9FF7E7C113DAFF25D3CEF9B772 +:107F70005E47F1ECEC1FA5927E769F85EF07E886C1 +:107F8000CED726CE6383D8CF864C6E57363AAFA570 +:107F9000716E15FA74E7EAE0131680FFDB324F6664 +:107FA0001DD7CFBFBB15F80AF0F14E879683FCE4CE +:107FB000BB22EF4DF20F7C9F1E6797749641D91636 +:107FC000B33F3B276B3956273EB37418B791FCA8D3 +:107FD000B398F7937229BB95CF9B7DDF886DB88FDF +:107FE0001495FB9F664F2FD9D6427AC1145A2FD3CE +:107FF000B41C05C63B3E6FB00EFD52F27CA60FD5F9 +:108000007E89F0B955F8F5E539C9F3FC8BD8F72C22 +:108010003DE815B0CF77B37C341EE819A385FF8BFC +:10802000F48CBFE019C7C197A991B1F8FEFF2338BE +:10803000FDFEEB8053E312E017BA8BE017027EEBF4 +:1080400095B0219BF30BB2A7F13DCA9D5F3A7D1F0E +:1080500066C6E5C7CCF85123E995725D293F7CBE21 +:10806000F63BEC7C3A4BD6FB3EC7F38AD34F3DD26E +:108070008F29E639F2B699E216478C21E29B47C078 +:108080001E6A41FE22E2EE15FFB2E075B407E5B8C4 +:10809000DFCDD2737FB03C77C5DB3DA718F35058D6 +:1080A000C08CFB986CA4739772B7D3C1F34A3AEFB4 +:1080B000CAA3BC92332CC2C81F5AC9883F021E50A3 +:1080C0007DF4962CA27F681FB060FB7997507BC02F +:1080D0008B00F1875BAC64BF74629C1AEB6F290D57 +:1080E000621E0CDACD846FF374346F3FF8C2FDCD9D +:1080F000C3799E85C49BAC56EED761AA367A729C32 +:108100009CBF228B9F734A79E4D9DFA35EBBD64222 +:108110007A2DCA588A097564D33870FEEE2CEE1792 +:10812000203CBBFDDE5491CFE6A940B8AE4AE578CD +:10813000B9D9C2E3559B418F26BE28F057E6D3F943 +:1081400084BE17A9D7A5A1BE303AABCFDFA0A1FD51 +:108150004FFE72A89F19518EA2DD3633A00F9BD01F +:108160000E6BBF568BC4D931F887F1BEDB045F6557 +:108170001B18F90F6FC37E6938BE350DE39BB761DD +:108180007FF4D72EBD36218EA76571FA96EB4BE6AC +:10819000FB5A96F04B763CA4C5CF23C74F1E0FEC7D +:1081A000D12A840FC0393C08CFB7454FE797BCCEE2 +:1081B000C806EEF78E6C2822BC93E30DB4CE3FEBDD +:1081C000A377282007E78CE776BAB47F660B3B9A43 +:1081D0002D4DB4EFD0CFD257D69F5F4EB617313E5C +:1081E0009FD89EEB2D2923A346A25BB792B07E09B0 +:1081F000AF81E030F72BC24DCABD872C4007E9683C +:10820000862B84BF1BEE4A2139E6340647205E2DBB +:10821000CA7253BB4D9827437295DBCD9FBE2EFD8E +:108220001E89F6B2DF1ADD82F0F25B19D1D3E9DDE7 +:10823000A9443F6C686406E6999DD9656288BF4D84 +:108240004AA404F9D66945ABA3762D296EA423E987 +:108250005778F739EE57F02324617DFEC07F529E98 +:10826000937F67A21D7D1AFEAB07BC3FAD8B54E028 +:1082700078921F801EAD917E54CFE33F4D3A164059 +:108280003BEB2ADDCC799CCE73D9367A7FB464512E +:108290009C9E0EEDF62BE91C7D906E1A041C9B74BF +:1082A000C7A85D03E62B213CD1DE423F1956C6F933 +:1082B000759BD67E48F9524D3B12CFBB21860FCA23 +:1082C000970AF68BC30FA2E780E0078CFB3B6A7826 +:1082D000FC3A5594536A7B297FCA2FFC1F99FB22D5 +:1082E0001390AFA49687D84C78FA4F707D635CCF1B +:1082F000D697D0AE76D4F6162019F8859F509EB743 +:108300005CE7953DEBC8DF21F59438BB73C494045A +:10831000BFC372EA87762CCE17C1573988065CBE78 +:10832000AD17F22D050D6294831DC3490EA29C4228 +:10833000FE24ED60E457C82752B2ABF720BD3E9251 +:108340005DFD02E76B8067A8D7A35175E5C0FE3DD0 +:10835000091FD90EEDE17FE4BF7B55E0ADF4ABD34F +:108360008ACA31DF3A53FAEB28AEB748716723DE89 +:10837000BEA7F7915F6E2E0B909F681EFAC3E0D9DF +:1083800020E87D8EF02FCD117E25F4F7C6C71FD1D2 +:10839000EF1A5F9ECF7A39DFD86E8AE5E5A01FA875 +:1083A00086855361BC46F453E13394D8AF8945A91F +:1083B0009F7FE797A684F86627DFF76DE2FC1D35FF +:1083C000413DF2898D16EE9F92FC63DC52EEC71A96 +:1083D00034462B5E8178FEAA81FC1B7F11E7D6E72D +:1083E0002FCDAA7E290BE064D5F37B6CD11526E254 +:1083F0009BC7411E770BBFCA14B44397310DF3DE00 +:10840000996A2F8CB753E573CD2E4B3DE2CF67426F +:108410009EC9F7DBB30CB41EF237115F4E21B90BC6 +:10842000EC6334E257C5602917D968F4731D1576DB +:1084300073D3CD361F8E17D1717EA3647339A564B3 +:10844000F3BC3E59EEB3F304FEC8B821FA7DE2FD59 +:10845000EEE6BEF6EB843EC968BFEBE789BCF03EB2 +:108460003CD6115F4A19E925FE7B95AE9AF852F485 +:10847000039B1BE152FB61C33CDCC727D3AD74FFF8 +:10848000EF76E10776653B687CE9F7BD503CAD7659 +:10849000CD08E297B27D1E1A2863CFF71FEF127C3A +:1084A0006C17E3EB0D9CB0F23C15950590AFED0A0F +:1084B0008D08E27AEB84FF01F51BE4AFD167F9394F +:1084C0003295EB43BB7A460511DF8F1A7C1B67A3FD +:1084D0003FA7DB407E39A6069F781CC7D993E3C12E +:1084E000BCA1D3BAE8965F43BB5D277E9E8771A28D +:1084F0005DC25FDF600C9790DE2CF2241BD2C22598 +:10850000E8077A519C578315CAF03EC3E22BCF1E71 +:108510001B8BA7613F7C7F2CC8F5F2638CE3416025 +:108520002D8F97027C7366E37A5767533C0ECF0515 +:10853000CFE1DDDDA3685FEB0DA2FD0B0AB557A609 +:1085400094CE20B9B0C69481F03FE335529EAFFF80 +:108550003EAE37CED2B9B72C415EB92785F637BBD0 +:10856000F310C549FCF7CEA5FB93FEF94B6F62FFF4 +:10857000207E807225DEEF7D9A450BC91EAE1F1C42 +:108580000AC33A4EF78CF0F0F01FBF8FD324F249A4 +:108590008F1B9886EB8EEE3604FBBB2738D0F8E4B1 +:1085A00040ACE0F28DFCE3F1711A920789719B0BEC +:1085B000954F1B222577C1FC6B337C73B2E3F445E6 +:1085C000FF9E1CE277EFDEF3D742D22B3A789CE194 +:1085D000B8419B8174E2A8091B67C6E9613FC916CF +:1085E000F68749E88FC007E3E95ED6575427D2994A +:1085F0007CFE389BEB21A922AFE0FC7A99B736D5F7 +:1086000084F293BB96705C37BD2F12F1BA7127A22A +:108610007B313FAB215446F1C0A2A561A24B8077CC +:1086200018F5FFE31B53393F816DE238732A19E9CE +:10863000AF73F43C4F628E09F4612EC7A9FD7B1B1A +:10864000B3090E15CBB91E187D5621BE28E39675C9 +:108650008CF77FBEED68400FEDEBB62B65C05A5925 +:108660005D5B15E551CCDF5C4CE73F4EF0DF5926F2 +:10867000AD6423E2DBF33CEE05F391DEDD80B9620D +:1086800063882F19511ED66F5718DE3796FB4F8E11 +:1086900013B260629C665C88F36F941B2C4E5F93F0 +:1086A0007208E5054BD22313F12220E257FC7C7EB1 +:1086B0002EE02AF93F41EC1FC841D0A79F44FCA9F6 +:1086C000A8E6F417ED5608CE8DAC99C795841CEA40 +:1086D0005B8F9063EFE9B9DC9C635A47CF305E1E35 +:1086E0001B8B7230C2E520C835E48B03E14578006E +:1086F000BC90F8B017F701E3359C60E16FC07C0DCA +:108700004B59B871347FA68E26B9CCE5B399CB67A7 +:108710007C5A2F424E27CBE764799C2C87510CA1C1 +:10872000BC957810EFA7477D64DCD2A09EFB61F377 +:10873000ED981F28CFA5D1A91DCE1B1BD3B7FC8751 +:10874000CD66F76558F6B2C136F42F55DD5E00FBF5 +:10875000F7ABFC9E720AC0692BBCEF12FAF9E40277 +:10876000BE7F97C80332A85E5666C373EA257B3A7C +:108770009AC928AF5BC2B72B15FA8DC17E5CFEF596 +:10878000F537B3366B5CFFEA5D16922F675F48A53D +:10879000FB684CF5153960BCAC3F829E0EE5D3BB3F +:1087A0005249BE9F16FCDE29FD166C259DD76778C1 +:1087B000CE998875D579E8FF65CAC43C46F7B4B947 +:1087C000DED8E818C86F2FEA8B7B6FE6786622390F +:1087D0007BD611B913CBB01ECA333E25CEDDBF63A5 +:1087E0007CD98F303FC06BF370A8FACA506F30E964 +:1087F00017DF6CD6E37DFDA5D1BB601F8D0536CAA2 +:108800005FAE297AE777B740F9831D06BAE738EFFC +:10881000B1A983C2D84DD55CFDC9E7794143C2FDFA +:10882000B905DB13CB8DA1C4B23FE9BEFC9277B68C +:10883000BEB63FAE3ED395EAA4F377330FE65F337F +:10884000FDF706F9FAE197F2F9D765C1D7F60FA35C +:10885000FCB57C17CFCB31A25E3313F1A19F7E6FA5 +:108860000ABDC6646A3E8179F0A6174D74AFFE4416 +:10887000B66F18F66FD2450FE0799A8A4E8D463959 +:10888000585DF4778AA79DFD31F3207CCE5AAA4823 +:10889000BF39BBD1E246FBACB3D04678D0B947096B +:1088A0002A5C7F9F34B602E3A7B407E6DF70FD07BA +:1088B000FCD20633F37BF860BDB890CF68644FBD3F +:1088C00037D96A5F0EFDEA377079DBC07AD3900F33 +:1088D000CC7771FEE3D73F6534C33F8BDBB4112DFA +:1088E000B0DE055E2BDDD751BF50E99EFA2A1C325F +:1088F0004EFFAF72093FA93962ACC2F9FFBEB8168C +:108900005D63D2CF6532F834BC1766D85916CE8372 +:10891000577397BC44764E5F1C7A37E75B73EFDA88 +:108920004BEF9529B5B4DFF760BF089797369A6883 +:10893000BFEF15D8C8CE7CAF8BDBBF73EDC6A09957 +:10894000F48D7319789FF6BD2E03DD633F1F1ED78C +:10895000D1BDD6F737BF427EB8F7199F37B0434F26 +:10896000FACAFBF6684518E1E86E4E437DB77EC350 +:108970003CBA173BB74BEF457E36B7EB8E5F5F894E +:10898000FEA329B796E396AE712CCE72DB62F55248 +:108990004F55D32B1F473ABCE68BF1BDD7A0BED4B1 +:1089A000057452CCF3EE514FDFDF751DE9A5732737 +:1089B0005B1DB82FF7E6C726A0FC787F722EDDE39B +:1089C0009DFBB4C2F0D30D731D4BB2F0FD5C45F5B9 +:1089D000F6874FCCC5FD6D5545364F18FBFD564FFC +:1089E0007802747533CACFC62E03E9BDFBA7BCFD60 +:1089F000BB5B9C31BA52A66CB8691CB6FF9981DA90 +:108A0000F7E93B9B6F94F8C2C215685771B825D33C +:108A100099A9686909AE2B99DEE62E6F2EE1F1ABBC +:108A2000AF46776C33BFD7DBE652D897BAAF4477FF +:108A300077BBC65E3CDDB1FCF4047BEA7CFE16200D +:108A40003C95FE7FB387698FD928DEAB29C07F773D +:108A5000B8F8BDF51D2E7EBF4DFD8F45DBDF00F85C +:108A600054BA7C5DB88E22A695A1DC7447EDD5780A +:108A700017C926F439B6D924ED00D2EFD767B2C7AB +:108A8000D7C4F91F422E6E27011F781CC739FD87F6 +:108A9000BF1FC0736A2A3C351AFDBEFE739F51BCCE +:108AA000D0D6C3E3CD364F94E2F006A797F050F24C +:108AB00077BF87CB9FF3E0E5E2F73BFCCE288DF351 +:108AC000560EE7CF9D22BEB2698995FCA99B9C41B9 +:108AD0000BF72F0418CAA749957A1E2713FAD68DCB +:108AE000C21F692E7F89617C8C5DCDF3C2DE287F39 +:108AF00049CD80F2AF2BAFF5D07DBEF247DA07E368 +:108B0000BEAF3688FA21F4BD8D7FD7AAA87E914BDF +:108B1000EF46FA9E54CEF322597D1AF94DDE287F96 +:108B2000D7797BDCFABDCCECB601DE4C01628DCF8F +:108B3000C3BBE96A8BDB16873F9F7428B55CEF7572 +:108B40000F9A368AFB45481E9727C26391CB48F39C +:108B50003E925D7508E17CCD37F9799C7CDA14444E +:108B60003E7852DC8F49865FC425F0471D9110B7CF +:108B7000771A438528273F5412FBCD6FD753DC7CEF +:108B80005EBBC28230DFC9279E2F447EFEC163CF09 +:108B900017CE8C5B4F723FF93C29E7137EC1643FCF +:108BA000EF40FE5DD9EECC06E6330F89B53F53FFAB +:108BB00037F2EFCEEC11FE614D1BEA447B48B44F17 +:108BC0001E2F3397F36B65A7427E0FE9DF3C76F0EB +:108BD000118CA4F49D9FA5A758179FCF289FE3C48D +:108BE000B94DC57383AD58DA7979A0F31A881E7F21 +:108BF00021E4903CB763ED4306211C8D4D3695F181 +:108C00007B6AA5A8AF7731AB07E9E9AF22AFD56999 +:108C10008527E869C65C970DF999FC2EC00FAD69F0 +:108C2000DBF0F95791F7EAB4C213C629C82DA5F1B4 +:108C3000FEAAF3925DF7437D07DD5F74093AC966CA +:108C40006145C14F1D2C784EA1BCAFF6447867B585 +:108C5000723912AD3392FC9270BF6AE69D64BFF622 +:108C6000735E1B108F722BF9BBC939C5C2DF11A10E +:108C70003882A592D9D1BE6FBD3240EB90E7E5E7CF +:108C8000CD99D2A390FE8CF92F29E9142F0D8827B6 +:108C9000B3A5B3BEF8418AB0775952BC201BF46E1D +:108CA0006C27D70965CAA3B9CF11EA28E1F156D2DA +:108CB0004B715C7C3F73A44AFE766C671C7361FC4D +:108CC000EBC35391973849BEAFB7F61B9F9884F713 +:108CD00083F01C403EA25EC83C8684FB419B419FC2 +:108CE000463B4DC67FF5BA50998BEC93DE08FA4FA0 +:108CF0008C156637CADB147DA814CF2F391E0CEDF6 +:108D00008A791E42BE03E58CBCFFD3B464BC17E372 +:108D100054A07F04CC787E93F9F935DD5545EF9565 +:108D200029A52D885FFEA58CBE5330BEA79BF2A45B +:108D3000FCB55C1FF3EF3C6A6480BF33853F870955 +:108D4000FF739638D76342FF8EC5BB225B30EFBB03 +:108D5000735E3EDDF74DCE2BF9AAF1CE33A900901C +:108D6000CBE2E25883CC5CCE88F397F42DE35AA98A +:108D700023BDC5A889FF2E3BFA2BEBD8AF90371245 +:108D80003878CF3FCE1B997613E68D9851CB17F5E7 +:108D9000B80C90A37DF7F92C6E8A7BF5D5E3771894 +:108DA000CC3B15717F8FDD74ED50CA3715E5D7D6F2 +:108DB00062DEF87D1696305FFCFAD4A4F10D30BE69 +:108DC000CD2DDA074EDE70AD4AF15F513F712DE6D1 +:108DD000C9DC67481C8F5050DE3F34C7E6BB7DF3CB +:108DE000867BD6E6C7E439C8F78D396363727DD5D3 +:108DF000DB933A2E73237D7D4AF9BB523EFB9D3CAB +:108E00008F24998F3D9AA348BD78028ADC55D317E9 +:108E1000D2770BFAE2BF3D751AEAC332FEEB5FEA86 +:108E2000A53C5ED007B6E7903E70EABDBD0CF5CE1E +:108E3000936417F8CFA9DC4F047A057E87C6DC530C +:108E400045FE504C4F1D1677FEF3859C421D1EE9D2 +:108E5000C1BFF93B8FE9B13E57EBCEC98CD987C969 +:108E6000EB7D2D87E7B9FB4BAB37223F608F2AF4B0 +:108E70001DA835A59F90DED1F4C2B563E3F3D0E71A +:108E8000ED7C90E7316F37F4BBFFD772F877629AC9 +:108E90005E7896FC9D2783FCFA4CBD1A5C8D7A683F +:108EA0007DBD0E352F561EACBB85F481E9B00FD8C1 +:108EB000572887C3C7BF7D6A00F3E2FDF09F02AF6A +:108EC0003679E7905DB069BAD986711C7FE9CC85A7 +:108ED00084FF76AB86FB4F5E672CCE6CA5FBCB6B1D +:108EE000761A6A518FAA00BDE95F61BD05E9136B6F +:108EF0003DC097F2F4DD653FB061DCBD7FB9ECCFDA +:108F0000E3E7D8A67803DF2A273F278BCFE329DAC8 +:108F1000C9F5B3A339C604BFFAD11C95E07975A091 +:108F2000773CE2DC1E3592827AB29F691FA3FDCBAB +:108F3000BC3637F977198FB33B97B9C9BF6B764603 +:108F4000EEBE8CF42895E2CCD2BE38FD02F78B4DF4 +:108F5000CDF59D46FCA8D0471EF816C2ED6E55F81B +:108F600089399F299C6A1B837E2C8B33F240AD9BF1 +:108F7000F26FC82F31E81B6D740E7B9CCC8EF019FC +:108F80001FA85395383923F9C6F8BEFB3B4EF29F14 +:108F90005673B6C686C169BD6726146DFB3223A61B +:108FA000271CFCFB34155F4AFD4167F6919D533346 +:108FB0001DEC46C4BB95D1033AF4D73B7B497F6C8B +:108FC0000C29344F63E92F293F6E81C8C3EACB8750 +:108FD0005223941F66CE4D117EA6368E97AC97EC29 +:108FE00062F614873FC84DCA1B8BE9F12DD44E8E13 +:108FF0006714718646E1C70140517D46AE22C65DC9 +:109000009E189F10F332D55D11EF77583F19240950 +:10901000ADCB9D86EBBDD7EACDCF85F6C7EA75040B +:10902000A263ED29F45DAAF54AAF86FEC84019CFC8 +:10903000A74DC6A33231EFA07DD109284FA22F0C36 +:10904000944FCBF367378EBD84F2D0CB777E3C0153 +:10905000F183D532A2C7A69D17974F5B81E731F602 +:10906000FFA17C5A8FA26D83E775B98EC47C5A0F1D +:109070003F2F19D74CCEA33D9D135679BE5B64CBD1 +:109080006368B7EF34519EC8A49DAF1C46BFE62469 +:10909000330B519C37497F38E29CEACD8579CE7CF1 +:1090A000F4DE96150CF3B09FF3F07B9989FAC0407B +:1090B000F600C53AE2ECC699126FBE267B40F26B11 +:1090C000BFB0AF3E54A2F796E0FE76EBEDFDDDA318 +:1090D000F1E7CAF8D80079203DFDE781C87B66B585 +:1090E00091E284B8D55D7D74F0D5E2604B5176F69F +:1090F000130753455E97AA70D6C11C3CEF47C6C103 +:10910000D4EE1114DF32C5E26061D64F1C4C1571EC +:10911000A55506AD8EFC34BB4D6E6E477B897FB581 +:1091200075677A90BFF9E79F7C063F05A03A26B89D +:10913000506F6813F06FB8F838D883B9FDC4C1B662 +:109140000ABDEDDD525DD80870DDCA38FF0DF4C8E8 +:1091500078988EECDAE83D05B46E658A99D6FDEE16 +:109160001ED336F44FCD9271AE3DDCBF364BC4B347 +:10917000DE9D5242FEA781E03CAB3D315EF0330103 +:10918000E7B3962AF2D3DF79FF64F2CFCF41FFFE37 +:1091900090D87D0926FC7CEE767E9FDEBD5DA1EF3A +:1091A00099229AE84827B5D3774D17001BDD84AC88 +:1091B0003700587305BC56740AEA43EE362883D24A +:1091C000AFAE56032E68B7F5700AF9155739DD2290 +:1091D0006F8DC79D036B95E0303E2E7DC72CD0A6CA +:1091E000D3709C5772B93FEACFB9C67EBF23D16610 +:1091F00010F163315F0B837387A74EE1CF55E23BDC +:1092000079C9F090E3B5199ACDE8DF8B16F0EFA19C +:109210009C356AD3C9EF9C5E42DF3D6A4B6D6EAFF1 +:10922000E5F544B3672D512FD57F43E50A2973A790 +:10923000E37A77E772FD2619CEB33B12CBC9719F53 +:10924000E47B5AB3986F78CE90F3EF31ED16FCF6CD +:10925000EC9A62712E1E8AA3B419DCBF29A6F829E4 +:10926000FFAE514B3E879BAE803F073B6AE8FB74E5 +:10927000402F5C8F637CFD83BFE154905EDA1C1C41 +:109280006FFFA7EB4E5EEFFBB9251CBE0E4EAF6D18 +:10929000AB952087175FF7C5FA490C795F2F5F7C84 +:1092A00057F13C1E2EA67EC41F02F71888EE765991 +:1092B000F8FD4BC9AF28B107ED4F61EF0E42651ABB +:1092C000E3A12756D2F78936D50F4EC378E9F8A91E +:1092D00036DA47D31E7EBFB77169A410F1BAA93A36 +:1092E00052D2DC0F5C710255F2576837D3C9F87758 +:1092F0006EDA13E37FC971DDB5195A415E26DA4B88 +:10930000EF76BF82E7DD6D21F9DAB434FA38FA0F6F +:109310007C19BEA1587FEAAEB727286EEA46FAFC50 +:1093200099DDC3E95EE2CCB6C47B5E6C6D625C9194 +:10933000B5A7F3FB6C9D89EFF13E5342BFF3E28C7E +:109340005CBF596FF48D40FDF39A6FF23C8A8FE653 +:10935000E9189EEB47167EFE817B5205BFF694C44A +:10936000CB83AA01CF17DA8DC4783ECF1F95ED1BB2 +:10937000F17CE15C1BC4F97EF4EC152578BEA7BA3C +:10938000AF28C1F35D6FE8D0903E52B27DD7629CAA +:10939000EDF8B55ED20F65BEECC5E2DDB4BCAFD76B +:1093A0003FF755E5719D9CFF2BCA63FC8BF79BEC47 +:1093B000F9BB3E6021F9C2EFB5C6FC7727E9FB5E39 +:1093C00067CEE914E4C7038DF789B0975C66164051 +:1093D0003DACA23A42FD2AFEA663A80F4A3D387969 +:1093E000FD8BC5B9AEC8D30EA35D28FDBDF5626C7B +:1093F00073F053AE6F3FAA903FD7EC0EA48D23FBC2 +:109400006AF6E57AE22FFF4AF725588F62473B65F7 +:10941000DEA32D547F7AE72CAAD799C361B4C71A6B +:10942000A11ECBABAE4ECC7F36EEE0F12069FFC281 +:109430003ADEC275A438A346C4CF26D4AF61894DA5 +:109440002AF77B37399927C0501F4EB417655C77D0 +:1094500093977F3F66538F42DF91CA32FA8AF3F1C6 +:109460005C93E2BBF7E769DD887732CEBE204BEB39 +:10947000CCE3F9678508A79FE2A2A01C31C87B5BFB +:1094800089F70F0FEEBD99F4A1CF997750FFF968D6 +:10949000C184F8FB1C714F748EB8278A7C3A9CC437 +:1094A000A7E3CB0D71F968E1FEF20AE2F2D1E2FB2B +:1094B000C5E7A38513F819A7FF6CFD228A7BFB0182 +:1094C000CF978C89E16103137F1BA2EFD2FD97ED4B +:1094D00026F2AB35887C547FFD31B257FC789F86ED +:1094E000D3A3C6EF61737DA801EC40CACB0D25E67E +:1094F000AD1EFC9AE953B61BC87FFE66123DCA7DBD +:10950000C97D34F4289C7E92D6996CFF26FBC1A5B8 +:10951000FD7AB17CE9FDAF591E7E55BEF4D9D7C4A2 +:1095200097CE8B270C8DA679BE8678C207EE8E2C3F +:109530007429CAFCE1F6DD3C7F7882DEA6F1F8A54D +:109540009EE73724C771DD13284E29E3C6E6E7F40A +:10955000C1E5C5D4DE83795F8DBB5329DFA0DE5D15 +:109560004F7A7772FC723EEB9E8047F1397B9DEE1D +:109570006FFD4FF306F2F3C57789DDACF82BE60DEE +:109580000CC9FF0AF1CB976C9F66F8E2F0A57A242C +:1095900028F02307CEEB2ACBE7F89722F24BCC6AD0 +:1095A0008039E2FA0FD4EFCA7CAE1FBF24F291EEED +:1095B0004B4DA17BFF2E23BFAFE0D2F1BC2996EB30 +:1095C000BD2A3F13E5013FCF875FF80EC3FB670F4E +:1095D0001B42740F3FD068F3A01C937E2739FE8393 +:1095E000397C3F174B47DEFCFF5DFE71AB9CEF62A1 +:1095F000E36F1B000671F4954C0F03F51B88BF2C1D +:10960000C8F7CEC9277B5C1B4D718B8BE44B29E5DA +:10961000C0B7514EEF30B9D17E403F0AC9C7B53906 +:10962000D2FEE6DF25B8AF80E4D747166E4FC8FB01 +:109630003F72FF3F1910DEFF9C9EF76E96378078D1 +:109640007EBC4AA3FB03AB52B97C893EC1F387922F +:10965000EFC124CB15798F43CE777FFEFF2D5F7D41 +:1096600058C2E77FC85741CE92FD32609CF6BCFEDF +:109670000191C7D9AB897C19BA0F21D7E5EFE579FC +:1096800077BF10EB93EFD70939F059BE1642BC3AB9 +:10969000F507B319E3A0E5E59C7F36796D144768BB +:1096A0000AF1FC9AA6A58CEC7E79DFB5D2E5DB85C4 +:1096B000FD56BD6DA3EF9E36EDDCDA3E98F20F7CD1 +:1096C000A4DF9DFE037F7F22DBB707DBF9974612FD +:1096D000E215155F7EBAB2B69CD64B76BBD39478B2 +:1096E0008F2892CFF386E4F34F7DF005FB04FA9DBB +:1096F000AAE779DE7EA766AFA2BC03EE0F4F71F733 +:10970000921FA8690709094649A758FFA37CC29B75 +:10971000A61D5565F4FD8190A58CBE5FF347FEBD87 +:10972000A75377E506F5DC7FFE5B5C6F6A79F07A1C +:10973000D4338B601E54494F755F5F46FEC124BA17 +:1097400093F4D6777FF4BBE660AB12A3C7F5062E81 +:1097500027A57C7B39DFCDFDD54E913FD83399CD00 +:10976000B6C5CA3667625EE58ABC6B5FC6F5BC9C4F +:10977000CFE30532CE5E6C06EB73F0F978582CE23D +:10978000EC93457E040B98637911832F1C6797EB4C +:10979000936519674F39277E5FC06E24BC486DE71B +:1097A0007C83015EA09E7D75B4773CDEDB1ADA19FE +:1097B000BE1AE13508C14F79AA91BB2FC3F845867F +:1097C0007A35C62FB62C19B30FE3AAEAEADE6FE0AA +:1097D000D1B83BECD5686256BABCBA02E22FCDA52F +:1097E00088FFD5BF35F07CC6D52924EF3B0B1B285D +:1097F0009FF1F4DBA6847B3AC9CF005BEE42BFD178 +:10980000E0F637297E90BA43E9374FB5AAC046FB48 +:10981000C4F6E8874A6DEF0D54A25FE51E857F3BD5 +:109820001256AFB8D0FE5775A877CCDAC9EF7DCF06 +:10983000EA70549B899F2A3CFE72B593F8A4BAFA49 +:10984000061DDA696A0BA3EFB45516703FF6B04EE9 +:10985000BB0ECFFDDFBED0F71B571B5E10CB8F4377 +:1098600070359AA2075CC5B178A0CC8B1BE8FBE7EA +:10987000521E25EBB3E7E9B1421EF5E9F349783C06 +:10988000503F89DF129FFFCDC0480FFB37C54CF713 +:10989000C1245EB7C93CFF2FB85FB748E4DB1C5B4F +:1098A000F39FA3F97D77194F09F23C294364651EA4 +:1098B000C12BF2CD00EE7B8743D73492FC614D344F +:1098C000CE6AFE7DB5A2F621CB2BCBF169670A2CBF +:1098D000E1D8AE0545489701C08361FDE081B180C4 +:1098E000DF575157A7D0B9A9EBE8CBD24C7564D15B +:1098F000B9A90FF2F361057C3F329E2BFD969FE5DF +:10990000FB6E463CECBBBFB5C4CAEF6F89FBC1A977 +:109910004BDE7E1AEF456D11FEE37D7B2EA5DF85C4 +:1099200038BB5A55504F3DEBA8A3DF41AA2BE0FAB4 +:1099300052AADACBECB678FCDC4779B58377F3FC36 +:109940004055DC7F56573BB7223C6B9C3ECA1FFEFE +:10995000465B987E3A618FFD38C5E9402FA27BAE09 +:10996000275F50A45E94200FA5DD966C8FDD51F02B +:10997000BFAB2705E47C5FD5CE6289F6665F7B6965 +:109980003F26DB1349FD07D27F981648C8937940DC +:109990009CBB94EFB98237CAFC99BEFBCE2C68C140 +:1099A000FB12239028C7C6F28898C82FDAA0583D2A +:1099B000A82F0D9447D497E7C39A2FE3FEC8E62B50 +:1099C000F029F390649E9105F34D32CECF37B1600C +:1099D000BE4906FE7E06BF372DF3455A0D6ECA3FBF +:1099E00009FC98511C5199524BFEBA74AF91F0EF9B +:1099F0000C0B6EC4EFC707A6D9E87E38DE2742BC41 +:109A00008F2A2E1A777CAD26DBEBB07DDF7708EB53 +:109A100018D5A70FD572500FB3403D7E1FB9EFBECA +:109A2000F46CFEBDF6E47C1399F724E3C0B9C39F40 +:109A300053D02F8A6E7FCA3FF881E857CCC7E9FC24 +:109A4000BE9BF846562BCF6B8A5EC9ECE897AF9663 +:109A5000FCC79C78AEEB155F31D2E77A2BFF5E40F6 +:109A600017F3B4EBA17C77C160EED761EEBD3A622B +:109A7000D81DF47B0F9B9CDA6B0599317C92EB62CD +:109A80001BF8BECFE0FD302536DF99797F2B44FDF2 +:109A9000AABAC7C4F13269FE4D7DDF6B095A509EE8 +:109AA000FCB980F1EF8C26E9BBF2F96789FF822FC0 +:109AB000CBF907DA9FC4CF0BE9F112FF06C2B7401A +:109AC000B538A72329A47F487CDBB76C3B7D877022 +:109AD000FFB2103DCF5894901EEFD55AA233903369 +:109AE0001EDFF25F37E1F73CCEA4460BF17B20D1BD +:109AF00087F55E2A67468F6099155DC1CBC3A25B6F +:109B0000F0FB20590FBFF82D2AE379E63276AE201C +:109B1000F4AD808DBECBB5B217E55679521E4BD24F +:109B2000770C52C4EF0765DB8CA44F668BB81EAB75 +:109B3000117A3D46A0A0DC9A5346713C1B73EFE8B6 +:109B4000C5FA7C13FFDE0103FCC7FA61C53C1F8226 +:109B5000F17DB37CE19F669100FD1E60B183FAF751 +:109B6000F1F11D26119FE2F31F7A96C711655E2F52 +:109B700063F602D4876C6E965096DF0161AABD0031 +:109B8000EFFDB74ABF9F28BF98E2CB2D8CD3970E2D +:109B90005DFBC391F4BB24CFFD6828F2CDEB8C892B +:109BA000DF7596CF3F14717BE58CF87EE11D29BEF1 +:109BB000218599F8BB243326E0A768A76754191DAF +:109BC000A4BF3DA1473E9529F0C3318DAFCF51E3EE +:109BD00055F0F740E4F703337D2AF90998AF538F26 +:109BE0007235F3B897F2051BCCD142FCDD9637CC29 +:109BF000BECB70FCB37547EFA47861EEA12398DF6C +:109C000071C8D0313E0DE548B1F89E040664A17CD0 +:109C100020AF88ECC13EFE304CA178E6A469FCDEA2 +:109C2000EB441652F19C27D8F93DAC09E5C59E5688 +:109C3000986F92C80F9970D89B86FC6DC277222AC4 +:109C4000FFDE45548DCFC7904FE632B8E3E9E17AA5 +:109C5000775C99E1778E13CB377A12CBDFAAFC625F +:109C6000787C7994A24DC47DBEA888EF46007FE140 +:109C7000FBE279873F17F6DCA52E662E427F8553DF +:109C800009A0BD70E9F3B9146779BE9251396BBB75 +:109C9000799B397EFFEB743C0E2DFCE0F2778DB0A2 +:109CA0000EE5ED737FC8227865D980DF3A89FB1015 +:109CB000BEED1374BB4FD069459ED98AFC7F9FC10E +:109CC000BD99F03CD5EC463FD5DE54237D37B675C3 +:109CD00021FF5D0425CDCC8C30AE7E262F433BF694 +:109CE0004DA8D75798299F649FC8D36EFDB14A7E6F +:109CF0002EACC7EFF9EAEFB5927FBB26ADF47B58E7 +:109D0000AF4F33D23D89BDA9153E311F7DCFFED166 +:109D10005473187F5F21F9FB9D87705D083758D712 +:109D2000637C1D448FFA0A23E9E1F2DE3A8C43F1A9 +:109D3000377DAE99E6DBE7B0EF45BC6BFD80343D87 +:109D4000A8AF7463FE97C4EF9AB44AFABD12A0BEDE +:109D5000A1F1DF67D76779DCFCBE2DFF1D8ED2BE77 +:109D6000DFE58069A11DFE861123BAE5F1BC020979 +:109D700077A66AD83E87C932BF6F96D557AE52E9EB +:109D8000BB418A2CB750F921512FBF37FA4EA19B06 +:109D9000DF4BEE79E53F106F87A6015CE09C3C2924 +:109DA000FDDF777AB290F3F7F3CFAFC2857E7F0500 +:109DB000F73932B6FF7D0E8FCB1B57EEE75C8288FA +:109DC0006FC9E7B2CFE271A39FEDC2E371B8CA7D5C +:109DD000E873393CFBF691D1FF3EDE11FB0889FBAD +:109DE000D9C9F5070B755FF73EFBC5BF7F7A9F5951 +:109DF00089FBFC1AD71951BE8675EA0B617DB6D86E +:109E0000FAE867C72A906F72FC9B28F29B59696237 +:109E10005E12ABF498B9BE989887749DB2B90DE5FF +:109E2000EB4322CEFD8AA0AB03293F198AFAD62B39 +:109E3000334AF613BF1DD4D286C425F9B3E4FF67B5 +:109E4000738E566019E44014E5D59D830FCDC0C1D3 +:109E5000F73B1E1A8AF20AF8E6C78599E7AF53D294 +:109E60006FDF7A817E918E24FD26AF5FD211BB29F0 +:109E700044099D5D2C4C4F17E3F9F3A097D0F7D11F +:109E800099BB20B63F20F209E666BE8F9600ADFB77 +:109E90003AC7039437682DF6198B605DD32FFB9872 +:109EA000BEA3C45C75C3518EC07A4D4563FFEFD627 +:109EB0000BFC2907DF4B3D3F59AFBF501EB95C6714 +:109EC000323F94EB51A66C273DDE0F7A3CCF3357DF +:109ED00088DFFBEB759C0FEF5448AF6F023983723C +:109EE0004A7ECFF79A126B1B7E2F729781FB53032A +:109EF000CF9ADC89DF574ACE3717F6C45226ED05D4 +:109F0000FE1D89463BFF7E9290339D770C96DF576E +:109F1000E2F210E454C2F795EADC89DF571AC05E1A +:109F200000BB80F433364827EC022EA73BAF74DB2E +:109F3000038CFCCFFCF7256F310A7D10609115FB77 +:109F4000FE1BD801F45DBB1B8A8AC5F7B582FCF7FE +:109F50003C84FE9FEC8F4EC9F6DD8478327BA4569C +:109F6000883F2D33CBC8FDCD806F9B7B19A64D3626 +:109F70003F8ADF47BD9E35BFA51B42F8360DDB4F3C +:109F8000BFF463FEDDD418BE7DBB2893CB2514320D +:109F900017A2E3234EDF0C1CA7D311FA237E3F7DCB +:109FA000538F89E02DF35293E93B6E3DC70D7C3D05 +:109FB0004EBD9ED63387F03F693D1783F7F1789504 +:109FC000CD387E0F84FF78FF23754C0CFF4729BEE8 +:109FD0003B70DE3E3A58C9EDAEF3D6ADB7D179DF6E +:109FE0007C0B8FCBF953A49DAC4DCAC9423F249F33 +:109FF000FFE6D51C2F6EAEE37944937B1A290EC77A +:10A000006A785CCD03FFA3DF8711FC6D9AB3CC8027 +:10A01000A8F739FB9E01FD9CD32625C6DFA69BAF82 +:10A02000A378DFCDD30C09BF8F29E1305DFCFEF6AC +:10A03000F4A4DFC54C864B72DCAE8F1F88FDE6E1D1 +:10A04000EFC5C0339FF17B3739E277CC3614F5C5C5 +:10A05000F7867FC5F8DEC31C8F2E2EBEB7DF10A596 +:10A06000EF3BBC9C3977F342A09BE13F1D49DF7B6E +:10A07000BF366BDEA3EBA0FCB34D9750F9E5ACEF18 +:10A080002E3E84F55B4AA85CA3FB7806D24169C5E5 +:10A090002D13F1FBF8FB2D7C1C97D5D789BF9BE2D4 +:10A0A0001A3D780CE60FD718A3D4EE86CB1A2FC72B +:10A0B0007CA81A2B2FBF5EF6FB31541E2CCA635EA0 +:10A0C000BC04CBFB958F67F4171FBCB45409E3EFB6 +:10A0D000A3D5A4F3F693C63C918BFEA29A6A5EBE0A +:10A0E000D453B57A08D6EB3E99D19F3EF286B0871D +:10A0F000A47EED15F4FEBC76B40DEF117A6D8A07DF +:10A10000EF8B782B8FF2EFAA99795E89572B53F159 +:10A11000BB9BD51AF7F38EB7B5E4205FBCC9672C9B +:10A12000477FBEDD56DC867AF1A0CAAAB178DEE3AD +:10A13000CD8CF009E8EA10D1D5151F17A62132DB26 +:10A1400012E94AE2ED64494F35897403FCE0F7FCFB +:10A150001C13E901C67D87F8C75589F2AA8FDF274E +:10A16000D16D323E0EA817B0443E18C3D390128F63 +:10A170009F5D48AF9C7E3FC2751875BD6E7C5FA425 +:10A18000782EA1449B01F40BB93E745BB231E7AF6A +:10A190000BFF54A98FF315D8ED59382FAF877E1ACE +:10A1A000FE989D5C17CCFF05C167255F4F97D22CA9 +:10A1B0007E1F85DB61D2DFD124F6FBDF798429C3E2 +:10A1C00000800000000000001F8B0800000000005D +:10A1D000000BE53D097894D5B5F79F7FB6249364CD +:10A1E000929090100893044280244CC222CAE2B09C +:10A1F00004A32C0E9B8022FE095BC84202E833B602 +:10A20000D80C844D8B6DA8A8A8A80302A2450C0AFF +:10A21000881AE8B088585163D5D6A5D244ADEC1061 +:10A2200083B6D8FAEA3BE7DC7B33F3FF498AF4BD17 +:10A23000F77D7DDF83DACBFDEF7ECEB9E79C7BCE69 +:10A24000B977D83ECBB9C64C467F7E48636C503850 +:10A25000F385E53196C8DC6B54153E76CAEDE3CD47 +:10A26000C6D2AE315FF5650C3FFD703D63172D8E94 +:10A27000354A346315E15139AC1F6353ECDE076C8A +:10A2800026C6A6C6CCB630E8671AF3ED894967EC56 +:10A2900085082DDA3510DA997CFB1B15C6E6328F5E +:10A2A00095C1F76CC5E3C4EF8C056050C616E23F5C +:10A2B0005DC17EBB415F0CE6B1D0EE08A839F06FFE +:10A2C0000FEBD129813145D4638679437D0F8B858E +:10A2D000F2FA37BE53B0FEAA3A05C7E9CA1A92305D +:10A2E0004D6295946F5D97613D3591B856C69A73EE +:10A2F0006DFECD388819FE1BC0D8F1C20CFFFD4A97 +:10A30000705EC7159669867A3E25DCBD3595B1BF6E +:10A3100086C1FAE17B2701872145FF318145B59D43 +:10A320006F959DD7BB3B3C6A33A6D76784AF30455A +:10A3300063FB143FD6EF140E694E70FE7F3531CDAE +:10A340000EF3BD5B8575A8B88EE6656618EF0956F5 +:10A350004BF9492E5834C0AF73EB7A7C0AE2C96AD4 +:10A3600052EEF03A604DF8E7FA603AC905008D27E1 +:10A3700070292C21086FE652981DF245222FE1DD4D +:10A38000C9EAEA8AFD18E15C64B735117CD7E47B41 +:10A390001AEDC1EFACF6114F683F1DD55300AEC9A1 +:10A3A000B16DE10FF3A7F98DAF1AE5FD320EC717B6 +:10A3B000F8B82792F031FE9E11F45D9994A934C249 +:10A3C000BC4615B8288D1DF09E9965135EA6D7650D +:10A3D00005F1F475BC368BE8CBDC387022E0F6ED85 +:10A3E00081CFE46A507EC2C48AB19E113E25089F87 +:10A3F000816DE1D34A7F06387434FFD722BC6538BB +:10A40000EE79A5611016C677710AB86BA9889F18F6 +:10A4100067EA881884FBF7302ED0FD142C023C3FED +:10A4200096A0DD89EDA6316FBE19D61B5BA059340D +:10A43000070D67C2F92C76F2F9E4AB0EA2CB961D9C +:10A440008ADF06F5467B7A3F3214F215C72CCC0F13 +:10A45000E52D8CD36DCB46D5EF037A99FFE64B8380 +:10A460006087B12F049DF6DA60622E890FF8AFB7CE +:10A470003F9CB93283F9BEDB6375F9ECBA2EBAFAA8 +:10A48000FDF6A5E9CA73037D74E5FD8FE5E9F203E6 +:10A490001BAED3D5BFE6A391BAFCB58D37E9EA0F61 +:10A4A000393549971FD67CABAE7E4D18EC9F7E08A0 +:10A4B0006E4F4326C0658EC0D3F5978B74EDCE46A4 +:10A4C0008D3986FB6ACEDAF9E3705F8D60A5BA7EBE +:10A4D00058ADE573A4CB4AF88BF89CC7BCD101807A +:10A4E000573E6B3E9A0CF05BE857DC08B7F91B78D7 +:10A4F0003DD96EC1BE45236330F5EBBF9732733053 +:10A500000FFD54FD71D36F8F84948F76169A90FE51 +:10A51000EA5C919D906ED835EC9A1FD476F1EB0EE3 +:10A5200020FE3E50DD36F8B4F84D95F6C1E2E71551 +:10A530003F837E3358CF68CC571C53991FF07F92CE +:10A54000553E3C14D2BF56FB7F7BA467103EB644F9 +:10A550003D9EC35C7A3C4764EAF11CE9D6E3397A54 +:10A56000B01ECF311E3D9EE30AF4788EF7EAF1DC8F +:10A5700079BA1ECF499A1ECFC9C57A3C77ABD4E3CE +:10A58000B97B951E9FA9BE123DFE0CF897FC377D46 +:10A59000CD625DBD563AF0168FC3B467ED4F74FDC2 +:10A5A00096AA6556660AD2830FFE223DF462CC1D40 +:10A5B00000382F043C045C6DE9A0B87EDDAAE47F7E +:10A5C000810E9A11FF1121F85767466BEDF06B99D8 +:10A5D0004ABC82BCFC8B0BF84878AAF61DA6D37B3C +:10A5E0007D9D6206BEC1BC85BDBC9141BE6794A77E +:10A5F000528EA23C320F0ACAA38EF85A1B393A4136 +:10A60000CA9F0EE4A8AB5B900F02403E665CCE335F +:10A61000B6D684F39821E8FA5038A7CB4B58742D5E +:10A62000D4833A83615E1FE3BC619C8FC3FB1EC170 +:10A630007D7A2BABB360FF335903A5B35833A51A0A +:10A640007392DE50C4DC94CE615E4ADFB66BC9A95A +:10A65000C037CBEC8D8350EFF84BE17B27149CCCBB +:10A66000F1389C6C877095FCFA7DFC27D4F3A67AB0 +:10A67000D353213FDAEEBAF321F87408E504F2DF90 +:10A680007171345F66F6664FCA6EAF9FE524375E20 +:10A6900053340DF9AE2FC9EEDE0A6BEB9BCCEC49BF +:10A6A00028E712FD6993003F79A97AF9D247D0C40F +:10A6B000F35DEA16A39EC4983F16E5C3D58E3B3CD6 +:10A6C000D5732DAE5FD6BFD27AADD6BA4538CFE6B8 +:10A6D00072877B33D0E707021F4FDF620BA851411F +:10A6E0003AFA2862D6D178C0DB5D11DA0DD8FFF4D2 +:10A6F0006937AEC2BC7228CEB518E677B110E0CD8E +:10A70000E13F96C35FEB9E004B3CDF4DEB158DF0B8 +:10A71000F772F8C33FB2BDEDCE9FCF6794C2C77F3B +:10A720002D429B82FD1C3235A4B8111EE68641A441 +:10A73000773AE2A99FF3560E978EE03032A2DB4CB7 +:10A740005CD71C9BCDAD429F23158ED72FE3EE988F +:10A750005501FF9C6BF2260454DDBC8B10DF65CEE7 +:10A76000C2EE494037E72D62DEF67801775716EEE4 +:10A77000AB8EE65D83FDA31E78AFE2473D90FE40C1 +:10A78000FE655F8CFF7EC8DB4C973E988CFA4BB61B +:10A79000C9BD198A368643D740EFEF0A783F6181F9 +:10A7A0007C2C7D5F83DF13C379FBC4874DFE1A6861 +:10A7B000EF1DF90AE1E9E9850E5A4F2173597193AA +:10A7C000CD16FAF39F47FC7D7F23E0C397AAFD14C3 +:10A7D000D771479C29E5039A87D617F51D36F4C72C +:10A7E000D1BFDCA7939C7C097305DC26330FEDBB3E +:10A7F000A94CB3E0B8BFBB60F520FFFC9DE027A0EB +:10A80000DFD3F719CC4FE96D2C40F56F678D947F3E +:10A810002F22A75B15CC6FE223BD7A227F0D81FB2F +:10A820003A82BB5DBBA313A797939D11EEEBE37F29 +:10A8300014FD4E14F402FBF551A417D8AF0372D3E4 +:10A8400042F6CD684E2FCCECECF9CFF64D430B978A +:10A8500017C0181D49B0FE1B040A6FF094929C406B +:10A860003DAB13C0BFC1A5929E5530A2C98CF3DF8A +:10A87000F635E7636F2C63913E287F6384CA105FCF +:10A8800013368C398DED8EB340A701503FFFB27661 +:10A89000241AD63F01F83B706456D015E444885C16 +:10A8A000BA2971DD68D4236EEAA1FF3E96D5AA08C5 +:10A8B000BF71597AB93201E58AAC07E31D4438C447 +:10A8C000B6952FF5A942BEF4617DAE46BE2C367911 +:10A8D0000E131F013A43BA2F32334F7BFBCDD54BBA +:10A8E000917C8CF4969BC5D82DE32E592FC27AFF0C +:10A8F0009EAABD83FD2C1EFFE759C88FE11CF5768B +:10A900007F94A3EFA8EC7E28FFBC1A200EC2F5CBE3 +:10A910006A3BF38082F355B593F2A7AA13293D53FE +:10A92000EDA2F45C7526955FA876533E2DCDFB070E +:10A93000ECB768CDD766D4A3568749FCF1792C11C2 +:10A94000F4BB3A8C9FA396442EF9A810C65D420230 +:10A9500010E4755DED18044BC9BEBAA398C277D553 +:10A9600081E5EB1437CAA7B947B455483EF38F3792 +:10A970004E40B633F0C32F13106EE59715A6C1569F +:10A98000BABFA7E72B1CFF64F5609AD7E96A0FCD21 +:10A99000CB53DF74340EDA9FAD2EA0FC9034EF3928 +:10A9A000ACE7615F5BB1FDF81D4DE66428CFF72889 +:10A9B0001EDCDFC33DCCEF07FC6DB07079B101E464 +:10A9C00005D2CF88EC494FDCC9909F6B7FC1FD3128 +:10A9D0003576767E1CD2D5E04233D69BF63DE85CD8 +:10A9E000A941FABED23E397F4021F89C3F1043F086 +:10A9F00090702A17F83ABFB7EFCD43A0DF03A04706 +:10AA0000AA30BF96CB269A5FCB47E17E54128CEDDD +:10AA100017EF49EFCC1CB84E686CC37CDFCE0CF04E +:10AA200010617FFA093C979D7DFEEE44C4CBD9D8D6 +:10AA3000BABF7C827CEF33CEF740E3FDEA31E48B92 +:10AA40005D13DDF743EE8205CE6974AEA98C40B983 +:10AA5000B8D0CA349ED7FA62FE6C38A3F3EBA09D3F +:10AA6000C923713FE178AE5E41BE96A9B85815D0B2 +:10AA70007DC6CE47D27E0AF3DE5E37F793C7203D10 +:10AA8000EF37F92C20B7CEB3BA0BAF225FDEE270FE +:10AA90006F6558DF1C8EF57F6EE1F3F26D8573BB39 +:10AAA0000BFBF3131D43B915CBCB5E7CB40BCEFF70 +:10AAB00035D44B20FFDABA08E277AF59DC27AAB0C9 +:10AAC000DD13BCBF677E71CFE7FB307DA03CEF1E7E +:10AAD00048FBA7C5523F737EB5A00FB607B9CF920A +:10AAE000803FFEFA6525100670CB5E7F7079128C70 +:10AAF000D76F6393A90BA4B95B941A4CFB762B38E0 +:10AB000086F2F6DA3417E1ABFF8E5415F5C93E5DD7 +:10AB1000FC9F5C4FFA805E4FC85AFFF5C82E2CA8E8 +:10AB20002FF451EACE2C037A58DDEDF779FC9C58CE +:10AB30004BF3D8533FF9FDDB18AE0334119C77A1DA +:10AB400095EC14B85C0BE4CFEF4EDF84F68CBD2699 +:10AB5000DF26925F455C5F39EFF53D8A74560EF54E +:10AB60007D902FCFF5455D07E5E59FF5700345B175 +:10AB70006E4FDE5080F058B8FBA1315DA0DEF9A128 +:10AB8000CC0DA860C57B2E8DC176AC1BE8D6D8CF86 +:10AB9000EE9A845BA1DDCFB3460E44BAF2AA7534B7 +:10ABA0000EABE0E33C22E41E6B04E024081104F544 +:10ABB0007E0E9FF17B6C7DCCC16416C44F45FDB207 +:10ABC00054B4B70CD0EC6E15F74DAA2FA9D211943E +:10ABD000A320FF6E4B837A4956D1AF73728AF72A4E +:10ABE000E49F55C833D9DF2356E60B8BE57AB38251 +:10ABF000F2D9CAE5F656E02F557941B90DE396E250 +:10AC0000B856A12F278390CE8579263F62F3936EA5 +:10AC1000F023C737DAD1A4DE323DAE667F23DA7B7C +:10AC200022B4BB711C69376366B70BF5A215119E80 +:10AC3000AA34D2BB9A53700D205797A6417F0B556B +:10AC4000D0C3D243F430FB8F93AB2F447896637F0D +:10AC50003FB6BE91EF2EF9D6C472810E963C64A326 +:10AC6000736A8DB037D408FB564DE4203BF20B7667 +:10AC7000C4547614E4ED30DE436BBF4B22F3889F5F +:10AC8000D430D62EDC0E001FD080EF04406E68C09A +:10AC90000F865F6E5639DD371C8E1E80FC9679223A +:10ACA0005D680730312D449E1AFB01BC6DC6758E60 +:10ACB00060114C0B919B1E1663C5FDCB1CB1FFD2DE +:10ACC000FA870AFCC9750C15F6BCA12D1F4520DFBB +:10ACD0005CF26D1EF1CF8ED6B75FACEF37B83E4851 +:10ACE000937A79F7E03C877DE334E33A879927A6A6 +:10ACF000A09E03F37F0DF13CFC1B937EFEDF87EBF0 +:10AD0000F23F761D7729CC67C2FDF9B5D58FFBB32D +:10AD10001EE81BF773FD822C3FF281BDB01FEC785B +:10AD2000AE9964253DB75ED849EBE39D645F7ACD6B +:10AD3000C2F3BE19A27D182339523FA30BB5EF62AF +:10AD4000AB7C2B1BFBAF8920FE596FF1AF49C3FED3 +:10AD5000EF8D73FB005F2ACA8FFE70DE10FCBBC64E +:10AD600012B84DC5FEBEB6321C6F7D4C20B902EA4A +:10AD7000AF5FD085EA7F04AA14DAEF86984C774C4F +:10AD80007460B9272916F27BFFA192DC589F0B79DA +:10AD900007F171B207AE9FE8490AEF84698289E63C +:10ADA000A3B24AFA9ECADB7D62E1F56E15F8FB5844 +:10ADB000E007F639F1016D428419E9D8945EF46D2B +:10ADC0001AE1DD93A4C07C1E9BD393211FBDB5E483 +:10ADD000C654A29BDA47889F4D173890FD6103FB4C +:10ADE00020D4A3F99F1973B786213EA71687917DBA +:10ADF000F4A3E2E5912E683F55530336B41B4FC9C7 +:10AE0000F7849EC74DE91E1AB7BCAE77FA97217436 +:10AE10005D6403BE01FDFF225CFB9EF6EDBE5C2A75 +:10AE2000DF07CACD0FB0AF3E9FD37327D935E6C831 +:10AE300073646036E2F540B39DE1F9A4237AA8413A +:10AE40003C40BFDD855C277A45FC4F0FE7E71C33AC +:10AE5000D00BE46BEA7AD339E7290BF32888AF3DAE +:10AE600036C27FC124BB87EC8FD3C337D9A0FC0E79 +:10AE7000C1CF6AA687D3F79AFD917E9342E727CA8E +:10AE8000FB7659A85D99D5FFEC36E8A7EC406F92A8 +:10AE9000377BAD62DC57237879942775E5002CEF7A +:10AEA0004C74F09AC5154DE56FAA8CCAC3031931CD +:10AEB00000C7B830AD5BFA40A43BC0B303FBE5DF8D +:10AEC0004F08FA3A01DD22FE7C9591D42F6D7DC8A2 +:10AED0006B35DD36233E352B2F673F51A9FC84D3DC +:10AEE000933417F2272A93695ED2CE74C26B25BAC7 +:10AEF0003F51A690BEF4C72A35600DB5E34FDA7E08 +:10AF00005F06B4FBE28085EC78337F597A1CBFCFB3 +:10AF10005C5E4EF6C899254BC94F7061E9178336C0 +:10AF2000C07A1A977F9AA285D8A5679641AB90FD03 +:10AF30007C43BA67503AE06776BA762DAEAF22AB63 +:10AF4000711EEAD717AC0D4FE27921A3933614BFD7 +:10AF50005F7CE5E436AE773767A09C5868E67422DC +:10AF6000E56D85A0C34BE9DA48AC0F709B8572256F +:10AF700022AB81F3BFA53F8EFF9FA9DFBA57817136 +:10AF80004AC3EB1752AAFA73B09FB34A204A492723 +:10AF9000386AB8AFCE390351087FCDC4F5BCD2EDC5 +:10AFA000FA75E11F7302DACD18D9C14BEB544F1873 +:10AFB000EE03E6B7E2FC4B9935583F35882FE8871A +:10AFC000F0C51C7F9CF553C043C9B3BDF3F07C5161 +:10AFD0001AB3EF1743A81EB493FB456D9B97EB691B +:10AFE0003B1FBEBE73621F9C832F16A4971D36792C +:10AFF000CEA7F12FBCD299C64F10FBE48222E8F510 +:10B00000D9304E576E5817CEF3054E570F4B3EF9B9 +:10B010002CEFA734CE6742BE545AED24BA927C0975 +:10B02000E642FBEBECCE646A27F918F33246F5777B +:10B03000266DE6FA9B38EFE284A17EC9AFF9389815 +:10B04000477E7EE6B964392EE9DB46796C5CF7EA27 +:10B05000746E9F0239DDF99F9D173313673F31A747 +:10B060007FC87A22AD822FB8132766A37FC1AAEBCF +:10B07000F742A4F50E8F03FD0CFAEFB2BF07D3F928 +:10B0800079B2BB01CF5DD4E68336DC874F33921BA8 +:10B09000C6793C26DA3DF75C2B5E55614F672E4939 +:10B0A0004F2EAECF13FE3EB64AFCDD990CFCB81411 +:10B0B00061951684E3DE5C2D19E5C605E11FDA1BF8 +:10B0C00003F92CD4A7385E645EE2C34897CB3F9E59 +:10B0D000978CFEA837D2B99FCD08EF6500572CAFEB +:10B0E000B1C0F9260BCFB9C71EFCB267703D5F55E2 +:10B0F0007B3C7342F2F336E4DA713FCEDF986B2F7C +:10B100000AC147CDF6FEC75C00F773DBCD6E64EF76 +:10B110003566FF2F504FAFD9AED6211D41B91DE185 +:10B120007DCE71E81DAC376F634C1EEAE1B2FDFCC9 +:10B130000DF99E392178E8BB5D8F97EC3A7DBEDF33 +:10B140003E7DFE3DD441E3AFBE5D6E409FEF7F4C40 +:10B150009F67CD80BD41A80F70BCBD3CD87DCC059C +:10B1600078EBEE57DDF8A9BB63D2E4F1A8476C5445 +:10B17000DD3DA1BCFB52EF58D42B4E6D9CEB46B489 +:10B1800017ABBE853F059C167F3AE618CAD5B3AC0F +:10B19000EEF7E3012FF3EAD759CD2E5CB79EDEF729 +:10B1A0009A04FD3EC7ED770BFCFAF2B67C6199B4C8 +:10B1B0007B6486D297910E60DC5B3C30A1B2AAF72B +:10B1C0001F44BE503C0E081FE8ECDABA7556D4FF97 +:10B1D000AE3C8E8FEB970E8F0BE1513898975D57F1 +:10B1E000358A7D01FB8EAD7D6F0CCEBBF0E70AE9A1 +:10B1F0001F852FF53A82F4D5B46BC64D94DE5240CC +:10B20000EB9776C2F9F54A2012F2CEC1AE7D8DD011 +:10B210006EAE9FDB3B8A56D882FC90A19FCC308FCC +:10B22000F521E530FFF9FB0E7EA740FFC51BF5EDCC +:10B2300016009F46F953B2E5075BE877791EBDAE6D +:10B240007E938AEB9E2BE62FE527F30D273FC575EE +:10B25000BC09FB12FF0FE44E698216DF233E28472C +:10B26000AF5BCFDB03DB2DC475973BAC2E5C77B9AE +:10B270009D0522603EC722AD1E277CBFB42192EC03 +:10B2800074F36CA0AFE651CA308E011831F9CBBE11 +:10B290007A5725BDA73C8EE3BDFC2985CE69E568BC +:10B2A0005CC5FCD33CBF8005683D482F9ED075FA35 +:10B2B000F57956CBCF7765E6C041844B096BE4E75F +:10B2C00033C0A727C4DF5D06EBFC2816F537437BA8 +:10B2D000E6D6C88FE7E0FA58C5BE1F6CA1E5F29C20 +:10B2E00029CFC1D27EFC5486371CC7B108BD79FD79 +:10B2F0007D9E0C9CEF4A8B2703E1E05B1746E7FD40 +:10B300005B3771F9B53E06F4D84EA43F933E7EAB51 +:10B31000C2F5733683F3C321A61703286F9A1F8AD9 +:10B32000716F76517D9263EB1FE8CDF5FF7FA8A486 +:10B330000F35AFE37111EB7339FCD63F90CDF57F3C +:10B3400029F7E219F5D756DFF664A01D823DC8E75C +:10B35000F5092E2944BF8EE8AC4D467CCBF549BD9E +:10B360009C15FF387FC65611A7D1BC2ECC8FFE8C02 +:10B370002F15EF5153887E3BA707971383467AB664 +:10B38000897AE4F798639A78FFF530AF390F9B5CC0 +:10B39000687F6B85B7C79381F2F3CB756179486796 +:10B3A0008346727BD4895CCEF72306308F1FD2721E +:10B3B000D16F790F932E4D0C07FA837EBECCE7F642 +:10B3C000F0C8015EB2036E7571BE6F5CC73DA29F8F +:10B3D0003956EF6F87B5331F0917369AEB1D5F2E6D +:10B3E0005236F37901BE213FE85761643FFC52C8F1 +:10B3F00025095FA01B8A7B907C2BA6955EFCCF86DF +:10B4000001BDACB3703A90E7B6107A11F8EF46F888 +:10B41000BD55E0973D1026E8C5C4FE8670CC777216 +:10B420007AB8CAF317E07B5D8F816DCF6112DFCCF4 +:10B43000EC1FF8CFFC2EE52F3FBFD7077A46C90B8C +:10B440000F4531A877DA5C9BE086F6655B57467955 +:10B45000203D65F6453961FCD37EB5C0DF0EBCDF0B +:10B460004578F3739C4309F1939E79EEE713709D41 +:10B470007FD96A71224BA8D86EA3F3D8C2DD0B48DE +:10B480005F877C13CFAFFE1AFDA615FBF4F6F99289 +:10B49000671E4A7011BC7DC9A6444C03C90CD285F5 +:10B4A0005B2CAD7E641806F4EFE655383F637B9C59 +:10B4B000C765C077459D5A688D6E5B5E21F84BC5A8 +:10B4C000EE9F7F8D76C38ADD379E447E5F61F00BF1 +:10B4D000140BFF88D12FF09B1E7ABF33C087E20C7C +:10B4E0007C30AF9E442EDCAE5CF3EC23394DA83F9C +:10B4F0006C792B4AC90AFA07A4DFA4A56EF653AFEC +:10B50000BA3ADE9717847D388837CEBF5CFB140CBF +:10B510005682833F4FCB2C81A82178DEDB6421FD4E +:10B52000B7ECF9A7B73D8674F6B18DE47BE9F3AFCC +:10B53000FFFE3AD49F77593A8DE3CB7028217139B9 +:10B54000152E6E8F93F82979E975AB2B9B7F5F1AC7 +:10B550001BC453E9AE83568C0F32C27354DD416B6A +:10B56000A3A31D7CD5358D213BD4B37FB5E2FE3836 +:10B570007D40619D53DBB62FDEF47A14EA6708271D +:10B58000944F126FAD7834D487FE27BC3A80EA39E5 +:10B59000F19C72253C3ED58371BEF272248B817979 +:10B5A000147F62F38F43FCEE5C1285EB3969AEE4E5 +:10B5B00074FFC4CA04D4F78A2DBE0427A5FC7BF10E +:10B5C0009377113DCE572A139C5944EF4926D22533 +:10B5D0007C49B8CEB91BA7D23AE7318DE8B1F8095A +:10B5E000D5EB87F45B332BD8D5CEBE19DB93F3A90B +:10B5F000939B01B9B0CE93223ECBF73B559CA3174A +:10B60000913CBF4BAC99B1C594FF56E873DD7AB657 +:10B61000FABFEDA1E7D08A2DAB1B104F67BA793A7C +:10B62000E33C010E3E0137E507E8577D2FBF33C7E6 +:10B63000137361FC02B503B93A0ABF63FD068B07B9 +:10B64000EDEC21EDC439918F7FA7181FE61D8EE721 +:10B65000E09309EDC77FFDA4A7E40BAC2134FEAB5A +:10B66000433EB0E53EA2AF6F3EE07C66A17F620143 +:10B67000953758029DB1DC7F708A427CC2C602EDCC +:10B68000EDF32D16B1CFF5E5304FB3120ADF035CB1 +:10B690003F95F4320FF4B240889E10A41F6BF03B2C +:10B6A000ADFF57623D8DE4CF937EC0F9823F18D73E +:10B6B0006FE417F93D0D714AA23DDBD8BEFF29C8E2 +:10B6C000277C346E19C877D447CA3EB6911E51F60E +:10B6D000BCC58B703ABBE3F0EF6FC5F36D9DDCD753 +:10B6E0007A3E6CDCD7C52F0E6C775F9F5D9BDBFECF +:10B6F000BE86EFEDEEEBB50AF1BBFF2E1F06C94784 +:10B7000076892BEDDFF91DF0E14A035CBF6559D165 +:10B7100043B0D059D89DF06480AF84AB91AF5A91BB +:10B7200049B6C35719867484C053C251D22B631AC9 +:10B730008DD34AD7926E255DB7D2AD71DD7A781A76 +:10B74000CBF310F7301FEF2B16D217CAEA797C2201 +:10B75000B4A378BA0AB4CF53EDDAA3C99D42F37EFD +:10B7600043BECE50DF63C87B0DF53543BE5257BF95 +:10B770006CDF612B3F3F0474F56C5563E93CD25696 +:10B78000CFF073BFD3EEAFAD3EA48FAECD56E493F2 +:10B7900096E5CC1709ED9BF7ABA4F75C743547A190 +:10B7A000DEB2328CEB75179D221FC3F3CDF1D65557 +:10B7B000C827E5F7E6306E87B9E86D8E8A0939CF7C +:10B7C00037D5AB5168FF6DF4B382F6E35B6A683F2F +:10B7D00035B28ECAB97E77319CDB1B2E86737B43D4 +:10B7E000BEEA48A9423B6C2D8F239CB36C5A14C50A +:10B7F00061D4A7DF3C1DBECF7D93C20C308ECE8CB2 +:10B80000F10FB3392AD929E6A378C2D9F53C0E62E3 +:10B81000CE5A3D9EE739B650BCDCB76C29A5F3D6AD +:10B82000EBE3174AD85AA2B3E28D86EFF563699F1E +:10B830009418F68926ECC3C67DF2A1DC27B92C57F3 +:10B84000172729F879BE9A75F374C0C7C5632AB360 +:10B8500041BEA55E65AB06F0B858F43FE18104F740 +:10B86000DF42D8AFA83749789DC37DD4AB63FDE5EF +:10B87000DC9ECF06FD14E966EFA7398F437A6EEFA1 +:10B88000C719AF61FEE53FA47CCADAD61F75E0BBDD +:10B8900059C8A72F1EB031A4F78B07DE48417BE4BF +:10B8A000C5576D74CEBEB8DCC6EDDC0722FD28623C +:10B8B0002E76E37A71CDFEBFE634925C5EC1E5621E +:10B8C0008695F0DC52FFF713684F6FA9875521DF8B +:10B8D0003F1041FBA9E2D530B2335FDCFFD741A175 +:10B8E000F6B9FFEE7AA4FFFD62249BFE22D2710C12 +:10B8F0003F1754BC76EDD3E85F2EDF7DD03A1BCAEC +:10B9000047FDE63F7390AF5E7C91EB53172C8D4F54 +:10B91000A28D3322E3D2AF2C4968E783CEBA30B68A +:10B9200025A3FF645F567B70E170B80870C0750195 +:10B930005C8A511E74048FB47F5B787C3D8BF3B7B7 +:10B940006B18FAA38370513CFC7BA4DFAED0FAF9EC +:10B95000F7037FCD41FE73A5F57A70BD03FFFFAC01 +:10B9600077D6BFED7A39BD7F85F235BE2DDDB7A51F +:10B97000EB97FF83F23B23DD34DF1FB9DF7FF6FF58 +:10B980008CBE37FEDBAEF74AF87E53E03BD289FE31 +:10B99000CC8BFBFF33855DC5BA5FFB3FBA6EA9C791 +:10B9A0008F54DDC772A1FE5BACEE03772A6923EDED +:10B9B000EA21A7321479BEA3F3D328C6E5F4287B85 +:10B9C00029E99FA3BA3E40FA720DCB23FF85AFABA6 +:10B9D0004A7E1D0A020138BC91984BF7AC9839D0C9 +:10B9E0007509E447269753BC98F15C392A7C7C01A1 +:10B9F000EAA78797C1BCA09FC3912627FAA84777DB +:10BA00005503B61C4A9B303D9A3296E2FE473BF402 +:10BA1000E7ABB18673D28D2E7D79017BB113FAED40 +:10BA20000AB22C74BF620CD60F39571ECD70D23AB1 +:10BA30006F64B52B9C8EAB8753622F7ECE6C0B87C9 +:10BA40007F0EB7367012E768B3A86F849BD9717FF9 +:10BA500003B633333817F3F5D2795A9E8BAF044FC0 +:10BA600026CEDB6631B484AFB92BF7CF86F44B70AA +:10BA70009170BF5A784B3C19E12EE12BE166C4C3AB +:10BA8000D90C26CEB71CFE5DCDB966DC77C3845ECB +:10BA90003FDA1CC3F35D1B542FED473FE16DD437F4 +:10BAA0006E33EAF5231C3114476ABCBF5034386644 +:10BAB0009002EB4D36339F0DCEA1E87B23BBEB7D8F +:10BAC00066FFF2541C87DB77BB99B9FD1A76B72F56 +:10BAD0003C8FEA7BAC902F7C703EF340FDC264E665 +:10BAE00056787D161D4BE1714CC5383148B15D610A +:10BAF00034EFB7B033F32FE7F824BCA0D907ED1B20 +:10BB0000D0AFC714CBDB47E5517B9F89B7F79821AE +:10BB1000ED9ECEE3149A5772BB7CE1EA6E19C83FE2 +:10BB2000C68DD4DB996B7B717FA44CBFEFC5F7BB8F +:10BB30006A7227D27D8A15BDE97CA4867BCBF7A0EB +:10BB40009D7E278FD3295C75FBF88138BF9D716E70 +:10BB50009CDE9909BB06F1FA33EEFA10BE6BDBC32B +:10BB6000E8BB2B531BDB0BE30114D7AC3DF0A16802 +:10BB7000EA616B220CA1D54D3C8F76C209BE5DEF08 +:10BB8000A07F72C21495EA4F603C0E93AD88A03836 +:10BB9000CCF1BEAFCD89D0DF78387460795398335B +:10BBA0006511CCBF50D887A7897863359C692F3A37 +:10BBB000705EDD32D2E0FB78D67E7CF243627FA9F4 +:10BBC00023958DE867EA3E8ADBEF657DEC07FB7D18 +:10BBD000BC17B747158954E601AE547FCE1A5B53A4 +:10BBE0003A9E7FD65802BD20FDB0F7C879BDA07C33 +:10BBF0005C1A1BB301E17E8FCA36D37C9B0BC9AFA5 +:10BC00001099E9423C6840D2E45FA94D75A15DAC52 +:10BC100069445D00FD094D8FA6BA6B5C84658A0797 +:10BC200092E7ADA611811E68C76FCEE57E8913CE5F +:10BC3000C6483C2FCE76D8F9FD4911573457DCA3BE +:10BC4000E95ED3F8C035780E7D48257FCDDC87F8D6 +:10BC5000FDB03F3BEC7E05CF6DEBF93E656BF571BA +:10BC600044CCE9263BD0ECDA11563C6FCE7178AC6F +:10BC7000B84E7FA6B602D725EF23F641244097851C +:10BC8000B58514AFA246C1BEC37D627645E139D801 +:10BC900018875421E28E64FE17E1DA03D85F51B4AD +:10BCA0006B27D2CBE755E9641F3D2EE86E1CC655C5 +:10BCB000A23FC3DC9884F3198EDF11AEB1CE0C071E +:10BCC000D17318433834599C1948DF4D2BC34CE8C5 +:10BCD000971BB79CD335EC33BB19DADF6766E1E815 +:10BCE00067B84DB49FB9CCECDD04F9AE76668E8CA6 +:10BCF00045BACA25BA4EECA315E17C4EDDCB06232E +:10BD00003DCC5EBB8EFC31922E98B961741C8C7355 +:10BD10006A6B6A1EF2CD563EDD67E4965EA1F43092 +:10BD200045213A80F4603AD1C3A46791EEC78D0CE7 +:10BD3000F4589C85E7D132E641F99EC8DCA827B4C7 +:10BD4000B066F257B638AC2EB47F497E22F986BC75 +:10BD50002F2BE9601BC87BB385B1EDD5764A9FAB2D +:10BD60007632734FC6765427527E67B58BD2BAEAC5 +:10BD70004CFAFE62B59BF2BBAB07537E6FB587F200 +:10BD8000FBAA0B287DB5DA4BDF255F02B8101F92A6 +:10BD90007C45F2A3D90E6B13FA2F255F32D2CD2C3E +:10BDA00000EFF03C6A4F7C4FF23B5C87292FC88F35 +:10BDB000247ED314AF2F3115F958E30CC47FBE7A1B +:10BDC000EEF997F15C5EEC70D3399D71BED702F449 +:10BDD0008A7049B1B27D6897AD59E4695A9D1A8459 +:10BDE000FF6DC50A3387D0D5ED9561CC1C2237EEA7 +:10BDF000A88AD1E56756BDFF7A67DC0FF1DA67885C +:10BE000097133FFBEA893FC0F7A77E76A627E21B80 +:10BE1000E6B1F5111C776978EB3C6231BFC2427E16 +:10BE2000AEEEC27ED25DD84FF04FE87DE6A77EF63B +:10BE300037DAE74D553617EAC59F20BE00BE7F149E +:10BE4000F82AAAB2111C0B577EF1FCCBB8DF975A27 +:10BE500089DF15AD10FBD1700FFAF324467609D0B7 +:10BE6000AA299EFDF37BAD8108E8FF7385EF63058A +:10BE7000948399187FB8E68D8F900F2855C7C8FF17 +:10BE8000AEE1BD3D9C9FCF724E77AFBAEA28D56335 +:10BE90008D5D63D0CF23EF25470CF0585DB07EA4B5 +:10BEA0006DC45F51E62196847E965AC589AADF1C2F +:10BEB000F17DCE1A85FC9A18C73305EF9167AAB4B5 +:10BEC000AF46F432135E9FC2187CD2EF6A494E49E6 +:10BED000BA9DB316DAE1FEA8CDB5CE0BE1C745E2B7 +:10BEE000FBEC4C13A5F27B02F60BFD7559933B1D41 +:10BEF000F58A2E589E8569DE74846F17C718B312B1 +:10BF00004207CE4CB398071FFF29442EFCEFFECC0E +:10BF100034EBDC2CBA0F48724C8E539499B70AE379 +:10BF20004B8BD68E402ECC6A2CEEC44E502FA9B52A +:10BF30001F711FDBCEE3A8CB3A9023D2AE760AFF67 +:10BF4000792DAD9BECBE253B7FBD13EF17947C6A2A +:10BF500023FC96F413715B59FE4193C900A9B7679E +:10BF60008FFEF56751E4A7D8CDE33B21E576D6A552 +:10BF7000C5DC2EEB86FDD58EBFE8C8CE4FA3DAB563 +:10BF800063EF567F941DBB42F93E0AF508B99EFC4B +:10BF9000FDDF26D03C94CBE427AAD8BF32A1BD3820 +:10BFA0002FA31DBBD5DE2DEC7A154B0BDAB5771B15 +:10BFB000ED77E3330DFE0333A37B66D27EC7D4ACAB +:10BFC00068F4037C2BEE9F7474CE91F6EF8A0DD04B +:10BFD000491CEC57B32B1AFD5B173BD0AF1FCAE4CB +:10BFE000F2FFBCB0975FDCA1D2B9E7E28E48DA5726 +:10BFF0000B773C7814FD8E0BB728348D72D640F049 +:10C0000003B8327BA85CC338B6B8B6F36EF1F78CD0 +:10C0100046B952FAEBC84AA4B705758A672BCCA774 +:10C02000C5EE8A8E0F99CFA24CBE6F4A6D758308FC +:10C03000DE62FEF3335D4457B2DE82FA07C9BE0CFE +:10C04000F52E905EF44204E3F7539ADFC1799EDD4A +:10C05000D8DF8DFEC20575BB16925EB123C289760C +:10C060008533226E59F673AF18EFDE4CAEE79D159F +:10C07000FEA3B33BF93B00384FDC6767146E87962D +:10C08000ED6AC4BEA8C9E47A5606C2203E587F4174 +:10C090005D53540FA87F72DFFB943E20C659E068C1 +:10C0A000C841797C727704F9BF4EEE7E7CCC6B3050 +:10C0B000DEF9BA119D705FC8FE1FCFB4707C6C545E +:10C0C0000B105ECCCFE366CA11BEFD43E719B7C9BA +:10C0D000971ABAFF78FCD0D9DD2F4599B282F82C97 +:10C0E000B757DA934CB88F167991BEA39178A07F99 +:10C0F000EBEE893E946115F5B90CE99AF65F12D51D +:10C100005F630AA967B3B829CED4B2AFD0C3EF99A1 +:10C11000887B51228E3F5FCD22BFE2AC7EAE69B7F5 +:10C12000219F7CCB42F858DCDB350DF9D3A5069571 +:10C13000E13C17A7B200EA274BEE89DC84724CCEB3 +:10C140007B567FCE0FCAD628CC03EB2BF3AB4C83A8 +:10C15000B40BE0DF87F494D83810E3249B52B95E27 +:10C1600021E3471F2B3679AC20075FCF8C157C5617 +:10C170007B742EFACF2665D279EE8495F954B42BD0 +:10C18000BDC8E34BCBD2785CF363221EBE2C369045 +:10C190001107FD9D13F82D9B14C8C0B88BB21793DF +:10C1A00028EEE29C95FB3DF13BFA59CBF2A0BD8312 +:10C1B000DED9D064FB98107A2A2B72BBB09E1AEBA2 +:10C1C00076E53A70BECE0BA4E7EE8964A8E79A5EE6 +:10C1D0008EE47153CF846DB685E0EDE34CAE47CB72 +:10C1E000F73BD8AD3CCEE8610B8F4B7D786B92DF8F +:10C1F0001F02AF872DDA0C8403AE03F5FB05D6DAF8 +:10C200000CD47FE57C1744D5D23CCF097A5F105E11 +:10C21000CBE3B9C57D60AC8FF9261187DEFCAC8D10 +:10C22000E280CE2435ECC5F1CF3CDB9BE1FA9B529A +:10C23000FDF3F65139E89780CF92E76C015CCFE9C6 +:10C2400067B93DFAB485EB6BA72726BA10BF0593F3 +:10C2500036CC227BCD169B8276BED30AB32662F9FA +:10C26000D6788A3F2FA9AEA2F8ED12601B787F081E +:10C27000D202BC07747A6B6F8A373B8DEF3628F495 +:10C280007D0D7ED758EDAC9F203CB6F3F3D599E7F2 +:10C29000FEDE3B34DE5BA6255BF4F175924E64F95D +:10C2A000DF047FFB9BD8E7FFC8E4F688F288BA87F3 +:10C2B000D3689D1CEE8027FE8E0D6B8C7C7C00C6A7 +:10C2C00053F454908F3CC602198FA3DD613B3F7F2E +:10C2D0009DD961A1B8F59297233D14C7B6FA1A13F8 +:10C2E000C553A85C4F2F3101F820557EB69DE2CB97 +:10C2F0003A3D17966723FD9CD139B779AB2AC661C1 +:10C300000CEF539EDEC6E38EC7A12E49E5D9547EBD +:10C310005AE44FEFCD26BD0FFAF7E0FDAA929FFC3D +:10C3200094C37172F171AE77D989DF96B5FA7986C7 +:10C3300046A31C2C5F3D241AEF2BB27755867A8BCF +:10C34000114E97CCEECEC867C7F7E6FCAC74EF137E +:10C35000E49F2A15F7084A9F53B81F1AF621DEE713 +:10C360002C5D35E411A2CF772CAC27ACE75CDD83E4 +:10C3700051A1F8B8A637E773ADF5AD6EAA5F0AF51F +:10C38000B19FD2556F45D17CB659285EC588C71F6D +:10C39000DDFE39F547B56FA58F3A6E6769B37ED676 +:10C3A000F01F9F42FFDFEC0873FBE86B1DDD833B52 +:10C3B0006BA99B87EB3FFB7C18F1ADB3319C3F9C95 +:10C3C000047EEAEB85F318FB4B8AEFFADD64BABF13 +:10C3D00037DFAFEF578E3BB437E7E3E571EE688C9C +:10C3E000172C7F97F341C0CBCDD4FE5D0BB537AE94 +:10C3F0002359B46BDD9FCF47103D9CEDC2F172769F +:10C40000672F924F4D319CCE61BE2978DFEFECF360 +:10C41000BD72E91E1D2A3D400F25E2FC7B36A62E8B +:10C42000C51952DE6411E7B800D444BAC136C0DF82 +:10C430004BAAB8BE556A5F4BF12518AF3B288FD287 +:10C44000802DB66DDC2DD02B9D2F1FEC2DEC983858 +:10C450005E828813273DA8CE8A7C5B13FA62D90ED0 +:10C4600063DC2E2F5F2CDBC36C3BC93861A4439F78 +:10C4700042712AA52B162DA0F8FBCA75B7E13E9391 +:10C48000F32F35B3023CA735292ACDA3298CDD3102 +:10C4900009F5CAD07142F4B97B83E3306702E9B190 +:10C4A000A4F42FEBEDA2EF98AFC57BAD2B94B53480 +:10C4B0004EAA3CEFF27549380138AC1827D83442FF +:10C4C0009477B06E394FE3BA5BF5AEDE9CEF37A5DB +:10C4D000BA7E3914F1FCB64AF77F2F7DDF3F3AB6BA +:10C4E0001D3D2D28E7ADC1785998FFE6DE8CFA99FD +:10C4F000D79BF3B5528CC78579666CD4C78B676EB2 +:10C50000D1E7FBECD0E7B376EBF339F5FABCFB8867 +:10C510003E7FBF1817CFE178DF18CFE198E239DC12 +:10C5200065E3E770CCE3391C533C87E3773C8763D2 +:10C530001ECFE198C77338E625BCF13C8E793C8F5D +:10C5400063F9FBBD39DF2E13F1968807A477F64A0D +:10C5500098EE3ED2C5FDFC7E09D001DF3733ACB486 +:10C560006F1EC31A741EE176A72E93ED2E8C1F5EEC +:10C570001BA7EDEF1D8FF7501A562521DECC8D1429 +:10C58000C75AF12A8F632DCB0B73A0FDA371E5C9A8 +:10C5900055181EAAC56987B0FE454BF336846F79DE +:10C5A000D561BAAFDFB8CCF5EEF51C7F648761C505 +:10C5B000B1A44715A29C8BED188FC67872B6561F92 +:10C5C0003F6E8C2737C6911BE940EA7F4F599A93FB +:10C5D00090AF7FF1AC7D2DCEFF8B30711F66BADD41 +:10C5E000100FE0207EB2F8016533CAEB2F7A733D5D +:10C5F000AAE518E8EBEDC85999CEBEDC9FF4F2D657 +:10C60000FC5AC544F1E99A87E4D01231A714A5B9C0 +:10C610006935F2B90526929B97405F237DF003951B +:10C62000F4077C572B743DF8AE56287DE1BB5AFACF +:10C63000FB125D74F5F15D2DFD7D893EFAF8FC2954 +:10C64000CB0EE2B97FF2DAFEBA7A73BC430C7014F7 +:10C65000F316FAEC1C901F1ED42F976E4841FC2E47 +:10C6600059D0D2B41AF0BB644F981BCB8BF1FF802A +:10C670002F16439F78EFB278B7B8BF5CA597C3B3C6 +:10C68000851C2A36339F33364887C54EE68981F6A6 +:10C690000BFA34E4E0FB590BDE7C7F90330DCF19AD +:10C6A000233A233F4AB17828AEB66C57CF9865D06D +:10C6B000EF373DB4D83E80972F6B0FFF6226CAC379 +:10C6C0005DFCFCF7C5DA97A228BE4CD05B8AC51981 +:10C6D0008E78DF54CBE3EBD07EA6C606E962536DBD +:10C6E0005C780F4770BD413AF89EF004F8E1769E01 +:10C6F000E243E41769A913EB1DA1F850CF96EB9321 +:10C70000EF6EB115BC9F3B45FE4B71DE90EB3CD705 +:10C71000FB608E0BEF7554EF4B51919F9B766CC372 +:10C7200073C83F6C5A769F788C07EDF9077C87AD0C +:10C73000E443BE9E3FAF1F15752DEA9FCF5BDCE340 +:10C7400020BFBAF6692B9E2B4ACC7E2BC5673EBB19 +:10C75000C98AF1CA376CDF44DFE76D2FA478CCF9C2 +:10C76000AC92CEA3A7E43B09021EC523958D4E983B +:10C77000F7837D389F2D0EE7FE3DD08F5EC7774A49 +:10C780002E6D577231CE678A7797B510BE8FE9C389 +:10C79000F98C719FB41C9F9C1F4FF0E0F7403E64E2 +:10C7A00070BA4F6FBB2F265F4EA57D31E5725F3AA1 +:10C7B000A74D0DF4E6E7E12CC379F8B8CAED79F599 +:10C7C0007C1F145B039D26E33E3960213DB7DCCC22 +:10C7D000DF792A877F5F07A977A8AAA3D78AD11113 +:10C7E0003A7A9ECE6275F7696EC1A09290FC947100 +:10C7F000E9BAFAD3A6F435D07F5EB09CF8C875BA12 +:10C800007B7FE54B7D2E85F4CC91FAEF8CC71732F8 +:10C810007693AE7D399B14AC87F4BD45E1E79EDD90 +:10C82000319BD10E586CE2E7A7E91AFFBE701FFFDB +:10C83000CEA633DD3EEC9EEEFE03978B16F21B4830 +:10C840007BFB74FC773BF0672CBCF51E3BDEE347BB +:10C85000FB84EE7EB7F017E2BC110FE5C29E549E3A +:10C86000C9ED49E5BE062BBE9300F037C7C5523D62 +:10C870007B1CC655D62A646FC47429C559EAE3B433 +:10C88000B03F8C7F5C784C2DC47D622C2FC6778A9C +:10C8900010BFAFF2B8D48568178A6AFB3EDA42B49B +:10C8A00013A17DCBF01EDA877D5CC26FE75FD505F3 +:10C8B000E1384EC9A57B9B3B0E5A313E6FCA949816 +:10C8C0005CDC3F463A93FC1DF635C515B61C3F4C63 +:10C8D00074D6526C263ABE123C167AB89DD5487F63 +:10C8E000F3588315EFA7CCDBADB8F15C8AF5102EB9 +:10C8F0005D902E0D70898B6D0B0F09A756B819CA64 +:10C90000E7330EAFF9FB143FF2C7367012F033CEA7 +:10C91000BF23F8C975CDD3B431C827E4FAE6E33AAA +:10C92000701C58078E23FD166CB071BFA693FD6A6C +:10C93000A197C7D91AE963D2656E97B9E5B299D2C2 +:10C9400029E3F4FB13DBE13E997A3981CAAF967E85 +:10C9500016C23C512E5C2DDDC8F5487E1CDC27FC40 +:10C960005EC295DE3932DA279BFA88FB1003D94084 +:10C970005D7CB3E0B7C6F6C6F866A91F18E54E6140 +:10C98000A489E22D5B1C69A47748FEAB09B9A2AD6E +:10C99000FC96EA69508FCFC6A393439AB0132E8EAC +:10C9A0004CA377245296C52520BE0AC39C14D75F9A +:10C9B000B84CA538EA42A8E70AD15B56AD484F41CA +:10C9C00039F2F97DBD9EF4813EFFF93D9D1206C30B +:10C9D000385FACB474B2BB82F53E5F999F82F11DA3 +:10C9E0005FACB34DF7B703AF88BEE23ED3CF3E2274 +:10C9F0003977DE743C6A3AB42F5BB9270AAF0F94DB +:10CA0000AEE4F2FDE11E5A78DF8128E7376D73222C +:10CA1000FC9C9B72D04E9C8436DFF8A05E51B232F3 +:10CA2000BF33EA1D65FF38FCA413EF852FB324A0A4 +:10CA30005E7AFA0390930AC939D2274E854117E4EA +:10CA4000878BA4F7CF4E29CC83FEA873A6837F598A +:10CA50008DE7C5DCBA8C8082CE532DA92FDA5557CD +:10CA60003E4DFA4CC9FDCB32F01D426D59CFE8F670 +:10CA7000EC2932DD26E439EAF598A25E8FF135A87B +:10CA8000D7631EF57A4C51AFC7EF151BF47A619A44 +:10CA9000F06F49BB73F79AE65CF4FBF946B2CC4AF7 +:10CAA00092C30E7A17788912EE46FEB4047528CC2C +:10CAB0007F16417607F6C18D3A3CCB7783E5BBC044 +:10CAC000C39A41570BD927D75FB6B3D07BBA235847 +:10CAD0008C2E3FCA9EA4AB9FEF4CD595DF90D85BC0 +:10CAE000577EA32B57971F9B79ADAEFE78F7085D55 +:10CAF000FEE6C137EAEA4FF44CD4E52717CCD0D58F +:10CB00009FEA2DD4954F9BBE40573E435BA4CBDF9D +:10CB1000567C8FAEFEED95CB74E5F29DE47A3C8FAA +:10CB2000D9F0FD173BA5F2BDE4BB5546EFB10D1D95 +:10CB300065E276461B97474BDEEEE908A583D97D73 +:10CB4000B91E7430CB330BE955BE8729DFB95CD4ED +:10CB500097E3359905147E1E6E48423A36D63396D1 +:10CB60000F8D3874C905B8FCA4EFDB53CDC02F86F8 +:10CB70005E73A87F3AE4D3B2E26EA1FC90432FA586 +:10CB800039F15C3AE31633F0ABA1FD0E5DC2F2DD84 +:10CB900059893C3F99916A3268C7BEA9182F3BF466 +:10CBA000FAB4B56E6E4769F7BEBB4C111E784F1CC8 +:10CBB000E1816900E818D34340C7981E013A9E639B +:10CBC00061EC28D031A6C7E07C8ADF7F0BE7534CAD +:10CBD0008FC3F914D377E05C8A69039C4B31FD5D08 +:10CBE000F5744A3FA8D6A8DDEFAB8B29FDA8BA9211 +:10CBF000BE7F525D45E91FAB7DF4FD81BE8A90E3A7 +:10CC000001DD7BA31DBD2B2AFD9CD2AF5953C91A50 +:10CC100023906F349A63BEB207FD951DDB09CCECFF +:10CC2000AB107D2D5BF16CE84BE37775121F17DFBE +:10CC30005DA9DA1388E70F5327F7ECAFA21CAB7C92 +:10CC40001D436D3E34B5FF7EE422411FEBB33C9B98 +:10CC5000B1DD303BBF9F3CCCCEEF1F0F3337D4202C +:10CC60007DD57CC75C18FF733092BFFB51739FD991 +:10CC70008F7650E532DFE7C33B31CAD77CD748F720 +:10CC8000958739DD8928AF64BED5EF8F7F42E27C7E +:10CC9000A41F5EC6F78CBEDC300AF585E10EAB0B37 +:10CCA000F94868DC00FADB0F467E25E7C3703CE9F3 +:10CCB000DFDFF21D0B9872827EFC61F68654B41B96 +:10CCC0000CBFD3EE0E8D5B92FE7AE572A38A765589 +:10CCD000199F24C791F38D34437F79C1F8A361CEA6 +:10CCE000BA5CF477D4943BA8BFCEF0DD9A47F53C0C +:10CCF0002AB5ABCB45BBDCF03207C5C1CA3881CE03 +:10CD000062DD508FD639FAB2467112C3459C04F6E3 +:10CD100063E7E53EEC6778A74012C6810DAFE4EF0C +:10CD2000903DA1F0F7E865DC02D68F08D9B7384FFF +:10CD3000ECB7C7DF60BEA847793C04DFC9F25CE707 +:10CD40001279E977B48F24FBD628C16B1E4ED5BE6D +:10CD5000403AF2DA9C9F45D0FE4EEF8676D3894268 +:10CD6000AFFF27F4720ADBFDF7E9C5C3F1DD95914A +:10CD7000BDCD4837122F12CF1DD191C47B489C19CD +:10CD8000E1B9356E4CF463A4AF8EE84AD2D3303BA0 +:10CD9000C73BE215E3D4241D2997F9BB6EC3CBEC46 +:10CDA00024EF241D19E9A02D1D71BAACB9CB4EFD9D +:10CDB000B5A5A320FE111EFF3A1D35AAE8BFBA5A39 +:10CDC000FAB9A3998D8986A26969DA22C46FE165EF +:10CDD000D751CCCF6623C62049C9720DCB07B62DDB +:10CDE000D7BE69B64487D0D9304167AB3BA82FEB9B +:10CDF000C9772F64FFCF7430FE5B426F782B4CC62F +:10CE0000A9781CB9838271A34BF2397D15A4AAA419 +:10CE1000778CCAE2EF9F3307D7B35DF017F9F14D76 +:10CE20004C3B129D8AEF947AE97DD2319D0CEF93B1 +:10CE30000AFDBCC0E0E7BF29EB06D2CF6FBAC23B08 +:10CE4000D7E3B3847E9DCA52AFF21DD2295964D76D +:10CE5000FEB1EF90F2F76B478BFD9E2CE829DDA524 +:10CE6000B2A1B1F89EBB6646E17204DFAFCDC177D7 +:10CE70005E7D94BF91F9291DCB02A4478C074184A4 +:10CE8000F99B19A37BFB872326CCC43B87A3FA8F8E +:10CE9000EA81DF43DED95B90154FEFECFDC919F253 +:10CEA000CEDEA1D12EBABF7AC89E4E7A28EE574B5D +:10CEB00088BDF44D90CF3D607D87417E63FA3AC8CE +:10CEC000EF1E2047DF00F98DF99B3297316C37C692 +:10CED000A58F7B92EDC73A47C141AD63F88DCD79FF +:10CEE000A52BC2F7AD985EA3912EDE8AB96634AE4B +:10CEF000F7AD98CE269EDAAC9466BFDCA33D3D59D3 +:10CF0000EE87E07863683C237C253C8D7094F0FDCF +:10CF100017E0F9607BF05C84E708B4DFDADF8F4A62 +:10CF20004C43FF26E7B3E51129E23DD2B773D43471 +:10CF30008CF71D42F31C5E752D33A3BFDDCEE1746B +:10CF4000B29AF910BEA7710968F036D8F79879A49B +:10CF500029340EFA659BB615E9EEE44695EEEB9F93 +:10CF60007F318CEC76A7FCDC2EB9D8A43D87E56533 +:10CF7000AA6BAD1BF5CDB754FE8EE8F78753264557 +:10CF80005E05BD6EE1EF1C94D9C7B48B4F79BEAC82 +:10CF90004CF310BF6086DFA3E86AE3EF41C877294E +:10CFA0003BD2B7E4EFB874B5717E2DF1BBD12AF452 +:10CFB00000E86710F0D9E45F86D379EBB104CF21A4 +:10CFC0005C1F9C63E8FDA996AE91249F0E89B8B8BA +:10CFD000E181BEF4DE5A81F8DD8137C47BEE8744FF +:10CFE000BCDC910CED6D6CFF86EB5057B43F5CCF11 +:10CFF000B81FE846077F3FFF6ACFE71F6689F8A1A1 +:10D000001C967355BF9310AFD27D8AE12C83FCF040 +:10D01000A370BEC8E7DE9C6D463919F23B09B4AE79 +:10D02000FF6BBF93C058B38AEB4A762AECB1D4ABFE +:10D03000FFDD04559CABE4EF2714F0A236BF9BF054 +:10D040007854018FCB77CC6BF7771392C5BBD6CCD6 +:10D05000C5E586FCDD84FC44BD1C19E51C71C44992 +:10D06000A9DECE937C85F8B1F86C213FAE16FFE5C2 +:10D070008CF0DF1A67DA89C73F0DD7FAFC12EDF39F +:10D08000A33A59DC7E575B3AF877FB5D948EF064E7 +:10D09000FCBD14239E8CBF9F92AC9699E91D4881DC +:10D0A000A7E9F017F174BDF87D8BD1F8FB16EC7F82 +:10D0B0000E6FE30C78FB96AD1D88EF965E2CE47C3A +:10D0C000BD23B91F9EEA99940DFC6396B01F49FBDE +:10D0D000888CCB35FE7E92B403C8785DDF488E6FB6 +:10D0E000DF8908F25FDDAD3646A29C3961E2BF9769 +:10D0F0009411AF69D8FF1D59950AC223917977CD54 +:10D1000083F9CFFA8D2D05F3B3BAF3F7225916FF41 +:10D11000BD2039BF59C93C9EAB385BF06F378FDFFC +:10D120002ACDE676B248B793E2CC0BB398889F65D8 +:10D1300029B3B2913E8F87F542FA5BCFED818DF82E +:10D140005E65A7E07B95A8A7A35EDC4DE8A5351F2B +:10D15000DBED9C0E994EFEF7F6DB7571CE7DB73B8D +:10D1600075F9ECBA445DFD7EFB5CBAF2DC40A6AE1C +:10D17000BCFF31B72E3FB061B0AEFE351F7974F9F8 +:10D180006B1B0B74F5879CF2EAF2C9ACF95184EF82 +:10D19000E6EC34C25B7745D8495C1C1FB3EE4EA069 +:10D1A000FB4AF2FC21E3DE3541CFC6734D772BD726 +:10D1B000EB6B92183FB7DAC5F994E9CF379A885BE1 +:10D1C000977A3DF3E9E3D665BC7AEB39489C73E482 +:10D1D0007922245EDD83F397F1EAAD7817EF871AA1 +:10D1E000E9F5856CE15733ACA3BB95DFAFABB9C7AD +:10D1F0004AF784E4FC8CF33A2EE298B7DADB7F0F2F +:10D200006A7F36B7AB44F6F0EE417A7D12D815C18D +:10D21000B3CD78EE46FCFD819A7BADEEE5AE2B8F6B +:10D2200037AB1F5FCF4C7C37378BDE5FA57B8172BE +:10D23000DCB7057DEFE9A7B4BBBE59D13C3E8E45B6 +:10D240005BE95E4BC7E371B8265AD90A7AB74ADC64 +:10D25000F3B87D6DDD035834D35A6BE10F0FF82D11 +:10D2600068471B3712F4C45CC0C3334B1E72805E28 +:10D27000F4649599EC621F3C7FEE16D0305BEFEDC5 +:10D280007487731AD2C938C43FF47B533F1E9FFE84 +:10D290006D365F5FBEFA7DEB7D0B9B8EFF33E2FF49 +:10D2A000EDD01DD1A35CC7FFD6FD0B49BF4638C9E1 +:10D2B00073391372AD879897849FDC17127EF2FE44 +:10D2C0008B6B91C5BBD941F7680A302E4FE2EFF660 +:10D2D0007E9C2E7BE57078603DE4471DD5CB57B32F +:10D2E000A2D15FD0C25CD1CE2BD8CDFF97EEA510D6 +:10D2F000FC3BBA4FD7119F68C31F3AB85FD7117D67 +:10D30000D29FABB86717C22778BC94C087BF878904 +:10D31000E2125647EAF7F1B41C2E17FE2EE5850FF0 +:10D32000CEE77A3EC1D0FF51B352157C625EEBEF7F +:10D330008DE0F7B92B2DA47733E67D18E334FEBCDE +:10D34000DE42EF3C0EF730D26F8A362AFE4D4AF0AD +:10D3500077BE0A7D86775AD4EF493FFC76ADE2C4AA +:10D36000DF8B98BD465F3EDFC17FA764AEF1BD1A7B +:10D37000E98FBBC2B9BE2047E8E56EE626BD4CC4C6 +:10D3800051148B3A46BDACC5CFFD8D782E57B91DD3 +:10D390008BE2EFA4DC77A1BF2BE41D16806B78260F +:10D3A000CAF115E676E3225BE1DA41DCC73987880A +:10D3B000FB70F0389796DD61DC3F2CFD70A2FE39E2 +:10D3C000DF252AC7FAD8DBF95C1EBF22FD6F46FFB6 +:10D3D0005E8BC344FEA996DD9114E7807EAF68A002 +:10D3E0008733A65D09835383F3D31A559DDFC8980D +:10D3F0006ACBF6D079F2E11EDAE21C8C6F37BBED16 +:10D400006EC8DFE73844EF788D137630E37C5B7FBE +:10D41000F76F287F57A7C5C7F5DD9602FEDE09F036 +:10D420004786FB49C6734C64A0DD415A18B896E69E +:10D4300073B5FEAFC99773B9FFF7F2106AAFADB914 +:10D4400096F2DD573CB008EF194DAD996FC1508091 +:10D45000C64797E68743D3C66EFEE5E188B7114A13 +:10D46000BBFE8B0773B85C6934DC5B90A9DA8FEF85 +:10D470001B573FC9CF453CD73285F6C36285C9F8F3 +:10D480002EE2E7327FA956E4F3797EC94A9E6F14F3 +:10D49000BFABB04DD85B70DD98E2BAD12EB043D8A7 +:10D4A0006370DD98E2BAF13BF22FCC23FFC23CF26D +:10D4B0002FCC23FFC214F9177E2F62DE945C95FBFC +:10D4C000ED4687EC0FF4DB8D0ED18FD06F179A47A6 +:10D4D000BF5D687DF4DB8596A3DF2EB41CFD76A1CD +:10D4E00079F4DB85D647BF5D689E0DBE3198477ED7 +:10D4F000E799A8CB4F06FD7F74C8FE46BF5D68FF65 +:10D50000E8B7D3F5A72DD2B5BF8D55E9DAA3DF2E45 +:10D51000B4FE1D558ACEAF7787788776F68638A217 +:10D520001F5FAAB701E9FE4F11FFB8CB82E745B5EF +:10D530007E013FB785BB399E6B0B38DE4DFC9E8567 +:10D54000D23C83F0BCD4CAF3F93CCEDB483FE817A9 +:10D550001B6DE17E314CD12F8629FAC53045BFD8ED +:10D56000E89EDC2F8629FAC5F03BFAC53045BF1886 +:10D57000A6E817C314FD6298A25F0C53F48B613BBD +:10D58000F48B618A7E31FC8E7E314CD12F86DF4F49 +:10D59000A07FCE129C17EAF33D74E74AA043DDB9A1 +:10D5A000D2A9CBA33E1F5A1FF5F9D072D4E743CBC3 +:10D5B000519F0FCDA33E1F5A1FF5F9D07C748E8B5F +:10D5C000F621EAF5A1ED50AF0FCD67D7FA5E47DB44 +:10D5D000D9F88D178E60DA18A93CA900CB8879613B +:10D5E000C534F45F3686292931C0392DCAFDD346AA +:10D5F0002701998838CA1CD66CA2DFEBC3C323C6A7 +:10D60000390418C5AD667F9744E569F2FE1DFE0139 +:10D61000BCE7EE66F47B34D2BF2EDBBB9953C55416 +:10D62000D60FE6DBAF671C5FD623FE19320FBC694D +:10D630008DF13EB94B1D791837BB4DFC5EEEB6E55A +:10D640003CDEDA4857F9425FDA66DA7508EFD33420 +:10D65000172A74EF3AC3CC8E59F2104E9579A84729 +:10D6600064F78B11EBAABC0E7F774CCE5BDA41815D +:10D670004FD0FDC4A1CD0DA3A2A11FCD37827E1F27 +:10D68000679C95EB0FD80ECF957D7D8A6773087DDB +:10D690005F23F471CDC7C77FE6A909BC5D386FF77A +:10D6A000CC535104C7092B148A3B1BBA8379F01E53 +:10D6B000B447CCBBEF8E808AE315AEE0E3C97E0BA6 +:10D6C00037A6D0BDD042D6381AEFB5B0010A43BE56 +:10D6D0002DE106EB3B82EBCB80AD8276EC1F7B9F8E +:10D6E0006AD880987C8C4764F58CDE151D3FE03D40 +:10D6F000DD7A09ED83A85F926BBD7C0ABDE33CC176 +:10D70000B76C39826FBC6FD1EBF1587F0B73A7BA3E +:10D710004814D1FD63399F3E9E5D26108B2C8B35BE +:10D7200098C214C4373B1C17423FB0F3A720BE7306 +:10D73000DD167A5779A2D969A1773A3A88D7B9E440 +:10D7400090F13A067DC1109753B3F4A314B4372F68 +:10D750008E3491DD64F19E08D21BB40D0AF135A917 +:10D7600007158A78BF4B2B5E8F9F8670DF65A1FE01 +:10D7700064BC4E79BA3FC584F713BA6CCA8955495F +:10D780000F58D20FF500DF4BB70CC67A2BF9BBA2AE +:10D790009756ECE1BF4B2AFC3BF2774EE788F8AF97 +:10D7A000C26C6F34C6C3C8DF5393F764E4EF984A82 +:10D7B0003B4FE1DBFD8F227E0B9F10EF7EAF29A454 +:10D7C000FBEFC6B8AB52A1FF2D5861A1B8AD05065D +:10D7D000FDB054C4655DE9F74DD7F633E887F277BD +:10D7E00072441DA676FD3DDA85E5BDCF9916CE07BC +:10D7F00066EE62E4AF9AB96C9409DFAB667B38FDE4 +:10D80000CC5CC6F59C99AF78E8FEA6D41BDF15FA70 +:10D81000CCA4CBC904FFF785FE3215E35501CEE356 +:10D820001AC3441C5B12A5D32EF3F8D5490ECE0FB4 +:10D830001AF7F377375A7C36AE571D61FCDD380393 +:10D840007D4E34FB4D78A1D13D14E813F2E3511F16 +:10D8500082FEA6A37E1487F49E9A4FF190050ADDFE +:10D860002332D2FB384BE5EB186F3B6E2B73FB5822 +:10D8700028BD031D637F3E85DE63D0C43957D2B116 +:10D8800091EE674508FB9483DB9F5AED14A8ABD259 +:10D8900023EA7F9A86F1C4B3D066D88596E1C1B8F1 +:10D8A000BDC82C5E7EB4DF9FA6ADC0BB1F1DD82DAA +:10D8B000D49F58091E9A7C77A2033B02DA0F905F2F +:10D8C000DE7E67AEB528845F3E9C3BF22BF7C0201E +:10D8D000BE8B0CF72917DFD7937EFFA823BD7836C0 +:10D8E000C015F7C7ACE8C6BB8052D99FFB31CFE863 +:10D8F000C1F8FB92727D2C80F198B78A7C6C9DED0B +:10D90000A3350E820BE59BFA9D9F867134E5F6C622 +:10D9100031487615599505189F1DE4539A273915F6 +:10D92000F9546E007F8FEFB8944306FB44AC9BD74D +:10D9300037DA29666771FECDC47BE39FDFF7F24ECD +:10D94000945B72FE9F5BF4F76A651AEE16F2A3FA17 +:10D950007FE65E89F13EC9AF92B5BFF783FE1F3601 +:10D96000F1F713BAA8B54CD88BC8AF2CF90613EF52 +:10D970008E04F1EEA1F78DFF0B290E70D50080000B +:10D98000000000001F8B080000000000000BED7D70 +:10D990000B7854D5B5F03E73E69564122621210F1D +:10D9A00048980402A94698BC20BC0F9147B068076C +:10D9B00092286812268447B068236A0D2D2D139291 +:10D9C0006040F0068D82D4C780CA45A51A955B4198 +:10D9D000693B48B56A513148F5D6DE303C7DB535F6 +:10D9E000E2F5AAFFE76DEF5A6BEF9D99733213F0E2 +:10D9F000D1FFEF7FBF8E9FDF669FBDCF7EACBDDEC8 +:10DA00006BED93960D8A735D36635E87F5849200A5 +:10DA100065BB12B08D618CF9666AC13C46BFBFE53B +:10DA2000307678B48BB114A8E4F5DEF3703263B5C8 +:10DA30006BAD6C233C7A6014D318D41FF891D5EFEA +:10DA40008371AAAD475EB04399E4E6FDDF69BAC3CE +:10DA5000C24C384A20D705FDAE6E8C716F84F6BB80 +:10DA60000B3C896E688FCB775BBD0EC6CEBA19F5BD +:10DA70009F91E249C6E7D76D3A78FF5BF0E8070768 +:10DA8000B2ADDE7CC6EAF615AC4F73E17BDE74778F +:10DA900009D41D4EAB07DEBBBE35D1EA82B2369546 +:10DAA0003576E5E33CBD59F3E361CDF89BC658817B +:10DAB0005B610CFA7F50C0A8FCC8C216F07E1D96B0 +:10DAC00079BA7E266A671D5B35FB108003DF3ACB8F +:10DAD00034339FA990B1E1562FD360FD2DE9CC8D51 +:10DAE000F01A0ACF6D85BC3D2629043F23DCAC8C9F +:10DAF0006926681F0AA5B53004C74C6857E1B925E7 +:10DB0000EFE442968370638B703F723DB25C2CD61B +:10DB1000CF16D84D0CD6B5D40EFF862166AAF9B320 +:10DB2000528B195BB54571DAE0D11287EBAA095027 +:10DB30005FF29285AD83FADC2497351DEABD70BE95 +:10DB40003BA1BEF8A602AB0BF65D8D6701EB58B2A8 +:10DB50006D02730D86D20F6551FF796579CD9643BD +:10DB600099FB5D787C9AD503F05AE2D4AC49F9A1CF +:10DB7000F6FA0E45F33BFAD7E7BB55DA67351C29B1 +:10DB8000C2AFE6A66CEB6207D65FB2ACCAC77DB97E +:10DB9000685FF23DE817C07E7373D88B0CD70DFB1E +:10DBA000DA99CDE72B0C1B7F318E1F363FF45FE4F3 +:10DBB000C17DB9E369BE3A27EC3B1B4B27AD13E0AF +:10DBC0004070EADD0CE3B9681E3A8FFA80DFE2C6E6 +:10DBD000F598615EA85FEDF45B709EC5AD055606D5 +:10DBE000A577139FC7DB9E68BD04EA7566A735134A +:10DBF000E789055824D3FAFC3BE16896005C921C47 +:10DC0000380F5B34DFD11F3E7562BD4B3A12AD4B0E +:10DC100075CFB758F03C16C27ABA229CFBED78EE6D +:10DC200029B89EE95686EF9B35AB1BD723E07BE6F0 +:10DC300086988D6C10BCDFB9D5920DF59F22FEA69B +:10DC4000E07B1CBFE6E6047215DCF70D316E5CE785 +:10DC5000426707EDAF0FBE77013CE0F952A787E0BE +:10DC60000B78E1630087259DFAF30CAD87C37749F4 +:10DC7000671DD1DB32B3D7EA0C5FC7B683B90AC0E0 +:10DC80006521D0B702F0674E6F16E2CBD9BBAECAA2 +:10DC9000A27DC23A11AEF16ED7ACB462C213C263B8 +:10DCA000892FB5459C7EE57CBBDC669A6F97D8577B +:10DCB00074BAD45E4C43BA84F35DE78A4E97560635 +:10DCC000E3C1BCD6258ABF45E94FA7923E255D4AF0 +:10DCD0003A95F47BBFC5134853427CA676106B7C03 +:10DCE0002A029CCE0A3E72B5385780EB6F10AEB256 +:10DCF000FD7571AED5397A7AC7F170DCE7647B596E +:10DD000020F786FC507F396F75127F0FF11EF1ED01 +:10DD100039011FECBF8AFA0B78097E51DFC72FF655 +:10DD2000B40D417EF1A4E2467EB16AF3A1CC5B0062 +:10DD30006EAB7E1E879C977DB8F2E1EBD3010ECCD3 +:10DD4000ECA77393EB5AFA7901F189659F4FE2FCD6 +:10DD50002210995FB8F2BC87916FCBFA923B7F3E5D +:10DD6000CACBF94D00F9CD1F7FFEDCB189C84798B9 +:10DD7000DFE2B924B49FC5ED6F58EA1CE1F0E3FC83 +:10DD80006E63DEB93A3CAF7A87D5A5C2A3FAD63A1C +:10DD9000E2BF2C8DB97395D0F91BF1A2AE55D1E835 +:10DDA000BDA6717EF55BE4D3F59BE6319453F2DCBE +:10DDB0006062C6C6C13E1987AF5CFF4762FDE704DB +:10DDC0007FBB5AE0F7D50DD3ADE9C9B8DFBA22E081 +:10DDD0008C6CA178BE7089FE79DFB939FBF8FC7ACA +:10DDE000A497735DFCDCCE6DB210FF39B727DECF90 +:10DDF000607F1FAE7AE6B52BA1DF0777EFC862AA76 +:10DE0000FEDC58113F372C97C3B9B1C111CF4D2D4E +:10DE100008E3C3CB1FE0E756FFF8ABFFF1AC8BF68E +:10DE2000CBF9DD669B1FF9F1E2AE27E91C17B66F4F +:10DE3000B16443BFC105D93A3E5EDF58E06400DFFC +:10DE4000ABDB7758904F0C2EE07034D203941A0B52 +:10DE5000A333944B4A12E25F301DF14FF647FEF8B0 +:10DE600024CC73D30D31096C6C689EC9059CCEEA35 +:10DE70001B139370BEFAC6BADBD998903C30EEF310 +:10DE8000540CA797C5301ED2EDA9E9EEAC55849F7E +:10DE9000A68872B7A8809FE3CF00DC31800F43E3F0 +:10DEA000BA1E41380CFD41AC1BF9C7C891413FCEA9 +:10DEB0008BF88DEBB602FFB443BF912B831FE33A7F +:10DEC000460286E17B58C62751C986407D272CBB78 +:10DED00014CA1C95970B0B389E407B00DB5972B01F +:10DEE00004F72FF1DB88BF56F6507B0EF2B164E6E3 +:10DEF0006E7185F0558E23F155E273B4FDCD2BE0A4 +:10DF00007CE57CFB3B95CDE1698D85FD257D85FD1F +:10DF100001B2962685F625D7C7F2605DA83FFEF8C8 +:10DF2000921D1B619E53CDEEAC46C740FBED9C3964 +:10DF300024C27E8DFB9474B3C4CE691AE866501077 +:10DF4000D67DAE63C420943BA714906FF0DEA91B6E +:10DF5000624CB87EB9AF5D6BA133AC75F75A3B9597 +:10DF60008FAE05C21BCDD89EB569547F7CAD8BCAE0 +:10DF7000AEB579F4FCE68224BE0F168C473D13F44F +:10DF800001CE0F029C4E7A9A46D0BEE473A917F4D4 +:10DF90003883F14961FCFB74A3909B2CB819E99B71 +:10DFA000358D600FC3543D1DA7E24DF9889F7C7DE0 +:10DFB000F2BD9B2CBDC40F59BCD5F530905CDC4D37 +:10DFC0006FCC4C85F99676661728F05E4D53514F0D +:10DFD00013B4D7B4A6BA916F2C75B8D6A35C5CEA1B +:10DFE000CB76A35C8CEB2C38BB0DDA97B65EECC617 +:10DFF000FE3729CC83F405FC9321DC96B1BE9F66E5 +:10E0000007BEB65CF0B5E5C82F015ECB9A0E8D74E5 +:10E01000C2FBCBDC310528DF976FE376C25C136B64 +:10E0200057500EB77866211FEBBD4771A3BEC9EEEE +:10E0300005FE6A0FF1577F9EA7A300E5D297807F68 +:10E0400030FE45288355DC579786FB60A08F3CCC7B +:10E0500070DD1ED2EB07097CE9E93C11EFCAE7F05D +:10E06000467D9D793513F2DD5542AE0DB7F69EB86B +:10E0700015F59978937B27E797AFBB709F2FABCCB3 +:10E0800046F246F417FC74F84F4BEDC8DF56C5E76F +:10E09000A4925EB54D25FE28F1A741AC79E98E8AA0 +:10E0A0002188374BA11DE5DD767C082C747DE7A522 +:10E0B0004310AF966C9979B70FE4589680E3697373 +:10E0C000701E9ECF7B3B52939A512FBCAE6514833A +:10E0D000F6253B6ECDC2F2BD1D310B90DFCF70CE69 +:10E0E0009B9108FB5D766F62811A26377E2DE8F1E1 +:10E0F000DAEB2E4D457B60E55F0FDDEF1C01F3038E +:10E10000AC11EE9F76C5F97DD065E5DA7D592AD050 +:10E11000D85F6DDE67916F7FDF74E0CA09C8FF15B5 +:10E12000FFAE74EAEF4A7546A0F73EF90AF8EE0230 +:10E130007CBEEEA76FD3387F361DBE6221BCBFF216 +:10E14000BAA713709CEFDF75749C139EDF3DD2FB62 +:10E15000229ED707CA8E5D4E144CDB768C41B9FDEA +:10E160005B6147CD4DF25CB910E1FEB24A708F366B +:10E170005FC33E85E02BEB35FE41A4CF7A03CCEAAA +:10E18000C4D2C9485F7E4F654DA80F48BD463EFFCB +:10E190008380CB7B833AB2102F56ECDA9A8572E5F6 +:10E1A000FD785EAFDE75D52BC8A7BC0FD9B8DE6E83 +:10E1B00066A427D7FBB8DECD1A805ED343F39F2E2B +:10E1C00088A3F5AFD856A4938780A1F4FC7D332BA8 +:10E1D000C7750C6FE92D40FDEB1D7360299EEB3B6D +:10E1E000A0D7A27DFB6B21CFDEE95067E1731F1042 +:10E1F00012EA23EF743C1D3FD211D2E3E28BBB0243 +:10E20000C8E7AEDB9B58A8729422FCBADE29F993CA +:10E2100063D6D064D2C79C88A7ABF6BF308BF13AE7 +:10E2200008C2E8F0BC56E8617DF5BD4F925DB7725B +:10E230000FD72756763DF962068C73FD3EA14F0835 +:10E240003DE53A41CFD7EFE570B96EEF096B7DB888 +:10E250003D9297B47E286882B6C2410BEE72A1BD92 +:10E260000D8B9808F8DD655AD80C4C3CCBEDE47A60 +:10E27000A5B997F4C38D79DD64975FD72AC6CBEB38 +:10E280005E9F43FB9D37385C1FB2175A08AEF27D84 +:10E290008007BDF7594CC218E47F81EB62DB51AEB9 +:10E2A0006BD73BCC58B65CE720397F6FA329CF0CE6 +:10E2B000F0D5945837EA714D76DEFF96D8849D5894 +:10E2C0001E88E5F5CF62B2484E7D66F23CB90CFA85 +:10E2D000DDA21E896123F0C87B0F99A03E2AC53BB1 +:10E2E000BC10E64F65403D2ACA8F8082ED1FFDF2CB +:10E2F000DD225CC7D4E1C14F182CCDA2242E9C0195 +:10E300007832BAD0C9F97B7EB008F13DE579CEAF5D +:10E31000EFB3B0769477CCEC61F3E17900F9179E16 +:10E32000FF17263FF2E3034AE0C170FDABBA90EB62 +:10E330000F1E9BA35D81752ECFF6BA711DDF532C86 +:10E3400097A0EAC25C6A2E8EFF9185B74B3DB64C12 +:10E3500030E14C618F5933D21CB8BF16012F45D321 +:10E360005813AC635DFEF3F5882FB7F5DA990DE627 +:10E370002FEB8D25BD3633A39CE45B8B808BE24A6B +:10E380004699C39ECF37F96CB0DEDB98DD8FFD99DF +:10E39000DDA0FF9A62347C4F39F0DB2F90DF0F5500 +:10E3A0003F3E3408FA0FBD4571B7409FDA7367EFFF +:10E3B0007B9DA1FDEC2F40F82D4DF15E5608E7D96D +:10E3C00073AEFC8417CEFB366797DD9DCFC70BDF9E +:10E3D000C781D55F24249942EBFBA8F7ECCF9F2996 +:10E3E000C6D24E72A8EC80CAFD4D86F57C94E6320A +:10E3F000D339F5DA0326ECEF30F91505FB1F7A1B4C +:10E40000D75766770454D4E3ED963F85CB1976242D +:10E4100033F1ECC5245AD8DF405918D2C2CF6FEA85 +:10E4200020BD7DF98342AE3FFE409C9384AF841BA8 +:10E4300073692C5CCEFCCAB1AB86FBB1381DFF40C2 +:10E440003C3FF7790EE917E70E809E1141EF94E506 +:10E4500051D433407F08E468B7149684E46C9594F3 +:10E46000BA420EAB62DC2A01AF2A8789C3A7D20069 +:10E470001F813746BC309EBB3C4FF6A3232F0CCAEE +:10E48000A673BCE45F189DDF3A5C47CF1787DB803B +:10E49000DC5886AA9DF066FF239E5F206634EA154D +:10E4A000779948AF40BD0FF544C93FBCC807C6D2F5 +:10E4B00073AE07E631E21BB56A2CF9198D7C43F285 +:10E4C0000B6F2C9463906F74103FB845ED7DC1A421 +:10E4D00084F8C4F0F2E02528877BC0F4C7F6A0A931 +:10E4E0008B9EBF549843F8328C1D49C7E760AF94A8 +:10E4F000A01EA8DA1FBCEF348894CE0D9C3E5A2C87 +:10E50000FE7B96217FA872B851AFFBC86FF25960AD +:10E510009D9D899C6F74AEC82079FE11137C648127 +:10E5200095F8C82493C947F6D6C20CB2B7FAFAE7F1 +:10E53000BAC8BFFA8BBFAAA3B661FB3C3BC9DD4E8C +:10E5400094C750EFDC7C09B53F27F9D20ACE973A41 +:10E55000E769E9B1D83E6F8809E7DB9EEC7D1ECF05 +:10E560003D43F53F1283FAE4F763D9C3F0BC335B54 +:10E570004B47797BB7E259B814DFBF84AF3BB83063 +:10E58000F6F15DFC7802E84FEA698ADFB9314C3E6A +:10E590001D1ECDF9FA70DF897B105EBE329687FAB8 +:10E5A0007C0FE2E7D8D0798155CE9A9242E7966CFB +:10E5B000383789AF3E0B9C5F323FBF754AF4F34B4F +:10E5C00016E7A734017E13FFE7E7738BCAF93BFB1D +:10E5D0001518E0507E9CE20DE27E5B6E8073218117 +:10E5E00018BC19E175DFEA780DF7D163620D5D1192 +:10E5F000E8F643C11F184A63A08745821E1649BC2E +:10E600005D63C0DBE0B0C4B371026FE1FDE7E23CE3 +:10E610007FC679FFAC1C1D870F0FFFB7BA20D23C15 +:10E62000FF25F8CF41BBF7D34292AF653A7DF57035 +:10E63000C1BB9928A7D8978786A1DC7D2AD9F33951 +:10E640008E1B33B297FCE63DE9BD16DC67CFC20FE7 +:10E6500032512F5AD4F45BA2AF0B5DE7BAB85A0B14 +:10E660008E9358996D0942995A99FD02E2CFB139BA +:10E6700036972D821E7270CEE84CD47FBBAB4667B6 +:10E6800022DFEB86033C82EB33BBE291FFB17D35A9 +:10E69000C4C7AA041FEBAE1CC19F0BBE19F67C7346 +:10E6A00031EAB50E933B5C5F3096EF03DF0C00DF81 +:10E6B0007C17EC332CCF807D1600FDF514D86758FD +:10E6C0003F01F61996C7C13EC3B27BAD9BDA5B2A08 +:10E6D00047EC0BC2397FDAAED0F8E8BF8DA4175FE4 +:10E6E000FB90CA02123EF07FC3BD712C9017AA2F77 +:10E6F000EB1CACAB2FD93454575FDC3A4257977AB6 +:10E70000A477CDC5BA712BCA8B74FDD6C58DB1E087 +:10E71000B926961770B8971710DCBB2F8F02F7CB6E +:10E72000C713DC8FCE199F89F03C8A7047FBCDEC74 +:10E730008EC77390709F2FE63C5A5EC49F0BB887BC +:10E740009E570C28A73E4478DB10EE762ADF4578EA +:10E7500013DC39BC4F21BC6D08F73C2A8F23BC4722 +:10E76000E3B800EFE2F3C37BE51E5507876B1FD2CA +:10E77000C3BBE1DEC106F80FD5C171C9A611BABA93 +:10E7800084F7E2563DBCBD6B8A0CFD18DB0470A813 +:10E79000C07F001D1C2D994D7129B39DF9E280AFFA +:10E7A0002422BDC1FACD950AD78FE0D70174381F56 +:10E7B000FF01F46576F0F6D6858A1FF912EA4468FF +:10E7C00057005C0371406715CE5167902F5D851C23 +:10E7D0004C45BBDE4FE5352C40F459C382545FC431 +:10E7E0007AB3AC505EAF06D6A3FFEE55BBF7C62298 +:10E7F000A0FBFF9AF3468F8244E9AE1B8D74CE1CBA +:10E8000049646F463B27E0945C1FC7AEE3C4BEE09B +:10E810005789FC1FDEEB8E1B73F3CD700E1FD505E1 +:10E82000C7E1FC2BEDDE07924D345F7311F2258BAF +:10E8300077F46078FE6AC9F84CA47FE649D1D949DB +:10E84000D1E6DB829B0538D495039C148CC371B848 +:10E850009CAEE27039B8C566457FC6E90D16F25721 +:10E860006E8DCBCA42BC3DDD363B0BF1AE79CBE8B9 +:10E870002CC4F7F9EDB3DF47FE3D539D5B8BEF9F53 +:10E88000ECE078CFD80DA477DD2CCEEEA48BB903C5 +:10E89000D05E3527DEED83FD787DD909B45EA639DB +:10E8A0000AA05FBDD8777DC7F2B9389EDCFFE24D84 +:10E8B00036DDF97FAF545FAF62D6109E65E3395BFA +:10E8C00043ED78FE6AF520EF007674D31F77BCF233 +:10E8D0009BB0F11E2B8A4F46BECAC6B3F17F53438D +:10E8E000EF4783EB676BFDAFFC26370457894FEB8F +:10E8F0008B3C7B111FE031C5DB8096481E5CDFE757 +:10E90000D73A9080F0DB12F7ABDB27215CDEE47EA8 +:10E910008EAD71B5C43F3E44BE9D8D7CFAAACC60DD +:10E92000185F90EF07053F3DF6F3AB888F1CAA4AAE +:10E93000A5784CF75EEE5F3E2EE8BEBBF2AA9A9B2E +:10E94000817F76EF5149CFEBDEF7C90BE8A7E9EEFF +:10E9500052DC02E4A6F071BBF7013F477EEBB150F9 +:10E96000FBC13D4FD33ABF2D7E5EB95FF0F36D7CA6 +:10E97000FEA5660FF117E65DA0DBDFDF8BAF9F8F93 +:10E980009F1FB3703CED3EA692BF8DF9B42379432F +:10E99000C2F0B39CE36773958D71F9CAF9CCFC4A58 +:10E9A000A003D4F399AB046DCA0FF755A490BCDC57 +:10E9B000643989FAB413FE43B96D846315339F0C2F +:10E9C00086E1EFCABDD03F6C7DF3B13D0C9F8DF861 +:10E9D000AA1403BE5E1CC2D74FD99759D61CDE7E3F +:10E9E000644888EFE12F9CBF48BE25F117F8562DEB +:10E9F000F235E02B8E62C0DB1F1666FF32A884F171 +:10EA0000950BE4635BE2FE4A72706BDC5F098F8FEB +:10EA100056093C063D039F775FCEF50DE65F40F457 +:10EA2000B048EA11164F3CFA498FAD199C80ED278A +:10EA30005A2B88EE243D19E73B2EF04FF65B64EE2F +:10EA4000B5B823C843EF1A3DFEB0DD0B08DF6F36C3 +:10EA5000E059B4F18DFDE53C8B0CF15EE33C938B0A +:10EA600085DED9557341F32119F6BD4FFA6D6C0857 +:10EA70002F55E4039FC50749FF5AA0D3CB8E978F2C +:10EA800027BDEC68E52711F5B3E3959FBC3A1EE975 +:10EA9000ADDC22E8BD81DEAF10EDC675BC2BF4867F +:10EAA00033827F9C12742DDBD51D6D43AE46BC5F57 +:10EAB000A3BA915F1D9B5B4478FE9EBF8AE63F5ED2 +:10EAC000A992BFA976EF77AE467F935C8F9CAFE2A9 +:10EAD000F24FE2D19FF629C00BFD631516774A2449 +:10EAE000FDC2088F68E34AFC017DF618EEF328F2B8 +:10EAF000516CF5EAE17414DF87F6F93B548AB719D3 +:10EB0000E17468CE68E24BC7770BFE0970453DBCE7 +:10EB1000E15EFDB92EEB8C33F09BC1BAF6F9555C82 +:10EB20002F93FC5AAEEFE89A1129CC71E1E72DC77B +:10EB3000B9507CB956BC8F62F36F247F9374E38124 +:10EB4000A568982FC7D07E91A1BD505FBF403C3EC5 +:10EB500021F047CA9F1331EE9A4871BCE397D91A46 +:10EB6000C2F313FEB598FB87FFB558C4BDBFA2DC46 +:10EB7000DE69E083E77B5FF2BDA622CF23C8EF58B2 +:10EB8000A082E2D917CAE7C2E4FC93C548E741C5B1 +:10EB90008AEF4BBDEADA722E17B6C63D4E791A7F60 +:10EBA0006EE67AD1C1661BE1E15F2EE7ED7FF9B732 +:10EBB00077499F3AB47F6B42B89C9778F9FEBED9EB +:10EBC00009E8173E5DF96042B81D20DB3FA87CF0E4 +:10EBD000F68944DFAA7BA073F9BAF64077A5B0079F +:10EBE00084BEF07D73D7FF157BC06807CC54EF4D12 +:10EBF00040FE67B407DE7769094E828FA03B21573C +:10EC0000AE15F0F98B454BA038DDEE222E570CF8EF +:10EC100029E17056C26153C580787346C805595FB3 +:10EC20006A66040FAF9D91BECC3A1537C6BF304D12 +:10EC3000A514CEE54865C183E8BF92FD7F54C2F3B9 +:10EC4000A9E43CC7EE53BAD0BFF2DBD68A9A9B3117 +:10EC5000DF616E1CF155D97F996F60F9756C73E2B5 +:10EC600015388F779BEAC6475EDF8994F0F54B3DF8 +:10EC7000CDF8DE0A73C705D9D15EDF8E04B46F8389 +:10EC8000629DC1833156577CFFF7305E83FB5F3155 +:10EC9000577537C3FA576CE2EBAAF2A9EE1CA8FF2E +:10ECA000B6E3C12B900E4E35594CDC3E70EAF0FCB9 +:10ECB0007047D16BD8FF7439972B272A2F4DC03C52 +:10ECC00038DF368B3BD7D57FBED108478CF3ECB30A +:10ECD00099D07FFA7E938505C87FE1217BF9D8A67C +:10ECE0001154BE8FF0E3F6359D7F5109F7739DEA0D +:10ECF000A81FC2E9C945EB90F87262B75AEE8FC0FF +:10ED0000AF8AC47C67BE7C82F0EDC5DD15248F4FD1 +:10ED100055F279CEAC7127203C7FB749253A3EEDBC +:10ED2000E3E31FDC7F6BC244D8C7FB957C5FEFEF4A +:10ED3000BBE5B509B0CF60A594C75C4EC9FC9EE0A9 +:10ED4000A61114EFFD732BB7BF25BDCB78F8A5AB8B +:10ED50008F25D0FB52CEED59A05B7FF7EE53648731 +:10ED6000BDBF0966E372CE5180F986FC75B66CAE04 +:10ED7000FE7CE757C6E9EA8BDAF5F2AC793FE75754 +:10ED8000463D77E926D083D12F65B0F3EA9B8B12FD +:10ED90004A917E510FC63C93872B5E48C57D74D542 +:10EDA00050BF4A1137ABEFB4E9F84155ABDEAE5B6B +:10EDB0006CB0E3FAD975067924E1745D14F924F591 +:10EDC000B96E61AF1CB7786A22E553AC2EE17ADBED +:10EDD00022A0DF348C1331AD6A9280F746848FB560 +:10EDE000F7D35CD0A7BB55F714D4ABFBD181410F4F +:10EDF000AC28D7C397B97DAC54FA235CA4DF9F45F8 +:10EE0000FDBF7DB090DB3E9043F12897B41F97A0E3 +:10EE10005CBA50FFC105EBE7B5423FAFD5E9E7DD8E +:10EE2000D825ECFD835557919FEAD8E55791BE7ED2 +:10EE3000ACCF4FE5D1F9A9A45E776C6E854EFF0C7F +:10EE40007B3E880DC04FA3E99B27901F139FE6725E +:10EE500069BDB0235B851D796CAEB0239319D19148 +:10EE6000D9ACB148FCECABEA6F8B5BF572C9BB4621 +:10EE70006F3F3E33DDFB5409E0872DED22DD738BC0 +:10EE8000B350EF3F34E0E750C6FDE7B7A22F00E0F4 +:10EE9000DE52C5F34EF139E6BF48B9C4A03FF28B4C +:10EEA000AA4D17F937F2769F5A88E9720C553AEA5B +:10EEB0006FE6754DE1759F43B4AB22EFCD02F513BC +:10EEC000D9EE05A877615E4F5C126F4714190A7876 +:10EED0009D9014927FE8D78FE1A1755F02BC37AC9B +:10EEE00032FB3748D798EF330AEAC74AB2096FD2E4 +:10EEF000D0A55F48E30730AF27D8328DFCCD15F69B +:10EF0000041E9F073B7A60FC6BE6F650F9609A6C32 +:10EF10009899AF272A3E8B7EE7C3E7303DEC24D19A +:10EF20000B3391BF654BDC180BE2EF7C872713E1B5 +:10EF300000F84EF2B5FB9756E2C307ABB81FB67B9D +:10EF4000CEF8FB6E82E7639E70902FBD7BA9F483A1 +:10EF5000F7C687E3EDF135A74CC8977FBF8FB9316E +:10EF60008FF1F89EEA175E81710EADA9DF5C8274A5 +:10EF7000745825BBC1E8BF9DFEC464B2BFAEBC5C83 +:10EF8000A5FCEEA3E52A43B9767453ACCE0E09F97D +:10EF90007555C28F4F0F98A91D4D9D3CCCBF42FFA8 +:10EFA00026E66995F3737956F0B32E718E8F083D7E +:10EFB0006697A09B4E41377708BAD960F4EFDECB55 +:10EFC000E9E6E83E301C40AEBF3EB7BE8CFCD6DB67 +:10EFD00018C5A1B3E7A81B8B617F17DBDC1684DFA4 +:10EFE000F4B9051C9E958A09E33715E50516A4F7C3 +:10EFF0008B07BB2CC8472BCAE7517D466536D9F92C +:10F0000007D7807C447B3FDE9D89743972AE2D60CA +:10F010004A40BBB188F8C4A4F74C3A7A2908C4EA3C +:10F02000E8EEA2879274EDA3B765E8EA299E1C5D1D +:10F03000FFC1E57A7A8C1D59A8E7BB8CEB8512CE0F +:10F0400033D5C9E4E73A1E92A3D42EF511E9AF9364 +:10F05000FD015A3ABED62EE4C818A8633EDD86CA22 +:10F06000163BE64D7CDA6576F3F1AB493FB067EFCE +:10F07000B5239D606815F3ABDAA5FE29FCF74C6358 +:10F0800086756D6218673D5ECE089F62463205F553 +:10F09000AF4E71DE778A7981AF4EB7909F8E9FE336 +:10F0A000E0B91EEAC73C7AFB200DE9AC10F184BF41 +:10F0B000FF88787F97C097E3E50FAE8B457C58C0FB +:10F0C00048DF98A9AE5C87F1C4E37319D14957E0D2 +:10F0D000F9585C3F8E83F981CF461BA7F2E977AEE2 +:10F0E000C7F5ECB6D238150FB1A98827177DEFC444 +:10F0F00007AF21F8B6390FC5B0FE7278CC439A1B22 +:10F100008193F71E0B58A80C68C87FF2DE3BA26102 +:10F110003CF0A2BFECFEE07186F372B9D02EF0DBBA +:10F12000C85F1F7BF8178B513E3FB66B7BE1DB500E +:10F130007E67DD3D194D503EB2EEFBDB6F7285FC04 +:10F14000A5BBAE58BEB313EAA3BFFB9347F7225E3D +:10F150005DF1933FECC5F55EF1C57F3860FDA35AC4 +:10F16000E219D2B75C9F719E34D6AE605C14F92868 +:10F17000F165B38FEA753EBDFD6394FBD8DF0CF0FB +:10F18000AB687A8CE2CB69E2FDA397DFAAA830EFE7 +:10F19000DB759CAF74AFEDED9C61A1FE01EC0F7CC3 +:10F1A00092F235870E03B682EF5B7D0AC6C54141F8 +:10F1B0007263BC371DDA919F33978BF4AB2C89BFF8 +:10F1C00082AFE0350746FE4033E1599E884722FF73 +:10F1D000457E7FE7381E071FEA601A9E6FF9739B12 +:10F1E00014CC537BCBEB72935EB096DD3503ECE42D +:10F1F0008B549E779157FED6D5782EB055B3B73045 +:10F2000034EE6EA1D7953FE7A0BCEDB7763B769084 +:10F210009E7FE40A53B87E58F6D89F9EFA1DE257A7 +:10F220005D0CE197516FE916F4D157B7B8EEBB0901 +:10F23000E0E3FBA59DDB559A2B93EC74B72B13F3FE +:10F2400077FAFAFD44C6D3DCFF81FC7C7E751CC5D1 +:10F2500019645C492DFFB80DE97151696309EAEF42 +:10F2600019780E834371ECB7575829DFC0A7C452F1 +:10F270005E7AB478F5A171D9229EDC3896D6C11A8F +:10F28000C763F9C98296FBACAEE8F2AA559C6BB491 +:10F29000768B957923C5950F8DE3FE90163C074B31 +:10F2A000D839387E7F35C687A39D0333FB0B29CF22 +:10F2B000D26E1F897920A9E2F1D6B89FBE8AF2AA40 +:10F2C000E7189757A94D9FAD45FA937E8BDA34D650 +:10F2D0001737D3E03D8B782F55C459908651FFAE38 +:10F2E00015F1A29E1A46F1A2D4A677FF1BE1B34501 +:10F2F0008C5FFB261FDF6A0E1C447CA975B848EEA4 +:10F30000F4A424B8F15E13FB92E7A764308E8F72E9 +:10F310007C26C6C795B3B075A7C656BF4ED7A7A65D +:10F32000B2401CE28F62A77933D6D828AF55EA578E +:10F33000A94DB7DEA08ED18DA7A05EFD5635B7B71B +:10F34000D1ECEC1B375BA757919E655C877CAFC700 +:10F35000C2F6A1FD1BA667911EC6C2E719A1AB0BA1 +:10F360003F9ABE6E49B3EAF8C45B5F560C6AE4721A +:10F37000C0953C8EFBEF101E521F937A5BBF710548 +:10F38000BD87E9973EE417328FA24F4F6A08B39BBF +:10F3900072FABF27F3D5E4394878467BFF99E95ADA +:10F3A000C278D2B302348E570C638A7364117C0D19 +:10F3B000FC12D816CFA7177A286891BA3C06A9572D +:10F3C0004AFEDC23F86E303B487E4399273E0CDE34 +:10F3D000C9423D687C22D183D44F8FAFFD88E2EFD4 +:10F3E000B5A887C2FCC1751FEAEEA114974D1F395D +:10F3F0009EFC73FA7C89B0B82BADD72BF8E64CD5C0 +:10F4000041792B3D2CD68DFCABC727F4B13FC6917B +:10F410003E26F985913F5CEED6F3FFEF95EAF9FFC2 +:10F420003C6DB0C12ED4C7A9AA3C8678F89B7374F2 +:10F430007C53F29F5BD0CDA7A27BC943719DC38251 +:10F440005FBE26F4402B6BA4E776CC171D81FCBF72 +:10F450008B4A073B426502EBA5D2C99C945F93C4DB +:10F46000DC5426330F9543582395698CE75365B0D8 +:10F470002E2A87B1235466B15E2A5DCC69C23287D9 +:10F48000B9A91CC93C547A9893E2E46FC607338F3C +:10F4900002FCE65EC5C86FCF7C7BAFD1E09C7AAA48 +:10F4A000441D1108E96A26E3C8E77B8AB7CF91F5C6 +:10F4B000A7AFD1B07D3AEF5F3F7EFFCF7C0EE23742 +:10F4C000A2FD17BCBDAFFE6FD74CC7F72D26AAFF14 +:10F4D00040F47FBC585B82F8DA349ED17927166BF2 +:10F4E000CBC2EB4F16690DE1F5E325DAB5E17556B0 +:10F4F000A4AD44FC91F5B145DAF5E1F5B612AD9154 +:10F50000D779BEE99B168DF45DF8ED56C6717CC3C4 +:10F51000DF20D5DB4474B34731E3B9DA04BD59F1D8 +:10F520001C55A423B7DD86A587E7FD04631CC138FD +:10F53000D300F68F818E82C89F000F2F51BC6D348F +:10F540008F819F283E913F98AC8F9B00BE935F3583 +:10F55000B886DBE98C456E97F39E0FCF9916E6E7E8 +:10F56000CD098D1B6D1F46FC3D22F4BC6EA1E7BD8D +:10F5700029E2C87DFB0E9A13CFDA43741CDD3E34BA +:10F58000B3B3E1FCB2DFBEFF546301BA0E36D99CBF +:10F5900028EF7A62D86B68A7F98EA90CF58CAFBA00 +:10F5A000DE9AA2594F72BE38CC49F903725EC16728 +:10F5B0007AF09FA0E75C3C48DA976E3B8737B73B11 +:10F5C00012C5BA5A66245D9647FE7CAED7E75B8EBD +:10F5D000CC9B0DEB4CDDC4FDAA0948DF183A7BE259 +:10F5E0008F4E8CA375CC3431E4536DD2CF6BF0C702 +:10F5F0006D99B1CA19EE0F6E4BF02B18BFCC08C431 +:10F60000703F4432F3C7A01C2D779753DE8C4F75A3 +:10F610009663BD9A5D9107F5C59DAAAB1CE63DD4E6 +:10F62000F9F42AF4032EA9B6521CC3A2CD7A9FFB8B +:10F63000FF78FE4692C0F3D60D367700E198E220BF +:10F64000BF6D7E5B6139DABB2D8EA424C4C5A4EAEC +:10F6500065E4376C71B85FC2FB1D3EA789F2139950 +:10F6600053B35780BEB2E3267339F2F1CC278B1324 +:10F67000D4B0759F6A3D17837190079C266A7F609E +:10F680004D997D9903EF3182BD00E521E7490DF5E4 +:10F69000F7EDD007FD8DB7379CEC1835C0392694AF +:10F6A0005B75781BE7D6D76D067FA3C5A017F48ED0 +:10F6B000177922E3D8383CE7B18F7E49F6EF2287ED +:10F6C0008BFCEA65ED0AE5C7040FBAB350DF3CB521 +:10F6D0007934E5BBB4B6EBFDD1C14C9685F77DEA34 +:10F6E0003A14D257D5D68F9BF1BDE179AE741C6721 +:10F6F000B8BB37DD19467F0FFCE4873128EF5AF19C +:10F70000C21AE111E3712161AFCA7BE575CE733591 +:10F71000A8F72FE978C383F04FD44C4433C72DFEAC +:10F72000343CFF8DD3E7135DE23D2DD463FAE9A3AA +:10F730009FC33AC3EE27B425E7C4E2BC21FCD5122F +:10F7400070BFA73B8A483FDAD95E46F7018CE3DCFD +:10F75000B69675A1DEDAB6D6DE1549FFBD2DCB9380 +:10F7600085F7B7CF6C99BE9EC1F99F39B8220DEFCE +:10F77000BB2FEDB0B11857FFFEA7B78CA7F996E2E3 +:10F780003D6A9CB7639E15E5C6ECCEE95684DB6DF9 +:10F790006B173C193ECFCFCABCA34A81FEE23A9E0A +:10F7A000243C71B0800FE1FAEB295A16EA17A773CF +:10F7B00059C47C4E77A942FCFC77533C743FE54C1E +:10F7C00066E47EC5A55C3F7FA4D445FDEBCCECB5DB +:10F7D000E5C9640F3A915E4FB51751FCCE8271773F +:10F7E000908B967D5FAE45FCFFA4BAFEEDE5D0DEC2 +:10F7F00036E7CAF7B01C6B6D24BD99FD5E257A0013 +:10F80000BD90EE89FD67A5DDD912964788FAA3A6BB +:10F81000F36B7818DA1F9676356005FE6E397096B0 +:10F82000F470C4572D0C7FE9374EE8F3223F246D66 +:10F830001CDDBBA35FDB6557FA03509E6CAFB74777 +:10F840003AC7E8F3878D8BFAED0CA6C584CD0F522D +:10F8500031407E6D2F9FAFAF9F68073354A3F509EA +:10F86000BDDCD82ED73F7A9B9E3E9789F391FA79DB +:10F87000B4F57EC7AF7FAF058313949771858E5E15 +:10F880002E52BB56615C85BDC5F93FD875CC13219E +:10F89000CE15E2B3B0F621027E00CFF5C9F3C93E22 +:10F8A00089B60EABFF88963D2664BF7D274DBF2EDF +:10F8B000D9AFA594C7C16D7E16B0246019A0FB1CFA +:10F8C00036781FE5F7A7D5373A2F8B4017B234F2B9 +:10F8D0002DFCB9C2E23F463E81683052EA2326FE43 +:10F8E000BE16C6E7E2EFE2FAEFE96D0AE9BF1BB721 +:10F8F000F03C8A4FFD5027E5829F13AA167F13CA5A +:10F900008E23ECDEE1B2E7DA6FBFC8A583DB128A93 +:10F910006789F6F71EFDD16BD8FEEEE33FF2E07289 +:10F920006F4D5E92C0F9D689C538CF998BADE48F03 +:10F93000C19F5DE207745CEEB7E9F070E3FE47B784 +:10F940002D46B9B3DFEEC674BCA5DBF4EDB6B4B09A +:10F950007D318E5F3E1D9C8239F3808E8EFFE45F89 +:10F96000E97E782CF24FA4C73536BA17D68F0E4AE7 +:10F97000FBBE334278BB381487A2FB2092AE4E6E9A +:10F980006A39A3C238EBD7585DF43D0583FD75DCB9 +:10F99000354F4B0B8B0F5BD7F07B9A2CDC4ECC0991 +:10F9A000ED5F8E7BDC576F7739FA8FD70FEFA28C24 +:10F9B00037A84CFB2DF2C5B432CFCBA5148FAEA720 +:10F9C0007D37ED5B73FC15E8737BACF7D5D2125C29 +:10F9D000FF88710ADE9731BBE8DE606BAB2906F960 +:10F9E0007E4797396624C2BBD54472BEA32B3976B5 +:10F9F00024CA258789E2A72857D430FF3E9BC0F947 +:10FA000064487E7812C2F59F58818F67F284FE3376 +:10FA100083EB3FCA130748EF686DE3712AA96F387B +:10FA200005FE385B791C329AFE838C07D71D5FB2C6 +:10FA3000C4897CAD2D817F7F63C90CB70FEF735EE6 +:10FA4000EA60243786E3A50AD4B31CCC3F1BE651F9 +:10FA50009D5CBFF17630D267921C0E37823AB5D3E7 +:10FA6000EFA3756B9CCEECF01FC233364F6338BEEC +:10FA7000D9A057580D7A836AA87F51AAD72398D066 +:10FA8000BF653C387EF3C07940D2AFDB21FC13A0C8 +:10FA90003FF9E8DE4829F323DE324D73250F09D9FB +:10FAA00001E877C4F6B452B6A3252CFEA4682F92C1 +:10FAB000DF40FA25A5FF41FA39C69482BD9610E6CB +:10FAC0008FF81598962AC5C39226009E64033B20A2 +:10FAD0007B329F29FC7AC6D7D4D39B2E2CEEF3B36E +:10FAE000E7F9FDA05653AC7B6776FF7EC593397D61 +:10FAF000C61EC21C4998E52A3BDDC399A9EEA17B2D +:10FB0000F75B8B4D3CAF991D71A23E903F81CB932B +:10FB1000EC32CFC5B81FE6F06423DE003C7C16BC97 +:10FB2000BF27FCB69937E7C4A23EFC76FAD92DA8C8 +:10FB300097FBDA4CC46F241CB39B4D77201A86C503 +:10FB4000E702E6C2509C6DA3E79C0FEF0BA74EE6C1 +:10FB50007ED7D879A70FA21F74C34813F9D96F8D28 +:10FB6000D7286E07F4635779BCEE258CB7B5BB92E6 +:10FB700092F0BB3B8F27F27626CEF1EEF8213BC206 +:10FB8000F34BE2C4BEEF5622EB2B7F9CC4E54BCF78 +:10FB90007E00E420F26B097BFC0FD59A23BC0E702B +:10FBA00083F7FFC5C7EDE97913FE50ED33939D242C +:10FBB000ECF9981AB2D7D1C708ED7B263C58ED83F3 +:10FBC000FAFDD991E7ED98CCE7BDFF65EF70D467FA +:10FBD00083FB017F06453ADF003395D2B859189769 +:10FBE0000AAEB62D88F41D9B33629F5BA1CD3628EB +:10FBF000A4C76EAD36EAA97EE2579F349C7C81D2C1 +:10FC0000B4817F94003D24B2C8FCF2FCFAAA3B0DFB +:10FC1000F5CE96D5CA7AE41F2DA0AF625C30D569C7 +:10FC2000257DB535F187D3F15C3E69604EBCEFBAF6 +:10FC300013D43EE45FE857C57BACB39B389FF13AE1 +:10FC4000B99F15EC38CFA5888FE966C247A9BF9A3E +:10FC5000AB39FFB9D8C6F3917B121DE4374D6CE286 +:10FC6000F9C7713ED067717F3378FEB006FF211F60 +:10FC700092FAAD23DFACCB23B61AF28CCD86BCE270 +:10FC80008D13F47C28BEA47840BDEA5760FFE23AA9 +:10FC90000F00FFC13200763096CF83DD8EE56FC056 +:10FCA0006EC7B8C18B6BF3A87C69AD9B9EBFB2B623 +:10FCB00094CA6959418A2B921F999C8F2CA0901F3E +:10FCC0004FE2D71BC3CA10DFA7F3F65F4EAC7EC06E +:10FCD000370CDA9365FFB1847F7D755F750DF6AFE4 +:10FCE0004DE3F551CF5E5D83FE9FDE99DA4313004D +:10FCF000EF524C9EBA36ECFB239B3B927D5F30511A +:10FD0000DE138B6CBF33FC4482DE9FF314F1892831 +:10FD1000FE9CBB15BE8E3F4E7AF05EA48B41F3CCA9 +:10FD20001EC4E3AC1CBD9F7FF044CE77168B32EB34 +:10FD300015A08F01E02EE9235A7BCB7E4081087409 +:10FD400025CBADF16C2ADDCFAEB12E8894E774409F +:10FD5000D055D4F11DCC651B1BA2B7168791DE824E +:10FD600014DFFDA4E9C683282FBF39BD31B20F834C +:10FD7000351AC9EB20D01BF273B581D39B6AE6F725 +:10FD8000336B0F73FFC84EA42FCC87437A837FCE8B +:10FD9000F6F17AAA81DE5A8CF4E6D0D35B10E90D35 +:10FDA000C64BF471FD22AEBAEB5BA5B7CFBF21BD48 +:10FDB000FD7A4A90F21A7AB21BD3113E5BC5F7F076 +:10FDC000BE2A1DDE35D1CABFCF7189467E81561C41 +:10FDD000C741FAFC26FCCECAEC61CDE62480DFDC0C +:10FDE000E402FA0EC1E48943043D1C71A0BF266100 +:10FDF000BAE69C88F475E57B74BF31C5C4E9B7E009 +:10FE0000D937491E64B675CF9B8D74B75A253969A9 +:10FE1000DC57EB548E6F2D0A9F174E2E3D3CAE37AC +:10FE200042D0A56B758B62477DBC8EB973B3E9BBBD +:10FE300032F4BD9B7F69FD4F278EDB3A3589D6E5CD +:10FE40006A7E33D1CBFD6B6968BFD195E6C2FEF403 +:10FE500008BF2ECB101D3DE74F1CC03F7B3EFEF17F +:10FE6000C80445F209CA03F68AFB9B322E12959EFE +:10FE70000D7EDCA8FEC34B387C8CEFC74FE1F3B698 +:10FE800008FFAF51DF93FB3F3ADD3B1BF7A7385E1E +:10FE9000E47EE003CC85EB9471B3BE3C23A91FFA4A +:10FEA00098BF05F56D33A83243B8BA81E3F5E51F75 +:10FEB000093D714599773E8EBB83B90EA27C73B81C +:10FEC00079BEC233D3B50A82E7D7D4034BCBB46B28 +:10FED00006C2AB15B3B54503B5B32F619471A1B894 +:10FEE000D6F47966CE179A14C1071CEBAD50DF9A91 +:10FEF00008FCCC857A3BDFB713F8868BEC0CBD1D74 +:10FF0000310B9D91C837908F1070B5B998579920D3 +:10FF1000C60FC9EBE00BA8970601B6774053828F56 +:10FF2000CBEB96C39CAF5881AF505CBA94DB09F21F +:10FF30005E505CBE9BEC2F551BD87E301BECFBE665 +:10FF40008922EFBD901523DCB24CAE3B27C0F3A253 +:10FF50007B661E9D008F4BEE5B3A18C5E9F81D6D60 +:10FF600015F8BDAF150F9FD9817ED209FF6E63E2F0 +:10FF7000BB6A9467F0779433742E07269FE1FA6387 +:10FF800076643CBE620A977F32CE3A001EFB098F30 +:10FF9000459CF32BE0B1E33C78FC58143CDEF30DB8 +:10FFA000F178EF44D8D7357808304ECC6CED17583F +:10FFB0008F86B7B36669CF0ED41E163FE0F943AC07 +:10FFC00081EC6719BF34AEA70DE56BEE007EA90D7D +:10FFD0003B63D09E6D69D8F9327EF7B1A589DBD934 +:10FFE0003DF16E7B29DA376FA8F43DAB68EFA3DDF6 +:10FFF000ED036639730ACF8F3EB4DA169806E364D0 +:020000023000CC +:1000000038B8BCCD70680CF3C5CDCEA0C51B8FFA37 +:100010009A87A19D614D36315F983F66ACE508C96E +:10002000E51E90E3481F409F9CDE12F938523E4F78 +:100030005B7D274672D8945E90836174F2F2FE5223 +:10004000F2C3C597EC5D85EFA9355617E2F7B4CF3B +:10005000416E86CD331D3491F0FAA5F674DD383348 +:100060009DD9BAF6D969DFD1B55F06F862A53836F1 +:10007000BF1728F59A39AE025DBF4411E7F86EDE6E +:1000800004DD7866F5CB3BC623FD0B3D6232FC8771 +:10009000F4AF1AF405A33E61D41FD824FD3DD53139 +:1000A00066918766E6F9115B999DBE4B017C90BE17 +:1000B0007B501BCA13203A19630DEEBC0DFD2A0BB1 +:1000C000ED6E1F3C6BDD7F595A5D71C87FB6B589F7 +:1000D000FBFD5AF6D977203D6C177429E92B3FFEBA +:1000E000E4424672DDCA501E1BE955E63B497F815A +:1000F000F427280DDCCFF0D4D46CA207C97FB65604 +:1001000073FBF7674A204619C1E9D29514FA3E5DA0 +:100110001A537C73387D6B49A254453EAACC7BC5EB +:1001200071D0CE4EE3F3B19778DE64F38FF17D2783 +:10013000F30D13FE8CCCA4909F02F31356F2F77CC0 +:1001400073C47BC345BEE520BEFEC04C31DF18281A +:10015000D5464DF8A7BD54DA301E0E658EE28E45A9 +:10016000FFC708D543819604115FCF10F1F43825FD +:10017000C099C7D7E42363818D625E024BE2DF172B +:10018000297BCCC154A20FEB4E9447B79E70BF8E13 +:10019000A9BAADF13F7C751A3C6F7F4375A39FF4FC +:1001A000D64CDFDB48D76640061FF9B53C75786E44 +:1001B0006AA5DD391BDE537D3B9A31BE3BD6EA3F53 +:1001C00048E7B9CE46F41E84F7101FB6C7039D2238 +:1001D000BEA2A76B5C281F48C6318213DC7694A3AD +:1001E00041ECC7FDCD3AFF67847C13F2979A45BD79 +:1001F000D5B193F4F7F5C956FCE226E6F76435214C +:100200005EA6C4F2FBB78CC70D86E33FC2F2EDAD2C +:10021000CEC87E4DD0D7080EC1E6E56903E95D5131 +:10022000E3280E53C09A70E17194B66BAFF407C225 +:10023000D629F7BDDEB15359CCBECAFC4C1F476965 +:10024000605ACC98087194A05FC1750E6FE07196EA +:10025000E1C25FFF75E3285953BF5E1C45EEF7729C +:10026000F1EFB980D8E29E31C513E8BC4CA1F58509 +:10027000C1EF21E247841B0245A0FE3D517F754F2F +:10028000F79F1E857F1EDEFDFC1E2CA51E374FB47A +:100290005F31FAB30398BB356FC32A11C7D2C71FAA +:1002A0002E07AB2EDCCF8FDF0B08AFCF33ACA7CC44 +:1002B000AC8F13CC70E8FBCF4AD6B7970FB3F53BA2 +:1002C00037F4CBD37E95FEFBBD35EE76C6BF371532 +:1002D000760EEAF9EB76CC9BC3B88FAB3F9E84C712 +:1002E000013CBF34B3A462C41713E9A5DB7DCBEF97 +:1002F000AA02FA590F7294F362978EFE42718F72BE +:100300000DF149FAFBA3D1D349470EF9FF87371DF9 +:10031000EC9A3198F5C5016E8FF5BE3109BF17E42F +:1003200038A7A01E32BCE937D47EE5C29201F1287D +:10033000B7E950D78CB0EF08E69A3D26B49F739B7F +:100340005EA4E751F5F9FE7C84F2D672055EC8BC66 +:10035000C0ED98170870CF6D10DF07EE1C38FF4D09 +:10036000CAC3D6B0FC3E4A6670292C7C7C29F7FAB9 +:10037000F9D319F7FBCAF9FAF2020DF3F6C93F27D0 +:10038000977FCF4CF77E312925EC5E86B8C701FBFD +:100390008E9807CA268B7BB1D1F3D8B8DD59F9D234 +:1003A000DB38FE57B63BA38C3B2D2B18F19ED4A017 +:1003B00089C28F1C13CC44BF418F25B25EFFB39915 +:1003C000B392270F60A761DE2CC232DA3ABF6EDE2D +:1003D000EC04116F92F156993F2BF362CF973FFBDC +:1003E0004DFDF065C21F10379951698C4318D73BFA +:1003F00059F8C7B3CB3C9326D37DAEC8F107D9FFDC +:10040000ED746B44BFF8FD53059EF4BF7F44F9A122 +:10041000B0DEE4703B48BE27F3F28DE3815D74C526 +:10042000E4307FA0B73997FC7D61F696CC8725FA3A +:10043000D82AFC107D7460D40B453CC4A817CAF8B8 +:100440008852CDFD13401F350807D4BB302F5DDA2D +:1004500079329F54E68D625E28C5A3BEA65EF5ADD7 +:10046000DB53CD3329AFABC559F6D237B1A7DAA7E5 +:10047000F27BC2D29EF23AB8DFC18BF6D425FDEDF5 +:10048000A9E2326F2BC2CB68571DFFE987941F0B7F +:100490007668DBE46F834F18FC53232670FC96725A +:1004A0005AFAD30E8E34E9FCAEB3D43507295FBCBB +:1004B00081FB5B32B42EB2D3AC0EAB0BFD2DE61933 +:1004C0009C8E2CF9CCAFF1382FF957645E599263AA +:1004D00059C4FBA6D24E0C4A3BD1C7EFA7F61CE687 +:1004E00071DB38F4B760C7722ED7A4BFC5922CFC5D +:1004F0002D867CEC38837FC5E86F7962B2DEDF72CF +:10050000BFE2BA0D49FDE96D337F87A0F8B77B974D +:10051000C6A1A9FF8CBFEDBBC2DF728F03D6B7FFA8 +:100520006DBDBFC518FF8A10F722E7D599034F901C +:10053000DF44C257D2ADF4676534F1EF37CD52F7DF +:1005400028C85FB63A387C55F4672587FC59CA132A +:100550007FEAF34BD17DDC7E71F2C697719D6660B8 +:10056000381B23F9B7045C8DF1A88426710FF85B62 +:10057000F267BD63806FE13D4577E2778D8BEFAB2E +:10058000388AE5B81D370EBE1ACAD287EFACC0F262 +:10059000BF5E0E66A3DE69F463BD821F414EE90FA4 +:1005A0005F231C259E7A1B249E3AAC44B7D51C8E33 +:1005B0004638A56A1C4F73014F4145E8C3BF9E44AE +:1005C0004E9F1933DC2FA17F6D78BE9945C26373AE +:1005D00013FF5E9684E37601C7A48665E42734E2C0 +:1005E000E9F0CEAF869FEA14E11710F07B6A5BD189 +:1005F0006D08B7BDF756FC0ECB5FF86F8C43B8EDB6 +:100600007BE8CEEF0AF8A5D3F7740DF05B14057EF6 +:10061000D3DCDCBEFEB8CC9B3805E4C265C021D07B +:100620001FB2B3BDD0AE8F03E9F969EAB7E49F0A00 +:10063000F6F153F65AEE57E0A74F1BFC53A93E4E76 +:1006400037A9BE13449F19409F31E8AF6AE07A246E +:10065000887D7F9C823637E7AF52AE21CB3181F067 +:10066000D9EEE471E7087ECA007DEFD7C087D1815B +:10067000138E772057274C4909C9BBED0D3C8E7668 +:10068000E34CCF2484AB8CAB3D335D9B3C85EE2F9C +:100690007C6DFFE30C9C47FA1F014F69FF2AE03B8A +:1006A0007EDFFC52902768FF9B1B8216942BB54D72 +:1006B00037285E28DF9EC8CF3F35CDCB30CEDADF7E +:1006C0005F178C47BD7DDAC83E7CA808C787B1ABF1 +:1006D0003FB913FD5CD1F021234ABED2F9F1A14C00 +:1006E000275FB7F6E143E38651C9178E0F478DF8B0 +:1006F00020E83FB521780FD2AF59E083D9097C0CAF +:10070000E0A1221EE487E29E921E8222FFC0089F83 +:10071000A06F44943C84554AE900EBBBE0FC031114 +:100720000F6D11F1506F13CF97ED596D9BA5CF3F12 +:1007300070D3BA673B1A95F03CFE0879B2B7E1F97D +:10074000C938A78C6B7E5CE6D98CCFA7E5F1730E18 +:10075000468F3305F07E2BA09FD380E777139ECB87 +:10076000FB07428FBB71A6B6159F8FB1FA29CF192F +:10077000F4BD7BB1BE7DFFA3FC7BBBC20F29F3F2AE +:10078000BEB1DF2CC1EAC7FB92D26FB635DEBA1319 +:10079000CFBB8E0567D2777E314E817EA7CD36CA1C +:1007A0006BAC57C0F046BE78A9B76B0AE94D1ECABC +:1007B000C7F556DA9DA8E7B726CE4A43BE51BB5EC1 +:1007C00025B91ECDBE91F4560BFC86E8AD89F39B8E +:1007D00054C02FC2379F42FC2603F80DE73F1A434F +:1007E000BDCE8C74E7E8CF6FB60E00FF0BE43B2F55 +:1007F000E17946E03BAFE03EC3F8CEEFA67C83B89C +:10080000C7A553188FE788FD633C80F68FF415BEAB +:100810007FA33EDBB76F3D7D49BAFB5F40679F23F7 +:100820005C23D0D9FFF98674A64E8D4C67E6A97A71 +:100830003A8B99FA8F496799534BCE4F675D02AF58 +:1008400064FEB6D42B2E52BBCEE5E2FCFF8FF3B78D +:100850006F9FC4FDA9E7CBDFC6DF85F84F8DF9DCBC +:10086000FFF4A7FEAFF5A7FE78EAB7E04FFDF74922 +:100870002ED2DB8C7ED5BDE3B5B6A903C495259FEA +:10088000364B3E0DFC18796F2DF033E4CFA9D5BD62 +:100890007F7E86DB9BEE3817F91BEEC0F566087E7F +:1008A0006DE4CBA077DE39F5EFE86FF87BF90DCB7F +:1008B000265FD87DFBB2C92EE1778D7CEFBE45D88F +:1008C000F72D3006DED3DBBEDAEA6F8505A78BF3A2 +:1008D00019D370E5654864AFAFB0C60607B09BE4B6 +:1008E000DF91E858EB7DEE746EF8FE5844B9D5B749 +:1008F0003F839E1C6E37B9BE82DD94324DEF873246 +:1009000037703BD70CF28EE2FA5A6900F975864FC0 +:10091000E9C2D4606F72A3827230B5C143F9F05F4F +:1009200035AE6FC4A36871FE6F3BAE6FCC1BF8474A +:1009300089F3FFF754FD772D659C5FFA5F8D71F9A0 +:1009400031D68E7292AF3526FC0B18AC75FF073B83 +:100950006FC3F35E68A77B1AC67C806871FB314960 +:10096000D6605C4EF4F8BDF417DC6F697C19EDF0CD +:10097000FB9B4D74BEC6BC81FC789E3FFED4AF3657 +:10098000DD47F93F521FAE167CA649B1D2771DABA9 +:10099000FDC467BCDAEE668C27A73A5817EA5947B8 +:1009A000A7727A51D334E233E66A2FE1958C4FD4A3 +:1009B00066F17B733102BFD4918DAFE2F889475461 +:1009C00037C6B7376357E019F1282B518F9860A2CB +:1009D000BC884EA591FC1E1D8A8BFEFE4762BE930D +:1009E000F4A3C713DDBF5F80EB4FE17FA7E4D09C8A +:1009F0006569C807D73737A7E1FDC4E2693C1FF135 +:100A00008E39676B288E9E07FA9F42A5EEEFD9CAF2 +:100A100072A7A688BFB7E4A77C4458F7367A6FA4BC +:100A200095FC6CAA76F78DC807D451B308AF3B1478 +:100A3000E7C2C5785EB956D2635A73C72D5802FB18 +:100A4000DA90E229CFC6734D1C49FB6C4D1C928095 +:100A5000FAE886F41C9ABF5DF19667E37BE926A26B +:100A60006B55C4E737E42E7B09FF0E484B8689E1BE +:100A7000BD83CEDCB3EDD8AF7302FF2338C6F5AA31 +:100A80004EFD3D29FCF011F26F358DC7C55511178C +:100A9000570D71E5324D917F6783E20E31826FD53C +:100AA000E6AE5B40DF4F70589D88642DF1C12AC2CD +:100AB0008FD51686713A66EED0E969B7ADD57FFF5E +:100AC000C591AF5F4F7BDFFD846C2FF219FA1BB02D +:100AD000942F9EE845FC407ECB93FEE2783D46D4C1 +:100AE0000316AF2FC2F9FCB3FC67F9CFF29FE5FF05 +:100AF000EFE5FF00834DEAE8008000000000000001 +:100B00001F8B080000000000000BC55B0D741CD596 +:100B100075BEB3333BBB2BADA459FDD82B90CDC8CC +:100B200096880C421E0BCB488D8D66A595B4322E4F +:100B3000D938FC98C476D6D8B8E43427559D26B168 +:100B4000135AADAD95254BB62C09829C43CFE9DAFB +:100B500024396DF00125E9690C01CE1A1C420834D4 +:100B60000A10427A92208CE39496E698828968690A +:100B7000E9BDF7CD6877462BFFC53D1187F3FC66CD +:100B8000DEDCF7DEFD7BDFBDF72D0078600180EC59 +:100B900007001D6073912709E500676B200DD5D80C +:100BA000F74E576841800FE9AF35DB0EF702647CE2 +:100BB000D97EB05E05B30EF8EF43D1B8E88E9B1630 +:100BC0005DF863D21DAC5537A48373E9DAE3DA4CE0 +:100BD00009A029EF3C205DD43CA77FA6E3F8E4CF31 +:100BE00064A8D5E7CEE7FEDEFE6E73D1FA12A8FF49 +:100BF000FF1B3F1F5F979A1E800AD18755B86F6A07 +:100C00009788AE8E7C5040F0A1AF73553A83FF9C1D +:100C1000901283D5B4BF90C7F806CCE583DDCADA5D +:100C20001CF965E9CB827CB94D1F9720EF0C9881A8 +:100C3000627A85DF21EF355CF6872812A5DCC3CF09 +:100C4000C1A2170678E6435CDFD1ACBC405B90A53F +:100C50002B6F5479FC72B5E785A695F8EC15D9F899 +:100C6000869EA5CBEBA9069E00ECEFAAB3EF156B11 +:100C7000DE8F1C5221638FC7FF8F9921E6D3C4A654 +:100C8000FB2181FCFDF9C64F9424F2E881DD2E4B57 +:100C90003BBF7F036902F30DD2DFC07FA77E312AFD +:100CA000F1E4C7C4F3D40A2D3D84CF87A4F4D03532 +:100CB00034EE2EC15F5B0E85961CF02F5C837CF4B6 +:100CC0005A72F2BAF7857FCA02E693C59C1C392C8A +:100CD000611A35B4EF3E9B9E6E6400F934BCBC6172 +:100CE000C5904EFB1FFD876FE13A0E1DDDF3E6B7A1 +:100CF000F075A0BE61A419D75360780C99F4F9532C +:100D0000C78EA1B860A0FE0BA34476DBA8646AF886 +:100D1000DEAF058FC8B447BF64123DE5E042DE4F49 +:100D2000789B530F2624634125ED6F4C02924BA113 +:100D3000E17CEFD373F683FF1F2239B37EE63C4795 +:100D4000BE21F7364CD6CFE5FB2B963E2B383E69BD +:100D5000D345BE8C7BF59B89CFE3FB644822C9F168 +:100D60005D68145700FC5BE6BE4FEF46DBFE42BFFA +:100D700097E5301151D3128E9F28D26EDB40FD0AC9 +:100D80008F7184998AFFE3BE46975DCDFBB2E76B16 +:100D90006AD579BEB1C8824AB2471C5719BF6EAE38 +:100DA000FEB9D77FB1FA77B7596AE9FB28107D9869 +:100DB000BCD943F6E4B7C65C234F362EA1F97E2E8C +:100DC00083D09B1E8817CDE54F3FF9838F64F54490 +:100DD000B5F4686FF9FA9F10F9F9F4594D4F99D5A8 +:100DE0000D340FF410DF97859DEBB3C77DCE92973E +:100DF0002F0D196F31B519131AA89D32256CCF6EBE +:100E0000FCBCB6569F7F1E1FE4D0AD267AC0FBF611 +:100E100042829945723573E4BAA7B0E10E924BFF56 +:100E20004D2AB0FEB9F97C9EBEAA648E4BC5A40FB4 +:100E30001F61FD48A27ED4221D6FD8A987F12756D5 +:100E4000C27450C829C9CF6326C96959AB77D67F08 +:100E5000FA73FC25E8BB7F2323BD7B63AA3E84EBAA +:100E6000BC37BEFDABB7929D3F2F1B12BFD7D91F1A +:100E70007EC19A034627581F4AAC7367E7B17B5E71 +:100E80007B8E6414535F27BE911DCFF245F867D364 +:100E9000BF2A3BDFC1E693834B910FA9C1FCF4EF5E +:100EA0002CD33F47FCB3F93C1FDD59FFBDF3F86479 +:100EB000F4FA6C7FA4201188A01C4682063A017ABD +:100EC0007F82DFC34AD4CBCAF9E5891C65FEBC46E4 +:100ED000FFC471DD51538B605F3E864B5F8E7EB1E8 +:100EE00048BF793DBEEA287F7D13F17F5BD0A3C95F +:100EF00039F6D5B7DF0B99203102E745BD5B07D343 +:100F00009BD6E338A8F1B29ECBE52BF8F9D6A2B870 +:100F1000E2C1F6EAC8129ECFFEBE1BEE5376E0F3A6 +:100F2000E55EED15D29354B9442BC2E7C8405CFA94 +:100F30005A05CC626CBBF4889FCEB5D8E33411401F +:100F40006B68BC9CCEA586C70E5525C8AE93E654EB +:100F50001DCA276489EB5ADF54BC1DE9F5BD201B6F +:100F60007BB01F0A6E5F07A847D22341F6137DE8C6 +:100F7000E77D287725D8F9263D5F7306209AA34F91 +:100F8000AD337E88E6F8BD0852CEEDB7FB2B1DE3EE +:100F90003BB46AC77B194C23837CEA0A2F738C2BE2 +:100FA0006A5AA9D17ABBF5158EE737D5B538BE8711 +:100FB000A872721AFBABF13F92BB0CA2CFEFAB0948 +:100FC00027603FE77B0572FAF87E6DA4A8FC341D0C +:100FD0004A37C00D6447289723C3E47F36F8F9DC0D +:100FE000EAF3C231A904C8F493D048CC36F9BC97CF +:100FF0002C7D4D46AA594E52F099F7590F1F9FF676 +:1010000010CE82C7A091FCEBDF6AFA710F0EB99285 +:1010100048E2F76154741DE584AE3A1968E4E7E6E6 +:10102000D2523AE7A46437F617E1B8B05045789643 +:10103000C6F961F757C4385844E3344856615F3302 +:10104000A080E45A85743E5BCADF25BBADEFAE12CB +:10105000DF254B4A05FD86463E47331DD81E060355 +:101060007CEC7FE2089AC88BF4707B15AD0A9F3F39 +:10107000084623F56B619AFD148A5FA2FE4298D45C +:101080008493CF08BF3DAD844EFB85DFCF672F59DA +:10109000BB51E0B42D0F1C7C55ABF925B2BFDBEE84 +:1010A000683A27EE50763EEDB0DBEF4474711EEEE9 +:1010B000EC623B51763EC3EF5F8AC4F7901D12EBA2 +:1010C000FD8D73F9DDA06680FC572A02461249A403 +:1010D0001E5D1BDE82F24D3EEA376AE1F2C9E36231 +:1010E000E59006AD80F82AF75CAA1C80CFF9E031C4 +:1010F000FFE121564693CFC93F402EDFBA14B9B85D +:10110000E501F79401B49CDF8F3E206502D252E6E0 +:1011100087196ECCF21FFBC96516BF4A2D79C8A28C +:10112000CDC8D673A5747EB910BDB2D2AC7CCE2723 +:1011300097701CDF3766E523F798CC3CFB9CF6C123 +:1011400019C6B74B2483E5B5548E7BA85F28652C60 +:10115000D093E673BD183496CF15D0C36DB9777AA6 +:101160000BE3E19D3811E1D90FF094CD89C752C14D +:10117000367F35F9D73AC5F060BFBEC8134F231F7D +:10118000AF542043FBAB542049FE1C9101D34F3D8B +:101190008AA7159E33293CA63DF4DD2E7F3A2565AE +:1011A000E76FB0FCF64F8ABEA94DD767F97C92FC79 +:1011B000D772C10F0FFB9FC90C7D1F8E81D1A7CFA6 +:1011C000F567382E295B7E8ADACDF4A285F9962C54 +:1011D000C6BE34F8C3F70967103D05FBDF8B24DE7C +:1011E00021BD219C1E2C65BF345D48C07A2E2E3057 +:1011F00009576CB1E6D970A3BE388EEBDC32E87BC0 +:101200009DE841CAE7C405EEEF750972BFB7BF9B01 +:10121000D52BF7F7976807B0B3E2827040E491D519 +:1012200025D37970FB2CCE243B29CBFD4EC8492D0C +:101230004F30EE50C95ECACE4FC7EBC22F361D2FBE +:101240002A2ED1F15AF8C53EA7B6C319AFB2D45A67 +:1012500027F26B2BD87FE5CCCFCD16FF3E4DE7555F +:1012600031F1130315DCF73688ABA4B77F86109AEB +:1012700070FC927DDB8A192F405423FE48998FCA57 +:101280001F5E7B117CB4F8B439F3A65727BFB4B303 +:1012900008DEC88DDFACF7EF6CFC8488D3FDFE1A46 +:1012A0007F4E7C5878EC835E72EA7B0AFFE68556B7 +:1012B0005C7AFF4BB22157D37B819B0320CEEF4258 +:1012C000B2535C77E1E3A7FF87C617BA7035518642 +:1012D0001CBA9EC2FD8C670B8B559D71B64BCF6CB3 +:1012E0001C0D1F081C1CB4B897435722BC6CC73D8B +:1012F0004C579A3BEF75163EC757910F2F00CFBB47 +:10130000713ACCE273F13E1854859D609C9971C48A +:10131000C17A5E3BB3D76D7F57A1C6AB8DFA3CDF78 +:101320005B72A8A7401CFDC2C22A48EFC6F50E0E8C +:10133000EE8814627FAC02748C3061A0F38B12E1F2 +:101340008DB672A14AA166810B690AB0E378FC0BE5 +:10135000FDAB3E5487EFB757050D5C192C7C0B7124 +:1013600032D2B9ABCA6F98F82005E27DB2D923E238 +:10137000C924BC4C78749B251FEFE30267B26CD084 +:101380000EF7B7097CB5EDD867D7917C474A6F3126 +:1013900032386E1BFAA732C263A35EC67388EB1C99 +:1013A000B8DFD79C8303F1FFBB0E791D7DAF0B2700 +:1013B0000EB7210E44FDB671E0FD6DC07646EBA27E +:1013C000F3E472CD03C172F6A7D729539E7CF93797 +:1013D0005B1E36FE7EA242F0D9FBAEE00B06CC3B94 +:1013E000E8B9EF5D118FA1030F362DA0D35FF0CFC9 +:1013F000D784FCA1A7EF8AF300BFE4759BF81FAD6B +:10140000DB8D877D2E3CEC5EAF2D87476CFEAC827A +:1014100055C41FC4E78C13ECFDB8F7F138C6E7518B +:10142000548A277BFDDC667A356E9FEA0D737BA2BA +:1014300057872802B0677AEBB87DB6D7E0E7CFF5DB +:1014400036736BF3612E7F445EF32A6BCD4AFD54F5 +:101450009CCED12BA21E3685B17B3CCCB7B3A89FC6 +:10146000647CC506E5DE707CCC93A690DE8E7F168C +:101470005AFA7AADEFCC711F8E1FA904630F7EBF9D +:10148000B0793BEBD99A339EAC9D00C539058E3CB3 +:101490004104CA1CFD76FF958EF11DDA52C7FBD2BE +:1014A000C834FBA9AEF0B58E71B69CFF8EE22C5C01 +:1014B000DF58F4A4467CEDD6AF778C53EE41F93774 +:1014C00050FCF351075D90D719E4A74B373AF5B0BC +:1014D000D82557F5EE73C741B69CDF6A73C643F350 +:1014E000C9D7ADAF365F4B67F92AE2CA14C595C8B4 +:1014F000D7524DF0D5DEEF88B55F7B5EA559ECEF96 +:1015000072C797C5145F56E78B2F4F597C3E4F7CAF +:101510001973C6976EBE9E2FBE5CD0EEF42B17CA11 +:10152000CFCD8B45DEADF47999E31639D6C3E760AC +:10153000D9946C74914BB4705911F9001CB7B94926 +:101540004D13CE1C83E9309DE70725E42AEA5B5959 +:10155000BD51497EE6E190F1CA06C28DDD220FF849 +:1015600074E4B630E18EFEDD87C37858414BBB870B +:10157000FDDD68E434E72F141D387F81AD99CE83FB +:101580004FECF176BEF1E026352DE1F88356BEF141 +:1015900060F76CBE91EB1B134D22DFF827EDBA9577 +:1015A000FF4B86295EB977D3AA4A3EAC14EC5F475D +:1015B000C30DB693A180564C71746A9347A37DC93D +:1015C0002BEFFF3CE9C701A9675F0DC56F151ECE64 +:1015D000BBA642AB2AB7E0387933C218EA6F5AF596 +:1015E0002AF9EC890A7D5F0D7D1FAA61FEF5AFBE69 +:1015F000CD4FF38C841674537E64A4C3C332920916 +:101600006714339DBA73C53DEE3A804C1E97E2B71E +:10161000724F46A5F38AF0474EDEDF96FF5048E54D +:10162000FCECD6F6870E276BF831FBAF85765D664E +:10163000531BE799CF129E90E6AFCBECB5F29DB36A +:10164000E74ED8B99E3CF3302EB0EB12F4A7DB790D +:101650005AFC4BDDDC99A673741CE231F29FC9E0A1 +:10166000B9EB204AF0DC7590F9EA1EBBDA451EF5AD +:10167000CB2477915F74D44B94985517B1E2D783FC +:10168000940F277D70D549EC75F459F452B37AE480 +:10169000AA9BAC562D7A06E4CB5FFFA1F593FBDB4A +:1016A00045BDE662EB26DF6D07B15E2BDFEDB5E4ED +:1016B0007F8D3CB983F4F18F9DEFFE6EFBE5CD7716 +:1016C000CFAD13A5D95EE0D89937D8AE972DB0F03D +:1016D000CBB9EB404304F4517EE32B109752FDC38A +:1016E000EA27AF1374DD75A1809547F951FB5211BC +:1016F0006F913F21E12AC662E26B50F97652C37DB9 +:101700001404C72084ADAF7C4B92DAD6C53AD78794 +:10171000C69779F8BC1A2F4A1CEEA7F52F0BE6B531 +:101720008B572DFF3768D56F48813D646F926D1CD4 +:1017300090F0A09C2640C8F9ADF6108F57B4D1E6C2 +:101740003B516F4E913E54F07EF2D67F4EB78BFAEE +:101750004F0EFDAF939EA62CE244670BD2F90F4BC0 +:101760001F810E8E0514EC88F9FCFA6833E182DFE4 +:10177000B56BE2BDB2C2207B180FE59FEF77D67E36 +:10178000805231ABB2F868E1464107FCE2FB83D2FC +:10179000990D2757B25CD99E681DF4DE5DFF72D3A8 +:1017A0000FD439E31BB5CA39FE83D97D38E3A203D0 +:1017B000F3D4C7164585BEB62E167A46FAB1278FE2 +:1017C0007EB8ED5DA5BC27C553D190359FF03B4158 +:1017D00065AA8DE29D603D185C53548EF37EE34F05 +:1017E000D41C9B5E497EBED8A03848F1A3AB6CCC1C +:1017F000C689EE7D9F2FCE5314487A1BE7C67B48DF +:10180000D72C6914E74C3287DE5551A127726E3C04 +:10181000584DE1887E33D7F1A80E48FD5DBE0DF925 +:10182000CEE9DA76EFAC9FCC57D73914C73882822D +:10183000D447F6EFDB8AFD77348FE6E3317ADEBA00 +:101840008E66F567EB3AF10BABEB8C464BBB6B2E20 +:10185000A6AE330FDDD9F3786E5D271AC57D8E05F0 +:10186000457D65B6AE734BF905E573C03A974B2DD0 +:10187000BF5CD46DC5113B258E239E6AFAEDF072D4 +:10188000D2B3262FEB01EC9F805C3B59B751FF5A36 +:10189000199D33AFFAA056F83593E8D971B1CD3F11 +:1018A000D5A2DFF6D0F30A8D1FAFF4AC627A90F1C7 +:1018B00079B8D89D54AD56A676B99A914B886E29C1 +:1018C0005875F48C44CF23C8ACDCF86064E6C5F6E8 +:1018D00012CA9304C120173412D17697D03FA80AB8 +:1018E0004478A75A4F93BF6DF7173AFCFF48B72AC1 +:1018F000FC6BADB82F337E5CFFDA361C3FB033C0D3 +:10190000B8E9409547D85752E27A7287E68C7BC691 +:101910002797083CB6DF6BD03D91A39362FCD6C8F5 +:10192000AAB4CCB8DB191775EBCEB8686B65E32B9E +:101930008417A1DFCBF978CDC2B537D539E3A4A29E +:10194000EA9E6709A76CEE1778786FB874C156F4F1 +:101950007FBF8AEA8E38714BFF5D5C37EA5781EBB7 +:10196000A9239B54B68F11EFEB87B6326E2C603EE5 +:101970004E6C522B1339F652D6E1B3EE4508FC817A +:10198000F0323199E77D5987F03BA8D87C8EDBFA9D +:10199000F2A79F117C2EAE82B44E38AE7B4786E212 +:1019A000CAF12ADC13BEEF0FD7741FA7F95F968127 +:1019B000F6E9D6C3EA8E5AB6D3D9F3B4D9E3E093A5 +:1019C000D717EF21FA7013E8E4D7A231EC531E6069 +:1019D000A30A941FF085FF8AF75B8AFD00F6FDB12C +:1019E000D1A4827D7F4DE27AC2C54FEFBA7D3052DD +:1019F0004EE79DB06FDFC6EDF14FD0F8955E08D091 +:101A0000FA4097C2B4BEA4B8CFE0B687BDA91F44C0 +:101A1000494E7B0D8945B4B97BFDDD7C6FA9BC8047 +:101A200071D3A837BE85FDD1AD7E2DC967E034C71F +:101A300011DEAFF880F46E62D76F2A087FFF382A74 +:101A4000EA9A01DD195FFB6194CFEDD5E6D446FA41 +:101A50006E75B34A150F78AAE534CB6DA2C967F845 +:101A6000701D132D12F3F9BD266F9AE679529D92DF +:101A700069DE27DFC3B9ABF3D9777EBBB2EDC83DD2 +:101A80007EA479BD9FF4622F4CDD42FC49CE883C98 +:101A9000957B5CBC439C577B53B7D6299CCF52B9EE +:101AA000DEAE9C31CC12A41E9A89FF3DE55E9351B7 +:101AB00045C449959EA484F406BAC5BD8C81A2C4D0 +:101AC00020E9F300EA3DC749E5E23ED27865B93145 +:101AD0009433DF78CB6D75E4CF5E680A30BEEF3BA0 +:101AE000F1177712BE6F93DFFAEE23145755A92C26 +:101AF000CF016FCFAB1407259B02BCDE138B54F0D4 +:101B0000933F28BFF3418AB3E1E846C8D5D7899807 +:101B1000B0D3892A61F7D2231B390E189764E6B334 +:101B2000597144223CE68BD9792791678A58EE6C2B +:101B300062E377380F7545B7C8A3466256BE490EB3 +:101B400026592F6F083C48F66F2A5E477CBCE68C0E +:101B5000335EBEC2152FBBF351FF1BB5F21156DE2B +:101B6000C9D6CB626BCC44B3E5A757FAD2420F7B00 +:101B70002AB5FAB9F6FDCF167E9EEAF5F33DB21707 +:101B80007B35EE179B6FEF2E433A2FF786F9F9C797 +:101B9000561F9672BF1B5979AB5F677F321D26BAFD +:101BA0006E3FE2D68BA16881E33CB1D759D4D226EF +:101BB000EEDF9D618F0C6B82D3ED7C36C254301703 +:101BC000EF677AC53DB7A7AC759EA075FA284F267A +:101BD000D6F76CAFCEED73BD75DC6EEA00510FB079 +:101BE000FDC355E81F900FD12AD1277F40F22F2D3A +:101BF000BF93F364BEB0A291BDFBAB4633528E7F60 +:101C00009828EAF9C55DE4F72B82AC8FEE7DADE94B +:101C1000F0E4DDD7E6961DEC77CEE23CC47FF433EA +:101C200077B31F42BFC0F36E54EFE07598E897D8C2 +:101C30002FF47CED76F60B5E203D77FB81D2A4B0CD +:101C4000EF842EF277F63DA159BF80F3A4719EA7D1 +:101C5000D0AF537F00FD00CD33D0F2FA9FD3BCEF5D +:101C6000BD5FC0F7A22636BDC27EE185B3E8B32FC3 +:101C7000A35FB0EDF0B5139123B9F17C56CEEB6FB5 +:101C80003F26F8A181E0EB86789E38F162E50CE60C +:101C900085E198B4327D87A83BAACC8779EB8E4941 +:101CA0008F416981BE492566D51D81EA8E76FD3159 +:101CB000A7EE58E0AC3BAAE914E39BB45577BC6DA2 +:101CC000ADA83BAA05D3C1EC3AEC7A633F3DAACC60 +:101CD000D6E7EFEC48ECEA68CAD6197549D4C15F7B +:101CE0008A985FA6E7505ECAE7BFBB4E69D723114B +:101CF000DE49899CFA66033EF79766EB5FEE7AA6AB +:101D00007D2FA3419D3E328C7CE9BBC3CFF8C15EE1 +:101D10005FDFA37FF26AA23C7B1FC0AE77DAF54C8F +:101D2000BBEE89EB1ECB5D373C0EEC77E031FF61FB +:101D30003ADFDCEBFD5E24717F47459E755F607D79 +:101D4000711D58F41177913DBF66F1D11EF7906572 +:101D50008FCB5591DF866295E39DB687822013CEA7 +:101D60002E528F905D6C81E90EE26F5F48E0BCD42B +:101D7000012FFBC9A31D3ACBAF4235F93E44C597AD +:101D800003C66E24933AAE1553FEA93B6A1EEDE0DE +:101D9000758CDEB29ED681B89DFCDDAF6BBF5ACE8E +:101DA000F57EBAF75442F19FB198F220CF77E4BFA5 +:101DB000AFD4BAF8CC7A9EB7C803149FA502C6B3B5 +:101DC0007CAFF80985E9752309B391EF2F45D5520A +:101DD000A223EEA7F6054FB2BC5A6B7D2B38AF5746 +:101DE000943F0E7CA643C4AD6B91968A743ED39605 +:101DF000F801AD9B72A561D66311DF3D4F7E52F8AD +:101E0000AF7B3CABB279B01239F13C8D87A39242E3 +:101E1000E7A3CFD21B3B4E7CBBCD7C81E48EF2305E +:101E2000697EFB1E903DFF4B961C921DE68B34EEA7 +:101E3000756B9E062D19213B6C48A03E486C3FAE49 +:101E40003ABCD00BB7BEDAFA365B87B7F450D2444F +:101E5000BD16F5EA755EEF93FA718F44F5F6C4E1AD +:101E600061FAF612EBDD57B69B6FD2BA4BDAE2FF9E +:101E70004E747FBDEB76BE177CA1F7385A17F784F6 +:101E8000A98E3F1010B8F9E188E1F0778B3A857C94 +:101E900016750ABC742DEACC14DF2F35F8DE37C076 +:101EA000DD8CA36DFF34DA9BF8FEA9DAECF7A95EAE +:101EB00098A47AD07CEBF0EEDBC179DDBEAA363F88 +:101EC000F91FF46F25D41FA832C3B9EB4815093D9B +:101ED0004F2E12790BCAA72573EE939776CABC9F33 +:101EE000F62AC890EEF882A2EEE643C3D5F1FCF1E3 +:101EF00099CD7CBF189F4F528AE18A4E5DC4E5E5BB +:101F00000698146F56C581ECDBA765BFA73A6A7BBC +:101F1000550FDFB79C8F8E1CB6BF4FF0F737766A30 +:101F20004C572DF738F200E7E39B9B2FFDC4B7DA3F +:101F3000F9F9A65E30DF84DDB9F9B5CAE2D7D3A1DD +:101F40002FF2FEE08376B6339F86FBC47675A7F04A +:101F50002F72D0844411F9A8382248CAB3F700D5AB +:101F6000A16D3ECB9AE0B3ACF5F077BE2A0312D751 +:101F7000115F12CC17371FD04F00F9891F3D7AA887 +:101F80009CF0692BF6C3C27F800FDB073A845C6C40 +:101F90003B5D073F0D8AFCB7F3BC70FB53BB7DD89C +:101FA000CA3FBB9F4B5D01E13F7470F0BDC8FAFDB5 +:101FB000C291C146C607787E26E95E4C67656D0111 +:101FC000F52F771DD15D3F74D709DDF5C1ACDE98E3 +:101FD0007E5AE73BDAC9E4C7F3E88BDD0E5BF6D641 +:101FE000DFEBCF6B77C368EF24BF8116334975A34E +:101FF000BDA1E930EBCDF13719172BCFCB06E14B63 +:10200000451172EE5C34CD72EC6A3681EA4DC3BD87 +:102010001BBE9D4BF781B6C4573A514F0AB5499341 +:10202000E8042193A4F3676D99D9930F370D587E77 +:10203000E4EDB6F86EFA8EAEAD93FC4F45CC3DD4D0 +:10204000BF50BF359F3D2936EF2EDA9E4E0A7B6A80 +:10205000DEC1F63452D5C3386BE4A73221A92C8EE9 +:10206000B4EC69A4E534DBBB6D5769DBFF340BBB13 +:10207000A03C029DDFC55526FB8D6F5AF6A4A09D9E +:10208000903DF92C7B2AD6B2E3293FDE4E7CC6E791 +:102090004AD5347F57DC6CD91FD95390EE0F03E338 +:1020A0008001B43BCA8BB8EDABB5469C9B8FB7257E +:1020B0001EEE247CB1683DE7E507AAFEB38CF18BE8 +:1020C000A5FF59BCDBC8E7F9D9418F41F6D04000E4 +:1020D000BA316B07F6BE57CFC89041D1AC9991B8D1 +:1020E000BD71A690DBD69900B7E64C19B79199104F +:1020F000B76D335772DB3E53C96D7406EDE07AB4A9 +:1021000087996A6E3B67AEE5B66B6619B7B199EB16 +:10211000795CF7CC0A6ED7CE7C94DB9B665AC43CC4 +:1021200075625F79EC81CA6097C11E8C2414911D81 +:102130007CE655F6EF9ACA779452A1555C27F229AE +:10214000D36C0F479A85BFEF0A0A39B9EDE1EDB6B6 +:10215000C4AFF2D9C32CBE554023FEAB60FDB9F02D +:1021600003E29FDFD0F736EE55C326EB19E293D397 +:1021700024CF4BC509B33873B1CA78D4C699238B21 +:102180001067566771E6408B88CB52077C1CBF6D89 +:1021900095C4FDB22BDB13FFC5F609224F94B8C5D9 +:1021A000AF116E4E853AC341CAEBED9581F20588B9 +:1021B000433EE0752A71719FF502EDF95444F87DB4 +:1021C0007B7C039CF4F45C048EF935FDB3657EBF23 +:1021D000507AA9E7ACB75DF8054DF8855455CF2086 +:1021E000D7A55D7EC13E67911F0EBFB0B4CBF20B89 +:1021F000969D975689F3B294FC02F2675997ED17B2 +:102200009CE7AC62E390988D432CBF1013DF216EE6 +:10221000779CB3286E3FE4E062D4A3E55D79700853 +:102220009FE739E75C5F4D6D847E4B103A03115296 +:10223000CFE2197DAD91E7DC49698D6C07C79576D2 +:10224000C8CDAF5CB49D85EC73C7E473C73DCEB613 +:10225000B781E3DD629FD639741CF76FE6D85B97D0 +:1022600026CE233C7F6EA27DBAEDAD75B19988E78D +:1022700059E727BB04DEFFF11A0BF722AE34828C3C +:10228000EFF3E2864F92FC9AC4EF341E43FFD31162 +:102290004BA6149DEDFC9334EFEAE8944C79A01B17 +:1022A0009B475FA69208DAE9A7BA9A2EDD4E9BDB20 +:1022B000AC7ADFCE3271D9D96ACFA7FF362EB2ED14 +:1022C000C03DEEE16A73433E7E3C63F1A36FD0D321 +:1022D0004D17FE6CBD38AE2C65FC93C7DF9AC66502 +:1022E000F1B717863F8EE33948723F07FE18CE27B5 +:1022F000FFF9F0C778D72CFE182339B5D60BFCF1BF +:102300004C179C33BEB9645C1139C97CBB545CF179 +:1023100050D7B971C5B7BB84DF54B469F61FC597F0 +:10232000882BDC7E02F1C33F317F0C71EEDABF37C0 +:10233000E10B9439E717FA99EFD338C20D7479ECB1 +:1023400048B02D29B11DC49FA0E7A3E612D6A3CBA8 +:10235000650F88137FD895D33F9F5D5CF0B8C94D5A +:102360009C07B4EB99BF0F1437507E64A75FB45F2E +:102370002A283E42ED58AFC843EFB7F27E635EE0D5 +:10238000FA41BF54601C91E8BBC569916FEF594E8B +:1023900079CFDF76D9BF97ECB9817F77037FEDA83E +:1023A0009BCEBF2E71CF97487DC8F7C1AB34CEA36B +:1023B0005B7CA174109DD343CBFC8C03873A8E1EAB +:1023C000BA93F2321D220F860A51FD713A7F11D65F +:1023D00034E79C0B3228A7293F3F4877DB19746C00 +:1023E00010F7A035F1BE348AF17B6EDDCEB8DBD1BB +:1023F000072B5F6AFF3EB070CD7ADB4E988E6D275B +:102400008545939A96E36F067B9DBFFF76B772ED85 +:102410007D71BA9B3C5AEFE1FAC5BE1A2540F5948E +:102420007D7522CB3E5CE389E5AB8F5F1B931C7906 +:102430006DBBBE5D1011EB9A6FBE01D77A7C7ADC62 +:10244000243D1DD6D371FE1D725DB994CCC93B7B72 +:10245000AD79862423D38ACC1C2A12E785AF2A09BA +:102460001EC203A1EDD7138FFD553D703A48F737D3 +:1024700092F006B6A1523591CEE38796C7841F1A13 +:10248000F24EC6588ED77938DF8B982A6F9E6C61D2 +:102490004CF8E9E19A23BCBE24F285EA55EE7101BD +:1024A0006B5C813ACAF58E7DB5DFD4695FFBE807C6 +:1024B0003757A07CBBFFFBC1DD41D2DFBB394F33B7 +:1024C00046F91AF4A705D71C8BB521DDFD372A1A6A +:1024D000EDA343AEDA4DEB1A8D82C17500975E9481 +:1024E000AC51025C2F353D7C07D4AD2705C554198E +:1024F000213D9CF20BFD107A16B4F4E68021EA3EF1 +:1025000007A2A27E65CB2FE77D80EAD267A30AC728 +:102510002576FD8A6A3DF970DC7ECB2EFB2DBB440F +:102520009CCA7587D9F78B337CEEEC6FC984E99C24 +:1025300029D2FC468CE81E75AE6B6FD39403971CB2 +:1025400058F1A2DFBA8CEF5A9FD02FE5A95FB03FB8 +:102550002D52A6F8BC2A5A7D8AFDE97DD67ABA9A10 +:1025600081F759BCD2F2DB713322E8FDA5C30F48D5 +:10257000D7BC6A7AE95CB855DC49F0368BBA5D8124 +:102580000A4606F97CA022C8F79ACA565A75BA7547 +:10259000E25E857D2FBC22EEBC1716829CDF0954BB +:1025A0008B7B59B97D90379EF3FEDBCE5F1E7EEEAE +:1025B000440EBD2FC59CF7C7CFF7FDEF7BD3CF9D52 +:1025C00040FD1A35CE6D87B6BCEEED6D667ED9FA4C +:1025D00068EB6788B6D838FFF763A178DEFACC31AC +:1025E000CB0ECEE7CFCA7CF11EC245F7AD893BF0DA +:1025F000D103967D3E1013F94F75F119CEAB1DB482 +:10260000EE5F1D0CC086EFE499371353797C56FFBB +:102610009D38C2D69FB97C380F8E5813B5E2104F43 +:1026200080CEF151A3ED59AA47BEABA93AE4F80117 +:10263000779EDDC61105DD76BEEF3DC65125C12969 +:10264000A1B72B9D71871B070C2BE90D64E7C375A0 +:10265000AAED9FD88F5CFD6CE1D7938C939252EEDC +:10266000B9B93F7307D30DB9F2EC50EEFCDDCAFEE9 +:1026700018F07A42FA9929BA671E8A29E2DED6A8AA +:1026800009B9F76EC63CBF9C3965FDFB031B77B0EB +:102690003EEF9FE2DFD3C0172077FEBD1FDBCCBF2C +:1026A0002F399FDC67FD7A5875E4DF2ED62EFE2584 +:1026B00066D5B7031020BB380BF770DD1D46638E5F +:1026C000F3882B100BF8C8167FB84D6595757449C3 +:1026D000597B817651D73F9B98F58B0A7D67589F30 +:1026E00055D2AD0A8AC721C3BF53B4EF959E855F0B +:1026F000F2BCC9A7246916675D89E13EFDFE712918 +:10270000A99CE6A1D6BDFE2560F0F31A88737B353F +:10271000F4705B07A3DC5E0393DCD6C314B70D70C3 +:1027200086DB15A0CB34C9F560CAC0573513DCBFB2 +:102730000192DCB640E2FD53B8FEFE8AED2B385E16 +:10274000B4FD87C5279BCF79EC9D71A4CD0F9BEF7E +:10275000FF48CEFA02EC3915127EB87D6586F53C4D +:10276000181438D98EAF6D3AF3E1DECB85CF6C5CAF +:10277000F97FE7ADB141E048000000000000000033 +:1027800000000018000000000000000000000040F1 +:102790000000000000000000000000280000000011 +:1027A0000000000000000010000000000000000019 +:1027B00000000020000000000000000000000010E9 +:1027C0000000000000000000000000080000000001 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:102860000000000000000000000000000000000068 +:102870000000000000000000000000000000000058 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E0000000000000000000000090000010000048 +:1028F0000000000800009008001000000000000226 +:1029000000009000001000000000001000009DA8D2 +:10291000000000000000000880000000000000002F +:102920000000000080000000000000000000000027 +:10293000800000000000000000000000000091A0E6 +:102940000000000000000008000093C00001000427 +:1029500000000001000093C8000000000000000219 +:10296000000093D00000000000000008000093D495 +:102970000000000000000002000094980000000029 +:1029800000000008000093D80008000000000008C4 +:1029900000009B3800400000000000400000941838 +:1029A0000008000000000008000094580008000023 +:1029B00000000008000094A800C800000000009873 +:1029C000000096380098000000000028000096786B +:1029D00000980000000000280000C0000540003002 +:1029E000000005400000CB200008000000000001AE +:1029F0000000CB21000800000000000100002008BA +:102A00000010000000000010000020000000000086 +:102A10000000000800009D600008000000000002A7 +:102A200000009DA000000000000000010000000068 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50008000000000000000000000008000000076 +:102A600000000000000000008000000000000000E6 +:102A700000000000800000000000000000000000D6 +:102A80008000000000000000000000008000000046 +:102A900000000000000000008000000000000000B6 +:102AA00000000000800000000000000000000000A6 +:102AB0008000000000000000000000008000000016 +:102AC0000000000000000000800000000000000086 +:102AD0000000000080000000000000000000000076 +:102AE0008000000000000000000000000000000066 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B20000000000000000000800000000000000025 +:102B30000000000080000000000000000000000015 +:102B40008000000000000000000000000000000005 +:102B500000000000000000008000000000000000F5 +:102B600000000000800000000000000000000000E5 +:102B700080000000000000000000000000000000D5 +:102B80000000000000000000000000000000000045 +:102B90000000000000000000000000000000000035 +:102BA0000000000000000000000000000000000025 +:102BB0000000000000000000000000000000000015 +:102BC00000000000000012C800800000000000802B +:102BD0000000000100000000000000000000A00054 +:102BE000071000000000071000001EC800000000D1 +:102BF000000000080000AEC000080000000000084F +:102C00000000AE4000080000000000080000AE8098 +:102C1000000800000000000800002008001000006C +:102C2000000000100000200000000000000000086C +:102C30000000A01007100040000000400000AF405E +:102C400000080000000000010000AF410008000083 +:102C50000000000100001ED0000000000000000184 +:102C600000001ED8000000000000000200001EDA74 +:102C70000000000000000002000012B00008000088 +:102C800000000008800000000000000000000000BC +:102C90008000000000000000000000008000000034 +:102CA00000000000000000008000000000000000A4 +:102CB0000000000080000000000000000000000094 +:102CC0008000000000000000000000008000000004 +:102CD0000000000000000000800000000000000074 +:102CE0000000000080000000000000000000000064 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D100000000000000000000000000000000000B3 +:102D20000000000000000000000000008000000023 +:102D30000000000000000000800000000000000013 +:102D40000000000000000000000000000000000083 +:102D50008000000000000000000000008000000073 +:102D600000000000000000008000000000000000E3 +:102D700000000000800000000000000000000000D3 +:102D80000000B00000180000000000180000B300B0 +:102D900000400000000000400000B30000400002BE +:102DA000000000010000B30100400002000000002C +:102DB0000000800000400000000000408000000093 +:102DC000000000000000000000008000000800403B +:102DD000000000040000800400080040000000041F +:102DE0000000BB0000280000000000280000BC40DC +:102DF00000100000000000100000880000800000AB +:102E00000000008000008800000800800000000230 +:102E100000008C00002000000000002000002008BE +:102E20000010000000000010000020000000000062 +:102E30000000000800001108000800000000000861 +:102E4000000011680008000000000008000011A840 +:102E500000080000000000080000127000080000D8 +:102E600000000001000012710008000000000001D5 +:102E700000008D000010000400000004000013207A +:102E80000030001800000010000013280030001867 +:102E900000000002800000000000000000000000B0 +:102EA000800000000000000000000000000011E8A9 +:102EB0000000000000000001800000000000000091 +:102EC0000000000080000000000000000000000082 +:102ED00080000000000000000000000080000000F2 +:102EE0000000000000000000800000000000000062 +:102EF0000000000080000000000000000000000052 +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000000000000B1 +:102F200000000000000000000000000000000000A1 +:102F30008000000000000000000000008000000091 +:102F40000000000000000000000000000000000081 +:102F500000000000000083080080000000000080E6 +:102F60000000000100000000000000000000200838 +:102F70000010000000000010000020000000000011 +:102F80000000000800008D1000080000000000088C +:102F900000008D7000080000000000080000845050 +:102FA000046000280000046000008EA000080000FB +:102FB0000000000100008EA10008000000000001D8 +:102FC0000000840800080000000000080000844899 +:102FD000000000000000000100008DF40008000067 +:102FE0000000000200008DF6000800000000000252 +:102FF00000008E04001000000000000480000000AB +:103000000000000000000000800000000000000040 +:103010000000000080000000000000000000000030 +:1030200000000000000000000000000000000000A0 +:103030000000000000000000000000000000000090 +:103040000000000000000000000000000000000080 +:103050008000000000000000000000008000000070 +:103060000000000000000000000000000000000060 +:1030700000000000800000000000000000000000D0 +:103080008000000000000000000000008000000040 +:1030900000000000000000008000000000000000B0 +:1030A00000000000000030000040000000000008A8 +:1030B00000003008004000000000002800003390AD +:1030C00001C00010000000080000320000200000D5 +:1030D0000000002000003720000000000000000871 +:1030E0000000102006200038000000080000A000AA +:1030F000000000000000200000003EA900000000C9 +:103100000000000100003EC80000000000000002B6 +:1031100000001C4000E000080000000880000000E3 +:103120000000000000000000000040000008000057 +:103130000000000100004001000800000000000144 +:103140000000404000080004000000020000406051 +:103150000008000400000004000040000008000017 +:10316000000000040000400400080000000000040B +:10317000000040400000000000000008000040483F +:1031800000000000000000080000800000000000B7 +:103190000000001000005040000100040000000189 +:1031A0000000500000000000000000200000500857 +:1031B00000100000000000040000500C001000008F +:1031C00000000001000052C70000000000000001E4 +:1031D000000052C6000000000000000100003000A6 +:1031E0000030001800000004000030040030001817 +:1031F0000000000400003008003000180000000249 +:103200000000300A00300018000000020000300CFE +:1032100000300018000000010000300D00300018E0 +:10322000000000010000300E003000180000000116 +:1032300000003010003000180000000400003014BE +:103240000030001800000004000050000100008061 +:103250000008000400005004010000800008000481 +:103260000000000A0000000000000000000050689C +:103270000100008000000001000050690100008092 +:10328000000000010000506C0100008000000002FE +:103290000000506E0100008000000002000050702D +:1032A0000100008000000004000050740100008054 +:1032B00000000004000050660100008000000002D1 +:1032C0000000506401000080000000010000506018 +:1032D0000100008000000002000050620100008038 +:1032E00000000002000050500100008000000004B7 +:1032F00000005054010000800000000400005058FD +:1033000001000080000000040000505C010000800B +:10331000000000040000507C01000080000000015B +:103320000000507D010000800000000100004018F6 +:103330000010000000000004000040900010000099 +:10334000000000040000409800100000000000048D +:1033500000004110000000000000000200004112C7 +:103360000000000000000002000041140000000006 +:1033700000000002000041160000000000000002F2 +:1033800000006040000800000000000200006042F1 +:103390000008000000000002000060440008000077 +:1033A0000000000400006080000800000000000829 +:1033B000000060C00040000800000008000060003D +:1033C0000008000000000002000060020008000089 +:1033D000000000010000600400080000000000027E +:1033E0000000634000080000000000080000638047 +:1033F00000080000000000040000638400080000D2 +:1034000000000001000063C000080000000000028E +:10341000000063C400080000000000020000640017 +:103420000008000000000004000070000010000010 +:103430000000000400007004001000000000000400 +:103440000000700800100000000000040000700080 +:1034500000080000000000020000700200080000E8 +:1034600000000001000070040008000000000002DD +:1034700000007040000800000000000200007044DE +:103480000008000000000002000070460008000074 +:10349000000000020000764800080000000000085C +:1034A000000070800008000000000002000070842E +:1034B00000080000000000020000768800080000FC +:1034C000000000080000804000080000000000012B +:1034D0000000804100080000000000010000804260 +:1034E0000008000000000001000080430008000008 +:1034F0000000000100008000000800000000000241 +:1035000000008002000800000000000100008004AC +:103510000008000000000002000080C00008000059 +:1035200000000002000080C200080000000000024D +:10353000000080C40008000000000002000080803D +:103540000008000000000001000080810008000069 +:10355000000000010000808200080000000000015F +:10356000000080830008000000000001000080844B +:103570000008000000000001000080850008000035 +:10358000000000010000808600080000000000012B +:10359000000060000008000000000002000060025F +:1035A00000080000000000010000600400080000A6 +:1035B000000000020000604200C00018000000028D +:1035C0000000604000C00018000000020000604CD5 +:1035D00000C00018000000080000604400C000188F +:1035E000000000080000605700C000180000000143 +:1035F0000000605400C00018000000020000605687 +:1036000000C0001800000001000066400008000033 +:1036100000000008000066800008000000000008AC +:10362000000066C000080000000000080000D94249 +:1036300000180000000000020000DE400000000052 +:10364000000000000000E000000000000000000496 +:103650000000DD4000000000000000040000DD4428 +:1036600000000000000000040000DD480000000031 +:10367000000000040000DD4C000000000000000419 +:103680000000DD5000000000000000040000DD54D8 +:1036900000000000000000040000DD5800000000F1 +:1036A000000000040000DD400000000000000020D9 +:1036B0000000DA0000000000000000040000DA0052 +:1036C00000000000000000680000BB600000000077 +:1036D000000000000000D000000000000000000416 +:1036E0000000B0C000000000000000040000B0C4F2 +:1036F00000000000000000040000B0C8000000004E +:10370000000000040000B0C0000000000000001035 +:103710000000D6B000000000000000040000D6B495 +:1037200000000000000000040000D6B80000000007 +:10373000000000040000D6BC0000000000000004EF +:103740000000D6B000000000000000100000D348C8 +:1037500000000000000000080000D3580000000036 +:1037600000000080000000100000000000000000C9 +:103770000000D35800000000000000080000000016 +:08378000060205000000000034 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex new file mode 100644 index 000000000000..aef9aa622420 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex @@ -0,0 +1,15456 @@ +:1000000000005310000000680000070C000053803F +:100010000000318000005A90000000B000008C18F1 +:100020000000C13400008CD0000000D800014E0850 +:100030000000F1F000014EE800000074000240E012 +:100040000000525C00024158000000B8000293B862 +:100050000001213C0002947800000FFC0003B5B8B9 +:10006000000000040003C5B8020400480000000FAF +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040258000000360204025C000000365F +:10017000020402600810000002040264081000007B +:1001800002040004000000FF02040008000000FF59 +:100190000204000C000000FF02040010000000FF39 +:1001A000020400140000007F02040018000000FF99 +:1001B0000204001C000000FF02040020000000FFF9 +:1001C000020400240000003E020400280000000099 +:1001D0000204002C0000003F020400300000003F39 +:1001E000020400340000003F020400380000003F19 +:1001F0000204003C0000003F020400400000003FF9 +:10020000020400440000003F020404CC000000018E +:1002100002042008000002110204200C0000020069 +:10022000020420100000020402042014000002193D +:100230000204201C0000FFFF020420200000FFFF3A +:10024000020420240000FFFF020420280000FFFF1A +:1002500002042038000000200604203C0000000FAB +:1002600002042078000000210604207C0000000F1A +:10027000020420B800000001060420BC0000000FAA +:10028000020420F800000001060420FC0000003FEA +:10029000020421F800000001060421FC0000000F08 +:1002A0000204223807FFFFFF0204223C0000007F07 +:1002B0000204224007FFFFFF020422440000003F27 +:1002C00001042248000000000104224C000000004C +:1002D000010422500000000001042254000000002C +:1002E00001042258000000000104225C000000000C +:1002F00001042260000000000104226400000000EC +:1003000001042268000000000104226C00000000CB +:1003100001042270000000000104227400000000AB +:1003200001042278000000000104227C000000008B +:10033000020422C00000FFFF020422C40000FFFFED +:10034000020422C80000FFFF020422CC0000FFFFCD +:100350000C042000000003E80A0420000000000153 +:100360000B042000000000030605400000000D0003 +:100370000205004400000020020500480000003291 +:1003800002050090021500200205009402150020CD +:1003900002050098000000300205009C08100000D3 +:1003A000020500A000000036020500A40000003095 +:1003B000020500A800000031020500B000000004A2 +:1003C000020500B400000005020500C000000000A6 +:1003D000020500C400000004020500D40000000172 +:1003E00002050114000000010205011C00000001CB +:1003F00002050120000000020205020400000001C5 +:100400000205020C0000004002050210000000403E +:100410000205021C00000020020502200000001C52 +:100420000205022400000020060502400000000A28 +:1004300004050280002000000205005000000007B3 +:1004400002050054000000070205005800000000EB +:100450000205005C000000080205006000000001C9 +:100460000605006400000003020500D80000000635 +:100470000205000400000001020500080000000160 +:100480000205000C00000001020500100000000140 +:100490000205001400000001020500180000000120 +:1004A0000205001C00000001020500200000000100 +:1004B00002050024000000010205002800000001E0 +:1004C0000205002C000000010205003000000001C0 +:1004D00002050034000000010205003800000001A0 +:1004E0000205003C00000001020500400000000180 +:1004F000020500E00000000D020500E80000000019 +:10050000020500F000000000020500F800000000F5 +:10051000020500E40000002D020500EC00000020B0 +:10052000020500F400000020020500FC000000208D +:10053000020500E00000001D020500E800000010B8 +:10054000020500F000000010020500F80000001095 +:10055000020500E40000003D020500EC0000003050 +:10056000020500F400000030020500FC000000302D +:10057000020500E00000004D020500E80000004018 +:10058000020500F000000040020500F800000040F5 +:10059000020500E40000006D020500EC00000060B0 +:1005A000020500F400000060020500FC000000608D +:1005B000020500E00000005D020500E800000050B8 +:1005C000020500F000000050020500F80000005095 +:1005D000020500E40000007D020500EC0000007050 +:1005E000020500F400000070020500FC000000702D +:1005F0000406100002000020020600DC00000001DA +:100600000406020000030220020600DC00000000D5 +:100610000718040000AD0000081807D800050223E1 +:10062000071C000029920000071C8000312A0A657F +:10063000071D000034A316B0071D80002E7A23D9B1 +:10064000071E000003502F78081E07F03F02022506 +:10065000021800BC0000003001180000000000007B +:10066000011800040000000001180008000000004C +:100670000118000C0000000001180010000000002C +:100680000118001400000000021800200000000102 +:1006900002180024000000020218002800000003D5 +:1006A0000218002C000000000218003000000004B6 +:1006B0000218003400000001021800380000000099 +:1006C0000218003C00000001021800400000000475 +:1006D0000218004400000000021800480000000159 +:1006E0000218004C00000003021800500000000037 +:1006F0000218005400000001021800580000000415 +:100700000218005C000000000218006000000001F8 +:1007100002180064000000030218006800000000D6 +:100720000218006C000000010218007000000004B4 +:100730000218007400000000021800780000000495 +:100740000218007C00000003061800800000000270 +:10075000021800A400007FFF021800A8000003FF99 +:1007600002180224000000000218023400000000F9 +:100770000218024C00000000021802E4000000FF12 +:100780000618100000000400021B8BC000000001CE +:10079000021B800000000034021B80400000001893 +:1007A000021B80800000000C021B80C000000020A3 +:1007B0000C1B8300000864700A1B830000000157B3 +:1007C0000B1B83000000055F0A1B83400000000034 +:1007D0000C1B8340000002260B1B8340000000011D +:1007E000021B838000086470021B83C00000022685 +:1007F000021B1480000000010A1B1480000000008E +:10080000021B944000000001061B944800000002F7 +:10081000061A1000000002B3041A1ACC00010227C5 +:10082000061A1AD000000008061A2008000000C8A6 +:10083000061A200000000002041A1BF8009002288B +:10084000061A371800000004061A371000000002CC +:10085000061A500000000002061A500800000004AA +:10086000061A501800000004061A50280000000460 +:10087000061A503800000004061A50480000000410 +:10088000061A505800000004061A506800000004C0 +:10089000061A507800000002041A52C0000202B882 +:1008A000061A405000000006041A4068000202BA0E +:1008B000041A4040000402BC041A8000000102C077 +:1008C000061A800400000003041A8010000102C10F +:1008D000061A801400000003041A8020000102C2DE +:1008E000061A802400000003041A8030000102C3AD +:1008F000061A803400000003041A8040000102C47C +:10090000061A804400000003041A8050000102C54A +:10091000061A805400000003041A8060000102C619 +:10092000061A806400000003041A8070000102C7E8 +:10093000061A807400000003041A8080000102C8B7 +:10094000061A808400000003041A8090000102C986 +:10095000061A809400000003041A80A0000102CA55 +:10096000061A80A400000003041A80B0000102CB24 +:10097000061A80B400000003041A80C0000102CCF3 +:10098000061A80C400000003041A80D0000102CDC2 +:10099000061A80D400000003041A80E0000102CE91 +:1009A000061A80E400000003041A80F0000102CF60 +:1009B000061A80F400000003041A8100000102D02E +:1009C000061A810400000003041A8110000102D1FC +:1009D000061A811400000003041A8120000102D2CB +:1009E000061A812400000003041A8130000102D39A +:1009F000061A813400000003041A8140000102D469 +:100A0000061A814400000003041A8150000102D537 +:100A1000061A815400000003041A8160000102D606 +:100A2000061A816400000003041A8170000102D7D5 +:100A3000061A817400000003041A8180000102D8A4 +:100A4000061A818400000003041A8190000102D973 +:100A5000061A819400000003041A81A0000102DA42 +:100A6000061A81A400000003041A81B0000102DB11 +:100A7000061A81B400000003041A81C0000102DCE0 +:100A8000061A81C400000003041A81D0000102DDAF +:100A9000061A81D400000003041A81E0000102DE7E +:100AA000061A81E400000003041A81F0000102DF4D +:100AB000061A81F400000003041A8200000102E01B +:100AC000061A820400000003041A8210000102E1E9 +:100AD000061A821400000003041A8220000102E2B8 +:100AE000061A822400000003041A8230000102E387 +:100AF000061A823400000003041A8240000102E456 +:100B0000061A824400000003041A8250000102E524 +:100B1000061A825400000003041A8260000102E6F3 +:100B2000061A826400000003041A8270000102E7C2 +:100B3000061A827400000003041A8280000102E891 +:100B4000061A828400000003041A8290000102E960 +:100B5000061A829400000003041A82A0000102EA2F +:100B6000061A82A400000003041A82B0000102EBFE +:100B7000061A82B400000003041A82C0000102ECCD +:100B8000061A82C400000003041A82D0000102ED9C +:100B9000061A82D400000003041A82E0000102EE6B +:100BA000061A82E400000003041A82F0000102EF3A +:100BB000061A82F400000003041A8300000102F008 +:100BC000061A830400000003041A8310000102F1D6 +:100BD000061A831400000003041A8320000102F2A5 +:100BE000061A832400000003041A8330000102F374 +:100BF000061A833400000003041A8340000102F443 +:100C0000061A834400000003041A8350000102F511 +:100C1000061A835400000003041A8360000102F6E0 +:100C2000061A836400000003041A8370000102F7AF +:100C3000061A837400000003041A8380000102F87E +:100C4000061A838400000003041A8390000102F94D +:100C5000061A839400000003041A83A0000102FA1C +:100C6000061A83A400000003041A83B0000102FBEB +:100C7000061A83B400000003041A83C0000102FCBA +:100C8000061A83C400000003041A83D0000102FD89 +:100C9000061A83D400000003041A83E0000102FE58 +:100CA000061A83E400000003041A83F0000102FF27 +:100CB000061A83F400000003041A840000010300F4 +:100CC000061A840400000003041A841000010301C2 +:100CD000061A841400000003041A84200001030291 +:100CE000061A842400000003041A84300001030360 +:100CF000061A843400000003041A8440000103042F +:100D0000061A844400000003041A845000010305FD +:100D1000061A845400000003041A846000010306CC +:100D2000061A846400000003041A8470000103079B +:100D3000061A847400000003041A8480000103086A +:100D4000061A848400000003041A84900001030939 +:100D5000061A849400000003041A84A00001030A08 +:100D6000061A84A400000003041A84B00001030BD7 +:100D7000061A84B400000003041A84C00001030CA6 +:100D8000061A84C400000003041A84D00001030D75 +:100D9000061A84D400000003041A84E00001030E44 +:100DA000061A84E400000003041A84F00001030F13 +:100DB000061A84F400000003041A850000010310E1 +:100DC000061A850400000003041A851000010311AF +:100DD000061A851400000003041A8520000103127E +:100DE000061A852400000003041A8530000103134D +:100DF000061A853400000003041A8540000103141C +:100E0000061A854400000003041A855000010315EA +:100E1000061A855400000003041A856000010316B9 +:100E2000061A856400000003041A85700001031788 +:100E3000061A857400000003041A85800001031857 +:100E4000061A858400000003041A85900001031926 +:100E5000061A859400000003041A85A00001031AF5 +:100E6000061A85A400000003041A85B00001031BC4 +:100E7000061A85B400000003041A85C00001031C93 +:100E8000061A85C400000003041A85D00001031D62 +:100E9000061A85D400000003041A85E00001031E31 +:100EA000061A85E400000003041A85F00001031F00 +:100EB000061A85F400000003041A860000010320CE +:100EC000061A860400000003041A8610000103219C +:100ED000061A861400000003041A8620000103226B +:100EE000061A862400000003041A8630000103233A +:100EF000061A863400000003041A86400001032409 +:100F0000061A864400000003041A865000010325D7 +:100F1000061A865400000003041A866000010326A6 +:100F2000061A866400000003041A86700001032775 +:100F3000061A867400000003041A86800001032844 +:100F4000061A868400000003041A86900001032913 +:100F5000061A869400000003041A86A00001032AE2 +:100F6000061A86A400000003041A86B00001032BB1 +:100F7000061A86B400000003041A86C00001032C80 +:100F8000061A86C400000003041A86D00001032D4F +:100F9000061A86D400000003041A86E00001032E1E +:100FA000061A86E400000003041A86F00001032FED +:100FB000061A86F400000003041A870000010330BB +:100FC000061A870400000003041A87100001033189 +:100FD000061A871400000003041A87200001033258 +:100FE000061A872400000003041A87300001033327 +:100FF000061A873400000003041A874000010334F6 +:10100000061A874400000003041A875000010335C4 +:10101000061A875400000003041A87600001033693 +:10102000061A876400000003041A87700001033762 +:10103000061A877400000003041A87800001033831 +:10104000061A878400000003041A87900001033900 +:10105000061A879400000003041A87A00001033ACF +:10106000061A87A400000003041A87B00001033B9E +:10107000061A87B400000003041A87C00001033C6D +:10108000061A87C400000003041A87D00001033D3C +:10109000061A87D400000003041A87E00001033E0B +:1010A000061A87E400000003041A87F00001033FDA +:1010B000061A87F400000003041A880000010340A8 +:1010C000061A880400000003041A88100001034176 +:1010D000061A881400000003041A88200001034245 +:1010E000061A882400000003041A88300001034314 +:1010F000061A883400000003041A884000010344E3 +:10110000061A884400000003041A885000010345B1 +:10111000061A885400000003041A88600001034680 +:10112000061A886400000003041A8870000103474F +:10113000061A887400000003041A8880000103481E +:10114000061A888400000003041A889000010349ED +:10115000061A889400000003041A88A00001034ABC +:10116000061A88A400000003041A88B00001034B8B +:10117000061A88B400000003041A88C00001034C5A +:10118000061A88C400000003041A88D00001034D29 +:10119000061A88D400000003041A88E00001034EF8 +:1011A000061A88E400000003041A88F00001034FC7 +:1011B000061A88F400000003041A89000001035095 +:1011C000061A890400000003041A89100001035163 +:1011D000061A891400000003041A89200001035232 +:1011E000061A892400000003041A89300001035301 +:1011F000061A893400000003041A894000010354D0 +:10120000061A894400000003041A8950000103559E +:10121000061A895400000003041A8960000103566D +:10122000061A896400000003041A8970000103573C +:10123000061A897400000003041A8980000103580B +:10124000061A898400000003041A899000010359DA +:10125000061A899400000003041A89A00001035AA9 +:10126000061A89A400000003041A89B00001035B78 +:10127000061A89B400000003041A89C00001035C47 +:10128000061A89C400000003041A89D00001035D16 +:10129000061A89D400000003041A89E00001035EE5 +:1012A000061A89E400000003041A89F00001035FB4 +:1012B000061A89F400000003041A8A000001036082 +:1012C000061A8A0400000003041A8A100001036150 +:1012D000061A8A1400000003041A8A20000103621F +:1012E000061A8A2400000003041A8A3000010363EE +:1012F000061A8A3400000003041A8A4000010364BD +:10130000061A8A4400000003041A8A50000103658B +:10131000061A8A5400000003041A8A60000103665A +:10132000061A8A6400000003041A8A700001036729 +:10133000061A8A7400000003041A8A8000010368F8 +:10134000061A8A8400000003041A8A9000010369C7 +:10135000061A8A9400000003041A8AA00001036A96 +:10136000061A8AA400000003041A8AB00001036B65 +:10137000061A8AB400000003041A8AC00001036C34 +:10138000061A8AC400000003041A8AD00001036D03 +:10139000061A8AD400000003041A8AE00001036ED2 +:1013A000061A8AE400000003041A8AF00001036FA1 +:1013B000061A8AF400000003041A8B00000103706F +:1013C000061A8B0400000003041A8B10000103713D +:1013D000061A8B1400000003041A8B20000103720C +:1013E000061A8B2400000003041A8B3000010373DB +:1013F000061A8B3400000003041A8B4000010374AA +:10140000061A8B4400000003041A8B500001037578 +:10141000061A8B5400000003041A8B600001037647 +:10142000061A8B6400000003041A8B700001037716 +:10143000061A8B7400000003041A8B8000010378E5 +:10144000061A8B8400000003041A8B9000010379B4 +:10145000061A8B9400000003041A8BA00001037A83 +:10146000061A8BA400000003041A8BB00001037B52 +:10147000061A8BB400000003041A8BC00001037C21 +:10148000061A8BC400000003041A8BD00001037DF0 +:10149000061A8BD400000003041A8BE00001037EBF +:1014A000061A8BE400000003041A8BF00001037F8E +:1014B000061A8BF400000003041A8C00000103805C +:1014C000061A8C0400000003041A8C10000103812A +:1014D000061A8C1400000003041A8C2000010382F9 +:1014E000061A8C2400000003041A8C3000010383C8 +:1014F000061A8C3400000003041A8C400001038497 +:10150000061A8C4400000003041A8C500001038565 +:10151000061A8C5400000003041A8C600001038634 +:10152000061A8C6400000003041A8C700001038703 +:10153000061A8C7400000003041A8C8000010388D2 +:10154000061A8C8400000003041A8C9000010389A1 +:10155000061A8C9400000003041A8CA00001038A70 +:10156000061A8CA400000003041A8CB00001038B3F +:10157000061A8CB400000003041A8CC00001038C0E +:10158000061A8CC400000003041A8CD00001038DDD +:10159000061A8CD400000003041A8CE00001038EAC +:1015A000061A8CE400000003041A8CF00001038F7B +:1015B000061A8CF400000003041A8D000001039049 +:1015C000061A8D0400000003041A8D100001039117 +:1015D000061A8D1400000003041A8D2000010392E6 +:1015E000061A8D2400000003041A8D3000010393B5 +:1015F000061A8D3400000003041A8D400001039484 +:10160000061A8D4400000003041A8D500001039552 +:10161000061A8D5400000003041A8D600001039621 +:10162000061A8D6400000003041A8D7000010397F0 +:10163000061A8D7400000003041A8D8000010398BF +:10164000061A8D8400000003041A8D90000103998E +:10165000061A8D9400000003041A8DA00001039A5D +:10166000061A8DA400000003041A8DB00001039B2C +:10167000061A8DB400000003041A8DC00001039CFB +:10168000061A8DC400000003041A8DD00001039DCA +:10169000061A8DD400000003041A8DE00001039E99 +:1016A000061A8DE400000003041A8DF00001039F68 +:1016B000061A8DF400000003041A8E00000103A036 +:1016C000061A8E0400000003041A8E10000103A104 +:1016D000061A8E1400000003041A8E20000103A2D3 +:1016E000061A8E2400000003041A8E30000103A3A2 +:1016F000061A8E3400000003041A8E40000103A471 +:10170000061A8E4400000003041A8E50000103A53F +:10171000061A8E5400000003041A8E60000103A60E +:10172000061A8E6400000003041A8E70000103A7DD +:10173000061A8E7400000003041A8E80000103A8AC +:10174000061A8E8400000003041A8E90000103A97B +:10175000061A8E9400000003041A8EA0000103AA4A +:10176000061A8EA400000003041A8EB0000103AB19 +:10177000061A8EB400000003041A8EC0000103ACE8 +:10178000061A8EC400000003041A8ED0000103ADB7 +:10179000061A8ED400000003041A8EE0000103AE86 +:1017A000061A8EE400000003041A8EF0000103AF55 +:1017B000061A8EF400000003041A8F00000103B023 +:1017C000061A8F0400000003041A8F10000103B1F1 +:1017D000061A8F1400000003041A8F20000103B2C0 +:1017E000061A8F2400000003041A8F30000103B38F +:1017F000061A8F3400000003041A8F40000103B45E +:10180000061A8F4400000003041A8F50000103B52C +:10181000061A8F5400000003041A8F60000103B6FB +:10182000061A8F6400000003041A8F70000103B7CA +:10183000061A8F7400000003041A8F80000103B899 +:10184000061A8F8400000003041A8F90000103B968 +:10185000061A8F9400000003041A8FA0000103BA37 +:10186000061A8FA400000003041A8FB0000103BB06 +:10187000061A8FB400000003041A8FC0000103BCD5 +:10188000061A8FC400000003041A8FD0000103BDA4 +:10189000061A8FD400000003041A8FE0000103BE73 +:1018A000061A8FE400000007041A62C0002003BF7C +:1018B000061A1AF000000042061AAF0000000008E5 +:1018C000061AE00000000540061AD0000000007271 +:1018D000061AD24800000010061AD6B000000020F8 +:1018E000061AD47000000090061AD46800000002A6 +:1018F000061AA000000001C4061A30000000001003 +:10190000061A308000000010061A31000000001096 +:10191000061A318000000010061A33000000001281 +:10192000061A339000000070061AD4580000000216 +:10193000061AD34800000002061AD35800000020FF +:10194000061AA710000001C4061A3040000000105B +:10195000061A30C000000010061A314000000010C6 +:10196000061A31C000000010061A334800000012A9 +:10197000061A355000000070061AD46000000002FC +:10198000061AD35000000002061AD3D80000002027 +:10199000021AAE2000000000061A500000000002EB +:1019A000061A508000000012041A4000000203DFF3 +:1019B000041A63C0000203E1061A7000000000046C +:1019C000061A320000000008021AAE2400000000CF +:1019D000061A501000000002061A50C8000000123B +:1019E000041A4008000203E3041A63C8000203E576 +:1019F000061A701000000004061A322000000008C9 +:101A0000021AAE2800000000061A50200000000252 +:101A1000061A511000000012041A4010000203E7D9 +:101A2000041A63D0000203E9061A702000000004C3 +:101A3000061A324000000008021AAE2C0000000016 +:101A4000061A503000000002061A51580000001219 +:101A5000041A4018000203EB041A63D8000203EDD5 +:101A6000061A703000000004061A326000000008F8 +:101A7000021AAE3000000000061A504000000002BA +:101A8000061A51A000000012041A4020000203EFC1 +:101A9000041A63E0000203F1061A7040000000041B +:101AA000061A328000000008021AAE34000000005E +:101AB000061A505000000002061A51E800000012F9 +:101AC000041A4028000203F3041A63E8000203F535 +:101AD000061A705000000004061A32A00000000828 +:101AE000021AAE3800000000061A50600000000222 +:101AF000061A523000000012041A4030000203F7A8 +:101B0000041A63F0000203F9061A70600000000472 +:101B1000061A32C000000008021AAE3C00000000A5 +:101B2000061A507000000002061A527800000012D7 +:101B3000041A4038000203FB041A63F8000203FD94 +:101B4000061A707000000004061A32E00000000857 +:101B50000200A2A4000002090200A270000000001E +:101B60000200A274000000000200A2700000000049 +:101B70000200A274000000000200A2700000000039 +:101B80000200A274000000000200A2700000000029 +:101B90000200A27400000000020100B40000000175 +:101BA000020100B800000001020100CC00000001A9 +:101BB000020100D000000001020100DC0000000171 +:101BC0000201010000000001020101040000000107 +:101BD0000201007C003000000201008400000028A7 +:101BE0000201008C0000000002010130000000042E +:101BF0000201025C00000001020103280000000055 +:101C0000020160580000FFFF020160700000000741 +:101C10000201055400000030020100C40000000170 +:101C2000020100F800000001020100F000000001C4 +:101C3000020100800030000002010088000000283E +:101C400002010090000000000201013400000004C5 +:101C5000020102DC000000010201032C0000000070 +:101C60000201605C0000FFFF0201607400000007D9 +:101C70000201056400000030020100C800000001FC +:101C8000020100FC00000001020100F4000000015C +:101C9000020C100000000028020C200800000211B5 +:101CA000020C200C00000200020C201000000204B4 +:101CB000020C201C0000FFFF020C20200000FFFF90 +:101CC000020C20240000FFFF020C20280000FFFF70 +:101CD000020C203800000000020C203C00000037FD +:101CE000020C204000000021020C204400000020D3 +:101CF000060C20480000001D020C20BC0000000162 +:101D0000060C20C00000003F020C21BC00000001B6 +:101D1000020C21C000000001020C21C400000001DF +:101D2000060C21C80000001C020C223807FFFFFF30 +:101D3000020C223C0000007F020C224007FFFFFF44 +:101D4000020C22440000003F010C22480000000069 +:101D5000010C224C00000000010C22500000000089 +:101D6000010C225400000000010C22580000000069 +:101D7000010C225C00000000010C22600000000049 +:101D8000010C226400000000010C22680000000029 +:101D9000010C226C00000000010C22700000000009 +:101DA000010C227400000000010C227800000000E9 +:101DB000010C227C00000000020C22D80000FFFF72 +:101DC000020C22DC0000FFFF020C22E00000FFFFFB +:101DD000020C22E40000FFFF0C0C2000000003E8CE +:101DE0000A0C2000000000010B0C20000000000382 +:101DF000020C400800001011020C400C0000100002 +:101E0000020C401000001004020C401400001021CD +:101E1000020C401C0000FFFF020C40200000FFFFEE +:101E2000020C40240000FFFF020C40280000FFFFCE +:101E3000020C403800000046020C403C0000000C40 +:101E4000060C404000000002020C40480000001850 +:101E5000020C404C000000F0060C40500000001F37 +:101E6000020C40CC00000001060C40D00000003AFB +:101E7000020C41B800000001060C41BC0000000348 +:101E8000020C41C800000001020C41CC000000011E +:101E9000060C41D00000001A020C423807FFFFFF79 +:101EA000020C423C0000007F020C424007FFFFFF93 +:101EB000020C42440000003F010C424800000000B8 +:101EC000010C424C00000000010C425000000000D8 +:101ED000010C425400000000010C425800000000B8 +:101EE000010C425C00000000010C42600000000098 +:101EF000010C426400000000010C42680000000078 +:101F0000010C426C00000000010C42700000000057 +:101F1000010C427400000000010C42780000000037 +:101F2000010C427C00000000010C42800000000017 +:101F3000020C42D80000FFFF020C42DC0000FFFF51 +:101F4000020C42E00000FFFF020C42E40000FFFF31 +:101F50000C0C4000000003E80A0C400000000001E7 +:101F60000B0C400000000003060D400000000A00BA +:101F7000020D004400000032020D008C021500200A +:101F8000020D009002150020020D009408100000C0 +:101F9000020D009800000036020D00A000000000B5 +:101FA000020D00A400000004020D00A800000004BF +:101FB000060D00AC00000002020D00B80000000297 +:101FC000020D00C000000001020D00C80000000268 +:101FD000020D00CC00000002020D015C00000001B7 +:101FE000020D016400000001020D01680000000202 +:101FF000020D020400000001020D020C000000208E +:10200000020D021000000040020D0214000000400A +:10201000020D022000000003020D0224000000183F +:10202000060D028000000012040D0300001803FFDB +:10203000060D03600000000C020D004C00000001C2 +:10204000020D005000000002020D005400000000CC +:10205000020D005800000008060D005C000000049E +:10206000020D00C400000004020D00040000000185 +:10207000020D000800000001020D000C000000012C +:10208000020D001000000001020D0014000000010C +:10209000020D001800000001020D001C00000001EC +:1020A000020D002000000001020D002400000001CC +:1020B000020D002800000001020D002C00000001AC +:1020C000020D003000000001020D0034000000018C +:1020D000020D003800000001020D003C000000016C +:1020E000020D011400000009020D011C0000000A8D +:1020F000020D012400000000020D012C0000000070 +:10210000020D013400000000020D013C0000000B34 +:10211000020D014400000000020D0118000000291A +:10212000020D01200000002A020D012800000020FD +:10213000020D013000000020020D013800000020D7 +:10214000020D01400000002B020D0148000000209C +:10215000020D011400000019020D011C0000001AFC +:10216000020D012400000010020D012C00000010DF +:10217000020D013400000010020D013C0000001BA4 +:10218000020D014400000010020D0118000000398A +:10219000020D01200000003A020D0128000000306D +:1021A000020D013000000030020D01380000003047 +:1021B000020D01400000003B020D0148000000300C +:1021C000020D011400000049020D011C0000004A2C +:1021D000020D012400000040020D012C000000400F +:1021E000020D013400000040020D013C0000004BD4 +:1021F000020D014400000040020D011800000069BA +:10220000020D01200000006A020D0128000000609C +:10221000020D013000000060020D01380000006076 +:10222000020D01400000006B020D0148000000603B +:10223000020D011400000059020D011C0000005A9B +:10224000020D012400000050020D012C000000507E +:10225000020D013400000050020D013C0000005B43 +:10226000020D014400000050020D01180000007929 +:10227000020D01200000007A020D0128000000700C +:10228000020D013000000070020D013800000070E6 +:10229000020D01400000007B020D014800000070AB +:1022A000060E200000000800020E004C0000003264 +:1022B000020E009402150020020E00980215002064 +:1022C000020E009C00000030020E00A0081000006A +:1022D000020E00A400000036020E00A8000000302C +:1022E000020E00AC00000031020E00B4000000033A +:1022F000020E00B800000000020E00C40000000042 +:10230000020E00CC00000006020E00D80000000102 +:10231000020E014400000001020E014C0000000109 +:10232000020E015000000002020E02040000000133 +:10233000020E020C00000040020E021000000040DD +:10234000020E021C00000004020E02200000002009 +:10235000020E02240000000E020E02280000001BE4 +:10236000060E030000000012040E0280001B04177A +:10237000060E02EC00000005020E00540000000CE6 +:10238000020E00580000000C020E005C000000006D +:10239000020E006000000010020E00640000001039 +:1023A000060E006800000003020E00DC00000003BF +:1023B000020E000400000001020E000800000001EF +:1023C000020E000C00000001020E001000000001CF +:1023D000020E001400000001020E001800000001AF +:1023E000020E001C00000001020E0020000000018F +:1023F000020E002400000001020E0028000000016F +:10240000020E002C00000001020E0030000000014E +:10241000020E003400000001020E0038000000012E +:10242000020E003C00000001020E0040000000010E +:10243000020E004400000001020E01100000000F17 +:10244000020E011800000000020E01200000000032 +:10245000020E012800000000020E01140000002FEF +:10246000020E011C00000020020E012400000020CA +:10247000020E012C00000020020E01100000001FBF +:10248000020E011800000010020E012000000010D2 +:10249000020E012800000010020E01140000003F8F +:1024A000020E011C00000030020E0124000000306A +:1024B000020E012C00000030020E01100000004F3F +:1024C000020E011800000040020E01200000004032 +:1024D000020E012800000040020E01140000006FEF +:1024E000020E011C00000060020E012400000060CA +:1024F000020E012C00000060020E01100000005FBF +:10250000020E011800000050020E012000000050D1 +:10251000020E012800000050020E01140000007F8E +:10252000020E011C00000070020E01240000007069 +:10253000020E012C000000700730040000D60000DD +:10254000083007D80005043207340000322A0000A2 +:102550000734800031300C8B0735000038D018D894 +:10256000073580002F82270D07360000263632EE11 +:102570000836710031E00434023000BC0000003045 +:1025800001300000000000000130000400000000E5 +:1025900001300008000000000130000C00000000C5 +:1025A00001300010000000000130001400000000A5 +:1025B0000230002000000001023000240000000270 +:1025C00002300028000000030230002C0000000050 +:1025D000023000300000000402300034000000012E +:1025E00002300038000000000230003C0000000112 +:1025F00002300040000000040230004400000000EF +:1026000002300048000000010230004C00000003CE +:1026100002300050000000000230005400000001B1 +:1026200002300058000000040230005C000000008E +:10263000023000600000000102300064000000036E +:1026400002300068000000000230006C0000000151 +:10265000023000700000000402300074000000002E +:1026600002300078000000040230007C000000030B +:102670000630008000000002023000A400007FFF4E +:10268000023000A8000003FF023002240000000016 +:1026900002300234000000000230024C0000000052 +:1026A000023002E40000FFFF0630200000000800B6 +:1026B00002338BC000000001023380000000001ACA +:1026C000023380400000004E023380800000001082 +:1026D000023380C0000000200C33830000086470C7 +:1026E0000A338300000001570B3383000000055FAD +:1026F0000A338340000000000C33834000000226B0 +:102700000B338340000000010233838000086470B3 +:10271000023383C00000022602331480000000014F +:102720000A3314800000000006328000000001021D +:1027300006322008000000C8063220000000000217 +:1027400004328520008F04360632875C00000009C1 +:1027500006323EB00000000606323ED00000000205 +:1027600006323E800000000A04323EA8000204C582 +:1027700006323E00000000200632500000000940F2 +:102780000632400000000004043294C0000204C776 +:1027900006324110000000020632D0000000007036 +:1027A0000632DB00000000D40632DEA0000000028A +:1027B0000632E00000000800063324000000011883 +:1027C0000632100000000188063250000000002090 +:1027D00006325100000000200632520000000020A6 +:1027E0000632530000000020063254000000002092 +:1027F000063255000000002006325600000000207E +:102800000632570000000020063258000000002069 +:10281000063259000000002006325A000000002055 +:1028200006325B000000002006325C000000002041 +:1028300006325D000000002006325E00000000202D +:1028400006325F0000000020063284F00000000223 +:1028500004328500000204C9063285080000000227 +:102860000632DE90000000020633286000000118E6 +:102870000632162000000188063250800000002039 +:1028800006325180000000200632528000000020F5 +:1028900006325380000000200632548000000020E1 +:1028A00006325580000000200632568000000020CD +:1028B00006325780000000200632588000000020B9 +:1028C000063259800000002006325A8000000020A5 +:1028D00006325B800000002006325C800000002091 +:1028E00006325D800000002006325E80000000207D +:1028F00006325F8000000020063284F800000002EB +:1029000004328510000204CB063285180000000254 +:102910000632DE98000000020232845000000000FF +:102920000632401000000002023284540000000011 +:1029300006324020000000020232845800000000ED +:1029400006324030000000020232845C00000000C9 +:1029500006324040000000020232846000000000A5 +:102960000632405000000002023284640000000081 +:10297000063240600000000202328468000000005D +:1029800006324070000000020232846C0000000039 +:10299000063240800000000207200400007300009F +:1029A00008200780001004CD072400002AF1000051 +:1029B0000724800027670ABD0824D35063FC04CF96 +:1029C000022000BC000000300120000000000000D8 +:1029D00001200004000000000120000800000000A9 +:1029E0000120000C00000000012000100000000089 +:1029F000012000140000000002200020000000015F +:102A00000220002400000002022000280000000331 +:102A10000220002C00000000022000300000000412 +:102A200002200034000000010220003800000000F5 +:102A30000220003C000000010220004000000004D1 +:102A400002200044000000000220004800000001B5 +:102A50000220004C00000003022000500000000093 +:102A60000220005400000001022000580000000471 +:102A70000220005C00000000022000600000000155 +:102A80000220006400000003022000680000000033 +:102A90000220006C00000001022000700000000411 +:102AA00002200074000000000220007800000004F2 +:102AB0000220007C000000030620008000000002CD +:102AC000022000A400007FFF022000A8000003FFF6 +:102AD0000220022400000000022002340000000056 +:102AE0000220024C00000000022002E40000FFFF70 +:102AF000062020000000080002238BC00000000117 +:102B00000223800000000010022380400000001219 +:102B10000223808000000030022380C00000000EED +:102B20000C238300000864700A238300000001570F +:102B30000B2383000000055F0A2383400000000090 +:102B40000C238340000002260B2383400000000179 +:102B50000223838000086470022383C000000226E1 +:102B600002231480000000010A23148000000000EA +:102B7000062210000000004206222008000000C8C3 +:102B800006222000000000020622B00000000330F0 +:102B90000622F400000000530422F54C000104D189 +:102BA0000622F550000000030422F55C000104D267 +:102BB0000622F560000000030422F56C000104D336 +:102BC0000622F570000000030422F57C000104D405 +:102BD0000622F580000000030422F58C000104D5D4 +:102BE0000622F590000000030422F59C000104D6A3 +:102BF0000622F5A0000000030422F5AC000104D772 +:102C00000622F5B0000000030422F5BC000104D840 +:102C10000622F5C0000000460622E2000000044043 +:102C200004221240009004D906223000000000C0A7 +:102C30000622670000000100062290000000040048 +:102C400004226B0800200569062211F0000000062E +:102C50000422120800060589062212200000000244 +:102C600006224000000005C00622C0000000000649 +:102C70000422C0180006058F0622C0300000000A9A +:102C80000422C058000605950622C0700000000A04 +:102C90000422C0980006059B0622C0B00000000A6E +:102CA0000422C0D8000605A10622C0F00000000AD8 +:102CB0000422C118000605A70622C1300000000A40 +:102CC0000422C158000605AD0622C1700000000AAA +:102CD0000422C198000605B30622C1B00000000A14 +:102CE0000422C1D8000605B90622C1F00000000A7E +:102CF0000422C218000605BF0622C2300000000AE6 +:102D00000422C258000605C50622C2700000000A4F +:102D10000422C298000605CB0622C2B00000000AB9 +:102D20000422C2D8000605D10622C2F00000000A23 +:102D30000422C318000605D70622C3300000000A8B +:102D40000422C358000605DD0622C3700000000AF5 +:102D50000422C398000605E30622C3B00000000A5F +:102D60000422C3D8000605E90622C3F00000000AC9 +:102D70000422C418000605EF0622C4300000000A31 +:102D80000422C458000605F50622C4700000000A9B +:102D90000422C498000605FB0622C4B00000000A05 +:102DA0000422C4D8000606010622C4F00000000A6E +:102DB0000422C518000606070622C5300000000AD6 +:102DC0000422C5580006060D0622C5700000000A40 +:102DD0000422C598000606130622C5B00000000AAA +:102DE0000422C5D8000606190622C5F00000000A14 +:102DF0000422C6180006061F0622C6300000000A7C +:102E00000422C658000606250622C6700000000AE5 +:102E10000422C6980006062B0622C6B00000000A4F +:102E20000422C6D8000606310622C6F00000000AB9 +:102E30000422C718000606370622C7300000000A21 +:102E40000422C7580006063D0622C7700000000A8B +:102E50000422C798000606430622C7B00000000AF5 +:102E60000422C7D8000606490622C7F00000000A5F +:102E70000422C8180006064F0622C8300000000AC7 +:102E80000422C858000606550622C8700000000A31 +:102E90000422C8980006065B0622C8B00000000A9B +:102EA0000422C8D8000606610622C8F00000000A05 +:102EB0000422C918000606670622C9300000000A6D +:102EC0000422C9580006066D0622C9700000000AD7 +:102ED0000422C998000606730622C9B00000000A41 +:102EE0000422C9D8000606790622C9F00000000AAB +:102EF0000422CA180006067F0622CA300000000A13 +:102F00000422CA58000606850622CA700000000A7C +:102F10000422CA980006068B0622CAB00000000AE6 +:102F20000422CAD8000606910622CAF00000000A50 +:102F30000422CB18000606970622CB300000000AB8 +:102F40000422CB580006069D0622CB700000000A22 +:102F50000422CB98000606A30622CBB00000000A8C +:102F60000422CBD8000606A90622CBF00000000AF6 +:102F70000422CC18000606AF0622CC300000000A5E +:102F80000422CC58000606B50622CC700000000AC8 +:102F90000422CC98000606BB0622CCB00000000A32 +:102FA0000422CCD8000606C10622CCF00000000A9C +:102FB0000422CD18000606C70622CD300000000A04 +:102FC0000422CD58000606CD0622CD700000000A6E +:102FD0000422CD98000606D30622CDB00000000AD8 +:102FE0000422CDD8000606D90622CDF00000000A42 +:102FF0000422CE18000606DF0622CE300000000AAA +:103000000422CE58000606E50622CE700000000A13 +:103010000422CE98000606EB0622CEB00000000A7D +:103020000422CED8000606F10622CEF00000000AE7 +:103030000422CF18000606F70622CF300000000A4F +:103040000422CF58000606FD0622CF700000000AB9 +:103050000422CF98000607030622CFB00000000A22 +:103060000422CFD8000607090622CFF00000000A8C +:103070000422D0180006070F0622D0300000000AF4 +:103080000422D058000607150622D0700000000A5E +:103090000422D0980006071B0622D0B00000000AC8 +:1030A0000422D0D8000607210622D0F00000000A32 +:1030B0000422D118000607270622D1300000000A9A +:1030C0000422D1580006072D0622D1700000000A04 +:1030D0000422D198000607330622D1B00000000A6E +:1030E0000422D1D8000607390622D1F00000000AD8 +:1030F0000422D2180006073F0622D2300000000A40 +:103100000422D258000607450622D2700000000AA9 +:103110000422D2980006074B0622D2B00000000A13 +:103120000422D2D8000607510622D2F00000000A7D +:103130000422D318000607570622D3300000000AE5 +:103140000422D3580006075D0622D3700000000A4F +:103150000422D398000607630622D3B00000000AB9 +:103160000422D3D8000607690622D3F00000000A23 +:103170000422D4180006076F0622D4300000000A8B +:103180000422D458000607750622D4700000000AF5 +:103190000422D4980006077B0622D4B00000000A5F +:1031A0000422D4D8000607810622D4F00000000AC9 +:1031B0000422D518000607870622D5300000000A31 +:1031C0000422D5580006078D0622D5700000000A9B +:1031D0000422D598000607930622D5B00000000A05 +:1031E0000422D5D8000607990622D5F00000000A6F +:1031F0000422D6180006079F0622D6300000000AD7 +:103200000422D658000607A50622D6700000000A40 +:103210000422D698000607AB0622D6B00000000AAA +:103220000422D6D8000607B10622D6F00000000A14 +:103230000422D718000607B70622D7300000000A7C +:103240000422D758000607BD0622D7700000000AE6 +:103250000422D798000607C30622D7B00000000A50 +:103260000422D7D8000607C90622D7F00000000ABA +:103270000422D818000607CF0622D8300000000A22 +:103280000422D858000607D50622D8700000000A8C +:103290000422D898000607DB0622D8B00000000AF6 +:1032A0000422D8D8000607E10622D8F00000000A60 +:1032B0000422D918000607E70622D9300000000AC8 +:1032C0000422D958000607ED0622D9700000000A32 +:1032D0000422D998000607F30622D9B00000000A9C +:1032E0000422D9D8000607F90622D9F00000000A06 +:1032F0000422DA18000607FF0622DA300000000A6E +:103300000422DA58000608050622DA700000000AD6 +:103310000422DA980006080B0622DAB00000000A40 +:103320000422DAD8000608110622DAF00000000AAA +:103330000422DB18000608170622DB300000000A12 +:103340000422DB580006081D0622DB700000000A7C +:103350000422DB98000608230622DBB00000000AE6 +:103360000422DBD8000608290622DBF00000000A50 +:103370000422DC180006082F0622DC300000000AB8 +:103380000422DC58000608350622DC700000000A22 +:103390000422DC980006083B0622DCB00000000A8C +:1033A0000422DCD8000608410622DCF00000000AF6 +:1033B0000422DD18000608470622DD300000000A5E +:1033C0000422DD580006084D0622DD700000000AC8 +:1033D0000422DD98000608530622DDB00000000A32 +:1033E0000422DDD8000608590622DDF00000000A9C +:1033F0000422DE180006085F0622DE300000000A04 +:103400000422DE58000608650622DE700000000A6D +:103410000422DE980006086B0622DEB00000000AD7 +:103420000422DED8000608710622DEF00000000A41 +:103430000422DF18000608770622DF300000000AA9 +:103440000422DF580006087D0622DF700000000A13 +:103450000422DF98000608830622DFB00000000A7D +:103460000422DFD8000608890622DFF00000000AE7 +:103470000422E0180006088F0622E0300000000A4F +:103480000422E058000608950622E0700000000AB9 +:103490000422E0980006089B0622E0B00000000A23 +:1034A0000422E0D8000608A10622E0F00000000A8D +:1034B0000422E118000608A70622E1300000000AF5 +:1034C0000422E158000608AD0622E1700000000A5F +:1034D0000422E198000608B30622E1B00000000AC9 +:1034E0000422E1D8000608B90622E1F00000000439 +:1034F0000622153800000002062211E80000000232 +:103500000622F3000000000802221148000000001B +:1035100006225900000000060622330000000002C7 +:1035200006226040000000300622F3200000000860 +:103530000222114C0000000006225918000000066B +:10354000062233080000000206226100000000305D +:103550000622F34000000008022211500000000083 +:103560000622593000000006062233100000000237 +:10357000062261C0000000300622F360000000084F +:1035800002221154000000000622594800000006E3 +:10359000062233180000000206226280000000307C +:1035A0000622F380000000080222115800000000EB +:1035B00006225960000000060622332000000002A7 +:1035C00006226340000000300622F3A0000000083D +:1035D0000222115C0000000006225978000000065B +:1035E000062233280000000206226400000000309A +:1035F0000622F3C000000008022211600000000053 +:103600000622599000000006062233300000000216 +:10361000062264C0000000300622F3E0000000082B +:103620000222116400000000062259A800000006D2 +:1036300006223338000000020622658000000030B8 +:103640000216100000000028021700080000000207 +:103650000217002C000000030217003C00000004C9 +:10366000021700440000000002170048000000029A +:103670000217004C0000009002170050000000905C +:103680000217005400800090021700580810000034 +:10369000021700700000000602170078000009FF02 +:1036A0000217007C0000076C021701C4081000001C +:1036B0000217034400000001021704000000008A02 +:1036C00002170404000000800217040800000081B3 +:1036D0000217040C00000080021704100000008A8A +:1036E0000217041400000080021704180000008173 +:1036F0000217041C00000080021704300000008A3A +:103700000217043400000080021704380000008112 +:103710000217043C00000080021704400000008AE9 +:1037200002170444000000800217044800000081D2 +:103730000217044C00000080021704800000008A79 +:103740000217048400000080021704880000008132 +:103750000217048C0000008002170038007C10045F +:10376000021700040000000F021701EC0000000225 +:10377000021701F400000002021701EC0000000231 +:10378000021701F400000002021701EC0000000221 +:10379000021701F400000002021701EC0000000211 +:1037A000021701F400000002021701EC0000000201 +:1037B000021701F400000002021701EC00000002F1 +:1037C000021701F400000002021701EC00000002E1 +:1037D000021701F400000002021701EC00000002D1 +:1037E000021701F400000002061640240000000247 +:1037F000021640700000001C021642080000000182 +:1038000002164210000000010216422000000001D2 +:10381000021642280000000102164230000000019A +:103820000216423800000001021642600000000249 +:103830000C16401C0003D0900A16401C0000009C8F +:103840000B16401C000002710216403000000028D8 +:10385000021640340000002C0216403800000030F0 +:103860000216404400000020021640000000000143 +:10387000021640D8000000010216400800000001B6 +:103880000216400C0000000102164010000000016A +:1038900002164240000000000216424800000000EC +:1038A000061642700000000202164250000000009E +:1038B0000216425800000000061642800000000276 +:1038C00002166008000012140216600C00001200BC +:1038D00002166010000012040216601C0000FFFFB8 +:1038E000021660200000FFFF021660240000FFFFA8 +:1038F000021660280000FFFF02166038000000205A +:103900000216603C00000010061660400000000235 +:1039100002166048000000230216604C00000024DC +:1039200002166050000000250216605400000026B8 +:1039300002166058000000270216605C00000011AB +:103940000216606000000000021660640000002B98 +:10395000021660680000002C0216606C0000002D4A +:1039600002166070000000EC021660740000000097 +:1039700002166078000000290216607C0000002A10 +:10398000021660800000002F061660840000000D03 +:10399000021660B800000001061660BC00000008B6 +:1039A000021660DC00000001061660E00000000462 +:1039B000021660F000000001061660F4000000032B +:1039C0000216610000000001061661040000002DCF +:1039D000021661B800000001061661BC0000000874 +:1039E000021661DC00000001061661E00000000420 +:1039F000021661F000000001061661F400000003E9 +:103A00000216620000000001061662040000000DAC +:103A10000216623807FFFFFF0216623C0000007FBB +:103A20000216624007FFFFFF021662440000003FDB +:103A300001166248000000000116624C0000000000 +:103A400001166250000000000116625400000000E0 +:103A500001166258000000000116625C00000000C0 +:103A600001166260000000000116626400000000A0 +:103A700001166268000000000116626C0000000080 +:103A80000116627000000000011662740000000060 +:103A900001166278000000000116627C0000000040 +:103AA000011662D400000000021662D80000FFFF79 +:103AB000021662DC0000FFFF021662E00000FFFF5A +:103AC000021662E40000FFFF0C166000000003E82D +:103AD0000A166000000000010B16600000000003E1 +:103AE0000216804000000006021680440000000517 +:103AF000021680480000000A0216804C00000005F3 +:103B00000216805400000002021680CC000000045F +:103B1000021680D000000004021680D400000004C9 +:103B2000021680D800000004021680DC00000004A9 +:103B3000021680E000000004021680E40000000489 +:103B4000021680E800000004021688040000000647 +:103B5000021680300000007C021680340000003D18 +:103B6000021680380000003F0216803C0000009CD6 +:103B70000216E6E8000060000216E6EC00006000B5 +:103B80000216E6F0000060000216E6F40000600095 +:103B900002168234000025E40216823800008000FC +:103BA00002168094000025E3021681F400000C0840 +:103BB000021681F800000040021681FC000001009E +:103BC0000216820000000020021682040000001786 +:103BD00002168208000000800216820C000002001B +:103BE00002168210000000000216823C0000001342 +:103BF00002168220008F008F0216821C008F008F19 +:103C0000021680F0000000070216821801FF01FF73 +:103C10000216821401FF01FF061680F40000000264 +:103C20000216811C0000000502168120000000051C +:103C300002168124000000050216812800000008F9 +:103C40000216812C000000060216813000000007D9 +:103C50000616813400000004021680FC00000000FB +:103C600006168144000000020216814C0000000488 +:103C7000021681500000000102168154000000026B +:103C800002168158000000050216815C0000000544 +:103C90000216816000000005021681640000000524 +:103CA0000216816800000008021681000000000072 +:103CB0000216816C000000060216817000000007E9 +:103CC00006168174000000060216818C00000004B4 +:103CD000021681900000000102168104000000001D +:103CE000021681940000000202168198000000056F +:103CF0000216819C00000005021681A0000000054C +:103D0000021681A400000005021681A80000000828 +:103D1000021681AC00000006021681B00000000708 +:103D2000061681B40000000202168108000000009F +:103D3000061681BC00000004021681CC00000004BD +:103D4000021681D000000001021681D4000000029A +:103D5000021681D800000005021681DC0000000573 +:103D6000021681E0000000050216810C000000042C +:103D7000021681E400000005021681E80000000838 +:103D8000021681EC00000006021681F00000000718 +:103D900002168110000000010216811400000002CA +:103DA00002168118000000050216809C0000004CDD +:103DB000021680A00000004C061680C4000000021D +:103DC000021680A400000000021680A80000000077 +:103DD000021680AC0000004C061680B00000000502 +:103DE0000216E6F80000020402168240003F003F7F +:103DF00002168244003F003F061682900000000435 +:103E000002168248008000800216824C00800080EA +:103E100002168250010001000216825401000100C6 +:103E20000616825800000002021682600040004020 +:103E30000216826400400040021682681E001E00C6 +:103E40000216826C1E001E000216827040004000A6 +:103E500002168274400040000216827880008000C2 +:103E60000216827C800080000216828020002000E2 +:103E700002168284200020000616828800000002BC +:103E8000021680900000004B021680600000014086 +:103E900002168064000001400616808800000002BF +:103EA00002168068000000000216806C000000000E +:103EB00002168070000000C0061680740000000525 +:103EC0000216880C0101010102168810010120046C +:103ED000021688142008100102168818010101201A +:103EE0000216881C0101010102168820010120042C +:103EF00002168824200810010216882801010120DA +:103F00000216882C200810010216883001010120B9 +:103F100002168834010101010216883801012004CB +:103F20000216883C20081001021688400101012079 +:103F3000021688440101010102168848010120048B +:103F40000216E6BC000000000216E6C000000002F7 +:103F50000216E6C4000000040216E6C800000006CF +:103F60000216E79400000001021680EC000000FF3A +:103F700002140000000000010215C024000000002F +:103F80000215C0EC000000010215C0F000000001A5 +:103F90000615C10000000002021400040000000128 +:103FA00002140008000000010214000C00000001CF +:103FB000021400300000000102140034000000016F +:103FC0000214004000000001021400440000FFFF42 +:103FD00006140004000000030214000000000000AA +:103FE000060280000000200002020058000000329B +:103FF000020200A003150020020200A40315002005 +:10400000020200A801000030020200AC081000000B +:10401000020200B000000036020200B400000030CE +:10402000020200B800000031020200BC00000002E1 +:10403000020200C000000005020200C400000002ED +:10404000020200C800000002020200D000000007C7 +:10405000020200DC00000000020200E00000000597 +:10406000020200E400000003020200F00000000170 +:10407000020200FC00000006020201200000000015 +:104080000202013400000002020201B0000000013F +:104090000202020C000000010202021400000001F2 +:1040A00002020218000000020202040400000001E3 +:1040B0000202040C00000040020204100000004054 +:1040C0000202041C00000004020204200000002080 +:1040D0000202042400000002020204280000002062 +:1040E000060205000000001204020480002008BF40 +:1040F000020200600000000F0202006400000007DE +:1041000002020068000000000202006C0000000EC5 +:10411000020200700000000E06020074000000039E +:10412000020200F40000000402020004000000018A +:1041300002020008000000010202000C0000000161 +:104140000202001000000001020200140000000141 +:1041500002020018000000010202001C0000000121 +:104160000202002000000001020200240000000101 +:1041700002020028000000010202002C00000001E1 +:1041800002020030000000010202003400000001C1 +:1041900002020038000000010202003C00000001A1 +:1041A0000202004000000001020200440000000181 +:1041B00002020048000000010202004C0000000161 +:1041C000020200500000000102020108000000C8C5 +:1041D0000202011800000002020201C400000000F7 +:1041E000020201CC00000000020201D40000000223 +:1041F000020201DC00000002020201E4000000FFF4 +:10420000020201EC000000FF0202010000000000B9 +:104210000202010C000000C80202011C00000002A2 +:10422000020201C800000000020201D000000000EC +:10423000020201D800000002020201E000000002B8 +:10424000020201E8000000FF020201F0000000FF8E +:10425000020201040000002002020108000000C860 +:104260000202011800000002020201C40000000066 +:10427000020201CC00000000020201D40000000292 +:10428000020201DC00000002020201E4000000FF63 +:10429000020201EC000000FF020201000000001019 +:1042A0000202010C000000C80202011C0000000212 +:1042B000020201C800000000020201D0000000005C +:1042C000020201D800000002020201E00000000228 +:1042D000020201E8000000FF020201F0000000FFFE +:1042E000020201040000003002020108000000C8C0 +:1042F0000202011800000002020201C400000000D6 +:10430000020201CC00000000020201D40000000201 +:10431000020201DC00000002020201E4000000FFD2 +:10432000020201EC000000FF020201000000004058 +:104330000202010C000000C80202011C0000000281 +:10434000020201C800000000020201D000000000CB +:10435000020201D800000002020201E00000000297 +:10436000020201E8000000FF020201F0000000FF6D +:10437000020201040000006002020108000000C8FF +:104380000202011800000002020201C40000000045 +:10439000020201CC00000000020201D40000000271 +:1043A000020201DC00000002020201E4000000FF42 +:1043B000020201EC000000FF0202010000000050B8 +:1043C0000202010C000000C80202011C00000002F1 +:1043D000020201C800000000020201D0000000003B +:1043E000020201D800000002020201E00000000207 +:1043F000020201E8000000FF020201F0000000FFDD +:1044000002020104000000700728040000B500004B +:10441000082807B8000908DF072C000028E9000079 +:10442000072C800036700A3B072D000035BE17D8D8 +:10443000072D80003B1B2548072E000035D8340F80 +:10444000072E80001B224186082EBFD0280608E1D7 +:10445000022800BC0000003001280000000000001D +:1044600001280004000000000128000800000000EE +:104470000128000C000000000128001000000000CE +:1044800001280014000000000228002000000001A4 +:104490000228002400000002022800280000000377 +:1044A0000228002C00000000022800300000000458 +:1044B000022800340000000102280038000000003B +:1044C0000228003C00000001022800400000000417 +:1044D00002280044000000000228004800000001FB +:1044E0000228004C000000030228005000000000D9 +:1044F00002280054000000010228005800000004B7 +:104500000228005C0000000002280060000000019A +:104510000228006400000003022800680000000078 +:104520000228006C00000001022800700000000456 +:104530000228007400000000022800780000000437 +:104540000228007C00000003062800800000000212 +:10455000022800A400007FFF022800A8000003FF3B +:10456000022802240000000002280234000000009B +:104570000228024C00000000022802E40000FFFFB5 +:104580000628200000000800022B8BC0000000015C +:10459000022B800000000000022B80400000001869 +:1045A000022B80800000000C022B80C000000066FF +:1045B0000C2B8300000864700A2B83000000015755 +:1045C0000B2B83000000055F0A2B834000000000D6 +:1045D0000C2B8340000002260B2B834000000001BF +:1045E000022B838000086470022B83C00000022627 +:1045F000022B1480000000010A2B14800000000030 +:10460000022B944000000001062B94480000000299 +:10461000062A9A7000000004042A9A80000408E325 +:10462000062A9A9000000002042A9A98000208E7DD +:10463000062A900000000048062A2008000000C852 +:10464000062A200000000002062A912800000086A9 +:10465000062AC00000000120062A9348000000033B +:10466000042A9354000108E9062A9FB000000002C2 +:10467000042A9418000208EA042A9CD0000108ECDD +:10468000062A9CD400000011042A9D20008F08ED0A +:10469000062A9F5C00000005042A30000002097C05 +:1046A000062A300800000100062A404000000010E1 +:1046B000042A40000010097E042A84080002098EA2 +:1046C000042ACF4000040990042ACF600002099414 +:1046D000062A9FA000000004062A60000000054092 +:1046E000062A9D1800000002062AB00000000050B3 +:1046F000062ABB7000000070062ABB68000000029A +:10470000062AB94800000004062AD000000008006C +:10471000062AC48000000150062A942000000032BE +:10472000062A502000000002062A50300000000235 +:10473000062A500000000002062A50100000000265 +:10474000022A520800000001042A9AA000020996D9 +:10475000062A95B000000022042A96380001099824 +:10476000062A963C00000003062A96E0000000227C +:10477000042A976800010999062A976C0000000333 +:10478000062A981000000022042A98980001099A2D +:10479000062A989C00000003062A99400000002287 +:1047A000042A99C80001099B062A99CC000000033D +:1047B000062ABB5800000002062AC9C000000150AA +:1047C000062A94E800000032062A50280000000261 +:1047D000062A503800000002062A50080000000295 +:1047E000062A501800000002022A520C00000001A4 +:1047F000042A9AA80002099C062A96480000002272 +:10480000042A96D00001099E062A96D400000003CF +:10481000062A977800000022042A98000001099FC8 +:10482000062A980400000003062A98A80000002227 +:10483000042A9930000109A0062A993400000003D7 +:10484000062A99D800000022042A9A60000109A1D2 +:10485000062A9A6400000003062ABB6000000002DA +:10486000022ACF0000000000042A9AB0001009A21A +:10487000062A50480000000E022ACF040000000063 +:10488000042A9AF0001009B2062A50800000000E97 +:10489000022ACF0800000000042A9B30001009C241 +:1048A000062A50B80000000E022ACF0C00000000BB +:1048B000042A9B70001009D2062A50F00000000E56 +:1048C000022ACF1000000000042A9BB0001009E269 +:1048D000062A51280000000E022ACF140000000012 +:1048E000042A9BF0001009F2062A51600000000E15 +:1048F000022ACF1800000000042A9C3000100A028F +:10490000062A51980000000E022ACF1C0000000069 +:10491000042A9C7000100A12062A51D00000000ED2 +:1049200002101008000000010210105000000001E9 +:10493000021010000003D000021010040000003D1F +:104940000910180002000A220910110000100C22A0 +:1049500006101140000000080910116000100C3210 +:10496000061011A00000001806102400000000E04E +:104970000210201C00000000021020200000000196 +:10498000021020C0000000020210200400000001FC +:104990000210200800000001021030D800000001C1 +:1049A00009103C0000050C420910380000050C47B6 +:1049B0000910392000050C4C09103B0000050C5172 +:1049C000021040D400000030021040D80000003037 +:1049D00006104C00000001000210402800000010EA +:1049E0000210404400003FFF021040580028000021 +:1049F000021040840084924A0210405800000000D7 +:104A0000021041380000000102104138000000018E +:104A1000021041380000000102104138000000017E +:104A2000021041380000000102104138000000016E +:104A3000021041380000000102104138000000015E +:104A40000212049001F680400212051400003C108E +:104A500002120494FFFFFFFF02120498FFFFFFFF02 +:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2 +:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2 +:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2 +:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A +:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A +:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A +:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 +:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 +:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 +:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 +:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 +:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 +:104B200002120504FFFFFFFF02120508FFFFFFFF4F +:104B30000212050CFFFFFFFF02120510FFFFFFFF2F +:104B4000021204D4F800C000021204B4F0005000B5 +:104B500002120390000000080212039C00000008EB +:104B6000021203A000000008021203A400000002C9 +:104B7000021203BC00000004021203C00000000582 +:104B8000021203C400000004021203D0000000005F +:104B90000212036C00000001021201BC0000004080 +:104BA000021201C000001808021201C4000008032C +:104BB000021201C800000803021201CC00000040EC +:104BC000021201D000000003021201D40000080309 +:104BD000021201D800000803021201DC00000803E1 +:104BE000021201E000010003021201E400000803C8 +:104BF000021201E800000803021201EC00000003A9 +:104C0000021201F000000003021201F40000000390 +:104C1000021201F800000003021201FC0000000370 +:104C2000021202000000000302120204000000034E +:104C300002120208000000030212020C000000032E +:104C4000021202100000000302120214000000030E +:104C500002120218000000030212021C00000003EE +:104C600002120220000000030212022400000003CE +:104C700002120228000024030212022C0000002F5E +:104C80000212023000000009021202340000001972 +:104C900002120238000001840212023C000001836B +:104CA0000212024000000306021202440000001932 +:104CB00002120248000000060212024C0000030625 +:104CC0000212025000000306021202540000030602 +:104CD0000212025800000C860212025C0000030659 +:104CE00002120260000003060212026400000006C5 +:104CF00002120268000000060212026C00000006A8 +:104D00000212027000000006021202740000000687 +:104D100002120278000000060212027C0000000667 +:104D20000212028000000006021202840000000647 +:104D300002120288000000060212028C0000000627 +:104D40000212029000000006021202940000000607 +:104D500002120298000000060212029C00000006E7 +:104D6000021202A000000306021202A400000013B7 +:104D7000021202A800000006021202B00000100495 +:104D8000021202B400001004021203240010644056 +:104D90000212032800106440021205B40000000152 +:104DA000021205F800000040021205FC0000001984 +:104DB00002120600000000010212066C0000000151 +:104DC000021201B000000001021207D80000000327 +:104DD000021207D800000003021207D800000003E7 +:104DE000021207D800000003021207D800000003D7 +:104DF000021207D800000003021207D800000003C7 +:104E0000021207D8000000030600A0000000000CFA +:104E10000200A050000000000200A05400000000AA +:104E20000200A0EC555400000200A0F05555555565 +:104E30000200A0F4000055550200A0F8F0000000A8 +:104E40000200A0FC555400000200A1005555555524 +:104E50000200A104000055550200A108F000000066 +:104E60000200A19C000000000200A1A000010000BF +:104E70000200A1A4000050140200A1A8000000003C +:104E80000200A6A8000000000200A6AC000000007E +:104E90000200A6D0000000000200A45C00000C008C +:104EA0000200A61C000000030200A070FFF55FFFD7 +:104EB0000200A0740000FFFF0200A078F00003E0F1 +:104EC0000200A07C000000000200A0800000A00002 +:104ED0000600A084000000050200A0980FE000007A +:104EE0000600A09C000000070200A0B8000004001B +:104EF0000600A0BC000000030200A0C800001000D3 +:104F00000600A0CC000000030200A0D80000400072 +:104F10000600A0DC000000030200A0E80001000081 +:104F20000600A22C000000040200A688000000FC7D +:104F30000600A68C000000070200A6F40000000096 +:104F40000200A10CFF5C00000200A110FFF55FFF52 +:104F50000200A1140000FFFF0200A118F00003E00E +:104F60000200A11C000000000200A1200000A0001F +:104F70000600A124000000050200A1380FE0000097 +:104F80000600A13C000000070200A1580000080034 +:104F90000600A15C000000030200A16800002000E0 +:104FA0000600A16C000000030200A1780000800050 +:104FB0000600A17C000000030200A188000200009E +:104FC0000600A23C000000040200A6B0000000FCA5 +:104FD0000600A6B4000000070200A6F800000000CA +:104FE0000200A030000000000200A0340000000019 +:104FF0000200A038000000000200A03C00000000F9 +:105000000200A040000000000200A04400000000D8 +:105010000200A048000000000200A04C00000000B8 +:10502000020090C40000E000020090CC0000F300F9 +:10503000020090D400000003020091A000000001D3 +:105040000600917000000003020090EC0000600078 +:10505000020090F400007300020090FC00000003C6 +:10506000020091A8000000010600918800000003E2 +:10507000020091000000400002009108000053006F +:105080000200911000000004020091AC0000000139 +:1050900006009194000000020200919C00000001B3 +:1050A000020090D800006000020090E00000730051 +:1050B000020090E800000003020091A4000000013B +:1050C0000200917C000000010200918000000001BC +:1050D00002009184000000000200912800000300FB +:1050E0000200916C0003F0080200912C0000030004 +:1050F0000200913000000300020091340000030020 +:1051000002009138000003000200913C00000300FF +:1051100002009140000003000200942C00000001F6 +:1051200002009430000000010200943400000001ED +:105130000200942C000000010200943000000001E5 +:1051400002009434000000010200942C00000001D1 +:1051500002009430000000010200943400000001BD +:105160000200942C000000010200943000000001B5 +:1051700002009434000000010200942C00000001A1 +:10518000020094300000000102009434000000018D +:105190000200942C00000001020094300000000185 +:1051A00002009434000000010200942C0000000171 +:1051B000020094300000000102009434000000015D +:1051C0000200942C00000001020094300000000155 +:1051D0000200943400000001021300780000003047 +:1051E0000213003C000061A8061301080000000340 +:1051F000021301040000000002130134000000004B +:10520000061301080000000302130104000000005F +:10521000021301340000000006130108000000031F +:10522000021301040000000002130134000000001A +:10523000061301080000000302130104000000002F +:1052400002130134000000000613010800000003EF +:1052500002130104000000000213013400000000EA +:1052600006130108000000030213010400000000FF +:1052700002130134000000000613010800000003BF +:1052800002130104000000000213013400000000BA +:1052900006130108000000030213010400000000CF +:1052A0000213013400000000021100B800000001E8 +:1052B0000216E6E8000020000216E6EC00002000DE +:1052C0000216E6F0000065550216E6F4000065558A +:1052D00002168150000000000216817400000001D7 +:1052E00002168178000000010216817C0000000196 +:1052F0000216818000000001021681840000000176 +:105300000216818800000001021681B4000000012D +:10531000021681B800000001021681BC00000001E5 +:10532000021681C000000001021681C400000001C5 +:10533000021681C800000001021681100000000062 +:105340000216824000BF00BF061682440000000221 +:105350000216824C00BF00BF0216E6C40000000126 +:105360000216E6C8000000030216E79400000000E1 +:10537000042ACF40000A0C56000000000000000084 +:1053800000000034000000000000000000000000E9 +:10539000000000000000000000000000000000000D +:1053A0000000000000000000000000000034003594 +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D0000000000000000000003500600000000038 +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:1054000000000000006000910000000000000000AB +:1054100000910095009500990099009D009D00A1C4 +:1054200000A100A500A500A900A900AD00AD00B134 +:1054300000B100B500000000000000000000000006 +:10544000000000000000000000000000000000005C +:1054500000000000000000000000000000B5031183 +:105460000311031B031B03250325032C032C033308 +:105470000333033A033A0341034103480348034F0C +:10548000034F03560356035D0000000000000000B8 +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:105530000000000000000000035D035E00000000AA +:1055400000000000035E035F035F0360036003610C +:10555000036103620362036303630364036403651B +:10556000036503660000000000000000000000006A +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:105590000366036D036D0379037903850000000042 +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000385038600000000AA +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:1056100000000000038603B100000000000000004D +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:1056400003B103E0000000000000000000000000C3 +:10565000000000000000000000000000000000004A +:1056600000000000000000000000000003E0040F44 +:105670000000000000000000040F04160416041DC2 +:10568000041D04240424042B042B043204320439A2 +:1056900004390440044004470447047A0000000031 +:1056A00000000000047A047E047E048204820486E2 +:1056B0000486048A048A048E048E0492049204965A +:1056C0000496049A049A04EA04EA05000500051603 +:1056D000051605180518051A051A051C051C051ED2 +:1056E000051E052005200522052205240524052682 +:1056F00005260693000000000000000006930698AF +:105700000698069D069D06A206A206A706A706AC59 +:1057100006AC06B106B106B606B606BB06BB06BCAD +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:10574000000000000000000006BC06E000000000B1 +:105750000000000006E006E206E206E406E406E6D3 +:1057600006E606E806E806EA06EA06EC06EC06EEB9 +:1057700006EE06F006F00705070507080708070B01 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A000070B074F00000000000000000000000091 +:1057B00000000000000000000000000000000000E9 +:1057C000000000000000000000000000074F07E19B +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F000000000000000000007E107EF00000000CB +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000007EF082C00000000000000004E +:10583000082C08350835083E083E08470847085038 +:1058400008500859085908620862086B086B087408 +:10585000087408D508D508EA08EA08FF08FF090215 +:1058600009020905090509080908090B090B090EB0 +:10587000090E09110911091409140917091709203A +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000920092600000000A0 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D000000000000926092B000000000000000065 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:10590000092B0933000000000000000009330934AE +:10591000093409350935093609360937093709388F +:10592000093809390939093A093A093B00000000E8 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000093B09AC000000004E +:105960000000000009AC09AD09AD09AE09AE09AFF0 +:1059700009AF09B009B009B109B109B209B209B357 +:1059800009B309B409B409C809C809DB09DB09EF7F +:1059900009EF09F009F009F109F109F209F209F337 +:1059A00009F309F409F409F509F509F609F609F707 +:1059B00009F70A1600000000000000000A160A1984 +:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F +:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020 +:1059E00000000000000000000A300A330A330A36C3 +:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277 +:105A00000A420A450A450A480A480A4900000000B5 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A3000000000000A490A610000000000000000A8 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000A610A620000000000000000000000005F +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A9000000100000002070000030E0000041500D2 +:105AA00000051C000006230000072A000008310042 +:105AB00000093800000A3F00000B4600000C4D00B2 +:105AC000000D5400000E5B00000F62000010690022 +:105AD000001170000012770000137E000014850092 +:105AE00000158C000016930000179A000018A10002 +:105AF0000019A800001AAF00001BB600001CBD0072 +:105B0000001DC400001ECB00001FD2000000D90001 +:105B10000000200000004000000060000000800045 +:105B20000000A0000000C0000000E0000001000034 +:105B30000001200000014000000160000001800021 +:105B40000001A0000001C0000001E0000002000010 +:105B500000022000000240000002600000028000FD +:105B60000002A0000002C0000002E00000030000EC +:105B700000032000000340000003600000038000D9 +:105B80000003A0000003C0000003E00000040000C8 +:105B900000042000000440000004600000048000B5 +:105BA0000004A0000004C0000004E00000050000A4 +:105BB0000005200000054000000560000005800091 +:105BC0000005A0000005C0000005E0000006000080 +:105BD000000620000006400000066000000680006D +:105BE0000006A0000006C0000006E000000700005C +:105BF0000007200000074000000760000007800049 +:105C00000007A0000007C0000007E0000008000037 +:105C10000008200000084000000860000008800024 +:105C20000008A0000008C0000008E0000009000013 +:105C30000009200000094000000960000009800000 +:105C40000009A0000009C0000009E000000A0000EF +:105C5000000A2000000A4000000A6000000A8000DC +:105C6000000AA000000AC000000AE000000B0000CB +:105C7000000B2000000B4000000B6000000B8000B8 +:105C8000000BA000000BC000000BE000000C0000A7 +:105C9000000C2000000C4000000C6000000C800094 +:105CA000000CA000000CC000000CE000000D000083 +:105CB000000D2000000D4000000D6000000D800070 +:105CC000000DA000000DC000000DE000000E00005F +:105CD000000E2000000E4000000E6000000E80004C +:105CE000000EA000000EC000000EE000000F00003B +:105CF000000F2000000F4000000F6000000F800028 +:105D0000000FA000000FC000000FE0000010000016 +:105D10000010200000104000001060000010800003 +:105D20000010A0000010C0000010E00000110000F2 +:105D300000112000001140000011600000118000DF +:105D40000011A0000011C0000011E00000120000CE +:105D500000122000001240000012600000128000BB +:105D60000012A0000012C0000012E00000130000AA +:105D70000013200000134000001360000013800097 +:105D80000013A0000013C0000013E0000014000086 +:105D90000014200000144000001460000014800073 +:105DA0000014A0000014C0000014E0000015000062 +:105DB000001520000015400000156000001580004F +:105DC0000015A0000015C0000015E000001600003E +:105DD000001620000016400000166000001680002B +:105DE0000016A0000016C0000016E000001700001A +:105DF0000017200000174000001760000017800007 +:105E00000017A0000017C0000017E00000180000F5 +:105E100000182000001840000018600000188000E2 +:105E20000018A0000018C0000018E00000190000D1 +:105E300000192000001940000019600000198000BE +:105E40000019A0000019C0000019E000001A0000AD +:105E5000001A2000001A4000001A6000001A80009A +:105E6000001AA000001AC000001AE000001B000089 +:105E7000001B2000001B4000001B6000001B800076 +:105E8000001BA000001BC000001BE000001C000065 +:105E9000001C2000001C4000001C6000001C800052 +:105EA000001CA000001CC000001CE000001D000041 +:105EB000001D2000001D4000001D6000001D80002E +:105EC000001DA000001DC000001DE000001E00001D +:105ED000001E2000001E4000001E6000001E80000A +:105EE000001EA000001EC000001EE000001F0000F9 +:105EF000001F2000001F4000001F6000001F8000E6 +:105F0000001FA000001FC000001FE00000200000D4 +:105F100000202000002040000020600000208000C1 +:105F20000020A0000020C0000020E00000210000B0 +:105F3000002120000021400000216000002180009D +:105F40000021A0000021C0000021E000002200008C +:105F50000022200000224000002260000022800079 +:105F60000022A0000022C0000022E0000023000068 +:105F70000023200000234000002360000023800055 +:105F80000023A0000023C0000023E0000024000044 +:105F90000024200000244000002460000024800031 +:105FA0000024A0000024C0000024E0000025000020 +:105FB000002520000025400000256000002580000D +:105FC0000025A0000025C0000025E00000260000FC +:105FD00000262000002640000026600000268000E9 +:105FE0000026A0000026C0000026E00000270000D8 +:105FF00000272000002740000027600000278000C5 +:106000000027A0000027C0000027E00000280000B3 +:1060100000282000002840000028600000288000A0 +:106020000028A0000028C0000028E000002900008F +:10603000002920000029400000296000002980007C +:106040000029A0000029C0000029E000002A00006B +:10605000002A2000002A4000002A6000002A800058 +:10606000002AA000002AC000002AE000002B000047 +:10607000002B2000002B4000002B6000002B800034 +:10608000002BA000002BC000002BE000002C000023 +:10609000002C2000002C4000002C6000002C800010 +:1060A000002CA000002CC000002CE000002D0000FF +:1060B000002D2000002D4000002D6000002D8000EC +:1060C000002DA000002DC000002DE000002E0000DB +:1060D000002E2000002E4000002E6000002E8000C8 +:1060E000002EA000002EC000002EE000002F0000B7 +:1060F000002F2000002F4000002F6000002F8000A4 +:10610000002FA000002FC000002FE0000030000092 +:10611000003020000030400000306000003080007F +:106120000030A0000030C0000030E000003100006E +:10613000003120000031400000316000003180005B +:106140000031A0000031C0000031E000003200004A +:106150000032200000324000003260000032800037 +:106160000032A0000032C0000032E0000033000026 +:106170000033200000334000003360000033800013 +:106180000033A0000033C0000033E0000034000002 +:1061900000342000003440000034600000348000EF +:1061A0000034A0000034C0000034E00000350000DE +:1061B00000352000003540000035600000358000CB +:1061C0000035A0000035C0000035E00000360000BA +:1061D00000362000003640000036600000368000A7 +:1061E0000036A0000036C0000036E0000037000096 +:1061F0000037200000374000003760000037800083 +:106200000037A0000037C0000037E0000038000071 +:10621000003820000038400000386000003880005E +:106220000038A0000038C0000038E000003900004D +:10623000003920000039400000396000003980003A +:106240000039A0000039C0000039E000003A000029 +:10625000003A2000003A4000003A6000003A800016 +:10626000003AA000003AC000003AE000003B000005 +:10627000003B2000003B4000003B6000003B8000F2 +:10628000003BA000003BC000003BE000003C0000E1 +:10629000003C2000003C4000003C6000003C8000CE +:1062A000003CA000003CC000003CE000003D0000BD +:1062B000003D2000003D4000003D6000003D8000AA +:1062C000003DA000003DC000003DE000003E000099 +:1062D000003E2000003E4000003E6000003E800086 +:1062E000003EA000003EC000003EE000003F000075 +:1062F000003F2000003F4000003F6000003F800062 +:10630000003FA000003FC000003FE000003FE00170 +:1063100000000000000001FF0000020000007FF804 +:1063200000007FF800000A90000035000000000126 +:106330000000FF00000000000000FF00000000005F +:106340000000FF00000000000000FF00000000004F +:106350000000FF00000000000000FF00000000003F +:106360000000FF00000000000000FF00000000002F +:106370000000FF00000000000000FF00000000001F +:106380000000FF00000000000000FF00000000000F +:106390000000FF00000000000000FF0000000000FF +:1063A0000000FF00000000000000FF0000000000EF +:1063B0000000FF00000000000000FF0000000000DF +:1063C0000000FF00000000000000FF0000000000CF +:1063D0000000FF00000000000000FF0000000000BF +:1063E0000000FF00000000000000FF0000000000AF +:1063F0000000FF00000000000000FF00000000009F +:106400000000FF00000000000000FF00000000008E +:106410000000FF00000000000000FF00000000007E +:106420000000FF00000000000000FF00000000006E +:106430000000FF00000000000000FF00000000005E +:106440000000FF00000000000000FF00000000004E +:106450000000FF00000000000000FF00000000003E +:106460000000FF00000000000000FF00000000002E +:106470000000FF00000000000000FF00000000001E +:106480000000FF00000000000000FF00000000000E +:106490000000FF00000000000000FF0000000000FE +:1064A0000000FF00000000000000FF0000000000EE +:1064B0000000FF00000000000000FF0000000000DE +:1064C0000000FF00000000000000FF0000000000CE +:1064D0000000FF00000000000000FF0000000000BE +:1064E0000000FF00000000000000FF0000000000AE +:1064F0000000FF00000000000000FF00000000009E +:106500000000FF00000000000000FF00000000008D +:106510000000FF00000000000000FF00000000007D +:106520000000FF00000000000000FF00000000006D +:106530000000FF00000000000000FF00000000005D +:106540000000FF00000000000000FF00000000004D +:106550000000FF00000000000000FF00000000003D +:106560000000FF00000000000000FF00000000002D +:1065700000000000140AFF000000000100000000FD +:106580000020100100000000010090000000010048 +:1065900000009002000090040000900600009008A7 +:1065A0000000900A0000900C0000900E0000901077 +:1065B0000000901200009014000090160000901847 +:1065C0000000901A0000901C0000901E0000902017 +:1065D00000009022000090240000902600009028E7 +:1065E0000000902A0000902C0000902E00009030B7 +:1065F0000000903200009034000090360000903887 +:106600000000903A0000903C0000903E0000904056 +:106610000000904200009044000090460000904826 +:106620000000904A0000904C0000904E00009050F6 +:1066300000009052000090540000905600009058C6 +:106640000000905A0000905C0000905E0000906096 +:106650000000906200009064000090660000906866 +:106660000000906A0000906C0000906E0000907036 +:106670000000907200009074000090760000907806 +:106680000000907A0000907C0000907E00009080D6 +:1066900000009082000090840000908600009088A6 +:1066A0000000908A0000908C0000908E0000909076 +:1066B0000000909200009094000090960000909846 +:1066C0000000909A0000909C0000909E000090A016 +:1066D000000090A2000090A4000090A6000090A8E6 +:1066E000000090AA000090AC000090AE000090B0B6 +:1066F000000090B2000090B4000090B6000090B886 +:10670000000090BA000090BC000090BE000090C055 +:10671000000090C2000090C4000090C6000090C825 +:10672000000090CA000090CC000090CE000090D0F5 +:10673000000090D2000090D4000090D6000090D8C5 +:10674000000090DA000090DC000090DE000090E095 +:10675000000090E2000090E4000090E6000090E865 +:10676000000090EA000090EC000090EE000090F035 +:10677000000090F2000090F4000090F6000090F805 +:10678000000090FA000090FC000090FE00009100D4 +:1067900000009102000091040000910600009108A1 +:1067A0000000910A0000910C0000910E0000911071 +:1067B0000000911200009114000091160000911841 +:1067C0000000911A0000911C0000911E0000912011 +:1067D00000009122000091240000912600009128E1 +:1067E0000000912A0000912C0000912E00009130B1 +:1067F0000000913200009134000091360000913881 +:106800000000913A0000913C0000913E0000914050 +:106810000000914200009144000091460000914820 +:106820000000914A0000914C0000914E00009150F0 +:1068300000009152000091540000915600009158C0 +:106840000000915A0000915C0000915E0000916090 +:106850000000916200009164000091660000916860 +:106860000000916A0000916C0000916E0000917030 +:106870000000917200009174000091760000917800 +:106880000000917A0000917C0000917E00009180D0 +:1068900000009182000091840000918600009188A0 +:1068A0000000918A0000918C0000918E0000919070 +:1068B0000000919200009194000091960000919840 +:1068C0000000919A0000919C0000919E000091A010 +:1068D000000091A2000091A4000091A6000091A8E0 +:1068E000000091AA000091AC000091AE000091B0B0 +:1068F000000091B2000091B4000091B6000091B880 +:10690000000091BA000091BC000091BE000091C04F +:10691000000091C2000091C4000091C6000091C81F +:10692000000091CA000091CC000091CE000091D0EF +:10693000000091D2000091D4000091D6000091D8BF +:10694000000091DA000091DC000091DE000091E08F +:10695000000091E2000091E4000091E6000091E85F +:10696000000091EA000091EC000091EE000091F02F +:10697000000091F2000091F4000091F6000091F8FF +:10698000000091FA000091FC000091FEFFFFFFFF64 +:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F +:106A100000BEBC20000000000000000500000003D4 +:106A200000BEBC20000000000000000500000003C4 +:106A300000BEBC20000000000000000500000003B4 +:106A400000BEBC20000000000000000500000003A4 +:106A500000BEBC2000000000000000050000000394 +:106A600000BEBC2000000000000000050000000384 +:106A700000BEBC2000000000000000050000000374 +:106A800000BEBC2000000000000000050000200047 +:106A9000000040C000006180000082400000A300B0 +:106AA0000000C3C00000E480000105400001260092 +:106AB000000146C000016780000188400001A90074 +:106AC0000001C9C00001EA8000020B4000022C0056 +:106AD00000024CC000026D8000028E400002AF0038 +:106AE0000002CFC00002F0800000114000008000D2 +:106AF000000103800001870000020A8000028E006E +:106B000000031180000395000004188000049C001D +:106B100000051F800005A300000626800006AA00CD +:106B200000072D800007B100000834800008B8007D +:106B300000093B800009BF00000A4280000AC6002D +:106B4000000B4980000BCD00000C5080000CD400DD +:106B5000000D578000005B0000007FF800007FF808 +:106B60000000022A000035000000FF0000000000C5 +:106B70000000FF00000000000000FF000000000017 +:106B80000000FF00000000000000FF000000000007 +:106B90000000FF00000000000000FF0000000000F7 +:106BA0000000FF00000000000000FF0000000000E7 +:106BB0000000FF00000000000000FF0000000000D7 +:106BC0000000FF00000000000000FF0000000000C7 +:106BD0000000FF00000000000000FF0000000000B7 +:106BE0000000FF00000000000000FF0000000000A7 +:106BF0000000FF00000000000000FF000000000097 +:106C00000000FF00000000000000FF000000000086 +:106C10000000FF00000000000000FF000000000076 +:106C20000000FF00000000000000FF000000000066 +:106C30000000FF00000000000000FF000000000056 +:106C40000000FF00000000000000FF000000000046 +:106C50000000FF00000000000000FF000000000036 +:106C60000000FF00000000000000FF000000000026 +:106C70000000FF00000000000000FF000000000016 +:106C80000000FF00000000000000FF000000000006 +:106C90000000FF00000000000000FF0000000000F6 +:106CA0000000FF00000000000000FF0000000000E6 +:106CB0000000FF00000000000000FF0000000000D6 +:106CC0000000FF00000000000000FF0000000000C6 +:106CD0000000FF00000000000000FF0000000000B6 +:106CE0000000FF00000000000000FF0000000000A6 +:106CF0000000FF00000000000000FF000000000096 +:106D00000000FF00000000000000FF000000000085 +:106D10000000FF00000000000000FF000000000075 +:106D20000000FF00000000000000FF000000000065 +:106D30000000FF00000000000000FF000000000055 +:106D40000000FF00000000000000FF000000000045 +:106D50000000FF00000000000000FF000000000035 +:106D60000000FF00000000000000FF000000000025 +:106D70000000FF00000000000000FF000000000015 +:106D80000000FF00000000000000FF000000000005 +:106D90000000FF00000000000000FF0000000000F5 +:106DA0000000FF00000019000000000000000000CB +:106DB000FFFFFFFF000000000393870000000000BA +:106DC0000393870000007FF800007FF800000BA30A +:106DD00000001500000000FF000000FF000000FFA1 +:106DE000000000FF000000FF000000FF000000FFA7 +:106DF000000000FF0000FF00000000000000FF0096 +:106E0000000000000000FF00000000000000FF0084 +:106E1000000000000000FF00000000000000FF0074 +:106E2000000000000000FF00000000000000FF0064 +:106E3000000000000000FF00000000000000FF0054 +:106E4000000000000000FF00000000000000FF0044 +:106E5000000000000000FF00000000000000FF0034 +:106E6000000000000000FF00000000000000FF0024 +:106E7000000000000000FF00000000000000FF0014 +:106E8000000000000000FF00000000000000FF0004 +:106E9000000000000000FF00000000000000FF00F4 +:106EA000000000000000FF00000000000000FF00E4 +:106EB000000000000000FF00000000000000FF00D4 +:106EC000000000000000FF00000000000000FF00C4 +:106ED000000000000000FF00000000000000FF00B4 +:106EE000000000000000FF00000000000000FF00A4 +:106EF000000000000000FF00000000000000FF0094 +:106F0000000000000000FF00000000000000FF0083 +:106F1000000000000000FF00000000000000FF0073 +:106F2000000000000000FF00000000000000FF0063 +:106F3000000000000000FF00000000000000FF0053 +:106F4000000000000000FF00000000000000FF0043 +:106F5000000000000000FF00000000000000FF0033 +:106F6000000000000000FF00000000000000FF0023 +:106F7000000000000000FF00000000000000FF0013 +:106F8000000000000000FF00000000000000FF0003 +:106F9000000000000000FF00000000000000FF00F3 +:106FA000000000000000FF00000000000000FF00E3 +:106FB000000000000000FF00000000000000FF00D3 +:106FC000000000000000FF00000000000000FF00C3 +:106FD000000000000000FF00000000000000FF00B3 +:106FE000000000000000FF00000000000000FF00A3 +:106FF000000000000000FF00000000000000FF0093 +:10700000000000000000FF00000000000000FF0082 +:10701000000000000000FF00000000000000FF0072 +:10702000000000000000FF00000000000000FF0062 +:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C +:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:1070B000FFFFFFFF00000000000028AD00002918BE +:1070C0000000291900000005000000070000FF0073 +:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A +:1070E0000000FF000000FF000FFFFFFF0000FF0097 +:1070F0000FFFFFFF000000FF0000FF000000FF0087 +:107100000FFFFFFF0000FF000FFFFFFF000000FF69 +:107110000000FF000000FF000FFFFFFF0000FF0066 +:107120000FFFFFFF000000FF0000FF000000FF0056 +:107130000FFFFFFF0000FF000FFFFFFF000000FF39 +:107140000000FF000000FF000FFFFFFF0000FF0036 +:107150000FFFFFFF000000FF0000FF000000FF0026 +:107160000FFFFFFF0000FF000FFFFFFF000000FF09 +:107170000000FF000000FF000FFFFFFF0000FF0006 +:107180000FFFFFFF000000FF0000FF000000FF00F6 +:107190000FFFFFFF0000FF000FFFFFFF000000FFD9 +:1071A0000000FF000000FF000FFFFFFF0000FF00D6 +:1071B0000FFFFFFF000000FF0000FF000000FF00C6 +:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9 +:1071D0000000FF000000FF000FFFFFFF0000FF00A6 +:1071E0000FFFFFFF000000FF0000FF000000FF0096 +:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79 +:107200000000FF000000FF000FFFFFFF0000FF0075 +:107210000FFFFFFF000000FF0000FF000000FF0065 +:107220000FFFFFFF0000FF000FFFFFFF000000FF48 +:107230000000FF000000FF000FFFFFFF0000FF0045 +:107240000FFFFFFF000000FF0000FF000000FF0035 +:107250000FFFFFFF0000FF000FFFFFFF000000FF18 +:107260000000FF000000FF000FFFFFFF0000FF0015 +:107270000FFFFFFF000000FF0000FF000000FF0005 +:107280000FFFFFFF0000FF000FFFFFFF000000FFE8 +:107290000000FF000000FF000FFFFFFF0000FF00E5 +:1072A0000FFFFFFF000000FF0000FF000000FF00D5 +:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8 +:1072C0000000FF000000FF000FFFFFFF0000FF00B5 +:1072D0000FFFFFFF000000FF0000FF000000FF00A5 +:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88 +:1072F0000000FF000000FF000FFFFFFF0000FF0085 +:107300000FFFFFFF000000FF0000FF000000FF0074 +:107310000FFFFFFF0000FF000FFFFFFF000000FF57 +:107320000000FF000000FF000FFFFFFF0000FF0054 +:107330000FFFFFFF000000FF0000FF000000FF0044 +:107340000FFFFFFF0000FF000FFFFFFF000000FF27 +:107350000000FF000000FF000FFFFFFF0000FF0024 +:107360000FFFFFFF000000FF0000FF000000FF0014 +:107370000FFFFFFF0000FF000FFFFFFF000000FFF7 +:107380000000FF000000FF000FFFFFFF0000FF00F4 +:107390000FFFFFFF000000FF0000FF000000FF00E4 +:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7 +:1073B0000000FF000000FF000FFFFFFF0000FF00C4 +:1073C0000FFFFFFF000000FF0000FF000000FF00B4 +:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97 +:1073E0000000FF000000FF000FFFFFFF0000FF0094 +:1073F0000FFFFFFF000000FF0000FF000000FF0084 +:107400000FFFFFFF0000FF000FFFFFFF000000FF66 +:107410000000FF000000FF000FFFFFFF0000FF0063 +:107420000FFFFFFF000000FF0000FF000000FF0053 +:107430000FFFFFFF0000FF000FFFFFFF000000FF36 +:107440000000FF000000FF000FFFFFFF0000FF0033 +:107450000FFFFFFF000000FF0000FF000000FF0023 +:107460000FFFFFFF0000FF000FFFFFFF000000FF06 +:107470000000FF000000FF000FFFFFFF0000FF0003 +:107480000FFFFFFF000000FF0000FF000000FF00F3 +:107490000FFFFFFF0000FF000FFFFFFF000000FFD6 +:1074A0000000FF000000FF000FFFFFFF0000FF00D3 +:1074B0000FFFFFFF000000FF0000FF000000FF00C3 +:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6 +:1074D0000000FF000000FF000FFFFFFF0000FF00A3 +:1074E0000FFFFFFF000000FF0000FF000000FF0093 +:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76 +:107500000000FF000000FF000FFFFFFF0000FF0072 +:107510000FFFFFFF000000FF0000FF000000FF0062 +:107520000FFFFFFF0000FF000FFFFFFF000000FF45 +:107530000000FF000000FF000FFFFFFF0000FF0042 +:107540000FFFFFFF000000FF0000FF000000FF0032 +:107550000FFFFFFF0000FF000FFFFFFF000000FF15 +:107560000000FF000000FF000FFFFFFF0000FF0012 +:107570000FFFFFFF000000FF0000FF000000FF0002 +:107580000FFFFFFF0000FF000FFFFFFF000000FFE5 +:107590000000FF000000FF000FFFFFFF0000FF00E2 +:1075A0000FFFFFFF000000FF0000FF000000FF00D2 +:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5 +:1075C0000000FF000000FF000FFFFFFF0000FF00B2 +:1075D0000FFFFFFF000000FF0000FF000000FF00A2 +:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85 +:1075F0000000FF000000FF000FFFFFFF0000FF0082 +:107600000FFFFFFF000000FF0000FF000000FF0071 +:107610000FFFFFFF0000FF000FFFFFFF000000FF54 +:107620000000FF000000FF000FFFFFFF0000FF0051 +:107630000FFFFFFF000000FF0000FF000000FF0041 +:107640000FFFFFFF0000FF000FFFFFFF000000FF24 +:107650000000FF000000FF000FFFFFFF0000FF0021 +:107660000FFFFFFF000000FF0000FF000000FF0011 +:107670000FFFFFFF0000FF000FFFFFFF000000FFF4 +:107680000000FF000000FF000FFFFFFF0000FF00F1 +:107690000FFFFFFF000000FF0000FF000000FF00E1 +:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4 +:1076B0000000FF000000FF000FFFFFFF0000FF00C1 +:1076C0000FFFFFFF000000FF0000FF000000FF00B1 +:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94 +:1076E0000000FF000000FF000FFFFFFF0000FF0091 +:1076F0000FFFFFFF000000FF0000FF000000FF0081 +:107700000FFFFFFF0000FF000FFFFFFF000000FF63 +:107710000000FF000000FF000FFFFFFF0000FF0060 +:107720000FFFFFFF000000FF0000FF000000FF0050 +:107730000FFFFFFF0000FF000FFFFFFF000000FF33 +:107740000000FF000000FF000FFFFFFF0000FF0030 +:107750000FFFFFFF000000FF0000FF000000FF0020 +:107760000FFFFFFF0000FF000FFFFFFF000000FF03 +:107770000000FF000000FF000FFFFFFF0000FF0000 +:107780000FFFFFFF000000FF0000FF000000FF00F0 +:107790000FFFFFFF0000FF000FFFFFFF000000FFD3 +:1077A0000000FF000000FF000FFFFFFF0000FF00D0 +:1077B0000FFFFFFF000000FF0000FF000000FF00C0 +:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3 +:1077D0000000FF000000FF000FFFFFFF0000FF00A0 +:1077E0000FFFFFFF000000FF0000FF000000FF0090 +:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73 +:107800000000FF000000FF000FFFFFFF0000FF006F +:107810000FFFFFFF000000FF0000FF000000FF005F +:107820000FFFFFFF0000FF000FFFFFFF000000FF42 +:107830000000FF000000FF000FFFFFFF0000FF003F +:107840000FFFFFFF000000FF0000FF000000FF002F +:107850000FFFFFFF0000FF000FFFFFFF000000FF12 +:107860000000FF000000FF000FFFFFFF0000FF000F +:107870000FFFFFFF000000FF0000FF000000FF00FF +:107880000FFFFFFF0000FF000FFFFFFF000000FFE2 +:107890000000FF000000FF000FFFFFFF0000FF00DF +:1078A0000FFFFFFF000000FF0000FF000000FF00CF +:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2 +:1078C0000000FF000000FF000FFFFFFF0000FF00AF +:1078D0000FFFFFFF000000FF0000FF000000FF009F +:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82 +:1078F0000000FF000000FF000FFFFFFF0000FF007F +:107900000FFFFFFF000000FF0000FF000000FF006E +:107910000FFFFFFF0000FF000FFFFFFF000000FF51 +:107920000000FF000000FF000FFFFFFF0000FF004E +:107930000FFFFFFF000000FF0000FF000000FF003E +:107940000FFFFFFF0000FF000FFFFFFF000000FF21 +:107950000000FF000000FF000FFFFFFF0000FF001E +:107960000FFFFFFF000000FF0000FF000000FF000E +:107970000FFFFFFF0000FF000FFFFFFF000000FFF1 +:107980000000FF000000FF000FFFFFFF0000FF00EE +:107990000FFFFFFF000000FF0000FF000000FF00DE +:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1 +:1079B0000000FF000000FF000FFFFFFF0000FF00BE +:1079C0000FFFFFFF000000FF0000FF000000FF00AE +:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91 +:1079E0000000FF000000FF000FFFFFFF0000FF008E +:1079F0000FFFFFFF000000FF0000FF000000FF007E +:107A00000FFFFFFF0000FF000FFFFFFF000000FF60 +:107A10000000FF000000FF000FFFFFFF0000FF005D +:107A20000FFFFFFF000000FF0000FF000000FF004D +:107A30000FFFFFFF0000FF000FFFFFFF000000FF30 +:107A40000000FF000000FF000FFFFFFF0000FF002D +:107A50000FFFFFFF000000FF0000FF000000FF001D +:107A60000FFFFFFF0000FF000FFFFFFF000000FF00 +:107A70000000FF000000FF000FFFFFFF0000FF00FD +:107A80000FFFFFFF000000FF0000FF000000FF00ED +:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0 +:107AA0000000FF000000FF000FFFFFFF0000FF00CD +:107AB0000FFFFFFF000000FF0000FF000000FF00BD +:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0 +:107AD0000000FF000000FF000FFFFFFF0000FF009D +:107AE0000FFFFFFF000000FF0000FF000000FF008D +:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70 +:107B00000000FF000000FF000FFFFFFF0000FF006C +:107B10000FFFFFFF000000FF0000FF000000FF005C +:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F +:107B30000000FF000000FF000FFFFFFF0000FF003C +:107B40000FFFFFFF000000FF0000FF000000FF002C +:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F +:107B60000000FF000000FF000FFFFFFF0000FF000C +:107B70000FFFFFFF000000FF0000FF000000FF00FC +:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF +:107B90000000FF000000FF000FFFFFFF0000FF00DC +:107BA0000FFFFFFF000000FF0000FF000000FF00CC +:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF +:107BC0000000FF000000FF000FFFFFFF0000FF00AC +:107BD0000FFFFFFF000000FF0000FF000000FF009C +:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F +:107BF0000000FF000000FF000FFFFFFF0000FF007C +:107C00000FFFFFFF000000FF0000FF000000FF006B +:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E +:107C20000000FF000000FF000FFFFFFF0000FF004B +:107C30000FFFFFFF000000FF0000FF000000FF003B +:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E +:107C50000000FF000000FF000FFFFFFF0000FF001B +:107C60000FFFFFFF000000FF0000FF000000FF000B +:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE +:107C80000000FF000000FF000FFFFFFF0000FF00EB +:107C90000FFFFFFF000000FF0000FF000000FF00DB +:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE +:107CB0000000FF000000FF000FFFFFFF0000FF00BB +:107CC0000FFFFFFF000000FF0000FF000000FF00AB +:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E +:107CE0000000FF000000FF000FFFFFFF0000FF008B +:107CF0000FFFFFFF000000FF0000FF000000FF007B +:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D +:107D10000000FF000000FF000FFFFFFF0000FF005A +:107D20000FFFFFFF000000FF0000FF000000FF004A +:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D +:107D40000000FF000000FF000FFFFFFF0000FF002A +:107D50000FFFFFFF000000FF0000FF000000FF001A +:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD +:107D70000000FF000000FF000FFFFFFF0000FF00FA +:107D80000FFFFFFF000000FF0000FF0000001000D9 +:107D900000002080000031000000418000005200FF +:107DA00000006280000073000000838000009400E7 +:107DB0000000A4800000B5000000C5800000D600CF +:107DC0000000E6800000F7000001078000011800B5 +:107DD00000012880000139000001498000015A009B +:107DE00000016A8000017B0000018B8000019C0083 +:107DF0000001AC800001BD000001CD800001DE006B +:107E00000001EE800001FF0000000F8000007FF8FD +:107E100000007FF8000005F60000350010000000AB +:107E2000000028AD000029180000291900000005F5 +:107E3000000000060001000100050206CCCCCCC900 +:107E40007058103C0000FF00000000000000FF0020 +:107E5000000000000000FF00000000000000FF0024 +:107E6000000000000000FF00000000000000FF0014 +:107E7000000000000000FF00000000000000FF0004 +:107E8000000000000000FF00000000000000FF00F4 +:107E9000000000000000FF00000000000000FF00E4 +:107EA000000000000000FF00000000000000FF00D4 +:107EB000000000000000FF00000000000000FF00C4 +:107EC000000000000000FF00000000000000FF00B4 +:107ED000000000000000FF00000000000000FF00A4 +:107EE000000000000000FF00000000000000FF0094 +:107EF000000000000000FF00000000000000FF0084 +:107F0000000000000000FF00000000000000FF0073 +:107F1000000000000000FF00000000000000FF0063 +:107F2000000000000000FF00000000000000FF0053 +:107F3000000000000000FF00000000000000FF0043 +:107F4000000000000000FF00000000000000FF0033 +:107F5000000000000000FF00000000000000FF0023 +:107F6000000000000000FF00000000000000FF0013 +:107F7000000000000000FF00000000000000FF0003 +:107F8000000000000000FF00000000000000FF00F3 +:107F9000000000000000FF00000000000000FF00E3 +:107FA000000000000000FF00000000000000FF00D3 +:107FB000000000000000FF00000000000000FF00C3 +:107FC000000000000000FF00000000000000FF00B3 +:107FD000000000000000FF00000000000000FF00A3 +:107FE000000000000000FF00000000000000FF0093 +:107FF000000000000000FF00000000000000FF0083 +:10800000000000000000FF00000000000000FF0072 +:10801000000000000000FF00000000000000FF0062 +:10802000000000000000FF00000000000000FF0052 +:10803000000000000000FF00000000000000FF0042 +:10804000000000000000FF00000000000000FF0032 +:10805000000000000000FF00000000000000FF0022 +:10806000000000000000FF00000000000000FF0012 +:10807000000000000000FF00000000000000FF0002 +:108080000000000000000001CCCC0201CCCCCCCC24 +:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A +:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A +:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A +:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9 +:1080D000030303031342020250505020706080508B +:1080E0000200020006040604000E0000011600D67D +:1080F000002625A0002625A0002625A0002625A0D4 +:1081000000720000012300F3002625A0002625A010 +:10811000002625A0002625A00000FFFF000000008B +:108120000000FFFF000000000000FFFF0000000053 +:108130000000FFFF000000000000FFFF0000000043 +:108140000000FFFF000000000000FFFF0000000033 +:108150000000FFFF000000000000FFFF0000000023 +:108160000000FFFF000000000000FFFF0000000013 +:108170000000FFFF000000000000FFFF0000000003 +:108180000000FFFF000000000000FFFF00000000F3 +:108190000000FFFF000000000000FFFF00000000E3 +:1081A0000000FFFF000000000000FFFF00000000D3 +:1081B0000000FFFF000000000000FFFF00000000C3 +:1081C0000000FFFF000000000000FFFF00000000B3 +:1081D0000000FFFF000000000000FFFF00000000A3 +:1081E0000000FFFF000000000000FFFF0000000093 +:1081F0000000FFFF000000000000FFFF0000000083 +:108200000000FFFF000000000000FFFF0000000072 +:108210000000FFFF000000000000FFFF0000000062 +:108220000000FFFF000000000000FFFF0000000052 +:108230000000FFFF000000000000FFFF0000000042 +:108240000000FFFF000000000000FFFF0000000032 +:108250000000FFFF000000000000FFFF0000000022 +:108260000000FFFF000000000000FFFF0000000012 +:108270000000FFFF000000000000FFFF0000000002 +:108280000000FFFF000000000000FFFF00000000F2 +:108290000000FFFF000000000000FFFF00000000E2 +:1082A0000000FFFF000000000000FFFF00000000D2 +:1082B0000000FFFF000000000000FFFF00000000C2 +:1082C0000000FFFF000000000000FFFF00000000B2 +:1082D0000000FFFF000000000000FFFF00000000A2 +:1082E0000000FFFF000000000000FFFF0000000092 +:1082F0000000FFFF000000000000FFFF0000000082 +:108300000000FFFF000000000000FFFF0000000071 +:108310000000FFFF00000000FFFFFFF3318FFFFFB1 +:108320000C30C30CC30C30C3CF3CF300F3CF3CF391 +:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3 +:108340000C30C30CC30C30C3CF3CF300F3CF3CF371 +:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D +:108360000C30C30CC30C30C3CF3CF300F3CF3CF351 +:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB +:108380000C30C305C30C30C3CF300014F3CF3CF323 +:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E +:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311 +:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22 +:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1 +:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C +:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1 +:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF +:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0 +:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F +:108420000C30C30CC30C30C3CF3CF300F3CF3CF390 +:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1 +:108440000C30C30CC30C30C3CF3CF300F3CF3CF370 +:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C +:108460000C30C30CC30C30C3CF3CF300F3CF3CF350 +:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA +:108480000C30C305C30C30C3CF300014F3CF3CF322 +:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D +:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310 +:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21 +:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0 +:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C +:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0 +:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE +:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF +:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3 +:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3 +:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03 +:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3 +:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2 +:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383 +:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1 +:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363 +:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F +:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343 +:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B +:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323 +:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53 +:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303 +:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23 +:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2 +:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC +:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E +:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF +:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E +:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A +:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E +:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8 +:108680000C30C305C30C30C3CF300014F3CF3CF320 +:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B +:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E +:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB +:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321 +:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5 +:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301 +:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB +:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD +:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB +:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D +:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF +:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D +:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59 +:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D +:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC +:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C +:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A +:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D +:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E +:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED +:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58 +:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD +:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21 +:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0 +:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0 +:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0 +:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00 +:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0 +:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF +:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380 +:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE +:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360 +:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C +:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340 +:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78 +:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320 +:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50 +:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300 +:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20 +:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF +:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF +:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF +:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF +:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F +:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE +:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F +:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD +:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F +:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B +:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F +:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77 +:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F +:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F +:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF +:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F +:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE +:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE +:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE +:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE +:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E +:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD +:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E +:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC +:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E +:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A +:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E +:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76 +:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E +:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E +:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE +:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E +:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD +:108B10000040CF3CCDCDCDCD000C0000000700C003 +:108B200000028130000B8158000202100001023067 +:108B3000000F024000010330000C0000000800C0DC +:108B400000028140000B8168000202200001024007 +:108B500000070250000202C00010000000080100DF +:108B600000028180000B81A8000202600001828067 +:108B7000000E829800080380001000000001010030 +:108B80000002811000090138000201C8000101E85B +:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94 +:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15 +:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005 +:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5 +:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1 +:108BE000CCCCCCCC4100200003030303034202029F +:108BF0005050502070608050131313131342121200 +:108C000050505020706080500301020000000000AE +:108C100000000000000000001F8B080000000000A2 +:108C2000000BFB51CFC0F0038A0F093230688A2055 +:108C3000F8C4E05C760686751C0C0C5BB849D3075B +:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA +:108C50008098850F559C871342FF015AC0C7CAC030 +:108C6000A0C1865DFF3A35043B408581A11C88D9AF +:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE +:108C8000D81D201DAB46BE9B47F1E0C1378D51F981 +:108C90005B0DA169012A7E0B4D7E1B54BE4A074223 +:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B +:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F +:108CC000A7D8030000000000000000000000000022 +:108CD0001F8B080000000000000BED7D7F7C14D589 +:108CE000B5F8999DD9D9D9CDEE6608096C20E02454 +:108CF000861AFB82DFE577A841878034B63CDF8A9D +:108D00005AD3D6F6BB506C551456BF3EE1F56933C5 +:108D1000F941122262049FDAD61F2B554BFB6C8956 +:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58 +:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3 +:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7 +:108D500073EE39E79E73EE8DEAF3C3C7CE05388E06 +:108D60003FECD913028059D9A771F5BCAEBE99006A +:108D70004721D2D35D0AD0A68009AC6C1D88A41F00 +:108D800094007F6A14565E2D7F3CDE5D097067D1CA +:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C +:108DA0000F453743314011A4B6E277F6937890F53A +:108DB00037109C9C866876FC32F0D1B80015FAA179 +:108DC00022AA07C765F6CF81E47C18072083FDB38C +:108DD000067A593FCAF3721AC795E5C5FA8B55D979 +:108DE0007EBC4F595721A389FEF01FF9B2E26438C7 +:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0 +:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A +:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31 +:108E20009E8DA7AE668D9E1DCD3A6402000C64B384 +:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B +:108E4000089EF6B02F5D5489502701187EFD881FBB +:108E500009DF2FD1CC1CEDED279432FCD8F36578D7 +:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B +:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08 +:108E80000B23BE4D84017C7A0AE282DE9F9486E940 +:108E900047D05931783F23E1BDA8C6971D97FD0DF6 +:108EA0001A21179F0462256EBEF1F225E2A90CE992 +:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9 +:108EC000F989A604C3C7DA66B05E73B4936360A67B +:108ED00073E069B568678FA794B27A39FA076811A9 +:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28 +:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0 +:108F0000B68807CB21256DF990BF4B21FE207BF859 +:108F100035BECEECEFDF073FF5B303250E1BA74DA3 +:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5 +:108F300087517EB1769224F0A1F502F25FD1070A43 +:108F4000C05884CF844404605D7583369CFC015D09 +:108F5000F9539FCD775543F9EEE36C18842B14CE6B +:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C +:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC +:108F80005CB7C758BDD942CECAD43FC911A8009218 +:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21 +:108FA000318E34B45F6FBB0128E1F811F0D8725DE7 +:108FB0008627A89F41789404E1CBFBDECFDEEBE16E +:108FC000937F7FB265BF9167BC1E89F869A4F6AF35 +:108FD000087E19C29F79E8BA5FAC33057A4D383DF7 +:108FE000CB47367F9D281F9D349FB0E1495FE4E168 +:108FF000130B52B46E5835AB7BDAE8F925079F6442 +:109000009CF5174B63F83C9438F10B834721BED590 +:10901000393C65D34BA93F09D7F819D88328231EBB +:10902000D87C97D9ED214EEB3584768EA33D9B1CE1 +:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006 +:1090400083E8DF032FEB4F73F627438587CF39DCA7 +:109050001B242EDF58FD0CE1D33BBE2211BC322471 +:109060002C1F6BB7598CEF955FF673BBE86FBD048F +:109070004DBD61BE9E9638F4618324E484C6D799C1 +:10908000573EF991AF669C385F152AD7174BB9F553 +:109090000EB38A621746F2EB9D629FAD0F323141EB +:1090A000B751D1FD74A9C445F742E15D7682F04E17 +:1090B0001C0A6F417C76A6E41B959EBCE104E10B83 +:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016 +:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B +:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5 +:1090F00038EE730A85EFD191E103F804FB6BBD6A8A +:10910000990AD96B0013009E6E79D5B2942C7C26F7 +:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC +:10912000FFF996B75CE32B8C7F90D90A1DF7854237 +:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207 +:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC +:10915000E3FEFE04F9B152AC97064977E9817CF64B +:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8 +:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356 +:10918000D73F5DD44F15585FF2F175984F7FCE975A +:109190006CFC816BFFD1A6713F88D9A640F09CA1E1 +:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44 +:1091B00084FC226B0012E837F92624EB7CAC1F6399 +:1091C000C74DF761BD238AA677EBC01724FB1E3C71 +:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C +:1091E00083E45F493549EC59668575F4DB0C5425F9 +:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927 +:109200009326E9322BFFCB39736FFB0C6B35F0E102 +:10921000CE974EC37AD3C655B592BC3425C44F6998 +:109220005C35E5287B5E7C71561FE03F8B1D6566D3 +:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5 +:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4 +:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483 +:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5 +:10927000AEF4B72C65CFB004BACC9652715CA5F9A8 +:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE +:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85 +:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035 +:1092B0004474DD3909E9621527397D40AA66CF2358 +:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604 +:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D +:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630 +:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB +:109300007B262ACC88DFD27C173DEDF9A12431ECF5 +:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE +:10932000D1FE7603CA113FCAE1745B14DFD7C1B422 +:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C +:10934000926D3437B745D93CAE2B87E9D8F7CE9725 +:109350001FE3DF2B607A8095773536905CED89FBD3 +:10936000D2814A82FF7CE4E79E461F3093078AEB56 +:10937000185C0EBC0662EEF2AE4626B066123ED215 +:1093800001293B7F852D33C4C746B32AE8DC57CF7C +:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F +:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C +:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1 +:1093C000982F8DC6E716813F1BBF03112E5F3636DF +:1093D000733F603E78367EEAAAD8707E03B5B1232B +:1093E00081FE54B5B1270167E1332D9EBD09A79FCA +:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0 +:109400008FB7FE785925793750C6BF77C45ED3979A +:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98 +:109420007F3FA22D0DE7683F897DCF4197A532FF91 +:10943000FEF4CB81863B901F057E77BFFC13AD1AEF +:10944000F1FDBC0CC8671BF73590BC453E4379B1B4 +:109450008BF1455F2DD27FFD2BCE755B5CE72E3304 +:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52 +:10947000EE157ED93DCD317A3EDD6CD07357730D3C +:109480007DCF34C7A9FC54731D959F6836A9FCE3B2 +:10949000E6462AEF684E50F9D1E6267A6E6F4ED234 +:1094A000734BF315F464FC4BFCBCA13925FCC06B79 +:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B +:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED +:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B +:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB +:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7 +:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD +:10951000B9BECBD47E64FE59D65589FC93F6C52DD1 +:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD +:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3 +:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0 +:1095500001CC64C42ECFAF5773D877649F061240F6 +:10956000F69D1FED34477B75722A69E6D09F57F947 +:10957000E66F95593F8152E8C0786840C9E3E795A6 +:10958000F93E25A0F1EFC16A93ECB26230A6CB633D +:1095900000AE796C5EF932F6FEE7421F765C089603 +:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682 +:1095B000FB18FBB9E9879126FC0EA5334798378F36 +:1095C000D7C8136737FDC660CF0B666F59CBDE86F1 +:1095D000AA9319F2019596927D9A0C19D4AF5997D6 +:1095E000B67CA518478338DA8972D884241B67AE05 +:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0 +:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110 +:10961000E905494BE2FEA9F8830C447F69DC653F0C +:10962000D9F353948499C8616FFC4EE04BD2E34D5B +:10963000DC0FA202CA877CF50FCAB6FFC972ED071C +:109640008BA13F23231C311E6F82631719174E1DF8 +:109650000A87AA2492380EC6AB37B371DAC77CC624 +:10966000483AC6F948E67E2A2966123CAACEE1515C +:1096700095B899C8C14703021EBB1F3B6E26C5FAA9 +:10968000A12F9C856F6D30D184FB256B8C4A786A45 +:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057 +:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8 +:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88 +:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A +:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6 +:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C +:1096F000B8364823C3DF21E0B7EB752A294DCF895F +:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27 +:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331 +:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC +:10973000BE8778FB7082FC5B5A38614055361EABA1 +:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8 +:109750005C92916A427ED22AD83A9286B6B39F49E9 +:10976000D1BEF3C3FFF712AD93328DD68964B075C5 +:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F +:10978000477232D77A5921E0D116270CAD8A427838 +:109790003CDFC303C73A85EB834336FC568AFC564D +:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D +:1097B000DF26E02901A3857C990697B300171ACE0E +:1097C000BC8B37C4F825424E314C11DDECEFFF2540 +:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF +:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815 +:1097F000898411AB22559F93AF9E1070F42B228E5B +:10980000665D3B2ABEFAD702E7F144962E8F09BA6D +:10981000EC186E1E8F8A79F4C830F70DF4339E2E43 +:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F +:10983000FC4ECCABD0F93C53209F1DCDD2E5393145 +:109840009FFDC3CDC751FF4551FF25519FFCE74701 +:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7 +:10986000AC776DFB2CBBDEABC80F5223D783ACDECD +:109870006BCE7A605DD08AF6DB5A8C897E02E081FD +:10988000F6AF3688766F52BBC583FDBF25D607B5C8 +:109890005BD73EBFD50A53BD77F07DCB828FEC7A84 +:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D +:1098B00013CAE7A9BF217947B19282EC1F7F699251 +:1098C000F2F74A20D283FEC50E2545FE640C36A071 +:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD +:1098E000237F6A005270177BBFA154A1F8C862257C +:1098F00019F1A31D21252D0AAE827E590BF63FD604 +:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24 +:109910008BA23B91AF364E520DE4AB9D936E20BFB0 +:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E +:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F +:109940002D67E5BE96625D3A87E641705B3E48B49E +:10995000CD74E42332B80371CAA7233FDC6D8D3C7C +:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2 +:10997000FBDE59A792FD7A5B45D57C1C6F539D4653 +:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3 +:10999000E8678FCE519901CECAA5460BDA9B91D9C3 +:1099A0002140BF5349051F2F7206901FCA0F3D89E2 +:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0 +:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B +:1099D0001EFF441910EF367DA33D83ED87CD638CC8 +:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493 +:1099F000582F5D60BD0CAF17800B87CDE78338CF44 +:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5 +:109A10007BBE8F362FF42ABFC80B9D0373785EE898 +:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31 +:109A3000F3F07E63FFB81B62987FD959F655F1BCED +:109A4000913FCBC5FBF2353194779DE5E27BF98DF3 +:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5 +:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A +:109A7000E6596A8AD540EB76B18FD66D008501AE86 +:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F +:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9 +:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC +:109AB0002517B47EFC3D05D64B17582F53583DB59E +:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A +:109AD000AB727D0E7F68C578BFFF139AABBCF613DF +:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2 +:109AF0006C777B750E6F1FEC800518CF2F749D1C43 +:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2 +:109B10002F510CC89492BE4A0BBD95331E7E9ACA33 +:109B2000D77F959FC7CF6F53F420EE23FFD6E72949 +:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297 +:109B4000E47D438C9F7FF043288E768EB1506B78F6 +:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB +:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C +:109B70001E5221D158C9FA6BABF0913DA28447D057 +:109B80001B150EB995232F2FEB970213CF53D02718 +:109B90000360FE9B7CDC501C08EE08F4D166BA180A +:109BA00053E54E07180386C493BEE212CF13ACD719 +:109BB000519E95064F75BF9751BF92791B1C2F1A66 +:109BC00045BF4A1FE5CB9CF27E478037087753BFDD +:109BD0006C97547A7C6CB65F7F2C452F314F56764C +:109BE000E4CBE1B908CA37F1C53394DF30214AFB31 +:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B +:109C00005A09E3BA15579B7DC3F079331357E4F72C +:109C1000AC586EF6D5E4AF3798A78FF99E39D64188 +:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775 +:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4 +:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82 +:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3 +:109C60007A12E1147AB26D047E1FD1EE51E3C95C21 +:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F +:109C800035146F8F217E717F3B06BAA4FFC3D9873D +:109C9000F2A52AF6BC8478585BB62836DC7CD90657 +:109CA000EAF0205D18897F16321F4179300C1C3F85 +:109CB000CC0507840BF37FEB0BE3C48783F65229B3 +:109CC00088FD98199518DF870457DE32737306CF25 +:109CD00043F897864DA49F6C6E01F457DB76936C26 +:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD +:109CF00044EB87B7AB654FF939D56D0FB535EF003C +:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3 +:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2 +:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D +:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5 +:109D4000ED283B288FEFDE05682F770F96D93690E8 +:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9 +:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC +:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB +:109D80005AC04FFC477B576A6FB5617F414594E1EC +:109D90009105EE3298084F50E3E505816DD43F8977 +:109DA0000036DEA7033FE0E34D11F96DB54B46C029 +:109DB00023F7EF5BAAC1FD5DB525143F52E3717433 +:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4 +:109DD000FFBA1941AF093846A23F4307F9D1EDF365 +:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B +:109DF0005B7886ED09353927C0DA47CCDE4C252B58 +:109E00004717672C5ABE058E3B3660E7392669FD39 +:109E1000DB7856746E77ACF0D0D15FCAE3754171D0 +:109E2000FEA4507893AA1847F4030F37940F67AF36 +:109E300095257C68840DCA8BB18D21E19CE1E531CB +:109E40006689AB5C5C37C1553F12AF727DF7EB1F83 +:109E5000777D3F513A5DE299C7A784DD6897CFF5DA +:109E6000CEB3C07E0F1627560570DD34404D8AE113 +:109E7000F5CE2F3C44F80F0DAED385ED6605E58396 +:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A +:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7 +:109EA000F96B9D67B45BF81D5AC96F0B152958E211 +:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE +:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2 +:109ED00062E8AF5C77E64331207927E58C07FE3CEA +:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126 +:109EF000876483EB21E535D4873E8BE7E3AB10DF46 +:109F000067A25D54C3FDD521F19DE85899AD3F4846 +:109F1000574FF9EF34AED77F87491B0CCEEF159B17 +:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2 +:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40 +:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A +:109F500048C00DDA9163A5E3ECF93DA417CAE39B71 +:109F60005280FA7BED990F35215E02997F0283E1E1 +:109F7000ED1F27A5C040FF6F80C315B8AC07483E52 +:109F800057F7109EBDF85A3788F7B40BEF3F0970AA +:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB +:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4 +:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB +:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A +:109FD0005B19C76E22B9DB3D6923C533D7556F26A0 +:109FE0007BF228B323F0FC747765EEF69DCD3C3F01 +:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D +:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F +:10A01000FC27471EE0EB72947C8766213FCF50D629 +:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7 +:10A030001E70E64BBE2FF82213E0722658C1F9A31A +:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B +:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E +:10A06000FBF42F173ACE7BB52B694D47F86B364A78 +:10A070004EBBF61B6632A439F627A1D805BF5C8813 +:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2 +:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D +:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9 +:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17 +:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8 +:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2 +:10A0E0002F200FDE87788C1B590CCF39F65743F1A0 +:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9 +:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40 +:10A110007757703C77D66CEEAA72E2B966D7DE4A02 +:10A1200003C7E7787E48E3E773438867079C5E3C94 +:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A +:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920 +:10A15000D1FEE94E29AF5EBA442B402F758A757443 +:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5 +:10A1700083F66F0B501FB27ACBA89E9EA27DF06033 +:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5 +:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F +:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2 +:10A1B0007F663B2696F4F083D2E3927B363F942F62 +:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8 +:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E +:10A1E0005928B94DE376209D83B0BE51946E636DBE +:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D +:10A2000070947A699FB0D73AC6301955CC9EFE44F7 +:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B +:10A220005182FC6BEDB1CFECE863B4331B7B20971C +:10A230009C4F86923FC7F9A9BA65927A15FE917C28 +:10A24000FD9626AC9D7B6792DCEDC7BC461072186C +:10A250004D6BF4C74519DE0E69E4C288A37FADECEF +:10A26000626B3ECAB10AC62F587F5CD33E29992B38 +:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E +:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29 +:10A29000A638F06ED3E90E2971E179284FE7713ABB +:10A2A000158F924E03824EB098E7A19E7BEC5C8D99 +:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7 +:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E +:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663 +:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A +:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C +:10A3000056CBDC7F7E67D1D7280F618D15D003A592 +:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687 +:10A32000B7566FC5FA9B0012E8976C9997A2787F91 +:10A3300054D1F4D638C2919A837A225A6AAFCF1F89 +:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8 +:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35 +:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9 +:10A37000875C65ADA2C455564B270C1BB7F819FA7C +:10A380008966E17CFA208E70E6C9179E12E476B6E3 +:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1 +:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E +:10A3B000D5A2B955BD180782319C2F304FD0C90F97 +:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526 +:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB +:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F +:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451 +:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D +:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF +:10A4200019CAA1FFA67DDBCD75BE46944306F45242 +:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B +:10A4400047A25326817A61435CF1A11CF99BE3C3C7 +:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF +:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4 +:10A47000E3C5F757C1CBA0BED0922B916FAE88A990 +:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694 +:10A4900081F126F8969FDFC7847ADBA15FFE180C56 +:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB +:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054 +:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51 +:10A4D000F919DEEF2B6448E53AB72885346167F651 +:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B +:10A4F000D13A8EEC1871AE61C5966775C501E70A51 +:10A5000085A9BFE943E763E37705AAC91247FBF4CE +:10A510005E577B6FBBC1FE447B66B7F9430C3E536D +:10A5200049EDC578B37D7E43DD323F436A330FDCAE +:10A530008C8E270577A1E7388E3CD0D681FB6DB491 +:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5 +:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5 +:10A56000E4A3CF79A12087E714F3D759210F7FF512 +:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29 +:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A +:10A59000EDF3B5637C95E07C95899E5D085F097855 +:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587 +:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2 +:10A5C000B8D74AE4B54306ED8940A949767448DC1A +:10A5D000CFA355BBE5A612739F9B8835253276BF66 +:10A5E000E8BF0CAC5169DCC1F8711832C12896790A +:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06 +:10A60000F65311F96A98CB4BF7B2C1E747C86F719F +:10A610008F13BB78F8FC1A6F7D082BC62107DEF379 +:10A62000B753E090639FB341DC2B6AE3DFDCB29465 +:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724 +:10A640004E7CCEC573BCD375DAAF55F0788B257DC3 +:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7 +:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81 +:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D +:10A6800032FAF79F098DA37ECEE9EF931738D6E50E +:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6 +:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1 +:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656 +:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961 +:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF +:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A +:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47 +:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D +:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B +:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60 +:10A73000B55B89874F049EBCEBBBAEA711DD08510A +:10A740004836CE9708BDFB5D7E92035F6FF932E617 +:10A750006B2C0D9B12EE65A12FF3249B5789A92525 +:10A76000F0DE98E2FA1E6932E677C4781EF937AF58 +:10A770007E2DF3322BDFDC5444655D379E5B84F81D +:10A7800028D5C99F72337A5C48407F732DE627D065 +:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4 +:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A +:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E +:10A7C0008372A8C49367A22F74E7A5443DFD4F454B +:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708 +:10A7E000FAF434D607630CE60D861B9981C4E83968 +:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA +:10A80000A7D350C4E5D584AB6E97709F7134CEB892 +:10A81000621A96DFCC997FD52EE4C76059DF45F2E6 +:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A +:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD +:10A840003378D65F8EFEB1E56EBC8F962ED714712D +:10A85000793512FD4F761C9B6E43D7478BA0DB03E7 +:10A860001417EDAE195EEE0FA5DB36D277E1DADC18 +:10A87000F9BAD715492E796C3F3548419CF1892C9E +:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9 +:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329 +:10A8A0001940FE3601ED24661E111FC99EFDDC46CF +:10A8B000C14741789EDAB35560E9A45752A03BF2F4 +:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E +:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F +:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D +:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3 +:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C +:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9 +:10A92000E5ED741C90081F659313F7E3FE0C7E257C +:10A9300003CFCB0413F3F656FF74167D1F1A574846 +:10A9400054225DDE3A50A4B75616922F9948B6B0FD +:10A95000FAC68140BCD520D5E2D3908E7D12D1516C +:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE +:10A970000E96158BE29B5DC674CD294FCA42C95F06 +:10A980001639E3F622AEEBF5AF07C3EDB16760F41D +:10A99000F18FD2F120E2F29F5F84F64B17AE019E59 +:10A9A0001747797A5DE5BCFC46D1944518DFE98A02 +:10A9B000F07271F8C8792D246713E4FF5BC3180E99 +:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791 +:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0 +:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750 +:10A9F000637C7A62D2CED774C74526A0D660F39B1B +:10AA0000C408E3677838ED626845B6A9BCACB71CEA +:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939 +:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829 +:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA +:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF +:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC +:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3 +:10AA7000B9A86866D719182F7A5EC61505153D3B2B +:10AA800025B4E7EDFB2010AD174FE5F3C579058040 +:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7 +:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768 +:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9 +:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC +:10AAD0003D771D567112E33103FE5417CAAB0DFFCB +:10AAE000E883CD34FFD1E937454FD03D7A15297D34 +:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42 +:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A +:10AB10007D678CEFABED7D783294BC3CECB0CF75AB +:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4 +:10AB30002B4F1EF31D11AE97A718AB79BF9386F765 +:10AB4000CBDA78F9A04B16BF1721134438FC8C914F +:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3 +:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362 +:10AB70004193CDCC3AD41B93533E40FBF4F688412D +:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7 +:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396 +:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06 +:10ABB000EBDD953758680F6CAA0013F5B8FF46B661 +:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64 +:10ABD000D6255263ADD140F6C3D1182F072AF839D4 +:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C +:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96 +:10AC000053EB1AF310DD4B635D033CDE69C7A515FA +:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB +:10AC2000C0F891E44C17E613E4C0676798E3F30EAD +:10AC300021E706FCF0298A97B4F8E83E176FFD6516 +:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45 +:10AC5000977FA3E20395E6B348BE1174A43BB39378 +:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D +:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190 +:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A +:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2 +:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3 +:10ACB00049FCFE196FBD83C25E64F620F1CD268B80 +:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF +:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3 +:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F +:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686 +:10AD0000AD805E4ABADFD858528971A15B6F540D8D +:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7 +:10AD20009A781EBD223ECEE8769CF72EAE7894CE61 +:10AD3000C3DFFE54000275783FA9E7F7D938E9234D +:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB +:10AD5000308833388F220B0CBA1FD9E8253BF4A872 +:10AD60001544DD0A467D2FD72BED2178308EF7CCA8 +:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273 +:10AD8000725175A29BECF369DBF55CFAE153914AD1 +:10AD900097DF24E4895369C91B9AB89F56852939DE +:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8 +:10ADB000F2C79B42DFE8D97D32F107C92E468F707A +:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355 +:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C +:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F +:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25 +:10AE0000632CEB03F37AD933E7BDD3078B785E78F5 +:10AE10005751624984F27281EE195E27E4C679F2D5 +:10AE2000CF8298871504A6E7908F16FBE0C11C74AB +:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5 +:10AE40007DA276FB83C20F50B81CE6F39D620ED044 +:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64 +:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4 +:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408 +:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9 +:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2 +:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6 +:10AEB000417D99562084FA7C008D4966C73D127EFB +:10AEC000A403F35DFCB5695064DCD70338EFF737B2 +:10AED000602FD9597EA687C96E52FA5A502EB5D71F +:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321 +:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9 +:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E +:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2 +:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB +:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5 +:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000 +:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975 +:10AF600014F9E71DF0917FE81DD81F9DE180676708 +:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A +:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D +:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056 +:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264 +:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82 +:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6 +:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD +:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B +:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A +:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2 +:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5 +:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB +:10B03000BFA84F8244AEFB77CA42C931D15943EF12 +:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121 +:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526 +:10B06000183F565CFC5184F11466F7AE12F6655138 +:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12 +:10B080008533329E6BAD73E73FDD59F44592BB2BA0 +:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C +:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5 +:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F +:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4 +:10B0D00019E11AC4838F9FA7D559D931CF233D5287 +:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F +:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545 +:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783 +:10B11000E10864487FA555D45F576D9773EA77CCF3 +:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503 +:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB +:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D +:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D +:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065 +:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0 +:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0 +:10B19000055BBF17453CACDAE18ED3ADD8FA610749 +:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74 +:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7 +:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0 +:10B1D00053B8C35DB5C32DF7566D799DF222741F28 +:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7 +:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165 +:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB +:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360 +:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20 +:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC +:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85 +:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545 +:10B26000E387B3AB905FD301275C69A2ABB143E244 +:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA +:10B280003FEAB995BD1FAAB83FD963423FE267F7CD +:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496 +:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF +:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7 +:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA +:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA +:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3 +:10B2F0007930127EAF90385C5D51F3A728EF0F6F65 +:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC +:10B3100017110FFD4F0674FCFD12573DF922ADB316 +:10B32000777FF89C6A505C07A2D26C5686C19FFD5D +:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19 +:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B +:10B35000817A335D46F35E99E6EB61657AE7C578FD +:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF +:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B +:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190 +:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3 +:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61 +:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC +:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38 +:10B3D000B55714485A132BB3F01E46FB82C17BF8B5 +:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5 +:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7 +:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341 +:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A +:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F +:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2 +:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839 +:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35 +:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102 +:10B470009F67FBFECF503E90DDDF631E7CCE79DE02 +:10B480005A1061FDCDE94BCC948DA172A3EE00DB87 +:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57 +:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07 +:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688 +:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B +:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32 +:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182 +:10B4F0006F18129E2D99DB674CC7F917432FE0791F +:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930 +:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155 +:10B520006B7B092F858CAB9DC0B8B79E8271C327FA +:10B53000806780CD058DEBCDB3F28EAF4EE379639E +:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9 +:10B55000A5C586EBF7958192A17BABB3791769A955 +:10B560007326C6EF06CF1B2734C77963F69DCE1B23 +:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0 +:10B5800080F705219F0215A918DA5F9D79E211AFB6 +:10B59000083EEF8C346838999DFAF4E2BE61F48677 +:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403 +:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D +:10B5C000379B80D61C706E17EB07EB5562BD581287 +:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569 +:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD +:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3 +:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69 +:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF +:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D +:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545 +:10B64000316F425B73761CCF6B876AF8EF61D8303D +:10B650000FE26106DF863CFCF13F595ADE2D008087 +:10B66000000000001F8B080000000000000BED7DB3 +:10B670000B5C54D79DF0B93377EE3C813B30C0F082 +:10B68000BE8310D1623A28A2363E2E0F0D3E62468E +:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD +:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C +:10B6B000358FF61B4C74ED635B626CE2F6D30613B8 +:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90 +:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2 +:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8 +:10B6F000840C151342F8B08DB808D95762B2433A9A +:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907 +:10B71000553322F9CEBC442E48FBD999F73819A6E7 +:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC +:10B730009287E6E55B7C561F4D5D24C3544ADB953A +:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9 +:10B750003220ED2C17324C3A787ABED04402749CD9 +:10B760008E72612DC0690D7F9E480991F2274513A5 +:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977 +:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB +:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997 +:10B7A00037FB06AF92FC69341FBE2A73302F0F9906 +:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF +:10B7C0006112A4E327160D1398BF43229249C27E4B +:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA +:10B7E000FE608E09A719E649D7D1D15CEA2F48211E +:10B7F000C4D63CDF5F40D725811F2222ED2741625E +:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5 +:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2 +:10B82000E2092A30FFC4D90C2F5A79A2344C643A69 +:10B830006E2261F324A5443E4693845285C0387439 +:10B8400048593F9F07547A7C409D0FFCC969588F27 +:10B8500010FA29415E74D57C2BE479F256112BFF46 +:10B86000D0477041DFB2A979F3D87CBCF94C94EE93 +:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06 +:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1 +:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD +:10B8A000FCED55DBEFFD2F86BF513C71A63540877F +:10B8B000D178D4EA578CC2AD205DD276847C0AF26E +:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82 +:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1 +:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6 +:10B8F000139F891CA328ED9AAB7861BDBA9153229E +:10B90000FDFFA33809EB774A8289FB244DCF2C4CED +:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2 +:10B92000EC8D21DF4EABF335373B671C9D111F8F2C +:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7 +:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974 +:10B950001FF2F9609C441CC7A5C2E52A349156DF4A +:10B96000C4701E57E98A6FB68F0B270F70C69033CD +:10B970001A9CED00A7273E9CCE9C0AA453BED985F5 +:10B98000E30C8A125B0F4B936D239D9FAB35496A85 +:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94 +:10B9A0005450B8F969D309A1FD745C9A659B04B43D +:10B9B000DFDC43023A391F74042F89B43F5E0C92D6 +:10B9C00020859377293280F1AC4A07DABA91A264D4 +:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B +:10B9E000274E8B4CC462E8C7248740DF416773222F +:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C +:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E +:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD +:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42 +:10BA3000EFBCA2E115FE15133CEF38917633809FE1 +:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903 +:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7 +:10BA6000416124BF870F213EBB5DBD5DF9749E8A95 +:10BA7000DFE42FA4EB45B24B0D788A4E096965725D +:10BA800070CCBAAE96C2B47D779189B702BD1690DC +:10BA90009019F092ED41BED4D635E8607463F13070 +:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B +:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2 +:10BAC000C1D499509304F8232FEF22D23400C3C875 +:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E +:10BAE000AF68F6103F48AB660549A89BC37CC0967B +:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11 +:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD +:10BB1000EF68F83447C6D3E3C7047AE78C25748C02 +:10BB20008BE02941FCB47790DC089E9A6C208F3A18 +:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE +:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA +:10BB5000CA05536C797E48956B5480F30BE9380B1A +:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7 +:10BB70000915C815017F15E0AD6A4D00C882085946 +:10BB80001F7C2288F45025025E3865B2E943E78DB8 +:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE +:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F +:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E +:10BBC000190B69EA02BC93736602765A5A3803CBA2 +:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2 +:10BBE0007F70ED5D7ED443D76F23614A3728CB4009 +:10BBF0008E65CB61B0A779512A374B30CEA336F092 +:10BC00006F3ABD354984D9DB24961ED8E20EFE007A +:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B +:10BC200022013BC07E810B812E3BB0727ED77029F2 +:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B +:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F +:10BC5000871FF0D05548979CF6F3BBA79C2142F371 +:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E +:10BC7000823D65FB603FFA8736D53F247CD32C5844 +:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902 +:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F +:10BCA00086293D99148E7C48E9D3E6DAE63D25C124 +:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4 +:10BCC0006712726431D8919D206FD06E250A07EB00 +:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6 +:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1 +:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754 +:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789 +:10BD100035C8CD4E4A975609E87097C14FD6528D17 +:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4 +:10BD3000A707E9D1E609A01D1D5D7F450AB363345D +:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3 +:10BD5000672D68221CA5138BC8FCE189E6110F3EF4 +:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75 +:10BD70002FC5F96C71CB93927578F4E451BCC798D8 +:10BD8000CF5792D97C3A027581FB69BF72BDA4205E +:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448 +:10BDA000543D9E983DA2F5AF704D8316E0730F6D24 +:10BDB00047BFB6939714587A8B2764E0EF2FA604F9 +:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05 +:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE +:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC +:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B +:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910 +:10BE1000AC959761BE8763E58F242F58AC14E37C03 +:10BE200050EE754D30AE395486EB77F3FDABF25BD7 +:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9 +:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC +:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621 +:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324 +:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3 +:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C +:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A +:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070 +:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3 +:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41 +:10BED000991DFBF79D9982FCBA4B647C34A11CF23E +:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B +:10BEF000F9FA693D5F533DD90BFC24902A8570A067 +:10BF0000871FF0333B4451E569E05832DA81016C18 +:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC +:10BF200046DF22F361DB30F2B5BC3CA38C10170373 +:10BF300081ECF287492EE025C34C6D31204B818482 +:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7 +:10BF5000110CF3E02F382F996E05F8587D4D0FF135 +:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6 +:10BF7000B6E30793557FD0497240EFB5B79C206F69 +:10BF80005B22FDF05171252DD5ECF9875358DC6209 +:10BF9000949E2446DF2F503F1DE8B1E31766D21B65 +:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4 +:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B +:10BFC000063CE635271BF23E25D3507F5257BEA1D3 +:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD +:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C +:10BFF00049F86E43FD1967361ACA670E3D64289FDB +:10C00000757EAB213F67F8AF0CF5BD41F1E409E067 +:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7 +:10C020009BCFEC63D0B7249BA8F631554C694057A1 +:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC +:10C04000FEE50B16C91BA15DBB68225E9D1C911607 +:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2 +:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C +:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2 +:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A +:10C090006B74FF90499E9CC2FCC3AA731E83DF830E +:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37 +:10C0B000FA3756D3879FB871FF269ABF684A714EE8 +:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60 +:10C0D00096F810CA3B2A17CB530C72315005F31354 +:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE +:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E +:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD +:10C11000447510CAD9E8FEA95D7537C2E965F4A473 +:10C12000F9439ABF65A3F203FC2B9B44105F568A28 +:10C130002F27DA478FA27D49E721817D64F550FBE7 +:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6 +:10C150004FD5972187DC94921ABFFF17E3EC479DD8 +:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E +:10C1700056203A3ADEFB125B77DA2291D3F62F246F +:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8 +:10C190005EDD37BB06DB0993780272266178C33215 +:10C1A000D093A494C90985FE03F4E62836CA0D5B32 +:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2 +:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD +:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6 +:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C +:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA +:10C200006736113FE067F670980469FF3FF4B0F5B8 +:10C21000C8F48738B0CF332F873880F3A085C58521 +:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896 +:10C23000F78A3C17F2E9671713A48F21EFC69E72A5 +:10C24000D857984BFCC03F2E0F4F32217FDE1A4249 +:10C2500079E21F51A8AF4392E944614DAFB490E930 +:10C26000F751FFFDDD161BA6D75A444C2BF38A0766 +:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A +:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0 +:10C290005404F184CE93FF8971CD083D53AC7901EC +:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49 +:10C2B000B404FF7103C413D70AFE6331F837E9E50C +:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E +:10C2D000E2FD93C8FA15B1F854C513A530B340E98F +:10C2E0003789910611E686DA1241AFFA493F059B7C +:10C2F000583A421CEC8790074509E245D9B6D02050 +:10C300009467D78BFE36AC4F705F415B278B9D04E3 +:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5 +:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72 +:10C330005D3CD64562EF0BFFCB6D15160FEDF77622 +:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC +:10C350001393D3C15E6EE663DB996691AD0FC47F24 +:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A +:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4 +:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E +:10C390007E6C26B0CEEF7D7FD669589431F36E392E +:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1 +:10C3B0002DE3510885101F5A79E387AF9541FC4A58 +:10C3C00068FE4DE6650AAF52418A9A204F0D68E635 +:10C3D000876E591A1E076F07D31ED802F1C2509BF1 +:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2 +:10C3F000DB4676727489B9F4779754D1FEB6728AA7 +:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B +:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6 +:10C42000652A87ED3F0DC11900D2CE052A13207E63 +:10C43000378D20BDDF76AD290FF695DD44C8073A6C +:10C44000B498CCD8CFC84567A817E56FD32C9043D4 +:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8 +:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90 +:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA +:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7 +:10C4900022627AA2C58BE9F75B244C075A8A30EDF9 +:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729 +:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276 +:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5 +:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E +:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9 +:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5 +:10C50000D27E68DEA9F643C72F61F567637F745C4E +:10C51000CCC7E8B784C173A224163CD1F5A9956FA6 +:10C5200026548F88F0BFE0EF59240EF75138123EA1 +:10C5300006F2F882B51CF4E79E12926FA2FACD9231 +:10C540005AC041FEA966229A4BA8CACBA8D9554E1B +:10C55000A09D8CDF95557CE8980FF513F6ABE9A705 +:10C56000E4EA30EA9D243FC937BB69CAD381A753A7 +:10C5700054DF4722E70D503EB13CAE076D2756937E +:10C58000C8790332717DAA5FA2CA63D3DB474D210C +:10C590003EA63FF771701EB1835F4B7DFD7E924BCF +:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A +:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878 +:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0 +:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498 +:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055 +:10C5F000BE06393D7784E9F751BDFE5B261F357BCA +:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C +:10C6100008920ADA3EB17CEBCBF09D9418BF270854 +:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2 +:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A +:10C640001B3E4C12253BED27F3A54B02C0D1611ACE +:10C65000168008473CCD4B786A0775089A9CA486DB +:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD +:10C67000AB54578ED63FE8086E813CFD936D54AFA6 +:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E +:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA +:10C6A000349FC86DE93E930379ADFE966E85B6BFA3 +:10C6B000EA61E700882BE803B9379A17693E41978A +:10C6C000E7599ED858DA77F23F05D0431D6923A772 +:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1 +:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2 +:10C6F000D7724644431DFEB475A176EA142FC17863 +:10C70000B210E242F960BF15F798D07EDB4E49B017 +:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51 +:10C720007FA650BEB34E0775651919D6FB5BC46F63 +:10C73000027811E5F01FE57F2F01FDD4375B714CC6 +:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF +:10C75000877AC2772663C73768FE5A7F4A2FF81B4D +:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4 +:10C770005BCDBB8DF976D59EF4BA157732FDBEF947 +:10C78000C4815C3000AF1E9B857EE4660D1E720086 +:10C79000E1B93A3827E9363ADFC69FB2B866E340D6 +:10C7A000C912987FE31E13013F6EF300A5271D7F7A +:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5 +:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C +:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F +:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED +:10C7F000ACA599185F5282433967766F43FCFF6B93 +:10C800003919B1BA119DB8CF9907FF47E19B2CCADE +:10C8100015505F5C465D22A053217012EC10A5C23A +:10C820008671D20A711996E7AE21A66E0ACF112938 +:10C8300039B99536B517C826B053F2030E8C7F9AD6 +:10C8400013AA76803F7AEC1CCB47D6E912E2C55199 +:10C8500014EAB7D17E6E71F122F8226966D906EB2F +:10C86000467979E85829F00BB303942F1663BCE797 +:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0 +:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3 +:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5 +:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5 +:10C8B000525FECF666209EF36DB4FC737FFD42B7C9 +:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA +:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7 +:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5 +:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A +:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1 +:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0 +:10C92000F81AC93161F922F3B322C407AC53781362 +:10C930009EE5214D01D0CF7C364F58BCF7B03C4529 +:10C9400082B029DB1FE47A56A07F682FD2ED071250 +:10C95000F0638DFB877C54BED03A9C61A27AD87379 +:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C +:10C970004D6572E6D18072BB45021A1B66E75649C7 +:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F +:10C99000B23D2E938AB749BBC305D45E763D27824C +:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623 +:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440 +:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0 +:10C9D000E9EB4BC240378373EE043F5000FEA59F46 +:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14 +:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0 +:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1 +:10CA1000719FE10349EB40DE9E63763D900BC63982 +:10CA2000C24F7010E778DF16488279EF771BEDBFB1 +:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0 +:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D +:10CA5000D61ADC2683BCB21145117571725BB631F2 +:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1 +:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864 +:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1 +:10CA9000431F0F5F379390EE9CCAC3FC8800F37965 +:10CAA000F8BA80DF897738B115F66528C175C33AC1 +:10CAB0003EFF5DD44B0ED213860373568853E8CEE7 +:10CAC00085122F3F324AFFF911FEC07D752E067F79 +:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035 +:10CAE0003CDFAB242360871232BC08F8B7B1D28197 +:10CAF00071EA87498FCD06062EDF23EAE3C58D0351 +:10CB000097123794E23E960476F0C32F951BE254B9 +:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B +:10CB200014C118B2507FACD1D673C69A1FA96FB783 +:10CB300004952CA0FF975AE52CFAE95B00279CABE3 +:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76 +:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3 +:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF +:10CB700001BF1D8EC01566B41399A7F64E47B24685 +:10CB800037CDDDA0FF0E0A11B908933DE860F9E446 +:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99 +:10CBA0006ADE43307F50E8413F41F9BE5502380FFD +:10CBB0003A027EF007951D5324D02755E92E9C8715 +:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5 +:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62 +:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1 +:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C +:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B +:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E +:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40 +:10CC3000F471C7498E33CE0C9413F1C72953E5081C +:10CC400051E3493C9E33D3F824BEBC30C671A3E502 +:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32 +:10CC600050A87F91035B076F85F5F9A36AF716F566 +:10CC70001D3809E47745945B5353E13C957C1CD205 +:10CC80009BE59BFA3436DE5839C6E20FDB1E945022 +:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B +:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC +:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F +:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262 +:10CCD00095DBEC542E1BF95606BEE57D64D40F029D +:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF +:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2 +:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9 +:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F +:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8 +:10CD3000172ACF023BEB4122C139E768BC27A9740F +:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA +:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE +:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36 +:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F +:10CD8000B65DCFBCACCB5B4492A5CF97846D599771 +:10CD90007576CB8C33A2213F73C86BA83FEBBC6484 +:10CDA000289F335C6428BFED8ADF909F3732DB50C9 +:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525 +:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7 +:10CDD000867A4273CA77C07E59F0C1021BF8173BAE +:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88 +:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034 +:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E +:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91 +:10CE2000FF2B42206FCD96F15C9BBDD884E7067640 +:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190 +:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2 +:10CE5000CD15C27B3E8353767A21FFA505DFF6828E +:10CE60009FD135E5112FD04F67CE570DE7F21C0546 +:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98 +:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902 +:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A +:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C +:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F +:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81 +:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84 +:10CEE00079156BF3F2AAF7283EA6793DF5179E5700 +:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E +:10CF00007DF1F92F69B6F19C5282DFE807E417043E +:10CF1000C63D7F745EC54F3C7E5D635152018ED726 +:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D +:10CF3000C3792D0EDAEF48186F1DD606CD063827B7 +:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9 +:10CF500052EA39038AA7FD105FD6F036669DFF4C72 +:10CF6000788A476F378AA7EEA29BC3D344F49D9A71 +:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98 +:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7 +:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2 +:10CFA00007D2E915900E27734D6717839FBDD88C64 +:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990 +:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145 +:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2 +:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6 +:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04 +:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47 +:10D01000C309768637761EA0EF7166B7F701BE6941 +:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056 +:10D03000BEE665F1F001416AC47741562EDB0DE78B +:10D0400051CEAD727310D2D0E038A6AE67595D6C88 +:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C +:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5 +:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D +:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955 +:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0 +:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80 +:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741 +:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD +:10D0D00019CE39DC59499A707C5E427852DEA4FE42 +:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20 +:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464 +:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0 +:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A +:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9 +:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8 +:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D +:10D1500097ADB0482E289718DDA970F409C19C122C +:10D1600057044F71E58F8A9F81F3413CB7B1BE9957 +:10D17000C373C7C5DB19FDADDF3E686AA4E911952D +:10D180000F57C03E93AE3F77069B5F5FAF2317E01C +:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D +:10D1A00010B71BE6881AE7332D87FD8661755FACE3 +:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2 +:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7 +:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2 +:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B +:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B +:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4 +:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E +:10D22000B6DF3237433DA71BAAD884FA4AB14A7801 +:10D23000B65885C7A3AC467C7EB8948890BFD32AE5 +:10D240003D0DF0DD556B8E92C321EC67FD32A76179 +:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE +:10D260009E137F80340970FEAB8E28F3912F896462 +:10D2700001FA3EA7E24F83EF1C91136682BC683629 +:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B +:10D290001EE1526DCA72887F2B018B1F8E375D6A2B +:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19 +:10D2B000AF5501E37AF5093DB8FFA75490A66394F2 +:10D2C000CE267FF9F2DE59347F36642A61E7DCD856 +:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF +:10D2E000637DE56FD8BCD6D58516C296D83D877AC2 +:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5 +:10D30000C7B707A2E9E996271D867CD97922E07B79 +:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D +:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B +:10D3300090C5D6637D3D17539E1FC84A60E50DB169 +:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A +:10D3500013118EB73B56AF83FDFB2B51F655452677 +:10D360008343CA64E72BAFF6BED09106F4B09313A3 +:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6 +:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8 +:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837 +:10D3A00063077D04FF0BFBAB1404252919D65D79B7 +:10D3B00008CFC5F43A44760FCA3F536F577F43A551 +:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F +:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB +:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887 +:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7 +:10D400005FA904F3ECB93596BCD5E4F22F55B918F1 +:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184 +:10D4200059D7648447E38F2BA13607BCAB45479F90 +:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03 +:10D4400074F2AB66338F72EF2887F1E95F353F9155 +:10D45000182B6E153DFFAB264A0F401F4FF3287F58 +:10D460000AEB379C4C9322F4F87F543CFCA974A837 +:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11 +:10D4800071E28F07326C88BF0DBC28C0FED1810CC1 +:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6 +:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C +:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6 +:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B +:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90 +:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7 +:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC +:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF +:10D510002593E1E35E3E847299B433FB99D8283EAB +:10D52000A85CBA0493007CFC35C7CE77F30141FFB9 +:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87 +:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C +:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58 +:10D56000C23ACD8CCC2F459DDF05C7C836D0179465 +:10D570006F4C78BEE47533C275F5ABDF6C827AE22E +:10D580005417DEF7423B96E6FB9627845A75F13A2C +:10D59000CDAEC9F7337EA8E565835DD890E933D871 +:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB +:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9 +:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794 +:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B +:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB +:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9 +:10D600004A267C1FF2754667D17222BADD285FC4B4 +:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5 +:10D620003F18539F935357817FDCAAFAC7FBACF591 +:10D63000BD31E0F566317CE6178C9C027CBFDFC013 +:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3 +:10D65000685EF34FB6B3F1A2C779575DB751FF4487 +:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1 +:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF +:10D68000FCAF08C17D73281C579798FD0AF08B8961 +:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53 +:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1 +:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D +:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA +:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A +:10D6E0001F295FF851BE211FF7F53AEB63F9298333 +:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F +:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD +:10D710002140BCE8FED1781141E7429C9A7D04FC8F +:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9 +:10D730001FACA933FAF577D51AE5C73BA1FC513DDB +:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F +:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353 +:10D76000D0F581B496344D7B81C2F3CEA19509608A +:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A +:10D78000FC7EED67EF00727943689A164BFF44C741 +:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82 +:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD +:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90 +:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D +:10D7D000619CED84403CA54F50A6EACF5DA5643323 +:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0 +:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC +:10D8000015F4A527A22FEFB4FA1F043A202E09CB56 +:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA +:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E +:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13 +:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D +:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC +:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6 +:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5 +:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3 +:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7 +:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A +:10D8B000B55EF4386F46ADCF183F224EDC2E299B63 +:10D8C000E13718276E9794CDE2766709D38B4AC863 +:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512 +:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E +:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842 +:10D90000EF15822055E307456619E3D4E43176BE6E +:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4 +:10D920006CFFB76DA05F353FFE2D8BFF411667661C +:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE +:10D94000FF6AFC71A2F518953771D6632279132FFF +:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18 +:10D9600034AD11080F78A859CEA19F5923C84B3167 +:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293 +:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80 +:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694 +:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD +:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986 +:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E +:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F +:10D9E000A335E085FB78F76597EC83FB786969F2EE +:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33 +:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891 +:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763 +:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D +:10DA30009FABE51F4B84BCC74922FB4CB309B144E3 +:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A +:10DA50004D95708FB3ECCB1DFB8AA710326B59B973 +:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F +:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D +:10DA800028E79467F655BBE13EC2F06920CB879B3F +:10DA90007B6C69867B098A0CA68970A23C9C85E018 +:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC +:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB +:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1 +:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF +:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3 +:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7 +:10DB0000268433D5CCE17B26690E123C4ED3D41447 +:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3 +:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9 +:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4 +:10DB40005D6D277F13DE7B19189A9A0F767565B67F +:10DB50006488CB940DD558E05CEAE51C554E48AC82 +:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE +:10DB70009D7F65E7B22F41BD86210B817388DB8EC7 +:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674 +:10DB900073E60D70DE7D06F4F75301CE37423FE0A9 +:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A +:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B +:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2 +:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA +:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3 +:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC +:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC +:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA +:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4 +:10DC3000C03CFCE169FA73201AFCB753D981E7496B +:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15 +:10DC5000998BE5654327059867431C3EFD650E3BA0 +:10DC600027927E3E9C08E703966633FD35D03FC37E +:10DC70007E1BF0C53213E124366FB033CB34F94A42 +:10DC8000DEFB590595AFE9A3792A5F2558875179BD +:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680 +:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872 +:10DCB000FBD6C3390906B9F5547325799BCE6F6538 +:10DCC00036D3E7B387157C2749E3EB68B95498C38B +:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E +:10DCE00062E5C4136880F234937A2F4164EBBEF18D +:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9 +:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7 +:10DD10004D47807BAF35CBEC98873FB03BFEBD874E +:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23 +:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC +:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0 +:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0 +:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A +:10DD700004EE7BF407F03C183C605488F775D9FB3F +:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C +:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE +:10DDA0007A4A0F33815F57E710633B73201BEE9570 +:10DDB0009374AB1FE4CD29217018D757246E58DF18 +:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24 +:10DDD000BA9152B4533F308741EFFC3C3703E339EB +:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30 +:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8 +:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090 +:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B +:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C +:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7 +:10DE400071D3D623CDC47E1F264DFDFD15E01348AA +:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33 +:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75 +:10DE7000958F1B6D3DD570955E77CF13EF2DF38495 +:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5 +:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597 +:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B +:10DEB000700745B88794E28CEDEF7E578527C5CC77 +:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA +:10DED000721DDE58937CF02EDB08DECFD5D631FAEA +:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60 +:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC +:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39 +:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2 +:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2 +:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84 +:10DF40005F47F513BE5748F55235C86FCD2F02BE57 +:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5 +:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855 +:10DF70009DB17A8B53EDE868F918AD178C7635A50D +:10DF80005B456F078CE11715AF374F1F93E2D0C782 +:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF +:10DFA00064569551DF3B7299DFE1C8751ACEE1D610 +:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D +:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3 +:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA +:10DFE000A11869E549AF07DAC97DC31E98974D04AA +:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7 +:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17 +:10E010005E0D9EB05040E1C86C60F064F70F72BCBA +:10E020004EEE65D7B37AC5B91683FEF1439EC2772B +:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E +:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53 +:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D +:10E060007379C1329877C3857018D036EBC2100F20 +:10E0700076DFFE3C79167CD7E62799C54CD81F770A +:10E080005E60F0F544D13F21BBD575E965F0B9027A +:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A +:10E0A000DE482341782F88D8683DB0831CB49EFE9B +:10E0B000DE260994C23E412875DA74D0730B1DFE2A +:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E +:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31 +:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1 +:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5 +:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D +:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777 +:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971 +:10E1300035CDCF782C97E9A3D37981AD30FEE613A6 +:10E1400007F09CE083472F09E3BDEB73A378E3EA74 +:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7 +:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B +:10E170004FC33BAD590DF24CFDEF126435B077E360 +:10E18000D212467F1F5400BD9DD9BFA201E95A2477 +:10E1900022413A0AA2DD956D63F6A886DFD34238A4 +:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B +:10E1B000F91C7E787FE1EF8FBF213D067886B81885 +:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A +:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4 +:10E1E000CC8AA28B59DB199FFC283751E55782EF67 +:10E1F000291DCF4D50EDA8601DDAAF741E9D731020 +:10E200002E9C87982B7F15E9564CC671331BC29CF8 +:10E21000FEFE899646E84A7E3637F566E0ECC77D15 +:10E22000C64DAA9C295F7B947B5B47072FE69A919A +:10E230006E329F3DC2817F48CB5B177AB03EC607E6 +:10E24000339F657ED3265A7EBF41AE6CC0F97439C8 +:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE +:10E26000C17766EFB8103E8DE25985F794C0D6931A +:10E27000A77868A5F99FE54A38FE6921781FACFBAD +:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A +:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6 +:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F +:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E +:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8 +:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29 +:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911 +:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C +:10E30000E8CB68FA745633B90831D742F60E1CEEE2 +:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38 +:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12 +:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD +:10E340005222FC7660A4FF68FCE5E631F91A438F9F +:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB +:10E36000E27D54BFE7B1FB578979BC0A8FEC853851 +:10E37000B644F9B9BB14DEF50B144B809F54A71FAC +:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90 +:10E39000CE77203C942F92F274EBD750CC7E67EA74 +:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A +:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709 +:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B +:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95 +:10E3E000D8BB43D4AF6F857889E6D727D605940488 +:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4 +:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB +:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D +:10E420008FF4BFE97213F28FAB9AC911D705A3FC21 +:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA +:10E44000892007E2C1FD19AEE967705E851C67E7A8 +:10E4500028167CF0F344FD3BA435798CBEAFF599CA +:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7 +:10E4700027BA7EFFD29784E782AE3DBBF2F3905776 +:10E480008E26E139929C702DD2C535CF1C3FD081AC +:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E +:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD +:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6 +:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E +:10E4D000DD6D0A1D61DFFB9244A877F59903F30116 +:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D +:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237 +:10E500001A824F3E0E79529BC8EE5D055F11F4BF33 +:10E51000DF75F0F820F2A146174BFB39F5DD30012D +:10E52000CF7968F4FB56457119F01DA550BF793EAF +:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA +:10E54000E142C0075D82D287F25CECCF0579EE2C08 +:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E +:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA +:10E57000BA1E5C07FD1D3613D19C118177B320A113 +:10E580007FB4B986F3530E231CD9762A15F6C79AA1 +:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7 +:10E5A0006C5BEC38E893792E953E19BF660EACC8CB +:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8 +:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D +:10E5D00040BF282EECBF11E293949FBEAACAC73455 +:10E5E0003180EF8CD8E4402AFC269B640DE0396E24 +:10E5F000697DC0D20A72861FC95D858AF09861FF65 +:10E60000F0A025983113FAEB52F5D351063F6D8FE8 +:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7 +:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49 +:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B +:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85 +:10E65000D448AAC581A2F1CC4BB49CF65321C998E9 +:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2 +:10E670003B9B833CD3BBC1CBA877FFA545266F53FB +:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E +:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2 +:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4 +:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA +:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9 +:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D +:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893 +:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C +:10E700005DC5DEC55D52545206F47672F50F778210 +:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0 +:10E72000EF511EB4F454C03DC9830B2511F8637337 +:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F +:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD +:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD +:10E76000F839B4F397866EC3735B1A3E96560DE77D +:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35 +:10E780007E8FD2DFFF05D640AE560080000000002D +:10E790001F8B080000000000000BDD7D0B7854D5B6 +:10E7A000B5F03A73CE3C1226939327E1E9C90308EA +:10E7B00098841308EF872704102BB583F2B2220E3A +:10E7C000C823424846C48AD77E37830331526F6FCD +:10E7D000AC2FEAA576A06AD12B106DAC51030DA821 +:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3 +:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998 +:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85 +:10E8100032802BD561BAAC03A42B6DBE3B3201D242 +:10E8200000F435986FB07B9D3A9647FE430A6DCE53 +:10E83000C5EFD3C0081501E4DF23192137408A262C +:10E840000164516A335307C008C0BF0691AA811200 +:10E850006F31C027B5067C3800F84FCB0658CEFF85 +:10E860000058B1A8D5A1617F554F89FE329D46E978 +:10E870002D989EA3BFCB305F013778B13C4B966E8D +:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B +:10E890005370FEDFA9043D0987E85D88DF310F7EF4 +:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67 +:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B +:10E8C00004D5F39649582FAB678A1EA4A1E4725B66 +:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0 +:10E8E000EA072064C2C15B66C37A47B353F4F5F408 +:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE +:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F +:10E91000A737044A204FC0C1EBEE8443684DF2DCB8 +:10E9200050143CC6131CB07D6830CC6D2C22F87B93 +:10E93000ABA89F6C9B9EB11E3715DC81926B526811 +:10E940009C20C36B00CD03D329B83E3FF59BEF5D00 +:10E95000C5F0C84AD113C163CF25021EBBE76C9333 +:10E960003760BDEA2229E4C4F9DDFFE28C525A6720 +:10E97000F54CB70E98AFF6290B695C08B8E031CCBE +:10E98000836FD1BD53305F5DE9D5D76BBCEE455485 +:10E99000DE3733495F8FE50F3E2F1994AF0EB84332 +:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D +:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35 +:10E9C000D1FF656C1F9041972762DE111EA8E3FA04 +:10E9D000AB27860712BC4E3E9F3497DABF62B30561 +:10E9E000689C57365FBA292875EDE7A4DDDB44EB58 +:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329 +:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2 +:10EA10008F23504878B5272F99F183E6E945381FB1 +:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF +:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167 +:10EA40003DEF8B4B01C65F57A847281885572E17F7 +:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28 +:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198 +:10EA70002F59E3EF49F680D107E7E3682E6FED8366 +:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB +:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8 +:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC +:10EAB000EDCB253E919D0CBEC604E359ED717E5C05 +:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32 +:10EAD0002A1E4674372559DFED227A1A963B2C08F8 +:10EAE0009DE320247267A474C5035A07D10FAD8B30 +:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E +:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C +:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D +:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD +:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600 +:10EB400089C60BE078B4CF2913E15319E1E319DD4D +:10EB50005078672EE179E35C5AD750256C2B25BE9F +:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40 +:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E +:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482 +:10EB90001FD03029263F68C37762EA0F0E5D1D93B0 +:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7 +:10EBB0003F253CA7F527E073561AD17279FF8636B8 +:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28 +:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39 +:10EBE000E23CCAFF2C87D627988785CF567E922293 +:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB +:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525 +:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB +:10EC200000EFE3D79F3A3A761FACF5E7F90637874E +:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F +:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB +:10EC5000C7F54EF02782C374130E95B982DE2F4498 +:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2 +:10EC70001C1A805D2DAC9776F544BC48F7B9592F26 +:10EC80005BA8B44269949CBFDFA4EF074DFADE5045 +:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E +:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5 +:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70 +:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598 +:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8 +:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6 +:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681 +:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B +:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C +:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995 +:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A +:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D +:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0 +:10ED600077F6983FC197605C294F8BA1CFD9336369 +:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50 +:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F +:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE +:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD +:10EDB000E192020ED2E5A0403D4C7482C610D145CE +:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA +:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6 +:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE +:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46 +:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F +:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA +:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65 +:10EE300076CD9917907F263F57FCF561C48BDBE4B4 +:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A +:10EE500073F5E9DE878673B7850AD71BC2F69D5323 +:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9 +:10EE70008D1CD389E99749FD4380B640699EE03FE8 +:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87 +:10EE900073286ADF86EF5563F223DA7262EA8F3AEB +:10EEA000A0C5948F0917C6948F3BAAC7E427444690 +:10EEB000C7D4BFEC8C11932F872B62EA57B866C476 +:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9 +:10EED000FD157887E7E1BA173ADCF5522ADA69B905 +:10EEE0004619E59393ABFD0BC84E5AE3516122D509 +:10EEF0000E85086E750E97BA1EF9D40792D11F10B1 +:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B +:10EF10009A676CF1119D6E2F4CD6681F920702B450 +:10EF2000919C52F424407EE2E811F95D01EDCB6F33 +:10EF30006CF01826DB5554F4A97E736688ECDFACC0 +:10EF400064DF15348FF5B606CF1ADA671B781FCB4E +:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2 +:10EF60003316F39F61F7329637B59DF8C995981F10 +:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712 +:10EF800078F6F10F843D15FFFD677982DF6755083C +:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47 +:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753 +:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA +:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3 +:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41 +:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1 +:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D +:10F000007F2F086444B7137CA7739CBE5C6E3F934C +:10F01000068184EBC8E4EF9063E410DEEC423A270B +:10F020007E519E96ED0024F1F91079C540F8CF206D +:10F030009300F1145C7A29F12950EC91B04517281E +:10F040003F1680F201D90B3644C67338B51B56DB28 +:10F050003F0847D1D10C23360F543F4ADE7C427D16 +:10F06000E37A928714A612BE9F022D554D805F56FB +:10F070003ACF257B95A8F51CEC464F6A33E178B072 +:10F080005762383E6FF2B191F320A1BED696E711D8 +:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE +:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960 +:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3 +:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4 +:10F0D0008AD163989BF8185426827F9F7C534F8D6A +:10F0E0005B771318390BC8AFA1D875E267C932F83E +:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B +:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922 +:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC +:10F12000DB890F77819F3BD34E7EDB78387A419B1A +:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD +:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5 +:10F15000E96F185877E155434AD6527AE9F83A9957 +:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D +:10F17000AF90E8E390A42D61384808079237BD8F1F +:10F180000F5C1005C715FDCA7F9F9F45E7036064AC +:10F1900090BF788793FD56B001580FADD9397813D9 +:10F1A000C9852FF27DAF51BD51934DFFAD11197837 +:10F1B00075CAC5C30BFFEC44271782976CD2FB417D +:10F1C0004F62BC19972FF6EBABD24B66BE8043045F +:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F +:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837 +:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A +:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111 +:10F21000E4C4F35CFC2D99E71B344FE2F32589E746 +:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B +:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A +:10F2400062BDD9C807A9DE373D5F082C984272E835 +:10F250001A9FF0FF1723C7253E845379F4DC70D240 +:10F260006FF5751B88EFACF4E80195F9C81BF982BE +:10F270000F8281F399394D627F52FB884F97288422 +:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21 +:10F29000473A799CE004D32303899F1C1C98984F1C +:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F +:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888 +:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A +:10F2D00027ED07E6BD12F981735E3F207918DE271E +:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C +:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F +:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED +:10F31000D36FD0132ECA6F509C29E865453F2FCB81 +:10F3200007921B643FD7BD30A6943617F50F20FB1C +:10F33000209292CCF222D87B6CA11605CF0FF32D30 +:10F34000FD53EE46AF74C47C7FB7D685266567FE55 +:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A +:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D +:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3 +:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427 +:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9 +:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403 +:10F3B000F757DD9764D3BF88FAC4399AB701557EF1 +:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84 +:10F3D0005D517478832D9225E476781D3999FE6706 +:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F +:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359 +:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D +:10F41000A2821EC4F5955F8ED884FD4D92FBB68402 +:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D +:10F4300074F2634E52ECC7A3F953BC1F684041AC51 +:10F440003FF914CC4B6D25B88C4F67B86C6F99940D +:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1 +:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C +:10F47000C0B4BC9BF58F32EB85938D5105599DFD32 +:10F4800051FD44F1106D832C3FAE80EB358105AC0E +:10F490006FD95CC857897FA2FE2AABE4272CB03312 +:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4 +:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931 +:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F +:10F4D000D237902E26DB2219822E4222AE017C0AE0 +:10F4E000E57F2B85831427B0D6F5EF3F273FB81172 +:10F4F00054206922E615603F63E0600A9FCBF1CC9F +:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4 +:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C +:10F5200095E9C69FACDB7B937FE93DCE4B2B937572 +:10F530002987FC4F9E42D2535743B2EEC4710C77D9 +:10F540007180C67568C0FEF86468E475B8DD9F0414 +:10F5500008282AA812DB4FC9BE65056CAF009F932F +:10F560001F7E2F6533AD3F493DD57A077ECA0083A4 +:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405 +:10F580004904FF9E73E3BFC7CA4B171C54899F48A9 +:10F59000ADDE9C73C89FDA086E659D706B53845D09 +:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51 +:10F5B000DF86001A45FA789BBA642BD547C3096CDD +:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831 +:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025 +:10F5E00020F4A3EAF4C3D524E70007B5F50738995A +:10F5F000727424F10D9497F5242F93EC06C3DB92DB +:10F600009B2B9AD600D15575F30220BEF28EE41BD7 +:10F61000F032DB23C076D99C6981576C1AF9B26647 +:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB +:10F63000761753BBD2CBBC53B270DC6031E8776233 +:10F64000BD60926FEBB3B4AE3765FD318DE2212A18 +:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF +:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9 +:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1 +:10F68000F247A93C5FE42FC37C8DD852C86F29FF95 +:10F69000DE0882479B0C141655D322D968FCFC99CE +:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9 +:10F6B000049DC849B3F97E762B95BF01BC0E30F985 +:10F6C000F7A838FA1DD749375C5EDA91F757D07C36 +:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2 +:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31 +:10F6F00060F205EFC607F89CC0A6937FB24E6A6021 +:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2 +:10F7100006CB1474A7EF157457065E99E03552BDF9 +:10F720003B48E3CF9997CB7C66CC5160B830E5611C +:10F730007E429AC4FB943F209FF165BC4BAF97116A +:10F740008F64B9343F09C79B3B4FE2F38959735D1E +:10F750002109FF390BE983E3A1145FEE6CC4F7398B +:10F760003E499CFB627E5E943F1EB5613E379BED39 +:10F7700004FFD309F0397F80C077AB7DCD5A478C29 +:10F780007FE792016EE1E71830F59302E6BF22AE03 +:10F79000252BD91B117CA381F9D4611BEADFA4FFBF +:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4 +:10F7B000BCB17AF43BB4274407D74AACE7CE997B77 +:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2 +:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72 +:10F7E0006D67D3B87ECFC7579CBB0451A152F09729 +:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5 +:10F80000695E63CF267CFE21E8025FDFAFEB83F306 +:10F81000EC53658C90B528BF4D554822BACE269E34 +:10F82000C3F08F38C82F37DBA157D1BA66A7831A28 +:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17 +:10F840002D6F8608AF9095EB849388391CD7D657D7 +:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1 +:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F +:10F87000346480E0570F4AC0F22270AD8BE19C9552 +:10F880002FE295B2527547308DF88D66D5E338BBBF +:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15 +:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A +:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7 +:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1 +:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC +:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A +:10F8F0009E657A2185FC5CC31064A4AFB7E5786788 +:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F +:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7 +:10F92000CE3CC53D56428383F0BD324E3E2E73BF62 +:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891 +:10F940007AAA8B3F88F954273F8BB32F417D89D604 +:10F950003302F931F121A3204566FF32CC13721432 +:10F960001E97C82F267B56D793DC6B97521AE4B2AA +:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978 +:10F980003115BACA01F0B3FE3211E526E9D152CBE6 +:10F990001C99C6DDB814FBA6F37C255C41F9DB9607 +:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3 +:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B +:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A +:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84 +:10F9E00080E54E128472087E4681E0B36507049F6D +:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913 +:10FA0000D80870FCCC0EF0559BFACE5D034650B47E +:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31 +:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546 +:10FA3000DAF9F99661F12588E54BB97096F70FEE82 +:10FA4000DE732BF90982717A50F022F5A05EB9BEFF +:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845 +:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756 +:10FA70004027DE75E07360D375B40E94E72AD97D14 +:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272 +:10FA90007CAB0DFC14AF003EF534E1A92577911342 +:10FAA000319ED42D1678374A11F9BEA8C8125E06C9 +:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378 +:10FAC000E13683F16404E81954CFC2939161518EF9 +:10FAD000F8F11AF19371D3105FF228CE76541FD249 +:10FAE000BBCA4163FC288F936B15EE990AD17985C7 +:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A +:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7 +:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F +:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367 +:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3 +:10FB4000BF2F08523E7B452EEB854FA7E92F71B999 +:10FB50005F9497B519720AE6F3576139E69FCEF5BF +:10FB60005650BE66359663FD11FB7C41CA17FC50AA +:10FB70009497DEE97F2985E47C40B47FE1589DECD1 +:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9 +:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441 +:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6 +:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2 +:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB +:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2 +:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA +:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C +:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3 +:10FC1000426B633F449778633FCBEF50BFE2618410 +:10FC2000B797539C31965F3E56C419979E3B3D351E +:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80 +:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687 +:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70 +:10FC60000196DAFC0AE111F497749AFF556DFEC90A +:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30 +:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE +:10FC9000743B8E3369FC00A6FB9973258BEEBF3352 +:10FCA00090F4603AC1607FB68FE3DD6F8290830687 +:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94 +:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E +:10FCD0006745636CBDCA0DBF3F209574E50395165B +:10FCE0001F08C5F2015438041F7868089F7FADCC07 +:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A +:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6 +:10FD100069EE42E2C336335E55E4ADF1212ECEE505 +:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A +:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A +:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F +:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9 +:10FD600010CE52B28B95E256EA7388A02717D111B4 +:10FD7000F1F769B1F65612083D7E789BF0E38CE806 +:10FD800094FB75B4BF4ED05D42EE3700D157B7F645 +:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0 +:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9 +:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B +:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2 +:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5 +:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D +:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C +:10FE0000774E098181D171054F0F12FC6E4281F14D +:10FE10009B81744E94D49FF99D568AF6541FCE73DD +:10FE20007F076FBE9CE3243E03E38271126BA3FC49 +:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697 +:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88 +:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5 +:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419 +:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89 +:10FE800014BDAF670796A70CA2F8A27CC3D18BE084 +:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8 +:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E +:10FEB0006E1776607B9248AD799D1D382365109D45 +:10FEC000CBDE1C66BED8919F1166BE7776A097C721 +:10FED0006D9F65959BF9FF10790D549DE65BEE32A1 +:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D +:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24 +:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015 +:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D +:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D +:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294 +:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA +:10FF50006BC4AF29F274E66BA79A24F68768D05673 +:10FF600047705E29897D59F9EA8D150ECA2F0695CD +:10FF7000F97C533C3FF305494F585E0F2CEF4A2163 +:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D +:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB +:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51 +:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E +:10FFC00036D1F58F80FFC1F112C175E206826BD385 +:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84 +:10FFE00089EE67B967AA6305C2614F8E0CD268BA01 +:10FFF00077B32CA6DFE57215FB0950ED6039E2C737 +:020000021000EC +:10000000FF313CE522B6933F6F962003F175E986F8 +:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C +:10002000F7DCAEE7404B0699F1C0BDA137E1F31410 +:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560 +:100040003FB214063D349EF7D10E218D8E4744F900 +:10005000A98D722890DB793E746AEFAF0EFBB0DE9B +:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3 +:10007000C6EE778A1EBBDFA9A363F73B1ECE694697 +:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829 +:100090007CB0E03B1AFF27F05563F82E41F83E2C68 +:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2 +:1000B0008B85F37D7170FE1CC657B819B830D335E7 +:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E +:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D +:1000E000CC26A267233385F980BEA107EFD73097CE +:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C +:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F +:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F +:10012000C88F91096D0ED263BAE38333728C5F93EB +:10013000DC402E06040F610AF05F427DB2A6A35890 +:10014000F8E79D7EE1E787401ACF6314887970A3B2 +:10015000287FFF2825C47E073429D8BF64D963F1DE +:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A +:10017000D37F8F56A041FAF5C8CF84FE34DAD51864 +:1001800054B4AEF6F927F9E639B762C67F5EE01CD3 +:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787 +:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469 +:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F +:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9 +:1001D0002E1FEBB5369761E7F328D37F09109E4AAF +:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5 +:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9 +:10020000ED9E047814170F102BEF17145AF7CA45F8 +:10021000BC8A06E2FE77A5E947AA746DF4887338B4 +:1002200094737DA18BDDA410E0C7F07985BD90EDBE +:1002300062B407F8BC5F73248AD7033593CFD56FB8 +:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12 +:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7 +:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F +:10027000B9B730B8509C7B97997A53A5CB8453611A +:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92 +:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA +:1002A0008C687BBC15E125A74C76117F5CD1CF37DC +:1002B0008CEAF73B103E4C74036E8DF5F593CDC779 +:1002C000F6CB799DEB423C7B701CADA35956C5BD66 +:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE +:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF +:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A +:100300003DAF714F6FD28B6F157A31EE2BFB41648D +:100310003B48A4974E91CFDE42F95339A092FD9904 +:10032000D923207B48CF5B00EC2702DDAF13AAC89E +:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198 +:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB +:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4 +:10036000C53973EE0FFEB69CE900B474E7181ACFD6 +:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726 +:1003800059F730D2CF7AD1392F8274A8491F9755A7 +:100390004486FBDD9D70CACC4F6CBF649BF03898DF +:1003A0007C72369D8758F7301EEAF1069F879F348E +:1003B000CF4FF28C69A984E707075AE75AAD59E491 +:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB +:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B +:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE +:1003F0009456079D6755FD9371514D6871273A0FCB +:10040000B3D65F9DA68032145309BCE7ABF7E23F39 +:10041000E48470DC629677777FE3E7E6FAACFB1959 +:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB +:100430002EE61E04D96BB4BEEA3313F97BC55D27E3 +:100440001C84DFD40F3D8560DDCFE80ECED985C298 +:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4 +:100460009A707B72AF6DDAE604F37CBD50D8DD4341 +:10047000B214F6175CDA0AC6A604E35AF5ACF70D17 +:10048000BA9B57D3A4F07C9A37C505271A6FA709E2 +:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C +:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39 +:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3 +:1004C000B4DEFA4A269B5D407EB49EF35A6D242723 +:1004D0003BF84F37FBDD096739E61E4C57383BB810 +:1004E000BCE3FE19181E299BE410B03EF0D01F4B50 +:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC +:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE +:10051000EF20BB6C49394464E45BC7DEEA5F477196 +:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7 +:1005300029D8EEC603DED456CC2FBA27568E1D7BA3 +:10054000EBC70EB207A4856E3FC515E13CA7BE8080 +:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322 +:10056000DEC6EBC39F179AFAF048184972E685DA9F +:1005700066F17E8E791F11F53F23119E587A7028FF +:1005800079D2DF99EF43A34C7C699C92B8FE92220A +:10059000B10F2B1F3BEDF068DDD3D971E42705388F +:1005A000FE895A95D3ACC1866B30F63F60B02F659B +:1005B00030B697B548FF4FD8CF29CE4111DF385F0D +:1005C00043F7D448DECE157A8253BEB992F5D13EB8 +:1005D000A006597FF1FBD99F6E43FD248DE2376E53 +:1005E000913DEC6F10EF078DF968511AAD37F3BFED +:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780 +:10060000CF70F379FF265B80FBA140ADBB109EA1AC +:1006100027C7EC26F77941E3BD93C8EE535B76B567 +:1006200092BD526FFB740FC525D44F043DC8D00E48 +:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E +:10064000D72855A3FAD720F21EE99927AB6CEC37CF +:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1 +:100660009B59713F7CF697C06F7802E51B44DDE72C +:100670005ED1B4C946FAF8A5B451517155D6BCAA99 +:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3 +:1006900003B98A26113CAF9354A18F9A7AF2B560C0 +:1006A000FD35BC42FAE942D293110F3F94421CAF90 +:1006B00069839667A9FDDC1CA10F82D63882FCD71E +:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D +:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530 +:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B +:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA +:100700007EAF7D5E8E0F6997D4F498775ED4865F56 +:1007100093DE5D6353857D73C028A5F398F6194574 +:10072000FCEECB497BB83FF311E47B149775EB13D8 +:100730004D3315845B756FD4BB30BFF9895D3315BC +:100740007A87272FBCC486F95707FF45940F091FE6 +:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F +:100760009127030C11EC6F4FFCEFCC00AEEBB8E916 +:10077000FF043D3C9FE659FDC2205BB47FF1C86099 +:10078000C1378F27897AC773E186AB49FF280CF3FD +:100790007D18ABDE6B83CDFB0426FEDFF462522BAB +:1007A000C5095BED202771FF41B3DD4DE67B59485C +:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3 +:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0 +:1007D00023394F72C01E7BFFADC1DC2F2812FD579D +:1007E000F756D3683FB2D3859D811B927617BF63BE +:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15 +:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB +:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B +:10082000396973F47B29274DF81E199C26E0D7B14E +:100830000F3D251E2768C2A52FC2BBB8137FACF69B +:10084000175AF7F67FD1BABBEC5399989FB51E8023 +:100850007B051C707E69A8E71F5F63B61B6DCD43E7 +:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3 +:10087000707059E316F1F9E40A530F96036F38C804 +:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184 +:100890002A9ACE32F3C53A33652333C8F488EB6322 +:1008A0007A34CC788358FCE980773C1D77E94F4B4C +:1008B0008FED4FE3FEBADB87B08917DFD83E041314 +:1008C000C3B383BFC4C1AF831E73CD76458867654C +:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646 +:1008E000335E558BC5E3154DB9B685459DF5EF6E65 +:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B +:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A +:10091000531AB2492FAE7A6C9DC7A0731625E021F9 +:10092000BE792C244F4B747F75D41029461FABA67B +:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201 +:10094000785737FDB58EECB73D862B4272FBA81267 +:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97 +:10096000FBE503D91A077707FAD8589F6AED43EDDC +:10097000AA1FB5EB64BF57EF93751C066A20524758 +:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740 +:1009900072E4248CF7354D3FFA54F6507AEC1D285A +:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F +:1009B0002CF840288BF59BE0130F95BC8FF33AF190 +:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26 +:1009D0005AF772F524E907CEAE7A80D62C0925BBEA +:1009E00045A455F6560FF905AA36D9F5007EAEDABC +:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382 +:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF +:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF +:100A2000402409EB2F7FFA7DF66F55F9DC7E578263 +:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE +:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F +:100A50000EA29B13B8211969025E649FD634CA0B9B +:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C +:100A7000D7101074F1DCD66D640F54BEE3D4A7D345 +:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84 +:100A90001CB7D21EC8563915DF2B1FB995F170E966 +:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F +:100AB0008DB3789D4BC0C77858F933E1CFF85C818E +:100AC0006989EE1B6F1F22E487136E2E21FAF81C32 +:100AD0007B223FCC11078878DEB7C43B644EB83A1E +:100AE00035FA9DB93B8708391080D07BF4FE640D40 +:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592 +:100B0000D71F30E1259D13F11C9A62C59DE6E17E59 +:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C +:100B2000FF1BD58EE17664B33359423BFF4876E232 +:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B +:100B400002B4BB527344FE61A243B48B52116E9F38 +:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B +:100B6000A0676954DFEABFA6D919F32E49CDA31FA8 +:100B7000C5D1B333EEBD133FC3B3065235D2378F61 +:100B80003822535FA471705C8AD75C72BF33E6BDB4 +:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B +:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4 +:100BB000ECA1C7093E5548AF01A657417FA8A347FE +:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF +:100BD0001E2D96CF563E83F44BFE348477924E7C86 +:100BE000F64B07E9BD39156807E3BC3F76EB74297E +:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5 +:100C000076C35FF7C5C1F373284AA53B0CC79F5C49 +:100C10007E09FB15E2E06BD9BBF17CB37A88C67024 +:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206 +:100C3000973807AB7EF4AF2CBF10AC1127E26D756F +:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B +:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548 +:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8 +:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D +:100C8000C1B4074AD400B54F32E30FBC114F5A9498 +:100C90009EF47E8BEC21BD2E1C826989DF050CF24F +:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C +:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590 +:100CC000733C7CFFAF25FF3F092F16BF8A70247A43 +:100CD0000A188E5E08E71B0508D0FC08F079B09C66 +:100CE00052B6E745ACB704014CE724F1FE9465E049 +:100CF0004D6DCDEDEA374139E820F9BF14E511FB20 +:100D0000BD37C6962F6BF998F16C591C9EF908CF28 +:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C +:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8 +:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43 +:100D4000F84E7A968587F1F67D7C7AE2D97747D29C +:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848 +:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6 +:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861 +:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1 +:100D900070C7972561965B6B791FA75FEAE0FD3E00 +:100DA000D5F2379623A75A9C1AADA366670FF68F24 +:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E +:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F +:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01 +:100DE000FE5E427CA9FD995D0EE25B68973E02883B +:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD +:100E00003BB3E87DACAE701170684738D0BA102E95 +:100E100095A49775078FEA6F2D3C3E657BA2AA6566 +:100E200014D351275C24437C4F09B9245AFFF31E85 +:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542 +:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F +:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F +:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01 +:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53 +:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E +:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72 +:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C +:100EB00010C21E914D7D631D0C3336915D857A06FF +:100EC000D901EB3245BE1EF50799EF0F72B00AD477 +:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8 +:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA +:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C +:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F +:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4 +:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A +:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6 +:100F40008641EB766A0AEB610AA0FD28D621EC4EB9 +:100F500084A316054730ED50C504B9A20D6338A22D +:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA +:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B +:100F8000F3D822111F100F672BCDF795AF21FD77F6 +:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8 +:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14 +:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9 +:100FC00012ED0CF657AA40F69F3C091AD91FE855B6 +:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE +:100FE0004B6CFC4F601214525CC314B9AA81E675B5 +:100FF0000A521A28EED2616FEDCFFEE17E008F918A +:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE +:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC +:10102000054A149CCB212D267FA2DFE126B213F2C4 +:10103000024E9582C72A5CBD62DA9FE87586C70BAF +:101040003A5D2AD94753D4DC98F6B267EF7B64D770 +:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657 +:101060000526CED23ABEF7AEB8A78AF6D623AF632E +:10107000BB37EF0720BFF1155A694CBB66D3BF12CF +:101080009962E7F766AE2C1C13336E737837C3A5ED +:101090002A0B243A0FAEB2214960BDEFEAE531F5E3 +:1010A000BE37FA8A987E67183362F255ABBF0025C7 +:1010B0000360DCEAB340EF0796B636C6B41FBEB78E +:1010C00039A6BEE7753485302DDDA705291D75507D +:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324 +:1010E00005D0323A16F0565018F2C8A3FE9728BD24 +:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965 +:1011000014FFD3F0E35D12C743EE263C1D1D69A812 +:1011100048C5EA63CF34BE446953DBF87A7AC7B373 +:101120000AA08DE5AFDBC6E70253E4961289ED9F76 +:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0 +:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0 +:101150005425128DE73F2AF51EA6384D2B4E2AB98D +:101160004216BF4771B98893A9B3E94926F362FDD6 +:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA +:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706 +:10119000F7459179BEA2A859D7931FBC3845B4270B +:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94 +:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436 +:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7 +:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32 +:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4 +:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B +:10120000478DB77282D0FF560E4EDE4A78EB3960BA +:1012100088B8A842B73680E9239CC37C4209E75CC2 +:101220009F22E2ABB4F3BCF37F7CCB88349263198A +:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD +:10124000D0C13AACDF3F19E7B58562D744792BF2BC +:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5 +:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD +:10127000AFDFBFB688E037CA467125EB7F67E777F7 +:1012800006709DAC4FAC447A06E97CF0EC710178B5 +:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112 +:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933 +:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E +:1012C000E3E68F37AC26BABEEA7821C52858EF5737 +:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345 +:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A +:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D +:10130000105D9E0637C7F59D561F9F4DF33DBDC529 +:10131000CE41B44D26BF0C149AEF11648673E85E7B +:101320007EF19B368E473A88F860203EE4B7BE993E +:101330005E4CED3295748A6F383DFECFFC6EC2E98B +:101340001F0207172F0B3B185E4D998B2ACA19FFF6 +:10135000B574F23F58F06D34FB79B8D4B8B298FD4B +:101360005CE67D1163EC45BD3FB96BC2977C2EB046 +:101370003617F5FC340A393E5347EF4BAECCB5B3C4 +:101380005C5A99F6C5D44CC2F7725784DE81A859CD +:10139000FD19C317BBC98DBE07A69C91418B8ADF7F +:1013A000D2868AFD571483F75F39E3E0F2AAD5A706 +:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700 +:1013C000CCF746911FD64BC328DDED5819C54FA069 +:1013D000F1D30E3E3F14F7EABEE96F25939F728664 +:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1 +:1013F000DEA06EDBFBB329BE60463F7516C517DC69 +:10140000573C790E97F7521FB0A1FC7AB964BEC859 +:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7 +:1014200075CE9C00F36337D3C1A9FA1E21E779E892 +:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120 +:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0 +:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72 +:1014600092F85DA2436DFD097E4736DEF203F2A7D6 +:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA +:101480005F1CEEBBB798F5A9368E775DBA7A27CF89 +:10149000EF53DD8C5B562345DEAFF54E04F69FF02F +:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC +:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50 +:1014C000B64FE851856C3FE524F37BD175BDDF292C +:1014D00049F43B088DB528EF91E49EA96DE674F5BB +:1014E00050607CEBA9841D3AF6537D40C89D916DF8 +:1014F0001F38A2E319779BF04D357FEF2A3E1E7708 +:1015000037C9A5A8B88315BD5BFB927E68ED6BE774 +:10151000BEB4F635F70568BE99192F3D45EF9D50CD +:101520009CEB0FE93CE3B9A456F25B778F27D63EDC +:10153000887937250BBE11793689F5A6F8751C34E4 +:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C +:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954 +:101560005F3CDE897B6D17C23B8BFF5483AF50DC41 +:101570009716FCC682B7354F0B6E4DDDC4E32AAB20 +:101580009F8F598FD236898C1E482D11EF5F298D80 +:101590005700ED87B2BA85EB75B71E39E5333EC704 +:1015A00059A6819FF4DEF875554123B7EBBAAE0812 +:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C +:1015C0007DDC5A77079FC6F5137D4F4086C37C9319 +:1015D000EE124A645FF862F4E372BA31117D6EE58F +:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C +:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27 +:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE +:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7 +:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A +:10163000CDE9EBB506A76DB55E4EE3F946595BB84B +:101640008CFCFBA33353F93C6AE350DFF525140708 +:10165000B92F5244F837F640E34B240AF2439FBEB9 +:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684 +:10167000EB322469E7D38B6430A2F0C7333D0C749E +:10168000FEED01F13E567CFD8525424F9E0B61F13A +:101690009EC06A3E0187B92EF5152393C54684EC9A +:1016A000F6B9E0673DD4B65ABC5333177428237B90 +:1016B000D607FE7B381E29F67D01AF3163DDAFB062 +:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15 +:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611 +:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA +:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD +:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E +:101710002D750CD1C71ABEDF50D5A6E94184F798C4 +:1017200043822E46205DD0BE8D3D2AE86024D20142 +:10173000CB41D33EB4E800EDA997A8FDA983A03B17 +:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C +:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3 +:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1 +:101770007FB97635E7F7D40638DD5B5B6FE2670348 +:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0 +:1017900067089FBB4B4C39ED2A37ED0A917A8D359E +:1017A00076BEE78F9F889FCCA5B9127E544A21E26E +:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD +:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE +:1017D000F164A619C77A20BDEE5607E2C389C6FB9D +:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F +:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2 +:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681 +:1018100038DB7F9D9C514D39030BA87E87FD9D7C55 +:10182000703EBD8FD7052E71F6F7E141627F2DFB2B +:101830001BF54CF64BB58764B6BF2A731B3C6C7F17 +:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21 +:101850001D6914D7D3BA7F1CCB99557B882F2D33A4 +:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30 +:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B +:101880007B25B1BFE7137F7FB73B7CA17882E8F768 +:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F +:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB +:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC +:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338 +:1018D0001DCC574787C57B01E3E95E6282F702268C +:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25 +:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC +:101900005E75D295796F8E6232F2BF3AFD698B4671 +:10191000E7907ED761B7BAA7F23B45A75B81A349A1 +:101920002DBFD8F083864CF712461CF20549DED64F +:101930009976E6A813013915BF4FF8CCCF76D018A9 +:10194000B453E552718FDA8882AFE5D7B2F89CC5FF +:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286 +:101960003FEF41436DD67BD6838612DF33EFE94DDF +:1019700091CFEE3A4776419B8817B8E46CFBE3645D +:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D +:101990005A698D4D9CA30CABD08693BD497A2BD947 +:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66 +:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C +:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81 +:1019D000A19E10991B23C7BEED7A1FD26119E11792 +:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB +:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B +:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5 +:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6 +:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0 +:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9 +:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E +:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE +:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5 +:101A7000E78595E8F3B39F9AF32FBF7632903D74D4 +:101A8000952AECCEAB5C90798678E1D9D345B390BA +:101A9000415C45FAEC707E87FD618273C73B20C4D0 +:101AA0008F2EC17D7B5F9CF3C14D12FB4B9B9B44F2 +:101AB000BE78711AAFEBABEE23F6DCA304D7BFB848 +:101AC000491946F43D343D924774593CE6ED74099A +:101AD000E75562DEC7C269D743D4EF5BBD6BAEE3A7 +:101AE000F3A1C6369ADFD0F4B6F5F7917EF9AC0DC6 +:101AF000C86F7864CCED4B204A2E7B4A27FD8AEADA +:101B00006D97CC77EA7688DF33C016D9D1FEAD3F2A +:101B1000E915CF53BD56D3CF00AB9EE77BFC3354C2 +:101B2000B1073039CBFC3DC948FF44BF2F649D67E6 +:101B30000D25580AFF23BF2BB6DDF44FBE39F483C1 +:101B400039E45F84D6481ECDE34892B847ED29F5C5 +:101B5000FD8EF8CC50F2F3D23A7E26FC0347D2FC3D +:101B60007C8FE46DE4CF747EFC975A17A7EFA27DBB +:101B700044E9FFA07D44E9FB681F51FA21DA47944C +:101B80002E3E839DE2FECDD08DB799BF76B38EEE0B +:101B9000F94BC0D4EF13FF4ED35B26FC4B9A0EDDFE +:101BA000D983F0A059E6F8E8E26715D64F4FB68C16 +:101BB0008AF95D52A4D7C3B4BE92E63FFE84EE59C3 +:101BC000973429AAA4D1BDECD3D91C7F18373F8202 +:101BD000039D37447638C4EF2999F3DD9ED6B69E2F +:101BE000DA6F7F368F6648E738020F773813FEDEEC +:101BF000B0156FF7C450A17F7DCF19298B3E7F8C24 +:101C00008F4F633FF018C2E7823FD03881BD320C5E +:101C100060BC8CF56FF4D3C53D042B2DDEE1E038BC +:101C2000E5ED3BF65F7D25F6F77F00222F54BD00E2 +:101C3000800000001F8B080000000000000BCD7D1D +:101C40000B7854D5B5F09A39F34A32934CC2000957 +:101C5000123809AF00018664121212E024048A8A45 +:101C60007482D482A28EB462541E23D29ADED23FF2 +:101C700027244012830605CA558401C1C7FDFCAE66 +:101C8000D102175BF44E50A9F6B73422E2A354C731 +:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF +:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9 +:101CB0003BB3265E5E24C900A7E9670A80CBDB1729 +:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0 +:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11 +:101CE0009B968EF51B334D07A8BC49CE999E812546 +:101CF0004088DFFF515EC5810CACCDF456DB024E4F +:101D0000800A9000F2807F4EE37F531D29008E6889 +:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27 +:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597 +:101D30001B74D23EBEBAA71CF70326080FA37DED85 +:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999 +:101D50008D1BFDA4A479E3FDF4B245B165F503B88C +:101D6000857EC7F6E3103E5286ED926BF9813BF11A +:101D7000BDDB322590BC00359BADEF4762D6B10488 +:101D8000FC6961EC77DB0EE37380882DEC03B83DD2 +:101D9000E00CB62000173D81ED0E433B8FBB78AFC2 +:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140 +:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A +:101DC00093A55F0F90719FE55E97E723040D4C800C +:101DD00009A711E42039CD80FD4EBD2485245CD7B0 +:101DE00034E99BD4483E3EAF423C67E17B26F90F85 +:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3 +:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E +:101E10001D01F0C73A07977FAA7373F96E5D269785 +:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B +:101E3000FCF7F1007D681C15A06FB41C67F39A07CE +:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7 +:101E50006F70FE620D0F4802D5448CA5F8DF8FB776 +:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6 +:101E7000D724C65DD4F1629627DA0ECBDF33F48720 +:101E800015A603867A638EB1DE5A7120F67D1D0E8B +:101E9000F1E52D9BEFB0055C58AE372921E799EDB0 +:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2 +:101EB000712BA0607F0B80D29E7FE67B00F50CE744 +:101EC000791204DB138C5B47E312BDEF4F02E93C50 +:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4 +:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA +:101EF00033404FB00E73693D63777D6C3663392E86 +:101F000059D0C95877C49C81E5899A7F6C3CE261BD +:101F100032F59B26637B6ED71107A2FCBEF6AB366B +:101F200039106F6F9BCD00034020BE04FBE31854B3 +:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737 +:101F400041E445A6A34AC1EF3710DD88791440511A +:101F5000B37415E8F32A241F68FF547FADDDFFE654 +:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0 +:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C +:101F8000BF0EFC773A97F83534DD89EBBD358CFC14 +:101F90000F179FFF9FF13AA37C3E22219F1FBA1289 +:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537 +:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D +:101FC00080F7368D2E86285DB369BE65CF5AA00591 +:101FD000D7B76CD288FEB1E3C7BFB7B44902396640 +:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1 +:101FF000A7322AF24559CFF868D3E44DD720FF180D +:1020000094D726FF9F7E8EF301E27127C2A7327319 +:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD +:102020000588E0EA92EBB201E1B919D12521DDCDB5 +:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5 +:1020400078FC6B5CCBAD606672CD36E17873E7D817 +:102050000B693FB31A045DBF9EDE759C9EBF3E298F +:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A +:10207000E80D37EEFE08F163524649A7537A9617EA +:1020800044C91FE97894A2F26F9AE454699E936E52 +:1020900033D3BD25ABD546EBBA154207149C7789DF +:1020A000376C23F9773BB82D5462D1D54D1F447F4F +:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E +:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C +:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8 +:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41 +:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3 +:102100006170749FE36C004E92F33B5358CE1F7B7B +:10211000AED84C783AF63B6BC844F52D23DEB8D3E5 +:10212000C7752079732CC36BB6517B466E48C5F6D4 +:102130005BCCA0925C86ED426E3D3FE9AE77488E67 +:102140002DDFE932D94D828E653401A447D7BEF325 +:10215000EF38CEADC8AC766F546F2C9AF2E8C62734 +:10216000900E1699DBEE29C767A7203CD68DF0FCB0 +:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D +:102180004B38FECBA98191B41FC854FAE7E0F39A0B +:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83 +:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59 +:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB +:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58 +:1021D00040765381645288CEBB9A115EA633E9499A +:1021E000196FE6F7169951BF121D06E44282C7091E +:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC +:10220000D63F4A774797FC86E86EB3DD6BC7251C3F +:102210004F32EA7DBD9C393E9DF9E516C79760298E +:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094 +:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80 +:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8 +:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9 +:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4 +:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC +:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33 +:102290003A6E32F17E17D13EF0F96F0AFD3733BE48 +:1022A0002DA827106E0B5AC66C2779304DCA4F23C4 +:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D +:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE +:1022D000677B469B9015A3CF333AC7A6E747F1E447 +:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD +:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB +:10230000394ED467D87F51E66F785D24E81CA8D792 +:102310007E00FA4FF5AA5F61BF3797A5B25C987B44 +:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364 +:10233000849EECEE07CCC3A43F013767C1FA24ADFD +:102340006E2AF963C3AF483EDF99EA95D064841AD8 +:1023500019C2C4D7272144F05E6D0AB2BDE7203D03 +:1023600080658BC99B69C1523277F5019E27C47085 +:102370009A06010BD57F6B8A3400BEB7CA539949C0 +:10238000F4FF2638FD6417FD207DF51892A395EE25 +:102390009973E9F96C35D5DD82FB6DB4CA77E793A3 +:1023A000FDF303C94B76AF0E175D7FCCB578AD0456 +:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86 +:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD +:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F +:1023E000C81E98F35B07CBF19B40667EFF11282C3B +:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0 +:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8 +:10241000C176B512F248CFFCDAF17FB646701D4A9C +:10242000830592D0BEFA35D129D9EF475DA19DD859 +:10243000EFAEE42DA91D588F9884FDA556069FA4E4 +:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A +:102450004EADC5E126F94806168DF3D13B2EA67781 +:10246000D2BB3761BD0CB145F03AD157D09BFA577A +:1024700060B97BC2EAED5468DC53B27727BD3AD528 +:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66 +:1024900043E6F72775590CFAC537CE1C7C1AF73777 +:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E +:1024B000E0FF68FC851092683D0D7B4DA116264219 +:1024C000611F94E9F40891D5446FE50041A27BD8DF +:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761 +:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51 +:1024F000B2D750218305EB49F8A290BB6E203BB6C2 +:10250000A502DAA93E092212E17B0A417A08F9C341 +:1025100032D3ED5450B8AED3F1F740E5F272087102 +:1025200079258485BE07B9F1299CFFAA4F40EC6745 +:102530005498E91D1D19F747686FC0E5B798C9EEB3 +:10254000F0FD30B1BF30A840870B22C473EE709904 +:102550000E814C31BF80879D9EFBA2F070C4C123C9 +:1025600089E0E18DC203E710F03803BE023E931408 +:10257000840FCAA7C9D025D13C8A66DF548297CB85 +:102580002AF073D90B5C5EA8F79C09979248C01299 +:10259000C84F009FA989E96684069F3F1600CB2F8C +:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A +:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C +:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1 +:1025D000B958FF41C128511F5759684578D59B46C6 +:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8 +:1025F00081A47B8244C7A60C709BB03D505FE42D44 +:10260000C07A00E912106E7629A79EE06CFF397837 +:102610001B7015196981C905B8DEFCF99DAB053E33 +:102620002BFBCFC5FEC73BAD6CB7ACB10583842790 +:102630006477777D69747FC79FFE790D3D7F7A004F +:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C +:102650007283E21F38DF4C9A2F80EA49A6753D2528 +:102660008508FECBEBA7B13F7024CFFFFD82BE31C2 +:10267000E3E33EA4F134AFD073E0C92924B8958CCC +:10268000F45F4BFD4EB850BEA651BBC0434F6563CF +:10269000813297E68D7F6E4EF9E6862538CF52A4BB +:1026A0001192D38B0B0237D2B84BCD914185F86C88 +:1026B00065CA3B36A60B05E993E403F12BEDB7069B +:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA +:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4 +:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E +:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363 +:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D +:10271000422805DF2FDBF77803F93BA5E8FF939FFD +:10272000BC78D753CC6FFB485F22E896FEF7B3CF57 +:102730003F487C7A6512C7A126BD767408D94153FB +:102740008E461A106D70E2D9372E13F4AFFB257F39 +:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972 +:10276000969982A26E75B855967BC24FAED1F6F19E +:1027700019746E9CCF72453D504AFBC99480E56345 +:1027800048F81332FE23FEBFFD686835AD13A46F11 +:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038 +:1027A00029F9DDE417E33E17B71BDB97C6EA870478 +:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1 +:1027C000309A777E1AD9871329AE90405EEAFE715F +:1027D00028B9F29102B697DB25E287324BE2FE0B75 +:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119 +:1027F000EC276BFC0A612FF3EF93A45788CE022FCE +:1028000003D1C12DDA9E60731FA6B95B9B4CECC748 +:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4 +:102820004326D527CC7DCCC3F655908435FA556C1C +:10283000673E99DE954BF33F992E838AF3352475D5 +:10284000E5929C559F757849EFC6AFFBED02E10F0D +:102850000C098FDF14F1083C139FE7BC54BA89F0D0 +:102860007C12F99CF0B7CC35BC3F38C96E989C19E6 +:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B +:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF +:102890001ECE35F841F16551189153D84BFB1B33CF +:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732 +:1028B000C00756C247B9D8876A77DB7D447FA1A994 +:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF +:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5 +:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC +:1028F0007BA6196403BD764A8B491E13DD23BD26D2 +:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3 +:1029100056926B684F574619DA8BA13612C0F514E0 +:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2 +:10293000FC52D85125F84FE8DB20DB4365118007B6 +:10294000900E261E37DA59259136F637930E5B0C1A +:102950007100FB59E250C9851A7F0D8481C45F481C +:10296000FF5E9263270F8BB893ACC17359B6D0CF7B +:10297000CB5E96D80E5C76CCCC7AE22478BBF14361 +:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929 +:1029900001235C2FAB31C2353B6884EBE05A235CEA +:1029A0007354231C87344D34F41FD65669A88FD82E +:1029B0007485A1FFC8D06C437DF463D71AFA8F6980 +:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4 +:1029D000DB538F305D1D40BA32A13E287CE9DFE237 +:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD +:1029F00099969798006A03F1E385C2FF1584FF94C6 +:102A000028FE75B9DA139FEAF81D42FA9AE565794E +:102A100084F07EB22485E9E5E04B270F2B40F84F88 +:102A20008502DCEFAC29228E22C9C126A2934E700A +:102A3000B591FDB9C61264FF4545B3702729E53845 +:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777 +:102A500087DB0DF5C297F61AFA1775860DF5F18723 +:102A600041227D55F0A6F7792A8B3E5438FC55FC5F +:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F +:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F +:102A9000377247AAD73400E191FC4E03F9DF807604 +:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3 +:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D +:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2 +:102AD00084F628D9230D157EB697A74370203DBFF5 +:102AE000069455C4779219ED577CFE3F23028D85DD +:102AF0004562B1443F777D21B3FF3D85FC6906A661 +:102B000002A4F74ED0EFB43E78691EC5E34F902E75 +:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031 +:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA +:102B300013FF3288EC917585C2EEB34B0829A4814E +:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA +:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B +:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33 +:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24 +:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9 +:102B900097FDF5DB338F731CC52E99C047FE505A45 +:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3 +:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9 +:102BC00062F6B9659347E835F2F3DF6FCEAE84D491 +:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64 +:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF +:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F +:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5 +:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F +:102C200011BD4471D844F6CC5D12CA0BF277495EEF +:102C30007862E405401ED9FF7749A3BC44EFB6FD96 +:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1 +:102C50002EC86E00A7787F81CDC176E81D3EE12F9A +:102C60001EADF8EA06B25F7320D58B32107FC27FAB +:102C7000A2B8C97C531AEBFFD55907B8FE61338857 +:102C8000BC514DF821F25797A6A60ABB58C1FE5871 +:102C90003F9161E6FAA11181AF981FF3C39CDF5801 +:102CA000DA5FC4F3C01319447CF833D9FFB5E05799 +:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B +:102CC000ED1A70AD05F1FE49B2FA395934637CFD55 +:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0 +:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9 +:102CF000038303561F8EDF66457BD2299ECF1E13AA +:102D00008DCB9EB0624971D024513A7DC2EE75F9E7 +:102D1000449E532F4710CCB09CE4D3E57CEB708AE3 +:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D +:102D3000F7CBF02F028117F71A5CAF6788FC05F11B +:102D40009F4742BF16F721FB720CF167726053B1C7 +:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E +:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648 +:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33 +:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1 +:102D900097F78B72AB117D7158EC88705CEF6CF11A +:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271 +:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2 +:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB +:102DD000AB743AB6268EFBD768F88CC74FC18860B3 +:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C +:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029 +:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC +:102E1000B723FD893867730AD3EBE2E7DE7AE7E789 +:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3 +:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA +:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F +:102E500013F2E3E27DBF7DD33496E8C41996B084C3 +:102E60005DC6F857BC9E7243E03A92237694236481 +:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2 +:102E8000EE2679645785BF362450C1F5E556E1AF8B +:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533 +:102EA000ECC7E56877B0A79317E4F54232FA41E939 +:102EB00009EC069357E6785C5A600DC14BFAD1D401 +:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0 +:102ED0008DEFD3E281686772BCB314029A1DA1C55D +:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0 +:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6 +:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1 +:102F100047DB0512D6D07AD5814823FEDA3AEB7723 +:102F20005D2F60D932E691C84A6AFBE6B44476A4C4 +:102F300043B303B8E847EB14EFD906AEBEC384FA37 +:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA +:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F +:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0 +:102F7000D16332C4EC9BED9E98BA14072F89CAEE38 +:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0 +:102F90008110AFDF6AF18317E9C9E6C176C3390C46 +:102FA00055CB7F220117C7ECEF1CF64576B955DBF0 +:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24 +:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF +:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E +:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063 +:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D +:10300000A6379A4374CE46AA0A73DE3857058E4710 +:10301000A73603E72BB67B851FA5C7E947D2103239 +:10302000FA2D567716D9D1DB1BEFABFC318E732A04 +:1030300013174FF9FCEC230A8DB36D1A70FEC2D939 +:10304000F8D1518A7FE540D81BCEA1B89A04E11887 +:10305000BBF4FA600A8463FC896AA58FA15ED43947 +:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD +:10307000D050BF492D33F4B7434E4B1EE55D1B2D99 +:103080005ECA8359686FA567C20D76D8F83D05FF03 +:10309000911F9383167DF7B8B88F74D56618D7192A +:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5 +:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856 +:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF +:1030D000E36FB44672FABEB7D519FDC9F446772539 +:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32 +:1030F00007E239B443D04708047D841A81F385A1DF +:10310000AADC95D47E2A047C0A46A78FD1550B678A +:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF +:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72 +:10313000E79D819727049CF5F3E7E97170CFDB6188 +:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255 +:103150009B2177A4519C540599E2322F660F373397 +:103160001C9ABC8C9F19D88DF830A70938DF134FF3 +:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5 +:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1 +:10319000CB641A1FF6CA0328AE105267F3BAB737CA +:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0 +:1031B00017DBFE8C696EECF920A40ABB3993F7612A +:1031C0003797706911A5A2956011ED6189EA835660 +:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81 +:1031E0008A73193E694A86015FD61223BF23180FDE +:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC +:103200001C5FE932D510DD68E72DD257CD06CA47DD +:10321000D567FF742ECBAF7A1BC31D5608BAD0F307 +:1032200082D6264187F1F4E3F21AE9C72A0D3489E0 +:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9 +:1032400001C467D6B8F1EC243C49DE78045F3A61EA +:1032500036D07BCE123BE7B1413ACAF8B74E00E810 +:1032600013734E217EBD675DE777A4F30FBF239DE7 +:10327000EBF267AD57933F45E25CE429A46B8A1FEC +:103280004DADEA04FEFE0ADC26A247A4835959C5C7 +:103290007CF4817F76911CB213BCAAD3A8DDD5A99A +:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6 +:1032B0007989EAADCD16A0732628674C3FA2794BD9 +:1032C000EDEE952479A481E369DD853E943B1447B6 +:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6 +:1032E0003D110F47D7040D8EC508C721DF1E8E364E +:1032F000AFD0C3E92542CEBE98FD537ED57D589C04 +:10330000AB495780E1FA852AF4F274E97898E4CB66 +:103310003A05E50BB6CFD0DADD25429EE870CED572 +:10332000E0ACCB9375F32183F8DE4DF2C44970FD18 +:1033300088F5765B9180334084F39FA98AE09335CA +:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A +:103350008397094C04DF78BA9421A68EEB4B8DAB92 +:103360007F5BF8964ED0F4643F283E1FF8AE4B4981 +:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D +:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC +:1033900018E07A53DFD5990CAF9C859944CF4DD670 +:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6 +:1033B000BD00DF5F8DF289F290A92501078DD794BA +:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8 +:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05 +:1033E00076FA15FBAD1906D0C979C89083E0642B35 +:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3 +:103400003B85FDD5D23ABBD7F351214D2E6CA97324 +:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C +:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05 +:1034300027ADCDA860395C051CCF5E99F239E7DF76 +:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5 +:1034500055BA62D457748E29B6DDE51D65684FC92B +:103460002B30D493E48986FE5326047E3981E48090 +:10347000A7324E0F223F8E899EB36B6915DF4BE951 +:10348000F0D3F59353E3F33556EF00CA3B395B05B0 +:103490009F366B765E13C111CB6405F8DC8CEDB002 +:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A +:1034B000D7286427B4C8C28EB78238F76BCBF4879D +:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3 +:1034D000F4D239DB96D6656E5E8F579CA771E3BF39 +:1034E000447980F8F3358EA1C67339D6B39C6FFC4E +:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC +:103500007429F22FF778043CED3DC8A3D6387BD957 +:10351000A9E55F60A02F61FFA83D25F20BAD717199 +:103520007BF4C312E66FDE9A2071FF3F4F9085BF98 +:10353000660903C96B9717DF8FF53B14F17DE8B976 +:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1 +:10355000083B254916DFA1D84051583E81C887D085 +:10356000591FD237A95ABEA75BCE908888A13BE7E6 +:1035700019FEAEC88BD06716443F96E8FB17C4BF50 +:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6 +:10359000D1BF1F832E4F3180EEBA23FC5C2589E119 +:1035A000172678359AD6CDC8C5E7A95E8B173100A6 +:1035B0001525F25E3A5FB14A4965FDBEAA446E2701 +:1035C000FEF942717A091FADF955ACAC93867DC8FE +:1035D000A2B7B1C4C676BA8E87246D5E444F679594 +:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F +:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0 +:10360000C9BDA492E9C7F82097861F660DD2237919 +:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1 +:10362000CF6791FD86F92F349E60A0D0436051F89A +:103630007B8333E95BF0B5DEAF673E50F5EF4E5765 +:10364000D2F9E0268F90A34DE07D3340F55724AFAB +:103650002AD3F38237E9BCE9EA8116C6CBEACCD992 +:103660004DC28E177E53936725E76DE3F5369DD7E0 +:103670008C95DB745E3356BE37C9B37BD5CB59010D +:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB +:10369000AB8A392FD56CF13B485EACF2DC678AD53A +:1036A000730F2881052531E793AC99B3F83D7BB6BC +:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4 +:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A +:1036D000EB23A2F8193EF4F26496CFEB441C8379F5 +:1036E00020665EA524B082D615C5AB390A17A4D3CF +:1036F000E1F957B0DDD1B06E7632E169E7FADED795 +:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48 +:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD +:103720004EE891E14F887D9C4987C6F5EE6CEBDD54 +:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0 +:10374000DCB8F65171ED0571F58971FD2BE3EA578F +:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D +:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34 +:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B +:1037800073C543D4DEF5339DD94A46B17CDF81F65B +:1037900015D9433BDB2ADDE27C4760E56E8D3E4870 +:1037A0003F58368879D0CE4AE6F89CD36390236799 +:1037B000C3B709328CEDB17668EE85C7F7D9E93326 +:1037C000A4D917BDAF5BE7E32913FC27490E414895 +:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3 +:1037E0009359C49FB5FB50E86E1D11270F684A38E6 +:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1 +:10380000094943839B28EE9B7C988FE740B3AFE048 +:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA +:10382000C35877FD5D827021DAE9635B14B259DA1F +:10383000948C243A4F946272B4939FB8AAB0CD3F4F +:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758 +:10385000D9D265227A837C2F7F9786EB54C9C6B272 +:103860009677D5253A77BAF60AB7898CB0F419B2AB +:1038700099CE11F79910E85B8AF018DC046605EB25 +:10388000196A98CFE25C532A0BFFEA196428DE6FAD +:103890005716C1EBAB66DB7EAAF68C0F90B438DD11 +:1038A0007995FA38698234E887E38EB245ABAB8FFD +:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5 +:1038C00098671E1FB812DB5B0B0799489EA67B52B8 +:1038D00013DE137375A9909FDB9B170E4EE48FE9DF +:1038E000A53C13383021E76B25D1D4042C876AA579 +:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0 +:103900009EF8F1E794BA753B7B809F8D6CC877F683 +:1039100033D88B5797F6622FA279CCF1DAAD56796E +:10392000009D23DCDA6C03BAFF616B3688EF905799 +:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67 +:10394000D14DC80486386EA6065FFB4493768EF28E +:103950009B307DC7B755CBF36C8588DB9D1F8BE70C +:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57 +:103970002B37E27BEB1ACD1C3759D798CB744EE32B +:10398000907D746AC52133D9ADF9D06E263B7F1482 +:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A +:1039A00061A0F0F341D0C5C0F9B438F01382CB1058 +:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF +:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD +:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8 +:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7 +:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2 +:103A0000207354565533BDFF14E11D9F2F0C07A79B +:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C +:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418 +:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3 +:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895 +:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6 +:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3 +:103A70006035FA358F2582A34EA73A3C6E78A26B4B +:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED +:103A900038F024BDEF6BF337701E7057275D47D4A5 +:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12 +:103AB0005772BC782F88B8589C3ED44BAB129F6786 +:103AC00010F7E58CDB6BB493915E958D9E587A353B +:103AD00073BE33A4E9935013D22FCDB742D06F48B1 +:103AE0005DE64E44678F687A658746B7FAF3A13D75 +:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C +:103B0000C0CBFC807C7084FA65101F607DF00A37A2 +:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188 +:103B2000F7D745343C227DBE43EF2FD9D475807C36 +:103B3000C5C12B047D7E4C77871545E90CFDC7F781 +:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9 +:103B5000B829C8E321FF1C2BE5713AC349CC724A4E +:103B600025ED676B1BB8693FF65F1474905C3855A0 +:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F +:103B8000AA33916C72298F6BCCFF0D6B33E20FE976 +:103B9000E76F344F91276013C1EBA08DE5690F7477 +:103BA00011D57BAA0EFF157172D73CB1177A3ED79B +:103BB00071D7162B8E8945DF621DE7D84F8F379D51 +:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB +:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436 +:103BE000889FAE008E03AD4C196B4A44379740FC5A +:103BF00074CAC444F1D3C87B063B735593900B3A07 +:103C0000FC86578D4C16792948A57C891E1FD3F751 +:103C100075B7664F3669706B21B8313C05DCDA0840 +:103C20006E0C4F1D6E33843F425F8853BCD66316C3 +:103C300079B1910B3651BEE054A6C893D767DB44E7 +:103C40007B8EC82F9C411F9931F634F2C19A667160 +:103C50009F08BECF79B517B30F3886509E33D3CCAB +:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65 +:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2 +:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B +:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30 +:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228 +:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD +:103CC0003523753FEA1147A2EF1852AB8CF4D8A206 +:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4 +:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86 +:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E +:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4 +:103D10007E1CD773A2724ACF870D75DB985E876AC7 +:103D2000F74535FC7B4A68650EE5D76675513E72EE +:103D3000E80E89F3EE439D7ECE43746C98CEF9F184 +:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D +:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9 +:103D60006727392E1F107F3F4E7C7D4E99D0C39917 +:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136 +:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E +:103D90007D4EF94093B3FF0997A29C3D5112389E86 +:103DA00050CE5ABA58CE8627289F919E5C4E177DDA +:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6 +:103DC0001D0FF75C92F942C4437659223CA05F452F +:103DD000F06AF32983A85D29510653D98D8F1F26D8 +:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF +:103DF000C769642D4E93C7CF9B357CAC39031FEF49 +:103E00000B7C94E8F878EEBCF09151956168779757 +:103E10001BF191EACB35D49DF9467C240F2D308CD3 +:103E2000B7BC4C16F7240D9C68E877263E8CFEC084 +:103E30009DF45E2FF6E8C04067057D4B34606E7BD5 +:103E400007C9E64C7F5B0595FA3E37C7F9737AB927 +:103E50005CC35FE6D4C4F85DA0F15BC644E526030D +:103E60003D7C2F317FD668FD979728B794C5F2F334 +:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA +:103E800031F6784FFB0E242BCBCB78FD224FB6A317 +:103E90003E95F3663B92E476CA57ABF54EC3BD75CB +:103EA00083E937AC67FEE89B0E95CED9D13D4168DA +:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE +:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266 +:103ED0007CBEEFC814EE63A27BB2C09D714EF92385 +:103EE0009467E25EB7C120BE238620EB41C90FE98B +:103EF000F4DDB205FC225F4EFDC5F785BCF9140860 +:103F000073DD0511AEA7697EDE0365393C6E3AC8E4 +:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A +:103F200036AD245FCE0250467EA073207FCF0B9526 +:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B +:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508 +:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C +:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA +:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9 +:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA +:103F90008F123F37B88AD9EED4CB78BC5DA12811F7 +:103FA000EA27395E1BF0619FA83DE73C6A627FA863 +:103FB000C124CE9FA9EF99D8EE827C41074E19F219 +:103FC00072C645C7717A838345DC49C45FEAFF74D2 +:103FD000D708B2BF7F99322B9286E31D7C55D87FDC +:103FE00096A991CD74BF73FF349B773BF2DD3DDA28 +:103FF0007AEDA513EEBD137FBD798A90172E8BF74E +:10400000F2023EB7343342F6A3ABD82253AEC01906 +:1040100097D76CB5B42553BCB275C77D15A3B0FB5B +:1040200063752FB91B137CEFE9D4F29A23A5C472F0 +:10403000F09F939244DCCB67BC4FD85AAE9D2B497E +:104040008554B2232DFF52D2129D07D04B7DFE2204 +:104050004FA48ABEBF8ED0256E88E7A292EAA464E0 +:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7 +:1040700035F6FBD3D61270911DEF9B22CEC36E5046 +:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B +:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92 +:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9 +:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95 +:1040C00075725F016F0856D3BD9DEB5226F37D9646 +:1040D000D973443C78BA74B483DE7FB0C4CEF81B85 +:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07 +:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18 +:10410000F5A8192456715D3CF974C929D6E5157EC8 +:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7 +:104120001E68F726E19FA68D777A91D271BD71E75F +:1041300085F475B5E1BAE8DE63D7508E4764CC31BB +:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8 +:10415000FD85FFA785AF71AB574EE47FB6D64167AB +:1041600055CCB904670F71C09AC982AE6D592F380A +:10417000C84EF9C27FC4433878E59F073EBC97CA52 +:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83 +:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2 +:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91 +:1041B00093B87D64398492B07DA445C9BA99E8AEBC +:1041C00053F2D6CB3488388FA8E37FED0D7E138C65 +:1041D000213CFA25BA0F639A76BE76C3229009FF76 +:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92 +:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B +:104200004F3563B9328FE75704BDA475169B9713DA +:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2 +:1042200077D848DECC4700D3FA5A357C69718322AF +:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228 +:10424000C7E34818497894A12D99F4E14300ED742F +:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3 +:10426000F91DB4579511740F8B83CB4EB457A9DC4D +:1042700085F62A95AE60C575CB71DD7BDE38F8D248 +:104280000F71BA594AF5957444AB48CB7B81BA7427 +:104290005025AEFF06E25E51DF4289C4777D92A1D0 +:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E +:1042B00094A108964C8B968F11F559E487C4B4EFFE +:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9 +:1042D0005BBA45B5C4B43F87F572805735FBF1FA38 +:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC +:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8 +:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B +:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9 +:104320005A35C4C2F70FA13EF0F696AFB3782C9F72 +:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA +:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89 +:104350004DE638AAE45A9FC2F731D535B13C7F40CB +:1043600009FCB63CE67C4963FAC242922FFA3999BD +:10437000E8BD47D798BFCDBDF71DD50780F4C297DC +:10438000485AF65EE8B0B16EEF115AC7EABA762E17 +:104390009D6E85858DDD12E4B8CF154AE04FB43EA1 +:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254 +:1043B0003BE224B86F28F9C049F3B71E167CBDE173 +:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A +:1043D000C0273EE5559661BBDF48BD9EE8674F4369 +:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17 +:1043F0009B6FE0E14195CE18BE818799AEBBF9462F +:10440000ABF7CC377F67BEDADDCD37A2EECB074303 +:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9 +:104420007DD2C35BD418BE3A49F558BEF909F24DA6 +:1044300002B93F7D9246DF17986F522E32DF0C9DF6 +:10444000A4C9CFEFCE3763275D14BED9633A1FBE30 +:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902 +:104460005AE79813FE7D900F347939757EA0B28D8E +:10447000EC1A45DCDF374D9A99E5F3109F497487B4 +:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541 +:10449000F58450B293160BBAE9AC1371DF6952F987 +:1044A000B4C5A477E93B024A3553F694EC02D4FB39 +:1044B00032D985D05EE1C179365499A04DA62D0739 +:1044C000AB87F1F861B6CF8668717FA7942FBE677E +:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5 +:1044E000265C770AF931EE12F17750164D8AD7BF64 +:1044F0006887E0FA3A07DA984E362857F71A273ACB +:10450000E35CB52F98302FF9D6249376CFBEF233E3 +:10451000A2B3DD6F6C49A673127B24E0F339F383F9 +:104520004FCD23BE73A942DEB4AEF833A52361D7C5 +:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21 +:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE +:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD +:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5 +:1045700066DFA4BE1743DE1C392F79937DA6BC39B4 +:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A +:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C +:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB +:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60 +:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A +:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95 +:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC +:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80 +:104600001F4FBF489FE9938B981E2D742FF8179D5D +:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3 +:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36 +:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5 +:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC +:104650005132B47D6FF8E735EF515C63C3BFAE7D77 +:104660008AE21AF77D9DB78DE21AFABD726910FDD4 +:1046700091F5EF8F102E2EBFF89E24634ECC774518 +:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182 +:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71 +:1046A000AB691DC72336A05F558F78EB9823E211C5 +:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335 +:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41 +:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5 +:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792 +:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1 +:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA +:1047100011EC47ED26BB06EBED934718EC1A7D9E96 +:10472000B566A821BB66ED0EF38C4476CDACF2C421 +:104730007E14D6390FE27039F8FB7F49FBFB5F51DD +:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713 +:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C +:104760004CF1E36F2B3F4692FCC837C88FCFCE4742 +:104770007ECC2A771BE2A20765B5CF58B2D37798D3 +:10478000A15ED6F42FD63BD1AF31219C7E5221B110 +:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB +:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48 +:1047B000309B3E235A9772C3DD4914D72E17F70456 +:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7 +:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E +:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682 +:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27 +:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1 +:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC +:10482000457A3917E524FB29E61E59FD7BD659E563 +:10483000621E27D94F8551BAE8A82EEEF55EDA94AC +:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4 +:104850009ECE2F90CCB27859AE3E5E89F239C178A7 +:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA +:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B +:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54 +:104890005DD7CEF5C773C53C132D211E6752178E09 +:1048A0001FC30F659FE03C31782E8DA886F6096FF7 +:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A +:1048C0000CED6F950502538AE85CC363867ECEFCCF +:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19 +:1048E0008302484F4867E9B5B2CA79F31AC197FD08 +:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D +:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D +:104910004CD4B76489F391C3AB447EA461A0B8972B +:1049200044CFC36F7169F793F8C43D1A83F223FC37 +:10493000DDED20EDEFC139CB45FECC0D6ECECF378E +:10494000D481F67D6284F31D1960F68AFBD5159932 +:10495000FF9E920542F5385F43BE5BBD85E44C3057 +:10496000D56BF6F29F960D99298F48E2899330ED29 +:104970009ADED1F2F2491F009F3BE886CFE7E27B47 +:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D +:10499000130FD78E5F7CC5F72A6DFDD95759C4D444 +:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892 +:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1 +:1049C000C6E730B6D69ACD24274F2DB2305CF4F529 +:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F +:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F +:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE +:104A000003C35742F8F2772A56D86B1A07F4870C7B +:104A1000196EF1DFC7665425C79DE7319EB74AF589 +:104A20000D30D49DF9C6F356C9434719CFA90E34AA +:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C +:104A4000609A566CAC27FC77FF7D477AD88FFF7E43 +:104A50005C37FD86F47340129D4349637ACDAC12F6 +:104A6000F499A17D0FE3864E2E53915EA874529E59 +:104A70005DA273902AD351F4FB37A5577A3ADFBF72 +:104A80000720AD4CFCF700F473087FD1ECA8A553C8 +:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9 +:104AA00085FFADF2FF01C18CE32B00800000000008 +:104AB0001F8B080000000000000BB555CF4B1B41B9 +:104AC00014FEB2BBD144A35934B6865A481A520DCB +:104AD000A4B06D37A225D2D5869283C8163C78E85B +:104AE00021879CFAE358E86D635B904A24A9422F22 +:104AF00052C8C11E0A821EFC03621B7A8E680B52CA +:104B000029C18AE7405B7A11D23793AC899BC47A7A +:104B1000E940F2F266E6FDF8BEF7E6E50D68798158 +:104B200090A2DD137D40245A2A3848065468B930D3 +:104B3000305324E9A2FDB5AA94359114C0A9095CAB +:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D +:104B500031BB0126252EAF1F39000FB015B3E51666 +:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549 +:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3 +:104B8000C73D0309F29F3180FC30BBF3D0CD745791 +:104B9000343BE5A33C427B4548E42F5284DC078646 +:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95 +:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D +:104BC000299DCF5C1121325DB71F962855D860AB67 +:104BD0005C237EA25255A755A1CF0334E894F70C6D +:104BE000D347EABAFB243029535ECF0FFC1B8591D3 +:104BF000BA5D805261FBB7B51ECF71376D8410AAC4 +:104C000088751C15B6EE36CB3F866FA360673821DA +:104C100030BED43D21E7A738BD5F96BB183EB1A892 +:104C20008B25B2478C508F13CE3DDD8D73FC7D6795 +:104C3000FC7502078683CBA22173B9650C72796C6F +:104C4000F8B83C3246B83C34142E4BC61897408A0C +:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3 +:104C60006775C78484F7ACCE432AB76BBA17253F64 +:104C70000D7C115DBC190A3D6F2799FDBB27028F82 +:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320 +:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4 +:104CA00096E711880B58A43CBC0EC529D3FDF4B679 +:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72 +:104CC000CB696A19829CD524997AEAD46F8F42F90C +:104CD00034F45560FAE320AB677A223FA8138ED5EF +:104CE0009B9FE786C92EB5232288E6BC5E6B369E65 +:104CF00097892B202982DC027F3B5C8F6BF618F2B0 +:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6 +:104D1000125D898C4675D2D66D9C07A70FFC7D77F6 +:104D200040CB33BC17C80FB8433CE7238994AB9EF4 +:104D30004FBB3A997974D7FACF9B2C3B12846FF909 +:104D40001F7DD8672F3A58BD9692423CD7228FF5E7 +:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D +:104D600056F35991C83F9B4F2AF96FC1F737C67761 +:104D7000B59FF745AA6B46137CAC9FFB891B8D4200 +:104D8000F547904B116FD9A8A0E4E9FC97DAA17020 +:104D9000F796F9D0145F6DE8A36BCD73675B73551D +:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374 +:104DB0004773EE34F358AEE24C567122DCFA3DD71D +:104DC000EB355F1BEA488867FBE6EB797DD38E7F86 +:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66 +:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8 +:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A +:104E000000000000000000001F8B080000000000F0 +:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161 +:104E200057F1A3F2CBB851F99E68FC2634FDE7D1C7 +:104E3000E4591820B4233BAA38B158988381410E15 +:104E400088353950C5F3A1E6D6002DE807E215AC48 +:104E500084CD7A27C5C0F05F9681E12890AE06E246 +:104E60004B4036931C0303AF34038307104703F111 +:104E70003B190686A940FA25106F9086E8E3048A5C +:104E80009D9421CFFD6D42E4E91BC5D4C1B7955077 +:104E9000F993B51918AEE93030A8E941F8E791E483 +:104EA0009D806253B421EC70550686BDBA0C0C8708 +:104EB00095B09B1B0194DF07948FD0C36FBF831104 +:104EC0002A7FAB352AFF8B212AFFB2272ABFD61BA8 +:104ED000955FEA03A10135720CD6D80300000000EB +:104EE00000000000000000001F8B08000000000010 +:104EF000000BCD7D0B7C15E595F899C79D3BF79987 +:104F00004972031708308941A2061C204040C44959 +:104F1000081A6C8A17A44A5DAA576A2D228F2B6241 +:104F20004D5D6B26EFF0B08DE856FE6AF5C26A97CC +:104F30005AADD1D296B6DA26802EB61422A5D6B6B0 +:104F4000ECBF415D6D5965A35BD4B5B4EC77CE374A +:104F500093CC5C6E1EF6F1B371BBC337F33DCE77D5 +:104F6000BE73CE775EDF7715D107FA250067F08F25 +:104F70003DCF170160E6C0335A01A57239C0262122 +:104F800068848BD8F34FD2F2CE30FB06567CE9947E +:104F90008176578340F59F2F6A8DF7B2EFED93BE70 +:104FA0001A8732567FBC40F59D7ACEF30690000AF0 +:104FB000004A3A56AA09D6CFA6318D2AD66FD7B75E +:104FC0002D0736DEA91205241CAF287BFBD67A807C +:104FD000AEC90097C056B538C6CA47256333641BAF +:104FE000A788C671CAFEB8085DA5407F67D8FF369E +:104FF0007D290909366ECBA4AF2E47B895AE9B40EC +:105000008F00DC3626093A7B3F0D449A9752618126 +:10501000C9CAAA6EC5AD29678FD38E7829C35E3BF6 +:10502000E24B2303EF97387861F8C8C00BC05C00EF +:105030000DA67759580E00B5CFECD7B4C7D7E223E9 +:105040001BFFECF9F3F1A7824E7800B5239E880C84 +:10505000C0B3C9D7D725317C5B45603CC6AAE4B054 +:10506000712A5DFD648ED73F4FB9C3B3FE5310CE96 +:10507000029A8720BBFACB8467965D6F169B393EF8 +:105080009D79E5CCE3E30CD7FFE588E202ACDF11C4 +:10509000B7222E7A942D0FDE83767DCDF4D61B0CAD +:1050A0003F21C4CF4CC48F15477A74E8580AEB0DE2 +:1050B000356C3E0516F449B94436268C02C8C77FC4 +:1050C000B126B2A65722BD8E32595DF67D74CC6AE8 +:1050D00090D8FB31F3D282CC9E1178487B23040810 +:1050E0004DC9196A6471BAEF9CD1DECBE8F614445D +:1050F0003A36B36793CCFA45BC1D8BA41F632035A9 +:105100005C9C7AA4979523960C8DE5342EF1E1ED05 +:10511000D2F9C66646D29B6DFA6FAF57E9D95AAF3E +:1051200041971FA0B93E4ECFFB4377FD1BF65F674B +:10513000F9353F7BCA9DB73E85E52680048E1789E9 +:10514000F1FE4156B5C7342C8389788F94F0E74B34 +:10515000881706E7571926112F3FB0F1A44317F11E +:105160006B93B13407B2E0D379864ABD7C16D08305 +:10517000ACE540D91FCFF3947DDA584F7D8042C211 +:105180001B9599A85825707914917BC0403819BE99 +:10519000B2CA055BAE48D2B4BE2E36BFF06CC5D8DD +:1051A000C99ADE2D78F96B8CC0E9A34C50E91983BC +:1051B000BE7D67102F8698DECCC60A4E2BEEEC8A99 +:1051C000E1988A3189AD63D097D6F2B2F01794CBCB +:1051D0006FF53A70177FFCF891A4EE5422CBB87F9C +:1051E000B0D7EF92D38755E47F759A98489721BC42 +:1051F00056824D1EB6EAB288F3FEF8E01E7ABD8EE6 +:10520000DBFCDC0A2AD59771BDCA07D6ABDD60EBA3 +:1052100085FC53CED7AB5DB6D491ACD7E3001EBCB2 +:1052200084FAF1D2C9F152F631E3A569EFF244965E +:1052300079B4DAEB29836194121E141DE1DCDAC023 +:10524000E9D662749B4DFE0E860729E7583C5976D5 +:1052500036DEAF12F8380B6C3E71F0B4C9106BD269 +:1052600061C453470DCAADAD25A28872E9E3C2936C +:1052700003D7E67EB8D21CAED28F172E29D4B53C08 +:105280001B3FB666F0E316849BD35D0DA73BF1632D +:10529000A53B07AE00F2035FE7045F67F91F629D5D +:1052A0005BFBD739C9D739FEF1ACB3B39F836A2C06 +:1052B000C7755BA5313E6470DC2C59CAF5B8BF8652 +:1052C0000478CC607480F08F617A66B8F1655D0710 +:1052D000B84F08707D435A919374C1BB4A663ACB6C +:1052E000747CBFF5DCE410F380B4AFAFD78193F1E9 +:1052F0006FDDB186B6FD2E38BF24446204E76C989A +:105300008D70BE1B5E9AD30583F777A25E6D907D8C +:1053100000EFD75B6DFB7D677FBF59825436FDF28E +:10532000415B2E80DAA9D0FCEF643C380DF1706E41 +:105330003544D97A841B47E13C20CC3ECE61FDEC5C +:105340000A34C82EFC0E369F7EBC3AED98BAE3CFE5 +:105350003BBBFD60ED3E14928F080CBF2D31B11A9E +:10536000E1524B208D6BE0DFB5A46B2C0C0E6F4B24 +:10537000EC6F03EFA0EB66D77B37DCD80AAC5D930C +:10538000CF38A0333A692E108D461880C3A1176715 +:105390005D1C3C8E745D7EDB4F5F5B2F05D233411D +:1053A00097A6FDF5747500E9EA82BF3F5DBDF18FF8 +:1053B0004B572784827F5CBA52EA24FD75666714D6 +:1053C000C9269793DA4A8BD61FC7667249EA98D6E0 +:1053D00085F212E2CC3EE3C380C8CA8A6672BD176A +:1053E0000C40FD552DF1CA495FA1574EC6979B5DF4 +:1053F0004EBF9B751C57A171D13CC271E53074053D +:10540000A25856A81F24E733E7303CC18335C5BCFA +:105410009D81ED069B8F8CEDD878A87E9C29C27665 +:10542000FF9493C862F70ECCDF3B4E7C59222711C4 +:1054300019797D08CBFA1B2EBC0FDE4E86371CBCBB +:1054400030FA2F453F49C100FECD5DB790FF2200E5 +:10545000A241765D61AB855FDBF0FFCDC17D9FF33F +:10546000755BE1740DF52D60FB0DBEB7842F0096C2 +:105470003F1474E25B673C299C00A21BBBDE70EB0F +:105480007F3BF25316FE5E21727DE3FDBB52FF8D22 +:10549000F6A0B559D01F63783D54FF01BCC6F87221 +:1054A00065D7790AFA3DAE134751BD95F38A940545 +:1054B000AE7E5602B70B017AE52511F7B80D5C0FE9 +:1054C000ED94F6E2BC5FAD90D2B8FFBD5AF13FA4B7 +:1054D0009FBF6A4A6944F2ABED57E60C25770ED5BB +:1054E000737BD6A977C894687F3F24F786B3E9F128 +:1054F00003E3A769FC2B2A24EF3E2DF7CAB8FEEF81 +:105500007F097CA83F1FAA5785D72631E317E7C933 +:10551000E868654591827E87E1E6B5C8F68339F88B +:1055200075E6D91C16699ECDE12AF25B356BEF92C8 +:10553000FD788ABD47793018BC8EDFAA595B9A1571 +:105540001F4A84EB5B8A2F99DDDEB4E7EB9433FDD1 +:10555000590E7CAD616E17B586395CAD31318DFC6D +:10556000DF1ACF3EAEF36CB2E173EA35C7B85EDA4C +:10557000CCE4C948E091C35E7818DA8EA0BF64BC61 +:105580002D6BF26B7B1A3E8F7676326C4A06BEE943 +:105590001126B0F2B8B8049B35366E4D557B356395 +:1055A00081BC1589171918301A3A2AD10F38F14BD6 +:1055B0001BBBBFC6E6356E8E5FC3767935A9EEE7B5 +:1055C00058BBB14CCC49ACDDE8636BD7A29CFD174E +:1055D000B41351105B3736A01FAB1987980BF0B08E +:1055E000B8A212FD6C3270B9C0A49E2E8F42FF0C7F +:1055F00090736630F9C0FE8433FE817683E12D62BC +:10560000CB2B9A37C9ABA543CBAB8DBC7F8BFD872A +:10561000F266DCC078D47ECC2AC583C7D119DFF707 +:10562000DB74E987257FD771C6C2D200EA2791656E +:10563000A296C6FAD0998B7EA8516B64E8C2EFE5BA +:105640001D0D4C7C0C8B7726F76AB8DF38292C713E +:10565000C1FB2B91FB9926DC715410D0EF6B309578 +:105660007E1A96EBA665A3D36D367DF6976B560A28 +:10567000491A2FB16812CAB55A91ECDE7F59363DEE +:10568000D7DDFE037B9C81F5075D9E8565BEFEF23E +:1056900032D10C4CFDCBD75FFE88EB9FBF51F1ECB4 +:1056A000A71F755D64B43D0A865FFFBF761C67DD8A +:1056B000CEE60F2E1F27DC511D40F9775F6268B9D7 +:1056C00072F6BA2DA5751BB50CCC7416B9129004E0 +:1056D000CFBEEA3C554881C1D6593A2A917C9346BF +:1056E000CF5ABE03061F578A2919F69BDD9F65EE28 +:1056F0002B61EBFF4970FE7A649443B52887502EE6 +:1057000095FB5E77FB4718C607CA0CF76F7F71DF02 +:105710007E9447169347E83FCDFC5E8B65173D5C52 +:105720002AF1FD77EF777E79AEC0C6396CF8753F08 +:105730007B7550E87983FCBE9512EDC7089F3A0B44 +:10574000DB032927874DC9AC66F57BCA05DA47FD1F +:10575000F0D2B5FF4CED4314EFE899F7DA972F62DA +:10576000ED3F79B10F39876302DBC7D93F51AF39BC +:10577000DDFBE58B58FD8317E70FA96FD5E27C5D54 +:105780007472C5B3DEF20AA43784FF3FDEAC7D90AD +:105790008D771872127E7C5670F80E237C48F7BD08 +:1057A000BF7E03F5C243A640FEA8C3153F8FA13DAF +:1057B0005E690AA42F2E9E27A4FD59E6B978DE2D36 +:1057C0001327B0FE1246480BB0EF072BDFD97A1132 +:1057D00083F78AEF4B77E3F3E41EA920593638BCF0 +:1057E000CEFB2B4CEFFB7EBD189216E21D341E97AC +:1057F000F0C58CB89B5EFBF518396166F3B7AD91C7 +:10580000B8FF51D00CD2EFE4B002388FC1EADF38D4 +:1058100008FDE6405F97847038FAF7E92B75B73CCE +:1058200074E050E44412C791340576A29E917B95B2 +:10583000EE9E7FBDC4E34242DC2478148DC3A3C82E +:105840008699CDDF5467C3E3F403D061B7EF83DEFD +:10585000F0007C2D81C472F45B58B9DC7FD81CF158 +:10586000FA0377DBFD3CE6F4E783AC71158046EA8A +:10587000BF6A54858AFD3755703D490783FCE3CDE7 +:10588000CC6E8421F4BAADB6BCD88CF10D3FC639CC +:10589000343BCE11E7FA53F819F2939D2A13C9AE9F +:1058A00019AC9F88E1D54742A55E3BC6D15F027A1D +:1058B0005E861FC8EBF7F18D924547EF437A1D0EC8 +:1058C000FE7E3DCFAED726A7542D2B9ED243EA7342 +:1058D0007F3FFCF1F6215FA7960DAEBF15DE1CBA27 +:1058E000CAEC5FC95752698ADB25E21E7DC09693D8 +:1058F0004ABE9AC27D01D4C1BE0779FB30FB8EF14E +:105900008C7042477F8A043C2EA4221FB8F0F38E8D +:10591000DDEE1A59B4F5F914C541053D457E3BB598 +:1059200090F18F70763BE7D96BB76FFBD3ADAF10BB +:105930007F14A8C41F82CEF827CB388D92F996C465 +:105940009EEB24F36D7CFAFE2C25B3F1C97FD9724E +:1059500045AD4DE86A31C515C91EC9842320F37EC3 +:105960006F74E0B75214A71C29FC1F8C107E671CB3 +:1059700006BF2C1710FC3E7C0E06BF64C393077A4B +:10598000838C724DE7F2156089EED64B6E90B9BCF0 +:10599000C8B3E513C02D71B7BD759DDDCF48E79342 +:1059A000278F6C3ECEB86C3E1364BE1E13E521D625 +:1059B00063BC0DC70D32DFEFD4EA841E67EB923B68 +:1059C000085DCDB3E148C9A2AD57DCF291E8EA82A7 +:1059D00011CE63DEC0BACCB6D7A562A879CCB2E747 +:1059E000D121C19CD7512F3EC7F1F72CF5ACCB6D1F +:1059F000367E3AFCCEBA6CF0ACCBCDF6BC463A9FC4 +:105A000085767FC3CDE7B681755962CF67E950F3DC +:105A100071D5BFDAAEBFDCAE4F76C76D726923DADF +:105A2000198D5262855C30301EABF71977BD779ABD +:105A30004E35D8F5AEC7F7420DDFFF58BD95EE7A6B +:105A400060451BD13FD082B602B3634A9AE756D96C +:105A5000ED5651BBDAFEFE6FB2F983DA059A854640 +:105A60002B4CF5D662BD86057F76EAADF3C27B810D +:105A700003EF0682B7BA1F8E5BDDF5E6C9E3A8BF68 +:105A8000B3E20E23F407F962C9768CF3E741A4036D +:105A9000F33C5AE5D42398076059323C86F9047EDA +:105AA00043401F5BB422F56F582FD762F635AE5BCB +:105AB00055EA292C5B22249ACA299F80F205EA64C0 +:105AC00055F31B987F61C07656D662721AEDF316B5 +:105AD0002169E1BEF83329F96599E4ABB6A201FB6F +:105AE000CFD7B99E0EBDB46F3970DD13BA96F21FD1 +:105AF00072195CE88F6AC980EBFED0846EDC6FEFB0 +:105B00002D50484F66065629CA97DBA5A081FD7522 +:105B1000177C81E0DDD6C0F31BB67DF20B04EF7D70 +:105B20000250DCF63E1FCF6FB8C7A76A8D1AF61772 +:105B30001DF339CA87C8D1FCE5361C08DF278A095E +:105B4000BE7CD02A6F10487C75A37DDB52A190BE2D +:105B5000BC2D36BD92FAAB50494FBD2F31BD81F4FB +:105B60008E8A20F9E8F3C306D9ADD1D90A58588EE8 +:105B7000190DA867466605310706F20B01930B2045 +:105B80003219D258F6414747097B46DB995D924F5F +:105B90007613DC80766F05C33BDA11967904ED92BB +:105BA00030D87FD24113E7ED1B2701FA3D9CF58DDC +:105BB00076F4B71FD2EE8AA64758AF6B64F522ED94 +:105BC000CCEE9F31827A1D23AC971E61BD2E5E6F95 +:105BD000587F87C1ED3D95FD87765B20D36E0E7BA8 +:105BE000ED615FC6F7CC785CE633331E7242F6C6D1 +:105BF00043866BEFC441869B2F3A25FAE19486AF2A +:105C0000EFE89B837D57C65E153759FB9631D7C4A5 +:105C100049AE8D59C19FE3EDF7E397DBE56BECF2FD +:105C20008AE56616F93EDAC7E57029FA4386F23B43 +:105C300000D71FDF60B09F1130796968FF49A6DE89 +:105C40009B29EF54D9AA427EDD96E07E4D3F322358 +:105C5000F26121901FD607A98E1294136046178E09 +:105C60001AE01F9FF98289FC7C688C044205AD8F85 +:105C700041FEF40C3AC9A40B7F863FE7AFA5930B16 +:105C80007DDE78ECDF8A4E94766944FCA3748CB098 +:105C90005E7A84F5BA4656CFDF2E8CAC5EC708EB31 +:105CA000A54758AF8BD76B9DA3F0FD1CBEDB689654 +:105CB00030B8E7AA9E72EBDCA0F7FB45614FB96DE7 +:105CC000A642FBBF53F6CF523DE53626E73DDF67E0 +:105CD00087A9BCA9A5AB8A6D6523E693FFFC0BF9E8 +:105CE000A4541DC62F5D2166D86D197CA5EA016CF0 +:105CF0009F2FEB80F953F931BE4FB1A799CE82DFC8 +:105D0000476CFEDF29F3FCCD6DB21E40FBF11F7D19 +:105D10009E0D3E0EAF33DFE1E075E4EF9B92AD6F79 +:105D20000D96F751CDF3326508525E6649B5596557 +:105D300032B924BFC8E36099FD5EAB249FF6B9EC8D +:105D400061594BF2F89EDDDFA20299F41299C93530 +:105D5000D47B1448D414511C51247F9F1C1E66DF31 +:105D60002874C9ADE221E0B6F358E9930E50F93B2F +:105D70003E6ED00092AF11E825633A07B59E73508E +:105D80004FD305A0F686C0FDE7F334DCF76281BF90 +:105D900075BF2BA85FC1BC07CE843E42BF722FF9EE +:105DA0003BFFE6FD0E036F00F37B2FA01042CC9D5E +:105DB000DFEB8BA7E8259C3E73469A05BC09FD25C1 +:105DC00029BE2E8B06F943616C94ECB296D806D5A9 +:105DD000BDAE7FF4157BFC268AD67A8B1065CFC2C8 +:105DE0003566EF10747E068331E81F29BCC1EC1DB7 +:105DF000623FED8F6762BC3E0B1FB42AC934EAEFE5 +:105E0000D68430B7E7E514F919DB84BCE99BCB5D98 +:105E1000F45BA874215C9172D3427BAF2D5F345048 +:105E20004F95616B8F3095B5936A8D64163D62A076 +:105E3000BD7CC23D9F98E2D5A79A86A1F79661F4F2 +:105E40001E9F6224B3F943272BDCAEF505B37FBF59 +:105E500043AC2A51669E8D37A6E673FB3617DA856A +:105E60000B39F950BE43E10BAF201E5A0A2E8D0F9D +:105E7000355FD0BC7997378AE634656838666683C3 +:105E800063A4F9205AB54174D8AF2FC5385DA39EDD +:105E9000248CC27C0FFE7777F9CE2ECC03F15DCF38 +:105EA000E3B292B90BD04FEDE84D92193C2ED27A65 +:105EB000CEE3FA5329D7874CF61FCE233A6F68BD3D +:105EC0005ACA282F51BCFA5053FD1EC0F8BC03BF5C +:105ED000E3C7CB9CD75CB1EAEAECF818993D7C1F8C +:105EE000A317988CF1281591021DF51A95BF5C1F18 +:105EF000A7F2D67A9D9ECDF5A5F4DC824DE7209FD2 +:105F0000A7DA8B18DEDAE38FC63FC7AADC87B28335 +:105F1000F6FD6B17A09EBCB9BFCCCC4006F7660C53 +:105F200078333DE256E58A0568BF6F0E80ED57581D +:105F3000B0C0F494AF6AAAC4B2ED67D8DC7A1DD5BC +:105F4000BF6F3CD8E7204CF553AE7DEF11C547FC41 +:105F50008D7B0B6F6F36617F01D92EC32D0BBC6516 +:105F600030119E80CACBFB940DD43F890036DE4FA2 +:105F7000955BF97893B81F1FCA960E8347EED70733 +:105F800045E7F2B32C8FF25914C340F72BDC976B23 +:105F9000C33DD27EE424DFEF8E66DF2F07F86698DC +:105FA0007DCD8663B8F567E8B0FD1049B070DC5F61 +:105FB000F038E2DF7BDCFB7C1F0D2F4A459F85E735 +:105FC00047E629C9EF21BD47CCCEAE22568ED67604 +:105FD00059C4BE231CF75E45B3E79D24FE77F0EC61 +:105FE000E81DFFE5F3AEA32F66521E5220CCF96FD9 +:105FF000A4F0F6A27E3573A01F78A26ACC50FA5A9C +:1060000041424425AC5F5EE4D704D118EB2FE79AF8 +:10601000799E724EC5584FFD8851ECF9EED3CEF7FC +:106020007CFF4BD7E91719F3F889AD373AE51F67BD +:10603000CE7384FD3AE5EEDE0562295B87976B251A +:10604000D2EF5EAE7DEDBE19584E4814BF3DB5BCD3 +:10605000C9878C7414CCC84CF4872525DB9F6E8EC1 +:10606000477CFE02FFC9C67B09F73D269F0EDBE792 +:106070007F989C188FE79F0E5F3C7B3CAEEB611FC7 +:10608000E76FB03A483EFDDC071E79F0735BFE18FF +:106090006DDB9BD00F7954E065A96DFB028BE28329 +:1060A0005B5B2F637ACB951C85B0B456C86A0F44EE +:1060B000FC0AE1E3432119F1B3799AD57A4B0CF349 +:1060C000DF74207DD50F09D2CBEAC0AA1451DF615D +:1060D000F447716EB9AF309BDEF1737B3FF7C39528 +:1060E000A4EF2FADCDF5A131EFAF99E6433FEA958F +:1060F00035953EB0F565CD059F9810E8FCD4B25AB1 +:10610000FF4EC4EB32D9F4658B6B5D99F07BF6A939 +:10611000690C8708FF51FBDC03405FA13BDE34CDF7 +:10612000CFED9D78C9D0F68203B7535E523BED792F +:10613000C403C3369D4701B5AFF0DA88BBDF9013C7 +:10614000178E60BF2F2FFF2CDF9F195DA05FF1C559 +:10615000E39FF7515C7659BE87FF96564B1EF813A6 +:10616000F3429EF255B557E60CA97F24FD19F2CCF7 +:10617000B2CF618A2487371F13483EE44CE84B6353 +:106180009E26BC2C01D7FF1CFFEB5CF2BF46C7F577 +:10619000E9A82FC06F43DA632EF9D96CD3E560E329 +:1061A0003FE7E77AAD9C5743F1EDF78F0B3ACE57B7 +:1061B000C8AB9B8CF39515B311C76D2E12D318F78E +:1061C000BEBD789B8AEBBDA9E4A3E981BE188FF719 +:1061D000EB96361DD97FB07669939F23C87CBFC6E6 +:1061E000CFE32D2DD652AD049771BF5689F30F140E +:1061F00042D673A68CFED7F8D16F1FB380C7D713D2 +:10620000A45797A82B290F571E3B74BC36136FB2A7 +:106210001D07CCACF7A44D8F25153BA9DFF7CF1B8D +:10622000BA5F072F1F1822F4D8FA04D65781CD87FA +:10623000E17F4B29CFC36D2E7B86F02C9995A4CF9F +:10624000FAB49489F5B694AD24BA6C6175F2D9D0DC +:10625000B9D59D744E73CB9F787CE2C9B6FD4DA82D +:106260003F6CE9BE0930AF32184F03CA8F2D536E11 +:1062700054110F5B7600F4201DCB9DE4940BD9FEE6 +:10628000F0900669664941A8CC04940B791A3F53F3 +:10629000B9375E05B86E5BCAC140D6CC4FA71A307D +:1062A000F4B325CEE3DFC152B3A608E11E23921852 +:1062B000D021D98EE5E65A99E6D1AA717CA0DD7588 +:1062C000C6C9EFC23C98126E7795A07F9FF5AF7C50 +:1062D00089CF5BDF5E427EA22DB92F9BA8EF5A9F2C +:1062E00004631270BD96F40499D111F65FA7655D41 +:1062F000F7AD62F29B7E57FC5ED67401E934133F22 +:10630000EFFBE0729C77F334117666D137F6F879BB +:10631000BC2E6D2CBDA238CB38CFF9754F9E80FEB8 +:106320008142700F567FA09E4C7E7D343C16B17921 +:1063300014D4707F29649C638D4192ECDBD160356D +:10634000203F3AE757C755277E95644F29B28CF214 +:10635000E9063BCFEAE479AEACB00532E857FF86F8 +:10636000CDF7A6033E40BC5D72FA9117305FCA5765 +:10637000E1D728BF0A3A5EC0FCCD1B983A86E59B60 +:106380008E4D5130FFE7E5B112E6C620FF44910E75 +:10639000DF0691F2CFDE8623D1192E3A7FCBDE774E +:1063A00050B2A21C69CAE5F392C3AD3D5214D75D49 +:1063B000B67A9DFC3D5298785E3B84D97B95B28F2E +:1063C0001A48FEB5F37C21273FF2731DDEFCA1CFF6 +:1063D0006FF7966F84A5A3906F6E640A5D9AF57B44 +:1063E000933BEF8B8D7FD4CFF583CF43AA15F79FD7 +:1063F000363B3F66EDF7A62848D737CDD08AF01C4C +:1064000086338F3FF8B91D7A82F1A9EEE2FFD5B14C +:1064100034E52767CEEFEDDD0BBA92ACFC9A2EA7E0 +:10642000B89DED9D679BAF6731E67B5977FB6CBDEF +:10643000C19BE7B87A57A589F9620C7B7ABEB73D54 +:10644000C1FFD976EF7C87C347E6FC1D7D70B0F9AC +:1064500028BB84ACF97E21D59B2FD5A4F278A3D993 +:10646000244360FED9E7A3ADAA149D6FB61AFD5A66 +:10647000538CE29314FFAB638483F1BD7255A77E06 +:10648000DE0F4C48039D4348CD46FDE8AFED778EC7 +:10649000CAF9F06FDDEFFC41E05DABF62AC89FEB77 +:1064A000E58E1AA178E07C40C06799E318BEFD7BB9 +:1064B00096748D034FBDF611D63B8047A04750AF71 +:1064C000461CA2BF93F6BEF5EF4FFCAB82FBF7DB99 +:1064D0008F1F5F8C72EEE61F4AA0B27A279F88401A +:1064E00017ED3B6905E5F2EADD12AD3FC85DB3AEDD +:1064F000F4E4DB37D1FC6F7E2A42FBC3EA67FCE998 +:106500005AD67EF5775F9B0A8C6F4F36F6BD300EFC +:10651000F1F7B8C0F318ACDEA957B2F7AB65B82EE7 +:106520005B1EC2F52AE7ABB7BE1F5A8EFBBBB0ABF2 +:10653000FB5AEAB7F36A9FDF257F97ABDC9E66F5CF +:106540004CFC6E7D43484F12387CD9F2F2DEFA06DD +:10655000F7A3ACDEE34B639EE2EA5D3B9424ABB76A +:106560007ED73B44DF0B9E7A328A7858BFC77B1EAA +:10657000E1E6A7FED43AB79CCE3BF5D5A2FC934EFC +:1065800053F994A9F6F13C78EE8F59471CCBEA7D7C +:10659000FBCD4B7FC3BE9F884B106022E544CF7F6D +:1065A0002A3FC472329C62A28CF5EF7BD5CD87EB7B +:1065B00077BD46E78E349129B017E179888CEF19C1 +:1065C000F5999EABA03C5CDFB9E91D9497EB77BFD2 +:1065D000FD6BA4BBF520BFEAE6E713F88F3167C770 +:1065E000B336A95E3FDD2938388B1C00BBF2B3DA25 +:1065F0008B4E3CCBE1EF9B9F3CF530EA116F3DF3B6 +:106600005F0FE3FD0C6BFEFC3F0F635E2BFC28A0CD +:10661000A1DC5AFFF82FA2E0C2FFA3B67C38F98DA7 +:106620007FFBFA030C0F277FE527AC9D7CEECD099D +:10663000784FC7C9A7FF7714EA1F1B9F5B381AE979 +:106640006CE377168C1EEA1C28D26DDAEF5EDF341D +:10665000BFDF608F809B20C0B3F633635DE0609F37 +:10666000827AEF7B02F46DCE65EF3BFFA4A0FEF2D1 +:1066700082097D88A77DBB5F7BE10E567E9BAD9333 +:106680003FCB3AB1F98F13697F63ECC39EEB765F22 +:1066900079C5C5E5F8F419D8FD7AE8A37DE3ACF532 +:1066A0003DCAD6B77C607D33BF9F82D30AE27FFDAF +:1066B000136C3DA7E2BAB2F59C7AF67ABE8DFF98CC +:1066C00073F67AEE53BDFEB853B0E69107F0E3EEF1 +:1066D000FCACF6ADB39E6BBFF3A921F572473E0C3F +:1066E00087673ADFCBE0FA8A6AFE5C45BE7DE69BAF +:1066F0005F7F20C6D7B99621E6E493A726E0618D97 +:10670000DFF9FAAE453CF43DE7D7508F5AFDDC2F58 +:1067100089EF4E7EE7253AD7C3FEA202DBEF4E4259 +:10672000FFDF1160E575022FACD5FB2EFD35EB7751 +:106730002DEBC23268FD2EFD7539AE9FDA47EB9125 +:106740005E52A3A3FC4D17D0BCD7A5397FAC4B77C5 +:106750002F437F7626DE2301279F70605DD15FBACD +:106760006EF7F14B91FE065B4F67FE1ACE7F36FB4C +:10677000FEA8977F07E5577B7D4FEE785F41FDAA26 +:10678000EB878A26323BFFA4AF4F198BFBCDD39208 +:1067900086E78D33D77D00FF8D59CF1D673E33E9E6 +:1067A000C31FC81EBF76F0341CBF0F3FBF8F86BF0C +:1067B00053F63E9C89C7B74E67DF0FCE09707B6EDC +:1067C0001D74D4A08A99B99FF920658D2B1A80B7C2 +:1067D000B5532239FFD62EEEA7C99417EB06B1CFD9 +:1067E000A639E3ECE99E8A72EDADBDDFB7E992D33D +:1067F000FDBA278E2B96BD3FA45DF85D3F88BFFB99 +:1068000022BBBFF5CF66EF6FFD13EF64EDEF846C35 +:106810005E8DF09FE8F1515ED2894E29AB9D3B29F8 +:10682000E0F3E85DAD9159AFE4B076523448795762 +:106830004D8DE62FD14F6A1DF1D97E00E377986F19 +:10684000D51409D239F7A6E88D745F92D35F730629 +:106850009EE47882EC27399628E731B0B4C78EF1F0 +:10686000318270C30DB255887AFFA1A23765ECF76B +:1068700030EA912EBBFEB00C2DF9E5782E42301A8D +:10688000208B7F23A3FFC43C0974B79FB06B8CF8A7 +:1068900007D6DE7F544A236AEB20D545E7020AA1DA +:1068A000F3B12CFD3D54AF93FD5C94B88EFC3FFEDC +:1068B00054CA447DAD70A3562CEA838F3B3EE58DD0 +:1068C0005F8F6594FF071CE7808FF441D8F5F8E3EC +:1068D0008F8FE25B0AEAE52FE093C9BF4B56E9854B +:1068E000587EC89E37E3013AC738DE4AC828E78495 +:1068F000D81219F58B85A984BCD2B59E0B63C258FA +:10690000DC4FD383DC03F5BD00DF3F1B1AAEA23C96 +:10691000F607BF24125D3F18B8AC10F96C7FEEEC9F +:1069200030FAD7BAD7CE3A3899C1392E2C019A9C71 +:10693000FBC2439FDB7CD8F62FECB4EF1F7AD4CE9A +:106940002FFFBA8DB75DF5A5F47CBCDEA0EF4FD468 +:106950005750B9B3BE869ECFD427E87DF48E60121F +:10696000E97377FD727A3F0EDE1170FDBF5B9FA465 +:10697000F2A3815C827FE29D2026D9FB85888FF07F +:10698000C0BC1D78D2B6DDFDBDC08F9B912FFAF142 +:106990009881EF4BA04750D17F1513745CF7BA80F4 +:1069A000CEF35C33F03BC1DF27605CAEEE4E9E0F52 +:1069B000F1B0E03DEF70BF2DFFBF6DF3E93BD1E4D7 +:1069C0009301D6CFBB35CB4A491F02AD0CE9E66136 +:1069D0002171D828223C7BCE9DACCE4B7E3BE0F291 +:1069E0000F4F68E776FDF6802DDF368288F4363E5D +:1069F000053AD29B33EFBD957A21CAC5BD8240EBE3 +:106A00008DF456EAA2B77EFA0DD879C9F1ECFBF8FD +:106A100000FD72FE8FCF2DBDA71AF1B241243F4871 +:106A2000137E72B5FBD0A62366B78816D2F32A91DF +:106A3000FCB9138F1D172630F874ED9B01BCB72BE2 +:106A40003E016C7F536700E9EBC155DCBFF8B563CD +:106A5000FC1CD3A98DC54B26B3FA8B197E30189533 +:106A6000B7A8C4E3B774CE2F7C4D4DE46843F8B7A4 +:106A700032F3DEEE9F78D707396C9C71C7423A9E9D +:106A800087B967E28FBA15561EDB2B903F696C38C9 +:106A90003519D7B3F2FF7F634CAF6B1D1E589B9A1D +:106AA000887A63EBC46F09C807634FFF58C07D64E1 +:106AB000A2967C33C0D6619C6C9F139653B3D12EA3 +:106AC000B8262FF17B5CB74461FAD3484FA76A36EA +:106AD000FE3BF6EFC421EBEAF4DCC92EF990799E77 +:106AE000E2A1D4D0FE4C67FE0FE1FC87A8E7CCDF23 +:106AF00059BF5335B135281733F199D96FDEA265E7 +:106B0000438EFF907D8F189BBF3FE8A2CFC254AF4A +:106B10008CED9CF683C55D33E7DBEF271A619CB6ED +:106B2000D307F948174FFF71C2B70F03924E424285 +:106B3000FFD4DE40724C7026DE1F97A232938E94F3 +:106B4000CF7E412EE7DF07467D7D0CF19D9C2EA276 +:106B5000BC8F118ED702894425EE73866864DB07EB +:106B6000A60439DDCF8314F947C5D09D43C7F90B7F +:106B7000BD71FEAD409300AB4BB5E31F206BE80F3A +:106B80003B00D3D10F991FE4FC5E2973FB72C60151 +:106B90007D87C4FD56D292880B7FB6DFCEC7BB6619 +:106BA00070DF099A8EE7BEA6750B2E7E7D3F949C02 +:106BB0008FEBA6C4B93FD2174BD279CB855258245C +:106BC0007F6E0797FF759050CFE37119C079EB1076 +:106BD0001771BF7F68233FDFAE6B2182FBA1984E08 +:106BE000E53A5B4FF9B14D47DFB7E5FEF76C7AF94F +:106BF0000ECA7DF62CE935F7E730B8BE6DCBFFA79E +:106C00006DF9FF942DFF671EED856F94933C363030 +:106C1000EFF9CBDBE28D38CD27EB4DAAB7B37E156C +:106C20003DF7E58E16F7B07A8F6E1477223F3FAAB4 +:106C30008DBE1CEFBB4A9BA221B0C60F59DB164488 +:106C400019FC3B5481E2670FD7A7A8DD0E556F549E +:106C5000319EC2AC650BC9A0AE87C21E95BFEBD3F7 +:106C60006A58BDAF75E45D8E71B87B6B646AE7F0FE +:106C7000913E73033687689E3F886C9557D0A59EDA +:106C80008376FA4691FAF94AE033EA02F61C3FFEAF +:106C9000887A998E8B71DC4CB1EF0B1892711E15AE +:106CA000BDBD16964B5E0F53BEF6AC577AE16956E2 +:106CB0002E5A15A1F278CBCB175376F75A1D0C8EAE +:106CC000F16FF1EFD579BFB73A59FD9C0D51EAAF9D +:106CD000EAF55E01E9D957EE3D7FB5DDF7AB7D11F1 +:106CE000367EEC604240BCED15B4059812627D9A88 +:106CF0009FBF197D00AAF07D3CBA88D6615BB08841 +:106D0000E8E76BCD47E237219E36C69AD1CCD9B79A +:106D100071039D4FF06FDCC8F5A014F77F8FBF6D36 +:106D2000BFF079977C286C96B3FAEDB605FD3C4E22 +:106D3000B271596232076F7F18F5BD12EEAF2C6A3F +:106D4000A9F6E43539F1910F85E4B620D94D3C4ED2 +:106D5000226B297A7FB184BA227B7DBBC8F5A4441B +:106D60004FC0ED87D16FE3F7B365C2B13328131C71 +:106D7000CD56F52A941777CF54E400C231D9BE9F7F +:106D8000C58E43F6EF63427267D0E3B7E7708D6755 +:106D9000A80C21DC5D3D9FEE64FD7C9072F63133E2 +:106DA000487AD23D22F1C7D6727E0E709FF16E17DF +:106DB000DE73E1F0538B2112FF6E9385B4C0FAD9D4 +:106DC000565E9C7B1ED24F0C776F9AAF8A782E91BD +:106DD0007D3C8703CCBDE817F7A35F9CAD77C9B1B5 +:106DE000D07191FC7FDEFCEF22CBBBFE629DF7DC15 +:106DF000DD78A6F4B8F39581114D3F9DD1FE5ABDC3 +:106E0000F73F901F968788CEC032A395A3307DD1DF +:106E1000FE936AE9FC7349C63983076CFBFD61FB8D +:106E20001C219CBE05506E3D609FBF7E608D18D4B6 +:106E3000195E9EB78ED0BE39BEAEAB9202339ADFDA +:106E4000935FEDBF536BC4FDB528E5CD13AACCC845 +:106E50000B2AF92BF3AC8F05BD76EADE134103EF65 +:106E6000C34B1F950CD467BF7CC70C927FD66AAE0C +:106E7000B7A457E53D80E75DF20530F0BDD3AF63C1 +:106E8000BFBE1BCC23BE49CF61DF73985C89742ED3 +:106E90005A85EB05395A630CCF43DF0EDFC2FE572C +:106EA000F1F5AF2C04BA5FA7300674CE993D379F39 +:106EB0008BFCBF51C498389C41398F725CED7911BD +:106EC000DFE75E2ED2FD3945CDD67938CFBD73C709 +:106ED0008E45FAD81AE6E75E9A841468086F01E7CF +:106EE000871D912ECA07BDBB468446A428864B0346 +:106EF000FB5919DC49792C08EF4CA23BD2BB304638 +:106F000081FC685D1FE4FBCE69EB3CF42B4743BD7D +:106F10009DFB583FE136C5D8C9FAD951E9BDA76EE6 +:106F20005288EF778190E0C4F70321F634B702E589 +:106F30002DB2B9107F33BEB280F6058DEC2A27BE84 +:106F40001FDDBB482C9AC29FC52EFEDD69CBD9B48C +:106F50009DB7F0B0BD7F38FAC603B6DDB0D5DE37D9 +:106F60008ACC2B1A15A4DB55300DF154B2A6535818 +:106F700099CDBE6FF7CAD54C7E9998C92F29EF39A4 +:106F8000D571AB8A3DDF23C6F99EEF148AC17567C0 +:106F9000FB37E2B92D5026A1DE370312A65BAE0CFB +:106FA000B6FFE707CDA9A18FA0FF44438914EA9F4C +:106FB00099FAF745F6BA5C1B48CCC1F588CE5D4E10 +:106FC000793C6B03898BA87F392DA03C9D87ED62AE +:106FD00059E1A5E4AF11C05BFD51E005D9A0F35C18 +:106FE000B74BCE7DB6DEF35C90717F6DE6FDB4F3FA +:106FF000FF7827DD4FDB2230450FCB39F6FDB47E1D +:107000007E3F6D4B84DB5D2D761ED53A1B0FD785F9 +:10701000F87DAF6B6C3A9D1FCA7EFF91E3F74AA1E2 +:107020006CC07AA3B3DF3B861A15F6377F5CF6EFA8 +:10703000A9108F3BCE9F38F4381B701CD6CFACA064 +:10704000B936E4F2AFCC0899EBDDE55B43767E918F +:107050009C20BDD294F97E581434378666BAF06B02 +:107060003FF31695D379BE53F6793ED66EBB407882 +:1070700095B491E0DDD1FF5B04FD1E9283BF607A81 +:107080005F96F5783F18B5C49C817894A31FED0AEC +:10709000717B92D1DB263E8F34E5418741BF07EFFC +:1070A000811887F770EBE85738F6F0BFA2BCBDB87F +:1070B000A706F5A7B53F90E87EBBB3F0B586D19D96 +:1070C0002B1FC5793FF6837164074F9492F7875C55 +:1070D000F6C7D8557D0AD23BC25FCDE1E7F9D3426E +:1070E000FA3C6E0F00C5715A6E8A7BF20933ED913E +:1070F0003CBCE780E48A427A5D265C8E3DE19433B5 +:10710000CF231CB2E908FFF451784F38706556362A +:1071100025E4AF9990A4E76CD0E9C9EC964E9C07A2 +:10712000E33F1DE16C0C4DB808E7F177C4DB8F42FB +:1071300033FFF1F0E6D07151F2927E3ACE76FFF550 +:10714000FDA128C9DBBA6311D2FBA37BBF48742D14 +:1071500031BA0EC406F265EAC0CEA30F4327EABDDA +:1071600045C97A3A177A8AD131F62B69FC1CAB0CE7 +:107170005A02E336528CF3874F2ED5440DE3B29674 +:107180001FF30EAC623050D6A23FD20D6F7938F9A2 +:10719000A61B8FB71FBB87E4EDB581E4095CCFDB8D +:1071A0004B2C3F6A762E39FC965B0E0B10D691FF66 +:1071B000E69FE6FB65655297911E16304E47BC2F41 +:1071C0008424952F038B9E8B204DCF4FE09546A4B2 +:1071D000C7D9E716BAAE16DDE716FAF3B9CB9D7C30 +:1071E0000E1EA72AB0E9106C3BF5F9E54B1B16B251 +:1071F000F1D9E29B188FFAEA729ECFE39F2DD3F963 +:10720000D582DEEB6B314E04CBB85EE6E441E4D5CB +:107210007AF5B4B3EEB73AF6FB63D82EF39C9CA391 +:10722000AF65EE5BCE33535FCB0B673F3F39D8BEC4 +:10723000931957A8C37F72FBD5B6AB1339EE7BE326 +:10724000339F87EAFB9AF7BBF2CC0FE3FD4659F771 +:10725000011EEF8DEEFD7DEDB272BA5FCEC094C916 +:107260009EFAAEF9AF4F1AB08313F3729F477F7443 +:10727000A23A77BAC4F0BE38FE5EF3FE7C80256683 +:10728000F7FCD75DF3ECD118B459F484FEF14CDF70 +:1072900087EEFDF76D85CB97167BBC881D1F6B13A2 +:1072A0002D3FF1ABED7FFB4321B7D31DFB3EDB7CD4 +:1072B0009B095FBD61A487C1E6FBD930DF4F472D35 +:1072C00037E8BEFC26FBBEFCA6F14EFE96A1A13E11 +:1072D00079633897DF57102EA1F86A53F71CF2270D +:1072E000171CF4913F7DD4B2A460B9F6C57BEBB90D +:1072F000FFF52B4CBFC37C902D4CAFC3F2DECA59B7 +:107300002ADA0BB746A653BC7673BDE1C917719E46 +:10731000781F5DD2E5DF6B4A546918EF6DAE9DAE04 +:10732000A2DD217DB29CCAF279D33BAA183F7F66C9 +:10733000EBD44B0B302E51C6EF23BB8E951B4A98D6 +:107340001D1DE6FBEC21E3F530E2A92AAC3BF4433A +:10735000EBE85B96347D2817E25A15E6CA38EFC190 +:10736000A62FF69EF4EBB795E44D6136FF43F6BDCC +:10737000586D4AAA7443199E8B670207FDC42AF709 +:1073800013221D34CF18807B838DDFB9F6B84C20D3 +:10739000894FBBD64F89F3F56B136155B6F5B933F9 +:1073A000CCF59B66CDD486A4234DFED0737F68793F +:1073B0008CE7E7C7181DB9F8F96C7AE7FC541E4E44 +:1073C00034870B502E42698AE61F26F943EDA481CB +:1073D0007B2CE361B31DEBFD2CD7CE872EE479D057 +:1073E000EC7D6B0E96E514C977471F6C93B93E3759 +:1073F000527D306FD146D207DF65AC45F6D92737CD +:1074000092DCDEE853E9FEBFBDF3648A6745CF81B5 +:10741000EBDC768B14B1EFFF8F70BF3CFE4E427AEF +:1074200032D77BF09C47340474CEA56F3CCF2F6DD0 +:10743000831D35E7107C9334F77E56399EFB19EE99 +:10744000AE0AAE72FB1BE6E4F27C91FDB995BF4734 +:107450003A280BA7AB90352FD0A017F369A08A9FCD +:107460001F130AF9391B1F182AE7D76A0DEF0D15EC +:107470002049E7CF065D3FF0DE2FFAB89C6E0C2264 +:10748000DE62DCAF13D92E50D29ED46976E1D99D4D +:10749000C6DCA53F0813BE1306F277F7AC20D97BF4 +:1074A000EF752B647FBE7713FC06FD49EFF972C0C0 +:1074B000624BF52351FCCD536CBE7D8C597762FE37 +:1074C00097C6BF4FDB2A90BFE9471F06C721BD1BE8 +:1074D0005110F1F72C16337D8227094208E3B3D10E +:1074E00005D07509B6EF0E13FE7CF19FCE7F7D06A9 +:1074F000ED3F21B102CF6B890FE2FC9F89431EB69D +:107500009FF1BF5512FAAF1C7DE81E2D7904E19D55 +:107510000DD6AA6ED6FE6E85F3D7DD794A1AE394AE +:10752000D30B44D243C0174A4F62DF171F78BD1AEE +:10753000F33B17574CC39A383EADF7442D790CE90D +:10754000AF5A5B529DCBEA971FD549FE5E1ABF65C5 +:107550003F96671DE3659F9FEBF1A8C7B8CF072C47 +:10756000FE6002CDEBCD30D7679BE3668F290CC957 +:107570005719F7F27ACF173874C0B6751DF3D2E9F0 +:10758000DF3AD145D2270EF89FA0C2B0CF9F38F482 +:10759000600A1F851E7687F9BED086F966B1817CA8 +:1075A000B3365B7F1B69BE59263FE52D92691DDE10 +:1075B00065FA16DEE771369FDC42F77F66F29303C9 +:1075C000E7E6F2BC18CA61876FB4D977925CF65FC0 +:1075D000AFD07DA60E1F39FC332BA79F8FBE82F242 +:1075E0006259585FC853344C70F3C995C3F0D562E3 +:1075F000E8DB1F63E5C53258394C041D9AF3BB9292 +:10760000092E3EC9C4E7E27902BCEA9183BCECC210 +:10761000B7D67F0F70163B79B0753922F3730F0E12 +:107620009FE2EFB1E0F9B176D100DC8F1A73571AFF +:1076300011364FB936770DF2C3162191427E88CCB0 +:107640007E2B7423C3FB7BA3981689FE437DE553F1 +:10765000C4EFAF84C82EBB7BD66A8A4BBD7753720A +:1076600022EE2F9B18DE5FA5FD3C3D5AA45CDBDEBD +:10767000D13C6F428FF36732CEDF83FD3D6D974D76 +:10768000BB5E2FD563EBEB919B07A29C0F0E44F9D9 +:107690003EB549E950911EFA8A54CD9DAF7C897D53 +:1076A000BFF0CD113BAE78BA49C7F8C4CD11DEEEBC +:1076B000DEFA4ED25736D5EFA1677E6D1A303F2ED7 +:1076C000586AE9A857A87F5E20E03E0BE7F3783BB5 +:1076D000BE6F70E96B9FB2E5B68AF700B179AB8DEA +:1076E00096EEBE77561585ACF703FD24CAFDBF6A3A +:1076F00023D07775EFFFA3BC84FC1243F81C961BC4 +:107700003BE87763025DFC7DACC4146E70F51BAB87 +:10771000EDF4EC8FAAD82B933D54079A85C69DDCD7 +:107720005B8D7EB7F6A5C10ECC57CEA423FC7BD5CE +:10773000450FEA9FAF24BD088E70BDB4BA5825FA34 +:107740006DA95376A05FEF0FB12ACA536FB2F196BD +:10775000391F8CAB334D8FFC64969FC7D7ADC93CA6 +:10776000BE8E658CAFE313E3EBF8C4F83A7EC7F83E +:107770003A96BF556F5219E3EC58C6383B9631BE66 +:107780008E658CABE3734FFD2A7AFEA03E45DF9FEA +:10779000ADAFA3F225B6DC8452FE3B5FED5F544CE7 +:1077A000CC8BFAA1BD3EFBCCA5AB7E8E7E40881A69 +:1077B000B85F070E36BEF213BB4CF75FC78BF3D131 +:1077C0002F093111309ED01ADFC674CC81F905E43F +:1077D0007B41A778BAB50AF31977460E5D2A33FDC7 +:1077E000A1247E4B551E2BEF8A1C6DC5FCD173F571 +:1077F00086E53B5C653D327DF5D3DA407962D90E92 +:1078000039C8BE3F79F7CBAD28070231AEF77D2FDF +:10781000F2AB4B1B1849741533C506E558919246D7 +:107820003ABE01D76912CE83EB2D9F80A638E6EFD2 +:107830004DD495E9C87FAC7E17A7FB91D5FF2106F3 +:1078400061669EDD6EA87A62F988EAD1F9DBC1EA49 +:10785000E17761887E5AA049EB61B06FF1F1FDD507 +:107860002AE0FEDF761FE7FBF6007F4EC8E1F4F763 +:107870004EB4EAAE287BDE15E5EBDB1EE0F70EF436 +:107880004D11E9F778A04EF827ECE70B6341C3BC34 +:10789000C7E9538AF351FF3F62D3C3A48911BE6F76 +:1078A000FFB34AFBF665139F6CCE63E549FF6A1888 +:1078B000B80F6F012388F7B65A5B45CA23FA66F9F9 +:1078C00039794B58F50B667E270FF5DEE9B6DC49B2 +:1078D000DBF64943CB8D13D13E78EF252EF78EDBB7 +:1078E000E3ECF0F5A4683D6786E91C054007E9254F +:1078F0000D7199F2BFC431FCA9F8B46BE85ECC16E7 +:1079000085EE6152FE345B257FEA077EFB1EE21E98 +:10791000D257944052CB65EF3B2C91FC0F4D5A301F +:107920008DF7616D094FA7DF65B0CA648A876D293D +:10793000E3719D50E42ABAEFEA2BDD01AADF12566B +:10794000290F385DB6FB40550C9FA286FB7EDA5CA2 +:107950004AF7535A9AA8513E31FB177D5F13233FD4 +:107960000F9D2BC6EF6B781CC237FA20959B3EA566 +:1079700051FF60E7ED93EA25E2EF4424BABDF7CD6D +:10798000F6FDF442F483ACE6E752A66A4BBB9F6374 +:10799000DF9B4D3551CCF8A1457B776F08CB2B8011 +:1079A000E2A4A129AF3786B0FE0D9AC1F3B0F83931 +:1079B00008B0EF376E2E5BD6FD1FD8FFF2104C32A9 +:1079C000B07EB58AFC0ACDF002DE475568EB33A1E4 +:1079D000DCE902EA632DB574ED2683CF7B7EA03906 +:1079E000EF7215E9465A9C47E3B480A9627DAB5615 +:1079F000A67DB130AC76A1DFA0D0F63B38F2203FB7 +:107A0000E53A47C0FE37768DEC396730FA066FB934 +:107A100020E37EDD0B6DFAC9C45BE63CF363CFE483 +:107A2000223CF96BE844C459F0DF1B9BBE04E735E8 +:107A300046DB2BEC28279346D3F17E714835B8F30B +:107A400030FE5A78A79635F7203D4CD565D0195EA3 +:107A50002E84BE46EC7F8B4DFFED45DEFDF9886D33 +:107A6000D7303EFD7C7426C63344B05CFD63BCC396 +:107A700072C1734E7B9EA73CA963ACA7FEE4EDC523 +:107A80009EEFE7A5CFF77CBF60D7744F794AE75CDC +:107A90004FFD0BF75479CAD3BA2EF7D49F7160A962 +:107AA000A73CB3E71A4FFDD9AFACF47C9FD3BBDA48 +:107AB000F3FDA2DF6DF0942FEEBBC353DFD1EB33A8 +:107AC000F7CDEBA37F993E8FBFFBE33E4F9C692F21 +:107AD0009C756FCE9F9B748CFF4194DF932BE3FECC +:107AE000CECA1BBEC8ED2E75BEA1A3BCB9DAA6CB0B +:107AF000D579E63A94AF955195F60939CCEBC9E1C1 +:107B00004B491F99B09DC9A919648FF57FC7387477 +:107B10007BBD35BFC4E5AF0A681D80F95F95D11AFA +:107B2000BA2FD0692F6B26605EDCD5519DDF73C301 +:107B3000AC59BA074067ED5DF362F61F5D1DD1C712 +:107B4000EC43D4EBFBED3F3987E2BECCFE23FBD008 +:107B500008727B104E4BF4DDF88A40F7F333FB8E4E +:107B6000ECC367C2CC3E9C86F658EF1694437D3F2B +:107B700093298EC8FEC8FE2B67F6DFE65CB71FBCF4 +:107B8000B7089F69D0C6E2B35BE9124717913D7809 +:107B90001FD2F36736BEB40AFB9D52CEEFD56B1FE2 +:107BA000551B473DB9BDA893F8A4AF48E6FB909C90 +:107BB0002875FBF77E6CAF7748FD26D9A16C1D4870 +:107BC0002E3BEBB045E84DE3FD85D61783E4EF9EF1 +:107BD000F05BFF11E437B5581D87F97FC63EC5C479 +:107BE000F1EEB5F15CAC4DABC29F792C892FD98BEE +:107BF000CF7375A68FB06769E93D7BF1F974949FE7 +:107C00005F3DDF78BA0A658C3A9FFBADE5A94ABAB9 +:107C100051407F3383238BDDD1EF9F886EE7F7FDE3 +:107C200094C86F20FDA1D67F864DA1324FA5B871B3 +:107C300000E942A027D153400ED1FE12C043A858FC +:107C4000AE10D218EA42FD15F3412BF3B6131D38DE +:107C50007A2DEABB496E1FFF18F11AABF5AE7F48CB +:107C6000FD16E1A9D93EEFDC9EAB1FAC62E3B6176F +:107C700014E7A1CF16FD294B5CF2679FBDEF3E9242 +:107C8000237AE4CF6CCC519839A017317ED82E9E40 +:107C900083F02628BE1E3828913D1FB8B3837E5F2F +:107CA00035A0593A90FE6FE9D86F75F172F2FFFD79 +:107CB0004F6C3AE9C181BA1F65C55BA0570273C614 +:107CC000E0F88C9EFB00E903302AA8E33E5B170B2B +:107CD0009A3BB2D8079F8D70FFD9A6098E3F3341DA +:107CE000E75D5BD0DF16C6AD4D15314FE7D69F156A +:107CF000EC74DF07716B01F74F0E367E80D999491E +:107D0000177C9B58BF28C75B4E2FA9A1FB54719BC2 +:107D100029C7F3A0653BC84F6FDB4B9FB5F17A7362 +:107D200084E37182020B76A03CC963FA114369A512 +:107D3000ED5771FC2FF11C1ED7372C90B85FCEE7A2 +:107D4000EC5BE219BC8746075D99651FF127159822 +:107D5000EF6BECFFBAF15CE039EDAE7D0E703FF0F9 +:107D600096276FF796CF4B7BCB4C8B7E19F58065B2 +:107D700000DCAFB1CBFB3D0CA60FE328639DFBF30A +:107D800013FC9CA0CA2040FA2EEB4C777F8DCD2FA0 +:107D9000E1DC7399715FFE94DD69D25FAEB07FCF95 +:107DA00023F31EF7B1F8FB1E53695E9E7D74BA4F34 +:107DB000227F03FA890C979F68A2A67BEC2AC7DF73 +:107DC0009329D783C7EE01F685ECF5A41FEF43D5C1 +:107DD000CAD0AFD05A78D76F8F970FF8575AE5D4DB +:107DE0009BC7C97FC9F4AF18F77FA05FFAD69FDDA4 +:107DF000F6DFC75D7ECA77A2C9A9E8CFB87F226F38 +:107E0000EFDC97EA9CE77BB7467E5ED0391C4917CA +:107E10001CB7975A977175253D06FD438E7FC5F1B6 +:107E2000235C9367DE857CB7C53892DAC7FAADFA72 +:107E3000951FB09F85D2C103F528EFC6CB942FA222 +:107E4000CD5EF34810FD99F89D95AB8AF4D1C41F1F +:107E50002FFAC89FD066F3BD732ED5F1C77CC2B68A +:107E6000032ECB71F4282B689FC708A29E7CC12EDD +:107E7000B6869EFD90FB031DBFDF944EEFF7F3F136 +:107E80008837F93D77507E933187E7378D5A9EDEEC +:107E90008BEB7CA1BDCE18B7AA9C35103F1DBD222F +:107EA000BD17F5D0A9769E52D98BCFD34FF9825406 +:107EB00028217D9D8FF949AC9DB15FF69C0719057E +:107EC00002E5F98C3A2A1969D6CFD467BDDFCBC059 +:107ED000552E42F8BCE5CCB81453B7DEB95EC0DF0E +:107EE000454D0928CFB6AE6036022BAFCAB1F38B31 +:107EF000CE8573916E174A6103EFCDDBF00B89F2EB +:107F00008BFDC727FF12E3A3F012CFA7D4CEE1F178 +:107F100056EDA792C12420682198362D3C10C7FA4F +:107F2000EA1903EFD0EFF78F3DCED61DF7A12798C2 +:107F3000DD5FE2433B5EA37227B3FBB1FC0CB3FBF6 +:107F4000F1B99BD9FDF8FEBBCCEEC7F21E66F7E394 +:107F5000F307CCEEC7F7CF32BB1FCBFB732BC91F88 +:107F6000DF83F7194DC6DFB5DD4DF98C6DAA4F43A0 +:107F7000FAC994679595B7AACB187E378717521C14 +:107F8000A56A21CFA76FCD5948F674BF9F2EC3CFE6 +:107F900039E0B7EB151CBF1D1E6D8EDBF66CBFFF05 +:107FA0003369D0BD05C3F7633AFD90FFF4AC7E6C36 +:107FB0003FEADB5FFCF5D79BD8A7B533B7B5078B96 +:107FC000F13C4F8A7FB7F30A337F4F6BEDEE06CA61 +:107FD000F353C61C4DE1BAEE2E0F93BE81BFB7849A +:107FE000723BD34E74ECC34C7DDC7966EE87997995 +:107FF00030115B2F192E2FE36E5F8AE2D656039362 +:108000002FB85FD4A7E7BFEE3BDB6F3B56CBCB3837 +:108010007FCCF3AEFC07783E5E3B2435F7FC9D73C6 +:108020000F64F31573FFA1DB6F1B2C49D3BD0CC18B +:10803000B049FAA2C0F448D22BB524C5015B07F9B8 +:10804000DDEC376D39D130E62ADAEF5B5FF491BEB3 +:10805000556DE7BF358D51A9DC3466569CF2262359 +:10806000B3D4DE2CFD6C88140FB9BF4A6CFFD787E0 +:10807000D8FF253F3FEFD5B4778E8AE7A2DAC32B2E +:108080007BD06E6F8FC7C8FFDF3D6696E7DE712934 +:108090005E41F7544861AE674B7195F46C19E75F28 +:1080A0003650DFA9B72F87EF238CCDC98F190877FA +:1080B000503DBF9C30D1DFE28FF1FC62BFC6E3854B +:1080C000C11211D42CE7309ECDE1E7ACDACB921A85 +:1080D000FA75DAE3329DE768D7A70F166F25BDE87A +:1080E0008F3982877E9B6CBF43D32A85F4C2445D5F +:1080F000AE569D4FE711FA90CFDBC38D2AC65F9530 +:1081000031E543F6AB68BCDFFF03837E3D1F008093 +:10811000000000001F8B080000000000000BCD7D58 +:108120000D6014D5B5F09D9DD99F24BBC924BB9B80 +:10813000ECE68F09241A34E026243168C449083C4F +:10814000F4212E021A5A2A1B1045050968EB6AB55C +:10815000D9908010A4067F2A4F2CDD58B0F6ABD6FC +:1081600068E92BAF455E50E4F9839AAA55B0A8019F +:10817000ACD53EB511A4A5EAFBF8CE397726D9993E +:10818000CC26417DEF7BD832DC99FB73EEB9E7FF5B +:108190009E7BF7D429F87321636D7B52545609CF27 +:1081A000A58E784A1163E1687976C324C6BE951519 +:1081B000FE22C3CF98C3B3488EB919B333A676C392 +:1081C000F394D64E7F7A658131A827CABF98F29E74 +:1081D00077E877FD29A66F661168CF8AA5F7FB5C63 +:1081E0008CD914269CB24199B9E5F7CF66F4E7948F +:1081F000887FF706C29EE4FD785CBF9CF2DEA4A1F6 +:10820000ED9697F5394485B1F5DB3AC30CCA9F0B5F +:1082100050A842B8636A1ECCEB869D2B59A48CB142 +:108220008D52AF4B0638367E292C0C970DED7F31E1 +:10823000CEA70A7B95620827FCB19D3A07FE5698A7 +:10824000E2A8662C0FDF8CC527FF0EA3EC3905FDD5 +:1082500097F740B9548307FE3FE93963B9AAD75865 +:108260003EF780B1CC58C81E9EC0D8EB2DD0E999FE +:108270008CCD39F4E12196CED8DC58E8D9A77C8C96 +:10828000E5AAAE705C666C1E0B3DFB3694F31AD308 +:10829000584F0806B7B1A5B82E30CD378B01BE4672 +:1082A00046B0B2BCA5A98CB906FB9F2F67D23A3560 +:1082B000F635CD641319FBE1AD6D8C413FB17A21E8 +:1082C000BE1DE09FDDB06DF638783E50692B781802 +:1082D0001B45ECEFE1FC5CD0D929986FA66DE598C1 +:1082E000B1503F3C354D68837A3F3CEFACF5C5500B +:1082F000EE9D5E1242BC03BEDE1B980FE07F5E98CF +:10830000B7D7C77FA5F2D8DC71F0DC52F9E46C7CFA +:10831000CE49AC0FFDCDAAE96A75407F972E532A4E +:10832000B0BF7083B17D5EADB10C90F3F9C0BFBC3E +:108330005943E11D091EF3F87A7F0FB428847FF6B4 +:1083400025D003E0338C9FA07D58EA974280E7DC7C +:108350005A418D03DDE4A982DA65C10F1D1A3F98E9 +:10836000F12FC63218F259FD3C31DE0155725D76AF +:10837000C27FEE4C21AEC0F8B94BFB7B4E41F97287 +:10838000973D2EC2F7ACCC6E01BF3FB08CB1CE2270 +:10839000022FBD2E617D1F70ADB117C2F7794191DB +:1083A000D9800E58ED381A8FE0184BF838C2F1E139 +:1083B000227CE42D0B3DFB6318FF8A1AA72C42FD9B +:1083C0002B1AF9771DBE8D12D0197CDF0874162385 +:1083D0003A938E24E267CEA1E5CB911EE798DE1793 +:1083E000435D9CEFC7930F9C5108702D173A67A40B +:1083F000012829F666C670A1018348D73A3FEA787A +:108400005ABEA395F83181CFECA7909FF1DFD984B4 +:108410001AE2B3A75DBF92516EECCEECDBC2808452 +:10842000B7CA2CD690CFD8BFA7F69F2D4079BB7C7A +:10843000F9BA7517C0F794FE5FB072C69CCE6FCFC5 +:108440009891504E4DBD86CA3E6D1C98428CAFF738 +:10845000C0B8441FFF2973F836A86C930865C92675 +:108460006F0A150DB6CBC276C230EDC26C9364D1E3 +:10847000CEADB7033CAD85F54BD5E695AA7DB76982 +:10848000F0248E2F21DE64C52DC07A48D32519E94A +:10849000E5EBC2913DD2BC236C937DDCD0760076B7 +:1084A000AB0EBFCD1AFE387E4F1CDF3E0CFCDF3416 +:1084B0003E46EACFA17D3F6DF8A0FAEAECE4F34531 +:1084C000B8ECA8AF14C56D4BE8E7AE3DFF78F11CE2 +:1084D000205E693E0BA5401F925D954340E765F223 +:1084E000BD2EEC5CCA6C9023C00FEBA1ACC2FBF5B7 +:1084F000DD9D2E05DE9715DFBD0E89BEAC2795A14B +:108500003C98C0E4CC47A1DF09B2C47A70D52ED81C +:108510006B4B8332BB84854AA0DF8C3DA9244F324C +:108520008BCEFBA900E36666BA546C9F9659FD5347 +:1085300046F4C11429011F6975AFD7A7215CB3594F +:1085400008595112E2AC0E996C3CF0109433A76DAF +:10855000630D50AEF8D8A388C8D312D7771DD81EA4 +:10856000F5743BDB87FA25A8C99F750E7913E98F4F +:10857000EB2486FA236DC2BD02C2F3007425025FAC +:10858000969565CD6E8072D97E5B4851703E9D4256 +:1085900021CE272092DED2F1A9CB918A4F7B38D30E +:1085A0008F67F1ED007FBB3DDE83F22A36F90A7951 +:1085B0003BC0937B5582BCC6BFFA010708EF4B97BF +:1085C0006DEF2842FA96DE4BEC2FE3D3780FCA33D7 +:1085D00056D718C6F6BE999241FEA76AF22CD5A4CA +:1085E000075AB2EC24CF747DC054499161DE8236C3 +:1085F0006FF68330E903270BB91C64AF2C203B4492 +:10860000607DC2A934983F5644B80BF83C86B4AF9D +:10861000E6ED5920E4423BC799DADC8CF5E163567C +:108620002B2057B82E5545FD2C38982B5801F3B602 +:10863000B14837D049ABC0242C0F8ED7C3703CA7AC +:108640002BAD1DEDAEA75D6D36C45FDB73A03F6043 +:108650001E77D85923DA056D72C89505EDA39AFDEA +:10866000B6AA7C6C0E963380B67BD16E90C232D2A5 +:10867000E52A7F710E83F7E9DEBE6FA39CFDA7CCD0 +:108680005FCF7015801CAD873AE781DCDFF4F8BA64 +:10869000582D8C77328F2909769E536A66684F3938 +:1086A0004F161ADEF7B4C08CCE1C2CAB6E5B038E5B +:1086B000735DA64278AD63723BB6AB03642809EBE9 +:1086C000E23C1964CA24ABFEF30DEF7BC04E529C12 +:1086D000A3E93F8D29A589FD8F4BD2FF19A6FE6521 +:1086E000CBFE07FBF51AFA5D2331B2A3633E37AD2B +:1086F000BBD92E589D59BF2213ED51276BEEB6B052 +:108700003B5B336D04F71D81E65E15DAD733607C81 +:10871000A0930BBF3C2232B26760A5805E58BED4E6 +:108720003F40C763B11EA75F5B4C6028972E94EC57 +:10873000063E99C28C65B35D54026B8DE3DA3C95BD +:10874000BD483FABFCA98AD3027EFDD9DBC2A6148B +:1087500097C07C53C34B19F0F10399FB5C6B02503B +:108760004EE774F248E61F67A0BFD02B70FA5BE3B8 +:10877000B3115EC2F5395D6242BF61072B41B91882 +:1087800046FA76737870FC5E7FFE431D16E383D84D +:1087900035D80FB355614A71C2BC7A353B7860BC9D +:1087A000A9795DC80703E33959158D2702FE13C760 +:1087B000CBFE6AE3FD1EE7573638DEECE9C6F9CD9D +:1087C00076C834BFD91AFFEAE3FD1EE757F415C691 +:1087D000C3F9258EF74FC6F9CD76CA34BFD922A783 +:1087E000AF81F1B2BFDA78BD2DA56407DFE100F9F2 +:1087F0000474925ABEC3350EC6BDC365970565B0F5 +:108800005D5DDD8DAEB9A87BDD53A7FB619CFA6988 +:108810005039177B993ABDAE98B14D02A78BFFDC5A +:10882000F4E7754817C767AE2A257DA2D9D79762A6 +:1088300055D0C7974A1CDE59F9EE786B021E1F000F +:1088400039A2021C0F02BFABC08F5B812FB11C6F1E +:1088500009D0F321B0D7F1B90DE0C5EF0FB784A867 +:10886000FC484B0D3DF57E4A6BB8DD3EBED6DA6E58 +:108870003F238BFB7D9B82F2FCAB50AFD5A586508E +:108880002FB29AF3999A6857B3E6A753E0FBC6CB89 +:108890005939EAC6333673B87D0DD964B7A796EF58 +:1088A000ED6D81F21D925D41BD7C87C26658F9CDA8 +:1088B00045A867AAD05EE5EDD9F9DC0FF385FBF694 +:1088C000A2DE9B83763AE0D53FB76F2FFA7F978180 +:1088D0005D4E7A991DDEFB367C7F1DFCBF0E2C8B16 +:1088E0006E264379D61C3F8D0F7FD2EBB2D17EE747 +:1088F0007FEE99798CFC8A700AD70B3E36FBD93D06 +:10890000086FC8A1C4A93F765F18F940B52B1D2494 +:108910000AC276D4D37ED4D3F0BDEEB093D910BEC4 +:10892000690E926B73E71AFD864D293D32DA3F9B43 +:10893000CA7DAC15FABF6CA6F1BBD3C9F92D6CF298 +:108940001B6699CA2021B9DF2D2EC8407BFF0E7C03 +:10895000357928DEA2875AEFD89B40A779591E1F88 +:10896000C501CE6067A03C3BC1CAEE6AC08FF95911 +:1089700064AC98DBFFBD2576C75E40FD2B28F7AAC7 +:1089800090BEB9DC18CA1F1C9EC95ABD075A7AA7E7 +:10899000BC5732085FAE1417500FE42D85F709F36A +:1089A000957C7101FD1D263E5A8EFE8D791E0F08A5 +:1089B0008F0699C578FA339749EF235E7029519E47 +:1089C0009BE73B79C87C6B5F296656FCA46C427BB5 +:1089D0006ED67362A85519C4873EFFFF69BE3AAAD6 +:1089E000E919A6FA580FD0CB2B40EF1DDC8F616838 +:1089F000A7EAF40A15C87EBAF452F88E74A1AA0543 +:108A000088CF57C6F66FBB1ADB81EC68437F57B738 +:108A1000837A0EDAD00EFAAAFD5E7A9D83EC2DC61B +:108A20001AE4F74B07FB4BB63ED8EFFB09FA73C0CD +:108A30004EC43FD59AE843185B4301B2076E01FB71 +:108A400018FDFD68C387523AFF7E24C14EC53F47DB +:108A500012FA6BDBF3734101B8BA5ABAA7BC674F7D +:108A600090174B65DB1AB4E75AE302C5217AA01EC2 +:108A7000D80363972AB676C0FF55D80FD2A749AE60 +:108A80008F6D877E12ED94DAB9F2A3400FED65F594 +:108A90009D2178AEDFCCE3657AFD81B8992F46FE43 +:108AA000B99D353301E074A4FCE0277D301FB54D3E +:108AB000622953A06CE7F60E7BDB4372417437FFEB +:108AC0000CBF076220B770DEF5CD8F63396663E1B6 +:108AD0003678DE9FC6DB472597EC0C619CA47D06AB +:108AE0004E3F3318B92F0BF0B7263B95E4A0E31D9A +:108AF000CF4328A71C99154BD1EE5910FD7E18E3E2 +:108B000091B2972D0C5BD0D702CD7E8867F1B8CBA0 +:108B1000217B4F4126C05D17AC8F63BF43EA477F7F +:108B200040FD4D11ADEDB09D5A3F5B6CD672E10931 +:108B3000EDFB15CB9FFCF061984F5AB13B84E4B636 +:108B4000FE1CB643B00DADBFCB1FE94E8423A55824 +:108B500096280ECABA27A33DB7FE8B07BB1F079402 +:108B6000677DE126399B257AE24291A1FDCEACAA30 +:108B7000A1ED77FFE38D00AECFEE1446FA95B11765 +:108B80002F427F72E34099C5048C73666AE5D8234F +:108B900017A986F2E28BEAB08CB40B4439F99EEF48 +:108BA000AE8F617B819759EC7BBCBE9DD7CFD1BE88 +:108BB0004FB9F8A39FDE85FAA0DA417EE846CD0ED4 +:108BC000D2E13BDF2B12FD9CEF1D1E8F0735B9E074 +:108BD0001A3D1E0F5AE17177507D0BDFA7B06E0171 +:108BE000E938E50BD74DD8FE5F5A58F82A807D8BBF +:108BF000B2E3E77729D4FEB0151ECF0AAA47B0BD6D +:108C00006BF9919FDE0570787438CE65372581E366 +:108C10002FC3ADE78E6C2EE7E6F9B8DEC8D2EC4D77 +:108C200087A337301B9E72E58F6E9441DEAC2DEA30 +:108C30006EB48A3F9FF0DAA85D6692787B8697E3F0 +:108C40006D574EF87384A35D7ED285E3A70A2C8C02 +:108C5000F537D4F43121A1DFB37D7C1D006E9B1765 +:108C6000DAA54E662AD2998779E20CE8CC53C9E19D +:108C7000DF10789D29D0CE530A4F37BEEF23FE4731 +:108C800097830B351074507668F491714FC745483F +:108C90000F59A24E6F791D482F0E9B5E3FEF622C3D +:108CA0007765F172B92FAF23960F7AC6016D502EFA +:108CB000E43AC8DE31CF2F4783B7C3AFFABD7E0B8E +:108CC0007C3AFB689D364E708462B0AE536CBD8DAD +:108CD0008BF1DBC56EB2D7E07D633C61FED3353AE4 +:108CE0009CEEE5F6D6C67FB81AE316EB918C4E27BC +:108CF0007A4F9B4E277AADE9F41CC47F029D7EC655 +:108D0000ACE9B4DAAA3DD0E9B956F8309745A66E79 +:108D10006E0200A5CFA73F72176AAB7FAEDDFC38AD +:108D20003CA77CE196BC50473C83919D687371F9E8 +:108D30003E28F723D3B07F496EA6F7A23B4CFB3504 +:108D40002F65F1FE87F47B6EF566945BA3E8378CA4 +:108D5000F336F73BC6CBE19D72B13B12B7C0FB497E +:108D6000AFC4FD521F1F3F19BF94FAB8DF9C945F38 +:108D700074FACF0947108E91F8E5C2417E593A3A0C +:108D80007ED941FC9256C6F9252D09BFB09893F8BB +:108D9000636D112FDF728F8FF861807F622546FE31 +:108DA000899518F867DABD2554DFDC3E1DE76D8133 +:108DB0009798579F47B805E7A19E2DB78B646FF42E +:108DC0003194535DAC7F8F13F9B056086D87B7B3FC +:108DD00062BD0D2E05BFF7B2D9607FACD3E87E2B04 +:108DE000C283FE50B516CF927AD9659EA17CECA9BC +:108DF000EC298D24E0BF40C3E3E5BEF05D387E176B +:108E0000EB1B8F7669B275BA5783F7A6807AAF15D8 +:108E10009D8FA47776A2DEF1E393C39DF585AB1910 +:108E2000E58099CFA7DCF0DB0F1F1EA69F5F6B705C +:108E30003CA63D4F83EF1FF35AE9E9A0FA4B13DF3D +:108E4000570A632DF9FED756ED81EFFFD50A1F5F54 +:108E500083CF9FB6E2F307BDBCFF91F02CF9389E9B +:108E600025DFD7C3F3116D9DDE3A7D3CBF9504CF5E +:108E70007FF4FA4785E72349E4EB512FC1618BE189 +:108E8000BE00F23BFAEFEBCE8DF5E37EA8051CFFAA +:108E900099D88F4BE1FD8069FF9900743EE5F37529 +:108EA000A188055F42BB6389F0EBEDEEF5CA9A1F1E +:108EB000A1AC44BB7ACB3FBB693F01F4E0DFBCDF30 +:108EC000AC9CB7F92CE4F1141B974397DF73783D02 +:108ED000C669BE46FFE956FD3FAFD1D748FABF2865 +:108EE00041FF633F6679D7C5783CA5C31FC9F71119 +:108EF000BEFA2E42F9B4F5D62C01FDBA7CB5474036 +:108F0000FBDFAFE9978D5EEECFE8EDB64A3D828498 +:108F1000F59B65212618FA3B63B8FECC70007CE314 +:108F200011BECB7DEA59F8BCD73B60EF9D963D540E +:108F30001D502BB03DC8E94A1C5F3DD328A7F579E9 +:108F4000D8C2DDAC0FF50BB8DF710BBAF26BFA12B9 +:108F5000FAB980FAD1E47D954FA72BDEDFE9EA1B51 +:108F6000806FBA06DF0C7C9AE133E36524386F46E4 +:108F700038797F9725C299AC3FDDBFD6D789F46990 +:108F8000425C67E1A0BEBE12FB73ADB1C5986F90A5 +:108F90007F757D0D922915FBDFE2E071D42DCBEEBC +:108FA000AEC37C83AEDBE4724449EE52AEE7946517 +:108FB000851457BD56EBD70CFF407B47F7F8496542 +:108FC00034EE721CF7C25AD683722303ED048A3F33 +:108FD000C812C617B29C9D018CCBAE173A1B17A1C5 +:108FE0001EBDC84DFA9605E65AC6A7F4A71E7FD245 +:108FF000E7CD029523D46FA5FA725A6733DA49A3F5 +:10900000AEEFECB4B4AB7EA8D95530BFF5C3E235B2 +:10901000E0A3F8968EDFA1E3F0F5AB0B370B88EFFA +:10902000D4321812583235DC499BADB6E238EB43E6 +:10903000FBA914E885FA7BDD32EE37D8DF5A1DAE86 +:1090400007911EBF2E5C7ABDE4E3F17AB87F46F14A +:109050000E37975BF401CAC79EF35AEE1FE8CF3B69 +:109060005A645502FD734C5632305E7887A6071954 +:109070000B052EF3FCF7D71B9C479CC73B4DF5A374 +:109080008CD33D0BB8C8BEC3307C22DDBCE6E3FE0A +:10909000684776F8392E1F4321A46B28BF80F867F4 +:1090A0002E287BA8BC9FCAF240F965AA1FE0F5995B +:1090B0002C8F0ACFD0EE0FD44E1AE8E74DEAD73DF9 +:1090C00030EE41FAEE1B28FF91BEE7F3FAA31D270D +:1090D000615DF9FC7B459AFF67929A81FBA39747F4 +:1090E00017539C687EF45A7AAE6B91EB301EF77280 +:1090F0004B7F7B3B3C2F9FBF5846BB7FFE927B68DC +:10910000FF5EEFFF52F42B90DF156906D94545B697 +:10911000F036F720BF0DC2D1AEE599F535201DB967 +:1091200054D6DF510EED6B3E6D6F37E4397552FE4C +:109130004C8A227D9E1857D7E5E0C70EF573DFE90C +:10914000D1B169BE8CED85F13F7317C76344D7F584 +:10915000B215BFE8F34ED6BF3EEF647246C79FFE1E +:109160007E7D7185CCF37FE206BCA4943450BECFE3 +:10917000A58206A7C7A5F11BAF370BC679B28CE84D +:109180004341FA9DA5F97166BDA08FFBB12352E45E +:10919000F7E37E0363B75558E07794783BD0B23459 +:1091A000DC604779DC9D42FBF74CA638BF5EAF31EF +:1091B000C9FC2FF0733DC29C2ACD67C3ED1971B471 +:1091C0003B3634FD5AC6E04ADA84CFAA62F814FA74 +:1091D0004F2C42F972BB87F2311A9B4E54B526F4DC +:1091E000BFF0997F7361BCB771C26A3FC65D16322A +:1091F000E9B3C47C07F3B88DD11B886E63AD42A37D +:1092000095BFF56636E7EB85982223527F4712F724 +:10921000919B940A07C6279A62C6FD1CD0900EA4A3 +:109220008FC5EBCCEF13F67344EC9FD1BC63B899B8 +:10923000877A6F8D8DE86D0BE00DFDC0425097F879 +:109240007C333B4BE3C75EC2E77F373C6F66CB7C2A +:10925000DFCDC562695983749313E964A89F3C9577 +:1092600002ED6FFA3C7A7E4437E9A97BDD7A19F486 +:1092700016E03F5CA6D939C5FCBB0DCBE8FFA4F5D1 +:10928000EEB5011FAFB9EFE98B03E3A1BFB248C050 +:109290002653F905C98FF6172FB3D8D32FEC257BAA +:1092A000563E4B0801FFB7EF7EE1B902F2E7357B8E +:1092B0006CF70B648FE965C67A18CCA72B75A0AC48 +:1092C000BA02501E3B508E6179AB66C7AFB96FF7DB +:1092D0000BED649F8463FE043D59C7787CF99BD6EF +:1092E0008F5D81AB3A319F28566C237F2FD5C48F79 +:1092F0008FFA1D54AF28277237C233EBB67E09E3CD +:109300000D8EE0EB3E9403638A8FA96381FEC7D480 +:10931000F2341956CAC7ED2A5E45764397B62EF049 +:10932000BFD5A8F706D7A7D7B43E7C3DC295BDB43C +:109330003E9EB25E5A2F1B9629EEC7F7E32FA9E493 +:10934000F686ECE4FB0ADBFD9C1F76F8B97FBBC315 +:10935000CFFDD38CE2BB29BE9332C346F533B4A70D +:10936000598EEFF04B9A3CE7F8D81D8C74FB13EC48 +:1093700056781F2EAD44F9E6CBC27DD6BA62E926F7 +:10938000A4E79F68FE29ACD35DB44E45BED4085F08 +:10939000B7DFF8FD16EB563ABA757BA32542F22AE1 +:1093A000D9BA5D3E5F0C5BC5DD5ED0F0F049E39F4E +:1093B0007E84D359EEEA77E03ECCFAE24D86BC6A71 +:1093C000D78ED93D980BADE755AF4E4BAF45B96D34 +:1093D0001EF78D2FFFC387F89DF90FA7A57CFC54BE +:1093E000938FAFB734523B586045CA2639C078DEF8 +:1093F000CB409E9870CA49D37B03F3D0AE24D66786 +:109400006C6EF830ED572F0A880CF7C71732635E81 +:10941000198BEA79C13C0FF60D095C5340E11B3111 +:10942000210498624DD26C5DAE18F2C3E6CD9DBDAD +:109430000FF7E1176BFBF0205F0CDF9798F2C6AED9 +:10944000686C0A3768DF8FD3DF71C2D35C85DB8D30 +:1094500073DD6ED2AFF3C2F3C30D09FB716FFE97DC +:109460006899877E41B68E9770B8A164285E16858C +:109470000587AC8C8C1F333EEA248EAF260D5F66C9 +:10948000FC98F1B078EE6C5A7FF3FCDF7085093FF1 +:109490006F007E305FD88C0FC6229720DDBE395F0B +:1094A00064681F4F1767DA314F60F16C81617ED1BC +:1094B00012164AE7F9C1EAAC6909F09AF168C6D711 +:1094C000E2A758A807FA5D7C9F87D6EF550D3F624B +:1094D000CF5F695E619857079FD7119EBF2AD3BCA3 +:1094E0002E53CB9FF5C1F7483B485BC54A8FF0F937 +:1094F0002C82F974C843F5C90956DB8C74B2C49444 +:10950000B76086CF0CFF4C94839387EEE357646B70 +:10951000FBF8135948DBC7CFA0630D21FFB0790BCF +:10952000837CCEE96B6174F6C078D8AFC022036546 +:1095300019F03BF379EFC679F0EF550151C13CC109 +:10954000D9F3C7ADC1F9875938A3A708EDFD7E3B14 +:10955000CA91CB1898B1D0EE429824EADB70430A46 +:1095600095F57E8F757E6A273D1E61CDDB69FF5DB7 +:10957000C9983B21B97C591570D078663B656679EE +:109580004906CA0B333E743CCD43BCA4115E269EF3 +:109590000E5E5E445D85FE2CC6D1601DFBAF65ECA2 +:1095A000A1F2C1FD6396AF727B329BD1FEFFB5D9AC +:1095B000999ADDD14C7187059A5E3864678D4FB8F2 +:1095C000F93E7245827CFC56B0EEDAEC043B55DF86 +:1095D0004776B33EC2DF952E778F3891E8EEA30130 +:1095E000FA20F9A5E76B46285F53CC58A6505C2CAF +:1095F0002D7D22CB00BB98F179831F7353B61FDFFB +:1096000017C6D10898F9FC4FD7CD5306D76DFD5535 +:10961000DB3B511EA72CF9558C3A57783E479AB63A +:109620006E75DABA0DD8D1A5F03E01BFC73A353B09 +:10963000AC548BE3E31F281F2B56E3C3F9AFFA3A70 +:10964000A69482FF61C823EC247CEBEB094E443FD7 +:10965000F265242051CEB08DB9C83F8EDCC2F33103 +:109660001632652BE6072D8CDA8F25F613094A048E +:1096700047647D8A163709513F8B82BC1F56CAFD4D +:10968000BC01BA8F41FB84FC479B0B4C496C9FC9C2 +:1096900042E83F417FD9A8EFD9BA8471C60E1D3781 +:1096A000597FE676A2B67F2B3A43A150829CDEAE6C +:1096B000D9CFC70295DDB6B1C9F1B7C8E555A584C4 +:1096C000BCD8234157A3555C4CEF4FD7DF0376221C +:1096D000BBE6C5443BD1ED687AF1B90B12EC44D638 +:1096E000F422EEFB7F553BF1E5ECA617DB617E7FB4 +:1096F0007FFB9F287FFC5833084CC0A3373A951D49 +:10970000F5A27C90497F1536824785C9DF92321ECB +:10971000E93D259AA74A09F9B26F662B04BFB758ED +:10972000A5FD3268DA8DAEB8570A0988B7BBB5B85F +:109730001910EEF8D99EC4767CDEFA784E974C70FC +:1097400038F4F158A895F2EB6732D2237A1E88CE0E +:10975000D77A3F47B38DF1BA51F0F3D16CFF507E09 +:1097600016C5E6776F4739F1A2487ED87702B7D0A1 +:109770007B733CE0E36C6E1F8E11231FA35CE86DCE +:109780007CED3B3743BB153B9C2154C3CBBFF7E17A +:109790000FAB14C4135FFFF94B16DF5785F32A9103 +:1097A00064DADF28E0711847AB40FE6B4A9123BCB6 +:1097B000039E877D75B93909701DF6355079EC0C1B +:1097C0000ED731E8B343C1769B1AC95FF4F07DEF41 +:1097D000638A92C148AE30B22744277FBA73785C5F +:1097E000D89DC3E379520EC7B7EBA4408B8474DDD8 +:1097F0008CFB16528CF2A05D27257AEF10044B7B70 +:109800004DEFCF75128433E22BCDDCDE41EF713E9C +:10981000D85EF432837DE3CFE176B27F008E340EE2 +:1098200087D7DC4F3A7FAFF19F198E15D9538388C4 +:1098300097C33E353787C751B81C76BF70409838FC +:109840001A79CCF3F52F094A2E8AEBDD2EC44B4052 +:109850003E75941E5B4372ABC8D58CE7A412EC270F +:10986000819FBBE1E72A06EDD3FE69732A317ACDE9 +:1098700094074243EDAD772B4FCC9B8305EDFCC4A1 +:1098800095BAEC8D4119ECB977B4629332762D8696 +:10989000FA2FADE5F6D962B4CF4224B70C7697D94A +:1098A0003E7383BE9F0374B12420C94817663BAD45 +:1098B000A3721ED9351D60D760BEF6503B8DCB9B81 +:1098C0003BA336A642BD976B45F2335E2EED7BFE81 +:1098D00042D417357685F44569FF9D73E8FB241A59 +:1098E000C7ADF977509F9F7708A5C54BE0DD2BB535 +:1098F00047DD8B13D6FBE59AA3E3D12FD89A24BF7B +:10990000428FD3ECBD95E77FBD7BAF107722DE6E33 +:10991000136DD8EFC2720FE5AD4E13DD34CEE28D7C +:1099200062DC493854D3A7650FDA8D4CACCD7E0D7F +:10993000F170979DE1F9C1829BFA0C76EEC2A8D135 +:109940009E8B3483FDA39CBE1D68B6FFCC76CCF203 +:109950001CCD7EA9601568BFBCDCB2931D2D19B467 +:10996000636625D9FFD6ED98F36CF5DFD5E899F657 +:109970000F6649D6FBFB9768FE290B717F709AF83A +:1099800011ADD7B190A420FEDCB7BC40E73ADCFFB4 +:109990002586ADC6BB33C7A1EFC791BCDD5A914642 +:1099A00079D77B6E3D2BA78FD64BB9BF16D7FF0556 +:1099B0003BC9C164FA2D252AB2629898272AD05350 +:1099C0005FCF31D11496A81FC624C953F8710E9FDA +:1099D00087FF3666433F3B33C6542BBF54AF07FE69 +:1099E000E8748C5143FD9E4C80EF86621BC5FD756B +:1099F000BF34C5CECFFBDA77AD8CA17F3A06E0430A +:109A00003814800FE57051348DCA63A35E7A8E8B53 +:109A100066D2B3389A47DF4BA2E3E87946B488DED2 +:109A20009F193D9BCAA5D149F41C1F2DA7E759D109 +:109A3000F3E97936E82DAC5716ADA3E784E83FD3B8 +:109A4000FB89D139F43C273A9B9EA1E8B7E97B79A1 +:109A500074313D2BA24DF47E52F47A2A57466FA4FE +:109A6000725574253DABA3DFA7E7B9D1367AD6444A +:109A70005BA9DEE4E8062A9F17BD879EE74737D13A +:109A8000B336BA85BEEBFC9CA6D9D32F05B6C994D4 +:109A90006FCF7ACA503E26E3C3439A3CAECF51F70C +:109AA00022FDE9F5F66BE70ECCF50EE40C9F77F39B +:109AB0009AB65E9F848EFC088FD3EAEBB63E307C6C +:109AC0001C8195F946D8B7E2F37B2647E1F42B7564 +:109AD00092BDB1B599513E98A7B2574079D3159030 +:109AE0006658D1913BC0F3C08A722247517FB88338 +:109AF000EFEDC5FDA84B63BDBEA9482F215FEA5419 +:109B0000E86F4CBB8DDC6B85C90296950626F7B0D5 +:109B1000C1780ED85706BD260574FBAD77E62484C0 +:109B2000E7ACE20AB25FB5FDE4FDB78E65E8776C9D +:109B300075F40812CACB558C25DAE15BD72E7A383A +:109B4000F19C8614E0FC39661D7B1AE364459D4A4E +:109B50003D9E271CB7597D1A533C4BE291FA54287D +:109B60009FF948EC697C8EEF8ED7A7C1F3EC9D3D41 +:109B70004FA3F899D0D357EF86F239CFB16730FCB5 +:109B800054DEAB4CF54079D201F519DC26A9EA8BFD +:109B90004C4D57109E785B3AC0B3F51D30B4A05CB5 +:109BA000F351A7086EC9E0FA83DDF644C2BAA414E3 +:109BB000F7AA22FC33FF26B91CE5EC56A92F25B3E2 +:109BC0006CE8FA74E1BC719EA057B66BFBE872C2F8 +:109BD0007A8402821E0FF40512E2815DEDAF523CE1 +:109BE000B02B55AEC35057FF34263FA4201D733F02 +:109BF0002175CD58D24F3ADD017E0DF6A414E074E4 +:109C0000B775C0DEB4C66F08F15BF5BF07BFFF9E36 +:109C1000A3C9AF24F87D09E7111C998FEB029C2F93 +:109C2000818F2F085425AF77B5867F339EB74AF2D0 +:109C300059842F37B3C5CA07D7AD49A3EF91F0FABE +:109C4000EDFF65745B13181EAFACD2CBE3CC5A7E2C +:109C50005A3279B33FC93991E6C01039C7E3A5320A +:109C6000C8B971C9E55C6D6004F99524DFE1F6803F +:109C70009EEF10FE7E601471FD3B6D721DE6BBC44D +:109C80002632F213C0BE6CC7FC9D3131A582B6B13D +:109C90005028231E2BCE263FBD08EC0DA98261AAB9 +:109CA000630F3E2FA9CCB42D2AC3BC068DDFE4A6DA +:109CB0004022BFE9FA7E901F75BAC8EAA273164027 +:109CC000AF984FB84BC3D3603F3C1EB1F696DCAEA5 +:109CD0008E0439D815CAA3B25E3F19FDBEA57D0713 +:109CE0007941FBFD97D45AE79BFC6B40D4EC9C7EFA +:109CF00015E93C3685C974DEB9FD08C9A74C904FFB +:109D000042110F0FE1F8F9D1D487314EFBEB40B689 +:109D100026CFE5D4CB3DFFFFE8B9037C75E2A75A17 +:109D2000790F9EAB18037A484139590BB057A29E60 +:109D300073D0BA2B8CAFA352CBE23D02E1AD07FD4D +:109D4000E6988D9FCFD8EFE85649EF383265CC3F83 +:109D5000D9E58FEC0DF893F3859CA694E3A2FE6100 +:109D6000F37533DD41CCCB9153B1FC2A94EFACC1F8 +:109D70003CA13EA695EF744FFEEAF1873F04AEDDAD +:109D80008FFB54D501F535A467A0EB3F205CEA9921 +:109D9000B244F1E151EE3FE9FC39C84F72B9CE4F00 +:109DA0004D65240FDFC5FEF5FE92D937FFA2C9CF5E +:109DB000FEC0F0F68D4EF7A76DDF68F0BE3302FFF0 +:109DC000CF7CFEB5CDDBD860FCCF93FB46AFA4A023 +:109DD000BD3D951D9D8471AF5E4EF78CC7F9548CC7 +:109DE000FF011DA454BA4C715B6186167719365E6B +:109DF000ABC793F5789F1ED74BD7E80A2F0C403D91 +:109E00009E5E234B8BA8BF3E7619F4E709723CE9AE +:109E10007C8D720BF7E75D6BB2A4B16583FD82A404 +:109E20002439D5D5C8E48E4CBEFF9A01F2A573350E +:109E3000233F2FF6B248FD1F576D1F3AA1DEF14AAE +:109E40004020CA05952972B6760E81885C267A75FF +:109E500032D68DFE36FB41C8E5C038F7E702530124 +:109E6000EEFD9F8BF49430C20D8D2E099587B07155 +:109E70005D466D08F703C5A35006381B326A33B040 +:109E8000BC7FFFA410B388DF5D116932C497CC7822 +:109E90001AA8F79D3594AFB06584FDCF9AA043B75B +:109EA0003B2B8268EF5CD5DFEE5006F73FF57DBDBA +:109EB00060F19317E13D3BC165DCFECC65F1D64412 +:109EC000BB29617FB116FBD932B8BFD87B46E2FE11 +:109ED000E28ADCDBF0E8FEBF0CEC2F46CEC1FAAA2A +:109EE000B7BB1CE953CF87DDEFE0FB006CD28B3EA4 +:109EF000C5823E16943FEB277AD4FC8921DFB5B8A2 +:109F000099D90F9E1534C6F18F87E664F4E0C72413 +:109F1000717C3D9EA7FBC118AF932DF9CE887F7D44 +:109F2000FC0502F763995D2079A7EB4D902791A07E +:109F30009F9A513C5A750A94AF753CB45821BF287A +:109F4000897C19D837603D2556FBAC0BB4BC13F3A4 +:109F5000FB5B825C3F2FB0F338A5B0724904C75D4C +:109F6000107409CE043BE9EA20D75FFAFE8B23F791 +:109F70006415E2D9E1882856F336EFA35C1D64032B +:109F8000E7DD42167A2F199E0ED83B695FEEC012AC +:109F900091CEEB1E8F9C4BF73E24930B6F21FD94CB +:109FA0003016CEE5E30DAEA335DEF43C19F37ED5D5 +:109FB000C0F7A6143A7F63CE97794CC3DB3E0D2FD2 +:109FC000FFDDF932FB34FCBDA4C567F478D6254922 +:109FD000E4FD79B6FA47888E4688CB9CA1E7FB68FA +:109FE000F861CF8CA77B3936F4DAE32902C263A388 +:109FF000FDCBC63F8821B4BFF4766E93BCD0F37717 +:10A00000F472DA4981C513F611D2A46E8A93A69D23 +:10A0100094E8BD99FFEE30F19FBE2EC9D6595F1767 +:10A02000F3FB2E6D5D0E34FD5B00CFBB6C4861967B +:10A03000F9445F048DF177731E40B27DEE835ABB05 +:10A04000E391C93928971B1DB192D1F0BD8E9F377E +:10A05000BEFC8D0BF96CC349E70CABF57835C8FD38 +:10A0600016D0A7EB12F7413DF35F6BC75ED324E335 +:10A070003EA8AE4FF57DD0B44AF33E9AF53EE806D1 +:10A08000662D1F93ED830ED9FFD4F4ED896092FD08 +:10A09000CFB2E1CFB3EFD6E879A4BC8F2B1CFCBCC8 +:10A0A000ACF9FD8B03EBB0BEE047C05737363969DA +:10A0B000F7A9A7C9497CB8B82985E2B28BCB79BC8E +:10A0C00077F17D82B65F678CC3BE04F262199EAFE2 +:10A0D000D7F4CE5116AE467B7456A560D8270FD75D +:10A0E000A618CAF397DCF312DE9BF0728D5DA1F81F +:10A0F00033F41543BBA096E72932A5FF4E8C73EBD2 +:10A10000F1677DFD5FAE3D4AF7A0C5C0CE2F096166 +:10A11000FC5924FE7AF9F549FC5E3A61703F5C0116 +:10A120003B61C379E328DFE360D9B728CEBB01E305 +:10A13000E230D30D5FFE6606D11128E518F2EBC4BC +:10A14000AC38CAC7C5132AB2912E9F99F8B907E354 +:10A15000A2EFDE76DC8FEBD4D7D24C7907E67537E9 +:10A16000C799CDF1E5D38D279F9B3B902740F4F015 +:10A1700092299EACCB2BB3FC4888275F983B8A780A +:10A18000B22EB77439A1CBAF83651D6F3F04FF3C7E +:10A190001871124C6F69F31EE04B8D2E0FEA7CF89C +:10A1A000A593EC916726FE96F2ADF47A2DC14CE2B0 +:10A1B000C36F95C5EDB43F8B790AA583EB323F722F +:10A1C000ED4019BBFDF6D29506FA18905323CAB19B +:10A1D000E1E59498CBE313C9F235753E18AA7F4A9E +:10A1E000C84E4DFBBD3DEE2AFAEA7AA8B1E9D70A7E +:10A1F000B683E7666A3FD111895BE827333C69275C +:10A2000045169F94F85EE1EF07F48083BEC7EA9598 +:10A21000D5AB7DDC9E6E23FE8C3969FFDCA7B6E4EE +:10A22000427D9F5F8D213D3CEC535B7313E4699B42 +:10A230009DEF478A361679C2022F4FE56A7A9985D3 +:10A2400003D8DF9A3AE3792EFDB93D97EFEFEDF1B0 +:10A250005707D0BE6E3B5C1E40FED9EBA9267B3B68 +:10A26000D9BADDA5F313CAAF92417F62A3B6DEC0AF +:10A27000A22AEEE3AEB1870389F1C675B93C8F23FC +:10A280007DF293BD6837B7C936CA136C9379FE75F2 +:10A29000BB5B9AB14D6BE733B493F47354745F8630 +:10A2A000E436E6573FA5D93BC9E6F954AE4DBB5F4E +:10A2B000B4E7DE5A6150AFD88FD4B9E8FE07A6CA1A +:10A2C0003CBF2964C8A7B66BFAA5DE94AF21CA5F6C +:10A2D000CD6F0BFA23BB722DFCB63D3EF5295CEF2A +:10A2E000A81473227D445DD67CFF8CB6AE3FD0E6C9 +:10A2F0006BBE575534DDFB209AEE7D88D537FFAC19 +:10A300000FE96DB5536EF3D13D0F74EF4314AF5C9D +:10A3100082E7DF53783E0BF87FE7F2F306A13E9425 +:10A32000AF2CE0A2785467BEAAE64359F4D81E5A6F +:10A330000DFDB5A9F52A1E5DE974DBBA709F2F33B8 +:10A34000183988F398EA9148EF745E9C4A7A08BEFF +:10A35000A77039C264A19AFC41BA34057D703C5F94 +:10A36000660F38289ED516617DCE71FCFC3FF653F2 +:10A37000C77AF6D716A1BDEDAA443CED0F4DCA88A9 +:10A3800058C809FD69DEFF7FFBBB6F1652BEAA18D5 +:10A39000F908FBEB6D5CBC11F7F557EC1443B88F73 +:10A3A000F09DEF1D3C839F3732EE33DF9F36A50FC4 +:10A3B000F559D4EDA07A7B3CD59D88A736C1D389C9 +:10A3C000FE6EDBE1953F413CB6B5F238B719CF7B65 +:10A3D0003DDFA3FB358EC372627DF3FD1AAC73259E +:10A3E0005F27A78BF62D61BE2CAF8AAF23C5070F61 +:10A3F00079E81EA8E3FB9F71237C5F63DE697955D2 +:10A40000C3CD3B5F26FB45A31F2685D7E1BC6E1657 +:10A410003D9D1D3EBC270DD61BE1DE65277FFFFE5F +:10A42000B4745AD728C087EB2A7A1A5474C9FEBA72 +:10A4300053A4758E4ACD342F1693D8767CBFEBC4C7 +:10A440000FCF473A50B368574B2C6826BCFC15F029 +:10A45000B2DA022F403F4579B85FB4EB46EAA7D3A2 +:10A46000E192D1B269F354D379E5D1DE2F5296C788 +:10A47000F924E17E91B2BC2A8BFA9A9F85FE368E32 +:10A480005B27B3CFE26C10EFC9F257CED7FA1FE8C3 +:10A4900067E4FC95F313C7D7C7FD1AEB3AFD74D6F2 +:10A4A000B5CDF57FA7A39DA58AE9A1944228E33AFB +:10A4B00021FE719D70BDB4B80DA92005E940EEC91B +:10A4C000433AB8313D84F43992DC90185F77BB048D +:10A4D000F40C769D538E1CA0B38B5ABC479727660D +:10A4E0003E6B7319E5559B7E2FDFA1D1C92BA09739 +:10A4F000AB71DDCC726BB474B2324F30DF43B33228 +:10A50000CF9F9C4EECC1F08D8877C4535E05C52B60 +:10A51000BE8BF5F7EF177738C6E2783C6ED61F642E +:10A52000F2430979593A3CEDB8D9CDE3D414FF9000 +:10A530001A19C33C386F694890CB464547ED89F0FE +:10A540007D037474D77074E466BD745E63B99E9FB6 +:10A55000B363F8FC9CAFAB7F603DBB109E36CFF77A +:10A56000883ED7DA5D32BF47EDF4D6F5D1A1EBFADC +:10A57000E8F0EB1A791CBFAB79D5748F11AB692267 +:10A58000BB69975F7D13F3C5981432C8C521FCA33E +:10A59000C9ED9BCF54285F7577AB26E75A9D32DA19 +:10A5A000E3CFFA6E7C1CEBDFCD9430C643A7D856C0 +:10A5B000119EFE0AF37B284472B514F77DA22C3558 +:10A5C000A4E9D1A7110F339456210BDEFB162836D0 +:10A5D000BA8654D9C46C65A3C7C34B43E5E04B238B +:10A5E000C8C15E8D9E6F427AD6CFDB279383874E9C +:10A5F0005F0E1EFA86E5E09FF34E43AF7F03F2E65F +:10A600003384DF2C6FDC1A3F5F1962218C978F3601 +:10A610009F0DEC4D05F9AB2EDD45F4D3F68440F9E2 +:10A6200052608747A8EC7191B0D9EB71F0FCDF1D47 +:10A63000FCBB58CFF16CC6D39779593CEFA67B652C +:10A640005832E449C5881FEE528FC9C522E6F7D7B4 +:10A65000123D7B357B46CFEB4FD7E4FF809E9F6951 +:10A66000A3F1BC055CBE7BC1DE41BB88497D0CFD0E +:10A67000F89BF378FE3EF003D1378C12467EC8A8D3 +:10A68000914C795A9C5FFC12B777327D4C205D83E8 +:10A690007962F0FE04D813783F41A66A6C7773EABA +:10A6A0009502EAADBE2677B340E7F4C37B7E0CE5A6 +:10A6B0002CCCF702BEF1CE30D6F7B384B2857F1E24 +:10A6C000AB67A598B75896AFF9E90E1620FDA8F923 +:10A6D000E9FA7D81E2C8795F95F9A3882F9E97AF4B +:10A6E000E79918F571770AB38CAFFD473E975B0D7C +:10A6F0007D75F56857AFF230B2AB56A1EEC472A6C5 +:10A7000083EEB509EDA97459DD5791A9DA0CF7F379 +:10A710007A67A41AEEBDF587B30CE59CC65C43FDD1 +:10A720006064ACE17BDED2B30CDF0B9A2B0CE5311D +:10A73000D1F30CF58B00C189E571EB2E36D42FE9EE +:10A74000BCCC503E73F3B70CF5C7C71719BE9FFDBD +:10A75000C87586EF13BA5719CAE7ECBCD550BF8D40 +:10A7600059DFDFB9219FCB29E0779263ADEEFA463E +:10A77000FA1D0DD96188F32FD1EAEDC9AC2EC57849 +:10A7800048DB91F252F287D3CF1BD61F36CBC5647C +:10A79000F2D8FCBE5D1BEF93A7DFAF5E86748E42DE +:10A7A0001EE4D227EEB7D6E29CD697F1BC04FD7723 +:10A7B00031CCF7F20FEC534A2ACD67419683599D6D +:10A7C0000F5892AF58EE2FB40B2117EE1525C39BEF +:10A7D0004E8F23E1ED4EADDED7C5DB21C118074218 +:10A7E0007DF284055C7BF307EE3B78389FEBABCAC8 +:10A7F00054F230F83D0EA7AB4F7438409F3C915F48 +:10A8000035343FFC93C6D7AEBE5FC1FA57F3FAB6F4 +:10A810005029AE4BB27DA5BDF9E67DA5AAA528E7D6 +:10A8200016785285C4FB9A7FA5D5D3E3D96DE99FED +:10A83000D3BE529B23543A9A7DA55FE19D1B558858 +:10A840007F858FA7AFAB5D0DC896FE9DD98E61CF7A +:10A85000E33D1831B74479C366FF2EAAC96DDD9F69 +:10A8600093F6D691BFDFE61E4B791F6DEA2AD29789 +:10A870009D49FC5CD0977F447C4EF5DC64F0E70694 +:10A88000E3012A8D076DC96E6A4BF0FF715DD5FB40 +:10A89000F9BDDADF801FFC51FE69D8090AE37EF0BA +:10A8A00071C6F1745CB5919D701CEC0494BF6B246F +:10A8B00046FBDEB14A41B1F28B3B576BF6E16A8E43 +:10A8C00037F37EB7D9CEB824B492F0B606E8C955AE +:10A8D00089F1386EFFAEB1F3FB37656F3880FAB699 +:10A8E000DFEF600F01B47BFD3C3EA7E3E5ABCAA3FD +:10A8F000CC8221767266C13076F234B1AC1BEF6D3A +:10A900003D7692C745143C8AE8C37BC8F9FAAD7A14 +:10A910007E4E6C05EAA922A919F3D745A664205EEC +:10A92000563C27B2B88072CC989F6F67CD3FC278F3 +:10A930001CF3F1F731E66A453B29A3C6A8C7325597 +:10A94000A31EF3CEC832E935A31ECB6934EAB16049 +:10A95000C4A8C7F2965698F49A518F8D89D69BF465 +:10A960009A518F8D5B779949AF19F5D8999B8D7A5C +:10A970006C7CDCA8C7CE7E649549AF19F5D8393B0D +:10A98000571BBE97F77418BE4F7AEE6E43B9AAF7FD +:10A990000143FD730F3C64F83EB9EFFF18BE03A2FC +:10A9A0005FC5F30C780F2D2EE2F91F3C69FCCE54E5 +:10A9B00007E6E35F8FE733611D2FE8FFADA13FD6C8 +:10A9C000C9CF2DC4E03F5CAF3FB308DD0300726C1C +:10A9D0005F1EB4BB212E847A18EAA727DEC77D9BB1 +:10A9E0006B0322F9712B30D88AF4F0A8278EF4700B +:10A9F000CD66E3F9876BE3C6720CE847C1B802D0B5 +:10AA00000FD2D7F5A6DF8D007B90E8ED7A456A4638 +:10AA1000BBD24C5F7FD6E92BA6BE8AE739F4F9EAB0 +:10AA2000F3B3EBE74F35FA5335FA63E22E82FBFAC4 +:10AA30003C917E7F479FAF0AFFF1EF1F39701E27C1 +:10AA4000760ACC8BFBFB2CB62FCF623E37ECDCE4D6 +:10AA500040FE34CFCB3C8F21766A81715F719AE8DA +:10AA60000E11DFBD2E923EA229209F3DC6CFEBAD39 +:10AA70007A5EA47331C887E82F88B146C2CB0AC07A +:10AA80000BDE1BAEDBADC7B476C71E14E97CF34802 +:10AA9000FCA868F870068CFC98A2A49AE8C988DF24 +:10AAA000B452237F5EFFCE450E945FFB00DF420D64 +:10AAB000639E90915FAF1797D13E9F8E6705FEC34F +:10AAC0007125307571DE37C0BC7B94A1F85DBA6B1F +:10AAD000D3DA3C0BBA1909BF8F1618F7E9F4FDB9A0 +:10AAE0003AC08EC322AF54C7DF2EBFFA24CAC76450 +:10AAF000FEF0EE02E3BEFA28FCE1DD89F2F61BF07F +:10AB0000879F2F1856CFF5CF427FCAC9D2431D1653 +:10AB1000713F89C93D18AFB537F3B8DF60FCEE1B54 +:10AB20008FF3BC5B5045F7CE919E4B91F4384FE8C4 +:10AB30004004ED938CB342981735DA38C75F0A8624 +:10AB4000C439FE52307C9CE34D3C4FA866E436D8B5 +:10AB50009099A45029DDEF8C20F03CA44F118F4335 +:10AB6000F2758BB3B4FC6365D8FCE34BB4FDDDEA4E +:10AB7000807A12E180FE3EC7E7C07D6C957EEA27B1 +:10AB80007D847E62F5DC5E8BD93C9D6DDC5EA37DB1 +:10AB9000A66F208E915E887EA99BE3BFCDC1E3B6F0 +:10ABA000A71B670B160EC17BB07018BCFFFDED1C18 +:10ABB0007E6E3504D6417972FAD6CF61EAE5F59911 +:10ABC000467F796D0587AB441BFFDBD9DC1F985CA2 +:10ABD000C8F94FCFBBC4BCC5940A28CFE4E794F4AE +:10ABE00073AD7A3F930B3D54FFB340FDE4423FE623 +:10ABF000CDF2FB77D6661AEFE1F9B8A06E32CE6BD4 +:10AC000092D6FFE442C6F399C772B8CC79A77FD336 +:10AC1000EAFFADA09E9E788E16FD1287285AE27339 +:10AC20004A218F13E8F7DE4CD7CFCFDDC7CFD799B6 +:10AC3000EF5D003E79037F1FEAE89D76F2F7401F43 +:10AC4000D1F9B92579FC1CA2F93E8548A9BC0FC5EC +:10AC5000EB095666792FCF903C8743B750FEDDCB8A +:10AC600093992C0447CE7BB8BCD0783FC257384765 +:10AC70007765E128F21E166AE7E8FA52B91EEB0F73 +:10AC8000BAE20F59F8BB516D9DEED4FC5ADC9FC659 +:10AC90007D72BCDFDB6ABF3C5AC8E967B4E7AAEF44 +:10ACA000764422C8B7E673D5C9CE53F739FAD6E44D +:10ACB00020BCE35908EDF79C05F29E1CA897DAA08A +:10ACC000D0F9C7B5452CBD06BF97DB4278AE2373DC +:10ACD000AEBCD68E7C5ACCB20428F7C5E6D0F87745 +:10ACE00036325904B8BA0AF93EFAC2DB3EA5F1FC85 +:10ACF000B5303585CE9D4F47FF2CD6C8E8DE42F3F0 +:10AD00003CEFD6F8C5B586DF9393516C9D877FB72E +:10AD1000468F20B736215FD415B31DFCFC2C3FA70E +:10AD200080D7D253FE662895F6052F8575E3FBE79D +:10AD3000BDB47E3705A6DE8FEBA9F39B43CB533022 +:10AD40009F27EF2A3CBDF3E4A90BACE1FD9DB6DEE5 +:10AD50004DFEF0CF10DED4D24EFEFBA55F9E3A250D +:10AD6000566B3FEDA860FB4804F55F0AE83F019F82 +:10AD70008A4CE768994BA0F3B02EA599E82AA5263E +:10AD8000E4C5DF456357D918DEE332556BAF363281 +:10AD9000017F4F827201494E9B7E5F420DB5B742E3 +:10ADA000FB69B86F16C2BCEFD052ECAFC19D2A63ED +:10ADB0007C33A5B8B90ED7EBD985BC8FBB939C97D4 +:10ADC000D0CFD90FDE3FB5EC95BDB509F70AACBDC4 +:10ADD000FA15E3FD5357BFF275EE9F3AB8F5EA57FF +:10ADE000FE27EE15D0E51BA8213BDAF507447E8F40 +:10ADF000DE5F9FBAC28EEBB0B68E7523DE639F0313 +:10AE00009E5D8378B6D7879FDD8276C9AAF410FF4E +:10AE10003D91D87710CE77D2988CEDF57C43819513 +:10AE200092BE9EDB2890FDC0A4FE1BB03C7F579ACB +:10AE30008CFEC35F9F7AB32006F4F9F6EDC73D9808 +:10AE40009FFAAED4EF41B83EB8ED350FE2EFEDDB3F +:10AE500044CA43A173DF0979625F6AF4B5604CF8B4 +:10AE600038D2D7C296FFAA4EB4CF58D44FFAFEDAE2 +:10AE700038409C68F73E9266F85DD1E5DD5E435947 +:10AE8000D7F3CB9DD6E7E62BC770B974EDA35D8EE3 +:10AE90003C05C78FD8C7C03C3FD0CE017DB0C3436F +:10AEA00076BC0ECFA247CB1D680FBFBBCBC97A289B +:10AEB0002ED86B676EAE3F30EF22C2871E02E7BE10 +:10AEC000DD790EE4B32502EB771273B37D88EF3F93 +:10AED00069FE9F791E4BDE961DB8BE4BEA583F9E19 +:10AEE0003B5B7493B0F666A8BF28E226BFDF3C4FF9 +:10AEF000B3BEB906EFB311ACEE816BDEF73BE8E70A +:10AF00002AE807EDCF259DC6EFC79EBB71DF161857 +:10AF100077C74E07D98BD78C10EF1F3F46D34BD541 +:10AF2000ECDC53E348FF654C5092DB1DBA3EFAA0BF +:10AF3000855192CA5FF0F77DE1F9518B4CCFE385E3 +:10AF40000AADC7F53BF7ECA3DF16967AAB51DECD21 +:10AF50007C7E71DAB7D8605E517557DB335B88153C +:10AF6000F47CD51E8AEFD568F7BF5CA39DFFA83A95 +:10AF700060CE57DDF3ECEFD06E83F99FCEBD3D0B75 +:10AF800046796FCFB1E7A6A6D1F9001D2FE7025E83 +:10AF9000C4AF8F9764ED9627F9DD169D9F8E6B7A6F +:10AFA000F7AA6DB3D7E6C2F86D4FFDB910E3C7310C +:10AFB000C6E9BBEA41FEFB3F55EE6CA23717D267EC +:10AFC00010F16ABAE721C6DE6009F47DCDAE34A285 +:10AFD0009300D843CE1A7CC3E9B50AEFED44FA7E5C +:10AFE0009DB77769FE6D64D7EDBCFEEF1CB23340B0 +:10AFF0007C19B0D1B32760ABB1B867CB7CBF58A781 +:10B00000B1FC89BDAF10E5CA35263FF413C13A3F04 +:10B01000EDCA3163497E5DA5A8D3310F60090BAF3E +:10B02000E5F15B7E6FCF0752E7BEEF23BF6F13588A +:10B030000CF0B4FC378FFD2BCAB1EB1EBF2F1DE502 +:10B04000D8875267368EB76CFB9A74BC5FE60329CB +:10B05000968EED3F8C737936445F8E11B47D293521 +:10B060005D00997C03911AFCFFAAFEB5B7C2387F38 +:10B07000033C23DFDFB0E31F54DEA7BAFA5900FB1D +:10B08000ED9B8E705CDBE46E6E0DA17F69E4CFEB0F +:10B090007E765FB642791EB13C0D7F79D8EE866D23 +:10B0A00076CAF3453F1E8759C1FA697EE6F62BBA88 +:10B0B0008F3A505ECB36D69F7FFED0EF602139901D +:10B0C000DF56ECD8F0A9988ECF0FDFC2DF835A612C +:10B0D000B24F976AF2DB4CFFBF30D13DE087E20B05 +:10B0E00031808BFF1C1397E36D3FBF7FE26180EFE0 +:10B0F000A36D2FA6E3EF4DE8F4AFDFF37CAC7BF15B +:10B1000042C730F7087DA2F1C9807ED0F493B21314 +:10B1100000CB81E22EFE5C66EF493F1FE6BBACCB65 +:10B120001E429A5FF698A8BAD1AE3AE8247B64D959 +:10B1300063C7896E97096ABF407A8EA5A31CD7D7CB +:10B14000EBFAC7FE341DE5F4F54191CD0456BCEE93 +:10B150005727787DA0F314A87FFD1387A77F1FCB07 +:10B16000204F5C16EB35B57B8FA3CF6DB15EDD87CD +:10B17000A7637CBEEDE77FA7F5F870B7C0728A863B +:10B18000B65FDAF5278A837D040BE3CDE4F8427DD0 +:10B19000B3A25B6C726458AD5FCFACDF56D277CA96 +:10B1A0000B1F691D378C615C3FFEE6B15FFE16E048 +:10B1B00058FA96333413C7FDE58DE90CE8E0CF5219 +:10B1C00033A7FB1FAFC946FDBDD41ECB96E9C9DF2F +:10B1D0002FDDFA5DA2C76B7EFFDD6C6DBF2168239A +:10B1E00079100BE23C973C388FE679358B103D2E79 +:10B1F000FD31BF67F104F8D9567E42A5C2E59693AA +:10B20000AD9C78AB0FE526DED902703818BFAFEBE6 +:10B21000559EFFEE64976524DAB90E85DB7331160F +:10B220007F07EDCE15A09651AE89BF3F311DFBB90A +:10B23000A9486A76527CD4FAFE9AFF075C96D1033D +:10B2400000800000000000001F8B080000000000CC +:10B25000000BE57D0B741445D670F5F4BC425E43DB +:10B260001E100884CE3B488803492001D481400C3D +:10B27000CA63025151220C014380BC445670F5DB75 +:10B28000740820B0AC06659515740704C5E706047C +:10B290008135C2441483EEC128AC8B2F761004791B +:10B2A000C980B08EFFB2F2DF7BAB3BE99E2402BBCC +:10B2B0007EE7EC7FFEEC598BDB555D5D75DF75AB92 +:10B2C000EA4E1583BF04C6F23E1ED5DD9BCE98859F +:10B2D0005D30DF9BC5D845C6A467EC8C5531A3EC27 +:10B2E000B532FABB12CFD889F5962EC28D5076634F +:10B2F000650DD0FE0AFEDDD2564E9704C6B2A9F9FE +:10B30000276C106395F82F09FAD974227F0DF4CBBE +:10B310006244161EC3E167A218B395845487E7C040 +:10B32000F70E1E35F7847A39CAC0926D50DFF20DE0 +:10B33000C1CC1E2D617BB5FFAA1D16E651C703FFC8 +:10B34000AFDAF08D99613F06E6EB35B47D3D63D50C +:10B3500019BF8EC279844BCBA13C61F6E5BF85DF76 +:10B3600081EF6E84EF94AE82F6699AFEB69EFC9CE5 +:10B3700065607B73DBF378FCEF423E2FB138DC1560 +:10B38000C2D84C9826CB6D3FFF055FD63EFAAEA6DD +:10B39000BF0C2934EA7830FC63301B7C456C7B9F02 +:10B3A000AD8D66AC47FBF77FA8911F7DD7846FCB2F +:10B3B0008C41937293FB05C453F96716BB0C782C30 +:10B3C0007FED92D9003013982FB92B63A75FDDF37F +:10B3D000E93D309FD30DA6A831F4554798D0AD0D67 +:10B3E000EF655BBEC95F03ED4D80F720A067E5D632 +:10B3F0001FCC06681F93C77C1618FFE9282763FD3A +:10B40000116FA6AFBD1ABCE5C1736F088D23D610AE +:10B4100083A52796415919C5EC1E78BFF2A06897FD +:10B42000105FCCB7C416D2FEFDAA86A30174D1D793 +:10B4300033E6333BF1BB5B7F7B5E0CD3E2DDF8B5DB +:10B4400057837715CF8178BD3B00AF97587A387C0A +:10B45000869D7A794E1F577A7BFCAA78FDAE8621AD +:10B4600093B73EBFD047223C4B3BE043DDA1AE51FA +:10B470002919FB9469F038FB95B3C4BFFFE821326A +:10B4800011F8A672C38F4B90AF00AD3E0BF06FA5C5 +:10B49000FB3CC18B1D561F23B8A948C8E868DE7A5B +:10B4A0007C06D6F742A466B7D1DFB490C9A1D0AF6D +:10B4B000EF6DD1BD1E86764EF28545C0FC1607B1F4 +:10B4C000A94E28CFD914B8AB0AB3A9D3609CE7E43E +:10B4D0000C9B8CEF05B1490D409F734E5F58D79080 +:10B4E000B6791F6914C32468EF75B3828690F67C21 +:10B4F000C8581D7DDFCB3AABAFA5718E122FBFEEC2 +:10B5000085EF5D908DCC02DFF3D6FEF0BA17CA63EB +:10B5100046AB0DF134A3F6AE306680EF37268E9F32 +:10B5200004EDEEDB07F8A3E939CC3D00BFD3F9D435 +:10B53000D9B74C7E6A18CC4F0CCDDAFB16BC5F0A2B +:10B540008815815F67ACD0E3673673867BE2516E06 +:10B550004D6D7C42FF759B3DF0DE4C5748F572F80F +:10B560006ED95A7DFDECC6D3C45FB303F8CB85FC1E +:10B57000D5A33D7F6D54F96B001B80FC354A0C311F +:10B58000203F9F6B16DD1678E7C222135B02F08521 +:10B59000570537837E2E34422384777098C9D1C4EF +:10B5A000B72A9FAB783B83FC97DA1E9FADF5DBBED5 +:10B5B0001AF43034297FF38B8C35509E79F3B39491 +:10B5C000B710DEFEB7B82F58FBF679BB7E9C42E37E +:10B5D000DA656138AE73BBDE8F7B18E13F5BECC888 +:10B5E000B7E7165A1C0CF5DDAE507732D6F7067E5B +:10B5F00000BAD7BDFD4306EA7BC616111D5B243396 +:10B6000095171AFF7958C079345A249C47D52E4093 +:10B6100002BC5FF5E72037C3F7DFFE61902BE497AC +:10B620009B4FA599B9883F43D9A42DC8BF5D990305 +:10B63000E753F556EEF3B5F0FD8AAD4DE6E9509FC0 +:10B64000B7FB5F19A88FCE6D6932A3BEFACEE47D39 +:10B650008E017F7C214DAE37019EBF0B85CE7A32A5 +:10B66000362F7E8D530EE9082F1C0FE7000F382F61 +:10B67000C04B993BBD737C5CF8AFC5C7F929F8FD99 +:10B68000F2C6C14C8CD7E24570F0E7A16EAB40F337 +:10B69000E7CF77FD90C142AE3E5F5BBC99E4FDFF12 +:10B6A00097F966C4FFB7D297F3FB9B12B74B817C27 +:10B6B000DF9EAFB73F48F0EBA1761AEF35CAFBB873 +:10B6C000FFDAF9FFEFD0BBFCBF76BE57A3F73E858C +:10B6D000DEA1360BEAADB7FF15C7AE63DEBFFD7F57 +:10B6E00074DEADFE8FC16ECD82F17DCEDC770C179E +:10B6F000C82BE9D01FD9112F507BA6AC3BC6297EA1 +:10B70000451DFB7AE434F8AE0CFE04FAFB75215FAC +:10B710001B0F02DC027E02FA170C9D13C0434BD1B3 +:10B7200000F772B4DBC66A6603D8F4E97482279521 +:10B73000FC68CC82F677809F87EDF7D77A67D44292 +:10B74000FDFEAE06A90EE0F18E89C95B01B6F514C7 +:10B750006DB88EA973645A25CDF8C6E7E8D723F7EC +:10B7600004AC2BEE9AA4AFBF93AD8F36427F779691 +:10B7700099981BA6744740FBA7E26D34CFBB58F5E0 +:10B78000625BC8F5E3E9783C5F9FD5B181CD12E2F9 +:10B79000C521DA37B2F678638837C44B4C265B6E26 +:10B7A000C7AF788D0701B628FE15FC913CDE116508 +:10B7B0007D01F1646173D983D0DF25C9588DED2DEA +:10B7C0000CD68D7CDCC215A13DDEE04F320E225737 +:10B7D0009C4830DEF100433CE3F33E31BAF769DECA +:10B7E0008178BE7EBC2E4C7E0AF15A146A77235FA4 +:10B7F000389E8F36C2F7EA00CF82D0864F154F8130 +:10B80000787F0B7943E397AB653AF34D41BF338CB7 +:10B8100085D99743FF61D65ECCC8E7E1B3F4C0C2D7 +:10B82000C670BD268E600DCB61BDC6728C675AE7AF +:10B830009540F59E87E1BDBAFBE17DC46B2F2639AB +:10B8400089FF8B6DC7FBE132CFC5AE04B7F99F1FEF +:10B85000E580FF194F25F1ED471BB8BF7969D81B6B +:10B860004B0680283198B33C08FD5CE54FF616E3A3 +:10B870007B2233D871FDCB1C0EC93608FB65B4AEF4 +:10B8800009CF31E8D6BF5D1D5D74788B2C88D0C19F +:10B89000D1CE9EBAF6DD2725E8EA7BB86ED0D5C7B3 +:10B8A000960DD4C1BDAB87E8DAF759304207C7CB54 +:10B8B000B7E9DA272E9DA08393EBEFD1B54F5D5DFD +:10B8C000A2ABEFEB9EADABEFB769AE0EEEDFF06B68 +:10B8D0005DFB1B772CD4D50FF02CD7D567363FA155 +:10B8E00083B35B9ED1B51F7C68BDAE3ED7FBB2AEC5 +:10B8F0007EE8B75B74F04DBE3FEBDADFE27F4707CF +:10B900000F671FEADAE7590FE8E051B62F74ED6FC1 +:10B910008D391A10EFB0C90F64A11A037E02391BCA +:10B920002D9DD6B587155A31F28D49E187DBD3BEFF +:10B93000D7D58FB5FF53D79F9955031190ADEAA97D +:10B94000ECC21AA80C612D543ED4DF757B02CAC329 +:10B9500073F21264AAFDB93FC4A11DF968D803327D +:10B96000F2DDA518661307C07898CF887C6D08BEF5 +:10B97000DCCBA5891B85F945E6C9043EF40B54DAF6 +:10B98000FCC1CC13097CE80FA232C21F49CF23FDB2 +:10B990005DA98CF2C7D2F3687F0F2ABBF913A9EC1B +:10B9A000EE8FA732C6DF8FCA1EFEBE54F6F467D2F2 +:10B9B0007BB1FE0154F6F20FA5E7BDFDB954C6F9FF +:10B9C000F3E8791FFF702A25FFED54C6FB47539912 +:10B9D000E09F48ED12FD855426F927D3F364FFDD7F +:10B9E00054A6F8A75399EA9F46659A7F0E957DFD68 +:10B9F000B3A8BCC1FF00BDD7CF7F3F95E9FE87E963 +:10BA0000797FFF435466F8EBA8BCD15F4BA5DDFFFF +:10BA10005B6A37C0BF8CCA81FE27E979A67F25956E +:10BA200059FE35F43CDBFF072A07F99FA772B07F68 +:10BA30001D9539FE57A8CCF5BF44E510FF1BF4DE79 +:10BA400050FF662A87F9DFA2E737F9775279B37F8B +:10BA50000F3DBFC5DF44A5C3FF213D1FEEDF47E516 +:10BA600008FF017A9EE7FF98CA91FE2FE8F928FFA8 +:10BA70006754E6FB8F5279ABFF089505FED3548ED1 +:10BA8000F69FA4F236FFF7F4DEEDFEF3548EF1FFDD +:10BA9000939E8FF5FF48656B3C619829402FB6EA6D +:10BAA0003FC3152859484487F1B6D6F7157DBC32F7 +:10BAB000F83986718F71D502ADD39F0EFEEE5DD23F +:10BAC00093B91609E1C5D8B407FF8EAD1B63F7E241 +:10BAD0003F24C69A722DB47EDFFF3FFCBD25C38F85 +:10BAE0007EF900DAC7FB2D0CED63A0FE55BFFB51BC +:10BAF000CE9E68F4C3960CF49663FCE577F1DE62A3 +:10BB00002CB727707FE4F5046E6FB72518A87CBCAE +:10BB1000BF8DCAE2FB93C3294E15756DF3BAA4D845 +:10BB20007DB5FD1F921438C41747F6E21AFBB9D64B +:10BB3000768BADBFF923C6751C7546167433C046A7 +:10BB40006EEFE52F43DD1B614AF288EA1731CE2301 +:10BB50002FB4D8EAA210CFBFF913B65FC098D302B2 +:10BB6000E53309AEFDA8177E088A73837184BFEAA6 +:10BB7000C113427FD1FE3FFF5FEEFFF8CFF5FF77A5 +:10BB8000858F6E4D749E4A40BFC0E8C8403A8C58BD +:10BB9000D8438C82F7A7AD106CC847D3170DC847A0 +:10BBA000FE18C81C1427BD37924D7576E0974524C2 +:10BBB0001A14FF4232DF05E339CB9807FD89128959 +:10BBC000115F96340A6E99E2D08EB0B160BFCB148B +:10BBD000BE2D595A6B9E0FED2A7AF0781973F378BF +:10BBE0009915FE877234A77EDD5E0A378A97293E53 +:10BBF0007609FD5E609D399BDAC763E7639C7987B0 +:10BC0000D98676A3A221209E1B10370B8C9705277F +:10BC10008646A1BC323BB3F3387748E9DFF07B2C92 +:10BC20004C12A3AE8E17353E2B31A93BE27194988E +:10BC30001E8EEB980BCDC9E10C4B49EA8EED5C40B2 +:10BC40008B162805A36B303E077CCA48575F6DB042 +:10BC50007B3D8CEB08D813291385DB35D88CF1C8D4 +:10BC6000CF7BB3E502518DFCB0AA0D22F9F5DE853C +:10BC7000FF5C8271EC59F1465A074CC3983B8E6FBA +:10BC80006757B72C50BF8477DF6B02C55D653637C9 +:10BC900006E3BA9AFD10F26B9D8BA3C7E5209D9633 +:10BCA000761D68415AC98E4F93BA69E8B3A88EF0E1 +:10BCB0005A1213C9E9B3C3447E2DD0A716E933CB7A +:10BCC0006D3AA6C5F32576D98CFB31254BCF13BD34 +:10BCD00066B7D14BD7AEA2BE89E80A74D23DAFAAEF +:10BCE0003EA1C6D18FFD1CBD86272AF14D855E1869 +:10BCF0003FBF0B2B1F8924FD50BCD0935CADE1D31B +:10BD0000C07D89A41943C29D200F053D393D98D1BE +:10BD1000DE0DE9F9FD8A6CA257209D0A7E9A4EF449 +:10BD2000609F87B28D309E7B13D9D409F07CAA1214 +:10BD30007FBDB76E7401C6CBEF4EE4FAF223587F95 +:10BD40003A60FDF9718D953940351FA8B111FCD7C6 +:10BD50009A1882FF562351F9594D1A95C7CCACACAD +:10BD600041235FC000661CDF5445AEA626AAFB52E5 +:10BD7000F36230EE5EF0D3816C03AA50B9A170D4A7 +:10BD80004DB8BE002468F033A928987C6915F69A4E +:10BD90006CF931A83F9609F68D4857E7505D7B96C0 +:10BDA00096D906A3FD32727E02BE588FFC77F798B3 +:10BDB000485DFB3B97C6EAE0F989128DAFB0205190 +:10BDC000F7FC9EE27E3A789A1FD6F3F0A924A9C028 +:10BDD0002043FF17FF62227EBE583DB8FB7C0E1346 +:10BDE000DF05E2FF9859A63882BCDE6247FDF76D99 +:10BDF00010E7EF6FFF2ABAEB68DD2B53DCE592D535 +:10BE000026E13AE5C1E9721CD63F180C2EF900C4B0 +:10BE100097C8307EC05EB690FE9CBE5A6032CA881B +:10BE20008FD17A79DE4B169AE78CD5227365129FF3 +:10BE3000C461FB79D112F5776FA2D480FCECDB688A +:10BE4000B1AF87DAE95EE57D6120ED8354CCFDDB9F +:10BE50006123CA434A4B06C6F78BE33DD1A807CFFF +:10BE60006C30D1BE5785B8AE34044834E7776F8460 +:10BE7000E54A247E84DF531F47AFC3F9B7CDD74DC2 +:10BE800071116F1FE7B38980CF53A5EE0C5A273F7E +:10BE9000C2E3F1EDF1C2484FC986306923CE77BACB +:10BEA0006BB02D5D6B0FF9BEDF7493BD9B3D1DB96B +:10BEB0003FAB07EA81632B4C05187701BD3F0EF1BC +:10BEC00074AC3ED2B09C16555B88BF4A8C9259FB2D +:10BED000DD9215A283DA837E2F447BBD5274B1C1FB +:10BEE00008D753FFF252C185FB4E492CA73BF2ED18 +:10BEF00003F70FEE8EF398D2C93EE37720332ECDB1 +:10BF00003ED6ECB745A71BBF97E53516F5D78E9FF4 +:10BF1000C781925C4B7BCD453A6D0EB22F9750AFE7 +:10BF20002686E33AF5E441B01BF08D59754D1912A0 +:10BF3000B05EF903DB890E65E31A523CF0FC63AB9B +:10BF4000EBFD4498C2B73D1A9E1A8A71A2C6E7E378 +:10BF500064B4830BF8FEDAEC9767F5D1FAF3EDFDE4 +:10BF6000091663C8C1C2D34D00BCB824968FF89D92 +:10BF7000CC1A94F8859BC627A1D2057CD8CAF9FEB5 +:10BF8000DB74837DCA812C447FA80DE9A2F677D4A7 +:10BF9000C4E35C9F270A3A3B1C9DC4E57BBA81CB76 +:10BFA0001DDB25109F02C13E4DD2D8CB2AB682ECB4 +:10BFB000654CACC870DFEE646284A217B8FD9B8349 +:10BFC000F60FF7856D02C947F9268BDB0DFC9598B6 +:10BFD000C4E573B6F9B5A70662F3F86A337E67D68F +:10BFE00056813D034D4F99DCA52DB82F655BB728D1 +:10BFF00082DE33D9DDC8A78A7EB7824240BD3013C6 +:10C00000FF09F515AB04B787F8C549766806C64D34 +:10C0100070FD8F7A5EA347DAE9F700BD7E1FD3DBA0 +:10C020002356AFB72FCEE0502B8E73F62AEED7B63D +:10C030008D4764570057A52EF7DE71345E81E222EA +:10C0400081DF9F89E3C3F1C2F83CF6EB1F4FA99D46 +:10C05000CB6979BDE07677303E15AFE1C39884F6C1 +:10C0600079CE06C18DFC382AEA7EC2EF6CC06F24FF +:10C07000E2557686DD05702930929BE22B1CFF5538 +:10C080006B39FE81CE9F68EDEE37513E33E2F51BF2 +:10C09000B09F32EE0756FF4074DF0BF445F99DB5B3 +:10C0A000D96DC68DC8D3AC3E2C04F97EF5C77B7123 +:10C0B00059F0CDAA37BAE1FAB538C2936C00BD1574 +:10C0C00029473C5170531BFF05DAEB767639003F68 +:10C0D0003273921D6A8727EB8A16DCF76E473F257D +:10C0E0002E761FFE0BF073DF06D11194A16BA79C77 +:10C0F000479089FFCB641FF9096530CF3A1B3E9505 +:10C10000F3112FF7D919E9DDEB1D6FE03899584C81 +:10C11000FC89713DF443FEDDF106FA1F85493FEFCE +:10C120007F04EA9140FFE34B93C3B010FDBE8FF94B +:10C13000BEF845A3A737CAEFC5A8043BB468D3A38C +:10C14000D103BBA39E57F568A962B7D47EEF437BAA +:10C1500005F0F1D56F8421DD55FACF443B91DE66C1 +:10C16000271E9C0EFDC3F71EDC1E44FD9F1D0B7693 +:10C170000AFA2C7EF6FD30A6D17F0BFBB82A92502E +:10C180009FA8764D5C176703FE52F5E5D5D65D9DF9 +:10C19000CE2B24605EA1FA7995E0BC32DBFA9BAE2F +:10C1A000CCEBEBA57C3E4757F0F9CD68372F6EF707 +:10C1B0001F7CDE6297C92FF044A31C7EBB596475B7 +:10C1C000445FEE375CB2023F0DC0F8CD0AB2EB27F8 +:10C1D000A39984719D4EEDF74A0BF905B3B6F1FDB5 +:10C1E000D653C2F0EEB4F1FFAE27EC2194EB2D2232 +:10C1F000433BD4369E56BBBD2A295A63B7AF116F55 +:10C200001867457B5609A843BEAF6CECCEF09CCBBB +:10C210008AE1AC41A47D782FE93160218A4F831FE8 +:10C22000AE8B375898DD6A453A75127FFD47F2F9B3 +:10C230002973091FBE14C4BFFAFDAA2E1E5377F43A +:10C240006B360BE4D754CC1B1E369CE17778DC6C44 +:10C250004B12B753DB143D2738AA292E063E8DED2D +:10C26000711CD75A1E1F66EFB006C42FC2143F368A +:10C27000F07908928D150FE471792BDAB51003D996 +:10C28000B5403C7CAD7CA7423490FF5B6EE67EF00F +:10C2900039819FFF7847B18FEF24717FF8FD241E0D +:10C2A0008738877E20F47BEE268BBB5640B7D54877 +:10C2B000EB64E3308B1BFD19A335C42366207A8D14 +:10C2C000DFB5CA33E06B0A6B31213DC7E5DCBF093E +:10C2D000E773B827B3895DA9DA89FB08934933303E +:10C2E000B6DFF4E57B188F94A1AD086B85C93927BB +:10C2F0007A63FBB508C3FC0F0735BC877196C3F1A1 +:10C300004686FB02F2DB16B2FFA611DEDE14A7ECB6 +:10C31000C258DD008CC7EC598C7CB4372632CD0670 +:10C32000EDA71ABBD845AE7F469EC7F196097CFFA4 +:10C330006691371BE973235B643B6EA5AD85AD57F2 +:10C34000227F8E7F8CECB8CA0730A6F211F08F21C5 +:10C350008C33560EE15307035E09FE2169DE8455D6 +:10C36000BD70D344EA8F742E4FF019713FC527304A +:10C37000DF7AC0C31D393EA303E9E5600DE3817F89 +:10C380003DFB9880DF4111C0EFDEE54918857860FC +:10C3900069120B87FAF14689E05E052C4254F60DCE +:10C3A000308E7568A8407430582513CEDB59200CA8 +:10C3B000C47DD1F285D736CEA08DBF99B06A18C0A2 +:10C3C00006035FCF3EC4D7B393E523A3C84F1AC675 +:10C3D00004E4C3AA880613ADA3415E70FC03A01B4E +:10C3E0002DFE261BBD7C7C6530BE5C948B24E2E375 +:10C3F0007BAA05F227ABCC1DC735A293D57D399B0F +:10C4000084EDE7C0BF90AFE7346E4FC6EFAD103894 +:10C410001FCC51F9EC55BD5C0E4E66C4A79DF1755D +:10C4200096D27F56B2819FE36AFD5E03D9DD398DD6 +:10C43000EF1FC2756567FD57589887F0F2B685E221 +:10C440000782C19744744144021D26A33F092EE28E +:10C45000C064EE27AAFC598AFE4722963C2E620051 +:10C46000E589F6B0ACFE7933222DF0FC11383E742C +:10C470000E68F686C0E79AB88AA8D33B14F714CCA6 +:10C48000BE19381EE1E6203BEAE3C9E6065A9707E3 +:10C49000B633D5733FCBB494FB59B4AF06B0650542 +:10C4A000F73327F7F2F567A4E76CF9423C6BF58B9D +:10C4B0004BF9A7E179B9CE2FB6601C01E35EABB9A9 +:10C4C0003F6854FCD792157A7F61F2228DBF48DD18 +:10C4D000FA2A70BCA6478229EE62417F42E307FC3C +:10C4E000DD5028A31E96138C74FED2C402FD0927CA +:10C4F000E3F14CFEDCA8F88923934DBA7D3779042B +:10C500004B433C14A31E4A4455E35C8AF1BC0B2CFC +:10C51000B41EE366A3C44728FE575CCBCFA505C66F +:10C52000FF2E54BFF72CB6C77A7C3EBFCB4F71B8F5 +:10C53000BF09CB52A77033C87797C3975C281FA059 +:10C54000A84C28EF41FBBF41583084332107BFEF8F +:10C550007916FB97CD561BEAADA783C3A89F050BA1 +:10C56000048A0F2FB27179FBEACBD0F5A8A7D47853 +:10C57000EF92E199ABF1DCD26F92774FB0F646F5CE +:10C58000C0E8DC1218C64F1C309FA2CB203704BF76 +:10C5900037C1110E7CFE9E6F8A15F0B46AE37B13DF +:10C5A0008CC08FE77EEF7B0EE11736EEE7F0EF7C75 +:10C5B000714108271F986004393A57ABF6776082BB +:10C5C00003F7DDFFC0E13AA897012E46FD86F31E72 +:10C5D00022D0BA7F23DAA5E8B6784FB1E11D5E8E8E +:10C5E000601EB49F576BF7A764E746B4D762E8B103 +:10C5F00050F42FB6A63A08DE92E87C2C19FDA083F1 +:10C60000EE6ED118C732B016A40BD8314747FBD213 +:10C610001B93B8FC6E4EE1FDA9F8827E9E4E8EBE45 +:10C62000FE7E6E69DF8FFBDF194F9754E8275BD7DB +:10C63000CF4BFF4E3FE501FDA87E1B38C012EAA993 +:10C64000D3698E77719E737EE318B115F5CF7E9115 +:10C65000F8F4FBEAED2968F7BF7FD51289F66FCEB3 +:10C66000EB3BE34A318EA0F845A79B3E334BF07E6F +:10C67000A55F640ED0D3557E81CACAAD4DE6FC7469 +:10C680003C57DB64CED38CAB5C192770BA7182C681 +:10C690008FD997ACC69F57D278E7BC7ED288F49CDE +:10C6A0006368388EE78FD9101EF70A9CDF16E5BD48 +:10C6B000C378DEA08338C047C9DCEF88E9E7D88FAC +:10C6C000F3DB8CFA1CF9C5C0CF8704B6EF9EC2FB22 +:10C6D0002BEEC2F57CF6417BE9015AF76518442838 +:10C6E000071DAA3697C0F30389230E25771887F410 +:10C6F000F13864238F431647B4CC0363C622522E0D +:10C700003C81F276FBD3AA7C80E8817E29B0A870B8 +:10C71000D0C491C3789C0BE14B1B0D4FE239C2E6AC +:10C720002E2DBF3A80F66159285B0F7276EFE0D06C +:10C73000B82D308EE972B800B6930DB784A64C833D +:10C740007627128647A4F0F327E41F9E48709EC503 +:10C75000F179E3830DE08C309799C7B35C1F88149F +:10C76000CF726504BBDC1DE0EBB482CF8814EE9F72 +:10C77000351B609C03711CFC7C2FFCC56DC178D3FC +:10C78000C23E02F29DFAFD5B1387774DC96EFBFE38 +:10C79000AD89CE9F92A3B5EDC319B6BFD671FC5338 +:10C7A000B1A75D5338BD9CC380BF347A7FC2C860D7 +:10C7B0001D5C34269239B4F1CDA2581D3CA93851E4 +:10C7C000D7FE9E19FD74F5632D2D59D5D7E1EF8B5A +:10C7D0006169E1B4FECFE6EB90AF1A2F7D3A19FD07 +:10C7E000D80DA25D8079CD7A7BE3A743A97789E252 +:10C7F0005CA79A45B247E0DE9AB5FB2767590B9DC7 +:10C800003B36765D44F66F4E0C3FDF3DCBADDFFF30 +:10C8100050E3F21DED9BA03D2BC773311DED9BB482 +:10C82000C5E37F76FF243345590F0F6403F97AF887 +:10C83000CC5E9829CBDBD144F4AADB27DA9155EB07 +:10C840007A0B4C8071DEBAD5E20E82719FDD79C41D +:10C850002C69F64FAAFC600022F1BD23663C4F759F +:10C860002099EBEDCAC6F366867CD1783FC9754B3B +:10C87000932B2A1AED17F8ABDBB290BF1AB2D0FE99 +:10C88000351B6C4EDC0F9BB37434C599C3FD93A963 +:10C890002CAF1F4DFD56F827125CE90F26F823B187 +:10C8A00065EBC7D8CFD3E136B4E71546F955A44BAD +:10C8B00085149C89FB55955B3FBEF86BB4A3367E0F +:10C8C000AF63ACF84916D68FED6333D475C5F10666 +:10C8D000513F2D23BEC842BB5480EB02785EBE257B +:10C8E000D785723FBC2ED486722FE279B20EF874CF +:10C8F0006A0AD72F262F1FEF287F21F5D7BABE4F00 +:10C9000049A0F9ABB0297A8311F5873A0F13187C47 +:10C910002C6FF3F7A3B26A6BA111CFC57F90F67CA1 +:10C9200014E209DA876099347228E999EFAB078736 +:10C93000B30EF4965A5A143D3C19F530F45794E668 +:10C94000F835CAE5B847BC462BEAD110AB0DF73F26 +:10C95000C6E50C904A35F311DFB91B5712E0ABF86E +:10C960004CE8074C8652ABB7A776625FE41483E2CB +:10C9700017D5F2739DAA7E5FF504C375D8147E5651 +:10C98000AB55AE2A94F6EAFB2D02F707E46D3CAEF8 +:10C990005F91E67A12C7DB329C4DDA42FAB425AEDB +:10C9A00030F4971B7F98B185E81C66930CB8AFA054 +:10C9B000D6AF6E9D0797EFABCD63B1D2FE23912D1D +:10C9C00040BEF8E8965B5A1CD06FD3C39999A2C6B3 +:10C9D0004EBD94C2CF35339BEF32E98B5DC112EA75 +:10C9E00081B1B8F790D5E6F7E379488C6B54EDB296 +:10C9F000ACC7F3605561B0CE87EF8FE9E77A09F1F4 +:10CA0000D1B43BF722DEA371E0C20CE4DCD138F8EC +:10CA1000229EB3775841DBD8D10F72BC4CFABF933A +:10CA2000F15E4D9F258D9C1385FEC4F73024B4B76D +:10CA300060F7B30E72D889F8722DE5F2E752E47010 +:10CA40009AC2BF258A1C4E3372399CBA2ADC86F101 +:10CA5000CE924784FE785E8E49A176540126E4CBBF +:10CA60004CE44FCE97E5FEAE8A3CC72BFD70FE0F1F +:10CA700094CF4A7F24B553E5F4E534D7216EE75AC5 +:10CA8000B216C0B86E03B946BDE75AD8230BE5A469 +:10CA90008D4FCC36E427E09398520D1FD435FD68B6 +:10CAA000443E310D13884F2C50E669F8C8D9EA9FEF +:10CAB000D8F2BBA15FB528DEB09CB5D57F95A2FAB0 +:10CAC00029D7C6EF1F28ED4B42C08FA0F84F18C3DF +:10CAD000F8DA852889E2A47397C1200105734D9E79 +:10CAE000648CC3CCBD3F88E260A507AB97844AED58 +:10CAF000E975B73F83F69727FA93A83C90E83A8DFB +:10CB0000F898E6BF53C163C635EDCF653B78DCCD01 +:10CB1000E4B6D8D7C563DCCD25D27E5C6F667B9248 +:10CB2000EC94BA1FC7E36E18CFC3F85EE0FE1AC6D6 +:10CB3000E1703D6D8932E8F609DBC5E386EBF7D39A +:10CB4000CA9B3E196480FA53F10E8ACB79FBB88CEC +:10CB5000A9308FD913DCAF9BB4FB6C0A1E1B8C9ED3 +:10CB600064B4A30DD51C3F0D2BC402DA6F622CB840 +:10CB700050735EF76A7C3CDB9F48F851ED8BAAB797 +:10CB8000B7D7D0A1CF56FD7D35BB53A1F07B05F2C1 +:10CB9000BBBDBD9D51F935909F55FD6C8A3E487ACD +:10CBA000E8367805FD07555F17E40D1D86767EE8AB +:10CBB0004B895BFF0CF38F4C7365A502FFDCF24AD7 +:10CBC000EFAC3500DF66741B6D21D7A20F7F349167 +:10CBD0003E7CA490913E8452AB0F4D9DF8E1B9A9E3 +:10CBE000D7A7CF5395F6E0C772FF10F4B5B6BF8A4A +:10CBF000B4116370FC85A9DC4EFE52E3EE4C8F1736 +:10CC0000A6AAF2796D7AFC66A5FDD5F4F88C54AE2F +:10CC1000C703F5366863D2DBE7DEEE4B71B2C30CB7 +:10CC2000F43CDAB3C6606963BCE69C7B9770B75688 +:10CC3000AFC7F49B3E03F9FD1AF4FA7D88BF7F5716 +:10CC4000AFE7176E26BF0AFE9CE36F86F5C76F61DC +:10CC50007D87F047B0BE8B6F2F0F817210C8F7B081 +:10CC60001ED9FA318CAFF9A93E1477003920BEAF36 +:10CC700000BE473950E5A572EB8070DC37607F114C +:10CC800019EAFF403928C87BC588712AD4E388AFE8 +:10CC90003D20F3A86702ED843FD5B50AE7AFCA830C +:10CCA0002A0757E7A39D265C979ACACF733D0FA525 +:10CCB00056CF77E6CFFCE13AF9FFD1D46BF3035EB0 +:10CCC0004DE5F7207E41FE7935F5DAFC82D752FF3B +:10CCD00023BFE02DE21FD49FB87EBBFD437BF87CD1 +:10CCE000CE3F742E11F8210BE3CECD837ADB314E8B +:10CCF00073FB15EED7834E27BF3ED0AF9EACE8BF87 +:10CD0000A94A9CE0409AB32595CB2BF9EDC3138338 +:10CD100007A0BDBA567F6F725435C338D35428B5B7 +:10CD20007AC28274EBC05FFF6BEAF5D9EF3DD7485A +:10CD3000DFE3A9FFB19FE7BB167D90E4B04E447CD2 +:10CD40007EEF3132C4D3D5D603A6D51CCF2ABCD8AA +:10CD50006354ED6624DA4DE08FF3FF097F8CCD6BD1 +:10CD6000B86805BA86A7198B301E78279EB5A078BB +:10CD70008669952309F50D53F70528DEF191A8C2C0 +:10CD8000E68323611CB73FC9DAF60DA07ED4B0F06C +:10CD9000D6F888C0DADA87A5890757D0B8F97915A7 +:10CDA000E6F21AF93E990267011CAA817302E0B506 +:10CDB000BC7D98D1CB6CDA7E14FD33CEC6F705DA94 +:10CDC000F6F37CF95DD1FFDB2AD8707FE19E61E745 +:10CDD000CC18CF199BE7DD1B0BEDE2D3428B42C091 +:10CDE000C4DFB355A0F10ED814B54A4EA2235B0E92 +:10CDF0003C6F589EC3F74D2C0D4DF98E0EF87040C8 +:10CE00009ADE4EE19FB11BC5C7E8CFD22030731622 +:10CE1000EF2721FEDADE47FAD1FB09F4BEC712750F +:10CE2000EDEFDF358C39DC1DF0D12D698A3EC4B8B9 +:10CE3000B0DA3FD0646283E0E8286E73ABD2BEC53F +:10CE400060A86080A7F19BD25661DC6B14E37C5133 +:10CE5000B829B548E6FCC71C01F3FDB9F166A7E99E +:10CE6000D767F827E9DFF7FC1CBE86B6C39742FFF9 +:10CE7000323D9F841B9DEF7E0FE3088F126CE8A765 +:10CE8000563A8356B070A4BBC2D7F2C022C73098BE +:10CE90005F10D3C5F15AF95ACE2C42BEAE646AFB7C +:10CEA000EC55487FA7A1B53DE7F346A1F5FD342336 +:10CEB000C34FD0FB733665ADC23839D083EA09362B +:10CEC000FE0C9F3704C0C302E4827198E412F5326D +:10CED000E027B983FDDBA50A7ECF0AFC7C53CB0893 +:10CEE000EECFB524F0F2C534EEBF3DAEE0F169A55A +:10CEF0006CE9A2C143AF363AC39F07D7039A7913AF +:10CF00009EEE8E52E62D4F2C1A03F36A8960FD05C2 +:10CF1000E093759BC6AF5AA4E193E7374D2C423C92 +:10CF2000B4F627171E443CDEADE0E9C54D130E22D2 +:10CF30001FE1911394B78A1CBEFF6AD9FA7187F278 +:10CF400036B73DFFC8985FA1821809DF131CA62CD5 +:10CF5000DE4F4207F859D0FE7D47C0FBCC14753D2B +:10CF6000EF2BF4191340BF8200FA8D0C808BF57003 +:10CF70009B1F0C3D83FF54B263E5E26E183FDB2438 +:10CF8000D01D2BD0CF66019E37A6DD5B14D203F9EE +:10CF90005432C5425B4FDAD483D6BE208FA8BF4837 +:10CFA000FFBA485F4F443927785A91E346E49BEA39 +:10CFB000C531D07E6F5AC92ABCF77ACFA2952644D4 +:10CFC000FA0769335619A1DFBBB3FEB417FB330A66 +:10CFD000A507C7083FC3A7F501F3581B00CB01ED18 +:10CFE000575D459F2F0A78FF9180FA1501F0EA00FE +:10CFF00078A9FEFD6933F8FEE534A01F22EE6AF23F +:10D00000E24D6B5D37B4DA2F01EDD9877A7EBFBD73 +:10D010008EC327373D50B4344403A7FDAA48CBBF85 +:10D0200026C55E4C8E723A3AE2DF439DF14F5AA01C +:10D030005D9375E7120F33A6B3BF7B443DDC24AA92 +:10D04000F2B5F0E0BC74CD7EA05C5B84F194CEF7C9 +:10D050002BE422DCAFB8FD71B57D4D9143333FB574 +:10D060007DFEBFAE88F8BD2B6935451B68FF4FD9E3 +:10D07000BF8BE0E52D97AF84215DF2F1FC28D677D8 +:10D08000F124CF4DD7CC8F35A4E0FC9A1EE6F70DE6 +:10D09000E53AA007C87909B3D3FE775378F8821729 +:10D0A000A0FD9E87C50568BF0E2F88A4F346E3FB4D +:10D0B000727F7B4F789F6EF701DC143CD58C71D565 +:10D0C000A6474751F98EE858E203E4F7EAFB5851C6 +:10D0D000485FAC0F27BCC4BCB4ACA816E420B6AF04 +:10D0E00044EFBB226CDD76A01FBADCC470FF89312F +:10D0F000FB73C427BFB3909F3AADB61FEDF794FC06 +:10D10000BE30BF07B42B596CA2F83FFCD17D0CD7C1 +:10D11000F25166AC9FB14829E55BA9DCFDD31B1F2A +:10D1200066D0BE8E48E77676F9238E8324B3AFE5CA +:10D13000FE745FE1A8925F656B5F576A5F18C7D79F +:10D140006792285F0AB3496113D06FBBC191D6378C +:10D15000BAADDDEE9F44DAAF7AEB4C4937DCDF1B2A +:10D16000D897F3CB2E7F49B7128D5D2F3D6B243CB2 +:10D17000EF364BF3506FECEED25B90496E1B2231D1 +:10D18000CE3A43F19B814F16BCD1011FF6E92B1219 +:10D190005E8E5916E05958D6F4DBE861382EF5BD9D +:10D1A000EC83AE3ACC1763EA250DD4FAC7B9C9238C +:10D1B0006EC6F1B6F1D706D2E7E41F033CBAEFBA68 +:10D1C0005532D80FB607FC7A1C4794231FF9493D06 +:10D1D0008FC7621A52B47185363F74A122FFBCDD3D +:10D1E00057783818BEFFD5AB4174EEEB2BF98B5056 +:10D1F000AD7FACCAC7CCB0FF39DC42EBE2704988E6 +:10D2000003BE31D61C7F08DE2B7DD6447AB3F4D919 +:10D21000E8477C580FF4C42DC3C0EF3EDF979F074B +:10D22000E85C3EB6148DECA5958FCD4538DFCEE495 +:10D23000637ADFCD9DC8474D37E4A3FC674D74BECC +:10D24000BAB84BF59D18472C36DCC8EA607C239EA3 +:10D25000FD5537DC6799F9AC85E8EA0D0D3DCEE761 +:10D26000D5271EE7D56A7FFA727DE5ADCD257B21F6 +:10D270001AC03B03FD2D2E31D17A44EC6626BD2722 +:10D2800086D9797D1716BF10ECF2E2D01C09E9EBC4 +:10D2900056E401EA25E4B3BCF049B7E1B996C30B03 +:10D2A00012691FEC6416DF079BF5D0F361E87F7EFF +:10D2B000358F9FEF9E8DF976709DFB6FEE7B552924 +:10D2C000F976FEB7F6BD9EE8ABDC1B6ADDF7E2E758 +:10D2D00040F72CC8CCE278619205F1143780F072E7 +:10D2E000AB95494180173182A5A0FE51F7BDC45FBF +:10D2F00073FD241A045AA71FAB91297F415E9895AC +:10D300003FFF35BFB7273E55C8681F2CAA9AF6C104 +:10D310004211AF18BF159813E5E768903DEEFE7413 +:10D32000E4BF20A2E7CCE7667DFA872CA4DBD828EF +:10D330005D3C41E13FF5FD13B537D1F84E08CC8691 +:10D34000F63EEF8FA923913E4DA2EBA9BB496F0694 +:10D35000D3FE39B3797F3718E099B5B0CE66C837B8 +:10D360003DE212D2DBFA99B9F0E114A477DE1F8313 +:10D370003C78FE66C6A2A0D5780EA3BC91DFF39ED2 +:10D38000B6EC7B3A8FCBE28DD518E7FC7A51103F93 +:10D39000A7BE7530F1CF34033FE7C2E2CC145F2A59 +:10D3A0000F51E05E39046BEE2F99911EEAFD9BBD93 +:10D3B000A857E0FBC7557CA0DF887A573D47CFAA26 +:10D3C0002594FF6283D0E139AFBFF5E5FEE9B438BB +:10D3D0003B9D17AD78CC625F18CFE92C0EC2EF32BF +:10D3E0005A1755187CF9ABB15F0393B6D970FDD0CD +:10D3F000528AEB6DB63595F210541999D11C01CFB4 +:10D4000025AECFD4F1544985B7123F19D921630411 +:10D41000E2B1E5D316E48F85A112C6452ABADA5DDA +:10D42000D46FA8D5C6ED84F25D1C7B22F281DF1C8F +:10D43000817CF0A960B0F0FC030E03D49F63BCBEF6 +:10D44000F53B8B96A5D3BCAD36C3881EC877E7F3F2 +:10D4500057C37BB73229A107DE135B1679E724ACEB +:10D460007F4D24BD04C2F4580EFA7BAF8999B84EA3 +:10D470009DB66C0FCD6FCEE6017883804D7BFD00AD +:10D48000D9A7390A7F7995736B25006F463C2A7AB4 +:10D49000C125B26A8A8729786CC5AF525FB1CC4486 +:10D4A000F4A8586C213A57D4FE8DFAAD086DE98680 +:10D4B000F4A8D866A2FC1DD61BF83C4A6A7B0F3B39 +:10D4C00004E32E3185DB0478542E8F35235C5E2FE8 +:10D4D00010AC7EAF62D95FBB19D2797F585A0C7CF1 +:10D4E0009FB5ADDFE838B467A75F8D8C9BA6A1FB25 +:10D4F000E945DBC370DFF968902719CFF9FAEE0F21 +:10D50000B2E3B942359E767A5132BF0F646B09C5DA +:10D51000FDEA19F31223D0CE1DB679CC587FB8217D +:10D520001E8FCC3187CD360C6187F146824F2BE7B9 +:10D5300048E80FF3070A9C6FCA5FDD634E80EFF582 +:10D54000BF81E3E7EC6B47F70E417C001FD950FF2A +:10D55000C4B5A4A01DAE30B4A4C4227D5E16C85FBD +:10D5600080F5A903F38F54225F0D047DA8F055E5E3 +:10D57000D6EDF3513E2BDE3C998F783D3B969931A9 +:10D580003E56A1CC1FD68FEF1AA17DC59675F98C9A +:10D59000BFFF2EF29D6AEF015E6402B8D9CCE18C28 +:10D5A0001BB87E6E367B29EF5DF39D8CD1FE999181 +:10D5B0008DC47640797E0F401495FB69D531137880 +:10D5C000DE3D597B7EAE12EBD3DBEA3BE39BF137CA +:10D5D00018143A5BC82E8D47BC00EC5DB62D0CF9D3 +:10D5E000E2EC6B7BF60E41B9D822D898561E54391E +:10D5F0008CF3F17AC0DF1388BF2DE7F3310FC5EC50 +:10D6000033A112D250C5932A6F2A5EAA18C7838A03 +:10D61000972AA38227A5DEA9E0A19CF9A83F76A6B8 +:10D62000BFB411FB7FF347DA6F3B3B8D09FC9C30A5 +:10D63000CF8BA6CECF15A1DFDFAFBD81F3FD146583 +:10D640009EE5366E17CBA398543B80F8CC6156F319 +:10D650004B4293B39B8FE8C6BF5A9183567AE33C03 +:10D66000609C5E03BF2718A8BFE6297C75A476B22C +:10D6700007F5CA6C19FAC94279B04DC17D4EF6BAA8 +:10D68000A8E86FB0999AEFE6BD7284F81074971409 +:10D69000016B16D3261807FA5F677A53BC30AFBB0D +:10D6A00097E6BD718C8D19409F1C11BCA13BD01E0B +:10D6B0003C24929E52C7E9903F247A381AB87C22C3 +:10D6C000BF607CB0552F048CB75619AFC560F7E228 +:10D6D000B960B650A0FB6BE2C2B3A187B8BDA34846 +:10D6E000625BFF37BD8BFB918E8B61924035762359 +:10D6F000B6ABBC189680F6FB88127738B2787B58A8 +:10D7000089860E4F75F69D258325A47F5EC8A18767 +:10D71000518E1E53DA359BED2317A03EB81426E137 +:10D7200079A9E608391DFDA866035BCA22381F1ACD +:10D73000BBB5E10FE485F007F5D293B636B954C70F +:10D740000D74F320DDA0BD83CB919DF6312AA3F8A3 +:10D75000BEE8D5E529D34BFAA95690D667B5B5539F +:10D76000EFE53DAACC9B64A45B9B3D40FE447B67F8 +:10D7700051F21805E641BDB557D738C45F5588D575 +:10D78000804BB8C0FA40B86D3D556D443F9F2D8A1F +:10D79000D9ABBD97763448A6FB67BE1E225B0FF45B +:10D7A000A8BDFF7D7E9EB791DFDB52ED34FCAD68F6 +:10D7B000E53F78AF2CEB7C3EEAD717732D74AFA909 +:10D7C0006BBF04FACE29D6601E8EF6FFDB96FC30C6 +:10D7D000A96D7D72D3458F184EFE42BC6E7D507E82 +:10D7E000E65D92E70AD642F7B1A72D3B307630D2FC +:10D7F000FB25139D1F98511F4F76EEE486E999385B +:10D80000DF698B93099EB5F13E0E2FE3F90FA72D2B +:10D81000CE7E01FDAFA3418E7CE467DF4AC186EB7B +:10D82000ABA11BB31FB907EA8786F6E98AE3FE6A54 +:10D83000C3D1B148F7AF1688A49F1C1B9EBC13EB45 +:10D840001D3B44BC3106EB19DB2398D79419C36DFB +:10D85000E817A8E70BEB4C5CDF9E51F4C231454F53 +:10D860001C53F82FAFAE2E05FD25DF3AB047B8EFB9 +:10D870006DF695D2F96EC1665F0FFCF2AD2013CC48 +:10D880006CB684DA5CBCCFB296F2E39C4BB6D8D0CF +:10D890004FBED7C2ECE8D7DEBBBBF7405C2A38945A +:10D8A00075D5D848FE5D155FEAF74F2BDF65E28A34 +:10D8B00052DA7788941250BF352BE7C68F2AE33DA2 +:10D8C000B9E8A53BD12F38B929398269F07E52C910 +:10D8D000D3340BF4E0960ED67BFE1BD4B8839BBEEC +:10D8E00053A6C403F799EA7B61DECFC0FB5D27D660 +:10D8F0000559313F6FE03DAF13266E3FDADDF7DAB1 +:10D90000A18703F3DC068EA7753D1378FFBF5F4840 +:10D91000877EBC2A6781EFB7BB4F9E746DE7AB3043 +:10D920002F19DEF7DE7303A3F74606FFEB0DD4D7FE +:10D93000A5F5161BDEBF3F1624D17A48CE66D24627 +:10D94000B43356291CD7F3C7F665D2F9BFD22F19C5 +:10D95000C955E956D18DA98ADF5D99FAF83080EF73 +:10D96000DB6AB2E3FB2757ADBC938B993ECF420EE7 +:10D97000E3F23913D6491E5BDBBA2870BD347BF560 +:10D9800066BA47F84BAD97D4385220BE73FBE9F323 +:10D990002D04DE9FDB0D6C9333B03DBECFD4B86851 +:10D9A0005DF45D4D1995B90DEBF26225BC4F71E444 +:10D9B000B1A12837A1E1140F3953534D9B78DFED06 +:10D9C000C8BC8CF743DF0A09B7A1BEF8AE66817206 +:10D9D000B940E113852F6FDADA24C6326ADF3814D2 +:10D9E000DAEF0A09A7BB2E498E9C70B4F32A5D03B7 +:10D9F000EF37ABF33BF510A7AB3ADE539BA687A1FD +:10DA0000DFD9B426B23117FA9383C36DE86FCF54D0 +:10DA1000CEBF1C5FCDF5CDB7D6F017C6E0F999B5EE +:10DA200013BBE1BAEE3E93CF6C877EED6F1786E1B4 +:10DA30007AFF1BA3370CEF1B7F03ED3D68278C6E2D +:10DA400011F5DC900246FB78433C4626C5D3963957 +:10DA5000F145EE19A31BE97ADA7371CF15E4A3330C +:10DA6000068A770166F65C81F6F6D03E1427BC6F15 +:10DA7000275F6FB27F75E1F501F7169FE8C7F5D212 +:10DA800089B56F8CA3F5F906930DC7F9DD86BF76CE +:10DA9000C37338B3193F5FFFED2681E6311BF831C0 +:10DAA000281EF5038F83CE06BD6F15DAF361DEA65F +:10DAB0005AE2C3D9C08716F4D31C3C1FF36CCCC701 +:10DAC0002CB176F93FBA2A7C3707F80EEFEFFED279 +:10DAD000793F96F70B3CB7CAF950A5BB8A1795FE5C +:10DAE0006D7CC874F905231A060C8F656DFA40BD6C +:10DAF000DFC18CDE15784F63BE185A8FF9AAF61B6A +:10DB0000ABFF48795B6423DB48F69CA561BEBCF99A +:10DB1000E20D768C07D699AB5BF3BA607D605E1739 +:10DB20003184BF5F88F98961BE21E9F1F4BD09360E +:10DB3000FB2844B729CA4B710131CFE0A07B79752E +:10DB4000165A3707EAA15714FADE86BE03FA3DFDDE +:10DB5000F8796DF5DE9F5A82A1E98DFC5E181C7183 +:10DB60004982263B5EF9FC0EDCA72D1C1AF1AB4462 +:10DB7000F87E53BF2377E0BD8DC2CC886D0900EFDE +:10DB800079E5EFBCFEC6886C13FA01C2D7778C44E6 +:10DB9000BFB19FE3CD7E9AEFA8FDC2F39DF8FCF3E1 +:10DBA00038D7DBFDF8BE6929D2FB9C10C6F3BD2532 +:10DBB000F9280EAABEF7B1C00EBF25B4C15E138B03 +:10DBC000C3BC06CDFDB83EEDAC8C4A77ECE5DFD7A3 +:10DBD0003F470A7D8FEB4C65FFC76095CCE8FF3966 +:10DBE000ED663BCFAFC89C56F0ABC62BFC5B62BD6D +:10DBF0003C92EC6F35B35B3081C952FD7DACBE6D9C +:10DC0000F7F6D65ECFBD3D26F33C7C754A1EBECEF0 +:10DC1000EE510A8DEFFF88FE65E0FDA9CCBFB4BCD4 +:10DC2000897C320EF80AED45560B87C72B7C52B122 +:10DC30007D2CE57B9EFBB1C98D7EC22CC51F4B722E +:10DC4000756112B4BB04F28B7AE1CC384F0AEA8FCB +:10DC50001335AC3E09145681D5E543BA34C7BF4FDE +:10DC600079D14EACAD0B43BFE72CAC27C64017E5CE +:10DC70008A7FCF2E8B9E5BD00F8EEFBB7EB986DF67 +:10DC80007EECC7EDFF99784F1CAE6FE4780BCFD7D1 +:10DC900078790FE5792E48189D8D71A4FD353BD814 +:10DCA000D1E4B6F73ABB8F32C43082A56BF625C7F4 +:10DCB000193B3EA7F1AD9A4F7303B7DF16633DE5FD +:10DCC000D1025256D712ECA4B8520CF228C687A53E +:10DCD00007085E328BD9E81E6BDB3E1DDD0755E978 +:10DCE000EFB05F1989EDC601FD51DF18AC3E23C2CC +:10DCF000CE027E3EA52F100EF5894AFF51E2238FFA +:10DD0000211DE62AF7B8E60AD51C3659E99C6BA016 +:10DD10007EC4B86631E94D796F2EFA63A02729AF2A +:10DD200082A21725F81FE545CA5967A66657CF8B0B +:10DD3000B437F73FD08F19E9FA3CE22A9D54FFAA85 +:10DD4000333AA97A12E835E87AE8A5E6299BFB2C54 +:10DD50008F77CE7D767ACC40C21B481CFA43317F48 +:10DD6000A2B8CA4C650E6C6D24F1B1698453427D32 +:10DD70003B76472C93E0D1AC1D029D6F1DB32392DF +:10DD8000E0307F0F9E5749B1F7635FEC3E02E393AB +:10DD9000275FF8621EE6BD1FF35B46F16343700820 +:10DDA000E59B104728791CC490F7F01EEB05C95875 +:10DDB0008DF6CAC9DAE50F3010FD9BF9395958E5DF +:10DDC000C99C4EFCDEDFDC7DDCCECF1DCEF7052FFF +:10DDD000E01BD0FE429148799A9E0ECE20FFADEE18 +:10DDE0000E13DD8F60B2E3135C574D52F8C112037E +:10DDF0000B4B0DBD822490570D7D1E0D7AEC3D1707 +:10DE0000F4EF857597D013FCD8B4085DBD510EFAB8 +:10DE100006F3C79A62449B1BC61F6AEFA9EBCF2982 +:10DE2000969B309EC25CDC8F56F98B89678C746F31 +:10DE30007E18CF5F71C724FD3D49D3B0F323C9DEFF +:10DE40000CD3FBDFCEABE46D5AA0F2535FD657C9BB +:10DE50004B4FF6FFC2417E3F4462CED5AABCA0FE26 +:10DE600007EFE669C4CF9DCD26E696087FAF61FD3A +:10DE700005D962C37840AB1F9E04EF45A191B4124F +:10DE80009F635E50ED3C312FA8162F9817540B63FB +:10DE90005E506D7BCC0BAAADC7BCA0DA7ACC0BAAC6 +:10DEA00085312FA8B63DE605D5C2981754DB1EF381 +:10DEB000826A61CC0BAA6D8F7941B5F59817545BD6 +:10DEC0008F7941B530E605D5B6C7BCA0DA7ACC0B60 +:10DED000AAADC7BCA05A18F3826ADB635E506D3DE1 +:10DEE000E605D5D6635E502D8C7941B5ED312FA86E +:10DEF00016C6BCA0DAF69817540B635E506D7BCC47 +:10DF00000BAAADC73CA0DA7ACCFBA98531EFA7B646 +:10DF10007D0B5B948C766C67BCAB393D1AF79DBE6C +:10DF2000257E3E742FF033CA61F3441BE52FBCCE2F +:10DF300075624BBAB26E51F8F7120B9982E7D03B7B +:10DF40007B5FE5CF97F09D6CB2074B897F59683DA9 +:10DF5000FA738F1A1D741F4A6EE0F7139991FB0133 +:10DF6000F345C5FF51F242CC1725F2033077B0518B +:10DF7000339EAE0E2B336AF0105960D3C1D1CE1848 +:10DF80005DFBEE93245D7D0F579AAE3EB6CCAE831B +:10DF90007B57E7E8DAF759E0D0C1F17281AE7DE254 +:10DFA00052A70E4EAE9FA46B9FBADAA5ABEFEB2E35 +:10DFB000D3D5F7DB54AD83FB372CD0B5BF7187AC1D +:10DFC000AB1FE059AAABCF6CAED7C1D92DAB75ED65 +:10DFD000071F72EBEA73BD9B74F543BF6DD0C13769 +:10DFE000F976E8DADFE2F7E8E0E16C9FAE7D9EF5D6 +:10DFF000631D3CCAF699AEFDAD314774F5A3A593F8 +:10E00000BAFAF2D3DCBF6775B03EC0386508CFAF4F +:10E0100051E9610DE85FDC9E765ED7DE1405EB0505 +:10E02000E09F0AD087E8F7FDD0258EF231B3EA30C1 +:10E030003BDEFB964754FF517BCF7BACFD47DDF7C2 +:10E040009F0E0EF304D1FAC24AF6F6A6FEFCBE59A4 +:10E050006B3E11F53E3BF3B198280A09F9D03F1207 +:10E06000F01796000E73F0BCD0E00791FF6403BF79 +:10E0700008FDCDD67591213E1EED72709B5FDCEBE5 +:10E080008A26CFCBD5FCE2DBF1DBD994A7D7D11F11 +:10E09000CAD90D9BF3719D358BC94B703F51CDB3E0 +:10E0A000B83F481FDF52CBD156C0AFE67BFB82EAB8 +:10E0B0007B0DFC19791F6D3D43ED5BFB55E25F0263 +:10E0C0004C76AEA6FFC760FD6704B9AEAF01F90399 +:10E0D0007FE8891A1BC1AB6A62087EAA46A27275E4 +:10E0E0004D1A95CFD4D8A97E6D4D0EC1CFD5380825 +:10E0F00076D71450B9BEC649CF37D44C22F8851A0A +:10E1000017959B6ACAA87CB9A69AEA5FAD5940F0F8 +:10E11000EB3532950D354BE9F9969A7A82B7D6AC44 +:10E1200026F8CD1A37953B6A3651F9E79A06AA6F59 +:10E1300004FF0DE15D351E823D35CD04BF53D34252 +:10E14000F0BB358708DE5BE3A5B2B9E65B2A3FA8E2 +:10E15000F151FD5F6AFC049F51F621E6F71774F751 +:10E16000F154D8C88E717F0FF356601E861CD3778A +:10E170003F971F37900EA794FE4D23C05DC23872A3 +:10E18000CF94F5759A75455D7F1EB7AC35F0FC2DC3 +:10E19000B53D99AD8EFC7607E3E7B4B8DF3E13FFDB +:10E1A00025C1D3A89ABDB8DE28ADE679CAB3911FC0 +:10E1B000D3881FFF725DEB34655DB025D1F904F2A1 +:10E1C000230B717F1A9FD5768FFE40A2EBF7F8FCE8 +:10E1D00042F57D7BB1F54C9B3D053F32D6E289C6C9 +:10E1E000FC5FBE7DA27DBDD4F9F7AA94FB0F9DD63E +:10E1F000EF3AD90BED55C14F22C5F5F79B4227E108 +:10E200003EFF8B0A3E5EEC6FD0957725395FE88F35 +:10E21000FBFBC9D52F3C20B4DDDF1F8F4B7C90EF7B +:10E220004226511E9C89CCF11EBAE077802388F0EB +:10E230005D4CA6F24482EB4F389FBB610182B06B0C +:10E240008825AEA3F9048E67A7329E9DCA38D47282 +:10E250006E927307F6772CD9A11BCF8B4A7EA171E2 +:10E26000CCF71C8EEB1F6F9F3F2E24B6E1BB359E73 +:10E27000C2AA294F4631E3F19447312F46545B5EE1 +:10E280000C75FD50BC8FFFCE11FDA1FD9C1F4FEB07 +:10E29000DBC0BC194B86EFE17930603D86F77F8BA0 +:10E2A000EFFF15E95FFC3D28BCB73BBFCB61CA332C +:10E2B000E39D05BC1A4B793578DE1B17203096F2AA +:10E2C0006A50BD7003FCBF078ECB9A66A4F175A19E +:10E2D0007C274F07EFA7BC341853B074C5BCC7F1F7 +:10E2E00034CFFDCEF3DCEF8EF2D1FDD42D89AEAF6D +:10E2F000FAF338F953991827427EC2EFD8DC747EBE +:10E300000DF8C92C008A6646013F75E06FA87C5362 +:10E31000A9DCC3519F033F9E407C7FB773701AF204 +:10E320004DD5AE5C09F15D67E0F7E9E40F947D41FE +:10E33000E5F710C4F0F47574EF009D71A46F6E28BA +:10E34000DD3B6812D982CD1DE8576B06A7F3FE1896 +:10E350009E4FB22E607F52C8E07417947663DFD967 +:10E360004779C82A9B79BC9A6579D39D1D9CCBAA15 +:10E370005AF0DBA79234F3A8DA71849FE762DE7467 +:10E38000ED392E49E957E53FD11CEA5A17A21D5F26 +:10E39000AB1C5832B2490E8EE3BDEE711629FC2E2D +:10E3A000817E1FEC3BCC2FE3FAA38DCE03AAE702BC +:10E3B0006730279533C17222DF3BE595747F7E3647 +:10E3C0006BA0E79539D3E310AE62BE9131B83E5AE7 +:10E3D0005AFB1E868326D6AF1CD503E635C13DED1C +:10E3E0003D2C0B3708C76589E42806BFEF15AA172F +:10E3F000F784EFDDF3EAF0C518B71E27723AB00FC5 +:10E40000391D8A819FC588F6F303B9E993114D72CE +:10E4100043E357E5A6782173E0F903F57E48AB1C8A +:10E42000E5CCF97B2CEEE1803F89FC5AB5CB12415B +:10E43000EB53CC3383FA4A919FC546EE5FCA98DA14 +:10E4400094F427F7374C0E259F17E3FEC81C99AFAD +:10E45000C74E99B8BC9DFA2AD48DFC3DBFCBEB7159 +:10E46000241F26553E7E9A42E77B18F81F37B7F7E0 +:10E470003F5AF3CCF462E46FB03857CCC0C4367B5B +:10E480007ECAE01E14C6F3F23B105F7B63F8FA7994 +:10E490000EE6A1C1FAAE4E09E3A5A7A2AD745F28AE +:10E4A00030CF1963769A9F49991F8C6C12FAD31654 +:10E4B00025AE561730DF1F82E268BED270D6C0D0BC +:10E4C000B130DAE4E928F70F703B31BFCB6F5CF86D +:10E4D0007D6F10B30943693E148F950DCC59C7E386 +:10E4E000B334BF0546AB0DCFE52C99267A05B213A0 +:10E4F000304E8CE74559ED3CAFAA9A7F3B70BC0E7D +:10E50000FDF8AC710CE7E710992F68281F2F8E4F8C +:10E51000067A107D009EA6191FF4EBA6FC3FC1925F +:10E520000DFDB0E67F3DC0E3CBB5DC7F84F16F220B +:10E53000FAF480F1C75E7DFC26645118FFDC0CAE56 +:10E54000A7EA700751443BDB95F4EF8420E7FDC850 +:10E550008749AEE5BDE6625C23D762C7F81DBB5CA8 +:10E56000D70BF554089328AFD63807CFAB05DD2D70 +:10E57000427E28C4BC7536F203CE68F3B0B180F891 +:10E580001A9085E2AB1330BEC6EF12BD8BF1D9896C +:10E59000CAF9E6BEEC4B157F145F13717C14AF769D +:10E5A000D1382D4859288330CE437470D33C82999A +:10E5B000478967B7907FB052E1C3218718D9892175 +:10E5C00021DC4EEC3AC2DC78EEABE9C73BF342A16A +:10E5D0007ED77923E929C013E503FCF35FB95DD940 +:10E5E00075F2782CEE07D4FEB83716FDC45D269779 +:10E5F0005885EFE75A6C0BED6D718DC643213CAE2B +:10E60000A3C4F96E52E6D9C85AEAAAA03EA787C8A1 +:10E61000300E987DD0138CF28C396A3BDA6F1C7601 +:10E62000D1ACFB5D0B934D0FE7300D1C8F21B280F9 +:10E63000DFFFBCCE75EE6B199DFCEEE799A86BFA77 +:10E64000DDCF2C651E8F6638DFCC20BB364154F001 +:10E650002E20BE400F3421BE9FA930D3EF1A34556F +:10E66000987B7835E3AB9FF50FC2EFEE7FFD83EC2F +:10E67000D6EE6C353F4E43103E37CBA114777BE688 +:10E68000B281E26E6BCABEA6F5497D0EA3DF11AB67 +:10E69000BF5C427EC0A502869B48ACF6E6FF53866F +:10E6A000F0E33759E97B81E37F1BFC790F10EA2DFA +:10E6B000F0E73DA9E0AF803F8F30DE67C5721BF801 +:10E6C000F358BAC19FC7F239F0E7B11DFAF3583ECB +:10E6D00003FE3C96ABC19FC7F229F0E7B1DD2AF0FB +:10E6E000E7B17C02FC797C0EE3CAA3711D62746FF2 +:10E6F0007F6170D832F433243994FC8D8F1C03BBB6 +:10E70000783576F6E68B061D9D879DD1FFBECD90B0 +:10E710006311BADF3FC9F9B2A7AE7ED0C1045D7DF7 +:10E72000BCACFF7D9B3E0B7EFEF76D62CB4604FCCE +:10E730003ECE6D01BF9FA3FF7D9B68E73D01BFBF3C +:10E74000A3FF7D9BC7957C992A1D53A4D782902F48 +:10E75000D6944D08671DF8176AF984420F157EF2AA +:10E760002171524771E4F01BB9BD7FE72BCBBE0D81 +:10E7700080CFDD2CDC8971F7DD0E03E9A5675687B4 +:10E78000501CD6E21D7212F967B78349C83FCF5CAF +:10E790001ED105C7331CC888CF63CBB87DEA79A3E7 +:10E7A00044FC1C5BE613F1BEE82D977D76E4C72799 +:10E7B000C3F8EF6C41BFEE85D0DF3B6307F5C5388A +:10E7C000CE3321C0CF286F1E5F7012C0E1570C0CF2 +:10E7D000F523D84ACAF32FFF2144398F7A85EEC337 +:10E7E00085A34E07BDB4BB8C7F3FC57B3958EB0F6B +:10E7F0003DFED3D5F0C288AF3AADBF6D76028EB77D +:10E800000DEFA01AA14C6165EC31C44739979FFA0E +:10E810003203C9D3259027C40FCC9AE8C25AF4F228 +:10E82000FE04CA87960EE509CB709ECFAC32D26E3D +:10E83000D928F1D57D37C22B6B0E8AB4CD2ED97C69 +:10E84000C11DF977EAB8D738F8FC22ECCC80762ED7 +:10E8500002F0E9A6FD6C7BADF6F7ACFEA0C8E7EFD1 +:10E8600015F97C5AE1075C6F233C4A5C3B3A05C7CB +:10E8700091C3F535D053C0FB58976630FA1DD1DFF0 +:10E88000172574E928CFF72A651CCF29F35A8BFD89 +:10E89000923C73B91F25160FC77ED63819E9F1359A +:10E8A0008EAF6B316E77A988F7DBE711AF80F8ED9B +:10E8B00055ED13B0FFDEF33C54BA9571F62C6BA105 +:10E8C0007AB53FC9EEE6FC5EFE356B86F9E2215B68 +:10E8D00091ECC519CA8FBAC668646887519F217CBC +:10E8E000C96AC43312ACE7AC630CEF33D78718693D +:10E8F0009F624DE5298257DA381C2657A7E3F98B2A +:10E900009DCA7CC264996077C07C52A4A9E1DADF19 +:10E91000730D2CB72B78DEA6E063A7C965B800E3BA +:10E9200018FC37917EBFA3B3F7543B9BF3A521405E +:10E93000FF74D1C93FFEC69E62171EBA11D7CFB26F +:10E9400093EC82BA6EDB3686DBD795C1533EC47535 +:10E950007F91C2474F078F7B0FEB0F8CE6BF83D3AE +:10E9600034FAD6DE5A3DB94319F77605EFB9B2E36A +:10E97000AB79D0BED069C191811973F4FE15F4E76B +:10E980001C23DA3D40B783D9AA3C388351EEDE1907 +:10E99000339D1DC2FE0BF8BED3B68289F45C62CEF5 +:10E9A000DBFBC37B9FB418C99F81E73F2B8FFB150F +:10E9B000FCFF4519C7070AFE9B153EDD8B76241523 +:10E9C000E32C6954BEA3D8118F6247762976A451EF +:10E9D000B1233BD18EA4E2BC2651B94DB12359A33A +:10E9E0009F243FE912E6C515D08E54B22530CE7C67 +:10E9F00018BFD8817D1B9F2306FC4E56B08E4EB7A4 +:10EA0000A745EAE0D1526CC0EF742506FC8E573F53 +:10EA10005D7D9E3533E077C086EADADFE21F11F0D4 +:10EA20003B627A3B32E4D804BD3FF3E53DBAFA419C +:10EA3000074B74F532FE03E69B7D8CF1FCB2C1C33B +:10EA40007E87FC927DDCA8FE3E33EDA3A9FE56A096 +:10EA5000FF93CD5AF7F10CB48F273309CF75D256F7 +:10EA60006582AE9EFCA78326672C9E3FAC2D04BE1C +:10EA7000C37388074BC730DA8707FE0579CA769ECD +:10EA8000F892F28D8AC599E4275D34EAF6D37203D1 +:10EA9000F6C59C23F5FB66D957D937FBFB8DCABE5B +:10EAA000433B7F2CE29AFC31902711C7FD74F09410 +:10EAB0003D88B79D9F713BD5F4D983B1F8FC5D6C5F +:10EAC0000AFD6CFFE641F2BBB6B7CA872B58EB6F65 +:10EAD0006DF3727BF1E6C1841DB8CEC88A16480F6B +:10EAE000661D993B99F8F1A0817E9F33A5A02A1855 +:10EAF000F1B2EDD0C260FDFD298D7E204269F48324 +:10EB000088AC1CA1AF8FD2F06102278EB6FDFF0545 +:10EB10006B92E82C00800000000000001F8B0800B2 +:10EB200000000000000BED7D0B7814D5BDF8999D19 +:10EB30007D25BB81CD03DD401226E161541E9BF78C +:10EB40002624611202460DB0101E414298243C5208 +:10EB5000AB3655ABD18FDE4C08841051A2B515AC45 +:10EB60008F958AEDEDE316AD045494E5E903840531 +:10EB70008346455D10D1DBD2BF28D0DA7EF4F37F27 +:10EB80007EBF7326D9193601FAB8ADBD37F9747254 +:10EB900066CE9C39E7F77E9D0321D790809DE0CF1C +:10EBA000D722FC3FD3D02E2081F4F076A9A17D831B +:10EBB000A1FF4C43FB2643FF3ADDF3ADA19983153A +:10EBC00027FD1B7E265E78DDDC4C48E0AABE7E3940 +:10EBD000669FE8197361BFDC6E53DFB8F4BF1D1F79 +:10EBE0002C319D4B20A4AB5BF4DB52E9F5E812A27B +:10EBF00066D371BA4D7E22E0D544E8F3AD3DAC6DED +:10EC000023AA631C7DBEB9DBECE99008D9CEBF3BDB +:10EC1000DAB770B02F869089E6D311BF2B9F37F5F6 +:10EC2000AD8FC07833079308FDB4EB4E3E6EA0D98C +:10EC30008ED76DCD2E12B0F53D176372BA7D741E5E +:10EC40005D219387DEA6F32F8D2774DDBB9C8B1D82 +:10EC5000302E9D2F214329163C49552D230991E83B +:10EC6000BC4D741D9B4326D241D7997D847D3FDBEB +:10EC700022C7BB22C09510931EFE178C477F004E03 +:10EC80004ED1DF41E1B2F38339F1E3E8F82F748B21 +:10EC900004E663551A1CBEB1B4DDC3E6A58D3BC9BD +:10ECA0002EEAE050421C3A7C149D8ED3B5B38FD12E +:10ECB00079D2F7ADD2F47880EFC5E64948B4818EB9 +:10ECC000E20CEDA1BAFEA3258AB7B1FDE3E1058E02 +:10ECD00087CD8007BAB017A23C55BE08F0DAFCA178 +:10ECE000B5C11F76FF3F3C142843E06AC26BF63182 +:10ECF000932740E173AEDBE401E0E5BB3AC5C6080B +:10ED0000E3149CD0D3676E77B40E5E44AC1E900FB4 +:10ED10009A8EB6ACDA1DD6FF1E4F4CC24907FD23B2 +:10ED20008FE4E1FA2FF2FE1F9BD555BB2D948E295F +:10ED3000C96EA2FD88AB9290C4FEFB13B29C325BFD +:10ED40001F1C892B9E2EEE52F0D489EF5D80AF7E82 +:10ED5000DEEF1B4765F0A4E0857EABC6F97EE88157 +:10ED600071423344F8FE838EDBC4109DF7238EDBA3 +:10ED700076017DEEFF935502BEDEF1A7AE24B8BF4B +:10ED80002F634B12D0FD3EFA4E10D667A658A36DE6 +:10ED9000ABBAC001F4F546F761E41F89046F1C9F0C +:10EDA0000D6D93A783767B39BD723019006EAF71FC +:10EDB0003AD9CBF97537E7D79DCD6ECEC7125E5FD6 +:10EDC000694EC7FBDB9A3DD87EB1D98BEDADCD3214 +:10EDD000B6BB9ACBF17AA8D987F70F365761FBCD2E +:10EDE0006685D161FA1D65208FCE255100D0752D25 +:10EDF000774C3347C2E7F5929ECFAE73EBF96C3296 +:10EE00008573787B927D98812F47E89E4FFCEA1AA4 +:10EE1000DDF3A2D399BAF684CF0A74FDF343A5BA01 +:10EE2000765ECF0DBAFE33CB2A75CF7D85F3F5F331 +:10EE3000139D285FB6BB0494CBD3B2EB75CFB7C399 +:10EE40001F2087ED825F4D05B8540E284F03801FA9 +:10EE50001BC091F1F1AB1C3F7B003F36C00B83FF21 +:10EE6000CB007FDA7E09E04DAF3967955D83259051 +:10EE7000030DD8B6A60F767A28FC5F768A28FFB7EE +:10EE80003437E27BFBCED59D1571BE0E09F0B29DE5 +:10EE9000CF679F45392B26405B90960B17CE2BA74B +:10EEA00047CFEFA3CB17A2DCDCDE7DDC01F4F6CA92 +:10EEB0005797A6F7B47EAF92CA49401FC5DD545795 +:10EEC000A55E5CFF697AEB62E36BFD40AF46D2174B +:10EED000C6716FF84A11095DC7CB3DEA0F62A01DEC +:10EEE000F89628D1766E8F3209F0B63B5D708902B4 +:10EEF000F69B24C3BCCF1FBE11EEBF12329B60DE57 +:10EF0000FBCFC71158C776AA776DB4DF1B64C49ACC +:10EF1000F114DE819E2FF7015FAA4E8B6714B97042 +:10EF20001E291922CA87CD636C26613CE83B330950 +:10EF30008C013E57109E5D5FA539E1BA395DE4F75B +:10EF400083C8EF5767B8F0BD97CF672640DB448290 +:10EF5000280F02674DE5FE08EBBD1ABE436548CE9B +:10EF6000F98F1C2EDA7FEFD93A07C897577AD8F86D +:10EF700039CB420E80D3BEAF3638E1FEF6F42C1CFE +:10EF800077C7D8A5685F6C3F6B42BADE3E669533A3 +:10EF9000331BD7E901D86D3F5BB72603E8BAC78CAE +:10EFA0006D89282408F496CEF4ECE6B375E4307D40 +:10EFB0007ECE23FA81CE7248E7DE4170FF8A555635 +:10EFC00092C6E06FBE82905BD9CB64924B2F074A0A +:10EFD0007BF4FAC41AAA9E3503EC08A067DA9E6A8D +:10EFE0008ED73DDFF7EEF2849980170A6FB8F7CA23 +:10EFF000D9DBF78D05F9E367EDDF1F7DDA3A985E1F +:10F000005BC6AE1A761BF4DBECF0D82478A2902F06 +:10F01000693BEFACD90FF6468E533F8F7D57572291 +:10F02000DC379F65F6D5B974B69EED9E7AF2007D09 +:10F03000EF656E7F4D3A36B202BEB79FDA4F60572A +:10F04000BCE4F94D7C16C833AFA8A3370A1FA497B8 +:10F0500073DD04C7A13F83A6523814B22E940F7DEE +:10F06000ADDFA1CFF7E5DB5CCB29AAB79FDFB9EB1A +:10F0700076DACE4B14894857F22DBF7E7EF93F7366 +:10F08000E8DAB77EA6B74B6C44E0FADC8972A03FA1 +:10F09000FE9970DAAA7B6FAAD9A61B378F843D47E9 +:10F0A0007C5AFB9EA75EDC3ED9C2E59A669F6CB196 +:10F0B00028F37D40D7C15917D1A3CBB9FE6D447950 +:10F0C000B195104F470695EB578B32F0E1B9A37617 +:10F0D0008463DE23332610D4D7CA04E00724C63065 +:10F0E0007BC07BF422F68A4B2509B9FC5304AEE6BB +:10F0F0009321DABF9DAAF9AF4187737D6E1CB73F9C +:10F10000BDFFA06310CAFDC232A6171E711C403D90 +:10F11000DFF501D5F302FB4688E27D36FC017AFF7C +:10F12000032BF67FE97A01E58866375412D94255F8 +:10F130001C99E63D6BBE9FE2CF67AF197B2BBDBE2E +:10F14000F46ED730E0DF97C03E40F9D0E860F6417A +:10F150008C1A4FA7B8ADC7867CB8E5B489D8C16F03 +:10F16000D866433AA57C7ADF58FA9D6D41662F74C4 +:10F170009DE6F6DE3607F2C98EDFB379742D733063 +:10F180003FE39455067B7CCBB21884F36829266054 +:10F1900086F19AD8F83D1CAF6F73BCEEE3FAEA75BE +:10F1A000AEAF5E057B02F517B32776813D41AF3BDD +:10F1B000B83DB11DF419BD3E7FFAB9F7812FCF6D6F +:10F1C0008B42BB733449DF04F3DAE6B4E23C8D7062 +:10F1D0009EA7E8F9606E95DE6EA818A3B71B6E189F +:10F1E000394CD72E4F1AA17B7F4AC2B5BAE765CEFC +:10F1F0002CBD3C324FD0B5E5F37ABB61BAF7463D42 +:10F200003DC9617603CA3BBDDF383BDC6F4C053C32 +:10F21000313F674BCFED88C72D47D3062B6176C2B0 +:10F22000560EE72D4799FEDC1AFA32468960477C74 +:10F23000C6FBFD96E3E314C7C77FA7C82732860045 +:10F24000BF7CC9E46F3F74ACBDAFBDF799FFE3412C +:10F25000E17A7DB828219368EDDF77BD3F1A9E5F84 +:10F260002A5F503A6D0F513CDF2DC67476D0575649 +:10F27000991B9F84B6AA9AC9C66C0447BA199F5FA6 +:10F28000E30179DC1AD3F85378BEB9C5E6DA900009 +:10F290007CF41FBF86761365051BBDFE312AC54F62 +:10F2A00028AB59334D38AF672CBE611ED09B826F9F +:10F2B000FEADB4BFBADEEAD9285D381F67A6A0311B +:10F2C000FB56D04322E7FB3F0B8A3393DE977F291F +:10F2D000A09C8E9208EA051BF105807F48833C1FA5 +:10F2E000F8839828FFD0EBBD594A1CF42732915C73 +:10F2F000741C646DFA3D21B8F74F029D978534AABE +:10F30000308EAD814A18CACF0F662889D8DF3C13EA +:10F31000C77F7E2A2120CFE872B09D7D177175C40A +:10F32000D2F911C5F4256DCFA7FE3E7CDFE4B80508 +:10F33000F5D4FBFF6DF28B11ECA55E38DF62391559 +:10F34000D2E82CED42FAE9E274B135D587F2D7F86C +:10F350007E6626F307B77C344D04FACAB60F92C115 +:10F36000AEA00B146750F9BEF5F80D8EDA08EF4D1C +:10F37000CEAECDCC1CD2D7CE0E6E126B9DE8CF8B0D +:10F38000B0AECDF46F58D78BDDA600E0F79CD38AE2 +:10F39000F2A4BF75E487F471883CB007C2F88D9081 +:10F3A0006AD7C96B01DE9DC2D7D786D3977C5F38F9 +:10F3B0007D3D7F217D219CEF7E2B1DE1DA2A30FAF5 +:10F3C00052297DC173B5B411E94B35115F6B36D24B +:10F3D0001BBEDF64B6BB6C54422ECD4C43BAE98AE7 +:10F3E000A9783F20E1F746CC447FAE86FB733528F1 +:10F3F000E75F3FC2E4BC715D3B8ECC1916027B62B5 +:10F40000D4DC61C0E75DA00086C2F473E7817DD9DA +:10F41000DBA6E8423B70328190157D9E3D4F86FE13 +:10F42000D76BED1CD6BF84F55F92F9F07A159E2F4D +:10F43000E0CF4925EBAFB5D5BC7925D0DF62C2F668 +:10F4400007BCFF431E7929D0E383197203E02F0321 +:10F450008C167AFD64BC7C33DC5F9A4970BD778D75 +:10F46000976F096FFF669C7C5B787B73AF9FDAC9EF +:10F47000FDD45BD12E7DBD6726DAB312F1DD087AAB +:10F48000E7F5208B476D1E39B01F7480DBF3FBB9A5 +:10F490009FFA06C8A3AB409F303F750FF7537771B3 +:10F4A000BDB283FBA9DBB95E7999FB492F713FE9B6 +:10F4B00005F053AF023BA48AC749989F9A3D6A5210 +:10F4C00019DA112ECD4F4D89E8A74EF7EAF5CD5444 +:10F4D0008F5EDFDC981E6FD02F7A7D332541AF6FB2 +:10F4E000CA9CD71AF44B96AEBF7C5EEFA7169F2D31 +:10F4F000D5F52F3CA5F7530B4ECCD4F55F9A2921B7 +:10F500001EBD476FD2F5CBEDAED3F5EBC39B0FF12C +:10F5100064551F77821DB779643DC71BB31734BC90 +:10F52000755D046FAF72BCEDE178DBC5F1B683E3C6 +:10F530006D3BB7075EE6787B89DB032F70BC6DE11E +:10F5400078DBCCE30B0738DEF673BCBDC1FDDDEC28 +:10F5500051BBD03F3B779A70BC3D2146C25B79924C +:10F5600068C083C380073DDE4ACDC30C784833E0D2 +:10F57000E11A5DBBF054A6010F05BAB6F768A90100 +:10F58000FE3718EC864ADD730D6F533DF30DF455CD +:10F59000AFEB77C9FCE66476DE5FCB6F7BB91DB756 +:10F5A0009BE36D27E00DE3441E1E8FF0F2B82FB3EE +:10F5B000E35EE478DBCAE3425D8037B0EF38DE5AC1 +:10F5C000479E413BFEDC790D6F0722E2ED72F9EDBB +:10F5D0003AB73E2E34D9A58F0B4DB2EBF9AD84E886 +:10F5E000EDBB895FE9F9ADE8B4DEBE9BF0999EDF23 +:10F5F000F24333756D6A0724640D013D7593EEBDCA +:10F600009C609DAE1FF59398DFE2E17ADF5F89FA97 +:10F61000A86D2AD38F940FD1FE7EE67BD40EC8E866 +:10F6200083C7F306FFE9F97EF4F7E82C66D774BDCB +:10F630005F8370CD01FD1DA15F06EF9791E5C2AB21 +:10F64000CD4CD4E84C9CE6EEA1743EE691CCEE3174 +:10F65000C7AC812003FC044DB97D7692E8F4111803 +:10F660009FDA4B195961F6A0D9D548C06E106D0FBD +:10F6700055C3BA8868F2A0DE35D847A4C125DF0E8D +:10F68000F76F1FE4E9A0B05892158BF370934D16F5 +:10F69000B033EECD920B605C711283C7E664EABBB7 +:10F6A00053786C8E626D95C26B236D8B83AB117E2C +:10F6B0005D145E62068C9F40EEA2F3AACCB2323893 +:10F6C000CC235C9F6ED4EB43301868FB9968D69EC0 +:10F6D0009DF5CC3C35A94FFFD6FCA66BBD4AC7199A +:10F6E000ED1C5A4FC6D171D7A97160678EA1F30383 +:10F6F000F968726C4B8E647FF76787A9E3E4594021 +:10F700001F7771FD3A9A42C49CD9FFFBCF44FBBEE0 +:10F710000DF8CD067884C5BDA66631FBAC12C6C90E +:10F7200041FB520EB72F49B012DB6D198CBE7EB271 +:10F730006626D29B93C24B8C85F933F8CDBF93D10B +:10F74000D7E5AE439BFF0074E20BB7A7C3E8E4AE76 +:10F750004874422A3C6EF4D7FBB3E75436DF566E4A +:10F760003F6A76B22D49B39BFD1C0E24501087577B +:10F770003299C235CE45305E53E332F9FD146451FF +:10F78000B19902CA9D3281B852617499303C564891 +:10F79000E1F2C7181FF41E8D36C8F738831E1EAA63 +:10F7A0006B179F4D33F889D70CA8E7CB9C130CFA45 +:10F7B0006992AE7F79D28D063FB6D2E0E7EAF58452 +:10F7C0009998558E2F13C62D544132E7C27D82F889 +:10F7D000097B8E7E672F9C1F93AB905FB95F63E4BC +:10F7E000D77BB32484B3E0627E8DC60FDAFB1AFCAC +:10F7F000AC6E86D7B5B99A7EF2A0DEB105BE4520C3 +:10F80000AE4A6D68795318BD6D68B6BF5F368A9091 +:10F81000A79BC9FB651479FE66175E9F6876E3F5C2 +:10F82000B16609AF8F36A763BF75CD1E6CFFA8D92F +:10F830008BD7879B65BCFF507339B63B9B7DD85EE9 +:10F84000D35C85D78E6605EF8F342BAA9DAE6B6493 +:10F850003BF1A87429A33AE9F7C2E036A29DCE2372 +:10F860000CEEA9AA4BD71EDEE4D6F54F6E9474CFEA +:10F870008735A4EB9E272A1E5DFBCA2AAFAEFF1078 +:10F880009FAC6BC79797EBFAC7CA3E5D3BC653A5C3 +:10F89000EBEF485774CF7716170C0E0DC0C70F3516 +:10F8A00007820C2EC12083D36B41069F1EBC9E0293 +:10F8B000F94BF118670EA2BC88CB7651D2A1F8B2F1 +:10F8C000B3FC5ABCD923C4868D1F5F4EC74B0F9F14 +:10F8D0002F1D4FE79FF9915E623C41DD7D477A8F96 +:10F8E000EEBDC9A2B314F211870A458C7B1D2A8C88 +:10F8F0008F01FBE53E8B6B6A36A5C7834744CF0675 +:10F90000780F5E88202F8F71BDE8186747B9307D6A +:10F9100085B04144A265EFD7758F8818F73CF87D14 +:10F920005205EB72EC7C4102BA985E581B1F15E63B +:10F93000AF4D0FFCA9CC0DF75764E446D1D1A6B763 +:10F94000A75AEBC7F4AD4BEB57B7426F5FF6D1BD8B +:10F95000DF0EEB18AD7EDF0EF2AD236903B63BD2AE +:10F9600007CE93FC96DB619F713BEC248FC39CE038 +:10F9700076D871EEF784B81DF621B7C38E72FBF905 +:10F980003D6E87F570BFE76D6E3F7773FBF930B75B +:10F99000C33AD29F9B82F2F097021123F8A9DAF5BD +:10F9A000DB3FD3DB61DFF2EBEDB0A5EBF476D8E221 +:10F9B0004EBD1D56DFAEB7C36A55BD1DB6B0496F0B +:10F9C000872D68D4CBC3F90D9374ED798A3ECE367A +:10F9D000B74A6F3F6BF899EDD3CBC5CA72BDFDDC5A +:10F9E000DF7A5F0A5C8FF91F40E2C7617AAF379F09 +:10F9F0000B7A85D245F679AA57300EEE6B85FCC995 +:10FA000056E842F56F9129F816E47DC8DB2281B8EB +:10FA1000D3CE73B915D323D05FAEAAA79BEAA3FABE +:10FA2000F8C64D77EAE13AE316BD5F622DD7C355BC +:10FA30004ED2FB2595463DE3D3C355250A01BA3482 +:10FA4000EA1B93E31609E4F7E5EA1D2BA17A85B5D5 +:10FA5000757AC70A77D274CF51EFB467B3785D2E49 +:10FA60009D07180B2D5179FB3D146E3BDF35639DCF +:10FA7000089DE0E19154FF14C3DF147E2F5B14B5A1 +:10FA800011F26C3C2F42C453BBBE43FB5B87B1BC3D +:10FA900008F9CA7C02C657E82FE02B97D076989ECB +:10FAA000CB09B2E761F3D53DFF31E06CC0F9C887FF +:10FAB00047E6FE4FCE272601EC21329E8CC77A8383 +:10FAC00050DC25C5578DF7B303CC0ECA4E62769035 +:10FAD0003779A6C8F34F04421E5E13B1633C3385E9 +:10FAE000F837429C337ABF631A6DB6C29089E0271B +:10FAF000E9F97F56C5C0F979A31F76BD34C2E0B7D6 +:10FB00005D6BF0EBF4FC6F2306FB254424B027115A +:10FB10000726DD7384D3614E472DC7DAE6C3BA5E8C +:10FB200048E6F9154E3F1338BE08D9B4AB963EF7F8 +:10FB3000BA4502FE868DA8F1E3A1BE28D82843DE8F +:10FB400021CF6B7321DEC4651EB44B4F31FC78E9C5 +:10FB50002FE0CF4BC2F005F83BAAC79FCDF0FC24A5 +:10FB6000A7A70BE7C5E8E89F372F035D39E32EA968 +:10FB70008EC578BF24288B31747E7B5C02E651F7FA +:10FB8000041B8325B47DC6CDEA865625CD34E37C9F +:10FB9000893C6832C5C314BE5E2FCF6B753513B474 +:10FBA0003B9E6FB6E395904611E4519BFBF678D0EF +:10FBB0008F5D29CA30A84FEB1A12BB02F2F39B2DBE +:10FBC000B14991EA5A7658F2509F76ED48344BF499 +:10FBD000FD12B3CB0CEF9524D589E0EF5DD743D070 +:10FBE0002E28492298CF7ABE3970887D4FC13A1CA1 +:10FBF000BA8E49609F96B96A27C524407C96DA364A +:10FC000012D8B9B1E8BFEE1E6243BCD95C4BCBBE83 +:10FC10004BD7772051248297E2C7433C01D0034958 +:10FC20004E8F1F86735B8E039C1BE8EFD7697D7A2E +:10FC300081F2F9F1707CE491B036E615F4EDA1396A +:10FC4000BC0E8AE347220AD659B4F5B0FA32128ABA +:10FC50009C67F988DB0D5A7CFF28B71BDEE371B780 +:10FC600043DC6E6833C46FDEE276C36E6E37ECE55C +:10FC700076C36BDC6E7883DB0DFBB9DDD0EB2F1028 +:10FC8000B505F28AF3883D04FEC2815A0667F70A79 +:10FC9000C15F0EF970A5D3574AEFDB5658507E0E60 +:10FCA0004F525B203E6EAB5227C33ADCD59D2D7080 +:10FCB0006D29EE4884FBF3949347C1CF067A999A55 +:10FCC000CBF99DE261AD95C179DDE218CF72A067F5 +:10FCD000654905F64B6270B3D35F8077E222550029 +:10FCE0003A702B161DBC6B0DF09D07ED30F9110D10 +:10FCF000F448E179BD06F72C92C5E0AE4601DCA3DD +:10FD00006A39DCD31322F2C93A0E770D2E3B8A6F83 +:10FD100036A9B4EB5B49AC6EE2ADC29B4D07E8FC83 +:10FD2000BB6511F3AFDD49BC4E907FD738DE3BDCBD +:10FD30009E5D5B3A70BCEE20EFD7DB6E27926D7054 +:10FD4000D838A5F75924FA7E55607532F0C5DA41E6 +:10FD50005A9ED883F6F564B1F0CD543ACF20AF83E4 +:10FD6000D4E4E51CC26163F8DE5B7C9DFDCDE7ADAC +:10FD7000D21B2D121D7756E01E02DFB3991BDDE169 +:10FD8000F5A5DD7C7EAB66DC41802F8329A71BD0E7 +:10FD90008FF7D924B0BB87277956021DB89314CBAF +:10FDA000F7E8FD69541E4A2E9856E78E04E847DFAF +:10FDB000799400BD5CB309E8E1AD643BCA9DFEE601 +:10FDC00073811EF113B447FAD32354FEA03D64ABF4 +:10FDD000F8F428F8B595A4D113A0EF05B33D4380FE +:10FDE0008F499505F5733AFD0DCFAB69D74A83FE70 +:10FDF00076782D03CAE1E1E79BDBC1EF780BF807CA +:10FE0000F3A02406EA73821577D8013ED393D37604 +:10FE1000027E48893D348AC26155E1CA0500AF556A +:10FE2000154B5D02D055D1087C1E2CB19F848A9C55 +:10FE30009E9255C95218BC57AD26C50AC03BF92E33 +:10FE4000F712BAAEB4A43F342B946F7A2CCCEF796E +:10FE5000A7F47749A961FDC7E694FC2C07F8DACD31 +:10FE6000E87CB455498B541FACD1794B7134C665CD +:10FE70008ED7B27A057A7F65137D55A1FAAAC3D3CE +:10FE8000C7C78B393D458D3ADB00FD95D53609FD59 +:10FE900033B1BAAD89B6ABC05E02FBE9610BF2A526 +:10FEA000C6CFC98D7AB9A918F8B6CAC0D71A3FED1E +:10FEB000BC908F6300AF51B58C9FB4F519D735EF67 +:10FEC0002B6AE7C41362F4EFDE5D34229AE9B130A5 +:10FED000FB763CCA26C94AD7378BD3D32C4E4F94D6 +:10FEE0002477C07C0EDE33622AE04B6DA17E00CC0D +:10FEF0006D99A5CFFE4D837592415EBAFE594D6254 +:10FF000006F8A7E44E4B1F3DA6E9BE87F50273C273 +:10FF1000DB40AFAAFC0ED81110CE848FFEF1D8A121 +:10FF20003DADF47BDD43E3498B07C73BC1E4A384CC +:10FF3000E31D2C140779E1F9BDA33220854FC2E9F6 +:10FF4000958E1F52D9F39A7B4664A2B9C9DB1F2D47 +:10FF50001B021564C45761E9EB0FFF2B3323FE67C7 +:10FF60002F133640FC6FB4F8C5E95DB4FFAC4A9B73 +:10FF7000A7958E3FFBC13A0BD8FD95AAB2A79EF676 +:10FF8000ABA474E177E13A747C72D84C2C30CE612A +:10FF900059209DB43D6B969E6F6A96E9DB467BE4E3 +:10FFA000488C9262A2EF7F2AD8C8067ADDB17EE93A +:10FFB0001330DE270FDAB0AE90C0B772410F101EBB +:10FFC0009F949FB8873EAF5B6723901799C7EDFD5D +:10FFD00041B9A938AEC9518DEFD776C4A05F7C7204 +:10FFE000FD95E300FFED718DB7413DF527B14A0D59 +:10FFF000E0B56ED5B526888FB447774E86FE9F9ABA +:020000022000DC +:10000000886B43066D4B0F59603E3DD43E8078AB04 +:1000100036CFDAF630FCC37773591C779A89289B60 +:1000200022D8350FE6F6D627A8B6B0F93F9C2BE1CB +:10003000FD6969716D3F80EF50ECBB3C1C2EB0EE4A +:10004000C92C2EDA9EE4A91942DB2704E25A9E004D +:1000500057F943E04FF57E1BD988E827D8DF3A6C83 +:10006000E8531D61FEFF383EAF8F63D9F3E3EE68BE +:100070003FACF3B8C4DAAADBE9477A362BE97362FE +:10008000D87A842B6017049BDF9118C99A86F820D0 +:10009000D273745E750F3F82F8DD4CE103FCD9E347 +:1000A00092DA76D0799CA4CA5A85E7EE4727033CBA +:1000B000EFC8A4849A78219CEECD8DC3F99C5CD7BF +:1000C0001A8375262EA258AFE883476DE796BB8545 +:1000D00071A8E755263F18FF09244CBE53FC4ECBB0 +:1000E000FFA1A50ED61B453A012FA6DD2BEC30CF84 +:1000F00079B516CC8F3989AF1CE469EDC302B6E936 +:10010000CF1AD017759CBFDAA5B8BD40C7C7C11EAE +:10011000477FEFB13D501F50CBE557D5223D9D2E77 +:10012000769B75FC32A349CF3F749DBAF6FA5C56B4 +:10013000D7D9E3FD2401F4733B5D36C0E5D336C166 +:10014000BF01E5AB2F25BCBE2E35D7A4C5E1254B9D +:1001500018FCEB28FDD581DEB093CED24458F7A829 +:100160002940EFD623D1384F237CFFD5E1F071B27F +:10017000543384CEE7634AC750FF737C7D2BDA2F5C +:10018000F023EAF8DAD506F4BD84CEF25117D2A7EF +:1001900075C6D83E7AD1E053BB2E752FF4737F1EFF +:1001A0002351E789D4BA0B96823DD94B4706F8C054 +:1001B0009ACDDA7746F4D1193E8F406793685F6E27 +:1001C0001F23BFD496F5E6F55206AA5F467C1700BA +:1001D0005EC7CF873C9426E7D616BF817470C645AC +:1001E000FC22F36BDF06B91FC3E7A61239509F004C +:1001F000CA84EA5D17DE437F399EAF37B64978AFD0 +:100200002C8B90B826F1BD327A33B62C18003D61A4 +:100210007373BDBB2DEFD7A3AF80DD0D04E3348333 +:10022000A22B3C015C8D2B11F729585C8960FF3CA7 +:1002300028085510B71F44F47655BC011E24DB7CFA +:1002400022DC2E8FE6F27EE9E41102FA3BE57AFF2A +:10025000D46CB08B7EDE4BD76CFD12FC49E1D846E6 +:10026000FD3790537181CE4EA0CF1A6AB7FA71FD57 +:100270001ECCEB58CB04F2A8D017BFFA67C52F2EBF +:100280008883F1F8457F71302D1E50C96E517F472C +:100290007143DEAFD24DFD9C416067DDEC46BFC9C6 +:1002A0007D12ED522BB74BA3462D72B1FC19E31F03 +:1002B0002D1E60A42B635CC9C87F46BBF4B7B9DCB4 +:1002C0007EBA865C7339F1012D8EBF2A9DF93DAB54 +:1002D000D2EB9643FDDA39EEF7B85413E271CE2C27 +:1002E00001F1A8D96B73BCA76701FF69F50717F384 +:1002F0007B3A0C7E48B4F729598EA03FAD792C2E5D +:10030000E42864CFE7D889D91E963FB0E5313D3760 +:1003100087EA413B5DE234BE8F683AD1E7A7E2F855 +:1003200038DA95FE04337375F5827179EC3EE64355 +:100330006D3C1F6AE7F582251967777D0DF76556D5 +:10034000076C936B1FFF1E8543F4AC188F09E957A8 +:10035000D9F843F093673950DE26A44B58F75A95E5 +:1003600064F720EDABF2DBE097A19D29C194659481 +:10037000B77329FF065C03F83BF681E3664ECDDFD9 +:10038000296474D51B5FF231F96DA2BF404FB3AB46 +:10039000F4F4325719987E32F3787C89EFE31A1D12 +:1003A0003ABFE36BA40BC6BF6B53583EFA5C05ED36 +:1003B00003F9DB7EEC71CDBF755AA85F44F112944E +:1003C0007721BD07D389251CDFBE425157DF10CCF2 +:1003D00027D12EEAF7042D24F941DA6F903CF70675 +:1003E00017F8BE25B6985AD41B7E9D7D7F908E7BD4 +:1003F000CCD9FF3C8C74BE7AD4128CFF3F703D0583 +:10040000199DFF6A483863FDDE73F3C16F7B00DA24 +:10041000585FF08BF9506FF74094D6EEFAB11C5646 +:100420006F70E796977FAC1652BFC64EF52D1DCF65 +:100430002111CC5311B209E5B308F14090CF63C24A +:10044000E08B7E831EDE463B5E2C647114D1C0F7C8 +:10045000C6EFDE9CA7DF6FD7DFBA8DEFD19FAA6B07 +:10046000F4F47F7BDE00F5B2C6F79D503F1173F9BF +:1004700075075490627E5A24260FF8CBA494E0F7B7 +:100480000417A32B9030A0072D8D833C0837DA8EFC +:1004900002BDE0776871559C7414E05F847C620053 +:1004A000F5399D4A481801FDB5FA03857CEDB8740D +:1004B000B947E5318E2395B3FCF2BB3209C1F7464B +:1004C0003FBACE970BFEFA11AA6725D0E337AB10DF +:1004D0002F3BBB8C607EC0E152B04D3F156A754129 +:1004E000DC8AB56B288C402FDBDCFAFAD71DC58F70 +:1004F0009658E9F3B632166F3DD81C787705A5B546 +:10050000B6C20294972BA063D87C833BA3AC108720 +:1005100051D4EFDAC16EFE689968856B7079AD0AC7 +:100520008B7E3751DD244810775008F8F9D665AD39 +:100530009381AFDEB5A89E3827E655314FDCBE5C0F +:10054000BD15FC1E59AA284FA57CB4A1DD8CFB8CDF +:100550008E95FE2E490AE3C3535C9E1ED811F5000A +:10056000C06195600F45C1D5A26C589D00DFB37A7C +:100570005AE814DF6DF941327C67D5E2559E9DF053 +:10058000BCC5063B50C9AAF5F62A187755F212F7F2 +:1005900092B071EDC3AC8D703F38B40DEB5A9472CC +:1005A0008F352A16D6F5450CE467DB9765C5032D14 +:1005B000B6255A53EAA1DF923FBE990778974C9827 +:1005C000B7B5BA3B2DB0EEE16E4585FCF85F72948D +:1005D00057F3E83CE7351D9B8C757365B12BE13A09 +:1005E000FCFC77DA01FEEFF2784C28B10EF3B56D22 +:1005F0008BEAED30DFE98969CBC3E3316D858BEDA3 +:10060000A3E97B696E53EDD24117D2471BC45FC685 +:10061000C3BCE87AC642BF3F342BB45F28D95A1511 +:10062000699FD6F13CE6EFD95B97A6415CA46DBD0E +:100630001DD233A44D50D6417E404D7546AC631F4C +:10064000EB65EFD528AEC95609F183FC762AAFE7F2 +:10065000C7EA48B02B19FEEC6662B784E9BFB1392E +:10066000259FE685F9D1177C37B10DF5419BC0F880 +:1006700077ECD6CF7F0CF5C2BFCAF17D0EEFAD6A25 +:1006800057D601BC886A27838AFBE793D06A9242D7 +:10069000A83C6E6BB15545AA430B2D12A7019F5084 +:1006A0000E3A3628254C2E2FAF4F83F848A8E52A5E +:1006B000E4EEDEFEEBED1F021E42EBD363411F862C +:1006C00092EBD2D2806E395D1AC7DF94C7ECC95F56 +:1006D00067F92C5EB02BC7B0BC67459ECFE645BD21 +:1006E000DDE9063BF71B40B72930DF7F22DDA29E04 +:1006F0003B9E770AE98AB82E2D1FE9232133E65362 +:100700008BFF8CF1DE8EB1DAFE27161FD4ECDEA84B +:1007100051275680DFEACBD7F25D857BC05F9FA66D +:10072000E5532B587CD0457F23C5077D86F8E03400 +:10073000435BB337A778B97DC2EDDB24A9D3570A51 +:100740007277BFE8017F229930BD32A342F0839DCA +:10075000DD521C6DC779E7F33827F7BFE6F179BFA3 +:10076000D76C27904F32390A57C2FCA715B0F93B16 +:100770001A32720212C87716E7260D3609E3268070 +:10078000FC44D2EBA7F96010BA9E790D4BD1DEEF95 +:10079000835F0B8BF310BD3FE12306FF6111B3C7ED +:1007A000347F6BBEC13E30DAFBC638755F5E609346 +:1007B0001DE8E9EC98CC8369123E56035A3E80F658 +:1007C0005BE8ED5E190A933FDD5C3F1C6E96DF5BD4 +:1007D00041D7BFD2F7133BD06987D96F077DD2517C +:1007E0007E470CD05F47B5580E7C1F6C2EC77E0726 +:1007F0009A7D786DF6327DB12F47BEDB1B1677AE42 +:100800002C2F796F4578DD837CFD7B2BC2E63FDDA5 +:100810003B43D7D6E86CBA481A3745902FBFF2321F +:10082000FE3753BD8F7586E22F3D03D5DF507FF530 +:100830006C38FCD678F5F6EC7D634A070F64B76830 +:10084000EBD3E0A2AD5B7BDEDF3CEFFA1BE7F9D434 +:1008500065CED3383F6DDEFDF59F0EC28AF2FF5D97 +:100860005B4BAAA12E765F8EF22CC8A3CA326125FB +:10087000E44B0FF378E2E1C218DCE7BE279DF97B79 +:10088000D10D8C6FA2CB6660DEEF72F17B9397D9AE +:1008900095B30A05BF4CFF9CC2F7DBBF97CEF2B9F8 +:1008A0002DC53F7F13F2D0EF145958BC97C8D3A67B +:1008B00086E5B1D65AFD01C827BDD75BA771CBCA63 +:1008C000BB683B5A932B55FABCC3AC59FAFCE17494 +:1008D000439E21DA2057821ADC7329DC47F4C1BD1C +:1008E0003F7FA23FFA20E6D3D9A0878CF0B9CD0094 +:1008F0001FA3FF327D9B811F2ED18FD9D09EBD07B4 +:10090000F26A2AB5274701FEE0117D2F5A7E16D3E1 +:100910002051F98C1E47874EAD01BDD84D5500E8DA +:1009200097B533EF5807ED7354EF035EFAFB8EE68D +:10093000BFFD2A473EE38D503FD02B47C03E180FE6 +:1009400079C1C8F641F7A2495323DA0733EBD372D2 +:10095000605E33F4F641F7FAF2C7B3E03ED807F42D +:10096000A73BBF5E671F90F2AC8BC087C9DDA85163 +:10097000D911EBF47C398A2B3F6C3D8EF446125E24 +:10098000CFF879AE1C9B4FDF9FC1E308DAF7A8FDD3 +:10099000B5DB12A17E51FB5EA697C53D49793CD3DC +:1009A0000FFC7A313C6A75D4F759643CEF458B7B78 +:1009B00069FD3CF94CCEB6A7C90DF09C38332F32F7 +:1009C0006E8B16E748CFB882D70D4BA4D71FFAB36A +:1009D00020E1F308FE1E81BC6474D2E9DD2EDAE565 +:1009E00013AF920370283AED57211F62AB10D05E0F +:1009F000B22511B46B2ED5BFBAD47EED501C00FECB +:100A0000561D8B97976498B11DAD881B402E4C3CAA +:100A10003F5800B9E153C4A760BED1F2179FFD044F +:100A2000F435D5FB1087F19146DC67EDB4F8303E24 +:100A3000D1514147CE8038CC724B1AC6D3539F8DCB +:100A400071C3D7FCED102FB779D87EA82AAFBA12A0 +:100A5000CECD985E344A20F4F9341F8BDFCC81F878 +:100A60000D8C3BEBF40E88FFCCF632F9057E1BE8CB +:100A7000CDB9F5778FFD91F4D7C46DFCEDF1D918A0 +:100A80004F92305E60880FD90AA7607C48AB53F163 +:100A9000158AB8BF9B2439F11C0A637CC718CF3173 +:100AA000C67B8CF19DEFE6B37D1A9A3DD598AF8F4A +:100AB00017DE0D7B1072C05EA2A292F275878524AC +:100AC0007752FA3C58F229B993CEC3F94313D48034 +:100AD000D37E7A3BEC52E55690CA958F6121BB5E7E +:100AE000B7807F5B2DD7627CCF48F70FE5B378DD09 +:100AF0008A7CA72E1F1C6C6EE2EF47A980E7EA9163 +:100B0000567F546ADF3897CA1F8FE6CA0FE433BF97 +:100B1000A213E89C7814DC4F5091E7D2D12D691CC8 +:100B2000423E0E8BDF18BFABCD471BFF72E7713F14 +:100B300087F7A5F2C9DAE202BB957EFF0CC5B18842 +:100B4000FA921AD461F1692D7EAEBD570379832CD8 +:100B5000B02305CC1F68F7C3E2D866A0DBE82445C4 +:100B60008E74DED4A1FCDE3C15E631B5EF104141B8 +:100B7000B950CFF335DA7866E26E413E00DAD6E658 +:100B80002546889B138FDD4649A66E8D4820FEE3DF +:100B9000247227C49FADED166C13B56A2FD8E98B6C +:100BA000385F580BA7EC85B89AC617C6BC8D554C54 +:100BB0009A02C3D677EAF357C6FC94D19ED6E2EBED +:100BC00066FA1198D7FFD3F04115B57869EB7D0A25 +:100BD000D7F30D5DAF46571559DF7643FD495B945A +:100BE000B2AE96CE4B7DDC8EF10A07CC0D6012A022 +:100BF000BF20271FF7FE04E4EF5FF2D9F9376D023B +:100C0000AB47D99DF88784F0FD0B7FE1FCFB74BEF8 +:100C1000C4E222661280FD52644C02F285567F7255 +:100C20003091D981D38B1607EEA0ED5FF07AC96BB6 +:100C30008B366AF9FE4125B9044B3F002E6BADACF3 +:100C40002EEDE0D566AC2723E2FE9D7724F4D5EDAA +:100C50005EBB49EF57DE98AEB7078DF69FD5D08EB5 +:100C60002BE072ADB7FE44B1631D5922AF23E3F30D +:100C700037F2C9CF9A595EE3E7BCEEFF977CFFE5F8 +:100C80007FF1FABD4D7CFFE5737CDFAC06F7FB2CF2 +:100C90000AC6A38F5D4F6DBAD8BE38E0DAE27BDDBD +:100CA000C0C7E30B587C68B2E8DC097AAA6F9FC51D +:100CB000C0E7845596EBF366B37DFABCD9DC2A7D98 +:100CC000DEEC0F59B2A76008ECC368580EE714CCED +:100CD000582162BE726DDB19D4B3E70AD1DABE5077 +:100CE0003EF07D18DA3E0EED7E69013BB7C8B133A8 +:100CF000D102F5F83356C44E81F83971655E92FD24 +:100D00007603C4DC613ECB5D16380F62462011E3EA +:100D1000A1B5ED9737CEEA5157609CBA37CE4FAEAA +:100D20005900EF1FD2E2FC6AFA0288F31FE271FE5B +:100D3000EA826B1F07FFE8E97C7926C06359BE5C35 +:100D4000599003F7995CA0EDD9E16DFAF35AACFE26 +:100D5000FC896A78AFBF78BA3849688C542FB2B82A +:100D6000A037CE5507EF137B6F9C6B116B77E23E7C +:100D7000BB26FEDDD6F748038CD3FA2269782E8293 +:100D8000DDFD9D02411BEF16982F716BFACD775B4D +:100D9000A4F1445B6C0AF8FDC7787D9971BCA6028A +:100DA000B61F938E7717BE9FD43BBF261C9F8FD74D +:100DB000B77FC615034CEBA8514C3D949E489B88C9 +:100DC00075278E2ED754A84B225346601DCBA1B257 +:100DD000CA7F89FD3487CA7EF36FB99FE63705A9BC +:100DE000480717DB4FE398499448718D97385DEEBB +:100DF0002CCC1A1C1A004FD6A67D41B0337ADB6684 +:100E00008540DECFDA7400EFDF17E5AA89685F70EE +:100E10003A6D2B5BE48394D0AAE42962B8FDF2BB5F +:100E20006C654F4184FD8967469EDD05AA69669918 +:100E3000601612D0DEF608547E662F9B21BA25423A +:100E4000BC8D0F4EBA923E9F9544FDBBB0751734D2 +:100E50003CBB8BB22B292C3BD49A40FBBD98AB1CDE +:100E600082F18BDDD26E68CFF26560DDFB7DB1046F +:100E7000EDBC63A3ACFE0DA917CEFB049F3795CB49 +:100E8000CBCD972197DB9AF5F9EF55C9A397C3FC12 +:100E90004797921048D834F7E912C8FF8DCD514ECC +:100EA000005FA5B9896C1B87F7651296BF318E1B51 +:100EB0003581E9DBD1A1A4FB219E7C50F3F78B2F78 +:100EC000DBDFFF221CDEC6EB31CDDF5F19D9DF3F50 +:100ED000B6283E723EA0ADBE0EF201C756EAFDFD39 +:100EE00063EBDD35B0CFEF18F7F78F4DA6FEFE9818 +:100EF000FEF301DA3AA91CB24D00B9D39B0FE0769C +:100F00003B8F6BFB72E468784EFD79075CEFCD9206 +:100F10009D13E0B9EA5A80FB9149E47DB2E4319730 +:100F20000C7E8EB6AF3DD3AB0C81F7B5FDB2A341BD +:100F3000B4C5415ED4755B247A9626307EF9EBF316 +:100F4000A4BD794C13EEA3BEC438FDA5F693BC9B9B +:100F5000583D8E99D519462596BA213F756E8C1D40 +:100F6000F57B3BFC2F4CAFA61428B91386848F6306 +:100F7000385F55BAB4EF6A75FAA0AF40BF74135228 +:100F80000EF2E681D8468C7B9471BC1AAFD74D70B7 +:100F9000713DEB4A0078A614F8A620DE9FDF24E11D +:100FA00039B0FC7E7FF5FDC6793C63F57D80FBEBB7 +:100FB0004B4589D5E511E48BABD25DA8A735FBABDA +:100FC0006E422A3B578184465AE93A5BE55DCE2C56 +:100FD000DAEFA3C7CC19F0DA4F638805E6ED4BA72B +:100FE000728EAEA3D4AD0C1F483EC28944262F5C3E +:100FF0000382C98DD778765505B87F013F3E767656 +:1010000008D8E33F7D9CE5A7AE7A7C91BD2E6CFCB1 +:10101000472670B999C4E65F230B7E2915E6731A3B +:10102000F350332493472690373E77642EC409A9A2 +:10103000FD360ADB67B01D944C5990D7FEC8FDE51C +:1010400011E87FD5F7175F81F4CFE1B17059D6333E +:1010500068E7E728DF03FC070BCFC48C188376FC16 +:101060003AA0FF8502F145B213EEE778BB416EBCB2 +:1010700009E8EC06D94660DF5AB0C48670FF699172 +:101080002081DF3A1D681EE2398F9931DE4CE17113 +:101090000B3CDFEF71E0B9D1A5F2B36668FF61AC3C +:1010A00040AE1C401F5F365C0BCF0C017EFC08E895 +:1010B0002FC2FCEB38FF6AFC44E15E8AF39259BD13 +:1010C000487F74F579BEBC0EE8B23D4D69C073111E +:1010D0005D332FE95CC4E93FF363ED9EEDE9C6A102 +:1010E0002442FDD741CE27C6FBFF3981F9054B3895 +:1010F0007F5CF5F8D9FDD7035F2FB3B800AF4FE79A +:10110000FB7E0178EBF5BBFECE7264B2588DF80B16 +:1011100056D0B9E3390E2406DAD3469A117F6A29EC +:101120003FE7E32EE26A8DC5B7B06D5F26209F3999 +:101130009C9D5560349BF31B8FCC86F74A44DCD7CB +:101140001FB6CF65C03AB210DF7FD606FBCFA82D01 +:101150001F5C216AE76E1181CAB6609999DBF79F1F +:101160003E2ED33F9FE1F5991F14894F407DE61134 +:10117000136B1F2A125396D3EF8452D83C3A1E1495 +:101180003C2D125C9F5A07F9CBFA26C1534EDB3532 +:10119000817B7A20C4B5E4611B0157E1931F2E9D2A +:1011A00002EB39E32678BEECDC44C6374A90F84DB2 +:1011B000A97DFEED87C9C4AFE54B611F9D97EB99F3 +:1011C00087601F1B9DF775EA77D5BB216F4AFD5ECF +:1011D00088ABC579583E333A68F6F809F8BBAC3E9F +:1011E000B2ED7E813C04E3886B5AC13FB7F17ADDF2 +:1011F00068B916FDC7384A9F1268D09059B78FADAD +:101200009E2848BFF1E5943332E0AAF78FB32FB29E +:101210009F6DEE8221B1C02FE726E8F765F4175FD6 +:10122000D7AE70DE0DE0A78BE757B752BB1DD6FBDC +:1012300022B5DBE1BA8DDAED701FCEA9862BEC6703 +:1012400083EB4E6AB7C315F6B3C115F6B3C115F6F5 +:10125000B3C17BB09F0DAEB09F0DF71F16A981C122 +:10126000009F926802F9A1360BA33335D98AFE4656 +:10127000A08860FE3E986CDDB01CE27502C3931A34 +:10128000CB9E0763949BB19D3A86E577CD9E14D89B +:1012900047B842182381FDD46E55B07EF9D8723319 +:1012A00081FAE5D054E103C8BB10C1E411A97DB3B4 +:1012B000FDEBDB10FE8B656282BAF4E5706E28C828 +:1012C000E3CFC806169F0B8A70BE5C6B0CE1756499 +:1012D00037F9654A7F2705ADBD57017F7422C404E5 +:1012E000907E7729F07C7193C0DBAFFAE59150D7FF +:1012F000A03D7FF349882FAE30B4BB4DBCAD0E7F0F +:1013000012C63BA27D4F1D5603E31D49D39E272ED7 +:1013100084F6C751DAFB9F2F84F783BDF33989E345 +:101320008592B5FE520DB67BFDE7050AB687B0FE85 +:10133000EB77EE7B0AFCE5BFF778AD8A8A717C75A6 +:1013400016211B6323F0FF44511F0F95055D3C548C +:101350008BBF9B1CD557E2FEB3076C28173F4E2668 +:10136000E887F417170D8BD7635CF4E713FB897FCD +:101370001285C0B855100FF4E05795F0FD69446828 +:101380002450A7EE3B1523811D694D0A8BDF71198F +:101390003050BCB0B591C507838A85A8A97D75FD7D +:1013A000D6425ED7CFE3855A1D83B5F047BABC81DC +:1013B000315E48C45B301FED5BA48F074E572E2F64 +:1013C0005E584D02962B81FE65C103FE7BB54BF93D +:1013D000F00AB4F7AF61E7334AAF61DC54DB37069C +:1013E00077E0DCA92ABEE68E5B8F7D7005EDE75FB6 +:1013F0001E25C166FCF9B794E0FBF9748510DFAADD +:101400002E4A4378E77CE6794D0279EA3679989955 +:10141000E6FB7E22D80B8B62316FB2E0CE8C0F617F +:101420009CC5AA03DFA37625A7F7AE27809E4408B4 +:101430005C86B5B35334FA9BFD04D0FFC478AD1D70 +:10144000FDA45C484889557B3F07DBF314CE7F6AD7 +:10145000FA93C07F474A357A7DA3069ECF1ED13BC3 +:101460001ED2F74487D6BE71213C6FEF1DAF1EBF61 +:10147000F70E9C6C84ED494F823E2A99A1E9ABE3BB +:101480004FC0F86DD5DAFBA3FD108F9A6FD2F887A5 +:10149000F8819F15D2DB96412FBECFF9FFC8B64D1C +:1014A0003550D77593F65CDD84EBADE6ED77B62964 +:1014B0004F023FFDDBAFEF7FF87BC6F602129C7C4C +:1014C00065761F5F18E5D56BC54C8E781B9E05723F +:1014D00025D58D4FE1F96E100F60F9ACC4593E90DF +:1014E0001776D1433983F8DC2E8C731AC7595CC444 +:1014F000ECEB4F0BF579B136435ECCC7F353FD8D62 +:10150000F3269F4F7B69643F766C4EE99785503F89 +:10151000404E8B309E8B020CCE276BC952BE82FB95 +:101520009475F1DC4D2AB23C709FFAC52AD899D344 +:101530002838210FDB52FC28C6E943F916DD792053 +:101540005A9E73AD5546F9F809AFEB985F2A4FBE26 +:1015500087B66B878A6403D6793831DF601E667D73 +:101560000AE53ACF7B6AE7714CBBC8BE08E3BE947C +:10157000CFF97ACF147658403EAB449D5C968DF2FD +:101580003A08F5C626C71ACC03DB8A2D9847D0F255 +:10159000CF0A3FFF5BCBFB4E3C3F98E9F7742DAE83 +:1015A0003B70FE5769DAE143FBA0532426E1C27C7D +:1015B000F0629F9A0CF52CD3CA6270BF4055DDEBE8 +:1015C00038FEA11482E70447CF6AC4FD41666A1F52 +:1015D000CA00179E2FD6EA63869FFF0EEE1BADD77B +:1015E000EACDC58A0360A7DA1EA17E1674E0F96011 +:1015F0002D5F3CC320EF171756A29E25D48E1F15D2 +:101600000BDF1978DFF3031359FEF84427ABE7F734 +:1016100016E9F3C0F759589CAF3D4D4F571B273281 +:101620007FF5075C9FEE2CFE7915DACFC4E481BC10 +:1016300018798C9D0B073116DC6F653C8F397D0E58 +:10164000DA758F0DA74BA4B6B6B9E97D8C2B0AEBE2 +:10165000D87B9F8D238DE0B798CDAC4D2F2AE4FF2A +:1016600033BDCAD422A8B368FA10FBB7AAACDEBB5C +:10167000BFF8CDBC226D9F088BDFCC77EFED817D6D +:10168000657F731CC7B0EFD527B1FA929585929606 +:1016900047C0730929E15AC05E4C29F0D5C3BCC9C3 +:1016A000984D12CC4393373B5EF9760DC81B224709 +:1016B000CE4B6B7CDF66C84BFBDCECFD378BEFAEB3 +:1016C00081F30DFACB433C5C2268F1B53B8A605E46 +:1016D000095ADE40BE13DABD7A1416E4D5E9D18585 +:1016E0000DFF0BF4689FDDFE760D8CF74D9B3FA53B +:1016F000ABFF42BC96B3F8D9376DFE1326C87B60AA +:10170000FEFFE8EF8C99E07B0BBEB35A90AB9C2CAC +:10171000B9E711F479BE778B06C8F35D2CFEF07F34 +:10172000F18681E30D62F1BF66BCC10A7BA87290AD +:101730008FAE2C06F95CC8F8E8DF5DEED1F5E6C0A7 +:101740007A570B9BFCD123FEFEFE7E4A8132A918FC +:10175000F5A062DA49E96775899DD9330106DFDEB4 +:101760007806CCDFAB8B673CD9F00F8867D0F55695 +:10177000227ECBF8F7BFF9F8BB15E12B337BE2DF14 +:10178000903E57E3FA36B1F5FD13BEBF1EE9E5976B +:101790008C5E7AE1C3EDA430F82C6CF8E7C0E75713 +:1017A000089FAD6C7EDF007CEE42787AD87C2FE615 +:1017B0005F1F2D1434B9FC06BE97CDE8E043B0AFEF +:1017C00099DF3DE94AA9CFEF7E34573E50CCEA631A +:1017D00082C5BAFA4FF910B407F08B8FC0F3087EB8 +:1017E000F1FBC5DF40BFD859C4E0D69777F1B3739A +:1017F0006F49D50D57D3EF7C48E10DF1B68E261118 +:10180000ED8B734904CF03D0EC8D502CABDFBB7054 +:101810003F581981FD88B67C76CE88763E8059ACDB +:101820001E1C902E84EB81418A15EABC96C8196D66 +:10183000B0BF75D29A2F70DF9555B6E1BFAB39DCDA +:10184000EDB1DC097E34F573AF83786A830BF7D191 +:1018500069FBCAB4FD1F4B02F3F6C23EDB0E4A0F12 +:1018600089F43BD3CB2CC7C3D76FB437CC86B6F142 +:10187000DF354D98A8AF07A4F047FBE7DC3A561FC9 +:10188000D761263BA1FEA35E15FD2DB4BD718D80F1 +:10189000E7712EA270027F7F52672AD6935B93D89E +:1018A0007967DABF7B4AE9A0331FECBF2322C17FEF +:1018B000C78EEF27D3CEF98E9A7A1ACFDBFA98AE7D +:1018C0001FCEEFD1CE9998C1E9448367544B3CC2F7 +:1018D000E51C850B01B8F0FD36D39A583EB8AD7AB9 +:1018E0007110C8BBA6F08B1591EA52E6B8F5E7A5D2 +:1018F0001BE319C6F3C6CDC43718F6D54D2F2C51AE +:10190000C15EB5F17ACD6822E3B9161FAFF9093B84 +:10191000D7A2CCA23B47C4F8DD68039DDA0C71075F +:10192000239D1AF1729D012F1BCDEC9CC1B66ED187 +:10193000A3D2DB6D0F2F6A877DF9EAC32656374F96 +:10194000643CF7A98D5ABCB8FF9C4E16E2F573397A +:101950003C35BC10D268017EABD6F6A19B1A57C2AB +:101960007ED2797C1FFA4D6413EE3358001604FDC5 +:10197000EE4208918B70AE8C6465CE818BC03CEAE0 +:10198000ABD83919265803E4091E3621BFB6B977FA +:10199000E2BFFB15186A893D99CEFC8948F66C6F49 +:1019A0005C8142E264581CFFFFE2577F5BFC2AB770 +:1019B000889D47D5161570E5A7B2F326A09E29B7D6 +:1019C00048423918B42829B8DF61FDA72AD081B66A +:1019D000DF81FE2CBB427F6EC2FA8903F87F45454A +:1019E00004C76B4B0D25835CFBB09FBACAEDE03892 +:1019F000303DB46122E6DFA9FD9B0D728FD9BF1582 +:101A000079BEA7F13EDFE7ACC5913EF12AFF39313F +:101A100007F6E71094C3B60AC10FFB77A63B853DD6 +:101A200082D4F77D62AC63FF5F9AB7BA93FB6DC156 +:101A30002882E720055349D57311F0F1835216A788 +:101A40000C6644C697F69CDA19EF4CCC61FED020A8 +:101A50004614A7ACFAF8C00703D18786C7F8C9F2C5 +:101A6000471373FADA0FE4299F40BB55F17D0078E4 +:101A70003DA98A12E8151250F03CBF69FF21BA0057 +:101A80008EFFE83CDCCAC2D44BCAC355039D0D503F +:101A90002F78B9D7FF0FF9613D6B0080000000007F +:101AA0001F8B080000000000000BED7D0D7854D561 +:101AB00099F0B973EFFC24998409041C24C00D0229 +:101AC000461BDC81802440E0CE4C12124860F83581 +:101AD00002E285008D5DB451791458BAB921102005 +:101AE000A260BFB4B5EAA34310DCDDFAD4D475AD6F +:101AF00088AE23A2A55DD4A8A1C6556910E4B3ADF4 +:101B0000ED870A6BEBA7F57BDFF79C3B73EF64C2B5 +:101B10009FB14B9FFDC2A337E79EBFF7BCE7FD3FD8 +:101B2000EFB939EA648C4D82FF8CC2655A01632D8E +:101B300058BE9CE18FC6A0BCB8BFA59C0B4D3B799D +:101B4000FBD1DAFF891A2319D399E82FDABF23F1E1 +:101B5000F6478303A28697B145A21ECA3A96CDFEE8 +:101B60008C29794105FAD749667997A658E7CBDAE7 +:101B7000A5C17C279CF6F19788F18AB42F69FC48AF +:101B80007CFE2FA31A948F27C17F03E3E552EDCF8C +:101B9000D47E65BCFD9F755CEF49C92C8FD2B1FF27 +:101BA0001197D9FF8A6538FF3D79BC7E6A6854D4A5 +:101BB000B804E1F9A6C7BFD0F647A7A88C0D047CEE +:101BC000D4FD2C7C19FCBAA47E97AC43BFA3CEC82D +:101BD0007B2C07C8EC5E49DD037D8A58BBCC6402D0 +:101BE000DB258F87213489B5C05C2B42F0BF09808B +:101BF00047AF83CF6304A21AD0D9E2A9269DD64469 +:101C000071DEDEE8EE9DE0771FC27527E0FEEE5242 +:101C10001BDCC6A865DA9404DCE110B487F116DF9A +:101C200072931FE15C3CC25CDF249AA739DBECD7DE +:101C30007DD6795F7BA194F0BD383E4F25B55F9C82 +:101C40006E8E37278AF326E05A48FB91806BA80DE9 +:101C50009F81D042C267C417DD3C08F013F1B38006 +:101C600001F85C54D728EB05163E32C22AF1913FA9 +:101C70005E8EDAF9A880F8A8AFE11A3629B24D8352 +:101C80007D62F9ED6A64CC37B1EE98F3325CB7212E +:101C9000D1BA4D3A5AE2B3D0BB07D6AD9AE52B97ED +:101CA000D579FB62DE8E329AF723C0374BF01333BF +:101CB000062FD3BC173E5E9377B90BE15EA5495A58 +:101CC00014DA7F853FD312CFA35324E217C0E7BFB6 +:101CD000123E8B009F99F89E111F3C5E18F9B906C1 +:101CE000F54CD51D07002E97E6612D8083AA8991BA +:101CF0007DD49EEDF423FE01001AA7F975A6209F5E +:101D0000016F051C93A1EC6435ED29E6FD61C84126 +:101D1000ED9B18AB6807F8C66FF4AD8A7813F5BE73 +:101D2000320E5796781EC9ECBE6120CCDF0D551BD4 +:101D300061FC260398179E1FD4495109D6FC416EB9 +:101D4000645631943BF21C818D307DC73AF7D03513 +:101D5000D0BE2BCF1B40E8BAB27766FA60FC0F0208 +:101D6000B2C0D74DEF235F1FC98CF39381FAA5430F +:101D7000E0F7D75A711BF2D3DB2A2F3F50FAF7EF67 +:101D80001B05486FCCC706011EB007F0AA23638A63 +:101D9000C70DF3BACA419C605F1FD35D50EFC67A8E +:101DA00058E29C1FECFEC13C95E4C6CB23AF65AC6A +:101DB00006DFABD85F31BA3D34AFF295444FE6BC95 +:101DC0003631AEABB5E9A526809FF9651642DEF245 +:101DD000F3F67ED6DDF89503C787723E43127CE1A9 +:101DE0002B58BF24CAF8F3152CD1CB2215790857EC +:101DF0003E0BB4C07C7374E789783D7F6C57AE1599 +:101E000070223CF2868A6278A6D7D9DBCDCC87B225 +:101E100027519ED15A1B42BCCFD0A0DB58C60EB76B +:101E2000D6C66A01CEC3456E9F049876E52AB6F6FB +:101E30003359FB26C43B530F1D94012F4BC57C4DDA +:101E4000BE39EF31E8B72A1F4AB0FE23FF10CC9C01 +:101E50009083FC26071CA28DC3C407A3764E079768 +:101E6000D30109DA373D63EEDBC436E4033943B20C +:101E700095832EB37E4C1BF2E191B85C1DB91CCB4F +:101E80000BAE30F926B30DF96A5A8659762D473EC6 +:101E9000EA569C429E0D6C433AD96A8E67EC20F953 +:101EA000F21633EB1D541F89CBBFF25D585EE81369 +:101EB000F018DF2779D8A4717D72D50BB16EE322BB +:101EC000DA037F5E19447E8B7079975C3FA933DA21 +:101ED00094857C07F819A5F6E4B7F54199F828A28E +:101EE0007D2CE3FE95D603CE60FFC23552E704A4F5 +:101EF0004F850D45BE6F6E009D3E0ACA2FA6B9D410 +:101F00004C94EBBE722D05FFFE3CC8F97752D09B76 +:101F100073127157C80A91EE9A1BD69AFD0DDC5FB9 +:101F20007DA42B9A96D7FB38AF851D24673A24DF12 +:101F30007CAE9F6586FA3978EF15DE629668F758B1 +:101F400098EBE5C6426D7A10E69D05E297C11E3614 +:101F50004EBD3F1282794E143B036EE233ED0DE429 +:101F6000B3B9828676B834B60EE546B1DBB71165F3 +:101F7000B75CE05C0B656508F02B962B387DEBF0C9 +:101F8000EFAB1138AE92A07F8063CE5A3B3F28CC96 +:101F900042DF50BF28989973F25B50B89A5D8DEB81 +:101FA000BFCBE95B8A726CEB08DF2D5679F6689837 +:101FB000CBB1A858EF81A9FF5283F8F994390228D0 +:101FC0003FF6A647489E1DCB62AC0D75BEC654DFDA +:101FD00020E46BBE0E297F21C3F60F0E87250C0669 +:101FE00038D6BED3515A08EFEFE3FD3EBC86D53359 +:101FF0007CAFF0323C0C632CB63B4AEDEE0C8EA06D +:1020000079D943018F07691F9AE37E7B59BB139FE0 +:102010008E8C6787EA29F6C77CB2D5CE8FE27840EE +:102020005E024D88EB9698EEF80AD72FE43FD0E990 +:1020300006DC1F90FAA447267D78CA466FE3822A01 +:10204000C1914C77D0AF89FACD37FB31A76EB1D7AC +:10205000D7077F146D1C49FA681BB5F3823ECAB1DD +:10206000E9A3BB8229F4D1C84AED6EFE9E97A1FF79 +:10207000BDBDF4FF5FA9FA43FB1FD27B8F4EF8AAC8 +:102080009AA8FD08CBE38799F2041A1681FC186020 +:10209000CA8FF41BEBA658E48F31E1619437D7EB7C +:1020A00092A8CF7F98F44EC8ECFFABA57679B4E048 +:1020B00061BB3C9A7923D627E44FED4376F9137E32 +:1020C00018E545708ED06BECFD8770FCE62566FF49 +:1020D000D1D120DA250E531EB228F2A1CEE2659BA3 +:1020E0001D79E4D9F6A5A8E74CBF8919ED0F213C6D +:1020F000A69FF1D6B3FAC3A817412EB2E3261F8CD0 +:10210000E8C9EFA61C30E9C7B40F5F7B31AA1BD02A +:102110006E6E8516B3EE4BDCCEECE6764FC2BEFC9F +:10212000DFDCFEEE7BFBF1759ABF80D3DB3730FE40 +:102130007BD6F14D7B0ADE7713FD89F7979A3F072F +:10214000F09D26F8C673F82EA2FF17B4EE00D75301 +:102150007F0578D343163FE012C4E7B04B1CBE7135 +:1021600021DCEF2ABEDF8F69CC94E31308EE1E74E6 +:1021700070DEF45F42E396F2755BC6D5ACF3F5E62C +:10218000AF43BB327BBB38FF54105C62DCB3F4AFAF +:10219000B6B78BF78F842CF4D9077CBEC8BABFDFE3 +:1021A000801C5945E38FE4E3CF4BE0F126EBFBFFC6 +:1021B0001F373B279DEF207AAAE7F4741EF6F60F2F +:1021C00010BFDBA4763D8BE2448689F7FB701C7858 +:1021D000DFED82F731B11F8F14471EC0F658F48F20 +:1021E000B3F827C6DC5D085FC23F81810A2CFA9EE6 +:1021F0005DB70BD763EAFB27428B761940277298AD +:10220000B77FF4C0CBCB70FDC965B04BFE99F63FEC +:1022100007EC92316497FC0BC275AE7101FE76C279 +:10222000C3D39C6E52D43F49E33EC6EBB7BAB81D48 +:10223000FBD6924FC98ED36E551D68C7997AFDF9AA +:1022400010B767C11EA9887A7BDA8DCF8B781A8C7C +:10225000FB3CCDDBCEF1DF199133D1DE4CD82D31F3 +:10226000F2831276D50AA2A3B85DC5BE4DE5A96278 +:102270009FDF087D679980F7571C0F623DE76EDF8F +:102280004170F879FB14F59D345E2E8793790F9D8C +:1022900040BF95E895FF8C7440799528049D0B4AC2 +:1022A00072C06E39D02AA948262BEF33F7F976E2AF +:1022B0008BB8DD26F8F07A41C79F84D6D33E5E7F87 +:1022C000DAE4FFFDD47E7CDC4F5D4FF0BF2DE213DE +:1022D000DF0BAF37E1FB90E053397CDFC0F8A70993 +:1022E0003F8CE3A786194EB4CBD0AFDCC37AEEEFB8 +:1022F00017228E03FDFE2FF5F370B86A7489ECF790 +:10230000C88A634EA4F7A59D4C4B451F72D865F64D +:1023100097C364970BFF36C0E342C9EDD3C2717A0D +:102320004AA3F63E3EDF86E2480696A7E8AF870757 +:10233000F1ADF1A03D1A2995A22D79E8DF78CB4ABD +:10234000A13CC7C1BAC9EF636C33C67DDDCF2AACEF +:102350002540AD55C512D7012EFD35FA910BC43E6F +:10236000CF61F1F88A03E33596F80DF981EEF09D1F +:10237000F9AD2AC55D286EE3F2CBE45704EF5E4168 +:10238000F191F422B7CF8DF3C8B9E4E7BA1E10F18A +:10239000A2F9DCBF74C03FB4A3D3D732F2DF666DBD +:1023A00097A22AD4BB357BFCA576C3A926F2EF56AB +:1023B000309F067EA25264AF7725F9AF8D857A00F3 +:1023C000F172F2BE5A07E22358C9FDB093F75DE1FE +:1023D00045FE4BF6A34FA21F4D52AA871F6DACC3FB +:1023E000F89AC58F5ED3877E74386CF7A38715473C +:1023F000CAC248E78A46F2EDC0D44973C95FDE2EEF +:102400003337B43FDE3AFED522281BDB9500861B0E +:102410003E706A4BB1DE007F5A1E46DBC430BE35CB +:102420005BC07FBCF85429C2AFDD3E2C80F47EFC3B +:102430006E37E1F9F8CAEC68068C97B5FDB34D69C3 +:10244000D0FFE5E8100CB2C5FDEB643F1CDC2703B0 +:10245000E9E6381BCA5A701F141FC37195FAAC8085 +:102460001148F8DBB3F37D068EA7473318EE7BECFB +:10247000974C3A99CFE8C801E9780E539D5898C710 +:102480003427E27F01D3A97C1DF09B7405CE976FA2 +:10249000101D00DF61FC6E7DA17E13E1E3414E1F44 +:1024A000EC1E65179E571C37EECD443EDB9B6E8FAE +:1024B0003798CF3522DEE0413F7F4C9FFAF9EB0899 +:1024C0001E2127CE43AE34F0FDE4FC7A1AFDDF81F5 +:1024D000A427EB90CF3B441CF89E6C1E3F690D7304 +:1024E000B992FC0486CFC1FE17AA27405FEE08DB35 +:1024F000FDF89D583E0F7DF94392334FF2753687B4 +:1025000099297F7E1CE676809A45F11410C5D7F292 +:10251000FDC59FCF25FD611C5F7B4CA2FD4A531971 +:10252000C921378BC4383119623D6CC3207BBFBDD4 +:1025300067EB776390CFFF4191FE136C57720A28C7 +:1025400014DAB9AB781C7CB6577A495213ED8E6019 +:102550001C2A55DC5FC85168167380BDB2230BF688 +:1025600000E3DB4AA01FCAEBB71AB4A368C31D6916 +:10257000A8A06797524FF2A3EB3E39DA085D5F6D72 +:10258000601DA5A37A8E5BB32478F484451ECD2EFE +:102590007BC403429135E5B71D92305EAFB9553724 +:1025A000F4EFC88CDC83F17AE37599ED017817CEEE +:1025B000AF3C7AC2221F92C785F998012CFB56982E +:1025C000C7315F0CBA63D3009E1586144579B0C23B +:1025D00038E6C478E5D2B5CB980EFBE42A3AA6E0FB +:1025E0007E96077DB4CED94532332C70DD7FADD6D3 +:1025F00011E6F19D37687F03713BEA4D2C079D5A28 +:1026000096AF20118734CF051E0BEF267BB4239B9A +:10261000D1FC113F8B36A2FCD296B9BAF19CC51FF2 +:10262000A1B8E9E1B04AF3AE6CDD45F0A44FF998EA +:10263000E001DB39E6E8DF13DF261FBC2EF0DE2CDD +:10264000F0DE1B9E3F09F3789E599E5DA664229E94 +:10265000DF50543AE7E88DBFE796DAF7C7EDAFB041 +:10266000959BB4DB1D484F275BE528EE133C5FC10B +:102670007D3B0DFBC6F212E37464B21AAB7E36F7F3 +:10268000674AA94C7099FBB3743BDF9FA5DB838439 +:1026900097A5A595AEC1FC5CAD1D689BE945CB181F +:1026A000E2C5A51D53508EF5B65FC06FEE528BFD8F +:1026B0007811F1F37EA516BBF69B8EEFC37C4369C0 +:1026C000BE243BFBAF75BE60D25327CAD582845C63 +:1026D0002D2BE5FA20F969CA558B3D49714D0B1C2C +:1026E000CBEB2E020E934F904F516E84774ACEEE75 +:1026F00002DC7FE0D731689FFD76F36539C8378CFF +:10270000E8C151CAF9C635658E0BFDA695F77DACBB +:10271000A0BE027C4E277C0A393CB694997A6806A2 +:10272000D1451DA78BFFEE731D806709C1B984C316 +:1027300079A99D3B7DA73A525F4AE7402097BC1894 +:102740008FF789FD674379DCFBC2CE373F68BD9DBB +:10275000A11D38E70F992ADA818B8AF768796ACA4E +:10276000F34D55B29D6FD68618F9158C8506B37357 +:102770009E6F269F9FF63CEF345E6ACA49D8DDC93A +:10278000E79DC9E79AAC97F3CF9EE79D2F561503B7 +:102790009C3302B24F5513E799AE2927DF65D7F472 +:1027A0003CEFFC12D623F099C32CEBED1AAAB6C766 +:1027B00000BE96C19E401B6FCEE46B1378043DE0D3 +:1027C00071C33C9BCA007EB497F3DA7E308FD9F098 +:1027D000E8223C5C201EE97C1BF1D22A4537627F4F +:1027E000A5DE4079BE92F9D4FB0389FD8C8F977FDB +:1027F0008786F2F91F6ABDCC01FCBF39E736B60CFB +:10280000DAA71F4E6332B43FACDE46FB7DF8A34C23 +:1028100015CF7BDD7ECB3E085C2A267C724F3FE9DC +:10282000AFB08F1E64B91EFBA8B695A29E3DDFFD1A +:102830007BA4387204F9D803FA5A199778DF3594D3 +:10284000E3B3FB2A166D937AEE23E05B23BF339F3D +:10285000EDDA48F5F50CE3039B24C6F19D44178E91 +:102860008C0D069E6BBB967BC98F6AAAAF277CBF77 +:102870000EF8367C9CBFF09CEA2CFC65D2059306D2 +:102880009D3F5D24EFFBE1D65AB6F6D2DED75EF867 +:10289000737729DA3DE7BBAF5593B57E6513ACFB83 +:1028A000AC65970DB4F2AD21F2520CDA47633E638A +:1028B0007BB27BDA51978BBC14186F30F61F52C66F +:1028C000441C501B82E579C3597DAABC17E774EEFE +:1028D000C72C01139CE22A463ADB331EBDAC9DEFA8 +:1028E0000D42BFCEB84AC532530F4591AE6AF912B8 +:1028F000D8911DBBBAB07E362CD69143AF54870514 +:102900003F81B23C1AB778F5B15754AA0ED0F82ED1 +:1029100010FEE8A72EC197944FC2A27B480EE86C28 +:102920002EC8FB1BD648EF61BB1A2383A15F9BC84F +:10293000AB783429AF829767E78A7AE3DFDA6CE70E +:1029400098C60B49FAEDAD36AB3FC58C63A4DF6C7E +:10295000F685459F1D79E9F7CB0DEB39A6F1318D51 +:102960007F7489395FD16EFB39E69734BE19A7664B +:10297000EC332A2F89973F27FD6AC691FF5436B161 +:1029800096C74DF5B9B8FF7258AA47FB08148C26B4 +:1029900051BCC6D786FE34D8FFF3B0FE6F7D9D6074 +:1029A00087DC5C6639FFF85B83FFB819DF370E2FD1 +:1029B000D70A2E7D7801DF0F10BE2B38BEFF06E050 +:1029C000FD59598A73804B08BE9708BEF839C47FF9 +:1029D0003B3C6F9559FCCF6F7ABEC993B513484FF6 +:1029E000DFC03A4E9559F20FCEA3FD7F517B715E49 +:1029F0009A5C7F73B98FC7B1C439F1DBF173BCAC9A +:102A00005A1CAF3B71AE47E75E8973C4E157044778 +:102A10005AE11FBE1BDB9BE78853CBF36A292FBA11 +:102A200097734C0DEB156B7F95FAB724CDE712F534 +:102A3000F3CBBF556BD8F07335B5EF486A5F23D63B +:102A4000B7BC7CDC6EC3820FF038A97D5C2EB189E7 +:102A5000B5F673C709B5D673C7D5E513779BE7FFFE +:102A6000E5881F714EFB3F1D1FC172E16F8AF37233 +:102A7000930E874DD242E5132E3D7861FF16965B8B +:102A8000E8FFAF30DF8A724BDEC585F68FF3A3D047 +:102A9000FB66FE04E0F7165CC7CDD355C27F72BE5D +:102AA00084E92746BA5914FD96C92C2AE3B944246F +:102AB000A0338C83C6F9DAD06A295E17BF1F51B1E3 +:102AC000DB7E3FA27137DA1709FDFD54AD3DCFA182 +:102AD000DC06F78E979F32D7DD546EC967E8EBF1BD +:102AE000574FB7E3255E16F8597CCB8F87DAEF5F37 +:102AF0004476D33946FCFEC5229A3791DFF1EDDDED +:102B0000F6FC8E35544EEC5743D27E7DCF06D71758 +:102B1000E50D04974BE4BDB95648BDDCAFB89EE463 +:102B20008279AE0B659B5CA0F23700D741938E048F +:102B30009FC6E1EC919FB76C37C699FA7A7E8B5CA1 +:102B40007809E9A2EFF1CEEF779878EFED7EC7F53F +:102B5000AA59FE6E6D5DC1D79F17F3FFCA53E61FDA +:102B60005DEC3AF87D1157F27D11B6AED62E7FCED0 +:102B70001BBED3A9E5CFF9F5FFB277F9F317943F60 +:102B80004D5E07DD47D1FD2CE57D949BA7F373A92E +:102B9000387F8AFB28F376A4F6A7FF7E3A8F5F9BE7 +:102BA000F1EEA0EBD40AEB79D70051EF9B1ECF1BBF +:102BB000F04DC771D772F886A13CC4F31EA6300D44 +:102BC000786AFEBCA1B9085FD37FF2F1981FFCE4DC +:102BD000CCC47893C578E63C2FCCC9ACB1E635E4DB +:102BE0009AF34C97CCF8F4B0E988CF0D7C1D72BFF6 +:102BF000D574CF2BEE571BAD24BF9A9DA69FFDE049 +:102C00006E92677139F463A28B056E93FEA3BBAD20 +:102C100071E3B25FECE67A158A788E97E8775F2DDC +:102C2000F979E7E85768E27993D82F23BE5FE3117B +:102C3000EE73F5B7F8D1312927E1473F5EA84D4142 +:102C40003C833F5D723EE3009EC2B42F6BECFE8876 +:102C5000A57EFA745B5ED2A9D567CB4B9A3BFDEC9F +:102C600079497313F43077BACDAE0F674EC038C9C7 +:102C70006047CA7B14BAD8D7447ED74F69BF9A4DF4 +:102C8000BE13E57BB279FD0DBF78BC56C07FE374FF +:102C9000CBF98579DEC20A0EC530CE63C92FD21CAE +:102CA000D6B84FF89813C75BBA5D4A993FD3835F94 +:102CB000B68AF1B7C7F7F1E6E93C1EAD63DCF17AFD +:102CC00073DC6F37D2B8352BF8B8C97C73A788533B +:102CD000DD99A0E33B691C2D9E6FB30ECB9832E0CB +:102CE0001E9718DFBCDF1374469EC3739D66435264 +:102CF00051BEEA6B97D1B922AB606C14EC5370F003 +:102D000088ED283ACCF98657F0FD825F4BB19D1FC4 +:102D100024A43118F3C497D1B9F3B51ACF5B9958ED +:102D2000D5280F5429AFA505F7AD78FEAE265CF681 +:102D3000754B7E26A7CA67E988E7B3B037460E020F +:102D4000FE16F0E1BD903530CFDBF17C96AAB23BA8 +:102D5000ACF92C91AF97CF62C6FF168700AF967D76 +:102D6000CBAEE078CDAEE0784D9C03333ABF1DCDBD +:102D70006A665C85F165BCB705AF3BC43DB733B946 +:102D80002C8AE7FF8D53D3298ED79DCDE85C15366D +:102D900024ABFA5ACC23E13F69A34A298EEB86750E +:102DA000E13AF05C3676250C2F2FE9174B41CFAF77 +:102DB00066E92CE0C5B8BFB19901DD84F57BE97CFB +:102DC0006EF88A8FEB70DEA5BA5B4512B8BECE579F +:102DD00046795CAB03CE3B300EE9979986F1EC2A3D +:102DE000E7FBFC9CC643789A5DCACB265EDC4C7937 +:102DF000DF8A1725A9BCF6DDC62D072DED5DB1B420 +:102E00004C3C177C69BAC80712F78A98EC253A3807 +:102E1000E37744F11CAA4361071480A35697E9FCA9 +:102E20007DCFF65B5FC1FB634BFD4AC001EB0CAF8E +:102E30009528FFEB7A1FC7D3670DC6968360C3A69C +:102E40000D1E41E730677C1E8AC6372FD943717B40 +:102E5000A0970E05F37AD6C90CCFBDCDFCA7398259 +:102E60005E4C3CA62DFB94F07206CFC3112F45D9C2 +:102E70009407350BF0A1FAE89C7F13E2299DD5C792 +:102E800006C0BC0BFD0E16B3C4A161FDB63C3218E2 +:102E90009BF2CE147A63AB27FCA4AF0BF37C34B95E +:102EA0002A86FB7AA688EF2B940348EFAC94D3A92B +:102EB00089FFF4243A7527E58725D36932FE4F232D +:102EC000DE2DF7B9F6282C10437AEB94C9BEE86ED4 +:102ED00055B228EFAAD54179578C45E91ED31ED6A5 +:102EE0003FD082723326D139C175026F26DE19AB0D +:102EF000DFBC1CE3DCF559018CFF3347FD66CC8F4A +:102F0000BA3E9A41F9778B583BE541DD801E32CCC1 +:102F10007B23F3B9B0BC9C05E829B102BA5FB2507B +:102F200097882F7416ABBE0AF017BBDC996DCDAB3A +:102F3000EA35AF09567ED2721ED1BF42C84B8FEE22 +:102F4000E7799EBAB8F7A3517E507659A9474F2129 +:102F50006FA715EB832B0626CA8AAF9ED1F9747131 +:102F60006448C58444FF470BB55C6C37AE481B8A88 +:102F7000CFBD68E7813E081F1AF508EA83C6424DB7 +:102F8000C5F6C9F2EA78EFF977B1B540775D28AFB9 +:102F9000288FB080F8B0AFF2EF0A2B7AE4DF4DA8AB +:102FA000B0E4DF1D75F27B65948B3C99F5BC9FB650 +:102FB000F63AAA37EFA725DF4B630FF2322CC86829 +:102FC000198BF777EB69DD26DE93F1C3C4BDB4C579 +:102FD000FE97BBA46BFA206FCD07C6DDE0B3D187A7 +:102FE000C1EF2F57DFDA954379840AE51136E7F10F +:102FF000FBCB9BB00926028DE4F6E097425F6DC9DA +:10300000AEF707A07E8B93E7C3B07C9DCD1B9318D2 +:10301000F7CB0AD93C175A8A7400761FD94BA6BD44 +:103020006AB6AB157A6195D00B8F17465612FE1310 +:10303000F9DDABB03FF3C6A20EF3DC8EFFD03990C2 +:10304000693F1C19524FF9346E2DB5BD706B455C4C +:103050009FDF4AE3B79AFA5CBB0DCBD306F8E623B1 +:103060009FB9C2326B433D36FB6692BB4F61DE288F +:10307000D83413F5C6F020D8EF860A71DE54978D48 +:10308000E8621D1ACF278D95D4FB51DF6D199CFA8C +:10309000DEF761B1CEF1C34EC938EE96658C6D1C7A +:1030A0008BF833288FCD5800B204CAE0EE1FC473EA +:1030B000190FDA01C5A817797B5F1DB4817D6C17E4 +:1030C000F80F8E06FA41FB6B943D1FC97C9AED9276 +:1030D000F3AD409467E2BA93F3DCCC7CAB2EC5C869 +:1030E0000CA4807F76D91A0FE56BE52EF7A09E6CB5 +:1030F000D6C2345E72DEDB965C3614E14ACE6B33A8 +:10310000F3A6CC7C2973DC7FAAB0E7B5B9FD5C6F70 +:10311000C193F2647E5AA1F2EF5268F6FC3633BFD7 +:1031200006DB537E4D2EE3F935FE7A86FDDC50C674 +:10313000F611917F969C570572E86744573DEC2342 +:1031400046764673B1C81B60DAE665681FE1F96D23 +:1031500020857D050201F5A00BF413D62BF2EA0AB7 +:103160004CE5F9BA76D4B4E2C8CB48972E7F5CCE52 +:103170001E22781372F697580F72F65756397BE66F +:1031800090F108E66F6E91381D6E01BC3F91823E52 +:103190008E5448828F53D3CF1F04BD361646DEC2ED +:1031A00079B41C7EBFE342EDCCE6849DC9F1D847DB +:1031B0007626E0E377840F21A7011FBF473893F1FC +:1031C000003F9B506E58F24C3FC57EBDE59926F7F7 +:1031D000BFD87BC212C80DFE1D09ED2F0857D5447C +:1031E00095EB5D218F13F76D2F4E5E773A408E027F +:1031F0003C681358DBFB2AB99C2B98ACFB2A492F5F +:10320000F3FBBEDB82FCBE2F8B69A4F78F64EA352B +:10321000C8A72C7FDC39E66B14F9B47A5D84E4FC32 +:10322000DC73B4DF48ED0B268BF5E6F727FDB14DD7 +:10323000D2EE4B9713E573ADCF53A98DAA447F53BC +:103240008FD0F712B6E43B54039676CF44FD5BB8BB +:10325000AE2DF91B69FF5A80E024909BB31CA7EEAA +:103260001E21513EF0D3523F787AC0634B41D7457F +:10327000023F60C5523D7B57F35BE31CB595F1B847 +:103280008A884BFCF323D67B4C732B7FB202E3F18D +:10329000A61EC378C91329E82224C691DDB7DAF443 +:1032A0006472BBD24A7E0F645EA5381F107A6F81AC +:1032B0009BFB51EC30C067D1AB05934315955C6E19 +:1032C0001992451F9AFA8F6A2CEFDD7E7EFF847576 +:1032D000DAC731D7B942D0A9392FD0EBFC4A1EBF8B +:1032E000585069A95F20331EEFE8B0E30BE0594462 +:1032F000F03076A217781E49094F971D9E1571BAB6 +:10330000D556E078A09757E2736B08E82E057EC784 +:103310004C08DD84F50A33B68EC83BABDD5A8FEB23 +:1033200030CB16BBF5B64ABB3CBDBD92CBD3359571 +:10333000244752CFDB50C9E5629F7D3FE03CF9FD59 +:103340002EFC3505DFB4743F99710DB09ADB6DDC4E +:103350004EFC5930EE1CFCC5F9F9C661F5A4E79E98 +:103360001376C8734EA6607E0DF0582055DE4FAC24 +:10337000D2B43BA243102FCFF46277C4DBF5925F47 +:103380007F25DB997131F647CB942319647F9C6EBE +:10339000CB403DFFCC89504AFBE3B9DC9D4352D979 +:1033A0001FFB7AB13F9EAE14F6C7072EB2274A3EE6 +:1033B000E4F647C9873B65B423FEBD52A5F5149FCB +:1033C000E8907580BB04ED0F18679FB03FB03DD902 +:1033D0001FA777CA0857F1871DD4AF04CA687F14A6 +:1033E000F7627F001432E2E1E992963771FF92D7DB +:1033F0005B355EFF85956E8BBA3B28CE63F66BC955 +:10340000DF98A1D37EDBE9675A3197BB897E9CDECA +:1034100093DBF546676572D5D66E58D73696B99365 +:10342000F23295FA87B16C180AE56BE10736906EB7 +:10343000EE9C0D306463BBFA47BB51BF186E1F7E14 +:10344000DFE0B3F4A5DCDF59C37CCEC90979444B76 +:1034500007D08C9018CFE5F13581BDF4A38C2CC238 +:10346000E35A9F19D7D9593102FADF79E548BAFFF3 +:1034700013BA170682F2E44E99EACD38D02B83199D +:10348000E5E903FFCEAA86F1278AF141DF69B74358 +:10349000FB05C21E2B97BDD4FEAE7CDE7EB271AAA8 +:1034A0000ECBC5DD2E15EF993179837C0BC66FD11C +:1034B0002E81F6773D1B29F3407DFA118004C77BEE +:1034C000D745710C0DFE21FF4EE86C277C669C7081 +:1034D000D9E21BE920E16216FBC5955466F2927EA3 +:1034E000A9E493F9EC110F9A21E211D7B0BFFB0ABE +:1034F000ECAD336CC3565CA37B54E8C5DDAC677F91 +:1035000033DEF0FBF19A7706ECE348A74EFECBBE24 +:103510000AC035ECD3BED6D699D720DE772A14DF81 +:103520003DBA3E83F669FFBDCA2E8C2B1D053EE5D4 +:10353000F1F3B52B915EF7679A6516C3F8DCFEF8D8 +:10354000F70A07F07A515667043E40DF78FF40D112 +:10355000DE68E5F56699DDB512F337F60FE6E51995 +:10356000337EBA07DB63C637F9D76B8F7B53C9CF7E +:10357000513355DB3D8F5945B7723A3E473F90F77F +:10358000D7CC18D8B35F5A35F7B3F62F0110C7223E +:103590009EF4C21930FEBEAEDBB68E81A9C64F596D +:1035A000DF41727440F79A54723F3483DBCBB1929F +:1035B00028F95DE0CB73BF972907318F751653C784 +:1035C000A17FBF63EA33FF710DCCF36AF1A871727A +:1035D0000ABEBE61C688A475BD2E2F47B9F4D1FBC3 +:1035E000F353C981E64ABDC2BE1E7E4EDAB45321F2 +:1035F000FCD7FDC7278F60FE43AC6427C5F1F6FDFD +:10360000C1C1D06FD93786DBFF78534FCEE913F8AD +:103610005A27A6A03B806F492AF846CF643C4F74D6 +:10362000BCB614EB93E15531DE0DF08299154039AB +:1036300092F6DBEF77605C735FB783822B674EB4E3 +:10364000C948822D5D234AD16C9D56754C46922AFD +:10365000F1DDBB198F80F50DB28DFF2676A5DBCA93 +:1036600037D40FB09517D70D49F023C3FB4057D877 +:10367000CA6EFFD5B6729015DACAF3AB26DBC62B3D +:10368000F3856DE5E9FE99B6F695EA3C5B7966FE51 +:10369000625BFBEA40ADAD3E523056C1AB7C409719 +:1036A000CD88AF8C4E8DF87C4BD76D3EA48B58499E +:1036B00084FCEA23991DB918B77EA597EFCB75CC8A +:1036C00090857E07D308E524E8F38DD989F6C111EA +:1036D000DDB6B8FCCF67707DFD84A0EF73DF87E3B4 +:1036E000FAF97CEFC125EBE1D957DD4672A965BE39 +:1036F0001CC57B554DF96F78F1FED82BF3793CA1B1 +:103700002517D6E9A5BC0CE2AF17175C3714CFD745 +:10371000D2F3F50128FF4DFD1DCE8FB2E3509FEE91 +:103720008BB22BF09E19946BC57DB370017F3F5A0D +:10373000BC5F854FD0DBE5167C25EBE3A067EC4B47 +:10374000E036B0A97FF2D177FCE617F0B84FE9E98F +:103750006829DEAB9EA9BD70905F9FE6F2E7D59227 +:10376000DFE5F4A2B7FFDDCE0FAF133FEC3B31F73F +:10377000ACF2FF370D3CCEFE548387C5607DEF363B +:10378000F8E8F99F0D7E7AFF7A834ACFE6867C7A45 +:10379000C61A0254FF6643113D0F3668F47CB9A186 +:1037A000829E871A22D4EE570D35F43CDCA0D3FB61 +:1037B000F76770BEBC54E0D1F2CDB842E44587440F +:1037C000789D8F29BB933ED464AB7C07BCFE76C644 +:1037D000849E78BD583D122B691F12E17A2B251F5C +:1037E00039679AF76EB99D3C4B27991F87CF857132 +:1037F000BA9C449CCE8D264D7F82F32F7D09E77EB7 +:1038000011C7D99FCD6A9EE0FED42689F48D6F2C16 +:1038100097E7F7474224CF078E4D2DCFF37AC8F3B1 +:1038200065A4B7D8218C9F627A110AE395387FEAA4 +:10383000B888D12FEFAC78A0734B130F96FD1A3ECA +:1038400033051F9C0B0FC9EB9F56AC8D9E3981DF52 +:103850004771F6EFA94746777FA1616CEAE9020E4E +:10386000EF8EF7E7F6437BC58D4129F2DFC1702B60 +:10387000C2FD66665EC19EBADC9EE3FCA6A49DF412 +:10388000FA5D713BE701B26392DBC1CF41C203EA4B +:103890002D0B1E52C881693353D04199FC6CF746F9 +:1038A000E8BFBF9B51DC4C459B1AE07F46E1DF6BD4 +:1038B000D8FFA183F07CC623917C74AFBBDD83313C +:1038C000EEA7BFC7DB19D512DD63C838B04F453B43 +:1038D00035D8AD0FC0EF8E15C52A9DF89DD0D09478 +:1038E000B181340B1D8414BB9E444B35AE77282820 +:1038F000D63FA97C79A2BD8CFB3F2251CEA3FBD73A +:103900008B705D734FD533B540C459BD29F1B45A9E +:10391000B2C4DD1416D83A318FECCE8397E3F9CDDB +:1039200028169589AE0CF2BF4D78656F84EEE79945 +:103930007EFAE792B60AE7EB317E9D46E76FCCE16F +:10394000A0F3B7F585FA2D33E99C3EE97CC6F7F282 +:103950009F25D0695B1D2C86F68591E522FC25EF1D +:10396000D7B8A2CADBB1BFFF6BFBF53B25EBF70273 +:1039700046ABD3C89F3A03FE14DE476952F83D298F +:10398000E3DDCCE81E0292E5A3DD76A77C7500F7A7 +:10399000FF4719FF48FED15A5824FA5FDB851CBE49 +:1039A00007E5303CB73BB9BFD5DCE8F6B5E5A0BFCD +:1039B00095653840717D96362CCA609DAD33B93E11 +:1039C00077B31BFA45C69C057EE19F38E3FB9EEB6F +:1039D000237F4394BD2EDDF109FA7547E428C6DD47 +:1039E000B68D7DB06639E26FAC879F7F2A31750E48 +:1039F0001A683E83E558EEF1CB4C398971DAAD6037 +:103A0000CCE039EFDDE21E6E66C061B377FA15D9FE +:103A1000EDB59FF411DC2E9444E8B7E6B8A2988F78 +:103A2000A3A2DC02B8B7FA1DC45F9B542E1F3679DF +:103A3000358F2FC5FE6E417CBB7B9F5FCEDBE4C321 +:103A4000B8F74EAF83F877ABAA6CCB83F2562F371B +:103A50006A9B544745AAFCAEEE99DCBE8226699467 +:103A60000F159C4BF64E6FF3B4887D37CBE905BA42 +:103A7000467CA60622B89E266F8E84FB62D6EF9FF8 +:103A800029097DC5E3CADB84FD949EDF1EC3B84EC1 +:103A9000F3E05585882E0FD84327E1BDA7A09DEC04 +:103AA00027EFE52E3D15BC27C478DB9C810AC4E7CF +:103AB000B64C0733007FDBF27A39DF12FAB2491DC8 +:103AC0001721FA067C8C927AB67B5EECF366E74EA1 +:103AD0003FDE5BDB366A21E5856D1BCAE5F3EAC391 +:103AE000BFDED388FE83FA5DF609F24D8E42FBA657 +:103AF000B28007F55CB34FF1615C607CCE1D9EA087 +:103B000045CE25F38973F0DC1ABC4F78A6283D809A +:103B1000482F930FD377459A032077F3306FA9DEB0 +:103B200067FD5E00D8DD9F21FF9F8B4E55A67B1061 +:103B3000BF303ED1516FFB970C8F1725D3B8B3B46C +:103B4000CFD66B527DC7645415C7AB4937CE73D0FF +:103B5000CDB9E0B7E9C5DC845E1C5875D92A3C7F35 +:103B6000BE9BF1FACB0EFF8EFCF4E4F2D7E5CF2634 +:103B70006527C9EDA6912EA2A7E4FEDBF2383CEF43 +:103B8000CC3C29E20431E2DF6C0F8F37DD53D43FA8 +:103B90002D955C2E1BAF8FA9B2D81BD9A5EDA46FB4 +:103BA0005D558CC76BD5886F248CE3ED94814601FD +:103BB000DF8E2FFE744CBD783C2A3BEB5904C6CBFC +:103BC000EA94893EF1E70B9083FD841CDC32FC8F84 +:103BD0000CF347765CA10478DECA4781B3E993AC65 +:103BE00029F678D285C68BAAAA441E431A4BE379DC +:103BF00043552185F2751C5CCF6AF0DF2021222419 +:103C0000B1FF83C451948AAF789C2C670923B919FA +:103C1000CF5FC1EFCFE0383A237B042FD062BBCB1C +:103C200057737B2B97754B781E381CB37864A47739 +:103C30002E3FCFB05C07E5EFC034987F22190ED23B +:103C40008B3F1C7E540AC2DB7B8A578D457C24AF98 +:103C5000636595887BC5D771763C9870F6359D9ADB +:103C6000FABBC9C3F5B1068A3B0D8DE5A4F8679987 +:103C7000BC81EB63C3ED437DDDA4D43F8E65E81DBD +:103C8000A1786952FCF3B3341E1F95EE603EA998EB +:103C9000E29FF9B84F6B597A00E393FD14DD83F589 +:103CA000192315FABB0C60774FC4F396845FAE7A84 +:103CB00079BEDC5ACA2B7C1EF51AB43BF0C5D9E597 +:103CC000D193E7D06B2D9D23BD145FF7D466A03F41 +:103CD000FE947FC461F46FCE7878BE97D9EE40D25F +:103CE000F74F9A859C3B5C25E2E8699FC9D87F9A8B +:103CF0005F5530AF2EE4194BF2BD494A7D5ED05975 +:103D0000C5F5C168F5354E67ABCDEF96AD26F9FF29 +:103D10004EA6A0DF3A7D31C59585BDC7344DF55D12 +:103D20009BB0F34C7DE9577CC6CD388EC8B7EAB15D +:103D3000CE033731FC1E0BF35BE2B32370FE7EF142 +:103D40003C3BE2E724FBAE377CB608FFB8C91FA2B4 +:103D50003C8D3328B3529C9F984FB0530FA29C9A2E +:103D6000D061972F19F976F9B2D5514F795FC6D541 +:103D7000CC877921AC2AE0B7DAC960AFFEB28ACE2F +:103D800077ED76E74DD58C7F673B5B55304E13F66C +:103D900004199E4B28B93AC3FD70F90367DD8FB64D +:103DA0002AAEF79BF39747D0AFD931F53B8497F113 +:103DB000153C0FD56C07FAF29D2A8B7F63E6299C90 +:103DC000F7F7947C0ECA5F3CDF3852CB9495FC7BAE +:103DD0004AFEE5F43DA5A73CFC7B4A0732F50CB44E +:103DE000BF2EF47B4ACBAB39BD863CDF7E71DA084F +:103DF0000B9EBA74CA1F71F94FD1F9CD34916F92ED +:103E00001C2F72BBEBE9BC2D5652BFD81A2F36F1CE +:103E1000D726F4F66F4A74CA0BEAEDEF4198ED101D +:103E200063B82EB788876E29594FF89F5B914DF183 +:103E30002845C4A35CA774CA038E8ED733AA2DF875 +:103E400077E71AA4EF32FE91F1FBEE9FF3FBEE1938 +:103E50001B5908EFB787BE1847E754A1581AF1D984 +:103E6000D4D301FA5E7599FCD8D611507FA053A126 +:103E7000EFC81F989A9E837AEDD34E6EDF661CB80A +:103E8000EAF0DF41B9A4B316630220770096FE3D45 +:103E9000D731F5B4E36BF99913D0CFB49C9798E37D +:103EA000FEBCE110D1C7930D1DF4DCD710A3674B06 +:103EB00043173D8B142D8CEB29EAA0B34B36E90454 +:103EC000D45BE0287A17FA5BE8C1375E1F5F4DFCD0 +:103ED000D7616B9791DF656B077E6E11B653FC1C43 +:103EE0009F2EFCCE188C3FBB8B6D96D4FF51F26A8F +:103EF0005175DFC8AB1BAB079E4D5EF1F3D45097F5 +:103F0000F8AE58123FFE5795CABF8F64F2A53857D6 +:103F100035F5F456FC15F46953D677B87C8BE76F0A +:103F2000F0FB8AE677E9EF78E5E45ECCEB697E5B4F +:103F3000D41B9FEFC5F3DCC4DFCDF8E32ABC77F2D6 +:103F4000023AB76087BEFBCAB3ABF0FB410B6BB262 +:103F5000150DE00BE3016C76E2BE8C99D7988CB717 +:103F6000DF543BCCEFD0511CBE7904FFFB06C9EDFA +:103F70005EAC167E9B6AFFBB1FE9BDDC137AAE9A6E +:103F8000CB8B5F0ABC6D75F13C85DEEE837CBFFA9E +:103F9000ECF741DE14F5E7BAFFF113D1EE0931EF8A +:103FA000B04991FB51FE987F97E349F13EFEF73807 +:103FB000FC2CE5386D42EE5E3ECB27F653A3EF9F17 +:103FC000C1788F107D88BF9F60D64FFA305EFF4F5B +:103FD000541FFF3B093AC589CCFB786DD51D7B1B6F +:103FE0002DDFFF6A8E7F5791E739FD51E02DF9698A +:103FF000DE47897F3F8A1DDEAB59BE1FF540F59B2A +:1040000027C5F7AD9EA6F58A7B38DB70BD03E9FDB9 +:104010007E7A9FF43D81A75E39B8577C47F179825B +:10402000BB3EF93B5DEFEEB57E1F615BF53BAB44FC +:10403000FB97683CF15DAF147421E8F6E85EBC1FA5 +:104040007A1EE3BD46E389EF72ADABE67CD41B3D3F +:1040500043FB23046FFC7BC5B51ED42B897BFF4734 +:10406000083FE781AFA334AF6ECECBF125BB39BF9C +:1040700098F964265DB0597C3F3656C7F3744F12E9 +:104080001C2BFA0C0FA7089EA47B48E75AC7E385B0 +:1040900091CF080E7F3C1FF94F34CED784C7BC3F69 +:1040A00096CC1FFD6649661EB46B16CE931BFF6E41 +:1040B000A77B561FCC0BE366D33889EF81F69F951B +:1040C0005AFE5CD0B84C3DBFFC12B3FCFF0015C8D3 +:1040D0004EA0007100000000000000000000000081 +:1040E0001F8B080000000000000BF3176060F85100 +:1040F0008FC09C687C5AE3BF4C0C0CFACC0C0C971C +:10410000D818189C39191884F8C833E7229ABE7B4E +:1041100040B366F030302C636560D809C47A5CD84F +:10412000F5D90822D847817E5F01C417E91C06A390 +:1041300078F0E01A11068649A208BE9E18AA7CAD46 +:104140000882AD2345995D4E40FD008850BECB806E +:1041500003000000000000001F8B080000000000AA +:10416000000BD57D0D7854D5B5E83A3367CEFC26E3 +:104170003949069884104F42C0A84007080A1675AE +:1041800012C146E5B663DA6A6CA91DAC527F61B410 +:1041900056B956CC4908C92484101015A9CAE02F75 +:1041A0005A6D53456B9FE5DE09508ABDBE277AD50F +:1041B000AAD5DE5829AD566DBC9692BE8770F75AC7 +:1041C0007B9FCC39273393A14ADB875FBBB3CFFEFC +:1041D0005B7BFDEDB5D75E7B8FE27041F509004753 +:1041E000F1DF5900F7FB01605C3A9DF9BD2F5FFDDF +:1041F000781DFBDBEF0E3FC89299BF985F119B962D +:10420000AE3F0724AAD7F08BC57F0456EFDFC1A9C4 +:10421000B9D9A79D0543FE30CBEB9213B09D1BEAA5 +:104220004BFF25C8CA871DE16E964F1D760480F5A9 +:1042300033039CD80968A006A2D3D977F9CB45608F +:10424000EADF9E9EB949865429C0AE95204759BDE4 +:10425000D505A72D1E0C00BCD092FACBFE290091EB +:10426000D449B2C6FAD9DDB297F2FFD6B2EF2FFB2E +:104270005D003128A6711AE67F242F61ED76B9A082 +:10428000B99FB56B8848AE25A6F162623EBBBCA261 +:104290005CAD97339617B072F6BD217841C6F2181F +:1042A0009B11D52B16FD0C0F3AB19E06437E9AE763 +:1042B000E1A68CF39C20DA19F9BA413EDF9D6F1D0F +:1042C0003A1FE99082A2A81BD3C3D56F22BE073C38 +:1042D0009206550CBF83E7117E53885FD6C5A1B700 +:1042E00039BE777DE208B7327C3778D44098E54113 +:1042F00066F460E50D0188105C324B191CE70BB8C1 +:104300002F166913A644178DE832E06174098C0DED +:10431000EF599B1482D798E700CE338F76065DD98C +:10432000D740B480B583CC7C301A3F6CBCD9C70E63 +:10433000A781D7E8FC81BFECF700FD3BCAFEB75070 +:104340007DEE2FFB6BD3F9B386F759F28CA3C173C3 +:104350002A8317FFD43095FF3C689457F1721C27CD +:10436000D1A2FDB986F15F5F0BFCB986F15F6F8B5F +:1043700087F23D2D2AE5BB5B42944FC8AC09A3638D +:10438000A207923A6B5F1C61F54DE315CD65ED4CCC +:10439000F01584554BDE5F1BB2D4F76A9AA53CA199 +:1043A0005DEF4832BA774D73249D12C2C164E44474 +:1043B00084C3432903F7D5109B4F0D6F026B5DDA61 +:1043C000AFAA119E179DD0C6F2855AC47129CB574A +:1043D000869C900CB3F10B8700587F8995001B5881 +:1043E0007F3D334F755CCAF2DDF3DCAA530548B25A +:1043F000FE136ED6CF9194B60AFB99AE84B11FE836 +:10440000937F8B78F2B0FF8E56034CD694B71D8500 +:1044100000553AFB6E9E9F5B0FA15C17CDB57E9F4A +:10442000AC2DBD1658FDC960FA5E95A6A731AE91B8 +:10443000B78F671FE78415B6FE6DFD566A83F5EAF0 +:10444000B474BF27C050AB1AF867EE37D220219D55 +:10445000C2A025671E3FB8032B3E2EDE3F3B8DE7F3 +:104460001E17D78376791B0407E90F90C74184C1D3 +:10447000A5698E6437EBA7BBCA41FCA3AD8624EACD +:10448000ADB593F6C531DF5DA5686D2C5F55BBA753 +:10449000599A01B066924A7CD7BDC30D6D610E4733 +:1044A00090F169A5C1A74706EBAB910F25086F6096 +:1044B000E555DA8156ACAFBEEAD35C7347CF0F56F1 +:1044C000F0F9539ECD7F08FF9833BADF5FCE5122BB +:1044D00051E45B1D926E064F574D5BA3CEC6B95794 +:1044E0009701E5A77B65FF6B88E7C4140EAF7DDEFF +:1044F000959AB204F91ACCE3B3F12A6B2EBC1AE7F1 +:104500006587C3D017DF6F51491EEF6AA9A5F4DE96 +:1045100016B51FF5C45D9F3833E2F77C89EBE7CD14 +:10452000AEA803E1D3E739920F92FE896DBE92E502 +:10453000EFF9EEF859B80E5C3FCF41FAE5CF3D1CDC +:10454000DFF7487D1703D55734AA6F93FF7BE54803 +:10455000DBB758FD7B42A5A03379AE74ED3BF74441 +:10456000EC6F45F54C9DF577CF0D1BDEC6F695F348 +:10457000A66A4ED67EF2DC036FB2451CEE3A3218C4 +:104580008A0630CFE5BA72C5F8FE1AC62713B5BE43 +:10459000EB70FCCAB98A96AC4AF3650584699C1332 +:1045A0009AFD9052C7E6CF8A6B72F3E7F1D3037F8F +:1045B0001FB92A47B92A4DC3BD59D82776BA2F92B9 +:1045C0001CC42F23723597CBD513A7733A1B727572 +:1045D000D7A4BE778B58BEF71B9C4FED7C5E35F79A +:1045E000403DD2B587C94F4908A0CCAD7D2CB17CE8 +:1045F000EF122187730F484B59FB3FBDE2D300E513 +:104600006971667D9D8D9FD3A975DC7B6F70344485 +:1046100059BD5F5E3EF58F6E1C6FB1A2A19CF5CABD +:10462000B534BEF65D45D34DF4AC5CCCE489F157AE +:10463000E50D427E6C7235D6F8899624BCC3E468D9 +:104640007D4B08228C6EEB5A3492AFB542CED01619 +:10465000853296177206B5B3289FCDFE046825B93A +:10466000F368298831FAAC677D43397E4F4522F3E0 +:10467000014A50579D4EE0A41C6C6D5F37520E11DD +:10468000C6F4D02B89BCFE473DC2C653C33CFF6C69 +:10469000EB1FF5554C08D77B797E87545BAFCF373E +:1046A000B7DF43FD1BF5593ED55063EA0FFB9F660C +:1046B00086C7518FF58DFE5E6F2DAFD7D9F8EB44CD +:1046C0005E692BE6F9E3DC7F8FD41F624C0F6B6CC5 +:1046D000FDF448024FFA7F442281F438774AEF46CE +:1046E000744BF91F228827A3FC07ADFFA1EBACFE9A +:1046F0004710BD4B627498B520560E8CEEFEC61462 +:10470000A029B5DE86EFF4FC5EA4F905A6F1FC7DD8 +:10471000AD9F4410DF46F9D352412BE21BF92630FE +:104720001E20444202B0E9E73D573E8F7FD79600F6 +:10473000CC63E3687DA0B13E1C357109F71DA1C5AE +:10474000F2018B3C08BE63F03D2EB174D6FCD8D785 +:104750007029CC009F6E86CF187F2C780D38B2F36D +:10476000271FDFCE470DE7CC7D613E932FFF3E57DD +:10477000D8ADE13C5409F5780902C5F45AF1915DD0 +:10478000442790FB436847DBFB2D59500E49D33C2F +:104790003F6B7ADE85798EB797CD7465F957CD7802 +:1047A0007C1CEBCD19CD77C6FCBC383F403B98CD87 +:1047B000AFCE3CBF279B717ED9F0669FDF3A6F5F1B +:1047C000733483FE3DD321F6BB67CEFD12F6CFC610 +:1047D00003D45F5E6D88F4AF8AE3B1AD66D1915DBD +:1047E000CDB8B5CD369E3A9F8D577BFCF039161F5C +:1047F0000798FED2583D4738371FDBE5D998B71FD9 +:10480000E72D211FF1FD807DDE008C8F0AFEFF9DCC +:10481000F7C732A7E70DAC7F9DCF8BCBC73F685E54 +:104820001F3F5F4AF28AF038393F8732F1D73B9217 +:1048300066D9E7DAF93ADBBCFE517C3A7A5EB9F127 +:104840007CBCF550BEFAB5ED551FE1B1F732BE4F55 +:10485000E8DDBB90FC0EBDCF9F3D01E1284C9C02E2 +:104860001166FF4EC5FE597FBD867DB1A96E8CFED7 +:10487000B97D71670BF4B74F0178AA7090F6C30C3D +:104880004E6ABF99D99F49A6E0EA5EBCC1BB848D40 +:10489000B7F98A0D5EF42BF50A7BB1EEC507D69FFA +:1048A000C3F039E1F292994EC60ABD5EE3FBF6E72A +:1048B000A6B2EF9B2E13DF85FF8A7D7F11EB874425 +:1048C000FD6C70952983B128C90B83CB847FA3FC31 +:1048D0004907B74B9F403BEB44DCCF703BABCCD799 +:1048E000B704E95BB859D1EE9346F7FBBF853EBDEF +:1048F00013ED3436DFBB2EEF2847BB6AE7D653777C +:104900000510AECB80F4F989C987065C1A8EAF4BCF +:1049100088E7275C60D859B4CE975F66D0B5493A2E +:10492000BB86DA093B8BE7BF3FB2AE7E9DEC968A31 +:1049300018CF3FDDF6DDFA55B2A95CFF767DA422E3 +:104940005DFE42DBB5F5B8EECEF2C4DE98CF483757 +:104950008BE9BD550C8E59B2E68C23BF6C0A66B448 +:1049600017B73DE7694E32FC6EDB3A75F2E519D6B2 +:10497000114645A2B3919FBDD72A674F20FEDC8820 +:10498000476EB7F630F462FD504C5B85F89CBD175E +:10499000C2B81FCDA6EFB2D13174B755DFCD92ADFD +:1049A000F33A5EF3F90854BEDF16FDB375FD250733 +:1049B0009F8F13E568B6CCE5FFD3CE278578E276E6 +:1049C000C46F32F5FFF79AEFAC001B27F8D98F13AD +:1049D000B28D93AD5FBBBED21B4092D11F5F0E6103 +:1049E00084A778411CD08FEF0CEC0BE9CCDE93D57B +:1049F000414A5DC1A190CEF4AE12D2CA307557843F +:104A0000CBF03BDB1F09F9E86C25BD3A92EF6A4514 +:104A10003DBA0EF3247F6BA87CC3487E2DE56F9BC7 +:104A2000C4E5F304E7ED03A887AB51D930B8D60E3F +:104A3000BCDE8C7E80D2DD81309A1AA58130A01E2A +:104A400036CA7B07DE0D79D08EDB1D002FE3F7120F +:104A50003502E6F6EB06FE1A525979409407825168 +:104A60004BF9868193CA420C453E51EE0BC5A8FC1A +:104A7000B68179651ADA31BB032A7EF757C469DC3F +:104A8000B37F718D83FCB18B1C49B7495F2516CD6F +:104A900022FDBE588A9DE464F4A8FF458F07ED8788 +:104AA000C4EE6913F03BD93CE44F92FF2FEE47313F +:104AB0007B94ECA0807AE014412F679A1E3D785ECB +:104AC000417E607E4E9110E7147A432A85E3EB85A0 +:104AD0009C4E8CA3D3FE676ABF37EDAFA6FC3E4B5E +:104AE000BE404D46701F2D07997E60EDFD113D8241 +:104AF00074572A78DE1908A7507F6CFA0684116C67 +:104B000099E113EBAF9BC7F21AD23F4AEDBBE6F037 +:104B1000BC128AE9984FCCE47977453C85F9352772 +:104B2000F1FC2683CEF088950FE04F44F7AE91BCA0 +:104B3000B70DCB1306DF80BF0DCBD79CC1F56CB989 +:104B40005CBF13F1BF69A0AB6C29EBBF08F981F51D +:104B50005FB4384CF432E872A7E6A0F5D6A0CB9D3E +:104B6000DA2C3A279859C4304113D2881E334FB8F3 +:104B7000DEA1E279C7298EE483129E4FF5780759AA +:104B8000BD4DB5B3A8BC52760AFF00F7873F28FC9D +:104B900001D5CCBA40BBE341B15EEFBC7D6A11B632 +:104BA000DBB9F97F11BDCF741653BB35B5FCFCE6FC +:104BB00019B64EA39FEEE9160FA53F62FDC598BE3C +:104BC0007EBCC543E90F5A544A1F617A1CD31E5656 +:104BD0009E42BF032B4FB17CFFA0A311E5FFF61649 +:104BE000669AB1F6B7B5783E96A7A0BF42A5FCBAC3 +:104BF0009610E5BFED685AE1E4FE14FF3436AFA726 +:104C00005EAA21FF5EF875473489F356A174515DA1 +:104C1000FABB819F6F3B1A5622BFFE7050A67140AF +:104C20001EEC3E2573BD36AC37E37599F7171CDCD7 +:104C3000707E3063BD4EACF7D87E0E377852BE2CF6 +:104C4000FDF520BCD3DE12F085522559FA5B8FF5B5 +:104C50001EDD2FE00B24BB4FCE5CEF0E1CF7E4B73C +:104C6000047C15C90DE7651EF7FBD89FA784DB2BD5 +:104C70009F437F461DAD035B25933C6F5CA24B0EAB +:104C800046674FE9601CEB4DAF8B4BD56CFCE025C4 +:104C900071C9319DDB190E96F7623F2C3DA59695A3 +:104CA000B37A1BB1BCC0548EED597AD2345E1EFC6F +:104CB000A6B57C446F378361A7A6D0D91AFA8A3586 +:104CC0003FD5C1F5E3B3CEDFD623BF4F5578F97F8B +:104CD000631EEDAE45B6FA3E9EFFAD51BF90B7776D +:104CE000C83CEF29E1F32EDCEC49A2DDB57E61473B +:104CF000E8D2407ABEC5E7246A316FCC6FFD399B9C +:104D000043979AE653FC85BB6B2F9D967D5DF16AB8 +:104D10000E8898D6DDA97DD32052FACFAF5FBE6A48 +:104D20005A37705D9920D6850973F9BAC2F0A67317 +:104D30007B95E36DDD1956BC159D69C5DBBA33ADB6 +:104D4000782B3A2B37DE7E29C6CF863F367EC43C91 +:104D5000FE8673ADE3979C671D7FC379D6F14BCE7A +:104D6000FFD4E3A7CC7CD3576F1D5F6DB08EDFD728 +:104D7000601D5F3DFBD38D6FD0A76BE02EEBBA5E5D +:104D8000170533FD12035D21CBBA1EE6EBBA51BE07 +:104D900066E0A7215CDFBDB8BEA37FA696AFEF3368 +:104DA000DFF928847EFB7567EC09E13E631DABBB30 +:104DB0006F5A7ADDD879C68D8E4759BFDF3989AFF2 +:104DC0003303673CED41FDBFA696AF3309719EDB0F +:104DD000DD923A788D2B3DAF828497F67B467EC478 +:104DE0005E82DFD5231F266A1DC25E2A6B8B305B75 +:104DF000D473926CC9774DE3E537B797B5E9E84BC3 +:104E000091F5325C87FCB5F0E76919F65BC6F806E8 +:104E10003CD9C7E7FBE2F4F8936DE34FB68C6FE43F +:104E2000BDD379B92ED734203C9BC4BEF906F9779F +:104E3000A45F8E1F7CD3DB223566F8783E0D1FCF32 +:104E40001BF0DD2ACF68D06BFE9EF09D66C3DF6944 +:104E500036FC9D66C1DF0A79EE31E1CF5EAFC7C691 +:104E60009F5743E426791CCA1190BD199755711EAE +:104E7000C4FBAB93857CE1F818B7B344494EA9E273 +:104E8000E54D6C5D5B2C8B7D98A8DF68CB1BF62B0A +:104E90002E4747C90F93D97E5580EB6D6677841FE7 +:104EA00024BD1E26794AEF3BB81F4396A39168069E +:104EB0007D7087CCCF872535DC8C70CA0185FCA836 +:104EC000D9EAF7C992B0AF75CBF94E110CA59C0881 +:104ED0004708283E090E7F59BB60FA683814391A12 +:104EE000C3719CAA02F7B171DA8B2FD4CC714C8FAD +:104EF00018F08422048FA2727814391CC9E407BE0A +:104F00004FE67E0BA31F06A1683F0468271AF0AD89 +:104F1000F6469B97A03D5FAC109EDA0BACE7E5BF71 +:104F200011F37A41A4ED59CEFD00A331307E69FC26 +:104F30005CB24357CD6DF0205F6A10F6A0BFBE3D56 +:104F400090399EC848ED766782D9A598EF6076299A +:104F5000A6ED81271A71DD39887C9CE15C7B44CF0A +:104F6000851D9032ED3FFDB53E4859FCA74982D3DF +:104F7000AB9558BEBB43E59676AEF132D9F3ED0161 +:104F80004712438DC682BF43C06FD4EB94E31E35F6 +:104F90008FFDB23B6485F7F8E18FB7F7BBFAD54CCC +:104FA000707D567833F8CADEBF52AAC4C92E96A3C4 +:104FB0002133FF3B5D9C4F95524F9CDBEBD9CA7D63 +:104FC000BC7D8095A35D1C886A78FEC2449EE2C4C5 +:104FD0003C280726FC4C14EDDA5DE23C1AE2E4AF13 +:104FE00095B47833F291A742A1F3017B3B23F58975 +:104FF000F69D9F7CE735928F711E920F4963F29365 +:10500000619CC7E4C878174B37C9910998BA8E38A4 +:105010006399E4649C8BCBB1271AD53C3CD4242300 +:10502000FCB345BF7D06FC7A9CCEBDF285BF3A4FEE +:10503000F867A7E19FE19A43F07F0ED36CF04F171A +:10504000F094427800F7EDC8A0D82FC0059AF95C1B +:10505000AE57F45B2AE003B88EE8669477093CE427 +:105060003B9FF979CEA7373D9F46319F7373CDE7BC +:105070000B623EBD2EBE5E791AA35A88F1554916C1 +:10508000BA2C15FD6F1EA1CB75C7C4575FCD731E1B +:105090004BD3F35822F8EAD25CF3880978FA9C30B3 +:1050A0006F3FC6CF4C16EB0D3459E8B2C5E02B3735 +:1050B0005F3700AEB7D0E576D14FBEF3599EE77C9F +:1050C000B6A4E7F33D41975B72CDC754BF55D46F8B +:1050D00013724576CB16D78E36B43F1E93A31DAE02 +:1050E00039E9F158BD4E73BD89ABBB8D7A6BF0BB0E +:1050F000B468A45E8F185FD845F7D37E6C35DA1894 +:10510000CCBEF9E2EA171AD01E67ED3650FF51BE49 +:105110006EB276B799FB9FBDFA8E3651EF4EACD783 +:105120007AF611A3FF4DE6FEB7B852061C77131CA2 +:105130008D23FDDD63AEB7D4D5DFC6CF092BD403F5 +:105140007E935D13CAEFDCC7158C2506D15F090578 +:105150007D687774C8F12D83C80FCCC87B907DBF64 +:10516000C91D9124B67EAA91F8C358AF4477AB4EBF +:10517000A45B43FC4798D71D10C5B8C83BFDB76E6C +:10518000C1FC0AD9A3BAC3686F697434D41B9429CB +:105190009E67B514D3715D3C24C79E7191DDC3BA7F +:1051A00064E3DC54AA25BB25F4DF82C4ED0E0ED7E0 +:1051B0007AFF250984C3CDE0C2F8E0D536B8D878A7 +:1051C000B42FEF1AC7E36D40865A19FB73FAC2D8A1 +:1051D000DFC0B81B09DE44AB5BC5F689293712BCBA +:1051E000AC2C4AF179AE38C1DBE9F2A8188F77A769 +:1051F0007FD9268CB75BA117517D8203E73FB99A0F +:10520000E0F7423CB5A40AD5575FC481F02C522880 +:105210002E3911DC40FBDBEE456C9163E376D76EF3 +:10522000D0B1DDC1453E8AAFF306FA00E3AD4ACF07 +:105230005700E380BCC13EB2334BCEF3F17C05D0C6 +:1052400038259FE7F1B22E1854AB595A9AE071C72E +:10525000DDB54DFA12B463E6F27854D0232F617CA9 +:105260005B31887FCE8A01ECDF35D109CE709ABEE2 +:10527000A57D23ED8B6219E465A45E32CF7AA9FC8B +:10528000EA9524E4FCEAF5E5592F9967BD14AFE7E8 +:10529000860B8A32C57B8CF0FD0285EC0F23BEADF8 +:1052A0009059FE23F64915B7DBCDF68A0B94B4BDB1 +:1052B000827CE65C9C138E156FB606779BEC9BA0F8 +:1052C0005210A4FDC669701AC9E518ED0FB5E8C102 +:1052D000DDAEB1E78B129632F9C9C7AABF06ED3D24 +:1052E00077F672FF8C0B43A4CFA67F4DA48B793A3F +:1052F000937D9F8669B3C87F4DE4173747328C573B +:10530000AF703D5C0BD19C74F00AF80FE0993F6BD5 +:10531000522BB3FA19CEC78D3430CD61B31BADFA21 +:10532000CE23EB0D74CE51CBE307DD288C283761FB +:1053300020FDE282945A4DE78B91C225E3D3F2E33C +:105340000A8D27F9F93F654E90E6127DC288473BEA +:105350009FD8F92260E38B4FCB27171F273EF127F9 +:105360009C79C98FBF2FCF7AC93CEBA5F2AB174808 +:1053700048F9D5EBCBB35E32CF7A295E6FCDBF282B +:10538000C2DF7AFE2AF4C3F8BFE8B1E4D77CD16764 +:105390002DFF52C092EF39D7DA3E709EB57DCF799E +:1053A000D6F681F379FB273BBE7A36FA79F29593EC +:1053B000DFFD8D7252EBC95DBF64D11872E5D16912 +:1053C0003FE99535480571FD62EB9444692499C124 +:1053D000BE7B4EC8FFF32EEEC749C83AED6BFFD92E +:1053E000E7F90385FB8D8CF98E05AFA17F7FEF1464 +:1053F000F696DDFE1AF1EB1C3E7AF454D42380C1FC +:10540000D2A06A6C6AE8C7055F184345BC357D7455 +:105410003E6DEFBF0BCFEBB8DF25D46482E33937A5 +:10542000F7ABFCBCAA2344E7B553EE08E13EBD6BE5 +:105430009294D1CF7244E1E782D5313FD9199D9A38 +:1054400087F461D7247E8FA9CBD547FEE3AE2A6BC4 +:105450007B8FB01F8E287CBCAE957140FB7FF5948E +:105460003B9A715C77EA5F4163707F77529CE247B9 +:105470003BDC7C1FE08EE880EB8247D3E9FCDD0E4D +:105480004FC2881B82BE509369DE4D6ECE373F6798 +:10549000F3C9675EEF280AD557231C7FD9F0B5E31F +:1054A00018F175B99BF7AB85BC84AF837540EB09E8 +:1054B00012D2C9E84824D6F0FF06C1CC6FF6F51821 +:1054C000C027F8ED28E535F9E29CFCD425FC30EB4B +:1054D000D00FC352EDEEAFE5E4E74EB19EBBE1EB7A +:1054E000D4AF5B8B4750DFF96AFBE052C22F4460B8 +:1054F000BCE03B82B73DE2C0F30580F0666627FA68 +:10550000C675855339FC629E5AEB7A77ACEBD96C41 +:10551000375BCFFCE9F5EC20F49013768D03AEC831 +:1055200074FFC358CFB4E0C539E7DDD5C2FD5600DE +:10553000B7403FCEE76527F1B3A306F4F58C5EEEE6 +:105540005A99E21CDC913E5CA4C15303296F61F6B9 +:1055500079BD2AF84E0BE51E77ADC0F71AA4D389A2 +:1055600039EC2C7434B37DD9AB9DF7AFC2FD5BF140 +:10557000022E07237C2FF759F87358E17E8D2EAF4A +:10558000D64AF12C55DC3F62EFB75BC06997AB445C +:1055900096FB3486DCFE55D1B81EF2F491DFC19043 +:1055A0002F4DFB57D2735D93DA3C88A784B681FCFC +:1055B000C4076B14C07B30767D300287C0FF59D0A2 +:1055C000E3C1FB4ADD2F3BE9FEABBD9E17376526E5 +:1055D000BF9EBFD6AA7FC7D227777E4A7DF21343EC +:1055E000EE47EB135A7F2FEF6CDF85F4E9F272FF81 +:1055F0007549A30E4B4CF3ED11E32F768B75A18209 +:10560000C3D1E552EBCD742A66DFEBCD7A330B7D47 +:10561000B2D1FD220C069C9386C33EBF87DCBC5EE4 +:10562000098E3F6D6C3C8CA603C7C32A77663EF893 +:10563000ACE6D3E6CE8F8FEF16F5EE167835E6356D +:10564000969C18FDF70B7C152FB0E97D59B7D0DF7C +:1056500069E0ADD156CF63AD67E04776737BC5583F +:1056600027C6EAFF2D85F387BDFF6C72F89B1139C1 +:10567000D4C92F6B8CE3861F4448EE985EEE9E09DA +:10568000501018247F01DBEBF378A76014CCE73AC5 +:1056900076FD65E8FF6CFAC8BE6F19ABBE12547296 +:1056A000DA49865D5322EE4D7A443CF00629F339FF +:1056B000CFB09023A6D8F38AEBC33011DCB74114E6 +:1056C000C4FDBFC8402BCB8F0F2B5A37FA3FE48560 +:1056D000035B597EDCCFDCD01D4697CB82810186EF +:1056E000AF35114F14CB2778AA46EE69F59D8A7E17 +:1056F0002D6E7781F396D7F01EF0F88B6440BCBA1C +:10570000611EC5691F5CC174D8CCD1F08C9701268D +:1057100096B054F807E8FC10B7945FB1AD8B8B4C92 +:1057200079F4037BACEB5EBEF3B6C393ADDD98F0CA +:10573000A4F7A1FB717C37E45ED78E757E23766D6E +:105740009EF332EEA319DFAB869DA0E1FDF66189E1 +:10575000D21386FD94560E7B299D345C0A1A235A77 +:10576000C57031A5138727D2F7F2E1324ACB8627DD +:10577000531A1AAEA2B478F8144AD5E193285D2FD3 +:10578000E4B0687836E58DFB6F85C333295F30FC64 +:10579000794A03C3F378B9384F5DBF3206E8AF5694 +:1057A000701D62F2B17AE1525A97ECF35AEFE1EBD5 +:1057B0007087B827DC61D3DBFDA2FC510F97FBF5A6 +:1057C000422E408E83D96F7E8FA8B7BE3A46F677B9 +:1057D00087B11E962DB5AC87F6FA1D59EE273F6DA1 +:1057E000940B78A0B6690CFAF0F357773046F706B9 +:1057F0000062A497408E59F46E87017F9EF708D708 +:105800002F7C9AF8D8CB0419430BBD5FB8BBF901C4 +:10581000D43BE7DC78C56E26771FB863377970DC38 +:105820002F5C454CF7FD65378750BFAD5F7807DDCE +:105830006F42F31BE39A3BCFB925FE00711DA3CB4A +:10584000746A77ABC7740EDAB5F4E6E687587F5A08 +:10585000BB033413BF56DEE203CDACBF0E97966197 +:10586000FB8A1B4A2CDFCBAF29B7B433EE49842E19 +:10587000ABB6D453179C6CA957387F96B59D382783 +:105880000FD49D6E69E70E1878E5E7888CFE96F5D3 +:10589000A353CA4CC7B887EBCB6C7C73A187AF6BA3 +:1058A000E9FE73D32D5BFFF9DE0B49F347D6799000 +:1058B000BD1B4F2C5A80F6945B8DD13D9563AF7F15 +:1058C0007CE7916F3DBBBE2A447D558AFA44A234E1 +:1058D00080FAAA14F5889752A3DEB1DEB75D8BFA81 +:1058E0002660D2377398DC67E0878037B7BE3945CA +:1058F000944FF1727DB356F0959D6F42A2DE5AD45B +:1059000037D3C6D637216F6E7D33538CF78FD6379A +:105910005DB3EE887D8BE5BCA7DDDD7C3F4B3B674F +:10592000DE4879A62F642F2BEF3CF596F8FD263D37 +:105930000287FF93F3A5E087A2B956FD61F45F10DB +:10594000B6E911431EFE46B93E22F8351B7DF67FAF +:105950004AB93E729CE4FA88A77B019E2FE62BD7BA +:10596000A3EB1FDF79E45B4F6F80D459B82F99EA1E +:105970004BAE42BF9BA32FCCEFE5C5286EA7EB39FA +:1059800097F0F370FFDF2C4FE43CE49F599EE82230 +:105990002F6B7F7D953601D76996FF227E37E5A371 +:1059A000B67C93ADFE576CF90B6DF59BCDE5094DBB +:1059B0009B80E78B89BD2E3A1F4C688EC64CFC74C9 +:1059C000AE97F3CB5E4F3486FD9D983C7902D2852D +:1059D000E52FA5FEBCBC3F96BFCC965F4AE3A7F37C +:1059E00057D8CAAFB2955F63CB2F33D7EF3A32F9AE +:1059F0004E7A7FE3972EC07B0976385F117AA273C7 +:105A0000CACDB1362E973761FBCEA9B7C42F05E2B8 +:105A10000BF2A33903B6FD1FE33333BFEC15FDFCD6 +:105A20007CD28DB46FEA64FB278A63443F5E06FC38 +:105A3000FCDA2BDEE1D2AEA4FB0F89B2EBC9CFD1E9 +:105A400059D146710A073585CE67135599DB1B7E00 +:105A5000A6CE8ACCE708BFC6205C933D0235DCFFAA +:105A6000876270D481EF0971FDBEBAAA83F4AB924C +:105A7000BA92FB37CA62E4DFB84FD04F09C4C9AF4E +:105A8000E0AE8867DCD7778EE0C3EAD7DC69E04315 +:105A9000EC234DF820396CEBFA6037AEAF096F6636 +:105AA00039FBB197CB992B94DFF8A3E7CFD7872D9C +:105AB00078A925C3BE36E1E271F2FA24EE0790D947 +:105AC0003866BF827DBC9179DAF6D9F70A3C25BCED +:105AD0003CCEDEE8CF0ECFC3A2DEC35EEE5730E68B +:105AE00025AB7C9CB1FA7F162F6BA11F40B5FB2123 +:105AF000AC7AEE1651DF15B4D6CB869F9523F8E12C +:105B0000F15806FF8EC5EFC6387B112EDACF66DE60 +:105B1000876B87E752FCC64128E8EBC67DB3ACBE75 +:105B200086711C37B16D12FA4557C93AC527E81A74 +:105B3000A80FD2F9273F7FB8C9797218F59D47C4DD +:105B40005500C655044D7189C2CF79A7FFD687B1DC +:105B50007C85EE56F17D9361EF641EB77A7805C5BA +:105B60005374B19D3A8E7BC85B99C4F7AC9C453D9C +:105B700064CF3B9D33E399E24C651FE7DBB30EAF87 +:105B8000233DDBA1F17B371D72CC53320D5DD53A3D +:105B9000C96B97963B7ED11E07E952EDF187567C83 +:105BA0004DF771FA26C4FA9BF0869BCDF149219FEF +:105BB00097CA87BD56F83A11BE00C215A778D244DD +:105BC00085C381783B5EF019E32A558E28E22508CB +:105BD000318A57F184641AD7E1E7F8CD362E68F29E +:105BE000FBE6F7638E173E47D6DF18E727197CC41C +:105BF0004FDA024FC336CC3FE7A4F5D43ECE7E5FEA +:105C0000EC349FC92F2CAB317A77C6E8EFDC713CBE +:105C1000CE5BAE00F2E32B106DAC62F35F55C1DFDB +:105C200059940363C44554D8FD15D9CEE5F8F988D5 +:105C3000719E53FF073EAE4FC40B14C020058B1658 +:105C4000A14A9F8CF1029AC4DF81084B3CAE7C3E96 +:105C5000C59107BD9F75BF8BA95F29B21E8EFA8FB4 +:105C6000A15F7990FC5C9F79BF63C0EB85BBA95FA6 +:105C70000C4D3D5A9AEE17F52F39950E1F3D8AE7C8 +:105C8000664E30FE713B5C76F07B55505E48718706 +:105C9000AB83D77BCC746DF5555BD65745EDB84ECD +:105CA0002AC47B9FD7440673F0E56A9423F42356F5 +:105CB0005C1619ACCD5ECF805366D3CFE40FED50A8 +:105CC00062C956B4172B033C5E558ED3F948A754CE +:105CD00032ABBBCEC4BF154A0AE12AA88BE818CF65 +:105CE000D859EA08631C960C3DFBE87D27E7A270B3 +:105CF0002E79952BE4F7CCF3D9ECB3C681AC1A839B +:105D0000DF570B7D9DADDCA5846399F4F0E33EB1D4 +:105D10008EF932977FEC6F78D49761DDD921F454F6 +:105D2000673153A59FE3EC837C2057EC790DF1B0EC +:105D30007ADC39B9F5936AD54FFFE58FFC04C7C902 +:105D400001C7B399E0007C4C210FBB5F5D40C18867 +:105D5000E978A020E76B8C0392C6D37928FD5B5BC2 +:105D6000775F0AED6ED7924004E9E78C6C035C47DD +:105D70008DB82067C4F7B683E8399FC707D5723F4F +:105D80006B84FD477164F373C78D396DF95FD9E991 +:105D9000DCF20CBD1761C06FC4A9DBE7F5A4BFE15D +:105DA0002DDF9C4CF8C86F1FB491F10B307ED9C029 +:105DB000D6778614E86B5129DFDB12A27C4F8B4625 +:105DC000697B4B2DA56BB0E93C8CFF8827AA703FFF +:105DD000127A207439ABB2116942712D5B17E23E21 +:105DE000B27B240FBAC4E0EEC6FBF1CC0EFDAB6F64 +:105DF000C342B443BBC5BB3BA0772C44BB2C9DBF67 +:105E00006B35DA85DD228E565D73DF42DC3F6E9C9A +:105E100064EC93239EAF9AECAF297E17F11FEDD56A +:105E2000A8FDAAD5D89F571679D8BED09A8708C2A0 +:105E3000E3F5F0FCB9FEA7081E52016CBC0BFC4F49 +:105E4000537EE314E17798D634061EB91FA3C3A787 +:105E5000713B685A09F929947018AF17C0C66201DE +:105E6000779EFDE0FE87D6BB9733AF9769B919637C +:105E70005D13708C457F860EB22F500FEB38EE2BE2 +:105E8000FCFCFC788FBBD1756C7851E60EE978F597 +:105E90006BA72F76869FB52F88F4A7AA58BE70519E +:105EA0004A27F1CD73DC32BFB84FC6E68BF26FE004 +:105EB000D9B03BAE433A8E4BF7E70A46E8BCCD2B50 +:105EC000DE13CE17DEA53ED5D20F3CD65096EBDCC6 +:105ED000655CD481414623FAA2B4D127823578BECD +:105EE000385262C917CD2DB7D42F08575BCA5DEA67 +:105EF000C996F2BF954E5FF7A916BE8EDAE6B5D009 +:105F0000569E6FBFDE154E0DDF83AC920D7B740382 +:105F1000DD4B3E883846FDD83793EEE9428D710F50 +:105F200001285EC5AB45883F7D10A6755AA9B0DA39 +:105F3000A972D06AA7869AF594D12FC6677B572895 +:105F400034EEC83A15E0F120C63919EDD727A3AAD7 +:105F5000FBDEDE2ADE2E6CBE7F6F4F65715E4677FC +:105F6000EFABC63E4FB58F13FA4AEE38357B7D084E +:105F7000C8DA0193FC656F27C301D3BB1A5B91F6A6 +:105F800073D2F88F6C5B427E0F37303B9AE17955C4 +:105F9000E84288B17976601546BF04A68CCF3B42B3 +:105FA000B3548AC3D7385D1D1E2E27DFF16B967858 +:105FB0000E6780CB89516F2CFADFE48478A6F5EC6C +:105FC000153FDF271FBA35FE27DC5FEA2F01BDE34F +:105FD000DADF324CEF5CD6A5CE75A2DFE435FF7870 +:105FE0009A4FDDEE88F36C533F75C0DFFB66FF9C74 +:105FF000667FAAE11F86C31E8A0BDE9EE271C1DBAB +:1060000053FFBDEB28E6F73AE85DD1EDFB72DB57B5 +:10601000FDC2BE32EAF5EFE5FBD57E19FC25B9ECF1 +:106020001C71FF6D66CA1677288313E97F68A5E6A1 +:10603000447BA7BFC523E1BA3F4BCCB32E1571E219 +:106040007A3AD6BC76DAE86BCC13EF1FE23CDB037E +:10605000FC3E60BBCAE64B7CCDDFCBCE06EFC8BEB4 +:106060005FCD8C0FA580BF7BA1B8626AA6798F75C2 +:106070004FD180AF03E19330E5707504391D3A428A +:10608000B9E9B04AC067D46B0F723AB433FB201F32 +:1060900078E480151E66E34968170620D9486F9A90 +:1060A000E9F012EE8348556888879DA97B105EBC95 +:1060B0007781F67C719D7439DEFB8871FBB0A02E70 +:1060C00095DA1124F3248AF7324A0707526FB1F2A6 +:1060D0003DCD7E7AEC49BD7C7F0AFB91D521929F14 +:1060E0006E1C8CECA3C91D68EFACC63F994A9FD0CB +:1060F000133A07ED0F19B85E6012A7C9E3857D92C8 +:1061000041DE4DE7FBD25177BA5D36BCD9ED4E3753 +:1061100034E5D657E2BC5F67FFA1BE516DF723ECB3 +:1061200076AE3D0EFE0CD4E7E3F2B887F129C7291D +:1061300082FB3CF81E82B3D6A1E23BCC4CA517E310 +:10614000FD1F7F448614A3675160909ECE1A0BEF0B +:106150004CFF35F2B8D17E30DF236D0A703F50B06E +:10616000A94E92F83D020DDFDD0C36ED0D67E253CE +:10617000833F47F28127483FAE866402E34EF446F0 +:1061800007AD6BDDB5D5C5E6FDD1750149EC430D15 +:10619000FA83269F9AA63F9B5FC43BE3EF47FF929B +:1061A0004556BC1F2B5D5606B85E1A8BFE9F761CAB +:1061B000836EA3E5A355D06D23E9BFAE9AFCF44AE4 +:1061C0009A6EF791BCFA6B2192CCD0AE4DD0CB7EBB +:1061D0006FDF0371C0DFA3708A7854E784539BB7E5 +:1061E000420EBA8C8AB3E2FD3803DC9FB656F285C4 +:1061F00071A8B559FCCB350592D0FF833C9E6FDE6C +:106200009E109E1FF7CC3910C2738EDE4F329F4313 +:106210009E5B20CE4522AFD33EA0770EF70BE23F28 +:10622000D43B37F13FA15A7F7713BE63B6F64DBF1B +:10623000C51EEA68C9ED6F50CAAF88A19D71E86DAF +:1062400049C3F5462A5F7122C235306F29BD3BD262 +:1062500051B793CE617AC2B9E962C4997688B8E839 +:1062600091F1B39C1B1E12F25AAD5F4DF6656FD9CA +:106270004B34CEDABADCE3E07B59B9EE45791C1039 +:10628000237FB1ED5CF70D31DE1B01713EE18A7EAB +:10629000697215FE2E874EFEB1F1B5D10107C35BC1 +:1062A0005341ECD500A36BEFBC1BCB100E7C27C673 +:1062B0004CF720F69F01BEF1050E8BDD74A83AFE67 +:1062C0005F2BEBF0F729A6D2BBF546BD9E2C71ECF7 +:1062D000271B74D6BCB4EFE9C0B87F065F4F597E68 +:1062E000F837E87C163CEF998CEDB3C4F91AA97D18 +:1062F000BD1F0BEF763CF4BA06290EAA57CA3C9F85 +:10630000730BB8DCF5AE4CF173B57907E85C2D90F2 +:106310007A9DE227BE3B671F9DAB5516707A601CC5 +:1063200025DA518573F97B80D9E4E85E413F59B5A0 +:10633000D60379D072EEB32520CECB82B9FB33E001 +:1063400004CF203FEF192D97B4FE3CD8F3C01E7A3E +:1063500037055274AED0F18A13EFA68EE061945CDB +:1063600025F8EFC2F4E2C6E3741CE7D60EF493F40A +:106370001AE76C33F9BE49AE4BD1399BA740B3D86D +:10638000EB81B0F12E627EF30CE05AC4FDC332AE55 +:10639000ABE88F47F8DA675E48FEB46C74FD8E3F59 +:1063A00036BB609CD9AFCFF75DFF6C7C7828A059D5 +:1063B000EC433B3FBAE11BC7B4AFCBE65F3E24E4FE +:1063C0003388154DFBA46F162899F1FBD64563E180 +:1063D000F79B99F17BB10FE13D747BE6DF2732D269 +:1063E000BB6CFAEE2E231E057F24A48CFAABBA20D8 +:1063F000C3BC8D75F55081F17E4FCC87EB46B53E21 +:10640000DF87E33FD473A90FC77D68536E7A1AE321 +:106410006F11E78B49F1EE88519E147CB9D5A6E740 +:106420005F16727D8F90AF873C511FFD5EC5AE8BAE +:10643000CF3B89E1AF9AF105BA14B52E28C9357E54 +:10644000956EDB971CE3BD96DE025B7C6F9EF73496 +:106450003F2D5EB622FF9C8E78F877927B67AA88E4 +:10646000E4A9FA1ACE37D5970DA5705F3B79A3231F +:10647000A9511C4B8CF052768DAC514C9BB8F77ADD +:10648000A258DFC1798BA312CBF1DEB88A6E17F563 +:106490006B140F73B7F5F73F1EF244DA14B47F1391 +:1064A00014E908D53DD6DFCB9808A6DFAB60E396AC +:1064B000BDF92EFD7E4A99ED77413E2DDE77FC83B6 +:1064C000F09E94C167D6C79A04D14C7AFF3F055F0E +:1064D0006AADBBF93B06F100BC633AE760F42B41BF +:1064E000BB608BBEA11EF1A927203C25831EFB6D3E +:1064F00081DFF81D9FDDF8CE82AB82DF3F5BBDE41C +:10650000C2C11D4C656DB9A5C1721FC0A4177E5BC9 +:1065100040EB13D70B49BD89A7879DC427537A2029 +:1065200089BF83B260637CC085A27E0D7F87BA2C51 +:10653000A14B0ACB5733F395750F93AF005E7F31B4 +:106540002423C447F06A687CFAF74E2A07AF1BC0C1 +:106550007DF11EB62FC6DF51317EAFC4E097897141 +:106560002B7F4C4958F3136CFC626F5FADC17938D7 +:106570007E4D8F03705F37AED9541FFB83A1771F09 +:1065800066E34FD98D0F33B2B42F77FF32C45C85E9 +:106590000C9F4FDD1AF8652D9BE0FD3D0DA58897FA +:1065A000873C40711107A31E7A7701A299CF9346C9 +:1065B000F1AD61F767A99FD697BC9EB1EE75BE2974 +:1065C000F1772E2AD5B7ABD0CFF92AFFDDBAF4BBCD +:1065D00015A7D3BB15218873FB11A294B60BFE54EB +:1065E000CFAEA8427F68E22DBF8AF7B3D452AB3F4B +:1065F0004D2E69A4F7C046ECEE126677B3F244B1B3 +:10660000558FD61772BB355CC8EF85AA7EDE0F7832 +:10661000F432B3DEDF582859CB037AD9974DE50D14 +:10662000A27D42BC5B7E56E1799D68CFA81359FDDF +:106630000CFCB9408C6B944330BC0FDFFFD8F48D59 +:10664000A639E6F57C63213FDF514F10E35664869F +:106650002B51C5C7BD4D8CBBB1D0FA6E1CA83C35C3 +:10666000BEDF5170A3B49FE1FB900B1A305E65D57D +:10667000384712DF4DBB69BC1117965B4F18741871 +:10668000C1B7CAE391CAAF50673933C8B1916E6ED2 +:10669000E47E2AFBF74BC43CDAAF68E8AB61704597 +:1066A0007673B9730721E3391093EF4B0AE7645807 +:1066B000F7DB1B691F77A838F7BA6FDFE7CAC2BFDD +:1066C00068AFD72AE8A4BD1CA2A7B8DB43DC9F684B +:1066D000F47FA88CFB15EDEDBA6CFD7BA1298271CE +:1066E000C678BE8AE7AA4A0D24F1BEA92FD8A756BC +:1066F00069181FB04FC7FD91060C8FE8670B03D9CF +:1067000075ED21BE1F95437DF50E8C278146D56C16 +:1067100087958BDF5534F2AE40ACB590ECA1884440 +:106720007891F979FE2157F25CC4E7AA2A07647AC6 +:10673000A7BFA790DBB99BB5A617AA32D06F7DA1E2 +:1067400066B19FCB87B9FD9DAD7EBA1E876F841F52 +:10675000433ADD3F008DF3635341E4F6C24CE7B7A3 +:10676000865E117EC84BE70A850BDA45BF66F3B833 +:1067700072AF8B62D3CF3ABC650FEA5F27D3BFDD20 +:10678000F43B727D7BD00F7919DE7F62F92BDF9CA1 +:10679000AE54B2F257CB9DE2D1F968218EFB01389D +:1067A000C85FF201BC5438DB44BF270B15BEDE24A2 +:1067B0005CA4470D7FDCE57D2E8B5EFDF6266B7EAF +:1067C00029348D473FC5D28D2E4832FC5E69D3BB3C +:1067D000F717F273A26F43BC03D7CFD5E2FCEFDA11 +:1067E0009F4C57506EAE9CAD56394DF7AE9E2DE482 +:1067F000F6DD7B8C8F34939C5D15482AB88F7B67C0 +:10680000FBEC0B3F0FD84FB2A31CFD69C599E30009 +:10681000BF95B0C239D63CEC701BE779D9E090B790 +:106820004919FD42CF154A167FFC2A0F7F0F29B266 +:106830004A06EF9918870774CF4F7FB380DEEFD6F3 +:106840001BE21457A7B7B9D555418AB3A378BA1537 +:106850008C60F8FED001C17F465C1D33284EC37D9D +:10686000DAB59E4105FDCACBE57823FE749A712EF8 +:10687000E376C5221319FCAE67EA5313C1522F9178 +:1068800067BDBD52755EF51A1D39FAFB50E8C95F48 +:106890003C76BF82EBCF078FBEFD4594C3AB9F759F +:1068A000025ECDFBF0B10248D1FE21A9A09C5FB5EC +:1068B000DD99F11D098631EAFFEA1F15905EBCEAF9 +:1068C000097772116B7FD5D3EFCC00264F1FB60D21 +:1068D000ED9988F87B54E2E785FAE00C5C9FAE9274 +:1068E000E19B99DE1DF31671797FFFA7FE66A49FD9 +:1068F000B46DE012EAB7FF2297F95D7C28E2EB0F56 +:10690000ABC7E3261F91925332E80F633FF4FE2397 +:106910003CAEE4AA675C490C09BE6ADB5625C6E0BA +:1069200058BEED23E297B37FF47821E261F9334E4C +:106930008B1D71F58F3EE9389DD1F96A270C2D42E8 +:1069400039761EA6FCC18867C84972CDE35396917B +:106950000A60F59EFCFD39BF66E5EF859C8021AE9F +:10696000EFEDFB9DF22CE6630166B961FF56BE5E5A +:10697000BEED1D857EC7C80143159FC7F30FAB9DB4 +:1069800064AF0F30A4A09E5ADEDFF59193F1DBF2E5 +:10699000ED1FBC817CB7DC261FEFE11F65A3EDF383 +:1069A000994536FB7C5B695EF6D1D58F1FBC17FD20 +:1069B00011EF3FF1C77BF11EED35473EBEF77B1867 +:1069C00017F66F5E15E57BF9A3AF148249FF9F5F51 +:1069D000C4D7CD0F1F79F8A1CD6CFE1FBEEE266C7B +:1069E0007DB8E3F795E8FFF9F0C77F1D8FFEA01B88 +:1069F000762CA4DFADB9E1A9B327E45A17915F93D0 +:106A0000E6DF5714E746DA33121A93003F13A98DD5 +:106A10001ED037A4E0BAF6170986BA8BD9F7FE4F15 +:106A200014B4CFF6446008F1B36BFB3B7B6E66F9A0 +:106A30000F187DDC19E8C3E63FD141FA99890D4B67 +:106A4000976DFFF297CEA8C3D44576F8721822BD91 +:106A5000398AAE2F33BAD6A5E96A2F3F0887153C8D +:106A60003758FE18A3E30CA427A3E38CD174FC00D1 +:106A7000FF98379A8E571559E3920EC2355B3663ED +:106A8000E1F6D28CE7BCC63EEBDAA7BE9AD37E32E3 +:106A9000F4C25878BE42E2709D5A14B9B908E5EBC9 +:106AA000891F3CB439C8E9BC8821E6C3C70F560228 +:106AB000E3933FB8862E413C0CED70ABB8BE5FB59A +:106AC000E357246F1F3EF5A2A2517C0B144AA7B2D4 +:106AD0003C8CFC7B09587E99C433D73EF0FFCE79BD +:106AE00083B5BF167F3A5525FA517E0F933FA247D3 +:106AF000F282460DF56E721CCD7B5992CBC5B2E485 +:106B0000C05730AECF8EF7278B1C86FE1FA12BC639 +:106B10008D2DDBFEF639C87FD9E869CC5FC5F99FBA +:106B2000C6CA1FB0CA6D563915F4FD70EB2105EDCC +:106B300083D4B38AEA60F6F087AE2185D6C71F3BBF +:106B4000D507C3A3E99EC6BF883F3AC67DF80FEDBF +:106B5000722EF033969C8F3DAF63C3DBDD451ADFA9 +:106B60005FD9F0F7FEE1CCFAFF39A1379641BCB10D +:106B70007CF2E8F54B86A83EB12A0DEFFB183FC624 +:106B8000E07DFF5127ED0F3BFA77911EB7EB8B6548 +:106B900059ECE8378AB83DB0EC998119A8D7DEDF07 +:106BA000F953E2CB658FBDADA0FF66CFB62795C187 +:106BB000696939C0F5C1FC3B38EFFF706006EAAF88 +:106BC000E559E2007F2FE6B3FC67D6FE973FF691CA +:106BD000A5FFABF57E85FC64638CF39E1CB908E7CA +:106BE000FBDE3E179E60C07BFDCEC64C76CEF362C8 +:106BF0007D34F0D45170EA6B4578EE55C2DF616C9C +:106C00006F8DFC8A7EBFF74597D8DF465E437B6673 +:106C100055B142F711DA0B2E247FBDD15F9F0D9F36 +:106C20006A50ADC7FD80BA205A67DE5719F0174782 +:106C30001C16F86F28689CA005F8FE4C63FB8FFFBC +:106C400001AB8A1A34008000000000001F8B08008E +:106C500000000000000BD57C0B7C54D5B5F73A73CF +:106C6000CE3CC24C2627AFC9D37892F09480431211 +:106C7000DEB40E0491226A505AA9F5AB03F28821C2 +:106C8000C9A4F8E25ABFCB8444F4029F8D95166ADA +:106C9000693B70A152217690A0B10DDC012C060554 +:106CA0006F105F78B18D5A152B246314B4575BEFC6 +:106CB0005A6B9FC3CC9C4C84DEFBFBBEDFEF0BBF4B +:106CC00076BBCFD9679FB5D7FAAFD7DEEB0C28DEFE +:106CD000DCEA5400D93D6B366461AB5AD41409E048 +:106CE0002BFABB2AD6028400C603585DD5E0776133 +:106CF000AB5A407300FF7D45FFA7785B7BF0F97BC3 +:106D0000E5D4D6B5348FB5F157D4872605B657F2FA +:106D1000B0914A25DDBFC2BBB61860A3F39F1FA781 +:106D2000FB2B8376D58E6D73EA3DBFA5FE0609AABF +:106D300065EAD3F3383E6875A8DB55BC9E0E0BC2DE +:106D400065317AF25424321BA00CE9A016FFFC3006 +:106D500001DF2B488266A8031C012959A120B5C672 +:106D6000730FAAFE62757CAC2FBBBAC18FF35E2D88 +:106D7000BB2CB4FE07732D217B31B537A641D9401A +:106D80003E18ED03ABAA213262F0FBADD98E855BD4 +:106D900080E90E5A681D9223B49D08F181A67A807D +:106DA00069030DFF873C74C4D18D037CB40E45BFCD +:106DB0006FC565D14D3B04B94D213960EB84084066 +:106DC00029D2AD96B05C52A1479F240AD563006ECC +:106DD0004CF57F93D6993BB451A2EB1EA8E6B612B0 +:106DE000FC12DDB738EBF2FC5FB33E58A09CE9190A +:106DF000A9CB175FB1C12AF8AF28A00C29273A36D2 +:106E0000ABEF8FC679E87E268D0AB21CC6557D672A +:106E1000740BC181888FE3F323336764126E8C7126 +:106E2000CD8EA29312F2DB27A7A82945D85790331D +:106E3000C4A753A9CCA71F4DC399F1FE8F4FA56ED0 +:106E400095511E8F48024F41C213E10A1A1F277C39 +:106E5000B8113F6BE9B9198DBF65BC58A0BAB952DA +:106E6000E7A487F827FE106F8CA7958A43B57B8926 +:106E7000B73E4DA1796C105A2B11BD7EE6A7035A7F +:106E8000B91D02616E5DD0CDED5DC4E76C92839754 +:106E9000FB69D0D33A149F9BA356D7AA78FDC7B3FA +:106EA00033245A9F0B549DBF8579D41F94BF3391CF +:106EB000BF8E187FEDC44FE7407E3A40653EA47B0D +:106EC000C1BB761CCF0B115CC723D321243388545C +:106ED00050112F39FA3A33C127117D841F5A5FF6BA +:106EE00002B13EF3FB72A195C7E54398DB42E8E6A9 +:106EF00036C3A14A0AD3734A97EF3BF09533468FC6 +:106F0000D1DA09C138FFB9429CBF98B9ED963CB4BB +:106F10007EE3AF9A71F887CA83BE2A1CA7F85D3E4C +:106F20003B2EE5FF54CE201082F5720548AEAE9E92 +:106F30008573C18DC3BD36888CA4D9834C5FCA4884 +:106F4000D137EC8B1D051531E8C7E7ACA73E3C45B2 +:106F5000CF59216E1CD121DF9A467C7F982E4C1E82 +:106F6000C8F795A79AB29E8B9B77AB9A9A45EB840C +:106F70008930F12B39F63C4CCA402333F0F9CF5617 +:106F800005B39EB3C6F8D0E2F867C6A50F019CF220 +:106F90004DEC138EB36238465CB29D0BAEB6ABCDF2 +:106FA000598C43C6E94A64901DDBCF528A42BC7EAD +:106FB000689C7823DA618BC3274978BD4E75878832 +:106FC0003FF5AEF02CB61326BB317DBE1AC9C77192 +:106FD0007D8DE025BE6EDC73C369E26B9F07347B59 +:106FE000BAC0856F02D909C38E8026A37CD748E337 +:106FF0001C12B6F5ED1FBFF47B1C9FD229838CF7C2 +:10700000FB70CDDDB46EC5974E4274C2FA04FD6EBE +:107010007608FD31D669D6D77F749D28799E9FE585 +:107020002093FD5DFF2FF47C3FA4B6D2F84D0ABE3D +:107030009AE6EFB286B6231F561C91196F2BDAA47D +:1070400010909C152D8DFAF7BE2883C01FF0FD7B94 +:107050007F55CA789461F48FA6E1F381CD562F5AFB +:107060004C48F725FAABCCD943408BC301047D2FA4 +:10707000E722BF16EBFCDAE87C780BD1B3A949F81C +:10708000A7ECEA8C84F19FA55C6F5B8AF36B79486F +:10709000D714C24DE7F035D85F5E20AB329A889C9A +:1070A00005F989FEB1D5FA0EE99F86FF08DF86FD56 +:1070B0005A4AF68BEC907C3FFBBF7320FC9F02C2C8 +:1070C000FF35A0BD8AE07CCB3689E78DF96A3A1F8F +:1070D000595380ED1DA1C4EBCB4189F5D9CFBA47F7 +:1070E000921D580943BC766920FE2DE9887F0289EC +:1070F0000B5C420E2E2FD997FE5764AF5DB082F520 +:1071000095F84E7644EE19B1711ACE17E8B242489E +:10711000237989FBFD9BE550B038A61FFD5D7B9868 +:107120001FCBF2901F884F7B6E22FF53B444FE3B6F +:1071300047667CAD3C52BD267ECA7399FFC86FA0DE +:10714000F9D32695243EAFF37B24FE13FCF6319D44 +:107150004B3B24784C223EAF3F5CA00DE46B43C711 +:107160002336D2FF8BF1D5CCC7D1E9BA1DD1F9783E +:107170000E3A0FE8A8AC7678D894F03A14B5753A80 +:10718000E1B410F5967062D66B837FD62CD567C3B9 +:107190007197D1385C5FBE232C94D10BCA09C2CB46 +:1071A0002261779B551FFB23C3DE3A2FD8ED77E191 +:1071B0002B6CB3E6553E4438BA534A6D952B07EA1B +:1071C000EDBA31F7B0FD2A5C8DF698FD6A629C1627 +:1071D0005EE5F02E467A9E5C05DEC5C3009E5AA58C +:1071E000726B8EDF0C7DDF8CF19B5DF8679E5741E3 +:1071F000FCAE55C9FE7855A2F3611BB09EF69541D1 +:10720000682BBE3F1CF9D4A391BD2E8F5E5F8DF11C +:1072100045600954539CF1AF1922AE7B466F6765F8 +:10722000D8B85D5B6D011FBEA7B7530E49485FAF6D +:10723000EA3B7215D99D4EABC6F1951A7DE97B7C70 +:10724000BF425D8BFCCCB3B48EA3F7E2F8D9219C8E +:10725000B7AFF35DF7ED717EB9B7E3D1511407FD18 +:10726000CC0235E124F1D0F2740BC731BD23DFF13C +:10727000E0B2A1DE11B501E2E9C19EC66A8AA7EEBD +:10728000746A4C97AD7D7AA480F1338FE3E3E7967F +:107290000E61BCED3D0321D2BB59F2ADD78EC1FECC +:1072A000E45715AF9D95CA77FDC2093C84E5BEE160 +:1072B000CB8A4DC4BF00F273355F6C3D41F27AF664 +:1072C000CF0A90DE55363EFDAE1FD7793817D13044 +:1072D0000960822F5C11C151333BD3A7937E074EC7 +:1072E00001EBEBF86E2501B720D71D2A20BBF286F3 +:1072F000080F27BE61BA0F4199E2FFC93D89D7A7A0 +:107300005E04EFFF62D80D377808EF8FADEA807723 +:10731000C92FEAFE331F17988C9F06BEF738673CCB +:10732000922EE2769970EB55928F7F2743C4F91B1A +:10733000BE9425C2655F14BCAB915F7D8BF379DD94 +:107340007D9F524086ED97F2EC709278EBD7E9364C +:1073500096DFCF6C02F73F5BEA0A35E17A0E2EAD7D +:10736000BDBC07DF77FE9FFC97AB5F1707A369B132 +:107370004C6279A511DFEF9CD722B11E426B1EF142 +:10738000CD3CDED013436F0C7DC95B3AC41F4AF27B +:107390009EE1B43EA46FC6D291928D70BB5F029203 +:1073A00063EF6AA4EB6BE2C720AC2E207A021D9F2C +:1073B000D8C85F3B3A255F28C9F8C3E96EE65FEF9E +:1073C000EA60D354E4D73D8BF059D20B5B6B71B2BA +:1073D000F983B0A1008343684BD704EE1D701BE90D +:1073E0002528AD79E4B77B3BAABE4576FD31D44371 +:1073F0008A1B7E66F532DDC17A80EDC4160A3CB187 +:107400005F783D6C591B974776A74F3F958EF39D4C +:107410004A5779DE4CBF5722BABD7FFBCC4DF3F7FC +:107420007D6E67F9E5930EC7C56D9FA60BFEACC9CF +:10743000F0BDC678A9C96263EAF5BBBD8B2B00AE6F +:10744000EC407EC7E13226B720AF3BC31F647A32DF +:10745000BA3171E2FCCBA751BC1CD08D334424500F +:1074600026C4EC73A5A3305220F287700EF237A326 +:10747000E6C76CAF53D00E53280EDD8979115B64DB +:107480007C9E749FEC42B32AE2AC967461E75A1E6C +:107490005142CDF8DECD4A4FCA306C8B7DDA0C45B7 +:1074A000237B5FC6F3E6DE05ACDF164748223BE4EC +:1074B0002CFD45FA85B86B2AC0EEBFC9CC7FB39CC2 +:1074C00046EB7AB126C3FF05F1756C57F420856F42 +:1074D000DE14C824B9CE925DBCEEC96785FD31DBF0 +:1074E0001B39F2AB9F91BDE9D3F3A724F6E676F200 +:1074F000AF86BD01B9EC10E167EA8B7A9AA9DB1976 +:10750000CC3E980F138FFA9B5D49ECCB24A84E43D9 +:10751000165FD4BE98E588C1FE857E2132A3A20BFA +:10752000F528EE79B33D2AC8D0FDAF6E8FCEC1B439 +:107530009CABB5185ECA577A0FD9E3F061D8A11891 +:107540005E428C33F37B24705CE8ABA5643F8ECA4B +:10755000696477A6A3DC71FE2E5D4FD23F0D7D8B53 +:10756000E4BFA1F39A14C2F5535D550E529B15B9B1 +:10757000B2F6678C9F9503F383A0C385EC9DF15E03 +:107580002B3834D748E28785F920ABD88F7B7F7FB3 +:10759000AB349BEC220A2D6DFE98C1EDC18A5C1BB9 +:1075A000BFE7A9AE9234C2910B30BF45F955764A78 +:1075B0001C2798716DC67133BEC0C2796335C7137D +:1075C000B214D6F71D12F3D2E2E064F65377611ECF +:1075D0004E716B7F17FA2D6C9F423F4F714AB36B10 +:1075E00016AFDB58AF41DF5DA93372A06CE0FA8DB6 +:1075F00036F0B90CA1CCB8BE12B5118E039FDB12C8 +:10760000AE1BFC1C8C0F063FA7103FA5FF3E3FA7FB +:107610006608B99AF9FA3F5D7FE18A49906C5FE0AC +:10762000FF97F54F05FFEF7B44BEF55AAE27664F37 +:107630000A57CC9697211F26503CEE8DD90707FE9E +:10764000237C8DED68657B3309ED0DC5990575616A +:10765000B62F137345BE64B61B5776C24D641F2701 +:1076600047302EBD04FBF129FD471EEFE3FC32033A +:10767000E91EF7FC82E5BBF0D2580D32E7E27BC68B +:10768000762B5EF27BD09D99745FC0EC378CB8D4BA +:107690008847CDE38C78D4F0270D3A1FFE3DC3FF19 +:1076A00064065D57D520E91BEA55F8312FC35EA368 +:1076B00078A13BBD7A37DF1F190E721E50022AEDEA +:1076C000EBA0BE721C56E97045E4B103F5D369D254 +:1076D000C330F285F609822E4B689834900E0CB7B1 +:1076E0008314F7E103FCFEA5BABF28C4312CB4060D +:1076F000E0F8BF702CF8C9EF1696638BEB3CA6C779 +:10770000232F995AA4FB79E2AB5581A0BDFC1FA79A +:1077100097482C2827FEF8FE40EB77CCF631FD0584 +:107720002A78298E2F50C29217DF9F51A74917360A +:10773000910C3F8DF315CCD5D85F160CC53E8DA7A7 +:107740007827895C7A32ACBCCE7A47CF611BF221B4 +:1077500030B771B6DB128BD3ED56BFAF80F68F3AE0 +:1077600044BC0EB4DF379EED9244EB516608FE0434 +:1077700054915FB94065BB59A9CBB1D23197F77726 +:10778000C827DA270F5CB7A4F97870FE7CD0829303 +:107790006376D5C87F701AA0F798ED6ADFBED72F41 +:1077A0000BA23EBEF5BF3F4905BCFF27259A4AFC08 +:1077B000387DFF89541FF2E3ADFB45FEF27D537C1B +:1077C000A4640AB92ECEACFE82F87ADBAABF4D883B +:1077D000B72FB0329BF5E28E904CC9F005FD59BE33 +:1077E000C3C97BCF46BF3E9C99D037F4A0DE0E8D37 +:1077F000C9E2EA6999222FBA63D7161BE5D18B3308 +:10780000FDA999D83FADC77FA7DB53793FC0A067DB +:10781000D1AE7136E2F79F3AED106103D96D157262 +:10782000F65D2F4DA0CD7BF167A6F3F0FE021BEDB8 +:107830009F2F91202AF6B5E0F0CFB1FF5EAE0C6B22 +:10784000BD03D7B1E42DD56641F92C990ED120EABC +:10785000D5A2BBA435F7E2F8457E17457003D6B92B +:10786000309898E72FD3E395DB1FB29AF2A4C6C3F2 +:10787000B45FB618E7A17C76496BE2FDFEAE3B0F24 +:10788000FF9CFC40878DFDC0B28BE44FE332F5785E +:1078900065024CFCAA94E295B21F956983DB25230F +:1078A0005E39BD0A083CF097550E6ECFAC52B9FD5B +:1078B00042B7D7CB3B0E1C665C2BDD13C8CF3ED541 +:1078C000F5AEF3162DE637BEB9E593433FC77E0507 +:1078D000ADB398EC65C44A78BC4AF71BCBF438A426 +:1078E000E273B3DF38F087DF539E8DEBDFCE19D71D +:1078F000A5C523B782F2693C1F0C3F62E6477F575C +:10790000A99370323F33713FF67FCA97C19EAB9700 +:1079100011D749EC87A14F5F64087C2FDE366F4D8D +:107920003EBEBF79DF07453DC22EBD069E185ED123 +:10793000D033DE960144D7223EFD9DFF7498F87443 +:1079400098F03689FA97F1FDDC2AC42FEAEDB2CE21 +:107950000FDF84B1AC5FB9965C6A23B9945F9A710A +:1079600068C69F196FBDD69E22B20F669CF54A89E4 +:10797000E76446BB34539C5F2CD67CB328DF45B705 +:10798000B646E5F508FB775A693DFC43D2DB6D123C +:10799000E787F5CFB43D4DF6A8F6B73F71933DFAB2 +:1079A0005069F5D0FBEAB63FE0F6915D52826E7AFF +:1079B000FEC390B04BE6F775EA7C34CE052EF8A5F1 +:1079C00087A26BEE437E9C477D26FD6D68FFEB9A98 +:1079D000FB28CFF039A294779E567A66111D772C3A +:1079E0007435367929BF4D5C77EDE33FF168BC7F94 +:1079F0001C2CD0F9C7F96AC336AB3782F336BC22E8 +:107A00007BE9350188F2FACCCF07C2EFDAC87EAB4A +:107A10001688164E1D781FC56823BD09B4AFFB58E4 +:107A200076532BE415203EC79D33D4E876D88CE3FB +:107A30005D99FABE888E5FE40FEFA706912EDA3FBC +:107A40008290B0C7CDBFD938F66DA4EFCCB617DDA4 +:107A50005259FCB9C26A96477FF8F65F392C83E326 +:107A6000B757C77B2C6E09F1735A87240E833A45AA +:107A70005B678DB8296FABDB62F506F1725D9B0C1D +:107A80000EF25F27ED1C37D4B57DC2F8AC937C5164 +:107A9000691C2FC32DC5C511CBDBDE9B45F676795E +:107AA0009E0C7351A56AF79C13E37D104DC1F1CB79 +:107AB00077BF3DEB87D447BC3B92C8AB2A7CC0263E +:107AC000F4C624AFF0DBB3281E6EFECD672C8F0FFB +:107AD000F74B90533CF0F99A2DEFD9C89F9C41C1C8 +:107AE00064A60B7E91DF0884E585B6B464F28B5CF6 +:107AF000FFBB4ABECFFB7F1793E37A3A6B1BCF786D +:107B00007FF2774847CD9B76EF5C7AEF9377BA01A7 +:107B100071F081D22870FF8B073CE4876BAC418FFA +:107B2000CAADB85EF3CBBB198FCB8EDFED11F98DEB +:107B30002F4FEC1705F3689D4B367F9BD7B914FC8C +:107B40008CC79A5FC8D5B44F734E81D9BB93E84DAB +:107B5000659688B7ECF083B1F789F300A0FCFC03CD +:107B60007DDF34F8B2CC719B1D6E4C9B17B7FF6460 +:107B7000CF12F62A08A13FD2B96A00DD2B9F831CE1 +:107B80003F378BE6B9AB5869A473225C7F50E79707 +:107B9000F415EF0B80A6C4C55955C7AFCEA17D31F2 +:107BA0003BF4DBFE5725C7D51AC53D71CF31DF3E0B +:107BB000D86A1F225D89AD27F9BEE9ED5986FEC35B +:107BC000CB1087A7C08E0F184F80FE3B2D57F41F98 +:107BD000237D5CE46A4C43BE7DFACABB363AD70AC1 +:107BE000E27A8611BDDDEF711FBCD91A8D37E60F21 +:107BF00074D863E781A4D7DBDE33E975E27DF4DF77 +:107C0000CCCF00A46994B77D608BCE227F1EC4F7D1 +:107C1000527DC1D20DF684F3C6185E4CE78BBA7E56 +:107C20001AFB9CCB4CF198D19AEDC29559897601FB +:107C30003667273D5F34E72175D6D0AF893F75277A +:107C4000ED9CBFD4B509FDC3803A3A0CF5E1A35DC4 +:107C5000875EBB05D7F151D89A3597DF96686F6B71 +:107C60009E42FDC5F132F23B85EDED671C4F19FEDA +:107C7000E823175E1C93446FF17A52BD7501DBB3A4 +:107C8000FF577676D92076F6BB5903E284347C0D13 +:107C9000FCE589E597537C61E6AF615FCD76F393B0 +:107CA0004C2DA9DD04DDCF1B7CACDD7996717B3ECC +:107CB0004F9C37356CFB2BFB31646BD48EB86D0851 +:107CC0007DCCFD07C88F71FFC07C696CB27527F24F +:107CD000D37CFF32922DE723D1EF139F658BDB2BF3 +:107CE000F6E7543ECF6F26BF49765A5381E40833F6 +:107CF000204C7187D4F9FC5FE97DE6BC223803464D +:107D000036F2B92EAC8BAFCF092B7A3D4530797D59 +:107D10004EB32D769E4BF7073BCF7D5FB7575E97EF +:107D2000CAE508D62C4D4E5657E2ADB224CD237E7F +:107D30009225CE774AB3C5BA8F650979B4C8D5FA0A +:107D400046A3C897680F95ED5FBA9BCF83AD7A7D48 +:107D500006CE9CCBE7074ECB27C812D8BDA17A8EA2 +:107D600042FBC315963B4BB1DFB5E1F6390AE2C7DA +:107D70003BD5B2A704FB2F6C582CFA575A2AAC08F3 +:107D8000FDC7834BE6CCA47D03CBDB3FA5F529AB38 +:107D900015A0FA91D296F7B87F97559C5F353CBBFA +:107DA000B786DEDF20A12090FF2DEE7023D731E4CF +:107DB00082BA9A368FB53D7EBABF260FF3799447C3 +:107DC00024CDFFDB2CF22B8E885B2BA1BCD2B7F12C +:107DD0007B785F79D94A3921AE53EC838FDE333516 +:107DE00097ECEEFF85F7FF5B56F6E0EF3FF3D4B577 +:107DF0000B68FC68195419E72B57B42AEADB31BF2A +:107E0000A6BCCD9043B922F85EE6B2713ED792EEA1 +:107E1000CB253C1D239C665F7ADBACD70FC94E8116 +:107E20000339CDD2B81BDB5774F9BFAAF383FE68C0 +:107E30005FA06F5FCE56AE5B816811C95796B7B62B +:107E4000113FA24D0A6CA5FDD77D8FB7113E5FB7DC +:107E50003978FFE8E6B4F5D62B90E47247D19D045B +:107E6000FE37A55D7753BB2FDBDF9325E68DD0BCB6 +:107E7000B77C5F16F3BA1A53C97F820FF54AECD369 +:107E800070FC0E7ED42BA2F920EAD5383205897514 +:107E90004E663AE4B45D4CC7CD7641C78250497313 +:107EA0000FD231CE1EBA8CF22B7C7F94E4700B86FD +:107EB0005B84E760217491DC5EBFEDCA2D627D8535 +:107EC000ACAFACFF7CFE7EE6499A2F80F3D3396AD3 +:107ED00040EAE1FE1EC5A1065561DF17C6EDBB3DB8 +:107EE0000BAD27CAC4FE7E33E51D53F5BCD8D87F41 +:107EF00033EA0D2676F9AB5C64B0E54E99ECCA39ED +:107F00008CD7C88E99F7DD269BECEFD48E8FD82EB8 +:107F10005FEC3CD099ADDBE37CC8A77584E93C906D +:107F2000025EDD4F7AE93C3089FEC79D0766660B2D +:107F3000397DED79E09DBABDD1A84E0ED7D18F1312 +:107F400093DCFA8F2E82F24AAE476884F4C1FD6A50 +:107F5000BBC9FE1B381FF38A7A3BD9B331AFC06D62 +:107F6000B4DEABF5F393FED3C0F580E37A1C5C1F5F +:107F700068EDB28642525C3DCA490BD7A3F4833701 +:107F8000C4F52B41BB1A647B3996EB4F5A4EEAE796 +:107F9000BD7A3D438560D93F5C0F61AE7F98E29E1C +:107FA000242FACE4F31990260DAC7F9822DF2A939E +:107FB0005D81A3429E17EA20E43299D6752E0240D5 +:107FC00029DA8457E2E48DFF9B981594B9FCE954B3 +:107FD000E2F529265C98E57F6DB61EDFE8F21FB456 +:107FE0008EE443B1AF360EC6721D89D55C47F2866A +:107FF000850B366375241521D2B7094D62DFF8620F +:10800000753CE63A1D731D4E9E3F914F0535572432 +:10801000DCBFACB13CA17FF9CA2909E38BD1A1C671 +:10802000F74B1F9A93307E58EB8D09FD119B6E49DB +:10803000183F2AB428E1FEE81DB549EB5E0C9C8C84 +:1080400009AF48B8BFD1F9E4BB84AF963C59A578D5 +:10805000FECA8EFB4C7531D31817538C7D785DFEAC +:10806000465D1D9581119FC7A3FC1F2BA6B8E9FE95 +:108070002A491B88036F24C87EFC1FC5C17A931D43 +:1080800030F4FF62FB373FD6FD849C5224519CE3C1 +:10809000C3B82A652AD5118B737B784BD4AB7C96F9 +:1080A000F2778E8B34C9ED856FD25B5589E2A07B68 +:1080B000AB348E83EE1D527480F60F7A7EE0F64A62 +:1080C000F903EB42CD75A0190EDF64E0AD11510745 +:1080D000D982869EEC7F708683E38C872D96DBAAFF +:1080E000E3E87F225BD89F27B245BEF5735B783704 +:1080F000D901C5016A539E789E8A1F802A7B502E23 +:10810000EE4C10F561F0C6DA9985E43F7B466AE9EA +:10811000543F8BFD6FE06525C4FEE4966685F3BC95 +:10812000D5CE27D99F942BC29F8C9385DF403FD219 +:1081300041F6F14DE97EAB88B38256924F810382BE +:10814000EE72F6AF7C4E9C0E59D28A32AA4FBDE039 +:10815000B7B4AF104C876AA75A884FFD8B653E0FA6 +:108160007E8948427AFB6B46719D73FF85FA3F2DED +:108170008DF2EBFEC58F9EBDBB32A697276DC9F36E +:10818000BC8BEDBBD56C793495CE514E8E8484FA80 +:108190008C37B3457EF866B62CEA0C42EF79884DF1 +:1081A0007D4BBE184E4407A4EE352E1CF2E0A61FF0 +:1081B00054935C6CEDF382B4AF69ECE35FC8033BAE +:1081C000A773FDB6912FDDFCBAD8D7BBF98BC47D60 +:1081D000EB8FB2C5B9C047F43E6CCBBBFCE3496E34 +:1081E000379042F0BEB27F3CC507D52A68E4F71746 +:1081F000F817DE7D14FBF3D64B1CEFD37D1A7F23DB +:10820000CA90EE9F00EFAB7B91BECFB3053DF3A1CB +:10821000DA4A74BEF6FDFA54C2D3EBE9627C54022A +:108220006D6BDC7C37E8F3BDFEFDE57B294FA7F7DE +:10823000D1FB891E7AFF3C154AA8FF1AF8CFBE5A17 +:108240003CF0BD3781CFAAD77B59C94F9642A8EDE4 +:1082500069B2AB472CDEB5C06D2493FD929DFD52F3 +:108260005F53F4C97B90CE3FD5FE75AF847CFDE3B0 +:10827000C2E8AF9FC6EBDFDD248386B8F838C32F92 +:108280007BE2EAB44F2EFE2495F889F1CAF69F925C +:10829000DEEDB47BA9AEE3CDDA9DC3E3E3FA54CFC0 +:1082A00074073D07932EED3CADEA89C98CBF15DB01 +:1082B00005FE56FC66440EE16C45EA05DC89FEF6D7 +:1082C000523E279D2041D2FC783FE24D1BC17535BF +:1082D000A021CEF67F2EEACAF71CCDA820FA14F012 +:1082E0005F16BF9E3D2FDD329AEB79DFC8BA243A84 +:1082F000496783687F6F665389F181AE270B3A33F4 +:108300002BF478729487E2B9DFFFE6EC7F105FF61A +:10831000EDDCFE43D6914BE3C3C03A5A7527DB2709 +:10832000230FA3BA57CAD30E59D84F5E2DDFCF798A +:1083300018D56970DE35A488C7A3C151ADC2BE8906 +:10834000EF24300E6EF672BD27EBEB4A55C42D4676 +:108350009E245BBCB98AF8C8E0C5A93C7F09D0FE61 +:10836000989B122BC35E611CE1962DBABD029F0340 +:10837000F3D3D1BA3D9BE5F15EDB22CE6B12E24F27 +:10838000EC57ED4A127756E33F8E3B37FB9B53D8B1 +:108390002F6D96CB28EEF03922E4C7CD71E7545803 +:1083A000CFFB0003E2CFE7FE7249F1E7F73CFF3D68 +:1083B000BFB3D4A3B1FD098F14762E1C19C2790E58 +:1083C000FE55907E0DA5BD003A07CD13AD4DEA1DBB +:1083D000E940FDACF594AF7B681AC265A8E00FF5E3 +:1083E00051A450AA7D72E82B8A03BB15965FFF73D8 +:1083F000577CED772495A887E4EC2387A770BD739D +:108400005F97D08FB60CEDDFA7529E8171E65624A0 +:108410003145E9B1A52759CFD3647F511FC21E91C1 +:1084200047393AC4B9A843F301D99714551D478970 +:10843000B9317EB147D8DDFAC36F16D9503E672DEA +:1084400047DD74BE52B7F729372E179A33FD0F90C8 +:10845000FE2C3FF9F20495EBDCB61451FE1D8EBCE8 +:108460003C83E3B3D9C8DA7183AF27B0A9823E4217 +:1084700080864D99DC8EA27D15BC14888875F676B1 +:10848000346724DB1F08FCDB5B0769BD3B8FA570ED +:10849000DCB233BB9BF520380F603BF2FB89CF4742 +:1084A000F37C0830A6E38A6A4D227FFF0B7D3D3BBB +:1084B000F5FCB2F77399C719F38EE9982EAB88AB28 +:1084C000B248EB41AEE3EAB46B24DF946D20F8D3FD +:1084D00099C2756181FDD788BC335D9C47B70D8912 +:1084E000FE91DE13DD67D7A84E35456D850C9CBF28 +:1084F000CD26FCEC2804FE53AED875E37D299D1BE8 +:10850000F92308C405D7E3A528ADF00D573CFF5368 +:1085100099DEFD1E11EFB40D89585CE4273057DA5F +:10852000CA74C5E8047EAF41E7288E8BDB6CD1F7B7 +:1085300069BF1DE9520917A340D0099D23348A570A +:10854000525471AE9EA26ADEA03490AEC05808614B +:1085500070000FAF860B7ACE758443627D07EA42C6 +:108560005B891EC70417AF9B392DAE4F866C52EC4A +:10857000F9139E65EB5A0A695DC20F2A4A98CFC764 +:10858000DD0B40A5F3EF14C5C77952CA7CD09A50D1 +:108590005E4E878FEF7B708EA6C9DC8F10FD2ADDC3 +:1085A000A77D9B34D53907E94EFB328D9F6BE8B62A +:1085B00072DD79DDDF6F4A2BC3F59DB11CBC6717F7 +:1085C000B61F2D0C0FA773DA0969FEB7C81E3F73DB +:1085D0006AD1BA3138FE2F6D56EF5CB24B3DC11FE8 +:1085E000D3B97DED13568DFCE2836FF447BE22F9BB +:1085F0003E2BB15DECB38AFBD8D79AF07E43E707F8 +:10860000363AD7BAA6E36D1BED7FAFCCF1BF4F7AF8 +:1086100030A9A3A98AF836195A9B699F13ED21D76F +:108620004B847385BDE87F65F8D6A6383EBB72F4EF +:108630007DEFA8FF72D29B4E5D3FF7537C84ED5EC9 +:108640003D4EDB7BE0BBA55ADCF969100EF27EE003 +:108650006A788EEB3A8DEB7D216536E168F46B8E9E +:10866000DB7C7138B3E5087DB7E9EFFB798EFF4B12 +:10867000D6DB03EFD8DCB8FEC09FC345E4AFC21819 +:10868000CF7D5D1D69C0A42F17EA8E4E03DB919D3F +:10869000AF7570FCBDF33E359DF41EE98734ECEFF9 +:1086A000C5F882F4686FB1D0BBA657CF8FA5FDE2A5 +:1086B000F3FB965F4EFCEAF5580D7CCF18427AB476 +:1086C0001BD88E197A58467A28D1F77B62BFA78CBF +:1086D000F04D7A67EB9EC37AB7D702A477886FC64E +:1086E0003BE25BA538A44C45BCF3F323588FDBBABF +:1086F0005FBE82EBD991BDC3C651DFC2F86A8BCC95 +:108700000949F87CA53572909EAFC4F7376931BD31 +:10871000AC9412EB7A167B449DAC611F7FA0EB6793 +:1087200078A496E6C5F14E594EC07F9C9F147DDD1E +:108730008FDEBBF127EB36A0BE94FA2A2C1328DE7D +:108740003926B31FD8AFC7C92BFE30E5865DE23AA4 +:10875000FBCF888E8B837ADCFCDCAA5CEE935FD047 +:10876000502EE3B1F55550BD7763156DC54D9ADDBB +:108770007A88DA29D5E12A3A2E9CB6A0FB90F8C671 +:10878000CD379AF0D67EF05BA3B94EFAA41DE83B34 +:10879000CEF6FF8CFEF1095CFF3DFB91DF90342E9D +:1087A00061BCA1C766FC0D86933EA9E7FAA968974C +:1087B000AFDBF8EB6B1574E80D04045CFF9C8DDBFC +:1087C000D605D1079EC8F15D9783F8FB22D77F5D60 +:1087D0000EF2ADEFF87F7AC89FEC7DE51D37F9E129 +:1087E000769B6F34E1AABD04F38824789C9263657C +:1087F000FF5A3948BD49638EC8B78607611DE1A598 +:10880000A15D5643E4A77DDDD793DF781F5949FB6F +:10881000DA4BA707DD942FD5EC3DC475FA463EBD73 +:1088200004F43FF9D659C4FF73B9223F5EBAC19A26 +:1088300090DF8E80888DCE91037E5763044552630E +:108840008A3BEEE8D8C2DF8DD46E4B7CAE8EE2144C +:108850008450DD45F2E3C61C7D9FA4144A294E4195 +:10886000DCF03E49F455D9BB15B8BEAA8BEAAB760D +:108870005A049F9C0E6849CB88C52B23F27C4BC8B9 +:10888000DE2D31FC875EAF146D93F87B8A513B443B +:10889000BE3CE5B4B685BF930AFAB84EAF86084031 +:1088A000BAA728415EFF94DC5208E2FA27A1792694 +:1088B0007D59DA2985989FFA772F0AFE13FB459B8D +:1088C00065FECE6FB30499C5346F94F953ABEF1FB7 +:1088D0002EDF91787E51B7E9F8610A95EAC3A6F3D5 +:1088E000209D3FE6F39DA7E83F929CEFFC24478F35 +:1088F000E78AA028E1BBBCAE4BFB2EEF238A075CC6 +:1089000074F8080971F91E1D470DFABAEB42B25806 +:10891000378A82EAA36FD76112002FF3A91E714232 +:108920003880F542DE463D632D54DBA88EACBEBDDB +:10893000E9309DBF2DD5E35A339E90A1CCAF657A27 +:10894000DD50CDE6C4FBB53A5F6A4D7C69F04B263D +:10895000FA44DC7DA9F4A1E5FA0EE1A0769795EB47 +:10896000B9CFC1AD5C7F55DFBE85E959AACB6F2079 +:10897000BD415ECF325C0FE9D3A5D26B96DF3103E8 +:10898000E757C01509F29B9D7949F22B057539AD62 +:10899000AFBF4BE4B5FD5D25BC2F61E0C5FCFC2CF1 +:1089A0003D8EBE66938837CF765439291EE83BAAA0 +:1089B0007825C47DC5B14FDDF4FD4DF93E19E89C25 +:1089C000B4AFB3625D10EDE59EAEA13769E807CAAA +:1089D0008F29EC372A8E9587528AA95FEE2CE53ACB +:1089E000132D93F2009C87FD70DFD1A127CA384E6A +:1089F0009F5949296AD3D17227C50B7B40EC6F4838 +:108A0000C72A337BE2FCCA7B3962BF614DEEBB0FE4 +:108A1000939DBA66B795F783AFB1465FA23C6C4FA2 +:108A200097E26DC27EDDB145AB5348DEBF91BC1409 +:108A3000761FEE5E9145E735F59D56D5CEF4DE7D89 +:108A400090EE077749DE61383EB0EFEAD16DB44F62 +:108A5000B4A5C24BEC35DE579EAE3D4AF5AE90E76D +:108A6000E4BCFD9ACBACEC5FCFE43BFF752EAEAB24 +:108A7000D6B76516D9E133BFDBC375157D6D12E43A +:108A80004AB48F7CE849AAF739F3F4711B9D075764 +:108A9000B51FE7BA8DC1FCC1D910E28EF3F6561BA3 +:108AA000E537F55B8C7E0F7F8F52ADC7510DDBDE56 +:108AB000E67E2DE50184C7CD7248C3FF3CB4EF19B3 +:108AC0003E1F6ED825EA3E2EDCDF26F17D03EF8BBC +:108AD00074BBB51C34C6FB7203EF7A7D9481F773C7 +:108AE0003097EBB496EF7A84F1BD44C7B7B96E0AFC +:108AF0002DB0AD2C4BE82BEDB799BFFFBB43C7F7AB +:108B00001D17C1F7A85C1DDFA36014E1FBFC7451C5 +:108B10004F77FEF81027CD7FFE08EFBE7E1DCED921 +:108B2000EF1ED5E382FE88C567BB3236AEB7E313CE +:108B3000FE0E3170B4DF467527B33A3F6679CCED4F +:108B40003C3093F87D1DF8EB887FD7753A558A83C2 +:108B5000E7F6087B36A7D3CEE713D741B885E4DC28 +:108B6000B7FFF1960CC2CDAF056E0C3BB74CE7EBEF +:108B7000B5653F9845F97BADEE0FFBBBEE9CC57626 +:108B8000671C1453BC3747FFCE7B4E58B7439B132B +:108B9000F94EE7D424B7864E3BD79B5C0B3D36F2AB +:108BA00067D7EAFED3EC27FBF29C2CE720FAAB61F7 +:108BB00038BE6E97A98E52E9617AFA3B6C7CDED59D +:108BC00060F2BFD372AD09F51783E1D32CAFDB722E +:108BD000757FA2CB6B6E54D431CC7945F6D2F94374 +:108BE00057647519C50B06DFCCF2EAD24AD3BEEE44 +:108BF000F7125ED2E37CA37F83FEFD5B586D75C5E3 +:108C0000E7EDCFE75AF473CED04F2B709D7749D064 +:108C10004D38C4FCE6867229697EB33217C73F5FC0 +:108C200078FBFA71F1F98D6FCB708AF71E44BB5255 +:108C300051C9F53BDD7C5EA8B4CEA573B0C02EABA8 +:108C400097F29A4087CCF14060973D64C179AF219B +:108C50001C215DD59DD2D58423CC1B5A72D13ECD2B +:108C6000A32D651C37AF03E3117C6EDECC8F197F1B +:108C700047868A75F72B5A4EB23CC2C81F1A3E1758 +:108C8000F1AA71BD01ED008D6FD0BF4B6B3FF8D7DE +:108C9000A2E2543AB7FDAC6821C5A9B9227F31E2FE +:108CA000D528C6AB257ABC4275174B85E860E973B9 +:108CB000F7D9C87E1DA61FB6A0FA49D5BF86F261B6 +:108CC000D50F8D3FA240436A613D6A209D221CEE74 +:108CD00095C4FECDB356AA0D81A69787705D60EF4F +:108CE0006BE21CCAACEFBD8BBAD95E9C5FE86A240C +:108CF000BC2D2FDBB206230C18BDFF75B637A37F42 +:108D000067532D6A6C5D4DF4DD1DE7692D09F17225 +:108D10006F47B38DF7A1E3BF1B2E19181FD55F64F2 +:108D20001FEB79935D41FA39DEED3B22ABB42F8422 +:108D30007CFC657E3CBFF478A8FD600AFBAFBEE317 +:108D4000AE10C5FD7FD1F17846DF976F9A24333F8F +:108D50002C93453B7AFF3325245F92871FEDFDCE90 +:108D6000FDCF5CE1E37DF490A823DE9158875D1F81 +:108D70004EACB336F81AD0F98A740DA7EF950DBA38 +:108D8000F62A3D6E6F123D92A4832C2F8B9498E7A8 +:108D9000069E95ABE3EB48713DB791DD3B69E88BEF +:108DA00012F5901F7E2B5763DC34750AF95AF68949 +:108DB00016DFFF1DB15F63E5F70FB83F235847F794 +:108DC000CF173BB9BE013E0FCEA5FE3D25E2F7030E +:108DD000EE79B97644FC3E1D48221F0F58A35CEF84 +:108DE00017386E61FA02C7FB3D435D6417B7CCA428 +:108DF0003ADA6B757B71B8C45943380FD27B736212 +:108E0000F32CC915E71B40EBCD8D7D5F69AC773541 +:108E1000DCC87C58ADE3EA3FF4BC1EF3A8F3B949C3 +:108E2000F2A8C1E2DF0B74EBF1D3F9E9DA89EF21A3 +:108E30000ECA8F2841CAD7F7BC911222FFDFB46F48 +:108E4000D99F281F0EBC69078A43EED9BF6C04D78F +:108E5000E1FBFD57923D39BFFF8E2BB98E5112DFDA +:108E6000970689BE5C8AA75EF5509C54BFEF55AE4D +:108E700073ACDF3BFE518A9F305EBA96AE631CC373 +:108E8000F82B3F56C9F8DB73B432B3940807AF939D +:108E9000E6AD3FA270DD63FD91CA17E7525C736CCB +:108EA00006C74F46BC5441F938C54F478626C44FC4 +:108EB000A979827F7D075278FF438212811F189A19 +:108EC000809FBAF63F709C5187F62E1E47C673C529 +:108ED000790ACF332C4FC74F58F2313E768BB6AE5E +:108EE000630FAF6FB935CCF26EDA6515F7DB446B03 +:108EF000D44907212348FC78912EA11CE6D842854D +:108F0000946FBE502CF20DB33C9EC813E7852F9C86 +:108F100014DF19BF30DD3F22D9F7C6419821F27026 +:108F200049E777BB7576B2EF7977E489FD09772653 +:108F3000249C4B1AEDA379425FE6D8C43E95F9BE56 +:108F40003FCFF03FB08ECE634ECCB5AAC6EFB7E4AC +:108F5000A1DDBD1E8C3FEFABF3B3E89C4BE4D50025 +:108F60003D33C91E7E9BF6F929FE9A24FCBAB1CF87 +:108F70003F6F333C20F6F96FB5925D30EA4BE6F96E +:108F8000CCF157F5D534CF8DE8DF699E9B6627DE9F +:108F9000FFF645E2AE0579BA1F1F0EC3455EE172CA +:108FA000923F38D76555655E476868B2EF0B0DFB99 +:108FB000737895383FEA42BB486DD3A8D779DFEA8A +:108FC0008503279F4C67BB9A0225C8E2ABBEFC9382 +:108FD00027D93C4D17F4757E02FE0C799DA53CA067 +:108FE0006CA0BCEECCB3E8DF259DB1F1F926343E90 +:108FF000649107FF2EA969D4672DA44F67F5EF5E32 +:1090000090BE227B9CDD3F9BF731DFBF6706448328 +:1090100078FFC0283BFBBFFA99129F1FD447843FBB +:10902000AC9F2FFCE1F0F6792C97EFA05C7C5E36CC +:1090300013AF515DAE21EFABBEEC9B69E493748E30 +:10904000D34438673B9DC56D7DFBDB2D7C5E897EFF +:1090500097E2C21B2625CA6D04F81FC8C6FB37CF8E +:1090600096BCE84106C8FDE65BE7B1DC6FD2BF8F76 +:10907000B998DC7F9BE7FF691EE97D77FF77C62003 +:109080008B5E18F54111F9D7864170BD55E72F0C5D +:109090008D3E4DE765DE0BE7E97F7F3AFE3CBDC4C0 +:1090A000E3DF924776D5F2A5FB0AA0F97A7EB942B2 +:1090B000223901EBC5607AB5439F7F479E2ADE9334 +:1090C00025CE8746E9FD17ACA142FE9EA2ECD2CE8A +:1090D000019B9E7D7E2CD9B9DE0347C6DAE2E47A95 +:1090E0006605DA07F237FB0EF1F78731DC5974DCDD +:1090F00029DC4AD28DBA1F4DC4E119C221D9E7DD5E +:1091000087AEA7FCF16CFB4D599216E767F79E708E +:109110000F8B9BF7ACFEBB1898B70DFF766A3C9D92 +:109120000F309D67C3623ED4FFE1378D89BFDF6C8E +:109130007C67C7787E7064239FD31B785640E0D944 +:10914000F83D8C0BDF55DA80BF7B0CEEB7737D45A5 +:109150009F355A941EA72F1F1A7244981566312BFB +:10916000B9DE75226CA8E273024CDED74DA6CFEFB4 +:10917000C2B2A80F6DE4BAC5698DE025DC4AB0998A +:10918000FB13668BF3F229D02D135DDF8428B73EE5 +:1091900050156A67508519B6931C6199C2ADB6F631 +:1091A000834EC257C4A3A4BFEF10A5A7C9E4175BA1 +:1091B000BF02EF1B78C5C1180425FD4E3F2B5FD8B9 +:1091C0007FAF53E863F4ACF8DD936F400FD33F55A6 +:1091D000E9667A53352D83CE4B763FB742A6FA9790 +:1091E000FDA04549CFBC998DBCFF169D0EE1ADE9B0 +:1091F000B1F54EA2F5AAB1FE940560A1F54AB04BB7 +:10920000ACBF1132E87C6C3244F83D5711C1B8DE76 +:10921000E9A029D4B7E517EB7C16F95B959EBF59F9 +:109220001C41AEFB49CD17B8762A2139AF92B7B6AB +:10923000C38FD0F94CA958E744BCCEE7388D82EEF5 +:109240000BFE3A5FD8BB29106639430DA82FF28F69 +:109250002BCC54895F52C463A1DF13BB54BEF67993 +:1092600080E977DF1EEDFD6165ECDCCBDB99C3F5B2 +:10927000D0EB254B5426BA1C85A21E3A0261FE2E65 +:109280003392F87B67C5F9375E9E4F7ECF2FBEC302 +:1092900035D775EE086DE5BA9B0541640FCD5308CF +:1092A00070DA13AB03B09684F8BE95CED955AE33C1 +:1092B000ADA07C715FB6FFF2FC6CAE371DC6932982 +:1092C000A1F1D5A931BC2365FCFB3B4E486D257B44 +:1092D000D4ACD7D30655B75ECF54C4EBD0D0CEF3C1 +:1092E0008F4828A2AEFBDE2A517F7AEF90FD5CE723 +:1092F000DB23812A15D0F9FF7EAE03A61F86B316A5 +:109300007CCDF97F96FEBB0F25FE372696EA461EDA +:109310009F6B3E95CAF5AFCA0C9F4675BCE67AF1C5 +:10932000D296F10FF5705E6AD06BAA1357BC7CFF22 +:109330005EDDBE363BC4EF0049ABEDAA348DBE7F87 +:109340005FC1BF63D54CA141257DF7BE829FA73A7F +:10935000662A02ED4DF3DF44FC32FF2E15C2ABFF4F +:10936000059A376D38EFF72593C734431E968175FC +:109370005228875B49BE46DDAD516F4B80A0753BDF +:109380007DE277F054C409FFEE1F42C94EB8F4994C +:109390007FCF43D4FFB6E8FC47BA7670DDA7437CA5 +:1093A000A76D7CCF6BE69B81DFFF02B9D77EA25011 +:1093B00053000000000000001F8B080000000000A8 +:1093C000000B9B22C3C0F0A31E81F9A551F9E8F858 +:1093D000049A3C0B0303C34F205ECC835F1F2E1CFB +:1093E000CB8260BB883330E88A3230E801F1142048 +:1093F0009E0AC49F81585B8C814107887381EC3C35 +:10940000207607626BA0DA2F1C0C0CDDC20C0CD38B +:109410008078A130AAB92F1821B41217038329101C +:10942000333263B77FAA1A03C3011D043F5D9781DE +:1094300061AB3E797E19C5430F6F7344E51FB5429A +:10944000E57FB06160B07742F08F5991667E35500C +:109450006F8D136EF9A36EA8FCBD1EA87C0B34F9AA +:109460001D61101A00FB3B7C21B8030000000000C6 +:1094700000000000000000001F8B0800000000003A +:10948000000BED7D7D7C1CC59560F5C7F4F47CAACE +:10949000471ED9235B323DD2D8964186B62DDB32AA +:1094A000B6714B06472424194CE20802B9C136AC08 +:1094B000B3E1B809770B0EC1D1E8FBC3B219192F7C +:1094C000311C81417CC4102E281F9775127219031C +:1094D000C9CF9BCB651D4238270739A1F8D87C6ED0 +:1094E00074EC19CF5D08DE7AAFAAA5E9D67CD986DF +:1094F0004DFE38F9472AD5FDAAEABD57AF5EBDF744 +:10950000EA758D22BA48EC2242CEC2DF6642DE7294 +:109510001142D6CC96A976234B5A68F934317AE9B0 +:10952000A34BB46CBB40CB15FE4951D009B92C9C60 +:109530002644242436F1301129DC509D4246A28471 +:1095400078F46D55C43FDBAFB3ECED2224BBACF82F +:109550007BE9F9E1881EA0FD3DB5B6D3A4FD0C7DE5 +:10956000A5B5D36C9E7D5F0B8352FC1A08C5A686F9 +:1095700090FEFAFB89182664908EBD8CFEA7DE93C0 +:109580002071DA4EC90E137D05C085105EFDFA0903 +:10959000F166FA7CD0453A2768A91E4D657D14EF27 +:1095A0004B9FD35649941E8F6C8ABFA5754F44CCF0 +:1095B000A4808EC841ECF734A50B867AAFE8590D2C +:1095C000F4503A365648CFC662F43C974A013D976C +:1095D0001DD557E6D3A3D6317AD4BA1E9CA7D31192 +:1095E0004A4FF442E8F90CD233C8E91974D0F34178 +:1095F0004ECF768B9EDA01A467A09ED2431FB9EFAF +:109600004991388557819E00C0D9E919007A9A0B93 +:10961000D0A3FE79E8F92B2E6F49A0674D797A9295 +:10962000404F4D05F4F8D344A3CF3D4430279AE78B +:10963000E2E5E17C5CF1F5742445FB1DFE9384F3C7 +:109640004C576464DB8A59B8498ED7F7A203914915 +:1096500090AF25F74708ED6FB85E407867BF0F10F1 +:1096600005E1B53AB31BFABFF888BDFFE17A86AFD2 +:1096700005FF7B3E8FBF2712B65BE08F0F437D78DF +:10968000C9374802C671A5231AB48BB276FD4BD6F2 +:10969000764EFA0BB567F40CEF4DA13CABD9CF2059 +:1096A000BFFEA63E4D745AF71C4910E0BF1261F888 +:1096B00058ED295E845C0E64DF699A0C3F4216D235 +:1096C000794ADD994DD1F162E9DBD538E5C7706D96 +:1096D0008F0A740FE9073B416F9D8E29448A025E11 +:1096E00085F960C9C56632AA36D0F9EC7D59324693 +:1096F000C85CB8140857CD6C5DF68B24DB44F0EFE2 +:109700002C017A1238FFFD4BEE47BA15A06B05D03D +:1097100095243A7DFE2D2E3FEEAFA708C895AAA747 +:1097200022A91573C71902FE3743AFE9C8B63CFA40 +:109730007F6ECD2F9D57C7FC225F1E206636057CAD +:10974000F1D8E7CD2AFF9EF3FDB2BA14F2B7DCF8E8 +:1097500073E967E3FF1DD1B11FA2A623F1C02C3E20 +:10976000C3AEC91E906BBA268D2728C8A5749CB6B7 +:109770003C7E3BC79BA1534EDBE4F81B9C4FC39E32 +:10978000E9E7F3FB73E2F35D0EF75DA26169D17562 +:10979000E951364EB9FE7F022CAE0178C7BA92531A +:1097A00036BEDFCDE12F7BCE0E578C3F9F9DE14F24 +:1097B0002A02F268AD47F833E713C24506FFFC6B97 +:1097C00009590EFF8736F9C3CD9377C2D27A259C0B +:1097D000380DED6F23898BBC8D74BDB8125F847218 +:1097E000AB6CBE85FD12BFF6C6255CEE24D4036CBF +:1097F0003CDA3DA1FD07787FB2D041089567772B11 +:10980000C98C50D4AE925ECD0A949F070931166878 +:1098100079FBFA14DBD7D76B992DB09F6F90292174 +:1098200074BC2AA279A004F82C850BAEF11B742419 +:10983000E2261FAF8A17901B4F0B4979AAE8F8ADB3 +:109840008A6D5D78CC0401BD108890AC2748F58DF9 +:10985000100823FEEBC83A86BF2E407FD5B2DE2D1E +:10986000D371A498688CD3A7551BC9FA1D7972A827 +:109870000B4C7EBB63A208740D50FDEFA64B325813 +:109880004FD73BAC8708B5370AC8ED8C7ECF49244B +:109890003B8FF69B13487635ADFBC9FA046D97767E +:1098A00093F5A7705C628C1790B3ED029B5721363D +:1098B0007DF62CDA0524F33EB40BD2B88E9558DA37 +:1098C000847D403583861BA6FDED7B995E938909D7 +:1098D00072128AA5B355F05E5F1A057C17C492E434 +:1098E000F566564EE5E1ABFA5311B49FA24B859E47 +:1098F000BC7DEC18959FA93C791BDACBEC80FEE887 +:1099000000D7339F44FD69BDFF04E79332499101BD +:10991000BA7425D320CC95EB21A1B09ED8C9E98596 +:10992000BF2BD7DAE5559ECFE5950EE19609CAD74C +:10993000E0532403F8524E3E7F33AD5FF2A24A4615 +:10994000A87C35931322C8CFA5641A4B8368129460 +:10995000AB8881650B8963F987362AF7B4BCCDA43F +:10996000F2DE80F2FF51818EFFFBFAC4B2207DEE61 +:1099700089A52E87FD85CAFF76784EE5440079AA31 +:109980003649C1FD3224B0F53A266B1E801B3309DF +:10999000EAC743426F0AF689216E270D79886D1D4B +:1099A0001FE0740FF132144B9049985F3A2FA0D703 +:1099B0008F456FC575EC96597D80CE0BCADD26B6F6 +:1099C0008F39F150615E569CFF3C6CFFF3CFC38032 +:1099D0005053701E06611EB60B4C7F2ABF62E39780 +:1099E000A00FF7E99DDD8F22FF9553E7066FD1BFEA +:1099F000D6A137D7713DB7814C2F96A91EB9DD9DF1 +:109A0000556401F1FE02E0FDD6CF4E7C02E82193C1 +:109A10008965B04F51BC1F16504F26C9093ABEFC8C +:109A2000B294013F45F45DA3264AF82944A3FA4CB9 +:109A3000E5FAAC01FEB74E7BC33757FF2E9DF8AB5E +:109A400093686F10353102FA69535205B9E8ADDBFE +:109A5000A6821C0DD6D13AC84D445185CB68E92762 +:109A60001D207F96FD3110D931140D83DD63AC8547 +:109A70006EADF1B7441244C0E78979EEA8FDF92F25 +:109A800061FD6B898844E95332EF5381CE7E6D9B33 +:109A90009AEF7729FE4444A1723808E3C1F8AEE496 +:109AA000F1680BE84FB2BA07F4B99624AB41BE2374 +:109AB000ED88E796BAB80AEFDD9155C4AD038BE3A4 +:109AC00068570D84EDFEDC60DD1DE456844F92374F +:109AD000FC73ED6BB73F4994BC7D02C691F2E6D9A9 +:109AE0002D27B340971429AC77FF07977F518FE359 +:109AF0007E43D29F37552AF72E2E03AE08F9997070 +:109B000069DE3C85F3F61D3A4F031EA3B3D0BAA419 +:109B10003B88BD5F4320EADACAFB9DDD6FF9BCA735 +:109B2000D70D4DE2BC07D230EFBD54EFE3BEFA6A69 +:109B300020F30425A17B53F21178EF4AC9A4278CA6 +:109B4000DD34C13E779774B101F27700F846378E65 +:109B5000D12E15CB912E0DCBA1AE08969FF77DEEA1 +:109B60008B93B4DD9E945B73831CA4EF7A16FAA3E7 +:109B70005E777C04FA0DD3FEA15F59D59ED0A0CEAE +:109B8000F61D578C95378A8C8F55A217F16D119958 +:109B90001DAE1313E525AD95F6D3AB5AED766EC029 +:109BA000F0CEAE07FA9FAFA9DA56F7E80B6DF0CE0C +:109BB000F5F26391E90D971C2746339485F5F85922 +:109BC000414238495A390DF687BC4041BBA05FB0CD +:109BD000EBED8745B6DF3D26AA4867844CBF7096FB +:109BE000F2C3A58968F704430D1359E04F8D622C29 +:109BF000A145D035A95517188F84E5DF4DE6ADF3A3 +:109C0000A7043326FE05F0690EFDDDED36B9DE272B +:109C1000B2FDEE2C5F2F92DBEC043D13A1624850A5 +:109C20003EF447810FA26FA3D144F9D01F5274F0C4 +:109C300087FABAC582FB8E930F52D58D11D08F4E05 +:109C4000BE7F97CBD1339CEF9BDFFE30EA89FD9A34 +:109C5000D891F103DF4E74809EEF6B114590F3BFF6 +:109C600018FE39E8D833C3BF193A906F7D61663763 +:109C70008F6A547E603D8799FCE824DB81EF0D4AB2 +:109C80009730972E27FFDE6BFA2CBE5785C478A637 +:109C900019F09B8E237E1BE582F8FD6BF1DDC2CBB4 +:109CA0003F835796E165FC65E0F594901887F57D54 +:109CB00080CBEB01795205BD10B3E4C6C7D6D15CA9 +:109CC000BD24D8E49DF6F325E8E75EE887C2DF2BE4 +:109CD0004FDBFAB1E002C007B62EE26C5DC87FD65A +:109CE0007561E135C2F1D64986C9755361B97EAF58 +:109CF000F1B2F6D31EDF1504F44DC81F47FB7B817C +:109D00003F9E057EF5D6283AD83FD451C2FD1A9B16 +:109D1000EA797E52CDF608C0F707B6A35DDEEF8A7A +:109D2000A39D7EBCE61BE6CD94AEDEB7AB88DBA080 +:109D3000FE80EF8AE33AE8C5E312FA6BBD6F372E77 +:109D4000481698671FC4C728FE5EC00FED6A65C637 +:109D500008077C7BFD54F1D17EDE6C2619D0A72E3E +:109D6000BF1901BBBB77856AF420549C007F7B7CC4 +:109D70009F684D34CF6DEFF30F7C5ABA74761CFA9E +:109D8000279C05DB97EEE1E0C7237D82ED7D413C1A +:109D9000CAD55DB3750DFBA7755D85AE05F36CE3A4 +:109DA0002CDF292D4D32EC9BC46BC0FCC7E21D3D5E +:109DB0007F043EFDBD847AD0C99FBF93125E69CDFA +:109DC0006CDD154EE0BC59FD5D5D23A31E95EB488F +:109DD000C62DC0A8F10EB06F7BEB448CAFC9FE6DF1 +:109DE0005525EDEEBACAEC6EC2E31E963CB4FD8A70 +:109DF0008DEB3598FE0E90490271952AC2E21A2128 +:109E0000A20B04DB1B421C83251B319E12F6BCDB1C +:109E1000FDDE88FD0AE61839EB3B877E65DA6FE3E5 +:109E20007BD06F197C3DE421EC97AA87F0D979B3F8 +:109E3000FDBA22497C48DE3E7B565A4B5813FC4BF8 +:109E4000A07CCBA281EB932C0C1A4FD0A23F7C8735 +:109E5000CD9FFA88D4608B9B2ADAC0A785202DEB92 +:109E60006E3327F3F483737E3B6120F02FEB7699FA +:109E70009315E80D30BB0BC5A5069444A61BF6EF61 +:109E8000C57E8C2312398971E141A17A15D8CF168C +:109E90009C5CA76401AF408B99027D31384F34241C +:109EA00003FA1D3D01FE0091AE311225E24B729D79 +:109EB000FC9B7C7AFEAD1408239E3CCED55B46DE2F +:109EC00007BA4A9F4F288A9128E4CFA42466BF2866 +:109ED000DEC2EFAF54DAF74A6BE6F22D0DBCA3CF2A +:109EE0000743D4E5BE8C890FC8815CF7FD93C0871A +:109EF00081DAAD9152F4128DDA39797E91A19823ED +:109F000052693C0E14C283F8A9F0AC2F310E9F5F4A +:109F1000ED4A83C53B4029C2791CB7CF28DE416199 +:109F20003ED3D3F0B7BF653C0B7134D7CD7E13E67B +:109F30004F328F1089C2FFA85622422BD4BDAF8B5F +:109F4000389F1B0DD4574DCCBF33E93FA023B851E8 +:109F5000B1ED5BA03F67F6AD28C8BFBDFEB4648F0E +:109F600067F6761D25BF5C328B3F7D64168A17CB62 +:109F70004AFB44617E5457C48F43545E08959783CF +:109F8000D46FA44C2169EA3742FD00F51B09FA930E +:109F90003A967D5D4D58EE83A6EBE1FC2C39148D8D +:109FA00042BCF4F1C82D14E410E80E3C57F1B6435E +:109FB000FC7CC4AAD32702D4F939CB0F7BFFD80687 +:109FC000F198110FAB1332DD66DAEA520FC4FB478A +:109FD00002ACFD2F257F3B9C471CE2E7484436D569 +:109FE0008FE6F9FF39C98574800DC4DAFFBE1BFA0C +:109FF000F3C8BC9EAA477C66EA948F808F4765F5BC +:10A00000BABEC5D83FAA003A5EACEF2236DE126671 +:10A01000DF93E66D65F8D883F27F3D1CC201CDCD9C +:10A02000D570A84C14C320B0DD1C0A71BC2BEC8782 +:10A03000C809B6DFF1B852F17553665FE378949BB7 +:10A040007F027E29C42FA81E4EC1B83F2DBC4FBF32 +:10A05000DBE31E729D1B5F94D6E9944C59FCB7520A +:10A060004293693D604E64A3B41EBC269BC2E55B6F +:10A07000E1B8BF93341E0F4DE0FAB7F82C6BCCEE6D +:10A08000B8D2318FAEB089E7921E3F5B7F95E2BBBD +:10A090001EC6C9EB873CD35E1B0F146F571317679F +:10A0A000ED2DFADFBC0EEFACBD46FF0B99D5B67AAD +:10A0B00055EB421B7CC068B0BD776917DBDE9FEFB4 +:10A0C0003C5DEAA0A3D1E21FAF479C74562C77B247 +:10A0D000CEF7B914B31F67EA7C3F2E577F7B99BD3B +:10A0E000CEFA75931BAA987DC3EC987F43388C13E6 +:10A0F0000F234FFF4A00C7EABA2810CBBECD36CD9A +:10A10000EDBF57FD1CC6E1CC5E9978AE981BA74BFE +:10A11000B52731CE96EA716BBD618CBB619C6D0F2A +:10A1200035E4DDB4BCCD95D80DF27BC6B33843829F +:10A13000D06F721DC4AD7B1DF104A73CC51EBABE15 +:10A14000E07999550E75B1F89F5557EB0AE701DC98 +:10A150002DB3F3FAEFBB1277031EA01B09C66909E2 +:10A16000AE0397CEF6C763D1ADE4D7E8FFB3F331C2 +:10A1700085A44E36527AD2D45F1BD1816EB64E86FC +:10A18000A25BD5187D3E1612B94D378DF653BA6DC8 +:10A190007E2DACA72A791ACFEDAA6285F1B95716A0 +:10A1A000F9BCDD54923EE77CDC048156DA6EAC5E8D +:10A1B0001091FFF562E6098847D589B8AEF79BCACA +:10A1C000A370D4BEBFA5FA7A8CA79B8A28211D59FB +:10A1D000B5D03AECE776532F8F9F1EA8637EEBB184 +:10A1E000B6375438AF3960B4633E809CFE11B61F59 +:10A1F000E4FC4EAF9CC238F96091F3971E99F9F9CF +:10A20000BD016F67A6E0FB20BE4F47DB9E7F00E8E5 +:10A21000A0FAF709F4CF48ED2E4A87666AAB80DFD3 +:10A2200063F5A6F86B90AB4D22CA5910E272129CEE +:10A230008BDAFDE7B14D229EB3A635BF01F6FB696F +:10A24000F34D821B91ACD5C2F962D5AB1B34DC2B2C +:10A25000A9BD539B67E7576D4CAE83F9B2E8729383 +:10A260006B0BCE87B0784F02F879D72AA2833FE6EE +:10A270005EDC91FD02EDF7CC7AB706AAE0CAC09584 +:10A28000D9EF803CD16D05FC6477D8CC82DDE4E960 +:10A29000F4119DBE0F4626D08E52231231C1AEFA64 +:10A2A000BF12CE17D51948977C68FD89CDB4BDB2D1 +:10A2B000495C80765933DB6F34FA0FF61B3566B78D +:10A2C000AB245716FBBB77F2513C57561C76954C86 +:10A2D000F2E0C1EEDAB4EDC38D05F481554A934145 +:10A2E0003CD725D28D25ED6CFFAB9FFC8717F3F88B +:10A2F0003E253BEC746EBF59FD14B3DFCE74EDFE0A +:10A300008717A92C275C2C0E2A2BE66F605D4EF177 +:10A31000F3C53147DE4DC2C5D6CB19BE8E6166C1CD +:10A32000DF06FF18F8D577D576E66711C3E6C7D004 +:10A33000F57E46CEF3B3ADFD2E6D96F62766F35A45 +:10A34000FC9E5889BC966BE584EC2A91D762ADD708 +:10A35000E14D2689D0F91D0D914C0FCCEF6693ECA1 +:10A3600004791588D1A331F869EB1C250A72781598 +:10A37000D905EB57970D3887EC6FFC1075148BE3FC +:10A380002B87EDF2516E1EF738E67191CB6E87BBCD +:10A3900048BC2A1B853846E47AC0637F5831603D4B +:10A3A000BAC41B77EFD0E7CE2359C7F4862B9C2580 +:10A3B00085C6B5F879BBCB5CE68238BB629C4C8025 +:10A3C000FCB72BE8F73AE16F72F13C962891C13E59 +:10A3D0004BC13A81F5DB61B2BC31414B3E6820FA9A +:10A3E00071DBB956EC2DCC677B4822C9791B09B9C2 +:10A3F000CE15657AA66D3BB37B3E40042904F00977 +:10A40000DCBF6A4D4DA07D9361CB2ED36E8E5C9BDD +:10A41000A727AFE3F239FB3E11F9A8EDBD8BE11997 +:10A42000E076B3B63372ED8A02ED4385F5E407B802 +:10A430005C5FE7E2F6446A27E605F5EB37C681CFB5 +:10A440007D9B4D6317682D9011C847F1139B7D4C80 +:10A45000E5FB3AE0A7153F92B53896963D506CFE65 +:10A460009D76802B62CF3BA9F4DC3676E8FA92E346 +:10A4700038F7672BBF0D345F3E9F5C9C0FCD7CBDD2 +:10A48000CCDA4B69BEDE0DCC079214330171494919 +:10A4900020367B6B8CCB8BE465EF9D7850FFF94EBB +:10A4A00058A752D044FF9AF85B98DD261BFAB505F1 +:10A4B000F0B7CE391FE379BCB1F48770FF1B0DB53F +:10A4C000E3BED7A795D61FD6BEBA995CA342DCAE31 +:10A4D000BFB8FE18CDD71F4A58B4AF63EEDF53FAAA +:10A4E000F5427CB6F814E1F1D2DEC0F648C9B8A056 +:10A4F000E37CC550CC07902FC5F9F685F3E1DB2846 +:10A50000CFABDBDBFFD2F33C0FC1AEAF5716D5D7D5 +:10A51000FFC9A64FB9BE7E0FF9FFDCBBC1FF4AE3FE +:10A52000309E3D927E6A1E55F1720AE919D60FA639 +:10A53000301E03EB1BEC80741BE62B901841BD080A +:10A540000D41DF797413F9E6E57126A5CEBECF483B +:10A5500061AFAD1EE94C11C857837E816ECF1E05D9 +:10A56000C7B5F84D6D16CC27B3EC4B584EE08F14A1 +:10A57000CB4FB34A2B7E03C73867719FFAEC71E06B +:10A58000EF693FC1FDA138FDF671221F8997D64FB3 +:10A590000E78E297F5370A9C0BCE6D279337F2F4CD +:10A5A000DAFF71E813F3C8CD9DA847896840FCB273 +:10A5B00037B29D2428DE0384E9932128D7433EC97E +:10A5C0002A0DFCDFEFBB74D65E67FE9DA8F238BD96 +:10A5D0005E99BF7717DD870AD93F4B15661F9FF934 +:10A5E0005CF20F9097901A1174D8DF4E75E5D07E0B +:10A5F000DA915DAE405EDA72653EC2ED381455B652 +:10A60000E4ADCF1D849DFB5344947C3D6AAD3F2552 +:10A61000ED7E1EE89C4AB3B8C654FA9FF15C7FEA0F +:10A62000B09401A64E0D5D5772FD9CE27ADB823B31 +:10A63000755832A1BFD490905942DB9F92CD60C132 +:10A640003C009261E7C1BC7E4B5AB2C9E599BD0995 +:10A6500005F4CCA92E55F8259D9B5B814E8AFF8E73 +:10A660007454019FAC1C5DF314FB7C5A74F643BE1A +:10A670004274367FA73FFC26D27B9A3E974AC4930A +:10A6800046B89EE80F17D6275E7EFEEA75650AE794 +:10A690003D38E8F535D9D7A585DF20CFA718D418E0 +:10A6A0005E831111E761B0AEB41EEBE3F360C1F558 +:10A6B00047D8796BBF1C572BC1C7A5D9F129368E56 +:10A6C000BA71A203B6F92A92E8688F227B5F8238BA +:10A6D00002860E75F09F9E3A762BC4816FF69B42E0 +:10A6E000041E4E67BF43EB0BA8BF03F6A966668442 +:10A6F000C52D90D72911881B3F947C33FB1AF8A3F2 +:10A70000D4FF817A484F86DE077A289610605DED87 +:10A7100007E58F9D7FB0B7AD99AF3F5AFFD440FB9F +:10A72000168843CA24CEE319A20EF97AB8F4C5E21A +:10A730007A02B4E759F76CBBA2743AFC2237D956B7 +:10A74000DAFFDECDE053F41FE89D050E3F2BD46900 +:10A75000B7BBAB1CEFC7B8BC16F32BDFAD71E693EC +:10A7600097543897555B442D03F0241982FD3678B1 +:10A77000A34CC08E9FAF6BDD10E22BC7F77D84E545 +:10A78000B9C11711F9EBEF4985D9B18B6E7F5C80A8 +:10A79000FDE93478D92BA19E330AC9AFD3EE1BD281 +:10A7A000A7309E38404E7434823DBF4BC4F3A4FDA5 +:10A7B0002D0743F9EDBFC7C7999D7FA2CB6BF1541D +:10A7C00016FD79A5453461DF3ADFF977FAC9E5E688 +:10A7D000BF76B7DD2E3ED779F93120BEA6FCFC5FEF +:10A7E000E838D6BCCD5D1F4C6F2EBAFD458CE38C8E +:10A7F0001AA5F5CDDC797B09E72DD842CC42719CB6 +:10A8000057F83EE6CCEB53499218909FF832DB7F25 +:10A81000A4C6B591F112FA478A39FC0FDE4FEE1645 +:10A82000424EC07E2BEB65BE879B3824D37DD3B7C9 +:10A8300067C3217935E4679998E735DC65E2F399D8 +:10A84000F9778B1C5F81886BB95ED1F1FCF3908C3A +:10A85000F68648CE421C846844B7E48E005CC7216B +:10A8600019E3313ACF23A0A0F3A11D41BDB4129248 +:10A870003D6BF09C1EFB818E581CA693D569439CB2 +:10A88000279769225E725ABD83F2739F87D7755EE0 +:10A890000FF1BAC6EB515E2707B1EE53681DE2F225 +:10A8A000AEB486752FAF4779BD9AD743BCDEC0EBF7 +:10A8B000C241ACEF53587F237286F5EFE5759DD703 +:10A8C000AB795DE3F5065E27E36C7C37ABC37E882E +:10A8D000751FAF47797D1EAF8778BD91D78571AC65 +:10A8E000179B3F6FCC44FECECE7F07E31B21DCDFFE +:10A8F0008C3BEA9DB3F079FE687F972EE49F1FBAE8 +:10A900008AC49F56B9999E996E8B639E12F5175211 +:10A9100053F9E78E91C2F26EF27633E7E6610A5799 +:10A92000307EDD5D705D548ADFD6F3C4EF23FF4ACD +:10A93000F8DDE0B6D63DF3CFA7DB0CC4D3D99FB387 +:10A940001DD85B24EF9CDE2B675210AFA13612FAA4 +:10A950003B2ED59ECF7A979B9D7376BB593E6B2F2E +:10A96000C76FBA8D9D3FF42FF166C685B971C6BF1A +:10A9700071B378C20F2C3CD509F47B7C39BA62D113 +:10A980000F627ED470ACBD4CFEBAFCFFF2FD656771 +:10A990001CE49FE11D1DC7EB2FCCA7BB66F4CD8D3A +:10A9A000A9290AAB7AE873F067B470A42E3F6F9AB6 +:10A9B000BF278228A17E799BC259F92212F6CFE2E5 +:10A9C000C5752C5E2C71781C27CABE633057C13EFA +:10A9D000439F37F17184B9FD3ADB65DDD56CBE3834 +:10A9E0003E567E8A449EC37E66F091E3C82FE7738D +:10A9F000C843D6FC17FEFC42EB2EBDC8786976FE34 +:10AA000052AEFD17B9BCCC91CF22F3FA1FDD969D53 +:10AA10003261423E902547967C9DAF1C5DB09CC044 +:10AA200086D4525C4E522489EB46069773E5B9CB27 +:10AA30004B0139C9E6C3D7A8217E9E6FA0BC507CCC +:10AA400064945B8DE153B32A8CFD09B0C697410F26 +:10AA5000BC0E7CA0F45EA286381F589CC20BE78C0B +:10AA600079ED297188AF20095CEF33B8CD2A5BE717 +:10AA70009BDAEB18FE84F7EFC097F6A7E6F727916D +:10AA80003A879C33BC3FA6B2F9A5F0F89DDF9CF154 +:10AA90006501F195483C25D2769FE2F04EFD659523 +:10AAA0007B397EC322D9CDBE938C93FCEF2A7DAA3D +:10AAB000C8BF7B64EBCCA99F5C2057ABCF5FAE2AAD +:10AAC000D5EB356AE17D87EAF92688F715DB774E05 +:10AAD000AA33FB41139FB7739AF7DF811E5A333BAA +:10AAE0009F95E27B091FF75CF13D3517DF8AE4ECA7 +:10AAF0004DAE272AC56FF379E2F79203BF774BAECD +:10AB0000DFE6FB51A5F87FEC3CE5E18773F95BD10B +:10AB10003A12D573E3EFA7CE13BF5F38F12BB26EB5 +:10AB20001595F12B45987CC8FCFCA552FCBACAE3EC +:10AB3000C7F3C5B6F69931B4D7D01FDFAF6EED4B72 +:10AB4000C9B3F89984E9F5731DFFDE8AC7FF509FEA +:10AB500029CF8EFF05F543B6F165D94061AB74DCB2 +:10AB6000872B1D37F5511BDDCF0C7DD436EEF9F266 +:10AB7000FDCB158F7F938DEEE7866EB2D3ED373028 +:10AB80009FB8D271BF739EEBFD371C5F9FAAD9F6A9 +:10AB90008162F6FBDBDCAEBD45D56C725C0CFE4D14 +:10ABA0006EAF7CB042F853BCFF460B9F32F09FE182 +:10ABB000F87FA642F8DF717CD65788CF0FF83A2C81 +:10ABC000B67F7A39DF7DA023F3FC9A0BCD5BDAE503 +:10ABD0004E081E38E7FC7A177E27F8A6AC6A10EFFD +:10ABE000241D04ED71CFAB8171965792E2FE7F2256 +:10ABF00025303D8CF12D57D8B09DC7597E972CC775 +:10AC0000CD42E76D210FD37F826674B2F5AE10C8D6 +:10AC1000432A06EFF3148EBF549169CC3F21117E75 +:10AC20008EF4F6757AC17302398E792D92A69071E1 +:10AC30003A4E5F68BB9E9FB71CB3F08998888FA27D +:10AC4000317C14D9300BE529D77BD8BC5AFD58FE8E +:10AC5000A1109926EC1E07865FBF27DE0979E2A9BD +:10AC600090827CEA0BD8CFC7AFE7FDBC9FD3D7E774 +:10AC70002A9D27D63EBF15F3957A5B59BE924E0C9E +:10AC8000CCEFECF397BED760B48BC5FF4778FED30B +:10AC9000107C3F0ADF13C3F7A3CBA0FD57F13BBCE9 +:10ACA000D3CD62C9FB7102863DCEEE6BB27FCF631E +:10ACB000C5E53DBAFDBB1E77C4FE5D8F6BBE8C79CA +:10ACC0005D7D7E763E500E7F2BEFDD821B9493AA36 +:10ACD00056904F19DBB9803B62C7F7BDE31F6BEF9E +:10ACE000734D6885F07AB7F8562CDE30436F959235 +:10ACF000CC30BD61CBCFE8E2F2E5AE5293A097A98C +:10AD0000DE2DF2DECBDAFBE3981FA246E23AC6A3C1 +:10AD1000F93EA0C27AC8E3D3E7AD75E915AD7C630F +:10AD2000CCEB107413CF1F555847C2DC7633F36A4F +:10AD3000C9FD9FB644709DD4A8B84E047D1ABFEBE0 +:10AD4000728EB3CC631EF4C0F998C7BC0F4AD73BD0 +:10AD500052A2D07A19F3303DAA5E13D7D5067455A6 +:10AD6000D1EE71E2F12C5F7F7E0BFF9489F917958C +:10AD7000E2FF7085F85BE350FC9F063D4BF1FF124C +:10AD800094C5F07F8AEBA36AA277E39EAD333D4B77 +:10AD9000C8B57A7E7CDDEB65FD56733D45489B2D3D +:10ADA000AFC7C5E9AA949EA3965E2B438F352EA507 +:10ADB000E7453E1FDF2B351F2F707ABC5EB66FA9AB +:10ADC00087E33A5D9A6469917999E278CCF7F2B8B1 +:10ADD00052AAED9CE4EAC715D231353B2FAFF17989 +:10ADE000F945293A5EE5729596C8FA53B09F365AEE +:10ADF000F90BDB6CF3B288F327EDB6E6A5DD362F51 +:10AE0000A1739C97DF5648CFA2D97939C3E725575C +:10AE10004ACEF2E0FFC4E1DFE1F068272EF2FEB196 +:10AE20000FCECB9679E2A2B766767FA3709277CDEC +:10AE30002CDCE7878F5B706E84EB988153BD79FDC6 +:10AE400091D4EB7D70FEDDCFBFFFF8C170E02ADE4C +:10AE50002E88EDAE61F4D07655F9FD3F3BFCB2D5BE +:10AE6000FF3C80EBDEF28E0517CE875BE47DC78268 +:10AE70008BC073E1F04C7FB5F9784C79FEA98FE572 +:10AE8000EB38F2BDB4CAF21D5CE104DEE7504D02BE +:10AE90006989960332BB5F21458DEA27207FD69DC5 +:10AEA000C8920AEC2E5165EDDCD4DE82F3E3791A08 +:10AEB00039E6D1C10531C861FAFE4058467FE00E3F +:10AEC0004FA2C55BC3F0C43C80D7983DD6ED6FE17F +:10AED000711486D798EF1343D09F46F182FE3FEF5F +:10AEE0000B1E03F883F50AE6F31EABBF13EDC4B1E6 +:10AEF0006E99C0FBB1AB15B413EF7B2D80FB70BF17 +:10AF00006C5C8FF90FA6A283DD7897F79D9390A7CD +:10AF10003CD95DA50957203D887F4A24F15EEC9F0E +:10AF2000D99D7B28FE900F8C5B17F4DBC1FC18C207 +:10AF3000F39CEFDAA263DE8C4ED8FD4D83AD0AE6BA +:10AF4000298DD535B4C178F7B5AA6877DC774D433C +:10AF500037E673B77A31F7ADDAAF0B90DF135CA742 +:10AF600010F810A43AAC7783DD1958EB853BBF4845 +:10AF7000751D1B2FB08CE03D7F2E928EC768191C6B +:10AF800052F01EA7FBAED996DD09764D2BCB5FA6FE +:10AF900084BD145B4B889FB392483F24808F6B1114 +:10AFA0003BCFB7E639989E695FF21C3198A9102E05 +:10AFB0005B195C6048C6FCE4B270E90AE13215C274 +:10AFC00065195CD9F37B9E4FA9D27F1087F338F3C4 +:10AFD000B1FDA5BF8B3BD77CDD31AF3DEFBA5C7BCC +:10AFE0002B4FB71CBD70983983A7541EDECAB32BF4 +:10AFF000F6DE35FFCE087C97365873372FEF616544 +:10B000002D7F5EBB2782F745D6F2F7B5F7E0FD91BD +:10B01000CE7EFE0BD7C74D245E721EAA39FE6F503E +:10B02000DC219EDD2497C90770E6FB39F49E2AA730 +:10B03000DA71DD5EC3F28B66BE9FACE3DF8D906498 +:10B040003C86F12C33B872FEECFA716DFC3EAE1FFB +:10B05000EBBB493A3FEC7B49879C38E5C2EDC84FD2 +:10B06000B9503979E53D9213D79054D1FA71A52B97 +:10B0700084CB540897AD0C4E19122AD22B4ABA42EF +:10B08000B84C85705906D7BF5EE1FBFA703FC4B774 +:10B090005C97ABB67AFFE55EFBFB0D7E5B7D608D5A +:10B0A000BDBDB2D6DE7E60ADBDBDB28EB5377C878C +:10B0B000AE4AC52A5F27FFEB3CD749935A1A3ED0C8 +:10B0C0005A665DA99A07DA57CB3A81FB85E87E95E7 +:10B0D000E1FB56C1F8CF561F5BFF577B35DBFD7494 +:10B0E0007FE97436F918BE16BDE5F0B5F4EF3F4AB6 +:10B0F000DCEE2A92771F029D538B8F17417FC78EFC +:10B10000BDB510ECCA675F5F87F79AF67ED0CA9B21 +:10B1100031301F523EE9FD38E8AD67E97E0BF93862 +:10B120001321E3F82560CF044402F63275A3F05EE4 +:10B130008F678FCA687FF43E57DAEF7FA68BE509E9 +:10B140003D0D7E3FD5FF47F8BD5B4FF27BB71EEF4D +:10B15000D2B11CEF6AC2F7992E03EB0F77B562F9F3 +:10B16000509789CF1FECEAC0FAE1AE38D6EFEFEA8C +:10B17000C4F2DEAE0496FBBB7663B9AF2B89E570F3 +:10B18000D71E2C07BB522C6FB36B887FBF96C6F2BD +:10B19000D2EF4C8D5C0276925FC4EFC08AE1BF6251 +:10B1A000C21E77B8E4883DEEB03C638F372C3B6C11 +:10B1B0008F372C4937D8DE370E5D6C7B1F4DADB213 +:10B1C000D52FDA73B90DBE3ED96EAB2FDAFD7E1BDB +:10B1D0007C6D629B3D1FACF3061BBCB67187ED7D99 +:10B1E000B0E5AF6D757FF31D36786FEC6E5B1DEECD +:10B1F0007DCE87BFD6D7C0E281E1111B9CEC3F68B2 +:10B2000083DB35DF7CC4B706F2F183685F3EFBAABF +:10B2100080F95DF3161BAF03DFC92B12CA13B99275 +:10B22000E5C3CF6B485E06F7941139B9EEBA40F921 +:10B230007BA4AD788F146C4D80BC9E795DD0C1DE4F +:10B2400015827B964D1690C7DDA7936402E2923C6F +:10B25000CFAC7121314DDACE4BF5091E2E926476BA +:10B260002FC62D45FC8EEA312181F926D46636FEA3 +:10B27000B30679F4CEFD77C3CF7787F17E04B4CBE4 +:10B28000DB0EB44E0D51F8F1150ADE7733075FC7B8 +:10B29000FD76BFF5313F78DF5E16AF6C7C7E7D8337 +:10B2A0000A76784B621EB8AA337A23FB33FC4E2908 +:10B2B000A01B6BE10A80402C4D763603DC0913E2BB +:10B2C000B614FE6BBEBCF1028F9F4879E9F3E547E7 +:10B2D000128DF0D9C4F85E162F1D1F5E2ADE4AC7F4 +:10B2E00069C82E1797A2BFF324BBD77D48176FA557 +:10B2F0007AA1E1505CDC5A806FE37F2A1C4F9DF4F9 +:10B3000049D87EBC3B83F7CB79B3DFC47B38AD79BA +:10B31000F135EB6202FA3D9C10C15E1BDFCBBED360 +:10B320001B17A20B239CCE6E079D8017A58BDC0AF2 +:10B33000E5434971AB9F3D6F0CCCF60BEF77C2FB39 +:10B340004C4ADCE2AF887FA6179E3FCEF9772423D4 +:10B3500096E49F7EC2047EAB31CA3FBD14FFEE6708 +:10B36000FCA37CBBD53F975F33F0295D5CDB9CC7BA +:10B370006FDE1EF8726B01BECEF089B64F60FBA87F +:10B38000B89A8F0B7C68A074EF2CD44E88F271327F +:10B39000F671281F6FCD8BA7C39F3F2F4FC48287A5 +:10B3A000BF8EB53C4F91D2ED9A0CED84EFAFDB9A96 +:10B3B00013780F70BF5FC4FB85FAFD5FCDE23DFDE2 +:10B3C0001A41BD29CB66CF4FC22C0EDD23145AA7DC +:10B3D000763F01BE4CC9FF9EACCF6FE5E197B197B8 +:10B3E000F8BDC212BF575891E31D51B69E8D6E3203 +:10B3F0001B5F9D3BFE41A45B8AD8F7DFBE5DF67DF7 +:10B400002FA6DD8071ECDE7065DF0DB973CCBE5404 +:10B41000383EAE9C8FDD779CF3209E666E1E969B19 +:10B4200073212CAFC82DC2F79B72B558DF986BC43F +:10B43000FA865C14CBCB7397E0F3F5B9E5586FCD82 +:10B44000ADC6725D6E253E5F9BDB80F535B9F55864 +:10B450006FC96DC17275AE0DCB55B90FE0FB95B9D3 +:10B46000ABB16EE4AEC37279EE5A2C9B721FC7F774 +:10B47000CB72D7637D696E27D697E46EC67A2CF7B8 +:10B4800029AC37E63E896543EEDF6319CD7D1ADFCF +:10B49000EBB9CF62FDA2DC67B0BE38D78BF5FA5CA2 +:10B4A00037D6EB72FBB0BE28378CE5C2DC7D58D6B0 +:10B4B000E6C6F0FD82DC0358CECF3D86CF43B947C8 +:10B4C000B1D4725FE2F7453F856530F7352C03B99B +:10B4D000AFE07B7FEEDB58F7E5BE89A537F7029634 +:10B4E0006AEE1896E5E6A9DCF74F9BC93C9B5C6CBD +:10B4F000CA2DB4D5374CDBF7EFF5BFBAD8565F3756 +:10B50000B9CA565F73F2725BFFAB4FD8F7EF95C7BE +:10B51000DF6FB71FB2F6FD7B59E606BBFD7078877B +:10B52000DD7E48FFB5AD1E1DBAC36E3FA4ECFB77B0 +:10B53000FD1EFBFEBD283962B71F761FB4C12F2048 +:10B540000F3AF2C9C76DF055E6D336F840EB571DF8 +:10B55000E72B19A6FF8D6FD99EAB4DCF173C87897E +:10B560001DBA1ABFDB3F5D27F27B86F8BDADFC7EBE +:10B5700034E77C56733D302FC7FCA7305F7735B07A +:10B58000EEF2F29EC0CE88E6D919F31AF4AFBC48A9 +:10B59000EB67162B4637AD5B7686055FF6772B1487 +:10B5A000633245F174BDEAC67BE78460A70971B5D3 +:10B5B000BBA604DCEFAB17119E1FD1D1C1E213C4AF +:10B5C000BA4F07EFF719ACB7DEEF7C1FBE8FB2FAA8 +:10B5D00071FFDEAD10471D7459EFBFF43E8C7378D8 +:10B5E00058FDBFFB770DC0FBEAAA8908ECB3FB8AC4 +:10B5F0009C6FFE4FBFC2EC7DBFF923FF9AD97BA69B +:10B600005F09275EF2D3E7B7A9898BE0CA6EB8E776 +:10B610001EEE71DE2A9B3F01B86B65F3653FEE0BB2 +:10B6200076FFE15AC87D5D83F702FE0CDE4BC1A3B5 +:10B6300098DF5FFD817BF0BEAAC100C5C75F1C9F7C +:10B64000FFE69766F61B62ED370D184F457B7020BD +:10B650004AF0DE8CC1503C05F7F9A5BEA792270C35 +:10B66000A03BCD9295787EE2E072DD920BDBFE444A +:10B67000483C0B717C5FC2AF83BDE6272730FF22B9 +:10B6800048A6B1D48826D8EEDBB6E8AF67F4C3FD90 +:10B69000FF7E3C87378F4E629C3549F8FDD56FC1E0 +:10B6A00073CA9733FE35C5F97295740FD1E8F80F58 +:10B6B000537B12E87898307CF773FF5426C97823BF +:10B6C0008FF7E4DF2321BFFA4D941B2BDE234B1BA6 +:10B6D0003BF07A177E8F4307FD07F6614DBC74BCC3 +:10B6E000C7796FC3B9C67BC20167BCC78FE7C9A75B +:10B6F0009B4B7F0767C57DF63797BEB732C3FDBE4C +:10B7000087F979EF43FCBCF741EEF71DE67EDFFDDC +:10B71000E0F7E1BD5ACCEF3B007EDF32382F366DCB +:10B72000DF978C16B9FF251A12B89CED41FBDEC7D6 +:10B73000EF2BA29E2BDAF35E6ECFF7FA7BE6C3FD0A +:10B740000CBE10C9809FB0FBEA71FC7E969262C06D +:10B75000FD00B7FFFA8DF9FF8ED6631162BBDFC91A +:10B76000DBECB82FA1DC3872C6847E7DD46F481B19 +:10B77000C5F973CEFDAA19E239AF7ED93D3FD6BDDA +:10B780006DD4034F81FCF9806E0DE4EADB38CE699D +:10B790003E0E91361EC7FB0C2F934929399833CEA4 +:10B7A00039CADFAE80E3F7291CF2A7CBA407EFA9C3 +:10B7B000E1DF43EA7EC39B1F5FB1E4B0B799C51FC9 +:10B7C000BA5FFF18FE6EC08B355B17E6FB7FD6773E +:10B7D0004ABD2D0C8E5A7DB8CEF7779FD43FA9CFA6 +:10B7E000C23D65C169A5E3194F5870A30C2ED06204 +:10B7F0008885EEEFFB22DF4FBEEC3353819AD9717F +:10B80000F59E8E1B504FAC51F17CC6D9EECBBEC419 +:10B8100050202F3FC1EA3FBF3DC85789F6E952ED9E +:10B8200017DFDDF17352BAFDE1C09AE2EDEBEEE80D +:10B8300078B00CFE99C2E3A71EC173A608FBDDB267 +:10B84000EE5AA501FCE57D6BA8BF4CE7E1C5155B91 +:10B85000F15ED9BED02B7A2139A2FD7EA9145E9467 +:10B860002F9D65E8FA5AB9F64269BABE5D86AF27E0 +:10B87000CBF0E58552ED295F0F97C1FFBF16C63F9C +:10B880007511E01DA863F1BAEE7ACA57F0D7D6B0A9 +:10B890003884B51E1E1F2BCAD757CAF0A59CBCFE04 +:10B8A000E202E5F58D52E35720AFFF5486AFE5E4A1 +:10B8B000F5AD62F28AE7A4E72FAF42F0C2E4D513F8 +:10B8C0002CCDD772F21A2AD5BE0279AD2D857F050F +:10B8D000F21A2D34BE9B508508F67E333B17DBDD14 +:10B8E000C6EE237335B17DD7F7EA17D13EEAA3FB45 +:10B8F000D3BC56D8A7A7EEBFBD65765F76EE3BCE2C +:10B90000FE9CFBE6EDFFFB49DC37037CBFB3F0F1A7 +:10B91000E8CE7E4ADF6771AEE37AE17798F27EDFA8 +:10B92000E2E2C7EDDFAD5EF878F67DDDDB42C7A76A +:10B93000EF091D7F0B9E233E83E7884B0F5DE8B820 +:10B94000A5E19B1E727C8F7B8E76C02D41BB1DDADC +:10B95000B0E76B8FE0FD23BC9F06D9C4DFED93C930 +:10B9600095ECBE9321962F24EDF9CA23A756E7DD67 +:10B970002B4574313F3F481A9A78E4541E1D39888C +:10B98000F7B0F832E62DC6B4CBD19E181C2D6DC78A +:10B990007E99EFE3CFF0F38BA7B91D7B84E72D3EB3 +:10B9A0000976EC3238C760E717E360C7629E632B05 +:10B9B000CF7334799E630796CFF1F3876F751DC6F9 +:10B9C000F747BB32587EA3EB08965FEF9AC0F75F4C +:10B9D000ED3A8AF589AE2CB38757DE897A66960EE2 +:10B9E00067DCAA341D971DB5C741564CD8CF312E00 +:10B9F00039623FC7589EB19F632C3B6C8F832C49A3 +:10BA0000DBCF311A87ECE718BE26FB398647B7C76C +:10BA100041DC91F73BCE41B639CE41ECE718F54910 +:10BA2000FB39C6A2DDF638486DC27E8EB1A0F36E3A +:10BA30001B7CC8ECB17F17DF6A8F836C9AB69F5F5F +:10BA40006CF8D583F6B8CFA43D0EB2EEA43D0EB28D +:10BA5000E6C4576DF5D5C7EDF18F0FFB122F823E6F +:10BA60005D9975C641264598BF9FFBD9F99FE55F53 +:10BA700053F81F80FEBC4AF2673750B97FEC28BBF1 +:10BA8000DFFD31C2CE3309F90FE82FC833FE8289BA +:10BA9000FA47E2FA67ECCAA957C09F91F7337FE7EC +:10BAA00076615D56CDF7775CFF28E4AF6B4973FA9A +:10BAB0000D65FA970DF473E432FEC8DC7E99DE9AC8 +:10BAC000BDDFBC25057954F28C3FF201873F523728 +:10BAD0008CBF6335AFB43F32679C73D4436F058B23 +:10BAE000F8C31111F967F923FB5AB83F42D87752CE +:10BAF000567F961E1A8B945E87D63D2D63DC6F9120 +:10BB0000FD85CFB1AD7C99B196CAF2BA7F1064E7DA +:10BB100049149AFBC3FF5F3EDE4DF9B8BCAA88BF4B +:10BB2000FA1ECB4731B873950F197406C6236F19E7 +:10BB300084EF985C50BF7CB6AEF07AF0DEDBB642A4 +:10BB40005EC81EC2CE75C8CBECBED57278C436DED8 +:10BB50005432FFC18AAFFE496379BBB1D69B306FC7 +:10BB6000F2341DA3D47DDACE3C0B299C841FDB83E9 +:10BB7000EFD80B9EF7FCB49AE593C73A3F51D26ECB +:10BB800071FE1E58CC2C7DBFEE30C7FF85D716A0A6 +:10BB9000BDBA6F88E963B973C5F3208F8F833C1AF0 +:10BBA000184F5197035D4332DEA7E6D709C6051744 +:10BBB000FB49A63B0A7C3552708F17FDC373E5190C +:10BBC000F91CB2DB51672C3EC54BF3B5ECEF19AC59 +:10BBD000D7312F4DD649520BE1FA216F84113F5CCA +:10BBE000B783AD06FBDD3B8A8FA6CD6DEFC4CBB925 +:10BBF0003EE55D57603CA941B0D6A7CF803C9DD3C0 +:10BC00007E7FC97BDEE6F47B8EEBF19939EBF19A0E +:10BC10009E9FC2B8A32C7E44F6D0BFBC734E677FF4 +:10BC2000D67AB4EA2FBC76177ED732387A07BBAF04 +:10BC3000B88EDF0B36CAF46331BCAC78D0016E1F0E +:10BC40003E71A8BD07F8DB47D74DBE3E5AF2B71F7D +:10BC5000F126D8B96235944F1E66DF6B2F7D6017D1 +:10BC60007FBE039F1F68DDD68EFECF21620259C1C1 +:10BC7000F5A754F67E4A43F8F0F471B81769299590 +:10BC8000378885DFBBB1C584DFA8AC0A89ED504A8F +:10BC9000A393A877492B3197E830AE8CBF9FB33878 +:10BCA000451E057C168F2646403E499A18F0BE2A4E +:10BCB0001CDF763585AFA282095756A7087BBF38AF +:10BCC000A9E1FCC5461307AF06F86682BFCB45DF86 +:10BCD00063BD6EB786F93FBED1C921B8F79A8EC150 +:10BCE000DFD33A7DBF30C1DA074627D35BD02F9927 +:10BCF000799FDED202F70EB2F7F228A507DE4718C9 +:10BD00003E29327D02DECF0FB3F7CA28DB1FEFDDFD +:10BD1000B803EFD3A3E3E37D532EFEFC31CEFF58EF +:10BD2000E73B27601C2B1F2345E2B67BA99CEBDE7B +:10BD3000FAFDBF5E6EC7FBD4455F3895771FC33EE3 +:10BD40007E5FB577D4BE3FFFB18AEDB3C7B89E29F9 +:10BD5000772F1B247A839CFF0B555919960080007E +:10BD6000000000001F8B080000000000000BC53D14 +:10BD70000B7854D599E7DEB9F3CA4CC29D300993CC +:10BD80009099DC840422043A814041512711111515 +:10BD90006D44DB066B7508C8FB11514BB4DADC90BF +:10BDA00004921060B0AE44E43189A2A8A08382D28C +:10BDB00096DA01B3145DBB4DAD456AD146D0A808F3 +:10BDC0003452517657D7FDFFFFDC4BE64E2689D61D +:10BDD000ED6EBE4F0FE79EF7FF3EFFF9CF19C61875 +:10BDE000FB2A17FE5795C4A2058CFE285F99CAA2AC +:10BDF000B698FCFC4C637930D7982F1F69CC7BC672 +:10BE00001ADBBB2F36947F7E1D631D4EC8487E1BF8 +:10BE100083543A7AB3AD6C3463B5EEE5943F7FBB9F +:10BE20005E1E48C27C9E7CD28EE58F5555D8582127 +:10BE300063AB3C330605E1FB57F87779EFB4A19A81 +:10BE4000B1A895B135D5214A9BAA5B286D2E6222F7 +:10BE50002B666CED6831DC96C3D8EAC219D45FBD9D +:10BE6000BBFFFEDAB0BF118C85AB6D946EAD96A9A9 +:10BE7000BFCDD51E4A6BAB154A37551750DA52ED78 +:10BE8000A77A0F554FA434541DA0745DF5342A7F52 +:10BE9000BEBA8CF2BBABCB297DB63A48DF7755CF23 +:10BEA000A7F4E9EA4A4A9FACAEA2F4896A95D2EDBA +:10BEB000D50D94AAB2C8581AACE74A7F6619CCFFD0 +:10BEC000D12B5979A4B0F7BC5559E0F56480E578D9 +:10BED000C6925828CADC882FE84B61CCDE10623647 +:10BEE0008047E662F886F9AA10B342DE3387E7D7C7 +:10BEF000E138D0AE8AB100C28D15B0F076809B4D8E +:10BF000009B159305EC0ABB21B92199BAE8D83DF75 +:10BF1000118E6A8ECA105F272C81EBE434EC8751B6 +:10BF200079FEFE8E8388D6311D91524C0B0F8744CB +:10BF300009D291532A579A201D345915B1FD2A8FE1 +:10BF4000582AC078E7AAC4B009BA568AD94113E47E +:10BF50001F2B14C34D307E73091345C46306E05193 +:10BF6000E8596FD2F9AD2C3A0EF05A3563104B00F8 +:10BF70000F3D1D3A5FECA147F82F2398D443AFF053 +:10BF8000DFEA50FFEDC7EC110DF50B77C6B52F8436 +:10BF9000F6FDD0D3C8C78CED0B362719E6B3DAD33C +:10BFA000FFF8F9E7AFA775F645B7A72C153F43B8DB +:10BFB000EBF9F4F397B1E860C6DE72CA84CFD46BB4 +:10BFC000EFF3040B69B82926A007298B859B04CCC5 +:10BFD00006D86C80AB19FED524F33CC2DD04486A58 +:10BFE000F223BB2A019682A93FC0C6601AA0FC2199 +:10BFF00073B0591E8FF932FE5D0E121D345F045D61 +:10C000005C8CFD6437042643FEFBF0CF4CC6AE0FBC +:10C010005D344D85FCE7E6A05805E3AFF5727E5C24 +:10C02000E11B9B84EB7EB4B97F7EACD5F851CF9BEE +:10C030009C0126403FB90DF258A4A3BEDA3DD8209A +:10C040004E0B27E8F729A45F987F7DC30C391F5753 +:10C05000DD8E328B31AB9311BDC5D787F53E85F0B0 +:10C0600035BBF93AD36E2AA3346FE7245B19F0C3CA +:10C07000E7C9FDE3AF316EFE76183292605E1F6A4B +:10C08000F3CA7BED17241F3F1FDD3F5DE972EF7C94 +:10C0900058641D885FA98CE469DA4D419607EB5915 +:10C0A0000DFCE244B9F7E58D0D3980577583487270 +:10C0B000409F7FFCB826A5B34484F2D5071630050F +:10C0C000C6377BCA985A88795D3E4718F6EF707676 +:10C0D0000470BD0E160A98A07F475550C5EF168F05 +:10C0E000CA90CE56675CA84FF2764D481411BEAB8D +:10C0F000B2C4301328654EE4F76246F9E48CE702D7 +:10C100002292CD17309F09D00FFEDB84F05699881C +:10C11000EBC8677E27CCCB56D01D10A17E1EDB1747 +:10C120004579602B61FE26E49F8C2301A45BF50E0C +:10C13000E6CF27320F923C6252D086F22AB7650CC6 +:10C14000F1834D8908B8EE1F5882EFC5F28BC5C345 +:10C15000E5D8EA2F4D09E5EABF6A7231A90FBC396B +:10C160005CBCFC73B3720DE91BC8B725A023B38B6D +:10C17000CBF13679C6EF0B941EBED4CBDFC2458E11 +:10C18000EFC9E79EB7D0BCF36EFAF1205C4F5F7445 +:10C19000B04AA3AFF583B8DCCD9B7C6900E17D0E8E +:10C1A000E6DA24F4AEBF609042F5F4BCE434CAC7CA +:10C1B000AF3F3F89E452DEA97B381F78FBA7577D4C +:10C1C0009E9F7B8DF6809867233D5D1F12492ED57B +:10C1D000BA459602F9AD481F3928303BED17C17AB0 +:10C1E0006C6F9818E27B6B55A9A84279728E142661 +:10C1F000FAF37447519CD9257600E903F0ABB8D225 +:10C2000010EF13087E59C51101E9FA94A617E1AFA2 +:10C21000CE0374E6E34B46FE1EE182EF819D02975A +:10C22000031E2E07CCCCAF5A717CD0881118CFF1E9 +:10C230008689BE331689DE0FF92459F4A3DC5C5BD2 +:10C24000BC321DF9CDE162A4BFE65FDD46F209E430 +:10C25000AA7F13C8D1A51F75A52F837C9E87CB5DB0 +:10C260001D1E498516835E18701C291C403DE9106F +:10C27000983FE4EF1BCEDFB85F5B98D9FFA17E410A +:10C2800061A4135F687F3B549A1FAE1BFAB5B25F7F +:10C29000D138E7B47198E9D861846FD27724664ABF +:10C2A000C01F7D8E63BAA55FFD50756CC1EFDB6367 +:10C2B000E8F73657B2BB6B14FCE3BBECBB5FA18263 +:10C2C000303989BECE813D81E32A367610F375CDB3 +:10C2D0006238117F7C5E3DFFF7ED80BCB59A5EAFA2 +:10C2E00079D75A4AF4395E0C5BA17E7BDAD4CCCE86 +:10C2F00018BED0E5706D31D70340DD0CF9616DCD0E +:10C30000516581D253EF49BD9EDCBFBED8AED76B1D +:10C31000E6F5928BFD623041FD27347E7AC611B876 +:10C32000CF35BE675C65E5B49B490E8DB73153824E +:10C33000F53DE308D6B962F858EF3FB63DD26F3FFE +:10C34000ED9B5D697DB7F7DD3BED2DD67FFB07FBF0 +:10C350006B9FB57CDAA601E6BF39F1FCD56DD82E0E +:10C36000D9636148E7351996DC06C8AF196FF15BF0 +:10C37000010FEDA3A77A106F75AE234A227A827E51 +:10C380009FE86F5E0097F201D6F5EC00702D17FA6A +:10C390005FD78BFDB507B81E1D002EBF1900AE2D4F +:10C3A00003CCFFB789DBABD938EFE42C0BE9931A48 +:10C3B0002FC0D58DFC0070653DFCF0D8863EE1FABB +:10C3C000FA40F436C0BADE1A002F03D1EBF101E0D7 +:10C3D0003A10BD9EFC96F47AB60FB86EC3797F0B07 +:10C3E0007AFDF25BD2AB39F5DBD16B726AFF72601A +:10C3F000207A4DEBAFFDD7A0576FA2F95B9923A030 +:10C40000A2FD53C8F5F8FC1291F4BAB980EB5FC7EE +:10C41000B127488FD6819E1A3C11F5F5F187961603 +:10C42000F7E8E778FD13DF5FBCFE5CFAC9E3CC8E6A +:10C4300078D4F49E3E1FBB12DFCF8FFAB5E3BEE97E +:10C44000B8491E16B58FE9693FF2318BC18EFBF6F4 +:10C45000E319F57B52318C8FFE0418FF8A89A857A7 +:10C4600077FA912E873FF86DC7EDBF7EC16663FFF7 +:10C47000DFD41E98950AF680A3C71EC8AD7A7EDB6E +:10C480007B837BFAC995024C06BA91D814B2DB586B +:10C4900003F36FC7E2AADDDBDE1BD7630F0047881B +:10C4A000B89FD0C7313544B6BD17B38EF37398B675 +:10C4B0000FABA47D4F9E7C7112D2F1EAE6FEEDE255 +:10C4C00067343DBE53F3373D85FE264877A0BF094C +:10C4D000D2C7D1DF04E963E86F1A81FE29EE6F6AE3 +:10C4E000427F9315ED0FEE6F5A85FE2648F7A31F86 +:10C4F0000CD25F6A7EB07DD5614A5FA8DE41E99EBD +:10C50000EA08953F57BD8FF291EA28E59B8B7E4262 +:10C5100072A6671DDC3ECF93757F5DFFEBF8CE3EC4 +:10C52000E33E6274C4E82719B523D590BF289C69FF +:10C53000A83FA225D7509E1F1A69281FD630D69033 +:10C5400077145C6CA86F574A8D74E5B9C6503F47A5 +:10C550009D61C86757DD6CA8EFADAC30940F9DBFEF +:10C56000D0509E115C6EC80F29BFD750DF15586997 +:10C57000281F34B1C9507E69F70386FC251F6E322F +:10C58000D49FD4D96628FFEED1A70CE5E33B9E33B8 +:10C59000E4C71DFEA5A1FEF71CC128CAC3A2E8413D +:10C5A00023BFB04E11F1D79EC268FF6387FD7B2089 +:10C5B000813DF95F83F83ED6CA4691BD7B0EE459B2 +:10C5C0005311B6AF0CE1FE3A17CA9A14DC9A8705EC +:10C5D000368CA1AF286A4F89E5876F260770A78F31 +:10C5E000F57DF0877CF95FFAFE75875DBD0CC7CFDE +:10C5F000E3F2589555D207F1ED75BF50DE8E998361 +:10C60000B0BC4E2E9513C9851396E089583D11BFD5 +:10C61000DFCD0B24B3008ED7A0FBC5B8DC33F12AE5 +:10C620002CF7D8558705F483958F49C5F5E8FE9C0E +:10C63000D51ABFD66B7C6A6597A8E8AF38A7EDFB23 +:10C640009869B2BF3F39150FAF6F2AD7BE488DDF4B +:10C65000E74C8FBE8FE33748E144FA524F75799625 +:10C66000F7C66DFDE24787AF8E4793DC1140FD6A48 +:10C67000532A5985B3379C4C599C1EFED9EB1E3A60 +:10C68000D828CFCFB1C2D240EED7586FF9ADB40E93 +:10C690001D9FF1F5D655F37D5733E295CE1164CD4C +:10C6A000DFCFF12B4E0CAC44F8A6C03E1AFD02A21F +:10C6B0003FCA3A13CC7BD044237D25FB8D72D051E9 +:10C6C00060948392D32807CDFE4A16413F2D8CC338 +:10C6D000881E830CFDB6F81FF19F3C10DF5D121021 +:10C6E00062E87020FEC321BE1A3630BFFEA3FCDD17 +:10C6F0003E279DFABF47E36FE0689EAAEC75A49FB2 +:10C700008A891A0131E5877F81792F386C263FCFDE +:10C71000E55F6C3BB405FDD113AD32FAA3190B1DD7 +:10C72000FA3594CF09D8CA30BFE0D8688B0FCA8FCA +:10C7300064021178B0BC2C05E5C069264E433FDD8C +:10C7400069F67ACAB81839B764B085FB7F1ACCC7C6 +:10C750003B6D38BC4AE753B787785E5FD7BC16633A +:10C760007E2E9B912EC138731F34A3E4630B987403 +:10C77000BC538703D0C18F07CBB49E79AC72950CA4 +:10C78000E3D69BF9F9CC9217475B100F0BC6C9395A +:10C79000A6A29E79DC3D98FB014F02BD29D69EEFF3 +:10C7A0000B9D610BCAE5137BC6FDE01286FD845725 +:10C7B00065A25FD305F688D21BBEB31B8CF31C6841 +:10C7C0001DF1F3666C25C1A3AF79483B844022FF7D +:10C7D00079ED60C180C75ADBCFB675C23C03B51294 +:10C7E000B35F0679899F1FA9C792C3DB517E975615 +:10C7F0003ED1097050575AE55A48373A7EF62CD642 +:10C80000AF0284E1F9D3CEC10AF79FDA7D613C5FC4 +:10C81000007DF3DD19C9DFBEDFDDFFA47E5FC07ED2 +:10C82000D37AF7BBC4D669C173B46552E5344144C9 +:10C83000BF22AF6735070343D19FB8AF283A5431C1 +:10C84000D46BF89AF50E0BB95FABDE34B19FFECE18 +:10C8500068F2EDB73B1FB5A0DC3AFDD4BBD7E3BE11 +:10C8600068D1AF4CCC06F5CEEC4C6651B2FBC2168B +:10C87000B45F17EE3105C2948F4EB8313996AF6B65 +:10C88000A9FF45CF26D3BE6AE173D6F07468BFF026 +:10C8900085136318C883332BBB0F0D45F83D2590D6 +:10C8A0001DCDD4CE3137C2F78512BBAD2C81DDF161 +:10C8B000678D1F4EFDC2518EF426EC38702BF51B90 +:10C8C000F9A1D91AA3C73A069B099F508FFCDBEA4E +:10C8D0009342385FE0F3BB6174ECFC6A78BD27B922 +:10C8E0003F77E13E73D88EF3DBD16A0942BD653BE9 +:10C8F0003E21FABEE2D95D29088765FB4C06B9B630 +:10C90000E8D92F575D0C785E6462DDD3498F7F4193 +:10C91000F973015BB789E450204500B9B59444161A +:10C92000D47BFE83A97F81F2931E13B3832838D969 +:10C93000F1BEE557980F3A2B991FFB37F2E1B21D74 +:10C94000272C382F5964DD59C0E8977D1AC397AC5E +:10C95000777DC6BA2D286797451A3F3101BD2DDB7B +:10C9600073FA2DA4BB6571FC7C12FF91D15B5F0A49 +:10C97000EE787DF9DA0486E7F43B601334A96F7D25 +:10C98000A9F3F7A25DE7B6AA30FEA9E73EDEAA0248 +:10C99000CA17FFF7DFB7FE14F7492FD965944BCBC1 +:10C9A0009EFA530A8B817F969B9F279D79F289C7B8 +:10C9B00037011CCEFCD94A503BF3EB0F7C0AC0FD7B +:10C9C000CCEEFF48C7F3A5BB7E7DE510A4B3BBF654 +:10C9D0005E31A4BF7D05D26DD81A8BDF30F5AFEC88 +:10C9E0008371864076BF96C6E1E5D4EECF2D784EB2 +:10C9F000F499C0BA51FE2E8D7C6941FBEC508075D4 +:10CA0000239C5EDE73E2D0BD903F0D78B226C0134A +:10CA1000AC7FA8487A253A14F5CBD23D377EEFD2C9 +:10CA2000624CCD7E05F1C4BA49DEF7C2EF1B80DF50 +:10CA3000E21EFCC6979F635F5810FECB76023EC78E +:10CA4000205E019F637AE3F334FE63526F7C5ED213 +:10CA50000B9F8BB76DC2C23D8309FF7DE173C9DEB9 +:10CA6000EFF76B67E9F2612038CF17F8BCACEEC086 +:10CA7000B56EE4B3E71CAA87E3393C1DCACEEC3A95 +:10CA8000E74367C887E6EE5B110EDDBFB6CA786E76 +:10CA9000BFF0D76F12DF9DD9FB070BE21FFE528458 +:10CAA00009906717FE5E67905FCA6D70B684754F18 +:10CAB0007DAB1853D6ADFA097F943F047C48F80843 +:10CAC000DF304D41F91B4EA3752F0D73FE581A3EF2 +:10CAD000709330A637DCEBDDA276FED3835761225C +:10CAE000E2F3DDA9487F7DE1535FBF8CEBFF2E941D +:10CAF0003F66E4DFF8FA4B815F717FD40BBFE1033F +:10CB0000FF8EE99956AB24802D7406ED04676FBC47 +:10CB1000F7C09FEBE76F6A1F57C7D187DE5E87D3E9 +:10CB200040FC3ED0FABE29FC96B815031DE9703CC6 +:10CB3000F545627DF088263F96B2CA6999C37AEBC3 +:10CB400033132B53870A3DF35D1531919C3FB5C3D9 +:10CB500044E733F1F262299EDB2618E74937B763D1 +:10CB600096EE3B3006E5DAA983BFD0E892D3FDD23A +:10CB70009DEF5A544D3F8463E5731FE7C0CF6BF3BD +:10CB80005EB63F717FCB767E92B0BF9352E087381E +:10CB9000FF931D66A642172723A684710B5BDC66F4 +:10CBA00083DDB52A79C2D141B82F48495270DDB52D +:10CBB0002B036FE2B9A8FABA99CEF999E4FFD00A2B +:10CBC000E5B5C9490AFAF36A53E63225468FD7C557 +:10CBD000C149F294D1F99DE42E2BE67BBAB0E1BCB9 +:10CBE000D70C04113B6FD0BB59A897DE29FAC08C33 +:10CBF000EBFC6B9C1DF95789AD1A02FDFD5515FC28 +:10CC0000354AA2FD81B1FFE07D26A6C4F4BFD4DA87 +:10CC1000FD0ECE87FDC6CED02E33BD6417509E2CA0 +:10CC2000DB6AA6FDD732D85621DC3ED8620FAB9026 +:10CC3000DFF87CF5ADA897FEB6D5CAF05CE2E5BD9D +:10CC40002BBAEE41B9F488C0D09FFEB75F547F86FF +:10CC50007A79C166581DC893798EEEC7B1FDBC675D +:10CC600087B25A68FFB11099809BD9AEB4E804DC52 +:10CC70008774EDCAF0ABD4CF8B4BB1DF33CF3AA87A +:10CC8000DF33BF7993C639F39B64D26BFAFCC1DE04 +:10CC90005662F538D8DBCA053E207B3B260FE32CD5 +:10CCA000C23CAF2F7CA5C93C947F8B3005BA5FB4E2 +:10CCB0006F5000FDBB31F5A89F65D6EE9FF869FF68 +:10CCC000AD668AB4778A66223F2EDA611CFF3FDCAC +:10CCD000DCAE5A66E99ECBEB873239DF76503B4BB0 +:10CCE0009A46AF5A797C7BBDBE94966BA8A7B75F76 +:10CCF0006A659589F8C0A5F5BB68C797238CFD7157 +:10CD0000BAED3D0EFF7EB7C0C87FC276DB29EE6C60 +:10CD1000B1253A3C15F8F6050B9B8FFCBB38253A3C +:10CD2000DC05E3FD4A939B8B93200FDF33B57960DD +:10CD30007DCC335BE719C4EB9217ED74AEB2E4859A +:10CD4000373F437C9E421803C64EA5757CF653A020 +:10CD500083535B4C4C057B6D8935EA7B04F5D46EBF +:10CD60002B6B43FE7EE915D25BA79FB38AFD9D53D3 +:10CD70002F890035D87AAF432D6505954E8CB709BC +:10CD800088ADB86F386C0AD7C0D8555260E5B3B8D3 +:10CD9000BEC366DA679C9DC30A705F799665FA55D3 +:10CDA000C2BFF2A604E52B5E350B89E290CCE741C9 +:10CDB000A88F033E387F2D532095CE0FA37485A5F1 +:10CDC0007204CA5D930C8B2B243F01D9ED66B79F8B +:10CDD000CD8374452A0B22FC98F39A0BFCF57B401B +:10CDE000E9F2879521D86E521A972B73D20357A672 +:10CDF000917C71CAE457D2E854DDCBE7F9B990E4ED +:10CE0000AF8179E59DBFF73684EFF2770525F6FC13 +:10CE10003C3ECEB34A52DE548A69BD248FF2E424EC +:10CE200086703D2BF3B8BEB3739441AE18B9BCA65F +:10CE30005A26F9D158EDA17475750153C8BFE6A7FC +:10CE4000BC495BBFB550A53835E469FCB33ACB02A9 +:10CE500068E7E19CF2153CEE0F121D593D95E49BED +:10CE6000B23919ED634D4E95CD83D4ECE4F03139F0 +:10CE7000CB083E162D2FB54C2778427BFA7E797A67 +:10CE80007011C2C39635D220972CEEB1867C2F78D4 +:10CE9000E9F8DFF57F053746706AACB651BABA7A61 +:10CEA00022C1ABBE3A40F9FF07B83DC0E17631C6BA +:10CEB0005AC4C0ADD490EF136E0F03DFB863F90608 +:10CEC000E0887CC392FCDB13AC3F3E7DA81A17C7F9 +:10CED000D803D52D94EADF53FBD0DB9FA4713BA090 +:10CEE0008A056BCC74BEC5FD2DCCADB2AC093DFE40 +:10CEF0004DE651998279E455C4CBD12482DDF2B755 +:10CF0000EDE43736C95257AC5C5B7E9D3204E59741 +:10CF1000A9EA517662708C1F6D7A995D21B8FA0585 +:10CF2000F4A7D66A7AB3FE02FE8C7CB0A65AA1742E +:10CF3000ADC60FEB357ED88078867CAD9F9F6F366F +:10CF40004F63A417FF05F27C1F1F65B171262E7F6A +:10CF5000246A067C938C54288D529CEF516B381FA9 +:10CF6000E3A80A19C5D1B98EDE43FE63C6221EF4BA +:10CF7000A7B934B8B1FDB9AE99C9B43C33D73BCCED +:10CF8000C4D39019EDF178B8D6FA0FDA707FDDD7F7 +:10CF90007C4ADE5920E0789FCF243431F72D91A3CD +:10CFA00015B00E67B383F46ABABF321BFD7BEC98F1 +:10CFB00095E8D3E90F0AF362F097DE875D7767FAA9 +:10CFC000D57F45FAEB4459067AE88196617684F379 +:10CFD0001A73C483F26E8D8BEB0FA51CA0F0DD9E3F +:10CFE00076AF687230A5D8C8EFBA7C95278F35D058 +:10CFF000AF2E5753A718E95C97ABCFA7717FC59C9D +:10D00000F4B24FD2201D7C7E33F1613CDDE7C917BD +:10D010009707DDA80798BF09ED35B419D18E7B5766 +:10D0200008737AE7FEA9B39D396D68E7C0AE80E466 +:10D030008A8AFC4078EA7EF92B68B74B930F2B6DF8 +:10D04000336CB8DE06A02386E77A403F08E07540DF +:10D050003F9886807E387F4CA454A74F4F7A8E210C +:10D060002ED0947748E4F1F222F99E25D8DF396179 +:10D070003CE9C0241BDA7B92D97F18E55477B218BB +:10D0800041BD59EF9C610BA0FFC6554C78FF2CB9F0 +:10D0900022BBBF3827B05BC86F2B3BFDEC388EC37B +:10D0A00018F96D4DF25886FBC45DCE8E24DCB7585E +:10D0B000D345C3BCE6A407BDE931F9D138BA862F00 +:10D0C000EC7697D64FFC7817A56B7ECB2C95056236 +:10D0D000CE2DAA74FA5654362586BF57E64F6518EA +:10D0E0007F11CFD77DCAADEDDF4E6ED56687095F64 +:10D0F000E67879E10639EEA45415659CB777CD8FB3 +:10D100008A88AE2E4DC7FDA1B3ED821D72796E02E5 +:10D11000FA3A3A7208C5675ED033B06B2E243DB33D +:10D120007122B747343DC3F5D3D96607E9A7B37376 +:10D130002A299EEA6CF31005E9EEC0BA4BC6203CE2 +:10D14000E69E6F640ACC6FDEF94994CE6FF939A57B +:10D15000152DAD40E48CD5AC9DB76E26B43BF1B037 +:10D1600089E283BAC2E3CE5441BEABD9CA4C304E39 +:10D17000D7E63BB3D12FDE05E3A07DD5B5399FE8D7 +:10D18000AB0BE046F906637D8C0B36015E2A18C7AF +:10D190000BFC2F80F5E7BE626A4D642755ACB706DD +:10D1A000129DEF5C286F496CB7D5E23F33F07F9555 +:10D1B00023105E25EFDC938DEBD5F97F452AC8233C +:10D1C00084D73B5696C81F7F79FA9573912E2F4FBF +:10D1D0000F2CE578494DE85FEBA17F3EEE0911EC9D +:10D1E0005BC24B30E506839F95FB314F68F62FB34A +:10D1F000F5519EA2B59713972F69FEF8D0FD0CEF5D +:10D2000029549621D1EBFB691383FDB480FBDF1B0E +:10D2100028FE599F0FD8A944C70CF081F2658EE60D +:10D22000EF01B87FCF02DF4FBC6212903E7AE8294F +:10D230009882768BB0E6BA95BBA0FCEF87F9FE6CBE +:10D24000C1F90D24EF8435A3374E82EF77BE6226F5 +:10D25000395FD374C9FA5B00BF9FBE66A2FCFCF3C2 +:10D2600076AAF7D1FDFE8DB740BDEEDF99C90EFF5E +:10D27000F4F09514FFF891D9E827983084F3F1F38E +:10D280001A3FCF3DBF86EC0FBD7C6EC36C8B4274E2 +:10D29000BA8EBECFC5439B4C9CFFF7FFAD44C2F393 +:10D2A0001C46F7149E7FE8866B57925E1B4BF6FE7A +:10D2B000BCB5567FA278D0E7D31583FC99D7D94C5B +:10D2C000FD32B08BDCE95A7F317264DEF9C1C407EC +:10D2D0004C5619C619CFD5E4C985F96D361BE4C97A +:10D2E00047F6C47E9097D3F93E6AEEF94B88BF7A31 +:10D2F000AFEF32FA3E571FB793F363CF7A364E4AF9 +:10D30000B49E9E754CA6FA1FB9128F7F52836F5739 +:10D31000F57C1600B95461857A4E1CFFCE55138BEF +:10D32000711DAE5421665DF35A16B140CCBAE66D5C +:10D330009E65A988E9B7070FCB0C783899BE90F0A5 +:10D3400070677AD911E49B8A35978E417A9CD7D23F +:10D3500048703E61F6FB50BE7ED072674AA238D854 +:10D3600093F1F869D1F003F66E710C7E74BCC4B70A +:10D37000EF7A7BDE6718D7D4F530376EFA82572FF5 +:10D38000BCE524869B3484E3AD0BF46D90E0A6BC31 +:10D390007014E97AADC38F74DD37FC46B1607FF05D +:10D3A000EBC37E057BE74B943B12FA68F11CB28518 +:10D3B000D3C14070EB1957A38392C4EB197B613D35 +:10D3C000554C05863D6E19880E7ECA545B3FEBB8FE +:10D3D00040073F37D0C1D88D4DD7AE847A1FA2BD4C +:10D3E00032A237FE8F5BD4948BF1DCA7C944E74AA5 +:10D3F000C793D4F49B79BE08E5F1F194D0F5784E4B +:10D40000A3E7176CCF4F991533EE070D008704F093 +:10D410001B3B4431F8A12ED04F9ECA0A27FCF3E8EB +:10D42000E78439F13DBECBD34B260C413B2594D844 +:10D430005FABA7BABC360D725ED867A2FE3CEECCDD +:10D44000FD2C0CA5F5E9C1D221E3317EF427B7A16B +:10D450003C387E5C207D5BF3F68A11A8D7E2ED04B0 +:10D46000D87F36E0B9E70A537288EC50A9721B9D49 +:10D4700083AA12DB5E8CFB94CA4DEFE5A3DFB08A72 +:10D4800052A6D9A12B4C23FD4DE497AD7C02CF4988 +:10D49000814864AC2FB14A3A3705415886F98D0E60 +:10D4A0007EEE5A25D9646B4C5CC2624D9ED757976D +:10D4B000FDFC3DF443DB5426A7637B2E3725C6EDE8 +:10D4C000AFFFC479C6E87B8B3928FB711F2AB032C5 +:10D4D000E40BB314A47B4E668FBB488DC1C3C2213D +:10D4E000DC7EB4B7B737E4407BFBEDBF93510F5AF6 +:10D4F000611CF4B3D9B2A4B3B1FE6AB33B42F7984E +:10D50000585ECC77B0AB9C859037F80160BEFDD8F3 +:10D5100085BF12FC9ECF901E6B383C26228820FDD2 +:10D52000F39C61AD2897274A75268C3B9A797B3E00 +:10D53000E537CEFE6A7867027A98B97F7507DA33E5 +:10D5400033F767CCC6F38399CEE1EF630ADB055B63 +:10D5500012B47F5960912648A7D81EA5B8C6973542 +:10D56000FF583BE663F462BB466F60E74CDB0DE9B6 +:10D570004C5BC87C47618F3F2D7EDC0D1ADFB79B6B +:10D58000236923910E601C5CC78FF787BF0FAA9F8A +:10D59000DD12095F371AF0732BEB36231C834CA680 +:10D5A000730FDDAF5BC1FC5A9ED1FEF42F8BCD6DA6 +:10D5B0004827F1FDDD12E5FDFDB81DFA83F4D6C361 +:10D5C000DDFF8A6A391891A73A584C7FFBFC871C0B +:10D5D000AC777FF170F64B36931A03574091180BD6 +:10D5E000F75EF01D547E0D1BD3379FF5C09BCF23F4 +:10D5F0001E1F9F6211F0E9234302BB906FEF1D12C3 +:10D600007806D3C5B66E9F047473C41D7C0EF34BAD +:10D610004DC1EC7480C7696F70441AC2A523F1F93B +:10D620006B3C7FE7959FDE827C736B8DC410CFAB24 +:10D63000F67EB005F9F2B419F808F6032FDFF341CE +:10D6400032D2CD1260C05879F24E553ED94F67F7AD +:10D650008CE8F7BEC93B9ABFE4558D4FF475DE8662 +:10D660000C08E3DDB6C741FB99DBAA4C17F6594815 +:10D67000EFB755F1F81026758CB9C96077D669E710 +:10D680006CBDFBC17D447C3F5DD5C16DC4F752705C +:10D6900002DADD27AAE76F43F9123F4FC5137C7BFF +:10D6A00008E9B75986B8DB39CD0BB6C5F2A15EBF24 +:10D6B000B60FF9BA7FB8B64E1B1F8F29DF29714EFE +:10D6C000A07B99F4678FDADE1562E861A0F158DE7D +:10D6D00094C005B940F7E545E64CEFDD5F7C3DBD04 +:10D6E0007F4FD515ECC4385C5FE0DC90F103CF9F31 +:10D6F000793479A6B5D3BFDB83218676A1FD8B4132 +:10D700006427EC1FCEFD0F9F6A760173C27A91C128 +:10D71000421B03FF1FEB8581E95EA67DB335615C8B +:10D72000519A47E274133954624B30BF5EFD452570 +:10D73000F675EAED1FCEA85F749391BF6B7812ED7A +:10D740006B2AAA6A699FDD08F203F541FC7C8E37DB +:10D750003DA2A01EB05B420AFA451B87A7E7AC8436 +:10D760007620D5C8EF634F0A2952EC77CD1F645F4E +:10D770001952707FDB989F49DFF5FE1A052E6775F9 +:10D78000BE68847DDF73E417F37B66605CE91BE1B0 +:10D7900069C9D0AE6D158B9A7C8C1DF4658EC27DE7 +:10D7A0006EA8DE42E77B8D0562C61CC8A7786DE4D3 +:10D7B0001F6B754567E23D5A559048BF865CCAD5D8 +:10D7C000C9E8DF5D39A403E5DFC13B2CB4DE359346 +:10D7D00044DA8F592F7E2F7405F67F17F3A35E6D01 +:10D7E0003BFF7C8B13E5F051D8CFA2DF103B0579CE +:10D7F000D436EDAC1DF773A918570774B3D91CA123 +:10D80000796DAAB152BF9B5A2DE589F0F77E864407 +:10D81000F5C34227C5070F66113BC2F58169333650 +:10D82000E641BB9C3C26E37E7E4DE1596DBF19303D +:10D83000F1F328DD8FC8ECDA79964D3BA7B2C5C667 +:10D84000173E12DA43FE43C7F4084FA789E47F8EE0 +:10D850009FC7520FF7E33926774C433DE1281699CD +:10D8600080FECD3C26E0BAE4696D748F39A780F55F +:10D87000D19EAF5B0E40FB62DE1E7D42F2D76C3F55 +:10D88000D7C3E30CD7A21F0ACAC366BF7035CC2327 +:10D890007C9D2CA84A4FBD6A0FD7AFDBA0FF28C9DB +:10D8A000D130ADCB57108922BDF9168B84A7B513A3 +:10D8B0008FD3B9C003C5BA1FD54FF3D85C73E4004A +:10D8C000DA5F9BEF6664276D46190AED365FC7C2C3 +:10D8D000FC3C8965A27CDBB4C0722D9DE71702FC7D +:10D8E000054A13CEFB4719365AB7EFBE07A2784F49 +:10D8F0003FC9CFEFDF429AB07E6D8689E6BFC91C73 +:10D90000CE40FF485F743143C387AF4AB3AB58C8BA +:10D9100083785DA7C187DD3496FB17A480121BC7EF +:10D92000D5A34FB81F03D64771AD83EB2CA48FC48A +:10D93000E9D199B8AED4020BBB2A07F98BC34D1DB0 +:10D940002DF2B833166E41FE6CBD289DE249578B0F +:10D95000610FDD132FB5D079F2C189E2CCF950BE49 +:10D96000BECE427E08C813BF8402B9ADC86F8EC94F +:10D97000A5E5F321BF41B6C808DFDA42D98E745C51 +:10D980001B106501F2EBCAF47B128CDE3128329950 +:10D99000EC0550BE2D43441F2DDB2608C4EFF58156 +:10D9A000D2D030F85E2FBB85583FC05E0DFF8BB2E2 +:10D9B000CBF67A906F020F8486291C97D20422310D +:10D9C000FA4B66D1F91873D35AFFF851BA0F556460 +:10D9D000A3FBB3DEBB42E574DFF1228B82786D3BA3 +:10D9E0003F7814ADAFCEA2203F6F10C25723DF6F38 +:10D9F000BEE3908A7E75FBFB4E8C1D66CECE4FAA91 +:10DA0000317ECC596C893BC76222CA717D5CE71BB1 +:10DA100051A2A74E21F8C764F2FF143615B8299E0B +:10DA20007902C273DDC56F15CC4D4017D0DE993E2B +:10DA300016ED65313A610CCA29AEC7982467C4E275 +:10DA4000778337F3CFE867DA5A02F3C7F1AABA6EE1 +:10DA5000A179058EFC14ED2AE7B18FBE4C3CCFD7DF +:10DA6000498F241F7344C531982E994EF6596C3D49 +:10DA700090FB8DD981BF7A00BEBB6AB8DC6FBE9DBA +:10DA8000D1BB13F8571003DFE64290D2F4000140F7 +:10DA90001EEB15CAE4475F2D2A9128C2738C8DE8CE +:10DAA00069080B925C8B5FAFE358E31D1877E4F0D5 +:10DAB0001BE77956C32FFE49E9745E819628B3644B +:10DAC000CCB1A3FCDB3D56C9C0FDF603AEC47AFE63 +:10DAD0004F197C5FB44B486C9FFF2DC3CEFB075999 +:10DAE000199D40A86214D70779319DCE6DC8C96DC4 +:10DAF00015B95C60D730D27B29459D767FCC784FB5 +:10DB00006BE3D01FF433486BC7E4EE680DACBF1570 +:10DB1000A816EFB5A578391C9D6A0F1CB1BEACAD37 +:10DB20000BF8A06644310251A6FAACCC42E72220A1 +:10DB30000DD5AFC41E38246BF5374D94041BCC2B88 +:10DB4000178021407DD7348BE11C45AE3BA262F9A2 +:10DB50004F4D4C499DD833FE9622165E09E30F0ABD +:10DB600018E19D7CD70B2BD02E8FA7039CC1857EFF +:10DB700031547C8EB15DFA2DBDF880E049F304D0BC +:10DB800034BFC1DA2C0094E61D921E1F4BF277BC05 +:10DB9000A943457F280624ED85F98F7CF28DC04E80 +:10DBA000C83707399F2517BCB002E9D291C9F1F4F3 +:10DBB00047F42D43FA0893FF8E713B6A95A8203EE7 +:10DBC000B64673498F3732A90CF1D458794444B919 +:10DBD000BE660FF30B02D2FF7F5B63E77753460EFF +:10DBE000C7BBA490FC937CFCFEE89A42D181F2F57D +:10DBF000E01D2F90DEDB724064C8FFA5BF3DF6B08C +:10DC000003E9FACF56CA37BF524972E327D04E4DC7 +:10DC1000E03F1F482FC7D7CF5BD226E0F944F6FC80 +:10DC2000C82BC3513E8724FF55888FF91D0184936B +:10DC300052CCCFD99CD3A3F44E88825A0D6C522576 +:10DC4000A4A5CDBC9CDD944AFBA8D1D6CE866B6042 +:10DC50007E8F3C2931D497266B24631EF46B7AD1D6 +:10DC6000899AA0D7FEE891E9D10C94E3499514066E +:10DC7000DD6B7E6F67703EF44D575E1D0EFDBA265C +:10DC80007358DA43430EA0BC449B19EF553854AE89 +:10DC9000E7D649E100C679AFBB2B68C1F199B67FE1 +:10DCA000695C52F138C2F984A6F758E57C7AAFC4B2 +:10DCB000A7F18BA38A9524DA673DE049E2F12DF7BD +:10DCC0008B07903F7C0146FA43AE8A4447687A1935 +:10DCD000272EDFF75C23EA17E76291D6B14EEAA858 +:10DCE000C17725D6DDC5E41AA5777FFF68FBE51966 +:10DCF000567E2E8A384EEB5907B9E440BEF9E62726 +:10DD00005E4708C71DDFB38E247D1D059D94D7E7B0 +:10DD1000B12D10F95AF3D8A0AD634D067FA7C851B5 +:10DD2000D849EFB3C4CBFB958E77E8FD9830D8EA9D +:10DD300026BA8F16B906F3CAB322E3F7B58CFCDD19 +:10DD40002BAFD155FC7785C58C938374C7F10C74C8 +:10DD5000A7D94FC077361401A2F215F93142FC9DC4 +:10DD60009C387AFCA7CBC5D87943FFC90D4CA0B825 +:10DD7000B8C54C29CDE82D179926176D4C8DA2FCFE +:10DD8000FBBF968B2007492E36C34A07C34E25B9E1 +:10DD9000BDE90ED4E3BA3C1C8F38C177A254F375A9 +:10DDA000A585B42FA27CD1C3AF36D37B43A276DE48 +:10DDB000A5C105DD500897CF3D8A419F3E84FF8075 +:10DDC00075EC6E4FBDB610C6DB589E5B84FB0B7BBB +:10DDD000E845B20F7C853C7EC557C5CFCF1D797312 +:10DDE0001F8FBD17B730C342F4B750A7BFAA900723 +:10DDF000C75987FDA27CCEB390BE7C8445B83ED483 +:10DE0000ECD3168F1647ACD1553C9FC4CBA771BF3E +:10DE10007397A27CCF10AC32EEE7503F1F4C37EA2D +:10DE20006BA4175D5FB774AC74A13F2C47F3F7E7A1 +:10DE3000D88C710E45995C5F7FA5F901568B95B41E +:10DE4000DF544B45DAC7E9F477418FC7C1311E7EF5 +:10DE500048A8AB26507C0CE5534ABA19F2EF56207D +:10DE6000D90D5066CB5034FB402638B7FE581C8B7A +:10DE7000F272777B851DFDEB82CF7635EE0FD70BE7 +:10DE80002C8A72737DC9EB1457D254053DC3A29CF2 +:10DE900005E22CCB98DE78063EA6FDAA43B576A017 +:10DEA0005F2B126DA3B885A6F0A1998CDBB10CE3B2 +:10DEB000529A0A56662E44F95E50568CF86DADB7EC +:10DEC00050DC8C5CC012FA11DED7F631DF548F398A +:10DED000F4FDE5E2C4FBCA6B32F9FE362281A8826A +:10DEE000F96415887EE4FFAC3A4BC2795CAAE1295B +:10DEF0002D93DF0F6BAD3F9441EF63899561D61F82 +:10DF0000BE60FA2BD363F031A90F7C78747C483A59 +:10DF10003E5CB3880F3B3B442E6F49AFAD63F2CDFF +:10DF2000A81FD54A0BD9B18D66BE2F6F2BD4F842EE +:10DF3000B6B522B17D53BA4E5922D23D1CEF449161 +:10DF4000F6898EC5CF515CD323ACFB1594778063E3 +:10DF50001A2FBE7D79A6A8C15111FCB49FE67804A2 +:10DF6000BCD27C36E7A7B7C6F2E9039A1DFD8087CD +:10DF7000F3E9E6FA87884FBFEE3C75B95DABD9D1BE +:10DF80000B02410BAA0355289B9A81FAF331E6470D +:10DF900038319393ECF20FB1498C5FF6CEACE0C20E +:10DFA000CC98F345395049EF165E89EF0A41FB0FD3 +:10DFB00022FC3EE80791E74BE8DDAD2023665EC01A +:10DFC0003A04627290A1DB21EF912254EE990F7313 +:10DFD00071D1ED48CADB6CA0176142A7ABF9FD8B8C +:10DFE0002EEDBDC8C7B5F7223FC6F721211DDDB212 +:10DFF000BAF4111C4F918228334EE27B9178FF795D +:10E00000E25B14177D0A646D930BE3617E5542F762 +:10E010004FEE65B23809F36B4B31EEF9CE97ACDABF +:10E020003DC98E9578EFE55111D60D6DD648A0EF1C +:10E0300087615183501943C7BB2EED48C173BED3CE +:10E04000911BFBF51FE3FD417A2F3393E369836353 +:10E0500029DD2F9BEB8CFAB0FD81DD4F3CBE09C65C +:10E06000FB78AF8DDE35D9E858EAC3F28F1F7ED337 +:10E0700087FAE2F4DE372D89CE27974891A9788F69 +:10E080006CB13A88AD84F99744665928FE64E7017B +:10E09000BA9FB6440E5AB0FFC52DBB293F65E71F96 +:10E0A0007C58FE6626D713A733823EF44BE4B5585E +:10E0B000A322E89F5DB9A18509CFD933456DDE2F35 +:10E0C00051FF1B1D2F1D42BC9C7ED84A7EB7030FFB +:10E0D000FF96FA3DB5F7459AEFC7BBDEBC15EDE9F3 +:10E0E000C58CF9519E9FB66B7E3D5B474AECFE7630 +:10E0F0009F060F3D7F3A59DB07670D504F3B8F61FD +:10E100004E803FDD1FE848C1FB851F9B831684C7F7 +:10E11000228407A425000794FB8B2202CD73514B68 +:10E120002BDDB75AB487FB071701BC082E2D0768F3 +:10E13000FE4732B9DC38B5F78F3E7A9F628F95F68D +:10E14000CFFABA1739833E848FBE5E80035FF7AE85 +:10E15000AF87A7B93A9E5AFE40F35ABC87CF6BF1FE +:10E160004E3E8FB97B004F4EC4D32CC2FFA9BD4C8D +:10E17000C17B305DBBDF3C89F6CCE9BD3605ED0ADD +:10E180007D5E59206E53C6221F717DCCF608A48F88 +:10E1900099D441E7394B6459C6F7092E94872D610C +:10E1A0002E4F3B4A8742F9D30F8AF48E25932323BF +:10E1B000D1BFFA61A67EFFA7C3877EB15D9786882F +:10E1C0003E3F4AD6E02D75F8307E66C3D0E0879991 +:10E1D000B1F878F7C591B8EE15A6CADF7A719C2719 +:10E1E000787CE8E7B9957FBD9FE63DCC70DE189F4F +:10E1F00002DC52F0FCBB406441BA97BCE7E5A4D80E +:10E2000073E82F33B9BEDAE87887EE239EC6F71C91 +:10E21000693E118AD31A1EA8F0E139DF47CC19C430 +:10E2200073D98F1F7B99E26DBA3274FF5307D53BC8 +:10E23000B5E7E5544C2BB4787816BE91E418C0B11C +:10E24000C13636917CD4EE1785F9BDB13302084C46 +:10E25000D4135B7438575A6618CE75B81CCDDA9C47 +:10E26000D34EFE9670E2FB66F1F237EFC14974AE11 +:10E270007C8E253E57665A9CDC0A5312C5DF6C74AF +:10E28000FC8CEEDF56A95619EFAF1CD7E4E27BDA1F +:10E290007B0B9F27A5A822D0CDF34383DEA169BDC8 +:10E2A000EFE156AC59E243F856E0B9076D6AB65D46 +:10E2B00087F1845D694C7B9F9445097E66BDFC5F58 +:10E2C00078B98BE78B873EB316ED13842FB7531FB6 +:10E2D000BD0EE31ABB7278791996437E566659E1F2 +:10E2E00050EE3711E81C89995D5D36AEC213C1A3AB +:10E2F000072E12EBD2ED6AA83C7B2823B8427F138D +:10E3000086D2BE1EFA1BFDEDFB03BCABB6D4FF8567 +:10E310007E6CFF5BFD44482F89417CEB0ABEF9B956 +:10E32000FE7BB494C94DAE6FDFFF3FDA7E852920B6 +:10E330007E8474384824BAD7F9BAEBE11145B8FFA6 +:10E34000B734DC1145B5D9955C6AC980EFE7147E16 +:10E350007E72FB831B0CEFA8EA69FC7BB5FA399E41 +:10E360006598F17C76D5502E8F560DEDF113E2B9FC +:10E370001C1E57D1C619FE9AD3291486DBE9AC526C +:10E38000C4F8C382761BBDD77B11034101F31FC5BF +:10E39000A222EAEFD1AC93F2DF411040BE882926D9 +:10E3A000CC8F63DD3E69189E3F4757A19D76C41D03 +:10E3B000AC43BAFDECE18E770428FF4966F0979DE7 +:10E3C000E8EF1CCAED5427988548CF32A64087A2B3 +:10E3D00063BA2791DCBF004F593A157BDE76831470 +:10E3E00058C7F9224BEE72F4C05997070BB5F7974F +:10E3F000F4F6279F7C2297DE1DEA7907BCDFFBC07D +:10E4000073AB163CF8D8B87ECA3539BBAB267C73E3 +:10E41000ACBE6FD3E0BC7DA868B00B6154B2E39E84 +:10E42000BA81DB4FBB2E0DAC7C14E56D8B89F6D326 +:10E430001FB5FC91BF8753C6C8AEEB6BDC8FE2F013 +:10E44000FED1F62732F97947D8A0DF173CFE8B9131 +:10E45000B1F1960066C53D81BFC341783FE457AD39 +:10E4600026A4D232F2C75858258F53C1F90EC3F7EC +:10E47000B822943A5907A529AC9B5299C9E49F4EFA +:10E48000657E4ADDAC8CD274562970FB2E44692619 +:10E490008B509A85F629FA7B5837A50ADEF88C89C5 +:10E4A000DFC8C513D361F8DE6E19FF1E171F2421C4 +:10E4B0001EC72590E7717141D28E2A92E7181794F2 +:10E4C000EFEEFD9E822EBF370C2DFD13CABFE787EE +:10E4D000068E20FD1C7EE6557EBF62AD40F6F50936 +:10E4E000FB748B02A87B3A3540EF80A8222BDB0E11 +:10E4F000FA7D8EEEFFC73F3D4E1881D96C3E151B4D +:10E50000BFC36CCE023C2F9EAD559DAD9D83CCD636 +:10E51000FC20F8CE19BFA7E7A7FBF6B3B5F387D960 +:10E5200071FE1716B21AFC282AFE03D6313B24D0FE +:10E53000B9C1ECA4E92F75B2BEE924A63FBAF757DA +:10E5400011E7871AD09F15979F13DFDE26305B3ABD +:10E550007EE7F4F4F4650AD975BA3F0B084EA1764C +:10E560000DD677C92F14BA32100BA7E42CBE6FB5A5 +:10E5700087AE4A49F4EE929ECE01FBCC9CDABB3DBD +:10E58000EC085DC8F7BA1CD6E93C0737B6C84705A2 +:10E590009684EFAEEAE91A4DDF37DD1F62386F7BF4 +:10E5A000F41E7A8FFA6EAF4ABE5A5B6198EE07246A +:10E5B00015843D6A82F935E13BCEC05F4DC9C67313 +:10E5C00093C5599CFF1767F1F3DD4317A597E279CF +:10E5D000F66A85BFEBBA5AE1BF47B03A6BA0F7C8FD +:10E5E0006D867BF2AB066FA57780EC5F6C63684F3E +:10E5F000DAA5C4F7526ED2E0BA41ABBF71F056F261 +:10E600009334E4F3F3FDF8FA07F21FA2F71F1B732C +:10E6100060BF8BE9FD2AF55F9FFF5039B6B7451BF8 +:10E620000DF7797F94C5E59A6D0FA747539E259CFA +:10E630008BF4208528BE40AFD7D8C779D2B42CAE92 +:10E640008F9ACC61BA27D3A4D9438BB31CEBC82FC4 +:10E6500097D57614F9F55C1EA3F3467BF4493A4747 +:10E66000B01558985DD07E0F00E33B0A23841F74D9 +:10E6700036450D741BF3EEBDA977FF755F853CB879 +:10E68000BEC69C108D3FD07A2FD5E0D9A8E9D746D9 +:10E69000BBF11C6DAE86EF2B75B8EC67244FFA8189 +:10E6A0000BD97BD336E75E8FF3B1ED1B108E86FA64 +:10E6B00039AC7C50227E8997FFCE4231EE1D2581F8 +:10E6C000E6756E8FA0BDBBC8DFB1E8B1032216ECC2 +:10E6D000F75F37571CBC1AE6B330E80C60FCE41354 +:10E6E0009BDBE89EFEA217CD149F30BC7316978368 +:10E6F0002DFC7D45FD7DA38B5AAC86F7A696B09880 +:10E70000F71761BC45C73E3AC6E89EB1F1BBFE6E45 +:10E71000C01AFC90204E2DFEDD8175597DBC3B500A +:10E7200098D84F13FFEEC0CE88487A6339C6B1D26D +:10E730003E606B29EE7BAA8E09E437E8CD87CA9646 +:10E740003C734C5EF0133DAAC94981ED09F8E94FCD +:10E750005E4E0FBBF0508DECFEFBD645B330AD6383 +:10E7600078DE547B9724E3B9766D3889EE97D4CA66 +:10E770006218E346BCC9A536F43F329728E33DB49E +:10E78000A9A6C974EFC972B7348EDE696D5BD881F2 +:10E79000F7EA6A3D12433EF6BA781C01CB10E97DD8 +:10E7A0009A3AF975D76CDCC739F93DBD6C99851576 +:10E7B00001EDBA00C3F365D8AC5446C1F4F20A8146 +:10E7C00028BE77C52659E5EDFC9D99EB8B26901F59 +:10E7D00098FE0EB44E8DFE1AC709D8CA10FF53EE2C +:10E7E00076933D18F69818C6011ECFCA21385A9262 +:10E7F0004BA36FE3FC663AC8B71B56C554C4C32B82 +:10E80000ADAB665C05DFCD6189E21D0ABEACBDF92A +:10E810002A68DFDD6AA1FB163A9C943AC9F07E8330 +:10E82000EF3E63DE12F75E85C462CA21FFC72CED9E +:10E830007C9295B3686C1CAF3BC00FDD6527BD5B58 +:10E84000D709FC49E71F5AFE4F5A7E87394478DFC3 +:10E85000F1B640FED583AD73B3495E3A966E73E070 +:10E86000BEF0283FC7EC4B3E3F9AA5E8EF7CD8B5F9 +:10E87000772AECE8F78AA7A7BA6AE6C738435BB8F5 +:10E880003D6914E2F7B0997E3FA05E938F9293CBDF +:10E89000719D6EE2D3FA38FAAB37FB0B4250BFFEE4 +:10E8A0004B93B66F3C797D7432863D28B4AF3667A2 +:10E8B000313FB287D9DD9129C33C46BD68F1E3EF12 +:10E8C000334C7DB67010CAF9512FCF24F9867042AF +:10E8D0007C4955163FDAC9D62AB75F1A87F59C449A +:10E8E00097679D16B287A42A4788ECAFD6091E25E4 +:10E8F000765F512DFB2533FE6E8D8DD2557DC8FB85 +:10E900006C9758867E578B662FBBBC5C9EBABC0E3C +:10E910007EBEA8AD739BA4CE407ADE0674837137A9 +:10E9200007EEE3F4BD3CC3467A73F92BC386F4E7E4 +:10E930001F7CBCDAE3CF03C06EBDAF82FCB625F707 +:10E94000BCD78874B73CD926231D9A52866F9C8CFD +:10E9500074FFAA99EE79D6264F5066C7F4674A9994 +:10E96000E8417898443513E979F8965DD74B939050 +:10E970004ED44D789F7F8CF75FAE9740BEEC4856E3 +:10E9800033F1BC6C82F7619E4F533709507E997703 +:10E990000BCF7BD54C11F253BDAD3C9FAF6EC2FC8B +:10E9A000F5DEED3C3F9AEBA31F789F24795E6BF672 +:10E9B00097A37FFA19987F613EBE93CAD3720D2E3A +:10E9C0007AF973F8DD8CEFAAF234BEFC05ADDDBE3A +:10E9D0003ECA7FA995EFEFA3FF97B476D13EDA1F29 +:10E9E000D4DAB5F7D1FE90D6EE701FE5AF6AE5AF89 +:10E9F000F5D1FFBF6BED3AFA68FFBAD6EE8D3EDA7D +:10EA00001FD1DA1DEDA3FC2DADFC585CFFEF68F5BE +:10EA10003BB5EFBEE486B7D05EF381BC427952903D +:10EA2000DC40FEAEAD55C544FFB5E3B9FED7E9DD28 +:10EA3000A7DD0BE8F0F2B8D20E2FB76F966B745EBD +:10EA4000724FDEFAC94887BFE3F714417F1CC57BCC +:10EA5000B8EA3D22F9F796BFC2DF95597E8F44E7A9 +:10EA60001B3A3DEAEDF5F987B579D669E9422F7F82 +:10EA70002F2347F5F8A7C7E847B36CCCDB809F305E +:10EA8000FEBFCECDF54CC13DA50D786E520B7A067A +:10EA9000D757EFB444D1FF552F4B545EE72E0DE10D +:10EAA00079BF2A4BA487EADDA9517CAFB9AEAED8B5 +:10EAB000F0DE679D2CD1FB31926B8A6DB613E5C6F3 +:10EAC0007419E5671D93534BE85C0DF669A84FAACE +:10EAD0004A65943B392E772ACAE55BB3F9BADA93D3 +:10EAE000BBEC788F42BA5FA4B70286CB12F17B5E93 +:10EAF0009D1856601EEDF272F2BF6E6FD6CE1419DD +:10EB00003F4FD4E5FC8E9F4D253D560B7A4C213D61 +:10EB1000C60615A5F7DCDF948E8DB2A0DE92334DCC +:10EB2000CC0C72F9803795C6DDFE20D75BF9A0B713 +:10EB3000F09DB56DC58CBFF3E6B1915FB742629EA3 +:10EB4000C1317ECC035E6EC733D3743FEEB3F3F1B5 +:10EB50003DC418F80E0B19F556CE007A2BBB0AE40B +:10EB6000654C7DAB4736E49FF26AEFADFA991FED35 +:10EB70009BA9CF6E267D7216F50943FDF2EF49A3DE +:10EB800050BF801EB1B2DE725097C7BADDA2CBE98A +:10EB90005A4D6FD4C6E98D81E5EEDF5F1941F42946 +:10EBA0001ADEA1E94BFE2EC73801A04B735020BDE1 +:10EBB000C2A420DDEF1F086E6673998CF6F840F052 +:10EBC00033A77DEA42396D0E4AFEF712DC931A082C +:10EBD000BE7A3D8B6DE816D46B9F1E5B51807EAF75 +:10EBE00055E68E593B916E854174BF43D1FC0E5B57 +:10EBF000ABF7B113F9F8FB3D7FD95C87BF8FC50236 +:10EC000032F94B324A156C67877DFA60B2E3F87EC1 +:10EC100093C9C1D042B4E75FB428782E70F819EDDB +:10EC2000FD06AF93E079E7EEBBA89D59A8F4F0F399 +:10EC30007E46F05E9D994A76B9B2C3A6D98D1FAFC4 +:10EC40000FE441BF62A780FAE7F7D95BD7DB501F1B +:10EC500069FB0198D9F770FF13095BB4FA78D19D6D +:10EC6000B1DDF8E334DCFF1C903CB176A8E97B53BE +:10EC7000B2F03C541E25417FEEAD96F5662F968B83 +:10EC80007AFB005E1E42F1A5E725C0C3D3ED5AB959 +:10EC9000EA5E3F05E6B3DBA28F0F06F5441C4FD4B6 +:10ECA000E829793DF6BFAB546F7F7A3DFE3E17CC25 +:10ECB000E75A13ECC1727D9EF5CE8C9EF97AB37D36 +:10ECC000EB6BA0BFD34A670A6EE396B4BE978E7A09 +:10ECD0007B7539BF3F8C0C80FE11FD1EF105BCED2C +:10ECE000B9414557ECDF0EFD674A21142D33751EDF +:10ECF0007200DC96ECABB499457CBFAB4CC5F7BB5E +:10ED0000F4764BF6CC223B67D9FE224A13B43B8CF7 +:10ED1000F767FE817636CBD718EF74F4F5A53B156F +:10ED2000BC3753D9E034517DC6FD5F89D7A7B73FC3 +:10ED3000BDF3F51FE0786794CEF46BA0F6EA28C027 +:10ED400025413BBDBE7EBFBAD81328F2C1F74F3173 +:10ED5000600CE59654E9C7FA115B88EEB1D9CDA1F4 +:10ED600032D42700FA30C629E869B12F8F9FA3C497 +:10ED70007D8FE7AF888D0D9E8EF2F22E89CEDD233A +:10ED800036D53106F2CDB04FA98129AD2C3A3216D5 +:10ED9000E3059AF73A49AED7DED5EE2944BEF25BD9 +:10EDA00018DABDCD977664E03BF875775BCA1F43F0 +:10EDB000FA8D2EF7DC1E638779B3791CB7D7152A35 +:10EDC000477EB4033FA23E6E34076DF86E8A9A21E7 +:10EDD000525CB51DCA5FA372AF56EE9F7615EDCBA0 +:10EDE0004419E7559F37675A29EA354F2AFF1DC254 +:10EDF000FC29E5F3A03C2C5B6424AF45D9153723EF +:10EE00009C9E96FC95C87F4F3B9D32C66381AC2487 +:10EE10007D20E5BB293ECBAADD77F216713D7F410F +:10EE2000FFF9B81EABF3F138FCE6E48E1B4AA05D97 +:10EE3000D2BDA2AC42FF8D773F5486F1895BEE3E96 +:10EE4000F2078C6F6D4A97E89D815D35D100D6EB56 +:10EE50001658471BFE2E52D58C0EDC8FAE658A826B +:10EE6000F6FA2E614608F573779AC4DAA07E529EB0 +:10EE7000315ED559688C97CA5A6CCC376607EFF665 +:10EE8000513C5071098E9326280A3E1D5CDCC12836 +:10EE90003E3F3D2F4FC6B8EE94E2B838D8C9C67E83 +:10EEA00052A718CBDDD3E3E2B66E32967B6E31E625 +:10EEB00033E718F3EFEBF4E8E1E70FFAEF3D6CB955 +:10EEC000FB71867ABAF18B4114CF8A7044BB3D69DD +:10EED000B8E4C77311AFA56326C6C1B19149642FC9 +:10EEE0001DF4253105F2D6A58CE4A935357200F75D +:10EEF000AB56512E534943450EBCEDC6DFEB32D124 +:10EF0000B96C3CFCBC5EEE1F7456F2DF858B485139 +:10EF1000B223ECF70C926BFCB8758CF3C32E8EC940 +:10EF2000F378EF2D3EED1CC5A3C7A9115E6165887E +:10EF3000B7498C7E3FD27BF77B6A14E6B156C9ABEA +:10EF4000443B63B5D849E3A815CE20EEBBD330CE01 +:10EF5000DB84F1DE2AA5F1F8D8A9D197C2E68410A6 +:10EF60008F9E5922C58FD41F4AAAC3C3977AEDBD7D +:10EF7000063D8E4DA7CBBD3E6E7FEE6E17C500FAE7 +:10EF8000C16FC96B437CEBF996A0BB95E2FA8B2A63 +:10EF90003B912ED975DC0E053D40F7B2F538313D79 +:10EFA000AEB0339BD3F707D9A2210E9CE28862E270 +:10EFB000C0E9E8CE8447172119CF7BBC456532CA2A +:10EFC000999FEBF72F18EF179F2FA47383E962E047 +:10EFD00022CD9F8E76DD606DBCC16E2940EFBBC334 +:10EFE0009C44A8FF20E3F507E7ED5981F7AE7623AF +:10EFF000E120FFDCCEE11C4FB719EDA1B2D1082F03 +:10F0000001F461566F3A167C2D741E587F2F4BB554 +:10F0100016F5A6EBF1266EFF742F5028CE72203A1B +:10F020003FE173713F76DA2619EDDBCCBC076BE864 +:10F030001ECCBD4C467D97D9DE7103FABDE2F921A5 +:10F04000EC4819CBE3E4BE991FDE64E2FCC18648BC +:10F0500084B7F8F8D2F878526FB64B3B87023D90F0 +:10F060008CF701E42B304EB0FB1E46EF0494BED863 +:10F070007CF3BF417F9FE55B6494D7D96F049F7099 +:10F08000C0BC3EFB45301BE5F456A9D3EE8AF17BAC +:10F090004A22BF7FD64B5E6BF4A1A0DEF0FCE3A951 +:10F0A00017E91B882B92973E4A467FD5B675BFB7A6 +:10F0B000A5FD1FDA2DAA3984768BAF5DCF67901D31 +:10F0C00096FD06CF8FDD9AB15E95106E8BC95F7489 +:10F0D000D03B97FC45D25BDC5F34DA1408639EFDBD +:10F0E000C54E71773BF6DE321FE3D5EAD3AFA1DF21 +:10F0F0003D1993CDF79D85D93A7F1BD72F590241F2 +:10F10000E49BF8EFC3B3F5F3C4B20F6701FE463FCB +:10F110006AA1B8BB02B1A22107F9A1D144F8AC3071 +:10F12000294BD7C4ECD3EAD34B2667A7D1BE8005C1 +:10F1300061C3A09C17581098CDE73E5E82F49A0DEB +:10F140006C86F2255BE506647655120BC6D0A97273 +:10F150005EA2FAF5E981C9D99ADCC3731FB3C6D29E +:10F160004FA796B159A897E11BEA5DF3CE247EDE46 +:10F17000E336DE8F349978BCC8D5DABACD78AE33B1 +:10F1800016DF7B13A3D631BDEB5FAFC149B239A304 +:10F19000A641E8277BED28DDBB8C3B07C6FD2DC5CE +:10F1A000E52C66E40745B850FE4E99BFDB5DC5E32C +:10F1B000016AEF63029E05D46AF754D45BF9EF0E3F +:10F1C000B34040C1F755688BA9E0FFA2C4BF1E1B26 +:10F1D0004BC5FA19AC83E218593B5378BC84F1DC77 +:10F1E000696B1FEF40E97E00A9CA44FB94512FDBF5 +:10F1F000F9EF4355317A279CDE6CC2FDEF7D2C2C54 +:10F20000093D7EB80EAF42EDF4F3D85D5FBE43BF5B +:10F21000C75C20B6055F23BB21596E43FD9864E4AB +:10F2200043FDFEDAFD1A1FE2EF490763CE8F7CEA49 +:10F23000718AB7CF66DD35B8CFCAAE4A35E0F982FC +:10F240005FF6FC50161C17DB6F98F3759E44EF7445 +:10F2500029E77D54BEB55A19A0FFDC3EFACF207ACB +:10F26000EABBFF2C2ADF16FDD4753D80626BF77B6D +:10F27000AE32A5C76E8D87B3EF3EA3FCFECEBEF8BF +:10F2800078720E17BB39E0BE01E066BF5FF4B7329B +:10F29000FCDD1B63BD6939E75CFCBC5CAF1F75DF3F +:10F2A00088F561DFDBAAE0EFE818EB9795BCEFE2A9 +:10F2B000E7EE7A7D3EBFCBCF1BEBC5E3277EBE30AA +:10F2C000AFB4EFC7CCEB0A9BD5505E3EABD7BCD2F8 +:10F2D0007E1833AFAB3CC6FAC19AC4F3BAB6C0DAF3 +:10F2E000EFBCF47ADF9BF8F5EAC5AFE3C669D63E1A +:10F2F000E0CEEBFFB0FCEBF5FBA3F9FDD7BBAD2AED +:10F300007E1C95E409C8CD0E944F154C5985EF84A9 +:10F31000336752C2B8E0C91A7F9C423F059E930EE4 +:10F320000DBC89F2F1A497C7FD1E7E666108CF610E +:10F3300096EFB52878DEE1D5FCD620781621FFEED1 +:10F34000B6C92E8C07147D8A763FAA2307E3F97687 +:10F35000EF387233C93D66B46760BF5682FA1A440B +:10F3600018DDCB780DDBA5C5C65104C8FEAB17FD73 +:10F370007FA47DD50FF8BE4A8FDF8FB5B3D8841E2A +:10F380003B4B8FDFDEA08D733E9BFB03C1CE570549 +:10F39000B2F3258A6FFEB9AD6303DE3FFAB9DBED48 +:10F3A000C2FDCC416DDEBADDA8DF6B18322BAFC8D1 +:10F3B00094005E17F44852CF7D098CA374E5E5D123 +:10F3C000BB1868E78D2DC47E395CFF07CA89A75634 +:10F3D00000800000000000001F8B080000000000FB +:10F3E000000BDD7D0B7C14D5B9F8999DD957B2BBC4 +:10F3F000990D4B1E3CC26EDE8100130831A095258D +:10F40000448C96D20D3E0ADAE292F094BC00ADF143 +:10F41000CAAD13121110356A44A0800B8A62AF681E +:10F42000E8450D08DE1035B5B7D886B6B6D67AF9F8 +:10F43000AFC0452A086B1FEAFD17CBFFFBBE339315 +:10F44000EC4E7655AAB7F7FEFEF187B367CECC79BE +:10F450007CE77B7FDF3973AF893156CA989A2F8555 +:10F460007609F05B666C4D19636EF8C9B2197B447E +:10F47000EE734B50FF88479255A8EFC9F232368998 +:10F48000B1BDAF994C7E0F638F7D3777A7E81B28FE +:10F490006F0A7A766079A489053B1DD888BC8CC137 +:10F4A000FDBD36D9BDBE048A529FAFDA09E5DDBF86 +:10F4B000B949703196398A517BB5CDD3D989898CB8 +:10F4C000BD6889BC7A11C7B35108ED82765EEA281F +:10F4D0009921C1FB0B4F336687476BEFBCEE9193CD +:10F4E00043189B7C529E86F76BB7BA1511EE37F422 +:10F4F00035CDC07E581353F214C6D2C569A213DAB3 +:10F5000049BFEFA8D20A437EB4C7DB158672648771 +:10F51000A0ECF462FDF292E5C5F0BCC3EF75C07CCF +:10F52000E7E350E9BE7B8619DFBBCEA2B4413B675F +:10F53000CD6C4E273C7711FFA60E5CE77FD75BCEE4 +:10F5400060FCF33BEF9C4FFDCA00B24C28DB641A11 +:10F5500087CD2BA7B640393D89D9EC13182B5B2DED +:10F56000F7DE85FD2F75CA3B01C6AE72B9F7873845 +:10F57000AFA62C5954B0F310C1416F7FA13F606119 +:10F58000D0EF98DD16688CD1DF45F837B633B63C3E +:10F59000BE2BB65CD21D5B9EF8466CF97998231B96 +:10F5A000CAD814DBF06D2701DE3D87AC0CC7BBEC7D +:10F5B0004C52C80AF03E60660CE7AFEEB1123E4C0A +:10F5C0005FE6F0237E9CF920698715CA87DF49A290 +:10F5D000E76FFD173B7FDED4F91C96D5E792193E05 +:10F5E000BF6C4867592A8CFBE5CFC45B02C57C5AC7 +:10F5F000666CFFB9A21DEBB17E6267990CF75F1CC8 +:10F60000CD581FD64BA17138CF17FF2652BB91673B +:10F61000ACA19DD0EE99FD4F3F87F03AF3CCF0546A +:10F6200001C67CB969E7C4F558DFE2F4EE84FB5308 +:10F63000CE3C9B138C5A9765BBAD31F35CE61568E5 +:10F640009ECD927FF513B83E47CC844F2B17866A28 +:10F65000BBE1FD954296A2623B16C0D3622C2BE91A +:10F660006EC0D7292E8EB72BED508EB3EEFAB5664D +:10F6700093C8821307CAC7D73D4DE3293CFD36E145 +:10F68000F501B36A4A4238AE13945D30FE0376D773 +:10F69000389682D7AC10E2CD3F794D343E98D70FE3 +:10F6A0001B102FDE14959D2C717F8519BFDF5A39F1 +:10F6B000F173EAA15FDF38C6CEFF21E9163F8CA3C4 +:10F6C0006053ECBA178562CBAB113E806F352CEAE4 +:10F6D000BE0FC793BD2683E884D1780A4FBF7B93C2 +:10F6E0000FC63BCCCA9A102EC67EEFC379403B3F73 +:10F6F000FA11B45348CD881745DE9E370DD641A385 +:10F70000AB97054E47F077DB70A0B76502E72FFA9D +:10F71000FD658671E8ED976A70F2589407C3B4FEF0 +:10F720005619D7FF83BBAB1E39691E3C9E5377FB2E +:10F73000FD9551F7176D5ADE9B09EFD5ED1D3A4146 +:10F740008C826FDD33AFA6DD0CF7CFEE96146481AB +:10F7500075739F7A600A3EF78CD889E3C57A3FCCEF +:10F76000F76CE7EB2E7C6ED156F704D13BF0FEE24E +:10F770004D57F92B0B07E079A974FA5239E773CB8F +:10F780003ACD211BD245E75B3386239E6E12943C13 +:10F79000E8A74C0A8A4877CE52BF599DCCD8D40BE3 +:10F7A000FFD63B0CEA1B0F4D2A5B0FF5EB4D81EBAF +:10F7B000BE8574B75D5476C16B2FFC7A455A306AAA +:10F7C0007D7A34FC5F7F631DB5A3026EE40153EFC5 +:10F7D00029AC998EE529C54CB0023F769D66FE9016 +:10F7E00003FB636F9B52193B7DF09E719289F8D1A8 +:10F7F000CD482767984B41BA3BE06CFA15F5B7C77F +:10F800004CFD4DED4E1190FF1E785250D63384477B +:10F810002CFD9D3EBDDA358DD3F52D01920326E6F4 +:10F8200081F6963C3196F8807EDFB87E4B43063AEF +:10F8300036E0C5096D5E889AD1F8657C6EC84CD5F6 +:10F8400082F458D70CF2228A6EEA4EB65B98637047 +:10F850003F8CF5E32F43FC05BC645E9AAF9DF80630 +:10F86000FC0936C0DB0FF0570E2F33E8FF5681A698 +:10F87000C6968DEECC473E274872455BE6007F6515 +:10F88000E521E2F367E1E77A05F942E731A47794ED +:10F89000A5BB50BEC8DDE7B660BD3ACA8FFC68188C +:10F8A00022295CD9F3C9C47FCF7AC34FD1FBCF8E55 +:10F8B0005554B87D1EE9C541EFB952A3F8534BE743 +:10F8C000ABAE3094CFEC1D5221BA106F7FE6C279F7 +:10F8D0007ED039A4C2E24ACC378C7C134646F07DF8 +:10F8E0000F7F02DE25F9FC661FC2BB0D842ECAB352 +:10F8F000214D254D71D64D7FCF63692AF122FFF846 +:10F900009E43413E9E6AAB7D1CE535FEF9E1FE1F3C +:10F91000DF18B213D7FF614DAECE17783F7A3B4365 +:10F920007D9C9FBC71383F250CFDFC917953505E46 +:10F93000ECC90964F8E07E46459F5F0478645CCBBF +:10F94000945678F584A87C5F86F558C0405EE2B591 +:10F95000346841BEC2DA86D278195366203C17CF8C +:10F9600004F897F032CAB7A5018BB21EE470ADC49B +:10F97000E15DBB5B08B5C258166C8885C7A20EEB6B +:10F98000005EE0FFB646D5433F4BA5D01A945B23FB +:10F9900040F318520EF8F064ECF3CB58378DABEE11 +:10F9A000D98BD67870FE8B06E73D39FE09383F616A +:10F9B000B68DC6B3728F40F2D563E9247D22B21CA6 +:10F9C000F8318C97FD9AAFC34D9ABED478E77CFF8F +:10F9D00002B89E6FAEF52F802A2235E4231D2984BC +:10F9E0003FCB2A3B7B89AF30F9C73767607BCC2F91 +:10F9F0006379A393EB7BECC95791AFFC85C99D88D4 +:10FA000087539608F4FE945F8B3B01C3D94DFDEB01 +:10FA1000172038D679998C707CC71CA079AB4B998C +:10FA2000BC0BF84A9D2DA0EB5FF2D5309F45AC8909 +:10FA3000E65DEDCBA6792E61ED54AE67610B1371D7 +:10FA40007DCB52105FFFC4145A5FD093983D753040 +:10FA50005E21FCFD51705BB235B6CC9E8C2A6723CB +:10FA60009CA11C05FF867D17ADFE38707FB45F1E1C +:10FA7000858AAAC746E3710BE1DF316D5D1EBD616A +:10FA80005126F2910751211EA635508EFC177E4D4E +:10FA9000A172B70DDA4F9AD85FA6FAB2D5BCDCB026 +:10FAA000E3C5C0A62B00DCE660A60C8B532B067AC0 +:10FAB0004D00D739B9C1154857B5267F9644FCC4C7 +:10FAC0009F1F8071B066BEBE8F4D682A6A8AA37F71 +:10FAD000E8E3DF2874769B908FECE7FA85B3346215 +:10FAE0008EE6FF1B7C5CBEA7F48469FD232F080C07 +:10FAF000F5DECDC24399B88E9B33BD422BCCA974A1 +:10FB00005FCB34E237C08BF2605DEBF7BDD73B1CB7 +:10FB1000CAA5557DB84C30EFC0F2D7919E2725710C +:10FB2000BD39B9698709DA4BBFA570422BE0E743BD +:10FB30003E2FF59334B1FD30B61359EE9577423B25 +:10FB400019AB55DF8A62ECBFA985F0B79AD1FDA148 +:10FB5000DF59D582CFDD378CA58AF81C6B11F0B93F +:10FB60003543055A8F35F3D99C1FC3556232E99D41 +:10FB700023E6C842CB642C374D23FCF2CAEE9F65C6 +:10FB80006299B5A5805EFDA88B919E39D424DE5282 +:10FB90000DD74727F072EA2AC1BF9388E121825727 +:10FBA000BA955509A9FC7EA89848D8BF97EA43346E +:10FBB000FEF4E94D25388EF41C7EF55882A65CE8EB +:10FBC000FFC851736835CCF388862FB7EDA8488FEE +:10FBD000E6BB47CEDA2413E8754732747DB6DB8185 +:10FBE000FAEC6D25D3D39118B373AB52705D3D59C8 +:10FBF000B1F5E7CDFE9489483F474586EBF7678727 +:10FC00003F05F5CFCB2D7CFCC6753FACAD67E3A7B8 +:10FC1000020B45C9B3C6391F939DD0F8A91473FFD1 +:10FC2000ECDD368622AE5FEE2DE99981CFD5B3BEED +:10FC3000358887F59DC92C1445179727C5EF57A719 +:10FC400087C64F45A6C6EDD7127BFFD3214C1D12A8 +:10FC5000EFB9B4D8FB308F9872D727FDF3C0FBAC57 +:10FC60003CEC0A809D3813E52894CF874CAA793C58 +:10FC7000AAF15CFE9D93C32ED4CF415E36E1BA9CBF +:10FC8000F386491E9E67AC0AEB2F37996EA9C6F51D +:10FC90009522AED9CE817EF47A7C3F7A1DCFCDB14C +:10FCA000B06E5A9F088D03E1A71630B6E5E04716FF +:10FCB0002FEA11070F13FC747C8986A31AC56FD233 +:10FCC0005AFBBA4D4057177C9FB51783C13AB447CA +:10FCD000E70B17DBFD2024D244530C9F482EEDE7A1 +:10FCE0001BC4A61E35893A9F79A872444C999E1F61 +:10FCF000785FA8AE04BE525ACCDFB7649B8EAE4686 +:10FD000059C6DA697C308F2C845F7FD966283BA086 +:10FD10003C36AA2C1BEA3D86FA0C4379047FFEACE4 +:10FD2000B33B0BED5777B6A55A023A3D9BD93D4FF1 +:10FD300080F286565B752594EB4BB9BC6E3828284B +:10FD4000246E34F835285CEF7428614B6D31C2A104 +:10FD5000AF17F94A5D97200B400F8ECEBDDD54C61C +:10FD6000F7BC51EF750AF45E5DE77BF45EC2F60BFB +:10FD70004D44E7EB0B8FF3E73ADF27BDE0DEB6E556 +:10FD800001646CBD662FF105B0E2FCC3E1C586AE2F +:10FD90006A16740CF0D77399FE5789BF1E1264A4BB +:10FDA000CF7E3CC5761D0374A13FFFFBB107DF4248 +:10FDB000B523F9B68F5A2478FE3FEADF9F847AE1B3 +:10FDC000EF3539B251081561BF5B58B008E5E0F76F +:10FDD000EAF30E9BE0B963E6F036E4BDD5D959D518 +:10FDE00012F0B563CEF04801E4FC75D945BC3C3453 +:10FDF000BC0DE1F92FD9A309BEC74686479AA0FCDE +:10FE00009D9D37F0725E781B96D59D7EFEFCD8F0E6 +:10FE10004811DECF51A755574279971C9FAEAFCE00 +:10FE2000E67AB43EBEDF4FF45764A39E57C7E5CFD2 +:10FE3000BC5BDF998BFC769E89C90CF8F4AEB327C6 +:10FE4000F6EC0278EC6A4E663B393A0624D087D34A +:10FE500039EA839C6827BE1EF1019F27E7515F584E +:10FE60008072F2249B77BD6F605DF4FED34737ED5F +:10FE7000C5F6D3E715931C117DFE67B17FFDFA76B9 +:10FE8000115CE1F967B365CEBF45939F9EBFCB1967 +:10FE9000C2E71FB4F37901FDD03A3BB475F95E3681 +:10FEA000E793DFCBE67AA4E2BB8ADABB49D7C7D7B0 +:10FEB000760E1D0DE3EA105827DA35EF98996A2778 +:10FEC0003D2689F4A10E1C3BD63F941952A19F9B5D +:10FED000051640FEA2F3930EB73F3335CAAEE928AC +:10FEE00081B263C08EEDA8F6672679F09A66421D4E +:10FEF0005FE74F1D3EFE9E2E9FD25B793FE90F16B6 +:10FF0000EDC4F9244B8CE4DDC239F93B5B483F98E2 +:10FF10004DF3677E7FA600ED9D5C9A6D4238EAEB5B +:10FF20007561A2BF99E62572BB5C5F371DBECF66C7 +:10FF300073BBB95604FD02F04EC90D527BA06F8C05 +:10FF400023C1AEE91BCF22D246C19949E14978FFCE +:10FF5000FF43786DC7FAAF0AAFFA66E023A62FC158 +:10FF60004734386E14BACDE99C8F90DD8CF7511E62 +:10FF7000DDE10BFE383B8A1EE6DD554F7AA63EAE2C +:10FF8000E43B5EAAFA0E433AFC80E86EDE3F25931E +:10FF90009D6BD40375FB4AD7571F4EE0AFECD6E6F6 +:10FFA000A7E87E596D1CC9C5E13DF703BC529953C2 +:10FFB000463E7ACC121EABC0FBC74CC1275EC27155 +:10FFC0000F1365E02183DA6BCE11A93DBB8E272C80 +:10FFD000E21AED19C093758027367CBFDA42F673BA +:10FFE000873BB47911E2C90D2314D54B7298E859B7 +:10FFF0006D4EA6FACB4DC719FA9923936519F54CA6 +:020000023000CC +:10000000C02BAAEF989B1F52B9BF40B593FF34296C +:10001000B413F1AE040080EDCD1D4DF568AF939F94 +:1000200063AE8DF73718AFB85D5DC078BD4FC3DBE9 +:10003000A5D984B769AD8CFB2924FFB8EA287D6176 +:100040004C0EE723C9A5E1177E8BFAE706BB92C7E2 +:10005000B80988FE0FD69E4EED01BE7C48F8C73821 +:100060005E2E78C0B983F33DA50CE17CAFB39DDD76 +:1000700049FE2B338D7FABBD9BF47093CDEB463F98 +:10008000F13C916DCCC7F65ACD32E28911DE2939A7 +:100090009CAF0DF667866F8FF667CEB3AAD62CACF1 +:1000A000BFDB4E7681EED79C97C2E94AF76B227D83 +:1000B000C6930BBA5FF3160DAF06D5AFFFAFBC1AF0 +:1000C00068EFFF6878A6F47C9A37DFC1E78DFE9170 +:1000D0001AFC05FDD6ACB2BF877ED01AD5DC6D7593 +:1000E000211FB9CA1F8EB2D3D8263E8FE09BE610DF +:1000F000C2A959621B9FC2F551F9FC572E0C2D8DD8 +:100100009ED7160B9F97FA4FCE98796D71B1255FE8 +:10011000CFBCFE3029765EA72769F362B634784FEC +:100120009373B7343BDF13C6C115E70557B60AE62C +:10013000553830AFABD1961B4AEBD9148F0EAF4E6A +:10014000B88EFF4BE6DBFE983FDE7C8DF3DC93E35D +:10015000AFCA994474D32D970EE0757033CCAB14AD +:10016000D77568A885D695E327632E05F9D8CA8583 +:10017000302FBCB6A4933F6B9ED5DB857E5DF6C366 +:10018000146D9E8CF8C0CACD23892E016F39DD3ED7 +:10019000C6E3412BEDDCCFB072B9ACA832CEFFC7BD +:1001A00064074780BF925ED21CCBD7BF180EF6AC57 +:1001B0009AE26838D8B2E617C75977D54AF89C68EA +:1001C000DDFF8F18B95DC849EC6763AB62FD14E8C9 +:1001D0006FEC2F8B83CB46BF07637FB3C63EAF2642 +:1001E000886F84BF178D47C7CC1A1EDD6927F9A316 +:1001F000E3D131279FAF118F1868D148C7FABC8D62 +:10020000709C87708C1387007CCA43381ED3EC33F4 +:10021000C0A73C84A34E07B734737E6084DB338968 +:10022000F9DA579B87018FBFEA3CF4FA44F3D0F523 +:10023000DB4DC2F2CD889F9B3299DC4A7A70782CD4 +:10024000DA491E4BA808C7B5C502F40BEDD668FD08 +:10025000932703E6F7A723DC2F7A5CEBD738AEAE03 +:100260001CDD2F1AEB376B7445B6A31ED298C4E57C +:10027000E1B9434EA21B961B9E87FAF7F9035686F7 +:10028000FCB54108E7E373E704FF7C7AAE25D98B20 +:100290007251F7379E7891FB1B5506F62FFAF982BB +:1002A000DC5FDAA8FE6C0DAEC3C51CA909EDCFC694 +:1002B000AE58FF1ACCCF85F33D67627DF87C83187A +:1002C0005A8A26EB460BD707369A5827AEDF805D51 +:1002D0007E3C9FEC844C99A13FA8C1F45EFE8A2825 +:1002E0003BBE41AB6FC8E2FE298C47939F1DBBF21A +:1002F0000D864BC386339F613CAD619F915E62E981 +:10030000A96EA02C5C14B0BDA87ADF003D913D8E93 +:100310007858C9427902FAD57839B9AA2F8471ED93 +:1003200046CDEF3AB4273C03F505676927433EDA2B +:10033000789ADB21530EEE7815FD6DEEAABE91A8DA +:1003400092346AF107A3FD33F9E04322FA8774FB84 +:1003500025CA1F55343BC61FB99ADE43FF16F61750 +:10036000C65BE8D796B89EBB51D373411F26BEB972 +:10037000B0BD80F461D45751EFD0FD63A887A03E93 +:100380003A27B7C2920BF3FC6B6E85903B89F74717 +:10039000763F3A5D267F0EFFD2E0A33F877EB2CF45 +:1003A0008F03707D6A8AC1FFBFE2A74309CF0F2484 +:1003B000D05387E6F6FBFFD3D1FFBF42F0A6239EC2 +:1003C0009F1283E4E75FCC54F21F2F45BF3AF1C17F +:1003D0006EF24BDFDAC494F514470FAEC172FD1212 +:1003E00026AF47BF746590EAD12FFDCDC93C4EE5DD +:1003F0008DC25F8C034597D96E28C7F0E93EF27332 +:1004000037400B5B14F423C43EDFC842D325C48BB2 +:10041000AE8BD698763A389C6ED1F065B39DFBB71B +:10042000A7ACDA21B2283F43CA04BFEF1EA4879FBE +:100430009AC9BFFA9FDAFAEAF0D89353918CEB95F8 +:10044000847E1F7CEE1E2BC9D99326B604F1E541AC +:1004500037BB6536FAB3EE66FE5C33E2859C15ED7C +:10046000EFD2AFEB0FD897209E4DCBE576807E3F45 +:100470009263A632F9AB493F4DA6F83BB0A571880F +:100480008765D9BA5ECCC6A19FFC3D8D3F35DCE8BF +:1004900008627B6113E767B372B93F6156AE85D6D8 +:1004A0004F2FF7FB8B343C837EA8BDA4892C26FEFE +:1004B0007743FFF30F697628A3F96E5C9AC4F5E8D9 +:1004C0007E7C37113F4B2E0E5882C44F2A889F45A1 +:1004D000FEE0F0225CAACED42DC579FC714E12C389 +:1004E0007C85055A7CA929D74DEDEAF1A438FAD7C5 +:1004F000CDDD9E0179A3E3A72E670E38F9BC2F3519 +:100500002FC078AD5A5F44FC5B1FC714835E92888E +:100510002E9AB57533C6C500AEC9C8670F98B8DD49 +:100520007500108BFC569D5ADC12EC64940307F6A0 +:1005300015909E3D5FF3A7829C24FB2A02F282AFB6 +:100540007770F3427CAE338FE2B9EF9943CF3C85AD +:10055000F2F610B723F4F53870607808E977CA9995 +:100560000B5908FF03A77F341CE3E407B4B8649D6C +:10057000A53B9FEC7D0BD753EB5CDDF908BF9735AE +:10058000BCA94B8232DC1F3934F830F21F3DAF007A +:10059000DF73D37CBC2EF4379CD0ECC8E36057E209 +:1005A000B8805AFA305E0AEB9D89E5C8BA74AEEF9E +:1005B000C1B8102F4E1C1A4BF3DB68E678ACEE176F +:1005C000C83F71DC1C39D50CCF1FCF9CC85A64942E +:1005D000779F3ED58BED6F179955C6BC8D4F3EEE7C +:1005E00082E7CF839D8B7EB35A53604626F28B17EA +:1005F000B9BD6E5C07947FD171BC732C92457EBDF2 +:1006000025D99D883FE70E16513E12F3C84C8572DE +:10061000E37E6EDF18E3CB27CDB1F86F6C17E7856B +:10062000FEB546FC8DF23DFAFD38ED7D51F99C3961 +:100630009C7F27C063AA37D8931B65A736BE924913 +:10064000FCF8C4FD9FD07AB2761E373D69F6CFC361 +:10065000F1B92BBB2D3551F8F83B8D3FD75AB9BCBA +:1006600006FE6B89E6377A7D59058B1BDF7F5BA31E +:1006700073671F977B83EB399EDFCE9E10915FFCE3 +:100680002ED74BED8DD2F2146E677F3A6C45FDA4E8 +:10069000B384F22046ADEA263E00E325FC3CB9399E +:1006A00085F823DBC0F175D10FADC43F1681FCE0A6 +:1006B000F636CFCB621B78FEC5A97B7C84CF65ABB9 +:1006C000BBCB881EDC4C41BDE4A5B6F75411EAE76C +:1006D000EF164A30EF6C7E9B8FEC945BF7F9687DE8 +:1006E000A7687CBDD6EAA73C33F6388FC32D78784F +:1006F00029F5539FCCDC22E97F210BCAE525BB05F8 +:10070000867435A593F3FF3AA9FB30EA91C6BC097C +:10071000168A8D2FA33C62517A26CA1F66B00B62DF +:10072000D75DBD24F96B9437E6BCF8F217EC3D4B6E +:100730001E5F572E27F60A9C6F68F2B71EE52FEA58 +:100740006A9ADCD3E5E6624D6E9E12B9DC5E647D8A +:1007500088AEC3F37C34CE5B311E4CF1CF8805F5F7 +:10076000934478315C1B978E1723304966E8005E0E +:10077000D49DEEEEB5929DA9BC8871EEBA55ACDB66 +:100780000976DA22A989E4C33099C9948F373D48A4 +:10079000E34A5F09FA39ACF3228CDD4EB874BD60D0 +:1007A000901E6090FFFAB8753C31EA7F535685443D +:1007B0008A33E533BAAF5F65D65982E3ADB671FDD2 +:1007C000BBDAE6E816D1DEAC349F8DB637AA257FBA +:1007D000791EC9CB11EE53638845306C57F1F9ABE4 +:1007E000464F1AD02B934B236BEE87F6CC6C9C09AB +:1007F000F9A4DEBFE89BB6B818E37A521FD92B2CB8 +:1008000083C9BBA0BFEB8B395C93611D76005CCDC7 +:10081000924AF033DB64778B1BD7BF8FE23291A112 +:100820008CFC74FA7A6D733215F31CAF2FE6F47DED +:100830007D31F727C3FB14FF3517C2FBD07EC501FE +:100840003BD1E5C7FB9D2194CF207746B9A13EED72 +:10085000F760A740F9DC0127E929E73479E1D1FD08 +:10086000B56C0DB5779386372AAB188EF60813AEA4 +:100870001D0E6367BA9E5CEF4E14C7D4EA7D7D37C8 +:1008800072FCB592BEF0B13BFC7D2CC37828276783 +:10089000B686578DFBA697DC85FC3BE05038D483A9 +:1008A00025A8FF58C5DB6EB401B06788AB2277225C +:1008B000DE8F74C85678A572D4BBBF990BE53FECA8 +:1008C00033332BE2CFAEEB52BAF135C99F11183B4F +:1008D000783C4B43E6E3E1283A5EB63BB65CDF1971 +:1008E0005B6E64D2F17014FF6F7E77E92F5E8BC26E +:1008F000B7BBF29C9E53C90C7D6FCA45A0A79377E6 +:1009000077B113280BC5EFA6207F5C00E41F4FAF23 +:10091000F8E4EE25BF780D9E932C15AD1C9FBC16F8 +:10092000A4AF1AD01BE2D9A125797C7DADD6A6D380 +:100930003B003ED697AD4A0BBC352B2FB801DF6F7D +:1009400030457A715DADA3CE8E437F76C5A80B94FA +:100950004FF0F13F3305E1F4B17D1AE1D3C79BEDD0 +:100960005EB4533BB21CDC0FFB8A1012B8DD326B55 +:10097000521AE68BD05C808F45D66C463E3DD92A14 +:10098000AF9669BA3613AD37586F70EDB0A86BD01B +:10099000AFDA0106648B82765E9F0B89E197B88E91 +:1009A00088DFE2B3161BFCF4B5F98B5AE0B9658118 +:1009B0002486797CD2675200F1EC5E6C2ACAEED9AB +:1009C0009DC7E54FBD2D6C9906CF355EB8AD6AA8C1 +:1009D00069C0CF6F3507FDC361DCE6AE92EEE17012 +:1009E0006B71F374B2EF80DF72BE7888F3C5C577A0 +:1009F0004EA3FBC2EC2A9AEF29982FC2E5D5CD561B +:100A00009AEFA9910EB2B74F6D13A8BC58B6501EFD +:100A100020E82743A679F0BE59B6B2C1F068DC746D +:100A2000EF9ACD50FFF34C910980FFEF6FFD09C5A0 +:100A300023DE67BC7F759F487ACFFB72A4AC1BE1B5 +:100A4000E96D7245DB938BB78901E4978BB7DDFEC7 +:100A5000F3C908B7D93795223CA6BA6F4BF33A06CB +:100A6000EA757D4F4A2D7F0AE972EA67D3FBA6A299 +:100A7000DEB50DE806C62D995810ED8FD7B65D4D41 +:100A8000FAF6E2EA2437CECFBB75D70C946FEF5756 +:100A90000F33D1BCF6084C4678B89BD3F0FE6241C8 +:100AA0000AC4C3AB45793C9E306D9443417FC3E299 +:100AB000B744C217A0B31B318E50BFCD4CFAFC6BAC +:100AC000B3DFF9CD5CCF009D09B337CD9A82CF3F1C +:100AD0006DA6E7FBF5A9AD1FBE8B7E01FC03C98E99 +:100AE0007288E067A43BEBA855F9382E23FD2D5EF4 +:100AF000DD94CFE3FB9746876C2BD021F0E3B34026 +:100B000027174D7F171DFEF952E8908D488D91DF14 +:100B100083F99E4ACFE9F1519BC2FCBB1C940FE3C1 +:100B200017805F8FCC97884E46E65BE839E9BF5661 +:100B3000EC7E13E0F4785ED0928F7A17F397A07C66 +:100B4000F646E40A74C53A34BD916DE5F9E1685F93 +:100B5000E0FA6F1CCA9E5A1FE59FC9CCD7ECC0BCF7 +:100B6000600AB673EE77177A71BD1AB2CE8E43BDA6 +:100B7000BAF1D33F535E85E320CFC7712811CA5322 +:100B8000327B02848F3ADF6F54B81C32CEAB2D9F7C +:100B9000DBAD8D9E08B5B3BF80D3BB1E8FDCD29C6E +:100BA0004471A12D9E909DFB5940DF83F667968A84 +:100BB000C4676CA5AD0CE5182B17299E33F5C22F21 +:100BC00018C6BF7E7EC57405F54A47E9ABD2109CB6 +:100BD00067B959AB7F7E6D36D4FFE28AABC83E5A07 +:100BE00091217A51AF9A599AA392FCF4F3BCDDA9F2 +:100BF0001752880E672D9D457AA53EDE00B3791DFC +:100C00008027B38158A3F39B675D61F73AA2F0EBAD +:100C10008FED4215D7ABBD29D78FE57EA1CE622ED1 +:100C2000CFA3E1B022C342FDFF3577DA6484EFD46D +:100C30002BF93A7CB0C71A5A0DFD7E608F6F47566C +:100C4000E5737F6BB6740DF1A5DBF658293E7F4640 +:100C500088FFFCAD6B45CA2B5ABA566021E8EF837A +:100C6000675ECA42BEFE875D2F65D5448D27D1FBE6 +:100C70000BF313F977BB1744DBDB332D3C2EC02677 +:100C80005863FCBB335D5A7EFE978C777C2BA19F0B +:100C9000FFA72370BC6FF6FBF9DF18111DEFE88F7B +:100CA0005B29DCCF6F8C57E596FFBB365E9E0FDD70 +:100CB0002C69E355AC3C6EB190C7C5571E1A4278FB +:100CC00037D3127980E259AF88B216D7F0DBE8FD4E +:100CD0000C5E9F605ECCEFCFF59491BF89C6237404 +:100CE00009DD4ED757981FE3710CE3FC6A0E8A7139 +:100CF000E3727F2D9079BCB3384276D5F1379EC030 +:100D0000C87B3FBEDB0FFA4CD179F4FDFAAC86DF2D +:100D1000D7217EC3FCEC6B7939115E27E25719F9B4 +:100D20009C8E75FC3EBE362705F1ED1E5B43B81761 +:100D3000E0E71753987D1894B5F8BFFA2ECF6315E6 +:100D4000A3EC1CA4836DEF3AC9CE6935373D8EFB09 +:100D50007ED41689ED82FB9EA486500B94BD662737 +:100D6000E54DDD91346B07DA7561507005287F928F +:100D7000746C07EA09CC96C2CCD08F5AA1BD6FB172 +:100D8000C9ADA05F3C96EC22FED2BC8091FC4E67C0 +:100D9000DD82000039989FCDFDB4CB5E1428FF188A +:100DA000281EF53E2527BE3EBA57A38B5F61020D74 +:100DB000C6E5A7C77FEE60BEEE179382E1283BEF42 +:100DC0005E41F112DF813FCC8F34B3BEB9C497418D +:100DD0008FFF05C883E1E28FC93F7BE2EEE0E3F1DC +:100DE000F649E8D705D3E3DBE9AF6BE32B6C174299 +:100DF0006617D1AF69470CFD6A713C679A0212060B +:100E0000E3B73C4E97CBF47CF94DE8B71F56CEC7FD +:100E1000E8F28719EA1719EDD7B0E010A4A729E97D +:100E200028DF562E8CF5A765D4ACCD24BF5ECDF758 +:100E300067A1FCDE6476AC1552F01AEB8FDB64F030 +:100E4000C77D115FC84848379333D0BFB16920FED2 +:100E500047F8D33A5F0E8902CD8245C7B5D35ABD54 +:100E6000BD41D483A6D9949DCA60FA61E54A06CEF5 +:100E7000ABBC80C34FA7E7460D35858302D9A58358 +:100E8000F9A106CFFA11044F7BFB1D64372597703B +:100E90003F76F2D29A20F29F64E03F68C7592C4D0A +:100EA00002ADFF146EB7AD147879E5345956E17987 +:100EB0008B4BCB97BD96E767AFB40783D1F1B4CB2B +:100EC0004D2BA645E7E5CA0CDE473E3C87F737D3F6 +:100ED000B68AE705074147CA1C80638506C7DCF26E +:100EE000249EA77EBB8DFC5B5BEDED345E9397DBB0 +:100EF000D935EBEDC4EF868B851437E93173FC509F +:100F00009D36A257A5E76DCA0F1B7E598657F4453B +:100F1000E1CF6DBC5EC70B66C82BB058BCBDE8BF47 +:100F20008381289897B252F0F656D0BCE488AAE0A4 +:100F3000BC35BE3C2E89CB11303733385C795CCC64 +:100F4000B05E8037DCAF3ED6C1FD462CE825BDCB78 +:100F500030DFC178B3BF10F96D4F3FDE7415C6E3C3 +:100F6000B70FBABDBD3BA3F18579D7A05FF53E139E +:100F70008BAC8F873F4AAC9D6FCC9333DAFB0DCDA2 +:100F8000D3039AFDA1DA683D2D647F34DC392DC08E +:100F9000ED8FC216F43F35AE024905EF4C3F28D81D +:100FA000B0BDC6392EB2BF1BBBF652FCBCA18A290C +:100FB000388C1ACD3FACCFF3B899C7F14066756253 +:100FC000FCBEC31DDE8EFBF23A96EA793C3CAF458F +:100FD000ED12B43C1E3DEF2B720CFD9F1D8297FC61 +:100FE000A0FDFBFB60FD79FECEA5E581398B033EBC +:100FF000B4C42FCF7BE29749932E218F563DD381E6 +:1010000079B289F3685FBF01EB6DB8165A3DA20152 +:10101000E8CB7AD96FF762FECE40BD0476A7AD4B20 +:10102000E0EFABD7DE709544FB72B4F2A147D01F5E +:10103000FEA09DC5F4173D3EC9D03E9A960EAFFE68 +:10104000FCB6D9D8DEA313B4B2FAB787FD30BE0719 +:10105000CDB1ED11CA68EF6341EFCF3BE6998E0D3C +:101060002306F476D0E3EF2E9834A0BFDFFBCECC7E +:10107000F6F1D057B2FC27DA07A5EBE18D1E9E579B +:101080006BC4F3F51A1F037B7806AAD6F7CE591E58 +:10109000C076FBF3DE0ECEF7A31DACE7BD35AE0A7E +:1010A000D07E28D0FB1F28C03CDADF9D3D7598A17B +:1010B0009DF901F9031A3F95B8DF19EC0701F0C556 +:1010C00076F021C21FB6DB1C42D74E875B65888F46 +:1010D0001D878449885F8C3565DD00B03F55E0DFB2 +:1010E00088F33897203EFE7C01B7DB1B0B2B36E7DD +:1010F00023AC9F1418EAE3EB0BFF487645C3FEAB25 +:101100002645EFDF5BDAF528DF07B6DB1C77DECF9D +:1011100017883C8F78FF0B143FF9202410CD2D91B8 +:1011200042EBD0DE5CB2C48496152B0DCDA73C59A2 +:1011300036C7C270FC8F1670B834EEBE4EC5FD8443 +:101140008DF00F48806D092C227D7BCB1C9B03E327 +:10115000D88D8535CB89DFC9497E34E58CE3ECCF6A +:101160007FBB3389F268D67799ABD04E2A03BAF8A1 +:101170005707F2D5A3BE1DC83F874C105B65CC3323 +:101180008CAF7FBF50C4F5873621A07EBB94E2228E +:101190002C3A9F795417B7BF7A0B2C31FEC9DE0267 +:1011A00089DEBB42ED9B8EB8F68A144E467BB89121 +:1011B000F93F42BF170B38BC1417629DE40FF4DCF3 +:1011C000ED25BBC9E609DF371EEBAF90C86ED2FD37 +:1011D00008E7F6A7933E36A530F82BC48B3231FCD6 +:1011E000C8B7116EF7495A7C89F395ACEB1C13D044 +:1011F000BE327BB83E63077D06F7895CB9EEE4CF6B +:10120000A6236FF504488F6020E470BFF9749BC07B +:10121000E32B06BD99C94A25BE3F43F34BE7C16A9C +:101220009DB2116AB65D1C82FE0C8F8AF07E032689 +:101230003004EAAF62FE365C97BF6A76E4460BD7AD +:10124000D7379A6CA4AFEBFA70B2A78FECC4FA4E02 +:1012500081FAA92FFC31ED1758A6E5A5F7E7874BD2 +:1012600061CA973F5790ACE96F6DDC1FC5FAC81F84 +:10127000C69EE5EB009A27E5D1EB70D7F3CAF5F6E9 +:101280002C5ABCB45EF3E702C0A8FEBF0A74BD705E +:10129000B5165FD5F3FE79BF4CF29645FB1D375668 +:1012A00033D647E3F2BA70BCF7A4054C85F0FE7163 +:1012B000C063C4B3E36B9343B8DF6BA3D0E7C7B895 +:1012C000875AC2E319467C4A2FE4FDA6F4446650CF +:1012D000DED5FE04FB8ABA62F715017F58FE3AF4A8 +:1012E000535AFA8E82F8FDA05B7BFF1A46F9E4C6DA +:1012F0007D45230ABDFF3BF71529827F275CC71672 +:10130000BAF9BE217D5F91C2D74BCFE330EE273AC9 +:1013100097D92DF1FCFFF0F65D242FAD6417BEFCCC +:10132000616F1BFA99CF975814DC479176D31B6DE8 +:10133000944F23484D188F34EA034FF8A65F563870 +:1013400009F7A5BDA850BEB0411F48E407A05869E1 +:10135000949FE89AC2AFD70F606FFFC485F87646B6 +:10136000883C8079ACEA21316E1EEB92C244FE00CB +:10137000FF9C68FDB44DCFF77227C5E43FB625C882 +:10138000F74AA4F74B09F3BCAE21FDADAD3FCFAB9F +:101390004AD7DF62F358E5A4CFB597F5FEABC2BEDE +:1013A00098B8FC3F6B74F2C5F3D4EC9804F34B642B +:1013B000B75D6A9E81110E6D09E4E83D85F1F7DFA6 +:1013C0000258648CCBB7615C1EAE92C054F29FEDA4 +:1013D000EDCF33E8267FF10B05E4F7B226CC33E0FE +:1013E000F967D2A1022F3E77AF39E0477B46DD6B2C +:1013F000D6E440E819F49BB41DCA243F1B2B0C8F84 +:1014000043FE28B96764E0B9066D1A7ED67DF93CC3 +:1014100083C791CF19F30C7684263C90CDEDE7BEBF +:1014200064D0CB76302EA7D483DCAF09E326BF5E31 +:10143000E4FE91A4AF0AB36D348F13AF58775A49C5 +:101440000F57286FA026439451BE7454979D42F9BC +:1014500075021457A4E3DA5B5791FD9A687D6AD749 +:10146000C6C671F5FB5F769D5E29E4FACE71B4EFD6 +:1014700049D0AAE42F5EB256384CF9BA8638723792 +:10148000F2109213B179011FDBA7513CF6FB0F5705 +:10149000531C56DFB7ABEFD7655ABCC5BB562239D4 +:1014A000E1DD2D84BC3E4E2626B2ED65139D1F0264 +:1014B000E26D0B8A4415A8E632B82D9804D453BDCA +:1014C0006D504E8779AD93D40C786EC7DBC9E47F3D +:1014D000BDD7E3D5F65170FB4BDD2090FE07ED92B2 +:1014E000FDACB601DE403BE1421E17F8B490FBA70D +:1014F000014542341EEDDAA6E551E8FDB53053371B +:101500005E4D02BFDE2B4B55F1F43BBDBD367393F0 +:101510000DE32D9191268A677E6CF1CFA178606AE8 +:101520003E437BB1CDD9B4B68AD7130FFDD81E097F +:1015300050FD37246E28306F2A8EF7371ADD18D702 +:1015400075617B6CD918EF379E4350CB8205993972 +:1015500083F7E5FF4693871FAFF769EBA250BCBC4A +:10156000CDECFDA50FE5E33A89E470CB080E37D347 +:10157000487ECD7657CE2139EC06FD94C6CBC79F69 +:10158000FD0D8F80F4D7E6E6F8F555C73DE81C81E0 +:10159000A27C1A6F1B1A0DD05FDB3A21C4E1C5C7CC +:1015A000FD65FDD559455FAF9C3A21284F75239EB7 +:1015B00039423F44BF5F6D8B55467E7646D0E87F0B +:1015C0009D48FC6CCB92542A1F5F9B477EA07EBA3D +:1015D0003DBD66399EAFF065F3B694228E173F3756 +:1015E000F8E16ACA85A3D88E11EE8850922E7FE06A +:1015F000D5E9D715CF40FED86062DE74D407D61A7D +:10160000F2430CF43CD51BBCB208ED0F4B5F2FE747 +:1016100053E17C89F46FBB82707BD47462EF4F100E +:101620005FF6DA29DFB06155E429F457BABDC1ABE2 +:10163000F0BDB377BE3343F05273A4279D3F5440AF +:10164000E775D4B419CE41D8109B97C2D6A6F2BC88 +:101650008F8ED8FBB85F3FE6BD41F92AED9ABE1DDB +:101660002C42FB62EA953CCFEFC3A5268678F1A118 +:101670009DE38F7ABF5393334A7EB45E5BA3D93721 +:10168000FDF871BF9DF0A356DBE7645C8F7AC40F51 +:1016900058B73A0D3F3E7CE1B27CC48FB37B2FCB71 +:1016A00047FCD8686EF7237DCDC90D2E2A82719D27 +:1016B000BC2AD06BE27C29FF52F0F676E3B8FE41FB +:1016C000FA55475122BDC3FBDDE8784B8F99FBC922 +:1016D000547BEC3EA19E4BF4AB26F68F15E5C6FA83 +:1016E000C70A73E3EA5736FBE7EA57973E0F46FB14 +:1016F000C4F4384C8F33F2C05351F05A69E7F928DB +:101700002B8B64592DC1F9D5E4D0BEB3DFD9949D9C +:10171000C2D73ACF183FE02B1772D6B4E338FCDCBF +:101720006FF98AE4EDBD1CFA7D8571BFA571DEBF3E +:101730002DE0F933BADDADDB81C6FE0F68EBFDB3FA +:1017400022FF21B4ABA75EB8487E84D3782E0FF475 +:101750006B0BFD2BD973ECA020D3BE352F8F8336B6 +:10176000EC5FF804FA5D9786B4F8E53E81ECF5A5E8 +:101770004F7E44F5E7BA6AA9DE7150E8C63868E3DF +:101780000813C96D3DFF41F7FF341E2C21BF8FEEBA +:10179000FF8171EC473F4DB2276221BE85F625BC23 +:1017A000D720F1F86E8387292AB2DAAE58BF899E16 +:1017B0001FB52560217ADF725008A13D9E6609FAA7 +:1017C00046103C47C894DFA2F18DB78BFC17905FA1 +:1017D000E9F96B7B72FCEF14F1BCB72CCA93D7D636 +:1017E00023D81F17E2FB2CFEF26BBECF229C805F3A +:1017F000FF67919E677B23E9CF7F618194F8F9E7CA +:10180000219E7FDE9FEFC6F3CCEB6632B6DECDCBFA +:1018100078CE4C3D9E33A370F9D96D909FD165CCA5 +:101820002FEB8EE29B75521FE5B1EBE7CA60BE5904 +:10183000F4F30DB84F2387E79DC5B4A3F1D37471BA +:1018400005C57FE2C45DBF1B6D7F1CD1EDAC127D71 +:101850005F4DC482FE9D952D9E08C6118E38B5FD44 +:10186000BE5A3EED4A7BE404FA3F563E934EFB4798 +:10187000FAF5FB3D56CD7FCEF1BE8EFF648D4B8ECB +:10188000939DDF88FBFA85017A9A99D02EFB692E09 +:10189000C6638EF4DB656FE4E2FE1B9DCFD6299C08 +:1018A0005FD475097C1F5667EC3E9CDCD15FAFBEF0 +:1018B000A03F97E8FD8AD189ECD92F8233E7B7475B +:1018C00012ED5FD2F8A40E47233FBA54F8E9F5FDB4 +:1018D000F003BA267E6B809FD18FA6FBC3589B4C2A +:1018E000FE32D0493A319F53F7877D5979F89DD11F +:1018F000FF33F2F0FBA313C9C3AFB63E89E4C4A51E +:10190000AECB207988EB332EB13CCC2DFF776DDC4C +:10191000C63C046DDC863C8423E6C82C7E8E05C064 +:10192000C737380F2121FE7D411EC2DF314F431ED4 +:10193000C2E7CFD39887F0F8A1C75C18AAC3FD6AA5 +:10194000E877E8D965A6F8FB0CD1E1E7F96122CF89 +:1019500027657E3A8FB3D16627FF82317F0E38D557 +:101960009A26D42FCB41EFC7FD3CDB5A492ED767CF +:101970008AE4ABC47C41D91B273F53AA4EE9F60E3B +:10198000CE13C3FC773A17E012F3C4F68EEECFD72E +:10199000F4FD9DF99AFB477F893C31258FF3A757CA +:1019A0001D7F1A127D5E66453118EAC589F3F47F02 +:1019B000A2D14DB296DF6B935416ED8F4AF4DE2F11 +:1019C00046737BE7554BE4ED4ED4ABA0198C7B6698 +:1019D00058C09A2E1DD8EF7EAA207014F394411F90 +:1019E000A1F53DB7FFB7E4EF7F3C93C99837FFB847 +:1019F00059A575568732C26B3D9F41EFE72ECDFF4B +:101A0000FD65F9CFFBFF60B9208DF9EF910B5F1BEE +:101A1000DF1994F7C4E9F1EFE037447FFDFCC4CC53 +:101A2000E341FA79175F28E7BE6E3E63C8D74834B2 +:101A3000AFBF1630C29FC23181EC31E417F3939FE0 +:101A4000F152E55F7229E843088F7D562F929A4D37 +:101A50003BD7826DC8D4FDA2FC7CC1074792DEF95A +:101A6000A19D8F573FAF439FCFE5630CF8F915ED6C +:101A7000582537F08D3130BF93D3FCB4EFF75E2794 +:101A8000D7DB22CFF0BC77E3F9134037FC3C0EEDF7 +:101A9000DC5FE33EFA6F1BC7F70F92DF0DFFDBE958 +:101AA000E812E5F7A5CF23D69E3DE2E4798503F65B +:101AB000EC7FDBBC2E495EEB79C665157D9ABF5F76 +:101AC00060E8EFD7FB69ECE3FB741ED2D653BFFF8F +:101AD0005BCDBFF7D618FFC388AFA5A5DDDB71BF0F +:101AE0004A0373318CBB3774DEB1FB4D0FDF7F4B84 +:101AF000E5421EAF640107EDCF7E3C2FB8750CC9DF +:101B0000C1F01AA4CF511E56867183F585B359AD25 +:101B100083F21042583F6A5578FB9BA59487D58481 +:101B2000F4AAE721975DFCD39AAA521A2FF97F3DB8 +:101B3000D6D8733B0E8FE1F24CBFBE3246D0E2AE38 +:101B4000FE4C1CCFD9257C3F6AA3C72FA31F598FFA +:101B50007B277BFB286FA0611F378ACAD056C4FA47 +:101B6000BB46107D35EC9B5682F150D6692FA1F310 +:101B70007E7FCFCFD93E7BE730F2374E290CBE8433 +:101B80007CC9591ABA06EDE851D00FC64DCFEEBD4B +:101B9000A62418876FA68BA92AC695D345D6F9889F +:101BA0003CC0B7C07E9E4BFEE23511F2633D3D86E0 +:101BB000DF6FF470B9DE78B09A2D740C941D9ED846 +:101BC000FD573F2BBAEA691CC7D363242D2F93E737 +:101BD00081FA400D43BFA1119F7C5A1E68B596E75C +:101BE000CC54DB407E73F617E781EAE3D3CB7A1E51 +:101BF00068F2A7DC7ECF962D9437E25CCBF92A5BA6 +:101C0000C5286E7045A46F7A0AC029B7A3FB0A8461 +:101C1000530A829DCE7F0DDF371EEE7B864857A08C +:101C20003F647BF3841ED47FA5757DDFC025F1B6AC +:101C3000CB15E8627C3C2F7082E480D454887CA968 +:101C4000E22D33DFA7B42E99F4CA8EAC3ADAA7742A +:101C5000EE1D6BDC7308F4ABCA566760DC217BEDCC +:101C6000AF282FC0B94F88BB9FADB2D8A1ED635A42 +:101C70009D81710CE7DA3EB51CDACFBE5F609A1920 +:101C80009D2964A07F5832A17CADEDE2E7DBD5B69B +:101C9000BB2B6C246FB8BF865DE1213922ADFBA65A +:101CA00009F984D4025A2CCCF3F2621E9FCEEB9039 +:101CB0004D28A7FEED33316E1CC9563CB0DF05C17F +:101CC000556F8DF466F806F27CF47D2EBABFA75FDF +:101CD000FEEC9B4FFE9E4BCFEB8EDC4C79839FA599 +:101CE000517C65A68BDB232088B4F35D62DF1F7413 +:101CF000BE8BA6B7E876B1910E8C79D2B9E5C388D0 +:101D00002E808F766E9163F85EDC7CE96689EBDD70 +:101D1000300FCB4A1CC7B40C05FD735F363FDD683E +:101D20004FF7EB399A5EA28FFBEFCDE7D6EBEB30A6 +:101D30008F3B8EFF43D76BDAF47DD09FF1F3B7462C +:101D400069F6C4F1F57F1DC7CF39D4F346427495C7 +:101D5000CCC03F097FC257AA8807FBDCA686628AEF +:101D60002F35503BEBF8F9FEA3D6E6AC2E2FC5ABD2 +:101D7000CC0480F7F103CB4651FC16E8222F0E5D10 +:101D8000BC3FC6CCDB5F974C782C3DC4280B52720D +:101D9000A7111E4B8F727C7D6F0CC72F3D6F4D8F2F +:101DA00003BE35263817F729F69FCBD19CC4CFE563 +:101DB000D0F2BF9DCDEFECC1F32EB66B71E09E5714 +:101DC000C6CCA6F8DC3A4940FBF063F7FC51E8BF0B +:101DD0005BA0E1B953EA63B2239A5E7B68FF60F6C9 +:101DE00021BEEF49D2F254A5759E1D889FA22F48AF +:101DF000FB24BFD1D62D521E947CF2912A2FDA1DDE +:101E0000110BE6AD7DD0224556BB497F8AF193196F +:101E1000FD5E4CEAA4BC9CE6E27FAC1DB2B138A1E9 +:101E2000FEF495F65FB02FF04F7D55BC4EE49FBA9F +:101E3000F47918F75D70FB84BDC2F39BE2CC2BC62E +:101E40007FF9B5CF4BF75B1AF3D506D131F77FE8B1 +:101E5000F6901E7F607E35269FBCC72C77A3DE835D +:101E6000F9B92F28A8573F6D8FCE27FB370DEFFB11 +:101E7000CFFD63213BEED73FAFED376692B216E35D +:101E8000A07788CE76B4EF5A31CF1FF54B84AF10D0 +:101E9000B5DFE15D27E53D344B7C3F0453F97E8A95 +:101EA000950B9B9EC6F757B6A4CB087FB5A2E979E0 +:101EB000DA2F61628156B87EA27DEF421F8F9EFFAE +:101EC0009F487E0ECAFFFF82FD0B9909F62FFC8703 +:101ED00086F7850B18ED5F606BFD3B705C1D2D1266 +:101EE000C3786F6A152F8F926CF4FD153BE6510F86 +:101EF000A1FDA694EF1C017862DEB61DF3A887E071 +:101F0000FE127ECEA130BB8AF02F15E0837A41AB62 +:101F1000999F6BA8DEE0207C9A5EC5E397A9010B30 +:101F2000F19FF34CA1BC7B15CF3FF3209EAD26FC67 +:101F30008C38D328FE9A9ACBF5487BC062B2F92838 +:101F40004F9AF03522E879D29CEF75CCF752FE7AA1 +:101F5000FF39870B19ADCFBABC1999F8DD8161D76C +:101F600059048CD7E872A642C38F8E1DDAFBF5FCAC +:101F70007D3C0711C7C756F2F7FBCF41FC1EAF6F80 +:101F800096C2748E10E830DA397CBC7EE5DC34A26F +:101F90001F51DBE7CA6ED2F2F4057EEED4CAB9C394 +:101FA00078BD8BF341766B9226CFB5F76F4F0D69F5 +:101FB000F1029E6FBFD4A49D1FD0CE62E2B91A9DDC +:101FC000A57EC17E8D8707F2EE899E5BAF9129AF1A +:101FD000503FC7B1C261E1FBB86CB174F542712AE0 +:101FE000C7FB72C586FDDEE2F3FBC6C6F50F87E6CA +:101FF00047F395613A5FB9D562B0CBD2395C5D9158 +:10200000ED7CBF97F592ECB2C471C5673263E38A89 +:10201000BB33A3E38AFAFA562CB1105FE9707B5FF9 +:10202000C3FCA32D005A3C17CF38EF2DFDE75B878B +:10203000ECA8971AEDC12309F28CE68FE5768F9212 +:10204000C00F317F6C22F992204E5B62FD6F8A37A0 +:1020500073FEDB93607F5F3FBC74BDC9668C7BA859 +:1020600097E4F7E9B1FD80F8A0BF5562F62BA16CAB +:10207000D88F067C90F8A2BADA2AB77A908FFE80C1 +:10208000F8623358AED628BE08E6E865C88F7BEE06 +:102090002EA4EFD9BC76B742D7F376A1531C8FD7C5 +:1020A000C83CD498163F77F8463CEFF9BC3392858C +:1020B000E743DFF3FC9BDFA1F2D0C8312CB73D270B +:1020C000CDA1725E643B9E17BDE5B935BC1E696C3F +:1020D00018633F187BD77754077D7F614D1FEAF760 +:1020E000A5863C7EC3F9B5B8DF14E793EEB050DCAB +:1020F000375DDBE7CB2A35FF10667A21DD65965028 +:102100009E9E8379F7F561FD082E77A1BE05CF4726 +:102110006DCDF3F13834E37C808DD0F238585845DA +:102120007F54ABCF4DEFF7EB77FBAC5A1E18EFFFA8 +:10213000E80BFC5C1F7DFF3263F248B41B1D5E168A +:1021400053D6CF8366923C12CF6F6DD5F0402FBF30 +:10215000941E0C8D8DB22B8F5E754731CEF3C31755 +:10216000EFCA457DEA6AED3B5046BC6A1CCFF17B65 +:1021700075F2DFE6211F7F5B7429E43F480FFE08FC +:10218000F9C6424FCB2437E04FA53C8DBE373345CF +:102190009D2B205F715FCFC7E7AE0C080B8B07BE8E +:1021A00043333428919F9E053B44D4B7879E0CC887 +:1021B000089F3A5B244B82767EE309BE80E3FC787D +:1021C000FE7BDFA7BCBC61478FE1B99247CDEDD361 +:1021D0005D884F3EED1C6126D1BE9ADEE1A3766A92 +:1021E000DFD3E1FB6BF2042D0EDB5D8972E15AC691 +:1021F000F116CB58FF4DED9CB419323F777346A9C9 +:102200008FBE8F368B4524C487196F075C0CE9E3BA +:10221000FA6069BC732BF42BCB307BA3E9E71A6F10 +:102220005419FE7DB330B6FC2D25B6FCEDF2CF0A75 +:10223000A2CBD592FF9708CF97052E7FD4C95CFE1D +:10224000C8AC7335CAC71F35C91328AEEE11542C5C +:102250008F796918E525B10C9ECF30DA951DE270B3 +:10226000C8D98AF38A809CDFE9C1EF2CF1F3AFD2A1 +:10227000DEB6ECC0F31598D7BB15E9F0457321E540 +:102280006DA6396AFEB585F41927CB233EE5DD4AF4 +:1022900078EDB479F1BB0F879D3C1FA1F52113C5E3 +:1022A0009B0497CDE487E7C49D1297FFCE25D3B159 +:1022B0005E2C83050159DDE3E6DF6D6A9DC4CCAB7E +:1022C0004B70DD94B7492F72DA28DFBFD255F85D25 +:1022D000AC175D163A0FE2B0B32CA8F5C7B0FD27D6 +:1022E0009D4BE87DE4D16630C87BECDCBF2E827D5F +:1022F000BC9AF74FDF67135730AD7F1BB360B986C9 +:1023000051FE7E8F5BE6E3BDDD44F110ACBF92C6AB +:1023100067A37AFDFCC281FDB2D3243AC75D605A3F +:102320007CAC85CA8F697CB0D52C1F463C55FFC05C +:1023300018AE47A5EB53A203D1E452E8BC1D3FCB36 +:10234000F5A431EEB380E7C534B91BF3D9C5152E1A +:10235000B29B51F3C1FAE1F893E85AF2B332CD35AA +:1023600043FDF98F231E8F125800D723388EEFA319 +:102370007DC2747413E55738025605FAB1DCC4689F +:102380007D95E4F8FB64C78FE3743A78FDCA323078 +:102390008F4370957BF1DAEA2CF7E2BE9F1EB7926D +:1023A00011882AC7599710E2CDC0BAD8BA4DE37048 +:1023B0003D142FEA175FDC1ED43B703E1A7F1DA62A +:1023C00078D10ECD75413BC0F79521F1E7111CC7BF +:1023D000FD8B9DDAB97AC6FA99E34C5FF73C0DF8AC +:1023E000F715E799163BCFAF719C61E16B18A79881 +:1023F00005E3730C8C0F7ED2395FD73A4C845FD7DC +:10240000EAE72D15C6EEBB30EEB3606CD566E4335B +:10241000576BF9A315C9FF4C7EFC6B40CF47B9D66B +:102420009BFC835CCCDF9C91D2D2C689A3E9EC42B1 +:10243000E4C73681F8CE3759F71ABC7F7E5AF0715F +:10244000770EF1FDDBC60DC5F3538305A950FED011 +:10245000DC9EBBDC477CF1F67193709C11A2BB6BD8 +:10246000F17B6C487733436D58863E9AE8DC2DA0AB +:1024700043A45B9D0E078F1FE8129E1FDEE4A2FDA2 +:1024800050DB58376D68CB60ED02F7B73491DC62F2 +:10249000DE9103F304A29D616BA279FCA44525F9AA +:1024A00070B5FB1109CB4F2AC1F538AE39E33FA215 +:1024B000F3F259C6FC02B43B61BCF7E13CFEA7C68F +:1024C0003B789FFAE7EFA3F847D9A3CF6B74ADDB56 +:1024D000A39E24D027609C5EC1A530D01FFBED5386 +:1024E000B38DF21206F6F5466A69FFB09012407994 +:1024F000A6EFEB35F2DDA95772BEFBE17297B29AF7 +:10250000CE39DC4D7669E3F50E7DDF2FE95F8D4B2B +:102510004CDABE5F81E44A03B3D1B943FDDFAB833C +:102520003F216DE0BB1E0770FF6FE9E7EDFFF5D2BD +:10253000FE6275158FD3F7DB77F532B75FF5EF43A2 +:10254000DC9EAD9FE3CFF594E5EC4BD9B771F60572 +:1025500093DEC8524C9AFDCAF5858EC95E59651442 +:102560005FE57AF85C0BD56F4C0AD1F7566AC576F1 +:102570004292E3E3DCBADFD34EDF65B228F9C82725 +:10258000F438EB9CDCE07F225E2F2CF66709309557 +:102590005A0B8F9F021D6CED83B7AA58D393F8BDD9 +:1025A000AE6B58D3AF4D3944076710DFE78CF9881D +:1025B0007FC76B800ECE623B36C6FD01D76A71A223 +:1025C000973F7CAA0DD7FDBCC0F8FEAE42E3FEAE3D +:1025D000C09FC7F17896F63D9E58BE13358E936620 +:1025E0003E0E8F28D2382EC41BC7203A6421EA1F22 +:1025F000D6B789F69F1BF0C8381EE1E01DB43F6EC8 +:10260000EBCD4C1627A31CEFB3233C472046E4E058 +:102610003C83C9E327913C0FE2B968BA5D3D68DCB1 +:10262000A283D6F5C6B9FD793AB332CB304EC4FB9E +:102630007D2CB9E151F47B34DE6C26FE5E7D702C7E +:10264000E969BDAA55C6244856C9F36B14F80FC7EB +:102650003587F9AF72433BD7C9D574CEDAF5338DE0 +:102660007939EA3D4DF0FE0D5A9ECF8DD79B8F47AD +:10267000EB9BE7CD1BCC0807B5D6D1244EC1F6A401 +:1026800081F77D83E132E89CA736CE9F18E839D8E0 +:102690007E6B7927F1A7447C6AFC787E2E14B455B2 +:1026A000F077E6FB5C36FE4BE4FB4CD0CE857ACD72 +:1026B0001CA1F33B5F1FBA78EB729867C10F8BE9DF +:1026C000FBA557A52D7DF221283FBD6534955F4FB1 +:1026D000BBF9B6A358BF3D9FCA95A68FE6213D140E +:1026E00096CDBD16BFFBFA9A9DB7939114ECA886C0 +:1026F000E732C6654FC003612A2D117AEE9BE3EBEA +:1027000027A23FA63289978F94FC760295B3B5F243 +:1027100084974763F935E1A379F1F8E29842A1BBC8 +:1027200008E46D652A7F7EE6846786A11D5F59C136 +:10273000CB639469EB72B0DEF4C779F1F4A505E3DD +:10274000F97CA75E38DF36C4836161FE3DD297FC19 +:10275000EFD1F73902206F71FF7EA09CC7E102FE26 +:102760001209BF0755E1E7E5E98E964CE483B38291 +:1027700096528CBBCA0E5F1B7E1F31A57CDA245C8F +:10278000F7E9A06E639C13E86B09C27FCE651F65F5 +:10279000B9482FD5E94B3613BD273EA7B19EAF5B95 +:1027A0002C3D407B2B906EE65C1E2B3F07D1AB018E +:1027B0000FAFB58DE0780772D15A3E985E8DFC9BC5 +:1027C000ADE914A2E9751BE2A54874BB1AC76531CF +:1027D000F579F1FE2841192D7F0EFD9E37BFEBA341 +:1027E0003810DC102F8FC337E04FD2F57C3E0A59EA +:1027F0004EA3FC659ED773F0B7F43E6E071133A964 +:10280000FF8771FE6C0D1FCF363CBF44447B2FF811 +:1028100004F289860CFE9D498CEB239D66E8FCAA98 +:102820002B76BEADE5CAAD6E71F0784D360EC7EBB6 +:10283000357DECADE6C0D01218EC8DACC98CF37DC3 +:102840002CD9A5623CB7B1869F43F92FE9C1271166 +:102850001EA2493D1486F242E6E7DFAF94FCBBC6F8 +:1028600047E95F0DDABA34D8DEA57C36FCC3F351F4 +:1028700006C1A3CBC84763E73FB02E7D9978CDC48E +:10288000F35772709ECA5A31CE7C98D4B42EDA4F68 +:10289000FFD817FAE919F7B72856ED3C95C8BC6878 +:1028A0007F5CABB3E9F1683B19CC323A07E9484B9E +:1028B0002E8B8777BA9E7444D0FC5AA0F7A23EF0C4 +:1028C00049D2DF483F018A0998B3D0AF358BF4185D +:1028D000C16293317E9D519341F8BA09F412F4B369 +:1028E000AB159D39E42FDF2E323CB760000E30125D +:1028F000DF007E7E383E9B7FF7AB1F1E2AF1518B97 +:102900004988AB5F7D38DEA49D9FCAF79736D8AC67 +:102910003CFF53FB9E859EC7D2602B5ED344F3B32E +:1029200071FA31ACD3A0BC16639E9C2D9DF40B793B +:102930000253501E0ECE8331DA092ACDE35BFDF13E +:1029400005C6F59F3B9DA4FF7C4B8B2F08B33FA58D +:10295000F54905FCB27A308EE015D05E492D3D2A4E +:10296000B1B103DF9FC4EF36A13FAB2B3BF87FC76C +:1029700047C5E3DF9CF434E5851C33F138A8113EEC +:102980006685C7816416A67CD5068D5FFD3F379CA2 +:10299000204A0080000000001F8B0800000000009B +:1029A000000BE57D09785445B67FDDBEBD25E924E1 +:1029B0009D104242583AAC4102762721806C4D80EE +:1029C000880A4C585450841B886C59059D41C73166 +:1029D0001D02880ECE84272A4F511B0444079846B7 +:1029E000D9D4C8B48088CF2D6E336E8F495C5925F9 +:1029F000864171C637FECFEFD4BDA46F13067CCBE2 +:102A0000F79FF73DF8B438B7EADEAA3AE7D4D9EA37 +:102A100054B5D8633BD19825F8CF8FDDF0FF4E49F0 +:102A20005FF61542053C02704088F642ECEE50E439 +:102A3000F052795269C847E5DF7ABB8518807A2D54 +:102A4000B3A89F1049EECC91491E027FF8F1C71F31 +:102A5000F3859882AAEE427CDA5D4BC47BD78BA2C9 +:102A600031564588E4B19A4D73093146A5FFE50911 +:102A7000D1B245093AE8F9687F8C45A4085179C874 +:102A8000160C12BCF055EA84E0858FAA4141708B88 +:102A9000F0AE6944FB80C31DA0F2A1B8FEBF1D4A81 +:102AA000E5678FDABC0EF41BF0BF9345FD96A05F7F +:102AB000827BAFB1088F539F17FDD727182B3C5946 +:102AC000AD70DFCDC926B85FA8A3A9FDE57BBA9993 +:102AD000EA7DE1CB4CF5B987724CF080862B4CED4A +:102AE000077E50608207375E6D6A3FE4C824133C5E +:102AF000ACF90653FB11676799EA4B130A0F2EA630 +:102B0000F91E4C538532488891A2D4D4BE542DB3BB +:102B10000B0BFDA3CEF66923BD57457F999EEA7442 +:102B20002BF07C668F22DA650A31778DAC37DE9B1D +:102B300057BF6A790695F383E6E7A5C2DA0AD37B25 +:102B40008B3F99FFD68188FE7AA7145B92A8BCDAE6 +:102B50001B9FF2651C262C06FEA8325DBD61D0E9E4 +:102B60003DD5EB90A4603A2FDCAA04EF253AF6128B +:102B70003D1F02DD88CE22E8015D657DCB5A351808 +:102B8000A07EBEAB9EF7D6011BC18772D73412FD63 +:102B9000E7D638DC2AD53BD2CCF48CF198E91997EA +:102BA00065A667BCD74CCFC441667A26F9CDF46CD4 +:102BB00037D64CCFF645667A76986AA667BA66A687 +:102BC00067C63C333D3B5799E9D975B1999E9981C8 +:102BD00005A6FA68FEEDBE62A1A9FEA1B8BD5F6AB6 +:102BE0008487948EAADB414BAF67DD1DA6EF097584 +:102BF0009C7D19E1AB344315AABB950F02F457AE87 +:102C0000EB2A5E5F73880F1E263A9C112B0F6678A5 +:102C1000CEE7878A3DABEC589F3F951F7E0D3EE87F +:102C2000DBCA07C47789F8CE8FF833E2FCD2A0F371 +:102C300044AB7F9597E4C806AFB61AE5D4DEDF74DF +:102C4000B192DC1045C5BD8BE2857089E619E0A71D +:102C50000A91E0BD17A5F3934CF00BFE38D2E97F43 +:102C60007ED1C34A785374BC892879A6D4FF29132E +:102C7000F35E4BCCA8A2FD849002F9D54934A4435D +:102C80003EA58B2A05659AF0AE50316E4FE756F996 +:102C900097C184B184E9FD0F4B6CCCBF4BE2FA6F56 +:102CA000015F7E502BF9F2349A0C16E20611B2E164 +:102CB0003B1FC63ED219FD1510C295C1A8ACBB0979 +:102CC000E39F8EF17B85B84934DAF0F19942D8510F +:102CD000160B0F97B385DF8EF76F16E1E598CC1FC3 +:102CE00053B45DC04785AA754D053E3A3574819C45 +:102CF00015AFB7C3A02F8857435EBF8B7F52BBE38E +:102D0000DEA2BDF8CE28A7E7D607083FFB2C625EFF +:102D100088E822C6B5E3710B6B51BF49FDDAFACEE4 +:102D20001296EF2F289A067C07D29DDE8D40725AAC +:102D3000E81985E67759B227E7DEA4D6F66F782D35 +:102D4000DC9E582FA050FBA777C432BEFA76589766 +:102D50008C79FDD47E3FF4FADFC3B88DF6179BAFB4 +:102D6000DDEE5D701BF5DBAC88AAF53488F774BA2C +:102D70006438887F68BC196A82B716748B9B71B0FF +:102D80003DE1A1A283F629F4D2D4EBAF5A0E58D973 +:102D9000D7CEB390C677AAB8311FE325FC7F89FE52 +:102DA000CB9C847F9ADAC9CE5AEF44304591C43F18 +:102DB000FDA35F519BE397E339A0E37F7707ED1411 +:102DC000FAD96769E8E2051DAD0DF94C47B79CD704 +:102DD00049BBC4CB85F05010D7793AF05FE27078E8 +:102DE00055C2678122BFFB79E2CC199534EE9B2D49 +:102DF00045A961D534EEFFE071BB8ABBA663DC3622 +:102E00007DDCCEF63ADE3DD95857171A772DBE4FE6 +:102E1000780AFC4A096ECCC4F3F05380770BB7FBF9 +:102E20005E1FAD398BD4CBCD354A703DD5BFA5E300 +:102E3000F9511BB5C3BA748AE41A1ADFCF862D5B29 +:102E40008776BFD69C3CEE8DC27BD9EA4CD043B08E +:102E5000BCCFB85B09D6123C4B7899EF4B445197E5 +:102E60001DD42EC3A7A5FA681C7F8EFBFB804C0BDC +:102E70002FE301EFD177762DE9E0BD17D0D04BE3FA +:102E8000FF2C921CE87FD278A9776ED6F1364514D4 +:102E9000F13ABD4E5471490BFE6405B59B4AFFC221 +:102EA000FA24B81FC6370DB0AF755D4F170D5CCE55 +:102EB00010EE171BE95BEFD474B8ED766A33C9D214 +:102EC000DCC5AE629DD2BACD64FCF7F311FEBF1D26 +:102ED000F3F6610578BF93E418E8BDBAFD25F1F17A +:102EE0004445E293D6ED00E081D66D9ECF12B17ECF +:102EF00046B797FC6775F7FC47EB870463427AAAED +:102F000010574A51281E3A9D2052689E0DDDD4A0CC +:102F100023137AFA4EEB0E9A6703D9130ECCDB5FBC +:102F2000DCF114D58F257D7BAF94AFF1018227F8BA +:102F300055712FF341E3D2F9F4FCF541544FED5FA5 +:102F4000A911F17904BFE2B3796B890FC79CD50E43 +:102F500024523981E47E985A5F9DB66A34EC83B17D +:102F60009D488F44E889AB7B98615A089D40A76BC8 +:102F7000747C8FCB36EB9D09D03B46FB36F40EC9F3 +:102F80005715F8BDD1A7EB9FCBC465D03FFBABF77E +:102F900088CF48BF187A6814CD30947D613D64B500 +:102FA00017CCF631DE3C76AC8F59566A0F7CBBB538 +:102FB0008E1323D6CB4BF90AE3D7438AC742F37F5C +:102FC000EB901A047EACFEF010E06FE18B0AF3E99F +:102FD000233EAD02DFFBDAD638077CD330343751DD +:102FE00050FF9F56D3407AD3FAAD760A3FAD852F76 +:102FF000ABDD0C1FA94EE3F258B587CB13D5595C56 +:10300000FF75B597E1FDBEA25FE07BB3567C63D54B +:10301000B2D17F15DB478B6AAC02F45A14BF50C2A1 +:1030200036A71B42F8EECE072D7104DF1D54BCD02D +:103030008BF3770497C34C2BADF7DB5D042FEA9C31 +:103040003CCA85F60F28CCF5730E551DC474BF7E9F +:10305000EFD3EBC68BD6F9969F5584464B2E7B80DB +:103060007F39FAFFAA7A108FEB68B59FC7E5AF6F7B +:103070003AD88EBE77BC7A2CC3FFEE2B5A09BEF528 +:103080008B6FD88E18BFA5C90A3B638C5FF183CEC6 +:10309000C3FD2218247CADB149BDB286F40AE4C058 +:1030A000C87E931EBD5540EE6B0FA29F6B93678F3A +:1030B00081BD3A615031DBAFD7FF20D87E35F8FFB4 +:1030C00062EBC8231ABECEA0FE4E06247E5A76BC02 +:1030D000CB708B95F04333DEBBA3B454907DD0729C +:1030E000F61DF99CDAB19DBA53B65B6893ED16EE06 +:1030F000FC75323F57946611A1EF8E131D05E12137 +:10310000CE99F1E8E7849FE35B7F91A645F0D7F184 +:10311000E4D0B71F414EFEBBC5BB9EF954FBEC7912 +:10312000C8D1A56E96335FDB425F3E0C39DB99F464 +:103130002AD757C54D223EABB00B8DF94E687D01A5 +:103140001F8F15338B5CB23F4F6FF91CFCD86BDBC4 +:1031500043DD7EE969ED6F73E8E68F1E061DB67DDF +:103160009C70198DB78F2A422AE62FE438021B6221 +:10317000B99FB267EE49F613FC94225A54E6F72041 +:10318000F3F3AF6D622AFACD52ACF6C5C9E457DD50 +:10319000B73B03F3EEAD8A2A95D6E5ECDF3C97F119 +:1031A0001CBDF724C92295C6FF82CDFBF51E7CF716 +:1031B000511A3FF5FBE47DE539908725FF32FF3258 +:1031C000E0E18F105A4487DFEDDECEF602F1A477FE +:1031D00014C9B57EAB5F5A924EED2F5FDB64E948B0 +:1031E000A56F83528BB274CBF6776AA8BF5CB7A584 +:1031F0000AF6EBC73E0F8F2B27B46EBD023DF0C31E +:10320000131DB12EB3577F53D0515CD8CEF85D97C4 +:103210000F5A8A3D2C17F8FD9DF593DFBD51C08EE6 +:10322000210B06E32DB67B59AFD1B46DC0CF8EEE26 +:10323000EBF0FE2E4B80F5556096B4734E1605FEEE +:1032400015F32FA7F60182CB7D0D4DB7537D795233 +:103250003711A0F91F092E9A86FA818A70033F154B +:103260003B1E28EC48F0C9A1C2AB50FFF3769E2E5E +:10327000647DD8996C757C6F476DEA0DD087D90550 +:103280000354AA2F5243DC9FA894FD55D66F7702B2 +:1032900026D427ABC46749F523F767785AE96369F1 +:1032A000FC4DA695BED79EF429C6BB2633905EE59D +:1032B0006AD5BF19BEA21F587EB9EF2FC677BEA030 +:1032C00071C13EBB547D69B754CDE7F1A409776065 +:1032D00070EB773B5BC2F3310F5A1DEE007D67A3A5 +:1032E000BB611AB723F8B7DCAFE6CA1900FB8AB096 +:1032F0009E22F57B2DFA754FEE027A5D6AFF0FC5AF +:10330000FD9DEDB44A4B82D791D76AE74C6D57FBD0 +:103310006223D1EB910E5A1AFAB959B79385D5EBBE +:1033200081DCBFA3833F3D87ED34D2C316D6BF9D5A +:103330007322ECE673769BF3D2F4EFEF3AF8BBE33B +:10334000FD4B6DEFD1E312E7E4F0991C931CAE8DB9 +:10335000B70B1F3DAF5DEDE038863860293B48FE76 +:10336000CA307CC2D2FABD45F1391DA01F6A8568FA +:10337000135F7B69FD6B84DB30E90D8DE4C0F0B336 +:10338000CDAAC672A2617F621EE4ADF0C77B103782 +:10339000B0082D423F467F87E85580F98D14714271 +:1033A0008BD0B37E9164C7BA15AEE44B9C77F80915 +:1033B000B3FED9F744E4BC87B67C1007138CF0D178 +:1033C00001E585E6F5A23EAF3F605E543E9F5F3467 +:1033D0002587BE3FEC2F6E2BE637CC3AB18BAF1B67 +:1033E0008FFB068C7BF85F2CE671FF106B822F75CC +:1033F000FCB729E4D8818FBFB107B1FEEA612BD0B9 +:103400003CEAE76707B1DE77D945C009BF67929DFF +:10341000EDE0FAF8403CE46ABDE20E21FEF482AD34 +:10342000619AF48B847BA30FFCFBE623E0FF1B5A1D +:10343000EC0AE2591D1DE24BD857424D141B532292 +:10344000BEDFDECD710E157A2397E0C1FAF36976FF +:103450007E5E6B13AC2703D362795CAB93AA5EEB01 +:1034600047F5AB6B32BC3472F18108AEE886FA3BAB +:103470005596E7432CEB373E08BF67621AEB99D5A8 +:1034800049E18C4AB49F7F993740FCB0EBEF2AEBBF +:103490008FD53E7F7AB20B7290E43CD179F5447FB0 +:1034A0007A6C0ACA540BE6DB91E43C3FCFA4765415 +:1034B0007E6493ED3ED4E946984E87BC7DB8A4A7C0 +:1034C00080FC599753703FE8840A27F1F3B59204C2 +:1034D00062DACD0F88DBD14E53836A26F0F29BFB74 +:1034E0007A117CC32CD58D38DDB5F3629A94FE54E5 +:1034F0006A6AD891402F4C19E38FF4D7D7E5F8EFDB +:10350000079DCB437DBA7F1EC1C7D36EEEF973C84A +:10351000874FC98F86DFBD2C557B84D7E91E1FB727 +:10352000DB43C6CD8FD0134E4F7FB6B74B0C3F3326 +:103530003C1BF8DDDBEC643BF642FC2084D77919B8 +:103540007DFF418B08819FBBEA7ABD160100D0390F +:1035500014C37C307692D3CFF12A97653DECE8C74F +:10356000895ED06F819D0EA617094AA6DF837B3B3B +:10357000B35E9AA9CBB1DAA9B1FC5EED765BD0025D +:103580003A2BC1A736E1BD1763587F96D905FB2BAF +:1035900065CFF7653ED865F7672E43BF7B1D526F39 +:1035A000277812B9FEDFDA09D4BFA0EBEBB2D870EE +:1035B000AF24A253E7F65A3DE8417C57C5CFEDF260 +:1035C000F9E160C13AAC4B41F64DDC7082857F1D5C +:1035D000E45580ECA08D5E493F8C4BABEDBC1EE307 +:1035E000D5681CA0B3B843E5F91CA6B58CF91DAE8F +:1035F000EACCE352268D4DBF99EA3F5B18C771D7DD +:10360000C34507CFC00E389CA6F2BA270975DF4024 +:10361000AA279DDB702FC195F33F7D73203DADA898 +:10362000FDB0CB1E4F2BDEA72F291F27880FA62FFB +:10363000B8738248B8F07A9D5EE6804FD9BABE85ED +:103640001DCE9D8449AE1FCBF17F8879DB73B54FCA +:10365000C00F95D9646F131F7D6D6F780C7195CF76 +:103660003CDA9FF1FCD4735F6DC273616DEEC5FCF3 +:10367000E16C2C445CA6CC22E34A0FE56A5FE03B98 +:1036800096C604A65F65C8C1F48BCB6E9072F1CE6E +:103690004BD307C7EA37EE52A89FD2D8FA0A2ED5E5 +:1036A000607FE8ABE34A3841E9CEF8D5B0AE4EB81A +:1036B000C309A08F6691F65EE9E6E879D25053110E +:1036C000771342FAA921FB101AD70212BD0FBBF1E2 +:1036D000DCDEDA3EB3958EF41DA6A3707D32E3974F +:1036E00068FF549F9C7B09EFA5497B7E3324F37CC4 +:1036F000FC45C3C67CCE1F8FBE4E8AC2095827C761 +:1037000015B94E4E0829BF029B63F478811CC7D7B8 +:10371000CF75E071A4EAEBE86B456FF79443B623ED +:10372000DE833D53FA7BC9770FDABCAC3703A44F75 +:10373000202F4BDB49B8D491E686BDD5510D586298 +:10374000C197D582D70B8D8DD7E5F16D19FCBE21C0 +:10375000D7449110906BA5DBD2D74BBB4EF79B3172 +:10376000016ABFE077B23FC090FFC79ECED0FB9703 +:10377000EB299AAED178C8CE9571AEDAF8FC0EFF7F +:1037800028BE9995F6F15A88A0076D725D07E2A5EB +:103790001E21BB256D623FEC4FD84DDFFD3ADE3E6A +:1037A000D3EFC23E85F9B9F1BD41B9D2EFEC1A456C +:1037B000F78E6AF34BB097C41382E544F43846E0C1 +:1037C0003DA2DBD34F9FA3B32AE94E8C64F09787C9 +:1037D000F1276CA0CF8776838EB766905C2F05AEFD +:1037E000BAB5E271974FCB801EF91A30E17B5712C0 +:1037F000C1D9B0B7A4FE3060831ED17CBAE4C3390E +:10380000198D904FB9D23FA88D49E82F12517609F2 +:10381000420ED4105E514F7A70665136FCE1B1F71A +:103820007F6E6B9DCF97D57E3FA9A073F09C353EF0 +:1038300027D6E7DCB53EE7AC087AD46ECE3DE4216E +:10384000BC9FD86C456452D45A83BFB92205CFD5EA +:10385000504070BD13F83EE1DAF726DACD599B945B +:10386000A346C8A7B96BC6F84B22E8D077B3992E08 +:10387000FD4266F8F23D66F8E7A4DB31BF9FFA9E91 +:103880002F6C86730F99E1DD839AD51FA19F5C96FB +:10389000A05341D9A2FE08F91E5483F033BADE5971 +:1038A00034793CC147D6CEF682CC73DF5F920FFAF3 +:1038B0009DDC79F7AE727AEF48B2C50BFFEAB80823 +:1038C000FD713CD1634EFD2ABBD583F99AF97C97F3 +:1038D00045E7DBA7651C707ED05C7FBE7CA8D1E38A +:1038E0004E222B92AFA2E94FFD5EE7A781952D9E58 +:1038F0007C3FEC9F79E388E1697C8343ABECC27544 +:1039000029FD0418AFD604114EA3F135DD1DCFF10A +:10391000972B168F129FD1F7CAADEEFC5FD23C6792 +:10392000391577C0DD1A576FDA9E5E017DBAD16D09 +:10393000F1928F23DC83AA0E66E4C19F1021B71792 +:1039400071FDBB96C3EF9F5795C0F8992F821C97C6 +:103950009FB5D4D12A1FE9BF929551E3591D514F0C +:10396000F398B7D6DC7EC1861F1D91B0E1975E51FA +:10397000BF4EC57C6FD6C7AD0626B05EBE428F5720 +:103980007C8EA6A46FB6762FDA9D8BF6AB47CA7AEB +:10399000AB53D7B37EF6F3CA5D760FCB33EBDBCBFD +:1039A000797F87D621F4C3A1F8393F87BC3BED145A +:1039B0006E870FED3586BF6C27FD42DEB7A0F6A7F8 +:1039C000D72AACD7CBDB49B8FC09258818703982D7 +:1039D000B6809F9471DA321D1FE0137FC47C40AF24 +:1039E0004858D419F1F130FBBF1555C20B3B4010BC +:1039F0001DFD06DE783F2A6C3F023D1B50420FFB47 +:103A000060EF99BF53B9E74747247C2EBE4CA4AB67 +:103A1000E1EF07198FAA5DF821C7D5BB62D96E27E0 +:103A200005100BFD6ED3ED6BB122D81EFA6A35F48A +:103A30001595CB743B3CB04AEAABD549FE5E6ED4DB +:103A4000AF4AF7020F3728BA7F0BBB3E09F6F53EA7 +:103A5000EEB75971BBD727A1BD08C4A4B07D2DFD19 +:103A600084BFABACEF9AC97E5F0F7BDD170A633C66 +:103A7000AB1FC8647BFD0543EFDD1723EDF9F3EDC4 +:103A80006EB6AFC4FDD27EFC4808E9F7F6D0BE039F +:103A9000DD67AB45BC1955B2C49F8EEF964CB25B47 +:103AA000400F31EFD2F645365A65FFCD345FC4EB97 +:103AB0003F578A0E5A22EC60679ED40FF905FE4DDF +:103AC0007A3B2FDA9558DE663C9458841BFEFCC680 +:103AD000B3AAB012BCB1CE115C42AF9474F3F75AE2 +:103AE000988DF7647CEAB04FCAFBB83CE10F52995D +:103AF0009427F555529EC5548AD132CEF2798CE482 +:103B0000C3E9A2A890F7073C52DE47CFA3B3FE9DBE +:103B1000127B83793C9FEC67BA90CE732F017F8F25 +:103B20009676C7E7B728ACCF693EBDDC04E7FF4B0C +:103B30000CC7173FD7F591815FE29F0188A31972E7 +:103B40002B49E797D5F7049F8A217CAFB211DF801C +:103B50006EC4371BF398EE6C17AE9E96CA74BF41C5 +:103B6000A7ABB82F9EE936C4629178BE2F9DF14C69 +:103B7000EDC55FF1DE188FB4E72FD10F23BA0FC860 +:103B80001B70BE3F66D05B588303FED1FE4DF9EE3D +:103B9000ADBB02C4FF0B7EFF4082A07647AD75A986 +:103BA0005E7ABF6CE3B2043F9547AC810437F57F82 +:103BB00034A88E0DB681EF453A3F60FF4049C5BE3F +:103BC000AB94E3C79EFEDBF23B689CDF2AA219F2AE +:103BD000B162C7F7CBEFA0F91DF43B9B214F8F5883 +:103BE0001B0B2177E717BBAA6ABC58BFE638FE82D9 +:103BF000271F48F530BE031996345EFF1978AF626F +:103C000083CD0BBFAEE23DD5EBC1BA17CDCB31BEF4 +:103C1000E8F72B439FD9817FB74534771AD246BD49 +:103C20006864395FB9E3D7DFA809288F7E04FFA253 +:103C3000326AFF609EBEBF12BD8F303BCF9CC74033 +:103C4000F8E13C86008DAB27B38B8C3BD73EF5501B +:103C5000FF26D80D1B5E4B50B25BF70F8C7D9796FD +:103C6000D0ECC79FF75C785D7EADC78D5BE926E53C +:103C700098670F0DAC83408081CB325B3801F67EB4 +:103C8000D93A1BCB91B2AD4F6C7A18FCF6A1C3DBCD +:103C9000D303F8B41DF2A04CF1372B2CDF458292F0 +:103CA000DF4AAFD2AD5F143E02FB3A5D15E3885E9A +:103CB0000B9E3D23DBFB45730CB52FDDDE5408FF67 +:103CC000A04C735539DBA0D7A8D04BF646571BF450 +:103CD0000A3515729CEAA9EF981E47F72AA243E617 +:103CE000F9EFCF5BF7855D48FFA0B95D92C417F48B +:103CF0005D65482DB6279EDF9EBE3FE1F93CAE775D +:103D0000C35FB9181D4701178813EC8E1749D0DB24 +:103D10001F3982E340DF6D8B1204F1FF57D62AC9A9 +:103D2000F78F2E4B859D37CF16487573299FCF7B14 +:103D3000EC36E6C7B94A55AA3B9BF93DDD3288E728 +:103D40009B8E79DEBCF65A9EE71CA1313FCE7B5498 +:103D50002D0A5279C62AC66E6F63DD9CD4E5944362 +:103D6000DCD21FEBE40C7D097AFC2BDDAF0FBC230A +:103D7000FD6987989418B99FB457978B01113C0C33 +:103D80003D50D960E33885FAF699427CE7D64C6B12 +:103D900015F23D68FE011D5FCA8FD27FF120EFA1B1 +:103DA00012FF227D3AEAED311D1AB3F1FD16FB4DEB +:103DB000D4EF5FE0277A4DEF31DEBE5AEF88552E03 +:103DC000A73255DAEFD1F3E8344031ECB877440448 +:103DD0003F556EFE8AF949A4A922314DC2D8BF7061 +:103DE000CF72552512DEFEF2DE6776C4BF032916B8 +:103DF000D113E36DF88261E16DEF417BE3FB957BCD +:103E00001C221CB96E377C11B5AECDF54254313E43 +:103E10002B45A207FAFB2B7B73E10BE887FADD4801 +:103E2000FDCC21FB2B6CB2AF9A0B1F813CD9637781 +:103E300073FC81ECCF7004DF9CDB1FD5F705E7EA4C +:103E4000F2201A0FD1F2E1AB28F960BC2FD6B6BD33 +:103E50001FD52A17022C4FCB6C22003BA3EC430743 +:103E6000EB8FB2AD723D0A92A73D697D1CDFB2FFB8 +:103E70008F37C09F0DD952C671AF66F93BEF992FAE +:103E8000785EB309FF315EC8DFEFECF07FD346897F +:103E90006607F68B57FAECE0FBF3D6313D6F731DE6 +:103EA000AF5458BEFD57E52EE1DB0E7BEB62EB75A0 +:103EB000EE05E46EF20073DED019919D380495EEA4 +:103EC000E2AEBC7F10855F03AFD172F4E93C4F9B3B +:103ED0007294FEFC5144E0518846E6E36F492E623D +:103EE0001FAE62C3F7ACD708ADCD0EE2E38AE03770 +:103EF0000C2F835E63F8A52988579E3F6F333EA33E +:103F0000EBDF03EFD3D08B9EB3B15D50562FF31C84 +:103F1000E93DF63B2A11AFE7D67507335222E1603F +:103F2000141C8A6AEF8F828BA2DA6B517095A97D7F +:103F3000D99EFDEC67D1B84DED1C8BAF613FE47CA1 +:103F4000BB22C878ADDCF18D3D00FEE8D46C875C07 +:103F5000B42D1181787ABFF94595EDDE539EE604C4 +:103F6000D829CB62A41D77CAADC349062C6616D3E7 +:103F7000384E05FABB9157D01C23E32DA78A9A131C +:103F80009222FCF6A67A35C143ED1B83626CDB7985 +:103F900031B58CD74671A17A69CF8D517FD826F380 +:103FA00045ADC241FD35D67CB70DF1A4CFC97F82A6 +:103FB000FD5252737D02F65F4ED577FFD954F881DA +:103FC000AFAA9CF325027E3BF226664B528A23223F +:103FD000F0E0509A9F1A9F77F005F857C428D8FF51 +:103FE0002C591965DF88A2C430FCE9D5D1F90D41FF +:103FF0003BEC9BB9A467218FE6AD35D72FA83FCE08 +:10400000EB6541D47AD1F4B871F47A596CAC179F4E +:10401000F0E9F9969CD777EA90CAFCD5B2D42696F7 +:10402000A7C8BC5AE4A3B4D4CB7C9D963D1216011C +:104030003D0F485FB706DE4E603DF5BEB0DD7262F3 +:10404000E7BFE7FF12FCB3EBE3FE8F507962D7873F +:10405000BD5E00BCFB4F5D3E16E7B71FB5F7FB1911 +:104060003CAEBD0E81719DDAFB4A17D81BA79E7727 +:10407000703EC2A9250EB6D7037BE3396E71AAB391 +:10408000B4876B5FFCAE7F23EBE3A54CC72706D854 +:10409000A55D55FF37D68F2DF50E0FE651B9378E3A +:1040A000D755E5F331BCAF76EAC5EFF223E371FFF4 +:1040B000D5F918FBF0A7E2C5D467C0BFBAFD5FF918 +:1040C000C2E0276AE02FEF78C93E1B79257FF88F81 +:1040D000FE90AFA79E7989E5EFD7B6C6C710DBDCA7 +:1040E000B6F3C0C3B674C4F5E8631D85B87297F51E +:1040F00046AC9FF3F122F1708AF08079115EE6C13F +:104100002EBF103E5EFEA7C5C73733A49C1B28B048 +:10411000EFD38A17C52F9FC773BC8AE62F9FEFFD89 +:10412000AE3FE4D0C5E6FB19E6DBFEFFCE7C95FC96 +:104130007FD6F94A7EBF678087C719CDF7E7F3F5C9 +:10414000EE9F33BC2DDECBE3BDC4F59E99FF7F8B84 +:10415000BF47FCD3CEF762F47E55A777BC1BFBA00C +:10416000A75EFC8F2EE227CC7BC6FF523E37ECF9D0 +:1041700002D57BC847ED5F13A1F7BC996C95B46974 +:104180008FFC3ADF88A7487F6A14FEE541FB9CA5B7 +:1041900021AC07B227E0C7D4BA720EBC4DF02B6435 +:1041A00027A8BC2F2BE349AFA4F98232BE5B2510B0 +:1041B000CF2AF8D36C865FF75D7900792585AA8CC4 +:1041C000C7ECAFF16E68A079EC4FB2786A091EDDDA +:1041D00069F6E7DBA9DEDD5175C33FABED94EBF487 +:1041E000448C6FB4CBEC675D13E5275DE531D78F69 +:1041F00015CFA460BF6E6CB64DE07C4E21DA47F857 +:1042000095F3F3DD3CCFAB44DD52B7EBA7E3E939DF +:104210003DAF92F0C2FB36814EAA9E1767C69B0047 +:10422000DE5280975CB6DF03C27BE06D82ADBA7D63 +:1042300025F4FDC74267FC26F8D10E51100E127C02 +:10424000C663AD427BAB207F58CE93FDE868BC09C6 +:10425000DDAFB6EA2418DD69541878C6F3AE69A656 +:10426000F779DED178FEE978DDD76911F09A16EF9B +:104270000D822F3A3D9B82386B2DE159515AF169DD +:10428000E0291AEFBFA1B14A7F5DE2BB93D567C5B4 +:104290003A1BA6DBF3A3AD4912EED4A016F1FA0B3C +:1042A0004ABEFE8BD70A7B64A42B89F349857ECE58 +:1042B00042D5F7C39161C7E320FF1479B913ADDA92 +:1042C000ABF99C8FEF1605F05B0B4408F15BA5FE84 +:1042D00095EFE11FE17C4911EF6B1EFC00706FA7A9 +:1042E0002B0C7F50ACB59E38672723EE1F75BE623E +:1042F000C2A0ED2341AF598BE919E2586ECF41AC12 +:10430000C7E2FB1D1ED0AF93B581EBC9D772D70CA6 +:10431000C66E7588E1D812B2F4D3D1EE9591DC7EE9 +:1043200091702B4948B70B29805D6E99AF46CEEB53 +:10433000B780ED4BE33DB5326E22C04F3D5076C3A2 +:10434000F765FBB4D1F43DE4BB098DEDE5D81E1C47 +:104350000912DD9422DE7FEFDA5DE645342F73B07B +:10436000BF537C77E75E904BE30ACC71EBA103650A +:104370003CC7289F1A28E5886AF1A6E13BB396F668 +:1043800061FF4B8D2D2ADF093C6E8B633E2F5E7ED5 +:10439000D3F801F4FDE26DEDBC18E6B109DBF3657D +:1043A000FB69B7BD4FCFB5CD31FCFCF581DAF7F92C +:1043B000C833503C3376D28359D7EEB7A751175A3A +:1043C00068E249C41D2704B6BF897DCE0953546EE7 +:1043D0003F41CFFF144BE378DF7C7CE01B6B1A7D01 +:1043E0006F3C3935A86F8A7177B985C65FACC79BBA +:1043F0006D03E53A546385F68C0BE3EADCAB1B3DB9 +:104400001F2F643E74F4BA1DA9B7EF3ACAEB4901F5 +:104410007E9418F7FABCD6F6F80EBE7BA58E0FF781 +:1044200040B9EF6BC084578E8B97AC7034754F409A +:10443000690BF7A6B27A7041CA40AA1FD74D14AED5 +:10444000C1776F57C57A1E6F7331C7D9E3B33CA0EC +:104450008326EA38DF48ACEEC9FB394D2305F34F1C +:10446000D3AA4C83DE9C9F64F8734D23BD0791BF94 +:10447000D53CD2E95DEF457E4B288C38CAE13572D8 +:10448000BFA66B6DB807E46CB34FEE837CB138D731 +:10449000033EB9F981C909909FB357AB6107F87D15 +:1044A000A5396F49B8BD9C373EBB6EA41DFE6B8914 +:1044B000CB6FC7BCAE1AA4790742FEEBE7222FC32D +:1044C0009870EEA7AEF875F87D6A02AD67AC3FABA9 +:1044D00027017E7574DE53A59EDF64C0CB52B5C143 +:1044E000F8DEAC44CF363E5FB9B83BC7556F1F28E6 +:1044F000E5AFB0867B003F8FD15AC0FA3C912FF9CF +:104500006F5CB2BB978BF93746605E4D36772FF004 +:1045100073D3B2180BF0346E89E4E37BAC727D0583 +:10452000FD1E4B80DE8FD1F9777A8DB5681DF5D3EE +:10453000C929ACF1C9C85BD3DC18C7F840CD61F814 +:10454000D7B3757D357BA53C3FD67594A4ABB0360B +:104550008C6E47CF8F6CCCCC415EBCC137F5830BE2 +:104560008A0646D07F5C81BFB03D7D679CC5D30283 +:10457000395C324579A9BBE4836B07B23F5FCFEB6F +:10458000BC85E4842309E7061B248C7C55C88DBABE +:1045900087FCCE08BFDD2E7670BDBD44E6A376B5A0 +:1045A000876B38FFEA16E15E42F026B223AC362173 +:1045B00036573BB97CBA9AE45D4F21B654A731BC5B +:1045C000ADDAC365A83A8B9F3F53ED657847F52078 +:1045D000867755FB19DE533D96CBE7AB8BF879B464 +:1045E000FC99ED9AC3F2C4DD8B683DF87CBE99E17D +:1045F000A17141FE3885FB6EE4D30A29EF92B2A483 +:10460000FC11BA3CEAD647F0F99BDB410FC2BB6D07 +:10461000C5480B9FF7B436A683EFC6A827B6EE466B +:10462000BC639E8BF3B25A4423AF931661F106F23A +:10463000A4FC7110DF75BD6B6C66649EFA8DF3147B +:10464000618DE0AF9BAA628435423FCD5C9C648261 +:10465000A72F7EF7E50EF4FD3EDDB47B41FFC37767 +:104660007DF9E89FE8F9E3771DEB29CFF5FEB02E41 +:1046700032EED2229A256C75F27EFCE377A4A7B6BF +:10468000EB26BF077ACDC23F3CA04FF3D127B10E36 +:1046900097A9DE25047F04FA103E3FD1E953BCAC54 +:1046A000FBF25F605DFB9D5E85BE73F88EBE858309 +:1046B000A8FDE3FA7E945841788DD43369527F7D0A +:1046C0000AFD9524F55901E46858EAAD4F7F951A23 +:1046D000B81BF5B724787102425BD1213097E09581 +:1046E0003EBB57455CAF5E2C47DC86702CED8A8064 +:1046F000CDACC71A3B25211E6C9C938ECB0B3AF98F +:104700009C167584FD985959FB443AE4529DE2C6C3 +:104710007E0DCE753A9321DF14DE1F451ED014D2D4 +:1047200097CF0E54797D9DCAB772790D92E508AF87 +:1047300031C2CBF1999295D41EF2B1CE679F13216D +:104740007F67E9CF676759B8349EEFD3BFD77185CC +:104750006F2AF8A323EAB351E64CC5F83ABA0AAD7A +:104760004AC4FE6FFD402BF7772A5FF67B0D884A1F +:10477000EFDF9BD5CD7E73369FCF62BD65F4332BC3 +:104780002B677937E8EB9523811D516BF3A6A55074 +:10479000BB97075AF579E8E7C29D323FBBEC027A36 +:1047A000C388D31DC13FE539499EEF826DBFDB86CB +:1047B00073120B3E76B0FE5A70B9D44B223B983F31 +:1047C00099039AE6B8F8E8DF9D3C78378DE724CE68 +:1047D0003121DEBFE3333BF24369D95425A60356AA +:1047E0009B90671A1D9F3DB0EDE38436E3E23BD416 +:1047F0004B8B8B2B3F24402F18F319F3E29954D89D +:104800005995CA59DE67AA7C9124751BF38E8E8B4D +:104810009F8B9F8B95DFA88833DF79A4CDF87974BF +:104820001CF0FB81D1FB11AE02C8893387D420F67E +:10483000D35B823D13451BFD1BF1F3CA35F4523B9C +:10484000AC4B4F22F6C34E5DC02E1F3E48FA2F27B9 +:10485000F578FBA92D2AFB4BA7B6C407619F566CC0 +:10486000B9FF20F6292B36286C9E978B06C617E1D8 +:10487000513823F518F2DDDAC1B8F624425E19E3A7 +:104880002BFD5D7C15F86A7E48F16FA471B4383D4C +:1048900089ED23C6D17190E4CF5247289FF1AA8FAA +:1048A000DB3D48CA41A3DDFCFAFB392E4DEDBE6667 +:1048B0007BE7F77182F30445F39B18DFF1B5B95E2E +:1048C000EC2BCE0F6DAFE0FC8E2D716EC4218EE906 +:1048D00079CEC6777AE9FDF51A24ED94E3FAFEDD88 +:1048E000F16DF27C3AC689F5744C31E70B66EBEF5B +:1048F00065EBF87A475FC746FBF9A1A6841ED4FE94 +:10490000AB3DEF72993F48AE97F9AE86FED0BB5FE4 +:10491000ED88E3FDF8AF763C528838F3C9D0C8146F +:10492000F0FF397F6D904DD261AD3A16F812419982 +:1049300067530EBCE6468EB3DDBA4066E43A93F99F +:1049400046C7773C9B60C96EA563B9B3CA89F3A11A +:10495000953B6E29021F1FB4497CDA774C0CE0D8D6 +:104960007365BD4F807F799DA573FB159688760E84 +:104970009B97ED62DB9E623FDA1B71E8853B6D7CA5 +:10498000BE70C6E59EEB6FC43A7CCDC67458D8C7DE +:10499000733DE72335A89CBFBC305384617F2CBA9C +:1049A0003D7E1DF6C38CF1CEC895EBBD6C8522FC17 +:1049B00034AFB2A02A342A3B12DD03C8514A6B1C23 +:1049C00080FCC9A6CCE03DBD52F8BC6F787D4A6B37 +:1049D0009E29ADE35E3817593E2899E7FDE0B442C1 +:1049E000D67787ED2200B9107846E6E1947593F901 +:1049F000D10F83EFD15F72B8573B9AEF099DAE6537 +:104A000093C2BD909751F64C3AE7659CB0CBFD52EE +:104A10003CC77E71590EBD4FED52F47C5EBC9F14B5 +:104A2000C14765B3BC1EB45393BD1E9F0BE3757F96 +:104A3000CD76EBCE7801BBD5B23B5ECFAF8AE13C01 +:104A400072E3BD9A41D22E4ED1E9296E90F9980FAA +:104A5000DA64BEEA831BD3F97E0CA3FD83366D1A9C +:104A6000EC27CC03F6FA7C7B5D2FECBB18E39D9F13 +:104A700050C7E33CA1F3F9FCD83A9917AE9F3B46E7 +:104A80007BC04D7A1E7BF3530ECE5F3996DEF02D40 +:104A9000C67BECA93EC88101BEE7ECE17AB21F8972 +:104AA0009E0B9E7684517FF42919B73E6A0B7E0BCC +:104AB000397CF4D1767C3EEA68FB603EE707286EDD +:104AC0000BECB3A38A0EDBDC6C5776B5134CED53BD +:104AD000628505F93B6327AD9981FC86960D0EB082 +:104AE000A738B6E9A154F66B842791F36C0EA9029E +:104AF000743BF6F4DFFA44DA2F46B9608339EFAE3F +:104B00002953DA9546FD3A7D5DAED3D7F5C64152BD +:104B10004F95C7851EECC6F393F826FAB07F470A77 +:104B20003E9EF327B6F65420371E16C19F7F9CC7C2 +:104B30005EB60779F365CF3CF526F66B8F594403D3 +:104B4000EC0FE5AECD3FC7FD1C29BF49643D24C431 +:104B5000069EDF51B73CD74A0B96E73FBF838417C9 +:104B60004CDEDC0BF041D2390AADAF051685FB5F98 +:104B7000B0AB1FE7DB113D2CBC4FB65DD5C743364C +:104B800025F0B749E62B8F4B0E6E82BDD7FC6877B8 +:104B900081F3EE63D4B5FD41BFD31BE22CE0A7F255 +:104BA000BB87240E01DEDE5205EC8FD3566F87C81B +:104BB000384234BEA2F3C0BFD5E55319AD3B9CFFCC +:104BC0002CDDF528DF2F520ABE045E9E56781FBBEF +:104BD00074F99087984FDFB4899ED4EF89D0FD098E +:104BE00091F469D4E5E2B9EFD8BDDCBE94DACBF735 +:104BF0005F4BE0716EB2715E4B345D2FF9FDA7D54E +:104C00004B7AFFDCFC436417F43F1F0FA745C3CF6B +:104C10003FA6EFFF654B0CFB83E401F039B6E3B62A +:104C2000D01CCCFBF8D618965FC793A49CF88AE4F6 +:104C300069A037C671CD6F994FDF99CCE7FDE606C5 +:104C4000CDDF35FAFD02721C7CD7CE9B08BFB3FCCA +:104C50002D290F895E3FE3F7DFB2F1FBD1F338A0D6 +:104C6000BF776E9D6E8D63BE38DE51D2E3F8B6DE3F +:104C7000AC9F9A92DC82F9E6299BACB785BAC00E4C +:104C80003EBEB5B7AF36E2BBC793425DDC11CF9BEA +:104C90006CC1E503A53C6D865F2CC2246AF3915F6D +:104CA0002458CE1BEF953A5736C04E417E6F7E0E8C +:104CB000976147F2F979BAE392A53F396CB08C0F4E +:104CC00070CE6AAA9E4FCE764FC80E39AEE9F66115 +:104CD000D996E83C5F59DFC9789FD65D8A91576CB9 +:104CE000C17843F6348E3708CF3334DED2A5B7CC43 +:104CF00047FE7869D5AA1B613F955AC5583B8DABD5 +:104D00004951791C4D3162E624D89191FD44D86F08 +:104D1000BD079F8BD30A772ADBAD6CDCF71D2CF522 +:104D20001DE03AFA5ED9526525BE6FC8170E14A66B +:104D3000B6E20979ADC8EF691AA9D75F60DE4D36D2 +:104D4000591F3D6F633C23064B39D594E9F9ED506B +:104D5000D0E50D95CF779DFE213731B90D3BAD558F +:104D6000DFDB5BF36C69FCE3605BD377DC83A5BCC2 +:104D70002BA5F1619CBDD69AF3CAB33698E1CBB6A8 +:104D800098E1EC1D66B87FBD19F61E30C3797ABF75 +:104D9000F0B3716E197E364AF8D91E87F4B301C399 +:104DA000CF46093F1BCFE16703869F0D187E366013 +:104DB00003DFF0B701C3DF46FDAF743C097F381550 +:104DC000F99A151699E74BF4F0F339A66976D3B939 +:104DD00094532FCA7329C40F52DECF77F13A791852 +:104DE0002D06432FC9F594F2BC23B884DE1BE1D114 +:104DF000E60EC67A5DF3CD1CF05D45B746CE7B6D01 +:104E00005AF64AAFFBA95DA3122F605754ACF9665E +:104E100006ECA8248F568EF695B10DCB0772DC3EBA +:104E2000CCF2A3B1C6F3D60849478EBF14ABB8295C +:104E300083EAE725B7993F149D772E569AF3CC2F36 +:104E400096771ECD07861DF8B8AD39DDCD7EFAD038 +:104E5000C710E75DA8C4BBE1A77F162396E0FEA0BC +:104E6000C0AB324FADE5904DE60DAC54D68B08FB90 +:104E7000E4D73ABE0D78F6D95CB6C7CFC12B158BF7 +:104E8000B85C881E5A7313FCEBD3F32C6C779F9E8F +:104E90005750D81EF61FF9655813B89F2B72BCB82F +:104EA0009F2B927F703F97F9DC4447537BDCCF65A3 +:104EB0003E377199A97EF2CA5C537D49D110537D6A +:104EC0000F21C7B768BE1C5F09E9077F3BC04B389D +:104ED0006F71116847764A1725B09CE5F23A85CF85 +:104EE0008D7B16AF28045E4E103B238E60F0CD6C98 +:104EF0005DBF086BC00EBE3B9322EB8F2A0D5FDEB9 +:104F00004DEF9DF4D56DC2D529272D6B1F1CEA41AD +:104F10007EFDBA2E6E5A87B72AA154889E3579DA5B +:104F2000AEC1ED919FD23891F713B7B74FAE81DD87 +:104F30007968C09B83D0DF1695F3260C7EE96293D7 +:104F400071BA75838866644FACAB93F9BCEBEADA4F +:104F5000C5F688D87F31E6D9023A08944B525338C7 +:104F60002E241A300FB2DB97C06E3B7D48DAEDC6B7 +:104F70007C7A2C0D775A44F5B76E8F61FC7CAEFBC2 +:104F80000D27FABCD4DF83F31BD57BBAA8B0072C5E +:104F90005B36C18F70A4686F82EFE7ADEBF927DC59 +:104FA000EFB5E07D55E03CCD17AB47250CA6EF1CD7 +:104FB000DB6AF38E23F8EEBA27ECF093175883766A +:104FC000CEC37C6A9D1D79C9576E5EC7CFE76C2E34 +:104FD000E6BCCBB9A28AFDC823FAB92C63DEF30A7A +:104FE00094B56EE22FEF15920FE7C5CAFD3CE2E7DC +:104FF0009731AFD39B151FECC72945DBEDC5D0CF4B +:105000003ABF7AA64E1D03FE6B09C9FB395A5E579B +:10501000E5BD63535499177381FB7C269FCD64FED5 +:105020009E72B62FFB59D786FB483F365BCA8F96D8 +:105030007A95F7E35A5EDF9F3219DFABB7F1EEDD09 +:105040003C7B833CFF6F11553847E099DA20F92A01 +:105050005354C1FE5BF4C6BB07B1EE16653A3D582A +:105060000F454355137F568E8E33F1EF54916C3AB2 +:1050700047731D924A22E029E3BA9BDA5F3FA56F8E +:10508000943CC869AD67797045D439C002135C4E51 +:10509000E59D904FE26AD37BE562526B3BF8C31B00 +:1050A000A4DD5ABE23693DF6C5E759A43F345593A4 +:1050B000CF2BF6C8E742C49E3B978EF3F8880F9833 +:1050C000CE6DEBFB7CE897E381DD1B38AED39C4EC5 +:1050D000F292305A9ED568473C8DCCE566C449CBE8 +:1050E0000304A35FBF68AEC5F911ABC4AFCBEBEE51 +:1050F000B624BD952F2A7698F3AD2A0EBDCBED8C44 +:105100007CC6E87AB2D39777C4B8C7293E3E37B990 +:10511000A5C98E78D014AD13DF4B117D5F5A59A805 +:1051200089C779ED9E5437F66D2BA2EE495B7885E1 +:1051300047EA273DFE8F7B86A49DD06097715BD7A1 +:105140003E0BAF3F792FCF39BE9C6791F70544E105 +:10515000659CEF7DEEAF63BACC43035EAC117889FA +:10516000E623E0C91A81A73942E2690E499320C1BA +:105170001DC16791F8F989F89A8B7F50FDDC3D4A93 +:1051800010F96FD1F899A33532FEE668AEAAA0FBFC +:10519000FCF954DCF9C141C8A76DE9F25EC368FCB3 +:1051A000CD150DCBE1F7CE25BD114E62BEB03BD97A +:1051B0004F53BCD0DB9E418D769B94671CE76D7985 +:1051C000FD5D5E772D5E5AD5E00B41F5D4DEE5F747 +:1051D000342F6923CF77D259193FB9EEAC95CB293B +:1051E000E3CCEBEEDAB3A9FCFCA7E2A50278069FBC +:1051F00023AE97D0C63D7B88F3259C3F5F633FC4B9 +:1052000090C3AD769D396FF942F65F749CF0AE2B7A +:10521000F47CC1016280296FF902764774DEB2A185 +:10522000C75B5C524F8E51B3DFF2D0BC8B5F55D958 +:105230004FF74C1D6BE1F3E3AFCAFBF1B465679A1E +:10524000C09F5ABC85E5E0C2F86E7CAF85A6C7ED6D +:105250008C7EBAD4B44B45FCAF38C6CDF9F8C53511 +:105260006A11F45731B5F344B45BBEB47B17E885DB +:105270004FEFE9FD5880D6CBA7B7A7A422EEFFD900 +:10528000325B0A49CE73ED3E5D36A60BF2333E5BD0 +:10529000E5981A6C033F9B747D517ED707ACB74EDF +:1052A0005A5E4F984AEF972DDB9980B4FFD265EF95 +:1052B000E6BBC9A4B8224FDB7805EFAFAEDBE4064E +:1052C000BEDCEBF83E815D242EF17EF1B2654CF739 +:1052D000058ADCAFBE55097F3982DA9D8859953041 +:1052E0003513B7A10ACED338B3215E3F8F56C379A9 +:1052F000432762C91EA0F64762243E8F6C8FF7F2E7 +:105300009D18DE4017F6DFDACBFD9D524BFD751878 +:10531000CF5529DAAE2B06601CC14D692AB7E3735D +:10532000EB5A4DCFC4B6E21FE7E6A9EB69D8DB28FC +:10533000616F235F06F63660D8DB28616FE379E59D +:105340001AB3FDD6A0EF171AF1E0AEB5CD3ED8BB2B +:1053500081029155C57A765CC1BF426FBD2AED8549 +:10536000458A774523DB4BF175F03B6BADD2CE0E12 +:105370007C22CF45D19F2CC8A75FA89779B19FFF0A +:1053800050DC5D8FA3FD62EC0FE5E1DE53B2BD2280 +:10539000F875C459A7883C773B928CB04878943311 +:1053A000DDD47E8C3BD3547F655A1F53FD551E9F21 +:1053B00009BE266BB0A9FD78EF4813FCB34157999D +:1053C000DA4FF44F34C193C74E33B5BFB6A8D854A3 +:1053D0007FFDD4F9A6FA69DA2D26F8C679B79BDAEB +:1053E000DF545563AA17A2EA49E0C71F90F7B0D56A +:1053F000C37F72E0FE17279754FF7BE4318F24515F +:10540000CFF7AEBC71DBE380F721AF9956DCD0510A +:1054100096AAB6E2F8B62132AEA80DF5FF7805FBE4 +:10542000B90D7C8F2662B7E0BB94211EDDCF96CFED +:105430003B598DB855433ADF9710D5FE42ED86C6ED +:10544000ED3BED2196BBF385C76EB20E461EC4BE82 +:10545000DCEE04EF1DD2749395E4CDD021FB9EEDDC +:1054600046F0C117FACC60F8F27DA7513FA5FE0BBC +:10547000593F59B069D230E4DE9B02C47743477488 +:105480005BE995719136CFB71B25F08473E1C013AA +:10549000CA30F13DCA7DC4F7280F10DF97905C3BFE +:1054A000487C8FF210F99978FE6FE467A27C9DFC2E +:1054B0004C946F927F89B281FC4B94EF544FE5F28C +:1054C000BD6A8DDFFB63F53C2E3FA8AEE2E71F55BA +:1054D0002FE6F293EA003FBF7C888C23B848EF4068 +:1054E000BF57200F06F902D1F72C57B9F9FE835A9E +:1054F0005D6F897A3DAF661FF9AFC067A335E94B91 +:1055000067EBFEE285FD7DABF832C26E9B68F50F5E +:1055100019C2F4EDE4E6FD21FDF90B5ECD3F84E810 +:10552000FB7EE6E49EB92AF45DD5CB8954F7BEA58F +:10553000EDFB2753747EF10DF58FC17BC39C8779FA +:105540003FDD934ED6EA108615D05FC991F1CB614D +:10555000D6865AD4D77E2F3CF09B5F8AFF23EF83F9 +:10556000D792B98CF3C7CA59E9AF0CD7F7EF6BBF25 +:1055700097FBF7C33176AA1FE696F5B53793A6F3E6 +:10558000A13EC4DF1F8ED3CEF27C9B296F67F4D976 +:1055900086515CEFB27B906F3ADC1996DF730A3765 +:1055A000E2CB2FC5EF92FD8F91FD6FF83ECCDF87E8 +:1055B000F7691B8CF1B78E67098FAF41DE4F972DCE +:1055C000DBD7EAED876BD47F12C65725C7574CED62 +:1055D000E5F859CE0DC73793E06DCBFAD834793E54 +:1055E00079F459BDDE2BE7DBC12A619C29417D4658 +:1055F0003B4DF8A9BF8C0CE145FC6D784A433AB7A6 +:10560000D7F319E2ADF27B895E791F578FBF6A72BB +:105610003F801080F11B7949C6BAED9C1C4E879DD6 +:10562000D779A19DBF97A16EF7415EE7F8B400E876 +:1056300067755A787EB57E795EFEED173D9D711FC8 +:10564000E944DD5EFF07F45F26E9BF57D21F97BC30 +:1056500065B4C2CA1CFA6F709BF497F8227EC1FC35 +:1056600089FE4C0FD053A7BF62E047A7FF397A2DC0 +:1056700089ACD7F9E37CFA8724BD757E1AEE94795C +:1056800013680FFA0FB34A7EA88D91F91E2FC51724 +:105690003E8C7BB208374588CF0F33F8A54A9E1F52 +:1056A000FEDF4AFF3CABBC47CE51E6E47BEA2EC6A8 +:1056B0000F339B4521EEE93CEBD35220278ACF7A6A +:1056C0000E029E2D4616C23C37EA959CB6EBB5BF3E +:1056D00034DB001BCFB3D06E406BBDD5F94E1CE45C +:1056E0009EF11DA3DD95E7B5CB71425F2C1A135ACD +:1056F0000BFD35B6C6CA716BB24C183E44FA4CE687 +:1057000073FA137CA991F99FDE030BF370BFA83CD9 +:10571000BF255CD2AEF6D05FC8D5C21F8A96A23F25 +:10572000A16EB1C2EF38837C5AFA4E618AD93E1F0E +:105730001BB5BF7E75F6576C8F5F7D917BAE8F0C6E +:10574000D1F7DD3345E67FF29ED1E621AC672FED40 +:105750009ED12C51CF7C30BA58E673D1FC2D3988BC +:10576000DBF84515E0425165051F8C157556E95764 +:10577000FA4F54E4B1D7CEF8B94684F9F9785228F3 +:1057800050263F23F601BC3F6EC274DC1F3C2A77D3 +:10579000540F3C8FB83FCF36B43DDF9FF76777C4D7 +:1057A000FD79FB46CBF5B6F05A196FDAE7ECDEA6C9 +:1057B0001DFA2AE9DB1E3D8117C1E5CBA48F7BD002 +:1057C000BC5F217D0CF8EAAC1A81F70A3DE6BC23E8 +:1057D000E3FD6BDCA384B5DD85F5DD35FD9FEB04D2 +:1057E0003CBF96D47B34E8F55AD2C0D188C7BF9667 +:1057F000D4C1224B879DCB7EBB7BB4353E637DB449 +:10580000F657C8FD19F7058F6E2FEF0B8EC6EBD537 +:105810002264C2EF381DBF3F01AFDEB6F09A82C3EB +:105820008EED81CF77771979538827F758DAC0F052 +:10583000AD36B90ECA778F2F405EF4C2F7657EC7CA +:10584000510C057A77F1101EFFF0C583853597F767 +:10585000A302C0779953E2F164E0A5FEB8D73CDC1F +:105860004E1B89FEBF5AABF279FB93CFC4703CEE5E +:1058700048F0D904E0D3E0E332D5B3D28B75F89A7F +:105880002AEF59FA617F17DC437A21BE267EBE7A61 +:10589000685BFCEC227EEE773E3F8B0DF21E83327E +:1058A00067619B7436FCCEA41C3FCB1FB708DF0298 +:1058B000FEAF10D23FAA70BE2EEFA92418E75EA358 +:1058C000EDAAFC586A4FF576A7CC1736E89DE19013 +:1058D000F75866C40937E22042CBBD0CE3FDB4BBE8 +:1058E000BF187821BF764B64DEDAF0705FDE771E7A +:1058F0007B48E57CF75762E5BDEF8D440F85ECD31F +:105900002BFB56B9BA111DE7E66B65785FA83FA877 +:10591000E8F7F59E8A68C7F1F35C17FBD93FD15FC2 +:10592000BF75A8EEAFF717FDFFE1EF29B497F70EAB +:105930002F7C353788712FAC21AD96C2BF8BC1F754 +:10594000C4D5C23FCF6C953BC3452FFEBD8C5129BA +:1059500036CE33FFDFF67B0A1942E3F5F79FFD5D94 +:1059600085B1F2D179BFAB9091B0E28096D2FABB0B +:105970001AD1BFAB90A1DF672D3C527F18BFA73073 +:1059800042F8392F7F4C9A59AF8C728F3CE0E6D2A7 +:105990001CEFC9B8483ED7B34375BD7231BA970BF7 +:1059A0009DEEF25C27F840FF7D9420F8D3F87D143B +:1059B00083EEC6EFA4D4B697BF93F2CFF6BB28D13F +:1059C000F489FE9D9468FA44FF6ECA702D96F134F6 +:1059D000AACCC57C6DD0692AFD657B00E77295FF76 +:1059E0007E7A1D8DA2D719B17200EE293D552CE5A6 +:1059F000FA85F4FF06AFFF14E4C58F8827E1BC8B5E +:105A000053C643FCB55611335CE07E42CE97FD454C +:105A1000ADBC07AAD62AE30101A22BEEC5FB2EF6E8 +:105A2000EFF23E47B28F6C1D1197A9E2F70376A7FC +:105A3000BBD60B7A27309F2C5E2CCF031FB6D4F138 +:105A4000EF5DCCCCAE52B07F792C535386B547BCBA +:105A5000B868FB1C8ECB570D847C9FF1074717D489 +:105A6000CFE82AEF8F14D98D0322ED911919322F27 +:105A70002B66982EC7BD320FCB354CFA09F15E3735 +:105A80009F6B28CE167A7EABE832A31FF8F813B6C8 +:105A9000E35B3CD2AE6EB4C97B2C03AFCA7C9EB52F +:105AA00055EFB0DDBF91EC5A55DA376BEEE3384372 +:105AB00082C03EEEE331CD49187FEF35C2642FF44A +:105AC000093A4D79C97D37BB4D70BF509AA9FDE5A4 +:105AD0007B3CA67A5F38CB549F7BC86B8207340C23 +:105AE00032B51FF881DF040F6E1C6B6A3FE44891EA +:105AF000091E3DAC9B8CFB8327693E3316B983F2AC +:105B00001E7D1927E96A97F654EDEDD29F30F2D742 +:105B1000357D1D44E7AF77B6CAFC757B95D46B9A8B +:105B20004BFAB7EE64E156F95C4C03C3B81B82F341 +:105B3000C603E63CF34E4EE95F59464BFFC3AEE762 +:105B400099C766C9732F465E39F9157EE0BB876831 +:105B50009CC6BF77A0DF271ACDCF453ADDA3C7DDAE +:105B6000D52ECFD3D5DE6EE7FD73CD656F5212CE45 +:105B70001FCFED0325FF6F74B67DEFD38C61328E9E +:105B800012CA2DBA6E18B57B8CD416DB5FE7F5E729 +:105B90006D84BCABFD959DF3C62FD6DF8CCBE57C29 +:105BA000A65B2C332766B33FC8E7008D7E2BF47EBF +:105BB000278D50DA9CDF8CC466BE774D24DA3DE039 +:105BC0005FCDB59C6177AC4852DBC07BEBB90C99DB +:105BD000A77FD3CAD07DBD699CD3ED753679E140EE +:105BE000D0067E18574076A40FF1D782475D448FC8 +:105BF000C7165B390E76DB8B2FCEC0D5F4E3453369 +:105C0000F3031251B09F08FB53CD691DF7B1E13288 +:105C1000EFFB415C2CCDF6CC0F3CAE163D3ED222C4 +:105C200042E7CE4F04DAE037CD7590CF21B8174A5E +:105C30007EEA1C71CE0AFEE7FFD47909811D52EA83 +:105C4000C75627E439C78BE0CF38A7E2B9C556B4A9 +:105C5000DE85F32262AC128187FF182EE3FC878673 +:105C6000497AA31DE4D185DA91DD9788FD8516E197 +:105C700049745F24AEFE3F31FF0CAB8C337471CAA4 +:105C8000F3229DAD1ACB0B7B967ECFDD79FCAECB9C +:105C90000D3D4ED6C92AD77D27AF5CD7E7CB85030C +:105CA000FC7DBB26EF4D8BC62FFF8988AB18E757CD +:105CB00062474B3962C88573E7507A4A3FD4A6CB16 +:105CC00087600F0BE71DDC1D6F5EC7DFEBF261AD78 +:105CD000A12F02E4C7E79BE484C0BE5EED3295E5E8 +:105CE00004C9C9831A8DB318F7B2B85B7F1FEEE6FB +:105CF00007A41E1BEE2F7A10FB26B356DBC43ADE38 +:105D00005790F7C3CED5E3E4C581A8FB59747BFC5B +:105D1000CC4AC58DDF8D98BDC25C3FD7F5E527F035 +:105D20001F6F8EBEA7C6D8AFBB481CE0E830DD4E63 +:105D3000F70AAF9E7FBF04E33B1394F75E9F3BAF30 +:105D4000A4C77F5A82CF4AF84E21227F47C2B00BA8 +:105D50000CD8837DB2887B5808BFB159D0EF4BADCA +:105D60006DE6371AF83D97E7A1EFD351B96419FBF7 +:105D70003332BF81E401EFCB9DA07AD8812702A7FF +:105D8000B9FD891D319C5772D2D7D01FFBB7C63ED3 +:105D90005D0F4DEE63B5EC8897F90D2E8B8437CBF4 +:105DA0007BEC17FC35D81F7E6C63E059D33907AD07 +:105DB000D1BCCF175D6A353BD9DFBC224F4B1E8E5D +:105DC000BC74ABD7E925F81ED73EBEA76B1CF98F74 +:105DD000906BC84B599622C7CFF22B705AE2AF4A4C +:105DE000E2EF6764E8417EBE2F487A228E29C8AB75 +:105DF000A5B2383C98FBFFA9FB6093CFFAE4FEEF15 +:105E0000D921FCBEB66230C359C1E6911F50BFD73D +:105E1000692E0FE248D7D6FE624C2C7DBAF15F5D49 +:105E2000CBB8EC6C3E3F6094BEE1528F34DADAAE10 +:105E30005FAFCB9F3F0C17FA7D3592DF17D628BC9A +:105E4000AFB6103C0EF83E793FA7019FAED3E131CB +:105E5000125EB44CC2504DB08367E9BF93B6498F10 +:105E6000BF60FE28317FC405B6E8F119CC1F25E6D6 +:105E70008FE790578021AF00435E0186BC420979CD +:105E800085E75F248DE27D6DECDB8D8E584FD8B7B2 +:105E90001B1DB13EB06F170963DF2EB23DF6ED2238 +:105EA000EBB16F17598F7DBB4818FB7691EDB16F41 +:105EB00017098B4157B5C2906BFE89267832F903DA +:105EC000A323D633F6ED22BF8F7D3BD3F7B45B4CD3 +:105ED000EFDF28169BDEC7BE5D64FB998B15D3BE32 +:105EE0009E10CDACD767AF69C77C94E12BAA04BFE5 +:105EF000FF39EEEFB7D9BAB17CE038C6C2F258AF7D +:105F0000A477DD58497F8B3C1FA134F3EF0B9CBE77 +:105F1000D32EE131E6FC6DA3C4BED7689BDCF7420B +:105F2000897D2F94D8F742897DAFD13DE5BE174AD0 +:105F3000EC7BE139F6BD5062DF0B25F6BD5062DF28 +:105F40000B25F6BD5062DF0BEF61DF0B25F6BDF0D0 +:105F50001CFB5E28B1EF85E787691C2511720CF6E2 +:105F60007A0F939F497C68F233DD2618F67A647BBA +:105F7000D8EB91F5B0D723EB61AF47C2B0D723DBA5 +:105F8000C35E8F8443C33CBCDE60B747BE07BB3DE6 +:105F900012EE57177819B1B5F16BBF3E80B2315E82 +:105FA000790CE70D43C3A7CCC47E66638CD22589E8 +:105FB00064BAAD66DACCD1B0C3F5FCC7FEA2D90293 +:105FC000F9A3C199CCE373869C57DAEFFB74AE6FEB +:105FD00030CEC5E10FD1DDB743F0EFCE18FBEDC6F3 +:105FE000FB5E52DBFC7B517AFB56B8ED76D1FD1B94 +:105FF000ED38B72A621C38D18CBC19DF9DAE1CF875 +:10600000219B2C0AE7996C5A22F3A2A3F9EA0B5DB3 +:106010003E6DB26CDF877330CDC58A17E73E7AD408 +:10602000697CCEACDF7461517DADF3E9FD7802E7A8 +:10603000D5BEA1CB3D63FC467C94E4059F1F1CDAD2 +:10604000DC302A91DA6B8191FC3B38E3ECD26E2094 +:106050003FF40AF8937D038A7F7D049FFF69B8D4DB +:106060006F5A408EE3C9C727C8F762E57B4F3E9E53 +:10607000C0FD4F58AA709ED9D02DC28F73CA8DFA19 +:10608000F8FB6E09ABE8AF78A9ECCFF86EF1DA2E29 +:10609000769CE736F0552C1A47E33E6991A7E04E0F +:1060A00059D1CBAAB15DDA61BADB023BE852CF41EC +:1060B0000DCB4B1A833C44512FF8DED0F1796F9B06 +:1060C000E6CBE8CAC7EFA00AF60DB5C02D16F43B23 +:1060D0008110D00EF16482311F4D13559984DFEB8E +:1060E000A61633BEB3A60B05F8EE337D9D2585DEDF +:1060F000EBABBD6481BDD6AFAE914B631EDEA14953 +:106100002AE07136F7188C7FDC1885E547741E0F7E +:10611000EC038697DA589F1BF6C3C2F873793E7F6B +:10612000429ECFE94336CEF339BDF40CD717EF8C3E +:10613000E1BC1E6D8DC272CDB01B8CBC9DB25BDE0E +:10614000CF077E8E6506372575673D9F3802F93487 +:10615000DDB627E008CE89A53BAFC3D1BDD34B77D1 +:10616000CADFABD5F7778CDF3D15D97ECE0733EC90 +:1061700040A1D6DB23F7718CDF4F23F9C9ED4EEF39 +:10618000B1BBF9F7EBF4DF3B35E23EC56FE41E042B +:106190005E8B1F95BF7F366BC5AAC2A904CFF13BAA +:1061A000C3F85DACE87CACF95176E0C57EEFB4CFC6 +:1061B000083DFED36AFF31BF9C795DDA7FC56FEC85 +:1061C000BF56DA2B36CEFB9F5E23E37562BBE0FB46 +:1061D0008FA6D78CB2E01EE9E93BFD5EC5D36A0706 +:1061E000BEA5DB2D93CE66307EDFD5ED946B917F1F +:1061F0004AF81DD718A3E7ABA57379FD59998F3AD3 +:10620000C925D77BE37382EDE9968043E611D60B6F +:106210003DBFD5CC773E41FC41F4B9CCAFEC47DA79 +:10622000F278D83DF4BDA9B083DA818F8B97215FD6 +:1062300096DE66BB339A8F2759C353F0FD495E1B28 +:10624000F3D73FE263DCCB714E2E89AA9771CE5F04 +:106250006C90BFE3305593FCDD57E7EF19717AFC82 +:10626000C925E34BE7E2011824626681AD33912F23 +:106270003C03C90B1D795A7EE4EBC567CBFAD97F85 +:10628000D83A73299C990BC425D43BEC7C7FB5E6A6 +:1062900072F2EFD05C284E80F800E4E34DB7FAECE0 +:1062A000B322E463C1C882D5FE0111E71DEF9179E5 +:1062B000500BEFE9D9A1ADF3B646399BF08BF53120 +:1062C00023B1F1369C37AF1921FCA307C9DF99E44C +:1062D00079E1C44D167E6F52C25B47BCFFE715D90A +:1062E0008C0F867F35E28599C8872977361682DD3F +:1062F0002AB3ABC622EFBA550E69FE8C4CC8215F9B +:1063000018BF1B76A1B8C3D611920ED1F187D9D987 +:10631000523E0BFDBEF04FEFD9BD0DF2DC18FFA7CA +:1063200017F87D8C8D232CFFADE73CA2CF777CD076 +:10633000477B6804E21A167F13F2E83BAA757AFEDF +:10634000ACBCD7C3A06F4CDD771CEF28D1EFC327BF +:1063500079C2FEE42CBFD35B0339922596E3BCD00F +:106360000C5534F3BEF1797497787C7CDA5FE723BF +:106370001FF7F15FC5CAF33A3AFEA6DB1B5E7666ED +:10638000B6E2EFE3C5FF6293F22BDC13FB723754E6 +:10639000C5707E5BC1C8A22D186F5CB697EFC1585F +:1063A000ED97FCE4EC56F47BC8C1F2952F3D86FBDB +:1063B000122AEB33F977658AF7F896E39C63C148B4 +:1063C0006D07DE2B76B9F9DE908AA549AC9F66741D +:1063D000D0CFBF8B66DE8733F0FE861E9FBA7FA4C8 +:1063E000FCFE29DDCF80209C686A77A1389DCCBF58 +:1063F000417E0EE28F9A6B17C709DC77C87B2AECC7 +:10640000E23D197F4C6B3B6E90A1C71BD3BD323E62 +:1064100064E0EFDEAC592CE76C463CF71CFECCE7A1 +:10642000318DD2ED97F6C2AC5B15F6574B56AB7C6F +:10643000AE7C8C3A8EEF7159B84AF1F0FA7AA03BF3 +:10644000E77B2FBC87AC310FCE97790A3BE4E1BEE6 +:1064500075C50DBB643A681111DF29593398D75BB4 +:106460004990CA36EE3535CA1B57EDEFFC9C0764E0 +:10647000F4F3FE6589DB6F4F8E58EFB3EB14D3FD59 +:106480000A062CF02316ED717F3D29481AC7F41E29 +:106490001E05FB8A6EBFC4C34DB766DAF17B24D3F9 +:1064A000E9CB969C0BF7FFFFBBFC7FC4BFEF53000B +:1064B000800000001F8B080000000000000BED7D35 +:1064C0000B7854E5B5E8BF67CF2BC94CD879910458 +:1064D00048D80904C2439C109EF5C1CE0B2610601B +:1064E00092808227840904091EF446D4126C940910 +:1064F00099C41051138D0629EA80C0A16A25564F10 +:106500008516DB017C8B8A20D6B636191E8A6D7DF6 +:10651000A470A8F67C54EF5AEBDF3B99D99904D0CC +:10652000F6DCDEFBDDF8E1CEBFFFF7FAD77BAD7F0F +:10653000A7289DBDCA2631D6DD2A48DBD318AB94E7 +:1065400014F3441B63DFE2CF0CC696B5088A6F7C58 +:106550006FB9289D2D75413952B1333699B10A4929 +:106560003627A7E15332C7C2FB65B71F30B178C6E3 +:10657000968F644CC882F6B10EB30DC75F05E30B6E +:106580008CDD20F90BB0FE86F132AB8B81F6DE2C70 +:106590003383F9DC9BF83CEEA618F31550AE304A75 +:1065A000E6142897453286ED617D3EEC5FE957CCD5 +:1065B000B1361C972D2DB1F1F5C606ADAF425D6F1A +:1065C000654B8C7945C8FB56930CE5C58C291D415C +:1065D000FBD39E331481F6B3CC5B9CDA0EEBADF4A7 +:1065E000D8259CB7D2A8981DB82E1C17FA2D6E6B13 +:1065F00037A505F5BF423150BF198A4CCFA2747F31 +:106600008680FBBD35C281EB5D2CB598109E451A86 +:106610009C1FE6705821F93370FC15560E076DBCAF +:10662000CA363E4FDFF5717857B6559865A8BFD189 +:10663000E84A6D87FE37C23A3DF05CBCF94086807F +:10664000CFEA088700E7C12477AACBDEDBFF938778 +:10665000AF4FA5FDC3FA11DE76873C3309D6B3BC34 +:10666000051623D393E62DCF66D51D4170BB5E3151 +:106670003296804F033D594BBB621D0CF060FC67A6 +:10668000B8F9480EEEA37E0C631B601F6EDBCF7360 +:10669000709FD29D8C89D361BD9BDEA3FAE5494CE6 +:1066A00012A0DECC5E10B0DE5C097DA0CC3C054AB9 +:1066B00020938FF56D3A63293832B4B701FE789292 +:1066C000195B3755A67917B3C0623602C6D9540C88 +:1066D00073C03A13F93ACB07B1EA9F8581579BBA49 +:1066E000DE1BD4F32E33B097596C6FFDDDEA79973A +:1066F000213E07F5C7F170DCD55A7DAE3FE3D6F1F8 +:10670000BDEDB579CB62793FA407C4C3D52A1E601D +:10671000FB35D49E970B44DB8606D8CF9AFB449F6B +:1067200045C0E7930D83B1FC9CE040B8FF79CD8B69 +:10673000EF5C07CF3F3DB2AD1CF7A7AD63C5D7599E +:106740004C8E83F3FDFA2A7A56FAA73339BBEF3E13 +:106750000F4F75FF48991C843F0FFD74941BE6FF93 +:10676000F3B36F65209C3F021C1001CEFFF6D327C8 +:106770004D2CBD77FDCB9ADE3355D882E12510BC78 +:106780009A338FD2F92DCFE4FD967BFF5281E7C17A +:106790006C663923ADEFF957789FE3ED6B1CD4DEBF +:1067A0006DFB809FFF102689C9173F6FED7CF5E7D1 +:1067B000FEB8C9E54F12F07C5A42E85FBFFFC7D46C +:1067C00075FB54FABB41C5E31BAA5AA9DFB2A68ADE +:1067D000274558F7628D7E2B43DF6BE773769389ED +:1067E000CEE7ECA68CC6242C77F0F3F977B163C220 +:1067F0005A68F7E7D53B6F494EC755FB525D57F0D6 +:10680000F361D9FC7CF0B912CE87C5853D9F3DC1AF +:10681000E7B3F2097E3ECB9F7DFB0FBF9009FFF8E7 +:10682000FEEEB3F890FF2EEB78EEF80FE0FDE2A657 +:1068300056531AB4FBB59246FBD2FA2FAFCE9258FC +:1068400034ECAF699B09F9C0AF15392C9E6B7065AC +:1068500046CE671E37C1D9C6503D13627BDB2F661B +:106860004A22F211E619C676C6F75DFF9F543A2A0E +:106870004A779813917F3544B1ED12AEA3E27E368C +:10688000A16F7BED792A82D3C5329807E9F3548E44 +:106890002315E9A2CC6008A137ED7942A5AFA1513B +:1068A0001D8B71BD43E398540F20FE71A4926B8041 +:1068B000797FFC03AB54EFC0FE6E19EB2D562679A1 +:1068C00000E4DB0DF244C24FC6AAEF494658062643 +:1068D00023DF1BB93AF0175C1FA253C444FEB4C3B4 +:1068E000BE2D391C4FA0CC06F3F77E7CA6183B8842 +:1068F0004F45D670FC33B3F7A96C06BE8578ABF56F +:106900001BCA8E08F83E19D682F337672EA3F333DD +:106910008DE4F4D2DFFEBEBDC4FD9D4A73FB484E3C +:106920004430697B0CED6F0D967BF697C91403F428 +:106930002FFFD115DB9A61C85375CA4133D49F5AD2 +:1069400067A3FEFFA8FDEAF7B9B8B222649F3D74C1 +:10695000D3027C2D0D9FD9A9B8CEB3569808EA4F23 +:10696000DD1A6140F89F4AE3FA0263017B099CCB80 +:10697000AEF5F0AB85B1DDEBADF47C6A3D20D368BC +:10698000C69E599F44E567D7CBF4EC589F49EFD397 +:106990007338FE95452AD12897BBEBECD2768487D5 +:1069A0009FD34D67CD088203E8099C1FAB7A41A7AE +:1069B00014B0C706F169901FF7A1BC633523D84E08 +:1069C00098A2B3E594DD301EF192AF4F6B7FBBA967 +:1069D00085ADC3768F0ABE9D306ED4EDEF1524A22F +:1069E0009C6E4BCB12A0DF929A73C40F97D806CB44 +:1069F0000CE5B8CDDD3815EB37A7491BA05B545B20 +:106A000056670DF45FE11DEDC0F6B70B7223CD5B49 +:106A10002738705EF851AC53800FE06F505E697B91 +:106A200075A4CA2F0DC82F97DFBFAE3119CA270C26 +:106A3000AC5B04D014198A6762B9684B8CA31EE55D +:106A40006D3DDF0FDB0A7CD4DACB470BA7B9AECEA6 +:106A50008173661700DF60FCB1B03626E27E3A141F +:106A60005C3F03BD6327C3F5BACCD8FF972ABFECC0 +:106A70006C3B6197D5F32946BA71779FB807CFD59C +:106A8000667034CB28DFE5776584FB1B22DB2E2381 +:106A9000FEF0FA35765E0FCF0D0D50BF669BE843D2 +:106AA000781488658303A87F6D16892FAED8563A6F +:106AB00018F58D155046F9B505A7027C6A6CCBE335 +:106AC000ED5A0B1EF1003F4D15980BF9D16963A0EB +:106AD00018E1F1E9B6C4D83AD4F76EAE1FC5A0BE2E +:106AE00072DB3DA9F8FC745BC422E4E3F952717EC9 +:106AF0000CEA3F5B63B244B997CEAA72389DDD744D +:106B0000735E22CABBD5DF1C7A5C02B9BA0270542C +:106B10008271CF7744F93CD064F5FABDA922A096E2 +:106B200025DEBD3C07F0EBDF0DFBAF9B8E7258F00E +:106B3000ED4AA6F672A2148E8E357D0AF058063CF8 +:106B4000BDF9EE0F699CCF0D87E72D86FEAB6F7EFA +:106B50003E1AC7F9F7878F4D91E0FD0F26B9FF1751 +:106B60008EFF2761DB2E0940C2366F9B80F2A33A6D +:106B70008771BE1AEBBA6E3187AF63BBDCFF7C5501 +:106B80007B0582A7565EE21B6466A897FA9959C2F4 +:106B9000A7C4480FFE54643528DF35BD447B5FAF82 +:106BA000C2E5D3412DA978FEAB76B5A7A2FCF8A328 +:106BB0009D97DD3B5E5B7127ACC3DD669018E09D61 +:106BC000DBC848EF5DEEE1FA34AB026692DC3BFFD6 +:106BD0007D3951B4FE559BB343E41EC8479AE78FF5 +:106BE00046E6C4750CAFEFCE42FDE9F746FF0A3C1E +:106BF000D7DF837EEA49C373E2F8F7FB167126BE3E +:106C0000F7DC2EB00C01CBCFDB47DA480F33105F37 +:106C1000FFA5C9B713DADB2775F891EFDDFC42CC8D +:106C200044046381383E11F167CD3ED3CCA15C9F13 +:106C30009270F6D546BF39DCB9DDA4EA513DE517BF +:106C40009E3323DEAF7E06F401A4CF17041FEA377C +:106C5000AB3B9E7B75088C77CBDE8A6C9C476B7F49 +:106C6000CB0B1C0E112C602E0DD2AB2B32631B876D +:106C7000028F7CF6C0474B1F862D55E039FD80B151 +:106C80007D333E70D78DC4A744FB64C66ED2C74126 +:106C9000BF32A3FCBFD9CBC7BB39F368633AEDABB6 +:106CA000388E059DFF9E1C13F5D3FAC3BEA95FBDA8 +:106CB000F5EE2702B05EA5DEC822AE85B2917DB4A6 +:106CC0000BE1C7A2A59DB80F233BFD2A3CD78A83C1 +:106CD00058333CB756AFF90F6A5F67914478D6DFF7 +:106CE0005CBB2700F3C9227331E8EFC9ADA6F13CC4 +:106CF000662E7FDAA39E7DF44628D72CB03900BDDE +:106D0000A11C4DF0D9FF4303F1F964D67DC800CF33 +:106D10004406540400FA539AFB30E237FDC0B86BC6 +:106D20006F937DC88F81830B88E75FBE74261BD766 +:106D30007DEDF0C039C42B53DD19773ED0FFFB3910 +:106D400012D74FC607B2B15DC24195AF198F907C83 +:106D50003425C9B1A8AFF8712C5CDFDF0C8407FBC8 +:106D600005FF9338AF06A7885CAEFF19B2DC7F4001 +:106D7000FEA708A63BFCD07EBE10EDC0FD1E891507 +:106D80003326023D7F69FA280DC7F500DA8A437B76 +:106D9000F5D85C75E9E621D336235C7200A0EC6A75 +:106DA000B065C6C7322394EF65866E0BAC23B7FB84 +:106DB00077DBEAA02C3D38888920AAEA2352592E95 +:106DC0008C2F1C848DC27E0E8E3FB81CD7796FB776 +:106DD00095219C983554CF351B92FD3F427CAE8E59 +:106DE00076B02494431D59C88FD82D364733B45FED +:106DF000722190F1BF502EFDED30E9E963D2DD5FE5 +:106E0000E17E8688CA0937D4DF2BF9473C80E3D777 +:106E10004439EAB81C61C1EBDFBFEE6FD171D0EF2E +:106E2000CBEE51C63DD0EE4BC5EA000D9675DE396E +:106E3000EEE5ABA07CB52A4FF4EBFA324936A2DD81 +:106E4000F165B7D58F7AC89736834F0090E6EE3F4D +:106E5000F4A100F23BD76AF38BD1D8CFF459B0BC80 +:106E6000614752623E194722867D0BF01CACCAA5D1 +:106E70006B0785DA8F4372B91D342497F31FA3EC97 +:106E800020389FF5185933E2218332CE6BB44ACDB6 +:106E9000B0BE5FD9762D01CA6767BF4E1F8472E30B +:106EA000ECFE1183D8F8FEF9E231D427404F583A6E +:106EB0005149CB9DDC2B5F17AA708968B9DE84F03D +:106EC000A8077834033C16DA0C7E0BEC8B2D088572 +:106ED00003ABE92E47BC61866807D20D9E2F9EBF8B +:106EE0002C18BAD9557DCF7BC605C9FF23282F8121 +:106EF000F344B8969FFDE48A07189DDB15B9097421 +:106F00008E0D57B2DEF3FB573B2F667434E139AC7C +:106F100015ED2D780EF546AEEF7900B776C650B771 +:106F20005D782E6BEB47D2390DAE073E81764A9DD8 +:106F3000916D8F47BE7294DAEF54F54196594D7CAE +:106F4000A6BCDE2221FCBE8A8CA6FE0CCED5342443 +:106F50001C9FE17CA5A692115F593ABE5AC0734F9F +:106F6000C219603F9D86801DF71988002D129EEB87 +:106F700072D389CE87224718C1CF19FB3FB6CEBE48 +:106F80001DF98D681DFAD8691045ACA93B7A2CAC67 +:106F9000AB4D601DB42F93CA3F56D9489F6B8BF100 +:106FA000117F6B5B38CC817BFD92A9F55591C45F55 +:106FB000AE3218A8DCBD7830D9636D31C05A71BCCF +:106FC000C563496FF8F93722B7D73218AFCF62A33C +:106FD00036637D71268DF74B8D5FDD67A7F1DA8A09 +:106FE00095E448AA1F6CC0FE4BD3DCB7217E0C1180 +:106FF000793B503CA8DD962D4A329EE7961233B578 +:107000007B44702D5E81E35C6123BD31B038F2D9E1 +:107010005DFC38FDE85FEAACE1FBD6E860DD54CE0C +:107020004F877B4E3C8AFCC3930B27624379F1C5A3 +:1070300012C46B458C76000AF739E7AF7AF09C757D +:107040000370597C6427D9EB72064360C3F9492C5D +:1070500017F1E410C013DA7B4C70CEF1FC9C37C4FE +:10706000E339CFDB167CCE309E672DBC17D6443B70 +:10707000846974CE99387E0D8B74A07DDD737EBFDC +:10708000F265E1533438922C008BBDE9EE8755FA56 +:1070900025F83EF607D81FC0A5DC1298DC82FAB9A5 +:1070A00081557584E1034FE472FB4062DD2694AFA5 +:1070B0004B35FCAFD5E17F6058CC27512AFE43BF4A +:1070C00017135DDBF01C3E178E4DC19787FF2E2EE8 +:1070D0000A37FE4F54F9F266BC6B37B61F693C386D +:1070E000EC36D437D65948FF65170E0DC379D7A6AD +:1070F000B99EC6FA8891DD66F44F7526779B707F3E +:107100009D8BFF94827AD6D29AD7883E2F757D1BAD +:10711000A22698506EC638B34C01E89FE8CC7A0599 +:10712000CFE5E85C8B6C09E3073930776A0AEA43FC +:10713000C70AA7A620BF3C9602244FF2D461473E5F +:107140006ADA7B851DD779CC994D6599C96AB9747E +:1071500040FEFA67E0AF7E5004FE08F61A3ECF808C +:10716000BDE6077EFB31D86BF83C05F61ABE3F0141 +:10717000F61A3EBBD63BE8FD31E788BD8817E75BD2 +:10718000B81F65B9D111562F5BFD8CC8FC1A7F83DF +:107190007F37ED880A29576D8D0B29DFD8061864D3 +:1071A000ED2D576E1A1152D6F4CF65DE7121EFDD49 +:1071B000B5D921E5FF67E0DBC4E18BFEF27F25F85E +:1071C000E2CF269077A5F80BE0F7DB9367111F3D20 +:1071D00026B0EA3878C6489CFF195D02F9DDF0A7B1 +:1071E00005E47609FE027463B4C90D58EF85F60F05 +:1071F000425BB47DD1FE60CC61AA80F70B9D111279 +:10720000CAF3EB5835D1D922D642CF1B58073DCB14 +:10721000D8117A96334E875F5604A6E0F3837877C9 +:107220005A1EAC7FB5D5FD443CDA6D29EED171C84C +:107230008F6CB16497F6774EA8613355CFB54D5139 +:10724000F7053F0B70EDD0EF68D4843BEE907BE701 +:10725000D1C687F9AECC433E63E2F3BC3D796A0AFE +:10726000F207E64A08B1A7FA9BAF559593154E0E63 +:1072700027F4D962F9F442C1B701CA075A2D66F45E +:107280002F9CDE6852F5F5BBC9CE3D719CFB654E67 +:1072900037CC4A45FCAB6B1D9D8A787EDA2437D407 +:1072A00000FC4F4F07FEED203F8E03E5C349A79D2D +:1072B000FA83A488CE82735BAEEEEFA4EC30AF838A +:1072C000F60B9345E681F66E4F5A34AE5FDBB77E20 +:1072D000DDCB365942F060FEB4D0F24266EEC5B75F +:1072E000343C6F736F3DEA4962D920F7007677CD61 +:1072F00047ABDE7D39085F6FC8B3C723DF6453D95E +:10730000D46FC5DEFEFDC1F7ABF555EFBE6CEA8567 +:10731000AF865793F25CCBF19CE0B519E916E062B9 +:1073200040797C6C2F87636BD4B5F75D0570287945 +:107330005F641CCEE59EDF233EEFE37E7DFD3C01D6 +:10734000A4EBD148AF9CAE2BBCEF91FDB6B4B6D840 +:1073500084EB2BB175A7A0DFE9C05DA353F05C8E71 +:10736000CE1D9D827CE350E1E8C76E8771BB8A44E5 +:107370008705F0E940D1B9FBB07CAC569470DEAE25 +:10738000BDE754FED2FDF65458DF174E13C9A1AE27 +:10739000BDFF1C3E53B20FF80CCC7FDEC7F9CC4AC0 +:1073A000A38B35C2BC2B012E68C7FFB3F9CDC5F83E +:1073B000CC5193AB2001E1552738D0FF56576821B7 +:1073C000FDE128D08785E353C3EDC827A781FD2BB6 +:1073D00021BEB926A34D796CEF88048417F32847A2 +:1073E00033A7F4E2FBF2DA9545E85F679B4C27513F +:1073F000EF466708CAE712663C1908C253F70BA6A6 +:10740000DE32E1B5F1642008AFF578BA4787A7E727 +:10741000D98554733AAF3F32B897EFE14F307FB917 +:1074200045F437B2B45EBCFD6BE17BE5A824005F98 +:10743000F905E2EB0F27A6BD141082F8CA25F2B1B8 +:10744000D6A86F48EEB5477D4372EF7821977B074A +:107450000AAF3FF83BC4FBBB38DE1F5B3895F0F248 +:107460009809E419C0EB686D7634964F6D2A253A79 +:10747000D3E8473F4F978AFF5ABBA5C66E93230CAC +:107480007EBA6BC590F3CC7861C920F407F4B77E5F +:107490006D5CAD9D36EE525D5C573FEE27795C4FDB +:1074A000CCD85136E0F86000F6F6437EC2227BF17C +:1074B00055443DE07AE601F87439397CBA8AAE2742 +:1074C0007A3CEED4E8D2CD301E7B7481E843FDB522 +:1074D000CB798EE8F43CD0298DD1CFBC9FAAF4F9AA +:1074E000894A9FA755FAD4EAC59D0F5F77038E5B43 +:1074F0002B129F3EBA203B01E7FBE38E0C9A17D676 +:10750000034605E8212FFFBD024C34E40F76E45F0B +:10751000C7010E6827942E2C257BBAD4E44808A70F +:1075200027E8F7AD1FEFC05C8B81F1F188DF95DCB8 +:1075300055CA1A912F001C103F8F637BA82FD9C901 +:10754000FDC087B07D7C309C4693BE727CB7E04026 +:10755000D161DAFB773B9EC32A5F28BF58B9392A2D +:10756000E4DC56B4C485944B0AF93E8ED78EA0FD58 +:107570005FEEF969FD2FF5FC6F52FBE39ABF253DE5 +:107580002536643C0452E87CE9BAFAB1BAFA89219A +:10759000E58BE1E309152F34397222425E122EBECB +:1075A000D435CF52159CA7313B9FFB5B66E773FF39 +:1075B000CBE5CAD582FCF072B5BFFE1A7F1A95E7FB +:1075C0002ACA4739EA2F35E1BE2E951F05C9E105C4 +:1075D000D43F2098B17FAB2A67AB3A38DEB547DDA0 +:1075E000FF2AE2D5E7AA9E0E7849FCFE0B95DF7FC5 +:1075F000F19F6AF9A702E1E5A17D6BA3516F3FB34B +:10760000777434DA61273BEAA391EFCBCC13FD0307 +:10761000C0C7CF5C203F61BA4F3B06969F7F54F9AD +:10762000CE193C07929B129DC729557E9E40F94971 +:10763000F23E939E47517E42FD82E7543D7DB74026 +:10764000F4BFCAD812DE3FBD23945F556D8DD2C9F9 +:10765000C950B959B96968487999774448D95D1BC7 +:107660002A370BC432E2EB677C1C8EA5CEEC90F679 +:107670006764395A22F870387C6192A311CF4EFAB0 +:10768000E2A283E945E3BF477570388D7040FCF492 +:10769000960E8827A7D4FE5A19EC4213CE5B6A7562 +:1076A000BC128F7E844D8203E3540C78CE3438C7ED +:1076B000230BB29E6C0ED233A40291F0F984F750E2 +:1076C0007932F21F30C0D0CFFB5AEDA154F4AF563F +:1076D0003C13457A937EDECAA2503EF3594371EEC5 +:1076E000EFA15FE9FBA2CF8AF0288A21FEB5E0393D +:1076F000D12742B9AB362F3A781F67543AD4E4CE3B +:107700004A6375D873ACDA1A7A8EA5457534CEB152 +:1077100087850E61103C0F4C0749DAB75FA991EFDE +:107720007FE53322F977577AFFF236C61557821E66 +:10773000886AC26B4DF5F310AF4FB84C06E2A71D37 +:1077400071F3103E9E05A22303DA1F6E1A41787E64 +:10775000B2296F30CEF772BE48747566AFC5205C33 +:10776000094F9789F9C95EF5D3797EE62D25B97160 +:1077700006E1827A905122BA78379FFB914EC03849 +:10778000586F003A417DB8CB273A7D61E8E3DD7C54 +:107790007E1EA72E3C40F8F3AAEF5034EA15273A94 +:1077A000F8F8A76AA5688C4FBDE5CDB6D3FA8A6014 +:1077B0005CD47BF75D4F72F28C97E323AE93ECC3FE +:1077C000262E3F8E7997DF3F1DE0F1F92691F4CE0A +:1077D000CF9B4AE74DC7F3DE64A2725EF1428A6F27 +:1077E0001CF371F972DC77AA1CCFEF8C174E1FCAFD +:1077F00075FBA6BE3D291ECFD944F850F94CE8B917 +:107800002CDC144A5FF0139D057A5725FE26E3FF12 +:10781000949968272D4B02F909947BA2A8D484FE81 +:10782000C9124FA83CB2B06213E21DEA97D86ED9D4 +:1078300063A593FD487F1E81E4E5D217009F603D5C +:10784000A61D5793BCAB68B184CC5B521B6A1F2D3D +:10785000D3D9437A7BE9B2E585A9BA3C9CBC1854DC +:10786000A0CA0526CD44B89F04C3BA390BE0F982FB +:10787000A860F9BC3782F867C5D2B3D7A87AE9B552 +:107880008807CCE161D3343B3D88CE9679459D9EF7 +:107890001E0A5FD09F3F41FDB8294E95A39E52F22C +:1078A000D78DCA53620A701D976A7F5FB27E5BAE46 +:1078B000EAB7E5A4DF1E5B08F202F673149B04F539 +:1078C0003FB0F07AF2EB1C9F7B3DE9B9C77BFC3AF5 +:1078D0002ED5AF730D9DDBF122C067921B0EAD3C20 +:1078E000A01EA1F18B8FD57338A5F2C9132A9FEC86 +:1078F00052EDAD46555E78557971BC48B5B7E21981 +:10790000C90BA3516197C2676E6C8BD2C987389D32 +:107910001D3554773EA1F262B7CB3DB300E0664916 +:107920001A1BF2DE244D0C2967ECD84FFEE3F3322C +:10793000CF27BA077102E3250B797E16B37690FF45 +:1079400078A143A6FAA1182784F66852611E898699 +:107950009FDA7B299EBFD7CAB1B0EB3A6C97D6416C +:10796000E5FA858C611ECC486D1C00471DE8094373 +:10797000D18F0DF324818186ED357C1FB6A095DA79 +:10798000E5563149807655056984E7494C21FE3238 +:1079900078355330DF85F99EA7764FDE0DFB00BCAE +:1079A0000FD4CF20BBBCD41ACDE3DD201F07C6B354 +:1079B0003A4E3FCE38D25B8619396AF68BB76ABB2E +:1079C0008BE16D901E7407D10533903FA2356A821A +:1079D00009F1B4C4E622BF01E0F5923BD05FF99211 +:1079E00099FB091672FFE4D1C2A98FA1BD3B618F3B +:1079F0008D7CC94757003E137FEFE676426DA9079D +:107A0000E5DE074E2EE7C6EDF9CC80F96E5D7B9979 +:107A100003CB876A9F3FFB26D2CB0281EC8C63B5F8 +:107A2000799C2F33E6C2FCCD63CEBC0D549E0686F6 +:107A30007116D283B2C188EB00B83653FDF2FB2633 +:107A4000A3BE735824FC4D52F38C243CD7E4DE7261 +:107A5000BCA296D95E2A2715F1FCC05FA8FA41871F +:107A60007A9E3F51EDA05D2ADDB4A974F3A04A3798 +:107A70001BF5FED0AD9C6E46191DF745417994C7A4 +:107A80004E72E6DDA253B46EA07F09E3B969856248 +:107A9000F32480DB384B80F8742988BD0DB09F9C9F +:107AA000A23ACA5F2C75338A57942CA8A3F50530E7 +:107AB000B67415EA4D7582A8D6237F1C17E7A7F682 +:107AC00025562661FF52E77307300F77A11B40034D +:107AD000E5FC057502C1A702C683F6076A1FA2F17D +:107AE0008E57F1751CB5F3FEC72A98E481720673B0 +:107AF0001EBC9DAFD385F1D0E3B5CF1F20782FE01A +:107B0000F0BEEA5343083D66F92343E87AEC8ED889 +:107B100090FAD19B878494135CE921EDE39CA1F456 +:107B20001E39726248FD3167A901E5ECF9055A7EFC +:107B30000FF78B69765DCE1E9B01E171DD5C51F321 +:107B4000E31AD860B4BA18F97D9B543D91B58C60A6 +:107B500098BFF1E49D06CA0FD8B8A0DE8A790FE776 +:107B60003B8C745E302EF191E3FB8D34AE35CD2B22 +:107B7000A01FF35E80B318A4FF3569F24DF5ABE3A7 +:107B80007A8C41EB899519668CF5B46F53F1E92134 +:107B9000751DC0B7734C38AF8BE3495C113398A0A7 +:107BA0007FC2022EA7F574D9A1F6FF89DA7F978AE2 +:107BB0008F5DCE273744225C1631D2470AC4D51BCD +:107BC00022701D458CE8B1C37F3032587FFC457F61 +:107BD000E32CC82EA0713C9C8F8E9D2FD447E0B91A +:107BE0006E0DFCE91D78FEF2F3C60DD1B0DEA704E0 +:107BF000D68114A5F14F4DFFBEEA8B26AA1F3B117B +:107C00004C34A8FFE517CDBCFD1426A3BFEB17AA83 +:107C1000DC6952E92763C778F22F9EDF6C26BB67C9 +:107C2000D7BC95DBDB60BDA3E7DCF5D40B882FF375 +:107C3000EEFADD0B72AF9E5F3A2FB913F3F747AD43 +:107C4000B733E40FDABC193B3ECBA5754B468678BB +:107C5000FAF4CE9F2FC3F17EB22BD2A0C0F84F6FA3 +:107C600037127F1973EF63DB37B3BEFE985267A8F4 +:107C70009DFF938DED4FEDC5F735CF3F713A284FFE +:107C8000E7D8DC7B52D06F7A747D555B7E46FFFC73 +:107C9000B3D4CCDC18BF73FEF2B39FBD05F3FFC6AF +:107CA0003D6662B01D306A26F7FF1C5D5FD3960FFC +:107CB00076EA5891E72930A36703C263EC8B8365AA +:107CC000D4DF80148C6E80A57376844181FDFDC65F +:107CD00067DC467C60F6C60C3CCFDCA78B0E7E8A48 +:107CE000E77C5CC5F77EF491A3EA39F5944D32C187 +:107CF000DDF39295DB378A9C42F6B1434E2909D2D7 +:107D0000E78EDEA5C5971C7F403E5E521645716525 +:107D10002DEE223AFFD2807C7EE9B4EAC912AD3F53 +:107D2000348E3F04E1978D715E1EAFF7788C8CF234 +:107D300082606B48276BC5B1946FF2E1AA1F52BCF9 +:107D4000DE53679132E2296EB007CB35C0772C93B2 +:107D5000288EEB43A1BD7826F7239C5B54FF9859EE +:107D6000EE1FFEDE8B9C8F493D1FFDFBC533B91E08 +:107D70005A8FE79211722E07DD93C29C4BB495F097 +:107D80004B3B1731BA89CE85596D9998F791C851F7 +:107D90000AF7F336CAA1CEE3DC5FF69BB2DBEAD684 +:107DA00042F9EC85410CE9428BAB9427F1FC033A94 +:107DB00012E05B26B57FA2AA77231F43BDBB5C8D73 +:107DC000BB742E611477D1C63B5F3348E2E3DD42DA +:107DD0007A737935D03FCA92A85F917ED13082E71D +:107DE0004794DBBA9750BEAA607060DC3C51A7D7BD +:107DF0007B5835AD37F17D91FCF986A84DD43F1104 +:107E0000C02366612B330181DAA36007A315F34910 +:107E100086E00B3948CF52F375136B5EE4FA511EBE +:107E2000F44C0E994FF896D65FFFB1887CA0C6221D +:107E300023DFC3DC2CE4DB04BF34C4A376EA2FDDEC +:107E4000C424BCC7C11426C74FE17E309C4FBF7EFF +:107E5000188FEB85A09FE17E855A3EFFD639FC1E28 +:107E600008DBCFE460BB8505AF67444859F59385CF +:107E7000964D49E61039F59B0BA583AA07F0D7E884 +:107E8000FB1B64D7C07EDFAA20BB2BBDB7BD9627E6 +:107E9000A6C179488DE58410DD7FBFDD2EE5E99927 +:107EA00080CF36E6CA7D13E0E17E5F247967883AA9 +:107EB0004CF0084470F8F4E8B38BB8BE0BDA791DC7 +:107EC000E55B83BCC3F3C33CED5180EFCC139A2731 +:107ED000A0CDABC5973A557E1C480B2C718581C748 +:107EE000C1993C7FA16BFD9714EF2E47FD167039A9 +:107EF000B0E1CF21F73F4616E71C9C497EB7D03C46 +:107F0000044D2F45394BF8EBE172B6D3934D7CE726 +:107F10003CB3B790FEAFE7374646791F6BC548477D +:107F200033F9EDEEA6BC911A8F45B2C073AE23D4DF +:107F30001F337F5AA83C2856E274F222D4DFB5D012 +:107F4000151A271AD9B68EF8D779D49B88DFF1F5A0 +:107F500018D5BC3213DE2F11D15EF7D0F3B0CA9F13 +:107F6000DF51F5CC08E4AFF03E0A13CB011FED2C36 +:107F700040E54188F22330A55DA67CC738A650397C +:107F800081B9A9ACE54126331F3DB5FC961416A076 +:107F9000F270D487442429999E23D00E19817A9EA9 +:107FA000A327DE4379937969142F2866CA1FB05D31 +:107FB00051F6E724F78AAE67944F0A9C64B9827938 +:107FC000250BB5322C14CB054C45CE7A5E5FA895B7 +:107FD000BDCB15E8DF99C3DB1B5FDBF8A4C746FC0C +:107FE0004BADBF87D7F7941B97E760D964A0B2A4C5 +:107FF000B62FCE574CB3009F936731C2835FE729FA +:1080000096E0B23B4F89082EAF2950A26625F49620 +:108010009FCF55ECC1E5AE5C655070FBA1054A0CE5 +:108020002FF33CD7F74D4A0ADABBF0B35B98C2F1A5 +:10803000107F5E35B993711CE51981E06501BEDDE5 +:108040004C7CDBC5904E816CAC9847047CC67C07A9 +:10805000D4B38966CAF73344D95207F247EAE92B09 +:1080600060627BD14F576C748FC675E9F99EE079D9 +:10807000ED6F98C703F4908B7A7E408D87046AB9C0 +:108080003F40A313EDBD7EBE8BE13D5382FCBCE9B6 +:10809000BDE3F6B77E3D1E1F51F5BDA3AABEF7BED8 +:1080A000EA97EED96FC018F389B597BEFBE79F46F4 +:1080B000F64910FFECBBDF534B4C5C7E48282F3A4F +:1080C00023D8A270F72AFB5B5F54DE4CD72CCAA7DB +:1080D0001826519C81697C9FF39B4EFC15F8E0B8F3 +:1080E000419AFDEAB0221C3258D2EC4C98B7D5C95F +:1080F000487FADCF3F5882FCE77C19483058D7A95C +:10810000DB4F23C531610FB7275A5218ADD79E26D2 +:1081100045A0BED4A0F24D0B8B291C89EB1F662411 +:1081200079AB5F7743B44FC0B8E2107F04F76FC4F8 +:10813000335F048C33C4E97052DE8A47949C582E16 +:1081400063F332A1BCAC4D949D30CEA1B65256091A +:10815000E3564E033E4719E93C9F2256C5E371168C +:1081600046F916ED09368A577B378E3EB002F9661E +:10817000B2C832A0FDF886894EF47BD6DB62632953 +:10818000E6A4AEA7DEE6781DEF61782403BF4722A0 +:108190002956CC43DF76BBD189FC3CE5B949D16295 +:1081A00010FC4F79CF46607EFB139281EA9FA8CDE9 +:1081B000B5DE68C37B847E85F20CA4938A0DE6DD70 +:1081C000026D1261BCFBAB4EB68C62FDE343B4D3CF +:1081D0001C82A7510EB3CE0F1AEAB734E9F4830715 +:1081E00066A9F1A4296C0A9EF3954F5D30A19EBB50 +:1081F000D426931F3DB749A0FC94C001472A9ED3C3 +:10820000A9FB4693DFDCDB24AA7E6B07F9AD0329CB +:108210002C15EFD754B408A4178BDEBFD461BFE18F +:108220009972328E337C527772B0BFEC89BB7E1864 +:10823000817CD45B6650FDDC8CC69165C59A06FBDB +:10824000FFD82BF0FC099324E03D66FBC36204AE2B +:10825000ABCBC4FD14CDC04FF17E6E734EC980749C +:1082600068FA1AD61964B734C4A747E2BCBDF8ABA4 +:10827000907FFD744B36C547B637E5523E887E9CED +:108280007BD7B30EB44F1AD65BE9D9A73ED595EA92 +:1082900080FE1FB7E6348290621F1F589584F783D3 +:1082A00056B4585844183C3EDD3A95E65B81F79841 +:1082B00071DE966233F2FD596D396684DBBDEB9554 +:1082C000E782E7692E76BF827C2FAAE539C2131BAD +:1082D000F37B109EBFBE464945FDE274060B9B270B +:1082E000F9EE2CAE67BC758D8BEE937C9C12BEDDD7 +:1082F000B1595CDF9F8DC43219F3D6D83B2B01CE28 +:1083000015404F75F0EA54537634E2AD89AD262618 +:10831000F59BB2520FDA73E7506F077EDE78D775A0 +:108320009B2BA15DC3DDA3DE45F67CA599EBCDECCF +:108330000391E802F4C20AA4CFFF5A6095EA83F8D9 +:108340002FEA8F4A487E1A971BA626D16F067E6EAB +:10835000DAFFC9DFD1DE41BC5582F0987EA6A8764F +:10836000819AAF913485B471FA69987D9DCFCF30F1 +:10837000EEB2DC8AE7A9D7D3FBE0499F75048D8F65 +:108380007A6E3E532282D6012CC14FFE72379FB7C0 +:10839000A79D5A6F0406F36D90FEAEAFD7F6317A03 +:1083A000B38E5E9DDCAE03F80E18AF1BE30BED97AA +:1083B000E16474CE6345E5E0272867DB45CAAB1E60 +:1083C000D7CEE3FFE78731F213F5379EC67FF1C7BB +:1083D00038588523C0B531BE84CEB3BF7E66DF1169 +:1083E000256D42AF7D382629745D5ABB8C9E7DDD9C +:1083F000C622B93ED881F699C5077C6F023E8F2808 +:1084000028BF33B7DD2E0DB46F3D3FC31F19D6BB58 +:10841000423D3219700DF9C3C79B05550F614923C1 +:10842000A7D0D545923FD85F09E27FC05778DE9E3E +:108430004F20F834B79EDA7E2FF961EC0EDE8A9F6A +:10844000D704A6C9419E07A4DD1364189A1ADC1B41 +:108450009FD2E0F8E9EE0DCF3E05AFCE3CB3E60B80 +:108460007C5A129645233CEF895F706D32B49B6055 +:10847000F625213F5DE9B3F4C13BAB862F69783F18 +:108480002FB4DE9214B47EF8D7BCEFA9CDCB504EFA +:10849000EDB33A30351CF1CB13029F407A31D05303 +:1084A000D75DFF41F7F323A5B34B28BFBDD642F7F5 +:1084B000BAF4F07D729641CBA7A4FB1A1A3D45B4DD +:1084C0008C66E85F3CA9DA4D2737819D0AE5C65ADC +:1084D000B38CDF35E872142B4961C633D79A4FE06D +:1084E000B9B2603B31BD779FDAF85D1EEE876C84D0 +:1084F000F18530FEBE8B8DF7AD4B59E904FCB21609 +:10850000BB56E1F3D4A6E5B4DF9ABDB55D6F429BDF +:1085100086C1EE9B9D09B8EE11530474441A65BAE6 +:10852000EFE7F5FE8CE449CB347807F67C4B8731D6 +:1085300002F50F8FD740F1DB968EF8C89128A76C13 +:1085400086B071D6279C1C5EBDF2C4151DAC0F35DC +:10855000E7737D48D853767F3AC0CB7B9CE7296A86 +:10856000FA87A4E2CD388B44FC59F2F23CB75E7D29 +:1085700088EBD5E751AF467D6972A5142C9F1AA2EE +:10858000F977302AF31D1EBC87996763243F86E381 +:108590006505F45BD8986F561A7E27C3C1303F3704 +:1085A00016F41F19303BB18DEB3B91369B43413C98 +:1085B00056385D59E13F846764A6C2701EA34EBF62 +:1085C00030EBF40751577ED409FAC438D6A34FC80C +:1085D000CC118D70B6DF37701E87E6CF05BD89EEF2 +:1085E000997918C01FF1D4EAA1F389064382E859AA +:1085F00051E4F8C1BD7A3FDE67E3FE1589E24582AA +:10860000D2487EFBADD9DCBF91CC78DC6B88C2ED63 +:10861000F909D33C5406FB81E250EC572C12F9F2D5 +:108620006E97FB39C48F34600368FFC58E67029173 +:10863000FB77D4CB59CDA5C5957E7C90FBFFBC863E +:1086400048C7F63078FFCE1C2E97230FC1DE50BFEF +:10865000BDDE4AF75B0AC4679A089F2619C8AFEDCA +:108660006547248AE7AB7C36A6D8F5A693E2B2AE7E +:1086700034847F92112C2A5076CDAA1F37E58EF4D0 +:108680004814F51F26FF9CE0E101D865C0BF6D3599 +:10869000F1B199F0FEF19A0D04573981FBC9B47B11 +:1086A000E77112BFDFDFEC3AEBC1FBBD1D73F8FDD4 +:1086B0009FC862E3EC74280FAF0D084877F7D89590 +:1086C00045A89734C93FA3F348CB920DE82F1B6A06 +:1086D00064AF5B2632F66C0CAF474189F58FD80743 +:1086E0006F0BCE27D9A1EEFB1121BCBEB2760ED7FF +:1086F0006B3AF7012007A17DCC54FBFBA94AB2B726 +:108700007BCA0037E8FF8087DBCFDDCEA72A3D2379 +:10871000C92EE2F59EDFF2F6182F85FAA237D6545D +:108720007AA0FDE369E1E7CD2CE2F07DFC8DEEC798 +:10873000308EF5D73A1EC7EAFF9CFDCC00BC658B96 +:108740009DA5B22B81CFAD322F0AF71D9975459C9F +:108750008F74DA3A085E0CE479F455748F5EAFAF2B +:108760005A918ECE49DBEBA6CA9C8F4C9E4257FB9A +:1087700039EEE9C6BDB8DEEA4842FDB37E5577035F +:10878000F28FFA03AB3EC47BE9E56566D25BCB8D25 +:10879000D5BF453BC87898E7BFE03726100F860065 +:1087A0003FC2FBA6B3AAF8F92D95B8BF56D8F391EE +:1087B0002B0FFDB1C946C24B4D8F1D67513CE89749 +:1087C000DDA2E6B73371581DDEF7320E15C9EF1B77 +:1087D000550B7A2DEE2F9FE7EB2AF01FF2214DCF9C +:1087E000B58D3786E4F59A7579BD465D1EF0D8C221 +:1087F000503E649F3C69407DEA576007E33AF703C7 +:108800001FC2A71FEC617C1E047B1D9F2F83BD8EA2 +:108810007EF057D767D2F3F5F50E7AFFE6FA69F4E2 +:108820009C911A30213E933F9AFC36CC2F905F4F9B +:10883000C3B36D2373A1EED91C5EBF68F6C8FFF009 +:108840005C0DF5F16A7BCF3784873D65367645EE62 +:1088500078F28353F9D5C2CC15E4275AA0E4170265 +:108860009E24185C15F89D0776A785E216FAFDBCD4 +:1088700057A8E59184B7E3197EC220D48F535238AC +:10888000B97F3FCE23025FC7DAB7D6EC40FA18545F +:108890006C74211EA7A687C60F9E2FE47429CCE610 +:1088A000CFD437DDC307BAAFAFD1477FF5F5FB00B3 +:1088B0000506F55FEFB5B36BB1BE3E263C5D95A8EE +:1088C00074D5EFF8366E4FB2D9406F43B1ACB70FE5 +:1088D00003945F72AE26CF4FE4F6BDE9AD3B05E9E8 +:1088E000AD2BC657877662D781559BF13B2122D2AB +:1088F0001B9205D21BC63F347AABE1E7B114E90DF8 +:108900007E9D55FB9E2B0FE93189D397B067FF1AE7 +:10891000CAC7B88BE7D168F416A3E6CB47491D64F4 +:108920002FD28739B01FD0DE1601EFF17CF211256E +:108930007F88450E7738BABB4C7ADBFC3DE9EDD732 +:10894000D704287FA2334D49427DC66BE27EABCB74 +:10895000A5C3ACD966FEFD8C2B7CC938CE16759CA0 +:1089600059C34E90FFAFC8EA10519E39650ED782A9 +:1089700049D9F4BDA18F0A79BF6FE62B1D445FD79B +:108980007D4A7EDE0403A7DFF7DED8417221A5E130 +:1089900068F12CC4977522E9DBFA7DC5CD53E366F7 +:1089A000029F1734AFE4E038E221952EE575C73811 +:1089B0009F8F615206AC27C9239538312E74B5813B +:1089C000BE2732A8F8680CCA676D3C38B824CC378B +:1089D00041D5D73AB12F3DC24F876970083D1F2E50 +:1089E0001CC02F7B31FE51A8D2311E3DF971D57BC1 +:1089F0009297EBB7EDD78F784578BFA44F95AFF539 +:108A0000269EFF01AD25FC2EC0CB2EF79942F2FB2E +:108A1000EAF4BFFD92DF8DFB58134D7EE52423D78A +:108A2000F792649EB732947908CE5AFC4DD31765FD +:108A300085E717DD50ECFE0BC2691B930FA03CB31A +:108A400039D8228AAF813C43BCD8ED52CED2BCDFAC +:108A5000510FCC2C56FE7B207C2ABE4EF906C7EF68 +:108A6000AF3EA7F8BF0E7D8BF45FC6FDA54BCBAA2A +:108A700029376B08D849B8DE996A7E46FD305EAF6B +:108A8000F957BD095AFC549987F993D12ABCC659A4 +:108A90005CAC02FA77A11CC6FB7B87037EBC176C1B +:108AA000C17B6412FA5119F58FA9117C32F6173F78 +:108AB0007B05E345A63CFA9C0863D3B83DA0DDBF27 +:108AC00091F22FCFDF98325BF5374E6493103EA9B9 +:108AD00006F9A1E9F03EFBD18263783C931F5B115C +:108AE00087E272EAB68652FCDED6AA9D1F6F437FEC +:108AF000E8F4DF5A189E07E88F7E63D87CAE7F9833 +:108B00001C21BA2A29FACF4A8F11F951783CED2A53 +:108B100052F54FC4D3F8103CBD7A76783C25FDE77A +:108B20007BE0E9CCD9A1785AA4C3D359B313BE17BB +:108B30009ECEC775FF37C6A9609CB30B95E2D903DB +:108B4000E065F64265E140F541F101B2FB46B169ED +:108B5000D6E0EF1E6ACF56949703E427C46E3C49D3 +:108B6000F971F535E7284FB9CB76F26DB483FEABDA +:108B7000C62207FBB3407F0FD1D75B40AE78C09EC3 +:108B8000FCA088E7411F5A67F1CF40BDB696DF478A +:108B900028AFDD2660BEF790AA6AC10DFC2D5101F9 +:108BA000D311FAC728865EFF09FCBBD27484F4D9BE +:108BB0007690C71E625FFC5E9A26FFC759AADF4007 +:108BC0003BB5FEEF46C7063C67261D407E5408F4C1 +:108BD00084F1CD6BBA41BE058DF7C6BE69E4579BE3 +:108BE000F135C8BF203F4E0E8C185CCEB32687F4FB +:108BF0002B90D242EA67258D09A9D7E8BE33468D6E +:108C0000AB4CDE918FF82356F03C8542392BA47D86 +:108C10007B592E7D0FE0CAE9FCFEDD9CCCE921E307 +:108C2000EBF582ABE13FA47751A707E8F504BD5E01 +:108C3000F0E3D9AA5EA0DE57D9680CE4127F623C4B +:108C4000AF6EF8855F131DB4CB1CCFBD6567291FC0 +:108C5000A31EEC7FF4370D0DCA2F45BA98600E9015 +:108C60007F6ECB622B9DC7967D4FD1772334FF1744 +:108C7000D00DD1D1845C89F25CC7DB1FA4FE6C15DA +:108C800097B37ABA146A5F24FD6FEB7CD81BD8EBDC +:108C9000B9F3D2B8BCDD1F203F04BBD3CC506E7AF1 +:108CA0002503E58DFD58F0470823907E15924F2C43 +:108CB00089495ECA977C8F7F4F9131C7C66434FD66 +:108CC00015CA6B04B4EF7E43CDA345BC8D7032C78B +:108CD0000628478DE7F41D3B899F8FCDC1CBD2D5A8 +:108CE000BCACD9DB3149AC05F36287E278D036BE43 +:108CF0008649F5E4D7F053FD30273B524FF3F3FE9E +:108D00008995CCD50465B15A51FDCD6E35BEDE4D89 +:108D100071EF74C11189FE8D11A28BE2DED14CA2DC +:108D2000B8F810564DCF28C1CF99C777E423570222 +:108D300000505EB09BCCF4FD8CDCA76D8CBE6FB494 +:108D4000CABC9DF2B20232F911EF39CEEFE16DB13A +:108D5000FF90E2044D6FF3FB04F7A4783EC478E67D +:108D6000905A81E13D56B18AC711C4D745C72CA896 +:108D7000176B5BE93B70895506F26B5D69AE3E404F +:108D8000E770B785BE1FD705FDD1CFD56E3730A2AE +:108D900057601E3DFE54F8E9BAC645718BAEBF0F51 +:108DA0002279C7747ECE7A37D7BFEBE3CD1CBF6C78 +:108DB00067FF807CBB313E92EEC72DBAB6FA6DE4F8 +:108DC000235BDE131D1B54FF33FAFF87E32F987FCD +:108DD0006076A5A1DE69AE0AEFA73433D7BB93D185 +:108DE0005F7AD7CAA481F4A87EE3223683DF1C7D94 +:108DF000E9719186721E07D1D6A9EDB3D1B6465856 +:108E000026E36FDF332E52D64F5C24502D20BF1F38 +:108E10008EF513103EDC6FFD5DE322CFCCE5F2F65C +:108E200072E322DABEE7AABF170162ABF91D14177D +:108E3000A07333F4AE2F088E3B707DE5F89BCCDF3A +:108E4000639C61BE5A7EFB99A39FA15FFFF0EE83F6 +:108E5000CFE073C68527CAD6005E144FB393BFF721 +:108E6000DD1FC53CCC870B8D1FCC755842FCF7F835 +:108E700083F849EB10F8BDFCE0FA62DDBA728DA10F +:108E8000F1807C5B68FB99F1A1F5CE61A16533AB04 +:108E9000263CD5EF7743D4DD9427D7781B73F00CAD +:108EA000F1A0F3102F5E360F3387DD97866FCC91DC +:108EB0004674DFFE3EA77BD74BB7BFB196EC580395 +:108EC000DD9F3FB7A8E19EB764C40F33F3D0384E9F +:108ED00005F1E8AB9F8E7F87623A92DB7323B45F24 +:108EE00096C7BF17D5279EA0FAF387D71CE8C80FEF +:108EF0008EF70E76AF9E03FC7CB8EDAC807AC8F09E +:108F00009A97A9FEBAC59307C4A38C9A431DF94149 +:108F1000DFF5CB30BA0CE8C7C8A87995DEF7A7F71C +:108F200018640FCFDF2B33CB646FA9796A192ADE5F +:108F30006494717FAB94CEE5CD1613976F1EA8167F +:108F4000AF82FFB5E9F3DD385F3F3F8DDFEB60C0F7 +:108F500085905F69E3E9E59926076C0AD72333CA50 +:108F60001EE17245CB176CD3E7C5B91F44F808550D +:108F70008DD46E6B9EDA6E3FD74FD96C26A15C867E +:108F80007D86CD137D748E1A2FEA273F8D69F6E317 +:108F900082D73FC4FCBCCBB61FFB1977466A20ECD6 +:108FA0007DDB3D85DC7EEC8C08A4201FEE3485D76C +:108FB000DF1B17CCFCE99C01F457CCAB4598F66B52 +:108FC0002F7CC7BCDA0FD57891162FD5F26B99D1CB +:108FD0003711BFF39969FBE0068A83F693577B8FBD +:108FE000DD11C07BEEDE8A08C776F6DDFDEB279C3F +:108FF0009C9FEE98C3B8FF5E175FD0AFFB83393DEF +:109000007185E373E85E58F8B842CF3E93C3FBE343 +:10901000AE98A7DDF757EF2B39B9DEA79814162EB7 +:109020000F54CB77D7BF077BE8CC9C20BF9EBB2ECD +:1090300083FC76F5268EB71E997F4F50D31F6DA8FF +:109040003F921ED542F5D1555C9FD4F42C498D6BCF +:10905000E8E909E8E3AF388F60E374ABE9893DF4F0 +:10906000711DD007D0E530C6E34A06356F74989578 +:10907000A7A07F573DAAAFFDF4B5FD3BD94F753B87 +:1090800023C87EAADAFE06EA55ED35DC4FD869AF73 +:109090007E03BF7FE0794F24BDA9BFFE9A1D95389E +:1090A0002FD48EC2B822E263A2CD27C857A01D15C7 +:1090B00030B9617DE56847D9306FD53DAC28A1AFA7 +:1090C0003DD575F79F29DF15ECCD94A27F047FD0A5 +:1090D000F9970EAA791007469E25BF8958C3ED3D22 +:1090E000B186C7438D653C6E6154B81FC50CF2084C +:1090F0005D819A1F658B23D48FD295C2FD2889F993 +:10910000D57ED4034DD32C9242F291FB55B4BCF6DC +:109110007116DF1B781FA33ECBC8300F1D1455B24C +:10912000032D6A7C83957179A5F94DF479D3369D29 +:109130009F44EF47C92F0AF59B3C2EC8F74E87790D +:109140009EDF5CF016A2ED7F6E5D11857E93177D2C +:109150000D7354BFC9A3B89E7D1F72BF49D73E6E21 +:1091600017B95181B92A1CFEF58953911F64DDE1BD +:10917000F5142FD3FC5089552A3CD4B80FC217E1FF +:10918000293A393C6374F0F40ED3E2422A3C133896 +:109190007CCB8B5CE47792109E522F3C353F95F749 +:1091A00070077D5FDBB2CE227B089E9F91BD6A4235 +:1091B0007822FCBFA71FEA9622D52E55E139F1D1BE +:1091C000EC87F03BC1931E2B3D86CF29DB6E8BBB1A +:1091D000019ED3763E548A4FF63A8F13FC752EE7E4 +:1091E0005798D91D4C8F3715CA21DF83D7E0A9E1E5 +:1091F00061AFFF8E913FB65CE2FEFC72150F33103B +:109200006EC1FE3C4728DCB6A8F992C6FC6A0FDAAC +:10921000BBC37570D3F0B01EE186FC2EC62C7BC894 +:109220007F572BA03DD41F1E0E6FBB3C3C7C588744 +:10923000873FDB9C7D2FC2EB85ADA56FE1F3E7BED9 +:10924000DBA2105E7B773C34A71FB82587F07974CA +:109250007227F485DB8962F70EE40F331C3E23F19D +:1092600059C037B47BB7374DB486C66734FEE8B40F +:1092700086931F17F72FADA1BCC2FAB235C41FBB2E +:109280007AF863B71DF3102F953FE6CDE5F7FACBDB +:109290006BBE7A6506C035AFE604D19F11E88FCE6C +:1092A000ADF68441CDC76011202F12CB981FE3C7C4 +:1092B0004398D51725507E02F14D2FE639E3074A32 +:1092C000F57E0AE9D5BF09441C4C3024011FC7DCD8 +:1092D000A92B490EBE5934B92F9F6D2F3390FF67CC +:1092E000BBEA1F2C5BE03A8CEDB4F8D66E97F276B1 +:1092F000D1F7F36B1F2F0AF21776C6B01EFF1A7E46 +:109300001F3CAF669B807928436A6F25F99058A669 +:1093100030940FB7CEE67462CC9768BF7DFD6DDDEB +:1093200079682774E28DF62CC2838F110F3A6B9EF9 +:10933000243CB87215F78F74D69C8B0B8F073511B0 +:10934000DFCDCFB83D444E7A6BF8774C3AEDCAEB9F +:1093500019978107CB543CD0E424CA1BC427635916 +:10936000E051F4630F017C88484379C9F9B108F2F0 +:109370002A0AF623F6E37FD4E8A10BD6661984F710 +:1093800084F5F900D5B4EE7365B9FEA903ACEF928C +:10939000F300D4B864BD1A975C5AC3F3573BD77D2A +:1093A0005580EB3D5706F601C0657B9983E1F9CD09 +:1093B00002C52A600B9EA74FDEEAB0B909BD71480D +:1093C0002D9E7FA2D8958AEF67004E25C5625EAFBD +:1093D0001AEF19A67E075A87FF80E7A3E6925F4E31 +:1093E00022B9A1F9D119EA8D76C46F6534D64F3010 +:1093F00057274B84DFEEF1586EDF7727E52FF4FA1D +:1094000007793EDCF7F66F459B29BF52F36F79ED84 +:10941000DCBF55C10205685F531C01F976AB85BE00 +:10942000D75029C866F2AF95B895B9A4F7B8281FE8 +:10943000D6BDC02A911F6CD5AE64E417E58D22C954 +:10944000EBFEEC92BE7476997C46A5BBEFC067AE8E +:109450009F7B697C6631EE2F88CFDC30F77BF099FB +:10946000F78B42F90BEA9D75304F9E4A4F3DFB56F4 +:10947000E3F818BF8AC80AD247D5FDEAE9A88F5E8B +:10948000FA7F1F5DDD83700D43571BF1FD65D055DD +:10949000EB45E8EA413CCF20BA6AFF17A5ABA72FFE +:1094A00085AE94B92C344F3A8E7FE7795C9C81E786 +:1094B00059FE1FCE931EA3DAD9FA3C69C6AAA95C4D +:1094C000046743E7A396E74D6232C6992CDB5EDE64 +:1094D0003456E6E305FB3B99CECFC9747E4DBD7E85 +:1094E00017C60F1AE2F73CFCD4EF0E8F855F9F7E04 +:1094F000F6BF49AF7D7BA640F7C9E78DFE6A3FEA1C +:10950000A0C51B97A9F30CECF7FC67FB39F127D832 +:10951000AFAADF5763D4DDEABD81CBF37332C7ADA9 +:10952000F47DF3F66AE640B85FCCEFD95ECBF3A6E4 +:10953000B5BC66D74B950F2F9CC4F3E9D0EFA9F7C4 +:10954000776AF9CAF5B665A4E79F54ACDC1FABF3A4 +:10955000772E8B936FA17B8C7DFD9D91F3FE01FE99 +:10956000CEDBE7C8DC4FA3F37B96CE52E2E70D904B +:10957000CFD019E360C8EFF26C3E01E3B5EC4236A0 +:10958000F97586D802F47DADF29A1CD2034716BB5A +:10959000D3701C637EF7E72F4EA27C03070EA5E76E +:1095A000CBA067A6CFA33CB67F8E9FE09FE5E7FBED +:1095B00068CEE5DD9FFF08E13D79807BF472E0B184 +:1095C0002878FF789D9DBEAFF5FC6C59CD3FE84EE5 +:1095D0006981FA77EF3A7310FD13BE3603C3FB6D52 +:1095E00097EA3F6AB8885E6CD6D9475B7AF462DF47 +:1095F0001B5383F4E286F5CE7DA7C38CA3E9C5BBDC +:1096000074FEA3721BD78BCB6DDD26B40FCAE3BFEC +:109610007E05F34E8D55AC03E5E210A59AF4E144C6 +:1096200089513EF1FF8FCBB37F685CFEFE79A1715B +:10963000F9096A3E0AF278FCFE4F97E6479DC6F5A7 +:10964000868D466EAF78157817268EAE8FCB0FBFFE +:10965000B087E2F2ED7BAD748F6FCBBE663E5E0EDF +:109660009330CF3C99A9FA5A11F797EAF58FC74D75 +:109670008A356D12E2BB81EE13E23D41F28BECB50F +:109680006E437FD3783BCFE7CE7D67F14ECAE7D6F6 +:10969000F443D043492F2E0BD07799CA250723BE18 +:1096A000133FCD4FF1F15A81F06BD93C4E6F4BF324 +:1096B0007DA41F0E2993047E4FCCC3EDF8541E7772 +:1096C0008E44FC82A662268FFB4A474407C69DEF64 +:1096D000C3A6D3F1FE2AE3DFAB986EA0BF43D12E21 +:1096E0007427215F6E1594647C82CE44F71E9F8D93 +:1096F0005106E3DF93AA4F31D0DF933A54D09884D8 +:10970000EB6BAA6B4D42BDF015D52FDE5AF009E583 +:109710003F98C6833E9846CFB07F77F4C1F982FA6E +:1097200077043B92E87B08ACE543C2AB4C33E37F64 +:10973000E7C7E15F8EF474DA46FAC203828FDF1363 +:10974000B25BE93E5ECB18737225ACA7D96E266D6D +:10975000C23B66E6913478DF9C2045631CC09B9633 +:109760002EA1FFC81BD3F83AFA419AD3D219E6FBCF +:1097700037954DA1F879D3056030D0B37EECA8774A +:1097800027C3FB8D4280BE1BE4996E60984FD8368C +:10979000666672F0BD4C51D2CB4907C9055136D02F +:1097A0003D3F518D678B7DE2D9A1F1E949EABE6564 +:1097B000D6B288EE81C69B25DC6FF998920FE99EA0 +:1097C0005BBC99F282CA4D8C7FF7630CA373D1C343 +:1097D000AF7E7D685CC1680B5DDF460C4C531EF6A6 +:1097E0009695881F0D0853CAE3BE7725F2A5869E7D +:1097F000FA465E8EE0E5AFE7D5AD44392833FEF793 +:10980000491A3279DE65794209F1E1725320EC7729 +:109810007E2FB61E99F914753CF63F39DEC631E647 +:1098200045BEF1171FAFF75C407DFE0EE36AEDF415 +:10983000E3EAFBFD4FB5EF6F9F89F3B5BC7A46793C +:1098400010A422AAF7D9504F36AAFCB03E778ACF8F +:109850002F233FF070BA883184CDB3ED9F3E82C68E +:10986000E749BDC46F697CFCF64C4DA11FF923BECE +:109870002F49EAA59B9EFC0B753CA87A15E5C3D63B +:10988000F942CFBAA5C1BDE3FEA62CDB8F761CD86A +:1098900019729C230CFDA9791AD43E8DF26D283FD4 +:1098A000868D65C447B4F646755E7DDEC66E152F9F +:1098B0002E376FE334EE6112C91AB207BDBF6DA136 +:1098C000FC25861FA342FF5C9644F7E1EED5DAD96A +:1098D00019D971DA3944B0DE1FB4D392B482CC46C0 +:1098E000E23DC38DA327D0DFA77C74F7833FC1FC83 +:1098F0008DCDCF6CF8233E23474EB87FDA24BC478A +:109900006F70A8B9D4643F69F934B67FDBFC35EADF +:10991000A9FA7C95C6F12B5AE8F882CF311DFF2EAB +:10992000B2A0A07FDF62B36DA7EFF95805B21FC4E4 +:10993000871269FD4995A1E7DE2E281FE077FF3CDD +:10994000F709C447231CA1F9377A7BA3A9E75C4335 +:10995000ED940784F071EFD7E6733923EAEE89B608 +:109960009A64FA8E6DEB46112399AC759D85F8D9F2 +:10997000EFE72F5989DF19BF03191ED4B75F63A61C +:10998000BF6BD56E97AE5B8465559E6971E607AE79 +:1099900018E50BFEFB47AFA29C85F95AAE31933C0C +:1099A00060C66ECA63D7DF0FEF6367E9F0EE6278D7 +:1099B00076C3FC5835DFC04772A5C7BE1F6DE0F700 +:1099C000A0471BFE25EE41BBE787B7EFBFEF3D6821 +:1099D0008AEB25F4A55F2DFF6F4354EA62DC7FC359 +:1099E0002C337D2FEE72EDDED6752B495E786E65D9 +:1099F0008E0C47DFBC30D74B23097FC42691FC7106 +:109A0000BDF8C5EDDA5FCC33F5FC9D166B109FD425 +:109A1000F2821E52EF153FE46AA4FC19AF93DF2BCC +:109A20008E685949F6722BE8619857A5D9C727A7C0 +:109A3000A54F1128EF47F1E0773D4EE6AA79415254 +:109A4000687E0B53F3FBB4F95AA7A5D37C5EB4C769 +:109A500007C003A353CDDFD38DD7C3AFD1EE0EB272 +:109A600097C1EEFEDB7CD8DFFD36073AE3A0FE654A +:109A7000AA6793622FE91E6817FE0AED7E50AAD0EE +:109A80009F48F9DF0A551CCD00800000000000004F +:109A90001F8B080000000000000BAD3B0D7054D57B +:109AA000B9DFFDD9BB1BB29BDC0D9BB8C1106F02A7 +:109AB000D1203F5E304913C572F303244AEDCD0F28 +:109AC00009BE01DEA26871ECD4ADB5BED03ACDC5F9 +:109AD0006C4888084BC4065F1D8D54FBDAB1D5D4A1 +:109AE000D7D7878EED5B90E7F84FDADAAA333E1BC3 +:109AF000D1F2FA3A9D37E96BB1E98C2DEFFBBE73D9 +:109B00002FD95D36809438E3E1DC73CE77CEF9FE51 +:109B10007FCEB655D53AF91180E350080AB61F85B5 +:109B2000CC35610078DF6706CC2500A7E86F1540CB +:109B30007FD20729EC836A0260BB0E263775E07C72 +:109B400058E88327B15122CBF9FBD690ADCA4180AA +:109B500012BB12A078667D1BEC57EFC2F1AB7C63A1 +:109B60002D500390D80ABA834BB684922AF5570336 +:109B700038801BAF351A031508B7F505DA086055AC +:109B800078240232C0B2E70F94C5687FC7FA7975AE +:109B90001DD054FE5BEC9FB09B717DFF1B8A791F2B +:109BA0007FD10FC770BD1A5560182148CFAC8C4EBD +:109BB000E279D4E089F7A000E0BA29809680587B4A +:109BC0008AE04F07A0A57AA6DF8890D3FBCD81D28B +:109BD0008CF9ABF58A8C71052C3325E1B9A38B3256 +:109BE000E6856A6B743A6F9BB13CE3FB0DD50D19AA +:109BF000EBA1453D3E89FD95F8DFA94A8227FA3C55 +:109C00005E01105C82FDB4F52AA4F571FC1A3B14C8 +:109C100039B1183B9F81CF9C52882EE60620BA802E +:109C20006C3E897829793E30998FF803CB32222512 +:109C3000880F1A3200BE6CE3E25AEC074FC884FF6B +:109C400047F271EF52C4B33E29139D401F97F83B72 +:109C5000C0F830223BAA5A3C0FA2A02770DEA5E034 +:109C6000483AF6435148527F3E24793EFE251F6C08 +:109C700040B60888F5051D60EEC5F1FC258E24610F +:109C8000BFA8154C05E105CD0989CEA9E37A05F9F0 +:109C9000A01452DC2F6B85897E866FDD47EB4B7BF2 +:109CA000411F2825B00E8F8F6D0487CEF33898E0C2 +:109CB00057081F36C002000DE2DC5E064611221175 +:109CC000BE0DE60AEA57C1242115A93A2651FF1212 +:109CD00018D7A90F90027B2936936AF84480A70011 +:109CE000F1A9C7AFD92DED74C2A30B4E1EBFD1DAB7 +:109CF00066237F77DF545B180BCEBE4EED7D71BCC3 +:109D0000E5EA99FEB76D83E542ED5DCBF2A2F6BEC2 +:109D1000C4E3476DFB2B36D26319C20FACF8F4F8DD +:109D20005FA6097C2624301D9C9F78EEFAE8161C5D +:109D3000779E0B985540F8457C125FD407A65E6964 +:109D400010EB891E11A407E1BB6809488483F9441C +:109D500007FCAE211D76311D930CB73C0EE60E7745 +:109D60005FEA97221D882E63A0CF21BC2AF14F47BE +:109D700007FE4338971C0A3C3E2C1176912E0B2E81 +:109D80000A5DBE752174C9A607DC3B17A0E16CFB18 +:109D90003A4CC76F49A93C69019105E983F7919055 +:109DA0003E84CF28087A680026E12917FEA99F572C +:109DB00003C67DDC17F3899E4EC30CFF1722FF8B71 +:109DC000BE90AF30D241F4059D22242FD88FDAE324 +:109DD000BCBE682BD80F94123D2C469E0F62DCFA55 +:109DE000614AA2B65232995E0B145BA67EBE9412F3 +:109DF00048464A923E28009DE9330FE2DC467C53F8 +:109E0000874F91BE0ECA634E05B5CF36D23EFDEBED +:109E100050C390CA0F8D34325FDE0E7A15F25DB9F1 +:109E200066B1FE2EBF52351D231D5FF7317C30AC6D +:109E300003646FCAE5100CD7CCEC9BF099D124D207 +:109E4000EB58E8C491187E9F53AA80DF9CC1F37140 +:109E50009FB81FC1542E257910F211ADC7B384CF1E +:109E6000D46F5155F06D701BE20FF1B19906104F90 +:109E7000D2D0BFF3F7479A85BEFBAE1DFB88F885AD +:109E8000F413E3CF029DF4936E02EB4DD9707E4341 +:109E900076F1E490DF203E85E4A815C07DB6B8FBDE +:109EA0006C19F27F2015A4DD33E18794A79F2B69FD +:109EB000BD5DC8FC6C4A10A83BFF7517CAFFD05B9C +:109EC0004CCC764EBE6D7C6665E1E492D9E76924A0 +:109ED0001F73D3D7093A6911E4A7208DBFC4E3E704 +:109EE00082E3EB3D9C21671E1C5FD46638BEDEA377 +:109EF00042DEC86E213D6F43BB358CF8FE474BD721 +:109F0000045F4EFD27D9F39BE30526D9734611CE96 +:109F1000BB25298D0D233FDE0A718DF85482850EF5 +:109F2000D16FB32399C338A572D7D602F617A045CF +:109F300027FC48A96B95538B3F051E5D3C6D4EFD7C +:109F40008FCF08115E43F0A1375E3933FEC78D0B0A +:109F50008ED51AA4B483D544DF7C97BEA8899CD73C +:109F6000F09CBE4F0A615847EECFFFC61BABF07C9A +:109F700003BF504CA582E6696021BC3920EC783ED5 +:109F8000C9E902E297F1D41DC46FBD853ADDD79BC4 +:109F900007EE3C076216DD331FF500C195F37733FA +:109FA0007FE6176886C2CC8F1A27FD1E01E4BB121C +:109FB0004635FF156BA914C9577153C0DC91095F71 +:109FC0003A45EB112694B8F790CEDC7F29F5033C97 +:109FD000D478CADDCF0AA4ED97D5F745D3FA20C6C9 +:109FE0009DF4F9A606A934BC9E961757CEBC7307FC +:109FF000835AA6BC64ADF3E8B1C427F8635E198C3C +:10A00000EDC0F30E0D1D6C247D335A0C861F8706A0 +:10A01000377F47029CDF44BA98EC4F0B8CF925DA66 +:10A02000C718AEC6BEAF2CC8FC73C96FEDD41D08EF +:10A03000E70BF57EDD409CCCFBBDA537E2F86D65F6 +:10A0400001D342FA26DCF94E0BFA5962FB5F915FAD +:10A050007AAB7B5EA605CAE1BDEDC2CF52C35D3BC4 +:10A060005FC3F9FBE629A0905E53369A649F6E5554 +:10A0700001E616617FBF8FFD3EF4EFF83EFE964C81 +:10A08000BFEFB6477C197D5F969FF8F576F403899C +:10A0900068AE1F38D00EBC2F9D67EE8ABF1F3E04EE +:10A0A00023AC3F97AA13B29EC3AE7AF8979E0932AB +:10A0B000FE7F528C78A575605B7762DF8F78247E97 +:10A0C00045455D508B78B2E89F06F9C93FBA8BE6EB +:10A0D000FB4F22FFD27C25D87227D1E152174F20A7 +:10A0E000CE65E17F74EE6C7FD89FE50F679FDBA3A1 +:10A0F000C3631E7EEAA08EF083FE39FB07DEBDB28D +:10A10000EFF3421F6A0EE4A59FF605B84DF5E9DCB2 +:10A110001EE98B727BB4CF801674AC5EEAABE6F6B8 +:10A12000E53E93BFBFDA57CFAD878FD9F44DA8581E +:10A13000667F61DFBDF2180993BA447FE50AE2DB6E +:10A14000B714561F3A1879EA02B643A0E2BCCB5ABC +:10A15000D5318BEEE2C63F97B87CB6D83F75D88F25 +:10A16000EB92A560DE470BD16E6FAD99897FAE9BF8 +:10A170009267E40428DE9933636780E29DB919FD94 +:10A18000E6C0A519F357EB0B32C63DFA3ED628E4DC +:10A19000666D7471C6FC7D2D4DA92F905FDFE0D7F1 +:10A1A000159DE29FAB33C66FA8BE36031E28EB4C4D +:10A1B000D2D3451BD3E8C6F7CFA4ABB6EDEC719074 +:10A1C00047E7F7DA33E3A1D9E89BCDB71E5E8B4EA4 +:10A1D000E355C495098A2B0DBAF712690B82DA731D +:10A1E000DA2FB1C00ECDECABD6637CB9ECE2C797E9 +:10A1F00005145F56E48A2F3FD2897FCF195FB66678 +:10A20000C6970559783B577CA97564EA95F3C5E76D +:10A21000E6F2F81BB514EFBDAEB01FA8B4C6D9FE68 +:10A22000CD9D50CCB508B7D8F5C74224F3386F732D +:10A23000ADC6FEE53E988C92DDDF2B215691FFE7FF +:10A240002E314B49DF3C1DB64A6EA238BF4D360F4A +:10A25000E292171BBF1925BF63D78EC7A36894600E +:10A260005187CCFB261B4F6C22B9520DF4E3246EB0 +:10A27000ADB11CFE8937FFAB033EB6037B37696384 +:10A2800012CEDF1BD2BB3750DFDD0711C2F676B42A +:10A29000F6F231F2FFAEEC3004BF801325FA3FB87E +:10A2A000A9AE948D948AFDA534DD643B3E1C32AD8D +:10A2B0005B887F7E1304073F3D20E90512D98B4D53 +:10A2C000B2FE24DE73B475C5BB5BB1BF2BA8992465 +:10A2D000F089705D29F197B219DD1EEC8FB48EBC48 +:10A2E0004CEBD52A99FB894D971F23F779B4586F0A +:10A2F000ABA4386F7525611A94439FF4515E231106 +:10A300003E11A5F5FDD788F5B3D147D1D3EC39700F +:10A31000FE82CFAB2C94531AC2515E38F15782A7FC +:10A32000A4DB71D6E3997EC57058A32001D6FF7CCB +:10A33000E1F71C9554B965111D4751E6094F9B374C +:10A340007514523CB5D937599CCB5E0CA07E4D5D3F +:10A3500091E66F4632FD846CF8FC5747F8C53F59CB +:10A36000748D123774C1BFC48D6BC652843748B622 +:10A370005652DC1B147679363CA8C14C3C78F01957 +:10A380001EFE4FE9CDB3F2D2F080D74A91BF73479A +:10A3900087C4F4FF22F141AD3806C51DDEB9D4569D +:10A3A00099D779FA01F978C338F1878BF7289A0C95 +:10A3B0009243EF1C5F75E1DD739AAF706A49DA3939 +:10A3C000566A2E3C93E3E2AB342157F02BC57CD286 +:10A3D000C84127D77FE3F51533E3AA7BFE2B0E6830 +:10A3E00019FA7788F6C77BBCBDB1F3ACF1F2A2B124 +:10A3F000CC75DFE9003EEF958A75E404F95257C841 +:10A40000634F22A8C557C82CCF27D1FF22BB361BCC +:10A410003C8FFE2C6225CC5D407ED9CE4807F3F9F7 +:10A420006CEBB4B109AB6219ED0BF171E4AF45D13E +:10A43000CC7379F3BE73FA5E5F8139741E74C8C938 +:10A440001EF9C75216E9693FC291B0AD7EFC6EFDA0 +:10A450006CF7F6431A7CC4E74792D0574E18F8BE03 +:10A460008977C7587EE0D0D48724DF894525C63058 +:10A47000CB0B4417D6913F22EEE5CBA2D3709E8042 +:10A4800033B25CF8A9236EDF592AE042BA9CE2FAA3 +:10A490003C37AFF242C702C6BB467A8688AC5AE563 +:10A4A000C41741F5878E8EFC3027B80FC2D8FA2327 +:10A4B0005B1C6A57951B7BEAF15C238B64B66323B4 +:10A4C000A1D8E303A487160573CAC76BAE5E1C222E +:10A4D000BEE5F8092C99E44EF284046232D26B9402 +:10A4E000391FE0FD8EB0C867E9C9FA9B118F6FBBB9 +:10A4F0007C81F7E1F5D9F0DF3D13FE13C4AF0917F6 +:10A5000038C1D982707EEDCA0590412971E33EDCE5 +:10A510002F6024EBC95F98ECD0C5B8BADCA4FB8FE0 +:10A520008473EF37E9EE67C97189E65DB251AC8794 +:10A530008058B7579ADA705CD093E589F6A7F17C1A +:10A5400033533F64C3CDABCED4575A59E6FCFF75A5 +:10A55000F92F3B1E7A40CA7DCEC24E71DF55E5C051 +:10A56000F688F8E2BE1C7C912DEF1AE53F11EEDF74 +:10A57000880EBC9FD03B4175A229BF86EC3B98FD5D +:10A580008CD8C37CDFFBF26FE43879E00691E7D02A +:10A5900054A1B7CB362018B4C7F64F5A1CEA2B7714 +:10A5A00083EE0F9F89874F1BEF91BD71D2D6873BFA +:10A5B00081CFA9A4C781788FA4CFB891F64DEE5270 +:10A5C00080FC80E476FF865C76BBB8C3E7E95D8EED +:10A5D0006B55972FC0AC0019D71F784BE1BCC081D9 +:10A5E000FA9D1C17276CCD902A284FF1086CC7F1F3 +:10A5F0003F5A32FBADBD87EEFDF5ABB8EC784B654D +:10A600009D24B31CC1AD38FF38C6C5E43793FC6543 +:10A61000E46310B181BA99FD922D95BC5F02F79366 +:10A62000CEA2E7541BE3D66567C23B6D8FB3F2231E +:10A630000325B1DA4EBCDFBEA0A8B3285E7EA42BF2 +:10A64000725E791D0392A95ED22B1B81F1106A1BE9 +:10A6500081ED944F888A38E348AD5FF0D776C98D95 +:10A66000CFA0053C3D857FEB361A0FCF25FBF28E40 +:10A670001FAA70BCE9A9D755EA8F94CA75143F5F29 +:10A68000A54DDE7F158DD7F9587F3422255319FC4F +:10A6900091F2CB513E8FE6B68A685312B5CD81FC5C +:10A6A0000C7DBD5ACF8C3FF64C1F510A893F753047 +:10A6B00025C4F39E46D32A24DD634EF6D3F73DAB83 +:10A6C0000D73D8207F38334ED9D3A6097D5A21EC9B +:10A6D000CEC861E361F2AF067BF3D8FF7CA04C16D5 +:10A6E000F75E0863C40F6D46665C33325EB96B215A +:10A6F000C959D2C7F9F2EF8F8BF95B772C1FA3B83A +:10A700005477FDD5ADA54DEC87C280987743F5E22F +:10A71000ACFB4FE8C417C9ED3E20FC0F96DD3C446E +:10A72000F9D00F12BEAB495C5EED3432E2C22D03AC +:10A73000B7729D6840839BE8FC7B3669CCFF7B8ABF +:10A740003F38700BE9E9E2398CE7D14D5A692C4D5D +:10A750001EFED6E9673918DD24FC8B621962E339E5 +:10A76000C6FFD629F4D0E76E07BE4F01DA65033F76 +:10A77000196A3CE5277C9401FC335D27FAD1437CC0 +:10A78000FF5619AAF08823918DECBF65F359B0AB41 +:10A790008AE19DB68FF572061E7D7E3BCE79EE1B5B +:10A7A000C0207DD5D28A7D8AEF376A40FCE68FDEF5 +:10A7B000CDF72CC27E1EF603AD4947C57E6061EC25 +:10A7C0006AF25B5FDCDE334479167F44D689DFFCB6 +:10A7D0001B6FB33B697E8D0FF2707C000C294AE73A +:10A7E0007424207D6D40AC95FCF591A8AC53DE66D9 +:10A7F0005D62FD36DA7F5D640E109D37B7C9BCDF40 +:10A80000494BE3A45531391A94FF2A09B2DD7DDFA3 +:10A81000177FB807E7BF8FF47260E65E873A2BF9BF +:10A820009E794666FC1C8024DBE195D6C446DA6737 +:10A8300065BD46150D38D270E200F9EBA3B57ED3A5 +:10A840008FE71A6D9018DF1FD7FAC6F0A8F0536D86 +:10A8500042A17D7FFA31F246452EF93DBBDC64CF43 +:10A86000DF53DF11207ED809135D841F675A66FB12 +:10A87000953DAFA14BD07F27E285F0ECE079AB2886 +:10A880002E9A42B942E8E169FBBBB760FBA54E9541 +:10A89000E77DB55476A82E34D8A6B19C0C866243C9 +:10A8A00015D4477EE7782812637E1E298DB01C7A66 +:10A8B000FB8C34745713BFBC519BC77EFB973B4F37 +:10A8C000DCEE2C44FDA1FCFE5F9FA1F8A94C637A4D +:10A8D0000EFAECD4ABC4D76DC25F3C3AFF1E96BBF8 +:10A8E000818D3703E10D9CF83B54B71AA86960F8D5 +:10A8F0005EBE6164BEC8270D44EE7228BF91AA17E0 +:10A90000F905ABF820E7F3BCBC52A3ABC716FBE3D9 +:10A91000AF54D1BADB55511756CA12A40FFC945745 +:10A92000A2756A66BEEBBAA9CC38785E561C9C9DAF +:10A930006782C0C4C24EB4A7BFEBCCCC2BD1155894 +:10A940008E6BFC1C2F8ED68B3828E98B97EA4BCE6A +:10A9500094E3375D3F78A22F801C00F0F33E9DFB0F +:10A9600005D61F76CC45506FF545F9FBE7573E2ECF +:10A97000A5AFDB53B33E60B0DE988C12DC6C7D91EA +:10A98000CD07BD9D7398BE18A701D177CF14307E37 +:10A99000430D2B52C4A727FF041C877EB6652208EF +:10A9A0009567AE4FD139FD94FF12E73C4AE7F45367 +:10A9B000FE4B9CEFE53E83DB57FBAAB95DD3052236 +:10A9C000CFEFE983CB501F20DE5ACA449FE49FECAF +:10A9D0007051E4669BF8CB1F557592EF40593225B4 +:10A9E000A5E983D150FC5DB2CB83C541E6BFEC73D2 +:10A9F0005DDE25BB762F7E13C1DD837009EF2F6EE0 +:10AA0000FFEF8716D03E6F29CC57451BBBB7B1DE91 +:10AA100041BD90C7FE86D087C9E220E71D46B757E3 +:10AA20004951EC6FDE211CDD73CA3DEE3386EB8E9F +:10AA3000A0BEA6FE20CA39DD67B0E1833B689F8FC8 +:10AA4000FF32872A7C48EF5FB1DCBF8101C8DC8B15 +:10AA500028F79E9CBDFE8B43DF233933C0EE39249B +:10AA6000EECF7A70343491A4FB0FFE52815C78BB38 +:10AA700050BA82757E7EC8983A75F8542447DDD066 +:10AA80001275C3FEF11F71DF59075085FD477D56D2 +:10AA900080F8E0D11DF259EB868FEE387BDD706CCB +:10AAA000BF0C7E7DE61C97C224E7592984A73AE0B3 +:10AAB000000D617B4357EC962EF623455DD168A0CF +:10AAC0009C03F5F539E43F1FB5ADAD3C1E2962BBD3 +:10AAD0001F55C75364D7A3542F37E8FD82C3754F62 +:10AAE000CACFD2FB85ECFBF7FB269BF87E3885EAC4 +:10AAF00095D9F54929F86351DF5F20EA905E7D72B0 +:10AB0000993679F07EC2D34D01C643FF73D7BC435B +:10AB1000F52FAF8E1F75EBC0FA36D077887BDCDB64 +:10AB20004571D00BA21E0AD7E03D96D3269395ED32 +:10AB30004BB9BEB983EE71AEF39F6FDD709DABDF95 +:10AB400090B9C7489E7FEDE2D39BF74D92C75AF26A +:10AB50001345DE1A0A34D6F34D4F0541217F39A43F +:10AB60001D2439D90293AB499EFAC3C26F4BECF353 +:10AB7000B1DF36DA65F03EC59AC5EF178ABF966732 +:10AB8000EE403089C37A01E591AEE9B446BBF81CCA +:10AB9000C9AE0E3AC790C2FAEEFDAAD5FC8EA94DF9 +:10ABA0002A64795475AB3C5D5F1EEACAFD1E695587 +:10ABB000F95407EF1F9281E2AD449EF9B241F8FECD +:10ABC00089CA70DB40BC5782ADBA3484F7EC0F1EE3 +:10ABD00067FAACAAF22F27FD74C8B5AF8950EEB85A +:10ABE000EE59171FFFD01EFB21D1E17A986A26FD8E +:10ABF00086A26D3AFCAE45C46B87485F8A78F75EE3 +:10AC0000B96E26AFF5922F7688EE6B7D5FF813FE56 +:10AC1000A8F0EB3152E37CD007EDD67304771DF139 +:10AC2000790D2B2A7872790E3977CF714797F51FF6 +:10AC300004EF98BBDF32DDE2BAEB3290CDFE485A2A +:10AC40005DDD38BFBABAA4FF58D4D3AF157C0C2F42 +:10AC500038820F9B40277942FE3B46E7F3DE972C74 +:10AC60007B7E5B05D75D2EB0BE9DDF61BD4DF04E96 +:10AC7000D9F6BBD4BEBFBD0718DE79BED758551E66 +:10AC80008FDA48A7C13CE1373FDD686EB0D3F23FB1 +:10AC900073D60B7B3267BD88C717233B4D88776F10 +:10ACA0006CC72F87FA00D12B1BFE401F8C531D68E9 +:10ACB000B6FDB55D7705284FDC5FD614A0F768892F +:10ACC000605321F507CBAC28ED3FD0D7FADC4755D0 +:10ACD000C44782EF9DF9221F9144FDECA4E5494F42 +:10ACE00075297CAEE63248513EDD1F147E911FE38C +:10ACF000456329F9CDF56CCFF1FB38A50EFCEB0DC2 +:10AD0000116F5B265841728340227CA18E3CBD9E10 +:10AD10004C5E73591CE85CB3C1515A703DC5A365C4 +:10AD20003AFB2157AED7196ED89267E278387F7C0C +:10AD3000ED3B07BE8ACE812F6F9E2777D978AA5C1C +:10AD4000AFF0F95E0CDFC3F7824F9A59CEFCA8F042 +:10AD5000A89E5FBD5EE8192568412CC4E1BF44F898 +:10AD600049D0039B2533F8455F91F1ABE8715EE76D +:10AD70002F3321B694F0A14B848FECFB2F7BFEBBCD +:10AD80002D84B757B608BDBA4A75F5471CEF82FC4B +:10AD9000B9D3D56FE0DAA5B63C6177D6C1CF8222B0 +:10ADA000AF2DF87419BAE381A233F5ABD73EEDE6C7 +:10ADB00095B3BFFF6E7D9EF0878C71D6EFFDAD021F +:10ADC0007E2824FCD083432BD87F58535A35275DE7 +:10ADD0003F5EEC3A61765DF05C75C019BEB10274FD +:10ADE000CE3FEA7739EDC6ECFC713FF18F8FE42658 +:10ADF000C0ED19E3E576D424B99A6F398074DB1974 +:10AE00008E47897F060E6F7F87EA24EAEB8A49FE28 +:10AE1000A6AADA40F3D614C7593ED696594075A56E +:10AE2000FBFBAC1FA6C31D6E8F6D5B4FEF84F471EF +:10AE30008BE00421E5903DBA7EAE15B773D0E16E8C +:10AE4000577F7CD06E7F693DF2E12AD29D2B007E38 +:10AE5000695B7752FF7CF5D599F2D41A20BD7FE16A +:10AE6000F2D411A0FB0D96D9FC4E6BF0670A79580D +:10AE7000A7E70DBAF23438FF1E88A5C9D5EEF559FB +:10AE80007A27E2EA9D88C57231E2EA1955B7593E40 +:10AE90007C244F4BD2F44CC4D33316CBA31AF1E429 +:10AEA000C9953F92A720BD0F9E6A263F6500C43B0F +:10AEB000C66CF9FA7E7BEC61A2C355C5FFD7596118 +:10AEC000CCBCFF340C214F83652EBFCF7F96F9FF9A +:10AED00024F23F3D16EE0F5666F0BBD7AE9C5620CF +:10AEE00085A4B86E5AE2F6B3D3F9DCAE9ACEE3D6B7 +:10AEF0009A9ECB6DE37498DBA6E94BB96D9E2EE567 +:10AF0000B6651AF9FE6AE4FFE90A6ED74C2FE676B9 +:10AF1000EDF4226E5BA7AFE6796DD3CBB9BD7EFAB7 +:10AF20005A6E6F986E10FB504DA82827FF5339EBCF +:10AF300022F0BFE9507D74E0F0EDEF107E7CBAC6E0 +:10AF4000799444B88EEB3D3E35CEFC7FB04CE8F7AB +:10AF5000B541419F6CFEFFA03DF632F16D36FF8397 +:10AF60004FBCDB52E9DD560DFB396F327F9FE1EFBD +:10AF7000BEF417CA83A2FF718CE877A1F6FFB45F15 +:10AF80005992E9570E1667FA9503F33DBFD23F4633 +:10AF900075B0AD92C1EFC4F23B621FF2FE606FA1CB +:10AFA000F1585740277F2A115E130D627FF34E053B +:10AFB00028DF87FEC56F781EEA07B21BE72BAFBFFD +:10AFC000B4851C78F397C17139FE29FC93F7E99F8A +:10AFD0000D67CAFD6CEB3CB9BF1CAAF372D9D9222C +:10AFE0005FB3907B5DC87DA2CC1EA27C4B224BEE52 +:10AFF0003D3B8A78C890FBFC6E57EE5D392E8A88FF +:10B00000771F4524F7C857E16EC3ADFF64DA51D509 +:10B010009DEF6B15F5ADE688D0AB6AABD017AA9E55 +:10B020006947916F8ABB73F8138E2AFCE3B6AA7F37 +:10B030003B6DCFC8AE1645C252216EADFF69D2A19D +:10B040003CD6617501CB77B61C25F415CCE787D5C6 +:10B0500066C825FFE72D4761CF8E586C47B2E77968 +:10B06000F23470B88DF1E2D995C3786F2BCD9EACD8 +:10B07000D5051ED09EACE8CE614F56955B313BC7DF +:10B08000399BBA855FFADA75B6F017D14F243F25A0 +:10B09000E1CBED0734750BFFA7A8D5FD7D8501F148 +:10B0A000B9A8075B5B53CD54C340796EA2FDAFB323 +:10B0B00026FB4906FB8323113A3FCA6733D1E1429D +:10B0C000E5B3BA5DF885D03B97FD16AF3D17DF7B42 +:10B0D000FE8EC7FFD9F39EAEB036E4C2CB0FBA45A1 +:10B0E0005C7370E8D90CFED8A32EB8DE3472EA5532 +:10B0F000CBBC287AF5FCFC8AC368E758AFCEEE5784 +:10B100007C25171FCCE6577CAD5BC49BE8576C27AA +:10B110003AAD5A22FC8A1F74C3C5F5171AEE627C39 +:10B120005DA8BF30D27D767FE140B7E72FC4596F6D +:10B13000F85DBDF169FD851CFEC1A3CCBF30A550F3 +:10B14000FD0F516D8A7C88D023A8670ED238C6F1D6 +:10B15000EC2F1C0C0A7EB15C3D734797FD04D16354 +:10B160004FBDF0172E961CA0DFF734C13D5F793834 +:10B17000DF79554FAC1C9A243F0742497A37DD4F9F +:10B18000EF95287E7C2F24DE11E05128EFFF4FCA77 +:10B190009526D9B9D1FC6F3C46F37B1D15E8DDE05F +:10B1A000FE3E917FDEEDE6FFF6FBE2FF328970EEB8 +:10B1B000DFE1D70FE2F89FE7143832F2D49FF3CAE9 +:10B1C000C7E85DD031570FF96153612EBE9A399FA0 +:10B1D000789F4B4F574EF1EF3ACA74CE93BBF88924 +:10B1E000683638087FE77C99EB233BDBBF7880E447 +:10B1F000C76917792E2EB4E278645E54E43BD08D93 +:10B20000A94FCB8B28A09EA07CFC10BD514FABBF9B +:10B2100016DB1847A7C51921D3CEE81B100307F783 +:10B22000D91B91393F3FB852C44583C17840CFA163 +:10B230005F76F565BE53CA6E95454F24E92DF183BF +:10B2400051D5A4F4E870754D1BE53113BA78B4A458 +:10B2500085653B571D3BDC23B9F97893EDB6FAB908 +:10B260008EC25C76C56B87FA449ED6EB07168E5B62 +:10B27000C49F5A8565F3EF75C211C949CB2FFFDE14 +:10B28000D5133B2533B50A91B63324EC44C0485A54 +:10B29000329E77A0F836AE47060C074ED0F78549A8 +:10B2A000F810DB488916CB5977EF11F1CC4E5F8C43 +:10B2B000F7DB59AA729D726745EEBCD75F5DBDACE6 +:10B2C000859B6CCEFF8755AE2767CF9B72F949D31C +:10B2D000ACA8CEF1F76D06DD2B311F389739D57349 +:10B2E000E7533B82C49F36E747F6BB79126DDE36E3 +:10B2F000C6FBEE7255A73CDC6A65DD0EDAE7415409 +:10B30000BBE49F64F3817F7E4D1ED73FD7C9FC66A7 +:10B31000339B2FE8EDDB04F9696A8AFD251FBCC366 +:10B32000798BDD3547B86FC084DB17FCE2D59B22F3 +:10B330002E3F9E61275C7A2549AE72F0CFFDE51362 +:10B340006CBF1F6898D840759B602460B6E23DF6DC +:10B350002DB739BFBDBB5666BF35DFFD3DCE83EB94 +:10B360008AC28497DDB547582F679FC777E415F6E3 +:10B370003B826A8AF317C1B28F389E7DC83DC7DA17 +:10B380007A214F05A6D0C3055D71D071DFE2B79475 +:10B390003103FBD2BC971D1FD50F6E126F8B352D5D +:10B3A000C57E467EFD1A89CEF766A90212C1505E9F +:10B3B000E0F7BA600BF9F6DE6597746919F17D184C +:10B3C000D2FA15E27704E9EFA840D978D6F766BD3E +:10B3D000EFDD7EEC681ABC9E1EF75DAF5B673BD766 +:10B3E000FA3FF76D3B761495FF83356797ABBDAE9B +:10B3F000DEDBD357CF74F2F8CBE3B7085D71C5EC51 +:10B40000EBF787C773FA25A33D82AFCFA58F0AFC60 +:10B41000E36CE7F75E379E9187FCBAAB1FBEDE2375 +:10B42000E4482F9FE2BCE55EF79DD3DE3CD8F06C8C +:10B430008E7B3DD6A309793ACDCF9E1FF0CE85F9FC +:10B4400001F3BB44FC105991477E00E2F3657AE7B3 +:10B45000F6A78866409A3C0F8432FD50CF0FF86DF6 +:10B460008FF0035E2CFE98ED786130C5763C6866FF +:10B47000E609B2EDB8E68B715CA9956A9E9EE17A09 +:10B4800057F0ED6F3CE5903E48EDE2FA513EF26F29 +:10B490009E488D3BB9E8044B32DFDD7CB107F83CB8 +:10B4A00011233ED148F6A54BE57AC87EF9BD431F6E +:10B4B00012BA9271B05DB8C3CCB7BB27F8FD8ECB82 +:10B4C000F7E7A227FD7D52E7FE6E85DE715CFB6625 +:10B4D0007DAEB8C36BE97D55E67BF84F2717CF7B70 +:10B4E00072910779422ED6C903E40FAC93F9DD0AB5 +:10B4F0003DEF55EBDC9423D5FDE964746F7A1F248E +:10B50000B9F5A40533F2029F17EF5E4E6E13EF6894 +:10B51000F877860BE877A193FCFBC1CBE895AB32BB +:10B52000A3DF4E42994CF562E788249DF6932EA541 +:10B53000278FA64CEB1682CD6DF6B92F87387FAFDB +:10B540008624B757C238B74B6082DB6530C5AD057E +:10B55000426F994745DD6305980A7DAF019BDB3A51 +:10B5600088735B0F496EBF79ED97FE70332EF9AF8C +:10B570001EB72E7F1A2F02AF39E43B458FFEBDFB6D +:10B580007B787EB0C760B93B17BD07C242DF369BF0 +:10B5900013ECDF878236EB615F44F0B707C7374BA8 +:10B5A000BEF8EFF5A3B27F67F2FF2B2134C6D03F80 +:10B5B0000000000000000000000000180000000073 +:10B5C000000000000000004000000000000000003B +:10B5D0000000002800000000000000000000001033 +:10B5E000000000000000000000000020000000003B +:10B5F000000000000000001000000000000000003B +:10B600000000000800000000000000000000000032 +:10B6100000000000000000000000003900000000F1 +:10B6200000000000000000380000000000000000E2 +:10B630000000000000000000000000000000000802 +:10B6400000000000000000000000000000000000FA +:10B65000000000000000000C0000000000000000DE +:10B660000000000E000000000000000000000004C8 +:10B6700000000000000000000000001800000000B2 +:10B68000000000000000001C00000000000000009E +:10B690000000001C0000000000000000000000137B +:10B6A00000000000000000000000003A0000000060 +:10B6B0000000000000000001000000000000000089 +:10B6C0000000000200000000000000000000000177 +:10B6D000000000000000000000000010000000005A +:10B6E000000000000000005000000000000000000A +:10B6F0000000000000000000000000000000000347 +:10B700000000000000000000000000AB000000008E +:10B710000000000000000008000000000000000021 +:10B720000000C00000100000000000080000C00879 +:10B7300000100000000000020000C0000010000027 +:10B740000000001000009FB0000000000000000892 +:10B750000000C08000100000000000040000C0884D +:10B7600000100000000000020000C0800010000077 +:10B770000000001000009120000000000000000800 +:10B780000000934000010004000000010000934805 +:10B7900000000000000000020000935000000000C4 +:10B7A00000000008000093540000000000000002A8 +:10B7B00000009418000000000000000800009358EA +:10B7C000000800000000000800009AB000400000DF +:10B7D00000000040000093980008000000000008EE +:10B7E000000093D80008000000000008000094202A +:10B7F00000C8000000000098000095B0009800000C +:10B8000000000028000095F00098000000000028CB +:10B810000000C480054000300000054000009D206D +:10B82000000800000000000100009D210008000049 +:10B8300000000001000020080010000000000010BF +:10B8400000002000000000000000000800009CD85C +:10B85000000800000000000200009D180000000029 +:10B8600000000001000000010000000000000000D6 +:10B8700000000009000000000000000000000002BD +:10B8800000000000000000000000CF2000000000C9 +:10B89000000000200000CF46000000000000000172 +:10B8A0000000600000200000000000200000730085 +:10B8B000000800000000000800009FA00000000039 +:10B8C0000000000100009FA800000000000000012F +:10B8D00000009F60000000000000001000009F6357 +:10B8E000000000000000000100009F610000000057 +:10B8F0000000000100009F66000000000000000141 +:10B9000000009F67000000000000000000009F682A +:10B91000000000000000000400009F6C0000000018 +:10B9200000000004000000520000000000000000C1 +:10B930000000000300000000000000000000000301 +:10B9400000000000000000000000000500000000F2 +:10B9500000000000000000020000000000000000E5 +:10B9600000060000000000000000002000009F70A2 +:10B97000000000000000000100009F900000000097 +:10B98000000000080000005300000000000000005C +:10B9900000009F98000000000000000200009F9C33 +:10B9A000000000000000000100009F9D000000005A +:10B9B000000000010000000900000000000000007D +:10B9C0000000000100000000000000000000004432 +:10B9D0000000000000000000000000010000000066 +:10B9E0000000000000000050000000000000000007 +:10B9F000000000890000000000000000000012C8E4 +:10BA00000080000000000080000000010000000035 +:10BA1000000000000000A000071000000000071058 +:10BA200000001AC800000000000000080000AEC0BE +:10BA300000080000000000080000AE400008000000 +:10BA4000000000080000AE800008000000000008B0 +:10BA5000000020080010000000000010000020007E +:10BA600000000000000000080000A01007100040C7 +:10BA70000000004000001BF800080000000000016A +:10BA800000001BF9000800000000000100001AD0AF +:10BA9000000000000000000100001AD800000000B3 +:10BAA0000000000200001ADA00000000000000029E +:10BAB0008000000000000000000000000000AF0057 +:10BAC000000000000000002000001B78002800009B +:10BAD000000000040000E000002000000000002042 +:10BAE0000000F300000800000000000800001AF049 +:10BAF000000000000000010800001B3700000000EB +:10BB00000000000100001B0F000000000000000109 +:10BB100000001B70000000000000000400001B7407 +:10BB200000000000000000040000005000000000C1 +:10BB30000000000000000003000000000000000002 +:10BB400000000005000000000000000000000006EA +:10BB500000000000000000000000000700000000DE +:10BB60000000000000001BC80000000000000001F1 +:10BB700000001BE800000000000000080000005169 +:10BB8000000000000000000000001BD000000000CA +:10BB90000000000400001BD40000000000000004AE +:10BBA00000001BD8000000000000000400001BDCA7 +:10BBB00000000000000000080000B00000180000B5 +:10BBC000000000180000C00000400000000000401D +:10BBD0000000C00000400002000000010000C001A1 +:10BBE00000400002000000000000E2000020000011 +:10BBF000000000200000E204000200080020000213 +:10BC00008000000000000000000000000000E200D2 +:10BC100000080020000000040000F40000280000DC +:10BC2000000000280000F540001000000000001097 +:10BC30000000F5C000200000000000200000F5C05A +:10BC400000020020000000020000F30000200000BD +:10BC5000000000200000200800100000000000107C +:10BC60000000200000000000000000080000110893 +:10BC70000008000000000008000011680008000033 +:10BC800000000008000011A80008000000000008E3 +:10BC900000001240000800000000000100001241F6 +:10BCA0000008000000000001000040000020000427 +:10BCB00000000010000059000030001800000010C3 +:10BCC0000000590800300018000000020000570072 +:10BCD00000080000000000010000570100080000FB +:10BCE00000000001000011E8000000000000000159 +:10BCF000000011F00000000000000001000011F839 +:10BD000000000000000000100000124400080000C5 +:10BD1000000000040000400000200000000000209F +:10BD20000000530000100000000000100000153853 +:10BD300000000000000000010000000300000000FF +:10BD400000000000000000000000000000000000F3 +:10BD500000000001000000000000000000000004DE +:10BD600000000000000000000000150800000000B6 +:10BD7000000000010000152800000000000000087D +:10BD800000000050000000000000000000008308D8 +:10BD900000800000000000800000000100000000A2 +:10BDA000000000000000200800100000000000104B +:10BDB00000002000000000000000000800008410C7 +:10BDC0000008000000000008000084700008000067 +:10BDD0000000000800060000046000280000046065 +:10BDE00000008520000800000000000100008521FF +:10BDF00000080000000000018000000000000000BA +:10BE000000000000000084080000000000000001A5 +:10BE1000000084F40008000000000002000084F626 +:10BE2000000800000000000200008504001000006F +:10BE300000000004000087600000000000000020F7 +:10BE400000006000002000000000002000007300DF +:10BE500000080000000000080000000300000000CF +:10BE600000000000000000050000000000000000CD +:10BE700000000006000000000000000000000007B5 +:10BE80000000000000000000000088080000000022 +:10BE900000000001000088280000000000000008E9 +:10BEA00000000050000000000000000000008810AA +:10BEB00000000000000000040000881400000000E2 +:10BEC00000000004000088180000000000000004CA +:10BED0000000881C00000000000000080000300086 +:10BEE0000040000000000008000030080040000092 +:10BEF000000000280000339001C00010000000087E +:10BF00000000320000200000000000200000372068 +:10BF1000000000000000000800001020062000388B +:10BF2000000000080000A000000000000000200049 +:10BF300000003EA9000000000000000100003EC813 +:10BF4000000000000000000280000000000000006F +:10BF50000000000000006000002000000000000859 +:10BF60000000400000080000000000010000400147 +:10BF7000000800000000000100004040000800042C +:10BF800000000002000040600008000400000004FF +:10BF90000000400000080000000000040000400411 +:10BFA0000008000000000004000040400000000005 +:10BFB00000000008000040480000000000000008E9 +:10BFC0000000800000000000000000100000504051 +:10BFD000000100040000000100005000000000000B +:10BFE00000000020000050080010000000000004C5 +:10BFF0000000500C0010000000000001000052C7BB +:10C000000000000000000001000052C60000000017 +:10C0100000000001000030000030001800000004A3 +:10C020000000300400300018000000040000300858 +:10C0300000300018000000020000300A0030001834 +:10C04000000000020000300C003000180000000169 +:10C050000000300D00300018000000010000300E1C +:10C0600000300018000000010000301000300018FF +:10C07000000000040000301400300018000000042C +:10C08000000050000100008000080004000050047F +:10C0900001000080000800040000000A0000000009 +:10C0A0000000000000005068010000800000000156 +:10C0B0000000506901000080000000010000506C89 +:10C0C00001000080000000020000506E01000080AE +:10C0D0000000000200005070010000800000000419 +:10C0E0000000507401000080000000040000506651 +:10C0F0000100008000000002000050640100008088 +:10C1000000000001000050600100008000000002FB +:10C11000000050620100008000000002000050504A +:10C120000100008000000004000050540100008065 +:10C1300000000004000050580100008000000004CE +:10C140000000505C01000080000000040000507CF2 +:10C1500001000080000000010000507D010000800F +:10C160000000000100004018001000000000000462 +:10C170000000409000100000000000040000409803 +:10C18000001000000000000400004110000000004A +:10C190000000000200004112000000000000000248 +:10C1A00000004114000000000000000200004116E1 +:10C1B00000000000000000020000604000080000D5 +:10C1C00000000002000060420008000000000002C1 +:10C1D00000006044000800000000000400006080CF +:10C1E0000008000000000008000060C000400008D7 +:10C1F00000000008000060000008000000000002CD +:10C20000000060020008000000000001000060045F +:10C210000008000000000002000063400008000069 +:10C220000000000800006380000800000000000417 +:10C23000000063840008000000000001000063C0EB +:10C240000008000000000002000063C400080000B5 +:10C25000000000020000640000080000000000046C +:10C2600000007000001000000000000400007004D6 +:10C270000010000000000004000070080010000022 +:10C280000000000400009000000800000000000210 +:10C29000000090020008000000000001000090046F +:10C2A00000080000000000020000904000080000AC +:10C2B000000000020000904400080000000000029E +:10C2C00000009046000800000000000200009648B0 +:10C2D0000008000000000008000090800008000036 +:10C2E000000000020000908400080000000000022E +:10C2F0000000968800080000000000080000804050 +:10C30000000800000000000100008041000800005B +:10C310000000000100008042000800000000000151 +:10C3200000008043000800000000000100008000C1 +:10C330000008000000000002000080020008000069 +:10C34000000000010000800400080000000000025E +:10C35000000080C00008000000000002000080C251 +:10C360000008000000000002000080C40008000077 +:10C3700000000002000080800008000000000001B2 +:10C3800000008081000800000000000100008082A1 +:10C390000008000000000001000080830008000089 +:10C3A000000000010000808400080000000000017F +:10C3B0000000808500080000000000010000808669 +:10C3C00000080000000000010000600000080000FC +:10C3D00000000002000060020008000000000001F0 +:10C3E000000060040008000000000002000060423D +:10C3F00000C00018000000020000604000C00018EB +:10C40000000000020000604C00C00018000000089E +:10C410000000604400C000180000000800006057E1 +:10C4200000C00018000000010000605400C00018A7 +:10C43000000000020000605600C00018000000016B +:10C440000000664000080000000000080000668050 +:10C450000008000000000008000066C0000800009E +:10C46000000000080000DA4200180000000000028E +:10C470000000DE4000000000000000000000E000BE +:10C4800000000000000000040000D0C00000000018 +:10C49000000000040000D0C4000000000000000400 +:10C4A0000000D0C800000000000000040000D0CC54 +:10C4B00000000000000000040000D0D000000000D8 +:10C4C000000000040000D0D40000000000000004C0 +:10C4D0000000D0D800000000000000040000D0C020 +:10C4E00000000000000000200000DB000000000051 +:10C4F000000000040000DB000000000000000068F5 +:10C500000000B94800000000000000000000D0005A +:10C5100000000000000000040000B0C000000000A7 +:10C52000000000040000B0C400000000000000048F +:10C530000000B0C800000000000000040000B0C00F +:10C5400000000000000000100000D6B00000000055 +:10C55000000000040000D6B4000000000000000449 +:10C560000000D6B800000000000000040000D6BCA7 +:10C5700000000000000000040000D6B00000000031 +:10C58000000000100000D348000000000000000878 +:10C590000000D358000000000000008000000010E0 +:10C5A00000000000000000000000D3580000000060 +:10C5B0000000000800000000060205000000000066 +:00000001FF -- cgit v1.2.3-59-g8ed1b From 5928c8baf67a36f553fe23a1b7820c7745e8bb2e Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:35 +0000 Subject: bnx2x: replace FW to 6.2.5 Includes FCoE releated fixes in FW flows Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 4 ++-- firmware/Makefile | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index ed90ec831fe0..6238d4f63989 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1832,8 +1832,8 @@ struct host_func_stats { #define BCM_5710_FW_MAJOR_VERSION 6 -#define BCM_5710_FW_MINOR_VERSION 0 -#define BCM_5710_FW_REVISION_VERSION 34 +#define BCM_5710_FW_MINOR_VERSION 2 +#define BCM_5710_FW_REVISION_VERSION 5 #define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 diff --git a/firmware/Makefile b/firmware/Makefile index 74d47cd0886c..69779d1637e1 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,9 +32,9 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ - bnx2x/bnx2x-e1h-6.0.34.0.fw \ - bnx2x/bnx2x-e2-6.0.34.0.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.5.0.fw \ + bnx2x/bnx2x-e1h-6.2.5.0.fw \ + bnx2x/bnx2x-e2-6.2.5.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \ bnx2/bnx2-rv2p-09-6.0.17.fw \ bnx2/bnx2-rv2p-09ax-6.0.17.fw \ -- cgit v1.2.3-59-g8ed1b From b0200e250b5eef29e5ed8aa17979499affcc11cd Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 22:34:37 +0200 Subject: bnx2x: remove old FW files Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex | 9476 ----------------- firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex | 13178 ------------------------ firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex | 15442 ---------------------------- 3 files changed, 38096 deletions(-) delete mode 100644 firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex delete mode 100644 firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex delete mode 100644 firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex diff --git a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex deleted file mode 100644 index 33b584c7c1ab..000000000000 --- a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex +++ /dev/null @@ -1,9476 +0,0 @@ -:1000000000003BB0000000680000070C00003C202E -:1000100000001AF8000043300000007C00005E3051 -:10002000000079E800005EB0000000B40000D8A035 -:100030000000800C0000D9580000008800015968B9 -:10004000000039C4000159F800000090000193C07D -:100050000000ABA80001945800000FFC000240080B -:100060000000000400025008020400480000000FD5 -:100070000204005400000045020400580000000083 -:100080000204005C0000000602040070000000048E -:1000900002040078000000000204007C1217000037 -:1000A00002040080221700000204008432170000BE -:1000B00006040088000000050204009C12150000E0 -:1000C000020400A022150000020400A43215000062 -:1000D000060400A800000004020400B8021000009A -:1000E000020400BC00100000020400C01010000058 -:1000F000020400C420100000020400C830100000F8 -:10010000060400CC00000004020400DC0010000023 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000060400EC00000004A1 -:100130000104012400000000010401280000000067 -:100140000104012C00000000010401300000000047 -:1001500002040004000000FF02040008000000FF89 -:100160000204000C000000FF02040010000000FF69 -:1001700002040014000000FF02040018000000FF49 -:100180000204001C000000FF02040020000000FF29 -:10019000020400240000003E0204002800000000C9 -:1001A0000204002C0000003F020400300000003F69 -:1001B000020400340000003F020400380000000088 -:1001C0000204003C0000003F020400400000003F29 -:1001D000020400440000003F020420080000021155 -:1001E0000204200C0000020002042010000002049F -:1001F00002042014000002190204201C0000FFFF6A -:10020000020420200000FFFF020420240000FFFF62 -:10021000020420280000FFFF0604203800000080B0 -:100220000204223807FFFFFF0204223C0000003FC7 -:100230000204224007FFFFFF020422440000000FD7 -:1002400001042248000000000104224C00000000CC -:1002500001042250000000000104225400000000AC -:1002600001042258000000000104225C000000008C -:10027000010422600000000001042264000000006C -:1002800001042268000000000104226C000000004C -:10029000010422700000000001042274000000002C -:1002A00001042278000000000104227C000000000C -:1002B000020424BC000000010C042000000003E83C -:1002C0000A042000000000010B0420000000000AC6 -:1002D0000605400000000D0002050044000000205B -:1002E00002050048000000320205009002150020BF -:1002F000020500940215002002050098000000305D -:100300000205009C08100000020500A00000003358 -:10031000020500A400000030020500A80000003122 -:10032000020500AC00000002020500B0000000055C -:10033000020500B400000006020500B8000000023B -:10034000020500BC00000002020500C00000000021 -:10035000020500C400000005020500C800000002FC -:10036000020500CC00000002020500D000000002DF -:10037000020500D400000001020501140000000184 -:100380000205011C0000000102050120000000021E -:1003900002050204000000010205020C00000040FA -:1003A00002050210000000400205021C00000020AF -:1003B00002050220000000130205022400000020B4 -:1003C000060502400000000A04050280002000002B -:1003D000020500500000000702050054000000075D -:1003E00002050058000000000205005C0000000843 -:1003F0000605006000000004020500D800000006A9 -:10040000020500E00000000D020500E40000002DE0 -:10041000020500E800000000020500EC00000020DA -:10042000020500F000000000020500F400000020BA -:10043000020500F800000000020500FC000000209A -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C0000406100002000020020600DC000000010B -:1004D000010600D80000000004060200000302200C -:1004E000020600DC0000000002060068000000B800 -:1004F0000206007800000114010600B800000000A8 -:10050000010600C8000000000206006C000000B8F0 -:100510000206007C00000114010600BC000000007F -:10052000010600CC0000000007180400007B00005A -:100530000818076000140223071C00002A1E000090 -:10054000071C800031E60A88071D00001DDD170228 -:10055000081D4470577202250118000000000000B9 -:10056000011800040000000001180008000000004D -:100570000118000C0000000001180010000000002D -:100580000118001400000000021800200000000103 -:1005900002180024000000020218002800000003D6 -:1005A0000218002C000000000218003000000004B7 -:1005B000021800340000000102180038000000009A -:1005C0000218003C00000001021800400000000476 -:1005D000021800440000000002180048000000015A -:1005E0000218004C00000003021800500000000038 -:1005F0000218005400000001021800580000000416 -:100600000218005C000000000218006000000001F9 -:1006100002180064000000030218006800000000D7 -:100620000218006C000000010218007000000004B5 -:100630000218007400000000021800780000000496 -:100640000218007C00000003061800800000000271 -:10065000021800A400003FFF021800A8000003FFDA -:1006600002180224000000000218023400000000FA -:100670000218024C00000000021802E4000000FF13 -:100680000618100000000400021B8BC000000001CF -:10069000021B800000000034021B80400000001894 -:1006A000021B80800000000C021B80C000000020A4 -:1006B0000C1B83000007A1200A1B830000000138E7 -:1006C0000B1B8300000013880A1B834000000000FE -:1006D0000C1B8340000001F40B1B8340000000054D -:1006E000021B83800007A120021B83C0000001F4CD -:1006F000061A100000000273041A19CC0001022728 -:10070000061A2008000000C8061A20000000000297 -:10071000041A499800040228061A2E280000000234 -:10072000061A2E2000000002061A0800000000022F -:10073000061A080800000004061A08180000000243 -:10074000041A08B00002022C061A2FD0000000067E -:10075000041A2FE80002022E041A2FC000040230EF -:10076000041A300000010234061A300400000003AD -:10077000041A301000010235061A3014000000037C -:10078000041A302000010236061A3024000000034B -:10079000041A303000010237061A3034000000031A -:1007A000041A304000010238061A304400000003E9 -:1007B000041A305000010239061A305400000003B8 -:1007C000041A30600001023A061A30640000000387 -:1007D000041A30700001023B061A30740000000356 -:1007E000041A30800001023C061A30840000000325 -:1007F000041A30900001023D061A309400000003F4 -:10080000041A30A00001023E061A30A400000003C2 -:10081000041A30B00001023F061A30B40000000391 -:10082000041A30C000010240061A30C40000000360 -:10083000041A30D000010241061A30D4000000032F -:10084000041A30E000010242061A30E400000003FE -:10085000041A30F000010243061A30F400000003CD -:10086000041A310000010244061A3104000000039A -:10087000041A311000010245061A31140000000369 -:10088000041A312000010246061A31240000000338 -:10089000041A313000010247061A31340000000307 -:1008A000041A314000010248061A314400000003D6 -:1008B000041A315000010249061A315400000003A5 -:1008C000041A31600001024A061A31640000000374 -:1008D000041A31700001024B061A31740000000343 -:1008E000041A31800001024C061A31840000000312 -:1008F000041A31900001024D061A319400000003E1 -:10090000041A31A00001024E061A31A400000003AF -:10091000041A31B00001024F061A31B4000000037E -:10092000041A31C000010250061A31C4000000034D -:10093000041A31D000010251061A31D4000000031C -:10094000041A31E000010252061A31E400000003EB -:10095000041A31F000010253061A31F400000003BA -:10096000041A320000010254061A32040000000387 -:10097000041A321000010255061A32140000000356 -:10098000041A322000010256061A32240000000325 -:10099000041A323000010257061A323400000003F4 -:1009A000041A324000010258061A324400000003C3 -:1009B000041A325000010259061A32540000000392 -:1009C000041A32600001025A061A32640000000361 -:1009D000041A32700001025B061A32740000000330 -:1009E000041A32800001025C061A328400000003FF -:1009F000041A32900001025D061A329400000003CE -:100A0000041A32A00001025E061A32A4000000039C -:100A1000041A32B00001025F061A32B4000000036B -:100A2000041A32C000010260061A32C4000000033A -:100A3000041A32D000010261061A32D40000000309 -:100A4000041A32E000010262061A32E400000003D8 -:100A5000041A32F000010263061A32F400000003A7 -:100A6000041A330000010264061A33040000000374 -:100A7000041A331000010265061A33140000000343 -:100A8000041A332000010266061A33240000000312 -:100A9000041A333000010267061A333400000003E1 -:100AA000041A334000010268061A334400000003B0 -:100AB000041A335000010269061A3354000000037F -:100AC000041A33600001026A061A3364000000034E -:100AD000041A33700001026B061A3374000000031D -:100AE000041A33800001026C061A338400000003EC -:100AF000041A33900001026D061A339400000003BB -:100B0000041A33A00001026E061A33A40000000389 -:100B1000041A33B00001026F061A33B40000000358 -:100B2000041A33C000010270061A33C40000000327 -:100B3000041A33D000010271061A33D400000003F6 -:100B4000041A33E000010272061A33E400000003C5 -:100B5000041A33F000010273061A33F40000000394 -:100B6000041A340000010274061A34040000000361 -:100B7000041A341000010275061A34140000000330 -:100B8000041A342000010276061A342400000003FF -:100B9000041A343000010277061A343400000003CE -:100BA000041A344000010278061A3444000000039D -:100BB000041A345000010279061A3454000000036C -:100BC000041A34600001027A061A3464000000033B -:100BD000041A34700001027B061A3474000000030A -:100BE000041A34800001027C061A348400000003D9 -:100BF000041A34900001027D061A349400000003A8 -:100C0000041A34A00001027E061A34A40000000376 -:100C1000041A34B00001027F061A34B40000000345 -:100C2000041A34C000010280061A34C40000000314 -:100C3000041A34D000010281061A34D400000003E3 -:100C4000041A34E000010282061A34E400000003B2 -:100C5000041A34F000010283061A34F40000000381 -:100C6000041A350000010284061A3504000000034E -:100C7000041A351000010285061A3514000000031D -:100C8000041A352000010286061A352400000003EC -:100C9000041A353000010287061A353400000003BB -:100CA000041A354000010288061A3544000000038A -:100CB000041A355000010289061A35540000000359 -:100CC000041A35600001028A061A35640000000328 -:100CD000041A35700001028B061A357400000003F7 -:100CE000041A35800001028C061A358400000003C6 -:100CF000041A35900001028D061A35940000000395 -:100D0000041A35A00001028E061A35A40000000363 -:100D1000041A35B00001028F061A35B40000000332 -:100D2000041A35C000010290061A35C40000000301 -:100D3000041A35D000010291061A35D400000003D0 -:100D4000041A35E000010292061A35E4000000039F -:100D5000041A35F000010293061A35F4000000036E -:100D6000041A360000010294061A3604000000033B -:100D7000041A361000010295061A3614000000030A -:100D8000041A362000010296061A362400000003D9 -:100D9000041A363000010297061A363400000003A8 -:100DA000041A364000010298061A36440000000377 -:100DB000041A365000010299061A36540000000346 -:100DC000041A36600001029A061A36640000000315 -:100DD000041A36700001029B061A367400000003E4 -:100DE000041A36800001029C061A368400000003B3 -:100DF000041A36900001029D061A36940000000382 -:100E0000041A36A00001029E061A36A40000000350 -:100E1000041A36B00001029F061A36B4000000031F -:100E2000041A36C0000102A0061A36C400000003EE -:100E3000041A36D0000102A1061A36D400000003BD -:100E4000041A36E0000102A2061A36E4000000038C -:100E5000041A36F0000102A3061A36F4000000035B -:100E6000041A3700000102A4061A37040000000328 -:100E7000041A3710000102A5061A371400000003F7 -:100E8000041A3720000102A6061A372400000003C6 -:100E9000041A3730000102A7061A37340000000395 -:100EA000041A3740000102A8061A37440000000364 -:100EB000041A3750000102A9061A37540000000333 -:100EC000041A3760000102AA061A37640000000302 -:100ED000041A3770000102AB061A377400000003D1 -:100EE000041A3780000102AC061A378400000003A0 -:100EF000041A3790000102AD061A3794000000036F -:100F0000041A37A0000102AE061A37A4000000033D -:100F1000041A37B0000102AF061A37B4000000030C -:100F2000041A37C0000102B0061A37C400000003DB -:100F3000041A37D0000102B1061A37D400000003AA -:100F4000041A37E0000102B2061A37E40000000379 -:100F5000041A37F0000102B3061A37F40000000348 -:100F6000041A3800000102B4061A38040000000315 -:100F7000041A3810000102B5061A381400000003E4 -:100F8000041A3820000102B6061A382400000003B3 -:100F9000041A3830000102B7061A38340000000382 -:100FA000041A3840000102B8061A38440000000351 -:100FB000041A3850000102B9061A38540000000320 -:100FC000041A3860000102BA061A386400000003EF -:100FD000041A3870000102BB061A387400000003BE -:100FE000041A3880000102BC061A3884000000038D -:100FF000041A3890000102BD061A3894000000035C -:10100000041A38A0000102BE061A38A4000000032A -:10101000041A38B0000102BF061A38B400000003F9 -:10102000041A38C0000102C0061A38C400000003C8 -:10103000041A38D0000102C1061A38D40000000397 -:10104000041A38E0000102C2061A38E40000000366 -:10105000041A38F0000102C3061A38F40000000335 -:10106000041A3900000102C4061A39040000000302 -:10107000041A3910000102C5061A391400000003D1 -:10108000041A3920000102C6061A392400000003A0 -:10109000041A3930000102C7061A3934000000036F -:1010A000041A3940000102C8061A3944000000033E -:1010B000041A3950000102C9061A3954000000030D -:1010C000041A3960000102CA061A396400000003DC -:1010D000041A3970000102CB061A397400000003AB -:1010E000041A3980000102CC061A3984000000037A -:1010F000041A3990000102CD061A39940000000349 -:10110000041A39A0000102CE061A39A40000000317 -:10111000041A39B0000102CF061A39B400000003E6 -:10112000041A39C0000102D0061A39C400000003B5 -:10113000041A39D0000102D1061A39D40000000384 -:10114000041A39E0000102D2061A39E40000000353 -:10115000041A39F0000102D3061A39F40000000322 -:10116000041A3A00000102D4061A3A0400000003EF -:10117000041A3A10000102D5061A3A1400000003BE -:10118000041A3A20000102D6061A3A24000000038D -:10119000041A3A30000102D7061A3A34000000035C -:1011A000041A3A40000102D8061A3A44000000032B -:1011B000041A3A50000102D9061A3A5400000003FA -:1011C000041A3A60000102DA061A3A6400000003C9 -:1011D000041A3A70000102DB061A3A740000000398 -:1011E000041A3A80000102DC061A3A840000000367 -:1011F000041A3A90000102DD061A3A940000000336 -:10120000041A3AA0000102DE061A3AA40000000304 -:10121000041A3AB0000102DF061A3AB400000003D3 -:10122000041A3AC0000102E0061A3AC400000003A2 -:10123000041A3AD0000102E1061A3AD40000000371 -:10124000041A3AE0000102E2061A3AE40000000340 -:10125000041A3AF0000102E3061A3AF4000000030F -:10126000041A3B00000102E4061A3B0400000003DC -:10127000041A3B10000102E5061A3B1400000003AB -:10128000041A3B20000102E6061A3B24000000037A -:10129000041A3B30000102E7061A3B340000000349 -:1012A000041A3B40000102E8061A3B440000000318 -:1012B000041A3B50000102E9061A3B5400000003E7 -:1012C000041A3B60000102EA061A3B6400000003B6 -:1012D000041A3B70000102EB061A3B740000000385 -:1012E000041A3B80000102EC061A3B840000000354 -:1012F000041A3B90000102ED061A3B940000000323 -:10130000041A3BA0000102EE061A3BA400000003F1 -:10131000041A3BB0000102EF061A3BB400000003C0 -:10132000041A3BC0000102F0061A3BC4000000038F -:10133000041A3BD0000102F1061A3BD4000000035E -:10134000041A3BE0000102F2061A3BE4000000032D -:10135000041A3BF0000102F3061A3BF400000003FC -:10136000041A3C00000102F4061A3C0400000003C9 -:10137000041A3C10000102F5061A3C140000000398 -:10138000041A3C20000102F6061A3C240000000367 -:10139000041A3C30000102F7061A3C340000000336 -:1013A000041A3C40000102F8061A3C440000000305 -:1013B000041A3C50000102F9061A3C5400000003D4 -:1013C000041A3C60000102FA061A3C6400000003A3 -:1013D000041A3C70000102FB061A3C740000000372 -:1013E000041A3C80000102FC061A3C840000000341 -:1013F000041A3C90000102FD061A3C940000000310 -:10140000041A3CA0000102FE061A3CA400000003DE -:10141000041A3CB0000102FF061A3CB400000003AD -:10142000041A3CC000010300061A3CC4000000037B -:10143000041A3CD000010301061A3CD4000000034A -:10144000041A3CE000010302061A3CE40000000319 -:10145000041A3CF000010303061A3CF400000003E8 -:10146000041A3D0000010304061A3D0400000003B5 -:10147000041A3D1000010305061A3D140000000384 -:10148000041A3D2000010306061A3D240000000353 -:10149000041A3D3000010307061A3D340000000322 -:1014A000041A3D4000010308061A3D4400000003F1 -:1014B000041A3D5000010309061A3D5400000003C0 -:1014C000041A3D600001030A061A3D64000000038F -:1014D000041A3D700001030B061A3D74000000035E -:1014E000041A3D800001030C061A3D84000000032D -:1014F000041A3D900001030D061A3D9400000003FC -:10150000041A3DA00001030E061A3DA400000003CA -:10151000041A3DB00001030F061A3DB40000000399 -:10152000041A3DC000010310061A3DC40000000368 -:10153000041A3DD000010311061A3DD40000000337 -:10154000041A3DE000010312061A3DE40000000306 -:10155000041A3DF000010313061A3DF400000003D5 -:10156000041A3E0000010314061A3E0400000003A2 -:10157000041A3E1000010315061A3E140000000371 -:10158000041A3E2000010316061A3E240000000340 -:10159000041A3E3000010317061A3E34000000030F -:1015A000041A3E4000010318061A3E4400000003DE -:1015B000041A3E5000010319061A3E5400000003AD -:1015C000041A3E600001031A061A3E64000000037C -:1015D000041A3E700001031B061A3E74000000034B -:1015E000041A3E800001031C061A3E84000000031A -:1015F000041A3E900001031D061A3E9400000003E9 -:10160000041A3EA00001031E061A3EA400000003B7 -:10161000041A3EB00001031F061A3EB40000000386 -:10162000041A3EC000010320061A3EC40000000355 -:10163000041A3ED000010321061A3ED40000000324 -:10164000041A3EE000010322061A3EE400000003F3 -:10165000041A3EF000010323061A3EF400000003C2 -:10166000041A3F0000010324061A3F04000000038F -:10167000041A3F1000010325061A3F14000000035E -:10168000041A3F2000010326061A3F24000000032D -:10169000041A3F3000010327061A3F3400000003FC -:1016A000041A3F4000010328061A3F4400000003CB -:1016B000041A3F5000010329061A3F54000000039A -:1016C000041A3F600001032A061A3F640000000369 -:1016D000041A3F700001032B061A3F740000000338 -:1016E000041A3F800001032C061A3F840000000307 -:1016F000041A3F900001032D061A3F9400000003D6 -:10170000041A3FA00001032E061A3FA400000003A4 -:10171000041A3FB00001032F061A3FB40000000373 -:10172000041A3FC000010330061A3FC40000000342 -:10173000041A3FD000010331061A3FD40000000311 -:10174000041A3FE000010332061A3FE400000007DC -:10175000041A4CB000080333061A400000000124AC -:10176000021A492000000000061A2500000000109F -:10177000061A258000000012061A09C00000004861 -:10178000061A080000000002061A082000000012D5 -:10179000041A2FB00002033B041A4CF00002033D70 -:1017A000061A500000000004061A449000000124AC -:1017B000021A492400000000061A2540000000100B -:1017C000061A25C800000012061A0AE000000048A8 -:1017D000061A081000000002061A0868000000122D -:1017E000041A2FB80002033F041A4CF80002034108 -:1017F000061A5010000000040200A468000AFFDC72 -:101800000200A280000000010200A294071D29111D -:101810000200A298000000000200A29C009C042488 -:101820000200A2A0000000000200A2A40000020921 -:101830000200A4FCFF000000020100B4000000014F -:10184000020100B800000001020100DC00000001FC -:10185000020101000000000102010104000000017A -:101860000201007C0030000002010084000000281A -:101870000201008C000000000201013000000004A1 -:101880000201025C000000010201032800000000C8 -:101890000201055400000030020100C400000001F4 -:1018A000020100CC00000001020100F8000000016C -:1018B000020100F000000001020100800030000081 -:1018C00002010088000000280201009000000000D2 -:1018D0000201013400000004020102DC00000001EA -:1018E0000201032C0000000002010564000000302A -:1018F000020100C800000001020100D00000000148 -:10190000020100FC00000001020100F400000001DF -:10191000020C100000000028020C200800000A1130 -:10192000020C200C00000A00020C201000000A0427 -:10193000020C201C0000FFFF020C20200000FFFF13 -:10194000020C20240000FFFF020C20280000FFFFF3 -:10195000020C203800000020020C203C0000002176 -:10196000020C204000000022020C20440000002352 -:10197000020C204800000024020C204C000000252E -:10198000020C205000000026020C2054000000270A -:10199000020C205800000028020C205C00000029E6 -:1019A000020C20600000002A020C20640000002BC2 -:1019B000020C20680000002C020C206C0000002D9E -:1019C000020C20700000002E020C20740000002F7A -:1019D000020C207800000010060C207C0000004F54 -:1019E000020C21B800000001020C21BC0000000123 -:1019F000020C21C000000001020C21C40000000103 -:101A0000020C21C800000001020C21CC00000001E2 -:101A1000020C21D000000001020C21D400000001C2 -:101A2000020C21D800000001020C21DC00000001A2 -:101A3000020C21E000000001020C21E40000000182 -:101A4000020C21E800000001020C21EC0000000162 -:101A5000020C21F000000001020C21F40000000142 -:101A6000020C21F800000001060C21FC0000000F10 -:101A7000020C223807FFFFFF020C223C0000003F4F -:101A8000020C224007FFFFFF020C22440000000F5F -:101A9000010C224800000000010C224C0000000054 -:101AA000010C225000000000010C22540000000034 -:101AB000010C225800000000010C225C0000000014 -:101AC000010C226000000000010C226400000000F4 -:101AD000010C226800000000010C226C00000000D4 -:101AE000010C227000000000010C227400000000B4 -:101AF000010C227800000000010C227C0000000094 -:101B0000020C24BC000000010C0C2000000003E8C3 -:101B10000A0C2000000000010B0C20000000000A4D -:101B2000020C400800000562020C400C0000055148 -:101B3000020C401000000555020C40140000057214 -:101B4000020C401C0000FFFF020C40200000FFFFC1 -:101B5000020C40240000FFFF020C40280000FFFFA1 -:101B6000020C403800000046020C403C0000000C13 -:101B7000060C40400000005E020C41B8000000016D -:101B8000060C41BC0000001F020C423807FFFFFF9B -:101B9000020C423C0000003F020C424007FFFFFFE6 -:101BA000020C42440000000F010C424800000000FB -:101BB000010C424C00000000010C425000000000EB -:101BC000010C425400000000010C425800000000CB -:101BD000010C425C00000000010C426000000000AB -:101BE000010C426400000000010C4268000000008B -:101BF000010C426C00000000010C4270000000006B -:101C0000010C427400000000010C4278000000004A -:101C1000010C427C00000000010C4280000000002A -:101C2000020C44C0000000010C0C4000000003E85E -:101C30000A0C4000000000010B0C40000000000AEC -:101C4000060D400000000A00020D004400000032B2 -:101C5000020D008C02150020020D009002150020DC -:101C6000020D009408100000020D009800000033DF -:101C7000020D009C00000002020D00A00000000008 -:101C8000020D00A400000005020D00A800000005E0 -:101C9000060D00AC00000002020D00B400000002BE -:101CA000020D00B800000003020D00BC000000029D -:101CB000020D00C000000001020D00C8000000027B -:101CC000020D00CC00000002020D015C00000001CA -:101CD000020D016400000001020D01680000000215 -:101CE000020D020400000001020D020C00000020A1 -:101CF000020D021000000040020D0214000000401E -:101D0000020D022000000003020D02240000001852 -:101D1000060D028000000012040D030000180343AA -:101D2000060D03600000000C020D004C00000001D5 -:101D3000020D005000000002020D005400000000DF -:101D4000020D005800000008060D005C00000004B1 -:101D5000020D00C400000004020D0114000000097F -:101D6000020D011800000029020D011C0000000AEC -:101D7000020D01200000002A020D012400000000D5 -:101D8000020D012800000020020D012C00000000BF -:101D9000020D013000000020020D0134000000009F -:101DA000020D013800000020020D013C000000007F -:101DB000020D014000000020020D0144000000005F -:101DC000020D014800000020020D00040000000187 -:101DD000020D000800000001020D000C00000001CF -:101DE000020D001000000001020D001400000001AF -:101DF000020D001800000001020D001C000000018F -:101E0000020D002000000001020D0024000000016E -:101E1000020D002800000001020D002C000000014E -:101E2000020D003000000001020D0034000000012E -:101E3000020D003800000001020D003C000000010E -:101E4000060E200000000800020E004C00000032C8 -:101E5000020E009402150020020E009802150020C8 -:101E6000020E009C00000030020E00A008100000CE -:101E7000020E00A400000033020E00A80000003093 -:101E8000020E00AC00000031020E00B000000002A3 -:101E9000020E00B400000004020E00B800000000B2 -:101EA000020E00BC00000002020E00C00000000292 -:101EB000020E00C400000000020E00C80000000274 -:101EC000020E00CC00000007020E00D0000000024D -:101ED000020E00D400000002020E00D80000000133 -:101EE000020E014400000001020E014C000000013E -:101EF000020E015000000002020E02040000000168 -:101F0000020E020C00000040020E02100000004011 -:101F1000020E021C00000004020E0220000000203D -:101F2000020E02240000000E020E02280000001B18 -:101F3000060E030000000012040E0280001B035B6B -:101F4000060E02EC00000005020E00540000000C1A -:101F5000020E00580000000C020E005C00000000A1 -:101F6000020E006000000010060E00640000000475 -:101F7000020E00DC00000003020E01100000000F42 -:101F8000020E01140000002F020E011800000000D4 -:101F9000020E011C00000020020E000400000001DF -:101FA000020E000800000001020E000C00000001FB -:101FB000020E001000000001020E001400000001DB -:101FC000020E001800000001020E001C00000001BB -:101FD000020E002000000001020E0024000000019B -:101FE000020E002800000001020E002C000000017B -:101FF000020E003000000001020E0034000000015B -:10200000020E003800000001020E003C000000013A -:10201000020E004000000001020E0044000000011A -:102020000730040000B00000083007680013037692 -:1020300007340000332700000734800032520CCAF6 -:10204000073500001A8C195F083539A058CC037881 -:10205000013000000000000001300004000000001A -:1020600001300008000000000130000C00000000FA -:1020700001300010000000000130001400000000DA -:1020800002300020000000010230002400000002A5 -:1020900002300028000000030230002C0000000085 -:1020A0000230003000000004023000340000000163 -:1020B00002300038000000000230003C0000000147 -:1020C0000230004000000004023000440000000024 -:1020D00002300048000000010230004C0000000304 -:1020E00002300050000000000230005400000001E7 -:1020F00002300058000000040230005C00000000C4 -:1021000002300060000000010230006400000003A3 -:1021100002300068000000000230006C0000000186 -:102120000230007000000004023000740000000063 -:1021300002300078000000040230007C0000000340 -:102140000630008000000002023000A400003FFFC3 -:10215000023000A8000003FF02300224000000004B -:1021600002300234000000000230024C0000000087 -:10217000023002E40000FFFF0630200000000800EB -:1021800002338BC000000001023380000000001AFF -:10219000023380400000004E0233808000000010B7 -:1021A000023380C0000000200C3383000007A12010 -:1021B0000A338300000001380B33830000001388CA -:1021C0000A338340000000000C338340000001F418 -:1021D0000B33834000000005023383800007A120F9 -:1021E000023383C0000001F406322A88000000C2D6 -:1021F00006322008000000C806322000000000025D -:10220000063223E80000004004322E580004037A0E -:10221000063250A000000004063250B80000000250 -:102220000632508000000006043250980002037EFF -:10223000063250000000002006323000000004008A -:1022400006321C0000000004043218300002038033 -:10225000063224E8000000B402322DB00000000075 -:1022600006324000000000B40632300000000020BA -:10227000063231000000002006323200000000204B -:102280000632330000000020063234000000002037 -:102290000632350000000020063236000000002023 -:1022A000063237000000002006323800000000200F -:1022B000063239000000002006323A0000000020FB -:1022C00006323B000000002006323C0000000020E7 -:1022D00006323D000000002006323E0000000020D3 -:1022E00006323F000000002006321C1000000002F1 -:1022F000063245A000000024063227B8000000B4D2 -:1023000002322DB400000000063242D0000000B4BA -:1023100006323080000000200632318000000020AC -:102320000632328000000020063233800000002098 -:102330000632348000000020063235800000002084 -:102340000632368000000020063237800000002070 -:10235000063238800000002006323980000000205C -:1023600006323A800000002006323B800000002048 -:1023700006323C800000002006323D800000002034 -:1023800006323E800000002006323F800000002020 -:1023900006321C20000000020632463000000024F5 -:1023A0000720040000870000082007800010038237 -:1023B0000724000031A500000724800008190C6ADA -:1023C00008248EB06C9003840120000000000000FF -:1023D00001200004000000000120000800000000AF -:1023E0000120000C0000000001200010000000008F -:1023F0000120001400000000022000200000000165 -:102400000220002400000002022000280000000337 -:102410000220002C00000000022000300000000418 -:1024200002200034000000010220003800000000FB -:102430000220003C000000010220004000000004D7 -:1024400002200044000000000220004800000001BB -:102450000220004C00000003022000500000000099 -:102460000220005400000001022000580000000477 -:102470000220005C0000000002200060000000015B -:102480000220006400000003022000680000000039 -:102490000220006C00000001022000700000000417 -:1024A00002200074000000000220007800000004F8 -:1024B0000220007C000000030620008000000002D3 -:1024C000022000A400003FFF022000A8000003FF3C -:1024D000022002240000000002200234000000005C -:1024E0000220024C00000000022002E40000FFFF76 -:1024F000062020000000080002238BC0000000011D -:10250000022380000000001002238040000000121F -:102510000223808000000030022380C00000000EF3 -:102520000C2383000007A1200A2383000000013848 -:102530000B238300000013880A238340000000005F -:102540000C238340000001F40B23834000000005AE -:10255000022383800007A120022383C0000001F42E -:10256000062250000000004206222008000000C899 -:10257000062220000000000206224000000000C6E3 -:1025800004224318000503860622432C0000000B9A -:10259000042243580005038B0622436C0000000B05 -:1025A0000422439800050390062243AC0000000B70 -:1025B000042243D800050395062243EC0000000BDB -:1025C000042244180005039A0622442C0000000B44 -:1025D000042244580005039F0622446C0000000BAF -:1025E00004224498000503A4062244AC0000000B1A -:1025F000042244D8000503A9062244EC0000000B85 -:1026000004224518000503AE0622452C0000000BED -:1026100004224558000503B30622456C0000000B58 -:1026200004224598000503B8062245AC0000000BC3 -:10263000042245D8000503BD062245EC0000000B2E -:1026400004224618000503C20622462C0000000B97 -:1026500004224658000503C70622466C0000000B02 -:1026600004224698000503CC062246AC0000000B6D -:10267000042246D8000503D1062246EC0000000BD8 -:1026800004224718000503D60622472C0000000B41 -:1026900004224758000503DB0622476C0000000BAC -:1026A00004224798000503E0062247AC0000000B17 -:1026B000042247D8000503E5062247EC0000000B82 -:1026C00004224818000503EA0622482C0000000BEB -:1026D00004224858000503EF0622486C0000000B56 -:1026E00004224898000503F4062248AC0000000BC1 -:1026F000042248D8000503F9062248EC0000000B2C -:1027000004224918000503FE0622492C0000000B94 -:1027100004224958000504030622496C0000000BFE -:102720000422499800050408062249AC0000000B69 -:10273000042249D80005040D062249EC0000000BD4 -:1027400004224A180005041206224A2C0000000B3D -:1027500004224A580005041706224A6C0000000BA8 -:1027600004224A980005041C06224AAC0000000B13 -:1027700004224AD80005042106224AEC0000000584 -:1027800006224B000000001704224B5C00010426C7 -:1027900006224B600000000304224B6C000104275A -:1027A000062238000000004006223000000002002F -:1027B000042251C00004042806221000000000C0BA -:1027C000062215C00000024004221EC80008042C86 -:1027D0000622390000000008022251180000000003 -:1027E000062251D00000000606221300000000025D -:1027F00006221410000000300622392000000008D4 -:102800000222511C00000000062251E800000006D0 -:102810000622130800000002062214D00000003037 -:102820000216100000000028021700080000000235 -:102830000217002C000000030217003C00000004F7 -:1028400002170044000000000217004800000002C8 -:102850000217004C0000009002170050000000908A -:102860000217005400800090021700580810000062 -:10287000021700600000008A021700640000008058 -:1028800002170068000000810217006C0000008041 -:10289000021700700000000602170078000007D041 -:1028A0000217007C0000076C02170038007C10043F -:1028B000021700040000000F06164024000000026A -:1028C000021640700000001C0216420800000001C1 -:1028D0000216421000000001021642200000000112 -:1028E00002164228000000010216423000000001DA -:1028F000021642380000000102164260000000018A -:102900000C16401C0003D0900A16401C0000009CCE -:102910000B16401C000009C40216403000000008DD -:10292000021640340000000C02164038000000106F -:102930000216404400000020021640000000000182 -:10294000021640D8000000010216400800000001F5 -:102950000216400C000000010216401000000001A9 -:10296000021642400000000002164248000000002B -:1029700006164270000000020216425000000000DD -:1029800002164258000000000616428000000002B5 -:1029900002166008000006140216600C0000060013 -:1029A00002166010000006040216601C0000FFFF03 -:1029B000021660200000FFFF021660240000FFFFE7 -:1029C000021660280000FFFF021660380000002099 -:1029D0000216603C00000020061660400000000265 -:1029E00002166048000000230216604C000000241C -:1029F00002166050000000250216605400000026F8 -:102A000002166058000000270216605C00000029D2 -:102A1000021660600000002A021660640000002BAD -:102A2000021660680000002C0216606C0000002D89 -:102A30000616607000000012021660B80000000167 -:102A4000021660BC00000001061660C00000003ED7 -:102A5000021661B800000001061661BC0000001FEC -:102A60000216623807FFFFFF0216623C0000003FBB -:102A70000216624007FFFFFF021662440000000FCB -:102A800001166248000000000116624C00000000C0 -:102A900001166250000000000116625400000000A0 -:102AA00001166258000000000116625C0000000080 -:102AB0000116626000000000011662640000000060 -:102AC00001166268000000000116626C0000000040 -:102AD0000116627000000000011662740000000020 -:102AE00001166278000000000116627C0000000000 -:102AF000021664BC000000010C166000000003E830 -:102B00000A166000000000010B1660000000000AB9 -:102B100002168040000000060216804400000005F6 -:102B2000021680480000000A0216804C00000005D2 -:102B30000216805400000002021680CC000000043F -:102B4000021680D000000004021680D400000004A9 -:102B5000021680D800000004021680DC0000000489 -:102B6000021680E000000004021680E40000000469 -:102B7000021680E800000004021688040000000429 -:102B8000021680300000007C021680340000003DF8 -:102B9000021680380000003F0216803C0000009CB6 -:102BA000021680F000000007061680F40000000501 -:102BB0000216880C010101010216810800000000C4 -:102BC0000216810C000000040216811000000004AF -:102BD0000216811400000002021688100801200469 -:102BE00002168118000000050216811C0000000575 -:102BF0000216812000000005021681240000000555 -:102C00000216882C200810010216812800000008F6 -:102C10000216812C00000006021681300000000719 -:102C200002168134000000000216883001010120E4 -:102C300006168138000000040216883401010101E3 -:102C400006168148000000040216883801010101BF -:102C500006168158000000040216883C010101019B -:102C6000061681680000000302168174000000014E -:102C7000021688400101010102168178000000015E -:102C80000216817C00000001021681800000000114 -:102C9000021681840000000102168844010101012E -:102CA00002168188000000010216818C00000004D9 -:102CB00002168190000000040216819400000002B8 -:102CC00002168848080120040216819800000005B9 -:102CD0000216819C00000005021681A0000000057C -:102CE000021681A4000000050216881420081001B5 -:102CF000021681A800000008021681AC0000000640 -:102D0000021681B000000007021681B40000000125 -:102D10000216881801010120021681B80000000186 -:102D2000021681BC00000001021681C000000001F3 -:102D3000021681C4000000010216881C0101010175 -:102D4000021681C800000001021681CC00000001BB -:102D5000021681D000000001021681D4000000019B -:102D60000216882001010101021681D8000000012D -:102D7000021681DC00000001021681E00000000163 -:102D8000021681E4000000010216882401010101FD -:102D9000021681E800000001021681EC000000012B -:102DA000021681F0000000010216882801010101CD -:102DB00002168240FFFF003F061682440000000218 -:102DC0000216824CFFFF003F0216825000000100F5 -:102DD000021682540000010006168258000000020C -:102DE00002168260000000C002168264000000C06B -:102DF0000216826800001E000216826C00001E008F -:102E0000021682700000400002168274000040002A -:102E100002168278000080000216827C000080008A -:102E2000021682800000200002168284000020002A -:102E30000616828800000007021682A40000000126 -:102E4000061682A80000000A021681F400000C0891 -:102E5000021681F800000040021681FC000001000B -:102E600002168200000000200216820400000017F3 -:102E700002168208000000800216820C0000020088 -:102E8000021682100000000002168218FFFF01FFE8 -:102E900002168214FFFF01FF0216823C000000139D -:102EA000021680900000013F021680600000014081 -:102EB00002168064000001400616806800000002CF -:102EC00002168070000000C0061680740000000723 -:102ED0000216809C00000048021680A000000048F6 -:102EE000061680A400000002021680AC0000004814 -:102EF000061680B00000000702168238000080002D -:102F000002168234000025E40216809400007FFF40 -:102F100002168220000000070216821C0000000733 -:102F2000021682280000000002168224FFFFFFFF25 -:102F300002168230000000000216822CFFFFFFFF05 -:102F4000021680EC000000FF0214000000000001E7 -:102F50000214000C000000010214004000000001F7 -:102F60000214004400007FFF0214000C0000000067 -:102F700002140000000000000214006C00000000B9 -:102F800002140004000000010214003000000001DF -:102F900002140004000000000214005C00000000A5 -:102FA00002140008000000010214003400000001B7 -:102FB000021400080000000002140060000000007D -:102FC00006028000000020000202005800000032CB -:102FD000020200A003150020020200A40315002035 -:102FE000020200A801000030020200AC081000003C -:102FF000020200B000000033020200B40000003002 -:10300000020200B800000031020200BC0000000310 -:10301000020200C000000006020200C4000000031B -:10302000020200C800000003020200CC00000002FF -:10303000020200D000000000020200D400000002E2 -:10304000020200DC00000000020200E000000006B6 -:10305000020200E400000004020200E80000000296 -:10306000020200EC00000002020200F00000000179 -:10307000020200FC00000006020201200000000025 -:103080000202013400000002020201B0000000014F -:103090000202020C00000001020202140000000102 -:1030A00002020218000000020202040400000001F3 -:1030B0000202040C00000040020204100000004064 -:1030C0000202041C00000004020204200000002090 -:1030D0000202042400000002020204280000001F73 -:1030E00006020500000000120402048000200434DF -:1030F000020200600000000F0202006400000007EE -:1031000002020068000000000202006C0000000ED5 -:103110000602007000000004020200F40000000437 -:103120000202000400000001020200080000000189 -:103130000202000C00000001020200100000000169 -:103140000202001400000001020200180000000149 -:103150000202001C00000001020200200000000129 -:103160000202002400000001020200280000000109 -:103170000202002C000000010202003000000001E9 -:1031800002020034000000010202003800000001C9 -:103190000202003C000000010202004000000001A9 -:1031A0000202004400000001020200480000000189 -:1031B0000202004C00000001020200500000000169 -:1031C00002020108000000C802020118000000020B -:1031D000020201C400000000020201CC0000000055 -:1031E000020201D400000002020201DC0000000221 -:1031F000020201E4000000FF020201EC000000FFF7 -:103200000202010C000000C80202011C00000002C2 -:10321000020201C800000000020201D0000000000C -:10322000020201D800000002020201E000000002D8 -:10323000020201E8000000FF020201F0000000FFAE -:1032400007280400008D00000828076800130454B4 -:10325000072C000033FC0000072C800038B20D0062 -:10326000072D000039171B2D072D800005D9297364 -:10327000082D8A204EBC04560128000000000000E2 -:1032800001280004000000000128000800000000E0 -:103290000128000C000000000128001000000000C0 -:1032A0000128001400000000022800200000000196 -:1032B0000228002400000002022800280000000369 -:1032C0000228002C0000000002280030000000044A -:1032D000022800340000000102280038000000002D -:1032E0000228003C00000001022800400000000409 -:1032F00002280044000000000228004800000001ED -:103300000228004C000000030228005000000000CA -:1033100002280054000000010228005800000004A8 -:103320000228005C0000000002280060000000018C -:10333000022800640000000302280068000000006A -:103340000228006C00000001022800700000000448 -:103350000228007400000000022800780000000429 -:103360000228007C00000003062800800000000204 -:10337000022800A400003FFF022800A8000003FF6D -:10338000022802240000000002280234000000008D -:103390000228024C00000000022802E40000FFFFA7 -:1033A0000628200000000800022B8BC0000000014E -:1033B000022B800000000000022B8040000000185B -:1033C000022B80800000000C022B80C000000066F1 -:1033D0000C2B83000007A1200A2B8300000001387A -:1033E0000B2B8300000013880A2B83400000000091 -:1033F0000C2B8340000001F40B2B834000000005E0 -:10340000022B83800007A120022B83C0000001F45F -:10341000062A3D4800000004042A3D5800020458D2 -:10342000062A3D6000000006062A30000000004821 -:10343000062A2008000000C8062A2000000000021A -:10344000062A31280000008E062A33680000000397 -:10345000042A33740001045A062A3A780000000254 -:10346000042A3A800002045B042A3A700002045DD8 -:10347000042A3E280002045F042A3EB000040461CE -:10348000042A250000020465062A25080000010020 -:10349000062A297000000004042A29600004046739 -:1034A000042A2F480002046B062A3378000000D853 -:1034B000022A3A3800000000062A3A88000000324A -:1034C000042A3D880010046D062A502000000002E6 -:1034D000062A503000000002062A500000000002B8 -:1034E000062A501000000002022A50B80000000115 -:1034F000062A50480000000E042A3D780002047D90 -:10350000062A3C1800000026022A50400000000055 -:10351000062A36D8000000D8022A3A3C00000000F3 -:10352000062A3B5000000032042A3DC80010047FE8 -:10353000062A502800000002062A50380000000227 -:10354000062A500800000002062A50180000000257 -:10355000022A50BC00000001062A50800000000E24 -:10356000042A3D800002048F062A3CB00000002699 -:10357000022A504400000000021010080000000160 -:103580000210101000000264021010000003D000AE -:10359000021010040000003D091018000200049100 -:1035A00009101100001006910610114000000008DB -:1035B00009101160000806A1061011800000000229 -:1035C00009101188000606A9061011A000000018B5 -:1035D000021010100000000006102400000000E09F -:1035E0000210201C0000000002102020000000013A -:1035F000021020C0000000010210200400000001A1 -:10360000021020080000000109103C00000506AF70 -:1036100009103C20000506B409103800000506B961 -:1036200002104028000000100210404400003FFF3C -:103630000210405800280000021040840084924A82 -:1036400006104C000000010002104058000000006D -:103650000610806800000004021080000000108046 -:1036600006108028000000020210803800000010C0 -:10367000021080400000FFFF021080440000FFFFA6 -:1036800002108050000000000210810000000000C5 -:10369000061081200000000202108008000002B520 -:1036A0000210801000000000061082000000004A96 -:1036B000021081080001FFFF061081400000000297 -:1036C0000210800000001A80061090000000002404 -:1036D000061091200000004A061093700000004A76 -:1036E000061095C00000004A0210800400001080FF -:1036F00006108030000000020210803C0000001024 -:10370000021080480000FFFF0210804C0000FFFF05 -:10371000021080540000000002108104000000002C -:1037200006108128000000020210800C000002B583 -:103730000210801400000000061084000000004AFF -:103740000210810C0001FFFF0610814800000002FA -:103750000210800400001A800610909000000024DF -:10376000061092480000004A061094980000004A93 -:10377000061096E80000004A0212049000E383401D -:103780000212051400003C10021205200000000285 -:1037900002120494FFFFFFFF02120498FFFFFFFFD5 -:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5 -:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95 -:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75 -:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D -:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D -:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D -:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4 -:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC -:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C -:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C -:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C -:1038500002120500FFFFFFFF02120504FFFFFFFF3A -:1038600002120508FFFFFFFF0212050CFFFFFFFF1A -:1038700002120510FFFFFFFF021204D4FFFF3330D6 -:10388000021204D8FFFF3340021204B4F0003000EB -:1038900002120390000000080212039C00000008BE -:1038A000061203A000000002021203BC0000000484 -:1038B000021203C400000004021203D00000000042 -:1038C000021203DC000000000212036C0000000181 -:1038D000021203680000003F021201BC0000004019 -:1038E000021201C000001808021201C400000803FF -:1038F000021201C800000803021201CC00000040BF -:10390000021201D000000003021201D400000803DB -:10391000021201D800000803021201DC00000803B3 -:10392000021201E000010003021201E4000008039A -:10393000021201E800000803021201EC000000037B -:10394000021201F000000003021201F40000000363 -:10395000021201F800000003021201FC0000000343 -:103960000212020000000003021202040000000321 -:1039700002120208000000030212020C0000000301 -:1039800002120210000000030212021400000003E1 -:1039900002120218000000030212021C00000003C1 -:1039A00002120220000000030212022400000003A1 -:1039B00002120228000024030212022C0000002F31 -:1039C0000212023000000009021202340000001945 -:1039D00002120238000001840212023C000001833E -:1039E0000212024000000306021202440000001905 -:1039F00002120248000000060212024C00000306F8 -:103A000002120250000003060212025400000306D4 -:103A10000212025800000C860212025C000003062B -:103A20000212026000000306021202640000000697 -:103A300002120268000000060212026C000000067A -:103A4000021202700000000602120274000000065A -:103A500002120278000000060212027C000000063A -:103A6000021202800000000602120284000000061A -:103A700002120288000000060212028C00000006FA -:103A800002120290000000060212029400000006DA -:103A900002120298000000060212029C00000006BA -:103AA000021202A000000306021202A4000000138A -:103AB000021202A800000006021202B00000100468 -:103AC000021202B400001004021203240010644029 -:103AD0000212032800106440021201B0000000012D -:103AE0000600A000000000160200A06CBF5C0000F1 -:103AF0000200A070FFF51FEF0200A0740000FFFF9E -:103B00000200A078F00003E00200A07C00000000AA -:103B10000200A0800000A0000600A08400000005B4 -:103B20000200A0980FE000000600A09C0000001416 -:103B30000200A0EC555400000200A0F05555555568 -:103B40000200A0F4000055550200A0F8F0000000AB -:103B50000200A0FC555400000200A1005555555527 -:103B60000200A104000055550200A108F000000069 -:103B70000600A22C000000040200A0600000030761 -:103B80000200A10CBF5C00000200A110FFF51FEFB6 -:103B90000200A1140000FFFF0200A118F00003E0E2 -:103BA0000200A11C000000000200A1200000A000F3 -:103BB0000600A124000000050200A1380FE000006B -:103BC0000600A13C000000140200A18C5554000026 -:103BD0000200A190555555550200A194000055557D -:103BE0000200A198F00000000200A19C55540000C2 -:103BF0000200A1A0555555550200A1A4000055553D -:103C00000200A1A8F00000000600A23C0000000491 -:103C10000200A06400000307000000000000000094 -:103C20000000002E00000000000000000000000066 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000002E004D00000000C9 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA00000000000004D008B00000000000000003C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000008B009000900094009400980000000079 -:103CE00000000000000000000000000000000000D4 -:103CF000000000000000000000000000009802DE4C -:103D000002DE02E802E802F200000000000000000B -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD000000000000000000002F202FA00000000F3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E300002FA02FF02FF030A030A03150000000052 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000031503160000000001 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB000000000000316035700000000000000008F -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE0000357037B000000000000000000000000FA -:103EF00000000000000000000000000000000000C2 -:103F0000000000000000000000000000037B03BB75 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F3000000000000000000003BB03F700000000C9 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000003F7043D043D045204520467BE -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F9000046704ED04ED04F204F204F700000000ED -:103FA0000000000000000000000000000000000011 -:103FB00000000000000000000000000004F704F80A -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE000000000000000000004F8050A00000000C6 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000050A051F051F052205220525D1 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:1040400005250555000000000000000000000000EC -:104050000000000000000000000000000000000060 -:10406000000000000000000000000000055505DC15 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:10409000000000000000000005DC05E305E305E783 -:1040A00005E705EB00000000000000000000000034 -:1040B0000000000000000000000000000000000000 -:1040C0000000000005EB062B062B06330633063BEB -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F000063B068806880695069506A20000000085 -:1041000000000000000000000000000000000000AF -:1041100000000000000000000000000006A206AE43 -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000006AE06B40000000001 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:104170000000000006B406B70000000000000000C8 -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A00006B706BD0000000000000000000000008F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000006BD06BE68 -:1041D00006BE06D006D006E2000000000000000087 -:1041E00000000000000000000000000000000000CF -:1041F000000000000000000006E2074F0000000081 -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:1042200000000000074F0750075007630763077639 -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:1043300000010000000204C00003098000040E40D8 -:1043400000051300000617C000071C80000821406C -:1043500000092600000A2AC0000B2F80000C344000 -:10436000000D3900000E3DC0000F42800010474094 -:1043700000114C00001250C00013558000145A4028 -:1043800000155F00001663C00017688000186D40BC -:1043900000197200001A76C0001B7B80001C804050 -:1043A000001D8500001E89C0001F8E800000934004 -:1043B00000002000000040000000600000008000BD -:1043C0000000A0000000C0000000E00000010000AC -:1043D0000001200000014000000160000001800099 -:1043E0000001A0000001C0000001E0000002000088 -:1043F0000002200000024000000260000002800075 -:104400000002A0000002C0000002E0000003000063 -:104410000003200000034000000360000003800050 -:104420000003A0000003C0000003E000000400003F -:10443000000420000004400000046000000480002C -:104440000004A0000004C0000004E000000500001B -:104450000005200000054000000560000005800008 -:104460000005A0000005C0000005E00000060000F7 -:1044700000062000000640000006600000068000E4 -:104480000006A0000006C0000006E00000070000D3 -:1044900000072000000740000007600000078000C0 -:1044A0000007A0000007C0000007E00000080000AF -:1044B000000820000008400000086000000880009C -:1044C0000008A0000008C0000008E000000900008B -:1044D0000009200000094000000960000009800078 -:1044E0000009A0000009C0000009E000000A000067 -:1044F000000A2000000A4000000A6000000A800054 -:10450000000AA000000AC000000AE000000B000042 -:10451000000B2000000B4000000B6000000B80002F -:10452000000BA000000BC000000BE000000C00001E -:10453000000C2000000C4000000C6000000C80000B -:10454000000CA000000CC000000CE000000D0000FA -:10455000000D2000000D4000000D6000000D8000E7 -:10456000000DA000000DC000000DE000000E0000D6 -:10457000000E2000000E4000000E6000000E8000C3 -:10458000000EA000000EC000000EE000000F0000B2 -:10459000000F2000000F4000000F6000000F80009F -:1045A000000FA000000FC000000FE000001000008E -:1045B000001020000010400000106000001080007B -:1045C0000010A0000010C0000010E000001100006A -:1045D0000011200000114000001160000011800057 -:1045E0000011A0000011C0000011E0000012000046 -:1045F0000012200000124000001260000012800033 -:104600000012A0000012C0000012E0000013000021 -:10461000001320000013400000136000001380000E -:104620000013A0000013C0000013E00000140000FD -:1046300000142000001440000014600000148000EA -:104640000014A0000014C0000014E00000150000D9 -:1046500000152000001540000015600000158000C6 -:104660000015A0000015C0000015E00000160000B5 -:1046700000162000001640000016600000168000A2 -:104680000016A0000016C0000016E0000017000091 -:10469000001720000017400000176000001780007E -:1046A0000017A0000017C0000017E000001800006D -:1046B000001820000018400000186000001880005A -:1046C0000018A0000018C0000018E0000019000049 -:1046D0000019200000194000001960000019800036 -:1046E0000019A0000019C0000019E000001A000025 -:1046F000001A2000001A4000001A6000001A800012 -:10470000001AA000001AC000001AE000001B000000 -:10471000001B2000001B4000001B6000001B8000ED -:10472000001BA000001BC000001BE000001C0000DC -:10473000001C2000001C4000001C6000001C8000C9 -:10474000001CA000001CC000001CE000001D0000B8 -:10475000001D2000001D4000001D6000001D8000A5 -:10476000001DA000001DC000001DE000001E000094 -:10477000001E2000001E4000001E6000001E800081 -:10478000001EA000001EC000001EE000001F000070 -:10479000001F2000001F4000001F6000001F80005D -:1047A000001FA000001FC000001FE000002000004C -:1047B0000020200000204000002060000020800039 -:1047C0000020A0000020C0000020E0000021000028 -:1047D0000021200000214000002160000021800015 -:1047E0000021A0000021C0000021E0000022000004 -:1047F00000222000002240000022600000228000F1 -:104800000022A0000022C0000022E00000230000DF -:1048100000232000002340000023600000238000CC -:104820000023A0000023C0000023E00000240000BB -:1048300000242000002440000024600000248000A8 -:104840000024A0000024C0000024E0000025000097 -:104850000025200000254000002560000025800084 -:104860000025A0000025C0000025E0000026000073 -:104870000026200000264000002660000026800060 -:104880000026A0000026C0000026E000002700004F -:10489000002720000027400000276000002780003C -:1048A0000027A0000027C0000027E000002800002B -:1048B0000028200000284000002860000028800018 -:1048C0000028A0000028C0000028E0000029000007 -:1048D00000292000002940000029600000298000F4 -:1048E0000029A0000029C0000029E000002A0000E3 -:1048F000002A2000002A4000002A6000002A8000D0 -:10490000002AA000002AC000002AE000002B0000BE -:10491000002B2000002B4000002B6000002B8000AB -:10492000002BA000002BC000002BE000002C00009A -:10493000002C2000002C4000002C6000002C800087 -:10494000002CA000002CC000002CE000002D000076 -:10495000002D2000002D4000002D6000002D800063 -:10496000002DA000002DC000002DE000002E000052 -:10497000002E2000002E4000002E6000002E80003F -:10498000002EA000002EC000002EE000002F00002E -:10499000002F2000002F4000002F6000002F80001B -:1049A000002FA000002FC000002FE000003000000A -:1049B00000302000003040000030600000308000F7 -:1049C0000030A0000030C0000030E00000310000E6 -:1049D00000312000003140000031600000318000D3 -:1049E0000031A0000031C0000031E00000320000C2 -:1049F00000322000003240000032600000328000AF -:104A00000032A0000032C0000032E000003300009D -:104A1000003320000033400000336000003380008A -:104A20000033A0000033C0000033E0000034000079 -:104A30000034200000344000003460000034800066 -:104A40000034A0000034C0000034E0000035000055 -:104A50000035200000354000003560000035800042 -:104A60000035A0000035C0000035E0000036000031 -:104A7000003620000036400000366000003680001E -:104A80000036A0000036C0000036E000003700000D -:104A900000372000003740000037600000378000FA -:104AA0000037A0000037C0000037E00000380000E9 -:104AB00000382000003840000038600000388000D6 -:104AC0000038A0000038C0000038E00000390000C5 -:104AD00000392000003940000039600000398000B2 -:104AE0000039A0000039C0000039E000003A0000A1 -:104AF000003A2000003A4000003A6000003A80008E -:104B0000003AA000003AC000003AE000003B00007C -:104B1000003B2000003B4000003B6000003B800069 -:104B2000003BA000003BC000003BE000003C000058 -:104B3000003C2000003C4000003C6000003C800045 -:104B4000003CA000003CC000003CE000003D000034 -:104B5000003D2000003D4000003D6000003D800021 -:104B6000003DA000003DC000003DE000003E000010 -:104B7000003E2000003E4000003E6000003E8000FD -:104B8000003EA000003EC000003EE000003F0000EC -:104B9000003F2000003F4000003F6000003F8000D9 -:104BA000003FA000003FC000003FE000003FE001E8 -:104BB00000000000000001FF0000020000007FF87C -:104BC00000007FF80000016A0000150000000001ED -:104BD0000000FF00000000000000FF0000000000D7 -:104BE00000000000140AFF000000000100000000A7 -:104BF00000201001000000000100860000000100FC -:104C00000000860200008604000086060000860878 -:104C10000000860A0000860C0000860E0000861048 -:104C20000000861200008614000086160000861818 -:104C30000000861A0000861C0000861E00008620E8 -:104C400000008622000086240000862600008628B8 -:104C50000000862A0000862C0000862E0000863088 -:104C60000000863200008634000086360000863858 -:104C70000000863A0000863C0000863E0000864028 -:104C800000008642000086440000864600008648F8 -:104C90000000864A0000864C0000864E00008650C8 -:104CA0000000865200008654000086560000865898 -:104CB0000000865A0000865C0000865E0000866068 -:104CC0000000866200008664000086660000866838 -:104CD0000000866A0000866C0000866E0000867008 -:104CE00000008672000086740000867600008678D8 -:104CF0000000867A0000867C0000867E00008680A8 -:104D00000000868200008684000086860000868877 -:104D10000000868A0000868C0000868E0000869047 -:104D20000000869200008694000086960000869817 -:104D30000000869A0000869C0000869E000086A0E7 -:104D4000000086A2000086A4000086A6000086A8B7 -:104D5000000086AA000086AC000086AE000086B087 -:104D6000000086B2000086B4000086B6000086B857 -:104D7000000086BA000086BC000086BE000086C027 -:104D8000000086C2000086C4000086C6000086C8F7 -:104D9000000086CA000086CC000086CE000086D0C7 -:104DA000000086D2000086D4000086D6000086D897 -:104DB000000086DA000086DC000086DE000086E067 -:104DC000000086E2000086E4000086E6000086E837 -:104DD000000086EA000086EC000086EE000086F007 -:104DE000000086F2000086F4000086F6000086F8D7 -:104DF000000086FA000086FC000086FE00008700A6 -:104E00000000870200008704000087060000870872 -:104E10000000870A0000870C0000870E0000871042 -:104E20000000871200008714000087160000871812 -:104E30000000871A0000871C0000871E00008720E2 -:104E400000008722000087240000872600008728B2 -:104E50000000872A0000872C0000872E0000873082 -:104E60000000873200008734000087360000873852 -:104E70000000873A0000873C0000873E0000874022 -:104E800000008742000087440000874600008748F2 -:104E90000000874A0000874C0000874E00008750C2 -:104EA0000000875200008754000087560000875892 -:104EB0000000875A0000875C0000875E0000876062 -:104EC0000000876200008764000087660000876832 -:104ED0000000876A0000876C0000876E0000877002 -:104EE00000008772000087740000877600008778D2 -:104EF0000000877A0000877C0000877E00008780A2 -:104F00000000878200008784000087860000878871 -:104F10000000878A0000878C0000878E0000879041 -:104F20000000879200008794000087960000879811 -:104F30000000879A0000879C0000879E000087A0E1 -:104F4000000087A2000087A4000087A6000087A8B1 -:104F5000000087AA000087AC000087AE000087B081 -:104F6000000087B2000087B4000087B6000087B851 -:104F7000000087BA000087BC000087BE000087C021 -:104F8000000087C2000087C4000087C6000087C8F1 -:104F9000000087CA000087CC000087CE000087D0C1 -:104FA000000087D2000087D4000087D6000087D891 -:104FB000000087DA000087DC000087DE000087E061 -:104FC000000087E2000087E4000087E6000087E831 -:104FD000000087EA000087EC000087EE000087F001 -:104FE000000087F2000087F4000087F6000087F8D1 -:104FF000000087FA000087FC000087FEFFFFFFFF2C -:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 -:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399 -:1050200000BEBC20000000000000000500000003DE -:1050300000BEBC20000000000000000500002000B1 -:10504000000040C000006180000082400000A3001A -:105050000000C3C00000E4800001054000012600FC -:10506000000146C000016780000188400001A900DE -:105070000001C9C00001EA8000020B4000022C00C0 -:1050800000024CC000026D8000028E400002AF00A2 -:105090000002CFC00002F08000001140000080003C -:1050A000000103800001870000020A8000028E00D8 -:1050B00000031180000395000004188000049C0088 -:1050C00000051F800005A300000626800006AA0038 -:1050D00000072D800007B100000834800008B800E8 -:1050E00000093B800009BF00000A4280000AC60098 -:1050F000000B4980000BCD00000C5080000CD40048 -:10510000000D578000005B0000007FF800007FF872 -:1051100000000166000015000000FF000000000014 -:105120000000FF0000000000000019000000000067 -:1051300000000000FFFFFFFF00007FF800007FF885 -:105140000000035F000035000000FF000FFFFFFFBD -:105150000000FF000FFFFFFF000000FF0000FF0046 -:105160000FFFFFFF0000FF000FFFFFFF000000FF29 -:105170000000FF000FFFFFFF0000FF000FFFFFFF19 -:10518000000000FF0000FF000FFFFFFF0000FF0016 -:105190000FFFFFFF000000FF0000FF000FFFFFFFF9 -:1051A0000000FF000FFFFFFF000000FF0000FF00F6 -:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9 -:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9 -:1051D000000000FF0000FF000FFFFFFF0000FF00C6 -:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9 -:1051F0000000FF000FFFFFFF000000FF0000FF00A6 -:105200000FFFFFFF0000FF000FFFFFFF000000FF88 -:105210000000FF000FFFFFFF0000FF000FFFFFFF78 -:10522000000000FF0000FF000FFFFFFF0000FF0075 -:105230000FFFFFFF000000FF0000FF000FFFFFFF58 -:105240000000FF000FFFFFFF000000FF0000FF0055 -:105250000FFFFFFF0000FF000FFFFFFF000000FF38 -:105260000000FF000FFFFFFF0000FF000FFFFFFF28 -:10527000000000FF0000FF000FFFFFFF0000FF0025 -:105280000FFFFFFF000000FF0000FF000FFFFFFF08 -:105290000000FF000FFFFFFF000000FF0000FF0005 -:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8 -:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8 -:1052C000000000FF0000FF000FFFFFFF0000FF00D5 -:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8 -:1052E0000000FF000FFFFFFF000000FF0000FF00B5 -:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98 -:105300000000FF000FFFFFFF0000FF000FFFFFFF87 -:10531000000000FF0000FF000FFFFFFF0000FF0084 -:105320000FFFFFFF000000FF0000FF000FFFFFFF67 -:105330000000FF000FFFFFFF000000FF0000FF0064 -:105340000FFFFFFF0000FF000FFFFFFF000000FF47 -:105350000000FF000FFFFFFF0000FF000FFFFFFF37 -:10536000000000FF0000FF000FFFFFFF0000FF0034 -:105370000FFFFFFF000000FF0000FF000FFFFFFF17 -:105380000000FF000FFFFFFF000000FF0000FF0014 -:105390000FFFFFFF0000FF000FFFFFFF000000FFF7 -:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7 -:1053B000000000FF0000FF000FFFFFFF0000FF00E4 -:1053C0000FFFFFFF000000FF000000FF000000FFD4 -:1053D0000000FF00000000000000FF0000000000CF -:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:1054000000001000000020800000310000004180FA -:1054100000005200000062800000730000008380E2 -:10542000000094000000A4800000B5000000C580CA -:105430000000D6000000E6800000F70000010780B1 -:105440000001180000012880000139000001498096 -:1054500000015A0000016A8000017B0000018B807E -:1054600000019C000001AC800001BD000001CD8066 -:105470000001DE000001EE8000000F0000000000CF -:1054800000007FF800007FF80000021A00003500DD -:1054900010000000000028AD00010001FFFFFFFF29 -:1054A000FFFFFFFF00220006CCCCCCC17058103C9F -:1054B000000000000000FF00000000000000FF00EE -:1054C000000000000000000000000001CCCC020140 -:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1 -:1054E000FFFFFFFF0000FFFF000000000000FFFFC4 -:1054F000000000000000FFFF000000000000FFFFB0 -:10550000000000000000FFFF000000000000FFFF9F -:10551000000000000000FFFF000000000000FFFF8F -:1055200000000000000E0000011600D60000FFFF82 -:10553000000000000000FFFF000000000000FFFF6F -:10554000000000000000FFFF000000000000FFFF5F -:10555000000000000000FFFF000000000000FFFF4F -:10556000000000000000FFFF0000000000720000CB -:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B -:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F -:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1 -:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E -:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C -:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D -:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2 -:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6 -:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00 -:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6 -:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7 -:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE -:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19 -:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E -:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC -:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E -:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D -:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E -:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F -:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D -:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B -:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C -:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1 -:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5 -:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF -:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5 -:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6 -:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD -:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19 -:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D -:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B -:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D -:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1 -:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91 -:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1 -:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70 -:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1 -:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F -:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91 -:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D -:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71 -:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08 -:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50 -:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0 -:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30 -:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0 -:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10 -:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70 -:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA -:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C -:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D -:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B -:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29 -:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A -:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF -:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3 -:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD -:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3 -:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90 -:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE -:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2 -:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE -:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8 -:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B -:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB -:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B -:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D -:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A -:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28 -:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19 -:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE -:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2 -:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC -:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2 -:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3 -:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA -:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82 -:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD -:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8 -:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A -:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE -:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E -:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE -:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D -:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE -:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C -:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E -:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A -:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E -:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05 -:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D -:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD -:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D -:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD -:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D -:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D -:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED -:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D -:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD -:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C -:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD -:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B -:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D -:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29 -:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D -:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04 -:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C -:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC -:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C -:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC -:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C -:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C -:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC -:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C -:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC -:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B -:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC -:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A -:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C -:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28 -:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C -:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03 -:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B -:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB -:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B -:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB -:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B -:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B -:105D7000CDCDCDCD000C0000000700C00002813069 -:105D8000000B81580002021000010230000F024097 -:105D900000010330000C0000000800C00002814038 -:105DA000000B81680002022000010240000702503F -:105DB000000202C000100000000801000002818003 -:105DC000000B81A80002026000018280000E829810 -:105DD0000008038000028000000B8028000200E021 -:105DE000000101000000811000000118CCCCCCCCD7 -:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3 -:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2 -:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2 -:105E2000CCCCCCCC00002000000000000000000022 -:105E30001F8B080000000000000BFB51CFC0F003D7 -:105E40008A5B591918EC39107C7AE0A58C94E95FCB -:105E5000C3CCC0B019882F00F12E66D2F57F9642D0 -:105E6000B0CF483030BC03E29D620C0C2B2411E211 -:105E7000D1D20C0CFF81FCD350313BA09EDD52945B -:105E8000B97B140F0E7C471D957F5C15428740C57A -:105E9000EFA2C99F80CACF5780D0F7D4B19BBB0077 -:105EA0002A0F0001FE3753600300000000000000CD -:105EB0001F8B080000000000000BED7D0B7454D513 -:105EC000B9F037E735672633939390C704123C83C4 -:105ED00001820618303C54AA93F068E8A53A3C04C5 -:105EE000E447195034822411D39AB6FC7F4EC8E49B -:105EF0000102C617A52DDA81E2BDD185BDD1466B61 -:105F0000FB6B5710A5B9B5772DA4A8B4451BD06B72 -:105F1000C10237DA72A1FFB2977F7F7BEF939C7348 -:105F20003293876257EF6AC3D2937DCE7E7CFB7B30 -:105F3000EDEF754E141803CA8D0097F0875CD7B942 -:105F40000020BBEF6ADE073556095900154145DFD1 -:105F50004A9EAD17237A7D09B97F85107E0AF0FE2F -:105F6000B839300940C671790053F17FD300A4CC11 -:105F7000969C988FDC1357A6E3D59CCFBC5648005F -:105F8000DA547CBE6D5CB2E7BDEB27E49E6E15E88B -:105F9000CFA53100B5C76F9DFF9AD926FF8D027F2F -:105FA000D68757935F66C08C4B22C027F98BD23BB4 -:105FB000F5D4F37D54D7A54963012ED42D9FFFDA84 -:105FC000D8FECFD78B50DD5EDCFFFE75A052BC80C3 -:105FD0006A28D1897DFB5E0FD0E9CE0468CEDFCC84 -:105FE000F69B4590752DB9DFF66F9A54D407E77A82 -:105FF00089F49BDA7F3F00069DD79CA7777CA2CBD4 -:1060000036DE39AE773E3E1E24F26F3A00ED42F6A0 -:106010003FCD15BB11EFBBF3171923497BFDFE5292 -:106020008815A786BF975E9F117E735C4A3AF27E01 -:106030009FEC6B6822AC071F2AAD375D47F8E8F785 -:10604000CF89E1CDC847BBC7CF8100B90F8C8F4C3A -:106050003A9DDED790938C3F52D1E97F8387F29FA0 -:10606000C95F15C2CAF44EF8ECFC7537F2579A8531 -:10607000BFDA170F38DF67E5AFB893BF383ECEB44D -:10608000B3FDC3AE118C2E9C5E4EFAA4A4CB671D4B -:10609000D79F9FB6205EDDED8B8D9190849F38BC9D -:1060A00026BD3E2FBC83F111402BA5334054C4F5CF -:1060B000FBEEB3ABB7447381409B87711F23F83E5F -:1060C00046C49AEE13089C7E682D1F1722EDEED56C -:1060D0000B500EFCC7E79FC66B6371595719E997C0 -:1060E0001ED616CE23576F11B8709F5B70B2EB703F -:1060F000BE4AA3B418E905B4FD8C7147C4403C40C6 -:10610000042007E06B7C4F00822E91B682BF8E493F -:10611000B60F053A193E5C97DCFDC7A7DABFD23748 -:106120000E2E85F0FF1B01F737D8385840C6A988D6 -:106130000E83E23BC3314F7A843D37E9E3074B9B43 -:106140003C3F8ABF507CDFF757594F8347549DA887 -:1061500014A550D012D81FB40C89B4BD7388222264 -:10616000678D16EC31047D70BA340294B7FB28C3F6 -:10617000C1427F1F7CA7C145F7135C130F3591798E -:10618000CF97F8C2943F34F2DFD4FEFB79B00E19FA -:10619000D9D22EDE0BC8E771C24763C878A3989C9A -:1061A00087084FE1F39A555FA5B95C9C2F9DFC01D0 -:1061B000BA341DC50C59855C0B858827F0F9F94365 -:1061C00072E071A8FC91B6C0421F183EBD82DC6E21 -:1061D000182A7F7CDEF54CBAF697AB7A4ED71A15A3 -:1061E0007C782E2F4A6A7FA4A6EB2394AEDE4288E9 -:1061F0002492E8E902978BCB8161D337F44AE823F4 -:10620000F692F77E1BBDC4DCE9CBF70C800F31CBD7 -:106210008E0F735E4FADA87F80CA4BD2049C4FC1D6 -:10622000F990CF828F1840CECFF3C8DB041F62EB0A -:10623000944E6C432150BB8CFC74BA48DB138C2405 -:10624000B68618FF235D4CF8DCBA60C3AF94E5B5A1 -:10625000B561B9E1B2C2EFA955281C0AB511C83C15 -:106260001A9990A042F24127F2ADC9AFC80697AE85 -:10627000C4F6B76C7CD0A24F85647430F915D1CACE -:10628000F8F55B43D32FCEF596D8E11DF2389FA4E5 -:106290007F683987528F93E043933E048915388194 -:1062A000850F9A6578C93519A0217F29C4C8DD6694 -:1062B0007C44CEB126BCE6211F4ED5E879D9E692C2 -:1062C000104EF35C856026ED37CDA5D3F904B59A61 -:1062D0009EABA22FC2CE57FE3C355C6CFD1CBD357B -:1062E000A211FCE6426B4420F4914A20DC09A84745 -:1062F00023807C0061C61722B7D3CDF171CECF1EAB -:10630000384AC713ED6A68F43CB3CBF15C913C2486 -:10631000F36C2982849BD2A955C5B6542401FA0591 -:10632000443FF9F2A6A39EE63FE28230C29F8EE789 -:106330002BF2C72CCEDF2EA2CF089E7D2576F9F654 -:106340003AE45FE2E7713F7D96C29F30AF4EFBEDCE -:10635000FB2E6EBFA5818FD29B8F075F727BD5B45A -:10636000DB4CBC660B40F109BF90134F85F8DE484B -:106370007BE3BB1909DCB751165DDD48F0609C7406 -:10638000851B909E52A4279D3CFFF09F45EA2F65F8 -:106390002FADBD02D7DB5E678C2DB4D883DB25CD56 -:1063A0008B78DE139FAAC62C7AE66688BDE8B2F821 -:1063B0005FA160D3D8C26B28FF9DEC2EC2A3C2455B -:1063C000F9CFE38B075F47B9E4F77BF1636D8BFD92 -:1063D000DB59B9C0CE4BB8A93442D66D41DD3592F8 -:1063E0003E365C04CE963CD6FE797D4E299E9F2D8E -:1063F0007ED6FEA4FEFD483DE58B981A25F76A81FE -:10640000E3A58BE085D25FCF5D3831355D9CFBDF46 -:10641000211DF6E0FE9FF01D993F1ECFCF99421837 -:10642000D1FE44CD116DB5051F2DEEB2B7111FA3DE -:1064300020E102A45F3C8BCA4F107A7F22D8CEE3C2 -:10644000F2940F8769BFD1D19E52196F2DD75EC5C7 -:106450006B53F0F90C2A4F3047FB90CABFE8BA746F -:10646000F5D0E53DD57E032E8826B3E7378A9954CB -:10647000AE022564DF36BD9EAF517EE4F37E0D692A -:1064800044F6B72783C04484678FDCBA3C9A84BF44 -:106490007FEE1268BF787C5E742DE533761E8CE645 -:1064A000E741E3E2DBC3C80F50A8E7227D242D4675 -:1064B000F5AD84E707E11F398BE915498DB48C27C9 -:1064C000FC1A3A2A8241C6855A33CA54D40F1A504C -:1064D000FB05D1B96422DB2F9EAF6EC2712897995C -:1064E000E47AC9B26F087AFBE4750CAEA3D0752EBE -:1064F00003BDB3846983D37924B497E261968ADEBD -:10650000979BCEA9C63BE91B7031F9DAD87021629E -:1065100010FC351D7709222AC5D6424A2F95EBA6D5 -:106520000B724C45BB71CBD704D84BF130B09D12E8 -:1065300077D82992168DB8C8F89115DA5464A15409 -:10654000E3765608E58924F3960B4CEF6FA978A4FF -:1065500095AABBD7ECFE9EBC3242ED52E2F79523E2 -:106560003DCC719E42C647B08FEC87F49739FF5DF2 -:10657000C85E940E49E4C0BC7E0FE11FDFD71EC584 -:10658000F9CBD9AF5AE4F6D5636C7ED3DEB9903738 -:10659000F0FC267E2E960B7018E1937A3C40E53D88 -:1065A0009BDA61A3391349B5846FC8BA3274D7E353 -:1065B00079B753808AF662BE69D2CFCDE9F3FDFC8C -:1065C0004F3CD8EF3651A0F08C8AF46C41BD3F6A45 -:1065D0009300E88F548A3ABD9FBBB2FA804CEEB765 -:1065E0003442D8A7E33A6CDE96031E7A5E2A5990AD -:1065F000F090FE8742399B915EEE3844DCA49FFB0D -:106600005E2272D82E84844E9ECBB53103E19582F2 -:1066100051746FE060E82EB59BFA2D60E39BA64DA8 -:106620001B55ECD7AC6FEC0AA1DF522851BF45D106 -:10663000AA23945D3F25F830FD0A2217A138740A79 -:106640002554CF277CB483CAE8A67139DA350B3AD2 -:1066500089DCB6647CBD13E133A601954BB403D04D -:10666000340089D813647CFC4E2DBC15F922CB7004 -:1066700059F97437C4B659F943D2DA297FB4FC45C5 -:106680005C9E4C2FDE2B307C5673BD77414ECC4741 -:10669000BC6EA92772E0EADFFF7A8EFFEF1A8B6EDD -:1066A0001E4FF5133B7FCCE75D2EDD16AF1C7951F5 -:1066B000A1FB71DA2FF3B8FDD2944FEC178A07587B -:1066C00080F64A1A277D5318E8737706240C428F08 -:1066D000341E178062667FA8E41FEAB9DCE576BB4A -:1066E000C5EDB04F52D92DDF7445DBA95E232A09D1 -:1066F000E1DFE56A9D3F0EF19DC7FC46E7BEBBB8F2 -:10670000DF3857DC166A22703D992584DD7A1F3FF9 -:106710001470B978128C1397C83C7BF2059D58C051 -:10672000B0A746A0F6C9799DD9E7F08187F6BF8268 -:10673000C3D2B86911F58B7AF532979B6D75AA4D66 -:10674000BF38AF3EA53596EC5CF273FAA4CD8AD083 -:1067500038872F9CA0E70EEE33993DFE6071993A81 -:10676000909E938A94D5147FF965A725BCCE74FAC0 -:1067700045C9E7755EC16A4F8AA9FB0DF5BA85E088 -:10678000E9A46C9D3FAAE239E121E728CA85274C9C -:106790008EA4005EB51C84DF130EFBE8B5BBB49C71 -:1067A000DD8F6EC5AB3AABE7F06CEAA74994EE7BA0 -:1067B0005462075AF031490C517CF6E2B750B0ED03 -:1067C0005F95AACB914FD57C01904FD5D8D7BB2EE2 -:1067D000E17C84FE6343C9F848E2FEA99D6FF69010 -:1067E000F30606A0C3E7E58B5F08A69F6CA717FD1D -:1067F000B1C63D389D7BE9DF2F7EF1B7416F75163D -:10680000A137E299D09BF9D7DA569433292E50FF5D -:10681000C7EC77411863A39F74916852E237EF2A5F -:1068200085A4FAF082A0D0FE443F94882CEEEAC200 -:1068300078E65C71533930B906F4B754E22F50BA98 -:1068400093F550CE9B3FAD5311EF6A4CA1F679976B -:10685000ABAEB45E1A8E9E6470C16E66978C32CFFA -:10686000D90D433B672F9043829DB3D5F43C92BA38 -:10687000ABD55202EF15F7B2F3116DB04CD21E4DED -:10688000CEB7CE501FFF85F83A7271EBE17149CE59 -:10689000A3EFC53F39E046FD950FEC5CAB6D8FA0D3 -:1068A0005EF1E777E2B6F1BC5921127CE5151AA535 -:1068B000B8A591BBE6D17D7C57022A47177061824B -:1068C0008F9D9B9FA8376611B98B443B0511FD62D4 -:1068D000A07A91D8B9DCAEB3AFFBFD4D4204F1EB29 -:1068E000C910F6A008FAEFED34DC16BD4CD6BD0792 -:1068F000D735CFBFBCC276C0F59D76414A7BE02F2D -:1069000022F7B3A6D7A3DF950F0CCE873727EAD19E -:106910004E2C7547EEA7F477F807BDF1251EC75E2C -:1069200033D314227DD96FC93AF774C9B0159B9F30 -:1069300092DE96F8CE3D780E117DB3869F63774246 -:1069400034800FCF8240E36667E148E01A0B9D1F59 -:106950001215B64E8B7CB2DB12B75DDBCADAA6FE2F -:10696000B97B97BD7D172CCA9108DEEE7A4C460F95 -:106970000DEE71F8A375A246F9FB6EA86E423C3489 -:10698000CA4C0ED668208D202ED2861F3F311DEDB9 -:10699000FF9D22F36F3E22FCA55BF4CD3A5F42419E -:1069A0007CBDDF71CDD2EB01C7279A46A2BF9D0106 -:1069B00049CFCD3B5AECF00D06BF135E80CD14DEFF -:1069C0005470486DAE48327B7A9F69B7727AD5AA07 -:1069D0008149180CB9E06157A30CA87D61BCE74957 -:1069E0003490750E70FB9158429359FEA27A065E60 -:1069F000071B7748D4B93E1FDEB83752ACB741ED1C -:106A00005690FFAB24A3DC25F4C5A154B93A328AD1 -:106A10006C497EA9B493D8EAD67E2D43EC572E0C50 -:106A2000D0CF09EF694D3584C9FDE1BE1962C75069 -:106A30002E2E08B14AEAFF73B8DD886711AF12A5A0 -:106A4000278D8B84705D5F0BFAD11E5F07B5473CC5 -:106A5000BA64A37795A9078A80C673D28AECCF9DC2 -:106A6000F1923F8866FCBE93CA170D75922D0554AE -:106A70005FA788F6E14CE94C6F7FB25E25EE6B3282 -:106A8000ED44F54B0DD72F95A03F34AB84CA178D3D -:106A9000C3D5CC1F63201C35D97A18FD7009C211EB -:106AA0003A8783AFAA2EBA2061F1ABABA41E05E5ED -:106AB000A88AE86FEBFD8D4116274EA5B765507586 -:106AC0005F11DAB102C593A891B665DF9FB4BACA67 -:106AD000B91F94BE64007F776390C581D76C199B02 -:106AE000CEE229767D758E9F0F3FDFFF0305FD9770 -:106AF000B3CF9CB809F7B9FEFF8AA09275CFEDF726 -:106B000043273D37120A9E1BEB3AC4A471768006D8 -:106B10009617FF573FA5D7BAE7DD890564FCBA177A -:106B2000DF9F0404BE739B7B0E8D42FBF919178B0C -:106B3000771BDD931693FBEB2458154D325FA1C4F0 -:106B4000ECD4333F495B8EF2EB6A3B703B9DB77DE3 -:106B500099ECB69CDFA32499AE4BFA45F0B9F1B499 -:106B60002B3136895F62E619CE3CED62F0BD2453CD -:106B70003F6F5DDB1E2546E0A86AFB98EA8BD9FFD4 -:106B8000FA6C00F150F59268B3E3AADAC44EF72428 -:106B90007A3D81578C9FBAA6239F707EE9D840E347 -:106BA000A695ED0F7E2C0670BC5D6F11BC843B1169 -:106BB000AFEF88E105D8FED1BF047482AA8F0E3FE3 -:106BC0001540BC9279572BE9189FB7F337CE7F3128 -:106BD000B3FF7C003D348F5BD5BE85ADE7D08B1F06 -:106BE000E12F79FDE3ABFF24D9F3E3D036B4FCED1C -:106BF000FA67CF3F6990F5CE3CFF87270D02F7BDBE -:106C0000FFFDC727BF8572F9338F867ABDEA99B732 -:106C10000260E1C3B512D3AFE70A88CB44FA9DFB0B -:106C2000B53B8106C1B9577E3F5A27FB3DF7DC9F34 -:106C30007374D2BFE695B9B9B8FF9A1766E70E64C8 -:106C4000DF229F26DC56B812747EFD251733165EB0 -:106C5000E657075D0E761C1C8D709E3DE60E635A4E -:106C6000AE8ADCAB9D8A74DA40CF596C6F22F8ADE6 -:106C7000DCDFFC31EA87FE7836460934A845D4606B -:106C800010E9FCFE3C4A2FE8A1E7A3B37FD55142AF -:106C9000C7C9A9E9761E3E5550CF55EDDFC2D67360 -:106CA000D0ED2CFE726D7FBA6D76D0ED3CDCFBFD35 -:106CB0003CCC97778CB0E5077AEDD4DEB878343DDC -:106CC0003A807E30E57F30BCD2FC09812B2A451EFC -:106CD00091508E9E4FEBA5EB02A4EBB3E74703E187 -:106CE0008B5372CFED781EF4BCE2D6303EB0EE95F9 -:106CF00077A85C9D7BE14D45A7E718F85CC4AE3CE6 -:106D000007BD3F87D1CEAC643E3E54EDF377BA0366 -:106D10007DF4A94C2C2CD703F4FE097A3FC1F8BDB1 -:106D2000327160892B09BD7E298D61FA3F914DF149 -:106D3000B261DF6F15F0D9E9E89A89743C310FEF41 -:106D4000A7A2A3B97F0DF73FC342CF7D4C4E9DFD57 -:106D50002B893CE279D74BD784EB1D482297E7F685 -:106D6000B8253CEFCEA15D95341FCAEC99E1E64D04 -:106D70000E39E5DACC9B703CA4E60F26DF83ED6F7D -:106D8000B8F8EB90741B1F99783CF369727D7F9281 -:106D9000EB8B4A30CA475ED9DF0E91206A8C0AF528 -:106DA000C17B061D52C27F679E1169FCA7A9FD2009 -:106DB000D5DB4E3D518971CB24EBFDD15CEFA503B2 -:106DC00093509F9D79F527943F2BF79F50D0BE3F5E -:106DD000D4F623A5BBB84F1EF03C4858CE83333FB2 -:106DE0003C3089E981E471515A6047E0AC7AD93E80 -:106DF0007FD5FE8F6DF3AF37DAA97D30D83A1F49C2 -:106E00009165B8DF8F0ECBD49FFCA85D4C1A27FE8E -:106E10000F3C0F2D766DD39BF37E8BF9AD92235EE5 -:106E20001DCFCD8ECD91DCED68AF1D9181E60FA415 -:106E3000C81FDCA4DDF1A657C7BC73C791A5A26E1D -:106E4000F1437FECC0E78CA3C66C3F996F4637F1E6 -:106E50007FF5FE7A63E671E25759F8A0E6CDF25C61 -:106E6000D4F7E887EAE371BD7010FD5C3130AF9C68 -:106E7000E5A505CD93F4BC66F3C9BE288D4FC99A2C -:106E800000BA65DE5190A8C73C3AF87CCEBC4354AA -:106E9000B5E697961F3E802E66D6E297F3709E0069 -:106EA000C4B50FA9FD09E14B03D85FCE3C8389CF60 -:106EB0005EF94B917748D36E0F1E80FEF3F5CFAF8E -:106EC000C454CCAF34F9D6B4842CF995A660BFFC79 -:106ED0004A4426786871258F478C91CBE6E073E2AF -:106EE0001DC7923D5F2E333EBF11BAEF5F8D7046D6 -:106EF000599E6696035F5FE2F8FAD964B271A242C6 -:106F00004B41976482DFD94B227199DC9FBBB2E77A -:106F1000EA5769779EA731C60B97D2868EBFE1E606 -:106F2000E34ADD8B56CBD983E7E352E585FBE030BE -:106F3000B83F9E69CB4F1C7CF7011AAF97A1BA25C9 -:106F4000648913E5747A208271FE2C9DDA87399D5D -:106F5000F77C672DC699B3F2C31EE83F8F74F17AB0 -:106F60001ACF30F3F4527E84C6E5254D2F15E93A49 -:106F7000CB2298CF6FD681DA1FCDC181E33553E4A0 -:106F80009881F4942EDE40E715545E5730C47D7E20 -:106F90007B7180E23940F08CF24EFD1FDCDF71170F -:106FA000CF87771B22E6C34F64D0FC404082228CFF -:106FB000075C7079C39B43D02F1F9E8A7FB74B8697 -:106FC0004AE3247ABF7CF82ED9124F53311F4E8BDF -:106FD000F9ECF970D557137C5D47FFC662EF86FA6E -:106FE000FAF5C99D231F8E73615CC6689E8D764538 -:106FF0007306F0FC38CB8737F37CF8B38DD366A3E8 -:107000009E6DF698CF67B0FE66DBF8F5AB111FAD4D -:1070100003A1EDD372CF66EC9F350AAA69FD9914DE -:10702000855B2C7AF0B82CB13A5539F2BC6CAD279F -:10703000E2FC60E67B0EBEFB7BCA57781D8374279B -:107040007C8571A99CCED360D5ABE6D5E49F667DE7 -:10705000E0F8AE7C710ACD9398ED40562C1249C2EF -:107060004757BAD9B963F271200809D4AF8199B1F1 -:10707000EFAC45BE0EFAC26914CE07689DC90E0D6D -:10708000749AA770EC6387BE91F2EDF92CC2E516F5 -:1070900079E90FFF0D1C7EE61F9FD7781C306840F2 -:1070A0002C097CF2C512BA8F2972E4B7563C665D92 -:1070B00091BCCEF60E85EDA731BA92E5D12BEC79D5 -:1070C0004F4C335BE3A6D35CB153A837CCFCB9A0DB -:1070D00046797EC330E3EAC1DE78B68EF580F71AD2 -:1070E000A8DFE495ED860BAF592C1F22AAB18FAD16 -:1070F0007C2C69DD4C0E1DF9BDB9E2198A971D8300 -:10710000D06F5B1DCBA76EADD3A8BDBDA52E48DB50 -:10711000CD753ABD36D545E8FDFEFCF4F3E01DC85B -:10712000473E2FCD270DC6270FD585E97CF1BA99AB -:107130006C5E97C9EFEE06E4774530E5C74FDB3E5E -:10714000D1948F2CDADEEE62CFAF514653F931F98C -:1071500079B0FD8989E994AEC39D3FE57E67F986E4 -:10716000B4DFF44EB6EE50D7713BD6D9314BA57A89 -:107170007947FE20EBB4B27506879FE16BDB81D3C4 -:10718000B45EC04DE4DF43F6E1D62249E5C1949FE9 -:10719000FEF3B8A9DE6ECE62F94FB9D0174165DEB5 -:1071A000ACF37C21916BB47FE4A29C32BC2F87AFFF -:1071B000A2F5DC72B18FE6E3E4C29C3BB0BDEDC04A -:1071C00016AD8CEA01819E5FB5D00D58974BC486F1 -:1071D000C663E5C2A2B5D85F43B9247064BA99FF0B -:1071E00024175E77378E3F30E590DE9085E716E313 -:1071F0003FE8966CFCEF94FB94FA2B68AF5F04E9D0 -:107200004E40BF74DB94BB8AA87CAA967AC62475CC -:107210007DA63E217A638D62A9E354608E8179D385 -:107220009DB7DE154EE62F91F3749D92DD7F1E73A0 -:107230007C851CDDA0B0BA74B0D7A527CF4737072F -:10724000CD7C74B58AE7A814ECADA75B9047F0C27B -:1072500052A9D05B4FE733EBE9C22CDFD54AFE25BC -:10726000CB4B3BEBC42F573DDD16A5B79EAE00EBD5 -:10727000E97E2A43B813F3EA6F89E1BD7A7FBE73D2 -:10728000CEE77C2FC23C0752C965A762CF87E6C50F -:10729000ECF950B8D3635BEF359497E2C1F5CBA816 -:1072A0000AFB3C05D5F6FAD72B6A336DED9031D247 -:1072B000D6FFCA9631B6E7635BAFB23D1FBF6BAA7C -:1072C000AD3D21719DADFFD56D65B6F6C4F6AFD865 -:1072D000FA4F7E6991AD3DA57385ADFF355D6B6C51 -:1072E000CFA71D5E677B3EE3D8465BFBDAEE6FDA25 -:1072F000FAD712F34641B9CDE2F5C259B98235CF7A -:10730000DA924DCE25E2B7EFC8260C43E3D9ACFEA6 -:107310004A618F7BF380CE7192AE44349AB71F37A7 -:1073200007AF20D5D0F354D273CA747A7FFA3CBC2D -:107330004289BD0E56D1591D31FA65F67CBFBD1E7E -:107340005811B7D1B206F7F12F77B926F5A7AB924E -:107350006F9783A1D613CBBA63DC30E5E28C291793 -:1073600005442E683CED5311FD1E98E3A7F685C534 -:107370003FA27834FDA31B5488A3C968CA45E9CA53 -:107380009E51B48EAFD72F720BC3A95F33E52F6028 -:10739000D1FB91AC3E3DD33C7368FA554C5C63B372 -:1073A0000F9DD786C0BA54FA31E01E403F4E91A3DC -:1073B000196EF42FA5880196F80B54CB36B8870ABE -:1073C000E7673D07561386B3EA15134E85E86DCC83 -:1073D0002B352DBE893AF55003363ECD591EA5FEFC -:1073E00009B10BAF76DBC633FBF06FCD4EFE8D6C73 -:1073F000DFA7692F9B780F84C2B49E04F204407FFC -:10740000AE69562C88F1B416EC62F10F1F705F491B -:10741000E7690C2A02D6B93776B1387B835ACDE2B8 -:107420000E72358DBF34640B5AB23AAE3BDD2CBFC1 -:107430002BD63E3876DF007C252AC9E30E0D7C7CF6 -:10744000C3816F74B17352D1D19F06E234BE6FC94C -:10745000BF8970381A72E13A3BE83A010E57A040F2 -:1074600080FAD0E070DECCFD1DA976CB80704A0892 -:107470006712BA9870C611CE92D470FAB3CB687EF8 -:1074800052AADD46D731F1BACACDE8E584DBC4B7EC -:107490000C91F2D9D83EF1E5284D8712B223BFEF07 -:1074A00098C9FC66A2D86DFC6AFA2D845FEB915FE7 -:1074B000258DF92FE6FB055F716B0CAF9C8EA067E5 -:1074C000D2B8432016A775E7FE18F3B7FBF40DE317 -:1074D0001BBF1C01EC2FF9049ABF5378BCC2ECF718 -:1074E0009E9BC5891A667547711FCDD74AB019F59D -:1074F0000FD63763FC2E9FED378EFB22F0FCCC9D20 -:10750000C1F891AFEB8525E9B41052DC1F1C480F80 -:107510007B117F23FAEBE327DDFCBDE03CC863FA77 -:10752000B87819E6A353CDE3B44BCCFAE7E1D7B56D -:1075300057D33846B36F6317C681CC381C044B92BF -:10754000C6CDFBF0CAF2897DF45DA67712FA49D365 -:10755000A6523E69CEE7F4AD76D4E99A75DD9CAECD -:10756000669C1B822CBE63D2D9D38BCFDD03E2D3C2 -:10757000C3E5C689CFAEFFA1F8FC11DA28E4EAF72B -:10758000B3F7C2E1E03780E68DF2EDF2688E33F9B1 -:10759000DDB9FF536E7EBEFF0FDDBFC90FA9FB1B18 -:1075A00049FD1433FFE9E7FCA6E2DB4D44F1BC3EA4 -:1075B000F364CB955978FE32BFDA3F334EDFAB959B -:1075C000C1D0502FF8CDFAD912FB7BA0DE62BB9D53 -:1075D000A53AFC1185D72DF57BCF95DB63CEF797C8 -:1075E0007AF1EBA0D7683545FE6A88EFFDECE4F947 -:1075F000B4BC9AD67AF46FF3EE6475F6BB65588521 -:107600007577232B0CC19B85F995D0736964FF793D -:107610002F3F5C3F0A4972A71E42B3E17BAA6E8BE3 -:10762000EFE7DDDB5AEA65CFA7E03CBB54A677F372 -:10763000CA5B693D59C30BE3D3D16F79EDDD651AA0 -:107640009EF79F6415D2B8EED917DD11CCEF9DCD12 -:10765000840A5AB7F5E28C436897FFA1AE2B53B268 -:10766000F0C9D91FBE395D26443AFBFC9BD3254A9D -:10767000AC84EDDCDF70E957D3116EA30C8AAA311C -:10768000BFA629F47D932A95E5B3CC7A9C9D394A0F -:10769000135E7FE261FA382757D881ED5A0C70A14A -:1076A0009DC0E3EDD79FD197613D644697ECC27AC8 -:1076B000B9875D86E123D70B271EA6EF5D2B9DD5ED -:1076C000183621F7C30711E5C658E6675C08415133 -:1076D00088E87DEFE1EAF1D43E76D42399FC2FCD02 -:1076E000061A97E8B9554DEC0D617C58FFF64AB281 -:1076F0005EC34A89D6CB6C970EAB5A123DF68667AD -:107700008C0DEF7E1E2F3EF8EEDDADA564FCC62984 -:10771000AC8EDA77624A3A2491DFED7533E9FA816B -:10772000BC93E5A508D6A7E4EEF43EBFC727819138 -:107730004E8E4839241832C18B6F26C0490BDF3575 -:107740000910D1C8F317EB80CED351A7D26B5B9D44 -:1077500036B69018FADFAD0BD2EB63753ABD3E52E8 -:1077600057449F3F5417B6C93DAE77B288B743A977 -:10777000E5F6725FF17DD8931638764E24524FE8C5 -:10778000B593E78B1E2C9E9ABE66807CC3EEBAAE84 -:107790001173C6726411FAE5D7687BB60E00FFEE6E -:1077A0007AD7AA459837B94F8AEEA5FA3196B7C865 -:1077B000A21F1BE5581E1056BC5FC99C33278FCAF9 -:1077C00023959792C331C03A9BBC60AB0BE3D6794B -:1077D00047D97DF3FD074A2F22683FCE9AE39251A5 -:1077E0006F16433B82A514C7A08CF49F91BDA414CF -:1077F000EFC344FBFDE90A936F9CB78C5CA7AAD149 -:107800003615EDA6CC5DC6B3643F7FEA70EB988772 -:1078100079E8D53F2B187F8FFF5A51D18EC97BF95C -:1078200004AD4B88BBBA156292C11B2D6BE748446F -:10783000CFC4793E802A16C22771D4B1349EF9FB99 -:10784000F89C627CFF2476DADA7FA737761FB65180 -:10785000F1AA41C2471EB3FF9A78249FB4797DEB09 -:107860001B2DABE3066D93FE53583B4EC6BF9811DC -:107870001B25107CF9EA57C5BBBE846DB3FFAA383F -:10788000D6C31E52593D26F8622194B7DEB646DAB9 -:107890007E4B5B626D50D9D5DCEF86837F3E847A68 -:1078A000AEF265573B8246F41EC3FF4B0FD3EF2465 -:1078B000B4D575697199D3DFA40311C90941A07EBC -:1078C0008A927025C610FD31817F1722AF24A2D77E -:1078D000A37E4DC861D49B577899DD382141E6B12C -:1078E000C8D58414DF1FA17959A4E33656D7DB8F9E -:1078F000BF3CCC9EAF05632BFA0DB05FD668BE903F -:10790000C71DCF98E71CF73FEFF5B0A6BCD9F05ED6 -:1079100085FA67B544E35AEB43ADA50A5967FD4FB5 -:10792000426172B242A387D51DACCF68CF994AF8A5 -:10793000A431C3DE7E98D7B906338C8CCC62AC0BF5 -:10794000787834E6ED2BA1F5F66F22BCBF64F9C15F -:10795000D307AE4DBF9EB437FC92C5753774BCA932 -:10796000C4483FC1C3EB093AA67C05F757B94D009F -:1079700021C4E433329EE039D27A9544F864A27788 -:10798000C45C4F01C0D363229A40F860FED68246A1 -:1079900015DB8A3601E566FED6C246E4ABF513CDAB -:1079A000EF2414BE1E29E4F54C23719D07E21877DD -:1079B000DEB7A2FC2B78CCE6084C6E0923D2FC9EE5 -:1079C0009811A779A7FF6C14685C1B53EE9BA66205 -:1079D0003D1D7449E4BA5361F4339AD8FB0CE47E3C -:1079E0008B3C15E9C2DE1B228E24D5FB635F76D368 -:1079F00038726175E41E6A1768C592F5BD2CE0798E -:107A0000E32BF03732CF780D4AF1BD80A73D2CFE35 -:107A100057B87CE97A1C27FA977851CE73C4844111 -:107A2000E7FF1E8B3BEF1412EDF81EA31128A4F400 -:107A3000DD19607C613C524CF9629F5076D57D84A3 -:107A40000E8DAED55BFF0DE99A51084857BCBF912A -:107A5000DCDFC7E929668435A4DF3E4ECF784230AB -:107A6000B07EC5BCFFA26BCD3D286FB76ED93F4736 -:107A70002578CD71475A47103A2CDFB23F1EBC968D -:107A8000D2618C4AF0BEDCB33F8E74D8571F19A95F -:107A900059DAE3FF42AC115A07BE9FCAB394F1C84A -:107AA0003A9477F2FC3595F0E9D399A6BE60CF0BF6 -:107AB000C7F4EA8F0890B346ACEFD3272A391F0AE0 -:107AC0002DFDE710F9FEE727599DF997C87A28EFB1 -:107AD000641F343FDB33414AA0BFEB25B0A0DDE299 -:107AE0009D3886D6CF917D03DA253D13257ACE9A2F -:107AF0007169F70481BEE78DFD911FBC05AC3F1194 -:107B00009428EA4D295F02D4EB92B83B3241C7700A -:107B100030CBBBBAB485F43D514F9125CF0A7D756A -:107B2000BAB41DA29F97B1B5C7BABBF3046257663A -:107B30001D5FE81A4DE65BEAE1FE4616B1B7C9FDE6 -:107B4000151E662F3D1035BE8C210DD0BBF3A87ECF -:107B500082E854BCE6DE56989B2C1FD277AE3BEDF4 -:107B6000EA6E6A3FECF009E5C9EA4F0BBD3CDEE086 -:107B70003B42BFE7510B44FE512ECCF764B9FE30B7 -:107B8000DF1F70D6FB9AFA44CE607BAC995F968B70 -:107B90007A40E2F5439216D6B0FEB1D45F42EDBE14 -:107BA000C7B99E120F5C7B33BE47A1A03E00D45FD5 -:107BB0003103F3FF3D79D08EFC2A052360CDD39AA3 -:107BC000FAA0A94EA5D7A7A68E2B4339796A6A4E8B -:107BD000994664E0E0A49F7661DEE8FC6E26BFE78C -:107BE0000FAF35687CC960F122642B1A67EC7C9476 -:107BF000BE27FB0329FA10AD7BC5FA0502D2B60CED -:107C00007B7DD5082FABA3ADE2F036CAEC79731DAE -:107C10008B072B17AFA671A9F3FCB93B76277DAF75 -:107C2000C24DCE327CCF5105C360DF196078C0F7FA -:107C3000986C798B8B93E8F82A0FC3BF59CFE1ACCE -:107C4000DB30E119CBE1E9FFDE849D1EA6FF65D2A2 -:107C5000C11C5FE38AE46A03F04DD545111296F822 -:107C6000475FFDB542EF9FC3BAF574ACB389B55E0B -:107C70001F42394850FFC8E3AB01E0DF35A27C1A50 -:107C8000947AAC75E2698EBAF57EF2A2DBDBCEBAED -:107C90008515C81CD3981EA7F5A6127CC745E87D9C -:107CA00036EDBDE968D75611F5A062804832345CE4 -:107CB000FF1CB7F7A597EF8B8CD2FBF663C60BCCF6 -:107CC00076E54B0B691CA16A9F8FD6E357A2FE9BFA -:107CD0008C75FD4697DB56CF1FE9C4FA39F9253676 -:107CE000DFE31C9E3F691579B8EF37B8FF9323C4D3 -:107CF00044F652CA618A87B827720C34A6CF24C2D0 -:107D00001371B3DEC2581B478761A702367B69A790 -:107D100097B5FF73CBDA789C9DB3DC9EF984DA3F8C -:107D20008D1EB37D96EABB9D4A6B27EA3BE345B7C0 -:107D30008EE717194FDF93365614D173201E8291A8 -:107D40008887D73214AAE7E22FB8F7A29E9BAAC66B -:107D50000EA916BFE16CC6DBA3D1FF4A329F619B1F -:107D6000AF6078F391F53B10AFE6F3D73276768AC1 -:107D70006C9C4EBFAB917F78F46AD2CE79D14DDF47 -:107D8000EB31FD4D275F2A5E265F4D8EF7F314948D -:107D9000371FEADB6A2A67EEA03DAF65CA9D7271A4 -:107DA000822DBEFF383F67152986A14AF2BC983E56 -:107DB000AFE2746DE27506A9D7C94CB1CE35549EB9 -:107DC00053AF339DCB3B703996B4DEEFB10CF01E50 -:107DD0009F33EFE1D453BDF2CAF5D0169C1FE3BA2E -:107DE000101BE325D77589F6795E3A3A3609EDE03E -:107DF0005F737FBCA8EDE157F1786E7147EEF24CEE -:107E0000A3EF657D17AFC39587F95EE0F1947E7AA5 -:107E100088D95777327BB566FE546ADFD56C1FA3CD -:107E20001903F8491517D36C7A48F0E8FC3B77063C -:107E3000D547151703F4F9E55BCF637BBFA4FF7A41 -:107E40003EFADC5CEF5E879E3D38E9173B0BC9BA12 -:107E500035CFC982DBB24ECD73BC3EDF43F4AE5D9D -:107E6000DE2328EF52087ABF4782FA619BC2DBC645 -:107E70008CC639F968D75AF4C34CB4BFFAC6E3F7D5 -:107E8000E5B679CDF19146B487FAF54F73F41F63E7 -:107E9000CE5F4EFB3BE131F50FB6D1DE92FEE2360E -:107EA000E1A3FAEB61C1315FA6B9FE423A9F69775F -:107EB0009F6BB9F57543423E6D2D45FFA9672DE8CF -:107EC000F8DD871F48616FD8C2B7E75466F7575C83 -:107ED000BCD246EF3EBC8FB3DDFF7D5DD0564F7BFD -:107EE00077AC86D6519F5339BD88654EC7ED1E6568 -:107EF000ABA3FD071C9F158EEB53C071C35F198E9A -:107F0000904D3EFBE028B4DDFFAC704454A68FE7F3 -:107F1000F1EB5C8DBDD73A5777851BC8ADB9E4BE90 -:107F200087F0FA97C95525D7B912183EFA3DD20401 -:107F3000EB4FDAE8DFDFFC97FB3FB89126AA82B669 -:107F40003A0191D7613BF50EBE77CDEAD854DBF705 -:107F500042CCAB5764F594CEFBDD3C6EF0EDAB2B21 -:107F600001ED6962AB277DAFACD1C7FA811A146C01 -:107F7000716EDE36EB702F175C7FE4E7F4B7AFBEAF -:107F80000930AE2B215C49FAB573B89AD408CDC339 -:107F9000C5B581BF07F359E191D34C3CDD40F124D5 -:107FA000A6C0D32A1FB72FB418F5939A825F0C3C52 -:107FB000B9BDF00C8C9F6FA43178E0E215948F442A -:107FC0004EA7265FF2EFDB98F98F26F58B857F723F -:107FD000DAD0E8BB87F7FBA2E95B3A44FA8E30F9C6 -:107FE0004DFB62E1593C4478AE35F92D18A1F4FA05 -:107FF000A2E0593B44787E6ED24BFF62F1F3C01091 -:10800000E139CBFB29692C3EDB54C4DEF7F08AD181 -:1080100087B0DE6130B9F016DAFD6C35DF6BAFB3D7 -:10802000FAC05EC7956A9FBFE1FB4C254F2BE44425 -:1080300036D2EF581D8B07BCCDFD93DF5434F86961 -:108040007CDEB14E5370AF7FA0B8CDFFAAB0BF3772 -:108050003B981C17A4B1FCCFAD31FBB865CBD31C4A -:10806000756106FB4E30C75FAAF9FE5EF0361993C4 -:108070009843C01BC1577A6800BFE172E32B95DCBF -:108080000D175F716D78F81A4CDED722BEA60D1D54 -:108090005FA6BCFEBDE24B1926BEFEDEF9ABF41FA7 -:1080A000F81A16BE160F571EB95DFBF78AAFA1CAA4 -:1080B000A3D36F23FE5D78A0F7FF2F37FE9CEB7FE5 -:1080C0005E3C9AF3AD48E1E7A5C2E7607098D76ED1 -:1080D000EF10F1EAF43FFFDA7875ACFFB9F1CAE7C7 -:1080E0001B365E0781C3BCFE11F13A0CBBAE4D617D -:1080F000DFF574CE93ED67DF5B1BEFAA3E321FF313 -:10810000C75F15697EFAC8EE391BACF540D97E66AB -:10811000FF1F299FBD81D65747D368EDD95121FC58 -:10812000EF2598575EC4C639E73FC2F1F55FBE0C34 -:108130001ECFD6B391AE47A38B07944728B7EC8BDD -:10814000E68D2CF415FBE3FB08E8DB4B300FB12088 -:10815000391C269D53AD3B5CFA1E8DFE6058FA67B4 -:10816000B0FDFE876FA8767A82E2310B7AFFDECD12 -:108170005588CF3681D5C31DC75B79F8DD35A09D05 -:10818000962DCFDD83748AF9595EB043D13760FEF6 -:10819000C4BD78C1837E42B7A3B764B8DC167C5DEA -:1081A000E3677ED5F495C9FDAE08E783BEF12E18CE -:1081B0009F84BF27F37EB7AC64DF07032952B0C8A2 -:1081C000F21EE90ABE8EF9DC397EBE3F40C71F4D64 -:1081D000F15EFEF57CFE654B061E0FD5ECFB3B8485 -:1081E000EF0AACEFB1F6F219978FE3BED81C3F81CE -:1081F000E76D57EC89AF211F4DF0B1F7802408617E -:10820000FD95394F96049D0AC1FB07B25E8079CD7A -:1082100024F37C75A07952E1D5DC8FB90E8A227ED9 -:108220004767AECAE28825118059183F7487EF630B -:10823000F943C60799BC0E7146755AA21EFD5E89A8 -:10824000ECD3026FC7FF9BFD4FF8BCE388A0D1F7CA -:10825000CF1D78184C3F6CE47C9325C6367B306F7D -:10826000B2CA95F43B73EBFDECEF0C15F87BEBA574 -:10827000E83AE31E8BC9F87D8AA512CB7F114E2CFC -:10828000B0FEDD9102CE07CE715922AB37827798CE -:108290003CB7ED5D57904C7E7EC5E5B4C05F64ABE6 -:1082A000735C12BD4F46F95CB260A1ACFBF0B9CE75 -:1082B000F88DC3D1A6C40AA6F8FAF094520F71FC47 -:1082C000741C8B35E0773956D5BA689D40F126C6C7 -:1082D00077AB361D103690EB1E2E7F0B910696F96C -:1082E0009EE0746DDBEB1D8DF0B799F91B9C98C077 -:1082F00071FB2EA0F990C7FD1F34613EA4DB053C45 -:10830000FF1B2DC7FC6F37AF6F7B8E3CAF4778E705 -:108310006453F91EB7E9E31AD4CF1D0AD0BF7BF12D -:10832000BB2DEE04BE4F60F24BAF9ED874A10EEB96 -:10833000871F553A2722DF6437547F2D59FE743F3B -:10834000A7C39F7CD1F46476A07935F5B9D96F9134 -:10835000A4CBC9FA2F2E779C6B1CEE11EECEB390F6 -:10836000248FD9CB878981EDB4B7B81EFF9523CF71 -:10837000BBE458F23863975FE0F396ADA7E796E168 -:10838000D669CD3487C7C45796C1F0B4748968D311 -:10839000B7AB16A439EC1E86D79BDDFA93B88F478E -:1083A000F7FE62227D2FCA713E78C59882CFEF8694 -:1083B0004E19F5C42951A7D7B7EBECDFFD7E1B6240 -:1083C000DBA7E1F9592B2695ABF739FFBCBDFC8E35 -:1083D0005B28FC715143F84FAC1C71D34CD42FCBAC -:1083E000E5F05832EE44FC7EFF5ACBFE7BED1A07D7 -:1083F0005CBFA9B863C0736BD9723BDDDA14661732 -:10840000185F6172780FE1D15994BFBAB7CF20EBF2 -:108410001F49644ED9CABA03FE7DA7C5FCF7534273 -:108420006CC70CA26F4E0B2C4F627C9DE98D258F83 -:10843000451B31757ABAF69A57BA49BF8B7C7FEFE4 -:10844000D50E7C3E3AF969DC63767B6FFA31507069 -:108450007CAC26F979B0554BE37FC72B3C1AF5CBA2 -:108460006D9B92F7FB213233A1EFE9FF162B92C5EA -:108470002727680CDE55D1E4E327687EF61CCFA5DC -:108480002478FE2090C6F59C361AF5F4AA14F076EE -:1084900007D8F9F57EE303B7A11E3825D8F5F39187 -:1084A0000093D7F600E3EFD37B57C8D948A72697A8 -:1084B00086FC7032233C01F96D75FC047DDFE55FBD -:1084C000020CEE43DEA81E9886F2B2686E36A14B0F -:1084D000C74A08BBF4D4FABF2860EA7F16AF25E785 -:1084E000DF0778FE91A11F50FB438A8CBE75229D49 -:1084F0009AD6819F168C75B4CE70AF97D595427879 -:108500009AD58E9FCEE13EBD6F78F4BE25EAB0834A -:10851000FAD97FAD9574DD7D691AD6A51C29173B64 -:108520006F24407EB82F8D7EBFD62917A9D61FAEE7 -:108530001D787ADFF0ECC0C1F6BD32101A921D78BA -:10854000BEFCD11D2528474AEBA464FAD7D4D347F3 -:1085500079FCDDC93FE6B582F3C5A9C4C070DDBDB5 -:10856000CB0ECF6DD576784C79399568F0AE463C18 -:1085700041E744AB5D0A73A60D72CEB2FC542A38B3 -:108580003705EC7A02390FE9700FD737EFD53E1A6D -:10859000B0D2C1B9FFD302F70F9E6475B963A3AB24 -:1085A000CBB2F53EFEDCC2E7BFDC7C699E33CE7900 -:1085B000FED6F9D03CE706E3C3AC14799C027C718B -:1085C000998C5F2D690AE6EB0B023A6B83360F5FDD -:1085D000D58299E6DF57D147E3FB5FA7F77AE97BBE -:1085E000C0C6567702BFDB7E6AEFF513ACFBE9E24B -:1085F000F459B524837E9EE294109E9F4BEBCE44AB -:10860000FA9DB5B78F65CEC3F6A38705D4D0705B4E -:10861000CD6A11F7F77A80BDB7B36AD39BD41E1C1D -:108620002E9FAFAAB69FFF13701FD9163B4BEA29A6 -:1086300041FE49858717100FE8074517CE45FD7C99 -:10864000C72617D5B72FF279EE9022546F439C9D21 -:108650008FA0127C9023E4046E02F1F138FFAE94F7 -:108660001455ACEFC9ADDDF6C05CAC7B75CACB97D9 -:10867000D3199EA6A433BD7DC81B7B2F90DDA79F79 -:108680004FBAAA0FE4922EEB039AF91D5F2AA7E6D0 -:108690007ED673B8889DF62CFDBE30DF1FF438F807 -:1086A0004D68ADFC29E2BF4CA57681D74DF43ED68E -:1086B00045FFC04BEBA84CB932ED1DE7F8A552CCF5 -:1086C00066377ECAF59ED976DA21FF382F92F71FDA -:1086D000931E1A929C5EAEF36252FAE5392F04CED5 -:1086E00067CE73A357AE9BD8FB20278E7D32379978 -:1086F0005CDFF819E170CAF3A9BD5EF65DE31BFC0F -:1087000054EFF4F953B909F4979D7281FE147EC7B2 -:10871000E3D1BD6F4CC4BADE13DB1FB82D193DAFDA -:10872000D6781D7677AE2D9EB72600B4FE1BC87A8C -:108730004F59E637C7F5CACB20F1CBA52BAEA5FE26 -:10874000E4DB2BAE1FBDBAB8BF5FD1AFBF2BF6F8CD -:108750002DB86E3DF7A777B82BF626F303395EFBED -:10876000C789EDF6FD2D9B4A1BD1A5DE9C76C397EC -:108770006249D6EFF56B36258FC7FD9F74875F631F -:1087800010BF86E0A37BA5189859D2E7D7741B5F6A -:108790008C5FF33BE8F9F71954FE93C3F7643AB3DF -:1087A000534F29B11DD712F84E13FFC740F911C816 -:1087B00038E497EF26F7D71EE1E37EB76998FAEA27 -:1087C00098DD9F49257FBD707D4EF96B537A0A5025 -:1087D0000FFC6ECFA7EF3E80FBD9E3A5F876CE73F2 -:1087E000A32672FFC24BF9D63C9F3B14A6FF7FF72E -:1087F000D591F4EF553BE503A0F5A6EBC8F3E37B79 -:108800008529F81DC4B6BD6915C9FC9C159A8BFB5A -:1088100017F6780F70FBEE16CE6FDADE67AAADF1B1 -:10882000E877B8BE32E300AFA4B37376C982850A95 -:10883000C67BD6F6C69B803A2BDA55F97BF03B52C5 -:108840006FF1F7B98C35FEA4EFC7FD82F3E56071D7 -:1088500088E52BED7182250B063E6F3E4C24AFCB95 -:1088600032F939D57AC33D5FDA12C3CB8B0DB64FDF -:108870008F36347FE416A8FE12C63B964258C6EBEC -:1088800012A89EF85382CA0F772DA6F0BC65FEDDB4 -:10889000E14FEF9F68B563FE8BE3FBFC92FBBF8A61 -:1088A000EAF21DA57A62B2F3C919F7792B053ECF1A -:1088B00070BBE71DA433F2EB5231299DDDDC8F7FC5 -:1088C000672593A3FF0F425212950080000000001D -:1088D0001F8B080000000000000BDD7D0D7C54D5CF -:1088E00095F87DF3E62BC924992433934FC2840075 -:1088F0002206984008A80813422428950904080A6B -:108900003A7C88817CAAD8B25BB74C0860A46E1B05 -:10891000566A5DAB74A0C152C536D1D422A638A028 -:1089200028FEABFF06EBBAB845775017F9924456CC -:1089300017BBEB963DE7DC7B336F5E6620B6757741 -:108940007F1B7FEDE3BE773FCFF739F7DC3B972EF8 -:10895000C1DF0CC62EE99E8BAA5516B232FABB04B3 -:10896000FFAB9E9B145576D9ED8C3919FBC7A5AD8D -:1089700089FE22C64E19E065096381C7D4E06E0501 -:10898000CA41FE5EF6E7B22B54FF547041AADF36AF -:10899000783CF9BCEB5118774C649C65CDD1E386EB -:1089A00059602D73C038C144FBEE0286FF0C592676 -:1089B00046DA77DA0D340E3B9569602EC6EE936D7C -:1089C000E38CF7BB0DD0C15583EB571BBD26BB66AF -:1089D0009E2B52DD8C4D8E94ABE746CF3335C54E82 -:1089E000DF19B3E7FB92193BBD2BD14BF0989E1CCE -:1089F0001C05F3ACB0B2800DE6F9F093D7BCCF46BE -:108A0000305625E051EDFBD484F0386DE8DF9C8CC6 -:108A1000EB7ACB60DF0D43951EF39AB4F05B9BA21B -:108A200050FFA73B2E0FBFB5297C9E0B2AA3E7B7AB -:108A3000F058625459BFDE7FFE9B072662BFFFFCE1 -:108A400037174DDAFE177D91CB421991F21D358A09 -:108A500037583478DC8E54F390E0DEA183E31D5F59 -:108A6000E453FF0E953577C65897C76EA5FA0B7D70 -:108A7000652627C073E5FD8A47812E8AED6E1A6F41 -:108A8000A591793B613ECCE8CEAF02B83B5B9BEF52 -:108A9000F3C5E8678D9DC3EF339B2FD57E19F8BDD5 -:108AA00023E841D65B64F49B62D55F5C130DDF3035 -:108AB0006395B1E67FFF57A44739BEBEFE50E7512C -:108AC00097C2F932C312FA84A9F0E21CF453FA15E2 -:108AD000C6D5D5D78FFBD702EEF1C63FFD47B536D9 -:108AE000161CF60AF8FB7D403F31BF27D3F7B75875 -:108AF0007BE37EE2EF24CF6E0443C7CAEF01DAD9ED -:108B0000EA39F7BD0AAFD91F920B68FCA5BEA315C1 -:108B10000856F6E5C3E311EF9F573EFCBD1298DA05 -:108B200069B3BF35191A9CDEA87802EEC1E3BC8593 -:108B3000EBB430F6F6062BADF70FD096F0330BFE04 -:108B40002F9BB131AAB70E850AFBB6C5BD5BC3B773 -:108B50008EF51737B0F18CED31FB36E21446DFFFAE -:108B6000E93A86328F0569DE1F983C6B08DE8C116E -:108B7000DF1FDF65DBB915EAFD3199E3032839DF33 -:108B8000374E23278C762A0F153FBF8B839FAF2A42 -:108B9000A7E43AE38D0390A7F9CE9F696B5352196E -:108BA000EB36BBEFC4F5F4CF49B0EF0214CE377B00 -:108BB0006F46F8BC75D4606829A06E8D48A70BF885 -:108BC00010ACE09682EF8E2D41F963F226C054AAD4 -:108BD000A00DBB16E868A62D80FD95FC6EEED3882F -:108BE0009F876B2C6E15FB9BEE7E4F85F2FC9B2CBA -:108BF000EE8DD05F69EF88830EE87FE15CC5CEA083 -:108C0000FDAC39A39C61585FD27AE82707A7F79D8E -:108C1000CAF2918C3D85835DC7F8840116F3155126 -:108C20000E3CD5360BE4C15867B7C106A05EB8ED5F -:108C3000A9362BF4BBB9C597654F83C9A6B5B459FE -:108C400087813E72797B6778189B9AD65A69BD01F5 -:108C5000D6F998EC6F539B378FB1170DFE0205BE06 -:108C6000DF91F644A511E6EF2894E377D2F7453774 -:108C7000ADD9BD0EFADFBCED50A511E7BD548EFF96 -:108C80005A65B911C69D26CB6F58B1EC4812ED71EB -:108C9000BE5319338D88CCDF9805E3A7CBFABD9579 -:108CA000B3A0ED3B65CDE54618FFDD6DEFB41525AE -:108CB0003036656E99DD0BE5F7D3CE5726017EBAC7 -:108CC00019D029943F48EBA7F93B5483E8FFD336EA -:108CD000EF349C4F602C7E57029FB5551633D660FB -:108CE0000DBF8AE4DAB43E6075C13F262B9C4EACC2 -:108CF000A6666F2EC0CEB4AF2C944BD369E7F4991F -:108D0000171A877A6CA03C06CAE334E52C5EEEDEC7 -:108D1000C8EE88256F83E95CEE7527C6FE3E318D6F -:108D2000CB03801BE993D463CCBB37865EC94EB3BB -:108D3000513F871359C09A1EE1B779C0C353812FA1 -:108D40009995CF53F633487FA4713DCB02F3D2916E -:108D50006FE66217B0F4428F1240BA66CD49C15136 -:108D6000483B2C645C80FA4335D07C9DAA72471541 -:108D7000F4E74A64FE2E783A331895A1BDB7CB16B6 -:108D8000E9EF0D41F71585BE0EECAF2233BBB8B548 -:108D900020D20FCC7B937562D4BC8D53D3F1FBFCF6 -:108DA000E2BB8B34F02CE2EB003AA07630CCD3332C -:108DB000800FBA7BC78ED80AF3FB5027774B7BE72F -:108DC0009B18D4DB9C2EE4899BB7779673F9D37FED -:108DD00077527017F2A7D5538C7892EDE60AB897C0 -:108DE0003F30F78758AFBED7C42C506F5D57592618 -:108DF000BB8C5EACFFE27A169CA4291B4366943BB5 -:108E0000F55F4CA7F7E50FBC61463EC57EDCB0AE12 -:108E10007509DE4C0FC2AD3536FE196BA179D47FD2 -:108E200091C60293B4EF399C22FD3BE8FB95D61521 -:108E3000E94F65C18CCBF567A6EF0370370AB89B85 -:108E400063CFF35E49A7006F8386BE160A7A03E9F3 -:108E5000E7457978FC96A25D28EF23E36EA476DDE2 -:108E600046C023DA81BD896EB48B4B8D5C7E96F64D -:108E7000A6DB034A843E245D48BC76A73797D17AA7 -:108E8000AB14FBAE82C1F3FA6B392FA14F3397FAC3 -:108E9000D5E59AF9497E80FEBB45FF2553897F9E23 -:108EA000E0FC007CB30CF917ED165C8727346E7E6E -:108EB000F2E0F97F0CE485F5018F1CFEDFB005516F -:108EC0000F48B80D867FEE15F0994FDF4B7B0F9959 -:108ED000719DF571F8F6DBE929346EE6B1508A1B15 -:108EE000EA9DB57379D5DD3929E17AE48BB9068637 -:108EF000220CD78DF66AE980BCBDE1F599A01F323E -:108F00006519E5AD1BF130207F43566BA47EC3DFAE -:108F1000DD306713D4775800FF4564875A99C69FA0 -:108F2000F8591A976353FD2CA6DDD2929E4CDF258B -:108F3000BCFF7E7D39FB10D6F7AF76CE9753C301C9 -:108F400005F122F95A2FA78E083C1EFE1F9353CA23 -:108F500015E454959053FCFD6130F3B19ECB151A86 -:108F6000A7804E5CF1FAA451E8CFDC93A5BA3F028A -:108F7000BE5AA078863D03FD565BDD9B93DD113A1A -:108F8000A96656B70DE10E46D325D4FB7313A88C02 -:108F90007F68975C6857381D32776AF5B8F8724871 -:108FA000CEE39E2C338DB7E2C151A97EEDFC849EA9 -:108FB0009867093DC30A07F3B92CC3FC1B0CAAE64A -:108FC000BB8DEBB3AC64EF87698087B7145643F36E -:108FD000D1D94BFF21FC36BDBDB449D8914E342FB9 -:108FE000898F0DE49C66B659828C3709A09F9AD967 -:108FF000C904BF860CF51A3AB8989647F358BA18C0 -:109000003E4E00A6B4BE3CE1230D1F1DC1F9905E8B -:10901000084D463E05B119358FA5AA2F4F41BB35E6 -:10902000D3E24139037822381C4E60C60418F73564 -:109030007822DE2AD4BB0F9A1C48078AA795A0BFC6 -:1090400053D8A72C84FA66DE8C24B25BD997F78EAE -:10905000AC0278389338DD423F56D18F95E844C84A -:10906000BDDFE65FBD0BF593949F120FEC4B95FAB5 -:1090700093DF0F2B557976281F765E55DCAA44DBEB -:109080003F680F45ECA7C40767033F4EA9EC0C19D6 -:10909000EC285592E77C0BED70B09F12603D19E90A -:1090A0005C0E1C2E08A829D8DF285807BC7A35D1B9 -:1090B0005FD46C8BE0036C1C3FE2CF6586A78DF319 -:1090C000073EBBD23932AECFE0CFCDE2E94AE1F57F -:1090D000F5F4F6830CCE9F6B150EEFAD655C4EE894 -:1090E000EB8D17FD36580395AE115AFBCAC7900E8B -:1090F0008D8CDB5913D2059D947378953FB0341550 -:10910000F5E6E7BD0B535951448E6E56FC760FD4ED -:10911000DF6CF27D9FE21DFFA032F447CC697E7BBD -:109120003AD4CB488AED2F57A7F3F966A03F0DF547 -:10913000BE27FC1DD317D7909F7D23DA65F03D2510 -:10914000AB9AE439C2D00DFDA6B2FE805D83BFD4D8 -:10915000A98628BFC1F4C5786AFFD5ED86E23876C6 -:10916000434994DD20C7D5DB0FEF6DC8A2F9CBF6DC -:10917000CBB2DEAE609AFAB7B3F066ECEFF675B933 -:109180005171A27876C75A8127B4130231E7658EF0 -:109190007AFF1EF88901EDF8A7F8F891719380D154 -:1091A00022E34E48F7D6A5133F4DB39FBC061E6081 -:1091B000BB5F5249DF90DC07BDE4DD69237D548944 -:1091C000F25AFA47C8F7F654E4EBB27BD3276BF4B4 -:1091D000A368A797439F087FFA13A167528F497B23 -:1091E00031D1AD28117D33585F093DA3938B57B220 -:1091F000AF815E035AFDAFEFF787E97FAA5D59188B -:10920000873E46FFB7D895A5D3FCEA38949B950ACC -:109210001B058F29B3A2F5FCD3E9DCFF783A3D2981 -:10922000CA5F99BF34BADE2FB0DE647C260DC95FF9 -:10923000D1EA21454579C7FB6B14F45070E62DB394 -:109240001BE4EF19B483A0DED10CEFF348579B1257 -:1092500053C6A37ED8F99FE56376C2BCFBDF3479A1 -:10926000766177FB387D942D59D76A84F7A64EC571 -:109270006E6191F9D9D6774D5805EB3D28F054EF42 -:10928000E0EBA87784CC2361DC9C7A3E7E5EE741EC -:10929000C5A8916F79B5BCDE6FD24D51FAE6B758CB -:1092A000867EDE94FE070BB65494607DAF712B88EA -:1092B000BE9C4E85E2C139CD0000A0831C0FEFDFBC -:1092C000E6092A2B8B22EB6C335415A15E687325BB -:1092D00079502F6439FCFF80EBAC3F1E0A2198A621 -:1092E0001CEF35A27D37D1E17D87F84AACD3ADDAEA -:1092F0007350AE261DE7F36BD7D13B63DF15F3DA6E -:10930000C5E5ADCA8E30C407CA0E18CFB5710CE9D9 -:109310002559DF952EF4848BF99F25BB8AB531C280 -:1093200017A375B8368E26FB5EE23362475D3D11AA -:10933000EDA8C28742C615D06EFFE386CA5876E212 -:109340006702EEB08E3EED3AE2F185D463B29E291B -:109350008E1F2DE93DA932B67D0A1A80BE972D7168 -:10936000DC8AEBAEDF6466162502FF890E9F21C3FF -:1093700089F8DAA9206C247D6D4A7F4AC985F5DD1C -:10938000BB86D955167FBEF5EB9F9BB04AE36F4174 -:10939000FF848F9D6656ABD5A7D29FC8C9E0F6F46F -:1093A0006A872F0DC76DDCB7CD8CF85DD371C2AC69 -:1093B0008D770F5AC710E1A5D4723FA5BEC61AC457 -:1093C00075962D3112FEEA369983288FEAF7768555 -:1093D0000C684FDFCF3CC8EFF59D5DAFE6005C72D7 -:1093E000EBBD935577A4BFDCFAA082F3710111F6AF -:1093F000929F1732A37ED6D335DAC36897BC9AC042 -:10940000F9FD5C992DA000FCCE99FCF558EF5C7637 -:109410009227501081F76B5DB38F28C0D2C9CF5A05 -:1094200042F86C33ECCAB242BDB6B1660FD2D14439 -:1094300087BF3403E0946EF47563FB3447B2A7052D -:10944000DABA2D6C22E9E721C2618A8E1EA6DCCF32 -:10945000F9A4362345DA7B13510EF93278DC156313 -:1094600042289F5E35F1756C627CBE5DE9DE0AC400 -:1094700013B3A7D3B839F52105ED7DFDB8117AF204 -:10948000DE9CF115E81BEC3C33CAF53A2167CA961D -:1094900074281F6AE8E0563064B05ECEDE9D0AFA9A -:1094A00081F0BDA5C241F59905E5CC5EBE1F51070F -:1094B000DFEFD4C815B98E18F26539C2D776BCF77C -:1094C000152E5F42447F72BE7A7C3664B869FC1BFD -:1094D000C12CA0F7E6C01837F4F7EA8844EA4FF247 -:1094E000BB9E3F1B049DE7D474281837702471BBC2 -:1094F00051CE4FD63B9A31F36E9CCF94CA5E8243D5 -:10950000438D91F026E75361F68D44FF6B83E8EFBE -:10951000D0E2F7CD61286FFFD551A2C78676C54B43 -:109520007E41FB51F3428CCF057EA6623CF6666E0F -:1095300092B0477E7994F4C8CDDD3C4ED0D0DD6545 -:109540005C698BD069C19943B7239D35745A5882A1 -:1095500082F8E376AB9E4E41BE10DDB38099F6B340 -:10956000403E06489E327F01FA2352FE7689B81F9C -:10957000B3F1F77F27E62DFB8DC8CD04A2F7823328 -:10958000130F59019E0D1EC503A612D8DBBC1EF495 -:109590001F22F9CBD808F4CB64FF7AF81D10F679B6 -:1095A0000C3CEF40B8EAF588D4AB053B66327C4A08 -:1095B000FC1905DC65BFCF6498A9DF67328CDCBF7E -:1095C0002BE3F1EB4D26AE3F36B55883C8D7AFA598 -:1095D000DD7844190F704A3787F079D8B0A21EBFE2 -:1095E0001FCEE1F368336C1CD3CCF5D7CF713E8727 -:1095F00016A7302E9FB83CDAFE1C9727F5011BF901 -:1096000089F5FEEA55B4FFE048F0A0BDCFFCAF9865 -:10961000172647E8418F5FF7B307CD6EF87E7327B3 -:10962000E78308DCB89E92740B728EF0DE952EF7FD -:1096300023FC050857F0DF5B30CE20FDF794A5BE74 -:1096400040B27B30BF6608FF7DB2F0DF4D53AD7F87 -:1096500051FFBD6EFD6FB2B1BC36EB757A4A7E012B -:109660003F318AAF7E2FF01D12CF0F04BDD4957409 -:10967000123FD47DD44C7C64ABE4F2C4763C5A0EE9 -:1096800032F6B7C22E7888E05091D479A38AFEF0E2 -:109690008F157B2B8B3FEFBB94E6FF7F2DE2A54B15 -:1096A000A57D29F62558F5A500D704010351EF3310 -:1096B00041EFE7F60022902F8DCDE6CBD9BF57EAD8 -:1096C0009785DE5610DF7502D6E7F6965FFB2F18FA -:1096D0004FDC93EA19054B3FBB77C15FFD0BB43FED -:1096E000D731C3837ADAD1EA23FAE9772678306E64 -:1096F000E850C1B2057A68E97C39E57ADC177B7AF3 -:10970000C244949B490EEE079E794E5D8FF0D9F8C6 -:10971000D35F4CC7EF75412503EDC6737B7EFC47D5 -:10972000D48BB51D4DE869B0D6A75F223BDC10DCB9 -:10973000C9DFEF4925FBF2F44FB64D47B8B776B60F -:10974000D2F7333FD949E5433FFDC5817F477BC30E -:1097500097E2C17A679EDBF69D7F473AAF4EF1E014 -:109760003AEAFD46BE6F2BE95B2FB7BA0E129F4A4D -:109770007AB919F52EC2A986CB1F49CF1F887DA5BE -:1097800015E5B63694671F6C4DAE8D154F9C20D6EF -:109790008B31179263350AC5D3DA806A30AED19621 -:1097A000C8A6E233A92864CE8571162FED9A4E76AD -:1097B0004FE0C46AACBF605F02DB4AF1370CDE8267 -:1097C000FD4FA4CED838108327C14F86DE3B2E81B3 -:1097D0007DFD0EC807D23B3AFB7F41DBEB7F403972 -:1097E0005A6D0D1F74BA23EFDB449C06EA93DE2901 -:1097F0005D173B1E3AC561137CCBF5664E77559ECF -:109800009BE484C5334A63970E3BD6BC15C410CB8A -:10981000A9EDBD11D771D398E593882E30CE87FA84 -:109820002760A3FE1B304E097C56E910F10F3B73F5 -:109830005C07E3571899C3864FC6DE36911CD94D95 -:10984000FD82FD417695FBA5C5BBD11E79C4E4CF51 -:109850009E8CFDB409BDD5C1E70DEDEDB85F0AFDE5 -:10986000D9AF9B48FDF49AD2A97D80B79FDDD1A2E4 -:1098700044E60B949A8F7A0BFB2BB1A19E09D4106E -:109880007EDC665AD719AC924DEB1EBF6C5C847FB0 -:10989000F5F11D9467B80FBCDA51B6DCE18C3C657C -:1098A000DC470FCFDDE2FB470EEF7207CE634F467A -:1098B000945E8967AF1C5A7C9EEBDF174F90BC69A2 -:1098C000443AC6F1FD1F45E9DF95928E5F38417439 -:1098D000BC721FD7BF8DFB8ACD48B7673778D98751 -:1098E0006080368A7DD64794F06A8AF3BC9060C760 -:1098F000F8DD79A16FEA1E3A7112F74747ECCB26E3 -:10990000BFFEFC0B0935D8CF618381E07978D7356C -:109910003B5B15ED3CB93F007630916A23D8A9DC5A -:109920000E5EB50DFDB3865AE641FE6FD4D14FE30E -:10993000BEA3442FD20E2ED8317F15B73F133C095A -:10994000E8BFCDE2F628037B14EBA7CD0AB69889D1 -:10995000BE8A4B91BE0E2D3EB005F578E32C66C74E -:10996000FE1F19E67D2197D6A330CC6779C4D43E7B -:10997000D308ED1FA970DB019200B70EB27BD91896 -:10998000B3D073ABC85E6ECCBACD437CA697072F1D -:10999000B490DDD5E84EA4F9DCBC4FB987DB2336A3 -:1099A000C6E7AF107DDE1CBC3E88FBCA9F08F849A5 -:1099B000389E37F5DE8EF038FF4B2044F87EF32CCE -:1099C0004EAF69B33A498EBCF6C26CD2E3922E9385 -:1099D0009FB7903E4F37DA150FE9B505162D5EDBC0 -:1099E0004D5C2FA5093D53F810C7EF2F043FFDC272 -:1099F00061104FB3A073116FB107C6A3DEFD44E041 -:109A00009FC408CA77214F1A5685889FEAF7F2FE4D -:109A10001C166FF1BD1AFA759473BD28E3FEB80FDA -:109A20005015435EBC2DE651B063C536B4976F0246 -:109A3000BCA34AC91923E428D005C22DA7D6477470 -:109A40007093E32E8F5A40FB07E427F6B79859AC82 -:109A500038CF31B12E6786AF04E3CDCECC64B2737C -:109A60009C6A992101DB152B9E5D6EDADF243BAFEA -:109A7000DF99EDD915C5EFBE1203D43BE54AE67870 -:109A80000EFED6387F1CF2A15BFAE95176DF607FCB -:109A90009BDB8D73DB03E3D10F91FB17120EC19695 -:109AA000C41AADFC7C5FC02178358FE7837D6FA33E -:109AB000F8B51DC641BF7ED7F53FE17E7D2BD57B36 -:109AC000CDC1E31915B03EB4DB9C85BE755C9F2605 -:109AD0007B62C163B543DAE5B717A35FD9586DF36D -:109AE00020BF6D7F515941F48CC141F4B7FDAB08E3 -:109AF0000F0CF080FCC0FCDC2F6D6CF60563D37B93 -:109B000015F15F23F29F42F44EF176A0F720A7777C -:109B1000AEFFA4DF8FF2B12AC67EA8942F8DE6F0A7 -:109B200068A463C90F8DD3C3A3116E439527E74D76 -:109B3000C0FFC83F0007E41FC92FC9FB399F6C6DE8 -:109B40007197E1F7AD15CCDEAAD1477A7F09E78995 -:109B50007EA794EB590E5FBA13E30086D016CCA310 -:109B60009072B871FF83A363E5B949396C3572F916 -:109B7000660D26055B35F4857B7BC913E949793B86 -:109B800049EB63C745463979BC6EA879112ED4E5F7 -:109B9000286F762505515EC93891BEDF4CA7121596 -:109BA0008F917E0BEE2F60FD3227B7434A9C9C2E8F -:109BB0006F72CA786C30CAEF711BFC27309F289EE9 -:109BC000FE92EDFE52712B398ED4A37AFCCBFD119F -:109BD0005C4F5551FC7AED07B97CD2D3E37C617FB1 -:109BE000A5E25AE17F3F17FB5983F1CBFB6135C6F4 -:109BF000A8FCB73643576DACF8D7C10D222F6ABB0E -:109C00007148F9753F17F5BF27F2BFD85263543E2C -:109C100095CDE36EC1F8E9841E77B14AE3F2385678 -:109C2000F274F629EAE194A9ED63304FC9E98BDEBD -:109C30001FC9AC498CDA7FC8F6A74795736B73A22E -:109C4000EA0F6B1E11F57DF8FAB151DF0B0213A379 -:109C5000CA856DD745D51FD53E33AA7CD5A33745D8 -:109C6000D5BF3A383FAABCB5A5B306F172CD9E5B0D -:109C7000A3DA4D30860DC5F07E5CE78AE83C311DE5 -:109C80003C67FE518D49873F7016103E27EC8B864E -:109C900047EAD46878605A1CF697CA447F897FF0F7 -:109CA0005C2E8F3595193F0BCBF60583E98159ED75 -:109CB00025DAFC8308FD04A3F2DF661A55DD3C02B9 -:109CC0007F12FDC59BA7DC5F8BBB8E3870DB27E462 -:109CD00084848B492C2B757ACD65E162BA125C586D -:109CE000D83314B8E8F7F706E2CDBAFE3626355277 -:109CF0003EF0DB58D0D8C761C147B2BC2890CAF546 -:109D0000906FC115EC681E07F65BF8FEA4FEFB45DC -:109D100021D79C300782CF10F9FA7D8187E3C8D71D -:109D2000E870EAF97AFDA78733517E5732F29BED4E -:109D3000CD2D9FA2DEBAC31862C530EFED623D8F14 -:109D400008B9F0E8063BF5F398D87F7C7C839BDE6E -:109D5000EFD830869EC10D1E7ABF6BC3547A7680D1 -:109D60003D87CF273754D273CF061FD57B6A430D6B -:109D70003DF76EF0F3790DC2172B253BC7971133D2 -:109D80005EBA3CA00E094F4CCD8BA92FE3F6A32E53 -:109D9000BD6C1EF9FAE34BE6BCA2E11B8B2BD9414B -:109DA000FB9953D814DCCFBC52FB8B1B6AE6BC3248 -:109DB0006AE87C24E9897D9931DA17237EE417F972 -:109DC000936F3B2F6E0DD8E2C32B4267B1E1546D08 -:109DD0003D9F83CEFA78B41934ED8FE9F8B8DA9F55 -:109DE0001AD36E287771FAACB1F0FDF7253AFEEE82 -:109DF00010DF3B5CDC2E7C378E9CB9CE6510FC1FDF -:109E000030D17EE020BEFBDE0DB1E0DBED7247F12C -:109E1000F112BF0EAFBA7EDE35B50FF3C4E0B32B3F -:109E2000F523D7A76FB7C9C5E5D6AEFFA3FCF9EEFA -:109E30009DC9E43F20DC9C9AF5BF7B67524DACB8CE -:109E4000CC5E17DF1705EB9C15A493A91F30A3ADBB -:109E50003886B9F93EEF483BC687641E407C7A35A8 -:109E6000521C8960A80E862BE0C36D2E84FE8D03E4 -:109E7000E3848C388EC710D16F9853C334E73CD439 -:109E8000C1F400ED0366CADF09E750DEE357A427FB -:109E9000A63E3EEA72FB7483DA7F4539B3FD6B96CA -:109EA0003392CFD9970F8F8AA5276B50CE5C07646A -:109EB000E82AFE6EA0E8CAFD7E55F8D5A861DAB79B -:109EC0001E32FCF6398614975A6F4D198FC6D5C5C8 -:109ED00004FE0CCC64FC3CD6FB0941B4F343629E07 -:109EE000E0F84FE07E75F3147CF664F90EB9A0FD3E -:109EF0000A33F713F35CDE975D502F51EC039B336D -:109F0000CD5BF0C9EC7C1DE3311F14BADA6270E757 -:109F1000E33A3E523C57A39F6237043DF84C61A19F -:109F2000713CEF2EE847FF2CE39A4437FAB789A338 -:109F300019EBA578B82701E366E6A4F05B23D19F6F -:109F40007DD148F1A1F198CF06E5F17F9F1B0C90E0 -:109F50003FE726F99021E0B615ED70683F8FF9DFF5 -:109F6000C5F99EB65B030698D7C3951313301F2A15 -:109F7000B4470D98F1BC42EFB9BFBB19D63DA1570C -:109F8000A538F30436E9F59128577A4DB4DF5B67BD -:109F9000640F21DFC483E7D96FC6CEEF2ACAE4720B -:109FA0004FE66DE9BF2789EF67E3E411FF87D00B28 -:109FB000323FC624F3639CDECBE6C79874F93126A2 -:109FC000A38FE13EB069203F6629A3FC18E8479BB8 -:109FD0001F737666EC79A8997C1EA62F92E2F49BFB -:109FE00042EFCF8EB8FC3A4D5F2444E55947DADBA7 -:109FF000E87DBCFC9C3C09A738F9495903F3CB66C2 -:10A00000810C6D3B4EBF9171F2E8BB4997E713F9A4 -:10A01000CEF37B36A5713A399865772C87AE97B326 -:10A02000B009E9F40E9BC384F1231FF374D1B91D69 -:10A03000A3A93F2CF96E04D6337E8076B601242D79 -:10A04000DAD977AC377D10D6C8A92A6F7499617DAB -:10A050008DDC5D9FC568BE8963C7505EDF05E64E37 -:10A06000B55F466E2EB5AA56A366BDC7E3D80D7E72 -:10A07000019FE3D9B1E13727D31095A734B87D4AC2 -:10A08000D479B47BED979797085F7F86B67F3D1EA6 -:10A090001CF4FD4A7076B672FEEE2F5378FEFE5F1A -:10A0A0001CDE69229F8D9F0B30E9F2D0D767B9394A -:10A0B0005D0DCC9BE7A1BF6CF7ADC8A476EED1DAFD -:10A0C0007300DD466FD244781E1772470F973D022A -:10A0D000CEFA75778B7CFA4495357769E0AF5FEF00 -:10A0E000E3028FB2FE2613DFBF823F9F15F0B28CD2 -:10A0F0007139DB9A3942E485A719511E2EE55DB00E -:10A1000065F657693F49C27910FC04DCF570F431FB -:10A11000F7ED98B77D25782E3F9A6846B97FBBB595 -:10A12000FF30FAA6E15EC33B23E179C236F2640751 -:10A13000C37DB731CF1F62180FF1F0FC09368BECED -:10A140001C2590AB5EBA66E876CE9614FF18E48BB9 -:10A150008F44BEB5D4435B72CE8CC6BCF9D4F4B286 -:10A160009A2C27C5DBBD19483FBFB670FA79147A1F -:10A170008272D381AB77A27E69C9F22FCA9A1CC9B9 -:10A18000DF63DEFED1987FF055E1037F26A49F2B8D -:10A19000C1675B26E37C98129B3E8EC4A10F3D5F96 -:10A1A000D0B9B292AF8F2F243CE57E859CDFA22CE4 -:10A1B0004E7FF229E1A6CF1B5A946510F5B8DC68F2 -:10A1C000C9F2119CFB867D7A3201E67E5C97E73509 -:10A1D00020BF86B87E09EFAF4BFE1E4F8C3DBFFE01 -:10A1E0004CBEAEFFA9F92D91F31B1F7B7EA6ACA13F -:10A1F000CDCFC7FADF4FFB1AF417E07909E2996D6A -:10A20000EA27B9783C3DF63C470E799E7ED3D7A12C -:10A2100067257DB3C0F25ADAA7CF4A8CB94FBF0881 -:10A22000FC26F47BF4FBF5725F1EE407ADB7DADAC7 -:10A230007F7B06E27D9658B78B85D2701FF38085B1 -:10A24000E2FEFAF55F23D60FF02A4639C5E6F6534B -:10A25000FCE2F8E8D872A1388BF3C540FD363E4EDB -:10A26000BC7305D70AFEBCD2B90256E2A7B85F9903 -:10A27000D51652010FF7087C9873D77AD02E2CCBC5 -:10A280007AE318AE13E07F6E009E9A3CBE331B8EBD -:10A29000D8479AE2CBED3AF5D9D2E618EB99E7F434 -:10A2A000CFC5750CD4DBF3BA7DA4065FE358D8C0E4 -:10A2B000CF45F71BA2FCE14CF695FC61AF95F34B43 -:10A2C0006ABA8FF401EA07D43B5BF65F5B8CC84443 -:10A2D000FB02F378FA9313498EB6E65C37C6AD817C -:10A2E000676396B45BD538F6E29F97F71FB19794F2 -:10A2F00028BB35D2BF91DE4BFC94D9FE5F4C7CCCA1 -:10A30000737AEF453A1C9DEE5D874F3DFC020F4C82 -:10A310004B23FF18E13723D2DF00FEE3E0F9C74EFD -:10A32000EF77B0BFDBC4F91945E6EF0DC4298CF611 -:10A3300093D608BC878A97EFE13FC03FDD91E5DD0A -:10A340008A78315B043F321B9D0B97F60AD3D935CF -:10A350006C2ACF275D96F5C61F30CEB32585B3ECAA -:10A3600096EF24505EDD1D8ADD8CEB06FBE3BD1FFE -:10A37000417D3F0BBDF76DDAC7927646927A296927 -:10A38000E8F3947EF295F2A80FA11D06F39969B047 -:10A39000D1BEE621209B6C901B33CDFC59361BA807 -:10A3A0000AFA9BA9E6F584615E9FB373E93740EB37 -:10A3B00044114F5C77747202D2E54CA3E98C566E5F -:10A3C000E9E31C5D59D1718ECFD9DCEFD3DEEF18F4 -:10A3D000EEEF3F3C7766A636CE3210E710EB581012 -:10A3E00058CEE5A94ECE497966B0F2FB439897B9AD -:10A3F000ED2E8A1771B883736D84F20DB28CCE097D -:10A4000094A7092429D81ED67D8378B215FE2C94F2 -:10A410003398BE83E381D79785CFD66B3D6E7CCED4 -:10A42000507C463E8F20CF3764CD7958DF600DAB2E -:10A43000FC5C1ECCC085EDE578BC9C2CCA9BAA2F89 -:10A44000DC7EA77B70FC82D992C9DE358B799DB604 -:10A45000DB0206786FB1854E535EAA78EAE31C17DB -:10A460000D8100E6657F4B0DD27C935828D48B710B -:10A47000092B80C040F1831348A7E0D534E23C1398 -:10A48000EC1742DF6698DFE855B09CA1D3474EDB5E -:10A490003ACA7776FA8C3A3DE457906F326BF4EF14 -:10A4A000A3F593951DA773404AC8977529E3CA7110 -:10A4B0001A7D7CC63493A3B87F0DB77BDF49E4EDEA -:10A4C000245D28D95CFF34A69B19E5B9B8AC56B415 -:10A4D000DBCF279FC2A396A837DA506F584D5E8214 -:10A4E00087D41F0DDD7733C44FE3BE2A86F4FA4FBD -:10A4F0000ADFF70C2C53283F41DED75053C4DE84CB -:10A50000966C59F6086AB7F0887F593D94ABDF60C6 -:10A51000E34250AF7886AF02EF65691DC73C1BA1CF -:10A52000DC9AE07FE697B89EA32AF5D324CEC33207 -:10A5300066AFDB0BFDEFBC7598672B2EA9BC7F0BBC -:10A54000E6FFF43FC8EC982F32884EBF84F501FE39 -:10A550007F82659877D32AFF13F741FDEC37988700 -:10A56000EA88EFE88B20DE14410FF87E06BC6F12FC -:10A570007453D8A3F07D7B8785F226D8B14CE2973F -:10A5800085563E4E534FD9BCC930AFC2DE4944C692 -:10A5900023A13EE635616601CFAB63E427EBEB8F89 -:10A5A000C4FA6E8A52F17C9A1C33DD7BC4849C9B76 -:10A5B000A2E3B7EB23F44FDF8B45B949E8A3283E6C -:10A5C000C17EC02FF796F26D7C6AE7E0FCE061F295 -:10A5D0008FF3ED752CF287FD9647C621F93B4B7C36 -:10A5E0003BBC640EE5734F31860E225F5F2F9EC524 -:10A5F000E2897C6D05382E36361F76C27AD2D63384 -:10A600004F0B8EB2D4DD8AFD95309F8A702EB53FF8 -:10A61000D88AF3BB76E9D10CA4AFEDD985447FD3BA -:10A62000AC9EC2042091D6A91E8F1D5ED52C550864 -:10A630002E0B6BAC41CC5B5B38704F8FBF6011F061 -:10A64000CD62BF22CECFFB0B966AE2B0329F6F91F4 -:10A6500005FCE718727A7B36B78764FB2671DE4407 -:10A660007E6FCFB6D1F76F66DFB82C9BF22A789E4B -:10A6700033F0BD3F7B72448EC0B89487B280794D71 -:10A68000B8AE05826F25DF2FF4DE4B76EB425FB468 -:10A69000FDF94F0AC777608942F6E0E29ACBDBA763 -:10A6A0004DD9729F37CF7E3229F25ED29594DBF37B -:10A6B000518FA3BCAD04BDADB18F977EEBCB346A97 -:10A6C00097F964C3A5E191F32D4DBAF32D8DE27C8A -:10A6D0004BD3BE16930BE95D9C6F69EA39B1459B7C -:10A6E000D727E134F87C4B3FE5332E32070FE2B930 -:10A6F0009F456B618D50FF65711EE2153C0F313136 -:10A700004247C9B7268478BE9C97F2F6F2EC491E00 -:10A71000CC3369334CA43CA1B694648F362F676B5D -:10A720004B7305D693F941F23CCBA238FBC08F673F -:10A73000733BF91185E76905965809DE4E951DD3DF -:10A740009ECF7716FA283F6E59B69BF0FE88882375 -:10A75000603EE9247806C11CE3F8E2EDF5F201FA67 -:10A76000DB84FD95177A282FA63C95E79739337C33 -:10A77000C5F71445FAADEEE1F978D5BE4F5FE5793E -:10A78000B55525084FBD3C97F4A597EB407F9D48F4 -:10A790008F170D5CEF44E4BB6FC99DD05FDF9B66F4 -:10A7A000CA9B63F77B1513B47BEE75BB07CFD16DE6 -:10A7B0002AF35555D077239DF373D5B09005BE97F6 -:10A7C000BC61DE85F97AB5ACDD8CFDD5EAF4D65AEC -:10A7D000DB2B66E4CFB51DA6083D32CC33F414A2C2 -:10A7E000A0ABDF3B28EE41F247CA253D1DB391D116 -:10A7F000F2A758CA5B900B5C5F2DE57A8E3DA9608D -:10A80000FCA72FF9942AFC67927793A590D2C9F9F7 -:10A81000C93DAF91BD321DE403FA670A96C7537D67 -:10A820002A83FC1C8379A3D7B344A2AF41768298D4 -:10A8300057C9C0BCB93D24E562D9546E6A4ABCC050 -:10A840003844CF729F6E32DEBF03CFEBC5B8DF3224 -:10A85000788B420AE289050D856847F8C9DED1DBAD -:10A860003FA5D6E6242BAC6F2A6B27B938E5F02B31 -:10A87000242701CF9FA09CF9359378F65851CE54E8 -:10A8800060C29F8ACF683CCDB66D37229C6667E96F -:10A89000F11130225CE7B807E189CE0778E3E0C91F -:10A8A0002BE5088B962305EC4B7E1EF9C157EF4331 -:10A8B000BFF74A76C821A7DF9C43F233DA1E899797 -:10A8C0004F979A63137EEAD0F2E9FA4CDC4FB88EC8 -:10A8D0008557EF5506D3C5F9C3EBD52C0DFD48BA06 -:10A8E000DC2FF2EB959744BE6E4932E9B9885EE4FD -:10A8F000F82F15A5EB90AE34F8BF615F4248057A9A -:10A900002B16EDAF437A9818D18B2183CD6D8671CC -:10A91000B7289E363506DE5DE96ED27F930C5E95D4 -:10A92000EC29E6C9403C03DE8B105E53AD9DAD467D -:10A9300098E749B3E747E8AF943137E1BD4CA75FEB -:10A94000CA6DD546E4CF72AB1EBF5EC27B857DD09B -:10A950007BC39F82F7E18877A93F86607F02DE2B69 -:10A960007262EC13C6C3FB2D7F22DEF5F8967CDF06 -:10A9700095602FB7615CB796E7114F7A73642B9699 -:10A980005D0D0574BEA52BCDF3327D6FE6DF4B7AEE -:10A99000BD2ADE9B58B80EBE43B9ABC0578EE5A6A4 -:10A9A000F50AC9CBC96FFB5BB13CF27EFEBD786393 -:10A9B000F3CB78FF585380B7DF7F7A0BDD2311DCB0 -:10A9C00022DA97B59763B9A98DB7FF38D91A40FF36 -:10A9D000BAF458B015DF5FFD109F87B4EB66083AF4 -:10A9E000EB529E7D99DAB5F37677BD6A4DE4C96E78 -:10A9F000DC4E9B2ED639E371BE4EC7873755BA81E0 -:10AA00000EEFEC0F98900E4E1AEA4B495EC6F1B766 -:10AA1000CA94F63C7CCE06B9C008DF409F23789EDE -:10AA2000E92E18626B0EB78B647E26E6895769F0B3 -:10AA3000B53587FB09B29E2B9DF17CE2C792C96EAA -:10AA400095F9A3A11F3205E300B846D2AF71F249D0 -:10AA500067173693BE9C3D5CE691868D2B60DCE2E9 -:10AA60004BFF7A632CFF7A9B18F794C87B97EF6BA8 -:10AA7000830506F43FBA9078E87EB5796FA25DD27F -:10AA800085FBC19AFB41BA0A78F9C78FDDFCB76D27 -:10AA9000E0ACDE6568360650E8E72B74DFC92DBDF3 -:10AAA0002C949A3278FEB38D2CC4F31DF8FC57B762 -:10AAB0009A776DD5D8E90BA5D898368AF448B5C0F1 -:10AAC0009394170B05BE80BFF7207F2FB236935D9E -:10AAD000B844C8F7352C48718A353AFEAEB37DF6D6 -:10AAE000BEC180F1B0683E6E80E970BDD0BFE35D4D -:10AAF000807FEDA3C976D4F30D9DD1F56A1F7DF358 -:10AB000018B7AFA2F9BC56F279309ACFF1A649E254 -:10AB1000F31F8EA5FD17799E2FC1DAFF7E8045D6E3 -:10AB20003BA0DF75FC9780E7FBC6A0DF62E079857C -:10AB3000A22CC7BDD0CEF57000F4B0F07348D45E3F -:10AB4000383E2788F4502CF857F271B1D0E783F4DF -:10AB500075A5DE8FD94EFC31499424DCA57E867E16 -:10AB6000483FCBF382A097DFF4927F0FFE27CE738E -:10AB70006C34BF6C55403E1744FC15C0DB3F23DEF0 -:10AB8000401E5B799CA29DA13C8B6BF7DBD6C5B4C4 -:10AB9000FBC18FA07D80C1F67E28CA8ED7E32B9E95 -:10ABA0005D3F80AF04B09792D08F67242FF7E17399 -:10ABB00008F91C20A7FF3D967E361FE2F5FA77269E -:10ABC00050BC40C6C725BFF5E572BBFA57595E9623 -:10ABD0008BFB57A2FFE377CFA67DEACF9897F6A924 -:10ABE00031CF2837469E04EE536FD2C4498FA7C594 -:10ABF0008E5B27E772BFE71BB97C5D794E6F4A2EEB -:10AC00003C4F99795CFC54A278A6F07D85EC81FAE2 -:10AC10005C4E4C10E55322FFFA547A743C5DD62BFF -:10AC200016F53EDA60B56ED2C815F70F2DCDA8AF78 -:10AC30009C85225F7D1DA7D7BE17D2766AEF699BE0 -:10AC4000965BF60D9C97B3D06BCEC638CB0B5C2FC2 -:10AC5000341AC366CC2BB9C1E1BF0AE1D4E866DE81 -:10AC600067B11F77D8BC00E0DC27F6E7FB4CDCDFE0 -:10AC7000E84BE04F39AF69B955DFC0767D7787493A -:10AC80003E0C94ABC2C4FFD3727D346EDF42F95DDB -:10AC900094FF969799F00FCB045F509C37465C77F2 -:10ACA000701C37FADE992673EC7D6596971C159F0C -:10ACB0005DD6C3E386B75BD9965CF87E474F26F92D -:10ACC0000FB52981D1768AE3FD7971D7BE61BDB414 -:10ACD000AEAD65FDF98F95D03E2EC57D1A7A5E2307 -:10ACE00039D720F9A43B9A4F96E40E6DFF431F1706 -:10ACF0001F02FFACC88DC13FCFA37E3245E07F8FDE -:10AD0000C877AA50EBCB312E746115A373AFF7BC93 -:10AD1000AE123DDDF38C42F74048FBAC41C037DE5C -:10AD20007AF0DC805B233FF0DC805BE39FE1B901DC -:10AD30006D19CF0D68EBE3B901ED773C37A0FD8EBF -:10AD4000E706B4E562B6B215E36C4D6DCC1E74F344 -:10AD50007304DAF6788E405BC67304DAF6788E40B8 -:10AD60005BBEC0381C2F3CAE529C1ECF1368DBDF8D -:10AD7000F5FAA42CA49BEE049E3FC602DEDE2280E0 -:10AD8000CB2A01173C67A0EDEF6CCA8D4718D0DDC8 -:10AD9000AADED573F13961DFDAA8FEEAD47AA243DC -:10ADA000D6CEE56E33FC47F2532D52711E9FEF5302 -:10ADB000584601DE1BAED39F3DDBB6A0E859138C8D -:10ADC0007E5FC734F1DA82C171F98EDC64C7499EB7 -:10ADD0006B9CA38DD344E8C0E609E1FADF563DB190 -:10ADE000E8A0985D954AF199232AC61ED8C7ACF908 -:10ADF00091698A267EAF8387252B9A1E12DCD1F4B7 -:10AE00009034269A1E923DD1F4903A359A1ED2BCC7 -:10AE1000632F0BDF8CCA68FAD0C3772AFC87F09DBA -:10AE2000883742625C09D68971DEBF147C7B75F07D -:10AE3000FD9C4D2BB7B9E973B5B534629F941C697D -:10AE4000A64D5A7DDC53C251DA09327E3999713FE1 -:10AE5000DD8AE72C0BD10EE0FE1BEA7F94AB27CDF9 -:10AE6000DC6F430A42397927F3933CBA53A7FFEFCB -:10AE7000B26D37A3FE1FB45EB0B8F0BE40FD7AD10C -:10AE80008E629A78925EFF2B3D4A28793C2EB74716 -:10AE9000CA65FF253276BCCA50E4C5719BF7739C26 -:10AEA0003F3A7ED6D2A8786F4C7B4ECE43C2458EB9 -:10AEB0006F61CD6A16D2F318BDFD15ED2F4BFF9AC9 -:10AEC0003AD5C4A3A57F2CFD133D9CD5E10564773D -:10AED0004DB24BBFB8F7367C2FFD61BD1F7AA57D03 -:10AEE000A9050125FCA382883D7983782E10F122E3 -:10AEF00058D687BF87C6D314F7301C6FFEFEAB9CB5 -:10AF0000482F5B9466A69BDFB117A11FD5D09FC1C8 -:10AF1000E32FFEA8FDAAD79430CD7B11F36EC66750 -:10AF2000A388A73576BF46FBA88DDD3C5EC0F645FD -:10AF3000E3456FEFAF659DE60265B0BD5FCF7AA9CF -:10AF40003FBD7D3F884EAEA0C777E4C97B3B78BE4E -:10AF5000001372A956C02B9E5F6044005F1BB9B7F7 -:10AF600013F8A12C6F72247FD6950E7E8C8A7918E7 -:10AF70006E73AC3C298697AA804DBAD2564D726248 -:10AF800065DBA0B88499F8A9FDF2EB9376C05FE584 -:10AF90003182FB883C37DF874A9C7BC48B9F4B7A8E -:10AFA000F3B5E73E9ACCFCBC216B8E3E97BF3ACFFF -:10AFB00020CF4DA94359FF60B8FE69F9F832FF0070 -:10AFC000E0B7460B3FB98F20D7F3C9E4DE27317EC7 -:10AFD000A826CFB2A25F9B9AEE6FCA73E2BD0CE1C6 -:10AFE000930ACA339B9BF243CEEF3BFD0EFAEF72FE -:10AFF0007D8C851FC17B6D6BF7A9E40FD6EE7B9925 -:10B00000ECA2F8FE5EFBC0FD09627FE37E1C473FB9 -:10B010002F99CF5CA116A5863576FABC3C1E0F1879 -:10B0200035DCB711DB95FC2E2F05E76B1AD149F7FC -:10B0300061F5DFC7ED6087CA6621FC40EF71BD6F27 -:10B0400033D2BE832329A0A6A01DB79CF1FBE73C09 -:10B05000CD1E2415755811C5695DF7A93EB4BFDF33 -:10B060005BB7320DCF29BB9257A515C2738685DF1A -:10B0700047E3520C3E7EDE74451ADEFFB1CCC2F7C8 -:10B08000E50BBE99142A047E7BC9CCEF197524F90F -:10B09000E9DE82FE3495E67366032C6D14EE7B7C4C -:10B0A0003609EF1BC8F9D23611E7932DEEB3A8CFBE -:10B0B000E3E7B7CF3E737112FAABEA251B9D6B979E -:10B0C000F4E7288CEDAFCC17F06874F27CF7F3C28C -:10B0D0007E3C2EF65B65FEFB3AB10F787CF4C0BD7A -:10B0E000604ECC0B694CF0A62EC678C451156FCCBF -:10B0F000609FD9BDA9696437F33CF675C27E382FCD -:10B10000F23DD7CD999989FE45BC3CE997F2B8DD6F -:10B11000FB75DD5329F34EE3C221CDC88C13E8BE85 -:10B1200025DFE5EABDF84735263C4F8AEFF1F2E529 -:10B13000DFCBE37E9BCC876FC47C7878B5EE85B29D -:10B140004C76993CE946BC875C935F837E1AAEAF30 -:10B1500011EF21A7FB49CFD1FD1CD80FDE1776A533 -:10B16000FB22E70B3837621E7986F6BD9BBF1FE8CE -:10B17000DF41DF9F12707BEA88A172578C79260E1F -:10B18000E3EB1EEB34FA705FF29A10BFEF335E3DD3 -:10B19000797E3BDEBCBA67866FC779637E66ACF1A9 -:10B1A000BE147094F3ED4E0FAFF6F1FDBCD155C94E -:10B1B0009AB2BD3F7FBE46BE4E11F8E9BE299C4FF4 -:10B1C000F700CCE1FE6B3C3C971A9B1584C31769D2 -:10B1D000FE5B50FEC97B8AF11E639EE711B82CBE50 -:10B1E000237056A3CE1D0C86B399BECBFEA4DC39CA -:10B1F000FDA84A72E7F45B821F99D7A694A2BEE22B -:10B200007C759AF1B8EEE976FEBB1F2BFC607B8261 -:10B21000FC58DE5137177FB763F5EE495B50FCE30E -:10B22000FBFB41FE2CCF626C3A3C576C8ADE1FFB65 -:10B230009C3D447A6ED5437A7DE633A39C5DBD3D4B -:10B24000BA7E2D7BE853B40F6A7576AF4BE85DBDCF -:10B25000FDEB1926F27E4A59E95739DFF428F34EFF -:10B260001946FA9FEFB74D16FBE9FAFA4FB8399C29 -:10B27000EFD9FDAF66FC29A078FD9E01793112FA65 -:10B280003DB7C14ECF6F0CF3CEC4FE970DF3570CF4 -:10B29000C338C4510EE70BF51756535CBA86DB0171 -:10B2A00016BC5C05FE69B9CD4A7EF40378BF18C0B0 -:10B2B000D962E1F685B4AB54F55E3505BE5FFB2F70 -:10B2C000ABD2707D8EA76757A2FFE17C3AC98BF89D -:10B2D000D85AE62D46F9BDB5CA46FBC43B0DFCFE67 -:10B2E00041AB85EFCF059FBAF610868347766E9BFC -:10B2F000897E86BDE76008E3126D06BEFFDA369DE3 -:10B3000089FBABF9784D3D555D38AFFC6A90F7D0BD -:10B31000DFD6026FB15DD33F13F652A3C045DFAF56 -:10B32000AFFA3EDE77F5A32364AEC23A4750FC6B1A -:10B330002CE37423F34BE8373134F1A273A07F98E8 -:10B34000E6DCF3D84E25644AA17BF5288E5DBF313B -:10B35000E4BA0DF5E7CFF87EAD9C9FE3A5EC991814 -:10B36000EF97FAF436CC6FC338B0B07B9730F9C79B -:10B37000F70B6A045D2F11F6EE6D491CCE2B9887F2 -:10B38000CE5DDD6A6529185FBEADBC7332DD7B5DC5 -:10B39000674A437B45C6BDE3E13D5E7CA6F1C964D7 -:10B3A0007E4F8ED23F1A3B398331909248BEBDBE4C -:10B3B0009F8787097E1E2DECB491CC8BFB2C8D07CB -:10B3C000AEA27C7C4B22DF5703F96645BC1E467D4E -:10B3D0000EEB5EF3624288EF1B07C57D382C40FB05 -:10B3E000310732695FC151E8A57DF7F3A6703EC908 -:10B3F00003905F0AE8CEBDC37A6FC1DF6169CC01FB -:10B400003B0ACAEF3EF1DE2D46A0C7C611E1D57852 -:10B410004FB8B2E3DF78796CF82496937628F3A8D6 -:10B420003C31BC5A85F2E81DA9F3A83D3A5040587A -:10B430009376B8E6E139E233227EC93C61BA1FA8AF -:10B4400071FF55066D7C70783EB737CF24F07A6770 -:10B450000AD81DF311DE63C2A3B5BF97A0E61B98FF -:10B46000F65E65B94ED98E65C5EEFF45A107D68853 -:10B470007B7D6624B1B604BE5F1140FBEA959EABAE -:10B48000082EC161E9025E61BAAF51F6A33FD72F22 -:10B49000C75D8B7A1BE5BA29FA1CD191615C5FC04C -:10B4A000389B689C226F31DEC7D3383FAF18F10656 -:10B4B000F8320A7C19B91FB893CF0FFA4D1B4F7A97 -:10B4C0006412E689BDF225D42F88CC5B4F1F6F0B29 -:10B4D000FA58D3CAF799FAD30A898E662471FB8F7A -:10B4E0009500FC408E8D16F01D9E9FC6E13780872B -:10B4F0004C85FA6F15F0CBE3F5BFEA7A4F7E4DEB42 -:10B50000D5E0C98B79C7AFECBB9AF024D7C3D8B6C6 -:10B51000A87ECEB4E8DA4DE579298DE985D4EE012F -:10B5200071BFBEBCAF18DB1540BB19E5FD93901F82 -:10B53000E47D6D2C309D9CF57A212D06EE5FEBE4C9 -:10B54000F9296CA497DF43347F6E89589F5DACCF97 -:10B55000AEBD8F6E800FDFEECFAFD6DC472DDF0F95 -:10B56000C07DA0BFA289A2BF287E8ED51FF2453C18 -:10B570007C64E573BAF88BE143CE5307CF0138EB17 -:10B58000E627E1897C4CED8AA2F949CE3369008F28 -:10B590003A7E2EF813C713F9FD0D7F25F221DDD178 -:10B5A000F4DCD05D60C0FD53D9AEADB3C587725E2B -:10B5B000C6BB2DDD5501D47F4D3D6594B7D9F0ABA9 -:10B5C000679E0F40FBB5BFF8410A26D39E36B6BB37 -:10B5D000D0CEADDFBD39C58BFB25C6400ACACFD35F -:10B5E00041B532D639C0C67C45FAD16447350A7DAB -:10B5F00073E6A9EFDE82F0F8B7DD263BEAD1A63D7F -:10B60000969085E2206BC88E82F2095E7EE053F44C -:10B610004B9BF645DB496B7FFA03979BE829906BC0 -:10B62000C0332E2C94CBE0D9D861F2841C3C9E0808 -:10B63000C3B026D6BF05E7A76F8FF3F802F0DED4BC -:10B64000A92EC7F3BCFAEF2049C80E6BEAFE2ED92B -:10B650005D4DDA3803E0A1368EDD75477E74BEB5E8 -:10B66000840B0B3AC9AE69FDD90FC79FB0E13D9A73 -:10B67000BF49518AB4FA7223C1E942E7CA1FEF7782 -:10B68000C7D7ABE7D12EB068DB71BCBAF729B427B6 -:10B69000C17AF8B3DE144A413FBF7EA7C9039A9727 -:10B6A000D53FF39327713F84BD6BA17B0FEA9E3991 -:10B6B000FCCE7550AEEB3239E6F2E9DB1457043FAD -:10B6C0004D6E6E9F487CAC7DEE30DD2F88EFD1AEA5 -:10B6D0009578A9EB3A6866E306C3AFBCF3A0F8BD62 -:10B6E000051D7E3A4FDC48F778FEECA219E9FAF422 -:10B6F000018565160C6E5FBBF3700AD21FC209FD8F -:10B700004B89A701BC0DC257E896FD25548FE21A5C -:10B71000F1F0E6CD677C9FE757CFFC1C7FFFAFF6CB -:10B720009F2C1E5C7FEDCFEF4DC1757C6C6CE6F4F9 -:10B73000FDC4669717C6AD35055C767AF2F7B53B62 -:10B74000EE23BABBEBE87D2EFE3B1ADE6CC3545AE7 -:10B750006736AEEFCEC717D2FA56333FD15DED1341 -:10B760003C3EF1B9F81D063D3E4F0AFEF87897853C -:10B770002E2DFA1813D1318FF02D55E4F9DECDB40A -:10B78000F75780C54DE5CF457CE0C5017B805999D1 -:10B79000262EDBD4F1402FE2E7CC306F26EEAB0152 -:10B7A0001C02025E0ADEABAB1EADC8E4F8616EA3FC -:10B7B0008C2B83FD5D8EEFB17EAFC99B303EAA9D81 -:10B7C000D8AFE7E3CBF804CC3B11F7FD3E76C53E9E -:10B7D000B7E5182EF99FF5322D7DC5E3F78E078961 -:10B7E000AE3E7B9BF34D63B0AA92BEF79A4278A41B -:10B7F000B83178B05A21796089BA6F69802E3A4C95 -:10B80000829FA3BFC33C8D8A16BE07785EEDEAED2A -:10B8100096A87B102274638EBC2F88F0A7F4A3EE49 -:10B8200012FCAF5FAF5E1E9CD0C903F6B87348F739 -:10B83000C9D49B824F3E86FC0BFC8A7E66FD332674 -:10B84000F2F3CFEE7DF99D5B81CECF764ABE8D9629 -:10B85000AB7ABEAD7D76328BC5B7676D1E16936F22 -:10B86000E17D4CBEB545F669DCECEB93AB77C59159 -:10B87000AB89C3C57ECEC03996A254CC753FF35474 -:10B88000DD708A0BE8E02AFD59BDBCECC877C7948F -:10B89000970CAF9ED2C051C24FD2E3DAA71B689C6F -:10B8A00001BA957429E976802E07E55746C151FF04 -:10B8B000BD57C8A38173431BC14F413BF6D72AFD37 -:10B8C000FE491FCC650BC0BD6F6F01ED836E167610 -:10B8D0007E9FBD3F05E37A9B855FD18FF1C4D4C8BD -:10B8E000FBFE049137E0EB4F49D3D845277AD414B7 -:10B8F000B4E3C2C1D8BF232BEFA70CC7F99D597978 -:10B900007EA942B5E5AFC7386D3BDF9F5CD5B23845 -:10B9100005E3197D3D85F43B4277BE0EFE2ECCB784 -:10B920004FC635035E637669E45ED3532C40FB95C6 -:10B930002B7BEA68BF501F07596DAB4EC5FD407D9C -:10B940001CE42ECC83C23CE4C7A3DFAFC5F808E2F9 -:10B9500049474F7EA4A7ECC1F4543D5CF065312B00 -:10B960008EDA7F1572AD422DFA3EDA277DE0B7639D -:10B970003C88A945BF457DFA39FAF1C8000127D1B5 -:10B98000699DFF94CCB322BA9674A7F7DFF5CF7305 -:10B99000BF7CAF14CF03D53FFFFBF13F82E7B9E790 -:10B9A000DF1DFD22967FF58FF9BF6783EB971FF8A8 -:10B9B00003F92B7D072C349FBE03AFE57F1BCBFB28 -:10B9C0002D1E9C6FDF460BFF1DE803C974DF74DF7B -:10B9D000301E676BFDF5C5F161D2539B7812F27092 -:10B9E0007E4FEC859EFF781FEF55BDD0637163DC01 -:10B9F000A1E94012F9E14DFB13E87EF8BE5F5F2C30 -:10BA0000D5C68BFEDCF5348AF3167DC9AC06F35B34 -:10BA1000FAD2B8BFD6F4E2B53F692940BBF420DDC5 -:10BA2000575CFED27F8E47F9D3F72CB72BC03FDF90 -:10BA3000819B88DF1DFEDCF74DD978DE88915F7D24 -:10BA400095FB33F2AB07C385C3A10FE080EB02B8CF -:10BA5000D03DDDF1E0B1EB7F2D3C3E257FA1BE67FF -:10BA60000AF151042E0AFFDD919EE4A055A1F5F3E1 -:10BA7000F7072E8E473BE96C670BE9FD2BADFBE02A -:10BA8000FFB9752BA1A1AC3BFCBF76DD9CFE570F27 -:10BA9000E7FA49CF0783E9FC57DFA4F2CF933D349F -:10BAA000DF21F23F6EBFA27CFFEF5EFF7F01F65207 -:10BAB0009D150080000000001F8B080000000000A2 -:10BAC000000BD53C0B7454D5B5FBCEBDF3493249C0 -:10BAD000261F2008C19B2F51F2194802E1A7938429 -:10BAE0005050C409488B157000955F4822D89A566B -:10BAF000DFCBC4440CD4D547D5565BD135A0509E7E -:10BB0000CF3E530C96564207540AADD5D142054D4F -:10BB1000E948AD480D6404157CA5E5EDBDCFBD99A0 -:10BB2000B9378988ABAEF55EB2C8F1DCF3DB67FFED -:10BB3000F73EE7586F035F8713A03711E6EF28C47D -:10BB400032053C900ED0F0E2C4A75AB20056777E80 -:10BB5000B408CA00EA764F0019EBD5BFFE477198CA -:10BB6000FAEF903CE27B62C021E1F73D9F89EF7BD9 -:10BB7000CE1503961FEE90827212D6EFB32F0FD020 -:10BB8000BC9930BF03CBD6AE73C5612C01DA00CAB5 -:10BB900001AE546D5C9ED9FDF763523A95761570EF -:10BBA0009D863D0940F337FC2A2E00387F6FD7B9B8 -:10BBB000F13E9CF722FD5C0BD0D38C538C8ED6CDFE -:10BBC00065CFCE3F8DBF07BBD4BDF04EF1E358F635 -:10BBD000BC7034FF45AAFFE2AD51EF60597FC97DCB -:10BBE000EFB52DC5F63BAE5419BEE8BEF7DAA08816 -:10BBF000F67B7011F5EFDD93E8B267117CFF180555 -:10BC000031FBBFD4BEAFF97FBA6F003FC01000ABAD -:10BC1000EC7564237C0F4230A462793FC08C0E67C0 -:10BC20007F785651E3101A0721180A2083F891D320 -:10BC300057CE82242A377C2417D3F83933B2100E1A -:10BC4000BF6A716F55A98785F1D03ED21DD880702B -:10BC500081E25DBE19EBD62BEBDC1B78863B01C67F -:10BC6000037CCBA1CD3774D60C09E76B6D41B8705E -:10BC70009ED62116572BCEA3A896A0BD98CB77A908 -:10BC80007C60E87507685DC56983A036F622FE739F -:10BC900002D60BB43AAE179F1B53C77F71B0CFA526 -:10BCA000E0FA716E0502B8253BC48CC7FE33551708 -:10BCB000EF331E027E97F3F2F1F4F825F064C68F9D -:10BCC0008EB77E780270D07885FE8BF69FBE2144B9 -:10BCD00072A880E20F8BFD481725C2A73BC381F3F2 -:10BCE0005993EF706F90F8BBAA8CD7C659E8CF1A5A -:10BCF000037E117F9EB8E2289E63E6E3FD9BF17C04 -:10BD0000B9F8D5E912077398CE71239DEE00C27F72 -:10BD1000BF2AF07E3FE25D92A2F8D5F166A6433DD0 -:10BD2000F14E7914FFD1728AEBFD314C48B888C8C6 -:10BD3000F557414123CE53234F09FB71FE331509BB -:10BD40006E3BC98B0441691C969543AB00F7D193B8 -:10BD50006953A89C1AC13DC5C07BED79072831FB0A -:10BD6000AB841443BD27339FC7573B861BC6F50CD6 -:10BD7000AF70D0F71A5796A1FFEB7149C55042E357 -:10BD8000A6CFA0F6AF655C651837FB78CFA6C5587F -:10BD9000DE2885CB88397A0E2EA8227CCD54C71A8E -:10BDA000FAED42B542F21CA991035B101FB5527027 -:10BDB0006831E2EDFA828946F8249846FBACB3205C -:10BDC0006B61BF1BDC9586F61B2B661AE6ADF5D4BE -:10BDD0001AEA754D9F82920630B9E90228A50063E0 -:10BDE000831D86F1A5077619FA27BD0A722296638C -:10BDF0000FA9AD5496768752897D6D690EBF2519BE -:10BE00005938ECADC6EDC0F80F1A5FA2B2C981F87F -:10BE1000C0EFE7E24489F4623EF71F8B0BB422BC0B -:10BE2000E72C011FE1E16E39504065FC883B8A2117 -:10BE30001BE064C6837232C10FBE632AF2C1C48F95 -:10BE400003AD54BFF64287EC233DBC5DF6DB4A8868 -:10BE5000EEB3127E4F7AB74302A27B9DD3E20990E4 -:10BE6000DD4AED285E1BC35F1F7E1B6EF516F6973D -:10BE7000D74D7995119ABF2DC3B3712FE9CDAA3F44 -:10BE80002D92B3FBF703971209EB78C9A671DEEC8C -:10BE900091384E4E9CE620BD1E5F2DF3BEE06BD662 -:10BEA000C0569C679DC51DA7093FDB57D774EB663D -:10BEB00092EBF62CA11FE27F07AA84F0C7A7F9E452 -:10BEC000221AF71F126C85E87A4B2B80F791926546 -:10BED000117CAFB8862C2CA2F1895C1F5F21F00881 -:10BEE000B32C813C9C72EFD413FE44C443FC8D966A -:10BEF0004CB4409054E1F95D2ED6C787DECC94490E -:10BF000096A0C042FA640DAA37D227C31ECC7A7419 -:10BF10001F8D3F60853C2C962EF09CCDC5FAF767AF -:10BF20005940C2F6CE8AAA84A218FC259D97402DBE -:10BF30008DD6DBB3548623490903C971D27985DBD9 -:10BF4000A129DF42FA465F276981FAD6DA9875405F -:10BF5000F1AC22B8375CDDAD92BE4A3A22F6091048 -:10BF6000CEF0E2D6FE86765125422AE18C8589FD07 -:10BF7000E9F0B7EDE5292AD231ADD29DE2A6F2670C -:10BF800088E4498C673FA9BFEFD39F2BA8F6686868 -:10BF90001AB66F271D28DA83807CBCC1A6B5930A28 -:10BFA000C17A9AA4B5FB1FF54E233ACAC6FE25D91D -:10BFB0007DFD3D8E8CE8FC53363F1A6A2BEC8FD703 -:10BFC000BD53ED6C87E3910FECD877CD5585C360F9 -:10BFD000003B11C56BC225F09A24F07A01B53DAE45 -:10BFE000739743ACF39EA48E22FE7AD882529F03AD -:10BFF000F092CB579D554EF0078BE8FB9224CFB0C3 -:10C00000A9C86F9D36CFA8EF901EE98A736FC171E2 -:10C01000B5777EF85813C9F1ECBF15A007039D8AC8 -:10C0200027611CAED3E0FA94E5BF462E4C26FFA64E -:10C030000F8FC4BFB8E6F72DD13AE983A4285E3D3F -:10C04000B9D8BE2106CF0E07E92B51FFF7AC67BC6C -:10C050006D44DFDB1C8CA7B59A0CB5A5C0460BF26E -:10C06000FF59D7B6AF133F9CDD6E05F2933AA99105 -:10C07000EC638183E508D2C319B5C8F7456F58BC96 -:10C08000E48775237F78883F1AF30DF39D9DF25660 -:10C090006A118E3B9BAEA4127E56866D8CB7850AC4 -:10C0A00004EDA81F3BD36FABAEC4F6CE232AB777FF -:10C0B00068F33C9BE7599EC576659AEB7DDC97E477 -:10C0C00099245F1C3338BDC862BEAFEB43C4730311 -:10C0D0006D3375703E68AB7404C8AF6CA8682924D2 -:10C0E0007BB026257F18E03E1AA6496C5F1B9A3E5E -:10C0F00066BCEBF32BE76550D3A275778ECA7650FA -:10C10000513CCC0FCA791BB7D7359D65BD8DE06416 -:10C1100091DCF4B408FDB6D10AB7D66259F74FF9ED -:10C12000D65AEC5F872CC5F601F6D9D6C4E83FE8AD -:10C13000F8A84FCF9720ED1E9EF5663CE9D55AC969 -:10C14000350F700F87B36DB5CA70ACC7B9E64958E3 -:10C150000F6CE9F5723DD335CF82F58EACDA5A65B6 -:10C1600022D687BB7E687103FC69CB4AD13FCB7571 -:10C1700098EA07B31E10ED89820F7E98755BADBFFC -:10C1800090F8CBC97839D39EC0F231189E9735BD4F -:10C1900068C04BBF7659BAD54B7C355FE8C153EBCD -:10C1A000476C66FF2737944F6B6E273D8B781B8A51 -:10C1B000B4A9C07FAFA0DC3B100FE939E0B160FF4C -:10C1C000F45FA0FDA1FEEF854611FE96FD222E280C -:10C1D000213D563FF1928DECCF1259CD27B9FAF59A -:10C1E00068DF7F935C9D4E0C717D59D31E86EB1FDB -:10C1F000B92EE19FB822855EE4CFE5B0D146EDCB04 -:10C2000041394E7602B528FB312B9D2FDBC80F5BE1 -:10C21000F9B4F57838C68EAE82F03192D3BA67ADF4 -:10C22000C7C331F616687C0C7F1DB70838140D1F84 -:10C230004BE4D0229B806B2FC1B53A15FD7999CC88 -:10C240004368A88FFDA0BA028E4332E281F86EDD0A -:10C25000156F17FB06B07B1DCD68E751E47634EF10 -:10C26000E2B21DE724BD334C09DBDC384FBDA69795 -:10C27000C7878EDB2066FC31CD7E25EF92B85DD777 -:10C2800017D176619FA0D033D68270AC9EF3EA14AA -:10C29000A28B4ECF6B13A0232E95E9E2D6E8E226BF -:10C2A000BAE8F8477C962A38EEE50B382E6B20BEAC -:10C2B000D0F12FE0ED8C17FA22B2338EFD2433FC3F -:10C2C000E7343ED0F791902DEA83C19F909D28E8F6 -:10C2D000FA2F863F215BC8B1791FBA1CF7C57D2DA7 -:10C2E00003FB293ADC97CF6721DB17E1335DCFD41D -:10C2F00083AF80E6D7F58A8E671D4E1D5F9D14FFC4 -:10C300000C00A7D2F44BC37E945015050D50909DA0 -:10C310002DF458C74C203A284DBBB9DFE5EE47D77E -:10C32000B783ED4BD7B3E6FDE9FA56DFA7AE77F555 -:10C33000FD4E4545C2FA10C3768AABAE3DEF33F8E9 -:10C34000BD95B0C2E017573BEE34D46B5CDF31F4DF -:10C35000FF5A468BA17DA6BADED07E7DC10F0CF5BB -:10C360001BDC3F36F9ED9B4D7EFB7F1ADAA7844339 -:10C37000EC67BFD63C031474ACAEF920C2FE76B0B5 -:10C38000D9C5F57DCD195CBEDCACB27CEF6F2EE07B -:10C39000F240B39BBFFFB6B982CB579B3D5C869AF8 -:10C3A000BD5C9AF5C2ECE7BFA1507C5211DA584D42 -:10C3B000AA7C5B8EEFEE6CE487D72D81D644C4D384 -:10C3C000846EE18FC372B33D3E77EC1EB2EB2E9BC1 -:10C3D0009BEC61DBDE89923A803F9784F6CE13C3F3 -:10C3E0002F49B3C2E021BF07CDF340FC756FB6857E -:10C3F000E9476A1F50EEE63BC09A8EF2367FBEE4F4 -:10C400006E15E6C00FA95C067DD83E5B013FD9FFE3 -:10C410005AA712B42731685E07C2394F8009766A7D -:10C4200027FB9D9EA690DF7A137D4478658F0CD7FD -:10C43000E0F77915BFFB8CE2E46F3A3BACC42737D9 -:10C440001FB8EFD43DD80E6DFE72928F3EBFC1FF74 -:10C45000B6E572FC867BB3855CF54AEE9087FC9D61 -:10C4600014C51DEBFFEBA5375BF8FFB35BFD721244 -:10C47000E233F206B01FA7CB23EEAF9DE0D7E5A2D3 -:10C48000D6A504472791BDFF4135F5AF3BA4325EE9 -:10C4900074B9D0E5408FFB7439A8919F6DA5FE67F4 -:10C4A0008E00C7CF137A7C1F3C4FFB34F99D15914A -:10C4B0008DD514875D2A4E9C74BEE325EAB7A7D9B3 -:10C4C000C77CB4BB793E97C1E6E51A7F3672FDE5BD -:10C4D000E626AEEF6FF67379A0B95DE3CF8DDCFE93 -:10C4E0006AF3635C7FAD39A0F1E976FEEECE11F61A -:10C4F000F7E350F530E2BFA7B245DE061C951C47B6 -:10C500008022CA2FCA2775192F0A7FCAC41F66BE88 -:10C51000D0F901506F4888AF6FA29D25FB700BF8D2 -:10C520008B1663397FD946EB64E9CBF3C54A671BA9 -:10C53000FB1F667DB80282ACEFFAEB77E1FF5F4A42 -:10C54000BFCB189F92BDD2F5DF6A08F37C76F94E17 -:10C5500037E54FBE3ABBE2D2EC0A2CA6FE7D7176DF -:10C560007CF722D972E9383B7BA418AFC7D9E83FE2 -:10C5700002D9E5DE80CC7EF5F2AC8D491C675744CC -:10C5800092C80F58D125333D30CE548623DD9669AD -:10C5900074EB81E01F892ECBA62CE33CDCF24DC668 -:10C5A000FDAC74DE941C5407F4D306DC673D3CF804 -:10C5B00011E5E3EA357CF17784A7A9FBE6992FC75B -:10C5C000F4FB243B319DF355136002E103E177074F -:10C5D00049CE0EC92C6783F1C5698C4F88CFCF3502 -:10C5E000CF9FF932F2FDE90BCD1C7FFD33FB811F9C -:10C5F000F8477E75F45A97E74DC8E1BC5BD846F220 -:10C60000A3D36F1DE948847B5D95234081766FB984 -:10C610004BA1F57B258F4C7987DE77C1DD82F8ABA6 -:10C62000DCFD9B23241F950E279F1BE0267A62E9E1 -:10C6300039F190AFD589FD26BCEA91C97D2F7F39AC -:10C64000DC4ADD747BA3DB9FC93D11D9C779815CCE -:10C650009623C0D8E262CE17972373BCD94AF1263D -:10C660002AA4B3CEE90CEFD920B8E97B348F25F2A8 -:10C670004B932F78E424846F9D161F4E7CCFCB7094 -:10C68000781C2AEB17BB164FDA332CF82D8A479704 -:10C69000CDB79DF29DF0AB38CEEB9AE19B9023F4A1 -:10C6A0007872AA7702E3D7A9E653DC5023F76C7BB4 -:10C6B0009CF8A133C14D791BB3BED5F5DB607E7B01 -:10C6C00083EBEC807EA45E3658C439C1B86AB59459 -:10C6D000E23FF22F292ED4E34473FF9ABCAAEB0861 -:10C6E000BE1A794AC84370B92C9FCBA70D4D1F7D48 -:10C6F0006E9CA6AFDFD055EE5A12930769CF91B466 -:10C70000FCAEE27ADF11A5DB17A5EFD4C87C83FD70 -:10C71000F9BFEEAFCD46374742192A9202C28F00C9 -:10C72000E14F2C8010978B20C2A50F3989CA25E0D4 -:10C73000E6F236F07219CEF535E790BF608D0C2524 -:10C74000393EF5C2DF0B892F4E5D33D995A546EDF5 -:10C75000AB6E6F2FD7AEC6D379D200FCF090C6B7C0 -:10C76000BADE1E943E26BDDD3B16F5834C79A1C88A -:10C77000A21729DFBBC7EEDA1AA31FC06FF4170791 -:10C78000D317358A88DBB75BDCAF531ED1FF5A1A4B -:10C790000C245F7A399BFC49E4C7E40561251BF949 -:10C7A0002D3FD5F334F1B3FF812929AC87498F5C44 -:10C7B000897478579CB7C00A299087FBDAD529EA93 -:10C7C00045B7A70424B6E741A6C742085B691FB76F -:10C7D00002B0FE5C0C2A974BC1C374C199138A51F5 -:10C7E0009FDCDEA98CDB807095A446B249CE8A26F8 -:10C7F0001E4D9570FD62F2639D9C6369277F4387A0 -:10C80000F3448EF0632FE67876115D4B52431B1E86 -:10C8100026FF6EA705C8BF3B31F13B77408C7D1CDE -:10C820009157D545FB784E12E77CFE2EBBC88F4151 -:10C8300064A837C6AF0EE756BF44F3FD568BE7A199 -:10C840007B3D9FFFD4BA044E61DA10C6018E1B45B2 -:10C85000FAA7BF9CF9795C09E97B91EFF34305AF37 -:10C86000CBF577724ED4B689FDF8C9AF1A91E73B84 -:10C87000447095D850A511FC4FD8035BD8FF691CB4 -:10C88000457988654FDA2D648F8FA23EA5F3CE7768 -:10C890009A1D5CFE09E3142AFF8C710A95EF629CD5 -:10C8A00042E55F304EA1F2F6F3635129231D723D3C -:10C8B0007F617D39C83E06D7177ECDBF86F9039DBF -:10C8C000D3756B7C5DDCF9DE7D09C407BB64771E24 -:10C8D0008250B453E17CC2E9DD130272562C5E7DB6 -:10C8E0001182A378D71F1E9A5C46E3149784FD4FEC -:10C8F000EF3A3B94E31F137C7DF8E8B2097C68F0C3 -:10C900003E9712DA40E39FDB994D10A23E00C187AB -:10C9100044CF01F261002DCC27CFE708FFF6467B1C -:10C92000A42CF65C12C8F453DE51B31735F285A47B -:10C9300070A1967F9D487C9DFB3AADE73F20431E4A -:10C94000F3A731BF50902BF0A097455D362FE545FA -:10C950009EEBFAE39CEB110FB327CD2C9763E42DEC -:10C96000237788E837F1B39F3C9CCEFD5DB4D4CDEE -:10C97000B0B9C685FD6E71EC7D8550B0D0F56E4DB9 -:10C980000AD66FCD90F653B958CD9A9EAA12B80127 -:10C99000DECFD282CAFDC462B3DCB536B2AF952415 -:10C9A0005431FAB3DA914027A07DF51A579AA1FEC7 -:10C9B000B58C1186FE33D51C43FBF505630CEDFAEF -:10C9C000BAB3DCA5867E24AFE4FFE23E98EEB05514 -:10C9D000E6F394A29D1FBFBD8AF77F7319EDBF17C1 -:10C9E000F1674307E1838AF53F7A98D4C6CE7D4943 -:10C9F0007CBE6AF233EBBA9EDAEF5107F7333F8120 -:10CA0000DD03FA67F583F8675FD4CF44FDF110E9E1 -:10CA10008F92176EE2F3F2E7267E76854AFE722E3B -:10CA2000FA9F884AB3FFD9ABF99F66FEE9E3534901 -:10CA3000157C7350667DABFBA166FE01B84FB3E376 -:10CA4000A2BC5C399FFDA6B03B7F25794F8BE56B7F -:10CA5000AD34E5154A6C680728DFF77B19B6D08737 -:10CA60000B08878EFF9C28DFC36D9B5F195EC6DFB6 -:10CA7000FD89B864BD966768CED5FC8EBABDAF0C93 -:10CA80004F8FB6C35DEF1AFAC3BDD27E43BD2DCB27 -:10CA9000587FB0727FECF8C1F4D0B24D77DA7C9455 -:10CAA0005F7E44E41BCDED3A3C35FBE23CA42F9580 -:10CAB000DD768E6BEA5D1ECE832883E44174BD7003 -:10CAC000B30C8D03E9B70DDABCB3F6C581FC25E6DE -:10CAD0003D8ABC42F0F87F21ECCCD1640F7863D65C -:10CAE000F961AEC8039F4AD9F86F9F62BF53BF0474 -:10CAF00037A1FE548AD0B7C59D272C16B213F182F8 -:10CB00005F8A5D614B2ADD53599EE0A773E086156D -:10CB1000897E3AFF29C98EFCD181A47F2277EE431A -:10CB20000EE4BBB72D1683DDE9255D87F56D4FCF8C -:10CB30009943E76DD7EF8B0B5ABEC47EB6511E9357 -:10CB4000EC549590F745C437FAF916CA47C3FD600F -:10CB500038EFA2FD53FD58EED7DF7C84CE6B0E0A72 -:10CB6000F9C766A739AEBC2526AE844D427E1DF8B6 -:10CB70004BFECBCA9737DA28DEF9AAE47E6FAE33D4 -:10CB80001A5F8EEE2FCFBABC371C16F27E66F727DF -:10CB90006F925E3F83F62E56DE757CE972DEF0986A -:10CBA000CCF2A87F3FBD5B9E111800BFCF6A7C000E -:10CBB000AE7CC3F9D79AA9E7E6905D5BD3A5F0B93F -:10CBC000DE60F6BAA1DD78DEF5DC1EFB72711E2C8C -:10CBD000F6D1ABDBD3AE4F522B0B45D9C2E7AE1B20 -:10CBE00035BD23FC18B4A3D674B2A3B512E7D10E99 -:10CBF000770DE37B15872508AAE3788A9B1C48B745 -:10CC0000B9623AFAEE247F0C320A145A678E46CF84 -:10CC1000B95A7E675ED7BC3CA2D71F3B971CF66013 -:10CC2000D327B939BCCF6F809FFDC1C329DE4CBA71 -:10CC30005F30BB55F0F7E194480FE5830E4F4D9000 -:10CC4000E85C09E76F8BF5F70E5BBD998DBC2FFD96 -:10CC50009CF16AF962C265C4B39A3E447AFA25111E -:10CC60009731FF2BC31F64BE5A0181FD1E5CB7DEE6 -:10CC70001D64BF741588F8DCEC97D74FF9D0467661 -:10CC8000C11C4756EEDA7B84CE2FFAE5134CFC7AB2 -:10CC9000A9FC81397E1DCCAFCF4FF566E4C5E4EF2A -:10CCA000CCFE799F1FAAFB515B13F87CE7A5A98FE7 -:10CCB0009E5E85F5BBB626B8285E3EF9A4DD4F7AA8 -:10CCC000F9E4167B40C2F693A9916E8A134EEE28C2 -:10CCD00072E30CB0CCA2FED7B364D79FB1325FE051 -:10CCE000CA86FB096BA6DECDF7F6D66C4D94E8FE3E -:10CCF0000C6488763D76937F9AC87EC18AE787F375 -:10CD000079A56E5F483EE87CF98327E23CE4E49F26 -:10CD10003C303799F2763D969FF3B93CC8F71EA395 -:10CD200073F755DB12C7F1FD8B4260BA2DDF721528 -:10CD30009F536E547C9368FFD53FBD6118DD075B40 -:10CD4000F1872140FBE9DDFD3C9FE345FDF481FDDA -:10CD5000BB33BB7392A1308A273D9FD7FE748B975C -:10CD6000E85E2EA9E2BC051A3D23882F76D502CDB8 -:10CD70003B4E16F73D23EB13D82F35F35D6D9EF038 -:10CD800003EBF4BC411A3832487E7CC078E85D3F42 -:10CD9000660B9D6BADC84BD5EC74247F4ECC7DC229 -:10CDA0001AB9BB9EE2BD339BEC9CCFE8891BF83CD3 -:10CDB0006B615E0AC3B7CC613CFFAE6FFACC582FF3 -:10CDC000040FE99D71AD6AE99D58AED5F0DF92E997 -:10CDD000F5E5E17A2B3B7EF0C2AB8C974DDF7E9B75 -:10CDE000D63DE01479945705FECCFEFF3287C85734 -:10CDF000006C6678F5EF279E788BCF494FEC1C933B -:10CE00002FCE7F43EF3F9EC5E7BEC7EEC172C781FD -:10CE100037992E6678FB9DDF4912EFB78EF6914663 -:10CE2000E7B4DE6FE7F1FD1D11B72DD950C4F8D37B -:10CE3000CFD17A4F0E1C9FE870EAF3EBF0E9F3EBE9 -:10CE4000FD5A357A5DA7C507A76CA1D37C1EFEC22B -:10CE50001889F2747DDF5343C52931FCF255E5C5CD -:10CE6000BFA9E5358E585ABE65A3FB6D1D0F5B7DCE -:10CE7000B17AEF32F3E17D7EA00754D750614AD8F2 -:10CE80006EE1E694A1746EA7D54918B03E45034FF4 -:10CE90002278E8BE9F56C24A5F06E7BB693E99AE5C -:10CEA0000F06B8DE5AE956A9BC56F22AE2BE5680F1 -:10CEB000F9723A348EA47D581C613EDFD2EFABCCC0 -:10CEC0004B59774316AED73604D6911FD3661572E9 -:10CED000E15F9CC0F19B8E27DDCE80ABD0605FDA36 -:10CEE0005CA02A38CF7C05DAADA9A2DF9588E7C31C -:10CEF0000796BC427EC25B4AE3105AF7A8F3912220 -:10CF0000C942FE5D209162C4B7DF7CA6FCF7D8F76A -:10CF10001DF04C7522FFDCF41B07EB7D733EE276BF -:10CF2000F0717D1984AD1FE3B83F4FFC9FADFB202E -:10CF3000BAAF3F4FFA7427C507B7A4DC574EE3F5E5 -:10CF4000FB93E67B7A275D4EBECF67BEAF7723F8B3 -:10CF500042C4CFE72CBE7A91FF689C40F6B737C534 -:10CF60000612F6EF1DA2E1E314303E7AADDAF88F37 -:10CF700054AE97558FE3BC229C53591F4F36D99B13 -:10CF8000B2311611875D14FDA7461483BD292BD13C -:10CF9000F2367F57D92FBDF6BCF2B9F6A82E5FE462 -:10CFA00059CAD22C8D03F98756ADBD1582B2D88FE0 -:10CFB000F01326F7F1954726FAD56BF57AB267C8D4 -:10CFC0004FBD490E3F5D509CBC5BF0D76425B897C0 -:10CFD0004AD4AED0447EC52EB4773A1C74D697316D -:10CFE00086F96092CE9F38D702ECB74E6AE4B8C596 -:10CFF00041FE0C961BA410C3710D44B8F46876BCB6 -:10D000000ADC5C4E032F97C89F5CCE404B42E5750F -:10D01000D0C1E52C0809BB7F75B095ED19DCEBE2BA -:10D02000F86FE6320BF91B65DF18385E187D493C56 -:10D03000A0C08DBF7C3C4C0794BB9C01F031B280FA -:10D04000F587191F66F99C0A6199E59314430EE56B -:10D05000095496D36AF070BDE60BE2A122EC533876 -:10D060004F63C647F5C07CE1D6F0F1E77C10E71FBF -:10D070001A9D96E6AB5CD7E985729541FC6FA6A335 -:10D08000FEBD2CA1EA2C5D29BF7E5BE65CBA1F5574 -:10D09000565AB59654F282FCA2B9743FAA6C72D566 -:10D0A000F37474B9685BB1A89754955ADD68DF5A78 -:10D0B0004AE64EC3FE3EED3E31CC17FEF55D9ADFEB -:10D0C000E26BF996DB8572E2CB74BA697F0E74EE7F -:10D0D000E95E8A9C23CEF946CD08EEB362BFA38AEF -:10D0E0006F7A3E9DF73982492AE2FDAE961ABE7FDD -:10D0F000F6804DF4B7DB457E55DF177EF7C7617DBF -:10D10000C78E316BA5ECC1D7C779E7E60F2138F29E -:10D11000FC24AFBE9D925B50B26AD87C94CF9E90A7 -:10D1200015281FAAAF939EE99B4F7080239FF3643D -:10D1300023347FA667C798314497A5F9DA7DAAF40E -:10D14000AC52C25B43A67729CDDF9B28F86B29D16F -:10D1500061C8E0E5F7F23D8B697EF3F7DEBF2200A0 -:10D1600038FEAE7CDF329AAF21E102DBF7D363FFFA -:10D17000B02E9C15E5530989B400F7DDEA81808D56 -:10D18000ED8076CF5C3B77EABD1DE7413C94797D2D -:10D19000ADA4D2262C888C27FD89F3AEA1751B6C1B -:10D1A000E1516371DC23738FD9049F8D147CA6E950 -:10D1B000A1AE3D07EF1921AA5E8891AB863D9F7D08 -:10D1C000FA0EE2AFE18CD34DDDA3F2F4E3B51C4FD0 -:10D1D00082D3A03774399BB4CBCE7EF5E4DD57DD26 -:10D1E0004EFDA6FEA13B87F6756D7798CFB37ABB4F -:10D1F000DE1A21E0D0E38D73D297B1BB74DECA7121 -:10D20000DC4E71DEBA466A7C2991EA3F93DC7E846B -:10D21000FF846637F4B878B9B6AFD507B7AEA3BC0C -:10D22000C8F24D4B67F17D9C80881B54FC25F9FFAB -:10D23000045EE573EE55DBCDF144C446F45FDD6179 -:10D24000BAD743F130DD5F88D5EF03C4C34FE56B38 -:10D25000F9AE4CC8E47DC80B927D03E83B73BCFB80 -:10D2600018789EC9677FD62BD3FAE5CAC0F9842700 -:10D27000A2EF3B581E96696B139E9C1CEFDAC4BD4F -:10D28000DF27D6BA5D54D7E47333F24A05F9D16D7E -:10D290003F66FED7C7E9F2BAA25DDCAF864D69CC26 -:10D2A0007325DBEC1EA26BC9B6611C5F601CC47EDB -:10D2B000DFE66DF676AAB7DE1FEF974B289F1CB905 -:10D2C00082F22AAD71E27D129947BAEF59922DF29E -:10D2D0001CC774BDAED975FDDE6C5FFC9398CFF7AB -:10D2E00093FBDAC38A21DE68D5FCE732828FFCC06B -:10D2F00046AB889FE204FC7BDFF87A02F9B13B156C -:10D300006F02E5A5CF1CCA4E8601F0A697E5685EC0 -:10D31000E073CE0BCBDF9A95F379F42A7B4CBB6795 -:10D32000AEF1E7AF9A3DF0176B941EFABE6AE46760 -:10D33000AB6D94E7B80D5C94F75873F0A9567A2753 -:10D34000B3663D7046E10CFDA178E1030B9F674F8A -:10D350003A589A41FCD8A9E93B3ADF5563F86A3C50 -:10D360002585B07FF94808D0BBA138351ED498B8C0 -:10D3700038A120D5504F745F61189F5C916D68078C -:10D38000BF2754383EEABFA678AE36F47F20693A0C -:10D39000BFA3991ABA83F34A6933C619DAEDC8D71D -:10D3A000745F013E16FE4F05FEB25D854699E09C16 -:10D3B0001C06F809F2DDA41EA37F5411DEC87160BB -:10D3C000DC21C510D7DB2F91674A1AADC9D54818A3 -:10D3D00029F48319DFC67B0D6B0ECAECC7ADC944B7 -:10D3E000C7336B707CEBF2A7E37D88D788F761F3D6 -:10D3F0008D781EEE33E279C472239E331B8D78BE86 -:10D40000B2C988D72CBF118F39ED930CFDF3365676 -:10D4100019EAA31FBBCED0FFAAC01C437DCCF66F78 -:10D420001AFA17752C31B497EC5AF9B9741F1B5CB2 -:10D43000636837D3BDF4C0774D7CA8309ECBB577F9 -:10D44000553AFDFDF84BF49F0CDEE4A044E9407F23 -:10D450002BC9E3BF8AFEB3476BF75874FA7F41BD0F -:10D460005AA8F94FE6F759B31384BE79EDC0994332 -:10D470001EACBFAE965A33C86FD2FC03AF7E1E619E -:10D480008AFBF438E5C60AC974DE1E67386FBFD45C -:10D49000FDB4F250D0501F7B48BC6B1A77C4FD120C -:10D4A00095E5EF79E4D8774C133F66B3DC2FEED4E3 -:10D4B000EFB9E97113643CC971E8021D7E1282F173 -:10D4C000FDF38B7A7C6A8E5BF578B5FF3B29E1979B -:10D4D000DC2D0F16C78AF8558F5BBF0E1E7E0F56C8 -:10D4E0003ED2B76E34DD9FB244D2A85D8F6709B1DA -:10D4F000746EDC4B8865E7E2E05C4F21BF23E5BC3E -:10D50000F7CA9657E6D27D7D04DF151E2FD23FF471 -:10D51000F3E468DFC6D1A8778F4BAE75A538F6B5B2 -:10D52000491F8EA2F91E1E2DF20C76193184F66762 -:10D53000D8020FD0F7FC54CF23A387F4BF676D2E1A -:10D54000CDF77F3A9B835C2A2E37DFBF31E707C3D5 -:10D550001695FD4EFF7725BE6FF321013731EAAFF7 -:10D560009C69B7B2BF025A3CBE50C3BF9EB758A019 -:10D57000EDE7384EB11CEDEFC25DBF61BAACCAE851 -:10D58000D1F21D8DEC5F2F1DE91CC7F7C93CA56EBC -:10D5900091E7D2F318232EEB9DC8A5F6BF2AE3A48A -:10D5A000218F04CFA67DA1F3EDE8BEC5FCC7D78BC4 -:10D5B0007CE4F1F5999CFF8ECE7F9AF3490B1BDF3B -:10D5C00030C8C5AD4D470D72B0D8FFAEA13D9C1E11 -:10D5D000B152FE30FCC2F0E9B720FE4EEDB4F33B91 -:10D5E00066E4833746C7E4CFC2EBC74CE3F79097B6 -:10D5F000DCE7870C47777388E9ABEFF358F311AE9C -:10D60000879BC35C9AF7A9E729F4D2B60F0AE89E74 -:10D610007D448A77535ED89CBFB8DBA2BECFF72289 -:10D620000BB2B57382C6122FD34FE42BBAB577A1D4 -:10D63000DDDABBD06EED9D67B7F6AEB35B7BBFD9CD -:10D640006B75B6535EA35B12F77716489E2717E3F8 -:10D650007AC9237D1F915C35AC8C142BB84E43499D -:10D66000789184741E39C4F731E145C2706138BFC6 -:10D670000BF2F33DAF0F2CFE627A47E32EC8B88958 -:10D68000E2BC0FE2FDA7C91329D89E26EA362187FE -:10D690001505FF60B97B0F27A3FDF97F2989BC928F -:10D6A000336CA3775053D37D503044DCDFE2F72F47 -:10D6B000F89DF852CF73F65A851FD8ABF983F6025E -:10D6C000710EE83095D944F3725A0F343FFFC17C94 -:10D6D0007E37B2C90EE4BFE2FAFC4E46BF67627EF7 -:10D6E0004733EED7767EEFA0E743471464F17CF42E -:10D6F000BE86E432FD7B09ACB7201C1A45EF71FAF7 -:10D70000E03D24DE439EA23C724CFE794481F6CE7D -:10D71000F13630BCE7597DF0F8318AB37E3DDA77D7 -:10D720006501CEBFC4A28E27BAAE4EDACBF9AEB138 -:10D73000052AAF8BF08AFDCAD046745AED08737E75 -:10D74000EC52F9F0C1F67FEAF6D08F0A39FFAB163A -:10D75000F37B3A6D5D84636C414CDE5A87233ACF8C -:10D76000E7F3BF9ED7D5EB279E78205FCBCBDFEAD0 -:10D770001DC09ECED0F0D26D1D388FBEB440C423E4 -:10D78000FDE8331A4D11DD538C471B81E53CC21374 -:10D79000E5816FC6FD707EC23396E8BB7A8E93DF5B -:10D7A0008DEBF3E33CBE9F7FCE3A2D99DE1B89FFC4 -:10D7B00056368ABCBBDEDE2B09BAFAD78B3CE8EAC8 -:10D7C0003D478FD1FFBF60C54F8B4A39BED7C69B3F -:10D7D000F18CF8E5F74D4B64716E85F85D40F39B75 -:10D7E000F3ED5F16AFBD99E27CB577F367A3E8DD93 -:10D7F000E86ABA7F46EFBCB4FC15741AF352882F5E -:10D800003FE52BFA9F47019F6BD9353B62D7C78F06 -:10D81000540CE3BB9DDEB5C41F2F687A03FB072CB5 -:10D82000B87EA71E279BF2289D2191EFECCCB0B1CA -:10D830009F4CFE0ED927DDDFB9EB0D91EFBC2B4BD2 -:10D84000F8D1041FD1573AB29FFD843EFB2FB95542 -:10D85000C29FDDEABB9FD607DF5AB65FF295485FED -:10D860003ABFF8ED755A3E40D8C372CDFE95D33C11 -:10D87000E4E01426B35D2CD3D645FF91F36E13C1BB -:10D88000D72A80D1F266EBF7731EE17F01BC43AE6D -:10D89000E0704400000000000000000000000000F4 -:10D8A0001F8B080000000000000BFB51CFC0F003ED -:10D8B0000917B0A1F2AFA1F1933951F93F5951F9CC -:10D8C00017D0F884B02E1303C30A46D2F420E39D88 -:10D8D00040FD0780F838109F6322DF1C103E28CCE3 -:10D8E000C0F0458C816116906E01D26781F82B10D3 -:10D8F000DF06F245441818948178BE28034314903B -:10D900005E0AC40522107D8780748D287976AAF37B -:10D9100050E6E6514C195E298DCA2F55616058A614 -:10D92000CAC0F05A0DC25F8824CFA0CEC050A60254 -:10D9300061EBC931307400D5CC94C66EAE3E50BE9A -:10D9400013282FA00EE10300D191FB3B68030000D8 -:10D9500000000000000000001F8B08000000000015 -:10D96000000BCD7D0B7855D595F03A8FFB7EE424E6 -:10D97000B9819B90C049081834E0490C0F11F12679 -:10D98000441A6CC41B8C1A6768BD606B231588C869 -:10D99000687C4C7381248497066D2D83FEF462AD00 -:10D9A0004329ADD16287A98FB9202D689D1A2D56C4 -:10D9B000ED4FFF46C6B1D42A7F44F1552CB3D7DAD8 -:10D9C000FB24E79CDC04D0CE7C838FC33E673FD62C -:10D9D0005E7BBDF7DAFBBAA104E0128053F8873D05 -:10D9E0006F9000206FF0095EA3092200CD9A5B5F63 -:10D9F0005F0CF04DC538A857B1F7A365E3073ABEF1 -:10DA00009F580B610005EBE70318F83FD66E4D7089 -:10DA1000F5A84490BD531666E1D3ECDF7C36AB002D -:10DA20005A257EDF3831D377F30929577F9F17E8CE -:10DA3000CF29066AEBE1D727EF37CBECBF020845C9 -:10DA4000DE0AB0BF4C87E9A71480E3C10559691805 -:10DA5000BEBFB7DBBACF5327007CD4F6DAE4FD13A0 -:10DA6000867EFFA6022D3DE543DF4F0736E854C40E -:10DA700047D21D9F3C38EF81790619922E64ED0143 -:10DA8000D29E1CF6DCB1F93CB56C104EE73C00921E -:10DA90001CBF9FB39D2752932E60A50A29318BE0AE -:10DAA00052D93FD300A82A5B97253B1A80E072C069 -:10DAB000DB11F9DBC03BEC7A897AC783AB3B91B4CD -:10DAC000D6B838BDB4E7C9C66A184A2FE67A98783E -:10DAD0003CD3F5B81D7C348E4947CDF2C211D7FD39 -:10DAE0007474743DD2D179FFFD7494FCDF4B471DF3 -:10DAF000D4CFFF323A02E8E6F8823E15C71F7CCF4A -:10DB00009F91853D12D2192BF622DC457C28286A8C -:10DB1000EDBC599EC2C41418CF9DC3E45651DFA278 -:10DB20007A847BF4E1797FC26767634DDDA56C7E03 -:10DB3000F94D3D2F7D893D23F1949460EB751FC80D -:10DB40002854587F3725ABD9FCDAB1B399008F241C -:10DB500017C592385F88018C02F8073127005957A2 -:10DB60005939447FCD340F37A4393EA4539EA1EDDB -:10DB7000879B7F08DB99758AF1FF2B00E777BA76E0 -:10DB8000B0928F9764FF20BEC70C8E4FFDE4375BC9 -:10DB9000CA80F8B17FEFC5BF107E6FFE1F19AF00BE -:10DBA0002A7D281F42F5B296C2FAD093ADB272E434 -:10DBB0002615D24C461454754B2EFDF4EBD2095069 -:10DBC000D7C3D7476A080DC2F79F2011FD8CBDE36C -:10DBD000CDED6B19C99D581834883E3480DC9CA16A -:10DBE000F3F94E1B12B2A5DC582325683CE3B95269 -:10DBF000D63ED9C8F5DE7DF50BB2ADF2CA23490297 -:10DC00006F4EFA005D9D866CC5E943AD9763BE29F2 -:10DC10005F9C3ED4CF491F792B2DEDE0ECD72B62D2 -:10DC2000DA0567481F5F743C735D87F2D52AB1AE91 -:10DC3000A53E607C7B6FDD828C76C6F0EB5A49FC9A -:10DC40001EA987582A43BBFC81F54C0E7DB2F551C5 -:10DC50000696F716DB7A29A3A7356D1F011F4AC464 -:10DC60003E5FB35F5FABA2BF99CB8AAA26637F6E8C -:10DC7000EC8FD1D9BAE8BD4960FC7002699BE143E1 -:10DC8000E9AE4863194AC1F881804066655F349601 -:10DC90005A4F7490A27531E1F3E8B20DFF6AC46F78 -:10DCA0002B435352B2C2EF6B75131C6E1C8FD1BB4A -:10DCB000A2B10E192AD420A47D61ACC1E14732384B -:10DCC000351ECB77DAE8A04BAF844CEB60D22BA2A9 -:10DCD00095D3EB9D67265F9CE335DAE13DE3764122 -:10DCE000557FCBA287866FA7C25BE6FA30247E0DF4 -:10DCF0003B983AB84E6B5DB0473A9FE9EBC2AB2117 -:10DD0000C1DEAEC54F17129D923DB3B6B05243BAB5 -:10DD1000821D928A709A7A14A23954AF42D2A91FF6 -:10DD2000D9DB02584F09C6E8697E1F1E2E417FC904 -:10DD3000D8DE52D6EFE5627D2F177A0DAA5C6FF61A -:10DD40009970939E5507CB6C1EEFDECEFEC7E8247C -:10DD50005921A57E200DFD5E8F7A91C9A57A7C6F31 -:10DD6000912B5B06F8204AEB552FBE3DFBC4AB134D -:10DD70002F60F4D16B2880626BF5139E582DEBFF5A -:10DD8000A58BA5944712F03238E70B385F88E5166B -:10DD9000219DF6D67A888EE77FE9A30892F1B13DFE -:10DDA000BF5133D1CBFC59AE4138D87FCBADF363F3 -:10DDB000FFFDF3C0BA14D238265C4B2B1582A37733 -:10DDC0009694C271F6FFFE8F775FC4E07CA14A3261 -:10DDD0003C3AC11B02365E6FECFDC8887E8739BEB7 -:10DDE0000E1AE2D339BEB91EE1314078853F30BC0E -:10DDF000B2F19235FD7D6B10CF4724630D1B2F6B65 -:10DE000076EB381CA7589609DE75B3BCB2C2E8079A -:10DE10005E1B25233E8382CFB3DCDDDEF10CCECE4C -:10DE200009323CC45EAD2B1D599EB53BE499AAC591 -:10DE300063126BAF27B54A6504BE48C5E4BA4CF21D -:10DE4000EE7989EBC98EE402AD14A7B7DF6E07A2A5 -:10DE50005E8A5BF42AB3179F97D8FC5D114EC7D931 -:10DE6000B5716E27F68E22F91510EB9135654116C6 -:10DE700064B083879D071B2893DD9C2D73F8E030E9 -:10DE8000EF5F35FBCF19B9FFB5A2FF8F9B25E845A2 -:10DE9000F8D4B817D71F621544CF7E419FB03287A0 -:10DEA000CAA6DCF594C5BB8AD93A7AA232E83ACE42 -:10DEB0002F49EBBC81AD712103C55FCBBEB3AA1B5B -:10DEC0003E53C82EC9964F24930C8E0D7B6F049D34 -:10DED000D9A9FE680AA83CF9062FE26703530A7C19 -:10DEE000FC1EC0F1038C6C51BE06987CD551BEEA75 -:10DEF0003D699995D53A3062EC534833243F2399D4 -:10DF00007DD192552A7BDFBE10887E01AD080B7E45 -:10DF1000DBA32FC71406576713905DD319A9A1F986 -:10DF2000B597D7788BD1DEA957E93D9C64F830EDE1 -:10DF300010260FFD6510C3F136E4432A88BC549BBC -:10DF400047F4E8D6F8FCF52DA590BE807DCF9EB6AF -:10DF500017C74FFE231813F89024D754932ED44498 -:10DF60005242FFAE5533D667A0BB2D90C892A7DAB8 -:10DF7000E894F4AE136F596EB80CF1DB59C1E8BFE9 -:10DF800078683F85C83F8CDE52C6822B4A328C535C -:10DF90002CEB441F6659FFD84DF00F577FB01EB3CE -:10DFA0003373B1EB98847881DA08CD2F0706FEC46D -:10DFB000B09C2BE63B0A5AA85E7446F75EE4B38237 -:10DFC000584F35E2E23BA1AB5FA2758307358C4722 -:10DFD00030684B4FE50ECA895890CB89E3864CF2E6 -:10DFE0003124A7B518EB20E4EB8D92B2D681FC88E2 -:10DFF0002C6CC2005EDFD63D19FDCB3018127E0FAF -:10E00000196AD22A7FB280956DF61F1C2A9D46A4FC -:10E01000C5F902B4BDC8325A59CB39D8DF7D0C20BE -:10E020001FF393378612A42F3EF285A7E0601FC925 -:10E03000F1AC346F5F8676F76D8ADF588FF46070CD -:10E04000FDE065FFA0FCCB9AA1DAE47176CC5ECE50 -:10E0500075E88DB94A90E69B7D39087D10AB9F30FD -:10E060006A103E065903D2CDE65A1570BC6090C3C3 -:10E0700065C299AB9C4CCB40701C4138187A088E15 -:10E08000701990BFC7E039E280E788039E23567875 -:10E090005ABD7CBE4EBF7FB12CFC7EE6F7A21E3C73 -:10E0A00001EFC4EA90606245A457C21AAF1BF4F6B0 -:10E0B0009251A58146EBEFF4FBD9FA1CB7E9871919 -:10E0C000A2AC33BBBE84E0B37F8742A2132A2B30BD -:10E0D000E0BF2E9E61E247BFE6FF32BEBBF1A00B60 -:10E0E00090AF18FF2AF8DD25BEDE28FCD8C5A8FFB2 -:10E0F00099DEFE1AC4C308DFBB2093BDFC2EBC1CF6 -:10E10000BEC02217EF93DD428FB305B5F22F185131 -:10E11000F4ABD56067AF1226349874269DA2753390 -:10E1200080FCEE20A7B7247857917DD1C5F5A3E9EF -:10E13000F77DBDDBAEAFBFB1C55EBE01168C42FA46 -:10E14000BAE1DB2E48B17E6FB4DA1F6C7DEE9035FC -:10E1500082EF1BD0D2A905C9CE6AC2792CD6404520 -:10E160003F6DE9BFFC9F698BD87CB60A3DFA3693B8 -:10E17000EBBA456F2C89A4DCB1F2A1F35B2319F350 -:10E180002F92869FDF5A57EF7CB40F929B5CE4D7A7 -:10E1900081D35FDBAD90BF666947F05EDF659FDFCF -:10E1A000E9E6EF9C2FF35868BE4B762C22BD39DC94 -:10E1B0007CDC3BA4582A837E7BCCD48742BE98F477 -:10E1C0006DF275B206B8BDF7FF7CA9356CBC57502F -:10E1D0003ED2FAB79CCFE3282DD3F179BA76BFFBB4 -:10E1E0009CEDFEF039DBBD29E4B8B3DD526F9F1B17 -:10E1F000D773B99AAC93E4413BDAEB6A898D61A895 -:10E2000070EDA94EA32966A9D77586F50E4A256734 -:10E2100054AF4E1EA1BF63C2CE38B0EBFBEE3EE45E -:10E22000BF9D6FCC47FDFECD2715F0B2791DDB15E4 -:10E230008234D2A79A72A3BDB284D1558ACAE96941 -:10E24000575AEC2A46B1D4FF371F0D917DB0E471C7 -:10E250004FAA9EB55FF2B3FF98020C0FC756F7FFA7 -:10E26000720CD2EB4E89FB7FC9BE2957B2F74B54D3 -:10E27000B82E9E814E6485F3CB3BFF1A6842BB4F9C -:10E28000DAB1F7ABD46FCF352E94CB66BD4F6417A0 -:10E290008DCBEAC5F07BF287526A82C4E16B983C71 -:10E2A000D4EF7EE78712876F8F2BE543F8766C7784 -:10E2B0002758BDE53BDE23BA9DF3E88FC38887E589 -:10E2C0007B149BBFBB7C8792F64CA1E71BF844CD27 -:10E2D00028317E5B26F875D9EEA5A40796F56C78F3 -:10E2E0000FF975F91E974DAE33BC1869C4EBAB8AB4 -:10E2F000518FE59FFE735867A87A3BBA33AC9553AC -:10E30000BF8BDC8CAEAE98616F87FD7F9C33B43FD2 -:10E31000807E8A6B2EEF59C7C703AE6F4C3E7D1BC4 -:10E32000FF923F546F4C52ECFB0E27E08569148737 -:10E33000DC919BD18F33F585C9AFDFFCF1896D4945 -:10E3400036EE3B8FFF795B92C17FD35FDFDF7627AD -:10E350009B173CE3D3500E2DDFF94A182C78AF55AC -:10E36000B81F76EC87FFFCC856C62FC75EF7905DD6 -:10E3700077ECE93F8ED5D9BC8F3DF6C928B43B5721 -:10E380003E7DE968A4AF954FCC190D23F80F48AF37 -:10E39000298F755D53B4AEFA1E098330004F89A7EB -:10E3A000637D9EDDADA43174FBEE6B9E9487E167C7 -:10E3B000397BD75A89EBB594F41096EF62785EB644 -:10E3C0006BED7BCA944CF84E8E91A3F8646C13C528 -:10E3D000F5BEF28A8BABF0E93274A40FE827F9EFAF -:10E3E0006CB7FC105BD7F3875FC71370D28DF85FF3 -:10E3F000BE6B1D1FD7B18EEFE25F2ECCA0FF87ACA6 -:10E40000E34DDFDB8A1F77E7D2BA0FB78E4B9FB899 -:10E410006A44FFCC9407A7C36FB3C4E13A5F89ADE8 -:10E420005090AF1EFFD1235B237C7DEB19428EFD04 -:10E43000F8C4580C2E1F75F57F15E564FFD31EED4B -:10E4400021D666C9D3AF129F1D7BE225B74E72124B -:10E450008212D37BC760E04F2FEAC165122F2C7F59 -:10E460003894F68407D76959AAA14E0FD3FB37E831 -:10E470007D8AD3FFB2D4DE4629C3BAED544AB85CD4 -:10E480004EE5115E96EABD6E2D685F4F6906AEE3FC -:10E490001B7391EE865B4773FE1ACE7FBA653D1FF4 -:10E4A000E67C3B1C7F1EDBEE51A5ACC1F53D26ECA6 -:10E4B00083E529E955C8C0B700AB39BCC3EC3F9A26 -:10E4C0004F273D3CECA007B3BD39EFD3F1F5E9E7A9 -:10E4D0007376F8FAB6A2DBE8C6C4DB3B2733CBFB86 -:10E4E000B49013CB205957307EA8BE52219E1C53A6 -:10E4F0003C086F678F4272FC9D1D0AD9E94EB9B086 -:10E500006C187FFCD70AB73F96EDD93B05E5D73BA2 -:10E51000FBFE55D021A7F365BBDE702785FC4F5964 -:10E52000E53FF697613D5E13702F7F2A737FCB77AF -:10E53000BD97B1BFB7D5D83508FFDBBD2E48B22E89 -:10E54000DEEE5132C637F6292E5B1CB73334EDB5FB -:10E550002C8C6F86FD3ACE7BCDEAD8AB49B4435EB6 -:10E560007601D981AA71D4C3BEAF09F969DF7B4DA9 -:10E57000F806D02D7ABADD8127351A273F588DC489 -:10E58000AB78EC3565F3475D9A6C831BD46421C688 -:10E59000537E5DFC4715FB7D11EDBF7306EBBFA8F5 -:10E5A00042472EEBEFC59864AC820CF12947FFF18E -:10E5B000590AE8563A8B95C9D6F86A78DFED149770 -:10E5C00068859634C689A0107A7E60E9F7C1360D59 -:10E5D000D26C7CA82B93ADF1554F4B4BCCC3E028AC -:10E5E0005CA995A06936DCF8452DB23DAE2DC65F1D -:10E5F00021E209B063E7CE9DACDF3AFC56827E0C87 -:10E600008F5731778AEC9839420EFE9BB083F749D9 -:10E61000F1FDE867C5F4CD2ACA39A974B38AF6C4F6 -:10E62000BC93DDEA620B3DCE2B5D5588F472F0336E -:10E63000A529135D35AA9CAE5615AF2DC4F6077DEE -:10E64000B7157227344AF32C10F3DC5FF48D601F8A -:10E65000EB776FF137364E6470D54515C0784B5D5A -:10E6600064D1C60A36FF82438AE163E582E6A49A52 -:10E67000983C749C6D28EF19FE1E423C32F81F6EC8 -:10E680008B52F991369D9E3BDACAE8B9B3CDA0EF23 -:10E69000BBDA6650B9A7AD8E9E8FB7C5E97DF80E7F -:10E6A0007F02E977775B13BDFF595B829E352AE7CE -:10E6B000B779021F9679D33E58637B7835C6514CA3 -:10E6C000FC39F15DCB282E87F60D241DF13D5AE56E -:10E6D00072C589D7D6D620D9A5DB24B0E1739ACAF2 -:10E6E000EDC8B880E3696FE23215F7F9EB4ACBC9A0 -:10E6F000EE81B881727A9B14BFA782F1CB81A2E927 -:10E7000051ABDC0D051371D5422F63BB787C66BA23 -:10E71000CAE5531DACDA9FC5E08B9D041DE9CC9C76 -:10E72000E7BE6ABD10E5E2BE550C9E72FC2E439911 -:10E7300085CECCFE660AF82098594E0FD22DE7FF01 -:10E74000E8CCB2CD1827668EA7314127ABDBD66E59 -:10E75000B36AC6BD75A263934E18FF1C288A503752 -:10E76000DC5F6C2EE6DF7D9CCE5BFBDEA3F856748F -:10E7700014D8E28D1DCD32F9395B0FF3B8F489E678 -:10E7800092CD1359FD6A8637F4DB73E69566252C26 -:10E7900074BD51D0D3566F3C4B1B417F758A7A664E -:10E7A000F9902FF12D5C97EF8EFB493ED2F356572F -:10E7B000EA5A948FAD873DFA6A36A593817812BFE5 -:10E7C000C70BD97B06D289BA951E9A5A90EF3FB4EF -:10E7D000DEA56F3EC7C2E721C3CED7DB5A478E4BBB -:10E7E0009B706F43B84788CB9A709BEB71A2AEB118 -:10E7F000FF1B30140FCE7E73E6358E38FE83C8774C -:10E800001EC2C3362BBD15B668B4CF60B637E7EB72 -:10E810006CEF9CEF60BEC299EDCFF4B82017D7F330 -:10E82000B1BF8CFDE98B804B1E57508E5DA7267AB9 -:10E8300010EFD3A085CAA0F6E723BFFCD6CFF970AE -:10E840006BE723F9C4476AAA18F5C2998ED701F17C -:10E850007835EA2D4336ACF2DC7CFE4235E30469C0 -:10E860008A1FD116331B520EDC15CD84E781FE0BB7 -:10E87000D577ACFB491B01B89F9EF6D23E070644F4 -:10E8800034562E3E0895EB597F3B853CA956B95F1F -:10E8900078C1417DBBC2E3474A43C88247114F3527 -:10E8A000E3581D701768ACA95BADD88BD54D3EBC45 -:10E8B000C29DF82DE2CB1DD569FFDD1549105F81A2 -:10E8C000887FCF1271FA4B95C301945FADD01B388E -:10E8D0001FF9F99002E41727C6135F5E34CC3EE1BE -:10E8E0002E619FEF10F2FA1141370FA3BC66CFEAF9 -:10E8F0009EDE34B2F4AC875373F0F99090DF292197 -:10E90000BFC355FEB4C4ECCEBBA71D4DB43038BA5E -:10E910008F1E5770294D793153C067CA87993E0EB3 -:10E9200047B8BFF366B4BFB7A1FC473DE73A30FE36 -:10E930001E86AF8E84DBF0907C89D7B5E03C0A65FB -:10E940009AC7CF0B6B641F2B3F658081FD3DD816A6 -:10E9500023389EF2F6BFFF22C6F767B98D247B1FCE -:10E960003E79FF2DD86F58FDD13FE0135213F8FCCC -:10E97000855C32F9ED59D70109F5F9D38540E38576 -:10E980004FEEB90DEDE7F0C9E76FC77697A4A03653 -:10E99000C0EA072B767FF97CD67FD6E532A0091A2C -:10E9A000ECEE4F74B3FAA5AD2DD538B57F93D201F7 -:10E9B000FC9E9CA7921C1C0BB15518E7C8DB9890D5 -:10E9C000F07BE8418EB78BB6F4FEAA1A109FDA3EB0 -:10E9D0001C6FBCAB98CB5FF9B939B8F7E2297AD391 -:10E9E00087EBFAECD11580F2CAF3814CFBF14F7F33 -:10E9F000B002BE61CDAF38AA668C838D7779F8BE40 -:10EA0000D5070BBAA7E89CBC907F66FEA9D64B7CC5 -:10EA1000FE02D8F661CDFD2AB37D859418EFCAA316 -:10EA20007D09BE7F25DA5FA4A02DC78A7F96F97E77 -:10EA3000693C15B0C641827F92E399ECCC2A974A93 -:10EA4000F0B41BB5477FCDC653A75F4DFA17BAED9B -:10EA50007038DB3138AA381C1C3E138E2246EF3E3C -:10EA600036FE53C77F978FF07D5C67EA95DE00FA2C -:10EA7000F97B4FC8C46F9BFA81F4CABEAA7D5EC4FD -:10EA8000E3C6AA1A3FB773383DE6087A7CB88ED73A -:10EA90003F51C5F7F5E1E429DAF77289EF3979FBDF -:10EAA000BCB457918C05ABA7A17E32FF58F2081871 -:10EAB0006E8A93F63C02B935C7562E8202477E4ACB -:10EAC000C9A05C453FBB2EF2FC38064A48EC3B57D8 -:10EAD0009BFBD8CA6103E7FF80A9FFDABCF4DCDE48 -:10EAE000F25000E31CBF30E9A4B9670ECE6FD64DDB -:10EAF0003DCF86D97C2E3ECAF7CD9C792928F75088 -:10EB0000CE6ED4D2B9563D0AAA87E031F7372E3EF1 -:10EB10006ACF5399E5C84319928F75967EE572972F -:10EB20003DBFF0046C9C4474D15B625B9FED173277 -:10EB300037E6FCA1FEE540BFC27F8228976F3942CD -:10EB4000AEDC7D87D28CF651F8B2CA6CEB7E68BB26 -:10EB50008BEF9BEDFFBD0730FEBEB6D64B711B732E -:10EB6000DFDC5CF70D986485F90DED3F0B205E9FAF -:10EB70008C94F8F0F9ECCC9D245FCDFD7F8F98D379 -:10EB8000EA993BBFDC8C72294F269DD251B86F0C9D -:10EB9000EE27DE5BEBA5FDFD70A0AFE759560E7EBC -:10EBA000E436703FFBE9EA7493D55FFDB18BEBA5CA -:10EBB000FB5DC2CEDA68DF6F66FC70BF8B7DF70449 -:10EBC000E3B45F297B459E84C3AF31F111DE972FFB -:10EBD000174FE6CF92C983F6F883827EB60AFF66A6 -:10EBE000A3B0CB9DFD14376BFBDC68E7DFA4552A8F -:10EBF00019F8735CABDD2E286AB1D3FF98663BFD34 -:10EC0000878C02871D9126BD65EADFB5BEE078B42A -:10EC1000BF2A997EE4F680265BF7D79DFA77A71A7C -:10EC2000FB99EB2CEC907020DE82F876DAB5FB04D1 -:10EC3000DEFFA2C4D288DF801ADF47FDAA719237B7 -:10EC40004E3B61089CC0E09C3C229CBF3A1B384F65 -:10EC5000B71FF0911CDFF22203797616883C8B10E7 -:10EC6000D91F1D21EE9F74B8B85FD02FE8E80D972B -:10EC700042F33B26CAB303D092397F8CC7878EA359 -:10EC80002182F54667CED7450B85BE8FC9FCFDB8FE -:10EC90008BEFABCD1E37F2381F88717EADC6FEBF3D -:10ECA000CBB26FF3A42BF69EB5FCA18BEF830DAC1A -:10ECB00087C8C735EDA53D6AEC235786BCB49C795F -:10ECC0002AEDDF9E00BFA130FC3C930FBB81C991B0 -:10ECD000672481CFDFFB488F99F81EB0A7517EA033 -:10ECE0003E381C4861FCC45C0773DFC59C87693FE4 -:10ECF00094B9B93C6174E37313DC71BE3F08699247 -:10ED00000F05826EB6FA16DE53CB9E77CF7CFB35AD -:10ED1000CC4F78F7099F8E706DAA3A12B6CA4D682B -:10ED2000B6D38FF9DEF5F118DA97BF554A8C765BCA -:10ED3000E328917E37B67F46D2C97F4BBEA290DDD5 -:10ED4000FB8C949A44FBE82AD0FEC533374653EB3C -:10ED50002DFB1B4EBB3EC7D7F7C0729C7733B39FCA -:10ED600060E8BA9976B959C63C106BFBF96CD9B911 -:10ED70005DCDA6CBF8BA42CCDB50630A100926E879 -:10ED8000391D747A32FBDF7033BC5D00FDF9C84772 -:10ED9000AB03632FE2F6C67F1BDE66E378FFDBF092 -:10EDA0003648B74E3DCDF719F2041E42D042FBED76 -:10EDB000BF685ABC6E021BCF5D18247B35AFA9FD1E -:10EDC00066398CD97DBD1AFA977962FF1B1AB97E14 -:10EDD00036F7A373EAEDFADCA9BF3DC2EEF00CA34F -:10EDE000D79D727338BDBEC46DD7EB03F1E261E409 -:10EDF0009F335E7C7AF9A7DF535B8C7919B1576B2F -:10EE0000D9BAEC9BA5527C333C1EAE8B5BE8E1B0DB -:10EE10005BA1FE0EBB791C643DE3D7D4399CCFE1E6 -:10EE20001CD4074C01E1FE41919CC2FC9AB5C95427 -:10EE30001DE69BAD552768D675AC2E62762DC3EBCB -:10EE4000A61A7FB3D5DE7ED3EFE271D840F541E458 -:10EE5000C7F260AA86DCBB1873FC46F13C4B5CB77A -:10EE6000F334E8C37D570F70BDCD38C2CBF54AAD42 -:10EE7000F616E56326E0546024BD60CFBFDCA9A68A -:10EE800056FB111F111E6F096D91281947E989A5BD -:10EE9000D17F981C58B095E4901A2FC371F64E6339 -:10EEA000662FABFFE15E37D9393DA1312ADA95CF24 -:10EEB000C88BBFE766F3ED7FDD03B87FD2F3D9B926 -:10EEC000748EA12774D15CA4831E099827CBE6CF4A -:10EED000F88727FB4000E3F4E13931C03865FF2FA4 -:10EEE000C078888DEF8AFE344E79BA100BC833583B -:10EEF0003B1F7461BE8AF1A9FFFD4B18DD3D1EACBE -:10EF0000BCEF7C18F4FB4D7FFF627FE231E4C78EDB -:10EF100051BF6B463EEB62702A6487C5A2087765D5 -:10EF20009E4CFC0779C1D404F6BEFA60A416F3CF58 -:10EF3000AAD50A94340C0EBEDE877C892771BEB533 -:10EF40005A436D36AB5F7548277B656EF4E6FD5816 -:10EF50009E7698973BDC40F620F22F58F8AFFAE304 -:10EF6000B134BF5F0A39DE1E8DF5C6A411D64353F6 -:10EF70001DE737EC792B563AD0A6D9E820E1B2D27A -:10EF8000C10C460793AD741093CE860EBE8D5838D3 -:10EF9000237EE17C729BC2F96628DDB77873CA874D -:10EFA000F28739EEFAAA9C08FA19261F68D3EFD225 -:10EFB000B0EC59E4267FCFE40B931F4E7AF9BE02E2 -:10EFC000E38B3A1F7B3606F54B33F105FA7356FA9D -:10EFD000BF72183E990FFDFB31C77EBE0AC92C26B1 -:10EFE000427E7DE1D1D2B116BA77E269FE2C098E5C -:10EFF00058E4D1A953BC6CC1A33690F7AC9C39BE80 -:10F000005F56F58E8885EF3A99FD8C4661976C4086 -:10F010005E31F2DD62BF07FDD5FAC7A214CFF7C497 -:10F020009B294F6DFA3B811B181D7E384AD671F221 -:10F030001DFAE247897F5F0B00DA6D9BA62D1987C9 -:10F04000FEC9873726C6A13FB68EE1FF081937A94A -:10F05000D132E53EF58DE6FB637A943F1351FE1EF7 -:10F06000C4F79428C744BD3EAAC7D6D9260F377B1C -:10F07000397D6FF6723B709DBBDB8BFCD55FECA5D9 -:10F08000FD53B3DE250AB7DB6678787D38B946C70D -:10F0900078D50C0F6F775F5B2AFEE6048473073D1B -:10F0A00073EB5380F17F7F5952C7F8BB7735243219 -:10F0B000D97DF779791CC0BBEF9F68DF28B7D4A052 -:10F0C0003856A49EF56759AFF90C35594C7E30700F -:10F0D0006348C71DBA9FECB0F9919A3FA95386AE19 -:10F0E0002FFE39625927EF5F95440FC50BF87EC696 -:10F0F0004AE1CFD59678892F3A5ADDDB712A0B3C4D -:10F10000D9DC0E8DD48C982F8B7E53D283712E2F09 -:10F110003D713F23790EDFCF487AF87E46D2C3F7A0 -:10F1200033F089FB19F81DF733B0FC93B6189571CD -:10F130005F03CBB8AF8165DCCFC032EE67E0734FC1 -:10F140005B333D7FDED642DF9F6A6BA5F2251E6EE4 -:10F1500067435932BA80E1B9EB76770CF7A9D789C2 -:10F16000F5793656926BB075F445B8DFE97BE15E10 -:10F17000C0F9F8A23C6ED419BD17AE67CFAEA9A1F5 -:10F180002EDC2FF63E1AA4A74FBD0FF420EE4F241D -:10F190009B3153B6C5F3C41C95E9F7D2E8CD353998 -:10F1A000AC7CABE7C93518BF9AA8AF32166B836544 -:10F1B0003D54B9E4314B795CF976D5CFEADFB9F645 -:10F1C000E935C8A708071A6F1D9EF49C556CC9D372 -:10F1D0002540E735FA8BDD29A4B3AFE17A21FD782C -:10F1E000B85DFF655813453F799CEEAE44FE60F56F -:10F1F000D39C2ECFACFE3ADC94CA1BDA6EA47A7292 -:10F20000D519D5036584FEF0BB34423F1DB046C31B -:10F21000B3631B9097312EE80B909FD6E5E27CD923 -:10F22000E5E3CFA35E73FFA8669E978D3B4FF06921 -:10F23000972F5E87F9CAFD93658A17F4B858179817 -:10F2400084DB5AFC9B1236EEADCFAB8071E694871F -:10F25000DB3713C685B8BEBCD34BFAF24BE37EDC7A -:10F260009EC3CA13BE6F18A8FF3680E1473A496EA5 -:10F2700094693FF74755E3731A58F5F3A63E918317 -:10F280007184CF047FA7F07C112BAFEAB8611CC654 -:10F29000953E7C89CBA547C538DB5DBD2DB49E531B -:10F2A0008364370074935DB02AAAD23EBC9CCF9F82 -:10F2B0006E97F67758CFCD146F92C1E3FE6CBA9774 -:10F2C000FCEF8F3DE25C5A2FD90B6E5F42CB66EFAD -:10F2D000BB9332F1FB1ACD9FC2D4FB0DC14A3A2732 -:10F2E0009B2C5729CF7A43398FD3054257A7D04E4D -:10F2F000B867AF8FCB87A097F2AD52E5BB0FD6446E -:10F30000F0296BC8EFA9D8823AC2BB266B94B7C567 -:10F31000FE46DF9B239497BD01C4BA34F37866C7D9 -:10F32000A84F7F85F1DB355FD70C715688F21EC977 -:10F33000B491F1DC6EFFBE00C2F315F39C51DFEA1D -:10F3400000ABDFBE5833701DA66835751827ECD0AA -:10F350006ABCC85781C9B5DE45248706F292E93CEC -:10F360005B7B39B757F13BF225B4C37E3CBF3246D5 -:10F37000C8B24076A584764E473D858D306FD796CE -:10F3800067D99E7319E5B12BF37308CE0E8879B156 -:10F390007EB29EC79DC704BD69B4E3C698F1434CD5 -:10F3A00031B6F811B937D9F394F39B55DB398ED1C7 -:10F3B000097B394FF805798E7CE64F3DE63E8A1D84 -:10F3C0004FCEF9E6461ECA467873F160B23E743EEF -:10F3D000F7452A1B709E63343FC11DD55657A3FCC9 -:10F3E0001A0D2DAB90EECE1A5E079C53CADB7B71D3 -:10F3F000DDA7E82A9D5B381FFA5763BF1B049D7782 -:10F4000015DBF564CAC3FD06C68F95C88F18E74A99 -:10F410005AC6C7386FD232DEF8AE1C5B79427781AC -:10F42000ADFE395B4A6CDF27A5CEB57D3F6F47A5A2 -:10F43000AD3CB967A6ADFEF97B6A6CE58AF465B6AA -:10F44000FA171C5C602B4FEDFD3B5BFDE9AF2DB661 -:10F450007DBFB06F89EDFB454757D8CA17F7DF610D -:10F46000AB6FDACD4EBD58EEFD7CF6B207CF75D945 -:10F47000E282767BDC694F7BFFBA465F8D722DECB2 -:10F4800026FA56518FB3F28ADBB93FE39D6DE82827 -:10F49000574A841C0D056317E2BA5587BDA40FD4E3 -:10F4A00020AFA706E792DD31760B934717A015082A -:10F4B00003DF032897DB92F152D720DC3EAD9BCED1 -:10F4C000285487EB00E3BD667B558B412284E3E93A -:10F4D000DC9E61DE22D6F3E9ACBD651ECFC8321DCD -:10F4E000E9EE677ED74316BF6B383FCBE9579DA93E -:10F4F0001F3556063F3EB74BF1167C96B7BC54837A -:10F50000E974CCBFFA0AE261933BDEBC1DF7434AC3 -:10F51000FCB42F66FA575DC53DC417FDC52AE9172F -:10F5200050F5F20596F8569797CBFB80F701F2EF6E -:10F53000D492190775C4FB2A95E20E1B241E1F499D -:10F54000B27540BDB66DE6D1F7FE91BDF79678C7AE -:10F5500078993C329E75C770BFF33E81D712ADA239 -:10F5600086595CCCBE68D887CF893AB333D8B3AC60 -:10F570006CF33E7CDEE1E5F974E71A8FD5A02CF13F -:10F58000CEE6F69F32C59D5A8DEBA7713886A33320 -:10F5900035670BDFAF2A55DF427A436BFB943C485B -:10F5A000073EA403899E443FBE4890F4860F0F7720 -:10F5B0006159955201F63D521A9330CFA23ABC855B -:10F5C000F6557C69BBBDCAFCCD2EC46BA4DEBEDE85 -:10F5D00001EF3682AF5DE2F1D7AE6CFD851A067F92 -:10F5E000575E490EC64E303ED16091379B85FDD6A1 -:10F5F000E4934DFD4FF24646DE983A68EF30FADF6D -:10F60000228F47F8BA01E596EFAE6E407AF7696C43 -:10F6100035D1DEFE5692E8DFB4776F11BC555BD270 -:10F6200044FB5EEF472AC9BEF5B5FE2423FE7C7D70 -:10F630000AC42E181EAFE1895B49DF43895B47BBD3 -:10F64000A25577C7B667900786D007EB30CF03E1A6 -:10F6500011791E5D021FE6BEDBFB66FE93D807BE76 -:10F66000251B6CFB7FB7E4558E1EC91EF731BF2FDB -:10F670006181771D1B07F1D271B2A12E4EFB80C0B4 -:10F68000CFA57D56BE9DCEFF0AFFC510F6CB0C0F51 -:10F69000C7EF5837909F3007E31717A0B7F9E53A3F -:10F6A000E44B33DE71C49B43F83792A0B490BDE2C3 -:10F6B00032F5967CEA7C8259779B714A3279B95E41 -:10F6C00063FFEEC57314E3BBECE7932674DBCBE773 -:10F6D0006CB19727A5EC6566351F42BBA001387E4B -:10F6E000CEDB61FFDE60C6F96AF9B90A2F1BF91497 -:10F6F000D7BFB673AC20F4BF194F2DEA4957A37892 -:10F700002D5C69D7AB0542CF1738F4676548213FB8 -:10F71000BFFA60643FDA8F66FCE510267F59E2A9E4 -:10F72000661CC529CFFD873703FB42FE72C2C3E3C7 -:10F730000B09E6DFB4168AB845117FBA14FDC585FA -:10F7400064A7B59C83F2E9696FE2032F192DF67364 -:10F750000FC7EBD45F483A1F276119E7B6B2E497A9 -:10F76000F8F453944762C6314C3FFD642036CFCB4A -:10F77000D67D83F172CBB318477ADD03D8CFA5CA03 -:10F780000B07DB587945914A798FDAF49BBEE7C7BE -:10F7900038207E67E5EA627D34D1FF732EF2D7D739 -:10F7A0000A7A36CFE398718F6C1FB79F433ED32EF2 -:10F7B0004AFA455EAB1FEDDCF37630D96CD3733C6F -:10F7C0009E66C6CD26F7D8BFF78094ABB1F53BBF98 -:10F7D000292573BB2A16ACB6C4D5CF15EB356561A8 -:10F7E000FADE85ACBC0B5295783F4485A00B63BF15 -:10F7F000FDFCD72890E89CC0A8438A9162F5A73CFD -:10F8000065FF5EEE381F76AEF3BC9823CE1B52E048 -:10F81000BD456CBC8D7A8B84F273E34266C3B3F250 -:10F82000B93E912F3C112622FD5DAA048D34E2F7EA -:10F830001585F486E78D735E5D84FAFC259E97A29C -:10F840008DD737D7B2B2F62B85F49316808A8AE02B -:10F85000605CF8FE5306B4BB06E34C3BD9BA964E47 -:10F8600040FFDA0BA8577EC2D617CB3DCC1FC7F29C -:10F87000E3CC1FC7E76EE68FE3FB9F317F1CCB7B9A -:10F88000983F8ECF9F337F1CDF3FC5FC712C2F0F1D -:10F89000545FE28C5359E3768371AA3EC98C53A11D -:10F8A0002839EED6699D07E255091EAF3A7D3F31F2 -:10F8B000B31F8A070EE947C405DFBDFD778FE079E6 -:10F8C000E9A5535777E1B957AFCB8C8BF13C08339F -:10F8D0008FD9E4BFA5BB6FA6FD6077FEA1165C8F34 -:10F8E000DD5541BA53C8ED4A68281F9DFE97E97758 -:10F8F00039ED5FF3E9D4477EB4032E403BA99BE288 -:10F900003EEB5D5046E76025BF817CE18C439A7CED -:10F91000FCA2AF24E3F9A5817C58119FF140CA8B6A -:10F92000F132B724E629F2354984B12E36203F5B07 -:10F93000F28B83E5698A73048331B2BF24669791A1 -:10F940009DA625A21887EA1C26FFF541C1A7ABF2A8 -:10F95000DD746F44673EDFFFAF2D34A2D87E4DFECD -:10F96000B4A8351FD6CCD7DD1F9AE6EDB3F4B72285 -:10F970005432A29E52985ED547D0AB8A87E7ABAF90 -:10F98000D977A117F390D70717F7A27DB53E1AA133 -:10F99000F3EA7BF3A791FD31503F3A83F29595202E -:10F9A000B75B95A897EC5615E75F3E58DFACD72AB2 -:10F9B000E433633F8ACF05823D54CFA3C629FEE1DD -:10F9C0008900ED5779BC3C5F20C8FC6BAF2D6ECA37 -:10F9D000C7BDD9C7E5DB7A3D11C776EBA3AA8EE296 -:10F9E000687D5925E1798DC0F39A3C53EF1B646F14 -:10F9F000F4083968F6B346F8EB6B9ADD6477C55BBB -:10FA0000B363B5B9947FF903E4BFF5C187BC98CF60 -:10FA1000EECEAF1AB1DF27C5FA0DDFEF1B35B517F4 -:10FA200050BF3D3E36BE3BB458C37E5DC3E4D91FD4 -:10FA300014707E5EFB92614EA3FD2E30F56D2A6A36 -:10FA4000DD27763EFD68275E30B4DD52BD6F2EE6C1 -:10FA5000F9AA90ACF32B43CF292CDBC3EF9DDAA49A -:10FA6000F692BDB3E9A494F1BC43965F12CEFE803A -:10FA70001F6EB357C6087E1A23BEEB68AF14A35F90 -:10FA800069B72F2E38682F4FEDB597A7BFE6B4574B -:10FA900062AFA0BDD228E45D2F93CF3C69A25F4541 -:10FAA00039104FA6AA11EE06E85985FB942E11676E -:10FAB0006E14FAEA0AA1CF5C7E1E971DD3ECB7F94B -:10FAC00089E6FD1985A2FFA2DAFD37B7A3708D9BE9 -:10FAD000F68F4EFE65D1BCC7AB494C3AECA0869878 -:10FAE000FDFCE9150E3BC7690F55ABDB29BFB2C062 -:10FAF000117F30F729719E780ED739FED98E6BF6BB -:10FB0000B795E92DB457CC7B09E8DE2ED6BE484D1B -:10FB10004B06C353410B50BEDF989510DB9E818E80 -:10FB2000A789751F82B7E42584B739E25D4190DF6C -:10FB30007B5250ABA4F462CCDFEF21FDBDE0263652 -:10FB40001FB2974FD13EB4593F27BB672FEE136EBC -:10FB5000AD97B8FF9804B243CC75DE1AE4E7651A96 -:10FB60002E965232B66F29A1F109AE92C1F5657891 -:10FB70003AC2F1C4F3CBAEACB39FEB6970D81B268D -:10FB80003D5CE178FFBA4F23FA30F9E0DD0B5F9B73 -:10FB90003896C1B1544AD6059433D79316FE709D5A -:10FBA000423EC4BF8FA2A9107FECF3FE54A3FC8099 -:10FBB000ECBE078091E4657E48D6CE02F8377FFF21 -:10FBC00079122B37F8CB3BBA2EC6E389FD3F42A30F -:10FBD000CCE3A9B8B4AE68B0ECF75F4CE588188701 -:10FBE000B91649BEDE967B0A18BCDF15F9011B6207 -:10FBF000B059C11C4B59DB6C140FB6CBC176D2087F -:10FC0000EDE2B059CDD02E68B663E8EA34EFF528BE -:10FC1000C127FF2E0B78ACE3AB88374D0FD2B99DCF -:10FC2000B9AA86790F5F148E51A79B770236BBC69F -:10FC30000F6DC7C05E65C22F67863F85DFADE3BB32 -:10FC40004680FF6F8D8FD3F5E716DFCF1A3E567DC6 -:10FC5000F5A8E1E78B70B9E87E0C3D285BFAB9673F -:10FC6000EF2714BF56AF053A97A3BA629AC1E8BC12 -:10FC70005CFB36F9E16A76AD8676C03A56463B6063 -:10FC80005D4F37C5A9CB4BEFED42A22F4FFB01E5EE -:10FC9000C164D0B277B17E276B2A66E2807AF17EAA -:10FCA00019E3DE7039D0B990ACBD7E7E8F45F1CCC2 -:10FCB000EFA37F949DEDA53850207BDAF7B9B1CB47 -:10FCC000E3C126FC81EA43351827571BC040565430 -:10FCD000A5145423934D02DA87F0C776DF86E72B0D -:10FCE00099E223FD44773BA05E1571F1D19C64A09D -:10FCF000CBAD35A09F907C5EA5F8FB68BCF2861169 -:10FD0000657979CE6684A73CC13A90107E1ED79A59 -:10FD10009C908D34EBBFF23DDE0EFE9D9F0760BED2 -:10FD200044D313C141BC9A7265B488974717DAE38C -:10FD3000C9D0CFE6CCDA57FEFB821F603C61D410FD -:10FD4000F9CDFD6BF3DE9CACF720FE04ED6BDAF52C -:10FD5000865FDC4FE177DC7B302E683F8737C46FEE -:10FD6000F8569CF480070CAF9BEC8B85643798FEAB -:10FD7000C856AC88F1FF22E079D9CEF6D3787B88DB -:10FD800072FFC4E367665E25FBBEC41FA37C1F0F22 -:10FD90002B333C4A6EF0E6B3F705328F8BAC9240C2 -:10FDA000C5F2E07869DAA75F2B195D8634E8FFAE0B -:10FDB000D10CCA1F809539367BD9CC435D7163F174 -:10FDC000E81CF6CC1A3CFFA3213DAEC82B25FB391D -:10FDD0009CDBF7F7285F8FAF5F7FA917E529E62F38 -:10FDE000CC04F8ABBFA323C9E4ADE7E331A05BECDF -:10FDF000328FDA427130CFC7636DEFD36DF6F38285 -:10FE0000B1A05C8BE3E461F23EC683416BC776D55B -:10FE1000603F17E8F938DF66A70FF65F687B9F66DB -:10FE2000F68CF53E8AE1FB0F805E66ED7FFC30FDCF -:10FE30004F74F4AF65EC7FB0DF5C5BBF1D2A8F8F22 -:10FE400026237E5A77A73D3039505310C81B217E98 -:10FE50001FE0F1C7B5D1168ADFD700637846279730 -:10FE60009C3CA2F0F36B40761B14DAE3F735827EFC -:10FE700065461148BF97A8F67BC06683F35E30BB2A -:10FE80003DD48B8C827E65A8AA97E2F89F0475F416 -:10FE9000BF86B3977BDB80E2C7B3037DB7E03EF557 -:10FEA000A51B1E7075CC10F9AF05CC8ED8D0732968 -:10FEB0009EF3EB15E7F33A2232E1255E339ACEDB6F -:10FEC00098FDC4DD3001E5615CE6F909F4878DDF5A -:10FED0009B57F0D0FA0CF8739EE76C8849F1520BEF -:10FEE000DDF4CA0CAFD6F1E68CD9AE58E611F7C0F6 -:10FEF000541A4FD8B903E38DFA7CE3BD24E24EE6F1 -:10FF0000780D73EDF36B706B34BF06C1BFE6782FCD -:10FF1000E1FC32E0F7B4E3C99C6E06C6FB927D7E3D -:10FF20000D1E8DE6D720EEF51D186FD4E71B6FADC3 -:10FF3000AB258176DB6689F3FFDD817FED40BFED88 -:10FF4000FDFA1551D207C22EBE021BB07A57A87C0B -:10FF5000BCF985DED42ACB785B991C88893CF7985C -:10FF600007F337342AA7DAA2F47C88D9D931CADF5B -:10FF700028A3EF8FB41954DED136839E663F6533D4 -:10FF8000F83D3393664919EDED5F06B8DFB8395F88 -:10FF9000BBF66BA897AAFDFCFCE38C8B2066B17FB7 -:10FFA0009941BCCF87FB2F574305EAB6895B38DC04 -:10FFB00091DA51295C3F7FC5FEDE3656F6B85C3AD1 -:10FFC000EA53C60BF14C7EEADE00F7C33D6E2EEF1E -:10FFD0006126BFB770BED02BA0D44B2EC4C715D995 -:10FFE000B4DFBFA03116D218DE1A25E99552A1A7B9 -:10FFF000F0FCCA5562A99C767E043506EB37125395 -:020000021000EC -:1000000052781FD15585079B502FC74357927F10B9 -:10001000670D73583F57093D59FD860730DF012EA4 -:1000200075131C8D8D767B7EB32FADA17DB2B92269 -:1000300002B83E0BEAEDDF3D6ECE8771C73D05F39A -:100040004F736F01DD9D95218FD4199F7C32608F96 -:10005000439E80F27B6AF1636164C47B0B5604C0EB -:10006000BCD73263FCC884E74D94635391DEF650ED -:100070003CCC84AF404D4928AFC734EFB1E53531B2 -:10008000C492316CC6E141D955817E88733E5BA52F -:100090005DF923DD535200EA5B7D65E21E4F69E89E -:1000A000BC7F1710F9B703F39EF5622964E21F1EA7 -:1000B000779D7F503156E9837831F1F03FCD479DF0 -:1000C000018ECF17E77C50C5FDB742DB7D99E63D39 -:1000D000C0570E9455502DF47CC51237D93310EB10 -:1000E0002F47BA3B747180DFDB66DA2FE9D765B43E -:1000F0005FBE78FFB1225BDEA6E877B8F572E61145 -:100100005ACE7D0EE6B9637E89C4F7B10A30CF2D91 -:10011000CCDF1FB1DB99B63CB7357B7F28619CEF04 -:1001200001CCC7B3EC5B8F61FE3CCACDC29BEC79BE -:10013000754EB8CCBCAA8173B3B31AB55D3ADD93E2 -:10014000D88D17CF746D49C6C1921F699E1334FDB7 -:1001500069E7F94025C8EFCB8B8AF316CE78F06DAE -:1001600072522B96301F35E5AD66CFF29C848147E5 -:10017000D36F539275F85E193DB319F1B0B0F54ED7 -:1001800003E3775A6EE6B8F442A1BF2F0A72BA3978 -:10019000EC4A17611C3B91537351302F43FDD66FCE -:1001A000517FB387B97FBE51F4F380D0E7CEEF978C -:1001B00007795CE59AA532DD67E183504A2AC67D5E -:1001C000E3EE19742E6FD95623D3B9B783E144BD3A -:1001D000151E5F293F6F0DD07321E26BDD5F1EECB2 -:1001E0007994A132E72F4192A3390AEFD7D2BE31D9 -:1001F00053FB673EF92D9D537E06CFA9CCC4FEB6B6 -:10020000CEC5F8F7A6813224252C678B72F2B6B9D9 -:10021000E8EF0D962BE6566319699011D9ABC1DA58 -:100220004EA4974D120862BC94D777F1FABBC5F77C -:10023000D997BDF37D3C970BD3DCE4076E12F688AB -:1002400009DFEB419E37F3FA69F079ABF81E447C85 -:1002500046CE0A9FB766C2C7EB39B1DB8253B19F66 -:100260001EBA17D2F717EF4ACC23FEA73630BEC608 -:10027000E6F080B1FB87F700B5FF5670EAD0F6F3E1 -:1002800072626DD86F70E9119A5FA83488EE0DAC78 -:100290009B0ED44F0638D666EAC75CD774169763B0 -:1002A00027D076CEC375E5F69FE2E98DE2FEBF5614 -:1002B00075FF2D1A93239DC5DD4D99E8FB3B21BEAB -:1002C0004F9D3D4CBC7A97A0C757B5F877118E76F5 -:1002D000ED5EBA4FD52D71BB61DD8C3E902CED7E6D -:1002E00015E2F519DCDFC3FAEE0BF93DA72186779D -:1002F0004C300B5571F8D7E98700F3BA43D14394DA -:10030000171AAAEA237EA7A30A059CAED05FF30AB8 -:10031000FB6C57F0DAB94817398A49777FEE443ACF -:100320005406CB4497DB7378FB97427FEE4C3291B7 -:10033000BB8DD92F78EF46B280E78D38E7F72F21B4 -:100340004E1FF787638F23BC43F0E9E9FBFE3DAC0A -:10035000FDA609FCBCCD6CB9B7E97AA4CBCB82640D -:100360007FB1F74DD673C86F0A7CBD19E4F6D3A6EA -:100370004FBCF4DDB91EC3D1EB0BA2FDE7A0D7172C -:1003800032D109A3D77F477AB3D0EB0790995E0F9C -:100390000D43AFAF607B275E9C6505625B707F5647 -:1003A000FD74EE0EEC4FFDF2AC2D8FB2A7F2E95DBD -:1003B000495A4D43B29D2F35C7A99012FF11B4C8B9 -:1003C00077F33EEE1B83BCFF21FD4E9FB605E5D8BB -:1003D00019F47B2C387568BF4F0539BCB32F0B2639 -:1003E000329D1FDF1252E9FB43213EFE707C7330C9 -:1003F000C4FDD9E1F8E65141578C6FFE7A267CF3B3 -:100400008741BE7187F2CE846FBE4D4F5F29E71BD7 -:100410003A863C7328DF40F2D54E94AF9DC59C2FA1 -:10042000466F7AB313E31C037C943C41DF95C132E1 -:10043000C963938FFE73D309E22367FBF030F75251 -:100440008D15F33E188E17E13C62E769EDFC9C4D7B -:100450001FE9EDEDD0BFD74379B63CAFD59F4CC671 -:10046000B8D9D00B78BE7FA2C0C336F4C1D0CF9923 -:1004700026E24C6A2F2C080DE5E75055BACA7A9F40 -:10048000C0D362FC0F43F1C9A1A9385EDF24B4BF19 -:10049000865BA74A31DE3DD9B1CA5006FE3F9D1E9C -:1004A000BA26C4CFBB5E23FAC9F98BB705ED4F2737 -:1004B000BFCF5EF6F33F3D32423F8DA27D7DE873B4 -:1004C000F37F7D2833FF5F1EB2F37F15DEB799817E -:1004D000FF1B33B567FC7F55E86FCBEF8B4219F8F4 -:1004E00072E619E2FB6181EF87BF20BE570B3AB974 -:1004F000E3F3E3FB8E61F07DE719E27B7528837DF2 -:10050000C1F0BD2644F6CAE3047F480F521CBB6B02 -:100510003AEC964A32C2B1C1DA8F57E7FD30BC7F60 -:100520002031BA9FFD699791E99E19D6EE5E2BFCAA -:1005300066BBCA9066266FDF8CFEF9035F0E52BC65 -:100540009FE9C7FBFFC674F050263A982D7339F423 -:1005500041F0B14E8CB37D81FE7F92A9FF6621D719 -:100560004F6717EC1574C1E6FD4468EA50F9B75DB2 -:10057000FC2ECAFDE1C45321C257DF3C9457DBEE89 -:10058000C891301E55184B4BE8273C2EF4D87921E2 -:100590009D9F6710EDB6A96909F359B6B568129E1B -:1005A00037B2F4F74B1C6FB8FE9C7030F89EC3F165 -:1005B0003F0CC59EC767A598DFD9DA490DD9B19719 -:1005C00043A47FE287486E9F6397DBE63CE478377D -:1005D000E5BDF86664FEDD96C783AAD063F1DF5BF4 -:1005E000E5FF2B0374C5FB3B5BFDC3E07B2BC4F530 -:1005F000CAD14CF039F1723A38F34203701EC77E0B -:100600009D7ACAD99FE9B79AEBE4469D648DEB0CBD -:10061000E8BDC45F897F3B643A87345FC893F93390 -:10062000B285DDAEF9B1FF07449CFC819BEEADC6FF -:10063000FDEEED77691588828266AEF7F49BC652AF -:10064000FCD317966C714CF339D0DEDD3309EF190A -:1006500067E386C2ACDE25B3208D7E6316DA0D1407 -:100660008FD0E877BB723CDD518C9FAE93BA9B165E -:10067000A35E9D17E4E74AA28DA7B9AF6DB58D6E55 -:10068000215A759AFAABA8BE16E8A6FB2FCEB8BEC3 -:10069000A7BB29537EC994B06CE275527824BC463E -:1006A0002314D732F13B741CBE7ED5F11609F11D1F -:1006B000AA92343C7A15627482F6925CDA4BF94C59 -:1006C0009757717A01E6978C7C7F46A769AFCD0A70 -:1006D000E77D71B8CC7AC38F27EA39CE2BE0BE17FD -:1006E000C567835C8E5145563E7E303763DCDF7CC8 -:1006F000AE6DD30A5597B5FF14E179ED40FEB41104 -:10070000457BAB15383D42D44B7618DDCB6E59CFC7 -:1007100084589FEF66C5FF3E4CF019740F2168DACC -:1007200019CD87B55B4CED54D62E74E6ED867F9AD5 -:10073000BF5767E871CBBD6726BF8E4E2401EF9986 -:10074000F1978326B1F58F84CC7D424E07DF0E9A58 -:10075000E5246D92C74BBB795EBE6ED209972B5ACA -:10076000A0272657006CBEBBEE4BD149ACBFD2448C -:1007700014AFD067E5032AF9E1BC0CC9BA03FB0B3F -:10078000917FB4732583E9A9F6DA03072F067E5417 -:100790008A7E4FADF600C93BB38C175294B1B27F3D -:1007A000A01CF34659B964A09CC4F236A12737DFD8 -:1007B0005D7BA03D48726CA3953FAA051DFEADE987 -:1007C0006FBBDEAEE13983645425BB6A9D831EF6A0 -:1007D00084F97D2C93B5C4365CD7F977F5AB787482 -:1007E000C55B1C09213F8C8B7E90C4FBF2C6CD12E9 -:1007F00069AAA5FC9E86EDD195C497DB715D80A7A3 -:1008000025607C72707D5299D7A72C45EBE3D7F910 -:100810007719CBE46FF3F85BA08CF3B3E6E1F1BD9D -:10082000C704BDA6C33C7E9416F2352BDA4EFE9467 -:10083000B74EA6F871569D6CD31BF48B77D44EB58A -:10084000DDFBFF7A4EE2A9B0452FB01AF132360F28 -:10085000FFA4480EEEBF5497A92BD1DFFE9EB0FF38 -:10086000D83A3D40EB5411F127486EC79FB5CA8F67 -:100870008175137839DDBAFDB62D61D4BA865FB7BC -:10088000ABAF5532DE93F6DB30F75F8F35FDE7FD1A -:10089000389DA5DE7EBABFBBAB7415C561CDB8ABC4 -:1008A0006777757A8C3E980FB83A109E854FE7B8F7 -:1008B000BF3DF95D8DCE897CE2C9B89F7452E0F9E5 -:1008C000505B13B5630B4CBFB7721D4E85E7B1D9B2 -:1008D000CEF199E711BE0A9C181AE38B2E4739B462 -:1008E000B849A17B1BAE037B3EC557CDBCAF563389 -:1008F0003F8EE77D25207B2EB2E1A2A4E3F722C044 -:10090000988BE7E887FC8E84D8DFFABA236FE29AE7 -:10091000A64546ADA8F73EFD3F45F369D4B9FC6D49 -:1009200034F8FD3D57C5AF356A2DFBD1AF7EA664C7 -:10093000CC9B9C9765E2236ED44E188A8FC571C9F3 -:10094000ADE9A7C7CB99E261915A31374F1F8A07AA -:10095000E7FC19C636219EBFCEF08C76E770F860B2 -:10096000F5683D5EBD56A1DF8F99ABD4BB701FE427 -:10097000FA0689F698187EC3222FAEFE520BBC4EA3 -:100980003C3AF175FDD340E706AEFF4E88E26D2F8D -:100990009BF8495F42FB17E6FE89659E4778FE9605 -:1009A00046F35C30A3E217786F42A25DA2FB1AD92E -:1009B0007C6DFB808B219E85E716D8BC8F0CB3EE37 -:1009C000B6FD40277C4EF87D42AF38F7C5404D97C5 -:1009D000A31E9C9D25F605A78021F6C7B2281DB74A -:1009E00034B3BC75DE3767D2D975AD0D03E362FF52 -:1009F000122406CA1A9ED77A4ED97415FBFB8A2890 -:100A0000FF1DC3F8B5B91DF86D3E98BF2F14A3FDA7 -:100A1000A6EB04FE1A98C787BF7D7609134EB8AFC0 -:100A2000373FE6D38396791EEF96EAC439AAACC65F -:100A3000C9D82EB957993214DE1551FE7B858C0E1C -:100A40003FB0D2A16F02BF47D68917135F8B06F163 -:100A500032E56CF0F22A2ACE3CDAAF213BB75FF2E6 -:100A6000D27978731F87FD35E966A2F3D6AC62614F -:100A70000FF0799BF77701B4907DBF509CC73AEC9B -:100A800082A6C7827C5FA7D222B76ECBA9BE35CB28 -:100A9000E2579BFB3AE67D51263D7FD51B4C2B9CB4 -:100AA0000E6DF7410DE63125288F49C9BA49477CBB -:100AB00074E1A70BC9EE5985FD2B01BE5FE57BEE06 -:100AC000A75D57E983EBB7FE6B4F744F6565FFD7A2 -:100AD0007F93A44EF51CC25B48AC5BB55837133E00 -:100AE0007F397F6F593F1E3F2B13F133B18EC3E91E -:100AF00009731DCD75433B0AE9D757A67E9AE9775E -:100B0000F7607F553FF26922AA520E5D427AB383A5 -:100B1000EED9027D1BEEBF5FD7EAB2FDDE5202CFF7 -:100B2000E963FD753EE19718D47E713E6F0F65DC79 -:100B30006E1CA0FB246B6FC903026F7814AE5B1FA1 -:100B40006B8B7962ACBF51A8EFA1CB324EC9D0718B -:100B500087EDCFD14E19D837310CC322AF1FCBE26E -:100B60007AF278B4AA47CE107F319F8BBDB985AA9F -:100B7000253FEC48BEB729E3EF0689FE06EE8D1B44 -:100B8000B013DF39B07FD6A09DB8C1F5C703078B7E -:100B90002C7622FCF100F9ED03E5B3B3135FCFFA35 -:100BA00023D9891FFDDE43FAEA789D9FD621B775C8 -:100BB0000EFC079EB755F1B7FCC8BEA77B6FBCAD56 -:100BC00063683E92CA3087BF07A61B12E2FB4896B5 -:100BD000CEF7637548871870B9AA2121BEEE15FEBD -:100BE00028A3B349D6DFFF3D22E66B8EE3F1421224 -:100BF000CF199BFD323A584579A5F5407AC4DC8778 -:100C000035F9D9ECE7589664CBAB3E03FE3D9635FB -:100C10007528FFBE20B7FCE11FD17E7D5EA17CD090 -:100C2000AF446FA7F757B75E4FCF6B5B6FA4E7C7B3 -:100C3000423FDF2A253E463EED6DFACD576E63F406 -:100C4000BA7CB787CE952DBDF54F77237F7A5BD9D8 -:100C5000BA63BBAF5FFF9DA9ECBB7B824CF66B57C1 -:100C600011CFE770AF9278BC5F77D7ED66CFE670B3 -:100C7000F544CD02D77F01C39B58310080000000AE -:100C80001F8B080000000000000BE57D0B7814D5D9 -:100C9000F5F89D9DD94792DDCDEEE6B5900713C2DC -:100CA000230AC44D202128D60D011A2B81A0A8515A -:100CB000826C0884008104B4B2552C1B021830D613 -:100CC00068B562B57C8B85D6B6DA06A52D6D23DDB9 -:100CD000085AA81463B50A562020B5286A228FB294 -:100CE000B6B6FEEF39F74E7666B21B82EDEFFBF734 -:100CF000F7FDE2D71EEEDC3BF771DEF7DC7367EB46 -:100D0000EC5347390A09216EBB811411B2CA42FF64 -:100D10002D1372F1E8FDEE05C984C45BAD1EFA84A3 -:100D2000989AB21F32D0323920921D148809647EFD -:100D3000C5580ACD0CBA1D122185000D081D00539F -:100D400008B184054292A09DC7D368A56529401CBF -:100D500000C3123E370942453B7DFF0BF8BB2E0214 -:100D600095FE2C619190F1309EFE7D133EDF249B19 -:100D7000CAE07D3189CD43793F9BBF9FCDE76309B1 -:100D800027B07924E9FBB1B3E722696CB7F69FC7B6 -:100D90007D89A5231D741D7576EF288084741B2B17 -:100DA0006C84DC61FDFD61218F428B35245248FC4F -:100DB000C68FBA7309FE7D311CFEBFCAF1FE184210 -:100DC00004D22D7C41879EF9B9101A46F11757229B -:100DD00006D765532838CA274CA0CD4A8C1EC06759 -:100DE000D78864DB70D5F8C50E01F1F7BAE4B0C15D -:100DF0003C2BA68915C1B1D87DCA1CE8675A4DD1D4 -:100E000066369C85A412329FFD9BBC2E6F6F194ED7 -:100E1000EB0301A36724A5E37C4B2008F39B4FA4BD -:100E200040B7059B085F080865A988BF47E73B7F77 -:100E3000AAE88DB36BDA912FE83CC97AB26F04ED62 -:100E4000FF0E810F10A065FADE315E3C3EF5DCCD71 -:100E5000B08C6EE2300DA7EDEFE8AE9E41F2B0CA65 -:100E60000AFCB488B79BEF379EEAEB97FEAF3AA037 -:100E70002D2F28CE7F859281E225583601F8EC0A85 -:100E800003F2594D8BB6DDA277AFFF80D8A15FE9A1 -:100E9000541FBE619EE461C66FD39A1D32C5D3381C -:100EA000878C749F39F5BDA9849667117233F43B22 -:100EB0006BAAE808D1D6AD7E03F1D2891FF28A4130 -:100EC00081AEED506EF781EB006FC5467907AC350A -:100ED000973C785332D48F77009E2BE0D9106C4F1B -:100EE00008B4735B8223E9B32EEF7BD61A15DF1D9E -:100EF0002A7EEF0A1FA5D75603A98BC64F8434E17B -:100F0000BCF6DD138FFD1C7F54089AE9FCA7899F6E -:100F1000FF61229D4FCD7D468F59C6651980AE3346 -:100F20003C4C1E09F15AA7517CDE4158F93D525103 -:100F300014A2E3D7E41F2D31D37E6A360828A70A0E -:100F4000FE29BE4FAAF1E66BAC480CC98877CD7379 -:100F5000DA9909F899E2F9640C3C9F54E3D9FFEE61 -:100F60009171FB54ED363B6CC9C0E7A480147C4101 -:100F70005173814C4E1C4FFAAF5B8117D71E1EB7C1 -:100F80006F24218F12EFC3A87748B754318ED2490E -:100F900022DE687A60BA9DC9C134F123A4CFD96238 -:100FA00051067C1DF27F68A51C460E7D2E96019E83 -:100FB0008997369A1479EF870E13E279AB89780115 -:100FC000CF5B875A824DB4ABCE7BAE4CEB46FAC8B2 -:100FD0008F4F063AFEDE4876C8B1E76BF38B6404A8 -:100FE00065CC72BF8050A1DF307F1C91C647DA0DFF -:100FF00023D1E7BF1BE498B64F59430C321DD719D4 -:1010000020DE6014BE50DA2DB7F44E9708B60F39C3 -:10101000E9FC56C886A040D79B2FC88CBF8D8DDEBB -:1010200074DA54EA981D4827300F11E721D3F949A3 -:10103000747ED9FE042C0FF72721CCF13B118EF0E2 -:10104000A763FD487F0EC251FE6C7C3EDA3F06CBA3 -:10105000B9FEF108AFF0E723BCD27F0DC231FE52DA -:101060006C37D65F82709CFF067C9EE7BF09E15516 -:10107000FED9083DFEB9589FEFAF4158E0AFC6E733 -:10108000E3FDCBB03CC17F27960BFD2B1116F9EF8A -:101090004538D1DF8CB0D8DF84ED26F91FC0F2D5FA -:1010A000FE6F23BCC6FF30C2C9FE27B11E1410E07C -:1010B000219ECBE303F242079514E07019F83896AD -:1010C000DC5DE4F668BEC37B1CF84E696732109F96 -:1010D000BABDD2EE1CB71B4EA06B94FE3EE1F4FAF3 -:1010E000C473F23BA349846E2DEEA60A2246E8653E -:1010F000DE55124AA7FF5CB17B3601BD40729335C5 -:101100007CDA5F3FB0F51DE3FA6BABD4E515817F68 -:101110001B8927401F954F785D807EB6C952593094 -:101120000ABF8D761AF1BD710EDFBFC05E25649FC8 -:10113000DA07FA6456C0F18729C02F63937F3F8591 -:10114000F6376CBD0146A0AAC4D13985EA1D792ABB -:1011500041BDB88D1094A76DF15A7B3ACCC9F041CE -:1011600048FBFEE1284F230A98FDE9BE1EE4CB743C -:10117000CF70B2391BE42D2448B4BFC02A42762870 -:101180003603DA6F5CF003A88FF467C2750E6B212B -:101190002F59E844B2DBE4297114E66CF1BE144720 -:1011A0005F1919F44D89A7E5D1CF045E0278457B1C -:1011B000704A02856376875EA2E6948C0B754FB108 -:1011C000D2F255FBC95E406B7E975C6AA3E5F1875E -:1011D000BD7B291B90C26E5FA95D86F9049BED74EF -:1011E0003E5B8F114F132D177FD426261215FD4D10 -:1011F000C4B7534517DB84AEA949F49F197739F278 -:1012000045785FEA8E738EED4F9F6DB06E5827B5AF -:10121000233BE8BA32BC21C1A1E2931B9C4C6F5125 -:101220003A5CE5043BB4A65782756E5BEFB221FDD4 -:10123000E21D253064EF34E2785A063E96104FA640 -:101240000DC351DE15BEA3F8BD62B64D8D3741D139 -:101250006B75ED6363E3F70627D37FFF2DF87DC73A -:10126000C1E421167E2DC02B932E2DC755CE3E39BD -:10127000AE74A6C46ED7C4F1AFC7F33603D94F6DB1 -:10128000151D97F229932B12A04DD770FEBE145E48 -:10129000EFFE2FE3DB9B9C03E395C8C9A82729BF7A -:1012A0005E417262EB1BE82F9AFD7A80E351A5E75D -:1012B0004CE02FB638A89ECB89ADE76E755E427FB5 -:1012C000713D63E27A5C196F0BE7EFFDF68AEF8000 -:1012D000DC58371802206725C4867241DCC99C4F50 -:1012E0001CF1C02733444709E81B329AA01F9D30E8 -:1012F0003618807DCAB0805C20423350CA80C7A1B6 -:10130000B9C1CDB4EB6CEA674894FEB4AB10408B26 -:10131000EC302CA0EB4E54E4CD51ED56CB9B62EF5C -:1013200023F2A8F0856BDBE66CC6AFB3A9FFF236FB -:10133000C753A41F01DB6DFCC6D06D9B557A709B13 -:10134000DB8D65A57D2CFEBDA0F0EFFA75C407F21C -:101350003139BADFF0BA53E47CDBEB053E0F7C8514 -:1013600038C09F71AE3F89FAC949F59380FA898DDB -:101370009FE18FFF418096BB9CA95C9F3BE26FB1D0 -:10138000FDFFE3E71D4EC2F4D46447A748EB875145 -:101390003B24839C4EA6739F00F83221DD65C2E892 -:1013A000284F2641F07B29DE4206D0BF065B10ECB9 -:1013B0008CC9D4E60579262627AE7FBFDD77DC39D8 -:1013C000805C3812E47C206AAF335C66A5FCB731E0 -:1013D000DB110FE58F69B9D54DC77575135E6EB119 -:1013E000A2FCD0BFA148C510DD1B807D54CA5E0B96 -:1013F000B41FDE570E40792BF82457D3FE1FFEDBB7 -:10140000FEF51431B39DDE4F9C8CAF7B017A47D340 -:101410000D6A4E849F2FE50F28F219912747BE22AF -:101420004FD563511FFEDD5918E92F967FB38BEB23 -:10143000CF04D7C0FE8DC2F797EDDFF0F97EC6F579 -:10144000522CF98F3BF0C696EDB4BCCA2DCAA7A8A2 -:101450007F671BFA569744CB16EA6FBE47CB064B05 -:101460009704EDCAA9845A29BEBDD4C983FD8765F6 -:10147000022BC31FEC3FCEB609654C5FCB8973C608 -:101480000D84C720AE6795DB84E3C58D1C9108727F -:1014900065E77C4524210876DC5EEC9016607FDDF4 -:1014A000E446DA5FAECBA0916BD05BCF8F05BDE495 -:1014B0009260BF6EB69080CD15E91FCA890511FDF7 -:1014C00044F83EEE4EBE676A5BE7491C01727A88BB -:1014D000C551DABEC9E4B23C8304D7819EF012D96B -:1014E00041DBC711E58F0A2E2D1B7969C6DF05E2A6 -:1014F000A5F33FF87711A13082846C74BF57EE11C9 -:1015000042B00F34192C41B0A525432DC40465BB4E -:10151000216806F93829E03A4D050941507E538784 -:10152000162776D3759C3BB8D7EA8B42FF5B7DD5F7 -:101530009EA9E363E3B1AFDDBC971D80C727E5F546 -:101540000EF023036E09E30E9BA0A94AAFDFEA3237 -:1015500029FED06C17F8430B7BD79B80DED9C9E8F6 -:101560000F91112EE4DB21EE5D9B4AC064D533FF61 -:1015700074280936A9FD2A85BF8EB87C73A19F27E0 -:10158000B91DA162D9350AE2555724BBC02F2D6978 -:1015900018DA01FEEE136B8967A111F5C14C68EFF3 -:1015A0004D6ACF07FE7DD2B3EB470F013ECD745F8E -:1015B0000C7A7CFC51AB4CE95555B83705D6F3078E -:1015C000DDFCFBFC0FFF37112FFA7DF03217DD0732 -:1015D0008342CC2379B00F3EE7B9293184BC9514FE -:1015E00055BEABFCF7623FCA7EF85D6328D3115548 -:1015F0000EB5F856C6AF12D8BE961805A6FFB81D90 -:10160000A5FAE53E58277D0DEDA6D72C3C0DF6E654 -:101610009C67BC07EC762C7DA3CC87E27164852D9A -:101620004ABD402AA2E989C75DCC5E5719E97E818F -:10163000D60B2B0B1B615E5536AB007CA7B46BE65B -:10164000ED147E56E25562E2E785407F880F465BE7 -:10165000FF7C229D57C7A39A41D65218BE3C51FC2D -:101660009558F83A6C6C2B87791D5E249226DACF58 -:1016700039DFC43412E57D05BE037C43E9B21CF6B4 -:10168000FC852A7A8E888EBFC36BEB3C538D117A12 -:10169000F6ABAF8EAB04FB5D0978548DBB9FE3E5E1 -:1016A000848BD97B62F6C90E5A6F5AF098838C03EB -:1016B0003D75BE306083B858EFCF9B80DEF7D930E0 -:1016C0005E51597DA1B0699C0A9FC5048DE4FCBDA3 -:1016D0004F3864FABC72E4FA948035361E4FB8D89D -:1016E000BA1E800793301EB3D77519F11832D6850C -:1016F000FC46F6C67942108FFC93E801BF01C6F59F -:10170000A1FE64F1E4BB1C6C5E713A3FAFD2BF42F4 -:10171000A35F12C2020926A9CA523BC66713C212AE -:101720003ED7CBDB0E178F3B717953F01F8B9E0A90 -:10173000FEF5CF431CEF87AB97C8103734C547F78A -:1017400083D392040D5FBDB5D6A719EFED7F8A9ABA -:10175000FDB202CF73FA9EF34D4A837855A5293026 -:10176000723072AEE0E7ADCF1F7740BF719F99A393 -:10177000CADFC7DC3E517BDA72B3ACB2A7B789EBE4 -:1017800001EF0912D76F3AB9F3825DA5F8BC0EECF0 -:101790002A9D62C225ECEA7C12E88438B27E7CC5C0 -:1017A0009EEAF94BB1AF7ABA297CE04CD2EA4B25DC -:1017B0006E184BBE14B93AC2E55F8F7F3DBCD5A40D -:1017C000F57B14F87E1F3DE24880EAC73B4BC420FE -:1017D00011903FD03E1E7E4C407F33546D46BB5C23 -:1017E000531D87F1D99A7C11EB6B1E14D17E86A80C -:1017F0007EA8A7F3F903D713FAF86C09113C5355E7 -:10180000EB9E39214E53BE6DD1B7FFB016E2CBC56A -:101810004619C63B24B37873C02BA2FF4AFBF08461 -:10182000203EFDE8B51EB0670A3F1CF28A286F8192 -:1018300037450F0CDBC5E3D1875AF28322D059F02C -:10184000F58D23E740FF3532D0E1887B8B03F45DD3 -:10185000DC3F1FAFA8C0FDA34FCE47BB499D553A03 -:10186000EF382EA7A5438B6F013B7EBCD548206E79 -:10187000747CCD3994E7EEB58D9EA92323F16525BF -:101880003EAC8F33EBE3CBFDE2CABA78B2C20F7A3B -:101890003EB939067F28FA2A167F503D5695947234 -:1018A000F97A4CD11FEFF075960EDDF26013C54347 -:1018B000C24211F1A0F0E591CFEFFF1EE8E138CA76 -:1018C0001FEB809FFFF9C397611F42960851E3C841 -:1018D000DFEBB37B942EB911BADCE65BD25706F18D -:1018E0009F5BB7B2AF0CEBD7DB95D87A6D60BD3597 -:1018F0002C89C581F476472F0FFF69BB5359FD58DA -:101900002EBC5F59BD280870D3504B1DE85FBD9EAB -:10191000D0DB09653EFA79268445121CAF9EB78C50 -:10192000ED2276C284F57E8B3D0F9CF58B710C0603 -:10193000C00904BFF4585CB019C76BBCAA02E7DF4A -:101940003811A09F78BA03B03E773CC60FDA325800 -:101950007BF1FA78E68F4F70E13A45C5213FEFC43D -:1019600072335FC35897EFD9243A8F66AF210ECEFA -:10197000154A6DD20108B9B44D31103389E049F1EF -:10198000DF094406E87AB14E807D67BEC59483FEC8 -:10199000E92EE4DB6FD27D21E5F78307C55DDBE847 -:1019A000120F7AC62746F3CF1538CFFD0DD40BB7EB -:1019B000F86B101EFDFADB5920AF770BBEDFC2BCFF -:1019C000BA2A6B1E2CA4F369D82DE2B9D2BCBB8F06 -:1019D0008C62FB34EDF9A468B7E4421CA55988F782 -:1019E000801E51F0D86933A17E693ECAF460F309C4 -:1019F0008197D93E621FAF3FF7AE0DF7190ADEE9B6 -:101A00007A0EC1F8DE6F3B713DCA3EE3DF58CF91DD -:101A100081D793E1407D017C2546E62FDA245C578F -:101A20000F89F7C0FCFD3C1E44DE8D43BF59A16FFA -:101A300003E73F85BE2B387D7B3A2E7CEB1ADABE5E -:101A4000CDEBC253063193E07A7BDE4D40FE50D69B -:101A50004BF9E06398DFDE0E6627DA8ED918BE6C8C -:101A600045B9303FC5BF7624313F59BFEE2ABE4F3E -:101A70000F27097DFE2DC4297CAE29E1A428F2A000 -:101A8000F8B514CFFF80FA1207391F24113C2BE35D -:101A900028E32AEF9993B5F255C5E30AEF1A4925D1 -:101AA000C41361DC02D5FC56BB4ACCC929FDC7FD75 -:101AB00037E8E84ABE0C3A3648D6162191F4ED8B49 -:101AC000319426F79773BD9C091D9D9FC1F9BC5E9B -:101AD000FE2F1A1A8940FB5D2DFA0EBB286CF69179 -:101AE0006E734E7F79B8941EA1F4BE32B9B0BF3E7A -:101AF000192C9D0B93FBD1B93079003ACBAE8A8972 -:101B0000500FEB4F2FC07DDE2428839E300DC7F190 -:101B1000902F7B9D24F8346D94C4E328CA7C202E3A -:101B20001147DF2B4BCE46FA0B120918693929D71A -:101B30002380DE1F041F94A9E7F71FE0839B06E6BE -:101B40008310FA25CB39BD972B7916BB06CEB31877 -:101B500004DDAA61DC8B064FAF2FFBF2E956DF9F55 -:101B60006EF503D3CDD700F2D36C22E7D10F2FAEA1 -:101B700076C378FBEDDE9389F4F99E26AE4FB22949 -:101B8000DD68FDCBC922EAAB47C895A887BF6230A4 -:101B9000E0FC7BA8FE7D3A3B1ADF0724177DFFE2BD -:101BA0008D04CFE3E8FABE998CFE4F4080E7ABE7A7 -:101BB00013033C77CB4DC470197A6813D713AA75F9 -:101BC0006E52EB81287AA815EA293FDE05FC689160 -:101BD0001DD2407A68CBE5EBA12DFF613DF4FD817C -:101BE000F9EFB2F9EA598677AD3E50F858D917C4E3 -:101BF000CA17A2F248D25DFDC725C483E7612576E6 -:101C00000BB3BB3B05B4B3CD27F27D58B659502971 -:101C10002876F8EC2E562F4E89EE0FFE3CD985FC27 -:101C2000BBBC7DA547D2E48104F0F943DEB38E113D -:101C3000542F4E17ADB8BEA472163F54D64FF5ECD4 -:101C40008C69A93C6E4AD79394C9F09044FD013841 -:101C500047B3F3FD4162B1A4F1FB15BCAD162B04F3 -:101C6000887B3B9309A4DD50BF7ECD6838BF777A6F -:101C7000B5ED5348EBA7220E42501E5CD47E431CA8 -:101C80002BA94CD70EF62179D05EF53CBBFF7EE246 -:101C90007832DF4F98881BEC0A11AB06E41BD57E27 -:101CA000E2FDE441EC273E4A56CEC7B5F6AB3D8E89 -:101CB000448D0BDC93C2F71FE79DE8FF8ADC6E4D75 -:101CC000EDCEC6FC94553619E305A2E8B1CCC8EEBA -:101CD000FFBED36B20B26A7D4965F14456ED1F52B9 -:101CE0002A5C9A725AE5504DFB21BEE19AFAF4BA89 -:101CF0002B35F5998D059AF230FFD59AF6D9540017 -:101D0000D4E59C96AF69DA8F6CBB51531EBDE57666 -:101D10004DFB2B820B34F5639E59AAA91FD7BE4AEF -:101D200053BE6AF73D9AF6CD3CEEABC7CBB51CAFC0 -:101D3000CD12D33B4DD6028C47365BB5F1C8B414F7 -:101D4000A67F4A1227E7421CBCF9647E2EE07B9FE7 -:101D5000FD6A8C8BC7E20BBD1E8BA53FF5CF8BF8C0 -:101D6000789FBC6432801CACD84BE5F52A5AB6BECD -:101D7000B311D6D432969DA74A84E5F728E72BCA3B -:101D8000FB7DE72B9287C557ED56B2390A5FA4A5B4 -:101D9000C851E39F0A1FC5C2DB3D83C4DB5778BB34 -:101DA0007F176FEF0AA4523D8F2A7E9EAD7F6F751D -:101DB0008A819F07FB2A5398BF33211E3D7107CAB2 -:101DC000E3E5EA7F651E54FFD7A4A480FE7F63DEAF -:101DD0006AD0FFBBCC1ED8937D52F946EDE332B4F6 -:101DE000AF65ED0D9E5CA04BACF8F7EA947EF1EF89 -:101DF0003A16FF8ED7E06D514AF4F877B3FDEF182D -:101E0000FF6E3679720713FF5E043A2305E8C0F8C7 -:101E1000A38FBE3C7E1E6B1FE427E48000FB1EAB3D -:101E200024C339D7A5F6B5743F9B0BE7A96DB06FF6 -:101E300052ED73E8FE96EF6FE2D02E50BBD79A8238 -:101E4000FA911C90E9F38B74DFBB5986A262FFBC48 -:101E50001ABFDC4C3C169388F47C04E849BE49EE7A -:101E60008A13215E163A3839FBDFB2E7DF4BB90C33 -:101E70007B4E2E7D2E8776A79CAE7F5D14BF4B7F59 -:101E80000ED7E77F839F26E0791CE26903B58B704C -:101E90001ED799C2ECF386A36C9FBCE1C46C37CA11 -:101EA0004D4AD180E77083D537BF4DE9E797FE36BD -:101EB0006500BF5459FF2ABEEF9D268E6D8778E3DB -:101EC000D9B009F12612961FD9B0DF4882484F9643 -:101ED00067ACD0D118DED805F6D948F479C572229E -:101EE000ACDBB85F44FD4492597D80589AC0CF491D -:101EF0002CD6DA2DA7576BB792CA5C3A3BA6B55BD6 -:101F000069955ABB35C4A7B55BE975053A3BA6B5DB -:101F10005BC3FC5374764C6BB7725A6ED4D931AD37 -:101F2000DD1ABD456BB7AE086AEDD6986756E9EC89 -:101F300098D66E5DB57B9DA63E3FB459533F7EFF5C -:101F4000239A7261D77735ED171F7801F36F261E3C -:101F50007E5AD36E52F78F35ED28C2BB204F7B21BE -:101F60009284906B4E3FAFA95FC8FDB46B7B7FAD91 -:101F7000E987B4B17CEB00FD0FE8F557E2338173DC -:101F80002291DE57D2295D5704054F88365BB27B1C -:101F90006711CCE3CCB1EBF7433F8BB768F3B49751 -:101FA00004B5E506323C11F44303E58B20E5936567 -:101FB00090BFADD26BCB48A31DF32106C9678B0F31 -:101FC000DC4430EF33E0ED82FC74659D0ABF793963 -:101FD000BF29F353D6BB8CFA7D2139B24E2FFD8F2A -:101FE000ED23BB4DC0B7B5BB05F25DA1FF7AEA3A60 -:101FF0001EDE981E655DFA75E8FDCEBC546D1C7B37 -:102000009A68C5B8FED937450F8B0F6AE570D501C0 -:1020100016CF5FF59C80F1353D3E14BF34165EC48B -:1020200000DB273424936050257F32C787D9AD95D4 -:10203000BFB3F00F98CF536210F282E2E4783DBF55 -:102040001585487F3C27E46AE5548F679B67685491 -:10205000BE92E97F308F5AC2CEA5F47CA5C7FB8A19 -:10206000DD0F9B402F5E2EDEE7A56ACF0795F38339 -:1020700012BA5A53943C3805AF745F5E935A187B7A -:10208000DFDA907AD9FBD686D4FFECBEF59ED40178 -:10209000EC5C0FC4CBA85FA98F97F58F8FEDFD4C3B -:1020A000B0631C9AC5BF7C1E0BCB57D1D9C95CB796 -:1020B000C64EF6ED7B4F0AC166DAF912BB7713CC38 -:1020C00067A9DDBB196099DDFB807ABDCD142F783F -:1020D0003F87DAA99D51FCC3975315BFA802E3229D -:1020E0001B4A587B7DBB9FA5B2FB3C9D29456EF4E6 -:1020F0003B4FE433FB692B1AD0EF7C889FE73C0011 -:10210000E7852323793C0FF273152A765EA0DB0660 -:1021100063855B9DE7FB48AA13C7B34F7ABE0BF2FA -:102120009D9B1D06872083FF6CC073D1F55E6BD924 -:10213000AEB1ECBD64CD7B12DA6111F00DFEBC5581 -:10214000FABB9A6F5FA6B884FA58EB7C3995F9BB55 -:1021500046E2B580DE55CE738D27F32DA06F25C1E5 -:10216000E38896C769E4795253F879AEE860E7BB33 -:102170007D727E893CA97ABB6F9F9A6ECAB9EE1CAC -:10218000BBF765A0AB5F0A98C1BFF45BA2EF7F5FAE -:102190004D65FE470B5F1F7534918F707C7150F158 -:1021A000933753312E17C07CC5D5A2E734C4E70658 -:1021B0001BAF3A9EDACFFF399E3A70DCFC64229C5A -:1021C0004F240E95703B21797281FF5BE0DF9330E5 -:1021D000BEFA3EBCDF2FFF5476F17C5A79C07C5AA0 -:1021E000A59FD94EEFC78057DA5F4F2ACBFB5B2FF5 -:1021F000AAFAB15FA21F8AA7DC46EBA0F0F739C3A9 -:102200009FE7340B265C5E5CD39CD62FDE674E1BAB -:1022100020DE77F1E8E844384F56E256FA76167F2A -:102220005286FA7E4C8B533BFEC6025676A531BAD7 -:102230002D4E647C3F8ACF43C90354E2D69619C41D -:102240000BF71D1EE1F9D94A3FA3D26CD83ED13518 -:102250006514CC7763B680FBCA8D4E41B3BF3C9901 -:102260005A322A8DB69379FFA3D2189F6E1BCEE205 -:1022700033FA3CC833BCFD99D42908E99B57003E8A -:102280004DA218158F63D2581EC64988911546E293 -:1022900067358FB1FB5D4ADC4C890312E2792B81F3 -:1022A000EA95F75A8D04E25A8B44EB46E0C3BEFB35 -:1022B00073FC5CDD41FF037B593DB602F38FFEDD0D -:1022C000FB5B80CF04577F7B599AD6E7A7782EF324 -:1022D0001ED7D7D22EE3BCBD3B9EF16DAFCD8AF1A8 -:1022E0006C7DBB859C3EAD3C4E01FA1AEC864B24BE -:1022F0008DD1ECC7C234C637178F9ABDE8C794C5D5 -:10230000633E8772FE2149C01B98061E0068F1A734 -:1023100067C07DA2BEF30F99E07B49562BBE27C94B -:102320002464832BA1924780FCB26E53F7863498C5 -:10233000EFB58207EE0FA455393AD392E11EA18C76 -:1023400062B6319BD88BA13EDF80F5CE398E8D46AB -:10235000C8BB96099C6413231DC746C7694DCBC6ED -:10236000F5B7066EEA4CA3ED12E55E327C2CE8115F -:10237000C77437C87125CB5FD7AFEF3E2E1FD60D80 -:1023800074DF00F890A3E781DFC7F98FEA99354041 -:102390008F1299EC62F7A2581E2AA45963BEA08737 -:1023A000E54B2740BE510ED33350FF90B3741DF060 -:1023B000B9225F22C737F0BD3A1FBE95E33B4927DC -:1023C0009F0A3EE9004D900F21CD20C8D7B3AAA2A5 -:1023D000CFF7879CCECBED158FC07C674D6EC23C8E -:1023E00077F2F9175F8845E0F43239A1EF1388439B -:1023F000C42533FD1B27CBA88F8943C03C538BECEE -:10240000A983729CF56A870876CFCCCF0B171A8800 -:1024100044E5AD94F7E3AD24C2FBB92CCECAF4ABCE -:1024200044DE57E442E4C82902FBC9FEA85FD49AFF -:1024300040D7536A3D88E78871231A4BE05EC1CBD1 -:10244000F3591F8FC4C8DB3F99C8E8E0127D6E03C3 -:10245000F8F4E4E4ABFB26239DAF841B9A0F6C7861 -:10246000F7D5FD993C7E0EF9E281775FF55ABF7C86 -:102470007EF9BEC7DF7D15F2CBBF3CFF7B04D0E306 -:10248000272963C1BCF5FCAFE8B3C3A2EFF0BD14CC -:10249000FF3753A6F21700944815D29BE50FCDE104 -:1024A000780EFC9DE2D912C1F3CD1D07107F878DF8 -:1024B00074DE747CE314866AE33D893C1F2388FD47 -:1024C000DF62699B06FE4D8FA9370FC6ED79F1EDEE -:1024D000CC00D52747EF3B672394FF8E4BBD367862 -:1024E0007E7ACD1B36C0D7D13522DE7FC37BC9AA09 -:1024F0007CA0F7395F95BA2B8E025FCD5FFBCF22B0 -:10250000B59F4DFC296877970445B8E3DBA7FF9694 -:102510003D93C0998E9597B72769CA8A3D5E6E8EA6 -:102520007E4F3CDDCDE8BEE4D96D26C8872F75FB14 -:102530007A409E4EF37C83D3BB6CB8BF52E6B3E0C7 -:10254000D97C13EC278F77984908F85EEA32128C11 -:1025500053796708946F7D9C0FF5F37C654F02F605 -:10256000B7E83111E348D5742C3FC5ABAF6309DB45 -:10257000DFEAD6B1E8A83C1DF4D5A24D0209C8ACEB -:10258000FD1A4A379FFF7E3C5FD1AF536F5F2E909D -:102590003526D0237AFBB290785A2683DD6AD33E63 -:1025A0005FDCF100F6BBF812E7314E37DF9F159183 -:1025B000895FE4409C7938E60BC6B237A7D732A1D1 -:1025C000FC70AD05E1476B1D088FA631BE5DB6BB43 -:1025D000F3957414EBAE22B04371074A2DB793887C -:1025E000FF2C6DBB29F4A40C7CA9CD87ACE27856F6 -:1025F000FCE7C5FC9EC1A5FCE72A58E700F9905509 -:1026000083CC873CBB7FBC059E8F57F03191E203A2 -:10261000EDEFD8D7647269FB1B0B2FB1DE5B0EDFC9 -:1026200039888267456E8E723BB270FBEC8D43E950 -:10263000049A5FFC6B5637F2258B4328E754A27B44 -:102640006317AC5F24BAF85F80BC4954FCABE7CF9A -:10265000C5C4C3EC8E95BD67E171893EBEEC7810B0 -:10266000F1AAF011DC2830B80186DC86E2FEDF0D2D -:10267000E8F77D80366DF913637716E88DC5BA7873 -:10268000C12742F4FDD734F770B67ED93B1DF22244 -:1026900016918A8D2CAEDE86F8392DB5BD722FC805 -:1026A000F376264FCB7FF9DC2F404F2DFDD9637693 -:1026B000D0531F486DA9305EFD8E0D762FE82B2973 -:1026C0006087F73F088A51EFEB06DDFC1C9078AD80 -:1026D0009017B602590C042C3013F4E4DF76181D61 -:1026E00010476D78C61C32537CACD8C5F048CB2758 -:1026F00058F97EC457C36EAD1C2EFDE163A932EEBE -:10270000E703E91C7FE9A0AA576C3762FEE88A3725 -:10271000450F0CD3407A717DFAF7611E614AB78686 -:1027200076B1DA94D8BF9E7A3C2690B3865D8C4E03 -:102730000D3A3FB38EEB653DBFB7E9F89CE205E388 -:10274000614A3E2B0932FDDCFCA3C7F34ED0797DF4 -:10275000B4FD55BB3036C2EF04B22E291DCEB6D71C -:10276000CC873C83587CFE09978B3EBDCFED8CBC5B -:102770009B4E0C7CFF0E06EB8D21FB35141FF5DB09 -:102780008C9E007D5CFF9CE8B5829F74C48CDF77D3 -:1027900058F6DCCB6F5D4DE7B76CA73179065B86E9 -:1027A00015F4B342A706E0EF82085D96BEF0B209C9 -:1027B000F220E1F91A57843ECB76769A20AF528FF9 -:1027C000C7D2F64E13932F1D9DDA4F4C07BBDCFC8E -:1027D000A38B26E0830FF608045C48FDFB75DB5EE7 -:1027E000B683FE003C81FD50E8D547BF7E740BCD1B -:1027F000FCF5046CE780739A58F45B09732944FE76 -:10280000FEE9AFE9F875EF983DB0FEBA9FDE698743 -:1028100075FC556A647CFEBD0DA9608FEB8C8154FC -:102820000742F6BC6EEBD791FF16BFFEF554827AD5 -:10283000D33B04E497AE7308AC6FD15337E3FA6A25 -:10284000890FF9AFEE7B6205F88917245216CDCFB8 -:102850001F3284C9C95F9F36E3A6E0AF26C2BEC35C -:10286000F14791E5F19195E8877C9DAF956A622CDF -:102870005FB0303A7DCCED33E17AAC81B76AD87E77 -:102880003FEAB10F33BD6920EF140FDA78EAEBD3DA -:10289000D2B8FEC3EFA5E07B94EF4AE139B4EF3242 -:1028A0007AE3F234EFF1BC5636FE5D7C7C3AEF7889 -:1028B00088CBFD3555BB7F55E05787287130D24511 -:1028C000D4FC154BEEB76F42BE3AFF26D32B2B82BA -:1028D000B3CBB0BECB184A83FA60E71C01F502F512 -:1028E0002FA2C9F57623976B6D3D9DA724A8F1BB58 -:1028F00087DD8BAB7D94B653F92111BE31459E67C0 -:1029000047E453C9AF58ACF3CF14A8D70B4943B42D -:102910007A41799F3C9512F51E56441F0490AEF5FE -:10292000C6E00FBE0B727CC48CF70CEB9F33E2F752 -:1029300072CE3CBBF7ADDB29BF9F6957E457AB674D -:10294000F5F25BF7FCCD249AFC9E49AE2051E59749 -:102950003E8F2ABFC92C7FFF7F5ACF2E8EA167AF33 -:102960001DD2CF9F48BC86163FFCF1B261B8CFD2D2 -:10297000E155C1A75E6FBEE596A3EA4DFAF7265171 -:10298000E151C19FC2974B7FB21CC7E9E35F853F0E -:1029900015FEEDE34FFD7AB578D4D71BE0CE51613B -:1029A00084EEC675747F0DE7AE2F8A78EEDA23F7D2 -:1029B000DA5D1097E579373D0E5E76B2726F8A69FF -:1029C00023E80FE5796F1CCB43E8A9E8B53B557EBA -:1029D000FD890ED10E79F5DDC1E8F912984901F1B2 -:1029E0008C18F914CAFDD969A235CB0FFBB2367623 -:1029F000DEB3B0E9563BF8D33D1D39B32AC18F3F52 -:102A000020A24FD513CFF3AB025E6908C56B0D5BF7 -:102A100032394D02DF013FBBA663D90CD8342E6C8E -:102A2000D5E2A3D63A07CFB36A1F3546F88280BFF6 -:102A30001334819F55F794F6F952C8AB02FAE8F8BF -:102A4000C8077C14E51EC646858FF2493EDB27F396 -:102A5000F32AAED7A68963675542FEE27E764FE23F -:102A60006C874836C27A9FE5E7578114E4CF159406 -:102A70008FD571CE8F80CF46C7B6DF1FFDFC68D1E2 -:102A8000BDB449FD2FFE9CF724851FFDE2C8A8DFD9 -:102A900040F9976F67FD99F46F5FBAE7B33B308FEA -:102AA000728F99C0BEA867CFEFB2EE85F2AFCD1E90 -:102AB0009867CF3AB63F0EECB1A15DEFC964FE5FF7 -:102AC000F38B17F3BAD13EAD477AED1CC2EEA99E47 -:102AD000EDF8C73101F2E93AE8AAC0EEF27D57C33A -:102AE000AFE3707FDDF3E245CDBEF2DF5DCF0A7E5E -:102AF0005FA9C7462AE17E718F93DDEF6CF8CDA404 -:102B0000EFC37DC5E5BB3A4D35B4BEF4B7FFCC038A -:102B10007DD3F33CF327A87FBB155CEA8E275E6D5F -:102B20003552FA7D023EDF50BAEFFE6E4239DCC309 -:102B3000E88F1786871E8A075817C54B1DE8C958A6 -:102B4000F8786308BB3FF2DF878F4FEF80F1EB3BF4 -:102B5000261288A747F02278D9731BE65DD0F5B31B -:102B6000E77B2EE6817F74A9F57EFA7F6CBD8943F1 -:102B7000FFBBF9FDF12132CE4FCFF7FDF9FA977780 -:102B800063F9A7360FCE7790F27ED5D0FF5BF42E97 -:102B9000FF5F4BEF039CDE36079CA7F4BCF8CF2CFD -:102BA0007219EBAEFF5FBAEE3E3FC7E0B14CA0F347 -:102BB0007B87046F2E1162E7713E3154BB8F98C939 -:102BC000FD8899C9B5E83FCCF4B2F84A3329D80F4B -:102BD000F7D4025E11CF1D309986E2A16B4E7E10B4 -:102BE000F3B6A4C0C8EF401ED72DCB3DEC3B5FDA57 -:102BF000FDD5CCD4B232F0DF0E35D179D176876CE9 -:102C00000647335DC22CAF88FE1E85E8E7FD69CA22 -:102C10000D981732AB58BBCFB85DB76FB8B5525BE4 -:102C20007F0B793A05F2EF6EA93362BED0CDBAF6CA -:102C3000AB873A709DB792C60D2C3E7379783AC037 -:102C4000F1D41F0F03E3AD1F9EF87E127379E4FEEB -:102C50007833FBD8FED24C2BB8BFC5F3E4560D0A2F -:102C60009F84EF3BCD7C6805BF662FFB5EA7AA5F04 -:102C7000C48B82F7CBC5B742273DDE15FC2A78D33B -:102C8000D3E12938934889E03F02953C121F51E770 -:102C90005BCEECF31BAD88C7D7B6B3FB0AAF15D735 -:102CA000B4E643F95901FDB50B93C7130B5DEF2152 -:102CB00023D9CDEE7F79654751249F4528FE1D9E7F -:102CC0002B403EA17A5F0AF984EA75413EA1BA0C15 -:102CD000F984EAF6904FA8AE877C42753DE413AACA -:102CE000CB904FA86E0FF984EA32E413AADB433E7F -:102CF000A1BA0CF984EAF6904FA8AE877C42753DE4 -:102D0000E413AACB904FA86E0FF984EA7AC827542F -:102D1000D7433EA1BA0CF984EAF69047A8AE873CA7 -:102D200042753DE40DAACB902FA86E7F5DF8254D2E -:102D3000B984BCAA695F6A7943539EE6F8B3A6FDDD -:102D400057DDEF69EAAF97CF68EA15FADF907B4E5F -:102D5000F31CCE2C0245B08F617FE59E7F68FA910F -:102D60004805C6994DA411A105E2B714C69376840F -:102D7000562AE6004B47F972D2815FB706360273D6 -:102D80001D9A74310BF4FF6B936F62F1077E4E3026 -:102D90000BFE2953264EF83C03F6B5CAB9A73D2CC5 -:102DA00092D078CA876101A1239C404249940FC305 -:102DB00071085DE1247C9E1476224C0EA7E3F39407 -:102DC000F01084A9E11C8469E16C84EEF01884435E -:102DD000C257201C1A1E8FEFA587F3116684AFC15E -:102DE000E799E14908B3C2A5F87C58B804A11CBE14 -:102DF000016176F87A84C3C33761BB9CF06C84238D -:102E0000C273F1F9C8F06D0847856B108E0E572319 -:102E1000CC0D2F4378457809C22BC377E27B63C280 -:102E20002B118E0DDF8BCFC785BF81302FDC8CF04F -:102E3000AA7013424FF8016C971FDE84B020FC6D1E -:102E40007C3E3EFC30C209E127F17961F8098445F6 -:102E5000E1EF239C18DE86B038FC138493C23F4216 -:102E60007875F8057CEF9AF04E8493C3BFC1E7D71D -:102E7000867F85F02BE1BDF8FCBA7027426FF855CC -:102E80007C5E123E80704AF80D7C5E1A7E1DE1D495 -:102E9000F09FF1F9B4F01184D3C3EF21FC6AF80478 -:102EA000C2B2F01984D7873F40F8B5F0397CEF867D -:102EB000F0A7086784FF81CFCBC39F21ECDBEF4FE6 -:102EC0008E752FD167F802F6CF56D7A0BEF345C84E -:102ED00016CDB9D4E30976D493B3D6B03C928D2500 -:102EE000E7A6A25FBBD22CF3EF6BEAF4EAE756F059 -:102EF0001F3640CD10D607E401CEE3FCFB5AF1DECD -:102F000014F097361674D7433CE4C1ECEE2A84E9FA -:102F10002CBEBA9EC307D259BCF4F651CCCE56ADE6 -:102F20001C89E757247970EBF803D8E79448FBFA3B -:102F30004C5EB6F666E1BD8041F633D87697CA8F0F -:102F40005A95EE0BA6A35FA4BF9F37E8F79F413DBC -:102F5000F1E5DF6F1FE8FDE39C5EF68C8A5D384F7C -:102F6000C99B07F553D60D1193693FD5AD8203EC8C -:102F700064CDFAFCE940BF02E2C578E2BC18795D95 -:102F800047D2599EC682462381B8E20299603C77B7 -:102F9000C12E96E70B71D072CA17759C2F966FDA07 -:102FA000690217B4AE7131CB3F0AB2389385FE0780 -:102FB000FCBCB47536E61F2D7B461B7FAA87B88EF6 -:102FC00008E7C8DAE70D3CCEA48F57EAE34B7F4C05 -:102FD000E7F1250FCB3B226206AEF7025D2FE473CB -:102FE000F8EEB65940FF533CE03989B27E255EA920 -:102FF000E081F4BFCF8079A167F78FC43CB5B3B24D -:103000009C06ED7C549CBAAC90FFE09B08CF29FE57 -:10301000309FA4B72901F3914E507D2E43E293C314 -:103020003711BE9FD6FD4E26E1DF6FD49E1B585A46 -:1030300031FFBADA4807A6EDAA7724E1FD47DA5F47 -:10304000DE6E8847EE30623E5080AC7293E2FEE75F -:103050000A151B8CC81F0B763B597E58C0FB26E413 -:10306000EB2BF438B13E673AE4152D68C9CEC7B0F2 -:10307000DB6E23FA79CA79A942A7FE79D11589F0C6 -:103080007DC4A52DAF233D29BD34F5F5AD9FE2FDEF -:10309000014AAF5331E8756A207A5932B4F482B8E4 -:1030A000F2AD50B92609E5B46A5D6864A38A1FF5DC -:1030B000717A9261C5FB8E4A3E71D950460F2279D2 -:1030C0005281AEE75A0B915E7A3A95FDAB06E94123 -:1030D000DEB1E1F776E7E590F937D2E7F379DC7214 -:1030E0005EF3F5E83F676730BFFEB5B5906B49C842 -:1030F000EB6B2DC44B9DE737D63AB0FCA7B56E2CD1 -:10310000BFBD564678646D2EC2532696CFA3C81312 -:103110006500CCAB1B9DC1E4687486B2AFBACB0D21 -:1031200071E9B27FBD5108F93D2981E499D3AE45DB -:10313000BF5B93A75139479B87D16DE4795E9B04B0 -:103140000F7C476541C5359AF624777CA40CF6833D -:10315000E78D2C6871E2F7DB6E9B91A4697F4B4B86 -:10316000BAA67C5D868CF39B5D96A3797E7BD51891 -:103170004DB99AFF6E02B1C41BD4E753D4336279C0 -:10318000DE0ED6F67CE3C4B4D574FCF3078D58AFDD -:10319000A7C7295300F7E381A7CD1EB043A7E11EBF -:1031A000192D9FFE9388FAEEB491041C54759F1656 -:1031B000C87A804462F274E13093A7B27F8904F642 -:1031C000E1E4C7663CBFABD9229000DCA1EAA59838 -:1031D000A7E3DEF52333AE7BE11691F8F0BE92DC77 -:1031E0000EE7D677ED18ED8173CB7939A14CB8B7DE -:1031F000D7FBF338CFD3B4B6A69BBD7F9AEEAF9D75 -:1032000090972414E0F9C1C7E56DB506C837100FD3 -:10321000A6809C7EFCBC88F194252BFF54E400BD65 -:10322000F64AFB5BC5749C536D228E7BE619F33620 -:1032300011E5DD9B06DF758DAC3B8871867DEE8ADE -:10324000BA0CCAC71FD606F350EFAC61F1EDFEF819 -:10325000A1EB057A03BFAAF458C46EB17332AA7CFD -:1032600086807EA8317AF0DCF454AB11CFF3A8FE4F -:10327000C7F3FF536D4906A67F9E47BE5B20C92654 -:10328000F5B80B5A452FFB5D08D904F3250F8B3E8B -:103290003211CA2C5F21D022F8D8798D96BE77AE34 -:1032A0009C88F78BF5F9530AFC84CA944F750EB4C9 -:1032B000F445763E4B26744BEAFC7125BE42DCACED -:1032C0007FE53B3EF5C31FFFD6640ACF7AD92707B7 -:1032D0002F6CB7A17EFCC8F052D16A0ACF9407DEEA -:1032E00097285D1A45DFA380CF6586D6AD029E8BF9 -:1032F000BCF72D388FFFF039A307C590E76B2DFD84 -:10330000F1926103E507C10CD8F972285570C357D3 -:103310007909E66FCC25ED3C3E1064E75830098A08 -:103320001F473D3BC77AAFD0B619EEE1D6E8EEEDC8 -:10333000BEC7EF2DFC3043D0D8E7BFF0728D81C9F6 -:1033400027D9C3BEBF08792F2354F654D1A7BFC8CD -:10335000188EE3F6D955D28E7AA5967F1FB8FE193E -:1033600033BBA7231307C8E312461E7216E4998ED7 -:10337000B3D4F4DC77809D17932EB4731F1A83B5F2 -:103380005DD9F0FEB6F52E7CDFE80982FC723B6069 -:10339000A18A03F4C762C2E6B7BC4D088654710A1D -:1033A000E5F73808D80595BEE96F0FB4766011B718 -:1033B000778B882EDFA74D6B972A126CB8AEA56D60 -:1033C0003CEFB96F5E22F982E2ACD6177C6526CE5F -:1033D0005BF004A3CC6331E90DC17780973FCBEE5E -:1033E00003E9E7A55FC760E759EB993D15BE27DC08 -:1033F00037AE6EDE0ABE095C5052D141C17B6D8092 -:10340000E1B3B643407AFD85FB55CA3D3B85EE8B63 -:1034100049C54CD06B8B1FA5FBC2EC081FF4D9EB40 -:103420009D41F497CE9036BB95F27FFD969DB74CAB -:1034300082F79E7ADD04FC5DE50A8D3438E1276968 -:10344000EEF956596614FBAEB3E7FF29FC101E6770 -:10345000C2F7283E166D1731AF41D58E9FEF07108A -:103460004F7501827944756F8A9E66FAB40E7ECEDE -:10347000A7E0F2E7ABE0E77F7ADE7A3F263B7360B6 -:103480003F46AF5FFAF9313AFB09F726C05EF6A670 -:10349000B03CF0F39237D1857A59A777530AF0BB45 -:1034A000A38ADEADE5764F196711D83B5A7E7FCBF4 -:1034B0000B76883FFCE5D11752318F02ECCBD888D0 -:1034C0007DB9BB868D77F72FE3306FE9E3F2AE3C31 -:1034D000F0FBAABEF73BBBFABBA6756EDF75993051 -:1034E0005F6E0F978BDBB21C600FFDD1F32AFAEDF4 -:1034F000BF62ADD3768975DAB4EB5C00EB54DD07BF -:10350000A9E1EB3CD9C2D6F75E2B5BEFC27EEB0C98 -:10351000E039C8DDDF377B02E86784D08E9FDE2983 -:1035200012B87FD6E767E8ECFE05D2B615F0B17C9D -:10353000D5DBC724CA174B4651FC503EA87AD88C1D -:10354000767EC9CFD9F9E78742491A1EC0EF0BD959 -:10355000BF419F2FA5FE01F8179179F4D9FDC599B8 -:10356000852ABB3F48FCADE071A8151DBFC3DF8BAA -:1035700012BC2C1F7285F21D98DDBAEFC0C8A003E3 -:10358000D83D790BD02983C86C9FA88DA7FE6DE428 -:10359000A777AC42FEEF1DA5FE5E6F437CC808F91D -:1035A000BEBD3B05F48B96DF55622F2190DFCAE24A -:1035B00060EB3399FD12BC5ECC7B3153BAC6D3F1BC -:1035C000EECF94D973D9C1F2BA9F22F8DD1965BE46 -:1035D000FAE7101FB780FDB31AD0FEE9D7FF8B4C76 -:1035E000E62F2F170DE84FD79B985FDDC3BFFBF089 -:1035F00028AF7F3493F9D7DFE5F1811EF023E17C1A -:10360000FA5A33FE5E0F2153314E2E11C67F92823D -:103610003787F4499F7CA3BFDC9B0178BA83741978 -:10362000819E338B67CB706FE058AA05BFA344FF20 -:103630002AA09FB9BC9F4346764FE0188C41D735EE -:1036400097C7938FC16740E9F8C78698D08F0DBCA4 -:1036500068463FE1FE7816EF23C98912F0F9ED5C68 -:103660004FCD9B6CF6C2F9C0DCC9F75700A4FD052D -:1036700008C55795A577433E1DA7C9C0EC7C938B21 -:10368000E07D49B2BEBB10F07715758B214F9EAE21 -:103690007ED7174903F191F69E423DC415AE268CA4 -:1036A000C18A11BF9A72BD89D51FCC3C36F3D10CAB -:1036B000BABF866C26B0338023E08BEA44DCE7CEC9 -:1036C000823C7E174009F9ED4689040C0CB658F18E -:1036D0003B442CAF5F3907B9B9988412E9FA420725 -:1036E000B4F7286E0D1942A3E17C470A7502FE0C5F -:1036F00016D9E8A0E35494090580F7FA75839BEF87 -:10370000F1CC0F70BEF5F0BD2B98E73704CCE799EC -:103710004B851EF8F40E89EC130B18FD800F1B5C13 -:103720007200DBAD647CAEDCDF50E8924FBB57E348 -:10373000772E9F1FEDA7C50EEF9BA2C74DCE70F948 -:1037400050FCB4655C6E97297CF7AC565E6D5932BF -:10375000FB9E1AF883146F73398CC5F7F159ACFFCF -:10376000F82C165FFBDB658EB7DC4C42B8EE17CD4C -:10377000484765DC591C5AB258FEB2320F857F6B40 -:103780004923E6DFD4F2788C816A12CCD36DFB3EFC -:10379000E6F7EBF384A8838479674BB7EB9FABE242 -:1037A00039A2462F619C5330F52E84F9095F89F3C5 -:1037B00000BFCF35B5633C40DFCED826A09C1B5B55 -:1037C000A83F25F0F32D5A36B70AF8FB0E73337A6B -:1037D000C7E1F7CAB95F5DCBE94AB5F774B80754DA -:1037E0000BFE149E7FF1EF446D617EA4C4FDDF05E6 -:1037F000AD5A3F63EE7A959FC980E65EBD59971F2B -:103800006EE4FEC67153EF38D0F7FA7BF6C70D6C45 -:10381000FE815482F991CA3D7B89FB930A3F0DC911 -:10382000326ACEC594FB9C55A0A7D8F70E74F95404 -:1038300056FCEE4A95C0BF57C9E38A67A9BF89DF26 -:1038400095391A87764B8933F694D8028644F89CCA -:10385000252BCF4BBC7B26F89955769304F0A2A17B -:103860001BC7592D76D9B2B32371DC8D25E3B74040 -:10387000DED0ACADA3675932F19483DF471AFB1A4F -:10388000E4ADCFF99CCE1FCBE36679E9FEA8E7E56E -:10389000DE3B2C54452FCACA9B25517BDEF358EFE3 -:1038A0005628AFCE9A384BA276B0E7C1DE2CF88608 -:1038B000F0EAADD7B0FA26A5BF6B66417E70CF1394 -:1038C000AC3C87D607C0CFE5F780AAAE1650CFAE86 -:1038D000E6F647891F55195E62700AFB9D8F4BB54E -:1038E0000B6455AC063F47B49DC2DF13D82C7BB1A7 -:1038F0007C5F866F7E16ECA3660B0113DC8B7F3337 -:10390000388ADBAFA8BF7BB13A93C9E5BA61AC3F57 -:10391000055FB49FBAACC2CBEFC701FD146AFA5978 -:10392000F965E673B4FF7CEEF932F3F1CADAF928EF -:10393000FE99F29DB957B2BDDF81F92DFB26DB0F51 -:10394000935356CDFDFF738DBF1C0576FFDCB3E6A8 -:1039500024E0C3653FFD55562DF87FDC1F3AD3792F -:10396000C40479DF2BC2ECBB380D61F69D9C15BBFE -:103970003A4DD3C7421E6BA7A95435BFFAC8EF5CB6 -:103980004937AAFC9827B30C3CDEC67ED771D94FC5 -:103990003FC0EF092E33B4BF0F79BEE46A1647D398 -:1039A000AFB399BF770CCEFDA3C40BB66531BFE3AF -:1039B000628E3708EB5C9745B02CC6F86ED787BC93 -:1039C000BFAA78A6C76B8A6C1699E2BBF04D5F332D -:1039D000E49DD63E955D20D2790433A6FC386BC0B9 -:1039E000F8662F8B6F76B0F86695ABEB2E6AA4C89D -:1039F0005FB6CE7DC8722D21373C4EFAEEFB41DC1E -:103A0000B0CCACC8CFAA595327B3781994F767D56F -:103A10003F04F2B39FFF3EDBBC89E3E241CEBBB380 -:103A2000130C0E2AFF3BD3ABFF027C316FE2B5D300 -:103A3000E17989D936AA9AC5C7913F76A65784A05D -:103A40001EDA43DCC3670AA5DC4AD7E1FBBD8879EF -:103A5000D3BEBC045FB47B2A7BB8BDFA4B163B0FC8 -:103A6000DA6FA0F32C88CC43199F72FC5D5D10B710 -:103A70005A37241FFC687B46C9A9ACC2C8F8F60CAB -:103A8000DFEBEAF1E972F3E0F960E77188D3E31460 -:103A9000A75BC56411BE94D0A7D76F9C9AA029CF0D -:103AA000999144BCEAB8E99C744DB9B22A47D3FE57 -:103AB000F6856334F5E5E6AE098D97E1EF37D89EDC -:103AC000C1FCDEA31D17DE9A0B7EEC76D123D0F568 -:103AD0002C7971C75B907F7D167E82A480C5C5D886 -:103AE000F71AF9798CE49534E731075E3081DFAE5F -:103AF0008AF3EBEEE51DC438BEFE3C46C917FFB2A3 -:103B0000E731D230FDEF797EF40A5D1929DDDD89D8 -:103B1000F4693EC0F2989BA9DF02DF13FBEA2E7323 -:103B200010BEE1FEF1AF4E9864D5B94C43B8097FA1 -:103B300057B774F7093CB7D991C5F4F68A8E4F4D43 -:103B4000704FEAAB1D2B519EA753FD9548F9A6ABCC -:103B5000938CDB05F1E46C1BE6E12C6BB91EE3D41E -:103B600089E1B908EBDBAEC7FE96876FC2F20AFEA9 -:103B70007BBEFBE3BBA6831DDEFF0B27EE075F13B7 -:103B800043A39E847ECC36D40FE5E9F3D6819FB063 -:103B90003F3E30F64E3A5EF9CFBE8A79E82B760981 -:103BA00018372D17C97E01F2EFC371D85FB9F8C776 -:103BB000092BE9F31B4A995D2D071F87D68B45B664 -:103BC000CDF83DE918BF93E619C6F48AB19BCD7BC9 -:103BD0005A7836F6A7D4170D1BAEF99E9F3165BBF8 -:103BE000B4C01A598FB15B40F8B5F018840DBB66AC -:103BF0004B907FFEFBDCEF27039E687BFC3E587FEB -:103C00007D3C319144D15B0A34733D3C17F4309CC8 -:103C1000DB677B670C4B81DF23EC962CA047AD164E -:103C200007F82F338BF3E55AD5BAC4976EC37B10D0 -:103C3000E6E45E23D8EFB914AAF5F6FC1876E6C6DA -:103C400061CA3D9B26F6FBBB8A7E7FF7EBEC3BA867 -:103C50003C3EA0C8D375C30C9AEFE974094C2E0200 -:103C60003F67E702D3B37D0B61BE5D25A4F279D433 -:103C7000A35D59701FFD3F357F4A5F0BD0DF2E7566 -:103C80001388632C19A6D81D26CF979AFFAD7CBD4B -:103C9000AF89C40F7CF1DA75D77579E9BC3AEF1DAD -:103CA0003F1EEC8232DE3DC3589E2971F47E8EF9B0 -:103CB000867B126488EB97C399C784883F0FF98885 -:103CC000103F6CD8637E1A3E90DA60A7FB7B2BE432 -:103CD00005C685806F3B7F1B2781FD1833C277CFD8 -:103CE000B042783E7A2A7CC7C7DB619608FA41DE8B -:103CF0007B015FB1E67B29FDA5C8A39ECF7C2D4C3F -:103D0000FE7C5C0EAB39DF2EE072582D7912E13C5F -:103D100066FE4111EF452E58238CDB05F101D98653 -:103D2000F7F4153954E4CD087C391EF893F1657D1C -:103D3000D8C9E53B9BF7CBE4A05C64F976E5639CCE -:103D4000B87F5E114EC2768ABC2A72BA3EDBF76338 -:103D500058777933956F3A8E6FDD9009202F113E99 -:103D60003139809F289FB86B557CD0DCF999047C51 -:103D7000629C2C209F98292C55F151459F7FE298F9 -:103D80009E4AE731737D367E4F59A9FF591FBF0CFC -:103D90008EDF9FE2ED17584323C1AF3536C679E079 -:103DA0003BF2679365D463AB3609F8E384AB8C15BB -:103DB000A5E05FAC7A42C0F81EF81DA07F8A0E37DE -:103DC0009AD4E720B785F3F0BCFAA6F00884C10CBA -:103DD000DF8BC017D5E15B381EF3A29EF79D6FBC49 -:103DE0001FE36AE783660FFBCE98367E57E8F5E05F -:103DF000F99FF1A0916C9321EEE613F17C2F93389B -:103E0000BE2DB0F81DC4F394F89B724EA7C4E1CC4C -:103E1000F03D5C951DBD20B565C13EA45F3CAE8400 -:103E2000D9FD8FB61BD9BDADCE3F161968FD87D918 -:103E30005E8CCBED73FBDE86F52CBD31F853232D64 -:103E40002F7BF0053BC4CB157CB64BA191B05F6ACC -:103E5000A77884F8607BAB581664FE4EC26C557E22 -:103E6000452CBE5E1ACE41FC28F646D1DFBF5CEB86 -:103E7000C64DA9A2C72F658714FE5ECEE56039C87E -:103E80000151DB9BD915F0BB662457C07BAE117B7B -:103E9000C3E441D1D394DF516ECA733231AEAEE880 -:103EA0006DBD3DDA2BB67FFB6A3847937D7132C515 -:103EB000CF949FFCE385776855FDF33F9A0A742AF7 -:103EC00019231038C7BC949EFC7FD95BF3F900809E -:103ED000000000001F8B080000000000000BB55B15 -:103EE0000B7854D5B5DE67CE9C9949322FF28020ED -:103EF000249C993C0825E0F08884879F0702018470 -:103F0000E0046F1135CA2422CF840494CF28F4CE64 -:103F100009090894DAA0D6528B7642C1528B6D788B -:103F200058D38A303CA441AD1DAF7DD02A7450CA0D -:103F30004B9088F582B754EE5A6B9F939933495052 -:103F4000DBAFE3E7B7B3CE5E7BEFB5D7FAD7DA6B7B -:103F5000ED73100F7E2EC94318B3AE2C678A9DB146 -:103F60007BA12D81F63AFE6E634C624C69059AB1D5 -:103F7000A879A623F6DC299B18CBC0E70D8C153158 -:103F80003643E77B7F3963B73076BF9BF15F3D30C7 -:103F9000F565ECDA0013F14DB1B239FE42786E8E60 -:103FA00064C7CF57EA9920CBC09A270B34EF8C9582 -:103FB00051B32D1DF8EC36F7360FD0C5C3E4798523 -:103FC000317EF12BCA5D26329B900AF29AA32CB562 -:103FD00010E7D7E556F93A5F22779AC6FF3B91D5AD -:103FE000B7C2F8DFDD765B4401B90EAC18314294FC -:103FF00063EB15CB16DA5F591A8C1DC958C76BD6FF -:10400000D016909BC17C02F05F7A6D50683D6CEDDC -:1040100004EBB8C68056F7A6C8B8AFDA7D29C45FEE -:104020009BEC0A09D05FEBECC8F7833C25FB93C2FD -:104030006C28ACB33FC9CC60DD2B390F14CB45F8ED -:104040007CE044C10942EFB59A19F0A9D9CA68D4F5 -:104050005B4FF2EBF225B6FAFE4BCB05D5E5626C71 -:104060005A89433541BBE86A0E6323185BBC762A44 -:10407000B5AF043341C98C4DBA5A0ECA60ACE6EAFA -:104080009DF47CC9D514A2A77D3B528AFB61AF0881 -:104090006C1BC85FD6EFBE550CE46B4F6643F6C091 -:1040A000BEDABD59BE46E8AE6E9E4AFC65BF983C7E -:1040B00005F7B5640F30E3B8022194877A3A653783 -:1040C000B1DE8C3D64E3E27F5AF7A791328CFF7436 -:1040D000A4631803D64362EB536304B2673BDA73FD -:1040E000C2CFFEB1FB2FC0275D159902F258AF0A6F -:1040F000D446E4C022D407F031067CD5BBFA8E0C3E -:10410000D8BF0A9E7E25C98047A9FA1309F16485A4 -:10411000B624AE7F8E8693443DD6CA1CD75FD50F9A -:10412000EEFB8A785A8578CAF88FE26915EAA91BEE -:104130003C3522CEFE553CDDC08E3EE689E16CDA90 -:104140009B1C1F2CC7E1DBC6082F2477BB252BD473 -:10415000087CF7A25D115FD7591DEA730EDA372D7F -:1041600086D7973C819FC4DBB93D592D5C5AF855E1 -:10417000EC7C37C3B8716F7A1D53E0F91C68E3E338 -:104180008615ED57D8757F3BBEA69D9FD5F8BFCC51 -:10419000CEAF6976666EB0E348B29F8C764DB43B85 -:1041A000DA15ED5EBBCFBAE546761D9C1B68EF2E97 -:1041B0004E3077B209E58CD9C57A27E2E6D3B099BB -:1041C000A17FF564576913D7BB4EAF0E9BA784E858 -:1041D0003C6069E543082F47FF9DF85356D2FA77B4 -:1041E0005B2FC6CEC8757E33F0CF2A86AE9BB07FDC -:1041F00069B362C6F8027F8EA1191566237D6AF441 -:10420000B2C844D8EFB4A73AFB55EC9F34CEA58D85 -:10421000670A6CAB93FFB45C1BD9407237733B06E3 -:10422000A266FF90387A24D08E38BA3881DECCF975 -:10423000F11C71D33C211EEF617E6138D2FA7C9A69 -:104240001FB08ED25E60BF197B04F77AB0F73DE3F2 -:104250002E59D03E6525D123FD60BFFF273FEAB729 -:1042600027C1738C83206FB2A7A159356BE3C17F3F -:10427000AA35355A5B0545043B55170B21AFA7AB53 -:104280001E933DC6F30C7F66E3786619F9F5C6A365 -:104290001D69BC97C687AD5F63FDBBC63125D44D94 -:1042A0009CCCD4F9AE01ADCF0FBABB13F617EAC65A -:1042B000DF640FF79F88C954C3405F059EEF35DB6D -:1042C0006E05FB328E8F6F789EF6AB855C5C256148 -:1042D000BF3792D7E9D1FD38B65FD9383E7C237D10 -:1042E000A577D197868F0546BCB8CCFEC39F821CAC -:1042F000AE74C1AD82FD97F893363017DA5FC7F719 -:104300008FFC4A7FD85F12EBC4AB11DF21FF44D092 -:10431000E312A6F76F69C673C96FEAE4E778DF2B8B -:10432000748E2F00FCB8181F3FD1D3D2ACDAC91E4F -:10433000D44F74EE0DF0DE9A408F4BF00F0DDFE49A -:104340009F18B7413F79DDC48D4A4DBF1705361B15 -:10435000E35E6402CFF7225EDE3678787EB750D314 -:10436000E352AD8D24C7E9A17FCCCEF00BB302C3DD -:10437000BE494F77A76BFB56C3FEE9B0AF482A1B77 -:1043800022004E56B4EC6D6ECA8A8DFF564BD88F04 -:104390007AE89C4FDD17C1B87FB7A6A78696FD11B6 -:1043A00095C73301FDAE86000138D823A822ECB3AF -:1043B0000671D0CD3EA775F51B3561BC22DD607C52 -:1043C00079571C2A09E39994FE75C66B769A9E600C -:1043D000C72909769C984057E874C810CFF438571D -:1043E000D5B671756F9063F176018F098CD7166120 -:1043F0001863CF78DEF0DB47235E65A91FC4FC6736 -:104400003D6F456C80E5728C6784DFDF362B6097EB -:104410003BD1DF897EDBAFB8103F75AB33813FE422 -:10442000F95DB30D58EF69DA28614EB3D5F34EB399 -:1044300019EC77F7C85F1CC1F9CCC2BB91E9C20D7A -:10444000F0DA9CB08FCD09B49AC0FFF497C4F7A6F8 -:1044500084F12B13FA3724D09B12E8B5C6F195737B -:1044600005F2934AB01F2AEECBFCE6D79ECE7CA184 -:10447000F33C13EC942719703FAD91D3873D27FD92 -:104480006B0BE3E8960FF47848389618FFDD9BCE67 -:10449000543C3FA41EE2D9AE9EE25941E279C7FBEB -:1044A000FF8A7FF6C5BC9319CEE543A2913E20EA70 -:1044B000FED61179D88E0F75FA921FF3F169DF37A6 -:1044C000EE0BEA42ADFFA27F22F8FFB4EFEAFD1740 -:1044D000FD4ADC3E75FED27F5E1771BDBFB45CF055 -:1044E0006F85F92A2684F3EAB04DE52D9C33229E90 -:1044F00063B536EE4FA5AF897E3C672A92C379CB70 -:104500000AE3F6C95AF3719F075688641FB591D71D -:104510002355CC6761500A1D70B9EA5F00FE432B3A -:10452000C47A3CD74ED4A7F546F9077B79BD77C846 -:1045300035A0F783401F4899639181EFC0E393A8AA -:104540003D282A6B3A00C7573DD7FCF641D8EF22E9 -:10455000FDFCBDE58ABF01E2F4158F4CE303A9EE33 -:10456000DE6D98AFAE97D83619E5F13D4FB8F98EAC -:1045700075D87A90A3B261706FCCDFAABE575EDAAD -:1045800017F8AA564B3E81F8D850943BB07E92055E -:10459000FBE73669AD3A99DAFD5FEC7E7328F07778 -:1045A000AC137D5B8079DF55AFB30AE4FA3089C77D -:1045B000E10F2EE43A51CEEF7A03A217EC5AE974D8 -:1045C000240B7878B865E74C9877438E62F616C569 -:1045D000F8F77F21CEC17CF3D50B55BD03403BBD21 -:1045E0001CAFFBAE56F5AE8A3BEFE75D34939EF70A -:1045F0005BE48731BFDC9F9C25A8E4C7AD69E5E09B -:104600002F73B5FC1AF052BFBB9B73FF1F1E917036 -:1046100076CA5ACF3E04101FF876C63894531F57F7 -:10462000F4FB40A303F1DC5F1E1E9F47BBB227DCF7 -:1046300084FB88E12CF51D3C2F298F063ACFEBDA5D -:10464000A802AED821C8FF518E74A514FBD94A60C8 -:104650008038C6325BF3E3EF236279EA2A2D1E70BD -:10466000BEE3AA83EAD6E33B924258CF1C57DF73DE -:10467000307B3C3FF793F94E878A87F11987C38CCB -:104680007A3D610E9E7E14C6CD7B4EA2383AEFB9BC -:104690008C951D180FC09E79ACEBBAFFED9568DDC7 -:1046A0001EFD84C9E513C7C5F9893AA01CF7D39349 -:1046B0009FDCE61D50BEB5B0673F99AFE5EDA5CFD5 -:1046C000497EC4F9FC228799DD0C75F673AF6F4300 -:1046D0003CCE5F9A34DC0A82CF7FCE4AF68D3A1CFC -:1046E000AA1BFA034E87B917B4FFA5E121DA90445B -:1046F000758AD8DB42714F5C5324A37E4A4466B668 -:10470000C1B9223A7DB29FD34D6EA8DB563B8A6574 -:10471000B4EF0AAF4C7AEBEC77CDBE5D80BAE632EF -:10472000EC230DC69DAB7FEA995120DF79169A35AF -:104730000AF47E190D0DEB5CDE238654AC8BCD8A1A -:10474000B90CE2DE02C6FDBDE6E86ECB78F8734137 -:10475000DDFCE9581F2D0C491F44B5DAE73AFCFF90 -:10476000197BCB82F9EDE2EDC6E7E03116F4AB9AA6 -:1047700056E3F35AB6E1137128B6E60FA205DA73D1 -:1047800058B7FEFD3F0F391CC757ED75A49F1E0C8F -:104790007F0C67C341B3B04EA1EB2E845DBD48F2E0 -:1047A0008AAB9242A847319B9F0F9399104A42408F -:1047B000B861DFB0EE95E0B121870110E2632348D4 -:1047C0002FA78280A781A00FA78DF8C5C7C4901519 -:1047D000D62D49634A2FD4E733E58C39489FAA1B6D -:1047E000E8C9E975668C4FE7B4F85229307F2BF998 -:1047F000BD2F1BEBE379CF2591FDE63FBFF08F3F47 -:104800001889F62A4B8FF7A3C735DCC17CCC961AE2 -:104810009BE74CC3B7B2519E921F415D89F5A61824 -:1048200078E66E8A97293E8A5BEEE87746214E1A33 -:104830005286AD678893BED9DEC2D8F8F9AB56E48C -:10484000F3F150AF3A315E25D17EAAF7580927958A -:10485000EB4485CEC72C0B9D8F1F3425115DDDBF2A -:1048600098FCACD2C402B80FC8053329AE7395B317 -:104870006A3B5376DB31CE6F88884EB28FAAD9CD92 -:1048800082F6D9E24DA3F5E7A08EE1DC3AE8D5F453 -:1048900062E2F861FB84D0368A4F7532FA7F85492F -:1048A000A03897E88FBB3109C371D9BEFB715CCDCD -:1048B0001356DF2A0F9741D4E5013CD59822F37EA9 -:1048C00088F3FED24AF71AB5B08F2427D517CA2E1F -:1048D00090BFD6CCCC16BC9792793CD3E5A995CBAA -:1048E00027234EA1FF9819FA6B1C3C1ED7F4E2F760 -:1048F0003DCC610B6D8B5F0F65CEE1E36427FAD988 -:1049000068C20BFABD09FA2F31DE5FE22C96A3F0E4 -:10491000BCDDC4D6E23D09CA336868DCBA40F71D85 -:104920008A785C6AF63AD00E69B366E37A2F891406 -:1049300097C0999E28C6FCEF257104D6B195EB0E61 -:10494000956E427AE730378A50F9F377E97C5AACB2 -:10495000E12C8A793F9E5740EF84F63D2FCF2F02FE -:1049600022BFC779CFCBF37F5DAF7A7FCD3A89EC99 -:1049700051B39AE3A1A6E14F346F8D23D21BED51C1 -:10498000F3B2740BE2FA941627AA1AB2C61D037C7E -:1049900054492EB7008FAAD5320BD2D5CD02D1FA09 -:1049A0007A35EBFED0DB54C8E7C3D6AAE128366FD0 -:1049B00046369E671FED48CBAE8CB3FB474DAF38F4 -:1049C000653BFA4D38CF8DF7304B937C5BC84FB9C0 -:1049D0003D3E6ACADB82F73473DD118700FD731F29 -:1049E000CE49C573EE843B6CC1FE13AD1E13D28A53 -:1049F000DB3D0E69C57C33D11F41086FD5EA56C433 -:104A0000F11281E3A67AC7218B17D64BCAE138BBD6 -:104A1000F8D2BBF9785F50931DC9C7F3177095DFC3 -:104A20000FEDF2A24079C2921DA292343486AB25DA -:104A3000882BF0FF451AAE96EC79E511F4D3258862 -:104A4000A7E15D710975E5617ABEABA594F1F187C7 -:104A50001177FA790F749384F76A168D8675904EE4 -:104A6000CEE1B881FE89BC5F2DA47384452D980FDB -:104A7000D78A3C4F007FCAC43CA2B64D523BE325C7 -:104A8000AE8BFD85B1FE9E703338879F27550D563E -:104A90003A8F066B7A89AE7BD989B8B8F8D2A12350 -:104AA00063B0BEDA25B831DE77F1434D6FB5A82784 -:104AB00027ED93F2A25AD48B33A6A74E7FD3705121 -:104AC000CBB81E74BDD49A353DE9FDDAF8C21C8E10 -:104AD000C36AA6E975CF40EEEF9A7FEBE788BEBFC9 -:104AE000402A1FAFE3EBBE1C8EFB31DA3EAB013731 -:104AF000BE42C29762B945ABFBA1EBE2CE16BA3714 -:104B0000D2EDA9CBBD5C5B1FE2B4D22B3566E7A822 -:104B1000892DE8EE9EDAAFE94FB2F3B872B2A1DFA9 -:104B2000FDF5A0BF453B441F290F6BAEB875ADA680 -:104B3000A883F2D2C74437EEABE467E5B7E3BE75AE -:104B4000DC49DB0573DB48AC337A91FE75F94AFA30 -:104B5000F86FEFC57117467974394F0A61B297BA89 -:104B60005370F33C376AC1FB43DD4F13E5BD2F475C -:104B7000D0F201618C7033CAE393D1BF199C8324B6 -:104B80008FFDD80A5A4F3DBEC23334B6CE09D56127 -:104B900046BE138CC7011D9727B5FB8893AB5FA159 -:104BA0003C585FE7A1AEEB04EAD3BBAEA3F32FD62C -:104BB000F875BF684FE5F82F69FA13F1E971167FB0 -:104BC000780FA7EB53D75B9C5F1AF4A3FB97EE4FCC -:104BD000BA5DFF55BF622B33285F7D5CDB37F94838 -:104BE000EFD8B980F8C4F3CE6A015CDA0DE726E5A8 -:104BF0003593FB7F620974F35CD753E2F3583DE5CC -:104C0000CE46FD4FB6679A300F604D998773E3F239 -:104C1000B20FF1BE0BE36906E3EF33187865DC7978 -:104C2000AEE76BFA790DBF0D9DB884F1B5E9CA39CD -:104C3000EC5F3072693EE6119772BCB4EE79D66AC9 -:104C4000190FF3559F8D943AE558BD72EBDFC3A25F -:104C50000BEF03F7780CF542F585C3E4DF352CB292 -:104C600006EBDBCA75EF968D42BBFF14F271E09B39 -:104C7000DBECA173EFDCD6074660295BB93A8FE81D -:104C800085DB1EE4F43A9ECF55AE2E7A01EFE33F6A -:104C90004C524A11DF1D1B0537D65B63B715ADBCFF -:104CA00007FAC73A06F442B98F6FFDB06C0CD60D07 -:104CB000F522F98BB2F5A959D8AFB4893EDCEA5C8C -:104CC000E65E790FE2DBEC227F3BA19D138D12C7DC -:104CD000D91B5A9C38A8C58D831A0E4B1A1BF34D4D -:104CE000B86E0B9C4FB0FF0A8BDC1AC6BAEFB53E0C -:104CF000BE2DA82F285333014767059E7F2FB03064 -:104D00001BE2EAA814598EF21F5DEE18D6800288C5 -:104D1000D76E41BF50B43A0BEA265A57D797BEFE1A -:104D2000512D8EE8F3E8E3DA319FC2F34393F75C49 -:104D3000D34F67619E706E7B5E2A8BD3FB39DC1785 -:104D4000E87B21C4C55DDDD47F7FCCD1EF23427CDD -:104D50001DEDDEF0A8D4DC1FDFDF421E7F2A3E2FD0 -:104D60003FD39264433C421E6F7C2EF1F304F278F1 -:104D7000C373F09B53C67C5FABEFC40A57A09B384C -:104D8000A4B78979FEB91C7BFAE914D625CFD7FDE3 -:104D90002E71BC9ED777DEB3BC6F4F781F33CAC568 -:104DA0006EB0FE852018066ABF16F45D907762CA61 -:104DB0003F7747B09E6CB6BAADA0DF53E857F81EF8 -:104DC000F06591E78936E60B032E4EFD61840FFDF9 -:104DD00070DEFBDCEFE6B50A217CC57E78E3E322DA -:104DE000F23FB859607D84B83AEBE98DB3D0ED2E2F -:104DF000FB026BFA02FFE5ED824F2509157B427D30 -:104E000075A4AFDC737DF5EFD655FA3D53A2DE33C2 -:104E100073B5FACAC77C46BDF3FA7C3FC0A7787861 -:104E200057BD5F0806A88EFA38B880DAD1AD2D25B7 -:104E3000FD40FE4BC2C927C6A2FF385C744F7221E9 -:104E400058472F013F6E1B716D06E8E755BBCB8DB0 -:104E500071E3E3603D3DEFC48B86CF5BF71C10FB35 -:104E600031E2DF3B16F8F7D95DF85AA39BF76DDC0A -:104E7000BE9041F1F7A35ABDFDD0D2517DF0B9BE2D -:104E8000DFF38F723BEBF29FDFFE8013F3D3033F20 -:104E90004CDB3B1AED9BE272238CE66F12596004E7 -:104EA00063A737F13874D6E67A613AE8EDECE63B71 -:104EB0007B633DF8A0D461F1C1BCBED7CA9D787FA9 -:104EC000F63773D4E9C616F8C32887392462FC1B69 -:104ED0003385D17BC0316133933DF48A9E7032FAC1 -:104EE00082391406FA237C3F88E7F6B564FE9E5E9D -:104EF0007BEFF7E0AFF87D5AE7FD89768F3056DB20 -:104F0000EFC3B9A95C4FDAF39262FEFCCCE6DD3365 -:104F100070BE735B2537CAFBF15689E65F0475BC2A -:104F200009707816F086F16BD1EF451F42FADC76F6 -:104F30005E272F02DCE27D71CD5249B1B8BAE2B1F1 -:104F400044E7DB2B507DADE37291122A25BD6BF84F -:104F5000B4C17FD7E1C8E8C55AD7A03E1271FAAFF5 -:104F6000D6FD8B1197DDC583041CE8FAD2F110C37E -:104F700027235CEA764F6D1D36BE1F0D50295EA8B3 -:104F8000135801E6058D165660461C98927DE8E799 -:104F9000F536E750BC67BA92C4DB474CEED7B15E3A -:104FA000BE62922501DA13B91EB2C323A26F12D2D8 -:104FB000527A94EE07C4129362C2F3AED14AF12240 -:104FC00031DE3C9ECBE3703F041BB43FCE75532BC8 -:104FD000B13ACA1FF416369885F949794AEA673218 -:104FE000B03CBD75CA4C33ECAF7C6CEAF21CC82CEB -:104FF000376F9D3113DFEB968F487DD90BF4F3B9F2 -:10500000659CBE39B54802BAA1E18E991381FFD5DE -:105010005CE5C9DCA2D83AFABCF0FC7BB940BFDE43 -:1050200027B009DB5A8B7D2DC6FB4B42C712931864 -:10503000E37F4760275E1562745462D9984FFF186A -:10504000DF7915F5DC9EC9555A72BB795EC5D86A01 -:10505000D46395FA9B6398AFC1CF6F03BCDDA1E128 -:10506000ADCA660F232ED85AE942272EBC18975C8A -:1050700066F4EF199AB9EF30870FE0F841ACC97DBB -:10508000DA46A9E0E6EB693DC779704C765A9F0F86 -:10509000F6774982FD825D05056C0D2E2580922BE9 -:1050A00020BE097B7FF339CEDBA8B26812D9A1C23A -:1050B0008D71516001D375686B52000FA0A7652FE9 -:1050C0005F3C8CF05FA8E75399FCFB8CE51A1EEF60 -:1050D0008828DF6F01A1CE04597A2ED8FA223BF836 -:1050E000B119D63D670AFC06F55D6D7A2B7B998C6C -:1050F0007EDBE8C4FCE5E2CF45DF741857ADE5ED93 -:10510000EC9A18BE0D9EB77B066D591F87A3482EDB -:10511000CF172E78C2D92B307E7878DDC9AE1DCA64 -:105120005E01FC53BC538BF05C7A9A29FF931BF70A -:105130007E7186B9FBEF2FDEBC89E73B6C2B3F5FAE -:10514000AD66A63A52A9654ED0C75490A518680915 -:105150006891DEC787687DE473629E223F90C9DF55 -:10516000D7303FFAA36E47DD3E5DEC0622637E6ECC -:10517000B23109FD6510DBEC46FFD6ED3749B4537B -:10518000BC59F632BF8F5B26449BD2907E09CE4B32 -:10519000D497E6975DCFCD6D1634C582CD0F507C88 -:1051A000D2E3920CFF217EFE53F792D7F57373186A -:1051B0001B86B8FAB27C478F4B601F4B5EC6D7B0D8 -:1051C0000FAA08F63B5F5B7B9258219B512F193643 -:1051D0001FC6E565CFE5D079C79A9E64F17C6C73F4 -:1051E0001AE1738D47243B96B5F563323C5AD826B5 -:1051F0003019CEB9E96D69443BAFF625BAEC277D8D -:105200002660FEDFF9DEF22703893EF7C29B230307 -:10521000FC7EC586F3FB992E47612BE64397ED2074 -:1052200007D8C16F5F4BF7857ED659C708D705A44D -:105230000125E84F8AA472BBD81AC8AFB57D2D737B -:10524000733B2E3BCACFDD65E3F9FB3DB33AC8851E -:105250007890DA451602FA9B47C5A230B0366A71DB -:10526000D99A6962729C3D92E46426C7D56F4C5509 -:10527000225827CDD6709252906AE87F5C08482861 -:10528000D76CFB3CC28DC3779361BE4876693BE91E -:1052900023C0F35B1D4F4CBC6046393F1B27B03425 -:1052A000C0C53767437FDCBCD2B84F260AD41AF397 -:1052B00062D0CBA91BE1696A9E86A7416C10E129E7 -:1052C000413FE01F947F5E86731CD326C82EBE3FED -:1052D0000EE859ED120BC9946F92FF5C5652E8FE2E -:1052E0007EB5A6271D77FE81CCA1C0BCAE62A3DE31 -:1052F0007A2946BDA54D31EA29C36FD44B9FD95EAB -:10530000437FDFC0370CFDFD160C37D05975630C99 -:10531000FC03EA2718688F7ABB813F67ED4C039D39 -:10532000D77C8F817FE0A62A43FFA0D02243FFE0F5 -:10533000EDCB0CF490D6C70CFC37B7AD32F40F0BA5 -:10534000AF37F48F687FD24017459E35F08F3AB65D -:10535000C5D03F3AFAA2A17FECD95D06FAD68E5F9E -:105360001BF86FBB7AD0408F676F1AF84B6CEF1A3F -:10537000E849EEF70CFC93333F34F44F953F32F499 -:105380004F2BF8D44097F9FE61E07FF6A6C0268C3B -:105390003FB34D1B8EAB0CE3B3FCDD7180E7BBD29A -:1053A000CDBE30327DCDBA2D94A7E5691A6E3F632C -:1053B000F6FB4DDE2F8F83AB312FC8405C4F6778F3 -:1053C000DF7BB955205CF7743EBB20DF35C7EDA30A -:1053D000976283023C46A74D711BE80C7FA681BFF4 -:1053E000CF6CD9D0DF375060E8EFB7C067A0B3EA21 -:1053F0008A0DFC03EA1503ED51A718F873D6FA0DD0 -:10540000745EF36C03FFC04D0143FFA0D00243FF65 -:10541000E0ED75067A486BBD81FFE636D5D03F2CAE -:10542000BCD6D03FA2BDD94017453619F8471D0B51 -:1054300019FA4747B71BFAC79E6D35D0B776B4192E -:10544000F86FBB1A36D0E3D951037F89ED1D033DB8 -:10545000C9FD6703FFE4CC9386FEA9F239437FF5CB -:1054600047003FCC9F5F15E8FDD7B4824F0CFD523B -:105470003AE4E9783FCD927DA2D0354FD7F3B732E9 -:10548000DFE786751E31D5D17771574C3CAFB3E459 -:105490007B097790BFDB6C1467E1841A42572D0DAE -:1054A000989FBA54817087A94605DD17A6D37B055E -:1054B0003A1A65FC0E0DF21B20524D1E0FD60F2915 -:1054C000B13CB4FFF5115F3D0F4DCF67FCBE293FE6 -:1054D00090949F81F5D8CE52AC4F1632750DCA010B -:1054E000E7AB0BDF33BD9D64BC37D2DBA936D05FA1 -:1054F000DC7A47939AFB0FBF81DF4EB55D20FECE6D -:1055000079B57B2501F6B72C6EFE27A06E324309D4 -:10551000D91C04FF023F7D32E826FAE96026D1CF8C -:1055200004656A37050BA87D36E8A3FECDC162A2EB -:105530009F0F2A44878253A8DD12F4D3F3ADC1D95B -:1055400044BF100C50BB3DB880DA178375D4BF231D -:10555000584FF4CF832AB5ADC1B5F47C57B099E864 -:105560003DC14D44FF3218A2B62DB89DDA5F075BEE -:10557000A97F6FB08DE87DC130D1E1603BD1078359 -:1055800011A20F078F117D2418A5B63D7896DA3742 -:10559000821DD4FF56F02AD117B4FBFEF1F9FC5E50 -:1055A0004ED78B4E333691F0A0E7B533B06E4170D5 -:1055B000144B1F1BEA9684FA21D11EE7B575A40986 -:1055C000706C639E7353FE96C6B87CBF4C5BEFF164 -:1055D00064A62641FC6BC0621EA0D890CA428DF41E -:1055E0007E95E7DDF3355CB2749E6FCFD3E49AAF5E -:1055F000F94311E2B380F0F9D6D7A993F43AF95BF5 -:10560000FD03F7113EB34C2ADD13D843F998F78711 -:10561000FA0702F920DFE5BA078FD07A6E5F3E2ED7 -:1056200052660D67DC85F73F4745BA2FED69BD5AD5 -:10563000EDDF2FF4D8BFEF5C7F3C87A67C21D27DC5 -:10564000FADB926336DE8F2CD3F4B22CDF6468076A -:1056500066F997A29C67F2EA5E7808582A96E6B93E -:10566000306FBD034B6BF0FB72264BF47D2C535E09 -:10567000C74F26BF09891DD2773195DA9DFD028F6C -:10568000E17EEE860202E9C0186B7677FB4994A7AB -:105690004993A74993436F2766F91B71BE53798AD3 -:1056A000419E47B364ED7BF78EE751AEFF7DED93EE -:1056B000D3424E4CDFFABDC49AF1DAF7534B05FDE5 -:1056C0003D35CF076D4CCF07A9BF6239BF9FB90FDA -:1056D000EA327C5FF9BE160F2FD749142F2B846452 -:1056E0001FE6D397EB960FC4FD24C6CD0A18678238 -:1056F00071158C7F0F51F17E0AE10BE663F8DEAD88 -:10570000023277ACFFAAB3F47B8FA83D83CBA3E032 -:105710007BD8397BAD2D58A7024EB6104E468BAACA -:1057200005EAE4B74DA17C41247C580490777E3A89 -:10573000E0A39BBC40C7C112EDDFC7E8CF015F3BD0 -:10574000507F1FFF6A5401BD37D9375A46FD359A3D -:10575000C01E785FF386C8BF93C02B76FC8EC355FE -:10576000D842DFF9631281F61AEDA0F721074456FB -:10577000BFB39BF8F9DB7C5E5FBD9D294D09D1BCB1 -:10578000C6F77C47343B1ED1EC5B76F068D62330FD -:10579000EF927689EA1D36325AE8EFE6FBA6DAFA8E -:1057A00037FBE6C6EDA3B6ED24FF2E8A450BE3BF1B -:1057B00087FA9BB6BE8E27D1E208B4D8E3E5E3F7BB -:1057C0004580EBB7345C9FC6BC7E865576DD0543CD -:1057D000A3A09A30B4811FB9E9BB3AFDFBBAB9CC9A -:1057E0004FED7C8003E2D8AF6EA4FA77116BA5E78A -:1057F0004B8A1FC846BA96754CCCC4FA656DC3EB8C -:105800009920DD9DCD1B27E1FDF3CC50E5EBD8962B -:105810006F154E63DD0D7E711CD78F0A75ABB124F9 -:10582000BD67C7F8D578CF3B43E476606F723B0025 -:105830008E1431B5EBFEC00F4EE178F003925FF7A6 -:10584000838A551C3FFABFC7E8F48BE2C57FED871A -:10585000EF3ECC1DF45D48ED3E6B2AE26B11569E87 -:10586000627C5EA89FCF3C2F580C7901F29D97B8BF -:10587000FDCF1F4FA27FF7725E007C0CEF8A7B3D4D -:10588000CFBC62E2F76E8F88B04511EBE5A7484FB9 -:105890000B6CA1A1A827389FBF401C2EFAB075CD74 -:1058A00030BCEF9B10CAC67C557AD1EA6BF418E283 -:1058B0003CBB9E12BBC77B42E2F76A89F276C95BAA -:1058C0008A8F7C8EF984D5C2547C9F04FECFFDFE66 -:1058D0000497FF8A2990798BC8F315AAA3FBFBA92B -:1058E000FE67BD6DBEF542D7F59BB475DBFFC9EB16 -:1058F00069358BD1F7388972086EBE6EA23CD664CA -:105900002E877EEE749587DB4197277FA087DF5334 -:10591000642BB4EF06532F8A5F97C440DE403C2FC0 -:10592000B5FB31BD8E6DF79CA1B8CEAE35F6E7DF85 -:10593000F7867B3A4F2F74D6CFDED879A7DF33B105 -:1059400071DDDF0BFA6D6E09ED3693F928EE0F620B -:10595000EFEBFAA17BA6FF0732EFAAC6A039000041 -:1059600000000000000000001F8B08000000000085 -:10597000000B7BC8CEC0F0A31E82C539106C6271CB -:105980002D0B03C37B56D2F5C17005507F3110E754 -:1059900001712610A700713C104701712810BF0249 -:1059A0009AFD14881F00F16D20BE06C41781F80C03 -:1059B000101F47B277291B03C31A36D2EDFF8DE4BF -:1059C000E70940761910CF20231C46F1F0C0723C45 -:1059D0000C0C5ABC08FE5E5E5479791E047B99203B -:1059E00065766D05EA070050DE58A18003000000CF -:1059F00000000000000000001F8B080000000000F5 -:105A0000000BD57D0D7C54C5B5F8DCBD773FB3BB2D -:105A1000D97C10120870F3014608B8240141B05E29 -:105A20003E8CD1A206B4482DD505F908494822DAA2 -:105A3000CAABBC66490209883628225AD4054141BE -:105A4000898D7CD8D406FECB4731F6A98D1615ADCD -:105A5000B641FB14154844119FB57FDF3967E666F0 -:105A6000F7DE6C08D6DAF75EF8F19BCCBD7367CE33 -:105A70009C39E7CCF99A898D6532CB10C6BEC69F9A -:105A8000CB18BB59668C8D8994A3EFBCAEACA90032 -:105A90007EFF9BCDBF558DB4D3CB214CA2768CA578 -:105AA000323696B1CB1CF02BB49BF2FC893F5D944F -:105AB000CCD87E26333B3C0A2B5392AE867EF67FB3 -:105AC000C5FCF8DEF2BC3BBDC38DDF05194B61ECB4 -:105AD0007B8C7F17CE50D37DB95861167CAE39E8E8 -:105AE00077E8276B63157C7FE60B377D6F86432F46 -:105AF000D957161616DF7C9D89FD2A9F75E4887A92 -:105B00000683C19980379DC6D5E13DF4CE0704EFE9 -:105B10000105E055638CEF00F89323F0EF67D7C5DC -:105B2000B35C0EBF363602FF378587E6DF8FB1FAEA -:105B30006AF5FBD956C6EEAE66DFCF1ECAD85DD574 -:105B40000EAAAFA8F651BDB63A95EAF50A7C0278DE -:105B5000A8DFC64241F8DE5B00EDF5FEE0BF3BD7B3 -:105B600061A8DB92E17B47A4AEB8530D7547BA6AD2 -:105B7000A80338475261DE23F823181F7060C7F16D -:105B80001D4CBB00DF0F25BC3805DE6A3DC36EC867 -:105B900004BC34BC22332419ABAACD42F886BA6DBA -:105BA0006A08E01BE15E308D79615C6F8031685777 -:105BB000FB2063F7C2F3E1EEC20FF1F913D07F03CC -:105BC000F42B7B1B8EDAE1FDAA0C9B2A235E762840 -:105BD000EF229E1CF00FF196B391D723F332D687B4 -:105BE00033A8EBF380EF7F9FB0FEA80470D466DB90 -:105BF00054BB1419A77B5DFAE87FD8BA73F73F54FA -:105C00002D9E8C74AAF73B8C056A7CEEFFBDFD8E41 -:105C100000DC26E545FAD5C7E9B35F58FE62F876A1 -:105C2000D846160A4B3DC719AAFA8B82B8DE1B1557 -:105C300016CAE0CF93811F860A7EA84F9FE10AB85B -:105C40007BC2C3A2C7C98CACCB50D536C7320ACAF7 -:105C5000EC996512D0075B17F55D262750E4975F36 -:105C600054FB881EEFAECEA1726BB54F433EB9FB1D -:105C7000EFF2ACE6DC9E7CF8579453F0DD3D5646DF -:105C80007418DCCE425B25ECAFEAE81CA8AF199D86 -:105C900092B75A25A02D28C774FA5E23A944DF4184 -:105CA000A06F947F66FEB8DB5A7C15D2FBAAD11692 -:105CB000A906F19CCDE97DA835ECC882E76BD665D5 -:105CC0008E0688D91AFFAB1D38EED0A1C388BE87D7 -:105CD0006773FAFFFD98F50E9483DDF35F9AA26572 -:105CE0002731168FEBE38EAC97EF3CE9C037310AD2 -:105CF0005F31E8401FE79FCD0FDF1D7D359E93BECE -:105D0000D6F8333FB4C3FBADC0E7B2D413AEC42161 -:105D1000E1D4E2DC9EF436341BE80CD7C97F6E3A3E -:105D200033976BAB43EC3D187C7D752AD1DDBA6AA5 -:105D300095CAD54887202751D6B0F150473AC4F5C7 -:105D40004A2FA07AAFFB155B4EFB51C2D410433EE5 -:105D5000598FF479093E5FA169B045F5CFD1EB2C9D -:105D60006C01D9BF0EDF0FA0BA865BD85D925E7F53 -:105D700026A8C1F7FD7278BD507A26589B0DFD39D3 -:105D8000F9F745D2292D981EFDFD5D9A3631D21EB8 -:105D9000EAE1C9D9D1FD41FFB9D1F01CA4F67A7F5F -:105DA000F3A4635A10EAEB9CBC7D8374F45FD2FFCA -:105DB0006AA93115379A5552375EA89FD57A3DD8D2 -:105DC000A869B9917132963FAD05A3DFB3A70DEF76 -:105DD000C72E6F0C06016F0FB0E22C09D637715633 -:105DE000552AA844CC393BA459D568F838BE23F3CA -:105DF0005B4FF0BAB2F9FB5CE98F5A6DD4FA4C9262 -:105E00005E0E22FCBA7E63E5A4057A4FFA6D2F027E -:105E1000BD5BFBDBFCA467A443250DC69B1A642A6B -:105E2000C06151830CE5815555DE8FE6039DFE0070 -:105E3000CE71046771D5AC5EE00C46C3A9C3D1171F -:105E4000DC3A1CBDD3291FDF4C4F936F1CF78789A9 -:105E500040E2CE76AB1FF53C54995822FCF2D57D3A -:105E60009A025DA6DC04B85769DD66B1AC9EFDF60A -:105E70009F358085A2E6F9CF5ED72CAC8F21BCDDA3 -:105E80002C8D89AC2FD4E744E3719C6867A63F7DD5 -:105E90007E0E9C9F1A3DBF5A4D2988CC8F298DA913 -:105EA000C59EBEE7B7CE593CABD8DDB3DDEF25AE1E -:105EB000474F9E31EE5AC6C72359928CE3E545C63B -:105EC0004B9EA98F178A395EBFE2EF169F667ED47C -:105ED000E17522BC19D1F0F2F5D7E15D6D05BE8DFB -:105EE000B1FEDF35BCE7CB7F2E90BF2A7C6FC901A6 -:105EF000FECBED9DFFFED9FD25E3AF404F9F2A2C41 -:105F00007C19E0F1F6E98E50508AC8B97F35BE524F -:105F1000F015ACDFED2FDD72EC320B5680AE47464C -:105F2000C6AF905482BB37FAEE6D3E8C850CFDFCFB -:105F30004FCDA737BC7ED772E87CE56BCDEB2E6EDC -:105F4000DF65B310F27F7DDBE5F10CBEAF7F714AF8 -:105F50007F84C3DE308269F98CDD8F9F805E512F94 -:105F6000F45D767DDE79E919ABAB995607FACB1E65 -:105F70006F15E945F512A3EFD780DE16023DA6E0C6 -:105F8000952D8E396ED4ABEEA5B2DECA488F297836 -:105F9000E5906F0A4CC135347134DA79F54EFDF96C -:105FA00091A22C787E57363C07D2A8F7F0FEE07914 -:105FB00031B68F1BCA9FF706571CA84D75517877CD -:105FC000DA428158F2F17B160BE1E75ED4BBECA814 -:105FD000F7AB543A5D8D01243AD7609BBA39A3E7F9 -:105FE00077B32C5CEF5F3BF4D9306E73AB84FE76F5 -:105FF000E0F2C7892F5DD98D9A05BFF773D7C0BD71 -:1060000026FDCA9DABD753A529B067BA4CF5BBF5A1 -:106010007D37A84E427DCD2BF49D4935974EAA8DF4 -:106020007ECF2E9A84FBAEFEFEA69A31F43ED1516D -:106030007574228C9F08F2B316594751A52AA4976C -:10604000EB1363D2CBDA2B1DB342F07EEDE5C33206 -:10605000E6C7B0736015699DF57A529191AEEF1560 -:10606000FAEADD427F4D451E8F926B4EDEB45BAE89 -:10607000392FE072CD95A32E47BA4C2A627ED4B355 -:10608000D702FE0251EBE4CC01F9166577242AC64B -:10609000797D57F37980693FB4F4EBBD7F337F3D61 -:1060A000C00273B07DA2D8A75C397E2990DBF7FCD3 -:1060B000CDF3ED6DDEDF17F884712A628DF3AFC288 -:1060C0004BA21BC629F8E78FE3C271A2FD45E78901 -:1060D00077D84784DF8DC9B80F98ED2A57814F6272 -:1060E00016AAB6A3FD9D84AF00EF1ED658340CF857 -:1060F0003AA978E5AD68AF79DEBEF243360AEA1D0B -:1061000073A66159979BD73619DAC5FB7DD30B89E6 -:106110004E19E1791576467CB768F924981FE1009D -:10612000F8EE51CB4D9382B99CBD71BD7F22E682C2 -:106130009AB7A2EFEB99B1E66163618E5FE96B7B81 -:10614000CFEF7B9BBF35F29DF0F72D213F695FDFDD -:10615000B16936F21B06E11FDAA309A67EE2355BC0 -:10616000C4AFC8104F517578FF42375FDFFA2F195F -:10617000CFC7EE75A8A807655B7C68A7C7335F0229 -:10618000EA7FAEA9A00880BCF02577052D6ADFEB79 -:106190005207A605ED674077D3A3F4DB3F5BB87EDB -:1061A0009C3C636AC60AE8F74C01F70327F9B8DF9D -:1061B000C13C9FBB603F0BDBA3EAB99B897F6B812E -:1061C0009E32812F82B916F267AFCADEE98BE66B89 -:1061D000264B026F66FA60AA027894057DC8D9162C -:1061E000CD39EADBD387FC0FD247DCB4A8EFD83730 -:1061F0005F2F8FFCCDE8E3DB8EA7AF6B4FBE5A2E2F -:10620000D6759E03F59B95A933E263C9D9DED7F510 -:106210005E5A57B067B5508CFE13BBD733D8B34C1A -:1062200011EB493FB719D64BEE3F76D6A673AD5B5F -:10623000B2111F7ABFCEA5B2FA57145E8A8FFCE462 -:106240000ED1DF2AF5DE20EA2967706F077CC88D42 -:10625000A3C3B89FB26CE6DFCA9B901EE254B5D0D0 -:106260006AAE2FD3BAE8F0D9D22D86F194649701A3 -:10627000DF6C1668D951F03B97DA080E078E07E3FA -:10628000C83EE85042FF3F0B3BBDD423F587437D1A -:106290009D85F53B0D74509F9E1773BF53C4BAA2E2 -:1062A000B9CAE9F5CEF3932FE6F1AE37C27BDEDF54 -:1062B000B915F5FD283F5DEFDF29EC7D1D5F80C43A -:1062C0001F77D33B5FA79556D622C5833C489DC90F -:1062D000022AD4F115EC630D588E473ACCF3915E47 -:1062E000B04D52104E626915FFF3FD6E382AB5406D -:1062F000B7164780F024BB3546EDD5F3DB0FCF5AF8 -:10630000B99E9C2C3143FB65B28DDE2BAC98A1BDB0 -:106310007CF69D2B52A95F0D1E8D8DC061EE77B866 -:106320001C58268F41B2E3F0E007E81F601D39E4F6 -:10633000CF4E13383B3B7F06D913BDC1F7A089BFB1 -:106340001E14F6012B2EE8635E9C8FCFC298EDD809 -:106350005E515D380E3B9E437CA08AF1370733E9DE -:10636000F9E68673F3F92F110ED04F1FAD7650F971 -:1063700058B58F4AFDFD63C2EED922713B447FFEC2 -:10638000B9CCED845699EF179B1D8D4EF2431F7CBF -:10639000F0CA61C05F038EC87E27E02F6B913F314A -:1063A00010435EE865F61A23BF3179F639E15DFAEC -:1063B000F6A4E987A2F8B149F624BF1F07BF5CCC59 -:1063C0002E46FAEBEBFBB3D5DAF44343BF3D5EB6A2 -:1063D000083BF4F3DA9797939E13BE8CF87380A072 -:1063E0009B01E55C1EA8752CA422FF7EF5358BA6CB -:1063F0000FD8A92DE84F1F58C2D843D07EF33C8B4D -:1064000086726BE05A5BC842FCAEAEC67ADA11996E -:10641000ADA6BAE69E13E58F4F93DF5E0E14CC86D1 -:106420000AFD4CF7ABEBFEFF4141637C62208BF22F -:10643000CB437F6942BF4B33F9F1BFED7AFCE57F77 -:10644000683D1E53FC2E5FD4F759122B8EB50F9E5C -:1064500011FB54D6DD5BB83D52E266EF45C52BB665 -:1064600048FE44DC0C1E5DB373BF0DE35125CC3FE9 -:1064700014F09D5EE5B344C3A72871D48F9569E1FC -:106480000BA0CB15736676EC45B9359119E4580C21 -:10649000F9A128F85D32971F8FAD99C1CBAF647217 -:1064A000EAA4055908E35B53E755EDB7A22828672E -:1064B000E4EF4D2B094A08CF802AE65755A22BA2BC -:1064C000AFB4D92CA4F178CD9154A08FC182BA0673 -:1064D000235DE0FEB3D418171A5865A48BB4126379 -:1064E0001CA83FD2057CD7DF442FE67E06A87E8A13 -:1064F000C765042D3C5E34CB18D749635D1F3E81D0 -:10650000F01D72FBC3384E9D715C73FF0A0B5CA0DB -:10651000801CD9F3F3896002C3AE1C9C9C8478D99B -:10652000EC288E27B982C1AB187E971EF4AAEB1D0A -:10653000BDB48FC8D1A0C1BF662E1B86A6DC36179E -:106540005AADF204188D1FCC20F96E15F1CA8319CB -:106550003F75A05FA33E398FF213F6631DFD38EA45 -:10656000B0FED172DF8A7EA4A4487D85885799C782 -:106570002B54385DBECFB442C4C3687B3015E9D913 -:10658000AEA6E4231CF654D0BB627C374E71717BFF -:10659000CFA77C698CABB97DEF8BE029F16172E20A -:1065A00079E1235F09FC10C70F4E067302E93F91A2 -:1065B000856A717DAB1AF93E17697713D231B40B36 -:1065C00062FCBFBB5D00DA8D34B4BB45F4A719DAB9 -:1065D00015F7685722FA638671B51EE32E16ED484B -:1065E000AFEB6EE7EFD1DF12312EE983DDEDD41E84 -:1065F000FDDDA1C36768E7EBD16E990E9F615C6614 -:106600001CB7FBFD705BA896F4CB62F2C71EE8577F -:1066100048F472A85F6111C6C16F7BC1CA65C436F8 -:106620009EE7210BBADA2FDAD5B9395DD556B371A9 -:10663000E5201F1B44BE4AAD7BAE2310F55C5F3FD7 -:1066400078EE8BFD7C8983EC31F15C6970925F138D -:106650009E933D56F777596C5A3F9B8C71CD0674CB -:1066600054613D78758D960DFC9EA618EAABD2F963 -:10667000FBAFEBAEAE09A2A34F29A6F808D0E7F70F -:1066800073A3F8B07BFC7F19FCDC7F1C81FF4735CE -:106690009A120D3FAFEBF0EB75E720FE5EB6CE9E93 -:1066A0008CF35921F6F5CF946535E44FFE5F3BBF7F -:1066B00045A6F55964581FBDAECFCF6A2DFD3F36B4 -:1066C000BF3B4CF3BBC334BF3B0CF3B35B974E0EE5 -:1066D000669FFFFCCCED565B8B49DEAEE8F7782A6F -:1066E000C2B542F8A79D56AD6639C61DFA75EBDBFB -:1066F00024DF4733ED6F2837FAFA6EA3A2927C7637 -:106700007A2C3C68D3CF161A9AC1E19A0172A1453E -:10671000F171F92DE03C62AA7799EAF0CB97B86F56 -:10672000FA986E4F9AE47C1FFB5A7D06DF4F1A3CA5 -:106730009A44792E625FB3E9FBDAA099B48FAD4831 -:10674000CD23FB65FFA005248F56A60FEBCFF3F0FA -:1067500052495ED9C55EF34035CF5BBB5FE407AD00 -:1067600048CFA376F7EBF19250BA61DF3CF0830596 -:106770004519201F4F1FE1F98AABADDC7EA8AF663B -:106780001ACFC37350B90FFA0D408356D0F7B07CBF -:106790000EF43D2C5BAA53A97CB65AA572278C8BAC -:1067A000E5AFAAFD5436558FA352D7171F14FAE24E -:1067B000F7D22DB47F3E56CDC62BD0FFA66A0795E3 -:1067C0008F56FBC62B40970F57A752795A9A31CE56 -:1067D0004AFED38EDA7858AF3DAF6653BED2C4744A -:1067E00085FC1E4C09CBF10591E73A5E4F4B932F88 -:1067F000B502DE2F512DBC9D2354EB8DDD6E32F69C -:106800003F4E55081EE60ECADEE498EDAEC0766334 -:106810009339DCCC17A8F5C4EE6F1A8E9B972CE049 -:106820004B566BDDB1FB9B8EED2E4A15F0A5761D08 -:10683000888BDD6E268E3B3255C097DE3E392EF6B4 -:10684000B83FC2FEFA2736521CE932B477A03F7B2C -:10685000BABA897C16A2DDE64155CC0274DB3FA9A9 -:10686000B10ADB5D5A55CC32A1CC4C296616A07F0B -:106870007B32BC077852453F13E6F1F79BF1BD2709 -:10688000EABDF87E7C09BC877A667FE37B7D3C7B32 -:1068900023D3E54998813CB0AF61DD793D584FB1D4 -:1068A000F0FA9DD60393296E69E3ED1FC13AF463B4 -:1068B000AF337E9FE2E2F57BF4F65EFEFDD3A27D70 -:1068C000FF443E6FE78D8E10C6C51EFDF79FA6CD17 -:1068D000CD8DCC77C8CF975E38376A7E8FFE7C35FA -:1068E000BDD7E733A47A0DBDEF8D5F53675B981674 -:1068F00025B7521A73499F1C6DAF22B9337AC8CCA1 -:10690000F01C58176B31876BDF8A553535D9045722 -:1069100090F205045C0FFFC408D7A09F1AE17AF833 -:10692000A746B806DD716EB8565BB95CEB0D3E1834 -:106930005F8B1E3FB4DC38BE5A631C3F54631C5F40 -:10694000ADFDD6E387A3D7E5917F338E3FF867C6C9 -:10695000F11FF99971FCC1777EBBF1FF59FAB8D7E5 -:106960001AF80FABD0C7E568BDB32A68D03BA15D6C -:10697000BB681794A3F5D840D0A0C742BBD7443B0F -:10698000CDD0AEB847BBB7443B661857EB31EE5F8E -:1069900074F82CD1FDF97BF4F757ABB0172CD1FD6F -:1069A000A93DFAFB5087CFD0CED7A3DD29D11F3325 -:1069B0008CCB8CE3C24F0EE6F3DCC15C7EF4F72E89 -:1069C0009DDA40F1AFFE2C20A1DFCF97C4461FC255 -:1069D0007D398BE7DD27142E1D82FB784382D1DFC2 -:1069E000D5CFC6F729C52653BFBE38564579878E01 -:1069F00060DAF4A87C8B32D1AEFBBD3B98765DD4D7 -:106A0000FB14F17D83885727AD1C538B72C537105B -:106A1000DAC7A0B7541BB70BF5F72CD9DFAE01BC12 -:106A20001B7E3C63CC6A163DAE95B71B22C64D8FCC -:106A30000D5743061FB714C7CDC5E7BA7E114C23C7 -:106A4000BCF978A93F5FEFF9A9F457C04BFD548713 -:106A5000458E87F76BB89F53F7B727D8AA1C98B70E -:106A60005B3BC8C236AB94877C4E3F4E5DB5D1EFE1 -:106A7000A9F88A35B4F70694F8F264D6FB770F15B7 -:106A8000598A62C51D0AC4BCEA4A263766C3F8ECB7 -:106A900090D17F0B84CDA2F36186CB81025B2CFF6A -:106AA0006D1DF79FEA7A50C28073FB6F6B857ED1B4 -:106AB0003D0FE828D6FACD12F0B10D1C6F8A8EB7C3 -:106AC000C41964DF25D45CE9F0C5F86E95A97F2769 -:106AD0009BA161BBB8E446662179C2CF4DE87A55E7 -:106AE0009D6F33DF87D280A6300E94BC338CFC734D -:106AF000A6809FA35052434189EC513E4F542BF145 -:106B0000274E0907D1DF386083C2C220B7D65A02A8 -:106B1000B36C185FC96E24FF98E2D324C4D3596BB9 -:106B2000E84A3A5700EAE266A927BCB7D8B83FF866 -:106B30002175C61F3262AC63894D35C4B7077C61CD -:106B400063E1FCDEDB47DA71B8BAE93415E8732497 -:106B5000C90DA2D34A592BB7119FA7FBC8EFA8CBE9 -:106B6000579DFF459C7BEE38267ED41BFE04F358D0 -:106B7000D46665C83FEC2B681D15FF5924FC5F7374 -:106B8000855F751E2BF6E2CB93CC52847C7592BD4B -:106B9000EACD8F5AAF069B8DC3D56025FF961ED7D1 -:106BA0009DDF6835F8BB166E30D617B019292897C7 -:106BB00016ACB3B210E07391C91FB614E70BF02FF7 -:106BC00064552B7DDCAE207D7AAE8F2949B0752CC3 -:106BD000FEF5C363E740FD17887718FF23A017353C -:106BE0008AAF4ADD211BE647BDB73B7FE60486DF5F -:106BF00087560E40799AC0629E2FBAA5C1085F5F82 -:106C0000F09BE165ACE69C7028DBA498FEAB877531 -:106C1000FE10EBB5D4E11DC540CE9C75F2B2DB9FF2 -:106C2000F26727C9F7BD4847B4DE5517F1FDA0EA62 -:106C3000622CFBFAEE80A03FF3778B1D1D36E48FAC -:106C40004AA5AA48B244E24D766B401B08DF595B67 -:106C50002685073243BB86F36CD726659E57BB2239 -:106C6000CB39FA3B25E4E5F33B1EB3A15D76F2C9CF -:106C700063D7201F96FD56660E68776A878785C999 -:106C80002E09D9509E94EE9663C667290300F056EC -:106C9000F62B0FC989D29DF6D034F8BEF4D9F74649 -:106CA00031C0C3A99AAEC303711F7D52E271D26095 -:106CB000C728DCB74A157673718CFE3A04DD9DF85F -:106CC0004D1CE5B548DBF6DF44FD36DF60B547C94E -:106CD0008737705FE2EDB87F6DBB141A1A437EE808 -:106CE00071AD13DB250E5F8B35E444F8B66DB2054C -:106CF000008ECA6D9F101D4DF9559317F150D92282 -:106D00001BFCBE95DBE4B07D1495C7B0C478890444 -:106D10007C5DC1B87CACD8BD98FCE115CD777D22F7 -:106D20007BF17B233D035EFC61C4EB1BB27F1AD673 -:106D3000773DE15501551FB56FF5225EA1DF39B6EC -:106D4000788CEB1AFDD8D8FF17893DFB03CBDD8685 -:106D5000F455D9BC8A8F67E2978FF097B49EF113F0 -:106D6000BBDD934C7AA21E3FD996745E7A6259D3EA -:106D700099478230DE899D1F3F1204B8CBFFFFA7E1 -:106D80008FDC897ACD3EA70FF9BDF2C9D7BC2C6A3A -:106D90001FCCB073BE3BB5FD89C71F023E39F5A6B7 -:106DA0009DF2F24EEDFD6030E6D39E7AE6BF52547E -:106DB000687FFBDECBC99EBF7DCF94FEE7DA0F91E3 -:106DC0004E43F668B842D4BFDA22A1B20586BC2889 -:106DD0004DEB7270B7CC9C00E7C9A3F610E63557AF -:106DE000C2B3A579B84E8B49FE627D19E0B7624700 -:106DF000FD27F2A858780E0EB4A46209EC928AEB33 -:106E00007CDDB597166069F5AB4817AC8BE4A7F944 -:106E1000BBCA23B09E17F5BE7E67D85736CC3FA9B4 -:106E2000DCB18A8F6B5ABF93F8CBF89EEB7799DD74 -:106E300018FF3AC3CA1F7D085FEE4E8A19D7D5E303 -:106E40005F8BF7FCE09C7A932E07FAC26F89C4E14E -:106E500072DBB56BEDC84F3B9F7AFCA164BEBED31D -:106E60000021A79ACE0C66401FC7AD5D37A17CEC10 -:106E7000DA6BF7E17E5EBAF70DE2AF537B5EB1A944 -:106E8000241F995B023DE114EBFE6947BDA142E27C -:106E900095CA2D9EB0DD1B59A78AD0F422D54BCFC1 -:106EA0008FD1F310A7FB8AD0FEEBA518EBB6D29ECC -:106EB000C9E571A81FE165F1963FD9288E1DB59EE1 -:106EC000D2385CC76385F8BCB775D4E7EFC3F95F08 -:106ED0001CB59E5B38BFF6C697A736D915CC4BD0EC -:106EE000D7F794C8BFAD0C496FB018FCAAEF6FDF9D -:106EF000341EBADC440FFA7CFBE2E7BEE7F1CDF0CA -:106F0000742B26578EE989AF135FC596EF1B857CDE -:106F1000A860554503B27AEE4F0A188C033322F06D -:106F20009EC05800D0D98927653A2FBBB2F920C935 -:106F300069B35CA8E8454F6EB2733BA7A265FF2812 -:106F4000945F270EFC86E8B062C7311BDA4787B72B -:106F5000EDB275E446E81EE57F741EE689A7F78F5B -:106F600022398DFDC7589FE744FF95ADC6FE2B77AC -:106F70007C62E8BF2CD86C23BF681FE37CA4683711 -:106F8000E07C3F6AB732CCBBFFA8592E8AA5DF3C14 -:106F90006AB71AF3613C638FA25F514EB4A928EF20 -:106FA000EA966B6F04715F7CC5CACF3D2ADA51CC7B -:106FB0000BA84DB0A968AFD6796632354A6E379ABC -:106FC000F0E94BF64DC2B89A6F6A7141B4FDA4C3A3 -:106FD0009FA0590CF0DFEE29EA8FE79FD00E53F106 -:106FE0009CB1E227BFB2EC2D2CC2F9C83E8BCF1961 -:106FF000737FE6FD59DDC56437597D96EE5C13EC71 -:1070000077F4949923D075A630D5A0E7AF9DCAE355 -:10701000B8FAFCD70E621B19C8DDB552571BE6B390 -:1070200007AFE4F9814CD8E95EB4D3337AEA734C04 -:10703000D354943F247E787BA6459D0FB903C0B1FD -:10704000601E8FC54FCAFC1DB246793D361C370BFA -:10705000EDA7103D8F6361AA5B1C5CFE7858153D5F -:107060008F671D8DD9D0F9DBF6E2B32837EF2D4AB3 -:107070009438DC61CADB4810E358E2D2D3CEC5FFB6 -:107080006CAA7222DAEF63671BC92E41B7E3D749B6 -:10709000113CE879717ABF6B9D1325DC6F707E031C -:1070A000F15C8F3837EFEB9EAF46F57E7ADD340E1C -:1070B000B6F48D155B2CB162405264BC2DA091FCDE -:1070C0001C03583395E9AC9DCA44874F5208BEB79C -:1070D000C92F6561EFB2AFE34CF09D873E7ED6A22B -:1070E000BD1980B2D62A9EBFE3096D85FABA04663F -:1070F000381F9CE9E0F264ACC3A2E72707A2EDAE1B -:107100005A564E737726F3632CFA773F7004863B0A -:10711000A2E219B2BB9DE77F09FB57B7D72F97971C -:10712000F1F87B2AB7AB7B5B9F15D5C506BBDA5C54 -:1071300036F673CCD9C4087EEEA7921CFCFCB2C60E -:10714000545F34FD61AECDD8E8BC464D23FB5EBC38 -:10715000B7C2F4F0A51DF128F7A4BF62A4BF7E4812 -:107160007F1DA2932EF25354CA81229C6F6A76959A -:10717000C49F0724EECFD2649C6F8AE8DF12579E2B -:1071800076AEBC2A360BE8232AAF659DB01F158565 -:1071900029AE3C8467A35877335D1AF354757DCDCF -:1071A0002D6A76912FF7BB8257E93C8A92ECA6FCB8 -:1071B000147741DDAD789E5C61553E949F6E3DFF36 -:1071C000C4CFF30A75BBD89963CCE7B49BF257AD33 -:1071D000C2FEEE91CF2DF6DD7BF0410C7DD8BCEFE9 -:1071E00056394C7AB4F89E8D8B9D37A8EB61E74BEE -:1071F000F7663BB2DCD17E9806F769946FA9087FE9 -:10720000C3A4EB7DE407EFDC21F1736B263AEADCE3 -:10721000193F0AE521F22FDE6F11279E4B3BF6EF57 -:1072200047BDA9CECBB484449273AA0C785F298D54 -:107230007648502EDEFDC9CBBF45FF7AABCC706BD4 -:10724000EE84B9B5E3FC142D01172B8EAD31ACEFF4 -:10725000379D4FCFB822E7B7253E9DDFDCF4FDE92F -:107260001D129D9F92D98807F01C44659B9585E06F -:10727000FD69C6FB3FBD91EB030B5F805160FD379D -:1072800088F1715F8ADE3F928A5C4C8DCEE3096A99 -:10729000ED78FE7F9EC047BFE244C3FB8FE716B583 -:1072A000917F26B080F44F3C5716DD5F99BCEC020D -:1072B0001C8F093F860AFF90FEF4F99FB5046C7C91 -:1072C0009F288E0F933E03F62FDA0D2189F295CC7D -:1072D000FE8E8A1689F6A745B03FE1BD028B422695 -:1072E000FBD19447A7E3DB4C97071D421F7433770C -:1072F0002F78F587797C94F86AC90B3C2F6C4993F9 -:1073000014A27CE68E0BE219E15926BFD107AC6AC4 -:107310003DEC1C11FA35E1CD9E6AC4B35335E23918 -:107320002EC788578FDF8847339EE3C7651ADA97E1 -:10733000C9E536223281E71CF88778063948F3A878 -:10734000807984D59EF82C695DBB12FD1B7DE2D14E -:1073500084BF8F4DF83BC35AF7F3B720525388B51B -:10736000797EA41226FE31F39B8EA7745FFB247AEC -:10737000E6F790BF38557422CDE3DF0D703473E625 -:10738000C9F313BFE979C271DDFBE57BEC6B286FB4 -:107390009B7EE818C6D3CDFCB5114BE0EBE66A87BF -:1073A0006F1E8CF77435F3CDB362BCDA47658C7D04 -:1073B00094FA077AA4FDE01E8C4B26235F2BA1CD07 -:1073C000DCE68A9B86E7FC5AAD3EF45BDE93D7751C -:1073D0000DEAED95F3799EE38F5D7C5FBDD5C5FD2C -:1073E000B08A8BE737AF2EB6300DEDFB563924A1AE -:1073F000BFC8A7BD7019EA5DAD5695F6355FD7CB0E -:107400003FA2F7F93E8CEFA6591A47231CD09EFCE9 -:10741000ED9DADEF796F89D2774EB5DC7721EE3BEC -:107420000F5A58492C3D3EDBC9C73F95F36E0A926F -:10743000E3624717D9D1F51D55C5382FDD8EB0ED64 -:10744000E6FEAD8A96E9A44F1E5AC0CF63EE39C15D -:10745000CF6316CAB3BF3F12EAE35F53B8DC64DA06 -:10746000B43929D484D6711DE64B221FFCD512AA4B -:1074700021FC34FE11E354B5FFA950BE6C4115BF89 -:107480001FE4B7DEC2362CC76ACDF9C8D7535B13E9 -:1074900026E17999CAB7795EE59876A33F87C9E571 -:1074A00007D10F76E628DF962F3EAA98ED2E19F722 -:1074B000E3F11DC6E713FAA0DBC94EB11F7959CA23 -:1074C00037C98BBDDBA25DE9E4712C3ACFE5576289 -:1074D000DB4F0FBBB87E057891504E7576317F0D2E -:1074E000E0A973DE009A6FE767FCDC65E75772512D -:1074F0002CFBE82627A797076D3C6EFBE002776818 -:1075000039FA4D17940E41BBE8F37F0B0C8915A790 -:1075100088D8072CDE427B9E16CFC6215FD4F1733C -:1075200066AC312DD6F9799D1F74FED0F9226D819C -:107530002B10CB7FF9AE93DB6F9317E44836A4D7BB -:107540007D12C5784ED5005CE7C06390D50C4478B9 -:107550002A5B3E25FF82A335B61FFAE7785803E978 -:10756000B626B87C02E0EBA7C0D441E4075B6346D3 -:10757000ACFE836C1DF99BE663923B7EE7E07634BC -:10758000531AD36678904FA65CB912E07C08F80FC6 -:1075900049FE41AB9FE00E2E668CFCAB0AE7FFF480 -:1075A0006BD8A6D551F6568373D23A5CEF754E1E52 -:1075B000EF480AF82584DBFFF7B35EECBFF30B3B23 -:1075C000ADDF00E1E7D1BFFB958E1F97760FD14B62 -:1075D000493209437FC0EB9B07FBFF452D80EF2815 -:1075E0007A8CAC5B90BE4B0C80EC2BC0F38C163AC3 -:1075F000BF82F616DA13954CFF0992F2A9F31F1E0B -:1076000036C3735ABABC955AA5B007E46681C31D48 -:10761000467F4A6209CC1BE351CCC1FB6B37EAA31E -:10762000287951EEA20CA07D5AD83BBA1CD6E5773A -:107630005D029783756B15CAA7DCA87438D17F9C4F -:10764000A1A99331B52A515129CF615009469C41D6 -:107650003E663D9CD0ADF74C60EC99BFCB31FD1B35 -:107660001F74E32BF02CE26B545BD701549FFC4E4C -:107670009684EB5D28F49BF127B93CD2F3FB2B8574 -:10768000BD619647BF013A478131FE52BEEF8D3F43 -:10769000E9F623FD74CBA10585B48FE6B5E61FC4DA -:1076A000FC9CBCB7393F32217FC07A23BC8C6D0B68 -:1076B000CA880FB3DCE94BDEE8F2C4BCCEA05C772D -:1076C000D731752EBF0DF82C6AFF36CBA9374C7217 -:1076D000EA0C9BD8FF7235424F794BFD07ED51F410 -:1076E000A3CBA9083D85886ECDE348CCD15DF76575 -:1076F000A17C7951463F48E7241E9F0C221FA1BF61 -:10770000E2B3D09538FF75AD573891EE77B64D712D -:10771000205B2D49E5E7BD94FDD70799209FE8B888 -:10772000AE953954770EE2C542F8907D508F9AD7C6 -:10773000E946499C7754E3AF8F713F825E2E49E55D -:10774000E7B976B665C6733B334CEBDE4DF7C20F37 -:10775000A1F3854EEF66FAD6F9A19671BF84AE3FCC -:10776000C852B3B00B8D7E815ADDCF1174529CF894 -:1077700076A10FD6BA87DD85D7DBD48527FB302EDF -:1077800071BB2793F2996FEFC7F166C6835E567E91 -:1077900001FA6154DE79A5D2457EADCA2F6C86E729 -:1077A0003A5E7BC3878ED74B10AFD23F8ED7B36282 -:1077B0007DCDF8FD47E79DBE645CCC7373FF57E653 -:1077C0003D81057EDB4176173FB7A1D3972E2FC6AB -:1077D000DEB6218D88A3DD78AE479723E35AAA0E43 -:1077E000A28A68961317B5B2EB104FE3C30A1DB116 -:1077F000ED4B6E7C86BFA4D1F98B592E8073F4F3C8 -:10780000B3CA76C0A3512A4B9A06408D6A57488E58 -:10781000B1F6F38B4335873F4B41FFA2AE979ADB1E -:10782000E97AA9BEBFE871A0D5AEC0421C5F6A016B -:10783000BE81F9D7FAB8BDDBE00C94E2F33880D909 -:1078400085B97639E10C6E9F1AF9B2373E8C33F167 -:107850005933E085CE21C03E3754EA09873E7E96F3 -:107860002B81C309D486FA4BFA58C607ABE0F7D987 -:10787000A58F6201DC87F1F826CEB3C1C5F7935519 -:10788000420FD3CB0667F17284DFAAB0A03DEF1F91 -:10789000875BF70BAE7669D52E18C751A4D13C068D -:1078A000FA981FF5FA814AB3E4073812CB55A9DBE1 -:1078B00059A3EFDF78EE679A3A89CE9765333A1786 -:1078C0003B10F5A018EBF34B17F7572F76741CC637 -:1078D0009079E5B4AA22EF39E2D391FB06FCC24FBE -:1078E00065CCC3E8DCFBC6208C4BBEF3EF9F7A303F -:1078F000EEF417A5CB83701E5FF6470F9E377867AF -:1079000019B7336E32E9333B053E7D71C5DB117F1C -:107910003757FF7DACE1FCF8521E47591492D1E86D -:10792000ECA6EFB26D71E49BD3EB8B9B930C759D32 -:107930004E17DB799E9479FEC785FDB468C726DBB8 -:107940004015C70FFC16C73F2EF4B5E3BB3DE4CF8F -:10795000D0E199BB63B40DF1F09756BB88C3B75B18 -:1079600039FEB569183F0B88A530C379785F1CF5DF -:1079700037FF7E99F48B3930D652A0EF40EB22B21C -:10798000B3CDF398FF8E5AD81FD66FFE2A89F452D2 -:107990006CBF0CE821B0B49EE26CE679CE099AE3A4 -:1079A00099CBC84E37E779CC63EA5D133362E47B49 -:1079B000B4F238F9C23EEC9A775C425F18CB2EC61F -:1079C0007CF4332CF717B96ADF76CDF16A46495A51 -:1079D0001F553BA83C51EDA372BB4BE5F1EC96FD66 -:1079E0008789BE94F6B1C8EF3BDBDE8BBB518DC8F7 -:1079F000EDEF6DFAF4E02FA19ECFB8FF46F78FCFE1 -:107A000016F8BE4CC8EF85421FC8FFE2DCF27B3699 -:107A1000CE77544F7875B93D1BEF938DC2832EC737 -:107A2000CDF838DD9615477EC638731CF8DBE1A526 -:107A3000B7EF16CBB1F30675FED92EE879DE96E9DD -:107A40002B07C0F8B57B3F18CCEF036647503EE8E4 -:107A5000F469A63FC6AA6CC8CFDD74D67A37E14771 -:107A6000A70BE0A354117F4C45BBCF4C6F7DE513B2 -:107A70009DB2760C463960A6AF53128B79AF68621F -:107A80001CF797CF53B542B443617B59C9E3745C8B -:107A9000FE1C571A0FDF89FCB985F3C7E25F373D3B -:107AA0008B72A7F457F77B51EE7CA834A6E078E5FB -:107AB0005B577831CE7D5C097AF1FB0F4372CCBC09 -:107AC000C2057192906BC67C05D610BC06F9F6F320 -:107AD000AD561FFA192AB7D9791C7C37C71BD47940 -:107AE000FC7B77EC7C85D227EE4F51797EAA316FF3 -:107AF000618B95F24FD05F86C3F416C7ED8E0B37BE -:107B00009F3BBE5DB9FBAE9879277A7E80996E6700 -:107B10009AE815F042764C10E021B7B8885BD76E32 -:107B20007F60D43180EBC496FFF04AB9D17E731EDA -:107B30001F3FDD7CCBA318E2E98D5E4F09FA8EE88A -:107B40000DA198790CE5D6B017EDF0F24D56B2EBD9 -:107B5000CA9B64E6C07C9637EDB46F9735FDEEF5B1 -:107B60004B00BEB267ACC9D3F834285F415FA7EEC3 -:107B70003C12B12EA5BB7EC7E3BDAAC82711EB53AB -:107B8000F6CC7E1BE6C598F138A579BFADC3948FBE -:107B900040EBD47CAC90CEE56D3F6BC3FDF4C37D70 -:107BA00012EB9FD1F3FB924DBFF3A27C403C515CA2 -:107BB0005EAC57EFF942E16B9E2BA076E487EB6D4C -:107BC000FD2EC6351A43F4FDF473307EC95B76CAC8 -:107BD000572A79FA36CAEFF940A9E274FEF08A14FE -:107BE000DC5F4BACC1141F95FC79C9233F21FA5BC4 -:107BF000F8CA4F52F8791E2D8DFB6D8269E4CFD8FB -:107C0000F8039ADF021620FA2B79582E467FC919FD -:107C100085153D13834FFE2CF8E483CD760CA2B27C -:107C20000F84DF32F8AA2CEEFD35C793F8BD2B6721 -:107C3000841DBD2BCEA2E7693BA2EDAACA2DF5EDAE -:107C4000B83E1F0DD2FAFB28AEAF0405BE24D2C742 -:107C50005FB9BCBF9063745F8CAEE74CC1E7D8BE20 -:107C6000DD4AF7C6447D67B8F7E576313EC0ED9250 -:107C70002E823225B63FD3ED9674F878FE8B4E5F98 -:107C8000BDF1FD169E4FF2D9112E57302F86DEB76B -:107C90005BC3FD0DF93076C3BD22917C0FABE06B69 -:107CA000E37B8093F255BAF1BB4FA238EB82757635 -:107CB000631E5C37DD98EFBB31E6AF2C34E95B7AAD -:107CC00069960B6FC699E2681BCF2F7FA5DC1AA2BD -:107CD000BCA3F237ED643F9437598B111F1FEF3867 -:107CE000F8FA8D40E71F37EB7C6B94AF66BE2DD959 -:107CF0003986C5E2DB8FDD7E16936FE1794CBE7568 -:107D000047E2112AFBEEE4EBC25EE4ABC5DD431FA4 -:107D100088C7BCDC8F9E2C1B427E06135E75B96A39 -:107D200096971BE3D45EF2EAF87E1EC977E4F8D397 -:107D3000E9B1F4A9C5344E37DDEA74A9D36D2F79C2 -:107D40005A663C9ADFB7097964F6670427B31CBC0E -:107D50005FAFD6C672D0FF1CB4B8FC5B3362E4756B -:107D6000B0AA0B50CFA87167C4CCCFF5BB7D68C655 -:107D7000326BB22AC78A77FBA75862EAF1F96E71B3 -:107D80003F09D202EA936E8EB73A115F014B90F22F -:107D9000FEE98C36C297E0257EB2C27346E72AFD23 -:107DA000746EDB1F67F9540515ECDA35430A15F4D8 -:107DB000A7E65B6ECB82FA823579850AACB37F8207 -:107DC000655726D44BD6E4F3FA45967C2B90E6E330 -:107DD000C182C2A9D0BE429FE7BC78837F43B11C59 -:107DE0005B8F7117E5392BAB85FA5DC0D78EBC4828 -:107DF000BC37CECE824EA8C7D9A084FACA8C3FAE7B -:107E00004423F03E7BE06A37C9A3C92AE2F584CF58 -:107E100041F932B7FFE672CACF2C7373BFF1885DA8 -:107E200013E8FEDDEF60FC1FBBC7F43E7E9D95F7B7 -:107E30007362E7882988D71143F8555F3AFEF31437 -:107E4000959E3B9BF1E829F17F2A9EFFA84DB051FA -:107E50003F65DDEB757E65ADC86B90E3381DC8F1FD -:107E600096AA67A05C22D6FF36810FFC417BB973CE -:107E70006FFFCDFCDEA7AEC1B8BEB27CFACFA8378B -:107E800076FD38CE8FE757DE72717CDD10BFC63AC3 -:107E90001CEA798EC1B72151BF25EDF80996D77834 -:107EA00002FFCEF1CFC2D8DF8D37C9BC3F7795072F -:107EB000EF519334AE474B4034B3010FB51A536DB5 -:107EC00059C8A2C67C0B59CEEB0AD3B81EC3B82C36 -:107ED0001DF64158A71BC6F375029CD2BEF8C638E2 -:107EE0005E9F15CAACED50098EBB118ED1F6D02025 -:107EF000B47F6E04B588D3B5D1FED6E3F495FF699F -:107F0000213BB352526BDD50DFF53623B97CCAE515 -:107F100015F907FC7E19DD2F31FEA5B95370C90A8A -:107F20005ACA781E87F043E971F433AC55C6C9F4D8 -:107F3000F0539BE4E104B686E4645FF1B1C7DD620F -:107F40009F19C0067CC3F85893FB3CE263E96E5D61 -:107F50009F17F176B1FF9F7E3193F285140573F27E -:107F600018B3A932A588E8DFED36C95F9D8E471E9C -:107F7000F1DD8278197984DDCCEDA55EF2238E33B4 -:107F8000CA6B1EDD9143F91156737EC4510B253C1B -:107F90008D7D215F457CD689B8F1378DDBEB71FF94 -:107FA0007CFEA8471CFF396F11C541F37DB1E3F892 -:107FB00097C8B329EEC05EE4EBA7C7F1999C2B23C9 -:107FC0009C67C28C25219C478CF7C55C9C1C94291E -:107FD000ADE66DE3F34BCCE7594CEBFD57F37A9FDD -:107FE0006F1EC487FC7EB5D16C14E54158451EC494 -:107FF000B32C705F741E848EC7BEF24CCC7925E61C -:108000003C92B480114F034B861BDE0FAACA33D4B7 -:10801000872CBDC4D03E0336C2E87A56C35586F6D7 -:10802000431B6718EA176CB8D1D0FEC2D05CC3FB03 -:1080300011DB4ACFB9EE239B9718DECB96503EDE7C -:108040000BA9AFFB452D3F8B4917FABAEB795A982C -:108050006E84F81D03EBFE5006F98FA6486ACFF533 -:10806000F78783B42F7FD3F5CFF6087DE81BF2BBEB -:108070001F898DF25AB99ED8697537A05E9C00B0F1 -:10808000A1BC35EB1709ADCFFF17FEDD899EF916B0 -:10809000EA72A4A33B646D3CEEF7FD447E649D450B -:1080A0009C279DEC207DE01E8BE5E6E87B922FF57A -:1080B000707BE0520FDF5F7E09FB26EE9303E358EF -:1080C00090F64F0B8BDC6701F3F52631716FF1A64B -:1080D0009553D3319ED991A326007F637D5044EE02 -:1080E000DF68576B311E305AE6721CE4FB959E7EAA -:1080F000B8EF2CB372FD2768453C0F74B0A0378FE2 -:10810000F63D8A6B26B06469492E9A5EDDFB8BFAD8 -:108110003510C3C1D211F16807BD8C906090D6E1D3 -:10812000A2FDFF87BADC2BB990E4DE69B79E37A6C3 -:10813000D279C7D3F3B2E8F99B3701D701FFBC6905 -:1081400033DA457DF9A74A36DDE741FFFF9B39CC9D -:1081500090675026F056861762E2B993D07FA6202A -:108160005A3AE7FF6D18025D29B5AF44115DBFE1D2 -:10817000D662CADBDD3D3D88FE3FDDEFACF753D96B -:108180003A8975DF230CFDDDF006F77FDDF037A3BC -:108190003FF7671E7EEEE86762BC9950F8006F33C8 -:1081A000613D12B07C7E6221F2033C0F4B50BFB6A2 -:1081B0000D543FA0FBE9810C2BC2F347E67F6D0F06 -:1081C000C0B3C2A3D238D7B3622BC2F5FA4D8B3DF0 -:1081D000D8AEBB3FBD9F8178A613F6E984A03505D4 -:1081E000E8A7EB5289F67518CF81CF8B670F5C81BA -:1081F0005B873EDEEB2C70F23558EF19CC4FFDEA71 -:10820000FD33E632C8C19D25657F49CA44F967211F -:10821000FFC792BD76927F9DA5679BD6C3FB9B0748 -:10822000760C42FDE2ADD2BF0D43BCFC7083CC5452 -:1082300058FF475D81B59E28BCBD39EF530FBE077F -:108240003D61EB7ADCE49FB2D339AFB74A9F1A168F -:10825000AD57FFD233693DD21D1B777EF19E294F6A -:108260005E48F6B64E5F8B047D2DD97E01E9834BC7 -:108270003CDDF4C5EB5BB3E83CD15889C5B423F1D0 -:10828000DE0FCC4BDF097485E708F77DC1F3C777B4 -:10829000BD98984FE751596047F4BC76BD7CE30820 -:1082A000F2B71E4D3E2F78912783A85F310EE74B22 -:1082B000823F66B526E50BFDAE05FBBFF1B7DB4F90 -:1082C000FE09F1B3F7A9AD77629B82F3C30713FBF5 -:1082D000985FE001F631B27F3A99CB6F8F61FF3C36 -:1082E00023F4AF3B2C1AD925672DC5227F9DDB21B6 -:1082F000B2C59F8A79DCCDAD721CE2CD8B068B2E88 -:108300005F4027F4E23D8CE2FE7C07D8672384FCC3 -:10831000F9C3DD9F16D671FF8E41AF2B38546AD05A -:10832000E78AE11FCAFB8B37066AF14EEE5EF5BAAB -:10833000B085ECE17F54BF7BF71F94F7273D9CFF8E -:108340009B73B8FC6E0EBB42DC6E60F9A8EF35790A -:10835000F97E7025E68900FE6DD2A91C07FCFEC9D6 -:10836000DD6756364C84E5CEE6F8C03AFDFD95361D -:108370004EA7DDFADFA1E1FCEFCB8973C005E25C1B -:10838000B4199E02E02BBEC9BA0CFA63F8F09774D8 -:10839000CEA52951FDC304D4E7414F41BE772A1D24 -:1083A000B68418F37B16E527D0F7382FDF3F1C2D56 -:1083B0003C0EE75035BAF7CCE9F38D467B496FFFA9 -:1083C000B187EBAD8B0FBF35D806EB74D2F2A21795 -:1083D000E308E57B767AD14C1E1517F07A51AEBED4 -:1083E000F9EA581FE55B6D1A8C766D7398C72746BE -:1083F0002A2CA8C4B8B7B972433E5DFE5DB121898D -:10840000CA0BD19F008F2AC37C9EA75A6A63DEDB0A -:1084100059F9FFF60EC0757BAA1F3F2F35B2357F85 -:1084200021CA3F84C50A72EEC92F46507F43BDDC86 -:108430009E87F1157CCE58C882F71D3D25ECB553BB -:108440005FC8D44EEF7764CB24D9076B991B6E3C81 -:1084500040F661AB5DC575766EE1F7C1395B9D2471 -:10846000F72AF75DC1EDB8041EF76C7275FD599CD3 -:108470006353314FD2E96B6489D07F938DEF8F17AF -:108480000203EC74479EEBE3395B1FA0A4764736EA -:10849000BF57CFA934B24BDDD178F710FC8582BE2F -:1084A0009A5C610BE6ED74E15D950457044E46E37A -:1084B000EA705E48FA7C93ADEB7D3C7F49E7EB5474 -:1084C0008483C3C95A2F5051AF70FA78FCD6E95350 -:1084D000FD41A9275C95A340CF057EBBA78645FE3D -:1084E0003E06E6B1B9227507F044532613F761E55D -:1084F000D4A37ED15D4781342EF2FD8FBC23EAEBFD -:1085000026929D1394D1AE87D29388F3E4FC85F72D -:1085100017F4CBE378403F719C83BFEF6E0FF4EE0E -:108520004EA47B8DA99D3FDE177795C4BAEF35D554 -:10853000FD4EB74BE1F72F43FF56F8C028156029D1 -:108540007FFE39A2DB324BEBFA912A9E4B0CCCF723 -:10855000C278BF7EDB827F53917DB4DD49E79073A3 -:108560007EB389FCD5E6FEEA8FD6DC8B79D99DBF38 -:108570009154CC03EDB47651DCA8A2F5033AAF7860 -:1085800045CB313AB765890F5462BFE35A964F41E4 -:10859000FC8D678DB5E8DF03794871FAE6542E3F0C -:1085A0004E1F19B6797914BEEFF70ABBB02B300411 -:1085B000F9A655F0E73ED46FA0DC23F4AC3DFB7F79 -:1085C00098157D0E2BC80E903FAC861DA2FC42FD77 -:1085D000796748A17360235E77DCAC45D1DB2F045B -:1085E000BFFFC2CBF5A0ECF8C00A84B76CFFBB3666 -:1085F000AF8A79ACCD8351EE36831E76AE7CC64A07 -:1086000013DF74E7B71CE7F772C3BAD6C5C33A3DA8 -:10861000F57ACB70FCBB22003FA3FBAADEB493DC4F -:10862000DC93C1F96FF96B9F8F42B9F5F9DEB22186 -:1086300088AF3BBC3CEE0F743ED985FCF40C23396B -:10864000A6F3632EF223809EEBE37E945CA473E496 -:108650003F5B3BDD03DAB587DF0B01744E740F74AB -:10866000EE43FD22D707744FDF5F40FCDCD46EE1A0 -:10867000E7C0418E0FA5FA64CA57696A9FEA237E54 -:10868000B6006AF3902FC307A89F667EE76D81E965 -:108690003ED78F3149634C443EFE9787CBFFE61CA3 -:1086A000351E6D84385936F041D43EC9EB621F95B2 -:1086B000E26FAC5F878946ED625F107AD73EA1E733 -:1086C000B2A35CDEDF26F6B225BFBBE4DA1D30DFE5 -:1086D000252FC95CFE0B3A3920F4E043D5A954C7D5 -:1086E000FD4285751A0325DE773756AB9A82DBCFBC -:1086F000B8A2C683585E52DC3C058F4C4D9CD57E9B -:10870000909F61D34620FDED3E70E508CADF7DD322 -:10871000CE304571F7975D7F7E12F351F701FE630E -:10872000EC4BE89F6514BF29267AEC8D6E3AA58E36 -:108730006B26F8613ADEF22B14D8E82B9030001F3C -:10874000AF794BEB8300D00FE3B5A3488F77FA02E4 -:108750005476BEF2650ACAF43D47DEF5A2BCDF6D71 -:10876000D346209DEDCE047B20067DFE4ED04F41AA -:108770002F79155F7A797EFAB020BB0BE9A762B733 -:108780004C7FBFE0E46E59C373D8EF6B8114D47390 -:108790008EB3E0CC09B8BF0BBB763E473B9B8F7ACC -:1087A000CB28BA2FC3606732799985EE7B6F95C865 -:1087B0003F5162D243CA59E3CA81B86FB46EB2E185 -:1087C0003C4AB718BF2F47FD651496E7B657BFF46C -:1087D0000AFD258B65A1FE02F443FE89AED764FF36 -:1087E0006646F93D6D98DFF39485E307E425F1A132 -:1087F000AEC73CE1D34EA05E7DC223F613618F76F7 -:10880000354994DF7FE1369E777DC9717513E3F3B7 -:10881000A7BCB01221072F5178FCE2922359140F04 -:108820001DA731F2872C68954288C7125DAF13E708 -:108830002960DB25BD6E3C0BD5E2FD720BB7497498 -:108840000EA36C9BD17F5FBEE195C3681E2E6E3672 -:108850009D8F177831C73776E22F31E21B83E3858E -:108860003F67301B6C386FD5767EE7AD3E16E7AFBD -:108870005F15FDEBED26C473BAA910F32D0FC921C6 -:10888000F1F729DD987F7B8BA08F5B047D54B2B01C -:108890000DF3F717AFE3F3656BAC867B8B17ECBE7C -:1088A00095CE2398E9A864078FBB010229BE53B275 -:1088B000D1F8BE54E0A3D4848F8A8064828BEBDB32 -:1088C0003DE16A9E89EBBB788795FE4E8719AE33F2 -:1088D0006C36E511FDB3E133AFD375FA3A0D67C3DA -:1088E0000DEB5474EEFB0922F68D51FF7DE6F0701E -:1088F000CA7739DD9649FE039D3ECCFD140AFDF989 -:108900008A0D5CCF3CD932256E24DA452F2A7E09A8 -:10891000FAC97FE9332F9EF7C8DB2B338C0B76B671 -:10892000E6DF85E7B477B5655F87F751E4BDA4D08E -:10893000BE91FF521EDD0B92F7525E5C16E551A808 -:1089400049880FE887F6DDCE17B3FF988BF2B36D39 -:108950006A01A279F98B7971A81FEC62DC1F21BD35 -:108960005490D411B58F94C773FFC0CAD4F7EE41A9 -:10897000FDFD8A67F8DF1FBCC2DAF532E61FEC6A3C -:1089800053FCCBA15EFED2DC1ABCA7A27CBBE447A1 -:1089900035FB70FB92E41F219DB55A7D7682F72747 -:1089A00007F07D708744F78557EEBD7C4413E67968 -:1089B0006FCAF7479FCBCE4B50EFC3BC4A961647C2 -:1089C000F6F71583ACB49F9E1810F718DDC7A26D9B -:1089D0002A44397BE2B95D363A37D824B15498C875 -:1089E000E1D4834FD3FD1ECFBE42F90A5376BF4276 -:1089F000F909BDC9FB93219985C9EE6EA47B611667 -:108A00006FD2EB1D740EA258E84D155B8E51BD144C -:108A1000F57F18AF74A31C52E1D7837B7F4DF90D0E -:108A2000153B787E03BC27F9538AF1533542E7732F -:108A300019A783B942FE94317ECF5059233F47A7EF -:108A4000DF8BA4D3F9FC1D73280FAD47BE19DA974D -:108A500014876824FAEE79DF10A7EF1EF72499E84F -:108A6000FB573A7D5FC82E44FAFE7C12CF0FFBFC09 -:108A700015575C2ECCE7F31764CABB3F079DD37E26 -:108A8000FAA2D8FF4F872DB43FE9ED4EB57C4AFBE3 -:108A900048E58BA76DA8AF16B67E42EB30AD75FFEB -:108AA00054C4F3D52C508E78BBBA35CE877C3EADFE -:108AB00083CBADAB5AED21F4535FCD9AEB707D3B88 -:108AC000F73D519788F4F238A7175D9E2D14F85C96 -:108AD00028F0B950E1F73D95E6EE5F8F6ACA558CF4 -:108AE000CB9BAB9A85BCD968C46FA7B55921BA197D -:108AF00029B1C68C9EFB5D19EBA0738F9D6923E89D -:108B0000EF4906C15E453DAC7C87390ECEEDFA0AD1 -:108B1000D37E7A205EDC67F00DEFC178D7B42ED318 -:108B2000BAF87E7615D013C643DAC235B928F77481 -:108B3000FC98D7A54DCD8A3FD779E79785DEAED78C -:108B4000AF15F74C34FB1ADDD176F8153EBE9F9475 -:108B50008E9783B8AEDDF64AF6C151AA2562AF8082 -:108B60009DF2657C3F6EB78C86AE9F4F97597272AF -:108B7000C45EA94FBD6F5A5E32DE1FC1E5C5A97143 -:108B8000D01FE60B288CE454E50E7B08ED0C3C77F7 -:108B90008476C07F03EEF3D8290080000000000037 -:108BA0001F8B080000000000000B8D577F6C14D74E -:108BB000119E77BBF7C33EFBBC87CD116AE2AECFF7 -:108BC000BF3018B3312636A449D62E6928B8CE193D -:108BD0001A429BB45C4814D284B351845C242AB1F9 -:108BE000B6898A42AA466AFF88AA28DA448A94A8E3 -:108BF000343A84514C655BE7C424B6532408D0183A -:108C0000D4B427FEA069656383149C5691E8376F3E -:108C1000F7B833366ACE92E7DE7BF3E6CD7CF3CD50 -:108C2000BC778F0E5EF7A5EB886283E21182AC2CD5 -:108C30008AFBB4A5441D44DE9246C80161A40872B3 -:108C4000D3755FBC8068BCB2A2280EBD1BAABE4C07 -:108C5000C3F8167F1ECECAAEAF15A262A24E48BDA3 -:108C6000383BDFA9A67DACDF39284C1BB2FFC3FF20 -:108C700094951712CD0CCD953D0DD9A8798896F213 -:108C8000FC0F57AB3877F6929FA2E538D8322FD039 -:108C9000FD44CF91F3D9A3111D5882F1E80B6D5417 -:108CA0008F0971B8949A61D74B460AFB3A2F2A86EE -:108CB000A563FE9497A889A8E7B33F8F2E2921BA10 -:108CC000F6BE30FCBAB3FF570D18EFB60F2F81FE7A -:108CD000CDF7846141FDB97B881EC2FC9ED7BD578C -:108CE000D201E7AC5BF27FF2CA41E8258E05F4576A -:108CF00030EAA1DE52826E2F1D963241AF5E57429E -:108D0000B037D0E7635CC8CED91F257AF1DDF9F61C -:108D100012A466C788EFC0DF5A3A4673D61FD50A39 -:108D20004BAE06F1A5966A6F29EC7FFE5181F36781 -:108D3000C615CD2F246E6F7E27179F3180B19CE71B -:108D4000F34C429C33E70AEC3CE8FDFB10D66A8802 -:108D5000A60EC1B81F769A158987678323570F7FA0 -:108D600010E57C32FEF135447F1CFE6095C9FE9310 -:108D70004DB49EFD86DECA1CBF93702AC74FF865AE -:108D8000A4705ED75F1503E6D9AF6A5F49D6AF938B -:108D90006A3A64E4F063EE90D9315A8574890F65BC -:108DA000BE3C6254CADBBC39A5C4ECBAEC18F1EC89 -:108DB00032B1FF27CC0BF843EA6C24063F7FA6E9CB -:108DC00092273D834E7E3D438EC4F93B8871C19806 -:108DD000CF5FB0DE6AEDE5F59BE541B218B7AFAD08 -:108DE000361E7747157A05E3EECF5EA8A19CF3897E -:108DF000FD447EBBBCB311E66DD7398FF4AFEBDC1D -:108E00008D4825C65BE8AD4D1AC65B297998D73FDA -:108E10008E069F675E5B7CEEB2AC9D2F8B14C77F86 -:108E20008E17F62CFABD63D78DB797B6491C7A5DBD -:108E30005EED2E72E23DA8C5BBB90E67CEFD37824E -:108E4000B0E9E4852B21CE5726DF77D6DD6DBF71E3 -:108E500002E373B3453FFF2478D030AE5A4588F320 -:108E6000C4649EDDC6B80CEDF9C741CEDB653F7129 -:108E70003D740FEFA921B61B8FAF8DA10E6F0EFFB2 -:108E8000622DE340A257FA65B17FF06B7AE062444D -:108E9000C77C62E86284D71327D7FFCE82FEBA333D -:108EA0000D5B79FEC4982AF9D770A651F2EFC45F22 -:108EB0001A8B2BD87132826C3731AEC6189FC478AA -:108EC000E3A76DD04B9C696D147CCC99C662EE3FD4 -:108ED000EB04C5925817E395729C89E7379A22E311 -:108EE0009919011F302F28EAF0872AE7F1676FFFF1 -:108EF000691FC7B1774031737994D9F796A64A3B79 -:108F0000EF307F806F4F5298921FC71DB977E08472 -:108F10008CEF456F52E6BBE798D759FF9323895EE4 -:108F200093FB2C5A62311E9FF214F2B0C567AF203A -:108F3000B838514E3B938BF4C3AAB090FB262EC594 -:108F4000BFCB7C996889D768750BF52C6A95F19031 -:108F500070F1EEF76EB617B157E1DA0B15D3AED854 -:108F600022EB5AD8E1CF161FC517F3E78B4C3D1102 -:108F70001DF58017E7DBBC1AF39FC82C588E3EDB2B -:108F8000EEF6D9ED3FF29ABEB55827ED741ED6DB4A -:108F900033FDB619FD0C7D21863FEE6FB1D76345D9 -:108FA0002940DA61CEEF73DB28E6A50AD8D93C7FE9 -:108FB000FE71EE97F52C5569E76E7DF022F7C1D56D -:108FC000F8524DD5DC074929080AF0E6AB31AFA6C7 -:108FD000487FED4AEE0777C697E9331FA3FFE9E81C -:108FE0007F63E87F2C7B6A3FAF4F038F89914BEF04 -:108FF0008765FFCCA32813F01B5847DC09CD3DFB48 -:109000000E7B3DB7EBF3C7F3F896C9CF34D1E664D6 -:10901000DDC2FC5C77EFB34460CA07B25217ED3B88 -:10902000E2411CAB14877F7E6FDC2C451CDE8196F1 -:109030005429F7D35A7451C437FD88B0B9CFC3CF80 -:10904000327F4E9F9F5E2EE47AF70E615BF83A52B4 -:10905000FBB9BCB713A9B33EE65375FFD32FCBBA08 -:10906000B5E80245B2797C2CE0DC97B7F397899795 -:1090700017758E0F7C96FDB8444AD6E7FBB1DDBD6F -:109080000F1F6B9E9FBF1A3AFB8352F8F184290C85 -:109090007BB1BCEFBCEFF452FAF6795F158E1787FF -:1090A00081C7CCD91B3BD6C0DE44ED3FCBF81EEDCB -:1090B000BC0B7FEF0D3BB8760543F55484EE52A30D -:1090C000F7A581C7F1C2F80A69C7F34D6815F1FE2B -:1090D000F49B2F09CE0749FDBBD54B855B2F15614E -:1090E000CDA98B125AC7BC7A4F73C6135E7B05F7A6 -:1090F00003AAC36366C3FFEFBB3DA73EA9E7BC5C01 -:109100001B19AFF7E5E46FEA25D43DDF23431F4584 -:10911000F4825C7E795C7EA9520AB1CDBD1FE7F373 -:109120006D8AF9C6F93EFE51FB93CC93FEED2542C4 -:10913000CFB93F4F9E0F55E5D89D1E54A43EA9E9D7 -:10914000EAC70B73FD7C59FA399D74EC11A5ABB7D6 -:10915000AFC95DEF73799B96BCFDF5CA7D31AEE377 -:109160000C6F557278DB39D041F23E72E34EFAF063 -:10917000057E59C37EFB1DACCF7867CBC23975F134 -:10918000AC8B73534A483E6E204B61BB4DB0F81414 -:109190008F554AA9900F504ACE13AD20E6F1FD2E0F -:1091A0008F9BD4D488A8977A960A5E6EA4B352EFA8 -:1091B000219A95D2243478C85632A46C0EA4B67283 -:1091C000FBA84B2615E6532AA286AF828FDC4A16EF -:1091D000CB5F367E95AE66F809653C6E76C516E9BE -:1091E000D7BF75EBDCE0B71AE7799AECB731F52019 -:1091F000A5153EE40195362B88E7419502F9F0F775 -:10920000F8A847D6EF705AB7B97F19C5EEBE7F618F -:109210001FC64DA653A77CD53CD5908DF74E1C3666 -:10922000C25E11EBA974C42B714CC9F31E66C71141 -:10923000770BE92A8F7BC3E56E9F9FFD399FF3FD76 -:1092400041BF7CE7780296C4E3485897790B02CF78 -:1092500010EC6C7C4DD024CE352A9C7833F637E266 -:10926000D557D4C0FA42EA634C93980F069C7D44CC -:109270009B34C64BA4229E5BC16F8FEB4C84A4DF52 -:10928000A16766AF1D94EF36BFF6365C32063F9994 -:1092900014784F0BD3A403EC4FA020C5EF6BB06341 -:1092A0002AF75DFD4678F71FC2F047E89AC48BE2C3 -:1092B000A4F33B6319BDA1F1BDE161BD6207BE2FFF -:1092C00081DF136EBFBB9CEFF48D77ED6DBA07F9AC -:1092D000D8591230381F0D81B27504BBED85716904 -:1092E000F7B23856258DA8F67AB69BE17990CC6610 -:1092F000C659B8F93A1070ECCDE539926B92F91C69 -:10930000443B0FC0AFA3A88B00C656AB936FEBEFE7 -:1093100079761FCE9BF3C424197FA91801C9F76879 -:109320007CB209526D35F57D05FC64471CC16C1C8F -:109330007D7C0EEE637A160F449061BFE6C4D3576E -:10934000E059C9BF97FA28DFC0E388F6173A3CDB3B -:10935000FF459E4DE50BFD1BF1C74738BE398F31E8 -:109360003921EFD17D4DDCEF18A7EF6570F2647104 -:10937000DA6947FBD2BAC4658CFBEB7D7EFBDE1459 -:10938000F6FDD46F57B1FF193C90204952CDC53935 -:10939000838FC6F9631E9BC85F26FFD12C4E47F30F -:1093A0001D7CF0F3CDC141471ED72C8C3FC3A3FFDA -:1093B000010A95CE3EB00E00000000000000000043 -:1093C0001F8B080000000000000B7BC9C7C0F0A382 -:1093D0001E81BDD0F8E8B89917BF3CA9588601C1D5 -:1093E000CEE6626008E060600804E2DD40BC078809 -:1093F000A539191842803814882703F95380380793 -:109400008893816A1B981918B6B13130EC05E223B4 -:10941000407C9A8D74FB9F8A3330A4C920F85B800E -:10942000EC4D72D4F5E3281EBC38C600953F4713B7 -:1094300095BF449B81E12E929AB99AA4992F68C84E -:10944000C02004C4008B7A89656803000000000016 -:1094500000000000000000001F8B0800000000005A -:10946000000BED7D0B7854D5B9E8DA7BF6EC994921 -:1094700066263B0FC2248664E70501031D6288400F -:10948000D14E5244B4D48E685BF478740848781393 -:10949000F09556BCD9900709093058AC81224E107E -:1094A00011156AA4F8AAB40E88163DB64D5B5BD1BF -:1094B0005A1B11410139296A9D5AAD67FDFF5A3B7C -:1094C000B3F7CE4CC0F6DC73BFFBDD1BBF8FE5DA14 -:1094D000EBFDAFFFBDFEB5462645442A20E40BF860 -:1094E000FB1A21B9222164423C254452FB9C901274 -:1094F000ED8B62539E7C613B9FFC67A3CC798D9082 -:1095000061907E9F906C426EE365F42F00F9A93C58 -:10951000A3CF474F895F26D1B2783F5309CBABA287 -:1095200040BE10E0ABB95C1FA7C1E91D47D208F9E6 -:10953000C4C552AD861655D2F42D57A4A9901097E4 -:10954000102A66EBACFF4A702CA61743DA24905918 -:109550003DEE04F320AB195C76E788A42A3E7F6BCE -:109560003D3D6D6A24243A2A9EB749FE288C4FA6B9 -:1095700010FF8309DA4DA4EB40F8B88904F0903964 -:109580003CDE154213E1BB9D04A2365CAF9FC03C9C -:109590000F78AA8E84B208E99C22FB1DF079530E45 -:1095A00081797975B8CE2AC0BC0C799590AFC33F4C -:1095B000B8DE685B319D47AA5F246BE9A7A69C0AC9 -:1095C000271D93AC9FF4575F88A6A9520F512075B1 -:1095D00093404FF9E0790689C8F7F12E723E70B0DA -:1095E000EE8F1DD680ED6947D9F1F96EB0D379D1F0 -:1095F000F568134402F0595739332D94601FF47401 -:109600000DC0972EBCA5D18969D3C49969A41C7AD1 -:10961000EA9F05705E3F295B5C2BC4E1A2C3E1C0F9 -:10962000A4179D7DB45E3BDF9F4EDF4127B46BE7FF -:10963000FB6E85DB7A800F2DAF2102CEBB6558CA49 -:10964000AC4802B8D4102F96AF77D176B08E1C12EA -:1096500079B010E6D3D73587E6BD13950A80B715E4 -:109660007FA60E93B0BEDB4D220EDCDF803B8796DB -:10967000A71236BE3B8FF8A3743D2EB7DBAFD2BC2A -:10968000345124511DE6F8EF72D33E7849BD835022 -:109690007A4D9D326F061947F36AFF1118DFF9A65C -:1096A000C31F800AE532B657E87F5F14D1FDF8DBAF -:1096B00087584EDE16FC0FC2FC767078296C7C67EA -:1096C000896C1ACFFEF93541806F47F98A9455426B -:1096D0007CFDB2719FE9BA6D96BC7DECCC6F15AB89 -:1096E000C9F7D3DEE725D18B6865DB0D43EE7BC37D -:1096F0009BE32F3D54169FCF8F8827EB3800EB62FA -:109700007231D2FF39DA7FD2E8BFF4901DD7291A1F -:10971000F950B2FA6D1CCFF47C7B21C513C4B33E63 -:10972000DFD563E3DF5FE5F841B46AE46F12DFBFC2 -:10973000F64B48BF8DC2B769ACACAEA67090DC7278 -:109740005418C7C6ECAF02BAA67FF0BDBCB557F03F -:1097500042E636137F6C29BE8A328EE4F393B2CC94 -:10976000FBF365E1F73CC0EFC238FCEC249816052A -:10977000BC0DFA103E1E7D1E977C478DAA09E0782D -:1097800031A53B3A9E3D2B42128DABF341BF10F801 -:1097900035F01F9BEC47BE4526CB09F9A05D109123 -:1097A0004FC5E1EC94101F09FFDB1F42B8C30C9DAD -:1097B000D91C7E8097252FFE0DE027A9249AEAC5A3 -:1097C000EFCD5205A5039568A994FFCB129120FF18 -:1097D00029007B02964F9533804F4CF38780FEED36 -:1097E0007C3C65B6EF6A4F7C3E9FF27D8D97877C0F -:1097F000DF3695DBD97C3D9C7F28734C7831D03E99 -:109800009DB5B7AEF723C2D6FB29A547863F737C2B -:10981000410FF4434CEB6E516F08D6AA280F3E85DA -:10982000FACD5F09F4CC017AE5F2C02A5793F263CE -:109830008B3CB5FB0C79F84731E05311FC9BA7201A -:109840007D11AB1CE76960C43F270F69CB4472767A -:109850009C203039A565E1FA753A225C4FD0F79B20 -:10986000F27593FC90613E94EFB948043B4F25514B -:10987000CC7B483DE63F9E581115683F0EA9AF0DC1 -:10988000F89783F251AD70F0F81BB83C49B68E0DD5 -:109890009724E6FFF9807C80DFEE7A1242BCBD415E -:1098A00001BA12B410F902E88B84B9FCF5FB60BF71 -:1098B0005A1B1BC83BA584A41CBC8EA863611FEA6D -:1098C000038172D04B6815CA824949254B25BF6A6E -:1098D000C4C7817D24ABF87841A43B8A17970AD08E -:1098E000BFD38C3703F85142896E12E6D560C2FEB1 -:1098F000F87EF27A49F16760FFF5F5A832E2AB0530 -:109900002F5C958A00A84DB3BD309FE17C36C343E0 -:10991000ADCBC571B02FDAF49174ADC3FB66CF0047 -:10992000D1E979F38AF7415E3597571CAEA1FB94D4 -:10993000E657AE9E4653570911009E6DD0592EF43E -:10994000F7A2564DD7DB049DD1FCF5AB9E0D686E9A -:10995000861E66BD5254251D5F8A86D44B842F1CFB -:1099600083DB275BBFDD22D70859717E7AD00DAC2F -:109970009D46FF03BA4AB7F4931630F3710F31E4F2 -:109980006979F380DEB4FC7F643C85AC76AA14056B -:10999000EDAAA844E8D869444997286AB8A64A2499 -:1099A0004AF34A567F4054CFBD2FCD844C677C3C50 -:1099B0004C8C78BC99D3B9AFB6B9B095F6FB71A50C -:1099C000DB0F743E9CB2C1CC8CC1EBE9B0C8E18E18 -:1099D000F2BB11EF9B88E62C02BDBE5C44FDA54D99 -:1099E000DDAB18E5D0B33A3F19841F4495AA9035F2 -:1099F000207ED85431E0F2FEEBF861D57BCE173FE4 -:109A0000526F30EFC797DDAFC3801F13CE1F3FFEED -:109A1000D5F1F47D4DC6977CB5B7A25DB1266F68D0 -:109A20003D7EF0BEAE46FEE952492092A0DD2F05F4 -:109A3000C12C7F8C69B6515EDC62DA2FA960DA91A5 -:109A4000EE21E021A91639A8F3B1069B7A2C133A2E -:109A50005050DE38797FEDEADD1AE8ED1FE7018628 -:109A60005079125E1E1540AF2961F61D742002BDAB -:109A7000A88108DA212097E8BE38F8FCEC3EB31E36 -:109A80006F5352CC7ADC2C4D30CEDFD520E33C9C9A -:109A9000301EEDD741ED0518D79647A22E6F1C5FFB -:109AA000612866AFDF795E78A0E32B8095E1ABB9E2 -:109AB0005DABAF22A15E3768BC6BCDF34DCA97ACEE -:109AC000EDDC927ADCA06F246F2791E306BDC50719 -:109AD000B2C5B0FFAD76F2B440F5BC26DF77349C5A -:109AE00037FC9303FC89A03CB3E5D490900A7252F2 -:109AF00065EDD40C265F7709267B5BFF9E7C1E6C90 -:109B0000BCD8CD84F482DC9154D47F93D56F6AF4B1 -:109B10007D55A242C8DEF0C06489EE5FF3AAC0ACF6 -:109B200020ADBFB671D764F8AED7AB11454EBF5468 -:109B30006C56811EC3F196D07A4EFC4ABE00FB885B -:109B40007266D580472ED233592AC3AF7CFF883046 -:109B50004007B4CB25225BAF833C8DF5A023A847FB -:109B6000B938CBD386906FB10702414A776BA5888D -:109B700073054D5B5C3CAFF27C3ACF2B3C5FC8F386 -:109B8000643BE6ED32CDD375A5D8230AE65378BE03 -:109B900090E733783E9DE78B785ED88EF91699F57D -:109BA000D721F5B0FE53785EE5F90C9E5778BE8854 -:109BB000E7C95E36BE83E553ED3DACFF549E2FE40E -:109BC000F94C9E4FE7F9629E17F6623E299F2C637F -:109BD000F08FF305066F1D0F09C0D5E4E78A5AF22E -:109BE0000C5F32058687B16FEA78E347FE48DCF9FF -:109BF000486FC3B9BFA1E906E66F20DC3F62F87E7B -:109C000058057E334BF40F455F8F707EBA8BEBB1F6 -:109C10003B1B15D4BB7734FA30DDDEA8E2F748638E -:109C200019A6DB1AFDF87D6BE3444CB7340630ED22 -:109C30006A9C8EE9A6C620A61B1B6761FD0D8D21BF -:109C4000CCAF6B9C8F6947633DA6ED549F85744DE7 -:109C5000A386694B631BA64D8D614C7F7843C54B32 -:109C6000A0D27EEC1651CE279BFF85BB44131F1E4E -:109C70001D31F3C5515D19A67C6938D754BFB8AD05 -:109C8000C8545EA88D319517345498F223EA279B67 -:109C9000EA5F30BFC694CF095D69AA3F2C38D394E0 -:109CA000CF987ABD29AF4CA935E5BD950B4D797795 -:109CB000F90A53FF2925DF37E59D79AB4DF53B5C6C -:109CC000A19F8A942FC8596B4DF524F7DD6679352D -:109CD00023EBBCF816F948CB06BCD2F98795DFDB3D -:109CE000F2492080728BC99726C05BF0678D209166 -:109CF0000705F0235D7E18FC178E1226771C83E47F -:109D0000A6B93FD9BDF38846C7A9F61EF6F519E8EE -:109D10008C18ED4ECAF7FF2C32BFE2DABB989DDCFF -:109D20007957627B19393BADD7F979623FED9F4492 -:109D30009B452F60764AE75D02D6FF57FBD7CBAD38 -:109D4000FDC6C7A37B5C65B05341EE4F60FFA7190A -:109D5000F4137B5FFA1CB07B743BD6C6E9BCBACC6B -:109D6000FF763385778B42FC0E9A6F71D710D02B1C -:109D70003E5618DD931DF9686FEBF507CFCFA0575E -:109D800020FF4931D9FB927B26F29796ACA1F532A0 -:109D9000396623512AAF6C3101FD72B2149C5E48C2 -:109DA000E9577ED5E65F45505E26B4DF09B91BE171 -:109DB00060B3E837CD732D7C6FEA085CB75DE76F61 -:109DC0005935F8BD59197A5E0E9817CC87CFCB1E3E -:109DD0004BC5D41673E17C27C532313F31968EE9ED -:109DE000C5B10B30AD8AE5603A21568C6965AC107F -:109DF000D38B621762BB8AD8684CC7C72EC2EFFEEE -:109E0000D8784CBF12FB2A7E1F179B84E9D8D8D77D -:109E1000F17B79AC1AD30B63DFC0EF636257603A12 -:109E20003A760D7E2F8B5D8DE9A8D8BF613A3276E8 -:109E30001DA6A5B1399896C466635A1C5B84ED8A49 -:109E4000620B302D8CDD82DFD5D8724C0B627762CD -:109E50009A1FFB1EA623624D98E6C556617A41AC57 -:109E600003DBE5C6DA31CD89FD00BFFB621B31CDD6 -:109E70008E6DC6343DF600962BB16E4CD3628FE2E8 -:109E8000776FEC614C3DB19FE07777EC714C536399 -:109E9000CFE2F794D83398BA62CFE37767EC00A6A5 -:109EA000E7DA2739CFCCC76D5929A6FCC463663ED3 -:109EB0005EF5A6998F57BE6AE6E315AF98F9B8FF2D -:109EC00090998F8FDB6FE6E3E5FBCC7C7CCC6E3327 -:109ED0001F2FDB61E6E323B75E6FAA5FB2C9CCC771 -:109EE0008B3A179ACAD566331FCF5FF97D53FDBCF5 -:109EF0005B579BCA7317AF3595FBE69AF97736D94E -:109F000062B6BFA76E37CB91298F98FA7357EEB51B -:109F10009C034490CFA494FFD4D4CE597230A15D59 -:109F200063F57F0348244ADF779014FF5A61F07E7F -:109F300066707E90097447D32C4E77C380EE689A82 -:109F4000F18DC5787EF4C937DB7E416D4392710196 -:109F5000FD673274BBA12640BFB7E6E879A209903D -:109F60001F4198DF80BC5F8DE5852CDFD574AC5A2E -:109F70002B477D9EFB154E57835FACD5C5F20FD99D -:109F80005E59057E858CB440AE9FA63BEC89F9F8FE -:109F9000633619E1714A0C6CB3D1F5FE6775DFEDDC -:109FA000E00FFCD411DA6EA3DF173B4305E06AFE35 -:109FB000C01E7A4802BE48020FC0F73412D861436F -:109FC0007E6DF67B36828140FBF98B187C18CA3394 -:109FD000AFDA857691BEEE56CFD0F3B9CFC6E45254 -:109FE0006B3A41BB51BB4746798A7F55713FD5BD1E -:109FF000A9DE009477DE236F87F320BB3F9BC9095E -:10A0000062911F9B5A9783CBD101FB6933FA3D7B49 -:10A0100031F5927EF47F2A441120D5D73FB0EE115E -:10A020006CDD141E87603D32F84B697E75EA55136E -:10A03000613D141E2F7078BC681B961C1E044E0ACE -:10A04000AAB82A01FFEC164CFEC7778550AF8D9D4C -:10A050005FE27C54CD8F707BC4C6FCDD3AFCE8DF48 -:10A06000AD19BA3F86B53B82FB60E94FEFA7D7C673 -:10A07000C7E7F250C7E34C918412C1BFA591F99F85 -:10A08000C9AEFC2FE5AFFECC2E261CC72E05F19CD9 -:10A090007410DFCBB2D8F5592138D385F38784E724 -:10A0A000A99364EECF900ACEEB3C4AF79790DDF986 -:10A0B000E755FF217DDD70BE908DA063FB74281FE6 -:10A0C000F3A5BC7D31D7EB9EFFD353D125940F74FC -:10A0D0005230B3F348B33ED7B949C473F4E2114CDC -:10A0E0003F6CE07A80839A0DAE710639DD69D60B3C -:10A0F000DB7438EE37C3B19822F44F2BE8FFB80B6E -:10A10000D8FC14F37A9AF5F55AE6D152EE2746BBFD -:10A110005B1A1B1421EFD8C4E6611D9FF0F3035DA9 -:10A12000EF75B8B9DF4429C07EF571ADE310DB4AA5 -:10A130003C1F4AAA8F58C7F992E76F174989CF2F5A -:10A14000E9FE209C4AB87E441AE81FCD8FE4F3D77D -:10A15000FBD3CFE1F4FCF37FAAC3F3EDD6702DEA75 -:10A1600079AD3E26A7C967B477E88F24C617FD3CB2 -:10A170007C0DD88D60CF95D438B15D568169BF5CB8 -:10A18000A59B9C008F66E56E05D2B565AC5ECAE8FE -:10A190001DFCFB76FCEEEAAA3F0CFAA28BEAAD129C -:10A1A000C07BC4AD58AF595981FED9942EE6B74D46 -:10A1B000E1E5B925AB9D10A2911B0E38A11D5125DB -:10A1C0007F29B4EB0A4F2F027F571BF14B6C0A4ECD -:10A1D000D8C7ED1C0E7925520DB4CB0B6B9A0BDB57 -:10A1E0009100B4D3EB45F87AF3CBC45570AE901F11 -:10A1F0008E846BC04F574FFCA5F8FD60B4D0507FE4 -:10A200001BEF5709B3F993F9AC9E5EBE95F7E70EC5 -:10A21000D7F756433F9B58B92FAF12D837C9566B63 -:10A220004598CF3A8EB7CE424960E741ACFD161D46 -:10A23000CD2CF45E1A66FE4EBD5E179F870DBE974D -:10A24000C7E97E0DB7E7F57A3FE4DD8DB4B40FF3CF -:10A25000EF8E4AD6BE89DBFFFA7E97CACC2FAEE3DB -:10A2600047327C256D067E060BD452CCF9860C93C2 -:10A270001D47EA73CDF9F945E6FAA131E6FCAC0ACF -:10A2800073FDC06453F92703FE92880BFD22DC5F47 -:10A290003292D7D9D2C5F03CEE8FEB7319ED8B3CDF -:10A2A0005E6F5B3D8B7369729F5F5C4918FC16C8DB -:10A2B0002C981F46D1FB69ECC2EFAD81DA141877F8 -:10A2C00067D7D0FDFD84D3D5E39CAE1EE3FBB787F3 -:10A2D000EFC7A3DC1FF330F7C73CC4FD310F707F1D -:10A2E0004C37F863E8F7FBC11FE3003F4D10D32D57 -:10A2F000E08F413F0DF3C7FC90FB6336803FC60102 -:10A30000F8D780E9C6F1E1EBC0CFD6C1FD32EDDC74 -:10A310002FE3B5337FE3C6CB02B950BEE3B2C4F638 -:10A32000AED7CEF024171414CABFF389164D01BA64 -:10A33000E82404CE5B9CAF680137CD8FDEC589640D -:10A34000BF1648A5F9511196CFE3E3809CC0F8A74A -:10A35000061617E3C8D3C86CD8A73CAAED50F8AED0 -:10A36000E1F8FA9AC4C68372A41B95F88C7CFB0DA5 -:10A370002170449A00FDB2F9B8422101CA86DFDAA1 -:10A38000AFC9B45C59DC1B80ADF2B6F544C17E5652 -:10A39000B528EA1B1BABFD87E13C6BF3EF6D7EE458 -:10A3A0001D59C4841FB4EF8476757E6C1BEAB7AD6B -:10A3B000F53CBEA892D5CB4F627F8FD96196FF65E1 -:10A3C0005BCD764F6BC3CC21FDC5C36789167F92E9 -:10A3D000E55C608A191F5B036C5EC9FAF3569AE765 -:10A3E000E32E37F7D7EA1E7A3EAED855A8EF27C33B -:10A3F000F332B1D66D9F10CF17C72EC5FA56FD4E5A -:10A40000227E543EA4A97200CE79A5A94A00F45A2E -:10A4100069AACA533FFF1EE0F920CB2B03E7DBB943 -:10A42000F661087FCBF97680C0F9F3C6D184D917DD -:10A43000DA9CD5812934FF6D82F6C2EBD2B21A2D97 -:10A440008FD2CB0CA768FB0AE01B8B57D0E3BB3243 -:10A45000E5487B21E5E39B378A643BCDEF080F4D50 -:10A46000CF83E218DC01F4CF14772A1520BE93B510 -:10A47000DBD4294E4F14377031A72F728858F5E678 -:10A480008B61BD2D9D33159067D2B57EB40F88CA00 -:10A49000E6AFF3BFCC2D43EF5FBB65BEAE247E9B22 -:10A4A000EFE9F328637C53C7EFCCEF0F8D5FBA7EE3 -:10A4B00016EB114CFE9D61D706ABED142EAD9B89BA -:10A4C000DF4DFB69FDDCC6FC64FB597C998EBF4DFA -:10A4D00081A3C8AFF5F1739568B500F50F4C222A3A -:10A4E000DDD791EE9088F6E001CADF81FE24AA75DF -:10A4F000D2FACAFC6880FBC905D87FA5DEAF411E31 -:10A50000F603F806D89BBC3ECA8D7003550F29FD93 -:10A5100037815FB330CED7753C68F271FF3AD53BD7 -:10A52000B0F433BA3EDD1EA1FF8CEC62FBDC3A8C4A -:10A53000F8719965F5C486FDB0382989EB8FAD9E19 -:10A54000DBF11C509BC0F4026A350704A82769445C -:10A5500084F1E72AFEB5345BDC350EF98AA4680283 -:10A56000E0DB0C21741BEC771CAF7AD83A38DCACFA -:10A5700070BF96F3D59424FB9922337D3B53F65F4D -:10A5800009F6E4E67B287E2788779164D6CF039B83 -:10A5900066A68D56E3F4AA973F6253B19F387DCBF0 -:10A5A0002C4E2F6AB63FFE5FD7E377DBCD7174FF89 -:10A5B0005F8FFFBF5B8F5F3780AFE7D2DBD9FAC910 -:10A5C0002C73FF71FD5D53709E5DAC5CB7073A2C38 -:10A5D000FDEB7ABCAEDFEBFABCAEB793C17A3D9728 -:10A5E0007781D5010AD0516E961FD51A58AD419981 -:10A5F000C5CF61A36CCDE8AFF8C042D792DBAC7792 -:10A600009C3F3F9050DE13FF08133FCDCC1D5A6E88 -:10A61000E872F49311BADE1E427D9A949411A37EDF -:10A62000B5B3A18608743D5B7DC4CF978EE3E4F299 -:10A630007539FB029A884E0D331FDE3AFFA06B94EA -:10A64000819F3BDC3D01380F77FB7A217CC9C877BD -:10A650004BE409C08FAB90AF39D530EECF5DA05F32 -:10A660004E180C57E073BE0CE8D1C25F48B017E239 -:10A670003D8AC7138CAB77409414E5030E3FE34F3C -:10A6800049F9CC79C669E87113F9F40FF8CB2A209F -:10A6900022D0879E36C7931385E289213E80BCD79E -:10A6A000448CF17E3ADCADED9A951A2511BF7B43BF -:10A6B000085D210F8127563F14B1F067AAB08910B9 -:10A6C0007F583C633AFA9706FC5192995F3B227A95 -:10A6D0001CCBFF2CDF9E2327E6DBC9DA0FC43D7FAE -:10A6E000497F5D3B3F8FD7E97B80AE2DFD88E53DFF -:10A6F000A42FC1F8EE7233DC534ACC76C53F802ECE -:10A7000027C0F97186E9BBE4CE4DECFFE77199B53E -:10A7100013F56D53BFFB478ABF0B0EDB09E827BA61 -:10A720009CD1FDB10B203E93EE4F2DC46BD27D9C8E -:10A730004B825E28FC8088D341FFF880FCD67B9159 -:10A74000619F36CBCCFF4EDAEC47E11E901E877836 -:10A750007398E5F5F9D47599F3F3C8CC6C388798FC -:10A76000B7C94E20EE7001918EF6E9F3A7FA4B3B84 -:10A770005C4CA0FDD691FA56E0672DDCDF5EAB1095 -:10A7800009E206973C755FD56C9A8F70FDE72485CA -:10A79000BF6A882F5BE88EC8709EF0CEBE8BBEF37A -:10A7A0005502ED23ADB9103F984E307ED00AF739EF -:10A7B0006DE6F99D6BFED6F9EAF78692CD43DA2570 -:10A7C000248C73FBB1ACC72D6AE7759FE9B760FCB9 -:10A7D000A23FDE7C9FE95CED5EFB27DBBD29AB245D -:10A7E000D1FDA973B57B3BC9784B9C7D32F08B655D -:10A7F0005268BA50148FD392EDC1C0051414D2D34D -:10A80000E3A370A464A8D7769EF50EC379C779D464 -:10A810009B2E0ED1DF194EC7BFD8FD800CF4F9C1B5 -:10A82000236F5F057AF5A2676D54A6D3F2DD1E1281 -:10A83000457B2322831C5BB8CF867E372245ABAE97 -:10A8400031F05F8C90A5FD2F7ACC8371150BF73A10 -:10A85000223368FB854FBE338E50389C59DDFFE2B2 -:10A8600005603F3C22B03842AD6FDC35F4FB4289D5 -:10A87000DC144CC407399E9F7E267516E091B0EB20 -:10A88000C08DD86FCF77ED0EC339DE5F65764F810F -:10A89000D6C3F325ED6121522AB0F919EF2BE8F167 -:10A8A0009BA71F16D8FC9EB6475C30BF5DDD728843 -:10A8B000D65BB6EB2F88B75F7F6C8F17E0B0EC6983 -:10A8C0009B89BF2CDB658B3AC661FAB603EFB904EE -:10A8D000DC02E5234B91C5D074DF128CF75EDAD32E -:10A8E000F1179B17DA9BE987C2C51F05B8BE66F34F -:10A8F000CF80FC4F1EF2821D78B2F7412FC095F633 -:10A900003B5BA67875E947063A23ACFF58C6E0FEE4 -:10A9100008E99701BF96F5B4B3F12CF47912FE273C -:10A9200067B05C18E930CB858FC92B55A818EECAE3 -:10A930004C181F3F201738BD2EDAF3F1368D8E7B71 -:10A940007AEFA96D1A9DFFE27F7CB8ED4ED0037FB0 -:10A95000EE5280CF2C7BE4F75E62807BB583D1FB27 -:10A9600099871FDAB985D2CB99D71DA8B79CF9D999 -:10A97000897C95AEFBCCE37FCB867B02B7FEECB245 -:10A98000E100875B9FF8FAF0A1EC7EC0D788C3B8DE -:10A99000AF11EC5F7D5A60C1F8FB796AD99FE7F788 -:10A9A0003D9F0FF3FCE08803EF152EA3DF1A2A600A -:10A9B000BF9620DF87FC4A0AE7A5BBD7FCC5362E29 -:10A9C00011BCB50B441FA4946C7CB0DFD77CEB9218 -:10A9D0004A48ED7E15FA23FDC8B7ADED96BD4AF79E -:10A9E000F52BC9F7F163F2990CF05FB6BB9D8D6B47 -:10A9F000D9C70FE07F260DDEC79B1CE6F3958FC9F4 -:10AA0000E2FB5197DF9799305E4ADFC7254F7C7B89 -:10AA1000483D40E707E782EF7C1EF757EE082C73AE -:10AA2000005DED4DD57C6C7F233368D9993D1FE7E0 -:10AA3000138A1FEFD9FB6F043ED9FF3387B29D7E87 -:10AA40005FF8B3D790CECE3CF11B5965F79DDC0281 -:10AA5000D513CE9081BF5ED01B96F233E4653B3CAC -:10AA6000518737BE4F4B23574F57BDF8FD6DFC1E26 -:10AA700061F8BF3472E05A21C1BE3DEC28627C39D6 -:10AA8000320CE1B284F4CA4AB9793F8589B08F6F3C -:10AA90004F03BC4BB68FFAFA1558FFC586FDDCC1D3 -:10AAA000E8D65A7F29A54FF00B0EEC6B44788D2425 -:10AAB000A0D333DD0E09E27BCFD8CF713FF74BEA4D -:10AAC0007F0F38929CBF71389C8BCECFB5BE2F0BB9 -:10AAD000BF8DE0B41E36188EA73F4BCCFF9F730886 -:10AAE0007C1EA1E9B9B6C1F2CB4602DA0585F1F9BF -:10AAF000B6F6D890AF9FDE65C3FBA6563EB1942450 -:10AB00003EA7FEA53ECED307C6013F3B7DF0198E82 -:10AB1000970CEF97EE7E5BD6B83C8818E54112FFA4 -:10AB2000D46B9CDF2DDB9FB8BF65BBFF92B0BF939A -:10AB300052E0BB30FF93BD76A2D12E4EF6D8A627A9 -:10AB4000D29F0E38EC26FDA9D55375248DB6B37966 -:10AB5000535418BA6975E035B0E7B4DFDAF11C83F5 -:10AB600048FEF71C704FD393A2AEA5F06AF2CE4315 -:10AB7000FFA3DE5FB3054E922FA8815D2A65052BEA -:10AB8000998ECCE6AD97DB15D1346F2A67F3400E72 -:10AB9000BD35FE841DD6F9678B3EF86789B40EA7D4 -:10ABA000FDFD5913FCABD444F86DEE3FB4D24654CE -:10ABB000A3FC73F4BF05F321CFB908C495D87EEE8A -:10ABC000D2809F2CDBE68A38E87A9E7FE2939D0054 -:10ABD000B733F73B88C310275EC7EDAF134F7CB286 -:10ABE000EDEFB4FC0434A6E3D76DA3F5410FDF9D70 -:10ABF0008AC1FAFFB9376D1CA1FCB9EEB93BAF02AF -:10AC0000FE52073443EBD73D361CF5BAE3C358FE7A -:10AC1000F89E1111D897C53FF9D95290238B7E9C8D -:10AC20004AC03479FE89D76E84FC99E73C18D778FE -:10AC3000E6B91397021D50FD5935CAF105C67704D0 -:10AC400068BF8B20CFCA852F0CF1328B20A57C6387 -:10AC5000D1D36901F0131AEA61BB658EFEDBD151D5 -:10AC60004BB45C116D9C682ED0E1A25DE6F1F29CC4 -:10AC70004C7F5A26F7CF63F5C3B98C5E7BB1DD6894 -:10AC8000A7602AB7B6D7EB8F721659FA61ED973ADB -:10AC9000487D22FCAFE4FD2EDAF5F928737F1AFF18 -:10ACA0006E1D877DBF4D60F74AC8E32E3C475B2C85 -:10ACB000474766507A7D5226F3816E177BA323D3D4 -:10ACC000E978CF723EB93885E6E9F75C3E0FA80F08 -:10ACD00079E2ECFB31ECEF92A75C04F07DC9731EC6 -:10ACE0003C6F59F2E427C77F44BF9F7E2215E3B42F -:10ACF000973C7707EEF71247F446F06BF73FEE40CC -:10AD00003FF2E9C75FCA073DE4B43D9A9F31847DB5 -:10AD1000BEA4070EC107AF83DA0565F5743EDA46B7 -:10AD20001677D64052FCAB68BF0DE0D7003C7ED30F -:10AD3000C5E2A3F839EE0AEE0F3A3B574DC3F99737 -:10AD400033FFD60A7E4F7DC537D5E1E98679405C71 -:10AD500028B988903BE4FA51C0676DB16F1015FCBB -:10AD6000EDB1624CF57A3685AA59706E90C5CEC9A0 -:10AD7000ED597E52570EED581C11715F394067BF77 -:10AD8000A65BBC62B33A1CFAFB7727E32F1DAEC06B -:10AD90004227F21937DEF7C4755286A03DC1D6F5B9 -:10ADA00089C0D6659DEF2776CD01FC3C7EBECDCE19 -:10ADB0004D1A24F53538A72487395F1AB47E4667C3 -:10ADC00067950CA4337D1D1D8D0AF293F6461FA6D0 -:10ADD0006B1ACB888A71F87ECCDB383C1CE51AB143 -:10ADE000C1FD5795CDD5E10E06E05C02FA047FABBC -:10ADF000CD1D42FC72F8EAD1F677BA991FD2E6D699 -:10AE0000481D4DED6E0627B8770A7092795EEA9A72 -:10AE10008170A5EDF1FB025768A313FD11634C7C13 -:10AE20004ACEAA30E507C14DC78B3DFFD3F02308BA -:10AE30002FF0D3A8E83F9F88706B690C60FEFF007D -:10AE4000FC9E61F09B4C5403FDC85935A67C52F81A -:10AE50006DA6F0CB8AD395150E0D3C1E4DA7A764A9 -:10AE6000F4FBC34682CEBCBB1BBB30D5BF6724916D -:10AE7000EB392E819FF78756C1F91F51985F856482 -:10AE80006924CFE04F223E0DEF31E19B2650EE6664 -:10AE90007E447D7F6D8A74DCCCFFD4D7603D77BC67 -:10AEA0006C17815FD91A1E20EF641AE87846D0A586 -:10AEB000229CFDE8BF6DE2F2B565603FCDF4D1D1D3 -:10AEC000A862BA8ED3C9064E271B61DFC13FE717C0 -:10AED000714F3BA713949FF7D03CB3EFA3C4E8D7BF -:10AEE0004EF7F744ED74FF9127A998B2775E8E383C -:10AEF00022A5B45D6A390900BEA41FF95E84BDDFD6 -:10AF0000D283F7FBD339FCC8FEA2F4EBF0FE34B1D8 -:10AF10003339456C2C0DDBC17EB2C2B7C97FD00975 -:10AF20007677B2F964FB35473E1D2FFB4D07F2EFF4 -:10AF3000AC1B7A8ED4D275B83B53D19ECCF6337C01 -:10AF400074FB43429D61FFB293E87D9B5D57385C83 -:10AF50008087107F4BF9F6DD5DC52E3CBFB0F7F85A -:10AF6000800F76A43339A3CEA2A35D1C6F7796F32E -:10AF7000476FA599FE757EAC4CA930E1B1CE6F3319 -:10AF8000A69AF15DE7B76F0EF0DB608E0BCE3563EE -:10AF90005B911EADF8DF649735E12BF0DE06617E34 -:10AFA000A7B705F60ECB603E80F12867FB0AB7C352 -:10AFB0003B00AB79FCB346E905E50EF77FEA77B9CC -:10AFC000F690609B5A08EF81500485776328FE0055 -:10AFD0003DACA7F843305EC8CFE96422A63A7E565E -:10AFE00083F3C4A0B7D94A5E14D9FD0B11640E9146 -:10AFF000A81DE8063FD381494ED00B253B8B53E972 -:10B00000F7883D7036D6E29EE984F86821BD12F7D4 -:10B01000FDAF9EDA82A1CE5508C4F152BC51DC7E50 -:10B020007214C6817BBA40174A05017B728FBB3709 -:10B0300005EC1BBF4B349DE374B842D35C86FC58CF -:10B04000189DEFDBD770FDAC1FEB783339BD933C17 -:10B050008D9418E85B8F0B25AA46CA0C74BEBA748F -:10B060001A8173CDC1F49D848F3DF8DFC3C79A0A5E -:10B0700022B86F762BDFC8A2FCDD8DA9262A30FF0F -:10B08000BDCDFF361EF1AC0EE041DCDB07F497AF1F -:10B09000150D9EA7956FC5E5918AFE2A2A8FEE9D14 -:10B0A000087C30893C3AF0A751DF9269F93B2FD9EF -:10B0B00004A3BF6E7EAC1DE5415D6C1251E97C6B53 -:10B0C000BB7E80E9BCAE6EC4FBF7222D5ED8C7F70D -:10B0D000DA983DF75EC41EC17884CFBEF8C2067E02 -:10B0E0007DC2FA7F6F6B13D623E07D318CFBDE5679 -:10B0F000D69E54AAA84F9FE56BACDDE008405CF9F2 -:10B100007B5DB4DD10F0AC056328817E8AF7FF21FA -:10B11000D69FD48F023EA7D3FB1D32E54B0087B7E5 -:10B120001C09FDEC0B5C97AD03782F70053601BF51 -:10B1300021EE8CF37A87E21D91EABD08EF90F76A61 -:10B14000939F95F931DFE17A31712629F7F2F64ABA -:10B15000E2F2259DA75EBC8BE65ACB434162B0AFBD -:10B160006D84D9D74B9FAEE6EF7DB0F924C04FA6D2 -:10B17000CF763A900FCDE5FE201D5FE3F812F2F294 -:10B18000FBA0267C5A10DB88FB2D748CBD771285C2 -:10B19000DF87148FC02F27745C321CE868D5DAAFC4 -:10B1A0006EB881F6FFD12B36FC3E3FE6C2FAEFDFE8 -:10B1B000E5BFF706D0D77F69C733F68F0E5F86E706 -:10B1C000B1EFDBCD7E841B5318FDFED1C5EC917928 -:10B1D000B10E937E3CAF6D8E0CFEC779B1F5F87D54 -:10B1E0001E1CCAB07B1B87AA4BE0BC86E0F9E81F97 -:10B1F000DBDF9DBA1AE55905FAB1EAD63912DE232A -:10B20000F9A34B35F19DBABE4EEC9750FD282B9B10 -:10B21000F767E01F7531B87402FBA311B867308F70 -:10B22000F39181F96DB59BF8C8FBAEC47E925303D0 -:10B23000EBFB2AD2D1E0F55DCAE84B1FB78FD15D99 -:10B240007C3DF74E4AB49EF83AA660FDF7D3138FC3 -:10B250009F91C2C63FDE389F04281FAA75D07A6E20 -:10B2600018FF96D68960676F4DCF100CEBAAEB5A8A -:10B2700044028675D56D9D2DD71AFA8DEF83ED05A5 -:10B28000E33E64A4FC63EAEA7290DBC17F003DD533 -:10B29000765C322E847636E327EFD8FDF9C0574F1F -:10B2A00074DD9290BE33522CFBD3C5F787EABD956F -:10B2B00086FDD1F7C5DAFEF89FEAFE7A17F8013667 -:10B2C00033A52619BC06ED5B6162B89573FC3C4E54 -:10B2D000E56C08E1A63E7904F07A5D2AC6712687FE -:10B2E000DF85243414FC92E8AF54DF294D9900E344 -:10B2F0001284435D17C38373C12D3E2EC783EAC4F6 -:10B30000EBB97E000F1A884609F6A87C2E3CB8934C -:10B3100068CE21D6318007A34C7870FDDAFCCB8053 -:10B320001EDF033D65D4E0FD3F2A6BDEC9700EB41D -:10B33000D686E74C4753B4ECEB597E3CF0E7A3DEEE -:10B34000F055932BE3F9050F967A671BC63DD1762E -:10B350008B37919FF5FA64F853A291F2AAFF7DF81A -:10B36000F34E927B570B5CD537A6005F0E27F6E7AE -:10B37000EAA9CEBF6D69EE01BB13E4E95177D15F55 -:10B3800023B4F451576801F47387A88E9B2DC4ED44 -:10B39000CF41FA67E3F44B8E9582BF3078C9313BD9 -:10B3A000EA43D81F01BDB290DFDF42FF460ECA0359 -:10B3B000EB79E9FA94C284E7AA2D8DF5171DC30035 -:10B3C000228D28867B6012617AD4A784F9BDF4F5BA -:10B3D000C8F690E207FB522041C073BB146A833861 -:10B3E00028BB2F6BBC66806B670A8BFF731D3AD43A -:10B3F0005648DBBBDE7D45C1B8153A0EF8D79C79BF -:10B40000D259A37FDA9EC5E2124989E17B11C42794 -:10B41000D0BCC9CEA7F31DC24E7D566070D03C0E85 -:10B420007E0F4EB381DCBB4E7FF8024047F1E575DD -:10B430003D0E446A66E5E97A71332BE7FECB65B5CC -:10B44000CC3F69DDD7EBF6AFC177F5AEDB9F3307B5 -:10B45000FC58D7B947BD0BE70BCF820F1FF03D9DBE -:10B46000C9656BBBC7389DFE5BB7A8D9E9BE1CB2E6 -:10B47000F71F84B876ED36F64EE2F5BF3F644FA570 -:10B48000E91BAF1EB5435CD14D10A043D7359BA837 -:10B490003253822308D739A4C7C3F23DC3667A8CDE -:10B4A000FD515315FA5BCECE79AFFFFDAB9781F816 -:10B4B000A4FDB5407AD32B4486FE67EF535BD9B524 -:10B4C0003BDEDF7EDA9F18EF2F0E4799D9399213B2 -:10B4D000E112879313E1F6FA405CA4867E14039C84 -:10B4E00051DFD0E13C00B7B459579271C9E9E53A50 -:10B4F000F7C877C9B8F8BCAC70FE088A28BD3D9380 -:10B5000012F815D04D2425F06B48173BFBF3A5220C -:10B51000BC77F83BE0B34B6DA182EC62BC8F386A1C -:10B5200018C471F5263E5FB5D2E95B402F10CFCD30 -:10B53000E32B6FE4EB7BFE7B273C1837F9C46BF9F8 -:10B54000902EB1F5ADFB2ED0DB7FD850FF3EBB6F08 -:10B55000D49071696F717FC7C914FD3D16B6BE9B4B -:10B56000B81E77D3BED408BC7B795383CDA4FFDE4D -:10B57000D4C0E23888D43BEE5A931ED99CB41FB095 -:10B580003BADFDE8EB3B989F7B21D887F74F90556B -:10B59000F03F1C78E5ECEB75349F32C289E7B2EBE3 -:10B5A000D239FE568BB8EFF7A70752C782DF696D15 -:10B5B000865FA3EB5CFB02E911297C0E8EBE3D5237 -:10B5C00043C75B7F89883EAB0DB107306E522B6756 -:10B5D000EF14295C1FDDD07BB40BF0F1C41107FA26 -:10B5E000FBED1E765F75AD3D980FFAFBBBDD72C2B9 -:10B5F00077EFFEEE96705DDD421FC6BBCD21612761 -:10B60000F08D7DBD3387C37CBC7EA200FA9FD86AD3 -:10B6100013F93D28EEE7884ACCCFAE492C1FE0A9AC -:10B62000E232C6ABB54F9F8AF114733B7F8371C280 -:10B630005E7E9FC93A8F0B53D97C3DBD1957007C64 -:10B640003D53457CD3C8E3EFC778F182DE1A19DB9E -:10B65000878521DB17AC54AE00B8427BE0FF05E7DD -:10B66000D9BE3895C53B6DE47672B7DDDF3A95F605 -:10B67000D3BD2E5D80FDD0EB4D4965FACC89A9BACA -:10B68000FF268CFE9BFC12C505EFA3E40790B8894A -:10B69000A7328C71B8DBA11EF36F221CBA473F1989 -:10B6A00085F3E3B5201B609FED0C9FD6AE13D09FB2 -:10B6B00049E1970BF2E2DD7B1CDF807514B4090AC7 -:10B6C000D8DE344D38EF5BDD4E66B774DE8B762006 -:10B6D000B847A1DFFCADBFC3797992AC779B9BC122 -:10B6E000EBDD73E0475AAA9DDD1B6AE8E57652144C -:10B6F000DF3F0CEBEFC2052AD9BB84524035C6A10F -:10B70000C4E987D961749D0138DFAA9D2847C00F1D -:10B7100020B675E33BBF73C20E72395D5FA7D01BC5 -:10B72000007AD12688FCFDADC05B00A7F51B8763BE -:10B730003CDB1A31908FFE9DFF25E3F9D8C1C0D9BB -:10B74000CD73687EDB4419E9E26080DD6BBD7F6507 -:10B750005137D8E19E861A7CB737A2E04BB8A4A92E -:10B7600092BC0CF1A44D2B4545A0F5C341FD7E8153 -:10B7700092027831DEF6E11565707E9623822F897C -:10B780009C10D8BB202D2B6B14D8D716254B30DA44 -:10B790002DB7A432F9F2ABF4E02DA934F5DD75B77D -:10B7A0000231DD1B62991782BF506B9355F67E30D4 -:10B7B0007B4F2493EF4B66AF189DE7C5BC7B3E35AE -:10B7C00091374C617ECA1F5C1962FE453893AC42CA -:10B7D000FF22FFF3E1BE66F1DCDA312998D9B47AB1 -:10B7E0001ED6877EB2693F999562B48AF6BB3D3D0D -:10B7F000B00DE5C9654E841391FABA004E91CB7233 -:10B80000FD10D77AF7A491BF8127A5320FF7CF0497 -:10B81000391A1991F24637F0A91659053ACF5C79D1 -:10B82000FC06F89EEEFFE12D906636FFE14E900794 -:10B83000E97D7F69C4EFD365937F2FF3CDF73F8711 -:10B84000F2CCA06CF2139E4E0FFE3095EEFBB6F2DA -:10B850007018DE3DC51DCD8EAF63CFAADEE9F08E38 -:10B86000F589AB45FF765E8EEBDAA444D632B85547 -:10B87000825CD3E1B646547BE01D65ED2A27E247A2 -:10B8800009E9457E9503A7C8C5F17DC97CB37D391B -:10B89000C44958E7F308A75BF883772531FE9ECAB1 -:10B8A0003139676A0AE0F5E315BD3ED0E3D7A52735 -:10B8B0008E4F38E966ED1D49EEA71FE7E5C012BBC4 -:10B8C0002A300D8C85D44DB43448F39CF83EE1E326 -:10B8D000A2FA47C4F3BB6D2AEC0FD4B7D3FD3BF0FB -:10B8E000F249F40F1E08FF0ED317DC657A7FD16C86 -:10B8F000DA7E7DE551F6CEB7C270A4AE8DF18B3AFB -:10B900005F9F13CE2BEACA89B29DE39BA6C319FCA5 -:10B910005D5C5ED55ECBE09A554EF0BC157C62F066 -:10B920004E5936D4A3F0CB6A5BB51CF791F46AC5C7 -:10B93000B4DE7AE817F6A799DD3B21A4CF89F41B82 -:10B94000B6E17923A5F75FC179626DE7703C6F8737 -:10B95000EBE9D05F061F3783F7D74DFB01FFDF8987 -:10B96000361BD98EFCAD97405E5D497119F1B3BFAE -:10B97000BA8CF6AB562ACA5A1D0F743E4649632E3E -:10B98000951700B7B99AB61CF0EFA8537919E6914C -:10B99000BAC9A1C2FAE76E7AEA0ED05B527D7D6D1C -:10B9A000C01FEA26B2F96674D2EFA8DFA8BF82FAF8 -:10B9B000759D0E958DC7E157C9F18CC3E1663EEFC9 -:10B9C0009BB7B279A78C8884013FEB5652B8425995 -:10B9D00088E13DB834BF1091AE0EC3FA3D5A36F639 -:10B9E0003B6C96852E2CF8A7AFAB96AFAB76255B5C -:10B9F00017E1F444A715857E6B2BD93AE712D65E82 -:10BA000084EFB4FF9BF97A6AB52731BDB9CD61EAFD -:10BA10007F5BD98E5E984F61B9AC0A0867F63E66C7 -:10BA20003E5F577E331B2FBFFC4984176930CC170C -:10BA3000FDA2863CA5AB132F51C2A27AAE0081FCB9 -:10BA4000B4DFA3DF93F11CA56493795D27DA473D4A -:10BA5000D009FECF7B643CAF785CF4BF558076A8FC -:10BA6000AC32FEE3FFDD0CE0D33737E3BDA93DD5B3 -:10BA70000CFE27BE4922800FA587831900EFD2C391 -:10BA8000219ED6E33936DE13AB8AE331359DDA04E5 -:10BA9000E097B1E247E7031FA0FB0CFAE008E3BC24 -:10BAA000E9FC32DBB26B200E296B62468D8C4FFABB -:10BAB0005ACA0F6F9909EFD7661DDA720B8C934340 -:10BAC0000CEBA1E5459E62A4BBCC43B414EA351C43 -:10BAD000BF0BF6A393BF2F5F0A33CBC0F410A4991A -:10BAE00094BE3B32609E12995A11E7070FDE533520 -:10BAF0001EF80ADE29A9C0344A2A06F30D43FDD1F7 -:10BB0000BCBE2624A837DAA39AECF207EF99361ABE -:10BB1000ECF7F5A027D27D6A27CA87101FA3F94545 -:10BB200084FB7A7BD4594EF36BA8DE08FACB86B23D -:10BB30003F884077EBF7113FE04766F01F0EE33E8A -:10BB4000CE71A7E3BA25997400FD1F1C7D7C3AECE9 -:10BB500053E48088EF48D4FCC2BD2515F4A1D75921 -:10BB6000FC49F74BF528BF6FCF9713BEC34CCEA14E -:10BB7000275AEB6794CE443F5EC1A68DD3E13E4E7B -:10BB8000DD74C97F39AD9DB5A9BA1AF4183548B12D -:10BB90006B389DF7D6F1AB8008D519ECBC4A9DCE29 -:10BBA000BEAB5359DAD138FF22B0DBC3BB24173CFC -:10BBB000853CA69DBD57D7517ED619A27A6965F5F9 -:10BBC0005EE737E9F76395540AD2EFC7A69C75C1C3 -:10BBD000F9CCFD95359900CF7D6D66BD8EC0636A49 -:10BBE000D40E1AEB08073C745E9DBF27084F9B23B9 -:10BBF000DA554BF3B6A7DCA0E10CB26FDA3BBB67BA -:10BC0000019ECE2DC3F0E441EB3DCBE5C59C867E85 -:10BC1000BC5755A811768E1ABE1799F2CD9C6514A3 -:10BC20006ABDC8743C9B987D1296022F025F0E97E6 -:10BC3000876468A2F3B3CED2DA9DC0CFFE067A1D28 -:10BC4000C8B9FAF978FF11E9DF06FA507F7522BB0F -:10BC500029989A82F33DB1F59AD7C03F3DB781E963 -:10BC6000FB055B3F14703FA8DE9743FB2FA8C4275A -:10BC70002AC9DC9561E758D89F1291A82ACCA787DA -:10BC8000809D10A6F2C70807BDDF7FB6FD3AB70357 -:10BC9000DB07C1781E165F8F9BAF27DF4FD793401E -:10BCA0004E5FC5C7BDEDBE0F0F4C02F8AF64265204 -:10BCB00041F86DC169984781767EF3F816F447E143 -:10BCC000B9D3CDEE437B2AFBF0DE9195BF833A0FCB -:10BCD00074BB2DF5CC7866DF9BF9E9A03CC72BEB54 -:10BCE000F77C0BBF1AEBE8B912F7770F7BEF9C10CC -:10BCF0004AB74E7C065465EFC446F477C9EBA1DE23 -:10BD0000188F5B013CE81CFD870A80CF3AAE2FDC20 -:10BD10005C4ED05EBD39AF17F58539CD5C5F90FCC8 -:10BD2000ADC06453B7A693B506FD0143FCE188B1ED -:10BD300099EB0BBAFCE772BBCED7DB867215F40326 -:10BD4000835CADD5985C2DF031B95ED746C75139CB -:10BD5000325719F51226C7D54D5C7FE07238938FA4 -:10BD60009BD5C6E45526E8115E083FD0502EE35916 -:10BD70005E765C6F1956CEE46566E7E328D75E0110 -:10BD8000A7CB04E01B4C5E8EF8CDAB1A80C9473FB1 -:10BD900077513EFD142FF729543FCB88EB676B4456 -:10BDA0007ECE44987E88B1F5749E8FF1FAFAF71D25 -:10BDB0007C7E8F1FCAF806F0D707C345E36D06BA2D -:10BDC00045AF27CDE757B273FAFC06764EEDF1CFBB -:10BDD000DB69339C3F34BB99BDD9ACE35543D407F1 -:10BDE000FDE2FD40E4E3EC7DA976FE1E946E5F7DEE -:10BDF0002795FB3538FE2493273A1FF29080B79C95 -:10BE0000C2F7586427F26B8DDA4BB0B663E1A6DC5B -:10BE10008540EFE1AB2B61FEEB27FD15E32E0A9287 -:10BE2000D88B7F073B93C1E14BF175CFF457991D38 -:10BE3000DA2B26BC2733D123E13C7B24920AF07411 -:10BE400085D9FB84AE8972C2FA177A18DF943DEC6B -:10BE50001ED1FA493BF17E6352F92C11CD96409EDA -:10BE6000EAF2B613F6793221D5EE59AD1AF2FD4851 -:10BE7000D086FC95A0DD19E6BFFFA295C9E837EC96 -:10BE8000B4879DB01F1B2AF9BE2ACE6EB88FFEA5BF -:10BE9000F785C203F6B93D2046E07E793BB554C72D -:10BEA00032BF0EFE7ECE096ABF1BCF292EF3881C3F -:10BEB0004EAA08F189056D0CBFD64F92711E6BC753 -:10BEC0006777DB0A8DFC97C12998CAE0B476D28BDC -:10BED000885FE73BBF790D774E3E6638473CBEF939 -:10BEE000A1228073FC9D96C090F717E635FC66F2A0 -:10BEF0008E04E70303E56047B9C10E8C5C6F3C67B5 -:10BF0000F9770FB3AB431EB3FF0EF8AB1D8D8B4813 -:10BF10002EF897F65C12F1A2FF7E313BAF5DC0CFE9 -:10BF20006B4FEEB806DF53184BD1CA9E60DFDF6F50 -:10BF300034BFA7F0FE830FE532BF46C414E7B160FB -:10BF4000E73363D8BB661AFF9D0CA26655B177AF85 -:10BF5000514EBFE8D71CF8EE5C10F9900CBF5301AE -:10BF6000FE76A0E062B8D7DF83A91BE8B778F07B44 -:10BF70006E19540D43BB8B0431CD26F598FA481841 -:10BF8000D35CD283691ED8B9C52017FA31558922EE -:10BF90001203DF2F227ECC979020A612EC5B66FC6A -:10BFA0005C42DAE5C4F80B38BF00BAD7CF29F4F306 -:10BFB000FD199EDA4E0F327BF379C5524F609D0713 -:10BFC000E11F45BE3D87B3F0C33F1ED303F77B5649 -:10BFD000AC63F74B74BE8E760DEDFFD10C2607B423 -:10BFE000BB05E45FAB53AFBA14E1D8693F6D3C6F5A -:10BFF000204E6709FCFE8BDEEF1CEE5F98C3E51F49 -:10C00000B8B7D9FD3B3FDEFF99037E0643391928B7 -:10C0100067F7AAF57EC4D42923873ADF33B4C778FB -:10C02000E45A8BFE7F4EB96DC9CFB5B6FF8C4E2852 -:10C030003BEE877BF452359F9D3331B94D1149C595 -:10C04000766D8EB7D10E0B5F1630C2E510C77F5DDF -:10C050009ECCB5F8F5ADE95C89D385A51F2AF9D248 -:10C06000E15E04BE6962A06BFDDD5BFD77D2160464 -:10C0700042720E6BE6C3773DF8BCC3646B4D0E4D48 -:10C08000DF83BCC19F7FD81BFAADC7608728817A48 -:10C0900091BFFF8774388FD3E165B6CE6AE06F2712 -:10C0A00042C40FF6C30252BF1EF431F2AA0DF9DBEF -:10C0B0000574DE7205D86F44133330AFC1EFF97CDD -:10C0C000D0C8EEE51CE7EF56EFE4EF249DE2EF5415 -:10C0D0008FEDBAE32AC08393FCBD6A9DFEF571C75C -:10C0E000F6A4CE06B93FB6E7923AA8377697230A68 -:10C0F000702EDBD71E04BF10BCCF9242C7C9A3E38A -:10C100003933808F1094B7A73A5322ABE93C4F756F -:10C11000D9902F7F5C2EE23B23F0CCA58DCF2F2D25 -:10C1200003FAF9FB8DA0879CE47C447FEFF154B5C2 -:10C130008AF6F10B7BD608702FE1D46C15D77D2AD7 -:10C14000A7273F83C2C7E765F1E525BB1DD1223A8A -:10C150008F858FBC5E540BFCAF28BC30D13973BACD -:10C1600097F1BF534F108C873BE5E2BF4FE4ECF1F2 -:10C170001AFDACA95EC164179EF2F0DF39CA3B47D5 -:10C180003D1E5F4EDC3D5E46F73D5E388FBA37F5AB -:10C19000C7787FEDF813EC9CE285CD75F9E08F1A36 -:10C1A000EE55D939FE9E9F60DC38AC03EC683A3F0F -:10C1B00015E6776FEA5B27C1FF40DBE1FD0CBDDDD3 -:10C1C000F13D75AC7E17ADEF45B8136F05E0038305 -:10C1D0003BD9CDF884AE3F2E8A64E3EF2DC4CB4526 -:10C1E0002C8729BA28FCC7EEBE1ACFB5467B3398F8 -:10C1F0007C507AC6CCC4F987F3611D7B2E09E58398 -:10C200001FEFB8FE7B4E52381FE030C3131AED35D6 -:10C21000F0F7F7DF7E0AF97B9958FFE7BB002FF7AD -:10C22000B2DF1FB9E3CD8DA2917F4CF432FFFABD8E -:10C23000A94BBD701E757CE09D9C308BF7D9CFDE7D -:10C24000615DC469EF7837B59F283CDEDFFD032CC4 -:10C250003F3EF08E4D0FC693BDBFFBF90C486B7986 -:10C260003C3F895C83F445E1D2E64C20AF06EE45C5 -:10C2700045D87DB733027F7FF43E1D6EF5F24CD377 -:10C280007915A3EFBCAD8587505F8E24BE276795D7 -:10C29000F7D6F764CF750FF828A7D363FC9D92A556 -:10C2A0009ED0B7BD09E4486DC7927C80732DDCA990 -:10C2B000C33887AF5E0EF636DE3761EFC946114EE2 -:10C2C000FA7BB1643C2B4F67F9C5DE2BD7804E74E7 -:10C2D0005C7F7F56FB1A2B2F64E56DBCFC254F70ED -:10C2E0002E1B9FBD2744B9623AFC2E85CEFF92AF2C -:10C2F000DFFCBB143F029E3C01FB5B8AFD49B4BFDF -:10C30000B1FF7A7F3ABFF997FB71FEF7F6A3F361AD -:10C31000A04B08D9237EFF98FF0EF8FDB3EDC9AC02 -:10C3200002133FFF6473712B9C037DCCDF0F71748C -:10C33000AE2220976EDEB4D1F4BB26D677BD9A78B4 -:10C340003C895C4CE9CC40CFFBBD4C8FDECFF92162 -:10C35000FCB90DEFF9C05F673686DCA0FD378ABFF8 -:10C36000F35E46C2A85F8D213D9896935E4CC791BF -:10C370007E4CF198B4185C7D7E1B7FAFB70A16BF68 -:10C38000D819BA1F42753F75849E017C82777B0560 -:10C390001BE8454B27C3FC7FEE55F4DFF52496DF01 -:10C3A0004B8BFF0E880A7ACD0CDF507A0D51A4D347 -:10C3B00003F11B45F8EEEF0B5EEC37D9EFBF2DB75D -:10C3C000BC7FC2EE11EB7058427A300EE285AD2B85 -:10C3D0005E1E4DE1BF70B707E5C1C8ADCDF8FB5F8C -:10C3E0000B496F36DC2F1DC9DF93205DECF785F418 -:10C3F00077224677394CEFD42DB1FCFED022FE7B5C -:10C40000618B2CDFF5FB9B1DF021411C81F5FEE7C4 -:10C410003BDE24EF369527FE1D18EBFDCFDD3D22D8 -:10C42000C6F7AC80782121CEF746EFA87798F1AB1C -:10C43000E7D212C3FB4E4D829FD9D39E94C083C2D4 -:10C44000E071462A0CBFF60842C238B26FA6897C5A -:10C450001F9AC995B49FA6C59202F666532405CFCC -:10C46000419B1466175EE0A971829D4ED2457C47C0 -:10C470006E9A6D0AC697CB4BA48BE0DCF3D0F685A1 -:10C48000BD707FA1C927A19FF68274760E4A7244BF -:10C490007C1FA059D99B3E07F6C9CDCE1947282449 -:10C4A0000271F007BA6F1721DF44CD96E1308E108C -:10C4B000EAC57B373912E1E7AF33C653FC2BE0F80E -:10C4C00020914EBC7F3C75C93117C8F502BEEF13F1 -:10C4D000D20A99DF98EFE7B686A3E980A72F75B750 -:10C4E000FE761AEDCF1E9130AEB5ECF3A637A6D18D -:10C4F000F1FABB658C67D5E190BF5232DD9FCDBBB1 -:10C50000D59C972DF788256228A7F9517C7C78C0A7 -:10C51000296A8CABCA0A3067A1E246FCB8284D20D4 -:10C52000786EC3F3A3214FF174973D5C03EF61EE86 -:10C53000FA93807E8783DDF30A304EFF995001E045 -:10C54000B78E0FD6FDFB1BD7872806B8F8FD6017FE -:10C550001CD659F1A7B99194823FDA193994722106 -:10C56000ECE3613BBE23D5C2F56F89FF4EAF8E2F42 -:10C57000D6B4C582772D9F5F8378D74FF16EFB10BD -:10C580007827292AEA09F63CE207F2B767F5E62A96 -:10C59000B4DD854FC97E3705D9B4C7CAD3409FB92A -:10C5A000F0F9EBF09E2CC00BDF796C904BC1EE776D -:10C5B000346495C2EF1D4D7BCC8DF878D6CDCE7FFF -:10C5C000A486543F94377557F954035EB7362AA5AD -:10C5D0005229BC6FEA2C85DF456A4DF23BCC23D251 -:10C5E000C520F897646EFFCF4B63F39D97968AE959 -:10C5F000CD3C7F9FA4CD84F9DF47F107E2050EDC37 -:10C60000CAF077458E13EF3DAF78A978F8507140A6 -:10C610003B1B7DA500B7ADB7D6A2DFA37AF921D722 -:10C62000E540E71EA702F868F38EBC770AE0FBCB73 -:10C6300076BCF7D5E4A952E718FAB37927A25FC907 -:10C64000266AB96014DD9976E4722907F045DB02A9 -:10C6500092A869C373974B943FEDF268B9022DEF2E -:10C66000D8F03CCB0FD3B608B4FC071B7EC1EA8FD1 -:10C67000D072E1973F7EB4E13F5879A9B605F20F39 -:10C680006CF835CB836E41F5984737FCEE72B82FC6 -:10C69000DD64F7CF02FFCE8FE9FCCBE9FC7B78BAF3 -:10C6A000278DF973F4F2BDF09DC27B1F4FADE54FAE -:10C6B000F2764F2729FF292FDF9FA4FF9FF376D122 -:10C6C00024ED0FF2768792B47F91B73B9CA4FC6572 -:10C6D0005EFE4A92FE7FC5DBF52669FF5BDEEED586 -:10C6E00024EDFFC0DB1D4952FE062F7FD3D2FF5B36 -:10C6F000BC7E1FFF9EE7697B43A37897D7CD5EF68C -:10C700002CF3B4A1FEBEB5BE12F1BF6902D33374DF -:10C710007CCF83784D9A2F52585C5591C2ECB85F0C -:10C72000F0FEAB97976C00BC5BF14B1BCA532A47DA -:10C73000F0F774B5E52CEE65C54BEC3EC88AE51202 -:10C74000BECFAEE3E32F2CF3DFC6E7D7CCE7FB5C2D -:10C750005A113F6FF195CE30C67B2AE6BC93D213B7 -:10C7600084EC346731F952B6BCC6390AE407952F18 -:10C77000C0375BDC7214EED1B72812963767D52824 -:10C7800050AE2912CA9F96AC1AE71CF4E764A07F4A -:10C79000A280C7ED352B12DEE397D2A762F9B4C7AA -:10C7A0006628C0479B497F3ABCCFA7AD94F0BCF642 -:10C7B000407D0D7E2F48FF281DF8F38174B6AE43EF -:10C7C0009E175DF08EAB749B88F26224C08F8E5BE7 -:10C7D000B4528CA8B4CA21658508F9079A99BCA2FD -:10C7E0007F9EF186771477DD5EF532C4EF34AD932A -:10C7F000F077B6E14F32C88312FE3BA5994A8649CD -:10C800005EDDC7FDB89ACF8971782512F1197FBF17 -:10C810003253E1E769B619F88E5971D82C9F0ADBBB -:10C82000CCEFD81458E493555E8DA8A7FCD150DF07 -:10C83000E1534CF9CFD3F87B167EE2077D66C5E362 -:10C840002B2E8750769D5FEBF2E5BF005F71521291 -:10C8500000800000000000001F8B080000000000A6 -:10C86000000BDD7D0B7854D5B5F03E67CE3C3349E7 -:10C8700066263393C97B1220040838811023BE2614 -:10C88000216044B403A2E2A338E11920C9044A2B71 -:10C8900056BC4C48C440B186DB8840810E2A8AF5DC -:10C8A000D1A1458D18EC808878ABBDD1D25ED4D6AD -:10C8B0008EC855501EA3B648BDB5FC7BADBD7732C2 -:10C8C000E724516CFDEEFDBE3FFDEC619FBDCF7EC8 -:10C8D000ACBDDE6BED3DE7CFD3BF2B09695D19BD64 -:10C8E00062A89E902D2B4DC314FA6CFD72DC4C5245 -:10C8F0004E4822D5E27F482264F54ADB3065182194 -:10C90000E779FB621B7DE92264AB129E4E9CF41911 -:10C9100051484B2121FB96C904CA4BB34C11236DDE -:10C92000B2F4D5DF5D3D1CCA4B641FF1F67DAF7DCF -:10C930003EBAD2330CC67F259D60BFFAA034ECD836 -:10C9400038FA6F25E809A41232A443391A3711FCCA -:10C950003B4FFF2B6CA7E592BEB25E1FB0D9AC84F3 -:10C960001490A476743E8AA6AC771DB6074BA17FBF -:10C9700005FBD7CE23AF99AE3FA95FA3C7A62AAFC9 -:10C98000969A4BC810FAA47305F8845D7264075D2B -:10C9900067EEF2BB261CCB2024E7A0A58DC01A3A77 -:10C9A0001E24C44D880EC6A6EB5624BF97E808691E -:10C9B0002B2CF349F479E8690B83539E15E16490BD -:10C9C0007C99D7D0A7510ED8A07FFAE787FEEFCD8C -:10C9D000B36C5F5B08C5A009E090BB9376984D8B64 -:10C9E000E1DC35FEA1749F28B8C904A8EF69F7D32C -:10C9F000F5EF947ACBB5508E460CAC3D2131F8BFA3 -:10CA00005DB2C4EB895FF110F29424F1FA91B5356F -:10CA1000B9B4BD621BA5F80899DD31BA5D7F39D480 -:10CA2000CBE27B3FA9A4EB83F17819E0F2C4015E6D -:10CA30001FBEB4BD86CE6797418C4FC2D07E972C67 -:10CA4000B372B8BCBDE632DA5F35FF3E9CBFC69F0D -:10CA50008BF3B9466727A4D97665BBF592BEF9B6C4 -:10CA6000D827B5B728849CF2C6D3E87691C6EDC71F -:10CA7000DC8476B57A6630007024C44702A309F9D5 -:10CA80006FC98BF822F64FBFBB2A9C435F9D39F8D4 -:10CA9000455A297D8674F18329147E8D5D4193BEAC -:10CAA00088C259EF0FE714F67DD7B87B1A095238C0 -:10CAB00085BACBF039C0778714F99FFACE64B88075 -:10CAC000F14EC5DE6C7A925635EA82EDD621D89EBB -:10CAD000B0FD1F787DE2FB534FBE79238C77DA1BC4 -:10CAE000774F01BC8C51B80CF09D68DFD4554500E0 -:10CAF000EFFF62F1AFB48D27E4263BA333A234FBF2 -:10CB0000A07DD4D461F3D17AB3BE23E0A3EDE9567E -:10CB100046E4CABEE72ADB506CAF7DAFA59FA8896B -:10CB2000644CA5781D6E507C3B0894C329636879DA -:10CB30005DA332AE854E6955D91FC69642F9192BB1 -:10CB400031D2726BC3014F29D091CF40287B21EBAA -:10CB50002E8966011DB7351A663E42E7138D2DF505 -:10CB6000CC2BEDEBBFC54E098FCE7FCDCB94CE2E17 -:10CB7000A24F7DD42EC1F7C314027468B6D37DA62C -:10CB800065739683840BA19D751DD0E31A7DB0B6A5 -:10CB90001ADA65C964071DD73C6C466D359D87C799 -:10CBA000254B3A9C47CD91F9B4BED56600CE467E62 -:10CBB0006B9FBD13E0F484E26B063A7CC26AB585D4 -:10CBC0006905E58D7EA05B6598330265A38E3447C9 -:10CBD000E9FC72CA48206AED9BE76F397FFCADCD56 -:10CBE00080F35D678E4EABA2FD5896CAB6301D6FBE -:10CBF0004DE3869EC9749C9F363EFB460B7DBFD697 -:10CC0000AD109887D5A9C40C69148FAFA573A4F390 -:10CC10007EAA256003FE997029E4215A6F196A20C3 -:10CC2000DE243E682DA5E524FE94E154FC66FAFD61 -:10CC3000497BF0D7363AFEB8D70F9BE07BCF7859C7 -:10CC400006B2892A6C9FD3CAD5FDD82E53F7E3A824 -:10CC500051D73BA7AAEBDD33D4F59EDBD4E5ECB985 -:10CC6000EA722DE0DB786848E75C41D7C1AA8825E5 -:10CC7000FEC94A9286F0790BE06F29967D001F73FA -:10CC8000E323C7E7D3FA1CE02774FE640C89ECA009 -:10CC9000FBB93FFF87DE3885B3D1D1ECB597F68776 -:10CCA000474E9EE91AD82FEB50C546687BEB1F4FC5 -:10CCB0007C09FD5B4952BB42808F3F0EFB0B7F1E00 -:10CCC0003A9F54F88717E0DDFCE7BB41EEBDA1F3C6 -:10CCD00001BC731A151CFFBE19DE88AE903527B44F -:10CCE0007D1A6F9F665AD7A31B439F7F5CB34497FF -:10CCF000D61FAE6ED22C015D52FC407941EA08CAC3 -:10CD00008B7B65520F7843C995407F36F880F29946 -:10CD1000890E03E2CDE71C7F28A6C950EFB6B13ECD -:10CD20000D5973CD40CFF71C64F87F8F81F5D3DBAD -:10CD30009F17074511047C52679755FD6CB0F1367B -:10CD4000BCECB2B3F2AE038E6B802E37CC708C0588 -:10CD50003C31CA2408FDA5E79AFC23E8FACCAF1AB7 -:10CD6000C212ED345D2107F40EDADE426E0FD07987 -:10CD70006C3A6409EBE87BF3BC7FB711E01B7636B5 -:10CD8000EF5DAB7CBF033E90A853108E6657876D56 -:10CD90006C295B4398CECF01FFA0FCB16A58A70D68 -:10CDA000F6D35CD581F2DB5CD6D10170DA3455461E -:10CDB0007DC23157467C36E745DF184ADFEBE7C9CD -:10CDC00036E8CF4105BB8176F293DC8E4000FAA5B0 -:10CDD00030972B18AA40BFB8423A4E0687ABD3B95A -:10CDE000FB0E89F69301FD8D61ED014E760EA75283 -:10CDF000BB17F1D3C9FBCD184ADB8F61FDB455F4E5 -:10CE0000F523F671532D89C0FCC4B8A29FDEFE89BC -:10CE10005F02BEAAFF0D851BDD2729DF8493BB6758 -:10CE20001189180B013E81E6ED48D756F210D08BE0 -:10CE300033B71AF028FBD0E6E9F218F8CE82E3E81F -:10CE4000E79108E071B6424C5738407F09201CB585 -:10CE5000F49A75A0E37A4A23BDFBA2A5DF2C85B422 -:10CE6000EB1CFDE938CBE9AC2E1E33003D6BE82509 -:10CE7000EB50E2FB80F45ABADE9672BA0CE04292B2 -:10CE8000DBEBBEBEACD345DF980C9B9549E50405B2 -:10CE90007DBE663C42FE6184B24464EFF921C0F776 -:10CEA000ED8C7F102AAF28B1EE1A6B9B68053A5DB6 -:10CEB0004210BFAA9F5B77CB6F687F6787196C2092 -:10CEC00057F20E75F4807C245DC1E1B00F5B94E0F5 -:10CED000CF5268FD96239904F8F61A339909F8ADF4 -:10CEE000703CD7CA97164E375E90739E7FFE29F42A -:10CEF000C1E850F7281BA5BD96F5B14326D7FFA280 -:10CF00009E4586A19E957BA0A7C50AE377F8DB4DD9 -:10CF100014BEE6D759FB302D8715805F4301D0E161 -:10CF2000FEBCF90827E56D23013C1DADF347A04C7D -:10CF3000DE3113E0BF3B9FB9ADDE0BFCC73DC50B37 -:10CF40007CE8DF81DE29BC3A38DD6BD7AF18FC41C5 -:10CF5000D027B4EFD7027C713F03C7EBE83E8E7E4B -:10CF6000D840D6D2CA1279767B21D0C51ACA7F6939 -:10CF7000ED6C9DB7E94752DFFE3C61AE8AD8C1EE49 -:10CF800058692241235DD73989042971E639DFAC1C -:10CF900002FE934F6212C8D9FC66AAF0025E2DB35E -:10CFA000906012BEE79E53B0FD13667FC4CEF9BFFA -:10CFB00089F2013DFB2779C21120754EC6A3407F3F -:10CFC000D13F69790FF80671D6F87BED8D22C05FED -:10CFD0002AF7E9784FF1F5EB290CF563E97F56392B -:10CFE000661CD3BFFD2F397C14933506FC52B1BEAD -:10CFF0007604F98B4D3999DCCE1461F2863490C8F1 -:10D000003089C105CBDFB3613987F25FE358D4FBC8 -:10D01000C34698671AB33F88DFEF75BA815E08028E -:10D0200039D744DA4DB41D623BA5B72CD26346BD57 -:10D03000F900F1023D5088D93F4841964500AE5B6A -:10D04000A8884EA603F12CB2B17D5296EBD05E1AA1 -:10D05000F59219E7A36F261133E84330370A6F655D -:10D06000198928606F2D3760BB229B17BF339066EC -:10D07000D4679FFAF2DD6CE0D39683541FBB08F6A9 -:10D0800059463E65B1A8E98F62287E17E7F8B17569 -:10D09000A50DF7B9D73E0B1EE6FB1C6F017991BFBA -:10D0A000CCA1DA5FD12EF75C0E098E4BEE3782FDF4 -:10D0B000E50E3D209152A8CFC7FAAD2BBD5FD37FBF -:10D0C000D120FD67211E0DDE7F2ED66F8D1DB65F30 -:10D0D0004741B12571C01EF0F6E9D75A38E72E5303 -:10D0E000F3E58BBAD4650117B3DEEF9C46616EFEA3 -:10D0F000BEECDB4EFBBBF888BA5D6DE1EFD1BEED57 -:10D100006B1F735E0FEDA9FDBD9DBEBDF4B8BA7D6A -:10D11000A0EA653BD0715F7B36BF2BCFA9DB69F7F7 -:10D12000473B5F3A2FD70D49F39A6832AAEA67D690 -:10D13000F59B97EBA6A4795DE551B70FB60C3CAF14 -:10D140006B4A8C5F392FD1EE3B9517D64EBB8EEBD9 -:10D150006B8D83C09DB5BF69E685F57B6BFD57B7C9 -:10D16000BB7DB9769C30F2875AC93FCE41EB67C38D -:10D170002BD017AD16D47BB5F812E1F26902E87333 -:10D18000F43935D53FC1419F954077F46978FC0F5C -:10D19000B7007F39F4F4C84CE0EB3920E7109ECC9F -:10D1A000AFB0ABC1837E8500A7532A4FDA805FEC16 -:10D1B000DA49BF4B63F34AD69F321A985D6123095F -:10D1C000A467A12F39884D62F638D377061B47DB59 -:10D1D000FFDDDC1E98B37C22799FD2E1B3065B951C -:10D1E00002F6D93609F58139357E5D2AC58F09EDFC -:10D1F00012FA8DE6DCF9BD71C0572E39E6ED8AD3FF -:10D20000F77322761F0CDBD443FC118A5799BA2599 -:10D210006577D3E703FBA9FEC3CB4B00DFAC7E2FC2 -:10D22000D81B753023DACF497D73990DF8E677ADB9 -:10D230007EE09B7533FC6FE17AFF4EB512DA6E1E0D -:10D240005B3A79AE739AC14BF58CBADBBC95A0F70B -:10D25000D445CD7E7C9A8862A1EBA8A3FA183C3312 -:10D260000D4431C3D3424CF0AC58C5F4AFB4CA80BE -:10D27000A18E8E5FD7FDD85FE1BB054A6C1FD32717 -:10D2800023B8EEBAEE57FF06FADA3C7FC000FC6224 -:10D29000D44E03D349393E8C8EAACBC00F92CB65B6 -:10D2A000317579DC2175F92D07C38B3D526414EC7F -:10D2B000CF1E2AE0C02E0E3F654479B17FAF11F733 -:10D2C00067F1C796EDE07F9AB8D88A7CFDE39F9B13 -:10D2D000D11FB5478E3E0DE5F0D3296857EF7B7B14 -:10D2E0004F8544CB8B7E912A43FD0B5FEA10CEB075 -:10D2F0001C3D7DBFF8E911DBD7D2F78BC7452B6CFE -:10D30000F4FDB32309E9817A253206D6F7EC3F74A0 -:10D31000D87FE27163E4218A0F1F3FFFD8D377D112 -:10D32000F13F7E3CC721D17DB914E4016D37E16145 -:10D330009305EC8C091F3F3904F8C5E29D46D5BA28 -:10D34000B63A24AE3778D300DF06F3271E5DF31814 -:10D350007E5F72FC08E2DB1E7D58B6C0FAD730FC57 -:10D36000D2B67FC4C1E48D98077C5748F7E7CC0953 -:10D37000CBED7E5A1EBE510DDF111175F949079391 -:10D38000EFB349D2FB42E8AF68B507F4D4ED04F53A -:10D390009992E37FBCA510F46823D31FB4F3788679 -:10D3A000CFE3E73FA7FD30FEA063FA335D31A5C7A9 -:10D3B000C51C8F5F9098FE4AFF96E550BC5D0C82BD -:10D3C000BFA8EFFD62CD3C44FF4B1C8C6F38B95DAC -:10D3D0009D785D87FBF1D1CAFA71C786F59FCF07AB -:10D3E0002B9B47D4E8FBCAF3372E399845BF6BD83F -:10D3F000E5423B51BC6F78FC25F7ADF4FDC99D8A31 -:10D400000F54D7869B1FFDF10468F7B82E0AF385E9 -:10D410007AF0479E8CBE9C06EDE66FB18FD525ED68 -:10D42000C3828DDF1F5193C40FBF293D08FA6DE001 -:10D43000F6ED73953D937300BF374A3E68B6387A70 -:10D44000C3F5D782AEB245E71B46EB2B1412D08D45 -:10D4500045D37B063C1B763D73309BD687F68EAF5B -:10D460008075AD9503D78C06FCDFA6473F96162E38 -:10D47000A7F97ED3EF6332FD7EED8DD6FA8815FBDA -:10D480003D00E5FD250FE9E2E067394EF9137B7FAA -:10D4900044A63479BCFB9E31E04FDCA3B7B6039EB3 -:10D4A000EF4965FB107E4A877C9EC4D83A2670BF40 -:10D4B000F1E23F751A14FA3C7E7C555A15A323E419 -:10D4C0002FC0949D747DF50F8F46BA5BB0514D27E8 -:10D4D000A29D98EFC288BA5E8B1F6919C2DF404ACD -:10D4E00092F14CDB2E636AD80074D5B09CF2E32431 -:10D4F000FDA7E1588701F426ED38A00112B1AF3A3B -:10D50000C44FE2C5F59AD97AA9CA6AA2EBFD08FE12 -:10D51000C5FCDE12D8E58B245C22593C92D47829D4 -:10D520003C174F27B5F0DC23C57EACE3FC0CFDEFC8 -:10D530004FA5203F3B698B3FFA53C0BF27F37C6167 -:10D540005A95CDFD7227BDB134077D9E01BA00FC0E -:10D55000B3B1F2A26ECACF297D7F7CCA807CBD2583 -:10D56000FA521AECD7C9A7CDB24CF7E5E35D19D54D -:10D57000E0CF3919FD4D1AACEBA3684635F8E50646 -:10D58000E3375A3E25E4F97BF0CF4B287FCEF08F6E -:10D59000C900F8B66580324E32339ACB9A07A07F25 -:10D5A000F19DD3D05CE605BEF15DAB0FE8F3D20C84 -:10D5B0002FBEAF93587FF0E7A7F59F1ECA7808F6F5 -:10D5C000FFD0BEE27490F39F126F3AF0DF29AEC035 -:10D5D0001519948F78AA7BFC3AF0FF4D21BE56FABC -:10D5E000CDFB3ADF0F6C14CE7309953BF02C0F1A6C -:10D5F000D05FD2E6C279CD51484CA1783A07E4E237 -:10D60000182C239CE76C9122AD741E73D7A9D739CF -:10D61000BFD3D8B7BFF4BF8584324620A02D49EDD3 -:10D6200068FF0B41FE51F82D3291580AED77D12356 -:10D63000EAEF169318CEA7E1C9F3C681E0F8570EBA -:10D64000C7292EFF4D192AFEA547FEB59804AE80C6 -:10D65000711773393BCFB80FE711BAF3CE1173A925 -:10D66000DE7066F95D23E666801F907D47364A8846 -:10D670007F8B6B482C8FCE6B71B7141B0D7AC061FA -:10D68000B63FA27FB28DB5BB85EB29F3283C40EEB7 -:10D690004F78520AA7523B669E899A60C03FF8BAFB -:10D6A000A03E9D96EB4907AEA791C4711EDFE3FB38 -:10D6B00007112980E75F0FB37D9B50BF5D07933A49 -:10D6C000B4AF221DF0EF33E2C3FDA3FA04313BFAFD -:10D6D000E307C0DB9F049FFA2DEA327924A95C049A -:10D6E000F0A4E5243837ED3E6FF40F00DF077AE54C -:10D6F0004964C4B4D1A49FBEFA2E87FF0337CCCFB0 -:10D7000002FABF1FF4B76CDE4125F04B22FC113149 -:10D7100013EDDF328EA8FC13542FC272C74F5EB9CF -:10D720007A632E211BF441F4F3CFD1050E4248EA6F -:10D73000842BD809F83A47F6E72BC807FCC568A739 -:10D740002E67FBF1E0D8E611CD03D8A762FE1BA43B -:10D75000684C067EF03C93EFA9E5097D3089BE9EBA -:10D76000E6FC2D7D7FFC600EE0CD3312FAD3374905 -:10D77000A44DA270F6D06D0139B0497AEF20C88D62 -:10D780004D577B492BAD2FDF3D6DC9CB68E35A7CEC -:10D79000109F68DC5DA56BB4E2FA999E99D2BC5DDE -:10D7A000A6F599B7978C05FAA0EBBE7D3A7DFF2BC5 -:10D7B000BEDF5956860F9E55E1C2A5E04FDD1F58CA -:10D7C000F232D0F5680BFAAD3229AC521DF86C0775 -:10D7D000FDD1435A2468F7401AEBDF25EB6E9F0614 -:10D7E000E5B1ACEC5821F91F42245E8FFD671AA900 -:10D7F000C9E060EF410FA6DDF977617D04F72D7375 -:10D80000627319F49739843D9D86582EF4F39AD8A3 -:10D81000EFEE2C19F8ED322E3797EDAACA74D0EF3F -:10D820005F3B6952800FBEE6117A5CCC0A7A1C1904 -:10D830005AC2DA73F9B4AC6C6226E0AF335FDDEE46 -:10D840008CDE9F3E0EF8FC1B3A8CB7FCC5EA4FB746 -:10D85000D376971AD83AB4FBF8A70CA6D785CE4949 -:10D86000249264B787669E45FD38744E51BD3FB91A -:10D87000D2442249767B43FDFEC9D0AE91F4AC067A -:10D88000BC6A8CA69048129E5F6A19785C81DFA101 -:10D89000733A121E87E89B0BFEC5D7F489D5F300B7 -:10D8A0009FF64AE8070A517B389C3CAF7319249CC9 -:10D8B00031D03CDDEAF7743DAA72D7E7D88E54C662 -:10D8C000D3609CD3B6789A9DAF0FDA09B97526223A -:10D8D00087F517617C8FC92FF0CF58997E3A0DF6E6 -:10D8E0005749A44D4FEDEB57D4437F8EA4759E9EB0 -:10D8F000692031DC97048E0B700B0F276473F727B8 -:10D90000062FC8F1EE7D0837812FC9F00B27C77BA2 -:10D910005A7B6232A5F9CC4ECBDAD21114F5F673EC -:10D92000FA0E5BD7827FD1AD9355F49E52DE4BFF4A -:10D93000C86E1E80E813FA2F53D7429CB9B7CCDBD0 -:10D94000F77E1F4E9B02F5E5A5ECFBC2CEF4FF5817 -:10D950000532887430BD5F49E4075293CA264DD919 -:10D960004ACBA393CA364DBD5353EFD1947359FBA1 -:10D9700093A9B17C9D8FDAB99D195314CA7F4E6665 -:10D98000C566514B94ACD3B9A7D4D072633993AB6D -:10D990004DDD920F7D6E1C7E4D3EA6EF597D71C30D -:10D9A0009C528043CF41E00F0D5D924DA274608D7B -:10D9B000EE8A6119BEF3267D1795F0BB86E87BF8E9 -:10D9C000DDA0FD97C848E76B4B8EB276D10F517E34 -:10D9D000AF6EABC3B8B888FBEA48C09F23F5C57DDE -:10D9E000059F3C9DE57F4966786D4BB68342D06FBD -:10D9F00092BF45B47F6774F7EF413D4859F6490B34 -:10DA0000E8A17F6AFC703CE865EF7079B0418A8CD0 -:10DA100080713793E0089077DF6D1CB64FA6EDDE7E -:10DA2000D5C7B7426C6B71E7A8290A6DF76E6A3CDF -:10DA30004FA23CA6D15981F07CD715DF0AF07CC9F2 -:10DA400079312BE7C5F3645A5ED259C7DA0F8B6F71 -:10DA500085F226E7B5AC3C3A9EA7B38189731DC217 -:10DA60007F876D607A9EED647C44CCAFABC8FF5D70 -:10DA700027ACA781C991AD546F34517E396BD14722 -:10DA80004FEDA07098F5C314E4633B4E5E3F85E90B -:10DA9000D5E18052017E53F687720EF9B5827A463F -:10DAA00016C83647DF7EA4E6F778510E8C6CDE058B -:10DAB000FA42E6AC529403A519FE0330AE78CECB01 -:10DAC000A64F0ACF034E1BE3CB3A19E3C89977A5BB -:10DAD000A25E75BF99AD87D20DEEAF95EFC71D4E13 -:10DAE00026B7EE7032BBED868C49D8CFDB927F93A0 -:10DAF00089C2FD6D3D099B81CF2EB4A01E7CEB76C3 -:10DB0000CA3728DFEEE4F3EE5C9F158138F8AD12DA -:10DB100009005F11FCA3D3EECF7224D9139D65B425 -:10DB20006CEDB31F3BA7F9B32C4E78BA6588970804 -:10DB3000BED459C8BE13F228B3958D9379FF888758 -:10DB4000601D290AF3FBCC9B59FC500BCAF5E9B8C0 -:10DB50007EE2F76781FFE0D8C22219FC41627FDED6 -:10DB60002AF2AF87F5DCC2FDE9629FC47E1E7032E7 -:10DB70007B788E8EEA0574BDFB5C415C3FD513C695 -:10DB800070BF13EA0907404627C19728F1F1F0FE5C -:10DB9000FF23383DFB6DC0A97139E517F205F00B85 -:10DBA0000EBF0D524C9FC9F805DAC1F01EE4CEA697 -:10DBB0008CE07F3893F25266DDD5887AA19857CAF7 -:10DBC0001DCFD5DE44FAD399566F3B0CFBE5EAD363 -:10DBD0002F7DC27FC8C779F76D13C60BDE35449120 -:10DBE0006FBE4BED9816E02F3CDE5DF1C3C5AF81F3 -:10DBF0001D27FA9DE0D2617F6B247F16AC6F0DDD8F -:10DC00007713CC7F9A01F57821573BED914D906FBA -:10DC1000D079432EE61B9C212CAF23BC3C05DB5D59 -:10DC20002A1F25E08F4C5C62C37833C513ACEFBC70 -:10DC3000B918F33E283E84CD504FF109F2E33ACBB8 -:10DC4000E882A0BF9B47623DD8B9689FDE6CC2FEE8 -:10DC500006C013E6DF1DCEF21A3A0B391E2E2C42F7 -:10DC60003C74B7323F2251FC63A625C979B78BF1CA -:10DC70008194F2F833FF0538BFCE8C7A29C8588CCE -:10DC8000C57464627F74FFCF3B597C0BF16CEE8FDF -:10DC900053791E99AF02E07A6F2AC3CB2D661627FF -:10DCA000DA42F560E48B1C7F45FE5A90EB79F17AFD -:10DCB000390DF4855457AF9FC00F763BFAA969FD23 -:10DCC000ECB8F41ED85DB3C3BA9811ECA8F649FEBF -:10DCD00078921D027F1067BB9DF355B291A0FFEEB5 -:10DCE00076F82E0DFAB7A4415CF176F81EFCA42B51 -:10DCF00026A9E2670530E6F8BEF969F97E819857F2 -:10DD0000C783FEE47144FFDAFEA81DE975B910CEA1 -:10DD1000B174B0075A74B88FDA79C637327F737C22 -:10DD20006301E29DE86FB079FE5997F8BE44E5E0E3 -:10DD3000FC89CCBE16F6CB3C6EFF92156AFB0CFC40 -:10DD400023BD655DFFB2D6DE83B8B8BA3DD35B5262 -:10DD50004A13068C977825D5FC05BC0683C3E46F6F -:10DD6000083721F71E34537EEA00335A42BCDD786F -:10DD7000670ACA31A7213202F06A9ACB8BFD6E8600 -:10DD8000FC1494ABCCEEFDEC35E1AF50DBBB214B8A -:10DD9000621BC02B646174747A6F2AD201191A9FB6 -:10DDA00005F95D67F61809E06F93142F06BA3E2D4A -:10DDB000F9EBB05D4B8A17E8E97DB907E11D020870 -:10DDC000D27985C2FF837945A12EB5FD7B9AFE5796 -:10DDD0004FF1FDB41CAF807E043F00FA47BDA89E02 -:10DDE000C55B9A641206BBEA5279F64294FF376724 -:10DDF0009387F0FD7BC56047093E4FDB1D901C0CEF -:10DE00006D805E1A38FC9AE4A3D8AE01F283008ECE -:10DE1000605F815F0B2A93FCB14DEB3EC6FCA4A66C -:10DE2000DDEA7D6EE8C303E9BC04DF25E105D271BC -:10DE300098F301C2FC14352C5E9CCACB29B53D98E1 -:10DE4000AF14E27E0BD7FEF864E027A9E551329BC0 -:10DE50003E43C7999E31A17BFB4B600FDB6B7BF28E -:10DE600000FD43DCAF27F659CCF392EEF5E8A7109E -:10DE7000FA49929D3962BACA5FB00ABF03BB15C6A0 -:10DE80008BC3AB2CD87E26D73670B946E51FF2D7A8 -:10DE9000791DC351FE817C02BE24EC5EE053C01F9D -:10DEA0004EB8AAB7009DB6B8AB1F74B9D878A8CF42 -:10DEB00083B174C9E0FE38011FD10EECDFAFF2B7B9 -:10DEC0003DC6F1D569E07C9730FFDAD2575DC2BF1D -:10DED0008671B4A5923713F0F5035D10FD680B4809 -:10DEE00018FD3B0BC17F459F0D9CCEE773BFD07CD7 -:10DEF000EE0F02FF6C72BC0FFCA4C9E54584E12F54 -:10DF0000D969ECCB8301FF4D0D89A5D2FE1AC1BFA3 -:10DF100004CFA8FABB26926078DF75DEA88A277640 -:10DF2000B275DFCEF7DF5E13D1017FD864667E2540 -:10DF3000C13726AC60FEA7F4B1FEC27B00CF5FD52F -:10DF4000A35FE2BFF9BE09384D71556F77D1F61660 -:10DF5000B0D3A0DD3D46E497C7A81CDEC5FD21D3A4 -:10DF6000C1FE5C191C0179DC44B1E527DBA7E2B9ED -:10DF7000768FB91EF0E74D97ACC2AFD52E9677835A -:10DF80007E22E4C729A86F53B63106F0ABA248C879 -:10DF9000433206FC53EFE9993FB7E9466B10FA8B21 -:10DFA000CB8CCFFC99F3B33FBB58DEE59F7BE515E7 -:10DFB000B7EF38FE88381DF86B92FDE41FF4B65FAA -:10DFC000CFF36309AE77C3429E87DD8BC732F2A3DE -:10DFD00094D200F2DD4BE56AE4478913562FC0A5C1 -:10DFE000F6E38685B08E4F675A08C4CBE672BFED64 -:10DFF0005948B873F5F969BF2E8E55BB7604F249BE -:10E00000D1FE6F3027577F7FEF1ECEC7F61036DF69 -:10E01000709B91F9D7F9FCF71C1F19013CA67A6D8A -:10E0200018F85C629799C93BAA87027FDDB37B78B9 -:10E0300004D6F39E9EE90B61CA7FD9F7C14DE00774 -:10E04000D9F34B970FF273428B3E1A03FAE39EE328 -:10E050003FFFD56FE1FD5EA30FECBD3DDCBFDE6091 -:10E060008815A3BECCF3121BD262C5E0F77981EF0D -:10E07000578385964B4179083ADCAEBE38187C0749 -:10E08000EF8F46985E7E94303C08AF63F14A0ADF1A -:10E090002C9847624D26C6D1605DB00FEFEF1D8D05 -:10E0A000F3DEA0E7EDEF63FADB515E3EFA7C19E6A2 -:10E0B000E99D091830AF36743FD317E7C8DE6DCB42 -:10E0C0008157BE9882FEC2799D6F605C23F4E305A0 -:10E0D00053A13EB468C575E42BFCFD205792FDD4D6 -:10E0E000A749221FEDE0FAA2688C8E7BBA7B848F51 -:10E0F00085ED3C18246AE2F99BC7287C61DE89BD66 -:10E100007A84FF85F60FEB05BB14E41BFAB593E3A5 -:10E110002A280FD47196AF2B9FD6C78BEFA4E3AFFD -:10E1200070046BDC497A62E8C52CE477EFDFF7799D -:10E130003EEA131D2C2E704CEF9F057462AF8919B7 -:10E140006627E95FB7B9B9DD61E47A23E583C9746D -:10E150002FEA2BAAD574269EB7BA19BDA5F2387E30 -:10E16000FF7A91BF7ABD11E427732941BF5EECB7F6 -:10E1700080C7D7261C4FEC837CA8866819C6EF0A97 -:10E1800056C4902E29BC63A0FF1FDB94CAF8095D1A -:10E1900026F433BF92A0DE3A5FC7F212E61BA91E37 -:10E1A000CCE438B6FF605326C2A16215D3FF12CF6C -:10E1B00048C817459CB18EB0EF9F6B7B2FACA3ED89 -:10E1C000EB764A6594B592BAB62ACC5B58B4A510E2 -:10E1D000F77F02E7BF738CFEE24D806FCFA522BEB2 -:10E1E000D1F150DF6E80DCACB1C8970C200FEB771B -:10E1F0004A642D498E8B6AF020A28EAB4C8832FE89 -:10E200000D728324E969420E81BC201AFD518D17DD -:10E210006195DC6BE77015FC1F21F6157290EAD151 -:10E220006B808E2BAA19BD25764908E746D2CCE231 -:10E23000405C0EF5CE87CBB10F744C6ECE37AEC7B7 -:10E24000E73677218EBB08E225E8FF4F18802F0EB6 -:10E250008617DB06C10B810F3FE3EB68384E6297F0 -:10E26000D3F11A569058E318F64C1D837299C9677A -:10E270001393CFF0B45C809CD6CA67AD3CD6CAE19C -:10E280004C0393B7020F92FDF2A08F4C5811D1317D -:10E29000FF6BAE0DF2F1C4BEDC90E17F227B7C9F70 -:10E2A000BE153A6232792F8272801459C1AF54552B -:10E2B000914BD71FA2FC1BE82E85C2693B7DBF9501 -:10E2C000EBE54372BD081F0FCFBBD12B0152668512 -:10E2D0007DEA413B3AE12268D70AF86E4DA5DF8D11 -:10E2E00085EF183DF67E6F226D96A4EFABF798513F -:10E2F0009E9C7D3E15F344A87C28B0D3FEDCEF50F5 -:10E30000FD9C964FEF4945F97E9AF37BA7F0579015 -:10E31000D5D8DF9BB0CF2EC0BAEA1CF0FB12694AF9 -:10E320000EB048A13736DA07F3D3F3FAC29E1B19B1 -:10E330009E1951CE9EB5C77F00653A1FCCEBFD0FED -:10E34000BEEFA1DD13CBEE82787EC0EA63500D965E -:10E3500081DE60D42DBB11FC4193752B1277D275F1 -:10E3600034E659315FB8A6E08F7FB899964FECD666 -:10E370001323ECFB8EEBD363F099E2F70C249F1789 -:10E3800046F4AAF3688B77AACB8D5175394492CEA7 -:10E39000AB51102CFF63D9150792F0E43377AA1321 -:10E3A000F7DF4B7C90EF4C74B7A50707E097E2F9D5 -:10E3B000F94ADF1507F4982FF6851BE9C06B00BDFD -:10E3C0006636E0C300DFED7233BFA8D1D87C1CF203 -:10E3D000CE8D2F187D2DF4AB83EEA02ED305F64AFB -:10E3E000E220ECA7B1E0E4189083D5057FC738D8C8 -:10E3F000D9BB890FE073D65C85FACDD94D662FD88D -:10E40000659DF956E6AF78518A484C7F9F3ABE0227 -:10E41000E29EB80612DA78F5097648829864DC5FE5 -:10E420006ABD7880CFF8D19EFA609AC5B68A7E57C9 -:10E43000BF91C9DB06D293067CA03693E15D48F715 -:10E44000A4C144FF59D8E61FD142E7BB3860C1F3ED -:10E4500031CA974A00F0EB5EE83249FF2FC8647278 -:10E46000A6D1143754C1F87F9F5BEB2AEAF36F19EA -:10E47000F4CCBFA57495C572E8A70B96CF413BA716 -:10E48000378EBC89E5252DB8B30EDFBFB4C988EB44 -:10E49000FB60AF8478FEC156B6FE051BCD5EC89FFB -:10E4A000BED2CEECD905F4BB81D77FD50958D7872A -:10E4B0005BEEF0817FFE43C2C609DB981FEA431B77 -:10E4C0008B77435BE8E7C3DD43508FA9DFB8702A41 -:10E4D000E68B6DD5F9408F207B53D1BFB360EBF74E -:10E4E0007F7B09F88FA6DF520E70B8D2BECC0DFE2E -:10E4F00012DA2E10617A31CBC375543E0A7478E576 -:10E5000097137BAE047D692BA5934296E70E7AFAAA -:10E5100081AD57A15EBA609AC50EEBF26ED9311982 -:10E52000E4C787D3B2655CCF5312B1011CECCBDDDD -:10E53000F07E81A40406C2A777DDCCCF565560F5E6 -:10E54000C5E0BBDFEB104F285DDD08F2B371AB1EF9 -:10E55000F5DE03D3DFFEC3CDCE3EBA5AA0EBB871D1 -:10E560004292DE13DA72ADC01312AB007B8AC14453 -:10E570004B5FC68215C5301F2D9D2D58D55CCCE252 -:10E5800055DF8CDEC8164A6FA3A8BCCE94985FE313 -:10E59000C2E9AD3EF31BD01BC975A8ECA8FE7C2DCB -:10E5A0008C7014FE7E938FF8775831AEEB9728DF8E -:10E5B0005D9FA9603FEB33D9B920E56F4B77BE4E25 -:10E5C000E1E3CE0CFE3013F41FE22F033CF2266C85 -:10E5D000D570E6C7CAF538B285E9CDA0DFC37E6F36 -:10E5E000709147D726F91DEECB64F611A5FF56E8CA -:10E5F000E7F45B7F3F08FBD3947F720C8B77FE05BB -:10E60000E383D66E1657B6FA121837D73B03887FC6 -:10E6100082AF877C4CEE68D7753893D97321670237 -:10E62000FBF98587D1A1F0B76F5E6E413FE9666760 -:10E63000C4CCFC0A610272696AA58EC5C5B89E7514 -:10E640002DF73F9ACA5F22100F2397B1FCADD7CBAD -:10E650005F523268F9B795937C786EAEFCE1F62292 -:10E6600058F7657A5E3F240CEBFE4F7F15D62FF5E9 -:10E67000E8BC40D753CB591E22A94F437FC9EBE5D5 -:10E68000EF3BE726CD3F404C5E2BC593E9D4C8490C -:10E69000CE9BBBEE32B3D79A845F9F7648B54CDFF2 -:10E6A000F5A6CF18CDFC212887CBD5F058EA31E06C -:10E6B000B82DEEAAA701CE575EC1F6E3A3A78C1131 -:10E6C000E07F1FF173285AF8EDCDE476E86D25AAB6 -:10E6D000F8BCD310CD07F9F8B1A4FE6E51BB0EE320 -:10E6E000E30BDB2512A1E37DF4F873F9C0C74FEC0F -:10E6F000782E7F76D27CB4DF89E72B991C5FB91F17 -:10E7000050EBD71DCC9F2BDA9DD94882A6217DEDF9 -:10E71000CFD47F81FEDCD9DDDC1FECF70F75821DC5 -:10E72000C4DB6BFB4B70FC90BA24F477087FE6D116 -:10E73000430F43E4A477FFCCDD857272DEA1784EEF -:10E74000E0FB763DEC1B5D8AB99D9507DBAFC1E828 -:10E75000711DC89FF17DFB76B47D483AC0D1D0646D -:10E7600055083B0F56027AFA5662F1013D19B23D47 -:10E7700056E05FCB4D6963E09CCFE766F6745AE8DC -:10E7800093EA6B79D925F8DD1D7200F3DB3E973BE8 -:10E79000F03CE01DBA66CC9BFE8CCBBB5C5B60D7CB -:10E7A0007CB44FA298474DDAD5F075B732F991A8ED -:10E7B00033A09C1270BE74F60FD04E1D607F3602DF -:10E7C000DE6457B277A59E42AE2FC7314E60AE24AD -:10E7D00036B0E75B2F09E37CC4FE84587322754B87 -:10E7E000A827437E4A8A03E3A161FE245607E98DE8 -:10E7F0000FA470BB9668E201946D85A19D9827B027 -:10E8000031C873B9DF1EED282EC7782AEA9FD02FB2 -:10E81000BC9F5DAAA03F1DDA19C67E3DBEF5E2256C -:10E82000CF179C2ADED75B068C3F4C857337B47DAF -:10E830001E9583A0FF119F5E75EE660BD59BC11ED2 -:10E8400013F15D9D1C2DF3A01DD21307FF88A1C2FB -:10E85000E405B99AA28B96C0BE69E3BDB45D21CB35 -:10E8600033C8B5835C11E76A9A964F0C40DE7AAFE5 -:10E870009EB197D9474D7756E1FB89DDCC7F1E6A63 -:10E8800037E2B9C0509784F1AAA6802162423F8640 -:10E89000B705F62B4CF530B01B3BED2CCFA9F36A36 -:10E8A0009B2F4C92FDD7F16D77A1FFDA8A71BA7F69 -:10E8B000367E79269502E0A2A4F854BA89C911EEF1 -:10E8C000DF76737C12FB2FE859C43B534B0385A0C2 -:10E8D00071EF76DFFE1BCBF86F901742C6DEF7951F -:10E8E000792164EFB570AECD04DA3CAF876951B9D8 -:10E8F000D97B4ECEECC5B8566F3DDC6F60EA92F81E -:10E90000F78BAE9DA4601E282F57AE83BCEEFBCDC7 -:10E9100044355EF2FC144DFF7ADABFD5CBDB876F4E -:10E92000BE66D2508CEFF272D78FFC747EF7EBD5B7 -:10E93000FD210A8A737DA6BEF12A72E4FBD65DD65C -:10E9400027BFA93C5FE671F5C9F17BDF9EDA7191C3 -:10E9500017E8EB33CCAB15F238E46479225ABEB534 -:10E96000D22309FD773288D8D533EBF03E80DEF82C -:10E970006EF7343FDC8B20E2BBA11501CCAF05F96B -:10E98000EF41F97FF2837D04F4CB8F50FF0F9D534D -:10E99000983F88EA1112C543537715FA3D216D144B -:10E9A000E4A6D8FF455C2E81AE0EF81DDA72D30EB8 -:10E9B0001DAD7FC7E35F87FD723B503BDF1D1E66C9 -:10E9C000BF874AAA37013F208F4804E4F6DA924F06 -:10E9D00051CF687A7ED2F8E4FCF0855D0FB0FCE29E -:10E9E0009DFA01D7BFC3A363F931CF3F83FECC8F1C -:10E9F00022EC584ABD12593301FC2AF532685AA458 -:10EA00003C527733CAFF99741D745D3FE27227B49C -:10EA1000F3FA30E4AB87E87F00B2CD81F9A8EF6F5D -:10EA20009E69B242BC2654327B09D283CDE287F57F -:10EA30006BE7D91B1FBED382FEC6B55DFA5AD09BC9 -:10EA40002AA89EF42B3ADF3CC7945A1FE54B39BAEB -:10EA50005D65DFB3425C7D60395C9DCDF6B14D0AEA -:10EA600084BF538EF98C24394FA7A08BE963DD1E38 -:10EA700083EA5E886E0FD3132F0BF74C049C7B51F7 -:10EA800089A7805E1C22FE4FC0CE2501AB17FA81FC -:10EA90001B1540CF72AEF4A23FD7E48CFFE822D41E -:10EAA0009B14B433841D71FA79E6FF1A9E157C1508 -:10EAB000F0B24217FFC977006E3F62E77589C2F86E -:10EAC0004DFEF5D6B1E0AF323BE33FA9F5627E0DD6 -:10EAD000FA1FD22F6FC37D78D1496C009F89E13A2C -:10EAE000454A9233826F4CEC3D17E3443F693567EA -:10EAF0002FC3E86E7D6042146D3B9FD1A7171CFAAF -:10EB0000FB0C055E0A7D413605D19EA99949ED436E -:10EB1000C0CBD5898332F8E59D3DA82F3646251C0C -:10EB2000A7B1E49798FFB698E759F5E63B2971CC71 -:10EB3000FF7ADF93C2E3036D4C6F253D68FF922798 -:10EB400019FCA9DCC4BCB03EBDBD05DB89FE0C3C94 -:10EB50009ED0C8FD351450587FDA23E209AB78FF08 -:10EB6000228F8D8D4B146F45B27F61C3342A49705B -:10EB70005EDE3498EF13E6C0E7404747EB65E6CF2B -:10EB80006E4F89C021CF0D528F1FFC8EE1B281CF15 -:10EB9000B358B3181EA5EF4F4C467FFFF383E5BB78 -:10EBA000B2FCD64DE347627E7879D72793013F4880 -:10EBB0002D417AA4FCE282F25DED595E1CEF5BCF41 -:10EBC00077F549FE87E83327CBAECE77F531B88BA2 -:10EBD00038A436CFF574564C617969F16D3B407EAF -:10EBE000761931DF6D6AD72B47C00F39D544A2188B -:10EBF00097D5E8012F665C3F348BAEE3CCA90FB606 -:10EC0000DD4320DFF9591FCB9F53CBF5C1F4788C3E -:10EC10004D24D97B157C1FBE2D3D5EF0DD10B78BDA -:10EC20003E96123F2E86F5EDD5D9063AA732314BE6 -:10EC3000E0DF20F91ADD03E76B887350B5F1425528 -:10EC40009CE95AB19E6F18B70A802F7980B895C297 -:10EC5000F3B01489B100926750C5AD147BF16071B7 -:10EC6000AB18D63F331CEBEFED17B762F9016D7BA4 -:10EC700033BDA0A737B8128F3EEA85FE0CD84FDB14 -:10EC8000F32911C83B6FE3F06FB8F0B8D5C2AC01FF -:10EC9000E256DBB91EF67E891C3350B86E276CFE37 -:10ECA000E16E11BF92D11E4DDC9727E68FF567EE1E -:10ECB0001B857E9F39222EF522F387CDE1F1A7F740 -:10ECC000A71763BED660709ED3AEF6EFDFC5E17CBA -:10ECD000D65C857EF51FFCFB34F433CD077FFC90BA -:10ECE000BE730984FBE5BCEDECBCB977A714F1B2A7 -:10ECF000F88849461DCF26C3FBC5941D6E06161A1B -:10ED0000A65873317D2D51A8D17A6F1B2D53E55D27 -:10ED100059A3843DB4DDF62329E807BBD7E9C5F93B -:10ED2000DEDBC6E2C4E175526418EB17EFF10AB7F7 -:10ED3000C97EE8E7A7594C5EFF2A8BF921BC9AFBF4 -:10ED400001DAF43CDECBC76B21720C9EB2C49EF795 -:10ED5000DA94DA81F400D15F9BBED95405F0CE631A -:10ED6000F7859C35F867A29FD8518CF702B5A53678 -:10ED7000B7D7B27AA4D9B3E64400EB2F57986249CB -:10ED8000BC0E98EFFA2CA6A768E13CAF435DD6C64F -:10ED900069B4E7A0E690E0F0AC21FDCF09ADCF6209 -:10EDA00072ECECDA42BE2F3E8C7BB4E9BD6F1602EA -:10EDB000BEAF61F7FEB4E432B8C979EC5964AFC1B3 -:10EDC000FBD9889DEB6384CDBFE872A704F4D066BD -:10EDD0006778FBAFCE5B3BDF17B28A197CED8C5EA8 -:10EDE000DBD64811062F36EF0BF56FBC25F8D2B7EE -:10EDF000C417DF977C8FC60AF13BE40BE1FBF448B4 -:10EE00007747492487E53FDA906FCEE6F6EA512E40 -:10EE1000AF36D717A5413C73CEF1D5787FCFC4EB81 -:10EE2000AD38FFA617CD688F35AE88E7033E6BE19E -:10EE300008B355043F9521EF98B07B5FDAD5F139DF -:10EE40006DDC7585239000F9D2541D2F86F8CF0311 -:10EE5000F2FBBB5E617C0DE563D38AC4A3E02F0E99 -:10EE600038829F43BB9377BE3D59F2E2E7C8DFCEBD -:10EE7000EC1D8EE7FD66B7A9CF4F9175EAF81F69C3 -:10EE800077B073629DEAF7705E48F55DBF7820D376 -:10EE90004F36188223407FBCF20A96EF706AA14C6D -:10EEA000603F4F99098FB30B3EEB2B4E9603CEEC90 -:10EEB000C1E41D6D0770E6F99DA27D23EC2BDDCF2B -:10EEC00006BEAFA79EB9B818F6F5E4AE8B8B615FAE -:10EED00037E83BFC4017275C414F36C597639302E8 -:10EEE000A8DF897CD60BC5B7E183CEEB7F470E97B1 -:10EEF00067FF737218FE92FD1E2FFE9DE59D86BB77 -:10EF0000D979D13E7FDB4778EFD59973B2047C780D -:10EF1000B0FE5EF730BCF7984818FC1C15D571FCA4 -:10EF2000AEE20B99803E27F458EDFCAFE2F09B99DE -:10EF3000EDFF15E8A3C23F5BCFFB36453E63FAF217 -:10EF40002312FA5F4DDE70DA04B48FE68DD3215FB1 -:10EF5000F9159E6720DD920DEC8C858FB460FDE97C -:10EF6000AE39582F9B6231B0A71A693D94575FA6FE -:10EF7000CE4FD6EF2E8B25DBAF741EBF00BB24C552 -:10EF80009930007E36817E4CA7D8A4303F7593938C -:10EF9000A07FA4BC4B6DEF89F8EBE600BB5765730F -:10EFA000B784F72BB90DC1C25CD8574D1C765EB63D -:10EFB000BF0DF04EC4C3A7B8FC0BB259BC3C1FE058 -:10EFC000D494CDE617D78BF373EAF37D87F6DD880B -:10EFD0007AD05F49207DE0BCB1882A4E3E9F9FBF1A -:10EFE0009CCFCF5F027F8E69F87372B921296F2C95 -:10EFF0003650FC3F296F2CF9BBE4BCB1988AAF7541 -:10F00000F0F3094B313E1DA278BE7C6C1F1E3610FA -:10F01000FEB731F13E9E4FD96944BF5803CF170D5B -:10F02000D51F457B2304E75D183DB2BC6A7EEF40E7 -:10F0300003B5E3306F36AACE2BFD69F6B72B0F442C -:10F04000BBC1FCDD8F0A7EC0E951AC4BACA3A15B18 -:10F0500062F4A399A7D67ED5FAAD85FD79A17C6926 -:10F06000CFB7BCEE6FCA975EF996F8523FFFFFD05C -:10F07000449AEF5BF0FF9FF076B8C125D82E317C23 -:10F080009DACB3FA597C51C7F20FB47157EF648C41 -:10F09000270A7FABE9595D645521B6C7786AE3DE7C -:10F0A00054CC07A8F7D6A39EAD8D332E22BB26C322 -:10F0B00016FC95BC86E7AAFED5B8FEE9ECDEB87E64 -:10F0C000E1378CEBFF35FB1BC4195FB27E96114C08 -:10F0D000C293EA52AAB0970E9E77A5CB61FB9EC25F -:10F0E000F33F4C4A98D893BE1FECBB941C16677F25 -:10F0F00089E70BDD9F9A82E7E83D06768EC023B351 -:10F10000BCA677A8B69FE30239C0F6F167CFDF440B -:10F11000204FF067FA289E6B0F375A7D20BF84BFBF -:10F1200048F4DFCCFD98174A3F4539FFBB7CA33438 -:10F1300047FA6671B28D14064974A5A583C1BE1B3A -:10F140008CAF5C9E13A8CC41BEE51F83F1860BE417 -:10F150004729E5945F837CDE6DF482BD60E2E75D64 -:10F16000C8BA2C95BD3DE7FE3C945BA7CCCC7E1085 -:10F17000E772C4FA0383C2FB9FD3EFF6B902D3014F -:10F180004F8E55F931AFFFDE542657128FB3FC1E58 -:10F19000EDF914AD3C11E72BC47873C5FEFC1FF1EB -:10F1A000D325023EFF223FA5F215FD2B83C653FB5C -:10F1B0007D1F66F79154F7F8799C09CF2B887985E4 -:10F1C0007A585E5C0B9F5F2FBC38FF3F98E35F056A -:10F1D000FB70F22D9309E297E5E58C7F3605ACE8EC -:10F1E000FF6F8AB27C98A61504ED7C710ED59D192F -:10F1F0005C07F878EFDB56BC07B4A96B7B7B11E6A4 -:10F20000090451AF3BFD167B7FD01DEC80FE432BE4 -:10F21000E2AA3843C5F9CF56D796E37CD14E771A88 -:10F22000D5E77B7E99C3EC6FF1FC452F7CA95D424D -:10F23000BF3B59CFF2B0434EBFAD0AF303981F3B1B -:10F24000C5DB83FEE7A6DD282408268542FD5DB9DF -:10F2500088374DBBABCAF05C7FD45C86F7C1BC631A -:10F2600045FBEAE49DD9111DF37B3F06EB4A2D8F48 -:10F270005C0DFA65011D07FCD827775D5D86FE40B1 -:10F280000DDD097AEB3DD779AB29D22AF5D1E3061A -:10F290003D938F42AE3D08CA2CE647F0FCBEEE69B6 -:10F2A000649EB5AF6C75AAF31E67664F7A10E6F3DD -:10F2B000608EC2E3D32C1E5E68A2D667517F3C2CC1 -:10F2C000E4F1F0693C8F81844D7DF90B455F1F0FA0 -:10F2D00017F31365110F4F39C7F4DB229B01F1229D -:10F2E000B59DF10D42F102F4EBCB123D13E13CD59B -:10F2F000D0CED86500AF74003FE691C67F7411C4CC -:10F300001D3294CB20EEB06DF9D8FD2627F88F7A08 -:10F310002E87ADF176D8AAC1B47467060E039E108D -:10F32000A5B904F0BFFAF77A966FB82605E57D67B0 -:10F330007E03E61B9E7EDBA83A47A37D86C92A0F83 -:10F34000F8898ADA7F877EFFD4DDD28079A419A07C -:10F35000F48F67EDC1EF94DADE13AE043FCA7D127D -:10F36000BB4B91CE5EF280FDAFC8A077CCE962E7DF -:10F37000B1E774D8AB4DC84F251637B9CC897C524C -:10F3800059738D0CF699D242F0DE324B2EF35B0F9F -:10F39000EBB4C9B0EFBFFE5237603CEC6F1CBF212D -:10F3A0007F0DC0D5684C1C8490BD88E389BCB5C175 -:10F3B000EE0317F248ABC7F6D35FB93CEAD5E335A5 -:10F3C000783CD87702BF053EFF5A4F500FFBB5641B -:10F3D000C2735A02AFDB441EFE97CC8F5BC0F36250 -:10F3E0008EAEFD9F31EC3E3F110789B07B25F5F1D4 -:10F3F000D53908AFF8156158F76EBBDC548AFEAFFB -:10F4000026EC670DBB7FACA07DC8AACA7278DA086B -:10F4100080E0E89EC5054097618A07C306C0832344 -:10F42000392CFF48599382FBA6ACC79B968962771B -:10F43000E3BE290FB0FD793387AD47C461859FF2E4 -:10F44000604EB004F26B7BCF572DB7B0F355FCDCA8 -:10F450006EEAF2B79F82734BDBB8BF78FF8BA3F0E5 -:10F460007710CEAE5124F01B9DB5D71580BD372E39 -:10F4700097E94BA94A0FB15993F1733FE6BD16EDD9 -:10F4800065F97B0ABFCF4859E3DC0EF02CCD08624A -:10F490007EEFE56D31FC0981176DC730BE46F52260 -:10F4A0003CC7FCD1F392D08B54F250D86B5A3BEC52 -:10F4B000AADC6F572E7E9D9E343D572D072FD8BE58 -:10F4C000226A3BB3B7BDB01BB57684E6FBC1F41F1F -:10F4D000E20FABF25BE6E57A851E87F23D9BF346D1 -:10F4E00091F7D27B0E9944CC709E017209C4FD58ED -:10F4F00090FFB351B2F8404FD2E6FDF4E6E390E658 -:10F50000E12C1FA4F92276BF44F3C5F014794166BB -:10F51000C80B49CE3F4D65793D66C80BA1EF5B072F -:10F520003DB7EC6D81F13BEFB68973CBCCCF5E4B31 -:10F53000789CE1213CD79CB82117CFC94CAC65FE23 -:10F540003B47C020035E3EFB0F9D1FF86E82D22D0D -:10F55000E8578EA1FE2CD0B7CCB41EF24D7ACF2D39 -:10F56000D79101CF2D8BBC2411A7CD1EBE4102F92E -:10F57000D39B2F12EA3BCF0CE3762EF1A27FB83754 -:10F580007FE9BB04D7592DF88C49BD7F697ED62E03 -:10F590006DA601F50CB71C7C1CE3789B7BCC78BF77 -:10F5A000446E11EE5B6B6504EFB3759476A0FFB506 -:10F5B00025C3BF39D7D5873F627E64235BFF1938E7 -:10F5C000AF25F58D7B66E117F9A04F55771B191E06 -:10F5D0006AE6B1B9F7DE143A0E7DFE2297EDBF4F11 -:10F5E000A3DF8AE72F047D713E2CC61F6C9D021F8E -:10F5F000BF4E6FD7E257B89AEFCFBBE608CB3B526E -:10F60000E3D7FE95B5E38E515E726065009F67CCCF -:10F61000525407F941E6C42CE08077E6CDBF0EEEE8 -:10F62000D338939AC887FB385AF2A77E07EEDF38A3 -:10F63000E34ABC0BE5CEBC7F63E561896D703FC7D3 -:10F64000CFF3145686B1B2097965CBB9EBC2A57870 -:10F65000AFD5EA1E904FE59A3C13CD3D02900F893D -:10F66000F71E58D97E66F27C5452C3F577882CD1A8 -:10F67000726B56990FF208ACC4BBBB07EA738DECF2 -:10F68000BE01C2F29F5A8715B27C058EEF2497FB0C -:10F690009F493C0CF8DB5A68C7EF7BF9F56E238F66 -:10F6A0003BB1F1DF78869D131379B684D8F240EF31 -:10F6B000B17A89AA2CEEE1208A2D0FCEDDB70ABFE0 -:10F6C0001E2F1FB1044FE426E9456F4CBAA3147FE7 -:10F6D0008FE3D9BB86C27AAF32A8EF33EEE5A7F944 -:10F6E0008C1F9EE1F7FE7558829F423F4752664D40 -:10F6F00086AB5467665419ECA8A73DAE037EE4E2DE -:10F7000078619FC1E667AF0948F03B18E2DE3D57DC -:10F7100050417F000976EA407EBA8E05309FAFC126 -:10F7200094C857287E7D610CFE03E8E16CDD7B3FC9 -:10F73000C03860F61BEF42FEC51BFA8E8969202F88 -:10F740000AF97D0ED4F00B3B41DE15A0DDD77B4FCF -:10F75000E73009F9C3D419ECFCE9141255D0FF6263 -:10F7600063E7A1269717FA5AE9785379FEC6E4238E -:10F770008134F0034CBE29AEB0784B4249CE97108D -:10F780004FE2D17B93E9E06A6F5299C0FDBEEAF285 -:10F79000B53E75F93B955F0E4F2EA7533B206F3C4E -:10F7A000F0AD389E270E5F426C6C5D2C2FF0E7DCCD -:10F7B0006E1BE521A602C85B744A61B00B463D97FB -:10F7C0008D7194E72A0996DD3B4D0F9992D7BF5E64 -:10F7D00066715AEEE716BFE3037520579F7DCB8D08 -:10F7E000F0725B65E4A7E001077CABC8315980BFCC -:10F7F000EB389F17E7AF27A599F0FED5D625ECFE8D -:10F800007FEDFD93AD7ADB3ED8C7D613740D749CA3 -:10F8100047520D31390DF68B1083B38F1F0BFC81CE -:10F82000FEAE00BC1FCF7E678962F9D0E4FBBF5BF0 -:10F830005D6CAEAD772B3C3EC77EEFA1A4F7F71F02 -:10F8400028D9D1F6A05312A413161FCB13EB248A88 -:10F850001FDA67115166E7ACDCBC2CEEBD24A44A6C -:10F86000C1FB7224D1AE05CB0FF27652F72B7F038A -:10F87000FC189A46D7439F4BF2189F78587E632313 -:10F88000E28935E8053CF1A50C7CEEE7B63C46374D -:10F8900093D22A3D9037D09AE5F3805E25E023DEAF -:10F8A0008B7E45BD18CF973170BF4B78BF517E6EB0 -:10F8B000585BBF388FE96DBDE3EA69BFD6AF18D793 -:10F8C000A51EB7F7BBBC81BF13EF457BFC79A60A29 -:10F8D000A03306B7293C5F9594A8F35348A5CFC43D -:10F8E000F8BD3A1FE52A694516D0E7D5A6C6EE3819 -:10F8F000FDFE158E2757C9C1BF40BCE19559C5070C -:10F90000803E6BE18279DACF3524B61A90E54C550A -:10F91000F067F621C82FDAF2E83A9A74C1E10E5A7C -:10F920003EA5EF18BAA410E9EB9EBCF1FDE727F065 -:10F93000B0779E14FF60DF05FE69E72DF0805C174D -:10F94000C5C4BCAD24864F0F61F9D0547EB1BC67ED -:10F950006F5EDFBA28724E36350F05F9FE4A4B1836 -:10F96000F9CF55F69F60FED78305C1CD30AF99170B -:10F970007D82F7DD104F1DEA5B74BE3FFDBF9C2FFB -:10F98000A5AB2C782FF440A1EFF5CB033E6150E5F9 -:10F99000018BF969E958CC2344D83D4613BBB7A382 -:10F9A0007E179A61F5C1798D10E4B79663FC0BF36D -:10F9B00085F770BB2C2CB1BCDD7EFAE2E0F9C2EC1D -:10F9C0005C7FA38DDD6723EE45FA7E91B8EF86CD8F -:10F9D0009BF22F7EDF0D963BEBBC68FFF5EA8DF3C3 -:10F9E000981E7A65B1A50DEE0FEC7FEF0DF3EF9148 -:10F9F000E78C5EAE27A2FCEE4C65E39C32B3FCF4D0 -:10FA0000243E4E2477DF7D5C1BF44C1FFC635E219B -:10FA1000BB5F44F655C07E6C86B895AEBF1FF284BE -:10FA20002BF867C0EB79A5FE7CF8898D3906E6676F -:10FA3000A478B5A587409A5BF32370DFE4D5A4F9D9 -:10FA4000B03C04F1EABFA1FDCC519FB07B28FBF094 -:10FA5000EA0386576164825F47A72F6604CF40FBA5 -:10FA60004E7BF49DA67288331A11FE228F504BBF35 -:10FA700049F339A667F371C23DB7743E9F0F349FB7 -:10FA80000BC1EF643CCA240C8F07C373C8D74F1D4A -:10FA9000DB87E7E92468C81F9F84EFAB7DEDBA21BF -:10FAA00003CC5B67C57DBFF166168F09A5303D1598 -:10FAB000E232596EF03FB1F16F5CC3F0E346B3112F -:10FAC000F1655A7723C65F480D8BA7F8E8FF603EC3 -:10FAD00033897F12FC54C6F5B66978FE72C6547538 -:10FAE000BC65A6E92A8CEFDC40983FEDC6197AD5B3 -:10FAF000EF000A38CC24EB3E817C8E999ADFFFD34D -:10FB0000C2451BAF11F068ADFC6ABA1F91DF1BD76D -:10FB100019FE0DE33ABE7C963F7741719D03FA04CE -:10FB20009EBB7FD9B560CB124A17C37F5A8AF7664E -:10FB30004F722F7C643D2D3FB67924965F76DFBAF5 -:10FB4000EC0DA8DF568CE51AF99359788F79C5CD5D -:10FB500053E0BEF10366D68FC712EC84DF8FF08CC2 -:10FB6000291A0B26598D2181EDAEB9A8711CE4C16B -:10FB7000D45858F9B5B2FF1A8BE5225E1EFBC24875 -:10FB8000281F903E9935505C6854891483DF89AAF8 -:10FB900071B0F653C73E9E0D7E829A6A561EE5AB43 -:10FBA0005A3304EAE54F670D248F67E573FB89EB51 -:10FBB0005B014EEFCFF9DF6B83735E01ABE483FC37 -:10FBC000FE40E57BEC9E2B13CB2308F8CB14B80743 -:10FBD000B1DACFFC7B13AD2D59C0FFAE0B1ACAC1F1 -:10FBE0008F6BB316B6C17DFFE99555E361BF275210 -:10FBF000350CE41FA5ABD9F94057177F929F867A41 -:10FC0000889AAE04DE4E13F454A3A61BCA0FEAD999 -:10FC10003EAAE981F6DB88FD5EAA964BBDFC5D43FA -:10FC2000B75A7C1C54EE13351FEC954FABA3889745 -:10FC3000B9849DE3D90A78CAE8F7DF607E06B9C7C0 -:10FC40000BEF0B24DF484CAC18447F10F303B5874F -:10FC50008CED3F2FF85384BEC86660B3B9615C5623 -:10FC60004FBFF3C38F7A8979D1F17F8CF059CDE6FC -:10FC7000B3556AE6BF13C1F47261F73689F576A908 -:10FC8000D75B6161E7D13D84F21DF4DD978DFCAA5D -:10FC90007987B89C9D610ADC67A46BB8C13E07F701 -:10FCA000F926127E06F49BD72CC108CC472787F78C -:10FCB000C625F89D073FC693E93E6ECF4FD217C4C5 -:10FCC000BCB4F0681A84AF6AE7AD8543DFFEF4A0E8 -:10FCD0007E96C57F0FAE775D9AF5B4F2FBE01365B3 -:10FCE00046559EE86B752C0F56CCEB358994A09C3D -:10FCF000942C1847EDF53B69F9DB20E7D2847C169C -:10FD0000F3BC839F8BFA5C667CEF0E5D0CE7595069 -:10FD1000DB630638C6F38BD87DC67CFEAD95616C7F -:10FD20006790A501E3C4F17C59E457A8F65BDC4F6A -:10FD300026E25C02AE4E833717F33D35F09C6D3200 -:10FD40000E1C57D5C65F07692751F8E538FAC35925 -:10FD5000C4CBAED5FAE1AE66FEA96BB91F6E622DBB -:10FD600083BF63792ADA6D8EF2371432BAEFFE64FC -:10FD7000B11F3DCEE049C423253E1EFC04AF8F7F5A -:10FD80000CE344E29E422D7CCE0D029FC1E861B09F -:10FD9000F91FB104BE80714F493D789F59C263E39A -:10FDA000CE836021D08BDD565805FE05CA57CF9F04 -:10FDB000076313AAE8FE2D770565B853EF2612985E -:10FDC00004B9D78EDAA09EF9E709FA8797723B71DA -:10FDD0001297EF9F3EC9CEC1D7F8473C7819E89FEC -:10FDE00087F424E2853C6E069F4FB7E850AE2F782B -:10FDF000759C07F4F3F739BE0DDF28AB7E2F6E44F8 -:10FE0000C4A2BA2F63D44E87AA3C3A9AAD6A7F51F6 -:10FE10005791AABE2C3652553FEED05855797CCF1B -:10FE20000455FB8B8F54ABCA97C4A7A8DA5F7A7CC2 -:10FE3000BAAA7C79E216F57D1F617F4F891BEECB54 -:10FE400067F0B8F2DC6C55FB8FD3261F02BA9BBB60 -:10FE50008EE56D5791C5AAEF17EB1A301F9A7430D3 -:10FE60003DA699FE8F9F3757304F8CEAEF1900B7A8 -:10FE70008D6A3DA7BE7BFD6AE0B5FDEE99D0E83303 -:10FE80005AFD65B8B30EAE69269717B0F3EDE4627C -:10FE90007231FFFD10EDBEE2B9FD4F0FEBD08E5871 -:10FEA000FA2AD3EF973EC5F2E18AC9B0743CCF7508 -:10FEB00048472212DC5FD0BCE132A94F8FD1C2C5C6 -:10FEC000E851EFB3D9ABDEE79412F53EA7FAD4FBC5 -:10FED0009C5EA9DE67BB5FBDCF19B5EA7D7605D410 -:10FEE000FB9C3953BDCF5941F53EE7D4ABF739AF51 -:10FEF00059BDCF05CBD5FB5A185EA4AA177C734811 -:10FF0000FB52D5FB56295A413925991BA8C77B1BA3 -:10FF10008675FC7040FC10FB1FA6FF63F4DC8CF9B7 -:10FF2000F5F3E9FE437EFD5FC9BA83108AD2E24150 -:10FF300053D77A8CAB7D533CB8BB80EBA762FF2FC5 -:10FF4000503FA5F2B015F802D5635617807D3D9C51 -:10FF5000DB1D8181F518C1B792F58664BB7A307ECE -:10FF6000D64F4E723B7B5039A9B1B3DF82EC26D419 -:10FF7000C7D7A15FEB668ED79FC1AB4BC0AFFA343A -:10FF8000CAFFB7E8442AE9BCDE8279D371DEB28CBD -:10FF9000423FC8AD24A6C77802646EEAF0DE4BCCBF -:10FFA000C3ACA37A393CE770FD601EF7937C610C0B -:10FFB000EE2C60FE9102378C9BDBC3CE6FBD967139 -:10FFC00041F73BFC0EFE49DBFDA92010857E6A4C03 -:10FFD000DE650FD057FBB9FF894C65F99F44098C4A -:10FFE0004EBE4FB1AF1F16377D410A06D1CECE327D -:10FFF000F9C0CE1E95434C5920DF3C91228853FD19 -:020000022000DC -:10000000BA4016712A942B23398E3C951D5D6A47A0 -:1000100078451C1827F886E3FEA6C07F10F041B48F -:10002000FFBAF51A0CD125CC9FC07EBFE430DF9714 -:10003000876F34C6C02E1378742465D6419717FD98 -:10004000E187012E336FBA7A3594A5FD19DEA574C8 -:100050007E67EAE268DF53F81F81F11B4C14FE74DF -:1000600089A7F282C3D301190219DC4919183DD0BE -:100070007924319F8912C70B4BF03D1867BFDC9381 -:10008000EF0378283D78FE8E5851B921A70C03FB69 -:1000900003051CAA53F26EC3FB748D461FD817D5F7 -:1000A00012DBD76319B7CF82D8E23C39E08EE9542E -:1000B000F33E03E335D8EA0AB28AC0AFC6E70D3F84 -:1000C000028A70F7960EE827E7F3861C128CEFDEA3 -:1000D0002D89DFCBC1F273613BC6338CF26787E1B8 -:1000E000F7FD12A3658CF76DB1D0AE29BEFF27874F -:1000F000B7B8EF9CBE67F97916F6BD67838CF1A39C -:10010000FF07EF54F02D0080000000001F8B080057 -:1001100000000000000BE57D097C94D5B5F8FDE6F4 -:100120009B2DC924992C6421102609598010266121 -:10013000111471588251034E006531E24C12206453 -:100140008100DAC64ACD40D854A8A122A2A20E0846 -:10015000141568B008A8D1372C527CDA8AADB52EB8 -:100160009597002A3B3168A57DBEFA3FE7DC7B33DB -:10017000F37D244F7CCBEFD7F7FBC7D777B9DFDD13 -:10018000CF39F7DCB3DD3BEE31AF2E6043187B7E19 -:100190009ECDA92A8C7999C3CC54C6CA99CBCC32AE -:1001A00018FB7CF4BFBFD1EA602CD2E1B13A8632B1 -:1001B000764F9C21F58334067F9E012591908C8C8F -:1001C000632C99B1EFF1EFA6AB53C67C8CF5C074EC -:1001D000B5810D636C929DD1DF2C180BDB4D662E23 -:1001E000138E7307F39870DC3F5C34BB5814A4067D -:1001F000282F606C2AF3D1F7E9CC4FE95D2C40F54C -:10020000EF66AD947F3F22AF773DCCAFE489EC4CF5 -:10021000066D2E795B8761F9DF2D9E549C6F8DD51D -:10022000734F3C7CBFD0DBF36522D467EB60322395 -:100230007E78BE25383FA8F7591F779603F2E3ACC6 -:100240008E21F9E98C1D34B0CA661B948DEB41F305 -:1002500067467BE6A4815DF5B3943118FF58475497 -:100260001E1B8479972D19D67F335F3EBBD9555D10 -:100270008CEB2C546D2C1EE07FCCA1FA2D3066D176 -:10028000686F4F5C17FC45FAE2199BE852D9C3002E -:10029000EFDF2E812F50EFB7F9AABF11EA4DDC3006 -:1002A000FE0CB62F1E3D795934AC7FFC77AD43026E -:1002B0009016F5329D68CDE1637C0FFFFB866D1CC7 -:1002C0001703E9AD49BB8D0CE67F6B5F6D79712E2D -:1002D000E4ADC1FC44660C96C3B807100EB18CD5D2 -:1002E000FF257FD4E190768C35A96E58F7AD8EC886 -:1002F000F82F0640B63FEBFF3DCE5B2D8DF6D8BA0A -:1003000087EFB70DCE51874D304FC55582F861400C -:100310006F6EA0A33223733577D1EEE94C45D00F31 -:10032000603781B1DBC55C3B8A2F9B2FC17A57397F -:100330003CA5D8CFC2099FCFC4F53123FBDD608037 -:10034000DBBCDF03DCA0FC4403403E9BB1530D56F5 -:10035000E6B230F645839DF2A71B92283DDBE0A074 -:10036000F47C430E955F6C7052FED70EF72CECB701 -:100370006CD557464F2E632BC3241EF93C16093A01 -:100380005ED97BD89F9D30DECA774D94AF6C6E1AD4 -:100390001F01E9A2DE279646C0F7452F284EFC5ED6 -:1003A000DDE232DB603EB30E7B5620F9CC79B775C7 -:1003B00022808FD55E519807B690A5AF7B11D2D918 -:1003C000D03F9D4A40F87DD9309CE673A6C145F3E5 -:1003D00071B5B41D8983F6E71A8A287FD4E1BE1F60 -:1003E000E7E7625F99B1FE841D6DC614282F74295A -:1003F0002E06E38E7231BF1FF0B7C1E4F120DD6C31 -:1004000048B63A1B213F7AE0A467EE8571DFE9E345 -:1004100069C4F677C49617C6C1F789C3BD46AC3721 -:10042000F53BC6302FE9FB87F7358747ADC0CB8555 -:10043000371582D385BD036EBF01FA7BF3A8CA547A -:100440009857C71503CDABE3A3703F5382F516BE93 -:10045000A2125D2F1C68F6B334CC0F4864B9B84EB5 -:10046000E80CD69FA338583DD0DFB99D3F4D423CA4 -:10047000C8F1CFC536FFF513E8AFFD338373338D75 -:10048000DCFCC55390DFD72BC9F930E42E9AD83461 -:10049000DAA7AC2E6212D0D73C33F3F0BC6700E68B -:1004A000CF85B37BDC901FB62B650CEE231CCF9160 -:1004B0001DE46B59BB9E487FC0111C6F7BF3AC4F92 -:1004C0009E82FC05BFC1678A8694355F7C0DC6F3AA -:1004D0006DB139B7329CA7311CE7F98889CFCBB70A -:1004E00035DCB9D581FDF9890F40B919CB6B5E7E3A -:1004F000B227AEE37580C170C8BFBE3682F8DDEBAF -:1005000026E7F17A6CF70CEFEF57BFB8FFC47E4CCB -:10051000D7D416DC0F69C0114BF0AEF8E5DCFED87D -:100520007E400AA007F8E34BFB9440581E6303D7B4 -:100530001D589A0CE30DDAD866E80969FE16A51174 -:10054000D301BD8B8EAAD0FF118783E63178479AFD -:100550009A82DBB5A7FF939B3208700AE2AFBFC057 -:100560005FEEBAAFC6F4847467CFE6853150DE5FC4 -:10057000693EBB240DE9FCC3020FC1AF89FA79A51E -:1005800065F21FEF62B80E5FB215E7ED353BB7A617 -:10059000F1E59A207F614FC6A687618D7B0DBE4D28 -:1005A00088775F99D5B915F1EEF63D89F8AE85FAF1 -:1005B0003EC8D7E6FBA2AE87F2DACFFA3A81A2585C -:1005C000EF676F2E4278CCDBF3F8F89E50EFC2480D -:1005D000E604126095AF5C1E8FED586FC690255CE7 -:1005E000D8D3983003DA3D923B6628D2975B6DA64C -:1005F00071D87C3ECE13B01DAD0032D60AC0491072 -:10060000A40AF51E81CFF83DB625E6400A0BE26745 -:100610007ECB923423B41FE2B13A55DC3769BEE495 -:100620003A58EF7B5865049D7FA7717F269B45BF95 -:10063000F6C9A9EE1F71FE99C57926FB7BC2CC7C59 -:1006400061D04F6FF8AE40BA11FB85F2ADC057EAEA -:10065000217D46CC1FC6BD82FB14DABB900FA7C01C -:10066000219D0FF34C79C242E7C0B58E7FC9645B10 -:10067000A500DDCE0FE77C6C8C387FA7C535BED1D9 -:100680000AEB7D35DC634C83716689739F199D0E7F -:10069000E4EFFE709729AD079EA3EDA9B806385781 -:1006A000C3303F4FF5F449C8A073353B1AF9BEF586 -:1006B000DACED577C35DD1D8FE5AEBEBF9EDA26F58 -:1006C0000C2C1FE860D1E316E2178DC897615D8D91 -:1006D00091C3ACC837D86143CD1138676FE42D3B67 -:1006E000FB5B1459407CA591B12EE1F526EC7F0F00 -:1006F000F09B009C131EE003A3AEB4AB9CDE8F1DE9 -:100700008A1E827C96B922817E6EBA62609E907348 -:1007100050DF0FE02B0FE1389A45304FC8B9EA623D -:100720003166DCB7CC16FB5F5BB798FF4881BF91A1 -:100730001D1F45301BC203BEDBBA5FD71B625DFFC6 -:1007400082EB82745DA6DB85F0BFF16BBB11D777BE -:10075000A3B12415E51A98F778FC3EEA6B8376DEA0 -:10076000DF856BF2D73AFFFB14E633E07EFCCAEC80 -:10077000C7FDD882C723C0B1656EAE1FF7FD5E33DB -:10078000CFFBA2A01CF0D812C97CC8475A4A12FC61 -:10079000BE34E487508E7CA307E3E561A2FDF40438 -:1007A0006ADFD30220457E7057B8E8BFEE9D8158BE -:1007B000BE2485F848A3C9BF2A1DFBFFB94A7CF8AF -:1007C00023C1B7D7C504EE52A1DF755F25301CE702 -:1007D000231648998FE3548613DFBDC160B8A7C4C0 -:1007E00086F55CC9B100EFBDFF50E99C58970F79C1 -:1007F0001BF1ED69CDF07D5D892B391CFB2949305A -:10080000D07C545647DFD378BB4F4CBCDE0C81AF55 -:100810008F057E605FD3BEF74C8C3022DDAE492B56 -:10082000F3A5911CE44A5660BE4F556432E49B33F5 -:10083000AA6E49237A697A82F8D7348103D91F36A0 -:10084000B00E43B999FF4D9FB5350CF17947655806 -:100850001B9CACECA3CAA5910E687F87470D5880FE -:100860009FB22985AE4EB92E1DC775D1B8B5CDFD45 -:10087000324E85D0739905F804F4FF52986725ED40 -:10088000D3FDF954BE1F849AEF613F9DA8C8DC8553 -:10089000FB8A55C4111D3063A01CF1F066BB95E4C2 -:1008A000D4EEE8A111E13F48D029E26531C73BC849 -:1008B0006B946F9CD6DF8FED9F3371BAF1ED0E23F1 -:1008C000BC164DB2129E3BA6856FB240F93D826FB9 -:1008D000354E0B772950AFF1158BDF807C40E1F46A -:1008E000E07B2392FAAD31F37CCDCB99444F7BCDA5 -:1008F000FE17B661F99B61440F35517CDC9AD752E3 -:1009000004BDB9D296E3B86F58880E6AC21DD1549F -:10091000FEAF7144272EAB673BC203E8AE0EE588FD -:100920001A73202B06E07B5CD0D5716883F8F3D571 -:1009300045D2BC69CB43DED3D87B33E2D363E6E553 -:10094000EC672A951FB7F3F18FAFE6E3973E5AFDA8 -:100950002E03BC1D778F4F9E05F3385E174172E35F -:100960005FEAD580390AF59EF6F55950EFE2E29339 -:10097000C336C0FC5B977E9A8AF451BAB4B618DBD2 -:1009800095562D9E88E76677FBB2B406367FC83E43 -:100990007E3FCD15C0F55C48F31C423A989FDB3A88 -:1009A0001BE5E78BE663CFA2FE1115E73982DF2F47 -:1009B000BDFAE5362E57B767E17930CFC8E9439ED7 -:1009C000ABF305FDDD97EE7997CE89F0C04C3C3F47 -:1009D00022728F717EB7F8DAF8FCD996AD7B1518C4 -:1009E000A73ABC651EA5AA3F0FFB39A704A2940C29 -:1009F000829F07F7D3797B200AE1EE317079AE7AD6 -:100A0000BB765DF867847955E33FA05D75B3EA0A6C -:100A1000435C33BF19E75FCDCCC1FA69413C413F2C -:100A2000842766FBCBCC0700FE552FF42B40FDA19D -:100A30003A66FF2F6EA07AD04EEE13F5EABC5CCF7B -:100A4000D5F3E1EB3B2FE8FFBCA4FF6982FEC5F8BC -:100A5000175F4DA4F1CF95F8B310FE171551EF05B0 -:100A60000BAF07D460C479FE9AD3D37A93CF80FCBE -:100A7000C7F77346F45C1DD73C0CE122F910CCC1DA -:100A80006780FAE776A5507DC9B7989B316C57BD52 -:100A90002B793397CF843E8B1385FA552FF1FE3196 -:100AA0008FFBF0EC8B29623C2E4FEBF1A75F6F447C -:100AB000BA81E4A9F5927F47CA7DEE4C2A01F86716 -:100AC0006F306BEA5F8C34DFE3827EFBF9B5DF6564 -:100AD000FF89E95CFFEBA3C35B4FB5FD8005F7D34E -:100AE000F38CF6AB7E5EA9A2DD8B2F76E249E5782A -:100AF000033150D28783CBE12684F3C79DF8B83702 -:100B000005F86A35C2203D089FBDF99E14E4FF1721 -:100B1000318FE7420CE473510EE2F0967909673D9C -:100B20009D2DFD78764A2BB4BF45C007109A88F4F6 -:100B3000D829BF98401FC9457DB472F0A94CD45341 -:100B4000EBFAC151D0B99ED91BF2ADB89FE66CCC7F -:100B5000B79685E0A171FBE0A30E80F3F9ED46277F -:100B6000B2E546A3FF17284F376E579B7D8CCAAD61 -:100B700008DFF3B683BFC77AB337C614A0BC2CDB3B -:100B8000CFD9705FBF8A10B80FD8AEC5C3C0666D2D -:100B90007ED07E6D7E32F286A13FBE5D7E409B1F81 -:100BA0007C549B67ED802DC0836AE578DA37DC7969 -:100BB000D40178EAE3579DF8A98F6DD2E409285F44 -:100BC0006C549D9950DE67B1FBB681903FBD719624 -:100BD00013D15CA9FAE63D0038ACFC74FC513C0F23 -:100BE000CFB1E60F27001E66B7AC351B1DB86E2DC2 -:100BF000DDEE35087A7D51213A98EBD7965FBDAF8F -:100C000097083CB29C507AD2E31DC6BDD30513AA07 -:100C1000A95F34F8141C9995C540E800B311CD6B59 -:100C2000CD28B7FDF0383E2E0FDA5C0E848777387A -:100C30002FBBBE7E2C3B3918FEB1FAFDF1386FEFA9 -:100C4000230AC90DDEDF641FC673A06DF7F45B29AC -:100C5000BDB388D62FED79735A944024E4EDC31DBB -:100C6000FB5BA1DD2CBFE2C479972DB304F919FC1D -:100C7000AF62B56E1EEB42CA61FE73F61FF89B02AF -:100C8000FD576ED4B69B0B7C16F957D596EF2DA168 -:100C9000DFA5DE787DCB2615D73D4BCEDF378AE149 -:100CA000BAAEE75559BC906F4E6106CE8D5B7BB8EE -:100CB000D7A763BB75BC1DB04B2FAEB7D66676E029 -:100CC0007A6BAD2C1001F3381A6976D9E1FBE50D8A -:100CD0009164479B6D0179B28052165680ED9CD18C -:100CE000D8EE8BF7B83DAD368EE3BBF63985F4A868 -:100CF0005A347E62FE799E9FCB02B40EA41357E84D -:100D0000FAFCDA3C6BE2FA578D317000E151C55ABA -:100D1000B9FE04787449F801BC6A609D1FC5A2BC85 -:100D2000A56BCF9C1E1C77BE8DCB4FF3F77F6F0951 -:100D30002D977AA0D4533786733DF1B92C77388E2E -:100D4000B35C713D6985792E17F2B56F6D18D1EFDF -:100D50008C4DFCBC0139360BE1B26E6DB213E58CE3 -:100D600019209787E1BE991B4EF540DE25BB4C3B11 -:100D7000C8D59BD3B07E7300CF8D758FA7911C0D06 -:100D8000F22FC1A57D4D987FB38272309763D6ADA7 -:100D9000CD2639FC75794EADE1725717723195B396 -:100DA000442EC77F824B099183CFF4F07C901EB212 -:100DB000AE8AA5AE643C772A26990D68AF6295711C -:100DC000D7243F6C1572643BAC1FD7714A711F3139 -:100DD00084C8A39FE37900E30C1BE3DA26EA39B168 -:100DE0005E85A1E4E19B70BCF506078ED7096F977D -:100DF0002B0BE7716A6D5801D2D9B031DC5E743CBF -:100E00009FF3F78821CCE587F4A238672E225F0F85 -:100E10004993C281FEA09F5385DC5E1D39C44D7687 -:100E20003A38AB89CFEBD7F177D14F85D9FDAF37C2 -:100E300076311F091F368ECB0BA716289BF9BC00F5 -:100E4000BF901FF6CB30B2EF9D12E78F8433D0CD29 -:100E500050B2D30B7EB556D0CB5A13A703DF5CAE8E -:100E60003F05E985113DAC137AD60C815FB686CB80 -:100E7000B5402F1CCE6B9205BDC0DC911E0A1D5CD7 -:100E8000CEBE467D09F01E9BD1E36ABD49E29B19A7 -:100E9000FD43D1BED21DBE6BF7EDDCEB83F3B3EAAD -:100EA000D78F4731A877C6D894E084F6355B97474B -:100EB000B9203D6DF445D961FC337EB5C8DF05BC72 -:100EC0006FCF907665974D01FE330FFFE94079E7CC -:100ED0009189B8BEBF6E35D99125CCDF6E21FD69F1 -:100EE000DE9EB9246743BE8DE7577EA5627EBFD6DE -:100EF0007E5EF5ABC7131C046F5F8A2109D3400ADD -:100F00008374DE1693338076E90F54270C037273D3 -:100F1000FB0A9C9FBE3DCEE30AE07B7EB3EA3547E9 -:100F20005F5D3E5FF097F97B1EF90AED7AF375F687 -:100F3000FA4AE1B7D0DBEB6FCA888CFF020DD3D73A -:100F4000B1EB500E02B83803B86F613E994426DC0D -:100F5000DEDBF8C213796D282F6C79274AC90DDAC8 -:100F6000EBA53FA3A3B9FCB9D71CDDEFC78BC26EBD -:100F70001BC417E75B8EFD0AF20050D0795A630A52 -:100F800044DD00F0A8D964223E53B3F3F96D4F213C -:100F90009D7D6CA1F3BC7AE75B1F5E8FF2EE6E5312 -:100FA0007C315F864D4908E269BE83DBC9245EAAB5 -:100FB0007EF396D931907F5F1C1BC44FF5EE03661C -:100FC00036F06A388E6D3E606EB57581A7E6B6F173 -:100FD00064277AE15B33EE83336F2A2C31EDEAF636 -:100FE000959BDE8A42790CE184E792C45727FE7410 -:100FF000F5A1FF89AF0DA17A76D42BBAC39F03CF99 -:101000000ED4CBF745B21818BFF2138BBF18F1BA44 -:101010006B5114AEE34B631DA7F3679627A05C5793 -:1010200069F225D829E5DF2B9FBD8FE86F8E529797 -:1010300060CF25FA4E3690CCE04BC6F5CDDA780776 -:10104000AD6F36F310FD553EA3BAFD907E63644547 -:10105000BBBBD8276F6770BEF9E566402AACEF4B83 -:10106000B4DB20DFF8832AF4DC05747EDF27D6CAE0 -:10107000D842CA7F23E4B68D1952DE056922445F47 -:101080009CBF65E531C4CFD9DEAE449C27C0C127E3 -:10109000E0A57C0FFDAAEF172672FC3087719868D7 -:1010A00007E7E858FC8EF58F995C68F70E6927F41E -:1010B000393EFEBD627C987738EAAB5F2670B95D39 -:1010C000BFBE6F3BF9003BC642E9ABBB7DBFE5212C -:1010D000A2ABAF3FE07C659EBFA488CA8F9902890E -:1010E00058EE3F304521BE606181AEF6F51693D8CB -:1010F000D7DA7298A7510985EF9B5C0E9D0D725748 -:1011000020641F07E9C61CFC4EEBFEA558472BF9CF -:10111000D3A41F6E8EE007FA75EBF9C3211D7F90F3 -:10112000EDD9C6AEFD4041BEE0A3716BE03C413954 -:10113000A3E6630B9D1B353B4D6E84CFB91D873EE7 -:101140009C817A68B3DCC75A7EABDFC7952F0FED61 -:10115000721F9F5B9DDFF53E86EF5DEEE3D50AF1E2 -:10116000B7FF2EBF85938EEC06DDEDD739DDF0DBC2 -:101170000B3A787EC372A36FC042BBB70FE147073B -:1011800057094F3DFF5C9EE120F8EAF927FC7DC03E -:1011900042E028E127E993310F8DD349C7924E25CC -:1011A0001D77D2A97EBD5A38EACB77237F82F9B862 -:1011B0005F3571FB598B42F236B43B923284F6A90B -:1011C0008B8E3FD67424253E34EFD7E59B75F55DB5 -:1011D000BABC5B57DFA3CBD769EAD7EC3F64E6FA2A -:1011E000414053CF527F1BE91957CB117EEEF7D9FF -:1011F000F395D98774D1ABDD8C7CD1B494F92251AD -:10120000DE7D432579F792A33D0AE592E5615C6EA8 -:10121000BB6417F9189E6FEF615E817C517E6F0F82 -:10122000E376924BEEF6A898103DBDAD458D427B1E -:101230006CAB9F1575654721CB28C0B5957557CE0A -:10124000E5B742D5965A8FF6D026D50964C22A96BC -:101250004C8DA2B887968CDBA7C1F7596FAB143EB3 -:1012600070299CDB1598CF65C4B883728E42769A3C -:10127000F9D68F847595B7F0F8838AD55AFCCEB627 -:101280004D890E3890EF68E304E6A05E9781FA9EE0 -:10129000F67B155B4DF456A5DB171E61A7D5EF0B4A -:1012A000775F112F90CFF2853D86FC1C0B05BF2E7A -:1012B00054736F9F06F0BF74546516C877B4A86C5A -:1012C00005AE778742FE1E7408E07E9B07FB12E79F -:1012D00023E1731EF74D76F772C9F9573E1BF600EE -:1012E000D2C9DE4FF39E86F4FCDE8FB35EC7FCBE30 -:1012F0003FA77ECAAEAE3FF6CDBFCD443E7CE94DA2 -:101300000B43FABEF4E66F53D12E78E9350BE9CBE7 -:1013100097965AB8BDF9CD483FFA232FF5E6726E7D -:10132000E31BDFE6B5D2B9BB8CF0F5405F33979B8A -:101330005AFEFD38DAAB3B5A6055284FBC1941FBC9 -:1013400067FE6B61E40FBFF4C6B7C342E326FEBB82 -:10135000EB91FEEE4B916CDACB48B742AE9FFFFAB1 -:1013600088E7D19F5BBBE780B91CCAC7FECB7FE48F -:1013700021FFBCF43297932E9A5A9F455BE38A2D46 -:10138000CE5F9A92D13E079DF564ACCFD6BA49B8EC -:101390004FAE860B87C3258003AE0BE052897CBF1E -:1013A0003B783C83F0E8F1CF088FAF66727E761D04 -:1013B00043FF6F102E0AF723B444FAAD0AAD9F7FA6 -:1013C0007FF3DB3CE4373FB4DED7FF69F1FFBFB307 -:1013D000DE8FFF69F1CBE9DDDBD741F3D4D3FDD557 -:1013E00074BDEF2794DF15E9A4F95EE37EFFDBFF10 -:1013F00067F84ECCFCBF8AEFB705BE23EDE857BCBB -:10140000F4C67FA4B21FB1EE61FF47D72DE5F531D9 -:10141000AAF3683ED47F87357FE04C23E9A34BB91C -:10142000A33C5391FA1BE94763193FA7C75AAB493D -:10143000DE1CDB6B0DC9C58DAC80FC10BE5E2AF9CD -:101440006328F802E0F0DBA47C3FF9938C815E8B8B -:10145000203F26A596E2B3F47AE3D8F00945288F19 -:101460001E5A02F3827E0E451AECE82B1ED74B0D56 -:1014700058F2286DC3F448EA6D47516E1967D3EAF4 -:101480004FB7E9F4A15B1CDAF222F6723CFACF8A7C -:10149000724DCC0FF3198FF543F4C6D199765AE704 -:1014A0002DAC6999DDF6E3E1F49880D3D570F8CFDF -:1014B000E176159C849E6C14F5F57033DA1E3E8639 -:1014C000ED8C0CF45EBE5ED297A5DEFB43F0644269 -:1014D0009F368AA1257C8DBDB89F34A45F828B8402 -:1014E000FB8F85B7C4931EEE12BE126E7A3CCC46BB -:1014F00063548F20FC7B19F38DB8EF6E1472FC38A7 -:10150000630CCFF73AA6BA693FFA399D7FED34A252 -:101510007C32DA1643F19ACCD13B06E54C1431BF4C -:101520004F61AC6C78CC3005D69B62643E0BE89B77 -:10153000E843233BEA4346FFD2341C87DB6B7B1B2B -:10154000B95D1A76B72FBC80EABBCC90F73E3687E0 -:10155000B9A0BE378539155E9F45C752381A533139 -:101560002E0B526CE78DE6FD7A13997F29C727E190 -:10157000A52FA6E9D4AFCB10CBDB4715507B9F81BD -:10158000B7771921ED93C1EDEBEDCB2DA47F785703 -:10159000F6CE42FE513C466B378EC8E2766699FE27 -:1015A00024CB41A96A7026A15C5CB6AC1FE9436AF2 -:1015B000B8BBF615B4F7EF8A207AF4AEB87BC25008 -:1015C0009CDFAE38274EEFECC4DDC378FDE9F7FDB4 -:1015D00009BE7BB687D1F7A7B23C473201AE67158B -:1015E000C7CC57E043D91D87CC493084A7B9E40262 -:1015F000DAFF26FA76FF1EFD8C13A7A8547F22E39C -:10160000718F6C5904F9A327F8BE3226417F13402D -:10161000D9C0F2B6307BEA0298BF57D87BFF20F6DC -:101620008B1ACE3C2F23BF5AD13B2B1DBE4F605D82 -:10163000C701DBB3B89D461DA36C44FF509FB1DCCE -:101640001E2FEB633FD86F8280C76799DCEE24F3CF -:101650000057AA5FB1CAD296817ACF2A53201BE3E2 -:10166000A773C6B4E13A8BD3D9F80D08F7FB55B68A -:1016700099E6DBEE253B77648E03F1E00192A6F854 -:10168000C2A63407DABDDA463707D03FD0F6649AEF -:10169000B3D14158A6781CA967B58D0EF445BB7C23 -:1016A0007B3EF7331CB7B746A27E586EB3527C8E92 -:1016B0008CEB9965E7FBBC4F63EB9AEB50EF7C5CDE -:1016C000756E86FCACC7B9DFE5739BD5AFA0BEB61F -:1016D0008EEF53B65A1BC7C3EC4EB2F794378D3614 -:1016E000A37E59617399719DC9D99EEF715DEC3BE1 -:1016F00080DF308CE364B419BC4D5E8A3351A36043 -:10170000DFE13E313AA250EFD5C701CD17713F322C -:10171000FF5298C79A05702C8B76EC427A39519F0C -:101720004176CF9B91EE107E18C788FE09636B321D -:10173000CEE7D54C4E8FC5B1F62C1BD1731843386C -:10174000B4990093906F5B1E66403F5BF1524ED799 -:10175000B0CFAC4668FF909185A3DFE043D1BE7463 -:1017600089D1BD09F2BDACCC18198B74954F74FDAD -:10177000688EE7335CDFE99FB3E1480FE5ABD792B2 -:101780007F45D205331E1B1707E39CDE9A56807CEB -:1017900053D2D1A33963FA6485D2C31485E800D249 -:1017A0000319440F93FA6279F19840DF85B9A88F45 -:1017B000D630179EEF49CC897242076B27FF6387AB -:1017C000CDEC403B97E427926F005E5DD684201DF0 -:1017D0006C83F3DE68626C7B8395D2171BECCC08BC -:1017E0003C6E474312E5773538286D6EC8A1EF2F60 -:1017F000373829BFA76138E5F736B828BFBFA188B9 -:10180000D2D71ADCF45DF225800BF121C957243FB1 -:101810002AB799DBD01F29F9929E6E660278471588 -:10182000507BE27B92DFE13A0C05417E24F19BAED6 -:10183000B87D4969C8C75AA723FE0BD5F33BF7A16A -:101840005E5E6973929ECE38DFEB007A45B8A49A4B -:10185000D97EB4BB362E70B5AD4C0BC2FFAE4A85F7 -:101860001943E8EAEEBA30660C3937EEA98FD1E4B5 -:101870004BEBFFF85622F43F2EDE332D0BE671FCC6 -:10188000C12F9EF9337C7FEEC1B399886F98C7D67C -:101890002770DCC5E19DF388C5FC3213F9A3FA4833 -:1018A0003B08FC215ECA18DF6FCF3DF877DADF6DA9 -:1018B000F51607CAC39F209E00AE7F11782AABB7EA -:1018C00010FCBCCB4FEEDC87FB7CB199F85CD932C5 -:1018D000B10F57013C43FCBB279219D923409AA66C -:1018E00078F5133F370722A0FF130ADFBF0A080568 -:1018F000A518F7B7EAB71FE1FE57EA8F92FFDC633E -:10190000B505480EF099CE87F6A7D41FA17AACB5DD -:10191000570CDA11E91C43BE3FC46576C0BA91A6E4 -:10192000116F6539075932FA4D9A143B6E990AF1D5 -:10193000BD629542FE498CBB9902729F2F4B253C9C -:10194000B6641A695FF5CC6242AE6BA2F349D26B02 -:10195000C56A6887FBA229DF3C3B840F9789EFE5C6 -:1019600039064AE5F726EC17FB5B953F0DE5899EA6 -:10197000589E8B69C134846F4FDB78A31282FF8736 -:10198000B3F8F82D997CFC9EB8D9E0FF1ECE4937FC -:10199000CFCA45FCF0F34B8E539653B002E338CBDD -:1019A000568F46EECB1A4DCEA478A8F718F643EB27 -:1019B000B17379C1CAE3956BBA393FA4FDEC34FE2B -:1019C0007304AD9BECBA55BB5EDA8571FC559F5A2A -:1019D00008BF558344FC54AE7FD86432346AEDD5D9 -:1019E000E35EFA2C8AFC0F7B785C25A4DC9EBAB8F7 -:1019F00092DB5F9DB0AFBAF0FF1CDEF569549776BD -:101A0000EA3DEA35D9A9E72BDF45A1FC20D753F8F9 -:101A1000C63709340FE50AF97FE6BFB13CA1AB7BBD -:101A2000377A7B75A73D5BD8EDF4E57A7BDD912CA9 -:101A30009D5FC0C8E81E97B4D73135371AEDFBDF7C -:101A4000887B1EDDE935D2BE3D7F03741207FBD3D0 -:101A5000E888467FD5A56EE4E9A86C2E1F5C10F6D9 -:101A6000F04B3B54D2732EED88A4FD346FC763470F -:101A7000D07F386F8B42D3A865C7086E004F660DC4 -:101A80003DC730DE2CEEEA7977F833A3F11CA97E4E -:101A900029B20EE96C6EB3E2DA0AF3E9B03AA27B3E -:101AA00084CCE7ACA0D76A4BF33082B3987FAB907D -:101AB000B764BDB92D8F91FD18EA5D2439E8D711BF -:101AC0008CDFFF68FF3DCEF3DCC6C14EF4FBCD6D6D -:101AD000DE3D8FE4881D11761481CE8A3861D9CF1E -:101AE0005F055DFF358BCB2FE7843FE8DC2E95F853 -:101AF00019CE13F7D759451B8FF79D68F75D1687E9 -:101B00009B1FF7778F60FDB9CD6D517DA1FE97FBCF -:101B1000FF48A9399BAF6BAEED581E9EBF5FEE89A3 -:101B2000207FD6977B9E1EFF3A8C77A179743CEE7E -:101B300007D97F7CB689E363A35A84F0627E1EF7DF -:101B4000528BF01D1C3ACFB84DBEB4D07DC7E37E9A -:101B5000CEEDF94D94213788CF5AABC79A9C8EFBB6 -:101B6000C7EB46BEF1B9C2E169DA33DA87F798E626 -:101B7000B7E433A467DA77C9547F9521A49ED9E4EA -:101B800024A668DC5FE24A21388B7B48225E1EEF88 -:101B9000D5D1BDA2122BF927660E724CBD0BF9E40C -:101BA0003B268E975E8E27507E9BF95E1CC54D2D81 -:101BB0004C734CC5F92F7A5FA578DF9983051F48D0 -:101BC0006A1D8A718B35AB14E68275B6A571B9A111 -:101BD000C6AF320FE47B023DF8001423B3D3053FB8 -:101BE0000D64E17DC0A72A0D2E339C7FC7CDCCA705 -:101BF000A2DDE8651ECF5C93CEE3869F42BA87B430 -:101C00002636901507FD9D17F8AC9914C8C238897F -:101C10009A9793294EE2BC99FB2DF13BFA496B0A46 -:101C2000A03DD48B17F1B0D83E26847E6ACA9C0EA4 -:101C3000ACA7C63A1DF9369CAFFD22C9B1AF4432FC -:101C400094630DFB22799CD3AFC2365B42F0E4CEA5 -:101C5000E67272BCC0239BC1E321D78B78ECF55BA5 -:101C600093FDA8BFC9FAEB4D9EE908075C07CAEFD0 -:101C700073CD4D5928DFCAF9CE8D6AA2799E17F42B -:101C80003D37BC89C74B9B793C25D6C77C9B895186 -:101C90001C77FB0B168A27399B7C6C2F8E7FF68571 -:101CA0007E0CD7DF96E69FBD9FCA417E04BC55BD22 -:101CB0006809E07ACEBCC0EDCD674C5C1E3B539208 -:101CC000E440BC154DDA3093EC315B2C0AE2FD8C1C -:101CD000C2CC4958BEB587D387ED1BEA294EBA0A54 -:101CE000D804DEC781B408EFD59CD9DA8FE2C3CE21 -:101CF000BCADE28D28FCBE0ABF7B58D3CC9F213CF3 -:101D0000B673FDE9EC8BFFDE2FF41E9A4CABB66880 -:101D1000E3E0249DC8F205D95C7F5920E07C5F3662 -:101D2000B737D44634AF4FA77572B8039E48EF0358 -:101D30000E13F9F4108C83C854906F3C0574F5347D -:101D4000DA15B673FDEAEC0E13C58557ED8B7451A9 -:101D5000DCD9CAEB0C1407A17239BCCA00E0A35449 -:101D6000A17EAB26E5F81B49FE66A4C7B66F55C534 -:101D7000388CD970DDDB789C6F31CA8A543E90CAAA -:101D8000CF88FC99BD0349AE83FE5D785FA9EA6701 -:101D90000F70384EAE7C97911DC34AFCB5A6D38F09 -:101DA00033321ACFBBDA953744E33D40F69ECA5032 -:101DB0003ED1C3E9B2D199887CF57036E75FD57B17 -:101DC0009F31233FA816F743AA5F54B83F19F6196D -:101DD000DE93AC5E71C313449FBF37B14C58CFF94B -:101DE000E6C7A242F1B14BF4D359DFECA4FAD550C7 -:101DF0001FFBA95EF14E14CD679B89E24CF478BCC1 -:101E0000E6F62FAAD7D4BE933E9AB91DE5AAF5B33C -:101E1000633FF914FAFF7A4798D3475F9BE95ED98D -:101E20003953F36C5CFFB99D61C48FCEC570FEF071 -:101E300025F04F5F36CEE3B647292EEB0F93E93EF0 -:101E4000DC1CBFB65F39EE6F906F63BC549C331AD5 -:101E5000E3FA6ADFE3FC0DF0723BB57FCF44EDF5AA -:101E6000EBF8A568D7B93F7746103D9CEBC9F172F6 -:101E70006E57369D476D319CCE61BEA9787FEEDCF2 -:101E8000CEEC7CBA9786C20DD04395D06FCFC534C7 -:101E9000A7DA43CADB4C424F0B404DA41B6C0372C4 -:101EA0005F553D97ABAAADAB293E04E36A87155059 -:101EB0001AB0C45E1D1F0BF44AFA63780EDF5F0C84 -:101EC000C74B10F1DB24EF349B917F7B845C58B3CC -:101ED000431F5FCBCBCF6477DA391DF1329E17E910 -:101EE000D0A7509C49F5B2057391CEABEBD6DE85F9 -:101EF000FB4CCEBFDAC88A500F6B53549A475B181D -:101F0000BB67129E1BA1E384C86D5F07C761F6041F -:101F10009257E91CBB92EDE074832726DE135DA681 -:101F2000ACA671D2A43ECBD725E104E030635C5F60 -:101F3000DB6851DECDBAE53CF5EB96F3B1E5707E9A -:101F4000D496E6787424E2F9772ADDA7BDFCDDE0BB -:101F5000E8D82EE4B2E0B96E0EC6B7C2FC9391F693 -:101F6000D0EE92CDE5F16A8C9F8579666DD4C67509 -:101F7000E76CD1E6FBEFD0E673F768F3792DDABCB6 -:101F8000F3B036AF887151CFC6FBBBA867638A7ABE -:101F9000B6C3C2F56CCCA39E8D29EAD9F81DF56CA9 -:101FA000CCA39E8D79D4B3312FE18DFA36E651DF83 -:101FB000C6F25B73B83C5623E224110F48EFECD510 -:101FC00030CD7D9F4B6FF07B1C40077CDF4C37D3BF -:101FD000BE790A6B90DEC1ED4A3D275B1D18EFBB51 -:101FE00038D633246728DEF738B62219F1666CA597 -:101FF000B8D3F9AFF1B8D39A82301BDA375A977F4A -:10200000B902C339DDB19E1158FF92A97D1BC2B739 -:10201000B6FE10DD7B6F5DE278EF268E3FB2B3B087 -:10202000CA58929BBC78CEC5768F477DDC375BADB6 -:102030008DF3D6C77DEBE3BDF57420E5BDE74CED30 -:10204000C9C8D74FBE605D8DF33F1926EE9F4CB3D4 -:10205000EAFCFD424E5BA36CC6F37A464E2CF79F1A -:102060001D05F9BC8B7356A6E55706931CDE995FD8 -:10207000AD18E85E5C52029D438BC49C5295F6B647 -:1020800095C8E7E61AE8DCBC0C72198E77F903955F -:10209000E487EC0D06CD7AFAF9C335F435607BACF4 -:1020A000EE5E434F4DFD41FBD375F71AFA6BE3E843 -:1020B000A72C3980FAFDE4D58335F52ADC37E8E032 -:1020C00028E62DE4D70A383F5CB0BEA7166F484516 -:1020D000FC2E9ADBD1B612E5D357C2E85E5825FE36 -:1020E0003FE08B95D027DE67ACDC23EE03D76BCFC8 -:1020F000E172710E551A99CF1E1BA4C34A3B73C5DA -:1021000040FBB9FD8FE50550AF78FB8FC3ECE9A824 -:10211000578C4E447E946A72511C6CCDEECC98253F -:10212000D0EFA20CCF4339B0CF4E351DFA45299ED2 -:1021300087BBB9BE7772F56FA2284E4CD05BAAC997 -:102140001E8E78DFD4C4E3E3D03EA6C606E9625310 -:10215000535C785F5B70BD413AF88EF004F8E1762D -:102160009CCA83E4F7E86816EB1DADF8509E96EB29 -:102170005B28CE15D697F773AFC89F12FA855CE738 -:10218000F97E07F21C78FFA2617FAA8AFCDCB063AB -:102190005B32A4B916CF165C4FE5A6CC3F8F847195 -:1021A000AAFEC4D7F3F9BAB1512350FEDC69721606 -:1021B000437E65D3F366D4B3AB8C7E33C557BEB0D4 -:1021C000C98CF1C5376FDF44DF676FF7523CE51C00 -:1021D0005647FAE769F9EE808047E51865A31DE6E2 -:1021E0001DD68FF38FCA70EEBF03F9E82D7CF7E39D -:1021F000F276251FE378A6B8779BBDF0FD0DC18F61 -:10220000F5FBA4E3DDC9853D081EFCBEC69F18682A -:10221000F11957EF8BC957D2685F4CB93280F4B2CD -:102220003B02FDB8FE9BABD37FDFE5EF2E74B4F02D -:102230007D50690EC44FC67DF2A689E4DC5A386F22 -:102240008617A05ECDD8F590BA47AA1A7A9D3F2E80 -:102250004243CFD358C83E81FEEEC4A09190FC9477 -:10226000E20C4DFDA95306E8E8BF20584E7CE47A05 -:10227000CDFDBADAC53E874272E618ED77C6E304B3 -:1022800081436BDAD7B249C17A48DF5BB81C5CBBCB -:10229000276633DAFB2A0D5C7F9AE6E1DFE7EDE79C -:1022A000DFD934A6D9877D329C7FE6E7A289FC027C -:1022B000D29E3E0DFFDD05FC4112E9BC1F8EF7E208 -:1022C000D11EA1B93F2DFC81386FC443ADB01BD5E1 -:1022D000E670BB51ADEF9819DF1D00F81BE362A952 -:1022E0009E350EE3239B14B22B62BA98E225B5719A -:1022F00058D81FC631CE3BAA7A719FE8CB81EE78C1 -:102300001CFF6B3CAE74CE067D1CE46AF247CE43E4 -:102310007B5008DE6EE9E710FE38FF8A9E08BF6238 -:10232000259FEE45EE3860C638BB295362F271DF57 -:10233000E8E94BF275D8CFA47F77BC7B88E8ABA3E4 -:10234000D248F4FB437098E7E276543DDDCD66C792 -:10235000CC784F7CF61EC589FA28D64378F4447AA7 -:10236000D4C1232EF66A3848F874C26B8F3ECE8DE6 -:10237000C369CE7EC51FE8024EFA79770737B99E4A -:10238000D91ECF78E40B725D7370FED83FCC1FFB73 -:10239000977E08365CBF3F33C83E35CFCDE363F54B -:1023A000F430E90AB7BBDC79C548E99462ED7EC434 -:1023B00076B82FEEB89240E53F965EE6C13CF9FD57 -:1023C000A76BA313B90EC97783FB81DF1BF8A17735 -:1023D00081F476C73BFA09BBE3503654138F2CF8CF -:1023E000AABEBD3E1E59CA01FAF3C51B69A0B8C9F1 -:1023F0000E5B3AC91792CF7AC4F9E159FE0DD5F3B5 -:10240000403D3E9B04CD79E311F6BF8591E9F41E72 -:1024100043EA92B804C49337CC4EF1F7DE252AC5BF -:102420003D7BA19E23443E59B12C2315CF8B130F26 -:10243000653FEB03B9FDC4FDF109C3619C93CB4D2E -:10244000F15647B0DE89E585A918A77172AD659A86 -:10245000BF0B7835F4E3E743ED831FD17976C1F004 -:102460006ED434685FB3FC95280CF3AF5ECECFF129 -:10247000C40CCF83FDC87FBB699B1DE167DF9487D8 -:1024800076DF35701C607B293F542D2F4C44F9A218 -:10249000E61F879EB5E33DEB25A604943FCF7C0065 -:1024A000E7A142E719C90DA7C3A00BF2A745921DEA -:1024B000E1B4C25CE8573A6F38F0D795A817E63711 -:1024C000670520ADB578D6F443F97FF9F324B75406 -:1024D0003DBC244B55B1DFCCE8AEEC2632DD26CE38 -:1024E0006D94DF3145F91DE364507EC73CCAEF9817 -:1024F000A2FC8EDFE76FD0CA7FCF087FA1B427F799 -:10250000696CCF47FF9D6F0CCBA9A3F3D69683F2DE -:10251000FA2225DC89FC6811CA4A98FF2C8CF458F1 -:10252000B625999FB702CFF556EE37FA56DCCFBDE8 -:10253000B11D64B210FABCE98A9585DE9B1DCD629F -:1025400034F9B1D6644DFD427B9AA6FCE6A47E9A8E -:10255000F25B1CF99AFC6D392334F52738476BF28E -:10256000B70FBF4553BFC455A2C94F2E9AAEA97F1E -:1025700087DBAB299F3A6DAEA67CBA6781267F5771 -:10258000E5FD9AFA77D72DD1947F6B008D14E8A5DD -:1025900005F52E0BBE9F62A5F4A7AADD887C63D14A -:1025A000EF326D88EF91630D755DD9F73F14741CA0 -:1025B00037C0F53ED24B6FF13E4E6FF1CECD293C88 -:1025C0007786A21F12A88AF4DD63C948BFFA7AFA97 -:1025D000F29111072F3B0087A35E34DF61043E3484 -:1025E000F2BA83833320FFD3176FE4F91B0EFE2664 -:1025F0001DF20D2F2EE5F941072F63B9F9A5313CE6 -:102600003F9991E8F148FF8E29184F32F2A6F4D590 -:102610004E6E27E9F29EB94C110E785F1BE180697E -:1026200000E817D38340BF981E06FAAD00FE74047D -:10263000E817D3A3A07FE2F77F05FD13D37741FF0F -:10264000C4F4F7A077627A0CF44E4CFFD0308DD2F0 -:102650000F1A3CD4EEC3864A4A3F6AA8A3EF9F34C0 -:10266000D453FA97061F7D27473FB74333CDFD006C -:10267000F433A23F71BFE97CA81F58FA2BA57FB2A3 -:10268000B18EB54620BF6835C67C610DFA1DBBB75B -:102690000318D91721F258347345F42779A1979D6F -:1026A000F8B7F8BEB38FC7DE1FE6F5A7B4C99983A4 -:1026B000553CB7EADE42B7EC9FC4FD7A7DBFA784E4 -:1026C000BCFC657F570F6C27FDEBD2BFDD193713BC -:1026D000E27F3784C4EBD05F48DC8DF483CB389F36 -:1026E0001BADFC9EB1F473CB781ED95FE1D78CF89B -:1026F000C3A85546925F228D2C80FDCBB89D51D644 -:10270000E67C8C63185563A37BB589F0DD5C40F5EE -:102710005C2AA45BFE06F5F3827EF544317F28A790 -:10272000F9177EED213BEC28115780EDADBCDC871D -:10273000ED47A16D6108A5C49F9EC17BBB05413FCC -:102740003FD68FE0F503D85FDFBFC37851C17DD39B -:102750003BB6391FF975EF7936BA17BA717480DE56 -:10276000B322A313C065B2D49FAC222FFD79DB1333 -:10277000C98E3456ECF50C87E766C4A7DB62FF2CE4 -:1027800082F659466FB44F9608F9F93FC15B31E2C2 -:102790004DC253E245E251E223247E8AF0D01D5E11 -:1027A000F5F8D4E351E2AFF0EB205E10AE57E32D25 -:1027B0008857B4E7FEB3E06D8891BF5F66A9B1D2D8 -:1027C000BB683F84C77BDAD9F868A872CAE139854B -:1027D000E7BCF78AE308E6CBD9E8F1885A597EA12D -:1027E0009B72CFD7EDA6E8107CDF28F01D9F06F581 -:1027F0007B5C5D5FD693EF31C8FE077753FF9D305A -:102800001977E1B2E50F0BC63F2E2AE4F02F4A53A9 -:1028100009FE6373E7909CCC6C5CCE74C07FC89754 -:10282000C67FE7A6772DBF613BD073CBC6C76BE5EC -:10283000D3229DDFFA562197DEAA934BF572A5BFEE -:10284000BF902BD358DA8F7CAFF257FD89AF5EEB88 -:102850007B95FCBDD371629FA5083ACB70A86C2410 -:10286000D211F3D0397918DF3BCDC377417D94BFC6 -:1028700085F929BD8D05E87C9D008C18F3B733469A -:10288000F7C80F454C2CC5BB7163078FED8BDF4339 -:10289000DE656BC17D3A4FF5FC9B3DE45DB683E39D -:1028A0001C74BFF2A03583E42FDC87A6107BE0DB2D -:1028B000703EF585F3E3109C5F98BE05E7575F58BF -:1028C000EF6FE1FCC2FCAD394B18B61BEFD0C6ED83 -:1028D000C8F6B7D9C78262D23DFC6ECB7BB517C2B2 -:1028E000F79D98EC71683F7F27E6BA71B8DE776292 -:1028F000120D3CB598291DB8AF6F57F2A1DC07C186 -:10290000F1C6D3787AF84A78EAE128E1FB5F80E7FC -:10291000175DC1F394909F3BAC7F8C4A4A47FF5DA3 -:102920009478C7F277792AE4CFE0D492315EF50645 -:102930009AE7A8FA11CC3898FC36B908D71A2B8731 -:1029400097DE6EC5B6241A42E377BF307BBEC5F171 -:10295000BFDCA8D2BDF10B2F87913DEAB49FDBDB32 -:102960008A14CF77488F35AA6335BE3FCADEE1EFC0 -:102970009CB1EF0EA54E8AFC1174BA85DFB7AFB1DA -:102980008EEF128F529FFA0F878BF80813EF454A8C -:10299000B9A29785BF4B20DF2FEC4ECE1816CEF98B -:1029A000602F8B781741E015DA513E05FA19067C45 -:1029B0002EE5D170D22FEA7BB8E2070C0DDA113A7E -:1029C0007A45F891DF8E0A0CA077B98A8EAA144F47 -:1029D0007C50C477DD3CA0CE960E78BA29D3933ACA -:1029E00000D7A57EA7229F7917D61987F687A383DC -:1029F0006DA43FFE483D346B80E017792C4F735F28 -:102A00004DD29D6AA3F89D8E0FF87DBC856FF3B8FB -:102A1000CD853D548AFFD7C7C58D62598FA2BD7140 -:102A20006CBCC9E97704F98B7C07C89264608E108E -:102A3000393BCC11CE1C21F389C889D5E4239D3DB7 -:102A400035F5A387A76BCA635CFD35E57145059A2B -:102A50007C0FF7F59AFA89D3C668F2C99E5B35F503 -:102A6000532A2769F3B8EF00EEBDEB6668DAF5A9E3 -:102A70002FD3D44BF35569CA99CF752C2701F93858 -:102A8000FFCB58B55053FE7454118F1FB7CDA67BA2 -:102A90008A994D3FD3F427F19B12C7F1CB1CFC7CE4 -:102AA000F0C17FE4B710782E4CD29E1B63EDA30FCC -:102AB000DB29D5DA35527E200E6ACE7F950E6A99D3 -:102AC000960EE2791C4FE1DB831D28C7E8F18FFEEB -:102AD00088D075A23F22142EE88F08CDA33F22B4E0 -:102AE0003EFA2342CBD11F115A3EF8A816FF438F5E -:102AF00069F17FDD4763FE533C8D68D5D2831E4F5D -:102B0000379CD6D2C7284F38C1652CC86348EF120E -:102B10004FD3E03F3AE7993B1AED06373117DD0B0B -:102B2000F89FC2D7333A7C7DC3560FC5772E2F79D5 -:102B3000391FEFEE9C7FA28FEB79E41FEF0B3EAFC6 -:102B4000B703C87852DF188E4FDFF130E257DF1A33 -:102B50005A23F1FCF8A9DA4A76F964D6FE16BE3F8C -:102B6000638AF7FC1AF95822460F40F95373EFCCE9 -:102B7000C7736EE6BF585251AE99D987BF27C87246 -:102B80005BE99D16399F99293CFE68DF00C1A79D2E -:102B90003C0EE9B5015CBE8E74DA290EDA9BCB449B -:102BA0009C274B9D3910E9F0DDB06CA4B375DCCEE9 -:102BB000D56A72505C8B0FE811FD94286FA33CDC42 -:102BC0005BC8A38D1F5BAD9CEE98E67CEFE7B76A10 -:102BD000E270076CB76BF2039B9334F507ED7768EF -:102BE000CAF303399AF2C1479D9AFCD063C335F505 -:102BF000AFFBC8A5C98F682DD2D4BFE1B45B934F9A -:102C000061ED4F223CBF1A90CEE3FB156107707057 -:102C1000BCCCFC6902DDA7917A848CCBF6083AD64D -:102C2000EB237DCC1E8AF36E4C664EBA0F6215FA0A -:102C300020D3EA291E11572DE579E6D3C655CB7866 -:102C4000EA4E7D46E82F529F0889A776E1FC653C55 -:102C50007527DEC5FB927AFAFC87C0BB7E1D7DCC52 -:102C6000FCFE57E3FD66BAC722E7A79FD7CD221E19 -:102C700070ABB5EBF7876CB9DC6EF068BADB980B1C -:102C8000F59E85E389E079D578CE561FC0B7F1E788 -:102C900066E752C70F8F3773105F4F29BEAB9A4B51 -:102CA000EF74D2BD35396EAF5C4EDF863CA5CBF5F7 -:102CB000CD8CE6F15D2CDA4CF72EBA1F8FC335C9E7 -:102CC000CC96D13B49E21EC2DDAB9BD7606845A9DB -:102CD000B9C9C4DFD5F79BD04E543C06E4C07CE0B4 -:102CE000135B77AEB381BCF66CBD91EC3E19B9F1C4 -:102CF000778204D979AFA40FE8694827C5887FE8AF -:102D000077C3401EEF3C2E97AFAF50FDAEF33E8031 -:102D100045C3E7B9FED705DD113DCA75FC6FDD0F70 -:102D200090F4AB8793D4AF9938BFFA8A7949F87594 -:102D3000DA4F04FCE4FD0CC702937BB38DEE7914EB -:102D4000615C99C4DF4B03395DFE04E13194D743E4 -:102D50007ED45DBD4235371AEDE01DCC116DFF010B -:102D60007BF0FFD2BD09827F77F7BDBAE31357F13D -:102D7000876EEE7F75479FF4F723EE8185F0091E7D -:102D8000EF23F0E1EF6B20BFFACA48ED3EDE9ACBAD -:102D9000E17BABD84F706EDBF2B57C82A15DBF7179 -:102DA000B92AF8C4ECCEDF9FC0EFB3969B48BE664D -:102DB000CCBD1EE30C3E5F67A2B8D8512E46724CC4 -:102DC000D946C5BF49C173746412CEDFEBD39EC729 -:102DD0003731E70AF47F94AFD27E9F63E3BF53316C -:102DE0004BFF6E8AD0D7E7FC80BEBE3E579CE34EB9 -:102DF000E624B94BF8FF2B451BBDDCD5E1E77E335C -:102E0000D4B7556E77A2B83179BE3BD07F13F21E8E -:102E100008C0333C07CFF165C62EE3F93AE1D94D3E -:102E2000BCC2799B8857B0F1F88C8E3D61DCBF291C -:102E3000FD4AA2FE79DF652AC7FAD8DB857C1E77BA -:102E400021FD497A7F5587CD40FE968E3D91E49FC6 -:102E5000473F4E34D0C159C3EE84E169C1F9795A74 -:102E6000558D1F449F7A96BC42FA62628627908BEA -:102E700071D846A7D509F9876C07E9FDA86261F703 -:102E8000D2CFB753EF1AC9DF77E9F07179B6A388CB -:102E9000BFC3017C91E13E927108250CB45448BD3A -:102EA0008111349F1FEBCF997C259FFB31AFDC4014 -:102EB000ED3DAB4650BECFB2350BF01ECC1D8D7331 -:102EC0004CE8C26E7D72716138346DEDED5F1A8E23 -:102ED000781BAD7469976F13E759AB2EBE5EA625BC -:102EE000821FCD1B28F9B888435AA2D03E58A8307B -:102EF0001997447C5CE62F37897C21CF2F5ACEF37B -:102F0000ADE27DFD6DC28E82EBC614D78D7AFF0EC9 -:102F10006167C175638AEBC6EFC8B7308F7C0BF36E -:102F2000C8B7308F7C0B53E45BF8BD8CB953F355B5 -:102F3000EE871A17BAEFAE58D9B890FD827EA8D0A6 -:102F40003CFAA142EBA31F2AB41CFD50A1E5E8877F -:102F50000ACDA31F2AB43EFAA142F36CF82DC13C5E -:102F6000F2395789263F19E4FC7121FB1BFD50A162 -:102F7000FDA31F4AD39F6781A6FD5DAC5ED31EFDF6 -:102F800050A1F5EFA957347EAA7BC43BA7E51BE20D -:102F9000887E221DEED48180E77F8BF8C77DA674E2 -:102FA000C473CB5CAE97853B399E9B8A38DE0D8C13 -:102FB000E3B97D3AE179B199E70B797CB29E7ED095 -:102FC000DF33CEC4FD3D98A2BF0753F4F7608AFEFD -:102FD0009E7199DCDF8329FA7BF03BFA7B30457FD9 -:102FE0000FA6E8EFC114FD3D98A2BF0753F4F760A8 -:102FF0003BF4F7608AFE1EFC8EFE1E4CD1DF83DFA1 -:103000008FA3DFC9149C17CAF17D35FA23D0A146DE -:103010007FB46BF228C787D647393EB41CE5F8D099 -:103020007294E343F328C787D647393E343F33D7FA -:1030300041FB0BE5F9D07628CF87E60736F9DE426B -:10304000DBD9848D170F63DA1AA93CAB00CBB867C4 -:10305000E74B771A413E6B0D53526380739A94DDB0 -:10306000778E83BC47C4FFE5B17603E2DB23DE53F2 -:10307000F70418C55B0EFC5B32953F23EF87E11F19 -:10308000E03D7F0FA3DF2591FE62D9DEC9EC2AA6C1 -:10309000B27E30DF753DFDF8B21EF1CF9079E00DC4 -:1030A000608C57C95F6C2BC078CF6D0685E224B663 -:1030B0002DE571C27ABA7A6C20F78B6E33EC3E88BC -:1030C000F740DABD0ADD07CE32B2A3A60284535D13 -:1030D000019EBF0F0C8C117EBEBAEBF1BE899CB76E -:1030E000B46F029FA0FB7323DB8F8D8D867E3CBE69 -:1030F000D1F43B29C5662E37603BD42707F814D797 -:10310000E610FA5E3E90F34D8F8F8FFFABE726F20D -:1031100076E1BCDDAF9E8B22384E5CA650BCD4C895 -:103120001DCC85F7737F21E63D604740C5F1BCCBE0 -:10313000F878B25FEFC654BAB7E865ADE392C84716 -:10314000A230E4DB126EB0BEC3B83E501B8EA27D2F -:10315000FA5AEFFDDC3824A610E3E8580BA3772CCD -:10316000270C795FB35E42FB30EA97CEB56C9F4285 -:10317000EF054FF42D598A6431C1B7E0AD1E587F79 -:103180000B73A639E828A27BB1723EFD5DBB0D70C2 -:103190002CB25C76CC10A620BED9A1B810FA819DC5 -:1031A0003F05F19DEF34D1FBBD2546BB89DE8FE89D -:1031B00026FEE4B24DC69FE8E4055D9C49E3E28F3C -:1031C00052D19EBC30D240F6DF85AFF0DF03F06C09 -:1031D0005088AF4939C82BE2D42E2F7BABC754841B -:1031E000FB6E13F527E34F6A33FCA9068CABEFB9EE -:1031F000292F562539E000F2C373BEDFDC391CEB02 -:103200002DE7EF585E5E764774807AE2FE9A0A01F7 -:10321000AF0A11C7E4C507BDD5E0EF69C9FB1DAC16 -:1032200089CB7BD29EE3FDDDE023885FEF33E25D57 -:10323000E9555EBA97AD8F239ABBCC44714773753D -:103240007261B5900BAB7F402EFC78A04E2E94BFE0 -:103250009722DA30B5D78718B727EF25969AF8FE68 -:103260002FDDCDC80E5BBA64AC81DE417E85D34DC7 -:10327000E9122EDF94BEEAA2FB85525E7C4FC83174 -:1032800093AEA410DCFF28E4963B30BE12E05BDC7A -:103290001A26E2B092299D7A85C75B4EB2713ED064 -:1032A000FA067F07A2C367E1F2D461C6DF31D3D14A -:1032B0006589D16FC00B77CE914097909F80721037 -:1032C000F4370DE5A238A4F3B4428ADF2B52E8DECE -:1032D0008B9ECE8B4D756F617C68F156E6F4B150D4 -:1032E0003A07FAC5FE7C0ABD0FE0117AADA45F3D36 -:1032F000BDCF8C10F6281BB73775DA255046C54769 -:10330000BA7DA6A918FF3A137D7B3D39C160DC590F -:10331000642E2F8FDB659ABA0CEF2A7463A7507F57 -:1033200066267878E43B08DDD80DD05E807CF2EE2E -:103330007BF3CD65217CF2E4A0318307F508E2BB85 -:10334000ACF3BE5F2EBD0BBAF0A14CFA3D9CEEE48F -:10335000E172802BEE8B99D1ADF7E12FB315E431FB -:10336000D7B824FC7D41261F210F601CE10C91BFC2 -:10337000272FEFCFAB6C0417CAE7ED8A9B8A712128 -:10338000B5D6D6F14876F3733D45788F31C89FDCCA -:10339000AE1405F9537E0075C29BB3F83D2FBD3DB9 -:1033A000E29E3C5E5F6F9728CFE57C5BFE2ECA896C -:1033B00087F6EDC2F34ACEFF4437BFC330358FCB1B -:1033C000B3FF53F720F4F71F66F5F414E5C17CD77B -:1033D0001BF87DFE9E6A1313F621F20B4B7EC1C4CF -:1033E0003B1841BCBBE81DDDC687147BA87DCAB372 -:1033F0004AE1F7E8BBB1E3B09CF627B742BB990DB1 -:1034000066FA1DBFE7B238FD3C07F443BF97623E42 -:10341000F696352D08C74FEB7F69A2DFA561814C79 -:103420007C7F67465D9813F9F1C941EE9938EF88C2 -:103430005C27F1A1C183387D65C4BBBD7978FF6E7F -:10344000F58167F13D81F92D69F47B25DEFDF92BCE -:10345000F09D9393833CB3B1DC6BB3D37B1AF396AB -:10346000C5D0F9353351DC0B65EDE46793F07F305F -:103470008FEB89D73999F8BD2D71DF01186489A6C2 -:103480009E88EFD6ED0F6927D4DB19F4EF4B7467F4 -:103490005F90F604B41F9843EC8CD23E61CA393178 -:1034A0001DE58652B3F65EA24C7F2DE62FF5C0597E -:1034B0009DE756EEF844948FD72A767A6FD2E69835 -:1034C0003A02F215474D18D9C98A631D667C7FA060 -:1034D0001DF08BF1D165B05F91CF948A38AD8A0D24 -:1034E0002368BF55F821EDE21D4E99DEB5F650EF89 -:1034F00057917E022EF25B56D85DE6D8907D5FDE56 -:10350000A468DE1D90F9E7F2545A672988E308BFE2 -:10351000BBEF4D33E3DB3EA5204660FCDFAF057D0E -:10352000C876508FE2418AD3D911FE0E3CCC3B8D38 -:103530008F5710D27F5913BF372DF3509FE49F1739 -:10354000F222A93FAF1DD69D86A99DE609702038BD -:10355000B5AF81FE1C340EE1A33CE037A1BE5D8A0D -:103560007128909F61F79B709CB265FC1D13CF6A18 -:103570003E8E67558C7920CA4746BBB937C22F9C0F -:103580009F57303F92232B002E781F0BEFBBE1D9C2 -:10359000A2878F57CCB7A22986DE51087E5F6B4287 -:1035A0007C4CEFE65D844F05DECB968DA6FBEB15DC -:1035B0004617DD73F008F87EBE20EC61F40F4C5F17 -:1035C000F784290DFDF882CF7C2AE05A9C1EC8A4FE -:1035D000F78A168439719ED3ED4DB4BE4EF83E0E77 -:1035E000F050F09D1B37C117E8C287717B15EBB413 -:1035F000F80CCE87C3B7629D97F6DB6CA3C76C0F40 -:103600009DC786039978AF6A3AEC6F7C5782D93DA3 -:10361000745FF28BC7A7A6D23A619E08D748A7630A -:103620003CBE3F0474C2EFC188F5C87BDD72BCCBE1 -:1036300079FC1EFCE51FDC972E926B1A01BF68F720 -:10364000EE6E5F9A9171C3B8E60AFE3B12FA7D2ACC -:10365000F7A7DC97729FCAFDFBACC91D4852827C5C -:1036600006CED9BA97BB80D3E0411C0F33045E016C -:10367000AE8743EF79F51AC4F15A9AAEDDEFD81F41 -:10368000F66B95E5630299F82E93AC2FC72D8DE567 -:10369000ED90EE91DEAC830C9DF517527DED3D95DE -:1036A000F24E7EB1637902F28BDD0AF783AE39D434 -:1036B000FBA728BFEEE4F2EBB99AADF3F0BC644689 -:1036C0007F6AE8FBFEB340CE413E315B9CCF158163 -:1036D000AEF9C553599EE44121FBB9E2B19D591E93 -:1036E000CE6F02C86FFEB2F3F53F5DEF089EA77282 -:1036F0003D65ABDE37796DA1F0E37ACEC3391D7439 -:103700001FAFDC667660BC73F9322FF15F960472EE -:10371000A112127FA6A30BEF3285EE9195D70FF37E -:10372000ABFF837CBA7C7509BD7B20F126DF6791F6 -:10373000E7AB9CFF4831FF9B06F1F633047DCFA831 -:103740001C6D4E8E27B91BC32CD974F17D7A85F67A -:103750007B27DE3AFDD7B92B70BFE0FD22D24F5652 -:103760009BB8BD6F07B73F9E5BB8EFF77742BDB31D -:10377000EB37A532558B379453670B79758EB0FFB5 -:10378000758137F7A090389E39CF71BC95EFFADD7F -:1037900067F89E5869BAE0776BF83B0065CDBB09C6 -:1037A0008FD357AD35A5213F1A94A6E1E3E575F90E -:1037B00076B42BCF58B5C9847CC223E1A0DB0FA51A -:1037C000224E58C219CF2525C4BF21EB237FC4F751 -:1037D000EFEF5D101685F13C729C87049D97D7C56D -:1037E000C4E278E575DE5FA03E24CF03FD3A4F8644 -:1037F000F1FD5206FDE1BE3D39DA99BA303728CFE6 -:10380000EAEBFBC4BE7BDAC47FA72625A2F9058AB2 -:103810006B981FEE44FED1B76FAB1FC745FAC67950 -:103820009B0DFC776DFAD6B47E85F3E8CB785C0D02 -:10383000A6F83E16FA171220BFD9C0EF6FA5AB3C11 -:10384000DD26E003E5012C67F1ADF4FB1A2171B32D -:103850001AFA35B32DF4FB89E67846EF9B497A9541 -:10386000FD487A95F4DCDDFA9EBDC6F59D4CE3F08B -:10387000348BDF4DB9E6F559F8EFE8CA75C9F9811F -:103880000CEFA2F73D1E1848F69E934B9CA91837E3 -:10389000D9FD7AD7152674B15EFD3AE5BE91B1F037 -:1038A0009DFEAC26EE7738A9C0F906ED4E2E08A392 -:1038B000F836B9AE1F6B0F3F382856D8775A2351C8 -:1038C000CE2C0D0FDE9747F81DAFE7BFAF2BBF4BD8 -:1038D000B940BE3327F9F7A93A716EB2D635B8BFF1 -:1038E000597D06BD7F72BCE96424BEC77272349FE5 -:1038F0009F6C77AF89DF4F66916607DE138BB8F751 -:10390000FDC244F40FAD4BCB57A0DDDDF5838FE353 -:10391000FBE3772F4B24FD7E96CDB102CFC559BE78 -:1039200034F20747ACCBFF02DFD19BB56C00FD6ED4 -:10393000EFBD0A73933E29F484D9ACF38FF4843934 -:1039400082AFCD417E89F7A5EA0FD1BB79B39D61E6 -:10395000F978BECFD9C0F58462035B85FEC43E8D85 -:10396000EEF1C8C7DA9F54F8EF3E6FD4BEC3959C02 -:10397000EDFE0CF98CFEDDBB7B4DCD2E5C07037993 -:1039800004ED4EB36C6E92EB4B05BD1C5FD746BF8A -:103990009789F0A6DFCBD1D96FFA98F93DE2F648C6 -:1039A00003D9E300EFEFE1EF91E17BEB163A6FB45F -:1039B000F69B3E0F0EA7DF6B93F7842A84DF49D274 -:1039C0008FF45FCDDA3499EE0FCD427BCDE0E0FD90 -:1039D000A915EBC6D2FB4E156B0BD7E3EFDCA40A9F -:1039E000389E32B696207E4E6F4A8CC57BB915B58F -:1039F0008D59785FA862D34ABA37747A5318DD1BA1 -:103A00001A672F1987BF1F327B23BF9F27F7A3CDCC -:103A1000C9F76355ED58BAF7F3FF00B910AD8C0044 -:103A2000800000001F8B080000000000000BCD5636 -:103A30005B6C1465143EFF3F7BEFECA5ED527AA161 -:103A4000EDB6E5B2EAB69DA51403189834802412A9 -:103A50005D0805368176088114686B4593164364CA -:103A600061951088711F5AA104CC52A1BEA8D986B5 -:103A70004621AE66A541A236B18117129266FB526D -:103A80002E11BB564D69A2E039FFCC660997C44799 -:103A9000E7E5ECFFCFB97FDF39B3ED0F473EF1D457 -:103AA00000ECAA02F02C01F82B91178F3080F6431E -:103AB000972A240E10B06A56650EC03E9EDCBCCC20 -:103AC00007708FC5074B84BE6FAE47067844CFAAF8 -:103AD000A7E5E421009F15A0E3BD9BC2CF7D3EFA80 -:103AE0007A18EDDB3B2EBAC8CFBEBE1B4B3D783FEC -:103AF000B7462B541AC9EFB9418F0400A7CED5851C -:103B00006A01BC0AFEC6FBF505A1CD61CC2BF3A36F -:103B1000A40CF89E1FAFED1226DD903B6F8FBB2DDE -:103B20001000D05260F190F480A500E51D097A12D2 -:103B300028D75743EB463977BF48417BACF38E3BE0 -:103B40005611C2FB3D83272B7C28EF3AF5F3B6C113 -:103B50002D3F810BF5CF5B2D407626B02868B7331B -:103B6000C2D4384A682B0028C9C50F2A7922FF3DE4 -:103B7000A730A9C2DC3D405CDCDF35C13ACAA332C4 -:103B80009A09BE85F29629B50BB0CE5B5D7625828B -:103B900058C88A4FE4732B26ADA5FBC83B0C1630E2 -:103BA0003A5F74CEC7F82D6EE8227BE792448A7B99 -:103BB000B1CFC3F98BA97DF8702802E8F4E8873506 -:103BC00092BCB60CDFEF1F621E2BBADC7FF9EA5AFB -:103BD000D0CF00ECF9FDDCFB6005F81ECB7BEFF0ED -:103BE00090C587F1DA3FC77A317E7B62E88752F46D -:103BF000D3796947831E3706B014F3A09F18A773C3 -:103C000058EF4BC7F084656720E76787BFE0681906 -:103C100062BB29D1B8A50FF576106ECB910F752F29 -:103C20006C3D6C22E911FD0153A622E40438EEBF7D -:103C30006ED1C8CFFB863FFFF5A3D5A2DE0D85F080 -:103C4000181F9A15B3B0CBDA633F845DAAC3710C19 -:103C5000EA01D44ED94432DA21BB489EE9E27E1310 -:103C6000F655650E45C27EF7D85C75E00698B1EB57 -:103C700032E9D065370F0DEDC61467F8981D90F73F -:103C8000DD528C915C15E862D869307BB57D341FBC -:103C9000C59060201A916294F7D4B7B71B28FECA6A -:103CA000CAF41F802999D9CB5B57233FDE568CFA83 -:103CB00002E906E2F99C2BD04AFC3A6B8663F6C512 -:103CC00054770836D69217FC4DB8CFF2F805CC2FB2 -:103CD000C9529F92FF6CBD9F115FD14FC82A1F63CD -:103CE00098E79F95DA41CAE30D66AE0D72C2405A5D -:103CF00040FEA7CCFA7B889D546DC88B269D16503C -:103D0000CE210248594B69B14CBC66AA0A3D18FF46 -:103D100048E0CA4EE2C7898C0DAC18376AF4A32973 -:103D2000E39860A8575EBA8E431DEAFBBCB00DED68 -:103D3000AF0478C48A799E005B9CF4C1B6464DFB03 -:103D4000F5188FAAD13FB7AB423F796D96A12C935E -:103D50007E1F71A37E593753A2A8D3323D79F6173F -:103D600094DB201EA4BEAEF66A7DB40FC6A7D74D65 -:103D70006888EF094FC2467346CFE3F9270FCCBAE4 -:103D80000A782EAFA9CCE4175F2F21695318DA35D2 -:103D900025A594B5EEE97CA68A7D268A837A294EEC -:103DA000FA328F3346FA233729BF269B9C925C64F4 -:103DB00067FE356DCBD9C15879FEE44B20207E5487 -:103DC000065014D5715B69CC611697CB0A17B85CA5 -:103DD00036F0C9F64F248FF3B1DFA6CFC777F2E0F4 -:103DE00076E24F765EDF34EEA71F54BB69BF4C27E7 -:103DF0006BDC1078FE7CDEC0FD0A8B005EAB52BF30 -:103E0000A77EE1A3DAD07FB3D11FC41BC8AF64F88B -:103E10006D36FAD42C73BD2F9B9EE88BC1932C0F6B -:103E2000B2796771CEE207EF8E5D755709DC6A3FA4 -:103E30000281D7CFC4BBF1D9D10F70ACA0545227A7 -:103E4000B4AAFF235E29FB22E475A68F2B03C47F4F -:103E50006AFC6221558EF5811FC43E68911CCAF12F -:103E600067EC038DF6413DED839898F3199EB9CA2E -:103E700019ED832E712E86CC61139EC779DA49F92C -:103E8000A6EDC87A94EE60B5D8E36534D1353A4EE4 -:103E900034D7670F38078EA37E94A9FD36B48F9A66 -:103EA0008D79DF23C72FE0FD549C47CC18AF373FF7 -:103EB000DEBF1BEF7B9BE72911ECD314187A6D0E44 -:103EC000B11756702ECE9970517CA08AF471AEB1A4 -:103ED000CEDEF08BE23BFED543744E752F00FD7DA8 -:103EE00010169EA2F71BFCC2DF37D93DF3A153F891 -:103EF000EBDDA09638C4FB224EF6870B357BB091E4 -:103F000070D5F5F08F80D03B7D5A2D213C4E6FB49B -:103F100008BD8F5928BC8BFCD4CACA05F49B0E3B44 -:103F2000BE1CD4E14831BC1FEFD1EBCDF2F7D585F3 -:103F3000FA1EAC8C4CF403B628D204FE2EE4FD38F5 -:103F4000F1B03E870F53118B821C4E593E46CC88F0 -:103F50009757C7EB087B1A2FAF8117EB41DEBA08E2 -:103F6000B784E8FF0CD771E896209D8735495C2916 -:103F7000B6A21CF36AF3F53AC74AE87D8B35DD1823 -:103F80000B109ED09678C61CD6D3929D23EA63343C -:103F900067AD06CF5BB37C3CF8041FD3F3F227F385 -:103FA0000C3EA2FD4D472848F1EEB31B4BE972F4DD -:103FB0001F69EBB3E22C0FEA7BE437ABB68CF4E17C -:103FC000FC5C2EF688479FEBD1E0ED72FACEC0DFA5 -:103FD00023F3E8BBD35F187A85F4ECF333168DFA3C -:103FE000599231533DE3E17BE5F47FA6B5E79A981A -:103FF0009BFF9AE7BF3AB4AF4B200A0000000000D5 -:104000000000000000000000000000180000000098 -:104010000000000000000040000000000000000060 -:104020000000002800000000000000000000001058 -:104030000000000000000000000000200000000060 -:104040000000000000000010000000000000000060 -:104050000000000800000000000000000000000058 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:104170000000332800100000000000080000333069 -:1041800000100000000000020000332800100000B2 -:104190000000001000003A78000000000000000855 -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C0000000000000003120000000000000000896 -:1041D00000003360000100040000000100003368AB -:1041E000000000000000000200003370000000002A -:1041F000000000080000337400000000000000020E -:1042000000003A70000000000000000800003A4082 -:10421000000800000000000800003D880040000089 -:104220000000004000003A500008000000000008B4 -:1042300000003A60000800000000000800003A8812 -:1042400000C800000000009800003C180098000022 -:104250000000002800003C580098000000000028E2 -:1042600000003378036000300000036000003EB0BF -:10427000000800000000000100003EB1000800003E -:1042800000000001000020080010000000000010E5 -:1042900000002000000000000000000800000000F6 -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000012C892 -:10445000008000000000008000000001000000005B -:1044600000000000000040000490000000000490E4 -:10447000000019C8000000000000000800004948C2 -:1044800000080000000000080000492800080000A3 -:104490000000000800004938000800000000000883 -:1044A00000002008001000000000001000002000A4 -:1044B00000000000000000080000401004900040D0 -:1044C00000000040000049980008000000000001C2 -:1044D00000004999000800000000000100000000F1 -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:104600000000000000000000000040000018000052 -:1046100000000018000043000040000000000040BF -:1046200000004300004000020000000100004301C0 -:1046300000400002000000000000300000400000C8 -:10464000000000400000000000000000000000002A -:1046500000003000000800400000000400003004AA -:10466000000800400000000400004B00002800008B -:104670000000002800004B50001000000000001057 -:1046800000003800008000000000008000003800BA -:104690000008008000000002000039000020000037 -:1046A00000000020000020080010000000000010A2 -:1046B0000000200000000000000000080000510879 -:1046C0000008000000000008000051200008000061 -:1046D0000000000800005130000800000000000841 -:1046E000000051C00008000000000001000051C19E -:1046F0000008000000000001000039400010000424 -:1047000000000004000051D000300018000000102C -:10471000000051D800300018000000020000000026 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D000000000000000000000000000000023E8CE -:1047E00000800000000000800000000100000000C8 -:1047F0000000000000002008001000000000001071 -:1048000000002000000000000000000800002DA0B3 -:10481000000800000000000800002DB8000800009B -:1048200000000008000024E802D00028000002D0A8 -:1048300000002E58000800000000000100002E5962 -:10484000000800000000000100002D90000800009A -:104850000000000800000000000000000000000050 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000250062 -:1049300000400000000000080000250800400000C2 -:1049400000000028000009C001200010000000083D -:104950000000000000000000000000000000000057 -:1049600000000000000000000000402002D00028ED -:1049700000000008000030000000000000001000EF -:10498000000050990000000000000001000050B03D -:104990000000000000000002000045A00090000898 -:1049A00000000008000000000000000000000000FF -:1049B00000002960000800000000000100002961DB -:1049C0000008000000000001000029700008000439 -:1049D0000000000200002978000800040000000424 -:1049E00000002FB0000800000000000400002FB4F9 -:1049F000000800000000000400002FC000000000BC -:104A00000000000800002FC800000000000000089F -:104A100000003000000000000000001000005040C6 -:104A20000001000100000001000050000000000033 -:104A30000000002000000808001000000000000432 -:104A40000000080C0010000000000001000008B782 -:104A50000000000000000001000008B60000000097 -:104A600000000001000010000030001800000004E9 -:104A700000001004003000180000000400001008BE -:104A800000300018000000020000100A003000187A -:104A9000000000020000100C0030001800000001AF -:104AA0000000100D00300018000000010000100E82 -:104AB0000030001800000001000010100030001845 -:104AC0000000000400001014003000180000000472 -:104AD00000003000010000800008000400003004E5 -:104AE00001000080000800040000000A000000002F -:104AF000000000000000306801000080000000019C -:104B00000000306901000080000000010000306CEE -:104B100001000080000000020000306E01000080F3 -:104B2000000000020000307001000080000000045E -:104B300000003074010000800000000400003066B6 -:104B400001000080000000020000306401000080CD -:104B50000000000100003060010000800000000241 -:104B600000003062010000800000000200003050B0 -:104B700001000080000000040000305401000080AB -:104B80000000000400003058010000800000000414 -:104B90000000305C01000080000000040000307C58 -:104BA00001000080000000010000307D0100008055 -:104BB0000000000100001C180010000000000004AC -:104BC00000001C30001000000000000400001C3831 -:104BD00000100000000000040000000000000000C1 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C0000000000000000000000004C100008000040 -:104C10000000000200004C1200080000000000022A -:104C200000004C14000800000000000400004C20AC -:104C3000000800000000000800004C3000400008A0 -:104C40000000000800004C00000800000000000206 -:104C500000004C02000800000000000100004C04AD -:104C6000000800000000000200004CD00008000016 -:104C70000000000800004CE00008000000000004F4 -:104C800000004CE4000800000000000100004CF0AF -:104C9000000800000000000200004CF400080000C2 -:104CA0000000000200004D000008000000000004A9 -:104CB000000050000010000000000004000050043C -:104CC0000010000000000004000050080010000068 -:104CD00000000004000014000008000000000002B2 -:104CE000000014020008000000000001000014048D -:104CF000000800000000000200001410000800007E -:104D0000000000020000141400080000000000026F -:104D1000000014160008000000000002000019B88E -:104D20000008000000000008000014200008000037 -:104D3000000000020000142400080000000000022F -:104D4000000019C8000800000000000800002C1036 -:104D5000000800000000000100002C110008000005 -:104D60000000000100002C120008000000000001FB -:104D700000002C13000800000000000100002C00BF -:104D8000000800000000000200002C0200080000E3 -:104D90000000000100002C040008000000000002D8 -:104DA00000002C30000800000000000200002C323F -:104DB000000800000000000200002C340008000081 -:104DC0000000000200002C2000080000000000018C -:104DD00000002C21000800000000000100002C222F -:104DE000000800000000000100002C230008000063 -:104DF0000000000100002C24000800000000000159 -:104E000000002C25000800000000000100002C26F6 -:104E1000000800000000000100001400000800006D -:104E20000000000200001402000800000000000161 -:104E3000000014040008000000000002000014122A -:104E400000C00018000000020000141000C000188C -:104E5000000000020000141C00C000180000000840 -:104E60000000141400C000180000000800001427FF -:104E700000C00018000000010000142400C0001849 -:104E8000000000020000142600C00018000000010D -:104E9000000015900008000000000008000015A0A8 -:104EA0000008000000000008000015B00008000025 -:104EB00000000008000000000000000000000000EA -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:105000000000000000000000060022000000000078 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex deleted file mode 100644 index 54f36f1d256d..000000000000 --- a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex +++ /dev/null @@ -1,13178 +0,0 @@ -:1000000000004F48000000680000070C00004FB8D7 -:1000100000001ED4000056C800000094000075A027 -:1000200000009EFC00007638000000CC000115386E -:100030000000DC6400011608000000940001F2706A -:10004000000040180001F308000000A4000233285B -:100050000000F378000233D000000FFC00032750AB -:100060000000000400033750020400480000000FA5 -:1000700002040054000000450204005C0000000679 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:10018000020400140000007F02040018000000FFB9 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200604203C0000001FBB -:10024000020420B800000001060420BC0000005F8A -:100250000204223807FFFFFF0204223C0000003F97 -:100260000204224007FFFFFF020422440000000FA7 -:1002700001042248000000000104224C000000009C -:10028000010422500000000001042254000000007C -:1002900001042258000000000104225C000000005C -:1002A000010422600000000001042264000000003C -:1002B00001042268000000000104226C000000001C -:1002C00001042270000000000104227400000000FC -:1002D00001042278000000000104227C00000000DC -:1002E0000C042000000003E80A04200000000001C4 -:1002F0000B0420000000000A0605400000000D006D -:100300000205004400000020020500480000003201 -:10031000020500900215002002050094021500203D -:1003200002050098000000300205009C0810000043 -:10033000020500A000000033020500A40000003008 -:10034000020500A800000031020500AC0000000218 -:10035000020500B000000005020500B40000000620 -:10036000020500B800000002020500BC0000000207 -:10037000020500C000000000020500C400000005E6 -:10038000020500C800000002020500CC00000002C7 -:10039000020500D000000002020500D400000001A8 -:1003A00002050114000000010205011C000000010B -:1003B0000205012000000002020502040000000105 -:1003C0000205020C0000004002050210000000407F -:1003D0000205021C0000002002050220000000139C -:1003E0000205022400000020060502400000000A69 -:1003F00004050280002000000205005000000007F4 -:10040000020500540000000702050058000000002B -:100410000205005C00000008020500600000000109 -:100420000605006400000003020500D80000000675 -:1004300002050004000000010205000800000001A0 -:100440000205000C00000001020500100000000180 -:100450000205001400000001020500180000000160 -:100460000205001C00000001020500200000000140 -:100470000205002400000001020500280000000120 -:100480000205002C00000001020500300000000100 -:1004900002050034000000010205003800000001E0 -:1004A0000205003C000000010205004000000001C0 -:1004B000020500E00000000D020500E80000000059 -:1004C000020500F000000000020500F80000000036 -:1004D000020500E40000002D020500EC00000020F1 -:1004E000020500F400000020020500FC00000020CE -:1004F000020500E00000001D020500E800000010F9 -:10050000020500F000000010020500F800000010D5 -:10051000020500E40000003D020500EC0000003090 -:10052000020500F400000030020500FC000000306D -:10053000020500E00000004D020500E80000004058 -:10054000020500F000000040020500F80000004035 -:10055000020500E40000006D020500EC00000060F0 -:10056000020500F400000060020500FC00000060CD -:10057000020500E00000005D020500E800000050F8 -:10058000020500F000000050020500F800000050D5 -:10059000020500E40000007D020500EC0000007090 -:1005A000020500F400000070020500FC000000706D -:1005B0000406100002000020020600DC000000011A -:1005C000010600D80000000004060200000302201B -:1005D000020600DC00000000010600B80000000078 -:1005E000010600C8000000000206016C00000000C7 -:1005F000010600BC00000000010600CC0000000065 -:1006000002060170000000000718040000910000BD -:10061000081807D800050223071C00002BDC000087 -:10062000071C80002DE90AF8071D00002F521673E1 -:10063000071D800015DB2248081DB0B049EA0225DD -:100640000118000000000000011800040000000074 -:1006500001180008000000000118000C0000000054 -:100660000118001000000000011800140000000034 -:1006700002180020000000010218002400000002FF -:1006800002180028000000030218002C00000000DF -:1006900002180030000000040218003400000001BD -:1006A00002180038000000000218003C00000001A1 -:1006B000021800400000000402180044000000007E -:1006C00002180048000000010218004C000000035E -:1006D0000218005000000000021800540000000141 -:1006E00002180058000000040218005C000000001E -:1006F00002180060000000010218006400000003FE -:1007000002180068000000000218006C00000001E0 -:1007100002180070000000040218007400000000BD -:1007200002180078000000040218007C000000039A -:100730000618008000000002021800A400003FFF1D -:10074000021800A8000003FF0218022400000000A5 -:1007500002180234000000000218024C00000000E1 -:10076000021802E4000000FF061810000000040058 -:10077000021B8BC000000001021B8000000000343F -:10078000021B804000000018021B80800000000C4B -:10079000021B80C0000000200C1B83000007A1206A -:1007A0000A1B8300000001380B1B83000000138824 -:1007B0000A1B8340000000000C1B8340000001F472 -:1007C0000B1B834000000005021B83800007A12053 -:1007D000021B83C0000001F4021B14800000000112 -:1007E0000A1B148000000000061A1000000003B36A -:1007F000041A1ECC00010227061A1ED000000008B1 -:10080000061A2008000000C8061A20000000000296 -:10081000041AAF4000100228061A3718000000041E -:10082000061A371000000002061A500000000002ED -:10083000061A500800000004061A501800000004B0 -:10084000061A502800000004061A50380000000460 -:10085000061A504800000004061A50580000000410 -:10086000061A506800000004061A507800000002C2 -:10087000041A52C000020238061A40500000000656 -:10088000041A40680002023A041A40400004023C84 -:10089000041A800000010240061A800400000003D0 -:1008A000041A801000010241061A8014000000039F -:1008B000041A802000010242061A8024000000036E -:1008C000041A803000010243061A8034000000033D -:1008D000041A804000010244061A8044000000030C -:1008E000041A805000010245061A805400000003DB -:1008F000041A806000010246061A806400000003AA -:10090000041A807000010247061A80740000000378 -:10091000041A808000010248061A80840000000347 -:10092000041A809000010249061A80940000000316 -:10093000041A80A00001024A061A80A400000003E5 -:10094000041A80B00001024B061A80B400000003B4 -:10095000041A80C00001024C061A80C40000000383 -:10096000041A80D00001024D061A80D40000000352 -:10097000041A80E00001024E061A80E40000000321 -:10098000041A80F00001024F061A80F400000003F0 -:10099000041A810000010250061A810400000003BD -:1009A000041A811000010251061A8114000000038C -:1009B000041A812000010252061A8124000000035B -:1009C000041A813000010253061A8134000000032A -:1009D000041A814000010254061A814400000003F9 -:1009E000041A815000010255061A815400000003C8 -:1009F000041A816000010256061A81640000000397 -:100A0000041A817000010257061A81740000000365 -:100A1000041A818000010258061A81840000000334 -:100A2000041A819000010259061A81940000000303 -:100A3000041A81A00001025A061A81A400000003D2 -:100A4000041A81B00001025B061A81B400000003A1 -:100A5000041A81C00001025C061A81C40000000370 -:100A6000041A81D00001025D061A81D4000000033F -:100A7000041A81E00001025E061A81E4000000030E -:100A8000041A81F00001025F061A81F400000003DD -:100A9000041A820000010260061A820400000003AA -:100AA000041A821000010261061A82140000000379 -:100AB000041A822000010262061A82240000000348 -:100AC000041A823000010263061A82340000000317 -:100AD000041A824000010264061A824400000003E6 -:100AE000041A825000010265061A825400000003B5 -:100AF000041A826000010266061A82640000000384 -:100B0000041A827000010267061A82740000000352 -:100B1000041A828000010268061A82840000000321 -:100B2000041A829000010269061A829400000003F0 -:100B3000041A82A00001026A061A82A400000003BF -:100B4000041A82B00001026B061A82B4000000038E -:100B5000041A82C00001026C061A82C4000000035D -:100B6000041A82D00001026D061A82D4000000032C -:100B7000041A82E00001026E061A82E400000003FB -:100B8000041A82F00001026F061A82F400000003CA -:100B9000041A830000010270061A83040000000397 -:100BA000041A831000010271061A83140000000366 -:100BB000041A832000010272061A83240000000335 -:100BC000041A833000010273061A83340000000304 -:100BD000041A834000010274061A834400000003D3 -:100BE000041A835000010275061A835400000003A2 -:100BF000041A836000010276061A83640000000371 -:100C0000041A837000010277061A8374000000033F -:100C1000041A838000010278061A8384000000030E -:100C2000041A839000010279061A839400000003DD -:100C3000041A83A00001027A061A83A400000003AC -:100C4000041A83B00001027B061A83B4000000037B -:100C5000041A83C00001027C061A83C4000000034A -:100C6000041A83D00001027D061A83D40000000319 -:100C7000041A83E00001027E061A83E400000003E8 -:100C8000041A83F00001027F061A83F400000003B7 -:100C9000041A840000010280061A84040000000384 -:100CA000041A841000010281061A84140000000353 -:100CB000041A842000010282061A84240000000322 -:100CC000041A843000010283061A843400000003F1 -:100CD000041A844000010284061A844400000003C0 -:100CE000041A845000010285061A8454000000038F -:100CF000041A846000010286061A8464000000035E -:100D0000041A847000010287061A8474000000032C -:100D1000041A848000010288061A848400000003FB -:100D2000041A849000010289061A849400000003CA -:100D3000041A84A00001028A061A84A40000000399 -:100D4000041A84B00001028B061A84B40000000368 -:100D5000041A84C00001028C061A84C40000000337 -:100D6000041A84D00001028D061A84D40000000306 -:100D7000041A84E00001028E061A84E400000003D5 -:100D8000041A84F00001028F061A84F400000003A4 -:100D9000041A850000010290061A85040000000371 -:100DA000041A851000010291061A85140000000340 -:100DB000041A852000010292061A8524000000030F -:100DC000041A853000010293061A853400000003DE -:100DD000041A854000010294061A854400000003AD -:100DE000041A855000010295061A8554000000037C -:100DF000041A856000010296061A8564000000034B -:100E0000041A857000010297061A85740000000319 -:100E1000041A858000010298061A858400000003E8 -:100E2000041A859000010299061A859400000003B7 -:100E3000041A85A00001029A061A85A40000000386 -:100E4000041A85B00001029B061A85B40000000355 -:100E5000041A85C00001029C061A85C40000000324 -:100E6000041A85D00001029D061A85D400000003F3 -:100E7000041A85E00001029E061A85E400000003C2 -:100E8000041A85F00001029F061A85F40000000391 -:100E9000041A8600000102A0061A8604000000035E -:100EA000041A8610000102A1061A8614000000032D -:100EB000041A8620000102A2061A862400000003FC -:100EC000041A8630000102A3061A863400000003CB -:100ED000041A8640000102A4061A8644000000039A -:100EE000041A8650000102A5061A86540000000369 -:100EF000041A8660000102A6061A86640000000338 -:100F0000041A8670000102A7061A86740000000306 -:100F1000041A8680000102A8061A868400000003D5 -:100F2000041A8690000102A9061A869400000003A4 -:100F3000041A86A0000102AA061A86A40000000373 -:100F4000041A86B0000102AB061A86B40000000342 -:100F5000041A86C0000102AC061A86C40000000311 -:100F6000041A86D0000102AD061A86D400000003E0 -:100F7000041A86E0000102AE061A86E400000003AF -:100F8000041A86F0000102AF061A86F4000000037E -:100F9000041A8700000102B0061A8704000000034B -:100FA000041A8710000102B1061A8714000000031A -:100FB000041A8720000102B2061A872400000003E9 -:100FC000041A8730000102B3061A873400000003B8 -:100FD000041A8740000102B4061A87440000000387 -:100FE000041A8750000102B5061A87540000000356 -:100FF000041A8760000102B6061A87640000000325 -:10100000041A8770000102B7061A877400000003F3 -:10101000041A8780000102B8061A878400000003C2 -:10102000041A8790000102B9061A87940000000391 -:10103000041A87A0000102BA061A87A40000000360 -:10104000041A87B0000102BB061A87B4000000032F -:10105000041A87C0000102BC061A87C400000003FE -:10106000041A87D0000102BD061A87D400000003CD -:10107000041A87E0000102BE061A87E4000000039C -:10108000041A87F0000102BF061A87F4000000036B -:10109000041A8800000102C0061A88040000000338 -:1010A000041A8810000102C1061A88140000000307 -:1010B000041A8820000102C2061A882400000003D6 -:1010C000041A8830000102C3061A883400000003A5 -:1010D000041A8840000102C4061A88440000000374 -:1010E000041A8850000102C5061A88540000000343 -:1010F000041A8860000102C6061A88640000000312 -:10110000041A8870000102C7061A887400000003E0 -:10111000041A8880000102C8061A888400000003AF -:10112000041A8890000102C9061A8894000000037E -:10113000041A88A0000102CA061A88A4000000034D -:10114000041A88B0000102CB061A88B4000000031C -:10115000041A88C0000102CC061A88C400000003EB -:10116000041A88D0000102CD061A88D400000003BA -:10117000041A88E0000102CE061A88E40000000389 -:10118000041A88F0000102CF061A88F40000000358 -:10119000041A8900000102D0061A89040000000325 -:1011A000041A8910000102D1061A891400000003F4 -:1011B000041A8920000102D2061A892400000003C3 -:1011C000041A8930000102D3061A89340000000392 -:1011D000041A8940000102D4061A89440000000361 -:1011E000041A8950000102D5061A89540000000330 -:1011F000041A8960000102D6061A896400000003FF -:10120000041A8970000102D7061A897400000003CD -:10121000041A8980000102D8061A8984000000039C -:10122000041A8990000102D9061A8994000000036B -:10123000041A89A0000102DA061A89A4000000033A -:10124000041A89B0000102DB061A89B40000000309 -:10125000041A89C0000102DC061A89C400000003D8 -:10126000041A89D0000102DD061A89D400000003A7 -:10127000041A89E0000102DE061A89E40000000376 -:10128000041A89F0000102DF061A89F40000000345 -:10129000041A8A00000102E0061A8A040000000312 -:1012A000041A8A10000102E1061A8A1400000003E1 -:1012B000041A8A20000102E2061A8A2400000003B0 -:1012C000041A8A30000102E3061A8A34000000037F -:1012D000041A8A40000102E4061A8A44000000034E -:1012E000041A8A50000102E5061A8A54000000031D -:1012F000041A8A60000102E6061A8A6400000003EC -:10130000041A8A70000102E7061A8A7400000003BA -:10131000041A8A80000102E8061A8A840000000389 -:10132000041A8A90000102E9061A8A940000000358 -:10133000041A8AA0000102EA061A8AA40000000327 -:10134000041A8AB0000102EB061A8AB400000003F6 -:10135000041A8AC0000102EC061A8AC400000003C5 -:10136000041A8AD0000102ED061A8AD40000000394 -:10137000041A8AE0000102EE061A8AE40000000363 -:10138000041A8AF0000102EF061A8AF40000000332 -:10139000041A8B00000102F0061A8B0400000003FF -:1013A000041A8B10000102F1061A8B1400000003CE -:1013B000041A8B20000102F2061A8B24000000039D -:1013C000041A8B30000102F3061A8B34000000036C -:1013D000041A8B40000102F4061A8B44000000033B -:1013E000041A8B50000102F5061A8B54000000030A -:1013F000041A8B60000102F6061A8B6400000003D9 -:10140000041A8B70000102F7061A8B7400000003A7 -:10141000041A8B80000102F8061A8B840000000376 -:10142000041A8B90000102F9061A8B940000000345 -:10143000041A8BA0000102FA061A8BA40000000314 -:10144000041A8BB0000102FB061A8BB400000003E3 -:10145000041A8BC0000102FC061A8BC400000003B2 -:10146000041A8BD0000102FD061A8BD40000000381 -:10147000041A8BE0000102FE061A8BE40000000350 -:10148000041A8BF0000102FF061A8BF4000000031F -:10149000041A8C0000010300061A8C0400000003EB -:1014A000041A8C1000010301061A8C1400000003BA -:1014B000041A8C2000010302061A8C240000000389 -:1014C000041A8C3000010303061A8C340000000358 -:1014D000041A8C4000010304061A8C440000000327 -:1014E000041A8C5000010305061A8C5400000003F6 -:1014F000041A8C6000010306061A8C6400000003C5 -:10150000041A8C7000010307061A8C740000000393 -:10151000041A8C8000010308061A8C840000000362 -:10152000041A8C9000010309061A8C940000000331 -:10153000041A8CA00001030A061A8CA40000000300 -:10154000041A8CB00001030B061A8CB400000003CF -:10155000041A8CC00001030C061A8CC4000000039E -:10156000041A8CD00001030D061A8CD4000000036D -:10157000041A8CE00001030E061A8CE4000000033C -:10158000041A8CF00001030F061A8CF4000000030B -:10159000041A8D0000010310061A8D0400000003D8 -:1015A000041A8D1000010311061A8D1400000003A7 -:1015B000041A8D2000010312061A8D240000000376 -:1015C000041A8D3000010313061A8D340000000345 -:1015D000041A8D4000010314061A8D440000000314 -:1015E000041A8D5000010315061A8D5400000003E3 -:1015F000041A8D6000010316061A8D6400000003B2 -:10160000041A8D7000010317061A8D740000000380 -:10161000041A8D8000010318061A8D84000000034F -:10162000041A8D9000010319061A8D94000000031E -:10163000041A8DA00001031A061A8DA400000003ED -:10164000041A8DB00001031B061A8DB400000003BC -:10165000041A8DC00001031C061A8DC4000000038B -:10166000041A8DD00001031D061A8DD4000000035A -:10167000041A8DE00001031E061A8DE40000000329 -:10168000041A8DF00001031F061A8DF400000003F8 -:10169000041A8E0000010320061A8E0400000003C5 -:1016A000041A8E1000010321061A8E140000000394 -:1016B000041A8E2000010322061A8E240000000363 -:1016C000041A8E3000010323061A8E340000000332 -:1016D000041A8E4000010324061A8E440000000301 -:1016E000041A8E5000010325061A8E5400000003D0 -:1016F000041A8E6000010326061A8E64000000039F -:10170000041A8E7000010327061A8E74000000036D -:10171000041A8E8000010328061A8E84000000033C -:10172000041A8E9000010329061A8E94000000030B -:10173000041A8EA00001032A061A8EA400000003DA -:10174000041A8EB00001032B061A8EB400000003A9 -:10175000041A8EC00001032C061A8EC40000000378 -:10176000041A8ED00001032D061A8ED40000000347 -:10177000041A8EE00001032E061A8EE40000000316 -:10178000041A8EF00001032F061A8EF400000003E5 -:10179000041A8F0000010330061A8F0400000003B2 -:1017A000041A8F1000010331061A8F140000000381 -:1017B000041A8F2000010332061A8F240000000350 -:1017C000041A8F3000010333061A8F34000000031F -:1017D000041A8F4000010334061A8F4400000003EE -:1017E000041A8F5000010335061A8F5400000003BD -:1017F000041A8F6000010336061A8F64000000038C -:10180000041A8F7000010337061A8F74000000035A -:10181000041A8F8000010338061A8F840000000329 -:10182000041A8F9000010339061A8F9400000003F8 -:10183000041A8FA00001033A061A8FA400000003C7 -:10184000041A8FB00001033B061A8FB40000000396 -:10185000041A8FC00001033C061A8FC40000000365 -:10186000041A8FD00001033D061A8FD40000000334 -:10187000041A8FE00001033E061A8FE400000007FF -:10188000041A62C00020033F061AD0000000007254 -:10189000061AD24800000010061AD6B00000002038 -:1018A000061AD47000000090061AD46800000002E6 -:1018B000061AA000000001C4061A30000000001043 -:1018C000061A308000000010061A310000000010D7 -:1018D000061A318000000010061A330000000012C2 -:1018E000061A339000000070061AD4580000000257 -:1018F000061AD34800000002061AD3580000002040 -:10190000061AA710000001C4061A3040000000109B -:10191000061A30C000000010061A31400000001006 -:10192000061A31C000000010061A334800000012E9 -:10193000061A355000000070061AD460000000023C -:10194000061AD35000000002061AD3D80000002067 -:10195000021AAE2000000000061A5000000000022B -:10196000061A508000000012041A40000002035FB3 -:10197000041A63C000020361061A7000000000042C -:10198000061A320000000008021AAE24000000000F -:10199000061A501000000002061A50C8000000127B -:1019A000041A400800020363041A63C800020365B6 -:1019B000061A701000000004061A32200000000809 -:1019C000021AAE2800000000061A50200000000293 -:1019D000061A511000000012041A4010000203679A -:1019E000041A63D000020369061A70200000000484 -:1019F000061A324000000008021AAE2C0000000057 -:101A0000061A503000000002061A51580000001259 -:101A1000041A40180002036B041A63D80002036D15 -:101A2000061A703000000004061A32600000000838 -:101A3000021AAE3000000000061A504000000002FA -:101A4000061A51A000000012041A40200002036F81 -:101A5000041A63E000020371061A704000000004DB -:101A6000061A328000000008021AAE34000000009E -:101A7000061A505000000002061A51E80000001239 -:101A8000041A402800020373041A63E80002037575 -:101A9000061A705000000004061A32A00000000868 -:101AA000021AAE3800000000061A50600000000262 -:101AB000061A523000000012041A40300002037768 -:101AC000041A63F000020379061A70600000000433 -:101AD000061A32C000000008021AAE3C00000000E6 -:101AE000061A507000000002061A52780000001218 -:101AF000041A40380002037B041A63F80002037DD5 -:101B0000061A707000000004061A32E00000000897 -:101B10000200A468000B01C80200A294071D29114D -:101B20000200A298000000000200A29C009C042475 -:101B30000200A2A0000000000200A2A4000002090E -:101B40000200A270000000000200A2740000000069 -:101B50000200A270000000000200A2740000000059 -:101B60000200A270000000000200A2740000000049 -:101B70000200A270000000000200A2740000000039 -:101B8000020160A000000001020160A400000262E6 -:101B9000020160A800000002020160AC0000001811 -:101BA0000201620400000001020100B40000000113 -:101BB000020100B800000001020100DC0000000189 -:101BC0000201010000000001020101040000000107 -:101BD0000201007C003000000201008400000028A7 -:101BE0000201008C0000000002010130000000042E -:101BF0000201025C00000001020103280000000055 -:101C0000020160580000FFFF020160700000000741 -:101C10000201608000000001020105540000003054 -:101C2000020100C400000001020100CC000000011C -:101C3000020100F800000001020100F000000001B4 -:101C4000020100800030000002010088000000282E -:101C500002010090000000000201013400000004B5 -:101C6000020102DC000000010201032C0000000060 -:101C70000201605C0000FFFF0201607400000007C9 -:101C800002016084000000010201056400000030D0 -:101C9000020100C800000001020100D000000001A4 -:101CA000020100FC00000001020100F4000000013C -:101CB000020C100000000028020C20080000021195 -:101CC000020C200C00000200020C20100000020494 -:101CD000020C201C0000FFFF020C20200000FFFF70 -:101CE000020C20240000FFFF020C20280000FFFF50 -:101CF000020C203800000020020C203C00000021D3 -:101D0000020C204000000022020C204400000023AE -:101D1000020C204800000024020C204C000000258A -:101D2000020C205000000026020C20540000002766 -:101D3000020C205800000028020C205C0000002942 -:101D4000020C20600000002A020C20640000002B1E -:101D5000020C20680000002C020C206C0000002DFA -:101D6000020C20700000002E020C20740000002FD6 -:101D7000020C207800000010060C207C00000007F8 -:101D8000020C209800000011020C209C00000012A0 -:101D9000020C20A000000013060C20A40000001D6F -:101DA000020C211800000001020C211C000000019F -:101DB000020C212000000001060C21240000001D5F -:101DC000020C219800000001060C219C0000000775 -:101DD000020C21B800000001020C21BC000000012F -:101DE000020C21C000000001020C21C4000000010F -:101DF000020C21C800000001020C21CC00000001EF -:101E0000020C21D000000001020C21D400000001CE -:101E1000020C21D800000001020C21DC00000001AE -:101E2000020C21E000000001020C21E4000000018E -:101E3000020C21E800000001020C21EC000000016E -:101E4000020C21F000000001020C21F4000000014E -:101E5000020C21F800000001060C21FC0000000724 -:101E6000020C221800000001060C221C00000007D2 -:101E7000020C223807FFFFFF020C223C0000003F4B -:101E8000020C224007FFFFFF020C22440000000F5B -:101E9000010C224800000000010C224C0000000050 -:101EA000010C225000000000010C22540000000030 -:101EB000010C225800000000010C225C0000000010 -:101EC000010C226000000000010C226400000000F0 -:101ED000010C226800000000010C226C00000000D0 -:101EE000010C227000000000010C227400000000B0 -:101EF000010C227800000000010C227C0000000090 -:101F00000C0C2000000003E80A0C20000000000177 -:101F10000B0C20000000000A020C40080000101109 -:101F2000020C400C00001000020C401000001004D5 -:101F3000020C401400001021020C401C0000FFFFA6 -:101F4000020C40200000FFFF020C40240000FFFFB5 -:101F5000020C40280000FFFF020C40380000004641 -:101F6000020C403C00000010060C40400000000243 -:101F7000020C404800000018020C404C000000F029 -:101F8000060C40500000001F020C40CC0000000175 -:101F9000060C40D00000003A020C41B800000001DD -:101FA000060C41BC00000003020C41C80000000107 -:101FB000020C41CC00000001060C41D00000001AC8 -:101FC000020C423807FFFFFF020C423C0000003FBA -:101FD000020C424007FFFFFF020C42440000000FCA -:101FE000010C424800000000010C424C00000000BF -:101FF000010C425000000000010C4254000000009F -:10200000010C425800000000010C425C000000007E -:10201000010C426000000000010C4264000000005E -:10202000010C426800000000010C426C000000003E -:10203000010C427000000000010C4274000000001E -:10204000010C427800000000010C427C00000000FE -:10205000010C4280000000000C0C4000000003E86E -:102060000A0C4000000000010B0C40000000000AB8 -:10207000060D400000000A00020D0044000000327E -:10208000020D008C02150020020D009002150020A8 -:10209000020D009408100000020D009800000033AB -:1020A000020D009C00000002020D00A000000000D4 -:1020B000020D00A400000005020D00A800000005AC -:1020C000060D00AC00000002020D00B4000000028A -:1020D000020D00B800000003020D00BC0000000269 -:1020E000020D00C000000001020D00C80000000247 -:1020F000020D00CC00000002020D015C0000000196 -:10210000020D016400000001020D016800000002E0 -:10211000020D020400000001020D020C000000206C -:10212000020D021000000040020D021400000040E9 -:10213000020D022000000003020D0224000000181E -:10214000060D028000000012040D03000018037F3A -:10215000060D03600000000C020D004C00000001A1 -:10216000020D005000000002020D005400000000AB -:10217000020D005800000008060D005C000000047D -:10218000020D00C400000004020D00040000000164 -:10219000020D000800000001020D000C000000010B -:1021A000020D001000000001020D001400000001EB -:1021B000020D001800000001020D001C00000001CB -:1021C000020D002000000001020D002400000001AB -:1021D000020D002800000001020D002C000000018B -:1021E000020D003000000001020D0034000000016B -:1021F000020D003800000001020D003C000000014B -:10220000020D011400000009020D011C0000000A6B -:10221000020D012400000000020D012C000000004E -:10222000020D013400000000020D013C0000000B13 -:10223000020D014400000000020D011800000029F9 -:10224000020D01200000002A020D012800000020DC -:10225000020D013000000020020D013800000020B6 -:10226000020D01400000002B020D0148000000207B -:10227000020D011400000019020D011C0000001ADB -:10228000020D012400000010020D012C00000010BE -:10229000020D013400000010020D013C0000001B83 -:1022A000020D014400000010020D01180000003969 -:1022B000020D01200000003A020D0128000000304C -:1022C000020D013000000030020D01380000003026 -:1022D000020D01400000003B020D014800000030EB -:1022E000020D011400000049020D011C0000004A0B -:1022F000020D012400000040020D012C00000040EE -:10230000020D013400000040020D013C0000004BB2 -:10231000020D014400000040020D01180000006998 -:10232000020D01200000006A020D0128000000607B -:10233000020D013000000060020D01380000006055 -:10234000020D01400000006B020D0148000000601A -:10235000020D011400000059020D011C0000005A7A -:10236000020D012400000050020D012C000000505D -:10237000020D013400000050020D013C0000005B22 -:10238000020D014400000050020D01180000007908 -:10239000020D01200000007A020D012800000070EB -:1023A000020D013000000070020D013800000070C5 -:1023B000020D01400000007B020D0148000000708A -:1023C000060E200000000800020E004C0000003243 -:1023D000020E009402150020020E00980215002043 -:1023E000020E009C00000030020E00A00810000049 -:1023F000020E00A400000033020E00A8000000300E -:10240000020E00AC00000031020E00B0000000021D -:10241000020E00B400000004020E00B8000000002C -:10242000020E00BC00000002020E00C0000000020C -:10243000020E00C400000000020E00C800000002EE -:10244000020E00CC00000007020E00D000000002C7 -:10245000020E00D400000002020E00D800000001AD -:10246000020E014400000001020E014C00000001B8 -:10247000020E015000000002020E020400000001E2 -:10248000020E020C00000040020E0210000000408C -:10249000020E021C00000004020E022000000020B8 -:1024A000020E02240000000E020E02280000001B93 -:1024B000060E030000000012040E0280001B0397AA -:1024C000060E02EC00000005020E00540000000C95 -:1024D000020E00580000000C020E005C000000001C -:1024E000020E006000000010020E006400000010E8 -:1024F000060E006800000003020E00DC000000036E -:10250000020E000400000001020E0008000000019D -:10251000020E000C00000001020E0010000000017D -:10252000020E001400000001020E0018000000015D -:10253000020E001C00000001020E0020000000013D -:10254000020E002400000001020E0028000000011D -:10255000020E002C00000001020E003000000001FD -:10256000020E003400000001020E003800000001DD -:10257000020E003C00000001020E004000000001BD -:10258000020E004400000001020E01100000000FC6 -:10259000020E011800000000020E012000000000E1 -:1025A000020E012800000000020E01140000002F9E -:1025B000020E011C00000020020E01240000000099 -:1025C000020E012C00000000020E01100000001F8E -:1025D000020E011800000010020E01200000000091 -:1025E000020E012800000000020E01140000003F4E -:1025F000020E011C00000030020E01240000000049 -:10260000020E012C00000000020E01100000004F1D -:10261000020E011800000040020E01200000000020 -:10262000020E012800000000020E01140000006FDD -:10263000020E011C00000060020E012400000000D8 -:10264000020E012C00000000020E01100000005FCD -:10265000020E011800000050020E012000000000D0 -:10266000020E012800000000020E01140000007F8D -:10267000020E011C00000070020E01240000000088 -:10268000020E012C000000000730040000C800000A -:10269000083007D8000503B207340000332C0000CF -:1026A0000734800030AC0CCC07350000353318F807 -:1026B000073580002A7126450736000018DA30E217 -:1026C00008364670373203B40130000000000000C5 -:1026D000013000040000000001300008000000008C -:1026E0000130000C0000000001300010000000006C -:1026F0000130001400000000023000200000000142 -:102700000230002400000002023000280000000314 -:102710000230002C000000000230003000000004F5 -:1027200002300034000000010230003800000000D8 -:102730000230003C000000010230004000000004B4 -:102740000230004400000000023000480000000198 -:102750000230004C00000003023000500000000076 -:102760000230005400000001023000580000000454 -:102770000230005C00000000023000600000000138 -:102780000230006400000003023000680000000016 -:102790000230006C000000010230007000000004F4 -:1027A00002300074000000000230007800000004D5 -:1027B0000230007C000000030630008000000002B0 -:1027C000023000A400003FFF023000A8000003FF19 -:1027D0000230022400000000023002340000000039 -:1027E0000230024C00000000023002E40000FFFF53 -:1027F000063020000000080002338BC000000001FA -:10280000023380000000001A023380400000004EB6 -:102810000233808000000010023380C000000020DE -:102820000C3383000007A1200A3383000000013825 -:102830000B338300000013880A338340000000003C -:102840000C338340000001F40B338340000000058B -:10285000023383800007A120023383C0000001F40B -:1028600002331480000000010A33148000000000CD -:10287000063280000000010206322008000000C875 -:10288000063220000000000204328EA0001003B6C1 -:1028900006323EB00000000606323ED800000002BC -:1028A00006323E800000000A04323EA8000203C641 -:1028B00006323E00000000200632500000000400F6 -:1028C0000632400000000004043274C0000203C855 -:1028D00006324110000000020632D0000000003035 -:1028E0000632DD40000000440632DA00000000D06D -:1028F0000632DEA0000000020632E0000000080000 -:1029000006328450000001180632100000000188D1 -:102910000632500000000020063251000000002066 -:102920000632520000000020063253000000002052 -:10293000063254000000002006325500000000203E -:10294000063256000000002006325700000000202A -:102950000632580000000020063259000000002016 -:1029600006325A000000002006325B000000002002 -:1029700006325C000000002006325D0000000020EE -:1029800006325E000000002006325F0000000020DA -:1029900006328DF00000000204328E00000203CAED -:1029A00006328E08000000020632DE9000000002AF -:1029B00006321C4000000038063288B000000118C2 -:1029C00006321620000001880632508000000020E8 -:1029D00006325180000000200632528000000020A4 -:1029E0000632538000000020063254800000002090 -:1029F000063255800000002006325680000000207C -:102A00000632578000000020063258800000002067 -:102A1000063259800000002006325A800000002053 -:102A200006325B800000002006325C80000000203F -:102A300006325D800000002006325E80000000202B -:102A400006325F800000002006328DF80000000290 -:102A500004328E10000203CC06328E1800000002F1 -:102A60000632DE980000000206321D200000003809 -:102A700002328D50000000000632401000000002BB -:102A800002328D5400000000063240200000000297 -:102A900002328D5800000000063240300000000273 -:102AA00002328D5C0000000006324040000000024F -:102AB00002328D600000000006324050000000022B -:102AC00002328D6400000000063240600000000207 -:102AD00002328D68000000000632407000000002E3 -:102AE00002328D6C000000000632408000000002BF -:102AF000072004000091000008200780001003CE8A -:102B0000072400002B0B00000724800015080AC3CF -:102B10000824AA10692403D001200000000000004E -:102B20000120000400000000012000080000000057 -:102B30000120000C00000000012000100000000037 -:102B4000012000140000000002200020000000010D -:102B500002200024000000020220002800000003E0 -:102B60000220002C000000000220003000000004C1 -:102B700002200034000000010220003800000000A4 -:102B80000220003C00000001022000400000000480 -:102B90000220004400000000022000480000000164 -:102BA0000220004C00000003022000500000000042 -:102BB0000220005400000001022000580000000420 -:102BC0000220005C00000000022000600000000104 -:102BD00002200064000000030220006800000000E2 -:102BE0000220006C000000010220007000000004C0 -:102BF00002200074000000000220007800000004A1 -:102C00000220007C0000000306200080000000027B -:102C1000022000A400003FFF022000A8000003FFE4 -:102C20000220022400000000022002340000000004 -:102C30000220024C00000000022002E40000FFFF1E -:102C4000062020000000080002238BC000000001C5 -:102C500002238000000000100223804000000012C8 -:102C60000223808000000030022380C00000000E9C -:102C70000C2383000007A1200A23830000000138F1 -:102C80000B238300000013880A2383400000000008 -:102C90000C238340000001F40B2383400000000557 -:102CA000022383800007A120022383C0000001F4D7 -:102CB00002231480000000010A2314800000000099 -:102CC000062210000000004206222008000000C872 -:102CD00006222000000000020622B000000000C60C -:102CE0000422B318000503D20622B32C0000000B07 -:102CF0000422B358000503D70622B36C0000000B72 -:102D00000422B398000503DC0622B3AC0000000BDC -:102D10000422B3D8000503E10622B3EC0000000B47 -:102D20000422B418000503E60622B42C0000000BB0 -:102D30000422B458000503EB0622B46C0000000B1B -:102D40000422B498000503F00622B4AC0000000B86 -:102D50000422B4D8000503F50622B4EC0000000BF1 -:102D60000422B518000503FA0622B52C0000000B5A -:102D70000422B558000503FF0622B56C0000000BC5 -:102D80000422B598000504040622B5AC0000000B2F -:102D90000422B5D8000504090622B5EC0000000B9A -:102DA0000422B6180005040E0622B62C0000000B03 -:102DB0000422B658000504130622B66C0000000B6E -:102DC0000422B698000504180622B6AC0000000BD9 -:102DD0000422B6D80005041D0622B6EC0000000B44 -:102DE0000422B718000504220622B72C0000000BAD -:102DF0000422B758000504270622B76C0000000B18 -:102E00000422B7980005042C0622B7AC0000000B82 -:102E10000422B7D8000504310622B7EC0000000BED -:102E20000422B818000504360622B82C0000000B56 -:102E30000422B8580005043B0622B86C0000000BC1 -:102E40000422B898000504400622B8AC0000000B2C -:102E50000422B8D8000504450622B8EC0000000B97 -:102E60000422B9180005044A0622B92C0000000B00 -:102E70000422B9580005044F0622B96C0000000B6B -:102E80000422B998000504540622B9AC0000000BD6 -:102E90000422B9D8000504590622B9EC0000000B41 -:102EA0000422BA180005045E0622BA2C0000000BAA -:102EB0000422BA58000504630622BA6C0000000B15 -:102EC0000422BA98000504680622BAAC0000000B80 -:102ED0000422BAD80005046D0622BAEC00000005F1 -:102EE0000622BB00000000530422BC4C0001047207 -:102EF0000622BC50000000030422BC5C00010473E5 -:102F00000622BC60000000030422BC6C00010474B3 -:102F10000622BC70000000030422BC7C0001047582 -:102F20000622BC80000000030422BC8C0001047651 -:102F30000622BC90000000030422BC9C0001047720 -:102F40000622BCA0000000030422BCAC00010478EF -:102F50000622BCB0000000030422BCBC00010479BE -:102F60000622880000000100062280000000020006 -:102F7000042212700010047A06223000000000C003 -:102F800006226700000001000622900000000400F5 -:102F900004226B080020048A022212C0FFFFFFFFF8 -:102FA000062211E800000002062212C800000009F3 -:102FB000062212EC0000000906228C000000000826 -:102FC0000222114800000000062213200000000623 -:102FD000062233000000000206226040000000309C -:102FE00006228C20000000080222114C0000000084 -:102FF00006221338000000060622330800000002F3 -:10300000062261000000003006228C40000000080B -:10301000022211500000000006221350000000069A -:103020000622331000000002062261C000000030BA -:1030300006228C60000000080222115400000000EB -:103040000622136800000006062233180000000262 -:10305000062262800000003006228C8000000008FA -:103060000222115800000000062213800000000612 -:1030700006223320000000020622634000000030D8 -:1030800006228CA0000000080222115C0000000053 -:1030900006221398000000060622332800000002D2 -:1030A000062264000000003006228CC000000008E8 -:1030B0000222116000000000062213B0000000068A -:1030C0000622333000000002062264C000000030F7 -:1030D00006228CE0000000080222116400000000BB -:1030E000062213C800000006062233380000000242 -:1030F0000622658000000030021610000000002843 -:1031000002170008000000020217002C0000000354 -:103110000217003C000000040217004800000002F3 -:103120000217004C000000900217005000000090B1 -:103130000217005400800090021700580810000089 -:10314000021700600000008A02170064000000807F -:1031500002170068000000810217006C0000008068 -:10316000021700700000000602170078000007D068 -:103170000217007C0000076C02170038007C100466 -:10318000021700040000000F061640240000000291 -:10319000021640700000001C0216420800000001E8 -:1031A0000216421000000001021642200000000139 -:1031B0000216422800000001021642300000000101 -:1031C00002164238000000010216426000000002B0 -:1031D0000C16401C0003D0900A16401C0000009CF6 -:1031E0000B16401C000009C4021640300000000805 -:1031F000021640340000000C021640380000001097 -:1032000002164044000000200216400000000001A9 -:10321000021640D80000000102164008000000011C -:103220000216400C000000010216401000000001D0 -:103230000216424000000000021642480000000052 -:103240000616427000000002021642500000000004 -:1032500002164258000000000616428000000002DC -:1032600002166008000012240216600C0000121002 -:1032700002166010000012140216601C0000FFFF0E -:10328000021660200000FFFF021660240000FFFF0E -:10329000021660280000FFFF0216603800000020C0 -:1032A0000216603C0000002006166040000000028C -:1032B00002166048000000230216604C0000002443 -:1032C000021660500000002502166054000000261F -:1032D00002166058000000270216605C00000029FA -:1032E000021660600000002A021660640000002BD5 -:1032F000021660680000002C0216606C0000002DB1 -:1033000002166070000000EC0216607400000011EC -:1033100002166078000000120616607C0000000FA4 -:10332000021660B800000001021660BC0000000137 -:10333000061660C00000000C021660F000000001DC -:10334000061660F400000031021661B800000001AA -:10335000061661BC0000000D021661F000000001BD -:10336000061661F4000000110216623807FFFFFF25 -:103370000216623C0000003F0216624007FFFFFF9A -:10338000021662440000000F0116624800000000AF -:103390000116624C0000000001166250000000009F -:1033A000011662540000000001166258000000007F -:1033B0000116625C0000000001166260000000005F -:1033C000011662640000000001166268000000003F -:1033D0000116626C0000000001166270000000001F -:1033E00001166274000000000116627800000000FF -:1033F0000116627C000000000C166000000003E86B -:103400000A166000000000010B1660000000000AB0 -:1034100002168040000000060216804400000005ED -:10342000021680480000000A0216804C00000005C9 -:103430000216805400000002021680CC0000000436 -:10344000021680D000000004021680D400000004A0 -:10345000021680D800000004021680DC0000000480 -:10346000021680E000000004021680E40000000460 -:10347000021680E800000004021688040000000420 -:10348000021680300000007C021680340000003DEF -:10349000021680380000003F0216803C0000009CAD -:1034A000021680F000000007061680F400000005F8 -:1034B0000216880C010101010216810800000000BB -:1034C0000216810C000000040216811000000004A6 -:1034D0000216811400000002021688100801200460 -:1034E00002168118000000050216811C000000056C -:1034F000021681200000000502168124000000054C -:103500000216882C200810010216812800000008ED -:103510000216812C00000006021681300000000710 -:1035200002168134000000000216883001010120DB -:1035300006168138000000040216883401010101DA -:1035400002168148000000000216814C00000004B1 -:10355000021681500000000402168154000000028F -:103560000216883808012004021681580000000560 -:103570000216815C00000005021681600000000553 -:1035800002168164000000050216883C2008100124 -:1035900002168168000000080216816C0000000617 -:1035A00002168170000000070216817400000001FD -:1035B00002168840010101200216817800000001F6 -:1035C0000216817C000000010216818000000001CB -:1035D00002168184000000010216884401010101E5 -:1035E00002168188000000010216818C0000000490 -:1035F000021681900000000402168194000000026F -:10360000021688480801200402168198000000056F -:103610000216819C00000005021681A00000000532 -:10362000021681A40000000502168814200810016B -:10363000021681A800000008021681AC00000006F6 -:10364000021681B000000007021681B400000001DC -:103650000216881801010120021681B8000000013D -:10366000021681BC00000001021681C000000001AA -:10367000021681C4000000010216881C010101012C -:10368000021681C800000001021681CC000000046F -:10369000021681D000000004021681D4000000024E -:1036A0000216882008012004021681D800000005B7 -:1036B000021681DC00000005021681E00000000512 -:1036C000021681E40000000502168824200810017B -:1036D000021681E800000008021681EC00000006D6 -:1036E000021681F0000000070216E40C0000000042 -:1036F00002168828010101200616E41000000004CB -:103700000216E000010101010216E42000000000A1 -:103710000216E424000000040216E428000000045D -:103720000216E42C000000020216E0040801200446 -:103730000216E430000000050216E4340000000523 -:103740000216E438000000050216E43C0000000503 -:103750000216E008200810010216E44000000008EC -:103760000216E444000000060216E44800000007C8 -:103770000216E44C000000000216E00C01010120DA -:103780000616E450000000040216E01001010101D9 -:103790000216E460000000000216E4640000000469 -:1037A0000216E468000000040216E46C0000000247 -:1037B0000216E014080120040216E470000000055F -:1037C0000216E474000000050216E478000000050B -:1037D0000216E47C000000050216E0182008100123 -:1037E0000216E480000000080216E48400000006CF -:1037F0000216E488000000070216E48C00000001B5 -:103800000216E01C010101200216E49000000001F4 -:103810000216E494000000010216E4980000000182 -:103820000216E49C000000010216E02001010101E3 -:103830000216E4A0000000010216E4A40000000447 -:103840000216E4A8000000040216E4AC0000000226 -:103850000216E024080120040216E4B0000000056E -:103860000216E4B4000000050216E4B800000005EA -:103870000216E4BC000000050216E0282008100132 -:103880000216E4C0000000080216E4C400000006AE -:103890000216E4C8000000070216E4CC0000000194 -:1038A0000216E02C010101200216E4D00000000104 -:1038B0000216E4D4000000010216E4D80000000162 -:1038C0000216E4DC000000010216E03001010101F3 -:1038D0000216E4E0000000010216E4E40000000427 -:1038E0000216E4E8000000040216E4EC0000000206 -:1038F0000216E034080120040216E4F0000000057E -:103900000216E4F4000000050216E4F800000005C9 -:103910000216E4FC000000050216E0382008100141 -:103920000216E500000000080216E504000000068B -:103930000216E508000000070216E03C0101012024 -:1039400002168240003F003F021682440000000041 -:103950000216E524003F003F0216E52800000000A3 -:1039600002168248000000000216824C003F003F11 -:103970000216E52C000000000216E530003F003F73 -:10398000021682500100010002168254010001005B -:103990000216E534010001000216E53801000100BD -:1039A00006168258000000020216E53C00000000E6 -:1039B0000216E540000000000216826000C000C050 -:1039C0000216826400C000C00216E54400C000C0B8 -:1039D0000216E54800C000C0021682681E001E00E4 -:1039E0000216826C1E001E000216E54C1E001E0010 -:1039F0000216E5501E001E000216827040004000B4 -:103A000002168274400040000216E5544000400057 -:103A10000216E558400040000216827880008000BF -:103A20000216827C800080000216E55C8000800027 -:103A30000216E560800080000216828020002000CF -:103A400002168284200020000216E5642000200077 -:103A50000216E56820002000061682880000000299 -:103A60000216E56C000000000216E5700000000080 -:103A700002168290000000000216829400000000EE -:103A80000216E574000000000216E5780000000050 -:103A900002168298000000000216829C00000000BE -:103AA0000216E57C000000000216E5800000000020 -:103AB000021682A000000000021682A4000000018D -:103AC000061682A80000000A021681F400000C0805 -:103AD000021681F800000040021681FC000001007F -:103AE0000216820000000020021682040000001767 -:103AF00002168208000000800216820C00000200FC -:103B000002168210000000000216821801FF01FF59 -:103B10000216821401FF01FF0216E51001FF01FFEA -:103B20000216E50C01FF01FF0216823C00000013A3 -:103B3000021680900000013F0216806000000140E4 -:103B40000216806400000140061680680000000232 -:103B500002168070000000C0061680740000000786 -:103B60000216809C00000048021680A00000004859 -:103B7000061680A400000002021680AC0000004877 -:103B8000061680B000000007021682380000800090 -:103B900002168234000025E40216809400007FFFA4 -:103BA00002168220000F000F0216821C000F000F69 -:103BB0000216E518000F000F0216E514000F000FA3 -:103BC000021682280000000002168224FFFFFFFF79 -:103BD0000216E520000000000216E51CFFFFFFFFB3 -:103BE0000216E6BC000000000216E6C0000000025B -:103BF0000216E6C4000000010216E6C80000000339 -:103C00000216E6CC000000040216E6D00000000612 -:103C10000216E6D4000000050216E6D800000007F0 -:103C2000021680EC000000FF0214000000000001FA -:103C30000214000C0000000102140040000000010A -:103C40000214004400007FFF0214000C000000007A -:103C500002140000000000000214006C00000000CC -:103C600002140004000000010214003000000001F2 -:103C700002140004000000000214005C00000000B8 -:103C800002140008000000010214003400000001CA -:103C90000214000800000000021400600000000090 -:103CA00006028000000020000202005800000032DE -:103CB000020200A003150020020200A40315002048 -:103CC000020200A801000030020200AC081000004F -:103CD000020200B000000033020200B40000003015 -:103CE000020200B800000031020200BC0000000324 -:103CF000020200C000000006020200C4000000032F -:103D0000020200C800000003020200CC0000000212 -:103D1000020200D000000000020200D400000002F5 -:103D2000020200DC00000000020200E000000006C9 -:103D3000020200E400000004020200E800000002A9 -:103D4000020200EC00000002020200F0000000018C -:103D5000020200FC00000006020201200000000038 -:103D60000202013400000002020201B00000000162 -:103D70000202020C00000001020202140000000115 -:103D80000202021800000002020204040000000106 -:103D90000202040C00000040020204100000004077 -:103DA0000202041C000000040202042000000020A3 -:103DB0000202042400000002020204280000002085 -:103DC000060205000000001204020480002004AA7C -:103DD000020200600000000F020200640000000701 -:103DE00002020068000000000202006C0000000EE9 -:103DF000020200700000000E0602007400000003C2 -:103E0000020200F4000000040202000400000001AD -:103E100002020008000000010202000C0000000184 -:103E20000202001000000001020200140000000164 -:103E300002020018000000010202001C0000000144 -:103E40000202002000000001020200240000000124 -:103E500002020028000000010202002C0000000104 -:103E600002020030000000010202003400000001E4 -:103E700002020038000000010202003C00000001C4 -:103E800002020040000000010202004400000001A4 -:103E900002020048000000010202004C0000000184 -:103EA000020200500000000102020108000000C8E8 -:103EB0000202011800000002020201C4000000001A -:103EC000020201CC00000000020201D40000000246 -:103ED000020201DC00000002020201E4000000FF17 -:103EE000020201EC000000FF0202010000000000DD -:103EF0000202010C000000C80202011C00000002C6 -:103F0000020201C800000000020201D0000000000F -:103F1000020201D800000002020201E000000002DB -:103F2000020201E8000000FF020201F0000000FFB1 -:103F3000020201040000000002020108000000C8A3 -:103F40000202011800000002020201C40000000089 -:103F5000020201CC00000000020201D400000002B5 -:103F6000020201DC00000002020201E4000000FF86 -:103F7000020201EC000000FF02020100000000004C -:103F80000202010C000000C80202011C0000000235 -:103F9000020201C800000000020201D0000000007F -:103FA000020201D800000002020201E0000000024B -:103FB000020201E8000000FF020201F0000000FF21 -:103FC000020201040000000002020108000000C813 -:103FD0000202011800000002020201C400000000F9 -:103FE000020201CC00000000020201D40000000225 -:103FF000020201DC00000002020201E4000000FFF6 -:10400000020201EC000000FF0202010000000000BB -:104010000202010C000000C80202011C00000002A4 -:10402000020201C800000000020201D000000000EE -:10403000020201D800000002020201E000000002BA -:10404000020201E8000000FF020201F0000000FF90 -:10405000020201040000000002020108000000C882 -:104060000202011800000002020201C40000000068 -:10407000020201CC00000000020201D40000000294 -:10408000020201DC00000002020201E4000000FF65 -:10409000020201EC000000FF02020100000000002B -:1040A0000202010C000000C80202011C0000000214 -:1040B000020201C800000000020201D0000000005E -:1040C000020201D800000002020201E0000000022A -:1040D000020201E8000000FF020201F0000000FF00 -:1040E00002020104000000000728040000A10000F3 -:1040F000082807B8000904CA072C000034F700009C -:10410000072C800039250D3E072D000037CD1B8878 -:10411000072D80003292297C072E00001AF33621E9 -:10412000082E4390378E04CC0128000000000000C8 -:104130000128000400000000012800080000000021 -:104140000128000C00000000012800100000000001 -:1041500001280014000000000228002000000001D7 -:1041600002280024000000020228002800000003AA -:104170000228002C0000000002280030000000048B -:10418000022800340000000102280038000000006E -:104190000228003C0000000102280040000000044A -:1041A000022800440000000002280048000000012E -:1041B0000228004C0000000302280050000000000C -:1041C00002280054000000010228005800000004EA -:1041D0000228005C000000000228006000000001CE -:1041E00002280064000000030228006800000000AC -:1041F0000228006C0000000102280070000000048A -:10420000022800740000000002280078000000046A -:104210000228007C00000003062800800000000245 -:10422000022800A400003FFF022800A8000003FFAE -:1042300002280224000000000228023400000000CE -:104240000228024C00000000022802E40000FFFFE8 -:104250000628200000000800022B8BC0000000018F -:10426000022B800000000000022B8040000000189C -:10427000022B80800000000C022B80C00000006632 -:104280000C2B83000007A1200A2B830000000138BB -:104290000B2B8300000013880A2B834000000000D2 -:1042A0000C2B8340000001F40B2B83400000000521 -:1042B000022B83800007A120022B83C0000001F4A1 -:1042C000022B1480000000010A2B14800000000063 -:1042D000062A9AF800000004042A9B08000204CE73 -:1042E000062A9B1000000006062A90800000004865 -:1042F000062A2008000000C8062A2000000000024C -:10430000062A91A800000086062A900000000020DE -:10431000062A93C800000003042A93D4000104D0A5 -:10432000062A9DA800000002042A9498000404D1E3 -:10433000042A9D58000104D5062A9D5C0000001146 -:10434000042ACB20001004D6042A3000000204E620 -:10435000062A300800000100062A40400000001034 -:10436000042A4000001004E8042A8408000204F82B -:10437000062A9DA000000002062AB000000000509E -:10438000062ABB7000000070062AB150000000022F -:10439000062ABB6000000004062AD00000000800C6 -:1043A000062AC00000000150062A94A8000000322E -:1043B000062A502000000002062A503000000002A9 -:1043C000062A500000000002062A501000000002D9 -:1043D000022A520800000001042A9B28000204FA65 -:1043E000062A963800000022042A96C0000104FC28 -:1043F000062A96C400000003062A976800000022DF -:10440000042A97F0000104FD062A97F40000000337 -:10441000062A989800000022042A9920000104FE30 -:10442000062A992400000003062A99C800000022E9 -:10443000042A9A50000104FF062A9A54000000033F -:10444000062AB14000000002062AC54000000150C3 -:10445000062A957000000032062A5028000000024B -:10446000062A503800000002062A50080000000208 -:10447000062A501800000002022A520C0000000117 -:10448000042A9B3000020500062A96D00000002274 -:10449000042A975800010502062A975C00000003D1 -:1044A000062A980000000022042A988800010503CB -:1044B000062A988C00000003062A9930000000228A -:1044C000042A99B800010504062A99BC00000003DB -:1044D000062A9A6000000022042A9AE800010505D5 -:1044E000062A9AEC00000003062AB14800000002E8 -:1044F000022ACA8000000000042A9B38001005062A -:10450000062A50480000000E022ACA84000000005B -:10451000042A9B7800100516062A50800000000E21 -:10452000022ACA8800000000042A9BB80010052651 -:10453000062A50B80000000E022ACA8C00000000B3 -:10454000042A9BF800100536062A50F00000000EE1 -:10455000022ACA9000000000042A9C380010054678 -:10456000062A51280000000E022ACA94000000000A -:10457000042A9C7800100556062A51600000000E9F -:10458000022ACA9800000000042A9CB800100566A0 -:10459000062A51980000000E022ACA9C0000000062 -:1045A000042A9CF800100576062A51D00000000E5F -:1045B000021010080000000102101050000000015D -:1045C000021010000003D000021010040000003D93 -:1045D0000910180002000586091011000010078656 -:1045E0000610114000000008091011600010079625 -:1045F000061011A00000001806102400000000E0C2 -:104600000210201C00000000021020200000000109 -:10461000021020C00000000202102004000000016F -:10462000021020080000000109103C00000507A648 -:1046300009103800000507AB09103820000507B045 -:1046400006104C000000010002104028000000107D -:104650000210404400003FFF0210405800280000B4 -:10466000021040840084924A02104058000000006A -:104670000210800000001080021080AC00000000DA -:1046800002108038000000100210810000000000BD -:10469000061081200000000202108008000002B510 -:1046A0000210801000000000061082000000004A86 -:1046B000021081080001FFFF061081400000000287 -:1046C0000210800000001A800610900000000024F4 -:1046D000061091200000004A061093700000004A66 -:1046E000061095C00000004A0210800400001080EF -:1046F000021080B0000000010210803C0000001099 -:104700000210810400000000061081280000000251 -:104710000210800C000002B502108014000000009E -:10472000061084000000004A0210810C0001FFFF07 -:1047300006108148000000020210800400001A8068 -:104740000610909000000024061092480000004AD5 -:10475000061094980000004A061096E80000004AEF -:104760000210800000001080021080AC00000002E7 -:1047700002108038000000100210810000000000CC -:10478000061081200000000202108008000002B51F -:104790000210801000000000061082000000004A95 -:1047A000021081080001FFFF061081400000000296 -:1047B0000210800000001A80061090000000002403 -:1047C000061091200000004A061093700000004A75 -:1047D000061095C00000004A0210800400001080FE -:1047E000021080B0000000030210803C00000010A6 -:1047F0000210810400000000061081280000000261 -:104800000210800C000002B50210801400000000AD -:10481000061084000000004A0210810C0001FFFF16 -:1048200006108148000000020210800400001A8077 -:104830000610909000000024061092480000004AE4 -:10484000061094980000004A061096E80000004AFE -:104850000210800000001080021080AC00000004F4 -:1048600002108038000000100210810000000000DB -:10487000061081200000000202108008000002B52E -:104880000210801000000000061082000000004AA4 -:10489000021081080001FFFF0610814000000002A5 -:1048A0000210800000001A80061090000000002412 -:1048B000061091200000004A061093700000004A84 -:1048C000061095C00000004A02108004000010800D -:1048D000021080B0000000050210803C00000010B3 -:1048E0000210810400000000061081280000000270 -:1048F0000210800C000002B50210801400000000BD -:10490000061084000000004A0210810C0001FFFF25 -:1049100006108148000000020210800400001A8086 -:104920000610909000000024061092480000004AF3 -:10493000061094980000004A061096E80000004A0D -:104940000210800000001080021080AC0000000601 -:1049500002108038000000100210810000000000EA -:10496000061081200000000202108008000002B53D -:104970000210801000000000061082000000004AB3 -:10498000021081080001FFFF0610814000000002B4 -:104990000210800000001A80061090000000002421 -:1049A000061091200000004A061093700000004A93 -:1049B000061095C00000004A02108004000010801C -:1049C000021080B0000000070210803C00000010C0 -:1049D000021081040000000006108128000000027F -:1049E0000210800C000002B50210801400000000CC -:1049F000061084000000004A0210810C0001FFFF35 -:104A000006108148000000020210800400001A8095 -:104A10000610909000000024061092480000004A02 -:104A2000061094980000004A061096E80000004A1C -:104A3000021205B0000000010212049000E383405E -:104A40000212051400003C100212066C0000000166 -:104A5000021206700000000002120494FFFFFFFF24 -:104A600002120498FFFFFFFF0212049CFFFFFFFFEA -:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA -:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA -:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82 -:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A -:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A -:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 -:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 -:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 -:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 -:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 -:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 -:104B200002120504FFFFFFFF02120508FFFFFFFF4F -:104B30000212050CFFFFFFFF02120510FFFFFFFF2F -:104B4000021204D4FF809000021204B4F00050005E -:104B5000021204B8F00010000212039000000008D6 -:104B60000212039C00000008021203A000000008CB -:104B7000021203A400000002021203BC00000004A1 -:104B8000021203C000000005021203C4000000046A -:104B9000021203D0000000000212036C00000001AA -:104BA000021203680000003F021201BC0000004036 -:104BB000021201C000001808021201C4000008031C -:104BC000021201C800000803021201CC00000040DC -:104BD000021201D000000003021201D400000803F9 -:104BE000021201D800000803021201DC00000803D1 -:104BF000021201E000010003021201E400000803B8 -:104C0000021201E800000803021201EC0000000398 -:104C1000021201F000000003021201F40000000380 -:104C2000021201F800000003021201FC0000000360 -:104C3000021202000000000302120204000000033E -:104C400002120208000000030212020C000000031E -:104C500002120210000000030212021400000003FE -:104C600002120218000000030212021C00000003DE -:104C700002120220000000030212022400000003BE -:104C800002120228000024030212022C0000002F4E -:104C90000212023000000009021202340000001962 -:104CA00002120238000001840212023C000001835B -:104CB0000212024000000306021202440000001922 -:104CC00002120248000000060212024C0000030615 -:104CD00002120250000003060212025400000306F2 -:104CE0000212025800000C860212025C0000030649 -:104CF00002120260000003060212026400000006B5 -:104D000002120268000000060212026C0000000697 -:104D10000212027000000006021202740000000677 -:104D200002120278000000060212027C0000000657 -:104D30000212028000000006021202840000000637 -:104D400002120288000000060212028C0000000617 -:104D500002120290000000060212029400000006F7 -:104D600002120298000000060212029C00000006D7 -:104D7000021202A000000306021202A400000013A7 -:104D8000021202A800000006021202B00000100485 -:104D9000021202B400001004021203240010644046 -:104DA0000212032800106440021205B40000000142 -:104DB000021201B0000000010600A0000000000C7B -:104DC0000200A050000000000200A05400000000FB -:104DD0000200A0EC555400000200A0F055555555B6 -:104DE0000200A0F4000055550200A0F8F0000000F9 -:104DF0000200A0FC555400000200A1005555555575 -:104E00000200A104000055550200A108F0000000B6 -:104E10000200A18C555400000200A1905555555533 -:104E20000200A194000055550200A198F000000076 -:104E30000200A19C000000000200A1A000010000EF -:104E40000200A1A4000050140200A1A8000000006C -:104E50000200A45C00000C000200A61C000000037D -:104E60000200A06CFF5C00000200A070FFF55FFF75 -:104E70000200A0740000FFFF0200A078F00003E031 -:104E80000200A07C000000000200A0800000A00042 -:104E90000600A084000000050200A0980FE00000BA -:104EA0000600A09C000000070200A0B8000004005B -:104EB0000600A0BC000000030200A0C80000100013 -:104EC0000600A0CC000000030200A0D800004000B3 -:104ED0000600A0DC000000030200A0E800010000C2 -:104EE0000600A22C000000040200A10CFF5C0000E0 -:104EF0000200A110FFF55FFF0200A1140000FFFFF8 -:104F00000200A118F00003E00200A11C0000000054 -:104F10000200A1200000A0000600A124000000055E -:104F20000200A1380FE000000600A13C00000007CD -:104F30000200A158000008000600A15C0000000368 -:104F40000200A168000020000600A16C0000000320 -:104F50000200A178000080000600A17C0000000390 -:104F60000200A188000200000600A23C000000042C -:104F70000200A030000000000200A0340000000089 -:104F80000200A038000000000200A03C0000000069 -:104F90000200A040000000000200A0440000000049 -:104FA0000200A048000000000200A04C0000000029 -:104FB00000000000000000000000003000000000C1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE0000000000000300031000000000000000060 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:10501000003100520000000000000000000000000D -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000052008995 -:1050400000000000000000000089008D008D00912C -:1050500000910095009500990099009D009D00A188 -:1050600000A100A500A500A900A900AE00AE00B1F6 -:1050700000B100B4000000000000000000000000CB -:105080000000000000000000000000000000000020 -:105090000000000000B40309030903130313031DF8 -:1050A000031D03240324032B032B03320332033990 -:1050B00003390340034003470347034E034E0355A0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:105170000355035B0000000000000000035B035CBC -:10518000035C035D035D035E035E035F035F036017 -:1051900003600361036103620362036300000000B4 -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000363036D036D037B1B -:1051D000037B0389000000000000000000000000C5 -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:105220000389038A00000000000000000000000065 -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000038A03D6F8 -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000003D604010000000050 -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000040104330000000000000000C2 -:1052B0000433043A043A0441044104480448044FC6 -:1052C000044F04560456045D045D04640464046BD6 -:1052D000046B04A4000000000000000004A404A863 -:1052E00004A804AC04AC04B004B004B404B404B81E -:1052F00004B804BC04BC04C004C004C404C4051342 -:105300000513052A052A05410541054305430545C1 -:1053100005450547054705490549054B054B054D1D -:10532000054D054F054F0551055105E805E805E90F -:1053300005E905EA05EA05EF05EF05F405F405F9C9 -:1053400005F905FE05FE0603060306080608060D18 -:10535000060D0612061206130000000000000000F1 -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:1053800006130624000000000000000000000000DA -:10539000000000000000000000000000000000000D -:1053A0000000000000000000000000000624063994 -:1053B0000639063C063C063F0000000000000000E5 -:1053C00000000000000000000000000000000000DD -:1053D0000000000000000000063F0675000000000D -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:1054000000000000067507780000000000000000A2 -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:105430000778077F077F078307830787000000003F -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000078707C8EF -:10546000000000000000000007C807D107D107DADC -:1054700007DA07E307E307EC07EC07F507F507FE94 -:1054800007FE080708070810081008670867087C67 -:10549000087C089108910894089408970897089A3E -:1054A000089A089D089D08A008A008A308A308A6BC -:1054B00008A608A908A908B2000000000000000022 -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00008B208B800000000000000000000000042 -:1054F00000000000000000000000000000000000AC -:1055000000000000000000000000000008B808BB18 -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000008BB08C100000000DF -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:1055700008C108D008D008DF08DF08EE08EE08FDF3 -:1055800008FD090C090C091B091B092A092A0939FC -:10559000093909AA00000000000000000000000016 -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000009AA09BF70 -:1055C00009BF09D009D009E109E109E209E209E3CB -:1055D00009E309E409E409E509E509E609E609E75B -:1055E00009E709E809E809E90000000000000000F7 -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C000000000000000000000010000000204C013 -:1056D0000003098000040E4000051300000617C0F7 -:1056E00000071C800008214000092600000A2AC08B -:1056F000000B2F80000C3440000D3900000E3DC01F -:10570000000F42800010474000114C00001250C0B2 -:105710000013558000145A4000155F00001663C046 -:105720000017688000186D4000197200001A76C0DA -:10573000001B7B80001C8040001D8500001E89C06E -:10574000001F8E80000093400000200000004000F9 -:1057500000006000000080000000A0000000C00009 -:105760000000E000000100000001200000014000F6 -:1057700000016000000180000001A0000001C000E5 -:105780000001E000000200000002200000024000D2 -:1057900000026000000280000002A0000002C000C1 -:1057A0000002E000000300000003200000034000AE -:1057B00000036000000380000003A0000003C0009D -:1057C0000003E0000004000000042000000440008A -:1057D00000046000000480000004A0000004C00079 -:1057E0000004E00000050000000520000005400066 -:1057F00000056000000580000005A0000005C00055 -:105800000005E00000060000000620000006400041 -:1058100000066000000680000006A0000006C00030 -:105820000006E0000007000000072000000740001D -:1058300000076000000780000007A0000007C0000C -:105840000007E000000800000008200000084000F9 -:1058500000086000000880000008A0000008C000E8 -:105860000008E000000900000009200000094000D5 -:1058700000096000000980000009A0000009C000C4 -:105880000009E000000A0000000A2000000A4000B1 -:10589000000A6000000A8000000AA000000AC000A0 -:1058A000000AE000000B0000000B2000000B40008D -:1058B000000B6000000B8000000BA000000BC0007C -:1058C000000BE000000C0000000C2000000C400069 -:1058D000000C6000000C8000000CA000000CC00058 -:1058E000000CE000000D0000000D2000000D400045 -:1058F000000D6000000D8000000DA000000DC00034 -:10590000000DE000000E0000000E2000000E400020 -:10591000000E6000000E8000000EA000000EC0000F -:10592000000EE000000F0000000F2000000F4000FC -:10593000000F6000000F8000000FA000000FC000EB -:10594000000FE000001000000010200000104000D8 -:1059500000106000001080000010A0000010C000C7 -:105960000010E000001100000011200000114000B4 -:1059700000116000001180000011A0000011C000A3 -:105980000011E00000120000001220000012400090 -:1059900000126000001280000012A0000012C0007F -:1059A0000012E0000013000000132000001340006C -:1059B00000136000001380000013A0000013C0005B -:1059C0000013E00000140000001420000014400048 -:1059D00000146000001480000014A0000014C00037 -:1059E0000014E00000150000001520000015400024 -:1059F00000156000001580000015A0000015C00013 -:105A00000015E000001600000016200000164000FF -:105A100000166000001680000016A0000016C000EE -:105A20000016E000001700000017200000174000DB -:105A300000176000001780000017A0000017C000CA -:105A40000017E000001800000018200000184000B7 -:105A500000186000001880000018A0000018C000A6 -:105A60000018E00000190000001920000019400093 -:105A700000196000001980000019A0000019C00082 -:105A80000019E000001A0000001A2000001A40006F -:105A9000001A6000001A8000001AA000001AC0005E -:105AA000001AE000001B0000001B2000001B40004B -:105AB000001B6000001B8000001BA000001BC0003A -:105AC000001BE000001C0000001C2000001C400027 -:105AD000001C6000001C8000001CA000001CC00016 -:105AE000001CE000001D0000001D2000001D400003 -:105AF000001D6000001D8000001DA000001DC000F2 -:105B0000001DE000001E0000001E2000001E4000DE -:105B1000001E6000001E8000001EA000001EC000CD -:105B2000001EE000001F0000001F2000001F4000BA -:105B3000001F6000001F8000001FA000001FC000A9 -:105B4000001FE00000200000002020000020400096 -:105B500000206000002080000020A0000020C00085 -:105B60000020E00000210000002120000021400072 -:105B700000216000002180000021A0000021C00061 -:105B80000021E0000022000000222000002240004E -:105B900000226000002280000022A0000022C0003D -:105BA0000022E0000023000000232000002340002A -:105BB00000236000002380000023A0000023C00019 -:105BC0000023E00000240000002420000024400006 -:105BD00000246000002480000024A0000024C000F5 -:105BE0000024E000002500000025200000254000E2 -:105BF00000256000002580000025A0000025C000D1 -:105C00000025E000002600000026200000264000BD -:105C100000266000002680000026A0000026C000AC -:105C20000026E00000270000002720000027400099 -:105C300000276000002780000027A0000027C00088 -:105C40000027E00000280000002820000028400075 -:105C500000286000002880000028A0000028C00064 -:105C60000028E00000290000002920000029400051 -:105C700000296000002980000029A0000029C00040 -:105C80000029E000002A0000002A2000002A40002D -:105C9000002A6000002A8000002AA000002AC0001C -:105CA000002AE000002B0000002B2000002B400009 -:105CB000002B6000002B8000002BA000002BC000F8 -:105CC000002BE000002C0000002C2000002C4000E5 -:105CD000002C6000002C8000002CA000002CC000D4 -:105CE000002CE000002D0000002D2000002D4000C1 -:105CF000002D6000002D8000002DA000002DC000B0 -:105D0000002DE000002E0000002E2000002E40009C -:105D1000002E6000002E8000002EA000002EC0008B -:105D2000002EE000002F0000002F2000002F400078 -:105D3000002F6000002F8000002FA000002FC00067 -:105D4000002FE00000300000003020000030400054 -:105D500000306000003080000030A0000030C00043 -:105D60000030E00000310000003120000031400030 -:105D700000316000003180000031A0000031C0001F -:105D80000031E0000032000000322000003240000C -:105D900000326000003280000032A0000032C000FB -:105DA0000032E000003300000033200000334000E8 -:105DB00000336000003380000033A0000033C000D7 -:105DC0000033E000003400000034200000344000C4 -:105DD00000346000003480000034A0000034C000B3 -:105DE0000034E000003500000035200000354000A0 -:105DF00000356000003580000035A0000035C0008F -:105E00000035E0000036000000362000003640007B -:105E100000366000003680000036A0000036C0006A -:105E20000036E00000370000003720000037400057 -:105E300000376000003780000037A0000037C00046 -:105E40000037E00000380000003820000038400033 -:105E500000386000003880000038A0000038C00022 -:105E60000038E0000039000000392000003940000F -:105E700000396000003980000039A0000039C000FE -:105E80000039E000003A0000003A2000003A4000EB -:105E9000003A6000003A8000003AA000003AC000DA -:105EA000003AE000003B0000003B2000003B4000C7 -:105EB000003B6000003B8000003BA000003BC000B6 -:105EC000003BE000003C0000003C2000003C4000A3 -:105ED000003C6000003C8000003CA000003CC00092 -:105EE000003CE000003D0000003D2000003D40007F -:105EF000003D6000003D8000003DA000003DC0006E -:105F0000003DE000003E0000003E2000003E40005A -:105F1000003E6000003E8000003EA000003EC00049 -:105F2000003EE000003F0000003F2000003F400036 -:105F3000003F6000003F8000003FA000003FC00025 -:105F4000003FE000003FE00100000000000001FF12 -:105F50000000020000007FF800007FF80000014010 -:105F600000003500000000010000FF0000000000FC -:105F70000000FF00000000000000FF000000000023 -:105F80000000FF00000000000000FF000000000013 -:105F90000000FF00000000000000FF000000000003 -:105FA0000000FF000000000000000000140AFF00D5 -:105FB00000000001000000000020100100000000AF -:105FC0000100900000000100000090020000900419 -:105FD00000009006000090080000900A0000900C5D -:105FE0000000900E0000901000009012000090142D -:105FF00000009016000090180000901A0000901CFD -:106000000000901E000090200000902200009024CC -:1060100000009026000090280000902A0000902C9C -:106020000000902E0000903000009032000090346C -:1060300000009036000090380000903A0000903C3C -:106040000000903E0000904000009042000090440C -:1060500000009046000090480000904A0000904CDC -:106060000000904E000090500000905200009054AC -:1060700000009056000090580000905A0000905C7C -:106080000000905E0000906000009062000090644C -:1060900000009066000090680000906A0000906C1C -:1060A0000000906E000090700000907200009074EC -:1060B00000009076000090780000907A0000907CBC -:1060C0000000907E0000908000009082000090848C -:1060D00000009086000090880000908A0000908C5C -:1060E0000000908E0000909000009092000090942C -:1060F00000009096000090980000909A0000909CFC -:106100000000909E000090A0000090A2000090A4CB -:10611000000090A6000090A8000090AA000090AC9B -:10612000000090AE000090B0000090B2000090B46B -:10613000000090B6000090B8000090BA000090BC3B -:10614000000090BE000090C0000090C2000090C40B -:10615000000090C6000090C8000090CA000090CCDB -:10616000000090CE000090D0000090D2000090D4AB -:10617000000090D6000090D8000090DA000090DC7B -:10618000000090DE000090E0000090E2000090E44B -:10619000000090E6000090E8000090EA000090EC1B -:1061A000000090EE000090F0000090F2000090F4EB -:1061B000000090F6000090F8000090FA000090FCBB -:1061C000000090FE00009100000091020000910488 -:1061D00000009106000091080000910A0000910C57 -:1061E0000000910E00009110000091120000911427 -:1061F00000009116000091180000911A0000911CF7 -:106200000000911E000091200000912200009124C6 -:1062100000009126000091280000912A0000912C96 -:106220000000912E00009130000091320000913466 -:1062300000009136000091380000913A0000913C36 -:106240000000913E00009140000091420000914406 -:1062500000009146000091480000914A0000914CD6 -:106260000000914E000091500000915200009154A6 -:1062700000009156000091580000915A0000915C76 -:106280000000915E00009160000091620000916446 -:1062900000009166000091680000916A0000916C16 -:1062A0000000916E000091700000917200009174E6 -:1062B00000009176000091780000917A0000917CB6 -:1062C0000000917E00009180000091820000918486 -:1062D00000009186000091880000918A0000918C56 -:1062E0000000918E00009190000091920000919426 -:1062F00000009196000091980000919A0000919CF6 -:106300000000919E000091A0000091A2000091A4C5 -:10631000000091A6000091A8000091AA000091AC95 -:10632000000091AE000091B0000091B2000091B465 -:10633000000091B6000091B8000091BA000091BC35 -:10634000000091BE000091C0000091C2000091C405 -:10635000000091C6000091C8000091CA000091CCD5 -:10636000000091CE000091D0000091D2000091D4A5 -:10637000000091D6000091D8000091DA000091DC75 -:10638000000091DE000091E0000091E2000091E445 -:10639000000091E6000091E8000091EA000091EC15 -:1063A000000091EE000091F0000091F2000091F4E5 -:1063B000000091F6000091F8000091FA000091FCB5 -:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A -:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD -:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C -:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C -:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C -:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C -:10644000FFFFFFFF0000000300BEBC2000000000B3 -:10645000000000050000000300BEBC20000000009A -:10646000000000050000000300BEBC20000000008A -:10647000000000050000000300BEBC20000000007A -:10648000000000050000000300BEBC20000000006A -:10649000000000050000000300BEBC20000000005A -:1064A000000000050000000300BEBC20000000004A -:1064B000000000050000000300BEBC20000000003A -:1064C0000000000500002000000040C000006180C6 -:1064D000000082400000A3000000C3C00000E48070 -:1064E0000001054000012600000146C00001678050 -:1064F000000188400001A9000001C9C00001EA8034 -:1065000000020B4000022C0000024CC000026D8013 -:1065100000028E400002AF000002CFC00002F080F7 -:10652000000011400000800000010380000187008E -:1065300000020A8000028E00000311800003950013 -:106540000004188000049C0000051F800005A300C3 -:10655000000626800006AA0000072D800007B10073 -:10656000000834800008B80000093B800009BF0023 -:10657000000A4280000AC600000B4980000BCD00D3 -:10658000000C5080000CD400000D578000005B0010 -:1065900000007FF800007FF8000000D50000150023 -:1065A0000000FF00000000000000FF0000000000ED -:1065B0000000FF00000000000000FF0000000000DD -:1065C0000000FF00000000000000FF0000000000CD -:1065D0000000FF00000000000000FF0000000000BD -:1065E000000019000000000000000000FFFFFFFF96 -:1065F0000000000003938700000000000393870061 -:1066000000007FF800007FF80000069200001500EF -:106610000000FF000FFFFFFF0000FF000FFFFFFF64 -:10662000000000FF0000FF000FFFFFFF0000FF0061 -:106630000FFFFFFF000000FF0000FF000FFFFFFF44 -:106640000000FF000FFFFFFF000000FF0000FF0041 -:106650000FFFFFFF0000FF000FFFFFFF000000FF24 -:106660000000FF000FFFFFFF0000FF000FFFFFFF14 -:10667000000000FF0000FF000FFFFFFF0000FF0011 -:106680000FFFFFFF000000FF0000FF000FFFFFFFF4 -:106690000000FF000FFFFFFF000000FF0000FF00F1 -:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4 -:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4 -:1066C000000000FF0000FF000FFFFFFF0000FF00C1 -:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4 -:1066E0000000FF000FFFFFFF000000FF0000FF00A1 -:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84 -:106700000000FF000FFFFFFF0000FF000FFFFFFF73 -:10671000000000FF0000FF000FFFFFFF0000FF0070 -:106720000FFFFFFF000000FF0000FF000FFFFFFF53 -:106730000000FF000FFFFFFF000000FF0000FF0050 -:106740000FFFFFFF0000FF000FFFFFFF000000FF33 -:106750000000FF000FFFFFFF0000FF000FFFFFFF23 -:10676000000000FF0000FF000FFFFFFF0000FF0020 -:106770000FFFFFFF000000FF0000FF000FFFFFFF03 -:106780000000FF000FFFFFFF000000FF0000FF0000 -:106790000FFFFFFF0000FF000FFFFFFF000000FFE3 -:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3 -:1067B000000000FF0000FF000FFFFFFF0000FF00D0 -:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3 -:1067D0000000FF000FFFFFFF000000FF0000FF00B0 -:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93 -:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83 -:10680000000000FF0000FF000FFFFFFF0000FF007F -:106810000FFFFFFF000000FF0000FF000FFFFFFF62 -:106820000000FF000FFFFFFF000000FF0000FF005F -:106830000FFFFFFF0000FF000FFFFFFF000000FF42 -:106840000000FF000FFFFFFF0000FF000FFFFFFF32 -:10685000000000FF0000FF000FFFFFFF0000FF002F -:106860000FFFFFFF000000FF0000FF000FFFFFFF12 -:106870000000FF000FFFFFFF000000FF0000FF000F -:106880000FFFFFFF0000FF000FFFFFFF000000FFF2 -:10689000000000FF000000FF000000FF000000FFFC -:1068A000000000FF000000FF000000FF000000FFEC -:1068B0000000FF00000000000000FF0000000000DA -:1068C0000000FF00000000000000FF0000000000CA -:1068D0000000FF00000000000000FF0000000000BA -:1068E0000000FF00000000000000FF0000000000AA -:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 -:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 -:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 -:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 -:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 -:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 -:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 -:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 -:106970000000100000002080000031000000418075 -:10698000000052000000628000007300000083805D -:10699000000094000000A4800000B5000000C58045 -:1069A0000000D6000000E6800000F700000107802C -:1069B0000001180000012880000139000001498011 -:1069C00000015A0000016A8000017B0000018B80F9 -:1069D00000019C000001AC800001BD000001CD80E1 -:1069E0000001DE000001EE800001FF0000000F80CA -:1069F00000007FF800007FF8000003400000150051 -:106A000010000000000028AD000100010022000677 -:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41 -:106A20000000FF00000000000000FF000000000068 -:106A30000000FF00000000000000FF000000000058 -:106A40000000FF00000000000000FF000000000048 -:106A50000000FF00000000000000FF000000000038 -:106A60000000000000000001CCCC0201CCCCCCCC5A -:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80 -:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70 -:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60 -:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F -:106AB000000E0000011600D6002625A0002625A005 -:106AC000002625A0002625A000720000012300F367 -:106AD000002625A0002625A0002625A0002625A00A -:106AE0000000FFFF000000000000FFFF00000000AA -:106AF0000000FFFF000000000000FFFF000000009A -:106B00000000FFFF000000000000FFFF0000000089 -:106B10000000FFFF000000000000FFFF0000000079 -:106B20000000FFFF000000000000FFFF0000000069 -:106B30000000FFFF000000000000FFFF0000000059 -:106B40000000FFFF000000000000FFFF0000000049 -:106B50000000FFFF000000000000FFFF0000000039 -:106B60000000FFFF000000000000FFFF0000000029 -:106B70000000FFFF000000000000FFFF0000000019 -:106B80000000FFFF000000000000FFFF0000000009 -:106B90000000FFFF000000000000FFFF00000000F9 -:106BA0000000FFFF000000000000FFFF00000000E9 -:106BB0000000FFFF000000000000FFFF00000000D9 -:106BC0000000FFFF000000000000FFFF00000000C9 -:106BD0000000FFFF000000000000FFFF00000000B9 -:106BE0000000FFFF000000000000FFFF00000000A9 -:106BF0000000FFFF000000000000FFFF0000000099 -:106C00000000FFFF000000000000FFFF0000000088 -:106C10000000FFFF000000000000FFFF0000000078 -:106C20000000FFFF000000000000FFFF0000000068 -:106C30000000FFFF000000000000FFFF0000000058 -:106C40000000FFFF000000000000FFFF0000000048 -:106C50000000FFFF000000000000FFFF0000000038 -:106C60000000FFFF000000000000FFFF0000000028 -:106C70000000FFFF000000000000FFFF0000000018 -:106C80000000FFFF000000000000FFFF0000000008 -:106C90000000FFFF000000000000FFFF00000000F8 -:106CA0000000FFFF000000000000FFFF00000000E8 -:106CB0000000FFFF000000000000FFFF00000000D8 -:106CC0000000FFFF000000000000FFFF00000000C8 -:106CD0000000FFFF000000000000FFFF00000000B8 -:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329 -:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66 -:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB -:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44 -:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316 -:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23 -:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC -:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC -:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA -:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD -:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2 -:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5 -:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304 -:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85 -:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7 -:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45 -:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328 -:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65 -:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389 -:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43 -:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315 -:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22 -:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB -:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB -:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9 -:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC -:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1 -:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4 -:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304 -:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84 -:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386 -:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44 -:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC -:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98 -:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB -:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76 -:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B -:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55 -:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B -:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33 -:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B -:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F -:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B -:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7 -:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B -:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7 -:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB -:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77 -:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5 -:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63 -:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387 -:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41 -:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313 -:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20 -:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9 -:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9 -:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7 -:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA -:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B -:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5 -:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD -:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5 -:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3 -:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42 -:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4 -:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62 -:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367 -:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40 -:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312 -:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F -:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396 -:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C -:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6 -:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9 -:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE -:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1 -:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320 -:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81 -:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9 -:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75 -:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9 -:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95 -:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8 -:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73 -:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398 -:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52 -:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378 -:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30 -:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358 -:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C -:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338 -:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4 -:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318 -:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4 -:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8 -:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74 -:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8 -:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94 -:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7 -:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72 -:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397 -:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51 -:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377 -:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F -:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357 -:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B -:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337 -:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3 -:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317 -:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3 -:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7 -:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73 -:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7 -:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93 -:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6 -:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71 -:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396 -:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50 -:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376 -:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E -:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356 -:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A -:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336 -:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2 -:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316 -:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2 -:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6 -:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72 -:1074E000000C0000000700C000028130000B815832 -:1074F0000002021000010230000F024000010330C0 -:10750000000C0000000800C000028140000B8168F0 -:10751000000202200001024000070250000202C0E7 -:10752000001000000008010000028180000B81A80B -:107530000002026000018280000E82980008038031 -:107540000010000000010100000281100009013854 -:10755000000201C8000101E8000E01F8000002D895 -:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B -:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B -:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B -:10759000CCCCCCCCCCCCCCCC040020000000000067 -:1075A0001F8B080000000000000BFB51CFC0F00350 -:1075B0008A37B231306CE344F0E98159181818F871 -:1075C00099C8D7BF0668C01620BE0CC47B5848D7E0 -:1075D0007F5E1AC15E20C9C0700488BBC51918EA55 -:1075E000A510E296320C0C3780FCC5503109A09EE4 -:1075F00069D2E4BB79140F1E9C648ACA773586D0A1 -:10760000374D2074329ABC1B545E500F42A79862CB -:107610003757488F38FB1354D0EC57C1AF3E5D034A -:10762000951F8EA6DE0FCA0700DCEC914ED8030032 -:1076300000000000000000001F8B08000000000098 -:10764000000BED7D0B7815D5B9E89AC79E3DFB99E7 -:1076500049086127049C8400C1F2D84280A0142705 -:107660001030B6D46E5E12BD081B1F95872411D34F -:10767000635A39CD401E2401243E4AE92DD50DC55B -:10768000367A6D1B6D6A698FF66C442D9EDBD303D1 -:10769000942AADE0096A2D58A0B1A71C68BFB6DCDA -:1076A000F5AF47F6CC64761E3EFAF57CB7F193C988 -:1076B0009A59CFFFBDFEFF5F2B0A2A443957217428 -:1076C000057EAE47C8101042D3534F744F86887260 -:1076D00010FABC8AC8CF255F7832CA40A84EA5CF21 -:1076E000FBFDE17DF06CAB4728391EBE8F4EA0300C -:1076F0004201848AE56C68E18F3E5100CF9A29B13E -:1077000049E439139E594844683894F3B57703B473 -:10771000EF2B12FEE764BC0CC693E82B24A3D268BF -:1077200092B47F00A119A979A09ACF6AB1506ADEFC -:10773000CEA7A42928C9EA5E817FA41519F160FAB1 -:10774000FA752785EFBE64A93F1685B2C9BC6424CB -:107750009379B1F60899C83A3F673F97EAD1775FC6 -:107760001ADB176EE9C6E5706BA957C9B3B95E435A -:10777000492F42B899D139113F83C8D837B16FBB6F -:10778000722430F8B1F9C0383AAE8FFF4718EE8D49 -:10779000D92811001CA2B80D6E8DC1C5AAE1D21F57 -:1077A0007FA26C0CB76236E7C2BEEBF5C1BC301CE1 -:1077B0007C302F17782E87794DEF3B2F5F91735ECA -:1077C0006B90153E439D977F024247001FB2811088 -:1077D000C1CB7DB6FE44CD30BB5DFA438C2E649D9B -:1077E000AD6F90780A148BA9F1010EBADF465FDE07 -:1077F00048969DDE9C740DF020F86A67F0894994E4 -:107800001FCC141EF13350AA0BA890148F00DE2257 -:107810000CEE913B9BEF15315F8551A2651CE6870D -:1078200048F7EA85C067E193379E459331FCA25340 -:10783000D579784D5A89FED002FC0C4CD404A0D7DF -:1078400036E0B36BA1BF5BCC325C6E80CEF270D100 -:10785000BCC93009DC0C1BDC30E47419973DF06BBB -:10786000A10BFC502F1E842BDEBEEDD3C1CF832C89 -:10787000F823FCBCD1469769F11EA7ED4CFC1FE034 -:107880002BCBD18F566EE7F330B294F1F7A7E01708 -:1078900002EF7BFF26E365A27DAA5E82D75B2C6A9E -:1078A00009A88FF44C1997031532023996998D0E59 -:1078B000628C0C889746842A80FF11EA448B26A5A7 -:1078C000E6F7AF8CBF723FF7E8EA66CC4F174B8301 -:1078D00051E0AF8886D0B0ACBEEBD9CEE44B6F3967 -:1078E000FA2C8A4F84F1122D85785E66548C3E0105 -:1078F000F3297E518B5BF8E574AF7C71D207D2E53A -:10790000194C1E60F848C5A2E19BFCE1E943FA80EE -:10791000F4118C2B36BE1C2ABE2E0C913E3EEC7808 -:107920001CAF7DF96A33C36BA30AF2AC455FDCAFD1 -:10793000BEEA8BD77D08EA078A91917069F75F5696 -:107940007DE17C5AE4BB538E4A236654EEED0F6F03 -:10795000D97678F07E7D7592FECE305C9435225FCC -:1079600015A6075A230F9B08D3DD45903D181E52DC -:10797000FB354928A32244E810FF24055CF6458C1A -:10798000441BA18304C10B9F9F57176DF095B3ED66 -:107990007218559A8275FEBE3A85CC4381F1B2C108 -:1079A0002EC01D6250C84194F485A1069D3FA8A435 -:1079B0002B63A06CB7335AF4A9C80D0F32C3AB20A8 -:1079C000707A7D6070F2C539DE52FB7C07DD2E28AF -:1079D000EBEFF2362E723AD54E46EF72FC6020CEB7 -:1079E000E1761DC3D3560F3A204CC1F220FF66B09A -:1079F00014D056F8340BDB21F0CCC5E5FCA9442E9D -:107A0000A00E4186799221311E11D677502F20E8A1 -:107A1000A41F51AD2172450A1AE4C9BFA79F171DC3 -:107A2000BFB7ACC6AB003F6B228ADE86E7B85E32DA -:107A3000F4CD4017D3B07CD2E1FDB872D0731E8173 -:107A4000CEEB4B422E59879CD59243ECB234F6DDF7 -:107A50001A19F3E454F8BE7D5C7FFC84129E9E6E7E -:107A60000B3C9DF6E0DD02B6073F817F99896602F7 -:107A70001C7F1F5D9C91EC075FEFD51FD6E4B129F9 -:107A80007BD0F97DBD846ADCE440B3A052BE544D86 -:107A900005EC03BEEEF5982FBC59C0E75BE87AB35E -:107AA000B3097CD777BCAAC916FE5B8FD58C776AE1 -:107AB000DFF57078F37E7ADB270EDBDA3BDBF5F659 -:107AC000C7E505B68781CE391D0484F83601BFF7B6 -:107AD00046179B7930FED36514FF69E6DF8BAF0F45 -:107AE000387FDE6E20BAFAFDFE8666D04FEF2AEDB3 -:107AF000375D8BE9E837CF48D12DF8EB9A3DE3CBE2 -:107B0000C16E7A97D137C7D3D9FD0D396EF4910E76 -:107B10004FAF0A3E320EA7AF35E28A7EE96120FA06 -:107B2000FA9E93BE3A977C2CF475C4495F0C1EE70D -:107B30003AE9FAD1EE61142F0C5F4EFCA4C5CB07D5 -:107B40006DD7979E7E2160BEF6762E71A727365F91 -:107B50008EAF0F3BDF81E82847370C0D8F3F02DBEC -:107B60003102E88F12144DEA60D745A9DE8A52BD72 -:107B7000C5E5126F7F41A0769A8C8E93F6124A9AD1 -:107B80001AB1B7ED76C67C09BFC4FD3416A384973D -:107B9000EC8B0C95E8A9621951FD67047371FD0C1B -:107BA000C47EA4D951587706B3FFD16CA67F056C6B -:107BB0006FE1F5054BECF687DF619F48B05F08BBCE -:107BC000D85B43DC1FFB44B63F0EA020D1477C7F2F -:107BD0009C863F7BF7C50CAEC315648878DDCA610F -:107BE0004F628B00DA0D11FD8C4E0A09EA2F40C559 -:107BF00060376F14F2A2A00FF03EAF27037F7FF72C -:107C00009B12D10F75919A554DB0EC9BEBC677E363 -:107C1000711FAE47D38A3CA9F11E96DB5580776B66 -:107C2000D146CDBAAEAF09F102D1A2777C11655A27 -:107C3000D134184E7EAB1BC343C48004FEF3071F30 -:107C40008DBCAC03FCE8FB5E3859CB52DF7236D8F2 -:107C50003C79A498043BAE3584A89D8F460A65986C -:107C60000E5A3DFCFBEB65B0DF6DF5D1F29E2DB3F6 -:107C7000369B501ECEEA9B95F47B2E2DDF273E517E -:107C800006DF139978CD5380AC13953117FEBE4FA4 -:107C9000A47E95067346EC2E323D6A7F5DC5F7D90A -:107CA0004B6E8ABE0CBF14E923C07F220563C4BE9D -:107CB0009198BD266B26D5E36AF4F0780CEF51C796 -:107CC000256462388C6A3F5AE6057A0F723B2D8A2A -:107CD00096E2F675CC1FA022BA3F06BFCE1542C76A -:107CE000FA08D8B720B0CF2CFB7689D963BD78725B -:107CF000E0ED11B986E06D6B7EEDE1023CBEB9505E -:107D00008C02D96CCD2FCC5C6DC1E3B7D4B9952270 -:107D1000D8318DD9C42EE1FB64601828E792290080 -:107D2000683BCBC078CCC7920F613A1D1DEB29038D -:107D300014E895DA8B648F8BCAB577895D2509576E -:107D40003E31783B0AD62D02BD62FA7DC2B2DE61B9 -:107D5000028AB9C9DD157216C1CBB00ABCDE7EFC41 -:107D6000049FC7FA84DA677135164A3F4EBA797EA6 -:107D700008786E01BE188912044E03C1351D3C9B64 -:107D800023CF661279FD11C3355D7B273C870994AB -:107D90005F56C8A5845F06EBDF6981FD14DEAF3650 -:107DA000811F0E3F1B981FCED9DE27B7A3A80B7EDD -:107DB0007DBADD3FA458E91EFF5F2BEA541F049DE6 -:107DC0007E228A67A75E58C0F4425304EB052A0F4F -:107DD00017821E0830F8374511F9AE8450C2C4DF4F -:107DE00003A00FB09D852652F9AFE2FF80DF465415 -:107DF000DAF58132487DF08E107B99F0174621CC60 -:107E00006FB7D07EE338A09F5C6A8F476E6F89584A -:107E1000FD05B522D5775C9F3D56D43B6F023F2FC1 -:107E20009BC36358A4023D26F2176710BFDD9D0176 -:107E30009B7C8A7C6931D9FF5AE899EC73DB997F86 -:107E4000341DFE342511779387BA249279858D9E4F -:107E500024F8FC0821E7309721236B0A7F64DB8735 -:107E600085A7F61C1E83D7FBF83522B11BE5D97216 -:107E7000D283E12B97BE5229E0E7E3B03680C72CCE -:107E800044E834A82F382B813E96BBD122DC5FB06A -:107E9000C2B92FB69425E8A76725D1DF563F753FB5 -:107EA000FBB8C13E1B30BCDEB2F03F42B10AD0B3DA -:107EB0003296E36D88B84BF3605CD9D072805E6413 -:107EC000231A24CFEEB20A5A8EB5C177DFECE8D17F -:107ED00072E0434D26F23EA152BCF17EE74805B662 -:107EE000FD5BA6E6F08FCA6625D0814F5710D0A75C -:107EF0002FAE180917FCD48A329377763AE1F4D181 -:107F00008F9CFB5074714AE47E6A3BDE6DF451989D -:107F1000C22B6F17ECE3A7B2E3D559FEA8F1E99B9A -:107F20004DF189303E99BFA40DE01C344504761113 -:107F3000AF17900A6DF8095EC61B2B6CE7EC2E4359 -:107F4000956EFA292029A43EE6FB7289DAE502D86B -:107F5000DBF3A53D06D079A208E306F7DFE2C126F0 -:107F6000112EB76C16395E89BCADDDD252B619D769 -:107F700069392988D214A09BE5049F3EE6F7B9E44D -:107F8000312B0A71BBB65122DAA783FEE9DFBFD5D8 -:107F9000506FF76F815F01ECEFFC1A6D2A80395D3D -:107FA000BB5D3562859BFFEB2E89FABF76D41C6BD7 -:107FB0002766E84BF67D876785011408FB8FBBA415 -:107FC000E9A976A112EAD74071BC1E5CDFC3D733A2 -:107FD0001CD3673FF18AFFCDF4092FE7B1788EB348 -:107FE000DE4F2446873A8597CAE8F05241FFF4CF26 -:107FF000E173B9456271901E1F227A7738F1DFE98B -:108000006C5D9279A40CFA9151F766D887EC12D185 -:108010001AEA578E117D1366E33D5EFA7B1FD4BBCF -:1080200041A6F27294D1D30A781EB54944E0C77EC6 -:108030004AD249D72356D41CF4E0F7AD9B5134887B -:108040005F8D867E71BB57C62A44EEABD954EEAB2A -:10805000B59804703D15EF6B745C6E3DD88A40AFE7 -:1080600087F1C6094C5EBD1489E0E7F6D4759B30F4 -:108070006EB8344AECD0436367907DD583D928EA43 -:10808000D5537281D3D1839B161B40072D781F06D1 -:10809000E596A22D2AF8B12F16CBA48CFE8CE1C355 -:1080A000FD85F81FDDA474D35A40E72B4FEC462220 -:1080B000E15B95E053D6E8FA5B43DF34617EE65A34 -:1080C00044EC23B06F497C468EAA20CFF377CF26AD -:1080D000FC236BED02D0C346147FCA4A27523049B5 -:1080E000E6DFFA1789D9EF2F6D06FB7D247485CB67 -:1080F000AF4AE7370FC51EE171416E8FB4C99D8449 -:108100000F4DCC63A06FB87DE22BEA24F4F9DF8C2D -:10811000BE07DBBFAFD8EE4775DA2B4E3BA556D472 -:108120006C76A9735D973CC91B617E6DB998BF0BD6 -:10813000FA8E775CA2FB923D91C5FF51A0A7FAE1B0 -:10814000DFB97DC4CBF9971502EFC1D7C7F20DF6A1 -:108150005E06E5A3D19C4FBFD03F9F723EBA84918B -:108160007E04F0239B2AE123A398F011E70FA9DBFB -:108170006C1983E94CAF13C1238DC04CCFC2E5AB62 -:10818000307D2785149D8E62E3CA1313EDE35DE80D -:10819000ECB15AD120FEEF28EE067F0F9B4788995D -:1081A000E92F4E70BABA0874C5E92C7FF702B2AE57 -:1081B0005781A0A7835E7597233F62760ED2F61B88 -:1081C000563FAD0F35BAC7CF6B1FEF377EAE167D6A -:1081D000B8F87948B6FBB3066A3FD4B8B9747918D1 -:1081E000A18FDE32DB873AEBC565265F4FEEB3C168 -:1081F000A50F3CA4EDD1783F74A27E487F3FD159B2 -:10820000838083138E3364E667F998E0E88C6BBF54 -:10821000CCE4FC40F2C06F1849710CF8C510F5DBD6 -:108220000411F3DBD8E9FDF14D94DEFD21712F88B7 -:10823000A870ED11D36B990FA6F725F2F014BDE7E6 -:10824000152793801FA7FE49A7770692B72B55E302 -:1082500036D925CF84EFB3537904988B5DF208D2D9 -:10826000E2B5E6A3C923182CBC7BFD962C2FE0F6C3 -:108270005246B7D8707803C365ED610FB1EFB1FE18 -:1082800093ACF1B2B56C7F773BDB1FDE896261F89E -:10829000781E8915C02FE7D1B1F0340BDDEF9415AE -:1082A000CA2F2D9EB7C06FCAE3E077B5D3329FCFF8 -:1082B000DDBBEDE5CFA1C539E0AFFBDCA31EF020AF -:1082C000A0B50EBF593D10049EFFDDA8A619F0D63B -:1082D000E4A176E8ED1A92216EBDE1075F9FB11A25 -:1082E000EC13667FBC87E5B26EB19FD605130AE03A -:1082F000F7EDAE69375F87A07DA2390FE2D7998885 -:10830000EC479D70BEA3C53EBF81E6EF9C2F425B4C -:10831000FA9D87DC21B8C659F7CBF6386BBA7C29B1 -:108320009E27F5924CF16FCE45C47E32DF0C241AA5 -:10833000883EA1795203B57F15DA4FFFE0ED7F3615 -:10834000C0F81BD49E05C4CECA3663E0EFE1F1BE8F -:108350002A54638CC4BFCACF2F3281E77AEB45061B -:1083600059AFA8FF7AE9E67D56534D714A6AFE5F20 -:1083700013E2276597F5DF2FC5ABA07F2FE0418281 -:10838000A74CF04DFCBB18BFD572B045C8803CA6C9 -:108390002EB2CFF3E9B28D1EAAE117906BC554AE91 -:1083A000058AEDDF9D7EDFDFF5E23D49F88F84969B -:1083B00075B01F824909FC32A5F2B9DEFA78BC2AF1 -:1083C0005817EC93508CC88D5A8DD6AF42FACED93F -:1083D0002584FFC8BEBBB6750C8997D70ED7A3E01E -:1083E000879551D4207D38E8AEFAB28012167D58B8 -:1083F0002DF728C067D5D82EB2BEDF18916CFE5776 -:10840000E7D383543D584CFDB9C43FA4E1B265DDC8 -:10841000BF6F17585E8A9EB1B41FBFDCC608F5F364 -:10842000DEDE3A3683FA03EDF2F702DB1FFDE4E904 -:108430006F28E0BF3FFFD4E99B00DEEBFF45422AF7 -:10844000E4653C1D4249628F2514B0C7D67549AE1C -:10845000FE0392390371CDEF8608BED63DEB4D2C5D -:10846000C4EDD73DF7F66484E777614BCF2B23C18A -:108470006E7E4AA07E6BB37BF212FC7E9D8C56B959 -:10848000F9058A3DD44E3DF7C34025F0B7D0717051 -:1084900025E9B773B9C76BD95F5FE5F1F07AD42EE0 -:1084A0007F52488C15DCE647F33ACE3D29D0F91DC2 -:1084B000F0247C30BF8EBD4A1CCFA3BAE37D224F8F -:1084C000E67DF7DB618043F501C9A607AA3BA4A4BA -:1084D0007732799E8627C483841940278C5EBA360A -:1084E00090385055E7B6F7C14F517DC02ED7305C5C -:1084F000A24980EBEB52742194BFF7ADB08E41F5E9 -:10850000DE9127C20057DCEF6A2503F48D9DBEA1E2 -:10851000FFCB597DFB43A887C4E1AA3B5BE9785DAB -:108520009FF90DE8956A87FC7C0F7EC9ED6BCFC47F -:108530003C0EBBB0637071B8F5DFBEF89889C73DDB -:10854000F7EC6F1F33F1FCEFF9EB7F3DF600F0E73E -:108550008F7D1AC8FFEAA77E1146167A5CE7A1FC58 -:10856000786114327371BD0BBFF4264CFCEAC20B68 -:10857000BF19ADE3755F78E68F393AAE5FFBC2FC99 -:10858000110087DAEFCF1BD1DF7E1BE835E1B5CED6 -:108590002B41F0AA1F10A811F43C7B3AF073A8EB12 -:1085A000D06898E7F913DE28D83DD5F85DDD54C0D2 -:1085B000D706A28FA1BC09C3B9EAE9ADEF839CE855 -:1085C0000B6F73A4489CF0C991E08CAFEA7A7B01F1 -:1085D000C11BEA217AD459BFFA38C6E794F4F8BB34 -:1085E00088FEAC80BCAB7EBA958ED789F117EE8B36 -:1085F000BFF3F0CBACBEF86B71E0EF22BAE7F15CF1 -:108600004868EB1A668B7FF2672AEE17CB88F52352 -:108610002FB83C1808BE6B043AAF651E63B707F865 -:10862000EAD9402F7E17027EBF7D7134C2F471C635 -:10863000D3B312E466CF0B5E6D1F7EBFEE85D70904 -:108640009F5DF8FE51452779972828E4B0FC2FFA62 -:108650007304E47015DDCBA1EAFDA1A4379CC253DD -:10866000556251851E26EF4F93F7094AFF558983BE -:108670004B0517BC1DF314523B2A319CC065C3FE49 -:1086800037146A5FA6F02994023E4F2F80F7E9F075 -:10869000C9D7AFC1FA675AF0BA9FF2ADB37E15E6FB -:1086A0004FD07B7DF09B105E87E785BD5E19F4DEC1 -:1086B00005B0BF827DF19E823FB57F86BA5FF9A982 -:1086C00093BF795C98C1213D7D98CC0EE87F7D43B6 -:1086D00085DF8F3CBA8D8E381CCFFDD95DFE9F6142 -:1086E00072A30A99157916FB44F560FB04F2C65093 -:1086F000CC1C59909AEF39D84760FA3BF79444E282 -:1087000030CD9D87881C77CA8BAA34FEBF3FF2F11B -:108710000E1C9C0C72EDDC8B3F24F459F5F46905BA -:10872000FC63AF747C4FE99E98E207D00F098B7E03 -:1087300038F79D8393A93C70DFFF2A0AEDBFFA79D1 -:108740007BFFD54FBF6FEB7FBDD9A9D0FC84FEC79F -:10875000794F3696C37ADF3BE241204FDFEB945CE2 -:10876000FDADBF05FD68C9336B3EBAE00D88DF97EC -:108770001CF3EBA047BBB618237680BD76CC8340B4 -:108780007E23D9F82DC497BB8EFA75C87BE83A765C -:10879000B3A45BFC133F70C073E671735E08F737D8 -:1087A000B33B56025B28A7DC283D2942CCA277FECA -:1087B000B5472B4680DC6F047B7E3C8C178D90F890 -:1087C00077784105CD0B14359FABFEA6FD79589CFB -:1087D000DCA38948B7D223DF6F31BF4F73D0DDFFF1 -:1087E0005CA670FB108F6B9183D856AD74C35B8908 -:1087F00042F741E9BE970EF07DB6C2F200D27CEF9F -:10880000E56F861F2524C6DCE63D99F5E3F4ABA6AB -:1088100093071ED6CF144567FDD3F502BC1759F256 -:10882000DD47A2C466F07FA160D019678EA9D63853 -:1088300073E591831057CE5EF27C2EC03F8C1AB543 -:1088400077891D8FA257FAB1639D716567BE61BAC2 -:1088500038B31AAC3A91447DFBEB1B5737485CBDEB -:1088600031BF5CB5C6D51BB53E71F50D0A1EB729E3 -:108870000D1E3EABCCBD17BE63B333EEF6BD49A1B2 -:10888000FEABEB51F7F756C33CA3342E3FDB01AFF1 -:108890004F3278FD780C5E38563D6548973D18BEDE -:1088A000F3961A8D2002E7AFE8597F10F88CC7E5E0 -:1088B000CDF1E295C0E0E137D47C8795EAE20795F7 -:1088C00041E43B202DCB552FA4E66132BE89907D3B -:1088D000128FBF1C3A75B70A724B46F18A024B3CA5 -:1088E0008CE4D1E3FE72923E64E0F92A9A4EECEDFC -:1088F0009CE4DAAFDE05F1722D9FC41FA4CBD71123 -:10890000FFA1B35F291235499E57502F932CE334B2 -:1089100067D3788CACC55CF381572AF1A761BDD2CF -:10892000E539A45F51A5F10C141C5C1EEC5796842C -:10893000097C550C5F908F0464B02E960FF5D09291 -:1089400030D133BEC39EBDF0DD17A4F951F78BFEC5 -:1089500028E44F39F3A3CADEA4F196E6D30289A333 -:1089600070FA6D2EA8B90AE4783FF9512F2B16BF83 -:108970007ABAFC285FF04E921FE5FBC0F951917264 -:10898000B0C79A337919AB133C8F6696EFF42BE599 -:10899000F03CD04FCD2C3F0A99AFCE23F57919D5B5 -:1089A0001C32E03BCBA7CAD9DADC00F5B347A29A68 -:1089B0004EE2CF33D0328B9CF579699CF9CB8AF1AA -:1089C0009F8A45EE71FCFB7AE96AAB0AFA1B3F49C4 -:1089D000BCB219D315D8ED39C95664D547FCC9E9DD -:1089E000A8B9A8FF789D7CF91AE2C7E765554B182E -:1089F000864B7D43A57A82D32FC4D3402FA97AFC1E -:108A0000AB77013D6707A3014A97244ED61224EEA7 -:108A1000A93EEB6829BA9DC4BD2E6AD4DBCDE9B866 -:108A2000EFFCE7B0F9179A405F1783288A5CE45F90 -:108A30006A1D25641D2B1543F55AE0987D957BBE74 -:108A4000E9762F5D4F536C45EC2E98C91A7BDC9567 -:108A5000E75FF0FA01213E1CFAF564D3B8ABA852E7 -:108A60007E4BE10BAB0A8B7FB301AD308104E41583 -:108A70009DE4C8A2AC2548FD31BEF868AF2D3ED7B5 -:108A80004DE3B88E78E27CE91ECADF03E06F07DBB6 -:108A90009F6C83B8DB7888CF45D8B93D9DC5E90C7C -:108AA0009A2F94869E5A8AFA8F43B5D74749FB9DE1 -:108AB000F5A5340F4940CCAFFDF506A013704B501F -:108AC000BADFDF007C1092385F3C45CA0F0AB41C45 -:108AD000DFDA45F8E6D0A9D72BEFC0F4D16CF8095E -:108AE000FF0FB43E2D3183E075A8E3F45D2F1DB771 -:108AF000C50892FDEE40EBD69274DCC18EC3E3E371 -:108B0000A9F5A9649C667D8071DAE93803CF9FF2EC -:108B1000C98E836B2B20AEAC62FEF7E1F7EAEC1E48 -:108B2000E4161FCA60FC73E89497C8EB966C9AC76A -:108B3000EB290E1AD40968EFDF3331672E39C7509D -:108B40007235C98BDF71B095C81905C6C1553CD1C6 -:108B5000E06ADA2E6EC0F9D970398A825FDF539CE1 -:108B60007307BCAF43EDB1B9A0874BE9B92D4F7185 -:108B7000F15DD04F26F0259EC73495E67D788AAF0B -:108B8000BD1BEA1F9CFE5ABC01E0544AE9001DCE01 -:108B9000B5C1B1592FE4E771FAE57B4FA93D6E816C -:108BA00054BF2D6F09C94B49BC1CCB856D5E8BFF33 -:108BB0001BEBC59D50F6A01213ECBD5DB7DC1CB5D8 -:108BC000F2F39795D8C3548EF03C2CCEE7EEF970B3 -:108BD000CDD93CAF2CAE4A2570FEA8374F7A61AE96 -:108BE00035AF8BE54907799E7494C6E1DAF17F6E63 -:108BF0007971CEF3891F559EF477BC6C3F1C40A35E -:108C0000204FFA471E144DE279B7FD428A421E8C6E -:108C1000933E9CFD39F3FB7BED9134FCFC6B008EA5 -:108C200045EEE5C61D78BBD347E2737CBC97403E5A -:108C30004D1C984F47AEB1F733AAC67EEEEAAA3A6A -:108C40007BBCAAC0CCB3D51FD35268FB3EB6FD6A2D -:108C5000DBF7F1BBA7DACA1312D7DAEA7FA263AE59 -:108C6000AD3CA9F353B6FA530E2CB695AF49DE6A64 -:108C7000AB3FEDF0EDB6EFD38FACB37D9F7962A340 -:108C8000AD3CABFB8BB6FA75D83C51483E1C8D37DA -:108C9000A1ED23452B7DB66662BD9281E1988909DD -:108CA0008626EB937833CD314EE51938DB49458A7A -:108CB000A161FE95F471E51AC91FBC93F09154941B -:108CC000335727EF672C00BF132AA1E7AF7CAC3FD7 -:108CD0004F114AC2B94B39E8C0AF232EED91B6937C -:108CE00078AA72F286C342B82F5E3D11679EE2E019 -:108CF000E2DAB2EE683744BEC854595C7B14E60B26 -:108D0000E247FCB344CE3D9787887D60D9DF1038B9 -:108D1000F2FDCD1C1535024C395F94ADE81949F2CE -:108D2000D97BF7355E7128F9C67DF58A97D85D5CE9 -:108D3000CE0CA457A4C4345B1E82F389E5DF14155E -:108D4000F6E1E15B893CEADD17F4CAC7D854F8EED6 -:108D500091A3443EF6CABF8E3C9B5C18AC7DE69462 -:108D6000D36D20F4C9791F77791D863C302C971E6E -:108D70005C72138983A15A643BE79753195341EFFF -:108D800061BBAC42B5EC9FC3A5D43EFB7BB353BDE6 -:108D90006CBDBD74CAEC550ED76105353112D70BC9 -:108DA0008908F6550DB3A311F003B64015CB3E6DFF -:108DB000973A86C8D1C6A02282BFB4F1F07C121FB8 -:108DC000F0FA622AE4D135786215B0AE864C517360 -:108DD000CB77DAA252FF8C521798B6BF1FFA501405 -:108DE000BCEF7759EF3E95FA5D1AB5C58741CF655F -:108DF00085141D526E9B0FCE5A04E3CA0B650DF607 -:108E0000B5086FE2DEB6C41521DF1711F88B442FC9 -:108E10002A756132FE40F3BD47A57E066F9DAFDF28 -:108E2000F97A15773F45BAF96E85F9660F3C5F6FA1 -:108E300036CD5FF5D605C9F8FF0C1759B8C0DF83EA -:108E40008C96725CAFE9F40DED458462689EDE237A -:108E50000BA7123AC582DA46BF7C1F81E937A10E03 -:108E60004FEDDFF939D5BB559A97C0F18A74EA8F77 -:108E7000181697C9BE372B4EF7BF29F941E928CB01 -:108E80001345E45C57BE4CE292E0A6B1FA31FECA4B -:108E9000F671DE4F4609BE5A3F23A32D406F457839 -:108EA0003D70DEF6308D3BB57AA295B1606A3CDE4E -:108EB000FE4D860F192DCD20F95BD2C2889BFDD9BE -:108EC0004BE70C6E4E39FB632E6773512E95B3132F -:108ED00097C311A174FD38ED0D7EBE67E8E74EDA49 -:108EE000093C5BF31F257634F78FA148C900FE1EAD -:108EF0001A2F4DE179B99EC478946F9C4A9C7EAD3F -:108F0000450CCF358EFC5D86678E5FEEB747916C62 -:108F1000C2D71CDF12C0137025CD8EF4A7AF24C6B4 -:108F2000374E789EF91F0ACF9FC31AF0336B145E39 -:108F30003FF0CDA11B11898339F891B7E374EF5C41 -:108F4000BFEAFB9FBD7E4E0FE9EB9BAEFB0F1ED72A -:108F50000D317A5399DE7CB9F4AD1638272267D3E8 -:108F6000FD6EA8B491DCD322235303FF5A889FCB14 -:108F700061E732793E957FA27DFFC1F30B4919F37A -:108F8000BB87ED3FFADC9BC2EC2C7E4EDF397F279E -:108F9000BEE6F8DCF30751BEBBDFD5198FE3F10D58 -:108FA0009E07CBE300040E78FD9E59628CC8BF1269 -:108FB00064EC75914FCB7C542F74BDE8237912A1DA -:108FC0004A85F863F34A926550CEAB4151D013D72E -:108FD0009E3982E2B8D3B17E2AF7F34A1202F83DF5 -:108FE000F2CED1BCD85D2C5E99579B10565BC679EA -:108FF000C047E5ECA553F713F9F8E2289A877E5F9E -:1090000019B5DF8E446E6F2F83714B693E7908EF7F -:1090100017216F2C74C24BF26F514937023F2AD689 -:109020000266087F3F538FA6DE3916F2BE54F23C2B -:1090300057AF91E7A151CAC1EB71BD8D057E1DFAF5 -:109040006D2AF4D373BB2195ECF7FF3BF373C4AFE8 -:109050007AA13E42EAB77CC9207645E3C1B3C46F2A -:109060001830A645A91FD5905029CCE788017E0E5F -:109070002447F5C5F0FDD02F493D4989FFD204FBB7 -:10908000E45685ECEF010E104F68F0D17CB9ADBE0F -:109090009A48263C0BD0AA452EF0BED5C7E34CAA71 -:1090A000A4E4A4F29094D2A49401FEE412D439165C -:1090B000E46553A20CF4345AABE9304EBE9A28034F -:1090C000FF71FE1A2D0A3E74A594DE23C2F1E1F170 -:1090D000A1D83341A89714EEC5E316FAA9DECC3B1C -:1090E0009120F70C5D3A35D3D5FEBFFF6419F9BE68 -:1090F000BDBEE258B9859F8369E2950F14CD7DD43A -:1091000087FBFD196C7486A7EF973F07DBEFCF7CD9 -:10911000549F1E3A357E04D8977569F2A8250DE351 -:109120006918954FE08FD838561F9119B4F643E16E -:1091300021BDF8438AD789943E1BBE3F3E03FA7D8A -:10914000E9D4720DFC7DBFCF2E22FB86F3CF790DC3 -:10915000B05FCE67A13524DFF2B999AFC0FEF0B79A -:10916000F587B3648B5C3CFF9DA3333CB8BFF3CF62 -:109170001E9D2113E64AD8F6F11BAEFC7C06D809E9 -:10918000E65C545C839FD59A82A0DF6A95AE83E744 -:10919000C9EDCA519AE1393F9049DAE78C101F8432 -:1091A000B2A4FE7CF43BD3C8BA695C81C571F0FA05 -:1091B0001A8284AE35BC018178A1E91D0DF1AC5352 -:1091C0005E427F970A5071C114F00B4AA45DCF5ADA -:1091D00094807C0A255903EC897C3F4D20E09BC09C -:1091E00071ED20A13576CF5BABAF90D121CD23DCE3 -:1091F0007CEAFEF1001F2ED7E57988C4337A6E51E0 -:1092000013608F3E2CEB5F590176E06D3299072E8B -:10921000FB34173C2E0F14DAE092C5E2131CAFE9C1 -:10922000E8645B3D8A166178FFB85E8DC2F8CFD7DF -:109230006BA4FCA3FA08291FA8D7C9F3B9FA62F2F4 -:10924000ECAA8F92EF1DF5A5E4C9F3FAC8D65E2209 -:10925000F674AC0CF4D032EA87D374D1807C850CE0 -:1092600019A9C3B0A9A29DFC4925ECB741AE64641D -:1092700011BE17A07D36CBF31B9E3BB7B54C4FC933 -:10928000572E4F1B3C48007964CEA27E8610F4878F -:10929000DB672F45E82D8B5CBF82FF79AB98AD0F64 -:1092A000CF27C3B07F77D60FCB7801597DDB61B96B -:1092B00048CAA97EDDE137D427F8CBDFB2D0F7AEBC -:1092C000E978D5988E7609548E3DC8BEEF983E2336 -:1092D000E37628CF9A9141F27F67215DC370DCA9C4 -:1092E0008BA62723557F4FFDE19CF2B14C07819C53 -:1092F000AAD5F6B659F631F9265A15B3D0CBCE1AFF -:10930000B9621FB133E2B98B27917C63E6D7DE5790 -:109310006ECC26FD927241DBA17293E915903373F6 -:109320002E533DD4AB7FFE4CDF73BDA730FC6F9F47 -:10933000BD450A039F803C057959124773F13C8370 -:109340009FA4F1EF59EF2411E4F72951FC1EEC51D1 -:1093500085E69BE4451202949FF4C5A6FA613F920C -:10936000B53BB90FE3FB0F5D5E1DE28D5D2FFE91F6 -:10937000E46748931515F83BEFF9D3246F4912BB06 -:1093800015D8F12E6BBB7ABE0CF62C4C84DC2B80EE -:109390001535C6B394C3D667763695031CC5F85900 -:1093A0006BFD5DFEF8BD74C78C0C3582F9C1C7DA60 -:1093B0009BE39B8C7C5CF6D0F2B2B6714DE66C28D8 -:1093C000E3FA99B4DC88ED846D999D111197839B24 -:1093D0008B9A0E8F8232AF5FD464E2F631A60F50C3 -:1093E000305E00FCDE5BD670396429CBB48C54FA55 -:1093F000E4EBDD70E88FAF8CC470A87A5EE82421BE -:10940000BEE7F70AB0EEBC037BE9B9800422FBFE9D -:10941000BC849080A39B1DF587B546EE5CE378C1C4 -:10942000A2614284DE1BA4243C51D85E4E60F782C8 -:1094300070BA782640F5C084046E6F8D4B3BEE0900 -:1094400099C0EEA1212403F2723B3DE7EBA4F3F1B6 -:10945000ACBF3A64B649A0B79FF668243ECEFCEC98 -:10946000E7B8DDC4FC39F730079E678BE9BF1AE423 -:10947000DF6A99F881D7172436631B0AADFF614173 -:10948000145BACA8C947E9657D6667CE544C2F4D87 -:1094900099F67203CB9F8F649A995913217FE8A1A3 -:1094A000D190DF5385DA577E11E6FB531A0F3F7BCD -:1094B0007056C675B8BCE1A7348EB1A1EBA802F412 -:1094C000BDC3CFF28EBAAEF914ACAF6ABB48CEC5FD -:1094D000015F1AE3F1748DF6AB654C2FFF1A383932 -:1094E000DF87F1FD64A1A189D720F4C6B6779BD4AC -:1094F0004FE2B2A24D00FA7863DBF926A0AFF5B3D4 -:10950000F87D76E75F368A58FE2306DE8EB6D94DA3 -:10951000700E63FFAD159F02732B47A4FC8B09925D -:10952000C4B5A5CC46727EEF774D22B19FC145BA36 -:1095300009C3BD48468765FCDCA5607C029F35CB2E -:10954000441EE2F72D1E829776727F086AA1F751BA -:109550008C7DDEBB1AECECA21A632DB1B7B589C4C1 -:109560000F301AF5FE903C89AB1095BFE3355426B9 -:10957000E37A2501EA2F2FAABC793DB493424BFD33 -:10958000C0EF3952C224FD7F8DCAE15D62A253054E -:10959000B91C2E24F8DD15A674613E3C91D0C57E21 -:1095A00071EED560173509ABDB5E05BC66169273AC -:1095B000AEF07E23AC9FE1B3418BAA80BFFD0C9F30 -:1095C000D25ED1847C4DFE7E9B70FB5A80EB3BFECD -:1095D0008DF3550CD71CAFD1320CE3E16DFFC6A65D -:1095E000C82C828742157F7FBBEDDE2615E365FF21 -:1095F00066234FB394C7FF054B752207EE257CDD2C -:10960000187C741D2821FCFD65F07F3C99C5F99EEE -:109610007E2F2AEC952306D8A50D664AAEA8582FB2 -:109620001459EA9763B9F0CDC72482D7C3783C9028 -:1096300013781D26D07DCF0499D8057E3C173F2E88 -:10964000FB2715927C5BBC6EE407BB61924CF43C3B -:109650008FE32813446237437DA0077F6E21C99FA3 -:10966000C3F23A06E77CA4088DEB48D21E03F33020 -:109670000AB0FC7D415B44EE17F1155BF20A40FE37 -:109680003AF210244779ACB73B17CE2B659F5C2488 -:109690008CC67839ED6771996CBC8FC5EF7FEDA7EB -:1096A000E71BEF8F993740BE0CD2BB73693C2A365B -:1096B000159E236E2B1AD19FFFA5EF7E354AEC979E -:1096C00047F265D77CB0E702745FE41D5544EECBEA -:1096D000A84398FF812FF8FD2A4C7E7898BDE03C86 -:1096E00027C0E5892793AEB1B675DE88AC60EA1C69 -:1096F0009C143454900707B5A919608FEA01CAEF8A -:109700008DC9599F05BB4566F2608F8F9E8FEDC94D -:10971000449DFB10D8BF5164CD4BE0F2607BBD4A45 -:109720009E4FCC1947E2974FCCC9990BF18A43D78A -:10973000BE47F6BF17F750FEBD78E465B823095D54 -:1097400034E9F95C202BE2974F3E42EE01F9861C8A -:10975000DB49F2E5215F074F6967A63D0FF38900FA -:10976000F59BFE89C927ACB7C9777E3F877CF91383 -:10977000C40FBC95C95D355E4EF695E0C6D3812E0B -:10978000503BB96789C3C1792F877C793269FF273C -:109790003F853FCF5F72E629F1F9FC80CDA7EF7DD1 -:1097A000AE767C70BF06C7036F5F2B1823B47EE8CC -:1097B000A6FAB2841296BC90D4B90D85BCBF00E75E -:1097C0005D32E05E9578FB7505C007096227FA8275 -:1097D0008DB6FB595144EEB19E2F0938CEBB38F9F6 -:1097E00005EE05063DADE8FD9F6BF935DEE6F2BC02 -:1097F0005C92A72EA3AF825D7B3EF0E60CF0C755CE -:10980000633101AE72249BE43CE905B62F919FBF02 -:10981000979CE7E1F3E3FE385EAE3AB088F8E9AA38 -:10982000F707C9799EAA0495831B54F3B057B4E691 -:10983000DD1A49C8B7F51CA0FDE980038C8F3F688D -:109840006B7261FD81BA3133E19C498E5873D568E2 -:10985000808F4CF100FBE56783E49CAE0C7A9C8F13 -:10986000FB4BB60F5CC6EC9100324580A7E48F76C7 -:10987000237A66D190B17D24F5CABDAB9B801F765B -:1098800039ECAD5D7E5ADEBCEDEAA646AA9F895C46 -:109890005CD6F62FC41E6AF2F1F273444EEE52DA31 -:1098A000932027CDE7BC3AE83DDC9E9C63376F2DC3 -:1098B00026FA432A447900B77270B480FC7BCEBB91 -:1098C0000FFC0C4FFAE231BF65BF733E746234EC9B -:1098D0002B5DFA336DFD8D1E5A7F78FC2EC003FF81 -:1098E0005E1EDE4DFAC7ED88BF03E51F7913DBBAB4 -:1098F00028E7392F3967B8C763B7B7F97337933398 -:109900002D8E7B39D478A3019B73CE9FCEFB9339E8 -:10991000BFCA9727D8F2A474A69F65D9005725FE21 -:109920003E917CFF939FD2410BCBC7493F4E569A45 -:1099300071EC71BBBEE3CC60720231FE97B5DEFB09 -:1099400036FBC97F75C6179DF28D3FB97CCB0E5093 -:10995000FE8A09F1AE001E675DA273819FF2E76483 -:10996000E0CF3B995E2AEE78E84550EBDF528DF769 -:10997000013F2B55636C60F8D0F9E70D369E8BFCE8 -:10998000A276D91A6AE7D6B64EFB14946B77146A9E -:10999000A64BBC883FD75C0ED8E4D70EBFCEEE45B1 -:1099A00034891C5B73394CBE7F74E3F96CE7D9FAD8 -:1099B0008E1724DFF978F738E4F3A16BFF6D572990 -:1099C000A6E3DA673CA2D7324EED33EC1C900FCB06 -:1099D0006B3BBF1BC0EF7201EACD5304F9B053617A -:1099E000651335835DF4A4553E9482DD966A0FF7C6 -:1099F00011EEF4F3F6BEE6F27C97FA0147FD42DE83 -:109A00007F26E9DF391F2E7FA00C769AFC172F9F47 -:109A10001F915F0F898EFEB2F8F879A43F6EAF7F79 -:109A2000A1ADF01553063A4D948DA4FE1D1DEC809A -:109A30006FC851BFF59EAB2FF8A9DC5C73798C0D14 -:109A4000DF29B88FB3BDFF4D7DC496AF7F77BC963D -:109A50009CD3F802F327AEC1163D69B767A42D4F1A -:109A6000FF1FF3F8A0F3B82ECD3CE6FC8DE7516064 -:109A7000E3CFD43C8A6CEF3FE83C7EE0A3F2F805EC -:109A8000F69CAFD17B01E6EB02F15BCFC7757D9809 -:109A9000D66FC04F153FE7CBC80C92FB6B13B43E9B -:109AA0002E833FE0B37FB9EF9DEBC97DCF06C9C7D9 -:109AB000E1F74EF1FB1007BA9FC8F9771B9CDF0353 -:109AC00069EE5FFD6290C2E9A129372192BF1E8C29 -:109AD0009338C1C1DC0511B0D3BF32A58A3C1B73DA -:109AE0006744401E35843E67CB37C77B04D773B0CD -:109AF000EFB17ED1E51B44EB7994AD701EC5A53E58 -:109B00008F8B6D55F9FD801FCF7A777F4CEB2D0D34 -:109B100051FDB9558D93B86073E4E399FFB3413AB1 -:109B2000CE4353E6203ADF39491AF75174EB796096 -:109B3000FE3C189A11817536642E88003D3766CE3A -:109B4000B0AD474AB39E957C3DDAC7BB9E7FEFC55B -:109B5000C7075DCF02D73C5839DBFDDEF9C6101DC3 -:109B60006F6B244EE8ECE35AD7990F8DA7A1AD2B6C -:109B70008BADEB8E20DD476CD5291F05A4D87F1453 -:109B80000803F3E1407F4F0415E9E260F2F07EC57F -:109B9000E0958E7F6FF52486C3BC4ED4D3FDF36B66 -:109BA000EC3EA95FAD690811BFB6639CADF9FB42FD -:109BB000FDF939FED71AFBF9F481E48619A471A0E6 -:109BC0005BE2F676CB2B03AEF79B60F8ED2C2848D2 -:109BD000C1B30FFE3F62B8A5A3C7A1C2AD393234ED -:109BE000B80DC40777C0253783801BA7B774FDFC69 -:109BF000FF4267BB83D46E1804BC087DFDADE0F561 -:109C0000F74A5FCF0E9EBEFE012FA23707475F5C6B -:109C10008E7528F49E45673FEF84E83D9BE3859A67 -:109C20006337427CE13312F1F71EDB53BE0189D664 -:109C30007A54BF1CAB98B781E4BBC60208EECF3A9A -:109C40002E46FFBD04E20E8B693B67FFC7187C5EA2 -:109C50000E65B27DBE3E1CFC08C7634BFA5D1FAAB1 -:109C6000B0AC8BE4655AEEA392FAC2F718D277949F -:109C700080BF69A1FB3C383ED38D3B547C1E8F7D59 -:109C80006348F81C68BD5DA1C1EAA504C14336EA7A -:109C9000FD3B1857033C3B449ACF710A5ECD82FBD3 -:109CA000C910A9B4BC7204B9E76C4A98E53D29FA19 -:109CB00006F09379972CDC16C2783BBE2C53B0DEAD -:109CC0007F2686A9DD326385BB5D9811A674906AF4 -:109CD0002FA0F17ADF7A7F65F6E3B215F45E2A24CD -:109CE0001BA3165BCED54D08DBBF3BDB47C2613201 -:109CF000CE71C1FD7E583F9BC7F2A5FDB747B5C3E6 -:109D0000D8E16D6D92DBFD829C3FFE4F283E2C8C8E -:109D1000EBBF26C4BFFE79A0A309411AF7905101F9 -:109D2000C4EB793FD9324A2A18EEEF78B449E0A75C -:109D300075E927BFBF7ED2C195AF878F03AC08F707 -:109D4000B2E0FD23D92F961808CD867DA2377A2F51 -:109D50003D6C48E9208BE5CFCCAC092436839D27A8 -:109D6000E3755AE6DBF5A7799F86EF5DC7446D4B37 -:109D7000415F380C241FCAC234DE902DC5B7F8C02D -:109D80003FB64A70BDDFECDA30FDFB23E742BD7120 -:109D9000F55130CEB847E31EB8E7E06696DF845051 -:109DA0007CD422CBF8E7189D38DB654B341E8D5EE2 -:109DB000A7FCDCB16FDD2837FEF939E3D373A1626C -:109DC0005B1ECED2D8BD1EE0CFA50B1779F4207C48 -:109DD000D729BDB1797428F151D70453704A2B8724 -:109DE000187CBA4EC41BE07E8755750289234DDC72 -:109DF00044E96ED5A683E206FCDCCBF86F91806C5B -:109E00007990F730BC76ECF38F86F977703F1D744C -:109E10008CE7B17237227EAF3B1FFCF456B84BB5CE -:109E20005B40CC4F76A002F20DBA599E8889BF6F75 -:109E300006F8950F27F31DB7E9FD5A90CF5D0A226A -:109E4000E7E5FEB3D54BFE6E05A7975E39B1E95243 -:109E50003D24DD3DA2242701DD0C6FA8F9BC9B9FAA -:109E6000FC0136CF3F0463196E762E7F7279CEEBFC -:109E70002D96758F5BFD25157639C6E73DCC9B3C4D -:109E8000EF765F432F1D26FAD77BBF60729CE3BD40 -:109E900017DF27DCF7455F6172AF2331773DD15B78 -:109EA000A6570779C8E7C3E1956D5238DDBC54B2B7 -:109EB000C9DB550B038EF34814AE9FF5EA8FC13A08 -:109EC0001ED9F76F93000F4EFDE097E20A7CBF1B8F -:109ED000253D2027CE483A79BE566FBF47FA351444 -:109EE000DF311DF4679DE4CA57CF32BCBC5679C739 -:109EF0003232FF464983F99F5E31ECA652902F958E -:109F00009E28E44F9E6EBC2F749765FD5CDF39E799 -:109F1000F5AB3577F4ABB79657DAF1D6A150BBC0A5 -:109F2000FC14E5C3B558DECC26F4D5BD63261EFF70 -:109F30005822EB9A365A1DC1DF695CC27E3F23C6A8 -:109F40001F9C89E5CD5991FAC3CC7FA27263E9A326 -:109F5000B12688F39EAD9BF64237AEF713A607DE17 -:109F6000ACEB5F3F3AE969DCA3F6FB29679C400A4A -:109F7000B48FD7BAEB835B32034CBE4447837CB9C2 -:109F80006D937BBD7F86E44A0CEFB37F95D6B8E531 -:109F90006D5ED6E87C57C5DCDB5FD642F43BE82536 -:109FA00017387F2F2340E5BCAC8D0639BD2ACD7C08 -:109FB000BF9B1126FDBCDD74FF6D10EF3B23DAE57E -:109FC000F3DE0C4A17F519543E9FDD77AB6738E096 -:109FD000A959D0801EDECA8C4E007A5BDD789AF8D3 -:109FE00011FE89D5AF0CC67E171E0EFCB278FE702E -:109FF0008C97AE15282AE8E9E5FF25C63FD912BDA2 -:10A00000C700EBBF7740FFE1A6EF10FB433646DF0A -:10A0100032895ED90879856745731DC943D9E7A799 -:10A020007947283ADD7ABF8C2783C2EFECFEA1E1A5 -:10A030007B592CD0AF1D7F0CB5579171F707348831 -:10A040003F1EAB9092D7E349BEBB3FB0572AE8CB47 -:10A0500017E9C61FAA1D7876FFD0ECC081D6FD890E -:10A060008C8241D9F5172B1E79B004F848699FEC12 -:10A07000267FB99C3ECEFC564EFAE1CF998C2ECE6F -:10A0800024FA9FD7DDBBEDF3B9ADC63E1FCE2F67D7 -:10A09000120D7EC80FC7A34FB2DAA5A87CFA00E75D -:10A0A0001CA8FF37DD3C3F9D6197134079104F5B43 -:10A0B000CBE4CD9B758F84AD7870AEFFACC8F6074E -:10A0C0008FD1BCADB1B1D57387EB29FAAC6470F810 -:10A0D000A8E992EB19673F7FEF74C8F5DC4074C8BC -:10A0E000E582B3FD3988F3E3A5AF963505E232E7A3 -:10A0F000C23A2D236D011C9141A5ECDC32D247C33D -:10A10000B99BB3FBFC08FECEA6D9E64D8CC52C70DE -:10A1100066DF7513ACEBF90AC3CFAAA59970AD0D34 -:10A12000A693E88D23487E8144EEEB7AED44D60277 -:10A13000283F724404098D6EAB5D2DC1FA1ECDA07F -:10A14000FBCE559B8E127B70A874BEAAC6AEFF2FA5 -:10A15000B375F4DA59724F09D04F3A383466503833 -:10A160002C8B2D9A0FF2F98E4D0291B74D193AF5BD -:10A17000D7CA0691DBA891EA47A462786015721AE3 -:10A180001601F0F832FBFB63724CB19E4FBA6BFBC9 -:10A19000FDF3C13E74F24B0ED34F481399BC8F7F31 -:10A1A0003B637A4A3EBF25D41C1C81AB5C9BA1F16A -:10A1B000FB61099FF2F55C9B41D787EDB46F93BFBC -:10A1C000BBC4D687A20E7A13DBAB7E04F09FAB1222 -:10A1D000BBC0EFC5721FF2E6BEE1D768DE1CE52BFF -:10A1E0006EEF38DBDF2CC76D76E3FF05B9373CBD7A -:10A1F0001DF20F7DE15EFF7D06B7BF95BEF8CB4730 -:10A20000A42F8E86759B9DC5F5C6FF03C8D629333E -:10A2100000800000000000001F8B0800000000000C -:10A22000000BDD7D0D7854D5B5E83E73664E669221 -:10A23000996492CCE41F9C49000324780221444095 -:10A2400098240482609D408060030E081A2584A82B -:10A250005879AFDCE684440C14BDF1E7AAB55EEF93 -:10A2600010D0F25ABC0D965A54DA8E54507BF53603 -:10A27000F88BFDA2466B292085E8AB57DB8F5BDEB0 -:10A280005AFB2773CEC94C08DAF6F2BDF0F19DEC0B -:10A29000B3F7D93FEB7FADBDF6CE098B3A3FD34341 -:10A2A00088B655264F10423E3CF65935961FE8B504 -:10A2B000B82528AFD8B84A0E390949C692979013E5 -:10A2C000E1C529583E8F3FB3873E6F7A44269142BD -:10A2D000427FCEC3FFEB5B920CE513DD890182E385 -:10A2E000CD7285C7FA09D9AF108D9412F2C1B6CCE0 -:10A2F000F0162857DB89E69C4CC8F4141F1DCFB319 -:10A30000F98B56F724984FF77F14937C98DF3D77AD -:10A31000AE08150D1DF72F6E0B215361009FCF4224 -:10A320003208B9C3CEC65C9D4C02D83F81F19ED0A5 -:10A33000F52FBE7BBB9590C8E5503F06BE2B8B7EAC -:10A3400067EE7FE975578EC675BF7DDD8CD1AB8A10 -:10A35000A2DFC583C35229F42F4B70DC365945B8B0 -:10A36000EEB937A1B13B06DCBE8D709D3A747CFC22 -:10A37000B1C23A16F3DF976CAEB8CB0520D9923450 -:10A38000EBAA508CF1DF26A17BA6C278DA66369E56 -:10A39000799C6BF8386FD7DFB004E1FFB926BB6555 -:10A3A00080477F839C5C8EDFD5DBD4B1D07FBF76C6 -:10A3B000BB6BAD6E9EBF8D039FDF36DEE08A8507E7 -:10A3C000F15C566FA4830FC8C06BD3709CDDB1E7FE -:10A3D000B75ED09712BAF74A98DFC9AB655583F9D3 -:10A3E0009CB4C077482F8FC277BEA1DFADE2DF7D7E -:10A3F000B07978BA5C5C639CCF92638946BAB490BA -:10A40000C69E18EB59FF15E97E05D2BD3D5ADEA365 -:10A410000C8C72C3F71FEC3CF7DE9DB89E9D89142F -:10A42000DEE67E9253653ADE49E41384D7F604CE25 -:10A43000275DCDCFC1771F5C93A36E2143F9839035 -:10A44000AE6F4C87FABE6E4BC976A8DAD39DD4188E -:10A450008E31DFF1A98C0E3CB2963801DA93771871 -:10A460003E90DC906F96707A7377FFB08558A2DFCC -:10A47000BD83749040C81BAD76FADCE1B6D3F1EB36 -:10A4800016D62A3E1867AD9504107EF407FA754F6C -:10A49000C8DBB91D867ACBC2CADA6AE03F69E87CBC -:10A4A000BEC7E9724F78D1B0F0AD6F900DF0AC5BE4 -:10A4B0006884AF993E8F872D35B1D62FE839DE7885 -:10A4C000D7D9C25EC4D331BEDEB7F97A7FDBD8EE0E -:10A4D000C2F6E671F684BB87E5836F361AE9E2427D -:10A4E000EB3CE6F653B82E0F19BF5B566F5CEF12CC -:10A4F000D272150152594A541B3EEB484BF173007E -:10A50000CAE38F2CA6F3798B909A1E9CEFB9DB8B54 -:10A510006B8BA3FD1FE6F0FEBCEEF66B50ECBCA30C -:10A52000B414BB63CCE72D0E2781EFB7E2C0F379FB -:10A530002E77DF413C23BD2E9563E2F96DCE47EFC8 -:10A54000340CCF474BEB86C7F3EFDD6EDE4F7B223B -:10A55000AEF38418F75136EE89307B2FFAFBFDDF1E -:10A56000887FFB89760BA5E370A21BF58807C9439A -:10A57000A7475A53B9FE291C5E8F88E71B42AE9A43 -:10A58000DAD75903363D3E4ADC8CCF45B96EA1710E -:10A590009EEF27BBD9B8C43D3AE8D2C90DAE5F855E -:10A5A000BE7BE0C989EFA3FEF471FEAF0B7E6A4368 -:10A5B00078807CBDCB85EB7ADDE246F95A762C605B -:10A5C000D3C3EFCA1406BF93BB8787DF955C1E5DBC -:10A5D00048CE9AD7FBC13FDD3D19FBFDE09FBEB0E1 -:10A5E000E9FB5FFA652E89A447CBD7D74B81700C66 -:10A5F0003EBBDDAD8C08EEB79BE078FD97A369FF0D -:10A600001E99B4F4C45A17CA37E87749B0C2E605B0 -:10A6100078DEB0595225E882A4B27E6E10F2CEEAFE -:10A620001B5D0B70F7B6B7DC118CD14F3987F79FE4 -:10A630009CC194587C36C81F9C1E44BBA5D6902D47 -:10A64000567BB35EEDE77C6E6EB700E9D13B727A64 -:10A650001CB4834CED473A8FE9298C2FD313227F0A -:10A660004479448A8C76D805C735B5378F3B1FE1CE -:10A670003E35FEF827FF2A37C682C3B75319FD8639 -:10A6800082403F31EB5DB4FE75C2F4AB164EA2FAC8 -:10A69000F0C4EE1BEE45F3EDC6F9771C4135F972B7 -:10A6A000B29F8EDF103C5A8D6025E71E988478FF9C -:10A6B000BCE6817B4B616A279550BB0B3E38B945A0 -:10A6C000A2768B799CD7B93E7913E5E9E5D81F616D -:10A6D000743B077ACB06B0CB81752854C8B7137C7E -:10A6E0007A3BD5B3E98B563209ED87E01617BC1FCC -:10A6F000B7F9D38DA8970909D3EF3FB2A93753789B -:10A700001366E7F6753B776E8776AF25337C10A22C -:10A710008E0E16EBE484D54DCB23C5CF1B71F073A1 -:10A72000B1724AAC33DE380079FA7D6D95B353BA15 -:10A7300002ED1DF71D088F816A97BB1BD6539B1036 -:10A740005880EB3BFABAC5D2E6A7DD527B6511FE15 -:10A750000643FBAFF67F17ED99450BE58003CA7DF5 -:10A76000F81EC65B52E9D4A41450116F2CFC11E200 -:10A77000E781BA049F0C24513BDBFD4719DAD7CEA1 -:10A780004BF26D8172596F7E9B07EAEB6A2437F6B4 -:10A79000F7E2C229AE7E585FD226E827073B3B5E30 -:10A7A000533586901FE2AFD3099B30C0E20D22EAF9 -:10A7B000D3B6CD017930C1BBDFE204508F494BDB0A -:10A7C000668779DED516CC72A742BBFB4E74DAAF32 -:10A7D00022242323D03B5B2524E1FE5335F651B0E0 -:10A7E000CE47797FDA279D8199A04F2D21BF04F5AF -:10A7F00093EEB7CEB75E09F82F10FD676DC3FA254B -:10A800007357ACDD0FF5756913E65BA1FFB2063136 -:10A810009F2BE65759E1FD4CD1BED481F3F5248935 -:10A8200032CCB79C105B7E74FED62C183F4D94CB77 -:10A83000E7CF816FDFAA68A9B242FF7BD2666D2B9A -:10A84000721032ADA6C21D80F53C75FF92F94940E9 -:10A850003FFB09D029D4EFBB7FD97C9CBF47B6B062 -:10A86000FEB57A3ABFB2066D02D64BA4615B0DAC61 -:10A870007BBDBDFF0892EB864D9A3D037E49921841 -:10A880009DD86D2D815C80BBED404524974EA78BF4 -:10A89000D1675EA418F5D860B910CAC5BA72162B74 -:10A8A000EFDF42AE8F256F5BD299DCDB9F18BB5E7A -:10A8B0004A63F218E046F549CA3112D81B43AF9CEF -:10A8C0004875D276871389664F8BF2DBB5C0C3E536 -:10A8D000C097C4CEE629FA1942D75CEE10EDDA34FF -:10A8E00094A70B399D16A812F577494B52782C3A4C -:10A8F000D824625D8C2248B6D0F97A65E9FA5AE824 -:10A900002F239184F6C1D39B4E6819BE0FEC73467A -:10A91000FB7B95B116A92E08EEC6FEAA33B34BDA1F -:10A92000FDD17E60DE1DF6C986795BCBD3B07E514A -:10A93000C9AD453A7816B175001DD0EF60981FCDAE -:10A9400006BED8DF3B211FEDF7A7538D7C5DD65B9C -:10A950006923F0FD92742E4F7CEC7B6F15933F03BF -:10A96000B72685915F895D2D09EAECCEDC34068F30 -:10A97000AABB173E8CED9A7A6D2401DA6DDC5791F3 -:10A980004986D18B4D5FCE20E129BAB235A2A0DC39 -:10A9900069FA72167D5F75F7AB0AF229F6E38379DF -:10A9A0006D74043255845B7B6CFC83434EE7DDF4AD -:10A9B000652AD1A6E8DF333845FBF7D0FA0BAD2B7B -:10A9C000DA9F4CC2E9C3F5A7D0FA41B85B39DC95F0 -:10A9D000D8F3ACE4F042785B74F575486F4E2AFD0D -:10A9E000681CA5EF1B45DD28EFA3E36EA1FDEFB7C3 -:10A9F000021ED10EEC4DF4A15D5C6605F9E9C1FEC5 -:10AA0000D2DC9A14A50F411702AFFBD35A2AE87A79 -:10AA1000AF91DCDD31ECF8F9827F16327B2CB3216B -:10AA200024AFD2D1BFE007E87F3FEFBFB49CF2CFA5 -:10AA3000BF327E00BE5981FC8B760BD2A11A295EF3 -:10AA4000E41A3AFF674076607BC02383FF35CE303F -:10AA5000CE47C06D28FC732F80CFD1B4BEACF79029 -:10AA600082F4D614876F17A427D3EF328F4592D183 -:10AA7000AF7D8EDB1DFB7BA63866205F2CB41014E7 -:10AA800061B86EB457CB660AF9FDC42B95207F33AD -:10AA90004519E5AD0FF130287F23767BB4FD550FC6 -:10AAA0003C31BF03E57302E0BF88DAA176A2F32749 -:10AAB00036A53139561E2231ED96DA7466B708781C -:10AAC0007F6F5315F91DACEF502AE3CBF27E4D5A40 -:10AAD0005514E56BB39C7A98E3F141FEFCC7CB2992 -:10AAE000E90272AA96CB29F6FE3098F9D82E2323D4 -:10AAF000522C814E5CFDCA94B1E8CFDC9625FB3E1A -:10AB000006BE5A2CA9A39E827EEBEC3E1A27137434 -:10AB10005247EC3E27C21D8CA6F312DA070E5AC626 -:10AB20001FB44B3EEB92181D125F4A5D717C3924B5 -:10AB3000E6715B9642C75BBD6D6C4A483F3FAE27EE -:10AB4000AE4D883C450A86F2B928C3FCD75B645DEC -:10AB5000BD93E9B33FB8024FA741F9288F43812243 -:10AB600003A72A3AFEAFB93E31DB4B8B93399FA046 -:10AB70007949F9D8429DD3CCCE8430619F68E8A74B -:10AB800066F6303ACA6C88589A747470242D8F36E1 -:10AB90006A5806956077D5D8AB021FEBE4D8CB1284 -:10ABA000A9A7710412998A7CFA521A31CCA3410EDA -:10ABB000E64968B76626A82867004F140E871DC4AB -:10ABC000EA80715F8227E2AD5ABEF5059B07E94036 -:10ABD00052DB29F47772FB944450DF5C3B3B89DA0B -:10ABE000ADE4DCED63305EE14D62740BFDD8793F7E -:10ABF000764A275CEEFD66F4F86ED44F427E0A3C3E -:10AC0000907332ED4FD41F966AF3DC503EECBDBC1E -:10AC1000A45D32DA3F680F45EDA7DBB6CDB3A2BD28 -:10AC2000D313B1000BB5691BE7DF897638D84F0E17 -:10AC300058CF47694C0F1EF66B7232F63716D601A5 -:10AC4000AF8E24868A5A9C517C808D1342FC6528E5 -:10AC5000F07432FEC0675B3AE33397873D97F16744 -:10AC600046326B6FA6B79B787D00790F9EDB2B98E1 -:10AC70009C30B7FB6FCEBFEBED5A4D46BEDEBE0A31 -:10AC800012A4432B6176D65F39DE409F517855DDA3 -:10AC9000DD90827AF3F3DE2529A4282A476DF63762 -:10ACA000467F0C72244216FF33F2ABF2964CD05E14 -:10ACB000BECB067400ED94D4903B0D9EE949B1FDE6 -:10ACC000E6317C9DE9E85743BB7BB9DF63FB722229 -:10ACD000F5B733B87D969C5547E53AC2D207704E1A -:10ACE00021039A5B87C794728BC17FB07D39897EBF -:10ACF0007FF1F643491CFBA1D4603F8871CD76C437 -:10AD00007BAD5974FEE2FB15596F56135DFB95A49C -:10AD1000FF2EEC6FE5C65C43BC289EFD319DC3074A -:10AD2000ED052DE6BC14C3FBF7C05FD4F4E39F60D0 -:10AD3000E347C74D02868B8EFBD7B4C08C741A0FC5 -:10AD40009AE93E3E111E60C39F97A9DE61FA1A9EE2 -:10AD50003B9D542FD5A0DC167E12F2BF3B05F9BBFC -:10AD6000A22ADDABD393FC3BB33C3AC8E31A07B944 -:10AD7000BE493926ECC6449F2445F5CE50BDC5EDED -:10AD800062937CBC909D0D74ABE9ED8021FC92FE3A -:10AD900055EDCB8238F431EE1F625F96CD0CC9C5FC -:10ADA000283F6B2432161ED3E618F5FDB7D39D74E9 -:10ADB0005DDF0686D3FB2D8B1A8CED5AD399BFD25B -:10ADC0008AEDBC1786A75E1F4932CA3DD65F33CADB -:10ADD0001BC0B3FFD4EB8A0FE4F0F3DC1EDAE50905 -:10ADE0006C45BAE8484C9E847AA223717418E31229 -:10ADF0003BFFBBAA7027FAE9AFD9D46EECF600F39B -:10AE0000F32B966F6CB7C27B5B8FE44E20D1793AFF -:10AE100037498135404AF7737C3579D87A9A3C11A5 -:10AE2000650C8C9FD3C4E691D7F38264D5C9BBBCB3 -:10AE300046D6EEB1749B41FF8479F9F17411EF08A5 -:10AE4000B7559762FB8015F741727A241A1FCE69B5 -:10AE50000140003DE4A8AC7FA71A966E288AAEB7E1 -:10AE6000D3525B847AA2332349453D71CA137A12C7 -:10AE7000F9A8A92F1241704DEBEBB5A2BD67F506FD -:10AE80007E807010EBF4C9EE1C94B3497D6C7E5D3E -:10AE900026BA27E4BB3C3EDBCDE4AF4C5E268817E8 -:10AEA0009421305EC69642AAA744FB8C34AE37325A -:10AEB00048E8696A67914E42F146E83A32B68CA397 -:10AEC000F6BEC06BD4AE1A3F19EDAA821D11EB6A13 -:10AED000B45B1F8B1DAF3FCCE50FAC2342E5C481B3 -:10AEE00091C565443B5B1CBF5AD07D524D6C7B15B0 -:10AEF0003401ADAF58EEB90ED7DDD4A19004290AC4 -:10AF00007FAB37F806CE27A767A784B031D3594760 -:10AF1000DA0FA55C58E7ED3713B74CE2CFBB699366 -:10AF20001C58A3E7E70E85E265A762DCDF137EC647 -:10AF300069AE8FCABDC1DFE1F8CD07EE5310CF3740 -:10AF4000EFFE50196E5F67A470931A99FFD2546F89 -:10AF50000FE37A2B965B291ED7752861944F4D7BA2 -:10AF6000F7452C68676F262AF27F53CFBE2339003E -:10AF70009FDCA6C054D9A7F39F9BC212CE2703889B -:10AF8000B1B788CA4D05F5B699BED14E467BE58866 -:10AF900083F1FFE90AA786F1B4D3B65013B63B9DFF -:10AFA0009DA46AFE28DC5FDA37EF650958DCF5748A -:10AFB00042049F9D96EE2C3BB4EB9CA0A8484F56B4 -:10AFC0006FC8EE8175A45983FBF1FB548F4B6D83E1 -:10AFD0006F7D096432D5D72384C334135D4CDBCC39 -:10AFE000F865BA2759D88193512EE57B5CC28EA2B1 -:10AFF000F2EA888DADA383B0F9B6A507323D48B714 -:10B00000EE343A6E4E5344423FC03C6E94AE02A3BF -:10B010003CDE8B99678F82727E1D973715CB774BFD -:10B02000BFD3D1419187EDCFE6ECDD29A17F08F5B3 -:10B030006DD51EDA9E24A0BCD9CBFCE27550BF565C -:10B04000275FC43A62C89929383F675FEF8B4CCEBF -:10B050004428FD89F99AF139DBC3ECBBB96026D0ED -:10B06000F78A56E883FE8EE427D2FE04DF9BF9744C -:10B07000B687D1794EFD6EC95244E382D49E14F353 -:10B0800013ED76792AAB3C140EBD140EEBEBAD2C10 -:10B09000DEC0E753AD04C7A05F56EB61FB5D87964A -:10B0A000BDAFF443F9C19F1DA5F4B8BE4B0A507F54 -:10B0B000A1EBA8B204E376DAFF91314EBB80992868 -:10B0C000E4A19F1EA57A65C17E168F5FBF7F9FF5A5 -:10B0D0000667944EFDA70EAD443A5BDF93401C1209 -:10B0E000E28FADD74CA7206728DD134DA1FB5C2074 -:10B0F00027352A5749C88F7E8A90C36DE97C5FCE79 -:10B10000C9DEAFE1F316FD46E5A783D2BBFFD4E469 -:10B11000437680E77A5552C174023BDC47DB43FF3C -:10B12000112A878144D15F13FD9BE1D7E5617A2D18 -:10B13000069E5B3C31F489D0B3FEC72B093E05FE69 -:10B14000AC1CEE83FADDA3D07E5B3D563A9F8E0A9F -:10B1500016D7EEB0313DD2D1660F235FBF943AF7D8 -:10B160006509E4A52B4D89E0F3B0657513D61FCEB4 -:10B1700061F3E8B46C296C617A4CF350FC2513261A -:10B180009F983C7AF0274C9E34694EEA3F3685EA18 -:10B19000D6D07D098F43C57D09127A5159E28AD2F2 -:10B1A0008319BFBEA75F507C50BFA087F141146ECA -:10B1B0004C5F09BA053947F1DE26E2888037842BD7 -:10B1C000F8F56D187F107E7D72435073F986F26B2F -:10B1D0003AF7EBA772BFDE566EFF9BFAF5EB36FD32 -:10B1E00007F5836EC97A853E05BF80FF68E0ABA78F -:10B1F000B89F763F7FEEE7FCB9AEB487F2C3BA8F53 -:10B200005B281F396B983C71F619E52021F7F0F5A2 -:10B21000EF60F498D43317F725AAFF4D72B793F86F -:10B22000F3BE496AF94FCC9321FB78FEC639B0F2E0 -:10B23000CB00AE0E0E03DEEE08E7FBD37B0011C899 -:10B2400097D61665387BF842FD92C89B12E27B1DAB -:10B2500087F5E9BD5557FE1EE38C7B52683ECB2730 -:10B260007B17FFAFDFC3F7A777CF56514F7BDA834A -:10B27000947E06BC0E15E3A7203E6B24A087B69EE5 -:10B280005F25CFC0FDB21F5D3119E5E67B7C9EA72F -:10B290007E226F42F86CF9C18F6761FDBAB0948E5F -:10B2A000F6E3E93DFFF657D48B8DBB37D0BCB4F63F -:10B2B0001FFD92DAE596F04EF67E4F0AB5334FEE5B -:10B2C000BA6F16C2BDBDA79DD69FDAB593960FFD86 -:10B2D000E0C7BFF80BDA1DC16415DB9DFAC97DDF3D -:10B2E000F90BD2795DB28AEB680A59D97EAEA06FAC -:10B2F000B3DCDAF702E553412F0B50EF229CEA99B9 -:10B30000FC11F4FC11DF6F5ACDF7B13EDAEE6A8C16 -:10B31000156794BC6CBD188BA172AC5EA271B64E61 -:10B32000A01A8C77742692727C261545945C186757 -:10B3300059C3BE59D4EED13EBC11DB2F3EE020DB19 -:10B34000695C0E83BAD17DB0621083C7C16F86DE9F -:10B35000779F07BA7D1BE403D53B267F6071E72BFF -:10B360007F46395A67EF7F0145A178DFC9E337D0BF -:10B370009EEA9DB28DB1E3A40EAF93EB6DA6377339 -:10B38000F6D7E6F9A89C4850C7EAECD351C75AB69D -:10B39000637A524E63EF5C5CC7D585ABA650BAC0EA -:10B3A000F81FEA1FCD49FB5F8FF14BE0BF1C2F93C5 -:10B3B0009F196EE2990EE3575B89C7894F42DEB44D -:10B3C0005139F204ED17EC0F6A57F97EB9EC09B464 -:10B3D000471EB285B2A7623F9D5C6FED66F386EFB4 -:10B3E000DDB88F0AFDB9A74FA6FDF4DAD2E8F71A47 -:10B3F000FB7EDEEE36293A5FA0D4D1A8B7B0BF52AB -:10B4000027EA19AD9EE2C7A7D0759DC226D974DD83 -:10B4100093561447F9D71CF7417986FBC3E5DE8ABA -:10B42000295E6FF429E2416678DE89F5D0CF33DEFC -:10B43000007D923D467F3B9EBD7268D919A67F9FD5 -:10B44000FF90CA9B66A4631C3FF4B141FFDE20E875 -:10B45000F8D90F291DDF7080E9DFE603250AD2ED58 -:10B4600027AD01F23B30409B2B816E817E1F92FA0B -:10B470006FA4F92ECF3ADC18D73BC3F5CDBA1D1F08 -:10B480001E97011EF907B2A99F7FE659473DF67343 -:10B49000D862A1F03CDC3D7167BBA49F27F30BC0D1 -:10B4A0000EA6A4DA0C762AB383D7DC877EDAFA46B6 -:10B4B000A222FF379BE8A7F9C0514A2FC20EF63FE0 -:10B4C000BE680DB33F1DAA03FDB839CC1E25608FA1 -:10B4D00062FBD439E13685D2574919D2D7A165BF6D -:10B4E000D88A7ABC790E7163FF0F8D0A3C9B4BD7CB -:10B4F0002311CC7379C8D6556985EF1FAAF6B90117 -:10B500009200B7DDD4EE25850AD7736BA8BDDC9C0D -:10B51000F54D95F299591E3CDB46EDAE665F229DD6 -:10B52000CF8203D26DCC1E7112367F89D2E782F0B2 -:10B530008C30C6CFFEC8E127E078C6D6BB12E171D9 -:10B54000E6A7408850BF600EA3D7D4393D548EBCC7 -:10B55000F4EC3CAAC7055DBA9E49A0FA3CCDEA9638 -:10B5600054AAD71627E8F1DA65637A2995EB998210 -:10B570001D0CBF6D5EA697DABC16FE548CF117B792 -:10B580003609F5EE1F39FEA91841F9CEE5C9FA359D -:10B5900011CA4F4D7B597F9E8440C9ED3AFAF5544C -:10B5A00031BD28F603707FA03686BC7892CFC3FFEA -:10B5B000F8EAFBD05EBE1AF08E2A25A790CB51A0E8 -:10B5C0000B845B4E6390D2C1D59E9B54CC4FF5A6A5 -:10B5D00013EA2F0EB4292456DCE7877C5DDEF46085 -:10B5E00029C6A1BD992E6AE778E50A8B03BF2B9186 -:10B5F000D46E1FDDF7A476DE80375BED36F07BB0CE -:10B60000D402ED4E64B8189EC3BFB12E2A463EF454 -:10B61000097FDD60F70DF5BB99DDB8B04B9B847EEB -:10B6200088D8D7107008B725D6EBE5670F976FE17C -:10B63000F12C9E0AF6BD93C6B5DD300EFAF7DD3368 -:10B640007631FFBE9DB6FB9E97D947D5B03EB4DBA1 -:10B65000BC05C18D4C9FBAD458F028E77AE5D0B22A -:10B660009525E85736D73955E4B7079F9756537A4B -:10B67000C66021FADDA135140F04F080FC4042CCF5 -:10B680002F6D6E098663D37B2DE5BF66E43F89D2BB -:10B690003B8DC303BD8719BD33FD27FC7F948FFA13 -:10B6A000BC432107847C6956FAC7211D0B7E689E26 -:10B6B000D53F0EE136527972C606FC8FFC0370400E -:10B6C000FE11FCE27A8EF1C9F6365F05D66FAF2621 -:10B6D000EE769D3E32FB4B384FF43B855C3FE509EF -:10B6E0007E8CF2B7D912D98AF915420E373FB76D61 -:10B6F0005CACFC372187ED5626DFECE1A470BB8EF5 -:10B70000BE70CFCF35993E693E4FD2A6D8F1912F6A -:10B71000BC4E1EC71F59BE4406EA729437DD493439 -:10B72000AF5DC48BCCFD9EE4F426F022FC16DC77E2 -:10B73000C0F6E9198C5E940CC69F7919223E1B361F -:10B74000F83D3E4BE843CC338AA7BFC4777FABF8C4 -:10B75000951847E85133FEC5BE09AEA7B6287EBB93 -:10B76000AE17987C32D3E3182E373EC4B5C2FF7FA4 -:10B77000E7FB5C43F1CBFA21A1F186BCB84ECBBE0E -:10B78000C65871B0175A79BED463E3479477F7EF80 -:10B79000BCFDBD3C2F8CAC196FC8B372AABE368CF1 -:10B7A000A35E71D05722D371591CCB358B7C8A7A1A -:10B7B00038B9BCAB10CF4D7883C6FD92CCFA44C3E8 -:10B7C0007E447628CD50CE6DCC31B41FD5926FA873 -:10B7D000BF6CD30443BD5F9B6C2817744E37B41FF6 -:10B7E000DB5569285FFEC8D586F6E3C38B0CE5ED13 -:10B7F0006D3DF58897897BAE337C7785B5DF520246 -:10B80000EF8B7B561BF3C74CF0ACFCAB1C930E6F5D -:10B81000CAF0537C5D71C0088F9472233C305D0E7A -:10B82000E19C42787F897F5687CB6F4D21D63FF5CB -:10B830008BEFFD43E981D8DDA5FABC8428FD840D9A -:10B84000798B9556D9340FED2BD15FBC798AFDB633 -:10B85000B8EB8803B7ED837CCFE062E3CB4A995520 -:10B860003F2C5C6C17820BE957470217F37EDF60B1 -:10B87000DCD9D4DF96A4669A27FC261674F6717F6D -:10B88000ABF13CCC522D85E9A1E0E20BD8D12C0ED6 -:10B890001C4A60FB95E6FA57B85CFC03C084CE678F -:10B8A000847CFD3EC7431FCF9F1FC2D79B3E3D9C5C -:10B8B00089F2BB8650BFD9DDD2F629EAADEBAD11D6 -:10B8C0005202F37E90AFE7212E171E6975D37E1EBC -:10B8D000E5FB918FB5FAE8FBC75B0BE933DCAAD235 -:10B8E000F7DDADE5F4B91BEC397C3ED95A439F7BBB -:10B8F0005A83B4DD0F5BEBE9736F6B88CD6B08BEC9 -:10B900004819B57382E931E3A5AB347944782272E2 -:10B910005E4C7D19B71FB961D8FCF24D7DD28F5FA7 -:10B92000D4F1CDBB192E0FDDDF9C46A6E1FEE685E6 -:10B93000BEFFA295FCF8C5B123E723414FE45CFAB2 -:10B94000B8608CF85188E7553E9911FAAEE68C0F35 -:10B95000AF289DC586539DFD4C0E3AEB93D066D023 -:10B960007D2FCE9F88725D2825A6DDE0CD64F45939 -:10B970009FC0F6E3979BF8FB5BBCFE5B994CDFBD79 -:10B980001B47CE38332DC29FB7D1FDC1217C77EF45 -:10B9900055B1E0BB35D367E063F3B915733FEFDA18 -:10B9A000BA46A931F8EC42FD88F599BF5B9AC9E423 -:10B9B000D6C64CC2E4E4FF67FCF9EE5A17F51F1037 -:10B9C0006E5EDDFADF5D9B541F2B2EF39D4C1BF347 -:10B9D000B703A0B3D3A8A9AF29682B16121FDBF7B2 -:10B9E0001DE3C6F890C80B884FAF561A47A2309493 -:10B9F00087C215F0E1530AA07FEBE038112B8EA32C -:10BA00005AA2FA0D736D88EEFC873C941EE07B4DC4 -:10BA1000A1793DFD3938BF8BA527223F3676B87D09 -:10BA2000BA21DF5FA49CB931F3EF2B67049F9373B6 -:10BA30000F8C8DA527EB51CE4C075193F9289333EA -:10BA400017E8F762E1572FF7D3FDEB11C3EF8067DB -:10BA50004471A92F1CC993D0B8DA6467CF3B139304 -:10BA6000BBF1F9856374982413F200CE13DA69955B -:10BA7000849DDF7A5FF84D2DD3E8FE4A76F05F3281 -:10BA8000A17EB5C2FCC53319818732615D897C5FB7 -:10BA90003891EF0B2B99CA562C9340215DD7247017 -:10BAA00097316EB1D5E21B8DEBFA5852C7A3DFE296 -:10BAB000B684557C26934831CBCF0B87D05F4B9F04 -:10BAC00098E8437F37711C21BD343EAE3A308EA6D4 -:10BAD00024F5BF3E06FDDBE7AD345E3409F351A12A -:10BAE0003CE97BB9618DCE3348E5453A87E376B4CE -:10BAF000CBE1FBEF4BA1A770DE27DD76CD02F37A19 -:10BB0000A0738A230DDE47F6C89A9282F931A7EF17 -:10BB10005F00EBBDA257A671E72BC89457C6A09C47 -:10BB2000E9B5D1FDDF7556B203F9281E7C3FF95601 -:10BB3000EC3C30922519F2BBCCF51F703DF0499CCE -:10BB40007CE3DF70392AF2676C227FC61B18367FD0 -:10BB5000C666CA9FB1598304F7856D83F9330D8496 -:10BB6000E6CF403FFAFC994F2A63CFE31D3E0FDB3F -:10BB7000974971FA4DA6EF3FC91F7E9DB62F1D86CE -:10BB80007CECE8F74EFA3E5EFECE001FFF9338F9DC -:10BB90004BA707FBCF265ABAFE3B46CFD171F268BE -:10BBA000BDCD940714AD67F93F1DA98C4E5EC872D8 -:10BBB0007B5641D7AB483F3DCF79BDD363C3785265 -:10BBC00090A8FBE8F91EAB6DA05FF0613EB6B37EB6 -:10BBD0008476B705242FDADDD76FB27DD4AF935BBF -:10BBE000B5016399607B9D1C5E88316CE4A7098573 -:10BBF00034FFEF33E24B710F23471BEC72D0AA5B8B -:10BC0000475F1C3BA2348BC1A72F3B36FC466559CE -:10BC10000C79CB43BF4FE6E73ED839B4DBDDC3CB6D -:10BC20004F846F285DDFBF190F1E5A7F21387BDBE1 -:10BC3000197F0F54482CCFFF6F0EEF549EEFC6CEE6 -:10BC40000FD84CF9EA0BB3CDF366F9EAF7A706CBA8 -:10BC5000B2D02EB3FAC6E9CF0BECB7069226C3B327 -:10BC60008FCB1D335C3667317BCFBCEEFD3CEF3EA6 -:10BC700051262DFB74F037AFB785E351B4EFB0B167 -:10BC8000FD2C147C76907B2B0893B3CBB2F2F93960 -:10BC900097542BE2AB81754156B88FD0FD2501E753 -:10BCA00021F0E37037C331487C2B31BFFB42F05C9D -:10BCB00075345141B9BFD23E70187DD5FE5ECBDBE5 -:10BCC00063E0F9A173CCF1DD04F7E10A9F39443058 -:10BCD0003EA2B27C0A3287DA3D92962B9F9F387241 -:10BCE000BB676B72A810F9E26389C56B853EDA9A6F -:10BCF000736A1CE6D7BF9F5651943D95C6DF03E992 -:10BD0000483F3F4F60F4F308F404E50DBF184FCFF0 -:10BD1000C12FC90E4DC8F646F3FB4860601CE623F0 -:10BD20005C2C7CE0C786F47321F8ACCD62FCDD9717 -:10BD30001C9B3E1EE37C7821BEA0E7CF4AFF7E7CA1 -:10BD400021E029F62FC4FC266433392C9E026EE6CE -:10BD50003CA209D916DE8EE5112DC90E52389F1D61 -:10BD6000F5E97107CCBD4F897DAF434F1CFE30AF65 -:10BD70005FC0FBEF257FFB1263CFEFC5FFE1F91535 -:10BD8000E3FC008E7D9362CFEFDD11CE2F4806DEFF -:10BD90004FFD3BE82FC07331F21DE918A072B12F9F -:10BDA0002DF63CBF1CF13C43B6BF879E15F44DB445 -:10BDB000558D74DF3E2B31E6BEFD52F0A3D00F321D -:10BDC000EFDF8B7D7A901F74BD75F68195E988F75A -:10BDD000397CDD1924928AFB9ABF48A0FB0043E41A -:10BDE0001AE77380978DC26BE1008D67F48D8B2D00 -:10BDF000176CD90C5E83ED3BD938F1CE1FB8387F74 -:10BE00005EE8FC01290DD1386085DD1991010FB77D -:10BE1000717C28B9B7A868175664BD7A0CD709F0A9 -:10BE20003F3D084F5D5EDFA9D697DD636CF1E5F617 -:10BE30003AF9E9B29618EBF167847C280F06DBED3E -:10BE400079C53D4687AF62D26F61E7A7072C06FF31 -:10BE500038935C947FFC3307E3E7F7D382541FA049 -:10BE60007E40BDB3F5B92B4B1099685F605ECF8003 -:10BE70002B91CAD1F69CE9853E1D3C2BB3855D29EB -:10BE8000C7B117BFDEB980A8BD2419ECD668FF562C -:10BE9000FA5EE0A7C2F9EB98F8F06704E6213C3FB0 -:10BEA0004F0BD4E03ACDF0D3EE9E994AFD6584DF86 -:10BEB000EC687F83F88F83E75B33028BB0BF89E93F -:10BEC0003E16BF10F97C83710BABFBB83D0AEF91B6 -:10BED000E2E55EFC05FCD5DBB2032BB17F2581F3E7 -:10BEE0002371D2F3E3C25E2126BB8694B3FCD21544 -:10BEF00059AFFE19E33E5B9319CB6EFD8E83E6D9F5 -:10BF00005D2FB9155C37D81FEF7D1FDA8748E4BD78 -:10BF10006FD37D2D616724C9E793463E4FE1375FBC -:10BF200028BFFA10DA61309F4A8B93EE731E02B27B -:10BF3000C906B951A9B067C53CA02AE8AF52CE3BAB -:10BF4000D80FF3FA9C9C4EBB0ABE4EE4F1C58D4758 -:10BF5000A73A902E2BADB6537AB9658E7BDC956DE2 -:10BF60008C7B7C4E16FE33DD0B2E64FEFF030B2B09 -:10BF700033F57197C1B8873897A6AD62F2D424E73C -:10BF8000843CB3D8D93D2324407CEE0C1A3F627028 -:10BF900007E71AEFBDBA4A94D13981F24C8E2409D1 -:10BFA000BF87755FC59F6475280BE50CA6F3E07825 -:10BFB000E0F565E1B3FD4AD587CFD952D0CAE61185 -:10BFC00066F987A4250FDB5BECFD328E2FE214743B -:10BFD0002619D88F1897955DBCDC51F7D9CAB5BE24 -:10BFE000A1F10CE27451BB57E1F33BE9766A165DAF -:10BFF0009C23C1193949F356F9D31CEFB853D634F1 -:10C00000CCDB4E243D545E3A9D7FD410186EE296F0 -:10C01000B0FC7D29F433E4B7E34A17F1C3FBB33F27 -:10C02000FF8220FED2F16458013E8DFAC9EBDC4854 -:10C03000F3A1BD41AB492F8524E4A3CC7AF37BA3C4 -:10C04000BEB2933E7A6E488A04B3CEA75F388E1391 -:10C050002F7E63AB64A81FB899D9C36F27B2EFDFF7 -:10C060004E64DF1DE37AA6394D212CBE63B7A33D94 -:10C070007FC675028F6AA23EE9447D62B705285EDD -:10C08000855E59BFFF5682786B3E504BE1F05B896D -:10C09000ED8F6A2B249AC7B094E7DFD51791D702AA -:10C0A00038B59C7CA6CF5E0EAD688272DDABA4383D -:10C0B00002ED4A6607ABF15E97F662A26E8172BB33 -:10C0C00023F4D44F711D47D93D631BF8795AC0C47E -:10C0D000BABDD0FFCEEB46A9DB714955035B314FAA -:10C0E00068601B71635EC910FA3D07FC00F4B00B79 -:10C0F000CB30EF0D6B42FF7A07B4CF7E95A8B40D1D -:10C10000AF471F05F12771BAC0F7B3E1FD064E47EF -:10C11000050725B6BFEF61F77FD1CEF17E2E3BFB41 -:10C1200075C3C18A6BA7C2BC0A7AA750F21E03ED81 -:10C1300031FF093310587B6289D57E0CB6F7E17E5A -:10C140003EC30FC951E8BD4984CBBF69263E9C114F -:10C15000E5075A5FC2CB1BB89E32F00DF603FE7A9C -:10C16000A08C6DF7D3EF3C8C3F54227E183F4F27B5 -:10C17000D11FECB72A3A0E95CB7378DDE1E5F36970 -:10C18000DEF7346BE405E4F719FC59C29FC8EF767B -:10C1900080E3326BCB612FAC27751351DB709406B3 -:10C1A0005F3BF6574A8232C2B9CCBDAD1DE7776519 -:10C1B000C3D174A4AF753905949E66DAD502079091 -:10C1C000487BB9AABA0BF09E3189C26549BD3D8C46 -:10C1D000F96D4B06EFF909F99702FF2C0BB1BC661C -:10C1E0002C37E8E2B522EF6F6902F8D531E4F7BAEF -:10C1F0001C662789EF37F07329A2FEA61C96FF71F3 -:10C200004DCEDCD21C9A97C4F2A181FFA76159C818 -:10C21000151897E6AB2C26011BAE6B31E75FC1FF0B -:10C220004B02B7537B7649D06897FE5662F8D69694 -:10C230004BD44E5C563FBCDD3A3747EC07E7B98F2D -:10C240002745DF0BBA12F27C11EA7794C335A0CFF1 -:10C25000757673C39DE752E977994FAE3F7F59F4E6 -:10C260001CCC06D33998667E0E66C381365B06D237 -:10C270003B3F07B3E1E0875BF5F97F024E43CFC157 -:10C280000CD0BCC7A54AF8053C1FB4F4165823B41B -:10C29000FF153F37F1229E9B981CA523D7758E086A -:10C2A000CBAB0BD0FCBE3C77928AF9289D96C93463 -:10C2B0009FA833D9A5EAF377B6B7B554633B914746 -:10C2C00024CEBD2C8DB35F7C7B0EB3B71F92583E3E -:10C2D00097B6DC4EE1ED95C931FDF97E6F4190E6F0 -:10C2E000D195E6F8447B1A5FC0BCD329F00C839942 -:10C2F000C6F0C5BE37CB07E8AF03FBAB2A5069FEDB -:10C300004C550ACB43F3A6074B6E2B8AF65B77900E -:10C31000E5EDD5053F3DC2F26F6B4B119EF1E4BADE -:10C32000597F01FD75E6C488D3DF29879A91FE6C99 -:10C3300095C1E56BA1DFB3AF2934CF8E6C0E4836C3 -:10C3400068F79357DC2A9EBFEBA808D656D37A2B02 -:10C350003D1F98514F2209505FFAAAD28DF97D8D69 -:10C36000A44BC17E1A4D7AEC16E78B0AF2E92DBB7D -:10C370006D51BA249897A816A0C06BDA3B242E42C0 -:10C38000E590904F667A26638C72A844C85D900F42 -:10C390002CAFAF81E93DF2A484F1A1B3AE1332F723 -:10C3A000AFA9DC9B2A849549DE4F3DF812B567049E -:10C3B0003C6781BC403F4EC2F793D8116EBABFA50F -:10C3C0004985986F3A8324527A1B6247F0F9950E9B -:10C3D000CE9FD94D424E56943393D48C1F188FD292 -:10C3E000B9D8E79B8AF7FAC073061FFF0B4BA0284A -:10C3F000E2477C91B005E0BC556AA17AC78EF99FEF -:10C40000F0DC2E85A85CFC99A6C908D72B49CBE2A5 -:10C41000857E8AF72339543EF626211E8E2BAA1DCF -:10C42000EBAB3151903E8DF89AE77CD08AF09A9729 -:10C4300065C68B6645F8CEF70DC1173D571088834A -:10C44000AF80902BC42857FCE41C3BD7BCEDC81D23 -:10C45000E81F5FC83E793023D48FF2339E9D122FA0 -:10C460001FEF2497C723CDC73B6B637EC574D27F74 -:10C47000E35E69289D9C39BC49CED2D193A0D3E715 -:10C48000787EBEF44B9EEF5BEAA2FA2FAA2F191D0D -:10C4900094F1D274A42F1D1D5C75C01191619D256E -:10C4A000FCFBE9480F93A3FA326271FA947CC4BB97 -:10C4B000DA29CB43EDE48C341FC5FF144B80E27FB7 -:10C4C0002A51D3B9DDA9E4C2FACBED3DED561FC523 -:10C4D000FFF7D1BFA9203E8AFF0A93DEA972D65981 -:10C4E000914EAAEC663C0728FEABDD43DE5BBE0A3C -:10C4F000FE2F43FC0BBD3202FB14F0EFCB1D669FF9 -:10C50000311EFEC7E73A795CE3E2F06FC6BB9003E9 -:10C51000FB1CEE2A27C6831B593EF294D7C6B46390 -:10C520003963BD9F9E93D997AAFE8AD6B7B0FAD237 -:10C53000DE808CF732166C847A28EFF307ABB0BC40 -:10C54000619344E5E8D43743ED581EB399D5976C11 -:10C5500069F915DE6FB64163DF3F77722BBDA72205 -:10C56000BC957F5FD15585E50D9DECFB3FB8EC1A7E -:10C57000FAE565C7C2EDF87EFC0E360F61F7CDE631 -:10C58000F4B64F7AFA57F4BB2EF6DD4D47EC89CC62 -:10C590005F6276DC2CBECED98FB1757A7E77758DD1 -:10C5A0000FE0BE7640B351B961692AA372348E9F01 -:10C5B000562175E5E1731EC80942F10E749ACFF257 -:10C5C00055BB6188B5B9CC0E11799E986F5EABC32F -:10C5D000D7DA5CA66F45BB8C34C2F2921F65F7CDEB -:10C5E0008A3CD4C8C344C2F801AE91EADF3879A9C5 -:10C5F000F30A5AA83E9D7799C847EDB7AE86714BAE -:10C60000CEFFDFB9B1FCF2263EEE099E3F2FDE37AA -:10C6100086FD16F44FF621F1D0FB7F7EFE1ADA2D4F -:10C62000FB701F5977FFC83E3F2BFFEFDC67EFE938 -:10C630000427F7264B8B554325305AA2F7A97CA334 -:10C640009744529287CE7F9E954458DE049BFF8D7F -:10C65000ED4AF7769D1DBF44888F9963A95EA9E3D3 -:10C660007812726309C717F0793BF2C7527B0BB59A -:10C670001B9713A6D76F26611ADFB8D9C4E7EB9CC6 -:10C680007F7ADF82F6F31E233FAF87E9B07DF58125 -:10C69000C7DF05F8373EE272A3FE5FDF636CD7F8B1 -:10C6A000C86BC798FD65E4F746C1EF6123BF8341BE -:10C6B000C1F8FDE10974DF469C0B74D807DED7484A -:10C6C00074BD837ADFC47F0E3C2758887E8D85E554 -:10C6D00027F2B218F7B32EA69735D0CBDC0FA222E3 -:10C6E000F7B3BE05340FBE44E8512E67043F977080 -:10C6F0003D3F448FD798FD9D07299F4CE125B3FE10 -:10C70000167A5B9C3F847EA9FE067DFD5A00E6DB1F -:10C710006B718611DE51BD1DA67C34D90EF2DA4252 -:10C72000F1F73CCAE9A91C6FED5CAFC7F50F9C1B84 -:10C7300063FA07E06FD07D84A17E41C460EF9BF176 -:10C7400016CFFE1FC49B03ECA924F4F709E3E31CF6 -:10C7500032A2FC1090DBEFE40EA3B79543ECFDC0D2 -:10C760004E078D2F8838BBE0BFDFE4B1F8C277B346 -:10C7700003EF613F7D7CBC3EDE7FDFADF3E8BEF7BB -:10C780009F4880EE7B631E536E8CBC0BDCF7EED0B3 -:10C79000C54BFB5263C7C13FE17260621E5BDF198C -:10C7A0006FE034F2D50985C5D94F24F26732DBA793 -:10C7B000F82297C57B27E6B1A72B8FCB119EDF7D93 -:10C7C00022CD189F17ED52F8F3E3567BB043170FB5 -:10C7D000F73D9CD0827ACC5BC0F3E137323A3EFB26 -:10C7E0006CEA4EFDFD7039791513F3304FA420A08B -:10C7F00064637CE659A62F9AADFD0ADEEB93E20D49 -:10C80000D9F2302EE32381A7B11F5FBFB218E07DBC -:10C8100096EFF79FE5F7009D75B0A798574E5EED30 -:10C8200044FCEEECADFD546E0C966BFBA95CC8C9E4 -:10C830000BD271CF2E11F5BC7C0F2B13EE57567017 -:10C840003EA171E31871E2A17161E33D371B94D8F9 -:10C85000FBD424CF6588F7AE38C8E2902BED646B2B -:10C860002ED45F7F3093FA1B8DC9DA38A487AF1BB3 -:10C87000C73D3BAA97AE6B7BC5C0E8474BE9BE30CE -:10C880008D17AD3FF812957FEB05DFEC37F2CDB495 -:10C89000BC91EDA798E3EC23E0A78ABC61ECA0670C -:10C8A000507FD9A278B88DE75155CB4D551857FA1E -:10C8B0006C0DA1E76B6F7B45A67475DB5312BD6FE2 -:10C8C00042D871EB399CE3AD0BCF27F8747205CFDA -:10C8D00027F8747E1D9E4FD097F17C82BE3D9E4FFF -:10C8E000D0D7E3F9047D3D9E4FD0974BC80DED188E -:10C8F000A7DBD049DC611F3BAFA0FF1ECF2BE8CBED -:10C90000785E41FF3D9E57D0973F230C6E9F3D269A -:10C91000D3F83F9E5BD07F7FD32B3F298BE0B21DA6 -:10C920002C3FADDD01F0473AD402BD45009F351CD8 -:10C930003E78AE41DFEF27C9735F46FCACE9BD71BD -:10C94000213EAF38708BA15FD2C5E4710BFC433838 -:10C95000DE488229E8CF4D26034730DED11C9654AD -:10C960001CF7A6478C727BF01E93B0F1FD3AA28BA8 -:10C97000FFFA87C6FD3BF25C9EE32CB739471FEFF9 -:10C9800089D283538D201CDE94D558F450422E4F0B -:10C99000A1719E97658C61903F909687664ABAFD1B -:10C9A00001133C12B28C74E1F019E922A9D04817A6 -:10C9B0002ED5481729E546BA480D4C1816BEE9355C -:10C9C000463A59273751BE17702E877F08E7C97836 -:10C9D0003325C217D689F162337C1B0FDEB715ED04 -:10C9E000FE8B856F4F1EDF57E1F0FD9CCCAC72FAD9 -:10C9F00068759DBD2C6AC794BEDC423781CDF1536A -:10CA000001476147883828E87F6A4F47FD7AE6EF9B -:10CA1000817DF04B94C3C715E6E72125A1DC5C4B73 -:10CA200042543EAD35D90737391F54D03E18B25E57 -:10CA3000B0CCF0DE42F37AD1DE22BAB894D93E907F -:10CA40000E4A11D7245CEE4121A743E7A931149087 -:10CA50004622377EE40ABC85720B1D457B99216E08 -:10CA60001CD3EE13F3107011E3279016390BE9B9BC -:10CA7000D06C9F19FD6BE18F8B78BB886B0B7F5A55 -:10CA8000F8316638CB97F9DB91FEA7B8851FDDFB3F -:10CA90004D7C2FFC67B3DF3A781E00218BE76D7861 -:10CAA0009CFE6EEF6A3BBB8F8FF19D78BFD5B3289C -:10CAB00065B83CCCBB5A8DE75F60198161CF13210B -:10CAC000C83270DF89605085ECB8E6483FDEB1B30C -:10CAD000E31BBF1E78119EDB8B9FECDF8275E7CED8 -:10CAE000CB08D7C1783E61E78315FE9D92B7F55616 -:10CAF000D4A389AA957CA4A30B3B68AA8F0AF9B892 -:10CB0000A827B206EB7FA3DFD7FF473DBF0BF0F9A5 -:10CB100068EC30F58ADA1833AFD6042F710D86A38E -:10CB200068EE49B44F1C44B76EAA0F7565390A2FD9 -:10CB3000AA5A657A5E4AD407F0DE92AFBB2EC4FBD8 -:10CB400047367D3972F4639B7EFE619657600D1205 -:10CB5000CCBB553C50AFD72F8374080C55A65BDF78 -:10CB600008D6854C83EE27B34B18BEFF56EBEA3050 -:10CB7000E10BFB0D665CD2F3D32EF1F9452E71FC6F -:10CB800092DA4B1B7E81DA4B1B7EDA253EBFC8252D -:10CB90008E5FB2E8D29E5F60D1A58D5FED129F5F80 -:10CBA000E412C72F597C69C32FB0F8D2869F7689CB -:10CBB000CF2F7269E357A376A0B33C42F05E095FC2 -:10CBC0000751FD3E3059E135FAF3052AA1791A845F -:10CBD000FB25F9DC2FB96F474B3DBA50BB34C54735 -:10CBE000E341E0DF6741FD78C2EA77752EA271D696 -:10CBF000B651E372F09E2A67E7DC93786E6FBCC68D -:10CC0000FC71F3DF0BAB0D18FFEEDAB5E5E986F248 -:10CC1000D45EE3BD15DF6C2C30D42F0F4D34FDDD19 -:10CC2000BC29C6BF47169C61BA7FE156A23F0F9947 -:10CC30004F222AC657F2EFB154E2BE99157DE62B7A -:10CC4000E1FF6E857E17807F7AFF251F3CA1C1FE24 -:10CC5000FD0837C5D0BFD3547FB1E74F9F19CDE34F -:10CC600031A6F3A7042F978C71DEDC9C8749AC3783 -:10CC7000D3F89CC0D7DDDB2CD4E5FD7C07A1F73BC6 -:10CC800056857D167AFF39C7DB444E7A62DDE15660 -:10CC9000E339F47C8D54223E0B3A8805E36BFEDDCC -:10CCA000440D101A17A274B24B8B4D27BB88BB12D0 -:10CCB000EFE3DA1526F4EF6309BAB8DBE6CBC17D02 -:10CCC000B5899D8C1E049DF8904E92312FC87CDF53 -:10CCD00080195F647204E6BA6B477E9A3E1F95EC3A -:10CCE0006570B7C3BFE1F055B8DB882F1FD195BF82 -:10CCF00002BE4E7F4D7C299E6024C583F14CE2C369 -:10CD00003CA9C3A3C659101EFE4E95FAFF35D00CA0 -:10CD1000E1ECEF64F7A8093C89FE76B492C81C9D4B -:10CD2000FFE75723018473B55C5489F9E73B4B69EE -:10CD3000C878087E76127722C6BD77765A12E9DD6A -:10CD4000D407002FC584FCD7B6A5298550DFED2771 -:10CD50008978BF56779B85DE57D6FDAC546FBC4FA4 -:10CD6000399260C9A2EB48B094D3A7953D03FC4922 -:10CD7000ACAC3E226379F4E621F77DC8589F5A6334 -:10CD8000FA7B812420617BEB652C8F332560BCC747 -:10CD9000C6566E940700C6DEAC328CB7707AE7F7E1 -:10CDA000A386AB4918FFCED7655CEE98E928F5AEAF -:10CDB000459498DA467D8BCAB3EE3685C2DFC6E568 -:10CDC00015D9CCE842837F484FA9263A72A9463A42 -:10CDD000B2C979340F57F095988F18BF6D5446A299 -:10CDE00095CECB4AEFC1B699E584697E4E0C06021A -:10CDF000EE9C1E120E43BD4D63FC41E43EFADE364E -:10CE00008D9074FF5798E7D7944F575F16FB7CFCC3 -:10CE1000C5CA2717EFF3EEA96C9D9FABEC3EEBAABA -:10CE20000E46EFAE1D8CDEF12437CBD70A2CCCD6C4 -:10CE3000EDABEEE772CA0C37576FA00AE979AEFC8A -:10CE40006A00F323EE7993D17FDBA8B75FC6F28E39 -:10CE50007B18FCFD2AC333D08B1A81A9DF7397930B -:10CE6000E6054F29057C21FE5F35CA93A9BD4638EA -:10CE70001698E4863F0E5CCDFC1A0FAE7708B89684 -:10CE8000015C0B2E1EAE8AC6E473EA4C76BFE2E16B -:10CE9000510AFBBBBC1A83636A40A5F277AE7C2EB5 -:10CEA0009202EDEE0B80BC8179D60418BCDD33858F -:10CEB0001C37C253C81701FF7C0E7FB7EA7E05FFFF -:10CEC000BE8B53B3129F84F0FDAF00DA115D538522 -:10CED000BC192088B79400A35B01E7AEAB189CF3A4 -:10CEE000031CCE9D1C6E129110CE667A35CBE79452 -:10CEF000AF09E76E01E70C52F655E07C5F12BB3FCD -:10CF0000D93686C1D5E61C88A09CEDF45BE9BA5EF3 -:10CF1000F02BB4BEB398D53F9CB4320BF56DA77718 -:10CF20006B16D2659BFFC62C94EF8E2C2E6748C0E3 -:10CF3000995D163D77502DEFA0F78F6EF529143FC0 -:10CF40002E5F6CF995323364A7E31459894CE1F0F4 -:10CF5000981A0B0EF652C5202F731B8DF04D32C15F -:10CF6000D7F135E5C37F7E4DF9803947D8EEEEB174 -:10CF7000E27E862E3BD54FE5B7D0B879011F6BDB3B -:10CF80008EFBD97BAED774EF6BF2519E38AD2AC2BF -:10CF900033DEBC859DF338BF0FE67E7E9F4B17BF07 -:10CFA000CFE55E7E9FCB0E7E9FCB76BCCF059E9D50 -:10CFB000789FCBE5684F07E853BE278DDE3BF839F5 -:10CFC00026B0FBF1DE9C3324D6FD247ECDA8FF2EB7 -:10CFD000DB64BC9F2CBDC6A8E75203463D87FB5EC1 -:10CFE000FA7A976ABCAF2DA9D0785F9BC367BCAFB4 -:10CFF0006DCF6521D907F0FD7FB1B1C61E0080005D -:10D00000000000001F8B080000000000000BDD7D09 -:10D0100009785445B670DDBEB73B9DA4BBD3095912 -:10D0200081849B950E84D040C0A0416F16302A8326 -:10D030009D088A8A1A013140481075CC3C9D97861C -:10D0400004081830A0A8332E34EBE0B845272A2A6C -:10D05000321D04069FBEA1595474D4BF757C0AC802 -:10D06000480417FC9ECBAB73AA6EF7BD371D088A28 -:10D07000FFE77BF1934ADDDACF56E79C3A55313B27 -:10D08000CB88DF4AF0E747F8C7DB4D3C76CC9A48BF -:10D090003221D9BC6CBCF8B0355840C8B2B6EA38B9 -:10D0A0005200F594402A2D8F85429990A566777F8E -:10D0B0000FFD1EDB366B227110B2B88910FF604283 -:10D0C0005A9BAC982E4CB7B8FD89846C7853744742 -:10D0D000D12616C5A33869FDAEF42584D0EFCB9CCC -:10D0E00084A464D2EFCEF984641122D101049A970A -:10D0F000DA261C2185B4C1D4B9848C09CF67599B29 -:10D10000C9ED2F22242ADEE686F14981F45190965A -:10D1100039E97F3FD2F63FC2CF45E1348AB0725C35 -:10D12000278C236BF204C6D39737BE273CBD5353DD -:10D130003E58B6277E028B3D8F9CF7A34853715A09 -:10D140005C8D8DA6AD09848CED39DE374DE4E99D0B -:10D15000B90850429220AD25004F89F7B934BEDAA4 -:10D160004A6C6138ABDF173B197CA30412B1DF16A0 -:10D17000806B54382F11A274003E061645ACAFA642 -:10D180001403848C26A4ADC9BFEF6373F8BBAD84D0 -:10D19000B6B7F5AC5F298B38EF29B28CED6C929F56 -:10D1A00038693DBB9BB6D7C0C5A69CDDF8F4A7285F -:10D1B00091AED7C1E9863C214880572BCFC70A35AD -:10D1C00053E424C09787229BD62B56484D011B4F12 -:10D1D00051DB09904AE42357185FF0E3A4E50CA45F -:10D1E00090D272ABBE5C4E467861BF52B8BDF2A31E -:10D1F000D0FBBC7FA914F0F851EE69CA2DEE5AE0BD -:10D2000027E3F77F974D2A1CBB1329DC44BEDE08B9 -:10D2100070FC772D1C451B83638B90B93548F9CD85 -:10D22000AC38DC1423A43451EE00BE6C516CC897AA -:10D230002D891D81329A3F5964724357F6DC32E4DE -:10D24000C796FEBB0FCD04B84EDA737823424D0962 -:10D2500054A8F0A5E5765765A042C50709E32B86DB -:10D26000FFBE7CD8E6E0229AF6BB7C1A715252B11E -:10D27000A5588848F1129D5B61ADB185F163815F6E -:10D28000E8F798C4094744CAF7316E0D1EE1FF1F45 -:10D29000591EE141176F19B8E41601882235546F01 -:10D2A0002FCC47923DE1F991738F2F329002298D57 -:10D2B000A6923B15E4654F7AF732BEE7F57AE70BA5 -:10D2C000566FBC3831F5460A97D637A87C04BE7035 -:10D2D00031B960B6327CB61225F546DA55EB40C955 -:10D2E000ED857CE274941F4B52AB5B417E7E95686A -:10D2F00022A200DF1759417EC0EFDA71933C26E28B -:10D30000D7E027656A8C4EEEB7CAD528CF7A9B67DF -:10D310005A8DBEFD805A7DFBF4F909BABCDA2E3A6B -:10D32000F5B20315FDC2F96592C70A726471E26A2B -:10D33000A14643DFF1F93507E5D1E1BC397512B6F5 -:10D340008B4A2F8A382FBF4B3904F5E9FA991CB65E -:10D350002546943FF7F17DE87EBE0F9D699D0FF253 -:10D36000FA7FE4F51F6E72621AC267CE6C1D5E967C -:10D370002651794DFBDB0C5534E33F23D71C07FEC8 -:10D380000BE3D914860F306DC11C13F0ABDA4F4B91 -:10D39000D274C49BBA9EDEE6D7CAE5BF5ACF2A79BB -:10D3A00089BB00F91EE57008EEB21E5F05995C6E40 -:10D3B0006C9CAD1B7767FC84A99994EE961C14496C -:10D3C00014CA11FDFA7AD2AB7E1D4B12D9FA7BA793 -:10D3D0006FC3BAA94408CD0BF309867C7F43FD2CAB -:10D3E00043F91043F94843FE7C43FD3243FE524368 -:10D3F000FD6A43FE1A43FDE986F23986F20586FC92 -:10D40000BFE9EB17313CDFAE7E3B8D7C01BC1AEBF4 -:10D410004B9282F8950CF8353BF5F82D4D2F3D3F9A -:10D4200013F7855A1D7E55FAEC2B7E96521917007C -:10D430007E926A987E523C8768E961496216EE1FC7 -:10D44000622971B3564C4E5978B998C6C6A3FA9A58 -:10D450008E8EBAD267A1FE481E4C6072F30C742106 -:10D4600090047DB9D23F5C9E05FF9E5BBA38331DA8 -:10D47000FBF8BE7BFA79AB7277CB20CFBC4C901710 -:10D480003EAA4F0F0BC3490EE9D37430CA77EB1392 -:10D49000892F8AEE77EBBD26CC7F954A07027DA5C2 -:10D4A00062B64EFF262428403F4639B00AE4144DA8 -:10D4B000EF013945D3BB9B52315DBAC2943613FAA2 -:10D4C0009B6841FDB8DFF0255E09D2B2E27CD8BF8F -:10D4D000EF1EB64531D1BCFD9448FCA3A8BE5078E0 -:10D4E0004D312C2776FCF4D49D30DC77749C31C010 -:10D4F0009D04958C7515C4671E4EC88A1D6997BA20 -:10D5000068BF728EE48E86B202F7422911EB79C1B0 -:10D510006C90A5EE3DD9343F28C784FA85B9B8BBD5 -:10D5200009F47775DE2B2EA5844B2B6656BA4D5E1B -:10D530000A823B07D5DC0B701AD4464C0ACDCB5E71 -:10D540005900B9F666A68CF0DEF02265C86C18A802 -:10D550003B0DF6D9AF575816C13C7BC713114DC5CB -:10D560003F3D55FB413DB33F7E57402ECB129210BD -:10D570005DE57FB52B346F1359FE95CC239E459AFC -:10D58000FCE399479C906F1B9561827564263A1461 -:10D590005F04BADA0FF298AE7BC38A5983B4FBA05A -:10D5A000319527D27E53685AC053A0B5F300FE3C94 -:10D5B00095F9F754967F0DE046FB951B7979224B40 -:10D5C000CFF538C6FE0F643A55BDB43FB71F0B6C9C -:10D5D000C9A7D54FF783BC32EAA754D0F5073A5F05 -:10D5E0004BED4913ED7BED0A0BF1529E5A9B4ED049 -:10D5F0004EF42EB3F836017F4872FF2B357A976FC1 -:10D6000059F23580179F40A66AE5E4FD1CCE2BB386 -:10D6100004AE671DF38A947ED7D26D13C4ED5AE22F -:10D620008C067D24846FEF098FA2C1F78559A5ABC5 -:10D63000BC30AF996CDFCC0AC9B3BC8512ED671D55 -:10D64000F443F3EB5A4D38BFB5DB28FFD2A1BEBA85 -:10D65000EB2313E8CDC388DF04EB1B4A7C98BAC8E0 -:10D660007C1300A583EB191B39FFE651FE467B07AF -:10D67000441F2DF70CAAF91AF8228EC89897BD4EB0 -:10D68000A4A7FA6DF16591F4039265E27626A99557 -:10D69000C6703B87C199648DEE097F33998F70BF47 -:10D6A000DDE53141B96DEB3EFF005AF4DCDB7ABABF -:10D6B00005A8546BE44E0A1F27CEED5144DACFB6CD -:10D6C0008C9A58685F5FFBC5EE64E8DAEBC5F6A399 -:10D6D000B29C58EF1A7FC778E866B83B5806B4305A -:10D6E000ACB26B0790CC50651D9819C4557CCB8E9D -:10D6F0007E32CCA326318BD6CF0B044B817C6CB50C -:10D70000FBFCC9389F0B4D4017D9301F4E1F5548A1 -:10D710005F32D2898A6FA0872A9ABFA68EC1875AA4 -:10D7200083584E24A76EFEEB17533AB1F5A4137B32 -:10D7300016D38F866485EC2B623EBD7D35242B820B -:10D740007DA5C2A5BAD36D067781E709E762B081EE -:10D7500026F9BA7746D3EF8B326A4640BBA2073D23 -:10D76000CD407FB66D012FD453E1642B092802D63A -:10D77000538A00AE6BEF2A2BC37DA19DA0BDD49B25 -:10D780009E6B2E31E9FD38A41DD791DBAED7D3298E -:10D790001DE37EDE838EEF0AD1718CD62FA1EE3F82 -:10D7A000BE36538C0BEC0C6A7F605FBDC891CD7C9C -:10D7B0005F52E95AFD9E4322FB19A686E19D2A9EEF -:10D7C0001EDE5323C1DB01FC918DFC320DCA9DA4EA -:10D7D0001BCB07DDA5E797FAAD5FEC1E40E76F2B8B -:10D7E0009247027ED4F167717AA6743C13E9F8C1BE -:10D7F000EEDDB0AF0DBA8BD1F13CD03592C2F478EA -:10D80000BB4BB919C651E9CCB89E9B787F8B323C93 -:10D81000F3B0DE831DBBA2B19DA701F2B60703FEE4 -:10D82000681286EF200EDFA8DF87F0EC04F9513D87 -:10D83000D1BD0BF6678FCB391ED24972770BA81674 -:10D84000D7D68A3ABDCF885F4A5FBF877514114F1C -:10D85000B9208036DB61C6FDB317BA09EF9B5E5570 -:10D860007EDC7506B9BD2C121EFADAFF890C4F3B1F -:10D87000B44FA8F490D3D96D3DE6D5C77AAADF2C72 -:10D88000ACC7FA747AAC4AF7CB5BABD1DE52F1A0ED -:10D890007E5FDC5A5D9909746E93DC91EC9FD07EBB -:10D8A000C3E9FC514EE7ABB9FED5CEF5AF954D328D -:10D8B000CAF7B62617A6CB9BDCDC1F5A8CE9E226FA -:10D8C00005EB89CB4E94A2FD7E1741BFD6A2D8426C -:10D8D00021125D657AF5FAFEA0463DDEFB55EAEDC4 -:10D8E000EF78ADBE4CFF8F2BCED295DBDD4374E5D8 -:10D8F000B1AE91BA7CB47CBEAEFE964135AF015D4F -:10D900005912CB74F548F00B9D7EABC271BC380D3B -:10D91000F57D0A4F660F707D562D27A48668ED149D -:10D92000759D6D063D7639C011E1CBE0D80E70448F -:10D93000F81673785632BB89DB3D31AADD93BF7A86 -:10D94000EAF444D4A7515E2D4CB7E0FEBC3C93E909 -:10D95000DB3DE82755233F29CF2F5DC6F673551FC2 -:10D96000DF95FE5625E8B5EB534D2827D727EE70F7 -:10D970006DC07C8C9BEDA7DE7617C59FD9C5FDD504 -:10D980009462D3E87AED9C6F969A09FABF9727D9EB -:10D99000DCE007B3BB664DC47A867109B98568EDD2 -:10D9A0003FF271AD4EEF20D26CDD3A43F32FB2B0AF -:10D9B0007E0422403F0905161DFEAC4493CF84F936 -:10D9C0005AC278CC84F5723C19F41CA39F421DCF37 -:10D9D0003951BFDF2CCD67EDBBD23723DE8DF0751B -:10D9E00054E8E97739A78B96A4F5C887C6FAC6FE2E -:10D9F00049498CCEFE5BEE3ABD9F44B5A7D57A600F -:10DA0000473B23D437DAD1E7C25E77E278FAFD2EBE -:10DA100082BDEECED6F893547887F0A0FA17B91DE0 -:10DA2000A6FAADD5FE24C2FAC33CFAB7BD28FF1E44 -:10DA30008875A01D9963B3F84016E6D079001DB72C -:10DA4000FC21D6B788E657C54EEA8EA3F99C8DA275 -:10DA50008CE5360F9EDB74AD99D03F48C77D48A852 -:10DA6000199FADF1C36D8CFF6D2AD307A48F822E51 -:10DA7000607201ED5CEFAA510105F4F17CE2DE4435 -:10DA8000C00A66E52A3D116D5EEC99FF3C9BEDFBFB -:10DA9000A9D792F91D11F0DF9CCDF6D1B01CF7C4C7 -:10DAA000A0BCE6723C87C36B537B758C568E6BBEF5 -:10DAB000C745A2AB7325BF5B407E0F8671F62BB8BE -:10DAC0006F17112EBF9F22BF46F93D27B36621D0A5 -:10DAD0009BD978DE2705517E0F939545501E07F69A -:10DAE0001EE0E5068A9708EB7881E3EDD78A177583 -:10DAF0005FDDD4FE2CC34B818A97952492FDFB2BCE -:10DB0000C04B27C0BDC7BE4A82780EDB3D50790EA0 -:10DB1000F8F11959791ED2107EAE8ACC379FFEC219 -:10DB2000F87994DBADAB397EDAB97F7C25C74F1B22 -:10DB3000DFAF9773FCB4F2FD7A09E027EAECF966EF -:10DB400050A31E3FFD2A630CF8D0E327AE588F1F69 -:10DB5000BB5B8F9F58D710033EF4F889CB91991E79 -:10DB600099AAC7530FBE3983BDE2807E22F83706DB -:10DB7000D6044AE18CABFFD48E2E3374E2692F8534 -:10DB8000545DEFC306BB544DE372983C4C2D8F8C13 -:10DB9000F7EF38DEFF98A5FCB78E8F2F8ECCC7A687 -:10DBA0001C56FF13591172B4747559E4FA565EFF8E -:10DBB000E020252A47D33FFDB94F3C8DBD605C7FF7 -:10DBC000ACA0C4E5E03AE4AD418AFB8D0BD939E461 -:10DBD000C668B903CEF3BD0B6DEE4D32F6E4B182EB -:10DBE0007DC4FB21DE38EC37830F33C8B6E75B38E2 -:10DBF000F7CB9C31B0FFCDB43C7341EAD11A9AE621 -:10DC0000E464239CB26ADD3B00CEA2636A7F767E29 -:10DC10003CCDF9C9504A6AFE7EC28F60703B13FA50 -:10DC2000742E47E520EA817422BE4D944EA324222F -:10DC3000D91360BD0AAECB0C7AAC08EB6DC77C0C77 -:10DC4000E9C0D44602ECFC9ADBA3A37332115E4E0A -:10DC5000E2447B3581B83155F9D89A48A4A491D8CB -:10DC60007F4BD448821BFE0560AFDA06AE5B0E36F2 -:10DC70008D42A130065905E121DCB71BD74F5C442A -:10DC800066FEB6BB9C189FF01A5DDFD0BEAFAFAF8B -:10DC9000F5BE8976149238421AAD2CBD23C6B11E4A -:10DCA000D26FA2337CE0B43A3FBBE63780576F199E -:10DCB00041FDC3FB41ACAF19273BFF3C661FF4B9E4 -:10DCC0009F2BCF513F379CA37E6A813FCED4CFDDBF -:10DCD000F0EB5838C7F4D4C1B82DF16350EF54536A -:10DCE000235CFD2E653EF42B590F647CDC2FACB712 -:10DCF000D9DE13506F6B11FC04FC94DE0F05D4AF1A -:10DD00004801C3934D26AECCE1E17E6CEEF98398D9 -:10DD1000BF8BF97B16BE7FC760D0BF1F889D148C58 -:10DD2000A3ED37ECA37A1EC4D194BBDFADA5F49468 -:10DD3000D4CFE25E4FE9A71FB793A3568CD95B4BB4 -:10DD40007FFD6C30932F5B9AF6385BA840B24BEEA8 -:10DD50004B46D276367E7E4BC48941D01BED632480 -:10DD600019CE38F2457F25CC97349808F0C5437515 -:10DD7000FAF3DC2579F9D89F9A1FC0CF734991D463 -:10DD80001D8AB3A17AFCEA1C1E57E3200ED00BA516 -:10DD90001F94B848710F6AAACEAF2891EE5B71E06C -:10DDA00017A49C42D3A2363F067F94B9FD56D06398 -:10DDB000D7F888D742E1F4D874CF6CE8AFADD81368 -:10DDC0000B7AF99A83D5970DA3F30E04253780E0DB -:10DDD000A5C10938CF8022AE88A5DFB7BE6772C261 -:10DDE000FA36F0F66D1E01F9FFA169C4E7A5F0D877 -:10DDF00050B7C32A82DE1B30915CD473A9C135862B -:10DE0000BB4E64F0D732BEBF6370127EEC0C2C8820 -:10DE100007B8AC8ABD30A0D0FEAB2A99DF79823832 -:10DE20007017F41B68B3207E9278FC9140AA507F53 -:10DE30004E98A6D197E9FF761E0715B88D60DC5382 -:10DE4000DC681BC6013C1764E7460F5532BFB3833D -:10DE5000F871FC09E2B66813FDDE592939819EE2AA -:10DE60000CFAB90DFAA324D7F920EBCF3182F5676C -:10DE700037C44159D57939E9BC28FE44BB8478764A -:10DE800056EAE3A71C867636C3787B01CF20970637 -:10DE9000923CC0F349CF6F471DC052B71C297EA2E8 -:10DEA000AD89042A34F116B65EFC875FE431BAB559 -:10DEB000A4EDB4C2BC4E7ADE4A0477D71BDFEFFE76 -:10DEC000F81E487FF88FCE06BAAEFFFCF6D0C6A784 -:10DED000018E8D77EF473AE476550A4C81CE67572D -:10DEE0009505E1385A61FE0152D4B5D35C84E578DA -:10DEF000AEB5624734960F2826BE680ACF019292CB -:10DF00007613F06B40742F94A113C5963686B0A398 -:10DF10002A9A5F713D251C2A1F92A629229C1F8CDC -:10DF200017DF20768AEF358A20B3F8376117F05370 -:10DF30007A85807658FA414F34D0C3C9C9268C7F80 -:10DF4000595875E525B9B4FF474A25F43754569416 -:10DF50005E0DE5030E327A71DCC6F047E1E4AFA056 -:10DF6000FC907D90F9138A48D0EDA7E503DCC49CB2 -:10DF700008FBC7340A60985F1BC70FF70F1415051D -:10DF8000BC0054BB5B8F47A7018F46BC5A73391E38 -:10DF9000F3493EB3EB98FE58C5EBACA91885F6EBF8 -:10DFA0004332F19A87F7C4D77EAA3F2A54FF0B5019 -:10DFB000FD11D2BF53FD11D24EAA3F426A574A2FDC -:10DFC0002BA2F30D24D17E81FF268E5E04E7038F02 -:10DFD0008CBBF9CE7FD174343F67A3949F5046E148 -:10DFE0005A0D5CCCF2AB15BA671E281275F915896B -:10DFF000927A8EE7853DD59E66E2E73CE5F7427969 -:10E000005BAAC4CFF5583EBB80E8F29D134DBAFC25 -:10E01000053B34FD0F04FC4461BE20F7B9D55E4DCD -:10E02000F9B23C9AA7E57BB93E5735CFE4591F8139 -:10E030007EE7E432BD4AFA8178058AAF2F7308DAA9 -:10E04000E9A24941F94DF224795384F83442A81CDD -:10E05000D4DAD73954AE6AFC23FBF3B85FDD53CA78 -:10E06000FC6C24FCF3DD181E6745E07B5B00F48844 -:10E07000256F5FEFF693DEE5AE39553AAAA5934BCF -:10E08000543AC825B930FE97A4646F29D059FB28AB -:10E0900009E8A188F301E17A1CAA8A947E5E3871AE -:10E0A000FFEB8A0C765AABB32517E37EAEC8D5F8E2 -:10E0B0001B1627CD1A05FB991AF7434885F313BAA7 -:10E0C0002EC17BA509F4B6DEF514897CA2814757E1 -:10E0D000D58438D8076C5C8E1BEB2F6EDAFA168C61 -:10E0E000BFB4A903535BA207858C55F2A2FFC6EF0C -:10E0F000AAA985795907D2728D1CB624D2763A3BEB -:10E100006020D3BB543C3889491BA7BAA66D644C28 -:10E110001405461BDD2F403EAF095447C3386DEE52 -:10E1200091A7F55F9D894F36541C2089148ECFBF6F -:10E130003DE9F5C934DD07FC46F7C1E738DFA41730 -:10E140003FF3CEAD3A7E399C5066D3F2CBE1D54A4F -:10E150008E965F58BE777E29B917CA3B53255D3E20 -:10E160001DF84593DF10E217960FF30BEDBF84CA3D -:10E1700085372D985F9D7B78B557537E67DE613D6F -:10E18000BF8C173DEB23E801815C26EFCF35BFDC68 -:10E19000C7F7913EF3CB3FCE8E5F9ECEE57ACECFD2 -:10E1A000E7971773937E397EF1F4915F3C3DF9E573 -:10E1B000EF3F855FDA9C7E8C076C9B6CAAF445C0B0 -:10E1C0007703978FAADF7B34F753944F53AE1E0625 -:10E1D000FA2C8F5B53E369DAA6B1FD7B61D504DCD1 -:10E1E0002F37EC63FBA5BA3FF3A35DCA4FCC8F3149 -:10E1F0003AC0F6CDA46201DB4F52049F4C7F6DA361 -:10E200002A413FD8AF4B04D22EC352E757E50A61EB -:10E21000BD898E877AD3236E16374B0E327DC74A5F -:10E22000FF037ABABCD8ACDB57538CFA9721AF9E68 -:10E2300063AAE7978F405C0285C7D72ADD18F65B93 -:10E24000150E6B0E96A11EF2D540CB69CFABDAF856 -:10E250007A43FA5491A734923F6C7A1E8B93B8DDBF -:10E26000A54879A3613FBE11F75D753F37EECB9DA1 -:10E270001507F472C65BD84F2767BC85F7EAE40C34 -:10E28000CFF72A6748119687F6659E0FEDCB3C1FA6 -:10E29000DA97793E2467A0FF92F0BE3C6873E1BD37 -:10E2A0005A393307F27DD897AFCBFB65E4CC5FCE0C -:10E2B00056CE9CE5BE5C9277CEE4CC84BC5F50CE5B -:10E2C00054819C893BB39CA9023953A09333D7E670 -:10E2D000FD043963AFEBF2C2F9FD35BDD0BDC8F521 -:10E2E000A5D939CA0CE89F4CEC5BDCB691AEBAAA52 -:10E2F000362F4E067A71333BAFB7F6F6C6BFBCD5A4 -:10E30000A2898BB64B0176BFA2F179FC7E6DDD3E12 -:10E31000F4979D69BED3F308A6C67DB4AB6AB71562 -:10E32000E9D66DC233F19F3A8FB6C98C2FDFDCF48A -:10E3300002EAB70F80DF2FA9A79EABE2B5AFFA8F35 -:10E3400071DC865C19D7611CFF4C744BE9F421A089 -:10E35000D393036F1B0A769E68BF2F16E0F52BD868 -:10E360000F3B7E0A9D0672193EFBB0EE977EC97583 -:10E37000FF0CFEDC0BF33ADB755F97D7E775BFF355 -:10E380004BAEFB67D80B9FFF9475CFC9256ADC0D98 -:10E39000DE9771C22F944F567F9FF721F82F56FFBB -:10E3A00030E4195867FBB7D675E0BF20DFFD283A87 -:10E3B000B5F7A708BB3763E7EDEC1E761FC659A972 -:10E3C000B91F45C2F7A5703DE8DF0895EF8D745F72 -:10E3D000EE974E411FF9C87C9A720BF3DB19BFBF51 -:10E3E0009323B07B6C425534C4C5774DDE81F10672 -:10E3F0006D9347E2B995514F51DB753629E84F6A65 -:10E400006BF260BAB2A932007E93E70F7C20403CE9 -:10E4100058D1813ADCDF568CB97400C6F18D2B8A55 -:10E4200081FC4A839EE2E07ACA90C16FEBF48A8E47 -:10E430003FD5ADF69684FD50F784F417DA4ED6D862 -:10E4400049340FE410B29320AFB393E6A15FA11358 -:10E45000F4175AFFBCC1F356471A678589D482FE68 -:10E46000B2A2CE5419497F793727B25F81E6F1DC39 -:10E470002DDA6EF52DCA047D86D468FD6A67D25FF9 -:10E48000FE34F82CFD0A6769274D1E7C6EF4971048 -:10E49000DF72BD253E5FB91E5CB2E74A4E0CE8A3B1 -:10E4A0009C18D0534EDC3AF827C8897773587CB54E -:10E4B0004A5F1B6437FA93DB2A09FA1FDB028BFAE7 -:10E4C00015D2FC73752622D0FCED6F32BFF09A6234 -:10E4D000E2837BB46B0612CC07DC8C0E2688B6DF99 -:10E4E000801FBCB382DA4F32F8EDAEA802D8AE8AF4 -:10E4F0009D747734A597AA628980DD34412CC1715F -:10E50000020A8B0FADB291DF44815D354E228BCE76 -:10E51000C26F6D170B04CA91943FE578E0DBDEFC17 -:10E52000D146FF3311DF70E33D27831FFA6CFDCF27 -:10E530006B07FF6CFF33F2DF179BEBAA311EFC0C5D -:10E54000F478DD601933C67DCAC8C72A3DF5467F19 -:10E5500036D0934669F2FC1EEEBBFC7CD9067AD21B -:10E56000A8305D74558D898B147FA5A6B18D2FBE03 -:10E57000A5BD8F172B75607FB18DDBF0FB7D10374C -:10E5800000EB93DC284F1F2BA37238C2FCB637CDAB -:10E590003F08F2735B5323A61749DD6202ADFF52B9 -:10E5A00093F720C06D6B532BA6CF37B5637967D334 -:10E5B0008398DED3E4C37445D3164CEF6EEAC0F4FF -:10E5C000B12C364E89E4C77E2E3A45FBD7D0D1B860 -:10E5D0006E3A8E06DF171CF6EACAC7065B75E5E7DA -:10E5E0001D6AD7E547071ED4D57796F874E5B3734F -:10E5F0006A3E01BE74146DD17DB71574E8DAF5D5A5 -:10E600002E38D7F532AC4FC1313989877B1770FF6F -:10E610000AEE0D513E4E69A4E295E61FB5733F47E1 -:10E62000073B274F25A11FA44BBC7245EB77D95957 -:10E630001C64731A6BDFFC3B967F349D9D1FA97190 -:10E640009AA23544D744480E9FE73F6AE7F7947291 -:10E65000585C6446810F3C12240302D4E03CA48839 -:10E660009D93A9E7DECDDCEFF0A8996C15A83ED903 -:10E670002CB1F9372BC4B790D66B2E60F9872A8856 -:10E68000CF04F357A8144FD69C7337EEFE56280CD0 -:10E690009F9793210A9ED788FC9C3D74EE1DFD4FE9 -:10E6A00082E7FA1C5E8B623FC738DAF8C66E01F863 -:10E6B0002BA5B1BB0BE6F7E8EF2D72247BA8EBF797 -:10E6C0005FA701DFACFDDDD769C0EC6B43F133DD43 -:10E6D000D1DAF8990C0E97B58D5918BFB0B6D6A1FE -:10E6E000BB07A729C77886AF6AF9FB044442BB6819 -:10E6F00080330C579F1A3F2242DC1D5D7F76F8FE67 -:10E70000E9CF8DAF59DBB880C5D70C243CBE66126B -:10E71000DA932A1ED6423ABCE7BDDE5F3ABEE68CEB -:10E7200071358638071DFD42DE6BA46F19F112C5E5 -:10E73000E95BB88BC545A419E8468DBB50E9528DFD -:10E74000CF50E335D4F80D0B8FEBA0C3F2B8E6C879 -:10E75000F465D9415C70EF4D34C5B8D7679E398EEA -:10E7600060812B8B6F0EF387B37E59FCC057839566 -:10E770005B5C49E17E07B8945B5DA3C37935DD003E -:10E78000BF8EA55DB88315A0AFE6172BCD709F2F68 -:10E79000A188E03D9DA26201D3FC832CBFD82562F5 -:10E7A000BB7F77317F939ABF5C515E85F671867629 -:10E7B0009787DA99B1DE932EA6E73DE992D8BC7926 -:10E7C0001CF2244EDF4BC78A2C3EBA426072030E05 -:10E7D00054C7F0FD90C2EF72E29C92A3F1BB5EC100 -:10E7E000B1B5B289C5F7A9F1D07F7F53C478685B12 -:10E7F000B1A71CEE9E8D0E04FC70BE5EB491381362 -:10E8000064985F50017E5C987EFF0E888778EE12D8 -:10E8100076667BF941A62F5C517C33BE37E2F84E19 -:10E82000447FACB3C4EEF6C14013CD6CFF57E3A1F7 -:10E830008BF5FA4295415FB8FC0CEF7F24906E2F68 -:10E84000EC935B5C067F2C7F07A437F91D7E078461 -:10E85000C98722DEA7ADD8190DFEEBFC8326BCEEDE -:10E86000296E5444BC1FDBC6E23C9E0B784E7B1FD6 -:10E87000753F876380CB89BFF338C94E2E27DEE50D -:10E8800072E210C8099ABEC5E3240FF23849E37D4D -:10E8900089B6A6CA035A7DC798DA05BF07E3A04622 -:10E8A0004804EFDFF5F2DE87DD4DFBD1C5312E44A4 -:10E8B000FAD9197F7F29EAA31E13EA95F7952869EB -:10E8C00091ECBBFBA6949D36FE7065D3D4032DA7B7 -:10E8D00099A7C3A2B767D4F45B977A3FAE1DEF5BED -:10E8E000A42826027155695619EFFFADEC52CFF7F7 -:10E8F000ADBE68585F9D8DFC5313A7D23E2DE081BD -:10E90000F2154512DECF51FB8D2BA6F3D1FAF92B70 -:10E910003FC278E995E382A9A0CFDC37F693A9B985 -:10E92000102FB24F2440063DE6ED62FE76755D295C -:10E93000D27C21529C7A6FEBFA90B757E3C58DF0E9 -:10E94000EF55EF808880D3DFB7B2E427F58CDFEB9B -:10E95000C33CD16EFD76CBFCC970BFB7AFEF5FC4CF -:10E96000723A4C9B49A2819FCE448F3673379E1BCF -:10E97000DD3333F2B951763EC3F73D25FBD9FB2297 -:10E980000591E7D1935ED97C5648B47FDA6F7B4915 -:10E99000E4FEAFC81754BA7E07E4557BA509F50A13 -:10E9A0003B159F10176F1F47F520F0E328EC9DA241 -:10E9B0002F4BD8F98C515EF418BF84C257636F1B7C -:10E9C000E55071BE4D671F9F1C3839CE1F89AE7848 -:10E9D000AAC25195433DE148F09CA91DE088708A88 -:10E9E000CCD7617C2D540FD16ACE705F6F5224FA60 -:10E9F000E90D0F467A5831D313E70778BDFA2D9108 -:10EA0000C1B955A2E7C7DEE06784D7F5BF30BC8C3B -:10EA1000E517E773FF481FD7D9E77A542F726AF4D6 -:10EA200062B8142DD1FC389EBFC22B041FA2724BBA -:10EA3000D8F637D47BC6F1F40A48E9FEB84DF0FFAA -:10EA4000F31FB4718920A703D2AA5F1A0C1E32B239 -:10EA50004498AFD37F960BEE432FA35FA8BB1FD480 -:10EA60001B4F6A2486641FAEEB6F42B01936AC2B85 -:10EA700089B218D27AD26E8176F59D7F3B04E3D4B9 -:10EA80007746FB45704E6E351FD3FA8D666BEF8F60 -:10EA900064C22B1A1D964C3A9FB95BF4E7A4752407 -:10EAA00080FDCDEBD07F37DE1F11440A18789C2003 -:10EAB00014FF5A82F1BD249A954B439C5CCE75E7B6 -:10EAC00069DF33ABE5F0AAB5DAFCF0BE10F1E9E797 -:10EAD000297139B48BCA31EB48BC0FF3A77CBAEE6D -:10EAE000234EABD744F5E5E4849A7A80C78D44B6CB -:10EAF000B094E90DEABA8893E173866DB205E03B04 -:10EB0000A3D5B80EC502F3B9A9FDF4EB53F1FEFF8E -:10EB1000F209C2BD355FC6745ECCC43D0A14170548 -:10EB200032B4EF4134C0FE00FC35BF9F8E7FDF5012 -:10EB3000E99128625FD6DF13AE39E82753E1DA3B6B -:10EB40009DEAFD642F44B37953F8ED0539A0C28FD7 -:10EB5000483585D0AFBA9E7F8D0E6CF6C3B9AA9D9D -:10EB6000BD03F54142CD9B00EFF443C14F043A751C -:10EB70006293F3609D9F6F3DF29698155E1F21C1D1 -:10EB8000FB213EBA76ABE85C0EEBD9FAEA21A0F79E -:10EB9000DED6A5C6C7527A40B8D1797D14695E9F8A -:10EBA000FD96DC007AC978B140E747798EEF276B94 -:10EBB0000A3C87617E4507063A60BEE6AC8EDDFD05 -:10EBC000E93CBA6F1730AE36512415003F351EE1CF -:10EBD000844D423B3B31D62B3A68BEFB46E25E0F8A -:10EBE000D370CF7703A988E905EEE5946E926F178D -:10EBF0003D204FDEBF6D46FC0C9A26DB67C667D30F -:10EC0000F4A228E28DA6FD250B264F073AA1A6C740 -:10EC10004FA1F3BC2E8ACE93E6337F1BEBCFA6FC2D -:10EC2000F6570BB102BD26C6D6AC1A0FE3C48B381B -:10EC30009FA3544F94A81C2BBDFACB51563A5EFFAC -:10EC4000EF6C23613E698DE5E49F1494FBF3995FBB -:10EC5000F1B327BF1905F7C0C51F6D6EBC67CEE9BC -:10EC60002F319BC1C388EFAD9CAEDE8B61F64E7D2C -:10EC7000926509F8DB3FE7F60F515C682FDCC6EDC3 -:10EC800085F762981DF45E9EEA5FF22769F5DBFA6C -:10EC90006825EE2A301EA89E04F1CE5F3A95B8781A -:10ECA000A8473CC8B7B771BBF973422A81CE6F5BE6 -:10ECB000569E9240DB2735333818E7377808DB9FBC -:10ECC000EB4E5182D6F8CFEA24BF05F486BA53162C -:10ECD000DDF7F7A91EEDD5DC57BFEEF0C1F130BF6F -:10ECE000EB497031D4BFFEB658E6B8E7FCDAC9E7A5 -:10ECF000D11B5CEAE325225178D40BC473BA7A2F76 -:10ED0000FF204684EFA421AC3CA93CF2FAC60F6177 -:10ED10007A5FF9D2890F009DD507CCA8CBDFF662C8 -:10ED200069CAE9F4E7FA5317109FC6FF572F051178 -:10ED30001EF5A72EC4EFE54B8F5980EEA11F997EDB -:10ED4000BF2D5A49017F6D6F70DECAF5A0FA53F1ED -:10ED5000C4DB4FFB9DF177B8FF442CFF3387DB9F6B -:10ED6000F7982A23C5772DE0EB1E92247940EF1AFD -:10ED7000EA27CABA08E3AAF5921322EBC5EABC3A1D -:10ED8000CB82D7C3BCCFAB204AA4F1667238AAF3BA -:10ED9000ED4C08CEF2207D76E7C13B13A1BCB33B1E -:10EDA00043FB8EC4235C1E745E1ACC80FE3FBF24DE -:10EDB000F2BD1D15CF63B8BEFCB7849A4E901FD329 -:10EDC000AEA2194A1F29D3FC26763F85F15B6FF866 -:10EDD0000EC35924BE51A783B305CBD5FE8EECE7F5 -:10EDE000FC48ED708853BF91CBFF1B37CEC5B827C9 -:10EDF000554E1D795044397504F7169AFA04D45FBC -:10EE0000A7D7509D8ACA95599BCA77C37670632A43 -:10EE1000211726B0EF7741DA62D6F9FBD5F1661CEF -:10EE2000F2A09E35B34DBFCFD592B62F403F38B23A -:10EE30009FC903CADF1690C7B3EED3F753BBF1B235 -:10EE40004F617EB506BB3C99EFCF463DEFA121DC7B -:10EE5000BF3F868C391BBBBC9E92C510DC173C2281 -:10EE6000CC63B4A47F674B4DE30A199D2CD874D2B0 -:10EE7000E2907BEFF728952339B4DF63D41E87F443 -:10EE8000C521CA934368BBE3FB185C5E1B52F30CBD -:10EE90008C777C1F5BFF89BA13B3E09D183295E92C -:10EEA0000D5170F980FE1A75ADD5D74CD7BB948A39 -:10EEB000A968B81714C5F411550F13C55B45072D84 -:10EEC0001FFB5F33E3619D898F5F5C09FD253D1E5C -:10EED000AB00DC96972A2340DE2FAFB2B9E1BECA61 -:10EEE0003A4A86C5B4BD95F603FB89EFCF6377C078 -:10EEF00071644EC7AA3278F7C5B9ADCB3F80AEABCF -:10EF0000D5C4DEC968BD90B89B4978BC866D55CF25 -:10EF1000C0BC3226D3FD41807BF4CA08A7A67FC2BD -:10EF2000F5AB7A8E93E3AF0CBEE702B897B04744D7 -:10EF3000F5F1445D16DAF54308A32735FE1EC60633 -:10EF40003D5285DF31BA5F114D9CDA900EC16FA63C -:10EF5000EB9AD7F90CBEC751B7C89F7C2DECB78F81 -:10EF6000496C1FE5F34BFC6B5A99EC08EFBFD70ACD -:10EF70004ED423553DF96AA2FE14A0BF702AE78340 -:10EF8000ABB97E7C6D2C83F374E2CE8076D7588942 -:10EF9000C34461766D79C7E8F9B0EFCE35C7837E9B -:10EFA000036B8984773535EA412A1FD66FB67BC15A -:10EFB000EFFAB9D09D079D1C35333EEB7E25CAB7CD -:10EFC0003E33427F7CFFAACFE37A5D0E51E0FE40E4 -:10EFD000FDF6C1781F2C2A86E27124CA3F2BE0750A -:10EFE00017ECFF74DDB35F8EF6E3BD30F5BD32275D -:10EFF000F1DAE9380DDB53D6839E9198AD8C5840F9 -:10F00000FBFBDC1CCC407941E59B40F7D6D4A14BFF -:10F01000A64894AFEAFB53BD8BE6C73F7EEF148949 -:10F02000D2637D56709689E6E73DFE04CB0F097EDC -:10F0300002F93B1E7F81D51F199C25D2FCEAC777B8 -:10F04000B17238C3A684B5F6F137A680FD7F349E31 -:10F05000E90FC41DBC1EE8A7FEA5C1A6E59AF5DE12 -:10F060003D94C9D1A3D1ACDED14C724335C0DB1580 -:10F07000CCABD69CCB350C0DF96F589C165FA7DA3C -:10F080008EA446EE7F306F37BB9CD5BB2896B44626 -:10F09000B3FB755ED0C7766E1B8C70B10D4DE0F082 -:10F0A000A2FD1485FB51E1A8F6A78E3B07F67590EB -:10F0B000FB662AF73572A66828C31B1DA705C7295A -:10F0C0005046C03B56F5D5034700DE28BE248E2FA0 -:10F0D000C98A8FABAD63F3A3FDC617E23E330AFCCA -:10F0E000CA3BBFA3F533C3F336D287C2C799DDCC81 -:10F0F000EEF777C767231D5D14CBF4455244E14713 -:10F10000E5D9EAA16CFFB97B683C5B5F080F290277 -:10F11000F6DFCCE13790D53FDBF556FF42EBD5E08B -:10F120004901FFCACEADF98827753D84ACD2F5738D -:10F1300074A1A15D31653C98474236B65B1A4DAC6F -:10F14000F89DAC0FB5CBA4ED2E2AEF1E05FC308F39 -:10F15000EBC3C47B21C635D4716931AF356001BFC3 -:10F16000F4BC0EE6272739747D401FD5138BF8FABF -:10F170009C7C7D4EB63E9F8E3EC9C1EE8CC9F69EEC -:10F18000741B827BA8BF8291BC3F1D3F47EA0FF8EA -:10F19000A2377CB40C65FBD439C3873A4F033C4398 -:10F1A0007036CC4F8527F031B62BD0F3933ACF3B56 -:10F1B0007AE3E7CC9F385E296B37EF77148FA0FF97 -:10F1C000C87A7A9ED799699A5E106ED7DAB1D00361 -:10F1D000723E5690991FBCB3CA0BFB5FC3B652F484 -:10F1E00053CD7BE1C9E7BDB4FD9CA7D73820B8EA71 -:10F1F00088D49E0C7A70DDA6C50E781FEEB0E4753B -:10F2000080FC3CE21323FA07FFC1F1A0EA5DF57C24 -:10F21000BF39FAE7BB27013CBEDE64C67B860D5BC7 -:10F22000A2FC51E837998DFA18CD7FC8F24BBF0088 -:10F230003BB661AB5E7F9AF3A735C9E80F23DE01C9 -:10F24000263C04F30F80C3B0FA8D663C4FA93F28DB -:10F25000BAE930A481742F81F919DBC33C4E51BC4B -:10F2600037748837427C9FB19C4A12D4C71A3AEF50 -:10F27000463DADA1F3924F41AF6830C453D4F6A2DE -:10F2800087BD3194EB61FC9D74153EC49784FA4DA3 -:10F29000F3630F147E48E7756CE3EB0EA140BB6F80 -:10F2A0002E423C9DE898B1F625B9F7FDF573D00FD5 -:10F2B000A2B4ED187EE5AD023B18DAC6D23AB3DF50 -:10F2C00001FE81BA756637DD8149DD931B36FF117A -:10F2D000ECCB77A2DC106A3AF7C95D6F9D4FF373F0 -:10F2E0009F31274E64D3B7C139B78A2788D9003DEB -:10F2F00045C5CB9CBFECB2C8C3D877D07B55FCCCFE -:10F300007DA6CB02F7FC8C702CEFE8B2603CAC1110 -:10F310004F1D1F4E0015A4F9B16F2C40DF47B60BEF -:10F32000F8EEBDB17DEDBA5D0EA0438013D8A12AE1 -:10F33000BE42F8EB8137FFA4978AB01EFA43CE8411 -:10F34000BF270047A391CE9F7A09FC28EF46B90159 -:10F350000EB54FDDEA80F57C2ACD67F4FEC8E26485 -:10F36000782FAFD6EC4D7662CABED73E7A3BD2E15B -:10F37000CDFB6E4F66EF482869EC1D4D6F1AACF35C -:10F38000A687A7E03A67911AA4C3DA47987FE32BD0 -:10F3900089543E13815FA614B07DE4D3F551101C4F -:10F3A000443E8573043837D92FE2BDFB1EEF22910E -:10F3B0000598FF8AFB17F20B42EF1F5A41BF6BE023 -:10F3C000B51A362E0D009E8EA62B29E0B7A570F03B -:10F3D00072B809F0EEBBB86F7C0AC31391E13C042C -:10F3E000DB517DBC1CBE43FD8059892ED4B5E3EFB3 -:10F3F000DBB0F155FF069D770C9CA77F9ACCE2F21B -:10F400008CEB6BE1EBA33F01A2A5B3DEF87FE33207 -:10F41000A4AF2F0F32FEA9F755556279C0EC4F818A -:10F42000725FD76401E54394EEFC3C441F1BCD9C06 -:10F43000BFF5E5749E92A085EF7601DFD354E965B0 -:10F44000D67D51BAF3FA30FDE8DF8B52F955B5B3EA -:10F450006EE6F2C0B86EA37CF01418FE8EC2C349EB -:10F460007DF27FD7997D9BFF08FC4CF9D72B033F9A -:10F470009BD13FF0D913AFBE750DA5FBCF3A543EDB -:10F48000D6CB5B231FD73E3B9A44E2E3CF6C6E1290 -:10F49000918FE9F7887C6C63F7A6FF7FC9DB9B7BC4 -:10F4A00091B7FF56A097B75F9182B80B08EC337302 -:10F4B000F1BD57237C55BBD72847130AE4887294C3 -:10F4C000FE1C241A78AA7054E973CEE3F3709C10E2 -:10F4D0001DAB74AAD271884E8DEBD6C3D3587E2152 -:10F4E000CC5D1307615E44ED18D0735F117DEBE9CD -:10F4F000D48ED3B92CA1F03FFE4426C61B2DE67650 -:10F50000C07167B703E2C71673BBA31BFC9271E11E -:10F51000EFDDD14C5F3AEEE976C46BF4A60FB78904 -:10F520000ED0F3823E5219C99F442536CE23487A25 -:10F530002B67E762C7B93FF438F7778E176D198DDF -:10F54000E0076E677FF764E6C2AB1C702E707C5BD1 -:10F55000F63DC07F37BD26B2773DBD8A04711233B8 -:10F560001808C861E2BDBF84AE73C6B6B918DF60C3 -:10F57000F4A3CCB26DC4F385AFC85D981AFD2773B0 -:10F58000C0CF02F4FEB0E1FBB6CB90BEE618E8AB0C -:10F5900006E82BAD277DED56F9750419A1BD7FB6A0 -:10F5A00080CBBDF162C13DA0CF1CA7763EC61288BC -:10F5B000057B61DFFD0AEC7E600C6F12D2EDDC9AF8 -:10F5C000C316FE8E33D2BB4A87467BDF981E7BEE86 -:10F5D000FD3177D22A75CFFFA3F0219A1E7BFE9DC5 -:10F5E000BC9721FFC2DB19FF203DEB976FFF16EDA3 -:10F5F0009BE3DBA3703EC7B7FF2DE34EC8BF148566 -:10F60000E7AFC71745615C9477BBDD07F7F98EA7B5 -:10F6100033BF5DF32BDF1462FC0569617A48818595 -:10F62000A5DBFEFB03889F3EB12D4A063F45C3F68E -:10F6300058B4DB1B5E8AC6B897E3AF7C3346EB67F2 -:10F64000FAB9EBA9E7E7FCC7ED64EAB340CFF1CC28 -:10F65000BE6B7879EC0688979BD7D96581F381F2E8 -:10F66000BF7E5F0872E9F8B34CFFA0F6FCA3F0D2AE -:10F67000E1F70575F79B29BC3F071D91DAE17F187B -:10F68000F6E4956087F7840B83C3710A07581785E2 -:10F690004B2DC8D3DEE09138ECD70A8F2FD0BEA80F -:10F6A000DB761EF251182E82C2BEDB7D5601D7CF0B -:10F6B000BE6FFFA610F4A9CF3A16A25E70A6758F92 -:10F6C000FA3FB76EC1DF977557C3BA937E8DEB666D -:10F6D000F47F88EF57463EE849E72FFC16F34FD9F1 -:10F6E000DD38DF3EF2FF82FF6B787F56C073F9335F -:10F6F000E17DD5FF5ABCBFC6F16E77427CD9F15788 -:10F70000BECF209AF59F69DD1DFF4BD71DD28F44D8 -:10F710008F159EB86F23FE00DC5F5FDC8B9EF2FED0 -:10F7200030D52FC1EC10357E474C9C837A8698B833 -:10F730001CF586C584BD83EC954DFC3D3616F7DD82 -:10F740003AD0ED43BFA8E4A95D47F3E64175EEE585 -:10F75000D883DE3E13932756829FA579219D17ED0E -:10F76000A739C9E46C96E19976933FAA10D30F218B -:10F770005D9A7CE91E1857B2E9DFABB519EC8D989C -:10F780001C8B3EAE98EC70C27975B45B82B7DCA975 -:10F790002AAB7FDFF6E5612CFE2386F8306EF36C32 -:10F7A000E1642FD4DB6B463819E1A3C2AD079CB8E6 -:10F7B0003DAABEC72F252E0F001F4A84DA936C3D49 -:10F7C0006887C2DF9182F31A73DC2CF772769E226F -:10F7D00087DEF18738086E6F86DE99954D6897AAA7 -:10F7E00070D6F487EB37C2F96CE1ABE2259A54236B -:10F7F0009EA307DADC3E3AFFC53283FB620A7778C4 -:10F800005F5C85AF0A37231E8240A34961F88753A6 -:10F810007DBC8EB78CB8E09C65BC5812F482BE5C8F -:10F820001C8BFAF23181F8056ABF1D2B4D2E03BBEC -:10F83000E258BA4582745C375D9366BE179DB28606 -:10F84000FE861EE44B49BC2E7F2C3D0FDB975BD31D -:10F8500074EDF642DC36B5DB8FA5155BF13CD4992F -:10F86000A96B3729D6B11ECAF7421C378E3F01ED6E -:10F870009B8B53F375FD4CFAE8D8C337D2742BB782 -:10F88000ABBBC799D11F7FECB5696500C74BE411CD -:10F89000BAFAFB883309888AAEAF02D677996BAC87 -:10F8A0006EDCBA0F77E4811FE237EE52DDF7CB8BC7 -:10F8B0002FD1F5E3B106FD40DE554A95EE7B5DE3C1 -:10F8C000D744EA47C8058DDF11691455DFFD1DBA1D -:10F8D0007E46EDD9AAABEF0E38CB41651C79C8FD49 -:10F8E0002AA46A3CBBA59FD56BA2E9B00FCB4438D4 -:10F8F000F71CFD714D33B8A12F38465C4007E791E6 -:10F90000183C0FEC2DEEFD1B93AF06D67987E873FC -:10F91000411A33605621ACEB486A9B08C7D20F09E5 -:10F92000355714523E1BFBA5AF19F2177DD7218224 -:10F930003DD9BC45C4FB75E3C589B1FF09F2B843A5 -:10F94000C018FF3A9B09FDF09F257414DEAAA13B65 -:10F95000356EC7C8C7FD4795DE5448E9AD255569E2 -:10F96000EF02795AF6FEF56284FBAEC4A97F97AE2A -:10F97000FF284F2B9CD3AB714931E5220B6EBFD8CA -:10F980008CFE9225267734170AB8EF3A2798D701CC -:10F99000BF7FCFE546CCEB44067F504CBF1A11EE3B -:10F9A000D9917B048C6B51C79B51CCE2ED9714AA83 -:10F9B000EF9B3893AE1B06EDED2C5E007C69D06E9C -:10F9C000A209F594AE719FA2FD1B73B9291DEEE14A -:10F9D000398A95D773687E4C607F3ADA59A418E368 -:10F9E0006D16F0389994B6CC077640FB3D668C3B9B -:10F9F0009E314D399943F32B27B2FB819DC565B1EB -:10FA0000C334F0739C1288AC892BF8BE50C6793889 -:10FA1000A420DE0F739C92B09C044730FB8F8FE3D1 -:10FA20009826BF7DAB661C22297361DECB87BC277D -:10FA3000831C731C22FCEF8804F1EFE4413C123E6E -:10FA400080260553AF8B70EFEEE896D1F16087F713 -:10FA50002B75E33DC17E4F8AA17BB2201657C23F72 -:10FA6000788FB6FAED0A5ABE0564232BF7134ACFF6 -:10FA7000CB2D6A39152D2EFECE2196575F55017874 -:10FA800014F5F5876785EA2BD6D470FFCF1456BFDF -:10FA9000DD52D013AE5DE3A2707F8EA17400FAE553 -:10FAA00082FC8294D3C5E93B4EC59E01AE0E06D7BB -:10FAB000EFE82E901CF6277E2CC819405FF7C2F5A0 -:10FAC000006A37AF8EAFD90A741C23FA87C1F7E9F1 -:10FAD0000E25651CA5B74E8B92F13BF48B4463BC9D -:10FAE00057D52D9F3D0857C41C938EBAA866433A3C -:10FAF00025257624F8A59C5FA31C50E3DAC270A4E8 -:10FB0000F44BC75C690AE7412E38C27055E06DE0DE -:10FB1000E51A385B69BE8AC3F5E45333AF4238CD8A -:10FB2000B4225DDCCA79A8259EB4435CDD49E7E6D2 -:10FB30002B811E4E6E3163F06A2714C2BEE9B2B249 -:10FB4000BFE393184C85BFDB326C9F09FD79EF5101 -:10FB5000FA50803EFC2310EE6A7F274BDE4E80FB7E -:10FB6000122713A50480CF9CA005E1769D44FCF0EC -:10FB70005E6A67E2CCF2525ADE7948C6F20EDECFF8 -:10FB80009051CAFB85B88FF3FBBECAF922BC8FDA4D -:10FB90001BBE8CE7F7E00F3E3FA1773A6829B5E23C -:10FBA0007B430DC50B0B605F58109F87F1570D15F8 -:10FBB00002EEBB0D8D5F22DCD5FEA553229135717F -:10FBC000524F80F73049F36EFC290B96D7359E448F -:10FBD000F94DA793097C738C9F6FB69BC90D553463 -:10FBE000ADFB41BCA1CA86E794ADB07FD4911D9610 -:10FBF000051AF9473ABE08C9FBE11477F74EDC1F36 -:10FC00000372B54A704E8147062EEDF05F05E7F7A7 -:10FC100055D1CE2970DE9FE4FEF355707E5F95EEE0 -:10FC20009C02E7FBB94FC74EC5F234E71AF84BA068 -:10FC3000D5EE5C96CF74BE09F90B8797B1BC9DD108 -:10FC400041CCD31953BDB87FDB102E275A637DA753 -:10FC50007B77E4E6C6977570E9512E0A180785810F -:10FC60001A947EFEB56C007B073727807159E9C373 -:10FC70000535FE8B142784E37513B38902E7A98940 -:10FC80002F44B3775A3F0E6400FC6E7E21DA0F7E5C -:10FC9000C8798FBC6A81FD67BA28E7015F8D1F5D57 -:10FCA000933D3C09FC2501CCDFDCB81DE775E74836 -:10FCB000FEF7AC9CDD05E0AFAAE571CEB58678DF36 -:10FCC00039B69DE87F9BB351EF679B4B821F009F26 -:10FCD000D63D71FA38DF8F4C6C1E1287C7743170B5 -:10FCE000BD85CD6BCC70389F49E8C23863C91948CF -:10FCF000AE41F8D6B9D03E498DC17B344BFABF5BDB -:10FD000018E97D988E26BADF53967BB6692BA6D26A -:10FD10000882EB4991821637EDA79ECBE531818FA2 -:10FD20002CDA78C12B385CE3B6B2F36E631CEC15A9 -:10FD3000C3ED3CBE9D9D2BCFAB7EA304F0A2E2F3AE -:10FD4000A258D281F1AA09C4CDF1E206BCA8F00FF5 -:10FD50009F2FD3769991E842853F61F175314C5ED2 -:10FD6000743F178DFA9471FE757CBEEA3ABCC39954 -:10FD70007DD3DBFCBD30FFA4733F7FEF7059F7DE0E -:10FD8000ADBA0E958F43F6E0C2C87A8A3AEFB3A7B0 -:10FD9000B380A52F74A6CA997A52E3423F2C972BC1 -:10FDA0002A9CD579AAF0EAEC25BE556A7C51B71E8B -:10FDB00029508697E31F19CEEE374A1D9760889524 -:10FDC000D4B80DEB9DED7A5479DBDBBA54396B5C1A -:10FDD0009F2A6FD575AA72575DEF382A48501EC208 -:10FDE0005B0F02D80B353AFDB7146E2868CF7DAC97 -:10FDF000B7E8F2E39DBFD3D5BF3875A1AEFC127949 -:10FE000099AEFC32D72A5DFE37EE3F18F4F875BA8A -:10FE1000F22AE5315D794930500E7AF6DF9B2A31BE -:10FE20007EFBC2C3DDAF42DEDFE4C4FC8EA6544CD1 -:10FE30007736C9C8DFBB9B5C98EE6972E3F7FF6851 -:10FE40002AC6F48D2605D340930753A35C98F497F4 -:10FE5000AB24D0D38B03EDA8FF678DA83906F270D1 -:10FE6000AFC9D76CA7703AEF3DA68F139F713FFEC5 -:10FE7000E6833B615F77B27B4D2D5D630539823E42 -:10FE8000E7A0FB9DA2A117C7C42081F36407891CCA -:10FE900067F9C570768E8BF1799436A75AD93BB63F -:10FEA00053A70A188F3895B0FB0934F5D7D0F2491B -:10FEB00012F1C2FE5F6593F0FC89F0FBC253D834A7 -:10FEC000E13D756F14ECDF89FDF07ED264F848E700 -:10FED0002B2A22C6B14E297E1DE3FFAEB1B1BF93DE -:10FEE00075F59E45FFBA93969316EF6876FF417DB0 -:10FEF00027E45DD3D9E80D5FC09D02380F12DCEC1A -:10FF0000EFA4C44B6EADFEAFA6BB8633FD7F52336C -:10FF1000BF1FB08FA01EA7F2235D5F2BCC5FE58BC8 -:10FF20002AA7E41FEC80FD7E5539D4AF3B28235C23 -:10FF300054BE50F940B5FF543E182F3ED10CF54F3A -:10FF40001C62EF929D77ACE6F05FE838FF03F207A2 -:10FF5000233E0080000000001F8B0800000000000E -:10FF6000000BB53A09705455B6E7F5EB2DA4937420 -:10FF7000428084CD0E110C64EB74D210B6E1911066 -:10FF8000DC101BD42F20420332614D62C02F8EFE45 -:10FF9000EAC63018F8D69F8C5A7EFDA2D53082CCA6 -:10FFA00068151948303343B0418D30E348545090C0 -:10FFB000882D322CDF848E2C223354F9CF39F73D33 -:10FFC000BA5F2761B1BE49A54EEEF2EE3DFBF61ECB -:10FFD0005CF95182BE002BAD00E00028EEAC2B4D49 -:10FFE000C27F0B82F560A439FCF911FF0AF7358155 -:10FFF000312B321EF343FDBBB46FB7CF0B4613C09A -:020000021000EC -:100000002EDF0C8641DF22300E05D8EBABE2F17B10 -:10001000BE553C6EF1F919EEF3D532FCABAF8ED77D -:100020003FF4BDC4E38F7C0186ADBEAD3CFF96D3EB -:100030000ED007E0426B693F6F0E409A3A06EBC460 -:10004000344F0242A38033082117422B9852531198 -:10005000CE909C35C0F37E486118F4E2FAB2B4BF8A -:1000600080B137A3EFB122BD0F80FA93DADB08230A -:1000700001EE0741FF03C57FBB2C25D2C09B251590 -:1000800001CC4AEB05EB258087C09F3B0FE18CF24A -:100090003AD35889D627D94F223F24FF17861FB35A -:1000A0009127F433A12B4444E1A4C6371960896D2C -:1000B0008D19860020978E8790BF0690E0C70C8030 -:1000C000C5103403ADBF6E3A1E8AE2F352800CC8ED -:1000D00044FCDF32F17E6D1EE8F9A873E552198AFF -:1000E00053886F0EE6D37208F17916F95167958D32 -:1000F000EEAB33D339B1F72EB1BD67C64137F7B692 -:10010000F2F3D7BB57935305C03CDABF264DA9DBAA -:1001100083E72EEFD536473674C30FBBB1F3EA79C8 -:10012000C887DAE1F8BC1BF14F9864F5229E65B2EE -:100130000D0C28C770400E58F09C45197589742E17 -:100140002A6622E0FCE26699E50146C5988E722B8C -:1001500057E5D60EC1CF482EE5E3CAA700CA6FD136 -:10016000063D3D4B6C2798EF176157B7F456C0B367 -:10017000DFC9895DE9AD1877FB293AAF42E51BCFAE -:10018000235EABDAA46DEF45ED5BEA4C483D198F79 -:10019000FF8C8251C417A4C31944FD397750765A95 -:1001A000A067FD38EB03D6F74B3ED8F61EEAFFD921 -:1001B0002B38D11FEDD159F2927FDCCF273763A1C5 -:1001C00067B593EC09F584EC4893E35AD42140BC1D -:1001D000D79658037EE467D86D37D2FD61295093D6 -:1001E0004872B90CCED5C8EF89BB3E384C7632D1B7 -:1001F0006A0B12DF9088F668B94E6817D3E34F0494 -:100200006A1270FFD836BF4C663BFAA0B7C686E3C9 -:10021000511F2A2869F433EF796492FB765F13F358 -:10022000A1DE57CF30623FB7B29D413ACE65DEB80E -:100230009DC1235603F9B5152A4E35C9506740872D -:1002400075DE36594E403ACE07C149F305071D35D4 -:100250008457619B2227225EEE13DE1AC27B2D8A11 -:100260004141C18D6AF7CB49386F3142D0827EC49B -:10027000926600258AAFA32F046AC80F6A7EEDED4F -:1002800038C1C70957EA65F25B76B377EB46E427D6 -:10029000FC39CEB9D9D115EF1D4E03EBFFB114CF08 -:1002A0000E9687CD31CC934BFAD3BEE515D29F86FF -:1002B00078A7059F83183FADF945ED1C8D6F1A1F78 -:1002C0002BEDE751C6A807ABCEB3DF8BBDB7D2008D -:1002D000DE7AE4BBABD451588DE7B4AF86B9D370A6 -:1002E0005C674298D375FFBBAE9216C2AF4C1ED767 -:1002F000AA105E76C335F5BA72D5777C7F8FEBEAAC -:10030000FD95CD6EFB7C5B64DE5820093F0F46FBFC -:10031000496B449E372AF7F19D3374716BC20F5EAF -:100320005DDC9A889E367ABDD4FAA86E5C667F4200 -:10033000B7FFF6B4D5BAF53B1DEB74EB7767FD5606 -:1003400037BEC7F9B26EFFBDC51B75EBD394DFEBAB -:10035000D6A7CAA0486873B952C044763613EA19C2 -:10036000CE86568673A093A1173589E07C70327CC7 -:10037000043C0CE7B8BCFF22B9844D9D7DC9EE3B1F -:1003800076FE2B87F4A2E31763ED198E485CD6E264 -:10039000F4CDC6E35E66945337FA905860603969CD -:1003A000FEBE47F9C4F8FB7001FA13C473BDA17314 -:1003B000CE5F508FFCBB2DF6CD51FE0435D240F1FF -:1003C00058B3DB9EFC4B99115301B4C7AD06E781CE -:1003D0001574CE47BDA13BFBD2E0D41F90D1A88FAE -:1003E00049B343C621A86F1753144701E2EF7F6654 -:1003F0005CF2C96CD5BFDC8272F8DAC0FE0F164B16 -:1004000081A14857538318E72E4C0E489C07045986 -:100410001E0F43C84474CC05607F3B0F1C0C178033 -:10042000C272C193E3F3D0CF2C6C30BAD6235EF9FD -:10043000299D43C8CE72471F4991F0FE3C742FA4FA -:10044000FFF906A8A53C45C3734181F0074F162864 -:1004500045056E7AAE75FDF3787F67A30136E13905 -:10046000A7463FF14B888AAB2FBB4A46D3BE6D12DD -:1004700028141FFDCD96C0E60CBABFB32FF9756DD9 -:10048000DF1C57E904DA37B900F87CA87F0788CF6A -:10049000D3EC82A730A90FF3009F1B4CFEA7AB9DA6 -:1004A000F959DEF9141FFA839828E67B79FC60C1BC -:1004B000E6196B72981E3FE5632FBBBC1EC6DF8C2E -:1004C0002E8DF07FD512D8C47953D56009F12C7FD9 -:1004D000CD62A0387E04FD2CDC0670D46765F8A5DB -:1004E000CFCEF02B5F1AC3AF7D0E86DFF8B2182E89 -:1004F000FC010940391E2E50E692FC7AA2A3677FC8 -:1005000021E8084B30A3DED6757D86AAD7790D2762 -:100510009E8E273D68929D431185DC465438C4FB6E -:10052000ECAE510139239AAFDE6584475ED3A7CF85 -:100530008D2DA2E78C7609F79F6D3ADF97EC301688 -:10054000BFABFC68360B7EA8F86E4B6E5D4FCF6F6D -:100550006B1C4218A23F00A187244FA93B3A56B317 -:100560001CF30B44BCB9D7D25964B745E8034A150C -:10057000305E54ABF1A24CBE9218427CA6D1B9A316 -:1005800049AF6F3D40F7F9F7C93094F513E67AA209 -:10059000ECFC75950F1ACC6D367B0278FEB6E6CF73 -:1005A000A6DF8D7C983AE64EB71C656F2F10136856 -:1005B000DFE8CBFFF37C2AEFB7D355336163991D96 -:1005C000F73D64DDF33EB1E061FBD765C9389E9B22 -:1005D00026B5109CE7C8989CE22074034CCF82ACEF -:1005E000892DA462539CD3CC94174C24A38AF29FE8 -:1005F000A5564CB274FEBAB76E7C7BDA00DDFE3BCA -:100600001D99BAF5BBB3B275EBDABD539C85BA7DC3 -:1006100064AF9437231D2C77D82C07864AA407177C -:10062000BE58CAF4CF2C22FAC3C83F332600A78B8A -:10063000D7BDF83CB98DC6BD89649FB1F9E9B2E672 -:10064000DFB5288E9EF3D30AF02405A59EF3D29E33 -:10065000F2BA1BCD4FD18F3C477E247FE7FDF61ABF -:10066000C463DBE8CBFD1D48DFDE02CC5BC9FFC500 -:10067000E4AD61356F8DD5A3ABFA2A3984FEEC97D2 -:10068000D9EF6AF96BAC1E013C2DFC8D0A6FD6DEEA -:10069000A77E22E2CF3FC8EE7B47EBB70A0305BA3D -:1006A00078916FC67880F2E9FCBB0C9B68E20AE2A5 -:1006B000A1C92133A2FFF0C8C6F7D38B78DE4FF96A -:1006C0006905C5073CFF0AE51F84EFB23DEFA7A708 -:1006D00046D661E5D7BAFDF094D4A21BAFC9D08F3E -:1006E0009F9DD812FD7C4FFEA87CC3A3662FFAE91C -:1006F000F2172425D08D3FD2F029DB1BA790DF34E1 -:10070000EEB2705D54615740B151F68371A49BF80D -:10071000ACF98799325475E7E72C2E91674DD91BB8 -:1007200007F24F38F708EA0AE1E37F5BC49B2349ED -:100730000A78A2EE497109BC3B92EBFEE37BDCD761 -:10074000F1277012EB3B9285DFCD6B38653050FCA2 -:10075000EB25F425CF1E32A4200C2F8AF703DA53A1 -:10076000E5E204BF211FD787747E6645D1F7DF9E7F -:10077000FCB215E5F685C1A08B3F61F27938CE74E5 -:1007800025CF5C83FFDFBD372E68F809F46462CCA7 -:10079000627F5A22EC7E0EE98DB84701743995BF0D -:1007A00006ED5E85FC04D14FE3D9DB538FBC407965 -:1007B000EC7EE10770D9165B973E145597C206612F -:1007C000BF56FCA53CA60202936D54FF07D1FEE183 -:1007D000E7B3FF092E5BC4CE6FEB6AD79ADD571ED5 -:1007E00012767F6ED7C54FC8CF9FC3F8176DF71A23 -:1007F000DF347BAF7C4966BBD4E6CFEE92EF087462 -:10080000C3E7E1AABE81E2647BADB68B7BABC75F79 -:100810009A4E71AEBA19252475BD478395B5323805 -:10082000A2EED9B6DBB228608BD011D6E26BF3C54D -:1008300094893902AEA6F80B75AAFF11790DC65539 -:10084000532AC5D5699273338243CDFD4A887F8789 -:1008500024083A5C7CC4FD56C4EF3E711CCDDB28F5 -:100860003F83B42C23DD335D95EB7D6A9FE881E601 -:10087000078692BFFFAC61FE21059756B83299CE2C -:1008800007C1CFF9E1A164CFA01588E7D41AA1E789 -:1008900087923BDBA9AF74687CBC5423F1F96BA24F -:1008A000F3BF4326CFA02AA64BED2F2923E41FE355 -:1008B0006FA2EE55FD22CAD32F893A8DEDC098FE66 -:1008C0002CF70B1643A045C17B2B9C41CE5397823E -:1008D000A8EF63F3F48A71DF9A293EC4D695139B7F -:1008E000F61C96F2BAE947C4E8EDF5FA0FB1F56CDB -:1008F0004F79FEC514CF8BAEA83E606CBE7E352FFF -:10090000D5F2AACDF1814D88CFBBE3FFFBEC521CA1 -:10091000AFDC1C6FA7FAF9CC6B163FF9E7339B2CC1 -:100920000109D7CFA474B651DD70667BAE134F803A -:100930007283E3CDB728CEFFC1C47A01E014F6710B -:10094000554F1F3F46FEAE7A738204945F7BC5BA53 -:1009500056CBC96F24709EB078477AC02245E20C0E -:10096000D98703538BD3AFC62994F49FD9775F12ED -:10097000F5A1DA0D7F1CCC7D2DF9A9634FE0734BF7 -:10098000B724B8289F801C60B92DDA347C23E5C7D2 -:100990002F9ABC4D447FE91BF7F4CBA0F33FED0346 -:1009A000444F78D78EBE941F45F2F6EEF3BD73BB6D -:1009B00032932027C227AD2F58FBFA6A0FC93D5E3C -:1009C00072F0BC11AA9401A4174DD380CE75C992C0 -:1009D0004276D9B92E9EF3D458BD3BE01275CA3287 -:1009E000AD8FD01BAC69643F5E603E84D7656F5AA3 -:1009F0008F7C3AE54A51E375E7B0E9B9D1FAD956A7 -:100A000041F5DFB90D16EE6FB4C7E9F3060D1E759B -:100A100025F3FE72EB055D3FA162D565FD38071435 -:100A2000F23BAE1A47E1A30857A8FCEF18E139E6FC -:100A3000423C97D4FF76E787CC970DFFFE05DDBBE0 -:100A4000CF26FA2A1F0AFEC5D603E556D1BF00D825 -:100A5000C8F76BF3A75EFD3C8FF4F05463F6309259 -:100A6000E37CB9F5E42B48E7D984D6634F22DCBE9A -:100A7000EF13964B2CBEB17D987649627A97111D83 -:100A8000385FE6F65C2039A320B88E9BBF3E97F90D -:100A90005726E724911CC367BAAF57343CB5F335EA -:100AA000FCB4F3B57D52A190578BDAE7EB30B79EDB -:100AB00025F976ECCC96A8CF77753EA5352F394A27 -:100AC0005F7EAEFEFA2CB5CF71D8B0FA3133EA634F -:100AD0007BFDF3266FB4DFBBC9BEFAD57C5001871E -:100AE000BDAF08251CB79038238EC76B6332061C38 -:100AF0008F53D193081FB4CBF12A8425DE34EE9BAB -:100B0000D37908E320C0E39A894E07C1099287FB95 -:100B1000175ADD3019AA06121D066B88FB7D6BA8DB -:100B2000CF8879CB03C96BEFC9C0FBD6F481B594EC -:100B3000CFAC3109BBF0CF8BE77A4EE3931667C099 -:100B40009EA38B2F6BECE030E239338C506B4A1153 -:100B5000FB6E413E1FDA37FF7DEA9F7E6EACEA43B3 -:100B6000F71EB1BD902B1928CF0B2450CDF8C52707 -:100B70007F70FF1DF71E05653CE515F77F6065BFBB -:100B80001FDB9F58085E1E9743C874019FFB6AF4E1 -:100B90003F37EF85085D5F8DF9BE91EA8487929FAC -:100BA00076D3F3FE12C8A2B874292E318FE85965A6 -:100BB00015F0F15E899B089EB1DBFCD45FBD143754 -:100BC0003840F1F415C97B6F611F7E8EEB58FFB181 -:100BD000F800C5BBC7656F05F79393CD20E1FE70A4 -:100BE0001F952F1DC07C099BD4FDDF39785C54EA2A -:100BF000E27E235C72B05F1E1B13778AB20DA23EA9 -:100C0000FB51EC1FDF69D4C59DA27CB59FF32F0774 -:100C1000E7A9137E305E332E75148A7AB7A8B7A180 -:100C2000AABB7C718DBA5E034159F47944BE30F69B -:100C3000AA7E2932C9B1421D57505C43BD0A275ACA -:100C4000FD32D23B7697D0B3B1C6E01E82E8656133 -:100C500015E5174D18F7343CD0AF405A36EBC318A2 -:100C60004D4FF1ACD9B86FAD54C5758C95F21A845F -:100C7000EBA556C6E317D0C95051E3790938194E90 -:100C8000020F43D4538677401DC3BBA09EE1146876 -:100C900015F17F44B086E31A3C65E7F71877961B99 -:100CA00028EF287AB0FBFA61CB75F9808637F2E637 -:100CB000F93019D0FE32BBE1C7C02CF623B1FC8855 -:100CC000B5D3F11092D94EC9416452FFC0C1F65A52 -:100CD0000A0A8FCB6E900FC521AF91FB37B1FC286C -:100CE000ED5E2FB6A9FC5840BAD62722A713850E71 -:100CF0001E6BF242FB4AA33C34568EDA7C517CC90F -:100D00007907BAE2BF157E39D388F1ABA8B0644544 -:100D1000268EBFDCD121C6634B760CC1F15785E12D -:100D200099C674D2EF92429313AB18A973E6241CB0 -:100D30007BC93EF309A21D923FF38AFA78A59AC7B0 -:100D400078573FE6B4A3BD7807D99C44A71593FD17 -:100D500038E4A39C29DE1F0EBE23B8D784FBBE3225 -:100D6000795BC87E975B83890EE4FFCAD565FDC8B1 -:100D7000753E6316FB2D16D17FD5E8C3797F1C8E97 -:100D8000B76FCF5E210DB93E1E78FE413ADFBB7AC8 -:100D9000A89FECD7DB283985644BFACD401EB6B747 -:100DA0009A80FAA6DA7D4F8DF01EA1FDE070B2FFA9 -:100DB0001EA0E639EDDBB3B3494E270AD5F7C3A928 -:100DC0001985C4C7A3233C27687F3841E8DB098A1B -:100DD000E5EE9EA1AD48395ED8CD7CF81F88003E77 -:100DE0007FB1D07B9AD62BE3AF70DC3F5BF0E9DAC2 -:100DF0005046446F2514DA6CA4BF46818099E3C342 -:100E000038FBD53C95FCDD423C07F951E4F1D69026 -:100E10008B1B35BB7324F9553CF73C9F6B0E0D2E95 -:100E2000C0E75EB8EF9859E8DD40A177AA5F6ADEB7 -:100E3000BDFFC90162E881283BABDC7DF9FBA3C89B -:100E4000BFCA7336276D8FD8D7CB2BB8DE049BCEA5 -:100E50008F687637A6C9C2F9F6D85DC317D2BEF13E -:100E60009FB665125D13DA42FC3E2CDCFCF9008172 -:100E70008756875C927E4A3C3EA5C6895356111719 -:100E8000E8FD2ED77B8DE2FD6EB5DAE7AC6E9602FB -:100E90007EF63FA27E5EA4D2B77C7F630BF54F1631 -:100EA0006D583085F52820EA0A07FE925F5872587F -:100EB000D4CD4BB7EAEB8D4AAA9B693F04CDA40F72 -:100EC000CBEB63D6379472DD5C19EDFFBBA99B8732 -:100ED00015A9FDB1413088E992672779BBF187B147 -:100EE00075710528B9459CF77A64BADF6DECBEFFD1 -:100EF000909427E9FAB5E5EADDC4271BF3C5CCF5E4 -:100F000044F5AB2B9C761AAB76BB1175A798F2ED26 -:100F1000DA03DC5FD69ED3EC7871ADC475076CE85C -:100F2000CD3A98BFC5A210BDF95BFA711D82F512CA -:100F3000E7871BB7586A695CF3EB5E7E399FFAD08E -:100F40009DFDA90F531387F9A6E8E783E4E23E0C61 -:100F5000F745E617A97E5FCD032058A0ABE76BD419 -:100F6000F85F9D30AC1F56CE917DFBD275F5498D53 -:100F70009A6F17119E94376EED2FD6E3041D7B3EBA -:100F8000FEB778CA7B1B8D9E78EA6B9F3B3884EB5B -:100F9000989EF8EEC63004D778DFE8FE7C4AE6B5C6 -:100FA000E456F49251F04BD5DB3FFB14F8C6149194 -:100FB0008B465F99FC56A999FA228F809DFA24D519 -:100FC000FB7F5763A5BA701D7007E21C087D3E7752 -:100FD000DAC0EFCF4742D66FC6E1D87DDAE80CE041 -:100FE000F30DAA5FA4F7C88E283DB3A8FDDF3847EC -:100FF0002F7044D5D1F15929BA7182B3BFEEB9A48B -:10100000E221BA75E4F7263A1FFC4A6BCEC848DEE7 -:101010009BAC8CD03DF74CE2E47D6CF7ADBFE4BEF9 -:1010200054EF3B5C7A7CE45D32F903B820F2A562B0 -:10103000FC257B1B05FE1A92C798767D1E551CAABF -:10104000E3BA31EEA051D707B05CA72FF59C665FDD -:101050000361A0F01BB1FCD67F4751BD5FE67CAFBA -:101060007A1026AA19DDF1FB561DBF357BD4F8DEB8 -:10107000C7A3E77BBF197A7EA77BF5FC1EB048CFDC -:10108000EF41557A7EDFB24ACFD70CBF9E8F99B51C -:101090006374FB87D695E8C6B7BD74976EFFF0C042 -:1010A00074DD387BEB2CDDFEDCFAF9BAF5FCA62505 -:1010B0003724FF8260B56E5FACFC0BF7FDEA9AF255 -:1010C000F7E3AF903FB03C8A511E41C7FF9F1E7CA3 -:1010D0001AAB0737E867DF249B15DF2584FCA407DC -:1010E000C5F1AC2753E385DFF968DFB9830A8E0FBA -:1010F000380A4D699467A9F98347F5435A3D135B54 -:1011000037DE5B2CC5BCB78FD3BDB7BFDEF771EE42 -:10111000D6A06E5C7010F8FB17D761E7BB04DD2723 -:10112000146E778D3C5DF52EC1D117386C77A957B9 -:10113000B5EFEC62EB2D701E64BF3F5B7B2F434627 -:1011400031B26B7F52ABC7B43A37B6FED5EADEAEEA -:10115000759AC863BAD61BCE3423E7D15ECEAB3FB7 -:1011600090BCDCE77C65B8D7E67653118075B28118 -:10117000EAE4508D60A602F41E3A4CFF7312F2ECC2 -:101180002CEAC7879381FBE7CAEADA597E1BA36F73 -:101190000F8D14ED23FAB9D5EDEDEB46B91E97ECA2 -:1011A0006B0BF1D98FC67C3B98F29174B7F85ECC8B -:1011B0002223A7302EF59BAD00CD5F4C51FAD3FD15 -:1011C0005ABFA427BD89FDCEA8C1176468B43BF9F6 -:1011D0003BA4D8FE62C8E0E0FCD4FF2B89BFDFF956 -:1011E00096901B1DC963CED59A388F01B59E7F5846 -:1011F000E5BFD6F798ADD2731C8F588471F9E1A67C -:101200000F582E4BD3DAD57E4915E7E30B06DA5C8F -:10121000FC5D9B52E8147D32AD0F3240BE99BCEBB1 -:101220007AF42F4D3BA3EB43C15BBD6FE87D79841E -:101230006E71FEF175A29F797CDD20EE9F47CE3F57 -:10124000CBFDA887AB3ED6D9C7DC554774F630CF67 -:10125000FFB56E3D94DA69A2FE636867FAE4879091 -:101260007F1D8D9691240FD48307DD51FDB7D0BA31 -:10127000EC4974EFF5E9FC96F168F3B5B27C353AC8 -:101280008FF90EF338E40BC57C6726E8D4FA1C1AF4 -:1012900034EF852C23BD4F947A39A9AFDC53FF433B -:1012A000B3B3F3EE21AC9F970C8E93A24F54358AC3 -:1012B000F2BFB6897D4B08EFB64166A380C3C43840 -:1012C000BDD82AC693EF201836D96AA92FD226890D -:1012D000EF82664BCA6BF3F0DEC7867B57917E5771 -:1012E0002EE9CC23FBABCC0FCD91F0FCB37DBC4FF2 -:1012F000127F242C2FD253980EFE7EECB4C19F2770 -:10130000A1A9BCDD787416D58DA77BF9CF5286B222 -:10131000CDFDF92CAA1B4F9B853DBED3189CE5A79C -:10132000FA090F233AFD7F92447FCA16324FC373E6 -:1013300092FA789FA1F3E9BB307ABF47F3A49F5A92 -:10134000BF346C12796258CD17FFCB2DF2D9DFB8BC -:10135000C5FB3F0DFE9EDEC1E0DF3B04D95F3F3B96 -:101360008CFAE9E7365880F25BBC5F311445BE5F0A -:10137000E98BB4501EFBBE59D499AE772C41F25381 -:101380005A5F75933B83CF49CD14FDD2D4FF44BF40 -:101390004576186A1D3C2D210ADF83C07DEC0EEADC -:1013A0004747F5B137B9453F141E117EAF63DD00E5 -:1013B000EEB72FDF7FFC18F9AF32B7770BD13DDFE7 -:1013C000E018497E6F79E21EEE9B35B91D7C2FE255 -:1013D000CBF4A21F5A43725A6E0D719FED7A7DF5C0 -:1013E0009EE8EF58D8FA620EF7911D79A437DABD5E -:1013F0008847933BAAFFADE11139E7DA76A0F5877C -:10140000B5F1A9579F19A6F6F7E77ABA89AF07DCB5 -:1014100022BF6F3375DF8FFF5F559E5DE4731B0046 -:10142000F5FF2DBD30F6236C233ED1FBDF99480F2D -:10143000F737940292EFF2E93627F1593B1FCFF1CB -:10144000FEF11AF7748CF07C467ABFA44AF4EFB52B -:10145000F5B024E4EA5F27FAA9CB771F39F624DE3A -:10146000B2F88DDC428A07DAF3B17C46FE0EE3EF78 -:10147000E864F1FE0BF9FB0D9D1FDBB7FFA97C0DA6 -:101480000F12EF69C31B2F0F76E0F3CBE9BBB63C1D -:10149000D20FD1FF82067D5F0BF9E5A7FE46D7F795 -:1014A0005AC0EFC72C6A3CB168CF0F34EA9E7F3335 -:1014B000C1F34FC27FA7EA37707FC080F737A8FE1D -:1014C000A941ADBB63FB2F0DADA26FDA9066E63C80 -:1014D0009AF21F5AD7F29F951F8BBEE9CA0C9167EB -:1014E000139E2467E9700BE70B57FBE212C67BE4FF -:1014F0006382D99B309274D2BB82E3997C0BCA99E8 -:10150000DE87FCF52EB58F20E2A35B8D876E3A87D0 -:10151000F0CA49E23859A4DE8BF505F7EF46835748 -:10152000CD1FD4FEDBBA16EE3FFC1F5946A94AB0C8 -:1015300030000000000000001F8B080000000000C9 -:10154000000BFB51CFC0F0030947B3A3F20FA3F187 -:10155000E7B0A1F233B9D0D4B3A0F283D0F4A3E3BF -:10156000762606064626FC6AF061116606061920F4 -:101570005601621D66F2CD0161235106866209069D -:10158000062E20FD5F9C81C10BC82E01625F20BF2B -:101590001D886700B11450FC029096156360782E88 -:1015A0000AD1670D647F1323CF4E4B5ECADC3C8AA1 -:1015B00029C3E6B2A87C013506064F750686891A4E -:1015C00010BE1E92FC0AA098A01A847D481E98DEC8 -:1015D000807C5559ECE61E06CAEB02E5776AE0B757 -:1015E0007FBB0E2ADFC10C959F8B26DFE882CAD70E -:1015F0007043E5EBB84368003560D6A4D80300001B -:1016000000000000000000001F8B08000000000028 -:10161000000BCD7D0B7C54D599F8B98F99B93399CE -:1016200099DC241398BCE02604881A6012121E8AE2 -:10163000781302461BC304D1E22EDB1D686B23CF57 -:1016400001ADC6C736139290204482765D162D1DDB -:101650007C15156B4AB14BBB6A27402B55B70E164C -:101660001FDDDA6E60FDB76A955F50A9F868F99FD3 -:10167000EF3BE74EEEBD998447BBFBDBF8B839F78B -:101680009EC777BEF3BDCF774E9CA484A8E30939EB -:10169000033F5710F21AA13FB9434F427A09A98676 -:1016A000E7801C9E02CF187FCF9E81A57D02ED02B0 -:1016B0008A4932839022C27E8A5A36AE13A71232EA -:1016C00096847E31B99896079635103F2DBF75D513 -:1016D000BBF0DCB8B8B67EBE4648DE92BE2357D219 -:1016E00067201C1722E584DC474442F2A1BFD25890 -:1016F0008D97900EE8EC5242C6C4F2F45839147437 -:101700005A20E49B0A1F88889A4CCB3EFC75681EC1 -:10171000C693102749946145E18C6B787B7B7DE310 -:10172000E98376469D62F8FF7A02F33B5B3B720BDE -:101730001B2F46FF3943F15230343EF693D76C2AC3 -:1017400013C08FF5BB9EC2FBBAFF95F1F249A55BB2 -:10175000ABA2F36D10D538D4277D59322D0756C969 -:101760002421D0EF55BD82433BFBBA6C24A4BECFED -:101770008BF8159A7C43F05D47049CCFB83BDEDEC6 -:10178000D51520E4D4526F08E9432524277BF87C43 -:10179000FEB9959084CB545E5C2B4470BCD02F4A2C -:1017A00069FBD86231F428C0D3B0280BDE1BF56E7C -:1017B000E3E30CA70FA2C9148F32A70FB941D4DD00 -:1017C00053FF7AFA902F903E726F31B523E7BF5ED8 -:1017D00088F7EA73A78FBF763C635D87F3551BC21A -:1017E00031EE8E5237A1EB7F6FFDA2CC489A7A235F -:1017F000AF6B25F27BA081E8F134ED36C17AE23C93 -:10180000631679834FBA3E526A796FB6AC973476D5 -:10181000C6925DA3E0430A58E76BF4EB6C91B4B752 -:101820007368515645E84FE6FD6D5497C708D02DB3 -:10183000D036C587D45B9120943F4890841EE51034 -:1018400088B4EC54F5F8DD0294E2B82E067C4AA97F -:101850006819CF51E8B1AC07591213CCF03B5B9C2F -:1018600008870C6CC2E55D18851B831B8638330125 -:10187000CA775AD65FF692849BCAD54DA595C4BC4B -:101880000E069D0A8241A7779E9B5CB18FB7D80A4E -:10189000E739B7F3CADAEF8D3625A3B593C9EF0D53 -:1018A0003C51E4FD0A7E31AD7B9783EC17A611D243 -:1018B0005EB831066FBBE07FB3913E416891AEC226 -:1018C0004A15E889EC166480D36D9047301BEBED28 -:1018D000221AD2534CB895403DC91B463C19DF47EC -:1018E000868BD35D4CEF2FA5FD5EC3BBBD86EB336E -:1018F00052E5787BC080BB04E73154A6F3F8E0766C -:10190000FA3F4A1FB10A21FEA830FC7B03E8432AB4 -:101910008F1AE0BD499EB804AB3C6BE0DF0E3EF38E -:10192000C6A4E9941E93218980B8DAF08C4BAFA34A -:10193000FD1FB95C88BB040E2FADDFC8E17C59CF19 -:101940002902FA4CD6B9907E1BAFFC2400E47B62DE -:10195000FFAFE474FCDA38C7310407FD6FAD797E60 -:10196000F4BF313006F2651DD29101D7EA4A09E190 -:1019700048CE11E230CEA1DFFEE19ECB289C2F574E -:1019800009219786F0FA081D2FA97F14184D4E10D3 -:10199000637C8DA8804FFBF8A9F550424B802F9BAC -:1019A00055A776371D6FA5143A0C7A8C8C65FAA171 -:1019B000599D5407EB23098C3EE60979D8AEDDBB6F -:1019C000610CAEBBB434ADBC6AA68A42AD84EF5B99 -:1019D000268D0A67DC313860A2EB96B78AEF39644E -:1019E00082738AE00BFC3E83FE3293CC8475FED07A -:1019F000BB28334146EEEFBD56A54D7610F249ABFC -:101A000076CF21C7F0EF2B2512ED2B1FFEFE6A418A -:101A1000E1F88839C13E33E69D9AA73780F4BD12BC -:101A2000C42F25F595BBDD6DB259FED8E691C2EF06 -:101A300005B65302EB63F91AF05B64A100FDC8F42C -:101A40009F1943FCB8724F13E33B1BBC9D81BF0D34 -:101A5000BC67E3E30FBD1B3682BDDAEE60F4D291C2 -:101A60002B863690E1F462AC8781C7735D8F2D823F -:101A70001BF9C3A0A36671E9A8EB7E363ABA15E854 -:101A8000E892FF793ABA0FE8A8FAFF241D6DFFBF6C -:101A9000484743E52BD15E58C8FBEA1FF8EF6F8338 -:101AA0007C7E5D9750EEBD3E87C9FFD7234C2E2626 -:101AB00049A4A71AF4C15109E554526FF721BCD4C7 -:101AC0002486791C81DFE8F847B9BDF46AAB42127D -:101AD0009371FE458BE8F757AFFAA410F4D7AB74B7 -:101AE0006DC1FE266450D769FB5752656A8043D9A1 -:101AF000CDCA836DA763609F270556FE69DB693DEC -:101B000086E36DD97825C5E742F895C271DD1C21C1 -:101B1000AD1DF6A2E06478A92316BD4AD7E545813C -:101B2000D28BB298DAA188BF3041FFB094DA09268F -:101B3000FBA2051418C8E57A17EA3F7BFFAFF079DE -:101B4000DAEDB8EBE6D438405FB8169F940728FC6E -:101B50000B170B0E660FC5886A825BD4051DF44017 -:101B6000788EEB21D07F619938D434F358A8BB2C00 -:101B700076D749AEC7285E9630BF452B6A9A325455 -:101B8000FFA4A17F6DF319892E8C7918E5C5734EDA -:101B90001ECAA1709106213451033AD58ABEE233A0 -:101BA000F79F61D8373EC0DBEB4BAECD647410417C -:101BB000BD6AD0D32F8E7DC33100EFEB72502E5D06 -:101BC00017962CF6E4B5F51996795D3FE7DA51EDF5 -:101BD000701231E1C144F7FE0282744AFE8BDA29A9 -:101BE000944E63B58311B45B8E0B5A3B2D67CE6D5B -:101BF000190FFDDE2966637D616ECBE401B4B71673 -:101C000020FD67F03E339DD13F94805C9D289287F4 -:101C100034B04747F70B3A016F9387CA8E402426AA -:101C200050BC6931B5521A05DF715DAC4F47AF1337 -:101C300044B66E9DB1456A290074C82A37B2EAA23B -:101C400068FF19F5291D4F107361DC18BE4FD17163 -:101C5000379D176DE761B608C9BC78512619651E16 -:101C60001DB6F5A7E25F4F27675772F8C87ED6BF4B -:101C7000219332B369FF69EA1BCF2EDEFFE990485A -:101C80009200A71C56001E52564BCCFD10BD02CB35 -:101C90004E5E7405C34A31C5A7AB5C846990CEF231 -:101CA000877459033CC470BD37D3B52D34F1E5E6D4 -:101CB0003F4BE8E7AF144BDA406E6CEEBF89681417 -:101CC0001F9E609C6079CA8D0AE0693375B29230BC -:101CD000BEDC47008E8C42FA3B1D274325718DF6F2 -:101CE000276B7D099196E57A12D2E9279F1A123C5B -:101CF000D4FF3E102C6993E9FB8EA504E52301AFC8 -:101D0000DC443F1DC1577509E867090901C01D8101 -:101D1000E538CF8DE5CBBB8BE9FB530D32C60FC841 -:101D200017145EC3AFA77E86A78CE830DEE63C12B0 -:101D3000F7A21DAC237E9D2A5B3F6D7B29494CA7F2 -:101D4000DFB366F4C3F8B17F22A1896C48946B328B -:101D5000972744A6F407E3B7A8A1BBD3D09F42229C -:101D60003789D5A67556C3E8C7DAF196E924570333 -:101D70007E3B2A281FA4917BB78A22D2413CB468BB -:101D800061499A71EE1435944F46593BED44F8473A -:101D9000AA3F544F26891CE85A17002F241CC0F96B -:101DA0006593D48F0EE51C3EDF31248AF582B37A29 -:101DB000FB81DFF2F5BE1AC0C53FFBAE3F82EB46AA -:101DC0001E54C18EA5D0969EC9199217A073607E2D -:101DD0001F8644F43B7C6242D569073E773288CE49 -:101DE000AF46302E97094D28C077B72A1D6097F867 -:101DF000494880EFBE901C33DBF59984962DF11491 -:101E000072B474069216E30FA2F603EBA865D169CB -:101E100000CC7D7EFDE7E0376DF145D00FFBC4EDD2 -:101E20009F0A83DDE6F13F04CF4FDCE3E2E89F85C4 -:101E300098BFA5D07F40DE65CE922DFE4D966E2DCB -:101E4000E7D8FCB0059217E799750DE1FE95DE30F5 -:101E500071CC105C14A226A0976D753201FFDFEBE8 -:101E600065F018F0E54877CD0478291CC7010E8A83 -:101E70001684E314F922014BEC2F23183FA5701DA3 -:101E8000B7C175DC06D771335C2D0A9BAFDD5E8C64 -:101E9000D592B22805EE3991FB1FD46E02BBF11426 -:101EA000795FAF07C2095F8D7AD6AFB2365E2589FA -:101EB000C10A95A8480776BB91AED38716FF6B166B -:101EC0002F6B4480795038ADDF4921D20B96259293 -:101ED0008A0B2F9F65E04BFBF26F28FFDD74D84122 -:101EE00080BF281F4BF0DDC1BFDEC4E3C3CBC1BF41 -:101EF000A6F8FB1A09FB01BE0F888871A80FC8ABB2 -:101F0000FEE926397942E4F6092CB1998F4928086F -:101F1000725CF66E4C4A7E4483416FC2195CC710F6 -:101F200093F35E467731A2B4A13EEC66FEA7114F53 -:101F3000FD7AAFD51FFEC6766BF946B2680CC44B6E -:101F40006FFCB683C469BF3799FD7BBA4EAF892A4F -:101F5000C2F70D12DD0876499783D91BCB55224372 -:101F6000FC73F5BF7D67C6323A9F53200FAAC17E2E -:101F7000A7E09BF4C88A40DCA9970F9F5FBB106A5B -:101F8000BC4C18797E5D8E6423F8DFB11E07DA99A8 -:101F9000C41E07DD27611CD4D40EE1FD6AB7757E2F -:101FA000679BBF7DBE84DC8BF35DB17B19DAE723D1 -:101FB000CDC7B99BDA9B69F49D57122C711F83AF73 -:101FC0000D7AB7F37795A4B1B80E558368AFFC2EA0 -:101FD00023DE8EEB1B9D09EB7BB6F6B3A17DEE8570 -:101FE000B79FFB578E3FEF2CED572B830B60BD3710 -:101FF000057AC3C09F461C6B0D89E905F457C7B32A -:10200000EB6260BAA5EA05CFB15E21AD279D43BD65 -:10201000D2D1FB3BC1ED9217F63CEC043BF5832794 -:102020008E35821DB0F2DF25A2507A38B1C7471233 -:1020300068AFC49D60DFACA07417C77262C6B526D6 -:102040007B985234AEC3CAA77D6847ACD8EB8A37B9 -:10205000D0F62B7EF4DF5309C5C3890D833F2F00D3 -:102060007A7E426071D7D8C0D46BE9FB1532F9C7CC -:10207000701A3A5A26317E7AFFC7194BC04E147631 -:10208000F77F05FBEDFBB2C365D2C74B24078E4B30 -:10209000EBA11F117B5C884F14187C667FC088778A -:1020A000BFFFB8C0E0DBEF88BB01BEDDBB9C115AAF -:1020B0006FEDEE9348D7F39E7ECA0F7858BBDF6A68 -:1020C000A7AFDD2D255C53F1790C9EA041851980C9 -:1020D0004FC6CF6BF6AD46BDB1A66FF349E0E7B58D -:1020E000FB1D16F94FF1124A005EDF90420D50FEC3 -:1020F000E1F7FC1A45D57BC947FD8057DAEF322757 -:10210000A5AB85B3ACEDA0FFD3D9C3FBA39E21FA49 -:10211000CD6BFB36B1F1F65DF30790B76B09D35386 -:10212000063FBF07BFE40DD7339B246B7CEB1479CC -:102130007906FA81BB73D2FACF865E31F87AE5531D -:10214000A776C6E8F8EFEFFDE3CE189DC7AABF7CDF -:10215000B4F34EF0979E77AB20AFD63EF19A9F989E -:10216000F0FF88C4F6034E3CFEBDC776503E39F101 -:102170006B17DA81279EFBC3388DCEFFC40F3E1D3F -:102180000376EA2DCFCD1F0BF8B8E599796347B3F5 -:10219000D7816EE32EF3FAC6B17F6DBF009B20841A -:1021A0003CCB9FB6753AB84F4A4088E083375D71A3 -:1021B00017C5CF5AFAAEA512D66D35EA2B28DF45E2 -:1021C000F1BD664FD749696A3ABCC70AC4203C13BF -:1021D000052408EB7EEDC2CBABE0E908694027643B -:1021E00010F584BDDDDAA3747DA78DBC9ED49E70EE -:1021F00002FED7EED9C4C6EDA3EBE91FBE9E1FC0F9 -:102200002FB387AFE741C91A673A45567D77077CF8 -:10221000DCC7FCCE91D673F533D78DEADF19F2E136 -:102220006C786E16185C5B25FD5712F0E3DE271FF5 -:10223000DB1160EBDC401173E2A953E36093F71DFF -:10224000C7E057404E0E3EE752C1AE5EF1DC1BC800 -:1022500077279E39E2D4707F9A7805AA274F90D4C9 -:102260004F12F4E61A8115D63EE24BB8FC43EBB5AB -:1022700026DE54AFF9F1FD317C1F67FCB026DEBFCE -:102280005848B37E5EB984E9A7782EE265B59674A6 -:10229000AA5EEBBA0AB3603D8F2D00FA1B693D8D33 -:1022A000F9AB30FF99A6757D84F1F148FC7A62970D -:1022B0004B163287AFF3096E57AC8D0B6FA45B776B -:1022C0004236B0F8DE08716FE369A70BA76CE573BF -:1022D000A3BD31FFB3F1F9D9E7757E783BC5F5B5FC -:1022E0001D7FEF7F915E0F94C802D75BBDF5F92685 -:1022F0007DE776503D560C76673456503C04EFC669 -:102300003E09E5FBFBBB25B4F7ED7262CD087E7D8F -:10231000C818677FFF549067EF1FF831A74746EF53 -:102320006BF61C73C6B85E889BF502F497663D2E6B -:10233000E5FDAD7D367D7F6BF79C4CDBDF7BB2FE30 -:102340006580FFBDA483C46817EFF54969E324A540 -:10235000B2C362676DF4CD783393B693FC1E0DE67D -:10236000DDBE417F2306F6C8AB0E82F6A31C7AC7FA -:1023700045BFB7FB3CB8DFD2EEBF916826FDDD61FB -:10238000C3931C0CA31F2D07C2556C2F346EF1672D -:102390001DAA68819BC8B142D8E7FC65F11F64E8BB -:1023A00017E2699A292EF48A4C3A73687FAFE842A3 -:1023B000A88DA4896BD9FA0FCF918866A6337DBC0E -:1023C000688E2FFA0FDC8E718D16124D40BC891469 -:1023D00092BE474DFD3ED8AAB1B86B78BC688EFF5F -:1023E000B9A251DD45E128BC452D01FF6DA4F18B5B -:1023F000A2D67D5F63FCF53C1E41763FF1C413B469 -:102400003C1EBE616A45BCCD09F13795D937F3B89A -:102410003CFC29B79F0F08E1436087E977C56490CA -:102420007782D626839D51FF454C5E6EA2C77AED1A -:10243000641EE8D5EFFE595A928E4EF773BA6AFBC6 -:10244000A71FE541FCEE01F76D85CC990D237C8536 -:102450007C9E878ABEE185EFFDAB6FF44EA6F8291E -:10246000084A04E2350581655B2A60FE47A5905B5A -:102470001BDEBFF1DCC9E37A0FB5AA28FF1F690D87 -:1024800062F9318ED7DDAD65F87CA23584DFF7B413 -:10249000CEC2725F6B3D3EF7B686F1BDFF8E17056B -:1024A000A03BF22DD207F19A7DAD4BF0FB8F5A2362 -:1024B000F87C94CFA71EF0E2B5CC1FE331FB3BAE16 -:1024C000D800F118038F76BCD7D1A962FF9AA0017A -:1024D0009DDF2E33F962C7EF38574208D3724B9411 -:1024E000E52BECE4716363BEFF2A337B731F87E740 -:1024F000C7EEC8F765D86FAA2F2DE7F1F110C8EF26 -:102500009D42786B05E59F178A6606CD72B8C8179D -:10251000D9279BE8675C378BF7EC9099BC1A4F4E34 -:10252000F66752BCEB5F100DE8CE98EF811AAD1044 -:10253000E4E40141C0F5D6BF10499989EE8CFEBE96 -:10254000238B7C7F23BDDC1EA263260FB2AF92CB10 -:10255000C0AF3D453C2189C2DB9947F681DFD209F6 -:10256000740976F26F33304E6CF8375BF87A67BBDC -:10257000D9F7536FF9E2207F46F27B36F2FA1F72E9 -:10258000B856CBE15FC9B8AF1C1758BE4302E398F9 -:10259000056C2A944E976EA56B45EEB9F4BD3721B4 -:1025A0003EF8C1336E0DE0EAA93AEE37E391AC9202 -:1025B000DF37EFEB18EFF34F17203EFF1F891C3377 -:1025C000E339BF79D009ED3B056D5B1DCCEB3509D7 -:1025D000F9AF53885F84F13399A05FD07953300EFF -:1025E00072CF68E70B59F93BDB1D5EB20CE6DDEC00 -:1025F0000CC5D2C8A7DF666816F9E00A5ADB0741A6 -:102600006756B3B246E9B382303911927509FCB40A -:102610006A12C1E74CA2E133CF11F90CE6319D8477 -:1026200035807343C6B8CBD8FEC1FF18DE14C7FF90 -:1026300041BC19F41ABCB46C1BE41F903B44DC6F22 -:1026400069874F263A5FE810387E1594E7053CAE5F -:102650004FE5FF0B4501EC86C549D40C9483057CFE -:10266000C3A065E024C67783E3088FBBC731DF6969 -:10267000C72A11FDF507DE12E290EC726A55C99186 -:1026800049B47D0DE573589FECAB4A33CDFB0C0686 -:102690007F3CA08433D551E2FC065F18E57F19FF2B -:1026A000BC007268DBF8E7FB413FE40F08211063D0 -:1026B000F9DEE864904735BF7B3C0FBEFFC6139937 -:1026C000635E9F1DABA3E3014EAF2F3C17DE870B6C -:1026D000E33780BC3B557F8B0B97D9CBF25E5AEE2C -:1026E000D2B64DD6465E9F9D2DA3EFDF18F3DA7963 -:1026F0008EF332D6EB54FDE228E8713B9EECFD668A -:102700005FB578D4F11F04BDE2C2F92F35CFBF30D9 -:10271000AA627E8BD1DE98AFBDBD7DBE43FBC0E714 -:102720009617D4E72039B0DE3FF87CDC0F5F2140FC -:10273000126109E89FF2E71A806706894A8C1FC276 -:102740001AC87F839E778C792C0FF5821C2F4679CF -:10275000778EE3759270B806ECB2901832DB2BC618 -:10276000B33D45E7098CABBAB81C1133EE0AA6C3DA -:1027700073AAFF42CAFFA63CA62D84B078544241FA -:10278000390F814295961D8749E5DDB4BF66079BE9 -:10279000478DCCE221D30F6BBB241657959A7C262C -:1027A0003CF2FD0623BEDB49EE22AA067E45453FEC -:1027B0005437F8F4E7CEC8B71D908717D430DFD36D -:1027C0001188086C3F8EED0F15717E9D2F2D55C021 -:1027D0002E6921E17AB04BC85189B03C3CC6D72E56 -:1027E000631F8CF3B1CB4D783C38C8F89AF77390DF -:1027F000FBA53FE5F6C9B3DC3EF909D827B45CF484 -:10280000F1E00180733FD8292EB03742F87D1FB721 -:1028100053FCB77812E01FEE6DD5B1FC706B333E00 -:10282000EFB9F5709B1FFA7FEE4707FD14BEEFB4BA -:1028300010E4D71692FCC54A80372A627C63576B36 -:1028400014FBCDDF923C007B24BD2D077485BEEFC9 -:102850008AD68A6E5A6F6715C1F8C64E85E21DE4A6 -:10286000631F41F908EE12CA2F2E9F32D79522FF1F -:10287000F654EDBD0AF051788D88DB2F06BFB9BA4A -:10288000070656D2F283CD7BDD4086D9B9C9F52F34 -:10289000815E9F43E5AD06EB92EC5E40D7B7A06842 -:1028A00091328F96FD7D1BD7817EF6EFBBFF66F0E0 -:1028B0008FFDCF3EF14D2817D8EC59FFBEFDB7B1C3 -:1028C0007A2FDE0EF50A0ED379D0F653D563FD309C -:1028D0007F8ABF81CDB49EA3CA9AEFF894613F74FA -:1028E00012A4ABED3FD82FC2FC0303E11AD8AE19F6 -:1028F000F366B41FC8A7F01D86FF5DAB3A76413F73 -:10290000EF3A8A919E1E6839001175F29D6FBE8E56 -:10291000F47C70D57A02F4E05A25635CB160F52D41 -:10292000E41B2679E16A91D3C699DF75B8907E3BA6 -:10293000572D4E4EE2640A7C38EEF63A05E5C5CBDB -:10294000D67C07637F781789BCEB40FE62FBC4B27C -:10295000CAF6932FA148077B89AC15599E5FB8CF63 -:102960006D8E1F16AE16C3E9E0F8D421E3BC3AA27F -:1029700075EFBC48E72BCFBC15ED52D26B1DDF18AD -:102980008F8EFFA9C3947F22AB0C2E8D84441F1D14 -:1029900077CF5E4F3E944F470D7D95C0FDD3A72B5B -:1029A000C4C4780ADFBDBD22E6A11CAC67FAABE760 -:1029B00016B6AFD5C3CB3BFAA801563CC44F863FF1 -:1029C000B023CAF6BFC91767D0BEF0723ECAAE7850 -:1029D00055C1FD8998EEADA1EFA71183DFC4A175A4 -:1029E00007FB658B950EC48E6C4B59A3C6BA39EFA5 -:1029F00018360D5365D4A74715F0274FF5C904ECD9 -:102A000097697C7FC88ECF1D9CAF7742DE0CF81D86 -:102A1000ABF6BA350AF7CF0C3A6989EAA0178BEE04 -:102A20000AC798DF63CDA3868C10C07311DF87229D -:102A3000D25B15480FCFB23C5A631FD15168CDAB62 -:102A40002EB7E58317D9F2A8CF37EE52EDB4C7E31E -:102A5000B65C84FA42F3A31CCBE7633D329BBAF920 -:102A6000D386C75F52FDF2F802E9F5E37AE673799F -:102A700078CF1D5233F80BFE159559E638E9D54E3F -:102A8000E6C71CFAAD0BE979679DC2F73D59BEA7B1 -:102A900083AF7B9353C37A3B7B6F55009F5D81125D -:102AA00037F473F0D29FB8315F85E7AD1AF278033F -:102AB0007D7F13EDEF3BB922EAA4CEC257F360BF8E -:102AC000FEDE3A05F352FD19037D0769D97BA73372 -:102AD0000479233B6B124BC226B86E7732BDB6D455 -:102AE000C9F787B658F33A285F2C7542DE98378AC3 -:102AF000FB99A2C2F37B6D7EBF810FFF81ABC4E265 -:102B000029EC593205FC54262FE33CDF6A27D70B0A -:102B1000867DB183FBAD5BB8DF6AEFB7B4593F8008 -:102B2000F6D92AB5124254F6F59DD06D959FC53160 -:102B30002B3F8C6FB1F2435134DF52BFA0B9C4F2C6 -:102B4000DD17BAD866B72498BE236C7DBADCDE09DF -:102B500020472AA93EE6F607CAB791F47DB343DFC2 -:102B6000E004B9768E76883F231C85789BDDCEBE47 -:102B700087AFCF3FC8FA16E88FFA75F760BF725C6F -:102B800060E787AC76C93038B99C1B05CE7F719E53 -:102B9000877D76B6FD37FBBEDB6D5278FB2BF439B3 -:102BA0003793E54976FA989FDF09F1555A7E8ECF23 -:102BB000EFFB4E099FFFCECB733368FD34FC6DC431 -:102BC0005D7F0A0939506F6CFAFC4BB08CF07B4189 -:102BD000FAEF3F75B27DEEB9E3471FA79F8FB3C5EC -:102BE000A13FEB34C5F7BA9CFAF3E6F24127DB9735 -:102BF00036E8C2C8AF34ECB45B1DFA2173FDA1A75F -:102C00005D5EB2FD915CBE9E3EC2F8EF674B966F73 -:102C10009A48F9D959E845FB277749C73AD10F793E -:102C2000494915FC845C2EBFC96226378DFDF6EC40 -:102C300006AB5CB59FC372F17C7997FDFC0D97AF35 -:102C4000767A1C49BE1EB3C9D7545C7B04BAB2C79E -:102C5000B55BE057667F72FB389CB968CAC8F4F868 -:102C6000CBD6C19E431387CAAFC0B99AB474C0F61D -:102C700019FD07DE6D585C05FB795208645CB235BE -:102C800031F7ED8943F22B3C27EB67100F0DD76529 -:102C9000A1BC690CFEA9E7500E95CB7AFFDCB74DBD -:102CA000F34CAA14DA09A3F089EEF8CCCC5FDF0369 -:102CB000590F76111F6F2BC7A7DDBEEE12632EE8EA -:102CC000F76332A00BC5A3CFBB03F136E0053A1B77 -:102CD00069DED35D4CBEFB67454310BF739D919089 -:102CE0000F5CE30D3B268476CC0C5716A3676F0967 -:102CF000EEEF51FF7DB01FD6C1CBF2FE0DFDF89176 -:102D00001167E57AEFE62C56DEDCCAE2CAAE83B381 -:102D1000DFD0683BDFCB0E0271CC4D54AE437CB0AC -:102D20009BDAF9F0DD5F354020BEDE4EEB474CFE0E -:102D3000787BA85685FDC68EF24A05EC0A694A15CD -:102D400096E5E24AB5968E39A5EBFE79B9101F2FAC -:102D50001531DF761A2DB79552BA76A938BF5F962E -:102D6000BDED05FB2C1B82A9D543EBE9A88AE8122F -:102D700085C711546B214723A5B7399DD1F70F4162 -:102D80007ED1F784C86C179DFF2FF9B9AC2E67B4BC -:102D90006C3DF84372CC0571C01685ED4F003D7453 -:102DA0004C1F82BB96E3D7CDC74DF9477C3D3F967C -:102DB000076290F2DA2592E674EBD3E06272AE43DA -:102DC000D5D551E949953FB3E455CF61FCE40C50AA -:102DD0007A32F1F548F25A728517BB7287F298E899 -:102DE000C2AAC8A784D981C6B99F3F38F52558CF54 -:102DF000CBF04A0AB3914EE9FBF99EEA0B91FBDA5C -:102E0000D63ABA6E07E6541DC17856D2817124FFB6 -:102E100004F28F663BE4251706E3E893C52DEFA681 -:102E2000F4119FCCE21504E826832A62D89F2C1265 -:102E3000E30F1503BCBBEA27D0FEBAE489D4521FC6 -:102E4000EAA7A688F9033DB59E66B35FF0C70CB646 -:102E50002F739BB7E619171DA7DC1BAF45F30BB209 -:102E600036C7B0735540C797A8644010410E860915 -:102E7000D39B2185C54DEB543847259008399331B4 -:102E80009A7EB49EB77A428E6FF0003E022C0EE618 -:102E9000DB2E6092A0D4A7273C2012BC8BBA5CA882 -:102EA000C7C365304EFF0C0FF1D2FA7FEA77E23EDE -:102EB000789FAF4006BC3E2F2EFFAE93CE77F0D763 -:102EC0002ECC7BECFBF3C59897DFE7BB6C01C8ED1C -:102ED0003E811CA6CA9ED49C2EE049882403F6FF9E -:102EE000FCF37402FB30833F2368FF39822FCD7DD2 -:102EF0007B3A4E3C439C45DBB949B79BB60B7DE61C -:102F0000F9E80A4A577BBD95F74D2343F11623CEC6 -:102F1000529711D90974D139E63F9B816FBA299C28 -:102F200012FA137A10E0AECC15312E4972BDF18938 -:102F3000F47DCDE1401DE495D6C8159832EB9FC7CE -:102F4000D6FB379EC86E986F9DDA549745EB571D98 -:102F5000D550CE2E08AE3B04E5196FB172A793F1A0 -:102F60000BC4918849EED69C1E87F3FB21A7938E54 -:102F7000A09ED48551F9C6761EC19A4767A603C89C -:102F80007F37D141C461A68359940EA698E94017B2 -:102F9000CE870EDA50595F08FFE86FD40943F1BCC1 -:102FA000E17CB04EC92E1FCE2F061C775765074017 -:102FB0008E1A7CA1CEBC0BE5AA6B99330CFB2D06B7 -:102FC0009F18FCF1A9DB817C48F9A411F87DB15769 -:102FD0009B9F8E4FC00F31F3C3B523F04D23193C97 -:102FE00014A08D1A6512CBA4A2E497B3DF291D6744 -:102FF000E2033BDE1AE708E4B8459EB1B209AF6AC6 -:10300000EADCA374EEF87F55D63A03263EDC48FD91 -:10301000103096BBC51001BD52ED5DFE29D0A5DC78 -:10302000F08320F8830E57B819F36967BE9F7123A8 -:10303000A5CB3F8D1135987CA7B6FC69E4E7373303 -:1030400008D8273D3356603CF84F3745C6839ED895 -:1030500044F17F1CF5727CAC88B9990363D93EBCFE -:103060001664CF4890BD27FC7B9C97755E6F00EB84 -:10307000D175B6C8C71E37A3F71E37D3179B9CBDA3 -:103080000AF0DB60B1A29AF3A0AF90981D5BA5F0A7 -:103090007DA92FDA35881B5629ACDD7DAD7D687F93 -:1030A0006C6ADD8FCF9C8638813C2B4F594C83FD59 -:1030B00070E52FF30407F0F1C56CDF16DEB799EC6D -:1030C000AF710AF36395BF4811E04F65434CCB36AF -:1030D000C959451422E9ECE8AD6E99B5DB40F0BB67 -:1030E00072E05F719F3BA734247C1DCA1B7A49881C -:1030F000F6E34EB0F781525DF89AA9DF40439F4551 -:10310000CF35D225C8AC44EB09CFC1746A1EDC1799 -:103110006B0CD4BE2B4F1D4E47F073DC440F06FCE6 -:10312000C6FEEC2DDCFFAE2B5190FF3A5B9CBB4002 -:1031300035372ACC2EFA38503BEA3902D897A59673 -:103140001BFAB9F084FDD9D864B63F0B65D89F85CA -:1031500027ECCFC213F667E13BECCF42F9FBAD3A67 -:1031600096619F16CAB04F1B9BCCF665632EB62F97 -:103170000BCFFDADCDF8FC496B14BF3FDBDA82E528 -:103180002B5CCCBF2165B120D8CBDDB73B75C8BF68 -:10319000E9E47470502FC909D1757507589CC0FDBA -:1031A000F2BD780EDA1D1471DF7563F05EF255FA28 -:1031B000ECAEF675431E8CF2B4179F6EF93EA2E199 -:1031C000BE6CAC1922A7AB94E97532B5134A83EBF8 -:1031D0006AB36979BD32BB03F21127696DA1E5EAD3 -:1031E0005059F355AEF881A93CBE7C97ECA1F56F20 -:1031F000EBBEAC03E401C001FBC86DCADC3AB0E32E -:103200001225D45001B956EC8C033D7F0DD66B22AC -:10321000C0CFFCA92F91F620C435C66BCE4AE0433F -:103220005A3FC1E8FFDCEA774210387778BBD1EA31 -:103230008955E7548F48A3F407DF85D1FA21ED6A59 -:1032400092C2BE196406D8476EB6FFDBED60FCDFA4 -:10325000ED66CFB739DFFFD85D3BDF4DF968BE9B28 -:10326000F161B73B5C0FE75006A788A18708EE9B8A -:10327000C4DC7028A1A5F857705EE8D6176502FB7C -:103280000A0F72BE9D38DEC7F4F49D0AEAE92BC727 -:103290003FD5914DCB131F0E8540EF6E26210FD0E9 -:1032A000496C8B88F9294F564DC86EA2D52FA97E3F -:1032B000261BF4CFA70AB377E3DCDF68EBBC713CD5 -:1032C000C4FFFE7484C9BF2739BDED7224A3B89E24 -:1032D000D55EB457A8C380F6485B50C6BC22318F78 -:1032E0003D9D0EF5EFA09E932AFC1885C7F9E7993E -:1032F0000AC63F4EBBF8BD1749B4539CEE889A45A9 -:10330000DFF7C644E4F776D51307BB7AB3B712CF1D -:103310009BC6CA653C77B2B95C64E7657CD7C7C118 -:103320003ED9DAEF66F2C1AB605E69BC7CDFE1DA00 -:10333000003C4515F83DAE2FAA47BCABA28AF9A9BF -:10334000F437FCDE1CC0732A1023C7EFCD2CFEDC43 -:1033500039E6B397A641BECED7D510BF8B00F3BFD9 -:10336000D1E412619F68F04006C0F30FC63D06032A -:103370001B3268FD8EE56A08D661AA5A5B0FF90513 -:103380009D6A2DFA391953EA9465288752E734F07B -:10339000BE8C8E7219F38BE03BF025E92087E09C10 -:1033A000BCB1FF9C915529807DD5D980613E38C73D -:1033B00060C937EFC8BE1ACF27498DD9086727D112 -:1033C00015A81F6B9051FF15789504EE3F18E7ED97 -:1033D000E1E88529DE90B3CA7A7E23AF59B69C17FF -:1033E0001F1BB1967379FC20D776CEE34F8AB16F5D -:1033F00066C5937DBE398187B200DE1C38E0AB0D17 -:103400009FCF7D81CA26986781EA41B883EA861AF0 -:10341000905F6349B40DE8EEBCE1B5C139B5BC239A -:1034200009EB3E559389A641BC7D7003F4BB99D34B -:103430007977B1551F3FA848063F4E75E7429C512A -:103440002431D3F810878C99C69BD09D6D294FEC01 -:10345000CDB7D49FBCBDC4F2FDA2F8C596EF97ECE2 -:10346000AEB494A7F45D6AA93F6D7FADA55C91B839 -:10347000DA527FFAE145967275F2EF2CF567BEB924 -:10348000DCF27DF6C00ACBF7CBDE596F295F3E78C0 -:1034900087A5BE61AFDBF56299FBC2EC7417DC1F38 -:1034A0006189CB5AFD00BB1DAFFCA55DDB0072CD71 -:1034B000EF44FA96418FD3F2FADB991FA5CC0D6940 -:1034C0002057C671395AE4D3AB418ED6F815D407CC -:1034D000B297D593BD0BD0FE18B79DCAA3E9606D16 -:1034E00092D4F70C90CBADB1B9A5A678935BEDC59E -:1034F000335B35FE7A02F179A3BDACEA2402FD40CC -:103500001004E2E7D44B857A6E8DB637CDEB795156 -:10351000C4A3D183D4DF7BC8E4EF8DE4DFD9FDB948 -:1035200073F5DFC689C483E70D8470149EE5D1234B -:10353000B590264CFDBA1B807E7B9CE1E65DB4DF36 -:103540009E120FEE5F1A7E5D77711FF2C560B18C1F -:10355000FA85C85AB9391ED7C1D737437912FD4AFF -:103560008A7794B706DE370B03F176903BB77B5032 -:103570001E8EFB2FD7ABC05F4A8952A0D0F7A18324 -:103580004E1DF6B7EFE3782D512B6A21A4541A6C27 -:103590003A00CF491AB533E8B3AC6CDB0178DEEA08 -:1035A0006679C217877E500BB24499CBEC3F79AA5B -:1035B00033BE81F623A9148E347E85F194FCDBD9C9 -:1035C000FE45A9FC7BA037B0EACFD029D4642B7884 -:1035D000FF8C1BE840C027D28F3BE045BDE186430E -:1035E000AF5096857886C0EC53D89FABC9DE8EEB82 -:1035F0006ED8AD60CF46989FDB01F41568B0AE770A -:1036000086F27DC45387C0E2DEDD59DACBB574DCC7 -:10361000EEDC926C88B1425CA4C9246F7AB8DEFEFD -:103620008A47E4F96F4CDEFC05FAAC1EB27728FD40 -:103630006F1727007CBD04E496FBAE5E02F4EE56E5 -:10364000E96AA25D1FD3C2A84F99BD7B3387A9AE9B -:103650006409EEFB7F14A844FBD6DDF27C5AFCB96A -:103660000724A24F1F19AFFE493B50DF9312A70654 -:1036700076458BE6D477A59107E5DC0FD934CE38B3 -:10368000E7CACEDB76737C18F1D0549C91C7D38CFB -:1036900038A3D1CFCDB9956347B3C7DDD4BF8C98DC -:1036A000E0DD44C701BC747ED1548F7890093BA7FC -:1036B000FBE7F25D904765F849E5DC7EA9E2F81D7D -:1036C000E724E827CC83B8490E78B55FAA07BE3453 -:1036D000E22CBF03638BD60BC588C4E26A0E436F2E -:1036E0008967A621CC9A7306BBE28BE5A332BD465F -:1036F000FFED87F36413BAADE73527F65ACB93B7DE -:103700005BCB17C5AD656A351F05BB006C348C5BA0 -:10371000ECB67E6F32F603EAD8F932858E7C86E904 -:103720005FCB7D3984EBFF7CDE4F515FA206C46B1B -:10373000E12D56BD9ACFF57CBE4D7F56FA248C27DD -:10374000D41C0E1C02FBD188FBFCC6A359EE7530BD -:10375000E2377679EE796B1BA15FD02F8FB8581CBA -:1037600003E2C39F14F17849218F978CE3F19222F1 -:10377000162F7148DA2B4B05CC0B3DE9463B233A1B -:103780008DC569D839AF0FEBE59F091A1B2F621A57 -:10379000EFB6B2D8950C0DF13CA867C44D8CB8803B -:1037A000D7A7CF073EDB1C7A357A90D249EDAF5DC3 -:1037B00004FA992FBD7CB815E45B918CF9DCEACC56 -:1037C00055DFF5401C12BED3726DB13616F9E01705 -:1037D0000E8C0F7471BA36CE271A7116BF87D94571 -:1037E0001E8F60EC037978BEBE07ECDD4B76535A32 -:1037F000B4E83B16CF33E27653FAACDFFB8890A3F4 -:10380000D2759CB6242E32FB4AF7D698F21D2FE6CD -:10381000EB367569E2DEA5B4BC87C42BE11EBA0A9B -:103820004E1FA143D673B1638880E7A2C61C9542A0 -:10383000715A7FEAB3D6EFE5B673B317DBCFD1DAAF -:10384000F6857C1239B98C8EB7458B0A2047B72C88 -:10385000A5B63C2D4FF6F0FDA2496412D0E17CC91B -:103860001B4A007E5F93707FCB756CF21B90C7483C -:103870008EB07C247502CB8B545F92504FA919A453 -:10388000A2C23BB48F74FF9910817D1123AEF50461 -:103890005D57D02B7BA85F5EEA003F5BC5721FF5CA -:1038A000CBA1BC97FAE5F0DC47FD72780FF94850E0 -:1038B000DE4FFD7278FE84FAE5F0FE59EA9743F98F -:1038C000366FCD7C4F2EEC1B9521BD782AF629133F -:1038D00028BC5D8A4305FAB0CBA19A9A9B95C59402 -:1038E000A4FECEF514EE5FD4CE67F9D3F33D4FCDF1 -:1038F0006B93ADF13573FC7128BE362018F1350895 -:10390000791EE3FB0CA9385B84C5D9CEDE8F6EF43B -:103910008371CD61FDF0F8E607B7FFE763EDF4D3FF -:10392000EAEA7BBB3D25709E234ACCFBC7C6390F14 -:10393000637EABF7B5619E8C33EF6814D6755F95E7 -:1039400017EFFA713A222AC85BBB3F67F871767BA2 -:10395000DA78DAF59B8FDB1546DCB4C741307F3A65 -:1039600026507B02EC8BD6F8DCB71D23C7535FF7DC -:10397000F0734536B9903A37C0E33E2EB066E93C65 -:103980009D02C707CF6747D158C2E27AE6B8AAA717 -:10399000348E87D53D5E1DED3A81DA7B68FFA991B3 -:1039A00020C4D136C2398134F37B98F37B5B9E13FC -:1039B000ED8D8D790ADA497585A120B46FCF9B1101 -:1039C000349F1B30CE351CF2CD50064CFDADF79523 -:1039D0008CAAFF24AAAFB551F4B5E462E77ADA0FF6 -:1039E000CC56E0BC46B7777912FCE8EE6000E3EF16 -:1039F000FD793330AF27553F380BCF75485E660FE2 -:103A00004B4105ED6119E65F3E54DFA8D7EA6174CA -:103A100042D919E38B6E6F2FD673C961BC4FC215A3 -:103A20006079772E95EDC7794A45A298E485316E85 -:103A30008B87C5A3BBCB232AC459BA8332E6E97767 -:103A40006B9588E7768EE7F622C39E08A11DF36F7B -:103A50001CCF463FED3C0ED0DEEC447B2EDC92A525 -:103A6000C2D52F5E5F780FF073B7778302FB92CEDB -:103A7000BCAA51FB3DC0E5F6C8FD568CA99B8EFD46 -:103A8000FE1BF4EBF42D57A15FC708E7915EE170D0 -:103A90005EA8DD6ADFC7A3D006CDF928F6A78FDBC5 -:103AA0009FF676ABCB079CB0EE9B1EB19E5F761067 -:103AB000769E6BCDFE75C8E73D7212EDA89E2F84F1 -:103AC000B4E7C2C66418FA2CE5DF5BECA002CE4F67 -:103AD00005FC3B901AE88B8A84D56E997ED85AAE45 -:103AE0004E5ACB33DFB4DB41FA6B60072DE6722F01 -:103AF00049E53D4B861994011FE158BC06E06E2252 -:103B00007D6D9027E1E071F2C55CFF2DE4FAD19B59 -:103B1000C1E2BD05CD1E8BFF49F8FD7F85BCFFA22C -:103B2000BA43EB3A40C8860DBB4A43BFB5E8AABDCD -:103B300035282E6DF655936E3DDFBFD0663FD9ED2B -:103B4000AC1A7917E6E9E6DBE21AC67E2ECC13EE54 -:103B500039B08F7FBEE31AFD411E16C837E3FE174A -:103B6000BC6F98B62F92134288E2291FCEE7507897 -:103B70000A6E21FAAE34747C395FF761788B5D810F -:103B8000789BC7DFE57BD9BD5DF975525C2B86F369 -:103B90000E7D680F2C5A45E78376F819CC8331EAFD -:103BA0006767F5F5C3BEE78E0681F9A53182768D8C -:103BB000B1CE3BBCEC5C61D3E5425C84F6D1121C17 -:103BC0001FE12A195A5F8AA7E30C4F2CCFF0DA7A4B -:103BD000EBF9C7269BFD62D0C342DBFB010FDB176D -:103BE00037F8E083D96F4E1A47E1582DF4D6674C69 -:103BF00038777D69E20FC719E043F87D0C4B7D01F2 -:103C0000FE38A0FC50057E7F3E6BE0014249B229A0 -:103C100083C4EA28F1FDD433788940CB4B363FDDAD -:103C2000D95D04C7BA079F0423CFD5B56F7EBDA960 -:103C3000ECB93B81E5001F07B616D97A9BEE83A14C -:103C4000A8DB0979F360E7EA649B04B9B6A2BA2D50 -:103C5000543CD42E1BDA09A3B40B936D729A765E92 -:103C6000A31D45D746B8EF89CFCBC3BF8B1C1EF32E -:103C7000F832E04DD5BC78BE7181AC425EC65F0BB8 -:103C8000C798B3CD3B42B639260C6F47C16E33E0BF -:103C900017D3C31F87EFE6F11DA3C0FFB7C6C7D96F -:103CA000FA73F2EFE70D1FADBE61CCC8F305B81C87 -:103CB000780F91E6154DFD6CEDFF14E3E2F20D0473 -:103CC000CF2FCA0E5D85FDBC72F5DBE8DFCB5975E1 -:103CD0002AD8019B6819EC804D7DBD18FF2E2FBDA1 -:103CE000B71B88BE3CE121200FA610356B0FED7786 -:103CF0008A2AC3892B225F7E4884783AB98660DE9F -:103D00004866BF87DD1B547CE9C3E06F656529B851 -:103D10009F919135E36166F4B238B3017F46CDD10E -:103D20005A88BFCB4D2424005C429CD400935D4450 -:103D3000707FC3A3EFBB0DCE1B1099E927BC3B07D7 -:103D4000F42A8FB78F652443BA9D6A13E6AFBC2867 -:103D5000631C6B2C5C0D4689B2BC3C7B1BC0531EA4 -:103D6000A11D08003F8B974D8988A104EDBFF22467 -:103D70006B47FE839D2BA1BEC99267BC437835E497 -:103D8000CA581E870F2EB5C6A9C9209D336D5FF98D -:103D90001F8B1E8538C59861F29BF9ED1E0E67E6F4 -:103DA000491286FE030D56BDE1E179D71EDBBD3217 -:103DB000953E87F53E68BBFFF0AD30EA0117092953 -:103DC0004EB42F96A2DD60F8253BA022D8E34584AF -:103DD000E5E7DBDBCF60ED4990F9292E0F51944ADE -:103DE000FA7D8547C77C43172D533C0A4EA2E4D188 -:103DF000F7F9228BB7B4094486F2D07809CC337036 -:103E0000295FEA00FBE580321DEF4B33FCEA763593 -:103E1000847910A4ACD662371BF95EEB2B4AC6C27C -:103E2000F7CC31A9B8930A74B93EB714ED687FCEC8 -:103E3000C0DF839CFD6CB37F81723995A39087713D -:103E400029E523AF7B636C0E1DF77401D14CF69905 -:103E50004B8E629CCD757A9CE57DA2D57ABE5AF7D1 -:103E60008A75304E9197F1610D513BA05D0DB19E69 -:103E7000A3769DCEB3D8EB43FD175ADE27A85D632A -:103E8000BEF767E4FE33885666EE7FC208FD4FB288 -:103E9000F5AFA6ED7FA8DF1C4BBF9D328BBFC602DE -:103EA0009EB4F750567B6B4BBCD523EF0F5479591A -:103EB0005CB32B18C5FD815A42199FD2CB155F1CEC -:103EC00097D8F95E82F61B29B4EE0FD4723A162900 -:103ED00065001D5F215BEF339E4BECF71B5BEDA292 -:103EE0003720B845F125FAAA92B84FF0A957033FF9 -:103EF0006C24BB39D94A303E3D3763E066D807BFF2 -:103F000066CB7867E72CCC67467FFEEFB7542DE091 -:103F1000F781B2BCE680887809D78EC5F35B463F4F -:103F20006127990872312CB23C08FCA1E32773F396 -:103F3000310FD13EAEFDFC7B932ECC2D35CD2B0920 -:103F40007985E6F1E615EC924CF308BB48358EC74F -:103F5000EDDDD478632E6CBC233C9E658CD7B4C059 -:103F60003ABF26A78AF36BE27C6C8C7704E697064F -:103F7000BF671D8FE74DA6C6BBD23ABF26978AF30F -:103F80006BE2F7EFA6C61B7361E319719D2E6734D0 -:103F90000A7438527CC788EB5CEF7AD212D721E4DE -:103FA000C97935A5846C1398FCD8E9ADD90874F1AA -:103FB00051C3FA32D42BDCBEC67B56A93E5E2833F1 -:103FC000781B0BBDF136131EE1BC8D3E19CE49287E -:103FD0004477B173133A9EA308E2F3216AAFEB98DA -:103FE0005F5286DF1F6B0D617977EB2C7C1AFD9495 -:103FF000CD62F7815D3447486BB7BFEE65FEECB626 -:104000003CF586AF817EABF1B07CDF599711DD6462 -:104010004753C3FA009C9FEBB99E54808E9CB49D7D -:10402000C11DA81B1387F5F7541C4AB6421C5476D1 -:104030006898EFAAA5FFFB0647BC4CDFB85CAC3D17 -:10404000B98CDD8BDA983A17D480F9478D0BB330F1 -:104050001F61D162DDA752BC2D1684D74AB9BE8339 -:10406000F350D7F1A5B6FB0B01D03C74BD02BA14D6 -:10407000877BE3AE2B7C798940FB0DFBAE453F236C -:104080004C1B66D37EAEE3FAB6E6988B403C82CCFE -:1040900077A2FC5ABCD8EA176C732754B073B65594 -:1040A00004481B6DB7A8C1FADDE5627C15B6DD0BCF -:1040B000D378967B628C7C5B3B7EEC71D397BCFCA7 -:1040C0009E181E1F3D45CAF1DCB991976B6F6FC4F6 -:1040D000413700AF835C7532F9309C0F183C7FE4A8 -:1040E000727047EB9B184733E0CB97E302C8FB8223 -:1040F000E6372D79EF14B168541BFB0444DA538181 -:104100007AD8369F1DC29EBCD1EE89CA27F2EF072E -:10411000CAF8DF331086CFFBBD61F39EF34A29490D -:10412000C73F2C1EDC78580AB569437831F0F0BFE0 -:10413000CD47F773BCBF32EFE32AE607165AFE6E8F -:1041400080717EEBDA545926B2899E17AE70EACCA4 -:104150005F1D2C07BA3C7A794688FDFD0B6E07255A -:104160007E2D821DF4D7F7AF1759F29A79BF23AD90 -:10417000973D9FD2740E99A4F68D20FFA52D14446F -:104180007B609D88FB1FF951968F07DF8F5BED5693 -:104190004B3E5E7BFFE302C40D1F80FC44D339BB62 -:1041A00082E63EA113ECBBB6388B4324683D0A7708 -:1041B000617342E8281FCAFBB2CBF5C255D67CC159 -:1041C000CE398BD53D1AE4D5D4F6C285609BB6B303 -:1041D0003897513F15EFE2E7511D244AE0FC85E492 -:1041E00065F1E620BFAFE36CF9BB9F8831B5B81825 -:1041F000F276E34A0D5DB7077322753E885F062AA3 -:10420000A3BB803EE510E6792F6DB9330C714235C2 -:10421000277D1C7C29B70F16FA585CE52D47A208AC -:10422000E2E6C99CDA85BEEA34F55BBE85FDCD1DAC -:10423000E11EFA66DECF03627A79B08C7FFFF26A04 -:1042400011EF1772131F9E577597F6CE027C3CB084 -:10425000664728DD39CB196A246286C75DCAEE0736 -:1042600020A46F36CC73D3E70FF63D4DE79DFDB923 -:1042700017E56CB6C4FA35B56FF6E50E6FFFFCA70F -:10428000EC1CF2F3FCBE75424AAF04BFB1275526C1 -:1042900031B88FBD278B976302FB9E2AFFFB02F884 -:1042A0007B4A3D40A394F8FEE8FBE54688C3F60848 -:1042B0008413EB2B0B206EDFC3EF773F0CDF69FB22 -:1042C000B957BFFFF056D007339CE86FF6707BC735 -:1042D00080EF031FCBFBF9C0C7F87D247CDECDF156 -:1042E000E9057C06CE0B9F77A7C3C755017D33BC7C -:1042F0007743260805C1FDB9720BE45BFF6B2B0900 -:104300007F8DCEE181D0BEC7E14C116D7F6FBAF6D3 -:104310003FCED1EF8375F2AE3E8EF3F3957A4380B4 -:104320008A4D3309F693068E07D2F563AC6B288B62 -:10433000C93977267B6673FB5272258390BFA056DE -:10434000DD7FB34AF97E63717249BA38F1E37E6664 -:10435000F7678D10174F70FC5E991D7E12E0EE50CE -:10436000EF457FCF299030D4DF346B8008A676FFED -:10437000E567F8A670FF10E076CE66F756FB28DEFC -:104380002141CE57C5E0DFA41D2590FFEE0B1EC5D1 -:10439000BC565FD500F23B8AC27C4657E00F2ADC50 -:1043A0007E4BF8FE7B01D04DB664D0DD37BB806E0E -:1043B000A4A1F29550DE95CDDAFF3FFF37BBC05F79 -:1043C000DCE9A46D400EE63BD1BEB1CFEF250EAFC8 -:1043D000ACEA3F87F90DC3A76BE0E1ADB47DCF44F4 -:1043E000767FCB5C31B9E4AB4097577BD13EA3EFEE -:1043F0009798EF1F3BCDE9ED34F7E77B3E55F0BBD7 -:104400007D3D46A2D7810BA7D78111E8F5988D5E37 -:104410003F26E9E9F59D74F283D2EBBBD0DE8E171F -:104420007B5922FA76D857963F5BB01BFA93BF347C -:1044300067FBD3F4297DB62586AB19122CE7998743 -:10444000E47DE4135FEED03D03C6DF2DFA27208420 -:10445000DC34FDCE9CB11DE4D839F42BFAD3F49BA7 -:10446000F43178E75EED8DA4BB376E8F9FE5C7FF13 -:10447000C8CFEA8DC4376FF9597ECA487C73D09F84 -:10448000E29B6C80E36C7CF311AF4FD721DF7F4E52 -:104490007CF36D7CBA4B19DFE0FC2F1DCE3724B6C0 -:1044A000AC0BE4F1C662C61797DCB306F922C54728 -:1044B000B156FC2E0D95517E1B7CF4E93DAD58DFC5 -:1044C000DEDE3FC23D819529FE0F57C03CF44BD440 -:1044D0000E763E6900CFE1EE2283FD2ECC13667985 -:1044E000B99E584C67E64192C07D1297723CEC042D -:1044F0001F0DFCA0193C9E2527C922DF707EF655B2 -:1045000025AACCF7BE1CE1ED3D99E11A187F1719D9 -:10451000C0FB9A465AA7051CDE33D9FA027F1A3A25 -:104520003F9B1E5AE967E7E556F27EB23F57A2600D -:104530009FDAF97DEE9A9FBCFBD828FD34F3F61183 -:104540000EFF05F07FC49F867F29FF2F83F726FE8D -:10455000AF124AD2F27FB33FBDBEBAC9FFB7E5F78B -:104560006FA6E3CB463FE3F7B3E17BBF9FE9FDFDD9 -:104570001C4F178AEFFB79FB7B2E1CDFF78C80EF3B -:10458000ADE788EFFBD3B5A7F8FE173FCAFFBD081C -:10459000BF4FF362BCBC7B26D92794A485E3BBE65E -:1045A0007E148DF54379EA6381D2FDDCCFBA43E90D -:1045B000EE45A2ED1E4BD76E815F3592CFD7E1FD60 -:1045C0005F5FF2E2BE02D58F4FFC8DE9E047E9E87C -:1045D00060AEC8E490E2BFAC0BF4FD5FD1FF817424 -:1045E000FDDFC5E5FAD9EC82D786EC825FF8AB87B0 -:1045F000CBBF5DFC7CB2AC46927E8CDB0F5C05F2DF -:104600006AE71DD902C4BB0AF584007EC2CFB91E79 -:10461000BB022E0DAA1E6AB7534E08F0773A7646B3 -:104620005501CE4B99FAFBCFD1FAB3C341E1FBADB3 -:104630001FE59DFE3B782EE0F33B5F3BA93F5BFF10 -:10464000BD1FF54FF81D78EA93AD72DB988718EE21 -:104650006579B6B3D2FF5DCB9FFB64AEC7C227CDF1 -:10466000F2FFDD145DB1FECE57FF50F83EF333BDCF -:10467000F2453AF8EC78391B9C17F965434F39330A -:10468000D3E8297B7F869F6DAC135C8B618EFBE446 -:1046900064A6F47736F4E7ED14F11C552397278DC3 -:1046A000B3B2B8DDAE7AA0FF07781CFE8155F7D60D -:1046B000C0BEFAAEBBD40A40417E33D37BDAAA71C6 -:1046C000185F2DCA142CF933C633D5DED97711FC07 -:1046D000BD083A6E318C7BC51C9200BF3113EC06CD -:1046E0008C57A8F8778DB35DBD4188CF6E127A974D -:1046F0002C07BD7A95979D8B092E3ECB7D991B2C5F -:10470000744B825567A9DF86F5D58C5EBC3FE59C6E -:10471000EBBB7AD3DA59B599A2E14F5C9E593D0AB9 -:104720005E83018C7B19F81D3E0E5BBF9A705400AE -:104730007CFBAA041552EF7C944EC05E124B9398FA -:1047400037754D15A31742FD92D1EF5FD968C0159B -:104750001E75BDCF112EA3DEC8E3F17AB6F316A9FC -:10476000BF3FE665720C2BD2F2878773D2EE2B180F -:10477000CFAE5655872B923F54B54CFCBB1DA9BC00 -:10478000EF507091EF7FBEDED0BCE22C3E6AAB9F53 -:10479000BA7F24A8A0FD877FD7C344479B3299DF07 -:1047A000EACC0A7F2B13E56508EF9FA5E518AC0757 -:1047B0005168D987E50DF85D4D953BB01C64F589CE -:1047C000AA9E13DE69BBCDD84E4EF5D383656F6AC2 -:1047D000DCAD386E2055DE86E54256FF5CC71976A3 -:1047E000FF4A52C2F97F2CEB99B06F7A7DCB5731DB -:1047F000BE7443CB4DF8EC6E556B204E67DC4372B4 -:10480000FD0D5F55C19FBEE1EBF7E1BEBED1FF429A -:10481000F03B80FF35B91EEC2567B1187EC43BC460 -:104820007F43707460B95166F7FC2F9C75B2A7C3C3 -:1048300014BF53E0EFA5437E8D66BA07830CC9C34E -:10484000EF09FAD399E741CFC3E749C8214ABF1F0F -:104850007B4BE331A4E75A351DDF18F31DA97F63B5 -:10486000BE23C91B036F297A2AE57F5FD716BF7461 -:104870004FACC3FC9F850287D3C7EF8BE4F51AE9E1 -:10488000387BCB912E34A0DB46EEDFD9F58331EEB9 -:10489000F784C8EB801F8813DF55391CBFE78A37C0 -:1048A000A3FFB19118817BB93CE504F7C5023E63D3 -:1048B0005F9DC9B56F7B8D720C934BC2A5BD28E778 -:1048C000DC9A21F7989E5433FA74B1828EB3F5CCFA -:1048D00095C18B200F3412848B0869F905B8E7392C -:1048E0005B6265123BF3C2A142D007EAC54288D29F -:1048F00043C7E72F1C2E22ECE822FEFDF4CF5F40D9 -:10490000FBC228C385BD65B4EC4995752548CB2508 -:10491000A9720CCA3BB9DD7766EBE72F74A03E0B9A -:104920007F6696AB355CAE9EAF3CFDFFDA45D4E9C1 -:1049300000800000000000001F8B08000000000045 -:10494000000BE57D0B7854D5B5F03E73E6956426F3 -:1049500099BC278190131E12157012480848DB0974 -:10496000AF862B8FC1074609304978846700AD4E6A -:104970009596810082628DAD0FBC2A0E16BDB6D50C -:10498000DE68E92D7F8BFC83A0424B3156AB684536 -:10499000A350A56A4D04B98E56CBBFD6DA7B67CE3D -:1049A000399909A1DAFFEFFF5DF874B3CFD9673FFA -:1049B000D67BAFB5F69EB367E1CFB7183B6B2A192C -:1049C0000B3396CBD80E6D8367FC28A879ADBE213A -:1049D0001A635BF05541BCDD051E3B63158C3D98A9 -:1049E000197479A09CBEA6CBEA8476CE921C77D0AF -:1049F000C558B1F79370357C5F3C8E310DBF1D9C5F -:104A0000C5D818E8D77BBD62CF817218F3288CDE39 -:104A1000ADF740FB1C3763ED50326B84B1618CDD28 -:104A2000E59275980F9481D208EB80E7A91A7F6F01 -:104A3000C13A3C571D6C651BD4D34A993F02758F10 -:104A400083CD0BE0F81E0BAD63844715A542F3CD73 -:104A5000F06E601AB477D658FC112833B074E9D7D9 -:104A6000BF81DA8DF058A994F0989213BCC8837076 -:104A700061ACA60DE7C5A281525847EA853959B7FE -:104A800042ADBAD47A3D83211F5ACB02F36D8C55C7 -:104A90007A0229081757594E6A7018D5CBF07BD780 -:104AA000464B98015CAA993BA294C4E102334F0D96 -:104AB000B893E3E395B5C1C0445BCFF7B29C758D65 -:104AC0001AD0AF439613110E308F8F6AFF7C0F2ED2 -:104AD00067B9B3CBCE06023E07DF19602AAE47A303 -:104AE000F7CE5D33A3FDE0FD8ADDAB18CE777D5AAE -:104AF000FA38C4A379DC57BEB8D71380F7299F3999 -:104B0000026D09C65B22E0FCF2DA5AFA0EBAD7ACA3 -:104B1000798CCDC3A50C6484D00E27964C39EBA0BC -:104B2000E5BD3C18DECF659C18AE0CD44F6300D7B2 -:104B3000865A95A925F85D777B7616EA733BEAA736 -:104B4000B2115009D94EE07327FC3D0BFD0659E622 -:104B5000640F3CAE0FF3E7D41EFE5BC07C9373E1A1 -:104B6000BBC6CDA6E76F4CF90B4BC7F7D6131DA5F7 -:104B7000F1FEAFAEAD0F4C14ED4ED3FF23B49E2B20 -:104B800035E647BC5DE94B8B8461895705AE094C1E -:104B90002C8DF7F7EA97EA3C848B191EBFEA86470B -:104BA000203071484F78340414BB473B375CFA0A15 -:104BB000877A6BD9E45CAD271CCCEB0788DD8E705F -:104BC0005E0070BEB524393CA01DE1E3D56BA01D8D -:104BD0002C65B23AD566013834CE54984321F8A6F4 -:104BE000B341D8CE3F75926EBE66389AE1D5F8349F -:104BF000F345A1DFC6BBDD3EA070F607099F280084 -:104C0000AD12E4096FAA5FE73B387F0FFCC5755E04 -:104C10005E55F66C0ECC23B841F131BEDE77F4EB75 -:104C20006B60818CA842EB7E2709DEDFD1AFD33CDD -:104C30003FF3FC53505881FC0BBD51F28303BA760D -:104C4000CC1A1D1618CED8E31E77CEBB69501FC1F3 -:104C50007C6781AFCEB0711923F1FDE01CE26F33A8 -:104C60005D7CBA56FBC1019B9ECF399DCD0BCDEC2F -:104C70001E17FB5758B0BBEE013807AE516FBF0A85 -:104C8000FEFDCAC1EC8DF86CB557D54E6423BC60EF -:104C9000BD842F3F6392BE1896E17D2AC06F2673B4 -:104CA0006A2EE8E75B20A4CEC25AA6FB5334976E67 -:104CB0001DA75A951A94A380BC8C2B87C7D76B9ECF -:104CC000F76AAF9DC6037AFC444F8F66B8BC523B6F -:104CD0002803E5C80B71B88C381FB84C42660678BB -:104CE00078B25954013C7729CEC8C330A7BAD0CD89 -:104CF000818923112E2C6C07D179C25342F251AE17 -:104D0000DBC6E49F950CE5699D9D05715D6FD858E4 -:104D1000ED932E2CA345E53AB9F55E76F50994D3CB -:104D2000B25E17FA3EF50F84487428E979AED315C0 -:104D300055391D7ED84D3724CFEA3CEF5E4C786262 -:104D400067619D6AC6320DD7ADA6A58F60198C6DBF -:104D5000C626B04E7B66A00BE5BF9A362082F4973C -:104D60007ACD8F37733CFEA866960E8F290B7E1185 -:104D7000A6CEB52C03FCD304FEAA05FE524A9D66BE -:104D8000FC31E4D370298B3CA2081040FDD4607F35 -:104D900004F93699DE90F84C29B57EDEA1A76BD6D2 -:104DA0004AF097786407467521BF06BD56762BBD3D -:104DB0002F25F8043D123E5D36D427F342B653FA50 -:104DC0007E8205F323EBF0BB2D0E1F3E6BB068799E -:104DD000D80EE0E4413DCE4A7D3EE41F1686EF2426 -:104DE0003D215CD198D0F5DF016B2828C7FE407AC1 -:104DF000E2779B75E30CEC396E375F99FB357DA745 -:104E0000AA603F901DE1F3F974F2BB2493DB0FA776 -:104E1000BCA3DA2C0393C3AFC199EDB766C7EBEF20 -:104E200014386B2309F480EC4FEAF32C35E8B5E035 -:104E3000DAC23B0F1E18877AD873114832769BED81 -:104E4000A183078B1892086385F8BF870EFA5D640B -:104E500077883A1026CC7F476A77DDEFF4427D6091 -:104E6000773D8CF5ED301C1B0B764BE6430737C0C6 -:104E7000F79F1E7390FE3A55931A41E6C90E4D6096 -:104E8000C761DE5630733280D4A00863E90CF5A305 -:104E9000F52856801CC03B5BF32908EFCB3335A2C5 -:104EA00007ABC6A26E985CB6D5A720BC7E68674DDE -:104EB000426E5C385367BF5C9EC9ED0E398EC3C924 -:104EC000C229E5F17E19F3AD433D629DCA48AF00AA -:104ED0009F93DD26F95BF6333793EBCF6EFE3C37BD -:104EE0003FCFCD4CC0CF872D2BDFFA1EDAB3BF5595 -:104EF000D923B09439DEEFD2F359A1462AAF092D58 -:104F0000A6B2498CF767166CC27EDA6B5F9A732380 -:104F1000D06FF32E870FD5F2F21BFEF2830A0DE15C -:104F20000478C7EF1634DE5D01EFED432C64CF6EDD -:104F30002E62B5484FF6750AD9475B347BCD2E28D3 -:104F4000EFCDA8BE2733373EAF7B3326529DD568C1 -:104F500016A4F3D54E4EE79F1EBBC5DB8076A5CBCE -:104F600045FC625F57728705EAEC10CC9BA1FC60A0 -:104F70006467A80E5E6ECEB4123D6D16F415167001 -:104F800077C610C99CAE57C2F84E6B98A19DED8CA8 -:104F900059E9B95D81F925A053D99F33064C3A12DE -:104FA000C7337F6FA7E7B82EFC5ECD6606BBE7CEA2 -:104FB0004C6E37DFD93D8F343E8F6C733FE9FCB9BF -:104FC000E03FF33C3EF04CB81BE17F6F86FF9E4C08 -:104FD000B2C33B6C28CFE7BA7E7B5419D11779DC7A -:104FE000A1A03C9EFE85122D06F8A554AB91F52597 -:104FF000A8D73CD346011DB06A9B0FE1D93E38C704 -:105000003D5037FE6302FF2F5A3D6E9C676012D8F9 -:10501000D544DF2CF74AEC67526325977F6070E92F -:10502000F4EC8BDACECD0351FE866DB45F9AE70CBB -:1050300047707E3ABB4D39CBE5B266AD8CDB7FF372 -:1050400026AAFE94F49EF61D6C430E90FD2765790A -:1050500018EAF0DD9BA2FAD6C4D357E1323A98C7DA -:105060003E506F0FE26EA912ED1BFE675EC868F737 -:1050700099EDC286AAB2E7000D009748CD28A4B3E7 -:105080000B2D44677DB59701D39C5E26B578705F84 -:10509000F5A09013D3271E9F887263069856D8EF09 -:1050A0008C89AA270AADB7862CCC0F133FE2572371 -:1050B0000AACED4869C7A16F21DCAA6C1AE9AD52B0 -:1050C00076FB1539F87EA407E11C107608B4E7FAE0 -:1050D000CDEB8C0C8167EDFEE3AE461DDD1DA93ADC -:1050E0007E21EE5740EE3525A227C6D6D1BC0EDC78 -:1050F000944AFDBC75971271C0FC27A95FFC7E34F1 -:10510000DAB3DFB3F91C1A2DCB82789DEA6362E330 -:10511000EA774DD2D901C759A092ECCAB263D50E35 -:10512000B45F372AC4A712FEF342467B33B812ECB1 -:1051300032ADA77D0A9DD9919EFB6A9F9AEDABCFB8 -:1051400033C1AE023A67E5AC5C6F5725D353D2AE9C -:10515000B232BF92457AA8C38A7A773A3C4824078C -:10516000AECD5008AF93D40F093FA7AA540DE175F7 -:1051700024F4BE0BF7E347BE50F93ED89F6BB0E373 -:10518000F2B3B85F60BB1D0C32F86E7BA133B20E78 -:10519000BADA77D345F91D841FEDDE7188C7DFDAEF -:1051A000480E279BAF3BA4B2C14098D3420A951248 -:1051B0007FC5A11466D5E987629678FEA5597CFE65 -:1051C000B96B9845837133C3CC9F687F2CDBC1BE1C -:1051D00078B29551FB6826CC6FC5600BD1A7DC1F58 -:1051E000A7D8C2FE7EB07EDB9E5561DC2717C3FCCC -:1051F000701E1ACC0FF56549288DEA0343D9540E69 -:105200000A65523938D48FDE0F090DA2F282500997 -:105210003D1F1ABA98EAA5A191545E182AA3F2A2DA -:10522000D0A5545E0C7A13DB0D0B5553393C741921 -:105230003D1F11BA82CA4B4233A9F48566D3FBB233 -:10524000502395E5A17A7A3E32B494EAA342D7512D -:10525000BD22B48ACACAD0CD548E0EB55059155A43 -:1052600047EDC6846EA3FAD8D08FA8BC34742795B6 -:10527000E342F7D37B69B7A40A7EBC4D9BEF417F25 -:105280000750B886749C8CEF1665713DF042A67F7E -:10529000465645BC9DDD027ADCD5B35D6316D76307 -:1052A0009988D704FDCDCDE2F2F923DF3BF70C65F9 -:1052B00071BC6DF1F6EECF60A589F71B71F9C0D70F -:1052C000373D4BA372BBB5DDAF22FDAE64BE303CB3 -:1052D0009A36EA4505E5CB0ECD5A93C8BEBB37CB0F -:1052E00046DF3D98195C81EB4C2B397100E5C98C88 -:1052F000B0E7F7E3915E86E5FC763CF457BCC1422B -:10530000DB7D8D79F6A17F4D9BC8482E4ABF12D810 -:1053100075067D7A87800B636D0707123F0D2EE7B8 -:10532000FAA7630AF297FDA681B47FDF6E8F2A5633 -:10533000B46F5633A6B7FFB76F6A7814DFC7FBB3F5 -:10534000D33C8B37B367D0C42E69D5C6A740396824 -:105350009BFF9914F8644824383E15EA431F0B3F1D -:1053600083E5856D91F169505EBC3BFA0C6EE38676 -:10537000473BC6BBA07EC941B61FD9BFAC5D9BE011 -:1053800086FAC8A3FEFD4006ACA22338215DC3F90E -:10539000445AD2613EDBDF04430FEA551FB6AAB080 -:1053A0001D8AE31FEC38B4DF245EDCA3DA2766C372 -:1053B0003FFB5FEF2953F17B6B474AE6B09EF8D97C -:1053C00081EBC675821E7904D6D5DF1F553C3A3A6B -:1053D000F98DE067C0C34328E7A45F72C7862CF24B -:1053E0004BEE48F554E3905D9398E7610DE9D84A98 -:1053F00070B26F1C48FE384977005F833D7B87A001 -:10540000BBEDDDF66E62F8FE46C8BF7F15F8FE5BA9 -:1054100016E78764F07522AD8C39371F1F167C099B -:105420007C7C50CFC7E6761F0B3899E1BCC3C20E17 -:1054300082AE8271814E395F31F4A37D28E8FB5C36 -:10544000707DF75F8C6EF70B39910CAE4CCB213928 -:1054500009F47A21FAC792C91BBBD8CF98DFFFADF8 -:10546000A79CE37E5B0FC8B941C9E5DCF302DF49C5 -:10547000E597903376937FC799CDF9A6D213B0679D -:105480005724F0537B730C7EEAA9AAA71AE50D1BDB -:10549000CAC88E4E1B1609E33EA538AC95ABD80C96 -:1054A0008532C2B1B094FC0F2560675801FFD0551A -:1054B000144BA7E6B134A0FF5DF29BA7DEABE73744 -:1054C000A9EFE3FC28E9226BC7ADDC2FA9CD04FBD3 -:1054D000E5DBD9C2AFDFDD0FF7836CFA6EE18E5BDF -:1054E00075727087D74B75D93E19FD2E10EF776C0A -:1054F000584FF0748E4B6C375467F3B8C2767B9775 -:105500001FE93CFC4DE6417B2673C33B249F32419F -:105510003E29249FF8F8FD43A98F86A1EECFCE1334 -:105520007E004FEA2CF7FF3B7ACE459B0AE5D43844 -:10553000CF3E15E334A08734E4D37130F751082F00 -:105540003BE15D631C8FDA381641BB17E016C57D61 -:105550007BD8E2263F93DDDEEA477E66F64C5A7F33 -:10556000A5273823BB17BEF0A4696588D46076DB15 -:105570001417D0DFA6124F2AD6E7407D6B158C9BFF -:10558000D5C1447D8B6BCC3FEEF708FEE8E787364C -:10559000C078FBB2FC73919E81AE8358FA877AACD7 -:1055A000E4AFF6F6CD1E90FC19E7274F99E4A7FA71 -:1055B00061240F9760BFB2BF64F6CDE06C2EE76E3A -:1055C000166532FB46D2FD79DB3762BE8BB37BE7D3 -:1055D000FF570EFE68DB4EA6F33716DED36ED5D02E -:1055E0009FC1FD3416673BF5E716FE463FFA1B8167 -:1055F0000E9C83791DFF24F21727876384E623FD21 -:105600008CD29F982EE88A599508EAF1F42A8FB532 -:1056100081FAEB6097437FDBB2B9BE917C8D72EB70 -:10562000A9612897B2ACB85F477F923B2BDE3FD68B -:1056300033CAE3F289897DDC7562CEADEB7D19E872 -:10564000720E1FE17E94D6EF73BE9CD69F45D6A303 -:105650009CF033CD03ED5398FCE337F893A77EAE6F -:1056600000EF821EFC5CA55219CCA26ED8EF4DF360 -:105670002951DC07DA2DCE08EAD2EA4227C3F8A680 -:105680003DDD12C1F888FD1D85D6692F4F8BA0F036 -:105690009B5858958171CCD387F7BB8209F07F75F1 -:1056A000B0DEE0FF32C3B1BBDD9C673D08C7FBCF76 -:1056B00011A77D3EBB3B4EBB0FF972FAFCAE0D76D7 -:1056C0002D1EA795F1C702EFAE2DD5A8B29671FB9E -:1056D000B49045D6E9ED2A5D1CF477D8CFFDF138BA -:1056E00068FB05FA386873E11EB477EFEB8E83062A -:1056F000F712DF65B79521FDDEEFDBF5933B109EDA -:105700000E11AF1879CCA5A19FBE627F2EAEE7F730 -:10571000A6F9CB52FAF1CCFBE03F651BE30BA77D6A -:1057200057644489B6B213F2B7F42FCAFD30FA0FAA -:105730003D09F9D0086F397E9DC2F7B5CCA670F946 -:1057400027F428C897BF921C8830D29B7E87F230FE -:10575000EA9BD3BE913E8A7B269137723E00C721D9 -:1057600089E2BF305EC238AB2387EBA93A1BF79BB7 -:105770002AAB2A56E2BCEADC2EC5A1F3F79F16FA43 -:10578000CC1C175233BEA8080ABF77A2F59BE33B97 -:10579000A7515FE47278E9FDE4E782D7515B2BC53E -:1057A0000F8F2E50D93AEC27383A9F25F85E96AFE6 -:1057B00023DD0C61EC18C2B84287CF24F1A2A36BA1 -:1057C0009B28CE6C8EA775BFAF4FA945FD5D8B7032 -:1057D000D48D5B25E0375394CC11D43CF0DEDE70E1 -:1057E000B78761FC6BC827156137FAC5BA7E89F1A6 -:1057F0000BF63D37F92B6AEBCF54AC1BAE83671524 -:10580000E3F1D9FDF77934785E3B64436ED8951C9B -:105810008E3373381C6FC30763C81F333287FB375F -:10582000FBE48F61C3785C88ED4FA1F869CA1F550E -:105830001FDA0D382ED703DC9F7CBD889B98E37858 -:10584000B5A11506F9921653584417BF48B3B6913F -:105850007F362D66A5E7667ECBCD31F29B847F3205 -:105860007C4AF89B9FFB72F87A8ED62FD6D06F6851 -:105870004F4D6C07DF22DAC9BA391F2159DC7DBED2 -:10588000C0EBE9E0987CF457D5DAC343FAC2E712DB -:105890003EE7CA739893C3F5B8FB9A97441C4FDD53 -:1058A00080BD49BD9A66ED3D1EEB37C563D346F515 -:1058B00088E7FD53E2B1EB7284DFF03CE3B15304BF -:1058C000DD9E2B0FE56ABBD1EE91E52C81C7D3C1DC -:1058D000141606F9785DB54A7128A00FD28F47EFEC -:1058E00056C8DE8CD63B482F37D6A7907FB6B14C32 -:1058F000A5F78DB7ABA43FA3201F96817CF8BD9080 -:105900001366FF6C35530CF1F3E9A3520CF56B16DB -:10591000FCE8F76BD1BF5C65D370BC231AF73787FF -:10592000FD2AD9AFD0872F8AFEE9BBBEE1437D2691 -:10593000E9E1885F257E0BBFACFA70D876E18F3E37 -:10594000B2B92C82792A4C89C7E9B541D87F23C5E1 -:10595000815FF36EA33867CA97F70602B47F0C6ABB -:1059600065A43779FC3445F0E984C2AA59A8C7DF99 -:10597000DA6A63E8377A6BCD69E2E78EB52B292FB7 -:1059800042FA97A57FD8EC6736FB977BF8954DFEDA -:10599000E464F90CCF26A10F29AF92D10788ADC3DB -:1059A000FF881C93F2E375B1CE0985DB6E5F07704B -:1059B000489BAF121C245DBEF6C52D0FA21C4E01E4 -:1059C000FA58CF109EFFF12CEE43D86225A11FD9C3 -:1059D0002DE53AE64F94C6F1724D7071771DD97F6F -:1059E00076D32A43DE8759AF24976BBDCBAD3B728C -:1059F000B8BFC2AC77CCFCF075EB9DDAFABB4BF1CB -:105A0000FBDAFA05112CB7143A9B50FE9AE583593C -:105A10004FCC32C9D9B87E505964A47EDE1AB58BFA -:105A2000EB093BBDFF3485E73B849CBCBC3135FDB5 -:105A3000612C3F4DE1F90E61340AD14E7D332DD2F8 -:105A400042FBF295A3914E42CCD711C6757A53C949 -:105A50008FD0DA9FB753A7A472BBFC4035AD5795E2 -:105A600086F9866AE29B16B19607B28345B980E74C -:105A700016BF2505E30B13DCD643E87A691D6F6179 -:105A80000E1687573C2F847914F89EDE29B8FF2C18 -:105A900073DA07919D3A2417F1F17DD81F02DD1FBB -:105AA0003EACEEDA014B3DEC1B9991C84EEFD603AC -:105AB000A638F2B1EFBC3A00F9F6CF2CE8CBA5F846 -:105AC00071E3ED181F6EDEAD527C69CE0DAF5D4007 -:105AD00076B7294EA9A63B4BD19FD2A2A4FA509EDD -:105AE0004838EE73DB49CEB41C4BA3FD44CBDB8AB4 -:105AF000A8BB491E4AB81F807605A33057C94D720E -:105B000053C21FD6E5C775493C54B3E8E171255F20 -:105B1000695D97F5BEAEFE1EB20F90CED4F83A5432 -:105B2000B795D6D7C9527D38BF90F00FB137D2683C -:105B3000FF27F1DC2CE851E27985C073E79E333F03 -:105B4000B814DAB7FAB328EAA016318243E71B6E1D -:105B5000A2130907B96EA08B20CE53AE7BFF9E9196 -:105B60004783F87D7A2AC5F1A5DD2DF30ECCEBAF86 -:105B700013FBF7A5B94AB7DD8BFE8BF6ECF14B733F -:105B80002B12B417F62EC07B05C2BBDAC33E89B018 -:105B9000F83E2F597EC34DB946BEEB437EC34DB987 -:105BA000B93DC7FD0AF8DC88FDF5159FCD56D766CF -:105BB00025230E6FB96F2696D67AF2BF99FF243E41 -:105BC000943DFB3EC338BE592EDCA8AE640A8CB3AC -:105BD0006938E74BB68669941F64E29773C91BC0A6 -:105BE0007F04F1944CEEF415FF3FEB89FF9FF5869F -:105BF000FFD6ECC013084F1CAA5F39ED0BFF13DB77 -:105C0000A33CB10FA4F1886EBB3219E5B3C9FC18EF -:105C1000391F9927B317935673757938A53E05F543 -:105C2000441FE863AF7E7E5F037D1CEA9DDFA3C453 -:105C3000A7CB05FE97CBBC8C5DBDE765F4017F4724 -:105C400013E1EF46D5D7152CE93BFE8EF7C4DFF103 -:105C5000DEF1177C17F1D762679F90FD5E55EF4527 -:105C60007AA9F4F82FC77C9DBDEB84DC2901FC9553 -:105C7000A0BDA4925CFB21BB88E4F6372D169A6F79 -:105C800027C8EB87953EADF3BF73C94E095BB3A040 -:105C9000DF1BAF6014DFF36AEB14ACE76BA0A7B5B2 -:105CA000BEAF57C9EBB15E25AF777965CDCB25FA8D -:105CB000BC1EE9D3A979ACBDC92B4FDE79CB2B4FE4 -:105CC000DED72BAFFAE59D875EED03FC87E0FC9203 -:105CD000C989BEE681029FB27E593DC7879D2EC508 -:105CE000D5AAD39D5C6F3FA9083D5E16A4BADB49D7 -:105CF000C2E280D0F3A776F1F7EAF8C476E588BC73 -:105D00002C9EAFD0B62A6035E49384E9F91DFE538A -:105D10009EC12AE669BB683DD9D3B81F52AE5FE683 -:105D200069A78BF56417F175671FE379ED125EE9DA -:105D300062BF91516535EC2324DC6E54030AFAD11D -:105D4000337318A649C03E6198827EAE4CBFB1BD88 -:105D500084772EDBFAB18A295F35C6F7B9B89F1967 -:105D600081EF75CF13EC5F013FA5983F764D9EF014 -:105D70003FD89917F51153EB7AA523DDFE249847F8 -:105D80007197DEF7270BF364BCDDA8F7DA525842AF -:105D90003FC327821FC05E217FB32AF4DCC48E126A -:105DA000CA7759EDD6C8FFA0AA3EE7D4929EDF6716 -:105DB000FA81BD75F0C8AE49659ADEDF12C832D4EB -:105DC000F36B0B0DED0B82030DEFFB355D64785F1C -:105DD000B4B2DC502F0E8D35B42F01C0EAEB833600 -:105DE000FF9BA1FD90D6CB0DF5A1DBAE35B4BF3046 -:105DF000D260787FF1634B0CEF87B7AD36D42FD9E3 -:105E00007D93A17D8BF0239BE1F2AB3CBE7F6BB118 -:105E10007239B4CE554EFECD1697D1BF79A7807F8B -:105E200075C6B852F4ABB7BC53568AF03E903E9656 -:105E3000FCECC9E8C22CD792C953F3F33631DE47E4 -:105E4000CFD82D48D72BF603DF5E0275D7EB9B70BA -:105E50004D5B86F1F8AC8DF17C2119AF91DF77C7EE -:105E60006BAC3EEEAF4D77B15B13D0C59D799A51C7 -:105E7000CE0AB929E92819DC243D9E0B6EBB057CAE -:105E8000BF2ADCDE5078BEAB5E1F3C99605E1FE728 -:105E900059447C39F8873C6E0F8D4A254BDE43FC14 -:105EA00078BEFA40CE03F4C131AE0F8C79BA1FD55B -:105EB000BEB4F05E0DDB2FE4ED2DBE52C44B327F3D -:105EC000FAC7026E3A7F7A13F7A7A71AE0F696E4AC -:105ED00077935FAF25FD73F2A7B7D87DA57DF1A7B6 -:105EE000BF05DF22FC77E771FAE8C6AFF0C727DB12 -:105EF0004785183B84E72198CBAAE9F74DC9F6C737 -:105F0000529EC3FEB814E3B4ADB8FF5212EA414743 -:105F10007E05ED9F491FB4821E74909F801DD2A004 -:105F20007EE3040BBB558BAF5BDAF30EE673DA55F9 -:105F3000C2AB1BBF67DF67D7A7A85FCB3ED39BDF92 -:105F4000EBBEC4AC67CF19EF233B6D1AAC7FBD6EBF -:105F50007F2DE1638EEF49F84CF3F1F8DD46D08FE9 -:105F600018DFDB97CBF5F446D87F231C3DD901EF32 -:105F700000B4E7E1F9C3888EDC4AE21F0957739C3D -:105F8000AFAF72676C7E0F3B6E6C7E2F769C5CFFB2 -:105F90006AB17F9EA40E6B433FE6A9989DE0A632AE -:105FA0009E77D97CD0C62284479EBF2CF1688B6D2A -:105FB0006A47FD6C63E67C652D03D76F3BC8CF89CC -:105FC000B11CFE3ECC9CEBD0EEC9A832EAAF4CBF70 -:105FD000517F65D76499F499517FE5D71AF55741F8 -:105FE000D0A8BFFA35959BF499517F1587C69BF4CD -:105FF00099517F0DDA7CB9499F19F5D7D06D46FDCF -:106000007561C4A8BF2E7E6CB5499F19F5D725BB15 -:10601000D71BDE97456F35BC1F79F087867A45FB25 -:10602000BF1BDA2F3AF40BCAEB197DF46143BB3185 -:106030001D3F35B40380B763FEF77C420963979E2A -:106040007CCAF07EBEB0D7BED1F56B433FAC95E7BE -:106050007187E12FE2EB3D16B4A39162655DCFF548 -:1060600003BCAE8828BE28345BBCFBC94A9CC7076A -:106070006F4E3988FD2CDA66CCFF5E1C31D69BD979 -:10608000C00C940BCD401711A093A59817AE936F39 -:106090004BD94A712EB06F74B6E8D0158CF249C353 -:1060A000FE76CC7B97EB94F4E617F426E727D7BB74 -:1060B00014ECBFA8165FA71FFEF2FD66871DE976E8 -:1060C000E16E85FDBBD2733D4D7BEEDCD42FC1BAB2 -:1060D000CCEB30DBA13FC937FAC727A92E8A179C22 -:1060E0007A59F5717FA3910F571FE27182D54F281E -:1060F000E4AF33C343DAA7C9E0A286F9BEA139876A -:1061000045223AFED3043C1C5E23FF9DC27FE07C07 -:106110001E5023986F94A2A59AE9AD32CA7AC2396B -:10612000ADD4C8A76638BB7D8509E94A83BF388FDF -:1061300085E2FCA199AECC705FB1FB4E3BCAC3F3C4 -:1061400085FBD1FCC47109D076A3EC09F2EB245C89 -:1061500061DFFE26CACD64FBD9F7F395F33D5FF40A -:10616000BE5E0E7F0DFBD933BDE9B94EF4B7817D1C -:1061700069F6B399F5B0B267FF674A3AF9B53B1CC7 -:10618000C877419F93E7C198F46469A9414F76EFBE -:106190007BDF5168DFBB2BC36FF5C2FA0E65F86D6C -:1061A0005EB48732FC76AFCE0E6D01B8D0B91FD089 -:1061B000534F26B013C77BA57D1420BFC9C66ADE26 -:1061C000DEDCEE222F3F27B42FB7D24BF6E7DB659C -:1061D0005EB23FDD95BDDA9F778838D16D18871C98 -:1061E00012CF0FBA5DC46B80EDFC88B78DB68057B7 -:1061F0009F3FECF666D2BCD2C73CD58E79D42D1E1B -:106200008B47D1B0E4F9DC1B5CD69A9DE2BB1CC382 -:10621000777C9E2AC21BE06A75593FD7D3ED782F51 -:10622000A3F7C9D639DECBED5E1B0BDE8EF6908C64 -:106230000FDBDEA976A2BC6B617E0F97933E8F3E8B -:10624000FFC3C6783C78BC880FCBE7AAE71FCBC357 -:106250003A9211AC463C9AF3B06ECCF08FC7E7216E -:106260006BD8817667C899785F5C23F0AA8AF5823B -:10627000014A7445F350CF3FFE03F6E61538EE8D24 -:106280006A98F2245BDC95A54157DFFD5C73BD9CE9 -:106290006F75F6D15C3D9D9AF913ECD3CBF11C9947 -:1062A0003FA3D04ADB0EABAF14E1BD19FF3D86FC26 -:1062B000B40BF0FB1E79AFE21C2EECE37ACDE39534 -:1062C000FDECCBF22FF3F27CC3155E9E6FB841D587 -:1062D000F5937E8E7EA49FA30F7EAB35DEC4FED1E8 -:1062E00093A8DFFB0AC75BBC3DECCC5BBCBDD89977 -:1062F0009F1E1B9A81F16CE9EF32B793E722657D0F -:1063000073A671FC4DE5BCFE4381BF3F8A7B3A1EFC -:1063100015F3709ACE8B3AA732BAA7439E3395FDF8 -:106320003CEA7553FBB5D9E31FC5F96E2A51681FC6 -:10633000BA295331EC47EBBDD58F225E23A2FF472C -:1063400005FDEE18C8FD39E63CCC25D8BE024BDE73 -:106350002F9E6B45396657D58470FC9997FB8B2E21 -:10636000878EB07FE9776BBC5B11FB27E3BD08C06C -:10637000E7AFA481FC39BED546E75E17A8AE4D480D -:106380008FC9EE39A81F16A0FCA7AF7A7E0CE19941 -:1063900096D553AFEEF776EB55DF799E23FBADF73D -:1063A0003CE2FD1DA99C4EBBDC2EF29B9BDB9D10AD -:1063B000F8D92AFC1A28D751BF64A96C65223D730D -:1063C00042C8D57FFC5C33BFCF23DBE5A2EFCCE72F -:1063D0009A3BEC1D1BF371BEDF507C787E21BFCE53 -:1063E000B32F3F07CF316AE4E3DB54C2D2ABF07D79 -:1063F0009985DE675EE9D964C3BC6F8D61E63EB303 -:10640000C1386E18C755C0E3385BC357ECCB8776ED -:10641000195A171B388CCE7B4FF622DFD6F2FC7947 -:10642000F3FABE14FCE1DA08FB0B848796380FFD03 -:106430004B417F206FBE403AAFD6D82E7E2E8BE7E1 -:10644000C1225952BEA28FE76BA761BED3202E6F27 -:1064500048DF644DB014E4C6F94B15F0369FE7767B -:10646000159CDF79EE197589E73BB480AFEB4F19C6 -:10647000812C1C77C6B875DC1FF6C5D9B36A251AFE -:10648000C79C4FE07B86FE8A941C2E8753348DE494 -:1064900032F32894E7EAD47C4D584F718DF5A86803 -:1064A000273B785C92CDB730BC5F6582E8C75FCB95 -:1064B00094774BB95F96CB592B7B57D2BF2A805329 -:1064C000897A96FF01FB696B1AAC6782EB30C527AE -:1064D0005306AFACC6730DCFCEE37DFC30C9B90116 -:1064E00079DEBDFB5C3F7BF8B0E15CFFC6070E1BAD -:1064F000CEF5871F38FC55CEF54FBCEF81C3FFCCDE -:1065000073FD529E1D5583476F06F85F0544152A9B -:10651000C7D2CAEA08DF5E82DB9502CEE1CF01CEA8 -:10652000CE389CAFDA7388E077D406F386F16DE35A -:1065300039A86D3765445A482E4668DC59CED6498D -:10654000B8EFECB4778DC0713B9F7EB5280CF2E4B8 -:10655000D8F74EBB19D0DF5BD62E373E3FB9E625C4 -:1065600037C2EBD81A95EC353A17ADCB475A28E825 -:10657000EAD982C01CA4AB796BBFACD4DBE32C940A -:106580004BFA777144A5D42B29FF963E9626888E28 -:10659000D797B7651BEA522F2F77243EA7FE6001DD -:1065A00097438B1FDF61EFA7E1F8C1E60298C74967 -:1065B00091DF7072979BF661723E0D8F97D971DFF4 -:1065C000F9D61E078B921FB8DDC6C89FE59FAAE4C7 -:1065D000E13D46FC8F799ECFED4DA3FE16DCAD92DA -:1065E000DFA91EC60A015C837B16F37DB0691D0B13 -:1065F0008E6993515E2DD8A2B0B0C6DBAFC1FB331C -:1066000042B7501CC6BC4EB37E5994E4FE9C457BF9 -:106610006EA3EFE733FF6D68CF2E6835BF9FF21E84 -:1066200012F9A273C4737E5820F44E251B7D761098 -:10663000C58F32866BE7D63B27D772267D7FAD9319 -:10664000CA0FD77AA89C53A0111E96EEDEF75C3FC6 -:1066500062F3F64AD44BAF1C6C4CBB568BDBDD951A -:106660003BAEDB7F3F91BC313FB34EC07DB4C8CB66 -:106670005C24CE3D541CED3D2FB30EE131A2E77CEE -:10668000A59D5D67F2FB4ABBDB0C8F530727A42156 -:106690007DFC52C26534C045FDEA7049F6DD729555 -:1066A000DF9B667E2EF9688EA0EBF93B676E2A842D -:1066B000F15B9E7E6F4007D129F75F54087855B88B -:1066C00036B5E3FA2B98C96F18662F331D3D033D8D -:1066D000A9A877CC742BE989BDCCBF770ABF463710 -:1066E000BDEEB99DE02BE90A4F3A58D0866351AF11 -:1066F000A5EADCF75C2D6835D63FB2750C4079B25F -:10670000C8E46FF84849BC7F7BBE60202D76BEE6AA -:106710009F8CF9170B586013F7CFF3FB714E5A5B40 -:106720009FBB19F97C27E7B3E5BF7AE2BF507E2D06 -:10673000F9CFBBD3517EFDC5DA9A87E32D7B646325 -:10674000BA1FE598359C8EDFFF25A2263C473CB852 -:106750005091F9FA2ECC535B41A406FFCD0F4F4761 -:10676000F9F9DF8FD83CE8876D7ECC1175003C5677 -:10677000ECE27084FADBBC7E0BC1AB79B7912F974A -:10678000FCC7DD791AF903C2FD04FCFAA1085FB168 -:10679000D34679AD2B5E567D384C33EBA2F599BFCD -:1067A000C779C4006FCD6D6ABD3DA3E77BB084ECB3 -:1067B000C86FCDBB383E9B77717C359BECD02621D2 -:1067C000B7CDF49F5328E2BA82EE013EE45793F925 -:1067D000B62CC2E577CB4FEE1DF136CCEFC39DBF93 -:1067E0004B5786C5E99F615628C0ED545BE33C7B5F -:1067F0002FF7F57C24F8A45B2F083DA4ED8689E5EE -:1068000043750F2F97D9A2E997025C96EDB0F9C2B4 -:10681000F078D913AADF8576D46B0EBA7F62E913BC -:10682000CFBE3216E6B7F4495BCE54BE0C17CA6F22 -:1068300089AF66A4F3F2387E96FCE2593BE669E242 -:10684000F33559713C2D7D729F1DF33ECDF09CD0E8 -:10685000B6CFCEF9CD84AFB6B727A3DE6EF9C9A700 -:1068600076A487BFEC55587E49CFEF9B763C9B8E34 -:106870007206E184FA45E2AD1B8F3DF0179DFEEBF9 -:1068800051D4CE83719E73E1F1133C835041F4FEE9 -:10689000F35FC33C9A5E77F8100E4D3FBF2E1DD7B5 -:1068A000F39E7525A7FB0737E6A1DE6EB285F33CA4 -:1068B00054F2E74DDBBF43F4B8E8C5EFF0FB9C981A -:1068C000BF00F919D65B80EB5CF0C055B4CE852CC7 -:1068D00048F4D8F420BFDFF08C95D524DA0F3C249F -:1068E000F8E6BD871DB47978CFCEF87D217F50C5FD -:1068F0007D58ABC85EF98E58334868AA9F71727C88 -:10690000AD2E94717F2EDF9A45ABE69DB7907C7BD0 -:10691000BFC89F8FFC0F7030FA675F9C942FE422F2 -:10692000DDEB42DF01FD4DC0E7D8BEDDE64F19616A -:10693000F84EE4DFF2F1AF17E3C3BC53D1CFF75EFB -:106940009E719F2BCB2385D2AFC6DA999ECE92C97A -:10695000819D5B88BE3E7999CB9915919935F4BE9E -:10696000DD16CDC7F7917D572A2427C00E49C4E70D -:106970003B6D82CF8DEF619E56450FDFBDFCFC9EC7 -:10698000A4978577417B1D5FC7E9C71E7F5E12E72D -:106990005799BFB1C864CFC9D22C27EE33C909F9C2 -:1069A0003D7B2037E1F988B87C0813FC96D9228F0B -:1069B000FE3BF2F56B0E3A17B9EC091BDDEFF3C1A4 -:1069C000E3FB5FB916E8FF8336C9CF46F96BE6E70C -:1069D000A6A7AE6289F8F9839C004BC8CFF03C2192 -:1069E0003FE7F0F306FFB7E4EFA224F2F740614F70 -:1069F000BBE352A8BEFFD3A5C5B43F33C157C2D530 -:106A00002C4F67A3B190DB539EC29F97990E9E12A5 -:106A10008E924E97FC6C398DD34DCF925E253D778B -:106A2000D3AB79DD46789ADFDF827BA7DC38FE6D59 -:106A3000EB615F8EF1DAA755CACFEBD4BAD2B3605F -:106A4000DC8D22BFA7D323EA99BCDE956BDF84F2ED -:106A5000443EEF4AE1F90E9D81AEF44CDD7EE0ED5F -:106A60003D6A3A9E07E88824CECBA08C0DF483249F -:106A7000C9DB90E77E3B53B9BFAF3395FBF926A93D -:106A8000AE0121DCDFB5F2F8D2FC7557A7E3FEBEFC -:106A900073CFA019B5B81F38A4F29CA3B0DF5A0079 -:106AA000F06DE44B672759F89E7168BFEF593A15AE -:106AB000FB99BFD5089785AE9D76ECE70C5B43E567 -:106AC000C2BB6C713A81FF9660BE16D2F903A6E78D -:106AD0007B2E23BA5A62A2AB20D25582F32419FD31 -:106AE000045D95B132BEDF16F13121F726A9C366E8 -:106AF000D4623EE5417EDEE3D41E956DC2F53E2EA6 -:106B0000E265E15CA2D71540DF7ABFE987487743A9 -:106B100093EBF90F7F79ACF26668B2ECBFFE34E21A -:106B20007E283FFCAFD72EF80DD67FF5EA803FB127 -:106B30009EED27ECFD6C2EE575EE75D0BDA69D7B18 -:106B40009F1F7033D67FEDA0FB453BD7F37D767852 -:106B5000AF9BF47F6711B7175B9EFE744407E92F64 -:106B60007E6FF0D87EFCBCEDA93D7F7B53C17CBE1F -:106B70003DB02A948F62FFD6FCEB14DAA7773EFD76 -:106B8000A9617FFA55D7B3429CBBEA74B35A3C273C -:106B9000DD99C9CFA936FF66CC8FF1DCE5F25DFB4C -:106BA000EC8DF07EC2FFFE7204CAA1CEA7B8DD0153 -:106BB000F6F076E6033CF46BBDDD06F8FB086D44A9 -:106BC000E09937FBB54FC3F3243DE1C2E1D0097032 -:106BD000C075015C9A507E268347DDBF2C3C3E9EEB -:106BE0008BE32FDB339AEE198EC345F1F3E76ECAC0 -:106BF000F780F5F3E77B3F1D8176D4B9D67B533F11 -:106C00007EEEE77FCA7AB7FDCBAE97D3BB864E99AF -:106C10008A9E74DF93AE7F7503D57FEEF6D17CFB41 -:106C2000C8EFBBFF87D1F72BFFDFE2FB90C0B7DBDC -:106C3000837199CEA7BF1CC0CE63DD67FE65F1DC12 -:106C4000FBBABBED1E8BCF390AE6F73A8B5C55AD2C -:106C500024CF1F1DD85FFA1FF83E43DEC33D3D67BA -:106C600021D911D3FDDC1FD3C2CA0FE239BBB05FFB -:106C7000A5F80525EF001CDAAF2C8B509E98353C0B -:106C8000E41ECC1B9BB5DCC7EF2B33EEBFA6E7D5CC -:106C9000D4A03D77641DCC0BDA1D715B3C2DB08414 -:106CA000197E95EC3F28C9EEFBE3F8CB280F65462B -:106CB00095711F72AD693F7175ADF1FD2CF6702EA7 -:106CC000E6FBCD6AB2517ED255E6FD477F0FADF3AC -:106CD0006AB67223F7E79C1F9C2EEFCFF7633DE166 -:106CE000D03BDC7AC049EC37297748EB093747902D -:106CF000EF3F1DF042D85B222F6F759FE0C9C4BEE5 -:106D0000D4218696F075F8F9BDA3BA7E092E12EE4D -:106D1000E70B6F892733DC257C25DCCC781882E7EC -:106D20003D2BE2F08F97C67BB599B01BA777DB8D23 -:106D30002E82E30B3BF9798917AA1AB79661FD7188 -:106D40007E1FFC9971239913D67BC4C676535CC809 -:106D5000EFD73C95F1FC19A5EA798A4F60FEA27E37 -:106D6000BF8AF98BFA7561FEA2BE8EF98BFAF6988E -:106D7000BFA87F8FF98BFAF798BFA8AF63FEA2BEBA -:106D80003DE62FEAEB98BFA86F8FF98BFA3AE62F12 -:106D9000EADB63FEA2FE3DE62FEADF63FEA2BE8EC3 -:106DA000F98BFAF698BFA87F8FF98BFAF798BFA8EE -:106DB000AF63FEA2BE3DE62DEADF63DEA2FE3DE646 -:106DC00029EAEB989FA86FFFADD833867A35FB9DF3 -:106DD000A1FD04E74B86FA24CF9F0CEDBFED3D6E7D -:106DE000783F45FBC0F05EE2FFB2D2D386E718FBE6 -:106DF0000857E23E86FF99E6FB9BA11F2B0B509C98 -:106E0000D4CE5652E9447F2F94A9AC8D4A17B0399D -:106E100096EF0D0D3EDE1FE9757B781312D7913189 -:106E20009F0E40F9FFC2B82BB85F42C41766E03F1F -:106E30003520E2B42FFAE33E57C64FD3632A8B8E38 -:106E4000043A8C29547A62692C9A0D74184BA13239 -:106E50002B964DCFB3639954E6C4FAD1F3DC5801B5 -:106E60009579B14154E6C74AA8F4C62EA6B2207659 -:106E7000219585B191F45DBF581995FD6397D2F3C3 -:106E8000A2D8182A07C426D0F3E25835955AEC3216 -:106E90002A4B6253A81C18BB82DA0D8ACDA47270EB -:106EA0006C363D1F12BB86CA0B628D540E8DD553B6 -:106EB000591A5B4AE585B1C5545E14BB8EBEBB381A -:106EC000B68ACA61B19BE9F9F0D877A91C116BA108 -:106ED000F292D83A2A7DB1DBA85D596C0B95E5B1E9 -:106EE0001FD1F391B13BA91C15BB9F9E57C4EEA3C4 -:106EF000B232F6632A47C776505915FB199563627B -:106F00003FA1726CEC17F4DDA5B127A91C17FB0D8E -:106F10003DFF46EC7F51F9CDD87E7AFEADD83E2AB2 -:106F2000FDB1DFD1F3EAD8212AC7C75EA2E7136219 -:106F30002F523931F6277A3E29F61A959363C7A95D -:106F4000FC76EC6D2A6B621F503925F6172AFF2D4F -:106F5000769ABEBB2CF6319553637FA3E7D3629F2D -:106F600051D9BDFF1F97F477052C6771FFECCAEA72 -:106F7000D37D6577A6A5935C9CBE86CBC57BD33EAF -:106F80003A4072728C437390F0DB668877D18F48F9 -:106F9000C0BE6FDF98F7FAA3BDB3A9FAF81BD7A15B -:106FA0003E5BE560429F99E4EE172EE1EF64988F17 -:106FB0003847D0F50B55FB73D18EDA54DEB10CFD9A -:106FC00026B79774D4615950C4ED098F28F38B7894 -:106FD0005CE9EF43B9FEAD5B3584FFBE404EDFD6C2 -:106FE000374BE8EDEEF6033C5C5FB8BA06D079BDEE -:106FF0003EF6D3D776E7CAC3FA5BFFE0F0A2047986 -:1070000058F1F3837DEEA7F26BEAE75B7DE9E72DAC -:1070100081F7878A02138A101E56FF087C3F7E7D07 -:10702000818ABFAB52BF55F120BD346E289B8C784E -:107030002D677EF24BCE49924FB658E0B561A58DD3 -:10704000A17FB24163E41F6ED8C5F390D19F3A0D82 -:10705000E8A549D0CBF22D1F93DFA969E5229EF761 -:1070600014E1FE29F93B364B5B773C876EBD33EC70 -:1070700030E5C72F7DCCE8BF6A16FEA9E56DA6E70F -:107080002BBF9DD0EF69F64B3514093FB28FE73D1A -:1070900031B53FADFB0CAC1BF3498237B89DA83727 -:1070A000001E14879170907E4F090FD6F3DC05E522 -:1070B000AF9E3A3884F2E44E695A3EB60BA6F3DF2F -:1070C000B352ACC1D1F81CE048F92C5DEBD2281FBB -:1070D000EA6DD0031A265E7982A3F1FEB88ED78BB3 -:1070E00098B8BFD2188F706EA53CF17A9803E6A5C8 -:1070F000D43F924DE736A1BF11BBD1AFF9888DF2D5 -:1071000091C26CB59755F58C570436DA882E1A76ED -:1071100067F2FCB4B0FF653C5720F1F2F68641936C -:1071200031AFA961734919B9EB76DBC83E94715947 -:1071300089AF9EF9DB3C5FA099453661EA12E0EB2E -:1071400044427CB5EE23BC02DE4E24C1DB89DEF076 -:10715000765F91F027FA64BEDAB08CABF1E59A6CF9 -:10716000E2E7BAF5D1212B75F469F6FFB3F963E9CB -:10717000DE1399FF5C53287F67CC9787F83DBDB538 -:1071800082F066C657CDDF1B092FEC7537DD3B3C1F -:1071900067109B77393C9F27FC9E735AA690FDFD94 -:1071A0005411DF17BCB016733F197B71AD93F9C151 -:1071B000F87E69AD87EA7F5CEBA5FAAB6B352A5F99 -:1071C0005B5B4AE5093BCF2B92FC058440F97DBB14 -:1071D000055FED2E92F19FEBBDE8E7AEF9FB4B1595 -:1071E00016127DC7A64F2A22BBDD902F527BA531F8 -:1071F0001FA4C326F2CDB6283EBC4FA62170A9A17C -:107200003D2B1D19AFA3FE11F92B0D9B33E91EBBBE -:107210006BA6661BDACFDADCCF506F2FD2F87D6A0F -:1072200035830CCFAFADBBD850AF17BF1FC1B42A49 -:10723000E21B19FF02CDCDF1E2E16D3F59393AFF72 -:107240004618FF93C3367A6FC6C7097B98F6F3E1F9 -:10725000871D3E8CEF9DC4F36F503FF94795F28B2D -:107260004EDA58D80322FEA4C23660C9AC9CAFCE19 -:107270001CE57C55F37795E13E9EFDD441F1C1C6F6 -:107280006D0A0BE3DD0C5D007918F7FA9F3868DDB5 -:10729000F3B7A92C48E7ABB4368C935FFFC8501FF7 -:1072A000C647E70C8A16E179C3AE5FA6F8F0DC5753 -:1072B0006307FFFE24ECCF33313F4A29A778C45F30 -:1072C000A7B52EB460BE9D7A3817F9F5AF4FF1DF40 -:1072D000355BBCEA8F951E80F392E7DA5EA9827176 -:1072E0004EB4AA34EE078F3976A8C4F7FE7CBCDF13 -:1072F00036BEEE08F929A614063E43F9FEFEC2C8C2 -:1073000008923F6BB87FBC277C60BD886FA4579DF7 -:107310003C8BEB371E7F0321548072A2D1E6A3B8C9 -:10732000EC89AD368A17823EA07C8313ADD9162E28 -:10733000879E22BA6BB06A76FDB80D5B553FFF7D24 -:107340000CCD8EF36577AA41361AEB3C3F22BC592F -:1073500009F2F88F11BFD7AD1A4DE7A2CD795CB213 -:10736000FC08782AA88B2B2D799AC77FD9A80EAB59 -:107370003ECF5DFA6758B0CA709FD1B281F7FE6008 -:107380001C94A7FCFCEAC5333BDD24273FB43C53E7 -:107390007923941F4C0BBF6B05BCBCA806870CC09F -:1073A000BC21CBD6ED0AC5558EFF00E3FEEF3F6151 -:1073B000F3111B8ABCB1253F5D4CF1A9E4F602F341 -:1073C000F2F875344FF1E2EDC48CF24566B336E164 -:1073D0005F88F03C039C04C0C7B38CC7C58E57B808 -:1073E0006FC5F3C38DA6F3C6C7C5398BAA01DC6E82 -:1073F00092FAFAC6015C0E345A387FB2BDFC1E4ABE -:10740000F97B71528E4B792BE575CD009EC722E535 -:107410002C636D245F168AFB92973DE6E0E78B3480 -:10742000E641382EE668621B0770BE5E627FE21E90 -:1074300024EB45AC9DF4DEFBB6C8C2F612FC7EC759 -:10744000862CFADEE68B201F47E4EFD159498E2CBB -:10745000627C9ECB5B954854E7EF90BF4FC2504F84 -:10746000E8E44E0FBD60D2070B84FE5BC04CF946CA -:10747000AD463D154873D3BA96B48A3CECEE79A973 -:10748000EC2CC6BB8291E7A6D3BC155F24C13C1689 -:10749000B1AE28DE8BBCFC717E8EC93C2FF33AFA6C -:1074A0003ACF85BE9913F17EE5EE714DF396F06605 -:1074B00078B04A870709F785610ECF857B14C2D75C -:1074C0009F85BD25CF079AF1BF8805A6A39C5B7455 -:1074D00017EC334BE2F420E960F193113A0FF80115 -:1074E0006B4D77013F2CDBF6E4AC31F0FDA2075E7B -:1074F000B423BDD7654587583261FF199E70474D4B -:107500005102BD6FD2F35F179C98F05BD177009763 -:10751000053B55CAA3D0B513790461E287A630FFB5 -:107520003DC1A697555F0B3C6DC29F392A3FFFF9BD -:107530004AB8FDB3E76DB66B760DE8DDAE31CB9B97 -:107540001E768D499FE2790ED49F5DB93C3FFD13B5 -:10755000AB3F238BE4B4490EE796D37DAC520E2F9C -:10756000147A508EB300F51FD4DFDDF68B74F46708 -:10757000FCF9AE5FE451BE06EA9B61717D73432363 -:107580001FEF865FA550BED45FA7B58F407BB0EEDE -:10759000C1E7D3F5F7BD7E5010FC03CA5BA91F9766 -:1075A000AB3B06E0EF1A4A397BCE7D5BB275BACFB2 -:1075B000B14EB7719D0DB84EDD399546B1CE7736D7 -:1075C000F3F51DDFCAD73BBFC73AC31457B9E1C7AC -:1075D0000E5F98EC8E28E9F5934FAA0CF759DD76EB -:1075E00087C90E38C35AB7233C96AF7EF54D2BD0D2 -:1075F000C5E20B003E400775773A48EF2FFE258F16 -:10760000A7BEAF54E75340FF4034FDBBF07C09D820 -:107610000B686FC4E7D16D077C3E406F07F4117EA5 -:107620002B845F6BC59EE7E977B4143FCFC75C211D -:10763000EFB5D96DBAD7464319C0CFF93B114FFD0D -:10764000CDF77171FFEC7F0FF978EE6AA2FFAE0BF8 -:10765000F4E7D89A53A336CC43EE7A52213B69F92A -:10766000F5D5E9D50CCFB771BF5A7E31D76F8ADF18 -:107670004FF9350EC06B2A8C5758ACF1FBAF340F65 -:10768000CF377F80D13D3A72BEE6E7E86F77A23E02 -:107690007459481F9AD73FA598EBCDE5AA85ECEB26 -:1076A00065766E67778AFB2B868A790C2DE6796082 -:1076B000C38BB99FA113ED4A8C777FC341BF63C4CD -:1076C000D844F2BB5B19A73FAB849BC7FA51377F05 -:1076D00093FDDCD51FE13497B5D3EF224EAF9AA9C5 -:1076E000E1798637F39C744F14FC09603FB3453F42 -:1076F000476CFCFCC29B3806AC6BB6F04FBF89D719 -:10770000A3C2F86F16D8C9AE0D3FED20BBE1965469 -:10771000EE3F64391956E4876B859C9A33CEE14776 -:10772000B93E7BDC2D012CA1BF300378D539BB36A7 -:1077300096C138EB2C5CDFAFCB62DC2FB0A1A3028B -:10774000E1770998C998BF0FABDF7536BB373A327E -:107750009E9F58867E86B18C135815C1D7505F66A0 -:10776000E7EFE73DF41F33EEEACFD81F306B0AF5A1 -:107770000CC208E9A23E83F6BF33F07C4116965650 -:10778000A2B7CBAD2C6CE1E56617DDABE435FC2E82 -:10779000EC55552C9A01EB8B1E329EEFB83A6A8954 -:1077A0000EC5789135BA0FE167716A360F8C13A850 -:1077B00051CA11EECBD6F76DBEAB1F7A6AC65DE338 -:1077C000A08EF779E13CBFAB50BED06C607AA4D3F9 -:1077D000B95676402DE7F8433A6CCED2C2D46E1536 -:1077E000A77379AE44E2A50CBAD7C377B6981FF455 -:1077F000B3391DBFB727F6AB7CBF58C6E3B8BDB6DB -:1078000054F0ED5249778F1BF935827C83FC84F666 -:1078100021C06DB62893D1FD83822F1E2CE6FBCCB0 -:107820002DC5729FD9B7F1963B5894D6FDB483F01D -:1078300028C79D21CAFB8BB9DD29E721E977215BA8 -:1078400049F93C0B859FC6029284F2835B7FCCFD95 -:1078500042A6BC23309428BF6DC94EF3739D9F4749 -:1078600035C825F29B2AF6AEF9383FE59B293EA4A0 -:10787000F7D9F636F20F98DBD9F0F75331EEB61997 -:10788000EC2A45C4CBA0EED8AAD0EF5ECCEEDF3513 -:107890001CF53948EBC9742E54D8DB0B057E1DE26C -:1078A0007EAB85685F615C0DED2B84D7366E575AD1 -:1078B000853DDCB0D5686FCCDEA0B33B7961B81FE5 -:1078C000C061CA53B709BBE32D7BD77094FBE6FBBD -:1078D00002DEB2F07584F318BF573387BFB70AFBD7 -:1078E00052D2D513C53643DC4D9E3BAD4379C5EF2F -:1078F0006D30E569B9E8FE983A85DFDF29FD906FC4 -:1079000088F214D8A1745FCEB1348A839BFD939D15 -:10791000D5EEB045E7A79C9371C374844F5DBADD83 -:107920008AE51BDDF78A75D0F8C73C03C9FED95438 -:107930003D721BE627FDF9A153339C45144D11E719 -:10794000A73E7D01F3E9AFFC02D643F5D80C3F8E8C -:10795000F36CD75C2788EEBF157F36C30A7ABEF377 -:10796000EEAEED58776B9600D56FEF1A80772EBB91 -:1079700023765E5F27FBB307304FB9F33E5E7FFF90 -:10798000217B00F39FEAC4B9A5BAB10AC9DF54C18B -:107990005FD2CF5467798697E3F9EFA29CAB5D9EE7 -:1079A00016482DCEC5FB504FD0EF2F940CF4A716E0 -:1079B00043BBF401C133582E99A984ED78DEFFE56D -:1079C000C80542AF25FC9D9054A1A70A4A02F4BD08 -:1079D000F4A3433F7FC7FECFD5CFFF016BCEE90AAB -:1079E00000800000000000001F8B08000000000065 -:1079F000000BD57D0D5C5455DAF8B973E70B6606BC -:107A0000464003F9700604B140470545A51A011127 -:107A10003FD041CD2CAD4634454341ABCDDDDC7785 -:107A20000651336B0BABB7DCB2763273ADD75A323B -:107A3000412C3F06B5D26C6B4C6AA9D4C532BFB29B -:107A400022D35DFAAFBBFECFF39C739939D7416D5A -:107A500077DFFDFD5EFCF93B3CF79C7BEE739EEF10 -:107A6000E739E75E2E5DA23F371312D94B43482E0C -:107A700021BFB7B9227B752764FAC2F46877162153 -:107A800051296E838DC2F3CA24AFBE3F21A4C5978E -:107A9000E1B210329E1067BD99904BFCFE4BAA7963 -:107AA000EEB35F368FF59F99E74FAA79EE94E8BD64 -:107AB00043E97FE2B0C1FD77A439B360DE7BFE8B82 -:107AC000B8611E52345C43061372AF91E0CF8FD57C -:107AD0005B338C39B4DD648825763AEEF56D29B3D5 -:107AE000E93C6431BD2981906F9A3FD3DBE83C0BC0 -:107AF0003A64E28C25A4AA43C276C196667D311D04 -:107B00005745DBC210FC2A39BE84B469275A82D794 -:107B100007D828BEDDE1FA6A6CEF79FDB4D64DC70F -:107B2000DDA3A93FF16C1CBD3C4C72BC6CBB7C9DC1 -:107B300009FCBEA38494D4675DDE3FC426617F5DEB -:107B4000BA7330AC339ECE01B0AC61EB558FF7F217 -:107B5000F9A64792BB5CB47FE6608BD146E99DDB1A -:107B6000E2AEB5503C66AFB50F94E91C03520A9CD7 -:107B7000301F99354CA057494F4202B03E6D7B0FE4 -:107B800042DB1FB7E746138AD7F498C07D64002113 -:107B90000FFA32EA8CC9848C7D868EE989B7380960 -:107BA000BDB7C4C061EF8DAEA27C0AFF4346F84E5C -:107BB000DB903A2F9D671FE043E7B963487624E9DD -:107BC00047A9673769ACD1F4E6E4190F021E770CB8 -:107BD000B9B118AE8F30583266207D09CA8733D9C3 -:107BE00035C596CBC613BA0EB7DEDFFD56BA0EF713 -:107BF000FBB2C34BD7E1EE6772FBC2D06D32A7C3B5 -:107C000083362BCAD13E0DC57360100FE5F9845839 -:107C1000EF0BD0F98E2F4D18B08ACEF7BBE411BF11 -:107C200082E729CFFF5DB27B4EE8F32946FDE0FAFB -:107C3000B5E2318BE3F12BE01B9DC7954FE58CD36B -:107C4000FA12FD3FB1C824C093C7C5126766109EE3 -:107C500032395180A74E4F13C6DF3EEB06A1BFD489 -:107C600010C8A93607E55B8D8FD25246215E559626 -:107C70008D5184A27864FB854FA7513DF97EBDEC00 -:107C80009028AE7377BCFCE9703AEA1C5D702CA5B5 -:107C9000DB392705E87ACF6D917D5E3BC887535B62 -:107CA000DA83900A988A8E9FBFFF4DFD08FA6B45D4 -:107CB000F59C71C0C7B93EDD976D21785E2017F540 -:107CC0002495EAC346F17A1579F407B91F407EBDC1 -:107CD0002B9BCE53AFEAAF1E759244C138ED976D22 -:107CE000CA3AE9F3171FB63FB63764DDCFD92C7116 -:107CF000276EA0BF0C24032FC9F0BCB3EFD215929E -:107D0000C2A666E453ED7ED901225A9B2C1189AE9E -:107D100073D416832F82AAD6B7DB8EE96D945E7F6B -:107D2000F5D81EDBAB03FDAF212416EE3BA66FA3F7 -:107D3000D787DB6C48A705DB7FD013CAF751DB1769 -:107D4000A25E17533B164DE527D04CB2B7D0F9BD14 -:107D5000768BE3653AFF3D2B4713328890E88E69B6 -:107D6000D856D68DC6F9E6774C4278418709E17D31 -:107D700091816242F1D8D7D88DD4523C3E92FD1900 -:107D8000CFC13C060BDA89D2C43B96C2BAF7457A1A -:107D9000B3EEA5CF2BFDC3A812A0EB822D9213E466 -:107DA000AC5426FBA418C03702E72B953FCE5948A8 -:107DB000AF8F2DB47835D1D84F08ED97075B5611AA -:107DC0000ACB7A6A2FC2C8E77BDCBEE8DA18DE236A -:107DD0003BCA703EA5FF8FB654945B05D6755FAF66 -:107DE0002D3707D7A36B93B01DD37103B6555BCA6C -:107DF000B436FA9CF7335F8A033AD1F1667758BB01 -:107E00003C249A84B15F4A6BE0F6781AD8633AEF63 -:107E1000DE54E757A087E397B4698D604FCD46EBFA -:107E2000CB540EC6E70DB0CD0E5997BCFB3662A3FE -:107E30007264886BD739E9FCD3681B6ABFEFEAC26A -:107E4000DF9CEEB4DF35B85EC52F91CC2584503968 -:107E5000BFD3CAF056F4EA533E5EB93F2031FDF07D -:107E600036187C2FD3DF8FA4BAFF06F8064690A9F8 -:107E70009BD19E0652CA2CFF3EFC297F8DC0FF2855 -:107E80006D1B89017F6657F0677A7D35FCBFB33182 -:107E9000FFFA914C16835C7C74F3CD0127C5ABF9D6 -:107EA000C14183C03F28CFEB66D7E338626DBF087E -:107EB000F25AB5D3645B45D7574A790370FB0E83FA -:107EC0006F9D1DAF13290E5AC33A89F65745B56702 -:107ED00080FF29DC15E107B96DDE15A1053FF24EE3 -:107EE000BABB9BBD3B5CEF532451F9766E376841BA -:107EF0000E7AD89C3170BD2B7CAF66C7147D54CBF5 -:107F0000997B25D33F37D7C3195C6ECBB91ECED032 -:107F10003AA21FA078DFF5814CC08E972F91B2B79F -:107F2000E4804DB338D243F450D1371DC8E52090DA -:107F30004F2697951DDDB87EDBF9BC4C0F4AA9830F -:107F400006FA94DED0CD07FABDA02316C729FAAAF7 -:107F5000E869629A7B04ACBBB496EA377D8E7B6994 -:107F6000420EE84B504EF45690272A27F1B343E4D3 -:107F7000A0B6F9272DC8892E5F423931D0B63044DA -:107F80008E5C9D718AB5B807C563FC32BB66150966 -:107F9000F617DB19FFAF55DE0771F92A37FBD3352A -:107FA000743E5D75846329C5EB5C9C0DEDD8A2879A -:107FB000294049B048E72A843863D16F2507D85F44 -:107FC000883FC0FE0C6EADD6BB43F0BBADA31FB166 -:107FD000513A4DEAE88DED8014F7647B2EF0670A84 -:107FE000A7633F6C892D4F03F8DC67647EE67CF560 -:107FF0004377C2F3CEFB0C0E781E21798CDF1CDF99 -:108000005CA7E3BA0700BF0F74E4453AFE54845BF3 -:1080100006BD3C954CAC4F521467AEA17CA6F39EB6 -:10802000D211AF95F2731685DD007723CE6E034132 -:10803000EFE83A43FCCA056D5D0A49A3FC5DF4A76D -:10804000A35A6A0AE76604FAF9E973A78F60FEFF8C -:10805000EC7A1DFAFFCAE68F076B68FF19BBF33A8B -:10806000426DEFE89EEE05C0D779137DAFEB287C1B -:10807000CF6FDE8C1A6A0BD2B35EEB4FD7D2FBEB1D -:10808000291DBD14AFFA47E5121F8B7B4C65D957EC -:1080900097EB791D69481FC5DF28F67BAB279E2E1D -:1080A0002268C7AFE68714F99ECFF5603EE8010964 -:1080B000F53765AE1120879992239D84FA1BA60F90 -:1080C0008A9DA6F28E7A539A96ECA82541BBADF60E -:1080D000477BE4FA2787D1F52E4D75FB80DF05FF3E -:1080E000F3B7373FA75D959B5F29023E8DB84122CC -:1080F000B2742D76F2271DDAC9256504ED246D438F -:10810000EDA4AE8B38FD65FBCFB3F34FF2F134BE77 -:10811000C5B811EC78E87C47520BB6C23AB6DB25FD -:1081200036DFBF096FB57DDFDEA9AFD766DF5FE55C -:10813000785FCDBE7FC4EDBBDA9E133A1FD8F3EF54 -:1081400077F4F581BD3F4AA8FD07FFB6DD647B9952 -:10815000DB7BF40791D1BE2BD9FBBAF4991F756173 -:10816000EF0340B77FD5DE2BF2A5D607B51EA8E5F5 -:108170007EEC2334FE023E6D9508D8D760BC455096 -:108180008EF7A5323956F42624FE423F4FF5C197AB -:108190006EBF5C2F7FACFE538E0DF2CD1CCB002248 -:1081A00005E55DD11745DED57E644EAA5B4ACD0D4F -:1081B000EA49E566B51FE84A9EB6E9207FD555FE37 -:1081C000C0FC006D43FD4057F18E3EF5E7E9C179F3 -:1081D000FBB5C50B09A97A9CF77F519E12804E61B1 -:1081E000E4A967EABF204F57E023FA1945CEC61E1F -:1081F00060F241D258BC4FE505F1DEA74FF6D5DA63 -:10820000C1EE317B38F612A9067ADEC5EB098ABCCD -:1082100016A5B96F0AE533C4F710B75F6B5C382D4C -:10822000AE9A38E9F5BB681B6A370CC0BF30F17DE8 -:1082300061EACFF3F30352AF8DCF93399FFF8D7176 -:10824000E15DA961EC047132FF1FE48B6112C8CDBE -:108250008F7E2D01FDEA8AAFBA358CEE0ABCDCAF09 -:1082600055FC6B2CF8572A2FEED47F21DE2C2DAC39 -:108270003F6FA4A1DF7FAD1B5EA61D4AF3F43CC295 -:10828000EB1FF9AB9D5AB02FF4F7613823D6473E68 -:108290009239ECBDF16011C563EC939DFD5EE81F62 -:1082A000991FDD594F81544219FFEB75C30E3E8A69 -:1082B00078D7313EBADBB4AEEC103887C2961038AE -:1082C0004F05AF65E3C18F58711E1FB3F7747E6908 -:1082D00020C0CA7C5C0F487B71378817B74856A806 -:1082E00087DC9EFFBD1EF8535AD8F66E225DEFEA7A -:1082F000754565E6BEF43AD8418AEF8BEBC6ADF61C -:108300006AF9FD3DB03E863F867AC929533E55E65F -:1083100049BE54FBE5747C3155F467F0A315EF2793 -:10832000FA9C9F773FE82FDE9F8AF7FB0D3FE3F92A -:10833000B7E613A72F8C9DFC8362272F5258999F75 -:10834000D26E523DCBC3D5E3B7F2F1018D663EA1AB -:10835000F4DAB5CEBD1AEA652309938FE6757795F1 -:1083600079991C12A76ABD57C2F7E55431BF831F24 -:108370009B78BFFF4AF4FA9FCBE8C5E5A3429497E8 -:1083800068AD6BEF8F148FE838C90A71ED0257C4DE -:10839000A310BF97162AF23DAFCC9944D71741845A -:1083A000FA5F50BEEF292BA274594094F1F3578322 -:1083B0005F72693AC73379DF2E75DE9F49E5074B57 -:1083C00071F4FE2FD655AEF666213FB01F61ED1554 -:1083D000E4BD5E05E7ABF483CB37EA27D86D4A9F4F -:1083E000F43076A383D3E75B894C05BB172860F193 -:1083F0005E2095B5F1692CBE23696C9C318DF339F3 -:1084000032840E49413ED31F3FE41121EB463ADD51 -:1084100016A7ACFBD1B271745D8118922D513989C8 -:10842000495BB97A59889CC4A53D8A72129C6FD564 -:1084300041A0E36D9C4EF1698F1CE4722481DECD76 -:108440004781A072B045F2CA749DF3410EC2ACF3ED -:10845000CBCBE5C8ABBADFA9BBC2FDA72EBFDFA956 -:10846000BA9FE8E27ECEFD9C4FE3547C2C51F1B1E3 -:1084700048054F57609F60CF143B57DEB47A798F21 -:1084800038A8374AE026C05EEBA5018464BFF4DF5C -:1084900065E60490579B2E91DAFC012F3D73D0487E -:1084A000ED5919D83394DF35AB9DBDA97E83BE232A -:1084B000FCDB32677F909FEAE5F174FC90979E5D4C -:1084C0006DA4436F5FB65A0731CDF097D6AED6D2C2 -:1084D000796FCBF9C3BB309FB6E68583E3A42BC885 -:1084E0006B9D6A1D6B55B05735FEA9ABD8F765AAD1 -:1084F000FB97A8FA1F55C16B54F04AF1FE19B3243B -:10850000D49319947F40B8ABE94D595A679ED1E98D -:10851000CF2433C64982DC8FAD65F0B4973695AD74 -:108520003487C069AF9781BE2B72AC23EC675A1CAD -:10853000F182FFD07561CF46A7752147996A7FC741 -:10854000FAFF0CBF26E03E8BE097F7C822DC2C2B0D -:10855000786F3F785F165C54E0B7CBA07ED1E5BE64 -:1085600007D95606FB1E631FE7B0B7A90CE23465B6 -:108570009DCAF8E2BF5F92E1790BD39ACAD6C3BE17 -:108580004A813F1DEAF5D363584BFD8C0C7EAC8AC3 -:10859000D73B8A77C82EF033D323FDE98BB242D67E -:1085A00049EA33609DCD0FCAC81F6F2DCB47CA89DA -:1085B000430FF58AE6E8E8C51BE8F83D0FCA8BC112 -:1085C000AF1D5D1CDB03F289DD692CDFDB13DDAB46 -:1085D000C7DD146E36DDA5877A6DF34323B1DD2D3B -:1085E0003B57B453397EFCA5F7D0CF379BA2913EC1 -:1085F0008FA4ED29ABA17AF1589A0DEF77C7587B7C -:108600003441BCBA4A47A05E4D88E305949BDF180D -:1086100006ACA278CCA8B901F78FCAFFBBAC3881F1 -:108620008E2B5FAEC37D05FAD30FF076AF1AA98704 -:10863000FE59CB78EB1D85EDAE7FBC79A01F1DDF09 -:10864000FEB0EC584707EFEC488D2AA7787D15C19E -:10865000ECF097677B47019E7D7ABB9F4DA37C9D85 -:1086600011658994C079586D5113E9BCBDD39DCF74 -:10867000A5E506C7EFFA878CFB606F9F2DEF01FC25 -:108680007B99DBEF9D1DE53DCA43FCFDEC6FB548D2 -:10869000E75D7ADB7D105FEE8A4C96BCA8C7F5B12A -:1086A00050B79DC5E36B2A2F8BDF0CE3F79F4893F0 -:1086B00071DEE386C5E42B2AC4CD8F74CF073C95C9 -:1086C000FB94FD375D926D60681CBDAE57C11BB059 -:1086D0008EA09C1D3D087283713485B7BFF4F96A82 -:1086E0002FF8C23D34FE073CE29CC5E007C8925813 -:1086F000B60F1A5F9F115A8F08C6A94BB93D60E3A8 -:108700008E782D98B71ED914E1837CE688F70B4B41 -:1087100068FD5DD1933951162F38E393168B16E817 -:108720007A54EB39F14BD8377C5E877674F6F3DDFB -:1087300097B4833DA0FC847A90FAB93D7AEB709EA1 -:10874000AEF707BF11F5847C53E63477AD279FBEA3 -:1087500074A66CBDB96B3D99C3E3F6E2E7752E9044 -:10876000F339B9162DECD3153CFFCECB208F731601 -:10877000460C3450C4E73C6F40FEB6592C5E2BECDF -:10878000234659B4DD68FB0D9787B69A08CC53E4AD -:108790001E7AB47BF28A5C1BD0A750265A23F52B95 -:1087A0007294C3E662F032A81B2EB7E4D980BFB141 -:1087B000BD993E74F6474F1D23F50BEE9B9D5EFC65 -:1087C000E4D343287E67886FCA10FBBFBE8F56452F -:1087D0005CD1507FFCDFDA47D3F6B6C49DA0A97800 -:1087E000701F2D2BFA5610BFC532E22D2F8DF001D0 -:1087F0003DE514E627461109F7D18895AE3F3BB811 -:108800008F26FF6A10D2E7B887CA551F4A972823D8 -:108810008E977F25FB0CF4B985B1ACDE2A3F5D460F -:10882000605F8DD2D56BA5F0A8B86ADC5FF3829D3E -:1088300001FD9688AB1EF5DF910279F2ECE72390FB -:108840008F735E98FBE96F73806FA571A1FAD48B6B -:10885000CB1F9D8F186382F39CACF9750AE053F827 -:108860003B9A5F42DE29BB9FBE0DEDA609F7DB8870 -:10887000B5ED3743405E6A4C03A04E3EE7F9849461 -:10888000D4ACE0FD73963E98C1EEA7796B14D8ADD9 -:10889000085C4FE51603CACB8C876527FAC9643D8F -:1088A000FAC92F9745205C999487FA3643C3F6DFBF -:1088B000684C188FF69D919C549A89F34D33D8FBE0 -:1088C000470332E38F97F34D0FFC19D63B169F7F7A -:1088D00017D098FAAFDB7B73BA68981C919D12EEA3 -:1088E0003711526D033B305D23A1BD53EBE5D8DE5C -:1088F0006C9F6F468AE34EB86FFE6306C7523BC358 -:108900004156F0A179D37C4D6036EC43924603D6B4 -:1089100037AAE83A22A2D8B987CD14FF2A2DD1EA86 -:10892000A13E6563764DC1A7CA56360AE495F6B7EF -:108930006A69FF7C0BB3CBF3BBB1BA0FB1187D2FC3 -:10894000873E0F704E63F7D9A240DF86A2BC80FE3F -:108950006B68FFF784F51746E5D9DAB270FF7E251C -:10896000D44B009FBEFD429E4BE1847E208F0BB511 -:10897000A916E043EC94A9F0BCD764B44F54A91EE7 -:10898000CB8338F0357910E4B3331EDE53BC06E0F8 -:10899000370658018519AF1F423F750F97B33688C8 -:1089A000FFC16F51F80DDADEDB9BD907B7CCEA398E -:1089B000F7F69684FD50A57FFEC33AE4C7FCE54C6C -:1089C0001EE6D7FC09E79D6F09F4007ECC6FD00D41 -:1089D00006B95EC2ED45794D727E2B958F725DB4FE -:1089E00055A2972ABDA57A802BEB248495E7CD7FED -:1089F000F8931E9A2C361FB4062E47C179BBA78068 -:108A00005FFB66536CCA8C10BE7FB36C6B14EC6B4F -:108A10007F15E14FB7423D666184631DEA29E3C7D4 -:108A200037CBD2D741BD6696356081FDF059F7A5A9 -:108A3000C580BF3B6AF5EBA1FF68BD5D03B0D36A9B -:108A4000CD07D8A9ED8FF037FC9C0AFE503E2D9043 -:108A500098DC546EDAA34FA5CF7B91D3E7DBD70E1A -:108A60006540DD607E4A2003FC3095AB8C44E0CB52 -:108A7000AB12C60B0B36C9CE887E41B95A0072457F -:108A8000F57F1E97AB055BB63E007ABA00E469E05D -:108A9000E57249F3CBBD787DF38BC584DDBF17E468 -:108AA0004EF1FB145EA683FA9A9EC3F43900AFE33D -:108AB000F4A7FD45ACDF9B85FE84B4E9212EAE9280 -:108AC00059BC40F5291EE289AA269DB72DC43E2E29 -:108AD00080FEAC607F5772B3A737DF2FAB31A05F4A -:108AE000DAC3F5AFEDE18628908B6F5FDBF3EE30F4 -:108AF000C8B3364B56B0FB97E921A75B15D0290ABE -:108B0000D789F15115D0252A48A74E7DE3725145EA -:108B1000181D14BA5469399D947E7EFF5E4E874AB3 -:108B2000C2E9BAA50FD377AEDF5462D08F28EB73BA -:108B3000C788E7072EF0F57DCCDB4A2A378E2C94C8 -:108B40002FA77E30CFFF69D7B76FBC88F523859FED -:108B50000ADE96749B62A79DDD62827C6ED3908A4A -:108B600070F5EA539C7E3A33B32BC76A12EF5C4C24 -:108B7000E9376F93EC40E241EE15F25C83A6CD82BB -:108B8000F1E9AF642BACABF07FCAC6C0BA15B9D35C -:108B90006D94B44DB04F48BA21FD15FC0AAF738DEA -:108BA000E9C6E4CE0FF828781E93FCC82FEF1B927D -:108BB00095C5BB6D7AA8232A7AAAC6F702C7578E35 -:108BC000928649FD011F870DF49B503F88F8985B02 -:108BD0001FC4E7798F3C68EF177CCE51AF450BE39C -:108BE0008E12660714B93CC6EB12C7966FC578584B -:108BF000798E29FDB2E7B817C75DFE1C65BC9CCE17 -:108C0000F453D18B7D314CFE0B97FD09C7297616A5 -:108C10007EA01EA7D053A15B885E0AF451F44BD10D -:108C20002785AFFFAC5E9125DD316E7D88AF1B756A -:108C3000A447D02F807C82BF33E8D939B810BF89D0 -:108C400071CDA8A41FF4EE30D7153AA9AF07F32AC7 -:108C50006B0AD07F94391EF7CBC9B2F8BDBD43E291 -:108C6000B3AFA0EE05F6F415D987F69450AD0CF12C -:108C7000E74ADC56B370947504C8D72609CF1D297E -:108C8000FE9BFE3CDA29A774BE8A9C8519104FAC66 -:108C90004C4F65FE2CCE791AEEAF3C15288EB205EE -:108CA000F3971BCFFBE568A80F6EB10BF943E5D92D -:108CB000BDA8E7F3496005E4BB331E3E543A04F80F -:108CC000FF8A0ECF2FCCAAB3A3FF3BBD7EE6204880 -:108CD0006D672C4F4778EECB7733F86116D7CD58B8 -:108CE0009EBB01EAF35F45388B41CEDB574B56C83C -:108CF000BF86BF9CBBE476DA3FDCD2AB1BE07B6473 -:108D0000FD57A5C3208F582CA3DE38D73F3905FA6D -:108D10009D4DB20396388B5897DC0E72AE8D46BDD2 -:108D200053CE35D6EA98BCCD4C67FE725A3AB31B87 -:108D3000D3B8FC16D6D666C0B982F617A99F82FDB5 -:108D400075BDADDE0F79E08EEB1CEBE873AA68DA37 -:108D50001A4FE5E994C4E2F10A3D31827CEDD70572 -:108D6000EE07FCF7DF6F19500308C8170797B3BC6D -:108D70001DED0CCDA3F0B90ABD94E797F3E72AF3F4 -:108D800028F7ED83B80AFC08C7F7F4B257A640BC31 -:108D9000707A637A0C09A1FB695817A5F75C6A1F02 -:108DA0003787C907ABD2957AAB0FDB0A5E47DCAFDA -:108DB000AB4B82FD5C1AD71F0F8DCF4FBE186104DD -:108DC000B9A471BD785DC7FC0A8DE785EB547F04BB -:108DD000B833DF93A747BBC3D823A555C7FB4BD3F5 -:108DE000CDAA73732CDE57F44F7DBF12DF77D65DAB -:108DF0007AFFBC735D673D9431542186417046EF24 -:108E00002F32FDFD4D387F39BBCE603550FA1E073D -:108E1000FD827DC10699C58B46A66FC7770CF041D0 -:108E20005D61F661E2F05378768BECB0D1F17B575F -:108E30003F84E73BEE5E2B91EBA490BCEBA9D553AE -:108E400040DDCE39DC2B12E8F8731BD97914DA6DCA -:108E500056E55BEF26D8BACEB7FE5D7996527F52C3 -:108E6000D37F733ACFB71CC421D29FE5EDBBA818BE -:108E7000E50DBC9CFE673D6ECCABBEF354603BB4CD -:108E8000FEC5C244BA8EEFA5638F0D073DB24463A1 -:108E9000FDE4ACA71A3707BF6B1A74713CA5D3DB8E -:108EA000E6682BD88FEF3C8BF17AA7DC7039BD7167 -:108EB0004BB39C4870FCF6E174FC4E73346C7784C1 -:108EC000D987637C569FBFB977E190EBE0BAB2DEF9 -:108ED00033BF64FC56F03FB3716614C4ABCDCFC54D -:108EE0006E1F0A7C36455B4114E6F0733827D63096 -:108EF0007B74CA18BD611CA5DBA9B5937A407E7846 -:108F0000B7AE5DEFA0F33A769445417DE46B6D5BBF -:108F100094155A3ADE0F78687D32D8C1612504F77E -:108F20000787F9B5C466C7AD7B949FA167B53EC8F6 -:108F30009BBF817D43F0E31723D9FE3DDF0FBC7B50 -:108F40001BABB375D655787D61385F6F74468CB2B4 -:108F50000F84D70BF3D8F5936BDF1C0FF39D5EAF37 -:108F6000B302BEDFADD7E1FCF3687EAFA1F2786A51 -:108F7000233B2F306F3BCD93ED60472494DF795432 -:108F80007E8D207F0B754E7DF4E57259B891E5D743 -:108F9000F3EA25CCB715F99CE7F41523DDB99C1A43 -:108FA000E9BF4BD4757423F52B801E5DC9EB3F5B85 -:108FB0000FD06784AF07A8E541A19B22174139254F -:108FC000289F0AFF63EA078C48C41BBC484F6F0107 -:108FD000C98478A1564F32E13C945713E900BDFF94 -:108FE0006B44543FA8432D36B2F681C8A875D0FE15 -:108FF0003522C50778FF55637D07F2AC5F67D871EE -:109000009E07649B4EA2BF4E8A6B2B423750A871BD -:109010006AC00FD61AD08EA8ED505A06F33FDB3344 -:1090200008CAFDCD19EC9CB88E54637CA1B4341EE3 -:109030004886F8A5CC1473018E923B36F49804FB55 -:10904000BD65C363EE4FA39167DE86A4495A2AE744 -:109050006583621A52293C2C2391F5F78FC9D551AB -:10906000B8A626795211856FCD70F6CB08798E326D -:109070002FBD3E2083E23132C19D03FD557AF34A74 -:10908000F003DF4BED0B347270FC41891C7D5B0AF1 -:10909000C26D3A9202F1F6CD807FF7AEDB1519CEA4 -:1090A0001B33C25C2F276439D425CABDEFB54A688B -:1090B000CF88CB48F93981CB5FB9D1EC473BB75268 -:1090C00077B6533E52C14E456B81EFE339DB2768DB -:1090D000FDCD707F5FB2CC7AC288A1E2DA4BB15D80 -:1090E000DB7FAAA8E484321F5DDFF73ABA5ECA5775 -:1090F000C949794D554CA2449E4EED9DB4FDBD9F8E -:1091000060DE5A2F698B403E4CB7829F92885B731A -:1091100089B6F34D542EFA434BE5818E5BD4F0EDC6 -:109120005E508BB94A9CE5CEC378F13E2B5B0F7144 -:109130000F4379BD9FCBEB490FA98652D1844020C4 -:109140000A8EC29E1DEFCF00FB5022BB6703BD4EAF -:10915000AEAD4D5A44E5E7DBCD06C7383AFE94EF95 -:10916000CD28F0AB953CDE271765FFCDB47F9FBDC2 -:10917000EFBA5521F25595C1FCFE59BB3FE541B010 -:10918000337696AF928B7B521EA4E34B5247E7AEE9 -:10919000422A381766E0BE05DBAF18AF0D7F7E634D -:1091A00072128B53C87AE68F0D5AE2B5C4604BA297 -:1091B000289D46535CF2E05C2A8565DCCFF7E1F33D -:1091C000615C14C435B699F16CBF87B8C06E29FCD8 -:1091D00055F876193F29CA10D76B8C4407EBED4B35 -:1091E000D65A41FF15BE9EE4FA78D2C8F470A46C3A -:1091F000463BB5A881D5F51649CCDE2EDA21B1FA69 -:10920000E665FEB66105D8E48AB533D19E2976CCF1 -:1092100046FF817CCDB3BAA2FDB67FC2EFAE2DBCB6 -:10922000267BE653ECD9003200E4EF6AF19262C784 -:10923000287B7E9F11B29F7C557E01C9E8BAE770FA -:109240001C47CAD36D5AA04B77A303ECF9A2E7D30E -:10925000D04F92F36BB08EA28C236B63517E57D8A4 -:1092600065E46B695322B1D14B739B243C273BAE21 -:109270002916E1A88E04844B7F7F5D01ACBB731F70 -:10928000F4F77D103EBDE1408E9BD5698C80878BC5 -:10929000287864D583FF3967A678503ABBCC2BB1C8 -:1092A000EEE8229DF990744902984A0DE89D53E733 -:1092B00065FC31D6A0FEF3752DE27AB5683FF3D791 -:1092C0008B46B0FD42ADB76F34F05FB74F263E0A14 -:1092D000DFB25FCEF5D3A1B5DC9E1BE235C416C26A -:1092E000B7085B24B185F087789D01C8B7A672796D -:1092F000792882D97D53668C306EAA7936CA4F2080 -:10930000A5781FACD7E2E829CC4BDC2C3E56E46AAA -:109310000AAF9B8F27EDCBC04FDE3295F687CCA7E7 -:10932000CBFF01FD862E5F8CAB295D8E5F499ECE03 -:1093300064F0F74EFA92BE284F2AFA50FD407F7F24 -:10934000AE85BD7F42A39267F2293C659F8EF86887 -:10935000FF724E17885B21FF39E7B4A0DE28721731 -:1093600000BF47ED5C749E48B76E4E916EB12522EA -:109370007DBABB447A5C373555E84F705F2FF427D0 -:10938000560C14E0E4EA61C2F85E8B0B04D8EE1DC3 -:10939000238C4F5B395180D3EB6E17C6F759532E90 -:1093A000F4F7F5CD13FA6FD8B84880B3EB7F258C6E -:1093B000EFDFB454E81FE05F25F40FDAF78400E72D -:1093C000069E15C60F695D27F40F6D7B55E81F7E5D -:1093D0006AB300DFD8FE9630FEE68EDD023C821CCA -:1093E00010C6171A0F09F048EB17C2F851F15F09C0 -:1093F000FDA36DDF08FD63337F14E0E53CCE2975E6 -:10940000FC4DB82F4096A5831CA725B987F7C1BA94 -:10941000CF292DE85FEB1D128985FC67DF242BEA3D -:10942000FDCFCC030BFB70BBC8E5F80231DF09E7C9 -:10943000D9AF6617ED3C9E18298FC3F7AACED5B3D6 -:109440007A87DAAF2BF15C3475CBDA90E776731A52 -:1094500069421F84634BAC02DCDD152F8CBF6EAA02 -:109460004DE84F70670AFD89150E014EAECE13C64A -:10947000F75AEC1460BBB744189FB6D225C0E97503 -:109480005385F17DD6B885FEBEBE0AA1FF868DD577 -:10949000029C5DBF5818DFBFC92BF40FF0AF14FA60 -:1094A00007EDAB13E0DCC01A61FC90569FD03FB4CF -:1094B0006DA3D03FFC54BD00DFD8DE248CBFB9C300 -:1094C0002FC023C87E617CA1F1A0008FB47E268CC2 -:1094D0001F157F4CE81F6D3B2DF4577EE3F0E3BE74 -:1094E000D4DBEC7D57259E1B9BF983304E1747E359 -:1094F0007DA87F9348079CF7EF2ACE57E2C052C75A -:109500004FC273FFAA61F1F9AB7DD8FB690FC82C7C -:109510004EACF5BAF07C5E0C1C78A57A12ED955035 -:10952000FE20C59A8EF5C838F4B7E8326D70DE8D2E -:10953000C6411488D1D8ED90879882716CD2A5412C -:10954000D71EC736F52188C7C93EEED7402FE7D5CD -:10955000BF510C79CE5CE25D017850BF1B0DFB580A -:109560001F4688F528A51D6DA4740C79DEFE88BA07 -:10957000A48157D0DFD1C6B338BE735E5EAF92E828 -:10958000FA1685CCFF18CDBFB4544FEB3C54CF68CE -:10959000A2FD84C78AF0539E78849FF6D8B05DE31D -:1095A000C9C4F6598F03FBD77AF2107EC1E344D8C1 -:1095B000E729C1769DC785D7D77BA622BCC1E3C664 -:1095C00076A3A702DB573DD5D8BFC9B318E1D73D75 -:1095D0005E6CEB3D2BF1FA664F1DC25B3C6B106E6F -:1095E000F4F8B06DF26CC4F62D4F3DF66FF73421F0 -:1095F000BCD3E347D8EFD987F06E4F00E1BD9E564C -:1096000084DFF5B461BBCF730ADBF73DEDD8FF8192 -:10961000A703E1B37C3FE1EB3EE2BE9D021352841F -:10962000F2A0C4BFE321EF01E1C8D37D27E43DAA46 -:10963000FC43CD8F33FC39BA021AFE42FCD33363AC -:109640005D6D485EF0037FDE4391C41B41F5A1468A -:10965000C3EA02353104DF0F233C3E9FC3E592C4C9 -:10966000B1B87C36C76B0ED7835C90CF4C94CF0FCC -:109670007E4E9EA5E4DB51296E2993E2312F59E3FA -:10968000C5BA8399BD873F20C5AD85EBE7AAEF7EBC -:10969000179F677564C0434A0DFEEEB7423D69BF30 -:1096A0008C75D8AE9E57C5DF93E8B27FE7E924F00A -:1096B0004725FF90B15EFFA1CE3215EA2D3D32194C -:1096C0005D7A646A84F6AD145777C0E7647AF586EC -:1096D0007BA5E0FBFF132035A77A5E466C3A3C87FA -:1096E0004B9CEFC0AB37B7D0800FE05B89175B674F -:1096F000B23B25B33B9C97F421EC1E664809B71E8C -:10970000353E99992C7ECFCCD408ED9F525C7D00DC -:109710009FE3E94E011F732F1B3F57DFFE02E0F569 -:10972000971D3F9C90D282F456EA1B2B46F0735A49 -:109730000B25651F9CC58946A2C489D83FFD7E566E -:10974000EF51FCE5E1CE96D9C373D53AB49BD3A5CE -:109750004807C4DBE7AAEFEF0FFB8577D07C0FF655 -:109760004F153B3A9DC21A0A4F27ECDCC5F4C316CD -:109770009433B57DA5F711D8EF9B4E4906F9E3A5C3 -:10978000143BAEE743D70F3A9897C4B5E37BAB548D -:109790006E4A809EF386CAF8FD860F35BE0C494698 -:1097A00079D14B14FF3971545EC2C40B8A5C2CE032 -:1097B000EFE528D7A9BC4D047A7EB76D4826EED3D5 -:1097C000EC1C6A037AD66AD87B75DEF765762E03C1 -:1097D0004AF9706E243AEB457CBF00820BE0DF5003 -:1097E0000BBE5FD02C93C56F84B1A7F772B9FA3066 -:1097F0005E57E2C379C57DC54ACED74ACEEFD2DDEA -:10980000FB93E1BDC105FB749817919CB62C57984A -:109810007355558B1FF945EF1039AF6A3AC6CE63C1 -:1098200091B6ACD073588FF07915F992F516F78B85 -:10983000E650FC3AE57C11D095CAF90988FBC71BB4 -:109840006CD1B7D25BDB2869FCB475FFCE8AE7F92F -:1098500094737DB3880BDB3994DD20D72EEF6A7CBF -:10986000AF7E1EA9C7EB0BF266A6005C45DA8BE261 -:10987000E97CB7ACAC79279E6237A96EF548A8732E -:109880004FF4CD7807DAB2F5D209AF0DF5A416F88A -:10989000D026552FEF499F77FBA611CBA18E3C5EBA -:1098A000667C2007181FA83C39E598CBD747F5629E -:1098B00015E04FF502F157F462FA52E294E282EFBA -:1098C0008174EA49DE3D7F4E843D166D3B9E43A97F -:1098D000DA698881FAC93CC2FC76B00EC4FCB5A234 -:1098E0000767748CEF675E93F03D9B3312C1EF39CD -:1098F00074153728F127D53FA677474D4CFE655E96 -:10990000D74B71C70F4C0BFAE7331ADFE0A834F4DA -:10991000DF1B801EBA02F7A303E0BCDEEB92A39626 -:10992000E272A69B2F859D13E8F403E49229582741 -:109930007C4CC7EA76EA7857594757781AF4C40B33 -:10994000FB5952DEBB3F411C7239BEEEF8C1942E6A -:10995000B5C022A84B16B86CE1F058C69FBFEFEF18 -:109960002C1FF726133C17A4A6A76465CFE9AABE4F -:109970006A8864F8287E4AC1F372BC18BF0E66324A -:109980007BA1E0478835D34A9FAFD5463A405FCBAD -:10999000B4EE00C887527F53F2E27DF693E80FC819 -:1099A000C5DA2476FED8DF951F3EDB998FA706FD2A -:1099B000A452C722F9E1EB912EA315EDD744E24062 -:1099C0007FD1971C56E885752C197608B1CEEBC669 -:1099D0007518C05ED33602EA28E82F7DB82E13E052 -:1099E00085EB0A404584AC3645211D86B512B4D3BB -:1099F000C3600D74BD3B8E111F9CA76ABE30A5D0FD -:109A000042FB777CABC53CE819D3EB89F01D891D7F -:109A1000A73F4D847A4FCD854684079F2D3ECDEAE2 -:109A20006787A7C17C6F9FD7DB0C18072C443A28A7 -:109A300075CAB70971C03E68DE67667CCF38B7A5C6 -:109A4000DE8474E375B57CBEEEFCF3AC1EB213800D -:109A5000A1340F68D7137F48BCACB38A701E09814C -:109A6000EDF0480A87D4397E6EFE68EACBEB2043DE -:109A7000C890D0BA1AE98809FB3E957A1F3147622F -:109A8000789FC874C5F5C5B86CA2CCE8FD0F19E87D -:109A900075B3D99700F16DF3DC0D0910EF3E63FA51 -:109AA00007D2F1D9BFEB1380AE7523FE827EA48E60 -:109AB000DE1B80FC57EB8B2058FF9A8F75E09BB91B -:109AC0009F7DF6E297249ED2B32E8FA0FF24DC0F59 -:109AD0002BFD7517CF55003F2FE41B6D60173278B3 -:109AE0003DB4E6A6FF17DF16428F1D34AEF65306CF -:109AF000BF4DE36A3F8DFDB7D1B81A6078EF14DA35 -:109B0000061A5743EBA37135B42FD0B81AC6415C7F -:109B10000DEDB334AE86760D8DABA17D9AC6D530F2 -:109B2000EE291A5743FB048DABE17ADDC5F242C43E -:109B3000A795E0FBF54B4D511AB0AF14FF48A80BA9 -:109B40007DE41C1809F4B8E9BC46E06FFED9480171 -:109B50001E763C26C85FE0FFE19E42FFE09654A1DE -:109B6000DFEEBD5E807B2D1E28C0501F0ABD3FB1B9 -:109B7000A2408013DC6384F1D74D9D28C0DD5DB722 -:109B80000BE3634BCA85FEC7A3547CF4556A443E7D -:109B9000B2EF2B5CC837E3F9CAAEE4F409CE17057F -:109BA0007EF297F2D47075DBB97D35423ED093E3F7 -:109BB000B6B0AF0DAFEF3D32E4958C1CE087866DFB -:109BC0009B3ADB4DBD295F329ED410385788270E53 -:109BD000287E567EDF9305E74C20977B4AF511C01F -:109BE0009F5DCE8248809796EA1342E5A8CEEE1E8E -:109BF00088EF29B8D9FA94FB1F2F9878C57DF427F0 -:109C000040FEFA5CA17FCCBC54D087CBE8482A70D8 -:109C1000BF3648C789F87D27E2AE10F057EB0581C3 -:109C20004DFA0478AE51A4A733F561A0C3B34F69D0 -:109C3000F11C56E77CFC7E65BE91F245535BD6E590 -:109C4000F8EF72B2F134FE8D00BAD06709F8C5386A -:109C50006C23803EBFE5FAF6DF5CDF9EE17C853C4D -:109C600016606265F7297CABAB78627406E84D1E1E -:109C7000C36BDDE427243037B1C451630DA1EB532E -:109C80001C8F17F8BAD6C2BC14EE3ED92901FD527A -:109C900016BB24D0B75E4BDA107E96EB7752753B3D -:109CA0005E4FBECF8F6DCF8A00F68F9437E13A3A80 -:109CB000E9E010E9A8E6938FAF47993778FFE6FD12 -:109CC000206F179C0CFF28AFD909FE22CA6B75B014 -:109CD000D6C65B8703EC7E94D7C9E1EA2C801BF8DB -:109CE000BAA2BC5E847D7C5D751571FB37D882CFCE -:109CF00023B62A4DA8BFE94A9E9A38FD1B399DD448 -:109D0000F735E8BC83AC61F44A69157F3AB44D235A -:109D1000E8F99056D14E7D04BF303FF0495F881B73 -:109D2000BC2E99EF5F211D2775E64BD3519E569BA4 -:109D3000EE3C00F9F6E41699307F3BFE1DB09787A4 -:109D4000461BD09F368F1E951C2A77CA3AB672BA28 -:109D50000FF53A8FDC47C797B90C8021755FCEE4C9 -:109D6000FBE97CAE71B203F6A15A3AFD89CBC4CEB1 -:109D70003B307F3291E3BC7BDCA447E0F9875AA8F3 -:109D80005DB005F154FA1B4A268DCD063E06181F1C -:109D9000BBA2CF7B9C5FEF70BCF6707E3573F9DEA3 -:109DA000C5FDC90EEE4FDE067F6200BF93C7D7C365 -:109DB000FC4903F7277F047F42DB03DC9FEC077F2E -:109DC00042DB9CD169456837E12536F4273441C12F -:109DD000F3040B847529789524C9027F8AE34C0229 -:109DE000FF8ACCB1427F813651809D175305F8A67A -:109DF000F3D7ABFC94E857861D1FA6F25305023C2F -:109E0000B8658C70FFF89C49023C2E6B9A008FE974 -:109E10003D538009DF0FCB65BF93DCC8B532E6B98F -:109E20007CDF4989A70E95C8B86F33F413D911AAFE -:109E3000B7B9A4739F4C03FB64347CB16995F952A4 -:109E4000857E8CA35A74AE4438BF575346E590B60E -:109E5000F92D344EC3E223956B1AF7E6BA46611C1E -:109E600048E3A541C88776B6DFA4EC5B0D55ED3F0E -:109E7000B98AC4FDA9DCABEC4FDD747D1771597E46 -:109E8000EC35C56554BF30FE7AC674E71E909B6DF5 -:109E90009FD13815E2DCCF7E81F1D7073094EAEB11 -:109EA000D6AF7F81F1EDD64E7D710BFA92CBF5B630 -:109EB000B125B5A98DEA5B4E37C9C1498DFA92C764 -:109EC000D794736CD1348C775A34187F91922AECE2 -:109ED0001FCCEF6F685D6A12DF5B0A897B306E8F83 -:109EE0000CCA0BE4932446ECB786C8672A635AE889 -:109EF0007842AE57CD3750050F538D2F50C1635464 -:109F0000E327AAE0DB55E3CB85FEA6B689578CBBD9 -:109F100015BBAE8CCBD5BA644718BB3BB8458C0794 -:109F200089AB4A38FFD07C6436DACFC6C32B389F62 -:109F30002A043EED569ED342E99D75F9FD055AAFC0 -:109F4000A91F95878216ADA3C616E4A3C22702797E -:109F500071C87C854659D0E3A656E61FBB5AE74E2A -:109F60006EA7B7737FF3962A8E93FF7EFED0042AE6 -:109F7000278D6D1ACCB31A5B0A62F1FDC18BB31049 -:109F8000DFA6560DBE4FB6F1D5F1B7D46883F829D8 -:109F9000F8E47CB2D404E7832E507F047296A37356 -:109FA000C65AC3D05D2D5F5DCDABC82F25542CD0D4 -:109FB0006517F547787E98DB55852EBB8F3C8D74F1 -:109FC000DFD6CAF0BDB943F48737B68BFE70F8A967 -:109FD0001801CE39C6E242EA7F71DE1C7EEEEE6ADF -:109FE00078ABF502764844B8A738FE1AE3826D5C78 -:109FF0004E1A389FB64538A6867BFFA8E1A8BE2238 -:10A00000F4FB0A27AF67F5B993D7B3B83BE79806D7 -:10A01000F35CAAF7686F875AEBE4EA30F30C3BAEC7 -:10A0200051E52D9102FD7E6EDEFAE5F57CDF53658C -:10A030001FBBBA5FB18F05CA77541C93C29E930DA4 -:10A04000F2819FAF54D19338C2DBDFCBF9A69C4B92 -:10A0500057F1AF8BFB83F378D579F5A5EB619EB60D -:10A0600032F43BAB4D0BB85D5F8076FD839FB85DEE -:10A07000FFA93109AE1F18B03509F4E840AEF23D32 -:10A0800058CABD907C5AD1A3F75B3E3685C6FB63A8 -:10A0900038EE3B320F8DED1FC2CFAEF0DCC7E5E7E7 -:10A0A0005D1EF7ECE57ABE9BC73D7E887BFA803D5E -:10A0B000C8E4F680E5D16FF1B8A789C73D8D3CEEC5 -:10A0C00039C8F3E88F20EEC13888E5D10D99F7E261 -:10A0D000F7C52E242971CF786D383E8FB689766A00 -:10A0E00054BC4990B7915631DE2934260AE3479093 -:10A0F00034A1FFE68EEB55FA2DC63BC34F8979F4A8 -:10A10000D036318F1ED22AE6D1138BC478C7952F53 -:10A11000C63BCA3EC22EAB84E7B1C6E788F1CF2E5C -:10A12000F885F63718D9F9AC86CC4957B4C37E6E9A -:10A1300087FFC8F5FB3DCE9F7778FEB093D37F07AE -:10A14000D01FE3521667E69E77EF89B6817DA8603F -:10A15000F9426615E6D537725CB67AAA597C7A411F -:10A16000637650BEEC32B3386B57E6CCF3F0DEFFCB -:10A1700005ABC906F599033A37C2BB32251B7C6F84 -:10A18000508D5F6EABCACFF1784191CF5D2D5FA24C -:10A190007FDBD9716D7E5519F71E998475979B5A8F -:10A1A000083184A92F5CCDBF5EED39EAF1E0C7C369 -:10A1B000F91FF573C674B86542F577476BE04948F7 -:10A1C0008BC6F8E7CAF05DA8C1ADEE42E0EBDE4C0D -:10A1D000C90AFBE9745C21EC4BBC77F1E3B1707DFB -:10A1E000E779ADC680FB4E56C11F7D7091D21FE44A -:10A1F00025939D4FF2B77EF9487FA8F31A657C7FBF -:10A2000064D7C58171A1747BFC0619ED4A43964160 -:10A2100003F5E686F35AE20F89F71A3B52CDD036A2 -:10A2200064CAFC7A00EDC37337B073AB3BE87CCCF7 -:10A230005ED8100F451EFCE73525E1BEBFF31C7F3D -:10A240005EEEC53F9B20BF7CF77CB909ECD3CE56B0 -:10A25000F69CDC256D26A0DB818E7566B8BE2B735F -:10A2600010CEDF9CFD907920C84DAB86EDE7F0F86D -:10A270004679DEAEAC398F0E8075B7B2BC6CD7F9BB -:10A28000CD7BA2402FD64B0E16BF307BA68C6F38ED -:10A29000CFEB4D3E76CE2D97783FCD06FDE9F17B95 -:10A2A0003DC839F1569250FB576815ED4841ABCA8D -:10A2B0004FB92B511F143E946A6385FE039F4D9C3A -:10A2C0005C067C33B3F7DB769E5F1A3711F4C2ACC1 -:10A2D0006371B38FDD3F2E58AFC1F7B594EFB0D4A3 -:10A2E000643F70A814EE6F607CCD358BF81CE85B82 -:10A2F0009BB880CED7B0C5E410D67798E0FA76390F -:10A30000DE9C8E75ED2C03EA61E185BDE6B6903AE0 -:10A3100051679CD8B2DB3C08E87C5623D04DA1C3E2 -:10A32000A83C317FDC91B907C75F38CBE89E4BAAC8 -:10A330000FF567755873E9E060FE95DBC1EAE373DA -:10A340007D22DE43378AF9E77C557CA4AE9FE76720 -:10A35000CD1927E4573C6ECAE37193BA4E5EAA3515 -:10A3600088F509559D3C575D27FF67E3249D7B1ABF -:10A37000BE0F17987C4DF1C3501A6BC6E3F95EEF20 -:10A380009320D76FF1F872A8BEEEDE04AA220DB2B8 -:10A390007B38EE5BF03A9D72FF55E325AB97C40D19 -:10A3A0000EC98789F604E4972B618F13F9E265E7FC -:10A3B0005955F376156F28FB23F945CCFF3C63FA1A -:10A3C00010E38BC6AF597C013F6D3D60BF9EA01F5F -:10A3D0006EFE5A8FFB276F8F66FBDE4ABC328938D0 -:10A3E00071DF667CDE79ED6F6CB09F7367F67CDAA7 -:10A3F000BEFD5923E6996F77E69975429E99CFE5A0 -:10A40000725BBBC61B0BF941ABC14742F6DB95FE45 -:10A41000C6F6F247B2410E031A94C3E66FF504BEC6 -:10A42000BFD7B8DD8078379ED5633CBA6DBB89C98C -:10A4300035AF3F2BFADACAFDE2A79C9F07B85FDC75 -:10A44000CFFDE27BBC5EF30E8F5BF6F07A4D338F6F -:10A450005B7681DFA4ED9676AE774B4C1C4F569F12 -:10A4600055F0BCAB4FDB112DE56BD57783D7403D65 -:10A47000EA36B7A80FB74E15E3937159627C32A63E -:10A48000B7588F29494A13EE2F8EBB41E82F320F60 -:10A4900012ED9676B8003B2F8AF1C984BCB1A23C7C -:10A4A0003943E213CCAFC57CF796D07CD70E7C62E3 -:10A4B000F9CCB6D627D04F6C3B9E1A1DFA9DE0AD65 -:10A4C0009CCEDB8E33BFBCF5F0394B68BFD29EE229 -:10A4D000E3CE707E9CE5FC9894E0BC238BCACA85D1 -:10A4E000E3E7F470FEA32B3956EE57EE3BE5FB2A6B -:10A4F0002AD4EF7D0DCC08393FF46DE31719684F6E -:10A50000AE512F6A2DECBC5B831489EFE15FEDFD4A -:10A51000962559A95C29ABFBB3FDD1EA21D06ED0B9 -:10A52000B912E13DA806C9356D3EECF3FE561FF6A3 -:10A53000EF4AD46649CA39F426F00B32D76FB249D4 -:10A54000D2827C4570F045E2AECDEA0E45B16A1C80 -:10A55000249B5D04D6B545479AC0BF1327B1597BEC -:10A5600010B655469FF3976CF7C3404F29C0F6913C -:10A57000A95BC5EF7EC0112DF8FE16B4B05F663042 -:10A58000B2F70F22B3DC8FC3FCF05DDBE881306FE4 -:10A59000411ADB4FF5A39D9EC6E7D598B627E3B9D0 -:10A5A00055759EC4EDB5A2779D74AD14DF4B51DB9C -:10A5B00059A5BEBBCDEE9A162E1F7D258BE59F4D6E -:10A5C0005F8D97E1B939C62827FB3EA45386F7C1B2 -:10A5D000B69D18639A1146CEF6F69BF10AAC4781F8 -:10A5E0007302F532FF7B151AB1CEA5F103BF2F9888 -:10A5F000F5A8D74361C13197CFA7B6CF798755F674 -:10A60000B9739FBF4E8273679DF2040C01FE1F64F5 -:10A61000DFD5B89A3CA9F7EFBFC84AE5EF4D557FA3 -:10A6200001E74CE468339EB3D972D0B84EB65F9E52 -:10A630001F36F0BA9F1AFFE6CF6627621DE993D94D -:10A64000ACFE07861DBF9B563D05DED3EB8461FD46 -:10A65000D00F1FB4C3EF002D60FDA315B86A0AC464 -:10A66000AB5B47B0F19F6F0A3C0DDF05DB7A07EF6C -:10A67000278FB1F10AEC5D386504C03A568FB9E511 -:10A680003536FEE2F5CE2F803F9159CEC320A7AFDD -:10A6900082EED0B6E87AE751B8FE05C8186D3FEEF5 -:10A6A000EB6C837E05EED6D7F965687F6367DE2B9A -:10A6B000D6FD8728F1E0E1727E5DCD77C5AF5CB94C -:10A6C000DEFF2197D30FB89CBECFEBFDFB78DEFBFE -:10A6D0002ECF7BF782FFE803F9B083E7C3793C1FF5 -:10A6E0006679D7769EF7BEC5EBFD4D3CEF6DE479FC -:10A6F0006FCE271359BD1FBE3B2841DEDB2F6CDE1A -:10A700003B214FF42BA50ED1AF8CCD14FDCA685B55 -:10A71000A22A4F4E53E5C93708FD85C641AA3C79A8 -:10A72000B82A4F16FDCA8DED635479B2B87FFC4547 -:10A73000968DEF27DDAECA97C57DE4201FBBAA47E3 -:10A740002F0ACBC7AD2D8B0E5CCBBECDBFBB7EF130 -:10A7500021E7E3079C8FEF2BFB369F7C8CF9DD858F -:10A76000F384F3F175F9FF62FD6242DEA4B07C2C44 -:10A77000754C53C9DBCC2EF8F84FEAA3F9CA75A87B -:10A78000FF943ED6B6C4307DD42A75A8EFE470F1AC -:10A79000CCFF357DA471C163D9D7A08F6AFFAEBC51 -:10A7A000B7A8C40D9D71028FC7947C690BA5157C59 -:10A7B00077A22141CFBEBBA175F784B843A1D7EFE3 -:10A7C000B259BCD3F8C502D48BC1E0CFC3D0F55584 -:10A7D0003EEED56C2BB6F09E64E440382DED65F16D -:10A7E0004FF4382B3B5F4502F01DAA2BC44DAF66DA -:10A7F000770FC64B5A6B35013ECA068D17BEC34B49 -:10A8000064239EBF6B80380ACE59ABE2A82FB3ED0C -:10A81000CAF7782598F70B3EAFD4F22E9EF3FE4B85 -:10A82000B6730BCE5FE868877DC8C6237ADC67699C -:10A830008C60DF4351C75B1F6667F0F79719FDE037 -:10A840003D805F803F850FC6A2FFFD52F49F1048F8 -:10A8500050784324EB0F647F35C59B14F4D79FBF1A -:10A8600076FE69F8BE6C86B9E74C383F20ADF1C67C -:10A87000B07D4B3FEA973A6EEB32FE55C5697FCE0D -:10A88000747E0472720EFC72773C5FE5D40EECFAB3 -:10A89000FE0D91AE7BD877619C323C57A153A7FD4A -:10A8A000CD6671DC877CBE4EBA287205DFA98909A6 -:10A8B000791F5685BF42AF1507F704E028E3CF5D47 -:10A8C0008FB28E30F2E3BA4ADC7D0EE8A0961F32DA -:10A8D000CEC1DFD70D1FF7E9781C19CAFF61B82E6A -:10A8E0009FC27F327220BC07A3BCBFCEECA1F2EEA8 -:10A8F0004C8CB5CE6AA77A74678B8CEF1F12BE1F83 -:10A90000AEEDE467BE04F6495B2C91D890784F5DBC -:10A910008754C7A9EAF365F9677B0AF04DE75355F9 -:10A9200079E4F5AA3C73902A0F15ED51715CA130C2 -:10A93000BE2469AC2ACFBDF239002DD12ADF1BE23B -:10A94000FBF6920DBEC3A365140AEDE7DF0362F4C4 -:10A950005ED6451EA49CA3FD4BB60DC775EAC75A2B -:10A960006263FCF30A7F1F4A1FCFF8FBF860C58FB4 -:10A9700039B0EE6EF0CF657FEFC921BE4FBCCE631C -:10A98000FCBC4807EFD990CF8BD2F1FC0EB62F78E4 -:10A99000E2B15DEBB161FBAC2713C7ADF138107EBE -:10A9A000DA9387ED531E275E7FC25382709DC78561 -:10A9B000F0A39EA9D8AEF2B8F17A6FADDB0B7F1F82 -:10A9C000B1F74A82E74BD3EBE8F342E89CB692E258 -:10A9D000114247BBD72AC0BD16C70BE393AB6D42EC -:10A9E0007F6245A6D09FE07608F07553F384F1DDD1 -:10A9F0005D4E018E2D2911C67773BA04D8E2982ACC -:10AA00008C3765BA85FEDD370D8B6EBB823E3FE12C -:10AA1000711E013A3CEA711D29C2F7A44A105EE595 -:10AA2000998AEDDC7EDD50AF62B401CC8F6272ACEE -:10AA300060B121BFC5FDBF58AD43EA16327F6C0936 -:10AA40009D4FC097CE27D4277D389FC5E13A22E29B -:10AA50003D55B88F3E0BFDE4043E66A49C64817CAA -:10AA6000EC607E2C7EB7F5119DB53487EAF1479FE7 -:10AA7000B0EFE4C21626096347BFE6718DA99F11A6 -:10AA8000F3C5094F4998DF11C2EE9FDD92E608FD3C -:10AA9000BB504AFBD1AFD977874CBBB7D9403E26D4 -:10AAA000E4CF888D08D97F99E0FFA92801E71B3002 -:10AAB0003882CACD843533F433B382EB53C6CD7EAE -:10AAC0004AACFF06E5DF67E4711CAED3C0C7AC4AF1 -:10AAD0005A87D757655E79BFE60C5FD7291EAF9DB1 -:10AAE000E071F7715E7FFB92C76B6D3C5E3BCAEB1A -:10AAF0006F8779DCFD39AFBFB5F27DAB4F79BCD63E -:10AB0000C2E3B58F79DCBD2A7333FE9D980B9BD8C9 -:10AB1000DF25EA0A9F7B368AF1DA5C9F18AFCD59B0 -:10AB200023C66B77D789F1DACC9562BC36C32BC6C6 -:10AB30006B772D16E3B53BAA45FB38ADA250806F6D -:10AB4000738B75B95BA78A71B7C2A75B5CA29D9C2A -:10AB50005422C6DD5DADF76DFF68DC7702667E15B9 -:10AB6000E20F43BE0B2F9C7BCCB13A0B61FF2697C3 -:10AB7000B86A61BFE6464DE010EC33914F65FC1EAC -:10AB80006413DC3194EAEB85C1E326D842FC8E578E -:10AB9000949FE987C5F311B7DF27D2B5AC52AC77E4 -:10ABA000EA4B44BA3A93C4F36793547E87707FA804 -:10ABB00067BF9322D795FD90C65489EF2DFD5C7F2A -:10ABC000A427EA7364CC1FE17353857EF447C6FE65 -:10ABD000EC7DA5C1FC7D859A88211FC0BEDDEECF2E -:10ABE000D87B0694EC81DEF4FE9B08A3B7DE380A1E -:10ABF000BF23B743C7DE1FD89560762CA55D375DB0 -:10AC000064EF09900E2D9E2373C3FB23A930AF7808 -:10AC10008E2C37A015CE99E955FD89E013AF880F2A -:10AC20003B4FF79FC3879FE3E84FFAE3F988B6F0FD -:10AC3000EF1D74C6712AFF1CBCCEE456B147397EA5 -:10AC4000EF213B5D578E2A5E32F075694CD3F1FBE4 -:10AC500063864F09BE7F9FA7F1C6C277B6C8390D7C -:10AC60007EF7650411EDC2E47157CEC747C58B76F8 -:10AC700061B42D4D95F7DDA0CA0B45BB6020AA3805 -:10AC8000A78D9D4F34B09585F623DD26F78F51DED5 -:10AC9000DF417AD51C5B81E7EFB625F3F751B85C4D -:10ACA0000DE7EB1D9EC4CE2FE6F17A71DE0F8B64AB -:10ACB0000BBD6E385ECCCF312E71601C7B96F12BB4 -:10ACC0008FFE037EE69110FE013F0F8BFC34A8FA45 -:10ACD000E7807CE586C387C9D57F1E1F7E8E529193 -:10ACE0002F73CC55F6EDC2CBD788805386F783DE21 -:10ACF000B14AB82FFD4EA03A00DF89FC319ED5271E -:10AD00001E4A9AA865DF6D719A4752BA17F375E625 -:10AD1000F17DB1460F09405CB2C563C496906A3CB0 -:10AD20001FBD227E512CF8CBC61477229C076CECF9 -:10AD3000DE6D199C1368D0754B0AF71E41B36E087F -:10AD4000FAD7C6E6042D7C577E84D6AA85FB462416 -:10AD500095CB90278E82F74DE20026B81FB6C5E34B -:10AD60000F14E1B950379E1FA2EB2884F8B5C83AFA -:10AD700003FFDE63F32754FE6D101777C37DE3BD39 -:10AD8000DDD9F96B83959D6F2D8E63FBB0390EF67F -:10AD9000FDBE9C24B3C307D3C5B3EFF854D07F974F -:10ADA0005283FE81EABBF07D9F212404B6237F04F9 -:10ADB000F839357F54E71157B4F273736DE1F76BCF -:10ADC000FECCE309E57CFB611E4F7CCEEB3F0779AF -:10ADD0003CB182C7137E1E4F1CE2F1C45E1E4FBC05 -:10ADE000CBE3897D3C9E789FC7131FF07842910B7F -:10ADF000C34A6233C07BB4C904EBF2F1CB245F09D0 -:10AE0000ECB3BB196C98C5F64F7B25D5B90AE2A007 -:10AE10005FE718057239D53B12D6113FBDBD02C69A -:10AE20002524E96D4E3BBC9FB40ADF2B51DE0B9B02 -:10AE3000C5E5E6367731DADD595C4F88BC3617F365 -:10AE4000D33AF1FB71096E5DF0BB49F4FF0C157D3F -:10AE50006F537D57492F317BF1BE6277079141A136 -:10AE6000748FE7748F98C1E90E2F5D85D197359C5B -:10AE7000EE0A5D9A6F1A6661EBA810E2C243F963AD -:10AE80002C206F2D497C3EFEBE8C8B3F6722D70F56 -:10AE9000655E657FF6F1822B9F6FFA888FEB848168 -:10AEA0002FD121F3143CA883EF92DFEAFF6532E84B -:10AEB00049F07D1A07C6E123E5FC3F423E1DE0EF65 -:10AEC0001F28F6720AE1B4523DEF90E7CAEFED1C7D -:10AED0002A18AB83EF764FF6FF12FFDE83415B1D2E -:10AEE0001F7ABEB785E3F750D9BDF877E00229EDA8 -:10AEF000F8BE9AC165B0417CDE2BC9B11CE8179F32 -:10AF0000D456C4EBA12A7FB5B6390EE4AB1FFB368D -:10AF1000E2FF072D97429600800000001F8B08007B -:10AF200000000000000BED7D097855D5B9E8DAE79F -:10AF3000EC3364E484C98326B813A658194E263826 -:10AF40000987B003C1460D7002018284709230C43B -:10AF50008A367632BD8F363B24246110F03EEB8377 -:10AF60004AF080436B3FEF355AEBEB40FB4544E53D -:10AF7000BE673128B4D8DB62982CB7AF03566BC7D5 -:10AF80007B7DFFFFAFB5CED97B7312A085567B0BBF -:10AF90009F2ED65E6BAFF5AF7F58EB9FD63E6DA56B -:10AFA000255903A98C2D0DAFAB645319FB00FFCCC1 -:10AFB00066CCC354632097E11FC7070AFC3FCA341D -:10AFC000753A3EC7279676F64136FEBF9985D3E09F -:10AFD00079E5C7FF83A533B6983507FAE0BDFEC211 -:10AFE000C0281F8CCF6A5C67B17F2EFCFD20273EF6 -:10AFF0008F2C1733F5AC79BC9420F4F78A3AA3F977 -:10B00000E27568EFEA669A671854FE04D08D86F7F9 -:10B01000B14D83E72A4BF34D86792B3FEDD5A1CC7B -:10B02000C974D47B605D0BB33EB5928D843EF33D15 -:10B03000BE09005757A8E8270550EFD2D769B83C9A -:10B04000ECB70EFAFDB0ECBE2C6D721CAEAECDAC02 -:10B050003402F374657DCEBF360DFBBDDF1AC17EB1 -:10B060002E56D30BEB3A31E7FF65669BFA3F3DADB9 -:10B07000ECE6C02818B002FE3786B189EE484E6073 -:10B08000F2C5EB65CC600CBAB495263356C8D8E946 -:10B090007A25EA01406ABA017F53B1FD42133E8F1F -:10B0A000747BB42D0820D353E7C33AD77014B0C8CB -:10B0B000848EA23E58EF9A6E4E37F6A0EB34E2CF64 -:10B0C0000B7F11BF59CDEA6933FE224C3D6DC66F2F -:10B0D0000D33B543DD8D7300BCE581B4916FDF0C9A -:10B0E000FF2E60051F3839FD11BF35A26F52FDE2FA -:10B0F000610CD6C3FC80BCE28BD7B5FC774ED6374B -:10B100008211C3B0A2F8F337578F4B8EE07BC8375C -:10B110005EC157D388669A1BF82A199FE460C9DB81 -:10B1200061692F105FB5B8E27C96836CE63262707D -:10B13000E758C66308EF52731DDF37F4E3E301FEFF -:10B14000958CF3C7CA505325F227FB0CE72F2F3CF1 -:10B1500014E3C4F90FC6A90ABBE27526E8355AC044 -:10B16000097F96943FD6FB6F30FE633BF3E7235F86 -:10B170002DF9829339A15E0DDDB05E5DA344A380FD -:10B18000D3A5A15B889E4B6DFC9D5C6D1DFFAD0D35 -:10B190000534CEAA4A180769B1C1D44EF0ED247C1B -:10B1A0005631DF26942789D7B7B3D97806787C61E2 -:10B1B000F7BABDC82FE71EF0300FAE1BDF05BCD6B7 -:10B1C000730AB2E3691CAE9F6E56A2FB61FCB3BB6F -:10B1D0003DC4776FAF51A20CE9CF7C4FA0BC76077E -:10B1E00032689E734991BD9F87F686AE9480017840 -:10B1F000EB1EDE7C4F18E63D9711A9C3711ABA6E9B -:10B200007618D83FD9F0E6E0B80DCEC07E9862B986 -:10B210000A381D0E25FCFB0628EBBB4DF482FF8E81 -:10B220000614E2FB050E16E94DBD987F92F2149AC2 -:10B230001F11EE31C1BF20C741F09E78D043F0A668 -:10B24000E469344E7D30494F4A473A325DCD077844 -:10B2500032F5B108E75905E413F8EDCC12C540FC0E -:10B2600030800BDF77DF70FD3E94A727C43ACFDE36 -:10B270003F632CF2F3990CDE7EDA9F1CC5759DD6D8 -:10B2800078DDF0A7461F477AA891DCA5697C1D0AE6 -:10B29000F0418380AB4173E84940DF860797DD8545 -:10B2A000746EF06FBB17CBE369469A02EFFF74B779 -:10B2B0009321BE111FDE7C6C2F5987ED76BCFC3AC2 -:10B2C0009043EB41FC8D00BCBDBDAB3D2D82FBA688 -:10B2D0008F45DCA3E378A8DFF9BFEF53F07DC6F715 -:10B2E0005FAF90138599F663E0DFE59ADBA8807184 -:10B2F000D8A1F1C4B7CB7D9CFFDDC59B46E5F06EC0 -:10B30000A931FED0A8BE0DF7F70651AF47BE05BC68 -:10B310002E4779998AF8183E1DF79B9AD5D67D79E4 -:10B32000D3C88DF72F8675AE09BA9813DAD7F855BA -:10B330000B5F57B558F91CD66DA9FBF218D1A17B4C -:10B34000B8E0CF4ECE9F8C85C786A7C4F9E2CB016B -:10B3500007E107A1730D817F3B5E3F6A78388DFC62 -:10B360000AE7CD992C6D6F318C77A61EF887C3C57F -:10B370009C2679A8EFF610DFC3CEEE463C017FBADB -:10B38000ABA6C4F945E2A77E571BF163BDE0BB86BF -:10B390006DC03FE9263EB2E10BD7ACCA79C6C5F90C -:10B3A0008CDA13F0D977021C6E297FF52C5CC79CD0 -:10B3B00017CBB52C89CE2548CFBB6A8C4C1CC52039 -:10B3C000BAEE282D1946FC2EE8A1C6E9E145BAA53A -:10B3D000CBBAC18EE17E9E26EA192DCA9BE505D027 -:10B3E0005FD0C9533E10ED83A6E12DCE37CB475039 -:10B3F0001F4D85FE23043ED881194F4F1C1D3F6F02 -:10B40000D2C479A03A33C7607B3AB3EA3D236CEBF0 -:10B410006785AA3837F839FB80CB3706F7E364B184 -:10B42000BFAF9B374EC17E0F280AED3F9E0AD5C2A3 -:10B4300027AA4D8FC9C97388FDCE90FC4DE7AD5B3F -:10B44000E83349631C2417BFC984035589E3C3CD7E -:10B450008760C3FBB4DE3E68AFF37B035186F0F236 -:10B46000F3A10C88D067E2AFEACA14D66782639E64 -:10B470006F84A5FE71FF0D96FEB76AE32CEDB7E76A -:10B48000DE6C699F1F28B0D4DDCC74AE239C031CF6 -:10B49000EF6E816753BB3C97FB918E8BC53A76B8B4 -:10B4A00023FE30E06BB17F2DD1A3ADF4137ED44BDE -:10B4B0003D7E4E57B7D0279326ACF6911E51C9E575 -:10B4C00027087F910EED38C898389FB96DE7AD5DBC -:10B4D000FEECFA64631EE83D2950F918FB18E93DBB -:10B4E000A9C313EA3776FD0DCE0807F26BB2A0D7D9 -:10B4F0003C672A9D1B5DD55C9FEBCA5DC4F5A5DC4E -:10B500004F125D17887ECC7090DEBA54AC5FEA5F54 -:10B51000AFB532D60747F38E12AE672D0D5EA83653 -:10B52000EBE5B2DC82FD26C5EBC9A17DBA9E40CF1A -:10B530006C13FC95A2F3F6A55EA6E23924DB378AEC -:10B54000F376A938B717821C23DF86B1349DCFDB91 -:10B55000C538DB63FCCAFAF361DD4E013F7B4A511B -:10B56000110F49A2BA8F45B6E715219E0DEAE44CAA -:10B570000D3392EF3F0176A1DF02D1AF2C6F75CF73 -:10B5800067817F3DD56901B42D3CC1FAC7BF54889E -:10B59000FA514AC0A1C5F99DEC0EA88FCCE5FC5E1E -:10B5A00093E90D50B3A11F1B0FE3558BF66A21CF12 -:10B5B000A35833C9C145768C97F3E5E0760CDF7F5D -:10B5C000E47C1EB1AF30E78600F15D98EFFB0EF82A -:10B5D0008B7CB7A4C6CA57CB2243F3596F9ED0AF1A -:10B5E00067B019C46791F5C4171ED167C7D88361C6 -:10B5F00092F7A09391BC0BFB46EA9D47822F12FF66 -:10B600001FC91D50F5D438BF487D7C41C8A947B13A -:10B61000BD9825FBE01C39E21AC87C00FAB954D663 -:10B62000A7E2DE2BF4F2F4E0B2DB7CB0AED78A5FA7 -:10B63000F19D4A6583EAF3767E9F08FFC07D7EF325 -:10B6400084B7FD08C76617345D8FCDBFAA4178B6B1 -:10B6500063BD04FB9FAF2983F6ED49B2FEEE2E6C6D -:10B660007F2299D77FF5CC1F771921A207F14D8A48 -:10B67000C0778AD4CF279BF00678F68ECCA77DC4FE -:10B680006BC3A75D6F770A7DDB69937FFBBC67A502 -:10B69000BC0B3A0CB6EE8BE005D6FBD8D07CFF8B0A -:10B6A0003C3A0F9B2D7C7FF1387DA49FAF10EB7649 -:10B6B000A41CC88A2490DF18FED7BB7E6EB6070094 -:10B6C000CFDF5450AFD5E1EDE99C55701C25F8F261 -:10B6D000EFF17C577619C3118F4EE880E7B80B2C39 -:10B6E000408447CA6312F28113F1DE47ED709E0E6B -:10B6F00028E370905A1FF2A702FD3F40FC5CEE3E2B -:10B700005861B513DDB87E18CFDDCDCA3CE9683786 -:10B7100036EEDF5C88E7983B40FA57F78532A41392 -:10B72000B4EB1E2A2FE8747EFB1D9673E585D23F8D -:10B730009C7F1458B3B3DF19F0C07B1DD800F074A0 -:10B7400086BECD50BF7E77320BE0E2EB22BE796E33 -:10B750000DE5A1EF44C784387C275A597FB92B5E89 -:10B76000EF3F98E4D660B111E35E2FD2E5AD0DED69 -:10B77000539E433B3BE8F1A1DED6BFB1DE40649C63 -:10B780001863F4224EBBD40843FBDDBDE17FCEC37A -:10B79000FDF384CB080C87B27BE3CEBBF1BCD2B502 -:10B7A000CA8A6C807B7FB75A114D60CF7C229FEF95 -:10B7B000AF475EB873FF66F4378C710792609E01E5 -:10B7C000F45F00FDBA5C46168E7FA2AD3D0BE5A38B -:10B7D000ABBE2B7010FBB5790234FF6E6F0D8EDBA4 -:10B7E00095B5D6BFD634BEF70677333EEFBFDEED54 -:10B7F0001E47EB7927CD0FEBE8DE50300279B373AB -:10B800008C7B6C23B637AC631AE8856EBFE142FED1 -:10B81000F2AA6C17EE0337FA2F7C7F06DA439A639D -:10B82000FAC7A1FF7D8148793ED0B1A6E5D43CD8C6 -:10B830000199BB3C63139E3F9D024EB90F49FA0E1E -:10B840008C69F062BFCE4823F7B3F81DF548E78551 -:10B85000631C61DC7F3A436BBC13C5F375E917E3E6 -:10B86000A513FD2AD3104E58D714ECF77E6B04FABB -:10B870000D64B96B12E13122F0E86D5F97D302706D -:10B8800077EEF6FA103F9D4A64573DE0CBC84E0D67 -:10B890003CAE5DFCDE53E23DC91F402792C34F3CE6 -:10B8A0003B7AB7311EF5514E47C08BD7653A179F8B -:10B8B0009E56B626DFE4BFB868DE319D741E742A3A -:10B8C0005CAE9F7A76EA6E03EA8140E46E7CAFABB1 -:10B8D0001B78791AAD732CEAF383C9CF8068EF6CBB -:10B8E000F3D44413C8FFC06A279B348C97D74139DF -:10B8F00071A373AC92003F03590D39D9781E40BB38 -:10B9000003C619D8EDE5253CCF81E76F0EC29F53E2 -:10B91000F2F9793E796AB81DE9CF2647C88FF772E8 -:10B920005E7813D5D94E3FDA171F01FEDDF321E112 -:10B930005F3A0F23F937137F31DF708B5E3AD8FE01 -:10B940001916FB715BE91F9AF0FCDF5AECD13C261B -:10B95000BF9FD4939327737D243CE1B100ECDC6C52 -:10B9600071701D3F2F2BB9FFCF077F13F9FFC23630 -:10B97000FF5FB2AD2EF5CF43F9423F117A70A6B604 -:10B98000333C07ED8B579D8128D03D0B5F1889FE16 -:10B990003125DA976D82F726B78097EB6B0BC57967 -:10B9A000F4A3562F2B9FC06276DB72B18E054DEF4C -:10B9B0003C8676F402A16732243ECC5F3D999FDF3E -:10B9C000D26E5B849D814597E772BB002C2B7EDE97 -:10B9D000382B8B901F1632AB7EB788D9F4B9D55C63 -:10B9E0001F93F6DA0A9BFE60B70BAA6DED3B60CEA3 -:10B9F0007ED4FB54B04600CEF782053B0A00EEBA77 -:10BA0000E0A14D0309F69BE378DEC07ADF68D5DF5D -:10BA1000EC80736753F5D7BD03F0FE56B5D78B7234 -:10BA2000B2B5F2D36928275B6B9D248F475B2BA8A7 -:10BA3000DF6BAD612AFF2B3F23E6FFEA93F601C0DF -:10BA4000B120A0BF8FFB8AD4D3AA2BCBDEEC30D1A0 -:10BA50007751F9AD967A3854F56687DD7F897CE6B3 -:10BA600064CD89FC6E530BA47F45B7F83999F3A9CF -:10BA70004024417F59021FBD67C6576A8155BF3DAB -:10BA8000129C3B6C28BD46AE5BE24BE243B60F0610 -:10BA9000EF6FF2A51DF297C19B7385F0DAE194F088 -:10BAA0000FD63F8C9B5909C2DBB6DC48453A46F2BB -:10BAB0000B00CFD515192FA14FE20D95CBD31B7AD3 -:10BAC0005AD400785E9ACCEDFD945C16453FAE9D4D -:10BAD000CE2915F5F3705FBB14BD93430AD9A14B72 -:10BAE0007425AAC33F6F1176E996C98CECD2B6D201 -:10BAF000AF1D4E2BC478878B897DA672BEC98E4A36 -:10BB0000A9E571881D6E16E8C3F7A6A40636C2F330 -:10BB10006A944394CFB0EBB4D90F0276D069B31CCA -:10BB2000D9F79B145BBCA1AA40E8DFD301EFE3E2A5 -:10BB3000781FCC0E198C4FC07A28C2F3CA8EA77B0F -:10BB40006CF8B1C723C207AAACED9769FFECEF2EE2 -:10BB50007C6924EA1BE54A6002E0E3756C82F79297 -:10BB6000F56728ECB1B940F0A5B0EBAAA55DB70820 -:10BB7000EC7920C111D40B86515C692CFAA5E3EB5A -:10BB8000E3765C20A07FBAA06870388E89F7BAAAE5 -:10BB900012EB0BC7505F98C6CBEBA09CB8686E56F3 -:10BBA000227DE1587123D717A01DF58463BB2B7844 -:10BBB00009CFCDFA02AB28B8045EDA68BD49130A92 -:10BBC000872592BBD7A7457622BFCB7A4A6E332B07 -:10BBD00037F149539EFE4001C535B8DF41CE07E736 -:10BBE000FC21B33E669FEF997C1FC773C5083A37A7 -:10BBF000647929FAA9BE66867CB6D5A5D7609CC0B3 -:10BC0000EE377AA680C727BA73F4266C67A9F9972E -:10BC100018B74DEED7B979A34D7E4B9B5D28EDA8A3 -:10BC20007DD868B20F551FB70F93332F1CF241D345 -:10BC3000DA82C8F388AF5917A286A310E3A90AE9EC -:10BC4000519E4CE622FFC9E5DA6397D9AF7B23DF2B -:10BC50007FBA1AB8DFBD2C4FA57A72C4B99FE248EB -:10BC6000C25F1316CB48D6DF217B6C01E803C23FCD -:10BC7000437AD509E1D70AB36617DA7DA9AEA8974A -:10BC8000E2BE36FF4C4DA6A36F22EC1F35C10BD58B -:10BC90001AC539ADFE9D1A2DE7D028D1EE83724129 -:10BCA00098FB7B96A2BF07C7AF8E76E7E0BE165023 -:10BCB000033AE3F61E9EB7CB1AEF9BF29076F5FCA3 -:10BCC0003DD28F24F546E9AF82F3A57B04D265AE61 -:10BCD000A2910FC0E60FB2FB7FC2C21F63F713D958 -:10BCE000FD42BF2DC8267A483D4CFA6BDE2FB0EAE4 -:10BCF00063FF09E281FDB614C35106F2BDC5C5B2AA -:10BD000076C2F8E9FAB2DB705F7EADEC151FEA1B74 -:10BD1000FF5960F3675EE6FEF663D887CEA0BEF6F5 -:10BD2000E21817EADD55CDF5E437B4CB89BF90EFC3 -:10BD300073C985A99678717F6B8B783FC9C0F3A6CC -:10BD40006ABC3B9A046BAAD2F938972B4F1979FA3F -:10BD5000C8C25164978CC69205C02E99827689908C -:10BD60007BC1DFAC7C143B638E937AC15E4933C3E5 -:10BD700021D67185F3238DCDF35C0A6F3B4A4BBC12 -:10BD80006EF447002C4ECE57BE989F3E07FD3BEB0E -:10BD900035B35E5187F18902D43F158A53C8E7262F -:10BDA0003FB98AFC9B9C19D1C309F6D5E5850E4B9A -:10BDB0009C34E667CF65141792E3A8CCDF46728007 -:10BDC000B22AE17126F0C70B781B259FB380D78379 -:10BDD00071DE6D4EC6F30FB89CC8B8835A1CAEC84E -:10BDE000C6F8F02625601014358750BF5F2DE4C8D3 -:10BDF0002DFC70F678D16A2957CEF5A4A735EEB49C -:10BE0000C6D1EC7131BB7E2EFDFA2A4C82707F5E6A -:10BE1000D2090E78E7D078D847EBFC3BC583E4C362 -:10BE2000CA82BBFC98BFD29914D9558FF1EB1E2F53 -:10BE3000F945BAB00BCA4B1FFC457F7B4FF0D12DA3 -:10BE4000F05E77A193DEEB54783ECBA1319FA3FD4A -:10BE500043F259B7E0B39B0A35EAE7C57D09448848 -:10BE60006572BB56E6AFBC3686EBABEE10CFFF7902 -:10BE70002AF3D0EB65042DCF63C90DC5F358CA0072 -:10BE80003F5304FE7227AC263B764A88E7B14C7ECE -:10BE9000CE6AB7DE9EEBB2D473ED76ABADBEA750E3 -:10BEA000EC7BB6FC95783C6D11E961127EBB5C7D44 -:10BEB000B595C755BE06762B964FB5FAA8FCD75652 -:10BEC0003F95BDAD1AE969CFB6E672BFBBC0FB5660 -:10BED000D7053A17CF65B9290F42FA29A5BFFC3B10 -:10BEE00085DC0FC5421C9E85624DF39C996918E75D -:10BEF0003A1AE2FAE160FBCCE20A6B3C6F49D81ACD -:10BF0000CF5B56638DE77D7AAA7EA010F5AAC9BFE4 -:10BF10007BF551E479117F5A23F0B0E3211E5F9243 -:10BF2000E31FFD02A7BFAC9F1378F83EF207C68F50 -:10BF30000E8A7DF4C1AA5B681FF5E55F965E785CAA -:10BF4000C867CA469F2B00E357F52D77E3386B7619 -:10BF5000C138A9973FCEE609A3B3ACF1864FDE8185 -:10BF6000EF1F8DC51BEEB903E30D4745BCE1FC7324 -:10BF7000CD5F467BEBA642FD27880747A17E12CB0B -:10BF8000F308CF28AA0FE0B922EBF0E770C6E8214A -:10BF9000FDFAE70B13F8F59D739584F6E93B85DC14 -:10BFA0009E86F3EB97F81EF3C6FC6A17789D9F53A5 -:10BFB0006A119FBFFD47AC09C769FF366B7A3681AE -:10BFC0005EFFC742458EF73B3A0FFDF23C0CFF2166 -:10BFD000D1784E4FD558C4F73917CF83B18FA716F4 -:10BFE000B9E5788E227C2733069F5A641A6F07E0E2 -:10BFF000A01FE9A4FAD2288EC9EEA678A7E4A394DC -:10C000003ADF7CCC53000393E13E93F2BC6F7E2178 -:10C01000E6D9FD605CE07136385D7F26F8EBBC90B8 -:10C02000B3B751CE409ECEA29C41791AE50C9E0F2B -:10C03000A09C4179B23540CF7FDC1AA4F247AD3ADB -:10C0400095275A2BA8FC416B98FA1D6BADA1F2F510 -:10C05000D6083D3F5AFEF55B289EF69442795583FB -:10C06000C173D757ADF27567D42A5FEB7659E56B8C -:10C07000CD4E6BBCBCB1DB1A2FAF37ACF1F2552DF6 -:10C08000D678F9CAE69996FE2B9AE65AEACB23B7F8 -:10C090005BFA2FAB596CA9EB455C5F5C125E617972 -:10C0A0006F7145A3A55FCA22164944FF8A22CE9F1D -:10C0B000074305C30686D877DC2DB7FF04F59458EF -:10C0C0005D8D30D4EBDD2D0BE8F9D6A4705D38C161 -:10C0D000F875457CBFEB2C5F1D9EC3D0FF7B8BD3D7 -:10C0E000ACFFAC9F16595464B273DD7E6E97BD3BB6 -:10C0F000FEBD17F1985854FECE4BD7E139D5CF028B -:10C100000AF0950E6A9F1FB6EC22A3CD791DD4AB21 -:10C1100033C18E34ADBBF833FBDA47C3F399EB5F21 -:10C12000983B12CAFCBC485D11DA5115A7DAF1FD43 -:10C130003995792A8ACDD60C467AE9B9096EB27753 -:10C14000EC707FAA48B1C4B3AE749FEE6CB5C6E57F -:10C1500073FC3CFE95E3E7F12EA853BCEBE9699133 -:10C160004F217CF09CE25E5D596B73703F192C8E01 -:10C17000F490A097F42B48B8769472788E8A78C39E -:10C18000107E852F168D1A1CEE73220ED1F5254FC9 -:10C19000C2F8CB3911873827E3100F2D4E18873896 -:10C1A000374FF815A01DFD09E776D7F0725EE390D2 -:10C1B0007108B93ED88F1EA4FD27168710FABEF06D -:10C1C000A3BF3E4DFF5FB88EA63C7D17F67B7F8AEE -:10C1D000BE1BEB474DF150DF68533CB4FC154B3CA4 -:10C1E000F499FCC83E7C6F226E693064BBC1069234 -:10C1F000C6617C367C4F223EFE9722A967F7FD453B -:10C20000F15A535CD5F1C1CDECB2E30297DD2FC8F2 -:10C21000F350EC7A4E0A620486E8C6AE70CE3E5900 -:10C22000183988EBEFC8785EE3F9568EF8FE8187FF -:10C230009F7679F3250B3B15CF2B3CB78E81C4E05D -:10C240003EB33DA399FC2AFD026FF6F28D22414FC9 -:10C25000E61B89F47DB230FC3AD28F3DD7AB511E3C -:10C260009B78CE722FCF5E7DC21DFE09EEEF9D73CF -:10C270009C1ACF1B64E4BF9894EB8BA27E2BF5B085 -:10C280005FE27E49F92803E3DDB0CE76FDC554CCEC -:10C29000FF7E6B8F8A1930EC2B69CC8570877361B8 -:10C2A0007F8375CCF1476E1C6A5FC4041E4790F80B -:10C2B0004271F8A91CC14B43C1E7F6FEAFED796F9F -:10C2C00014EAE55FE9E1F1B0493DABBD0DA6F173BC -:10C2D000A6F37DA73393C35FA72B512D1BE1B9F0C4 -:10C2E000FD19186FD11CE4EF786BC36F8E2F43FFDD -:10C2F00063C8199840F577A9DEAF390A307EFD96FC -:10C30000FFD7C7B1FFA42FAC194DB68EC0C7AA0D79 -:10C31000054F203EEE0B4494E9304F7FE8DDB471C9 -:10C32000A678DA2A858513E93163A673BADDA637C4 -:10C33000DF81FBE66DBA87615E737F9987F0FE95BA -:10C34000598A86F6EE42E475680FEF51C98F0DF8F1 -:10C35000588FEDAF065218CE3B477F46C5FAFB53C8 -:10C360001476DD10E7F015E335F4EE2894C3B790AA -:10C37000FF12C0FF4BB96F0A399AA882DCE723FE8F -:10C380000FA59AFD95929FFEA9501F37BD08FD7F0E -:10C3900091A630E9B98B2EC1871B093F0BBF1AA5A7 -:10C3A0001884E7B1E6EB5982FB0DAF09F9B03F2FD6 -:10C3B0009CCECFC95F0BB998D4F3DEABB7629C7942 -:10C3C000838BF2116E2A0C4F47786276D755DE3791 -:10C3D00064BE5A7F5021FB0DD4699AA71F245005D3 -:10C3E0007A2529C9014E4FEEA7F38AFD0FFAE9C35A -:10C3F000A0DF2AD6DB87FE3EA6EA3B9DD07F73B145 -:10C400008BE8BD6CA52B0DE9128F9F052CF686BD20 -:10C410001C1071B3CE562FE56BF47738B99E0F7FA1 -:10C42000401387461EB767C6948775F8E713228FB7 -:10C43000F493C15B1FC67C9AE30E5E6F08DE7AC37D -:10C44000468C7B8F6D3EBE04E3160F2881360DCBE4 -:10C450007DBB1A30CFA345095440BDAEEFF37E74C7 -:10C460008935747848C73FB56912E989EFFA990FA1 -:10C47000F5C46563B8DC34F6B3A8233B6EE79ECC05 -:10C48000E2F113B463E74DC76D97E3E39F5BFB08ED -:10C490007E4F0B8F9B0C0FF0B86972BF1A884297C2 -:10C4A0008F6F7B87ECE0B0DFAD219E47301E578950 -:10C4B00064A606300E1AF4F3B84AB27EEFF125F006 -:10C4C000DEF07295E7B70D707BB809FEE2391261B4 -:10C4D0008136DC9F465458EDE4425B7C459E6F1EDE -:10C4E000FB7315EC5178DE36DD7ACF6330FFBD2C5F -:10C4F0009F033D02D7F7BC88E77E13F475A4D3B73A -:10C50000415FC7F200E8EBF8FC7BA0AF63D907FA04 -:10C510003A9607415FC7F210E8EB58BE0CFA3A961C -:10C5200087415FC7F7FE0FE8EB58BE0AFA3A3E7F35 -:10C530006E16DF473AB3DCD18D8067EF9F808B01A9 -:10C540002F9D2EF663E42FA3CCA3F17C7CDEAF2BD2 -:10C550006322EDF3FD4AE4138CE781688F633DEDC0 -:10C56000C21F7F85F54DD964873055FBE600F4EF97 -:10C57000F87C76600B54BBDDFCBC1F38CA7CA83746 -:10C580009C5EA24C45BDE9CC7CA55701FDA67FBEB3 -:10C5900042FAC44414BDFCF83E5AF29EB61FE76B43 -:10C5A0004F63821FF7F5E8C07FA71126E2D7B43AA0 -:10C5B000B48F677B643DB90EDBEB5B1461A7A6EF1C -:10C5C00045FEED92FD8DEB7AB07F87AD7ECC21EB01 -:10C5D0004D7BB07E3C365FFD0A1CEF788E6C6FA8F9 -:10C5E000D5E1CC184892F3CD5C89FDFB15D93FAF5E -:10C5F00007EDE43359B2FFDA15D87E2666473FB619 -:10C6000092DA47F1FE93BE3BE211B49BAFF678EDB0 -:10C6100011BE3FC33EA69BE33A2D25DCBF10F39F1E -:10C62000EA8AC57F2AFDF68E94DAEB30EEE6D9C8A9 -:10C63000F3B406B20275785E0FE64735F9F9C98F93 -:10C640003ABB24767FC0EA2FD5159E47EF6311CB06 -:10C65000FD369127EFCE34F9ED84AC5F8EFF50C6E6 -:10C660004BA4FFB0461FDA7F5833CBEA3F947912D0 -:10C6700083F90FE57D04E93F0CAFB6FA071746AE24 -:10C68000CC7F58CBFA5C686F315D2179A9F5F5BE96 -:10C69000341AEDFAB31AF90F9976381ABB7FA0D184 -:10C6A000309A633ADE23E3F5D3772B7EB41FB6DCF2 -:10C6B000AD8CC6F2E4DDCAF5284767EF567C2857F3 -:10C6C000BF98C1EFB7149D0F1CD6705FF53B021CDD -:10C6D0001DE12FE03E1C5E9DA16D41BADEAD0CC791 -:10C6E000FE2B3F93E1C6F303F44B21371F3C8C7CB8 -:10C6F000E54C512CF5C2B1924FF73C8C72317B84E2 -:10C70000E4C3C57BB05EE696EF7F710FCAC9F288BD -:10C7100022FADFBB07E5F0F81CD97F782DF65F32EF -:10C720004E8EB7770F8E3F3B45D61FA4F6EED878D6 -:10C730005FA3F97E882721D5B7EDD1C7C37C55E229 -:10C74000DC323E46E377D6CAF7EFE92983F1568813 -:10C75000738A191F2739273F33BD0F7A3AD4FF5DFB -:10C76000EC030D337EBF02E5E68E58FBEF69BDB5E5 -:10C77000A2BE7AC6937B30DFECEF7E7D7FE5F9ECDD -:10C78000F595AC7FDE758571B9B09F8BCB8BF9BE0B -:10C79000126C7A068F2756DBBCCF89F2887E001197 -:10C7A0007FAA0E237F7B9D943717F687C9EF691FF9 -:10C7B000E7FD195CCFFECC0C6B3CADD3164F0B6381 -:10C7C0003C2D7BF071EA8AF938DD7312DBB34F4FF1 -:10C7D0009BD33A63545C3F4055D00D6529940E2895 -:10C7E000FF3425B26946115EE6E1FE16E9BF5E2020 -:10C7F000F288DB4ABF1C9E83F7928A5D01E1FEEE60 -:10C8000037C777D56DDCFFBF62CE05CA0B5BD3E9B6 -:10C81000D1F6631E4B87C85373A652FC41BDC1BD00 -:10C820008FF679113F8D60BE710ECE33F4BD0DFBD6 -:10C83000FD1943ACF7DDD01617EEDB35E56A9F5BDB -:10C84000C48F79BE9835BE2CE3C56579E329AEDC8B -:10C8500098E9A5BCE22ACC0F41D910F1EE3AD1BF3C -:10C86000B1E58530E2BD7EA793A11E78A5F1E5FA7A -:10C87000B091F539787F41791AD7E76CF1E69A865D -:10C88000277517B41F055C8FC00E225E2EEF85C47E -:10C89000EE1F883874443C5F1ADBFF2BD371FFF422 -:10C8A00074811D86EF8B38B38C4757D9CE81FAD06F -:10C8B000DC74F2D70654B21FD54BDCB3CE29E1F9B4 -:10C8C00068321E7D7886351EBDD5C5FD7FDD3956A3 -:10C8D0007E2B29E1F6EC2471EE1E2C4DEE4B42FD31 -:10C8E0009A79C9CED882FE9A61DCDE40FF84DD6F82 -:10C8F000A3B6AC20FF22B62BC07F4AEECBBFC7FB4E -:10C900006A582F81FE2ADE578175A8A90EBAAF2971 -:10C91000FD3BA886CCCB273FCF49E463B5A58EC6A7 -:10C9200091F7D307F3F3FC6C86D40F7A5DD86F854B -:10C93000FFE51338DF5FECE7117696EC1FD6789EA3 -:10C94000CBF0199A8C5BBAF8FD3DE65A3485FC2190 -:10C95000EFA17CB2C9BD1AC221F7A345C5CFAEC0B5 -:10C96000FD88E9A3D819D3BD08FBBE20F78BD87C7E -:10C970007EFE7EDDB7BEBBC2183978BC2227148B81 -:10C980002FA8419C7FA48C2FE82EACC7CF595850BC -:10C99000D072CED636FD37386763FABD31B616DBB6 -:10C9A0003F6AF0035FCD0E52BE14F7B37DD4E07F33 -:10C9B000A5485F8A7C78ADE7F956517835CEB359F2 -:10C9C000D16B52793030A00C1D17BC0BFBDBE3821E -:10C9D00097F257FCC33F31B47FE24B416B1CFFC35E -:10C9E000E29FF867C029EE93204F4F923C85B83CF8 -:10C9F000FDBDEF7FB0DE57B85CF44693C75D7DFFA9 -:10CA0000C09385916388CF895A6A3D9EE3308F86B3 -:10CA1000F217F37B20DC418BDF634FD335F07BC013 -:10CA20003ACF125DCB395DFF0EE8F65F749EEB5C8A -:10CA30009FF83BE4CBEB8B915EBD7C7D7F83F93F20 -:10CA400046F33FC5F9258E1FAE2799F053DBF4B7A7 -:10CA5000C14F29C1F74D0EDF47809ED5046F80C3BB -:10CA60007B29FBFBCE193C7E02EFADA0F70A391FF4 -:10CA7000DC85FA35B7CBE762BE80B4CB33F2F45530 -:10CA8000D80FF4DC7A3E4F4CCF6D281E35A4DDBCA8 -:10CA9000B67868BB797DF147C86EDE2DF0168FCF72 -:10CAA00044E93E1C9CE41447AE137DB7B42CBEEDA4 -:10CAB0002680FB37807FAC7B703D4ED37AB254B278 -:10CAC0009FEDF7D48E883C08B92ED5593B0CF5085C -:10CAD00089CF23E99A1BEF4335E84A272603CE3551 -:10CAE000DEA175BB750FE91F37FA7D9D187F5DAC20 -:10CAF000F3F5BB9B7C74EF45DE7393F74E1AFAC6D1 -:10CB0000BCEC86F7B680FD3206C65F586EBD876204 -:10CB1000D72F545BBDE5C7D9DB0F99FA3F566CCBD5 -:10CB20001F743E5541F94386427A1713F9840D620A -:10CB30008CB6D23B92FD5C8FD3100F73773ED08FB3 -:10CB40007133B7E1A4EF30FDB655DB7E08442A69A6 -:10CB5000F3BBB4BEDFC0FAC8C8ADE4F1FA4611AF0A -:10CB600067363F8527F9E72EF44F4B3C26DDCFF3A0 -:10CB70003CDCC153E574AFB1764D7F11EF4BFE073E -:10CB80009543C6E47735AAC438553ACFAB5CEA770B -:10CB900058F284EC7E0C95A9B6BCF881974620BF6C -:10CBA000015EBF8CEC91CBFD10C94CA7EF7024B790 -:10CBB0002D1ED687DDCA5D96EFA12C0CDDCBCCF601 -:10CBC00072B28D2F3D367F839D2FEDF4F8818D1E3F -:10CBD0008FAB5C2FED3CE6247F79E783ABBBD17F45 -:10CBE0006E3CE8207FC65999070240A23F7F198B0F -:10CBF000E197F4E5CEE68C28FAE1255D96EDE4F9BF -:10CC000021D4CBE477672C9399BFCFB14CF817EEC2 -:10CC100060BD74BF61251B70A11CAC4257BA13FDE7 -:10CC2000E21A958DCCD8C4087F91EE6C98EFF1E6AE -:10CC30001101F46BF75DEFCA783B97DB1189F4D7EC -:10CC4000785C56656F9BFCFCFFF06B5DAE5FCB695B -:10CC5000D0F7FDFCEE287EDFEF527EAD97453C42DB -:10CC6000FAB5CEEEE4DFD5E817F72AFA5DDAD89DFB -:10CC7000A9D84FE3DFCBE85E761BC2FBDAE6577C30 -:10CC800003B44FB20DA387FE0EC4D4920476E1F72D -:10CC900067309E17973D9085F999275DD6BC5B5903 -:10CCA000CE0FB9C5BDECC88C12935ECC7CB13CCD27 -:10CCB000E212F257F1FBD9D2CFB4B620528ACF6735 -:10CCC0005D60640F7A2A95A882F919A9CA4B8A1661 -:10CCD0009F9FD9F3E5FF1107E3DFB712F8E94FE2B1 -:10CCE00079B3FDD9ACE6D904F4C99EC5CFCFFEBC5B -:10CCF000C4F493EDA097DC83F443BB299D33CBCFE1 -:10CD0000DD43FB133E5B9220CF58D2F7C9D9FA7DA1 -:10CD10009CEEBC9E941FF902D6DB23E19FD0F7EB7B -:10CD2000B639B536C47F9F762488F2F945A70FE35C -:10CD3000DDD73ABE377C46F665C5F77E81F81D45DE -:10CD40007C2FF4C67FAA433D708BB4CB84DEB862DF -:10CD5000B8A90E5B71C931DEFF1B25D3F71AEAE0D3 -:10CD60007AE6FA0377F4A01E29F54CA8AFC4BA7C82 -:10CD70009FB1DBC796815EDBD824E388B7EF453DE2 -:10CD8000373EDF92BDA8079F7559C7977AEA2B25D2 -:10CD9000E57B71BC706CFEF2BD08FF800D7EFADE93 -:10CDA00024D4DF28D1F7A2DE5BCF64BB4EF901713A -:10CDB0007FE27AB25B8FBB65FB27285F607B361F03 -:10CDC000FFD503EB7BF03B691F3678AEF5F857DAF9 -:10CDD0007F307DFFA48BE7071AA09F615E4890F526 -:10CDE0003AB9F0E96E27F07F89AED07EF4EB109768 -:10CDF000D770AA43CCD3D2437C512AF11AA53C8FD9 -:10CE0000C1F8EECE03DF7818D71D87FB1B2B900EE1 -:10CE100031B88DF575E81792701FC5FE30DE8A7B3C -:10CE2000EEF4239C2B627E8DB61EECD79921EB93FA -:10CE3000F6627DB0795786B6F5E0BC2B62F8798052 -:10CE4000DE5F912CDFDF65CD4F317A565AE15A6DA6 -:10CE5000C1E7F70EF4F4205C615F74D368F2073227 -:10CE6000FAFEE71D4D6D94BF1D97A3AD592447FEF3 -:10CE700058BDC72A479F26B8AF365CB09FFA67E215 -:10CE8000F995CBEDC3ABBF6ED82771DDDB145AB774 -:10CE9000E4A35A9F89DFE19C6BD464FD9EBAA6C9C6 -:10CEA00057635E6EE7867FCEE8FC93F2C48C884DB4 -:10CEB0007E2E6FBCF6D41CCA9F00FB4A4F946F7D38 -:10CEC000D70C45FA31E7103E83D26E6652EFB86553 -:10CED000E62893DEA1C5F48E0AEA6FD33B3A451EDD -:10CEE00055A7B86FA2438BDF94E7337E168FD3B676 -:10CEF0008B3CCDC28DE1B5663BFB89D91C9EC766D4 -:10CF0000733994DFAB3DD3A4501E58FBB611E9989A -:10CF10003F7B2AD3B700CFB5FE6C4700AF2E9F14DE -:10CF2000DFCBECFFBC27EB33F0FC44762AD9A927F2 -:10CF30003276A6E13D855301A738679E7B8BFC5D69 -:10CF4000717FA281E78AF417AE9ED94EFEBF3735B6 -:10CF50005E0FCC7EFE2D8AB7E5DAEF7186488F71C1 -:10CF6000DF22BED32BBEB729F5A5AA4D8F7E896CD3 -:10CF700060A1BFC8F3D37EAF13FFB8CCFA57879335 -:10CF8000EB5F7EDECFCF06DA3E30E9DDDE41BEF379 -:10CF90005A23EF11DAF429BB7ECCC4774DA57E9ECF -:10CFA0003CB281FCFAC94DD67EA73A5EAC0CC2FAFF -:10CFB000BA024ECAB3BA3DD7AA474B3DECB68E472C -:10CFC000C90E05BDD0D22EF36B6F67BD1D74FF5B1C -:10CFD0003B7CC8393A6E77B4FBAA484F69C8851ABA -:10CFE000ACE7F8FF284B2B42FD609B13BFF0CA73E0 -:10CFF000EB4DEB807E2EC748DAA7038A62CE076A24 -:10D000007B04E5229E0FC4EB713FFC7D8FE07E1018 -:10D01000F317B37B5659FC9BC632EA1FF38719619D -:10D020006A3FA30AFF97B1EA11DCCFE2FEB11FF617 -:10D0300058FC6346E523C84F32BECA8CFB29AF6F4C -:10D04000A94FC2F3A31EACB7EBFC3CF9E6773C2733 -:10D05000F17B4057DA1FE4F379944316E6FB9DBD5C -:10D06000BDE458B43D5DE875F83D0ABB9C27857862 -:10D070007E5DB99ED7314AE37E2B0FD0475FE95CD6 -:10D0800089FC1ACF5329A6EFA2350E9257322FC42E -:10D09000E5F7F0CC548B3D6ECF4F691471E8C1C6F3 -:10D0A000A92FE571F67EC557CDCF6527C373B9ECBF -:10D0B0008171A9783D55F62B2DE5FBC19FA6E8C7E8 -:10D0C00071FD763FDA59F4A3A1AC0A7FC722C13BB8 -:10D0D000EA4EEB774BCE64F0EF962CDA26BE935EE9 -:10D0E000F197F9CDCECFB4DEAB1F2CFFA1B894EFF2 -:10D0F0006379A55727FFE189645D477C9D83BEE87E -:10D1000017BC281F42E439C83C08772887E76D30F0 -:10D110009E0FD16EF0EFF15DF57B2CD22E290CA77E -:10D1200084F05CA8E1E788E4B3BE991AE7BFF30195 -:10D13000E23FC977D03F23847C5DCDFB979CE7DF3E -:10D14000B790FA45D281933D6DE3E91CBA2E643E57 -:10D15000875263F71EC784129C4347E7EA37F0E71C -:10D1600086C86788DC182A4AF87E762881FD3C79D3 -:10D170006A783C3D8FDDD7D42784FE91FF00D3260B -:10D18000CE3B691C24EF44EA85F5DFFBE94A03FA4C -:10D190007D30475F1032D9AD31FD7280EB3B31BD40 -:10D1A000D2984AFBE235D01B57854C7935D760FCC5 -:10D1B000BB88EF265BF528B4FFCDCF3F6C761CC053 -:10D1C000B791F022E2267FC6FB5B42A678CD5F01D5 -:10D1D000DE5D2193FEFF21C4E75384CF0F2F7C7DBA -:10D1E000045F25A7F7CC99313E7D31311F5C36FFB6 -:10D1F000FFDF90296E6E1AF7083DAF1C3A2E07FD2F -:10D20000DEB0F68BBDFF03F3B843BCFFEF047FAC89 -:10D210005FECFD93F45CF0E75590F3F366FA5E8300 -:10D220007DE43D5AEF783EFEE992D83A7E6B7EFE71 -:10D230000F7FD925F93C6B16E2AB99F3D365E8D99A -:10D24000E366F1FC9608F7D31A52AF99289E0FE0D7 -:10D25000BDD105C8D7A3E85EDE4D38BECEB89D1B54 -:10D26000B34B8CDD7BAD76090C34D972DEEF35DB48 -:10D270001DFAAC7D7B115EE75CDEBFE8BBE9AB70FD -:10D28000FDF63AE825336659F3328338FFA5C6C563 -:10D29000F83FBD678BFF9BDAE7CCB2E42F703D16F9 -:10D2A0008E70AF0768FCC35AE7C806A857CEE27A6B -:10D2B0002CE82109EF6F57CE8AF9132A693E918F26 -:10D2C000712CECA47B80317D8579C9AE8AE953C687 -:10D2D000D7C84F14D7A7FE85F8A954D077D5777B48 -:10D2E000EB049CCBF8FAC53A2EDD7F25F5F7F3FE6B -:10D2F00009DAEBA93D93C3C9520F9F755AE2156C29 -:10D30000BC6374FC7740CA5C4B668D047DE56007A6 -:10D310008F47D5770BFA1ADFDA6BB513B9FC2D17E7 -:10D32000FCDEFADDBE3AE4FFE5EF49789D7CFD3195 -:10D330007F5F1FADFF4DE19748FB5E9F84EFB30415 -:10D340009FC6E1BB06E3B711DD19C74F0D335CA3E0 -:10D3500087C8B3D82CE80FEF75D37B5E0E574D44CA -:10D3600071F1B8CB2917F279DD3196D0DFB473961D -:10D370005BBEBF93DE4F15F66C20F1BDDD87E2F199 -:10D380009387A8BF8FCFE780F31FEBA1C8D1B94027 -:10D390001EFCDE1CD935E17255C7EF2C84831716AD -:10D3A00031D377E5641CBCECFEF1BD680F269727EE -:10D3B00071BBD16BFD7D0ACFDCFB721FD4485AE9EB -:10D3C0003BB54B041354316B5C34419CCBE27791F9 -:10D3D000FE9125B1B85426D9B9EEADFCF7A158B5E8 -:10D3E000358E99DCC2C8CFB5C050A21A8CEFD1AD32 -:10D3F000FE96C8066D3BFABB54D515D0B58BE39AA3 -:10D40000F6DFB998ED657A7A3EE5A37C6FD6A87809 -:10D410001ECAE9EE71A92887763BFAF4607674B7E4 -:10D42000D58EEE9776B47E75ECE8A3B3AC76F4DED9 -:10D4300082F01BC4EFAA4EFBDBC1D29245685FBCF1 -:10D440002BF228061E54D3110FC6367E6FE1948846 -:10D45000F3CB78FF40314BC5DF3B1868F3103E0734 -:10D46000D6644453E0BD74635D25FECE81B4A7113C -:10D47000F3E80793DF27B6DBDDC941A0E7341233B9 -:10D48000B2B7077C3EBACFBCB0437C4742E40B48FE -:10D490007B5BDE7B6F2CE7F7A7D17367FE7D8B8507 -:10D4A000C21E977679DFBF31C59C07B08805289FDB -:10D4B000A09A85A95C2ABE9F58E3639B10A8F7A792 -:10D4C000447E47FCBF87F309DBAED2EF570D6C7B80 -:10D4D000807E1F6AB0FB0C6AA9BCCF60509CF61A14 -:10D4E000D8FB49A5A6FDE332F69B61D45FE572DC6B -:10D4F00086F77C47C5BF1FD12FFCC2DB33B83F6521 -:10D500007C29F737D94BF97D882B3D3FE0FCBCB136 -:10D51000D46AD76BA597777E4EA4F7C4F7294663E4 -:10D520003C88EF4B379572BD404B27BF0A6CD14307 -:10D53000E703044A8788EBB24BE713044B13E41369 -:10D54000FC42E8236B0B22B370FC591718F1AD3D78 -:10D55000EE2FFB1D473F5582FDB659F8DBCA8045CB -:10D560001DF917DFDBFF61AB7E1275BCE3AD15540F -:10D570009E508D34CCDF3A22EEEDC30894CF24F3D5 -:10D58000A2E4B835B56527CF9AF6AB85F31EA33C68 -:10D59000B3F6DCFD871580F394C8F7EA4FF36D47C7 -:10D5A000BFB371947F476A69F5AD27CF9AF60F3BF9 -:10D5B000BC98176580A8DF59CABF5FF76299A76F4B -:10D5C00036C8E1EA6D5C0E576F3BE5427F665D4B06 -:10D5D0003D8B4CA1BC2915E97B6C26FFCEC2C2A0B5 -:10D5E000931926B832F2F486528A7B845713BDE32E -:10D5F00079816BB05EE6D2D331AF5DFA2965DCA0EC -:10D60000B4F467A43FF767309A3FEC67518CBFCF03 -:10D61000D5B3DD03187FF1FBC8AF5A57AAF1DFABD2 -:10D62000EBD847F02487DE2178CA54C0F7F08BF19D -:10D630002DE5A253E0DBB46EC2F760F2BB709E9A98 -:10D6400086F83D82F4827E9BC43EF09A7A21D5977B -:10D6500080EEB1F78265167C7BFC1516BAB5EBE35C -:10D66000D2713D92CEF5A2ED7487F3FB48C7F73037 -:10D67000AF8DE898381FE228D26B12B497727FB44E -:10D68000A4579DC1E9556794713C056F758FA178CA -:10D6900080D28BF7251BCBEB19DA0B6E3D83BEFFD7 -:10D6A0002FE9B7A81CE8678217E4F1E15293DEF98D -:10D6B00067F8D91F2D35E9C1D73A0E00F33D43F382 -:10D6C000D9F372FF4A71888BBFDBC3F7DD3705BF23 -:10D6D000D84BB9EF0E9ADF6C54AE6AFA33E0907211 -:10D6E0008372DBA660FEA4E2423E0BA3FC4E417DAA -:10D6F000EE3F36615CB4C1CF7A712F7C08E508F04B -:10D70000E6AEC870A3FCD47767135FA0FD4FF81492 -:10D71000FBF44BA54C9E5327E97913E78BBF75FCAF -:10D7200007E0B940F0D48AFB051FB2F854564558BB -:10D730009D8DFE597D1F9D2F7D33E5F79A5816F775 -:10D74000935F593CD4A3F3FC3119174D1007D594BE -:10D750003F230E6A8FAF0E16174D1007B5E8EB8307 -:10D76000C541992D5E6A8F83DED63182E2D0B765DE -:10D770003A28FF51EAFD32FEF96AC7D7E97B47AF85 -:10D780004E565846F6C571D26DC23FC650AB33AD4A -:10D79000FF4416FFDEF596315EFA8E28FE719AF28E -:10D7A000F1E07CF07A60DE8E794ED24BABB2F7DBE3 -:10D7B000F1EA1676C965E155C6D9DD1D3CCEEEF11C -:10D7C00033FA3D4D49C7F8F7749FA7DF8B642ACF22 -:10D7D000D3ABCFF5515EAB9D0E9E8EB67BE9779CA9 -:10D7E0007CD3D75129E8EFF15F9C3FA84AF812E4B7 -:10D7F0000FFED9F4BC041DDDCE0D5E14B98BE8A973 -:10D800001D4CC5EF8ADF1670FA342D4E4749D78B71 -:10D81000E9E7A3FD45C6B96F2A0CDF857223BFD3A4 -:10D8200024E97B228BE3F7CC4D2C2ABF4F66A62739 -:10D83000E05FA77B77B96C1FE11FF330A75ECC17C1 -:10D840009E5C837EC7D39D5CE927B992F8D50E1004 -:10D850005DDA9B7D0B507F3A5AEEA2BC9504FC40EA -:10D86000BF5B7B297EB888EEDBF8EF845E29FDEE96 -:10D87000287E5CCF4EC01FD790AE15C14474C57CC6 -:10D8800086BF80AE278AF4C791AE929E3715EA5FB5 -:10D89000995D64965F83DB312CF1F76D9E16792DCF -:10D8A00030CEBFE27BBD686391FF50EFC5FAE21B4B -:10D8B0005973A2EF823D5BC6CFDD5AD6FBD268B466 -:10D8C000FBCE3291B71938ACA19FA6655CC2BCCD26 -:10D8D000E3F86121E8BFD0CFF639C4FEEA30E16950 -:10D8E00040E46FBE89F99B60E7BE3C3B9BD6B10527 -:10D8F000F338E1F92991E7598B63E33CA0CF627CCF -:10D900009EA91186F7D3FB63DF6769A373379E8FE8 -:10D91000F1EB47ACDF67E1F58599B23D356A898364 -:10D92000327F04EDB6B8FD35356A39EF5830628D77 -:10D9300083F27C1D79BE6DD4E7440C731C9455D0E2 -:10D94000F8276B65FF1DD1B2C9E638E8E2A86E8EF4 -:10D95000731AF3A3E638279CAF54977EE8C7FBEE13 -:10D960008FA05E3F796AE43CD25FDE9B870348C7A5 -:10D97000DF9D73FB7DFBD10E07FB00AFE40FAA57C1 -:10D980007FD8CBFF0F02C2B069008000000000000A -:10D990001F8B080000000000000BE53C0D7454D5FF -:10D9A00099F7CD7BF393644226017480A02F01DCAC -:10D9B0005843187E020109BCF9C94F157480A0B103 -:10D9C000207D842CA55D5A83959676EDE6416248CC -:10D9D0008240E8D2EDCFE9CF88D03DAEEE69E87164 -:10D9E0002991D20E6229964A634B8EB14B75B0597C -:10D9F000165BDBA295DAEEF194FDBEEFDE3BF3663B -:10DA0000323128B4C7EE8EC77373DFBDF7BBDFF7C3 -:10DA1000DDEFFFDDC79DC58CB105F03FF3C60C8D72 -:10DA2000B18110FC3911FB7ED380B1955364BF22C4 -:10DA3000669433B6384FF6AB4C6321639D2EB99E86 -:10DA4000590CE6BFC09CD4DF66844C6B2A63C16569 -:10DA5000AA985F4FF05F5A2DE7EF8E0501DE2A8707 -:10DA6000E85B2B628697B10F31D95F4AFDD5C97E3D -:10DA700094FAF732BEFF81F84ED382F58FCD894EEE -:10DA800034C6C3B348AF1E9DFEB787FF3945E233A6 -:10DA9000C5C4F1F73BBEC0EF7AA312C1737EFF0D80 -:10DAA000E0BB86E4E330C7F77D88DFFDC4CF2738CD -:10DAB0007EEF037CDA099F5EC027FF2FBFDF0F2BAD -:10DAC0008D3DB8DF5F808EAFD1B997733AAE60FEFF -:10DAD000A34477809F43E6F8C4A08F311C9FC3E125 -:10DAE000BDE8147264359B28F709D9C77383FE8299 -:10DAF0003372BFCD7A50B3E3BF99F46455119FFFE1 -:10DB0000EBF8A74DAB38D5879F81E72ED7FF06C727 -:10DB1000D3D67F8AD67767ECE712E3CAB1AD846FBC -:10DB20008A5E8BE6F767CC6F14F4151CEB8C5936C4 -:10DB30007E306B3BF1276997AC9D6497065CB2BF62 -:10DB400083F4665709873FE1D8CE18E20FFC3B45C6 -:10DB5000FC9ECAF9F7FF9D1FBF3584BC94717E48B7 -:10DB6000397C6C8EF13B94B3F71BBE707E6A707C7F -:10DB70004AFEFF0AFB15D27E429FDEEDFAA43E0A62 -:10DB8000BFCF9624F93B2908CF2784741AAFDA70E7 -:10DB9000307C3DFCB9BAE511D544B830878D632C93 -:10DBA0009A60B16DB0E7AD2CA632F061D180C97C2E -:10DBB000E536BD665F243C5C5E87E87F83ECDFAAC8 -:10DBC00045E25CD8600CE38B14DEDEB5784E49BCD0 -:10DBD000D9D7D2F05E78CCFB88A03B10B4E9C9B5A8 -:10DBE00086EF0F015F6CF150B22FF8B3EA135F9E1E -:10DBF0008C7C58552AE17E3386705E2C94700FD24F -:10DC0000BEAB92FB7C8FF773E5FC1FD1FC145E0367 -:10DC1000661A5ED6CF28EE92783D766C80CECBE544 -:10DC20008B3D74DD1C689B958005E7F1A10D5B556C -:10DC3000D36E1758AF1E04FF760F4BF649AE5276DF -:10DC4000A097F6BDD6786D0A0AFE083D4DE29960B0 -:10DC5000018BD9F13BCCCFE71AEF6FB30BF7A3DC05 -:10DC60005E7BBEC79DD7DBF82EF560B52FA9DF061A -:10DC7000F300DF7509E707E606EFD5EF0B72BED3B9 -:10DC80006E4FAE9E8EFE1AA2E3357E2E29FBF31355 -:10DC900033DDFE5C317E8F046DFEFCDDAEFFB760D0 -:10DCA000BA9ED9ECCFE348779BD7E1423E9B7E6694 -:10DCB000C400DE65FC2D4EB513420AD9A7A47E56DA -:10DCC000F1F52B76B396DE2CF3AF0F39685EDB539C -:10DCD0006C432FC00DBA2E36476DF3E2413E7E34C1 -:10DCE000A8500BF41D25FE6FE1F89D0AEAB45F9081 -:10DCF00069CC009D6A5831B918F16BFB398707E987 -:10DD0000125B9E9F827741C093FB1C5B96DF18F3EA -:10DD1000A6C69F15FB9C0A723AD0FF133F1FE474FE -:10DD2000A8051BFD085FCD5384FEFC9AF8DAE114C8 -:10DD30007DEB0DF26B03493BF43B92F7956E29970F -:10DD40006F91FECB78FD8DE0FFC4AC85883F638E7C -:10DD500059F675BF253B38DABA84F417EDE2BCAC4E -:10DD6000E4799D43BC475BAF869516E29387C51562 -:10DD7000F01F2EBF6F5F3790525E61BC8A7C3E31D0 -:10DD8000D3F815B6A3C1013E5DA47379203D1FB140 -:10DD90008DBF194CCB072E6E8C221CD8D90DE7F6FF -:10DDA000C26A755C13F0EDCF783E95941FD4DBCF3B -:10DDB00045B67F4E9DCB9F8369F17C38BF12F488B6 -:10DDC0004D7004A6E9C3D779438A9433714EDA23A0 -:10DDD00048474752DF787F57211FCF79DAB956E895 -:10DDE000535E08F77952F097F9C6E17EACFC645CAB -:10DDF0009D0BFE95257F8603FA6BF12FD87F207C43 -:10DE0000CE8972B0A65DB9323DE914F01F4E9EDF97 -:10DE100084D078826BB2B9C27FC06FE0235B096E99 -:10DE20006333C0CDA22F53429C7F5342493E4D21C4 -:10DE3000FC0D0ED731273A0DE1C254E69E9582BF04 -:10DE400046E01D74468F5E0F72D061293ADA557331 -:10DE5000CBDACE12E4ABE60C4C83E626E414ACEB52 -:10DE6000F0977AD1CF3D27F643782E3847F425FE38 -:10DE7000229AC73468E7D66F3A0EE0D8DBD3CD4A92 -:10DE8000C4A32ABA278C642D683C781CDB3BC04CA9 -:10DE9000639CB275D157A221D8A77FBE3380A2065A -:10DEA000D159FF54C0AB41E0A51975AFB2319045CF -:10DEB000B958203E07FDBA37B00D9E37347F64094C -:10DEC000AB803951E750C283C498EC7229C2D58621 -:10DED00012659C6797C1C62DDBE24CF511371CF724 -:10DEE000A4C657DCC8EDD3AA10F0D32677DF17F409 -:10DEF0007D5FF07337E0D05F4E00F219EA0DDBE092 -:10DF000040FE991E8E67BFB5E2B69B81E04B652C43 -:10DF100080A36EA44F4DD19798AC05DC3A898B77DE -:10DF2000E975B0AF38D7D3AD60EBFE0EC05A9C4E4A -:10DF30004D5D5D10B7C9F1E931260B60DC56663DD9 -:10DF4000C4404EC2E61E6702F0B8B1F9F50D18F7ED -:10DF5000AD31DD7A1DA078CF065F0DC6B52B4CC163 -:10DF60009725CE57906E0FFC877C71C55FFD810BA6 -:10DF7000F9BC50611300FE9D113E2EF9E266DA2BCA -:10DF800076BE6819FD2D674B763D639B7F5F287FCA -:10DF9000DCF95BE08FD96CF665A093A9DEA588CF8C -:10DFA000A576C5A796D03407033A5D823F07DA37D6 -:10DFB0003D877ABAC6AF051CC887258CF8D728F6E6 -:10DFC00078AB55DFF50CC4AAE12D7B7A4A00CE3D33 -:10DFD000675486FCEA587D0021E1CF83F034211795 -:10DFE0008EBCAFF66B304FFBACCA703FC947E0B791 -:10DFF0006F2E3C3F3700EB61EA3D55C027D8F70E46 -:10E00000C3ADEB302F77E1EBEDC8A75CD6121F0B49 -:10E01000FDBBFC0E16F7A4E802BA2DC117C7658533 -:10E02000F6D235B9AF236D9CF892FB99306368BB8B -:10E030002DA37F2ACC5B26E5B61DCE13CE6199C1F8 -:10E04000CF439E2B8B707995E7929B21AFEE2A6789 -:10E050004A3EB3C86BE639C432CEE180C6F52471BE -:10E0600046A5B822B1571B53057D6BAF83F418F258 -:10E07000B4C34A01FC11579806FCBF5BE04B3FE07C -:10E08000DB8196C2587749EA3CEE2E3BF127A58208 -:10E09000F159D7A5EC11C32416FA7789DEDD5FB2FA -:10E0A0008A507E3FC47A9DA8D7F762C60CF87C9848 -:10E0B000F95CD86F62016AE1BC5DC8AF037B9FCE9B -:10E0C000473B129FE82C3C5F46AAC2EC7632B34530 -:10E0D0004E9C9774C3E4B8B49F1ED34F76D90B2DD2 -:10E0E000D9698361BFB026E231B3F891F86CF38748 -:10E0F0006807655FF3B530C4E3EBB3A3CF72BBCB66 -:10E10000D74FAD307E84FD83B38C53D87E13E33D6F -:10E11000F00F17430F525EF2F674E334DAB54C3B5E -:10E12000760EED989E9287E519F220EDD820DA312F -:10E13000185A8EFA0A7C63F55767C7CE4939F8003A -:10E14000FB00F207E8F925D97F0DE801BEBC84E7A2 -:10E150003E8361F52DCE8A884CDD07F829023F7C8D -:10E16000AE807D57B6FCF04FCA18DE5F00F3147125 -:10E17000AE9846D6A0DFF87AC0E39982F6C21C4476 -:10E18000BA33F9028ED9497999FFC420CA8D23EF99 -:10E19000BB93CD2C7E3079AE1B9DAF25E9423D82ED -:10E1A000481EE95098E9B88CF4F8008909EF241763 -:10E1B00016C941C75285E8EB28618D68CFDB7168CD -:10E1C0003E63DB972ABDF8FCF170118F97A6F2B879 -:10E1D000707B618B3F00F3B63B613EDAF33293AD67 -:10E1E000989E82FB7858A5F937CF31F2D07141DC87 -:10E1F00047F1928C57E53C5F98C79563C33CCE28A6 -:10E20000AF881685719F7126F11DE2A8B1D4F7C6BB -:10E21000638EEB445D84FF74872D8E1898D4C2D032 -:10E22000BFBB0DEEDF33E9BC219CF4EB3710BCBD66 -:10E23000D2AF1B37227E8BC7FA1AD0CEB900EF7D42 -:10E2400025297F7D68E9E754D896DD122E21FCAAA6 -:10E250009AF7B45D07E71D0C4EF1A27B8F57B7F814 -:10E26000D1EF6D9FC0F996B9EF9630F783736E10BA -:10E27000F304BFA4DFF740F8ED847D30CD77601C58 -:10E2800050CCE3807BC3A5B44EC60330DF72C1BC63 -:10E29000E04DA0A718374FE37032F7BB57F033E5D6 -:10E2A0006F030568AF196B217F1115FEE48556E3F6 -:10E2B000A52110CA81D67A6AC1FEF747C0C00D6A8F -:10E2C000567E200B1D77D63CE041386DC54D1EF4BF -:10E2D0009F1D4698E036AE0EBE3464B3B7DB8BD9D3 -:10E2E00064C4EFAE860FBE3464D3B7FE7C8E2FFAC3 -:10E2F00019CB9D82BB12E504F03D1E74C717034382 -:10E30000DD7E16739750EBD4314F0CEB341E35D6AF -:10E310003213F3F1AA731AD5BF0A5972FE5638DACE -:10E32000703123BF1EF5B7305CE7863ECE8F2E7C62 -:10E330009DE6DF59A532CB8627D89F35145065C49A -:10E340004BBB51C0006EC77C25B60DF068F0AF27FF -:10E35000FFB375512E3D877D09BF3BA63593DF92F4 -:10E36000F15547241220FF7495F1547C76F47EC455 -:10E37000CBE54FDAD507485E5376757398DBD54FFA -:10E38000E173693FF61D7F81ECC77685CBE176E0CE -:10E39000F7B7B3C8C756A107DB0BB3CBCF9785BC84 -:10E3A000BE3D3DDA86F00DF069FE59EF3DDEEC90A2 -:10E3B000F1A6E0E3D5F207F8F12F619B5D067E7CC4 -:10E3C000313C7E381FE0D78EF64295D6E2094543B0 -:10E3D000F9CF11DD47981943381ED64293546F94F4 -:10E3E000A1BF1B0E27CE70DD2A41DFBBB5C7DF8280 -:10E3F000F086DB35E38930E5853AB7A3C22E33D604 -:10E4000023FCEE7BB3DB671C604FB1DE8D8F6CF3BA -:10E410008F8A73EEAB348F229D37E9DEB5782E5D9F -:10E420008AE1F74EC1BAA7D9887ACACA668DB2CF37 -:10E43000568233506A6E88929D5F3ECAFC6D625F61 -:10E4400041675911F911D8F74BB96AAA3F1A5D878C -:10E45000C2C64F11EF3633FA0BD4BBED650EDD5259 -:10E46000A8253DECAECA8929D0CF9965BE887C0528 -:10E4700011319C00BABBEC0D8A8BDC4B148AD3DCC7 -:10E480001EC8E0B2C8F979E16F20D6A07176D6F047 -:10E49000DBEB1D8511477ADE0B2261D8EB171147A4 -:10E4A00013D6E5A53FC3BAC9B7B3C8C545A14FAA9E -:10E4B0007B539ABFCC9CF746D845F39488A84B0869 -:10E4C000FFB7D2CDF32BF663C0CFE65FFB2A437FC5 -:10E4D000203DB098A5D8FCA2F48334627BEEC6BA86 -:10E4E00013D279261D8EA4B328C2D2F605797544BD -:10E4F000781D438D54A6C657AA8CD73DFAD3F9058B -:10E50000F8782264A7D8D008F8ECCF8ACF603A3EDA -:10E5100045117E2E7D954611C203FF3C16DBCE10C1 -:10E52000C85F16FE7E6B46E87AC45363566769C9B6 -:10E530003BC6AD37201CD9B7C5AD7A24DDBE9644A5 -:10E54000B87D2D8D907DCDBE6F85E0DBD5DA87F768 -:10E55000AAF73BF0CF2C7AD49D7832AF02F070BB93 -:10E56000AD4F92BE96CF1A45DFB87E7FF886FE4942 -:10E5700048E751219F68DB31DE30741E8F7C22C258 -:10E58000E53878538CE63D3542FC919C078CC1BA46 -:10E59000DC4871C8FCF71887742F1CC8A338E4CD79 -:10E5A0007D79E8EF9F1A0A658D438E16F74CCA16DF -:10E5B00087F48D1087AC8FF078F5F87FB928AEA876 -:10E5C000BEC0FD7CF5851E15E3898D119DF83E7F4B -:10E5D000A85F35414EAA310E01387D220EC1F914D3 -:10E5E00087BCD9A3225EF32FF4D3BA6AE8631C3246 -:10E5F0007F843804B05051EE0E5777FF0CCF2D9327 -:10E60000DE5315E666BBDC5625FAE93D895CD75D2D -:10E61000B62DCFA4734E979BF86C8E6F6A1D97F73B -:10E62000CC7923C9578DEA2DC3FA4017CB0D201F93 -:10E63000DECA1953C10A785E837171174E05BABBE1 -:10E64000CEE6C52CCCAB3D7CFCD3B963F6612BED9B -:10E650008F47E8C55B3937C4441E6414C0FA4FAB1A -:10E66000467C31F8A1AEA99FF7717A36911E6D16DE -:10E67000BC09EDD1289FBE55C48332FE7A6EA51227 -:10E680007353D2652C590AF3E709F8AE393C3FAC15 -:10E6900055BD346F4719A379B75A17A97E313FE1A9 -:10E6A000D275E8CF4BACE7F9A2FADD937918EFDF2A -:10E6B000A231159EAF6C8FB6917C9E75513DC38083 -:10E6C000FF503F2BCFF412DFF2865C69758E5CB091 -:10E6D00064715BDCE2CAE833757541363B24DBCC00 -:10E6E0003AC4C188C83F2BD88CCBC0974BECC14EE5 -:10E6F000A4CD3D2D74FC51367CBDAC2F6C9C617C4F -:10E7000007E563AA33F1EFDF017EF5BDE6A2F73A34 -:10E710007D7BF7DE5E81758B1E8DEABA329F01CA62 -:10E720008A96613E8B3CA0BAF4E92694CB23F9B2D9 -:10E730000F060DF03E82092BF9BD8F3619B6FEA9E2 -:10E74000C843AFA0DF3B325ECE7F95AF977D2BD124 -:10E7500084F7358E4CE0FD4B11F5518BCE37A1512E -:10E760001EBDE597DE6CF6F1744DBABCDE51B5897D -:10E77000CBEB28EBC0AEBF18C9B22E67A9B9633A7C -:10E78000F0E3C89083EA389067C5313ED838C37C3F -:10E7900019F9B57D90F3F5C86BF7FBF09CDC6313BA -:10E7A0000F64B3F3BF11FE285E1DA3BCAB7BA6C8EC -:10E7B00077D990867E6BF7A2A74E55C03EA7E74F4C -:10E7C0009BA50209C00B0FC6CB72BDBB86E77129A2 -:10E7D000FC9E579BD0FEBCF64A43367DAF8C98BF5B -:10E7E0008FA4CDE7EF45DB7A34E27FD189BA7D781B -:10E7F000EF275EDDD3AFC1F9F6FDC6C1304FE99B0F -:10E80000CEE3FE11F10A005E455784D7DE7959E464 -:10E810000DF072D58C1F8ED74F6A187FEF53617839 -:10E820006A2A87E3C9441D7381B0F739AF7E9EEA37 -:10E830008E7D0907154F2E0DED5351F464FDBB7B02 -:10E84000B0142320B678C9391545CA7C504DD3BBC6 -:10E850007983B969FD7B5BC6A6F5576D9894D24361 -:10E86000F87F79644A5ADFEDFF405A3FC866A7F542 -:10E870001B96DC9A06AFC6174EEBD7F96F4F9BFF7E -:10E88000417D455AFFF6B25569F39706D6A58D57D7 -:10E89000FBF63C84E5A368F94C6D2C23799C897CBC -:10E8A000CD3B63903C6E1FBCDF877211AF8E521E52 -:10E8B0003D90DF5F8CF5EBE79CD9EB0B0FD6A8D230 -:10E8C0007F17A3BF3718CFD7E4FC606922AD2EBFF6 -:10E8D000AE86FBE735354AD63A41A63F967E58FAD2 -:10E8E000E5CCFD33FD6EA6BFBDF3E67D1E5EEFE712 -:10E8F0007E7FA59083B6B29F7A13485703AF2374E7 -:10E900001703BD5EBA8F41FA757CE5DD93F1BD5A00 -:10E910006E9939D65D92F2D7E1B218FB258CE7FAF1 -:10E92000626CCA741C8FB175D3A92EAD85CBF9F377 -:10E930009BC4F3F5D8829FAEB5F12DD3FF063D33CE -:10E940007F50C052F14AC31F8D4801E0775BF3410D -:10E950006D1CB461EF31CD6E874E57FF6ADC087EC7 -:10E96000FA633519FA84EBFA8696BFA31F78B99536 -:10E97000D7DD0FB57A581CE83BDBEAA3F6E7AD7E9E -:10E980007AFE7CAB4E6D476B19B5F1D6008DFFACAE -:10E99000B58ADA675A0D6A4FB4D6537BB2354AF35B -:10E9A0007ED4DA48ED8F5B4D7ABE4BE8E9FB051F5C -:10E9B000A34CD615A2C71D0AF1B501AFEA2EB86067 -:10E9C000A8763B0F7CFD4236BEBE577F12AFEE9D50 -:10E9D000847206FE2AAB3EF5D6C8B83E79DE84972F -:10E9E0008C87317F413991753AC0EF31C4CF8DF5B5 -:10E9F000B9A2ABC7EF88A8DF1C29648DDF1670961B -:10EA0000E5A33DFF4A3444F67CFC4CB2E77EA6A564 -:10EA1000DBF39261F67C2DE91D3B897552AC2FD258 -:10EA20007B8A8C3A4841AD4EEB641D64D11F791D41 -:10EA30006434FA81EE9368B7A4DDBE52BA879DC7ED -:10EA40006CE327C83FE99F87F90F7323F98F2AA149 -:10EA5000B34C7B93E2C43C41CFEE579617A07D7137 -:10EA600023823C4F3758159E3393F701F66D281ECD -:10EA70000EF7E5EA5EF2E73B9271CEEB14C70CF7B6 -:10EA80005FE97CC058C8EEDF810FAFA6FB45CE879B -:10EA90001AF5BB896DE09F8F2418AF93CDE1EFEBA2 -:10EAA000A41F3C7281D7312E694A8CC1D185584B45 -:10EAB000CF3C680F7F8E8D8BC2395B931D810330F5 -:10EAC00035EFE93EDD03F38209736C0E8C57C57395 -:10EAD000685D68C9CC18F61BA2AF937D0A69E97E10 -:10EAE0001223D4A4DFA1225851467F626ABE8AE76E -:10EAF0005B9AEA03DCF5B34DAD16CE65F9C516A6F3 -:10EB0000978B7AAA37AB7FDFA8D8EA6C1A0B7422EE -:10EB10001DDA6776F0F77A19F226F924EB6D320FD9 -:10EB20007F8419BEDA2CF143BB78EF92F9BEE50F72 -:10EB3000D34D7F2DF05DF19DA0F72D6C03E3F723FE -:10EB40001C909F20FFC6B862074A86CBDDC1591FC3 -:10EB50009C5C4BFA6D29D7266FEF51286F177913FC -:10EB6000D3EF73D8F318993765E6470F0B3BBB0B10 -:10EB7000ED2CB40F3B19E55B1D4A6E609F92CA975E -:10EB8000C06FCE40BA16D58AF72FAC651EAF177E80 -:10EB90002E2D5F1A116F91973893E75EEC3B9F978C -:10EBA0003A77AFABC78FF71CBB667EB5B109F936B4 -:10EBB000D343EF399916D7D1EE64D2C37C161B37F5 -:10EBC0003775DE2AD3CE637DB61382197CDFBB1383 -:10EBD000BF040078F901475ADC5350951EB7DD5D3C -:10EBE0002BEDECB5A1030580DE6F4B3C5954D45599 -:10EBF00079FCE911CFDB756E2F18DA3BDBFBF5767C -:10EC0000AFE1F1D9CE7F3B9E8F7B647CD492761F9F -:10EC1000D6C17BBC0ED2EF4E5DEBC2FB1E9D5E8D5E -:10EC2000C737BAA33EDBFD95DDB58AA09BE3E513AC -:10EC300078A9C1E514078DB45FB79017D9CF2D37E8 -:10EC40000DD2473D10C53CB9CD3B4EC1FAA81CFFC3 -:10EC500068AD22E485D797BB445C955BD61B77A053 -:10EC60009C4D583F1BD9E68138E93C3CF794F7525C -:10EC70005CE59DE832B3E1FDCF025E9733504F79FA -:10EC80007FBE8361DEDF5592DD8FFE632D8F33DB28 -:10EC9000F459519C6F015FA629C3E77D5CC8C1434D -:10ECA0004E9043D8BF6BDA5D744FAC6B3223FB5D83 -:10ECB0005A37FDD1ADDE2C72A8DF47E7E7F431F912 -:10ECC000FE3DEDBE449BDED0B816F6D59E6701B47E -:10ECD0001999FAE69CB0BC712DDEB7A8CA0DE0FC0C -:10ECE0001AF5C716F2B123C0A8DEA115367BA8EE2F -:10ECF0005CACD1FD08892FC4EB8FA19D1A4DBE33AA -:10ED0000F181FD48EE463ADF4CFC28949FF50EF366 -:10ED10000BCDC66816783F4FEA55BA7C394791AF9C -:10ED2000D1E849F3AFC529FFFA6CEDA675784F6DB0 -:10ED300027E3E3A76A4394EF67F6AF959EB7693D73 -:10ED40008D782E6D535D247F99EBBB4A385EDD27AD -:10ED5000AAC5BE3E05E57F5755510EDA772F1A6AD0 -:10ED60001B5F9FA930CFD5DAE2A6C2482F8FDB6B9D -:10ED700019C9AF578FFAA6825C78CFA82053C07705 -:10ED8000C7DB7F3CA7BF773EB21E83E4964C3B9720 -:10ED90005BF636F0A54088F518F6703FBF2FB299A4 -:10EDA000E6497EEDBEF1B781F83BF06DCCC2F4FAD6 -:10EDB000D4BBAD3F2975F9E388CF392C07F97C899D -:10EDC0003DA890FF8E18A477BEA45DE5F756C6C98E -:10EDD0002E90837D123925559762F8DE03F5CB64BA -:10EDE00014DFD0CCEBC42B2FA2DB47EB260930136A -:10EDF000F1428D8AF2CFEDEE25F61ADF1F96E1BDC6 -:10EE000015C572909FBD11E51AE69530F34FE7B234 -:10EE1000DCE799EC6B3EB80EDA4975A29E26E8193C -:10EE20008D1F12EFBF94DCCAF820B38E2AEBAC1D05 -:10EE3000A2CE3A5A1D956917896F32FECDACABD27E -:10EE40008D3AD08FB76ED25837F19DC70BA93CDFF2 -:10EE5000CAE375787EFF6E9EA0EBF0D9A45FA4E7AD -:10EE6000D26E65D2F9E4287EB1FB4C7B1EC2694BA1 -:10EE700034517DFE907FDB2905E3DC844B67367DD2 -:10EE80003D9C9FEE373A84FDDB5627EAF0E73EA52E -:10EE9000627D609EDF52F1DE5E5522407EA14DC94B -:10EEA000FEDEA1BB8EFB9B617E22E3FDCC7FE6787C -:10EEB00063AE5296F41FAAA053FA57E08F62D7BBF5 -:10EEC00043F2BE9761E8BEB9A9F8B3FBE98F321DE2 -:10EED000E323BFADEE5B9A65FF617163BA5F5006D5 -:10EEE000F9FD30C9D76E9177B7F9F979CC4102B203 -:10EEF000F801887F3F5B07F254D99F6E6FF2CAD248 -:10EF0000ED4D663CECF6302BD7060FE2E1D63A52D7 -:10EF1000DEF478B6B89E91BC1E2EB454ACFF8413B8 -:10EF200006C3F3D08A4D86E7E1F2BFF37934D6F118 -:10EF300078A1A3AC298A7993AC3FEF5E741BD957B3 -:10EF4000F0A33D75B6BC49DE7778B7F52829AF5AEE -:10EF5000867E66D6A5BA17FE3DD5A1DAFC4D27B14F -:10EF6000AE7408E411F5ED70BE9987F725ADE7554D -:10EF700076401F5EBFCAA44BD6A1C6D78B7B2BE7BA -:10EF80005CF1C5788F7290BFA7D0064DBA7F02F4AE -:10EF9000D07BA279E23D5166DDC9ED6EA1F773F138 -:10EFA000EA9655F6BAB3E45BA390E797AB4DBA3750 -:10EFB000D43142FD4FCE7333C31A87EFC7AB3F4BFB -:10EFC000FCC6CFCD302F97752D7D86F9BD3A98E7D9 -:10EFD000BA68AAE375CCE72C3A87BC7F6224642C1C -:10EFE00057891D80F54F2F7A8AF2CDDF27D8587CBC -:10EFF0007F92CC37359E6FCA3C56DA8D1AF589CE92 -:10F0000052183F7C46A33838EFE9AE5358770F9E2D -:10F010005947399FA1ACCCC37DE43D2689F7D5E69D -:10F02000AB9598AFDADEB748B8DF69ADFF05CAC562 -:10F0300093AD516AFB5A0D6ABB5B1BA9ADD28C30F4 -:10F04000FAA5AA7ECA00D9822118B7E1517516D651 -:10F05000DBCE7F5785F9DFC8B7CAFE68DABCBCB221 -:10F06000C6B479902FFF1AE7697ECE4FD71285EE8E -:10F0700027DC39C81E52F42C76E1FFAE5DCAAFBF63 -:10F080003676A9A89EF29791EC1223BDAB1A14EF25 -:10F090005DA57D12FAF7789D4E7A91D4437CFF4AA4 -:10F0A000FECDA2F59DF8E77CA067CCC7B81D4BDD6F -:10F0B000F3A0EF1B83E2BBEB9B4F2EDA8FF7803A76 -:10F0C0005E94E3CBF71BB67166D534E3F726C73001 -:10F0D0005986B873C7C9F1CDF45DB6F8AE26DC58D1 -:10F0E000583CC052F71F33F9B5AB9EC7EBF27E4DCB -:10F0F00090F1FA9A1CFF64BDC8E3801CACE3C9FB25 -:10F1000013B9237C47F4F17A6E0F3E23F8D4E9E279 -:10F11000F71716677C2F1212FB8EF4BDC836313EEE -:10F12000DAF721ABC47E4D62BFC7E6446FA3738B91 -:10F13000F2EF329AC5F30567626D633068F4B3ACE1 -:10F1400070960B7BFA6C3DBF97ECF21B1A9E0BC0BE -:10F150006B20788DFCBEA61C5F702139DE48E30D64 -:10F160007C7CC10593EA4AF23BBDE5F565FBB74EF1 -:10F170004DDDD3E9C0FA8417BF57E1F79FBE26F0F3 -:10F18000CF6CE5F72A77F9C47D1F3675BF81700C07 -:10F19000FE7DE6EDF5B70CE177C7B0FF06DA5F7CE0 -:10F1A0009FB300E9ADA4E7FF40CF33FE9D81F5F5A5 -:10F1B00093F78BEF7AEE433D612D1CEFE4BF9B602C -:10F1C000CDD96FFF4E6841FDEC66317F33C1DBC0A6 -:10F1D000E7679107218F73F7634DF60AE0B512BC1C -:10F1E000D51CBF5BEA757EDE19728BDFFF139EE2D2 -:10F1F0007BA133D1751EB4E7C97F07C09A4EFB5D72 -:10F20000019F76121C53EEC7C4BD28AE1752FEA54F -:10F210003C7C4BC8DFEC7A45CAD517687DF335A333 -:10F22000FF1B042FE3FBA4D1E828AF887E93D6F917 -:10F2300093F793FF95FA57898FFC9E2C532FBE2787 -:10F24000E8877DFF83CE0BE22FC413F63D742DF6C5 -:10F2500005B87182E349C23D762DE032FDCAEE99D0 -:10F26000FC2FBAA2684270460000000000000000B7 -:10F270001F8B080000000000000B93E16660F8514E -:10F280000FC121486C62F17A76068678160686B937 -:10F29000AC0C0C3540ACC8499AFE5540FD4B81780A -:10F2A0000110CF06E269403C11887B80B81D88655B -:10F2B00080E68903B11010F3023107103303F13FE8 -:10F2C0000E06869F1C08736E03C51E93683708DB05 -:10F2D000F220D8E781FEDF02C437C80887513C3CE2 -:10F2E00070163F03439D00822F2C882A9FCD8F608C -:10F2F000F38A5266971C503F008DFE9C5880030095 -:10F3000000000000000000001F8B0800000000004B -:10F31000000BE57D0B7854D5B5F03A73CE3C333312 -:10F320003909794C20E049483055C0214004A1F505 -:10F330001010432FD78ED42AF5A2774004E49554B9 -:10F34000B1D2AB6D46264050F4060B0A0A3A50A8DB -:10F35000D08246C4962A7A07454BFFB6365A6F7D4F -:10F36000D4F6C6DAEBAB18E28362FBEBEFDD6BEDB4 -:10F37000BD33E79CCC24A0C5DAFB874F77F6D9AF25 -:10F38000B5D76BAFBDF6DA3B1EA884C273013EC68B -:10F390001F96DEE60180E24C3AEAFAAF2EDA3386B7 -:10F3A000FDFE7F3DD11D46A69E4C4F0305602C2BD4 -:10F3B0000713A004E05C1FFB95D59BFCD323BF3D46 -:10F3C000AB08E020A8E0659FD2DAE401FFCCFA396F -:10F3D000F82144B1DCF5D360796710DB25A8DD970F -:10F3E00080B74B5718E5FA70CC800BBF9B3EFA9D57 -:10F3F000F5337473136B7FEC8320B577C22153F818 -:10F40000D00569D1E6E34AEC577BBFB346E42B80D5 -:10F410000D0E02DE29007519780FFDEE7582F77169 -:10F420008DC16B6419DFC7E02FCAC07F10BE9A0F71 -:10F43000C339FC665D06FE938587E6CFF09C6C368B -:10F440001EA9AA0658DB0C8F54B901D634FB28BF7D -:10F45000BA59A7FCCAE608A5498D356170247742E0 -:10F460002AC1501F8AB2FAB27FF65FA0CA67CBFBEF -:10F47000CA755BDE53C4FAA9C9E4B5A061CB278382 -:10F48000F5BE7810C76773F7E2F83E4A1998CF4582 -:10F49000183ECEE455C16F246602A34775D063A41D -:10F4A000D83CCE0CCE9B0E61AC7719E1CD23F07A1F -:10F4B00075D98A4E84F77D560F58BD338253DFC409 -:10F4C0007AFFA7E2FB7C1E1B014AD9F7D5DF6EEA63 -:10F4D00054587F2BCB3CC60A36AF7BD9F8ADA75B1F -:10F4E000F0B85BFB03E2CDC7FE211E6B36F37C66F2 -:10F4F000DEF6FC19C0F272DE15997E4EB6DF61EBC6 -:10F50000FBEEB7DA88D523BFCA7E87417C851EFC17 -:10F51000FCF67B26C3F980DA4CBF729C7EFB65EC5F -:10F5200010636D876D86545AE93D4EB5116D4820C4 -:10F530003F6CD62055C1BF1731B9A81672D1A2CFE2 -:10F5400008205F39E101EB389519BA54177966BB89 -:10F55000189F54472E5EA4205FADB7B4AB049072E1 -:10F56000F3EFCD3A986C1EB734D750BAA3596F4712 -:10F57000B9B9E5237566FBF0DEF2F8DF425FDDEA3C -:10F5800006E2BFC42E48ED50B0BFA61766B3FCDA42 -:10F590005125B53719989FE942FDE0177CBC5631DB -:10F5A0002EA9C4FACFA8807AD0290FB7B8635F46D6 -:10F5B000795833CAA5AC403C577179A876A77D43EA -:10F5C000D9F7B5EB2B473188616DF4599287EAEA98 -:10F5D00061868AF25025E461ECED3ED4873DF35F0D -:10F5E0005ED25E3500201FE913CCD04B3F413ED0A8 -:10F5F000275AF0F519CAC3A9E3AFB63EF96B6DB44B -:10F60000F24D2F2BDF51E53154A5375C85A7A5239B -:10F61000B1E1BDF9ADBA4AF059B46F3E73A62B9B68 -:10F6200053F02A1BFCF6E608F1DDFA6683D29B054F -:10F630001F7A91A7C6B3BCE043281F43F99CEB1681 -:10F64000DC487CE92E4A01CAC9EDC89FE7E0702B6F -:10F650004D7322D3913522CF9648175B03D663F9B9 -:10F6600040CA9B508EFC29CBF7264CD6BEB8869755 -:10F6700037287B13B866DCEEE7E55F56BACDC444A5 -:10F680004BFBC4CDA6599EA9CFF2E97ACDDA1FEB88 -:10F690007FB8051E3844F5657FF39457797F7EDE89 -:10F6A000FE26E52533517EEAFBBF49698B30D30244 -:10F6B000D638FAB9A927BFCE348767C6A9BCF17E70 -:10F6C0003311B496DF6F229E64F938655D22C1EA7A -:10F6D0006F845895C2E85038B329C24C23F0CF4A02 -:10F6E000996EC30A1FC777667EB713BC812A5E3E38 -:10F6F000E2C6E7CC6455A67CB2F2AB04C2EF2F8A17 -:10F700008321EC055C1FDD9CC5981D547ECD2F1810 -:10F71000DFBB4B3D51B23BCA59A68C7D8FC4C1AAF9 -:10F720000FDC11ED35AB3C4B3E64F09E43F0C69AC6 -:10F7300066E68037618557C2D31FFC128EDCFCCA97 -:10F74000C777F255FDA5E37E3591B1BABFC31D451C -:10F75000B3014D282864BF7CF85D53615D965CCE93 -:10F76000686010FD66C2D0DEFD96CE1C08298BDCD9 -:10F77000FFADE95B85798EB7D94A7186CE2C7F853E -:10F78000158FE7887A4E3E94F3F3F49ADF15B6F9B5 -:10F7900081D6168985FA9FDF7A7F7C662CD8BBDEFE -:10F7A000D38A42E3D7CF18F715E0E381B782962CCE -:10F7B000136A33E3155D2CC74B651DAF38766AF1CC -:10F7C000E9944B09AFBF17BCDFB5C17B939BC96FF1 -:10F7D00016FA9F6A78034CBF9E941CD69C981C9E78 -:10F7E000AA7E8BF057C65FEF69903E97E175D98589 -:10F7F0003EB2FBA5FEFBACF15782458C9ECB7E79D9 -:10F80000C52BE7BA30C3F87C4466FC26C520B87324 -:10F81000F17BAEF900A46CFDFCBDE6930BAFA75ADB -:10F820002F9DA8BE5DF19B00A07CADAE8214DA18BE -:10F83000AB0F9F970FACBFD5BF985C8A70785BCF3A -:10F84000047334C0066CC2EC8DD5D2FEB8A8F68421 -:10F85000EC8F9B9AA1BD85D9350F859BC85E5AADAB -:10F8600000B567FB524831BB66CC33DB7DB311FE7C -:10F87000E86D94AE76B3F2207E3FA44F66530854F1 -:10F88000178E62E883D57EF9FDB986A1ECFBCD55D4 -:10F89000EC3B638DD521DE1FFB1EC3FA79D5FC7BC3 -:10F8A0002EB8F26A183C16BCFB3DA978367D59EF9C -:10F8B0007211FCB7A13DE6C5FD8041A93FD01647B6 -:10F8C000A60B0CF118DB2A7AB79BE5E2FB8175D514 -:10F8D0003F4AE3D67A8DB0EB1E3FEFFBD089FAA208 -:10F8E000AACD7461FB28771DDCE6B0BB82C3657EC0 -:10F8F000A03299751070E46FE9B1E32A27A11D17B2 -:10F900001676D0792BCE9D84EB6C4F398CB295CF87 -:10F910005971F624B4DB0A7D4D2F4C64E317327D18 -:10F920009A44D1D10CA509EDFF8B0AB3F2CBBA6989 -:10F93000BE992956BEEEBC61155766D9FF302AD252 -:10F940007C657E40839DAF6F1376EC2DC2AE2D4754 -:10F95000191F2BF88F098B9F57EDD16BFED3B95E22 -:10F960000BD41837225F0E688028DADFEB18FEE22E -:10F97000163AF96BECFAAD50B3CFEB54CD67239840 -:10F9800097B9C6E6EEDF295F1B217E25D62F14EB43 -:10F9900056A026AAC487F73F7FE77C73CDFB2B02D6 -:10F9A0009F6C9CABB38DF359E1A530C8C619F3B772 -:10F9B0001F2780E358D7B113C43B2CDE6EE27E1BB9 -:10F9C0006510F7737E98124DD33EEF7AF2D35D2B1C -:10F9D000FA84F8261DED1C82394BBF5A9527E36F38 -:10F9E000C3FFA9B3F2B3D145A6CB5F7EA7E090A534 -:10F9F000FE7657A8E835DCD49F0D677FAC66DA83C6 -:10FA0000F0076A128E60A14D9F1E6FEE2E38C4F46F -:10FA1000C6CDFA0CD2C7B9C6FB21D3A3692657BB02 -:10FA20009A7D94DEDBAC43DA8B7E8B08A5DF63F234 -:10FA300087DFB7B27D24A6F73447E9FB96E67194D9 -:10FA4000DED56C52BAA9B981D23B9A63546F43F3A5 -:10FA50004C4A7BF0F9211BAF4EAC6FCCCE3A7366AB -:10FA60002AE1423FEE3E885633FCAEC6EF16F8D789 -:10FA7000B9263D4E7232D34F7E8F02E1F70840CA5D -:10FA8000ACC276CFA9B00372CF2B29E67581EAE22A -:10FA9000E36B35347840CACB6EA075AB640A5BB7B4 -:10FAA000185DB582ED85885796A7EF056C3D43FF3D -:10FAB000A07F0AA4FD23A98986ED8B44FBD6A08BE9 -:10FAC000EAADABD168DD73F2C508D0A75561E59802 -:10FAD0008FFCD4BE90C6EB4FE4E3159CCF143DB32E -:10FAE000EB5B751775BA6E0C5F3FFD358C5F2C7242 -:10FAF0005130F50F486928572B691EEBC2535E64DD -:10FB0000DD317ED4CB2A583F77B02D35AE6BBBB6F6 -:10FB1000BFABCFB6D039A8727B7DC4AC773B10BFEA -:10FB2000233426D76C1C757B2085EB0EA3878AF0C7 -:10FB3000E60B0532C2C7E7ADB6406A9B9229D70BE8 -:10FB400038DE47E85113D7B99EEF7EF1DDE84EABC2 -:10FB5000D82E05D16D46A63C24DB99F67621D92E08 -:10FB6000018A86EDD6B37690290FCB7630CAD62E91 -:10FB70002CDBC1B3268DB7D1DECE5F207026E61F09 -:10FB80001E1775C52DFAC15F65BAB8DCD8E9948B2C -:10FB90007F8A40D0E1F184F231E2630ACF2B8AAF51 -:10FBA000F56317FAB3EC721D1E63A71B5459F28C50 -:10FBB0007417A1EC16931DD480F6C6B6D6ECF4DA11 -:10FBC000A0C5A655E3FC266AB6F9493A6DF0093A94 -:10FBD000B606B2D269832EE8B8006C7496F4DA20C7 -:10FBE000E9B52C3BBD36E4A0D70649AFE5F67692E1 -:10FBF0005E1B72D06B83A4D7627B3B492F273DC22B -:10FC0000E3D28A9D6E6D943F55F470EA850E97415C -:10FC1000DF5DBB4D7D12EA871B34DA57438DAEE0C2 -:10FC20007E00CA4F70FD8026C075612DFE2AED331F -:10FC3000368F5D788EC5ECAB39C95727A11D1E5490 -:10FC400064F9A14968876FF3F0FC75C9E393D00E9E -:10FC50007FC4159BAB92BD93021ADF812F6F2C05D9 -:10FC60001B1948A76B4D3F43BE397DBB2B9A3032E1 -:10FC7000F07881E305B7EF1F6759BF72CF43E017F4 -:10FC8000EB0C3D2138BF45706A299A772F382F62D7 -:10FC90007032BBC240FE66FC6BB49E1A38612E5FA8 -:10FCA0002F7AD667C7FED7D9FE8CED2E1BDFD46C1A -:10FCB0000ED8F866D8FA425BBE6AED405BBEB2A5CC -:10FCC000D296376E38C3D6DF9065B5B67CF9E2734D -:10FCD0006CF98173EB6DED7BF10B707ED9A9BE7C65 -:10FCE00023E2B9870E899A7AA283A8BF3B59536F42 -:10FCF000E3A71CE55FF9B666FA18FEB5220FAD431F -:10FD000000D7107E24BEF275487850BF140553E723 -:10FD1000B3F2806E26D02FA0EA26A01DE1D2E39494 -:10FD20007747ECF275211A4A8CFE5FD9A5816F4C9A -:10FD30009FFD9B9FA4FFFEE6E5E417B9BEAB457CA3 -:10FD40005DBD836D97D0DF9360FA71071BD7CDCC73 -:10FD50001C7F18F942F00FE367D42B459A22F6175F -:10FD6000272767D529BBFE19BAD10E7F459B431FB4 -:10FD70009D207F7F56F2DB1FFE364034817ABC3FE8 -:10FD8000FC8DD114A1FF4E4EFE872CB3E3A77CB1AE -:10FD9000C721277F5FFCB5AA20F8A2A91EF112DABD -:10FDA0000C705305DA5DCFEAD9EC0AC92F77CCBACB -:10FDB0002D60B5F7618CC776FE2EC7A1BC9A2DFFCA -:10FDC00079E313A847FB2394E03EA46DAD39E62FF9 -:10FDD000E8BDE1A2CA80753DFFBCCF3F43E76F9FFE -:10FDE00054FB480FBCE5FA6B7916F81DFBB2DEED4B -:10FDF000135C5EE27E97554FB29F1AB4B7821088AB -:10FE0000229E8FFBC323219FED0F7D3C3DD5FBB68A -:10FE10005DB3F8FE26F1725EAA1AF189FA1DCF8D44 -:10FE20005F1E9122BA5FE482DBB17CB88BCAAF0B54 -:10FE300084B7215C5F57E3D76BC508EF9014C55FAB -:10FE400068697D46C8324F6117C9F9E7B28F56B568 -:10FE50005C5B6F5BEFE0E27AF4634A7EBCAB654DBE -:10FE6000BDB03B5AB5CF957D9413CE2D1AD99B9F2B -:10FE70004FFB4885ECFDFCA3D847BFD096AEB0DB66 -:10FE8000470F733A88FA1D2D0FD79F48B9B48F02D8 -:10FE9000418FD8D73BEC971A661FE1795250D82F83 -:10FEA0003529B257FC35296EBFD4487BC6BE7E5D6E -:10FEB0008B066871C63EEAA37FF393F4DFDFBC7262 -:10FEC000ADEFFEA0B48FDAB87DC4708DF1276A0D56 -:10FED000F77BA88EF57D9CFB7FBB7D945D7EFBC38D -:10FEE000DF0668E3F6513FF89B990B7FFFE0F6D100 -:10FEF0006E0DA47EFFFFC43ECAC527FFBBEDA30C59 -:10FF00009DFF36768ED3AE9176C4A9B66FA47DC21E -:10FF1000EC981A0DF51EB3B3D08E39EE6AF7DDCE2C -:10FF2000E6739DCAB03514E356F87EE6062DB6C1D9 -:10FF30004DFE8DB48E76C666D4E763859E45B90FB7 -:10FF40008AB83D2D0A334660FDF866B7E51C420DC0 -:10FF5000A6F59E739BCF111E989D679FBFC08BC453 -:10FF6000C37E7781DCF79C1DE3F3FA31E101D2DC3B -:10FF7000DED2D23E4CFF43AC6FB41E1759F1C1F133 -:10FF8000A3468D14EA03D6FE3FDCC536BCF86C7878 -:10FF900061EB101F0F546ECFC9EF3C0D8CD115F4DF -:10FFA00087B36C07F2EF002C3298BC415BC330D6AC -:10FFB000FF80D8AA6F60FC5CE8E5696F02D3BF03DD -:10FFC0003A674FC7B46578EDE17A562F3FAA5F389C -:10FFD000D5C07515C8AFB8063BA3F3505772D270A1 -:10FFE000718EC3E4F9D995C7853C9B60B7CB5D861C -:10FFF00026FD4995B9E585FD281F7B7BB7CF251FD9 -:020000022000DC -:100000006EAB5C937C5E7D62F2399DCB7582FD4365 -:100010007D51E0E827DFB4AF1321B0E459F98782BE -:100020008F01BEF1998CA7C36D3E03E34FAA5C3AE2 -:10003000C64DE6835E80FC1798A201C659EA45DDED -:100040000974C1F6479716E14747BBFF42CB7EA232 -:10005000C0C3E5B568C6948A95ACDF6363787CFE5F -:10006000009DC7813AE77333CA97D7921FBE8DCEE2 -:100070004D938C9F2AF9FE86CE6FD654EDD5ADEB0D -:10008000D4688FF47338F9832DE175C29E66F851F8 -:10009000AB5C26DA019F963FD44FC81F79D31DE78A -:1000A0004927492F53DCBB3851FEF8B4E349BAF66F -:1000B00096AB1B894F8B66CCF5A1DDBF2A32A3CF4F -:1000C00073D4DE74BD8DE81AA8023395A5FFF33C06 -:1000D0004A26AEC0195F6BD91F39ED75B5B46EE60F -:1000E000D6BEE856E4B4CB78BFFEE5AAF147545E2D -:1000F0009A4EEB804FF4B7C6B82D81FAF318DA0C9C -:100100000C1F6ADBA834EA4FA882E80E5E85E23F46 -:10011000FC8649FB703AEFAECBC0E72977D9C6D34E -:100120008A02F6F3E79909C50ABF7FB987E0F0E1D3 -:1001300078A8A775D6A182F730B87FAFD7FED16176 -:1001400037AC2EAFCD1A67A0FDADF6AB17D9E13DA8 -:10015000E17641CD78CD6247E56EA7C16B167BAAEB -:100160000DF9DDC207ABDCB05F61EB70327231C4F8 -:100170000D96C7A23280564CC7231FD6F2757DA7B5 -:1001800042E7C324D206FEC7CF892EF318D49FCBF3 -:1001900017273CA94113A8BE7162E748C707F3F8C7 -:1001A000A422056CF5EFF778A85F0D62749E7EFCC3 -:1001B00077E747A85F937DAACBC0E1ECF7324FFC0D -:1001C0007E4F31B21D87071B903F621CF70BD0DDBD -:1001D0001CD6EEF8BA19749F28177C9B1CF2B549FF -:1001E000C465416C4C3FF3E2727C9C8DD981F5B5BE -:1001F0005880EE2DB5717B68B0187FC7B219F47DB9 -:10020000C7FABEE57C8BB08FEE42FB88EC1C9DF2FA -:100210003D708978B33B057CF27B8D97C7671D15D0 -:1002200072BFC36706E85EC013D3025F60F255F980 -:100230009C1AC523CCB2356D057D8D3F70AEDD3F78 -:1002400072B2F11D9D9E5011D9D18EF88E5CED6574 -:100250005CC7A7C5CB9D621F53E35D90A4F393F4E5 -:10026000B9249F95428F542E03B2E3062F8694C182 -:10027000EA1ACBDA47A591AF3FFC18AC7C3218A242 -:100280002E20BD600667D7D1BD094EBF36179D53DE -:100290000FBECA93C290B661C20E838DFC3E83BC72 -:1002A00077B1C3175DE1457DD74A961F5426ECF719 -:1002B000440683E57E04D32383D0AE637A6990E35A -:1002C000FBA7A54381F7EF43874D5A9B5FB7B42F38 -:1002D0005320966DFD3BDDCBF9B4ECCAF779FCD722 -:1002E0000D417855CEBF12E9D9568074B86BEEB384 -:1002F00093F0DE49A215A2781765C8727B1C449D55 -:10030000378FDFEB00338DF6F2CAD917773E8A7448 -:100310009D0836FD95456FD479E93E08D71B9BE6CD -:10032000CEE0E9872AF149D53248E13DA3296D4D58 -:1003300007DD2C5FBE1CE8DCBCBC35A1A03FABF2E6 -:100340000688E23083D181C7F255B32065D2FA0521 -:10035000CF45EA68A9A39F0AE4135C775AECF773C8 -:1003600086DC60E78BAA56FB7D9C52C117A50EBEAA -:1003700070F65369B44D4378872E73F17B3B33EDB0 -:10038000F76BAAA0FDCDEFE37C0E05A3C8EF556B7C -:10039000EDE33AFBD720FE75C4CB434B374F3B9D73 -:1003A000D5DFB2AC7E00E265872F964FF7A2F01240 -:1003B00051967D712F7E95F6468EFA19FD99B0C53E -:1003C000333BD3D5D525D7CC61B5D6841240E327AE -:1003D000BE4E7ADD2DE4F589C1F3E85ED7AAA25AB4 -:1003E0008A0B3B8879B4A7CA87955AF5BD1BE3767B -:1003F0000764F22B518F66E1F3E5822F5F077339B3 -:10040000E26194B72982E37ACA4BDE9BCDC663CB07 -:100410009F99CAD26EA137C0E7AB6B7FB5DF6F0A79 -:10042000EAAF894B6C24874527E657B8D21BBF1922 -:10043000C74FD4B36D04EE3F0B219544FA36B5098E -:100440007F7B4FBD36512F81F73B7BEAC5DBC0BABE -:10045000DF64F536887AA6AD5EAC57BD3B453DB04E -:100460008D6BF61AF71E091F58FB8BF6EA6FBBB7A8 -:1004700098C307D6FE8C5EFDED92F0D9EAE9BDEA9D -:10048000DD27FA03DBB8601FB7A77CA44794C72811 -:10049000FEFDF1E2A9C41F878AA736E07DC46B7E0A -:1004A000E6163AE2725AAF55C1570745BD96602D20 -:1004B000D90DC966685DCCF696AD787FB81AEFF1B4 -:1004C000CEA17DBEFC2EE9C7BEEBD9BF5F4DF77E46 -:1004D000E577ADD54F71E4EC3BEDC35A3E52851F35 -:1004E0006EC0143CA76C8DB884FFFBB5A459C5E45D -:1004F000BD4CB3E5D794F3F251ADAF2513789F48C7 -:100500008BD1FD146F041E196ED1233DE37F66F07D -:10051000F3738C0CFCEF3BE07FDF06BFCCFB07F3F3 -:10052000F2B1BE639313ECD795A84BD97E7998AFFF -:10053000B885D6F3CFEDFC5C2DA6669D1FCF67E690 -:10054000C7F3727E67FBD429FF58F3D31DF3D31D85 -:10055000F3D36DF31BEF2B9882FC78A2F373D6BB19 -:10056000D91D8BA0DDBAB2F84764FFAF1C0CD4EFE5 -:1005700004DF8BC91BB19CC97607F56794A2BE1F27 -:1005800005E6085F71FFED9EC62072DCA786787CC9 -:100590002A147BC439702C82FECDB7BCBA889FE385 -:1005A000707A7C3ADF37897CA523CF7EF92BAE9B0E -:1005B000189EC8F7910E3DDFDFBA5651321AD7B5F3 -:1005C000D690A958D7354FCFBA7631AD6B2B23D9FA -:1005D000D735DC36D3BE48AC357734F3F7043688EC -:1005E000FBB12BCB6BA9DE06793F253195F49B5CE3 -:1005F000371FFFDABC860AA61FDF7D8EBF1F71C0C2 -:10060000C7FD3FAB9BA19DBF87E0A3F431D66F9C94 -:100610005538C0EC3D4C1F66F61EA6FB9B2394FE8E -:10062000A8D9A0742F1B17D3FB9BA394EE691E4778 -:10063000E95DC25EDC24FCBD5F2A77D1FAF9BD66B4 -:1006400058AB55A39FD747E93DCDFA5ACD8DF665F6 -:1006500084D23F2B3316FAC85FD199CC67F47AE87D -:10066000D92ABA373EB15C237F076869357F4CE6EB -:10067000BBC4EB9F95FA461FA3D339868BD7F3A54E -:1006800092E1ECF59661BD718646F04030A1868B13 -:10069000B2D6FB16C25157C4E1063D9E0C65EFEF82 -:1006A0003BD85F6D9180AFC84806B3F797C4FECEC4 -:1006B0008A08F822DD8FE765AFD78AFD8D8808F8B4 -:1006C000CA3BEAF3B28F7B0BD62B2D6CA37B3BE7A7 -:1006D0002E06E26F6FB9B1957C15A2DEB6C14DE072 -:1006E000627C5B3AA0AD09EB7DB12906952CAD2C5F -:1006F00089818BF1BFB78895337822A29F097379DE -:10070000F9362C0F59CA45FBF10B5839CB5796DAFD -:10071000CBE578DE3690FA24CD8C50F0AE859EFB8A -:10072000D5982F71F1FC1EDFBF4C41B92F11E74E58 -:100730001D22EF6DB1B72F09F07C1ACBD938256196 -:10074000DEBE53D42F2DE4F3F65FEAA338E17BBE7F -:10075000FDCDB239C333F33DED3BCBBF30C732BF24 -:100760007BBE731395CBF99CD6BC96CA73C96B64D8 -:10077000960B4C8BDE2A691B4EF6A4B40F479D7670 -:10078000717A36A38B3BC6E1EA6EAD6C5951457068 -:1007900025E85C55C0B5E55A3B5C83BF69876BCBE8 -:1007A00037ED700DBEAE6FB80EF8B85ECB051F1BEF -:1007B000DFB48E9FBAD13EBEB1C23E7E6A857D7CDB -:1007C00023F9A9C74F5BE972F7B7ECE30FF937FBE1 -:1007D000F877FF9B7DFC21D77FBAF1FF56F6B8E989 -:1007E0008B7FE413F6AE6AB53B9B1236BB93D57391 -:1007F000F985BDAB5AEDD878C266C7B27A5E51CFE3 -:10080000B4D58BF5AA17F40B7BDC36AED96BDC02C2 -:10081000512FEDB2F617EDD55F8984CF65EDCFE8A6 -:10082000D5DF20D19F69ABA7F7AA6788FEC0362E17 -:10083000D8C70511FF759D88FF2AF070795D1EE706 -:10084000FBEC52882BB8DFD707C0A843B83E0FE5B2 -:10085000EF21154C5D7E1ADA27CAD4E5A7E3FAD753 -:100860005A00B67DDB343FDFAF8DF3AB348E9E078D -:100870004D580EBE44D98596FBAE5B45BD9EF260D9 -:10088000A2ECAB96F22F8BF6ADE2BEE0F96B3A5AD2 -:1008900050CFE88358FD2CFC375DF627CAA128DA33 -:1008A0006132B8375E3663EC4D601DD7CDE13A4D0D -:1008B0008C5B9E1DAED60A3E6E4A8CBBD52FED8D4D -:1008C0004419E151E7A9FC7E7BE89BCA1F197E60B1 -:1008D000BBCFF61E5081A7E9DE0A064772B00BF0C7 -:1008E0007EC2EAF2BEFD392DCD76BFA7A6C7E81EAF -:1008F000F9C0057AAD0AB9DBDDD9E06AC876EE3019 -:100900005FCCA765417D5B15C277C8EEBF650C0E55 -:10091000D67BC89779E2F391CF7AF96F5B7CB67D8D -:100920007E4149DFF7BEE4FDA89E79B08EB2D1EDDD -:1009300056BF38E77A8EF72FEF9B1514BA68DF7928 -:100940006C383F2F80441958EDB18281F53EEBF8A9 -:100950006B1CE3F9618689F6272E53282F9E2A48BF -:10096000E1FDBA40519B5E81EB42A483CE0141DCA4 -:100970007393FDB64466D07EFC98B8FFAA45DA268C -:10098000B9487E047CBAD055629C811B354833BD82 -:1009900076C81DBFD55F6CA59BA920FE8EBB53E416 -:1009A0000F4A5630FA2BBDE7BFC9CFEF8FDD69CCB8 -:1009B000F8554516FADEED376CF70D077EE081F449 -:1009C000E8DCF533F5385C3D7C1B61FC3A82F40AC7 -:1009D000F1ED368FB9CD9F2DCE42EA0771FE3D670E -:1009E0001C881FE392DFB2795C75D80D284FF29E08 -:1009F0008D3C17BA4AF8C7E6083FEC5C8885B1F031 -:100A00006D70D1FDB1B7E1D9F0680BFD1FF3F3F3C1 -:100A10000526E0E4FF92E7BD57B6B96DFEB0F91BBD -:100A2000EDF97930A304F5D6BCF56E48317C5EE56E -:100A3000F097DD27E63B1F9A56A11DB0D2CDFDF2FF -:100A40007374D006B0A565C98FB7D4CD66F92705F4 -:100A5000DEDF627C6358E46D6130E5C1B89B57F717 -:100A60008DBE780260FBD4AA81A86F0B20EB7B704F -:100A700057B4DAE1EB0F7E27BC002B08DE5C706810 -:100A80003B95ACFEAD5FFBEDE789B9E23B64BCC5CD -:100A900031E423AB1FE6F779A924F94779DC457FD8 -:100AA000EDFFDA4FFB25BE4E0FCA4FA3D6D4A0B838 -:100AB00032E7525E77DC1CC4E6E9DE3F293D086C74 -:100AC000F55AFBAED73D15485F32C358CDD45B0A0B -:100AD000AC1ECAE5810B13B67A55ACDED0DCF5BA94 -:100AE000845EFDE9EEEF79701FF7F60F5EB900E561 -:100AF00072D1232AF8D8B85DBB4390A67D4CCA8337 -:100B0000FBB485FBD4ACE7B81429C0F0B0E8FE1004 -:100B1000AD970BF77A53D359FB853F7A7524303C58 -:100B200074ADE87E6A10AEBB3F50F8796AA27324B8 -:100B3000AE6B0B35F8D75896FE2201CE87477E92D2 -:100B400047F78E959D072FA77EDB2F717B2DFA220D -:100B50003FE0A679B17ADC1FB74B495567D127F240 -:100B6000FCEBC82E85C3B7DF9DF2237C3BB77AE24E -:100B70000C8EC69DEF105F4DBE7F4F18F1D0B85F51 -:100B8000B59DE736EE54D3DE9194BEE2A57BA9660F -:100B900050A9437C72FDB874DF12F29F2F6DBFF92C -:100BA0001D358CEDEDFCCDF0124D235E9F57A3D388 -:100BB00031FFE0BD6183A1EAAD8E1D61C42BEB77EF -:100BC000B6271FCF7FED7E6FECFF83C2DEFD31CBFA -:100BD000DD83FCD5D8BE868FB7EF9F5F47FDD2E897 -:100BE00090A3B7F097B2DEE72E66C071EEB273C085 -:100BF00009D9978BF61CBB3BC1C63DB2F74F77278F -:100C000018FC8BFFDF7B775F8F76D0637E1DF5400E -:100C1000E30FFE330C9675F3D2005FC7BA76DDFBA7 -:100C2000FD3B997C74BDE8A5F5A3EBD1D787E03BEC -:100C3000295D0FFCA5C460F5973D7A1EF901963D2C -:100C400034B9B4AFF513F935E5B5C29522BA1AFB3C -:100C50001534CE98A12D52077D9ED8A7829FC1F949 -:100C6000F60B5EBA1FD5C8BE2DAF457A2D21BD8CBF -:100C7000F91B189E97EE5EFD8E3A321BBE13835C05 -:100C800078D90098184690DE5FFDCA17C760EAA6BB -:100C9000F39546E826BDEA6CD7F81CA3EB59B9E9F1 -:100CA000780C3EF4E0E15FE3EE357CDC7646C7701D -:100CB0006F3ABE8DBF8CEF4DC76F39E8780C16DFE9 -:100CC000732716EE1B90F53C589E9F2D79E86B7D9F -:100CD000DA5B522FF487E7050A87EBBC80B92680E0 -:100CE000F2BAF787DFBFB388D3793A434CD79E6314 -:100CF0004380F1C91BEEEECB513F763FEAD571BD83 -:100D00005FF8E8F3246F5D0F3DE331C84E87A0C262 -:100D1000EC8D2EE8F9E940FB63293FAB82C6EDA1DB -:100D2000B4379CA1D7D2D4850D4698BEBF42DF53BD -:100D30005C0E96A60E5EA464A1DFC100BFC70DA91C -:100D400062C2CB92EDBFF540D04E57651CD2F395F1 -:100D5000A9F83D173DE5FC759CFFD916BA6EE7F280 -:100D60009B4B4EBBB67A358C6770D2B94BBC9BD2CD -:100D700098529ECF4677B90E9EECB9EA01A77C8BBC -:100D800079F727DFFDCFE7E4F0F5C38061E31B8946 -:100D9000B7231F66D7FBCF0B7DB1149A1A060EED51 -:100DA000BD0E6A6CE339A82203EF118C7364FC76E4 -:100DB000E4076A2AC1BEAF6A7F82F4B7534F2CCDD5 -:100DC0006167BF21C7DB7F7024EAB3238FFF84F8FC -:100DD00071E9EE573CE8AF796AE7839ECEE119FEF0 -:100DE000C775C1FA7EC691FB0E8E24FD8DFD67A1ED -:100DF000CF31D17FE3017BFF8DBBDFB1F5BF28D1C0 -:100E0000EE21FF6A3FE3BCA59997E07CDFEA70031F -:100E1000BE97F456BBDA90CD0E7A29E0B6C553AD35 -:100E20000AD5BD80FE49B5D063A0FE6BB9D17C3E2A -:100E300081EBE5336EFE8EA566BE80E7D7C9028FD3 -:100E400081FBDE96D0C56058F4789B039F7A913E73 -:100E500009F703FA94D818EBFE4BC25F60BA6CF046 -:100E60002F0B35941A41BE8F33F07D0A2D4AFE694F -:100E7000353CB581EED5EB2EDD9F75DDE6FDB98302 -:100E800031DA77B975171816FE1A35F9E233D1053C -:100E9000A78161DB0FAC9BC2CF83E5FCD70D86CD6C -:100EA000C0F4F03AA5FB30BE439498C6E30BA57D91 -:100EB0000762DF1FC67D7F456F7B0F4CD3407D44AB -:100EC000EAC8E0E39B96FBCD99F85D305C14C71C43 -:100ED000A54D8006718A13F26194C550DC77B55335 -:100EE0001A64EA0DD373F3B85EF24237E56F6BF81C -:100EF000039D7394E6C5C6E41563BE50E1F348D381 -:100F00003E4F5EDF77E59597F5A50F608A76C4EAD8 -:100F10004FF2C266DACFA03BF3E30119BCC8383BFD -:100F2000D9EF3AFF447A1F03E73908DF6BC3C78D57 -:100F30004AF8F9019FB749F96299778C8335F53AF8 -:100F4000B1049368C615F750BCA7D7467E9381D0ED -:100F50004E693974505AE8D3158DE07B99FC5D2EAB -:100F6000F8037C9CE780EF04EC78A7FD7D9D6ABECA -:100F70001867744C8A7DCEFA027B1C523C8FEF13AB -:100F800096E5B964DC73DCBA6F4BC262C281BF887C -:100F90003F4B26DB7D372FBE20CFB29F55831D3CB4 -:100FA000AECCB15F3E4FBD81CE455647FA8EE75A73 -:100FB00029E2C27395B715FB666F05829FFBC114CA -:100FC0001F8FEF36C1D0ADFC88B13D75D67849D3BF -:100FD000F68E8E1BF950453C2728F5A35CB1340FE3 -:100FE000F98AD1E156C18721E8149D7493FF639B70 -:100FF00027BE0AE71BA96A52F8F7B8C2FD65A68AA0 -:10100000F32D11FDBBF21697C5FB9827CC647C62CB -:10101000899B592FE8A269A0056A119ECD82FE4ED8 -:10102000FEB4C7BF4ABB2E28725E1187F7E49867EB -:10103000E97D31AD2848F12FC1312DDF708DC4F924 -:1010400037E9A8578332BE25CAE315E5BEDAF9EEC3 -:101050008BD71117EB16FBF75E71E2623DBE153FB1 -:1010600064B19B9DEBF17D7939DE131A973D1E51DA -:10107000DA699F94FFE5FE73B1AFE3290242372995 -:101080009E53137E8B4917E9E46F3FBA5BE1EF1182 -:101090003AF8E9E8DEFC91A82F519EF15DF33CF1AE -:1010A0005DD97DF020DA572D61300B0A49FF192AEE -:1010B000C3FF2A65944F61E9927DEF3CFD08FAF188 -:1010C0000FA880EFB91D0DCA7350B3008996076B46 -:1010D0006D74FEA4F3EA7D8EC9E5EF6A5DCA5F9088 -:1010E000DABDBB5BA17B622A9C7907BE73D578D839 -:1010F0000D2956FE2EF07EDFDDCCED86F93F7BB06C -:101100008E49026C14F0E0FA655D67063404C0B0E5 -:10111000F04944AE0B09B303DF7F9E2BF0531C2B29 -:10112000B4D593F3FBD39C86C3E4FF89CF23FB158F -:10113000DF11B4F60FC23F62B07FC8974E3C1C77F8 -:10114000C53D40EB4A2C3F4D7610DB4FE3FE23A517 -:1011500044116EA73F65E97E85D6B3ABD87A86EF9A -:101160004B5F9572EC471DEF224BFC3BF9D61D14EB -:101170007C1B84600E3C47D3FC7C96E4EEEA9FF136 -:10118000B8B4ABF728F48E93DA797A3E10DE55F2D4 -:101190004BBD0E4DB7B31526C3DF0EFC792376BCCD -:1011A000FB0D3BDEF36AECF80D45ED7874E2397F18 -:1011B0005CA5ADFE2275B187984FE0BB86FD437CF0 -:1011C000333D49F358CAE691367AE373C18175AB72 -:1011D000D05FD22F1E1DF81BE1C0DF313870909711 -:1011E00042CC5742A24FF32ED3D224574E39947893 -:1011F0002AD73B26D1B76888FCD411D1893297B75A -:101200001BE86BE742551B253994F1C9793DEBEAA0 -:10121000ABF0314BAFB9F0D02B7320B7DCB537FB57 -:10122000A2739950DFD70CD1B9D5785EAE53BA19F5 -:10123000EB9FD5E77A4BE3B921AAD37A22CE4D8E24 -:101240000EE7EF5AB5A7DF2F41FBEFD6DAEE0BD052 -:10125000EE6FBC92C75B7E2FC4D7DF1F8BF4FC9070 -:1012600087F4DD4D311798E82F38A0A614F443E930 -:10127000E6CFCE45BBED80DBA0F54FEF7EFA5FA851 -:101280007CB48EE7CC65AEB651382EAB4FFEFEA3D4 -:10129000075E0D5F61B18FBAF67FF70BB83E6D72D6 -:1012A000C1826CFB80F9413E7E57CD1F4A902D973D -:1012B000F8BA695FBEBAD3EE67F3ECE37EB8A5FB7C -:1012C0002F247BF4D03CFE0EE74347F87DD4A9EAF7 -:1012D000AC7F1AC1F2E3FF53E37A15CCE9B34BA814 -:1012E0000AD133E9677866785C8FF19B28177F74A1 -:1012F000A5F0EF1C8CFF227FE769FC8B7812C68A71 -:101300009AF8BBF18F84A71EC674CA0185FC478D6D -:1013100047F8FA36B6C3EE273A7B0AD30BACFFBACE -:1013200003DCBF55D7C9CF07CE7EC15E6F7CA73D1A -:101330003FA11FFE5D1914FBC830949C4C7C6EDAF3 -:101340006DAE0D72BB8AEE9345B5ECFBAF57437C97 -:101350007FC4F041F33FDA0DD1156C1E47E70E9CB8 -:1013600084F7938EBECFCF1B8E7EA83664DB5F6D75 -:101370000D727ED9E4E1E7C79BE6055337B2793CAD -:101380003E6FE169B8AFFAF3B7E2A7E97DD9254C22 -:1013900045B8684D34F3611CCA470BBFE7066D655D -:1013A000D9DE51967221E544CA47D9BC403C9B5FC7 -:1013B000B45ACCAF7E5E0DC5E3763DA6D01953D7A7 -:1013C0000A06571F784CC08A41084FE3FEF7C84F02 -:1013D000E13B90DDDF7D3018E67CBB2271E30486C3 -:1013E000AF6F32E14EA03C78DA2AB2F59F80F5E487 -:1013F000BFDA19E4FCDCE5E3FB70D0DACAF0BD88A3 -:10140000AEFD93A7AD6270DEC9E40FD7EF4DEE28B5 -:10141000C19D5802F4EE1F887B85E517C0D69B2C32 -:10142000FBB59F07273D1F64F37C3EC8E39306C4CA -:10143000A30AC21DFDE87818FB3FFA8197E83750F0 -:10144000F88B64BB7783DC0E5F1D329F217E595081 -:10145000444A311A0F47E78E06386B3FC3779638F8 -:1014600033691715C6990E1C83EF58BAF87918DB43 -:10147000A7E1FEA311E44F828C54297F78D90DEFA8 -:101480008949BDAB1C50D221A63FC7F88269F4CB75 -:10149000142E70E1DB3BCC1EF5F1FE3AEC762B6AA4 -:1014A00060D4BFA80378D03EDF1F497D2CF5784B70 -:1014B00001D77F2DEB34D28F9BB54E3FFAA52B4C35 -:1014C000A35E33E8FD568AB718BC80CB7BDED02DF7 -:1014D000053D76D10480073E52B3FA47CE10FCB4E6 -:1014E0003A14FF0BE27BE4E1EEC7D1BC8AFA61005B -:1014F000D27BAAB07BC6BFCDF591BC5FD028F625C4 -:101500004E7DB4C92FEC1868FB359EDBFFE48F1AC3 -:10151000DD9FEED13FF3A6D27A0AEAF02790BF26EC -:10152000FC5C6C0F84FE61BB3DC2CBD9BF88271128 -:101530000EA7BE19074C2F29FDEB1D279D9911DE23 -:1015400093C710BED187999C59DA3BF5D4C0905807 -:1015500067859E3A06134BCF3332FC54BB3CFA846A -:10156000D7C23F524F65F829457CE81C47015F4FC1 -:101570005E1F8AFAE5172AFA518E4EE27FFFE709CD -:101580009423468782F753D3901FD61F38DF8F7C72 -:10159000BFF7F0641F8AD5D5117EDF4C3B7851022E -:1015A00004FB58CF95DDE0338235880F17E141D534 -:1015B00059DE32FEBB6D8AB86F69E45F94E55D6CFD -:1015C000995E1DE1F7C9F61EAECCE7FBD134D1BD63 -:1015D00087EF85FF42CA85E477277F4B7948B2566B -:1015E0002E8B1DA12AED62FF68F72324851D91949F -:1015F000EFCE24CAC83E5C26ECC36470D8CD13D9A4 -:10160000AF2DE97A1DCF3D96852A29BE7A5931C77B -:101610009F131F326DFC80D98B9638F846AD9BFC2A -:10162000638D1F786CDF257E73E145E2F71CC4AF44 -:10163000F2C9F17B4EC820FE70E2F9D3CEBFFCEABE -:101640007159EFF1FDA3CC7F02C41FE9247F2CBFA9 -:101650004F22F94DEA8FBA6B5A937946465FC8FB21 -:101660002052EF48FD72F6E2B627F2B2E80FA7DE8D -:1016700088BAF52BD632FC459F0CD23B1D4E3DF26D -:101680003EFE52467EB7BB434C2E1F78EA2D17FA1A -:101690004D1E7A98CD9D95470F4EE17EC18E133B2E -:1016A000EF9276ABB4579DF5A4BD2AD71D79DED451 -:1016B000118AEF09317C29FB993C313C2475BE4FDE -:1016C000FE7930DE8E70E5319803180B5893AEE04A -:1016D000FB59BBBCE692CF3C87FCB5A7355AFF123D -:1016E0006CFDAB567AC321C79F1F12EF0930AE4382 -:1016F000BBA6BC0EF8604BF97B01E523218EEB33D2 -:101700005E2BC5793E2DD6995F85F8FA2CD39F07BD -:10171000633F45F8DD1A24BCB59F1C6EE95FEC08F9 -:10172000994F229E7C0D26CD63900E51B4F7076928 -:10173000ED4A94C151B8D8507A9C3D725D67FD0D59 -:101740009A6E4C42391A84770AB03EDA4759E8F368 -:101750004A88FBC197F83A9F4213BE717A5343B847 -:101760008FF3F5CC3B0851E1E7B2C7811C7DF4F95A -:10177000C178FEF9BB6FBF17C273ADFFD2BA430881 -:10178000E71B37FC3A84F7217E7703DF7F5CEEB0FE -:10179000733E10F8BC241C3B8AF3FDD7E68FEA6C3D -:1017A000EFAF2CE7E73357A554DC94F6F0FBA29D8E -:1017B00079E4DB93F925ED036C79C9A74BBC3C6E4A -:1017C000CB39FFB3C2FC1CFDAADD5B3D830C1C3F83 -:1017D000AE84D9F86F083BEE8D7D21F27F4878E624 -:1017E000EC1EE5413CFCD701AF38F7EF7073FC9B72 -:1017F000D3F17C2E2E48E184F3A9C7F2A8BF2B3782 -:10180000A86477CC66632D67FC1D3F7015EDC39D02 -:10181000F3B8F277C6D45246BF2BD72864AF62FD27 -:101820001B183FC497AFA6733CE73C67271CF12306 -:10183000C2AE70C699CC3FC0CFDFE78271F3C48AD5 -:101840002C712707A6D1B9DBFC7EF63D5561B1EFBF -:10185000A983B3316EFE180CFFF7E146FFFB9E37FC -:101860009A8182C8DE6AF6517AA459A7F428EA4F11 -:101870003C3FDF7FF029E233ADA30EE57EEFE15779 -:10188000F32E35327AFC4B5BDF7BE22E961F0DDCAC -:10189000CF23FDEDB304DECF15FA7CBEB017467F33 -:1018A000D0B73E9F85F818D91B5EA9C767E1DF2135 -:1018B000B4E041EA75273EDE3D3C340FF9E3FCB06D -:1018C000F3BCF9D3E12557BB256AF678462947478B -:1018D000439CAFE76EBF70D540367EF2D1D7877498 -:1018E000723DF11CEA09C9A7004D1E9463273F4AC7 -:1018F0003EE9E1BB03B7109E247F30B98A8873CEDE -:1019000008EE0F9DFCD75F7C5397BB7308EA052751 -:101910009F7539EE43CBF4EB61EE7F9F6B9853716B -:10192000BFCA969B55FC3C90EBA337B4B6A7AE4715 -:1019300079DDCEE565C98FF7FC08F5D0C2FB3784A9 -:10194000510FBDA9B595E0788B77AC0CE3B9FA1BC4 -:101950005A228CEDDF4CA959E31FEF0F2BF2EF75E4 -:10196000DAE224A0357101CAF19F77B8753C076BA4 -:10197000DCE9E5E7EEFB38DE589E9FB7EFCB1E278C -:10198000B1F0DE0D25068FA7B5C74B6C7793FF022C -:10199000FD6B384CAEF3E29EF3E7F6BECFD31BF7F8 -:1019A00089389B7DD3B2C64BC8B804271FDFE3E05C -:1019B0005F861FF2FB25185CE46E17E7E4C95D77CC -:1019C0008C7C85C17764FBCFC3CA70AB3F9E9FC739 -:1019D000BFDB7EC53D3E576EFEED12FC9EB1275229 -:1019E00059E32716BBD361DC572DDEEAA67DE0E282 -:1019F0003D2AE03B78F0A297D6F3457B9EFCCD399B -:101A00000CBE450FB88BA6F369509C84A4574F1C9D -:101A10008BA0CFC2079FE4E7CB86886711745AF486 -:101A2000C0410FC6E538F139B9FDA0A7D311074170 -:101A3000F46A7F652ADD27DC75DC83EBEC9B8F295C -:101A4000F4F7399DED176C7D328CFA02F144710088 -:101A5000826EB9E396D2173C3C86EA91DFAE3F3AFC -:101A600036A32C8E257EBFEF6106C78297BC143F3C -:101A7000B5E0BE6B28CEE875AD89F3FD969525B827 -:101A8000FE2E70274A744AF9F705775F4BFC38FF42 -:101A9000996B4BC47DA432EEEF4994E13CAFDCFC82 -:101AA000359AE73C88133F2ED8A2C6D0CF724C831C -:101AB0008607B2C8CD17F2B9DCBCBECD8B8FE8C0AB -:101AC000EBC2CF997856157F3FD2795EC5DF8B394F -:101AD00026F6DF1F89F5187075B3ECC71AB7AFEE9D -:101AE000403ABD35D82CD5299E404B08BCD1BBEB24 -:101AF000EA33E7950AFD46EFDC483B68327EC7FAD9 -:101B00001D6E7AEFC6D2CEF65ECD32313E833BA05B -:101B10009CC5D292EC7ED099F9522F88F81BC967E8 -:101B2000B9F4C0761ECFF2FE735CCF605C0E957781 -:101B3000B8D3A5B6781CAFEDDE7526CEC42DE4DC97 -:101B40005ECEE0A478991EFC3EA6A4F0FD63C92FEA -:101B5000F3D67BEDF1793DFCE37CAFC71E3F33DF6D -:101B60006197C9B4D7FA9FEF38AFDB7C62F1338B52 -:101B7000DD298A7F5AFCA297F6278BF7B8638897EE -:101B80003FED7EE2379732BEFF53BB9463BBDE75F9 -:101B9000CAF182BD63219B1CFF291885AC72CCBEA3 -:101BA0006795E360E65CC38053AF77E7E7D0BB1788 -:101BB00038F0C9EC867C8C237EEB078B4E237F8527 -:101BC00003BF52DF3AF5E86B6183F0DC3BDE8FAF99 -:101BD000FB99784C8E47C99F0B7FB884C6E9E163B7 -:101BE000C9A7928F73C48D39F1E92C2F44DFD9D85E -:101BF000DE7E91443DD4E0DF674A7A80BFF3E60A97 -:101C000044917FFB3BEF7C36BF42BEFB7616DF176D -:101C1000F2F3CE6850C7BF5401EE2243CD76CE1EFC -:101C20009DECCA6AFF27F2F9B9463EFA2318DE1E78 -:101C3000CE37F8BD0735261C79ED748F81CE56114D -:101C4000CE8230C9995BC4A9B09EE93E7A34CFF503 -:101C50009EC1FAD892FFD4F91AA36F74B4EB9AA17B -:101C60002CFF50FE4BE76BE8AF9DE07AB092E57F2A -:101C70009CFF5B9E3FCB35DACD587527BC7CFE14AC -:101C8000567FA998F752E92769196BF39368AE5705 -:101C90006EC7F31CED61372459FE6626F7BEDACC19 -:101CA00039739E17127E96CFF3B094E55755FC7AA0 -:101CB000156E229F0EC4EFCA277CD51B88E723BA76 -:101CC0008FE27796FDE43C8A237D389FC7BD9FF95C -:101CD000E004FAFB8EA7108EDDF9C5B9E16871F357 -:101CE0007E8EEC3D7332E2F9CCD3D0A796A147ADFE -:101CF00066D0773F437B82DBFD11BCDF922CF05036 -:101D00003F0FE74BFA9D582AE35ED43CCE176ABEDC -:101D1000ABE901961E14FCF0B8C00BFEE0BEFBE878 -:101D2000A3A5DBF8BB56DD4390DEAAFAEEEFD1DEC9 -:101D3000ECBE2C8FFE7EC84B018EB797021C6F97AE -:101D4000E4AF759FC1BED7FA865C834CFF92B2FBAD -:101D50005A4CB7EBF15F723C401AFBBDF47295F739 -:101D60001B6C0AE17B718AC9ED708531D32C868F9B -:101D7000A4098667288AB03DFE43556BBBD3347EE9 -:101D8000C8363E94B37593C9F925E339BD186E6919 -:101D90001D7D7E1CCF4BF866A62A939D06C1F37B62 -:101DA000E48F51DED460DC4F5DCACC2AC8F25E7885 -:101DB00057809F6F7661FB9199F881C6FF76D17E3F -:101DC000B611E7C0F20F1E01F1770AF9BB3BD2EF63 -:101DD00031FE975793FF7BCCFE453CCE44F8BBE4E5 -:101DE000797EDD217E3EE7F46F4D80B5A44FC73B81 -:101DF000F4E884FDFF44FAB5BFF3B9BF48BD3A101B -:101E0000069EE4F91CE896F3B9FF01DBE0C6DF00AB -:101E1000800000001F8B080000000000000BB55A76 -:101E20007B7054559AFF6EDF7E25DDE9F48B100838 -:101E3000869B0448421E36498010706CDE4C8C1222 -:101E400060406418695021E6D56CD6416A748B0EE7 -:101E500041459DB2326A29556BCD5E18DC45496615 -:101E60001B4934BA9D4C0710120437082830AE665F -:101E7000DC1D44973C645670D42AF6FBCE39977E1D -:101E80002428F3C790A24E9F7BCF3DF73BBFEFF7CF -:101E9000BDCEB91E3D7883F900D7E9DF9D91B62A02 -:101EA0005902980EF44F0729000D66FCA5005C3915 -:101EB00091990C385EAF07909D004645865267E4C5 -:101EC000B9B66D38CE14E9BF93ACB0790ACED81F3D -:101ED000001BB5B00E0AA3E6B5F37917CA568012F7 -:101EE0009CFF12A8A60C8069FD392FCFC1BEA1C7E7 -:101EF000002ABD979EA0FBE7746A00459BD1FBBBFF -:101F0000E2305EDA91602B84DBF195A93A50CC6C1B -:101F10005EB88EFF1394445072227D4B8E33A62FF1 -:101F200027DAF64032FE0878FB52518E627E0B9221 -:101F30003CE363E679C7B6A487E42EB66FAC20B95C -:101F4000934B3363E68113FACFFAB19F837FD73384 -:101F500069A995C96194BF082ABD12CAEBF9183C5A -:101F600061947FC6193E4E7BCE130EC83EC4B1F4B9 -:101F7000E3D8EB6510D5C779B67EFC95E348943C71 -:101F8000A5F624F7C53CFC311EC65F9747C5D113A3 -:101F9000269CCEC81E540334F4E22037B65F800A74 -:101FA00088DB34284C0686AB0C2AF6DF04DF0B7383 -:101FB000B0BDB66DD8716472044F8737164FD79293 -:101FC000583CC754C6E23976752C6EE37CB138A50F -:101FD000554D8DB97FDBE6A298FEC4AD6531E33384 -:101FE00002F362FA593BCB63C64F6E5E1ED3CFDE5F -:101FF000B526667CAEBA21E67EDEBEEA5BD27F41C4 -:10200000B021665CBCFE6FEFF855CCBC65F25A1986 -:1020100032233C08E01FF1A088544CFA473D84610C -:10202000A4FE67BA03C4F8BF59FF5B49FF9628FDB9 -:10203000CB6B937DD691F6ABB59A5EFF89D63A9D70 -:10204000F48A73A070D748CF786DC860DD2961EB42 -:1020500040EEACC5EB5BCDFCFAA3029F6B09E92A0D -:10206000ADDF113AF657095B540BB3C3C02716B561 -:102070000979F3A8AC3412AF5E942B254079D25085 -:1020800075BA2CE4910EAAC8AF3CA7D3ADAB8C9225 -:10209000EF793B0E1E43AD8EB5FF6C445BC5F7A6D2 -:1020A0005920602E62CFD1DAE89F1770DD36170312 -:1020B00005FF55EC5C3001EF3BFA731407E02DECA3 -:1020C000DF06702191CB7B2191CBB9C6A434F59367 -:1020D000FF90D5C924CF5EBBEF5FECF89E0BD2E337 -:1020E000067C3318DC0103D95D9A1902367C5F93B4 -:1020F00001D65562DF016EA901DB6478C54EF68515 -:102100006228D7911487ABF392FBF1FAFB24C23813 -:10211000B2318F0E6600DCA7F9C3AA5CE60FAFE010 -:102120001AFB48A17A2519B0BDF26016BB7EFE7E6F -:10213000B442B4A7F3468E8786C325E127BFDC6689 -:1021400066EDE56DF618BF59B5FB852405E7399FA7 -:10215000034B8251F8750BFCBAED32D3E7A0FAE7D6 -:10216000148267E8A1EFA690D07EA9EF492B0E79E3 -:102170006AD73F5402EAC1D8B62C803A815F18155D -:10218000365E9BC71F9A0B84033196E6BBF723D8B4 -:102190004CF2DDFB1DB651EFEBB31BD8737DE27D36 -:1021A000ABB0B1236EAB502F0E6A8FCD5944768100 -:1021B000D7C312F697F68081EC61992FC340F29C49 -:1021C00006CFD97694E78F76FEFE9F41A581E4FA8B -:1021D000F0FEBA241A77633E6D1E14D681F1E42313 -:1021E00047C090827E6BF80EC9B34761EF33D3F5D9 -:1021F000CAB5694F5895C8FB3E04DFC059D4F77281 -:10220000F0B079B5F9D1F262FCE21B55359FBA32D4 -:10221000C91FEAC04CFEB0D3C4FCE150F5B5D69757 -:10222000F0FEBAB4FEDB8CF8DC85EAEFA6102EF7E0 -:10223000ED924141FDFF39C9F739F147C3E3FC8312 -:102240007F49A2FB6B4CEAAB2FA11DC07E93E755E3 -:10225000A0E7F6B3E7B4715FD9E75EB653FC2C454F -:10226000A066DDDC3E35FCE7BF9E3B9678A6F1EB31 -:1022700061C1AF86D7B2C7129F1A926EF08BF75F1B -:10228000CD1A4BFC9A21715EC6CFDB85FC52B27130 -:10229000DDC82B0579D5F5CD3C17F98983279CC579 -:1022A00024A71E7C3A47141F0EBEBF268FEEC339EB -:1022B000F72DC94BB6194039EF052EE749611FAB21 -:1022C00043AE62D23BDA9DCD81E3D6FCC76B037F80 -:1022D000247C3AF7BFFA188D29B9353C34FF7420B5 -:1022E00091C7231071CE2370C13897A3475187201F -:1022F000D143F9C2CDFCD601F20BC8AB6B3A747C6A -:1023000059E4AF2A81FC82053C0AB5E865DE9B8D65 -:102310007A6CEAD6C133D8B59153D3FC4F29F66510 -:102320009DF03FE035A7621C11FE29E737EA921DB8 -:10233000CC7EBCD6F533984B6472951CA9AEA0F741 -:10234000421FFA7194B512FF281ECC86CD87135018 -:10235000CE19BB303FC07133CFF1FB9A5F9F15D6CA -:10236000AD3726D3B85F7F25DB08A2D83830FB48CD -:10237000F9E734EF6C887A6E94F830C711971FDC58 -:10238000627C584C0100710FE670FF1E0C27AA8179 -:102390000C366D716501BA26B43DBAFFEF6E1E476B -:1023A0008CD2608E19FDF05DBFD9B373E71CA4C356 -:1023B000248E0BF59BF4844531E3F18DBCF1C854B8 -:1023C000E60FE17B948AF0B20B99E3E42941BBE389 -:1023D000C1D8139377868F7E6BEBC775B43A95FFA0 -:1023E000247D0D635E437E2141DF6F748CB2BE3766 -:1023F000C9BF22FF9F77E898BCE60EC9ABE2FBCDD0 -:102400008A17245C4382DD3E4D9622E3173A78BE5C -:102410005B77F442BA11F535A03B61CBC7F96BDBB2 -:10242000DFB0E1F2618BCD57457CAE39FFC10C0ABC -:102430005D00BBD32B9308A7CC64B2A7023D04F484 -:102440004523E5F0EFC2C520E5EB77B9589BDB21CA -:10245000B1F5F9C37C9D831D4DCE68BF71E3B93FD3 -:10246000748E27BDED1F03ABC91F17848A37118FE8 -:10247000491603EAE2F56FF2D87CDB1C194C2FF801 -:102480007E3D5D075075CB71D07E033E87F30E7E97 -:1024900023B371DABC051D73653BF2283FDC7C88F1 -:1024A000F2C2849049213D27EC058E4B2881F945E5 -:1024B0007FD762A0FC75C8011E09EFB7260E7F42C8 -:1024C000BC18EE34297B24C2AF199C387FAB91C76E -:1024D000CF5C348437AC91EBDAFB12422F03F92B3B -:1024E000E48757A5FBFA66B8C31A8D7B12C35D75E6 -:1024F000705EB526867556F2FBC8C93D4CAE889C09 -:10250000C0DEABC999CBEA8056E3F0C5C7DC4C2EE0 -:102510003BF12117B89C10CA565EA5E7ED5EB68E5A -:1025200004BBE2094823E5F217625E8C76F7DC769D -:10253000B861E764F7FEC448DF8C36D19AC9F90D5B -:1025400081B33B17CC89EA93C32A8D3CDFEE38B7C1 -:1025500073C704561F0564E48305DB2427AD93C7C6 -:102560003F340DEF98228E830771B298F9FD1BE37B -:1025700091EF56EA5BF9384FB2DD522E31BB01B212 -:102580009B7AE1671E91C217EF44D57E1D3E54A889 -:10259000A02CB5C7DE61BCADD1855E2A20FF98E8CE -:1025A000FB03F9F7B73ED6810DD7FFE56B096A0546 -:1025B000E291F3F6EE14AF75E47C4F9DDBFE7C1ADE -:1025C000E9FB6D4941A4312F1C4E27F9EA439F1BBB -:1025D000BDD82EEEF89391E2D32F9CBE5EB283D28B -:1025E0008EC6F984DF2C686EB25B995FF4114F835D -:1025F000A9DC7F5C3933654F6314DE43C2BE60D80B -:102600003791EC2624ECB38BF21F6CDB451ED6DE33 -:102610007D5F965210792E0087D200E7DC0E47D2FC -:1026200008E71BF3A9FA25C4A7BC0FCDEBBC517C6E -:10263000FB42D8FB17E27D01A7EF53C2A1A6FB33F3 -:10264000A30DD7E5FF9F603AC5A720E669F61FF006 -:102650008BFE38BBF1EB878D34DE7F09981F41BDBF -:10266000EE48463DEDFFB063EA7A2B931F9271DD91 -:10267000EDE74DCC6FB66770FB6B3C7BB590FCD63D -:10268000D5CE9A8984D7298741E3F9BC44B2A70300 -:10269000C0FC98668FF9648F287A3EF1BC84FAB941 -:1026A0006CBE56635F39B3BF761D90FD21CF19EF25 -:1026B00091E776CA3FF2EDC87BF67C36B3E7D63EAB -:1026C0000C78D80FA01F9FCCFAF35650BFB56F817E -:1026D0009DD9B30EA12D22BB0C1F62F304B1A6221B -:1026E000D54950199DA72E74D898BC9A7F5C21ECCF -:1026F0003498A3247B703D16598EB183A878C9FB0A -:10270000229EAE759A9E7E71025993880B222FEB02 -:10271000127930F88A99BFFF4711CB1ADE2D5BDAA8 -:1027200082EB6D382973FF2F787248E4C947B6A54C -:10273000B23EC50B05F5341D5B2FFAD319DECDF380 -:1027400029FC942E693E4C6D596570BE81E2E2EA27 -:10275000BEC3066ECE79C4BFB6433FCDD313DFCF21 -:102760009B2001456CFB76F893D711872D5D88FF80 -:1027700028710997C3F887119DF1F166BC1992FA87 -:10278000EF99EDC1FACF39EEA7FA04B41F2206E2A1 -:1027900071BB73ECD30114A8C3E92D72227E9FB8DC -:1027A0007CAC1D3AF56D0AF9F4F6339FD9C8DFB752 -:1027B00019BD79C4B3B64CAC1746E1E744A781F91B -:1027C000FB12536C9EAEB52B9DBCAE9A12806789EE -:1027D0003FF56DB25D457D0FB4C95E23E65117BD6F -:1027E000BE143D427A0902AB66537C17F5EF431CD9 -:1027F000767888F2178C331B5F34C4D4A5B5625F3A -:10280000231BFA9F4C439CFC7B2556D756C5E523DA -:10281000B594BF14527DB1DB48EBA9DE1B370FE541 -:10282000318534EE87EBDC954E91C7644116E53176 -:10283000C823564F0F9F953D7B2806EAA1C784FC0D -:10284000DDAFE338A1DF64F6A8E533896EEF22B28D -:10285000FB450E9EB7B48ABA75B8555299FDEC4344 -:102860003F8FFDB24BCA6EE0389C499D41EBE1BC05 -:102870002CD3F3F165A10C667FA55EACE771DD1B7F -:10288000B19E5769DD5A9EA71AD8FA31FCB23C6F47 -:1028900016A84D361CB7699FC4F67D6AF61962F218 -:1028A0003CBFC0A776D7A9A3544ED605E3EE0B7C58 -:1028B000FC71F8BC413F668DC4E9574EB11F900EC4 -:1028C000E9D1F91EF43847AD0B347CB43CFB7F0DE5 -:1028D0003CBFF840CCAF8DDBE5E47EB4DE0B6CFF93 -:1028E000A856955595E783D6F5C89707045F1E103F -:1028F0007CF1031F57B74F52C314AF7ECDF56EC6A0 -:102900003FC2E5A1E0FA4569CA485E550B3CAA5AA8 -:102910000C2CFF05D86C24FBAC7A256E9CC0A53A24 -:102920000E977A9F14271FCFC7FF56F96A0C7CBFFA -:10293000A606F91550FE7EF2C6EBEF0D8DE753614A -:102940006A8CFE96B86E497FF179F281A3532DF41B -:10295000FC959E4CB60FA1F1267E9E4522CF5EBC13 -:102960008BE7A3031DF32D05544F9DD07B249CA71B -:10297000F8E4FFD90A108FA24E192A708AA150F1EB -:10298000B3015CE7C19E492B148C0F4527F52CBE83 -:10299000149F2C52A9AE293A5964C94A62C6E3A2CF -:1029A0007A01E761F179E8C4A4D3F9E4677B16946E -:1029B00010EC8D278A2C94471C04BEAF219D2C71EE -:1029C000F547C59BF79C325BD793A9FFFD1CE5F942 -:1029D0008B0F183C948F2C360CBF3FDB4DEFD77B11 -:1029E0001AB15F7B72C3F604D2FB6B9287D2F1A35C -:1029F0007D0DEE9F937E4306BB89C9FBCB43743F9D -:102A0000D0227926E3787FE7C2BC56EC17ED2EF68C -:102A100010CCDAFB8A1CCA0B15942F8EB3B03A7E09 -:102A2000F16D0616772F8FB7FC8EF2A56AEFEE4593 -:102A3000E48F2FBF73D048FE60A85582545CC8D184 -:102A4000D4C3BF0FE03A2FBF79CA4849F9FCB65347 -:102A5000C6FE1FC827065419C2AC7E6F36521D54DD -:102A6000B75BEBF71B494F9522BFAADFFB27D6AF19 -:102A7000A63A01DF57FD8AAC2AF8F370E75B46C23D -:102A8000BBBE4582B11951F7F74AECBEC6FB0DC07B -:102A900079B041F8A71AB10F5943FB90781D7672AF -:102AA0007FA3F1FEC17DCB8E52F87EA839D60F3DB3 -:102AB0002C78BE89EA52567FFB8CA4D74DBBE2C668 -:102AC000099E3FFC233C4F76093F950BB9C4F3ABFD -:102AD00073793CB97A2AD1928FEBBADA2B7B007EDC -:102AE00090EF2CFE9E10F9C295B08EC5336DDC6060 -:102AF000C75F58BCF19FB862A4FC7651E82BA68F43 -:102B00008A50F702C2FB6EF0D5127E77872C76B220 -:102B1000FF8A7EEE0FCA432695F6C1EF86E00ED2FD -:102B2000F350D7BFED70126FFE95F30684BFDB2420 -:102B300070DD2470DD840EDF852EB63ABFFB252CB8 -:102B400007A01CB81F2A0F0A3FF44A2CCE1879EEB2 -:102B5000277DD5874CF00CDEBF4BF8A3BB5AB83F9E -:102B60008A8F93F5621F60685CDE52B6DF8AF52EAD -:102B7000E571B52DB1F8D78B7D81FAB8389CE9E2C3 -:102B800079C28FD5FFF17A5A10A7A78A61CE9F72BA -:102B90008A7BB8FE9EF0F67CDAB7D3F08AD7538FE3 -:102BA00092953C5A3DABB5EF8BBC5FEB2F057EFE9B -:102BB00014B4375BA3EBF8D75D3CFE54CF9203A46B -:102BC000E71BF5CEA4C3858A2E52EF609DB3D635A0 -:102BD0009DD73DD370EA63136470BB23F5CE53A930 -:102BE0002F541451BED2C2FDC86029CE974CF93C77 -:102BF00030FFE56F31A954A7F8913FACCE21DE60DC -:102C00005B199216126FB07EA872218ECB68EB18FA -:102C10007158D6C1F39E650BBE627CEB9DC4D77B19 -:102C200045AF8C1DAD9ED0EA88FA6F789EAA5DAF45 -:102C300047BBA7F1F52189D5C56D87FE9A9E81FE18 -:102C400073A8F35AFA7A6C5F76F13C4ECB53873116 -:102C50004FCD14790AE5CF1BB9CA6013A6C35B91A7 -:102C6000871B459C036907B3937A4A76896FED12F7 -:102C7000DFC7791B2FCC44FFFB4122CB63063FE427 -:102C8000E743F4FCE398470D6E081E71E2F8ABAD24 -:102C9000128B7F1B31C7FD49D1487BAF13BC6C84BD -:102CA000EDA22EDBC1DAF29C039F3D46FEA8C5AC27 -:102CB000907F1DEC6832B2FD6535EAF9CC91F95090 -:102CC0009DE06FDD8FEC6BBD1EC74B5C07CB6F8744 -:102CD0007A65BB4962F8FD767C344E22FF693B94ED -:102CE000C0F43C74CAAA529EFFA5E0DF65B1EFDED6 -:102CF000582A335C74B3789BD7F55626E995F4E0EF -:102D0000A37D94AEB7A67AD93E9FCAF858B34FA612 -:102D1000C3BE88FC410BDB0BD5FA1ABE7E812FCADD -:102D200035C5E88EC8D5AEEFB77946B11B493AC470 -:102D3000F4A69362EB5CFFDB72A51A654FB89E7533 -:102D4000E4DF42821FA01F4E21BF1C76294CBEC665 -:102D500010D7B3AE93B7F8FE557CDFC6C0DE3FE2B6 -:102D6000FEBC402DDDBF9A6101C6936F0215D4DF12 -:102D70009229333FB5E583EA6C887A3F48BC1EF759 -:102D80001B8653583D7C4AC7E4F39FBA9232C94A26 -:102D90007E70F7027B3EF937EE1F8E665AAA88DFF7 -:102DA000017AEFD8C83CE52E7E9E00B4DE54CA6698 -:102DB0005EE4F38AF56E87E50C87ED8267DD221FFE -:102DC000C5BAE93CD9637CDD74B37C37AA7E6378ED -:102DD0005D9DAB9CFE39F2A0A8571FA07AFDE0399B -:102DE000EE271A3B377D4A75B0FF8209C84F6CE960 -:102DF000DA944D71187CBEDB29BFBBDAF5F0ED6CBF -:102E0000FF52DACEE40A907CA994379D4DA17CA8AC -:102E1000AEF36C0A8BEBEDD35FA03C09F3A2BBE8E9 -:102E20003AE62B8C7F45274B18FF0E9E2871659143 -:102E3000E0E0B1D0BC75BDFA4AC2A7AEB7E4BD0AA6 -:102E4000CA5F4ECE637992961715533D4E7952EF75 -:102E5000A4983C69D8C5F3A4A1EE04B6FF2141268D -:102E6000E70F4C8AE14F6DDBBB2C9FA8ED90BDD1E5 -:102E70003CD29ED3BBF57C7FD42DF81394BC8C1F21 -:102E800007785BDB7190ADAFC61064FA6E6C31F001 -:102E9000FBADBC0568E6FB2CE00C101EEFD125D481 -:102EA00043B9519D40FBEBC733787D11AF8F67DD90 -:102EB000FC1CEBF879DF44E2CBF1B9BE6CFB287166 -:102EC0002300F378DD2D09BCDB0C2CAF8C1FF7B48D -:102ED0009BEF4FD85C1073DEA8B5BF7473FE941BD4 -:102EE000F93E55FCFDB96E614F289A0E7971BAC250 -:102EF000607F46D413E3D0DFDE23FCED8ABB0D2CCC -:102F0000EF382DCE99EED1FC6E298FDFDA7EFFB23D -:102F100057E0092CFFE16BC867E760CBBCB17E6F5F -:102F2000A5C8AF562C89BB2EF2A9953F924FCD7202 -:102F30008BBA610A4CE17583D542FBA25FF718ECAE -:102F400032935B9D545930729D9ABF392ACE877A4D -:102F5000D00F52DB98FB11DBA73ADE7DFEF70EE6C1 -:102F600047132093EF3BB2FDFABA9BECD737DEB0A4 -:102F7000D39FC5F04ED3D300E5F9F923F5B452E061 -:102F80005D67BE6C64E796B079A74E8E9C539A0C31 -:102F90003E6F1AAEC3D031374CE7978DB926962FC6 -:102FA0000D2C9454F2F72867BA29CADF0F8CE3F985 -:102FB000D7965512DB17EECEFD88C5F1BA709F91FA -:102FC0007835A56DFD13CC7E037086EA254D9F4BA9 -:102FD000CD3C7EDED0A3B65EBAA9D0FA9C01EE97B6 -:102FE000DDACA5F1142FEF11F1716969ACFEB2A14E -:102FF0006F11ED8FDCEB9558BE7433BD2F5F3DED47 -:103000005DA2DBADEABFD9EDDBEAA6FDA2BE2BAB2C -:10301000687FF778EEE7E9145FEB6FC2E726C177C8 -:10302000BF859F8BF92DFC3CCC93AD34F5233E2618 -:10303000876FBB9BFC87EE7BDB54A079FA7FDB209C -:10304000917E80E9E56676F4B498F769B79DFB6FE9 -:10305000373F1FB2529FECD9A04E203F01F9B776FF -:10306000CED7F8F6B142D2D360776FA1314A9F979D -:103070001BD01F507CE93C9CA258A3F9A6137CD31B -:10308000B35692968BB819CBBFCBC43FD2FF81C346 -:10309000F7505D38D0B6C22D295171B5FDB46D72AF -:1030A000D4BC0321998DC77A6CCACAA468399F60C1 -:1030B000720E04F97C00FD53561444DF6F123CEE8F -:1030C000673C7E2A67333B77D778AC07CEE3FA8E2E -:1030D00065C0E2945877D0883FA8CEE832A9744EF4 -:1030E00041FBED8E283B392EEC63261607C4CF59E1 -:1030F000109069DE9938E35AEAEB21AC77D2796017 -:1031000058E6E7DD1380783D43F07AA63EDC2D15C6 -:10311000B271EC5CAA0CFAD8B89FC0306BBD60D716 -:10312000533B0F3CAC2D3587EF2277921F0CB2EF4B -:1031300092C2297AC745333B2A85D1F41759BF1E5D -:103140002E6A3CC5C198F4B07DFCF8715F0B7FEF2F -:10315000A11C8EF43C006C1FEE0EE897E925B3F538 -:10316000B084BE27BB430FE64494F7C0111DB3E7FC -:10317000AE7E45257FE67189E7BEC0E7B03FD3CB81 -:10318000ED9642107DB7A2AD371E87329C8FF605B3 -:1031900067EAB1F2653886D9FBEE24C171DD73416F -:1031A000D153FF923B437CEFC6EBB4F9A24ED399C7 -:1031B000030C8F418A8F63F8798E0DE7296B96E0B7 -:1031C0001C9DCF64F1F56AF39761284DA67C5AAC3B -:1031D00097B6C2CF39F9398F8D9DCF2DB0135E527E -:1031E000384577DD72EBB80EA50093DBF6C0F0E052 -:1031F000632591F32E4FE8D839FA2E47F27AD97722 -:103200003D1EB3354CF939B2E37274DEAD1BB30128 -:10321000C6E0FA24C5CEF0021F28947F8C8D7CEF87 -:1032200002D75D91EF6908C64B2991F37DEDFB9ABA -:103230007DEA7245877A59ED367B482F45E6F46280 -:10324000AA07F7DA7D30867D67D332994DA657A756 -:10325000572645F86E016F29E1AD9DEB4B427F3754 -:103260003BB7275B259E5BD0EDD37741CFA2BD98BE -:103270009DA37D7FC4CFF3D10A15FAEE081E9FAF40 -:10328000D077014F3ACC9E67C8CFD1FA2C91F53553 -:1032900099F9F7044D66FE5D00EC98CEF6CF1E114D -:1032A000E7114D565D0ED55B4D90E8A1925E93F708 -:1032B0009124CEC747FECBC2CE47E3E5FE3ED19771 -:1032C0004FF86AF23F2A7BCE61EE1383E71C0D4F65 -:1032D0005D04CFD56A6653BFC2F02BA1E7A799D48E -:1032E000DB685F648D897FBFA4E1860A65A4B60BA5 -:1032F0007D68F8D949DFB40E2FEA5BE34B6604BF63 -:103300006713396E06FA72228B3DABB0F3FC385C62 -:1033100034DEFD3FD45368B1102A000000000000E5 -:1033200000000000000000001F8B080000000000EB -:10333000000B7BCFCFC0F0A31E81FDD1F8E8389100 -:103340000F534C94118257B3E0D78B0D5B3122D8C9 -:103350009EDC0C0CB29C0C0C7240DC01C49D40FC49 -:103360001288B5B81818B4813801C84E04624B20D1 -:1033700076E086E8A96567606805E25E209ECA4E31 -:10338000BAFDBF2518181A6411FC0B4036AF02E9CC -:10339000E68CE2A1897F1BA2F245B451F9F6BAC0CE -:1033A000F46184E08B6A9366FE36A0DEED46B8E5F4 -:1033B00079CC51F9CC96A8FC6E3354BEAA3B840656 -:1033C000009B2185B9B80300000000000000000048 -:1033D0001F8B080000000000000BC57D0B7C54D53E -:1033E00099F8B977EEDC794F260FC20021B9794000 -:1033F00002267188E1A5A013040B886CC017B4AE37 -:103400000EE111DE44B49AAEB8B99010420861B42E -:10341000A8C18D3841405468830D4A57AB03524BC5 -:103420006DB71B1505772D0D688358A0298A4CFFB1 -:103430006BEBFF7CDF393773EF6426E0BAFFFDA743 -:10344000BF7A38F79C7BEE39DFF79DEF7DCEC8243D -:1034500087A4DD44C837F0474BBF891032205A9209 -:103460007255206308F9A195E09FD62FB6ACAB2129 -:10347000246C2124B290904E27ED28555949212DD6 -:10348000EF982E92744292E07D85907AA1EA686E60 -:103490002921EA5091ECA28F3664CC4E0A38138F62 -:1034A000BB978FFB931A2B96ED351E2C5FAEF16206 -:1034B000D951A390703E21AFD4146079B0C687CFA4 -:1034C000FFB5661C96AFD7F8B17CA3662A96E19A41 -:1034D000722C0FD7CCC1F2484D00DF7BBB66319612 -:1034E000476BAAF0F93B35D558FEB646C5E7BFABEA -:1034F00069C0B2B32688E57B352D581EAB0961BF84 -:103500000F6BF66079A2A61D9FFF47CD412C3FAE01 -:1035100009637937494678DE79E725EB3CBADEFC6A -:10352000671E7C6F5A1A215B468B3E0057FE339F05 -:103530007A0385D1756FF99B694E7B1CB8DC450415 -:103540001C678B8B60FB96431F11A58890E6D15DAD -:103550005E95D6A7F1EF8CD875CC3AAF30DA2F76DE -:103560009C3F12131BC74CDB69BFE1DB587FAD7D6D -:103570001A7C6774B47D77CB7BD6F94E7D3B7BFF9D -:10358000F9D6F7AC80BFCD11898411EF2A21B4B4EC -:103590002B3D2D03289E6D272CC4924DF1AFB49383 -:1035A0002E3A4EF3F827C36229AC9B7653609DEF09 -:1035B0001381C2417511A40705C6181BFDCE582200 -:1035C000E23CF29F39C6BE73C7252CDFF8AB4C082E -:1035D0007DAFF94E21E4A0E3374FBCE8F503BDA968 -:1035E0002F9880DE905C15F84F97B79C8EBD65E2F2 -:1035F000875E95C269F3DFDE9F331FE86F14F1C168 -:10360000F7361FFA3951A0BDA807E157CBD7BD79CE -:10361000EEBC2C4F6162BAA49444C47174B94EE2FA -:103620000FC581EF3F0210287C4C9E10AEC94EFBA7 -:10363000C5C3C33F1219FB6D76957F007051EF34FF -:10364000FB76D179DFEC0B936E6774DE50FF84D686 -:103650009D5F8689C905F33EEB35D1F53BC6C9D7D9 -:10366000D9E86C9C3D3D27E07DE784457E587BF39F -:10367000A82EEF22DADF5AD089EB253EE21B46C79F -:10368000B517A8647E21C0C184788D9DCF7C80F75A -:1036900000C0D3575EC08946871FDCF1BEB542D754 -:1036A000FF798D3E04465FA4296C9DE58AB63FA351 -:1036B000B5DB18FD10ABB17D5B0C1D938C04ED6682 -:1036C0000A68C49718DA2520DCADB38BFACEBB2983 -:1036D000FC6BDC074E5FD81A88B32EBA4FACC077AC -:1036E000924A451FC0AB7922DD2F85D1755E69DF17 -:1036F0003570B86C2E9DED82F1AFC4B78ADA4512F1 -:103700002EE03C93FEFFDA83763AF3687D5438C5A9 -:1037100050BFEEE86043FFD19D3986F6B127461AC7 -:10372000DAC7779518EA377C76BDA1FFC49E498633 -:10373000FA4D91E986FE65E47643FD66EB0F0CFDDC -:10374000A778E61BDABFE75D66689FA63C60A8DF46 -:103750005AF088A1FF6DBE5A43FB3F8CDB64689F23 -:10376000E5FFB1A17EFBD47F31F4BFB3FC3943FB4D -:10377000DD735E32B4CF0DFCCC50AFB4074E027E89 -:103780007EB0F835C37BFF58F596A1FE012153E3C7 -:10379000E197088CCF500AF2745FC3FB5316E70120 -:1037A0009A033A1EC0E8B4A02D019FE4ED2FEC7CF3 -:1037B000CFBAD0C027CD8C8E07B1F63DA1F7E2BFBE -:1037C0003F94EF13D2699DEDD2B7B3795DF357CA39 -:1037D0005FA15D52BF157F75797CD85FE3AB94BE66 -:1037E00009B99EC2571DA2AAF83D3A1EE59726B612 -:1037F00064524D189F22E4017CAEC97D9241C226DD -:103800003A6EAD2BA3AD116042C796D2A05EB8034D -:10381000EAA2E2275D71E06AF2C8063CC5C29738A9 -:10382000532831F7C76755849F3A851448F07DC106 -:10383000EE5B4BD72B91C060813EBF2C06BC30F9AC -:10384000874DEAAF02D9D1FE6B27D27F42FF5342A8 -:10385000681DF657108EB545C40F72431D24877638 -:1038600065233C2DC04FB4F7E803A58BCD57FD264B -:10387000D75067F3BD62FDEB7C635D1BF79F8CF057 -:10388000A47086FA7DBCD267DD3E394AB726E8C708 -:10389000EA8A28906F900F1ADBB5EF5CB6B98B49B6 -:1038A00012C5A395950FDBDD3BA0BC6CCB0C11378B -:1038B00021C562609240E1A04E62F0514F3A42B59C -:1038C000385ED5D8F222806F7C7D8190756C7F7CCC -:1038D0003C4DD4AF2311DE3682DE961FADDB32289D -:1038E0005DC5E1CB77094CFE511A95605C0B61B464 -:1038F000E53005EE8279CAA4DC2F225E7D04E677EE -:1039000068D893732A28FE9A26C83EEC1BA40A277F -:10391000D54FA55EB84EC5BA95D7E7090A8EBF3117 -:10392000F9B03587AE77B34FE47A4110C76BC8FE64 -:10393000CA0B7CDC26058907CABCF8727AA52072FE -:103940003C3E4AAE461F8EC5CF48FA3AE32F04E10B -:10395000A7CD6FCBD0B03507E8713CD3879BC7F5B7 -:103960002F57D673B8D6727D78B3323B8938A3EB24 -:103970009612CC6B03D7A309E99903786FC84E1749 -:1039800061DF6E1018DF3994FDB615F84793E7B084 -:1039900015C60B08D96CBD31F06D487E0FF5FA5A8B -:1039A000977D4E280E3E03821BD7D900388375259C -:1039B000132EB7552FE0CDAA784A1A95BE7434D984 -:1039C000F525CECB594A140BEDEF4C63EFDB3E16D9 -:1039D000420ABEEF770EA2F37070FAB02B46F9BA26 -:1039E00076E22D2AE8910FE71032109FDE6FC09328 -:1039F000A3343003E8DFF457138E4B06B17949A4A2 -:103A0000EA0FF361FC42C6A73CF47FDFD031AC790A -:103A1000317CEBD834DCBFB2877D9F982674DE44BE -:103A2000E72BE58B034D74AD2673A71FF4B18D5DB5 -:103A30006D3E55077F594F07C0873E9E769614C34B -:103A40007775E3C3FBC3666FC9ED879E4C5D6E124D -:103A5000BE0EBE7B4FBFF4E1FAB8ED9D233AB8BC71 -:103A600021B8D2BA016863C958E4135778FF724D80 -:103A7000E89D23C370BDE2D5D0797DCC3EDF90CDEB -:103A8000F5398AEF593A3DEDB2C0F439A296211CBE -:103A9000258EC70D13490FC895CDD9B2B20EF0517E -:103AA0002A8781849052E9F7CDF00F809B52DFC9BD -:103AB0009EFFD0C047D70F99E90B2B89E727A5C5F3 -:103AC000E0F10AEBAF06F8E9FA7703FCAE89C2CF62 -:103AD0004CCA93C240DBC1A948BF6E6D1E13EF52A2 -:103AE000F4F3E885E30D6C7F9AD354124F2FADE5C4 -:103AF000F0BB53F45F047E67927D2702409F39320A -:103B0000DA27B1FD478A8C0F45E16C95004F76C2EC -:103B1000FF668410EEF4AFDC9ACEE147FFCC196F5C -:103B2000FF5500BAA366B3A3189FD74925747F79C0 -:103B300089EAA0F2C12E1109EA59C06C4763FB64FF -:103B40003905F6F12D3ED477CDFC7B9E36AF5E4F26 -:103B5000CF12195EA3ED21EF9D8676338EB7C1C5D6 -:103B6000F51BCF7306BAE87D3F39BEDC192832FD5C -:103B7000274BF470FA790EED39F3D0BB1A0E517859 -:103B8000D7E5FB7D15B0400F413868F243931754D9 -:103B90008E64890300FE010278973CE558C6CAE3AB -:103BA000847C3C460E9B0B6403DF217AFD2607FED6 -:103BB0009BE1C1FD4662E53F2FCBA75FD5BEAA8D35 -:103BC000D95726125F2EDD2E32FD91A869B87E6D81 -:103BD0005F11AE5F68F8A7F2C140AF32CC87321CEC -:103BE0001B09E1E00E6A6641DD45AAB07E695C49C9 -:103BF00058A0E358A4AE06E0CB96712251B3E3D8A7 -:103C0000555C0E255AC79689F1E5C4CDA29BD9C74C -:103C1000CE2ADC1784DC837AA1A006C837A81F0649 -:103C2000B9BCF479018F1B6BAAC927743F590FCF18 -:103C3000457BDD9CA7FAC1DE075901FA23C9286537 -:103C4000A5E453F4F4D98B47B216C7333919FEE50E -:103C500034AA17E7207D2C00FA205623FDF4D24920 -:103C6000461AC80A9887521E775C8E57DE2F211D90 -:103C7000F5D281B62E4586F162E9C35E4A2D0E115A -:103C8000AB9D309F811C7B0303F5F78BC5809FE0C4 -:103C9000D4E1140F03BBE6A13C737179525F38FB8A -:103CA00028A874493ECFAC5B14B0F3890070DD08DE -:103CB000835D0FE3CD5D5B46EBEB61B0C1B4BA6EE3 -:103CC0006699EA646462D44B4545D2F430B15FBD75 -:103CD00046F8C6D2F7FD44EBB7C4C83B42565F9DD9 -:103CE0001E750FFB9E4AFF07FB2B39469E26F98D5A -:103CF000FCDD15F39D17019608DFFBFF57BEE7219A -:103D00008F5B154A0A963CD113A2B499443CC96012 -:103D100027D92753FB8DD63D193D2A4CE94A78A96E -:103D2000E7762AA1FB534FCF6F727EE9ADA8CBAEE9 -:103D3000A7E35E2A75FA805E0752F6989AD2773D1D -:103D40009BB8DED75B2FDC8174BD9ED211E8C36ABD -:103D5000A188FEA68D792F7BF472F194C657FAD014 -:103D60000751244D2EE7C03E14FDB6E2EF4E1FE68C -:103D700018385F2D7D38EE31E2E3DBE2EBC2B7A409 -:103D80008FEFFABDFA44FE07CE9F285E51FF6E50BA -:103D9000FAB703FAE2F571C4AB9DDA2FF1F8ED172B -:103DA000BDF8548DF288DBFF51B961B4FBA5AC5B63 -:103DB0004EB4F5030F29564FE6E3DAAA4DCAA7A978 -:103DC0003080C760EF6C541E5741FFBE047A34E860 -:103DD0007BC132F4FF923CE68F850144D0FB157F16 -:103DE00008FD0C209F74724DCE30EAFDA634BB5105 -:103DF0001ECF5105FDFC6DD532CEC30ADF4B437F8C -:103E00006D08BE6BF290B0CD1DA557F814B3F71F27 -:103E1000B92A3A3069EF091ABD1ADFDB905142E244 -:103E2000E1AFCFF7EE30CE37215F8A7DCF2929DD94 -:103E30003ABD23F17B12E9D6E92F376A711D8EA7AF -:103E40007A33392850FDAFD67B170928489F28C7F9 -:103E50001AA0A4F2B4DE5BE241F9BC4788B1CF15E9 -:103E6000464F4A0AF617AD4CBFD2EA89E7C3BE1BDC -:103E70008D1329A81F27EA5F5B33EE0989321B7374 -:103E8000F55B5B256AFFD4ADF5CF29A7FD1B6B8ED3 -:103E90006E958645FB2D3169F639159F6340AFE17C -:103EA000F44B683F849B48BE01FB8972684527E755 -:103EB0006DA473AB84769FC2F14884DEFD4087DC3D -:103EC000CAD7692127B01F0C84761CE9C271E1456D -:103ED000A8AF37FBFDE5144E8D52C8BA1AF8B98D5C -:103EE000D7155E4FE6750FAF67F33AD98175B34CBE -:103EF000EBB07FCD210FD6EDBC9ECDEB29BC9ECC87 -:103F0000EB39BC2EECC0FA7A998DB7496A67E3DBCE -:103F1000795DE1F5145EF7F07A0EAF9397D9F72D3E -:103F2000ACEE30B7B3F11DBC9ECDEBA9BC9ECCEB83 -:103F3000B9BC2EBC8CF584FCB280C13FCA1F18BC32 -:103F4000357A240057831FAB2BA69DD18B49205C6B -:103F50000FAB42FDFFD0D0BBBCE06F5C7FAAD20BA1 -:103F6000F4537F9B464F01E49F24E356E463662DA0 -:103F7000EE98B67A0EECFFFA0C19ED49C2FD305AF4 -:103F8000FB86E4C0D46CF0577C6022F1EC2EAD6C63 -:103F9000E57CF769D07BA97EDEC2E3914FF278E43D -:103FA000568847D23208F1485A36F37864138F475F -:103FB00036F27864038F47FE04E291F910E79C83A0 -:103FC000E58B108FA4CFF7403C9296BB211E499FF2 -:103FD000EF8478242D77403C923E0F413C9296DB53 -:103FE000793CB23EADE428E81D97AA45D40712CD2E -:103FF0007F6895917F0E596C8C4B0C0A18E3120365 -:10400000E718E31203CA8D718964BF312E9134CE53 -:10401000189770F98C71094781312E61538C718921 -:104020006B0FCE36D48BDABF6FE87FCD9E0A43FB91 -:1040300088D052437B7ECB6A437D58F09F0CFD7342 -:104040001BD619DA9F32E5207D65AB8D867E59D56A -:104050008F1BEA95767FB709FD946957E5AF265F18 -:10406000AAE97A7E192B1F4C99C4EF4739C7E4118E -:10407000FA6081FE8632BF94F5E3EF1D057BDD9289 -:10408000C7E4944589B13B63C6939DBB4FA8F43BFD -:1040900065EEA3DE2EDD7E245EDD7B60EF488C4F77 -:1040A000363ECAECF1265EF65D473DF66BFA5B7C68 -:1040B000BBDC269962F40866D7343D2A60FFEF3AEC -:1040C000BED61E3B6EF47B141563F4F66D48F3AF59 -:1040D000923A9DBE60EE4A9E4F50CE33FBD7C4F756 -:1040E0007B5981EF541D85F77A0FF159687DBD73B7 -:1040F000929FE925A2824276CD6D68A76BFDB579C6 -:10410000D5396733FE42D947D8C0A7EC063FC1FA7C -:10411000B4FEF53739622261AA97982202FAF56453 -:10412000A97C6A36D5C7E56326DF5AC067027B9F44 -:1041300090C7193FF48A063AAE5BA0F13F1F9B1F60 -:10414000CFBBD0F85B6DDA247C5EE7E97F5E169822 -:1041500017CC87CFCB1C7160698AD870BEE323A9C6 -:10416000581F1749C6726C640896632283B01C1DE1 -:10417000C9C5B234928DE575916BF0BD92C8082C1B -:104180004745AEC3E7BEC8282CAF8DDC80CF8B235C -:10419000E3B12C8ADC8CCF0B2365585E13B9159FD5 -:1041A0008F8C4CC37244E4767C5E109985657EE406 -:1041B00007580E8FCCC57258643E9679917958E6AF -:1041C0004696E17B3991255866471EC0E74AE47E52 -:1041D0002CB3228F609919F911964323B558664480 -:1041E000D6623924B209DF1B1CD988E5A0C88FF13B -:1041F000B937F21896E9916D5826479EC3764FA4B9 -:104200000DCBA4C84BF8DC1D79014B57E467F8DCF3 -:1042100019D98FA523F21A3EB7477E8EA52DF21627 -:104220003EB7460E6179253C5D490F1EF7A9918F77 -:104230008FF9D8C8C74B8F19F978C96F8D7CDC7797 -:10424000C4C8C78B5F37F2F1C20E231F1FB9D7C88E -:10425000C70B761AF9F8F056231FCFDB6AE4E3396F -:104260004D463EAED419F978E61A231FCF78D0C850 -:10427000C7072F37F26FEF0223FF4E274F1BEDF4D6 -:10428000C93B0CEDEE092F1AC67396BE1C63D7848A -:1042900090BFD80BFFD5F09E35EF700C5F56197F9D -:1042A0008AF19F0348207EF930B1FBC0AE89C56713 -:1042B0000AE707A9B0EF6899C6F7DD00D877B44CD4 -:1042C000B97502C6A952678E9B07FEB8CBA7040535 -:1042D00074226166753EE841294308F32790FC9BF0 -:1042E000FDB45E3B48AB135580FA5082FE0588FC56 -:1042F000617B36ABFFB2EE91491007AE35F376B570 -:104300007612F8D56A6DAC7EACAE621DF82352927F -:10431000FC83215169A7393E3FFF5892113E032586 -:10432000FF6F245AFEB9ACEB21F027FECA1AF877CA -:1043300089C263B935900521B4F3E6C0F3203A721F -:10434000047F27F42B12FCEF4AC8CF8D7ED35B404D -:1043500070D2F6A152F987D09E3A730FDA171A1C61 -:104360006A5DFDCFE79D5EF944504E6AFE8AA71C48 -:104370006EB43F1B9F904310373717A4A37CA84D02 -:10438000262C1E0A71218C0BB3FAAEA14AA891E922 -:104390008B46B9B2B5FE7E884758413EE5EAFDA797 -:1043A0005DE83F4D024B2117FC033D99122D575AF2 -:1043B000C2F52057BE4AEE3C2998102E1761FD0F1A -:1043C0004D0F61FF758E99E3605D142E5FC07A29F1 -:1043D0005CBE944627860BFD2BF78EE1AA05FC6791 -:1043E000AF60F05F3A4C81BFC3383229C7F115D5B1 -:1043F00087F03B2E79F07D0D8EF4EFC19431D1F82A -:104400003F7D4F360FE83B9E36CEDF25FE7D2E1FCB -:1044100035FAAE4E20AFB47825516FFB567EEFC310 -:10442000B218F73B66A91CE3B47DF8619A511E9A55 -:10443000D258DE83498A1F7746C7318CDF3AF3AA08 -:10444000E2D99ABF85D4DD7655FD1BB4FED44084F5 -:10445000FEB91A9E5A6F437A1CC6DFCFE57ADE5B3F -:10446000BF7F556D02BACC2398CF11ABDF356E15E7 -:10447000911E739399BEA8C15BE2FAA1F65DA9C92A -:10448000A827BE2673BB78EBD5C17F0F877F2EC5CB -:10449000F3BF96F49D07D93993ADC7C3AA0545C1AB -:1044A0007720DF64580BAB4B5BE97C8A13CF87F036 -:1044B000B884B68FA416D69FEC318EDBE7BBA61965 -:1044C000BE78F1B384DFF99671BEF966639C4F7BC9 -:1044D0009FE20BF19DC7F528524DFFE8BCF2891110 -:1044E0008E5ABC4FABBFF5FBB1184FAF0D96B078ED -:1044F000B993C973F2351D7D0CB8BBE2E3418BA7BC -:10450000D671FBB2DEBB03F3D9C85E239DCA831606 -:10451000E0F3C6820A0FCB4763FD2C431FC4FCC8DF -:10452000C682D5E8CF955BFD56B06BE502D107306A -:10453000979227F3F649D86E69657AA705DA15D000 -:104540005B77AE45D1100C35807F98A4493E086357 -:104550004AAD8106E82735101C8700EBA3F3D9C1CB -:10456000F198E195D695D17F6604CBC3367C8FF860 -:1045700087E9FA85F87A33331E0F43BFCC6055675D -:1045800019F8FDAA088E9F99B103CDF2C19ED96298 -:1045900099EEBDED7CFCCD7C3FD9827E0FBE1760CD -:1045A000F98CB1FB577BAF955786A75594C1B8F6E8 -:1045B000607939BED7CADFE3FD9EE6FD86417B29DF -:1045C0005227CEA777BFF37E2D7C1EF5DCDE1F1EA3 -:1045D00064799F75DCEED7FA3DC9C7B3589F7B0657 -:1045E000FC8EF941E68FD5DA83BC5DCBBB904B8D59 -:1045F000F9A31D66B65F3F97197FD2E826111D9378 -:10460000061DDF83F8A36A37D6AB530CF61FA91A31 -:104610006CAC2FCE31F60F8C34D6E79418FBFBAF81 -:1046200037B45FEEF5BB846C98EFCDFD2EF97CBFFF -:104630003CDD5A827647D4DFD765D3DB27197CACC3 -:10464000ED551576787F770BDF27DC3F63D3EC974A -:10465000BCD5D8AEAD7B3BDF271BC0FF6101BCB42E -:1046600030BFCAA8AA7746503CEEF9C0E4DBA124CB -:10467000865B223FCE46C027EE3F9657FE24F7E3E7 -:1046800004B91FA719FC38F9E0CFF1737FCE54AC01 -:104690001FE07E9C9FF1BCF2FDDC8FF3539E57BE62 -:1046A0008FE795BFC4FD382FF0BCF21D3CAFFC2650 -:1046B000CEA71BA6F807835F6DE794F876F14D321D -:1046C0008BFF4CA7EA1641F9DE23A0FF7C1CD555D1 -:1046D000E87AB3AA7AD6CAB49E7E0F835B56A0A7A7 -:1046E0000CFCE99EC9AC3E83CB55901F204F8897A8 -:1046F000EB3B1974C752786FE1749E59DD13867CC9 -:10470000165B866714B8406DFCBBB4CD8BF9FC9C7E -:104710008E6DD55561682726BF5D1E00E3B379E530 -:104720001CE99904E14DDF89CEC380CEE2CE76113B -:10473000FA159606D7510B9B380A4322F0AB86B286 -:1047400040E388B428BEE82C0C7441E788722B53F0 -:10475000E3BF138C742147B6A37E5C5B353B09E94C -:104760004F61FD8727907303E718EDA664BFD1FF63 -:10477000555B3DBB5F7FB4EF75E3FBC51D46BBAB2F -:1047800036AFFFF70BF71ADF1FB933E6FD16B68E0B -:1047900044EFE74466A27DF07C6B7CBEF00FA68AF6 -:1047A000898007ADEE8EDC88FD63F53E09F4B95CC7 -:1047B00070BFCB7ED07F25C5E3C7BC2445E1A58F64 -:1047C0003FF7F37A39D6A97E385D1E8D7831E887B8 -:1047D00026CA902116D23082703BE3EB75FE0C5A4C -:1047E000BF93A01DE290AD37AB13807F2C34F855FA -:1047F00052E5AA330AECD7C74494253B83FDF3BBAB -:104800003E79114E3FC68F729B3C25A638F8D6CA1A -:10481000AD4DE2D47871B1259CAED737CDF6A05C12 -:1048200038123F8F44EB4FD7BF44D6E5930CB88383 -:10483000E7099C63F96C83392DA52EED9F0EAE36EA -:10484000BF63AFB6EF9C2C6F44A3FBD4E1FDD389CB -:10485000A67F464222E9847D2155D9F148C21D3EFA -:10486000CC770701AADF27B57F7BA011F8A6FA2332 -:1048700011F9C8803BAA443D1EB4790C56C265B0FC -:104880007F6B0F2D1121DF3EBFA54AC4731387082C -:10489000FF0E9570B4B42D0EF9999F8CE559DAAAE4 -:1048A00002EBE0F9F016062FB04F797F940F1BABA7 -:1048B00067FB018FBB33888FE7AF18FC75BB9DA2E8 -:1048C0000A7AE625CAAF5051F89ACE4BB3EB28F0DE -:1048D000F25B996BB676180939A1DD3F15E1A5E5C4 -:1048E000EBD9B65D5471DE031E0AE37993514C0F88 -:1048F0003093CE30C616A4802AD0F1D7073C3EC8EC -:104900004FCC6D29667E99BC20E651AC16037B80A6 -:10491000EE357898D3DA316FA536C179810D9C9F39 -:104920004B24BEFDD1C9F970AAEC9B0EF6E89E2778 -:1049300028FDC7F10BBCC3C7796EEBECA4114A7418 -:10494000FF6AEDC74169D3CD2B3722B33CC1966FC7 -:10495000A7EFDF6C263CBFCAF89E49F219ECAD21E7 -:104960006605FB6975C969E467573F4F09F9122964 -:104970009C6EC073AABB7FBAD6F6CDE5A1317A474B -:104980005E01D27354EF10899BC2B5358FD30BA74C -:10499000274D8EC805414FBED0974E5AAB4BF0BC49 -:1049A000C9A509940EE99FC5D3EE07BF816B4218D4 -:1049B000D237800ECE021D0CCA53D70A4827631087 -:1049C000DEED5CEE593DCCBF123B6F4DAF03BBCA71 -:1049D0009B0223C7D83724F81ED077EE0888190227 -:1049E000DDD0CF51BA960AFAB7EFAE365EADC58FBD -:1049F00033E91FD8371D806FE0E39FC5F8A93C5409 -:104A00004F1DA393EF9F3D80FB2316FEB1EFD57999 -:104A10002679E2F16D620A782CA313D34BAC3D4D9D -:104A2000FAE4AD3D88FCC332632ADAC9BD7675EB82 -:104A30004C5CB785DB8BE63C6E47F6B11BEFF1F5BE -:104A4000274FCC19DF2D3F74A425BEDD98E8FDDE8D -:104A5000BCD06FE977D8C8F3EC34FBA3D7EE881944 -:104A6000472C6C8F7B0EC3596884BB3DCFA877144D -:104A70009AD9FEB4788D7E63B367707CFF26CF4FE2 -:104A8000AB18A7E149B9FB3FE97E5B72D44C1AA190 -:104A9000CAED5CCDAFB404F2D4281D5740DE1AC570 -:104AA000D30252EE86C6F344C47C98F3E43DF77516 -:104AB000BA7D1FB0F073010DE6D3709E42CBC75A8A -:104AC0001864756D3E952DC6FA22323B1DFCAC8BE9 -:104AD000B69A09E45F2D21D2E92E6DFE940F945B06 -:104AE000981E5449AAEA81AFADE7FEC30A0F912090 -:104AF0007F6AC5ABCF8C81F33995166E8751F82B41 -:104B0000BA3C9BA5CE900CFED14F3AAEBBEB060251 -:104B1000EF87EA0797629E3BE651C5C27D7E8371AF -:104B20007E579A7FEC7CB5731789E621ED11E29EE2 -:104B30003FFCA14530C4E7AE742EE41908820D484D -:104B40007C2EE44AEFEFF88EEF3FFF1DDFDF6B6155 -:104B5000F49BE8FD15D69E5B30CE9F56558EFE5ACF -:104B60009ED7B19204FCE03A37BD3E4B1DA2E8FA55 -:104B700079AFB25F06ED67BA8A7E79FD8F7781EFF4 -:104B8000F35FED7D4E86FD7BFEC55333412F58F616 -:104B90009A8958214F6DAF8B9FFF0AC920EF9676F7 -:104BA00098985F410A8FB95D971F082758018ECBEF -:104BB0007EEAC278F2D2972DA119F4FDA5AF7C52FE -:104BC0004C281C2EACEB797B08E83F2F0A2CDF4ADF -:104BD000ED2ABE9D3E5F2A91FBCAE3F9D12D4C4FD1 -:104BE00039F773C71CA03361CFA17B71DCF6BBCD55 -:104BF000169D5C3864316BFDD8F9AA1784D03081DA -:104C0000CD4F9FEFADE5B99D7B4160F33B680ED979 -:104C1000607E7BDAE400EDB76ACF5F90AE6FFEE9AD -:104C20003E37C061D5419381FFACDA630A5B8AB13C -:104C30003C65417EEF770A63009E04E5F7CA8E1556 -:104C40009817BBB27DD35F4C6E78DFB8BF285C7C11 -:104C50006180EB71936F06D47FF6BC1BF2893FEF46 -:104C6000DCE506B8D271E7C994AE6EFC52B70F0905 -:104C70001B3F92D2773C427A64A0AF55ED1BD9F727 -:104C80003A6E3B03FC6D55CC3EFE1CFE31A8AFFCDA -:104C9000B818233F2E91DF8E017D83EC498D9B67F1 -:104CA000D02B3FF8BE5EB6EFD276381F7CEEE53FE4 -:104CB0006D07BD7EF9DFBFD8FE08F803DEB079804E -:104CC0001FAD7AF10337D1C1DF65657CE1C20BCF3F -:104CD000EF7E9AEE930B1F5950CFB9F08B33990AA0 -:104CE0005DFF85FD7F4D07BDFEC15F4C1908F07863 -:104CF000F0C0CD03FBB363806E43163D7E43885FF7 -:104D0000E5A0C092975FE7650C9EDEEA782B13E67C -:104D100079FE8405CF71ADA2CFAA4B006F2B503E18 -:104D2000407D0D85F7CABD1BFE622A8E0777758808 -:104D3000E885323C847801EFB7FFC3C45228CD3EEA -:104D400005C6233DC8DF63DF5B758CE2F7DAC4F884 -:104D5000BC44BE9601FEABF66E64DF6DA7F874F737 -:104D6000C5E779F8C7F8BEF82CB4C6E273F9B3E822 -:104D700063EC488D9B17A7E173C5813BFBD51B34C2 -:104D8000FE7025382F16D8BC2216FF042BECB397E3 -:104D90001DAA97E1393483B65DD8772993503AF943 -:104DA000CCDC732FF0C99E5F583C60772CFDC57139 -:104DB000DC77170EBC2B2BECFC8853A07AC505D2F0 -:104DC000FBD7097AC64A815556ED74852DEE28BE6B -:104DD0005686664D55DCF8FC143E0FB1FDB03274BA -:104DE000E80E210EFE1EB2E630FD333400E1B28241 -:104DF0005A449E42235E857180CF53B700FD25C281 -:104E0000A7B67E0FAC7FAC0EAF3BD93E8EEDBF9206 -:104E1000EE57E0C37DF01B128E4379A1CD22413EB7 -:104E2000E4057E9E2516EF51F8F3F390DF525FAC58 -:104E3000B226883370385C69BF5F697DDF167EF704 -:104E40005A151C37168EE7BE8E2F0F9A38FF584919 -:104E5000AAA60ED6C9338B99CAB36CD0F7CAD5218E -:104E60004274BEF5EDECBCDDB93DA610C88B587E92 -:104E7000B132817DFCB495F9BF571E3C540C7CEDDA -:104E8000DCE19F73BA6474BF72EF2959E5F221A483 -:104E9000970F09FC283BF9BC57BD1E7FBC557BFF13 -:104EA0001277BCCF25FFDD30FFCF3BCD44A5437C3F -:104EB000DE6E9A1A4FDF6AB69A8D79B5AE312792B7 -:104EC000E87B26B71DCF33D6AEF31F57412F79CFDE -:104ED0008CFE1522F93EB3E0F969BB02F1E55AF701 -:104EE000223CD7A28D57170327C95B8EFE0929AD37 -:104EF000BC94E9D421833D6DF688867953B99B0132 -:104F000072E9E4A8336658E71F62F4C73F48A47EFD -:104F1000201DEF0FAAE05BABC4B3178DE307D69853 -:104F200088A29787969E93301FF2A68D40BE9AE97D -:104F30000D9B0AFC64D5761BC6D5DF3A707937C065 -:104F4000EDC2B3161ECF6479B595DC5E3B73E0F21B -:104F5000F6FFA2ED67E065FAFDCAEDB43FE8ED7B30 -:104F60001D98E4FCE797938A09E5D3956F3E3213C9 -:104F7000F84B25C4C069FFCA9F0E0C41EE42F700F2 -:104F800056EFDE3734047859FEB35FAC0479B2ECE7 -:104F9000270E0224F9D681E3F742FDC29B2ECCEF07 -:104FA000BAF0E6991B611F507D5BD1CBF525FAF372 -:104FB000DB74DC655067EDC2379CD7811DB30C4AAA -:104FC0004AEFCB0E26E179075D3F7C6F95A5E7217F -:104FD000BCC885A88345B489C283611F2EDB63FCEE -:104FE000DE592BB32B56C93D8B58FFE060B65F3BB3 -:104FF000F1BDAF38DD6BEDB1EF6BFDBFE4FC333AD3 -:105000000E7B7FA58554C5A37FC1C6C65DB6E76F7D -:10501000F9C6F118BDF6FD0E7BFE4381E5E393FD75 -:10502000368C132C97C3C353E87E7D45268B61DFF6 -:105030002E77878727D3EFBDC6F9E5723BADD3E75F -:1050400083F93CA03FD489B5EB2780DF15AFDA08A0 -:10505000D0FB8A375DE8575EF1CAE5EE7FA1CFCF7E -:105060001D70A0DF6FC59B0F23BE5758C2F7829FEC -:10507000AE67BF85ECA0FDCFEDFF7526E823E7CC3A -:10508000E1CC947EFC432BDA2DFCF217E33AA85DC9 -:10509000505045E7A33EC6F270AA09BB47A09AE765 -:1050A00079908F6DEC9C328F4BADE67EA28B0B948A -:1050B000249CFF845BD973EE275A7D9B323059378D -:1050C0000FC89323D751BB44AECA073E6B8ADC4A54 -:1050D000145A9722B9586AFD4C701F4321E427B037 -:1050E000B8A039CD472A69F9700A09E0F948E7F410 -:1050F000DE7DF6EF14C5ABB7290361BC9136C65F00 -:105100002AEDFEB136E433C67B14D4036C5D97F907 -:10511000FD08B1F3BD6C562DC0CFA3F13A962758C8 -:105120002D29C7C1FF4E8E72BED467FD6C9F5DF402 -:10513000A4E03ED3D6B1A9C683FC04E265506EA8B4 -:1051400029204A3EE47BF8B06EE2F0B014AA04CE07 -:10515000F7C21E843F8BB3DC2FB2F83001FFABC91E -:105160001940FAB278ABD05760E5F7E9989C2AA9C4 -:10517000A4A5D9C9E004E7F6004E32AF4B2D331099 -:10518000AEF47D7C7E933D702FC0C59A31D2C0A70E -:10519000E4B41243BD0FDC34BAD8F7BF0D3F82F040 -:1051A00002BF8E8271CC7108B7F5357EACFF7F806F -:1051B0005F3D83DFF544D1ED1F396D92A19E107ED6 -:1051C000DB28FCD2A2FB2A160ED53C0F47DB4F8909 -:1051D000F6EF933504832F8FD7B460A93D4F492054 -:1051E000D7CFD8985CAF2681B566E0531EE68721FD -:1051F000692AC9D0F99F8857C5731FE8EB87F68CD9 -:105200005BD17FA9E1D7E491BA8DFC4F390EEB79E0 -:10521000F81DB308FCCA54FD1CF92455B78F6794D8 -:10522000DB1484B30FE303B55CBEAEEFC5A7717F9B -:105230006CAA51B0DCCCF7C916BE4F1E03BCC37DAF -:105240000E702F05FD5ED35482F2F3095A67F67E85 -:1052500098E8FDE1C9BEF6B099E21F79928225FA7D -:10526000ABC9094B685836C455891FE825F9C48F66 -:1052700042B856D28EE72592B57B5D5ECF499E8BB4 -:10528000F11F6266728A98581934831D150BDF5A14 -:10529000DF612BD8E189E65376728900DFBB3C974A -:1052A000C5CCD2EE693F01F73C389B1C6857A6FB82 -:1052B000AAB23291BF5A905E9DBE8050A9C3637A54 -:1052C00002FDEF21FBB40F801E3F843C445A3EDEBA -:1052D000926B03386F32B77B811F6EE2E7C5953959 -:1052E000140ABAFBC2DEE47CD25D6AE4031A5FF6FC -:1052F0004C2831D0B3C67753261BE95EE3BB2FD8C9 -:10530000985FA3D25E7E06E6931A69C57D19BB0F2E -:105310006ACDB22A5C8BF7CB30FFD32981C5D5FB90 -:10532000F2038CBB5FECCADE01E7A9B5FD13BB7EBF -:10533000A9611A7EA7571F34C7CF07182230B9DEDC -:1053400040E98D605E82828868A6744678DE02DB62 -:105350004FE3B0D4E8781D613C44ED10D93CB9BFAF -:10536000563B7BB3CE5AE2073CAE6F677B68A09D8D -:10537000C749D344905D44A2F6A4933E920E8DB7E4 -:10538000827E29997D47810FF6B8C47688E3AE778F -:10539000CEB6421C44482E45FAF9CA5591D55F5CF9 -:1053A00007EE5303FAF3387DE474219E8745BFB0BE -:1053B000C95342C02EDDE7ECB4633E935D34C49F15 -:1053C0002AED810CBB4E4F2D82AF73BCC3B0FB12D4 -:1053D0009CB72CE0EB21192AC9D3F189DEFB8F148D -:1053E0009514E8F8C5BA61B7E0FD4A7DF944027E3C -:1053F000B8EB7F861FD6668510AFE658FE93E6C7EA -:105400003B9D68A9C2D508263274FD0F92914E27A4 -:10541000023C887347AF1E74534EDF79C6F2BFA8B3 -:105420005C53D00F46E5DA53E3809F26946B55F723 -:10543000211D370D51808E0F353FF22CD43F69B6B8 -:1054400028C0BF1645361285CEB732321ECBC52DC9 -:105450003FC6B2A2A58D6E2242D66EAE6C9E0BFDEB -:10546000B799D0FFD31DBAEE4235AD773759507F8B -:10547000EF6E7D200BF4BFEE268702F7AB74B78E7C -:1054800036B63798709F75B79843261E0F36413C45 -:105490008270FE0E5E20DD7C49A9827AFCC5987878 -:1054A0004BC5168B5F7027867F454B7C7DB216FE01 -:1054B000C9CEA3E5037F2D3BF9A32CA00F8DCF3CD4 -:1054C0009C42F91EC0EFA485C48B0BDC649FB2C460 -:1054D0003E004AFFFD768CEF5FDD3D589F8854EF1C -:1054E000463C05DCB30C7E5FE657FD84EBE5C49AD1 -:1054F000A0DDCDDFF7C46F5FD1F4A7B71FA5B50D51 -:105500008546BFB609FCD502D8E3B3F8FD196C3E59 -:1055100071E89AE9D34D16E42B0BB83F4AA3F32860 -:105520009D05DCFC9C9E810E97441E43BE276C2A81 -:105530007A6A3C85DF1794FE803E844D1307027C17 -:10554000D736DEB0E51E3AFE97BF35E1F3C5111B35 -:10555000F63FFBA8EFA97BC05EF83733E6917C7974 -:10556000740AC691CF9A8D7E8C1B1C6CDF1FE4FBE6 -:105570007F516493413F5FD4305F063FE8A24833D8 -:105580003E5F044124CC8BBFFB976579105F229866 -:10559000CF72D07EC79475284F4BD08F56B9D91291 -:1055A00037AFFFA05D31F2ABAE261C9750FD2C2D1E -:1055B0009D8FA7E33B959154DC1FC4A312C8EF5EF7 -:1055C000C4F94FEFFC5ACD06FE73D616DF4F73D4E5 -:1055D000CEE4C2A2C80DB8EFFAAEEF467CBE48FBDF -:1055E0006E17DBA7D1F53C353EDE7AA2EB9880FD45 -:1055F000CF26C7FFFE9FF9F7BB6B16133FE55F157C -:1056000016DACF09DF7FA07E1CD8F9ADC929826EDA -:105610005D952DCB885FB7AECAD679B2FEBEC928DC -:105620001EEEFF659914C5C39F1B974F595708FA83 -:1056300042F97FC23EAAD834B1388076FE4684F360 -:1056400027665F26F0E3332D0FB8E3E50FFFD9AEF1 -:1056500018FC1C952D1C3F54EF2ED5E147C34BEC95 -:10566000FBDDBFAFFCEA51E053DB5C06BE125BF62C -:10567000C15B767CB8D91C1ADC0A4800E1A6BC7272 -:1056800002E87AB3C307749D187ED790407FF04B31 -:10569000A03F533D4B748C86EF12665FB6303AB82C -:1056A00012DCA2DFE57450167F3D63F97EEBAEA9F4 -:1056B000262ADDB0A7E52BD1C12344B5F6B38E5E13 -:1056C0003A78C24007631D9B910E3E03FD27BF2F12 -:1056D000FE4FCBAAFB7AD0771A4D18F73A6D57D305 -:1056E000BFCFEAA3803F9F7607675E5F1AAD2FD9D1 -:1056F00035CCADBFA7F14C0385431CF88D75C4ECC8 -:105700006F8D7EF2545238E6FF1DFD7C92E0DCCBBB -:105710004DF6B21B009F2418DF9FAC95BDE7AA93FE -:105720009CBD762FC8D1D3CE9CAF42B4B5C11EF874 -:105730009E83B6D7253F8472FEF46901E5F0DADF77 -:105740003F9C0F7CB88FFE5B1379FAD361E8B7FCFE -:10575000974FCDA84FE1B884EA3F200730671CED92 -:105760008021E8674914CF5D0197F98E8EC675B523 -:10577000F8EDFA9ACE1FC3F8C4AA128FFEFC00619E -:10578000FAD8FF8179E8FCF3B239E0F181BD2B90C2 -:1057900072A07BB3C4F2D7CDDEB451AA0ECECB1C1F -:1057A0004C9FB41D39D2904DDFB72DFC770FF8F91F -:1057B0002CF43B505A33A48B7A7FB996F745F27498 -:1057C000CF7320BF82D60D7E073ADF7EECE6D7048A -:1057D000EDBE4F15EF2B9EAB5D5800A0A374F39167 -:1057E00096BF22D5B1F664ADB98EB5733FEAAA0A69 -:1057F000E6277D6B5E12C24F5BD7DCD737E07D6951 -:10580000735F1F341FFC69739DF97F0478BE06899E -:105810003540F7C94C3EC7D2C566CE7F7ED026AA9A -:10582000663ADE1173CF6107EC8B1F0A68577FFF62 -:1058300083236620F9FF3876DA0CF723DC078945E5 -:10584000743DF3882233253A84EFCF27ED2E566F2F -:105850001F00F79946C7A326338C773F8B3F7FFF06 -:10586000836353408CD2F1D64379DF6F890CE3CF49 -:10587000EB50EAD9B1273EDEEB743C313A5E2FFCA7 -:10588000242BC2230A1F2BC2EBA3DE73242AEA17A0 -:105890003AF8A2BEA2C1B716E046E1373769CE7426 -:1058A000529C78BFCC750EFF23298ECE2716BE5F83 -:1058B00042D320385FE67F09F6CD3F3BFC7BA15CFD -:1058C0006EEDC99472F0BC573BECCB95A640563AAE -:1058D000A5ABF34303F903E0505067FC386FEC3E8F -:1058E0003D09FBE55A28E9BE8079F07329F7F27586 -:1058F000BEF5A3332ED897F5078E6742B9C2D4B54B -:10590000F96ED86FBF31A1FE79B123BFDFBCBA9366 -:10591000DCEF72D4A1DDA3C1D6791FD7E7EEEB701F -:1059200084D652D2B8AFDAD46B5F015DDF57CDF2C7 -:105930004F88D4597C87419FACE3E7D4FA8E03F6B5 -:1059400042EC38DA3A0F670EBE06ECCB6747CB68FD -:10595000471CFAEDC58F2A69DD3ED48A76C2E6641B -:105960004EBF65CC6E7D36D9EF2802FF57638A4F54 -:10597000A5EB6CFC256917299C0E8F782834A91497 -:10598000EE7916D177B625F25C7012BC57C8EE9945 -:10599000F170BD744BE7E916A0C733272C1877F8D0 -:1059A000C465C2F9369ACB33418FFF639B1CF7FE67 -:1059B000B28F5C12CEB74DE8C23CBDF92468057EBB -:1059C000D1D1397B20CCC7ED231E20FF33AD2691EA -:1059D000DD6FA6F95BC212F3F7AB12ABFB79E9B14D -:1059E000E9EF17DB387532E6792C687A17CFB1B951 -:1059F0004BE3DFEB6373B2F9BA3A53A6017C5D93D4 -:105A000045CCC376F97A04782FAB73928CEF078577 -:105A10007EDFCF5AE399067085F781CF675DE5FB9E -:105A20008293E5693DC6EDEC36B3AF7E321DA76DBE -:105A300073B200F8D0FA0D7632BE7266B2E64762F3 -:105A400079C299791E5B1E9D77A61F37377195061F -:105A5000F11CD30EE8C7FCAC0887B611AF84218EC9 -:105A6000DD08FE15C0B399D153E36601FDAA147E8B -:105A700083414EFCF109CBADB08EAC06C103B63B01 -:105A80002DE3CE7BB6CBCAE8BCE929B40BC14D0BE4 -:105A9000E366B6BE8FF3722558EF1A4E1F7FBC0225 -:105AA0007D9C77303F54667527BFDF2E8CF7D80575 -:105AB000014E50F797F2FBEAFC8A3E3F26BA7FD6AA -:105AC000723A247E88B3558C9343E047101BDAF07A -:105AD0009ED4F9410BF91E5D5F93C0EE1D55478BB7 -:105AE000FCFE24FF498053F36303310F6F83E8CF3B -:105AF0000439ACFEB38C71BAC3FE8BDBE03EF8ED2B -:105B0000E364DC1787FDEC5CE1B36B72DA204EE9ED -:105B1000AA9ED4329F8E17F260462CA92D25EFE461 -:105B2000439C728DE81168FF60B996B7EDC17CF2B5 -:105B300051A62FA615401C6F90883EA53302BBA727 -:105B400061FD9A491EC0EB7A4F9AA0B75F66713A21 -:105B50003891523ECB49E1E37DF4710F9C85DB1215 -:105B600049BD06FC886A83ACEC62F142BCDF21953A -:105B7000E325B5530C2F7263DDB9989ACA5B2630C2 -:105B80007FE98FA707989F1362A363D0CFC9FFBC9B -:105B900088D7345E6B1C69C7CAD6758BB03F8C93AF -:105BA0004EC7492D15C363207F2DD9BF1DFD7653E8 -:105BB000AC08272275B5009C425306633EF8E3E328 -:105BC00087BF0BF9E3A9477B66831C0D0DB5FF4723 -:105BD0001BF0A9F5B202FB3C754DF73DF03CD9F73F -:105BE000E40350A6D67DF808F0E9E4AEBFD4E0F3B4 -:105BF000A9B2C1BF98FAF1D9BF417B6AB96CF05321 -:105C00007E9552FEA093C2677B613058A1B0E7FE3B -:105C1000F4E83AF6ADED9C0AF7D89F9925B2F33235 -:105C200084F1C3AD5B3DDA39E552900B1ADC36885E -:105C30004A7B18D635D38AF491473A915F0D826832 -:105C4000766E142FA91F6FBC1FF23562E7D3E014E4 -:105C50007ACF51C3BD80786E3107CE1F4EB6035D3B -:105C6000EF2FE9F4823EBF39C1FD9D475DEC7D8B8E -:105C7000C8FCACB1ED47783BB0C496122CFD455042 -:105C80003A899A046586D50FF9CFFB45E53F91CE59 -:105C90001F3729801FE86FA6F83BF4CEE7E85F3C8A -:105CA000147C1FCBE75C05DA78E174FA7E73E9694E -:105CB0008CD3347B188D5436307E51E9EDB242DC02 -:105CC000A4B2907876707A53353883BF8CCBAB8A88 -:105CD0003B185CD30A09C67DC11704F74BA5433FA7 -:105CE0000ABFB486B5F7231E49A79A4BFB35C3B844 -:105CF000809F3A91B071BBACB87F83268C7BD2FD7C -:105D0000FE3BF06B55340DC4B83F1C0F86F152F8C2 -:105D10007753F8786D741CF01F9E6930E1B9004824 -:105D2000BF81BAB286D232D2674F59011D5729F5C9 -:105D3000781A353AD0F818DD1A0BA8BC00B82D50E7 -:105D4000D5FB81FE4E5B3DEFC03C1C5B2D0AAC7F5A -:105D5000C1D6571F06FDC5E1ED6A00FE50398ECD54 -:105D600037A5893E473D47F91DF4AF6CB228EC7B5F -:105D70001C7EA59CCE381C16F2792F6C65F3B60FED -:105D80000D05813E2BD750B8425B80D13DB844BF52 -:105D900011715F1D85F5BBD4741C77C09C987D1173 -:105DA000437FDABA2AF8BA2AD6B07511BE9FE8B492 -:105DB000C2306E45295BE702C2DE17E1391D7F2143 -:105DC0005F4F85FA0A960B1B2C86F1B717ECEC8413 -:105DD000F96417CA8A807066F71B66F27565D6B1DA -:105DE000EF6516BE82F022D5BAF9A25F5557A7FB20 -:105DF000EACCAFE9C682C3FF70D0808E7BFA47EC55 -:105E00009E81BCADC6759DD998FF1C9CF7FEE40928 -:105E100019E3DEFB45DFC92CB4476585F11FDFFBC5 -:105E200033804F2FACF3011FDF57C6E07FE63612F9 -:105E3000027A1876B43C05E03DEC68809755184F1F -:105E4000A700117AF91E9D1F35991A04E09791DC7D -:105E50009716031F18C7CEF70CD5CF9BCE2FB521B1 -:105E60007D12E443A58D4B9924E315DE31ED479F68 -:105E70009E0DF78FA61D79FA01F8CE20A25B0FD0F8 -:105E8000833B979D6739425BA15F75F7A3808F269F -:105E90007E9FFC3098590A9647A04CA5FB7B530A7D -:105EA000CC5322934BA2FC60D7136346015FC1948D -:105EB000A7122CC3A4A42FDFD0F51FC1FBAB429CBB -:105EC0007E16B762B0CF773D71CB08B0E39B414FF0 -:105ED0004C827B383D5F409E8EEA1311EECDE6B0DA -:105EE000B5300DEEA51609E82F5B0A3E1461DF35CB -:105EF00077101FD0476AF9DF2D7A3C96B9D8EFEDBD -:105F00004832D904FBFFF088EEA980A7D02111AF59 -:105F10001898F42BE7D30ED0873E6279306DBFAE70 -:105F200042F9FD50A61CF73E5D72053D31B67FCAB1 -:105F3000B0D9E8CFCBDAFA18DEE7593955F27D8FC0 -:105F4000F64EDB5A56067A8C524EA96B209D77EBA3 -:105F5000A8B5F83B103358BC4C99CA9E2B9359B93D -:105F6000A9E6E88FC16E0FEE916C7974BE2337B24B -:105F70007BC436155EB406A85E5A5AF6B2F536FAF8 -:105F8000FCD3522A05E9F34F275CB4417CE7D9D210 -:105F900049A900CF8E06A35E47E0722B6A0F155900 -:105FA000827E179D57D30704E169B2845B2A68DDBE -:105FB000F4AA13349C3E76CEC6A6B63940A70B0A87 -:105FC0006474DBC7AEB793CB8BF9D53D53E1DEFCF0 -:105FD0006C9530FF7EF02964CA0B39CBC8563B91D3 -:105FE000E9B8B632FB2428F9DF06BE1C2C0CC8F039 -:105FF0008AC6CF9A8655EC067E76DCC5EF0BA95A89 -:106000008CE7CA70FF9B401FEA298B6737153BED71 -:106010004C9F6DBDFD38F8A91754337D3FABF50B90 -:1060200001F141F5BE4174FCAC52BC5A902C58139E -:10603000B416017EF244A228309F7602764290CABE -:106040001F3D1CB471FFBBEF2F7359701DC5A03BE2 -:106050008F8EAEC7C9D793E9A3EB8923A70BE1BB0A -:1060600090EFF3CC1787C603FCD73013292B784A5F -:10607000B0EAE691A55EDD3C8AF83AEA5CECBC85C4 -:10608000ABB44BC0FB6B62F83BA8F3B06FB73B2ED1 -:106090008C62F6BD919FF6A973BA8A7D9E19C3AF33 -:1060A0008A2CEDD311BFFBD8BDD584D07D6BC5EB59 -:1060B0001B1576CF6748BB5FBA0AFA8D74393D402D -:1060C000074D233E2C01F86CE6FAC2C24282F6EA82 -:1060D000C28C4ED417E6D7717D41F2D5039375B4C7 -:1060E0002613ED7E18D01F50550213BA8EEB0B9A73 -:1060F000FCE772BBD2DBD98072B58E9DF7EBD5334E -:10610000542657B3BC4CAE5736D0EF289C98C7E8FE -:10611000F51226C795AD5C7FE07238957F37AD816B -:10612000C9AB54D023DC9006A1A25CC618567A54A1 -:106130006F1950C8E4656AD37E946B2F3A199F4C4F -:10614000DBCAE4E5D0778FA900262F7DDC42F9F485 -:1061500013BCDDEBA1FA594A543FDB20F2781361FE -:10616000FA21E6FCD3796EE6FDB5E73BF9FCF61FB4 -:1061700049B915F8EBAE600E9E2BD7F62D7A3F6924 -:106180003D93DF879059CDE2E42EDFA2DDFAF3677D -:10619000152E76CF50858BDD07EFAA0E7B615CBC98 -:1061A0005701F9B88CFEC58D545F42FF13B7AF4A53 -:1061B0009DFC3E194E3F89E489C6875CC4EF2EA43E -:1061C000F0FD34B41BF9B54AED2558DBA7C1DAC19F -:1061D0004B61BF076795C2FC9BC77F85F91F5909B3 -:1061E000ECC58F343BF35BF275D7D463CC0EED1462 -:1061F000E39EEF497733FF43BB441C004F5B90DDC8 -:106200001B671B27C7ED6F7333BBEB53BE1F9BC7C9 -:10621000EFC6F39909E5B34454531C79AAC9DB26A8 -:10622000C0F3F574DDAE5FD5E3EF0849A17213F258 -:10623000578276679074A11DA916C8E8376C32079B -:10624000AD808F2DA51CAF1E6B1B9CCBFCD678A1FF -:10625000F0003C6FF48B21211BF01CF21431BF0EB7 -:10626000DEDB7986DAEFFA7845AE5BE47052F087D0 -:10627000F6B21A187D358F97711E8DA3D2DB4CD9DB -:106280007AFE2B70FEC9E8AB71FCDB485F573BBF61 -:1062900045D52F3DF3A92E9ED8BDEDF91C8073F492 -:1062A000FE0B7FBFE7291655FF65EBCE387182DE06 -:1062B00076B0A39C600786BE6F886BBAD9BC6F743A -:1062C0001BFD77C05FCD685C8406837F69DFC49067 -:1062D0001BDE236B58DC76098FDB7EBEF3763CAF8A -:1062E0005E44C9CA1C07EF676B8CE7D5CFEE7A7E98 -:1062F00030F36B840CF1B325BB7F3ED2101FF61335 -:10630000256D0CBBB718E5F4DB3ED5628ADE3F2075 -:10631000C3EF0DE446EFD1B293762C9DB07F69E9CF -:10632000263D587A401CE5829DE4C3328D946399E2 -:106330004EAAB0F492209683493B961960E7E68214 -:106340005CE8C152211E91E8F87E0EF1613D8F9408 -:10635000632901DE52A37109698F15F337207E018D -:10636000FB3ED1B9B391EE8A656E8477D5B5E598D9 -:106370004FCEE21533DCFEE56E942F61E4DFF33996 -:106380002B3FFA9391ED70FE68F56676EE45E3EFEC -:1063900068DFD0EFBC94C2E481FAB8807C6C9D6366 -:1063A000E68D08CF26F3397DBC8158AD79F0FB1E10 -:1063B000DAB8F3B99F613E9783E0EE66E7077D7830 -:1063C0003E693EF81B74EDA4B79DDD4BA38D233AC7 -:1063D000260CEF2FDEA77B1FF3A32B62ED802BC9CA -:1063E000EF98FA82D8F7BFA6134A8FFAE35EBA5144 -:1063F000C9447AE5F29B129482EF35584EA13D16BE -:106400009CE2D7C3E539CEE734B9B22026DF23B604 -:106410005C20F1FD11330E9580C970EF1ADE29A1C1 -:10642000DBDFDA7DA4DAEF642DF107E441EC352FF0 -:10643000E0D1C3E71D24AD9306D1F233A8EBFCFBFA -:10644000BF4B0AEC77EBF68BC7CFEE59203C2EB151 -:106450009CEFC729A6A632E0736702C40776C41270 -:1064600052E5BE01FCF9C7D8FDC443E8BCE512B053 -:10647000E3882AA6605D85DF6B395FC3CE0975F3BB -:10648000FB6876F37B85FFC4EF112E6A797826D0FE -:10649000C1E7FC1E9A828E8DE5E0F7296A77CC036E -:1064A000B95FD43EB112DA8BF658D8EFF0703EA146 -:1064B000CD0B8EB9DBE97732E8F7AC29C04F08CABB -:1064C000DDF34DF610FC7ECFF97613BB47B550C413 -:1064D00073F770EDA089CF2F2905BEF75FF7823ED5 -:1064E000F239E727DDEE64862F4915D434484B2175 -:1064F0003ED06B1E73ACC473908B9CA1DD4FA74143 -:106500007EB8D5B78E7EFFD0FE5733E1F9538E9516 -:1065100058FE69DBF14CE05BE70F1C97E3D1ED0A15 -:10652000292C837F6A59872042FCA4AC7D9E0CF104 -:1065300091457B0FA15F79852780EDCB5BF6637D6D -:10654000F2DE77317E323449417C9F1F14403F6F29 -:106550005E8B250C3F59B22F27B8346EDC3E89F193 -:10656000DDC71C6FE0F84F39DE781BE1B2CD82E762 -:106570003F0E6DFB158E7BEEC0AB7CBE04F305CFEA -:10658000DBDA4FFE13C8AFFDFC3CA6B5D3ADF70771 -:10659000FF9DF375AD7E5EFB1D9D8C2BF4D37E8F2E -:1065A000C7D9E9667CA9D30D71B345ED0C0E7F32D6 -:1065B0008765D02397B50B0AFC3E5ED9DE363C0FCB -:1065C000B8ACC38AE72596013C006E145E08979626 -:1065D0004338FF0C80CB6858C7FB988F9FD741E1A9 -:1065E000521C5DF7326700F7ABB65E0A07B6EE7D68 -:1065F00057C253C088A7967765F0CB2CEF10107E5A -:10660000CBF7B2792CEA60F39ABC771EE2FFDC018B -:10661000A280BFA57BFFF1CF613DE70F58F1FE5E81 -:106620006D5E944E89BB04F60FA353D2C1F8AAA69F -:1066300077AF08A5E3EF0CF4B6EF65BF330A20B3DC -:10664000517A2DEA988571C162205EA0534FFB48B4 -:10665000F67B81C14C80EBBE89E14C98F739ED7730 -:106660004CA56026E065A43B509CA4DBE7674FBDCA -:106670008A72B140ACFAC3A3B08F5F66BFBBF1F0C2 -:10668000C78F897A784C841F4A1E0D70FB9D1BE1D1 -:10669000D67B7F4B90E54B9100EEC7457C3F9E6FCC -:1066A000A376275DFFD9969F61FBF941C6FCAA3FFF -:1066B000B5BC950270ABE0E73148E876E447142EAC -:1066C0000DD63872BEF75C5B889D57BC2010BC2F7E -:1066D000537D46835B953CDB10E763FC30A335FBC1 -:1066E00008DA19A1F8E71C63F5A4D8FB5113E503F8 -:1066F0009CE6FCEC537E4F97267767B8033F481A19 -:1067000090F8BC77C5A6159900EF0A381B89F711D8 -:10671000BDF13DC823C57343EC5ED430C0A75BBB5D -:10672000F79474B0F664565F9DF46F1BE03C58B765 -:10673000768FAA7A98B567B3F666DEBEC75DBE34BB -:1067400009E53C11D8EFF99893E1771934B991181C -:106750000EC6DF6568830B3706E0780FE278121DFE -:10676000AFE8BB8FA7F1E9EF3C8EF57F761C4D7E3D -:10677000C1FE84D447E2F38DFC9F80DF7FF77D125A -:106780005C68D85797B7E5D6431CED9297DF03D3E3 -:10679000B496803C5FB8F531C3EF7AC4DEE354CBE6 -:1067A000F372E45CBADF74FBFA7012B3730E27095C -:1067B000BDF794437C6B3821FC9E29AAE2A5F37BAC -:1067C00025A9FE91CFEF2D2F2041D44F4792762C53 -:1067D0000B492796C5A4074B0C33E782ABD487E55A -:1067E0009FCBBAC6C0E2975B03CFDA44CC3B7813A9 -:1067F000F6C9F9A181E7E1DED9758E95D7C3FC8F83 -:106800002479F83CC286DF5721FADFBF50401F9C35 -:10681000E1ED4F1F241EE95C6FDE4B0EDE5BFB9B40 -:1068200024C443A2DF41BB3FE6DE1B762E5C83C35C -:106830000AB84987F6FF65EB6ABCC76FE95E17EADD -:10684000C9C35BEBF0F7AF9692CE7438273C9CDF60 -:1068500023425AD8FD2DDAFD20235A2C86FB4B56B5 -:10686000C4FCFECE32FE7B59CB627F8F8A9FC3DD94 -:10687000040FE2E463C49EE33D9B14FF7715496176 -:10688000FCDF3F893DC7BBB75DC4FCA8D59077A5A9 -:10689000B32F46ECACB218E94BF94D9E5957177C13 -:1068A000CC1FE1B2FB77097DBF5394CCF4807D828D -:1068B00010371FEF760FB7B7491D994EC7F9BFD4F0 -:1068C000AD220900800000001F8B080000000000BE -:1068D000000BDD7D0B7894C5D5F0BCBBEF5EB349F2 -:1068E0007693CD6673DF4080201737185244AC6F23 -:1068F00042C4886817A48ADAE2060402E406A58A7C -:106900002D2D1B122120D6F83522D0842E7829581F -:10691000F5DBB4A848835D3022DEFA87D6B654ADE5 -:10692000DF827C8A88B06A4BEDC5FA9F7366267B4E -:1069300021116CFDBFEF79FEF4B12FF3CEBC3367AC -:10694000CE9CDB9C7366B6B55EB56F608CB506AD4C -:106950009ADE094FBB2EA8143396975A655E0265DE -:10696000E6D0D94778189BA69F72C853CE98B141FC -:10697000BDC404E5BE1D4BFA0D506E75ABCCA440F2 -:106980007B878E3128B31C5D700494DBEC3F73CCA5 -:106990001FCBD8481BBC877E0AEC2CE8817EF76FA2 -:1069A000BF5D87E5D666C6B2711CC5DFEFA1EF54A7 -:1069B000F630C33F6D46998BB122FC278CA3B28D74 -:1069C0001FEAD318AB6E386E89D8E07DA476061B1B -:1069D000CFD86576F87822D4BF79F57B58DEB6F249 -:1069E00098C30FE3BDB87DEDAFA7417F8620C005FA -:1069F0005D947EDAFAFA34182FBADDC87640F9339E -:106A0000FCBB82B1C255EAB1889906649FC17FF987 -:106A10002B12CB4606E552512E4638E2EAA13C0E37 -:106A2000C7CFC2D21C167661BD80D7A9310670329D -:106A3000BBCDF9CE18C62EB52BECB361B1F2C5585B -:106A40000694EC3474545901CE9D7F54BC2D507D76 -:106A500060FBC2229CDFD967FC457698C74A73DA8F -:106A600078961E8377E099EE11E3062C3A373EC301 -:106A700016E68EB51FFD50B3C90FFDB4AD66DEE35B -:106A800023183307FBAC63701D0F19BC50647729C2 -:106A90006C4E08EA551BD34230CE388742FD253F65 -:106AA000EF5AED79B9C4101BF7AE4FAF9F83EB1BC4 -:106AB0004DB56A3B9473E192DFA9764F00D7D7902A -:106AC000CFBC29309EC1D99F6B87EFC63C6DF4DAED -:106AD0000065D3FE736C7A04C61DF3DC4DCC93CAFB -:106AE000F185F0AA2B8DDEE3998C99563ABDEA2503 -:106AF000D8CE46F4F891CD183421FE57DEDD81F56D -:106B0000ADDB2BDC9EB1B171D7AEB67B5580B36BDC -:106B1000B5D9ABC204D78AF925C357E0D0F982F0C2 -:106B20009D51C7FC585F0FEB80F4536F4FA1E752A4 -:106B30003B87BF5B0DCC42F8BB817E5A905E57709D -:106B4000FA5D9E630E229D2F7F7178361B3BC8BA7B -:106B500088E723ABDDDE1280A36BC53C37834F2B68 -:106B600097F559AE82F92F4F35DB911EF569231F3A -:106B70009882F4FE9281215FB5A65678E6C7F5A704 -:106B80004F9BE4467CE875815C6667ACC57E4B8DA7 -:106B90009A83F412D8CABC8CADEFA8AA512F857283 -:106BA0006A205781FAFB3AA6F1FAACC05605EAB75B -:106BB000744CE7F505815C1D94B7775CC7CB230265 -:106BC0005BB1BCAB63162F8F03187219EBE9B8A148 -:106BD0002600E3B71ABC73BC30EE1300FF58803FA9 -:106BE000249E3F177891F53FC3F780EFDDE2995C73 -:106BF000FF94F86ECF10F57B457DEF10FD3F2BBE67 -:106C00000B0FF1FD01F15DDF10DF1F14DF1D1AA274 -:106C1000FE2551FFCA10FDFF4A7CD73FC4F7BF16BF -:106C2000DFBD36C4F7BF13DF1D19A2FE7551FF6625 -:106C300052FF6F89F611F13E3FB5FDF500D05D3E84 -:106C4000C82DFC2B4D6DCF40BAEB6A2E27FA6F9DF5 -:106C500008743E3646EFF90AF361B9D4A1527FA514 -:106C6000288FE1F9AAE8BF7259C9BD4877CB5FD533 -:106C70007B910E5B15EF113FF41F58A6F3A2DC5D6C -:106C8000FEA29ED3F93235C8E2F8FBD524F8B70945 -:106C9000F8DA04BCCFDB87517DD14AB77786949769 -:106CA000C8F7F6C4B219F84983F1DB9C5CBF942E97 -:106CB000AB328F42FD01FA05E5E65D3663D804E3A9 -:106CC000DF6557A9BECD5965C7FA805D25FD73976D -:106CD000B3CA3C1FE5AA0D845D058C67E77DB7D973 -:106CE000D59A20CA0F4735D54FFBCF197694A36D9F -:106CF0002CEAA8C4F9AD02BD02DFEF6FAEA2F745E2 -:106D00008E3F39503EBF9CC1F9BF2FF5A0A518DAC0 -:106D1000A9DFD691BE186957498F0D5BA50B7AA0E4 -:106D2000499F7DB90ECB0FB6717D057FA965307E79 -:106D3000091F9EEDBCBDE2A552D467F7A85E8F8700 -:106D4000BF53E3F44109EA2BD05F398E0C2E1F8527 -:106D5000BEEA2E671AF61B709B830F43BF252A736A -:106D60006766C4F09EE3D07339AF9FE145BD36BC82 -:106D700023513F15B7C7E92786FA32513F25EBABC0 -:106D80008266908F71DF9BDCF684B2DE914AFA094D -:106D9000648CF733187A79CFF2ABAC2C26AF93F52D -:106DA00051ABD00F52EEB67E7A49827E907239593D -:106DB0003F9C5FBEFEE6EA51448720AD3CE797B3B7 -:106DC000AF221DC03A1AFC0AE90FA6FADDBED4F3C1 -:106DD000E3CB60F0D9EDB6F3E3CD90F51AD9150603 -:106DE000BF4AFD9FA357CE8357D9CE687EB0FB38EC -:106DF000E8B53FBD7947290396590BB8A1F5CFD225 -:106E0000051F8679E7AFFC6937F69F77D0DA867879 -:106E100036BAE777B7E17C3A1E600CE8496FE6F4D2 -:106E200064CCA9B2E3F7AA4E73670C87F2AEDFDD3C -:106E3000AC003DE9339BBD0CD6EDD0132F655C83D0 -:106E4000F87BD5407C6ED2F9EC6C388143F4B6AE59 -:106E5000C0BA7D03D1B1DF8C78CADF69263DC0029C -:106E6000DBD76B40D4ADB01C6C32D67F7DBD06F84D -:106E7000D9A90C94AFC6722868E4ED4144E3FFF54C -:106E8000E81451CF341558F3714511F5FF59533DAE -:106E900005DAABF6312AE89DFAFB7ED66EB81CEB1C -:106EA00075F27B8D4D82F9E278A2ACC2FAFCB44F48 -:106EB000D407C2EDD5C0443D46393E0B60FB1E9D54 -:106EC0008E9703CFB463FF8F5789EF030FAED7F2CE -:106ED000099E6BF40EC6BEE3E86BB75D1A83F7EE4E -:106EE0008C97DA5B607E1F782269B09CAC61FB7185 -:106EF00017EAE775739A7D8837247C1FE8C414BDB0 -:106F000087E86960DD76CF0CE441ED99837F4B1B08 -:106F10000B554DFAC8C114C05FC39E66B301BE379E -:106F2000197C81BCE2D8770DBB6BC99E69EA2DA3A1 -:106F3000E720DF1D5287FD4BDF998D1730DE07E11B -:106F40005F373E06550DFAE6769B9EDA33BEFE832A -:106F5000CF4F7EFFC163BFBE01C73BED89B8A643DB -:106F6000EB7561C0CB20DFC9F68D7B66D2F3D729E4 -:106F7000DA7A07F0752DC82E92576AB317DB87CCE3 -:106F80001D762F20DA62E8F0A1DE00D40775936247 -:106F9000CF8D8E126A9FFC3E99BF4266963903E5FB -:106FA00078BD4A7A2A640EA48C87F246D887B4004A -:106FB000486BCA7E37612C969FB431DC97B4D6F704 -:106FC000B9C7225F798D0CEDDD8D97867290CFDB8E -:106FD0001A8C731E027842E1E5EE0571F6D6DD19D2 -:106FE000069AD7FAE781EF2E86A721E450F0FB112D -:106FF000A03780942D0EBF19F739969C0C1628C621 -:1070000076B68DC89FEB0DFE9A2A6C97A323FD627E -:107010001931BBA60AE07067E9143DC1517D6421B6 -:10702000EA37BB1135283B9231EF6788A79FAADE6C -:1070300066E4C39FDA6CF60054808CD450FEA9231A -:107040009C412C9BF4AC19F5785E19E8F3383BF6BB -:1070500088909F471C468277A32534B312FAB12E3D -:10706000D7D90330DEFA864DFDD3609C1F353C75C1 -:10707000B805DE6F70A90CE1B039D5B011F48FE11D -:107080005A8011E07EBCC56747F91ACD52D90EA8C7 -:10709000B7961899274E5ED9C642394E4E663A5574 -:1070A000CD02DF9FCDF0BFE880712F79F535337EBB -:1070B000EF9EA8D321DB8454BECE69E589FDD8A715 -:1070C00024F693519D58EF9C9158EF9A9D58EFFEEE -:1070D000466239F7B6C4F22C496F20736CA08FADAD -:1070E000BC8A59231FAE467D0BF8F903E2DF3A5202 -:1070F000E745FC581A1E3AB110EAF3509EE07E684C -:107100003C23BD7BA0F03B1EB40B4C19CD1EC7D851 -:1071100073F1915760BE06D7CB56A2DA19B4B7BD4A -:10712000F9DEA7D8BF8DC5B52B46FC6827113FF8FF -:10713000E7067852F11F1EC477F37F7D0FF5E261F9 -:10714000BD17F19DD7A0D2F8F7CCF604F5DC9E7000 -:10715000A33D9326DAA79937F6EB419EA7BDB97EEA -:1071600019EE7B93F1EA62CD0AF225D007DF6FD7E3 -:1071700032D21FEB74AC0EE906F708D81F994720EE -:107180002FAECD34129E1461EFA0E6C07A97B09F67 -:107190008C39B759908FEF3AC8E9FF2E23EF67A0DB -:1071A0003F0F0D8A24CF504EA666E812FAD9641715 -:1071B0006D4439CBC1CB3D7D19D7205F6E9A9D318F -:1071C00001E9C484FB2EE82F3DDFAC8D86F9595EC2 -:1071D000340614E8345D657D0658CB1E2BBBD507FD -:1071E000706C39640DE8E1BD65C17FD8D14E1B9F3D -:1071F000C1E9BE678DF7372807A2B52AE1D192D53C -:10720000619F3096CF2100F02139A05EAC1CD1499E -:10721000769EA5B283F4BBA5ACA303F1B465868EBC -:10722000EC8D8CDB7444CF9682D0E112F4132CD019 -:10723000D9B1BF0C50FC46E8E487F91D3E1FF60BA0 -:1072400038D7557052C17E6986304EA6C0ABD3B9CF -:10725000FB0E05FAC9C4FEC6F3F6882787C053455E -:107260008687E0768A7E334BA0FD78DE4F5B45ACA7 -:107270001FB98E5B6A5810E193E3CA7E06FA679ADB -:107280008272D5F032E00DD64929341370772D6122 -:10729000B43FEE59E36BDE4E7C6D233F47AE33BF08 -:1072A0000AE928F7D0D659BAF1F89D95C6312C6075 -:1072B00041A4E35C9599BF9A81F68D8FF098CCAF8D -:1072C000397D1DD7A39D2AD725997F7354D6AECF7C -:1072D00038978F739CCEAA91E307E1E7247EC939E2 -:1072E00014FD36127D325F6F4B395D867861F1EDAA -:1072F000F5E72FEBF5A1C3E8E761D9A02700F585F5 -:1073000049E331F64F139615A6F37C361CE5BE43D0 -:10731000D031E82B60D69E09F6A936E4D3658CE817 -:10732000ABEAE98D37BF0CFD9D1D61B4A35E293822 -:10733000D4D18FFA91EDF18FC275E852FD3F4E81A5 -:10734000FAAE23D90CE5F67A0BDF8FA982CE93F53E -:10735000CBDD197C3FE6413DE7FED79FD23E0C9541 -:10736000B8C6D881F7EEFE8F2B5F3467FD0FDA5970 -:10737000ECD1F51A94F3FBFA5B6C38FE7DCFB79B2A -:1073800001BF965779FB0D500EA888BF7AF2671D92 -:1073900028584878525F3731A4D3717A2D8865F622 -:1073A0008685A1FCDDF9E437EA3C287F5CD33D28E3 -:1073B00087BA04BF6F15CFE4F9AB46CD8FF644F220 -:1073C000FBCE01B9E43B510BEB38EE4123DB0095DA -:1073D000A5BA79EDB8BF8BAE07F90BB5F3F49EC62D -:1073E000BBE3F6B7EDD6CA4733E0BBEED566E6079A -:1073F0008339FF1385F981390B9CBFAE44F953C81B -:10740000C20AEAD9C266307891AE5658993F8EDEEC -:10741000F33F51A97DBB557B34238BBF37831C3091 -:10742000F07FB29F66F858AD93CB28B45F0C8F59AC -:107430008FA2DC60CE6A6D603F320CE917F43E8C9F -:10744000F7B498B70170689800FFD97461D3F873E6 -:10745000DBF70A79AE9A6D619497AAED9523245FC4 -:10746000ECEAA9F876B8EF262156CFC82F8B78A181 -:10747000F2B7EC54CE03F96B9A40767F00F7DF81C8 -:1074800034BE1F619AE671BA905F182139DFCCDAF9 -:10749000CDD08EA81DF82D87F55BC86EEE631EE477 -:1074A00007F4B0BD9342228B215EBB18AB89E70382 -:1074B000F9947E0975A59EF653639EB3103C8666CB -:1074C00016B4A03D84B001BED5152CA816C7FC8209 -:1074D000A50E0F7D6764CD64CF3EFEE95BB928A79A -:1074E000AD07C11EBB18D7594772CA6A4DE43FC6E3 -:1074F0005A084F27057D74AFB6D33A0FECDFFCAFC7 -:1075000089758EB4A0BE285C9191B0BEB25DFE2795 -:1075100079CC7F497CBF41EA2FBFA44F41BF4CFECD -:10752000278554DFBDDA739EFE870DD17F0ED1D142 -:10753000D0FDE7537D77F835C775808AAE689FC365 -:10754000E789D9D7C978CE5F9128972FDE935896CF -:1075500078B11834E74CC0B9E5DB3AEF76E8EF2BA9 -:107560004712DBD514FF96F6BFB1F661E7F5D81EDA -:10757000F6E7DBE1ED652712DBFB2A9F77201FC7CB -:10758000DA73F8AEF824B15DF2FA24C30B70657DAE -:107590003D0EAEA9665342FD9CDA73E0CABA310EC5 -:1075A000AEABDC89EDFD2D83C3754DA9E973E19286 -:1075B000EDBE36E9C2DA25CFE3FA1AD31078E7ED4B -:1075C0006F9C7361FDDE52F7F9ED6E5D993C4E8064 -:1075D000F8A551A75D9E09CF79F80AED459B95EC7A -:1075E000DE647A7954E8A76A343CA0BF8BD2B4EA4F -:1075F0004C785649BE137E86434F5C948D723D4F46 -:10760000F8D199F02BF4D4BBC9AF70B3680FFAA4CA -:107610000DE545CF4EF82E8DC3156F3F65D6F37D32 -:10762000859D45899FA5BD94C1EC0ADF8F737B675B -:10763000A87192FB5F97C1E19EBF722A7B1BF8F095 -:1076400029A3BD52C5FDD93685EC81F9D59A3E15E1 -:10765000E86372BB427EA5F977FEE687E88FB9F44E -:10766000B8674F04DECF0F3ABC386C633FD3304E5F -:1076700090AD5F56F63D78DE7F00EC1F515E86F4DC -:1076800066D33CB8DFA84588A09F5386E6323BCA44 -:10769000CD6FDA34949BB5B3B53FD07CFF0156096A -:1076A000B45BC0A7CE9EEE9C69C47847ED373C938F -:1076B000D0EEA90D59347A9A996A8579D4823D869B -:1076C000CF6C23532DF8B432333E2BD670FB2B6D89 -:1076D00092CF580BE3D7F6FEE4CFF8DD2235BC9FFE -:1076E000DB93419A776DEF8B7F457B6D81E633A20B -:1076F000BC18B3D3C86D52410FE34289659407F1BA -:10770000E5B27062F9924389E5F771E1607D260B7D -:107710003FD6817D2692DB4BDFB792FDB917141E51 -:10772000EE93038F9B487F4C5D6AA3F57AFFA475A7 -:107730003BFAF5F6BF6EA5F64B7E6AE1ED75A12723 -:10774000B01C782285F6D94B3343151900F72F3E2C -:10775000D513BE715A06ECFF89D1DB3760FD25A138 -:107760000A8C8B3D751163FD58AF06C7E33C9FFA49 -:1077700027F75B477799823BA0DFF79FF9C913DFB3 -:10778000C57177E56528B03E97A15E8076931F347A -:107790005B71BF31F9FDC786A3DC58BAD39430BF03 -:1077A0009D998A88AB79D290EE86F23B1E5BFF13DF -:1077B000FABEF4C411A2BBBD86800EE37881F59CAD -:1077C000CEF65AB89F74AFA53088EBF47426D73B39 -:1077D00097E976FCA811EDCB57B91D3254FFA5EE01 -:1077E000F9DDD583F81907EA61DC6258E733EF5910 -:1077F0006FD5008E519B13D7697430B1FC4B31AFFC -:10780000792CEE7D31C2336CAD1BE1D9CE089ED20E -:10781000136FDE5C8CF6B889DB21C9E31ECAE4F283 -:10782000E1D147A11F2E67F4DC0E078C015F2F15F5 -:10783000FCF00B85DBC1F0B7220FE87F291A10C3DB -:1078400062EF9726C121FBFFAEC0D3C7E6B41DA8E7 -:10785000CF9D464EF727571FFA21C63165BB775695 -:107860006B5A759C5F79E1E665077360FDEB7BB24F -:10787000689F29DFD7EF7ACE750BBC3FB553F5A2D1 -:10788000E95B7FD3233F988CED76E9430827D6A3A5 -:107890003FF354E8F9346CB7B0CB3101FD25F2FB6E -:1078A000459BAFD4AAE3E4E917E527C9FFF5627F5A -:1078B000FCF4A4FE697980EFA59B152F365B1AFABC -:1078C000FAF5D7A2ADD3A5F7627CA342653EFD04CD -:1078D000DABACFC6677DCF930773A1BE69DFC40A4A -:1078E0009CD7069DEF9A71C82FDB0CE4074B5E1FF7 -:1078F000E6E4EB0CDF8775F0FD861B6C75181781CD -:107900007EFBB07CA074871EFDF8692740BEF1F7AE -:10791000477420334FF4DE351EF62C40C7B676E4AC -:107920008FBDE8B8C0711ED7939E60613E8FC9C2FB -:10793000FFBCF48F9D46159E274EAC49ABE4FC4737 -:10794000EB8442DD09F3AB7B701CF1EBA2CD89FC2B -:1079500025DB4978170713EB93E9C2E394FE0A5637 -:107960001A4F5FC9ED3267048CC88FF52B419EC753 -:10797000F14DFDF10E23DA5DC9E3A005C9E4BAEAD1 -:10798000892E612C9CAF85CF174C5E33CCF724FE3B -:107990008BFBCD15DCD72F51688A6CE945ACDA0337 -:1079A000F85C3A8BD5E053CAC3539342E3B1FD5E12 -:1079B00043E4911F911C4C257970CA1E4E43BF525F -:1079C000AEF0EB9DF284D350CE9D11713BACC7F26B -:1079D000925ED007C0D7EF7F6024BDD0127A2E0D03 -:1079E000D7EBD413169D0ED6E5FD9ECC2AF4079D49 -:1079F0000ABD9C86F33A19CAAC42BFDE50722259C6 -:107A0000BE497BE028FEF352C6AE746A9A13E51DA8 -:107A100006197240DF643697350FC2F7F23BA7B103 -:107A2000B90CF334A2DFB47951CE5EEBF4D0FB5A3B -:107A300085F7877F18DFFBE850E60E5CFF43FB47C6 -:107A4000A6A39DF011F3A4A3DC9EEBF2F99CB09EDB -:107A5000EEAA7E8AEBBBA7336F2B7CF3B6DE7BBB33 -:107A60001DF0761B03BD85CF72BF91FC2D6D5904AF -:107A7000D77C958555A0D3F9A857C75399EC98F9A9 -:107A80005D4AB015E0B86D63E23C17769A62EB0B85 -:107A9000FF2D6620109181BAE2DA41FF8B517F02FF -:107AA000FE9698593805FA5DF250E2774B5998E006 -:107AB000A97FEC33D36078FCB3C0E35C97B618F1D0 -:107AC000A8CC32135CDF7A5C21FDE6147EC6E8FDAB -:107AD000E9418C872D15FA7A81693FC1D37467AD6E -:107AE000761BD0CD9995F3B5DB3279CA08EDCB364C -:107AF0002B44874BAB59B800E05BDAAB84C7A13DA0 -:107B0000F11A5F27D92FDBC6DBDD2CEC9D05801732 -:107B1000B41F263FA60452417E2E30C3560EE58880 -:107B2000981FD6A743B98E75D0BC1A5884E0588BDD -:107B3000EBC8FD7904FF9F5FE3EB37B96EBB1E8195 -:107B40003AB4BF82E27F1F332FAD23D825CC927188 -:107B50002E9D20DEB5383CD5752596D94371E5615B -:107B6000885728C7E1BB71F767266D103CDF3FA03F -:107B70004F82A3678E63E7D8BD6F8975B8FFEB0BA3 -:107B800073500EDC8BF66BAEE86012CA4D26FD1A00 -:107B90006133F46FBD8425F839C0BEA2F283CE995B -:107BA000D337E733B6C9E0A778C17CBDEF2086B6EE -:107BB000FEE9F2FF04D777BE4E2B54491E682369B5 -:107BC000BFBB92AFC703139A47370FB2CF95F06F81 -:107BD0005242611DCA8367B87D905A1E35F8E3F89A -:107BE0006CBF9073E9072207F3905E9E54C82FBFC5 -:107BF00045616D0AE0D90DCB82FA608B72F420EA00 -:107C00008F2D577B582BD497EF9EB9EC79DA2B5BED -:107C100029AFA76177A5BEC146F3E7F66A4AF376B6 -:107C20001DD467DF5A3A01F904E67DEB2C787F50CA -:107C3000F06D8E8DD3837B4DA07839FA650FF89661 -:107C40003D8FFC3DCE4AFEAF6C33FA7AE9D98E7691 -:107C5000A89BB528D8EEFE34DE7F964E7FEB4C2CE9 -:107C60004FE0E58C558AB68388F83EEA3FDBC46A6C -:107C7000107E7C8FF63474A7F5507D90E69B3DB561 -:107C8000B90CFBCB1ECE9F4E63381FFB796560BDE0 -:107C9000FD3A94BB2B84FE5CB1BD2A1BE5E42BA707 -:107CA000CC2ACAC357DCD20E0CDBD00E6425A5BC8F -:107CB000BDD0532BCAA66623FD3A0B13DB9D31685A -:107CC000E997A0BC3FACA7B8CD9F6C5ABA03DA5D68 -:107CD00066E4F3485EC7A8D0AB4D9F282C18B7FFC9 -:107CE0006F9A7396ECECA64FD484F7A7569B593045 -:107CF0006EFF5F5F77601AB66B60FD6B91AE1A42E4 -:107D0000292C1847E79759071F57D277D3277A1698 -:107D100018745C63E2FB4F32592073B076AEC4F73F -:107D2000308F84F29EBF0CCC03DFB3499134F487CB -:107D3000CE40BD06E533415DC000F2E41503D757E0 -:107D4000A7ED91047D76DA13E1FA0CFD3D366E6FF6 -:107D5000CFC47556A369B35263E3C87AFC3E236E61 -:107D6000BEA7E7185998D6274A7020FE02A318DB51 -:107D7000DAFBA111F35CEA7BF713FE24DDC4E331E7 -:107D8000101F3F6AED0FEB80F7C7DCDFB961EC68CD -:107D900058B20382CF039B36605CD8A5D725F07D0F -:107DA0004AF9801C20B1733F46B3C81FFAC086EA67 -:107DB000FCB8B2683FF07D60F374AC2F1FCBBF9F5F -:107DC00078FF9697D65032480797A36AB4D0971A8F -:107DD000573627956D501E1757B627D53B93EADDCA -:107DE00049E57CDEFE546AB850EF05E0EFEF9E8E69 -:107DF000F95CA772C27331FF6BA33E38BD1ACA0D7E -:107E0000E55CCF36F62A5EF2E109FC357AB9FD670A -:107E1000F3468C98779652DE7F10E544FD1EC5AE82 -:107E2000003FD8423D612AE3779EB8EF420A7D5772 -:107E30001F3A4ADF0DD97FA98EF87D43E931DE2E46 -:107E4000F42EE9F3756DCB28CE2EE3C87AE6D7F28F -:107E500094581C59CACBD339DA73242FF72976E406 -:107E6000CF013AC57EE3FC37B2FD1BE37A7F8BE698 -:107E700042CA8A0F5BD02EFD63C3BB13D14E7B4336 -:107E8000E8854D4A70348EBB95F947A3DEFB66C387 -:107E900088FD3A68F79621D28DB1B2D5F73F49F8FF -:107EA0007B2B355280F9742D59E1E9984FF75656DE -:107EB000A41BF1F9FBACFDBCBE205280F97377DD49 -:107EC000FF3EAF1F11E9C6F2E359BFE7F5E3220514 -:107ED0007A3B6E758E4CAF86FA87ED83F3F5ED59DC -:107EE0005C9E48F8869768CBB2D00EABE7FAA41B2D -:107EF000F63666909B73979C7CFC61C0C3DCEFA454 -:107F0000903C7BF8D4F5D3B99D1DF0A915E887E521 -:107F10007FA4EF486EABB4FFCD411D97115B8FD4AA -:107F2000C27E0FE9838B9A7BD06EC89E3B96F4C1CC -:107F3000579DDA111C573EBF9F074F687F24CBCE59 -:107F4000E5B35E4771E9ECEFA6929D75AF85CF076B -:107F5000F886D6D726D6E3EE2CAEBFEECEE2FBB740 -:107F600045CE2BA9BF9B855DDCB93EB8CB02F87F1F -:107F70005DE6BBDCC7EDEC5BB6835C0139DEE9D0C6 -:107F800072509EDC22F2D7A4FCC0F71971FB8BCE95 -:107F90003228DB62FBC8CE995A8ED5894F970EE303 -:107FA0002F521E7516F3EFA45ECA6EE5E366DF3B43 -:107FB0007A07CE2345E57EA4057346EE6821FD3E93 -:107FC0008BE6CD342D4781FE8E2F1EA643FF925C9B -:107FD0009FEA12ED61ACBF59F8E7E53AC9F53C22DA -:107FE000E63D5F0FF601CCF3772E3FCD1FEC85F118 -:107FF000C28F45F6C2115CE3AC187E991A9988EFDE -:10800000FF3FC2D34B5F069E1A5682BCD05D80BC38 -:1080100010F8DBA4840DD95C5ED0BE18DFA3DE7936 -:10802000CCE97F0BFB97E3CFFD6E03D98712AE94AB -:108030003B9EAEB9919DCB67C9F6DB09B15ED2CE4E -:10804000F44A7FA418E7ADD7CD147F78CB1822B9B6 -:10805000F916EC6B5A50BE88F879C57796BE82FB4C -:108060003AD9EF752E9ED76791EBAEF87A16166364 -:108070003E090B98711E338DB4EE52EF763A787E3E -:1080800048E79D79941F72864518F9352731928FFC -:108090004007541FBDC945FC0FED03166CBFF82205 -:1080A0006A0F741120F9709395F6219D186FC6FA26 -:1080B0009B4A8398CF82FB5FA2B7C53A1A77107AA2 -:1080C000E17EE3513C5F42D28DAB95FB6798AA8D70 -:1080D0009F19A7E72F72713F514A79E4C9DFA37D49 -:1080E000BAD142F629EA588AED7464533FB0FE993A -:1080F0002EBEBF273ABBED07A9222FCD5B81785D4D -:1081000097CAE9B2CBC2E34E5D600F935C14F42BC7 -:10811000F3E2FCC2DE8BD4E9D2D05E28760DF80DF6 -:1081200034DCC793DF1BEAE74594A3B8FF9A17D066 -:10813000874DB89F6ABF528BC4ED47F00FE376B707 -:108140000AB9CA3633F203DE8ADFA561FFD6348C62 -:1081500053DE8ADFA3DF75D59509F1B84B5C9CBF70 -:10816000257CC972FF120957C7035AFC38B2FFE4D5 -:10817000FE605F59EECA223C87D3717D5BF4B47E0A -:10818000C970463673FF75647311D19DEC6F283842 -:10819000FF4B1FFDB6027A70E154BEDF96FB9805D7 -:1081A000623FCC5625EED3D05F3250D69F5B4EDE79 -:1081B000F7619C3DB13DB75B52C6468DC4B71E25E5 -:1081C000017E89AFA1F070F317C49BD47B0F588058 -:1081D0000F32703BAD10FD6EBE3385F498D3181C82 -:1081E0008D74B5C0E5A1765B31DF85F42ADFFF7EB3 -:1081F000FC8AF45F24EE7B9BACD16D88AF262B23E9 -:108200007E3ABD2F95F8879544E662BED899BD2683 -:1082100086F4DBA84446A2DC3AAD68B5D4AE25C5E9 -:10822000837C24FD036F3FC5FD034D884980AF2942 -:10823000F077CA576ADA93B81F3E0DFFD501DD9F6C -:10824000D6452AB03F290FC08ED6C83EAAE3719CFE -:10825000461D0BE03EEB32DDBCC59CCF73D90E7AD8 -:108260007F74E4F2383B1DDAF529199C7C906FEAA3 -:10827000051E1B75C7A85D3DE61D213E71BF85FE2D -:108280002EAC8CF3CF366E7C9FF29E1A7727AE779A -:108290007D8C1E94CF14FC2E8E3E889F03421E3090 -:1082A000EEB7A8E671E854514EA9E9A73CA826E12B -:1082B000C7C83A1099867225B53CC4E6C1B3E90433 -:1082C000B73726F76E7F0EF7C78E9AFE02648326B5 -:1082D000E1EF93EB2DE1BCB4F73EF25B483B256E3A -:1082E000DF397A5682FF600D7D87FB581C2F82AFE5 -:1082F00072900CB87EDB24F41BE84192B70B3A462F -:10830000911E443D85F249EE83515EA19CF8A7ABD6 -:10831000AA07F9755376D563AE2C3E1ED9F5B8A9D8 -:10832000BA74683F9DC48F6C87FBE1CFF3C3F5221D -:10833000DD66C5FCE3045139E64D6749BF1BC5E75F -:10834000962B9E6CA4DB77F47EF2AF2D6201F2F7E0 -:108350002C46BF163CEB05BF2F147EA285C23F847E -:108360007EDBF83822FA4FE3CB4B583F971B3B4D4F -:10837000B1FC1AF4E754B3702AF4D780FE267C8649 -:1083800012BF6B6451FAAE69CF67A6843865279F28 -:10839000F7AD62FD1DD5413DCA892D16EE6792F2FB -:1083A00063F22AEE8F4A9FA015DF8574FEA281FC3E -:1083B00014FF2DD66D40CFBBAA9E42BD62D5F3F30C -:1083C00068D1BB4C24378F833EEE11FE9159B80F14 -:1083D0005DCD34CC5F67AABD307E9F2A9F1BF65AC5 -:1083E000EA907EDE75E912E8EB472E9ECF437E23AE -:1083F00092CB29A477417C8C47FAAA1826F5221B38 -:108400008FFEAAA362DFDC7883CD8FFD45745CDE2E -:10841000FCC9C5F7017F72F17C4E591ED8E709FAF5 -:1084200091F13FF4DFC4FBCFFF3ED0FE3E9177CB0E -:1084300068BE9B168BFCEE013AD6915C4A19EB2381 -:10844000F97B99AE8AE452F43D9B07F152F37EFD2D -:10845000629CC74773AC748EEF36E1CF4DC976503E -:10846000BFD27F7BBEB858CD86D1242F65FB34DCCC -:10847000A0649DEB07DE2BE4D85EC6E10D9CB0F254 -:108480007C13950550AEED0D8D0E22BCB5C2FF805C -:10849000F60DCAD7E8937C1D99CAEDA1BDBDE38254 -:1084A00048EF470DFE2D0BD09FD36320FF1A538357 -:1084B000BB1EC17E9ECDF162FECF695D74DBAFA0B5 -:1084C000DDDE138FE661BC67AFF0BBD71BC323C9EA -:1084D0006E16F98EF569E191E807FA8558AF7A2BA7 -:1084E00094E17DAAC53F2A3B2B1617C3EFF0FDB1DF -:1084F00020B7CB8F314E07818D3CEE09F8CD5980E6 -:10850000F0AECFA6B81AAE0BAEC3DBFBC6D1BC36FD -:108510001944FB67146AAFCC2A9D4B7A61832913F7 -:10852000F17FC667A47CDDA67BB9DD385FE7D9B6ED -:108530001265E5B32934BF059D8729DED1F4834553 -:10854000740EB269C9AAEBD8E7C40150AFC4FBAF3F -:108550004FB36821ED87EB8685C200C7E9DED15EA7 -:108560001EC6E3E76A1A455EE87103D310EEE83EE3 -:108570004370B0F37E43F58FF3C5FD29EA37F273FC -:10858000C7C75B481F24C65FCE573E6D888CBC139F -:10859000C65F9BE9BF293BCE5E6C7A3687E4DDDBA4 -:1085A000F7FCA590EC8A0E1E2F386ED0E6229F387D -:1085B000AAC3C6797176D8B26C6E97CE3709FB1113 -:1085C000E4603CDFCBFA8AAA443E93CFE66C6E8728 -:1085D000A48AFC8073EB65FED9F526D49FDCB584B4 -:1085E000FD72795D24E26E934F44F7639E557DA83A -:1085F0008CE27A45ABC2C49780EF30DAFFC7B7A4EC -:10860000727902D3C47E164E6264BF2ED4F37C8787 -:108610008526B087B91EA7F6EF6CC9263C54ACE19D -:108620007660F44985E4A28C3FD632FEFDD36D47D7 -:10863000037A685FBB532903D1CA6ADB2A291F6208 -:10864000495731ADFF64217FE79BB4915B90DE9E7B -:10865000E6F12B188FECEE7ACCF99A4072C988FAC1 -:10866000B06EA7C2F0DCB09C7F72BC8F0513E32D07 -:1086700093435C7EA3DE6071F69AD443A82F589290 -:108680001D9948178104BDD78D789D1893FF84B13B -:10869000CFD183604F6F43FAA9A8E2FC17ED5108D0 -:1086A000CF0DAC99C787841E1A8047E8B177F45C78 -:1086B0006F2E34DD47CF9FE321B02CD48311AE075A -:1086C00041AFA15C1C8A2E7E3E045D487AD82DE81D -:1086D000A3FE040B5F0EE3D5AF62E186F1FC993A8D -:1086E0009EF432D7CF66AE9FF169BD003D9DAC9F31 -:1086F00093F571B21ECE36727D2BE920DE4F8FF6D8 -:10870000C8E455413DF7C3E6DB31CF4FAECB22A7DE -:10871000D6979715B3B79A8E98CD9E8BB1EC63C35D -:108720006CE85FAAF415A0FF5CE5E78D53004FDB12 -:1087300071FD847D7E79015F47B7C8E731A83E5659 -:1087400066C375EAA7FD74348B517EB6C46F772A71 -:108750007C3701BFE3FC38F0BD99B559E3BEAFDA11 -:108760006B21FD72F699543A57C6547F9103FA7300 -:10877000BD01763A944FEF4D25FD7E5AC87BA7F494 -:108780005BB0B5B41EEFE23A4F44AAABCA43FF2F29 -:1087900053A6E7313A6FCDEDC606C7507E7B515FD9 -:1087A000DC7F03A73313E9D9B38EC8ED58067828C8 -:1087B0005FF8BF04FD36ED9E5AF65D8CF3FB6C5EF0 -:1087C0008E557F19DA0D26FD8A1BCC7A3C77BF2A9D -:1087D0007A27CCA3A1C04679C8D5456FFEEE2628DE -:1087E000BFB7DB40E715173F7C7D7A183F5335F75D -:1087F00060FA7971D090700E6EE9CEC4724328B1E0 -:10880000DC9474EE7DE59BDB5FEA8BAB37BB539D5D -:10881000B4FE1EE6C53C6AA6FF46BA7F1079299FC2 -:108820007F591D7CA96F04E5A1A5BB797E8D11ED53 -:108830009A79480F837C77309BDB352653F309CC3C -:108840006737FDC244E7E3DFC8F6BBDDE85FD64526 -:108850000FE27A9A8A4E8D473D5855F40F8A8B9DC8 -:10886000FD1EF3227ECE5A2AC9BE39BBC5E2C1FD28 -:108870005967A18DE8A0F35925A870FB7DC6C40AED -:108880008C83D21C58D3E6ABDFE3872F98999FA740 -:1088900087DD8B1BE58C46FBA977665AED6BE0BB49 -:1088A000BACD5CDFD6B3FE349403DF748BF5D33FCF -:1088B0006634C33F8BDBB4D12D00EF529F95CEDDE4 -:1088C000A89FAA74DE7C1D761967FF97BBB93C6828 -:1088D00030478C9538FE3F56D4A06B4CFAB94C0605 -:1088E000BF86E7BB0C7BCAC279F06AD1CAE7689F32 -:1088F00033104FDEC7E5D6A23BF7D37B65560DCDCF -:10890000F71D982FE2E5B92D269AEF3B0536DA6779 -:10891000BED3CDF7BF8BECC6A099EC8D4F32F15C86 -:10892000EC3BDD063A8F7E2E3EAEA2F3A9EF76BD7C -:10893000407EB877191F37B05B4FF6CABBF6684563 -:1089400018F1E8694E437BB76EF3623ADFBAA85B71 -:10895000EF4379B6A8FBDBBFBA14FD47B36E2EC751 -:10896000295DE158E1F2D862F5D24E5533263D82B9 -:108970007C78C5A753FBAF407BA91BF8A498E7CF31 -:10898000A39DDED77D15D9A58B665A1D382F4FD7ED -:10899000C3D3507FBC3B3397CEE32E7A5C6178051E -:1089A000C322C74A17BE5FA4A8BEC1E8E9E36C3D75 -:1089B000E1B5B2C8E60DE377BFD5139D005FDD805A -:1089C000FAB3A1DB40766FDFACD77F779333C6571E -:1089D000CAACCDD74DC6F63F3150FB017BA7EB5A51 -:1089E000492F2C5C81FB2A8EB7643E3315AD1A8962 -:1089F0007025F3DBA235CD2379FCEA8BF11DEBE288 -:108A0000E773EF70F3FB23BE00DF7DFF8BF01DCB20 -:108A1000CF48D84F9D2BDF02D44EFAFFCD5EA63D46 -:108A20006CA378AFA680FCFD0906AC27E2939F3BC0 -:108A300052FFBA7CE7AB809F316E7F07F26F11D394 -:108A4000CA506F7AA2F62A3C536413F61CEB32C963 -:108A50007D00D9F79BB2D8231BE2FC0F0FBAF93E79 -:108A600009E4C016ECE7F41FFE7110D7A9B1F0D4E9 -:108A700078F4FB367DF2278A17DA7A79BCD9E68D4D -:108A8000523CDDE0F4111D4AF9DEE4E5FA27795E97 -:108A900027DD061EE77546A99F17723C54EE14F1B8 -:108AA00095AD2BADE44FDDEA0C5AB87F21C0503FA5 -:108AB000CD98A4E77132616F5D2BFC91E6F2E71867 -:108AC000C6C7D8149EDFF56AF9736A26947F35E924 -:108AD0004A2F9DCB2B7FB07D18CE7B8A41D40FA728 -:108AE0007B33FE8F5649F5CBDD7A0FF2F78C729E01 -:108AF000DFC8EAD2C86FF26AF9DBCEDBE2E0F73119 -:108B0000B3C70674330B98353E9FEEBA29168F2DE6 -:108B10008E7E3EEA506AB8DDEB499F3D8EFB4548AC -:108B20001F9727E263B9DB48E36ECAAEEC43BAB9DC -:108B3000E2AB7C3D4E3E6E0AA21C3C29CEB924E33A -:108B4000EF376EE1A7534727C4ED9DC65021EAC910 -:108B5000F795C4EF96B4EB296EBEB85D614118EF8E -:108B6000E4AEA70B519EBFF7F0D385F3E2E049FED8 -:108B70004E3EFFE816F42AFC82C97EDEA1FCBBB2A1 -:108B8000DD99CDCC6F1E1E6B7FA6EE6FE4DF9DD707 -:108B90002BFCC39A56E2C4FD90689FDC9F3997D3A3 -:108BA00087B24721BF87F46F1E3BF420465206D69A -:108BB000CFD25BAC8BCF4B94CFC962DDAEC7758390 -:108BC000A958DA7979A8F51A8A1F77083D24D7EDD4 -:108BD00058FBF074C4A3B1D1A6327EDEAC14EDF51F -:108BE0006E66F5223FFD45E4A73AADF0043BCD9813 -:108BF000EBB6A13C93E7FBEFB0A6EDC0E75F44FE08 -:108C0000AAD30A4FE8A720B794FAFB8BCE47FBBA4A -:108C10003BF41D740E3145F049360B2B0A8636960F -:108C20003EA550FE567B22BE5DAD5C8F446B8DA48D -:108C3000BF24DE2F9B773BED5F0759AFCD4847B987 -:108C400093F8BBEA9C62E1EF88501CC13289D9716C -:108C50007FDF7A6980E090EBD5C49B33A55721FB79 -:108C600019F3585232285E1A104F66CB6003F18315 -:108C700014B1DF6549F1826CB0BBB19D8413CA9415 -:108C80000F73AF23D43192C75BC92EC57EF1FDBCF3 -:108C9000B12AF9DBB19D71C2F9E96F804E457EE1E1 -:108CA0000CF9BECE3A687C62069EF3C17500FD8861 -:108CB0007621F31A12CEF974813D8DFB3419FFD55C -:108CC000EB42656EDA9FF447D07F62AC307B50DFB9 -:108CD000A6E843A5B87EC9F1606857CCF310F21D31 -:108CE000A867E4399EC695537D18A702FB2360C68A -:108CF000F59BC9D7AFF1CE4A7AAFCC2A6D41FA6A5B -:108D00005AC5E8BE81A9BD3D94EFD454C3EDB1A6C8 -:108D10003D478D0CE8779EF0E730E17F7689753D21 -:108D200026ECEF58BC2BB20DF3B73B17E7D3B9DDF8 -:108D3000E4BC922F1AEF3C930A08B9382E8E956E38 -:108D4000E67A46ACBFE46F19D74A1DEB2B464BFCC5 -:108D5000C507DE7BD99AF545F2469EBDE773F3461B -:108D6000D8F4EBB0DE8C56BEA84730408F0E9CCBBB -:108D7000B37828EE35508FF72998F72822EFE4ECE6 -:108D8000B5579650DEA8E8AF6F23E67FDF6B610929 -:108D9000E3C5C3A726F56F80FE6D1ED9FEF83557D3 -:108DA000AA14FF15F04FDD88E7FAEE3524F64724C4 -:108DB00028CF119A63E3F9BA7E70CFC6FC983E07BC -:108DC000FDBE3167624CAFAF7B7D46C7C51EE4AFC9 -:108DD0008F290F57EAE72627CF234996630FE470C0 -:108DE000790E76F13454B9EBE62CA3FB0706E2BF0B -:108DF000BDB51ADAC332FEDBB4CA47F9B8600FFC5E -:108E00002887EC8153EFEC6768779EA47D41D327D8 -:108E10002AF713815D81F7C9987B2BC91F8A69A640 -:108E200023E2D67F89D05368C3233F3475DDF8B081 -:108E30001EEA3FCED11EA27E0D83DF27B52F87DB32 -:108E4000F14DA5555B501EB08714BACF6943E94771 -:108E50006477343E73E5C4F87CF2C57BEEE7F9C86D -:108E60003B0D83CE7F5F0E8F0B373EF324F93B4FD4 -:108E700006F931983A35B81EEDD0BA3A1D5A5EACB3 -:108E80003C587B13D90373601E30AF0773387E9A4A -:108E9000765E1FC0FCF626F84F81575B7D0B695F3D -:108EA000B0758ED986719CA6D279CB88FEED560D11 -:108EB000E79F0C672CCE6CA573C81BF6186AD08E82 -:108EC000AA00BBE9E7006F41C6F41A2FC8A53C7D94 -:108ED0004FD9B76C18771F5C2FDF92C7ED8036C56E -:108EE00017F85A39F939597C1E4FD11E6E9FBD961D -:108EF000C3ED43F9FEB51C6E374E09F44F459A7B1E -:108F0000568DA4A09DDCC4B40F71FFCB7C360FF945 -:108F100077198FB33B577BC8BF6B7646EEBE98EC94 -:108F20002895E2CC727F71FA19EE17BB22D77F1415 -:108F3000D7B1421FF9E1D7106F77ABC24FCCE54CE8 -:108F4000E1F5B609E8C7B238233FACF150FE0DF9A0 -:108F500025D22F6FA37578D6C9EC889FA9815A5561 -:108F600089D333526E4C1D3887E324FF6915176B84 -:108F70006C04ACD63B6622D1B6CF326376C2A17FF9 -:108F8000CC56F1A5B41F74663FED73AAE7C0BE11BD -:108F9000E9726DF4A00EFDF5CE7EB21F1B420A8D64 -:108FA000D350FA33CA8F5B2AF2B006F2A1D408E597 -:108FB00087FD3D2745E8C7364E0FAC9FF6C5EC311F -:108FC0008E7FD09B943716B3E35BF8BD67A23FA3B7 -:108FD000883334083F0E208AEA8DB9C2AE137E8DE5 -:108FE000589E1B1F97A99E8A78BFC3A699A04908BF -:108FF0002E4F1AC2DB6EF5A5E7025CC7EA7484A2A5 -:1090000063ED2974BFD426A55F437F64A08CE7C5B8 -:1090100026D351891837FD40741AEA93E83343E5A3 -:10902000C5F23CD82D132FA27CF2F23D1F4E43FA1D -:1090300060358CF8B171CF85E5C58E16EBF1A5E7EB -:10904000C57A156D073C2FC97524E6C57A39DE65EA -:109050007C32391FF6744E58E5796B916D0FE3FE43 -:109060007B8F89F23D66EC79E108FA276798598889 -:10907000E2B54976C061E7F55310DF673E7867DBFC -:109080005D0CF3A29FF2F27392897A7D28BB9E62F7 -:109090001671FBBFEBE4FA7F4976BD94BB4D629F2E -:1090A000F4BE12FDC1489CDF3EBD7DB0732DB7E418 -:1090B000CA38D710F91CBD83E773C8735F3591E2D6 -:1090C00084F8D382017AFE62F1AC3AD48113CF8D59 -:1090D00067A9223F4B55B808600E9EBF23E3596A2B -:1090E000CF688A539962F1AC301B249EA58AF8D0D0 -:1090F0003A83564BFE967D260FDF0FFB480EB5F5E3 -:109100006479514E352D39F9041ECD571DD3DCA895 -:10911000FFDB04FEEB2F3C9ED5923BF1DC78D6764C -:10912000617FBD5DAA0B1B01AFDB1997A3815E199F -:10913000D7D2D1FE347A4F01C1ADCC3213DC6F3FB0 -:109140006BDA817EA6F9325EF52CF793CD1771A903 -:10915000B7678D243FD250789EDF9EE8F7FF21E26B -:10916000398BFC78E46FBFFD3F66929F7D21FAE961 -:1091700087C7CE2F30E1AFF3B4F3F3ED9E9D0ADD48 -:109180002F8A64A223DBD24EF78C2E0571B81545C9 -:109190006800A8E62BF05AD12968D778DAA00CC667 -:1091A000BBBA5E0DB8A1DDF62329E41F5CE7F488A5 -:1091B000FC331E3F0E6C54822378BF74AF58A04D11 -:1091C000A7613F3FCFE57EA59773B95FC293741F38 -:1091D000419B41C481C5782D0CD61D9E3A853FD751 -:1091E000897BEB92F121FB6B33349BD14F172DE040 -:1091F000F7939C356A73C87F9C3192EE216A4B6D60 -:109200006EAFE1F5C4B3672D511FD55FAE72C39247 -:10921000793210DE5DB922EF2E09CF0B3A12CBC99D -:10922000F19BE47353F3997F54CEF073CF15ED4265 -:10923000B909FD9FDD502CD6C54BF1903683E7D799 -:10924000C51407E5F70CB5E473BCE90AF87398A3F5 -:109250009AEE8B037EE1F618E3F00FBBDCA920BF8A -:10926000B43938DDFEBB7027C3FB9BDC91445F6DD6 -:109270000ECEAF6DEB9520C71787FB42FD1D1F4A31 -:10928000B9F425C9C5B715EF23E162FA8EE443E0CE -:109290001E03F1DD5E0B3F0F29E51525E8E03E5288 -:1092A000EC5BFF2EF4D6FC136BE9BEA0AD75C3D208 -:1092B00030EE39F57A1BCDA3F1597EDEB66155A4A7 -:1092C00010E9BAB12A32B27910BCE200AA94AFD048 -:1092D0006E9E93F17B67DA13E378C9F1D9B5999A59 -:1092E00005E33FF7EBDEEE7901D7BBC7427AB271F7 -:1092F00055F411F403DC9CE9B7E7017D9CBAF3F562 -:10930000698A873E23BBFCCCBE51744E705E5BE223 -:10931000B92BB631313EC8DA33F8F9B2CEC4F7789A -:10932000BE28E1BB73E285DC4ED964F48F463BF284 -:109330008AAFF27C880F16EB18AEEB0716BEFE81E3 -:109340007B5285BCF68E8CD707E3F2865A5F68376E -:1093500016E3F23C0F54B66FC0F58575AD17EBFB05 -:10936000C1935F1989EB7BAAE72B23717D37193AEB -:1093700034E48F7FBAFC6588AFE357FAC8CE93799F -:10938000AF174A775ADEFFAE3EBE56E2E50BEA6300 -:10939000FC8BF77F3CFB0F7DC042FA859F338DF934 -:1093A000E14ED27D5B673ED129288F87EAEFBF85EA -:1093B000DFC96D6601F477545445E8BB8ABFE918EC -:1093C000DA75D29E4D86DF2FE05F96A7BD9C83F3B2 -:1093D000107EDB3AD1B739F831B79B1F52C82F6BDB -:1093E000F604D226D33E69C1257A922F3FA7730F88 -:1093F000AC57B1E37E63F1432D547F7ACF7CAAD77B -:1094000099C361DC5735403D96D74D49CC6336EE64 -:10941000E6711DB98F05385E4038529C5123D267E2 -:1094200023DAC90062A3CAFDD78D4EE60D30B46BB6 -:1094300013F77D323EBBD5C7EF73D9DAABD0BD4E43 -:109440002EA3BF381FD735294EFBFD3CAD3B2F2E39 -:109450005E3ED7A505B0EC34B242C4D3BA3C8ECF41 -:1094600088419EBF4A3C0F7868FF0D640FFD99F953 -:10947000D207CF2B0B26C4D1178A739B0BC5B94DCE -:1094800094D3E124391D5FAE8FCB2B0B0F961F10A9 -:10949000975716FF5D7C5E5938419E7588730CCBDB -:1094A000297EDD0474BE72428C0EEB99F8DB1C7DC4 -:1094B0009BCEB1EC34917FAC5EE49536D51DA37D97 -:1094C00047139E8BE1FCA8F173D1DC1EAA87FD1C1B -:1094D000E5D78612F34F770F2937FEDFF8C17F29D2 -:1094E000E581E047392F398FFA5E85F34F129CC929 -:1094F000FBD8647FB6DC875EB0FFFF7F592E4592B4 -:10950000F0F0AFCAA573E20225D134EF97101778B7 -:10951000CFD3E142D7A0CC036EDFC7F380A7E96DBC -:109520001A8F43EA799E42723CD6338DE28D32FE29 -:109530006B7E4A1F5C534CEDBD98BFD5B02F95F2A2 -:1095400006EA3C75647727C72197B09E69B8147FF7 -:1095500066AFD039AC7F3BFE9F2FEE09F6B0E22F0D -:109560001AFFCFE7FBAE0B8A433E67FB38D31F479A -:109570002F5563C1801F3B747E56413E5FFF14919F -:1095800027625603CC11F7FD50DF8DC8E7795FCF16 -:1095900089BCA27B5353E81CBEDBC8CF1DB8753C09 -:1095A000FFE9E31CDF2884DFECE1EBF9E3676E649D -:1095B000788EECC786109D8B0F34D8BCA8C7A4FF4B -:1095C00048F6DF9EC3E1BA503E9A92FFE5F2D1F928 -:1095D000E4C7B47CE58BC5D136030EE2F82B991FA6 -:1095E00086FA6E28F97263BE6F16A70B6D3CC51F15 -:1095F0002E502EA59483DC463DBDDBE4C1FD03FA6D -:1096000051483F6ECC91FB6F7E4FC0BD05A4BF3E5D -:10961000B0F0FD843CC73380BF21F1FDAFD979BFE5 -:1096200073F9EAF3D1BEABD4E81CC0BA54AE5FA262 -:10963000BB781E50F2799664BD22CF63C8F1BEFF9D -:1096400025D3C31795AB77CBF1FF4DB90A7A96F6C0 -:109650002F43C65BCFF93E20F231FB3591F742E74D -:109660001A245C4DFD3C7FEE47827EE5FBEF09FD51 -:109670001BC9D7BA90AE4EFDC16CC67866793997D2 -:109680009F8D3E1BC5031A433C4FA67115A37DBF9A -:109690003CB73AC6ED7F04D76FDDEB36BA87B471BD -:1096A000CFF6F6619447E027FBEEF41FF8FB37B2E4 -:1096B000FD8F62BBA6559184B843C5671FAFAD2926 -:1096C000277869DFEE34259E077A259FEFC7E5F3FB -:1096D000C501FCC2FE04BE3B55C7F3B59B9C9ABDB9 -:1096E00092F207B85F3BC5D34F7EA0C6DDA4241815 -:1096F000258F62FD77F3896E1A775796D17D002109 -:109700004B19DD27F306BF7FE9D49DB9413DF783AF -:10971000EF477853CB8357A39D5904E3A0497AAA16 -:10972000E7EA32F20F26F19DE4B78173A0B7988380 -:10973000AD4A8C1F3719B89E94FAAD27DFC3FDCE12 -:109740004E9107D83B932DB0C5CA3667627EE4B20E -:10975000BC2B7B707D7AF25511BFE6F1F26233ECDF -:109760003E879D4B87C5225E3E53E439B0803996D3 -:10977000DF30ECFCF172099F2CCB7879CA27E2BE6E -:109780007FBB91E822B59DCB0D06748176F6946877 -:10979000FF543C7F55D2199E82F84A47F453BE6964 -:1097A000E4EE8B310E91A94EC138C4B695130E600C -:1097B0007C545DDF7F392E8DA7C35E855BCC316E17 -:1097C000DFE97CB2079B4B91FEAB7E6BE07989EBC6 -:1097D0005348DF7716D6535EE2E9D74D09E76D921D -:1097E0009F01B6C68D7EA361EDBFA13840EA6E65CC -:1097F000D07CD371053691B7B8C68D7EA8D4F6FE5D -:10980000C024F4ABDCA3F0BB1C017AC58DFB7F55F3 -:109810008776C7FC3DFCFCF6FC0E479599E4A9C28F -:10982000E328539C2427D5F5D7E8709FA6B630BA15 -:1098300037ADA480DF9B3AA2D3AEC375FFE5A7FA8C -:1098400041E3639905B13C37445783297AD05D1CC5 -:109850008BEBC9FCB6A1EE2397FA28D99E3DC78EA3 -:1098600015FA68C09E4FA2E3A1BE93F42DE9F997C3 -:10987000064676D82F15339DEB9274DD26F3F53F1F -:10988000E57EDD229137736CC3DFC7F373EB322EB5 -:1098900012E4F7711A226BF3085F91AF0670DEBB1A -:1098A0001DBAC6B1E40F6BA47ED6F3FBCE8ADA876D -:1098B000AF99548E4F3B530084637B9716215F060C -:1098C000800E460C42071FE5F37327EAFA145A3755 -:1098D000F53EBAE999A90E17AD9B7A3F5F9F53F900 -:1098E0007C3E322E2BFD96917C7F55C1C4B87358B7 -:1098F0002BADFC1C9638E79BBAF2F5C7F17CD3364A -:10990000E13F3EF0EC18FA9D86B3EB5505EDD4B37C -:109910008E5AFA5DA26B0BB8BD94AAF633BB2D9E8E -:109920003E0F507EECB07D3CCF4F15E798D5F5CE7D -:10993000ED88CFAF3AFD94077C795B987ECAE059F9 -:10994000FB718AB7815D44E7554F3EA348BB284170 -:109950001FCA7D5BF27EACB6E07FD64EAA2F48F4DC -:109960007B5CF03E8B25EE3707DACBFD63F27E227F -:10997000E9FBA1EC1FA60512F25D568B3C68A9DF3E -:1099800073856C94793003E79659D082E71EF29183 -:109990002927C6F28198C813DAAC58BD682F0D95F7 -:1099A0000F3490AFC39A2FE6FEC8E6AFE053E6133C -:1099B000C97C210BE68D649E9B3762C1BC914CFC37 -:1099C0003D0B7EFE59E67DB41A3C944712F81EA367 -:1099D00078A032AB86FC75193E23D1DF1916DC82E4 -:1099E000F7B90766DBE89C379E0B42BA8F2A6EEA0E -:1099F000776A8D26DBEBB0FDC0BD80B58CEA334ABB -:109A0000B41CB4C32C508FF7150F9C7B5EC0EF4F76 -:109A10004FCE1B91F94B329E9B3BEA2905FDA2E8F4 -:109A2000F6A73C826F89EF8A793F9DDFF490DC7066 -:109A3000B5F2FCA4E8A5CC8E7EF92A297FCC89EB6F -:109A4000BA49F117237F6EB2F273FFDDCCDBAE872C -:109A5000F21D05C3B85F8779F6EB486077D0EF2F2A -:109A6000743AB5A70AB262F424E1629BF9BCCFE074 -:109A7000392F2536DE99C57F2B44FBAAAAD7C4E926 -:109A80003269FCAD03F7AE042DA84F5E2E6044672B -:109A9000DE247B573E5F96FC26E4B21C7FA8F94982 -:109AA000FA3C9F1D2FE96F287A0B5489757A2B8514 -:109AB000EC0F496F0756EFA47B01FB5687E879C688 -:109AC000A284F4783ED6129D8B92B17FDB9FAEC309 -:109AD0007B39CEA4460BF15E8F377FFCD7AFE1BD5B -:109AE0001D67B2A26F61F954E1381FD58F886EC32C -:109AF0007B3E743FEEE1F5B89EB960BF173CF2B50E -:109B0000808DEEC95ADB8F7AAB3C291F25E93E8256 -:109B100014F17B3ED93623D993D922AEC7AA855DED -:109B2000CFF8EFA2B5E694511CCFC63CBBFBB13ECB -:109B3000DFC4EF2D6040FF583FA298E735303E6FFD -:109B4000962FFCD32C12A0DFE72B76D0F703727C84 -:109B5000B749C4A7F8F8879FE47144999FCB98BD93 -:109B600000ED219B872594E57D1E4CB517E0F9FD9E -:109B700056E9F713E52753FCC6C238BD7CF8CA3B4B -:109B8000C6D2EF843CF5DD12949B571913EF59961A -:109B9000CFE78B389D9C11F70936A5F8D30B61DD13 -:109BA0008FA4CC9D8657C3CEC9AC343AC87EDBA502 -:109BB00047399525E8C3319BC3E7A8F629F8FB1C74 -:109BC000F23EBF2CBF4A7E02E6EFD4A35ECD3AEE52 -:109BD000A3BCBF7A73B4107F47E505B33F0FE13CE8 -:109BE0005B7BF4768A17E61E7E0BF3340E1B3AA6D7 -:109BF000A6A11E2916F742604016CA07F38A683FDD -:109C000038201F462814CF9C319B9F5F9DCE422A4F -:109C1000AEF3343B3F4F35ADBCD8DB0AE3CD107912 -:109C20001ED38EF8D250BE4DBB31A2F27B2BA26A5E -:109C30007C5E857C32B7C113CF0F577BE2CA0CEF35 -:109C40001D4E2C5FEB4D2C7F6DD2A7A3E2CBE3140E -:109C5000AD02E7F90B45DCFF00F285CF8BE70F3E45 -:109C60002AF67363DCCC5C84F98D4E2580FB85314C -:109C70004FE7529CE5E9498CCAAE9DE61DE6F8F92E -:109C8000DFA7E37168E10797BF338475A86F9FFA78 -:109C9000838BF0E5B281BC7592F4217A3B20F8F613 -:109CA00080E0D38A3CB315E5FF0183A78BE83CD560 -:109CB000EC413FD5FE5423DDE3DABA8CFF4E8192AE -:109CC000666646E8573F8F97A11DD80650AE3053C1 -:109CD0005EC801916FDDFA3D95FC5C588FF7EBEAA9 -:109CE0007F6025FF76755AE937B05E9F66A4F30E54 -:109CF000FB532BFC623CBA5FFEA15473187FEF202C -:109D0000F93ECDC30817E20DE07A98C341FCA8AF35 -:109D100030921D2ECF9F433F147FD3E79A69BC0337 -:109D20000EFB7EA4BBD6F7C8D283FA491ECCE392C1 -:109D3000F45D9D36897E3F04B8AF24FEBE74BDCB72 -:109D4000EBE1E766F9EF62940EFC4E060C0BEDF0CA -:109D5000378518F12D8FE71548BC3355C3F6394CBC -:109D600096F9B931D740B952A5FB7F14596EA1F2CB -:109D700003A25EDEFF79A890CB29A5F785BF22DD7F -:109D800096A4015E609DBC29839F5B7AA090F3ED51 -:109D9000B9EB57E146BFBF82F31C1B9BFF0187D77E -:109DA000ED8B2B0FB22E41A4B7E4753960F17AD058 -:109DB000CF76FEFE385EE53CF4B91C9F03F3C81C69 -:109DC0007C1E87C43C42E29C7572FDEE426EBF7EF3 -:109DD00089F31C94FEFEE579BA12E7F925C2195100 -:109DE000BE0438F585009F2D061FFD0C5805CA4D91 -:109DF0004E7FD3459E322B4DCC4B6293BC666E2F6B -:109E000026E6215DA574B5A17E7D40C4B95F107CB6 -:109E10007530E5FB25686FBD3077641FC9DBF496AC -:109E200036642E299FA5FC3F9B73B402CBA007DEAE -:109E3000443D73FBB0C373B1F33EC70325A8AF40E5 -:109E40006EFEB170E2B9704AFE1D8017F817F9482E -:109E5000F26F32FC928FD875214ACCEC66617ABAE7 -:109E600019CF8307BB84EE2B679E82D8FC80C9A7DD -:109E7000999BF93C5A0204F7558E1F52FEDF598F09 -:109E8000FF23846BCEC51FD27D48CC5D3B0AF5080D -:109E9000C0FBF1FF26BC209F72F0BDB4F393EDFA36 -:109EA000F3E5834B3893E5A1844799B593ECF82605 -:109EB000B0E379BEB842F2BEA94EC7E5F01E85EC0C -:109EC000FA46D033A8A7E4FDBA578CB4B6E1BD8FEB -:109ED0007B0DDC9F1A78D2E449BC2729396F5CECF2 -:109EE000275631B95FE0F74134D8F93D4842CF7485 -:109EF0007E7B98BC2789EB43D05309F724D57A128F -:109F0000EF491A62BF00FB02B2CF58BA4EEC0BB851 -:109F10009EEEBCD4630F30F23FF3DF7BBCC928EC6C -:109F200041C0852B768F1BEC03E87EBAAF14158BEE -:109F30007BB282FCF73584FD9FEC8FFEA7CB3FB947 -:109F400008E87DC158AD107FEA65BE91FB9B81DEBC -:109F5000BAFA19A63F363F84F7955ECD9A5FD30DC6 -:109F6000277AD3B0FD9C311FF27B4C63F456599491 -:109F7000C5F5122A99F3F1F161A77F7AD144C45F44 -:109F8000E80DBCCF7C6BAF89F02DF34B93F93B0E02 -:109F90009EE3060E8F53AF2778660D06CF85D07DE2 -:109FA0003C5D65334EDF43D13F9EE3489D10A3FFE8 -:109FB000718ABF16C71DE083B57CDF750EDC7A1B86 -:109FC000ADF70D37F1B85C538ADC276B33725CE870 -:109FD00087E4E3DFB09ED3C50DB53C8F68666F03A1 -:109FE000C5E158358FAB79E17F08CF0121DF663BB2 -:109FF000CB0C487A7F66DF30A09F73F68CC4F8DB09 -:10A000001CF35514EFBB61B621E1F72A251EE68843 -:10A01000DFC39E93F43B95C978498EDB0DC80331AD -:10A02000DF3CFCFD1678E6337E7E2647FCAE585BAF -:10A03000D1C0F9DE515F30BE7777D11788EFF519BF -:10A04000A2744FC3F3598BBA9601DF8CFAD158BA78 -:10A050007FFD4AD7E287EE83F24FB65E44E5E75DC7 -:10A06000B7AC388CF5DB4652B95AF7E15CE483D2E1 -:10A070008A9BA6E37DF57D16DE8FDBEAEFC4DF3138 -:10A08000718F1F3601F380AB8D516A77CDC50D9767 -:10A09000603E54B595975F29FBFD042A0F13E5092F -:10A0A000BFB808CB7DCA8773078B0F8E2955C2F8BE -:10A0B0007B65D519BCFD8C09BB72D15F545DC5CBE6 -:10A0C00063BC95EB8763BDEEA3B983D923CF140995 -:10A0D000BF91B0AF7D82DF9FD68EB6E179409F4DB4 -:10A0E000F1E2B90FDFA4A3FC7E3433CF2BF1696515 -:10A0F0002ADE9F59A5713FEF545B4B0ECAC5EBFC9E -:10A10000C672F4E7DB6DC56D6817A74FAA9C88EB94 -:10A110003DD5CC889E80AFF6E13ACCF9CA878569F7 -:10A1200048CCB644BE92743B53F2537522DF803C58 -:10A13000788ECB83447E807E0F11BF5E96A8AF06DB -:10A14000E47D12DF26D3E39076014B9483313A0D00 -:10A1500029F1F4D98DFCCAF9F70F088751D7EFC15F -:10A16000F7458AF7224AB419C2BE90F0A1DB924D9E -:10A1700038172EFC53A53DCE21B0DB5D382EAF87BE -:10A18000EF34FC713909178CFF1EE1672D87A75B3F -:10A190006916BF57C2F761D2DFD128E7BB2771BE6E -:10A1A00015567E7F811BFD3D14C329BBE8F3E06E8D -:10A1B00012FA77B6D9778F09E6F075C77C5AE71B94 -:10A1C00041033A60FEBB52FC7F4778F4BAC0BE88B8 -:10A1D00082BF37A2513E0CACE33FF83AF275917062 -:10A1E00025E3E3FF02863CEC3E0080000000000017 -:10A1F0001F8B080000000000000BE57D097C54D592 -:10A20000D5F87DF3664B324926098484409824644E -:10A21000830426611164712004A3020E8B028AF864 -:10A22000C21AB20B5D624B9B81B0A9684345A5166B -:10A23000754040B0408302A2463A2C2A56ADA94B45 -:10A24000EBD2F22548658718AAE2576BFFE79C7BA3 -:10A250006F66DE4B52A45FBFDFAFDFEF0FB597FB3A -:10A26000EE7ECEB9E79EEDDEA9B43B02EA00C698C9 -:10A2700087F5ED16CF9802FF642EF8EF80E57C732A -:10A2800016A33FFF4865ACB7096AC44279E3EB5FA8 -:10A290002B587F5583C2D218EBC59A12314D64D525 -:10A2A000944F60EE35AA8AAD7AC57CD69F31FCE723 -:10A2B0003F6E60AC2E12FED18DB1D63C9B7F330E2B -:10A2C0006286FF0633F6567186FF7EC85FB238D6C7 -:10A2D00028D19057589619EAF99470F7D614C6BE4B -:10A2E0000A8B1AC0E07BB7704807323662CE0F2661 -:10A2F000B1A88EF3ADB1F37A3F0C8FDA8CE90D196A -:10A30000E12B4CD1D83ED98FF5BB85433A2038FF9D -:10A31000AF4C4CB3C37C7FA8C23A545C47EB32339A -:10A320008CF704ABA7FC68172C7A08633DDAD7E3F7 -:10A3300053BCB98C594DCADD5E07AC09FFDC104C2B -:10A3400047BB4C8C752770290CE65529E1E85298DB -:10A350001DF27344BE52C0BB9BD5D50BFB31C279F5 -:10A360008EDDD642F05D53E869B607BFB3FAC73C4D -:10A37000A1FD74554F01B826C576843FCC9FE637C2 -:10A38000B1A6C07B320EC717F8B83792F031F1DEB4 -:10A3900031F45D9992A534C3BC0A8A5C94C60EFE62 -:10A3A000BD99E5125E6634E404F174B2BB76B30B7A -:10A3B000D76B6E1E321970FBF69067F234283F6E31 -:10A3C000622558CF089FDB113E433AC247C2C308FB -:10A3D00087AEE6BF2FC23BC305FD5C509A8662A1E3 -:10A3E000BDA753C05D4B41FCC43853C6C420DCBF7D -:10A3F00081718732360D8B00CF0FC66B1AB69BCE9C -:10A40000BC8566586F6C9166D11C349C09E7B3D843 -:10A41000C9E753A83A882EDB762A7E1BD41BE7C9EE -:10A420007E6C24E4AB8E59981FCADB18A7DBB68D6F -:10A43000AADF07F4B2F08DE78706E0D3A7824E3398 -:10A440003798984BE203FECBF68733575630DF7FC1 -:10A450007BAC2E9FDBD053577FE081545D795EA0AB -:10A460009FAE7CD0B17C5D7E48D3F5BAFAD77D38FB -:10A4700056971FDE7CB3AEFE88D35374F951AD7787 -:10A48000E8EAD785C1FE1988E0F63465015CE60983 -:10A490003CDD70658EAEDDB9A8F1C7705FCD5BBBEA -:10A4A0007002EEAB31AC4CD70FABB79C40BAAC8668 -:10A4B000BF88CF05CC1B1D007815B2D6D792007E81 -:10A4C000957EC58D705BB881D793ED161DB8676C0E -:10A4D0000CA67EFDF732660EE6A19F9A3F6DFAED5F -:10A4E000D190F271CE6213D2DF465764B7CF2210FB -:10A4F00010ECBA7FA89DE2D71D40FCBDAFBA6DF04D -:10A5000069F11B2AED83C5BB143F837E33587A342F -:10A51000E6AB8EA9CC0FF83FC5AA1F1D09E957B5B8 -:10A52000FEDF1E4D0FC2C796A0C773984B8FE788FA -:10A530002C3D9E23DD7A3C470FD3E339C6A3C77376 -:10A540005C911ECFDDBD7A3CF798A1C773A2A6C768 -:10A550007352891ECFBDABF578EE53A3C7678AAFA0 -:10A56000548F3F03FE25FF4D5BB35857AF9D0EBC84 -:10A570002513304DAFFF91AEDF32B5DC0A1868A766 -:10A58000071FFC457AC864CC1D003857021E02AE76 -:10A590008E7450D2B86E55D2BF40077F42FCF70F81 -:10A5A000C1BF3A2B5AEB845FCB54E23557F19C4044 -:10A5B0007EF6A54BFB0BA633323F4F3603DF60DE42 -:10A5C000E24C6F6490EF3116606C68907FF5C6B511 -:10A5D000E5333A8FCC4383E751577CADC3393A49D1 -:10A5E0009E3F5D9CA3AEDE413E0800F988F95E699E -:10A5F000A641D69A701E33055D1F0EE77479198B3C -:10A6000086433DA8330CE6F511CE1BC6F928BCFFE6 -:10A6100051DCA777B0060BF63F8B35513A9BB5520C -:10A62000AA31A715D339CC4DE93CE6A5F475BB6634 -:10A630004B017894DB9B873298FF97C5BF3FAEE014 -:10A6400064DE8AC3C9760957C9AFDFC37F42BD91B3 -:10A6500029DEE814E0BFE3ECAEEF3D029F0EE339E4 -:10A6600081FC77421CCD9799BDB953723BEB67399A -:10A670009D1B2F2B9A867CD79768776F85B5F54FF2 -:10A6800062F6443CE712FCA953003FC929FAF3B72C -:10A690009FA0895D3D1B16C7201E993F16CF876B73 -:10A6A0001DB75F8A271DD72FEB5F6DBD566BC33D6E -:10A6B00038CFD60A877B33D0E7FB021F4FDF6E0B04 -:10A6C000A851413AFA3062F66BDD016F5511DA207C -:10A6D000EC7FC6F49B56615E391CE75A0CF3BB5401 -:10A6E0000CF0E6F0BF8EC35FEB130F4BBCD05BCB1F -:10A6F0008C46F87B39FCE11FB9DE4EE7CFE753A06B -:10A70000F0F1F745681EECE7B0A929D98DF0303794 -:10A710000DC576CCD19DFAB960E570E90A0E6323C8 -:10A720007ACFC275CDB3D9DC2AF43956E1783D1918 -:10A7300077F7EC2AF8E77C93373EA0EAE63D09F18B -:10A740005DEE2CEE93087473C122E66DEF2EE0EE01 -:10A75000CAC17DD5D5BCEBB07F94037FA2F8510E62 -:10A76000A43F907FC117E3BF1FF236D3E5F7A7A23E -:10A77000FC926B726F86A28DE1D035D0FB3B02DE7E -:10A780004F58201F4BDFD7E0F78470DE3EE1519336 -:10A79000BF0EDA7BC7BE48787ABAD241EB29662E63 -:10A7A0002B6EB2B9CC4374FF97317F7BA519F05162 -:10A7B0009EA22D44B8DD1D674A7E9FE6A1F547792C -:10A7C000878DFC6EF42FF7E914275FC27C01B7A9CF -:10A7D000CC43FBEE36A65970DC772F5A3DC83FDFDD -:10A7E00015FC643AF3D1F799CC4FE99D2C40F5EF75 -:10A7F00062CD94FF7DC480DE3530BFC98F65A6234E -:10A800007F0D81FB4F08EE76EDEE6E9C5E4EF540BF -:10A81000B8AFEFFE9DE877B2A017D8AF2B71DDB0CF -:10A820005F07E7A586EC9B719C5E98D999FECFF6F1 -:10A830004D531B3F2F80313A1261FD370A14DEE879 -:10A8400029A37302E5AC6E00FF26974A7256D19891 -:10A850001633CE7FDBE79C8FBDBE8C45FAA0FCF59E -:10A86000312A437C4DDA30FE0CB67B8B05BA0D865F -:10A87000FA8557B4A3D1B0FE49C0DF8123B3A25EED -:10A88000704E849C4B3727AC1B8772C4CD7DF5DF9F -:10A890006F61F52AC26F428EFE5C9984E78AAC072D -:10A8A000E31D4238C4763C5FB6A708F9A21FEB77D8 -:10A8B0002DE74BA5C9F36BE223406748F773CCCC77 -:10A8C000D3D97E73642A928F91DC72AB18BB6DC2B0 -:10A8D00065EB2558EFA914ED25EC67F1C4BFCC4614 -:10A8E0007E0C7AD4DB83F01CFD9DCAEE87F213B593 -:10A8F0000071385C4FD6DA9907049CCF6A9D943F6B -:10A900005D9B40E9D95A17A5E76BB3A8FC62AD9BE4 -:10A91000F251A9DE23D8EF9C359F9B518E5A1D26FC -:10A92000F1C7E7B144D0EFEA30AE472D895CF26160 -:10A93000318CBB840E4038AF1BEAC723584A0F3412 -:10A94000BC86297C571D58BE4E71E3F934FFA8B66A -:10A950000AC967E15BCD9390ED0CF9E0643CC2ADB0 -:10A96000E28AC234D84A3F48F7BC8BE39FAA1D460F -:10A97000F33A53EBA179791A5B5E8B83F6E76A8B26 -:10A98000289F99EAFD10E9DBC33EB762FB893B5B78 -:10A99000CC49505EE8513CB8BF477B98DF0FF8DBED -:10A9A00060E1E7C506382F907EC6E44E79E27B88E9 -:10A9B000B614ED048E735BECDCC238A4AB61C566E3 -:10A9C000AC37FD1B90B95282F47DB57D72E1A04297 -:10A9D000F0B9703086E021E15421F075617FFF5BB2 -:10A9E0004740BF07418E54617E6D574C34BFB60F50 -:10A9F000C3FD282418DB2FDE97D68339709DD0D86D -:10AA000086F9FE3D18E021C2FEF413A8979DDBF500 -:10AA1000C304C4CBB9D8862F3F46BEF767CEF7181C -:10AA20006BF8EC71E48BBD12DCF743EEA205F43455 -:10AA3000D26BAA23F05CACB4328DE7B5FE983F1719 -:10AA4000CE487F1DBA3B692CEE271CCF9519E46BCD -:10AA5000598A8BD500DD67EC7E2CF5C730EFED0D04 -:10AA6000F33F7E1CD20B7E93CF02E7D605D670F162 -:10AA700025E4CB5B1CEEAD0CEB9BC3B1FE03163E95 -:10AA80002FDF56D0DB5DD89F9FF800945BB1BCFCF4 -:10AA9000B95FF4C4F9BF8C7209E45F5E1741FCEE44 -:10AAA000658BFB780DB67B82F7F7CC43F79E388039 -:10AAB000E98315F9F742DA273596E03DEFE78BFA9F -:10AAC000617B38F75922F0C75FBDA004C2006EB9A0 -:10AAD000EB0F2D4F84F1066E6C31F584346F8B5281 -:10AAE0008769FFDE45C7F0BC4D4F75D13C06ED4C84 -:10AAF00051519EECD7D3FFF10D240FE8E5849CF56E -:10AB00009F8FEDC982F2423FA5E1EC32A087D5BD0F -:10AB1000FF90CFF5C47AEA675FE3D4F7EE64B80E2E -:10AB2000904470DEC556B253E0722D90BFB0376DC1 -:10AB300013DA33F69B7C9BE8FC9AC3E5950B5EDF4A -:10AB40002F90CE2AA0BE0FF21579BEA8EBA1BCE2D1 -:10AB5000CF7DDD4051ACF7933716213C2AF73E32CA -:10AB6000BE27D4BB3092B90115AC64DFE5F1D88EB5 -:10AB7000F586B5603F7BEBE2EF80760FE48C1D82BB -:10AB800074E5551B681C56C5C7794C9C7BAC198075 -:10AB9000132F5809D47B003EE3F7D8C69843492CBD -:10ABA000889FAAC66529686F19ACD9DD2AEE9B1467 -:10ABB0005F62B523788EC2F977632AD44BB48A7E5C -:10ABC0009D5393BDD770FE59C57926FB7BCCCA7CBB -:10ABD00061B15C6E56F07CB6F2737B2BF0979AFCF9 -:10ABE000E0B90DE34E4FE5ED495E4E82433A0FE684 -:10ABF00099F498CD4FB2C1771C5FCA5B55427F91E3 -:10AC000072CB8CB8BA579A61BD8F456873717DF36A -:10AC1000C5B9CFCC6E17CA453F8DF0CC4B25B9AB2B -:10AC20003519D700E76A09E62B5590C3D242E430C4 -:10AC3000FB773B577744782AB1FD77AD6FE4BB4B88 -:10AC4000BE30B13CA083258FD8484FAD13F6863A6D -:10AC500061DFAA8B1C6A477EC18E9ACA5F83F37636 -:10AC600014EFA1BDDF2591F9C44FEA18EB146E076C -:10AC7000810F68C07702706E68C00F465F695539F2 -:10AC8000DD371D891E8CFC9679225D680730312DD9 -:10AC9000E43C35F603787B08E1398645302DE4DC69 -:10ACA000F4B0182BEE5FE688FD97D63F52E04FAE2A -:10ACB00063A4B0E78D6CFB3002F9E6922FF2897F36 -:10ACC00076B5BE57C4FA7E83EB83D492E9DD84F86F -:10ACD00018F557A719D739CA3C3919E51C98FF331D -:10ACE000F87DF45F4DFAF97F13AECB7FD7757C5FAB -:10ACF000613E13EECFCFAD7EDC9F8D40DFB89F1B52 -:10AD000017E5F8910FEC87FD6047BD668A95E4DC96 -:10AD10004661276DECEE24FBD2CB169EF7CD14EDE9 -:10AD2000C3189D238D337B52FB9EB6EA3773B1FF68 -:10AD3000BA08E29F8D16FF9A54ECFF27716E1FE050 -:10AD40004BC5F36310E81B827FD7590277AAD8DF7F -:10AD5000E75686E3AD8F09245541FDF58B7A52FD08 -:10AD60000F419442FBDD0893E9EEC90E2CF724C68F -:10AD7000427EFFB72A9D1BEBF320EF203E4EF6C02C -:10AD8000F5933D89E1DD308D37D17C54564DDF534D -:10AD900078BB8F2DBCDE1D027F1F09FCC03E273E05 -:10ADA000A04D8A30231D5F4C9DD342FB8379121541 -:10ADB00098CFE3F3D219F2D13B4A6F4A21BAA97F67 -:10ADC0008CF8D90C8103D91F36B00F45399AFF99F9 -:10ADD000397F6B18E2F3B69230B28F7E58B23CD214 -:10ADE00005ED6FD3D4800DEDC6D30A3DA1FAF8C5A9 -:10ADF000540F8D5BD1909D763284AEE7D8806F4042 -:10AE0000FF6BC2B5D348CFEC401E951F00E1E61F93 -:10AE1000B0AF4ECC4BDF4D768D79528F0CCC45BC0C -:10AE20001E6CB533D44FBAA2873AC403F4DB479CF7 -:10AE3000EB44AF88FF19E15CCF3103BD40BEAE21CA -:10AE40009BF49CA72CCCA320BEF6D908FF4553EC5D -:10AE50001EB23FCE08DF6483F2BB053FAB9B114EB1 -:10AE6000DFEB5E89F49B14D29F28EFDB63A176E5CC -:10AE700056FF8E6DD04FF9C16C3A6FF65BC5B82F97 -:10AE800045F0F2284FCACAC158DE83E8E0658B2B33 -:10AE90009ACADF50199587073262008E91615A581D -:10AEA000DA10A43BC0B303FBE5DF8F0BFA3A0EDDEB -:10AEB00022FE7CD591D42F6D7DC86B75BD37233EA6 -:10AEC000352B2F673F52A9FCB8D393381FF2C7AB7D -:10AED00093685ED2CE74DC6B25BA3F5EAE90BCF454 -:10AEE000A71A35600DB5E34FD97E5F06B4FBF4A019 -:10AEF00085EC78B37E56F6167E9FB5BC82EC91B396 -:10AF00004A97929FE0E2D24F876E80F5342FFF245C -:10AF1000590BB14BCF2A8756A176D5344F6A1AE028 -:10AF2000E7D6342D1DD75795D3BC00E5EB8BD6A6BD -:10AF300027515F7075D3B2F0FBA5174F6DE37277A1 -:10AF40006B069E1395664E27F2BCAD1274F85F69CE -:10AF5000DA00EC0FE0361BCF95889C26CEFF967E5C -:10AF600037FE7FB671EB7E05C6290B6FACA454F596 -:10AF70000FC07ECE298128258DE0A8E1BE3AEF0CD6 -:10AF80004421FC351397F3CAB6EBD7857FCCF16823 -:10AF9000376364072F6B503D61B80F98DF8AF32F3A -:10AFA00063D660FD9420BEA01FC21773FC69F68FA4 -:10AFB000010FA53BB2F351BF288B39F0D008AA0787 -:10AFC000EDE47E513BE6E57A3ACE87AFEFBCD80799 -:10AFD000E7E18B05E965A74DEAF934FEC5177BD09B -:10AFE000F8F1629F5C5404BDEE08E374E58675E1F8 -:10AFF0003C7FCDE9EA51C92777F07ECAE27C26E49E -:10B000004B65B54EA22BC997602EB4BFCEED4EA2B4 -:10B0100076928F312F63547F77E2662EBF097D17BA -:10B02000270CF54B7FC5C7C13CF2F3B3CF26C971DE -:10B0300049DE369EC7C6752F49E3F62938A77BFC43 -:10B04000337D312B61EE13F30685AC27D22AF882CB -:10B050003B61722EFA17ACBA7E2F465AEFF638D003 -:10B06000CFA0FF2EFBAB4DE3FA641F039E7BAAAD7E -:10B07000876CB80F9F66746E18E7B14AB47BF6D937 -:10B0800076BCAAC29ECE5C929E5C5C9E27FC7D64D0 -:10B0900095F8FB5E12F0E33284556A108EFBF3B430 -:10B0A000243C372E0AFFD0FE18C8E7A03CC5F12289 -:10B0B000F3121F46BA5CFED18224F4473D2FE168AB -:10B0C00080F732802B96D75940BFC9413DF7D8C38E -:10B0D00027D383EBF9ACD6E39917925FB021CF8EDB -:10B0E000FB71E1C63CFB9C107CD46D1F74CC0570D9 -:10B0F0003FBFDDEC46F65E67F63F84727ADD76B5DB -:10B1000001E908CAED08EFF38EC3BFC37A0B36C658 -:10B11000E4A31C2EDB2FDC50E899178287FEDBF5B9 -:10B1200078C96DD0E7071ED0E75F4119B4FBB5B70A -:10B13000CB0BE8F3838EE9F3AC15B03714E5018E41 -:10B14000B71786B98FB9006F7DFCAA1B3FF5714C0C -:10B15000993A11E5888DAA3B1DCAFB2CF5DE827257 -:10B16000C5E98DF3DD88F612D557F963C069C927A3 -:10B17000E38FE1B97A8E35FC6122E06541E33AABB9 -:10B18000D985EBD6D3FB7E93A0DF67B9FD6E915FC7 -:10B190005FDE912F2C93FEC1AC50FA32D2018C7B32 -:10B1A000BB0726545EF3DEC3C8174A2600E1039DA1 -:10B1B0000D6F586745F9EFEAE3F8B87CE9F0B8108D -:10B1C0001EC5C378D9F53505EC53D8776CEDEFC7BC -:10B1D000E3BC8B1F5048FE287E3EF328D257CB9EFF -:10B1E0009937537A7B11AD5FDA0917362A8148C83F -:10B1F0003B87B90E3443BBF97E6EEF98B3C216E4B9 -:10B20000870CFD648679AC0F2987F92F3C70E86BB9 -:10B2100005FA2FD9A86FB708F8349E3FA55BFE61E9 -:10B220000BFD2EF5D1EB1B37A9B8EEF962FEF2FC4F -:10B2300064BED1E4A7B89E376127F1FFE0DC991D19 -:10B24000AF297DBB07CFD1EBD7F3F6C0768B71DD8D -:10B25000150EAB0BD75D6167810898CFB148ABC7BE -:10B2600009DF2F6F88243BDD021BC8ABF994B23095 -:10B27000F47B3037F9CB3E7B4725B9A7228EE3BD5F -:10B28000E22985F4B40A34AE62FE699E5FC402B45A -:10B290001EA4174FE83AFDFA3CABE7FA5DB93970E6 -:10B2A00008E152CA9AB97E06F8F484F8BBCB619DD6 -:10B2B0001FC6A2FC6668CFDC1AF9F11C5C1EAB3A13 -:10B2C000F00F5B68B9D433A51E2CEDC74F6578C36A -:10B2D000711C8B909BD7DFE7C9C0F9AEB4783210F0 -:10B2E0000EBE7561A4EFDFB1899F5FEB63408EED09 -:10B2F00046F233C9E377285C3E6733393F1C617AF5 -:10B300002E80E74DEB2331EECD2EAA4FE7D8FA077A -:10B31000B3B9FCFFAD4AF250EB3A1E17B13E8FC3F2 -:10B320006FFD83B95CFE97E75E7746FD7594B73D88 -:10B33000196887600FF3797D8C4B0A91AFBF8DD769 -:10B340006EE81BB23E2997B392EFE6CFD82AE234DB -:10B350005AD785F9D19F7152F1BE660A916FBD7DB2 -:10B36000F9393174AC679BA8477E8F79A6C9F7DF9E -:10B3700000F39AF7A8C985F6B776787B3C19787EF2 -:10B380009E5C17968F7436742CB7471DCFE37C3FB5 -:10B390006230F3F8219D29FA9DD9D7A44B13C281BD -:10B3A000FEA09F9385DC1E1E39D84B76C0AD2ECEF5 -:10B3B000F78DEB982FFA9967F5FE765427F3917085 -:10B3C00061E3B8DC71F21E65339F17E01BF2437F27 -:10B3D0001E46F6C393E25C92F005BAA1B807C9B75E -:10B3E00062DAE9C5BF230CE8659D85D381D4DB42D1 -:10B3F000E845E0BF37E1F70E815FF66098A01713CC -:10B40000FB6F8463A193D3C335EA5F80EF9F20BEB7 -:10B410008D7A98C43733FB87FC33BF4BC50BBBF623 -:10B42000FB40CE28FDF523510CEA9D31D7C7BBA1C7 -:10B430007DF9D695511E484F9B7D514E18FF8C5F6C -:10B440002DF27702EF97FB4AFBB5C7A184F849CFED -:10B450003EFBC0245CE7975B2D4E640955DB6DA471 -:10B460008F55EE5D44F23AE45B787EF5E7E837AD60 -:10B470003AA0B7CF973EF348BC8BE0ED4B32256046 -:10B480001A486290566EB1B4FB91611890BF5B5739 -:10B49000E1FC8CED711E5700DF550D6AB135BA63C2 -:10B4A0007995E02F557B1FF81CED86557B6F3A850B -:10B4B000FCBECAE0172811FE11A35FE0577DF571AD -:10B4C00007001F8A33F0C1BCD2895CB85DB96EC772 -:10B4D00063035A507ED8F266949213F40F48BF4922 -:10B4E0005BC3DCA75E7275BD2F2F0AFB70106F9CCB -:10B4F0007FB90E2818AC048A3F4FCB2D81A811A824 -:10B50000EF6DB290FC5BBEEBE96D8F239D7D64A374 -:10B51000F3BD6CD7AB7FB81EE5E73D966E13F832EE -:10B520001C4A485C4E958BDBE3247E4A9F7FD5EA1C -:10B53000CAE5DF97C606F154B6E79015E3838CF0B1 -:10B540002C6838646D767482AF8696F16487DAF180 -:10B550009515F7C799830AEB91D2B17DC9A657A378 -:10B56000503E4338E1F924F1D68E47437DE87FD23F -:10B570004B83A99E13F594ABE1F181BE8CE056F1AB -:10B5800042248B8179947C6CF34F40FCEE5E1285F3 -:10B59000EB3965AEE674FFC4CA7894F74A2CBE78DE -:10B5A00027A5FC7BC993DF277A5CA854C73B738827 -:10B5B000DE134D244BF812719DF337DE46EB5CC071 -:10B5C00034A2C7922754AF1FD22FCCAC684F27FBB1 -:10B5D000E6BA74BE6F4E6D06E4C23A4F89F82CDFAE -:10B5E000BBAAD0A3EFA1F3FCFB62CD8C2DA6FC1768 -:10B5F000429E0B4B6F8FAFB287EAA1555B56372146 -:10B600009ECEF6F6F4C079021C7C026ECA3FA05FA3 -:10B61000F5F7853D389E980BE317A81D9CAB05F800 -:10B620001DEB37593C68670F6927F4443EFEF7C4A9 -:10B63000F830EF70D4834FC5771EFFB500D7C7E74A -:10B64000D7141AFFD5251FD8721FD1D75FDFE77C2B -:10B65000A6D23FB988CA9B2C811E58EE3F344D219B -:10B660003E616381CEF6F9168BD8E7FA7298A75936 -:10B670000985EF412E9F4A7A5900725920444E089D -:10B68000D28F35F89DD6FF73C1E79AC99F27FD80F9 -:10B690000B057F30AEDFC82FF2D23B8F53611B3BCF -:10B6A000F73F05F9848FC62D87F31DE591F28F6C66 -:10B6B000244794EFB278114EE7761EF9C31DA8DF38 -:10B6C00036C87DADE7C3C67D5DF2DC904EF7F5B9B7 -:10B6D000B5799DEF6BF8DEE9BE5EAB10BFFB9FF264 -:10B6E0006138F9C82E71B5FDBBB00B3E3C2B5DCF68 -:10B6F00087BF6039D123B0D059DC87F06480AF8434 -:10B70000AB91AFB6F57575CA5719867484C053C22C -:10B7100051D22B631A8DD34ED7926E255DB7D3AD20 -:10B7200071DD7A781ACB9311F73075EF8B1692177B -:10B73000CA1B797C22B4A378BA2AB4CF53EDFAD7C6 -:10B7400092BA85E6FD867C83A1BEC790F71AEA6BA4 -:10B75000867CB5AE7EF9812356AE3F0474F56C3518 -:10B76000B7903ED251CEF073BFD3DECFAD3EA48FA3 -:10B770005EAD56E49396E5CC1709ED5B5F5149EE5B -:10B78000B9E46A8D42B965651897EB2E39453E8656 -:10B79000E75BBB5B57219F94DF5BC3B81DE692B7A5 -:10B7A000352A26449F6F6954A3D0FEDBEC67459D84 -:10B7B000C7B7D4115C9B5957E55CBEBB14CEED0DE9 -:10B7C00097C2B9BDA1507524D7A01DB69EC711CE92 -:10B7D0005B363D8AE2301AD36E9D01DFE7BF4161DF -:10B7E00006184767C6F887B91C95EC34F3513CE15D -:10B7F000DC461E07316FAD1ECF0B1C5B285EEE0BC7 -:10B80000B694D205EBF5F10BA56C2DD159C946C301 -:10B81000F7C65B689F941AF68926ECC3C67D72480A -:10B82000F29F3C96A78B9314FCBC50CDB97506E0F3 -:10B83000E3D23195D920DFD6A8B25583795C2CFAB2 -:10B840009F5021C1FD5709FB15E52609AFF3B88FBD -:10B8500032BB965FCEEFFBF3D01F23DDECFF64C05D -:10B860002F213DBFFFA38C9731FFC21F933F611D66 -:10B87000EB171CFC7A36F2E94B076D0CE9FDD2C1DF -:10B88000D793D11E79E9251BE9D99796DBB89DFBA3 -:10B8900060A41F8F984BBDB95C5CF7CA57039AE947 -:10B8A0005C5E41F83B9F6EE5F255E3DF8EA33DBD44 -:10B8B000AD1156857CFF6004EDA7AA97C2C8CE7C67 -:10B8C000E995AF8686DAE7FEA7EB91FEF74B916C20 -:10B8D000C67348C7315C2FA87A79F8D3E85FAED831 -:10B8E0007BC83A17CA0B7EF3F701C8572F3DC7E54F -:10B8F000A98B96E627D1C6F955FA999F5B86A39D39 -:10B900000F3AEB09BB3B237BAA2FA733B870385CF7 -:10B910000238E0BA002E25781E74058FA88CFF54DB -:10B92000787C3E9BF3B7EB18FAA38370513CFC7B09 -:10B93000A4DFAED0FAF9F7835F0D40FE73B5F5E6EC -:10B94000FC7FB6DE9BFF63D7CBE9FD5D5442867476 -:10B95000A4FB8E74FDC20F28BF3BD24DF3FD8EFBBE -:10B96000BD14D7DFFD3F71FDFF3BF85EF31FBBDE6B -:10B97000ABE1FB0D81EF4827FA332FBDF2F7647678 -:10B980000DEB7EE6FF289D4B397EACEA3E9607F52F -:10B99000DF640DEFBB53481AE9540E793F43AF3FC4 -:10B9A00015307E4E17D8CB48FE2CE8F520C9CB7554 -:10B9B0002C9FFC17BE5E2AF975280804E0F07A4235 -:10B9C0001EDDB362E640AF25901F9B5441F16246F5 -:10B9D000BDB2207C6211CAA74796C1BCA09F23912B -:10B9E0002627FAA8C7F55203B60194B660FA5AF2B0 -:10B9F0002D14F73FCEA1D7AF6E31E84937B9F4E542 -:10BA000045ECB96EE8B72BCAB1D0FD8AF1583F4476 -:10BA1000AF7C2EC349EBBC89D5AF703AAE1D4EE664 -:10BA20004C0EA78E70F8E770EB0027A1479B457D71 -:10BA300023DCCC8EFB9BB09D99815ECCD74BFAB4B6 -:10BA4000D48BAF064F26F46DB3185AC2D7DC8BFBEC -:10BA50006743FA25B848B85F2BBC259E8C7097F0D9 -:10BA6000957033E2E18F194CE8B71CFEBDCC7966C6 -:10BA7000DC77A3845C3FCE1CC3F3BD9A542FED4703 -:10BA80003FA7F3BFBACD28D78F71C4501CA9F1FED0 -:10BA9000C29C61314315586F9299F96CA087A2EF4F -:10BAA0008DECAEF799FDCB53701C6EDFED6DE6F6B5 -:10BAB0006BD8DDBEF07CAAEFB142BEF8E185CC03C5 -:10BAC000F58B93985BE1F559742C85C73115E3C468 -:10BAD00020C576C5D1BCDFE21ECCBF9CE393F082CB -:10BAE000661FB46F40BF1E532C6F1F954FED7D2610 -:10BAF000DEDE6386B44F1A8F53685DC9EDF2C5ABC5 -:10BB00007B6720FF9830566F675E9AC9ED2E323DF5 -:10BB10009DE92278A9267702DDA758914DFA911A5E -:10BB2000EEADD88776FADD3C4EA778D55D1387E079 -:10BB3000FC76C7B9717A6727ED19CAEBCFFCFE070F -:10BB4000F05DDB1E46DF1D59DA7599180FA0B86647 -:10BB5000EF830F736E3B624D8021B486C917D04EC0 -:10BB600038C9B7E777E89F9C344DA5FA93188FC37F -:10BB7000642B22280E73A2EF737302F43711940E14 -:10BB80002C6F097326DF03F32F16F6E102B15FD4A1 -:10BB900070A63DE7C079F5CE4885EF1359E7F1C9A6 -:10BBA000CB447CB23A56D9887EA63E05DC7E2FEB8C -:10BBB000633FD8EFEA4C6EAF9F24529907B852FD0D -:10BBC000796B6C2D69A8FFACB10432213D943D76B0 -:10BBD0000AAE73422A1BBF01E17EAFCA36D37C5B3B -:10BBE0008BC9AF1099E5423C6840D2E45FA94F7120 -:10BBF000A15DAC654C4300FD092DBF4871D7B90864 -:10BC0000CB140F24F5AD963181BE68C76FCDE37EAE -:10BC100089E3CEE648D417E73AECFCFEA4882B9AD9 -:10BC20002FEED1F4A96B7EF03AD4431F51C95F3394 -:10BC3000FF117E3FEC2F0EBB5F41BD6D3DDFA76C5A -:10BC4000AD3E8E8839DD64079A5B3FC68AFAE63CD2 -:10BC500087C78AEB5C9BA5556722DF16F711FB218E -:10BC600012A0CBE2FA628A5751A360DFE13E31BBFA -:10BC7000A2500F36C6215589B823995F13AEDD8BCC -:10BC8000709A13EDDA8DF472A2268DECA30704DD11 -:10BC90004DC0B84AF467989B13713EFDF03B8C3F52 -:10BCA00021D699E1207A0E630887168B3303E9BB0E -:10BCB00065659809FD72139673BA867D663743FBF6 -:10BCC000FBCC2C1CFD0C378A7E672D337B3741BEA5 -:10BCD000979D99236391AEF288AECDFDB449B8BE6D -:10BCE000D33F61C3901EE6AE5D47FE184917CCDC1A -:10BCF000342E0EC639BD35251FF9663B9FEE37B68B -:10BD00001EDBB5D3C33485E800D24369440F531E0C -:10BD1000217A181BE8BB3807F5D172E6C1F33D81E3 -:10BD2000B9514E6863ADE4AF6C73585D68FF92FC27 -:10BD300044F20D795F56D2C13638EFCD16C6B6D76C -:10BD4000DA297DB6D6C9CCE98CEDAC4DA0FCEE5A13 -:10BD500017A50DB559F4FDB95A37E5F7D60EA3FC72 -:10BD6000FE5A0FE50FD41651FA52AD97BE4BBE04E2 -:10BD700070213E24F98AE447731DD616F45F4ABE4B -:10BD800064A49BD900DED1F9D49EF89EE477B80E66 -:10BD9000537E901F49FCA62A5E5F420AF2B1E699E3 -:10BDA00088FF42F5FCAE17502F2F71B8494F679CA2 -:10BDB000EFB501BD225C92ADEC00DA65EBEEF1B4BB -:10BDC000AC4E09C2FFCE12859943E8EAAEEA30666E -:10BDD0000E3937EEAE89D1E567D5BCF76A0FE87F3B -:10BDE0004677ED0DC4DBF19F7EF6C41FE1FB533FA8 -:10BDF0003D9B8EF886796C7D0CC75D1ADE3E8F58B0 -:10BE0000CCAFB0909FAB8FB09FF411F613FC137AB8 -:10BE10009FF9A99FFE37EDF3961A9B0BE5E28F1170 -:10BE20005F00DF3F097CCDA9B1111C8B577EBAEBB7 -:10BE300005DCEF4BADC4EFE6AC10FBD1700FFA445C -:10BE40002223BB0448D514CF7EE227D64004F47FDA -:10BE500042E1FB5801E16016C61FAE79FD43E403E1 -:10BE60004ACD31F2BF6B786F0FE7E7B39CD7DDABFC -:10BE7000AE798DEAB1E65E31685F94F79223067B76 -:10BE8000AC2E583FD236E26F4ED66196887E967AB7 -:10BE9000C589A2DF3CF17DDE1A85FC9A18C7330DF7 -:10BEA000E4BFB64C95F0999B69A6F4018CC127F9C3 -:10BEB000AE9ECE2949B7F3D6423BDC1FF579D605B5 -:10BEC00021FC788EF83E37CB44A9FC6ECAE2FDF621 -:10BED0005C933703E58A9E589E8369FE0C846F4FFE -:10BEE000C778B3124207DF88F173C5F80FE0A68365 -:10BEF000FFDD9F956A9D9F43F701E91C93E3CCC941 -:10BF0000CA5F85F1A573D68E412ECCEA2CEE846EE5 -:10BF100068BFCB92FD88FBD8761E475DDEC539220F -:10BF2000ED6AA7F19FC369DD64F72DDDFDABDD7818 -:10BF3000BFA0F4131BE1B774A088DBCAF10F9D4AC0 -:10BF40000648BD3D7BDCAFFE1C457E8ABD3CBE1372 -:10BF5000526E675D5AC2EDB26ED85F9DF88B8EEE61 -:10BF6000FE24AA533BF65EF53BD9B1AB946FA250C9 -:10BF70008E90EB297CE58B789A877285FC4455AFCF -:10BF8000AC8CEF2CCECB68C76EB7770BBB5ED5D22F -:10BF9000A24EEDDD46FBDDF02C83FFC0CCE89E9980 -:10BFA000B4DF3135271AFD005F88FB275DE939D200 -:10BFB000FE5DB5013A8903BA34BBA2D1BF75A90BA6 -:10BFC000F97A59163FFF2F087BF9A59D2AE93D977D -:10BFD0007646D2BEAADCF9F06BE877ACDCA2D034AE -:10BFE0002A5813C10FE0CAECA1E71AC6B1C5759C67 -:10BFF000779B3F3D1ACF95B25F455623BD2D6A50C2 -:10C000003C5B613E6D765774F790F9DC85F406F47D -:10C0100053666B184AF016F39F9AC5F9A4ACB7A8FB -:10C02000F161B22F43BD8B2417FD3A82F1FB29AD9C -:10C03000BFC3799EDB38C88DFEC2450D7B2A49AE51 -:10C04000D819E144BBC25911B7DCDE8FA0EF4559C6 -:10C050005C8E3927FC47E776F37700709EB8CFCE29 -:10C060002ADC0EDD8E6FD1AE4AC02D368BEF3359F0 -:10C070007F51434B545FA87FEAC07B94DE2BD6B53B -:10C08000C8D13400CFE3537B23C8FF756AEF2FC7B5 -:10C09000BF0CE35D6818D30DF785EC7F759685EAD4 -:10C0A0005FD8A81621BC989FC7CD54207C0785CEA9 -:10C0B000336E932F2574FFF1F8A1737B9F8F32E5C8 -:10C0C00004F15961AFB6279A701FDDE345FA8E403F -:10C0D000E2817AD6BD937D78865535E631A46BDA58 -:10C0E0007F89547F8D29A49ECDE2A63853CB8162EF -:10C0F0000FBF6722EE458938FE423587FC8AB307B9 -:10C10000BAA6DF897CF24D0BE16371B66B3AF2A7F8 -:10C11000CB4D2AC3792E4E6101944F96DC1BB90991 -:10C12000CF3139EFD983383F285FA3300FACAFDC74 -:10C13000AF320DD29E807F1FD25342F3108C936C8E -:10C1400049E172858C1F7DBCC4E4B1C239B8272B8C -:10C1500056F059ED17F3D17F36258BF4B9E356E647 -:10C1600053D1AEF41C8F2F2D4FE571CD8F8B78F806 -:10C17000F2D840461CF4775EE0B77C4A2003E32EF9 -:10C18000CA9F4BA4B88BF356EEF7C4EFE8672DCFE8 -:10C1900087F60E7A674393ED6342E8A97C8EDB85D0 -:10C1A000F5D458B72BCF81F3755E2439775F2443DC -:10C1B00039D7F442248F9B7A266CB32D046FAF0AD3 -:10C1C000FA93EF77B03B789CD1A3161E97FAE8D686 -:10C1D00044BF3F045E8F5AB49908075C07CAF78BC7 -:10C1E000ACF51928FFCAF92E8AAAA7799E17F4BEC2 -:10C1F00028BC9EC7738BFBC0581FF32D220EBD7544 -:10C20000878DE280CE2636EDC7F1CFEEC866B8FE48 -:10C210009614FF8203540EF225E0B3F4595B00D765 -:10C22000736607B7479FB17079EDCCE40417E2B7A6 -:10C2300068CA86D964AFD96253D0CE774661D60436 -:10C240002CDFDA9DE2CF4B6B6B287EBB14D806DE69 -:10C250001F82B408EF019DD99A4DF16667F0DD06A3 -:10C2600085BEAFC1EF1AAB9FFD2384C776AE5F9D3D -:10C270007DF66FD9A1F1DE322DDDA28FAF9374224E -:10C28000CB3FCBE2FAD067595C9F3B9BC5ED1115C4 -:10C29000110D8FA6D23A39DC014FFC1D1BD61CF9BB -:10C2A000CBC1184F91AE201F799C05327E897687CD -:10C2B000ED5CFF3ABBD34271EBA52F447A288E6D1B -:10C2C000F575268AA750B99C5E6A02F041AAFC74F3 -:10C2D0003BC597757B362CDF46F239233DB775ABEE -:10C2E0002AC6015D10D7BD8DC71D4F405992CA7334 -:10C2F000A9FC8CC89FD99F4B721FF4EFC1FB55A5B9 -:10C300003FFA3187E3D492B7B8DC65277E5BDEEE77 -:10C31000E719198DE760C5EA11D1785F91BDA332A5 -:10C32000945B8C70BA6C76F7403E3B3C5BF0DDFD75 -:10C330004F907FAA4CDC23287B56E17E68D8877813 -:10C340009FB36CD588C7883E7F6761E9B09EF30DC7 -:10C350000F4785E2232D9BF3C5F6FA5637D52F8379 -:10C36000FAD84FD9AA37A3683EDB2C14AF62C4E3D6 -:10C37000776EFFACFA9DDAB7D34703B7B374583F73 -:10C380006BFAC127D0FF5F7786B97DF4B581EEC126 -:10C390009DB3342CC0F59FDB15467CEB5C0CE70F9E -:10C3A000A7809FFA32711EB7FC8CE2BBDE9D4AF774 -:10C3B000F716FAF5FDCA71B3B22D3CFE2ACE1D8DDB -:10C3C000F18215EF703E0878B995DABF63A1F6C621 -:10C3D00075D8B239FF6FDF9FBB22881ECEF5E47897 -:10C3E00039B73B93CEA796184EE730DF64BCEF77A2 -:10C3F0006E57661EDDA343A107E8A154E8BFE762BC -:10C400001A929D21E52D16A1C705A026D20DB601D1 -:10C41000FE5E5AC3E5AD32FB5A8A2FC178DDA1F921 -:10C4200094066CB11DE36E815E49BFACCDE6E7209A -:10C43000C3F1E2459C38C9410D56E4DB9A9017CB15 -:10C44000771AE37679F96CD91EAF64C83861A443D2 -:10C450009F42712A652BEE5944F1F7D5EBEEC47D6E -:10C4600026E75F666645A8A7B5282ACDA3258CDDFB -:10C470003D05E5CAD07142E4B945D9EDF656E68CE2 -:10C4800027399684FE8A6C17A71B3C41F19EE20A6D -:10C49000652D8D9322F55DBE2E0927008715E304D7 -:10C4A0005BC688F22ED62DE7695C77BBDC95CDF9AB -:10C4B000514B8AEB672311CF6FAB74FFF7F23783D1 -:10C4C000A2633B91D382E7BC35182F0BF37F289BE7 -:10C4D000D1FCA7647339BD0CE371619E191BF5F1A2 -:10C4E000E2595BF4F97E3BF5F99CBDFAFC80467D90 -:10C4F000DE7D549FFF018E3B84EBE178DF18F57001 -:10C500004C510F77D9B81E8E79D4C331453D1CBF2D -:10C51000A31E8E79D4C3318F7A38E625BC511FC74C -:10C520003CEAE358FE9B6C7E3E968B784BC403D26C -:10C530003B7B314C771FE9D22BFC7E09D001DF37E2 -:10C5400033ADB46F1EC71AA48F70BB53CFA9761733 -:10C55000C60FAF8AD3766477C77B284DAB12116FB5 -:10C56000E6668A63AD7A89C7B196E78739D0FED18E -:10C57000BCF2D42A0C0FBD234EDB8DF52F595AB7D0 -:10C58000217C2B6A8ED07DFDE665AE776EE0F823C8 -:10C590003B0C2B892539AA18CFB9D8AEF1688C2766 -:10C5A000676BF5F1E3C67872631CB9910EA4FCF7D2 -:10C5B00094A53511F9FAA73BEC6B71FE9F8689FBB8 -:10C5C0003033EC86780007F193C50F2A9BF1BC7ECF -:10C5D000279BDFCB6E3B06F27A27E7AC4CE75E1970 -:10C5E0004472797B7EAD62A2F874CD43E7D01231FC -:10C5F000A764A5B56535F2B945263A372F83BC4601 -:10C60000F2E0FB2AC90FF8AE56E87AF05DAD50FAB9 -:10C61000C277B5F4F7257AEAEAE3BB5AFAFB12FDD2 -:10C62000F4F1F9D3961D42BD7FEADA41BA7AF3BC40 -:10C63000230C7014F316F2EC3C383F3C285F2EDDDF -:10C64000908CF85DB2A8AD6535E077C9BE303796FD -:10C6500097E0FF015F2C813EF1DE65C95E717FB915 -:10C66000467F0ECF15E7508999F99CB1413A2C715C -:10C67000324F0CB45FD4AF6900BE9FB5E88DF7862A -:10C680003A5351CF18D303F951B2C54371B5E57B85 -:10C69000D2639641BFCD7DB56F91EE4ED61F7968BE -:10C6A000169E877BB8FEF7E9DAE7A328BE4CD05B7D -:10C6B000B2C5198E78DF54CFE3EBD07EA6C606E96B -:10C6C00062537D5C785F4770BD413AF886F004F8AC -:10C6D000E1769E92C3E417696B10EB1DA3F850CE70 -:10C6E00096EB93EF6EB115BC9FEF89FC49A16FC823 -:10C6F000759ECF3E34C085F73A6A0F24ABC8CF4D44 -:10C700003BB7A11E72C5A625F61B82F1A0E97FC426 -:10C7100077D84A3FE0EBF9CBFA82A8E1287FEEB266 -:10C72000B827407E75FDD356D42B4ACD7E2BC567E6 -:10C73000EED864C578E51BB76FA2EF0BB617533C74 -:10C74000E642564DFAE869F94E828047C95865A31A -:10C7500013E65DDB8FF38F9270EEDF03F9E8557C13 -:10C76000A7E4F276250FE37CA679F7588BE17BBE30 -:10C77000A867DC276D6F4D2DEC4EF0E0F7403E6072 -:10C78000A0DDA775DC1753AFA4D0BE9876A53FE90E -:10C7900069B705B2B93E9C63D087DF52B93DAF910E -:10C7A000EF83126BA0DB54DC27072D24E75698F9A2 -:10C7B0003B4F15F0EFEB21F58E5475F45A352E42B0 -:10C7C00047CF3358ACEE3ECDED185412929F362130 -:10C7D0004D577FFAB4FE06FACF0F96131FB95E7756 -:10C7E000EFAF62A9CFA5909C3956FF9DF1F842C6E4 -:10C7F0006ED6B5AF605382F590BEB7285CEFD91BFB -:10C80000B319ED802526AE3FCDD0F8F7CA03FC3B27 -:10C810009BC174FBB04F9AFB8FFC5CB490DF40DA95 -:10C82000DB67E0BF3B813F63E1EDF7D8F11E3FDA04 -:10C830002774F7BB85BF10E78D78A810F6A48A2C63 -:10C840006E4FAAF03559F19D0480BF392E96EAD972 -:10C85000E330AEB25E217B23A64B29CE521FA785C3 -:10C86000FD61FC63E531B518F789B1BC04DF2942ED -:10C87000FCBEC4E3522BD12E14D5F17DB44AB413BF -:10C88000A17DCBF01EDAA17E2E211FF957F5443889 -:10C890004E50F2E8DEE6CE43568CCF9B362D260F67 -:10C8A000F78F91CE247F877D4D71856D6F1D213A65 -:10C8B0006B2B31131D5F0D1E951E6E6735D2DF0287 -:10C8C000D664C5FB290BF62A6ED44BB11EC2A52730 -:10C8D000D2A5012E71B11DE121E1D40E3743F942F9 -:10C8E000C6E1B5F080E247FED8014E027EC6F97778 -:10C8F000053FB9AE059A361EF9845CDF425C078EAF -:10C9000003EBC071A4DF820D33EED734B25F557AEA -:10C91000799CAD913EA65CE17699DBAF98299D3676 -:10C9200041BF3FB11DEE93DBAEC453F9B5D24F25E5 -:10C93000CC13CF856BA51BB91EC98F83FB84DF4B3E -:10C94000B8DA3B4746FBE4DBFD847D72081BA28B13 -:10C950006F16FCD6D8DE18DF2CE503E3B9531C694B -:10C96000A278CB36472AC91D92FF6AE25CD1567E77 -:10C9700041F534A8C767E3D19D439AB0132E8E4C7E -:10C98000A577249297C5C523BE8AC39C14D75FBCE4 -:10C990004CA538EA62A8E70A915B56AD484BC673CE -:10C9A000E4C47D994FFA409E3F716FB7F86130CE75 -:10C9B000A72B2DDDECAE60BD132B0B9331BEE3D363 -:10C9C00075B619FE4EE0F59538372A7EFA219D732B -:10C9D000174C6F45CD80F6E52BF745E1F581B29513 -:10C9E000FC7C5FDE57FBB21FF97D376D7322FC9C28 -:10C9F0009B06A09DD8C261DA2E5794AE2CEC8172B2 -:10CA000047F9B7479E74E2BDF0659678944BCFBC6A -:10CA10000FE7A442E71CC913A7C3A00BF2C345D27A -:10CA2000FB67A715E6417FD479D3A12F57A3BE9802 -:10CA3000D7901180F47ABB66E98F7AC1CAA7499E64 -:10CA400029BD7F5906BE43A82D4B8FEECC9E22D325 -:10CA50006DE23C47B91E5394EB31BE06E57ACCA398 -:10CA60005C8F29CAF5F8BD6A835E2E8C127E4A69F6 -:10CA700077EE53D79A877E3FDF5896554DE7B083C0 -:10CA8000DE055EA284BB913F2D41190AF37F8E2003 -:10CA9000BB037BFF261D9EE5BBC1F25DE051AD20CF -:10CAA000AB85EC931BAED859E83DDD312C46972F72 -:10CAB000B027EAEA173A5374E5372664EBCA6F7277 -:10CAC000E5E9F2B7640DD7D59FE81EA3CBDF3AECBA -:10CAD000265DFDC99EC9BAFCD4A299BAFAB7798B72 -:10CAE00075E5D3672CD295CFD4EED1E5EF2CB957AD -:10CAF00057FFAEEA65BA72F94E7223EA63367CFFDD -:10CB0000C54EA97C2FF9872AA3F7D8461698B89D59 -:10CB1000D1C6CFA3256FA73B42E9E0D6FE5C2FDD4F -:10CB200095E3B9B9FF90E07B98F29DCBBBFA73BC5B -:10CB300026B180C2F5E1A644A463633D63F9C888C9 -:10CB4000C3975D80CBD7FA1FB9CD8CEF475E77785E -:10CB5000501AE4A372C26EA7FC88C3CFA7423E7EE0 -:10CB6000E7AD3C3FF0F0652CF7E744F1FC5446A2FA -:10CB700049EACEDDB7613CCAC81B52D7BAB91DA578 -:10CB8000D3FBEE324578E03D718407A601A0634CEB -:10CB90000F031D637A14E8789E05E605748CE9316D -:10CBA000D04FF1FB6F413FC5F42DD04F31FD1DE853 -:10CBB000A59836815E8AE9BBB533287DBF56A3763A -:10CBC0007FA82DA1F4C3DA6AFAFE716D0DA57FAAC4 -:10CBD000F5D1F77BFB4BFB4340F7DE6857EF8A4A02 -:10CBE0003FA7F46BD655B3E608E41BCDE698CFEC2F -:10CBF000417F65D7760233FB2C445ECB553C2BFA44 -:10CC0000D3F8BD9C749F427C77A468F7217FF820FD -:10CC1000656AFA2015CFB1EA5731D4E60353E7EF3E -:10CC200047DE25E8C397E37908DB8DB2F3FBC9A3A0 -:10CC3000ECFCFEF12873531DD257DDD7CC85F13FB4 -:10CC40008722F9BB1F75F799FD680755AEF07D3E49 -:10CC5000BA1BA37CDDD7CD745F7994D39D80E79513 -:10CC6000CCB7FBFDF14F489C8FF4C3CBF89E7157B6 -:10CC70009A0A505E18EDB0BA908F84C60DA0BFFD21 -:10CC800050E467723E0CC793FEFD2D5FB380694090 -:10CC9000D08F3FCADE94827683D1DFB3BB43E39665 -:10CCA000A4BF5EB9D2ACA25D55C627C971E47C238E -:10CCB000CDD05F7E30FE6894B3210FFD1D75150E3B -:10CCC000EAAF077CB7E6533D8F4AED1AF2D02E3714 -:10CCD000BADC4171B0324EA0875837D4A3758EBBF1 -:10CCE000A2519CC468112781FDD879B90FFB19DDC9 -:10CCF0002D90887160A3ABF93B644F28D03E3F185C -:10CD0000B780F52342F62DCE13FBEDFBDF305F94A9 -:10CD1000A33C1E82EF54A9D7B9445EFA1DED63C946 -:10CD2000BE552078CDF214ED1DA423AFCDF9E70850 -:10CD3000DADF69BDD16E3A59C8F5FF845EDEFFF7D0 -:10CD4000D08B87E3BB17237B9B916E245E249EBB15 -:10CD5000A22389F7903833C2737BDC98E8C7485F19 -:10CD60005DD195A4A751768E77C42BC6A9493A52B6 -:10CD7000AEF077DD4697DBE9BC937464A4838E74D0 -:10CD8000C4E9B2EEFB76EAAF231D05F18FF0F8D7C8 -:10CD9000E9A85945FFD5B5D2CFDDAD6C7C3414156B -:10CDA000A46A77215D145F71BD86F9B96CCC7824D3 -:10CDB00029593EA18B72EDAFAD96E8103A1B25E8DC -:10CDC0006C4917F5653DF9EE85ECFF61ACDFBD639D -:10CDD000FD3785DCF066988C53F138F28606E34621 -:10CDE000971472FA2A4A5149EE28C8E1EF9F330797 -:10CDF00097B35DF017F9F1CD4C3B1A9D82EF947A11 -:10CE0000E97DD2F1DD0CEF930AF9BCC8E0E7BF3948 -:10CE1000E74692CF6FBECA3BD7C373C43DB71496E3 -:10CE2000728DEF907A72483FFCAEEF90F2F76BC7CD -:10CE300089FD9E24E829CDA5B291B1F89EBB66C6B6 -:10CE4000C3E528BE5F3B00DF79F551FE26E6A7F477 -:10CE50001616203962221C4498BF154458CC1F89ED -:10CE600098340BEF1C160C2AE88BDF43DED9BB0D80 -:10CE7000E757A96AFFE50C7967EFF03817DD5F3DEA -:10CE80006C4F233914F7AB25C45EFA069CCF7D6145 -:10CE90007D47E0FCC6F45538BFFBC239FA3A9CDF47 -:10CEA00098BF396B19C376E35DFAB827D9FE1667C8 -:10CEB00001286A5DC3EF96012FF642F8BE19933937 -:10CEC0000EE9E2CD98EBC6E17ADF8CE961E2A9CD0B -:10CED0004A69EE0B7D3B9393E57E088E379EC63301 -:10CEE000C257C2D3084709DF7F019EB539433AC212 -:10CEF000F32ED423D07E6B7F2F2A2115FD9B9CCF50 -:10CF00005644248BF748DF1EA0A662BCEF089AE7C0 -:10CF1000E89AE1CC8CFE763B87D3A95AE643F89E8B -:10CF2000C125A0C1DB60DF63E6B1A6D038E83D369D -:10CF30006D1DE2F5D44695EEEB5F782E8CEC76A76E -:10CF4000FDDC2E5969D21EC5F272D5B5D68DF2E63A -:10CF50009B2A7F47F49B23C95322AF815EB7F077AA -:10CF60000ECAEDE33BC5A7D42F67A57AEEE2F20D1A -:10CF7000D3FD1E452F1B7F0F42BE4BD995BC3534C8 -:10CF80009CF3BD5E36CEAF257E375A851C00FD0C66 -:10CF9000053E9BF4B370D2B71E8CF7EC463C801E66 -:10CFA00043EF4FB5F58AA4F3E9B0888B1B1DE84F1A -:10CFB000EFAD1589DF1D785DBCE77E58C4CB3564C5 -:10CFC000682F62FBD75D877BA1FDE106C6FD403778 -:10CFD00039F8FBF9D7AA9F1FCA11FAF90036E09A6F -:10CFE0007E27A1BB4AF72946B30CF2C317E07C9118 -:10CFF000CFBD31D78CE764C8EF24D0BAFEAFFD4E69 -:10D000000263AD2AAE2BC9A9B0C753AEFD77135446 -:10D01000A157C9DF4F28E2451D7E37E19751453CB6 -:10D020002EDFB1A0D3DF4D4812EF5A33173F37E45C -:10D03000EF261426E8CF9102E798A34E4AF5769E94 -:10D04000A4ABC48F29B9E2FCB856FC5730C27F7B31 -:10D050009C69371EFF345AEBF733B4CF1774B3B85B -:10D06000FDAE8E74F09FF6BB285DE1C9F87B2946C2 -:10D070003C197F3F25492D37D33B90024F33E02F9A -:10D08000E2E906F1FB16E3F0F72DD8BF0F6FC30CF2 -:10D0900078FB82AD1D82EF965E2AE67CBDAB73FF06 -:10D0A0004B9767742EF0BD9B05DF97F61119976BB0 -:10D0B000FCFD24690790F1BABEB11CDFBEE311E4A8 -:10D0C000BFFAA1DA1C89E7CC7113FFBDA4C4EEDA64 -:10D0D00004ECFFEE9C6A05E191C0BC7B16C0FC67C6 -:10D0E000FFC6968CF9D97DF87B912C87FF5E909CCA -:10D0F000DFEC241ECF352D57E8BB6E1EBF353D97A4 -:10D10000EB01916E27C59917E730113FCB9267E786 -:10D11000227DBE159689F4B79EDB039BF1BDCA6ED6 -:10D12000C1F72A514E47B9B8B7904BEB3EB2DB3945 -:10D130001D32DDF99FEDB7EBE29CFB6F77EAF2B9A8 -:10D140000D09BAFA030FB874E579812C5DF9A06373 -:10D150006E5D7E48D3305DFDEB3EF4E8F2C39B8B01 -:10D1600074F5479CF6EAF249ACF51708DF8772536D -:10D17000091E7D14612771717CCCFE613CDD5792E4 -:10D18000FA878C7BD7043D1BF59A3E562ED7D725C0 -:10D1900032AEB7DA857ECAF4FA8D26E2D6A55CCF28 -:10D1A0007CFAB87519AFDEAE07093D47EA1321F1E5 -:10D1B000EA1E9CBF8C576FC7BB783FD448AFBF14E3 -:10D1C0007837AEA38F95DFAFABBBD74AF784E4FCCB -:10D1D0008CF33A20E298B7DA3B7F0F6A472E971319 -:10D1E000BE4EF36ECA857A4F02BB22787618CFDD29 -:10D1F0008CBF3F50F713AB7BB9EBEAE3CD1EC8D72A -:10D20000330BDFCDCDA1F757E95EA01CF74541DF19 -:10D210009B060A39C530DEEC681E1FC7A2AD74AF8D -:10D22000A5EBF1385C13AC6C05BD5B25EE79DCB584 -:10D23000B6E1412C9A65ADB7F08707FC16B4A34D53 -:10D24000180B72621EE886CF2C7AC40172D1933516 -:10D2500066B28B05769DB8DDD737786FA70FE86982 -:10D2600048271310FFD0EFD0813C8EBC2597AFAF7D -:10D2700050FDA6FDBE854DC7FF19F1FF4EE88EE8B3 -:10D2800051AEE37FEBFE85A45F239CA45ECEC4B9C0 -:10D29000D657CC4BC24FEE0B093F79FFC5758FC5F2 -:10D2A000BBD941F7688A302E4FE2EFA681DC6E1FB2 -:10D2B00087B260775E0FF95157F50AD59C68F4176D -:10D2C000B43157B4F32A76F3FFA57B2904FFAEEE01 -:10D2D000D375C5273AF0872EEED775459FF4E71A28 -:10D2E000EED985F0091E2F25F0E1EF6BA2B884D5A9 -:10D2F00091FA7D5C3080F38753621FC3F9EDC8D388 -:10D30000F30986FE8FBA95AAE0130BDA7F6F04BF8C -:10D31000CF5F6921B99B31EFA318A7F197F5167A72 -:10D32000E771B487917C3367A3E2DFA4047FE7ABA6 -:10D33000D86778A745FD86E4C32FD62A4EFCBD8862 -:10D34000B96BF4E50B1DFC774AE61BDFAB91FEB829 -:10D35000ABE8F5830788F3DDCDDC249789388A12A2 -:10D3600051C72897B5F9B9BF11F57295DBB128FE01 -:10D370004E9EFB2EF47785BCC302700DCFC2737C2A -:10D3800085B9D3B8C876B87611F771DE21E23E1CB4 -:10D390003CCEA56D6F18F70F4B3F9CA87FDE7799A9 -:10D3A000CAB13EF676218FC7AF48FF9BD1BFD7E603 -:10D3B00030917FAA6D6F24C539A0DF2B1AE8E1AC4C -:10D3C000694FFCB094E0FCB46655E73732A6DAB298 -:10D3D0007DA44F2EEFABCD1E8071FA66B7DD0DF93F -:10D3E000FB1C87E91DAF09C20E669C6FFBEFFE8D2B -:10D3F000E4EFEAB4F9B8BCDB56C4DF3B01FEC87009 -:10D400003FC9788EC90CA43B488B03C3693ED7EA59 -:10D41000FF9A7A258FFB7FAF8CA0F6DA9AE194EF22 -:10D42000B3E2C17BF09ED16D750B2D180AD0FC8B39 -:10D43000A585E1D0B4B9B77F7938E26D8CD2A9FF68 -:10D44000A276003F5F9A0DF716647A49EC1BC7403D -:10D4500026F89388E75AA6D07E58AC3019DF45FCF1 -:10D460005CE62FD78B7C21CF2F59C9F3CDE27715FE -:10D47000B6097B0BAE1B535C37DA05760A7B0CAE24 -:10D480001B535C377E47FE8579E45F9847FE8579BC -:10D49000E45F9822FFC2EF739837394FE57EBB7186 -:10D4A00021FB03FD76E342E423F4DB85E6D16F172D -:10D4B0005A1FFD76A1E5E8B70B2D47BF5D681EFD3D -:10D4C00076A1F5D16F179A67C36E0AE691DF7926C8 -:10D4D000EBF25341FE1F17B2BFD16F17DA3FFAEDDF -:10D4E00074FD69F7E8DADFC96A74EDD16F175AFF86 -:10D4F000EE1A45E7D7BB5BBC433B77431CD14F7962 -:10D500008AB711E9FEBF22BEFDBE05F545B5711112 -:10D51000D7DBC2DD1CCFF5451CEF267ECF42699DCF -:10D5200049785E6AE5F9421EE76DA41FF48B8DB35E -:10D5300070BF18A6E817C314FD6298A25F6C5C3A2E -:10D54000F78B618A7E31FC8E7E314CD12F8629FA91 -:10D55000C53045BF18A6E817C314FD62D80EFD629A -:10D5600098A25F0CBFA35F0C53F48BE1F7E3E89F35 -:10D57000B304E785F27C5F9D5E0974A8D32B9DBA46 -:10D580003CCAF3A1F5519E0F2D47793EB41CE5F935 -:10D59000D03CCAF3A1F5519E0FCDFF2DD745FB0C12 -:10D5A000E5FAD07628D787E673EB7DAFA2ED6CE283 -:10D5B000C68B47316D8E549E548065FC7DF78FA6D7 -:10D5C000A3FFB2394C498E01CE69517CD3C7415E6D -:10D5D0001371940358AB897EAF0F95478C73083055 -:10D5E0008A5BCDFD3A91CAA3329DED71CB88F7BC21 -:10D5F000BD8C7E8F46FAD7657B3773AA98CAFAC16D -:10D600007CE7F58CE3CB7AC43F43E68137AD31DE6E -:10D61000276FA9231FE366B789DFCBDDB69CC75B05 -:10D620001BE92A4FC84BDB4C7B0EE37D9AD6628503 -:10D63000EE5D6798D9314B3EC2A93A1FE588C48197 -:10D6400031625DD5D7E3EF8EC9794B3B28F009BA3B -:10D650009F38B2B5A9201AFAD17C63E8F771265831 -:10D66000B9FC80ED50AFECEF533C9B43E83B4DC819 -:10D67000E39A8F8FFFCC539378BB70DEEE99A7A20D -:10D68000088E9356281477367227F3E03DE81C3154 -:10D69000EFFE3B032A8E57BC828F27FB2DDE984C72 -:10D6A000F7428B59F338BCD7C2062B0CF9B6841B52 -:10D6B000ACEF28AE2F03B60ADAB1BFEB7DAA5183D7 -:10D6C000630A311E9135327A5774E2E0DFEBD64BB4 -:10D6D000681F4AFDD2B996E953E81DE749BE65CBFC -:10D6E000F1589FE8BBE7D5EE587F0B73A7B8E82841 -:10D6F000A2FBC7723EFD3C7B4C702CB21CD6640A68 -:10D700005310DFEC485C08FDC0CE9F86F8CE735BFB -:10D71000E85DE5C966A785DEE9E8225EE7B243C6B3 -:10D72000EB18E405435C4EDDD20F93D1DEBC38D25A -:10D73000447693C5FB22486ED03628C4D7A41C5427 -:10D740002CE2FD2EAF78B5FB7484FB1E0BF527E3AE -:10D75000752AD2FCC926BC9FD073D3805895E4802B -:10D76000BB07A21CE07BFEF661586F257F57F4F2E1 -:10D770008A7DFC7749857F47FECEE93C11FF559CA9 -:10D78000EB8DC67818F97B6AF29E8CFC1D5369E715 -:10D79000297E7BD06B88DFE227C4BBDF6B8AE9FE82 -:10D7A000BB31EEAA4CC87F8B5658286E6B91413E18 -:10D7B0002C13715957FB7DD39A8106F950FE4E8E7A -:10D7C000A8C3D45E7F40BBB0BCF739CBC2F9C0ACB4 -:10D7D0003D8CFC55B3961598F0BD6AB68FD3CFAC8F -:10D7E000655CCE99F5A287EE6F4AB9F11D21CF4C49 -:10D7F000B99244F07F4FC82FB761BC2AC0794273F9 -:10D800009888634BA474FA151EBF3AC5C1F941F359 -:10D810002BFCDD8D369F8DCB5547197F37CE409F32 -:10D8200093CD7E135E68748F04FA84FC449487A0C1 -:10D83000BF19281FC521BDA714523C649142F78827 -:10D840008CF43EC152FD2AC6DB4ED8CADC3E164AD5 -:10D85000EF40C7D89F4FA1F71834A1E74A3A36D214 -:10D86000FDEC08619F7270FB53BB9D0265557A44C5 -:10D87000FD83E9184F3C1B6D863D69191E8CDB8BBF -:10D88000CCE1E5CF0DFC60FA0ABCFBD185DD42FDA1 -:10D890009195E0A1C97727BAB023A0FD00F9E55D15 -:10D8A000DFCBB3CE09E197CBF3C6BEEBEE1EC4F7D8 -:10D8B0001CC37DCAC5F7A5D3EF1F752517CF05B8C3 -:10D8C000E2FE981DDDFC7DA054F6FB81CC332E01D9 -:10D8D0007F5F52AE8F05301EF30E91FFF6D77FFFAC -:10D8E000E31A07C185F26F0FFC743ABE3B57616FB4 -:10D8F0001E8F645795535D84F1D9413EA5799252AC -:10D90000904FE505F0F7F80EC87BE006FBC4B703BF -:10D910005DDCFF62B053CCCDE1FC9B89F7C64FDCE8 -:10D92000F7C26E3CB7E4FC4F58F4F76A65FAE5407D -:10D93000D3BFF55E89F13EC94F93B453C83F1E353E -:10D94000F1F7137AAAF54CD88BC8AF2CF90613EF70 -:10D950008E04F1EEB1F2B804C5196AAFD2D628FC34 -:10D96000BD822EEC3A2CABF5175BA1DDEC5A2BFDFA -:10D970009EE353199C7E9E02FA41F96C96B5E955D7 -:10D980007B4A108E9FD4FCDCC2F958201DDF3BBAC5 -:10D99000A33ACC8D7C79799EF7EF38EF881C37F16C -:10D9A000A377DD9CBEAEEBEE656EBCCFB8F6D09330 -:10D9B000F87EC3FF037EDA89FC00800000000000CF -:10D9C0001F8B080000000000000BED7D0B7454D588 -:10D9D000D5F0B973672693CC244C42200F489800A9 -:10D9E000911401270981800837C82358C081100588 -:10D9F0004DC28467B46023D51A2D2D03493020DA37 -:10DA000080C120F53150A5685163B56DA8D80EE2EC -:10DA1000BB682948F5FBDB86E18D8FD608B5DAFFB8 -:10DA2000E7ABDFDEFB9C93B9F7662680DAF5757508 -:10DA3000FDE3721DCE3DE79EC73EFBBDF7B9F9F68B -:10DA40009E1CBB7F1863D5EDF96BD33D8CADC9F738 -:10DA5000DBBC7DA0EE72DB7D2EC66E6948B67BA076 -:10DA6000AC4A63B56DD08FB1CEECD9898C7D81BFC6 -:10DA7000098C657915C6A0FF1FF2A1A988B18F6D29 -:10DA80006C2EEFD76C9B65E867A17EACB95573F43B -:10DA900065CCCFF82FCBCA029602C606D8FD4C4BF8 -:10DAA00065AC3E8379D7E430D60F9EC715F0F6F803 -:10DAB00014E8EFB21F5592E085C0642D9CC7DFFDCE -:10DAC00062206376C6340BB4F783D20EFDDB877811 -:10DAD000689E2C6857E1B92DEFD83C06FD2AEC6C06 -:10DAE0003EEE47AE479633C5FAD95C8785C1BA1674 -:10DAF0003BE0DF30C46475D894B4918CADD8A8B83D -:10DB0000E3E0D12297E7FA31505FF4BA8DAD81FAA4 -:10DB1000F4148F3D03EA9DEB14F776A82FB82DDFA0 -:10DB2000EE817D57C03619AC63D19631CCD31BCA78 -:10DB3000209485DDE795E58D1BF765ED86F958485E -:10DB4000B3FB005E8BDC9A3D6558A47D61B3A205F2 -:10DB50005DDDEBE3BD2AADBB82B14908BFCADB7214 -:10DB6000EC0B5C587FDDB66218EE8BC341BE07FD3F -:10DB700042D86FFA40F62AC375C3BEB6E7F0F90A79 -:10DB800074E32FC0F175F343FFF93EA8977A136948 -:10DB9000BC6A37EC3B074B37AD13E04070EABC176B -:10DBA000C6F3D03C741E0B43419B17D7638579A104 -:10DBB0007E833B68C3791634E4DB1994FE0D7C1E2A -:10DBC0007F53B27D38D4ABAD6E7B16C22F0160910E -:10DBD0004AEB0B6E87A35904704971E13C6CFE6CF3 -:10DBE0005777F8548BF52E6A4EB62F363CDF68C354 -:10DBF000F39807EB698B72EE77E1B917E17A4AEC9B -:10DC00000CDFB76A762FAE47C0F7E4ADF1EB592FC2 -:10DC100078BFA5D59603F59B05FEDE85702D42B82D -:10DC2000847215DCF7ADF15E5CE73C7733EDAF0B4A -:10DC3000BE9B011EF07CB1DB47F005BC083080C301 -:10DC4000A216E37946D69348E32E6AA9267A5B6248 -:10DC5000F5DBDDFA756CD99BAB005CE6D5C67B15B0 -:10DC6000803F73FBB3115F4E6DBE3E9BF609EB44E4 -:10DC7000B8267A3D53D247129E101E4B7CA92AE447 -:10DC8000F42BE7DBE4B5D27C9B705F453DD1A5F674 -:10DC90006A3AD2259CEF1A4F6CBAB433180FE6B526 -:10DCA0002F5282F54A773A95F429E952D2A9A4DF96 -:10DCB000476CBE50BA12E13355BD58EDCFA2C0E952 -:10DCC000A038871BC4B9025C5F46B8CAF617043D8A -:10DCD000570C34D23B8E87E3FE449C7BC5C450EE88 -:10DCE000ADC322FDE5BC1529FC3DC47BC4B79F082C -:10DCF000F860FF15D4DF62E0170BBBF8C5AEC6BEF7 -:10DD0000C82F9E55BCC82F56DCBB2FEB0E80DB8A7C -:10DD1000A79C5E84C187CB1EBF2503E0C0AC413AFF -:10DD200037B9AEC59FE7139F58F2F9959C5F84A25F -:10DD3000F30B579EBFDD5B14A92FBAFFA9CBFC9C48 -:10DD4000DF8490DFFCE9A9170E8F453EC28236DFE3 -:10DD5000F0C87E1634FDDE56EDD2C38FEF777DDE40 -:10DD6000D96A3CAF852EBB4785470B1BAA89FFB2FA -:10DD700074E6CD5522E76FC68BEA0645A3F7EA465F -:10DD800005D5AF914F2FDC300BDE8D9C1B4CCCD8D2 -:10DD900028D827E3F095EBFFA3587F87E06F37087B -:10DDA000FCBEA1A6C49E918AFBAD2E04CEC8E68916 -:10DDB000E7F316199F779D9BBB8BCFAF457A39DB75 -:10DDC000C6CFEDEC061BF19FB3BB12830CF6F7E157 -:10DDD0008A5FBE7D1DF4FBE0816DD94C359E1B2B07 -:10DDE000E4E786E5523837D63BEAB97DECD5F1E178 -:10DDF000A58FF2735BF8F45B7FFE9587F6CBF9DDB8 -:10DE0000BD7141E4C70BDA9EA5739CD7B4D196834C -:10DE1000F4EACD21FCEBE2FFB5F96E06F0BDA16995 -:10DE20009B0DF9C417120E267A8052633A3A43B911 -:10DE3000A4A420FE853310FF647FE48FCFC23CB7DB -:10DE4000DD1A9FC4AE88CC9397CFF17E616D720AC4 -:10DE5000CEB7B0B6FA3E3622220FCCFB3C1ECFE93D -:10DE600065018C87747BBCC49BBD82F0D31255EED8 -:10DE70000EC8E7E7F82300773CE0433F67DB130871 -:10DE8000877EDF4EF022FF183C381CC47911BF7129 -:10DE9000DD76E09F0EE8377859F8135CC760C03034 -:10DEA0007C0FCBC4142A595FA86F8765174339507C -:10DEB000E5E5E47CBE7F680F613B4B0D17E1FE2575 -:10DEC0007E9BF1D7CE1E6B1A887C2C9579EB3D1189 -:10DED0007C95E3487C95F81C6B7F575DE4FE8EE7EC -:10DEE0007078DA13607F2997B03F40D6E294C8BEBD -:10DEF000E4FA581EAC0BE6A9FADEF06DEB619EE386 -:10DF0000ABBDD9B5AE9EF6DB32B96F94FD9AF72959 -:10DF1000E9669183D334D04DAF30ACFB6CF3A05E97 -:10DF200028778E2B20DFE0BDE3B7C65B70FD725F04 -:10DF30003B56416758EBCE550E2A9F5C05843784CB -:10DF4000B15DABD2A9FEF42A0F956DABF2E87975FD -:10DF50007E0A97472C9C887A26E8039C1F84389D6C -:10DF600074D40DA27DC9E7522FE87087135374FC57 -:10DF7000FB44AD909B2C7C2FD237AB1BC41E87A9D2 -:10DF80003A9A8F275A86217EF2F5C9F76EB3751239 -:10DF90003F648976CFE34072CEDB7E3F390DE65B8E -:10DFA000DC9293AFC07B9575851D75D05ED990E6E8 -:10DFB00045BEB1D8E5598B72717120C78B72D1D92A -:10DFC000927F6A0BB42F6EB8DC8BFD6F53980FE90C -:10DFD0000BF82743B82D615D3FCD017C6DA9E06B47 -:10DFE0004B915F02BC96D4ED1BEC86F79778E3F378 -:10DFF00051BE2FDDA284E290DE2CAC4941395CEFAA -:10E000009B827CACF341C58BFA267B08F8AB23C21C -:10E010005F37E4F956E6E3F99F07FC83F187A20C2A -:10E0200056715F6D1AEE83813EF238C375FB48AFBF -:10E03000FF7F428FE968399AE819C6E18DFA3AF311 -:10E040006B16E4BB2B845C1B60EF3C7A37EA3389A8 -:10E0500016EF76CE2F7FE7C17DBEA1B2389237A2F0 -:10E06000BFE0A7037E50EC40FEB62271601AE9556E -:10E070005B54E28F127F6AC49A176F2BEB8B78B3D5 -:10E0800018DA51DE6DC587C042D7B65CDD17F16A7C -:10E09000D1C6C90F04408E650B389EB08667E1F982 -:10E0A0009CD99696B21AF5C2E5F59731685FB4ED42 -:10E0B000EE6C2CCF6C8B9F8BFC7E927BD6A464D8AD -:10E0C000EF928792F3559DDCF8A9A0C79B975F9DBF -:10E0D00086F6C0B27FEE7BC43D08E6075823DC3FDE -:10E0E0006D730603D065D9AAF66C1568ECF338FF9A -:10E0F0000E84E7B72C7BAE1B83FC5F09EEC8A0FE45 -:10E100009E3477147A97E529C0770FE0F3F21FBCAD -:10E1100047E3FCC5B27FE63C787FD9F2E792709C7A -:10E120006F6D3E34CA0DCFD70CF6FF0CC7FF40D938 -:10E13000B6C38D8269CBB61128B79F1376D4F41479 -:10E14000DF75F310EE6FA804F758F3D5B42B045F16 -:10E1500059AF0CF6227DD61F627637966E46FAF2DC -:10E160001995D5A13E20F51AF9FCD57CAE0F9DE995 -:10E17000D59C8D7871D38ED66C942BEF27F27AC50F -:10E180008EEBDF443EE57F2C8EEBED56467AF2C2F5 -:10E1900000D7BB590DD06B4664FE03F94E82F34D98 -:10E1A0005B0A0DF210F4129AE77D2B2BC5750CA8B3 -:10E1B000EFCC47FDEB8FD6D0623CD73F825E1BC8C9 -:10E1C000C173E27CEC8FCDEA147C1E0042427DE4F8 -:10E1D0008FCDCF250E7645F4B8C4916D21E473CB75 -:10E1E0009F4F2E50394A117EDDE296FCC935A55F5E -:10E1F0002AE9636EC4D315BB5F99C2781D04616CB4 -:10E2000078DE2CF4B0AEFAF3CF925DB76C17D72757 -:10E2100096B53DFB6A268C734BBBD027849EB25CBF -:10E22000D0F32DCF73B82C7FFEA87DA1DE1EC94B85 -:10E2300059DB0F34C173F9B6B99B518FC2731BCB35 -:10E240005842DBE7735783EA9CE07573FE6DED245B -:10E25000FD707DDE41B2CB973788F1F20EAE1D48DE -:10E26000FB9DD55BAF0FFD2DDF467095EF033CE8BE -:10E27000BDCFE2934620FF0B2D4F6842B9AEDDE2E1 -:10E28000B26259BFDC4572FEA15A4B9E15E0AB2924 -:10E29000095ED4E3EA1CBCFF1D0949DBB1DC93C075 -:10E2A000EB9FC567939CFACCE27B7609F4BB433DB8 -:10E2B00010CF06E19177EEB3403DA38FDF5900F315 -:10E2C000A731A01E15E54748C1F68F5F3C5D88EB7E -:10E2D000183F207C8EC1D26C4ADCBC49A82215882C -:10E2E0007D0E0B1722BEF77989F3EB876DAC09E53C -:10E2F0001DB3FAD86C781E42FE85E7FF0F4B10F96C -:10E30000F11E25F463BDFE555AC0F1D617E76A52D7 -:10E31000609D6539FEFEB88E6B15DB70545D9847C5 -:10E32000CDC5F13FB6F176A9C74E144C384BD86332 -:10E33000F6CC7417EEAF5EC04BD1345607EB5833B2 -:10E34000ECA585882FF7743A581CCC3FB13381F483 -:10E35000DAACCC52926FF5022E8A2715650E7B69D6 -:10E3600098251007EBBD873982D89F394CFAAF2525 -:10E370005EC3F7943DAFFD03F97D3FF5937DBDA0EE -:10E380007FBF3B146F3DF4A93A7BEAE1DF31B49FD4 -:10E3900083F908BFB97DFCA30A50CF3D5B7AD40F47 -:10E3A000E77D8FBBCDE11DC6C7D3EF63CF9DFF488F -:10E3B0004AB144D6F771E7A9A77E39124B07C9A124 -:10E3C000897B549223E6F57C9CEEB1D239753A42B2 -:10E3D00016ECEFB2041505FBEF7B0FD737D1E10A3E -:10E3E000A9A8C73B6C1FE9E50C3B90957CEA72122B -:10E3F0002DEC0B5016FAD6F3F31BDFCB685FDE581B -:10E40000C0EDA41B0B38DF95F09570631E8DE9E518 -:10E41000CCAF5D3B2A992542C7DF16CFCF7E3E9019 -:10E42000F48BB37B40CF88A277CAF210EA19A857C1 -:10E430000CD416161445E46CB994BA420EAB62DCE7 -:10E440007201AF729785C3678E093E026FCC786107 -:10E450003E77799EECAE03AFF4CAA1731CFE43462F -:10E46000E7770BAEA3E31FFB1B81DC58A6AA1DF5C3 -:10E47000E7FC3B9E5F287E08EA159B2DA457A0DE93 -:10E48000877AA2E41F7EE40357D073AE07E631E239 -:10E490001B556A82777D14BE21F9853F01CA11C8D8 -:10E4A000379A891FDCA176BE6251227C624069786E -:10E4B00038CAE10E30FDB13D6C69A3E7CF170C24DB -:10E4C0007CE9CF0E64E073B0578A500F541D3F7E35 -:10E4D000F804889496759C3EEA6DC10797207F28C2 -:10E4E000777951AFFB386809D8609D2DC99C6FB40E -:10E4F000DC9449F2FC6326F8C85C3BF1912B2D9625 -:10E5000000D95BF332C9DEEAEA9FEB09A2FCF9C548 -:10E510003FD5CBB660FB2C07C9DD1694C7506FB949 -:10E520007738B5BF20F9D24D9C2FB5CCD23212B07E -:10E530007D565F0BCED792EA7F1AE936530D3E1116 -:10E540008FFAE4B712D8E3F83C47CB4079FB80E27E -:10E550009BB718DF1FCED71D9E97F0F40E7E3C218F -:10E56000F42775D4256E5FAF934FED4338BF1C1071 -:10E5700038FA20C22B3091E5A13EDF81F87945E4DD -:10E58000BCC02A67752991734B359D9BC4D7800DFC -:10E59000CE2F959FDF1A25F6F9A58AF353EA00BF1F -:10E5A00089FFF3F3B943E5FC9DFD1A1448284FF4A5 -:10E5B000F1EF473CAFBF15CE850462F87684D7C330 -:10E5C00077266AB88F0E0BAB698B42B7EF1608BF80 -:10E5D000134A63A087F9821EE64BBC5D69C2DB70FB -:10E5E000FFE4534E81B7F0FECF9DBEFFC279FFA27C -:10E5F0001C1A850FF7FFB73A37DA3CC7849C78C1FD -:10E60000E13F4A7CC13AD1A0AFEECF3F9D85728AEF -:10E610009DDFD71FE5EEAE54DF093CBFF8C19D7604 -:10E62000F447746474DA709F1DF33EC842BD687E7F -:10E63000DD6B445F17BBCE35CE11361C3FB934DFDE -:10E640001686F7D34AF35F41FC393823CE131745BA -:10E650000FD93B637416EABF87A68DCE427E77083A -:10E660000EF000DA11566F22F241D65E497C6CB68C -:10E6700098F35069217F2EF866E479598FFCF243B4 -:10E68000E09721D053DF07BB0CCBD3609785807F09 -:10E690009E04BB0CCBE36097E1F3A36097617964C0 -:10E6A00095979E1F2A1DD41E467DB959213B68A10E -:10E6B000D56B8FA60F2FDBA5B290E457F0FFCD8F5F -:10E6C000390DF59A877A1BEA4B5A40737044EA8BEE -:10E6D000360C32D4A5FEB8A0E172C373FFCA424320 -:10E6E000FD3F16DE4D1CDEE827FF778237FE360041 -:10E6F0001CCAF01F80FF878AA6DA508E5B1D2CE0B3 -:10E70000047E928C7406EBB7CE51B85E04BF66A04F -:10E71000BFD9F80FA02BAB8BB737CC5382C88F5023 -:10E7200017427B02E01A72027D95B92F3B89FCE803 -:10E730007AE45C2ADAF3412A6F6421A2CB4A16A656 -:10E74000FA7CD6996D87F21635B416FD76AF39FC92 -:10E75000558540C77F9FF6FB0E0589D15B3D04E9D7 -:10E760009BB952C8CE8C754EC021B97E8A5D47894F -:10E770007DC16F0EF27D78EFA073C4EDB7C3397C15 -:10E780005C1D1E85F32F73F81F4DB5D07CCB0A910D -:10E790001FD9FC437AC3F3B78A466721FF60BE3EA8 -:10E7A00006FB28D67C1B71B30087EA52809382F166 -:10E7B000370E9713E51C2E7B37C6D9D18F71629D1A -:10E7C0008DFC94ADCEEC6CC4DB138D53B311EF56BE -:10E7D0006F1C928DF83EBB69EAFBC8B727ABD3AB81 -:10E7E000F0FD63CD1CEF19BB95F4ADDBC5D91DF36E -:10E7F000306F08DACBA7257A03B01F7F202789D690 -:10E80000CB34573EF45B28F6BDB079E9741C4FEE6B -:10E810007FC18638C3F95F5B6CAC97337B04CF72E2 -:10E82000F09CED91763C7FB5A297BF07FBB9EE4F08 -:10E83000DBDE7C5937DE038589A9A8AFB0D16CF443 -:10E84000176AE4FD5870FD6C55F0CD9773237095F1 -:10E85000F8746BA1EF513C1F784C7136A0259203E0 -:10E86000B774F9B3F62421FC363A7F7DDF9508971B -:10E8700077B87FA3D55945FCE3C369004758FFDE4D -:10E8800069D76785757C41BE1F46FA067A3DFCD480 -:10E89000F5C447F695A7511CE6E0F3DCAF7C44D005 -:10E8A000FDC139D757DE0EF2F1E02E95F4BB83EDB2 -:10E8B000E75E41FFCCC136C52B406ED18F7BB07D6A -:10E8C000D0BD23A1FD539F8DDAF7EE7A8ED669DE97 -:10E8D000F7FB62FED3380FF11537CD775CF097A3C5 -:10E8E000C85F86E03AF2A83C88FC05DAE7EC06FE51 -:10E8F00082E36FE1F32FB6FA88BF30FF5CC3FEBA44 -:10E90000ECE1C754C379D73CE434F115239F59B4E3 -:10E91000A19FA1BEA06190A1EE5F69E42F65A585CE -:10E9200086F6C3368EA7070FABE4676301ED405E42 -:10E930005F1D7E9672FC5C5D1E47F472781AE733A9 -:10E94000B3E7001DA07ECF3C45684B7ED85ED6075E -:10E95000CF856DB01D433DDA0DFFA1BC36C3B19C20 -:10E96000598F8575F8BBEC79E8AF5BDF6C6CD7E14C -:10E97000B3195F3F427C7546F0F553763EDB3E901F -:10E98000B71FE81BE17BF8D3F317C9B724FE02DFFA -:10E99000AA42BE067CE533E463DF2DC87931ACE8DA -:10E9A000F8CA45F2B18DCE7F921C6C75FE93F0F8DB -:10E9B00050B9C0E3F22184C707670CC92279169CBD -:10E9C0004BF4305FD847076DBE44F48F1E5ED93BD1 -:10E9D00009DB8F369411DD497A32CF7744E09FEC22 -:10E9E00037DFDA69F3469187FE9546FC613BE71213 -:10E9F000BEDF6EC2B358E39BFBCB79E69BE2BCE67D -:10EA000079868C14FA665BE545CD8764D8F53EE9D6 -:10EA1000B50911BC54910F7C9618267B9CD349B93B -:10EA200080DB91D2D189A447CC39472513F4DCD5BA -:10EA30003EE7DC5BA391DE4A6D82DE6BE8FD32D1FE -:10EA40006E5EC769A1379C14FCE3B8A06BD9AE6EAB -:10EA50006BEC7B03E2FD4AD58BFCEAF0F442C2F397 -:10EA600033C1729AFFC81C95FC4CD3460EB801FD09 -:10EA70004C723D72BEB219E712D18FF629C00BFD60 -:10EA80006265366F9F68FA85191EB1C695F8B3772F -:10EA9000DA90C3B8CF43C847B1D56F84D3217C1F68 -:10EAA000DA676F5329CE6686D3BE6943882F1DD996 -:10EAB00029F827C015F5EF9A878CE7BAA4C569E253 -:10EAC00037BD0DEDB3CBB95E26F9B55CDFA19583FB -:10EAD000FA30D7C59FB71CE762F1E566F13E8ACDF3 -:10EAE0002F48FEA618C6030BD134DF4053FB50530A -:10EAF0007B81B17E91787C54E08F943F47E3BD9554 -:10EB0000D1E27747AE89ABD1E7256C1AC9FD369BB8 -:10EB1000468A78F725CAED7B471AF9E085DE977CAF -:10EB20006F61A1AF6524D269A88CE2D817CBE774D6 -:10EB300072FEA191B8DEB062C7F7A55E5523F4CF8F -:10EB400056E77DAF22DEFD45D8037B67C4111EFE6C -:10EB5000F529AE77FDF5E7A7499FDAB7FB8EA4B09C -:10EB60000E6F9609BC39DD3E2409F1F0585B7D92A9 -:10EB70009EBE65FB19783E7664445EC75AF7979649 -:10EB8000D7CF0A7B602797D737599BA3DA03FF6A51 -:10EB9000393D595D497A88595E9FF67892DC041FA9 -:10EBA000417742AEC8B8CF5F6D9E24F4171E0B723A -:10EBB000B922F9FA41131C4E201CE222F224161C41 -:10EBC0008F8BF7651DEC511BCE5FE6F0BE928AFE7F -:10EBD000970D8A17E35E989E520CE77C604EFE8F7D -:10EBE000D16F25FBCF2F52492EC8793EDAACB4A1A4 -:10EBF000DFEFB595FBB2BF07FDAB773989AFCAFE32 -:10EC00008BA61BED2CB33CFAA8F193B746C3BC65A9 -:10EC1000CDAAD701EF954D2FE9C3F56AB7118F043F -:10EC20005D9ADF5F6AAD8D7A9E66BE57367D35E9A7 -:10EC3000EB87C47A0FED1D63F324767FAFCCCAE176 -:10EC4000B014F4CDD530EFD2864F48FE2C9DAE7A6D -:10EC5000512D79ADA97E26E2FF519FCD82F471A49A -:10EC6000ADF74C8453608EEACD85FEFB9B06111DEB -:10EC70001C6BBABA2FCED74BC0EB747B9C05FD4FF3 -:10EC8000A77D3616227B3944E7F9514319D9C7A726 -:10EC9000114E78FE5637D149BF22EEC73A0AE370CB -:10ECA000FBD9C3F4F1C02341B53418852FF513F314 -:10ECB0001D3FFF43C2AB5783FB08EF8EB6F1798E41 -:10ECC000AF7427619CEBB70D85248F8F4D87F1A121 -:10ECD000DCBB7BE97D98AF777A834AF2E374FBF57E -:10ECE00033B17E688394BB5C1E558BF957EF1E3D94 -:10ECF000A318DA3FFAB98C6B72BA5E20DAAF9E7550 -:10ED0000F8BE62BD3CDB35D7B0FEC3C1E3646F9D86 -:10ED10006E80B7018ED53306D9D11E5EB4CB786E26 -:10ED2000E51B8C74083F577EDF489ECBA206D06758 -:10ED300081651D9D5E4676F4EC406F93BD6DB4E336 -:10ED4000CADBB8BDB7E0E1B2A210D269E0131B9EE6 -:10ED50005375739C619ED92B8D76DA02935D66B6EE -:10ED6000DBCCF245C263B9ACB755D23ACC7A4B375B -:10ED70007963ABAD8A961F5155C4F5B16AA0CB74C7 -:10ED8000F42B33EF0CB4BB8E017CD7C378D576F768 -:10ED9000DF73414F3EA2B2F1E44CF30658B1F41BCD -:10EDA000E8E65BD0A09AFC1346F882BE7E0AF5F92D -:10EDB000A6DE420E0740AE24A29CD1FC4528272E99 -:10EDC000D61F70D1FA7695D0B7AB0CFAF641ECA20B -:10EDD0007B7F6FF9F5E4773A3CE37AD2BF0F77F99E -:10EDE0009D7C06BF9384EFE1E965067D52F7BC1771 -:10EDF000EB813FC6D21F8F0AFE7A44F89DD60A39AE -:10EE0000D320E4CCE1E9C22E4C65442F56ABC62E8C -:10EE1000862F5D481F5BD0D0CF745E4639E32CF15E -:10EE2000B716015EC4A50F353CB7B90B8C7463C22D -:10EE3000CF7E8CFBC1EF46DB1EE05E5FCEF347F179 -:10EE400039E6B148BC64D01FE573F986A1C1F5BCB1 -:10EE50003DA01660DA1B43158DFA5B795D53783D52 -:10EE6000E012EDAAC85FB341FD688E772EEA519893 -:10EE70009FE34CE1ED8822FD009F935222F88FFE24 -:10EE8000F9781E220F24C17BFDE7E4BC8CF48D7958 -:10EE90003B9741FD5745398437E9E89A2FA0F14364 -:10EEA000989F13AE9F40745CE648E2717690B33D44 -:10EEB000E3DF6A6EDF94F6A6C9FA5BF97A62E2B321 -:10EEC000E877097AD56B442FCC42FE938DCE11366C -:10EED000C4DFD92E5F16C201F0BDF276B4D35FB4A1 -:10EEE00093BCDC5BCEFDAA07A78D7EF836783EE2A8 -:10EEF000191791F1C1C580E724173A13F5787B649F -:10EF0000E5710BE6D3FCA19D79311FF1C8AE8A579C -:10EF1000DE8471F6AD5C786F11D2D17ECEC7CDFEA6 -:10EF2000D89267C6913CBB6E864A79DA874A55C645 -:10EF3000F97C82C1AE88F86955C28F4FF758A91D78 -:10EF4000F3AAF2308F0AFD95986F552ACE45E81541 -:10EF50006DE21C9F10FEDA1D826E5A04DD6C127485 -:10EF6000B3CEECAF7D88D3CDA1763004404EFE6E9B -:10EF7000FAC289E487DEC2289E9C334D5D3F12F6BB -:10EF800077799CD786F02B999ECFE13947B1601CE9 -:10EF9000A6AC34DF86F47E796F8FCD477AD62CAA63 -:10EFA0004F9A934376FBDE95658964BF277AB390C9 -:10EFB0002E074F8F0B5992D00E2C243E71E5198BE2 -:10EFC000815EF2430906BA1BFA588AA17DC8964CA5 -:10EFD00043BD8F6FA0A17FEF52233D260C2E30C979 -:10EFE00025AEE749384F56C791DFEA48445E52BB29 -:10EFF000B4EFA4FF4DF6076819F85A93D0074740BD -:10F000001DF3E2D6CDA97760FEC3A76D562F1FBFB3 -:10F0100082E4BD23E77907D2098648314FAA49CA5D -:10F020001FE18F671A33AD6B03C378E9915246F83D -:10F03000143F9829182F6811E77DBF9817F86A893F -:10F040008DFC6EFC1C7B4FF7513FE633DAA9E94893 -:10F0500067058827FCFD27C4FB3B04BE1C29FDF186 -:10F060009A04C487B98CFCF793D5656B302E78640D -:10F070003A233A690BBD9480EBC77130CFEF57B19B -:10F08000C699F3DC1F6FC1F5ECB4D338658F815C92 -:10F09000043C197AEDD10FDE46F06D71EF8B67DD20 -:10F0A000F5E9118F695E044EDE1916B25119D2903E -:10F0B000FFE49D39A0615C6FE85F777EF034C3792F -:10F0C000B95C6812F86DE6AF3F7DFC170BD663B9EB -:10F0D000636BC17B507E63CD839975503EB1E65B17 -:10F0E0005B6FF344FC9F3B662EDDDE02F521DFFC07 -:10F0F000FE93CF235ECDFCFEFF791ED73BF31F7F2F -:10F1000076C1FA2FAB4F6448DF727DE679D259930E -:10F1100082F14DE4A3C497AD01AA57078C7A7759C1 -:10F12000A9D3807FD8DF0AF02BABFB29C589D3C5D3 -:10F13000FB8766DCADA830EF7BD59CAF1C5CD5D9D6 -:10F1400032C946FD43D81FF824E55DF6EB0F6C0588 -:10F15000DFB707148C6F8382E4C5B86D06B4233F14 -:10F16000671E0FE93BD9127F055FC1EB0A8CFC7B60 -:10F1700056C2B33C115744FE8BFCBE6ED440E2CB6A -:10F18000FD5C4CC3F32D7D618382F966EFFA3D5E31 -:10F19000D20B56B1CD93C0EE1DAAF2FC89BCD2773A -:10F1A0006FC07381AD5AFD059171778ABCA6D217E5 -:10F1B0005C947FFDEE4ED736F2EB1F9869D1EB835E -:10F1C000137FFAD1CF7E8BF8551D4FF865D65B0EB5 -:10F1D0000AFAE8AADB3C0FDF86FAFE8B0E6E27697F -:10F1E0009E2CB2BBBD9E2CCCC3E9EAF77D191FF360 -:10F1F000FE19F9F9EC0A27C50D649C482DFDA411F0 -:10F20000E9717E716D11EAE399780EBD23F1E8F79B -:10F210006EB253DE404049A0FCF25871E79DA372E4 -:10F2200044FCA5F60A5A07AB1D8DE5B9B9F50FDB0D -:10F230003DB1E5558338D758ED363BF3478B0FEF9B -:10F240001CC5F5D07A3C079BEE1C5C7FB801E3BC83 -:10F25000B1CE81598305942FE9700CC67C8E34F1B0 -:10F26000B8D5F983B7505E751CE6F22AADEEB355FA -:10F27000487FD20F5195CEBAE2601ABC6713EFA552 -:10F2800009FD1B6918F5EF2A11FFE9A86414FF496D -:10F29000AB3BFDDF089F8D62FCAA77F8F8766B68C0 -:10F2A0002FE24B95CB4372A7A34F9217EF27B1F3F1 -:10F2B0003CCF2493717C4C33EBF7A809E9D69D969B -:10F2C00050F13B541FE68E672127E28FE2A079338D -:10F2D00057C6517EAAD4AFD2EAEEBE551D61184F73 -:10F2E00041BDFADD0A6E3FA399DB356E8E41AF2238 -:10F2F0003DCBBC0EF95E878DB5A33DA9D3B3480FB6 -:10F3000063FA790619EAC22F66ACDBD2ED063EF14C -:10F31000EEF9B25EB55C0E785247717F1CC243EACB -:10F3200063526FEB36AEA0779D7E19407E21F321AC -:10F33000BAF4A41A9D1D35B0FB7B32EF4C9E83843A -:10F3400067ACF79D25DAB951941711A271FC6218C8 -:10F350008BD3954DF035F14B605B3C2F5EE8A1A05F -:10F36000451AF211A45E29F97387E0BBE19C30F9DC -:10F370000165BE777F78271BDE8F1F9DDC952F8F61 -:10F380007AD091551F533CBD0AF550983FBCE643D7 -:10F39000C37D92A69292F8D1E46F33E63DE8E2A8ED -:10F3A000B45EBFE09B935517E59F74B0042FF2AF96 -:10F3B0008E80D0C7FEE4247D4CF20B337F98E1357C -:10F3C000F2FF6B8B8DFC7F96D6DB144732FAB3CA03 -:10F3D0007DA6F8F63BD30C7C53F29F3B542F6DC2B5 -:10F3E0000A821EE334FB05BF7C5BE88176564BCF77 -:10F3F0001D98F73908F97F1B952E7680CA24D649C7 -:10F40000A59BB9294F268579A94C653E2AFBB25A9E -:10F410002AD319CF8BCA646D54F66707A8CC669DB2 -:10F42000547A98DB82E540E6A57230F351E9636EC9 -:10F430008A7BBF9318CE3A04F09B7E3D233F3C630A -:10F440003FB9518373EA2897754020A4ABC94C207B -:10F45000DFE3376A589F26EB3B78BD84F72FFDE545 -:10F460004F7F141846FC46B43FC1DBBBEA3B6F2C10 -:10F47000213AB5507D0EF687FA8323B569A3015F63 -:10F480002B4733E2A3E70BB56FEAEB0F156A33F4B2 -:10F49000F5978BB46BF5F58F0AB459883FB29E5936 -:10F4A000A895E9EB371769E5BC3FF71FBD63D34863 -:10F4B000DFC50529A338BEE1CFA9FA2B090F7729AB -:10F4C000563CD738416F763C4715E9C8EB88C3D224 -:10F4D000C7F377C2F1AEB0D3D283FD63A2A330F2FB -:10F4E00027C0C3E18AFF665C8F999F280191079826 -:10F4F0006A8C8300BE93FF2CBC92DBE98C456F972E -:10F50000F35E08CF99A6F3DB0E8C8C1B6B1F66FC99 -:10F510003D20F4BC8342CF7B47F899BBF61DB6264D -:10F520009F7244E838B67D6865A7F4FCB2DBBE3F45 -:10F53000AAB4015D87EBE2DC28EF3AE2D9DB68A7E9 -:10F54000050EAB0CF58C4B5D6F69E1940708EEACD2 -:10F55000BF9BE20A725EC1673AF09FA0E75CDE4B98 -:10F56000DA975E078737B73B92C5BAEA27A55C935F -:10F5700047F137AED70FB31D983515D699B681FB35 -:10F58000479390BE3114F6CC9FDC18176B9E6C61CC -:10F59000C8A71A05FF34FBDF364E5AE1D6FBA71B7E -:10F5A00093820AC6233343F1DC0F91CA82F12847C4 -:10F5B0004BBDA594071350DDA558AF6033F3A0BE33 -:10F5C000A045F594C2BCFB5A9E5B817ED84515765A -:10F5D0008A4BD8B42914BF96F9182902CF1BD6C577 -:10F5E000794308C73E2EF2CF0E6B2C28457BB7DE41 -:10F5F000959282B89852B184FC87F52EEFEB784F44 -:10F6000023E0B6509E21736B8E32D057B6DD662D47 -:10F61000453E9EF5ECC82455B7EEE30D67E331CFC8 -:10F62000FD51B785DA1F5D39D1B1C485F711C15ECF -:10F6300080729FFB9886FAFB56E89306E3DD5773CA -:10F64000ACF9B21ECE31A9D46EC05BA7D7588F33A8 -:10F65000F91F6D26BDE0F06891F7318A8DC273BE47 -:10F66000E2C9F364FFCE7779C83F3EB149A17C97E8 -:10F67000F05E6F36EA9BC7EF1D42FEF0862655F816 -:10F68000A3BDE48F0E67B16CBCB753DDAC90BEAACE -:10F69000367CB21ADF1B90E7C9C07106783B33DCB9 -:10F6A0003AFA7BF4FBDF8D4779D78017CF088F18A4 -:10F6B0008D23ED55793FBCDA7DB692FCBBCDBFF70B -:10F6C00021FC93350BD1CC115B301DCF7F7DC96CF4 -:10F6D000A24BBC6F857A4C377DF47358A7EE9E41E0 -:10F6E00063EAC0049C3782BF1AF9CD4F3417927E6B -:10F6F000B4BD6922E5F59BC7B967156B43BDB5710C -:10F7000095A32D9AFE7B4FB62F1BEF619FDC58B25D -:10F7100096C1F99FDC7B533ADE5B5FDC1CC7E23DA0 -:10F72000DDFB9FD8389AE65B8CF7A171DEE659764F -:10F73000942B535B4AEC08B77B56CD7D563FCFC721 -:10F74000257E6731D09FB3F959C213170B0510AE50 -:10F75000BFB94ACB46FDE2442E8B9A97D9A798C7EA -:10F76000177F7B958FEE999CCC8ADE2FA398C71FBD -:10F77000EF2BF6487FF1DB4B53C91E7423BD1E6F80 -:10F780002A4C42BCB5611C1DE4A2ADFDFC2AC4FF9D -:10F7900073150BDF5B0AED8DD3AE3B83E515F65A8F -:10F7A000D29BD91F54A207D00BE9BED7DFE638DCC5 -:10F7B000F5BABC40D41F35835FC3C7D0FEB035A9AE -:10F7C000213BF077DB9E53A48723BE6A3AFCA5DF7A -:10F7D00028A1CF8B7C8FF451747F8E7E8DD75C17E0 -:10F7E0000C318CA32C74443BC7D8F3EBC645FD7693 -:10F7F00012D3E275F383540C915FDBCFE7EBEA277A -:10F80000DAC10CD5687D422F37B7CBF50FD962A48A -:10F81000CF6FE2F91445F4F358EBFD46D0F85E4D96 -:10F8200031137916330DF432546D5B3106CE8DBD34 -:10F83000CBF93FD875CC17255E15E1B3B0F6BE0203 -:10F840007E00CFB5A9B3C93E89B50E7BF080963353 -:10F850002262BF7D23DDB82ED9AF46E05D5C908586 -:10F860006C495886E85E461CBC8FF2FBD38AEFB821 -:10F87000AF894217B234F32DFC79F0BB11F2AC4CD6 -:10F880007C02D160B0D4472CFC7D4DC7E7123773A2 -:10F89000FDF7C41685F4DFF51B795EC4A741A89374 -:10F8A00072C1CF09558B2F84B2E3D2DD1F5CF242C7 -:10F8B000D37D433D06B82D62BA78D29927EF7A1BE3 -:10F8C000DB4F3F7D970F977B77EAA224CEB78E2E32 -:10F8D000C0794E5E6E277F0CFE1C123FA0E3D26003 -:10F8E0009C010FD7EF7E72CB02943BBB1D5E4CAFE9 -:10F8F0005BBCC5D81E97AEDB17E3F81530C0293CBA -:10F900007016D0D191EFFF84EE792720FF447A5C06 -:10F910001947F7BBCC70FE6074D7F742983E0EC70C -:10F92000C4BD0E4957C736D49F54619CB52BED1EFC -:10F93000FA2E82C9FE3AE299A5A5EBE2BDF695FC46 -:10F94000BE25D3DB890323FB97E31E092C74785C67 -:10F95000DDC7EB867731C65B58A2ED2A06845D567B -:10F96000E27B1ACBE31B16D2BEEBDA571E7913FAF1 -:10F970003425F87F867CF3D88641A314BCF762F562 -:10F98000D0FDBF86064B3CF2FDE6366BFC6084770B -:10F990008385E47C735B6AC260944B2E0BC549512E -:10F9A000AEA83AFFFE49C12723F2C397A4D77F121E -:10F9B000043E9ECC13FACF24AEFF28CFEC21BDA38A -:10F9C000A191C7A9A4BEE116F8E316F1C858FA0F31 -:10F9D000321E5C7762D12237F2B5C624FE1D8D45FA -:10F9E00093BC01BC9779B58B91DC1880972350CFDD -:10F9F00072B1E05498477573FDC6DFCC489F4971DA -:10FA0000B9BC08EAB4966080D6AD713A73C07F087D -:10FA1000CF843C8DE1F856935E6137E90DAAA9DEEB -:10FA2000512CF250841EC184FE2DBFDB90786FCF25 -:10FA3000793DD2AFDB2CFC13A03F05E8FE47310B2C -:10FA400022DE324DF3A4F68DD801E877C4F6F462D5 -:10FA5000B6AD5E177F52B457C96F20FD92D2FF201A -:10FA6000FD1C238AC15E4BD2F9237E0DA6A54AF167 -:10FA7000B0CF104F72801D903D398C29FC9AC597EC -:10FA8000D4D3EB2E2EEEF3A397F83D9F064B82774F -:10FA90007B4EF77E19E3B8DF2C611FEC0DF5DAEB36 -:10FAA0001D749F66B2BA8BEECFB78EB4F03C65760C -:10FAB000C08DFA40F218CE776F2FF1B9C7202377A7 -:10FAC000F972106F001E011BDEC3137EDBACDB0777 -:10FAD00026A03EFC5EC6A98DA897071A2DC46F24E8 -:10FAE0001C73565B36211AEAE273216B4124CEB6B1 -:10FAF000DE773680F77ECF5FC9EF1125CC3AB1179C -:10FB0000FDA0EB065BC8CF7E77A246713BA01F87A6 -:10FB1000CAE375AF63BCADC9939282DFCF793A99DE -:10FB2000B733718E0F24F6DDA6CF17E9BC92EFFB39 -:10FB30000125BABEB2F74ABECF8EDD00C85EE4D75B -:10FB4000E2F678607F85E6D2D591F6E0FD1F06B833 -:10FB50003D3D6AF7FE8AC060B29344FBF90AB2E702 -:10FB6000D1C708ED1B776FAE40FBFC919CE8F3DE3C -:10FB70003E8ECBEB47DEF00F407D36BC1BF0A75727 -:10FB8000B4F30D314B318D9B8D71A9F09D7173A331 -:10FB90007D8FE6CD719C9FB4425B5CAF881EDB5AC3 -:10FBA00061D65383C4AFCED51C7B85D2AE817F1482 -:10FBB000013D24B3E8FCF2C2FAAA371DF5CEFA3BA8 -:10FBC00095B5C83FEA415FC5B8609ADB4EFA6A4313 -:10FBD000F2774BF05CCED53037DE5BDD0E6A1FF27C -:10FBE0002FF4ABE27DD4A9759CCFF8DDDCCF0A768B -:10FBF0009CEF6AC4C70C2BE1A3D45FAD159CFF5CDE -:10FC00001EC7F38B3B925DE4374DAEE3F9C4CE00E3 -:10FC1000E8B3B8BF493C1F5883FF900F49FDD63564 -:10FC2000CC6AC80BB69BF286ADA63CE16F8F31DA89 -:10FC3000338945237BD4AB7E0DF62FAE730FF01FB7 -:10FC40002C43600763F912D8ED58BE0C763BC60D05 -:10FC50005E5D9547E5EBABBCF4FCCD55C5544EC895 -:10FC60000E535C91FCC8E4BF612185FC7812BF5E35 -:10FC7000EE3F11F1BD84B76FFFD5CC4703FDA13D29 -:10FC800055F40FE45422FE75D5D9B595D8BF2A9DF9 -:10FC9000D79D636754223E4E9AACAD1B0378D2C702 -:10FCA000E2AB6EC4BE77C579A3D9F77DC7CAFB5E48 -:10FCB000D1ED77869F3A30FA735A894FC4F0E73C0A -:10FCC000A0F075EC7D61F343E887EA35CBEA433C6D -:10FCD000CE1E68F4F37F3E86D3C5D4B19C2EB3DF2D -:10FCE00004FAE801EE923E62B5D7EF061488425757 -:10FCF000B26C4D64E3E99E75A57D6EB47CA66D8201 -:10FD00006FC61CDFC53C715744E8ADDE65A6B73051 -:10FD1000C577CFD57D672FCACBAF4E6F8CECC37044 -:10FD2000A546F23A0CF486FC5CADE1F4A65AF93D26 -:10FD3000CBAAFDDC3FB21DE90BCED98FF406FF9CA8 -:10FD40001AE0F53413BDD59BE9CD65A4B730D21BBD -:10FD50008C971CE0FA85B3A2ED6BA5B73F7F457A7F -:10FD6000FBCD5561CA6BE8C8A9CD40F8B48AEFDA7B -:10FD70005D2A1DDE35D6CEE5C1708DFC020D388EB4 -:10FD80008BF4F90DF8BD94A9FD575B53007ED35356 -:10FD9000F3E97B023963FB0A7A38E0427FCD024DFA -:10FDA000FB94E8EBBA33744FB18F85D36FDFB1AFFB -:10FDB000913CC86A3C386B2AD2DD9D2AC949F3BE02 -:10FDC0006E1A2FE25B0A9F174E2E431FD77308BA95 -:10FDD000F4DC59AF38501FAF66DEDC1CFA3E0C7DF8 -:10FDE000B7E6870D7F73E3B8378D4FA1757956BF9E -:10FDF00093ECE7FEB574B4DFE86A7241777A845F0A -:10FE00009BADAF819E93C7F6E09FBD10FFB84FE852 -:10FE10000F78F4A837F8C53D4C19178949CF263F0C -:10FE20006E4CFFE1700E1FF3FB67855CAD17FE5F44 -:10FE3000B3BE27F73FA4C43F0CF7A7B85EE57EE04A -:10FE40003DCC83EB9471B3AE3C23A91F0658B01E82 -:10FE5000F56D2BA8327DB9BA81E375E51F093DF137 -:10FE6000C512FF681C771BF3EC45F9E6F2F27C053E -:10FE70006789564CF0FC927AE086124D1BDB035EDC -:10FE8000BD38459B34B628763B3B0FA38C8AC4B55E -:10FE90004A6659395FA853041F70ADB543BD351983 -:10FEA000F89907F576BE6F37F00D0FD919463B620A -:10FEB0000A3A23916F201F21E06AD3312F32498CF7 -:10FEC0001F91D7E157502F0D036C3741535280CB10 -:10FED000EBFAFD9CAFD881AF505CBA98DB09F29E7B -:10FEE0008F739897EC2F55EBD97EB09AECFB256376 -:10FEF000051F296023116ED916CFFD63E079E183D8 -:10FF0000930F8D81C7450F2FEE8DE274F4B6C63284 -:10FF1000FC6ED74D8F9FDC867ED231FF15C7C4F7AC -:10FF2000D128CFE05F2867E85CB6ED79B72260455D -:10FF30007E151D8F0BAFE2782CE3AC3DE07123E121 -:10FF4000B188735E021EBB2E80C7CD884F51F078FA -:10FF5000E357C4E307715C0D0F01E34653B41FF58B -:10FF600084B75B276B8FF6D4AE8B1FF0FC21564312 -:10FF7000F6B38C5F9AD7D388F235B707BFD4BAED02 -:10FF8000F168CFD6D76C7F03BFDF585FC7EDEC8E2B -:10FF900044AF03F38D03BF57E9BB54B1DE47BB3B0E -:10FFA00000CC72E8553C0F7ADF9D71A109304EA656 -:10FFB0008BCBDB4C97C630EFDBEA0EDBFC89A8AFBE -:10FFC000F918DA19F6540B0BE8FC3157D80E905C8F -:10FFD000EE00398EF401F4C9E92D998F23E5F384FD -:10FFE0003BEFC7480EBBAA13E4A08E4EDED85D4C93 -:10FFF0007EB8C4A2E757E07B6AA5DD83F83DE173D4 -:020000023000CC -:10000000909BBA794A4013D1D7AF766418C699EC61 -:10001000CE31B44F4DFF86A1FD1AC0173BC5B1F9D3 -:100020003D3FA9D74CF3E41BFA258B38C737F3C6FD -:1000300018C6B3AAE7378D46FA177AC438F80FE91D -:100040005F35E90B667DC2AC3F9C1C6BBCBF32C206 -:100050002AF2D0AC3C3FA29539E8FB12C007E9FB7D -:100060000555913C01A29311F6F0F67BD0AF32CF4B -:10007000E10DC0B386DDD7A4578F8CF8CF5AEBB80B -:10008000DFAFBEDDB10DE961ABA04B495FC3128F9D -:10009000CD6324D7ED0CE5B1995E65BE93F41748A6 -:1000A0007F8252C3FD0CADE37378DE91E03FAD1566 -:1000B000DCFEFD91128A570671BAF4A444BE339750 -:1000C000CE94C0344EDF5A8A2855918F2AF35E7140 -:1000D0001CB4B3D3F97CEC759E37B9FA7BF8BE9BA0 -:1000E00005FA0B7F46564AC44F81F909CBF87B814C -:1000F00069E2BD0122DFB2175F7F68B2986F049496 -:100100006AAD26FCD37E2AE3301E0EE540C59B80F7 -:10011000FE8F41AA8F022D4922BE9E29E2E94E257B -:10012000C499C797E42357001BC5BC0496C2BF13EC -:1001300032F1A72EA6127DD8B7A33CBAFBA8F77759 -:1001400098AADB90F8DDB726C0F3A6DFAB5EF49388 -:10015000DE9D15780FE9DA0AC81020BF96AF1ACFD6 -:100160004D9DE3704F85F7D4C0B6D518DFBDC21ED4 -:10017000DC4BE7B9268EE83D0CEF213E6C4D043A8E -:10018000457C454FD7A8483E908C6384C7781D288E -:1001900047C3D88FFB9B0DFECF28F926E42FB58AE5 -:1001A0007A836B3BE9EF6B53EDF8E54CCCEFC9AECE -:1001B00043BCEC93C0EFD3321E371880FF18A4E382 -:1001C0005BEEE87E4DD0D7080EE1D54BD37BD2BB9A -:1001D00062C6515C96903DE9E2E3288D375F170CCB -:1001E000E9D629F7BDD6B55D59C02E657E668CA3CC -:1001F000D4302D7E4494384A38A8E03A07D4F038F9 -:10020000CB00E1AFFFB2711475FC978BA3C8FDCE94 -:1002100010FF9E0E882DEE0D533C81CECB12599FC0 -:100220000E7E8F113F22DC102802F56B45FDAD5D7F -:10023000073F7A12FEB97FE74BBBB0947ADC2CD132 -:100240003E73C8677B30776BD6BA15228E658C3FBC -:10025000CC00AB4EEFE7C7FBFFFAFA2CD37A265A55 -:100260008D7182492E63FF29A9C6F6D2FE71DDCEBB -:100270000DFDF2B45FA5FB7EEF76DEC7F877A374C1 -:10028000E7A05EB8EEC0BC398CFB78BAE3893E0EBD -:10029000E07BD1CA524622BE58482FDD1A58BAB95F -:1002A0001CE8672DC851CE8B3D06FA8BC43D4A35FC -:1002B000C427E9EF8F454FC75C03C9FF3FA06E6FAE -:1002C000DBA4DEAC2B0ED094E0FFC5958037035C39 -:1002D0006715D44306D4BD4CEDD7CD2BEA118F72F0 -:1002E000EBF6B54DD27D0F30D7EAB3A0FD9C5BF79E -:1002F0002A3D8FA9CF77E72394B7962BF042E605E6 -:100300006EC5BC40807B6E8DF8CE6F4BCFF96F52BF -:100310001E36E8F2FB2899C1A330FDF852EE75F3C2 -:10032000A733EEF795F375E5059AE6ED927F6E2E0D -:10033000FF9C25FE0E845FD7BD0C718F03F61D3523 -:100340000FF4E49522DE143B8F8DDB9D735E7F0FEF -:10035000C7BF64BB33C6B813B2C395D1EE47FD4DDA -:10036000F8AD3AE2C359E837E8B045D7EB3F9E34E1 -:10037000E51F57F660C761DE2CC232D63ABF6CDE8D -:100380006CF6180E2F196F95F9B3322FF642F9B3A8 -:100390005FD50F3F44F8033AAF64DCCF6F8A4398D0 -:1003A000D79B33AE2BFEE019D743FC41F67F2FC31A -:1003B0001ED52F5E3F5EE049F7FB47941F0AEB4DC9 -:1003C000D5DB41F23D99976F1E0FECA2C2713A7FC7 -:1003D000A07F752EF9FB74F696CC8725FA68157EFA -:1003E000882E3A30EB85221E62D60B657C44A9E04C -:1003F000FE09A08F89E3FA70BD0BF3D2A59D27F308 -:100400004965DE28E685523CEA4BEA555FBB3DB5BF -:100410007A32E575D5BB27BEFE55ECA9E5E38DF62E -:1004200094DFC5FD0E7EB4A78677B7A79A4AFC373E -:10043000E13999EDAA233FF890F263C10EBD99F01E -:10044000EAABF209937FCA3186E3B794D3D29FB661 -:1004500077B0C5E0779DA2AEDC4BF9E235DCDF92E8 -:10046000A9B5919D6677D93DE86FB14EE274641BE2 -:10047000C6821A8FF3927F45E695A5B8B83D65F61A -:10048000CB483B312CEDC400FFAE4AC77E1EB7758A -:10049000A2BF053B9672B926FD2DB654E16F31E53A -:1004A000633B4DFE15B3BFA5659CB0BB84BFE51192 -:1004B000C5730F92FA735B26FF1641F1F387163B63 -:1004C000D1D4FF65B0F19BC2DFF2A00BD6B7FB3DE4 -:1004D000A3BFC51CFF8A12F722E7D59BE3B653DC06 -:1004E0004DC257D2ADF46765D6F1EF024C51772972 -:1004F000C85F5A5D1CBE2AFAB35223FE2CE5998FC1 -:10050000BAFC52981FD73D4E5EFB06AED30A0C676D -:100510007D34FF9680AB391E9554C7FDE35F973F4E -:100520002B34CEE8CF2A78B0F07EFC3EF1C887CBE2 -:100530000E61396ADB777ADF0065F1E3F79761F9DD -:10054000F737C239A8779AFD58CFE0C78CFB74877C -:10055000AF198E124FFD35124F5D76A2DB0A0E47A2 -:10056000339CD2348EA7B980A7A02274E15F4732B2 -:10057000A7CFCC49DED7D1BF3660989545C3636B12 -:100580001DBF0F2DE1B855C031A56609F909CD7819 -:100590003AA0E5D2F0F38C097E3FDB52780FC2ED32 -:1005A000F987CA7E8BE52F82DF7122DCDA1FBBFF61 -:1005B0009B027E19F45D5C13FC26C580DF042FB717 -:1005C000AF274FF4FF1DF9F335C021D01FB2BDA9ED -:1005D000C0618C0319F969DAD7E49F0A77F153F601 -:1005E00076EE25F0D32D26FF545A80D34D5AE028BD -:1005F000D16726D0673CFAAB6AB81E09623FE8545F -:10060000D0E6E6FC55CA35643916103E5BDD3CEE9B -:100610001CC54F19A2EFF69AF8303A70F4780772B9 -:1006200035FBAA3E1179B7B586C7D15E9BE4F3E0EE -:1006300073195773966839577D35FFE337AED2F992 -:100640001F014F69FF2AE03B7EA7FC6A902768FFE5 -:100650005B6BC236942B5575B72A7E285F1CCBCFB7 -:100660003F2DDDCF30CEDADD5F174E44BD7DC2E0D9 -:100670002E7C28BE4A870F57DC79EE7EF473C5C204 -:1006800087CC18F94A17C6878906F9DADA850FB5D3 -:10069000EB2E4BBD787C68477CE8A3C30741FF691C -:1006A00035E107917EAD021FAC6EE063000F15F1DE -:1006B000605824EE29E9212CF20FCCF0090706C579 -:1006C000C84358A114F7B0BE8BCE3F10F1D07A11B9 -:1006D0000FF5D7F17CD98E3BE3A618F30FBCB4EE2F -:1006E000A9AE5A459FC71F254FB616CF4FC63965CD -:1006F0005C73F244DF0AC49F0979FC9CC3B1E34CEC -:1007000021BCDF0AE8E736E1F9F708CFE5FD03A1F0 -:10071000C7BD36495B89E38EB00729CF19F4BDD533 -:1007200058DFBAFB49FEDD5CE1879479795FD96FC8 -:1007300096640FE27D49E9376B4DB46FC7F3AE663F -:10074000E1C9F4BD5E8C53A0DFE9DE38CA6B5CA85A -:1007500080E10DEF7F7BA27F33D11FF3513EAE7F4F -:100760008EC38D7A7E43F29474E41B556B5592EBE5 -:10077000B1EC1B496F55C06F88DEEA38BF4903FCF6 -:10078000227C0B28C46F3281DF70FEA331D4EBAC26 -:100790004877AEEEFCA6B507F85F24DF790AE11CC6 -:1007A00085EF3C83CF757CA70DEB5F16EE7957196B -:1007B000F90DC60368FF485FFAFD9BF5D9AE7D1BB6 -:1007C000E94BD2DD7F009DFD19E11A85CE8E209E7A -:1007D0007D053A3B1383CEDE37D1D95FFF4DE9CC9F -:1007E00032BEE8C274B659E095CCDF967AC550B5F2 -:1007F000ED6C2ECEFFBF9CBFFD1D915F77A1FC6D00 -:10080000FC5D8CFFD49CCFFDFFFDA9FFB1FE54FF22 -:10081000F83E5FDD9FFAEB2B3DA4E79AFDAA0F8E11 -:10082000D66E1EDF831F4EF269ABE4D3C08F91F703 -:1008300056013F43FE9C56D1F9975F727BD3EBF490 -:1008400090BFE10E1C2F53F06B335F06BDB36EFCFF -:10085000D7E1978CE16FF857F90D8788BCD20BDD93 -:10086000B71F32CE23FCAED1EFDDD70BFBBE1EC6C9 -:10087000C07B7A5BEFB4071B60C1FF1CCBCF674422 -:10088000CD75D72091FDEE267B42B807BB49FE3DD2 -:1008900088E655FE174EE4EAF7C7A2CAADAEFD9949 -:1008A000F464BDDDE4B904BBE9FF8E37EAC9D61AAA -:1008B0006EE75A41DE515C5F2B0E21BFCE0C286DD6 -:1008C000981AEC4FAD55500EA6D5F8281FFE52E3EE -:1008D000FA663C8A15E7FFBAE3FAE6BC817F9738EF -:1008E000FFB1F1D1E3FCD2FF6A8ECB8FB037979284 -:1008F0007CADB4E05FB2600DBB3FD87E0F9EF73C8D -:1009000007DDD330E703C48ADB8F48B1879D0363DB -:10091000C7EFA5BFE0115BED1B68873FB2DA42E786 -:100920006BCE1B1896C8F3C75BC7AF7A98F27FA44B -:100930003E5C21F84C9D6247FCF7570489CFF8B51F -:100940009DAB319E9CE6626DA867B58FE7F4A2A6C9 -:100950006BC467AC157EC22B199FA8CAE6F7E6E206 -:10096000057EA9836BDFC2F1930FA85E8C6FDF8BCE -:100970005D816724A2AC443D628C85F2225A945A70 -:10098000F27B342B1EFA3B1EC9C3DCA41F3D9DEC39 -:10099000FDC35CCA0FE57F6F64DFB4EFA6E3FAEE38 -:1009A0005EBD3A1DF5C08C093C1F71D3B453950848 -:1009B000675B1EE87F0A9586BF4B2BCB8F26F038EE -:1009C00009F005CA4784756FA1F8FB603BF9D9545B -:1009D000ED81EF201F502F9B4278DDACB8E72DC092 -:1009E000F3CAB5931ED3903B6AEE22D8D7BA3EFE27 -:1009F000A61C3CD7E4C1B4CF86E4BE49A88FAECBD9 -:100A00001A48FA6793524BED812C0BBDA78AF8FC6C -:100A1000BADCEFBEBE18FD59D9FCFE674BEEA9D774 -:100A2000B15FCB18FEC76CCCEB55DDC67B52F8E14D -:100A300023E4DF6A7F0BDD2F54455C5C35C59537B9 -:100A4000C87D8AFB2BF1826F55E5AE994BDF4F488D -:100A5000B5BB11C91A13C3E5586FBCD3C6304EC716 -:100A6000ACCD063DAD7E95310E617519D7D3D475E9 -:100A70003FE1D5F9C8671A15510FFC82D7B19D9295 -:100A8000FEDAE623BE34C6F3FA35BF79723EC511ED -:100A9000C5FA6C727D7DF8DF5BF97430A3FB6D5590 -:100AA000B670D4EF0B5F685DDDC7DDA48971D9FF37 -:100AB000E6B84DB93C4E641E57F6339F9B6E1EA69A -:100AC0005CD23CA7CA09FF0EAB0CF98C793EF3FB54 -:100AD000F2BDAA3EB349DEFDABFAC782EBF2095D77 -:100AE0007FDF8575C52DC43D3B8F2E3E563F651477 -:100AF000DD8B6D556A896E02C996A8F9BFB1E947C9 -:100B0000373E0F8E10BFB5728833B52E9EF2382453 -:100B10003DC93C0F6BBA859E33311EF0E157491F2A -:100B2000D2BACE8BB9FB46C6552BECD4DF7C8FD81E -:100B30004CA7323F84DECB89B45BC5BCE6FC109782 -:100B4000C6BFB7D25AF900F9F32F354FE438D22790 -:100B5000C18D915DD8F05FCD942FC5DAF9F3867C15 -:100B6000377DE770BDEC97C828BF499E83539C032F -:100B7000137691CCBB89969783F65CBA84B9870DBE -:100B8000C67D36CAF73D3E0DF9E53D578CC8C7EF27 -:100B9000773EB873D313680F6DD9B5E67D2CE38724 -:100BA0008DA0EFA726782D5EBC9FE5BAB1BD1D399B -:100BB000E4DA618B9BE938F5E74AF75315CD0DFD73 -:100BC0001D2ED776E4BFCCA1D077AFD41FA605D118 -:100BD0006E4D5F64C48356C5DB17FF3E6660A3425B -:100BE0007A177E6F40DF6EF718EBC7262842BF34B6 -:100BF000DA31CD31EE750DD5B8DEAA9AEEB56EB20A -:100C000079E8FBB99BD6A9A40F6C1271A5F1DADDC6 -:100C1000F357036DDFDEC8FF9E706B893D88F75385 -:100C20005B13DDD7CDC5BA907F32BEDDFC8DCB82A4 -:100C3000FABFFB9439C14378B8B1A46F06E371F0F1 -:100C40000CDFF0D878F165CBFF0132DEFE59008071 -:100C5000000000001F8B080000000000000BC55BB7 -:100C60000F701CE5757F7BBBB777924EA7BDD3C9CC -:100C70009C8C6C56B6146490E5B56C9953B0A3BDCA -:100C8000D3BF9371E9C5FC3333B67BC6C6214D266D -:100C9000114E494C42AA333A59F21F84AC24953381 -:100CA0006D9AB30999CC8401259DB6860073024ADA -:100CB000288144492990690684096E483313A7C1E5 -:100CC00089D2A1A5EFBD6F5777BB3A59B6E34ECF96 -:100CD000237FF7ED7E7FDFBFEFF7DEFB6E8DDAFF60 -:100CE00072DB7A007855361ED6B104154C3FF0E71A -:100CF0000319FFD3F06F09007D857A2AC57B052093 -:100D0000FF810470F57115F2767BFCFB6E4718A02D -:100D10008D6A63905A8DC5E48D1ED800E0B7DA5C09 -:100D2000234FB6AEA0F95E93E1617ED20FA94AECE3 -:100D30004B9F8E42393480135C2DFA284B6855F84E -:100D400059017030B2F54734BCBBBD5DAAB969B377 -:100D5000BE85E681FEC966805551E7FAEC76A73A72 -:100D600070F13500BE1CE4BD412AF326B450396D44 -:100D70004A589EDBFE196DB3BEF03C3E281AB79E62 -:100D8000C603DEB75C4C3F7CEE853413EFFE8A96DB -:100D9000DB01F73D74830AB25482CE8BD455253FD4 -:100DA00025E13AC7EFBDFA468800640EC9D088E352 -:100DB00078A345EDF02FF5D47A9809887564F87911 -:100DC000D2243E053BBCBC5FFAF89730FF0088DFB9 -:100DD000FA8177641CEF4B49553F8CEBFD526AEF6B -:100DE000576EC17AF625D990F83DFE87FCBBC79AAD -:100DF00003C626581EAAFCA2FFFE53F7BDF922F136 -:100E000028A9BE457403AD882E2BB830FD1B0AF30C -:100E10003D183B3DB212E9901D293DFE1DD5FAA7B4 -:100E2000885E369D171AD77E2FEF9F9AEC5A57A8E7 -:100E30008F94A77798C887D180014074D8FF1CBFD2 -:100E400087F52897B50BF31329CAF47993BE62BBD3 -:100E5000AF759A7B4CACCBA770E96B00DEAED46F5C -:100E6000DC8AAFBA236FED20FAEF097834E2A3DD14 -:100E70007FF0A817F2012204CE8B72B70566766C5C -:100E8000C576D0E0653997236BF9F9EECA94E2C1D3 -:100E9000F2F3E60A9617BB7F1F7C59D987CFD77824 -:100EA000B557494EB211895684CF9180B8F4CD0A16 -:100EB00098412C7BF5B8BF1EC74D3E491301748481 -:100EC000C623E0016879E2785DBA99B6614E3721B0 -:100ED0007F4216BBAEF54DA73A71BCC19765E37E64 -:100EE000AC87027BB700CA91F4182E969E8720E744 -:100EF00043BE2B819E77E9F9A6B3005D45F2D4315C -:100F0000EB87AEA6423D8E2317D73BFDB58EF6DDAF -:100F10005ABDE3BD0CA691473AF5465739DA55B6A6 -:100F2000ADD768BD7DFA5AC7F31B9ADA1DFDA14BF8 -:100F3000393D83F58DF88FF82E83A8F37B5C77A07D -:100F400019EB45FD1528AAE3FBBF352B2367AEC57A -:100F5000CA75701DE911F2E5E411B23FDBFC06F140 -:100F600065D00BA7A42A20D5CF402B11DBD4234872 -:100F70003FC992D757CC7A960B29F0FC1F580E9F89 -:100F80009CF148C4D727A0F53036FA1B4D9FF2607C -:100F9000932B6948EC1F4541D7914F0D385E592B73 -:100FA0003F3757623D0A52A60FEBCBB05D54882203 -:100FB000BC40EDFC70E00BA21D2CA3761A64EAB0D5 -:100FC000AE19504E7CADC3713E19E67E993EABDF43 -:100FD00055A25FA62A2CC66FA179D15C76637902EF -:100FE0000CF0C9448714C04AB222FD5C5E45ABC216 -:100FF000E70F81D14AF5469861BB84EC97A87E053E -:101000004C6AC2C8E785DD9E514267FCC2EE97D2AA -:101010009782DE2870C6E607CDDB61FE80F4EFD64E -:10102000DBDBAAD28185FB29FB9F75E8AD1AD79936 -:10103000CECAFE5ED61365FFF3FCFEEA78EA551AC7 -:101040008F48EF6F9D4FEF16350F64BFB27130328E -:101050003844F6F1CDD15DC8DFCCE37EA3112E1F5D -:101060003F2E960F39D0CA89AE72FFA5F2013FB864 -:10107000AFC029FF89C32C8C269F937F045FFEE7B6 -:1010800052F8E2E607DC570DD0BEB81DFD6B295FB4 -:1010900026AD647A98D1D602FDB19E5965D12B6CEC -:1010A000F14316655EB69E2BE185F942E355870B49 -:1010B000FC598C2FD114BE6F2DF047EE379978F67E -:1010C000B9EC83B312952B2483F9B5524E79A85EFF -:1010D00021E52DD093633B1D048DF9B314FAB98C2F -:1010E000786776117FB2FB71229447781F4F59C2FF -:1010F00049D6B9980D24FCF5645F9B14C383F5E6CB -:101100004A4F2A8774BC52813CEDAF56810CD9738B -:1011100044063C7EF6713CADF09CC9E231EDA17E07 -:10112000F7FA7359A9307F8B65B77F54F94D6DA6D7 -:10113000B940E7D364BFD6087A78D8FE4CE6A97FD9 -:101140003409C6A03EDF9E61BB8C6CD9292A77D2B8 -:101150008B76A65B26887569E4FB7F209C41E3299A -:1011600058AF88A77BE3354C770884D92ECD5478C7 -:10117000A0142E300957ECB2E6D9F6117D790AD7C2 -:10118000B96BC4F7168D07599F1317B8FBEB1214F0 -:10119000F7B7FBCDC995BBFF25EA01ECAFB9201C21 -:1011A000107F6C6315D179419C497A525DDC4FF018 -:1011B000498DA41977A8A42FD58B8FE375E1177BF0 -:1011C0001C2F0A2E8DE3B5F08B7D4EED85B35E6549 -:1011D000A5B54EA4D76EB03F11A6E74E8B7E7F46D5 -:1011E000E75590E8A9AB44A43D9052496E3F861064 -:1011F0009A70FC8A437B828C17A04B23FA48F9EB48 -:10120000E50FAEBD083A5A74DA997FD7AB935DDA31 -:101210005F096FDBEF5714DEFF76FB4D8CDBD101EE -:101220006820FE5658EBAB38F5FE0019F5FB2BFE97 -:10123000F2E50E5CFAD0BFC8865C4FEF11CFE23802 -:101240006520CEEF0AD2535C77C59367FE9BDADB4D -:10125000EFC17A4F2343D1B89E8AA38C672B82AA11 -:10126000CE38DB2567368E86F7050E0E58D42B1A3E -:101270005722BC6CFB3D3CAE347FDED5163EC757D3 -:10128000F10F2E00CFBB713ACCE173F13E105085C7 -:101290009E1888738BE9B8809ED9EBB6FBD5A8A9B8 -:1012A0007AA3B9447F8B0FCD685708EF5D5107B91A -:1012B00003B8DE91917DF10AAC1FAB01DD87AF86EB -:1012C0007B3E2B11DE4844842885620217D21434F9 -:1012D000BFD79A2FF40BFD7013BEDF5B173070651C -:1012E00070C5AF4C2D8EE3DC59E7374C7C9005F18F -:1012F0003E13F3087F3203AF101EDD63F1C7FBA47A -:10130000C099CC1BD4C399B8C0577B4E7D720BF1EA -:1013100077347CB391C7767BD03E55131E1BF332D6 -:101320009E435CE7C0FDBE58110EC4BF3B8F7B1DC2 -:1013300075AF0B27BE19471C48CCB470E02FE320D3 -:10134000E6C582CE93CB350F04226C4F572BD31EAC -:10135000ADC4396BF3C3C6DF4FD5083A7BDF1374D6 -:101360004187791F3DF7BD27FC3134E081B62574F4 -:10137000FA0BFAF9DA903EF4F43D711E604F5EB755 -:1013800089FF68DD6E3CEC73E161F77A6D3EC80958 -:101390000B276F800D441FC4E78C13ECFDB8F7F1E9 -:1013A00024FAE75D28144F0FF8B9CC0F685C3E3380 -:1013B00010E5F2B9011DBA10803D3FD0C4E50B0322 -:1013C000063F7F7120C6A54D87F9F44129C4FD5E13 -:1013D00065AD59699E4ED139BAB4CBC3AA70EC3E03 -:1013E0000FD3ED1CCA27295F10BD2005977855D271 -:1013F0009333692F96FF738525AFD7FACE4EF9B098 -:10140000FD682D18F763FF2B627B59CE369DF514CE -:10141000F404C8CF2977C409E250EDA877FAAF7475 -:10142000B4EFD6563ADE87E3336CA77AA3D73ADA1D -:10143000D97CFE3AF959B8BE635DA735A26B9FBE51 -:10144000CED14EB90FF9DF42FECFF58E7141DE628B -:10145000909D0E6F77CA61D0C557F5AEF3FB41364C -:101460009FCD84530F16E2AF5B5E6DBA86E7E82A24 -:10147000FCCA2CF99548D7B026E86AEF77D4DAAFE2 -:101480003DAF1213FBBBDCFE6590FCCBFA52FEE5D0 -:10149000CF2D3A2FE25F269DFEA59BAE8BF9977F5D -:1014A0009E70FA97174ACF9DCB45DC2DFC92CC7EDF -:1014B0008B9CECE773B07A5A367AC9245AB8AC924E -:1014C0006C00B6DBD9A6E608671E8399289DE70F56 -:1014D0004A485594B7EA66A396ECCCA321E3D56DB0 -:1014E000841BFB3CC649ECF26CFCD628E18EA103C0 -:1014F00027A27858C103090FCF3B163FC3F10B4514 -:10150000078E5F6069E64AE013BBFD3D435E3E0F18 -:101510001EDCA1E6246CFF60A576EB36AA5BF32007 -:10152000414C7A3FD1F6A11CF929A309DD8A336524 -:10153000A2E4AF7C69C7865A3EAC14ACAFA6E606FF -:10154000EBC9E1322D487E74768747A37DC9EBFF56 -:10155000EA33241F0F48FD871AC87FABF1009D1F97 -:10156000D9D086DA5DD84EDE893086EA3B36BC4E6D -:10157000367BA2463FD440FD430D4CBFA18DB7FA48 -:10158000699ED1D0923E8A8F8C767B984732E18CCF -:10159000208FD3743EBF47D68ACE77E0B805AF53CD -:1015A0008E78F22A9D57843F82F3E37B87432A3962 -:1015B00005F08F895B4E641AF831DBAF2B2C3F604E -:1015C000E78E84C9F68AF004D267A777A6A6D4B9B5 -:1015D00070D08A77CE9D3B51E77A4ACCC3B8401190 -:1015E00033F247B7E3B4F8C9DED893A373741C523F -:1015F00049B29F998087E31D0BED5F0938E7B3C7B8 -:10160000E7F1648AA395996545FBD7ACF8EFCB0960 -:1016100089F1EA0F89EF6D62199125857529490FC6 -:10162000F7B3FD5794DB6D93240F16BDD1AF78BE91 -:10163000F8BC7D2D21E2B2AFCFC911365D52B48E18 -:101640008DAA359EC1718A35AEF8B59B3F171BBF79 -:10165000FEA5B59FD7B6DF745E3F7955CED9CFD7FB -:101660000962FF56BCDB6BF1FF1A79721FC9E3FFF9 -:1016700077BCDBD77979E3DD6F937D229C8776FE9B -:1016800061FC9EFD698EF5054E9D7D9BF57AD51218 -:101690000BBF40B4C1C68F2BA874E90F017DE4DFF6 -:1016A000F85AC4A5581FB7EA99D5625C28D6CB155D -:1016B000E4178838CAB2CE95C2DF227B42CC558C63 -:1016C000E544D780F29D8C86FB280F1C831096BEC4 -:1016D000C8AE0C951DCBF5D118AE6B7C9587CFAB02 -:1016E000F1CAF489215AFFAA4049BD68EE14F66F89 -:1016F00084E495FD24303DA46F92AD1C90F6209FAC -:101700002640F0D9EC0CF17A146D2C7607CA4DCC3A -:101710009207DC0FF7778FFF611ABFCD31FE374894 -:101720004EB3D6E034CE2E1C27DE29D97A95A1F708 -:101730007E6B3EBF3E16235C90E8D4C47B65AD4112 -:10174000FA301E2A3D5FC29A0F2814B3A1808FAED3 -:10175000D82EC601BFE8FFA07476DBE9F5CC57D6DA -:10176000275A07BDAF309CF6C13D7E5993D3BF5178 -:10177000EB9CED5373FB70FA450F48A5D77BB7D5AB -:10178000BE63B99033928FFB4BC8875BDF558A7B72 -:10179000E2B869E207DB0F617702CA7482FC9D4000 -:1017A0003318834CE029DE6FEAA9865333EBC9CEA8 -:1017B000070DF283143F9ACAD6829FE8DEF7627E55 -:1017C0009EA240C6DB3ADFDFC371CDAA5671CE645C -:1017D0008AC6FB8C252772B13F584FEE887E23EDD9 -:1017E00073EC90CCF1A5B17B7DDB4A9DD3F726CE7F -:1017F0009FD7399E423F829CD4C78E1EDA8DF5DF7B -:101800006A1ECDC76DF492791DCDAACFE57552172A -:1018100096D719EB0AF7355C4C5E678171E7CEE32A -:10182000F9799DE39D48A76301915F99CBEBDC1C9F -:10183000B9A0780E58E772D8B2CB957D961FB15FEC -:10184000623FE299B67F3FB286E4ACCDCB720047EF -:1018500027A0584FB66CD7BF5A4DE7CCEB3E681463 -:1018600076CDA4F16CBFD8A69F6A8D9FF8F64B0A7F -:10187000B51FAFF56CE0F120EFF344793DAA55CAEE -:1018800054AE51F372158D1B06439C0F79899EC788 -:101890009158C5FEC1E8EC4F3AAB284E1200834C7C -:1018A000D0685C3B50455F280B4478A75ECF91BD64 -:1018B000EDF45738ECFF689F2AEC6B23FA4BA43FFA -:1018C00053FA57F760FBE1FD658C9B1EA8F308FDFA -:1018D000CA4839A99EF0B5D3EF199F5C21F0D851C1 -:1018E000AFD188ED1F9914ED77C737E464C6DD4E9C -:1018F000BFA84F77FA45BB6B5B5F25BC08435E8E84 -:10190000C76B16AEBDA1C9E92755D6F7BF403865EC -:10191000E790C0C307A3E125BBD1FEADEDD21D7991 -:10192000B25D437772DE684805CEA78EEE50593F10 -:1019300046BD6F1DDFCDB8B19CE938B143AD4D1741 -:10194000E9CBC7BA7C3CCEC40E813F105EA6274BC4 -:10195000BCFF589765A714E073DC96973FF9B8A0D1 -:1019600073B00E723AE1B8BE7D79F22BC7EB704FBF -:10197000F87E28DAD03745F3BF2203EDD32D87F761 -:1019800090135CB40F5FCCE3A093D797EAA7F1E183 -:1019900006D0C9AE7525B14E7180ED2A507CC017B6 -:1019A000FD0BDE6F18EB6558F727C7320AD6FD0D21 -:1019B000E975848B9FBDF7B6917884CE3BA1DFBEDD -:1019C000ED7B533751FBF55E28A3F5812E45697DEC -:1019D0001909449EDFA90F07B3FFD4457C3A684834 -:1019E000CCA29D7D5BEFA2F59C8B94336E1AF3A67F -:1019F00076B13DBAC5AF65F80C9C613FC2FB051FCF -:101A000090DC4DDCFB4E0DE1EFABBA56B0BE95E974 -:101A10004EFFDA0F637C6E6F34A7B753BF8D3195DD -:101A2000321EF04CFB19E6DB449BCFF0E13A26DA9C -:101A300025A6F3EFDABC399AE769755AA6799FFEB5 -:101A40001DCE5D5F4ABF4BEB95AD47EEF6A3B1AD42 -:101A50007E928B83307D33D127332BE254EE76DFB9 -:101A6000B0E4E060F6962685E3592AE7DB95B38675 -:101A70005985A3876653DFA2D8EB2B9D0AB7BBA776 -:101A8000D6939170BCE13E95F568B8323D42F23C88 -:101A90008C72CF7E5204EBA467B511E370D17CE366 -:101AA000EDB736913D7BB9AD8CF1FD6BCFD6DE91B4 -:101AB000C12113F2AFFEEE31F2ABEA54E6E7B0B764 -:101AC000FF75F283326D65BCDEE796A9E0277B10D7 -:101AD000B9E321F2B3E191ED502CAF1349A1A71363 -:101AE0007542EFA5C7B6B31F302EC94C67B3E6A445 -:101AF0004478CC97B4E34E22CE14B7CCD9C4F6EFD9 -:101B0000721C6A699F88A3C69356BC490E64582EFE -:101B1000AF2B7B88F4DF54BC0EFF78D359A7BFBC32 -:101B2000D4E52FBBE3515BBBAC78841577B2E532CB -:101B300068B5998859767ABD2F27E4B0BF566B9E59 -:101B4000AFDF3FB4F0F3F4801F2502E027031AD77C -:101B500083E66F0E54139F06A2FCFC4F379E908ABB -:101B6000FB8DAEBFC5AFB33D9989D2B86E3BE2964F -:101B70008B373ACB1DE789BDCECAF60410EE3D7710 -:101B8000962D326C0ACC74F2D908D38162BC9FA71F -:101B900075FA284E26D6F91CADD3477132B1BE175F -:101BA00006742E5F1C68E2F23B5D20F201B67DB840 -:101BB0000AED03D2A1AB4ED4C91E10FFC3913B382E -:101BC0004EE68B2A1AE9BBBF6E2C2F15D98789CA1E -:101BD000FE9FDE4976BF26C0F2E8DED7B1AE397C83 -:101BE000E8D8D7CEF67D6C77CEE13C447FB433772E -:101BF000B11D42BBC0F36E576FE775986897D82E3A -:101C0000F47FF536B60B5E203977DB817046E877D6 -:101C10005A17F13BFB9ED09C5DC0797238CF336878 -:101C2000D7A93E8C7680E6196E7FEB1334EFEFFE7A -:101C3000500E34C4C48E57D92EBC7C0EA0FA32DAB2 -:101C4000055B0FD73DF71F27324A293E6FBDED9444 -:101C5000A0870682AEDB5225FCC48BE5339817863D -:101C60006372CACCED22EFA8321D16CC3B663C064F -:101C70008505062795A4957704CA3BDAF9C7A2BC67 -:101C800063B933EFA8E6B28C6F7256DEF1D6CD227F -:101C9000EFA896CF040AEBB0F38D43F4A8B6909F5B -:101CA000FF87AEF4CB5D6D853CA32E893CF8D571E2 -:101CB000F387F41C22613EFFDD794A3B1F89F04E19 -:101CC0004A17E5375BF0B93F5CC87FB9F399F6BDB9 -:101CD0008C1675E6E411A4CBE0ED7EC60FF6FA068D -:101CE0001FFFF0EBE948E13E809DEFB4F39976DE0B -:101CF00013D7FD4EF1BAE14960BB034FF84FD0F95D -:101D0000E65E6F453CFD4B6A3F6FDD17985FDC0276 -:101D1000D6F888BB489FDFB4E838D7BE4BF89F6B36 -:101D20005411DF86A0CAFE4EE2DB0190096757AA74 -:101D300027492F76C14C37D1773024705EF6012FBA -:101D4000DB49E8D6997F35AAC9F7216A3E5F661C50 -:101D5000C0C7D9292D48F1A7AF759AD0DD46EB1839 -:101D6000BB792BAD03713BD9BB371ABF12E17C3F66 -:101D7000DD7BAA22FFCF584E7110BDBBF47DA58E2E -:101D8000E567B7F2BC951E20FF2C5B66BCA013BDB7 -:101D90009F5278BC3E1CC26CE5FB4B5D6A98C61135 -:101DA0007EF260E034F3ABA3D1B796E37A95A5FD5C -:101DB000C0A5DD820E9B712C15C7792A9EAEA57534 -:101DC00053AC34CA722CFC3BBD1B6CFB759F674344 -:101DD000210E5621A7F56EB2D78F480A9D8F3E4B34 -:101DE0006E6C3FB13B61D6770B7E9834BF7D0FC8D8 -:101DF0009EFFEA6E61175FE9323F44EDDA681E929A -:101E00004B2D13273D6C49A33C48AC3FAE3CBC90E6 -:101E10000BB7BCDAF2369787B7E450D244BE16E56A -:101E2000AA8DF6074FEB531E89F2EDE91347A8EF91 -:101E300025E6BB3F9D3037D1BA77C7531D54BE71DD -:101E4000EF6DC0799D0BBCC7D1B1BC3F4A79FCE1B5 -:101E500032819B1F8D1B0E7B77B7459FBBBB055EF9 -:101E6000BA1665669AF44031AA80F5F82EC6D1B646 -:101E70007D1A1B487FEFE78D85FED90198A47CD0A1 -:101E800042EBF01EDAC771DDC1BA849FEC0FDAB7FE -:101E90002AAA0FD799D1E275642B859C679689B8D9 -:101EA00005C5D332BEC2FBBDDD32EFA7B30EF224AF -:101EB0003BBE80C8BBF95071753C7F7C662CCFB8A7 -:101EC0002600931462F814E90FDDFF8B186092BFAF -:101ED000599702D26F9F56E84F79D4CEBA7EBE6F23 -:101EE000B9D03872D4EE9FE6FEE3DD1A8FAB463CE4 -:101EF0008E38C0627473D36588E8D6B830DDD40BF1 -:101F0000A69BD03B37BD0E13BD909FCF863ECBFB2B -:101F100083F73B59CF7C1AEE13CB31CBBEC80113EC -:101F2000D29564A352882029CEDE0F9487B6E92C7F -:101F30006B82CEB2D6CFFD7C7506A457135DD24C12 -:101F400017371DD04E00D9897F7EFC7884F0690751 -:101F5000D6A3C27E800FCB5F5BFEA0ADA75BE0C7C0 -:101F60000111FF769E17F3ECA9553E6AC59FDDCFA0 -:101F70006FE92913B84E0707DD2B2BB7323F4E8E82 -:101F8000B4323EC0F33343F7627A6A1BCBA97EB901 -:101F9000F388EEFCA13B4FE8CE0F16E4C6F4D33A2B -:101FA0007FAB9DCE7CB484BCD8E5114BDF8606FCAC -:101FB00025F5EE08EA3BF16FB8DDCC50DEE860684D -:101FC00026CA7233F52EE362E525D9207CA9288242 -:101FD000CF3DCB66988FBD311328DF746460DB770B -:101FE0008AC7FD753CFD23B26715DAA449E30420D6 -:101FF0009FA1F36773B5D95F0A37FD9B6547BA1395 -:10200000A97F257BD5A10BFEC7E2E6AB6C172FD0CD -:102010006E2DA44F8A4DBB8BD6A7D3429F62FB582F -:102020009F46EBFA19678DFE58262455C091963EBF -:102030008DB69F617DB7F5EA3D4B9F3A63422F28ED -:102040008E40E777B0CE64BBF15F963E29A827A407 -:102050004F3E4B9F825AA13DC5C73B89CEF85CA934 -:102060009BE17EC198A57FA44F01BA3F0C8C0386EB -:1020700051EF282EE2D6AF8E06716E6A89B4A7871B -:10208000F0C5B2AD1C971FAEFBCF6AC62F96FC17EA -:10209000F06E2B9FE7E7463C06E9430B01E8D6824A -:1020A0001ED8FBDE382B431E59B36956E2F223B328 -:1020B000155C76CC967169CE5673199F0D719998FF -:1020C000BD92CBCED95A2EBB66510FD621DF67EB1E -:1020D000B9EC99BD96CBDED9555C2667D771BBBEEE -:1020E000D9B55C6E9EBD9ECB1B66DBC53C4D625F69 -:1020F00025F481D26097411F8C0C54921E7CFC7594 -:10210000B6EF9ACA7794B2A10D9C27F22933AC0F8F -:102110002763C2DEF706049FDCFAD09D48AF25BADC -:10212000BBF5610EDF2AA011FD55B03E2EFC80F8F4 -:10213000A7BDA7E83EB21A3559CE109F7CB887F4E8 -:10214000E31271C21CCE5CAE321EB571E6E832C439 -:1021500099F5059C39DC2EFCB2EC033EF6DF764B9C -:10216000E27ED9A713E91B7BD82F1671A2F4CD7E8E -:102170008D707336D4130D505CEFA00C142F401CDF -:1021800092E2764A4ADC67BD407D8EC5857ED8EDF9 -:102190005BE0B4A7FF2270CC1BF4B57D61BB10BE21 -:1021A000D473D6DB29EC8226EC42B6AE7F84F3D220 -:1021B0002EBB609FB3480F875DF85C8F854B2C3D2D -:1021C0000FD789F3324C7601E9F3C51EDB2E38CFE9 -:1021D00059C5C621491B8758762129FA216E779C5B -:1021E000B3C86E3F14E16294A3C19EB6F9F681CFE5 -:1021F000F3A2736EB0A1314EBF25089D8538896763 -:102200007056DF6C943877B25A2BEBC194D209C563 -:10221000F1958BD6B3907DEE987CEEB8DBD9FA368B -:102220003CD527F6699D4353B87FB348DF7A3571B3 -:102230001EE1F9F3F59E12E74FC772339D2AB1CE26 -:10224000477B84BFF1834D16EE455C690418DF9728 -:10225000C40D8FF608BB4EBFD37802ED4F77329393 -:102260005574D6F34749CE37764DCB1446F8486CB3 -:10227000EC154A89A09E3EF6C7E8E9D1B895EFDB98 -:102280005F2D2E3B5BE562F26FE3225B0FE6EDA371 -:10229000DEDC568A1E4B7B05BE1F1CF1F4D1853F48 -:1022A0005B2EA694958C7F4AD85BD3B82CF6F6C2E9 -:1022B000F0C7149E83C4F7F3E08F374BD9DB85F06A -:1022C000C7991E912747FCF10EF5EB6816F8636974 -:1022D0002FFCDFE08AF869A6DBA5E28A0F6CFBB170 -:1022E00000AEF0F6EAE27715DA0CDB8FE025E20AC1 -:1022F000B79D40FC50DE4BF431C4B96BFFDE842F38 -:1023000050169D5F6867AA7A055ECFD3E5B19381C9 -:102310004446623D4885E8F998B982E5E872E903E8 -:10232000E2C42B7B8BEA8BE9C505B79BDCC171400E -:102330003B9FF9FBB2600BC547F6FB45F9B9F2E0EC -:10234000492AC707441C7A94E27E588E7B81F307A2 -:102350004352B97152A27ECB7322DEDEBF86E29E6B -:10236000D7F786AD7872FF75FCBB1BF8A2236FBA56 -:10237000F0BAC43D5F1AEA03BE0F5EA7711CDDA26E -:102380004B981880F31E5EE5671C78B8EF91E377F1 -:10239000505CA64FC4C140D1EB3F4AE72FC29A58C8 -:1023A000D1B920837286E2F32374B79D41C7367199 -:1023B0000FDA5A4F7512FDF722FFA32A76D7F77E60 -:1023C000EEBC37E429CE231F31B75689CBCA77F14B -:1023D00038B69E1C094CFAB5227B7374C079FFC9CC -:1023E0005DCA6DAFF07DC3634D0AE72F1E581F29EC -:1023F000233D39D42082B4E58D9E54AE843E0FF443 -:102400004A8EB876C83AE7CBBAC5BA169A6F784002 -:10241000C46FEDBA4F4F9924A7E5F56329A26B79F4 -:102420006344A2F8ABFDFEF65E61370E4B46BE0379 -:102430008979B8529C17BEBA0C78080F84F6AE237F -:102440001AFBEBFAE14C80EE6F64E06D2CC3613552 -:102450005D6ADD83D6BA0F7B7329C2538757299CE7 -:10246000E7444C55324EF609CB4E97378EF3FAA01F -:1024700051E17C95BBDD0EBB9D3AC6F98E438DDFE5 -:10248000D4695F87E807374B914BC9871F3A40767D -:102490006600F9EA25794E73597ECDB798FEA32DD3 -:1024A0008A46FBE8969B0FD03CC79260105E71CBCA -:1024B000C531D0CA687CB77C54AC7E8FE34FE54110 -:1024C000CA8C901CCEF8851D157216B0F8336A8838 -:1024D000BCCF684AE4AF6CFE15DE8BFB06E7520A00 -:1024E000FB2576FE6A0940491C67EBE590158F9F36 -:1024F000F77E799ECF9DA39BF251BA2711D4FC465B -:1025000092C67DC4B9AE837876F2BAFA44FE62CE42 -:102510003EAF15FEE1FC758AF881F2CCBBC2AE5A23 -:102520007E42B0F93DB6ABF6BDAFDE8D425FABACDF -:102530007BF755919429E872B7C31E48D7FC224314 -:1025400079A6076BC5DD84F04671AFB65C05234FF5 -:10255000F700FA027CBF6949CCCAD76D13F72BECA0 -:10256000FBE16A4475C41322505427DCE9AA83BCFA -:10257000FDBCF7E0F6FFECC48BCF15F1FDA55EE7DF -:102580003DF2C5FAFF7E20F7E27368908E19E7D717 -:10259000479B6F5F1E887169CBA52DA761DA62EB3F -:1025A000C2FDC743A992799A6052E8C362762DE2D0 -:1025B00033DBDF41BE7BAB81F3675FD9E41CEF37D0 -:1025C00096BEFEC6D22F7539D4129E1A0B093B3027 -:1025D0005606DBBE5B426F972455B61B057D70E245 -:1025E0000A5B8EE6D363115CB1BA4BE00A2D5C4600 -:1025F000B8E898917881F281EF69AA5E2CB7EEB8BD -:10260000BB8D2BD2493BFEA74A840BB4C00CE3ED33 -:10261000395C60E108372E28F7E6B6917E94AF5218 -:102620006D7BC576E5F3DFFFFB8732BCBF8C547C46 -:102630008E8EE66FE771C3AEB83B449CBF63798B67 -:10264000F017AE27AC4F4E2728FFB84511BF6F1BC0 -:1026500033A1F81ECEB8E7FDD83BD6F7F76D1C5274 -:102660004FEF8F4EF3EF6BE01E289EFFE04D3BF9DE -:10267000F7148BF1DF5E17DDEB2AD69F8BD50F2386 -:1026800069E9471994917E9C83FB380F0F6349C712 -:10269000F9C41989256C12C407B7A96CB0A082547B -:1026A000D01BE8B5F2E3E9393BA9503FC3EA564BEA -:1026B000B72C64CA37E4F9778BB6BD39073FE379A5 -:1026C00033CF48D21CEEBA12DD7FFA3DE44A5A827B -:1026D000E6A1D2BDFE1560F0F3064871F921E8E7E6 -:1026E000B209C6B8BC0626B96C86692E5BE02C9789 -:1026F0006B419769927560CAC05737D35CBF0E3281 -:102700005CB643BA9DEE970FD5EC5D4BE7D12D2E0D -:102710003AD9742EA1F78C2B6D7AD8742F27E35DEC -:10272000B3385FB321618F3B6379F61F0201819B50 -:102730006D7FDB1E67211C7CB9F09A8D33FF17CFAC -:10274000A588169043000000000000000000000073 -:102750000000001800000000000000000000004021 -:102760000000000000000000000000280000000041 -:102770000000000000000010000000000000000049 -:102780000000002000000000000000000000001019 -:102790000000000000000000000000080000000031 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000090000010000078 -:1028C0000000000800009008001000000000000256 -:1028D00000009000001000000000001000009DA803 -:1028E00000000000000000080000000000000000E0 -:1028F00000000000000000000000000000000000D8 -:10290000000000000000000000000000000091A096 -:102910000000000000000008000093C00001000457 -:1029200000000001000093C8000000000000000249 -:10293000000093D00000000000000008000093D4C5 -:102940000000000000000002000094980000000059 -:1029500000000008000093D80008000000000008F4 -:1029600000009B3800400000000000400000941868 -:102970000008000000000008000094580008000053 -:1029800000000008000094A800C8000000000098A3 -:10299000000096380098000000000028000096789B -:1029A00000980000000000280000C0000540003032 -:1029B000000005400000CB200008000000000001DE -:1029C0000000CB21000800000000000100002008EA -:1029D00000100000000000100000200000000000B7 -:1029E0000000000800009D600008000000000002D8 -:1029F00000009DA000000000000000010000000099 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B900000000000000012C800800000000000805B -:102BA0000000000100000000000000000000A00084 -:102BB000071000000000071000001EC80000000001 -:102BC000000000080000AEC000080000000000087F -:102BD0000000AE4000080000000000080000AE80C9 -:102BE000000800000000000800002008001000009D -:102BF000000000100000200000000000000000089D -:102C00000000A01007100040000000400000AF408E -:102C100000080000000000010000AF4100080000B3 -:102C20000000000100001ED00000000000000001B4 -:102C300000001ED8000000000000000200001EDAA4 -:102C40000000000000000002000012B000080000B8 -:102C5000000000080000000000000000000000006C -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000B00000180000000000180000B300E0 -:102D600000400000000000400000B30000400002EE -:102D7000000000010000B30100400002000000005C -:102D80000000800000400000000000400000000043 -:102D9000000000000000000000008000000800406B -:102DA000000000040000800400080040000000044F -:102DB0000000BB0000280000000000280000BC400C -:102DC00000100000000000100000880000800000DB -:102DD0000000008000008800000800800000000261 -:102DE00000008C00002000000000002000002008EF -:102DF0000010000000000010000020000000000093 -:102E00000000000800001108000800000000000891 -:102E1000000011680008000000000008000011A870 -:102E20000008000000000008000012700008000008 -:102E30000000000100001271000800000000000105 -:102E400000008D00001000040000000400001320AA -:102E50000030001800000010000013280030001897 -:102E60000000000200000000000000000000000060 -:102E7000000000000000000000000000000011E859 -:102E80000000000000000001000000000000000041 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F20000000000000008308008000000000008016 -:102F30000000000100000000000000000000200868 -:102F40000010000000000010000020000000000041 -:102F50000000000800008D100008000000000008BC -:102F600000008D7000080000000000080000845080 -:102F7000046000280000046000008EA0000800002B -:102F80000000000100008EA1000800000000000108 -:102F900000008408000800000000000800008448C9 -:102FA000000000000000000100008DF40008000097 -:102FB0000000000200008DF6000800000000000282 -:102FC00000008E040010000000000004000000005B -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:1030700000000000000030000040000000000008D8 -:1030800000003008004000000000002800003390DD -:1030900001C0001000000008000032000020000005 -:1030A00000000020000037200000000000000008A1 -:1030B0000000102006200038000000080000A000DA -:1030C000000000000000200000003EA900000000F9 -:1030D0000000000100003EC80000000000000002E7 -:1030E00000001C4000E00008000000080000000094 -:1030F0000000000000000000000040000008000088 -:103100000000000100004001000800000000000174 -:103110000000404000080004000000020000406081 -:103120000008000400000004000040000008000047 -:10313000000000040000400400080000000000043B -:10314000000040400000000000000008000040486F -:1031500000000000000000080000800000000000E7 -:1031600000000010000050400001000400000001B9 -:103170000000500000000000000000200000500887 -:1031800000100000000000040000500C00100000BF -:1031900000000001000052C7000000000000000114 -:1031A000000052C6000000000000000100003000D6 -:1031B0000030001800000004000030040030001847 -:1031C0000000000400003008003000180000000279 -:1031D0000000300A00300018000000020000300C2F -:1031E00000300018000000010000300D0030001811 -:1031F000000000010000300E003000180000000147 -:1032000000003010003000180000000400003014EE -:103210000030001800000004000050000100008091 -:1032200000080004000050040100008000080004B1 -:103230000000000A000000000000000000005068CC -:1032400001000080000000010000506901000080C2 -:10325000000000010000506C01000080000000022E -:103260000000506E0100008000000002000050705D -:103270000100008000000004000050740100008084 -:103280000000000400005066010000800000000201 -:103290000000506401000080000000010000506048 -:1032A0000100008000000002000050620100008068 -:1032B00000000002000050500100008000000004E7 -:1032C000000050540100008000000004000050582D -:1032D00001000080000000040000505C010000803C -:1032E000000000040000507C01000080000000018C -:1032F0000000507D01000080000000010000401827 -:1033000000100000000000040000409000100000C9 -:1033100000000004000040980010000000000004BD -:1033200000004110000000000000000200004112F7 -:103330000000000000000002000041140000000036 -:103340000000000200004116000000000000000222 -:103350000000604000080000000000020000604221 -:1033600000080000000000020000604400080000A7 -:103370000000000400006080000800000000000859 -:10338000000060C00040000800000008000060006D -:1033900000080000000000020000600200080000B9 -:1033A00000000001000060040008000000000002AE -:1033B0000000634000080000000000080000638077 -:1033C0000008000000000004000063840008000002 -:1033D00000000001000063C00008000000000002BF -:1033E000000063C400080000000000020000640048 -:1033F0000008000000000004000070000010000041 -:103400000000000400007004001000000000000430 -:1034100000007008001000000000000400007000B0 -:103420000008000000000002000070020008000018 -:10343000000000010000700400080000000000020D -:10344000000070400008000000000002000070440E -:1034500000080000000000020000704600080000A4 -:10346000000000020000764800080000000000088C -:10347000000070800008000000000002000070845E -:10348000000800000000000200007688000800002C -:10349000000000080000804000080000000000015B -:1034A0000000804100080000000000010000804290 -:1034B0000008000000000001000080430008000038 -:1034C0000000000100008000000800000000000271 -:1034D00000008002000800000000000100008004DD -:1034E0000008000000000002000080C0000800008A -:1034F00000000002000080C200080000000000027E -:10350000000080C40008000000000002000080806D -:103510000008000000000001000080810008000099 -:10352000000000010000808200080000000000018F -:10353000000080830008000000000001000080847B -:103540000008000000000001000080850008000065 -:10355000000000010000808600080000000000015B -:10356000000060000008000000000002000060028F -:1035700000080000000000010000600400080000D6 -:10358000000000020000604200C0001800000002BD -:103590000000604000C00018000000020000604C05 -:1035A00000C00018000000080000604400C00018BF -:1035B000000000080000605700C000180000000173 -:1035C0000000605400C000180000000200006056B7 -:1035D00000C0001800000001000066400008000064 -:1035E00000000008000066800008000000000008DD -:1035F000000066C000080000000000080000D9427A -:1036000000180000000000020000DE400000000082 -:10361000000000000000E0000000000000000004C6 -:103620000000DD4000000000000000040000DD4458 -:1036300000000000000000040000DD480000000061 -:10364000000000040000DD4C000000000000000449 -:103650000000DD5000000000000000040000DD5408 -:1036600000000000000000040000DD580000000021 -:10367000000000040000DD40000000000000002009 -:103680000000DA0000000000000000040000DA0082 -:1036900000000000000000680000BB6000000000A7 -:1036A000000000000000D000000000000000000446 -:1036B0000000B0C000000000000000040000B0C422 -:1036C00000000000000000040000B0C8000000007E -:1036D000000000040000B0C0000000000000001066 -:1036E0000000D6B000000000000000040000D6B4C6 -:1036F00000000000000000040000D6B80000000038 -:10370000000000040000D6BC00000000000000041F -:103710000000D6B000000000000000100000D348F8 -:1037200000000000000000080000D3580000000066 -:1037300000000080000000100000000000000000F9 -:103740000000D35800000000000000080000000046 -:08375000060022000000000049 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex deleted file mode 100644 index 78b41615e7d9..000000000000 --- a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex +++ /dev/null @@ -1,15442 +0,0 @@ -:10000000000052D8000000680000070C00005348B0 -:100010000000318000005A58000000B000008BE062 -:100020000000C14C00008C98000000D800014DE891 -:100030000000F16400014EC800000074000240306E -:1000400000005250000240A8000000B800029300D7 -:1000500000012110000293C000000FFC0003B4D87F -:10006000000000040003C4D8020400480000000F90 -:1000700002040054000000450204005C0000000679 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040258000000360204025C000000365F -:10017000020402600810000002040264081000007B -:1001800002040004000000FF02040008000000FF59 -:100190000204000C000000FF02040010000000FF39 -:1001A000020400140000007F02040018000000FF99 -:1001B0000204001C000000FF02040020000000FFF9 -:1001C000020400240000003E020400280000000099 -:1001D0000204002C0000003F020400300000003F39 -:1001E000020400340000003F020400380000003F19 -:1001F0000204003C0000003F020400400000003FF9 -:10020000020400440000003F020404CC000000018E -:1002100002042008000002110204200C0000020069 -:10022000020420100000020402042014000002193D -:100230000204201C0000FFFF020420200000FFFF3A -:10024000020420240000FFFF020420280000FFFF1A -:1002500002042038000000200604203C0000000FAB -:1002600002042078000000210604207C0000000F1A -:10027000020420B800000001060420BC0000000FAA -:10028000020420F800000001060420FC0000003FEA -:10029000020421F800000001060421FC0000000F08 -:1002A0000204223807FFFFFF0204223C0000007F07 -:1002B0000204224007FFFFFF020422440000003F27 -:1002C00001042248000000000104224C000000004C -:1002D000010422500000000001042254000000002C -:1002E00001042258000000000104225C000000000C -:1002F00001042260000000000104226400000000EC -:1003000001042268000000000104226C00000000CB -:1003100001042270000000000104227400000000AB -:1003200001042278000000000104227C000000008B -:10033000020422C00000FFFF020422C40000FFFFED -:10034000020422C80000FFFF020422CC0000FFFFCD -:100350000C042000000003E80A0420000000000153 -:100360000B042000000000030605400000000D0003 -:100370000205004400000020020500480000003291 -:1003800002050090021500200205009402150020CD -:1003900002050098000000300205009C08100000D3 -:1003A000020500A000000036020500A40000003095 -:1003B000020500A800000031020500B000000004A2 -:1003C000020500B400000005020500C000000000A6 -:1003D000020500C400000004020500D40000000172 -:1003E00002050114000000010205011C00000001CB -:1003F00002050120000000020205020400000001C5 -:100400000205020C0000004002050210000000403E -:100410000205021C00000020020502200000001C52 -:100420000205022400000020060502400000000A28 -:1004300004050280002000000205005000000007B3 -:1004400002050054000000070205005800000000EB -:100450000205005C000000080205006000000001C9 -:100460000605006400000003020500D80000000635 -:100470000205000400000001020500080000000160 -:100480000205000C00000001020500100000000140 -:100490000205001400000001020500180000000120 -:1004A0000205001C00000001020500200000000100 -:1004B00002050024000000010205002800000001E0 -:1004C0000205002C000000010205003000000001C0 -:1004D00002050034000000010205003800000001A0 -:1004E0000205003C00000001020500400000000180 -:1004F000020500E00000000D020500E80000000019 -:10050000020500F000000000020500F800000000F5 -:10051000020500E40000002D020500EC00000020B0 -:10052000020500F400000020020500FC000000208D -:10053000020500E00000001D020500E800000010B8 -:10054000020500F000000010020500F80000001095 -:10055000020500E40000003D020500EC0000003050 -:10056000020500F400000030020500FC000000302D -:10057000020500E00000004D020500E80000004018 -:10058000020500F000000040020500F800000040F5 -:10059000020500E40000006D020500EC00000060B0 -:1005A000020500F400000060020500FC000000608D -:1005B000020500E00000005D020500E800000050B8 -:1005C000020500F000000050020500F80000005095 -:1005D000020500E40000007D020500EC0000007050 -:1005E000020500F400000070020500FC000000702D -:1005F0000406100002000020020600DC00000001DA -:100600000406020000030220020600DC00000000D5 -:100610000718040000AC0000081807D800050223E2 -:10062000071C000029B30000071C8000312E0A6D52 -:10063000071D000034A816B9071D80002E6C23E4A6 -:10064000071E0000034B2F80081E07F03F02022503 -:100650000118000000000000011800040000000064 -:1006600001180008000000000118000C0000000044 -:100670000118001000000000011800140000000024 -:1006800002180020000000010218002400000002EF -:1006900002180028000000030218002C00000000CF -:1006A00002180030000000040218003400000001AD -:1006B00002180038000000000218003C0000000191 -:1006C000021800400000000402180044000000006E -:1006D00002180048000000010218004C000000034E -:1006E0000218005000000000021800540000000131 -:1006F00002180058000000040218005C000000000E -:1007000002180060000000010218006400000003ED -:1007100002180068000000000218006C00000001D0 -:1007200002180070000000040218007400000000AD -:1007300002180078000000040218007C000000038A -:100740000618008000000002021800A400007FFFCD -:10075000021800A8000003FF021802240000000095 -:1007600002180234000000000218024C00000000D1 -:10077000021802E4000000FF061810000000040048 -:10078000021B8BC000000001021B8000000000342F -:10079000021B804000000018021B80800000000C3B -:1007A000021B80C0000000200C1B83000008647046 -:1007B0000A1B8300000001570B1B83000000055F2C -:1007C0000A1B8340000000000C1B8340000002262F -:1007D0000B1B834000000001021B83800008647033 -:1007E000021B83C000000226021B148000000001CF -:1007F0000A1B148000000000021B9440000000014E -:10080000061B944800000002061A1000000002B304 -:10081000041A1ACC00010227061A1AD00000000898 -:10082000061A2008000000C8061A20000000000276 -:10083000041A1BF800900228061A3718000000045A -:10084000061A371000000002061A500000000002CD -:10085000061A500800000004061A50180000000490 -:10086000061A502800000004061A50380000000440 -:10087000061A504800000004061A505800000004F0 -:10088000061A506800000004061A507800000002A2 -:10089000041A52C0000202B8061A405000000006B6 -:1008A000041A4068000202BA041A4040000402BC64 -:1008B000041A8000000102C0061A80040000000330 -:1008C000041A8010000102C1061A801400000003FF -:1008D000041A8020000102C2061A802400000003CE -:1008E000041A8030000102C3061A8034000000039D -:1008F000041A8040000102C4061A8044000000036C -:10090000041A8050000102C5061A8054000000033A -:10091000041A8060000102C6061A80640000000309 -:10092000041A8070000102C7061A807400000003D8 -:10093000041A8080000102C8061A808400000003A7 -:10094000041A8090000102C9061A80940000000376 -:10095000041A80A0000102CA061A80A40000000345 -:10096000041A80B0000102CB061A80B40000000314 -:10097000041A80C0000102CC061A80C400000003E3 -:10098000041A80D0000102CD061A80D400000003B2 -:10099000041A80E0000102CE061A80E40000000381 -:1009A000041A80F0000102CF061A80F40000000350 -:1009B000041A8100000102D0061A8104000000031D -:1009C000041A8110000102D1061A811400000003EC -:1009D000041A8120000102D2061A812400000003BB -:1009E000041A8130000102D3061A8134000000038A -:1009F000041A8140000102D4061A81440000000359 -:100A0000041A8150000102D5061A81540000000327 -:100A1000041A8160000102D6061A816400000003F6 -:100A2000041A8170000102D7061A817400000003C5 -:100A3000041A8180000102D8061A81840000000394 -:100A4000041A8190000102D9061A81940000000363 -:100A5000041A81A0000102DA061A81A40000000332 -:100A6000041A81B0000102DB061A81B40000000301 -:100A7000041A81C0000102DC061A81C400000003D0 -:100A8000041A81D0000102DD061A81D4000000039F -:100A9000041A81E0000102DE061A81E4000000036E -:100AA000041A81F0000102DF061A81F4000000033D -:100AB000041A8200000102E0061A8204000000030A -:100AC000041A8210000102E1061A821400000003D9 -:100AD000041A8220000102E2061A822400000003A8 -:100AE000041A8230000102E3061A82340000000377 -:100AF000041A8240000102E4061A82440000000346 -:100B0000041A8250000102E5061A82540000000314 -:100B1000041A8260000102E6061A826400000003E3 -:100B2000041A8270000102E7061A827400000003B2 -:100B3000041A8280000102E8061A82840000000381 -:100B4000041A8290000102E9061A82940000000350 -:100B5000041A82A0000102EA061A82A4000000031F -:100B6000041A82B0000102EB061A82B400000003EE -:100B7000041A82C0000102EC061A82C400000003BD -:100B8000041A82D0000102ED061A82D4000000038C -:100B9000041A82E0000102EE061A82E4000000035B -:100BA000041A82F0000102EF061A82F4000000032A -:100BB000041A8300000102F0061A830400000003F7 -:100BC000041A8310000102F1061A831400000003C6 -:100BD000041A8320000102F2061A83240000000395 -:100BE000041A8330000102F3061A83340000000364 -:100BF000041A8340000102F4061A83440000000333 -:100C0000041A8350000102F5061A83540000000301 -:100C1000041A8360000102F6061A836400000003D0 -:100C2000041A8370000102F7061A8374000000039F -:100C3000041A8380000102F8061A8384000000036E -:100C4000041A8390000102F9061A8394000000033D -:100C5000041A83A0000102FA061A83A4000000030C -:100C6000041A83B0000102FB061A83B400000003DB -:100C7000041A83C0000102FC061A83C400000003AA -:100C8000041A83D0000102FD061A83D40000000379 -:100C9000041A83E0000102FE061A83E40000000348 -:100CA000041A83F0000102FF061A83F40000000317 -:100CB000041A840000010300061A840400000003E3 -:100CC000041A841000010301061A841400000003B2 -:100CD000041A842000010302061A84240000000381 -:100CE000041A843000010303061A84340000000350 -:100CF000041A844000010304061A8444000000031F -:100D0000041A845000010305061A845400000003ED -:100D1000041A846000010306061A846400000003BC -:100D2000041A847000010307061A8474000000038B -:100D3000041A848000010308061A8484000000035A -:100D4000041A849000010309061A84940000000329 -:100D5000041A84A00001030A061A84A400000003F8 -:100D6000041A84B00001030B061A84B400000003C7 -:100D7000041A84C00001030C061A84C40000000396 -:100D8000041A84D00001030D061A84D40000000365 -:100D9000041A84E00001030E061A84E40000000334 -:100DA000041A84F00001030F061A84F40000000303 -:100DB000041A850000010310061A850400000003D0 -:100DC000041A851000010311061A8514000000039F -:100DD000041A852000010312061A8524000000036E -:100DE000041A853000010313061A8534000000033D -:100DF000041A854000010314061A8544000000030C -:100E0000041A855000010315061A855400000003DA -:100E1000041A856000010316061A856400000003A9 -:100E2000041A857000010317061A85740000000378 -:100E3000041A858000010318061A85840000000347 -:100E4000041A859000010319061A85940000000316 -:100E5000041A85A00001031A061A85A400000003E5 -:100E6000041A85B00001031B061A85B400000003B4 -:100E7000041A85C00001031C061A85C40000000383 -:100E8000041A85D00001031D061A85D40000000352 -:100E9000041A85E00001031E061A85E40000000321 -:100EA000041A85F00001031F061A85F400000003F0 -:100EB000041A860000010320061A860400000003BD -:100EC000041A861000010321061A8614000000038C -:100ED000041A862000010322061A8624000000035B -:100EE000041A863000010323061A8634000000032A -:100EF000041A864000010324061A864400000003F9 -:100F0000041A865000010325061A865400000003C7 -:100F1000041A866000010326061A86640000000396 -:100F2000041A867000010327061A86740000000365 -:100F3000041A868000010328061A86840000000334 -:100F4000041A869000010329061A86940000000303 -:100F5000041A86A00001032A061A86A400000003D2 -:100F6000041A86B00001032B061A86B400000003A1 -:100F7000041A86C00001032C061A86C40000000370 -:100F8000041A86D00001032D061A86D4000000033F -:100F9000041A86E00001032E061A86E4000000030E -:100FA000041A86F00001032F061A86F400000003DD -:100FB000041A870000010330061A870400000003AA -:100FC000041A871000010331061A87140000000379 -:100FD000041A872000010332061A87240000000348 -:100FE000041A873000010333061A87340000000317 -:100FF000041A874000010334061A874400000003E6 -:10100000041A875000010335061A875400000003B4 -:10101000041A876000010336061A87640000000383 -:10102000041A877000010337061A87740000000352 -:10103000041A878000010338061A87840000000321 -:10104000041A879000010339061A879400000003F0 -:10105000041A87A00001033A061A87A400000003BF -:10106000041A87B00001033B061A87B4000000038E -:10107000041A87C00001033C061A87C4000000035D -:10108000041A87D00001033D061A87D4000000032C -:10109000041A87E00001033E061A87E400000003FB -:1010A000041A87F00001033F061A87F400000003CA -:1010B000041A880000010340061A88040000000397 -:1010C000041A881000010341061A88140000000366 -:1010D000041A882000010342061A88240000000335 -:1010E000041A883000010343061A88340000000304 -:1010F000041A884000010344061A884400000003D3 -:10110000041A885000010345061A885400000003A1 -:10111000041A886000010346061A88640000000370 -:10112000041A887000010347061A8874000000033F -:10113000041A888000010348061A8884000000030E -:10114000041A889000010349061A889400000003DD -:10115000041A88A00001034A061A88A400000003AC -:10116000041A88B00001034B061A88B4000000037B -:10117000041A88C00001034C061A88C4000000034A -:10118000041A88D00001034D061A88D40000000319 -:10119000041A88E00001034E061A88E400000003E8 -:1011A000041A88F00001034F061A88F400000003B7 -:1011B000041A890000010350061A89040000000384 -:1011C000041A891000010351061A89140000000353 -:1011D000041A892000010352061A89240000000322 -:1011E000041A893000010353061A893400000003F1 -:1011F000041A894000010354061A894400000003C0 -:10120000041A895000010355061A8954000000038E -:10121000041A896000010356061A8964000000035D -:10122000041A897000010357061A8974000000032C -:10123000041A898000010358061A898400000003FB -:10124000041A899000010359061A899400000003CA -:10125000041A89A00001035A061A89A40000000399 -:10126000041A89B00001035B061A89B40000000368 -:10127000041A89C00001035C061A89C40000000337 -:10128000041A89D00001035D061A89D40000000306 -:10129000041A89E00001035E061A89E400000003D5 -:1012A000041A89F00001035F061A89F400000003A4 -:1012B000041A8A0000010360061A8A040000000371 -:1012C000041A8A1000010361061A8A140000000340 -:1012D000041A8A2000010362061A8A24000000030F -:1012E000041A8A3000010363061A8A3400000003DE -:1012F000041A8A4000010364061A8A4400000003AD -:10130000041A8A5000010365061A8A54000000037B -:10131000041A8A6000010366061A8A64000000034A -:10132000041A8A7000010367061A8A740000000319 -:10133000041A8A8000010368061A8A8400000003E8 -:10134000041A8A9000010369061A8A9400000003B7 -:10135000041A8AA00001036A061A8AA40000000386 -:10136000041A8AB00001036B061A8AB40000000355 -:10137000041A8AC00001036C061A8AC40000000324 -:10138000041A8AD00001036D061A8AD400000003F3 -:10139000041A8AE00001036E061A8AE400000003C2 -:1013A000041A8AF00001036F061A8AF40000000391 -:1013B000041A8B0000010370061A8B04000000035E -:1013C000041A8B1000010371061A8B14000000032D -:1013D000041A8B2000010372061A8B2400000003FC -:1013E000041A8B3000010373061A8B3400000003CB -:1013F000041A8B4000010374061A8B44000000039A -:10140000041A8B5000010375061A8B540000000368 -:10141000041A8B6000010376061A8B640000000337 -:10142000041A8B7000010377061A8B740000000306 -:10143000041A8B8000010378061A8B8400000003D5 -:10144000041A8B9000010379061A8B9400000003A4 -:10145000041A8BA00001037A061A8BA40000000373 -:10146000041A8BB00001037B061A8BB40000000342 -:10147000041A8BC00001037C061A8BC40000000311 -:10148000041A8BD00001037D061A8BD400000003E0 -:10149000041A8BE00001037E061A8BE400000003AF -:1014A000041A8BF00001037F061A8BF4000000037E -:1014B000041A8C0000010380061A8C04000000034B -:1014C000041A8C1000010381061A8C14000000031A -:1014D000041A8C2000010382061A8C2400000003E9 -:1014E000041A8C3000010383061A8C3400000003B8 -:1014F000041A8C4000010384061A8C440000000387 -:10150000041A8C5000010385061A8C540000000355 -:10151000041A8C6000010386061A8C640000000324 -:10152000041A8C7000010387061A8C7400000003F3 -:10153000041A8C8000010388061A8C8400000003C2 -:10154000041A8C9000010389061A8C940000000391 -:10155000041A8CA00001038A061A8CA40000000360 -:10156000041A8CB00001038B061A8CB4000000032F -:10157000041A8CC00001038C061A8CC400000003FE -:10158000041A8CD00001038D061A8CD400000003CD -:10159000041A8CE00001038E061A8CE4000000039C -:1015A000041A8CF00001038F061A8CF4000000036B -:1015B000041A8D0000010390061A8D040000000338 -:1015C000041A8D1000010391061A8D140000000307 -:1015D000041A8D2000010392061A8D2400000003D6 -:1015E000041A8D3000010393061A8D3400000003A5 -:1015F000041A8D4000010394061A8D440000000374 -:10160000041A8D5000010395061A8D540000000342 -:10161000041A8D6000010396061A8D640000000311 -:10162000041A8D7000010397061A8D7400000003E0 -:10163000041A8D8000010398061A8D8400000003AF -:10164000041A8D9000010399061A8D94000000037E -:10165000041A8DA00001039A061A8DA4000000034D -:10166000041A8DB00001039B061A8DB4000000031C -:10167000041A8DC00001039C061A8DC400000003EB -:10168000041A8DD00001039D061A8DD400000003BA -:10169000041A8DE00001039E061A8DE40000000389 -:1016A000041A8DF00001039F061A8DF40000000358 -:1016B000041A8E00000103A0061A8E040000000325 -:1016C000041A8E10000103A1061A8E1400000003F4 -:1016D000041A8E20000103A2061A8E2400000003C3 -:1016E000041A8E30000103A3061A8E340000000392 -:1016F000041A8E40000103A4061A8E440000000361 -:10170000041A8E50000103A5061A8E54000000032F -:10171000041A8E60000103A6061A8E6400000003FE -:10172000041A8E70000103A7061A8E7400000003CD -:10173000041A8E80000103A8061A8E84000000039C -:10174000041A8E90000103A9061A8E94000000036B -:10175000041A8EA0000103AA061A8EA4000000033A -:10176000041A8EB0000103AB061A8EB40000000309 -:10177000041A8EC0000103AC061A8EC400000003D8 -:10178000041A8ED0000103AD061A8ED400000003A7 -:10179000041A8EE0000103AE061A8EE40000000376 -:1017A000041A8EF0000103AF061A8EF40000000345 -:1017B000041A8F00000103B0061A8F040000000312 -:1017C000041A8F10000103B1061A8F1400000003E1 -:1017D000041A8F20000103B2061A8F2400000003B0 -:1017E000041A8F30000103B3061A8F34000000037F -:1017F000041A8F40000103B4061A8F44000000034E -:10180000041A8F50000103B5061A8F54000000031C -:10181000041A8F60000103B6061A8F6400000003EB -:10182000041A8F70000103B7061A8F7400000003BA -:10183000041A8F80000103B8061A8F840000000389 -:10184000041A8F90000103B9061A8F940000000358 -:10185000041A8FA0000103BA061A8FA40000000327 -:10186000041A8FB0000103BB061A8FB400000003F6 -:10187000041A8FC0000103BC061A8FC400000003C5 -:10188000041A8FD0000103BD061A8FD40000000394 -:10189000041A8FE0000103BE061A8FE4000000075F -:1018A000041A62C0002003BF061A1AF000000042AA -:1018B000061AAF0000000008061AE000000005400C -:1018C000061AD00000000072061AD248000000106C -:1018D000061AD6B000000020061AD470000000904E -:1018E000061AD46800000002061AA000000001C415 -:1018F000061A300000000010061A308000000010A8 -:10190000061A310000000010061A31800000001095 -:10191000061A330000000012061A3390000000700F -:10192000061AD45800000002061AD348000000022C -:10193000061AD35800000020061AA710000001C4A0 -:10194000061A304000000010061A30C000000010D7 -:10195000061A314000000010061A31C000000010C5 -:10196000061A334800000012061A355000000070B5 -:10197000061AD46000000002061AD35000000002CC -:10198000061AD3D800000020021AAE200000000082 -:10199000061A500000000002061A508000000012D3 -:1019A000041A4000000203DF041A63C0000203E1CE -:1019B000061A700000000004061A32000000000839 -:1019C000021AAE2400000000061A501000000002A7 -:1019D000061A50C800000012041A4008000203E36F -:1019E000041A63C8000203E5061A70100000000420 -:1019F000061A322000000008021AAE28000000007B -:101A0000061A502000000002061A511000000012B1 -:101A1000041A4010000203E7041A63D0000203E92D -:101A2000061A702000000004061A32400000000868 -:101A3000021AAE2C00000000061A5030000000020E -:101A4000061A515800000012041A4018000203EB55 -:101A5000041A63D8000203ED061A70300000000477 -:101A6000061A326000000008021AAE3000000000C2 -:101A7000061A504000000002061A51A00000001291 -:101A8000041A4020000203EF041A63E0000203F18D -:101A9000061A704000000004061A32800000000898 -:101AA000021AAE3400000000061A50500000000276 -:101AB000061A51E800000012041A4028000203F33D -:101AC000041A63E8000203F5061A705000000004CF -:101AD000061A32A000000008021AAE38000000000A -:101AE000061A506000000002061A52300000001270 -:101AF000041A4030000203F7041A63F0000203F9ED -:101B0000061A706000000004061A32C000000008C7 -:101B1000021AAE3C00000000061A507000000002DD -:101B2000061A527800000012041A4038000203FB23 -:101B3000041A63F8000203FD061A70700000000426 -:101B4000061A32E0000000080200A2A40000020908 -:101B50000200A270000000000200A2740000000059 -:101B60000200A270000000000200A2740000000049 -:101B70000200A270000000000200A2740000000039 -:101B80000200A270000000000200A2740000000029 -:101B9000020100B400000001020100B800000001D1 -:101BA000020100CC00000001020100D00000000191 -:101BB000020100DC00000001020101000000000140 -:101BC00002010104000000010201007C003000005D -:101BD00002010084000000280201008C00000000C7 -:101BE00002010130000000040201025C000000015B -:101BF0000201032800000000020160580000FFFFFE -:101C0000020160700000000702010554000000306E -:101C1000020100C400000001020100F80000000100 -:101C2000020100F00000000102010080003000000D -:101C3000020100880000002802010090000000005E -:101C40000201013400000004020102DC0000000176 -:101C50000201032C000000000201605C0000FFFF95 -:101C600002016074000000070201056400000030FA -:101C7000020100C800000001020100FC0000000198 -:101C8000020100F400000001020C10000000002816 -:101C9000020C200800000211020C200C00000200BF -:101CA000020C201000000204020C201C0000FFFFA8 -:101CB000020C20200000FFFF020C20240000FFFF88 -:101CC000020C20280000FFFF020C2038000000005A -:101CD000020C203C00000037020C204000000021D4 -:101CE000020C204400000020060C20480000001DCB -:101CF000020C20BC00000001060C20C00000003FC8 -:101D0000020C21BC00000001020C21C000000001F7 -:101D1000020C21C400000001060C21C80000001CB8 -:101D2000020C223807FFFFFF020C223C0000007F5C -:101D3000020C224007FFFFFF020C22440000003F7C -:101D4000010C224800000000010C224C00000000A1 -:101D5000010C225000000000010C22540000000081 -:101D6000010C225800000000010C225C0000000061 -:101D7000010C226000000000010C22640000000041 -:101D8000010C226800000000010C226C0000000021 -:101D9000010C227000000000010C22740000000001 -:101DA000010C227800000000010C227C00000000E1 -:101DB000020C22D80000FFFF020C22DC0000FFFF13 -:101DC000020C22E00000FFFF020C22E40000FFFFF3 -:101DD0000C0C2000000003E80A0C200000000001A9 -:101DE0000B0C200000000003020C40080000101142 -:101DF000020C400C00001000020C40100000100407 -:101E0000020C401400001021020C401C0000FFFFD7 -:101E1000020C40200000FFFF020C40240000FFFFE6 -:101E2000020C40280000FFFF020C40380000004672 -:101E3000020C403C0000000C060C40400000000278 -:101E4000020C404800000018020C404C000000F05A -:101E5000060C40500000001F020C40CC00000001A6 -:101E6000060C40D00000003A020C41B8000000010E -:101E7000060C41BC00000003020C41C80000000138 -:101E8000020C41CC00000001060C41D00000001AF9 -:101E9000020C423807FFFFFF020C423C0000007FAB -:101EA000020C424007FFFFFF020C42440000003FCB -:101EB000010C424800000000010C424C00000000F0 -:101EC000010C425000000000010C425400000000D0 -:101ED000010C425800000000010C425C00000000B0 -:101EE000010C426000000000010C42640000000090 -:101EF000010C426800000000010C426C0000000070 -:101F0000010C427000000000010C4274000000004F -:101F1000010C427800000000010C427C000000002F -:101F2000010C428000000000020C42D80000FFFFBC -:101F3000020C42DC0000FFFF020C42E00000FFFF49 -:101F4000020C42E40000FFFF0C0C4000000003E81C -:101F50000A0C4000000000010B0C400000000003D0 -:101F6000060D400000000A00020D0044000000328F -:101F7000020D008C02150020020D009002150020B9 -:101F8000020D009408100000020D009800000036B9 -:101F9000020D00A000000000020D00A400000004DB -:101FA000020D00A800000004060D00AC00000002B5 -:101FB000020D00B800000002020D00C00000000188 -:101FC000020D00C800000002020D00CC000000025B -:101FD000020D015C00000001020D0164000000011F -:101FE000020D016800000002020D02040000000161 -:101FF000020D020C00000020020D02100000004043 -:10200000020D021400000040020D02200000000337 -:10201000020D022400000018060D028000000012CC -:10202000040D0300001803FF060D03600000000C00 -:10203000020D004C00000001020D005000000002E3 -:10204000020D005400000000020D005800000008BE -:10205000060D005C00000004020D00C40000000436 -:10206000020D000400000001020D00080000000144 -:10207000020D000C00000001020D00100000000124 -:10208000020D001400000001020D00180000000104 -:10209000020D001C00000001020D002000000001E4 -:1020A000020D002400000001020D002800000001C4 -:1020B000020D002C00000001020D003000000001A4 -:1020C000020D003400000001020D00380000000184 -:1020D000020D003C00000001020D01140000000987 -:1020E000020D011C0000000A020D01240000000086 -:1020F000020D012C00000000020D01340000000060 -:10210000020D013C0000000B020D01440000000024 -:10211000020D011800000029020D01200000002A14 -:10212000020D012800000020020D013000000020F7 -:10213000020D013800000020020D01400000002BBC -:10214000020D014800000020020D011400000019DA -:10215000020D011C0000001A020D012400000010F5 -:10216000020D012C00000010020D013400000010CF -:10217000020D013C0000001B020D01440000001094 -:10218000020D011800000039020D01200000003A84 -:10219000020D012800000030020D01300000003067 -:1021A000020D013800000030020D01400000003B2C -:1021B000020D014800000030020D0114000000492A -:1021C000020D011C0000004A020D01240000004025 -:1021D000020D012C00000040020D013400000040FF -:1021E000020D013C0000004B020D014400000040C4 -:1021F000020D011800000069020D01200000006AB4 -:10220000020D012800000060020D01300000006096 -:10221000020D013800000060020D01400000006B5B -:10222000020D014800000060020D01140000005979 -:10223000020D011C0000005A020D01240000005094 -:10224000020D012C00000050020D0134000000506E -:10225000020D013C0000005B020D01440000005033 -:10226000020D011800000079020D01200000007A23 -:10227000020D012800000070020D01300000007006 -:10228000020D013800000070020D01400000007BCB -:10229000020D014800000070060E2000000008003A -:1022A000020E004C00000032020E009402150020C5 -:1022B000020E009802150020020E009C0000003063 -:1022C000020E00A008100000020E00A4000000365C -:1022D000020E00A800000030020E00AC0000003129 -:1022E000020E00B400000003020E00B8000000005F -:1022F000020E00C400000000020E00CC0000000628 -:10230000020E00D800000001020E0144000000018E -:10231000020E014C00000001020E015000000002FC -:10232000020E020400000001020E020C0000004038 -:10233000020E021000000040020E021C0000000409 -:10234000020E022000000020020E02240000000EF7 -:10235000020E02280000001B060E030000000012FF -:10236000040E0280001B0417060E02EC000000059C -:10237000020E00540000000C020E00580000000C79 -:10238000020E005C00000000020E00600000001061 -:10239000020E006400000010060E0068000000033A -:1023A000020E00DC00000003020E00040000000129 -:1023B000020E000800000001020E000C00000001E7 -:1023C000020E001000000001020E001400000001C7 -:1023D000020E001800000001020E001C00000001A7 -:1023E000020E002000000001020E00240000000187 -:1023F000020E002800000001020E002C0000000167 -:10240000020E003000000001020E00340000000146 -:10241000020E003800000001020E003C0000000126 -:10242000020E004000000001020E00440000000106 -:10243000020E01100000000F020E01180000000043 -:10244000020E012000000000020E01280000000022 -:10245000020E01140000002F020E011C00000020DB -:10246000020E012400000020020E012C00000020BA -:10247000020E01100000001F020E011800000010E3 -:10248000020E012000000010020E012800000010C2 -:10249000020E01140000003F020E011C000000307B -:1024A000020E012400000030020E012C000000305A -:1024B000020E01100000004F020E01180000004043 -:1024C000020E012000000040020E01280000004022 -:1024D000020E01140000006F020E011C00000060DB -:1024E000020E012400000060020E012C00000060BA -:1024F000020E01100000005F020E011800000050E3 -:10250000020E012000000050020E012800000050C1 -:10251000020E01140000007F020E011C000000707A -:10252000020E012400000070020E012C0000007059 -:102530000730040000D60000083007D80005043238 -:10254000073400003222000007348000312C0C894F -:102550000735000038DD18D5073580002F16270D08 -:1025600007360000261532D30836711031DE0434E8 -:1025700001300000000000000130000400000000F5 -:1025800001300008000000000130000C00000000D5 -:1025900001300010000000000130001400000000B5 -:1025A0000230002000000001023000240000000280 -:1025B00002300028000000030230002C0000000060 -:1025C000023000300000000402300034000000013E -:1025D00002300038000000000230003C0000000122 -:1025E00002300040000000040230004400000000FF -:1025F00002300048000000010230004C00000003DF -:1026000002300050000000000230005400000001C1 -:1026100002300058000000040230005C000000009E -:10262000023000600000000102300064000000037E -:1026300002300068000000000230006C0000000161 -:10264000023000700000000402300074000000003E -:1026500002300078000000040230007C000000031B -:102660000630008000000002023000A400007FFF5E -:10267000023000A8000003FF023002240000000026 -:1026800002300234000000000230024C0000000062 -:10269000023002E40000FFFF0630200000000800C6 -:1026A00002338BC000000001023380000000001ADA -:1026B000023380400000004E023380800000001092 -:1026C000023380C0000000200C33830000086470D7 -:1026D0000A338300000001570B3383000000055FBD -:1026E0000A338340000000000C33834000000226C0 -:1026F0000B338340000000010233838000086470C4 -:10270000023383C00000022602331480000000015F -:102710000A3314800000000006328000000001022D -:1027200006322008000000C8063220000000000227 -:1027300004328520008F04360632875C00000009D1 -:1027400006323EB00000000606323ED00000000215 -:1027500006323E800000000A04323EA8000204C592 -:1027600006323E0000000020063250000000094002 -:102770000632400000000004043294C0000204C786 -:1027800006324110000000020632D0000000007046 -:102790000632DB00000000D40632DEA0000000029A -:1027A0000632E00000000800063324000000011893 -:1027B00006321000000001880632500000000020A0 -:1027C00006325100000000200632520000000020B6 -:1027D00006325300000000200632540000000020A2 -:1027E000063255000000002006325600000000208E -:1027F000063257000000002006325800000000207A -:10280000063259000000002006325A000000002065 -:1028100006325B000000002006325C000000002051 -:1028200006325D000000002006325E00000000203D -:1028300006325F0000000020063284F00000000233 -:1028400004328500000204C9063285080000000237 -:102850000632DE90000000020633286000000118F6 -:102860000632162000000188063250800000002049 -:102870000632518000000020063252800000002005 -:1028800006325380000000200632548000000020F1 -:1028900006325580000000200632568000000020DD -:1028A00006325780000000200632588000000020C9 -:1028B000063259800000002006325A8000000020B5 -:1028C00006325B800000002006325C8000000020A1 -:1028D00006325D800000002006325E80000000208D -:1028E00006325F8000000020063284F800000002FB -:1028F00004328510000204CB063285180000000265 -:102900000632DE980000000202328450000000000F -:102910000632401000000002023284540000000021 -:1029200006324020000000020232845800000000FD -:1029300006324030000000020232845C00000000D9 -:1029400006324040000000020232846000000000B5 -:102950000632405000000002023284640000000091 -:10296000063240600000000202328468000000006D -:1029700006324070000000020232846C0000000049 -:1029800006324080000000020720040000730000AF -:1029900008200780001004CD072400002AD500007D -:1029A0000724800027740AB60824D36063FA04CF92 -:1029B00001200000000000000120000400000000D1 -:1029C00001200008000000000120000C00000000B1 -:1029D0000120001000000000012000140000000091 -:1029E000022000200000000102200024000000025C -:1029F00002200028000000030220002C000000003C -:102A00000220003000000004022000340000000119 -:102A100002200038000000000220003C00000001FD -:102A200002200040000000040220004400000000DA -:102A300002200048000000010220004C00000003BA -:102A4000022000500000000002200054000000019D -:102A500002200058000000040220005C000000007A -:102A6000022000600000000102200064000000035A -:102A700002200068000000000220006C000000013D -:102A8000022000700000000402200074000000001A -:102A900002200078000000040220007C00000003F7 -:102AA0000620008000000002022000A400007FFF3A -:102AB000022000A8000003FF022002240000000002 -:102AC00002200234000000000220024C000000003E -:102AD000022002E40000FFFF0620200000000800A2 -:102AE00002238BC0000000010223800000000010C0 -:102AF000022380400000001202238080000000308A -:102B0000022380C00000000E0C23830000086470C4 -:102B10000A238300000001570B2383000000055F98 -:102B20000A238340000000000C238340000002269B -:102B30000B2383400000000102238380000864709F -:102B4000022383C00000022602231480000000013B -:102B50000A2314800000000006221000000000423A -:102B600006222008000000C8062220000000000203 -:102B70000622B000000003300622F40000000053DB -:102B80000422F54C000104D10622F5500000000398 -:102B90000422F55C000104D20622F5600000000367 -:102BA0000422F56C000104D30622F5700000000336 -:102BB0000422F57C000104D40622F5800000000305 -:102BC0000422F58C000104D50622F59000000003D4 -:102BD0000422F59C000104D60622F5A000000003A3 -:102BE0000422F5AC000104D70622F5B00000000372 -:102BF0000422F5BC000104D80622F5C000000046FE -:102C00000622E2000000044004221240009004D991 -:102C100006223000000000C006226700000001000C -:102C2000062290000000040004226B0800200569C1 -:102C3000062211F000000006042212080006058991 -:102C4000062212200000000206224000000005C0FB -:102C50000622C000000000060422C0180006058FEE -:102C60000622C0300000000A0422C0580006059564 -:102C70000622C0700000000A0422C0980006059BCE -:102C80000622C0B00000000A0422C0D8000605A138 -:102C90000622C0F00000000A0422C118000605A7A1 -:102CA0000622C1300000000A0422C158000605AD0A -:102CB0000622C1700000000A0422C198000605B374 -:102CC0000622C1B00000000A0422C1D8000605B9DE -:102CD0000622C1F00000000A0422C218000605BF47 -:102CE0000622C2300000000A0422C258000605C5B0 -:102CF0000622C2700000000A0422C298000605CB1A -:102D00000622C2B00000000A0422C2D8000605D183 -:102D10000622C2F00000000A0422C318000605D7EC -:102D20000622C3300000000A0422C358000605DD55 -:102D30000622C3700000000A0422C398000605E3BF -:102D40000622C3B00000000A0422C3D8000605E929 -:102D50000622C3F00000000A0422C418000605EF92 -:102D60000622C4300000000A0422C458000605F5FB -:102D70000622C4700000000A0422C498000605FB65 -:102D80000622C4B00000000A0422C4D800060601CE -:102D90000622C4F00000000A0422C5180006060737 -:102DA0000622C5300000000A0422C5580006060DA0 -:102DB0000622C5700000000A0422C598000606130A -:102DC0000622C5B00000000A0422C5D80006061974 -:102DD0000622C5F00000000A0422C6180006061FDD -:102DE0000622C6300000000A0422C6580006062546 -:102DF0000622C6700000000A0422C6980006062BB0 -:102E00000622C6B00000000A0422C6D80006063119 -:102E10000622C6F00000000A0422C7180006063782 -:102E20000622C7300000000A0422C7580006063DEB -:102E30000622C7700000000A0422C7980006064355 -:102E40000622C7B00000000A0422C7D800060649BF -:102E50000622C7F00000000A0422C8180006064F28 -:102E60000622C8300000000A0422C8580006065591 -:102E70000622C8700000000A0422C8980006065BFB -:102E80000622C8B00000000A0422C8D80006066165 -:102E90000622C8F00000000A0422C91800060667CE -:102EA0000622C9300000000A0422C9580006066D37 -:102EB0000622C9700000000A0422C99800060673A1 -:102EC0000622C9B00000000A0422C9D8000606790B -:102ED0000622C9F00000000A0422CA180006067F74 -:102EE0000622CA300000000A0422CA5800060685DD -:102EF0000622CA700000000A0422CA980006068B47 -:102F00000622CAB00000000A0422CAD800060691B0 -:102F10000622CAF00000000A0422CB180006069719 -:102F20000622CB300000000A0422CB580006069D82 -:102F30000622CB700000000A0422CB98000606A3EC -:102F40000622CBB00000000A0422CBD8000606A956 -:102F50000622CBF00000000A0422CC18000606AFBF -:102F60000622CC300000000A0422CC58000606B528 -:102F70000622CC700000000A0422CC98000606BB92 -:102F80000622CCB00000000A0422CCD8000606C1FC -:102F90000622CCF00000000A0422CD18000606C765 -:102FA0000622CD300000000A0422CD58000606CDCE -:102FB0000622CD700000000A0422CD98000606D338 -:102FC0000622CDB00000000A0422CDD8000606D9A2 -:102FD0000622CDF00000000A0422CE18000606DF0B -:102FE0000622CE300000000A0422CE58000606E574 -:102FF0000622CE700000000A0422CE98000606EBDE -:103000000622CEB00000000A0422CED8000606F147 -:103010000622CEF00000000A0422CF18000606F7B0 -:103020000622CF300000000A0422CF58000606FD19 -:103030000622CF700000000A0422CF980006070382 -:103040000622CFB00000000A0422CFD800060709EC -:103050000622CFF00000000A0422D0180006070F55 -:103060000622D0300000000A0422D05800060715BE -:103070000622D0700000000A0422D0980006071B28 -:103080000622D0B00000000A0422D0D80006072192 -:103090000622D0F00000000A0422D11800060727FB -:1030A0000622D1300000000A0422D1580006072D64 -:1030B0000622D1700000000A0422D19800060733CE -:1030C0000622D1B00000000A0422D1D80006073938 -:1030D0000622D1F00000000A0422D2180006073FA1 -:1030E0000622D2300000000A0422D258000607450A -:1030F0000622D2700000000A0422D2980006074B74 -:103100000622D2B00000000A0422D2D800060751DD -:103110000622D2F00000000A0422D3180006075746 -:103120000622D3300000000A0422D3580006075DAF -:103130000622D3700000000A0422D3980006076319 -:103140000622D3B00000000A0422D3D80006076983 -:103150000622D3F00000000A0422D4180006076FEC -:103160000622D4300000000A0422D4580006077555 -:103170000622D4700000000A0422D4980006077BBF -:103180000622D4B00000000A0422D4D80006078129 -:103190000622D4F00000000A0422D5180006078792 -:1031A0000622D5300000000A0422D5580006078DFB -:1031B0000622D5700000000A0422D5980006079365 -:1031C0000622D5B00000000A0422D5D800060799CF -:1031D0000622D5F00000000A0422D6180006079F38 -:1031E0000622D6300000000A0422D658000607A5A1 -:1031F0000622D6700000000A0422D698000607AB0B -:103200000622D6B00000000A0422D6D8000607B174 -:103210000622D6F00000000A0422D718000607B7DD -:103220000622D7300000000A0422D758000607BD46 -:103230000622D7700000000A0422D798000607C3B0 -:103240000622D7B00000000A0422D7D8000607C91A -:103250000622D7F00000000A0422D818000607CF83 -:103260000622D8300000000A0422D858000607D5EC -:103270000622D8700000000A0422D898000607DB56 -:103280000622D8B00000000A0422D8D8000607E1C0 -:103290000622D8F00000000A0422D918000607E729 -:1032A0000622D9300000000A0422D958000607ED92 -:1032B0000622D9700000000A0422D998000607F3FC -:1032C0000622D9B00000000A0422D9D8000607F966 -:1032D0000622D9F00000000A0422DA18000607FFCF -:1032E0000622DA300000000A0422DA580006080537 -:1032F0000622DA700000000A0422DA980006080BA1 -:103300000622DAB00000000A0422DAD8000608110A -:103310000622DAF00000000A0422DB180006081773 -:103320000622DB300000000A0422DB580006081DDC -:103330000622DB700000000A0422DB980006082346 -:103340000622DBB00000000A0422DBD800060829B0 -:103350000622DBF00000000A0422DC180006082F19 -:103360000622DC300000000A0422DC580006083582 -:103370000622DC700000000A0422DC980006083BEC -:103380000622DCB00000000A0422DCD80006084156 -:103390000622DCF00000000A0422DD1800060847BF -:1033A0000622DD300000000A0422DD580006084D28 -:1033B0000622DD700000000A0422DD980006085392 -:1033C0000622DDB00000000A0422DDD800060859FC -:1033D0000622DDF00000000A0422DE180006085F65 -:1033E0000622DE300000000A0422DE5800060865CE -:1033F0000622DE700000000A0422DE980006086B38 -:103400000622DEB00000000A0422DED800060871A1 -:103410000622DEF00000000A0422DF18000608770A -:103420000622DF300000000A0422DF580006087D73 -:103430000622DF700000000A0422DF9800060883DD -:103440000622DFB00000000A0422DFD80006088947 -:103450000622DFF00000000A0422E0180006088FB0 -:103460000622E0300000000A0422E0580006089519 -:103470000622E0700000000A0422E0980006089B83 -:103480000622E0B00000000A0422E0D8000608A1ED -:103490000622E0F00000000A0422E118000608A756 -:1034A0000622E1300000000A0422E158000608ADBF -:1034B0000622E1700000000A0422E198000608B329 -:1034C0000622E1B00000000A0422E1D8000608B993 -:1034D0000622E1F000000004062215380000000278 -:1034E000062211E8000000020622F3000000000896 -:1034F00002221148000000000622590000000006C8 -:103500000622330000000002062260400000003066 -:103510000622F320000000080222114C00000000E7 -:103520000622591800000006062233080000000297 -:1035300006226100000000300622F340000000086F -:10354000022211500000000006225930000000063F -:103550000622331000000002062261C00000003085 -:103560000622F3600000000802221154000000004F -:103570000622594800000006062233180000000207 -:1035800006226280000000300622F380000000085E -:1035900002221158000000000622596000000006B7 -:1035A00006223320000000020622634000000030A3 -:1035B0000622F3A0000000080222115C00000000B7 -:1035C0000622597800000006062233280000000277 -:1035D00006226400000000300622F3C0000000084C -:1035E000022211600000000006225990000000062F -:1035F0000622333000000002062264C000000030C2 -:103600000622F3E00000000802221164000000001E -:10361000062259A8000000060622333800000002E6 -:10362000062265800000003002161000000000280D -:1036300002170008000000020217002C000000031F -:103640000217003C000000040217004400000000C4 -:1036500002170048000000020217004C0000009012 -:1036600002170050000000900217005400800090E4 -:103670000217005808100000021700700000000632 -:1036800002170078000009FF0217007C0000076C99 -:10369000021701C4081000000217034400000001D3 -:1036A000021704000000008A0217040400000080D2 -:1036B00002170408000000810217040C00000080BB -:1036C000021704100000008A021704140000008092 -:1036D00002170418000000810217041C000000807B -:1036E000021704300000008A021704340000008032 -:1036F00002170438000000810217043C000000801B -:10370000021704400000008A0217044400000080F1 -:1037100002170448000000810217044C00000080DA -:10372000021704800000008A021704840000008051 -:1037300002170488000000810217048C000000803A -:1037400002170038007C1004021700040000000F6C -:10375000021701EC00000002021701F40000000251 -:10376000021701EC00000002021701F40000000241 -:10377000021701EC00000002021701F40000000231 -:10378000021701EC00000002021701F40000000221 -:10379000021701EC00000002021701F40000000211 -:1037A000021701EC00000002021701F40000000201 -:1037B000021701EC00000002021701F400000002F1 -:1037C000021701EC00000002021701F400000002E1 -:1037D0000616402400000002021640700000001C83 -:1037E000021642080000000102164210000000010B -:1037F00002164220000000010216422800000001CB -:10380000021642300000000102164238000000019A -:1038100002164260000000020C16401C0003D0900B -:103820000A16401C0000009C0B16401C0000027190 -:103830000216403000000028021640340000002C20 -:1038400002164038000000300216404400000020FC -:103850000216400000000001021640D800000001DE -:1038600002164008000000010216400C0000000192 -:103870000216401000000001021642400000000045 -:1038800002164248000000000616427000000002C6 -:1038900002164250000000000216425800000000CC -:1038A0000616428000000002021660080000121492 -:1038B0000216600C000012000216601000001204D4 -:1038C0000216601C0000FFFF021660200000FFFFD0 -:1038D000021660240000FFFF021660280000FFFFB0 -:1038E00002166038000000200216603C0000001044 -:1038F0000616604000000002021660480000002327 -:103900000216604C000000240216605000000025E2 -:1039100002166054000000260216605800000027BE -:103920000216605C000000110216606000000000DA -:10393000021660640000002B021660680000002C74 -:103940000216606C0000002D02166070000000EC92 -:103950000216607400000000021660780000002962 -:103960000216607C0000002A021660800000002F12 -:10397000061660840000000D021660B80000000109 -:10398000061660BC00000008021660DC00000001A2 -:10399000061660E000000004021660F0000000015E -:1039A000061660F40000000302166100000000012A -:1039B000061661040000002D021661B80000000127 -:1039C000061661BC00000008021661DC0000000160 -:1039D000061661E000000004021661F0000000011C -:1039E000061661F4000000030216620000000001E8 -:1039F000061662040000000D0216623807FFFFFF82 -:103A00000216623C0000007F0216624007FFFFFFC3 -:103A1000021662440000003F0116624800000000E8 -:103A20000116624C00000000011662500000000008 -:103A300001166254000000000116625800000000E8 -:103A40000116625C000000000116626000000000C8 -:103A500001166264000000000116626800000000A8 -:103A60000116626C00000000011662700000000088 -:103A70000116627400000000011662780000000068 -:103A80000116627C00000000011662D400000000F4 -:103A9000021662D80000FFFF021662DC0000FFFF82 -:103AA000021662E00000FFFF021662E40000FFFF62 -:103AB0000C166000000003E80A1660000000000118 -:103AC0000B16600000000003021680400000000694 -:103AD0000216804400000005021680480000000A1B -:103AE0000216804C000000050216805400000002FF -:103AF000021680CC00000004021680D000000004F2 -:103B0000021680D400000004021680D800000004D1 -:103B1000021680DC00000004021680E000000004B1 -:103B2000021680E400000004021680E80000000491 -:103B30000216880400000006021680300000007C97 -:103B4000021680340000003D021680380000003F5D -:103B50000216803C0000009C0216E6E800006000AF -:103B60000216E6EC000060000216E6F000006000BD -:103B70000216E6F40000600002168234000025E41C -:103B8000021682380000800002168094000025E3AF -:103B9000021681F400000C08021681F800000040B3 -:103BA000021681FC000001000216820000000020C5 -:103BB000021682040000001702168208000000802E -:103BC0000216820C000002000216821000000000A3 -:103BD0000216823C0000001302168220008F008F24 -:103BE0000216821C008F008F021680F00000000772 -:103BF0000216821801FF01FF0216821401FF01FF65 -:103C0000061680F4000000020216811C0000000568 -:103C10000216812000000005021681240000000524 -:103C200002168128000000080216812C0000000600 -:103C300002168130000000070616813400000004DF -:103C4000021680FC000000000616814400000002FD -:103C50000216814C00000004021681500000000191 -:103C6000021681540000000202168158000000056F -:103C70000216815C0000000502168160000000054C -:103C80000216816400000005021681680000000829 -:103C900002168100000000000216816C0000000680 -:103CA00002168170000000070616817400000006ED -:103CB0000216818C000000040216819000000001B1 -:103CC0000216810400000000021681940000000228 -:103CD00002168198000000050216819C0000000574 -:103CE000021681A000000005021681A40000000554 -:103CF000021681A800000008021681AC0000000630 -:103D0000021681B000000007061681B40000000210 -:103D10000216810800000000061681BC00000004A5 -:103D2000021681CC00000004021681D000000001C0 -:103D3000021681D400000002021681D8000000059E -:103D4000021681DC00000005021681E0000000057B -:103D50000216810C00000004021681E40000000538 -:103D6000021681E800000008021681EC000000063F -:103D7000021681F000000007021681100000000109 -:103D800002168114000000020216811800000005CE -:103D90000216809C0000004C021680A00000004C1F -:103DA000061680C400000002021680A40000000075 -:103DB000021680A800000000021680AC0000004C33 -:103DC000061680B0000000050216E6F800000204A6 -:103DD00002168240003F003F02168244003F003F2F -:103DE00006168290000000040216824800800080BF -:103DF0000216824C008000800216825001000100F1 -:103E000002168254010001000616825800000002CA -:103E100002168260004000400216826400400040AA -:103E2000021682681E001E000216826C1E001E0012 -:103E3000021682704000400002168274400040006A -:103E400002168278800080000216827C800080004A -:103E500002168280200020000216828420002000AA -:103E60000616828800000002021680900000004BB7 -:103E700002168060000001400216806400000140CC -:103E8000061680880000000202168068000000000C -:103E90000216806C0000000002168070000000C056 -:103EA00006168074000000050216880C010101014D -:103EB000021688100101200402168814200810013F -:103EC00002168818010101200216881C0101010157 -:103ED00002168820010120040216882420081001FF -:103EE00002168828010101200216882C20081001E2 -:103EF00002168830010101200216883401010101F7 -:103F000002168838010120040216883C200810019E -:103F100002168840010101200216884401010101B6 -:103F200002168848010120040216E6BC00000000C9 -:103F30000216E6C0000000020216E6C400000004FB -:103F40000216E6C8000000060216E7940000000111 -:103F5000021680EC000000FF0214000000000001C7 -:103F60000215C024000000000215C0EC0000000192 -:103F70000215C0F0000000010615C100000000029B -:103F800002140004000000010214000800000001F7 -:103F90000214000C000000010214003000000001B7 -:103FA000021400340000000102140040000000016F -:103FB000021400440000FFFF061400040000000388 -:103FC0000214000000000000060280000000200033 -:103FD0000202005800000032020200A00315002077 -:103FE000020200A403150020020200A80100003014 -:103FF000020200AC08100000020200B0000000360F -:10400000020200B400000030020200B800000031DB -:10401000020200BC00000002020200C00000000515 -:10402000020200C400000002020200C800000002F8 -:10403000020200D000000007020200DC00000000C5 -:10404000020200E000000005020200E4000000039C -:10405000020200F000000001020200FC0000000665 -:1040600002020120000000000202013400000002F0 -:10407000020201B0000000010202020C0000000177 -:1040800002020214000000010202021800000002F5 -:1040900002020404000000010202040C00000040BF -:1040A00002020410000000400202041C0000000490 -:1040B000020204200000002002020424000000028A -:1040C0000202042800000020060205000000001281 -:1040D00004020480002008BF020200600000000FFC -:1040E00002020064000000070202006800000000F5 -:1040F0000202006C0000000E020200700000000EC0 -:104100000602007400000003020200F40000000434 -:104110000202000400000001020200080000000189 -:104120000202000C00000001020200100000000169 -:104130000202001400000001020200180000000149 -:104140000202001C00000001020200200000000129 -:104150000202002400000001020200280000000109 -:104160000202002C000000010202003000000001E9 -:1041700002020034000000010202003800000001C9 -:104180000202003C000000010202004000000001A9 -:104190000202004400000001020200480000000189 -:1041A0000202004C00000001020200500000000169 -:1041B00002020108000000C802020118000000020B -:1041C000020201C400000000020201CC0000000055 -:1041D000020201D400000002020201DC0000000221 -:1041E000020201E4000000FF020201EC000000FFF7 -:1041F00002020100000000000202010C000000C8E1 -:104200000202011C00000002020201C800000000BE -:10421000020201D000000000020201D800000002EA -:10422000020201E000000002020201E8000000FFBB -:10423000020201F0000000FF020201040000002061 -:1042400002020108000000C802020118000000027A -:10425000020201C400000000020201CC00000000C4 -:10426000020201D400000002020201DC0000000290 -:10427000020201E4000000FF020201EC000000FF66 -:1042800002020100000000100202010C000000C840 -:104290000202011C00000002020201C8000000002E -:1042A000020201D000000000020201D8000000025A -:1042B000020201E000000002020201E8000000FF2B -:1042C000020201F0000000FF0202010400000030C1 -:1042D00002020108000000C80202011800000002EA -:1042E000020201C400000000020201CC0000000034 -:1042F000020201D400000002020201DC0000000200 -:10430000020201E4000000FF020201EC000000FFD5 -:1043100002020100000000400202010C000000C87F -:104320000202011C00000002020201C8000000009D -:10433000020201D000000000020201D800000002C9 -:10434000020201E000000002020201E8000000FF9A -:10435000020201F0000000FF020201040000006000 -:1043600002020108000000C8020201180000000259 -:10437000020201C400000000020201CC00000000A3 -:10438000020201D400000002020201DC000000026F -:10439000020201E4000000FF020201EC000000FF45 -:1043A00002020100000000500202010C000000C8DF -:1043B0000202011C00000002020201C8000000000D -:1043C000020201D000000000020201D80000000239 -:1043D000020201E000000002020201E8000000FF0A -:1043E000020201F0000000FF020201040000007060 -:1043F0000728040000B50000082807B8000908DFF6 -:10440000072C000028C30000072C800036720A31F8 -:10441000072D000035B617CE072D80003B00253C48 -:10442000072E0000366D33FD072E80001AA8419933 -:10443000082EBF20281C08E1012800000000000011 -:10444000012800040000000001280008000000000E -:104450000128000C000000000128001000000000EE -:1044600001280014000000000228002000000001C4 -:104470000228002400000002022800280000000397 -:104480000228002C00000000022800300000000478 -:10449000022800340000000102280038000000005B -:1044A0000228003C00000001022800400000000437 -:1044B000022800440000000002280048000000011B -:1044C0000228004C000000030228005000000000F9 -:1044D00002280054000000010228005800000004D7 -:1044E0000228005C000000000228006000000001BB -:1044F0000228006400000003022800680000000099 -:104500000228006C00000001022800700000000476 -:104510000228007400000000022800780000000457 -:104520000228007C00000003062800800000000232 -:10453000022800A400007FFF022800A8000003FF5B -:1045400002280224000000000228023400000000BB -:104550000228024C00000000022802E40000FFFFD5 -:104560000628200000000800022B8BC0000000017C -:10457000022B800000000000022B80400000001889 -:10458000022B80800000000C022B80C0000000661F -:104590000C2B8300000864700A2B83000000015775 -:1045A0000B2B83000000055F0A2B834000000000F6 -:1045B0000C2B8340000002260B2B834000000001DF -:1045C000022B838000086470022B83C00000022647 -:1045D000022B1480000000010A2B14800000000050 -:1045E000022B944000000001062B944800000002BA -:1045F000062A9A7000000004042A9A80000408E346 -:10460000062A9A9000000002042A9A98000208E7FD -:10461000062A900000000048062A2008000000C872 -:10462000062A200000000002062A912800000086C9 -:10463000062AC00000000120062A9348000000035B -:10464000042A9354000108E9062A9FB000000002E2 -:10465000042A9418000208EA042A9CD0000108ECFD -:10466000062A9CD400000011042A9D20008F08ED2A -:10467000062A9F5C00000005042A30000002097C25 -:10468000062A300800000100062A40400000001001 -:10469000042A40000010097E042A84080002098EC2 -:1046A000042ACF4000040990042ACF600002099434 -:1046B000062A9FA000000004062A600000000540B2 -:1046C000062A9D1800000002062AB00000000050D3 -:1046D000062ABB7000000070062ABB6800000002BA -:1046E000062AB94800000004062AD000000008008D -:1046F000062AC48000000150062A942000000032DF -:10470000062A502000000002062A50300000000255 -:10471000062A500000000002062A50100000000285 -:10472000022A520800000001042A9AA000020996F9 -:10473000062A95B000000022042A96380001099844 -:10474000062A963C00000003062A96E0000000229C -:10475000042A976800010999062A976C0000000353 -:10476000062A981000000022042A98980001099A4D -:10477000062A989C00000003062A994000000022A7 -:10478000042A99C80001099B062A99CC000000035D -:10479000062ABB5800000002062AC9C000000150CA -:1047A000062A94E800000032062A50280000000281 -:1047B000062A503800000002062A500800000002B5 -:1047C000062A501800000002022A520C00000001C4 -:1047D000042A9AA80002099C062A96480000002292 -:1047E000042A96D00001099E062A96D400000003F0 -:1047F000062A977800000022042A98000001099FE9 -:10480000062A980400000003062A98A80000002247 -:10481000042A9930000109A0062A993400000003F7 -:10482000062A99D800000022042A9A60000109A1F2 -:10483000062A9A6400000003062ABB6000000002FA -:10484000022ACF0000000000042A9AB0001009A23A -:10485000062A50480000000E022ACF040000000083 -:10486000042A9AF0001009B2062A50800000000EB7 -:10487000022ACF0800000000042A9B30001009C261 -:10488000062A50B80000000E022ACF0C00000000DB -:10489000042A9B70001009D2062A50F00000000E76 -:1048A000022ACF1000000000042A9BB0001009E289 -:1048B000062A51280000000E022ACF140000000032 -:1048C000042A9BF0001009F2062A51600000000E35 -:1048D000022ACF1800000000042A9C3000100A02AF -:1048E000062A51980000000E022ACF1C000000008A -:1048F000042A9C7000100A12062A51D00000000EF3 -:104900000210100800000001021010500000000109 -:10491000021010000003D000021010040000003D3F -:104920000910180002000A220910110000100C22C0 -:1049300006101140000000080910116000100C3230 -:10494000061011A00000001806102400000000E06E -:104950000210201C000000000210202000000001B6 -:10496000021020C00000000202102004000000011C -:104970000210200800000001021030D800000001E1 -:1049800009103C0000050C420910380000050C47D6 -:104990000910392000050C4C09103B0000050C5192 -:1049A00006104C000000010002104028000000101A -:1049B0000210404400003FFF021040580028000051 -:1049C000021040840084924A021040580000000007 -:1049D00002104138000000010210413800000001BF -:1049E00002104138000000010210413800000001AF -:1049F000021041380000000102104138000000019F -:104A0000021041380000000102104138000000018E -:104A10000212049001F680400212051400003C10BE -:104A200002120494FFFFFFFF02120498FFFFFFFF32 -:104A30000212049CFFFFFFFF021204A0FFFFFFFF12 -:104A4000021204A4FFFFFFFF021204A8FFFFFFFFF2 -:104A5000021204ACFFFFFFFF021204B0FFFFFFFFD2 -:104A6000021204B8FFFFFFFF021204BCFFFFFFFFAA -:104A7000021204C0FFFFFFFF021204C4FFFFFFFF8A -:104A8000021204C8FFFFFFFF021204CCFFFFFFFF6A -:104A9000021204D0FFFFFFFF021204D8FFFFFFFF46 -:104AA000021204DCFFFFFFFF021204E0FFFFFFFF22 -:104AB000021204E4FFFFFFFF021204E8FFFFFFFF02 -:104AC000021204ECFFFFFFFF021204F0FFFFFFFFE2 -:104AD000021204F4FFFFFFFF021204F8FFFFFFFFC2 -:104AE000021204FCFFFFFFFF02120500FFFFFFFFA1 -:104AF00002120504FFFFFFFF02120508FFFFFFFF80 -:104B00000212050CFFFFFFFF02120510FFFFFFFF5F -:104B1000021204D4F800C000021204B4F0005000E5 -:104B200002120390000000080212039C000000081B -:104B3000021203A000000008021203A400000002F9 -:104B4000021203BC00000004021203C000000005B2 -:104B5000021203C400000004021203D0000000008F -:104B60000212036C00000001021201BC00000040B0 -:104B7000021201C000001808021201C4000008035C -:104B8000021201C800000803021201CC000000401C -:104B9000021201D000000003021201D40000080339 -:104BA000021201D800000803021201DC0000080311 -:104BB000021201E000010003021201E400000803F8 -:104BC000021201E800000803021201EC00000003D9 -:104BD000021201F000000003021201F400000003C1 -:104BE000021201F800000003021201FC00000003A1 -:104BF000021202000000000302120204000000037F -:104C000002120208000000030212020C000000035E -:104C1000021202100000000302120214000000033E -:104C200002120218000000030212021C000000031E -:104C300002120220000000030212022400000003FE -:104C400002120228000024030212022C0000002F8E -:104C500002120230000000090212023400000019A2 -:104C600002120238000001840212023C000001839B -:104C70000212024000000306021202440000001962 -:104C800002120248000000060212024C0000030655 -:104C90000212025000000306021202540000030632 -:104CA0000212025800000C860212025C0000030689 -:104CB00002120260000003060212026400000006F5 -:104CC00002120268000000060212026C00000006D8 -:104CD00002120270000000060212027400000006B8 -:104CE00002120278000000060212027C0000000698 -:104CF0000212028000000006021202840000000678 -:104D000002120288000000060212028C0000000657 -:104D10000212029000000006021202940000000637 -:104D200002120298000000060212029C0000000617 -:104D3000021202A000000306021202A400000013E7 -:104D4000021202A800000006021202B000001004C5 -:104D5000021202B400001004021203240010644086 -:104D60000212032800106440021205B40000000182 -:104D7000021205F800000040021205FC00000019B4 -:104D800002120600000000010212066C0000000181 -:104D9000021201B000000001021207D80000000357 -:104DA000021207D800000003021207D80000000317 -:104DB000021207D800000003021207D80000000307 -:104DC000021207D800000003021207D800000003F7 -:104DD000021207D8000000030600A0000000000C2B -:104DE0000200A050000000000200A05400000000DB -:104DF0000200A0EC555400000200A0F05555555596 -:104E00000200A0F4000055550200A0F8F0000000D8 -:104E10000200A0FC555400000200A1005555555554 -:104E20000200A104000055550200A108F000000096 -:104E30000200A19C000000000200A1A000010000EF -:104E40000200A1A4000050140200A1A8000000006C -:104E50000200A6A8000000000200A6AC00000000AE -:104E60000200A6D0000000000200A45C00000C00BC -:104E70000200A61C000000030200A070FFF55FFF07 -:104E80000200A0740000FFFF0200A078F00003E021 -:104E90000200A07C000000000200A0800000A00032 -:104EA0000600A084000000050200A0980FE00000AA -:104EB0000600A09C000000070200A0B8000004004B -:104EC0000600A0BC000000030200A0C80000100003 -:104ED0000600A0CC000000030200A0D800004000A3 -:104EE0000600A0DC000000030200A0E800010000B2 -:104EF0000600A22C000000040200A688000000FCAE -:104F00000600A68C000000070200A6F400000000C6 -:104F10000200A10CFF5C00000200A110FFF55FFF82 -:104F20000200A1140000FFFF0200A118F00003E03E -:104F30000200A11C000000000200A1200000A0004F -:104F40000600A124000000050200A1380FE00000C7 -:104F50000600A13C000000070200A1580000080064 -:104F60000600A15C000000030200A1680000200010 -:104F70000600A16C000000030200A1780000800080 -:104F80000600A17C000000030200A18800020000CE -:104F90000600A23C000000040200A6B0000000FCD5 -:104FA0000600A6B4000000070200A6F800000000FA -:104FB0000200A030000000000200A0340000000049 -:104FC0000200A038000000000200A03C0000000029 -:104FD0000200A040000000000200A0440000000009 -:104FE0000200A048000000000200A04C00000000E9 -:104FF000020090C40000E000020090CC0000F3002A -:10500000020090D400000003020091A00000000103 -:105010000600917000000003020090EC00006000A8 -:10502000020090F400007300020090FC00000003F6 -:10503000020091A800000001060091880000000312 -:10504000020091000000400002009108000053009F -:105050000200911000000004020091AC0000000169 -:1050600006009194000000020200919C00000001E3 -:10507000020090D800006000020090E00000730081 -:10508000020090E800000003020091A4000000016B -:105090000200917C000000010200918000000001EC -:1050A000020091840000000002009128000003002B -:1050B0000200916C0003F0080200912C0000030034 -:1050C0000200913000000300020091340000030050 -:1050D00002009138000003000200913C0000030030 -:1050E00002009140000003000200942C0000000127 -:1050F000020094300000000102009434000000011E -:105100000200942C00000001020094300000000115 -:1051100002009434000000010200942C0000000101 -:1051200002009430000000010200943400000001ED -:105130000200942C000000010200943000000001E5 -:1051400002009434000000010200942C00000001D1 -:1051500002009430000000010200943400000001BD -:105160000200942C000000010200943000000001B5 -:1051700002009434000000010200942C00000001A1 -:10518000020094300000000102009434000000018D -:105190000200942C00000001020094300000000185 -:1051A00002009434000000010213003C000061A8DA -:1051B00006130108000000030213010400000000B0 -:1051C0000213013400000000061301080000000370 -:1051D000021301040000000002130134000000006B -:1051E0000613010800000003021301040000000080 -:1051F0000213013400000000061301080000000340 -:10520000021301040000000002130134000000003A -:10521000061301080000000302130104000000004F -:10522000021301340000000006130108000000030F -:10523000021301040000000002130134000000000A -:10524000061301080000000302130104000000001F -:1052500002130134000000000613010800000003DF -:1052600002130104000000000213013400000000DA -:10527000021100B8000000010216E6E8000020005C -:105280000216E6EC000020000216E6F0000065556C -:105290000216E6F400006555021681500000000079 -:1052A00002168174000000010216817800000001DE -:1052B0000216817C000000010216818000000001BE -:1052C000021681840000000102168188000000019E -:1052D000021681B400000001021681B8000000012E -:1052E000021681BC00000001021681C0000000010E -:1052F000021681C400000001021681C800000001EE -:1053000002168110000000000216824000BF00BF9C -:1053100006168244000000020216824C00BF00BF45 -:105320000216E6C4000000010216E6C800000003F1 -:105330000216E79400000000042ACF40000A0C5631 -:105340000000000000000000000000340000000029 -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:1053700000000000003400350000000000000000C4 -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A0000035006000000000000000000000000068 -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000600091EC -:1053D0000000000000000000009100950095009979 -:1053E0000099009D009D00A100A100A500A500A9B5 -:1053F00000A900AD00AD00B100B100B50000000093 -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:105420000000000000B503100310031A031A032440 -:105430000324032B032B03320332033903390340C4 -:10544000034003470347034E034E03550355035CD4 -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000035C035D0000000000000000035D035E1B -:10551000035E035F035F0360036003610361036273 -:105520000362036303630364036403650000000014 -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:1055500000000000000000000365036C036C03788A -:105560000378038400000000000000000000000039 -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00003840385000000000000000000000000DC -:1055C00000000000000000000000000000000000DB -:1055D000000000000000000000000000038503B090 -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000003B003DF0000000005 -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:105630000000000003DF040E000000000000000076 -:10564000040E04150415041C041C04230423042A5A -:10565000042A0431043104380438043F043F04466A -:105660000446047900000000000000000479047D75 -:10567000047D048104810485048504890489048DE2 -:10568000048D04910491049504950499049904E807 -:1056900004E804FE04FE0514051405160516051895 -:1056A0000518051A051A051C051C051E051E0520F2 -:1056B000052005220522052405240690000000008F -:1056C00000000000069006950695069A069A069F29 -:1056D000069F06A406A406A906A906AE06AE06B352 -:1056E00006B306B806B806B90000000000000000C6 -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:1057100006B906DD000000000000000006DD06DF1F -:1057200006DF06E106E106E306E306E506E506E731 -:1057300006E706E906E906EB06EB06ED06ED0702CD -:105740000702070507050708000000000000000029 -:105750000000000000000000000000000000000049 -:1057600000000000000000000708074C00000000D7 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:1057900000000000074C07DE0000000000000000D1 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00007DE07EC00000000000000000000000001 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000007EC082995 -:1057F0000000000000000000082908320832083BC1 -:10580000083B08440844084D084D08560856085FF0 -:10581000085F086808680871087108D108D108E6AF -:1058200008E608FB08FB08FE08FE09010901090457 -:10583000090409070907090A090A090D090D0910D0 -:10584000091009130913091C0000000000000000E2 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:10587000091C0922000000000000000000000000D8 -:105880000000000000000000000000000000000018 -:1058900000000000000000000000000009220927AD -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000927092D0000000072 -:1058D00000000000092D092E092E092F092F09307B -:1058E00009300931093109320932093309330934E0 -:1058F000093409350000000000000000000000002D -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:10592000093509A6000000000000000009A609A72B -:1059300009A709A809A809A909A909AA09AA09ABD7 -:1059400009AB09AC09AC09AD09AD09AE09AE09C294 -:1059500009C209D509D509E909E909EA09EA09EB02 -:1059600009EB09EC09EC09ED09ED09EE09EE09EF87 -:1059700009EF09F009F009F109F10A10000000002F -:10598000000000000A100A130A130A160A160A1960 -:105990000A190A1C0A1C0A1F0A1F0A220A220A25BF -:1059A0000A250A280A280A29000000000000000031 -:1059B0000A290A2C0A2C0A2F0A2F0A320A320A351F -:1059C0000A350A380A380A3B0A3B0A3E0A3E0A41AF -:1059D0000A410A4200000000000000000000000030 -:1059E00000000000000000000000000000000000B7 -:1059F0000000000000000000000000000A420A5AF7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A200000000000000000000A5A0A5B00000000AD -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A5000000000000000000000010000000207003C -:105A600000030E000004150000051C0000062300C2 -:105A700000072A000008310000093800000A3F0032 -:105A8000000B4600000C4D00000D5400000E5B00A2 -:105A9000000F620000106900001170000012770012 -:105AA00000137E000014850000158C000016930082 -:105AB00000179A000018A1000019A800001AAF00F2 -:105AC000001BB600001CBD00001DC400001ECB0062 -:105AD000001FD2000000D90000002000000040009C -:105AE00000006000000080000000A0000000C00076 -:105AF0000000E00000010000000120000001400063 -:105B000000016000000180000001A0000001C00051 -:105B10000001E0000002000000022000000240003E -:105B200000026000000280000002A0000002C0002D -:105B30000002E0000003000000032000000340001A -:105B400000036000000380000003A0000003C00009 -:105B50000003E000000400000004200000044000F6 -:105B600000046000000480000004A0000004C000E5 -:105B70000004E000000500000005200000054000D2 -:105B800000056000000580000005A0000005C000C1 -:105B90000005E000000600000006200000064000AE -:105BA00000066000000680000006A0000006C0009D -:105BB0000006E0000007000000072000000740008A -:105BC00000076000000780000007A0000007C00079 -:105BD0000007E00000080000000820000008400066 -:105BE00000086000000880000008A0000008C00055 -:105BF0000008E00000090000000920000009400042 -:105C000000096000000980000009A0000009C00030 -:105C10000009E000000A0000000A2000000A40001D -:105C2000000A6000000A8000000AA000000AC0000C -:105C3000000AE000000B0000000B2000000B4000F9 -:105C4000000B6000000B8000000BA000000BC000E8 -:105C5000000BE000000C0000000C2000000C4000D5 -:105C6000000C6000000C8000000CA000000CC000C4 -:105C7000000CE000000D0000000D2000000D4000B1 -:105C8000000D6000000D8000000DA000000DC000A0 -:105C9000000DE000000E0000000E2000000E40008D -:105CA000000E6000000E8000000EA000000EC0007C -:105CB000000EE000000F0000000F2000000F400069 -:105CC000000F6000000F8000000FA000000FC00058 -:105CD000000FE00000100000001020000010400045 -:105CE00000106000001080000010A0000010C00034 -:105CF0000010E00000110000001120000011400021 -:105D000000116000001180000011A0000011C0000F -:105D10000011E000001200000012200000124000FC -:105D200000126000001280000012A0000012C000EB -:105D30000012E000001300000013200000134000D8 -:105D400000136000001380000013A0000013C000C7 -:105D50000013E000001400000014200000144000B4 -:105D600000146000001480000014A0000014C000A3 -:105D70000014E00000150000001520000015400090 -:105D800000156000001580000015A0000015C0007F -:105D90000015E0000016000000162000001640006C -:105DA00000166000001680000016A0000016C0005B -:105DB0000016E00000170000001720000017400048 -:105DC00000176000001780000017A0000017C00037 -:105DD0000017E00000180000001820000018400024 -:105DE00000186000001880000018A0000018C00013 -:105DF0000018E00000190000001920000019400000 -:105E000000196000001980000019A0000019C000EE -:105E10000019E000001A0000001A2000001A4000DB -:105E2000001A6000001A8000001AA000001AC000CA -:105E3000001AE000001B0000001B2000001B4000B7 -:105E4000001B6000001B8000001BA000001BC000A6 -:105E5000001BE000001C0000001C2000001C400093 -:105E6000001C6000001C8000001CA000001CC00082 -:105E7000001CE000001D0000001D2000001D40006F -:105E8000001D6000001D8000001DA000001DC0005E -:105E9000001DE000001E0000001E2000001E40004B -:105EA000001E6000001E8000001EA000001EC0003A -:105EB000001EE000001F0000001F2000001F400027 -:105EC000001F6000001F8000001FA000001FC00016 -:105ED000001FE00000200000002020000020400003 -:105EE00000206000002080000020A0000020C000F2 -:105EF0000020E000002100000021200000214000DF -:105F000000216000002180000021A0000021C000CD -:105F10000021E000002200000022200000224000BA -:105F200000226000002280000022A0000022C000A9 -:105F30000022E00000230000002320000023400096 -:105F400000236000002380000023A0000023C00085 -:105F50000023E00000240000002420000024400072 -:105F600000246000002480000024A0000024C00061 -:105F70000024E0000025000000252000002540004E -:105F800000256000002580000025A0000025C0003D -:105F90000025E0000026000000262000002640002A -:105FA00000266000002680000026A0000026C00019 -:105FB0000026E00000270000002720000027400006 -:105FC00000276000002780000027A0000027C000F5 -:105FD0000027E000002800000028200000284000E2 -:105FE00000286000002880000028A0000028C000D1 -:105FF0000028E000002900000029200000294000BE -:1060000000296000002980000029A0000029C000AC -:106010000029E000002A0000002A2000002A400099 -:10602000002A6000002A8000002AA000002AC00088 -:10603000002AE000002B0000002B2000002B400075 -:10604000002B6000002B8000002BA000002BC00064 -:10605000002BE000002C0000002C2000002C400051 -:10606000002C6000002C8000002CA000002CC00040 -:10607000002CE000002D0000002D2000002D40002D -:10608000002D6000002D8000002DA000002DC0001C -:10609000002DE000002E0000002E2000002E400009 -:1060A000002E6000002E8000002EA000002EC000F8 -:1060B000002EE000002F0000002F2000002F4000E5 -:1060C000002F6000002F8000002FA000002FC000D4 -:1060D000002FE000003000000030200000304000C1 -:1060E00000306000003080000030A0000030C000B0 -:1060F0000030E0000031000000312000003140009D -:1061000000316000003180000031A0000031C0008B -:106110000031E00000320000003220000032400078 -:1061200000326000003280000032A0000032C00067 -:106130000032E00000330000003320000033400054 -:1061400000336000003380000033A0000033C00043 -:106150000033E00000340000003420000034400030 -:1061600000346000003480000034A0000034C0001F -:106170000034E0000035000000352000003540000C -:1061800000356000003580000035A0000035C000FB -:106190000035E000003600000036200000364000E8 -:1061A00000366000003680000036A0000036C000D7 -:1061B0000036E000003700000037200000374000C4 -:1061C00000376000003780000037A0000037C000B3 -:1061D0000037E000003800000038200000384000A0 -:1061E00000386000003880000038A0000038C0008F -:1061F0000038E0000039000000392000003940007C -:1062000000396000003980000039A0000039C0006A -:106210000039E000003A0000003A2000003A400057 -:10622000003A6000003A8000003AA000003AC00046 -:10623000003AE000003B0000003B2000003B400033 -:10624000003B6000003B8000003BA000003BC00022 -:10625000003BE000003C0000003C2000003C40000F -:10626000003C6000003C8000003CA000003CC000FE -:10627000003CE000003D0000003D2000003D4000EB -:10628000003D6000003D8000003DA000003DC000DA -:10629000003DE000003E0000003E2000003E4000C7 -:1062A000003E6000003E8000003EA000003EC000B6 -:1062B000003EE000003F0000003F2000003F4000A3 -:1062C000003F6000003F8000003FA000003FC00092 -:1062D000003FE000003FE00100000000000001FF7F -:1062E0000000020000007FF800007FF800000A9420 -:1062F00000001500000000010000FF000000000089 -:106300000000FF00000000000000FF00000000008F -:106310000000FF00000000000000FF00000000007F -:106320000000FF00000000000000FF00000000006F -:106330000000FF00000000000000FF00000000005F -:106340000000FF00000000000000FF00000000004F -:106350000000FF00000000000000FF00000000003F -:106360000000FF00000000000000FF00000000002F -:106370000000FF00000000000000FF00000000001F -:106380000000FF00000000000000FF00000000000F -:106390000000FF00000000000000FF0000000000FF -:1063A0000000FF00000000000000FF0000000000EF -:1063B0000000FF00000000000000FF0000000000DF -:1063C0000000FF00000000000000FF0000000000CF -:1063D0000000FF00000000000000FF0000000000BF -:1063E0000000FF00000000000000FF0000000000AF -:1063F0000000FF00000000000000FF00000000009F -:106400000000FF00000000000000FF00000000008E -:106410000000FF00000000000000FF00000000007E -:106420000000FF00000000000000FF00000000006E -:106430000000FF00000000000000FF00000000005E -:106440000000FF00000000000000FF00000000004E -:106450000000FF00000000000000FF00000000003E -:106460000000FF00000000000000FF00000000002E -:106470000000FF00000000000000FF00000000001E -:106480000000FF00000000000000FF00000000000E -:106490000000FF00000000000000FF0000000000FE -:1064A0000000FF00000000000000FF0000000000EE -:1064B0000000FF00000000000000FF0000000000DE -:1064C0000000FF00000000000000FF0000000000CE -:1064D0000000FF00000000000000FF0000000000BE -:1064E0000000FF00000000000000FF0000000000AE -:1064F0000000FF00000000000000FF00000000009E -:106500000000FF00000000000000FF00000000008D -:106510000000FF00000000000000FF00000000007D -:106520000000FF00000000000000FF00000000006D -:106530000000FF000000000000000000140AFF003F -:106540000000000100000000002010010000000019 -:106550000100900000000100000090020000900483 -:1065600000009006000090080000900A0000900CC7 -:106570000000900E00009010000090120000901497 -:1065800000009016000090180000901A0000901C67 -:106590000000901E00009020000090220000902437 -:1065A00000009026000090280000902A0000902C07 -:1065B0000000902E000090300000903200009034D7 -:1065C00000009036000090380000903A0000903CA7 -:1065D0000000903E00009040000090420000904477 -:1065E00000009046000090480000904A0000904C47 -:1065F0000000904E00009050000090520000905417 -:1066000000009056000090580000905A0000905CE6 -:106610000000905E000090600000906200009064B6 -:1066200000009066000090680000906A0000906C86 -:106630000000906E00009070000090720000907456 -:1066400000009076000090780000907A0000907C26 -:106650000000907E000090800000908200009084F6 -:1066600000009086000090880000908A0000908CC6 -:106670000000908E00009090000090920000909496 -:1066800000009096000090980000909A0000909C66 -:106690000000909E000090A0000090A2000090A436 -:1066A000000090A6000090A8000090AA000090AC06 -:1066B000000090AE000090B0000090B2000090B4D6 -:1066C000000090B6000090B8000090BA000090BCA6 -:1066D000000090BE000090C0000090C2000090C476 -:1066E000000090C6000090C8000090CA000090CC46 -:1066F000000090CE000090D0000090D2000090D416 -:10670000000090D6000090D8000090DA000090DCE5 -:10671000000090DE000090E0000090E2000090E4B5 -:10672000000090E6000090E8000090EA000090EC85 -:10673000000090EE000090F0000090F2000090F455 -:10674000000090F6000090F8000090FA000090FC25 -:10675000000090FE000091000000910200009104F2 -:1067600000009106000091080000910A0000910CC1 -:106770000000910E00009110000091120000911491 -:1067800000009116000091180000911A0000911C61 -:106790000000911E00009120000091220000912431 -:1067A00000009126000091280000912A0000912C01 -:1067B0000000912E000091300000913200009134D1 -:1067C00000009136000091380000913A0000913CA1 -:1067D0000000913E00009140000091420000914471 -:1067E00000009146000091480000914A0000914C41 -:1067F0000000914E00009150000091520000915411 -:1068000000009156000091580000915A0000915CE0 -:106810000000915E000091600000916200009164B0 -:1068200000009166000091680000916A0000916C80 -:106830000000916E00009170000091720000917450 -:1068400000009176000091780000917A0000917C20 -:106850000000917E000091800000918200009184F0 -:1068600000009186000091880000918A0000918CC0 -:106870000000918E00009190000091920000919490 -:1068800000009196000091980000919A0000919C60 -:106890000000919E000091A0000091A2000091A430 -:1068A000000091A6000091A8000091AA000091AC00 -:1068B000000091AE000091B0000091B2000091B4D0 -:1068C000000091B6000091B8000091BA000091BCA0 -:1068D000000091BE000091C0000091C2000091C470 -:1068E000000091C6000091C8000091CA000091CC40 -:1068F000000091CE000091D0000091D2000091D410 -:10690000000091D6000091D8000091DA000091DCDF -:10691000000091DE000091E0000091E2000091E4AF -:10692000000091E6000091E8000091EA000091EC7F -:10693000000091EE000091F0000091F2000091F44F -:10694000000091F6000091F8000091FA000091FC1F -:10695000000091FEFFFFFFFFFFFFFFFFFFFFFFFFB4 -:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 -:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 -:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 -:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 -:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 -:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 -:1069D000FFFFFFFF0000000300BEBC20000000001E -:1069E000000000050000000300BEBC200000000005 -:1069F000000000050000000300BEBC2000000000F5 -:106A0000000000050000000300BEBC2000000000E4 -:106A1000000000050000000300BEBC2000000000D4 -:106A2000000000050000000300BEBC2000000000C4 -:106A3000000000050000000300BEBC2000000000B4 -:106A4000000000050000000300BEBC2000000000A4 -:106A50000000000500002000000040C00000618030 -:106A6000000082400000A3000000C3C00000E480DA -:106A70000001054000012600000146C000016780BA -:106A8000000188400001A9000001C9C00001EA809E -:106A900000020B4000022C0000024CC000026D807E -:106AA00000028E400002AF000002CFC00002F08062 -:106AB00000001140000080000001038000018700F9 -:106AC00000020A8000028E0000031180000395007E -:106AD0000004188000049C0000051F800005A3002E -:106AE000000626800006AA0000072D800007B100DE -:106AF000000834800008B80000093B800009BF008E -:106B0000000A4280000AC600000B4980000BCD003D -:106B1000000C5080000CD400000D578000005B007A -:106B200000007FF800007FF80000022A0000350016 -:106B30000000FF00000000000000FF000000000057 -:106B40000000FF00000000000000FF000000000047 -:106B50000000FF00000000000000FF000000000037 -:106B60000000FF00000000000000FF000000000027 -:106B70000000FF00000000000000FF000000000017 -:106B80000000FF00000000000000FF000000000007 -:106B90000000FF00000000000000FF0000000000F7 -:106BA0000000FF00000000000000FF0000000000E7 -:106BB0000000FF00000000000000FF0000000000D7 -:106BC0000000FF00000000000000FF0000000000C7 -:106BD0000000FF00000000000000FF0000000000B7 -:106BE0000000FF00000000000000FF0000000000A7 -:106BF0000000FF00000000000000FF000000000097 -:106C00000000FF00000000000000FF000000000086 -:106C10000000FF00000000000000FF000000000076 -:106C20000000FF00000000000000FF000000000066 -:106C30000000FF00000000000000FF000000000056 -:106C40000000FF00000000000000FF000000000046 -:106C50000000FF00000000000000FF000000000036 -:106C60000000FF00000000000000FF000000000026 -:106C70000000FF00000000000000FF000000000016 -:106C80000000FF00000000000000FF000000000006 -:106C90000000FF00000000000000FF0000000000F6 -:106CA0000000FF00000000000000FF0000000000E6 -:106CB0000000FF00000000000000FF0000000000D6 -:106CC0000000FF00000000000000FF0000000000C6 -:106CD0000000FF00000000000000FF0000000000B6 -:106CE0000000FF00000000000000FF0000000000A6 -:106CF0000000FF00000000000000FF000000000096 -:106D00000000FF00000000000000FF000000000085 -:106D10000000FF00000000000000FF000000000075 -:106D20000000FF00000000000000FF000000000065 -:106D30000000FF00000000000000FF000000000055 -:106D40000000FF00000000000000FF000000000045 -:106D50000000FF00000000000000FF000000000035 -:106D60000000FF00000000000000FF00000019000C -:106D70000000000000000000FFFFFFFF0000000017 -:106D800003938700000000000393870000007FF852 -:106D900000007FF800000BA700003500000000FF96 -:106DA000000000FF000000FF000000FF000000FFE7 -:106DB000000000FF000000FF000000FF0000FF00D7 -:106DC000000000000000FF00000000000000FF00C5 -:106DD000000000000000FF00000000000000FF00B5 -:106DE000000000000000FF00000000000000FF00A5 -:106DF000000000000000FF00000000000000FF0095 -:106E0000000000000000FF00000000000000FF0084 -:106E1000000000000000FF00000000000000FF0074 -:106E2000000000000000FF00000000000000FF0064 -:106E3000000000000000FF00000000000000FF0054 -:106E4000000000000000FF00000000000000FF0044 -:106E5000000000000000FF00000000000000FF0034 -:106E6000000000000000FF00000000000000FF0024 -:106E7000000000000000FF00000000000000FF0014 -:106E8000000000000000FF00000000000000FF0004 -:106E9000000000000000FF00000000000000FF00F4 -:106EA000000000000000FF00000000000000FF00E4 -:106EB000000000000000FF00000000000000FF00D4 -:106EC000000000000000FF00000000000000FF00C4 -:106ED000000000000000FF00000000000000FF00B4 -:106EE000000000000000FF00000000000000FF00A4 -:106EF000000000000000FF00000000000000FF0094 -:106F0000000000000000FF00000000000000FF0083 -:106F1000000000000000FF00000000000000FF0073 -:106F2000000000000000FF00000000000000FF0063 -:106F3000000000000000FF00000000000000FF0053 -:106F4000000000000000FF00000000000000FF0043 -:106F5000000000000000FF00000000000000FF0033 -:106F6000000000000000FF00000000000000FF0023 -:106F7000000000000000FF00000000000000FF0013 -:106F8000000000000000FF00000000000000FF0003 -:106F9000000000000000FF00000000000000FF00F3 -:106FA000000000000000FF00000000000000FF00E3 -:106FB000000000000000FF00000000000000FF00D3 -:106FC000000000000000FF00000000000000FF00C3 -:106FD000000000000000FF00000000000000FF00B3 -:106FE000000000000000FF00000000000000FF00A3 -:106FF000000000000000FF0000000000FFFFFFFF96 -:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 -:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 -:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 -:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 -:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 -:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -:10707000FFFFFFFFFFFFFFFFFFFFFFFF000000001C -:10708000000028AD000029180000291900000005A3 -:10709000000000070000FF000FFFFFFF0000FF00DF -:1070A0000FFFFFFF000000FF0000FF000000FF00D7 -:1070B0000FFFFFFF0000FF000FFFFFFF000000FFBA -:1070C0000000FF000000FF000FFFFFFF0000FF00B7 -:1070D0000FFFFFFF000000FF0000FF000000FF00A7 -:1070E0000FFFFFFF0000FF000FFFFFFF000000FF8A -:1070F0000000FF000000FF000FFFFFFF0000FF0087 -:107100000FFFFFFF000000FF0000FF000000FF0076 -:107110000FFFFFFF0000FF000FFFFFFF000000FF59 -:107120000000FF000000FF000FFFFFFF0000FF0056 -:107130000FFFFFFF000000FF0000FF000000FF0046 -:107140000FFFFFFF0000FF000FFFFFFF000000FF29 -:107150000000FF000000FF000FFFFFFF0000FF0026 -:107160000FFFFFFF000000FF0000FF000000FF0016 -:107170000FFFFFFF0000FF000FFFFFFF000000FFF9 -:107180000000FF000000FF000FFFFFFF0000FF00F6 -:107190000FFFFFFF000000FF0000FF000000FF00E6 -:1071A0000FFFFFFF0000FF000FFFFFFF000000FFC9 -:1071B0000000FF000000FF000FFFFFFF0000FF00C6 -:1071C0000FFFFFFF000000FF0000FF000000FF00B6 -:1071D0000FFFFFFF0000FF000FFFFFFF000000FF99 -:1071E0000000FF000000FF000FFFFFFF0000FF0096 -:1071F0000FFFFFFF000000FF0000FF000000FF0086 -:107200000FFFFFFF0000FF000FFFFFFF000000FF68 -:107210000000FF000000FF000FFFFFFF0000FF0065 -:107220000FFFFFFF000000FF0000FF000000FF0055 -:107230000FFFFFFF0000FF000FFFFFFF000000FF38 -:107240000000FF000000FF000FFFFFFF0000FF0035 -:107250000FFFFFFF000000FF0000FF000000FF0025 -:107260000FFFFFFF0000FF000FFFFFFF000000FF08 -:107270000000FF000000FF000FFFFFFF0000FF0005 -:107280000FFFFFFF000000FF0000FF000000FF00F5 -:107290000FFFFFFF0000FF000FFFFFFF000000FFD8 -:1072A0000000FF000000FF000FFFFFFF0000FF00D5 -:1072B0000FFFFFFF000000FF0000FF000000FF00C5 -:1072C0000FFFFFFF0000FF000FFFFFFF000000FFA8 -:1072D0000000FF000000FF000FFFFFFF0000FF00A5 -:1072E0000FFFFFFF000000FF0000FF000000FF0095 -:1072F0000FFFFFFF0000FF000FFFFFFF000000FF78 -:107300000000FF000000FF000FFFFFFF0000FF0074 -:107310000FFFFFFF000000FF0000FF000000FF0064 -:107320000FFFFFFF0000FF000FFFFFFF000000FF47 -:107330000000FF000000FF000FFFFFFF0000FF0044 -:107340000FFFFFFF000000FF0000FF000000FF0034 -:107350000FFFFFFF0000FF000FFFFFFF000000FF17 -:107360000000FF000000FF000FFFFFFF0000FF0014 -:107370000FFFFFFF000000FF0000FF000000FF0004 -:107380000FFFFFFF0000FF000FFFFFFF000000FFE7 -:107390000000FF000000FF000FFFFFFF0000FF00E4 -:1073A0000FFFFFFF000000FF0000FF000000FF00D4 -:1073B0000FFFFFFF0000FF000FFFFFFF000000FFB7 -:1073C0000000FF000000FF000FFFFFFF0000FF00B4 -:1073D0000FFFFFFF000000FF0000FF000000FF00A4 -:1073E0000FFFFFFF0000FF000FFFFFFF000000FF87 -:1073F0000000FF000000FF000FFFFFFF0000FF0084 -:107400000FFFFFFF000000FF0000FF000000FF0073 -:107410000FFFFFFF0000FF000FFFFFFF000000FF56 -:107420000000FF000000FF000FFFFFFF0000FF0053 -:107430000FFFFFFF000000FF0000FF000000FF0043 -:107440000FFFFFFF0000FF000FFFFFFF000000FF26 -:107450000000FF000000FF000FFFFFFF0000FF0023 -:107460000FFFFFFF000000FF0000FF000000FF0013 -:107470000FFFFFFF0000FF000FFFFFFF000000FFF6 -:107480000000FF000000FF000FFFFFFF0000FF00F3 -:107490000FFFFFFF000000FF0000FF000000FF00E3 -:1074A0000FFFFFFF0000FF000FFFFFFF000000FFC6 -:1074B0000000FF000000FF000FFFFFFF0000FF00C3 -:1074C0000FFFFFFF000000FF0000FF000000FF00B3 -:1074D0000FFFFFFF0000FF000FFFFFFF000000FF96 -:1074E0000000FF000000FF000FFFFFFF0000FF0093 -:1074F0000FFFFFFF000000FF0000FF000000FF0083 -:107500000FFFFFFF0000FF000FFFFFFF000000FF65 -:107510000000FF000000FF000FFFFFFF0000FF0062 -:107520000FFFFFFF000000FF0000FF000000FF0052 -:107530000FFFFFFF0000FF000FFFFFFF000000FF35 -:107540000000FF000000FF000FFFFFFF0000FF0032 -:107550000FFFFFFF000000FF0000FF000000FF0022 -:107560000FFFFFFF0000FF000FFFFFFF000000FF05 -:107570000000FF000000FF000FFFFFFF0000FF0002 -:107580000FFFFFFF000000FF0000FF000000FF00F2 -:107590000FFFFFFF0000FF000FFFFFFF000000FFD5 -:1075A0000000FF000000FF000FFFFFFF0000FF00D2 -:1075B0000FFFFFFF000000FF0000FF000000FF00C2 -:1075C0000FFFFFFF0000FF000FFFFFFF000000FFA5 -:1075D0000000FF000000FF000FFFFFFF0000FF00A2 -:1075E0000FFFFFFF000000FF0000FF000000FF0092 -:1075F0000FFFFFFF0000FF000FFFFFFF000000FF75 -:107600000000FF000000FF000FFFFFFF0000FF0071 -:107610000FFFFFFF000000FF0000FF000000FF0061 -:107620000FFFFFFF0000FF000FFFFFFF000000FF44 -:107630000000FF000000FF000FFFFFFF0000FF0041 -:107640000FFFFFFF000000FF0000FF000000FF0031 -:107650000FFFFFFF0000FF000FFFFFFF000000FF14 -:107660000000FF000000FF000FFFFFFF0000FF0011 -:107670000FFFFFFF000000FF0000FF000000FF0001 -:107680000FFFFFFF0000FF000FFFFFFF000000FFE4 -:107690000000FF000000FF000FFFFFFF0000FF00E1 -:1076A0000FFFFFFF000000FF0000FF000000FF00D1 -:1076B0000FFFFFFF0000FF000FFFFFFF000000FFB4 -:1076C0000000FF000000FF000FFFFFFF0000FF00B1 -:1076D0000FFFFFFF000000FF0000FF000000FF00A1 -:1076E0000FFFFFFF0000FF000FFFFFFF000000FF84 -:1076F0000000FF000000FF000FFFFFFF0000FF0081 -:107700000FFFFFFF000000FF0000FF000000FF0070 -:107710000FFFFFFF0000FF000FFFFFFF000000FF53 -:107720000000FF000000FF000FFFFFFF0000FF0050 -:107730000FFFFFFF000000FF0000FF000000FF0040 -:107740000FFFFFFF0000FF000FFFFFFF000000FF23 -:107750000000FF000000FF000FFFFFFF0000FF0020 -:107760000FFFFFFF000000FF0000FF000000FF0010 -:107770000FFFFFFF0000FF000FFFFFFF000000FFF3 -:107780000000FF000000FF000FFFFFFF0000FF00F0 -:107790000FFFFFFF000000FF0000FF000000FF00E0 -:1077A0000FFFFFFF0000FF000FFFFFFF000000FFC3 -:1077B0000000FF000000FF000FFFFFFF0000FF00C0 -:1077C0000FFFFFFF000000FF0000FF000000FF00B0 -:1077D0000FFFFFFF0000FF000FFFFFFF000000FF93 -:1077E0000000FF000000FF000FFFFFFF0000FF0090 -:1077F0000FFFFFFF000000FF0000FF000000FF0080 -:107800000FFFFFFF0000FF000FFFFFFF000000FF62 -:107810000000FF000000FF000FFFFFFF0000FF005F -:107820000FFFFFFF000000FF0000FF000000FF004F -:107830000FFFFFFF0000FF000FFFFFFF000000FF32 -:107840000000FF000000FF000FFFFFFF0000FF002F -:107850000FFFFFFF000000FF0000FF000000FF001F -:107860000FFFFFFF0000FF000FFFFFFF000000FF02 -:107870000000FF000000FF000FFFFFFF0000FF00FF -:107880000FFFFFFF000000FF0000FF000000FF00EF -:107890000FFFFFFF0000FF000FFFFFFF000000FFD2 -:1078A0000000FF000000FF000FFFFFFF0000FF00CF -:1078B0000FFFFFFF000000FF0000FF000000FF00BF -:1078C0000FFFFFFF0000FF000FFFFFFF000000FFA2 -:1078D0000000FF000000FF000FFFFFFF0000FF009F -:1078E0000FFFFFFF000000FF0000FF000000FF008F -:1078F0000FFFFFFF0000FF000FFFFFFF000000FF72 -:107900000000FF000000FF000FFFFFFF0000FF006E -:107910000FFFFFFF000000FF0000FF000000FF005E -:107920000FFFFFFF0000FF000FFFFFFF000000FF41 -:107930000000FF000000FF000FFFFFFF0000FF003E -:107940000FFFFFFF000000FF0000FF000000FF002E -:107950000FFFFFFF0000FF000FFFFFFF000000FF11 -:107960000000FF000000FF000FFFFFFF0000FF000E -:107970000FFFFFFF000000FF0000FF000000FF00FE -:107980000FFFFFFF0000FF000FFFFFFF000000FFE1 -:107990000000FF000000FF000FFFFFFF0000FF00DE -:1079A0000FFFFFFF000000FF0000FF000000FF00CE -:1079B0000FFFFFFF0000FF000FFFFFFF000000FFB1 -:1079C0000000FF000000FF000FFFFFFF0000FF00AE -:1079D0000FFFFFFF000000FF0000FF000000FF009E -:1079E0000FFFFFFF0000FF000FFFFFFF000000FF81 -:1079F0000000FF000000FF000FFFFFFF0000FF007E -:107A00000FFFFFFF000000FF0000FF000000FF006D -:107A10000FFFFFFF0000FF000FFFFFFF000000FF50 -:107A20000000FF000000FF000FFFFFFF0000FF004D -:107A30000FFFFFFF000000FF0000FF000000FF003D -:107A40000FFFFFFF0000FF000FFFFFFF000000FF20 -:107A50000000FF000000FF000FFFFFFF0000FF001D -:107A60000FFFFFFF000000FF0000FF000000FF000D -:107A70000FFFFFFF0000FF000FFFFFFF000000FFF0 -:107A80000000FF000000FF000FFFFFFF0000FF00ED -:107A90000FFFFFFF000000FF0000FF000000FF00DD -:107AA0000FFFFFFF0000FF000FFFFFFF000000FFC0 -:107AB0000000FF000000FF000FFFFFFF0000FF00BD -:107AC0000FFFFFFF000000FF0000FF000000FF00AD -:107AD0000FFFFFFF0000FF000FFFFFFF000000FF90 -:107AE0000000FF000000FF000FFFFFFF0000FF008D -:107AF0000FFFFFFF000000FF0000FF000000FF007D -:107B00000FFFFFFF0000FF000FFFFFFF000000FF5F -:107B10000000FF000000FF000FFFFFFF0000FF005C -:107B20000FFFFFFF000000FF0000FF000000FF004C -:107B30000FFFFFFF0000FF000FFFFFFF000000FF2F -:107B40000000FF000000FF000FFFFFFF0000FF002C -:107B50000FFFFFFF000000FF0000FF000000FF001C -:107B60000FFFFFFF0000FF000FFFFFFF000000FFFF -:107B70000000FF000000FF000FFFFFFF0000FF00FC -:107B80000FFFFFFF000000FF0000FF000000FF00EC -:107B90000FFFFFFF0000FF000FFFFFFF000000FFCF -:107BA0000000FF000000FF000FFFFFFF0000FF00CC -:107BB0000FFFFFFF000000FF0000FF000000FF00BC -:107BC0000FFFFFFF0000FF000FFFFFFF000000FF9F -:107BD0000000FF000000FF000FFFFFFF0000FF009C -:107BE0000FFFFFFF000000FF0000FF000000FF008C -:107BF0000FFFFFFF0000FF000FFFFFFF000000FF6F -:107C00000000FF000000FF000FFFFFFF0000FF006B -:107C10000FFFFFFF000000FF0000FF000000FF005B -:107C20000FFFFFFF0000FF000FFFFFFF000000FF3E -:107C30000000FF000000FF000FFFFFFF0000FF003B -:107C40000FFFFFFF000000FF0000FF000000FF002B -:107C50000FFFFFFF0000FF000FFFFFFF000000FF0E -:107C60000000FF000000FF000FFFFFFF0000FF000B -:107C70000FFFFFFF000000FF0000FF000000FF00FB -:107C80000FFFFFFF0000FF000FFFFFFF000000FFDE -:107C90000000FF000000FF000FFFFFFF0000FF00DB -:107CA0000FFFFFFF000000FF0000FF000000FF00CB -:107CB0000FFFFFFF0000FF000FFFFFFF000000FFAE -:107CC0000000FF000000FF000FFFFFFF0000FF00AB -:107CD0000FFFFFFF000000FF0000FF000000FF009B -:107CE0000FFFFFFF0000FF000FFFFFFF000000FF7E -:107CF0000000FF000000FF000FFFFFFF0000FF007B -:107D00000FFFFFFF000000FF0000FF000000FF006A -:107D10000FFFFFFF0000FF000FFFFFFF000000FF4D -:107D20000000FF000000FF000FFFFFFF0000FF004A -:107D30000FFFFFFF000000FF0000FF000000FF003A -:107D40000FFFFFFF0000FF000FFFFFFF000000FF1D -:107D50000000FF0000001000000020800000310043 -:107D600000004180000052000000628000007300AB -:107D700000008380000094000000A4800000B50093 -:107D80000000C5800000D6000000E6800000F7007B -:107D9000000107800001180000012880000139005F -:107DA0000001498000015A0000016A8000017B0047 -:107DB00000018B8000019C000001AC800001BD002F -:107DC0000001CD800001DE000001EE800001FF0017 -:107DD00000000F8000007FF800007FF8000005F928 -:107DE0000000350010000000000028AD0000291838 -:107DF0000000291900000005000000060001000134 -:107E000000220006CCCCCCC97058103C0000FF000A -:107E1000000000000000FF00000000000000FF0064 -:107E2000000000000000FF00000000000000FF0054 -:107E3000000000000000FF00000000000000FF0044 -:107E4000000000000000FF00000000000000FF0034 -:107E5000000000000000FF00000000000000FF0024 -:107E6000000000000000FF00000000000000FF0014 -:107E7000000000000000FF00000000000000FF0004 -:107E8000000000000000FF00000000000000FF00F4 -:107E9000000000000000FF00000000000000FF00E4 -:107EA000000000000000FF00000000000000FF00D4 -:107EB000000000000000FF00000000000000FF00C4 -:107EC000000000000000FF00000000000000FF00B4 -:107ED000000000000000FF00000000000000FF00A4 -:107EE000000000000000FF00000000000000FF0094 -:107EF000000000000000FF00000000000000FF0084 -:107F0000000000000000FF00000000000000FF0073 -:107F1000000000000000FF00000000000000FF0063 -:107F2000000000000000FF00000000000000FF0053 -:107F3000000000000000FF00000000000000FF0043 -:107F4000000000000000FF00000000000000FF0033 -:107F5000000000000000FF00000000000000FF0023 -:107F6000000000000000FF00000000000000FF0013 -:107F7000000000000000FF00000000000000FF0003 -:107F8000000000000000FF00000000000000FF00F3 -:107F9000000000000000FF00000000000000FF00E3 -:107FA000000000000000FF00000000000000FF00D3 -:107FB000000000000000FF00000000000000FF00C3 -:107FC000000000000000FF00000000000000FF00B3 -:107FD000000000000000FF00000000000000FF00A3 -:107FE000000000000000FF00000000000000FF0093 -:107FF000000000000000FF00000000000000FF0083 -:10800000000000000000FF00000000000000FF0072 -:10801000000000000000FF00000000000000FF0062 -:10802000000000000000FF00000000000000FF0052 -:10803000000000000000FF00000000000000FF0042 -:10804000000000000000FF00000000000000000130 -:10805000CCCC0201CCCCCCCCCCCC0201CCCCCCCC8A -:10806000CCCC0201CCCCCCCCCCCC0201CCCCCCCC7A -:10807000CCCC0201CCCCCCCCCCCC0201CCCCCCCC6A -:10808000CCCC0201CCCCCCCCCCCC0201CCCCCCCC5A -:1080900000000000FFFFFFFF03030303134202027F -:1080A0005050502070608050020002000604060408 -:1080B000000E0000011600D6002625A0002625A0EF -:1080C000002625A0002625A000720000012300F351 -:1080D000002625A0002625A0002625A0002625A0F4 -:1080E0000000FFFF000000000000FFFF0000000094 -:1080F0000000FFFF000000000000FFFF0000000084 -:108100000000FFFF000000000000FFFF0000000073 -:108110000000FFFF000000000000FFFF0000000063 -:108120000000FFFF000000000000FFFF0000000053 -:108130000000FFFF000000000000FFFF0000000043 -:108140000000FFFF000000000000FFFF0000000033 -:108150000000FFFF000000000000FFFF0000000023 -:108160000000FFFF000000000000FFFF0000000013 -:108170000000FFFF000000000000FFFF0000000003 -:108180000000FFFF000000000000FFFF00000000F3 -:108190000000FFFF000000000000FFFF00000000E3 -:1081A0000000FFFF000000000000FFFF00000000D3 -:1081B0000000FFFF000000000000FFFF00000000C3 -:1081C0000000FFFF000000000000FFFF00000000B3 -:1081D0000000FFFF000000000000FFFF00000000A3 -:1081E0000000FFFF000000000000FFFF0000000093 -:1081F0000000FFFF000000000000FFFF0000000083 -:108200000000FFFF000000000000FFFF0000000072 -:108210000000FFFF000000000000FFFF0000000062 -:108220000000FFFF000000000000FFFF0000000052 -:108230000000FFFF000000000000FFFF0000000042 -:108240000000FFFF000000000000FFFF0000000032 -:108250000000FFFF000000000000FFFF0000000022 -:108260000000FFFF000000000000FFFF0000000012 -:108270000000FFFF000000000000FFFF0000000002 -:108280000000FFFF000000000000FFFF00000000F2 -:108290000000FFFF000000000000FFFF00000000E2 -:1082A0000000FFFF000000000000FFFF00000000D2 -:1082B0000000FFFF000000000000FFFF00000000C2 -:1082C0000000FFFF000000000000FFFF00000000B2 -:1082D0000000FFFF000000000000FFFF00000000A2 -:1082E000FFFFFFF3318FFFFF0C30C30CC30C30C313 -:1082F000CF3CF300F3CF3CF30000CF3CCDCDCDCD50 -:10830000FFFFFFF130EFFFFF0C30C30CC30C30C395 -:10831000CF3CF300F3CF3CF30001CF3CCDCDCDCD2E -:10832000FFFFFFF6305FFFFF0C30C30CC30C30C300 -:10833000CF3CF300F3CF3CF30002CF3CCDCDCDCD0D -:10834000FFFFF4061CBFFFFF0C30C305C30C30C396 -:10835000CF300014F3CF3CF30004CF3CCDCDCDCDD6 -:10836000FFFFFFF2304FFFFF0C30C30CC30C30C3D4 -:10837000CF3CF300F3CF3CF30008CF3CCDCDCDCDC7 -:10838000FFFFFFFA302FFFFF0C30C30CC30C30C3CC -:10839000CF3CF300F3CF3CF30010CF3CCDCDCDCD9F -:1083A000FFFFFFF731EFFFFF0C30C30CC30C30C3EE -:1083B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6F -:1083C000FFFFFFF5302FFFFF0C30C30CC30C30C391 -:1083D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2F -:1083E000FFFFFFF3318FFFFF0C30C30CC30C30C312 -:1083F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4F -:10840000FFFFFFF1310FFFFF0C30C30CC30C30C373 -:10841000CF3CF300F3CF3CF30001CF3CCDCDCDCD2D -:10842000FFFFFFF6305FFFFF0C30C30CC30C30C3FF -:10843000CF3CF300F3CF3CF30002CF3CCDCDCDCD0C -:10844000FFFFF4061CBFFFFF0C30C305C30C30C395 -:10845000CF300014F3CF3CF30004CF3CCDCDCDCDD5 -:10846000FFFFFFF2304FFFFF0C30C30CC30C30C3D3 -:10847000CF3CF300F3CF3CF30008CF3CCDCDCDCDC6 -:10848000FFFFFFFA302FFFFF0C30C30CC30C30C3CB -:10849000CF3CF300F3CF3CF30010CF3CCDCDCDCD9E -:1084A000FFFFFFF730EFFFFF0C30C30CC30C30C3EE -:1084B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6E -:1084C000FFFFFFF5304FFFFF0C30C30CC30C30C370 -:1084D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2E -:1084E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C6 -:1084F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD82 -:10850000FFFFFFFF30CFFFFF0C30C30CC30C30C3A5 -:10851000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD60 -:10852000FFFFFFFF30CFFFFF0C30C30CC30C30C385 -:10853000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3F -:10854000FFFFFFFF30CFFFFF0C30C30CC30C30C365 -:10855000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1D -:10856000FFFFFFFF30CFFFFF0C30C30CC30C30C345 -:10857000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF9 -:10858000FFFFFFFF30CFFFFF0C30C30CC30C30C325 -:10859000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDD1 -:1085A000FFFFFFFF30CFFFFF0C30C30CC30C30C305 -:1085B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDA1 -:1085C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E5 -:1085D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD61 -:1085E000FFFFFFF3320FFFFF0C30C30CC30C30C38F -:1085F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4D -:10860000FFFFFFF1310FFFFF0C30C30CC30C30C371 -:10861000CF3CF300F3CF3CF30001CF3CCDCDCDCD2B -:10862000FFFFFFF6305FFFFF0C30C30CC30C30C3FD -:10863000CF3CF300F3CF3CF30002CF3CCDCDCDCD0A -:10864000FFFFF4061CBFFFFF0C30C305C30C30C393 -:10865000CF300014F3CF3CF30004CF3CCDCDCDCDD3 -:10866000FFFFFFF2304FFFFF0C30C30CC30C30C3D1 -:10867000CF3CF300F3CF3CF30008CF3CCDCDCDCDC4 -:10868000FFFFFF8A042FFFFF0C30C30CC30C30C365 -:10869000CF3CC000F3CF3CF30010CF3CCDCDCDCDCF -:1086A000FFFFFF9705CFFFFF0C30C30CC30C30C397 -:1086B000CF3CC000F3CF3CF30020CF3CCDCDCDCD9F -:1086C000FFFFFFF5310FFFFF0C30C30CC30C30C3AD -:1086D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2C -:1086E000FFFFFFF3320FFFFF0C30C30CC30C30C38E -:1086F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4C -:10870000FFFFFFF1302FFFFF0C30C30CC30C30C351 -:10871000CF3CF300F3CF3CF30001CF3CCDCDCDCD2A -:10872000FFFFFFF6305FFFFF0C30C30CC30C30C3FC -:10873000CF3CF300F3CF3CF30002CF3CCDCDCDCD09 -:10874000FFFFFF061CBFFFFF0C30C30CC30C30C380 -:10875000CF3CC014F3CF3CF30004CF3CCDCDCDCD06 -:10876000FFFFFFF2304FFFFF0C30C30CC30C30C3D0 -:10877000CF3CF300F3CF3CF30008CF3CCDCDCDCDC3 -:10878000FFFFFFFA302FFFFF0C30C30CC30C30C3C8 -:10879000CF3CF300F3CF3CF30010CF3CCDCDCDCD9B -:1087A000FFFFFFF731CFFFFF0C30C30CC30C30C30A -:1087B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6B -:1087C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E3 -:1087D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5F -:1087E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C3 -:1087F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7F -:10880000FFFFFFFF30CFFFFF0C30C30CC30C30C3A2 -:10881000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5D -:10882000FFFFFFFF30CFFFFF0C30C30CC30C30C382 -:10883000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3C -:10884000FFFFFFFF30CFFFFF0C30C30CC30C30C362 -:10885000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1A -:10886000FFFFFFFF30CFFFFF0C30C30CC30C30C342 -:10887000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF6 -:10888000FFFFFFFF30CFFFFF0C30C30CC30C30C322 -:10889000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCE -:1088A000FFFFFFFF30CFFFFF0C30C30CC30C30C302 -:1088B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9E -:1088C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E2 -:1088D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5E -:1088E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C2 -:1088F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7E -:10890000FFFFFFFF30CFFFFF0C30C30CC30C30C3A1 -:10891000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5C -:10892000FFFFFFFF30CFFFFF0C30C30CC30C30C381 -:10893000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3B -:10894000FFFFFFFF30CFFFFF0C30C30CC30C30C361 -:10895000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD19 -:10896000FFFFFFFF30CFFFFF0C30C30CC30C30C341 -:10897000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF5 -:10898000FFFFFFFF30CFFFFF0C30C30CC30C30C321 -:10899000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCD -:1089A000FFFFFFFF30CFFFFF0C30C30CC30C30C301 -:1089B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9D -:1089C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E1 -:1089D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5D -:1089E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C1 -:1089F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7D -:108A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3A0 -:108A1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5B -:108A2000FFFFFFFF30CFFFFF0C30C30CC30C30C380 -:108A3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3A -:108A4000FFFFFFFF30CFFFFF0C30C30CC30C30C360 -:108A5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD18 -:108A6000FFFFFFFF30CFFFFF0C30C30CC30C30C340 -:108A7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF4 -:108A8000FFFFFFFF30CFFFFF0C30C30CC30C30C320 -:108A9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCC -:108AA000FFFFFFFF30CFFFFF0C30C30CC30C30C300 -:108AB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9C -:108AC000FFFFFFFF30CFFFFF0C30C30CC30C30C3E0 -:108AD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5C -:108AE000000C0000000700C000028130000B81581C -:108AF0000002021000010230000F024000010330AA -:108B0000000C0000000800C000028140000B8168DA -:108B1000000202200001024000070250000202C0D1 -:108B2000001000000008010000028180000B81A8F5 -:108B30000002026000018280000E8298000803801B -:108B4000001000000001010000028110000901383E -:108B5000000201C8000101E8000E01F8000002D87F -:108B6000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45 -:108B700000002000CCCCCCCCCCCCCCCCCCCCCCCC45 -:108B8000CCCCCCCC00002000CCCCCCCCCCCCCCCC35 -:108B9000CCCCCCCCCCCCCCCC04002000CCCCCCCC21 -:108BA000CCCCCCCCCCCCCCCCCCCCCCCC41002000D4 -:108BB00003030303034202025050502070608050B0 -:108BC0001313131313421212505050207060805030 -:108BD000030102000000000000000000000000008F -:108BE0001F8B080000000000000BFB51CFC0F003FA -:108BF0008AF7093230288920F8C4E0427606864D8B -:108C00001C0C0C5BB849D307C32C0C0C0CDA4CE4DD -:108C1000E905E1DBBC0C0CCF8098810F555C80131B -:108C200042FF075A20C80AB4830DBBFEE56A08B6A6 -:108C3000A70A0343011033283130E8AB22C445D4DE -:108C400019182602F99150B1AB403A4C8D7C378F00 -:108C5000E2C1834F1AA3F2971A426807A8F8293491 -:108C6000F96550F9621D087DDA18BBB9253AC4D9F7 -:108C7000BFCB1A953FCD1ABFFA93F6A8FC7568EAE8 -:108C80001741F900B9FAD21DD80300000000000016 -:108C900000000000000000001F8B08000000000022 -:108CA000000BED7D7F7C14D5B5F8999DD9D9D9CD30 -:108CB000EE6608096C20E024861AFAA25D20609016 -:108CC000A843401ABF8FDA15A9A62DED77B5D4E2D7 -:108CD0000F60EBF3097DCF36931092101017B1D5CA -:108CE00056AB2B0F2DF56B25B5D4D2FAA38B581E9E -:108CF000B6EFF3BE4869EBD7621B7FE18F228D5A36 -:108D000084B658BFF79C7B273B33D94D36407FFC58 -:108D1000F1C207863B73EEBDE79E73EEB9E79C7B1D -:108D2000EE8D0A35F0A133003EC09F0B016E0F019E -:108D30004045EE695C7F7E4F7F03C05188A47BCBAA -:108D400001D62860022B5B072399FB25C09F3A853B -:108D50009557C91F8EF75603DC51F2957B117EB5EE -:108D6000A540803D7BDB00B267B1EFA1E816280586 -:108D70002881D476FCCE7E12F7B3F68E05276720C5 -:108D80009AEBBF027C0033F173957EA884E0E00388 -:108D900099FD73303917C601C860FFAC863ED68E88 -:108DA0007240CE60BFB2BC50FF554DAE1DEF53D6E2 -:108DB00055C86AA23DFC475E529A0C17865F7DB08B -:108DC0007AFBD37539F8B320527EE89FD87F1450D0 -:108DD000081F7903201D8E86212357176EE7589BA5 -:108DE000B1FD693FD2F133A589B30BC3D974EA69E8 -:108DF000D3E8D9D5A6433600C05036FBEAD9330CA8 -:108E0000E696FAA1F5E68144F4D20C8BF0E90CFB6E -:108E10003225D588751280D1D78FF491F0FD22CDFF -:108E2000CC53DF7E4239A38F3D5E46C720F0F680EB -:108E30008DEF7ED65E10FBCF43AFCBB07F2627C130 -:108E4000DAA1FD5B0D27DF7F682AC0BE30D2DB448C -:108E50001CC0A7A7202EF8FD51699876049F1583A2 -:108E6000B73312DD4BEA7CB97ED9DFA01172C94954 -:108E70002056E6961BAF5C229D2A905F86F4F29402 -:108E80005CBB2AF22D0FBDAE11F41A989B684D30D1 -:108E90007AAC6D03EB25473D390666260F9D568952 -:108EA0007A767F4A3983CBD33E40BB983F960BBE40 -:108EB00058FCBE7C92F8ADFF1BE1B749C83B409A15 -:108EC0009E03739384A7B7BD7CF38B4DE2C17248B8 -:108ED000C9583E94EF7288DFCF1E7E8DCF33FBFBE7 -:108EE000C3E0A77676A2C661FDAC11F80DCCE5FA19 -:108EF0006FED3435B345227DE4C2F321D45FAC9EDF -:108F000024097A687D80F257725C01188BF8999079 -:108F10008800ACAB6DD686D33FA02B7FEAB7E5AE19 -:108F200066A8DC7D9875837885C2F9E9F4F0A01E07 -:108F30005D62BDC4DAD182ECFD99D86E79AC6A1657 -:108F4000E0E8E8C72FBE83E4933FC0797B82C1CDC0 -:108F5000127A56A6F6498F401590BE97053CF5C388 -:108F6000E0036C58E674F6C4F775A21F6968BBDEAF -:108F70007AC7A08CD347E063EB75191EA77606F17C -:108F80005112442FEF7B3F7BAF874FFDFDA996FD2C -:108F90004681FED212C9D348F57F23E465887C164A -:108FA000E0EB7E31CF14E833E1CC9C1CD9F275B2F2 -:108FB0007274CA72C2BAA7F5A2809C5890A279C3F3 -:108FC000C0ACDE69A397973C729275C22F94C6F02D -:108FD0007128719217868F4272AB737C2AA69753C1 -:108FE0007B12CEF1B3B00551463AB0F15E65D7873A -:108FF00038CDD710DA398EFA6C7084AF244B42EF3B -:1090000073B89BC43C3FBFB98AE30FA27D0FBEACCF -:109010003DCDD99E0C551E39E7786F94B87E63F02C -:1090200059A2A7B77F45227C6548583E566F8BE80A -:10903000DFABBFECE70ED1DE06095AFBC27C3E2D4A -:1090400072AC87CD92D0131A9F675EFDE447B99A40 -:1090500071F27255AC5E5F28E55F77985514BB34AA -:109060005278DD29F5D9EB413626F8362ABE9F29FC -:1090700095B9F85E2CBE579D24BE1387E25B949C85 -:109080004D957CA35A276F3A49FC821EFC4E975C93 -:10909000CF1072562CFEF63C182DFEF250FA163503 -:1090A0008F668F12BF2D2749DF0A9F6D2709FC0AA3 -:1090B000CCDBF305BF2DE0F2A1303B1CFD9C62F13F -:1090C0007B7464FC00CE637FAD172D53217B0D6054 -:1090D00002C0D3ED2F5A9692C3CF04AED747DBFF21 -:1090E0009E91F927FA7FC3326B73FD1F687FC3D54A -:1090F000BFC2E40785ADD87E7F51ECB8E16DD7B82B -:109100005F96DE76F57BB2747FB5E8FEFFE81AF76E -:10911000BBD21FDDE30EB3719F597CBF7F38497905 -:10912000AC16F3A559D25DEB4021FB7D86E0EBDD6B -:1091300036BC8D6F01F8A902AFCE22E1278AF63F37 -:1091400055247C9F68BF0FE12B46863F53C0A78AFA -:1091500084977C7C1E165A3FE74A36FDC0E57FACFB -:10916000D1781CC45CA340F082A17113AB39F5AD7A -:109170007EC67BAB23A0AF29A7B809C545560324FB -:10918000306E7217241B7D187FD9F9E57B11EE1D17 -:1091900045D37B75E013927D0F1E8C6CE9ADCEF547 -:1091A000B74A4EB64A284B6BA2FAFD145F49B54A3E -:1091B000EC596185758CDB1CAB49B45F598EE3308B -:1091C000748BB5F3FCB2CB7661F9364DD265266A65 -:1091D0005FBD60EAA6CB0D06F7FEAEE7CE40B869EC -:1091E000E36A3A485FC6259487B171D594CF61CFC1 -:1091F000C58BB97E07E10FB738CACC0EF864EB27F0 -:109200005CDF3F9D74973FD1F289DC7AC2FE5E91AC -:10921000707FCF8D07B8DF3187EBED6335A9DF7243 -:10922000BC3E546DF1F8028DB7D48AD2F836BCFF3B -:10923000452A6F68AFD73BD8B83F75CD510BC717DC -:109240009680C6178DBF97C532B0F1AA8D00B75E64 -:10925000F04CCF2C28EC7F459B16BBF084B87B9C50 -:10926000ADD7E7C75BD5DF9DF00AB3978EED0A9ABD -:10927000884F74AF9C0956235F07B293B07FAB341D -:10928000C9F93300B5C8575307E463B399CCC8ECA8 -:109290007D3AA6C5032866D0AF21DD372168257B3E -:1092A000DFF88E96ACC7F6DFA3F675F1FDD6C69A49 -:1092B000F1181F79BC6DF54485CDF71FB55913150D -:1092C00066B4EF6CEBA1E7A36D697ABFA3ED4E7AAC -:1092D000DAE3434D62D8E393B11FB303E5ED989F02 -:1092E00099460CAF8DE7FBC8BFDD20F44897782A7C -:1092F0004A562EC5EF7198D60B88D7FE79584E374F -:10930000C0346459BAE929B9948DE3864A988E6DC0 -:10931000EF7AE157FC7B154C0F30F97ACA6CA679CD -:10932000706BA32F13A8A6E7C5D8DFADA60F98C909 -:10933000039138C3CB41D740CC5DD621B926D2406A -:10934000FDC77B0DAC7FC36E2CDF3093194A40ED17 -:10935000CB11A223C4B1BF99074CD2E381261FC50C -:10936000E9D24DBE20D271A47ED248D761E25573B6 -:109370005E77C3CFEE779799C6FBCDA07C70FA3E9F -:10938000EC637A62F70BE37D5639E141E3674F1EE8 -:10939000478CF9326894DE26E86CD3FD5884EB9D47 -:1093A0008DCC3FC47860217C369E776D6CB8788216 -:1093B000DAD8958073F0994E60BC556DCC88671FE4 -:1093C000BDF7C23F8F46D1CC5CB92B367DCC95F52D -:1093D000397CBCF0136495E4FF5805FFDE157B4A29 -:1093E000BF32EC6C4FF27ED73E5FEFFCEEA7FE8EF5 -:1093F00055DADFF76B57D6E7A93F897DCFC397A52D -:1094000032D7C34FBF1068FE1ACAA7A0EFEE175E8F -:10941000DB7B26D2FB800C280FE97DCD240F287F33 -:10942000A8479E62F2D0CFDA1BDBB2E137CEF91C3F -:1094300089BBCBE946864003E71B76F55F821F3F79 -:1094400015F1DABD225EBBA72D46CFA7DB0C7A3E15 -:10945000D55647DFB36D712A3FD9D648E5C7DB4CF7 -:109460002AFFA8AD85CA3BDB12547EB4AD959E3B66 -:10947000DA92F4BCAD6D193DD34D7C9E6F684B51B3 -:10948000B9AB6D35D5B3C7FF31A6359CF2F7CF75B3 -:10949000EEF2C5C659B9F9CEFE7E34E62E5FA47F42 -:1094A000D4559EA7B9CB73E10BAEF62E3C7EB5AB7F -:1094B0007CFE40970B7ECEEBEEF2ECFE075CF0E715 -:1094C0003EE72ECFDCB7C7551EDBE22E47E2875CB6 -:1094D000ED0562EEF256543E5C7F917C74C56AC61F -:1094E000E495BFC1EFD3839F737D978B949FAB7A35 -:1094F000AA517E5A7C71CB40F9E1F294467D260D4B -:1095000095139B6F23C9978DC7DF5AAEFE479E8682 -:1095100097A7A2E5A141895B30541EBC7CF7CAC75E -:10952000103D23E4E57FE4E01F430E607E19EBA4C9 -:10953000F0BA9AC7EE23BB35B015C8EEF3A30D5DA4 -:10954000E95887276793F9F6C1AEF5CD7D4466EDFE -:1095500004CAA10BF749034A01FF56AC73018D7F82 -:109560000FD6A67D284F1130A6CBD30096FFE096EC -:109570000957B1F6F709B8AEFBC1923E02306E82D0 -:109580009A44FF2652EBF673F6CA3CEE613FB77D74 -:109590003FD29AA1987F830BEFA1E3E6FB38F2C498 -:1095A00059ADBF66F340DE326BDB5AF60CD5264D63 -:1095B000D9C0FAE544B7A52183E0CCC68CE563AFFA -:1095C0008255CC6E639FE5B0096887CDF699CFCA06 -:1095D00033C93EDA8F4FDBEED9269E8F8B7978998F -:1095E000CFFC25D287C1FD6A3838BBDF11F90549A8 -:1095F0004BE271ABF8FD0C457F79DC653FD9E35355 -:10960000948499C8C3AF23B2D8E7D1E3AD3C3EA25E -:1096100002EA8742F0AFCBEEFD31FB59CAFC0219DA -:10962000F188F17D2838719971E9D943F150954459 -:1096300012FBC17DEC2DAC9FCE31971B49473F9269 -:1096400022F08999848FAA737C54256E26F2C8D1A2 -:109650009F043E763BF67E9A141B80FE700EBFB5CB -:10966000C144EB95E8B78E51894E9D11B7FD354B3E -:10967000E17276967876FAF3DB87001DDC4F1ED711 -:10968000A861FB6B1A9B35B4AF0D886BE87F7786BA -:1096900017950E676F6F68E3FBE3BDA80F03B84F24 -:1096A000AE8B7DF2183D3BC38FB4E0BC3B5ACFE894 -:1096B000505DB89D48DCBDDF5B5217F2ECEF6608E9 -:1096C000CFA051E6D9079EE0AAE71FA7F8ECFD6EF0 -:1096D0009046C6BF4BE06FC3752B294DCF4BA78C6F -:1096E000CBEE0EC4DCF8FEF5E8C7EB97F8FBF47C94 -:1096F000789D2EBA15DA9FB59FEA583595E1719697 -:1097000098731E2C11F2A58ED55218C702ADD0F752 -:1097100010AF1F4E50DC4B0B270CA8C9EDD36A3895 -:109720001F1C74BA51D47B41B1F74B5331F4AB25B4 -:1097300023D58AF2A455B179240DAD673F3F27EABE -:1097400077BFFF2FCFD13CA9D0689E48069B4779B1 -:10975000FA511473A5827151D94C29B86FF3173996 -:10976000996FBEAC10F3595B9830B41ADADAE3792A -:10977000201E3C36287C1EBF21E0C14A513CAB581C -:10978000FCFFBD48FCED7E18FEDD02FF1E7C16C20C -:10979000BF4BE05306463BC5380DAE67012E359CE6 -:1097A000F918AF89FECB849E02F822F1CDFEFE921D -:1097B000E04BB1E3F96A91E3792DC78FFB900F6C11 -:1097C0003C5B86E34746E0F19AC2D7192D9130629F -:1097D00035B4D4E795AB1F0B7ABD6BCB95F5C5516E -:1097E000C9D5C3A2FE48E3F8718E2F3F12E3786C0F -:1097F00038BEFC50F0252DC3EC5730FE78A65877C4 -:1098000060918B2FC745BBE980CD971B5C7C3932BB -:109810004ABEEC2D723CC773E33920E4EC17C3F168 -:10982000C501FFBC18FFAFC5F829AE7EBCF39A0E88 -:109830002B4CEBF26F9599B9FE185CBF6897E06E00 -:1098400054CEEDB0EA09EE157C2FB5F07590C1BD90 -:10985000EA84034874A0FDB616F74ACF03F896725F -:1098600073B368FF77546FE160FB879DF53628F38B -:109870006C3C06F07DFBBCBFD8706F3BE18E775E21 -:109880006FC31DA5F6128378BCE71CD78F3B9710DA -:10989000DC907CA45871F6AABF3C49797D651049DB -:1098A00063DCB14B49519C193721303EB92A10A7CE -:1098B000149691E2D4158B793D5DD128CE1A80148F -:1098C000DC89F1B97285F64D3EAE24753FDA11524E -:1098D000D2A24D57D097B463FB630DCA0BB3F1D935 -:1098E00054F2D91E6A87E183EDDE5112DD8572756F -:1098F000DB24D540B9DA35E9268AA76F6AE779858E -:109900009B2E56298EB8F98508ADBF6B95F82711A7 -:10991000DE325503E3C5AB427F796E292BF7B7974B -:10992000EAD205340EC2DBF241624D83234F91E14E -:109930001D88539E1DC5E136B5F0FD1EF65389F511 -:1099400057CD3328CE68A01E63DFBB1B55B25F37EF -:1099500055D5CCC5FE36376A646F6C5E58D34E71F0 -:10996000BCC610C531CBC28684F1F7E8B92A33C032 -:1099700059B9DC68477B33322B0418772AABE2FDF8 -:1099800045CE028A43F9219DA865CF688F0AD9B1D7 -:10999000D8DEA2ECE7D09E690CE832C6FD2D737FBD -:1099A000FD384A85E33FF27F01E2E39F2803D2DDE1 -:1099B000E66F343D587FD8FCC668A648B86C717015 -:1099C000911E05B2338A804B17099729122ECBE1DD -:1099D0000270E9B0797E10E7F9851AFBC3F31B1D0D -:1099E000F986D5DC7E77DA2D7ECFF7D1E68B2EF7A0 -:1099F00047CA695E9E0BE7F27CD1E1EBDB79A223DB -:109A00008D17C097C3531E197EADB0FB0A7DF78F2B -:109A1000BB2986FAACBBE2DFC4F366FEAC14EF2BC5 -:109A200057C7CC303EC5F7CA9B5BCD3CFD7DC3CF4D -:109A3000F5701D2486E54399C0FF10C31DF37EEA2F -:109A400014061F290CAF96FB86CDBFD414AB99E644 -:109A5000ED421FCDDB002A039C37557C1EFB219570 -:109A6000A8253D63462B1DF3C7DFB487E6CF7F579C -:109A7000CA2035127FE24847AF9C78E522008E72FB -:109A8000F5A9CBC9237E91577C9AE5C4DF2317350E -:109A90007FFCE922E13245C2658B83537BA4A2F4AB -:109AA0008A9A2E122E53245C96C3AD9DADF2F5DC3E -:109AB0003AD6817900FEF3345779ED7921F7F739F9 -:109AC0006157B96BA6BBBE3ACB5DBF6B96BBBE7A86 -:109AD0002EAF1F567DF3709FBFD879F2EA49CE931F -:109AE0003A6D78F848E308F34AD38358BF4C3120E5 -:109AF0005B4EEB5546AC5B79F7C96B543EFFA7F85C -:109B0000F9BEFD26450FA21FF98F3E4E45E5F8DA56 -:109B1000E31D095F5BFFBE260B7BAB403E38C4F8FC -:109B2000B9083F84E268E718F3B5E6DF303AFA9FF8 -:109B3000E1F9F0DE765F54930DAAC32F66F619247F -:109B40001D71988B2B149E87C3F880F6900A891696 -:109B50008C3BAFA9F2913DA284475837AA1C7A2BBF -:109B60004FBE5E2E2E05269EB3A04F06C0DCD779D1 -:109B7000BFA13810DE11E82767BA1453E8CE0418E5 -:109B80000386C493C1789E0040938EFAAC3C78BAA9 -:109B9000DB5D42ED4AE626F8A06414ED2AFD944709 -:109BA00073DADB1D01DF20DC4DED322FA9FC83B120 -:109BB000B976FDB114BDC4FC59D9914787E7252872 -:109BC0000FC517CF52DEC38428F9656BCB6F70E5E4 -:109BD000897F45AD71C58754BDEB8B12EEE3565DB1 -:109BE0006FF60F23E71D4C5D517CA46AA9D95F571E -:109BF000186E307F1FF340F3CC832E359941FBDD87 -:109C00009A1CE6FEBC92A27863B75436BDB7210712 -:109C1000A754314DCBF00AC74D0BFDBDEEB1BE3898 -:109C2000DAA90A6CD8279DC3EAC90BE3CEF8A5F7D9 -:109C3000A954296F3AC77387EAB6A7D68C20EF23B9 -:109C4000DA3D6A3C992F2EFAA0CAFD637F28FFF700 -:109C50005742CDDF522B86D2ED47485FF46FC740A5 -:109C60000FC6DBED3C5AA56ACF734887B5150B626A -:109C7000C38D9739508707F9C258BC2F64EE5067DF -:109C80000E8BC74E75661EFE858B8B7F03F3D374D8 -:109C9000062A8BF339681F494CDE4383F218874E3E -:109CA000D457CCFFE8657C0BD5C7612B2BC7E66981 -:109CB0000985D94BB7346C018C5BFB99FD44FE8957 -:109CC000DCC4EDA73A6E0F99EC0F8E23DA34BC5D3D -:109CD0002D7BCA0754B73DB4A66D2738F3DFBCE728 -:109CE0002DECE7D650F3F3F9E9519C3FBC99C90B31 -:109CF00033EE60539B46CF5BDB747ADED216A3E76C -:109D0000FA3683F2F33BDBEAA8FC55AC3A1BCF45AD -:109D1000A57AAA19FD7A625B9F5BCA5E6D46DA522C -:109D20009C20330FEDE45E2C53BE1F7303B13C89BE -:109D30007F7FAF2B3D0FE30DBD411B7EED3CD35527 -:109D4000BE73CD5C8417718648F77DF3D0DFDF3CAE -:109D5000C9CE4333B54F38D6BD9A003FAF42BE2B74 -:109D6000D5EF5883FD0715BBFC3D6A3F570613F13D -:109D7000096ABCFCD1C00EC2875400EBEFE381EF4F -:109D80005379F3141EEF87C58B46A0238FEFAF5195 -:109D90000D1EEF5A5C46FB472A939B1AF66AF3188E -:109DA000817791ED8092E4EB9D38DF5778DE8CB0BF -:109DB000AE093C469E0F26C5D1ED736BCA2FF2AF9C -:109DC000D3A7BBDFCDFED1D1456B4A9AD87CB4A5D1 -:109DD0002F8BACFEB19A9C13C07DA4F9FB6859513E -:109DE00063596E3714D9FFB8809D079924BFC9A65F -:109DF000B7A273FB6385879FFE72BE6F1714E7538C -:109E00008AC5FB73AAE847B4030F4DAF1CCECE2A18 -:109E10005FE843636C506F94CD0FB9CA7A539908C9 -:109E2000DAF072B46182AB1CAEAF7195FDFA875D5A -:109E3000F54F965FADC25EB4E13FE61957B3779C2C -:109E400045B6FB6269E25F0233314E05752946D79C -:109E50003B3EF300D13F34385F17749A4D942F2E58 -:109E6000FC8A0B7959B7BF9FD76956B1B2617F9F02 -:109E7000C9BF9BF6F7E9BC6CD9DF3FC2E1D15F6691 -:109E8000E58EEEA99D167E870E8ADF42550A1639A9 -:109E9000F44B787C7317E2377E492666B1F7BDEF45 -:109EA000CB5C6E211D73C2DDA5713FE02753BE164A -:109EB000C3B8E5BAA90FC480F49E94775FF0D900C7 -:109EC000CF1BAB0C256E4739667A6D00F3050F3D4D -:109ED000201B7C5D525EC275D167F17C7D15E2FB73 -:109EE0004CB48FEA78DC3A24BE131FAB73F0837C4A -:109EF000F5943FA2F1F5FDF79864C9C6F3ED52F36E -:109F00003EEA1732520B9BF755160CE0F92410F677 -:109F1000DF445E15CA13198AF74D62F4C47DF6C991 -:109F20008B07DAFD8CD6C612DD8753A46669DC0781 -:109F3000A4076C7B72ACF4017B7E17F9857AF9CBB0 -:109F400029C0757CEDD4075A912E81EC97C06074BE -:109F5000FBD749293018BDDF0E70BC024BD2407AC6 -:109F6000BB364D74F6D26BDD20DD332EBAFF4CD4F8 -:109F70008F2579BD413885C19D3D14AE37989EAB84 -:109F8000A21D3785D3D1DBCFD100DF1FF1E261B74E -:109F9000EB85DF1410FBDB5A86F6397E32F5A61806 -:109FA000C6B7BBA730FED717E6FFA600CFBB324E21 -:109FB0007C99F46FEFA4DB685F735DED16B22B8FB5 -:109FC000327B02F3367BABF3D7EF6EE3793217C205 -:109FD000DD2D358C3FDD07648AD77AE1BE1370DB57 -:109FE000CD5A95DB2F64F2F74A60E6C8F22747B6F0 -:109FF000F279394AB953698AE2BC1BDF89FCF58BD7 -:10A000003273E63A851D40EB6CE5D23438F31E8F8F -:10A01000097E3D2DF474B08ACB47AFDF929CFC8B58 -:10A02000B1F7731DF50AF1AD903CFC58CC877795DC -:10A03000782B19014A4ACFE7572BB17FFEF97CC72D -:10A0400079B04E25A3E9887FDD6D92D3BEFD869958 -:10A050008C6A0E7F3614BBE4E7F3D10F52E279FD30 -:10A06000F5FF659A65DA4CB4B360462D9E5B50AC43 -:10A0700000C2AD57B22DE45FD4FA286EBEAEEA86B8 -:10A08000BDD538EE7A5F1CC1D6543DD582F6C5BA2F -:10A09000DA4774A4DB2BFAA22A6C27105367D48EFC -:10A0A000A5FCEF048E3B5CCFDA75F0DBEE3723E4E2 -:10A0B000FC5EDDAC417C993E3853FB1BE883772185 -:10A0C0001EE3C616A3739E7570289D79BE4077D592 -:10A0D000103ACF71D23980749E81EDC6F3C6311823 -:10A0E0009D2F74D119189DCFCED1B9B78AD3B9BBE2 -:10A0F0006E4B4F8D93CE754FEDAD36B07F4EE7076B -:10A10000357E7E37847476E0E9A57358B2D79FBA5E -:10A110004EB43FBD72CFE87E29E263BFF769FBC84A -:10A12000EE0C8F4F7C82F8C0FC6594833BA482EBDD -:10A13000D227116EA475697D80EF57DEA57139674E -:10A14000ED5F89FD42B968DF5E6FC57A7899B66BBD -:10A150001EAE870CEE6AC2434F913F3C0867C1B008 -:10A16000EB28ABB79CDA0F7BDA376154EB316BE746 -:10A17000266A47F3F46FC029ADF3ACDD761A97E297 -:10A1800069F734DB13AC9F8D9AF0375D74F82BDBE5 -:10A1900031B1A4471E94B44BEFD9F250B9D40D5746 -:10A1A000785D4BF3756DA85D4372FB6CF7DEDDE8FF -:10A1B0009FBDA29BFF07F935DA7960DB8195A1E4A9 -:10A1C000A3482F6607521EA9F58D92CC1A5657F94F -:10A1D000201DE5FBF0EEF568BC6D0FD5F27520385B -:10A1E000CA75E98026F204C7301D55CA9EFE446B2D -:10A1F000BE78C33302CE6B37FF56CC2705121467E7 -:10A20000EB8C5DBEB39FF1CE6C49433E3DBF3494B1 -:10A210007C16E9A3EA29939657112729D46E79C2AF -:10A22000DAB5B781F4EE803C465418C74D6B8CCB41 -:10A230004519DD0E6914528B639CAD62B13517F57B -:10A2400058159317841FD7BA4F4AE6DB2717F41E19 -:10A250008B48E4F15FC67D6A5692F2E216368CE0D6 -:10A26000DFF0FC3C663FFC0EC775484D5F32C541D0 -:10A27000779B4F5F9312975E84FAF47CCEA7D251FE -:10A28000F2E9CFC2AE8685E534F80B4F5C48E77F34 -:10A2900082115F02E3F1417F5A2F73C8D1381F2426 -:10A2A000FB46817F130CECFE00FDBFB08FFCDEDEB1 -:10A2B000F055DFC6FB792C5D8D4F3172FDF6B2F59E -:10A2C000BECCB1FE78E35683FEB4802FDC2F879B93 -:10A2D000629D4BFBFEB9FB85DC79084CB0EA307F10 -:10A2E0006895CCE3E877947C85F211565B013D508C -:10A2F0004EEB18D97FEB445E5BB7C86B5B2BF2DA91 -:10A30000FCD6AAED08BF192081F1C9F6F353B4EFCA -:10A310001F5534BD834E0CA5CEC575225A6ECFCFC6 -:10A32000C7E7A37D3558B6EEEE6C66E38DC6ECF25A -:10A33000ED347F3BDBB9BEF94CF057F351DF18E247 -:10A340003CD6E6C645A5304C5C325CEFCEA30BD5BF -:10A35000865C65ADAACC5556CB270CBB7FB10FE30D -:10A360004515389E7E88239E05F286A70665829352 -:10A37000E5690359CC3B98A3C6B71878CEDA9DCFD0 -:10A38000D913E4F6E08F30303413DD2C21178D7CA7 -:10A390007FB564764D1FEE07C1182E17982FE894ED -:10A3A000874272F1F7A68FAFE4700CF32F6EE98845 -:10A3B00002E6BBDC32FB97F1AC817AB53F86791AB5 -:10A3C0006B9826E960DF37CEFEA5912FAEDCAF2576 -:10A3D0009705917EE104D95F9186243DFFDEE31A63 -:10A3E000899F7705F93A3755F053417E36E4F8B93D -:10A3F000AE91F1B32137CFD72969AD187E7E0CFB22 -:10A400009F897AE8F7E4B7AD6FF4B5A01E32A08F4C -:10A41000F27037D6FB7CD8FEDF8B2E365EE1D94C4E -:10A420003F129FB2095C1736C6151FEA917F383973 -:10A43000FC4B3FBD2F420E7F984F0E97D9F250B282 -:10A44000AF355FFEDDD4A0E4E2D706E417A74B0BDF -:10A45000A78BEFEF4297C1F5424BAE40B959165367 -:10A46000C9EF56CA7ABA68DF88AD7BB86F749D6C45 -:10A470001AB8EF04FFE1E7F735E1BAED585FDE0FF8 -:10A4800006793BF2860594FFC186867E192B7F688C -:10A49000D87DD18C7FC0798F89373FE350D0BDEF15 -:10A4A000F44ED5A252E457A1F6DE6CDBABE3395B88 -:10A4B0003B4FC3FBFD3A1952F9CE2FFAD120263A71 -:10A4C000F4A944879BD95A3B0DE9F1A1F9783EB331 -:10A4D000BBAA631CD931E27CC375DB9ED115079EF4 -:10A4E000D7296CF99B3E743C367DAFC365B2CC5125 -:10A4F0003FB3D755DF5B6FB03D519FD96DC1107B26 -:10A500009A4A6A2FEE3BDBE738D46D73B3B46C160E -:10A51000C09BF1F194F02EF63CC73B5BD774A1BF12 -:10A520008DF6D7794C4E5EFBAE1CEF605F97DD7DFC -:10A53000D67C3CE77A08B8BCD8FC7963EB9A71F911 -:10A54000E4A2107F2E0EFD75E46B7AC8235F7D9721 -:10A550009566E1F4CB57A2907C09FA1CEEE3F480F7 -:10A560003BC7E6E553A1F10CF2C9AE27E4CC5BBFD3 -:10A57000503D26578B433351AEB2D139C5C895C033 -:10A58000D7E6DFA9E23B925C69AB6503CF75552B3B -:10A5900009D29B3DE51D96B8F791F23EE5F4347E75 -:10A5A000BFCC607E3B64D19ED0CA4DB2A343E2FED5 -:10A5B0009E40AD5B6F2A31F7F989586B226BB78BE0 -:10A5C000F14B6DB54AFD0EEE2387211B8C6299EF8E -:10A5D00097A2FA43BF22007751DC93D5CB1BF7B487 -:10A5E0009F8AC85BC39C5EBAB70D3E3D429E8BBB43 -:10A5F0009FD8E2E1F36CBCF010568C430EBA17AE54 -:10A60000A7C021879F739BB877D4A6BFB9ED4ACA6C -:10A610002F0F822F4EFE41EC260BFDBE2E319F7B6D -:10A62000F0399BCEF3EAE4AF197CBFC592AEA638F1 -:10A63000837DFECCEECF3E7766C38DC4FF55389F39 -:10A64000F2CCEF3D21EE8F1DFB4AEAF7E887587FF9 -:10A650000203EFC97CACED38ED575F907D43C6F83F -:10A66000FE33A1710477C140BF3CCF312F2F10E7DB -:10A670003900FAE47CE7BDFC56E0299487270F7384 -:10A680007FECC9C3EF901DFEE41F7C1994BB278F9C -:10A690000F9FFFF098F08B6CB8C7FEC0EDB3C79466 -:10A6A000BE927CF65DAEFF0CF7070FBBE515943E3E -:10A6B00019E5E5D897F7C9181F78AC4D935E66FA8F -:10A6C000E77C31CE0B0EF7CBE8378D34AEEF79F85F -:10A6D0006B8F737B13B747B737BD13C2F8FFF6C74D -:10A6E000F9788F8A73B285F07DAA8DE7796C7F3C0B -:10A6F0003F3D9ACFE7FE71B3DF28CF6BD77ACE5BB1 -:10A70000CDD364F739AFD38CDFEE266E77ED56E20A -:10A71000E193C1C77E5FD2149770BD2B85CCDE0F4D -:10A72000551339F73BE322A507BFDE7E35E6B75E5A -:10A730001936A51896EF9226B3B23E41067F0CF368 -:10A7400037DEC9BEC0F05FDB5A42F91B9D0DE5ED57 -:10A75000786E73ECF2DA5DB88FDC8B1115CA5BB8DA -:10A760006B2DE62174E27F5939B03E7D119D930037 -:10A77000AE0F98456B28E3C4FE469E790EB9FC0ED9 -:10A78000E98340AE5E217AA99E7C90002C1A5E4F30 -:10A790002DE57ACD627F3EA07352EEFCDC312DAA0E -:10A7A0008B7EA59EF6CF2EE1F23862FEF829F65395 -:10A7B000065B3483D15FADF3E9198487F818CC0FB9 -:10A7C0002C59C80C203C1F10D377F98C91E9BE1688 -:10A7D000A085C7B7FBC039BF9A4BB87D3FE1DADB34 -:10A7E00025F4238EC699144CC3F2F178BE79714BCF -:10A7F0009BFB3E915B1A1E21BDD809991E5C4FAC94 -:10A80000061FAD67BD75FB7567FD2B4B24911F6659 -:10A81000F31F0C6516DDEB484138A5CE6706A3276C -:10A82000CF7FC543D791F81F59EAA6FB68F9B21C40 -:10A83000F93F7364FE9F6A3F36DF86CE8F76C1B7DD -:10A840001B35A0FD9DE1F5FA50BE6DA175AEA42E9D -:10A850007F5EEE0D2576DCD672E95D0D521077E451 -:10A860007FC9E367B5DE0785FB95CBDDE31B8C3342 -:10A870001A9689FB7FE35919CF7733998E6701CFF9 -:10A88000F198807610337FC85F933DFEDA6D428E7B -:10A89000343840F5D92CB0745A37785E9A9D877257 -:10A8A000911C8E637CA2470FD3BD48A81F799E0ED2 -:10A8B000CFE72FE528313B600026B37AA14A192C57 -:10A8C0008CEB35097C25267798C77FF08D83E88F40 -:10A8D000841BDCF968CAC192177DE7A09DE6390F99 -:10A8E0007270F972F25F3C7C1E6D7EFFC325229F61 -:10A8F000AD04C2641789FA85F2F46CBBDEA6AF71B1 -:10A90000224279395D0725A247C5E4C47DE87FC1AD -:10A910002F65E0F99760E23DC6AB7E3693BE0FDD52 -:10A92000374854235FDE3858A27754179317994855 -:10A93000B633F8EA8301F29FAA416FD6B0BF7E8991 -:10A94000F8288DD3282F6BD54FFDF70586C9CBB2DC -:10A95000F71707CB4A9AF689D7D54ED79CFB979520 -:10A96000A1E4CF4B1CFB9741B19F3874DFFD769279 -:10A97000F3D1EE6F945F76379DEB2F1F0F62FFFDD3 -:10A98000D30BD04E595701AEBCBC7595BCFCEAFA4E -:10A99000290B701F679DC8BBD337BC73513BE9DBE4 -:10A9A00004C5F95633C1437AC25EBFB84FD2187F8F -:10A9B000E9307AC34B870DCA3ECA8BFF6678FFC564 -:10A9C00067219FE23E8ABB7DF346BEAF6AC3BDA24C -:10A9D00037FFA184E6ABDE89FBD0139320F234DD90 -:10A9E000FB1F1370F560E39CC418E467F43863310F -:10A9F00074A0F8542FE9ABC4F5786DF92363F8F926 -:10AA0000FEF9FA21B2CF65DA872E84AFD71E2F3434 -:10AA10005E7B5FDD5BFFF608BF4FD5BBFFE58DFBBF -:10AA2000DC87F465703DB8EFF411F6F467F2C6AD5B -:10AA30005E2DE1F1E84E6341E2F3382EC59CFD2A1C -:10AA4000A347A63C4A7EA2FFB2FA2BF08A3E1BDE49 -:10AA5000CE5B5384DFE62F4FD1BAA668A656C7C691 -:10AA6000A11D90716681966E277D65DFFF80645D14 -:10AA70007C361F2F8E2B00DCFEC5F3091F38C60D58 -:10AA80003147BC0BF58AF0D34E03BFA787670EE5AD -:10AA9000EFDC1E9E771E5BC6CF334D54F2F37BFC7A -:10AAA00012DDC7F7B94E2F9F0BD52FB4BF79FB2D01 -:10AAB000EA02B453A6E8ABF64E62787759A549DCB2 -:10AAC0007739E64FD13D39BDFFEA832D80E31F7E04 -:10AAD0009DEBF4AC738A9EA0FBF4AA52FA749CE638 -:10AAE00085EA7D2DC5FD1CEFFBCF87F97AB329558B -:10AAF000B609F319CCA753BBFCE857C6B8DF6CFB0B -:10AB0000D94B43C9CF871DFA68CC7C2E3F5392574F -:10AB1000D0FC3F5631FC3D0BEB3D789740FEFB5D92 -:10AB20006F8B707CA618AB78BB93868FBBDAF4383A -:10AB3000DE238BDF8B00E487F8990027187DEF3543 -:10AB4000B87C2806FC14E56CB2E503C3C0EF03ED46 -:10AB5000A877BFE68365F9F0688BF0F935D964A66C -:10AB6000A7A887F6693A62D0FC1CBF84D3695D351B -:10AB7000C4C3ECD519D81EEB7FCF1495E492F9BE6F -:10AB8000742F526035D0BA1DA8838C81FB0ABBBEDE -:10AB900094457EA9F5100FB27ABBA774D17D2BDD49 -:10ABA0000698786F92FF6636B1F07BAD2F6362BE78 -:10ABB0008975157D5FABF37BFCD6D63603D9B131F1 -:10ABC0005ED60C7EDE65DD5485F0B0EF1F27BB93AB -:10ABD000AD0FFEFA812C5E5967C0326AC73F9BF306 -:10ABE000B5EACE263A8FB66ECC0374DFBFB51CF83B -:10ABF0007EA6BDEFAC30B962EF3B97E979E327EF72 -:10AC00008592DF72CA83A2EF2379289407D71DE6C5 -:10AC1000F4BC4DE8B763FE2CDD6FD8BBD647F7B662 -:10AC200078E13F2BE87F77E7A28FD3F5D4629DB11F -:10AC3000BF1F2A315CF765541D57693C0BE49B41EB -:10AC40006778DFC3EC24BAE7052F063D931AB8A452 -:10AC5000D2716EE59E781FD945AA6D17D5737BC654 -:10AC60003EDFC8E890FD26FBAE639E3FF303C7B707 -:10AC7000E6B78FBC7E5921FBA8A7C4FC19D2AB4B09 -:10AC8000E4ED7F7DE9227E6F6581BCFD3BC5F8EF79 -:10AC900094ACEA2ED48F93F83D335EB843C25E6421 -:10ACA000F620C9CD3A8BDFC7B58EB93E8FB272CFD1 -:10ACB0008DFC3EBF1ECBC7CF7FD602C54962375D34 -:10ACC000A5E59BAFB61DBD5EDCAF5568DE95A899C6 -:10ACD00064BE75E99F227C5F6D6CA3417E1B51723F -:10ACE0001C2E279CEEF4C4785E1D5FB7CF007D2E2E -:10ACF000E6316E5E58534DF77CB275036DE27BAA68 -:10AD000033D9F9289712F4DD8F95948CB59495CFAB -:10AD1000888F337A1DE7BAF5AA07B278EEFDF627D9 -:10AD200003106864E5F99EDF67E3E40F2AC83AF789 -:10AD3000EF532934BE629FB7327ABDE488370324CB -:10AD40005B703E85D87A8AF326D894C9D2EFD3B007 -:10AD50008280E3E8D15819F9D21902BC6F36541F2A -:10AD60000F63DC36D43FB7859EF5895E949FE8EC8F -:10AD7000AD7ABE73312D916A97DC87EBDCF99A418D -:10AD800071EE2858A552BE5A30A9E6BDDFF85089A9 -:10AD9000C2ED68D625CEAB1E6B783D7BAA72F1BAA8 -:10ADA0005867F49C7F4C72C14325EC59B5E00DD92E -:10ADB00071DF66C4EB5F78F9E8299F2A1F7B3D7C31 -:10ADC0000C36713E02E323BF07C4EAA17317860F56 -:10ADD0009CE72EC6476A5CFC508E2B748EF6CEB96B -:10ADE000F9EFE31C1FE179DD3D25894B2294570BD8 -:10ADF00012E5F70ABD7091BC81EE3162D2C1EF8FCE -:10AE000067FDDD9F473F8E8F70FF756BC8BC3C525E -:10AE100051785C8F4985F0E0F50F093FBF783DCB55 -:10AE2000C737C57C2D4871CF2F0DBFEEDBEBF3315B -:10AE300036B67D686F2B29D23B4ABF019D389F6390 -:10AE4000BE0CAEABDDB145A417EEB1988C4824978B -:10AE50005086FEADD01350DF1FC4F88B5FCCAB7BA8 -:10AE600056FBE8BED8508542F7D7066E4EB2B510F5 -:10AE7000CF350E6431965F75E702C293AD53372329 -:10AE80009DA3B1BE76D447FEF20CED0BDFADE821F9 -:10AE90005CFF8FA191C8ECB3EF86B777519EBF9945 -:10AEA000C8E29597E81639EFEFCF58EEFED800DAF2 -:10AEB00051EF7436E9646F9F71733F38E72BEB777E -:10AEC0003DF265625D66AE64E4D647AF3D51C88E23 -:10AED00060EBA8F0CBE675A15F46262C2B3F147ED5 -:10AEE000A40BFDB07B75F3AB11F283F2FB0F4C2E7C -:10AEF000BE7E3272F1AC98A7B65C0CC647441CF516 -:10AF0000AA46103FC615BF66785FB3D70F38FE0B51 -:10AF10004FDCBBE79B8C1EB23817C734F99E27D88D -:10AF2000F7A5A696C0F23507CF5631CEFACB093237 -:10AF30009E0146398BA29CBD053E8AFFBC05FBA342 -:10AF4000331CF83C21E60973805EEA77C4173F9F03 -:10AF5000E6655BDF7DE14E77F96A58340EE387578B -:10AF6000DFEE878C84BF57CAED177F27C2F3C5BFBA -:10AF700000A92EA4F35A71EFE9F21F9CADA27D74D3 -:10AF8000CD0CBD1AF72F6D3C7E22D6B337991C1B12 -:10AF90000EFBF5DA7046C57CA79777CCB87C0E60BF -:10AFA0003B99AE09B85E8D81BCEBF4E77ADC788E14 -:10AFB000340E2FDEF679A1427828DBA4BC71AE9F57 -:10AFC0000B7BDAE6E3A9DEBFFE7684EB03FBF7D367 -:10AFD000D97962A7DAEE7BC2AEF6B6BB5CC30BA42E -:10AFE00001562AE916A926B76F15F4A7CC8968DFA0 -:10AFF000ED9C9BC5DC73075C4F91702DBE61E046F4 -:10B000001ACFAAD03D518C07F5337F3FDF3D3A95EB -:10B01000A164245A31F43E1D10BF0FE8D06FEC7BC1 -:10B02000EA0716601C2F00CC6FA7A7427240F11DE3 -:10B0300009EDD17416FD80A0A1B8E4A304F74398EC -:10B040005DBB52D88F2575EEEFDE78CF19512E07F4 -:10B050004DD04FF67D540B6771BD854677FED21DEE -:10B06000259F253B72C53E3F1D015801C6AD4D0DC4 -:10B07000340F29CE75E3BA33699FF7C60A83EEF918 -:10B0800055206E525D8FDCAD3C2E41C6E1FFAF54C2 -:10B0900006549C6F2BD9FAE17C7F434C365EC9F392 -:10B0A000FB99ECA79F69F5701DD2C1C7CFC5EAAC6B -:10B0B000EC18E73B69A985EFAB19A58B87F1CB6F3E -:10B0C00088A9D4CF55EBA694F2B88F5B6F1E11EB15 -:10B0D000D47F3EF41F2AAEBF6F3DF8E2254887EBD0 -:10B0E0001E934163FD1E792802595ABF322AAE5F72 -:10B0F000D7EE90F3DA5598A9447925DB797CF2DA1A -:10B1000047029985ACFEB58FBE7C0E30FC8E740C68 -:10B11000EC9988F3E0411E3704ABFF9CCBD8FB6B66 -:10B1200015F8DFF9ECA62BA2DC0F38FCC312BA7FAE -:10B1300054DAB6EBB3D46EDF15FE80637FED92A8D0 -:10B14000DF86E371CE6F4B992979F6DFECB8FAE12F -:10B150006F4B1CBF9D7EBA8FF5DA6DF7A94986C784 -:10B16000CA6D6F933E99B7FD3B51A4C3CA9DEE7D56 -:10B17000B6EBB6BFDF857924D7C930B010E5593EAC -:10B1800041E5A3A6362093DEE7E7A557104B18DC70 -:10B19000F75E5BF06BF6FDCD980C41A67ADFDCF72D -:10B1A000AAFA189693E1147AB02B77BAF5DECA6D35 -:10B1B0002F535E83EE8381AA39B8BFEF966B2F3C85 -:10B1C0009B3F2ADA212BFBD6BD2D33BDB172C75B65 -:10B1D000CFA3FE58E9D19F6FE27F2A87C6A1DBA2E9 -:10B1E0009E7B66B61597FF70DD778EDE63B17E0FAE -:10B1F0003FF2BB7B304FFEFABFBC7BCFBFA3BDF09D -:10B20000645047FDBFF2C15F44C1218F5F8F727BE5 -:10B21000EBC824B02A19DC91FF17C8E0FD57479E00 -:10B22000786D329E733BF2DD3F8E3318FC8D4F5CA0 -:10B2300044F7EBDFF8FD79E387B3C7515E330127AD -:10B240005E197E5E6CA7C48D97C7C5D3C38FC3DF5D -:10B250003DA6A25DFB9E0403B8CEADE87B5F457FB3 -:10B26000648F0903489FDD3B5EDEF36FACFC16E3A1 -:10B270004F200F7FD8F827FA68FD666A923D57EC99 -:10B28000787901E2BB1206683D1DC2CF038C9F0D89 -:10B29000397E7ABF1F85132AC663573EC4F8770EDE -:10B2A000F291F1EF9CA1FC7B0BFF337B28FF7E101A -:10B2B00075E7091D85EBEFADC48DDA1D63F3E6314B -:10B2C000E4F61186BFCFC4D60723D17799C4F1EA3B -:10B2D0008C9AFF19C579F548C9207F17227FBF7363 -:10B2E00074323A39AFFB073E8B74187822A0E3EF33 -:10B2F0008FB8F6895FD13C3BF2FD675583F66D2030 -:10B300002ACD626518FCD90FACBC82C7B661F9D6EC -:10B310003F2F789ED55F8EBF204327BE51790F9B6C -:10B3200077C487CCA52D06AE9B990A1AF78A0C9F85 -:10B330000F2B32BB16E3BD125EBA4BA5F6BD9E398C -:10B340007EE27D4F2B76BCB800E5AE103FEDF1EB11 -:10B3500038FE73D9F7ADEEF9EA855FC1E627AD5344 -:10B360005EFE6676FD373E8FDC1750F07CC51171AE -:10B37000DEDBCBF71CFDC5F9F751EE33FDD93BBF42 -:10B38000ED7D2641A7C2F2C1E7F948E31B2DFDDEA2 -:10B39000881ADCEFF6D0F1F089FCFA7F7C295FB7E0 -:10B3A0005740BA054D67AFBDA240D29A589DC3F72A -:10B3B00030DA170CDFC30FCA14F7E9EADB4D7ADC89 -:10B3C000AB2F561488BFD6D9FDEDDC750EEAB5C398 -:10B3D0004FFD90E473C5432FAAE877ECD9F63DB54D -:10B3E000BF3E371F707DC838E87DF8E15DE7707DAE -:10B3F000903FAE3553B4BFF27177FB2B1F7ADBD58C -:10B40000FE75561FD90B23F5F3A6625E81E37D73AB -:10B410009F9FEE137CB34FCE1BE79E50EA77D9C1B6 -:10B420005DCF2EF8359E676DD81FA27B1477749878 -:10B43000E36F41FB6DBF5FEC1F9ABF43BB74C7B3A3 -:10B440002103EDB41DFB2FA77C1EBBBD1F78E8793F -:10B45000EE016B5E84B5776E7FA201F345BC7AA3E3 -:10B46000F120F3F71C7270E3B32DE351EFA37F6C6F -:10B47000A0E3ADC4E91C951C5D4079E2B2EED38334 -:10B4800079D76FDE9E3F9CA0FD1C3F134CE7BDECBF -:10B49000179EF8BFE4BF77C5F3C7FBEF2AB5F7BD2A -:10B4A000F9EF77B2DF6F90B8DC58CFF07D8E42F3C2 -:10B4B0006B5B5B2C5ECB4879575B631CF77396978D -:10B4C000F2F8C7D4572C1F9E0D99DD6F4CC7F14F72 -:10B4D000843EC0F3FA3BDA74821FE4FF4266519760 -:10B4E000E37DF3104738EC17FDB5D1F67B73A17EF1 -:10B4F000EBFB882EC5F4AB9D44BFEB4BF979E953C8 -:10B50000E9377C127406DC1D2A62BCDE3C296FFF21 -:10B51000EA349EF7E5ED6F4929B733EDFD039A7ADA -:10B52000C3C4D5FCA29DCF941A2E7902254BF74FA8 -:10B53000E7F22A32527703EECB0D9E174E688EF358 -:10B54000C2EC3B9D175E63F23C56568FE6418F88F6 -:10B550004FE03EE5550E7C9F15FA2350958AA1FDDC -:10B56000D58DFB0D79F4D8F342CEBB23CD943FB2F9 -:10B570004B9F5EDA3FCCBAA1ACBE6B86F35CB1A246 -:10B580006725D7FEB0F932DD8355A8BE77DFD0C678 -:10B59000BF7BD797A006F35CCB13D09107CF3E219A -:10B5A000C708578D70B124B43BE0D4181FA75DEED7 -:10B5B0007E9FDF73FBFCAD07BB515F16A2D30EC1AC -:10B5C000CF6731116426B96F1AE663F6447CA4276D -:10B5D0007B82F9EFA3FF45CE2EA0FA2A9E5FA478C6 -:10B5E000EB3EF21B8D132F9878BFD1ADF52AED0BF2 -:10B5F000459AF653F9A8E923EBBF107DECFB08064A -:10B60000CB05E24F8D3AE7EF6EF311CA6FBDE16CE7 -:10B61000D5182E9F22B47A5A1CCFB36BABE7C43136 -:10B620003F2254C77F9FC2C6F3793C6D6301F998EE -:10B63000A573F958FF453B2E992539D938CD17C444 -:10B64000E7FF075094EC5E00800000001F8B0800AD -:10B6500000000000000BED7D0B5C14D7B9F899DDFC -:10B66000D9D92730C002CBF21A10140D268B226ACA -:10B6700035664134F8885915A326185763521201CC -:10B6800037D636B4B5611010C447486349DADA7664 -:10B69000A5D892366D31A58D491F77D5E8B58FDBDA -:10B6A000A2318937571B34DE5C494D2F7DA4F5DE6E -:10B6B0006BEBFF7CDF996167965D3069DA5FEFFFC6 -:10B6C00077C92F999C39E77CE73BDFF9DEE7CCD9D6 -:10B6D000A3DE6909830E426EC0DF1DA39FE6862F9D -:10B6E0004EAF981E2EB7E5C473FE224276E63C4E5E -:10B6F00006E9D37CBD91F8687F334FBC7DF499E8AF -:10B700002547139CB4EC9D986BCEA54F0749379401 -:10B71000D07E6513B91DB9A3E11FCDFA84EB12EDFC -:10B7200097E625E9F06C2B13D20D1A7C3A3F1320D3 -:10B730003E3A4E6B99B016F034873E49A4384DBD61 -:10B74000682064067D5FDDE9F5D276F42FDD47EBF6 -:10B75000094FD25768DB71644D5FD1E8F1F78B1C5C -:10B76000212984EC56EAF7CD7EFB990728FEA257E3 -:10B770002A365230FB8E0E91BCA9B41C1AF27230DC -:10B780002F27996625A3E140BB5CDA2EDEE5271B57 -:10B7900000CFCC41E2A7E3C7170E1298BF4D22920B -:10B7A000414238887FC2AC6122D3760973075DF2CB -:10B7B000540D9C3F1BA3E27923C18078DA1A4A3CDE -:10B7C000F9C984581AE679F2E9BAC4F10344A470BD -:10B7D000E22446FFC87E6F2530FAA874E92C9B98B6 -:10B7E000E08F065F5DDFC653A9BC49532EEB5C03B7 -:10B7F000F43739FD32CC3F7E16A38B5A1F2F0D1222 -:10B800002F1D379EB0799212E23D441F712532817F -:10B8100071E8905EED7C362AF4DE28B2F9C09F37DD -:10B8200015DB11425FC579170E196F85324F2E1542 -:10B83000B2FA1BB90417F49245291B479763CD67E9 -:10B84000BCE7AE46422E69E66BC9A4F357E1D27F4E -:10B850003B4D241DE8FB41E926B806911FD4F701B2 -:10B8600065FE26E720D26714FD8A18FDEC458C7E24 -:10B87000F608FAED52FAEFFA07A3DF089D38C31A6B -:10B88000E0C3483AAAEDE78DE02DE393F623E423E5 -:10B89000505E5609F2DB6965E5FDE25D9572119334 -:10B8A000AB71E485103721A59D37DAA0BD5B14117B -:10B8B000AE7913D5070E4DD9AFEA0736AE23D7536D -:10B8C00049283F935C03394449DA3E5776C17A757B -:10B8D000A0A484E1BF2A4EC0F66D9260E06EA3CFB3 -:10B8E000530BD20885DB6CE9B4C07CDB4D9D08A707 -:10B8F00039CB207647D16FC794F91A1BECD37BA6BE -:10B90000C7A6A35120FE6872FFA6D2BFF9E8E74F91 -:10B9100019297FF092205929BE20F46FA9EB9B478B -:10B92000FB93BE81DC5C18271EC7712878390A0C8E -:10B93000A429777C3CBFA5F015DF601D134F1EF0D6 -:10B940008CA267543C5B004F676C3CED59E5C8A77F -:10B950007C8303C7F99128A17E729802968D747E2C -:10B960008EA604A9893E77F181F66A780E98884CF4 -:10B970009B9888F75439C59B9F3A8D100AA7F5E22A -:10B980004CCB04E0FD864EE2D3E8F94D36FF05913D -:10B99000C2E3453FF1533C7947C00B68F42A7CA0D1 -:10B9A000AE1B294C2264361DCFCF4F077D6AF70BA3 -:10B9B000F854E1A87C623779895804700CDE207D48 -:10B9C0005A00D8EC70BB8F2432BA35CF0DF908D8A5 -:10B9D000B9629E809D6B33794F6DA0E50E3A9F6EE4 -:10B9E000FA6C51F846EDE74E4C647CA88C6F2355F9 -:10B9F0000921806D7CCEE51FC31EDB806EB47DC344 -:10BA0000F9DCEFBCACD295FEFB3F629CF3ED5B90A2 -:10BA100077D3419EDF2345AB0D86D870FED4287DB9 -:10BA2000E7658DBE6A20CC7E1022A52D9F1ABBDF54 -:10BA3000EE46323DBF205CDEC3072C409F36C7D6A2 -:10BA400053B9749EB2C7E02990004C898E4E914F35 -:10BA5000429A70DD4DC403CC4B9A33CB4F954BB01B -:10BA6000BE2B5C8F43B5D1C1535B4B4C1349D008FF -:10BA700074919C3AB9DC64637C13B9CED6113A1E3A -:10BA800018938E56454E22E9989FF8BF938E2265F3 -:10BA900027E4D7B8150921E8779CFA49747C92A964 -:10BAA000973FB59FCAEF91F3AFF85F3EFF483E194D -:10BAB000DD5E56ED267F9436CDF093600787659F57 -:10BAC0002515BB5218543E2DA126304D59D57DE980 -:10BAD0002708D8E716F16D0BAA2ECF8DE4B1E0F35D -:10BAE000E46D959EC6F0785AFA18C0EE9C32050FA8 -:10BAF00071613AC589F7BB8E920F4EA7B6CCE7C5E8 -:10BB00000D1AFB71592CDF9E48E9B213FCDA28723A -:10BB1000B03EB15C4EA4780986E8FA7C3FE835F483 -:10BB20001B457E011DE78E613D9D6E57E8342FED6C -:10BB3000ED4FC334A996E40955C8E53E4F05D0AD95 -:10BB4000628D0FD8820819D76FF1233F54884017B0 -:10BB50004E9E64B861BF79FAC5A2978323BE687808 -:10BB60007F455CF1259897A388D24DE37F50411023 -:10BB7000DFB66BD6C5E11C87AFD8BA1DBF90669003 -:10BB800069D336972108F18C8904DA81EEE4AC910F -:10BB9000809F961A4AC77AB32B2F08F62E35642554 -:10BBA0005E8C13C4A095B6EF5A7B8F07F5D3B539D9 -:10BBB0002444F906751965323ED31B027F9A17A5F6 -:10BBC00032A304E33C6681F8A6CDB52281307F9B89 -:10BBD00044D35F7589FE17615DF96BF3109EC1E276 -:10BBE000453FF166E7F3F4CA78027E80F53C1734EE -:10BBF000535C9E5C39AF7D90CEC742E23ACDF4D91A -:10BC0000CCCB21B063F279AB04F4DE5A20DF69A01B -:10BC1000CFB25F590B79FABE9DB379800EED0574F2 -:10BC2000C9299C3F7DDE1E24B4BC73E5B2E10480CB -:10BC3000D36394A07EFF8DC06DE04F59AE3F81F17C -:10BC4000A145890F091F9809EB67FD807A6237DFEC -:10BC500089FCBF2B7F9A45EB8FA7DBFCE7812E6A1F -:10BC6000D9EAA2FA6D3AF2D3A541CA4F0699233711 -:10BC7000287F5A1CDB5C2724982F7DAFF2476EB8D3 -:10BC80005D586EF56527A535F89994C316815FD97F -:10BC900006FA06FD562273504E67F5BF7DF2EE455B -:10BCA000E087B659D5FAE58BBCDAB2FC3FA7B0BF46 -:10BCB000E2F7162525ED82F6CE0C1260F4F19155CF -:10BCC0001A7F464AE2510E7B12BD7F4C9C319A2F5F -:10BCD000DBF3195F1EBFD05699077C4AF9D22C01BD -:10BCE0001FEED2C5C9EA53E5C3B67CC667B1E86E9C -:10BCF000BA564C421A3FD0E4EC447EB4387DE84753 -:10BD000047B6BF2B99E90B95FF2D2E82F26091FC6F -:10BD10009F7F10E5C3E101F133E7070847F9C42429 -:10BD2000B27878BC79C4C24FE5FFB6FC3C19F8F58F -:10BD30003D913A1263B4375D2BC1F9D4257A7392E1 -:10BD400034F1873387D23DCA7CBE98C4E6D3EAABD0 -:10BD5000F63D48E17A6B2419E5C6453C1D609728FD -:10BD6000FB83DF49FDCD5B9252B4740A307954E015 -:10BD7000CB5CE0A809E4DC49FBD1B72DE487322C89 -:10BD8000BDC919D4C9F7BE647F4992867F7991C530 -:10BD9000870B8C0E03F900F47982C665A14984EC07 -:10BDA0006D14F1B9A7D185CFF646099F1D8D5E129E -:10BDB00032D3F0875C3BF700F8D90E1BE2371E5FE9 -:10BDC000B4367AB07F4BE32C068753F9BC7017F07A -:10BDD000B5CDA0CAC9AD584E30AAF525BB30BEE3DB -:10BDE00058FDD6A4DB514EE87C50EFB58F33AE3111 -:10BDF000588AEBF7FEE12BFA5BA1DF13B77FA23283 -:10BE00000FF8EF7523D1E63146F14B888D77B3F00B -:10BE1000DB330DA84F9FB87DE7A95CF05B5FA3F013 -:10BE2000C7E2C74E063F263C15DFA3BB105F335D5C -:10BE30006F2B85671699BE8F250F91F3A54F82F260 -:10BE4000E124A8A79F38BA961C07F9A4C35A4590C5 -:10BE5000539F17F25D420BA5B107ECAD2FF455B01F -:10BE6000B734D03944CB822237D4ECCBC7291CC19C -:10BE70006B211DB4DFD1DBEF21D0AFED650BC589A0 -:10BE8000DA87E43CE4776B411569A6ED76565A896A -:10BE900091BE4F98B78600BC9DBFB022FCDC539387 -:10BEA000515E77894C8EC6D5432E030969EDB8C51E -:10BEB000162EE781BEDC447C5351AEBF90A4D18FD7 -:10BEC000D44E7E19CA02A990090776F8210FF343D0 -:10BED000587D4FA2EF206BEFC3FE61BF304044900E -:10BEE000D7B3C66007C49BC65A74FA161A0F580611 -:10BEF00051AEBDCBD24B09713014C82E4F886403AC -:10BF00005DD28DD417A32F3C020951BBD149FF014B -:10BF1000FCF8F343E7C9AD84A4AD1174F3E0CFDBC3 -:10BF20002F1A6E05FC587BD50EF1E7EBEAA03D4FCA -:10BF300034EDC13E19AB13C68A6722FDF81F2529CF -:10BF40007EBC9D6481DD6B693C42DE3285E1F0118F -:10BF50007925F5A9FAF39B930D7AFF4762FCFD1250 -:10BF60008DD3811F5B5F3592EE28FCFD87A45C9D1D -:10BF7000BF9BEE3784E747FF7DF982B9BC4BC79F73 -:10BF800063AF7F468DBE7F56C0A6A3634E4392AE7D -:10BF90009C2BBB75ED27B4E7E9EA0B3AA7E8EA2743 -:10BFA0003D334D579E1CFC88AEFD2DBDE5BAF2D445 -:10BFB000BEC5BAF6B71D59A12B1787EED5B59F7E22 -:10BFC0006AA3AE7EC6C023BAFA99E7B6EACAB30737 -:10BFD0003FA56BEFF28BC78E807C527E34527AED98 -:10BFE0004A979F01FB39D84CFDB879CC3F067B4B73 -:10BFF0003289E21F53C3940A7CC5FE5AC00E809E4C -:10C00000DFF3E9D067D04E1A3C20BF7CFE42EF46FA -:10C01000E8D7221A884BA347A48504DE97EF49C4CA -:10C02000F7DE9226940F819A0D6B3CD86DFD7A1045 -:10C03000E376D207F8BDCEF0E34539AA7E1232F599 -:10C04000FC6F26F725F8C6F0FB4C92BEFDFBE5FF22 -:10C05000AC64CAFFE0706451FE378EDF5FE5FB47DA -:10C060000CDE09C92C5F5E71D6A98B7B90AE237163 -:10C070008F85B4803895550F679C60CD95F8C66C58 -:10C08000B871CBCDC73791F2459F94E6749D5C4C57 -:10C090005FABFEFD687B385DE79F453E9BE31F413C -:10C0A0007D47F5E2EDC93ABDE8F32643DCC77B5195 -:10C0B0002FAAEF737BA7A05E6E17999FD22651B966 -:10C0C0001C835E917AF9F34912D39F31F4B340F5A2 -:10C0D0002C18DC9D2BEF6F07BA79B711B44BD4063F -:10C0E000A19E8D844FFDAA7B006FC1C5FC29351E22 -:10C0F00052E32D0BD51F105F592482F432537AD9A5 -:10C10000D13F7A0CFD4B3A0F09FC23B393FA9F60A1 -:10C11000EFA9FFC9FCCD0FD7BFCC56E63D4217C5EE -:10C120005EF6D8BCB5C929B1E1FF20C67ED4CB49A3 -:10C130006ADCFDBF93FFE6264B887F241FAA7C663E -:10C1400006A6A3E3BD27B175A7D38AE7D4FD0B09E3 -:10C15000FEE3477E3931EB8C3C1FD6CDEFF09AA938 -:10C160005DDD376B05F61326F004F44CDCE086A5A4 -:10C1700060274909D31332FD07F8CD56A4D71B9683 -:10C18000083B2A803D8E1F6D7755FDA0C6E7E3E989 -:10C19000976755FD3293CCD4EA975871B8AA5F548B -:10C1A0003ADC71BD5144BFE33AAD57FD090AC7946B -:10C1B000C5FB20CF2C7888F76014F9FB27C52EEF3C -:10C1C0003D66C5F8DBB146C038CBED0995019FBA95 -:10C1D00003C403F4993518227E0AFF0527E34FB7FD -:10C1E00027C881FFEABE1CE400CF2E13CB0BB9B7E2 -:10C1F00005396DDEE8DF93593EFB4F171EF3C0BAD9 -:10C2000097E738504E3FF620417B3DE0DAD859069B -:10C21000E3CE221E334E97276E289F3307519F7817 -:10C2200006BD024BC1C97174E82B8D64DA261ABFB2 -:10C23000BFD368C1E7D546119FF3730E1CBD83C2FF -:10C24000DD9A6BC37C416B9E0DC769CB16900FFFC7 -:10C2500098F5480EF805BF697461FBF6C703859031 -:10C260004F683BC6F68332BCD3711F14A9E6027C2B -:10C27000426C7F870FB860DF37E3F84FB05D9BC932 -:10C28000FFAF1B283EF25AC17348627480F9B6585A -:10C29000D9FCCDF680279196CD13C8FAE5D1E451AB -:10C2A000A107E524A3900A7940C6A7C22CA909F2E8 -:10C2B00021542BF451F488A935C8C1BE077958948C -:10C2C000202F9469091EA5311FC9AC113DCD04DA98 -:10C2D000136FD0115E0F9395F80E3BA05D887B9491 -:10C2E0008EDBEF64FB13EE736C7D7E7FFECEA35975 -:10C2F00024B61CEF69AC3C53A1C9BB3A48F4FDDF3E -:10C300007373CAFF027A087D045CD79963DAC19B14 -:10C3100085EB75323D75FCC2A434F08B1BF8E8FE4A -:10C32000A45154D7494A8378796B819496E8D0C256 -:10C3300061FAC278EC455C2F7B5110CF17347FEF48 -:10C34000F5FA4F53FAFE8E7684BCD4CB173E8A7131 -:10C35000E2BB49D213105FC93F351258CF77BF3FB8 -:10C36000F32449183DEEAF1B4F25F19ABCD1BBDF3A -:10C370003E5D6AA2F0DF7DFE74298FCA26A8D353E2 -:10C3800075375E29853C95D0F07BF7658AAF5C4EAA -:10C390000A0350A68E32C69B72DD92D01874EB4A07 -:10C3A0007DE851C80B069B1D2247FDB2A7ED7F110A -:10C3B00080EF1A007FFADC6219DEC9D125FEEFAEEC -:10C3C000B71757D078722B27CB0E0EE8269B217E0D -:10C3D00020E7CD1EE09BAD05CC2E6E7D580CCAA08B -:10C3E000AF42012FA6852CAFB82F537D6BFD79107E -:10C3F000F6FA490BE79B1F0779BAA904F97ACED55B -:10C40000400EEC1F2712210FF8D06430229CE10B64 -:10C41000F66037EAD9C04CD0374D171E9B04EBF5B8 -:10C42000FB64762E40CDAFA51A024F56E7427ECD73 -:10C4300083F9B5DD7C1FEE93C59AAFDDC5F60FF825 -:10C44000F944898F7FDB119A1BE60755BE22FBED6D -:10C450006F249E7CCA5F2F355A3C30EE671B457CAB -:10C460001E6974E1F38946099FDF6F2CC4767B1B3C -:10C470003D58DEDD380BCBAD26B2DEA7E1B34F3839 -:10C48000D93C5627947DC2499FFD14EE65DAAE97DC -:10C49000F687E79CB341631CA5C79C2B542F4A50D9 -:10C4A000DFEEB94CE17D91C283E7E87A4B31BC2FD6 -:10C4B0000DF685044ABFD222F6BEB7B157E977041C -:10C4C000E1D27AA47FE955566FAF6570EC57D4F688 -:10C4D00085C5CA38C5D09E8E5BACF48B848BEF29A2 -:10C4E000DCE268F844B6A7DEBC91942AFB1410D7AE -:10C4F00099FA38F067648E840EC17EC6F9A7CBC066 -:10C500002EEC29267906DAC894D2CF41B9B78188B2 -:10C51000C644420AD3A7759401FF98BCF85EDECBEF -:10C52000070FE5A21D42B8AA1DCAA80D79817FE2B6 -:10C530003D24CF584CD741BA84F686D035B6CFA12A -:10C540004353F1B9A4B1B337E87FE0BC01AE0BEDC2 -:10C550009F5EABAF1FAF3DB52711F5D1F9EE833E1E -:10C56000BFD8A83FE7D15547B538D51B5D8A1F76A0 -:10C5700000EA61BDEA4A133642F9D187D2416E7FA3 -:10C580004F5C1CECBB8FF48BF0DB0E349E4AAD2865 -:10C590006078037D32B78907B5FE6CA64CF9552348 -:10C5A000077B037C6537E611FCE92B34F14FABC9FF -:10C5B0009F4E8597FCF6A9D717817E00BB0C7AFAAF -:10C5C0002357981D1FB1DF57997E54FD064159AF7F -:10C5D000CF95FC2E04722F833D02FBE4F19372DAB7 -:10C5E0003F658681033B448AF5EF9D02C3CBED0A8C -:10C5F00072504E76FA5E06F9E1939E21C0477FE8BD -:10C60000374BC06F7B8FAD2D04FF790B8997ACF44E -:10C61000BDFB871705C0A3D5302810AACF86F66FBB -:10C620005BCC537FA75550F4243838741D5B5315E9 -:10C63000BD20FFB1A302FC0D837F08B67AD5F65D5D -:10C6400036FFA350A67F5E0BB5DFFBADAA9E0D742F -:10C6500078298FED37B1F2D0FE2D1D329669FB623D -:10C66000566E4987FD296FBA81D22BBEA9AEE3541D -:10C670001694D5F6751D72265D4BC59E12873F1721 -:10C68000F4DE4859A4E5384D9967656261CFBDC7AE -:10C69000FE4B807DD3D6D4E1931940CF1F737DA08C -:10C6A0005FEB8E3F7B14CAF53544823C9CFBC8414E -:10C6B0005C87678D6543CE1490E353223AE4F0A77C -:10C6C000AE0BF54727BB08E68D852017CC033FADA1 -:10C6D000A8D3807EDA76EA5B1703BDDB53619DE762 -:10C6E000A4323F637290C2D1C8C1649E86EFD3C0AA -:10C6F0005C998607B57115F118005F2439FEE7DCF7 -:10C70000E210C5A777966C9B42C7DBBC81F7344922 -:10C71000607F824DE08F91231CDA89DC53E93BBEB8 -:10C7200041CB57FB92BB21AE30ED607CB039B72FC7 -:10C73000751A7DB65A997EDD9CA89413F5E516C549 -:10C740006F7425CA8949F47DFD9127B3658AC7D0E6 -:10C75000A199182FD6ABF8C87B1783BD1C3A3A3B7A -:10C76000610E9D6FDDCF59FEB2AEBF7831CCBF6E8A -:10C770008F8140BC56DF4FF9492B1F540EBD93E803 -:10C780003CBC9D5378CA1F8B52739758E9FA3E9B65 -:10C79000E715815E1BBAA6ECB6D020E859419C0C87 -:10C7A000F2B2A1CBB31BF869F38C4BC88F96CF794B -:10C7B0007E569944E3AF7B2B17835A4B3530B9A48F -:10C7C0000C877ACE98B80DE9FF9F6564D89C88E401 -:10C7D000C4FDCC1CF83F8ADF24D15B0EEDC5A53427 -:10C7E000F4013E157CC7C00F91CB2D980F2D1797E4 -:10C7F000627DF61A62E8A0F81C9492929A68576BD0 -:10C80000BED7007E4A9ECF86794E635CC50E909B54 -:10C8100043675939BC4EBFC275B21506FB2C14CE06 -:10C8200044072F42CC916AF45A60DDA82C0F1C2AD1 -:10C8300001792168BFE5CF16615EA72B9ED43C4FDE -:10C84000E9D463D8D8F113DAAE27C949C0AF6CE593 -:10C85000B8F52BF07DF994AD146E8FB27EC6448F7F -:10C8600008EBD593A82FEFE7363E0C72B4E5732F93 -:10C870002C86F9A59ABD9DC914BFFACFBDD0E19A07 -:10C880008D74CEB350BAD4A7BCD061A174EF69F255 -:10C89000BA454D79D29FA9B6C679BC8072CA277EA7 -:10C8A000F61190635AFF530BE5DF6793547F80D5F1 -:10C8B000E7E7A9651ABF521D6F6C1A29CB16AAFFAC -:10C8C000F335ED2BA8DC7EEDCB46A2C20FD1B26DC5 -:10C8D000769FC566C479101BF8335379F4676C8969 -:10C8E0006C5D6D93F3D04FEAB1327A0D6719B07E6B -:10C8F000A1F13911F200E6C9BCC18CF173C0672AFD -:10C90000817D579EB0BCEE01EF6409D2A36C1F90ED -:10C91000EB5C8E71A0B550B3EF47205ED5EF13F2FC -:10C9200011E502F360BA81DA61E7F9E55C36855713 -:10C930009BA2C4854E920E79D7400AD3338FF9E477 -:10C940003B4D12F0D8203B9F4A7CD3E099B62E3F56 -:10C950006DAC7385A3F7FF43E897ED711814BA49DE -:10C96000BB43D4476D763C2F821EA1667EC701F083 -:10C97000279D3CF24D01C83F2D6F4B64F9F6DCDE7C -:10C98000C54FCF02FFF0748101E49F173D229CA7A1 -:10C990002B8B2B4900BF8D1FE1D357507E8D4767EE -:10C9A000DF0DF19E00F24BDF1EB0B273A0C3E9A40D -:10C9B0000FF2BFBCCB4BB4FB81AAFCEE6CB4E073AE -:10C9C0006FC98A6FC03EC1D7DB09EE07082E1F96DC -:10C9D000A516C2815C1C2FBD17C7FD2AEF4B580757 -:10C9E000FAF62CF3EB815D309F117A8A837CC67B4B -:10C9F000165F02CC7B5FA2DE9EDE96CAE2613985BD -:10CA0000E9CF3625DF295CBB05F337AD26551F5925 -:10CA100096807F2AF07E3C2F6BF66FF382BEB210B9 -:10CA2000591635F9704BA63EAF255CBB15E1C829F8 -:10CA30006C9CC873050E4E854FD7610C7F597D469F -:10CA40009E4368203ED44764809D6FD8B66B7E5A63 -:10CA50009206CE36CE9B268EC11F5BAE194950730F -:10CA60001E650B3F2CC07CB65C13F03D710DC637C4 -:10CA7000C1FE0B65B80E58C717BF8B76C9463A433F -:10CA80007060CA0CF908CDF94FE2E28747F83F2FF2 -:10CA90002C1FB87FCE45910F495F8EDC370F808DFC -:10CAA000A57EC50EFB6F0498E7BBF3C930F89384ED -:10CAB0000C2E04F9AD9B6FC37CF416D269B1401EF5 -:10CAC00085EF14B579E1BAFE8BF1708E8E2EA90434 -:10CAD000FECD961F96E9F251EA3930B55C7F6403CA -:10CAE000E609B7F45C15A694201A03261A8FD559C7 -:10CAF0003A4F99F3C2EDAD26BF9C01FCFFC347BD81 -:10CB000019F4D5D7004F383FD5306126C47F7F1048 -:10CB10006BD2814E765EB11F6B2C683F5AAC345E8F -:10CB2000033EBD3009ED29ADE6C13EABE32F56E231 -:10CB3000E221F02F6640D73EF4D35B6DBE2B609FA1 -:10CB400080B179EAEFB426A97CB3AD03E4A74B0822 -:10CB5000EB45F09FBA6CAC6CEFDAD6D1C2EC30F397 -:10CB60006F9CDC6EF06F5A157F6968FF75F48FBAA1 -:10CB7000844EE6FF7DDF2C019E5D369F07E2417902 -:10CB8000C76409EC49459A03E7617AC1DC0DFA30C4 -:10CB9000D9E9BF047E0B7132FFE8DD94F3D9200F91 -:10CBA00051E00C733703C7A587639DCBC67F9733CE -:10CBB000FA769484DBD1FE21DCFFBFCF82791EB5EB -:10CBC000FD01935EAED5675E2AA327E813906BF54F -:10CBD000BDE0DF84F26B2601945FB34BBF2FA4CA84 -:10CBE000B3706DB22E4FF9B514B63FA5EA01E15A04 -:10CBF00011D6CB0A9FEE84FDF231C7498A31CE743B -:10CC0000D413B1C72955F40851F2BB3C9E2753E514 -:10CC100024B6BED0E76B23F59FFA54F5DF17143E18 -:10CC20003E6DF5CF4BA5E33C12EC5B68C3DEFE5BCB -:10CC3000617DFEA4F06561EF93C780FD2E8BDE4F12 -:10CC4000A5CC807353DE6FA4A4BC7FB9D990CAE68B -:10CC5000335A8FB1FCC3B68725B4CF5FE53D364F5D -:10CC6000143D5673CDAED35F19296C9C1A5E463DB8 -:10CC700056732D1EEB3F387C2B094E1F0BBE03EB6A -:10CC800047E0F731F8C74B7FDA350BE01F3619CC98 -:10CC90009A786EDBE105699097DC66A57AD9A19355 -:10CCA0005B2FC82D9F4B46E22090F37D23F5F37751 -:10CCB000837FF3AC56CE6781FF15EECFD375DEA729 -:10CCC000C83D9197446F6F8F683FE25F5561FB48A5 -:10CCD0007C543D0265F0B7F83F9B55FC500F3D6911 -:10CCE0008880A7FA637235C2DB3C83F919969407F2 -:10CCF0007F26E703FF05CB200E1A7E9848DD6434BB -:10CD0000DD2D0A1FD65C9BA05BD730BD27EADEFF76 -:10CD100047A38B0435F2F651FFB6856897619D00F5 -:10CD20000E917762BF031924A891BBFFC3E383E28E -:10CD30003127061EF3FECE78E4EAE4328C47BEEEDD -:10CD4000FD07C5C368B9E6BEAC299B4492A12D1767 -:10CD5000872C1997357ECBF453A2AE3C63C0A56BEC -:10CD60003FF39CA4AB9F3D58A8AB9F73C5A32BDF9B -:10CD70003E3C4BD7FE8E6B5E5DB98C2CD2B59F6F5F -:10CD800059AE2B2F10D7EADA4F54F2E477BA36E8CF -:10CD9000DA2D921ED6B5131A92BF03FECB1DD7EF24 -:10CDA000B0407CB1D361A8847D879DBCDF921445DF -:10CDB0003FDEA6C01DB177AE54ECBF400CB4803E40 -:10CDC0005C4043E166EAAFA555FB5AC0EE578A2C9A -:10CDD0008FA8E6CFC9F59515F0FEEE4544EC480C5A -:10CDE00097EFFC14215036677AF1FC9AB5C880E7BA -:10CDF000037617AD1873FF619FE2BFEF89B0F7EAC2 -:10CE000033C1C8CE4946BE2F48637EC29377EC2318 -:10CE1000B04F607104F17B9EA39377BAA0FCF41D20 -:10CE2000DF76419CD13EF9132EE09FB6ACAFE9CE40 -:10CE3000DFD9F2097EDF110977BF0237FFDA631607 -:10CE4000B09FBB33193D23DBA9E7D0775B58DEFCED -:10CE50006F35CFF234263F1FF63C2F2870775B8268 -:10CE600098FFEF28FCDBE05F3D82FFE384E1FB38C5 -:10CE70009E376ECF1224AD9D559FF07D28CCA72DF7 -:10CE800077A70BEC6E7BEE2774FEBF399FEDAB45A9 -:10CE9000F6E35C6CDD768B7FDBF93CF657CF67679A -:10CEA000D4FD754B8C7915A8F3720591CFFE56F31E -:10CEB000FAEC883CFD7DE6F5A2325E7C1AF34F77F2 -:10CEC0004B4C8E128CBE5FE6E5C696BF8459FAF3D2 -:10CED00048711E7D1C9097EF1BF39CD139853EB1A4 -:10CEE000E4758D494E013C5E6B64E769CF021DE934 -:10CEF000F39C7F42397C97F01A9CCBE2A0FF8EB85E -:10CF0000B1D661ADDFA8C3733CFD30258D9DA75C14 -:10CF1000BD46DF6F95CFAE3F17A59C27A0747A0260 -:10CF2000F2CB2ADD46ADF38744A758FC76B374EA0A -:10CF3000287C7F741A8FBFE3D398FD1A8F4E2A1F67 -:10CF4000C582F3FF2B1F95037D6E828F54FEF95B24 -:10CF5000D3E71F8D7FAAFF8F3E63D2E7B19BA48FDB -:10CF6000AA877A055213ED1C48934B40399DC4059E -:10CF7000CE2C8238FB2E239E773873A0A78EE469CF -:10CF8000DB317B7AA6F2AB7578EEAEC68EE7BDDEFE -:10CF90003078FEA504F2528F1831EF1609FF8C424B -:10CFA000BF4DAE44E5BC8E9402F47EA366E598F3D3 -:10CFB00023959A79E1BE9A2D5C3652B84442FACA5A -:10CFC00094BE90173853393D2E9A5D53D72FD6789B -:10CFD00037BB7E6FD434BFAFF51B6F7E2B5D7937C7 -:10CFE000A51FE1C43ACB4BB17301BD8F33FFBDD751 -:10CFF00040D793C2BF0FF2DCB3210E2098FF5BBD78 -:10D0000026ED20E0FB2F2E76FEA25F90EAF01E9028 -:10D01000954B77C3B988B3AB1239486DA8787C4576 -:10D0200059D7D2EAE8FEE7734A7DB83F472645590B -:10D03000E72F2AFECFAA6A0EFD08C27BB3B4F77CA5 -:10D04000FC73447D64FFEFBBE2B1FE6C8CF3975F31 -:10D0500057FAAFAE1ABB3FA94D510E618853B5DFE9 -:10D060009F8FF095220F8B5DFE3E176DFF1AE7FF35 -:10D07000D2C7818F263B90EF094F7261FF7F040E6C -:10D08000EFC5731B97EB18DD23E16AE0BD3416BCD6 -:10D0900058F455E7A58E57427C18DF914A223E315D -:10D0A0001BC737C279B6BBE793008ECF4B884FF2D0 -:10D0B0009B34AECB0DF3C7798358871FCE2870FA07 -:10D0C000FF7BFE1280D37FC620EEC88D8D772CBDEE -:10D0D000F0A6C23F4EA37F079C2F20EBB9A8F27D9C -:10D0E000CE65C576BB5CCC3F24BC3F0BC699B8DF90 -:10D0F0006F9228DC7B94F36784F8B3966BC6DFA548 -:10D10000CC3BB29FD3C8F6C9C9EB4C0FF5763F9222 -:10D11000154D8E5E51FCE65DAE42DD39DF2ADFA3A0 -:10D1200026D003554B979B2407D44B8CEF143C7AA5 -:10D13000057F56B1234CA798FA47A14FFF397F339B -:10D140009CFB59DFC0E139E3A2ED8CFFD66F3F6A4B -:10D15000A8A3CF838A1C2E57E450ED6F4F6772D37C -:10D16000DB6DCB06FC7BB5E730281EF73F43307FF5 -:10D170006748FFE21E99276490234ABEEFC65DB060 -:10D18000EF30A8EC8FE5D0FA26C0B782E1BB7EFB7A -:10D19000728CF72756B278BF5F20781EE8CDDBE3AC -:10D1A000823B0086C57BF4315ABEF4E704D2E10924 -:10D1B000F3C75342682AF0474AB3EFE3BE28EBEDCA -:10D1C00056F0FD8383EDE7C5A28BAACFD5762B78E9 -:10D1D000C914ADFDCA4ABD5E53F14F3687DE2551F5 -:10D1E000F2EA23FC181CDBEEBDAAE8E95722E2A60E -:10D1F000AA73D1E397D274C6C7BDC1F2CD78BE5928 -:10D20000364B789658C1C729AF467ADE5842442833 -:10D21000DF6D96BE0CF8DD53658CD0C34184B37EC0 -:10D22000A95D37AFA7BA7F3A15BE43CACB67FAF7F5 -:10D23000BD42079E0B7F880404D85FAA26F23C9467 -:10D240004B229980BFCF2AF453F13B4BBC71334042 -:10D250005F3444B79FBE742627677DF357A1DD6D09 -:10D2600031E2B9848B55C9CB200F2EFB4C1E38E61A -:10D2700074B16565DC839A7555ED9EEADF9CF3CF4A -:10D280001FD37EADF2E9D7AB57E8C47D40B99C040B -:10D290000E513E9BF4A5CB7B67D2F299A001EF190A -:10D2A000C23F2C67A8E7E0099F4AD75DA91A320C54 -:10D2B000627BF90B6C5EEBAA830B606BECBE673A8A -:10D2C000F7CDA4E587D2993FB0C33EEF7690D75F04 -:10D2D000358C632F23F869E27E9BAE5C7A8E08D092 -:10D2E000DFBF2DBA7DF88F0CBB72AEC8930DEBB0CB -:10D2F0006E7BF476F64C07DB27FC8BB1265AFCBD1F -:10D300003B83C9C9FA1A2EAA3EDF9D11C7EA6BA357 -:10D31000C3BFDBADE22166C3BAAC8F81EF1237B376 -:10D32000676FB5AE5E07FAE08A41AFA7E7BA195F4B -:10D33000B8DD6CFF7BA8FBA5D654E0879D9C08E771 -:10D34000C92E257A2603FF6D68B988F17EA2D2DE48 -:10D3500098E6DB974EDBDF7BEEF913D0BEBF9A7801 -:10D360003829B61DE84A57ED80FA1DB46A0F3BAD67 -:10D37000608FE07F619F15B6FA139260DDE547F09C -:10D380007C4CB74D64DF3D796668FDEB1E45CF0CE4 -:10D39000F5BCBFF5BEAF46EF1745FA7F4382B4B781 -:10D3A000848E3B44F9AD89CE875C7FEA56ADBD5192 -:10D3B000E521D6B837EB070EF5BC3F3F70BC799E30 -:10D3C0004ACFBD293FF0BDCAA7F6954830CFCE5B06 -:10D3D000A3E95B552FBFA1E8C5487E19D1378A3E26 -:10D3E000B9121C1BAF8F3EA3C7675D408F8F2A1FEA -:10D3F0005782CD36B8478B8E3E15D659F54B49C569 -:10D400008C9BBA1F24169E57143C7FD560E451EFC5 -:10D41000F57098A7FE55C353F1D1FCFCC8F90F195C -:10D42000283F007F7C9947FD5350B3E158AA14E68A -:10D43000C7F714F87F2D1FAAFA55B52791FDFF51A4 -:10D44000F94EB567E3F19D33461E7277BA05FB6F5F -:10D45000E04501F69176A74BAC4CC4852EF05F6792 -:10D46000B1F3EFD4EE65C33D1243DD36FCFE4BEE67 -:10D4700030070BE83A5EE99E3359BB8ED3DC8A5EF7 -:10D48000AD4DDC095BD7570C9E4569B07E2BD87D2E -:10D490001E67CF252D4CA3FD9F1A30C08D5864DD2B -:10D4A000B60D4698DF6DEE446697B79F46BFEFFD19 -:10D4B000F2F5FA80DE9E3F9DAE9E3F657EF8DDD49C -:10D4C0002F80F384B1E890E3B660FBFB6A0EA33EC5 -:10D4D0007D603B87FA54724BF8FE013E887A99B41E -:10D4E00030FF9958283DA85EBA0893007A7C8E6375 -:10D4F000E7BC799FA0BD6FE3C13DAB17C0F9CB4836 -:10D50000F9F88EA2C73FEF3628FADCBFC88DF1A12B -:10D510008F0378973EC9F05DBFFD513CA7FC7ABAF6 -:10D52000E25F2BF2F9BAB24EEAFC9295F99DB70D83 -:10D530006F037B41E5C680E74C5E33225E435FFBB1 -:10D540006600DA89531C18EFA31F4BCBBDCBE282D8 -:10D550004D9ABC9DEAD7E479983C54F15E9D5FF802 -:10D56000903B57E7A747FA1BFF670FD8B3C3FDF7F8 -:10D57000B5075DEE0FC71E04D219BF47DA85113912 -:10D58000DEC9E4F8E2B9DF2D8072A41C7F5D91FF53 -:10D59000BF567EAF74DF8B7C2D2F2662812E3ECA54 -:10D5A0000A421C3CC2FFE1388983736E4F75FF6CE1 -:10D5B0002AE4BB2EEE5DBD2EDAF87B33989FB531A1 -:10D5C0005E32E07D90AF313E8BD41391FD46E42274 -:10D5D000469EB16AC56C8C0FCFAE98930DDFBF45E8 -:10D5E000C607A3DA73DE9455101F3729F1F13E7395 -:10D5F0004D77147C93143F352F7FF804D0FBBD5A30 -:10D600000EBF1F863FAD9F7EEF39CF8F06A5D1F8A5 -:10D610008E94D5F8643B1B2F729CCBEE88F844A601 -:10D62000F109A5F36095311ECEB3AAF1C9A0FCE1C2 -:10D63000C6276F92E17F9909EBDC131D2F3E43E172 -:10D640006BC1BF6F36C56368B1D12383BC18683F17 -:10D650004D5C12D9EF9AC2876F6E7F9FFAE89C3EAD -:10D66000AF1C4BDE46F0FA2BE5AD5718CE02B97F62 -:10D67000F3E0F50B8FC17C0EDAF0BEB1483807330A -:10D680008C4A7C60433950ED6FBFD059FF12EDF7E3 -:10D69000E65D6ECF0EA2910B42E582BE3FFF172AD8 -:10D6A000171ED46F28C7BDDDF69A6871CA0F143EE5 -:10D6B0008BCCDB88DDDF08405CEC251E9336EFF475 -:10D6C000BAB2EEAF2A7A292F83D9CF7BAA960B90D4 -:10D6D0002F7A70245F4430B810A7641E84F8F215C6 -:10D6E000E57B0179631CCA5D241EB729741D2F7F59 -:10D6F000B0A65A1FD7DF53A5D71F6F07F346EC48D4 -:10D70000C118FB522AFFC61AEF66ED476FF0FDED18 -:10D710000B8C37BFBA8CDC9BDA17584502B7639E77 -:10D7200083AE0F3CAB4860EA4B149FB79F59897991 -:10D73000F45709A9443FFEFAC7A66AFD927B95F506 -:10D740007EAFEA637701BBBC2E04A646B33F917956 -:10D750009A5783D1CF67F814BDFABAFA5DC53DC6B2 -:10D76000A8EBBB5959DFD7ABC7969BC8BC4DD55268 -:10D77000FDBC3F95212A709A6D7E1657B371BFC0CC -:10D78000C605BBA5F54B3FF521C9EB20E4EF619C35 -:10D79000ED84403EA55790A768CF5FC565323AE457 -:10D7A000158EBD1FF58A4257B55DA49FF513B7A42A -:10D7B0003B3754B5548FD76746FC4111F320436083 -:10D7C0002F9D617B79B7D9F330F001714858FFBCC8 -:10D7D000B2DEF7D6FCD604F3A7FAB315F2A1F2191C -:10D7E0008308FAB3F45CD0A4A5CB6B3719DFBFA6CE -:10D7F000F80BE3E9D1BCC261D46FEF051DF89DC4FD -:10D800009B9FF993291ADCAA6B19BAF3C4EB7DD15B -:10D81000F32AB60CB6DF158BCEB60C49E7A7AEBF20 -:10D82000968DE78363F9FF9FCD6071D07D35075BEF -:10D83000B5FEFF530A9C07547DC633BF3F56FEF525 -:10D84000A71937977F55EDB3DA2E72FDD567A4BDC2 -:10D850001C54E439B2DDBF65DC1CDF8DF83131F8D2 -:10D860002ED6B86AFCA1E67DF38A68FF28FB32A3B6 -:10D87000C651DA458EF3AF197AFE1E1547C4C8DBD0 -:10D880005933991CFB63E4EDAC9971587F8630BB2A -:10D890002807ED68C7AEF43CB00FDCBD87167DFCF1 -:10D8A0002498B78F2AF99AEA9AD327204E55E38A0B -:10D8B000B03FEE6F867DB2A11D1CFA1B91E344FAC6 -:10D8C000E51F853D269047257F5068F4629E9A7C2F -:10D8D0009A9DF37736AC46FF52CD4FF70ABE1D71C5 -:10D8E000F4FDC4EDBFDD06F6558DE32F993C0FB373 -:10D8F0003C33F377CF773BF07BD7DA1179F760BE13 -:10D900007144FE95FCE378EB31A26F62ACC778FA04 -:10D9100026565E447D8EECB308E28C97E17C2A1794 -:10D92000EF817B99979B09E67D962FE130CE5C6E67 -:10D93000F6E27ED6E9330603947317E7EE067F63BB -:10D94000C552A3D74A51F83700359BAAF257AA0B04 -:10D9500000CE5374C210C7F6BF21BE07CF5717C4FD -:10D9600049E0FF9F9E27353969F9F4624EDC41FB9F -:10D97000BDBCF401E3545A7E8586CF70EF8CBD8127 -:10D9800028DF7FDCB26C7E3E21DF00B89AEF3F5E7D -:10D99000216AFD3DFB2A281F4D49E937382849BF38 -:10D9A00075E09E7D160ABFB5C9E782EFF2EECFBCE7 -:10D9B000751F7C0F999AEA1DB883FA519D999E654F -:10D9C000F09D5EFF175478C5FBE03BBC1F18FCB907 -:10D9D0001CAD7F2173D1321EF62326A8F0ABB17E99 -:10D9E000D5C2750FF6D3FA0B07EA97C119F6D26ABA -:10D9F000A5BFFCB165F3794AEFB96AFB8678283B8D -:10DA0000ED24BCCF348B1053F83B3F3CF7DE3F7224 -:10DA10008E7CFBB20ADAF7D5B2C07CF89ED3F3A5B0 -:10DA20001DFB8AAC84CCAC2C13BD743EA5595F5849 -:10DA300066877521941F69FD47B20E2C83F9388DD6 -:10DA40000605FE9710BFD26A790AD47372705F65BB -:10DA5000227C97307812D8724B43A72555F77D4228 -:10DA6000C00BAE8970A42C9481E828FBDA99A1A997 -:10DA7000ECBB3BA55CC8F2142365172BF7EF88FEBF -:10DA80007DC57F6531FDD56F8B5EDF91A9DFDF4EF0 -:10DA90003847BCCF4591FF8F29797F559E4E403E38 -:10DAA000C48957CC059A601FD6C2F08CB58FDBAE07 -:10DAB000E897FCA604BC976869C08EF7E84CF03084 -:10DAC0007D43A5885F09FADF68403C538C1CDE6B00 -:10DAD000926A23FEC3F49992CCEE39594AE517EEC7 -:10DAE0001F5930C1D783E77CD3D28B9BE19C5DD398 -:10DAF0002F79F0C3D4FEA3F1141F053C538C2B8A5D -:10DB00001F2DD2D0AF88E14DD75DE9E7FDE61D209E -:10DB1000170353F2C0AFBE3D536FEF4A07CA4DB073 -:10DB20003FF9AB2C250F26B1FE29F3995E197E54DF -:10DB3000B9B7C2E229D6E5F5153ACF6F5BFA34B42E -:10DB4000AB1D3011388FB8ED7099EE7EF5C8672D9A -:10DB50009C7BD7D8ED5A3E84E7CD6BE1DCFB74802B -:10DB6000F77301CE39021C880FE0FB0EF09B529A2E -:10DB7000A3AFB79A57AEBD9648E4E9DAF78C5E6179 -:10DB8000F84EAC1F6F5E6178FAEFF946C353BEEBF7 -:10DB900053E9CE2B7417A2E3F933952F29BDB5BFF6 -:10DBA000AB52554D94F313EC1EDFF3CB8ABAB5F7A5 -:10DBB0001610B2839DEBE0E93A823F3960C3FB80E7 -:10DBC0004B79AA1F9D002F4994B9D17CA1AE6B7FE0 -:10DBD0005200EF231ABE8B13BBA3F8D967143E2E55 -:10DBE0005DCAF836ADDA6FDCA0E17795FFC3F007C8 -:10DBF0003EA3CAC73A94DBBD0C3FF037800F3DA16E -:10DC0000A9DA73202AFE659904E74FD791D1FF2E38 -:10DC100047B09B0BD36D34FD33C659CF6CAC2F1D71 -:10DC2000382600BFD5C690D3B359F1386EDAB95053 -:10DC30003C9C0F58A0F07F7FDF74EB1C908BA506F7 -:10DC4000C2496CDEE06796CE55F5E73BBF28A7F6E4 -:10DC5000206DA44CF5AB04EB30A26F43164BB8FD1E -:10DC6000C9AC7796B5803E36B3EFBCA9FF68219A60 -:10DC7000EF11B92C96BF9DE58FBE6FFD4616F34799 -:10DC8000547A7FBE613E798BCEEFAE4C66BF670D96 -:10DC9000CA785F922AD7917A29278BAD634616E31B -:10DCA000B3BFBD5EE2C6D14BCB15BDC4EA89D35725 -:10DCB0000BF5A906E5FB0491ADFBC69F4C2F803CFC -:10DCC000DC56975182EF1D56729EAC6FD171AA2C13 -:10DCD000526B9C14E68F2A62911C406F3A027CFFC3 -:10DCE000BA62A915CBF0077EC7EF3A39C67F444A1E -:10DCF000A81AC3AF55F1D9EA1270BC8DBB0A12FC49 -:10DD00005A3C79DF7398DFB32B785A22EC15AF2F8A -:10DD1000A7A686EA0C464DBD83D9AF1697774E1657 -:10DD20002D9F56F242A43659E717AD52E42ED22F5A -:10DD3000FAAD8B287A6205C68F69347E847B02D265 -:10DD4000FA7C781E0C2E322AC0EF76D97DC6970E4B -:10DD500093B91027A9707C59453AFD5EBD1A364D1E -:10DD6000A8705AE67B2F6BF4D929E53E7ACA0F33A7 -:10DD7000405E9767117D3FA32F13BE2F2769660F63 -:10DD8000E89B1382EF00AEAF4812617D17181F3D6C -:10DD9000807C612489CD784EEA20F6AFAC1E2E41FE -:10DDA0003FF5BA310476E797D9E998CF49B133BE48 -:10DDB0003D610D603F9E4849A84714BDF7CBECC9B3 -:10DDC000780F86AA3FC3DFB5A87058FD096E792683 -:10DDD000DC0B7B2265527133A7F777C0FF09FB4B41 -:10DDE000DFDF77673EF8377D218A33D52A2F2E7BF8 -:10DDF0008CB6DF9C25317ECDF5F5C3B82712890896 -:10DE0000F8CF1AF43F07E5452E3BDEDBA6AE47AA66 -:10DE100081FD1E4CAAF27B2B2027F0B4653339EB31 -:10DE2000529E83D96C3D53E3A3FF7ECCB0D26EBF2C -:10DE30008DD1B9A34C7F7F92FADCA9C8719DA5B39F -:10DE4000123EA9D77CEF89DF87F384FA551C7C4FFB -:10DE500042F03DB56748AFF96DD5F8FB61EF0DAC09 -:10DE6000C27B5C477ED703EEABA2EB1E222B9F004A -:10DE7000BA0BAF1AF16EBD56133B772724FA45F85B -:10DE80001E29D91E3DDEFD96824FB291DDCFAD7EBB -:10DE9000C76052BEEBFF8AE28FC5BBAAD83D45944E -:10DEA0008612A55F0219C6EF74D5758C3C976B522C -:10DEB000BEE77FFFFE43710CFFA144E73FA8E346A6 -:10DEC000FA1117E0FE6D4DBE7B9DEBEC02A2697F5F -:10DED0003F196C0578F76FCBD0E52562F91FC715A0 -:10DEE0007D0BFE821C152F41F7FE028D0365EDF8B8 -:10DEF00057D8F8E171ED44D68CDB96E57D390BFD02 -:10DF0000D4B922DE234C7D76380F4BED0EB3D77398 -:10DF1000D9FD84D42E5582FE56E322907B3101E454 -:10DF2000BAECE759291A3BA9F48BD447772AFAE8C7 -:10DF30004EC5DE249C53FD469BC47161BB33DA6E33 -:10DF4000718A1F1DA91F23ED82DEAFA67C2B6BFDFE -:10DF50008051F292F541FDCB0931F863E2DFC5BF94 -:10DF60002C9DEBC7F892547204F6416656E8ED3DDD -:10DF70009FEDC079F1D9769DBD5F51AD6F6751DAE4 -:10DF8000599476E3D1536B8F3823E83D06AF9E63F7 -:10DF9000FC90FBCE19BC4FA9229BF943B7E4781340 -:10DFA000B269FB837F9EDF0BBF3B31DCC4936E27DE -:10DFB000F4F3F60E3A615E1611E2D4B2B515850798 -:10DFC00069BDE9E7260FC4CBE448F4F8DED1C07997 -:10DFD000375196CA54F460AD93CDABD61912F229DD -:10DFE0001EEE5A864F66DF518ED7E8BDCC1AD66E2C -:10DFF00062B649677FA628E5C26C252E21C126F8A6 -:10E00000FD93CC1A2F0FF6CEDDC711E59E4DBC1F38 -:10E01000D5ED61F01D9E20F7405178DEED86E54597 -:10E02000602FDA53ED1EB0175B72FC9E6C90D7F335 -:10E03000A110906DE6F9011EFCBE5D39DE62A0877D -:10E040003A3FC928BA617FDC7E9EE1D719C1FF84BF -:10E05000EC56D6A59BE1E7F015033EA9F112DE4789 -:10E0600044FFF2C0AEA62629762395F8E1DE2062B1 -:10E07000A1EDC00FB2D176DAEF3789AF04F609828D -:10E080002953A7819D5B60F31CB3807D9D963B0D5A -:10E09000EE177AE940F47CFA32C5AE50FC1769F10C -:10E0A0008F251F23F7AB2BED4C31E26895EFED95F3 -:10E0B000D1FD556A09985FBFD6792FCCA7B6452008 -:10E0C000708F844AF75D39BE6AC0C7DD77900379E7 -:10E0D00075F795215FB9659E805FD162CB0EC2BD99 -:10E0E000B12D491F4903FAC7C2BBB6C1E8DDA495EB -:10E0F000E71601D7E360C4F93535CEF87836F3B3C7 -:10E100004339BE5A58E7FA234FE239C1877B2E0ABA -:10E1100063DDEF73B374E36A58FC52BB86DD9B5139 -:10E12000B696473EDCDC22E0BDACB5CF1D0EE17EED -:10E13000F17682FBA0B57D874FC2BDAC19B5DE1963 -:10E14000DADF21C8A865F7C7A5521E192842BD29E4 -:10E1500080DD76F72DAF45BE168948908FFCE877B5 -:10E16000655A983FAAD2F7A410CA7E99B63B692097 -:10E170009E665A7FD52417C24F345DCDB579E01E17 -:10E18000867F3EFCBAF469A033E4C55CB01EFE276E -:10E19000811E1D4DEC3C79C702EAF7D0760BEC648A -:10E1A0002B9417343B08C8C7CDD26166045FCCDC22 -:10E1B000CEE4E4B8A25FE81FDEABF4CD6C16D7A4C2 -:10E1C0001AFCD5E8BFD279B4CD46BC701EB66C6FD0 -:10E1D00010F02262128EEBAE0D71DAEF50D4679818 -:10E1E000AFBC5FCB4E793F78F6E13EE36645CF9416 -:10E1F000ADEDE1DED2F0C1F7B2D97EA9FBB9831C47 -:10E20000C487B4BE698113DB637ED0FD1C8B9B3653 -:10E21000D3FA07757A6503CEA7DDC6FC47AA577EF9 -:10E2200008FC7EC2F0E871D82F39318DE07DB377DC -:10E230009D0F9D44F5ACE07B4260EBC9533A34D16D -:10E24000F2A96CE6DF9D14FC9B60DD4FBAD977DE46 -:10E25000ED861D78EFA92AF791727A4AE173F79A51 -:10E260001ECE50847940F42755FCD476B7E494FF51 -:10E270003C1BE9308074A85BC3B37C8382CF02C1AE -:10E28000970F71DA1B0ABC63ABBF6D7C86E25757F0 -:10E29000C4213FEF7FE134F2655D27C77E27A8F3F5 -:10E2A000B4B04A135F757DEF34DA9525FD6CFFA598 -:10E2B000AEFF30FF8003ECCD31E4CF3ACA7FD612F7 -:10E2C000583709E97CD514CA067B19C99FF64AA6B6 -:10E2D0001721E75AC0EE83C3FDDFE05A0BFAFDAA0F -:10E2E000FEB5652BBF5BE9F0E7827E7D5729ABF079 -:10E2F000C3F1AAD503FC9DFBCEB46370BF5B9D87C1 -:10E30000F3C079E4E1117BC2F4B544D915F4B50A40 -:10E310003F927EAE1C66CFA2D891FF8A6647543BDF -:10E320009BFBE572FCDD3775FD7885EE23F63D87B6 -:10E33000ED4B597278051FAF0BF2D81295E78E128C -:10E34000B8DFCF57043FA1D69262F7407EE79F1314 -:10E350005F933668E87552A0F24ECB27F36C880FB6 -:10E36000950B6B8E66FD6A8BD8EF4AEDFFEE72A4BB -:10E370006B2DAC1DA56BAD7FD326A4B38B888740D6 -:10E38000BFF899FEAA5D730FBB075CB57FCF7348DA -:10E39000FF5AD981F75A2FE95B8EFC499C564F01F1 -:10E3A000877A0DD7599533DB085DD9FD4334AE6FBD -:10E3B000827C891AD7C757FBE43869B49C262B7135 -:10E3C000FD0C25AE37CDB27CA871FDE6869F61FCC1 -:10E3D000F388EB27F854E584C68D3A799AA1ACB35B -:10E3E0003B87D9D3B9394C2E3797F421FF6FBE1C28 -:10E3F00040F97154323DE238AFD77F6A1E8C903DB0 -:10E400008C0FED7D0B611F62C1573811F4402CBC9D -:10E410003FCA057E01E755C861768EE28EEBBF8C60 -:10E42000D7DE47BA3487F1F7D55E230901BDF980FD -:10E430003096FF1B0B5E56A862F6BFD3F5FB756FD7 -:10E44000029E0BBAFADCCA4F4259EE49C0732459F6 -:10E45000A12AE48BABCED91EE0036733A3D3D5BE8C -:10E46000F9C83FEFA44906B82FACA9EFA979F0FB92 -:10E47000D01B15BCDEF9AEB101E8B0E3EBDF9907C4 -:10E48000F74B6E0E72C9F0BDD9D5DEAFFC05EC5E60 -:10E490004DCF163CF7D5FCCD7F42BFDB103CC8DE2C -:10E4A000F72688D06EE8AB4FCE03FA36F73563FD1A -:10E4B0003B5F3D88E5635FFF8EF19992301FBFF3AC -:10E4C000DD833FFE6F28FBE2F1BB9C5AFFFEC7A134 -:10E4D0004CAAE2D97757FE9705EDEF75751D3E8A78 -:10E4E00072A8F2C5923E4EB93F4CC0731E2AFF5E21 -:10E4F0002A2F2A05B9831B768DF368B923AE265AD5 -:10E500001E71A732DF5AE04518770D1704396817D6 -:10E51000E45ED4E7625F36E8737B5148807B5756F0 -:10E52000571F9EC77E76B009EB575AD879B1A954C8 -:10E530005EE01E290AADE706F56B56B63FBC0EE05D -:10E540001D3012D1981EC6B75E90303EAA5FC179C9 -:10E55000A884118E6C3B9102FB5F0D4439D7C5DA5C -:10E56000B5D3F0D29284768858E9B3745BF43CE872 -:10E57000BE1C87229F4C5EDDFDCB33417F10A7D9A7 -:10E5800053901B8697752ED001D7F9BB6B0616C228 -:10E590003C16176E980EF37042BE0FEC8BEC40F8F1 -:10E5A00075909FA4F21454E42655F4E17D2316AF30 -:10E5B0002F057E834D32FB703F4F5AEF3335819EDE -:10E5C000E187B357A1213CA4CB7B7599FCE93300CB -:10E5D0005EBB629F7A18FEB43FC293E67B9DD09FDC -:10E5E000C24778966A2F8FBFF16661EBF09F3FBA02 -:10E5F000F3903E5F1E1C05BFC401F6455E83EB260B -:10E600000938DF77A029D25BBE559BC78ECCF78037 -:10E610003E83FDDE504ED90F7266849F6A1E28929B -:10E62000CE7F817AD01F92179FA437F9A67E0F5014 -:10E63000D5DBF57B14BBFB838BA877EAFD3CB3BB32 -:10E64000FECB68777FDDE8256F51C7B2EBC58BC87D -:10E65000DF0F1C6176B7FE48B100FCACDE8B5C5F5F -:10E660007E15EDAF6C24C8D7F542DF4917C0EF2007 -:10E6700089D4B327F5F3062782FEFBCD8BD635D0A0 -:10E68000FF84C180FC76A2FB9683CD9C163F1607C3 -:10E6900070354194C77AC52F285BBBE94988C7EA22 -:10E6A0006A08C685F5FD8A7CD1780CE85B7FE43486 -:10E6B000F28FEAF7E67E7905F25B22E537FC9D846E -:10E6C0008A01C48FFE790AE833B182DD8FBBB8B00E -:10E6D000B814F8EDD8EA1FEF04BB5D5F414480DF5A -:10E6E00095E57D11EF017E91C37B29BB4C9DE5F043 -:10E6F0009D64D7024904F9A8F7578DD8273C5FEDF0 -:10E70000AFEA47F971AEF380FFD0D1E447BFBA2337 -:10E71000DD8E7E41D78B4D683FEB259B077EBF6426 -:10E72000C9116E2BF6971D84E1CFA19FBF24380736 -:10E73000CF6DA9F458523198CDF405C3FB37A681AB -:10E74000FB61DEBFF99E19EEFE1EE1BFC48AC00167 -:10E75000B8AF768938CD03F76B26F1037EF077A842 -:10E7600009F634C1FEB0C967F640DCBD97C37DA889 -:10E77000FF076B233BDE0080000000001F8B0800BA -:10E7800000000000000BDD7D0B7854D5D5E83E730A -:10E79000CE3C924C26274F1208F14C123040124EBC -:10E7A00020BC114F88416CA90ECA2354C4E11D201E -:10E7B000242362C55F6F33381023BFD71BAB156AA4 -:10E7C000A91DF0516A45A38D354AE01F10107BD575 -:10E7D000466B11FDD18E4A798964E451E957AA77D5 -:10E7E000ADB5CF49E64C263C5A7B3FBF1F3FD9EC25 -:10E7F000B3DF6BAFF75E7B4FEA64A6058B192B780E -:10E8000040D0824EC6EC8AC05826A6163DB5313699 -:10E8100082C19F669ECAFE524F09635F3468ECB3A3 -:10E82000018CFE28598C2DA37F30B67C41C8A640B0 -:10E830007FB5CFF2FE32EC5AD9ED907E837FAE8663 -:10E840007C25BBD503E599A270EB544A2D941AE5BB -:10E85000465AACCFC3FDF8BC87AA3218FB5E0D53F5 -:10E86000136088BE45F01DF2CCC78203DC90AFF187 -:10E87000E42A589EB15815219F99CE7E88E591D5FE -:10E8800036B659E8D9AF8AEB1A81F53CE502D4CB0C -:10E89000EC93AC067028B1C29280EDCA0475B382C5 -:10E8A000F91B9F64E590CFCC51B11FC6823A1C3C46 -:10E8B000E516A877342B595D87DF837F906E047847 -:10E8C0008C5764A3BC0CDB292EC6D69575B7AB2A32 -:10E8D000F0507F557D12D400CC734AB3BF94E573DA -:10E8E00038789CDD7008AE4EAC0E46C16324C20180 -:10E8F000DA0707B1EA966284BFA716FBC9B2A8E996 -:10E90000EB5221EFF497DE948CE304085E57E03C71 -:10E9100020AD82F5F9B0DF02CF4A824766B21A0F06 -:10E920001EA12B383C76CD7C4EDC00F5EA8A85A012 -:10E930001DE6F7C8B6A965B8CEBA694E9541BECEF8 -:10E940002BCDC37199DFC19E823CF32E78A80AF2C9 -:10E9500075351E759D42EB5E80E5B91909EA3A28C6 -:10E960007FF41541C37C9DDF194C80FCF7DB383EFA -:10E97000D4B5BD20CD873409F1CE89EDFCA5534B2C -:10E98000BAE7C3D86A9A4FDDC41379BBA1BD5F64EF -:10E99000AA3801F2B6F04015D65F37213C10E17578 -:10E9A000F295846A6CBFC762F1E3387B360FD914E5 -:10E9B000107AF673D2EA69C5F59F84F5FBA1FCF5E0 -:10E9C00057DE0FDE0DF935800A6236ECD16AA502FA -:10E9D000CBD7553119F7C5D8AFBD367F11E2D5DE9B -:10E9E000FC44C20F9CA707E07C1CFF99C358FD158F -:10E9F0009E250ACED3126A94B0DD9674C6C640FE38 -:10EA0000D5FB077A9D3DE10CED695F1C1223FC7577 -:10EA10000493828128BC7238184B1E46A9DF09690D -:10EA2000D22A0E9FD87EEE519C547FB923BC177614 -:10EA30008ED5AF6A7664011E2D4854E87B82D5A737 -:10EA4000F583F9D8DA2A42FDA03C2B0DFEC27DDB0E -:10EA50009C14C47DCBCA62DE17E3F45BA7D39BB1E1 -:10EA60002FCD698CF032CBC5EBFF4CA79B07F47A16 -:10EA70009BF5348A2ECC78EFF4BA914F6425326F2F -:10EA80004B9CF18CF6303F2A37E6C51CD04F06B6BA -:10EA9000532C84DF317417CC2C1986745795A8EE4B -:10EAA00072203D0D730F0BB0EE710031DD53937B7F -:10EAB000E201AE03E907D78574D65BBDE69D9C3FB6 -:10EAC000C5E2E5B33A9D2C425C87793F27003DC6FD -:10EAD000DD67DE4F93C56D7914E6FB9FFBC5E066ED -:10EAE00077CF7A46FA6003D0A09DB1FC8DB3523C3B -:10EAF00025BDD7DB89F5AE84711B1C54DFA92AAB79 -:10EB000025E87FA2C35D26321C4F9988E3F9613C5A -:10EB1000DCE7E409EC4B11E053DAD65C74AF1BF18F -:10EB2000BCA51AD7355192A532E40B1E0B0B1571FB -:10EB3000FEFD0DFCDFA73A91851CDDF91C6F9A29BB -:10EB4000DFAFA6AFA97E7F5FBEA9FC8A55834DE5E6 -:10EB50006EFF3053BEA069ACA9FE80E689A6FC9585 -:10EB60001BBE67AA3F2878A3293F64CB0F4DF54B06 -:10EB70005AE699CA53BE2ED8F533C4735C7F1C3E47 -:10EB800067A4C71537EDCF444934F537B4CDBC7E03 -:10EB900089852D48EF29138E0E8B47CF465ACAA47C -:10EBA0003361A31DF20187627914E6E17A5F0CAE4E -:10EBB0008BB3EF063E1BF994D1E67D30F8C4C5F067 -:10EBC0002BDF7B617C31F0AAB7F294AFC5B87499A2 -:10EBD000E8E67429310FE3EBAF562FB47E6BECFA05 -:10EBE000994278FFAFAE3FDF3BA82D0CFD9CAD16E0 -:10EBF00048BEBC8745637AF6F751CC3A67AC4C21E6 -:10EC00007D86796E8A5BBF7B1EF7D23C6EB1335F27 -:10EC10003C384C7273B93BCFCDE9FD62F4F9893EC3 -:10EC20008F3F1BF4B9C64DF4C8DE138303A0AB7944 -:10EC30004DC2CE3E8017695EA72AAA909742AC2C9F -:10EC40004ACE3FA2D3F7A3D81ED20D0D32F5F3580A -:10EC50004336A51B1B14FAFE784311A5C10695BEC9 -:10EC60006F6E184DE993A08F61FA74C3644AB7348C -:10EC700078A8DE330DD5943EDBE0A5EFC6FEDCA21E -:10EC8000EF0FF3A4933C8B5DCF9C9566FA30F6852D -:10EC900089C5D47E0ED0997801BED6A3BD383BE598 -:10ECA0004278B4EAA0FBF9DD517830DD9D9C7178A3 -:10ECB00008FC63141BF58D78F1F65F3528CFEFB6AD -:10ECC0005E9C2E0C7C61E73F1B10AFDE2D49503659 -:10ECD00016F893FB97CD7E67EFF0E9C6A3187CF595 -:10ECE00000BEC2D75294ED39581EEE1B3DCE9FF4A4 -:10ECF0007D36F2D3A6717C8DEDF7419D0EA7237E64 -:10ED000042F98C187AFD422FFFC2CDF5F4FDBDF01B -:10ED10008B46B745979F7CDFA7033EA2FCBC3769B3 -:10ED2000CE55DE38E3FEDDAD98E873C634F33EEE33 -:10ED3000B772FEB6FF4F6270759CFDBF587B633D96 -:10ED4000B1EDFEA0AFE773C4C911FF73E86DFFAC6E -:10ED500064D2E7F75BBDFD33A3F667FFACA4EA78A6 -:10ED6000FB7EC66DE57456243394EF2C8D69A8079D -:10ED7000C192FC36D4E558A17C18E9048C21A48BFF -:10ED8000DEF15262870D7A12119E09A48F9F9D9623 -:10ED90004CFBCFBCB2C6A2FA67924C7AE9733F0033 -:10EDA0005D01C793603CD043996AE9DEBF7CFC3BC0 -:10EDB000B19B5F8BBDD3DBC5F0C0E02333908F5C8C -:10EDC000405EF76C77797CE4E37F131F31E8989D10 -:10EDD0009F3FC093DCB37C3AF291BE8C3DECDE4F9A -:10EDE0007CE49F869341B7EF73BA8DE527BDB66B80 -:10EDF000CBB888FCD3F9B9E46B0A035EDC2926376B -:10EE0000AF8326F749BE5F62DEEF97D85390DA579B -:10EE10009DEE7B6838755B2451BDC164DFD925DF69 -:10EE2000AFC2640FDA65ACB73EE9C7CF637E157039 -:10EE30004C3BA45F25E40519D80243F2397F121D2B -:10EE4000E7FA1E8A9A9F5566FDA2F3652147BF43E4 -:10EE500051FB367C9F6CCA8FE8C836D51F75403190 -:10EE6000958F091799CAC71D554DF9AB22A34DF5CA -:10EE7000AF3EA799F215EC3A53FD4AC75453BE4A28 -:10EE80009E65AA7F6DF65C53F975CA1253F9D84294 -:10EE90004F493EEA0F36679390C2D812B7569A0F81 -:10EEA00070484CACF3CD453B69B54B6613B076303A -:10EEB00088706BB439E475C0A73E15B43C0678FA87 -:10EEC000B005ACEE02A82F8619A6072D6A19A6F97F -:10EED000DA162FD269E9A04405F1217120631D28BB -:10EEE000A7243581013FB12585DF2D44BADE06FB1D -:10EEF00007A8559A0A8A3EDA013F480BA2FD9B9368 -:10EF0000E8ADC479ADB334BB56E33E5B98E729ACBA -:10EF1000CFD4FB47437AF87A8B05F7B7B5C3F9C06E -:10EF200058C80F85EE19A59FFDE4FBB8DF1DA28A26 -:10EF30006E9F87A7BC3809BFAFBC8E896259EF7836 -:10EF4000F6F98FB83D15FB7D7D3ED7AF322BB99DCD -:10EF5000195B7E875EFEB92D7EF9C27C2E2F2AEFCB -:10EF60009BB21ED767EDB032F45BACCCD4FAB00BD9 -:10EF7000E9ABE70A587078545EF230D989DF07D2DE -:10EF8000F7CAFB66B3B093F7837EAC95095A1FF4BA -:10EF90003B7C3E31FE3C96EBF3B49E4BEAA55F17FB -:10EFA0007DFF3CFFC2EBB49E4B60C1F478ED9DF455 -:10EFB0003D3310BF7DA301A7B4F8E5F7EA70B29E18 -:10EFC000CB61FEF4E8769CEF748F934BE5D673A982 -:10EFD000CC1F771D19F49D656BD988373B81CE9185 -:10EFE0005F54A466D91890F81C16D9A301FCA7A2F7 -:10EFF000490078CA1C6A19F22926592361832E40D8 -:10F000007ECC65D2A7682F580019BF81A9DDBACA86 -:10F01000FA69388A8EA66AE63CC3FA51F2E630F6FF -:10F020000DF34E1C5C9482F87E8A2929721CFC32F6 -:10F03000D2D90ED12345ADE7602F7AD2EF75381DB6 -:10F04000CC890FC7DFE6733D6AE46C16575FFB7D22 -:10F05000BE8BEB81456A9F0BC90D84AF373DBADF8C -:10F06000D87DC8A0F24B8533E005C9F5C80F9C4197 -:10F07000F2537EEBF036F0A79F092F0E1728FC7B8A -:10F08000D7BCF3A83C2FD7F3663EC9156520CAC587 -:10F09000569D7E5B252D699813F918AB8907FF8C67 -:10F0A000025D4F8D59772BD3B2E7A25F43B2AA4FCF -:10F0B00031E487CCF7421CF8C7AEDBA1CF1BDA578F -:10F0C00087B03D73A99CCF318F230BF47CFC172CA8 -:10F0D000A1C2FF8E15FB9FED73A9EB40053AA9CBAA -:10F0E000ABB92C6C453EDC037ECE0C2BFA6D63E194 -:10F0F000E861CA1CA1E0E2F0B438E4ACADB0BE39BE -:10F100007E1743FFCCADB399AB04E6E1FD41DADBFA -:10F110001AD49977FDE0D235980E19DF2852AB6BDF -:10F1200048DF13FCFDC46F865CBABED7E8F2162137 -:10F130005D1C129445B47E01D68F72A6EFF18173E7 -:10F14000A3E0B7B87FC5DE02F47B5999968E7EE2C4 -:10F15000ED76F257B10D8CF4CFFA1D8336A19CE900 -:10F160002CF0EEC67AA3AED1FDB65A64E08DC997F5 -:10F170000F27F86345FAB8189CCEE7733A3FE88A40 -:10F180008F2FE5057C9F2E954E320A381C22008772 -:10F19000CDE5DF3E9D00FC4C7C63B78E7F466AC0A8 -:10F1A0006DD464B35F77B7BE8EDD059C7F7416782F -:10F1B00008CE9DFDBF3C9C8072DF06EB8F83EFD7AE -:10F1C0005DE6FA7BA3936F8B1F1F4C8C3FCF39DF1B -:10F1D0009179BE6ECCB334FE3C6FBFCC79C2FE2CAD -:10F1E00072147CFBF3EC2CD05E2F403994167F9E7A -:10F1F0003FB9CC7902935B14827A3380FF61BD6F93 -:10F200007BBECC3FB70AE5CF4D5EEEF72F014E8BAC -:10F210007C08A6F2E437C351AF55D76E40BEB3C2E7 -:10F22000A5FA65E223AF237E031F641ACC67DA6474 -:10F2300081FC489D23BE5C2421BE67B1502AF2ABFD -:10F240001D76F263C7AEFF67BA9C003AF925C28902 -:10F250004D890C447E7270607C3EF1CBD8FA4D1122 -:10F26000924BEB2AE2EBA5BFD2E975B9A37972966E -:10F2700025FA5C0516282297F569FD50CE96CB6BD2 -:10F28000909FD8401E215C6DFD06F7C1FD80BC47F4 -:10F2900080B422FBCD03828BE07DA20B7EF9DDE3FF -:10F2A0001C6FD827175A7BE7E7CBC41747FAE2ACA5 -:10F2B000E7578AF7D582287B71D99637E4C268BFB1 -:10F2C000380B5B18098E08F9AFBBFC057DD865F9D2 -:10F2D0000B0622AE64A27CF0907C40B9817673E389 -:10F2E000AB63CA707341EF6022F2D3E4449217819A -:10F2F000BE638B9428781EECD21BC45EF4499BE954 -:10F30000FB470D0E3025BBF3B71C7DAF0AF5F8396E -:10F310002CBC16EBCF599984478F5DEBECEAEF9C40 -:10F3200060D26BBBFB97E87B85C31912C188A970BB -:10F33000FE3EEE7EFC4AD13EC1F5FDB8BFF629A6E1 -:10F34000B1F0F3DF373E95FC0708BFAB7BEE7B6F78 -:10F35000FB7C5AD14E607FADFD65C39FA3D2395C63 -:10F36000A2712E2CC9871DDDF0BED47D7910FF015E -:10F37000767D52A1760EFBD758AD0FE733DBA0EFB9 -:10F3800018FD868D4E233F64A3AB63EDCE283ABCB7 -:10F39000D512C9E4723BBC169D4B7FDE9E40FCA398 -:10F3A00073FBEBFDBD748E66E81D49E23749973E5D -:10F3B0003FC3AF604D8CAF471BE717BBACC585A4FF -:10F3C00097E0F9EE68C80BCA02B4272599A90198FD -:10F3D0006FC5B5804DD0DF4431B73D0CEB38CB4E17 -:10F3E000A45D85E0D3FDAA2BDF199180F39C2859F9 -:10F3F0008F47F3A758FF4F5EA1D9FF738ACD4E09FF -:10F40000215C8AB87FA4F4956B52D00FFAF09489EE -:10F410007D30DDD9D0244BD66E3F50ECFC2B7AB139 -:10F42000478714727CEF48D48614C2FA2A7A59BFEF -:10F43000AAD73B94A8A98599DDFD61FD7871106F6D -:10F440005CA9F37B1DAE37F9E792BE6571005F459D -:10F45000FE097AAB28A37FB0D04AF4AE3145CE2264 -:10F460007F21DF7FE0EB12E4AFD2F342D307016CE0 -:10F47000B7F176179D7F33AFC2503E0060E83CA0E5 -:10F4800051F091BFC181F11E90AE13D40D22A4A200 -:10F490002592CEE922C8E3199857C2FCEB42388086 -:10F4A000F1016B1C3FFE25FABFB580C41226405EF9 -:10F4B00062E45FF41F4CA6F3389A19CCC36ECC4BB0 -:10F4C000CF27EBF9CEE993260F80F4CEC4C75D8831 -:10F4D000A76101F828F4F355E28F434437BE44D5C1 -:10F4E000DA17FD4A1F535E5891A80AD9E8777215BA -:10F4F000A19EBA8A25AA7618477396F8715C9BC2BA -:10F50000C80F9FC85A681D4EE7177E048ACC640155 -:10F51000F33989DEF98564A7303A1F3FFC71F26642 -:10F520005C7F827C2A74377C4A671AD54B8F918F17 -:10F5300099CE9502C56D78A418B9E81510FE7DAA7C -:10F5400063BF9BE5A5831D94111F859027FB1BE0DE -:10F550004F1D08B7F26EB87548DC9E33E0E69FE8B1 -:10F56000FB15C2D57FAF5D0E64F4EE6703008D42DC -:10F570007DBC435EB415EB83C1C42CD85F365F9F5E -:10F58000BFC6CEF741F26EC5F61F5AB365B4770C0D -:10F590003C6B1EA8FB217AF1733C58C8F1B02EEDEC -:10F5A000701DCA3906835AF2C05E4A3E3A12F90605 -:10F5B000C8CB26949709568DE06DC8CDE5ADB7311F -:10F5C000A4ABBAB6B90CE9F543C13B6037D9238C7B -:10F5D000ECB19993FD7B2C0AFAB0A6AD75427AB8CE -:10F5E000309F9F67EC99B487D890E82CC176655717 -:10F5F0007BAA3261DC400953EF857A8104EFD6970C -:10F60000705DEF882AFAB9EA5755B2CF86EBC80485 -:10F61000DF37CD48277F694665A411E30422F7331D -:10F6200019E37A7AD0C77958DF48C69EA0B1A09F67 -:10F63000057208F12707F04D90BBCB9FC4F2029EE4 -:10F64000BF1AF2F57C4B59417BC50D23B85F8CA1E5 -:10F650005FACBE5D207F5BC1B4E1A4D71462794684 -:10F660007479EAB267215F587D958AE4A458BCBFDB -:10F67000B803CBDF66B40EA6F3EF5131F43BAE9B7B -:10F680006EA8BCAC2BEFABC4F9EEB98D91FD5AAFAF -:10F69000CB5B13BDE162A14C1B89F8D7D50FC37EAC -:10F6A0002AF5FC3849A67E727D4CE70B9E8D3FA55E -:10F6B000F3018B8A7EC946A199E0C3FC3ED2F730A4 -:10F6C0005E06E9256FF6CE5D561C2C83D39DBA8F5E -:10F6D000D35D39F38808AF91F2FD011C7FE66C37EA -:10F6E000F199314719C185280FF257A50AB44FB9CE -:10F6F000030A68DFC73BD42611F04814CB0A126016 -:10F70000BCEAD9029D4B4CAF760405F8E774A00F14 -:10F710008A8392BCEE1980EF33BD023FEF85FCEC8B -:10F72000283F3C68C3745E36C3CE7C2FC4C1E7DC7F -:10F73000019C0F1BEDEBD7D84C7E9DEC014E2AFFB0 -:10F74000BA70D261E2138CC7B3E4247A8E217F674A -:10F750005233F1A9C316D0BF51FF651AE9DB37E96F -:10F76000F46EF08BE9DAED64074FF798F5E80F7166 -:10F770004F900E6609A4E7CEACBEB09E7DAE50D0D1 -:10F78000CFF172E5C349DDDF15A6903D7D23EA394F -:10F79000A5F07132E82151FAFDEC3BCFA752FD3EB6 -:10F7A0004F2FFFE60A40851ACE5FEA019EC82F2B35 -:10F7B0006649442F756B6C14F755DFB6DA9A85F8F5 -:10F7C0007C0F5339BE7ED2D80FE6D9AF561B212A03 -:10F7D000DDF0E9571B1490AEB390E710FC2336F42C -:10F7E000C7CDB0A9B5B8AE19694CF6A7025ECEBABE -:10F7F0006E23F6BFC6C16411E46DDFF677828857C9 -:10F80000C0CA55C449C01C8A67CB9593E85CA1C99E -:10F81000328CE2B59A5CC96A747CD4BAD5DD78873B -:10F82000715A8A9D0D93F5FD8D6727150CE0FCEA52 -:10F83000518191BCF0CF72109C330B789C52668A38 -:10F840006A0BA422BFE17CEA5181C7D73D6AF5E685 -:10F850000CC7383C502BF9FEF076B1749F99AEF787 -:10F8600093A4080120C669ED65E516849B3359C54C -:10F87000B844A3DFCA44CD8A7CAB72B0302240F0DA -:10F88000DC242D40FD34C1CCF7AD56BE2FEC23CE89 -:10F89000F763E520C801E2FBE8AF0F9493FC1A3F41 -:10F8A0006004C903EA6795E490ED2AEB21CF323C6E -:10F8B0002C19FD5BC30064A8AF77647BA662DC9E55 -:10F8C000FF4D89FC69E5D5EACD0BA3F6F5E7037595 -:10F8D000BD7D62640EC541DDA3F6C338A83515DDD4 -:10F8E000798C77AC61CD36C4F79A18F9B8D4B99B46 -:10F8F000F4C8A54F5ABBF197617CA85A80FCA3F6C7 -:10F90000D91EFE20E253DDFC2CC6BE64F26BB89E0D -:10F9100011C08F910F6985C922F995D96C2E47D9ED -:10F92000D302FAC544D7AA26947B9D4272B358DE0F -:10F93000CD2747E8FB759FE479ED6E5C37E84B4FC8 -:10F94000C9ACA71C603ED25F2680DC443D5A689F4C -:10F9500029E2B81B1743DF788E2F852B317FE762B2 -:10F960007E3ECAFCB7D1F9D738BF5D46FAFF2A31CF -:10F970006F8D3EAECF0ACCFA987C0FF5C7605F5012 -:10F980006F11901F4279DFC9D014E8605CFB11EA67 -:10F990006F633AA78B583D66B7C519B45890EFFA14 -:10F9A00049EE24B06036C24F2BE47CB6FC00E7B3CE -:10F9B0002FFB4183165195F5DD34C54D7A20958F87 -:10F9C0008D308A9BD9CEBC75BABEE31F908951A2F7 -:10F9D0003ECEC7757DC1D0E3AA62F6F15AE7231285 -:10F9E000F2AD6BB37BEC9788FD4F6602E98BD729AC -:10F9F00017E65B9AC19798992FB9D979DA3F76FFC4 -:10FA0000DE3BD04F1088D1830297A907A5BBBD1B51 -:10FA1000911E62F5A1DEE2289FD2F9FBA5C65182B4 -:10FA2000063107E5D758C3CE8AC19FBABDC7E73CA8 -:10FA3000C0BAF1AE0B9FFD9B6EC675803C97D1EEB0 -:10FA400013FE6B3DD1F51AA8278E47681E0CFC1CCF -:10FA5000F2210BF3619C02F3CAA7114F0DB90B9C65 -:10FA600088F0A47121C7BB5112CFE782228B78198D -:10FA7000181DABAF7BDDE887D6CA4B282ED690C7C2 -:10FA8000C32D1AE1C908A6A6633D034F46867939FE -:10FA9000E0C76EC48F7193015FF231BE76543FD4DC -:10FAA000BB2A9842F8511123D72A9DD324A4F34AA4 -:10FAB00047ECFE6B16ECF71A1D3FAAE47F0E3FAE33 -:10FAC00040FC30E416E8C9F7C5D817F7C5D8179732 -:10FAD000801F615CDFA5E2C7B101971767DB69BDD5 -:10FAE000E7637F39D9B33E31AF277E08ED772E7AB1 -:10FAF00000E93D90CC70DF5F48902B9D30CFFA1A23 -:10FB00001E6F3EFCADC200E6B396BB492F7C21556B -:10FB10007D8DCA7DBCBCBC431393215FB012CA214A -:10FB2000FF82DB5389F9FA55500EF547BCE70D60AB -:10FB3000BEF01E5E5E76AFEFB56494F37EDEFED55A -:10FB4000638DA20BCA838D7AFB8AE64ACCD737F144 -:10FB5000F6230F0403981FF4001FDFD03BAFD6F944 -:10FB6000E70BC2A9D7EEC2FE807F6E06FE39EE8497 -:10FB700056F61CE417C8160BE2EDC288DF8AF8704F -:10FB8000D8523B12F187CDF366239ED9D16E15BBB7 -:10FB9000F997059D3AD06E826425BDEF0DC12761AE -:10FBA000BDC94812286747AB0EE4EF1887BC19E4BB -:10FBB000CD005D1E1971BB787F606AD47E0D18C8B8 -:10FBC000E5BC512F2B8DE3057B8CE38511571C5A27 -:10FBD000CF04F4B7E0DAC80FD123CED847F23BD830 -:10FBE000BF6418E2EDB5185F0CE5D78EE5F1C56589 -:10FBF000DF9C9E14CF2E2AD6C73DAADF8730BED702 -:10FC000004DD16A49F171079FA62FFFDFF88FAD26F -:10FC10000B38D65802A99F8DC67DE4F9B103731E37 -:10FC20006E02BC586CF14988472C4F5071FED77753 -:10FC3000F8AEA1F5D43276434E9C75E8F27E51C001 -:10FC4000B699C78770FE335DDFB763F2EC3D7791FD -:10FC5000FDEC52AD30CEC4F10388EEA7550B06DDA6 -:10FC6000570E443D184F30C89FEDA538F7252C6836 -:10FC7000C34196C4D0FD32E7998F512E2DDB62A689 -:10FC8000EBE52C64E3FEE6C8E31F40FF351B9265FD -:10FC9000943FCB5BCCF56A36BC754028EDC9076A4A -:10FCA0000C3E1034F3015038381F583F98CEBF56E1 -:10FCB000648BCAA174F47FF848DE27302EEFEF93EF -:10FCC000D430D15FBB9DDB51BA7E7EA7C8F5F3046B -:10FCD000E6509C45C8872D7A9C2ACF1BE3B398F841 -:10FCE0009653CDB711BF31E260008024EF4FF9AFDA -:10FCF00095A3FD6C5D7C3E86DECBDAFB84F09E81B5 -:10FD0000E16701FD80EC2BB60038DD38E243B46FCB -:10FD1000C252F87F0CAECB46EB5A9F9447FC7D1540 -:10FD20001084BD0CED62A924847D0EE6F4E4403A13 -:10FD300042FE3ED96C6F2530AEC70FEFE07E9C11BE -:10FD4000DD72BF01F7D7CE540797FBCD0CE9AB5757 -:10FD50007BC5B932AEBD42120AFA9F3199F3F58BD9 -:10FD6000D92BBDD9235DFB99007A1BA4D3BC09CF45 -:10FD7000E3BAAF3E9F921C2F8E6A5A85E841BB6C56 -:10FD80009A55CB4C8B1727897A7666547DAF93FAB8 -:10FD900093BCE9CF63DC12F41B42FEDFF1A62D6EAB -:10FDA0003CB2A4F72F5935395EFFD7A2532ACADFD8 -:10FDB0002E79B3A8DF6F415F7971601C7DC5B62BCA -:10FDC000E69C92F90746C7133CA3FB0347166A6DEE -:10FDD000D8FE60421EF13BA50CECA97E94A7FE0E56 -:10FDE000DE762DC5479C61DA45E323D644F9CF0F73 -:10FDF000A6C63F17795DE773368C7983716F57B468 -:10FE00007D8857476DFCDCE568A29EBAF8B9D51F1E -:10FE1000BBEAF3F498C1272DBCFC689AF9BCC6A8CC -:10FE2000F7B9EE873AD4E0F0AC89F2BF2AEBED3EA9 -:10FE300094D39905FAFD8D958CECE7CE5752374552 -:10FE4000EFEBD98115B62B33B19E66CB4138BEC2DC -:10FE5000E55F9D14B6E1FE3E7285F7139C779DC267 -:10FE6000B417B11F256CBBA904ED061E17D269E5B6 -:10FE7000766067024F8D799D1D38D576259E23DDEE -:10FE80001626BED8959F1A26BE7776A087C6ED9C0B -:10FE90006E94EBF9FFCDF30A93559C6F8543B71F22 -:10FEA0008AE435E47705BD0FFD36B1E7078C8DE7B1 -:10FEB000FAB11EE7A9E5FE83CEF17AF3F35B1C1DD0 -:10FEC0007B7E0EDFE7E8FE606FDB977BEE56087FF8 -:10FED0000EE3B87383098CE2BDFF45BF7E67FF0E5A -:10FEE0005ACFBA8A48DE63E5142F407EB5E5EDAF00 -:10FEF000135F5F6ED07DAB99EED3AEBCB473B5D853 -:10FF0000F3966F81CEAEB8320E9DFD0EE535E0570B -:10FF1000953885F8DAA95681FC210AEB684438AF98 -:10FF200010F8BEAC78637EA50DF30B994C7CBE3502 -:10FF3000969F7903A8272C6B6224EFCA58410AC206 -:10FF4000BB7E9F883E04BA67A344F149BC67A344C3 -:10FF5000D9C578CF263A8FF76CA2EBE33D9BE872C8 -:10FF6000BC67135D8EF76CA2F378CF26BA3EDEB382 -:10FF700089CEE33D9BE8FA78CF263A8FF76CA2EB67 -:10FF80001F61BE47C70B08D7091B10AEADABED32E2 -:10FF9000C295F9B5778BB3489C11FEE17D9CE87E54 -:10FFA00096B926D996031CF6668B4C188DF76B967E -:10FFB0009AFA5D26D6929F00D40E92233EF88FE0E7 -:10FFC0002916939D7CB64D80BD037D68438CFED081 -:10FFD000FE5023EADB4B82E6EFCB5894DFDDDDF306 -:10FFE0001CE8D62BF573A0BEAC2FE27395E85471D4 -:10FFF0009F4FBD27AA76A6BB00709FB7727F64197A -:020000021000EC -:10000000BB72FD78DA472B0B2A783CC2CB4F6D14BC -:10001000837E77F7F9D0A97DBF3DEC857A8B734459 -:1000200019E9CE9E6DDEEF04C5BCDF4945E6FD4E05 -:1000300056CDFB9D32DABCDFB1704ED5CCFBCFC4C0 -:100040002904E765FDC0BC83F1D3279BF1C180EF94 -:1000500068F88FE3AB42F05D04F07D4CC073B507E8 -:10006000F6F6537AC2B9AEED211BEAAF970BE7075C -:1000700010CE49DD703ECBC6573A09B86C9A63641E -:10008000B7BE54BECF474102C7E4DC4AFD3E2F3F16 -:10009000DFD1E10AFA0BD90B51E7504DA248FACC57 -:1000A00063C857B58C64E203EA8624DAAF610EDEDA -:1000B000DF42E625FEB43046AF59EC7CC4867A4D6B -:1000C000EC3A7136E877A969E77A4DEC7A7BF8A3C8 -:1000D0008AE4503FCEB75B1E537199ED069FF6A29E -:1000E0001F238375D8508FE98D0F7E2F5B7B1EF900 -:1000F00011703186F0E0A600FD89AB4FD6771573FD -:10010000FFBCDDC7FDFCCC9F4AF318C5F83CA851E5 -:1001100094BF7F941424BF432EE3FE25C31E8B851A -:1001200027CB15D6BC0BFD8AAF311D8EAA2858BA35 -:10013000FDF760056AA85F8F3CC3F5A7D18E968056 -:10014000A4F4B4CF0F17E8E7DC921EF77991734857 -:100150009C3FFA396ED2E3EEAE6A1FB507F35DE756 -:10016000923BDEE887FB357EC75BE998BE2B284FC4 -:10017000DD0DE3DF2870BC88B52B03DBC729B8FF92 -:10018000570B1EF2574C62BE5C6E8F0449CE4C700A -:100190007849AFB538342B9D47E9FE4BC6C2935022 -:1001A0004F5FAADA681E6BE44F27A13F6619D3FDA3 -:1001B000316DE6FDEB610FC5D841B5B0FFD86FAC2E -:1001C000DD13078F62E201CCF2FE87453A3C198FBE -:1001D000575118BFF75DA3FB916A1C1B5DFC1C0EF9 -:1001E000E45C2EEB61374908F831745EF135E25B6F -:1001F000561AD80374DEAFD8E2C5EB313983CED5B9 -:10020000E73BA7115F9EDFD4C3AF4378BDB0F922AF -:10021000EBD2F58411F80DC6FDF3950AF7A3244E31 -:10022000D9A7617179475EB43E5B6FE3F772992F8E -:10023000DD745F21BF88EBB9E5BADE54E3D0E15449 -:10024000E46F44FDB84B6FEA612FFE73F7638C785F -:100250001780D78022FD7C677546F7F98EB18E2F07 -:1002600046743C1D027889C9D738903F2EEEEF1DA9 -:100270005204EDFA1F081F46BA614E85F4F5936DDE -:10028000C7F68BF9DDEB023C7B741CAEA34D94F9F1 -:100290007D797FE338E8B7B38CE35DEFF6AFDF98A5 -:1002A000D7E878F332E2EBABC4E2947094DEEED49C -:1002B000E17774B06702B62BFF63AE0BE76BCD6FCF -:1002C000D9DB17F5E23BB85E0CFB4A7E10D1CA04BD -:1002D000D44BABC4F3B763FE543693D1FECC48F293 -:1002E0008B2ED4F3E632F21331D5A722AA88FD8BE8 -:1002F000C94ECEBA03EC27E8F7A395F353F15E7F1E -:1003000056F282D40227C637C15407405EB078F84F -:10031000BDEC173FFE8F722C9F4D7EE95BECFC9C81 -:10032000D9FDA3BF2F233A604A9A7D0C8EE7A577AB -:100330000522A922CDAF62D699E1A85FF53DEF1C59 -:1003400086FA590E9EF302488B74FAB8BA3232DC40 -:10035000E7EC865346417CFB254587C7C1C49333F0 -:10036000F03CC4B87FB13EE96D3A0F3FA99F9FE4CE -:100370006B935310CF0F0E34CEB54299E8B2AA4B0F -:10038000D05266E23CDF11199E9B9C91B594542893 -:100390003FC9F8FD0A7F8795CE8956DE5FD927CD04 -:1003A000D97BBCFE7F1471FBA636262EAA560AD92D -:1003B000F03CABF65F8C8B6A058B3BDE7998B1FE27 -:1003C000BA54894943211598E742F5B67D2DC68573 -:1003D000E3A622CB05EF6D6CD0D767DCCBA8C37B3F -:1003E00019F069E52B157DD805ECD0BA73E34CF70D -:1003F0001FD05EC3F5D59D9B40DF2BEF3B6143FCD7 -:10040000C67EF00904E35E466F704E29E2F6461D93 -:10041000DE67488FFEAEF0EF5DFD6750F9333ADCE2 -:100420009ED96799BC39CE3CF7E870199C2991BFD9 -:10043000604888699BE28C6BD433DE35E86D5EAD35 -:1004400013C37370DE18171C6FBC97F57AC67C5BFC -:10045000D3C28B3CFC9C7520BE5BD095972379372B -:1004600046F1D3B3BA7FA0F57BE13C7A27E33A6E3D -:10047000C7F6B6CF53FB7B93903F8C944277ECC981 -:1004800020B38BA11FADCFEC9005E5A44157BDED86 -:1004900077379C45D3FD979E70B65179D7BD33A66B -:1004A000B9842C94438CF481F57F2CB5D960FC631E -:1004B000161641BE5325E64E7A15F3603F205D1EA9 -:1004C00023D901E90691EE311D7BB2C08676D9A20F -:1004D0000A1611816F1D7B37AF11E32E95B9A04924 -:1004E0008E0375678DF9FCB186697B93A1DDFC03F2 -:1004F0009E9410E4173C609663C7DE7DD086F6803C -:1005000030CFE9C3B82298E7A45721BFB0CD46F752 -:10051000B2163D12DB9F590FCED2E56DAC3E7CB2D8 -:1005200048B73B46B29128675E6D68E3EFE6E8F7AF -:100530001041FFD3E2E189A1073F9938F1AF4504AB -:10054000AF1611F9D238297EFD5B8B39DDAD78EA23 -:10055000B4CDA5F44E67C7819F14C2F8271A644A28 -:100560005D83346110F49F37C86B1B04ED45259201 -:10057000F705F939F93928E01BE5EBF17E1ACADBFA -:100580006AAE27D8C5DB6A481FEDC7E400E92F3EF5 -:100590001FF9D32DA09FA462FCC6EDA28BFC0DFC1D -:1005A000DDA0317F59908AEBCDF8CDCC1710AE7815 -:1005B000C781E1FB2B155A19F2F775539D74DEBF05 -:1005C000C9E2A77E3050EB3E8067F09931BBD07D09 -:1005D0005ED8F2D044B4FBE4F69D21B4579A2C5F68 -:1005E000EEC5B884A6094C0D10B483344E7DFBD4FF -:1005F00017B07DDE34A78AF74AD7B9B53239AA7F5A -:1006000085453E463DF364AD85FCA6A7DA9EA0F382 -:100610002AB0EF22A87C9FAACD27BF9911F7436784 -:100620007F71FC862740BEB1A87BDCCB5B3759507D -:100630001F1F821B15155765CCABF6DE50D6CD2893 -:10064000777F2D911CCDF8AFEB287EC02D2902C2FB -:10065000F36641E6FAA8AE27CF62C69FE63DA89FA3 -:10066000CE433D19F0F0332148F19A16D6FE12B66A -:10067000AFCEE6FA20535A46A0FF3A5CABBF4BB46C -:10068000CC9A8AFA8D714ED01B3EF4E6E7819E1615 -:100690007D08E39E1418F99BEA2D913C9CDF716B59 -:1006A0007CF93A7D10C7BFBA81BE20C9F334263F1A -:1006B00085F32AF4BA912EEB2CCA0AF27BBDE7A18E -:1006C000F8904E414E33BDEF2237FF0EF5EE7A8B98 -:1006D000CCED9B035A199EC7744E2DA6F75E4E5A59 -:1006E000C379C44780EF615C56DDA017A649F8DEE8 -:1006F0004E5FD0BB20FFF3413B783E3FBCC802F9C0 -:100700005DBF7E7F9A0470AD1B1C3E8CF937077D60 -:10071000CAF3C3C28B707F8E0C8AF03C1A60806073 -:1007200067067D35CD0FEB3AAEFB3F991A9E83F3FA -:10073000AC7BF54A4BB47F313C88F3CDE309BCDE9A -:100740007137BBF546D43F8AC2741FC6A8B77B90E9 -:1007500011B7C9F17FC9B68410C6091BED5876FCE4 -:10076000FEEFD1DB2DD1DFC902FAFB2DD6DB9DAD2B -:10077000A4D13E1F051E85707965109DF7CC1B9492 -:10078000A6BF7314CE4B2BEE39DE5294F32807AC80 -:10079000E67B6FF70FE27C9B15F3FEEBFACAA9B874 -:1007A0001F5969DCCE800D49BD8FDE2FD8A4EB55D3 -:1007B0007C7F3244B92C2093DC198E76F3EEF3B9AA -:1007C00065643757C6C78B4775BC5812E0E344725F -:1007D000147933DD37671AC6A3EC6E4BA07518F594 -:1007E0008F0CE2FA4578502AC78BAE7DE823D038CB -:1007F000011D2EB900EF926EFC31DA5F6CDD5BFEFD -:100800004DEBEEB14FE57C7EC67A187B88EF2BCCA2 -:100810002F15F4FCE3ABF576A38D7928440F4BB686 -:10082000DDB581F33F258DEC76F6133E5F87316EA3 -:10083000319D4F2ED7F560D1FFB60DED8DE54D1DE5 -:10084000F4EEDAF216FECE5637DD692BA3E92CA3BF -:1008500080AF3343D43202448FB03EA2474D8F372E -:1008600030E34F17BC63E9B8477F4A9AB93F85FA2E -:10087000EB6D1F3EF8B6F721101F9E5DFC25067E2E -:100880005DF4E8D6DB15039E95F7A4C737BBF62FBA -:10089000868EDDFFE478FABD93E577E9F1AA8A193F -:1008A0008F97B7BA2DF38ABBEBDFDFF290273A9E22 -:1008B000D6DE3AD78FF2AFBEBD82E26A97BFBCF5F3 -:1008C000777E68BFF4F99FBA3098FA98D49C857AFD -:1008D00071ED536B5D1A9EB3487E17F2CD63417183 -:1008E00072BC7BABEA60415F1FD7C7EAF09FD0FFC5 -:1008F000F167FEDEF81F30FFBF0AA05F21BF6DFD6C -:100900005B23DA6F7B354704E5F651293C09E5E8BE -:1009100092B94EDF6A15E306CDFAD4D25FFD344BAF -:10092000A1E06E7F3F0BE953A17ED8AEEE49AB8AC2 -:10093000F67BDD7BA20AC3B07A1669C4F9C5B6AFEF -:100940006FF9CC867095411FCC1DD7B31C3809E1D7 -:100950007D7DEB7F7E29BA303DF6212BC5FEA2FCC2 -:100960001100F79A5EF432F760DD4FA9DF0B30E03B -:10097000C38299A4DF047EBDBEF41398D78927FFF4 -:10098000AF4B288E9697F712BC4EB5CCFFE5AB4A1D -:10099000EF72F524EA07F69E7A80D2267025BB9D79 -:1009A000A7B5D6900BFD02B59BACAA1F3ED76E7DB6 -:1009B000E2693C57611FD8553C7AACDD7ADA86EFA4 -:1009C0009ED50A5A44203D8BB98491DDFBB46CEB73 -:1009D0005FB8BF2A476453609F96FEF62CAFAFB155 -:1009E0004802D45FF6C227E4DFAAF53A7D8E38FBD1 -:1009F00054D9B2D31676C6D9A7964F26A11E14F89D -:100A0000F557B40FC77608AC8FBB67FB9A4D7FB123 -:100A100021DD9C800D494FE5F042FBB4BE459C6B47 -:100A20004B89B76FA1EB51FF8372F2835C6CFF843B -:100A3000C18CD3C5CB5B9F437BA0E643BB3A05C7C4 -:100A40007DEE761743FE2AF938BEFF626D9606E307 -:100A5000D658FD5932A5FC7BCDE377101E2E7EE7DC -:100A60008E2CD2EB989663194DEBCDC1752EDC38E8 -:100A70009DD6B98879090F6B7EC1FD196725363976 -:100A8000DE3DE32D8339DFB2B3DB4A913ECE424FE8 -:100A9000E8873962633C9EF75DFEFE989DDD981203 -:100AA000FDBEDCDD83391FF1B3E0C7F8EE643DD84D -:100AB000C5C817C477CE4EC27E56BA259F5DA6F52F -:100AC000FB757809DFF0780E4532E24EF361BFDE48 -:100AD000A9EA8376B09D9DB2DD528EE7BB4C41FF03 -:100AE0006F543B82DB91CDF64401ECFC2359F1EFCE -:100AF00011BEDF45F7EC5D16854FF55B8E103E317C -:100B0000B0BB52B279FE31A443B08B52006E67DEA7 -:100B1000FBCCD617FD1D19163600E7DBF117CA33DB -:100B20003553C1FA46FFF56D76D37B24F54FFE258C -:100B3000869EED31EF9CF8089EF52C45417DF388AB -:100B40002D32691B8E03E362BCE6A247ECA677C296 -:100B5000BAF1C5D6FDDDDD4D9F867DB558A7FFD81E -:100B6000F5C7F2832762F801DB987949EF3ED55A41 -:100B7000834F237C6A815EFD44AF9CFE40478F0C0F -:100B8000007AF8FCD9D7F6FF10FD742DD68C2934E5 -:100B90009A99CFD6BC08F48BFE348077828A7CF693 -:100BA0002B1BEABDD9956007C3BC3F77AA7829AD56 -:100BB00027DDC2F7B874EB6474AEF5FF8BBF2EEE81 -:100BC00085BFBE35D87CEFEA2C2B4EC13B0CC79FAE -:100BD000597605F91562E06BD8BBB17C73F160857D -:100BE000E01CCB37E1CF7E1605C7A5BFF982F0F632 -:100BF000AF39FC1CACEEC9BF91FC02B046EC80B72B -:100C000075C12F29BF16E517E5774EC3F3EA9EEBB2 -:100C100036C333B6FC219D1F75DD73BB97F931EEEA -:100C20002EB25DA4F7173A612E8DA89F3FEBA673F5 -:100C3000C2B5BABEDF29475CA89FAF4D35F2EC566E -:100C40007C07A6D35F2AFBB17D821E7FE089B85264 -:100C5000A3F4A44FDA4517EA75E1209B1CFF3DC0C1 -:100C600000CD23CC7A2B5FCDEF6B89E79F0BEB7622 -:100C7000BD1DC60BAFFEEA393C373F2439E8DC72B4 -:100C8000C1EA992EBAFFD75EF07F102F16BE017011 -:100C9000447AF26BB61C80F37C0E02303FFC741E6B -:100CA0002C2697EFDD06F5160180F19C24D69FB225 -:100CB00094795242EE9E7E1390833694FF8B411EB0 -:100CC00091DF7BA3B97C69FBE784674B63F0CC8B36 -:100CD0007896D313CFFA0ED1E9B68C95E9E7BA64CA -:100CE000CF77EE13E93CFF948391BE81E7BCB063FC -:100CF000EC54BB48FB73EA592148F186FE4CFE6E6A -:100D00002BE03BEA59061EC6DAF7B1E989973E1A8D -:100D100089F7C46A7FF7DFA53F87F4C4EF3E18B8B0 -:100D20000DF32FBF9FF7DFAC67FDCA1D7F233BA6E6 -:100D300073879DFCA19D3B5ECF43B9DCF9AA5D455D -:100D4000FCEDBCD7CEE31A7624D3FB659DFDB9DF5D -:100D50002EB0FDABD230C9AD357C1F87D868BF4FF0 -:100D6000B5FF9DE4C8A976BB82EBA8DF9144FEB134 -:100D7000FA571382E81FE8DCFED5C8E877AEFED547 -:100D8000F5D4E9F7693A935935C6CD74A6F238CB54 -:100D9000FA6D639E588DF648EB4E1BFAFF2BFFEB66 -:100DA0001FA5C8973A5FDC6943BE0576E9E30CF0FE -:100DB000C3F39B9FFED49A83F7C518D9DB277EB374 -:100DC0007F3ABE8BD5132E1C0E9D00075C17C0A565 -:100DD00006F5B2DEE0B1F83B0B8F2FC99EA86D1F60 -:100DE0004574D40D1741E3DF93830E01D7FF8A0BBF -:100DF000FD469DF920FF555CF757A5A83F5D6CDDCA -:100E00008DFF53D66D6197B5EEA786F0F7C8BF7B0F -:100E1000EBE6F83F64089757B174D013CF5FFE112B -:100E2000E59F4B5669BE9748FF7BBEB3EBBFE47DA1 -:100E30002F45BFEDE5EEFBA1EFECBA2FB6EF6FE863 -:100E4000FB9E2CE3FDBACEEDFFC8A3F55EE2BAC56A -:100E5000E2EF2A9D5F78DD5DFA91E871E0D35A0FE9 -:100E6000B0508702E9DA5EF414B5D86C8F88BABE48 -:100E7000B1960DD336A15D057A06DA016B3378BEE3 -:100E800009F40791EE0F52B00A6BCA55F97BB6927E -:100E90008FC990B7BE3F9FE259D6667D8FE597E335 -:100EA0007905F7630456ABDE9DD03E906A51022A65 -:100EB0003E53B5C2BB09CAE5BEA28CF6CD5AE54683 -:100EC00047F43B1692D366B2539C31F64662A1CDED -:100ED000649724B05D32FAE1135489E2FFEC2CAA46 -:100EE0003DD47715F373EB4416F4CBCECB87D32DDB -:100EF000C5BADFECF2E1E4A07B95B20E27A669B893 -:100F00006EBB22911E2631B01FF93AB8DD0970542C -:100F1000A2E0C8743B54D2412E29C3088E604028F9 -:100F20001347235C7D04C7408E28135CBBFBA3756D -:100F3000C7EEC35A6522CBD7F57141FDF6E13CBC43 -:100F400098FF1E432C9C8DB4C05BB11AF5DF95ABA6 -:100F5000F939D78BBFFF1EE55BADA00FC37CC6A7D9 -:100F6000781715A3DFD1A30948A72BA7F27705CBE4 -:100F7000F11E58069AFA3C0E37C391CB24F25782E1 -:100F80009D41FE4A99A1FD274E642DE40FF448319E -:100F900071BD32C53D056EE3714FAC8829FC9D16CD -:100FA00073FC8F7F222BC2B8862AB1B619E7758AE7 -:100FB000253763DCA5CD1ACA23FF707F9085E86FC3 -:100FC000A9F8EB462C77835ECFF03E9914FA18E32C -:100FD0001BEE145318C55545E05314DCAE3EE760D4 -:100FE00052149C2B58AA297FA2FFE156B413F2FD9C -:100FF000761983C72A1D39A6F62772CED17801BB90 -:101000004346FBA84A769BDA8BAE7D1FA35DF37641 -:101010009A85EC826BB30799DA5FFFE9898D737566 -:101020009CC575DCF011BFA70AF6D6E36F42BB770B -:101030001E610CFDC6D72965A6766DBA7F2552655F -:10104000A5F766BE5F34C6346E5B7817C1A53693CC -:1010500009781E5C6B0192807A3F502B4CF56E181C -:101060007D9DA9DFA9DA5453BE76D55F9994CED879 -:10107000B855E719BE1B58166A31B51FBEAFCD541F -:10108000DFF52698429096BDA704301D7590DF23AA -:101090001D0EFB81E71B6DE1792AC6EB94E005D0BC -:1010A000723C16F0546218F2C8A3BED730BD58FC8B -:1010B00032D3DF634DD4CF5FD759822D73DD18FF54 -:1010C000D3FCE04E81E221B7158F40377473650A77 -:1010D000541F7BAEE5354C5B3BC6378D2DA76B436C -:1010E0001D247F9D163A17A812DB4B05B27F92860E -:1010F000DBA3CE5D7A7BA7F3EEB28AB7900ED664FF -:101100006BCD3B91EF4FFC688E98DFB31E93A548E3 -:10111000349EDF5DE6F933C69D197152899522FF31 -:101120001D8A6B799C4CA3454DD09917E907F22491 -:101130002BC5F1CF2DE1726064C7E6166739DA9DE1 -:101140000E05F73531DD7CCF7BFE687E6FEF8B625D -:10115000DD3F2FC999B79460FB64DE1E7D7C38DECD -:10116000140BE9533BAF3A42767AE20D96FE2041EA -:10117000996BB46A41BB7BE4BE3FD17B04AD53F2B3 -:10118000D7EF82FAADFBFEC40428EFF340D95E2B03 -:10119000D2D9688B8CC7F5ADA3279E2EC4F229EF58 -:1011A000524CA3310FD739812951710F734B141A47 -:1011B000DF2585E91D22D73989CA5DB3554B1EF657 -:1011C000B7CF4ABF5BB3E22AAEEFAD1894B815F1C2 -:1011D000D47540E37150454E6500D143389BF88289 -:1011E00014CEBE2599C753291778CFFFF89611A9B9 -:1011F00028B7D22BD454F47BA66F15BBEE99E17CB3 -:101200001FC4BFF020DDBF76FF3550BE0563D57823 -:10121000790878105B67D3CB9105413E5DD0CBFD5B -:101220006B675CE3A477174DF587E677D5D71CD9B4 -:10123000DDFDF7D9BA76FF9A6284F7280BC69124B0 -:10124000FE5F2BBD2BB0629093F4871540BF4CE836 -:101250007D1DAE73491781A78BCA0F094ACC3BB9D4 -:10126000A112CCE7E57AF34A005FAF389F42F7FE60 -:10127000CF342590BCBBE2FC0DF42E67AB4DCBBB4D -:101280008BFC3509145F36F5B6CF37AC423ABEFE5B -:101290007811C62418EF54D6CB7F25FA37E2EABA84 -:1012A000E087F80A78FEA0A53B8FFCC0D50D4F0D56 -:1012B000DFE35A17055FFC6D97A93A3C676E5D3F07 -:1012C00003E1A32C989C8D74789A39298EEFB4FC95 -:1012D000F40C9CEFE92D560A9A6DD5F9A3BF487F0F -:1012E0007F20239C8DF7F04BDEB150FCD141C0072D -:1012F0000DF0A120F44E5A09B6CB90D2309EE1F405 -:10130000F8F7E99D84D3F7300A265E1AB611BC5A65 -:1013100033165456A07C3BA0A4A1BFC1806F8BDEC6 -:10132000CFBA326D6209C947FD7E8836F6B2DE9BC0 -:10133000DC79D557740EB0C60D7A7D2A86189F6B5E -:10134000C4F72457B8AD248756A4FE755206E27B35 -:10135000852382EF3ED4AF3A43F0856EDCD1F7BEF1 -:10136000A4732253A2E2B5FA0CE5FB2F491AEDBF94 -:1013700074CE46E5B5AB4E139F36DA9FD0CF53F10E -:101380001D46BC1F54FBB548F74481FF3509C330E7 -:10139000DD655B117D8ED3F265175F1F6AC1F79F14 -:1013A000DE4D44BFE454419E8EF3FB6DE99919185C -:1013B0001F3035419E8EF105FFABF4239EEF2F4F7A -:1013C000C77882755BAF9E89F1065373E49F5A40DC -:1013D0005E6D7B6ED64C2A77CB7FC2FC132577F2ED -:1013E000F264BEEF752537CDC4F8822A91D3C1A926 -:1013F000A6A4A0FD0274B078D53616FD6E6D8F726E -:10140000FD77A35835E7735FDCDF8FDEE964851D68 -:10141000141FB6BA44D0E3D08CF35426E3796A465D -:1014200001D3D0BF9CF17202FFFDA1431D7908BF1B -:10143000231B6FFF11FA4F970B8CDECBAF65CA48A9 -:10144000A4AB7996F0C798FE66B8B789E34707C59D -:10145000B72E5EB583E6F789AAC729CB9162CF3F45 -:10146000F52E04F41FF75D08735CF1A7166520F6EE -:101470002BE970992776CCB1F179FDBC04CF87D2E6 -:1014800076525CB324776479B9DE5444F6527622FE -:10149000BD0BDDD8F7C3D278BF77D0D200F21D489C -:1014A000EEC586364AEB87325A4F1F296C53A19FEF -:1014B000BA035CCE8CECF8D4161DBFF88A2EA75266 -:1014C000F4DFB58A8DBF7D459743C6F9F6F2BEA11C -:1014D0005CD4078D7DEDDE9750AEBE2F0CE79B915F -:1014E000FEDAB3F8BE09C6B5DE83E7172F2784D02E -:1014F0004FDD3B9E18FBC068BCD644CE37222F255B -:10150000909E14BB8E3F76C957BE9E233A9EF4B67A -:101510008E23B88ECC7FDF3A8E207FCFECB91E832E -:10152000BE8DEF067DF76CCFE77FF978C7EFB15D31 -:101530000CEF0CFE53C7BC45FC7E34E73706BC8D70 -:10154000791A706BED25FE565AF58A693D52C744EB -:10155000347298AD349FF3B796EB18EE87B4AA9D1A -:10156000EAF5B61E31F90C9DDB2C55980FF5DCD849 -:1015700075D5B2166AD7735D11E2C7CB15CE8F7BD6 -:10158000C6ED47883FD7813D86FAB7B1EE2E3E0DB6 -:10159000EB47FABE0A180EF14DBC3B28A03DE135E1 -:1015A000E9C315784322FA9CCA719B295F25DF6540 -:1015B000AA7F6DF66A53F975CAFDA6F2EF173D646E -:1015C000CAFF40FD598C3EBF29469FFFB5A97C7CD0 -:1015D000B883F4EDB71B26533CFA84A311D2BB4366 -:1015E0000D32E577356453BABB4121FADFDB504455 -:1015F000E9BE0695BEFFBE6134A56F3668947634A9 -:1016000078288DE51BE51DE172F4E78FCE48A1F344 -:10161000A707867AA795E2D1C27B9162C4BFB107C2 -:101620005A5E43515010FCF263AC775AB651FCE15C -:101630009A9D63FE703BE4D3DF1459827221BD484A -:10164000645A14FEB8A684199E77BB187F0F2BB678 -:10165000FEAC521E4756CDC2FCFD805574E2CDAAA9 -:101660001DF21E2D83C44604EDF46AE6233DD4B278 -:101670008ABF4B53CD54568EF6AB97F91EA0F82374 -:10168000F37B021E6DEADADF42F90CBC670AED7FDC -:10169000E86CA17BE42FEE4BBBA60CBECFF208F4A6 -:1016A0007B1E0776DC778783EC5DE3BEE98796CB0C -:1016B000D127669572FAEA14D40E9CAF3F95BF57B6 -:1016C00014DBAE545FE7F58108E91F11D03F30BE4F -:1016D000CCA0CBA9F2217DFD8A25650CD2C76ABAC0 -:1016E000CF50DBA1A80180F798439C2E46005DE017 -:1016F000BE8D3DCAE96024D001C941DD1E34E80039 -:10170000ECA7D7B0FDA9834C453BA271C27F8A6884 -:101710006F8D39130C607AF5F9C8CE6FA07C5C0729 -:10172000FF7DA48BD98F865EDADE504D78B4A3C1DD -:101730004B69A8A146C74F1FE57737ACA2FCDE0670 -:101740003FA5FB1A9A74FC6CA6F2371B3650FEEDCF -:1017500086A08EA75BE87B1F5D9EF94B653D2EA999 -:1017600042B72B78EAD1565BE95E3F7C427E528DD0 -:101770007345FCA81182C8BF1BD3FC56CC3726E2A8 -:101780001EE0ACFD54FF66270BA11CA8CDDEC6F5FC -:10179000B0183CA9C8B889F0649A1EB77A20ADF198 -:1017A0000E1BE0C3899687ADE6F7452F0F2F963ABB -:1017B000D7D03DBE58BEB804DF9F107BF243C6545D -:1017C000B5BC9CDFE7C2B8BC4BE5F7B2A543BF1F71 -:1017D000C6EFBBD4E53A29AEF6DF2767645DCEB02D -:1017E000B958BFCBDE4E3C3807DFC3EB0197187BFF -:1017F000FBCF57F2F686BD0D7A26F9A13A8322D99E -:101800005F35EE6617D9DBA3232EDCCF25DB4546FB -:10181000FAA2C4CF771763470AC6F184F68F23393B -:10182000B3722FF2A5A5FAF96EEC396D1D9EEF0A81 -:10183000F1E01DA638FA65FAF96EECBAEBC61FA105 -:10184000F3DDBA8BDC23FD53A9391E23F6BE6E6F80 -:10185000F882F103D1EFB79E3CDF4076DAC7A57777 -:10186000AEF78FFFF7EDDFC232CFE7A53C6E9AEE01 -:10187000C919FBD9A8FFFE66E34407DD5BE81C211C -:10188000D37B379D027F6FA7F36F4C5DADE07B3A52 -:10189000F26E940B57AB36E2ABA3C3FC7D80F178BC -:1018A0000F31CEFB00571D0A0692B1DD413FF99F73 -:1018B000C6BCE70DE03DDB516F6A229257D96E8FAF -:1018C000887860C827435E75D3957E4F0E63300AD3 -:1018D0002E9DFE9405A3B351BFEBB25B9D93E85DD3 -:1018E000A2D32146D1A3861F6CF8414DC47B0823A7 -:1018F0000E7903286F1B753B73D409BF9802DFAFC5 -:101900003AE3233B680CD8A9F8FB31786F5A8B82F5 -:10191000AFE1C732F89CC1D78C7B7AB2CDBB05FD55 -:10192000CDECD5047AEF2576DE7943B95F68717F17 -:101930004FDE50E47BFABDBC2AF1FCCE6FD02EE81E -:10194000E0F101579CEF7C1AED9E952F25D1BDB497 -:101950008BDA07F2E9B8FAA991D65BF8B9C9B04AAF -:101960006538DA9BA8B7A21D6AD8A5B1F50BCB26BE -:10197000960DCDC4798DEFD010BF65CB05F1BB7E40 -:10198000D59717B40B8DF1EBB78F90E7459D1FD41A -:101990000F35CE57FEB977A7AF8A549BE4D8775D51 -:1019A000EF033A2C47FC429B15E5D40F7107601DED -:1019B00037B310E92BB7E8BF5B712BA8E0D1F76212 -:1019C000E7338DF8C31ED5BB08F765218BCCC17CEE -:1019D000BD10A9DD0620FC62C238D9ADF494D797BA -:1019E0002B9F13F57BAFB170BF6B28D7670CFEDF61 -:1019F000EBFEC4F0FFCE3299EE3D77BE34CE82E7E7 -:101A0000369D6F89F45EEA3A0BE72BFE6136F529C5 -:101A100015DF1F997D8DE10FC0F8B258BEB2C5A287 -:101A2000FEE17628F7BF9DCEE2D195915E8FFA2830 -:101A3000E061CAECB094EFA4F7D3D721BCBADEEFD3 -:101A400040BE7205C0FF137E3EC79608E4F76C6B7C -:101A5000E5F99285A934BF4BDD0FE839A914D6B159 -:101A6000B0551A86743A342D928FF45532E6833489 -:101A7000C189BFC3CAEF4501F89A585AF73CDFD273 -:101A8000E1F997A1DAE338BFA1691DEB1E463DF1EC -:101A9000250B43FFDF9131772D6251F2F56B75E233 -:101AA00013C82F9E17F4F7E5B6F3DF21801659D13E -:101AB0007EAA3D6AE5AFB15E0BEA5748579E57E8EC -:101AC000FEFD5499C3925D93A9FFFE63242FDEEFC0 -:101AD0000119E75043513E703F22BD07F6BCEE6747 -:101AE000DC39F4C3996B90918722F9388F2309FC74 -:101AF000FEF3D7AAF7555A07FA6B711DBFE076FEC1 -:101B000091541FDDFFF800F82C9EFBFE778383D2F3 -:101B10008FC0CEC1F4CF60E760FA09D839987E064D -:101B2000760EA60BCF41A7B08F15AAF6C6D00BAC88 -:101B3000A3773EC1D7D1D9CBEF2AEDD2E15FDA7AD4 -:101B4000E8DE24C4833691E29A4B5E9248CF3CD9BA -:101B50003ECAF43BA24077FB711EA56D7FFC09DEF7 -:101B60008F2E6D956441C1FBD4A7B3286E30667E7D -:101B700008073C27886CB7F1DF3FD2E7FB7C6AC7D8 -:101B80003A6CFFFC4BF938433C7FE178B8DD1EF737 -:101B9000F7818D38B99FE972FB067BA43CFADC30F3 -:101BA00036AE8CFCB963109F0BFF80E3F8F7896CAD -:101BB00000E1A5D94F91AC723964A425DB6D145FA7 -:101BC000FCFCF6FD377E1FFABB7EEC75A67775FF31 -:101BD000819B9B8978FDB7C71ECEA0FA320E358B4C -:101BE0006DAA92A1DECD8E9D7B70E9B7C89F54A5EA -:101BF00042FED66C612FA67315F7A43405E71BA42B -:101C000071E61755EC45D49AA24EB5F1771C453CC8 -:101C10006BECE28F958E247A0CFAFF01C9CDB6AA3F -:101C200000800000000000001F8B08000000000082 -:101C3000000BED7D7B7C54D5B5F09A39F34A329395 -:101C40004CC2041220709200060830249390902019 -:101C50002721D088944E225A54D4915A44E53122F7 -:101C6000AD694B9B13122084A04191624518285AFC -:101C7000EDF5ABA9052FF6AA77824AD55A1B149F1A -:101C8000A576A4D66AAB9282D87A6BCB5D6BED73E6 -:101C900032732693F010BE8F3FBEF0D39D7DF63E8B -:101CA000FBB1DE8F7D7600004EE27F33DD83001CCA -:101CB000C03F54FF4AD630808268FD1239DFD07EA3 -:101CC00069C178433B4008A004608EB7D8D06F52FA -:101CD000464F5ED00930E1A9CFEEA8F4E0031384AB -:101CE00047633961EFA76FDF82E5DCA957FA241952 -:101CF000E043E8B862BC09E083B2F55BEEA6972D3D -:101D00008A2D7B30C08DF43BB67F04E1D72BB05DCC -:101D100072AD3C701BBE77739604921760F136EB80 -:101D20009148CC3A96813F2D8CFD6EDE6D7C0E1075 -:101D3000B1857D00B7049CC13637C09247B0DD61E4 -:101D400068E77197EEB3B9A97D1958A2EDB9000DF6 -:101D500087731F7D3666BC4919DD77DD8DE34D7ACB -:101D60007C9EBB19D7F768F9E74365DC67A1D7E527 -:101D7000793F053B4C812927252C25A719B0DF8900 -:101D8000E7A59084EB9A297D911A29C4E73599003B -:101D9000D9F89E49FE6D05B6AB2F48F0008EF3F7DB -:101DA00046F9D167AD343E5CE7C77E27E9673ACD97 -:101DB000BA9AE1AB976F35E2AF1701FCAED1C1E53E -:101DC000EF1BDD5CFEA1318BCB771B652EFFD85856 -:101DD000C0E5DC5720D089E3FDE91F930106D13827 -:101DE0002A4066B49C64F39A87E23A7A7E23857629 -:101DF000E17E8F574E49035AE717387FA98607249B -:101E0000813ADC0394E37F37EC7C2EDBC7CF551798 -:101E10004EB5EC1F122838EE0D5E9358E792AEE7F0 -:101E2000B23DD17658F9AEA13FAC321D30D45B72D1 -:101E30008DF5F6AA03B1EFEB70882F6FDC76AB2D32 -:101E4000E0C272B3490939FBB6EBEB99B93F4931AE -:101E5000E1789627ED213BEE6F995B0105FB5B0076 -:101E600094CEC2BEEF0134F17B574A10EC4C30EEF9 -:101E7000721A17E136677F12486731EE5B481BB470 -:101E80001EF53FEDA107F0BDB7D214F0C7CCF35D4E -:101E90006DDD1FA7777CFF33ECF7F113404FB00ED9 -:101EA000F3693D13F7FCD96CC67252B2A09389EE68 -:101EB000883903CBA38BFFB9E5750F93A9DF743184 -:101EC000B6E7F5BCEE4094AFEE9CB9D581787BDBEC -:101ED0006C06180A02F165D81FC7A0FA06EFCCF904 -:101EE0002DF8FBA5FB93C2E6B3D8CF06E4452A271D -:101EF000550B7EBF96E846CCA300F2C3F235A0CFC7 -:101F0000AB907CA0FD53FD99CEDA3737D31AA0678A -:101F10000BC9878F00C26DBC7E253596FF973FF5B4 -:101F20002DE6CF25D9C8F748EAB04DF0AF03FF9DA5 -:101F3000CC237E0DCD72E27A6F0A23FFC3F9E7FF4F -:101F400087BDCE289F5F9490CF5FB914EBCB9F9055 -:101F5000BC766C3EF6E468C14F1ADFEB7CDE4B4F7B -:101F60005B25E64BBDFEC993526D2801BC376974F1 -:101F700091AFF4D4D37C2B9EB2401BAE6FC5B48B13 -:101F800086C48EDF875E5B259063C67FF469FB6243 -:101F9000E217197A06D721FF4C7AEA444655A12860 -:101FA0009B681CE8D0E44DCF08FF0494D726FFEFD0 -:101FB000BF87F301E2F101844F75D6FC1C9ABFDEA6 -:101FC000094ADB6406CB3C07CA89CB0488E0B2B27D -:101FD000AB7300E1B90DD12521DDCD53EA5EBB1A0B -:101FE000F178B939F05592F36F79F379FC2B5C2BCA -:101FF000AD606672CD31E178F3E7D98B693F739BB1 -:10200000055DBF96DEF3113D7F6D5A8AA919DF7B0E -:10201000CD042D9011DDC76B567F4E90E9A7C6FD0C -:102020003EE2C7A48C934EA6F42F2F8892DFD7F1FF -:102030002845E5DF4CC9A9D23CC7DC66A67B4B76B8 -:10204000BB8DD67513840E2838EF326FD846F2EF69 -:1020500016705BA8C4A2A7973E88FE2AFFD9751206 -:10206000DF5FD62D854CD8BFB3B1132C88DFC71ADC -:10207000F77139F28B912DC3101E2B27DBBC6DA499 -:10208000B734FA32AB263899405FF5A54F4BB41DF3 -:10209000D75DE57086A5547A6CFD28761D3FC85142 -:1020A000FEE945B8AAEB2AD3DF4715CDB43032BAE2 -:1020B000CF49360027C9F9075258CE7FF874A9993D -:1020C000F0F4E18BD69089EADB2F7AE3361FD781D3 -:1020D000E4CD87195EB38DDA33F2422AB6DF6806A3 -:1020E00095E432EC1272EB9969B7BF43726CE50369 -:1020F0002E93DD24E858461340FAC9C677EEC57121 -:102100006E4266B57BA37A63C9F49F6C7904E9607B -:1021100089B9E38E4A7C7602C213DD08CFBF9A3AB2 -:10212000C790DEFEF3FDF6B099DEFBF1D85D128EAE -:10213000FF5C6A207B32E9A92C65482E3E5FFC4A91 -:1021400026B4E1FB337EF2AF97496FDEF46826F3E5 -:10215000974EF733890F713D47910F693DC79ECC6C -:1021600067BE8BE25FC06129CA034038AEDFBDC9DC -:102170004FF8BC2159667AB440501946F8DE773DD5 -:102180000490AE8A24934274DEB31EE165EA4B4F9D -:10219000DEC9667E6F8919F52BD161402E26781C29 -:1021A00035C9451A5F00ADE7C8D36377B5E1FBB524 -:1021B0005AFF28DD1D5EF65F4477DBEC5E3B2EE1C7 -:1021C000A324A3DED7CBCAC9E9DCFF46C7A7602991 -:1021D0008E3E5FD6F0B9B15E080AC98DA266B9F825 -:1021E000562C6FD3E03E63AC7F3AC1F1E6CE4D8F03 -:1021F000BF24D3BCDBBEFD36CDFBBC93E785970483 -:10220000FC8E9A847EE9D5AF8EBFF1F8003B797ED3 -:10221000FDF99FEF7F636200C7FFF3DEF16300E922 -:102220006EA1D4FDFE7D88AF4F5CDDEF7C0FCBC788 -:102230009E7F6530C12F7EBD4B1A8E8325460E7D55 -:102240006432F17E97D03EF0F97F14FB2F9F5CC281 -:102250006CAA10DC16B64DD845F260A654984676A6 -:10226000D3D10F8DEB8B5FA73EBEBE3E7D7CBDDF25 -:1022700042823FEE63F22437971FDBBA3F21FC7E98 -:10228000FCF87813B262F47946F7C4F4C2289EFCD5 -:102290004A9395FA5D41A21E5131DF21F03A7FB198 -:1022A00029D49CCBFDB8FD6A7C4E78AFF234737DA7 -:1022B0009E13F519F65F92F55FBC2E12740ED46B67 -:1022C0009783FE53B7E617D8EFCD15A92C17E6DF95 -:1022D000D861253BB7579EA96F9B4F8E3F73798678 -:1022E000D093DD83817998F427E0E62C589FA6D51A -:1022F0004D65BF6BFE05C9E7DB52BD129A8CB05825 -:102300008630F1F5310811BCD79A826CEF39480F4D -:1023100060D966F26659B094CC3D8380E70909BB69 -:102320000A0216AAFFCA1469067C6F8DA73A8BE8C9 -:10233000FF4D70FAC92EBA3C7DED0492A3D5EE395B -:10234000F3E979BD9AEA6EC3FDB658E50D8564FFE1 -:102350005C2E79C9EED5E1A2EB8FF916AF95E03B83 -:1023600038287B55A4DFE297148789E1EF5069DCB8 -:10237000372CC14C5AD75BCECD134C66B2D342AE8C -:1023800009B8D9B75FF969C96FF0FDDF81328DEC0B -:102390008179BF72B01CBF1E64E6F76F80C272FC09 -:1023A0009B10E0FA8D10B17E8AEFFDA1FC7F1ED854 -:1023B0000FD17DFD61EA677BC9AE9F2F7566E6622E -:1023C000BB5A0D05A4677EE9F8C18E08AE4369B615 -:1023D0004012DA57BF243A25FBFDB02BF400F6BBC0 -:1023E0003D797B6A17D62326617FA9D5C147A9BF4E -:1023F0006A067F3396D9C9815F101FFE30458CD3A2 -:102400006071B8493E928145E3BCFF8E8BE99DF433 -:10241000EEF558AF406C11BC8E660A7A53FF062C5D -:10242000778F5ABDDD0A8D7B42F63E40AFCE30F34A -:10243000FB7052E67554C4E917DF7833BF0FFF9481 -:10244000F9FD693D16837EF14D32071FC3FD4DFF37 -:10245000876540BD737991905FBE41E660227BF055 -:102460002F1A7F2184245A4FF33E53A88D8950D8C8 -:1024700007153A3D42642DD15B254090E81EF6A138 -:102480001ED3E7C9E3FD7FA2FA880EB19DEDC1CE50 -:1024900067484EDA83824FB03E83F6E3088297ECBA -:1024A0003554C860C17A12BE28E4AE1BC88E6DAB2D -:1024B000824EAA4F838844F89E4E9046FC5781CCAA -:1024C000743B0314AEEB74FC1550B9BC04425C5E63 -:1024D0000A61A1EF416EF939CEFFD50F40EC675C80 -:1024E00098E91D1D1937DB8197DC6826BBC3F7F51A -:1024F000C4FE426A910E174488E7F4E1320B025998 -:10250000627E010F3B3DF745E1E188834712C1C37D -:102510001B8507CE21E0D107BE023ED314840FCA2B -:10252000A78BA147A27914CDBEA9062F9735E0E766 -:102530007200B83CDBE4E90B97B248C012284C00AB -:102540009F1989E966884657BF2E022E75F933BB5D -:102550004866B8E97208F9338BECD178F9A43FF7F3 -:10256000A5541F97911E7C45E9575A509FF98AAB95 -:102570006FCBC7FA8CC76451AFA8FE451ED667164D -:10258000E589FAA4EA622BC2ABC9947F650DCA99AA -:10259000FC80690BF1E5CA26B4AB715F81A43B8274 -:1025A00044C7A60C709BB07FA0A9C45B84F500D281 -:1025B0002520DCEC526E13C1D9FE3DF036E32A52E1 -:1025C000D302138B70FD850BBAD70A7C560F998FF7 -:1025D000FD3FEAB6B2DDB2CE160C129E90DDDD4DA7 -:1025E000E5D1FD7DF4D8F716D3F3C786829BF40BB3 -:1025F00078E462BFABEF7ACC0EE0FA52941B14FF82 -:10260000C0F92A69BE00AA2799D6F5732944F05F5C -:10261000D93493FD81DF16F8A717C58E8FFB90265E -:10262000D3BC42CF8127B798E03679AC7F368D7323 -:10263000D485F2358DDA051EFA2B571629B5346E7E -:10264000FC7373CA17D72EC37996238D909CBEA6B0 -:1026500028F0351A77B93932A2189FAD4E79C7C61E -:1026600074A1207D927C207EA5FD2E467A24BADEC0 -:102670002FF81539C0DD6BBF227E3DFE9E6B17F92A -:10268000848893F07FA5F383CFA0594DE35FCDE31A -:102690004B3D8B882E3F497FD5F627E6CBE182EE76 -:1026A00034B9B5FCE9CF997F9E324350D2FC6388A0 -:1026B000E1BBE54F2759C83F5CFE1708A5E0FB15B5 -:1026C0004F3EDC4CFE4E39FAFFE4272FDDF373E674 -:1026D000B727495F22E896FFF753CFDC477C7A693A -:1026E00012C7A1A6BD7A389FECA0E98723CD883612 -:1026F00038FAD41BC304FDEB7EC9DF4D67A3C7675F -:102700004AABEE207CAF40FCDB71BE15A6A0A85BF7 -:102710001D6E95E59EF093176BFBF818BAB72C6009 -:10272000B9A21E28A7FD6449C0F23124FC0919FF93 -:1027300011FFDF7238B496D609D21736923727D0F8 -:102740002FA67DDDF250BCDFD173A09CFC6EF28B16 -:10275000719F4B3B8DEDCB63F543023FF98E222DEC -:102760001E960339B4AF5FA23FF4C7D134EF823471 -:10277000B20FA7525C2181BCD4FDE3DDC9D55B8AD1 -:10278000D85EEE94881F2A2C89FB5F57A8C5793440 -:10279000FB7FC5FD12FB712BEE1F348EFD648D5F38 -:1027A00021EC65FE7D94F40AD199FC021A19643F6C -:1027B0008A35C3B6414C7337B59AD88FB14BB77AC7 -:1027C00049EF4F7A70C8CDDF65BA49754316D5A772 -:1027D000CC7FC8C3F655908435FA556C673E9ADEB7 -:1027E0009347F33F9A2E838AF33527F5E4919C555E -:1027F0009F727849EFC6AFFB454DEEE587276F8D99 -:1028000078049E89CF739F2FDF4A783E867C4EF8EE -:102810005BE11A33049C64375C9C15C1B259B3D395 -:10282000731F1A97568F70F1D17A63ECEAAE835713 -:10283000A490BDBCD7E24F7163BF6387F20C7E509A -:102840007C591246E4140FD0FEC69CFC4002B8EB43 -:10285000A56FAB85E1A5D3ED2F1B15F8A395F0511E -:1028600029F6A1DADD761FD15F6806F9932BBE0940 -:10287000EE36ECBDE2851F373BA8BE1E989A8FD17D -:10288000FFA8FF07E610D9E33F4C99786725D6F7F4 -:102890007C68117E8AAABC521863C7DAB3CC201BAD -:1028A000E8B55B5A4AF298E81EE935494E06398682 -:1028B0001E530A320C759777A8E1FDB4B23C437BF6 -:1028C000BA32CED05E0A0D9100AEA7244B7287704B -:1028D000C5836A8B0CED76A4EB30ADF3536147955D -:1028E000E13FA16F836C0F5544007E847430F52363 -:1028F000A39D5516E9607F33E990C51007B09F226C -:102900000EF53F3A7F0D87E1C45F48FF5E9263C7D3 -:102910000E89B893ACC173458ED0CF2B5E90D80E84 -:102920005CF1A199F5C431F0F6E287E4A3CE77F12A -:1029300070CFF41BE13C64BE11AED901235C872D3E -:1029400036C235276884EBC806235C7355231CF315 -:102950005BA71AFA8FEEA836D42FDA3ADBD07F6C59 -:10296000A8DE501FFFD05586FE133A171ADA27ED5E -:10297000BBD9D01E4F5793C32B0CEDF6D4D799AECD -:102980000E205D99501F143FFFDD38BAB030DC4B8C -:10299000863BBDA118FCABF88FF05FA1E525A680B2 -:1029A000DA4CFC78AEF03FB518F13F3E8A7F5DAE61 -:1029B000F6C7A73A7E0769FA1AF93342783F569666 -:1029C000C2F4F2F2F3C70E2940F84F8522DCEFDCA7 -:1029D000E9228E22C9C156A2936E707590FDB9CEC0 -:1029E0001264FF4545B3F00152CA71FEE6D7CAD062 -:1029F000DF8C59679D92049698FD4E0E771AEAC5B2 -:102A0000CFEF33F42FE90E1BEA930F8144FAAAE8C3 -:102A10004DEF335496BCA770F8ABF483E033549673 -:102A20007F1ABC9DF46FBC9F7B99DA24A5E1A2A616 -:102A3000FEA3F319346BD03F1BA192DF1BB935D530 -:102A40006B1A8AF0487EA799FC6F403BDA8ACA0865 -:102A5000BA7F43C884050EF1FEDF932E5E43FD4D21 -:102A6000E89F13DE112E0564EF3540B297E0427601 -:102A70000BF961305BD8F36B4D2ADBA349688F9269 -:102A80003DD25CE5677B79160487D3F32B4059432D -:102A90007C2799D17EC5E7C72F0AAC2C2E118B2538 -:102AA000FAB9FDB8CCFEF774F2A719980A90DE3B8C -:102AB0004ABFD3FA207CA5427110D265B8FECD6D15 -:102AC0004F5EA952DCC903EE08AE3B204006EDC5BF -:102AD000811F14A31C3E6272AF2DC6775F9EFAD78A -:102AE00011648F34150BBBCF2E21A49006862C5079 -:102AF000809EFF2047595D9C198DB3F4473F7A3C77 -:102B0000538F6FEE690C7369717B25A2BBF8B863B4 -:102B1000C4ECAE994CFA6F8589FDCEBFD2E2CA797A -:102B20009E5496F30EE8B6A7F392D9FFBF46C39B17 -:102B3000D9D1BDE67BF8DEB541616F2D3479D95F1F -:102B4000BF25EB238EA3D82513F8C81F4A2BDC25FD -:102B5000E22F7ABC6498742676D6A9F67B4BD6878A -:102B60008678153C3228617C3D3ABECAF08DD9E7A3 -:102B7000F6AD1EA1D7C8CF3FB23EA71A5213CDF370 -:102B800009C7AFAE091E34F0C5750D6F19F8E07AAC -:102B9000F55D437BC4D363A57865E4F1EC59145F1C -:102BA000FF78AFBD94F080F87FBA38265E17593FA2 -:102BB000BE06269ECE7EFFCAEB38DCD8CD78D5F790 -:102BC000FB4EE39B5C8F3446B88CDFAF1E1FD14BAE -:102BD0001487AD64CFDC2EA1BC207F97E485274607 -:102BE0005E001490FD7FBB34CE4BF46EDB1FFC09FE -:102BF000B5F734D9DDBB7C1C1FE1B84903D205D938 -:102C00000DE014EF2FB439D80EBDDE27FCE9C35513 -:102C10009F5D4BF66B2EA47A5106127FFC9EE22636 -:102C20000B4C69ACFFD7661FE0FA7BEB41E48D16D5 -:102C300087EF277F75796AAAB08B15EC8FF5A319FA -:102C400066AEFFFAA2C0FBCC8F8561CE6F2C1F222F -:102C5000E279E0898C203EBC4DF67F58CC7EBC3BAF -:102C600040ED8B33D0DF46FAFDC0AC4E34E1FBA320 -:102C7000F7645C6541BC7F90AC7E42164D8E2FF5AB -:102C80002AF2333FB009FE9DB0E7EFCCAFEF9924B5 -:102C9000F6CFD5274C1CAF0167C456877ED8E69186 -:102CA0008113347F8715ED49A7785E3F211A973D40 -:102CB0006AC592F83F49945F148B3CE4BF8A85FD56 -:102CC000AB97430866F87C8256CE94DAC750FCED89 -:102CD000D8363B90DCC2F915F2B7D4A7441C7F70FC -:102CE000867F0908BCB8D7E17A3DF9F271E23F8FDF -:102CF000847E2DEEC3EDCBE571F5782E39B0A9D8E1 -:102D00007EE471FB4EC25FEF7A0F8978D8C7EBC7BC -:102D100073BC5BA713B7862FB80140B40FDB49ED36 -:102D20004B5F38F20EC5E7FEA338E0F1E1F80BCDBA -:102D30007229C9C9A5A95D1CA71BE393F93D5C2FA6 -:102D4000EF17E5560BFAE2B0D411E1B8DEA9E2F7CD -:102D5000FDEDFFE36F766F29E478B53C91E48A3EA0 -:102D60002FAE638C2F26CEAEAF233ACEC0FCA3C7C6 -:102D7000A1F5FA9FEF5F3746CB235CE74FA097A7FB -:102D8000E9746C4D1CF79FEF13F88DC74FD145C107 -:102D900010C7F3DCE06EC6FA6C0D4E1F5F89FBE1D5 -:102DA00078883299F0BBB4DEE92538EBE30FCE80AA -:102DB000C0CF079867C6587F0DEDFFE6A0C813E89F -:102DC000ED487F22CEB93E85E975E9D36FBDF33D6D -:102DD0009CE5A69F4C2826FDA1BF1F0F6784EF1816 -:102DE0005ACF4249E4CF10BE75347E7C7EE06CE160 -:102DF0007A34A79BF5C2D19DDF09D1FA8E6683DBB9 -:102E000084FCB8F4C95FBD699A4874E20C4B58C29F -:102E10001E63FC2B5E4FB9217035C9113BCA11B23C -:102E20006FECFA7BC32D86F766672937FA585F2B5C -:102E30001B481ED955E1AFE507AAB8BED22AFCB59A -:102E40003DDD6699F87B8F0542A4C7571ECC50C95B -:102E50007E5C8976077B3A05415E2F24A31F949EF2 -:102E6000C06E307965AA57A6056E277849DF98713C -:102E7000DF23B9517F54D797259ABE570AAF6BA667 -:102E8000F17D5A3C10ED4C8E77964340B323B43815 -:102E9000DCFA031C87D0E5B60DE63B28FEB32E73A3 -:102EA000A183FC431987E5F89AA73E0D06B023D706 -:102EB00034A2A4BD285AB7F6E3C7EBE703788D83A5 -:102EC00069BB40C21ADABF7A20D24276CADC177BCD -:102ED0009EC5B26DC28391D5D4F6C54989EC4887A9 -:102EE0006607703198D629DEB30D5F7BAB09F567B5 -:102EF000B2D7024762F4A00339FF4881362FD903C5 -:102F000059BDEDBF25BCF5B78FF3556E40F81C19C0 -:102F10003D40BBCDBB3811BFC7C32B49C36F52E186 -:102F2000AC0FC9E04D82987DB3DD135397A2F02218 -:102F3000D54DF8B746DB959309F297675A12DE8FA5 -:102F40005863EBE183EF19EC8110AFDF6AF183176F -:102F5000F767F360BBE11C86AAC5C191804B357A47 -:102F6000603638F5BEC82EFFBFB52F1AD73FF8829E -:102F70005E9F7A81AF2F7C81E317EA2E6CF829756A -:102F80001736FCD40B7C7DE10B1CBF507F61AF4F2B -:102F9000A9BFB0F1AB5EE0EB0B5FE0F885CB2E6C28 -:102FA000F829975DD8F0532FF0F5852F6CFCAA6CAB -:102FB000073A2B81CFCDA6B7984374CE46AA0973A2 -:102FC000DE384F058E47A7AE07CE57ECF20A3F4AD0 -:102FD0008FD38FA52164F45BACEE6CF2AB77B5DCDC -:102FE000557D038E73220B174FF9FC9CD7151A677A -:102FF000E74CE0FC85B3E5FDC314FFCA85B0379C00 -:103000004B713509C23176E935C11408C7F813751B -:10301000CA2043BDA47BA8A1FF8D5BF30DEDDFECBF -:10302000186F68FF466BB1A17EBD5A61E86F87DCFF -:10303000B602CABBB658BC9407B3D0DECAFBC20DF9 -:1030400076DBF83D05FF911F938B9E50EFB8B88F4C -:1030500074D56618D719D77EAA7C407C3EA1A654A9 -:10306000CB27F47EBF20DE07B72761DC53CF27E8EC -:10307000F81C6349627C6D5245BE69DD4CE147CE68 -:1030800068719B286FA9E36F3CE83F6E33F99B0F93 -:10309000350A7F5287437A48AD667F74B7A08FB1F7 -:1030A00035E6109DC39D293993699C1092B41BDBB2 -:1030B0004335F59CD7D4E9607CCDA239145F6DCA45 -:1030C000199C4DF184DC1A81F7E5FB8CF8A6B42D30 -:1030D0006D29FD90C4EB4C6FCA28A2BC5D1FF83F60 -:1030E00022E0A99F334F8F83EFD89011FEF1F8397A -:1030F00053F8AFFC92F0B7D5CA5D69140F5541A6DD -:10310000F8CB733963CC0C87562FE3A116BB113C67 -:10311000735B81F33AF174D7DE08E19A183ECDF57E -:10312000861582EF4CA9B09AF909DF1D027C1A942A -:10313000F3EC3B5B459E16CB641A1FF6C943099F0F -:1031400021B59ED7BD6BBD2D99CEED7DD664063AD7 -:1031500017BF2B571E4AF9AF5D4F98E6C79E034233 -:10316000ECDBCD59BC0FBBB98C4B8B2815AD048B58 -:10317000680F4B541FB1CA1C874F55A2F6F4DAE40E -:10318000B8E78A89FA6F28CD63BF344DC930E0CBE8 -:103190005A66E46B04E32B85280747D2EF32D195BA -:1031A000A093D06B526835C7517A4C8B896EB4733B -:1031B00015E96BEA81F24E4D39DF9ECF72AAC9C67E -:1031C000708755822EF4FC9FB555D0613CFDB8BC8C -:1031D00046FAB14AC34D228F25F8445FC74E459B3E -:1031E000375B0295E59B6D28F181356E3C3B0949C3 -:1031F000922B1EC17F4EA8077ACF5966E77C3548CF -:103200008719FFD629008362CE23C4AFF794EBFC65 -:1032100092747EF01CC9999D35E2BCEABA35E27C15 -:10322000E389E7859E98D1EA36B3BC0199E50BD2D4 -:10323000C1DCEC52717E88E0D9AEC91B3BD4A551EC -:10324000BB4EE7B3A4E155B1748E72E44517C9B320 -:10325000172C1CCF5C6795AB6FA0F672BB7B35C398 -:10326000B3B088D6ED6B41B943F1C26E01275D5E04 -:10327000C4C3AD0862EAB9443A89E1D89F3EE893F5 -:10328000FFD7E1588A70CC3F7338DABC42DFA6978B -:10329000097DFB5CCEB7F955F721717E265D0106ED -:1032A000DA7155C07596F45198E4CB2605E50BB656 -:1032B000D76AEDEE32214F7438E78925F6CA934D6F -:1032C0000B2083F8DE4D7076125CDF67FDDC512247 -:1032D000E00C10E13C67AA22F8649D15BC148FED48 -:1032E00028777A292E98A768F06DD5E065025322D9 -:1032F000F8CA71F04D8DAB9F297CC74CD1E03B18CB -:103300004ACF06BE9B525205BF8D12F0B13A237CC4 -:103310007EB935D7E25D8D74D8958BF0C6F6D6D7D9 -:1033200004BC7FA8F55F3301B8DE9AB9368BE1950E -:10333000BB288BE478ABB543A57C552BD11F9FF3FD -:1033400014E7BF5C1A5DCF44FE5E88EFAF45F944D9 -:10335000F9C6D4B28083C66B2DB480C4FBDFE64DC2 -:10336000B47F87CF669083C3161BE19A1207C7A468 -:103370002FC9FF7553BE1CFFDF49BF62BF75A39104 -:10338000E538DF1872109C6C657F71101DB595EDE6 -:10339000E2BA0CA1D63CDCFF1D4E6167B595D50F96 -:1033A000780E6A972617428D0E2EB737BA51330121 -:1033B000DCD598C5F58E4699CBF6C6022EDB1ABD34 -:1033C0005CB6369671B9A651E1FE527951157F0F60 -:1033D00036876915DC8E4FC061EE3B5F7EAB518F47 -:1033E000E5AAC906B88F6C30EAAB41B5467D95AE0B -:1033F000E419DA5DDE7186F694822243BD704AA03C -:10340000794A099D8B9A6A78CFE6A936F4D3CFD151 -:10341000B59589EFA174B8E97AC9A9F1F73A6B2497 -:103420008BE2D8CE32C19FEB35F8B56AF04B5680AF -:10343000CFC5D80E49DE1010DFAF65FABE03713874 -:1034400004E1D295738542F6419B2CEC742B887372 -:10345000BDB62CBFFA0D7C9E847A8BF2B6B6F929E4 -:103460002C0FEEF038BD748EB6AD6C859BD7E3158E -:10347000E765DCF82F519C3FFEFC8C6394F1DC8DFA -:10348000F514E7171F9C12FF3DAF46A7951909E5F4 -:10349000471FF9DA9B5FD96FC8AFB46BF9157B3F53 -:1034A0007248D74F7ADDA9E55760B82F61FFA81D94 -:1034B00025F2071B292E1F937F705526FE7EF3B938 -:1034C0002912AFF3E01499DF7359BA81E474AACFDB -:1034D00018B7772967363FFEF83C8349FE02CBA533 -:1034E0001B92030789EE9447847D92345CE86D1B40 -:1034F000282ACB2510F90EEE6FA252E4737AE50B61 -:10350000898618BA73F6F16745DE833EA320FAB1C7 -:1035100044DF3F27FEEB99962D8D03E77F5AFAC9CA -:10352000FF7C3E45FF3E0C7A3CA500BA6B8EF0FB5B -:10353000BC1FF885095E2DA64DB57964E7F92C5EB0 -:10354000C4005479E57D948F5CA3A4B25E5FE395DB -:103550003B890F8F2B4E2FE16363610D59F090343F -:10356000FA59D63F2D74BC26060F7ADE0914A5BB86 -:10357000468733E9DB82DAEE9A18BA583F610BE7E7 -:10358000EDDABEFA20E7F3DAE6FE94F3796BB3677F -:1035900015505E38C93BEB43CEA3424C5E8AF447DC -:1035A00081317F77F2A4A8331C28FEA0E5F9C0631F -:1035B000CCE359647F743D70EEF104C385FE018B4A -:1035C000C2DF13F4A56FC1D77ABFFEF940D5BF2B78 -:1035D0005D4DE77F5B3D428EB682F7CD00D55F92B1 -:1035E000BCAA4CCF8BDEA4F3A46B875B182F6BB304 -:1035F000EA5B85FD2EFCA556CF6A961BF1FA9ACEA2 -:1036000063C6CA6B3A8F192BCF5BE5FA01F5717669 -:10361000C01CA7EF8DEFE7048D7A477F2F29EBD2EF -:10362000576B62CE43ADB7F81D242FD678EE320526 -:1036300062E8F9474A606E5949B46ECD9ACBEFD92A -:10364000737C09D7355B51EACB3279FF03DA019BF2 -:1036500035B9B845D32FA7DAE756ADFF8FB4FEDBF7 -:10366000489F5F14C5CF98516393583E5F22E43161 -:10367000C13C76DEC2B2C0E2D87D10D3F4C205E907 -:10368000744CE1B824B2379A2F294A223CDD3D67B9 -:10369000E0F5E87973BD9F9E278DCF9FDB3C6603E5 -:1036A000FC7795897322CFBA1655FF08417377AD21 -:1036B000A0A7E64B845E1EF388D8475F3A34AEF786 -:1036C000EEDA81ED9FF8FE1439ECA513AE67C4D590 -:1036D00087C6F5CF8B6B1F17D75E14579F1AD7BFBE -:1036E0003AAE3E3BAE7F7D5CFDAAB8FE0BE3DA6FDF -:1036F0008E6B5F1157FFAE119FBEABD212C1311E50 -:103700007F7ABFD3C5DF6F7D553F23FA1E03054C7B -:103710002F3ABD9D2E1EA276AE97E9CC56366E1F6F -:103720009D8FBB0BED2BB287EEAEAD760BFB22B0BF -:103730007AAF461FA41F2C5F15F374E59426B13FA2 -:10374000ECF418E4C8A9F06D820C63BB12637FE649 -:103750009D7B7C9F9A3E439A7E1C78DD3A1F174ED4 -:10376000F1BF43708790F02F75BB76A72AF867A743 -:10377000BAB07A33C9DB56B3882F6BF79D64D0405B -:103780001C070F684A3862227CB712FEEDE4070876 -:1037900079B25193271BC83FC0E749A3825B29AE8A -:1037A0009B7C888FDFC07A5FD1DF16127ECA4B7791 -:1037B000D2F7611B26943DFC63ACBBFE2141B818D7 -:1037C000EDF3896D0AD92C1D4A46129D174A3139ED -:1037D0003AC93F5C53DCE11F85FD36EEFFB0F319BB -:1037E000C4B39C65F326615DB6F49888DEA0D0CBA7 -:1037F000DF9DE13A55F2FDAC953D8D89CE956E9CED -:10380000ED369173985E2B9B557A6F4AC0548EF0BB -:103810001BD90A663A479CA186F9AC4D75B9CCF222 -:1038200065D713C850BCDF9E6C82D767EB6DFBA9D0 -:10383000DA3F3E40D2E2736755EAE3A409D2A01F03 -:103840008EC3C816ADAE6EDB46F78F3825511FFF0D -:10385000C48E05AB0BA3F5EC27760CA77A7BF10899 -:1038600013C9D3744F6AC27B60A6970BF9B96BFD7D -:10387000A2918101E84B267F6D0896855A4934351F -:1038800005CB515A296BCFB3447D0AC10DE12937CD -:1038900068ED1E519EEB79E2C757CADDBA9D38D458 -:1038A000CFCE3F143A071BECC5E9E599FDDB8B68E9 -:1038B0001E739C7687551E4AE70477ACB701DDEF8F -:1038C000B02307C477C66B6C7C2E142CEEA157B8BE -:1038D000A2EB0EAD19CCE7CF432630C46F2DE5C265 -:1038E0006E3D5E6ED2EC9E2FC2F49DDE0E2D8FB328 -:1038F00003226E8AD747F1FCF0022506CF0F957F91 -:10390000BA8DE8B32B6751F5167C6F538B99E3257D -:103910009B5AF298CE691CB28F4EAC7AC54CC1A5A9 -:1039200042E834939D3F8EBEACCEA72B8E025C76D0 -:103930006AF2F967C49F38F16850F8F908E861E065 -:10394000BC511AB89EE0924FA24D22FE91CD0E9C22 -:1039500067D993E95589F4F62DE5BDF6F8624BA9D0 -:10396000E65FC80CDF5BCA13D8E374029FE38D8A5D -:103970007F29B53BF71D0C0FC3EADE378CF449787D -:10398000AB8FD133AB35FA747BFD0AE1707669E019 -:10399000DBF4FEB2AD7F3B40E6A8ACBACDF4FEFD51 -:1039A0001ADE178583B3689809DE7035F51FDFB01E -:1039B000733FC5D10A82B7560FC1F58D51EAAA3DB2 -:1039C00044434AA091C619D51DA97261DDB9F560BD -:1039D000389BD73391C7CBD3D783F450C774E41641 -:1039E000F17B0DBF847F3A97BC689B800FB667F36D -:1039F000FE2CEEECD8F5EF9C8974E1EC4B170DDA58 -:103A0000BE3647E10856A35FB339111C753AD5E1BC -:103A100071ED233D6B2897B920D4FD1CC941FF5699 -:103A2000F74C2ADDA581FBE87D5F87BF99F37C7B9E -:103A3000BAE9BAA15EF838956E4A1B613F653BE171 -:103A40007DC7AA23D51C97D907C2DF89D3877A6996 -:103A500055E2F30BE23E9C49FB8C7632D2ABB2C509 -:103A6000134BAF66CE5785347D126A45FAA5F956D9 -:103A700009FA0DA92BDC89E8EC414DAFECD6E856EC -:103A80007F3EAA9F73954F97EBDF9343966484E73D -:103A9000D303F17D1A78991F900FF653BF0CE20300 -:103AA000AC8F5C25333DE87CB06CDFDF0E0C637FB0 -:103AB000522EA2FBD9F4795FD2E645FA7C91DE5F03 -:103AC000B6B5E700F98A235709FA7C95EE06CB8C48 -:103AD000D219FA8FBFA17E3AFDC4EFE3D71A5DB8C1 -:103AE0004BFDAF121E176D0DF278C83FAF31FF6C62 -:103AF000ED0E2731CB29D5B49F1D1DE0A6FDD8BF03 -:103B00005FD44572E1448389E17A5D61788D19CB98 -:103B10006B468195AE13AACB42B2C9A33CAD31EF3F -:103B200037BAC3883FA49F3FD23C259E804D04AD49 -:103B3000833696A7FDD04554EFA93AFC57C5C9DD99 -:103B40004F0694BBA739EE774B954F699CD35EC760 -:103B500069F6D3E34D7DE3A6E39289AFDB5AEBF53B -:103B600038552DDDB7B38BE2A608D735AD03DBABF7 -:103B7000218D7EB76BF47B971637EDD0ECA23B4ED0 -:103B8000376EBAFE5815FBBFAB80E340AB53269AA5 -:103B900012D14DAE6AE4CF910DC9717152A3FF9A53 -:103BA000AE18E3A6F49DE799C44DE3E3A58553025F -:103BB000E3A796F48D9B42E45D839DB9A655C805A5 -:103BC0001D7E636A6EE2F8E72E8F3914FB7D845EFA -:103BD000B66B70D3EDC936821BC3B3408B3F7B35C8 -:103BE000789669F0ABE5FA18B2E23C1C471579F714 -:103BF000B177CD5F4870CC02CE1234E53C9895E8A1 -:103C00007C3D64C5D8D148FFEBD66B79B42CE0EF8E -:103C1000439FCB79BD369FF29A59668ECFEEF2EC78 -:103C20002FF831D79399EFACA07614E07C63DE9B3C -:103C3000AFD27CBBCAEC6E711F07A4521E48CF4B9B -:103C4000E8F99CB64C91CF711568F99CB8F9ED7004 -:103C50007D7507CD5F20FC977EE9D9A7E523B43CAD -:103C60005046A1315FE188CB57C4E72BD7AD5FB891 -:103C70007F9788B3B09C1E73C3D864BFABEF3CEE94 -:103C800039463F6EDD58DD9F7AD091089EA93546B2 -:103C9000BA6CD3F0DE9C29F211A71A1F2A930DFEED -:103CA000555BC1E9C513F47EE48FBA13F48FF7476F -:103CB000CFC6CF75F3F8C63872023F77C354115799 -:103CC0006179B26EBDD87F6F5C4DF3AFF47346FA85 -:103CD0003856CD9FE37A6E545EE9F9B0516E1BFB06 -:103CE0006BA3B47BA19AEF4D09ADCEA5FCDADC1E27 -:103CF000CA478EDA2D71DE7D94D33F94E2AA5DF738 -:103D0000CCE2FC78767260C7D498EFE076BBBE9DBB -:103D1000C579032DEECFF7E3A0FE533715772B645B -:103D2000F78E05BE4F27392E2F107F0F4E9FFBD8E1 -:103D30002A841ECBBA1A12DE6FF2BBA9426F46E587 -:103D4000AE3F59F8F1B3194E0F74D4270BB9ABE855 -:103D5000F501FDE073256F1FE87885BFEB39E103BE -:103D60004DDEFE0C2E4479FBBBB2C05B09E5ADA570 -:103D700087E5ED235394B709CFD7D3851E8487EB0E -:103D800012DFC3E3AAB850F1F098C043A18E873B7D -:103D90002091FF7801E021B922111ED0BF2278A91D -:103DA0003E25A52293E2A68A93FAF5E2E3EB89F990 -:103DB000A2E23CE36393868F3BB5FCED460D1F1BEF -:103DC000081F76CA570A7CACEB838F23021F653A23 -:103DD0003E9E3E2B7C64D46418DADD95467CA4FAC2 -:103DE000F20C7567A1111FC9A38A0CE35D5F218BDB -:103DF000FB90864F35F4EB8B0FA35F10A0F706F016 -:103E0000B38607BAABE81BABA1F33BBB483667F9F7 -:103E10003BAAA8D4F7B92DCEAFD3CBEB35FC65CDFB -:103E2000488CDFAF69EDFF2E57E656C4F2E7571214 -:103E3000F3E7E59A1C0D9429F30CF47369E2FE573D -:103E40006BE37F7D8A72556C7FFCD92CC5D8E5FD6C -:103E5000EDFB8664E57A7A2F6B86CCF1D4DD4DA933 -:103E60009C3FDB9D24F2656A93D3703FDD48FA0DD9 -:103E7000EB59DFF8A24BA57376741F105A583B6FAD -:103E80001D9CB70E9B76668C594D70FC56453EAF17 -:103E90002B7F89FF6DCAF328EA51933887B480EFEE -:103EA0003532850799E83E2C70679C561E09E599C6 -:103EB000B8BF6D2488EF8521C87A50F2433A7D9FC0 -:103EC0006C01BFC89B537FF11D216F3E05C25C771B -:103ED0004184EB699ABFB7AE2297C74D07D92480BA -:103EE000E435911CD5F9D4E10932FD7B1ADCA6D565 -:103EF000E4D3599057C91F740EE7EF76A11A54CA3C -:103F00006B99C0C1F6A669F381CF395FA77F67F8C7 -:103F1000C220F19DE169EEEF74FBB5D0FD7B9EE818 -:103F2000FD7B2D9A3DA0DFBFA75607F93B7275B503 -:103F3000DDDDECE9FB1DF9E6A9819D44877F4F1A81 -:103F40001112C9E6E0947AD7391DFFFF9CE7F19F73 -:103F500038CFE33F47FCD0DFF81BE8D772CAEFF950 -:103F60005FA07ECDAE52B63BF5321E6FB3D1FFA738 -:103F7000F54A8E5787BE37286ACF390F9BD82F6AEC -:103F80003689F367EABB26B6BBA050D08153868240 -:103F9000DC49D1719CDEE048117F127198A6DFDF09 -:103FA0007E11D9DF3F4C991B49C3F15E3E28EC3F9F -:103FB000CB8CC836BAC779489ACDBB0BF9EE0E6DDB -:103FC000BDF6F22977DE86BFD64F376BE71CBC976C -:103FD00014F1B9A53911B21F5DA516997206CEB8B4 -:103FE000FC66BBA583CF19B7EFBEAB6A1CD039E521 -:103FF000E7DD2DD6BEFB746AF9CDB1526239F89770 -:104000006949422EF98CF7061FABD0CE41A5422A52 -:10401000D991967F2B6989CE05E8A53E7F892752E5 -:1040200043DF5947E8B236C47349595D52B287CF6E -:104030004774137CABBD6107D9BF0F2F0CDE14FB97 -:10404000DD797B19B8C88ECF9D2ECEC3DEA3482E56 -:10405000BA47E3BE8885EF17BF6FC963EB53B0BEA5 -:10406000EFB0D94DF068F7BFEB4CC6FAC3382EC994 -:10407000BB97778B7B26D505101A8DF06B27EF1237 -:10408000EB7B15E073C0EC90956A57F221FCDFB929 -:104090003853C01B8275743FE7A6948BF9DECA9C27 -:1040A00079222E3C4B3ADC45EFDF576667FCE56B27 -:1040B000E7754C6A1DDF5B99B9C0785EE7BE95DD98 -:1040C0002AE1D75D6E77D33958909CAE89F8BEEB64 -:1040D0002766905835F6F0E4B324A75897579CA369 -:1040E0007B580EAB74AF7126BED7E4E6DB110DE74B -:1040F00082F66E15FE69DA64A717291DD71B776E45 -:10410000485F5707AE8BEE37768DE2B844C63CE386 -:10411000FAD2E2FC06675CDD5BD97B5FCF18C2F7A1 -:1041200071FFB78B5FE556AF9CC8FF6C6F84EE9A4A -:1041300098F309CE7EE281975F2CE8DA96FDAC8396 -:10414000EC94E3FED73D848397FE75E03D3A2BF770 -:10415000D2BF5FDCB31CE1F39BCFDFDCFD28EDAF0A -:1041600061C32B44AFBA3FC66730713DCFD5D91874 -:104170006EFE5AED3CA7AFEB59AB8FDB39CFB47174 -:104180007F12B78FAD845012B68FB528D9DF24BA0D -:10419000EB96BC4D320D22CE23EAF8DF78ADDF047A -:1041A00013088F7E89EEBD9829BDA4B8F0FD7B96DB -:1041B000804CF8B72DE9E4F3EABE95E2BCBA4FA90A -:1041C0004BE2F3A6F3CC7C4EA4A9EE8A4B46637D6A -:1041D000CF25E21EAADA95CA953CBF22E825ADBBE1 -:1041E000D4BC92E8325BDCCBA49F372D811EFECE7F -:1041F00063ACB7B3CB46F266010298D6D7AEE14BBB -:104200008B1B94F8BA55B2275D5E231E33E2F0167D -:104210008FD79B743C8E85B18447193A92491FDE33 -:104220000FD049F707DCB3F2B12BE95CDB71358DB8 -:10423000E1D51F3FBF83F6AA7211DDB7E2E0B21BE2 -:10424000ED552AF7A0BD4AA52B5875F54A5CF7E352 -:104250006FBCFCFCD771BAB94ADDA57C544BCB7F4F -:10426000012C1A518D70BD96B857D4B72BA300FE00 -:10427000E0930CF58D1E4BF4DE7FFCD595ADFD1D56 -:1042800000F5C4764A40B66759B47C9BA8CF253F59 -:1042900024A67DEF1C63FF8AFD31E357E27A97DAAB -:1042A000B87D63E5A2EDEAA868FBC7D3B03E1CE089 -:1042B000A0663F5EF380D9BF2B817C7BA952D87169 -:1042C000967F834A72ED5319D8BF97CC0ACB77C833 -:1042D000B3C889EECF03407918EB97CB46F95AAAB9 -:1042E000F185C55F055A9E0CBED0E30FF8F3F8EFD9 -:1042F000E6F2BD4B6BF22D7CCF10EA03EF40793B29 -:104300008BC7F297D8FBB97EAAD3C168184DF37F4B -:104310000A95BFAD623E88B99F01D73DA3E399617D -:10432000CB711EDFE1648EA74AAECD29344F4B63BB -:104330002BCBF31F29813D9531718A96F445C52415 -:104340005FF4F332D1FB8DAE309FC9FDF65D75078A -:1043500080F4C2A7485AF601E8B0A571DFEBB48E2D -:10436000B58D9D5C3ADD0A0B1BBB25C8719FD94AF0 -:10437000E0C5CA12BA570FDB63F8C4EAC6F70C7E71 -:1043800087F1DE4DD91D7112DCEF29FBA393E66F97 -:104390003F24F8FA9E43F57C8EA1DDFB4A12F1CD55 -:1043A00071BAE0F14BF0894F39C8326CEF1BA9D7D5 -:1043B00010FD3CDE9CC676C5CB2BEFBE8AF8E7BA73 -:1043C000EF5FCEF0EEE51BF5DE11D585317CA3DE87 -:1043D000CB74DDCB375ABD7FBEF944F0452FDF8863 -:1043E000BAAF100CF597E718FBF7F20D8D8F7CF143 -:1043F00070959DDB3F7DF25E03DFFCE1A97B8D7C48 -:10440000F32DE49B0472BF789A46DFE7986FFE3184 -:104410004DE3C7F3C437E9D3B473B55F9E6F864DE0 -:104420002B391F7CF3B8E96CF866585FBE993CEDF8 -:104430002CF8A6DD1DE67375EDF3CC09FF0E487769 -:10444000A5C0FB8C0581EA0EB26B14714FDF4C697D -:104450004EB6CF437C26D15DD1A83F853E7FF99AE9 -:10446000DEEF33583FFB353C6E2684929DB454D02A -:10447000CDAB8D22EE3B5372CE5C4A7A97BE23A021 -:104480002BE3E698B8DF65A8F765B20BA1D3948952 -:10449000F3DC83EABD43A62D07EB46F3F861B6CF04 -:1044A000F2B53C80532A14DF3329E2EF5BE8DFC525 -:1044B000CC9B63BC4776C829EC261C2085FC18776A -:1044C00099F87B2757EAF4D3AB7FD10EC1F5750F6E -:1044D000B7319DDCA35C36609CA8CFF96A5F306180 -:1044E0007EF2C0349320464559342D93E4CBF664D4 -:1044F0003A2FF1B8047C4E6741F0E75712DFB95408 -:10450000216FDA57FD89D292B067E6D78D7A5A8D3E -:1045100018F5B41A31EA69ADDEAFBC81F78D7A5A6D -:10452000ABF7EA69ADDEABA7B57A54DE440C7A7A14 -:10453000F55391ED6A4CFBCB54AF3CB59EEE9A76A9 -:104540007EF4F490F3ACA7779C3B79F3F0F99137C4 -:10455000AF9F95BCC9E92B6FFEFB6CE48D6B5B973D -:104560004AE99945FDF0C137353D73A042F9158DF3 -:104570000F65A717AF89A7AFAEBA456BE9EFC77C48 -:10458000EA15FE5F7FEFBB1A7EF17A4B8C1FAE7F80 -:1045900097E06A789C9FDFB8ED20C7634FB95EBA99 -:1045A0000834B3AF5E45BBC8C1F4EB35734EFC6C49 -:1045B000D7D13E4FF05BD9B4C5CC4F7FD7E28FF156 -:1045C000F66F579DCDCCF3950939DD9F3DD4DFBC07 -:1045D000DD95B2E1FB0C7DFE78FA45FAFC37C9297E -:1045E000A4470BDDFF7DBC1BF8EF51FDE7B12DBFEC -:1045F00056E40B4A2F7A283470A6745AACE133C1C2 -:10460000BE732E2E399FFB3E67FC597C36FBEE9A1B -:10461000067A5C3B7EDF95E777DFE7CC7FA8BFF8C3 -:104620002CE4D24B95BDFBE6EF5232B47DDFF3AF05 -:104630002BDEA5B8C63DFFBEEAE714D7B8EBF38280 -:104640009D14D7D0EF8F4B83E88FAC7F1F8970719B -:10465000F9C5772519F362BE2F02F6EFA3DF9F900D -:10466000BDE1EB6DFF7F727F1CD9274712C4197B18 -:10467000DB6DC6B89E5E4EA53FAA85F4D56EDAC442 -:10468000F1887BD0AF6A42BC75CD13F18876B45304 -:1046900058EECC2B1AD03EDAD3A870DCA9BDD1CF0E -:1046A000E59D8DB55CEE79755905C95DDFAB4B585D -:1046B000EFF9BCFEAB7F8C407257BDE7A4E7777A79 -:1046C00074FB44D82F6964BF60BDE3E9B61DB1FE39 -:1046D000CD90E939AC0FF4785547568CDD23C7F8F7 -:1046E00051582772E9F5A3A83E2AD6AEC9613F6AA0 -:1046F0002FD93558BFFFE91C835DA3CFB3D10C8BF5 -:10470000C9AED9B8DB5C9BC8AEA9A84CEC47619D8B -:10471000F3200E9783BFFF97B4BFF315E59781EDA4 -:104720009AB4E9E7D78FFAE5C5E726FED0CBC79A5A -:104730003DF323457956932B5F527E6C3153FCF841 -:104740004CE5C758921F8506F9F1F6D9C88F8A4AF9 -:10475000B7212EFAB2AC0E9A4876FA6E3334C99A63 -:10476000FEF5907E05FEFB77DFAA92D8CFB9C70B86 -:10477000FC77FC66490B5E207AD8BBC4CCDFBBDF7C -:10478000A7887322F7CF13E7AA7EBCB2A89E3E2764 -:10479000DA9472ED86248A6B575A80FACD922A39C0 -:1047A000CE7D5FADB073729C9D97D0FE5FAEB200C0 -:1047B000D1D5A9E2DC146EE778B57E9E4ADAC67ED2 -:1047C00087EBEB16379D5B8D8F5F3BCBFECCDFCD50 -:1047D00083F4127FDF7DAAF8F599C6ADEDD37BFF98 -:1047E000CEC0D9C6AD991F2FBF38E75AFE0E218E15 -:1047F0003E9FB958E64A7F7A2C9E9FBBEA66A54544 -:10480000063817E524FB29E6BE58A725CC7454A129 -:10481000D9514EB29F8AA374D155573AE0FDB329BE -:104820000D4FBC1E9B174AB174F278290D4FF2F35D -:10483000CD747E81F665F1B25C7DB81AE57382F1C4 -:104840009E6C0C1E22B8FCB2B1E110C5A9A759BAE2 -:1048500025FABBADFB1A55AE3FDED8CAE59EC60EA3 -:10486000EEB7B9712B97773586F8F99D8D0F717D6D -:10487000436327D71FCE13F34CB584789C693D382A -:104880007E0C3F547C80F3C4E0B93CA21ADAA7BC8A -:10489000D96A682FE9EE30D433FD5B0DFD07D5866C -:1048A0000CED072A025F9D9E49E71A1E32F473162B -:1048B000761AEAA7EB2F9CEB7EAB53522DFF447E7A -:1048C0001D11407A423A4B6F9055CE9B2F167C3982 -:1048D000A4C11BA6FA76978DF95BA74B3EBB6C1261 -:1048E000EB37C5DC47DBE5B2B1BC68CE14F194E62A -:1048F000EF88FAF66C715E724C8DC88F340F17E733 -:1049000030F53CFC7697C89B9DF0897B3446144675 -:10491000F8928C11DADF7D73568AFC991BDC9C9F20 -:104920006F6E04ED3BC508E73B32C0EC15F7A82BD2 -:1049300032FFDD240B849A70BEE642B77A23C99910 -:1049400060AAD7ECE53F211B32531E91C4132761A7 -:104950003A35BDA3E5E593FE087CEEA0173E9F889F -:10496000EF121A7AF87EA6210D3D9C8FDBFE7D7139 -:104970008F4D3C5CBBBEFF19DFABB4E33B9F6513BF -:1049800053EFE83DB7D363F82E6DFBE254BE6F6181 -:1049900047431E9FA3D8B1587C772C83D8EFF625C8 -:1049A000363E87B1A3C16C263979628925A4C33B01 -:1049B000A49F5BA1FF158041BEE8DF73DEA59DEFDC -:1049C000E9D0BEBFBA433B6FD5AE9D976DD3CE5BEA -:1049D000B56AE765D7D2F91E3BE919859FEF68589C -:1049E00021CEF70C07ED7CCF270C670BC299E2387C -:1049F0003BACB0CF3409E80F1732FCE2BF971D542F -:104A00009B1C77CECA78EE2A2DEE5E2197D778EEE2 -:104A10002AA5605CDC392BE3B92B7B96F1DC95D5BC -:104A20005D6D3C271A4BA70854D3AA2D4D4407BDF2 -:104A30007FCF911E0EE6BF17C7FB53280F85FBCA19 -:104A4000AA15743948FBFE259DCE85E493FC0F33EF -:104A5000BC5D44AFF9746E44E57A92F6FD9B7EBE70 -:104A6000A43F3A3ADBFBFEA5D589EFFBD7CF1FBCAD -:104A7000A1D94F0BA62BAF4F2F89CEA74E57DE8C57 -:104A8000ADEB657FF2E0FF9789CBFF0532DED6778D -:104A900000800000000000001F8B080000000000E4 -:104AA000000BB555CF6B134114FE36BB69923669C6 -:104AB0001649B5211536C668031122A6A59588D3D7 -:104AC0001A24875AA2F4E0C1430E39F9E3EE6D537C -:104AD000158A92D218C173840A160AEDA17F40AAE2 -:104AE000C1736AAB281609B5F42CA87829C437B36A -:104AF000D9264D36B5170792973733EFCDFBBEF762 -:104B000023CF41CB0F4462EC9AAC0123895AC549AB -:104B10003214072B4581E92A4937ED2F1A526532A5 -:104B200029808BD98434F574AAA62864A7B6D9A5A0 -:104B30000FECECE2DE18B71BE05211F2DCAE13F022 -:104B4000016B49A9F42C08CC6DD0791CF83D269551 -:104B500010E4C1EDD7EBA3C21490F917EBF79F0453 -:104B600066F84F7AAF7FDC379021FF0B3A503ECF8B -:104B7000EFDCF172DD9D284C6A144764AB0A85FCBA -:104B80008D54A19E00C7F78381F6674F5F97157A12 -:104B900077691E3845FB73F65AF22EDD5B1B77A84A -:104BA0008F62DCCF94FD019D4F0764C85C4FDB77BB -:104BB0006A142A2448F533C44F4231745A75FADC1A -:104BC000448B4E714F737DB8A97BF743132AC5F50B -:104BD000703BB852196EDA852814BE7F89797C7BC8 -:104BE0007DB41141A42E3771D4F9BADA29FFE8DA7D -:104BF0004AC5CE71C2C6F98A6FD94A417AA7FF6306 -:104C0000B197E393AB69B946F64812EA71C2B99518 -:104C1000F6E2087FDF387F0E605B770A59D55521B1 -:104C2000D7F44121F7744DC85D7D58C81D3D2664F9 -:104C30004D1F1312C8897C3A2488F7DEE8A9CD6499 -:104C4000B8FB7B1129778BE71DAF14BCE6791E8A70 -:104C50000BBB8E7B25F2D3C217D1258AA1E279390D -:104C6000C1ED5FA46C70907D31A1F9D3D14EFBE210 -:104C70008D492F2CF64D99D76F6F3EB1773F77F75F -:104C800020B36A61FFB851C74041C41148D8C0EB96 -:104C9000D7EF844BA5FBF97597A8EB50CC597271EF -:104CA0007C7937BE9B38A87E16EE1704FEA54545D5 -:104CB000A59A3AF0EB89513C2D7515606F0779DEA6 -:104CC000F257CA836992C58BEF3F9F25BBDC868C68 -:104CD000303AE37ACA241197892BA0AC4AAA45DE60 -:104CE000BBE1BAD7B0C790CF980B6DFCB7DF37F3F5 -:104CF000CE112AA38D16A595EDCD2C30DA67CB9277 -:104D0000E0C13504D1DF3D60658EF718F101978968 -:104D1000E7F24826E76EC6D32D4F661C7D8DFAF369 -:104D200067355786E7E11F75E8B61BF92A646DA958 -:104D300092451CCB8D3957601F9CBC1F11B58EC38B -:104D4000136BAF53239E7985FCF3BC31F26FC1F72F -:104D500057CEB751CF5F646A81E2944DE33DE421C1 -:104D60006E183DE59940291714751E2BD3F92FD6DF -:104D70001313EEDBE643C7FBACA58ECE74CE9D7558 -:104D8000E636E64D18613E6F7E0ECD78CB16F96D96 -:104D9000F689C1A339773A79D40C9C590327A2D656 -:104DA000FDDCCCD76C63A823231FAE9B4F47D54DAA -:104DB00037FEDBEB603E9BF696E9FF01EF5C9276F7 -:104DC00081F371B8FFBAF1D6CED3DE7FE6A9FDBC80 -:104DD0006ACE9563E23CEE3D53FF0BC81D4E69F071 -:104DE00007000000000000001F8B0800000000000A -:104DF000000BFB51CFC0F0030977F3A0F2BFA3F182 -:104E000057F1A3F2CBB851F99E68FC2634FDE7D1E7 -:104E1000E4591820B4033BAA38B15888838141165D -:104E200088353850C5F3A1E656012DE805E265AC9A -:104E300084CD7A27C5C0F05F9681E12890AE06E266 -:104E40004B4036931C0303AF34038307104703F131 -:104E50003B190686A940FA25106F9086E8E3048A7C -:104E60009D9421CFFD6D42E4E91BC5D4C1B7955097 -:104E7000F993B51918AEE93030A8E941F8E791E4A3 -:104E80009D806253B421EC70550686BDBA0C0C8728 -:104E900095B09B1B0194DF07948FD0C36FBF831124 -:104EA0002A7F8B352AFF8B212AFF9A272ABFC11B15 -:104EB000955FE103A10157D509D0D8030000000098 -:104EC00000000000000000001F8B08000000000030 -:104ED000000BCD7D0B7815D5B5F09AC79933E799BE -:104EE0004972028710601283440D3884F0147512E1 -:104EF00082C6368503A2E6B7B61EA955449023D2D2 -:104F00009AF6573379125E6D406FE5F779A0DA5261 -:104F1000AB357AB1F5B66A9340BD784B21526B6DD3 -:104F20004BDBA05EB55EB5D18ADA5E947FAFB56724 -:104F30009299C34988B5FD6CBCBD9B3DB367EFB585 -:104F4000D75E6BEDF5DAFB285002FA2480E3F877A0 -:104F50002EC0E92200CC1C2AA373A04CAE04D8209A -:104F6000048D70312B3F94EABBC2EC1D58F1A55360 -:104F700087BEBB04046AFFB3E2F6783F7BDF31F9FA -:104F80005B712867ED2708D4DE69E79457820450E7 -:104F90000050DAB95C4DB07E368C6B56B17D87BE61 -:104FA000AD1ED878474B159070BCE2ECDFB73702E6 -:104FB000744F01381736AB2531567F4E323642B624 -:104FC000718A691CA7EE8F8BD05D06F4779CFD6F0C -:104FD000C3CD4948B071DB267FAB1EE156BAAF01A5 -:104FE0003D02F0957149D0D9F3E920D2BC9439162D -:104FF00098ACAEEA56DC9A7AE2381D889772ECB526 -:1050000033BE3432F47C898317868F0CBC00CC030A -:10501000D0A0A2DBC27A00E8FBCC7E4D7B7C2D3E8B -:10502000BAF14F9C3F1F7F1AE88407503BE389C8C1 -:10503000103C1B7C03DD12C3B7550CC6FDAC490EFA -:105040001BA7CAD54FE67883F3943B3DEB3F15E1B0 -:105050002CA07908B2ABBF4C7866D9ED66B19963E4 -:10506000E9CC2B673E1FE764FD7F06515C80ED3B7A -:10507000E356C4458FB2E5C17BD06EAF99DE76C3EF -:10508000E12784F89989F8B1E2488F0E1D4B61BD84 -:10509000A996CDA7C082012997C8C6843100F9F826 -:1050A0002FF689ACE95548AF634CD696BD1F1BB3AC -:1050B0009A24F67CDCFCB420B332027769AF84001A -:1050C000A1293D4E1F599CEEBB6674F433BA3D0ACC -:1050D00091CE8DAC6C9159BF88B7C391F4FD0CA4EF -:1050E000A6B353F7F6B37AC492A1B992C6253EBCD3 -:1050F000513ADDD8C8487AA34DFF1D8D2A95ED8D14 -:105100001A74FB015A1BE354DE1EBAE5BBD87F8339 -:10511000E5D7FCAC94BB6E7818EB2D00091C2F1260 -:10512000E3FD83AC6AF76B580713F11E29E5E5B37D -:10513000881706E7B71826112F3FB6F1A44337F1B9 -:105140006B8BB13407B2E0D32943655E3E0BE84177 -:10515000F6E550DD1FCFF3D47D5AA1A73D4011E104 -:105160008DEA4C54AC10B83C8AC87D60209C0C5F22 -:1051700059E5822D572469FA40379B5F78B662EC77 -:10518000649F6E11BCFC354EE0F4512EA854C660ED -:1051900060CF71C48B21A637B2B182D34BBABA6348 -:1051A00038A6624C66EB18F4A5B5BC2CFC0595F24C -:1051B0001BFD0EDC259F3E7E24A92795C832EEBB41 -:1051C000F6FA9D7BECA08AFCAF4E1713E97284D7E8 -:1051D0004AB0C9C3665D1671DE9F1EDC23AFD711CE -:1051E0009B9FDB41A5F632AE57E5D07A75186CBDB2 -:1051F000907F2AF97A75C8963A9AF57A00C0839713 -:10520000D0205EBA385ECA3F65BCB4F4D627B2CCB3 -:10521000A3DD5E4F190CA38CF0A0E808E7E6264E4C -:10522000B716A3DB6CF277383C483987E3C9F21331 -:10523000F17EB1C0C75960F38983A70D86589B0ED4 -:10524000239E3A6B516E6D2E1545944B9F169E1CF6 -:10525000B8360EC295E670957DBA7049A1EEFA6C2B -:10526000FCD89EC18F9B106E4E77B59CEEC44F95B7 -:10527000EE1CB802C80F7C9D137C9DE57F89756E7E -:105280001F5CE7245FE7F8A7B3CECE7E0EAA518F4E -:10529000EBB642637CC8E0B856B2942B707F0D0920 -:1052A00070BFC1E800E11FC7F4CC70F3F3BA0E7011 -:1052B0009B10E0FA8674594ED205EF0A99E92C1535 -:1052C000F87CF3A9C911E60169DF40BF0327E3DFDA -:1052D00086C34DEBF7BAE0BC5988C408CED9301B61 -:1052E000E17C27BC34A71B86EFEFF546B549F601F4 -:1052F000BCDF68ADDFEB3BF1FDB512A4B2E99777F7 -:10530000DA7201D42E85E67F13E3C1E98887536BF7 -:1053100020CAD623DC3C06E70161F6722EEB675704 -:10532000A04976E177B8F90CE2D5F98EA93BFEBC2D -:1053300013BF1FEEBBBF09C97B0586DFB698588334 -:1053400070A9A590C635F0EF5AD25D08C3C3DB162D -:10535000FBC7C03BECBAD9EDDE0937B733D30B5AE4 -:105360007CC63E9DD1496B816834C3101C0EBD388C -:10537000EBE2E071B4EBF2C741FADA7C1E909E09D1 -:10538000BA34FD93D3D53EA4AB33FEF974F5CABF4E -:105390002E5DBD2E14FCEBD295D220E92F333BA31A -:1053A0005836B99CD4965BB4FE3836934B52E7F42A -:1053B0006E94971067F6191F064456573493EBBD49 -:1053C0006000EAAF6AA9574EFA8ABC72325E6F7605 -:1053D0003BFD6ED4715C85C645F308C795C3D01DEF -:1053E00088625DA17E909C8F9FC2F00477D696F074 -:1053F000EF0CFC6EB8F9C8F81D1B0FD58FE3C5F88C -:10540000DDE7731259ECDEA1F97BC7892F4BE42449 -:1054100022A36F0F61597FC585F7E1BF93E115079F -:105420002F8CFECBD04F5230847F73D7F5E4BF086A -:105430008068905D57D46EE1DBF5F8FFE6E2BECF01 -:10544000F97A7D518586FA16B0FD069F5BC2570139 -:10545000EB7F1374E25B673C299C00A21BBBDDC998 -:10546000D6FF46E4A72CFC7D99C8F58DF76F49FD62 -:1054700019ED416BA3A0DFCFF07AA0F1037889F199 -:10548000E5F2EED314F47B5C2E8EA176CBE7172BDE -:105490000B5CFD2C076E1702F4CB4B22EE719BB810 -:1054A0001EDA25F5E2BC5F9C23A571FF7B71CE5F00 -:1054B000483F7FD194D288E4173B2ECC1949EE1C8B -:1054C00068E4F6ACD3EE8029D1FE7E40EE0F67D3C0 -:1054D000E387C64FD3F88BE748DE7D5AEE9771FD20 -:1054E000DFBF197CA83F1F685485972633E317E771 -:1054F000C9E868F99C6205FD0E279BD705B61FCC4D -:10550000C1AF33CFD6B048F36C0D5793DFAA557BAC -:1055100087ECC7A3EC39CA83E1E075FC56ADDAD25B -:10552000ACF850225CDF527CC9ECF6A63D5FA79E2A -:10553000E9CFFAA4F0B565C0D71EE67A56BB9CCC7D -:105540006E4F65C0A3C4448F9C885DD625E03E376E -:10555000168C67A614131A0FA1FF64822D7BC61E3A -:10556000FE4DD3D50CDE0357844D218EF5DF091394 -:10557000199C5AA1043E56FFB7656B7B7E8FFEBD1A -:10558000FA10481A836BD96D4D8C5C61FCCDF7091C -:1055900058DE8A76210A5EEBCB4DE8B76AC54EE746 -:1055A00001DC257EBE0AFD6A327039C0A49C2E8FB4 -:1055B000417F0C9033663879C0FE84E3FEA1EF860C -:1055C000C353C4964F344F924F4B47964FEB78FFDF -:1055D00016FB0FE5CBF8A1F1E8FB712B14CF3A8E47 -:1055E000CD78DF6BD3A11F96FC53C729848A00EACC -:1055F00023913A514B637BE8CA45BF536C950CDD50 -:105600008C6E0A2B3B059F7E72BC333957CBFDC491 -:10561000A6E0E6AB5FDB7268E2D79F1304F4F31AEF -:105620004C859F8EF586E9D9F8E1DF901EFDAEFA34 -:10563000B26A01DBB5327A2A4539B64C243BF7D63B -:10564000BAA5B9EEEFDF131DFBD8597FD0E5595845 -:10565000E7EB2FD7896660DADFBFFEF2C75CFF8217 -:10566000758A872F3EEEBA88686B149C7CFD3FE9F3 -:1056700038CEBA9DC81F4DF6BA9506509E6CABCD7C -:105680002EBF865FB70A01F7B7581D98E92CDFF9DE -:1056900025C123679D528514186C9DA5E724D24F20 -:1056A000A4B1B3EA77C0F0E34A3125C35EB3FBB3DC -:1056B000CC3DA56CFD3F07CE5F9F8C72A62E2EC100 -:1056C00046669F41A5EF65B73F84ADF0509DE1FE72 -:1056D000CDAFEDD97B37FA97E6FAC95F9AF9BE0EDE -:1056E000EB2E7AA891B8FFB4F7B15F9F2AB0710E84 -:1056F0001A7EDDCF1EED17FA5E213F6F9544FB2F1A -:10570000C2A7CEC2EF81949183A664D6B0F67D95F0 -:1057100002ED9B7E78F68BFF97BE0F517CA36FFE48 -:105720004BDF388B7DFFB9B37DC8391C13F83D932F -:1057300095807ACCB1FE6F9CC5DAEF3F3B7F44FD8C -:10574000AA0EE7EBA293C54F78EB9722BDB1F5E81F -:10575000FDFDAB7577B2F10E424EC28FE51C0EDF38 -:1057600041840FE9BEFFB7AFA01E78C014C8FF7414 -:1057700070CE2F63687F579902E9878BE60B697FAC -:1057800096792E9A7FFDA489ACBF8411D202ECFDDC -:10579000FEAAB7379FC5E05DFC1FD2162CDF7A5CEE -:1057A0002A48960F0FAFF37CB1E97D3EA80743D29C -:1057B00042BC83C6E310BE981177D3EBA0DE22274C -:1057C000CC6CFEB59512F7370A9A41FA9C1C56002C -:1057D000E7315CFB2B87A1DF1C18E896100E47DF32 -:1057E0003E76A1BE64EA897028722289E3489A0253 -:1057F0003B71DFCEBD5877CFFF66079EB849F028D2 -:105800001A8747910D339B7FE9AB363C4E3F009D95 -:105810005417E203D01F1E82AF2D90A8473F8595F5 -:10582000CBFD85AD11AFFFEF519B8EBF6D97AD3EA8 -:10583000C81A470168A6FEABC7CC51B1FF96395CC8 -:10584000EFD0C1207F782BB31361043D6EB3AD77E9 -:105850006CC478861FE31A9A1DD788737D24FC28B0 -:10586000F9C58E968B64C70CD74FC4F0EA43A132BA -:10587000AFDDE2E82B013D2FC3EFE3F5F3F8C6C837 -:10588000A2A34721BD9E0CFE41BDCE6EB75E4EA9C0 -:105890005A563CA547D4DFFE79F8E3DF877C5D5A92 -:1058A00036B8FE517873E82AB37F255F49A5294EA3 -:1058B0009788BBE9FFD7365D29F96A0AFD9FA00EDC -:1058C000F73EC8BF0FB3F718BF082774D42B25E0E5 -:1058D000712015F9C0859F3FDBF45F2F8B363FA603 -:1058E00028EE29E829F2D3A9458C7F8413BF73CA17 -:1058F0003FD8E3AEFFF08617883F0A54E20F4167B6 -:10590000FC93651C4B325F9758FB5592F93F58FA50 -:105910003E9292D9F8E44F128FE7AA75095D2DA146 -:105920003822D91F9970F8653EFE950EFC568AE222 -:1059300092A385FFBD51C2EF8CC3E017E59904BF68 -:1059400084E570F00B363C79A037C928D7742E5FF8 -:105950000196E86EBD64B9DD6F9E2D9F00AE8FBBD2 -:10596000F5C02FD8FD8C763E9A3CBAF92C1F9A4F81 -:10597000913D9F0923CD67BCCCD763B9CCF73BB52C -:1059800026A1C7D9BAE40E4357F364BEDED70DAEE5 -:10599000CBF51F8BAE4E1BE53C9C71D83C66CA9C78 -:1059A000AE668D348F4A1B9E4E09E6BE8C7AF12975 -:1059B0008E7F67A9675D6EB0C7EFF43BEBB2D6B3DD -:1059C0002ED7D8F818ED7C168C723E370CADCB6212 -:1059D0007B5D1223CDC7D5FE227BFE17DBEDC9EE22 -:1059E000B8419ED28C768625252E95670E8DC7DA16 -:1059F0007D5E2E186AF7E796779BAC30B5BB9CDAD4 -:105A0000D5F2FD8FB54BBAFB032BD28CFE8036B49A -:105A100015981D53D23AB7DAEEFF2AFAAE6EB0FFF0 -:105A2000ABDDFDFB5BA1D9EEFF5A7CDEB4E023A722 -:105A3000DD2A2FBCA73BED52D84EA81984E37A7714 -:105A4000BB797221CDEB8438C328FD3FBE58B20329 -:105A5000E3FA7910E9C4BC8E7639752FC6FD2D4B5B -:105A600086FB317FC06F08E8538BCE497D17DBE59D -:105A70005A7E8DF23FAA530F63DD1221D15249F9AC -:105A800003941FD020AB9ADFC07C0B03B6B3BA16C9 -:105A900093D39897D326242DDC177F2E2537CB243C -:105AA0005FB5CB9AB0FF7C9DEBE9D04FFB9603D757 -:105AB000D6D01729DF2197C185FEA7B60CB86E0F87 -:105AC0004DECC1FDF6D60285F464666095A17CB903 -:105AD000510A1AD85F4FC15709DE6D4D3C9F61DBFB -:105AE000E7BE4AF0DE2600C5696FF3F17C86AD3E65 -:105AF000556BD6B0BFE8B82F53FE438EE6AFB4E186 -:105B000040F83E5B42F0E5835675A540E2AB07EDF9 -:105B1000DBB6390AE9CBDB621555D4DF1C95F4D42A -:105B2000DB12154DA477CC09924F3E3F6C90DD1AE5 -:105B30009DAD8085F598D1847A66645610735E2099 -:105B4000BF083099002253208D751F747696B232AB -:105B5000DAC1EC927CEC6F295C8976EF1C8677B415 -:105B6000232CF310DA2561B0FFA4FD26CEDB375ECF -:105B700002C9185ADF68E7E0F723DA5DD1F428DBC1 -:105B8000758FAE5DA483D9FD3346D1AE7394EDD24B -:105B9000A36CD7CDDB9DD4DF61707B4F65FFA1DDAA -:105BA00016C8B067516FF7C4F332DE67C6DF32CB79 -:105BB000CCF8C76BB237AE76B2EF9DB8C7C9E68BEB -:105BC0004E894138A593B777F4CDE1DE2B8517C711 -:105BD0004DF67DDBB84BE324D7C65DC6CB09F6F3A3 -:105BE00009F576FD52BB7E59BD9945BE17F8F83EC2 -:105BF0005486FE9011D6211FB8FEF80A83FDB880A6 -:105C0000C94A23FB4F32F5DE4C79A7CA5635F2EB71 -:105C1000B604CFEFF02333221F1601F9357D90EA49 -:105C20002C4539016674E19821FEF1994F9BC8CF4C -:105C300007C64920CCA1F531C87F9E41279974E160 -:105C4000CFF0E77C523A99EAF3C6C9FE5174A274C8 -:105C500048A3E21FA57394EDD2A36CD73DBA76FE9C -:105C60000E6174ED3A47D92E3DCA76DDBC5DFB5C12 -:105C700085EFE7F058B359CAE09EA77AEAEDF382C0 -:105C8000DEF767853DF5F53315DAFF9DBA7F96EAB5 -:105C9000A9AF6772DEF37E7698EAEBDB7E5ACDB66B -:105CA000B251F3C97FFF9D7C52A69EC42F3D47CCC5 -:105CB000B0DB32F84AD503F87DBEAC03E64BE5C74E -:105CC000F83EC5CAAC7EB9BB6DFE4FCB1A95DB64FE -:105CD0003D80F6E3BFFA3C1B7D1C5E67BE2783D781 -:105CE00091BFAF4AB6BE355C9E470DCFC3942148E5 -:105CF0007998A53566B5C9E492FC0C8F7B65F67B77 -:105D000099927CD8E7B2F7652DC9E379767F1714AD -:105D1000C8A497C84CAEA1DEA340A2B698E28622E2 -:105D2000F9FBE4F049F68D2297DC2A19016E3B6FEE -:105D3000955EE90055AFF1718306907C8D403F1967 -:105D4000D339A8F59C827A9A2E007D6F08DC7F3EBD -:105D50005F4379160BFCA3FBBD8CFA15CCAD703CF0 -:105D6000F431FA95FBC9DFF90FEFF724F006309F05 -:105D7000F70C0A21C4DCF9BCBE788A1EC2B1E3C7A5 -:105D8000A559C03FA1BF24C5D365D1207F281446A3 -:105D9000C92E6B8BAD55DDEBFA575F89378EA6B5F3 -:105DA0005F2F445959B4CAEC1F81CE3FC42018FA62 -:105DB000478AAE34FB47D84F07E397189FCFC207F7 -:105DC000ED4A328DFABB3531CCED7939457EC6F5D9 -:105DD000425EC5C64A17FD1629DD0857D8302DB4D6 -:105DE000F7D6E78B06EAA9326CEE13A6B1EFA43A18 -:105DF0002399458F18FA5E7EDD3D9F3CC5BB4FB6AB -:105E00009C84DE9DF8E470EF7D8A91CCE60F9DAC1A -:105E100070BBD617CCFEFEEB62758932F344BCE151 -:105E20007680DFADCF850EE14C4E3E94DF50F4F42A -:105E30000B8887B682F3E223CD17346F9EE555A217 -:105E400079A65230221C33B2C131DAFC0F8014B370 -:105E5000D186E225A81F096330AFC3F933A015ED41 -:105E60000B667F60DC23586EC07DAC1E5FA026648D -:105E7000A62F6DA9DC09E8AFF631FD89EC13693E68 -:105E8000D79FCAB83E64B2FF701ED1F923EBD5523A -:105E9000467DB1E2D59B5B1A1F078CC73BF03B7E6A -:105EA000BCCC79CD13AB2F520AB2E16374F6F0ADDE -:105EB0008C5E9872075B1B552ABFD9A851B9A531D2 -:105EC0004EE5A64646ECE81F6D2CA3FABFE1A7738A -:105ED00091CF531DC50C7F1DF1FB5EB812D02E056E -:105EE000DB4FF08505A82F6FC43AE901CC0CC4FA4A -:105EF00004FEFE7A65D102B4F337069CF6D50B504A -:105F0000AF1EAA5FD45285EF6D3F43877239B5BF8C -:105F10007502D8E7184CF522D7BE77B7E2A379E02F -:105F2000DEC2BF3FB705FB0BC84E3D45F00CD63176 -:105F3000E08A7595D77BDBAFA7FE4904B0F1FEABD5 -:105F40007DED02F42FDC3A99FBF961D9D293E0910F -:105F5000FBF53FC2A02FD2E5B23CCA5F5118DD94D9 -:105F6000B047B7E6DA708FB21F90937CBF7B2EFBF1 -:105F70007E39C43727D9D76C384ECE0FA6ED874867 -:105F80008285E3FE8AF3C53F7BDC5B7D1F0F2FEA32 -:105F9000FCA489DD476BBBBA71A9E729C91F22DDC3 -:105FA000E7D4F4D1B6A2C4BBB9DE30CAF1B72A9A9D -:105FB0001D8F4A92DDE4E0DBD13FFE94B19EBE9896 -:105FC00049F9478130E7C3D1C2FD071F3FC7E3F45A -:105FD000030F568C1B49CF8AD589A88C0DCA8DBC5E -:105FE0009AA0A7AECDCF43236DB01EAD2CF4D4C381 -:105FF000E5259EBA4F3BDDF3FDDFBB5EBFB4F54543 -:10600000A7FDBE8CFA9399F31C65BF4EBDA77F8197 -:1060100058C6D6E1F9F912C5439F9FFFD26D3318D8 -:106020003D3E6FE2EEC9ECDAFA161FC633FA980A63 -:106030005289FB7052B2FDEA3001F1F92BFC171BBB -:10604000EF97F6FEF7AC7DEE876DBC13F09CD4B3F2 -:106050000BDF2FC2F57BD607B65CEA24B97070B0AF -:10606000CEE5C2C100AF9FE9DFDE8272A04FE075CE -:10607000D1BF7D01F73B6E6E3F9FE92F8BF19F6C87 -:10608000FC65F305339D657F0BFB15271F32EC671D -:1060900078326B4C5F01E6BDE9407AAB1F12A49FDA -:1060A00035805525A2DEC3E88FE2DDB236211B7DA7 -:1060B0001C6CE4F9027EB890F4FE65F3A7FBD0A84F -:1060C000F727DE96D14FBA3821F8C0D69B35177C1A -:1060D000A2299848DF89F9FE9DA83F2764461259F6 -:1060E000F691C5A6DFB35F196C2C84BF4FB0F914CD -:1060F000B409EEB893E1E7764FBC7464BBC181DBB1 -:10610000A95F38FFEDBDF9E86FAC158CC9D8ADAA11 -:106110004DF862C4DD6FC8891347B0DFE7EBBFC439 -:10612000FD1A8C2ED0AFFACC91AB7D149F5D96EF0B -:10613000E1BF6575DEFCB6A535214FFDE2F923E729 -:10614000D741D29F21D72CFBFCA548F278E361818F -:10615000E443CEC48134E667C2F312703DD0F1C38C -:10616000CE233F6C74FC808EF9A2F0C79076BF4BB3 -:106170008EB666E021B37CC2CFF55B39AF96E2DC28 -:10618000EF1F1174F4A70A790D5370BEB26236E3A3 -:10619000B8ADC5621AE3DF37966C5371BD37947E94 -:1061A0003C7DD017E3717FDDD22A90FD87FB2E6DF9 -:1061B000F2BCB6CCE7D7FA79DCA1CD5AAA9522D3A6 -:1061C000ECD5AA70FE8122C87ABE94D1FFB57EF2CA -:1061D000BB5BC0E3EC09D2AF4BD5E5947F2B178EA8 -:1061E0001CB7CDC49B6CC70333DB3D68D363E99C0C -:1061F0009DD4EFFBA78DDCAF83970F0C11FA102E07 -:10620000A657607B15D87C18FE3795F1FCDBD6F2DB -:106210004709CF9259457AAD4F4B99D86E53F972D1 -:10622000A2CB36D6269F0D9D5BD345E733377DC87D -:10623000E3140FFAF7B6A05EB1A9E71AC07CCA60F2 -:106240003C0D283F364DBD4A453C6CDAC1788BF495 -:10625000992E72CE856CBF78488334B3A840D6BBE4 -:10626000BA512EC8B56098EC556FBC1A70DD365522 -:1062700072D6CC4FA79A3004B4297EC8C4F8446BB8 -:106280003D50BE4BB0CCAC2D46F8C789240E7448A7 -:106290007660BDB54EA6F9B46B1C2F68871D77F2EA -:1062A000BD302FA694DB61A5E8EF67E32837F3F94B -:1062B000EBDB4BC96FB42957A9473967DAF611D31D -:1062C000532CF4F3B7366859D77DB3987CC0EF925E -:1062D000EFB296A0FCA64CFCBCEF83CFE0BC5BA762 -:1062E0008BB0338BDEF1233FB74BD2C6D2C52559D5 -:1062F000C679C2AF7BF611FD0385E01DAEFD503BB4 -:1063000099FCFB68805CC0E65150CBFDA690717E85 -:10631000350649B273C782D584FCE89C5B1D5F9348 -:10632000F84D9295526419E5D50D778ED5C9E75C85 -:106330003E07EC3FFD92DFB1F95EB3CF0788B7733C -:106340008FDDFB34E64D39F606DB979E7E92BDBFAE -:1063500092A96558BFE6F05405F3809E2F9430470C -:1063600006F9278A74F826889487F6261C8ACE7048 -:10637000D1F9FFD8FB0E4A5694232DB97C5E72B832 -:10638000BD4F8AE27ACB56BF93C747F60FCF6787D8 -:10639000307BAE52165213C9BF0E9E37E4E4497EDD -:1063A000B9D39B4774F5766FFD2A583A06F9E6AAE9 -:1063B000DB7C9066FD5EE3CEFF62E3FFD2CFF58328 -:1063C000AB21D58EFBCF7A5BFF5BFDA3A90AD2F58B -:1063D0003533B4623C7FE1CCE32FF6BABFCEF8543C -:1063E00077F1FFCA589AF29233E7F7E6EE05DD49F6 -:1063F000567F499753DCDEF6CE73BDAF6F11E67D55 -:10640000595B7C8EDEE0C9775CB9ABCAC4BC31860F -:106410003D3DDFFB3DC1FFA50EEF7C4F868FCCF9E4 -:106420003BFAE070F3517665D72382AA376FAA450D -:10643000E57147B34586C039279E8BB6AA5374AE23 -:10644000D96AF66B2D318A53521CB081110EC6F9F0 -:1064500066A83ACF730F4C4C039D3F48CDC673E1FD -:106460009FB4DF392AE7C37F74BF670FD3EF6AB5E4 -:106470005F41FE5C2377D60A2543E702023ECB1C30 -:10648000CFF0ED7F7C49F778F0B4EB1865BB7D78F1 -:10649000F47914ED6AC511FA7BCBDEB7FEF3C16F58 -:1064A0002BB87FBFF9C0914528E7AEFD89042A6B60 -:1064B000F7D68311E8A67D27ADA03C5EB95BA2F5B7 -:1064C00007B97BD6859E3CFB169AFFB50F47687FC0 -:1064D00058F9A83F5DC7BE5FF9C397A601E3DBB7D4 -:1064E0009A079E1E8FF87B40E0F90C56FFB40BD93B -:1064F000F395325C9E2D1F21A972BE7AE33F42F5CF -:10650000B8BF0BBB7ABE48FD765DE2F3BBE4EF2576 -:10651000AACF6947FAA3F53D213D59E0F065CBCFFD -:106520007BE37B3CFEB4F2715F1AF31557EEDAA100 -:106530002459BB35BBDE26FA5EF0F04351C4C39A42 -:10654000C7BD7ADAB50F7FD83EAF92CE390DD4A150 -:10655000FC938E51FDA8A90E70CD9FFB67AE238ED4 -:1065600065EDFEFDD5F37EC7DEBF1E9720C044CA91 -:10657000EB7DFFADFC04EBC9708A8932D6BFEF45D5 -:10658000371FAED9F5129D37D24418283A0BCF41A8 -:1065900064BCCF680F30A0A03C5CD3B5E16D94978C -:1065A0006B76BFF95BA4BB3520BFE8E6E7D7F11FE8 -:1065B000E34E8C6B75A85E3FCE51D83F0BED16D8DD -:1065C000959FD55E74E25A0E7F5FFBD0D17B508FD2 -:1065D00078E3D1FFB907EF6558F5D15FEEC1FC56FE -:1065E000782AA0A1DC5AF3C0AFA2E0C2FFB76DF9D0 -:1065F000F0D6F7BEFB9D3B181EDEFA8D9FB0F6D697 -:1066000093AF4EC4FB39DE7AE4AF6350FF58F7E432 -:10661000C2B14867EB1E5B3076A4F39F48B769BFF1 -:106620007B7DD3FC5E83C705DC04D9866B9719EBB1 -:1066300002FB0714D47BDF136060632E7BDEF5A1C1 -:1066400082FACBD3260C209EF6EC7EE9E9AFB3FAB2 -:106650009B6C9DFC59D689CD7FBC48FB1B631F56A4 -:106660005EB7FBC2C5675762E933B0FB353040FB0C -:10667000C609EBFB1C5BDFCAA1F5CD7C7F148E291C -:1066800088FF350FB2F59C86EBCAD673DA89EBF931 -:1066900026FE63EE89EBD9AB7AFDAF4761D5BD77B6 -:1066A000E0CBDDF959ED5B673D573F76D1887AB98C -:1066B000231F4E86673AD7CBE0FA866A1E520B90AC -:1066C0002EBEFF9D3B627C9DEB1862DE7AE8E844BB -:1066D0003CB4F19A6FE08B88878127FD1AEA512B31 -:1066E0009FFC35F1DD5B8F3D4BE779D85F5460FB54 -:1066F000DD5B30F8770858FD3A815756EB03E7FD2C -:1067000096F5BB9A756119B47EE7FDB612D74F1D99 -:10671000A0F5482FA9D551FEA60B68DED7A5397F75 -:106720005C97EE59867EED4CBC87034E5EE1D0BA95 -:1067300062BCF9BADD47CE43FA1B6E3D9DF96B385A -:10674000FFD9ECFD7D5EFE1D965FEDF57D6BC7FB11 -:106750000AEA57DD3F513491D9ED6FF9069442DCD6 -:106760006F1E91343C679CB9EE43F86FCE7ADE38E9 -:10677000B3CCA40F25903D8EEDE0E964FC7EF2F9E8 -:106780007D3CFCBD6BEF9799787CE358F6FDA02427 -:10679000C0EDB9EBA0B31655CCCCFDCC07296B7C72 -:1067A000F110BCED5D12C9F9377649148FCB9417FF -:1067B000D70D639F19CE388FF74C43B9F646EF7F5C -:1067C000D874C9E9FEBA078F2896BD3FA45DF85D6D -:1067D000339CDFDBEE6FCD13D9FB5BF3E0DB59FBC2 -:1067E0007B5D362F41F85FEFF3517ED2EB5D525661 -:1067F0003BB734E0F3E85DED91592FE460DC201AFB -:10680000A4FCAB9666F3D7E82FB50EF96C3F80F188 -:106810001AE65DB5448274BEBD257A15DD93E4F4B5 -:10682000D79A8127399E20FB498E252A792C2CED79 -:10683000896FF91841B8E106D92A42BDFF40F1AB92 -:1068400032F68B7E15DD65D71F94A10DFD2A074D0D -:10685000C168822CFE8D8CFE13F325D0DD7EC2EE46 -:1068600071E2BBEC7BFF73521A51DB00A96E3A1F39 -:1068700050045DF767E9EFAE469DECE7E2C4E5E45E -:10688000FFF1A75226EA6B45EBB412511F7EDC09DB -:10689000296F1CBB9051FEBB38CE3E1FE983B0EB85 -:1068A00081071E18C3B714D4CB9FC692C9BF7357B4 -:1068B000E84558BFCB9E37E3013ABF38C14AC828E4 -:1068C000E784D812F2832D4C25E4E5AEF55C18136D -:1068D0000A713F4D0F73FFD30F037CFF6C6ABA98A8 -:1068E000F2D9EFBC5924BABE33707E11F2D9DEDC86 -:1068F000D961CC57EC593D6BFF1406E7F8B004683A -:1069000072EE098FEC4FBAC7F62FECB4EF1DBACF79 -:10691000CE33FF8E8DB75D8D65543ED068D0FB07BA -:106920001BE750BDABB196CA471B13F43CFAF560A8 -:1069300012E97377633D3D1F0F6F0BB8FE3F6C4C40 -:1069400052FDDB815C827FD24D2026D9F385888F72 -:10695000F0D0BC1D78D2B6DDFDC30D4FB5A21F62CD -:10696000108F19F83E17FA0415FD573141C775BF4E -:1069700031C0E549267E27FA07048CCF35DCC4F305 -:1069800022EE11BCE71EBE65CBFF476D3E7D3B9AF4 -:106990007C30C0E07CA7765919E943A09523DDDC63 -:1069A00023240E1AC58467CFF9939579C947032E1E -:1069B000BA99D8C1EDFADB035C3EE9EB40447A9B1F -:1069C00090021DE9CD99776F955E8472B15710687A -:1069D000BD91DECA5CF4E6F4776780EBC110CFBEF0 -:1069E0008F0FD12FE7FFF8BCB2AD358897B522F9EC -:1069F0002D5BF095EBBBBFDAF364768B68213DAF7E -:106A000010C99F3BE9F0116122834FD7BE1F403F61 -:106A1000747C22D8FEA6AE00D2D79D2BB87FF1EEB3 -:106A2000C3FC3CD3D175254BA6B0F68B187E30281D -:106A3000957741698E3B7EEA9C63B85B4DE46823A1 -:106A4000F8B732F3DF6E9F74CB07396C9CF1874344 -:106A50003AFAD7B74E7AAA4761F5C27E81FC4985DA -:106A6000E1D4145CCFAA3F7C6F5CBF6B1DEE589DD8 -:106A70009A847A63FBA41F08C80785C77E2AE03E74 -:106A800032494BBE1228C0FC70FB7CB09C9A8D76BC -:106A9000C1A57989D770DD1245E9FF83F474B47616 -:106AA000DD7F62FF4E3CB2A141CF9DE2920F99E79C -:106AB0002AEE4A8DECCF74E67F17CE7F8476CEFC2B -:106AC0009DF53B5A1B5B857231139F99FDE65DB0C6 -:106AD0006CC4F1EFB2EF0F63F357822EFA2C4AF534 -:106AE000CBF89DF3FD70F1D7CCF90EFA894619AFBA -:106AF000EDF2413ED2C523FF3BF1DF0F02924E4241 -:106B000042FF544F20190F16E0BD7129AA33E948FE -:106B100079ED67E472FEBD63CC77C611DFC9E96227 -:106B2000CAFF18E5786D904854E13E678846B67D07 -:106B3000A03CC8E5E77C48917F540CDD3472BCBFB3 -:106B4000C81BEFDF0C3409B0BA553BFE01B286FE1C -:106B5000B07D5081FEC7BC2087BF4AE6F6E58C7D3C -:106B6000FA0E89FBADA4251117FE6CBF9D8F77CD62 -:106B7000E0BE09341DCF7F4DEF115CFCFA7E287911 -:106B800036E24989EB744ED6174B925F72A1141608 -:106B9000C99FDBC9E57F0324D4D3785C0670DE3A55 -:106BA000C445DCEFEF5AC7CF8DEB5A88E0BE2BA669 -:106BB00053BDC1D6531EB1F5FA876CB9FF7D5BEEAC -:106BC0007FCF96FBA55DA9056106D7776DF97FBFDD -:106BD0002DFF77A2FC67E569F7F5C3F72A491E1B6D -:106BE000985FF08D6DF16644C13D8D26BD7FA27129 -:106BF00005957B7EFF7C7588C177DF73DC1F7CDFAA -:106C0000E1319FC1F859DA140D81B5BFCBCA131F0A -:106C100067F51DEBC49D28577EDC98A2EF76A8DDB2 -:106C200012EA314799B56C2119BC66B68458FBC885 -:106C3000BB035A2D2B77B41E0AE0BCF33E2702DEBD -:106C4000D3E7F051F40F5FED8EA21C9B290691ADA6 -:106C5000F20ABAD553D04E5F27523FDFFCD565EA22 -:106C600002C07B1B5E84D5ECFB095784293FA2E858 -:106C7000FA97CDD5ACDD9697C394AF5DB1AFBFFBAE -:106C800021F67ED68A08D5CBBBFACD2DAC5EFA06AE -:106C9000AF4FB0BCFC71FAAE7EF321F67D712A4A8B -:106CA000EF67EEEE6BC2F9FA2ABDE7AF72FED031A4 -:106CB0006E0B836F22187B826C3D1E1352BD01F454 -:106CC0005B2CE1E73C0AD2C92ADC3AC66EEFEAA1A6 -:106CD000D07F0754235EE3BF7D217E0D2BB7E147B4 -:106CE0008C2E66EFE5F8B8BBF5C50BCE67EDF6ACBC -:106CF0005B4BE715FCEBD6717D88E10DE5FF84AFBA -:106D0000EC15AE76C989A25639ABFF6E5BD04FFC4D -:106D1000D1B66E59620A07776F18F5BE52EEB72CDE -:106D20006EABF1E439397192BF09C96D41D23F7937 -:106D3000BC44D652F47C06E37DF4B3C28D22D797CF -:106D4000127D01B73F46FF0ABF9F2D138E9D4199CB -:106D50009F77B46A5EDBCFE6B765A62207108E295F -:106D6000F6FD2C763CD269CFC6DFE9966FB2C6E15C -:106D70009AC00C2505E15ED537EE21D6CF072967ED -:106D80003F3383B89FFD68AB48FBDFE64A7E2E7039 -:106D90008FF14E37DE73E1F0559B21121F6FEB83AD -:106DA000349EB3D85659927B1AD2510C77719AAF50 -:106DB0008A782EED93C1CECFE945FFB81FFDE38C55 -:106DC0009E4A0F878E88E407F4E683175B5E7A108D -:106DD0001BBCE7F02630E5C79DBFCC2C9F213AA312 -:106DE0007DB6A617EF51388AF728A007C532A355FC -:106DF00063C874E2CA917493847EF8D28C73077767 -:106E0000D8FC7E8F7DAE108E5D0F28BFEEB0F38B69 -:106E1000EE5825067586979F598768FF9CD0D05DF0 -:106E2000458199C33C8FC2C9B7F6DFA435E33E5B09 -:106E30009CF2E60D5566E45D977EC2BCEBC341AFA4 -:106E40007FAAF7C74103EFC34B3F2719A8D77EE3BB -:106E5000EB33480E5A2BB9FE925E917707C697F234 -:106E60000530F0B9D3AF63C7BE13CC23BE49CF659D -:106E7000EF7398FC88745DB002D70B72B4E6189E6D -:106E80008FBE117E80FDAFE0EB5F550474BF4E51A5 -:106E90000C28CECFCA8DA7227FAF1331360EC76D17 -:106EA000790F6ADF33F83CF73322DD9F53DC6A9DAC -:106EB00086F3EC9D575888F4B139CCCFC1B4083C67 -:106EC0009FCB2AE0FCB023D24DF9A15B6A4568C68E -:106ED0007563B833B09FE5C19D94D782F0CE24BAD4 -:106EE00023FD0B6315C88FD61541BEFF1CB34E435F -:106EF000FF7234D4DFB587F5135EAF183B512E56C1 -:106F000079EFA99B1CE2FA5E20C4F73FC62F8110DF -:106F1000C6F93703E531B2B9107F33BEB280F60748 -:106F20008DEC2B27CE1FEDBD402C9ECACB1217FF38 -:106F3000EEB4E56DDACE5FB8C7DE471CBDE30E7B6D -:106F40001FD96CEF1FC5E6E26605E976054C473CA4 -:106F500095AEEA129667E1FF533ABC7235935F260D -:106F600065F24BCA7B6E75FC8A12CFFB8871BAE75B -:106F70003D856470DDD93E8E785E1F289750FF9B5B -:106F80000109D32D5786D303F282E634C4DF68F5B6 -:106F900092682891423D34530F3FCB5E972F0412E5 -:106FA00073B1BFE8BC7ACAE75915489C45FDCB6967 -:106FB00001E5E97CFC2E96155E4A061B05BC351FD3 -:106FC000075E900D3ADF75A3E4DC67EB3DDF051942 -:106FD000F7D766DE4F7BCEFFDE44F7D3B6094CE130 -:106FE000C37A8E7D3FAD9FDF4FDB16E1F6579B8F57 -:106FF000E7AD5D67E3E1F210BFEF75954DA7E7845C -:10700000B2DF7FE4F8BF52281BB0DDD8ECF78EA1C9 -:107010006685FD9D333EFBFB5448E1DF4F1A799CAA -:10702000B5380EEB6766D05C1D2A18C2D38C90B9B8 -:10703000C65DBF2164E715C909D22F4D99EF877A44 -:10704000D05CE76EE794791754D2F9BEA3F6F93E07 -:10705000F6DD7681F02A69A3C1BB6307B409FA564D -:107060009283BF62FA5F96F5783F18B5C49CA1B8C9 -:1070700094A327ED0A71BB97D1DB06A20F266110FE -:10708000EE30E85BF15E88F1780FB78EF6E7E17BD2 -:10709000BE8DF2F6ECBE5AD4A356FF58A2FBED4EBD -:1070A000C0D72A4677AEBC14E779E107E3C91E9E34 -:1070B00020256F0FB9F6E9C215030AD23BC25FC3A0 -:1070C000E1E7F9D442FA346E1700C573DAAE897B72 -:1070D000F20B33ED923CBCF780E48A42FA5D265C09 -:1070E0008E5DE1D433CF271CB0E908FFF431784F2F -:1070F0003870A5563625E4AF9990A47236E854321C -:10710000FBA50BD793F19F8E703687269E85F3F8EB -:1071100027E2EDA950C1BF1EDE1C3A2E4E9E3B4811 -:10712000C7D9EEBFBE3D142579DB7038B2D34FFB13 -:10713000C9D788AE2546D7A8F73A79330D60E7D589 -:1071400087A10BFD94C5C9463A277A94D131F62B15 -:1071500069FC5CAB0C5A02E337528CF3874F2ED399 -:10716000440DE3B3961FF51EAB040C94B5E8977479 -:10717000C35B194EBEEAA6BF1B0F6F2579FB854086 -:10718000F275C4EF8DA5961F353B971C7EC32D87E6 -:107190000508EBC87FE71CE3FB65555297911E1667 -:1071A000304E47BC2F8424D5CF078BCA0B204DE52A -:1071B00067F18A23D2E3EC730CDD9788EE730C83BE -:1071C000E7E12A9DBC0E1EAF2AB0E9106C7BF56783 -:1071D000F54B9B16B2F1D9E29B1897FA563DCFEBCF -:1071E000F1CF96E93C6B41FF1575182F82655C0F56 -:1071F00073F221F2EABC7ADA09F75D1DFED361FC75 -:107200002EF3DC9CA3AF65EE5B4E99A9AFE58587B5 -:10721000892F0CB3EF64C6171AF09FDC8EB5EDEB27 -:10722000448EFBDEF8CCF240E340EB5E57DEF941E2 -:10723000BCEF28EB3EC0E3BED1DE3FD52DABA4FBB7 -:10724000E50C4C9DEC6BEC3EE7E5C943F670627EC5 -:10725000EECFD02F9DA8C9AD407B7251FCBDD6BDED -:10726000F9004BCC9E735E76CDB34F63D066D113DD -:1072700006C7337D7F73EFBF6FE0B903F44FD8E3E8 -:1072800045EC38D97AD1F213BFDA7EB8778BB8BD26 -:10729000EED8F9D9E6DB4AF8EA0F233D0C37DF2FA9 -:1072A00085F97E3AA6DEA0FBF25BECFBF25B2638AA -:1072B000795C8686FAE45561EE8F5D1F2EA5386BEA -:1072C0004BCF5CF22B17ECF7915F7DCCB2A460B989 -:1072D000F645CCBF473FEC37997EA753BE7D19D505 -:1072E0007BAB66A9682FDC10A9A0B8EDC646C39396 -:1072F00037E2942DECFBA4CBCFD792A8D630EEDBAF -:107300005A57A1A2DD217DAE92EAF269159DD58C76 -:107310009FBFB079DA7905189F28E7F7935DCEEA29 -:107320004DA500D561BECF1E305E0E239EAAC3BA06 -:10733000433FB48EBE6549D3877221AE5563CE8C70 -:10734000F31C6CFA62CF49BF7E43495E13C67EECE4 -:107350007BB2D62BA9B2B5E5784E9E091CF417ABCB -:10736000DC5F8874D03A6308EEB5367EE7D9E33245 -:1073700081243EE25A3F25CED76FBD082BB2ADCF58 -:107380004D61AEDFB46AA636221D69F2DF3CF78795 -:1073900056C678BE7E8CD1918B9F4FA477CE4F95E9 -:1073A000E1442BCECFAA86B214CD3F4CF287BE93D8 -:1073B00086EEB18C87CD0E6CF78B5C3B4FBA88E7BD -:1073C00043B3E7ED3924FF5224DF1D7D70BDCCF5BA -:1073D000B9D1EA837917AC237DF01DC65A649F7D2D -:1073E0006E1DC9ED753E5543FBB477BE4C71ADE8DB -:1073F0002970B9DB6E91225C1F9422DCFF8DBF9354 -:10740000909EC2F51E3CE7110D4137EE0303137841 -:107410009EE97AD8517B0AC1375973EF675513B883 -:107420009F614B757085DBDF303797C7CDF6E65629 -:10743000FD29CCCAF270BA1A59F30C0DFA31AF0615 -:10744000AAF97932A1889F27F381A1727EADD1F08C -:10745000DE500192741E6DD8F503EFFDA20FC8E94E -:10746000E620E22DC6EF59896C1728794FEA32BB26 -:10747000F14C4F73EED21F8709DF0903F9BB675642 -:1074800090ECBDF77A14B23FDFBB067ED785755FFF -:107490000E586CA99E12C5DF3DCCE63BC0987527FF -:1074A000E68169FCFDF4CD02F9B39EFA5B703CD233 -:1074B000BB1105117FCF6211D32778B22084304EE3 -:1074C0001B5D00DDE7E2F73D61C29F2FFEF3735EB7 -:1074D0009E41FB4F489C83E7B7C43B71FE8FC6219A -:1074E0000FBF9FF1D76A094A86F4A1AD5AF210C2C4 -:1074F0003B1BAC153DECFB2D0AE7AF2D794A1AE397 -:1075000095150522E921E00BA527B3F78BF6BD5CA5 -:1075100083F99D8BE64CC796383EADF7242D79183C -:10752000E9AF465B5293CBDA573EA793FC3D2F7EE3 -:10753000FD5EACCF3ACCEB3E3FD7E3518F719F134A -:1075400058F4C1449AD7AB61AECFB6C6CD3E5318FE -:1075500091AF32EEE5F59E3370E8806DEB3AE6A729 -:10756000D3BF75A28BA44F1CF23FC11CC33E8FE258 -:10757000D083297C1C7AD88D3C89F217F3CE6243E4 -:107580007967EB6DFD6DB4796799FC9477814CEB6D -:10759000F00ED3B7300FFD443EB99EEEFFCCE4278A -:1075A00007CE8D95793194C30EDF68B36F22B9ECA5 -:1075B000BF42A1FB4C1D3E72F86756CE201F7D13C3 -:1075C000E5C5B2B0BE90A76A98E0E6930B4FC257EC -:1075D0008B60606F8CD517C960E530117460EE6BFD -:1075E000A5135D7C9289CF45F30578D1230779DD1A -:1075F000856F6DF01EE02C76F270EB7248D6DB6280 -:107600002E3E6DB7CF99758806E07ED49CBBDC8892 -:10761000CCC47B277357213F6C121229E487C8EC36 -:1076200037425731BCBF37866991E83FD4973F4C0A -:10763000FCFE4288ECB22DB356527CEABD6B9293AD -:10764000707FD9C0F0FE22EDE7E9B122E5DCF68FCC -:10765000E5F9137A9C97C9387F0EF6FBB45D37EDD8 -:1076600076FDD48EADAF476EEE8B723ED817E5FB3C -:10767000D406A553457A1828563577DEF2B9F6FDBB -:10768000C2D746ECFC97632D3AC629AE8D08F67931 -:10769000BB2ED25736343E4E657E5D1A304F2E5883 -:1076A00066E9A857A81F2D10709F85D379DC1D9F10 -:1076B00037B9F4B58B6CB9ADE2BD406CDE6AB3A5E9 -:1076C000BBEF9D554521EB7D41FF15E5FE5FB519EB -:1076D000E8BDDAFBFF283F21BFD410BE8CF5E64E93 -:1076E000FADD9840377F1E2B35852B5DFDC6EABA43 -:1076F0003CFBA32AF6CB640F358066A17127F7D730 -:10770000A0DFAD6369B013F39633E908FF5E74D16F -:1077100083FAD185A417C121AE97D694A844BF6D32 -:107720000DCA0EF4EBBD1BABA63CF5161B6F99F30F -:10773000C1F83AD3F4C84F66F9799CDD9AC2E3ECFC -:1077400058C7383B961867C712E3ECF81EE3EC58AD -:10775000FF41A349758CB7631DE3ED58C7383BD68D -:1077600031BE8EE5E38D2BA8C4F809BE7FA2B1819E -:10777000EAE7DA7213CAF8EF7C757C4D31313FEAE3 -:1077800027F6FAEC3197AEF825FA01216AE07E1D62 -:10779000D8DFFCC27FD975BAFF3A5E928F7E4988E6 -:1077A0008980F184F6F836A6630ECD2F20DF0A3AE1 -:1077B000C5D5AD1598D7B83372E03C99E90FA5F15E -:1077C000EBABF3587D57E4B976CC233D556FAADF78 -:1077D000E1AAEB918A958F6843F549E53BE4207B6C -:1077E000FFD096E7DB510E04625CEFFB51E437E714 -:1077F000353192E82E618A0DCAB162258D748C678D -:10780000395F9C8CF3E07ACB67A1258E797C9374E9 -:10781000A502F98FB5EFE6743FBAF63F89E8F43C6C -:10782000F3BB91DA8995A36A47E770876B87EF8589 -:1078300011FA698316AD8FC1BEC9C7F757AB80FB7C -:107840007F3B7C9CEF3B02BC9C98E3E42F54DF120F -:1078500065E52D51BEBE1D017E0FC1C054917E8FC6 -:10786000071A84CF633F5F2D040DF31F2BA696E408 -:10787000A3FE7FC8A687C993227CDFFEBF2AEDDB6B -:10788000E74F7AA8358FD5277FDB30701FDE04469F -:1078900010EF71B5368B944FF4FDCA53F296B0E6F3 -:1078A00067CC7C2C0FF5DE0A5BEEA46DFBA4A9ED82 -:1078B000AA49681FBCF72C977B47EC7176F8FA52FF -:1078C000B49E33C3749E02A093F492A6B84CC10C2C -:1078D000711C2F159F7629DD93D9A6D0BD4CCA8780 -:1078E000B355F2A77EE0B7EF25EE237D450924B519 -:1078F0005CF6BCD312C9FFD0A205296EB3295C4146 -:10790000BFCB6095CB140FDB54CEE33AA1C8C5744E -:107910004EEB9B3D016ADF1656291F385DBE7B5F2B -:10792000750C4B51C37D3F6D2EA5FB2A2D4DD428E0 -:10793000AF98FD8BDEAF8A919F6713D8EBB28AC7F1 -:10794000217C63F753BDE5228DFA073B7F9F542FBF -:10795000117F2722D1E3BD7F76E0E767A21F642570 -:107960003F9F324D5BDAF3247BDF6AAA8912C60F90 -:107970006DDA3BBD21AC5F06142F0D4D7DB919E3C7 -:10798000A9AD576A06CFC7E2E721C0BEEFB8B57C04 -:1079900059CFEFB1FFFA104C36B07D8D8AFC0AAD9D -:1079A000F034DE4F5564EB33A1DC0A01F5B1B63A91 -:1079B000BA8693C1E73D47D09AF71915E9465A941C -:1079C00047E3B481A9627BAB4EA67DB128AC76A318 -:1079D000DFA0C8F63B38F2203FE53A4FC0FE57B86B -:1079E0004AF69C37187BA5B75E9071DFEE9936FD9D -:1079F00064E22D739EF9B14773119EFC557432E217 -:107A000004F86F8D552CC1798DD37A851D9564D27C -:107A100068BA86A986A926773EC62785775A796BE4 -:107A20001FD2C3345D069DE1E54C1868C6FE37D908 -:107A3000F4DF51ECDD9F0FD9760DE3D3ABA3980FA4 -:107A4000D52082E5EA1FE31D960B9E533AF23CF5E2 -:107A5000C99D859EF653B69778DE9F963EDDF3FE70 -:107A60008C5D159EFAD4AE799EF6673E5EEDA94F09 -:107A7000EFFE8CA7FD8C7D4B3DF5997D977ADACF93 -:107A80007E61B9E7FDDCFE959EF767BDB6D6533F34 -:107A90007BE0EB9EF68E5E9FB96F5E11FDFBF47985 -:107AA000FCDD1FF7B9E24C7BE1847B743E6AD13187 -:107AB000FE07517E6FAE8CFB3BABAFFD1AB7BBD45C -:107AC000730C1DE5CD25365DAECC33AF43F95A15A9 -:107AD00055699F90C3BC9D1C3E8FF49189DB999C96 -:107AE0009A41F6D8E0FB10CAEB46EB9C5297BF2AAE -:107AF000A07502E68155456BE9FE40E77B593301ED -:107B0000F3E32EC12486023C766A51BB80CEBE7759 -:107B1000CD8BD97F7495C400B30F51AF1FB4FFE470 -:107B20001C8AFB32FB8FEC4323C8ED413826D17B06 -:107B3000E39B02607C9AD977641F3E1A66F6E17473 -:107B4000B4C7FA37A11C1AF8854C7144F647F65FA2 -:107B500025B3FF36E6BAFDE0FDC558A6412B247FCC -:107B6000B8D22D8E2D267BF036A4E72FAC7B760580 -:107B7000F63BB592DFB3D731A62E8E7A72477117D6 -:107B8000F1C940B1CCF7213951E6F6EFFDD45EEFF3 -:107B900090FA7DB243D93A905C76D66193D09FC675 -:107BA000FB0CADAF05C9DF3DF18FFE43C86F6A899D -:107BB0003A1EF3008D3D8A89E3DD6AE3B9449B5E9A -:107BC0008D3FF3581A5FD28BE5A93AD347585956DF -:107BD000B6B517CB47A22534DEE9C623D52863D432 -:107BE00073B8DF5A9EA6A49B05F4373338B2D81D6C -:107BF00083FE89E8767E8EBF547E05E90FB5FEE3ED -:107C00006C0A55792AC58D0348170295444F0139EE -:107C100044FB4B000FA3627D8E90C65017EAAF98CD -:107C2000175A95B79DE8C0D16B51DF4D72FBF8A78D -:107C300088D7589D77FD43EA0F084FADF6EFBC7526 -:107C4000E4EAFBABD9B81D052579E8B3457FCA1234 -:107C500097FCD963EFBBF7E6881EF9331B731466F4 -:107C60000EE9458C1FB68BA720BC098AAF07F64BDF -:107C700064CF076EEAA4DF570D68960EA4FF5B3A47 -:107C8000F65B53524FFEBFBFC42A480F0E343C95DB -:107C9000156F817E09CC19C3E3337AEA1DA40FC0A6 -:107CA00098A08EFB6C432C68EEC8621F7C29C2FD35 -:107CB000671B263AFECC049D7B6D437F5B18B7366D -:107CC000557C84F573C32F0A76BAEF87B8A180FB81 -:107CD00027871B3FC0ECCCA40BBE0DAC5F94E36DBB -:107CE000C796D4D2FDAAB8CD54E2B9D0F21DE4A70C -:107CF000B7EDA52FD978BD36C2F1385181053B507B -:107D00009EE431FD88A1B4CAF6AB38FE97780E8F99 -:107D1000EB1B1648DC2FE773F62DF138DE4BA383FF -:107D2000AECCB2AF00211598EF6BECFF7AF07CE09F -:107D3000291DAE7D0E703FF0D6A76CF7D64F4B7B5A -:107D4000EB4C8B7E1EF5806500DCAFB1CBFB3E0CAF -:107D5000A60FE32885CE7DFA097E5E506510207D52 -:107D60009777A57BEE66F34B38F75E66DC9F3F7531 -:107D7000779AF497C54C7FC1F799F7BA171E5EBD85 -:107D80001AF585C28C7DB4C22791BF01FD4486CB14 -:107D90004F3449D33D7695E3EFC994EBC1C35B8182 -:107DA000BD217B3DE9C7FB51B572F42BB417DDF261 -:107DB000C7239543FE957639F5EA11F25F32FD2B24 -:107DC000C6FD1FE897BEE1175FF9F311979FF2ED2B -:107DD00068721AFA336E9FC4BF77EE4F75CEF5BD49 -:107DE000532BFF4CD0391C49171C379659E7737534 -:107DF000254DF76738FE15C78F70699E790BF2DD48 -:107E000026E3506A0FEBB7FA377EC07E164AFBF7BF -:107E100035A2BC9B2053BE88367BD5BD41F467E2BA -:107E20007B56AF2ED6C7127F3CE3237FC27A9BEFEF -:107E30009DF3A98E3FE6B3B61D707E8EA3475941D0 -:107E4000FB5C4610F5E43376B135F4EC87DC1FE8D3 -:107E5000F8FDA67679DF9F8E47BDC9EFB983F29B07 -:107E60008CB93CBF694C7DBA17D7F94C7B9D316EFC -:107E700055356B287E3AF6B2742FEAA1D3EC3CA5B7 -:107E8000F2677E463FE50B5211E5279D3E9EDF4B94 -:107E900064EC953DE742C68040793E639E938C3406 -:107EA000EB67DA13DEF7E5E0AA17237CDE7A665C7F -:107EB0008AA95B6F5F21E0EFA2A60494679B2F6302 -:107EC0003602ABAFC8B1F38B4E8553916E174A6142 -:107ED00003EFD15BFB2B89F214FD47A6FC1AE3A349 -:107EE000F02CCFABD44EE1F156EDE792C1242068DF -:107EF00021983E3D3C14C7FAD67103EFD41FF48F8E -:107F00003DC0D61DF7A10799DD5FEA433B5EA37A2A -:107F100017B3FBB1FE28B3FBB1DCCDEC7E7CFE4396 -:107F200066F763FD7166F763F96366F7E3F3279815 -:107F3000DD8FF5BDB955E48FEFC3FB8DA6E0EFDA19 -:107F4000EEA6BCC6F5AA4F43FAC99467555537A8A3 -:107F5000CB187E378617521CA57A21CFAB6FCF592D -:107F600048F6F4A09F2EC3CF39E4B7EB171CBF1D12 -:107F70001E718EDBF6ECA0FF3369D0FD0527EFC73D -:107F800074FA21FFE909FDD87ED437BFF6DBEFB4E0 -:107F9000B057AB676EEB0896E0B99E147F6FE7159C -:107FA00066FE9ED6EADD4D94E7A78C7B2E85EBBA64 -:107FB000BB324CFA06FEDE12CAED4C3BD1B10F3398 -:107FC000F571A7CCDC0F33F36022B65E72B2BC8CC5 -:107FD0002DBE14C5ADAD26265F70BF684C9FF3B2B1 -:107FE000EF44BF6DA1969771BE99E75DF9F7F17CFB -:107FF000BC0E486AEEF93BE71FC8E62BE1FE43B72B -:10800000DF36589AA6FB19826193F44581E991A461 -:10801000576A498A03B60FF3BBD9AFDA72A269DC9B -:10802000C5B4DFB73FE3237DABC6CE7F6B19A75244 -:10803000BD65DCAC389D3389CC52FBB3F4B336520A -:1080400032E2FE2AB1FD5F1F61FF97FCFCDC574B5B -:10805000EF5C15CF47758497F7A1DDDE118F91FF97 -:10806000BF67DC2CCF3DE4527C0EDD572185B99EE5 -:108070002DC555D2B3659C7FF9507BA7DD9E1CBEF4 -:108080008F3036273F6620DC49EDFC72C2447F8B7F -:108090003FC6F38CFD1A8F17064B4550B39CC7782B -:1080A0002287DFE3D5519ED4D0AFD31197E95C4747 -:1080B000875E315CBC95F4A2FFCD113CF4DB62FB22 -:1080C0001D5A5628A417261A72B59A7C3A97308002 -:1080D0007CDE116E5631FEAA8CAB1CB15F45E3FD10 -:1080E000FE7FA3B2F95D0080000000001F8B080036 -:1080F00000000000000BCD7D0D6014D5B5F09D9DF6 -:10810000D99F24BBC924BB9BECE68F09241A34E019 -:1081100026240134E224048A167111D0D052D98069 -:10812000282A48405B57ABCD8604842035F853A9F4 -:1081300058BAB160ED57ADD1D296D7222F28F2FCB4 -:10814000414DD52A58D400D66A6B6D0469A9FA3E10 -:10815000BE73CE9D497626B34950FBBE872DC39D85 -:10816000B93FE79E7BFEEFB9774F9D823F1730D630 -:10817000BA27456595F05CEA88A71431168E966794 -:10818000D74F60EC1B59E1CF32FC8C393C8BE49823 -:108190009B313B636A173C4F69EDF4A75716188370 -:1081A0007AA2FCF329EF7A077FD79F62FA661681DD -:1081B000F6AC587AAFD7C5984D61C2291B94995B2C -:1081C0007EEF6C467F4E89F8774F20EC49DE8FC7F3 -:1081D000F58B29EF4E18DC6E7959AF4354185BBF0D -:1081E000AD23CCA0FCA900852A843BA6E6C1BCAE89 -:1081F000DFB99245CA18DB28F5B8648063E3E7C2AB -:10820000C270D9E0FE17E37CAAB057298670C21F5E -:10821000DBA973E06F85298E6AC6F2F0CD687CF227 -:10822000EF30CA9E53D07F7937944B3578E0FF13F7 -:108230009E3596AB7A8CE589078C65C642F6F03898 -:10824000C65E6B864ECF646CCEA10F0EB174C6E6CF -:10825000C642CF3CE9632C577585E33263F358E897 -:1082600099B7A09CD790C6BA4330B88D2DC57581FB -:1082700069BE510CF035308295E52D4D65CC35D079 -:10828000FF7C3993D6A9A1B771261BCFD8F76F69A8 -:10829000650CFA89D509F1ED00FFECFA6DB3C7C0A2 -:1082A000F3FE4A5BC143D828627F17E7E782CE4ED0 -:1082B000C17C336D2B478D86FAE1A969422BD4FB33 -:1082C000FEB967AD2F8672CFF49210E21DF0F56E05 -:1082D000FF7C00FFF3C2BCBD3EFECB95C7E68E819E -:1082E000E796CA2766E3734E627DE86FD6A4CE1682 -:1082F00007F477C932A502FB0BD71BDBE7D518CBF8 -:1083000000399F0FFCCB9B3518DEE1E0318FAFF7D2 -:10831000777FB342F8679F033D003EC3F809DA87D1 -:10832000A53E290478CEAD11D438D04D9E2AA89D03 -:1083300016FCD0AEF18319FF622C83219FD5CD139B -:10834000E3ED5025D76527FCE7CE14E20A8C9FBBEE -:10835000B4AFFB14942F73D9E3227CCFCAEC12F094 -:10836000FBFDCB18EB2822F0D26B13D6F77ED71A81 -:108370007B217C9F1714990DE880D58CA1F1088E84 -:10838000D1848F231C1F2EC247DEB2D0333F82F12F -:108390002F9FE49445A87F7903FFAEC3B751023AFB -:1083A00083EF1B81CE624467D29144FCCC39B47C0C -:1083B00039D2E31CD3FB62A88BF3FDDBE403671423 -:1083C000025CCB858E1969004A8ABD89315C68C020 -:1083D00020D2B5CE8F3A9E96EF68217E4CE033FBDB -:1083E00029E467FC7736A186F8EC29D72F65941B22 -:1083F000BB337BB73020E1AD328BD5E733F69FA995 -:108400007D670B50DE2E5FB66EDDF9F03DA5EFE720 -:10841000AC9C31A7F39B336624945353AFA6B24F61 -:108420001B07A610E3EBDD3F2ED1C75F650EDF060D -:10843000956D12A12CD9E44DA1A2817659D84E1880 -:10844000A25D986D922CDAB9F57680A7B5B07EA9B9 -:10845000DABC52B5EF360D9EC4F125C49BACB8050D -:10846000580F69BA2423BD7C5938B2879B77846D35 -:10847000B28F19DC0EC06ED1E1B759C31FC7EF89A7 -:10848000E3DB8780FFABC6C770FD39B4EFA70D1FD4 -:10849000545F9D9D7CBE08971DF595A2B86D09FDA2 -:1084A000DCB9E75F2F9C03C42BCD67A114E843B26E -:1084B000AB7208E8BC4CBEC7859D4B99F57204F8B9 -:1084C000613D945578BFBEABC3A5C0FBB2E2BBD63D -:1084D00021D19775A7329407E3989CF908F43B4E95 -:1084E000965837AEDAF97B6D69506617B35009F4C8 -:1084F0009BB12795E44966D1B93F1160DCCC4C971C -:108500008AEDD332AB7FC2883E982225E023ADF6B8 -:10851000B5BA34846B360B212B4A429CD522938DFD -:10852000051E8272E6B46DAC1ECA157FF32822F2D6 -:10853000B4C4F55D3BB6473DDDC6F6A17E096AF2DF -:10854000679D43DE44FAE35A89A1FE481B778F807A -:10855000F0DC0F5D89C097656559B3EBA15CB6DFB0 -:108560001652149C4F875088F30988A4B7747CEA8C -:1085700072A4E2E36ECEF463597C3BC0DF668F7772 -:10858000A3BC8A4DBE5CDE0EF0E45E9920AFF1AF75 -:108590003EC001C2FBE2A5DBDB8B90BEA57713FBDF -:1085A000CBF838DE8DF28CD53684B1BD6FA66490E1 -:1085B000FFA99A3C4B35E981E62C3BC9335D1F305E -:1085C00055526498B7A0CD9B7D2F4CFAC0C9422E5E -:1085D00007D92B0BC80E1158AF702A0DE68F151155 -:1085E000EE023E8F41EDAB797B1608B9D0CE71A675 -:1085F0003635617DF898D502C815AE4D55513F0B03 -:108600000EE60A56C0BC6D2CD20574D2223009CBBE -:1086100003E375331CCFE94A6B43BBEB2957AB0D22 -:10862000F1D7FA2CE80F98C7ED76D6807641AB1CCF -:10863000726541FBA866BFAD2A1F9D83E50CA0EDC6 -:108640001EB41BA4B08C74B9CA5F9CC3E07DBAB7DA -:10865000F79B2867BF96F9AB19AE0290A37550E758 -:108660005C90FB9B1E5B17AB81F14EE63125C1CEC2 -:10867000734A4D0CED29E7C942C3FBEE6698D199C8 -:108680000365D56DABC771AECD5408AFB54C6EC3A5 -:1086900076B5800C25615D9C27834C9960D57FBEA3 -:1086A000E17D37D8498A7324FDA731A534B1FF3164 -:1086B00049FA3FC3D4BF6CD9FF40BF5E43BF6B24B0 -:1086C000467674CCE7A67537DB05AB33EB5664A270 -:1086D0003DEA644D5D1676674BA68DE0BE3DD0D475 -:1086E000A342FB3A068C0F7472C1E7474446F60C6E -:1086F000AC14D00BCB97FAFAE97834D6E3F46B8B51 -:10870000090CE5D20592DDC0275398B16CB68B4AAF -:1087100060AD715C9BA7B207E967953F55715AC080 -:10872000AF3F7B9AD994E212986F6A7829033EBED4 -:108730003F739F6B4D00CAE99C4E1ECEFCE30CF4C8 -:10874000177A044E7F6B7C36C24BB82EA7534CE889 -:1087500037EC60252817C348DF6E0E0F8EDFE3CF9E -:108760007FB0DD627C10BB06FB61B62A4C294E98B7 -:10877000578F6607F78F3735AF13F9A07F3C27ABCC -:10878000A2F144C07FE278D95F6CBCDFE3FCCA068B -:10879000C69B3DDD38BFD90E99E6375BE35F7DBCF4 -:1087A000DFE3FC8ABEC07838BFC4F1BE669CDF6CD4 -:1087B000A74CF39B2D72FAEA1F2FFB8B8DD7D35C4E -:1087C0004A76F0ED0E904F4027A9E53B5C6360DCF4 -:1087D000DB5D76595006DAD5D6DEE09A8BBAD73D06 -:1087E00075BA1FC6A99B069573B197A9D36B8B1950 -:1087F000DB2470BAF8EBA63FAF43BA383E73552975 -:10880000E913CDBEBE04AB823EBE44E2F0CECA77D1 -:10881000C75B12F0783FC81115E07800F85D057E5F -:10882000DC0A7C89E57873809E0F82BD8ECF6D0057 -:108830002F7E7FA83944E5879B27D153EFA7741279 -:10884000B7DBC7D658DBED676471BF6F53509E7FAF -:1088500025EAB5DAD410EA4536E93CA626DAD5ACE5 -:10886000E9A914F8BEF132568EBAF18CCD1C6E5FB8 -:108870007D36D9EDA9E57B7B9AA17CBB6457502F4F -:10888000DFAEB019567E7311EA992AB457797B7618 -:108890001EF7C37CE1DEBDA8F7E6A09D0E78F5CFFC -:1088A000EDDD8BFEDFA56097935E6687F7BE05DF83 -:1088B0005F03FFAF1DCBA29BC9509E35C74FE3C3DB -:1088C0009FF4DA6CB4DFF99FBB671E23BF229CC202 -:1088D000F5828FCD7E660FC21B722871EA8FDD1B79 -:1088E000463E50ED4A3B8982B01DF5B41FF5347CFD -:1088F000AF3DEC6436846F9A83E4DADCB946BF613D -:10890000534AB78CF6CFA6721F6B81FE2F9D69FC70 -:10891000EE74727E0B9BFC8659A6324848EE778B2C -:108920000B32D0DEBF1D5F4D1E8CB7E8A196DBF782 -:1089300026D0695E96C747718033D81928CF4EB0CC -:10894000B23BEBF1637E16192BE6F6FF6C8EDDBEB3 -:108950001750FF32CABD2AA46F2E3706F307876768 -:10896000B256EFFEE69E29EF960CC0972BC505D4B4 -:1089700003794BE17DC27C255F5C407F87898F94C2 -:10898000A37F639EC7FDC2234166319EFECC65D2A4 -:108990007B88175C4A94E7E6F94E1E34DF9A978B82 -:1089A00099153F299BD09E9BF5AC186A5106F0A102 -:1089B000CFFF7F9AAF8E6A7A86A93ED60DF4F23247 -:1089C000D07B3BF76318DAA93ABD4205B29F2EB9B6 -:1089D00004BE235DA86A01E2F3E5D17DDBAEC27679 -:1089E000203B5AD1DFD5EDA0EE8336B483BE68BFFD -:1089F000975CEB207B8BB17AF9BDD281FE92AD0FF3 -:108A0000F6FB5E82FEECB713F14FB526FA10C69660 -:108A10005080EC819BC13E467F3F5AFF8194CEBF80 -:108A20001F49B053F1CF9184FE5AF7FC4C5000AE71 -:108A3000CEE6AE29EFDA13E4C552D9B606EDB99603 -:108A4000B84071886EA807F6C0E8A58AAD0DF07F22 -:108A500025F683F46992EBA3DBA09F443BA566AEA9 -:108A6000FC08D0435B595D47089EEB37F378995E6D -:108A7000BF3F6EE68B917F6E674D4C00381D29DF3E -:108A8000FB712FCC476D9558CA1428DBB9BDC3DEE6 -:108A9000F2905C10DD4D3FC5EF8118C82D9C775DCD -:108AA000D363588ED958B8159EF7A5F1F651C9254C -:108AB0003B431827699B81D3CF0C46EECD02FCAD1A -:108AC000C94E2539E878DBF320CA294766C552B478 -:108AD0007B1644BF1BC678A4EC650BC316F4B540E7 -:108AE000B31FE2593CEE72C8DE5D900970D706EB09 -:108AF000E2D8EFA0FAD1EF517F53446B3B6CA7D67D -:108B0000CF169BB55C785CFB7EF9F2273E7808E6D1 -:108B10009356EC0E21B9AD3F87ED106C83EBEFF26D -:108B200047BA12E1482996258A83B2AEC968CFAD0B -:108B3000FFEC81AEC700E5599FB949CE66899EB862 -:108B4000506468BF33AB6A70FBDDFF7A3D80EBB3E6 -:108B50003B85917E65EC850BD19FDCD85F6631014A -:108B6000E39C995A39F6F085AAA1BCF8C25A2C2385 -:108B7000ED02514EBEFBDBEB63D85EE06516FB0EEB -:108B8000AF6FE7F573B4EF532EFAF02777A23EA844 -:108B900076901FBA51B38374F8CEF38A443FE779D5 -:108BA00087C6E3414D2EB8468EC7835678DC1D54E8 -:108BB000DFC4F729AC4B403A4EF9CC7523B6FF61C0 -:108BC000330B5F09B06F5176FCEC4E85DA1FB6C2ED -:108BD000E35941F508B6772D3FF2933B010E8F0E16 -:108BE000C74476631238FE32D47AEEC8E6726E9EBF -:108BF0008FEB8D2CCDDE74387A02B3E12957FEE07D -:108C00000619E4CDDAA2AE06ABF8F309AF8DDA654A -:108C10002689B7677839DE76E5843F4538DAE42778 -:108C20005C387EAAC0C2587FC3A45E2624F47BB6FB -:108C30008FAF03C06DF342BBD4C94C453AF3304FFC -:108C40009C019D792A39FC1B02AF3105DA794AE192 -:108C5000E9C6F7BDC4FFE87270A106820ECA0E8D88 -:108C60003E32EE6EBF10E9214BD4E92DAF1DE9C5B0 -:108C700061D3EBE75D84E5CE2C5E2EF7E5B5C7F258 -:108C800041CF38A00DCA855C07D93BE6F9E568F00D -:108C9000B6FB55BFD76F814F672FADD3C6718E50CE -:108CA0000CD6758AADA761317EBBC84DF61ABC6F74 -:108CB0008827CC7FBA4687D3BDDCDEDAF82F57434E -:108CC000DC623D92D1E978EF69D3E978AF359D9EBA -:108CD00083F84FA0D34F98359D565BB5073A9D68F2 -:108CE000850F735964EAE6460050FA74FAC377A216 -:108CF000B6FA7ACDE6C7E039E533B7E4853AE2194A -:108D00008CEC449B8BCBF701B91F9986FD4B7213FA -:108D1000BD17DD61DAAF79318BF73FA8DF89D59BCD -:108D2000516E8DA0DF30CEDBDCEF282F8777CA4570 -:108D3000EE48DC02EF27BD12F74B7D7CFC64FC5251 -:108D4000EAE37E73527ED1E93F271C413886E397E0 -:108D50000B06F865E9C8F86507F14B5A19E797B4AF -:108D600024FCC2624EE28FB545BC7CF3DD3EE28757 -:108D70007EFE899518F9275662E09F69F794507D29 -:108D800073FB749CB7055E625E7D1EE1669C877A0C -:108D9000B6DC2692BDD1CB504E75B2BE3D4EE4C37B -:108DA0001A21B41DDECE8AF5D4BB14FCDEC3668363 -:108DB000FDB14EA3FBAD080FFA43D55A3C4BEA6117 -:108DC000977A06F3B1A7B2BB349280FF020D8F975A -:108DD000F9C277E2F89DAC772CDAA5C9D6E91E0D69 -:108DE000DE1B03EA3D56743E9CDED9897AC78F4F5D -:108DF0000E77D667AE269403663E9F72FD6F3F786E -:108E000068887E7EA5C1F1A8F63C0DBE7FD46BA517 -:108E1000A783EA2F4C7C5F298CB6E4FB5F59B5072A -:108E2000BEFFB5153EBE049F3F65C5E70F7879FFCD -:108E3000C3E159F2713C4BBE2F87E723DA3ABD7983 -:108E4000FA787E33099EFFE8F58F08CF4792C8D79E -:108E5000A35E82C316C37D01E477F4DFD74D8CF5A2 -:108E6000E17EA8051C7F4DECC7A5F07EC0B4FF4491 -:108E7000003A9FF2E9BA50C4822FA1DDB144F8F55F -:108E800076F77865CD8F5056A25DBDE5EB6EDA4F73 -:108E9000003DF80FEF572BE76D3E0B793CC5C6E55B -:108EA000D065771F5E8F719A2FD17FBA55FFCF693A -:108EB000F4359CFE2F4AD0FFD88F59DE75321E4FF5 -:108EC00069F747F27D84AFDE0B513E6DBD254B4007 -:108ED000BF2E5FED16D0FEF76BFA65A397FB337AD2 -:108EE000BBAD52B72061FD2659880986FECE18AA6F -:108EF0003F331C00DF5884EF329F7A163EEFF1F6C5 -:108F0000DB7BA7650F5507D40A6C0F72BA12C757DF -:108F1000CF34CA697D1EB67017EB45FD02EE77DCD3 -:108F200082AEFC9ABE847ECEA77E34795FE5D3E91B -:108F30008AF777BAFA06E09BAEC137039F66F8CC92 -:108F400078190ECE9B104EDEDFA5897026EB4FF709 -:108F5000AFF575227D9A10D75938A0AFAFC0FE5C2F -:108F60006B6C31E61BE05F5D5F83644AC5FEB7381A -:108F7000781C75CBB2BB6A31DFA0F356B91C519295 -:108F8000BB94EB39655921C555AFD1FA35C3DFDF45 -:108F9000DED1357642198DBB1CC7BDA08675A3DC1A -:108FA000C8403B81E20FB284F1852C674700E3B2F1 -:108FB000EB858E8645A8472F7493BE6581B996F1DF -:108FC00029FDA9C79FF479B340E530F55BA8BE9CA5 -:108FD000D6D18476D288EB3B3B2CEDAAEF6B76158D -:108FE000CC6FFD90780DF828BEA5E377F0387CFDB6 -:108FF0006AC34D02E23BB50C8604964C0D77D066F1 -:10900000ABAD38CE7AD17E2A057AA1FE5EB38CFB59 -:109010000DF4B75687EB01A4C72F0B975E2FF97895 -:10902000BC1EEE9F51BCC3CDE5167D80F2B167BD7D -:1090300096FB07FAF3F666599540FF1C93950C8C46 -:1090400017DEAEE941C642814B3DFFFE7A03F3884D -:10905000F378A7A97E9471BA670117D97718864F5C -:10906000A49B577DDC1F6DCF0E3FCBE56328847436 -:109070000DE5E711FFCC05650F95F75359EE2FBFAE -:1090800044F503BC3E93E511E119DAFD81DA49FDAF -:10909000FDBC41FDBAFBC73D48DF7DFDE53FD2F792 -:1090A0007C5E7FA4E324AC2B9F7F8F48F3FF445268 -:1090B00033707FF4B2E8628A13CD8F5E43CF75CDF3 -:1090C000722DC6E35E6AEE6B6B83E765F317CB68C0 -:1090D000F7CF5F7237EDDFEBFD5F827E05F2BB22DB -:1090E000CD20BBA8C816DEE61EE0B70138DAB43CD6 -:1090F000B3DE7AA42397CAFADACBA1FDA48FDBDA18 -:109100000C794E1D943F93A2489F26C6D57539F819 -:10911000A143FD94E63F723A36CD97B1BD30FE27AC -:10912000EEE2788CE8BA4EB6E2177DDEC9FAD7E7F0 -:109130009D4CCEE8F8D3DFAF2FAE9079FE4FDC80A8 -:109140009794927ACAF7B944D0E0F4B8347EE3F544 -:1091500066C1384F94117D2848BFB3343FCEAC1759 -:10916000F4713F74448AFCD80EDEDC5A6181DF1151 -:10917000E2ED40F3D270BD1DE571570AEDDF339982 -:10918000E2FC7ABD8624F33FDFCFF50873AA349F53 -:109190000DB765C4D1EED8D0F82B19832B69E33E07 -:1091A000A98AE153E83BB108E5CB6D1ECAC76868E0 -:1091B0003C51D592D0FFC2A7FFC385F1DE8671ABCB -:1091C000FD187759C8A44F12F31DCCE33644AF27DE -:1091D000BA8DB5080D56FED61BD99CAF17628A8C86 -:1091E00048FD1D49DC476E542A1C189F688C19F7EE -:1091F0007340433A903E16AF33BF4FD8CF11B17F83 -:1092000046F38EE1661EEABD3536A2B72D8037F4EF -:10921000030B415DE2F38DEC2C8D1F7B089FFF6EED -:1092200078DEC896F9BE9B8BC5D2B206E82627D257 -:10923000C1503F792A05DADFF479F4FC882ED25345 -:10924000F7B8F532E82DC07FB84CB3738AF9771BB5 -:1092500096D1FF49EBD96B033E5E73EF531705C6FA -:10926000427F6591804DA6F2F3921FED2F5E66B1AD -:10927000A79EDF4BF6AC7C961002FE6FDBFDFCB3C5 -:1092800005E4CF6BF6D8EEE7C91ED3CB8C753398C7 -:109290004F676A7F597505A03CBABF1CC3F256CD13 -:1092A0008E5F73EFEEE7DBC83E09C7FC097AB29622 -:1092B000F1F8F257AD1F3B035776603E51ACD846EC -:1092C000FE5EAA891F1FF13BA85E514EE42EE2C745 -:1092D0005BFB248C373882AFF9500E8C2A3EA68E69 -:1092E00006FA1F55C3D36458291FB7B37815D90D93 -:1092F0009DDABAC0FF56A3DE1B589F1ED3FAF0F5C5 -:109300000857F6D0FA78CA7A68BD6C58A6B81FDF3D -:109310008FBFB892DB1BB293EF2B6CF7737ED8E153 -:10932000E7FEED0E3FF74F338AEFA2F84ECA0C1B53 -:10933000D5CFD09E6639BEC32F69F29CE3637730E8 -:10934000D2E54FB05BE17DB8B412E59B2F0BF75926 -:109350006B8BA51B919E7FACF9A7B04E77D23A15C7 -:10936000F952237CDD7EE3F75BAC5BE9C8D6EDF513 -:10937000E608C9AB64EB76D97C316C15777B5EC3AC -:10938000C3470D7FFA014E67B9ABCF81FB30EB8B42 -:109390003719F2AA5D3B6677632EB49E57BD3A2D0E -:1093A000BD06E5B679DCD73FFF2F1FE277E6BF9C0D -:1093B00096F2F1634D3EBED6DC40ED608115299BEF -:1093C000E400E3792FFD7962C229274DEF75CC4384 -:1093D000BB82589FB1B9E1C3B45FBD282032DC1F06 -:1093E0005FC88C79652CAAE705F33CD8D725704D6A -:1093F0000185AFC78410608A354AB375B962C80F5A -:109400009B3777F63EDC875FACEDC3837C317C5FB6 -:1094100062CA1BBBBCA1315CAF7D3F4E7FC7094F09 -:1094200073156E37CE75BB49BFCE0BCF0FD727EC68 -:10943000C7BDF1DFA2651EFAF9D93A5EC2E1FA9220 -:10944000C1785914161CB2323C7ECCF8A89538BEAF -:109450001A357C99F163C6C3E2B9B369FDCDF37FD8 -:10946000DD1526FCBC0EF8C17C61333E188B5C8C8C -:1094700074FBC67C91A17D3C5D9C69C73C81C5B3F2 -:109480000586F9454B58289DE707ABB3A625C06B69 -:10949000C6A3195F8B9F64A16EE877F1BD1E5ABF0A -:1094A0005734FC88DD7FA77985615EED7C5E477867 -:1094B000FEAA4CF3BA542D7FC607DF236D206D152D -:1094C0002B3DC2E7B308E6D32E0FD62727584D13FE -:1094D000D2C91253DE82193E33FC33510E4E1EBCEC -:1094E0008F5F91ADEDE38F67216D1F3F838E3584D4 -:1094F000FC43E62D0CF039A7AF85D1D9FDE361BF60 -:10950000028BF49765C0EFCCE7BC1BE7C1BF5705E2 -:109510004405F30467CF1FB306E71F66E18CEE2214 -:10952000B4F7FBEC28472E6560C642BB0B6092A8DF -:109530006FC3F52954D6FB3DD6F1B19DF47884353F -:109540006DA7FD772563EEB8E4F26555C041E39958 -:10955000ED9499E52519282FCCF8D0F1340FF1922C -:109560004678197F3A7879017515FAB318478375EB -:10957000ECBB86B107CB07F68F59BECAEDC96C4666 -:10958000FBFFD764676A764713C51D16687AE190BA -:109590009D353CEEE6FBC81509F2F11BC1DA6BB252 -:1095A00013EC547D1FD9CD7A097F57B8DCDDE27802 -:1095B000A2BB0FFBE983E4979EAF19A17C4D3163F9 -:1095C000994271B1B4F4F12C03EC62C6E70D7ECC84 -:1095D0008DD97E7C5F18472360E6733F59374F195A -:1095E00058B7F5576EEF40799CB2E49731EA5CE1E9 -:1095F000F91C69DABAD56AEBD66F4797C2FB04FC4F -:109600001EEBD0ECB0522D8E8F7FA07CAC588D0F0E -:10961000E5BFEAEB98520AFE87218FB083F0ADAF29 -:109620002738117DC89791804439C336E622FF3828 -:109630007233CFC758C894AD981FB4306A3F96D8DC -:109640004F2428111C91F5295ADC2444FD2C0AF2E0 -:109650007E5829F7F3FAE93E06ED13F21F6D2E301E -:1096600025B17D260BA1FF04FD65A3BE67EB12C6E5 -:10967000193D78DC64FD99DB89DAFEADE80C8542A2 -:1096800009727ABB663F1F0B5476D94627C7DF2283 -:1096900097579512F2628F045D0D567131BD3F5D93 -:1096A0007FF7DB89ECEA1712ED44B7A3F18567CFAA -:1096B0004FB01359E30BB8EFFF45EDC497B21B5FF2 -:1096C0006883F9FDF3ADAF51FEF8B12610988047DD -:1096D0006F742A3BEA45F92093FE2A6C008F0A93A7 -:1096E000BF25652CD27B4A344F9512F265DFC856F0 -:1096F000087E6FB14AFB65D0B40B5D71AF141210D8 -:109700006F7769713320DCB1B33D89EDF8BCF5F1B9 -:109710009C2E99E070E8E3B1500BE5D7CF64A447E5 -:10972000F43C109DAFF57E8E661BE37523E0E7A346 -:10973000D9FEC1FC2C8A4DEFDC8672E20591FCB0AB -:109740006F056EA6F7E678C0DFB2B97D582046FEF9 -:1097500086FDF434BCFAAD9BA0DD8A1DCE10AAE1D3 -:10976000E5DFF9E0FB550AE289AFFFFC258BEFADA1 -:10977000C279954832ED6F14F0388CA34520FF353F -:10978000A5C811DE01CFC3BEDADC9C04B80EFBEA2B -:10979000A93C7A0687EB18F4D9AE60BB4D0DE42FD7 -:1097A0007AF8BEF73145C960245718D913A2933F00 -:1097B000DD393C2EECCEE1F13C2987E3DB7552A08C -:1097C0004542BA6EC27D0B294679D0AE9312BD7761 -:1097D0000882A5BDA6F7E73A09C219F195666EEFB2 -:1097E000A0F7381F6C2F7A99C1BEF1E7703BD9DF23 -:1097F0000F471A87C36BEE279DBFD7F8CF0CC78AD8 -:10980000ECA941C4CB619F9A9BC3E3285C0EBB9F2C -:109810003F208C1F893CE6F9FA17072517C5F56E1E -:1098200013E225209FDA4B8FAD21B955E46AC2734C -:109830005209F693C0CFDDF0731503F669DFB43932 -:109840009518BD66CAFDA1C1F6D63B9527E6CDC1E8 -:1098500082767EE20A5DF6C6A00CF6DCDB5AB151D8 -:1098600019BD1643FD97D470FB6C31DA6721925B0A -:1098700006BBCB6C9FB941DFCF01BA58129064A4EC -:109880000BB39DD65E398FEC9A76B06B305F7BB0B0 -:109890009DC6E5CD1D511B53A1DE4B3522F9192F75 -:1098A00095F63E7701EA8B497685F44569DF1D73AD -:1098B000E8FB041AC7ADF977509F9F7708A5C54B01 -:1098C000E0DDCB3547DD8B13D6FBA54947C7A25F4B -:1098D000B035497E851EA7D97B0BCFFF7AE71E21C5 -:1098E000EE44BCDD2ADAB0DF85E51ECA5B9D26BAF0 -:1098F000699CC51BC5B89370A8A64FCB1EB01B9919 -:109900005893FD2AE2E14E3BC3F3830537F61AEC88 -:10991000DC8551A33D176902FB47397D3BD06CFFC5 -:1099200099ED98E5399AFD52C12AD07E79A9792717 -:109930003B5A3260C7CC4AB2FFADDB31E7DAEABE50 -:10994000ADD133ED1FCC92ACF7F72FD6FC5316E216 -:10995000FEE034F1435AAF63214941FCB96F7E9E6A -:10996000CE75B8FF5B0C5B8D77478E43DF8F237915 -:10997000BBB5228DF2AEF7DC72564E2FAD97725FFB -:109980000DAEFFF3769283C9F45B4A5464C530315F -:109990004F54A0A7BE9EA3A2292C513F8C4A92A748 -:1099A000F0A31C3E0FFFADCC867E76668CA9567E5A -:1099B000A95E0FFCD1E918A386FADD9900DFF5C591 -:1099C000368AFBEB7E698A9D9FF7B5EF5A1943FFF4 -:1099D0007414C0877028001FCAE1A2681A9547470F -:1099E000BDF41C13CDA46771348FBE9744C7D0F368 -:1099F0008C6811BD3F337A36954BA313E839365A3C -:109A00004ECFB3A2E7D1F36CD05B58AF2C5A4BCFFB -:109A100071D1AFD3FBF1D139F43C273A9B9EA1E839 -:109A200037E97B7974313D2BA28DF47E42F43A2ADA -:109A300057466FA0725574253DABA3DFA5E7C468F8 -:109A40002B3D27455BA8DEE4E8062A9F1BBD9B9EB5 -:109A5000E74537D1B326BA85BEEBFC9CA6D9D32FF8 -:109A600006B6C9946FCFBACB503E26E3C3439A3CA7 -:109A7000AECB51F722FDE9F5F66BE70ECCF50EE41F -:109A80000C9D77F3AAB65E1F858EFC008FD3EAEBA0 -:109A9000B63E30741C8195F986D9B7E2F37B3A471C -:109AA000E1F42B7590BDB1B589513E98A7B24740FE -:109AB00079D319906658D1913BC0F3C08A7222477E -:109AC000517FB883EFEEC5FDA84B623DBEA9482F7C -:109AD000215FEA54E86F549B8DDC6B85C902969533 -:109AE0007A2677B381780ED85706BD260574FBAD6C -:109AF00067E60484E7ACE20AB25FB5FDE4FDB78C2B -:109B000066E8776C75740B12CACB558C25DAE15B6D -:109B1000D72E7A28F19C8614E0FC396A1D7B0AE373 -:109B200064451D4A1D9E271CB3597D0A533C4BE2D8 -:109B300091BA54289FF970EC297C8EED8AD7A5C183 -:109B4000F3EC9DDD4FA1F819D7DD5BE786F239CF45 -:109B5000B2A731FC54DEA34CF54079C201F569DCB3 -:109B600026A9EA8D4C4D57109E786B3AC0B3F56D1F -:109B700030B4A03CE9C30E11DC9281F507BBEDF1D6 -:109B800084754929EE5145F867FE8D7239CAD9AD01 -:109B9000526F4A66D9E0F5E9C479E33C41AF6CD72E -:109BA000F6D1E584F50805043D1EE80B24C4033B0B -:109BB000DB5EA1786067AA5C8BA1AEBE694C7E506B -:109BC000413AE67E42EA9AD1A49F74BA03FC1AECA9 -:109BD0004929C0E96E6BBFBD698DDF10E2B7EA7F2E -:109BE0000F7EFF3347935F49F0FB22CE23383C1FA3 -:109BF000D706385F021F9F1FA84A5EEF2A0DFF6637 -:109C00003C6F95E4B3085F6E668B950FAC5BA34623 -:109C1000DFC3E1F59BFFCBE876526068BCB24A2F08 -:109C20008F336BF969C9E4CDFE24E7449A0283E4DB -:109C30001C8F97CA20E7C6249773358161E4579239 -:109C40007C87DB027ABE43F8BB8111C4F5EFB0C953 -:109C5000B598EF121BCFC84F00FBB20DF37746C586 -:109C6000940ADAC642A18C78AC389BFCF422B03757 -:109C7000A40A86A98EDDF8BCB832D3B6A80CF31AB4 -:109C8000347E931B0389FCA6EBFB017ED4E922AB57 -:109C900093CE5900BD623EE12E0D4F03FDF078C416 -:109CA000DA9B733BDB13E46067288FCA7AFD64F4A8 -:109CB000FBA6F61DE405EDF75F5C639D6FF2EB809C -:109CC000A8D9397D2AD2796C0A93E9BC73DB119249 -:109CD0004F99209F84221E1EC2F1F3A3A90F619CFD -:109CE000F657816C4D9ECBA99779FEFFD1733BF857 -:109CF000EAC44F35F21E3C57310AF4908272B20624 -:109D000060AF443DE7A07557185F47A586C5BB0502 -:109D1000C25B37FACD311B3F9FB1DFD1A592DE7117 -:109D200064CA987FB2CB1FD91BF027E70B394D29A6 -:109D3000C745FDC3E66B67BA83989723A762F915F9 -:109D400028DF3109F3847A9956BEC33DF98BC71FCA -:109D5000FE10B8663FEE535507D457919E81AEFF73 -:109D60008070A967CA12C58747B8FFA4F3E7003F10 -:109D7000C9E53A3F3596913C7C2790B04F9ECCBECA -:109D8000F9A1263FFB0243DB373ADD9FB67DA3C135 -:109D9000FBF630FC3FF3B957376F6303F13F4FEEEB -:109DA000EB3D9282F6F654767402C6BD7A38DD3306 -:109DB0001EE75331FE07749052E932C56D85195A7A -:109DC000DC65C878AD1E4FD6E37D7A5C2F5DA32B92 -:109DD000BC3000F578FA24595A44FDF5B24BA13F46 -:109DE0004F90E349E76B945BB83FEF5A93258D2E74 -:109DF0001BE8172425C9A9CE0626B767F2FDD70CA4 -:109E0000902F1DAB19F979B19744EAFFB86AFBC0EE -:109E100009F58E570202512EA84C91B3B573084430 -:109E2000E432D1AB93B12EF4B7D9F7422E07C6B9BD -:109E30003F15980A70EFFF54A4A784116E687471DF -:109E4000A83C848D6B336A42B81F281E8532C059E6 -:109E50009F519381E5FDFB27849845FCEEF248A3D2 -:109E600021BE64C6537FBD6FADA17C852DC3EC7F41 -:109E70004E0A3A74BBB32288F6CE957D6D0E6560AE -:109E8000FF53DFD70B163F7121DEB3135CC6EDCF56 -:109E90005C166F49B49B12F6176BB09F2D03FB8BBA -:109EA0003D6724EE2FAEC8BD158FEEFFB07F7F312A -:109EB000720ED657BD5DE5489F7A3EEC7E07DF0700 -:109EC00060135EF02916F4B1A0FC193FD1A3E64F50 -:109ED0000CFAAEC5CDCC7EF0ACA0318E7F3C3427E1 -:109EE000A31B3F2689E3EBF13CDD0FC6789D6CC9CF -:109EF0007746FCEBE32F10B81FCBEC02C93B5D6F3C -:109F0000823C8904FDD48CE2D1AA53A07CADE3A1AC -:109F1000C50AF94549E44BFFBE01EB2EB1DA675D96 -:109F2000A0E59D98DFDF1CE4FA79819DC72985951E -:109F30004B2238EE82A04B7026D8495705B9FED285 -:109F4000F75F1CB927AB10CF0E4744B19AB7791F02 -:109F5000E5AA20EB3FEF16B2D07BC9F074C0DE411A -:109F6000FB72079688745EF7786422DDFB904C2EB6 -:109F7000BC89F453C25838978F37B08ED678D3F354 -:109F800064CCFB55FDDF1B53E8FC8D395FE6510DBA -:109F90006FFB34BCFCBBF365F669F87B518BCFE8F3 -:109FA000F1AC8B93C8FB736D750F131D0D139739AF -:109FB00043CFF7D1F0C39E1E4BF7726CE8B1C75385 -:109FC0000484C746FB970D7F1043687FE9EDDC26CC -:109FD00079A1E7EFE8E5B493028B27EC23A4495D70 -:109FE00014274D3B29D17B33FFDD6EE23F7D5D922F -:109FF000ADB3BE2EE6F79DDABA1C68FC8F009E77E3 -:10A00000D990C22CF3893E0B1AE3EFE63C8064FB47 -:10A01000DC07B576C7239373502E3738622523E1CA -:10A020007B1D3FAF7FFE1B17F2D98693CE1956EBEF -:10A03000F14A90FB2DA04FD725EE837AE6BFDA8652 -:10A04000BDA649C67D505D9FEAFBA06995E67D34BB -:10A05000EB7DD00DCC5A3E26DB071DB4FFA9E9DB12 -:10A0600013C124FB9F65439F67DFADD1F370791F58 -:10A07000973BF87959F3FB17FAD7617DC10F80AF91 -:10A080006E6874D2EE5377A393F87071630AC56556 -:10A090001797F378EFE27B056DBFCE18877D11E44B -:10A0A000C5323C5FAFE99DA32C5C8DF6E8AC4AC19C -:10A0B000B04F1EAE493194E72FB9FB45BC37E1A53F -:10A0C000497685E2CFD0570CED821A9EA7C894BE80 -:10A0D0003B30CEADC79FF5F57FA9E628DD8316039B -:10A0E0003BBF2484F16791F8EBA5D726F07BE98488 -:10A0F00081FD7005EC840DE78EA17C8F8365DFA068 -:10A1000038EF068C8BC34C377CFE9B194447A094D8 -:10A1100063C8AFE3B3E2281F178FABC846BA7C7A97 -:10A12000FCA71E8C8BBE73EB713FAE536F7313E5B0 -:10A130001D98D7DD1C6736C7974F379E3C31B73F18 -:10A140004F80E8E145533C59975766F991104FBE4F -:10A15000207704F1645D6EE97242975F07CBDADF26 -:10A160007A10FE7930E22498DED4E6DDCF971A5DCE -:10A170001ED4F9F07327D9234F8FFF2DE55BE9F546 -:10A180009A8399C487DF288BDB697F16F3144A070B -:10A19000D6657EE49AFE3276FBCDA52B0DF4D12F49 -:10A1A000A786956343CB293197C72792E56BEA7C55 -:10A1B0003058FF94909D9AF67B7BDC55F4C5F550A2 -:10A1C00043E3AF146C07CFCDD47EBC2312B7D04F7E -:10A1D0006678D24E8A2C3E21F1BDC2DFF7EB010733 -:10A1E0007D8FD529AB57FBB83DDD4AFC1973D2FEF4 -:10A1F000B94F6DCE85FA3EBF1A437A78C8A7B6E448 -:10A2000026C8D3563BDF8F146D2CF2B8055E9ECC6A -:10A21000D5F4320B07B0BF35B5C6F35CFA737B2EAD -:10A22000DFDFDBE3AF0EA07DDD7AB83C80FCB3D787 -:10A23000534DF676B275BB53E727945F2503FEC4F2 -:10A24000466DBD814555DCC75D630F0712E38DEB9D -:10A2500072791E47FAE4277AD06E6E956D9427D8EE -:10A260002AF3FCEB36B734639BD6CE676827E9E761 -:10A27000A8E8BE0CC96DCCAF7E52B37792CDF3C9BE -:10A280005C9B76BF68F73D35C2805EB11FA975D172 -:10A29000FD0F4C95797E53C8904F6DD7F44B9D2997 -:10A2A0005F4394BF98DF16F44776E55AF86D7B7CE0 -:10A2B000EA93B8DE5129E644FA88BAACF9FE696D32 -:10A2C0005DBFA7CDD77CAFAA68BAF74134DDFB10DC -:10A2D000AB6BFA692FD2DB6AA7DCEAA37B1EE8DE50 -:10A2E00087285EB904CF7FA6F07C16F0FF26F2F334 -:10A2F00006A15E94AF2CE0A2785447BEAAE643596B -:10A30000F4D81E5C0DFDB5AA752A1E5DE970DB3A16 -:10A31000719F2F33183988F398EA9148EF745C9451 -:10A320004A7A08BEA77039C264A19AFC41BA3405C2 -:10A330007D703C5F660F38289ED51A61BDCE31FC1A -:10A34000FC3FF653CBBAF7D714A1BDEDAA443CEDC0 -:10A350000F4DC88858C809FD69DEFF7FEBDB6F141D -:10A3600062BB0231F221E2BDA761F146DCD75FB1E9 -:10A37000530CE13EC2B7BE73F00C7EDEC8B8CF7C92 -:10A380005FDA945ED46751B783EAEDF15477209E8B -:10A390005A054F07FABBAD8757FE18F1D8DAC2E36A -:10A3A000DC663CEFF57C87EED7380ECB89F5CDF730 -:10A3B0006BB08E957C9D9C2EDAB784F9B2BC2ABE18 -:10A3C0008E141F3CE4A17BA08EEF7FDA8DF07D8997 -:10A3D00079A7E5F9879A77BE4CF68B463F4C0AAFD2 -:10A3E000C379DD247A3ADA7D784F1AAC37C2BDCB17 -:10A3F0004EFEFE7D69E9B4AE51800FD755F4D4AB63 -:10A40000E892FD7DA748EB1C959A685E2C26B1ED7D -:10A41000F87ED789EF9F8774A066D1AE9658D04456 -:10A4200078F93BE065B5055E807E8A10DEA777DDB2 -:10A4300040FD74385C325A36AD9E6A3AAF3CD2FB6E -:10A4400045CAF2389F24DC2F52965765515FF3B30B -:10A45000D0DFC6716B65F6499C0DE03D59FECA79A7 -:10A460005AFFFDFD0C9FBF725EE2F8FAB85F625DB5 -:10A47000A79FCEBAB6BAFEEF74B4B354313D94522E -:10A4800008655C27C43FAE13AE9716B72115A4200C -:10A490001DC8DD79480737A487903E87931B12E3D8 -:10A4A000EB6E97809EC1AE73CA91037476518BF7A1 -:10A4B000E8F2C4CC67AD2EA3BC6AD5EFE53B3432DD -:10A4C0007905F47215E2C12CB7464A272BF304F341 -:10A4D0003D342BF3FCC9E9C41E0CDF80EB8878CA3D -:10A4E000ABA078C5B7B1FEFEFDE20EC7681C8FC7F2 -:10A4F000CDFA824C7E30212F4B87A70D37BB799C3C -:10A500009AE21F5203639807E72D0D0972D988E874 -:10A51000A82D11BEAF808EEE1C8A8EDCAC87CE6B70 -:10A520002CD7F373760C9D9FF365F50FAC6727E28C -:10A53000B7D5F31DA2CFB57697CCEF513BBD757D56 -:10A5400064F0BA3E32F4BA461EC3EF6A5E35DD638C -:10A55000C4263592DDB4CBAFBE8179A44C0A19E490 -:10A56000E220FED1E4F64D672A94AFBABB4593735F -:10A570002D4E19EDF1677C373C86F5EF624A18E302 -:10A58000A1536CAB084F7F87F93D1822B95A8AFB5B -:10A590003E51961AD2F4E8538887194A8B9005EFFA -:10A5A0007D0B141B5D43AA6C62B6B291E3E1C5C199 -:10A5B00072F0C561E4608F46CF37223DEBE7ED9343 -:10A5C000C9C143A72F070F7DC572F0CF79A7A1D7C7 -:10A5D000BF0279F3098E6796376E8D9FAF08B11071 -:10A5E000C6CB479ACF06F6A682FC559BEE22FA69A7 -:10A5F0007D5CA07C29B0C32354F6B848D8ECF5386C -:10A6000078FEEF0EFE5DACE37836E3E9F3BC2C9EFA -:10A6100077D3B5322C19F2A462C40F77AAC7E462CB -:10A6200011F3FB6B889EBD9A3DA3E7F5A76BF2BFC4 -:10A630005FCFCFB4D178DE022EDFBD60EFA05DC466 -:10A64000A45E867EFC4D793C7F1FF881E81B46099D -:10A65000233F644C924C795A9C5FFC12B777327D51 -:10A660004C205D837962F0FE04D813783F41A66ADE -:10A670006C7753EA1502EAADDE46779340E7F4C300 -:10A680007B7E04E52CCCF702BEF1CE30D6F7B38446 -:10A69000B2857F1EAB63A598B75896AFF9E90E1641 -:10A6A00020FDA8F9E9FA7D81E2F0795F95F9238828 -:10A6B0002F9E9BAFE79918F571570AB38CAFFD57E2 -:10A6C0003E975BF5BDB5756857AFF230B2AB56A19A -:10A6D000EEC472A683EEB509EDA97459DD5791A9B0 -:10A6E000DA0CF7F37A67A41AEEBDF587B30CE59C94 -:10A6F000865C43FD6064B4E17BDED2B30CDF0B9A71 -:10A700002A0CE551D1730DF58B00C189E531EB2E93 -:10A7100032D42FE9B8D4503E73F3370CF5C7C617BF -:10A7200019BE9FFDF0B586EFE3BA5619CAE7ECBC37 -:10A73000C550BF9559DFDFB9219FCB29E0779263E0 -:10A740002DEEBA06FA1D0DD96188F32FD1EAEDC9B5 -:10A75000AC2EC57848EB91F252F287D3CF1DD21FB1 -:10A7600036CBC564F2D8FCBE4D1BEFA3A7DEAB5EB3 -:10A7700086748E421EE4D247EE37D7E29CD697F11C -:10A78000BC04FD7731CCF7F2F7EF534A2ACD67418D -:10A790009683599D0F5892AF58EE2FB4092117EEAA -:10A7A0001525C39B4E8FC3E1ED0EADDE97C5DB21B2 -:10A7B000C11807427DF2B8055C7BF3FBEF3B7828BC -:10A7C0009FEBABCA54F230F83D0EA7AB4F74384044 -:10A7D0009F3C9EEF1F9C1FFE51C3AB57DDA760FD42 -:10A7E000AB787D5BA814D725D9BED2DE7CF3BE52F0 -:10A7F000D55294730B3CA942E27DCDBFD4EAE9F176 -:10A80000ECD6F44F695FA9D5112A1DC9BED22FF12C -:10A81000CE8D2AC4BFC2C7D3D7D5AE06644BFFCEF8 -:10A820006CC7B0E7F01E8C985BA2BC61B37F17D5F4 -:10A83000E4B6EECF497B6BC9DF6F758FA6BC8F5630 -:10A840007515E9CB8E247E2EE8CB3FE657613CE0C0 -:10A8500046833F37100F50693C684B76536B82FF3D -:10A860008FEBA0DEC7EFD5FE0AFCE00FF34FC34E1F -:10A870005018F7838F338EA7E3AA8DEC84E360270B -:10A88000A0FC5D2331DAF78E550A8A955FDCB15A58 -:10A89000B30F5773BC99F7BBCD76C6C5A19584B7E6 -:10A8A00035404FAE4A8CC771FB778D9DDFBF297B4A -:10A8B000C301D4B77D7E077B10A0DDEBE7F1391D26 -:10A8C0002F5F541E65160CB293330B86B093A78985 -:10A8D000655D786FEBB1933C2EA2E051441FDE43DF -:10A8E000CED76FD57373622B504F15494D98BF2E3D -:10A8F000322503F1B2E25991C5059463C6FC7C3B55 -:10A900006BFA01C6E3988FBF8F31570BDA49199361 -:10A910008C7A2C5335EA31EF8C2C935E33EAB19C60 -:10A9200006A31E0B468C7A2C6F698549AF19F5D8A2 -:10A93000A8689D49AF19F5D89875979AF49A518FE0 -:10A940009DB9D9A8C7C6C68D7AECEC875799F49AF9 -:10A95000518F9DB373B5E17B7977BBE1FB8467EFE2 -:10A960003294AB7AEE37D49F78E041C3F7C9BDFF8C -:10A97000C7F01D10FD0A9E67C07B687111CF7BFF79 -:10A9800009E377A63A301FFF3A3C9F09EB787EDF58 -:10A990006F0DFDB10E7E6E2106FFE17AFD9945E84F -:10A9A0001E009063FBF2A0DDF57121D4CD503F3D38 -:10A9B000FE1EEEDB5C1310C98F5B81C156A4874776 -:10A9C0003C71A487AB371BCF3F5C13379663403F86 -:10A9D0000AC615807E90BEAE33FD6E04D883446FE8 -:10A9E000D7295213DA9566FAFAB34E5F31F5153C62 -:10A9F000CFA1CF579F9F5D3F7FAAD19FAAD11F13A1 -:10AA00007711DCD7E589F4FB3BFA7C55F88F7FFFA3 -:10AA1000D081F338B153605EDCDF67B17D7916F326 -:10AA2000B97EE72607F2A7795EE6790CB2530B8C64 -:10AA3000FB8AD3447788F8EE3591F4114D01F9EC97 -:10AA4000517E5E6FD573229D8B413E447F418C3594 -:10AA5000105E56005EF0DE70DD6E3DA6B53BF68002 -:10AA600048E79B87E34745C3873360E4C71425D590 -:10AA7000444F46FCA6951AF9F3BAB72F74A0FCDA36 -:10AA800007F8162631E60919F9F53A7119EDF3E9D7 -:10AA90007856E03F1C57025317E77D3DCCBB5B194E -:10AAA0008CDFA5BB36ADCDB3A09BE1F0FB48817137 -:10AAB0009F4EDF9FAB05EC382CF24A75FCEDF2ABF4 -:10AAC0004FA07C4CE60FEF2E30EEAB8FC01FDE9D0B -:10AAD000286FBF027FF8B98221F55CDF2CF4A79CB8 -:10AAE0002C3DD46E11F79398DC8DF15A7B138FFBBC -:10AAF0000DC4EFBEF238CF3B08A724733D9922E97D -:10AB0000719ED08108DA27196785302F6AA4718E6B -:10AB1000BF140C8A73FCA560E838C71B780E50CDB3 -:10AB2000C8ADB7213349A152BADF1941E079481FB6 -:10AB3000E3BA0CCAD72DCED2F28F9521F38F2FD640 -:10AB4000F677AB03EA498403FAFB149FFDF7B1558E -:10AB5000FAA99FF461FA89D5717B2D66F374B472FA -:10AB60007B8DF699BE8238467A21FAA56E8EFF5605 -:10AB7000078FDB9E6E9C2D583808EFC1C221F0FE76 -:10AB8000CFB772F8B9D5105807E5C9E95B3F87A977 -:10AB900097D7671AFDE5B5151CAE126DFC6F66738D -:10ABA0007F607221E73F3DEF12F316532AA03C93DA -:10ABB0009F53D2CFB5EAFD4C2EF450FD4F02759352 -:10ABC0000BFD9837CBEFDF599B69BC87E76F05B565 -:10ABD00093715E13B4FE2717329ECF3C9AC365CEA5 -:10ABE0003BFD8756FF1F0575F4C473B4E8973844DE -:10ABF000D1129F530A799C40BFF766BA7E7EEE5E03 -:10AC00007EBECE7CEF02F0C9EBF8FB5047EFB0936D -:10AC1000BF07FA88CECF2DC9E3E710CDF729444A04 -:10AC2000E57D285E4FB032CB7B7906E5391CBA99B9 -:10AC3000F2EF5E9ACC6421387CDEC36585C6FB11D9 -:10AC4000BEC039BA2B0A4790F7B0503B47D79BCAD2 -:10AC5000F5585FD0157FD0C2DF8D6AEB7487E6D7D9 -:10AC6000E2FE34EE93E3FDDE56FBE5D1424E3F2398 -:10AC70003D577D97231241BE359FAB4E769EBAD786 -:10AC8000D1BB2607E11DCB4268BFE72C90F7E4401B -:10AC9000BDD47A85CE3FAE2D62E993F07BB92D8489 -:10ACA000E73A32E7CA6BEDC8A7C52C4B80726F6CD0 -:10ACB0000E8D7F4703934580ABB390EFA32FBCF578 -:10ACC000631ACF5F035353E8DCF974F4CF620D8C41 -:10ACD000EE2D34CFF32E8D5F5C6BF83D3919C5D660 -:10ACE00079F87769F408726B13F2456D31DBC1CFE7 -:10ACF000CFF2730A782D3DE56F8652695FF01258E6 -:10AD000037BE7FDE43EB776360EA7DB89E3ABF399A -:10AD1000B43C05F379F2CEC2D33B4F9EBAC01ADEE3 -:10AD2000DF69EBDDE80FFF14E14D2DEDE0BF5FFAC9 -:10AD3000F9A95362B5F6D38E0AB68F4450FFA580A9 -:10AD4000FE13F0A9C8748E96B9043A0FEB529A8894 -:10AD5000AE522685BCF8BB68EC4A1BC37B5CA66A76 -:10AD6000EDD50626E0EF49502E20C969D3EF4BA858 -:10AD7000A1B616683F0DF7CD4298F71D5A8AFDD54A -:10AD8000BB53658C6FA61437D5E27A3DB390F7714B -:10AD90005792F312FA39FB81FBA796BDBCB726E1A7 -:10ADA0005E81B557BD6CBC7FEAAA97BFCCFD530747 -:10ADB000B75EF5F2FFC4BD02BA7C03356447BBFE43 -:10ADC00080C8EFD1FBFB9397DB711DD6D6B22EC4A2 -:10ADD0007BEC53C0B36B00CFF6BAF0335BD02E5987 -:10ADE000951EE2BF2712FB16C2F9761A93B1BD9EDB -:10ADF0006F28B052D2D7731B04B21F98D4773D96F8 -:10AE0000E7EF4A93D17FF8FB936F14C4803EDFBA1B -:10AE1000EDB807F353DF91FA3C08D7FBB7BEEA4120 -:10AE2000FCBD75AB48792874EE3B214FEC738DBEA9 -:10AE3000168C0A1F47FA5AD8FCDFD589F6198BFA07 -:10AE400049DF5F13078813EDDE87D30CBF2BBABC35 -:10AE5000CB6B28EB7A7EB9D3FADC7CE5282E97AE53 -:10AE600079A4D391A7E0F811FB2898E7FBDA39A081 -:10AE7000F77778C88ED7E159F448B903EDE17776D2 -:10AE8000395937C5057BECCCCDF507E65D44F8D0E4 -:10AE900083E0DCB73BCF817CB644607D4E626EB60A -:10AEA0000FF1FD27CDFF33CF63C95BB203D77749DD -:10AEB0002DEBC373678B6E14D6DE04F51745DCE407 -:10AEC000F79BE769D63757E37D3682D53D704DFB5A -:10AED0007E07FD5C09FDA0FDB9A4C3F8FDD8B3371A -:10AEE000ECDB02E3EED8E9207BF1EA61E2FD6347A7 -:10AEF000697AA99A4D3C3586F45FC63825B9DDA13B -:10AF0000EBA3F79B1925A9FC057FDF179E1F36CB06 -:10AF1000F43C5EA8D07A5CB773CF3EFA6D61A9A706 -:10AF20001AE5DDCCE716A77D830DE4155577DEF035 -:10AF3000F41662053D5FB59BE27B13B5FB5FAED6B1 -:10AF4000CE7F541D30E7ABEE79E67768B7C1FC4F92 -:10AF5000E7DE9E0523BCB7E7D8B353D3E87C808EE9 -:10AF600097898017F1CBE32559BBE5497EB745E7C3 -:10AF7000A7E39ADEBD72DBECB5B9307EEB937F2E92 -:10AF8000C4F8718C71FAAE7A80FFFE4F953B9BE856 -:10AF9000CD85F41944BC9AEE7988B1D759027D5F0A -:10AFA000BD2B8DE82400F6907312BEE1F45A85F7AC -:10AFB00076227DBFC6DBBB34FF36B2EB365EFF7751 -:10AFC0000ED91920BE0CD8E8D91DB04DB2B867CB48 -:10AFD0007CBF5887B1FC91BDB710E5CAD5263FF4B8 -:10AFE00023C13A3FED8A51A3497E5DA9A8D3310F11 -:10AFF00060090BAFE5F15B7E6FCFFB52C7BEEF225E -:10B00000BF6F13580CF0B4FC378FFE1AE5D8B58F1C -:10B01000DD9B8E72EC03A9231BC75BB67D4D3ADE28 -:10B020002FF3BE144BC7F61FC4B93C1BA42F47090E -:10B03000DABE949A2E804CBE9E480DFE7F65DFDA04 -:10B040005B609C7F009E91EFAFDFF12F2AEF535D95 -:10B050007D2C80FDF64E4738AE697437B584D0BF7D -:10B0600034F2E7B53FBD375BA13C8F589E86BF3CAD -:10B070006C77FD363BE5F9A21F8FC3AC607D343F92 -:10B0800073FB155D471D28AF651BEBCB3F6FF0775A -:10B09000B0901CC86F2B766CF8584CC7E7076FE26E -:10B0A000EF41AD30D9A74B35F96DA6FF9F9BE81E48 -:10B0B000F043F18518C0C57F8E89CBF1D69FDD376F -:10B0C000FE30C0F7E1B617D2F1F72674FAD7EF7960 -:10B0D0003ED6B578A163887B843ED2F8A45F3F68F2 -:10B0E000FA49D90980E54071177F2EB377A79F07EA -:10B0F000F35DD6690F21CD2F7B5454DD68571D7445 -:10B10000923DB2ECD1E344B7CB04B54F203DC7D25A -:10B11000518EEBEB75DDA37F9A8E72FABAA0C866EA -:10B12000022B5EFBCB13BC3ED0790AD4BFEEF1C339 -:10B13000D3BF8B6590272E8BF59ADAB5C7D1EBB6C6 -:10B1400058AFAEC3D3313EDFFAB37FD27A7CB05B67 -:10B1500060394583DB2FEDFC13C5C13E8485F16664 -:10B16000727CA1BE59D125363A32ACD6AF7BD66FB0 -:10B170002BE93BE5850FB78E1B4631AE1F7FF3E809 -:10B180002F7E0B702C7DD3199A89E3FEE28674061C -:10B1900074F067A989D3FD8FD664A3FE5E6A8F65BC -:10B1A000CBF4E4EF976EFD36D1E3D5BFFF76B6B6AC -:10B1B000DF10B4913C8805719E4B1E9847F3BC8A02 -:10B1C00045881E97FE88DFB37802FC6C2B3FA152A6 -:10B1D000E172CBC9568EBFC5877213EF6C01381C64 -:10B1E0008CDFD7F50ACF7F77B24B3312ED5C87C285 -:10B1F000EDB9188BBF8D76E70A50CB28D7C4DF9FF7 -:10B20000988EFDDC58243539293E6A7D7FCDFF03B9 -:10B2100074C90FBA00800000000000001F8B0800F6 -:10B2200000000000000BE57D0B7854C5F5F8DCBD8F -:10B23000FB0A792D79404220DCBC1309718104128C -:10B2400040DD10C020AF0D444589B0040C0112123E -:10B250009116ACFE9A1B0208946A50AA54D02E088C -:10B260008ACF0604C18AB01145A8FD300AB5F8A2FC -:10B270008B206F6441A8EBBF54FEE79CB9377BEF8E -:10B28000261168FD7D5FFFDF3FFDEA70EECC9D3B40 -:10B2900073DE7366E66C0D83BF64C68A3E1ED6D528 -:10B2A0009BCD98855D34DF97CBD825C6A467EC8C01 -:10B2B000D530A3ECB532FABB9AC4D88975964EC284 -:10B2C000CD507661954DD0FE2AFEDD1628A74A02A4 -:10B2D0006379D4FC13D69FB1D9F82F09FAD97862D3 -:10B2E000F86AE897C5892C328EC3CFC430662B0F1D -:10B2F000AB8DCC87EF1D3C6AEE06F5728C81A5D92B -:10B30000A0BEE51B82993D56C2F66AFF35DB2DCC07 -:10B31000A38E07FE5FB3FE1B33C37E0CCCD77D50DC -:10B32000DB7AC66A737E1583F38894964179C2EC02 -:10B330001BFE367E07BEBB01BE53B112DA676AFA46 -:10B34000DB72EA739683EDCD81E749F8DF057C5E19 -:10B350006259A42B8CB1E9304D56D076FEF3BFACC8 -:10B360007FF43D4D7F395278CCF150F8C70036E07C -:10B37000AA18789FAD89652CBEEDFBDFD7C98FBEBB -:10B3800067C2B765C6A04995C9FD02E2A9EA338B39 -:10B390005D063C56BD76D96C009809CC97D699B11C -:10B3A00033AFEEFEF45E98CF992653CC28FAAA2349 -:10B3B00042E812C07BE5E66F86AF86F626C07B08C2 -:10B3C000D073F696EFCD06681F57C47C1618FF9908 -:10B3D000182763BD116FA6AFBD1ABC15C1736F18D6 -:10B3E0008D23C11087A5278141393B86D93DF0FEC9 -:10B3F000EC83A25D427C31DF625B58DBF76B9A8E97 -:10B4000006D1455FCF98CFECC4EF6EF9CD05314240 -:10B410008B77E3D75E0DDE553C07E3F59E20BC5EDF -:10B4200066D991F01976FAE5593D5DD96DF1ABE237 -:10B43000F5DB3A864CDEFAFC624F89F02C6D870F03 -:10B440007585BA1D4AC9D8A74C83C799AF9C23FEFE -:10B45000FD47BCC844E09BD9EB7F588C7C0568F560 -:10B4600059807F67BB2F10BCC861F531829B4B852B -:10B470009CF6E6ADC767707D77446A5E80FEA605E0 -:10B480004C0E877E7DEF88EE7530B4F3922F220A42 -:10B49000E6B728844D764279DEA6C09D55984D9E2C -:10B4A00002E33C2FE7D8647C2F844D6802FA9C7736 -:10B4B000FA223A8705E67D64871821417BAF9B1508 -:10B4C0003785B5E543C61AE8FB5ED6517D3D8D73E1 -:10B4D0009878E5752F7CEFA26C6416F89EB7FEFB9A -:10B4E000D7BD501E335A6D88A769F5774730037C66 -:10B4F0007F47CAD809D0EEFE7D803F9A9EC31C0FBD -:10B50000F89DCAA7CE4E32F9A9C1303F313C77CF62 -:10B51000DBF07E052056047E9DB65C8F9F99CC198A -:10B52000E94942B93505F884FEEB367BE0BDE9AE6A -:10B53000B0DA65F0DDCA35FAFA993BCE107FCD0C52 -:10B54000E22F17F2577C5BFEDAA0F2571FD607F9FD -:10B550006B981866407E3EBF57745BE09D8B0B4D29 -:10B560006C31C0175F15DC0CFAB9B8031A21BC9D09 -:10B57000C34C8E25BE55F95CC5DB59E4BF8CB6F8CB -:10B580006CADDFFA55FF87A149D59B5FE4AC86F22D -:10B59000EC9B9FA5BF8DF0B6BF257EC1DAB62FDA32 -:10B5A000F9C3241AD74E0BC3719DDFF941E2C308DA -:10B5B000FFC96247BE3DBFC0E260A8EF7686BBD33D -:10B5C000B0BE07F003D0BDE19DEF7350DF33B690FE -:10B5D000E8D82299A9BCB8E39F87059CC70E8B8445 -:10B5E000F3A8D9094880F76BFE14E266F8FE3BDF4A -:10B5F000F77785FD7CF3996D662EE2CF7036613367 -:10B60000F26F67E6C0F9D4BC5DF07C3D7CBF7A4B3D -:10B61000B3792AD417EDFA570EEAA3F39B9BCDA872 -:10B62000AFBE35799F63C01F5F48131B4D80E76F26 -:10B63000C3A1B36E8CCD4D5AED94C3DAC30BC7C30F -:10B6400079C003CE0BF052E9CEEE181F17FF6BF155 -:10B650007161127EBF6AC700262669F12238F8F3AD -:10B6600070B755A0F9F3E73BBFCF6161D79EAF2D0F -:10B67000C94CF2FEFFCB7C7392FE5BE9CBF9FD4D2A -:10B6800089DBA560BE6FCBD7DB7E49F0EBE1761A94 -:10B69000EF75CAFB98FFDAF9FFEFD0BBEABF76BEC1 -:10B6A000D7A2F73E85DEE1360BEAAD77FE95C86E90 -:10B6B00060DEBFF97F74DEADFE8FC16ECD85F17D9A -:10B6C000CEDC77160AE495B4EB8F6C4F12A83D538D -:10B6D000D61D6314BFA2817D3D740A7C57067F028C -:10B6E000FDFD86B0AF8D07016E013F01FD0B86CEDB -:10B6F00009E0A1A5B48F7B19DA6D632DB3016CFA53 -:10B70000742AC113CA7F30E642FB3BC1CFC3F6FBAC -:10B71000EBBDD3EAA17E7F6783D400F058C7F8B4AD -:10B720002D00DBBA89365CC73438FA5925CDF8C606 -:10B73000E6EBD723F706AD2BEE9EA0AFBF8BAD8B0C -:10B7400035427F77559A981BA6746750FBA7926C79 -:10B7500034CFBB59ED225BD88DE3E978125F9F357A -:10B76000B0BE7B25C48B43B46F606DF1C6106F888B -:10B7700097B87E6C991DBFE2351E04D8A2F857F029 -:10B7800047F278678CF505C49385CD61BF84FE2EA2 -:10B790004BC65A6C6F61B06EE4E316AE0A6DF106EB -:10B7A0007F92B13FB9E24482B18E0719E2199FF747 -:10B7B0008CD3BD4FF30EC6F38DE37541DA5388D7B2 -:10B7C000D270BB1BF9C2F17CAC11BED700781684D5 -:10B7D000003E553C05E3FD6DE40D8D5FAE96D9CC82 -:10B7E0003709FDCE0816615F06FD4758BB33239F1E -:10B7F00087CF128F858DE17A4D1CC29A96C17A8DC2 -:10B80000E51BCFB6CE2B99EA3D0FC37B0D0FC0FBD6 -:10B8100088D7EE4C7212FF97D98EF7C2659E8B5D6A -:10B820000D0DF89F1FE583FF994425F1ED47EBB916 -:10B83000BF7979F01B8BFB80283198B3DC1FFD5C4E -:10B84000E54FF696E17B2233D871FDCB1C0EC9D6AD -:10B850001FFB65B4AE89CC37E8D6BF9D1D9D7478BB -:10B860008B2E8ED2C1B1CE6EBAF65D2724EBEAE301 -:10B870005D37E9EA132AFBEAE01EB50375ED7BCEDE -:10B880001FA28393E43B74ED53968CD3C1698DF76B -:10B89000EADA67AC2AD7D567B967EAEA7B6D9CA379 -:10B8A000837B37FD4AD7FEE6ED0B74F57D3CCB7408 -:10B8B000F5FDF63EA183F35A9ED1B51F70689DAE8B -:10B8C000BEC0FBB2AE7ED0C9CD3AF816DF9F74ED94 -:10B8D0006FF3BFAB830BD987BAF645D6033A789896 -:10B8E000ED0B5DFBDBE38E06C53B6CF283B9A8C6AE -:10B8F000809F40CE46486774ED618556867C6352D2 -:10B90000F86164E677BAFAD1F67FEAFA33B35A20DF -:10B9100002B25523959D58139561AC85CA877ABBB1 -:10B920004626A33C3C272F46A6DA5FF07D22DA911B -:10B930008F063F2823DF5D8E6336B10F8C87F98C2D -:10B94000C8D786D02BDD5D9AB851845F649E7EC0D7 -:10B95000877E814A9B3F9479A2810FFD215446F94D -:10B96000A3E979B4BF339531FE047A1EEB8FA7B2F9 -:10B970008B3F85CAAEFE242AE3FCBDA88CF7675135 -:10B98000D9CDDF8FDE4BF0F7A1B2BB7F103DEFE1E9 -:10B990002FA032D15F44CF7BFA0BA994FC23A94C92 -:10B9A000F28FA032D93F9EDAA5F84BA84CF54FA4F0 -:10B9B000E769FE7BA84CF74FA532C33F85CA4CFF11 -:10B9C0002C2AB3FC33A8BCC9FF20BDD7CBFF009500 -:10B9D000D9FE87E9796FFF4354E6F81BA8BCD95F0D -:10B9E0004FA5DDFF1B6AD7C7BF94CABEFE27E97902 -:10B9F0003FFF0A2A73FDABE9799EFFF754F6F73F44 -:10BA00004FE500FF5A2AF3FDAF5059E07F89CA8104 -:10BA1000FE37E8BD41FE4D540EF6BF4DCF6FF1BF6E -:10BA200045E5ADFEDDF4FC367F33950EFF87F4BCB3 -:10BA3000D0BF8FCA21FE03F4BCC8FF319543FD5F20 -:10BA4000D0F361FECFA81CEE3F4AE5EDFE2354166D -:10BA5000FBCF5039C27F8ACA3BFCDFD17B23FD1765 -:10BA6000A81CE5FF273D1FEDFF81CAD678C26053B1 -:10BA7000905E6CD57F86AB50B2B0A876E36DADEF2B -:10BA80002BFA7845E8730CE31E636A055AA73F1D3D -:10BA9000FAED7BA4270B2C12C28BB0693CFF8EAD54 -:10BAA0000B63F7E13F24C69A0B2CB47EDFFF3FFC0B -:10BAB000BDC58547BF7C10EDE3031686F63158FF00 -:10BAC000AADFFD287F772CFA618BFB7AAB30FEF280 -:10BAD000DB246F1996DB92B93FF27A32B7B75B93EA -:10BAE0000D543EDEDB4665D903699114A78AB9BEC1 -:10BAF000795D56ECBEDAFEF7A90A1CE64B247B7191 -:10BB00009DFD5C6FBB45D65FFF01E33A8E06230BBC -:10BB1000B9156023B7F7F297E1EE0D30257948EDBE -:10BB20008B18E79117586C0D3188E75FFF11DBCF59 -:10BB300067CC6981F29964D77ED40BDF8724BAC1C0 -:10BB400038C25FED8071E13F6BFF9FFF2FF77FFCF5 -:10BB5000A7FAFFBBC247B7A7384F27A35F6074E4BB -:10BB6000201D862C881763E0FD29CB051BF2D1D45C -:10BB7000857D86237FF4650E8A93DE17CD263BDB19 -:10BB8000F1CBA2520C8A7F2199EF86F19C63CC8382 -:10BB9000FE44B9C4882FCB77086E99E2D08E88D145 -:10BBA00060BF2B15BE2D5F526F9E07EDAAE379BCD7 -:10BBB0008CB979BCCC0AFF43399AD5B8760F851B6E -:10BBC000C52B141FBB8C7E2FB0CEAC8D6DE3B1F3B3 -:10BBD00030CEBCDD6C43BB51DD1414CF0D8A9B0508 -:10BBE000C7CB4253C263505E999DD9799C3BACE26E -:10BBF0006FF83D16218931D7C68B1A9F9598D415B9 -:10BC0000F1384CCC8EC475CCC5BD69910C4B49EA5A -:10BC10008AED5C408B162805A36B003E077CCA4862 -:10BC2000575F7DA87B1D8CEB08D813A91F0AB76B43 -:10BC30008019E3919FF760CB04A21AF96135EB45B7 -:10BC4000F2EBBD0BFEB918E3D833928CB40E988298 -:10BC500031771CDF5B9DDDB240FD12DE7DAF091444 -:10BC60007795D99C388CEB6AF643C8AF752E8A1D40 -:10BC7000938F745AD2B9AF0569253B3E4DEDA2A111 -:10BC8000CFC206C26B795C34A7CF7613F9B5409F5B -:10BC90007AA4CF0CB7E99816CF97D91533EEC7948D -:10BCA0002FB940F49A19A097AE5D756333D115E8AA -:10BCB000A47B5E537B428DA31FFB297A15A628F136 -:10BCC0004D855E183FBF1B2B1F8926FD50B6C093C4 -:10BCD00056ABE1D3E07D89D46903239D200FC5DDF8 -:10BCE000383D98D1DE05E9F9DDF23CA257309D8A56 -:10BCF0007F9C4AF4609F87B30D309EFB52D8E4715D -:10BD0000F07CB2127FBDAF614431C6CBEF49E1FA9E -:10BD1000F223587F3A60FDF9719D953940351FA88F -:10BD2000B311FCD7BA3882FF562751F9595D2695D1 -:10BD3000C7CCACB249235FC000661CDF6445AE26A9 -:10BD4000A7A8FB5273E330EE5EFCE3813C03AA50EC -:10BD5000B9A964D82DB8BE002468F033A134947C0E -:10BD60006915F69A6CC3E3507F2C15EC1B90AECE90 -:10BD700041BAF62CB35F0046FB65E4FC047CB10ECF -:10BD8000F9EF9E51D1BAF6772D49D0C1F352241A5A -:10BD90005F49718AEEF9BD65BD74F0143FACE7E10F -:10BDA00053A952B14186FE2FFDC544FC7CA97640C3 -:10BDB000D7791C26BE0BC6FF31B34C7104799DC5E3 -:10BDC0008EFAEF6408E7EF937F15DD0DB4EE952949 -:10BDD000EE72D96A93709DF2CBA97222D6FF32140B -:10BDE0005CF23E882F9161FC80BD6C21FD39759518 -:10BDF000C06494111FA3F5F2DC972C34CF69AB44D7 -:10BE0000E6EA477C9288EDE7C64AD4DF7D295213E3 -:10BE1000F2B36F83C5BE0E6AA77A95F785BEB40FDD -:10BE2000523DE76F878D280FE92D3918DF2F4BF230 -:10BE3000C4A21E3CBBDE44FB5ED5E2DA8A3020D1D0 -:10BE4000ACDFBE11512091F8117E4F7F1CBB16E76D -:10BE50001F98AF9BE222DE9ECE6753009FA72BDC8C -:10BE600039B44E7E84C7E3DBE285919E920D11D2F8 -:10BE7000069CEF54D7005BB6D61EF27DBFA9267B89 -:10BE8000177B36727F6E3CEA8163CB4DC518770114 -:10BE9000BD3F06F174AC31DAB08C16559B89BFCA30 -:10BEA0008D9259FBDDF2E5A283DA837E2F417BBDC3 -:10BEB0004274B101083752FFF212C185FB4EA92C22 -:10BEC000BF2BF2ED830F0CE88AF398D4C13EE3B7A1 -:10BED00020332ECD3ED6CC7744A71BBF97EB3596AB -:10BEE000F6D68E9FC781525D4BBACF413A6D0AB1EB -:10BEF0002F9350AFA644E23AF5D441B01BF08D1910 -:10BF00000DCD3912B05ED583DB880E95639AD23D94 -:10BF1000F0BCC5EAFA00F17832BEE9A9411827DA87 -:10BF2000F17CA28C76703EDF5F9BF9F28C9E5A7F8B -:10BF3000BEAD3FC1E20CF95878BA08801797C486A5 -:10BF4000237E27B226257EE1A6F149A874011FB6FB -:10BF50002ABEFF36D5609F742017D11F6E43BAA842 -:10BF6000FD1D35F138D7E72982CE0EC7A672F99E9E -:10BF70006AE072C7760AC4A740B04F5335F6B2865E -:10BF80002D277B19972032DCB73B9512A5E8056E6B -:10BF9000FF66A1FDC37D619B40F251B5D1E27603FE -:10BFA0007FA5A472F99C697EEDA9BED83CA9D68C68 -:10BFB000DF99B14560CF40D3D32677450BEE4BD9FF -:10BFC000D62E8CA2F74C7637F2A9A2DFADA0105086 -:10BFD0002F4CC77F427DF54AC1ED217E71921D9A9B -:10BFE0008671135CFFA39ED7E89136FA3D48AFDF18 -:10BFF000CFF4F68835EAED8B3334DC8AE39CB992D2 -:10C00000FBB581F188EC2AE0AAC2E5DE3386C62BB7 -:10C01000505C24F8FBD3717C385E189FC77EE3E345 -:10C02000A9B07339AD6A14DCEE76C6A7E23572307A -:10C0300093D03ECF5A2FB8911F87C53C40F89D0939 -:10C04000F88D46BCCACE88BB01AE004672537C85D3 -:10C05000E3BF660DC73FD0F913ADDDFD26C66746C9 -:10C06000BC7E03F653C6FDC0DAEF89EE7B80BE28A6 -:10C07000BF3336B9CDB811798635468421DFAFFAA2 -:10C08000780F2E0BBE59F946175CBF964579D20C36 -:10C09000A0B7A2E5A8278A6F09F05FB0BD6E6397CD -:10C0A00083F0233327D9A13678B22E6FC17DEF36C6 -:10C0B000F453E262F7E3BF003FF7AF171D2139BA2F -:10C0C00076CA790499F8BF52F6919F5009F36CB083 -:10C0D000E1537938E2E57E3B23BD7BA3E30D1E27C8 -:10C0E00013CB883F31AE877EC8BF3BDE60FFA32401 -:10C0F000F5A7FD8F603D12EC7F7C69721816A0DFFA -:10C10000F731DF17BF64F4F440F9BD14936C871660 -:10C11000013D1ADBB72BEA79558F5628764BEDF7A0 -:10C120007EB457001F5FF54604D25DA5FF74B413BB -:10C13000D9013BF1CBA9D03F7CEF97DB42A8FF733D -:10C14000A3C14E419F65CF7E10C134FA6F414F5756 -:10C15000752AEA13D5AE896B136DC05FAABEBCD633 -:10C16000BAABC3798505CD2B5C3FAF729C57BF40FE -:10C170007F5395797DBD84CFE7E8723EBF696DE658 -:10C18000C5EDFE2F9FB7D865F20B3CB12887273746 -:10C1900089AC81E8CBFD86CB56E0A73E18BF594E4F -:10C1A00076FD542C9330AED3A1FD5E6121BF60C6F5 -:10C1B00056BEDF7A5A28EC4A1BFFEF79221E42B99D -:10C1C000DE2C32B44381F1B4DAED95A9B11ABB7D0E -:10C1D0009D78C3382BDAB3D9803AE4FBD93BBA3225 -:10C1E0003CE7B2BC903589B40FEF253D062C44F1F5 -:10C1F00069F0C375F1060BB35BAD48A70EE2AFFF64 -:10C2000048BB30690EE1C3978EF857BF5FD3C9634F -:10C21000EA8A7ECD2681FC9AEAB98511850CBFC3D6 -:10C22000E3669B53B99DDAAAE839C1514B7131F0ED -:10C23000696C8FE3B8D6F0F8307B9735217E11A674 -:10C24000F8B181CF43906CACAC2F8FCB5BD1AE8576 -:10C2500019C8AE05E3E16BE53BD5A281FCDF2A33CB -:10C26000F783CF0BFCFCC7BB8A7D7C3795FBC31FD4 -:10C27000A4F238C479F403A1DFF3B758DCF502BAAD -:10C28000AD465A271B075BDCE8CF18AD611E3107AE -:10C29000D16BFCB6559E015F93588B09E93926FF97 -:10C2A000818D389FC3DD984DEC4CD54EDC479848C6 -:10C2B0009A81B1FDA62FDFC778A40C6D45582B4C91 -:10C2C000CC3FD103DBAF4118E67F38A4E97D8CB3C6 -:10C2D0001C4E3232DC1790DFB190FD370DF1F6A025 -:10C2E000386527C61AFA603C66F722E4A33D71D18F -:10C2F0009936683FD9D8C92E72FD33F4028EB752F1 -:10C30000E0FB370BBD79489F9BD942DB712B6D2D2C -:10C310006CB91AFD53FC6364C7553E8031550D81DD -:10C320007F0C649CB1F2099F3A18F04AF0F7A973A8 -:10C33000C7ADEC8E9B26526FA47355B2CF88FB29F4 -:10C340003E81F9D6011EEECCF7191D482F076B1A56 -:10C350000BFCEBD9C704FC0E8A007EF76E4FF2305F -:10C36000C403CB945824D48F354A04772F6651A246 -:10C37000B26F8071AC438304A283C12A9970DECE70 -:10C3800062A12FEE8B562DB8BE71866CF8F5B8956C -:10C3900083013618F87AF621BE9E9D281F19467E25 -:10C3A000D26026201FD6443599681D0DF282E3EF36 -:10C3B00003DD68F137D1E8E5E3AB84F115A05CA4B7 -:10C3C000121FDF5B2B903F59636E3FAE119BA6EEB1 -:10C3D000CBD9246C3F0BFE857C3D6BC7B634FCDEAD -:10C3E0007281F3C12C95CF5ED5CBE58034467CDAE3 -:10C3F000115FE72AFDE7A619F839AED6EF3591DDD2 -:10C400009DB5E38343B8AEECA8FF6A0BF3105EDE84 -:10C41000B150FC4030F852892E8848A0C344F4271C -:10C42000C145EC9BC6FD44953F2BD0FF48C192C748 -:10C43000450CA03CD11E56363E6F46A4059F3F02D8 -:10C44000C787CE01CD5C1FFC5C135711757A87E25C -:10C450009E82D9370DC723DC1A62477D3CD1DC446C -:10C46000EBF2E076A646EE679996703F8BF6D50024 -:10C47000B62CE77EE6C4EEBEDE8CF49C6DB890C4AC -:10C480005AFDE20AFE69785EA5F38B2D1847C0B805 -:10C49000D72AEE0F1A15FFB57CB9DE5F98B850E3C6 -:10C4A0002F52B7BE6A1CAFE991508ABB58D09FD0BB -:10C4B000F8017F3794C8A887E564239DBF34B16035 -:10C4C0007FC2C9783C933F372A7EE2D034936EDF37 -:10C4D0004D1EC232110F65A8875250D53897603C67 -:10C4E000EF220B6FC4B8D930F1118AFF95D5F373E1 -:10C4F00069C1F1BF8BB5EF3F8BEDB11E9FCFEBF460 -:10C500006322EE6FC2B2D429DC0AF2DDE9F06517CE -:10C51000CA07282A13CA7BC8FE6F10160C914CC894 -:10C52000C7EF7B9EC5FE65B3D5867AEBE9D008EAF6 -:10C5300067FE7C81E2C30B6D5CDEBEFA327C1DEAD5 -:10C540002935DEBBB8B0DF2A3CB7F4EBB45DE3AC11 -:10C550003D503D303AB70486F11307CCA7F40AC822 -:10C560000DC1EF8F7344029FBFEF9B64053CADDCB0 -:10C57000F0FE3823F0E3F9DFF99E43F8850DFB392F -:10C58000FC5B5F6208C26907C619418ECED7ABFD5E -:10C590001D18E7C07DF7DF73B801EA6580CB50BF97 -:10C5A000E1BC070AB4EEDF8076293610EF2933BCF0 -:10C5B000CBCB21CC83F6F35AEDFE98E6DC80F65A1D -:10C5C0000C3F168EFEC5960C07C19B539C8FA5A1F0 -:10C5D0001F74D0DD2516E35806D68274013BE66849 -:10C5E0006F5F7A432A97DF4DE9BC3F155FD0CFD309 -:10C5F00069B137DECF6D6DFB71FF3BE3E99401FD5F -:10C60000E4E9FA79E9DFE9A72AA81FD56F030758FB -:10C61000423D7526D3F11ECE73D6AF1D43B6A0FEA4 -:10C62000D92F129F7E57BB2D1DEDFE77AF5AA2D199 -:10C63000FECD7AFDADC40A8C23287ED199E6CFCCFD -:10C6400012BC3FDB2F3207E8E91ABF40E5EC2DCDE5 -:10C65000E6E1D978AEB6D95CA4195795324EE074AC -:10C66000E3388D1FB32F4D8D3FAFA0F1CE7AFD94EF -:10C6700011E939CBD0741CCF1FB3813CEE153CBF00 -:10C68000CDCA7B87F1BC413B71808FD2B8DF11D717 -:10C69000CBB11FE7B709F539F28B819F0F096EDF28 -:10C6A000359DF757D689EBF9BC83F68A03B4EECBF8 -:10C6B000318850F63F546B2E87E70752861C4A6B31 -:10C6C000370EE9E371C81D3C0E5916D532178C1987 -:10C6D0008B4ABFF804CADBC8A755F900D103FD5245 -:10C6E0006C51E190F14307F33817C29737189EC495 -:10C6F00073847B3BB5FCE200DA87A5E16C1DC8D9E9 -:10C700007D03C21337C338A6CA9102D84E566809B2 -:10C710004F9F02ED4E241746A5F3F327E41F9E48D2 -:10C72000769EC3F17993420DE08C309799C7B35C44 -:10C730007F16299EE5CA0975B9DBC1D719059F5136 -:10C74000E9DC3FDB6B8071F6C571F0F3BDF097B8A3 -:10C7500019E34D0B7A0AC877EAF76F4F29EC9C9ED4 -:10C7600017F8FEED29CE1FD362B5ED2319B6BFDE53 -:10C7700071FC53B1A79DD339BD9C8381BF347A7FAF -:10C78000DCD0501D5C3A2A9A39B4F1CDD2041D3C5C -:10C79000A12C45D7FEDE69BD74F5A32D2DB9B537A3 -:10C7A000E0EF8B119991B4FECFE3EB90AF765CFE96 -:10C7B0007422FAB1EB45BB00F39AF1CE864F0751D4 -:10C7C000EF12C5B94EEF15C91E817B6BD6EE9F9C4B -:10C7D000632D74EED8D87921D9BF5971FC7CF70C40 -:10C7E000B77EFF438DCBB7B76F82F6AC0ACFC5B427 -:10C7F000B76F1288C7FFE4FE49BF74653DDC97F54B -:10C80000E5EBE1B37B60A6AC687B33D1AB619F689D -:10C8100047566DE8213001C679FB168B3B04C67D77 -:10C82000EEAD236649B37F52E30703108DEF1D3150 -:10C83000E379AA03695C6FCFDE71C1CC902F763C9F -:10C840004072DDD2EC8A8945FB05FEEAD65CE4AF96 -:10C85000A65CB47F7B0D3627EE87CD5A3282E2CCC0 -:10C8600091FE895456358EA07EABFDE3099EED0FF7 -:10C8700025F823B165CBC7D8CFD39136B4E7D546D9 -:10C88000F955A44BB514DA0FF7AB666FF9F8D2AFD0 -:10C89000D08EDAF8BD8ED1E227B9583FBAA7CDD0F5 -:10C8A000D019C71B42FDB40CF92217ED5231AE0B63 -:10C8B000E079D5E60217CA7D6143B80DE55EC4F3A1 -:10C8C00064EDF0E9E474AE5F4C5E3EDE61FE12EAB8 -:10C8D000AF757D9F9E4CF3576153EC7A23EA0F7539 -:10C8E0001E2630F858DEE1EF4565CD9612239E8B6B -:10C8F000FF73E6F3318827681F8665EAD041A46795 -:10C90000BEAB1D10C9DAD15B6A6951F4F044D4C3DF -:10C91000D05F69A6E3572897631EF11AADA847C3F5 -:10C92000AC36DCFF1893DF47AAD0CC477CF71E5CFF -:10C930004980AFE233A11F30114AADDE9EDC817D1C -:10C9400091D30D8A5F54CFCF75AAFA7DE5130CD72A -:10C950006193F859AD56B9AA56DAABEFB708DC1FA8 -:10C9600090B7F2B87E75A6EB491C6F4B219BB0992E -:10C97000F4694B6249F8CF37FE08630BD139C22600 -:10C9800019705F41AD5FD53A0F2EDFD79AC722A548 -:10C99000FD47229B8F7CF1D16DB7B538A0DFE687CC -:10C9A000FBF5133576EAA5747EAE99D97C57485FBE -:10C9B000EC0C95500F8CC6BD87DC80DF8FE72131F2 -:10C9C000AE51B3D3B20ECF83D544C03A1FBE3FAAF7 -:10C9D00097EB25C447F3AE824B788FC6810B33901B -:10C9E00073C78E0197F09CBDC30ADAC68E7E90E3B2 -:10C9F00065D2FF1D8CF75AFA2C75E8AC18F427BEE7 -:10CA00008321A1BD05BB9F7B90C34EC4976B099743 -:10CA10003F9722875314FE2D57E4708A91CBE1E4AF -:10CA20009591368C77963F22F4C6F3724C0AB7A3E1 -:10CA30000A30215FF643FEE47C59E5EFACC87392FF -:10CA4000D20FE7FF60F99CED8FA676AA9CBE9CE909 -:10CA50003AC4ED5C4BEE7C18D71D20D7A8F75C0BD1 -:10CA6000E273514E027C62B6213F019FC45568F8C3 -:10CA7000A0A1F90723F28969B0407C6281B248C362 -:10CA800047CE56FFC436BC0BFA550B930CCB58A0BF -:10CA9000FEAB74D54FB93E7EFFB3D2BE3C0CFC0852 -:10CAA0008AFF44308CAF5D8C91284E3A67290C1276 -:10CAB0005030C7E449C338CC9C0742280E5671B0A9 -:10CAC0007671B8D4965EF7F873687F79BC3F95CAE3 -:10CAD0000329AE33888F29FEBB143CE65CD7FE5C8D -:10CAE0009E83C7DD4C6E8B7D6D12C6DD5C22EDC76B -:10CAF000F560B627C94EA9FB713CEE86F13C8CEF80 -:10CB000005EFAF611C0ED7D39618836E9FB04D3CD6 -:10CB1000AE50BF9F56D5FC497F03D49F4E72505CE8 -:10CB2000CEDBD365CC8079CC1CE77EDDA4DD6753FA -:10CB3000F0D864F4A4A11D6DAAE5F8695A2E16D3A5 -:10CB40007E1363A1259AF3BAD7E2E399FE14C28F4C -:10CB50006A5F54BDBDAD8E0E7DB6EAEF6BD99D6A9E -:10CB600085DFAB91DFED6DED8CCAAFC1FCACEA6740 -:10CB700053EC41D24377C02BE83FA8FABAB868D04B -:10CB800060B4F3835E4AD9F227987F74A62B3703EB -:10CB9000F8E7B6577AE4AE06F80EA3DB680BBB1EC7 -:10CBA0007DF88389F4E123258CF421945A7D68EA89 -:10CBB000C00F2FC8B8317D9EA1B4073F96FB87A058 -:10CBC000AFB5FD55670E1985E32FC9E076F2E71A78 -:10CBD00077477ABC244395CFEBD3E3B72AEDAFA5D3 -:10CBE000C7A765703D1EACB7411B93DE3EFF4E16D6 -:10CBF000C5C90E33D0F368CF76844A1B9234E7DC84 -:10CC00003B45BAB57A3DAED7D469C8EFD7A1D7EFC7 -:10CC100047FCFDBB7A7D78C926F2ABE0CF39F656EA -:10CC2000587FFC06D677087F04EBBBA4B6F2102C25 -:10CC300007C17C0FEB912D1FC3F8F63ED593E20E92 -:10CC40002007C4F7D5C0F72807AABCCCDED227122C -:10CC5000F70DD85F4486FA3F580E8A8B5E31629C8E -:10CC60000AF538E26B37C83CEA99603BE1CF70AD1A -:10CC7000C4F9ABF2A0CAC1B5F9E82D13AE4B4D55BE -:10CC800017B89E8752ABE73BF2677E7F83FCFF6855 -:10CC9000C6F5F901AF66F07B103F23FFBC9A717DAA -:10CCA0007EC16B19FF915FF036F10FEA4F5CBF8DCB -:10CCB000FCD01E398FF30F9D4B047EC8C5B8F3DE40 -:10CCC000FE3DEC18A7197995FBF5A0D3C9AF0FF677 -:10CCD000AB272AFA6FB212273890E96CC9E0F24A02 -:10CCE0007E7B614A681FB457D7EBEF4D8CA965185E -:10CCF000679A0CA5564F58906EEDF8EB7FCDB83182 -:10CD0000FBBDFB3AE97B3CE33FF6F37CD7A30F5234 -:10CD10001DD6F188CFEF3C468678BAD67AC0B48A61 -:10CD2000E3598517798CAADD8C46BB09FC71E13F7C -:10CD3000E18FD1454D97AC40D7C84C6329C603EF6E -:10CD4000C2B31614CF30AD74A4A2BE61EABE00C552 -:10CD50003B3E1255D87C70288C63E4932CB06F0056 -:10CD6000F5C30647B6C6470416681F91291E5C4ED8 -:10CD7000E3E6E75598CB6BE4FB640A9C0B70B806BE -:10CD8000CE0F82D7F0F611462FB369FB51F4CF18BE -:10CD90001BDF1708ECE7F9867746FF6F8B60C3FD52 -:10CDA000857B079F37633C677491774F02B44BCA0A -:10CDB0000C2F0D03137FEF1681C6DB6763CC4A3956 -:10CDC000958E6C39F0BC61553EDF37B134350F7745 -:10CDD000B4C3877D32F5760AFF8C5D283E467F9688 -:10CDE00026819973793FC949D7F73ED28FDE4FA686 -:10CDF000F73D9698EB7FFFEEC1CCE16E878F6ECB4F -:10CE000054F421C685D5FE8126E39B04477B719BA4 -:10CE1000DB95F62D064335033C8DDD98B912E35EB4 -:10CE2000C318E78B928D19A532E73FE6089AEF4FBA -:10CE30008D372F53BF3EC33F49FFBEE7A7F035A84C -:10CE40000DBE14FA57EAF924D2E87CEF3B18476488 -:10CE50008C60433F75B63364398B44BA2B7C2DF715 -:10CE60002D750C86F985305D1CAF95AFE57EA5C8A4 -:10CE7000D7B399DA3E6F25D2DF69686DCFF97C8729 -:10CE8000D0FA7EA691E127E8FD591B7357629C1CDE -:10CE9000E841F5041B7F82CF9B82E0C14172C1381B -:10CEA0004C72897A19F093D6CEFEED1205BFE704D5 -:10CEB0007EBEA96508F7E75A9279F96226F7DF1E68 -:10CEC00057F0F8B452B674D2E0A17B80CEF0E7C13F -:10CED000F58066DE84A77B629479CBE34B47C1BCC7 -:10CEE0005AA2586F01F864EDC6B12B176AF8E4F93D -:10CEF0008DE34B110FADFDC92507118FF728787A07 -:10CF000071E3B883C84778E404E5AD3A9FEFBF5AB0 -:10CF1000B67CDCAEBCCD69CB3F32E657A82646C214 -:10CF2000F704872997F793DC0E7EE6B77DDF11F4CF -:10CF30003E33C5DCC8FB0A7D4605D1AF38887E4349 -:10CF400083E0323D1CF083A167F09FCAB7AF58D48D -:10CF500005E3671B05BA6305FAD92CC0F31D99F7E1 -:10CF60009586C5239F4AA60468EBC99C7CD09A0588 -:10CF7000F288FA8BF4AF8BF4F578947382A7943A25 -:10CF80006E46BEA95D1407EDF76496AFC47BAFF79C -:10CF90002E5C6142A4FF3973DA4A23F47B4FEE1F03 -:10CFA000F7607F46A1E2E028E127F8B431681E6B04 -:10CFB000826039A8FDCA6BE8F38541EF3F1254BF88 -:10CFC0003C085E15042FD1BF3F651ADFBF9C02F4F9 -:10CFD00043C45D4B5EBC99ADEB8656FB25A03DFB83 -:10CFE00050CFEF231B387C6AE383A54BC23470E635 -:10CFF0002F4AB5FC6B52ECC5C418A7A33DFE3DD427 -:10D0000011FF6406DB3559772EF130633AFBBB5BC9 -:10D01000D4C3CDA22A5F0B0ECECDD6EC07CAF5A5A0 -:10D02000184FE978BF422EC5FD8A918FABEDEB4AD0 -:10D030001D9AF9A9ED87FFEBAA88DFBB9A5957BA69 -:10D040009EF6FF94FDBB285EDE76E56A04D2653865 -:10D050009E1FC5FA4E9EB439D99AF9B1A6749C5F49 -:10D06000F3C3FCBEA1DC00F400392F6776DAFF6E53 -:10D070008E8C9CFF02B4DFFDB0381FEDD7E1F9D1F3 -:10D0800074DE686C16F7B77747F6EC723FC0CDA137 -:10D0900093CD18576D7E741895EF8A8EC53E407EED -:10D0A000F7ACC74AC3B2B03E92F012F7D2D2D27AEE -:10D0B0009083842C89DE7745D9BA6C473F7499896F -:10D0C000E1FE1363F6E7884F7E6B213F754A7D2FA3 -:10D0D000DAEF29FF5DC9F0786857BEC844F17FF8E0 -:10D0E000A3FB18AE65C3CC583F6DA152CAB753B964 -:10D0F000EBC7373ECCA17D1D91CEEDECF4471D076B -:10D1000049665FCBBDE9BEC25125BFCA962C5746C2 -:10D11000168CE3EBB3A9942F85D9A48871E8B7DD09 -:10D12000E4C8CC8A0DB4DBF5A348FB556F9F2DEF07 -:10D1300082FB7B7DB338BFECF4977729D7D8F58A8B -:10D140007346C2F32EB33417F5C6AE4E3D0499E4D0 -:10D15000B6291AE3ACD314BF19F864FE1BEDF061D5 -:10D16000CF2C91F072CC321FCFC2B2E6DFC40EC614 -:10D1700071A9EFE51D743560BE185377A9AFD63F8E -:10D180002E481B722B8E37C05FEB499F937F0CF0AC -:10D1900088ACB52B65B01F6C37F8F5388E18C770A2 -:10D1A000E427F53C1E8B6B4AD7C615027EE8024584 -:10D1B000FE79BBAFF070307CFFAB5743E8DCD7574C -:10D1C000F217E15AFF58958FE911FF73B885D6C55C -:10D1D000919290087C63AC3BFE10BC57F1AC89F493 -:10D1E00066C5B3B18FF8B01EE8895B86C1DF7D3EAE -:10D1F0008B9F07E8583E36970EEDAE958F4DA538BC -:10D20000DF8EE4636AD6A60EE4A3AE0BF2D1F0671C -:10D210004D74BEBAAC53ED5D18472C33DCCC1A60AC -:10D220007C439EFD4517DC6799FEAC85E8EA0D0F4F -:10D230003FCEE7D53309E7D56A7FB2B8BEF2D6173D -:10D2400090BD100DE09D81FE16179B683D22763142 -:10D2500093DE1323ECBCBE134B5A0076795178BE93 -:10D2600084F4752BF200F512F25951E4843BF05C22 -:10D27000CBE1F929B40F762A97EF83CD78E8F90846 -:10D28000F43FBF9ACBCF77CFC47C3BB8CEFD37F706 -:10D29000BD6A947C3BFF5BFB5E4F6429F7865AF7BF -:10D2A000BDF839D0DDF3FBE572BC30C982784AECB9 -:10D2B0004378B9DDCAA410C08B18C5D251FFA8FBB2 -:10D2C0005EE2AFB87E120D02ADD38FD5C994BFA078 -:10D2D00028C2CA9FFF8ADFDB139F2A61B40F16534F -:10D2E0004BFB60E188578CDF0ACC89F27334C49E13 -:10D2F000F84036F25F08D173FA73333EFD7D2ED2CB -:10D300006D748C2E9EA0F09FFAFE89FA5B687C27D4 -:10D310000466437B5FF4878CA1489F66D1F5D43DBA -:10D32000A4374369FF9CD9BCBF1D00F0F47A58674D -:10D3300033E49BF8C4E4EC403FD3173C9C8EF42EBE -:10D34000FA438807CFDF4C5B18B20ACF6154EDE097 -:10D35000F7BCA72CFD8ECEE3B224632DC639BF5E89 -:10D3600018C2CFA96F1940FC33C5C0CFB9B0443340 -:10D37000C597AAC214B87B3EC19AFB4B66A4877AB4 -:10D38000FF660FEA15F8FE71151FE837A2DE55CFCC -:10D39000D1B35A09E5BFCC20B47BCEEB6F59DC3F4B -:10D3A0009D9268A7F3A2D58F59EC0B92389DC5FECC -:10D3B000F85D46EBA26A836FF82AECD7C0A4AD36BD -:10D3C0005C3FB454E07A9B6DC9A03C04354666349A -:10D3D00047C17389EB33753C3552C9EDC44F46766E -:10D3E000C81885786CF9B405F96341B8847191EA7D -:10D3F000CE7617F51B6EB5713BA17C17C79E827C5C -:10D40000E03747211F7C2A182C3CFF80C300F5E73A -:10D4100019AF6FFDCEC2A5D9346FABCD30241EF944 -:10D42000EEC2F055F0DEED4C4A8EC77B624BA3EFA7 -:10D430009A80F5AF89A49740981ECB477FEF35B10E -:10D440001FAE53A72CDD4DF39BB5A90FDE20605313 -:10D450005E3F40F66996C25F5EE5DC5A39C09B10BC -:10D460008F8A5E7089AC96E2610A1E5BF1ABD4577D -:10D470002F35113DAA175988CED5F57FA37EABC3B2 -:10D480005BBA203DAAB79A287F87F5263E8FF2FA2D -:10D490001E830FC1B8CB4D9136011E55C9A3CD08CF -:10D4A00057350A04ABDFAB5EFAD72E866CDE1F96CB -:10D4B0001603DF670DF41B9B88F6ECCCABD18953C8 -:10D4C00034743FB3705B04EE3B1F0DF1A4E1395F90 -:10D4D000DF0321763C57A8C6D3CE2C4CE3F7816CF2 -:10D4E0002DE1B85F3D6D6E4A14DAB9C3368F19EB82 -:10D4F0000F3725E19139E6B0D90623EC30DE4CF048 -:10D5000019E51C09FD61FE4081F34DD5ABBBCDC9CA -:10D51000F0BDDE3771FC9C7BEDE89E81880FE02337 -:10D520001BEA9FC49674B4C3D58696F404A4CFCBEB -:10D5300002F90BB03E7560FE91D9C8577D411F2A94 -:10D540007C357BCBB679289FD56F9E1A8E783D3778 -:10D550009A99313E56ADCC1FD68FEF19A17DF5E6D5 -:10D56000B5C3197FFF3DE43BD5DE03BCD004F05EBC -:10D570003387736EE2FA79AFD94B79EFF6DEC518CF -:10D58000ED9F19D9506C0794E7F7004451B99F56A5 -:10D590001B378EE7DD93B5E7E766637D76A0BE2394 -:10D5A000BE197B9341A1B385ECD258C40BC0DEA554 -:10D5B0005B23902FCEBDB67BCF40948BCD828D69FF -:10D5C000E54195C3441FAF07FC3D81F8DB7C613822 -:10D5D000E6A19879365C421AAA7852E54DC54B0D02 -:10D5E000E37850F1526354F0A4D43B153C54311FFE -:10D5F000F5C7CEF6963660FF6FFE40FB6DE7A630AE -:10D60000819F13E679D1D4F9B9A2F4FBFBF5377108 -:10D61000BE9FA4CCB3CAC6ED62550C93EAFB109F23 -:10D6200039CC6A7E4968726ED311DDF8572972D001 -:10D630004A6F9C078CD36BE0F70483F5D75C85AF0A -:10D640008ED44FF4A05E9929433FB9280FB649B84C -:10D65000CFC95E1715FD0D3653F3DDA2578E101F8F -:10D6600082EE92A260CD62DA08E340FFEB6C0F8A93 -:10D67000171675F5D2BC378CB23103E89323823785 -:10D680007C3BDA838744D253EA381DF287440F4744 -:10D6900013974FE4178C0FB6EA85A0F1D62BE3B5AC -:10D6A00018EC5E3C17CC1608747F4D5C702EFC1095 -:10D6B000B77714490CF47FCB7BB81FE9B814210964 -:10D6C00054633762BBD9972292D17E1F51E20E4735 -:10D6D000166D8B28D7D0E1A98EBEB3788084F42F45 -:10D6E0000A3BF430CAD1634ABBBD66FBD0F9A80F30 -:10D6F0002E4748785E6A6F949C8D7ED45E035BC231 -:10D70000A2381F1ABB04F007F242F8837AE9495B9A -:10D71000402ED57103DD3C483768EFE07264A77D89 -:10D720008CD9317C5FF4DAF2D4CF4BFAA95E90D673 -:10D73000E506DAA9F7F21E55E64D32D225600F90C4 -:10D740003FD1DE59943C46C179506FEFDE3911F17B -:10D7500057136635E0122EB83E180EACA76A8DE856 -:10D76000E7B385717BB4F7D28E86C874FFCC172FD0 -:10D77000B275408FFA073EE0E77977F07B5BAA9DB0 -:10D7800086BFE5ADFC07EF55E65E188EFAF5C502DB -:10D790000BDD6BEADC2B99BE739A35990BD1FE9F9A -:10D7A0006C191E2105D627B75CF28891E42F24E975 -:10D7B000D6075567DF2379AE662D741F7BCAD20367 -:10D7C000A30720BD5F32D1F981698D4964E74EAD71 -:10D7D0009FDA0FE73B65511AC13336DCCFE1A53C38 -:10D7E000FFE19445792FA0FF7534C4311CF9D9B7F6 -:10D7F00042B0E1FA6AD086BC47EE85FA41E13D3B92 -:10D80000E3B8BF5A7F7434D2FDABF922E927C7FAD7 -:10D8100027EFC27AC776116F8CC17AC6F608E63553 -:10D8200065C6481BFA05EAF9C20613D7B76715BDE6 -:10D83000704CD113C714FE2B6A6848477FC9B716CE -:10D84000EC11EE7B9B7D1574BE5BB0D9D701BF9CFC -:10D8500014648299CD965C5F80F759D6507E9CF314 -:10D8600069161BFAC9F759981DFDDAFB76F5E88BA6 -:10D870004B0587B2AE1A1DCDBFABE24BFDFE19E5DD -:10D88000BB4C5C5E41FB0ED15232EAB7BDCAB9F166 -:10D89000A3CA784F2D7CE92EF40B4E6D4C8B621A87 -:10D8A000BC9F52F234CD003DB8B99DF59EFF2635A0 -:10D8B000EEE0A6EF542AF1C07DA6C6EE98F733F845 -:10D8C0007ED789B52156CCCF1B7CCFEB8489DB8FEB -:10D8D00036F7BDB6EBE1E03CB7C1E3695DCF04DFED -:10D8E000FFEF15D6AE1FAFCA59F0FB6DEE93A75EE2 -:10D8F000DFF92ACC4B86F7BD77DFC4E8BDA1A1FFD5 -:10D900007A03F57545A3C586F7EF8F8548B41E9257 -:10D91000F398B401ED8C558AC4F5FCB17DFDE8FCAB -:10D920005FC5978CE4AA628BE8C654C5EFADC87892 -:10D930007C30C0F76F31D9F1FD532B57DCC5C54C96 -:10D940009F67219F71F99C0EEB248F2DB02E0A5EEC -:10D950002FCD5CB589EE11FE5CEB25358E148CEF76 -:10D96000825EFA7C0BC1F7E77601DBE4F76D8BEFA3 -:10D97000B3752E5A177D5B57496541D3DAA2040966 -:10D98000EF531C796C10CA4D7824C543CED6D5D23E -:10D9900026DEB7DBFB5DC1FBA16F8745DA505F7CFC -:10D9A0005B375FB95CA0F089C297B76C6916131832 -:10D9B000B5DF3108DAEF0C8BA4BB2EA98EFC48B47E -:10D9C000F32A5D83EF37ABF33BFD10A7AB3ADED311 -:10D9D0001BA746A0DFD9BC3A7A4701F4278746DA6D -:10D9E000D0DF9EAE9C7F39BE8AEB9B93D6C817468C -:10D9F000E1F99935E3BBE0BAEE7E93CF6C877EED1B -:10DA0000EF9444E07AFF1BA33702EF1B7F03ED3D49 -:10DA100068278C6E11F5DCC06246FB78033D462614 -:10DA200025D19639F145C159A31BE97AC67369F727 -:10DA300055E4A3B3068A770166765F85F6F6F09E15 -:10DA40001427BCFF2DBEDE64FFEAC4EB83EE2D3E3F -:10DA5000D18BEBA5136BDE1843EBF3F5261B8EF38E -:10DA6000DBF57FED82E77066327EBEFEE44681E63E -:10DA70003113F8312409F5038F83CE04BD6F15DA15 -:10DA8000F261D1C67AE2C399C08716F4D31C3C1F59 -:10DA9000F34CCCC72CB136F93F3A2B7C370BF80E40 -:10DAA000EFEFFEDC793F96F50A3EB7CAF950A5BB09 -:10DAB0008A1795FE013E64BAFC82514D7D0A1358C7 -:10DAC000401FA8F73B98D1BB1CEF69CC13C31B3197 -:10DAD0005FD57E63ED1F286F8B6C641BC89EB34CB3 -:10DAE000CC97374FBCC98EF1C006736D6B5E17AC17 -:10DAF0000FCEEB2286F1F74B303F31CC372C3B89F0 -:10DB0000BE37CE661F86E836C578292E2016191C2A -:10DB1000742FAFC142EBE6603DF48A42DF3BD07721 -:10DB200040BFA7173FAFADDEFB534B30343D90DF16 -:10DB30004B42A32E4BD064FB2B9FDF89FBB4258384 -:10DB4000A27E9102DF6FEE75E44EBCB751D22F6A10 -:10DB50006B32C0BB5FF93BAFBF392ACF847E80F008 -:10DB6000F59D43D16FECE578B397E63B6ABFF0FCD7 -:10DB70002D7CFE79A2EB9D5E7CDFB402E97D5E88A0 -:10DB8000E0F9DE527D140755DFFB586087DF16028F -:10DB9000B0D7C41231AFC1DE5E5C9F7654C6643B21 -:10DBA000F6F0EFEB9F2385BEC375A6B2FF63B04AC4 -:10DBB00066F4FF9C76B39DE757644E2BF8556315CA -:10DBC000FE2DB75E194AF6B796D92D98C06489FE26 -:10DBD0003E5656E0DEDE9A1BB9B7C7649E87AF415A -:10DBE000C9C3D7D13D4A61C7073FA07F197C7FAA2F -:10DBF000DF5F5ADE443E19037C85F622B785C36396 -:10DC0000153EA9DE369AF23DCFF9D8E4463F61864B -:10DC1000E28FA5BA3A3109DA5D06F945BD70768C16 -:10DC2000271DF5C7893AD6989A86F12A970FE9B247 -:10DC300037E903CA8B76624D4304FA3DE7603D3114 -:10DC40000ABAA852FC7B7645F4DC867E7052D6BABE -:10DC5000651A7EFBA117B7FF67933C89B8BE919305 -:10DC60002C3C5FE395DD94E7B93879441EC691F604 -:10DC7000D76D6747D302EF75741F65A06108CBD6D7 -:10DC8000EC4B8E31B67F4EE3A49A4F733DB7DF164F -:10DC90006323E5D10252D6D613ECA4B8521CF22865 -:10DCA000C687A507095E3C83D9E81E6B609F8EEE90 -:10DCB00083AAF477D8AF0EC5766380FEA86F0C56A2 -:10DCC0009F116167313F9F920584437DA2D27F9867 -:10DCD000F8C863488739CA3DAE39422D874D563A58 -:10DCE000E71AAC1F31AE59467A53DE5380FE18E86E -:10DCF00049CAABA0E84509FE477991F2D79AA9D95C -:10DD0000B5F322ED29F80FF4634EB63E8FB84A27DB -:10DD1000D5BFEA884EAA9E047AF5BF117AA979CABE -:10DD2000E63CCBE39D739E9D1AD797F0061287FEC3 -:10DD300050DC1F29AE325D99035B134D7C6C1AE2F7 -:10DD40009450DF8EDE9EC024783463BB40E75B478F -:10DD50006D8F2638C21FCFF32A29F67EF48B5D879C -:10DD6000607CF2D40B5FCCC5BCF7A37EC3287E6C6D -:10DD7000080DA37C13E210258F8318F63EDE63BDE9 -:10DD800028196BD15E39599BFC0106A2FF5E7E4EBD -:10DD900016567932A713BFF737671FB7F3730AF91F -:10DDA000BEE0457C03DA5F2C15294FD3D3A139E4BB -:10DDB000BF35DC69A2FB114C767C82EBAA090A3FD5 -:10DDC00058E26061A9A1578804F2AAA1CFA3218FCC -:10DDD000BDEF82FEBDB0EE12BA811F9B19A5AB3715 -:10DDE000CA21DF60FE58539C6873C3F8C3EDDD742D -:10DDF000FD39C52A13C653988BFBD12A7F31F1AC6C -:10DE000091EECD0FE6F92BEE9CA0BF27691A7C613D -:10DE100028D99BC17AFFDB798DBC4DF3557ECA6250 -:10DE2000594A5E7AB2FF170FF2FB211273AE52E528 -:10DE300005F53F78374F237EEEDA6B626E89F0F797 -:10DE40001AD65F942D368C07B4FAE1A9F05E0C1A4D -:10DE5000492BF139E605D5CE13F3826AF182794177 -:10DE6000B530E605D5B6C7BCA0DA7ACC0BAAADC7EB -:10DE7000BCA05A18F3826ADB635E502D8C7941B5E1 -:10DE8000ED312FA816C6BCA0DAF69817545B8F792F -:10DE900041B5F59817540B635E506D7BCC0BAAAD62 -:10DEA000C7BCA0DA7ACC0BAA85312FA8B63DE6050F -:10DEB000D5D6635E506D3DE605D5C2981754DB1E7E -:10DEC000F3826A61CC0BAA6D8F7941B530E605D536 -:10DED000B6C7BCA0DA7ACC03AAADC7BC9F5A18F368 -:10DEE0007E6ADBB7B0856968C7DE4A72EDCD8EC544 -:10DEF0007DA793C4CF87EE037E4639DC3BDE46F92F -:10DF00000B6F709DD892ADAC5B14FEBDCCC226E108 -:10DF100039F48EDE57F9F3257C278FECC112E25FCE -:10DF200016DE88FEDCA34607DD87929BF8FD44667B -:10DF3000E47EC03C51F17F94BC10F34489FC00CCDA -:10DF40001D6CD48CA7B3C3CA8C1A3C4417DB747005 -:10DF5000AC334ED7BEEB0449571FEFCAD4D5275474 -:10DF6000DA75708FDA7C5DFB9EF31D3A38492ED648 -:10DF7000B54F59E2D4C1698D1374ED3356B974F5B8 -:10DF800059EE4A5D7DAF8DB53AB877D37C5DFB9B8A -:10DF9000B7CBBAFA3E9E25BAFA7E7B1B75705ECB74 -:10DFA0002A5DFB0187DCBAFA02EF465DFDA0934DC6 -:10DFB0003AF816DF765DFBDBFC1E1D5CC8F6E9DA7D -:10DFC00017593FD6C1C36C9FE9DADF1E7744573F2C -:10DFD000423AA5ABAF3AC3FD7BD600EB038C538628 -:10DFE000F1FC1AB33DAC09FD8B91991774ED4D31DD -:10DFF000B05E00FEA9067D887EDFF79D12291F33E3 -:10E00000AB8DB0E3BD6F7948ED1FB4F7BC47DB7F44 -:10E01000D07DFFE9D0084F08AD2FAC646F6FE9CD1C -:10E02000EF9BB5E61351EFB3331F8B8BA190900F8D -:10E03000FD23017F6109E00807CF0B0D7E10F94F2A -:10E0400036F08BD0DF6C5D17199292D02E8706FCCC -:10E05000E2EE5735795EAEE5178FC46FE7519E5EED -:10E06000476F2867366D1A8EEBAC194C5E8CFB89B6 -:10E070006A9EC5FD21FAF8965A8EB0027E35DFDB26 -:10E0800017D2D8BDEF4FC8FB08EB596ADFDAAF12E1 -:10E09000FF1260B27334FD3F06EB3F23C875631D6A -:10E0A000C81FF8434FD4D9085E591747F05375126B -:10E0B00095ABEA32A97CA6CE4EF56BEAF2097EAEAC -:10E0C000CE41B0BBAE98CA75754E7ABEBE6E02C167 -:10E0D0002FD4B9A8DC585749E5CB75B554FF6ADD94 -:10E0E0007C825FAF93A96CAA5B42CF37D73512BC55 -:10E0F000A56E15C16FD6B9A9DC5EB791CA3FD535FB -:10E1000051FD0EF0DF10DE59E721D853B797E077C5 -:10E11000EB5A087EAFEE10C17BEABC54EEAD3B4932 -:10E12000E59FEB7C54FF973A3FC167957D8879BDA9 -:10E1300005DD7D3C1536B263DCDFC3BC1598872155 -:10E14000DFF4ED4FE5C70DA6C369A57FD310709727 -:10E15000308EDC2D7D5D83665DD1D09BC72DEB0DB0 -:10E160003C7F4B7D37666B20BFDDC1F8392DEEB7A4 -:10E170004FC77F49F034A66E0FAE372A6A799EF2F8 -:10E180003CE4C74CE2C7BFDCD03A4D59176C4E7126 -:10E190003E81FCC8C2DC9F26E506EED11F4871FD1A -:10E1A0000E9F5FACBD7F0FB69E6EB3A7E347465B85 -:10E1B0003CB198FFCBB74FB4AF933AFE5E8D72FF80 -:10E1C000A1C3FA9DA7BAA3BD2AFE51A4B8FE7E53EF -:10E1D000F804DCE77F51C1C78BBD0DBAF2EE54E7FE -:10E1E0000BBD717F3FADF6850785C0FDFDB1B8C49D -:10E1F00007F92E6112E5C119CF1CEFA30B7E27385A -:10E200008208DFCD642A4F24BBFE88F3B9071620AD -:10E2100008BB065A12DB9B4FF078DE52C6F39632EB -:10E220000EB59C93EADC8EFD1D4B73E8C6F3A292FB -:10E230005F680CF33D87E3FAC73B178E0B29017C1F -:10E24000B7C653582DE5C928633C9EF228E6C58819 -:10E2500009E4C550D70F65FBF8EF1CD11FDACF7961 -:10E2600049B4BE0DCE9BB1B87037CF8301EB31BC42 -:10E27000FF5BF6C02F48FFE2EF41E1BDDD799D0E67 -:10E28000539E19EF0CE0D504CAABC1F3DEB8008190 -:10E2900009945783EA859BE0FFF1382E6BA691C65F -:10E2A000D789F29D3C1DBA9FF2D2604CC1D219F3BE -:10E2B0001E27D13CF73B2F70BF3BC647F75337A70C -:10E2C000B8BEEACDE3E44FF5C33811F2137EC7E6DA -:10E2D000A6F36BC04F660150343D06F8A91D7F437D -:10E2E000E59BD9CA3D1CF539F0E309C4F7B76F0DBA -:10E2F000C844BEA9D9592021BE1B0CFC3E9DFC6719 -:10E30000655F50F93D0431327B2DDD3B40671CE9F0 -:10E310005B104EF70E9A45367F533BFAD59AC3E908 -:10E32000BC3F8EE7936C08DA9F147238DD05A5DDDB -:10E33000E877F7511EB2D97B79BC9AE57AB39DEDA7 -:10E340009CCBAA99FF9BA75235F3A8D97E849FE75F -:10E3500062DE6CED392E49E957E53FD11CEE5A1BC0 -:10E36000A61D5FAB1C5872F2480E8EE3BDEE31164F -:10E3700029F26E817E1FEC5BCC2FE3FA838DCE03F6 -:10E38000AAE702A7312795D3C17222DF3BE51574B6 -:10E390007F7E266BA2E7B3F3A726225CC37C43E310 -:10E3A000707DB4A4FE7D0C078D6F5C312C1EE635AC -:10E3B000CE3DE57D2C4BD60BC76589E4280EBFEF1B -:10E3C000156A177583EFDDFB6AE1228C5B8F1139CB -:10E3D0001DD8879C0E65C0CF6254DBF981DCF4CC7C -:10E3E0008925B9A1F1AB7253B68039F0FC817A3F2F -:10E3F000A4558EF267FD3D01F770C09F447EADD9F4 -:10E400006989A2F529E699417DA5C8CF2223F72F76 -:10E41000654C6D4AFA93FB1B268792CF8B717F6404 -:10E4200096CCD763A74D5CDE4E7F15EE46FE9ED799 -:10E43000E9F544920F932A1F3F4EA2F33D0CFC8F47 -:10E440005BDBFA1FAD7966BA33F23758A22BAE6F99 -:10E450004AC09E9F36B8FB47F0BCFC0EC4D79E381E -:10E46000BE7E9E857968B0BEB353C278E9E9582B69 -:10E47000DD170ACE73C6989DE66752E607239B8098 -:10E48000FEB44589AB3504CDF7FB90449AAF54C830 -:10E490009A183A16469B3C15E5FE416E27E675FA3A -:10E4A000B50BBFEF0D61366110CD87E2B1B2813996 -:10E4B0001B787C96E637DF68B5E1B99CC55344AF5D -:10E4C000407602C689F1BC18AB9DE75555F36F073E -:10E4D0008FD7A11F9F3591E1FC1C22F3850CE2E34D -:10E4E000C5F1C9400FA20FC05334E3837EDD94FF12 -:10E4F0002754B2A11FB6F75F0FF2F8723DF71F6104 -:10E50000FC1B893EF130FE846B8FDF842C0AE39F75 -:10E5100093C3F55403EE208A68673B93FE2D09717F -:10E520003E807C98EA5AD67D0EC6350A2C768CDF62 -:10E53000B12B0DDD514F853189F26A8D71F0BC5AD6 -:10E54000D0DD42E48712CC5B67233FE0AC360F1B83 -:10E550000B8AAF015928BE3A0EE36BFC2ED17B1813 -:10E560009F1DAF9C6FCE625FAAF8A3F89A88E3A3C1 -:10E5700078B58BC66941CA421982711EA2839BE697 -:10E5800011CA3C4A3CBB85FC83150A1F0E3AC4F9EC -:10E59000705018D7773B8F30379EFB6AFEE1AEA2F2 -:10E5A00070842F18494F019E281FE0DB7FE571A979 -:10E5B0009DE78E27E03E4CFD0F7B12D04FDC697249 -:10E5C000893530EE9D0516DB027B20AEB1E3501895 -:10E5D0008FEB2871BE5B9479EE602D0D35509F1F37 -:10E5E0002F328C03E61DF484A23C0F54E2B2C1FA30 -:10E5F00070F025B3EE772D4C363D9CCF34701286EB -:10E60000C8827EFFF306D7B9AFE574F0BB9F2763DE -:10E61000AE6B3F147FCB87CE27E438DFCC21BB36EF -:10E620004E54F02E20BE400F34239D9FA936D3EFC9 -:10E630001A34579BE3BD9AF135CEF847029D73FE1D -:10E64000D73FC86EEDCA53F3E33485E073B31C4E75 -:10E6500071B767AE1828EEB6BAF26B5A9F34E6333C -:10E66000FA1DB1C62BE5E4075C2E66B889C4EA6FD3 -:10E67000FD3F95083F7E8B95BE173CFE6DE0CF7B3E -:10E6800080505BC19FC7D20DFEBC2703FDF4382A22 -:10E69000D7803F8FE533E0CF63FD2AF0E7117E0A94 -:10E6A000FC792C57823F8FCF9F007F1EE177C09F60 -:10E6B00047F86DF0E7117E0BFC792C1BAF7C5248BC -:10E6C000E39ACBE8DEFE82D088A5E8677493C3C9DD -:10E6D000DFF8C8D1B793576367F3BF34E8E8DCFFCE -:10E6E0006027DDEF9D24C95141BF47D32DE8F76A6C -:10E6F000F4BF6F9350A9FF7D9B7857DFA0DFC3194C -:10E7000018F47B3943827E4F47FFFB36B75E1AA76A -:10E71000AB1F7C56FFFB36038F95EBE0C7957C99CA -:10E720002A1DD3A5D742902F56578E8B64EDF8172C -:10E730006A89EB2B8F667FF5C987C409EDC59123E4 -:10E740006FE6F6FEDDAF2CFBD6033E77B14827C659 -:10E75000DD77390CA4979E59154671588B77E029BF -:10E76000E49F5D0E2621FF3C736548271C4F2190D6 -:10E77000119F275472BDD0ED6689F839A1D227E2E6 -:10E780007DD1DBAEF8ECC88F4F46F0DFD9827EDD5D -:10E790000BA0BF7747F7CFC238CE3361C0CF286F09 -:10E7A0001E5F682AC091570D0CF523D84ACAF32F73 -:10E7B000FF3E4C398F7A95EEC345A24E07BDB4ABF0 -:10E7C000927F3FDD7B2554EB0F3DFEE3B5F0C28821 -:10E7D000AF3AACBF6366328E378077508D50A6B3A8 -:10E7E0004AF618E2A38ACB4F63A581E4E932C81345 -:10E7F000E207664D74617838215EFB3DAB9E0E5595 -:10E80000C94B719ECFAC34D26ED930F1D57D37C3B0 -:10E810002BAB0F8AB4CD2ED97CA1EDF977EAB8578E -:10E820003BF8FCA2ECCC80762E0AF0E9A6FD6C7BCE -:10E83000BDF6F7AC7EAFC8E7EFF0FBF0DED30A3FE2 -:10E84000AC54E47398B866443A8E239FEB6BA0A750 -:10E8500080F7B12E4F63F43BA2BF2B4DEED45E9EEA -:10E86000EF95CA389E53E6B54691FB67B05FBCC7CB -:10E870002E9615623FAB9D8CF4F86AC7D7F518B792 -:10E88000BB5CCAFBEDF9885740FC76AFF509D87F31 -:10E890008FB91E2ADDCA38BB55B650BDDA9F6477E2 -:10E8A000737EAFFA9AED85F9E2215B91ECC559CA06 -:10E8B0008FBADA68646887519F217CD96AC43312A1 -:10E8C000ACDB8C630CEF33378619699F62F5ECD3B0 -:10E8D00004AFB0713842AECDC6F3176F29F38990FB -:10E8E0006582DD41F3499726476A7FCFF55A7AF072 -:10E8F0002D93CB7011C631E06F22FD7E4747EFA903 -:10E9000076F65AFAEA4FF88F78B20B0FDD8CEB6788 -:10E91000D94976415DB76D1DC5D76D2B42277D88DE -:10E92000EBFE52858F9E0E1DF33ED61F18C17F074A -:10E93000A779C4ED3DB47A72BB32EE6D0ADE0B8E60 -:10E9400039BE9A0BEF8F745A189EFB18293B7AFC3C -:10E9500002E15122E5351FC01A1BF05CC5C13C55D0 -:10E960002E9CA1287FEF8E9ACA0EE1778AB99DDF8F -:10E970005A3C9E9E4BCC39B237BCFF498B91FC1A56 -:10E9800078FE9372B94F19CF070A1EDF57E8B05BC4 -:10E99000A14333DA132877A13D217B6157EC05B7FA -:10E9A00027DBD09E64201DB83D69417B9281FB6FBF -:10E9B00013A8DD5FD09E40993BA288F6232F232326 -:10E9C000913D99CD16035C08E317DBA1D71DA9A2E1 -:10E9D0008E3EC5DD4375F4191E13AD83878625E889 -:10E9E000E021C6141DECB87253903DE81B640FF48F -:10E9F000F624FFCB21BAF6FD0FDEA1AB2F718CD729 -:10EA0000D58FCD9FA8AB1F6D9FAAAB9759635104BB -:10EA1000CC37EF4B467E685EA73522ADAB957D3493 -:10EA2000D5DF027A923F56F05791E456C5471E6BE8 -:10EA3000DDCF33D07E9ECC243CDF495B96C9BA7AC9 -:10EA4000F2A30E9A9C09780EB1BE04F80FCF231ED4 -:10EA5000AC18C5683F1EF818E42ACF79E24BCA3BD0 -:10EA60002A96F5237FE99251B7AF5610B43F36206E -:10EA70005BBF7F96778DFD33EFCDCAFE431BBFACE6 -:10EA8000FDDF450AF6CB40AE441CF7D3A1937623B5 -:10EA9000DF7CF819B757CD9F3DD51D9F7F824DA1D3 -:10EAA0009F7DBD9FEE8E7CBFAF553E5CA15ABF6B74 -:10EAB0006B26FF1D9A370F266FC7F546AE4920FD1E -:10EAC0009F9BF5249D47BC7CD040BFD3995E5C13CF -:10EAD0008A78D97A685D98FE1E95464F909FAED190 -:10EAE0001322FAF751FA7A6342004EE6C4C1F6FFE8 -:10EAF0001710600A2E008000000000001F8B080025 -:10EB000000000000000BED7D0B7C14D5BDF0D99DFD -:10EB10007D259BC08604DD400293F030228F0D7965 -:10EB20006D42122621D0A03C36801004E384A0D090 -:10EB3000566DEA137B6933493089014B546AC1FA37 -:10EB400058B1DAC7E7FD9A5A0950B15D9E55A1B296 -:10EB500048B051515779685BDA0F155AEFFDF17DD6 -:10EB60007EFFFFFF9C4976864D88BD7DD97B939FB4 -:10EB70004ECECC9933E7FCDFAF73608CB1CF24F875 -:10EB80001F9BC0422E463FBC3DD5D42E62A1ACE8AF -:10EB900076B9A97DB5A9FF0253FB3A53FF1586E765 -:10EBA000AF642D1CAA26C0DFF833FDE2EBB606C623 -:10EBB0004257F4F5CBB30524DFC48BFBE5775BFB51 -:10EBC000C685FF768F5B653D9FC25857B714746644 -:10EBD000C075EC2AA6E5C238DDD620B3D0D5CAE090 -:10EBE000F92B3DBCED64C10D53E1F9B66E9BAF5DF1 -:10EBF00066EC45FCAE93B1F1811B860612192BB170 -:10EC000085637EB7F49CF1BBAFF42C18CA62F4D3D1 -:10EC1000AFBF10E3BED0E0A275ED6CF0505B7F2E6D -:10EC2000FDDF7347E7E3BCB3241FDC86F997273386 -:10EC300058F72F2FAC74E3B8305FC6463036A33395 -:10EC4000ADBA712C63320B2658A1FFB62C89B5C31F -:10EC50003A738FF1EFE7DA95644F0CB8326635C23C -:10EC6000FFA2F1E007E174C11AC4F1F68C5BF2D0A7 -:10EC70005418FF60B7C4703E0E75B53B3009DA3DDD -:10EC80007C5EFAB8D33FB5F6E119FE2B3E136F80D8 -:10EC90004BD1C96186E7B9572E1C8AEF3BE4F9C90D -:10ECA00008DF4BCD93B178131D0D33B54718FA8F9C -:10ECB00097016F93FAC7C37681876D8807B86E8F07 -:10ECC000F3550762E06DDB78E7EA60D43A1B7C40DD -:10ECD0002C7978B5D235F74AC91702F89CEFB6FA05 -:10ECE0001078059E7AA93E06DCFDC78D7492DF1D63 -:10ECF0006F800793960FC8076B8E37B6EE8BEAFFCF -:10ED00000D5F62CA6937FC51C00A68FD9778FFCF72 -:10ED10000D5AEB3E3BD031634A27AC93552E64AC81 -:10ED2000B0FFFE8C35D1FA7438B2CA64C65207837C -:10ED3000A70E7AEF227CF5F37EDF381A63C3019EBB -:10ED4000005E9C57EBE4C0C33E1C275225E1F71F31 -:10ED500070DF2A45607DDF75DFBA17E9F3D07B0EDF -:10ED600019F97AF77B5D6978FF60F6F634A4FB83C6 -:10ED7000F04E18DACC065883B643BBDE8DF4F54A64 -:10ED8000F76DC43F32AB3F3889CB015F3B74DB9EEC -:10ED9000C5E9B0BF79BD24E4CF01C1AFFB04BFEE2C -:10EDA00069F0523BD420D3F5170D59747F57838FE8 -:10EDB000DA3F6FF0537B478342EDAE864ABA1E6955 -:10EDC00008D0FDC30DD5D4FE75834AD76D59B7570A -:10EDD000A03C3A9F0600807535B9E7D962E173B669 -:10EDE0002C19E8E64B5EB781AE667A920DED19AE4E -:10EDF0009186FE656C8CE1F9F44F27189E979C9DD7 -:10EE00006A684FFBB0C8D0BF30526E6817F45C6DB3 -:10EE1000E8BFA062A1E179A07899717E5202C997FA -:10EE20009D6719C9E579B97586E73BF10F94C31F52 -:10EE3000B2A09681705938A03CD5E5F45E819FDD83 -:10EE4000023FBF14F8E942F8139F571AE09D7FBCB8 -:10EE5000F39A29C0AFBF6A584DCF1D5943CF49F02F -:10EE6000DDED67E365947BFB1BEAA9DFC1B71F24D7 -:10EE7000BAD929E671D0CECE4929D8B6C84D968BDD -:10EE8000E793D763E4F3F1953790BCDCD9DDE44632 -:10EE90003ADB115930287DA7F7FBD5B90533902E01 -:10EEA000FCDDA0A3322EADF7747D75A9F1F57EA827 -:10EEB0004F63E909F3B857475489C13AB6F7D43FCD -:10EEC0009488EDD0972519DAF93DEA0CC4D7AE2C19 -:10EED0008B47B250BF190ACEFBE46DD7E0FD1DC7CA -:10EEE0006D569CF72190FFB88E9DA06F9DA87FCF97 -:10EEF0006D754F06F8BFD8F3E03593A19F76C6E64F -:10EF00001BC72E9EC7A86C89E4C2B6894EAB650AA2 -:10EF10005C8FDB5808E5974D25787645B6D215F518 -:10EF20001FBF5F4FF8BA32DB43EF6D3FF95C32B67B -:10EF3000ADAC9EE4C08BC7AD95C118EBBD12BF034D -:10EF4000B223EF4283DB03FD0F1C5FE146B9B2A39E -:10EF5000878F9FB75673239C0E46B626E0FD9D59BA -:10EF60003FA371774FE276C5CEE356A2E79D13AF7C -:10EF7000D8E0CBA575FA1076703F01DBDB7A6CD454 -:10EF80009699CAC2292877A460BB05D7B382BD066B -:10EF9000CFCFFBA420F27D1ED31CC0A26CDBFF6B85 -:10EFA000599CCDC1CF6C9731760B7F994D3B6BD47B -:10EFB000B3453D463DE2885C383A1FC6EB3AC3E5AF -:10EFC000DB8C4F8D7AF7E01B999B028897337C3E50 -:10EFD0003B8E2F58548572E77989DA8D93563DFA26 -:10EFE000757CBECDED73C2F7BE9CFB644B327F7D5A -:10EFF000C85C9847B19853DE19E33C0E5E59C73E92 -:10F00000C6759EB4D13AB61DE7F6D5F92CBEAE9DB5 -:10F01000BE3AF66DE42F617FCD78FBFBD74C4A41B9 -:10F02000BAB0925DF182EF67C939289F3C9281EEB8 -:10F03000004E4437E7BB198D031245BA15C629F0B7 -:10F040003B3DED1EE4C70EA29F836FDB7C4DF8585D -:10F050003AB4F736E89F375262B8A22F074DF2F262 -:10F06000876E43FB16D9282F9DAC6A40BB61DA59E5 -:10F070008751BE7EEA308C57C0A29E133EA39E6786 -:10F08000FC0576895D5D8676090B2F1A94BE66AC09 -:10F090009EE4C50EC67CED404085574A0AC1EFB8D4 -:10F0A0008BE057F0DDAA698CF4B43A0DF981883110 -:10F0B0004A2F5FD24EF1682C255F7C0AE980D94E39 -:10F0C00047A07F1B10C967A8BB851E378FDB9FBE7B -:10F0D0007FC03D84E47D718585F8E7BBEE5749BF6D -:10F0E000779DE2FA1D7F224077D7E21FA8EF4F39C4 -:10F0F000881E5E986D2139A2DB0B0B996247BE9981 -:10F10000E73F67BB1FE836E0AA99740B5C5F78A302 -:10F110006B24F2EF0B6817907CE8207E7668895AA2 -:10F12000328CB3ABC7497CB813F8CA85DFDDE52460 -:10F13000FA043E5D8F76C2AE30E7A3AEB3566EE7FB -:10F14000ED72139FECFE8383E6DDB5D6CDFD8B33E8 -:10F150000E05EDF09D6B13E9FDF17262C88676FC39 -:10F160001A3E7E8FC0EBEB02AF07859E7A19F594AD -:10F1700013F5904CD7FDC28ED88B768413F5995F2A -:10F18000E833AEC79E3FFBDC5B48FFE777C591BD28 -:10F19000399E6575E2BC762538689E66382F558D98 -:10F1A000F4BFA4DA682FCC9968A4FFABC78E34B43F -:10F1B0002BD3C618DE9F957295E17945428EE17991 -:10F1C000B96D9AA1AD5C30DA0BF3FDD718E9498926 -:10F1D000B21732F1FF467FF1DA687F11E5C8D90531 -:10F1E00064AFEDEC117AF964E65075E2C5FCB3F357 -:10F1F00024D79FDB8F7F9CA8C6B01F3E14FD7E27BF -:10F20000F07146E0E3B7A39493D94097E74F7EECC3 -:10F2100000A5D12F1DEBEFEBEF7D183C31245AAF49 -:10F22000A74B32D1B7DEFE43D75BE3F1F960F902B9 -:10F23000F4585B04F07CB794D8D10EAFB4DAEA9FEF -:10F24000C0B6A6D9D8D3B9048E2C1B3D9FE0437B12 -:10F25000A539B1FE07F87C5BA3D3B33505F9E85BAC -:10F260003FC1F61A6005275CFF1C372AC880D51CF1 -:10F2700053B9DFF28C3D30D2877AD31258760BF433 -:10F28000D7B6387C4FCB17CF2761AA4567F61DA8A4 -:10F290008724C1F7FF695113A6C27DE5590BF163BD -:10F2A0001C38A2380F270B8490FED96A6519F20723 -:10F2B000B302FFC0F51B39EA30ECCF14267B601C8B -:10F2C0001215F03D4BF8C07F58605E7656AFE138BE -:10F2D000CED52061809F1FC85653A9BF6D018DFFF9 -:10F2E000FC5CC6DA492106A89D7B17F3B427C1FC54 -:10F2F000986AFD18DACBC0CFC7EF5BDD37931E7A73 -:10F30000EBB7D6A014C35EEA85F3CDF633119DCEDC -:10F3100032FBEEEF1078ED1274B12323B02C965F20 -:10F320003815E182F6C5BBF324A4AF5CD71005ED18 -:10F330000A58A05405F27DC7FB57BB6B63BC37333B -:10F34000B776EAD428BAC80D774AB509080A4DC27B -:10F35000756D83BF715D3FEFB68610BFE7131C2448 -:10F36000B7FB5B4761C4A8870B7A8C7E3763CB3DC4 -:10F37000A7AF427877583EBB2A9ABE94F5D1F4F5F0 -:10F38000FCC5F44570BEFB6816C1B5D9C2E94B0394 -:10F39000FAC2E75A793DD197666581E65CA2377A71 -:10F3A0007F8DCDE57182845C353593E8A62B71CED7 -:10F3B0005B2199BE376601F97135C28FAB2139FFE8 -:10F3C000F23190F331ECE8DDC7168F8C00FCB68D7E -:10F3D0005B3212F9BC0B15C0089C7EFE52B42F7B29 -:10F3E000DB802EB20367320C55C1F3DCA50AF69F11 -:10F3F000ADB7F378FF32DEFFA6A99BB668F8FC7ABA -:10F40000F19C2DE4FDF5B656B0B40CFBDBADD47E1B -:10F410005BF47FC8A7AC42BC3D90ADACC66B361A5E -:10F420002B703D3D45F90AD2E9AAA98CD67BD714A9 -:10F43000E5E6E8F6CF262BB746B7B7F5FAA71DC223 -:10F440003FBD85ECD2977B16905E9259E01AD43B73 -:10F450002F87791C6ADBD881FD9F5F097B7EBFF017 -:10F460007FF6A23C223F88FB3FBF147AE545A157B7 -:10F470005E107A65A7D02BDB857FAAFB47AFA27F02 -:10F480000AD743C23F7D05FD25E8973BEE04D91519 -:10F49000E73F65C4BC4DEE5F48B1E46A659AD17E32 -:10F4A0009B9562B4B72A128CFAA6DC66D437CA855B -:10F4B0004C43BBF4DC0443BBF88CD13F2D3A596478 -:10F4C00068FB8F971BDAF9DD579BF4CF42C3F355E6 -:10F4D0005365C2E35C9FD14FBD26ABCED0AF0F6F5B -:10F4E00001613F3C968076DCB6B175026FDC5ED080 -:10F4F000F1D6F54F83B7BDE49F9D3FCB445CE171EE -:10F500002996FFF9AF8FB74BF05B02B7F32EC56FAB -:10F5100007847ED827F4C31EA1FF43C28EFB8588D3 -:10F5200007ED42BC511C88C7837620DEA2E211CFD2 -:10F5300023DE9CFDE3AD79EC439CDF4EEA78BB35DE -:10F5400026DEBEE435DA77333D46FB6E86CB88B7E0 -:10F5500032668C074DFFD488B792B3C678D0B40F0B -:10F560008D782B8C18E341053D46FB2E2F6C8C07C4 -:10F5700099F10676404ACE20F0067E924274EB1353 -:10F580007A3FB890F451CB5CAE1F810FC9FE7EE686 -:10F590004EB003B2FBE0F1BCC97F7ABE1FFD3D3E19 -:10F5A00087DB355D6FD5105CF3507FC7E8972DFA88 -:10F5B00065E778E8EAB4312D7E2A4D73DF08988F2D -:10F5C0006D2CB77B6C891B18D98B406ED6FC3E3BEB -:10F5D000494A08301C1FECA5EC9CBCBE716D9E7A9C -:10F5E00086F253723EB81CD7C524AB8FF4AEC93E29 -:10F5F00062AB3DCA6D78FFB621BE7680C54D3949F4 -:10F60000340F2FEBB4A39DF18D1CA508C795667030 -:10F61000786C4B071F1EE0B12D8EB73580D7D3D045 -:10F6200096862E27F87501BCA46C1C3F85DD05F37A -:10F630005A98E3E07058CA843E7DDAA80FD1608002 -:10F64000F633F1BC7D6DCE334BB5B43EFD5BF3B309 -:10F65000AE2D1A8C333E61441D9B0CE36ED686A101 -:10F660009D3911E687F2D1EADE951E4B4FF467878C -:10F6700069939545481F7709FD3A1E20629BDAFF82 -:10F68000FBCFC407BE8AF8CD457844C5BDE6E67019 -:10F69000FB6C218E9347F6A5126D5FB2F0426AB7FC -:10F6A0006473FA7A6AC302A2B70480979484F3E77A -:10F6B000F05B7607A7AFCFBB0E7DFE03D04920DA03 -:10F6C0009E8EA293BB62D1099BE3F392BFDE9F3D66 -:10F6D000A7F1F9360BFB51B7939D69BADD1C147085 -:10F6E00060A1A26174653301AEC33C8CE234351E67 -:10F6F0006B3008208B4B9A6A21B95361619E0C1CB8 -:10F700005D611C8F73E468F9638E0FFA8FC79BE409 -:10F71000BB31EE547C6684A15D7A2ED3E4274E3053 -:10F72000F99139263F739A493FCD30F4AF4CBBC6AF -:10F73000E4C72E34F9B946796363364DE0CB4A719C -:10F740000BCD22DBF2F13E23FC443D27BFB317CEA5 -:10F750008F2AD5C4AFC2AF31F3EB37726482B3C521 -:10F76000C3FD1A9D1FF4F775F839BC1AE17563BE25 -:10F77000AE9F7CA4775CA12F338CABBA7C3C4FA3AB -:10F78000F7DFDAE07AAB621C63DF6F606F5500F27F -:10F79000820D1EBA3EDEE0A5EBA30D325D1F69C8E7 -:10F7A000A27E9B1B7CD47EB8C14FD74D0D0ADD7F56 -:10F7B000B0A192DA1D0D016A6F68A8A66B7B834A1F -:10F7C000F7C7DA540DE32063DB984F83A58CEB80F9 -:10F7D000EF45C16D4C1BCC230AEE199AC7D01EBD54 -:10F7E000C66BE89F5E2F1B9E8F5C9D65789EAAFA74 -:10F7F0000CEDCBABFD86FEC3038AA19D5C5969E885 -:10F800009FA4040CED445FB5A1BF3B4B353CDF53D7 -:10F810005A343432001F773484C20887F686305D4C -:10F820003734BC44D796869E30C2E90CCA5FC0A369 -:10F83000C7D649F2C333D1C3304FE17201BE008F46 -:10F8400049368F25296AFC2405C6CB8A9E1F8C6702 -:10F85000F0CF82442FEEACB0E1BED3DB63786FA66D -:10F8600094508EF98923C512C5BD8E142727A2FD99 -:10F87000B2DEEE999B0BF3387C4CF26DC5F5E20BD2 -:10F8800031E4E529616FBA27BB482ECCDF64D92A61 -:10F89000115DF3F76FEA1E13337E74F89BAC1AD731 -:10F8A000E5DEB35346BA985F5C9B1C17E5AFCD0FFE -:10F8B000FD47452A8D979D1F07F4327F73ADA36ED8 -:10F8C00062DFBAF47E376D32DA977D741F74E13AE5 -:10F8D000C66BDF74A17C6B4FDB4AEDF6AC81F32481 -:10F8E000BF13EBF950D8CFA7851D7652D861EF0B27 -:10F8F0003B2C22ECB07784FD7C5CD8CF6F0A3BAC0C -:10F9000047D861AF0B3BAC5BD861AF093BAC3DEB7B -:10F91000B959240F9FB53029869FAA5FBFFA43A328 -:10F920001DF6E5A0D10E5BB5D96887DDD861B4C3FB -:10F93000EADA8C79B95AED2AC3F31BD618E36CD7EF -:10F94000D71BE5E1B2D5330CEDA5AA31CEB6A4DACA -:10F950006887E9F8B93660948B0B2B8D76587FEB6E -:10F960007D21349BF23F88C413517AAF378F8B7A55 -:10F9700005E825F702E8158A83079A317FB203BBB1 -:10F9800080FE2DB1868F4E41F9F9BAC430EEB4E74E -:10F990007CFE9CF9F2C5DFC9D78C74B3FCB831BECC -:10F9A00071DD1D46B856DD6CF44B1C9546B82A69CE -:10F9B00046BF64A159CF048C700529CD902ECDFA95 -:10F9C000C6EABE5946F9FD79F58E83815EE16D8305 -:10F9D000DE71E09D4CC373D23B6DB93C5E970FF373 -:10F9E0004063A131AEE010E693F6BC61A3FA109833 -:10F9F000E06B6341FF94E2DF00BF17EDAA560FF4FE -:10FA0000FACB42A7A7094C56269DD9FB35E8EF1043 -:10FA1000F910F6A9ED248EAFC22FE22B9F413B4A8D -:10FA2000CFE585F9F3A8F91A9E7F0F7136E07C9433 -:10FA3000D7C6E6FF3DE7939882F6109BC2A6509D7D -:10FA40004164D8A0E2ABE6FBB9216E07E5A6713BA5 -:10FA5000C89FBE40127927E6C1B695B9289E398A5B -:10FA6000059FC63867FC21F73C6836E390A9E85744 -:10FA700019F97FD19C81F3F25FF21AF97FB63CC687 -:10FA8000E40F19F97FAECFC8FF4E66B25F224C4635 -:10FA90007B927060353C2738BD26E8A8F1BD96659D -:10FAA00094874DE771379D7EA6097C31D6B9B7168C -:10FAB000F3CDE057A2BFE1645AF214AC2B0AD72B66 -:10FAC0007ADE8DF026ADF5915D7A86E3C70FBF88AB -:10FAD0003F3F8BC217E2EFB8117F4ED3F3D3829E24 -:10FAE0002E9E17A7A37FDCBC4C749530EC12F9B79F -:10FAF000D874551656A44498DF7E8F85F2A9FBC3AF -:10FB0000F5E132687FE2E5F542AD690B6C345FA642 -:10FB10000C9909789825D6EB1779ADAE064676C7CD -:10FB2000F30D2EBA32562FA13C6AF1DE968CFAB153 -:10FB30006B943A12EBD2BA8627ADC3FCFC367B52EB -:10FB40005AAC7A96DDF602D2A75DBB536D32BC5F2C -:10FB500066F3D8F0BDB2B41512FA7B5FEA616417A0 -:10FB600094A5F1BA8CE71B4247F8F754AABF8175F8 -:10FB7000CC40FBB4C2533B233105E3B3608BC9686F -:10FB8000E72691FFBA6FB893F0E6F4ACAAC0FCF197 -:10FB9000ABA912B3F8013F3EE60BA11E484BF0059E -:10FBA0007138AFFD7D84F36AF8FD2CB34F2F009FB1 -:10FBB000BF1F8D8F0216D5A6BC82B13D224FD43F08 -:10FBC00009FCC84CA53A8B961E9E1F6291D8799667 -:10FBD0007785DDA0C7F78F0BBBE14D11773B22EC9A -:10FBE000861661378484DD7054D80DFB84DD704047 -:10FBF000D80D2F09BBE11561371C127643AFBFC08A -:10FC0000EAC99EAE65AE08C6D95F05FF1CE58877D8 -:10FC1000A5255809EB98A17604CAA1ED5C6727F9E0 -:10FC2000393A4D6BC4F8B8B35A9B89EBF02E3FBB01 -:10FC30001AFBA7A6396405FA3796B6A746789E61DF -:10FC4000C85CE08F95825E96AAB30E207FE870674D -:10FC5000D2A379946FEAE0F076C12FC23B55857646 -:10FC6000941CA935C17529B6A3E48603E910E058B0 -:10FC70009927F82187E570786B7108EFB85A016F02 -:10FC80006F4A4CFED82CE0ADC36377E957AC1A74C9 -:10FC90003D9AC6EB258E167FC5FA2AACAF5B91283C -:10FCA0006FDA9DC6C75B20E8DF3C9E9E47DD583E6D -:10FCB000709CEEB0E8D7DB6E63B27368D438E5FFB2 -:10FCC0006697E1FD25A17BD2911F360ED1F3C33E8D -:10FCD000B2AB674AC5BFCE80798645DDA32E271714 -:10FCE00033011BD3F78E8A75F6379FA3E5D7D86506 -:10FCF000187751E81E86DF73DAEABDD1F5A4DD621C -:10FD00007EAD55B733E4C7F028C03BFAEF01A78CAE -:10FD1000F6F6E834DFBD88776F9A6ABF13EECF033B -:10FD200039287B705A1DBB53B01FBCF30843FA98A7 -:10FD3000D089FC7634DD45F2A6BFF95CA43F828C05 -:10FD4000EC90FEF407D031D941CE391F1C477F76A5 -:10FD500021ABF785E0BD70AE6F38F22FABB6935E86 -:10FD6000CE82DFE87C9A7E5D68D2DB6EBF7D40F993 -:10FD70003BFA42431BF2CD51C137AD3696887539F7 -:10FD8000E139B7BB103EF3D333F7207E58992B32BD -:10FD90000EE0D05A7CE7F508AFD639AB3C16A4ABE1 -:10FDA0009231F43C5CE63A8D9538BF29BB3B5D8EC1 -:10FDB0008277EB7DAC544578A7DFE5BD09D69599F0 -:10FDC000F6A7067532F4B3737FA7A7FCF76919513C -:10FDD000FD27E595FD200FF9B97238F1C378879AB0 -:10FDE00019AB1E58A7F3C6D278E2F3F76B799D02E0 -:10FDF000DCBF770DCC47C5BA155F1FFFDE28E829A9 -:10FE00006EDC39E273F53EA78C7E069396B7AC8123 -:10FE10007635DA4968376DE27CABF3717ABD515EB5 -:10FE2000AA26BEAD36F1B5CEC7BB75B9D9C7C7894D -:10FE300088D7B85ACE4FFDF1F1D24FC1BEA142A032 -:10FE4000A0C1AF7B63E59878AEBFA2ECDA2924931A -:10FE500064473E568132B26BE3C57320C9DD389FDB -:10FE6000F03D3973115F5A23D8FF38B735F63E7A23 -:10FE7000CBC475B2217E587FFC5A291BF329ACDE16 -:10FE8000DE6717671ABE4775028BA3DB48AF9AF28D -:10FE90001BB41F308C891FFDF37B47F637C3F7DA9D -:10FEA0004724B34684E71D9CFE5CF010C703353D34 -:10FEB000C48FCFBF352E1B53F72C9A5E61FC88C6CA -:10FEC0009FBFB36678369999A25D73CF98A9D8AED3 -:10FED0000AD84F46CB55566123FC5FBBD6B215E31B -:10FEE0007EE3A58FCEEE85FEF157397CCD30FEB591 -:10FEF0000FACB0235C1669EAFE3AB8BF08E822E806 -:10FF0000A37518F8E4A8CD63C7718E56585807B486 -:10FF1000E31719BF53B3D6C847663BE458A23ACAA1 -:10FF20000AEF7F6071B2AD70DDBD65D5E338DEA943 -:10FF3000079C544FC870AC7CD4034CC42595C7EFC4 -:10FF400081E72B363B19C603960A3B3F313F83C6F8 -:10FF5000B5BA97D3FBB5ED89E40F9FDE72F964C49F -:10FF60007FDBB0FA5B03C037A792D41AC4EB8AD602 -:10FF7000ABAC1A3C6F8BEF9889FD3FB032CFD66C9B -:10FF800068CB0FDA713E3D6017609C559F676D5BD3 -:10FF9000147EE1BFEA7C1E779F67656A670C7BA6CB -:10FFA00023DFA2C7573567D4FC1FCA97E9FEBCCC34 -:10FFB000612D0FE17700FB1E9F800BAE7B268F87A4 -:10FFC000B6A5F96A8643FBA485799A52F0AABC8348 -:10FFD000FCA9DDEF644F13FA19F5778C1CF1647BF3 -:10FFE00094DF3F497CF744127FFEBE373E88EB7CAE -:10FFF0005FE66DCD9B10247AB6A9598B13F97A2C44 -:020000022000DC -:1000000097E1AE073EBF6389B22393F0C1E4E76096 -:100010005E2B367D97F0BB0DE083FCD9E3915B76D8 -:10002000C33C4E83F2D6F0B9F7919908CFDBA70213 -:10003000A1A65E0CA77BF287F13CF4E6E644D2F77A -:100040001EA63A2EEB83476DC7F6BB2D9349CF6BA7 -:100050005C7E70FEB3B028F90EF89D57F81DFB0AC0 -:100060005C6F1CEB40BC58F7AD73E13C97D6DA29C6 -:100070002E94C00295284F6B3759A80D3F1B505F37 -:10008000AC10FCD5260F3B5087F0403B9CFCBC4796 -:10009000F7635D40AD905FD52B8D747AA3D766A0D2 -:1000A000E3AA3546BA86751ADA9BF379FEA5C77FAF -:1000B0002A05F5731B2C1BE1F2418B25B895E46BE7 -:1000C0006054745D9D9C6FD5EB56647B14FC5700A7 -:1000D000FDAD40BDE1621DE5A9B8EE71B390DE1D36 -:1000E000C7E2699E66F8FEB3C3E144BA5C331CE61E -:1000F0007302E818EB7EDEDFD24CF60BFE4806BE3C -:10010000F6B4207DDF04B37CC443F4E9C0FC914E17 -:100110002F3A7C6A37671CC07EDEFF932883D3C4E6 -:100120006ABD45AB30AFD34B4726F8E09A6DFA77FE -:10013000C6F4D1193D8F4167E5D097E345237EA9E9 -:10014000ADE8CDE78D1AA86E99F05D049FEB9ABCDF -:100150004C2B16EF03DD6F2C7D85E8E0130F0B4A67 -:10016000DC9F7D1DE57EA2989BC69410CAD721A274 -:100170005E14F512FAC9C962BD496B2C6F56E430A2 -:10018000366C8DF46605DC4CAA0887504F38BD42AA -:10019000EFEE2AF8C9F8CBFAF4D890F839BE10ADD2 -:1001A000C6934AFB12EC9E54B47F1EB058AA315E2F -:1001B0003F8419EDAA64133C58AEED64B43D1E2F84 -:1001C000E4FDAA99632CE4E7541AFD529BC92EFA68 -:1001D00011D2F5F0BEF5CBF827C0B105FC3694532B -:1001E000C3421D1D489F3560B70669FD3ECAE7380A -:1001F000407F3C62E98B5BFDA3E21617C5BF44DC80 -:10020000A2BFF8971E0758C86FB18D0ED58BF9BEE7 -:1002100085DE9BE6A01DDA58FA152FF94BDED36474 -:10022000973A845D1A376EA587E7CD38FFE87100ED -:10023000335D99E34966FE33DBA5BFCD17F6D304E2 -:1002400036E1F3C405F4F87D6B16F77B5AB35634E8 -:1002500061DDDA79E1F778342BE171F1220BE151BC -:10026000B7D716FBCF2E42FE7B55F81797F27BDAF5 -:100270004D7E48BCFF494589A13FED055C3EBA8BE8 -:10028000F9F3C52E667345E50D1C055CFF2E063D92 -:10029000E88225CE633CBF319F19F35249621CFDB1 -:1002A0000A3FE1A9F9863AC1A4027E9FF2A04E91CD -:1002B0000775893AC1B2EC737B3FC3FB0AAFFF7588 -:1002C0002AB58FDD8976DFA2449F95E8577DFA3BFA -:1002D000E81F2F7293BC4DC992A9DEB53ACDE52334 -:1002E000DAD794D7D12F5BC488B701D40AC9DB25EC -:1002F0005817E119C0DF710D1C2F4BD0FD9D624EC8 -:1003000057BD71A50097DF56F8457ABAB6DA482F7F -:100310004BD481E927BB40F8D162DFD6F8C885DD30 -:100320009F115D70FEDD388AE7A1CFCF813E98B77F -:10033000EDC71ED7FDDB043BF8450968BFEE257A03 -:100340000F67317B34BE03C592A1AE215CC8E23D8C -:1003500043713641C257D8CED21F80FE87CB3E6054 -:1003600077C0A712BE33CC82F57BFD7DD74CD7F783 -:100370008DBB89E2FCDF9E0D2082F9DE878965AAAC -:1003800023F8E9329CC7B7B14D75753F5A8675752C -:10039000DF8ED3DBCF7F4F89AA2BF87AC1AEEFA1D6 -:1003A0005C575DA05F613CB7CCA88E8AB14E92C706 -:1003B00012C6FD501E4F8C8227F90946F89AED7639 -:1003C00009F13719E9D1C8E7E6EFAE32E1A5BF750B -:1003D0009BDF839FEA09467AFF5AC10075B1E6F7B1 -:1003E00013B04E22F1F3D71780E0A43CB4C4AC3E66 -:1003F000F48F5939A3EF593C9C8E50A2A0DEB3D79D -:100400000FF111DCA01D877A20E8D6E3A734E93884 -:10041000A40309F38621D2DF309588650CF6D7EB6B -:100420000C54F6997BF0720EE42F8D2357F23CF2B8 -:100430001B0A8BE0F7C63FB239908FFEF931D0AB83 -:1004400032EAEDAF682E689F5BCB280FE0F6A8D4A8 -:10045000864F459A61BE5E95B76B0046A8879D5E44 -:10046000639DEBEED247CA1CF0BCA582C7550F377F -:1004700084DE588779DAE222928FEBB063D47CC3B2 -:100480007BE21C187751B5AFBBD04E7E77ADE4C090 -:100490006BB8A956C345BF91AA755A648C33A80C92 -:1004A000FD7AC7DAE69948BF6FD835DF30B8BE8726 -:1004B000715818BFAD49BB05FD1C459E539901728B -:1004C000616B9B8DF613BD57FEFB34398AEF7E5B63 -:1004D000C0FD845777C77D1BE1D06A7145E2F06AA1 -:1004E00057B7DE9782DF73F81A618A6F343E948EB5 -:1004F000DF69BDB1D5B7079F373A7187296BDDE258 -:10050000AAC6715BD36FF2DE1435AE6BA4A31EEFE7 -:100510008747B450FE59ADF439E292705D1F257AD9 -:10052000E1FDB6B539C9488B2DA98E5175D8EFA616 -:100530003FFFBA00F12E5BF391F51CDE0E3BAE7B64 -:10054000B457D5300F7E214FDD87F4BA74CD7B339D -:10055000A93EAE22E95EBC8EBEF0B53684FF1B22FA -:10056000FE12495D4179D99695752E9CEFFCD4CC4D -:10057000A6E8F84B4BF18DAEF1F05EA6D75ABB6AF8 -:10058000C8C5F4D182F19629382F58CF24ECF7A7AB -:100590000615FA45D21DD5B1F663BD2BE0E76A5EBC -:1005A00095897190962D2E4CC3B0168BBA19E39C89 -:1005B0005A4642CC7AF5097EFE5E8DEA99E99009A9 -:1005C0003FC46FBFDDFEFAF7B4B1684772FCB96C87 -:1005D000CC658FD27793F2CA4E1644F9CD177D378A -:1005E000B585E47F8B85F3EF04FF1FBF87754FCF81 -:1005F000E605CE20FC5ADBD4CD082FA6B9D890D280 -:10060000FEF924721F1BC540FEB6343AAB63D59B7E -:1006100045564AF3904F8083DE1B322A4ADE37D597 -:1006200065623C24D2780571776FFF2DAE77100F8D -:10063000912D5949A8FF22E92B3233916E055D9A1D -:10064000C7FFF7026E3FFE242760F5A35E9EC8F346 -:100650009BB30B02366AB30E2FDAB55F00BA1DE901 -:100660001FFE0FA55BD273EF6EFF1DD115F30C2E8D -:10067000EF1810F2B6B1F43F29BEBBBE90E74DF4BF -:1006800078A06EE7C68DFB7E08FDF140A19ED72ABB -:10069000BEF7768C1FE979D3393C1EE881DF58F12B -:1006A000C080291E18DF4F5C7F865FE83D61CFA6C2 -:1006B000C91D817294BB87241FFA0F98AEC079566A -:1006C000052CC110E51FE25D34EF1211D714FED6E0 -:1006D0005231EF371B5C0CF3461B1DCA7E9C7FBB5F -:1006E000C8FB5EB7FA817BD1EFC6B835CE7F1EE37B -:1006F000761C2B8EF351BC05892095F5FA670BF01B -:100700001EFAADD29CBC68BD083320BB653E33DA0F -:10071000730B98C9CF5AC9ED30DDCF5A66B213CCEE -:1007200076FE22D3F3BE7C0078174037E7FC391BF6 -:10073000B1B4ABC6BFEFDE480CB9734CE4E98E36FA -:10074000286FA21EBA77D1CF5C48A7EB6D9D2ED43F -:1007500027EBE7DC9E88F4B77EB9447C79A4A192AC -:10076000FA1D6E08D0F55BFEA4DE785648CF33C084 -:100770003C5EC953EE423AD7EDB14573CADE5C1711 -:1007800085E70515B30DED4071D59BEBA2E3903ADB -:10079000DD49AC3E561CED593FB7DB6D4097545FC9 -:1007A000283DEB1BA8EE06E8E85C349CD6FB8DE701 -:1007B00010BCEA9F3174203B465FAF0E271D0EFA36 -:1007C000F3FEE679A79FCBADBF749EC1CF394FF33F -:1007D000FCF479F7D73F2071BD70A7BF6C39EE17D5 -:1007E00079254FED4479BAA832693FC61A8EDA38B6 -:1007F0001F1D5512695FFBFE89566ABBB378BED5D3 -:100800008C5777652DC9B54BE137BED8C2E3CCE034 -:100810003F29F0E72CB1BFBE7D2223FE6C2CFDF1F9 -:100820004B987FFE4D999D0939336F6E94BFB4D1BB -:10083000D119BA338A4F81DFEE45BE75EB798780D7 -:10084000317F08FE8E217F6896336E53DEE1B00E55 -:10085000F77C80FB983EB8F7EFD7C4A60F407C1E0C -:10086000E2DD0CA75B4DF031E72702BBAA8CCF0776 -:10087000E9D76C6DCBDD8F79350DECCB7100A7D747 -:10088000F011BC17AFFC94D220AE42CE37E3236701 -:1008900036A09EEC069580FA66E382DB3763FB3C6C -:1008A000D80188DFFEF980FB6FCFE6291FFB63D4F8 -:1008B0000DE8D76EB417A6605E30B6BDD0BD72C667 -:1008C000DC98F6C282BACC3C9C5795D15EE8DE52E9 -:1008D000F9580EDE477B017EBA0BEB0CF602ABCC6F -:1008E000B9047CB8FC8D1B971BB33E6F7E9E3AB457 -:1008F000306A3DEEAC7A165DC7F8C77CC55308EF89 -:1009000057F59E43C2BF07F6D83E7B8CBA45FD7BA8 -:1009100053FC7C3FBF7E8EC860CF13D1EBA7D7DBE3 -:10092000956AB4FBF4B897DE6F4A218F73B4652AD9 -:10093000ABF1394B987A89711BF5384756F665A2A9 -:100940005E5866BDFED17F5A647A1EC3FF639897D6 -:100950008C4F3BBBCF035D4EFAD55C8443C9D9A015 -:1009600086F910E71C0BD94FCE344676CE60FDAD2C -:10097000C1F66B6BE2F2A775058F979765DBA81D33 -:10098000AF4A5B51FE4CBF30D4827223A04A4FE283 -:100990007CE3958F3E7C0AF535D801188709B07A3B -:1009A000DA5F9D600F507CA27D0E8C9C8D71982625 -:1009B0007B26C5D3337E9AE8C5AF05DB305EEEF407 -:1009C000F17D50D57EED5E3C2F637EC9380B83E709 -:1009D000F3025CEF2FC6F80D8EBBE8EC6E8CFF5C6B -:1009E000EBE7F20BFD38F4B396D4DD3DE961F92F66 -:1009F00089DB04DB9273299E2453FCC0141F7216FA -:100A0000CFA2F8905E271128E6E7F7B0B4043A7F4A -:100A1000C21CDF31C773CCF11E737CA7BE90EB7193 -:100A2000DDBEFA5AA1D1BEBA0BF71E0C47790B2ACC -:100A30000AF8BADDCED23B2646C75FAC0CE32F776F -:100A4000159AE28C83945B61902B2770217B5FB6B3 -:100A5000A3BFBB5CA9A5F89E99EE1F10F2ABB930FD -:100A6000C150D7116E5823DE8FD310CFCBC73A8237 -:100A700071197DE30C963FB6E42BF717723F6323A1 -:100A80005E994FA57D04B30B3C06BA65F5C3D989C1 -:100A9000E8BCAEE9BBFA7CF4F13FEF3C3608780FD6 -:100AA000964F369616B91CF0FD4F00C7BC3E1A0C87 -:100AB000ECA8F8B41E3FD7DFABC1BC410EDA9316E9 -:100AC000CA1FE8F7A3E2D836A4DBF8345509C4906E -:100AD00097E1C2DEB829E531F5EF308B4A72A14EBD -:100AE000E46BF4F16CCCDB487C80B4ADCF4B8A1165 -:100AF00037673E97134866C50689613C2881291DE2 -:100B0000187F76B4D9A9CDB4EA0363A3EA871CC5DC -:100B1000B30E609C4DE70B73DEC621A5CDC261EB21 -:100B20003A8CF92B737ECA6C57EBF1751B7C04E78A -:100B3000F507C4075F6F501ADC7A9FA4F57C41D794 -:100B4000ABD3D59C9CAF7AB1FEA4254EDD5C0BF3F4 -:100B5000D21E7351FCC28D73439884E017E5E463A1 -:100B6000FEA750FE5E28E4E7D1B458783DCABED453 -:100B70003FA544EF5BB850C8EDE1A70A651E27B159 -:100B8000B110EE93621353882FF4FA93C3A9DCBE1D -:100B90009C5F7263E87668FF2F51277955C9D37A35 -:100BA000BE7F48593EA3D20F6E0FF27AB4C357F6F8 -:100BB0009EA7B207FD4EBD5EF7AA4EA39F794D9644 -:100BC000DDD0BEC8CF34B5938ACC7564AA8BEAC891 -:100BD00052451D9998BF994F7ED8C0F31A3F16F51C -:100BE000FECF8AFDB2FF5BD4ED758AFDB2CF89FDE1 -:100BF000B23ADCD7DB558A4F9F9A0D365D765F5C43 -:100C00007063E937BCC8C7938B2C7A7E660FEAA95C -:100C1000BEFD15039F0BB6B0D29837BB3660CC9B98 -:100C20002DA936E6CDFE94A34C29C27CCBE4D54D4C -:100C3000783E41D52689CE27D8F8F0271F3E85F685 -:100C400062313F7FC7FC9D2362FF85BE7F43BF5F4C -:100C500056C4E9C3BD27D58E75F8559BAA66613C7D -:100C60009D79A60ECA7E9B8D317858B7BBC963C7E4 -:100C70007320AA424B1D38CE8D9B619C84C18F731B -:100C8000DFB8CB286EDD1BF7D7AEBC1EDF3FA2C797 -:100C9000FD59D6F565F0FC8888FB2FFBF984C7D099 -:100CA0003F7AAA50A94278FC5BA1B200AFCBC47CCA -:100CB000A0BD28BA0D3F2F2519CF9D585634407C32 -:100CC0005D9A6189E93FAE2CE27216F4516D118E86 -:100CD000EBEA8D7BD5E178CCD541FBEBEE2EE2F251 -:100CE000A9F94DB61AC769FE395BFD5C0CBBFBD692 -:100CF000228B3EDE57693CAFAEDF02B7F0F18DE3E9 -:100D000049CEAA5108E753585F1663BCBB8B1CFA47 -:100D10007877D2FB69BDF3BB3B7A7E7DFB663C896D -:100D2000C8B4EE1AD5DA03F4C31E96A82EDDDDE5AD -:100D3000995B88ED5963A88EE548C5C0E76BFEBD99 -:100D4000F6D11CA9F8D9BFE43E9AE78A3206B58FDE -:100D5000C6BD80A9B1F0FE7341977B8A73864606B3 -:100D6000C09363CDC130DA19BD6D9BCA30EFE7582F -:100D7000F32ADD5F1F17A889B5CF392CE8B4A56227 -:100D800065005344ADE9B30CE736FC3E57DD57141C -:100D9000E52F3BBCDC5FFA64ECB9BDA89A16545849 -:100DA0006C9614B2B77D16306D73D756495E993183 -:100DB0007FFD03332E87E78BD2C0BF8B5A77D1EAF2 -:100DC0009FEE057665C515479A53A0DFCE7C358C1E -:100DD000E3977AE57DD85E14C8A67AF7F5498CECDE -:100DE000BC53E31CE48F98E77D42CC1BE47293ED87 -:100DF00073C8E516939C6C4D1FDF84F31F5FCE22F2 -:100E0000286133BD67CB301F38294F3D817C96E97F -:100E1000658A7332DD5758543EC73CAE6B1AD7B75C -:100E2000E32369F7637CF9B0EEEF977E6E7FFF6C8A -:100E3000D100FEFE29911F68FD8E33665EE4D4CAA0 -:100E400085B1F3030FD7AD40BE3FF51DA3BF7F6A49 -:100E50004B750DEEEF3B25F203A766D60D981FD01C -:100E6000D70972C8310DE5506F7E40D8ED22CE3DD6 -:100E70003F4F89C3E7E0CFC74FCBA37DE86EBC32BD -:100E8000CD733DED4366B1F7C7B2473D0AFA39FA73 -:100E90007EF6297E3505C7D1F7C98E47D1368CF647 -:100EA00075DF1A8B9E478BF9FDE579D3DEBCA695DD -:100EB000F64F0F326E3FD87EB2BF93D7E3D8789DFE -:100EC000615C6AB917F355E727BA48BFB7E1FFA2DB -:100ED000F46A7A919A376D78F438A6F354E5C17DB7 -:100EE000375EF89BA8AF506F75335689F2E6DB4941 -:100EF000F514F79821E066BECE9A26F0CA3C290880 -:100F0000CFF4A2C04CC2E3F39D329DFB2AEEB3ACFA -:100F1000C1F99FCF38026FD3BEFA7249E675798C5A -:100F2000F8E28A2C0FE969DDFEAA9DC6E5A6934585 -:100F3000C63A609DCDCADE841CE8F7EEA3B66C7C91 -:100F4000ED0789CC8EF30E64819C8375947BD5D19B -:100F500003C9473C89C88AFB1E58C862F5D2359937 -:100F60005F350BDEBF881F1F3D371CEDF11F3CC6F0 -:100F7000F355573CB6D2B5226AFC87A709B999C682 -:100F8000E75FA358827206CEE72CE5A5AA64AB4FB3 -:100F90006198473E7F6C09C609C17E1B47ED4FA88B -:100FA0001D96AD3998E77ED7FBF131EC7FC5376FE1 -:100FB000BC8CE85FC0E386B539CF909D9FA7DE81EA -:100FC000F80F177F92386622D9F19B91FE6FB0B06F -:100FD000402C3B6683C0DBD54AFD754867572B4ED6 -:100FE00086FBD5C2654E82FB0F4A2C32DA95F3910F -:100FF000E6319EF3A88DE2CD008F9BF1F9219F9BF6 -:10100000CE892E577E6AC3F69F2659D8E503E8E3BA -:10101000CF0DD7E24F86233FBE8BF41763FEB56238 -:10102000FE3A3F01DCCB695E0AAF1FE98FAEFE5886 -:10103000A87C17E1D496A9AEA6F3103D0B06751E49 -:10104000E2FC1F06A976CFF9FDFA112C46FDD76107 -:10105000C127E6FB3F9CC6FD821BA7F17ACB2B1E66 -:101060003B776836F2F55ABB07F1FA5461E0C7D313 -:10107000A2FDAEBFB21C99292D27FC85E7C0DCF983 -:1010800041A089D89E37D646F8D3CAC5F91E773114 -:101090004F7312BD456DD75A0BF1993BA1A31A8D21 -:1010A000665B61FDB16BF1BD3289F6F347ED7319F3 -:1010B000B08E2C22F2592DB8EF0C6CF9F03A493F62 -:1010C0006F8B5940B6852B6CC2BEFFE031652CF0AA -:1010D000BDA8CF3CFEA2F571AC6B3966E5EDF08B97 -:1010E000D6514D400791517C1EED0F587C8D325EDC -:1010F0009FDC8C7906758DC55709ED9AD03D5E0C45 -:1011000071AD58E764E82ABC77EF15642F7EE2657D -:1011100074AEEC9254CE37756116B466F4F9B7EF3D -:10112000A4B3A09E3FC5FD737EA1671EC4FD6B30B6 -:10113000EF2F6DF8BA7637BC1700BF17E36AC37C90 -:101140003CBF191FB6F9820CFD5D5E1FD9D26861E4 -:101150000FE238D28666F4CF9D22FF11AFD492FF02 -:10116000380CE853C68879C466D8BFA63295E837EC -:10117000B91238231BAF46FF38F712FBD8965C3FF5 -:101180003C09F9E5DC34A35FDC5F7C5DBFE2393705 -:10119000889F2E916FDD01763BAEF7E760B7E37570 -:1011A00017D8ED781FCFA5C62BEE63C3EB1EB0DBBF -:1011B000F18AFBD8F08AFBD8F08AFBD8F03DDCC777 -:1011C0008657DCC746FB0E4BB4D050844F593CC306 -:1011D000FC508B9DD39996EEA03AF75009A37C7EE4 -:1011E00038DDB1B509E375168E272D893F0F27AA83 -:1011F0005FA176C64499D7C5B351B87F709D65A2EB -:101200008CF6539B43A63AFC534D36DA9F7062AE80 -:10121000E56DCCBB308BD527817DF3CBCF6E25F828 -:10122000D72ACC8AF2A109CF0B4579FC2113E71705 -:1012300084253C57AE3991097ABC2EA880CC7E1FFC -:10124000BF45F47A4045BF78BA536FEF55F179ED59 -:101250001A8BE8FFAB20D26FABDE5F3BF404FAAF32 -:10126000EB4CED6EABFEFE686A1FEBFDDEC81A05A7 -:10127000E93D537F9E7A03B62371FAFB7FBC01FBE5 -:10128000135CA8EEEDD413389F13E97A7FB986DAA0 -:10129000BD7573D7ABD8FFC470DE7FCB9E834F6222 -:1012A0009DC95F7BBC6655A338BEB688B1A7932E97 -:1012B000A6AF77A74BC678A86231C443F5F8BBD573 -:1012C000BDFC72DA7FD6E424B91849F7D5A0DEEE6A -:1012D0002F2E1A15AFA7B8E88FA6EBF5CCA6F827E6 -:1012E00070168E5B8DF1401F7D558DDE9FC62CF5EF -:1012F00021AC530F9C4994D18E74A445C5EF840C46 -:1013000018285ED85CCFE38361D54EE777E875FD9A -:101310008E6251D72FE2857A5D83A3F86143DEC0E8 -:101320001C2F64D2CD948F0EAC34C603E7AB9F2F35 -:101330005EB89C85EC9723FD2B16AA8B58EE91DFA7 -:10134000B90CED6836819FCB28BF14ECADEB9769E3 -:101350001819CF9BAA16EDF65BDE7B1BFB079BE201 -:1013600064DC84BFECE6B2772E23D32D81617C6BE5 -:1013700059093F9731EF43DF4B32CA53AFD5C7CD41 -:10138000B4C03751FE06562651DEE4FA3B2CF4DD9C -:101390005ACDCD104E60570A7AEF7A1CE94B725B3A -:1013A0000CEDDC513ABD5DFB38D2FFF464BD1DFF8E -:1013B00004F25B99437F3F8FDA4B558B789EF5841F -:1013C00002AAE458B94EDF2FD7E0F36BC7F48E477B -:1013D000F43DDDADB7AFB9019FB7F58E5747DFFBE1 -:1013E0000D9E6844ED194F203F9755097DA5BDF727 -:1013F000388EDFB25C1F7F7C10EB509759F5F759A0 -:1014000010C7AF63BD6D05F5E25B82FFBB8B3B6B25 -:10141000305E755DEFF34E5AEF72D17EBD587D029E -:10142000F9E95F7E7D7FE7EF99DBD7B3F0CCCB7333 -:10143000FBF8C22CAF7E55CAE5887FF54F91CCD919 -:10144000F2FA27E95C378C07F07C56EAA200D2B7A3 -:101450004BF20167B08037302B565DFCCA123ECE8E -:10146000E962635EACC594170B88FC547FE31C2AC9 -:10147000E5719DB6F2D87EECA4BCF28F8A319EC095 -:10148000CE4A389E470550823DDB98A3FE19EF03F4 -:10149000EB56903DC7980FEF835FACA19D390FC00D -:1014A0008979D8C6D247284E7FA2D06E380744CF5C -:1014B000736E7428241FDFC3BA0E908FCBCA959920 -:1014C00058CF78E308896DA57AB204CA37D8463A6E -:1014D0009E24B92EF29EFA391CF32EB12FC2BC2FD6 -:1014E000E58F62BD9F14B7DB513E6B4C9B59914B0E -:1014F000F23A8CF5C756F706CA033B4BED9447D03A -:10150000F3CF75E2DC6F3DEF3BFDC250AEDFB3F4CD -:10151000B8EEC0F9DFBA35BB03641F7448CC9A71CA -:10152000713EB836A0A5DF85F66F4522ED17A85E9F -:10153000F1328D7F6414A3F87BFCA27ADA1F640376 -:10154000FB50C17A17912FD6F7798FBEF035DA3775 -:10155000AAEAF5E7D29C2128279DADE067D1801C3F -:101560002E7ABEB8CA24EF6B8BF939730CECF87184 -:1015700049F89D81F73DDF3F9D9FEF77B283D7F319 -:10158000179418F3C7EBED3CCED79669A4ABEF4F99 -:10159000E7FEEA83D3453CB1F4C7D508974F98D509 -:1015A000877931F6283F0F0E632CB4DFCA7C0E73A7 -:1015B000D662B2EB1E1D0D4B045BDBB6E62D8A2B0B -:1015C0005A36F3F73E9CCCEAD16FB1D9781B2E1A6C -:1015D000E6FFA7F8D53925583FB6E61DEADFACF19E -:1015E000FAEFFEE237D525BABEE7F19B65DE033D93 -:1015F000B8AFECBF1CC731ED7B0DC8BCBE645DB19C -:10160000ACDB17741E2110AE1DEDC5F4A2C00A9C00 -:10161000379BD829E33C7479132AFD6A0DCA1BA6AF -:10162000C4CE4BEB7CDF62CA4B07BCFCFD43BFB8AA -:10163000AB06FF3D88FEF2109BCA7AF306B795E031 -:10164000BC52F4BC81723BB6FBF4282CC86FD0A30B -:1016500037ACFE6FA0477BED76ED580DCAD52FDA7B -:10166000FC81AEFE9DE8AA92C7CFBE68F32F9AA672 -:10167000ECC3F9FFADBF73D5B4C06BF89DFB2C4A2A -:1016800075024FEEF92CC63C5F4FC90079BE4BC5C1 -:101690001FFE27DE3070BCC15AFACF196FB0E39E2F -:1016A000AA3CE2A3CB4A918F8A391FFDABCB3D58B0 -:1016B0006F6E29F14367307ECC5FDFDF4F2F52CB57 -:1016C0004B490FAAD63D403FF795B9B83D13E2F01C -:1016D000ED8B67C0FCFD8678C613ABFF06F10C5896 -:1016E000EF02C26F85F8FE171F7F37137C156E4F10 -:1016F000FC0BD2671BADAF93AFEF1FF0FDCD442FB6 -:10170000CF727AE9830FB793A2E073C3EA7F0C7CB0 -:101710009E25F8ECE0F3FB02E0730FC1D3C7E77B33 -:1017200029FFFAAD629E0F81F75EA675E6723A78E0 -:101730005BD8D7E077CFB85CEEF3BBB7E42BBF2E16 -:10174000E579E4C3A586FA4F258CED01FCE2EED2E3 -:10175000D87EF19B38DF2F9A5FEC2EE170EBCBBB8C -:1017600004F979B7ACFAEA2BE13BEF00BC31DED6E5 -:10177000BE4622FBE27C1AA3F300747BE34412AF63 -:10178000DFBB787F584508E7ED2CE4E78CE8E703FA -:10179000D8A4E54343F2C5707D7588ECC07D482B25 -:1017A000144B0B9E133843FB88F69F391427FD3BDF -:1017B0005BA3BD3EFB1DE847839FFB25ACBF5CEDF3 -:1017C000A1FD27FA3E337DFFC78A50EA01DC77DBB3 -:1017D0000EF4900ADF995F61DC0F62B6376CA6B633 -:1017E000F9DF314D9E6E3C8F0AE04FF6CFF9365E41 -:1017F0001FD76E637BB0FE43DD2005C164624F6B73 -:10180000163A877325C0C90AED191D19544FEE48C1 -:10181000E3E79DE9FFCE29D041079DE7744C62784C -:101820009F897D65FAF9DE7173F9B97A11583F9E87 -:10183000DFA39F335125E8448767DCFDC90497F394 -:1018400000178671663FB747E7ADE1F9E096E537E7 -:1018500086918D6A8A3F5A17AB2E65B1D7784EBAFA -:10186000399E613E67DCC60243F1FC8AF9C5651A00 -:10187000DAAB4E51AF19CF143AD722A23DC5CFB53E -:10188000A8B01BCE11317F37DE44A74E53DCC14CCC -:10189000A766BCCC32E1E5691B3FC7B1A55BF26925 -:1018A00070BB65D3CA36DCA7AF6DB2F2BA79A6D0E9 -:1018B000B94F2D60F1D27E74982CC6EB970878EA68 -:1018C00078C183BCEE49413921F6A55BEBEFC5FD3C -:1018D000A54BC5BEF4EB5827ED33B89E45ECE80C9C -:1018E000DC80217209E3DDB2833B071E86F3A8ABDF -:1018F000E6E76458710D9827D864257E6DF1EEA156 -:101900007FEF2B34C29E743A8BFB13B1ECD9DEB857 -:101910000240E274541CFF7FE257FFB5F8555E09A0 -:101920003F8FAA252EE429CCE0E74DE03E87BC128C -:10193000599C37218FEA003E397CDF071ACA617D46 -:10194000BF03FCACBDCC788EC2E6E903F87FC525A9 -:101950008C7F2723928E7595EF8873FBCCF8FD253D -:101960003A0E5C0F3D399DF2EF60FFE6A2DCE3F634 -:10197000EFEC82C053D3A91E9DEF7BD6E34827FD31 -:10198000EA0FF17E09FEBB39B9B43F2788FB77E641 -:101990002758F65BE4BEEF33731DFB7FD3BCD5ED58 -:1019A000C51C1EE1385EDF1ACE60D5CFC5C0C74367 -:1019B000E55C1F86B363E34B7F0E76C6EB882FF49E -:1019C000878670A238E330C6078E0F441F3A1E93F5 -:1019D000672AEF10DEF57AF002F524B69BD5C0DB5E -:1019E000747EDB06496E44FD1A925FC5FDF5F3BEB9 -:1019F0002579108E7FEB3CDCBAE28C41E5E1962143 -:101A00009DE5F52FBFFED2EBFF0742E7FBCB008041 -:101A1000000000001F8B080000000000000BED7D9F -:101A20000B7855D595F03EF79CFBC8931B08F42224 -:101A3000014F0268D4602FEF04089E9B9B272470FF -:101A400041C0280F4F08626CD1466514289D9C90B8 -:101A5000104244C119ABAD75F4120CFE7FC7AFA69E -:101A6000FDAD15E9E38268A9851A6DA8B1551A90F4 -:101A70005AFA8F9DC10A63EBE8386BADBDCFBDE765 -:101A8000DCDCCBCBD8A1DF4CF8F4649FFD5A7BEDB6 -:101A9000B5D65EAF7D72D4C9189B01FF1993EBB424 -:101AA00002C63AB07C19C31F8D4179E9504B390702 -:101AB0009AF6F2F65768FF1636C63156CF447FD1F4 -:101AC000FE37126F7F34302C6CA4337693A887B224 -:101AD0008E65B33F634A6E4081FE0D9259DEA9299F -:101AE000D6F932776A30DF09A77DFC6562BC42ED2A -:101AF000131A3F149DFF93B006E5FE38F897335E46 -:101B00002ED5FE42EDEB9859FF171DD77B5C32CBEB -:101B1000E375EC7FC46596C7D6E1FC0FE4F2F1678C -:101B2000978C0F1B97203C9FF7F817DAFEED592A88 -:101B300063C3011F0DDF0D7E017E5DD6B853D6A1B4 -:101B4000DF5167E86D960D64F6A0A476419F42D6FA -:101B50002D3399C076C95360084D621D30D7AA1243 -:101B6000F8DF54C063BA83CF63F8C31AD0D9D2D98F -:101B7000269DD68671DE6474F79B7D773C8EEB8E56 -:101B8000C26DDCB1C206B731BE4E9B15833BB81F98 -:101B9000DAC3784BEFB8CD87702ECD33D73783E6D5 -:101BA00069CB32FBF59F75DE57F79512BE9746E776 -:101BB000A9A2F64B53CDF1168471DE183E97D07E64 -:101BC000C4E01A6DC3A7BF6409E133E40D6F1E01C1 -:101BD000F809F998DF007CDED4D02CEB05163E32F4 -:101BE000822AF1912F5A0EDBF9A880F868B0E11A29 -:101BF0003D23B455837D62F9DD6A68C2E7B1EE88A2 -:101C0000F30BB8EE6D12ADDBA4A3655E0BBD7B607C -:101C1000DDAA59BEB2AE217D30E6ED29A379DF03FE -:101C20007CB3183F3163649D967EE1E3B5A4E7B9C8 -:101C300070BF566A921686FE9FE2CF75B1E7DBB39E -:101C400024E217C0E7FF237C16023E33F03D233E1B -:101C5000786672E8071AD4335577EC07B85C9A8730 -:101C600075000EAAA687F6507BB6C387F8070068F2 -:101C70009CB6D798827C06BCE577CC84B293D576A7 -:101C8000170C9CF7E11207B56F61ACB21BE09AB27A -:101C900029B43A6469E72DE370658AE7918CFEE523 -:101CA000C361FE77A06A138CDFB20D98179EC71A26 -:101CB000A4B0044D8EE578E715427D4FAEC3BF0951 -:101CC000A6EF59EF1EBD16CA7DB9E97E84AE2F6B13 -:101CD000478617E639E697059DDE761CF9FA4846F1 -:101CE000949F0C3C5F7A245EFE9556D489FCF4A642 -:101CF000CACBDF2AFDF271A300E98D79D908C003B0 -:101D0000F6005E75A4CDF2B8010E57398813ECEBDE -:101D100065BA0BEADD580F4B5CB079D7D7AFA7D1C6 -:101D20006B5F1E378DB15AFC5DC5FE8AD1EFA1797C -:101D3000954F257A32E7B4D8B8AED696975A108F19 -:101D40003E9995206FF9787B1FEB6FFED481E343BA -:101D5000399F2109EEFB14F65C1265FCF914969884 -:101D6000CE4295B908573EF377C07C0B74E789687B -:101D70003D7F6C53A60938111E79636521FC9ADA00 -:101D8000606F37371FCA9E58794E6B7D0903BCCEF2 -:101D9000D1A0DB44C60EB5D647EA619E43856EAF3F -:101DA000049876E528B6F67359772BE29DA9070FBC -:101DB000C880971562BE16EF82B7719C95F95002E4 -:101DC000F88F7C359031351BF94DF63B441B8789E4 -:101DD0000F46ED9C8E6C92D37EDCEF9617CC7D9BEC -:101DE000DE897C20A749B672C065D64FE8443E3CE8 -:101DF0001295ABE3566279F158936F323A91AFAED8 -:101E00004B33CBAE95C847EF284E4127C33B914E8D -:101E1000DACDF18CED245FDE6066BD83EA4351F9D3 -:101E200057BE13CB4BBC021EE31F481EB668FC3CDA -:101E3000B96A5FA4DFB888F6C09F570690DF425C9E -:101E4000DEC5D7CFE80DB76422BD007EC6AB03F96F -:101E50006D4340263E0A69EFCBC837A58D8033D845 -:101E6000BF60ADD43B15695C61A391EFDB9A60ED77 -:101E7000E3A1FC62914BCD40B91E2AD712C88D1F39 -:101E80000438FFCE08A467BF8BB89BCC2623DDB5F2 -:101E900035AD13FD530CDCDFFA71AE704A6EF27192 -:101EA0005E0D3A48CEF448DE45FC7C96199ECF8103 -:101EB00007C7A617B158BBA783FC5C6E9EAC550440 -:101EC00060DE79207E19EC61F3EC47432530CF8941 -:101ED00022A7DF8DEB30B4D791CF160A1ADAEED2F3 -:101EE000D87A941B456EEF2694DD72C14BEBA0AC03 -:101EF0008C027EC57225A76F1DFE7D9A87E32A316D -:101F0000FA073816ACB3F383C22CF40DF53705325B -:101F1000B2DFBD060A57B3AB71FDF739432B508EC4 -:101F2000B5E785EEB0CAB3A7825C8E85C57AF7CFD8 -:101F3000FE762DE2E703E6F0A3FCD89D1A2279F69F -:101F4000BB4CC63A27E23E32D53B02F99AAF43CAB0 -:101F50005FC2B0FD6397C31246021CEB7ED3533AB7 -:101F600019DE7F83F73B792D6B64F85EE1657818A5 -:101F7000C6446C7794DADD1BC8A379D9E37E8F075A -:101F8000691F9AE37EA7B36E273E1D693F1CAD27EC -:101F900090D3E693AD71BE17C503F2129C84B86E60 -:101FA00089E98E4F71FD42FE039D6EC4FD01A94F6C -:101FB000E7C88C93A76CF43629A0121CF17407FDB6 -:101FC0005AA8DF22B31F73EA167D7D43E09170F3B8 -:101FD000383A8FB652BB74388FB26DE7D17D810429 -:101FE000E7D19555DAFDFC3D2F43FF0793F4FFC77A -:101FF00044FDA1FDC3F4DEA313BEAAA66B8F6079D6 -:10200000CA18539E4043109CD70D33CBA93737E4F1 -:1020100058E5CFD427505EDCA84BA23EFF09E4EF81 -:102020002325A6BCF9D90AAC8FCA23B6F809945F58 -:102030005179C4E6DE8CF551F9C3EA1F47F91595CD -:102040003F2CF804CA8FC002598C77EC711CBF6D0D -:102050009939FE15E100EA250EB33F0BE3F8C9F408 -:10206000C8DE59DD2BF09CBB295ADFFDB866B133C1 -:102070007E354B7F02CF45B66D387BC7E483BC818C -:10208000FC6ECA01937E4CFDF0D517C3BA01ED1664 -:10209000566A11EBBE44F5CC7EAEF7C4F4CBDF73C9 -:1020A000FD7BF0F5C7D768FE024E6F9FC3F86F5BEC -:1020B000C737F52978DF4FF427DE5F6AF61CC07753 -:1020C0009AE09BC2E1BB88FE1FD3BAFDFC9CFA2BB1 -:1020D000C09B5A62B1032E417C8EB9C4E19B5482ED -:1020E000FB5DCDF7FB698D99727C2AC13D800ECED8 -:1020F0009BFE8B69DC52BE6ECBB89A75BE64F63A15 -:10210000B42BB3B78BF24F25C125C63D4BFF1A7BCD -:10211000BB68FF5089853E0781CF6FB2EEEFE720A5 -:102120004756D3F8E3F8F8D7C7F0789BF5FDFFFAE8 -:10213000CDCE49E7DB899E1A393D9D87BEFD75C42A -:10214000EF56A95BCF243F9161E2FD1B380EBCEF37 -:1021500077C1FB88D88F5D45A16FE17B2CFA2659AA -:10216000EC1363E14E842F669FC04005D6F3FE86D4 -:102170009DD6F3FE7B2537ED34804EE4206FFFD4EF -:10218000FE97EB70FDF165D04BFE2FED7F36E82515 -:1021900013482FF936CE7FAE7101FE6EC2C3F39C99 -:1021A0006E12D43F4BE33ECDEBDB5D5C8F7D63D99C -:1021B00007A4C76977AA0ED4E3CC73FD27255C9FDB -:1021C000057DA432917FE127C29F06E3FE84E6ED00 -:1021D000E6F8EF0DC919A86F46F51616213B28A69B -:1021E00057AD223A8AE955B75279B6D8E7D74BBEF0 -:1021F0005427E07D85E341ACE7DCED7B080E1F6FE3 -:102200009FA0BE97C6CBE170B2F48327D06E257A2B -:10221000E53FE31C505E89BFA900BF73717136E8CA -:102220002DFB5B255586725DBBB9CF77135FC4F478 -:1022300036CE87370ABAFF53C906DAC71B4F9BFC55 -:10224000BF97DA4F89DAA91B08FE37857FE26BC199 -:102250000D267C27093E95C3F7398C7F9AF0C33849 -:102260007E6A99E144BD0CEDCA2E36707F3F167E22 -:102270001CE8F71FD4CFC3E1AAD525D2DF43AB8E2C -:102280003991DE57F4B284FE2739E832FBCB41D2D4 -:10229000CB857DEBE77EA1F8F629C1283DA5507BD3 -:1022A0002F9FEFAB45A1B420BC9FA5BF161CC1F763 -:1022B000C983FA68A8540A77E4A27D935E560AE5BA -:1022C000050ED64F761F639BD1EFEBFEA1C23AFC01 -:1022D000D45A552C7E1DE0D25FA11DB9586CFA026C -:1022E00016F5AF38D05F63F1DF901DE80EDE9BFF7F -:1022F000904A7E97975AD04FE693C9AE08DCBF2A22 -:10230000520FE5D442B7D78DF3C83964E7BAEE036C -:10231000FB1365D4226E5F3AE01FEAD1A9EB18D90E -:102320006FF30C29ACC23C6ECDEE7FD1379E6A2193 -:10233000FB6E15F36A59F02CB4D7BBE2ECD7E6C9B3 -:10234000BA1FF174BCBDDE81F80854713BEC78FB18 -:10235000D874E4BF783BFA78723BDA40BBB92766A1 -:10236000473BD70EA21D1D0CDAEDE8D145A132DCAA -:102370004FA66824DFF6CF9EB190EC6543666E6889 -:10238000DFFF909289FE3E639BE24777C331A7B699 -:1023900082FC07604FCB63689B18FAB7E60BF8FB2B -:1023A0008B4E9522FCDADD63FC48EFFDCD6EC273E7 -:1023B000FF2D59E134182FD3F8B03505EA5F0E8FA1 -:1023C00042275BD4BE8EB7C3C17C32906EFAD96807 -:1023D000D681FBA078D97A7C3666FA0D7FCCDE9E5A -:1023E0009FEF3570BCFA701AC37D8FFC8C49EFE605 -:1023F000330A39201D2F60AA130BD733CD89F85F1C -:10240000CC742ADF00FC268DC5F9F20DA203E03B57 -:10241000F4DF6D98ACDF46F8788CD3077B40D98920 -:10242000F18AFE6D0F66209FED4EB5FB1BCCE75A7F -:10243000E16FF0A09D3F6150EDFCF5048F9013E734 -:1024400021579AF87E727E3D8DF6EF703A271B90E9 -:10245000CF7B841FF8812CEE3F7928C8E54AFC1316 -:10246000183E1BFB5FE83901E7E5F6A0DD8EDF8152 -:10247000E5F3382F1F2639F32C5F675B9099F2E75D -:102480009B41AE07A899E44F01513C8DEF2FFE7C94 -:1024900024E94FE0F8DAD312ED578ACA480EB95949 -:1024A00028C289C910EB611B47D8FBED3E5BBF9B7F -:1024B000037CFE1385FA3FE3FCC5A78042A19DBBC8 -:1024C0005A0A4BD06E7EBAF492A4C6DA1D413F542C -:1024D00002397A54C85168167180BEB23D13F600B5 -:1024E000FDDB8A7F08CAEB379AB4A3A8C31D69AA8B -:1024F000A4679FD248F2A3AF5D0E37C33CBF6862AA -:102500003DA5E3078E5BBB2C70F484451ECD2F7B6D -:10251000D2034291B5E4771E94D05FAFB955E4DFA2 -:102520009E0CEF0385C8AFAFC9AC0BE05DB2A8EA63 -:10253000E8098B7C881F17E66306B0EC1B41EEC7E9 -:102540007C31E08E5C07F0ACDA268571BC55DB8E01 -:1025500039D15FB9625D1DD3619F5C85C714DCCF43 -:10256000F28097D639BF50668605AE6F4ED37A8219 -:10257000DCBFF33AEDAF3FAA47FD12CB01A796E9C6 -:102580002D88F921CDB8C0D3C15DA48FF664319AEE -:102590003FE463848FA096EBEAC7388BCF4B7ED3A2 -:1025A000434195E6AD6BDD49F0A4CE7A9FE001DDB5 -:1025B00039E2183A10DF261FBC26F0DE26F09E0C0A -:1025C000CF7F0A727F9E599E5FA664209E5F5754FC -:1025D0008A7324E3EF85A5F6FD71FB2A6DE516ED00 -:1025E0006E07D2D3F15639EC96E87918F7ED34EC52 -:1025F0001BFAE9CD717A3258ADF57C36F76756A9EA -:102600004C7099FBB3C2E0FBB3C208105E569456FF -:10261000B946F2B85A37D036AB2FAC6388179776E5 -:102620004C4139966CBF80DFDCA516FDF122FCE73A -:10263000434A2D7AEDE7EDDF87F946D37C717AF6D0 -:102640005F2BBE60D2532FCAD582985C2D2BE5E755 -:1026500041FCD394AB167D92FC9A163856365C0436 -:102660001C269F209F3643D3E00EC9897C12427EF0 -:102670009D80FAD91F367F211BF98675A7C0308E41 -:1026800052CE37AE59592EA48BBAF6F7153CAF008F -:102690009F15844F2187279632F31C9A4374D1C02B -:1026A000E9E2BF3BAE03F02C23389771382FB5B861 -:1026B000D3ED35A146842FA4815C4A477FBC57ECFB -:1026C0003F1BCDFDDE1716DF3CD67A37433D70C188 -:1026D0001F3354D4036F2AEAD272D584F14D55B218 -:1026E000C537EB4B488FD1182B19C9CE19DF8C8F0A -:1026F0009F0E8C771A142F35F5EEF878677C5C9373 -:1027000025897F0E8C77BE588D7AE61CBFEC55D597 -:10271000583CD335EBDDB7D8B503E39D9FC07A04B1 -:102720003EB39965BD7DA3D5EE08C0D731D2E3EFA6 -:10273000E4CD993C2D864738073C6E98A7B50CE050 -:10274000477D39B793E2C6163CBA080F1788478A07 -:102750006F235E5AA5F026DC07A5D140795EC7BC81 -:10276000EAA3DED87E46C7CBBF47F341FD57EBD384 -:10277000990310B239FB2E5607E5D443294C063D88 -:10278000F6907A17EDF7A1F732548CF7BA7D967D63 -:1027900010B8544CF8E48176D25F611F3D7989F618 -:1027A00051ED2CC573F67CF76F5751E808CA150F29 -:1027B0009CD7CAA4D8FBBED11C9FEF5CC5C29DD2DA -:1027C000C07D047C6B6477E6B39D846FD6C8D03F30 -:1027D000D02A31F551FF40BA70A46D341C682FAE79 -:1027E0004C273BAAA5B191F0FD1AE0DBF072FEC2C6 -:1027F00038D559F8CBA40B268D387FBA88DF778C73 -:10280000E3AFCBBEA4F735097FEEBAA07D9D3B5365 -:102810001B5236DCBACF5A56D9542BDF1A222FC599 -:10282000A07D341631D69535508FBA4CE4A5C078CA -:1028300023B1FFA83226FC80DA282C5F7F396B4C4D -:1028400094F7E2ACE076CC3250C1C9AF62A4B2AE2C -:10285000296865ED787B04EE9771958A65A61E0C54 -:10286000235DD589F51FD9B2B30FDBCF074C621EAC -:1028700004BE7558F0E32FCBA5718BD61C3BAC5230 -:10288000B5F7288EE702E18F76EA327C89E382BED3 -:102890008AF175A6E86C21C8FBE56BA5B771DC5A17 -:1028A000238DA15D1BCBAB782A2EAF8297E7E788FB -:1028B0007AE3FB74FEC4E298FBE2CEB7373A6D715F -:1028C0004CE3D84A7B1C93E7DB98E7D99197FE65E8 -:1028D000A5A158E398EFD3F8479799F315EEB2C73F -:1028E000313FA1F14D3F35631F765AE3946049D1E2 -:1028F000F96AFA91FF5C36BD9EFB4DF585B83F72D3 -:10290000506A44FD080E184D227F8DB713ED69D033 -:10291000FFAFC7FABFF575821E727B9925FEF1B72E -:1029200006FF31D3BF6F1C5AA9155CFAF002BEBF77 -:1029300045F8AEE4F8FE1B80F7BB6509E20097108E -:102940007C2F117CD138C47F3B3C6F9459ECCFCFA6 -:102950007BBE1933B51338DFE7B08E536596FC8321 -:10296000F368FFEFD45EC44BE3EB6F2FF7723F9633 -:102970008813BF198DE365D6C7C5F528EE158B23DF -:102980005E3E3630CE0AFFE5BBB0BD19479C5D9E6A -:102990005B4F79D149E2981AD62BD6FE2AF5EF88FB -:1029A0009BCF25EA17955F536FD8F07335B5EF8944 -:1029B0006B5F2BD6B7B27CD22EC3820FB038A97D05 -:1029C000542EB1E9F5F6B8E3D47A6BDC714DF9F425 -:1029D0005D66FCBF1CF1336E403EC4FF487C04CAF8 -:1029E00085BD29E2E5261D8E9EA195944FBDF4E09C -:1029F00085FD5B526EA1FFBFC27CABCA2D79171754 -:102A0000DA3FCA8FE2DC37F32700BF77E03A6EAFD8 -:102A10005009FFF1F912A69D18EA676427CE646198 -:102A200019E31221BFCED00F1AE56B43AB277F5DB0 -:102A3000F47E44E52EFBFD88E65DA85FC4CEEFE79B -:102A4000EAED790EE536B8B7BFFC9CB9EE96724B4D -:102A50003EC3608FBFA6C28E976859E067E91DDF4D -:102A60001C6DBF7F11DA45718CE8FD8B9B68DE58C9 -:102A70007EC7ADBBECF91D6BA91CDBAFA6B8FDFA98 -:102A80009A0DAE8FCB9B082E97C87B73AD9292DCCC -:102A9000AFB891E48219D785B24D2E50F97380EB0F -:102AA000804947824FA3700EC8CFABDB857EA6C19D -:102AB0009EDF22175E42BA187CBCF3FB1D26DE9314 -:102AC000DDEFB85135CB5FA96F28F8ECF362FE5FFC -:102AD00079C2FCA38B5D07BF2FE28ABF2FC2D6D776 -:102AE000DBE5CF79C3773AB1FC39BFFE9F24973F2E -:102AF000FF89F2A725DDE1423CEB3EA68513D8C74E -:102B0000B757F0B854943FC57D94EBB727B6A7BF2D -:102B10005CC1FDD7A6BF3BE03AB5CA1A071D26EA3D -:102B2000BD15D1BC016F058EBB8EC33706E521C62E -:102B30007B98C234E0A945D78FCE41F85A7ECDC7E5 -:102B4000633EB0933362E3CD14E399F3EC5B9051B1 -:102B50006BCD6BC811F38CA9904CFFF4980AC4E7B5 -:102B600046BE0E79C81ABAE715B5AB8D87487EB553 -:102B7000394D3BFBB15D24CFA272E89B44178BDD3E -:102B800026FD877759FDC6653FDDC5CF5528621CF8 -:102B90002FD6EF1BF564E79DA3DF6413CFAD62BFB3 -:102BA0008CE87E4D41B8CFD5DF624747A4EC981D35 -:102BB000FDCC646D16E219ECE9E2F31907F014A4F8 -:102BC0007D596BB7472CF51515B6BCA4536B30AEC9 -:102BD000992C2F6961C5D9F39216C6E86161854DBC -:102BE000AF0F664C453FC94847C27B14BAD8D75887 -:102BF0007ED77768BFDA4CBE13E507B278FDF29F47 -:102C00003E532FE0BFB9C212BF30E32DACE06004E9 -:102C1000FD3C96FC22CD61F5FB048F3971BC15ADEE -:102C2000D2F9F14BBB187F5B741F6FAFE0FE681DDC -:102C3000FD8E378A498EDCDA4CE3D6AEE2F7C2E28B -:102C4000F9E65EE1A7BA3746C7F7D2385A34DF66ED -:102C50003DE20D5306DC9362E39BF77B02CED08FFF -:102C600030AED366482ACA577D5D1DC51559256308 -:102C7000E3619F0223F3B6A1E830E7BBBC92EF17F4 -:102C8000FC5A8AED7C20218D9198275E4771E76977 -:102C90001ACF5B995EDD2C0F5729AFA503E72F5A9A -:102CA000B4B305977DC3B2EFCA89F2597A309F0554 -:102CB0006132D8EBE346007F0BF8F05EC85A98E724 -:102CC000CD683E4B75D93DD67C96D067CB6731FD3C -:102CD0007F4B4B00AF16FACBAAE478CDAAE4788DEF -:102CE000C58119C56FAF60B573AEC2BC14BCB70562 -:102CF000AF7B0C7ECFED4C0E0B63FCBF79762AF9CF -:102D0000F1FAB318C5556143326BA6611E09FF493C -:102D1000195FCA30CFC50DEBC275605C3672250CE9 -:102D20002F2F1B124940CFBFC8D4993F1DFDFEC6AF -:102D300066067413D41FA4F8DCE5ABDE6FC07957C8 -:102D4000E86E1549E0C6066F19E571ADF13BEF81FC -:102D5000F7F37D32D3D09F5DED3CCEE3341EC2D37A -:102D6000FC525E36F1E266CA712B5E94B8F2BAB7D5 -:102D70009AB71CB0B477455232302EF85285C80746 -:102D800012F78A989C4E7470C6E708631CAA4761C4 -:102D9000FB158C63E832C515BB5AEF3C8C7CBBC27B -:102DA000A7F81DB0CEE03A89F2BF6EF4723C7DD830 -:102DB000646C39003A6CCAC83C8AC39CF17AC81B5F -:102DC000DFB6AC8BFCF6402F3D0AB43FB69EE7174A -:102DD00099F94F0B04BD98784CA9FB80F07206E37B -:102DE000E18897C22CCA839A07F850BD14E76F4553 -:102DF0003CA5B2C6C830186789CFC122163F34AC93 -:102E0000DF9647066353DE99426F6CF5849FD4F5D5 -:102E1000419E8F26576BE89F3F53C8F715CA7EA483 -:102E20007756CAE9D4C47F6A1C9DBAE3F2C3E2E9CB -:102E3000341EFFA711EF96FB5C5D0AF34790DE7A24 -:102E400065D22FA279570F3928EF8AB130DD63EAB6 -:102E50006243FD1D28372312C5096E107833F1CE69 -:102E600058E3E695E8E76ECCF4A3FF9F391A376381 -:102E70007ED48DE134CABFBB8975531ED472B49021 -:102E800061DE9B99D785E595CC4F4F8915D0FD9292 -:102E900025BA447CA1B348CD5580BFC865CE2C6B04 -:102EA0005E55D2BC2658F9BB9678C4D04A212F3D36 -:102EB000BA8FE779EAE2DE8F46F9415965A51E3DF2 -:102EC000C1B931BB481F5969C9BB50BC8D8CE2D315 -:102ED00045A151955363FD9F9AACE554C2F85F2C10 -:102EE000D446E37337EA79701E040F8E7F12CF83C6 -:102EF000E6C99A8AEDE3E5D5B1E4F9771AF2751FD0 -:102F0000CA2BCA232C203E1CACFCBBC99503F2EF94 -:102F1000A6565AF2EF8E3AF9BD32CA459EC906DE70 -:102F20004F5B7703D59BF7D3E2EFA5B1C7781916AE -:102F30006474801C6F311A69DD26DEE3F1C3C4BD01 -:102F4000B4A5BE97FBA46B07216FCD0BCADDC8B338 -:102F5000D187C1EF2FD7DCD987F13A83299447D89D -:102F600096CBEF2FCFC385E23AC6717D9055F1F332 -:102F70006A4B56A3CF0FF55B9C3C1F86E5EBECFA42 -:102F8000099671AB64332EB402F1097A1FE94BA69E -:102F9000BE6AB6AB17E7C26A712E3C3339740BE1D7 -:102FA0003F96DFBD1AE988A547C20E336EC77F285A -:102FB0000E64EA0F474635523E8D3BC97DEF3B2BF1 -:102FC000A3E7F99D34FE43E679AEDD85E35F37CCB8 -:102FD000BB08F9CC159459279E63F36F27B9FB1CE6 -:102FE000E68D824E335D6F0E8E80FD6EAA14F1A6C3 -:102FF000862C4417EBD1783E69A4B8D187E7DD96DB -:103000009189EF7DBF2AD63965CC2919C7DD028A9F -:10301000CEA689883F83F2D88CC5204BA00CE6FE53 -:10302000018CCB78500F28C27391B7F736401BD86C -:10303000876EA12F04AE00FA41FD6BBC3D1FC97C19 -:103040009AEDE2F3AD409467E0BAE3F3DCCC7CABFD -:103050003EC5C8F027807F7ED95A0FE56BE5ACF4FA -:10306000E039D9A60569BCF8BCB72D396C34C21556 -:103070009FD766E64D99F952E6B8FFA7D29ED7E6EC -:10308000F6F1730B9E9427F39D4A957F9742B3E721 -:10309000B799F935D89EF26B7218CFAFF13532EC93 -:1030A000E78632B60F89FCB3F8BC2A9043DFC57DB2 -:1030B000BF50BDA92DA6376DAE1B44BDE93CE4EF62 -:1030C000CF10DE04F2F7E7C41F31F97B08E91BE4F7 -:1030D000EF617C9AF2E5CF959B48BE6C91387D6E8E -:1030E00081FDF85E8279FA049F6CC94A4C57A704A7 -:1030F0001D374F0EFD1AE7D5B2F9BD8F4B058F80F6 -:103100008F3F5AE537E0E35F13E1017E5A519E5845 -:10311000F24FFF9DD69324FF34BEFFC5DE1F5640FD -:103120009EF0EF4B685215D989AAB0F751A8602BD1 -:10313000F31E6E9C1C17F5E792E3BD0E90AF000FD7 -:10314000EA0A56B93FAC8AEFEB3533F56155442FA7 -:10315000FC1EF0D600BF07CC221AE9034732F45A0E -:10316000E45F963FE91CE746B3C8B3D51B4224FF92 -:10317000179EA3FD266A7FCD4C55F8C187D27AB63B -:103180004ADA3752E558F95CEB4BABD2F2ABD0EFF1 -:10319000A187E83B0A5BF21DAA014BBB6FBA7E2DEB -:1031A000BEDF92BF89F6AF03084E02793ACF71EACB -:1031B000FE3C89F2849F9786C0D303965C02BA9E38 -:1031C00029F0033A08D5B3B7349FD5FFB1BA2AEA3C -:1031D0006F11F6EFB79FB4E6092CFED9D3AB0CCB39 -:1031E000F9867E94EF25A08BB22ACE3FB2FB4EDB50 -:1031F000F919DFAEA28ADF0F595225E206E23C5CE4 -:10320000ECE6F6153B04F059CEDB6B6696CCC5F5C3 -:10321000039A0CC9724E9AE722D558DEBB7DFC5E3C -:103220000AEBB58F63AEF35641A7E6BC40AF3770EB -:103230007AD56AF169D62F9619F783F4D8F105F09B -:103240002CE774C64E2481E7C984F0F4D9E1B9357E -:103250004AB7DAADB83E38AF1B70DCF612A0BB043B -:10326000F89D30B5640DD62BCC68CFCB3DAB3CBDC3 -:10327000BB2AB13CFDBB2ABB3E7B4F1597A7F75637 -:10328000911C493CEF2681B741FBAEC079EA6DF74E -:10329000E1AF09F8A6A3FFD9B46B81D5DC6EE36E6C -:1032A000E2CF8249E7E02FCECF378F69243BFB473F -:1032B000423FF99193299877033CE64F940FF462CB -:1032C00095A98F8447215E5E48A28F44DB25C9BB48 -:1032D000BF92ED48BB18BDA463D69134D24B4E7754 -:1032E000A6E1F9FFC28992847AC98F72768C4AA4CA -:1032F00097EC49A297EC15FAEB8BBF73919E517C2A -:1033000092EB25C52777C8A85FECABE272BBE84417 -:103310008FAC03DCC5A897C0387B845E82ED492F53 -:1033200039BD4346B88A4EF650BF6228A35E529418 -:10333000442F012864C4C3F3C51DBFC4FD8B5F6F58 -:10334000F514FD152BDD16F6F790FFC7ECD791BFEE -:10335000294DA7FDB6D3CFEC22D596375FD8CFE95C -:103360003DBE5D323A2B93ABDBFB615D5B59C60E14 -:10337000CAD7541A9FC0B2612894C7851FDE40BACD -:10338000B9773EC09085ED1A9FEAC7F3C5707BF10F -:10339000BB071FA6AEE076D05AE675CE8CC9235A7D -:1033A0003A80669488F15C1E6F0BD8798FA4651201 -:1033B0001ED7794D7FCF8ECA3CE87FEF95E3E85E5C -:1033C00050C98330109467F6CA546FFA870E8F6421 -:1033D00094BF0FFC3BAF06C69F2EC687F34EBB1BA8 -:1033E000DA2F2E747BD1EE2E97D3A9FD7DF9BCFD8B -:1033F0004CE35403968BFA5D2ADE3F63F246F90EE6 -:10340000F4EBA25E02EDEFFB61A8CC03F5A9470047 -:10341000121CEF2D17F93734F887FC3BB5B79BF03A -:103420009976C265F37BA482848B58F417575C9914 -:10343000C9CB8624924FE633DE4F913247F829AE4E -:10344000655FFC14F4AD336C633BAED13DBEE4C5A7 -:103450005D6C607FD30FF12F53B42173601FC739A8 -:1034600075B26BF65402AE619FF63CF4D0DC6B1182 -:10347000EF3B14F2FB1EDD9046FBB4F7416527FAE3 -:103480009B8E029F72FFEEFA5B905EF76630334EC2 -:103490001441BFDDDEE87DE7E1B76896F2D8572634 -:1034A000FE0ECFC3BDC3CDF60FF3FE66D9D8760BA3 -:1034B000E675EC1DC9CB35AF3CD365101DF72B6409 -:1034C00077AF7B273D91FCCC9FCBF9CE2CCF2BBC8B -:1034D00093D3F139FA81BC9F382741BF941A6E7F8C -:1034E000ED5D06204D443CE9D3E6009FECE9BBAB23 -:1034F0007D024C3565D6861E92A3C3FAD72692FB71 -:103500006573F8F914290E933D06363EB787997214 -:1035100000F35BE7317512DAFDDB67BFF0F36B6137 -:103520009E5F148D9F2427E06B7D4E5EDCBA5E9318 -:1035300057A25C7AEFF8A24472606B953ED7BE1E2C -:103540001E3F6DD9A110FEBF3CF7F49398F71E29DA -:10355000DE41FEBD3D7F74B04D406F7B2670FD1F88 -:103560006FF0C9D98302DF43D313D01DC077732214 -:10357000F8AE9ACB689CEA295A1DD6C7C3ABA21FE6 -:103580001CE00535CB8F7224E50FFFD083FECE3DC6 -:10359000FD0E72BA9C39D129230976F4E595A2DA99 -:1035A0007A5DF5311949AAD8FBE0660C0DEB1B6575 -:1035B0001BFF4DEF4BB59597370EB39597368C8A19 -:1035C000F123C37B42636D65B7EF6A5B39C026DBCD -:1035D000CA8BAA67DAC62BF3066DE50ADF5C5BFBD4 -:1035E0002AF57A5B796EFE525BFB1A7FBDAD3E54C5 -:1035F0003051C12B7E40975B115F69BD1AF1F9967E -:10360000BEBBBC481791E210D9DB47327A72D09F1B -:103610007D38C977E77E394716E73BA8462827E17A -:103620003CDF94156B1FC8EBB7F9EB5F98C3F5D47B -:10363000EFCF89F7D727BB27C7CFE7F3BD1F177F8A -:103640000ECFBFEA2E924B1D8BE430DEB76AC97FE6 -:103650003DBD1FD7B388FB193A72609DE994AF4115 -:10366000FCF5E2E21B4663DC2D355F1F86F2DF3C92 -:10367000BF83F961F60ED4A77AC36C2CDE3F837248 -:10368000BDB887162CE0EFAF10EF57E313CEED7205 -:103690000BBEE2CFE38067E24B6036B0D97FF6D253 -:1036A000F7FD1615707F50E9E97029DEB79EABED86 -:1036B0003BC0AF5573F9F38BE2FF9F9DE4DCDE372F -:1036C00067AA9D7F901FF69C587856F9FFDB26EE7F -:1036D0007F7FAEC9C322B0BEB79ABCF4FC75938F8E -:1036E000DEBFD6A4D2B3AD299F9E91263FD5FFB2AF -:1036F000A9909E079A347ABEDC5449CF834D216A43 -:10370000F74A532D3D0F35E9F4FE777318D1C7A55D -:10371000028F966FFA15422F3A24C2EB224CE59D98 -:10372000715293ADF21DF0FA5E22BC5EEC391229A3 -:10373000EE1E15E2E756423EF2CC35EF8D713D7933 -:103740009E4E323F0A9F0BFD77D931FF9D1B559A44 -:10375000A104A73477F8E0C1B957F871F666B1DA79 -:10376000EF717BAA55A2F3C63B91CBF347432524C7 -:10377000CF874F4C2CCF7307C8F33A3AB7D841F4F0 -:10378000AB62DA110AE3069C7F6A42BF883124F7F4 -:10379000AC78A078A68907CB7EE5CDBD88FD8A5F91 -:1037A000FFEC22ED2AC427DE53710E1D788E5CD10A -:1037B000FFB186BEA9E70B38BCDB8F2F1C82FA8ACB -:1037C0001B9D52A4AF80E25688FBCD843EF2685721 -:1037D000C3AC81E3FCB6B89BCEF5FBA27ACE3F9199 -:1037E0009E13DF0E7E0E101EF0DCB2E021811C283D -:1037F00049B4FE32F987FD9BA0FFDE7E467E33157D -:10380000756A80FF05857FC761EF4907E1F98C473D -:1038100022F9E85E7FB7077DDFCF7F8DB7336A245B -:10382000BADF90B67F8F8A7A6AA05F1F86DF232B6C -:103830008C5439F1FBA125B326FA532C7450A2D82D -:10384000CF49D454A3E70E39C586C6952F8BB597BB -:1038500071FFF362E55CBA97BD1CD7B5F0542353F2 -:103860000B84FF35319ED64816BF9BC2FCEDD37347 -:1038700049EF3C7019C675C6B3307D1F02CC8390EA -:10388000C59F20A787E8DE9E69A77F2469B7E17CF2 -:1038900003C66FD0282EC71C0E8ACB6D98ACDF896B -:1038A0007432206EE37DF92F129C69ED0E1641FDF6 -:1038B000C2C87411FEE2F7EB8B8555F7E03CBECF32 -:1038C0006CD7EF90ACDF11B842BD8EECA933604FDE -:1038D000E13D951685DF9F32DECA087711902C1FD7 -:1038E000F5B67BE5ABFDB8FF8FA4FD3DD947EBC036 -:1038F000DE42FB6B9B90C30FA01C86E73627B7B751 -:10390000DA9ADDDECE6CB4B7320D071C5C1FA68CD4 -:10391000093358E723426EB9D9F221A10967815FC3 -:10392000D827CEE8BEE778C9DE10E57497EEF81325 -:10393000DA7547E430FADDB64E7CAC7625E26FA24C -:1039400087C7459588BA001534AFC1B22DF7FB651E -:10395000A6BC8B7EDA76506630FE7BBFB89F9BE1BB -:1039600077D8F49D2185767DED3B8304B70B251137 -:10397000DAADD9AE30E6E9A828B700EE769F83F835 -:10398000AB55E5F2A1355DF37813ECEF16C4B73B08 -:10399000F9FC726EAB17FDDE3BD21DC4BFEDAAB2BF -:1039A0003517CAEDE90AFFEEABEAA84C94C7F2CE90 -:1039B0005C9EC7024D52284F2AB090F49D64F37468 -:1039C000887D37CBA905BA467CA6FA43B89E96F403 -:1039D0006C09F7C5ACFFF15C497C6F81FB95B70AB8 -:1039E000FD2935BF3B827E9DB691AB2723BA3CA013 -:1039F0000FBD0BEF3D05DDA43FA55FE6D213C1FB74 -:103A00007B31DE56A7BF12F1B935C3C10CC0DFD67A -:103A1000DC2471AFB95C8F6C51278588BE011FE330 -:103A2000A581EDF68B7DDEECDCE1C3FB6C5BC72F83 -:103A3000A17CB1ADA3B97CFE4A755F577301F2CD8D -:103A400057D89F906FB215DA3795F93D78CEB57992 -:103A5000152FFA05A664DFE30958E45C3C9F38475C -:103A60002EACADA37C82543F22BD4C3E44DF1B698B -:103A7000F383DCCDC57CA646AFF53B02A0777F84FF -:103A8000F2E35C74AA32DD83F885F1898E92ED5FF2 -:103A90003C3CE92899269DA57D965E9BE83B16F95E -:103AA000D50E1BDD38CF4137E782DF762EE6C4CE58 -:103AB00045DF21DF6A8C77DCCF78FD65D5EF75A116 -:103AC0005D1F5FFEACFCD9A2EC20B9DD32CE45F41F -:103AD00014DF7F6B2E87E7E8CF7F4FF3A1FB01F761 -:103AE0002DCBC3FD4D0F140E4D492497CBA6E8FEF8 -:103AF0006A8B9E9355DA4DE76D4A3523BA4C57438E -:103B0000DE71304E7AAF0C340AF8767CFCE763EA5B -:103B1000C5E351D9D1C842305E66AF4CF4893F1F2E -:103B2000831C1C22E4E096CBFF95615EC9F6B18A46 -:103B30009FE7B3BCE73FDB799239CBEE4FBA507FBA -:103B4000D1FC6A91DF90C252783E51758942793C2E -:103B50000E7ECE6AF0DF08212224B1FF2378C89FB1 -:103B6000CE49C6FD64D9CB18C9CD685E0B7E9706D9 -:103B7000C7D119E92378B116DB5DB686EB5B39ACAA -:103B80005FC278E0E598DD2323BD73F97986E538D7 -:103B900028AF07A6C1BC14C970D0B9F8F0E547A595 -:103BA00000BC7DA068F544C447FC3A1A06ACE3ECBF -:103BB0007830E11C6C3A35CFEF160F3F8F3538B8AF -:103BC0005350598EF37F96C91BF9796CB8BD785E56 -:103BD000B7288DCF60197A87C85F1AE7FFFC308558 -:103BE000FB47A57B98572A22FF673EEED33A96EA19 -:103BF00047FFE41045F7607DDA3885FE5E03E8DDB7 -:103C0000D331DE12B3CBD5749E47B78EF20D7F82CF -:103C1000E71AB4DBFFF1D9E5D1B3E738D73A7AC771 -:103C2000A5937FDD539F86F6F873BEBC4368DF9C87 -:103C3000F1F03C30B3DDFEB8EFA2B40939F76AB554 -:103C4000F0A3A77C2863FFEB7CAA82F976259E89E6 -:103C500024DF5BA4C4F18237847CBB427D95D3D939 -:103C60001AF37B666B48FEFF2643D06F83BE94FC3D -:103C7000CA42DF639AA67AA7C5F43CF3BCF4295E76 -:103C8000E3761C47E4610D58E7FEDB187EA785F953 -:103C90002CFED93C9C7F4834FF8EF8394EBF4B86B2 -:103CA000CF0E611FB7F84A287FE30CCAAC04F113AA -:103CB000F3097AEA4F514E4DEDB1CB97B47CBB7C02 -:103CC000697734523E987135F362BE08ABF6FBACAF -:103CD0007A32E8AB87AAC93EB5EB9D6B6A18FFFE46 -:103CE0007696AAA09F26E809308C4B28393AC3FD66 -:103CF00070F9FC67DD8FAE6AAEA7B4E5AF0CA15DCD -:103D0000B37DF697082F532A797EAAD90ECECBA37E -:103D1000D516FBC6E5E3FAFA797F67C9EBB8A0EFE1 -:103D20002C75CCBA857F67C9B792BEB3F41CD02579 -:103D3000F2CBFE0C3D0DF5AF0BFDCED22D35E23BA7 -:103D40003E293C1F45E9E3F107A54FA7BC1297EFB9 -:103D500014C56FAE137928F1FE22B7BB91E26D91C5 -:103D6000E2C6A5567FB189BF2E41D7BF2DD6295FA8 -:103D700028D9DF8930DB21C6705D6EE10FDD52BCD2 -:103D800081F0BFB0328BFC518AF047B94EE9941FE5 -:103D90001C9EA267D658F0EFCE31E8BC4BFB7BC629 -:103DA000EFC17FC4EFC1A76D622578EFBDE4E349A1 -:103DB00014A72A89A4109FCD3EEDA7EF5897C94FAD -:103DC000B7E741FDFE5E85F2F2F6CF4ECDC673ED4C -:103DD000835EAEDFA6EDBFEAD017A15CDC5B8F3E51 -:103DE00001903B00CBD081EB987DDAF199ECCCA926 -:103DF00068675AE225E6B83F683A48F4F16C530F19 -:103E00003DF73445E8D9D1D447CF42450BE27A0A91 -:103E10007B2876C9669C807A0B1C856F417F0B3DA1 -:103E200078A7E8D36B88FF7A6CEDD2F2FB6CEDC01B -:103E3000CE9D89F8557C1C9FAE6AFE7738E6F7B1B7 -:103E4000CD92FA3F4A5E2D473C0C82BC5A597356BC -:103E500079C5E3A9257DE27B63A6DC12FCF8976AAD -:103E6000957F37C9E44B115735CFE976FC15CED392 -:103E700096CC2F71F966E66F887B8CE6F7EAD7D788 -:103E80009CDC8DDFBD6B7BD3ACFF78B766A967C6C2 -:103E9000BFADC6FB28FBD0B8053DF4B7353F5E8DFE -:103EA000FE8625B5598A06F00531009B15BB476390 -:103EB000E63BC6E3ED780DB7878EE479C90FDF06E0 -:103EC0007BD29900CF2FD708BB4DB5FF3D90D424AE -:103ED000F7872262DC43026FED2E9EA790EC9EC80E -:103EE000D745FB64F7447E5523E2F5E7B817F21D8A -:103EF000D1EEFB38EF70CAAFFC27E423F3EF75FC7B -:103F000040C013FD3B1D3E96709C2E217747CFE3AA -:103F1000F9C92E9F46DF4583F19EA2F1C4DF5530DB -:103F2000EB679C8CD6FF33D547FF7E824E7E22F313 -:103F30009E5ED7E1D776372BB1BC9CB6E8F71679F1 -:103F40009ED3FB02FEF8A7794F25F65DA9C3BB35CA -:103F5000CB77A51E3FDCFBAEF8EED55EA25F713FCE -:103F6000675B0C0F3FA6F771DF19D853F3F26EF1C0 -:103F70007DC5FD047763DCF7BBD8D1DDD6EF266CB9 -:103F80003BFCD66AD1FE20B517DFFB4A4017826E94 -:103F9000FB77E3BDD1F318EF75824F7CAF6B630DF8 -:103FA000E7A364F40CEDFBA87DF43BC6F51E3C577B -:103FB00062DF317E83F0731EF83A46E3E8E6BC4CDC -:103FC000E443717E31F3C94CBA90E7713ADD5C236A -:103FD00099F796FE407858356878F880E089BB9F5D -:103FE00074AE753C3339F411F5F345F394FF83CA8D -:103FF0009F111EF35E593C7F0C9D2799F9D129F33F -:10400000709E9CE8F73C53E725961317342F8C9B42 -:104010004DE3C6BE133A7CDE20AC87A9E7975FF27A -:104020005FBC10FE351071000000000000000000B1 -:104030001F8B080000000000000B0B146060F8519B -:104040008FC0DC687C5AE3BF4C0C0CFACC0C0C978C -:10405000D81818DC38191844F8C833E7329ABE87E4 -:1040600040B366F130302C636560D809C4865CD8F3 -:10407000F5D90922D8C7817E5F05C497E91C06A33C -:1040800078F0E03A11068629A208BE8118AA7CBD04 -:104090000882AD2745995D2E40FD00C5F694E2806B -:1040A00003000000000000001F8B0800000000005B -:1040B000000BD57D0D7854D5B5E83A3367CE9CF921 -:1040C0004B4E92012721E0991031D840074C145AE9 -:1040D0005A27116D14D4887FD17A7B07DB228ACAD4 -:1040E000D47A956BB199FC4F4280008A142D8C3F95 -:1040F00054B0FA9A2A5AACB577A2146DF55DD15A2C -:10410000ABBDB42F566BAB551B5B29F415E5EDB574 -:10411000F63E99734E66328348DB173FBFCD3EFBB8 -:104120006FEDF5B7D75E7BED3D0A5441D569008749 -:10413000F18FA5F7F900A03E93CEFAC605CB1EACD1 -:1041400063FFF6B923DB5832EBE97995B1DA4CFD20 -:104150007A90002600343E7DF91F81D5FB2F70EA4E -:104160006EF6E9C9C0882FC2F209C909D8CE0D0D73 -:1041700065E70459F94147A48FE5D3871C7E60FDAC -:10418000CC04278DA383E66F9EC1BECB171483A9F1 -:104190007F7BFAF94D32A4CB009EBA05E46656AF98 -:1041A0002B70EAE5C37E80E75BD37F7DE304806804 -:1041B0007ABAACB37E76B73E43F91FB7EEFDEB1B80 -:1041C0002E801894D0388DF3DE9717B3764FB9A0B0 -:1041D0006590B56B8C4AAEC5A6F162623E4F7944DC -:1041E000B9D620672D0FB072F6BD31787ED6F218A1 -:1041F0009B11D52B11FD1C1C76623D1D467C34CFD6 -:10420000438BB2CEF338D1CEC8D70DF3F93EF9EBDC -:10421000030B900E69286E76637AA86A1FE27B48CA -:1042200095740833FC0E9F4DF84D237E5917075E99 -:10423000E3F87EEA4347A48DE1BB51D5FC11960714 -:1042400099D1839537FA214A70C92C65702C10706A -:104250005F2AD24598125D74A2CB90CAE8E2CF0FD4 -:10426000EF699B1482D798E710CEB38076065DD9AC -:10427000577F7380B583EC7C30163F6CBC938F1CEA -:104280004E03AFCDF386FEFA860AF47798FD7F865B -:10429000F6D3BFBE5193C99F7670AF25CF381AD4DD -:1042A0005318BCF84F1D53F98361A33CCCCB719CD0 -:1042B00064ABFE4135E3BF8156F8A09AF1DF9A5610 -:1042C00095F2FDAD1AE5FB5A43944FCAAC09A363BE -:1042D000B21F5209D6BE24CAEA9BC62B9EC3DA99E6 -:1042E000E00B44344BDE5713B2D4F7E8BAA53CA92F -:1042F0005FEF4831BAF7D63A524E09E16032722286 -:10430000C2A152CAC07D39C4E653CD9BC06A97FE94 -:10431000CB2A84E70527B4B37C911E755CC1F253A8 -:10432000424E4845D8F8452300ACBFE42D00EB5978 -:104330007FFDB34E715CC1F27D73DD9A530348B1CA -:10434000FE936ED6CF4769BD03FB99A144B01F18F9 -:10435000907F8B7852D97F87AB00A6EACA6B8E22FA -:104360008070827D37CFCF9D08A15C17CFB17E9F33 -:10437000AA2FB91658FDA960FA1ECED0D318D7C8F7 -:10438000DBC7B38F73FC0A5BFFB67EA7E8C30D5A89 -:104390006DA6DFE361A44DF3FF2BF71B6D94904EE8 -:1043A00011D053B38E1DDCFE157F2979E3E40C9EFA -:1043B000FB5D5C0FDAE56D181CA43F409E005106C2 -:1043C00097AE3B527DAC9FBEB083F847EF8214EAB4 -:1043D000ADD593F7C631DF1756F476960FD7EC6953 -:1043E000916602AC9AAC11DFF53DE186F6088723B1 -:1043F000C8F8748AC1A71F0D3754211F4A1059CF1E -:10440000CAC3FA9B6D585F7BD9ABBBE68C9D1FACD2 -:10441000E0F3A73C9BFF08FEA37E6CBF3FAB57A217 -:10442000CDC8B70948B9193CBDD5ED4D0936CE9672 -:10443000840C283F7DB70CBE82784E9EC0E1B5CF7C -:104440007B8AAE2C46BE06F3F86CBC29D5172FC369 -:1044500079D9E130F4C59DAD1A4419BD36B7D6906F -:104460005C6E69D506514F6CFED09915BF0B24AE1A -:104470009FEF70353B12B8CE4E77A4B649D85F6C2B -:10448000F3550CDED5F51367E33A70FD748EEF0F2C -:10449000FA05BEA5D4A540F5159DEADBE47F8B1C8B -:1044A0006D47795E1D2A8304C3EB14D7DEA6A99855 -:1044B0005F51352B8178AFBBFB35EC6FCAF4693A9D -:1044C000E2636ACD9BFB502E377F9422B99D5AC37D -:1044D000E49ACD73CA8A8983D58C4F2AF5D4D7A89C -:1044E0007E8DA2A7A40C5F4E86483BD2EBF8161F28 -:1044F000A4B5FCFC39393E3E7F1E3B3DF08F91ABAD -:104500004936B9BA23875C2D941CC42FA37255C3B6 -:10451000E48AE175C74956B9DA3C39F55631CACF54 -:104520000CCEA7763E0FD7BCD98074ED67F2531A34 -:1045300002A8700FFC5942399CC5EA4B542E7D9954 -:10454000E5FFF40BAF0E284FB59CAEF9E4CAE0E7E7 -:104550004C6A1D774B9DA3B19981FAB3AB36BEED82 -:10456000C6F16A151DE5AC4FDEF467C4B35EAFE873 -:1045700009C9244FB55C9EA6D431F9C92257F9C6A2 -:104580004FB6A6E0752647EB5A43245F6B5B7592E6 -:10459000AF5542CED660D5B92C2FE40CE6CCA67C24 -:1045A0002EFB13A08DE44ED5F702DAC1EB58DF5095 -:1045B00081DFD3D1E83C80D23A230F69075BDBD798 -:1045C0008E9643142A09DF009F41F0FE9888B2F6C8 -:1045D0005A1DCF3FDEF6C7440713C2751E5EFF09A2 -:1045E000A9A62131CFDC7E0FF56FD467F97463B5CE -:1045F000A93FECDF028FA301EB1BFDBDDA56D19082 -:1046000060E3AF1579A5BD84E78F71FF4CDF841897 -:10461000D3439FAD9FD592E827F16C34EACF8C73DA -:10462000BBF456346129FF4314F164947FB7EDD98C -:104630004482D57F1F9ABF25313A4C9F1FAB605BE8 -:1046400018F036ED0534A5D6D9F09D99DF0B34BFAF -:10465000400DCFDFDDF66114F16D943F2A05DA10CD -:10466000DFC837FE89CCAEC27FB23157FDE4474B7D -:104670009FC37FCF29052867E3E803CCD264B3AF9B -:104680004E01EE3B7C35F29BA3FC0719BE63F03D67 -:1046900028B174FABCD865B81466812F6186CF182A -:1046A0003F1FBC061CB9F9938F6FE7A3C633E73CE5 -:1046B0003F8FC99B77AF2BC2C480CD4393701D2819 -:1046C00045A0985E2BF9E8E721DC8A81CCF478607C -:1046D0006CBFA5F32B206592FB4F9A9EDFC23CC7AF -:1046E000DB4B66BAB2FCCB663C3E88F5EAC7F29D6E -:1046F000313F8F989F67CCFCEE69C1F9E5C29B7D85 -:104700007E6B3D032DCD59F6119F7788FDEEE7E7CF -:104710009C87FDB3F100F597471F213B5EC3F1D89D -:1047200056B3F8A39FB720DFE71A4F9BC7C6AB3934 -:1047300076F8CCC7C701A6BF888FEB181FD7E6E66F -:1047400063BB3C1BF3F68A797B73CC9BAD9421DC75 -:104750008FFDFF3AEFBFC87C5E37B03E127C5E5CD7 -:104760003EFE49F3FACB736512AEEF088F93F373F5 -:10477000281B7FBD2EE9967DAE9DAF73CDEB9FC507 -:10478000A763E7353E9E8FB51E2A54BFB6BFEC2502 -:104790003CF6D5B27D02EE0B9E3983FC157DCF9D94 -:1047A0007E1CFA1FBCC94F41B40C601AF6CFEC89CD -:1047B0003EB42FB0FF4D7505D917FDAD30D8790245 -:1047C000C023450C0F7E9A27B5DFCCECCF14537075 -:1047D000752FEC5617637EE9432AFA95FA84BD5883 -:1047E000F7C2BDEBCE64F8F4CF289DE564ACD0E70A -:1047F00031BEEFFCE934B4E36BD977C45B80F7C713 -:10480000BEBF80F50333F8F75C70F994540CEDFBF0 -:104810004084C165E207A3FC6107B74B77A09D7593 -:1048200022C2A993BDE5F30EC690BEDECD8A7E7787 -:1048300096FDD2FF16FA74FB8C3D092FC285F61A3D -:104840009BF7937775575CCDDAF9EE04D2E7BE9A01 -:1048500054C2C150E7AB03DA0DEE7099E85E4970BF -:1048600009BA2E924E67EBA4CF96DF3C5AFF8B64B9 -:10487000B74CAAE5E58FB6FF4743876C2A4F5CD952 -:1048800010ADCC943FDF7E6D03AEBBD3D5D8AFE681 -:10489000B1F1A733BDD7C1F03A5D1E70C4899EC186 -:1048A000ACFCB27D9BDA92627D6CBF6B63D557B373 -:1048B000AC238C8A4467237FD2BD56BEDE21F0B77D -:1048C00059E0B39FA117EBFB6A07DA119F27DD0BB5 -:1048D000116738B7BECB49C73BADFA6EBA6C9DD7EE -:1048E000B19ACFFBA0F1FDB6E89FADEB2F3AF87C73 -:1048F0001C284727311A384B8E7E3E69C413B723D4 -:104900007E93ADFF7FD47CA7FBD938C14F7E1C9F1F -:104910006D9C5CFDDAF555A2112419F7FD151041C7 -:10492000784AE6C769FFE2F4EF0D25989E95B561D8 -:104930004A5DC1915082D97F4A482FC7D45D192959 -:10494000C7EFAB3F740A79EA6943BDBA6634DFDB6F -:10495000867A742DE6497E5651F9FAD1FC6ACA6FFF -:1049600098CCE5EB78E76D43A887AB503931B85662 -:104970000FBDDAF2650657D96E7F044D8D327F0484 -:10498000500F1BE56B86DE0AA968C7EDF68387F139 -:1049900043A9160573FBB5437F0BE19EC52FCAFDE6 -:1049A000C1664BF9FAA1E9E521D43FA2DC1B8A518B -:1049B000F986A1B9E53AEA93DD7E0DBFFB2AE3341F -:1049C000EEE94F5F43FC925CE820BD6EE031B970C8 -:1049D00036F9952F9762D39D8C1E0D4FF7AB68FF6C -:1049E0002777D792BEA7358BFC49F2FF457E245D21 -:1049F0004AEB985F7BF353825ECE0C3DFAF1BC82AA -:104A0000FCC0FC9C2229CE29128DE934F9678A3832 -:104A10009D184767FCCFD4FE998CBF9AF27B2DF985 -:104A200080968AE23E5E0E32FDC0DAFBA28928D271 -:104A30005DA9E479A73F9246FD71C75510F1EB4897 -:104A4000F72860FDB57379DE156CA6F6BDF53CAFB1 -:104A5000846209CC2767F1BCBB329EC6FCAAE93C44 -:104A60007F874167D861E503F813D1BD7734EF69DB -:104A7000C7F2A4C137E06BC7F2559FE37AB6426E26 -:104A80007812F17FC7D063AF2E61FD17233FB0FED0 -:104A90008B97462C74D9AC5BE9B259E7749955CC25 -:104AA0003081749075A2C7ACE3AF776878DEF129E6 -:104AB000EE176B7CFA471EB4F7EEA8994DE55364E8 -:104AC000A7F00F707FF836E10FA862D285FB9F6DCB -:104AD000C21FF0E46DD38AB1DD939B7F48F4FE3CA6 -:104AE0002A11D66E550D3FBF7990ADD3E8C7FF6E42 -:104AF000AB4AFEBA5DACBF18D3DB8FB6AA943ED4E6 -:104B0000AA418CF5FB3DA6C7313FC0CAD36E3A0F10 -:104B10008034FBFED84E47538AF5BBA9959966AC05 -:104B20009F8DAD2AA5B7B66A7F91597FEB5B439401 -:104B3000BFD2B1688593FC1A030B66B2793DF2626D -:104B400035F9F7E63EE868C6F6A00D5C706E5DE6E6 -:104B5000BB819F2B1D8DB720BFFE60A7DC847A062A -:104B6000E4F8B333B2D76BC77AA73E283753BD609A -:104B7000FCE7E704B3D6EBC17A0FEFE270831A7952 -:104B8000B6367B7FFD08EFC9DF77F0FE42919F2F9D -:104B9000CCDEDF3AAC37B84BE6FDF999CACE5E6F92 -:104BA000238E1BF9BE80AF12CA16661FF70EEC4F9C -:104BB0002DE5F6CA9C28905F6CD235FA5D92896F1C -:104BC0006EBF765072303AAB65A938D63B657E4AE7 -:104BD000AA62E97157A72407D3779396B272068F1A -:104BE00007FB61E9EC39BCFC762C0F98CAB13D4B50 -:104BF0003F3D8F95B3F4B865D67263BC495F815170 -:104C0000BF103A5B27C5C0B05F283FCDC1F38F3BD3 -:104C10007FDB80FA699AC2EBFF19F3AC9F492DD66E -:104C2000F6D3BC3CFF5BA37E116FEF90795E6566A7 -:104C30002CEDD336AB29B4BB6E3DBF3B74853F33FF -:104C4000DFE0A264CD15A6F9DDBA6873E88ADACC94 -:104C50007C8217DC5983F95CEB8A477740D4B40E29 -:104C60004D1BA8257BF75F5DBF5C645A37705DA95B -:104C7000C07581E1A782310A9633BC25B8BDCAF15F -:104C8000B6FE2C2BDE4ACFB6E26DFDD956BC952E72 -:104C9000181F6F3F13E3E7C21F1B3F6A1EFFB68B4F -:104CA000ACE34FB8D83AFE6D175BC79F70C9518F00 -:104CB0009F36F3CD8673ACE3979D6B1D7FC3B9D64A -:104CC000F1CBCE3BBAF10DFAF40E7DCBBAAED735AF -:104CD00083997EC9A1DE90655D8FF075DD285F3513 -:104CE000F45808D7770FAEEFE89FA9E1EBFBACD7FC -:104CF000DF0FA1DF7EEDE7F6846298B2BA7B6B33FB -:104D0000EBC6939FBBD1713FEBF7EBD31D74FE3322 -:104D1000F4B94755D4FFAB6A6693BE4F8AF3DCBE45 -:104D2000D6F4FE6B5C997905921E889AFCF7A3F67F -:104D300012FCAE01F93059E310F652797B94D9A2F6 -:104D4000EA74D992EFADE5E5377796B727D0972289 -:104D50000F96E33AE4AB810F6A4D7832FA37C637E3 -:104D6000E0C93D3EDF1767C69F6A1B7FAA657C23AB -:104D7000EF99C1CB13727523C27387D827DF20FF49 -:104D80008EF4CBB1836F467BB4DA0C1FCF67E0E3C0 -:104D90007903BE6FCA331B13D5FF48F84EB5E1EF58 -:104DA000541BFE4EB5E06F853CE788F067AFD76FC8 -:104DB000E3CF6510BD499E807204646FC6654D9C4B -:104DC00007F1FEEA64215F383EFAF2AF55522784BC -:104DD00079F922B6AE5D2E8B7D98A8DF64CB1BF6E9 -:104DE0002B2E4787C98F97DD7E5580EB6DB6AD8B37 -:104DF0006C23BD1E2179CAEC3BB81F43969BA3CD03 -:104E000059F4C146999F0F4B5AA405E194FD0AF944 -:104E10001373D51F9025615F272CE73BC530927631 -:104E2000221C21A0F8243874817EFE8CB170287277 -:104E3000730CC7716A0AA05EEB2CB95837C731ED05 -:104E400030E00945091E45E3F02872249ACD0F7C15 -:104E5000B7CCFD16463F0C42D17E84CE050CF8BA85 -:104E60003CCD2D8BD19E2F51084F9D01EBB9DE6FAC -:104E7000C4BC9E1769A7884BB28F07188D81F14B70 -:104E800013E7901DDA31A75145BED421A2A29FACF1 -:104E9000D39F3D9EC848FBD1EE3C11F95E25FB3304 -:104EA000C9EC52CC7733BB14D34EFF434DB8EEEC74 -:104EB000473ECEE2A719D5731107A44DFB6D5F8D58 -:104EC00017D2E6FDA8D8AF7AF452CB7777A8C2D232 -:104ED000CE3551267BBED3EF48E13E3F1FFCDD02BD -:104EE0007EA35E8F1C57B502F6CBEE9015DE63876E -:104EF0003FDEDEE71AD4B2C1F549E1CDE02B7BFFFE -:104F00004A991227FB596E0E99F9DFE9E27CAA94BF -:104F1000A971B29BD55CE55EDEDECFCAD12EF63735 -:104F2000EB78FEC2449EE2C4549403137E26897635 -:104F30009D2E711E0D713A3792F4780BF2915AC979 -:104F4000E4471ADBCE48BDA27DCF875F7F85E4634F -:104F5000824AF221E923E497B78FF3801C9DE8622F -:104F6000E926397A1CA6AE8F9CB16C7232C1C5E5B8 -:104F7000586D6ED6557E249E15FE9345BF0306FCE4 -:104F80008938F99B0B85BFAA40F84FCEC03FD35557 -:104F90004FF07F1AD35CF0CF10F094416408F7ED26 -:104FA000C8A0D82FC0F9BAD91FBE46F45B26E003CB -:104FB000F81AD1CD28EF157828743EF30A9CCF9AC1 -:104FC000CC7C9AC47CCE1A6F3E5F10F359E3E2EBBF -:104FD00095DAD4AC87185F95E6A0CB12D1FFE651E5 -:104FE000BA7CED88F8EAA202E7B124338FC582AF1C -:104FF000AE186F1E3101CF8013E6BE11443349ACA9 -:1050000037B0C84297AD065FB9F9BA0170BD852EB9 -:10501000B7897E0A9DCFF202E7B335339F6F08BA96 -:10502000AC1C6F3EA6FA6DA27EBB902BB25BB6BAEB -:105030009E6847FBE301B9B9DB559F198FD5EB316A -:10504000D79BD4D567D45B85DFA585A3F5FAC5F8D2 -:10505000C22EBA87F6635D686330FBE6DCAEE71B01 -:10506000D11E67EDD653FFCD7CDD64ED3698FB3F56 -:10507000B96B63BBA8773BD66B3BFD23A3FF4DE623 -:10508000FEB7BAD2061C77121C4DA3FD7DDB5C6F08 -:10509000896BB09D9F13566A6FFA4C764DA834CF3A -:1050A000B90CD7BBAE602C398CFE4A080CA0DDD100 -:1050B0002DC7B70E233F30236F1BFB7E933B2A493E -:1050C0006CFDD4A2F1FBB05E69C2AD39916E8DF179 -:1050D000EF613EE180668C8BBCDDF7CDAD985F2142 -:1050E000AB9A3B82F6964E47436B8232C5C97549EF -:1050F000B104AE8B07E4D82E17D93DAC4B36CE4D5C -:10510000653AC5FB94CC0789DB1D1CAE75BE2F2507 -:10511000110E37830BE383BB6C70B1F1685FDE3B2C -:1051200081C7DB800C3532F6E7F446B0BFA1093702 -:1051300012BCC936B786ED9327DC48F0B2B2668A56 -:10514000CF73C509DE1E97AA613CDEEDBEEB36616A -:10515000FCD68A4431D5273870FE53AB087E0FC485 -:10516000D38BC3A8BE06A2786ED3B550A1B8E464B1 -:10517000703DED6FFB16AAE4DFEFAB599FC076FBE5 -:10518000177A29BECEE31F008C032A5BA000C6C39A -:105190007A82036467969EEDE5F94AA0714A3FCB97 -:1051A000E3655D30AC55B1B42CC9E38EFB6A1625BE -:1051B00016A31D3387C7A34222FA22C6B79580F8EB -:1051C00073560E61FFAE494E704632F42D1B186DBA -:1051D0005F1CCB222FA3F55205D64B1756AF3429AF -:1051E00017566FA0C07AA902EBA5793D379C5F9C4A -:1051F000ED9C7594EFE72B647F18F16D45CCF21FA1 -:10520000B54FC2DC6E37DB2B2E5032F60AF299F323 -:10521000F271E158B1AF2DB8DB64DF04954090F630 -:105220001BA7C2A9249779DA1F684D0477BBF2CF78 -:1052300017252C6DF293E7ABBFAA95FB697395FB1D -:10524000665E1C227D36E332915ECED359EC7B2D17 -:10525000A62D227F99C85FDE12CD325E83C2F57023 -:105260000D348F4B078F80FF4D3CAB674D6A645602 -:105270003F4B9C8E91FA6B1D36BBD1AAEF5439D1AE -:1052800048E71C353C2ED78DC288721301D22F2ED1 -:10529000486B55B8178568D1E28919F9718526924E -:1052A000FCFC77B913A439449F08E2D1CE2776BE1F -:1052B000F0DBF8E268F9E4D263C427BEA4B320F9B6 -:1052C000F10D14582F5560BD7461F5FC49A9B07AF1 -:1052D0000305D64B15582FCDEBAD3A4711FED60539 -:1052E0001DE887F19DAB5AF2ABCEF55ACBCFF35BFD -:1052F000F2FD6759DBFBCFB6B6EF3FDBDADEBF80EE -:10530000B77FB8FBA2D3D1CF53A89CFCEE63CA49A8 -:105310008D3A7EFDD28579E44A4DD07ED223EB9042 -:105320000EE2FAC5D62989D2682A8B7DF75321FF70 -:10533000CFB9B81F272927685FFBAF3ECFEF2ADC24 -:105340006F64CC371FBC86FEFDBD53D85B76FB6B0C -:10535000D4AF73E8F0E153508F00064B83A6B3A996 -:10536000A11F17BC110C15F1540FD0F9B4BDFF5E8D -:1053700023BE0612A14526389E7373BFCA4FC2DDF5 -:10538000213AAF3D616308F7E9BD93A5AC7E968FE6 -:10539000147E2E5815F3919DD1A3ABA40F7B27F358 -:1053A0007B4CBDAE01F21FF786ADED55613F7CA48D -:1053B000F0F17A6F8903DAFF5D276C6CC171DDE96A -:1053C000FF049DC1FD1F93E3A0E3F86EBE0F70477D -:1053D0001380EB82AA27E8FCDD0E4FD2884B868132 -:1053E000D022D3BC2F32E6C5E653C8BC5E57141A90 -:1053F0004F8B72FCE5C257FA08F1B5D4ADF07B6271 -:10540000210FE16BFF3CBE7E20219D8C8EE452D4A7 -:10541000292F99F9CDBE1E037805BF1DA6BC2E5FAE -:105420003A2E3FAD12E7A7BDE88761EBB47EE76592 -:10543000E3F2738F58CFDDF045EAD7ADC7A3A8EFED -:105440007CB569403BDE53ADCD767270A23051F031 -:105450001FC1DD197504291E25B299B1BC6F426FB9 -:10546000242DE51E47AD55AC727384EB5A9DDBBA13 -:10547000AEED877E72C6AE76C0D26CF7018C754DEC -:105480000F5E3AEEFC57D9E6EFA88D0B3FE54A1EBA -:1054900057C5742BDECB84502FD9EB3E89CD3752C4 -:1054A000F83C5F75733DA687C687636D2BF7A3AD88 -:1054B00016F4CB556F353AA031BED7BDAD03F76BAF -:1054C00025F3B97C8CCA833C60E1DB830AF777F46F -:1054D0007AF4368A730973BFC9987E057FDBE52DA0 -:1054E00099E39E8D21CF7F5374AE9FD401F247186C -:1054F00072A7EBFF49FAAF7772BB8AFA21A9AF27EF -:10550000FFF1FE6A05303ECBAE278CB44FE0E134AC -:10551000E857F11E53DF4B4EBA176BAFE7C1CD9A78 -:10552000C9DFE7ABB1EAE57C7A66B39BE3E5E3EA82 -:10553000991F0ABA66D133B42E2FEDE97C0AE9D35C -:105540002BE20C4B9B12B0D834DFB542CFFDBB5BD6 -:10555000AC17951C8E5E97D660A65309FBDE60D60D -:10556000A739E8938BEE976190E0840C1CF6F9ED77 -:10557000107828C5F16BF3E3612C1D381F74BBB3A1 -:10558000F3C127359F2E81AF7C7CBC55CC67ABC067 -:10559000AB31AF7C7262F4FF30E2AB1EEBDBD603C3 -:1055A0003961A1BFD3C05B93AD9E6AAD67E047761A -:1055B000733BC6583FF2F5FF6B85C363EF3F971C03 -:1055C000FE66540E13E4AF35C671C3E3E457D8CF7B -:1055D000F474DF2C80623F48E837706A3CEE291093 -:1055E0006C06F3798F5D7F197A31973EB2EF67F2DF -:1055F000D55782CAB8F69361EF948A7B5FAA881365 -:105600005E2F653FFFF9BBA01B53F405C5FB61F896 -:1056100008E2039A21B58DE244A3436D2C3F31A2E9 -:10562000E87DE81791CF18BA8BE527FCC80D7D11EE -:1056300074C5CC1F1A62FCB62AAA366379851A1E75 -:10564000BD1F39700AFABBB83D06CE95AFE0FDE04C -:105650008997C8807875C35C8ADFDEBF02EF8E8DC4 -:105660008567A20C30A994A5C26F40E78AB8D5BC63 -:10567000D08A4F5868CAB3FDE304D5B6BF2B70DE9D -:10568000767872B5CB0B4F667FFA068EEF86F1D730 -:10569000B5239DDFA8BD5BE0BC686D36D50B1F74DC -:1056A000828EF7DE0F4A941E7FD047E994831E4A0C -:1056B000271F2C039D11ADF26009A5930E4EA2EF9A -:1056C0001507CB292D3F3895D2D0C130A525073FEE -:1056D00045A976703AA5EB841C161F3C99F250330D -:1056E0009BC62F3A388BF281839FA5D47F702E2FD3 -:1056F00017E7ACEB6E8901FAB1155C87987C749D55 -:10570000B184D625FBBC6E55F9BAD22DE2D6BB6D5D -:105710007AFB6151FEA048D709B900390E667F7A3D -:105720004AE57A615D558CECF26E633D2C5F6259FF -:105730000FEDF5BB73DCAF7CCC804BC003358BF237 -:10574000D0879FCBBA8331BA4F001023BD0472CCEF -:10575000A277BB0DF8051E73F727F078C6A3C4C760 -:105760001E85C72D7BBE7067CBBDA877CEBC71E907 -:105770006E267723EED8CD2AF2FB17AE26A6BBE322 -:10578000BA9B43741FF18C8D74EF09CD72BC4FD15D -:1057900073E6CAF8BDC4758C2E33A85D9B6A3A1FA8 -:1057A000ED5D7273CB77587F7AA7037413BF4E59A0 -:1057B000E905DDACBF0E959563FBCA1B4A2DDF2BB7 -:1057C000AEA9B0B4831AEE470F7DA5CA524F9B7F96 -:1057D00092A55ED1BCD9D676E2FCDC5FF7194B3BD3 -:1057E000B7DFC02B3F5F64F4B7AC1F3D52763A7E03 -:1057F0005D758CCB3797AAC22EF21746B75CFD1B9E -:10580000F3CDAB978279E741F6EED7D573E7E3396D -:10581000865B8BD1FD9523AF7F6CE751683DBBBEA6 -:105820002A427D5586FA44A2D48FFAAA0CF58887BD -:1058300052A3DE6AC36E29504E56A3BEF19BF44DAF -:105840003D93FB2CFC50EC195FDFCC14E535225D59 -:105850002DF8CACE37938C72D437B5F9F5CD24DB49 -:10586000B876B8EA3C421FFD93F54DEFEC8DB12FB1 -:10587000B39CE7D43B5BEE6169CFAC1B29CFF485C9 -:10588000DBC3CA7B4E5919BFC7A447E0D0CF395FED -:105890000A7E289E63D51F46FF81884D8F18F2F03F -:1058A00031E55AF270B9CD459FDF1FA55C1BFD7F26 -:1058B000D2722DF5AE3A22B91E5BFFD8CEA3D07AB4 -:1058C0008946489F86FB9269DE5407FAE31C031160 -:1058D0007EDF3346F13CBD3F75D17902AB41FBE23F -:1058E0007A357A0EF24FBDDA7C1EA6D787F5E370C3 -:1058F0009D66F9F36DF90B3C132CF98B6CF94B6C2D -:10590000F52FB5957FD15C9ED4F5E3D08F917CC601 -:1059100045E78649DDD194F53D0581A767D5E62F9A -:1059200063FB1353271D877461F9AF527F1EDE1F7F -:10593000CB5F49E365F257D9CA97D9CAAFB5E597A6 -:10594000DBEA7FCD9CEFFD68EAEDB8DE277EE682DC -:105950006D59FC4BAF083DD273C2CDB1762E97374F -:10596000935C4E5B19BF02882F00E176FA6DFB3F16 -:10597000C667667E7956E89B9F4CBE91F64D3D6C9E -:10598000FF44F18DE8DFCB829FDF78C4FB5CFA55E2 -:10599000742F22597E3DF9397A2ADB297E61BFAE08 -:1059A000D0B96D329CBD7D6F2BF773F454663F5FA9 -:1059B000F88D276C89D7826AEE17443138ECC077AE -:1059C00086B87EEF0A77937E55D25771FF46798C61 -:1059D000FC1BDB3C7CFD52FC71F22BB82BE359F72E -:1059E000F53DA3F8B0FA3B7F22F06AEC234DF82096 -:1059F00039ECF2FC6937FA37929EEC72B6538CEFB1 -:105A00000A1536FED8F9F3F1EFC6CB2E28AFB67DD6 -:105A10006DD2C5E3E71393B91F4066E398FD0AF61C -:105A2000F146E769DB67DF25F83CE9E1F1F7467FFE -:105A30007678EE17F3B9DFA359E6256B7C9C7CFDE5 -:105A4000FF182F71A11F40B3FB21AC7AAE55D4775C -:105A500005ADF572E127318A1F1EA765F06F3E7E06 -:105A600037C67916E1A2F385ECFB70FDD01C8AEBFA -:105A7000D80F81813EDC37CBDA2BE817BE896D93D6 -:105A8000D09FDD2127C8BF90D041E3EFECF07389B0 -:105A90009B9C274550DFA922DE0230DE22688A5710 -:105AA000147ECEDB7DDFBC0FCB5724DC1ABE7BF22D -:105AB00077CF543E9F432B28CEA297EDD471DC03C1 -:105AC0009E29297C4FC759DC4FF6BCD3392B9E2D1C -:105AD000FED4EDE5727CDAA1B5A467BB997EC3F371 -:105AE000A56E39A696D6A2EB3A41F2DAAB8F1FD754 -:105AF000688F8F7469F6B8442BBE225E4EDFA458BF -:105B00007F939E488B252ED0EBA1F2BF7BACF0F5A6 -:105B1000E8FCBE900E718A334D563A1C88B7630577 -:105B20009F31AE12E6F78F8210A338163524D3B812 -:105B30000E1FC76FAE714197DF31BF2B73ACF039C9 -:105B4000BAFEC6383FC9E0257ED2E7AB8DDB31FF18 -:105B50005327ADA7F6717EEF8D7DC66BD29BB21633 -:105B6000033A8717FD9D3581C77FCB95FC7EBA022E -:105B7000CD4D6136FF8E4AFEFEA2ECCF132F516948 -:105B8000F757E43AAFE3E72554C444B4E10F7C5C33 -:105B9000AF882308C030059116A34A9F8A7104BAC2 -:105BA000C4EFF747241E6F3E8FE2CB839E4FBADFD0 -:105BB000CBA95F29BA0E0EFB8EA05F7998FC5C9F83 -:105BC00078BF79E0F5C09DD42F86AC1E2ECBF48B28 -:105BD000FA979C4A870E1FC6F334714605861D2E20 -:105BE0003BF87D2BA828A278C4AEE0F5AA99AE9D1B -:105BF000DE2ACBFAAA68DD5FC3779494CA6BA2C38E -:105C0000E3F06552C89152F995E870017E4C994DC8 -:105C10003F9B3FB45B89A5DAD05E9CE2E771AC7232 -:105C20009CCE477AA4D2D97D7526FEAD54D2089772 -:105C30003F124D609C634F992382F15932F4EFA5D6 -:105C400077D39C0B23E3C9AB5C29BF6D9ECFB7BD57 -:105C50008120C129FC871D79F8BD4BE8EB5CE52E5E -:105C60002512CBA68707BD621DF3662F3FE06B7C34 -:105C7000D09B65DD490BFCF6943055FA69CE3EC8E1 -:105C80000772E59E57100F5D13CE1C5F3F6956FDEE -:105C9000F4BA2FFA43EFF870FCD85B9F857EFE6064 -:105CA00061FB038803DEA775BEE414E7BBD122695C -:105CB000229EDA1A7F11E864E5AE396E0DFDC9DE69 -:105CC000DA08DCCBF2A1D3D566790EBD1B47E7AC71 -:105CD000AE7227505C9E731E8F1BAAE17ED628FBF6 -:105CE0008FE2CBE68D1F4FE6B4E57F65A773EB2E01 -:105CF0007A3FC280DF885FB7CFEB07BEC6E1ECF822 -:105D0000286C1FB481F10BB8F15D3195D2B5AD1A95 -:105D1000A5AB5B4394AE6A65CC4EEB7F0DE56FC3DC -:105D2000A673312E249E0CE37E2474EF2B78257409 -:105D300003E296EE19DD7306DA597D98E7F7421310 -:105D400012E627F3F2437D1BCEC0FD609FC7A89FDC -:105D5000E4F547F37774A15DD827E26BCB56DD7B82 -:105D600006DAAD1B261BFEAFA87A91C9FEAAF1B9CF -:105D7000B89F266CB4EFEAC27DAC4736F28F9E61C5 -:105D8000CD4314E1F1A83C7F8EEF07040FA9003644 -:105D9000DE45BE5D94DF7082D8975FB8280F1EB9CC -:105DA0001FA3D7AB733BE842FEEE8AC2F8A68A7DFA -:105DB000DA20DECD2DB41FDCFFD07AF752F6F532B3 -:105DC000233779D6B50B0B7BFF85A183EC0BD4C3AE -:105DD000F8FEA2FC0B2E17C77ADC0DAE23C38B3A5C -:105DE0002F16C5EE8B9A06D348EA9F78630D3ED6F0 -:105DF0004FF1FCBDB4AC28A134B71B0A1CBFD2279D -:105E0000EE9BB179E3BA63E0DBB03F6E407A4EC8F7 -:105E1000F4E70A46E9DCCD23DE1B2E14EEABBC9A78 -:105E2000A51F786076F978E76DC1850E0C421AD50A -:105E30001BA5F3BD96BC36AF540475F07C515D854F -:105E400025EFAFADB2E45DDA4996F61F975E5FF2DB -:105E50006A16FEBEC036AF26FB3C0BECD7B3C2A918 -:105E6000BFC1EC84B06CD8A5EBE9DEF27EC431EAA8 -:105E7000C98159748F17AA8D7B0A40712C1E3D4A27 -:105E80007CEA65FA9AECE34AABBD2A07ADF66AA84C -:105E9000259136FAC5F86DCF0A85C61D5DAFFC9019 -:105EA000F6E0DD73A19769DF3E1555DE379E09F3F5 -:105EB0007611F3FD7C7B2A8B7333BA9B1FCE7FAEAA -:105EC0006A1F2774E1F8716CF6FAE097F5374D72A6 -:105ED00098BB9D0C6F9ADEDDD886B49F90C17F740D -:105EE000FB62F27FB881D9D30CCF1DA18B21C6E60E -:105EF000D98D5518FD9298323EEF0ECDD6284E5FC3 -:105F0000E77475A85C4E6EF2E916BBCCE9E77262E5 -:105F1000D4CB47FF9B9C10CFB6AEBDEAE3FBE503B5 -:105F2000DF8CFF09F799891741C7F3DFC1D683F4E6 -:105F30000E665DFA2C27FA4FF6F92652BDBADD51EE -:105F4000E7E9A67EEA80BF07CEFE9C66BFAAE127EE -:105F500086432AC50DEF4CF3B8E19DE93F3F751824 -:105F6000F3CF38E8DDD19D7BC7B7B306859D65D4F7 -:105F70001B7C86EF5B0765F0958E67EF88FB71B33E -:105F8000D2B6B844199C48FF03B7E84EB47B065B11 -:105F90005509D7FFD9629E75E9A813D7B17CF3DA0A -:105FA00063A3AF314FBC9F88F3ECF4F3FB829D1ADF -:105FB0009B2FF1357F4F3B17BCA3FB7F2D3B3E94BE -:105FC000007FB74371C5B46CF3CE778FF168E1EB16 -:105FD000B2C1D7EDE7FB73C37F900F1E25E8B0E891 -:105FE000096F9D26E182128081A6696142E38BB828 -:105FF0001F2255C1583DB06FAEB404E3C617FBA3D2 -:106000005208F39F95A63038B50A27DBE3307BA909 -:10601000F6C5F4AF713E2D3EBA97D151FB01C517BD -:10602000947C556EC375AA173B27BBA8BABB81C128 -:10603000D781FF642ABCBCBFFC4CB43B64E07A80CF -:1060400049982E4F44BB11F031979CFA80FD498747 -:10605000DD9976B9F064B73FDDB0687CFD24CEF9F8 -:1060600013EC3FD42F25B6F6C551AB7D1BB0DDA791 -:10607000380DF5777D01F7328E721C0DD6AB187A8C -:10608000E0AA766829AC0F5A09DE07F2CE9701E341 -:106090001BB5E048C2A1E7C77B275BC2B85CA52C53 -:1060A000E73017FAB9FF2774451DC5E1EC8F302E94 -:1060B0009885F957B2EEE3ECF72D56D5DE4D7AB25E -:1060C00083F113C69B246A1DB47FECAD7E4833CBAD -:1060D000D3D7C53819FA832E1BFB64BCBF5AED8891 -:1060E0007A667E7CFADBF71BF9E8EF5B688DFB399B -:1060F00052BAB4FA41C4B18C4FFFA31DC7A0DB58FC -:10610000F9681374FB0AE993EED091DD935955BBFE -:106110009EE8E6ADCE1EEFDEE997AC7A56A42ADB08 -:106120005F464CFB4BE771A7B4DC05E3D0654C7CC4 -:1061300015EFC7E9E77EB4D592378243ADCEE1577C -:106140009E1630E018E6717C73F784F0DCB8BFFE71 -:10615000CD109E6FACF930FBF9E382008F0FD7A30F -:10616000AF92FDBFA69EFB03F10FF5CE4DFC9F50F5 -:1061700095786B13BE6BB67A9FCF62FF18EB42AE79 -:106180007929154BE9BDC403AF49F4BEBA54B1E255 -:1061900044846B68EE127A87A4BBEE493A7FE98F9C -:1061A0008C4F1723BEB45BDC571F1D3FC779E1DF5F -:1061B000045DAA12CBC89E5C53FE228DB3BA6EFC5E -:1061C000719236FADB53D50131F213DBCE73F70946 -:1061D000B9DDE717E712AEE6F3A686318E2A4EFE4A -:1061E000B10935D121D4FB170662AFF859F99AB934 -:1061F0004BCA691FA15BD7C15B73CC2714E0FD1AA2 -:1062000076D281AAF8FFB9A50E7FAF62DAAC848995 -:106210001EFD39E2DA6B03C6B99787F639DD780FD0 -:1062200080C1D75F5E18FE0D3A9F06CFA9F8CE7ADF -:10623000778EF85E23B5AFEFF9F06EC7C31AD7308B -:10624000C53FAD91B2CF674180E37BCD2D697E9E86 -:1062500036F74D3A4FF3A75FA5B889FFA8DF4BE7A4 -:10626000697A809FFF04FCC3144F5A3487BF0F988C -:106270004B8E527E5E5FD6ACF5401EB69E0FF98DFA -:10628000F39EF1FB33E00475989FF38C954B5A7F96 -:10629000EEEBDFB687DE5181349D2774FFC2496F74 -:1062A000C11A7818235749FE3B316B241EB7BC2016 -:1062B000D0DA8DFE9135C6F9DA2CBE4F92EBD2744E -:1062C000BEE60DE8167BC71F31DE492C6C9E45B833 -:1062D00016D573B580EB2AFAE111BECE5917933F5C -:1062E00037175D6FF2C5EA03F5667F3EDF67FDABEA -:1062F000F1E1DFFCBA252EDDCE8F6EF8B723DAC7C9 -:10630000E5F22B1F10F269BCA36BB45F1C50B2E323 -:10631000F7D797E4C3EFE2C0846CF83DCB4BFB8822 -:1063200075E39FEF6CB2E9EF4D469C8D78D797F5FA -:10633000577E7E167BC258570F048CF77C9ABD3867 -:106340004E55A2D68B78DA965C44F96DB78E4F4FD6 -:1063500063FC2D42AF6F15EF9018E55B055FA66CEF -:10636000FAF66521D75B857C6D53A35E8C5F82A7AF -:10637000CEF24E67F80B33BE4057E2F15D2325E3C2 -:106380008DAFAFB4DAFD477ABF652060F5D7167AD6 -:106390006FF368F1921271352F07D224F7CE743162 -:1063A000C9537829903C85632369DC37550D3852F1 -:1063B0003AC5AF347BA733928696CA3AC5B2897B79 -:1063C000B0278AF51D9C2B1DB87F09897BE48C853D -:1063D0002FA338983BADBF07B24D8D342A78AEDC81 -:1063E00049118E104E9A7EAF8240B2FE1E4868DF81 -:1063F0005BF47B2A2130D50B1F3DDEFF2BF0F1EE45 -:10640000CB1E353FCA231EB33E3E5E82E66C7AFF4A -:1064100017C21E3BFE969D12C9E5357E78DDE4A7C6 -:106420004949232588DF2D2BDB25C467A2132227AA -:1064300064D1636F047C865ED88DEF2EB82A397DD7 -:10644000BBFEEDE2E12798CADAB2A211B2ED3F98A5 -:106450005E782340EB13D70B5B572EE2E92127F13F -:1064600049751252F83B2AF307626D2EA4FB52FEC7 -:106470002E75A8333E84F9F03510D159FF55E8D474 -:1064800067E356B7402A4A7C042F8726E2EFDDF007 -:10649000BFC9C38B87BECDEAEF99E3D6F07755E04D -:1064A000062BBF545C63FD7D95EA4E2BBF4CB4F1C7 -:1064B0008BBD7D581F390BE19D9A7400EEEB82175E -:1064C000DAFA83E11DF7E17C76FB2369066F75BF7D -:1064D000B5DCDEBF0C317711A3CB23371FEAAD61EA -:1064E000F5EF4E3696215EB6A9C0EF5B342B74BF34 -:1064F00035D73BC463F8D6B0FB0B7CB7D858F77AD6 -:10650000F649FCDD8B29DA6B61F46BBECC7FC72EBC -:10651000F38EC567E81D8BE320C6ED478852DA2964 -:10652000EC53EDF4CA30FA3F93BFF669782F4B2B4A -:10653000B3FACFE4D2267A1F6CD4EE2E6576372BD1 -:106540004F9658EDCBD38B389FCE2EE2F6A1E6E3E3 -:10655000FD801A2F37BFABB4B148B296FBE3E51705 -:1065600098CAE71789F767C5BBE30D450B7A502F2B -:10657000699358FD2CFC79A618D7288760642FBE34 -:106580000772FBA58BEACDFB8B8D45FC5C473B5E20 -:106590008C5B991DAE64988F7B9B18776391F10E8D -:1065A0005C9CBF03A7F1D4F87E5B6089F406FB7C9A -:1065B000C0058D18A7D231C141EF43DE34D1880721 -:1065C0001B5F4F187418C5B7C6E3902A96F27B97E5 -:1065D000B9DA6D6EE2FE41FBF7989847E7D2C681C3 -:1065E0006A36FFE86E203E710721EBF90F93EF58F2 -:1065F0005136BBAAB389F671074AB2FF4EA1917614 -:10660000D8D67D59F813C7D41374D25F0A118B778B -:1066100086B87FEE4089234AF7026B81DE3B3B5010 -:10662000CEFD75F6F6BDB6713CB0288AEB349EB34C -:10663000623CA3520D293CC8F10607B4B08EF101AB -:106640007BC94FA303C3272BEF8E00D9779D216E03 -:10665000C7C8A1810607AE1FD0A499EDB10AF17B8E -:106660008B1E7FACA3C812479220FD7BC095223DB4 -:10667000D21176C0DD59FC886B8AB89DBB595FF496 -:106680007C380BFD3614E916FBB9E220B7BF73D591 -:10669000CFD4E3708DF263284EE73EA0737EBC300A -:1066A00010BDBD689C382EC3EF78C51CA17041BFDA -:1066B000E47FD83CAE7AC64531E9A71DDABAE7DBFC -:1066C0000C4F4E714ECD56E53D4FB0F2AFE0BD27B9 -:1066D00096BF6ADF0C650A2B7FB9C2898B30FB6BD2 -:1066E0002EC271DF054713CAD3BBF062D1C926BAE7 -:1066F0003D5224ECD0A48BF4A6E18FFBEA80CBA220 -:1067000057AFDC64CD2F814513D14FB1E45617D973 -:106710002657D9D6FB6D62FE5742BC1BD7CF2E1130 -:106720003F7EED0F66282837579DAC859DA6FB560A -:106730004F087ABCCDF84737C9D9D5FE9482FBB84B -:10674000D7779E7CF16701FB497557E0FA59923D76 -:10675000FEEFCB492B9CF9E66187DB38BFCB058781 -:10676000BC5D8AA6B2C8D9B34556BF5087CADF47B9 -:106770008A76C8E0F93CC6DF01C94F625F80DEF36C -:106780004E34C6299E2ED1EED63A82145F477174DC -:106790002B18C1F03DA23F08FE33E2E900E2A7E278 -:1067A0003EED5A7558417FF47239DE843FA5669CF0 -:1067B000C3B85DB1E82406BF6B57437A1258EA2587 -:1067C0000BACF78C545550BD26C738FDBD27F4E4FB -:1067D000D30FDCA3E0FAF3EEFDAF9D8B72B8EC7142 -:1067E00027E095BCF71E08409AF60F2905E5FBEA5D -:1067F0009DCEAC7E36F2D4323C2EFB5E80F4E2D5E8 -:106800000FB9530B59FBAB1F7D7D2630797AAF7DD5 -:1068100064CF24C4DFFD123F1F4C0CCFC4F5E96ADE -:1068200019FE3DDB3B64BE62CE5FEF3CE66B41FA96 -:1068300049DB87BE44FD0E5EE232BFC7EE28E6EBC1 -:106840000FABC7E3257748A913B2E80F633FF4CE37 -:106850000E89C3B7CB95C250E0ABB7DFA5C4181CF7 -:10686000CBB7BF4FFC72FAF71E2C423C2CDFE5B4CD -:10687000EC2F977DEFC3EECF303A2F73C2C842940E -:1068800063E721CAEF8FAA234E926B1E9F721DA948 -:106890000056EFE1DF9FF93FACFCED901330B4F50B -:1068A000EDBDBF531EC77CCC1FC75F1459BECBCAFA -:1068B000D7CBB7BFAE205C9A03462A3F8BE79C56E6 -:1068C0003BC95E1F6044413DB57CB0F77D27E3B70F -:1068D000E53BDFFD15F2DD729B7CBC8DFF281F6B55 -:1068E0009F9F5C6CB3CFB797151487B2ECC1FD5B6B -:1068F000D01FF1CE437FDC82F767AFF9E82F5BBE94 -:1069000081F1603FF66828DFCBEFFF451198F4FE78 -:1069100039C55CCEDEDB71DF7736B3F9BFF7AA9BF2 -:10692000B0F5DE13BF9F82FE9FF7BEFFB789E80F69 -:10693000BAE189338E43FEBAE111FE7B36B9E040FD -:106940007E4D997F6F519C13E9BBC81803F891489D -:106950006DF480811105D7B3BF4A30D257C2BE0F44 -:106960007EA8A07DB6270A23889FA776BEBEE766CD -:10697000967F97D1C79D853E6CFE931CA49F99D8A6 -:10698000B0F4BA9D179CF7B93A4C5D11EC7E398C86 -:1069900090DE1C43D797185DEB3274B597EF8743B1 -:1069A0000A9E1B2C7F80D17126D293D171E6583A72 -:1069B000BE8BFF983B968ED714DBDF6FB866EB6615 -:1069C0002CDC5996D5DE35F659D73E72D1B8F69300 -:1069D000A117F2E179A9F093CC298EAE2C46397C2F -:1069E000E8BBDFD91CE4745EC810F3DE83FBA7E0CC -:1069F000A31C7F708D7C09F130F2845BC3F5FDEA46 -:106A0000277E49F2F6DE232F283AC5B54091740A55 -:106A1000CBC3E8DF8BC0F2D7493C73EDBD7F3FF3BA -:106A200057ACFDB5F853AA1AD18FF27B98FC113DF3 -:106A300052E737E9A877531368DED7A5B85C5C97AF -:106A40001ABA10E3F9EC787F44E817335DF17DA9B9 -:106A5000EB76BE7626F25F2E7A1AF3D770FEA7B2D7 -:106A6000F27BAD729B534E057DDFBBEB8082F6411E -:106A7000FA714573307BF83DD78842EBE3F79DDA36 -:106A8000B6C858BA67F02FE28E8E701F3E586CF36E -:106A90007F08FCE493F3FCF33A32BC6D29D62DFC5D -:106AA00063E0EF9D43D9F5FFB3C5DCDEBE0EE24DDA -:106AB0001553C7AE5F323427268533F0BE8371632A -:106AC0000CDE77EE77D23B7DDD834F911EB7EB8BEB -:106AD000EB72D8D1FB8CF1760DCD44BDF6CE938F01 -:106AE000115F5EF7C06B0AEE57F66C7F5819AECD9A -:106AF000C801AE0FE6DF297BE77F0DCD44FDB53C35 -:106B000047FCDF5BA2FFE53FB2F6BFFC81F72DFD3E -:106B10002F4B0C2AF43BAF79C6795B8E5E82F37DF6 -:106B20007BAF0B703FFCF6A0B3299B9DF3DF627D2A -:106B300034F0D41D38E595623CF72AE5EF3276B69D -:106B4000457F89BF379C78C125F6B7D157D09EE9DC -:106B50002851E81E4267E062F2D71BFD0DD8F0A96C -:106B600005B506DC0768F39BEBCCFB2A03FE92A875 -:106B7000C302FFFF03C228CF4D00800000000000C9 -:106B80001F8B080000000000000BD57C0B7C54D547 -:106B9000B5F73A73CE3C42269393D7E4693C4978E3 -:106BA0004AC02109101ED58120A6986A50AA5CEB24 -:106BB000D50121444832292A5AEB779990885EF012 -:106BC000B3B1D28296B60317AA95C40E1034B6811B -:106BD0000E606950B4019F7851A3D68A15C8180574 -:106BE0006DAFD6BBD6DAE730332783D0EFFEBEEFEA -:106BF000F7FBC2CFDF769FB3CF3E7BAFF55FCFBD54 -:106C0000CEDC91529DAD3901DA560268A30040F105 -:106C1000E4D4A600C8AED9D59089AD6A519324803A -:106C2000AFE9EFF2680B100498086075D6820F9FE9 -:106C3000B7AA16D01CC07F5F03CFD3DE8FCFDF256E -:106C4000A7B4AFA179ACCDBFA43EB428B0B58287BC -:106C50008D562AE8FE259E354500EB93FFED71BA6F -:106C60007F77C0AEDAB16D4D59F11BEAFF4A825A07 -:106C700019C7B5D2F3D806AC0E75AB8AD7D3607EF0 -:106C8000C8195D4FBE2AF17AC6E33AA8C53F1F4C2A -:106C9000C2F78A25412B34008E80A4CC60805AE351 -:106CA000B97F577D25EAC4685F76F681AF14E00AA4 -:106CB000D969A1FDDF9F6309DA8BA8BD36154A8724 -:106CC000D2C168EF5B590BE151E7BEDF9EE558B0DA -:106CD0000978DD010BCE1B901CC1ADB4102F68AA42 -:106CE0001B786DA0E17F484347CCBA718097F6A12D -:106CF000E8F7ADB82DBA698700B749C4076C93218E -:106D00000C500270A55A0C90059002FDFA2411A8AF -:106D10001D07302FC5E7A57D660FF749342E0BBC44 -:106D2000DC5640AD44F72DC937E5FABE617F304FE0 -:106D300039D13F5AE72FBEE25756417F450165588A -:106D400019AD63A3FA97B1380FDDCFA051015EC72B -:106D500084AAEBC7B6111C68F131747E78D6CC0CCE -:106D6000C28D31AED551785442BA78E52435A91098 -:106D7000FB0A5286F87D2C85E9F4A3E93833DEFF5F -:106D8000F1B194CD32F2E36149E0294078225C41CF -:106D9000F3E3840F17E2670D3D37B3F9378C170B18 -:106DA000D4B656E8947413FDC41FE28DF174B7E2B3 -:106DB00050ED1EA2AD5753681E1B04D748B45E1F8A -:106DC000D3D301EDDC0E8310B74EE8E37605D1791D -:106DD00022F1C1C3FD54E86F1F8ECFD5A8B50D2A8F -:106DE000EEE7C7D5E912EDCF09AA4EDF825C9FF32B -:106DF0001BE83B0BE9EB88D2D74EF44C1E4A4F07F9 -:106E0000A84C87340F78D64CE079218CFB78780633 -:106E1000046506910A2AE2255BDF6786CE67C20F0A -:106E2000ED2F6BBED89FF97D39D0CEE3F220C46D33 -:106E300001F4719BEE502585D7734CE7EF7BF0751D -:106E400072743D466B2704E3FCA70B70FE22A6B6C6 -:106E50004B72D3FE8DBF5AC6E11F2AF679AB709CE8 -:106E6000E2737AEDB895FF5D31934008D68B15201B -:106E7000BE3AFB17D4800B877B6C101E4DB307788E -:106E80007D49A345DFD02F766454D8583F3E673DF7 -:106E9000F6D1317ACE0A31E3681DF24DA944F78765 -:106EA000E8C294A174BFFB584BE67331F36E5153A3 -:106EB00032699F3019267F2D479F87CA7480DCA1D5 -:106EC000CF7FBE3290F99C354A8736C7BF312EBD81 -:106ED00008E0A4CBB04F38CE8CE21871C97A2EB03E -:106EE000CAAEB666320E19A7772381ECD87E9E54BF -:106EF00018E4FD43F3E46B510F5B1C5E49C2EB0DDC -:106F0000AA2B48F469748666B39E30E98D19F3D4D0 -:106F1000701E8E1B68060FD175FDCE6B8E135D073C -:106F2000DCA0D9D3042EBC93484F187A043419F945 -:106F3000BB5A9AE090B06DECFAE4A5DFE1F8A41E2C -:106F40001964BC3F807BEEA37D2BDE346262323C51 -:106F50001827DFAD0E213FC63ECDF2FACFEE133932 -:106F6000CFF3331F64D2BF0FFE3B3D3F0829ED3402 -:106F70007E8382AFA6F97BADC1AD4887E50765C6C4 -:106F8000DBF24E2908C467454BA5FE5D2FC820F0F3 -:106F9000077CFFAE5F96301E6518FBA3E9F8BC7F47 -:106FA000A3D5831A13D2BCF1F62AA37A1868313814 -:106FB0008080F7480ED26B914EAFF5C90F6DA2F5E8 -:106FC0006C6811F629AB363D6EFCE74957DBEA7079 -:106FD0007E2D17D7359570D3337235F697E5CBAA4A -:106FE0008C2A227B7E5EBC7D6CB7BE47F2A7E13F58 -:106FF000C2B7A1BFEA487F911E92EF65FB771AE9FD -:107000002593BC80B07F4DA8AFC238DF920DE279E6 -:1070100063BEFA9E8757E7637B5B30FEFA3250A26D -:107020007DB6B3AED1A407EE86611EBB3414FF4A11 -:107030001AE29F40E204A7E083D343FA65F015D932 -:107040006317A4607925BA931E91FB47AD9F8EF319 -:10705000F97BAD10D4885FE2FEE0463918288ACA71 -:10706000C760EF4EA6C7925CA407E2D39E134FFF02 -:10707000242D9EFEC9A3D3BF911F291E133DE51ADF -:10708000A63FD21B68FED4CAE2F8E7757A8FC67FA6 -:1070900082DE5E5E675DB7048F4944E7070FE46BED -:1070A00043E9DAD4FDB08DE4FF7C7435D3715C9A8A -:1070B000AE47743A9E869EBD3A2A6B1D6E5625BC1D -:1070C0000F456D9F41382D40B9259C98E5DAA09F6A -:1070D0003553F5DA70DC45340EF797E7080961F4AB -:1070E00080F232E165A1D0BBADAA97ED91A16F937B -:1070F000CFEAEDF7E16B6C33E7563C4038BA5D4AB6 -:107100006967BFCA24B76BC7AD60FD55B00AF531DA -:10711000DBD5783F2DB4D2E15984EB796A25781616 -:107120008D00D8B152E5D6ECBF19F2BE11FD37BBC8 -:10713000B0CF3CAF82F85DA392FEF1A8B4CE876CCD -:10714000C0723A500AC1CDF8FE50F83337F9A30F98 -:107150009545AEAE457FC4BF186A43D86E4DB7B0F3 -:107160007E7D365DF877D5E9366ED7D45AC08BEF81 -:1071700039D52307255CDF29D57BF072D23B3D56FC -:107180008DFD2B35F2D2F7F87EB9BA06E9996B6915 -:107190009F40EFC5F1D5419C77A0E77DD7AD317613 -:1071A000F954F72363C80F7AD402F5A104FE5063A3 -:1071B0009A78FFA9D1EFB971DBD0E888D800F174D3 -:1071C0007F7F732DF95B77256B7CDFD635239CCFD2 -:1071D000F899CBFEF17375C3186FBB4E4090E46E07 -:1071E000B67CD355E3B03FE555C56367A1F25EBDFC -:1071F00060120F61BEAFFBB27C03D1CF8FF45CC5D0 -:1072000017DB5F267E3DFB670548EE2A9A9F7EDFEF -:1072100087FB3C908368A80498E40D958771D4ACF3 -:107220009EB41924DFFE63C0F23AB14F89C32DC862 -:107230000DFBF349AFBC21DCC3C96F98EE43402678 -:10724000FF7F4A7FFCF569E7C1FB5A03EF2E7013FD -:10725000DE1F5BD90DEF935DD4ED671E6E30113DDF -:107260000D7C3F933CF39134F6274026DC7A94C49E -:10727000E3FF9C2E310ED67D294B84CB81087856B6 -:1072800021BD0616E5F1BE073E23870CDB2FE5EA9C -:1072900050027FEB89341B3FFFA84DE0FED13A67D7 -:1072A000B005F7B3AF6EE9C5FDF8BE333FF05DAC96 -:1072B0007E931F8CAAC552C9FC4A25BADF3EB74D42 -:1072C000623984F65CA29B79BC212786DC18F29295 -:1072D0005B37CC174CF09ED1FAFE66D68D966C8447 -:1072E000DB3D12101F4FADC2757D83FF188055F92D -:1072F000B41E7FF7A736B2D78E1EC91B4C30BE37DF -:10730000CD25F0BB2AD0320DE9B562213E4B72612A -:107310006B2F4A347F00D6E5A37308BF49D3785D4D -:10732000A71C700BC92528EDB964B74F75577D9B15 -:10733000F4FA632887E4373C6AF5F0BA038D28B382 -:107340004416723CB15F70356C5A1313471E499B4B -:10735000F1761AAEE3ED3495E7CDF079245AB7E72C -:10736000ABCF5D34FFC01776E65F1EC9708CDF7649 -:10737000264DD0E78174EF1B8C97FA4C56A61E9FC2 -:10738000CBB3A81CE0D26EA4770C2EA37C0BF073B9 -:10739000E9BE00AF27BD0F03278EBFBC1AF9CB7E15 -:1073A0005D394358026552543F57380AC2F9227E6C -:1073B0000865237DD3EB7FCCFA3A09F530B9E2D0EA -:1073C000171F17B146C6E749F6492FB4AAC2CF6ABC -:1073D0004B137AAEED6125D88AEFDDA8F4278DC076 -:1073E000B6C8ABCD5434D2F7A53C6FCE1DC0F26DFC -:1073F000710425D243C9253F4F3BEB774D03D8FE9F -:1074000095CCF437F3695CBA4117DF574497F1BD67 -:10741000917DE4BE79922083F83A5B76F2BEA79C18 -:1074200014FAC7AC6FE4F02F1F257D33A0C74F09B6 -:10743000F4CDAD645F0D7D0372E97EC2CFB417F465 -:107440003053D733187D301D261FF2B53A13E89715 -:107450004AA84D45129F57BF98F988CEFED97E01A4 -:1074600012A3BC17E528E679B33EBA283D5E1F9DFE -:1074700086E9D9576851BC94DDEDD96F8FC187A1DA -:1074800087A27809B29C98DF2381E36C5F2D21FDF0 -:1074900071484E25BD3303F98EF33FAFCB49DA6710 -:1074A000C16F13FFD7F55C9944B8DED15BE520B11D -:1074B000599E236B7F46FF59D93B2F003A5C48DF2A -:1074C00019EFB58243738E267A58980EB28AFD98CA -:1074D000F70FB64BD5A4179169A9F3C69D5B1F2C76 -:1074E000CFB1F17B76F416A7128E9C80F12DF2AF0E -:1074F000A247623FC18C6B338E5BF105168E1B6B0E -:10750000D99F90A5909E77888F4B8B0253D84EDDE4 -:10751000817138F9AD83BD68B7B0DD81769EFC948A -:1075200056E76CDEB7B15F637D77A4CCCC86D2A181 -:10753000FB375AFF1732043362FA4AC44638F67FE3 -:10754000618BBB6ED0F35C7430E83995E829FD9F00 -:10755000D3F35BE91AE3C14CD7FFE9FE0B96574220 -:10756000A2BCC0FF2FFB9F06BEDFF58B78EBB51CDE -:1075700077549F142CAF9697201D26913FEE89EAF1 -:107580000707FE237C8DEF6E677D5389FA86FCCC5E -:10759000FC8610EB97C939225E32EB8D4B7BE03ACB -:1075A000D28F53C2E8975E80FEF88CFE2797F3389F -:1075B000C174CA43FD71FEB20EBC345E838C1A7C6A -:1075C000CFF83EC543760FFA3212E605CC76C3F00B -:1075D0004B0D7FD43CCEF0470D7BD2A4D3E170BAE3 -:1075E0002F44EF07550D90BCA15C851EF330EC35A0 -:1075F000F2178EA4D5EEE4FBA343018E038A41A5C6 -:10760000BC0ECA2BFB61150E67581E3F543E934DAE -:10761000721842BA509E20E0B404474843D781EE26 -:107620007680FC3E7C80DF5F9F2EF2A50538869930 -:10763000D604ECFF178C071FD9DD82326C719F7F57 -:10764000D2ED4A9F3EDE6871DD07D329FFAB40C013 -:107650005EF6CFAF9796985F46F4F1FE91E67154CF -:107660007B79FDF92A78C88FCF57429207DF9FDEDA -:10767000A049679348869DC6F9F26B34B697F9C363 -:10768000B14FE3C9DF49C097F7D2ADBCDE4647FF33 -:10769000011BD2C15FD35CEDB244FD74BBD5E7CD15 -:1076A000A7FC51B7F0D781F27D9C3FF648B41F6527 -:1076B000A6A08F5F15F1951354D69B153A1F2B1C6E -:1076C000359CDF219B689F3274DF92E6E5C179F338 -:1076D000400B4C89EA5523FEC16980DE63D6AB03BB -:1076E000BB5FBF2880F2F8D6FFFA3405F0FE3B4AB4 -:1076F0002485E871FCDE9753BC488FB7EE15F1CBBB -:10770000CD26FFC89621F8539751FB15D1F59695D4 -:107710005F4D8AD52F707716CBC56D419982E1B345 -:10772000F2B3EC8964CE3D1BFDC650465CDF90830E -:10773000463B3427F2AB2FCB10F1D96D1D9B6C1457 -:1077400047D765F85233F0FDC775FFEF78570AE762 -:10775000038CF52CEC9860237ABFD36387302BC859 -:107760003EABE0B3F76A691225EFC59F799D07F636 -:10777000E4DB2C38DF62092222AF05077E86FD0F8D -:10778000726458E319BA8FC56FA936CAB72F9E0124 -:107790009100CAD5C23BA4D577E1F8853E27797020 -:1077A00043F6B920101FE72FD1FD955B1FB09AE279 -:1077B000A4E603942F5B84F3503CBBB83DFEFE600F -:1077C000EFED077E4676A0DBC67660C979E2A7F2C8 -:1077D0000C3DEF3209267F5D42FE4AE98F4AB573C0 -:1077E000EB25C35F39BE12083CF0D7950E6E4FAC47 -:1077F00054B9FD4AD7D7CBBAF71E605C2B7D93C82E -:10780000CEEEE87D3FF9462D6A372EDBF4E9FE9F88 -:1078100061BF9CF65944FA326C253C5EAEDB8D2587 -:10782000BA1F52FE85D96EECFDC3EF28CEC6FD6FA0 -:10783000E588EBC2FC919B40F92C960E861D31D356 -:1078400063B0B724997072BD41173D1FFB3FA5CBB4 -:10785000B99E6B9411D709F487214F5FE979874569 -:107860005BE6AECEC3F7B7EEFEB0B05FE8A5D7C01B -:107870001DC52B2A7AC6DB1280C81AC4A7AFE7073A -:1078800007884E07086F95D4BF88EFE754217E51D3 -:107890006E97F47CF4268C67F9CAB1E4501BCEA134 -:1078A000F8D28C4333FECC783B65ED2F24FD60C6C7 -:1078B000D92909E627DA577D8638BF58A479675356 -:1078C000BC8B666DB5CAFB11FAEFB8D27EE0872497 -:1078D000B75B248E0F1B9FE97C9AF4D1D2DFFCC4E6 -:1078E00045FAE823A5DD4DEF6BD87A9FCB4B7A495B -:1078F00009B8E8F98F82422F99DFB747A7A3712E05 -:1079000070D62E3D10597D0FD2E30CCA33C96F5388 -:10791000D7DF56DF437186D711A1B8F3B8D23F9BAA -:10792000D671DB0267738B87E2DBF87D2F7DFC2746 -:107930006E8DF3C7817C9D7E1CAF366DB17AC238E7 -:107940006FD32BB2875EE38708EFCFFCBC3FF4BE5A -:107950008DF4B76A8148C1B4A1F7918D36921B7F2F -:10796000D7DA4F6417B5825F7EA273CC3943BDAEC0 -:1079700087CD387E2A23FE3C01E9C3F9D400AE8BC3 -:10798000F2471014FAB8F5D7EBC7BF8BEB3BB1E564 -:107990000597541A7BAEB08AE93618BAF5970ECB24 -:1079A000B9F17B4AC77BD46F09F2735AB7240E83AF -:1079B0007A44DB600DBB286E6BD864F504F072432B -:1079C000A70C0EB25F47EDEC3734747ECAF86C90AA -:1079D000BC1169026FC325C5F811CB3A3F984DFA27 -:1079E0007659AE0C3528524B779E16E3BD1049C22E -:1079F000F1CBB6BF3BFB87D447BC3B12F0AB2AB4FC -:107A0000D726E4C6C4AFD0BBB3C91F6EFDF5E7CC23 -:107A10008F8FF648905D34F4F9FA4D1FD8C89E9CBC -:107A200040C664A4097A91DDF087E405B6D444FC2D -:107A30000B5FFDDB0ABECFF9BFF3F1F1213A6BCB4F -:107A400062BC3FF55B5C47FD9B764F0DBDF7A9DB44 -:107A50005D8038F8506916B8FFF97D6EB2C3F5D66F -:107A6000805BE5565CAFFFC59D8CC72587EF748BA7 -:107A7000F8C69B2BF245815CDAE7E28DDFE57DD627 -:107A8000818FF158FF73B996F234A715A8DE9E4096 -:107A90006E26654AFAF9DAF7C7DF23CE0380E2F3F0 -:107AA0000FF5BC69E088CC7E9B1DAE4D9D1B937F7E -:107AB0004ACA14F63800C1B7E95CD58FE695CF41C4 -:107AC0000E9F9E4DF3DC51A434D33911EE3FA0D369 -:107AD0004BFA9AF302A029317E56D5E12BB2292F19 -:107AE000668741DBBF56B05FAD91DF13F31CD3ED6A -:107AF000C3CDF661D2A5D8BA13E74D17EBFBC0BFD3 -:107B000023108327FF131F329E00ED776A8EE83F14 -:107B100046F2B8D0D99C8A74FBEC95F76D74AE151B -:107B2000C0FD8CA0F5F67DC07DF0646934DE98DF81 -:107B3000DF6D8F9E07925C6FF9C024D7F1F7D17E7D -:107B4000333DFD90AA51DCF6A12D329BEC7900DF8C -:107B50004BF50575EBEC71E78D51BC98CE1775F9B7 -:107B600034F29C4B4CFE98D19AF5C284CC78BB067B -:107B70001BB3129E2F9AE390066BF057449F86A387 -:107B8000768E5F1A3A85FCA1431D1981F2F071C708 -:107B9000FED76EC47D7C1CB266D6F0DBE2F56DFDCF -:107BA0000E945F1C2F23BD9358DF7ECEFE94618F11 -:107BB0003E76E2C57109E416AF27945B27B03EFB21 -:107BC0007FA567979C43CF7E2F73889F908AAF8154 -:107BD000BF3EB9EC62F22FCCF435F4AB596F9ECEB8 -:107BE000D012EA4DD0EDBC41C7A5DB4E326ECFE4DA -:107BF0008AF3A6A62D7F633B86648DD811B74DC14D -:107C00004FB87F1FD931EEEF9D278D4FB4EF787AB3 -:107C10009AEF5F4CBC65B989DC4C74962D2E8FC8E9 -:107C2000CFA97C9EDF4A7693F4B4A602F111664296 -:107C300088FC0EA9E78F7FA3F799E38AC04C18DD73 -:107C4000CCE7BAB036B63E27A4E8F51481C4F539BE -:107C5000ADB6E8792EDD3FD779EE715DCE3D4E951C -:107C6000CB11AC999A9CA8AEC45365491847ACCFC8 -:107C7000147ED608DA33B67FCAD4C4B9BA5CAB274F -:107C80001A45BC443954D67F692E3E0FB6EAF51921 -:107C900038730E9F1F245B3E4592C0CE7573E72854 -:107CA000941F2EB7DC5E82FDE7D72D9AA3207E3C81 -:107CB000D32C3B8BB17F68DD6271FF524BB915A1AC -:107CC000FF78A06ECE2CCA1B58DEFD29ED4F59A5BA -:107CD00000D58F94B47DC0FD3BACE2FCAAE9D95D30 -:107CE000F5F4FE26091981F46F73859AB98E210780 -:107CF000D455943CD676FAE8FEEA5C8CE7911FFBFB -:107D0000527DDB33C9AE38C22EAD98E24AEFFAEFAE -:107D1000E17DE588956242DCA7C8838FDD392D8738 -:107D2000F4EEFF85F7EFCD9C78EEF79FD871D57C08 -:107D30001A3F560655C6F9CA14AD8AFA768CAF2991 -:107D40006E33F850A608BA973A6D1CCFB5A5797373 -:107D5000084F7FCA34F875616DAB55F8A572B2C093 -:107D6000819C6A69DE8EED6B3AFF5FD7E9417F94B3 -:107D70001718D89DBD99EB56205248FC95E5CD9D2E -:107D8000448F488B029B29FFBAFBF14EC2E7EB36CA -:107D900007E78F6E487DD07A092EB9CC51783B81A8 -:107DA000FF4DA9E34E6A7F9FE57B2F53D4878569FA -:107DB000DE1B6F96C5BCCEE614B29FE045B91279C2 -:107DC0001AF6DFC18772456BDE8772358154417CBC -:107DD0009D93791D726A07AFE306BB58C7FC6071BB -:107DE0006B3FAE63823D7811C557F8FE41C2C18D2D -:107DF000E86E119E0305D04B7C7BFD964B3789FDC9 -:107E000015B0BCB2FCF3F9FB89A7683E3FCE4FE743 -:107E1000A87EA99FFB3B15871A50857E5F1093773C -:107E20007B16DA5F2E15F9FD568A3BA6E971B191F2 -:107E30007F33EA0D26F7FAAA9CA4B0E51E99F4CA8E -:107E400069F4D7488F99F36E534CFA775AF7C7AC59 -:107E500097CF771E9892A5FBBD799047FB08D17903 -:107E60002039BCBA9DF4D0796002F98F390FCCCAA1 -:107E7000BA80F3C03B33455CA1519D1CEE631027D3 -:107E800026BE0D1E5A0865155C8FD00C69E7B6AB8F -:107E90005D26FD6FE07CDC2BEAADA4CFC6BD02B74A -:107EA000D07EAFD0CF4F068F03D7034EE877707DDB -:107EB000A0B5D71A0C4A31F528472D5C8F32089EA1 -:107EC00020D7AF04EC6A80F5E578AE3F693BAA9F06 -:107ED000F7EAF50CE58264FF743D84B9FE61AAAB54 -:107EE000525E50C1E73320550EAD7F982ADF2493B0 -:107EF0005E8143829F67EB20E45299F6753A0C400D -:107F000021DAA45762F88DFF4DCE0CC85CFE742CAC -:107F1000FEFA54132ECCFCFF4E966E8F75FE9FB367 -:107F20008EE42391579B00E3B98EC46AAE2379C3D4 -:107F3000C2059BD13A92F220C9DBA41691373E5F6D -:107F40001D8FB94EC75C8793EB8BA7537EFD2571C0 -:107F5000F72F6A2E8BEB5F7CF7D4B8F1456850633E -:107F6000FB250FCC891B3FA2FDDAB8FEA80D37C652 -:107F70008D1F135C18777FEC134B13D6BD1838197F -:107F8000175A1E777F7DF253EF13BEDA726595FCA8 -:107F9000F94BBBEF31D5C54C675C4C35F2F03AFF7D -:107FA0008DBA3A2A03233A4F44FE3F56447ED3BD4E -:107FB00055923614079E7080EDF83F8B83874C38BE -:107FC00030E4FF7CF99B75BADF2327154AE4E77894 -:107FD000D1AF4A9A4675C4E2DC1EDE12F52A9F270D -:107FE000FD83FD224D7279E0327AAB2A911F7457DE -:107FF00095C67ED05DC30AF752FEA0FFFB2E8F947C -:1080000037B42ED45C079AEEF04E012EA115759070 -:108010006DA8E8B95E77A683FD8C872C965B6A63B2 -:10802000D6DF9125F44F4796B05B3FB385B6931EDC -:10803000501CA0B6E48AE7A9F801A8B207F9E2CA81 -:1080400000511F0647D7CC9A4EF6B37FB49646F53B -:10805000B3D8BF082F2B41B62737B62A1CE7AD4A45 -:108060007E8AED499922ECC90459D80DB423BFCDBD -:108070009A4876ED5EABF0B30256E24FBE0302AE15 -:1080800032B6AF7C4E9C0699D2F252AA4F3D6BB7E6 -:10809000B4AF114CFB974EB3109D0617C97C1EFC64 -:1080A000122D09D73B583F86EB9C07CFD6FF69A915 -:1080B000145F0F2E7AE4E49D1551B93C6A4B1CE71E -:1080C0009D2FEF56BFE991143A47393A1AE2EA3345 -:1080D0008E6509BFF158962CEA13821FB8894C03AC -:1080E0008BFF6B242DDA2FF5AD76E290FB377CBF4A -:1080F00096F862EB9A1BA0BCA691C73F1B07F6CC73 -:10810000E0FA6D235EBAE17591D7BBE1BFE2F3D629 -:1081100027B3AC7CFF24BD8FFC9A5EDF44E2DB35E5 -:1081200024109C57F64D24FFA056058DECFE7CDFF5 -:10813000823B0F617FEE8312FBFB749FC65F5B8007 -:10814000F606EFBF0C9E5777E1FAFE9E25D6330F59 -:108150006AADB4CED76E6E4C213CBD9E26C6472478 -:10816000D036C7CC778D3EDFEB372FDB45713ABD7C -:108170008FDE4FEBA1F7CF55A198FAAF81EFE4ABBB -:108180004543DF7B1D78AD7ABD9795EC6409043BD0 -:108190009F26BD7AD0E25903DC8633D82ED9D92E5A -:1081A0000DB4449E5A81EB7C67E9DF764948D7B726 -:1081B00017447EF5345EFF970D3268888B4FD37D70 -:1081C000567756944E47177D9A42F4447F65EB4F9D -:1081D00049EEB6D93D54D7F1E6D26D2363FDFA548A -:1081E000F78C616EF2AB2A2FEC3CADEAC9298CBF4B -:1081F000E55B05FE96FF7A5436E16C79CA59DC8955 -:10820000FED6123E279D2441C2F878CF4AF1DDC246 -:108210000EC4998638DBF385A82BDF7928BD9CD660 -:10822000A780EFE2D8FDEC7CE9C6B15CCFFB46E667 -:1082300005AD93643680FAF7065695002FEA723240 -:10824000BF27A35CF727C7D2FC37FEEED727FF93E3 -:10825000E8B27BDBD61FB28C5C181D86D6D1AADBB8 -:10826000583F197118D5BD529CB6DFC276F20AF993 -:108270005E8EC3A84E83E3AE61853C1E158E6A15E3 -:10828000FA4D7C27817E70AB87EB3D595EEF5685BA -:10829000DF62C449B2C593A3888F0C5E98C6F317FA -:1082A00003E5C75C145819FA0AFD08976CD1F51557 -:1082B000781D189F8ED5F559B57BC2556DE2BC2649 -:1082C000CEFFC47E554702BFB316FFB1DFB9D1D789 -:1082D0009AC47669A35C4A7E87D711263B6EF63B2B -:1082E000A7C1839C0718E27F3EF7D70BF23FFFD56B -:1082F0001DEF7F5EA8DDA9776BE2BC77B4D073A1D8 -:10830000F0308E73F0AF9CE46B64B6B04B7D1463B9 -:10831000519D9F746AB403E5B3C15DBEF6019449F3 -:10832000C770411FEAB7E2FF97689FEEFF9AFCC053 -:108330003E85F937F8DC25DFF81D4905CA2119FB10 -:10834000F081A95CEF3CD02BE4A3335DFBD3348AEE -:1083500033D0CFDC8C4B4C52FA6D6909F6F334E91B -:108360005F9207B7B0478E6E712EEAD0BC40FA25F7 -:1083700049552750606E8CAF730BFBD578E0CD422A -:108380001BF2E7A4E5908BCE571A76ED70E176E10B -:10839000BE0CDFFD84EF65478F4C52B9CE6D532183 -:1083A000C5DFA1F09199EC9F552369279C7B3FFE87 -:1083B0000DE5F41102346DC8E0760CE555F0923FFE -:1083C0002CF679AABB353D517EC0FFFBB7F6D17EB6 -:1083D000B7BD98C47ECBB6AC3E9683C05C80AD483A -:1083E000EF27BF18CBF32127781D97D46A12D9FB4A -:1083F0005FEAFBD9A6C797A7BE90799C31EFB8EE8C -:1084000019B28AB82A0DB7EFE33AAE1EBB46FC4D4F -:10841000DA02823E3D495C17E6DF73A5883BD3C490 -:108420007974E7B0C8DBF49EC86EBB4675AA496A8A -:108430003BA4E3FC9D366167C720F07738A3D78D56 -:10844000F725F5ACE78F2010175C8F97A4B4C3B75E -:108450009CB1F44FE1F586DD02579DC3C21627D9C2 -:10846000098C9536F3BAA2EB047EAFB1CE31EC178E -:1084700077DA227FA17C3BAE4B255C8C01B14EE8C4 -:1084800019A591BF92A48A73F52455F304A4A1EB16 -:10849000F28F87203A07F0D02A382BE75C47382C38 -:1084A000DA77A02C7416EB7E4C60F1DA5905317D39 -:1084B000526495D1E75F75D7AF6D2BA07D093BA8BE -:1084C00028213E1F77CD0795CEBF93142FC749496A -:1084D000F3406B417E253BBC7CDF8D73B44CE17E69 -:1084E00098D6AFD27DCACBA4AAC97370DDA95FA606 -:1084F000F2734D7D56AE3B6FF8C775A9A5B8BF1393 -:10850000967D2B3AB0FD784168249DD356A6FADEBD -:1085100021BC3E736CE1DA7138FEAF9D564F0DE918 -:10852000A5FEC08FE9DC7EE993568DECE2FD6F0C71 -:1085300086BF26FE3E2BB15E1CB08AFBD8D75AF010 -:108540007E53CF87363AD7BAB2FB5D1BE5BFEFC982 -:10855000F61D27FB56D9DD5245749B02EDAD94E71D -:10856000447DC8F512A11CA12F065F19B9B9258653 -:10857000CEAE6CFDDC2BE2BB98E4A64797CF3DE482 -:108580001F61BB4BF7D376EDFD97122DE6FC34004F -:10859000FB381FB80A9EE3BA4EE3FA4050A9261CE6 -:1085A0008D7DCD718B3706678E6C5DDEF5F7FD3CFA -:1085B000DBF70F96DBBDEFD95CB87FFF9F43856487 -:1085C000AF42E8CF7D531DA9DF242F67EB8E8E03CA -:1085D000EB916DAF75B3FFBDED1E358DE41ED70F6A -:1085E000A9D8DF85FE05C9D1AE2221772DAF9E190E -:1085F0004FF9E233BB975D4CF48AB8AD06BE670E07 -:108600002339DA0EACC70C392C2539C4A597AA2218 -:10861000DF534AF826B9B3F5CD61B9DB6501923B6A -:10862000C437E31DF1AD921F52AA22DEF9F9512C95 -:10863000C79D7D472EE17A7624EF8809D4B730BEF6 -:108640003AC37382123E5F610DEFA3E72BF0FD2D5D -:108650005A542E2BA4F8BA9E3AB7A89335F4E3EDFA -:108660006EA1EF43A3B5540F8E4F96E538FCC7D8E3 -:1086700049D1D7EDE80FD6FF74ED3A9487126FB960 -:108680006512F93B2FCA6C07F6E87EF2F23F4CBD4B -:10869000A6435C67FB19D671B14FF79B9F5B99C3EB -:1086A0007DB20B1AF26522B6DE72AAF76EAEA25444 -:1086B0005C6575FB7E6AA7D686AAE8B870FAFCBE30 -:1086C000FDE21B37EF58C25BD7BE6F8FE53AE9A3D7 -:1086D00076A0EF38BBFE1E79FB49DCFF8A3D486F70 -:1086E00048E89730DED06233FECE859301A9FFEAD9 -:1086F00069A897AF59FFF8550A1AF4260202EEBF8F -:1087000066FDD6B5E8BAC0ABD9DE6BB291DF5FE5E6 -:10871000F8AEC946BA0D1CFEBB9BECC9AE57DE7362 -:10872000911DEEB279C712AEBA8A318E4880C7E980 -:10873000D9A26EA7E21CF526CBB3C5F9D6C800AC0A -:1087400025BC3475C96A90ECB4B7EF6AB21B7F419F -:1087500052525EBB6E46C045F152FDAEFD5CA76F46 -:10876000C4D38B41FF936F9A4DF43F9D23E2E3BA4C -:1087700075D6B8F87614846D748EECF7399BC3C83F -:10878000927A93DF715BF726FE6E64E996F8E71A3A -:10879000C84F4108359C273E5E9EADFB29255042BF -:1087A0007E0AE286F324915765CF66E0FAAA5EAAB4 -:1087B000AFDA6611744A76405B6A7AD45F1993EB3C -:1087C0005D4272BE44C767A75EAF14E994F87B8A26 -:1087D000314F887879EA716D137F2715F0729D5EAD -:1087E0003D2D00D73D5509F0FEA7E6944000F75F08 -:1087F00089EA99E4A5AE470A323DF5EF5E14FC27FD -:10880000F2451B65FECE6FA3041945346F84E9B3AE -:1088100054CF1F2E7B22FEFCA261C3E103E42A3564 -:10882000864CE7413A7DCCE73B3BE87F129CEFACBE -:10883000CFD6F308855018F75D5EEF857D97F7B1C9 -:10884000FEBDEA117D7E63DC2E5D6F36E9FB6E08AE -:10885000CA62DFC80AAA8FBE5587891F3C4CA7464B -:10886000C409E1001E14FC36EA199742AD8DEAC82E -:108870001ABB5A0ED0F95B9DEED79AF18404657A43 -:108880002DD1EB86EA37C6DF5FAAD365A9892E4DC5 -:108890003EC9B43EE1775FE8FA50735D4F3858DA6D -:1088A00061E57AEED37013D75F35766DE2F5D4E9E2 -:1088B000FC1BBADE00EF6709EE87E4E942D76BE6FE -:1088C000DF9F0C9C5F0297C4F1AF3AE382F8570236 -:1088D000EA32DADF60AF886B077B8B392F61E0C546 -:1088E000FCFC6CDD8FBE7283F0374F765725933FCB -:1088F000307048F14888FBF2173F73D1F73765BBFA -:1089000065A073D2819EF2B501D4973B7B875FA7A8 -:10891000A11D287B5161BB51FE625930A988FA65BF -:10892000C9255C67A265501C80F3B01D1E3834FC5D -:10893000E552F6D367555088DA72A82C99FC859DCC -:1089400020F21BD28B1519FD3176E5C36C91DF58EF -:108950009DF3FE43A4A7AEDC6EE57CF095D6C84B34 -:108960001487EDEC553C2DD86F7871E1AA24E2F71D -:10897000AF250FB9DD07FA9667D2794D638F55B5EC -:10898000F37AEFDC47F7031D9267048EF7EFBE62C0 -:108990006C27E58936957B88BCC6FBCAD2B447A84C -:1089A000DE157293396EBFF2222BDBD71379C9FF24 -:1089B0005183FB5AEADD349BF4F089DFEEE4BA8A96 -:1089C000814E097224CA23EF7F8AEA7D4E3C7DD80E -:1089D00046E7C1555D87B96EE35CF6E0641071C788 -:1089E000717BBB8DE29BC64D46BF9FBF47A9D5FD9E -:1089F000A8A62DEF727F29C50184C78D7250C3FFD1 -:108A0000DDBFFB193E1F6EEA10751F67EF6F91F80F -:108A1000BE81F785BADE5A061AE37D998177BD3E9D -:108A2000CAC0FB69A8E13AAD651D0F33BE17EBF86C -:108A300036D74D0134DB4A3385BC52BECDFCFDDF59 -:108A40006D3ABE6F3B0FBEC7E6E8F81E036308DF52 -:108A50006766887ABA33878725D3FC670E72F6F586 -:108A60009B70CE76F790EE170C862D5EDBA5D1714C -:108A7000A7BA3FE5EF10FD87066D547732BBE713C9 -:108A8000E6474DCFDE5944EFEF80AF81E8F79D9E7A -:108A90006495FCE09A7EA1CFE6F4D8F97CE23B1025 -:108AA0006A233E0FEC79BC2D9D70F32B811B43CFC5 -:108AB0002DD1E97A55E9F76753FCBE54B78783BDDA -:108AC000B7CF66BD33018AC8DF9BA37FE73D27A4EC -:108AD000EBA18DF174A7736AE25B538F9DEB4DAEF2 -:108AE000827E1BD9B3AB74FB69B69303B9C9CCE7DB -:108AF00000DAAB1138BEA1C35447A9F4F37A06BB20 -:108B00006D7CDED564B2BF97E508BFF27CF1BD99FC -:108B10005F0B72747BA2F3AB2622EA18E6BC227BC1 -:108B2000E8FCA137BCAA94FC05836E667EF56A2535 -:108B3000A9DFF47B092FE97EBED1BF46FFFE2DA43D -:108B4000B63B63E3F6833916FD9C33F8D372DCE75A -:108B50001D12F4110E31BEB9A64C4A18DFDC938306 -:108B6000FAE38F05B73E382136BEF16E1A49FEDEB4 -:108B7000FDA857CA2BB87EA78FCF0B95F61A3A07D8 -:108B8000F377583D14D7F8BB65F607FC1DF6A00532 -:108B9000E7BD927084EBAAED91AE201C61DCB09A27 -:108BA000E69F4B29651C37B71BFD117C6EEEAC4F61 -:108BB000187F07878B7D0F2A5A76A238C2881F9AA2 -:108BC000BE10FEAA71BD09F5008D6FD2BF4BEBDA66 -:108BD000F7B7C2A2143AB7FDBC7001B64FE7083B25 -:108BE0006CF8AB11F4578B757F85EA2EEA04EBA085 -:108BF000EEB97B6CA4BF0ED00F5B50FDA4EA5B4DB9 -:108C0000F1B0EA83E61F91A321B5B11C35914C1157 -:108C10000E7749227FF3AC956A43A0E5C830AE0BCE -:108C20003CF59A388732CBFBA9857DAC2FCE2C70D2 -:108C30003613DE96956E5A9D4EF2BDE775D63763B4 -:108C40007F6B532D6A745F2DF4DD1DC7696D71FE56 -:108C5000F2A9EE561BE7A163BF1B2E1EEA1F359E2D -:108C6000278F75D0A45770FDECEF0E1C9455CA0BDE -:108C7000211D7F91174B2FDD1FEADA97C4F66BE0B9 -:108C8000B033487EFF5F753C9ED0F3F22D9532D312 -:108C9000C33245B463F73C534CFC257EF850DF6F7C -:108CA000DBF3CC255ECEA307451DF113F175D88DFE -:108CB000A1F83A6B83AE7E9DAEB8AE91F4BDB2B171 -:108CC000AE5D4ABFCB93408E24691FF3CB22C5C74C -:108CD000B9FE67E5DAD83A52DCCF2DA4F7FED3907F -:108CE0001725E2263BFC4E8EC6EB6BE911FCB5EC7A -:108CF000162DBEFF7A91AFB1F2FB87DC9F1968A0F9 -:108D0000FB678A92B9BE01BE08D4507F45B1F8FD19 -:108D1000801547968E8ACDD38124E271BF35C2F586 -:108D20007EFEC3165E9FFFF0A07BB893F4E2A659C7 -:108D300054477B95AE2F0E1427D713CE03F4DEECE9 -:108D4000E83C4B72C47903D07E73A2DF571AFB5DF7 -:108D500005D7321D56E9B87A4B8F73308EFA222729 -:108D6000411C752EFFF7ECBA75FFE9CC0CEDE5EF71 -:108D7000210ECA0E2A018AD777BE911424FBDFB2D6 -:108D80007BC93B140FFBDFB403F9212BF62C19C56B -:108D900075F83EDFA5A44FCEECB9ED52AE6394C496 -:108DA000F7A5015A5F0EF953AFBAC94F6ADCFD2A25 -:108DB000D73936EE9AF808F94FE82F5D45D7D18FAD -:108DC00061FC95BD58C1F8DB79A822A384160E9EDC -:108DD000649AB7F1A0C2758F8D072B5EA821BFE6FC -:108DE000C599EC3F19FE5239C5E3E43F1D1C1EE74F -:108DF0003FA5E60AFA0DEC4DE2FC8704C5023F30C0 -:108E00003C0E3F0D5D7F603FA301F55D2C8E8CE72E -:108E10004A72159E6754AE8E9F90E4657C6C176D08 -:108E200043F74EDEDF326B88F9DDD26115F73B4543 -:108E30006BD44907203D40F478812E211FE6D8826B -:108E400005146F3E5F14FFFB4446DB912BF209CF04 -:108E50001F15DF193F3FC3372AD1F7C6019829E212 -:108E60007049A77797B53AD1F7BC4FEAF3B93220EA -:108E7000EE5CD2687F922BF4EA1C9BC85399EF2FCB -:108E8000CC35EC0FACA5F398976BACAAF1FB2DB9E0 -:108E9000A877AF06E3CFF3EABC4C3AE7127135404E -:108EA000FF2CD287DFA53C3FF95F95C2AE1B79FE50 -:108EB000B91BE13E91E7BFC94A7AC1A82F99EB35AA -:108EC000FB5FB557D03CD7A27DA779AEAB8EBFFF75 -:108ED000DDF3F85D37E6EA767C248C1471853399EE -:108EE000ECC1E95EAB2AF33E82C3137D5F68E89F65 -:108EF000032BC5F9512FEA456A5BC6BCCE79ABE7B7 -:108F0000F71E7D2A8DF56A121423892FFFF21D7733 -:108F1000A2795ACECAEBBC38FC19FC3A497140E937 -:108F2000507EDDA9D3BDD171C2C6E79BD0FC804580 -:108F30003EF777492D633E6F23793AA97FF782EB9D -:108F40002BB4C7E8FD93B99FF0FD15332112C0FB88 -:108F50007BC7D8D9FE35CE92F8FCA0312CEC61E36A -:108F60003C610F4776CD65BE5C8F7CF17A584DBC75 -:108F70004675B906BF2FFF726096114FD2394E0B5E -:108F8000E19CF57426B78D5DEFB6F17925DA5DF2D7 -:108F90000BAFA98CE7DB28F0DD9785F76FA8963C2F -:108FA000684186F0FD869BE632DFAFD3BF8F391F65 -:108FB000DFB7E7FA36E492DCF70D5E3F0E49F4FCCA -:108FC000980F0BC9BE369D03D75B0C5C0F8F3C4DD1 -:108FD000E7659EB3E7E9FF783AF63C7DB8DBF71F1B -:108FE000B9A4572D5FBA2E019AAFFF17CB25E21314 -:108FF000F0F3E792AB2775B97A325715F9DD4C716A -:109000003E3456EF3F6F0D16F0F714A517760ED8C5 -:10901000F2EC1FC7939E3BB5F7E0785B0C5F4F2CDB -:1090200047FD40F666F77EFEFE308A3B8B8E3B8521 -:109030005B49BA56B7A3F1383C413824FDBC7DFFEB -:10904000D5143F9EECBA2E53D262ECECAE975D2362 -:1090500062E63DA9FF2E06C66D23BF9B12BBCEFB69 -:10906000C4797948CC87F23FF2BA71B1F75B753CAD -:10907000F7339EEF1FDDCCE7F4069E151078367EA1 -:109080000FE3EC779536E0EF1E037BEC5C5F31601D -:109090008D14A6C5C8CBC73A9D314E930B32999417 -:1090A0005CEF3A19D655F1390106EF6BA7D0E77797 -:1090B0002159D4873673DDE2F466F0106E25D8C8E6 -:1090C000FD49D5E2BC7C2AF4C9B4AECB20C2AD17B1 -:1090D0005485DA995461866DA52324933AE9ECDA34 -:1090E000974CF80ABB95B4BF3844E96922FE45F7AE -:1090F000AFC05F0CBCE2607482127EA7EFCE137526 -:109100000E9E64218F9193E2774FBE05FDBCFE69F0 -:109110004A1FAF3745D3D2E9BC64FB73CB65AA7F46 -:10912000D9035A84E4CC93D1CCF9B7C80C086D4E5E -:109130008BEEB792F6AB46FB53E78385F62B418760 -:10914000D87F33A4D3F9D81408F37B2EA705E37E88 -:109150006780A650DF9157A4D359C46F557AFC6637 -:109160007104B8EE27354FE03A5909CAB9159CDAAF -:109170000E3D4CE73325629F93F13A9FE3348B75A4 -:109180009FB5D77942DF4D8510F319EA417D817F84 -:109190005C61964AF492C26E0BFD9ED885D275C072 -:1091A0000DBC7ED7AD91533FAC889E7B797AB2B926 -:1091B0001EFA41C91291695D8E02510F1D86107F02 -:1091C00097198EFFBDB392BC6B8BF268BF3EF11D49 -:1091D000AEB9AEF389E066AEBB991F40F2D03C0554 -:1091E00000C7DDD13A006B7190EF5BE99C5DE53A19 -:1091F000D3728A177F9FE52BCACBE27AD3113C99B1 -:10920000129C589B12C53BAE8C7F7F271952DA49BE -:109210001FB5EAF5B401D5A5D73315F23E34D4F322 -:10922000FC23128AA8EBBEAB4AD49FDE356C0FD765 -:10923000F9F64BA04AF974FEBF87EB80E987E1ACF1 -:10924000F9DF70FE9FA9FFEE43B1EF8DC925BA92F9 -:10925000C7E75A8FA570FDAB32D3AB511DAFB95ED6 -:10926000BCA46DE203FD1C971AEB35D5892B1EBEFD -:109270007F97AE5F5B1DE27780A45576559A4EDFEF -:10928000BF2FE7DFB16A25D7A082BE7B5FCECF5369 -:109290001D33158146527DDF257A997F970AE13586 -:1092A000F83CCD9B3A92F37D89F831DDE087656823 -:1092B0009D14F2E166E2AF51776BD4DB122068DFD8 -:1092C000C95EF13B782AE2847FF70F9762275C7AC8 -:1092D000CDBFE721EA7FDB74FAE3BA9EE0BA4F879D -:1092E000F84EDBF89ED74C3703BFFF0D047C0BCE46 -:1092F00060530000000000000000000000000000BB -:109300001F8B080000000000000B9B29C3C0F0A3C6 -:109310001E8145A451F9E8F82C9A3C0B0303C34F76 -:10932000209EC7835F1F2E1CCD82607B8A3330183E -:109330008932301803F14C209E05C43F80D8408C00 -:1093400081C110888B80EC6220F6016207A0DA2FC1 -:109350001C0C0C138419186603F1326154739F328C -:109360004268252E06065320FEC784DDFEC96A0C1E -:109370000CDB7510FC385D068635FAE4F965140FD0 -:109380003DBCCD1195BFC70A95FFDC8681C1DE09C2 -:10939000C1DF6B459AF9D540BD354EB8E58FB9A10F -:1093A000F2F779A0F22DD1E41787416800E6955CC9 -:1093B000CAB8030000000000000000000000000028 -:1093C0001F8B080000000000000BED7D0D981C5560 -:1093D00095E8ADAEEAEAEAEEEA9E9A494FD293CC1E -:1093E00040CDA443069884CAFF04265033C130AC54 -:1093F000A84D94ECA0A89D1F312ACB6B780A01C11F -:10940000A9F9EF9924A4F3F342F89134D12CA0AE3A -:109410000EC87323B2CF4E88BCE0DBA711D12F6AF0 -:10942000F01B621E4FD45D67D92F4BBB06F3EE399C -:10943000F7D64C574DFF4D02ABDF7EAFF3E1F5544D -:10944000DD9F73CE3DF7DC73CE3D7547264D247608 -:109450000D21E7E047CB3F780921CB264BABC3C8B2 -:1094600092A5B4FC0A31FAE8A3CBB56C8740CB05D2 -:10947000EA9847D009B9229226C443486CF431E2F5 -:10948000A1F552F532196924C4AFAFAD22EA64BF29 -:10949000EEB2AF9B90ECFCE2EFC523C3513D44FB21 -:1094A0007B6A799749FB493DDDDA65B64CBEAF83EF -:1094B00041297E4D8462534BC840C35EE28910321D -:1094C00044C79E4FFF53EE4B90386D27678789BE88 -:1094D00000EA55637DE5D9E39EF5F4F99097748D24 -:1094E000D2523964658314EF85CF6B8B454A8F5F09 -:1094F000323DBFA5B03FEAC95840477417F67B8696 -:10950000D20543BD5BF42C017A281D6D15D2D356CC -:109510008C9EE72D0BE8B9E290BE289F1EA59ED138 -:10952000A3D4F7E23C9D89527A1A2F849E7B909EA9 -:10953000214ECF908B9EF7717AD6D9F4D40D223D6F -:10954000830D941EFAC8779F45E2B4BE02F484A04E -:109550009E939E41A0A7A5003DCA9F879E4F72790A -:109560004B023DCBCAD393047A6A2BA0474D138D8F -:109570003EF713C11C6D998A979FF371C1B3E9A897 -:1095800045FB1D7E5BC479A62B32BA76C164BD3122 -:109590008ED7F71A07A363205FF3F64609ED6FB87D -:1095A00041C0FAEE7E1F2232D6AFAD377BA0FFCB93 -:1095B0009E74F63FDCC0F0B5EBFF139FC77F2222FD -:1095C000B6AB51E3C3000FCFFB1649C038DE74546D -:1095D00083768DACDDC0BCE55D636AA1F68C9EE14F -:1095E000FB2D9467257B0FF2EB730D69A253D8FF17 -:1095F000648200FFE528C3C76E4FF122E44A20FBD6 -:109600002ED364F811329BCE937557D6A2E3C5D200 -:10961000B72B71CA8FE1BA5E05E84EE9BBBA406F5D -:109620009D89C9446C04BC0AF3C1968B6BC836A5EE -:1096300089CE67DF2BA23142A6D6B340B86A276134 -:1096400049F5906C33C1DF3902F42470FE07E6ED72 -:1096500045BA65A06B01D095243A7DFE1C971FDFAB -:10966000B31601B952742B6A2D983A4E0AF8DF02EC -:10967000BDA6A36BF3E8FFB93DBF745E5DF38B7CC1 -:10968000798898590BF8E277CE9B5DBEC4F97E4588 -:10969000BD85FC2D37FE54FAD9F87F4F74EC87282E -:1096A000E9683C3489CFB077AC17E49AAE49E3203F -:1096B000ADB2908ED39EC76FF77813744A69871C3A -:1096C0007F8BF369D83F7E24BF3F373EDFE5F5BE91 -:1096D0004B342C6DBA161E62E394EBFFC7C0E25AFE -:1096E000A8EF5A5792E5E0FBBDBCFE15CF3BEB154A -:1096F000E3CFE727F86345411EEDF5083F732621C8 -:109700005C64F0A72E27E452F83FB4C9EFD78FDD91 -:10971000054BEB1791C419E8E73692B8383097AE8D -:10972000176FE20928AF95CC7F83E7B495F6FAE589 -:109730005CEE44D4036C3CDA3DA1FD87787F92D087 -:10974000490895675F2BC98C50D4DE239ECC0A94C0 -:109750009FBB0831666979FBFA29B6AFAFD432AB4B -:10976000613FBF4AA284D0F1AA88E68712EA6769FE -:10977000BDF032D5A023111FF94855BC80DCF89705 -:1097800012CB5F45C76F951DEBC26F2608E8855069 -:109790009464FD614234211441FC5790150C7F5DA7 -:1097A00080FE6A24BD47A2E388318F71803EAD6A96 -:1097B000232B37E4C9A12E30F9ED89793C40D7201D -:1097C000D5FF3EBA24C30D74BDC37A88527BA380F3 -:1097D000DC4EE8F79C48B23368BF39816497505833 -:1097E000252B13B45DDA47569EC6718971A0809C03 -:1097F000AD13D8BC0AB1F173E7D02E2099EBD02E6F -:1098000048E33A96636913F601C50C1B3E98F6B31C -:109810003B985E93880972521D4B67ABE0BD7E4951 -:1098200023E03B2B9624AFB5B0F2541EBE8A6A45A6 -:10983000D17E6ABC44E8CDDBC70E53F93995276F5A -:10984000A9FB991D30D038C8F5CCA7507FDAEF3F7F -:10985000C6F9248F5164802E5DCE340953E53A2534 -:1098600014D6131B39BDF0BB76B9535EA5995C5E67 -:10987000E9103E89A07C0D3D4532802FE5E491F54D -:1098800014BEFCA84246A87CB590E31E909F856458 -:109890001C4B836822948B8981E55212C7F2F7ED45 -:1098A00054EE69799B49E5BD09E5FF2601F68986F5 -:1098B000C4FC307DEE8F5957C2FE42E57F1D3CA7A8 -:1098C0007222803CD598A4E07E592DB0F5BA53D2CF -:1098D000FC506FA749503FEE11FA2CD82752DC4EAE -:1098E0004AF989631D3FC0E94EF1B23A96206330D0 -:1098F000BF745E40AF1F6EBC15D7B14F62F0209DA4 -:109900001794BB556C1F73E3A1C0BC2C38FF79586A -:10991000F7E79F87416159C179188279582730FD4F -:1099200029FF9A8D5F823EDCA737F63C8EFC974F6D -:109930004FAFBE4DFF7297DE5CC1F5DC5564FC2273 -:1099400089EA91DB7D59591210EF2F02DEFFF6B341 -:10995000E31F037AC858623EEC5314EFC704E46770 -:10996000921CA7E34BAF8819F0533CC11B944409E8 -:109970003F8568549F295C9F35C1FFD66BAF07A711 -:10998000EADF4B463F7902ED0DA22446403FAD4A47 -:109990002A20177DF56B1590A3A17A0A83DC446514 -:1099A00045B882962AE904F9B3ED8F17A21B14D0AB -:1099B000CF723431C397B7FE574713E457B0CEB5D3 -:1099C0004454A474C899EB14A067405BABE4FB5704 -:1099D000B29A88CA54DE86A05F18C79B5404D493F9 -:1099E00064462FE5CBEAFA24F67338DA81F80C687E -:1099F0001BB0BD4EE26837BD50BFA1B311F68B5707 -:109A00003612D063C5F8E1B6A37D6A92C879FB81AE -:109A10004F4B12316F3E7D52320B7888D1C2FAF52E -:109A20000497738F1EC77D85A41F34152ADF5E3E01 -:109A3000D7DE28F999B0306F3E2279FB0B9D8F411C -:109A4000BFD15568FDD19DC2D9AF21106579E5FD23 -:109A50004EEEAB7C7ED32B526338BFA134CC6F1F4C -:109A6000D5EFB87F9E0C650E52127A5625F7C37B50 -:109A7000AF2591DE0876D30CFBD9DDE26506C8D9A7 -:109A800003C037CAD86DDD0A9623DD1A96A9EE28E1 -:109A9000960F06BFF0C4186DB7C5F2693E5ACAE901 -:109AA000BBBF01FD51EF3A3E02FD4668FFD0AFA4B7 -:109AB00068073580D9FEE28DB1F2660FE3A3EA09AB -:109AC00020BE8B3CCCDED68989F292D64AFBE35588 -:109AD000AD4E7B36640426E59EFE176CAE71C07EEB -:109AE0007DB6A3BE7B5DFC80EA26C0C72BC589D1AD -:109AF0000265617D7D5610114F515C340E768634BF -:109B00004BC6FD7F4070EAE7473C6C5FCB7814ECB6 -:109B1000374AC65F3847F9E1D53C68DF84AB9B46DE -:109B2000B3C09F5AD998478BB0774CAB29301E8968 -:109B300048BF1BCB5BCF4F0966A3E72F804F53E88D -:109B4000EFE970C875CAC3F6B5B37CBD883EB30BE8 -:109B5000F449948A2141F9D01F073E78826D46333B -:109B6000E5C340B5AC83DFD3DFE329B8BFB8F92044 -:109B700056DD12053DE8E6FBF35C8E9EE27CBFE617 -:109B8000EC07505F6CD73C9D19D41FC73B419FF732 -:109B90002FF57840CEFF62F8E7A2E3735C7ECE0A31 -:109BA000137420DFFA23CC3EDEA651F981F51C6147 -:109BB000F2A3936C27BE37285DC254BADCFC7BB796 -:109BC000E9B3F95E55ED89675A00BFF138E2D7264F -:109BD00015C4EF3F8AEF365EEA045E598697F19727 -:109BE00081D7534262BF87C20F70797D401A5340BC -:109BF0002F34423DD03B41B68EA6EA25C1DDCF933E -:109C0000A02776403FB4FE0E69DCD18F5D2F047C27 -:109C100060EB22CED685F4675D17365E231C6F9D00 -:109C200064985C371796EB771B2F7B3FED0D5E4DED -:109C300040DF54AB71B4B367A9F12CF0ABAF56D68B -:109C4000C1FEA10E11EED7D854CFF3876AD745D104 -:109C50007E09AD43FB7BC01B477BFC58EDB7CCF5C1 -:109C600094AEBEB355C46750BB3F78F5311DF4E2E6 -:109C70003111FDB2BEB37367250BCC7310E26014D3 -:109C8000FF00E087F6B33C616C03BE7D2A557CB4CF -:109C90009F375B4806F4A95735A3605FF72D508CBA -:109CA0005EAC1527C0DFDEE0C75A132D53DB07D5A6 -:109CB000C13BC48593E3D09F700E6C5CBA8783BFB1 -:109CC0008EF4098EF705F128077B27610DFBA7B0FD -:109CD000AE40D782796EEE24DF292DCD12EC9B2485 -:109CE00060C0FCC7E29DBD7F043EBD24A21E74F38C -:109CF000E75931E113F3E25EDE4802E7CDEEEFFA19 -:109D00005A09F5A8544F323E01468DA31DD957EF8D -:109D1000C1389AA4AEAD2A695FD757665F131EDFBC -:109D2000B0E5A1FDD76CDC80C1F477888C11889FE9 -:109D3000541116BFA826BA40B0BD21C43128D2861E -:109D4000719388FF9DEEF716EC5730779273C169D7 -:109D5000F42BD17EE7BE0BFD96C1D74F1EC57EA961 -:109D60007A889C9B31D9AF379AC487E4ECB973E207 -:109D700072C29AE02F81F22D790C5C9F6476D838FC -:109D8000488B81C89D0EBFE946B1C9111F95B5C169 -:109D90003B84302DEB6F33C7F2F4837B7E6F82817F -:109DA0009641BD4DE658057A03CCEE42F1A7413904 -:109DB00091E981FDFB2215E385444A62FC7748A8BE -:109DC000590CF6B35D4FAA97B380976A9816E88B43 -:109DD000A1191E4334A0DF6DC7C11F20E20D46A2AA -:109DE000441C49AA977E934FCFA745673CABAF8CE5 -:109DF000BC0F74973E87F0CA46A2903F73BFC8EC71 -:109E0000176FA0F0FBEBE58E7BC56553F9B69DF3AC -:109E100077A89ABAD65730F1013990EA5F3C017CB5 -:109E200018A85D132D452FD1A89D93E7172D93CD2D -:109E300021B1341E5BC5DA02F3A752E15959629C85 -:109E400009F94E120DFCC557983EA2F88685994C2B -:109E50003FB39F01361BF1B6FAB4113A6F811683F6 -:109E60007C99C2D1D54A5C6AA5F42E3D4044785F06 -:109E700027121174ACD866A0BE6A66FE9D49FF0128 -:109E80001DE136D9B16F81FE9CD8B71A41FE9DF015 -:109E90001330CFC1BC79EE3E447E356F127FFAC8D5 -:109EA0002C1417F6CB1D7F57981F3515F163379586 -:109EB0001770C87752BF11CA1DD46F84723BF51B4F -:109EC000A1DCDA4D859DCA537F7733C2FF0D9AAE70 -:109ED0008473B264AAB111E2A25F3EB1893EDA0D89 -:109EE00038CC866EFD1D10271F01F84A44C71200AA -:109EF000E6E7292F89FFDE0E719711BF5DFF9FDB1B -:109F0000B1FE042CF4425C7F24C4DA8F89C10EA810 -:109F1000BFBB81F0F8B9A9DC94E7FF9F11BD287F92 -:109F20006003B1F6BFED81FEFC920DD777401C7542 -:109F300002A67C047CFC0A8367F73774C0B906AAC2 -:109F4000003A5E53FF456CBC792C6E463EB4B60CAD -:109F50001F7B71FC7570D806347FA8060E8F894C64 -:109F6000E5A6893EDA5DCDF1AEB01F2225D87EC7C9 -:109F7000E347C5D74D997D8DE3517E3D9868BF81FC -:109F80001EB660DC9F14DEA7DFE971777BA7C717D9 -:109F9000A52D6142F7E1CED12C4CF52E31119668FA -:109FA0003F55D71EC76D458E6699DD50E1F86F8825 -:109FB0001A8F7F26305E68F35BD298FDD1EE9A4F00 -:109FC0006FC4C47348BFCAD661A5782F8771F2FAEF -:109FD000215F5B5C57687FB1CBC80D9E49BB8BFE90 -:109FE00057736DC0016B6D3593761CF063E96C0798 -:109FF000ACB6343960AF7699A3FDF9CED7E52E3AE9 -:10A00000749B7F1CAE75C195CB9FA4F3FDCE627689 -:10A01000E404CCF7E572F0D9F94E98F5EB231FAEC6 -:10A0200062760EB3673E4E781D371E469E1E16A101 -:10A030001E83758F406C3B37DB3CB5FF3EE50B184C -:10A040008F33FB24E2BF7A6ABCCEEA4862BCCDEA19 -:10A05000F5697D118CBF61BC6D0B35E87DB4BCDD4D -:10A060009BB855A2FC7ACB7F518684A1DFE40A8895 -:10A0700053F7B9E20A6E798A3D7A73C1F331BBECCA -:10A08000EF6671401B96EA0B9FFB6F9164A4E3257A -:10A090006F620BAC2349234731CE43ED6C11ED6C5D -:10A0A00013EDC7C3D56BA260C7A44C19FD1C297D55 -:10A0B0003BAE9707DA3CB85E7A241DF1EA5FD97BA4 -:10A0C0006C2EF8A3BA87737A0CED801DABE43A5876 -:10A0D00037616A8FC27949382614DCC7B64BFCFC5D -:10A0E0009A7CB4247DEEF9F838CF234A3708786E8D -:10A0F00067853CC8FF94EA413DBABD4D7E1CFC9F7C -:10A10000ED4B3D37C3FB336DB2472CA1DF06B9FDE4 -:10A11000B415E2A8B0EFA91BB09F33862753497E40 -:10A12000CEE1556B30FEDD2798CA5C3C5FF690832C -:10A13000C8B71F60FC6FC7A20ECC1FB02416F7DA99 -:10A14000BA20D09529741E2E85F1FD8EC6F6230FF8 -:10A15000015D542F1F44BF6DFCC4C6089C5F6A8B11 -:10A160004774A0DBF4BC01E3ACF4E0FB7463F20AD7 -:10A1700003E2B66D1E87FD915EC9F8B12342908E51 -:10A18000336DA7206909F653F321387F8D2C9DB0DC -:10A1900087EAF2ECA1706B724522EF1CC1B69F8A70 -:10A1A000ED4FA26C8C59F4BD7AD287FEAB107E9233 -:10A1B0008810A79E2DA2DF7CED82A3088B6382E12D -:10A1C000D3216E6F9904FD3D93C5F1EB0979983E5B -:10A1D0000FFE41C4736112E2F636B7AF34FA0FF6E0 -:10A1E0001D9FEE3C079E625F9D7CE324AC2BF164D7 -:10A1F000F0350F94AD89BF21E027BFFD4D8C1F3D89 -:10A20000D07A67A047986A879D59FA4C7A6E013DCB -:10A210006197C1B1309EF312F1969276B87AF253FB -:10A220003F3C9A87DFAF24971DCFED3BBB9F62F683 -:10A23000DD5BDD9B7F7894CAF8062F8B17F965F3F9 -:10A24000B7A0374EF1FD330DF93779F2B3C1CBD654 -:10A25000D11FF8FA8619067F1CFC6798DFFEF67599 -:10A2600038EFC5F0A6FAE00F4C1FD87E38B3E77779 -:10A27000B495F63B26F35CCEA21E2896E7F20129A0 -:10A28000217B97E5E927579E8BBD9E075799244A66 -:10A29000E7695B35C9C0F912B9C6241B417E056266 -:10A2A000F41AACFEF872BED5417E14794F16D6C5AD -:10A2B000195D32E05C3235EBFDD4A12C8EAFE49217 -:10A2C0009F72F3B9C5359F0D5EE77C8A245E0586D3 -:10A2D000492CAED46D02BDA3CA06AC4FEA1FE8F903 -:10A2E000FE8F3D9F64058B8B896A86141A7788EBF5 -:10A2F000F1A4D7BCD40BFB8D377902F4B0B54A4634 -:10A30000FFD85DFFE35EE6BF0D3612C962792DA866 -:10A310000749A769C2B95F4AD0920F6B887E1CCEED -:10A32000BF4097837FEF8BBE6EC2BA7B5424C9199E -:10A330006DD45FF63622FF77ACBA8BD9A1EF2582B8 -:10A34000580DF52DDCDFEA4C4DB0EA26F3CD88D66A -:10A3500013BD314F5FDFE4657A6DF2BD15BDC9F104 -:10A360009ED9EB83216EFF697DD11B4305DA571718 -:10A370003EB77E1FA7F3262FB747AC3ECC83494597 -:10A380006E3804269B74CD607A3D2D4D2D89725B0D -:10A3900040BE6F02F9F352F9663B15936FDB5E28FE -:10A3A00036FF6E3BC1AD7F2A3DC78DEDB9B9E438AC -:10A3B0006EFF7D90E7BB516977F0C9C7D7F942BE00 -:10A3C0005E26EDA934870DE48B0FFC7D3817075905 -:10A3D000C8B3C776733EFA02ECBD1B0FEA676F0184 -:10A3E000B9F385991F8E8B11EC3AC970CCF7047FB5 -:10A3F000F879E8418E4F2C7D358B0B87EC7CB94A80 -:10A40000F547E93C39AA3F1E28A53F4894C5016C91 -:10A41000FAA7E2C9F814E5F33ED430EDF8C42330CE -:10A420007E09BEED3F1FBE8DF03CBBEE811F1FE1DC -:10A4300079094EBD7DE93A8C9F15C393CAF5A8B73B -:10A4400080DE7E17E7E1BBDEDA0B9F07BB5E51FEC5 -:10A45000F37AFE2DA27E9AEEBB8D928576D4B0BEA5 -:10A46000CB427B0E6885FD3EBD08F3CD488CA07EB7 -:10A4700084869037E5D74DE45F801818D793EB9D1D -:10A48000784A11E77943B4CBCADAFD82FEF66F91C0 -:10A4900071DC89B896CAF2CC6C3B149615F82D3E47 -:10A4A000F2F9638DAC1DEAFD62F44884E90938FED7 -:10A4B000017BA358BEDB24FDCE71A21F8A97D65321 -:10A4C000AEFA4495F4D70B9C234E6D2791D7F3F445 -:10A4D000DB5BB08EF3F213CC27D77761BE1FF11888 -:10A4E00010EFEC8BAE23094AE720617A2505E54A97 -:10A4F000C83F59ACE13985CEFC3F8FC2E4F125AFAE -:10A50000EE88DF8A2AF3A7ED7AE5E6FF6EBA3F15FB -:10A51000B28F2E97D97EF1D61792BF87BC066B44B7 -:10A52000D0C10E3EDD9D43FB6A43F65219F2D716A9 -:10A53000CA33B1DE863D8DF2EA7C7B89B0BC018AEC -:10A54000889CBF3EED7529A77D4780EE536916179D -:10A550003995FE57CC0B38B54F443BFA54EA832566 -:10A56000D7D369BE8FDBF54EEF134DF453524266DD -:10A570001E6D7F5A32C305F308A8994EF2F4DC270A -:10A58000D2A2436EDFBA3F2183FE39DDAD08BFA200 -:10A5900073752BD049F1DF906E9421FE558E2E48B5 -:10A5A00067CFDF376C3AFB55E6D7F5ABCC4FE9D731 -:10A5B000DE447ACFD0E7A5FCA614A7B35F2BAC5F2F -:10A5C00094103BBF55BC56E1BC0917BD7EDDB94EAA -:10A5D000DF69FC8655765E3B2CA595F3C127645A4E -:10A5E00002D8D11AC9A6203F9FB2F165883360888E -:10A5F000918ABA76F229E19314AF1FAC574D210A24 -:10A60000F057858B28AC513FC81B05FFC373F85525 -:10A61000BA8E86BB8218471E6CDD7418CC84E83D68 -:10A620009FC5D0D33650F6183F7D5F5F7B0B5F67C9 -:10A63000B4F3CF0C76AC8678A544E23CBEE1D125DC -:10A64000DB5F2BB0BEF3FC65E19C6FB25D313E0574 -:10A650005CFE908FAC2DAD9F36337D66D17FA05FC1 -:10A66000A2AEF6336F71C6C1359207D3F73B65C210 -:10A67000E33537BEABE3CC2247141DCFB13C5A06BD -:10A68000EA13AB1AF2A742098980DD3EAB39D10E3D -:10A69000FC2FC7F761C2F2EA08394EF2D7D5DF7254 -:10A6A0003D547FE79705B0A7CF18540A1601AC2C8C -:10A6B0002A645FD8F95A1370EBCBA80F0729D61874 -:10A6C0003768F5A0DFBBCD38A5E5AFA7EFF1712660 -:10A6D000E79FE8D2723CADC5F9970D8FE95F78FE30 -:10A6E000F32F4F73FEC39B9D76F074E7E5475C0F35 -:10A6F000959BFF0B1DC79EB7A9EB83E9C3FA3B9F50 -:10A70000C57CC5AD2DA5EDA3A9F37604F7B790419F -:10A71000CC4C81763F9505977DCE4A8524899177EB -:10A720000E255EBE7C1FE415151B574CB8FC0DDED4 -:10A730004FEE135412F15C442FF33DDCE81E89EE1A -:10A7400087C12D57ED919640DE9689F95FC3DD26CE -:10A750003E9F987F9F87E32B108FED5FEB782EBA9B -:10A760004742BBC243CE2D21C861DD963B02F53A7C -:10A77000F7480A3EE5F905B4EA4C6847D06E5D0437 -:10A78000C19E5A3CBFC77EA023A827912E06D38620 -:10A79000006FF59A669CEBE53BE97AD8EAE7B0CE24 -:10A7A000E16A0E6B1C6EE430D9857050A630C4E9A6 -:10A7B000BD690DE100871B395CC3E16A0E37715832 -:10A7C000D885F05699F537226558FF010EEB1CAE7F -:10A7D000E1B0C6E1260E93036C7C1F8303DE0CEB15 -:10A7E0003FC8E1460ECFE0703587E7725838807079 -:10A7F00051BD1C3391BF93F3DFC9F84608F72FE32F -:10A800002EB86BB27E9EFF39D0AD0BF9E78ADE22FF -:10A8100071A7C53EA667C6DBE398BF44FD52EB5463 -:10A82000FE792475A00AC52D4DDE6EE23C3D5278BE -:10A830005DD8EBCEBD2E2AC56FCD79E2F7A1FF2002 -:10A84000FC3EECB3D73DF3C7C7DB0DC4D3DD9FBBE4 -:10A85000DD08D52F24CFFF0F48190BBEDBA0B60FA4 -:10A86000FA355EC599E77AB7CFCBBE5BF1B13CD77D -:10A870003E8EDF783B3B8F189817C81C10A6C61772 -:10A880003FE763FEFFF76D3C9551F48F8239BA6262 -:10A89000F3FC9DE1584799FC75E9DFF3F314DD7192 -:10A8A0008F7F8577749C805A984F774FE89B5BAC7D -:10A8B00053B4AEE2A7CFC16FD122D1FAFC7C6AFEBD -:10A8C0009E081E11F5CB595ACFCE2311B17F3C976C -:10A8D00020F52CEE25F2FA384E23FB8EC15C0CFBE2 -:10A8E0000C7DDECCC711A6F6EB6E97F5D5B0F9E27C -:10A8F000F8D8792B22791EFB99C0478A23BFDCCF79 -:10A90000213F59532FFCF985C25EBDC87869763E58 -:10A9100054AEFD135C5EA6C86791797DC467DB29E0 -:10A92000A3269C23D97264CBD7F9CAD105CB096C75 -:10A93000484B8BCB894592B86E247025174D5F5ECE -:10A940000AC84936BF7EAD52CDCFF90D94178A8F14 -:10A950008472AB317C6A1747B03F01D6389EB7701E -:10A9600018F840E9BD5CA9E67C60F18C009C3BE6F0 -:10A97000B5A7C421BE02758698DE67F5AE51D83AF8 -:10A980005FD551CFF027BC7F17BEB43F25BF3F91A5 -:10A99000D4BBE49CE1FDD70A9B5F5A9FC55DDCE315 -:10A9A0004B02E22B92B8E5A1ED3EC3EBBBF5975D00 -:10A9B000DECFF11BF690CD2CCF234EF2BFAB0C2A8D -:10A9C0001EFEDD235B676EFDE405B95A72FE72550B -:10A9D000A95EAF550AEF3B54CF37437CB6D8BE7360 -:10A9E0004299D80F9AF9BC4D6BDE7F077A68D9E49B -:10A9F0007C568AEFE57CDCE9E27B7A2ABE15C9D970 -:10AA00009B5C4F548ADF35E789DFCB2EFCDE29B90A -:10AA10003ECBF7A34AF1FFEBF394877F9CCADF8A12 -:10AA2000D69147991E7F3F739EF8FDD28D5F917539 -:10AA30002B2B8C5F1661F221A904E33395E2D75DDD -:10AA40001E3FEE8FAFE9376368AFA13FBE5D59D3BC -:10AA50006F4993F89984E9F5E98EBFA3E2F1DFDF4E -:10AA60006F4A93E37F5179BF637C89CA0F085BA566 -:10AA7000E33E56E9B8D64D0EBABF96BAC931EEF9E3 -:10AA8000F2FDEB158FFF5107DDCFA73EEAA45B3542 -:10AA9000304FA4D271FFE13CD7FB6F38BE41457304 -:10AAA000EC03C5ECF7B3DCAEFD84A239E4B858FD85 -:10AAB00037B9BDF2BE0AEB9FE6FDCFB5F12953FFD2 -:10AAC0001E8EFF3D15D6FF1DC7676585F87C9FAFBD -:10AAD000C362FB6780F33D083A32CFAFB9D03CA6E2 -:10AAE0004DBE84E08773CD67BBF1FBC1372545833D -:10AAF000F377D249D01EF79F0C1DC0DC4C3BCE4CE7 -:10AB00001296C0F430C6B7BC11239AEF5FD87E9777 -:10AB100024C5CD42E76BD57EA6FF04CDE862EB5D90 -:10AB200026F03D47B1FA417FE1F84B1519CF421E9F -:10AB30002F89F2F3A2B31FD40BC6FFA57802BFAFD3 -:10AB4000D6647200E2CED5EB1CE7F9311B9FA889D1 -:10AB5000F8C81AC347960CB350FE72839FCDABDD85 -:10AB60008FED1F0AD171C2EE7160F80DF8E35D78C8 -:10AB7000DE5F2D239FFA43CEF3F09B793F7FC5E93B -:10AB8000EBF796CE1BEB98D9AA40FF7DAD2C6EAEAD -:10AB90001303CF05FBD5D2F71A6CEB66E78123FCD4 -:10ABA000BBD2147C573A1FF2A4A23C3FEA19FC3EE8 -:10ABB000EF4C8BA7E4FD3821C3193F0F363BCFDDA7 -:10ABC000EC78BB5F777EEFE38B3ABFF7F1CE943C36 -:10ABD000F87D91CAF2B1CAE16FE773D9F586A4A4F2 -:10ABE000A215E453C611EFF7459DF8BE7BFC63ED5B -:10ABF00083DE51AD105EEF14DF8AC51B26E8AD92EF -:10AC00009319A6371CE7D4DD5CBE7C554A12F4329A -:10AC1000D5BB45DE07587B358E790A4A34AE633C96 -:10AC20009AEF030AAC873C3E3D68AFCB80C7CE436A -:10AC3000C6FB5E04DDC4734605D69130B5DDC4BCE9 -:10AC4000DA72FFF66ACC4FB46A155C27823E8EDF5B -:10AC50007BB9C799EF3777F96939C36FEE86D2FBB5 -:10AC600027315168BDECF4333DAADC10D79526742A -:10AC700055D1EE71E3F10DBEFE541B7FCBC473EED4 -:10AC80004AF17FAC42FCED7128FE5F013D4BF1FFC4 -:10AC90002A94C5F07F8AEBA31AA2F7E09EAD333D5C -:10ACA0004BC88D7A7E7C3D1060FDD6703D4548BB1B -:10ACB00023BFC4CBE9AA949E43B65E2B438F3D2E9F -:10ACC000A5E7289F8FEF959A8F17383D8100DBB756 -:10ACD000947D719D2E4D7249917939C5F19819E095 -:10ACE0007125AB7D5A72F5A30AE93835392FAFF2D9 -:10ACF00079F965293A4E72B94A8B64E569D84FE70C -:10AD0000DA790A6B1DF33287F327EDB3E7A5C33178 -:10AD10002FD5D39C97DF5648CF9CC979798BCF4BE1 -:10AD2000AE949CE5D57F9BD7FF13AF8F76E29CC096 -:10AD30001FFBE1BC6CBE3FEE09D44EEE6FB49E1813 -:10AD4000583659EFC1E163763D1FD6EB9CA8A704A6 -:10AD5000F2FA23D66BFD70AE3DC0BF0BF9FE70E872 -:10AD60003DBC5D18DBDDC0E8A1EDAAF2FBFFC6F03B -:10AD70002B76FF33A05ECFEA3FD9F522F9F5E60442 -:10AD8000FE64D78BC27361DF447F75F9789CF2FF54 -:10AD9000733FCBCF71E5776995E531782309BCE73F -:10ADA000A18684D290073B28B17B172C6A541F845C -:10ADB0003C595F224B2AB0BB3C0A6BE7A3F6167CDA -:10ADC0005F36432387FD3AB82006D907F9AD11094C -:10ADD000FD813BFD89A5815A8627C8CBC0ABCC1E1F -:10ADE000EB5197F2380AC36B67F06329E84FA378F9 -:10ADF00041FF0F06C387A1FEAE065907F93ADC7082 -:10AE000017DA893B7B2402EF775E2FA39DB8FBD531 -:10AE100010EEC3039281F9D59629EB6037DE1DF859 -:10AE2000D3894D141EEBA9D284AB911EC4DFF290DE -:10AE3000781FF6CFECCE2D147FC80BC6AD0BFAED04 -:10AE4000647E0CFDD541FBBB57EB984FA313767F77 -:10AE5000D350AB8CF9483BEB9BDA61BCDDAD0ADA31 -:10AE60001DBB6F68EAC13CEDD600813C801A5517C6 -:10AE700020EF31BC422616C011BD07ECCED0F20047 -:10AE8000E446929A7A365E683EC17BFEBC241D8FF2 -:10AE9000D1329C9231BF77F70D6B593E69AB4FC3EE -:10AEA000EFBC2CF3E5D872C25295E127FE23017C5A -:10AEB000BC734402FCB7E7399C9E685FF21C319C6E -:10AEC000A9B05EB6B27AA19484F74E95AD97AEB0B4 -:10AED0005EA6C27A5956AFECF93DCF9F54E83F8841 -:10AEE000C3F95DE7B760C797FA5E6EBAF9B93B037D -:10AEF000CEEFE9CAB5B7F372CBD10B879913788A35 -:10AF0000E5EB97FD1E73E65D51F83E6DA8F65E5EBB -:10AF1000DEC7CA3AFEBC6E4B14EF8BACE3EFEBEE30 -:10AF2000C3FB23DDFDFC0FAE8F9B49BCE43CD4701A -:10AF3000FC5FA7B8433CBB592A930F10F1B8EC4D06 -:10AF4000A7DE5324AB03D7ED0D2C2FC707CA00D6BD -:10AF50004D3D5BC75E928CC7309E658617CD9C5C6D -:10AF60003FDEB61771FDFCA04E24422BCE0FFB8EA8 -:10AF7000D225276EB9F0B9CEF52F544E7EFA2EC9E0 -:10AF800089372556B47EBCE90AEB652AAC97ADAC8F -:10AF90009E9C122AD22B72BAC27A990AEB6559BDCD -:10AFA000819532DFD7870720BEE5BD5271C00357B8 -:10AFB000069CEFAF521DF0E032677B79B9B3FDE03C -:10AFC00072677B79056B6F04F7BCC78A55BE4EFE6E -:10AFD000CF79AE9366A574FD506B9975A5687E68B0 -:10AFE0005F23E904EE1DA2FB5586EF5B05E33F6B93 -:10AFF000826CFD5F1FD01CF7D3FDA5D3D91C64F86C -:10B00000DAF496C3D7D6BFFF57E47657913CFB6A74 -:10B01000D03990774DB275D0EFE13BBE550776E55C -:10B0200023AFADC07B3DFADE67E7CD1898F7239DCF -:10B03000F8FECDA0C71E49CA04F2711EAD368E5D62 -:10B0400012C1EFC908D8CBD48DC2FB3E1ED92CA1AA -:10B05000FDD1775BE97B4DBED1CDF284FE8EFBFD49 -:10B060005FE5F7713DC5EFE37AA25BC7F260773326 -:10B07000965FEA36B07CBCBB15CBFDDD26EE1B5FD0 -:10B08000ECEEC4725F771CCBBDDD5D58EEE84E6020 -:10B09000B9BD7B33FF5E2D89E570F7162C87BA2D7D -:10B0A0002C07BA5358F675A7B19CFD3707862F5960 -:10B0B0008AF99290A156147FE37967DC61E1B301CC -:10B0C00007DCF23567BCE1B22FCF76CAC5A34D8E3F -:10B0D000FA97ECB9CCF13EB66DB1E37D53FF950E16 -:10B0E00058BFAFC3015FF4D9BF72B4AF4BAC75BCEE -:10B0F0009FD5F56167FE57DB06C7FBF0D24F3B607B -:10B10000B5E54E47FD40EC5E070CF73EE7D7BF3193 -:10B11000D8C4E2819111473D49DDE5A8F7A999E638 -:10B12000FE20C443D361B42F1F3929E03E38E32207 -:10B13000E3359027F25311E5895CCBF2DE673425C5 -:10B14000AF80FBCB88945CF1C150F97BA4ED788F84 -:10B15000186E4DC03EFBD66B820EF6AE10DE323F4F -:10B16000DF9FB3CBCD67926414E2923CCF4C9B4DF2 -:10B170004C13FC46AA4F08DAD9C9ECFD18B7F4E025 -:10B180007753692181F74E539BD9F8EF1AE4CBBB73 -:10B19000F7DF20DAE5673482EBA0BD4369ECA7ED69 -:10B1A000B72F90F17BBE29F8BABE8B7923C8FCD7A4 -:10B1B000ADF7B378A576C4DFA82C85FB321233C077 -:10B1C00055B5DBA9D997F0DE5335662C87AB01D492 -:10B1D000E60CD9A842BD2CDEBF40EB7F1396FD44A0 -:10B1E000FD4D594BA6CFEB3627E6C2773DDB79FF05 -:10B1F000DB0FFF8C5C42F91A5A7A9CDC8AFECE5E29 -:10B20000E45FA8758CACC95BBFDBDF2EFCBDD12F22 -:10B21000832CAF667B8F85F7CC29D96FE37DA8F6A9 -:10B220003C045B8E9304F4DF368EF7036FBF9F7D83 -:10B230008FB75DF85134CAE9EA71D285F8001DB7BD -:10B24000523DA7DE9214D6B4B0E773F3FA85F71B2C -:10B25000E17DC212205FBD127EC9F07C13E5179D0F -:10B260000775734628C9AF58967D1FD15C845F94DB -:10B270003FB7A29F3BE8881BDA7CDADE739C2C6F19 -:10B2800001FB9FD59FE02BE5C3AD797C9CE0C7B265 -:10B290009F627E6BC8FA1159A2B276406F88D2B70E -:10B2A000B100DF29FFB07F9B1FF63821CA2F869798 -:10B2B000657FDF88F775DAF91F767DF8752EE7F977 -:10B2C00087941FDEB1EA8DF03D687B4B02BF131EF1 -:10B2D000503D789FD080FA4CD6C3E519EA4992D9FF -:10B2E000FB639E67DE2B145A7F4EFB1F32A6F3BF13 -:10B2F0000BEB57D9BD990391327610BF2F58E4F765 -:10B3000005CB52BCB391AD53A3874CC64DA78EBF9E -:10B310000BE916A3CE7DB57F93733F8B691FC6F8EB -:10B32000745FA403E16279F976E9CB31BB51E6F8A9 -:10B33000787341768F71CE8F789AB919585E93AB36 -:10B34000C6F2EADC1C7CBF2A5787705B6E2EC257A0 -:10B35000E51AB1BC3277393E5F99BB14E1D6DC12F5 -:10B360002C57E416E1F3E5B9AB105E965B89F0D299 -:10B37000DC6A2C97E4DAB15C9C7B2FBE5F94BB1E29 -:10B380006123F7412C2FCDDD886573EE23F87E7E97 -:10B39000EE66842FC96D44785E6E3DC2B1DC6710E5 -:10B3A0009E9BFB14964DB9FF8A6563EE0E7CAFE75A -:10B3B0003E8FF0C5B97B10BE28D7877043AE07E13A -:10B3C000FADC5684E7E486B19C9DDB8D655D6E27D3 -:10B3D000BE9F957B08CB99B92FE1F3EADCE3586A6D -:10B3E000B9AFF27BA09FC2329CFB2696A1DCD3F8BA -:10B3F0005ECD7D07E160EEDB5806722F60A9E40E9A -:10B4000063596E9EDCDF2F8911E7BE7C0D99E190B8 -:10B410008B5539E7BE7CD57893035EF96BE7BEBCEC -:10B42000626CB1035E76C2B92F2F39DEE178BFE8D6 -:10B4300098735FBE34EBDC97E7673EEC80E7EDDBAB -:10B44000E0A83F37FD6907DC98BAD351FF62CBB95A -:10B450002F376C71EECB7392230EB86EF32E47FD2F -:10B4600059E461877F58DD75C051BFCAFC8AA37E4D -:10B47000A8F519D7B94986E979E339C773A5F94819 -:10B48000C1F395D89EEB3D6F803ED13DFC7B7A7E2B -:10B490004F2BBF0FCD3D9F355C0FCCC831BF28C2AD -:10B4A000D75D2DACBBBC7C266A3F3436417E08B7E5 -:10B4B0001F6634E94F1FA5F05B4DB2D14361DB7EBF -:10B4C000B0EB97FD7B14FC3B7D1F7CA7AFA3FD80F9 -:10B4D000F7B7DF7D4AC07B1E6AE6107EFEDFD90922 -:10B4E000FB5A0A6C69767F0EDEE7936AE0EFC9FAD1 -:10B4F000EBF07D23835FD876EF1A88A3A6BC76FB9A -:10B50000AF5E07718B949FC12F6F5B3F08EF6BAAF3 -:10B510001275B09FEE2D726EF973957DBFAEAAE6DF -:10B520004B6AEDE4FDD1BF8824FE37C0B729898B73 -:10B53000E12A6EB8BF1EEE67BE56327F00CF3F20B5 -:10B54000993F54715F70FA05EB20A7B516FFAEC4A2 -:10B550002B2ADA4F87703FAA79EF36FCFE3315A20B -:10B56000F8A8C5F139A68A13FB0DB1F79B268C9379 -:10B57000A29D37D840F0BEF85475DC82FBFBACEFDF -:10B5800029E4A00174A7591212CF3B4C5DAADB72CB -:10B59000E1D89FE09EBF0DF47D30A1EA6087A9E469 -:10B5A00038E65584C938961AD104C73DDA36FD0D00 -:10B5B0008C7ECA9771A04B26E6A1317EDECEEFA528 -:10B5C000FE17CE9737D565C5F9F21EF13EA2D1F12F -:10B5D000F7533B11F6C5FD5081D2F17494FA9D02E8 -:10B5E000E09988B760BFEC7E08FB7E38E9E4B7F1EC -:10B5F000DE063B8E23896D9DB83DB730BBAF93FE11 -:10B6000003BBAF36EEB423DDDF9948AEB8CE74E3AA -:10B61000385521771C47C573E2335D1EBC57B158BE -:10B620003F763CE7E9AED2FEDCD7F97AFA1ABF17CB -:10B63000E42BFC1CF7497E8EFBB7E0CFD1F2CBE0C8 -:10B64000CFD1F200F873B4CC803F47CBC7C09FCBBB -:10B65000FB6EE4B122F7BC5C526DE72B6C41BB3D45 -:10B66000C8EFD9206414ED7409EC742A574F1FED0C -:10B670009D19A37CA7BE06D2B7F9FA0EFC8E9F0EC9 -:10B6800061C077FEB7BFF1FACCFF1281AF6FD9F777 -:10B69000C3B43EE6494A2DEEEF48CA8C2399A81759 -:10B6A00082D41F481BC5F933ED7E1513AF6C9B7E0A -:10B6B000BFEC3E9FC975D389F924414EB78F7C07F3 -:10B6C000C739C3FD1922D6FF2FCC8FBA4222A5BE9F -:10B6D0000F9C32CE34E5EFE365E40FEECA44BB3392 -:10B6E000C9E663E173C7EA0ADD0B61CB61CF6B3E4C -:10B6F0008CAB0E7D8FFD1D8AA30DF21C885F8C1E06 -:10B700007EB111BF5FE4F2D877D4997F509F244275 -:10B710007EBF0F75B338445F84F5ABAB2C6FC14D62 -:10B720008FFD5D53AA4C3EC3837CDCAF07CDFB424B -:10B73000A80FB378EFE3C2E7948F00BE8FDEA114A9 -:10B74000E4F3D78389FE50ED543CF3DBE33D14C5AD -:10B75000DB6F0B2D2BDEBEE519E517A474FB3DA5B1 -:10B76000DA5FF615E59132F83F5A187F6B3FB4ABBC -:10B770008FB2BF4BD653F7FA81AD14DE7B07F38748 -:10B780008FDEBC0EFFAEC3402D9BB702FD3E510ABB -:10B79000AF85CF757595C1EB1BA5F9DAD55586AF89 -:10B7A0007F5FAA7DCB335D27CAF0F5BBA5F9DAB57B -:10B7B000AF0CFEFFB3707BEB62D03BF53A8BC7F565 -:10B7C0003452BE523C866CBEBAD643817E5F2E2771 -:10B7D0006F65F0FA79E979292BAFA74AF3B5ACBCCC -:10B7E000FEE602E5F5CD227CDD0F785F80BCBE7DF4 -:10B7F00081F2EA0D5F98BC86C225F5405979AD2DDE -:10B80000D5BE02796D2884BF8F044DB0A7CFB4B0E8 -:10B8100073AFCDED1EF6F79134A6EF8327AFC37D4E -:10B82000B49FEE53335A61BF3EB5F7F6A593FBB311 -:10B830007BFF71F7E7DE3F6FFF973544A5F022BE2F -:10B84000EFD9F80462EE7E4ADF2F31DD7125FE77F5 -:10B8500096ECF6B337BDD3E339F777E9281B9FD0D1 -:10B86000F157E33921BB3FB7AAD51D979CEEB8A588 -:10B87000EB476FB9307B607DD8793FD49C2DDFDCFE -:10B880007F3AEFDEB039FC3B2F2FF910DECF446E4C -:10B8900063F940E296A7F79F5E92774F141915F26D -:10B8A000F37FC4DB46F79FCEA33B07711F8C1F5B62 -:10B8B000989718D3AEC4FDBDDC3EFE28DFEF1FE62F -:10B8C000F6EC3E7E3EB1979F4FA4B93DFB003F9FF3 -:10B8D000D8C6EDD9117E3E91E2E71303FC7CE279F4 -:10B8E0007EBEF05CF73E7C7FA83B83E5B7BA9FC481 -:10B8F000F2D9EE517CFF4CF7218447BBB3CC2EBE6E -:10B90000E756CC839DA4C3E474DC8BF7BCF4D797D3 -:10B91000B6CB1B92CE78C89CCD01D73981F39C62FF -:10B920005697332FB2DA74C643AA5A2F73DD47EF06 -:10B930003CA708365FE9BA8FDE190F9123CE78C88D -:10B9400015879CF19005A3CE738ACB9F749E535CA0 -:10B950009A71C643E6EF739E53CC4BDFEBA83F379B -:10B96000D5EB8C9F58CE78C8AA71E7F9C455BF7E35 -:10B97000D819FF1973C643569C70C643961D7FC6DF -:10B98000012F39E68C837C2098C8823E5C9475C771 -:10B990004332A84F7FA2B2F33DDBCFA6F55F0CA3E5 -:10B9A000BFA966AFA2EBBE6F33BBD7BD8F687E0D5C -:10B9B000F5F067D16FF04EDCCF1CCFDE1F99D43F7E -:10B9C0003BAF3DF553F06BBC21764FE5EDC27559A9 -:10B9D00092EFF778DF12F2CF23A588534F94ED5FF3 -:10B9E00062F7107AC12FD18ACBDDD47EDD7EC9B556 -:10B9F00059C893F2025E06EA1B1C27CF2F1946BFD7 -:10BA00006496444AF9A753C699A61E7AD3A58726F9 -:10BA1000FC9228BB2F4597482FE0B1F7A8A7E0BDBF -:10BA2000BFB61EDA192DBD0EED3C979D5D95E56301 -:10BA3000EF3C5ABA9E1DBFD2F97DEC5EADF0B9F76E -:10BA40008B619657F9C12AC2FDE6FF2F3FEFA4FC98 -:10BA50005C59F59F467E78FC72E3107CCF24BB6076 -:10BA600091C3E1AA4FAF81EF9BB610760E445E61A1 -:10BA7000F7AE961B27D6F6D1CAEEF5D398BCC65AB8 -:10BA80005761FE24DE33562A2EE1BA57CDAB5AF069 -:10BA900047F726FEFEA3BBFECF6B58FC28D6F5B1B8 -:10BAA00092F6CD41BEFF7F89EFFF31B3F4BDBB8F6E -:10BAB00071FC5F787516DAB57B6F637A5BEAFA879B -:10BAC000C3609F8D72F9F791CFF85B80AEDB2402E3 -:10BAD000E7C373419669FD8B55928173D02DC440A5 -:10BAE000B9A63F3C5FB6FB176F73DA5B7FB0F91402 -:10BAF0002FCD57FB9E4CF7731FF94E3BF25727C9CA -:10BB000087ABE15AF52FC4FD149E534B10AFD41EE2 -:10BB100003ED2E99E2A11558A76E7CECF5697F4FD5 -:10BB20002A6DBADA82F673043BEE1434204FE78CA8 -:10BB3000AA96BCFF6D4ABFD35C8F5F9BB21E6FE8B5 -:10BB4000FD4964F2FE2BB285FE964FDEEF596C3D47 -:10BB5000DAF00BAF0EE1772D29D5BE1FD0BE4F8B8B -:10BB6000948C9B6EE57C1FE6F92D5B5B3A7A5F87D0 -:10BB70007353BA5EF2DB05173C8B71C77EED19BCBF -:10BB8000C7689BC1BED756171D55C01EE8D78EE0AB -:10BB90007D71C1FA7427DC3718A472043AD03F6F64 -:10BBA0000F7FBF0BDFABF599149C7FA8F09ED235B9 -:10BBB000D2FCCA61F89C3B50FDE6E10EA85F3F7ADB -:10BBC0000CDEFB3582ED2575F47807C8D966827FD7 -:10BBD0006FCBE2F72A356435CC5BB858653049D075 -:10BBE000F73ABED756537876177B6FA819F4D74823 -:10BBF0003331597B8A1F85A347359CDF996A3A8E7A -:10BC0000FD4758FB99C6B326E0311C637FCF47ED53 -:10BC1000228F031F16A90C6FF8CE8C8DC3E988B153 -:10BC200071BC6A26DD017AA6DEC693C210378DB0DC -:10BC30007164957D0F49C7C7FBA67C2ADB0727F4F3 -:10BC40004E5718C73B13218F97FA7B01F67A7F9CDA -:10BC5000DBF9FBB99D2F2973BE783AEF3E867EFE55 -:10BC6000F7421B55E777987FAC62EBF1C51A9667F0 -:10BC700056EE1E49F259763EFDFF00D7C62C0E0047 -:10BC8000800000001F8B080000000000000BC53D75 -:10BC90000B7854D59967EEDC796526E126992493D3 -:10BCA000D7E426241021E0000141B19D445454D42E -:10BCB00088B6069F43409E01026A89169B9B172403 -:10BCC00021C0A02E445E99605154D0C18252ABEE87 -:10BCD0008029C5D6B6A9F54195DA08181501532A69 -:10BCE000CAEEEABAFFFF9F7B93B9934982B5BB9B2B -:10BCF000EFD3C3B9E7FDBFCF7FFE738631C6BECD9C -:10BD000081FFCD8B61212BA33FCAFB1258283F2C0A -:10BD10005F9AA6CF7B72F4F98211FA7CEE587D7F90 -:10BD2000CE4B75E55F5DCF58870332A2D7CA0A2094 -:10BD300039F2A0B52496B1BA8C1A2B83EFE7EFD174 -:10BD4000CA991DF3B9528CC09C8CB5960A81260302 -:10BD500063C115350D79858CADCC10189321754DC7 -:10BD60001FE2837ADFE2DF0FFBA6DBAB180B0D6768 -:10BD7000ACA9CA4F6963550B0B59185B953170BB61 -:10BD800000B6837ADBAAAC946EA992A8FDA62A1706 -:10BD9000E55BAA644A3754E553EAAFF2505A573587 -:10BDA00091EAADADF252DA5C3595D2BD552554FE1F -:10BDB0007C5529E583553E4A9FAD9A47DF77555517 -:10BDC00050FEE9AA4ACAAF1E23DD5E02F0D959A58A -:10BDD00050FE89AA064AAB2558F77828BFD2E3C29D -:10BDE000F2DA2B596930CA3AAA2503D55B23012C14 -:10BDF0009318B3318F6006B831C8EF00B80D553CC9 -:10BE00003516C827DFC1088E432B3C356680B33416 -:10BE100085E7D7E138D0AE92312FC376B92CB02365 -:10BE20009BB19C06F69601F2AE7CA9CD98DD3BDE77 -:10BE3000F5EA7850EE12A89C05B0FCB8D97B839443 -:10BE400084FD312A1F16EA1400DDECE2B742350EFC -:10BE50001867D41B811A23E4474E56044C630BFD2C -:10BE600082AF00F12A14E338E75608D48F5CC80487 -:10BE700001E61774713A585D04F0095BB7EDFC36C2 -:10BE8000161AC758C38AE943D800784D29157AE9AC -:10BE900011FE8BF786D13FFCD710120E1A619C73EE -:10BEA000406F2CBBFF7E2EDEAFEF675430A29FD2D7 -:10BEB00081E73172A7BEFD458188F640D7C81FFDD6 -:10BEC000B51F76FE065A6F7F747CCA5C56258DEFCF -:10BED000CD8BE77FC042898CBDED90080F09D73527 -:10BEE000BB10CEF03705D72B6630822BA03B540613 -:10BEF0007913FCAB09AA8A0592978DC65456538FC5 -:10BF000097C561EA55F325947FDDE45B83781625B8 -:10BF10001FC3F920D9205FAFBE08FE9986F9AC0691 -:10BF2000EF64C8FF08FE792963374A23A62A90FFE9 -:10BF3000CAE4132A61BC3DD942603BC07B79CE582C -:10BF40009203B58E81F9B34EE5CF9EF549255E0388 -:10BF5000F4935E2E8D453AEAAFDDA3E5CFBF3E0CEC -:10BF6000EA294EC19327F72DDFA5D2F1A325C214EC -:10BF700007C22193D3B1B69EC8FAB0EE5DB86E93F6 -:10BF800093AF3BE996124A73775D632D1905EB8BEE -:10BF90001F980EB644AC2303060A46C1FB499C1702 -:10BFA0008C93FBC67C1BF53B63E07E1B55B9773E4B -:10BFB00020B00EC4B35841F236E9161FCB85753553 -:10BFC000A40A0107ACABE19B7B1BB2111E070492D4 -:10BFD0000B49B754305F41DF71C5DCEE6A01E9F20D -:10BFE000C07C26C3F8165705530A30AFC96B9F01B2 -:10BFF000E7932C495750CA025EEC3F79854FC171D7 -:10C00000CD2E3FC1A521B5A7BE0DBF6F080924DF06 -:10C0100057CAC06F064A9903F9BE82513E23F561A3 -:10C020001A977D0DF39900FDE0BF01C1960CBF1773 -:10C03000E541C345CC8372C496CF8ACCD928A60EDD -:10C040001B50AED91E609E269C6FEA130ACA23E5D8 -:10C050007246F80605C7107E30BEF526C0677ACB5B -:10C0600068E20B5B6EC880EBBEDDECEB427C6AEBFA -:10C0700037BB3A091E0DDF184BA3E1E537AA9CCC6C -:10C0800044BC45C1476C3C97D75F9982D7A01CDD63 -:10C090009324B0ED86BEF52C6ABDCDCEE97F94E544 -:10C0A0005EFED4CADFC64586F173FA7933CD3BF71D -:10C0B000963B87E07AFAA383552A7DAD1BC2F540F3 -:10C0C000EEE43BBD08EF73F05F5394792C182253D4 -:10C0D000BD9EF53B059D5CBAF0F989249F724F35F2 -:10C0E000927EFF2A7B607A6D50E7F955A6DE3E10FE -:10C0F000725B08CFAB5C804F19ED0481C5011C5BFE -:10C1000055FA804F84DF20E8A726C07FEB8AB3B6BC -:10C1100002C867BC6D4432017A98A7A01EB15DC405 -:10C12000E941923BBD0CEC9098FC6EA2C78C8A4E04 -:10C1300003A680F7BCF8F1480F1374F47046D59F3E -:10C14000F057E79AA08A3299F8BE201EBE7B77C1CD -:10C15000249CC80F7C7C13F32A669217952C08E365 -:10C16000DADF32D2779861E8A142945382A7C903FB -:10C1700074D05E938C7C684FE2F265DE35C524BFD7 -:10C1800000049E4D30E6E24FBB929740DEE3E27240 -:10C1900019EA5B719E628159A737061D47F48670C4 -:10C1A000FD7603F3F83DFDC3FF3BF76BF532948F4B -:10C1B000DFBD5F10A4C968DE7138323655C175DB4A -:10C1C000D5755BD8AF689C73380EC2DE98F13B849E -:10C1D000AF78B1C88C51E8B5DF718C770CA83F2AD5 -:10C1E0008FCEFF637B58FDD9F1B1CE2E9804BB846E -:10C1F0005DF22D128ED12120BFA21D40F607F20064 -:10C20000CCA3BE82E363F44B8753C3E9FFABAA79A7 -:10C210007F6C07A5B947D5FBD51F5A8AB1FDAA5F28 -:10C220000B010BB46FCF34A777C2F7E08143D93845 -:10C230002F4D3ED7B6EBF57C46053384F7FB98CA05 -:10C2400017B54EDEAFECF058A3F1FB5AB55E836331 -:10C2500060BB61A33AEEB3766F753CD175C880FCC4 -:10C2600039FA25EBED38DF2D4BAD51E1FCACDDD7D4 -:10C27000189FD4779EE1ED118F03B45F3F50FB828E -:10C28000E7ADEFB381DB3F163FBEFFF6239EB66EF0 -:10C290001E64FE6DD1C7575AB15D86CBCC90CEAB34 -:10C2A00053BBB6AF86FC86A5668F05E8B37DC68F07 -:10C2B0005D88B7FA248EB728FDEE1A685EA35F2A60 -:10C2C0002D1D645E7B076B3F085C5F1E18AEA547A3 -:10C2D00006816BFB40ED473C5DDA32C8FCDF883EEF -:10C2E0007F250BE54E866C263D539D0D704539AE7E -:10C2F000C135821FA2F4FBEEC07019945EFFF63DBB -:10C30000E9F5E381C6BF007AFD7C60B80E4AAF5FF5 -:10C31000F547AF38EFEF41AF42C2807019945E63CA -:10C3200012BE1FBD260CD4FE02E8356DA0F95F00D9 -:10C33000BDE6441BDFC2EC5E05EDA202AEC7E71509 -:10C34000095CAF4B5CDEDB8F5E4D7AB40EF454E2D9 -:10C3500044D4D7C7362C2EECD5CF91FA27B2BF489C -:10C36000FDB9F8EF57919D3B46D57BDA7C6272238D -:10C37000FBB97D40FBEEBB8E2BBA58C816D7DB3E0F -:10C380006DF6BF7A3CBD7E17DBF9F80CC6BF6222A2 -:10C39000EAD5691E84F79089669D5DF9DDC71DB8F1 -:10C3A000BEEB8EEF670FCC49007B6064AF3D905EC3 -:10C3B000F98BD61389BDFDA48B254C72A0BD778B5C -:10C3C00017E9829533CF0E2CAEDCD37A625CAF3D99 -:10C3D00000F037DC14B66F3496075B4F84ADFBFC7E -:10C3E0006CA6EECF14B27773A54B49BF0FA6C7B5A5 -:10C3F0007DE326F44F0D477F94A4FAA35CAA3F4A3D -:10C4000056FD50DC3FD58CFE29F2834DE47682EA5E -:10C410009FAA57FD532FABFEB19754FFD8FEAA0039 -:10C42000A52F54EDA4746F5590CA9FAFDA4FF960F1 -:10C430005588F2DB1E9823233E7BD7E155D7A1F91F -:10C44000F506B6FB332BF47E90F4797A3F482AFA4E -:10C4500023C3F229E1FE4886FE9B1C5DF9908923E7 -:10C4600074E5B19EB1BABC3DFF525D7D9B5CACCB27 -:10C470009B9DD7EAF217EF9F1EE1E7B94D573E7239 -:10C480006759841F6781AE7C78CB325D3ECFFFA0B9 -:10C49000AEFED0861A5D79B6D2A42BBFBCFB615D1F -:10C4A000FEB24F36E9EA4FEADCAE2BBFE4C8D3BA9E -:10C4B000F2F11DCFEBF2E30EBFA4AB7FA3DDF76B70 -:10C4C000948763420723ECF400C9D310C80ADCFF49 -:10C4D000B857485778A3E0F1BF86F07D2BD8ED45DB -:10C4E000642F833C6B1A83ED95121BE4D37F0D34CC -:10C4F00027E396DD676043216DD7CB1F63F977E3B0 -:10C500006BF400607D37FC215FFE97B6AFDD6953A9 -:10C510007E80E3FBB83C56A4008BD64FAD6AFFE6A5 -:10C52000EE9C3184E8532A96A2C985E366DF27E1B1 -:10C530007A4674E8E934D71BCBBC385EB9E637E3FA -:10C5400072CFC8ABB0F4A3571F36A09FACF4D57818 -:10C550009CC73675DC06955F57229F0EC7F55E16A1 -:10C56000B2A870DB04F29919277B06925391F0FA76 -:10C57000AE72CD90A8976B208F431FA1FC2E17039E -:10C5800003EDAF347996FBD6DD03E24783AF8647F0 -:10C59000A3245D81F2C196ABB032475F3819654E76 -:10C5A0000FFFDBEB9623D67D8EBD5CE4C5F309E679 -:10C5B000894A273DEB2DBD8BD6A1E133B2DE0E5566 -:10C5C0000E3FAEE2B54D95C342B347403BAC5595E7 -:10C5D000C7C2A3DE1A84731EECA7713F686EAE0853 -:10C5E0005901EFA60C467AD2E804388CEEED77D8E4 -:10C5F000A37ABF4B6EB35E2EE6D425E8E021AF48A8 -:10C60000FB4EFAB42FDF5D46F68D468783F11F920D -:10C61000FCB743FF99712E8CBFDB672753FF0FAA2E -:10C62000FC0D1CCD5385BD89F4533651252026DFE2 -:10C63000FA3EC075FE611343FFCE0FBF6E3DB415C9 -:10C64000D6619C6891D0DE014D78E815289FEDB544 -:10C6500096607EFED151663794BF930644E0C2F2E5 -:10C6600092389403A7993015FD77A7D99B71E3C23F -:10C67000F4EEB244331FB7C174ACD38AC32B748EAB -:10C68000758F9FE7B575CD6DD1E7E7B0E9C9228C0D -:10C6900033E751134852189789C73A353800FECB13 -:10C6A0001225EA772EAB58897644BD89917F71D1E6 -:10C6B0008BA3CC683FCF1F27651BC7F4CEE3C144D3 -:10C6C000EE673C09F42687F98B173802662FB43BD6 -:10C6D000BE77DC8F2F63D84F60651AFA3BE3C11E2B -:10C6E00091FBC27756837E9E83AD2372DE8CD590FC -:10C6F000BCEF6F1EE24E833710852F1B12B95F5DB2 -:10C70000C363ADF567AD9D304F6FADC86C3F80BC66 -:10C71000C8CF9994A3B1811D28BF8B2B9EEC44BF39 -:10C72000748D45AA8574A3FD67CF61FD4A4018CA80 -:10C73000CB3D8932F7ABDADC013C7F60ACE292E9B9 -:10C74000B1DFBFDF17B0DFA47F7DBFBFEA67BE8B5D -:10C75000AC9D66E4FF2562C55483807E453EBEC520 -:10C76000E4F3A6A33F717F51289DE9EA355C60BDE3 -:10C77000C3869C0BAA375518A0BF33AA7CFBCDAE4D -:10C78000C7CD28CF4E3FFDE10DB82F5AF82B23B36C -:10C7900042BD33BB625988ECBE8019EDBE057B8D6E -:10C7A000DE00E543136E8E0DE7EB5AEA7FE173B1CD -:10C7B000B4AF5AF0BC25300DDA2F78E1F86806F2F4 -:10C7C000E04C4DF7A17484DFD306B2A399D239FAB5 -:10C7D00066F8BE4064779744B1833F48E476C7A9C2 -:10C7E0005FDA4B91DE0C3B0FDC45FD066F3559C21D -:10C7F000F4D8DB8926AD1EF9BD95A70C813C039FBB -:10C80000DF4DA3C2E757CDEB3DC5FDB90BF69B024B -:10C81000369CDFCE36B30FEA2DD9F977A2EF2B9EE7 -:10C82000DB1D877058B2DFA8936B0B9FFB66E5A5F5 -:10C8300080E78546D63D8DF4F8D7943FE7B5761B63 -:10C84000490E79E30C20B71693C8827ABFF8F8AA8C -:10C85000F7A1FCA4CBC86C200A4E767C64FE15E6DA -:10C860007D8E0A5049D0BF9E0F97EC3C6EC6794929 -:10C8700002EBCE0046FFC117617CC9FAD667ACDB7C -:10C880008C727649B0F1EF46A0B7257B4FBF877415 -:10C89000B724829F4FE23F52FBEA4BB333525FBE55 -:10C8A0003101FDE66C276C8226F5AF2F35FE5EB8B0 -:10C8B000FBDC3605C63FF5FC67DB144079F97FFFEA -:10C8C00063DB4F61FEEC559B847269C9D36FC7B1BE -:10C8D00030F8673BF939D399A79E7C6213C0E1CC4D -:10C8E0005F2C04B533AF7CEC96D10FBFE73F92F1DC -:10C8F000DCE9BE57AE4C413ABB6FDF152903ED2B87 -:10C90000906E039670FC0608BFF27E182705B22FC2 -:10C91000AB69045E4EEDF9CA8CE7095F1A5837CA55 -:10C92000DFC5C16FCC78FE70C8CBBA114EAFED3DFC -:10C930007EE841C89F063C59A2E009D69F2E905E32 -:10C9400001F68174F1DE9B6FBCBC10539347463CEB -:10C95000B16E92F77DF0FB16E0B7B017BF91E5E737 -:10C96000D8D76684FF925D80CFD18857C0E7E8BEF4 -:10C97000F83C8DFF98D4179F5EA7DEBF7D8E95B7DC -:10C980006EC2C2BD8984FFFEF0B968DF8F06B4B302 -:10C9900034F930189CE719F8BC1C4E6F893309E94B -:10C9A000C2AEB8389E03D3A0ECCCEE736E0674F220 -:10C9B00089A9FB2E8443F72B1609CFC916BCF22E8A -:10C9C000F1DD997D7F3223FEE12FCE3001F2ACE71D -:10C9D000EF4D06F9C5DC06678B58F755EF1562CAAF -:10C9E000BA150FE18FF287800F091F819BA6CA2815 -:10C9F0007F0349B4EEC501CE1F8B03076E318CEE69 -:10CA00000BF726A7A0E9AD1EBC1A26223E3FBC0AA2 -:10CA1000E9AF3F7C6AEB9770FD9740F9CFF5FC1BBF -:10CA2000597F31F02BEE8FFAE03770E00F989E6956 -:10CA3000B38806B085CE9878BC4724DE7BE1CFF57D -:10CA4000F377B58FEB9C91FB02DE5E83D360FC3EF7 -:10CA5000D8FABE2BFC963965EA37128EA7BE8EAE89 -:10CA60000F02AAFC58CC2AA6A60DEDABCF4456A2C5 -:10CA7000A467F7CE7765D04872FED44EB0C70D7D5F -:10CA8000E5C5E27ECEE19F75723B66F1FE03A351E0 -:10CA9000AE9D3AF84B952E39DD2FDEF5A15951F5B3 -:10CAA00043205C3EF7733EBC5F9DF79297A3F7B7B8 -:10CAB00064D7DFA3F67752F4DE8AF33FD961620AC6 -:10CAC000747132689C1ACDEEDAEE34E9ECE795B178 -:10CAD000138E0C8176C6B81819D75D5BE37D57417C -:10CAE0003BE64D139DFF33D1F38905CA6B63636445 -:10CAF000F4E7D5C6CD6172981EAF8B8093E82AA16A -:10CB0000F355D15952C8F77401DD39B00908227CB8 -:10CB1000DEA07733502F7D30E66313AEF36F1176CE -:10CB2000E4DF44B63205FAFB9B62F054CBD1F60742 -:10CB3000FAFE7D2B8C4C0EEB7FB1A5FB03F2C7FDFB -:10CB4000BB8DA15D667CD5664079B2649B89F65D3C -:10CB50004B601B8570FB78AB2DA0407EE32FAAEEC7 -:10CB600042BDF4F9360B9EBDB2D7F62DEF7A00E543 -:10CB7000D26603437FFAE7BFACFA12F5F2FC2D460A -:10CB8000DC2AB2B9F6EE27B0FDDCE7D2592DB4FFAE -:10CB9000CC109C809BD9AEA4D004DC8774ED4EF5FC -:10CBA00028D4CF8B8BB1DF33CFD9A9DF33FFFE2E53 -:10CBB0008D73E6DF6349AF69F3077B5B0ED7E360F4 -:10CBC0006FCB3D7C40F41A96877116629ED7377CF6 -:10CBD000ABCA3C947F0B3105BA5FB87F8817F791D9 -:10CBE00061F5A89F2596EE9F7868FFADA409B477FC -:10CBF0000AA5213F2EDCA91FFFBF5579B7C4DC3D34 -:10CC000087D7F7A771BEEDA076F624955ED5F2C85A -:10CC1000F65A7D5B528EAE9ED67EB1855544E38337 -:10CC200064B5DF853BBF19AEEF4F51BF478EC3BF21 -:10CC3000DF6F600AEA67B6C746F169E5E6D0B0047F -:10CC4000E0DB17CC6C1EF26F795C68583C8CF72BDC -:10CC5000556E96C7401EBEA7A9F3C0FA9867D6CEF8 -:10CC60003388D7452FDAE85C65D10BEF7E89F83C35 -:10CC70008530068C9D4AEAF8F2A74007A7B61A99B4 -:10CC800002F6DA224BC8BD19F5D41E0BDB8EFCFD73 -:10CC9000EAEBA4B74E3F6F11C2E3E222D34541A0B5 -:10CCA000066BDF7528C52CBF02E6A3ACF70A6DB88A -:10CCB0006F386C0C54C3D895A2B7E6395CDF6113AA -:10CCC000ED33CECE66F9B8AF3CCBD23C0AE15F7E05 -:10CCD0005784F2E5BF35199AA28C6B3A0F4A7F1C34 -:10CCE000F0C1F9EB983C0EE3C08652BADC5C311C13 -:10CCF000E5AE5182C51590FF81EC7693D3C3E64231 -:10CD0000BA3C81F9107ECC716D0F7FFD1150BAECE9 -:10CD1000313905DBFD2089DBD5F393BDD726917E24 -:10CD20007448A43F543A55F6F1797E6588F154630E -:10CD30005CCEF907EF46F82EFBD02087C79DF4C6DE -:10CD4000837A28EEAB5294DF950B69BD248F72A5D0 -:10CD50001886703D2B0974BE7076B63C243E4C2E6E -:10CD6000AFAE92487E3456B9285D5595CF64F26BCC -:10CD70007B286F54D76F29509811FA419EC63F8B7C -:10CD8000A3C48B761ECE09E3828C0E1FD111C6354B -:10CD9000A11CB33A18ED638D0E85CD453FBF83C30B -:10CDA000C7E82821F898D5BCD8328DE009EDE9FB19 -:10CDB00094645F4512E0D39A31422797CCCEB1BA42 -:10CDC0007C1F7869F8DFFD7F053746706AACB25288 -:10CDD000BAAA6A22C1ABBECA4BF9FF07B86DE470AC -:10CDE000BB94C75AF4C0AD5897EF176E8F01DF3868 -:10CDF000C3F906E0887CC3623C3BA2AC3F32DD5005 -:10CE0000C528F8E6E1AA164AB5EF09FDE8ED2F932B -:10CE1000B81D50C97CD5261C47E2FE16E65458C6FC -:10CE2000845EFF2673294CC63CF22AE2E5480CC119 -:10CE30006ED95F6DE437364A6257B85C5B76BD9C4D -:10CE400082F2CB58F9383B9E18E6479B566293090D -:10CE5000AE1E3AAFAC55F5667D0FFEF47CB0BA4A13 -:10CE6000A6748DCA0FEB547E588F78C6B8130F3F47 -:10CE7000DF6C9ECA482FFE1BE4F93E3EC4C2CF9D24 -:10CE8000E23DC19009F04D3252A63444F1C0472C26 -:10CE9000813C68672F605EA48FF8230F90FF1823F2 -:10CEA00074D19F16AFC28DBD9C133F23969667E247 -:10CEB0007A871979EA37A13D1E09D75ACF412BEE5F -:10CEC000AFFB9B4FD107F30D38DE5733084DCC79BC -:10CED00047F008C6AB3A9AEDA457933D1559E8DFE1 -:10CEE00063472D449F0E8FCF30370C7FC9FDD87517 -:10CEF00095C9D79C40FAFB086D25C0EBC32D436D47 -:10CF000008E7D5A6A00BE5DDEA78AE3FE45280C283 -:10CF100025BDEDFEA0CAC1B8423DBF6BF2559A3C9B -:10CF20005647BF9A5C4D98A2A7734DAEEE4FE2F6FE -:10CF3000DAFCE4922F51AE269EDF427C1849F7B905 -:10CF4000D2A5A53E27EA01E669427B0D6D46B4E312 -:10CF50003E340438BD73FFD4D9CEECED68E7C0AEE3 -:10CF600080E48A82FC4078EA7EED5B68B75B950FCF -:10CF700035D6E9568A73043A6214B72E1380F1FC51 -:10CF800090A9F1ED9C3F2652AAD1676672B62E5E3B -:10CF9000D0987B48407CD5831D4171C5B0BF73E0FC -:10CFA000F9F8814956B4F74493E730CAA9EE5821FD -:10CFB000887AB3DE31DD8AE74A86F842C2FB97B150 -:10CFC0006559039D7B82DD427E5BC9E161C7701CB0 -:10CFD000C6C86F6B94C632DC27EE7674C4E0BEC55B -:10CFE000912CE8ECC4F9C9BE9CE4B0FC281C5DC5DA -:10CFF0001776BB5BED2772BCD1C9AADF324361DE75 -:10D00000B0738B4A8DBE65854D09E3EF9ABCAB5872 -:10D0100067415FBEEE576EEDF87E72AB362B40F87F -:10D020003245CA0B27C87107A58A0028352A59AB93 -:10D030006F1F4374558C70608EED3D76C80F73A2E0 -:10D04000D0D791112914B7D9A36760D75C407A660D -:10D05000E3446E8FA87A86EBA7B3CD76D24F67678D -:10D0600057503CD5D9E61419E9EEC0DACB46233C3B -:10D07000E69C6F6432CC6FEEF94994CE6B7984D222 -:10D08000B296362072C6AAD7CC5D3B03DA1D7FCCA0 -:10D09000E841BEEE0A8C3B5309F9AE660B9E11B116 -:10D0A000AE2DF766A15FBC0BC641FBAA6B4B1ED130 -:10D0B0005717C08DF20DFAFA182F6C04BC9431A6E4 -:10D0C000C619CA5EAC3FE775635B343BA96C9DC56E -:10D0D0001BED7CA7A7BC25BADD568BFF4CC5FF55C1 -:10D0E0000C4778157DF04016AE57E3FFE509208F19 -:10D0F000105E1F5858347FFC94E42B17223EA62460 -:10D100007BEFE5784988EA5FEBA57F3EEE7101ECA5 -:10D110005BC28B2FEE269D9F95FB318FABF62FB315 -:10D12000F6531EA7B697A2972F6AFEECD043905BEA -:10D130005550518244AFEDA745C6F7D38BF7DFA416 -:10D14000C6F9F3F9809D4A74CC001F285F66ABFED8 -:10D150001E80FB8D78AFE4F8EB4603D2472F3DF9F4 -:10D16000E2D06E31ACBEBE663794FFE330DF9FCDB8 -:10D170003FBF9EE49D61F5A88D93E0FBBDAF9B484A -:10D18000CE57375DB6EE0EC0EF176F18293FEFBCD4 -:10D190008DEA7DFA9067E31D50AFFBF726B2C3BF5F -:10D1A000387C25C54D7C6AD2FB092E4BE17CBC5FE7 -:10D1B000E5E739E75793FDA195CF69986596894EC4 -:10D1C000D7D2F739786883C1BECAADBF2B12F13C04 -:10D1D00087D1BD85FDC9B75C57437A6D2CD9FB73E8 -:10D1E000D7583CD1E2A8F727CB3AF933B7B399FA2D -:10D1F0006560173993D5FEC2E4C8DCF389C4074CD7 -:10D200005218C619CF51E549CFFCB69874F2E453D1 -:10D210005B743FC8E164BE8F9A73FE32E2AFBEEB2F -:10D22000FB017D9FA38DDBC9F9B1773D1B27455BD2 -:10D230004FEF3A2653FD4FE3A38FFFB93A7E57D500 -:10D240003CE605B95466817A0E1CFFDE95130B711E -:10D250001DF10986B075CD6D59C8BC61EB9ABB65EF -:10D26000A6B92CACDF5E3C2CFD5D516E2F1E3EDF5F -:10D27000507E5D0DCAA3E492F7916FCA565F3E1AC5 -:10D28000E9716E4B23C1F9B8C9E346F9FA71CBBD18 -:10D2900071BEA8F394757A6B6E8B8A1FB0770BC33F -:10D2A000F0A3E125B27DD75FE77EF910CA9FC7B82A -:10D2B00071D31FBCFAE02D3B3ADC6C291ADCF299E1 -:10D2C0008FE026BF7004E97A8DDD8374DD3FFC4674 -:10D2D00032DF40F0EBC77E057B474849C27119D168 -:10D2E000E9DC164E0783C1AD775C950E8AA2AFE7E5 -:10D2F0001295DFBAAA2A99020C7BCC3C181DFC942B -:10D3000029D601D6D14307FFA6A3834B52D6101DC1 -:10D310007C82F6CAF0BEF83F6656E22EC5739F26A1 -:10D32000239D2B1D8B51926FE3F931288F8FC5F907 -:10D330006FC0731A2D3F7F475EDCCCB0713F6E002B -:10D34000384481DF252911FCADD14FAEC20A26FC3D -:10D35000EFD1CF71F59C38B2DE94E4A2CB52507F6E -:10D36000F8A3FB6BB55493D7C6218E9E7D26EACFDA -:10D37000638E9C2F0350DA94ECBB1AFBA98BFFC978 -:10D38000DD280F8E1D3390BEADFEEBF2E1A8D72253 -:10D39000ED04D87F36E0B9E77263AC9FEC50B1A2E0 -:10D3A00095CE411591ED28C47D4AC5A61379E8377D -:10D3B000ACA494A976E872E3080FEA6123AB781273 -:10D3C000CF49814824AC2FB20A3A3705415882F937 -:10D3D0008D767EEE5A295A254B585CC252955FEAEB -:10D3E000AB4A1E39817E68ABC2A4F0B843C6EDAF2C -:10D3F000FFC47986E97BB3C92779701F6A6025C8A5 -:10D400001726D1D7900DFD9B5CCE314A181E96A4ED -:10D41000F0F3765B7B7B4336B4B7DDF37B89EE1D9F -:10D42000C138E867B3668867C3FDD5266790EE0903 -:10D43000B1DCB0EF6057390A20AFF303C07C07B00E -:10D440000B7F65F0B8BE447AACE6F098882082F491 -:10D450002FB387B6A15C9E28D61931EE68C63D79F8 -:10D4600094DF38EBDB619D51E861C6CBAB3AD09ECF -:10D4700099F172EA2C3C3F98E118F611A6B05DB024 -:10D48000C640FBD70C2CD804E914EBE314D7F89A68 -:10D49000EA1F6BC77C985E6C57E90DEC9CA97B205A -:10D4A0009D61F59B9616F4FAD322C7DDA0E2A5DDB7 -:10D4B000144C1A817400E3E03AEE7C39F02350FDFD -:10D4C000EC8E60E0FA51809FBB58B709E1E8631227 -:10D4D0009D7B687EDD32E651F38CF6A7EF979BB615 -:10D4E000239D44F6774788F777673BF407E95D8724 -:10D4F000BB7F8D6AD91794AEB2B3B0FEF67B0ED95E -:10D5000059DFFE22E1EC11AD46250CAE8022211C34 -:10D51000EE7DE03BA4F45A36BA7F3EEB85379F4759 -:10D52000243EBEC022E0D3408AF77994C35529DE59 -:10D530005F605A6EED768B4037EF3B7D2F221F2EBA -:10D5400036FAB292011EA7337DC393102E1DD1CFA0 -:10D550005F23F93BB7F4F456E49BBBAA4586785E9B -:10D56000B9EFE3ADC897A74DC047B01F78ED818FE5 -:10D5700063916E16010386CB930F2AF3C87E3ABBE4 -:10D5800077F880F1A71FA8FE923FAA7CA2ADF36EA8 -:10D59000644018EFEEBD76DACFDC5D69ECD9672127 -:10D5A000BDDF5DC9E34398D831FA169DDD59A79ECA -:10D5B000B3F5ED07F71191FD7455F95A89EF45DF81 -:10D5C00004B4BB8F57CD6B45F91239CF3C97EF1898 -:10D5D000C2756ECB4C5DDCEDECE6F9ADE17CA8D517 -:10D5E000AFED47BEBE344C5DA7958FC7E48B8B1C57 -:10D5F00013F05E35FFB385AC1F1AC2E861B0F15875 -:10D60000EE146F8F5CA07BF702EC59FBF617594FB5 -:10D61000EBDF5579053B3E0ED7E7FDCF94F183CF85 -:10D62000DFE452E599DA4EFB6EF3F919DA85B6AF0D -:10D6300087909DF0D230EECFF80FD52E600E582F88 -:10D6400032987FA3F7FF63BD3030C5E7D9B658A243 -:10D65000C615A5B9443ECFE0A1226B94F9F5E92F98 -:10D6600024B20BA9F7D230BE7E749391BF6B580CD5 -:10D67000ED6BCA2A6B699FDD08F203F541E47C8EED -:10D68000356DA678689BD92FA35FB4715872760D5B -:10D69000B403A9467E1F5B8C5F16C3BFABFE205B45 -:10D6A0008D5FC6FD6D635E1A7DD7FA6B347039AB42 -:10D6B000F14523ECFB9E27BF98C7351DE0D2F856F5 -:10D6C000606A2CB4DBBE92858C6EC60EBAD346E27D -:10D6D0003ED75F6FA6F3BDC67C217536E4E332AD5D -:10D6E000E41F6B8B0FCDC07B078A4124FDEA8F9727 -:10D6F000AF8945FF6E4D4A07CABF834BCDB4DED517 -:10D7000093F8BD35CBA527FC5760FFF7310FEAD55D -:10D71000EDE77FD182F7FE9423B09F45BF21760AC3 -:10D72000F268FBD4B336DCCFA5605C1DD0D91653AC -:10D7300090E6B5A9DA42FD6E6A339746C3DFC95455 -:10D7400091EA070C9D141F9CC8823684EBC353A733 -:10D750006FCC8576D9B94CC2FDFCEA82B3DABD72D2 -:10D76000233F8FD2FC88CCA69E6759D5732ADDFD56 -:10D77000B8CDFEBDE43FB44F0BF274AA40FEE7C83B -:10D7800079DCEBE27E37FBE48EA9A827EC85023337 -:10D79000A07F3397D1BD66692A58E19066E7B37ED2 -:10D7A000DAF3754B5E685FC8DBA34F48BAC0F60B6F -:10D7B0005D3CCE700DFAA1A03C60F218AE817904F8 -:10D7C000AE970C8ADC5BAFCEC5F56B2BF41F22390C -:10D7D0001AA075B9F38321A43777B940785A33F189 -:10D7E000189D0B3C5CA8F9513D348F2DD5EF1C40A2 -:10D7F000FB6BCBFD8CECA42D2843A1DD96EB59806F -:10D800009F27B134946F9BE69BAFA3F3FC0280BFCC -:10D8100081D2A8F3F6A55A892EDD2B1E0EE13DFE1E -:10D82000180FA37713208D5ABF2195C369932990B0 -:10D830008AFE91FEE8E256151FEE4AD5AE627E17CB -:10D84000E275AD0A1F76CB58EE5F10BD72781C579B -:10D85000AF3EE17E0C581FDDAB4DAC33933E12A6BC -:10D860008566E0BA12F2CDECEA6CE42F0E376594CF -:10D87000C0E3CE58A005F9B3EDA2648A275D250464 -:10D880005CE86F568ACD749E7C70A230631E94AFA4 -:10D89000AB33931F02F2C42F7E6F4E1BF29B7D723F -:10D8A00071E93CC8AF97CC12C2B7B640B2211DD7C0 -:10D8B0007A05C900F9B525DA3D091683781B63346A -:10D8C000DAF2A1BC3555401F2D6B351888DFEBBD52 -:10D8D000C5FEA1F0BD5E721AC2FD002FB9F8BEAA46 -:10D8E00022ABE42517F28DF761FF5099E3529C407B -:10D8F00024467FB12C340F636EDAEA9FA0FB546B91 -:10D90000C65819DAF199F7F9E97E57EC456619F12D -:10D91000BAFD7CE2485A5F9D59467E5E6F085C8383 -:10D920007CBF65E92105FDEAB68F1CCC08F682A311 -:10D93000F3EF55183FE62834479C633101E5B836CC -:10D94000AEE3AD10D153A7C1F7E758F2FF1434E5A9 -:10D950003BF11E46CC0484E7DA4BDFCB9F13852EC8 -:10D96000C8653B16ED6521346134CA29AEC79828D5 -:10D97000A586E3777D66DA5FD0CFB4AD08E68FE3A6 -:10D980005576DD41F3F2BEF353B4AB1C473FFD26A1 -:10D99000FA3CDF243D127BD41E124663BA681AD9C2 -:10D9A00067E1F540EEAFCDF29E70017C775773B919 -:10D9B000DF7C0FA37729F02F3F0CBECD0520A5E912 -:10D9C0006102803CD62B90C88FBE4A90832184E7A9 -:10D9D000682BD1538A7AEF2172BDF6A38D4B31EEBD -:10D9E000C8EED1CFF32B15BFF82726D379055AA25D -:10D9F000CC9C3ADB86F26FCF583915F7DB0FC7475F -:10DA0000D7F3EFA572F9B0DB10DD3EFF22D5C6FBE0 -:10DA10000759199A40A86214D707792199CE6DF851 -:10DA2000FB0A02970BEC5A467A2F6E4CA7CD1336A1 -:10DA30005E501D87FEA09F216A3B267587AA61FD67 -:10DA40006D40B578AF2D2E93C3D1A1F4C211EB4B2D -:10DA5000EABA800FAA8717221025AACF4ACC742EC3 -:10DA600002D250F956E88543AC5A7FD344D1608541 -:10DA700079E500300C503F7EAA59778E22D5BDA3A0 -:10DA800060F94F8D4C4E98D83BFED6312C5003E3B5 -:10DA90000FF1EAE11D7BDF0BCBD12E8FA4039C415C -:10DAA0004FBF182A3E5BDF2EF98E3E7C40F0A479F2 -:10DAB00002689ADF62DBCD0094E69DA2161F4BF24E -:10DAC00077BCB143417F28C0AA641FCC7FC4536F89 -:10DAD000797741BED9C7F92C36FF85E54897521AA8 -:10DAE000C7D311F42D039C3733E91F18B7A3540A89 -:10DAF00032E2635B2887F47823134B104F8D15EFC8 -:10DB00000828D757EF651E8301E9FFBF2DE1F39B7E -:10DB100091CACF69982893FC13DDFCFEE8EA02C1A4 -:10DB20008EF2F5E0D21748EF6D3D2030E4FFE2DFE2 -:10DB30001C7DCC8E74FD170BE59B5FAF20B9F113F4 -:10DB400068A744F19F0FA69723EBE72EDA6EC0F388 -:10DB500089AC79417A8F25D12F7AAE467CCCEBF017 -:10DB6000D23DF7427ECEE6981652288F5A0D6C525F -:10DB7000D9AFA6CDBC9CDD9240FBA85196CE866B5A -:10DB8000617E9B9F1219EA4BA325983A17FA35BE7E -:10DB9000E8404DD0677FB4795A2815E5784C058563 -:10DBA00041F7B5E352391FBAA7C9BF1D06FDC64FDD -:10DBB000E6B0B4F9530EA0BC449B19EF35D915AEAD -:10DBC000E7D68A012FC679AFBDCF67C6F199BA7F74 -:10DBD000695C54F604C2F91355EFB18A79F48E8961 -:10DBE0005BE5177B252B8AB6CFDAE88AE1F12D0FAA -:10DBF0000907903FDC5E46FA43AA0C8686AB7A1989 -:10DC0000272EAD78BE11F58BA35CA075AC153BAA91 -:10DC1000F15D89B5F731A95AEEDBDF3FDB7E79AAEA -:10DC200085E0B1D1C574EBA0F73040BEB9E7455FE0 -:10DC3000C7BFE1B8E37BD711A3AD23BF93F2DA3CB2 -:10DC40005ABDC10B9AC706B53F7F2A7FC7C85EC0C1 -:10DC5000DFEF8894F735F60FE85D9900D8EA46BA09 -:10DC60008F16BC16F3F27302E3F7B5F4FCDD27AFB1 -:10DC7000D255E47799858D938D74C7F10C74A7DA2A -:10DC80004FC07756140182FC2DF931FC34CF487A0D -:10DC9000FC5F978BE1F386FE631B9841BDA72A17B3 -:10DCA000A7F6958B4C958B56A68450FEFD5FCB4511 -:10DCB000908324179B61A589B053896D6F5A8A7A26 -:10DCC0005C9387E31127976227D6EB8B0B685F4441 -:10DCD000F909A9BF6FC6F8C855827ADEA5C205DD6D -:10DCE000500897AF5D728F9EC2EF1BF01F39F89EF0 -:10DCF0004AC2750530DEC6D29C31B8BFB0F95F2488 -:10DD0000FBC05DC0E357DC95FCFCDC9E3BE789F083 -:10DD10007B714B52B99DBE44A3BF4ABF0BC7598B01 -:10DD2000FDA27CCE3593BEDCCC825C1FAAF6E95600 -:10DD3000971A47ACD255249F44CAA771BF7716A340 -:10DD40007C4F355824DCCFA17E3E98ACD7D7482FE6 -:10DD50009ABE6EE9A889477F58B6EAEFCFB6EAE3E4 -:10DD60001C26A4717926A6723FC02AA182F69B4A7E -:10DD7000B140FB388DFE7AF478041C23E18784BA25 -:10DD80007202C5C7503EAEA89B21FF6E03925D8F05 -:10DD90007A2C5583BB44706EBB53188BF2724F7B49 -:10DDA000990DFDEB06B7F51ADC1FAE3330BAFFB89C -:10DDB000AEE84D8A2B69AA849E61518E7C61A6795A -:10DDC000745F3C031FD37ED5AE583AD0AF150C6DAF -:10DDD000A7B885A6C0A1198CDBB10CE3529AF26BEF -:10DDE000D216A07CCF2F2944FCB6D59B296E46CAFB -:10DDF0006751FD0827711F43F3FD6E7ACCAEED2FFE -:10DE0000CBA3EF2B6F4CE3FBDBA008A20AE69391B8 -:10DE10002F7890FF33EACC51E751ACE2292D8DDF0A -:10DE20000F6BAB3F44EFCC00BE026C207CC1F46BA7 -:10DE300092C3F031A91F7CB8347C881A3EE2671285 -:10DE40001F7676085CDE925E5BCBA4DB503F2A1522 -:10DE500066B2631B4D7C5FBEBD40E50BC9DA86C46C -:10DE6000F65DE93A6E9140F7703227F2F7F5ECE58E -:10DE7000CF535CD366D6FD3ACA3BA580DFA38F6C37 -:10DE80007F679AA0C2513678683FCDF10878A5F92E -:10DE90006CC94B6E0BE7D38DAA1DBDD1C5F9744B70 -:10DEA000FD06E2D30B9DA726B76B553B7ABED7671D -:10DEB0004675A0184AAE4A45FDF973FE1E15333A61 -:10DEC000C82EFF049B84F9652B337C4BD2C2FC72B5 -:10DED00092B742C07A57E2BB42D0FEE320BF07FAB6 -:10DEE00071F01745F41E978F1133CF671D066272CC -:10DEF00090A13B20EF128354EE9A077389A7DB9120 -:10DF000094B75A412FC2844E57F1FB175DF8BEE417 -:10DF1000707C2792BF2FF999FA9EE4A89655C59B6D -:10DF2000713C59F4A1CC3889EF4BE2FDE789EF5100 -:10DF30005CF42990B54DF1180FC3EF6F4B0F3249C8 -:10DF40009884F935C518F77CEFAB16F59E64470D3C -:10DF5000DE7B795C60F48EC46A11F4FD502C6A306B -:10DF60005484D1F1EECB3BE2F09CEF74F0E601FD7E -:10DF7000C7787F10E7B143A5F7F5F6C574BF6C8E7F -:10DF800023E4C6F607F63CF9C42618EFB37D567AAB -:10DF9000D764A37DB11BCB3F7BEC5D37EA8BD3FB12 -:10DFA000DE35473B9F5C2406AFC27B64E5CA105652 -:10DFB00003F32F0ACE3453FCC9AE03743F6D91E4D2 -:10DFC0003363FFE52D7B283F65D79FDC587E348D7A -:10DFD000F3C7E9549F1BFD12B92D969000FA67779D -:10DFE0008E7F41D47376951ED7DB5FA5FE37DA5F4F -:10DFF0003D847839FD9885FC6E071EFB0DF57B6A24 -:10E00000DF8B34DFCF76BF7B17DAD3E58C79509E78 -:10E010009FB6A97E3D6B475CF8FEF615151E5AFEAD -:10E0200074ACBA0FCE18A49E7A1EC31C007FBA3FF0 -:10E03000D01187F70B3F33F9CC088F85080F488B39 -:10E04000000E28F717060D34CF852D6D74DF6AE1B9 -:10E050005EEE1F5C08F022B8B41CA0F9BF8F7019E7 -:10E060008FEBF8B39BDE75D86BA1FDB3B6EE850ED2 -:10E070009F1BE1A3AD17E0C0D7BDFBC2F03447C37F -:10E0800053CB9F685EE57BF9BCCA77F179CCD90B9D -:10E090007872209E6612FE4FED6332DE83E9DAF37A -:10E0A000EE49B4674EEFB3CA685768F3CA00711BF4 -:10E0B0003716F988EB63B6D740FA98891D749EB37A -:10E0C0004892247C9FA0A73C600E7079DA519C0E88 -:10E0D000E5CF3C0AF62142420A8E40FFEAE934EDE0 -:10E0E000FE4F871BFD62BB2FF7137D7E1AABC25B11 -:10E0F000EC7063FCCC8674DFE9B4B07882D31FBEC9 -:10E100003802D7BDDC58F19B4C1CE7491E1FFA555D -:10E110004EC5DF1EA2790FD59D3746A600B7383C05 -:10E12000FFCE17988FEE25EF7D2D26FC1C5A48E771 -:10E130007EB78DF60FE83EE2697CE791E613A438DE -:10E14000AD61DE32379EF37DCA1C3E3C97FDECE7A5 -:10E15000AF51BC4D57AAE67FEAA07AA7F6BE9680DB -:10E1600069991A0FCF0237931C03383658C7469364 -:10E170008FEAFDA200BF3776C6000213F5C4560D24 -:10E18000CE15E6E9BA731D2E4733B664B793BF25A3 -:10E1900010FDBE59A4FCCD7D74129D2B9F63D1CF81 -:10E1A00095991A27B7DC1843F1371BED3FA3FBB74E -:10E1B000958A45C2FB2BC754B97842BD97FF554C91 -:10E1C0009C2200DDEC4FF7E5A48FEF7B0FB76CF5D9 -:10E1D0002237C2B70CCF3D28CEA0ED7A8C27EC4A6F -:10E1E00062AADDC942043F9356BE9197C7F3FCA4CF -:10E1F000CDC135F81E26C297D77F829767F3F21FED -:10E20000A9E573D24AC6A473FF0EBDAFC19829BE5B -:10E21000CBCA55783478F4C245645D9A5D0D95E7B4 -:10E22000E1E5DC24EAEF32EA4F84FE467DFFFE00A2 -:10E23000EF8A35E15FD08FF55FD54F90F492E0C360 -:10E24000B7AEE09B87EBBFC78B99D414FFFDFBFFF4 -:10E2500067DB2F377A854F910E870844F71A5F776F -:10E260003D367C0CEEFFCD0D4B43A836BB628BCD0B -:10E27000A9F0FD9CCCCF4FEE79743D8B164FA2BD1B -:10E280009BD19357CFF1CC43F5E7B3ABD3B9DE596C -:10E290009DDEEB7FC373393CAEA28D33FC35275333 -:10E2A000280CB7D3598580F187F9ED567ACFF7223C -:10E2B000068202E63F928504D4DFA35827E52F4665 -:10E2C000100CC5F7A8647A38731CEB768B43F1FC0D -:10E2D00039B412EDB4F79DBEC67418EFCBC73A3E01 -:10E2E0003040F94FD27C2F75A25F289DDB570EF589 -:10E2F0007D5C0953A043C13ECD154DEEF7C05312CE -:10E300004F859FB7DD287A1F49A7F564485DF65E03 -:10E31000386BF26081FAFE92D6FEE4534FE2563734 -:10E32000ECBD70EF80F781E754CE7FF4E7E3062879 -:10E3300057E5ECEEEAC06DE1FAFEC974AE679F4E98 -:10E34000177476218C4A76DCD33771FB69F7E5DEEA -:10E350009AC751DEB618693FFD69CB9FE9FDC773C7 -:10E36000258CECBAFEC6FD3402EF9FEE78328D9F0D -:10E370007704F4F1CB4FFC724478BC258059764E7B -:10E38000E0EF7010DE0F79148B91EE39923FC6CC1E -:10E390002A789C0ACE17D218DC8F0E453C75501A8D -:10E3A000C7BA29959844FEE904E6A1D4C94A284D84 -:10E3B0006615066EDFF9294D63414A33D03E457F2D -:10E3C0000FEBA654C61B9F61F11B3978623A14DF2C -:10E3D0005D2DE1DF23E28344C4E3B828F23C222E22 -:10E3E00048DC5949F21CE382F29C7DDF53D0E4F70C -:10E3F00086F4E2F7906EF6A77BDFC7F4F0B3BFE5D3 -:10E40000F72BD618C8BE3E6E9B66960175CF247852 -:10E41000E91D104560253B40BFCFD6FCFFF8A7C5DE -:10E420000923309B4DA7C2E37798D5918FE7C5B3F9 -:10E43000D4AAB3D4739059AA1F248631F59E9E871F -:10E44000EEDBCF52CF1F6645F85F98DFA2F3A3281B -:10E45000F80F58C72CBF81CE0D66C54C7BB593F520 -:10E460004F2761FDD1BDBFB2083FD4A0FEAC88FCF0 -:10E47000ECC8F65603B326E3774E4FCFFC4026BBDD -:10E480004EF36701C1C9D4AEC1F221F985FC577AB8 -:10E49000C3E19490C1F9C4E6BF3A2EDA3BD95A3AA7 -:10E4A0001BEC335342DFF6B0238C47BED7E4B046B3 -:10E4B000E7D9B8B1453ECA3707068A4B5DADEAFBDE -:10E4C000A687FC0CE76D0B3D40EF54DF9FA990AF92 -:10E4D000D65A10A0FB0131F9019712657E4DF8BEA6 -:10E4E00033F05753ACFEDC64A9BAAEA519DC7F7BD0 -:10E4F000E8A2E4623CCF5E250B746F7895BC8CCEAD -:10E500005907FB3D815AF57704B4FCCAC46D0CED84 -:10E5100036DBD7AD0CED499B18FD5ECA0C75FCF5DA -:10E520006AFD8D89DBC84FD290C7CFF723EB1FC898 -:10E53000DBE042FBBB311BF6BB983EA450FFF579F4 -:10E540001B4AB1BD35D4A8BBCFEBCBE0F6AD752FE0 -:10E55000A74763AE399083F420FA29BE40ABD7D8E1 -:10E56000CF79D2F56AFB265380EEC934A9F6D0D212 -:10E570002DB16BC92F97B1FD08BD6F95CBE8BCD10C -:10E58000167A8ACE11ACF9666683BC55F6337C5F89 -:10E59000C3561024FCA0B329A4A3DB98DE77368CE5 -:10E5A0007DFBAFFBD6EFC2F53566FB69FCC1D65BE0 -:10E5B000ACC2B351D5AF8D36FD39DAC20CAE57AF10 -:10E5C000CDE0F2DEFA32237932005CC8DEBB3E23B6 -:10E5D000EF06B4EFACFB0785A3AE7E362B1D128D84 -:10E5E0005F22E5BFA340887847C940F33AB7D7A078 -:10E5F000BEBBC8DFB1E8B5038266ECF7D75BCA0ED5 -:10E600005E03F359E07378317EF2C92DDBE99EFE9B -:10E61000C2174D149F30AC732697832DFC3D46EDF9 -:10E620007DA38B5A2CBAF7A416B1B0F71A61BC853A -:10E63000473F3DCAE89EB1FEBBF66EC06AFC10259E -:10E640004E2DF2DD81473222DF5D56DF1D2888EE38 -:10E65000A7897C7760575020BDB10CE358691FB083 -:10E66000AD18F73D95470DE437E8CB87F2D65C53FC -:10E6700058DEE0217A546263BC3BA2F0D37B999CC4 -:10E680005E76E3A11AD9FD3F5B1BC237BB581DC3A1 -:10E69000F3A6DAFB4409CFB56B033174BFA456125D -:10E6A00002183792195B6C45FF238B1724BC8776C1 -:10E6B000957132DD7B32DF2F8EA3775AB72FE8C0FA -:10E6C0007B75B52E91211F67C6F33802962AD0FBC1 -:10E6D0003475D29BF1B3701FE7E0F7F4B2241690C3 -:10E6E0000D68D779199E2FC366A52204A657A6C127 -:10E6F0001BC2F7AED8248BB483BF3373C39809E42D -:10E7000007A6BF036D57855EC171BCD612C4FF94C6 -:10E71000FB9D640F065C467CDB947D9CC1CF05CDE0 -:10E72000B1C5A1BFE2FC66D8C9B71B508404C4C3FD -:10E73000EB6D2BA75F0DDF4D0191E21DF2BFA9BD6F -:10E74000ED6A68DFDD66A6FB161A9CE43A51F77E97 -:10E75000837B853E6F8E78AF426461E5903FA2CEA9 -:10E7600083B152160A8FE3757AF9A1BBE4A0F729A9 -:10E770003E02FEA4F30F35FF9E9ADF69F213DE77A7 -:10E78000FED540FED5836D73B2485EDA17B7DA71F5 -:10E790005F78849F63F6279F7766C8DA3B0936F572 -:10E7A0009D0A1BFABD22E9A9AE8A7930CED01A683B -:10E7B0008F1989F83D6CF2605873BD2A1F45079781 -:10E7C000E31ADD44A6F511F4576FF2E4FBA17EFDD8 -:10E7D000374675DF78FA86D0640C7B90695F6DCA26 -:10E7E000601E640F93B3234D82798C7CD1ECC1DF22 -:10E7F00055B8EAB9822128E747BE3683E41BC289AF -:10E80000DE87AF347BD04EB6543A3DE238ACE720D9 -:10E81000BA3CEB30933D2456DAFD647FB54D70C9A8 -:10E8200061726F6595E4114DF47B3794AEEC47DE71 -:10E8300067C50B25E87735ABF672B2BAAEE44C3B50 -:10E84000A5496ABE5554A6233DB702DD60DCCD81E3 -:10E85000159CBE97A55A496F2E7B7D68CA40FEC1A4 -:10E8600027AA5C9E5C00ECB61565E4B72D7AE044FF -:10E8700023D2DDB258AB8474688C1BB67132D2FDE2 -:10E880006F4D74CFB33676823C2BAC3F63DC4417BC -:10E89000C2C328286948CF233383378893904E9486 -:10E8A0004D789F7FDCD68D3788205F76C62A6978C1 -:10E8B0005E76D9D6CDBC3C49D96480F22BB6B6F28F -:10E8C000F24C254D80FC755B1FE7E579CA26CCDF4D -:10E8D000BCF5495E3E8AEBA3DBB73E7303EAA35A5D -:10E8E00093A714FDD3CFC2FC0BF2F09D549EDEA97A -:10E8F000C2452B7F1EBF9BF05D559E4696BFA0B6BE -:10E90000DBDF4FF94B6AF9CBFDF4FFAADA2ED44FC7 -:10E91000FB836ABBF67EDA1F52DB1DEEA7FCB76AEB -:10E92000F91BFDF4FF07B55D473FEDDF54DBBDD5B7 -:10E930004FFB77D47647FA297F4F2D3F1AD1FF0737 -:10E940006AFD4EF5BB3BB6E13DB4D7DC20AF509E2F -:10E95000E4C73690BF6B5B6521D17FED78AEFF35A4 -:10E960007A77ABF702DECEE471A56F6772FB66794A -:10E9700026B70B8A1EC85D3719E9F0F7FC9E22E81E -:10E980008F23780F57794020FFDEB2D7F9BB32CB07 -:10E990001E1075BF1FA4B5D7E61F50E759A7A64B99 -:10E9A0003273689C6CC5E59916A61F4D923E6F05A3 -:10E9B0007EC2F8FF3A27D733F90F1437E0B9492D53 -:10E9C000E8195C5FBDC31C42FF57BD2452799DB35B -:10E9D000D88FE7FD8A24921EAA772684F0BDE6BA76 -:10E9E000BA42DD7B9F759248EFC788F153ACB31CE8 -:10E9F0002837A649283FEB98945044E76AB04F4324 -:10EA00007D52592CA1DCC98E7726A05C9E95C5E16C -:10EA1000DE1EDB65C37B14E24302BD15304C128958 -:10EA2000DF73EB84800CF368979691FF7547B37A98 -:10EA3000A6C8F879A226E777FEEC2AD263B5A0C76C -:10EA400064D2636CC898E4DEFB9BE2D19166D45B30 -:10EA5000529A9199402E1FCA4CA071773CCAF55624 -:10EA60001EE82D7C67ADB590F177DE5C56F2EB9633 -:10EA700089CC9518E6C73C946954DF47E2EF50E72C -:10EA8000E17B8861F01DEAD7EBADEC41F4565625E9 -:10EA9000C8CBB0FA1697A4CB3F97A9BEABE4611ED2 -:10EAA000B46FAE7A6E0BE993B3A84F18EA973FC4E0 -:10EAB0008C44FD027AC4C2FACA414D1E6B768B2685 -:10EAC000A76B55BD511BA1370697BBFF787D38D189 -:10EAD000A7A07B87A63FF9BB1CE304005E269F81AD -:10EAE000F40A137D74BF7F30B8994C2512DAE383A2 -:10EAF000C1CF94F4453CCA69934FF49C88724F6A25 -:10EB000030F86AF5CCD6F4ADA8D7BE38BA3C1FFDB4 -:10EB10005E2B4D1D337721DD1A86D0FD0E59F53B56 -:10EB20006CABDACF8EE7E1EFFABCBFA56E1CDE1F3F -:10EB3000F74AE42F492D96B19D0DF6E98964C7F196 -:10EB4000FD26937CFE0568CFBF6896F15CE0F0B3CC -:10EB5000EAFB0D990E82E7BD7BEEA3762643858BFB -:10EB60009FF73382F7AAB404B2CBE59D56D56E3C2D -:10EB7000BDCE0B65B542A701F5CF5BAD817556D40F -:10EB800027EA7E8029811B71FF130C98D5A01ABC3F -:10EB9000E8CED81EC1A0F99FBDA22BDC0E35DD3812 -:10EBA00065329E874A2345E82FD56D5B67CAC472DC -:10EBB000416BEFC5CB4328BEB4BC087878A65D2B6B -:10EBC0004F593705E6B3C7CCB4FE15ACBF071F835A -:10EBD000A4BCB40EFBDF5DACB6573E5F87BFDF055C -:10EBE000F3B9CE087BB0E1DBD2D639527BE79BD3B9 -:10EBF0002AAFABCE052A943BE3701BB7A8ED443295 -:10EC0000EAED55A5FCFEB0F6FB59DA3DE21EBCED7F -:10EC1000BD494157ECE787FE33AE008A96183B0F9B -:10EC2000D9016E8BF657584D02BEDFC5DFEDD2DA43 -:10EC30002DDA3B93EC9C252F17515C70947687F16D -:10EC4000FECC3FD1CE6ABE80F14E87DE5CBC4BC6A7 -:10EC50007B33150D0E23D567DCFF157D7D5AFBD365 -:10EC6000BBDEFC318E7746EE4CBE166AAF0A015C05 -:10EC7000A2B4D3EA6BF7AB27B9BC13DCF0FD3FDCE1 -:10EC80009C0F9958E1413F53D0EAA77B6C3693BF64 -:10EC900004F509803E80710A5A3AC99D4BF523BF9D -:10ECA00047F257D0CA12A7A1BCBC4FA473F7A05516 -:10ECB000B18F867C33EC53AA614A3563DE198BF140 -:10ECC00002CDFB1C24D76BEF6B77E1EF2B291E33B2 -:10ECD00043BBB7F9F28E5409E65177BFB9F4E74860 -:10ECE000BFA165AE7BC2ECB09C2C1EC79D19EF2F57 -:10ECF000457EB4013FA23E6E34F9ACF86E8A922A8A -:10ED0000505CB50DCADFA0F24CB5DC33F56ADA977A -:10ED10000912CEAB3E77F6D462D46BAE04D207B6FE -:10ED2000BC29A573A13C20992524AF8AACB2BB11A4 -:10ED30004ECF889E0AE4BF671C0E09E3B14056928D -:10ED40003E10F39C149F6551EF3B658EE17ABE67E0 -:10ED50005FEE56FD026E1EDFD31CDB715311B48BC8 -:10ED600079509014E8BFF1FE0D25189FB8F5FE7795 -:10ED7000FE84F1AD4DC922BD33B0BB3AE4C57ADDA6 -:10ED800006D6B11DECC83595D33B703FBA86C93263 -:10ED9000DAEBBB0DD3FDA89FBB9344B65DE6BFEF96 -:10EDA000101EAFEA28D0C74B6594EBF36BB37C0F12 -:10EDB000BAC7633C5061118E936490657C3AB8B0D9 -:10EDC00083517C7E726EAE8471DD71851171B0935A -:10EDD000F5FD244CD1973BA745C46DDDA22FC7DFBD -:10EDE0004F08CFE3EF4484E74F223D523C093F7F79 -:10EDF00088E145009F2718EAE9C6AF87503C2BC23F -:10EE000011EDF69861A207CF4532CD1D33300E8E3D -:10EE10008D88217BE9A03B86C990B72C66244F2DB5 -:10EE200009C103B85FB5085289421A2A78E0AF5089 -:10EE30006E87FD2ACADF48F8656672FFA043FD3D74 -:10EE4000B0A018223BC2F6C010A9DA835BC7083F06 -:10EE50006C79589EC77B6F77ABE7282E2D4E8DF0CF -:10EE60000A2B43BC4D62017C8732F3FE134A08E64D -:10EE7000B146CEAD403B6395D049E328650E1FEE09 -:10EE8000BB9330CEDB88F1DE0AA591F8D8E3E6F635 -:10EE90009FCC66FB118FAE9902C58FD41F8AA9C380 -:10EEA000C3977AF5BD062D8E4DA3CB97DCDCFEDC37 -:10EEB000D32E085EF483DF91BB1DF1ADE55B7C4E84 -:10EEC000FA1DCECC31159D4897EC7A6E87821EA034 -:10EED0007BD95A9C981657F85196999FE767093D38 -:10EEE000F80B6971446171E0747467C4A30BBF844B -:10EEF000E73D99634A2494338F68F72F18EF179FE3 -:10EF00002FA473836982F722D59F8E765DA23A5E25 -:10EF1000A253F4D2FBEE302701EA3FCA78FDC4DCED -:10EF2000BDCBF1DED51E241CE49F7B389C23E93643 -:10EF3000B5DD5F320AE165007D98D1978E0DEE1642 -:10EF40003A0FAC7F902558C6F4A5EBF1466EFF74DE -:10EF5000CF9729CE72303AFFC41DCFFDD8499B24EC -:10EF6000B46FD3721FADA67B300F3209F55D5A7BAB -:10EF7000C74DE8F78AE487803D6E2C8F93FB6E7E49 -:10EF800078A391F3074B11096F91F1A591F1A43981 -:10EF900059F1AA9F02F4402CDE0790AEC038C1EEB2 -:10EFA0000718BD1350FC62F36DBF83FEBECC334B1C -:10EFB00028AFB3DEF23D6987797DF94B5F16CAE968 -:10EFC0006D62A72D3ECCEF290AFCFE59A4BCCEC928 -:10EFD000E27427A3DE70FDF36926D2F710FC7DBE34 -:10EFE000E4919284FDAEFFA335E9FFD06E61563FF8 -:10EFF000DA2DEE762D9F417658D65B3C7F893B63B8 -:10F000009D928B702B277FD1C1CC39E42F12DFE387 -:10F01000FEA251466F00F3EC7D1BC5DDEDDC77C72A -:10F020003C8C57AB4FBE5646FD3C4EDDFF8CC9D2E3 -:10F03000F85BBF7ED1ECF521DF447E1F99A5C59515 -:10F04000947C3213F037EA7133C5DDE50B65F47B50 -:10F050009CDD8D46C26799515EBC3A6C9FD6945C2C -:10F06000549495C47F97D8071B06F9BC81F980D9C1 -:10F07000DCCE634548AF59C066285FB2146E406667 -:10F0800055C6305F189DCAE745AADF94EC2DCAE249 -:10F09000710874EE635259FA9984123613F5327C72 -:10F0A00043BD6BDA15C3CF7B9CFAFB9146238F17C8 -:10F0B000B9415DBF09CF75C6E27B6F42C832BA6FF6 -:10F0C000FD9BD57AA2D511320E413FD91B47E8DE10 -:10F0D00065C43930EE6F292EA79C911F14E142F9C7 -:10F0E0007B25FE6E77258F07A85DC10C781650AB87 -:10F0F000DE5351EEE2BF4FCCBC5E19DF57A12DA607 -:10F100008CFF0B11FFBAAC2C01EBA7B20E8A636423 -:10F11000ED4CE6F112FA73A76DFDBC03A5F901C42D -:10F120004A23ED5346BE66A3714D958CDE09A73781 -:10F130009B70FFBB82054443AF1FEEED4C99DA692B -:10F14000E7B1BBBFF9200DE572BEB0DDF706D90D02 -:10F15000B1D276D48F317A3ED4EEAFD5A874B2ADA9 -:10F160004A227C6BE56EE518C5DB67B1EE6ADC67A9 -:10F17000655526E8F0DCE3973D9FCE7CE3C2FB0DAE -:10F1800070BECE15E99D2EF9BC9BCAB755C983F454 -:10F190009FD34FFFA9444FFDF79F41E5ADA12FE25B -:10F1A0006F00506CEB3E115F22F7DAAD917076AFD5 -:10F1B000D0CBEF8BF747C69373B8D84C5EE74D00C2 -:10F1C00037DB4382A78DE1EFDEE8EB4DCD3E17CF75 -:10F1D000CFCBB5FA21E7CD581FF6BD6D32FE8E8E2E -:10F1E000BE7E49D147F1FCDC5DABCFE7F7C3F3FA54 -:10F1F0007A91F8899C2FCC2BE94761F3BAC26AD186 -:10F200009597CEEC33AFA45BC3E675B54B5FDF5784 -:10F210001D7D5ED7E55B069C9756EFC68917562F76 -:10F22000721D374FB5F403775EFFD6D20BEBF7F6BE -:10F230007903D7BBBB32721C85DF53377BDF46397E -:10F2400057C6E495F84E3873C4448D0B2E52F9E33B -:10F25000EFE8A748C27800EF516CF779268F4B3959 -:10F26000FCEC023F9EC32CDB6796F1BC2353F55B9D -:10F2700083E05988FCBBC72AC5633CA0C52DABFB06 -:10F28000AB8E6C8CE7DBB3F39DDB48EE31BD3DC349 -:10F2900098A708F5358830BA97F1276C97141E4760 -:10F2A000E125FBAF5EF0FC99F6553FE6FB2A2D7E8B -:10F2B0003FDCCE62137AED2C2D7E7BBD3ACE3759E2 -:10F2C000DC1F08763EFD3E6A72AE48F1CD8F583B9A -:10F2D000D6E3FDA3479CCE78DCCFFC469DB76637CE -:10F2E0006AF71A5266E68E3146819796FE0F29DC40 -:10F2F000A2280080000000001F8B08000000000012 -:10F30000000BDD7D0B7814559AE8A9AEEA57D2DDE3 -:10F31000A90E9D178F509D7720840A8418909126FE -:10F3200009195486E9A022E80C360908485E181F1E -:10F330006165C7CA431E51C7384604046CA228BE83 -:10F34000669A59D488C16DA3C3E82E8E61D7191D62 -:10F35000C7CBB6C05506105ADD41BDABC33DFF7FDC -:10F36000AA92EE4AB7C2E8CEDDEF663EA73875EA4C -:10F37000BCFEF3BFFFFF9CBE2B81AC0C1411FCE361 -:10F380004A0971E6E4F476B9091957E215A7D0F7EE -:10F39000BFCD3410328D900DF44168BD9227F877BF -:10F3A00073F4DF2221EBCBE8F7D0308B9007C44118 -:10F3B000A740EB1F7009A2C2413B09DBED7DCD6088 -:10F3C000F0B80879E82739BDBC7BB8BCC5E7DA05D9 -:10F3D000E57106E20BD8A0137135A1EFF75A446727 -:10F3E00057092D0A83EE1A3B2DEFF9C3759C8390C4 -:10F3F000CCF1F45D0A2175AD95E4D854429E378571 -:10F400005F3D0FF3D9CCF977D37E5EE829A9166862 -:10F41000FBE52708B1D24FEBD65EF5C0F151844C25 -:10F420003F2ECE86F775DB9D324FDF370E3657C342 -:10F4300038A499C8B9322169FC6CDE4EFB49BBFB8C -:10F44000B0DC41A7FCE080D417A2E5F02E4EEE958B -:10F45000A07E4DC91A808FCD23D9E87A97C254F186 -:10F46000BDB3DA08EDAE32C99DB49FD346B208E011 -:10F47000781EFE660D3F97FE442A2774FE4B036BF1 -:10F4800097E2B8220559062D5B449C87451293DB11 -:10F4900068392D8158AC5308296B170FDE01E3AF93 -:10F4A000B28BBD14C68E72F1E0C3B0AEE64C91973C -:10F4B00061703FC255EB7FB9C76B2274DC897B4C0E -:10F4C000B433B68FE7E97F9302D1E5C97DD1E592E8 -:10F4D000607479EAEBD1E57D1283F70CCB981DC7F8 -:10F4E00029BC070E9809CC77F5A904BF99C27BBF48 -:10F4F000911058BFF2AC19F1A172B5CD03F871EAC1 -:10F5000064C22E332DBFF25E027E7FD3D356F6BD8A -:10F5100021F04B282BBF4C24F0FDEA5181B2643A14 -:10F52000EF97BEE66FF016B16519A1FF5F16EEEA20 -:10F5300082FAA9813291BE7F7E022183502FF88BFF -:10F54000619DCFFF95C77EC34F9AFDBDB4DF532F9A -:10F550003EF14B80D7A927C7247374CE971A7AA798 -:10F5600076417D9B5DEAA5EF679C7A26DB17B12F7C -:10F57000ABF798A3D6D92C71B8CE56C1D3FE28ECE0 -:10F58000CF2123E253CB727F5D90B66FE1326505E8 -:10F59000FA31513C2D82B29CE6A4F83AC3C1F0B6D0 -:10F5A000C54ACB31F65D7BD66EE1896FEA70F9E82A -:10F5B000A627703E0527DE45BCDE6F540C0900C748 -:10F5C0004D9CBC9BCE7FBFD5514C92E099E907BCC6 -:10F5D000B95332E0FCE8BA1E6E04BC7893977B49BD -:10F5E000FCF10AD2FFB4BD6AEA37D4D371DDC58419 -:10F5F0009CFD73C20D1E3A8FFC2DD1FB5EE88F2E51 -:10F600006F00F8507CAB2511EFDD309FACF5E94879 -:10F610002704E75370E2FDEBDC74BEA3CDA419E030 -:10F62000A21FB75B627CE4A9A7683F05D80D7F9E47 -:10F6300067FD49A9745F54BA7A89637444FF6E19EF -:10F6400043E96D35C7F88BF67EB56E1E5AFFD3D5EC -:10F65000FE5D26F9BE10EEBF5984FD3F79E7DC0759 -:10F660008E1B47CEE7C33B3D9EAA88F7376E597382 -:10F670003083B6ABDF9B32858F806FFD93AFA65E84 -:10F680004FDF9FDE23C8C002EB173FFEF319F0DD0A -:10F69000937C00E60BF51EBADED381DF38E0BB1B9E -:10F6A000B73BA7F0D270FB155BE678AA0A86E17932 -:10F6B000B174FA4239E373AB0346BF05E822F0FBAD -:10F6C000EA3180A75B3839978E5326F878A03B7BC8 -:10F6D000A9C7A84C2764D657FF7C7034AD6F3A3069 -:10F6E000ADAC8BD67719BC57FD08E86E272FEFA677 -:10F6F000CD9E7BFBE6545FC4FEFC56C5FFAE85F590 -:10F70000D88F4271239732F58182DA4A28CF282296 -:10F710009C99F263C709E2F1DB603CF2AE2199905B -:10F7200013FD77150B06E447D7039D9C220E19E8BD -:10F730006EBFBDF9DF71BC678D38DEAC601207FCAF -:10F7400077FF639CDC45001ED1F477E244BB63364F -:10F75000A3EB1BBC28070CC445FB5BF9E824E403BE -:10F76000DA7BFDFEADF247F7A3C78B132ADE026AF0 -:10F7700046E297FEBB51F31413D0637D2B9517110E -:10F7800074537FBCDB446C23C72164087F09E02FDE -:10F79000C54B22E17AADC837E81F67A1787B12FE1E -:10F7A00095CDCA848E7F13874B23AB2704F280CF7D -:10F7B000718258D19931CC5F49B91FF9FC69FACFF0 -:10F7C0002E19F842E008D03BC8D2DD205FC4E09992 -:10F7D0006D50AF8CF7003F1A0D484A9FE45789C817 -:10F7E0007F4F4BA1C7B1FD33936485BE3E0BF462DE -:10F7F000C3768EE408FED41678D511A2E5537B4774 -:10F8000055F00EC0DB7F75C03A4F064655981CF187 -:10F81000F9869E6FD29921DE7C00FFA47897E4F6EA -:10F8200024B869997452A10BF26C547349738C7D9E -:10F83000D3DAB94CCD2512F08F9FDA64E0E3C99694 -:10F84000BA47405EC39F87BEFFF4F551BDB0FFBF0E -:10F8500050E5EA528E8DA3F533DACDE8FDF557F287 -:10F860009242749C4F899404F2E2E96CEF38377D40 -:10F870009F5E31E8E1293CD2AF2072076D7A8C9708 -:10F880006F13E97E2C23545EC2B3D46702BE423AA2 -:10F890005370BE84C8D500CF15F328FC4B5819E42B -:10F8A000DB2AAF49EEA272B84E60F0AEDBC3F93B83 -:10F8B000E85C96DD130D8F1B7BCCC37801FFB73D51 -:10F8C000A29E8EB34AF0AF07B935968A9C51E514D3 -:10F8D0001F1E8BFE7E3509E2BCEA9F396F8E05E75D -:10F8E000BFA8707E3ADB7309AC8F5B60C1F9B43C92 -:10F8F000CBA17C759902A84F84D7507E4CE74BDE94 -:10F9000066FB709DAA2F35AD5DEA59469F675BEB9C -:10F910003CCB6815921AF0919E24C49FD5558183E3 -:10F92000C85788F8EBEBD3A13FE211A1BCD9CEF4C4 -:10F930003DF2D8ABC057FE42C400E0E18C951CB646 -:10F940009FF136DF4B319C5C37B47F5E8463BD44EE -:10F950004480E37B462FAE5B5945C4DD94AFD45B56 -:10F96000BC9AFE25FE90AEE746D28CEB5EE8CEC296 -:10F97000FD5C49BAB1DC404226C2C3FE962501BEF9 -:10F980007E4664DC5FAA27116BF248BC02F87B223A -:10F99000E0B6727B74993C1651CE0238D37204FCE7 -:10F9A0001BF79D377B62C0FDC12179E42FAC991410 -:10F9B00089C76D38DF23EABE3C78CD8D19C047EE8C -:10F9C000038578B4DA4139F05FFAAF19580E5A68F6 -:10F9D000FF095387CA585FD6CECA2DEE17BD5B28E4 -:10F9E000726C36FA3244BA3975BCF7A081C27561BF -:10F9F0008EEF76D8EF3A832753407EE2C9F3D2796F -:10FA00009056B6BF0F4D692E6C8EA17F68F3DFCC88 -:10FA1000058206E0232F32FDC25E1A3646F2FFFB56 -:10FA2000DD8C4F260D8470FFC3CF7104F4DEADDC96 -:10FA3000FD19B08F5B3324AE83AEA9745FDB6CE439 -:10FA4000379417E5D27D6DD8F7C1C131B45C3A77F0 -:10FA500010B689AEDBBBE63740CFD31298DE9CD818 -:10FA6000BCCB40FB4BBBA1604A07C5CFCD6E09E7BD -:10FA70009330B5FB15E827BC46127B693FE9ED8A58 -:10FA8000FBE62218BFB90DF1B786E0FB946BD7B542 -:10FA9000C177778F26C93C7C47DA38F8EE410741B9 -:10FAA0007D31C5C0DF5003E529AC9CBC8EF3F42248 -:10FAB00052DF8FE3A499C95C2E99BDF71721297AEB -:10FAC000F662BD1FD79B56D95C02FDA565B3A7CBD7 -:10FAD000E433E4D0F10E1D36FADBE97C0FA9FB7E9E -:10FAE000CBAE8AB448FE79E8B4453050FDEC50BA4C -:10FAF000A697066DA097DE52529906449595333726 -:10FB000009F6C795195D7FD6E8499A0A7470982757 -:10FB1000B00FFF69F324811E79A989CD5FBF7FFFF4 -:10FB2000ACEE4BD3171CF147C8A5A645E750DF6FD5 -:10FB3000FA42887A7FFA4E0B01513524BF560E5493 -:10FB4000C3770D64703DE053432091F823F0FBD25E -:10FB500084D8E36A78DDF4054F9498E39AA2DF7FB6 -:10FB6000318A28A3627D971AFD9EAE23AADCF7F99D -:10FB7000D03AE03D290F39BCD4DE9B07F29096CFF6 -:10FB8000FA0D8A7132A8E34C8E9D11430ED0B3A9B1 -:10FB9000DC6B867D39238550AE9D25642ED45F6A4B -:10FBA00030DC5003FB2B841D0BECC3E368F5D03E27 -:10FBB000721FCF2C329120EE4F18E701F053F2095B -:10FBC000D9D6FF8949027DA0FF15849F862F9170A9 -:10FBD0005422F8466AC760D040E9E3FFB8BFEA2E76 -:10FBE0002AA4A837A0D1F75FBB3D33693D6F88A237 -:10FBF000F7C4D221FA4776F3A08157F9C5F9EEAAE6 -:10FC0000999165F67D44FB9A2ACA1F4A8B587B213D -:10FC10008B3BDC9E03AFBB999E238433017E4365FF -:10FC20008BAE6CA3E54911655157EFD2D5A7EBCA4E -:10FC300063D9F7A7EDC14CB04393B28C3502E57B95 -:10FC4000A733824B385ABEA7C35C5345CB0DA54C96 -:10FC5000EE36F673328A0D157E8D32D31F6D72C863 -:10FC600054570470183C08FCA1BE8F13394A0FB6D4 -:10FC7000C0DE2096A19D14D12EC061BBFAC007D86A -:10FC80002E6EFF0506A4F3AE82A3ECBBC04728DFAF -:10FC90003774AEF102837AC3C8F88F407C9E3194EA -:10FCA000BE1BFB6A88CF36CC27CF64785E453E7991 -:10FCB0008013813E87F014FAB50DD385F6FD9F269B -:10FCC000F5FF1ED487C45B3E6913E8F7FFABE1A3E1 -:10FCD00069A0DFFD4995079B397F218CBB8DF80A10 -:10FCE000419EFDB421F71503FDEE8831B40378E899 -:10FCF0008FB3C6D508947F1FB187C671545ED76491 -:10FD000015B0724A6807C0F3C9AC42561E171A678D -:10FD1000A0E56B7AAF46781FC90DED80F2CF7A6708 -:10FD2000B1FA49A1713C6D9FAD7810FEBBC5D87486 -:10FD30003D278BF1136D7EFF36D5E3C982F5D433B1 -:10FD400039B2E4A6F71603FF5D622022A1FC76F724 -:10FD5000E963CFEEA6F0D8DD9A487A193A7A05AA77 -:10FD6000D7A631D4A7FCBE1BF973D84DF9353A811B -:10FD70000643E03F4A9C6691BADCC3FBA28D9F36E6 -:10FD8000A1792FF49FB6A408E581C5ED790AC6D7FD -:10FD90009E6F15B2E7535922E3DFBCC183DFDF61F9 -:10FDA000F7C3F7F759D9BA28FDE03EDBD47DB95E39 -:10FDB0005DD7F5594C1F9CE69EF354560AE823AADA -:10FDC0005EBD31903281CEAB872301B04FDE33125E -:10FDD000C58AFA4802EA353D3077A8BF3FC3AFD0A5 -:10FDE00071AEE78817F88BC64F7A9C9E8CE408FBAF -:10FDF000A4A784966DC3F6684F8D2723C105CF5401 -:10FE000003E8EA1A7FEA71B3769A7C4AEB60E3A4CE -:10FE1000DD57D80BEB491408FA4B962FCAEB6D430C -:10FE200039BF00E74D3C9E0C8EF6777C559601E07D -:10FE3000A8EDD767533DB7017CAEE3997DADED9B4F -:10FE400006DFA7B2989FA08EA77A02C5BBE21C1F4F -:10FE5000C293EA0DC528A055BDE12940DA08381340 -:10FE600021340DDEFF7F08AFED8807DF115E0DAD99 -:10FE7000948F182E808FA870DCCC058D698C8FA094 -:10FE8000FD0BEF411EAD73FB025911F4B0E48E0679 -:10FE9000D417B57925DEFEC2DC6B09D0E149A4BBDD -:10FEA00025FF9088F6AA5E9FD3EC244DEFFC451CFD -:10FEB000BFE3CBEAFA64CDBFAACE23B128F4ECBDF0 -:10FEC000145EC9C42E021F3D620A4D9269FB2306CF -:10FED000DFA32FC0BC47F322E52123FABB2D9B47AC -:10FEE000BCB16A7842C28E09AE613CD944F1C40209 -:10FEF000ED6B4C6807F738FD5B6F043CB966ACAC42 -:10FF0000482887919E95D644ACBFD4709480BF3862 -:10FF10003C5D14415FA47885F53D8BF3FC0AB3FB8F -:10FF2000152BFA4113FCBD8077251400D0DFE209C0 -:10FF3000580F7637FA2B165BD87823F18AD9C7F990 -:10FF400084D5BB55BC5D9585789BDA4198BF41F05F -:10FF500014D744E80B85D90C6E89A5A1E7DE013BD7 -:10FF6000E51EAB9C4B9829077E0CD29D86FD517CEB -:10FF70003995C5FC0B8897CB7E6EDFC5F89E5C0675 -:10FF800070DE60EF266BD10F65C4F96FB706519F25 -:10FF900036582427F87B97F064731EF4D761140158 -:10FFA0004FF4F0B667C7F34B866E8DF44B2E312BB2 -:10FFB000E64CA8BFD38AFABDE69F5C92C4E84AF338 -:10FFC0004F027DC6920B9A7FF20615AF46D4777D1D -:10FFD000995B4BFBFB0F15CFE4812F7297DAD8BAF0 -:10FFE000C1CF510BFFA2E3D6AEB37E00FECC5AC503 -:10FFF00018343B808FCCF18422EC2DB285ADC3F751 -:020000023000CC -:10000000A6D10F706A15C8E6C7617F14B6FE96E5E3 -:10001000FE5591EBDA6662EB52FEC11EB5AE6D0E77 -:1000200016AFF8EEEBFAF3B4E8759D98A6AE8B58D0 -:1000300052693B55CEDDD06AFF802BA64F58177D05 -:100040009275745D05C3EB9A93CDF8E912958F8D87 -:1000500090BB71F7F17FC87ABB1FF2C45AAF7E9D87 -:100060004F677BAAB353906E8262E9305EFBB6D2D3 -:100070007595C2BEA6F8DB705F197E12E290818F83 -:10008000B52CA7EB82675B1AFAA59698A53EF0CF30 -:10009000928793D47512E4032D5BC7215D52BC6532 -:1000A00074FB108BEBB45899BFA0658D282B22AC44 -:1000B000FFD768CF86297F45BDA4359AAF7F3B1C0B -:1000C000AC99B5459170B0642E2D8AB1EF8A19F1C3 -:1000D00039DEBEFF071FBE95CB8EEF2F23EBA2FDAF -:1000E0000DE0371C2AF323CB7AFF05B51FCCD1DFF7 -:1000F0002BF1F8C14F23F1E88851C5A3B556943FC1 -:100100001A1E1DB1B3F5EAF188502D1AE8585BB7F5 -:100110001E8E4B008E31E209149F72018E4754FBF4 -:100120008CE2532EC051A3831B5A193FD0C3ED89D3 -:10013000F87CEDBBAD4387C7DF751D5A7DBC756884 -:10014000FAED166ECD56C0CF2D1944EC403D383433 -:1001500009EC2497C95F08F3DA66A2F44BFBAD55AE -:10016000C707CD01F0FBB343CCBF79541D573FAF58 -:10017000E75539A4F77F3539C23B410F694A60F230 -:10018000F0CC013BD20DC9092D01FDFBEC7E330102 -:10019000FEDAC885F2E0BB339C67297ED7962881BA -:1001A0005CD4FC86C79E677E438550FB17FC753E7A -:1001B000E6F76C52FE753DECC3F96CA119ECCFA6C5 -:1001C000BE683F195D9F03D67BC64006E1FB46DE55 -:1001D000BF0A4CD6CD26A60F6C369000ECDFB05D82 -:1001E0007E340FED840C91805FA7D1F041DECD11FC -:1001F000767CA35ADF98C9FC4C1057467F390CE532 -:100200001E0997C67B4E7D0D71B1C67D7A7A89A68F -:10021000A7FAE132779E83FE22EADDC3F484F63842 -:10022000E06115F1E772E01F63E5C4B9837E884F92 -:1002300037A9FED394815035E80BF6D200013EDA9F -:100240007482D92133FA77BD0A7E33E7DCC171A00D -:100250009234A97104BDFD33BDFF7E1EFC439AFD9F -:1002600012E18F2A5C10E5576CC776E0DF82F1421D -:10027000F00AFCD302D37337AB7A2ED587916F2E59 -:10028000EFCE477D18F455D03B34FF18E821A08FFE -:100290002ECCA91072E83ABFCCA9380FFC1BC6437C -:1002A000BB1F9C2ED3BF817FA9F0D1BE033FD9379E -:1002B000FBF3993E3543E7C7BFF98D14C4F3FD71D5 -:1002C000F4D45139437EFC34F0E3DFCC496980E754 -:1002D0001FF23EF4D7AF200AFA8157817F1CF960E4 -:1002E00010FDCB373513B90BE3E1BEF5506E58491D -:1002F000C42EF02F57F9B01EFCCB574E67F12629BC -:10030000027F219E1359267B68398A4F0FA2BFBAFC -:1003100091F6B04D063F42F4F74DC45F29005EF4FC -:100320009D3747F5D3C3E074838A2F5BADCC4F3D37 -:1003300063DD2E9E44F81992A678DC77013DBC61FE -:10034000443FE9FF56F75783C7D3D915D61C0A8F08 -:1003500004F0FBC077779951CE1E379095802FF728 -:1003600039C90D0BC09F7527F1E418012FC4CC4883 -:100370007F97F6ECDA6F5D0978362B87F111EDFD8A -:10038000996C2396D1EF8CFA6922C6D1295B2A0693 -:100390003C2CCBD2F462520CFEEE0F54FED4B8D0FB -:1003A000E683FE4206C6CFE6E530BB7B5E8E09FBE8 -:1003B000D3CA43FE2215CFE838D85FC2541215C7FE -:1003C000BB2A87C901CD5F4BD4F8CAE655094C8FCB -:1003D0001EC27703F2B3C422AFC987FCA402F95945 -:1003E000F8CF3609E032F754FD2A58C7A78B120818 -:1003F000E41D2C53E3448D394EEC578B0BC5D0BF15 -:10040000AE0FBA86E58D869F9A9CD96F67EBBED8F2 -:10041000F8BEFE39B7AB10F9B7368F193ABD241EB6 -:100420005DDC364C1751F12D0AD744E0B3FB0DCCFF -:10043000EEDA4F110BFD560135FE48ED649003FBDB -:10044000F7E5A39EBD54F5A7523989F65598CA0B16 -:10045000B6DFBEADCBE1BB402EC6653F30FA9F7C18 -:100460001CE4ED01664768FBB17FFF183FD0EF8CBD -:10047000535F6502FCF79F786A0CC4BBF7ABF1C50C -:100480007A53300FED7D13D353EB1DC13C80DF4B0E -:100490002ADED427D0327D9F95E2EB063EA4E50705 -:1004A000403B27AE477280BFE1986A471EA576257C -:1004B000CC8B52CB20C43DE97E674039BC298DE905 -:1004C0007B745E8017C70E4CC2F56D36323C565EAB -:1004D000E4D03F71D418FEB0957E7F34632A69134F -:1004E00041DE7DF1F841E87F274FCC22E45F7C7E3E -:1004F000AE8F7E7F96DAB9E037AB3378AB33805F6F -:100500003CCFEC75FD3E80FC8B8CC79D21E14CF40B -:10051000EBADCC0A00FE9CE92FC4BC22E21289425A -:10052000CB4D2F32FB461F273E6E8CC67F7DBFB062 -:100530002EF0AF35C1BF41BE47B68FD1DFB795CFE3 -:100540001843796B293CAA245F302785B163D8CF43 -:10055000A69733901F1FBBF773DC4FD2CDE29FC726 -:100560008D9E25303F6755D0541B818FEFA8FCA38B -:10057000CECCE435E5BFA6487EA3D59755909871BB -:10058000FA3FA87CC13EC8E4DEC87A86E7B7924746 -:1005900079E017EFE448D8DF7835DFE056F2D92B61 -:1005A00066D04F022598CF307E5D10F9009D2FE276 -:1005B000E7F1AD49C81FC93D0C5F6F7CD88CFCE3E7 -:1005C000462A3F98BDCDF2ABC83D2C8FE2C3BBDCC1 -:1005D00088CF65EDC132A4072791412F79A1F3039C -:1005E00085A7F54BF77025903FB6B4D38D76CA4DED -:1005F000FBDCB8BF3354BE5E67F660BE187984C5B5 -:10060000D396FD62158ED390489C3CEA7F7E13C83A -:10061000E5957B3802743523C0F87FBD107C05F466 -:10062000487DFE03F147C789411E91083D13E40F41 -:10063000D1D905D1FBAE5C94FCD5CB1B3E37B6FCC3 -:10064000A5F69E90CBF695C989BD1CE31BAAFC6D4F -:1006500000F90BBA9A2AF734B9B942959B1FF24CAC -:100660006EDF68BE1F9F19B96E1CE72688EB621CFF -:10067000336C02FD241E5E64E432BCD2F062746E00 -:10068000345ED49F081E34A39D293F0FF1EAFA750A -:100690002468A776DA8D4233CA87D1221131AFAEF2 -:1006A000D287F34A6BA1FA39DDE71B21063BE5E26D -:1006B000F582117A804EFE6BF3D6F044AFFFCD5831 -:1006C000E7E7219E74328FE07BED29924009CCB799 -:1006D000C6C2F4EF1A8B2DC883BD59653C1D696FE6 -:1006E000FC58F094E5A25C1DEBFC7022B20802FD00 -:1006F0004E737B664D9836AC57269686D7DF4BFBFC -:1007000033926203F0496D7C8B7BF692220ABF26FE -:100710006110ED15924EC4DD74BC2B8B249C4722D6 -:10072000DD875D14AE464141F8192DA2B3CD09FB1A -:100730003F887199700A413F9DB65F3BEC44817CD4 -:10074000C52B8B187D5F5924E293B6C738AEB180B4 -:10075000B6A7FD57ECB7225D9E7BD1EE07F94CE5BD -:10076000CE7827AD4FFD13B55368F9CC7E3BEA290F -:10077000675479E1D2FCB5643DEEF722156F14524F -:100780003106EC11C25D3186CE9D687A7283335E8C -:100790001C53AD770F2E64F86B467DE19C33741BC0 -:1007A00094E97C30B7C69BCBD6DFB4AFB2E40EE0A1 -:1007B000DF5E9BCCA0EE2B01FDC7CCDFB2D0428127 -:1007C0005DCDAF0BAF05BC1F6713CDB449D5F8F7AE -:1007D000FFB09896FFBCCF48CC803FBBAF4A0A42DF -:1007E00033C193EE9D34723EABFCC6A3A1083A5EC2 -:1007F000BD27BADC10882E3711E1682882FFB7BE0A -:10080000BFEAADD722F06D6DAEDD05784024229FA2 -:10081000A7F474FCCE3E720C6421FF9324E08FCBCE -:1008200028F9C7D22B3EBF73E55BAFD1EFACA68AE8 -:10083000B65C940B9209E8AB96EA0DB1ECD0C9B95D -:100840004C4F339B9B4FECA2F031BF6496DB68ABFF -:1008500079B9BE2EC0C74643F820ECAB79FCE962FB -:10086000F067578CFF0AF302CEFD2391014EE7ACEF -:10087000B3119FCE6DB54A60A7F664DA981FF6658E -:10088000CECF31BB65FEB454C8FBC0B5503E165E3A -:10089000BF15F8F474B3D82EE2722D06DC6F6ABD72 -:1008A000D1678F49590F7ED51E6A40B6C960E70DE2 -:1008B0003A80180655FED0C43F63B2D07FBA3B3DA4 -:1008C000856DF4BBD5DE0402F978C2D78217F06CCF -:1008D00003741561F73CAEF2BF46F1EDF5307ED3FF -:1008E00057B7CC4D310CFBF9CD46E6E737F6CD0EC8 -:1008F0008EA14D57B456A27D47F92DE38B07185FA3 -:100900005CB17636BEE716CCC5F57E48D70B70795C -:1009100075AB19D7FBE1381BDADB1FEEE0B0BC4248 -:1009200034613E1FD54F46CD76C17BA3682623E1B7 -:10093000D1B465C3FAADB4FE77193CE128FE7FB4AB -:10094000FDB7188FF888B0F1957D3CEA3D1F89E12D -:10095000B220C0536A7644DA932B76F05EE0972B90 -:1009600076DCFABBE900B705D795023C66396F49DA -:10097000956CC3F59ABE2724973F0E7439EBEBCAEA -:10098000C159A077EDA07443E72D18880FEC8FD7DD -:1009900076FC10F5ED1535094E589FB47D7735C8B6 -:1009A000B78F6A461B705DCF72440478385B53E1A1 -:1009B000FD0A4EF0C6C2AB65B92C9E307BBC4D061D -:1009C0007FC38ADFF3882F94CE16421CA161871162 -:1009D000F5F9D716BCF787C5AE613AE3166C993FB7 -:1009E00003BE7FC288DF0FE953DB3F7E1FFC02F0AE -:1009F00047253BC821849F9EEECCE3D7E5C1BCF4DC -:100A0000F4B7A2BD398FC5F72F8E0EC9764687275A -:100A1000299D9C37FC4D74F829E3EB174687646CDD -:100A20007294FC1EC9F714FC4E8B8F5A64E2D96D88 -:100A3000C37C180F47F9F5983C01E13E268FD96D2C -:100A4000C29737EF7993C26947AE4FC8A3EFC71378 -:100A50004F09C867292C56802BD6A6EA8D643BCB5C -:100A6000F306FB02F67F730A79BC2BC23F93A6F60E -:100A700047F9821DFA39F3C7AF0EC27E35669E2E46 -:100A800006BDBAE98BFFC4BC0A5B3FCBC7B1C961E5 -:100A9000CC3732BABC888F1ADF6F92991CD2AFABB9 -:100AA0003D8FD9AD4DAE30F6F3423EA34F2D1EB96A -:100AB000AD3501E342DB5C7E2BF3B3507D8FF63F17 -:100AC000AF94473E6329ED2020C748398FF19C59E8 -:100AD0005FBD4520FEF5BB999532E895B6D25785A6 -:100AE00051B0CE72A35AFFAB8D59B4FEAD9973D0FD -:100AF0003EBA399D9740AF9A579AADA0FCF4B0FC2E -:100B0000DB595F25211DCE5F351FF54A6DBE5E6244 -:100B1000916C144F1650628DCC539E3FD32AD9222C -:100B2000F0EBD36E6E2ED3ABA5A4AB2731BF50A094 -:100B300088C9F34838DC9C6EC2F1BFCC997D09C0EE -:100B400077D6656C1F4E3E6BF6B7D3714F5A63DB99 -:100B500091D5790C6FB284CB912FDDF2AC19E3F310 -:100B6000A7B8D8DFDFB491C7BCA2551B39E2A7E311 -:100B70009D7CF2854CE0EB7FDEFD42666DC47CE23D -:100B8000B5AFCB63FAC0487B3BB82CD2DE9E676220 -:100B9000710132C51CE5DF9DE750F3EC2F30DEF12B -:100BA000A3B87EFE37C6C27CDF1CF2F3BF3E3632EE -:100BB000DE3114B792999F5F1FAFCA29FF1775BE28 -:100BC0002CAFB95550E72B9B59DC62398B8BB71C86 -:100BD00018857837CF14FE39C6B35EE64535AEE1E9 -:100BE000B160FB74561F675DC4E3C97195A1BF096D -:100BF000E7C3F57141BBE33BAC8FB038867E7DB572 -:100C0000FD7CCCB8DC97F92C0F20B1288C76D5D19F -:100C1000D71F85C8FB10BE5BFBDD86C87CF8217D35 -:100C200056C5EFAB00BFE9FAAC1B59391E5EC7E3EE -:100C300057A9798C8E35FC3EBA313B09F0ED2E4B2D -:100C400063E820859F874F22D6D1B4ACC6FF95F7C5 -:100C5000593E2A1F61E7001DEC78DF8E764E87B182 -:100C6000F91138BFA3B40964377DEF4A68F4B7D1EE -:100C7000B264B463DED4ED09F377815D17A20A2E66 -:100C800047CB9F271CD9057A02B12411231D47A900 -:100C900050DB9B2C6207D52F1E4A74207F695D466E -:100CA000507EA79120C75180ECCF63F9AA29AB9F52 -:100CB000E7308F98523CE87D72766C7DF4572A5D60 -:100CC000BC0B0934F42957C6FE6E7F9EE617137CD1 -:100CD000A1083B6F03274BC877E85FDB74D0EF07B1 -:100CE00017235FA67AFC5B541E8CE17F8DFED963CF -:100CF00077FA1E8975DE6148EE56C6B6D35F55E7B2 -:100D000057D0CDF98D0EA45FC3AE28FA55E378F61F -:100D100054994A1888DFB2385D0ED1F2DEB780DF11 -:100D20007E74399BA3C31322A05FA4775F4E7CA37C -:100D3000809E66A4817C6B591EED4F4BAFDD988180 -:100D40007EBDDADBE683FCDE62B46DE492E019ED91 -:100D50008FDBA2F3C77D1B5F488F4B37D3D3C1BF57 -:100D6000B16538FE87F8D3B154F4F31CAE8244C6A3 -:100D7000B5533BA4833ED083665BE45E7924FD904B -:100D800072391DFD9CF9EABEA9F4DCA4A226D7CFD6 -:100D9000A15D3A921FAAF06C188BF0B476DF8E76C4 -:100DA000536209F36327AEAAF501FF49A4FC07ECDF -:100DB0003893A999C3FD9FC1ECB6168E955B668BDF -:100DC000A242BF37399A6763FD152CCFBAC5EAF343 -:100DD00045C6D32E35DC3C3B32BF5624B43DF0E152 -:100DE000456CBC7996752CBFD74775A48C61385675 -:100DF000A870CC294F60F9E6B75AD0BFB5DDDA8DBF -:100E0000F33548CCCEAEEDB222BF1BC31760DC6415 -:100E1000C0C8F043B15B905EE58177313F6CCC2573 -:100E2000E912EF8EC09F5B58BD861744975760321A -:100E30004907C17F472722435E4A0B271DACC07577 -:100E40008961458675AB7CB93881C9116A6EA63354 -:100E5000B8B2B8986EBF28DE30BFFA241BF31B115E -:100E60009F847A976EBD23F1E6C502E0B70343780D -:100E7000D357108BDFDEE7940EF646E20B91D68354 -:100E80005FF56E030977C5C21F39DACED7E7C9E926 -:100E9000EDFDC6D64AAF6A7F2816DC4F13DA1F8DE8 -:100EA0006B677B99FD51D006FEA7A6755452D136CB -:100EB00095FD9C05FA6B5AE440FBBBA96F2FC6CF8A -:100EC0001BE71219A651ABFA87B5751E35B2381E4D -:100ED00095590188DFF738433BE17C5DCF2A2D8FA0 -:100EE00087E5B5287D9C9AC7A3E57D858F80FFB3F4 -:100EF0008793D00F3A744E8FEE3FCBDFB9B83C30BA -:100F00007B91D70D96F8F4DCDE7F4B98763179B47F -:100F10001FF5409E6CDC3C5A25780DD45B602FD4C5 -:100F20007A4003AA2F6B658F5582FC9DE17A81DAA6 -:100F30009D963E4E1DAFFA9A393978BE46EDAFFF09 -:100F4000013847779F95448D17393F41D73F989691 -:100F50003649FB7EFB02E8EFC1296A59F9FA17907E -:100F6000377C9F31BA3F4419B53D14B4F1D29E7E0F -:100F7000ACE79E99C37A3BD5E3FF317FDAB0FEBE82 -:100F8000E1BD79DD93E95889E267789E49D3C39B37 -:100F90005C2CAF568FE71B553ED6600955836ABD62 -:100FA00061D11A2FF43B94F7D6BFD40376B096F7ED -:100FB000D6B4CE8BE79AA8DE7F4F3EE4D1FEF1F4A3 -:100FC00087AF10B0334FA23FA0E90B81F99DA9FD77 -:100FD000C0517CB1F4DF8FF843F618FDE0DAE97117 -:100FE0002A04F0B1E700370DF08B90E6CC6B28ECCB -:100FF0008FE77B7A601D67E2C4C79FCD67767B531E -:1010000041C5D63C80F5631C017DBCABE053B42BDD -:101010001A5F9C332DF21CDEAABE07D979AE3DC6FD -:1010200098EB7E369FC7F535BEF81CC64F4EFA3991 -:10103000A4B995827F13D89B2B571AC0B222A5FE64 -:10104000A598274B169908CCFF01D50E69DA739540 -:1010500002E7029BE87F9404C836EF8DA86F6F5BB0 -:1010600064B1411CBBA9A0760DF23B31C103A69C23 -:101070007E9E43F96F6B13308FA6ABCF3817ECA46D -:10108000324A17FF6403BE7AD8BD0BF8E7A8297C63 -:1010900087087986B1F5EF670A991CEFE4BCCA8F1F -:1010A0004B312E4222F399C7F731FBEBB57C5354F9 -:1010B0005CF0B57C6617CE54062B01D75E164289CC -:1010C000600F3711CF27E0F7225E9B847121124019 -:1010D0007FA0EB4E09ED268B2B74F764A89F29A007 -:1010E000DDA4F911CEBC9886FA584981EF30E0456D -:1010F000191F7AE0C700B7BB0535BEC4F84AE655EC -:10110000B629605F195D4C9FB1527D06CE7B5CB6FF -:10111000E9F8BF56026F7579518F2054C8C1B9F1F3 -:101120004A0BC7E22B3ABD99887215B4AF56FDD26F -:10113000B974B73EB4206A769E1F05FE0C9702F084 -:101140007E9D2E6014AD9F433C9DB02F5FAAFBB7E0 -:10115000D9C4F4F5CD060BEAEB9A3E9CE81A443B61 -:10116000B121C0E1380D05BFC6F302ABD5BCF4A177 -:10117000FC702184F9F2A7F313D5F86727C34F3227 -:1011800088FE30F20CDB07AA79621EBD06772DAF10 -:101190005CEBCFA4C64B1B547F2E0518D67F9EAFA9 -:1011A000C557DBA3E3ACEAB84490CA22FD8E9B6B23 -:1011B0000819C479490E986F57AA9714D0EF8F5227 -:1011C0003C063C3BBA31D10FE7B63673831E887BB1 -:1011D00028252C9EA1C7A794024E3D1F14AEC6BC65 -:1011E000AB17E39C0FEA8B3E1F44F9C39ADFD07123 -:1011F0004A4BDF9301BFEF73AAED2F27984FAE3F05 -:101200001F34BA40C271FEDBCE07C99CA7973E735C -:101210000A9CECFC8F763E486670D7F231F4E78288 -:10122000CE64040596C71FDAB91BE59E19EDBB977E -:101230003E3ED809FEE2B3252619CE43A45EF77AD6 -:1012400027E6C5704233C415F5727D97BBB218E02E -:10125000FFE035CFCB98F7AB93EBF1EC798C794687 -:10126000F87B3CEA7E7C5FF6BCB5FB7307E0CD29DA -:101270002EFC73C847550EF031F3516F28E0E2E4BD -:101280006D791645EA999D5ADE9633212A8FB1333E -:101290004EDE563CFD5D889BAF7539EA619D43F992 -:1012A0005A73353D2C3A1F554CF846BB571B7F6E81 -:1012B000C81D155FBFE582D7A9DA2371D617CFFE07 -:1012C000BAD87C013D1C3AE3C8C37505F1F2053C70 -:1012D00022C4D73B21BE4E9F024714F483ED1DCAA2 -:1012E0001708A2DFF7B97CF45F99E3E60BB03C3254 -:1012F000E140BE04DF6D307A3D6097287B8D2A3F48 -:10130000F73F09FE8FCE0319E82F2305A162E07392 -:1013100082B33A1DF4A34E153FEB2F3C5F6073413F -:101320008C7C815DFE293FCF6276F06022D5AF765E -:1013300011266F947EE69FA4F346FF5CF8DE71A849 -:1013400077720B2CB88E632F9B7BCDA84FCB18FFE9 -:10135000AF4DE74590133D35651F821C3A46155049 -:10136000A0E3BA9BD6A11D1A6F7FEA3646C763B5C4 -:10137000F717BA4FCFA9FB7414EC7414980AFA7DCE -:10138000576EE45EC1BC5B5D3CF805E021C8EFA38D -:10139000E3FBE7ACB331AE7ADB2F6A309EAA9DA3A4 -:1013A000D5CECF12356E226D1490DF4B7B38BFE463 -:1013B000666462401B5D34E07D1E544C6D03D1A613 -:1013C00050AAB984BEE60C1CE89B52272DA7D17504 -:1013D0006D129474FADDAE7713D18FBAC125A9E7E7 -:1013E00021981DA5DCC3A11E47FB453B58E9A47805 -:1013F00043FB79A780F9F7CF16303D83A2881FE71A -:10140000A33E3BD57C086DBC366208C2D3C0B1E7B1 -:101410000651981B4B4FD3FAEB34365B206E121EED -:1014200067C0B8E439936711C6F592F308D87D9D7B -:10143000F6E68D73593DF2D073D6B017EB7F2030AE -:10144000859F48C930DF37D5FDD0EFEBF2EEE8B22B -:101450003E6EAFBF17A08EF8F233B2479E937F5314 -:10146000956BE7BADCEABEC818F7EE344AFFE60629 -:1014700039B7494079DA3696C1CD308E3DB39C55A7 -:101480008B509E3AA99E89F365F3CFFA818B03FABC -:10149000EB7432FCFAAEF3D6CFF7F3823CA63F8270 -:1014A000F24FC7EBDCC4F919BCD8BC2FD4EF9C5267 -:1014B000F8FDFA9D8F71F2E341C0339BFF61F0DFCD -:1014C000D5B59945E067A73895FE37F1C8CFB6ADD9 -:1014D0004CC6F2D18DB9E8CF19A2DB13EBD7C07D92 -:1014E00007179A7F955FC8F0E2773A7F5A6D397790 -:1014F00018FAD1C31D104AD0E40F6D5A79555135F1 -:10150000F0C7460391D2401FD8A8CBF3D0D1739532 -:10151000E49B5608FAA269F020E353A13C01F56868 -:10152000AB0C707BD0706CEF6F015FF65A316FB00F -:10153000715DF871F03BA64ABE998514CEA7D7BE5F -:1015400057CD49D81DDA5B670FE4E3FD19B59DBAA5 -:101550007B09EE89CE2F211B9359FE464FF47B3831 -:101560003F1FD56E44DE09D33F379B7C856027CC77 -:10157000BA8CE5EB7DBCCA40002F3EB632FC51EE82 -:10158000B5AB7246CE8BD44F1717EAF4987BAD8873 -:101590001F75EA7925FD7E34007ED07DAB57F1E3DF -:1015A000E3E72EC903FC38BDF7923CC08FCDC66E71 -:1015B0000FDE2390E3FB29C0F1F81CEF4103E34B5E -:1015C000791783B7F5FA79FD9DF4ABBB0BE3C54DF5 -:1015D000A49F44C64D068CCCDFA558A3CFFB0C5C62 -:1015E000A47F34BE9FAB3027DACF55901353BFB2E0 -:1015F00058BF51BFBAF875103CEFA5C55306ECE1D2 -:101600009F3F1E01AF162BCB2B69291445A504D68D -:10161000579B8DE7C7FE68917BB9EF759D51FEBC66 -:1016200097BFCA5EDF0DF3F030FFE3CB8274F05258 -:101630003AEECB84F91FF5EBFE7D3ECB83D1EC6710 -:10164000CD9ED38FBF57DDEF8142CF4B601FCFFAC6 -:10165000EA3CFA034EC03D39745C8BFF9FD02E23C9 -:10166000FD9C88E7CF2416CF6C7C71F9A3E03F5D29 -:10167000E557E390FB38B4BB573DF609D69FE9AB7D -:10168000C37A5B3F17847866D35803CA6D2D8F41A8 -:10169000F3E334F5CF2680A79A1F87CEE30598475A -:1016A000A22B6C42BE0576226DD728B0386DA38B75 -:1016B000C80AB0DABE68FF8796E7B4CD6B427ADF1E -:1016C000D6CFF9C1AE4E35F9DC63119E63C50F1359 -:1016D00087F9C65B859ECF805F6979684F677B0E0F -:1016E00003BDBA4C2413F3DDD5FDF00DC577D879D1 -:1016F00089BFBCCDCE4B84E2F0EBF70BB5F3120BF8 -:10170000517FFE0BF126C5CE23F7B33CF2A1BC35C9 -:10171000962F5E3F8FDAC84E56867B5F1AE0DE1743 -:1017200099C9CFA04E7E4696214F2C18C137EB8524 -:1017300041CC47D7EE7981BCB1C8EF1BE1BC45363F -:10174000CB1F8BEA47E5A769FCCD18C789113FFD80 -:1017500049A4FD7148B3B34AB4F3316113F8695A2F -:10176000DA5C6188071CB2ABE776D5BCD8166BF89B -:1017700018F8315A9E4CC3732043FAFDB366D50F57 -:10178000CEF0BE9EFD9334AD3C8AF67A139CCFE733 -:1017900086E9695E5CBBEC8D1C88AB1C1AB2CB5E23 -:1017A000CF8173341A9FAD9719BFA8EFE3D879AAF8 -:1017B00040F4799A3113BE5FBEAB7D17AFFDF409DB -:1017C000F1F8EDB7C199F1DB43F1CE21A97C528349 -:1017D000A39E1F5D2CFC86E492063F4AD7C86F7516 -:1017E000F0D3FBC334BF16E914D1EF45759200E482 -:1017F000656A7EAD0B9587F3BFE77DB95079D83028 -:10180000219E1DFEDDF6279E9CB8D87D19210F6113 -:101810007F8AE3CBC39CF27F51E7ADCF2750E7AD82 -:10182000CB2738640CCF67F75150F8B847E613C49C -:10183000C5BF6FC927F81BD6A9CB27F8E675EAF311 -:10184000091E39F09003426E70EE0CFC0E03BB8D46 -:101850001847AFE66D1E96E7C5B3BC50E2C1FB3139 -:101860009B2C56F42FE8F3E028A75ADF0CFA6539D1 -:10187000D5FBE15CCE8E0E94CB0D193CFA1C21EF0A -:101880004F9462E4590A3549416964BE17E4B1E3F3 -:10189000F9FE8BCCF7DA336128EFD2FD37E65D062F -:1018A000265C40BE57712EA3BB576D9F8D8ABCBF6F -:1018B000B2A2881AEA45F1F3ED5F56E93551CDD36E -:1018C000B5080A89F447C56B777002B3775E358532 -:1018D000DF0D805E45BB81F865BA895AD3A5C3E7A1 -:1018E000D68FE77B5F87F9537D04F7F7CC8BEFA0AA -:1018F000DFFE910C2242FEFB234605F75949218861 -:10190000D75A5E8236CE5AD58F7DA1FCE7C8DF5903 -:101910002EFCD7FF74BE33227F89D1E3DFC06F90E6 -:10192000FE86F88991C575B47B2BBE55CE7DDF7CD4 -:10193000469777116F5D5FE613C487F113BD1913E6 -:10194000918E3CE867BC58F997584AF52180C73E0C -:10195000B304A46651EFA720F764687E5176DFDFF9 -:101960007DE350EFFCD8CAE6ABDDBBA1AD67CAC4CE -:10197000EFD78E2DCEF1964EA4F33E3EDB83E77774 -:1019800037D899DE167E92E5AFEBEF91A074C3EEE7 -:10199000D550EFE1D59F87AFD6CFEFEF24BF974F5C -:1019A000FC1F4E471729BF2F7E1DD1F6EC213BCBE4 -:1019B0000F1CB667FFDBD67551F25ACB172EAB184A -:1019C00054FDFD1C017FBF364ED3203B6FB351DD6C -:1019D0004FEDFDEF54FFDEA1899E4D4087A5A5C1C7 -:1019E0009D70EEA49138F01EF1C6C0ED7BDE74B19F -:1019F00073B4582E607147E2B5E139EB1DB9BE07EB -:101A000018FD86D6037D8E779132881B74152C20A5 -:101A10007536CC277808E860FCBAD0CE374B319FBA -:101A2000AA19E855CB272E3BFFD9FAB9A5385FF4A0 -:101A3000FFBACCD1F76FF44D64F6A0F67C4EA50347 -:101A4000BAED19309FD32BD9B9D2269747043FB2AC -:101A500016BF4E940631FEDFB88F194565602B42E4 -:101A6000FD1D6391BE1AF7CD2E81B82609584BF0A3 -:101A7000FEDD3FB17BAF4FAF1D8DFEC69202DF2F63 -:101A8000615DF652FFE560478FA7E340FCF3F4DEAB -:101A9000CB4B7C31F8661A9FAC407C388D27810790 -:101AA000C461BE45EDE7C5E82F5E1F463FD6CE892F -:101AB000128B27BB985C6FEAAF21CB6DC3659B2B64 -:101AC000FA1CD540E19C9D308F9D13595C5FCBE79C -:101AD0007453350CFC867A7C72ABF99C356ABE3245 -:101AE000512CC379CA59DF9ECFA9CD4F2B6BF99CDE -:101AF000895F30FB3D4B3461FE877D23E3AB641D82 -:101B0000C1B8C1CCF060651285534E4F7026C02914 -:101B100009C08EF7B186EE9E4CDFBB460933C11F6C -:101B2000B2B375CA00E8BFC2A6C11FC09648DD6245 -:101B300005B81877E47ADF033C21427301F0A58AE7 -:101B4000DF1BD979A34D89A857F664D6E379A3336F -:101B5000EF9963DE27A03D15D29E0E7187AC8DFFF5 -:101B60008EF17DFB3E2EE6B9B44B8B6CEA79A4F680 -:101B7000748863D8370E2AE5B4FFAC7B39A29AD1BA -:101B8000195C3AF8870503C8D7BA3E764F5D5DB752 -:101B9000B3C282F286F96BC84C17CA1161D395069D -:101BA000E013421BD562E93AA714B1F8746E8F684E -:101BB0000039F5CF5FF331E348E755BC6EB0844C94 -:101BC00000AE0673F860BA7B385F473BAFA2F97B83 -:101BD00086E4CFBEA5E8EFB9F8FCECF0F598FFF786 -:101BE000752AC657E639983D4205917A4F4B74FBEA -:101BF00011F7B4A87A8B6617EBE9409FEF9C533E30 -:101C00001AE982F2D1C036318AEFC5CC7B6E1598C5 -:101C1000DE4DD7616A8179CC4E97C13F77A179E6D5 -:101C20007A7B7A48CF51F5126DDE7F6B5EB6565FD8 -:101C30000FF9D831FC1F9A5ED3A99D67FE9ADDA3E8 -:101C4000355EB5278E76FD5731BBAF50CBFFF0E345 -:101C5000533052FE89F813BA4C013CD8E73434169D -:101C6000617CA911FBD9C4EEDB1FBF31BBBDBC1425 -:101C70009E22E128BC8FEE5F3D1EE3B7942E726377 -:101C8000D0C5918946D6FFA644C463E17E82D98C33 -:101C9000823315F1587890E1EBBB13197E69F9672F -:101CA0005A1CF0D0449F17CE1B0EDDAFD19AC0EE68 -:101CB000D750F3B8EDADEF3D0BF756EC54E3C0034E -:101CC0002F4F5C80F1B94D0207F6E139E7D2F1E020 -:101CD000BFBBBE88E1B95D1824A22D925E07F01C3F -:101CE00060D601767E4950F34D854DAE5D809F16DE -:101CF000B70FCF3BFEA033C8633E9378FC81B91287 -:101D0000D81D6113E49F9D6C13C2ED4ED49FA2FCBD -:101D1000647ABF171102985FD354F4F7B543EE2DE0 -:101D20008AEB9FFA4EE728C8B7F8A7BE2B5EC7F329 -:101D30004F5DFC3AF4E727987D425E66794A31D6DA -:101D400015E5BFFCDED7A5F92DF5796723E898F9ED -:101D50003F347B488B3F108F1295173E601483A051 -:101D6000F7409EED7332E8D54F5823F3C29E57F1EA -:101D70007EE8FE3EE2B7C2B9FB8FE1DC30CA3B79B8 -:101D800023C4416FE7EDDD60DF7540BE3EE897009C -:101D90005F2EE2DCC2FB76CC7B6815D8B906A2B018 -:101DA00073112DCB9B9F80F62D6D6922C05FA968B2 -:101DB000FE159E7B30106F077D7EAEFEFE84361FC3 -:101DC0002D8F3F9EFC1C91C7FF2DE71032E29C43F4 -:101DD000785BC5FB826504CF21908D9E5D30AF9E00 -:101DE000368140BC37792E2B8F172CF87B2856C8AC -:101DF000871E85E746316F394CE109F9D756C88708 -:101E00001E05E744D87D85DC82B9887FC9143EA0D1 -:101E1000177418D9FD84CA3536C4A7CAB92C7E995F -:101E2000EC3521FF394B64CC9F57E01E3317E05946 -:101E30003BE267D89E8AF1D7E41CA6475ABD2683A9 -:101E4000C58DF9CE88AF614ECB77667CAF67A9842C -:101E500079E843F7152E27B83F9B72AB33E0770044 -:101E6000465F65E2205EA3C9990A153F7A76A9ED1F -:101E70001B587BB8CF10E6475A58FBA1FB0C7FCA12 -:101E8000EA5B8510DE07447518F53E3D56DFB23833 -:101E900015E98757CFAB92EBD47C7B8EDD1FD5B293 -:101EA0007834AB77303E486E4A50E5B9DAFED664F6 -:101EB000BF1A2F6079F3AB0CEA3D00DD24329EABF4 -:101EC000D159F2B79CBBF8C570FE3CD273C7E5226E -:101ED000E6076AF73156D84CEC3C96259AAE9E2917 -:101EE0004A66785F2E5B60DC656E4FFAA498FCD181 -:101EF000BF3492AF8CD6F8CA4D269D5D96C6E0EAF7 -:101F000008EF64E7B6CC176597C58F2B3E99111D76 -:101F100057DC93111957D4F6B762A509F94A8F53C4 -:101F20007A0DF28FB651D0C2FD76FA756F1BBAA743 -:101F3000DA6F05BD546F0F1E8A9367B46812F3E71A -:101F4000C971FC108B26C5932F71E2B425E6FFA65C -:101F50007833E3BF0371CEE90DC14BD39B2CFAB8A4 -:101F60008772517E9F01CBCF900F7A3A0462BD8C6D -:101F70009675E7CA281F44BEA8B49BC50E17F0D1BA -:101F80009F215F6CA596AB39822F5273F412E0C784 -:101F9000037716E0EFCBBC76A78CCFB3562EC04F9D -:101FA00086677809684C4B8A0F2C847B9BCFDAC3F9 -:101FB0009970CFF3BAC96F5C8BE594F01128DF51AB -:101FC0004C16613937BC13EE7DBEBFB8FD5AB8D789 -:101FD000F92CD0D868426E7DF6B66B9522FC3D8414 -:101FE000F583A0DF97EAF2F175F7D0C2B951584FE7 -:101FF0009ACD8471DF34F5BC2EA952FD4390E905DA -:1020000074975182797A3622ED1B84FAB14CEED264 -:10201000FA36B8E7B423D7CDE2D084F1013256CDF9 -:10202000E3202105FC511D6E27B61FD2EFF699D58E -:102030003C3036FEE1E7D8FD3CDA396442C47160D9 -:1020400037DA241255D6EE752682380EEE61ED5041 -:10205000F1402BF7A7F91E9A1461571E9E737B114E -:10206000ACF3E3E7EFC8017DEA87EAEF32E9F1EA92 -:10207000C6C90CBFDB13FFBA04F8F8BBBC4306FFAC -:10208000414B9A6F17F4B7DCD536CD49F1A74A9C7E -:102090008DBFFF324359CC015F715ECDE6E7ACF2F4 -:1020A00072CB8B867F1726C527A09F9EF87A78D0A3 -:1020B000B7538E7B45804FBD259C29D07EFEE4F230 -:1020C0003D03FD9E5BFAC16D989737FAF011B81F7A -:1020D000F2B0B1BBD201F8E456EF03A63B06E763CA -:1020E0000E8E19DFABFEBE0D3B2793CBA971D860D6 -:1020F00015C8852B08C35B2843FD95EA7D67D5226B -:10210000BB3FB3BAD48DBF57369F8405C087EA77EB -:10211000BD0E02F471B5AF34D6FD13DA93A41BA53E -:1021200048FAB95C8A28D3FFAE2C882EFF488E2E41 -:10213000FFB8FCEBFCA8B2E07963520AC837267FEF -:1021400094E94CFE8824D00EF2F1A966710AC6D536 -:102150005D9C02E5892F8CC6BC2492CEF2192638EC -:10216000B2FC0C0ED9DB615D612AE77B5DF0BB47F9 -:10217000EC1EABD4774DBBE09E042249DB810E9F61 -:10218000371660DE66AAADF69FDA509FB1935CE425 -:1021900053D276C46BBB4582DF6F78C5CEF2113A5D -:1021A000EE3760BC8973580C1EFA1DDF2B30F96FB7 -:1021B0005F5909F57C19DD102AAB079CEC77943A3E -:1021C000A611637B09EC9BFC2EEA45760BE6ED57E6 -:1021D000390A7E02F5BCC384F73ABC622FF3A9E347 -:1021E00011E8FF31FB4A6C0F3CDA48E977C0CAFCC2 -:1021F000EB3CB58FDBD9F8F87B69FCCD441DDF42A1 -:102200004C50AE2598873FE014D97C6F35603C0474 -:10221000EA2FC3F959B05EBB8770F8DCEB6C01EFB5 -:1022200063E7881A1F6BC3F2432A1FEC308AAF00A2 -:102230009E2A7F2604F6A3CAF105D2016F70C878E2 -:102240006F8E87E4B85209F359D0EFF9543108F989 -:10225000ECFCCD0EB49B41F3817AF02110A46BC14C -:1022600043CA54D70C8EE7390A783C9E235ED88F38 -:102270006B8BB3901F3D6A38BC05F32B6C5EB34C7F -:10228000C7315D47707FE5C4D8E75DF38A199D8E3D -:10229000DCBFB274C8E3E01CE5123C3BECE5129CE9 -:1022A000DF1970CAE9DE88728C7DF103DE0CEF8BDA -:1022B00025682886FD9025D02FBEBD3F5A6F83F537 -:1022C00048382F7EB42C811D9AE3A0FD50BE2F8F7D -:1022D0008ABD8E6BD57504D4FBF1F4F595C586EFF8 -:1022E0007B9D3AFCFB8EEB4C8D5EE7F738CF10F709 -:1022F0003DCC93CFA4F3B30DCF8FFE13EFEBBAC257 -:102300006640FCBA42BB37A920FADC85FE9C0595E5 -:10231000C05B81CFFC50CD1FAD48FC47F4E35F4E5E -:10232000F57C906B07137F9603F99BD5496D9D8CC7 -:10233000389A4F2F077E6CE190EF5C4982EBE1FD0C -:10234000D9D9BE479CD9C8F75717C3B931DE979F73 -:102350004CCB1F1BBB73D6B8912FD6C37B1B092355 -:10236000DD5D01BF8F067437CFDF09653A4633DE86 -:102370009F45E910E856A3C391F3A77449BF1FD343 -:10238000ECC0734D3B48100FA6A5936E8EF95B9A77 -:10239000516E1169DCF03A29D1565B9A711DBF6DFF -:1023A00053503EFCD0F98000E587655F1BCC6BD1B4 -:1023B000E44FF0DE7B92BE341FEC4E3ADFF6FF971F -:1023C000F31D79DEFC9BCF51FCBDECD1C78B599C32 -:1023D00043B3475D09549FA0F39438874CA8FE3857 -:1023E000649F1A2D9897307C3E375C87E780B9242C -:1023F0002FC833ED7CAE9EEFCEBA8CF1DD8FD7388F -:10240000E476BCAF700FDAA54D57DBB4F3BBA87F01 -:1024100035AD34A8E77739942B8DC482F7070DFDCD -:102420007E1CFDE352877F9F633F9CE32DFDA673D7 -:10243000BC129E1356D6B138FD907DD72032FB5585 -:10244000FB9D875BB3B4FBF8999EB2865C907D1BC5 -:10245000E37C2FEA8D24C9A0DAAF4C5FE8992E897E -:102460000AC1F82AD3C3179BB07E73821F7F37A59A -:102470008EEF4624F963B153BD17C16FC5DF5732E4 -:10248000C979C027B438EBC21CDFFB80BFCB8B3CC3 -:10249000991C5D4A9D89C54F291D6C1FA4ADE6920C -:1024A000E6C7E0F7B32E27CD6F1BB2910E8E221D2B -:1024B0004CFC84FDAED6301D1C2B86FC06C2FC01F4 -:1024C00057A871A2973E7EBC13F6FD2C47D8F9AEF3 -:1024D00002FDF92EEFA9629C5F48FD5D9D68BE1369 -:1024E000318FE346360F17CFE33C3E8B358F1174A7 -:1024F00048FC383EDDDF663C47AEC323FD7CB8FEBA -:10250000DBF1BCFFF6EB89C84F07393E6805788ED2 -:10251000058CC88675FA0C93A7A13CF7C1FD669A95 -:102520005D3D62DEBC0DF775E1E2A13C9DF91965E8 -:10253000102762E33E94D8F820F83D9AAE37227F08 -:10254000AFE99F847ADA41C52C421224A962F93599 -:1025500032FD1FCC6B11F1CC71D27EAE126BF0BE8E -:10256000B4ABE7E9F37294BB9A69FB6BD43C9F85EB -:10257000571B8F46EA9B678DF718010E4A9DAD9950 -:102580009F01FD09C3EDDD23E132E2BEA64EC69FE9 -:1025900008D573A0FF8EF200F2A7787C2A6FF25064 -:1025A000BE4FFEDF98EF533C19F1E29BF37D64359B -:1025B000DFE7356318EFE1FC4DCA8AED6BE83AF3CB -:1025C0001F2EC2DF139D93BAEAB1FB69F9896D131F -:1025D000B0FC9BD4EB6F390CF53BF3B05C65F86451 -:1025E00009D04341D9E22BE077585FB3B27ED213D2 -:1025F0007C3D35F4BBF4E2AC2970B14B95298CDFFE -:102600005D39B9612AF863AA1258F950C93B53B031 -:102610009CA596A7BC3401CAAF719F2C89C517270A -:102620001670C1422A6FAB92D9F7F3A63C391AEC67 -:10263000F8AA0A569E28CFDE940DF5864F97C4D28D -:1026400097AE9FCCF8EAACAFCE768E72415898FD2B -:102650003EE80B9E0FF07736BC54DEC2397C6F39F2 -:102660008BC3793D2502FCAE538587952B6D6D1983 -:10267000C007E7FB4CA51077156DEE4EF8BDC2A460 -:10268000F2D9D360DF2BA9BA0D714E4A5F37009E95 -:102690002FBAE4934C07EAA51A7D8946787EC37D5C -:1026A0008BCBD8BE45D303ED6F15F67769B4FC1C10 -:1026B00041AF3A3CBCC23296E11D958BE6F291F4F3 -:1026C000AAE7DF647D808BA4D71D80973CD2ED5AAA -:1026D00018DF641894E0FD784E9E207E03FD9E3541 -:1026E000BEEFC638107DC15F1A836FD03F41D3F370 -:1026F000D92C443115F397595E4FFF3BD81E8E837A -:10270000F01938FE26189FAC67F3D901F790F060F6 -:10271000EFF91E053ED198CE7EF711E2FA40A7E907 -:102720001ABFEA8B5E6F47B97C93931F395F83852D -:10273000C1F16A551FFB7DAB37A5844E7621693602 -:10274000C27A1F4A742810CF6DAA65F74906D27C59 -:102750000FC33EF106E540889697138F89F137CF76 -:102760007698A7B62F8DEABE345ADEC77C36F8833A -:102770007B4E46C0A34FCF47A3D73FBC2F8319F052 -:10278000CC807B54B2619DF2463EC67A88D0BC298B -:10279000D24FFFD0B7FAE909F3B7C866F55E94F0F7 -:1027A00092487F5C87BDF991483B999A65789FD1A3 -:1027B000A1B61C120BEF343DE910A7FAB5A8DE0B49 -:1027C000FAC0E7097F45FD84528CD798097EADF9A0 -:1027D000A8C770268B08F1EBF4DA74C4D72D542FF8 -:1027E000013FBB5211C8467FF94E9EC0FD03C37026 -:1027F000A033710FE3E7F1C9CC0E4C1B8287827CBA -:10280000D464E062EA57C7271BD47B50D9F9D2467B -:102810008B99E57FAABF4BA1E5B1345A8AD637E33D -:10282000FA2C8C7E74FB3422AF459F27674943FD09 -:10283000429C4264908723F360F4768282EBF8D165 -:10284000507C8130FD67AD1DF59F1FA9F1056EC15C -:1028500017B83FC914BFCC2E8823481CD82BC9A554 -:1028600087053269F87724E1F797C09FF57C96EFEA -:1028700093C911F1F837A73D817921470C2C0EAA95 -:1028800087CF5743F00961BE6AA3C6AFF4EB8F331D -:10289000FFFE34EF5F61BC8FB9C132A8D4E253545C -:1028A000ECBBA1BFFF0B8F9234BF00800000000083 -:1028B0001F8B080000000000000BE57D097C5445DB -:1028C000B677DDBEBD25E9249D859010960E3B129E -:1028D000B03B21618726408651C000A2A008371076 -:1028E000D6AC82CEA0E3980E0144079D38A2328A6E -:1028F000DA202028308D02A246A70544FC74346EED -:10290000E3FA98C40551B61844719E6FFCCEFFD40B -:10291000BDA46F13467CCBEF37EFFBF0375339B7CD -:10292000EADEAA3AE7D4D9EA5475923B6B5492474F -:1029300008F1C38F3FFE982FC495F4A7E82644639F -:1029400037CDEECD13E26A5134D6AA08913C4EB38E -:10295000692E21C6AAF47F038468D9A6041DF47CDD -:102960008C3FC6225285A83C640B06095EFC8A2A6D -:10297000002F7E480D0A825B84776D23DA071CEEF8 -:102980000095F7C7F5FFFD302A3F7DC8E675A0DF4B -:1029900080FFADDED46F09FA25B8D75A8BF0380521 -:1029A000FFFB91FED727182B3CBD5BE1BE5B924D30 -:1029B00070BF500753FB4BF77635D5FBC29798EAAB -:1029C000730FE598E0BC8621A6F603DF2F30C183A4 -:1029D0001B2F33B51F7A74B2091EDE7C8DA9FDC88A -:1029E000B3B34DF5A509850797D27C0FA6AB421965 -:1029F00024C428516A6A5FAA96D98585FEA8B37D4A -:102A0000D248EF55D17F3F7625589D61059ECFEC8A -:102A100055444A9610F3D7CA7AE3BD05F577AFCC93 -:102A2000A47261D0FCBC54585B617A6FE9C70BDFBC -:102A30003810D15FAFD4624B1295A3BCF1A947FA0D -:102A400062C262E08F2AD3D51B069DDE51BD0E49BE -:102A50000AA6F3E2ED4AF00EA2634FD1E37ED08DD9 -:102A6000E82C821ED055D6B7AC538301EAE7BBEA07 -:102A7000056F1CB0117C28776D23D17F7E8DC3AD8F -:102A800052BD23DD4CCF188F999E71BDCDF48CF7CC -:102A90009AE99938C84CCF24BF999E29E3CCF46CAD -:102AA0005764A667FB69667A6668667A662E30D3D5 -:102AB000B35395999E5D969AE999155864AA8FE645 -:102AC000DF6EAB169BEAEF8F7BE188467848EDA07E -:102AD000BA1D6E217AD4DD6CFA9E50C7DB5710BE4A -:102AE0004A3355A1BA5BF92040FF311F882A5E5F47 -:102AF000F3880F1E203A9C11AB0F667ACEE7878AC7 -:102B0000BD77DBB13E7F2E3F2C8BE203E2BB447CE2 -:102B1000E747FC1B797E69D0F90AAB7F95B79D101A -:102B20000F7AB5DFA19CD6EBEBCE56921BA2A8B8CC -:102B30005751BC102ED13C13FC542112BC77A07409 -:102B40007E9C057EC13F4706FD9F5F74B712DE1471 -:102B50001D6F62AFED78A3312E9AB752FF5E16E675 -:102B6000BD8E985145FB892145D0F83A8A860CC81C -:102B7000A70C51A5A04C17DE552AC6EDE99484791F -:102B8000E0CF1F3399309630BDFF41898DF97759D9 -:102B90005CFF6DE0CBF76B255F9E4693C1425C23E3 -:102BA00042367CE783D8073BA1BF0242B832189572 -:102BB00075D761FC33307EAF10D789461B3E3E4B44 -:102BC000083BCA62E1E1728EF0DBF1FE5C115E89C6 -:102BD000C97C94AA6D073E2A54AD4B1AF0D1B1A11D -:102BE00073513F2A5F4BC1A02F8857505CD07B6F39 -:102BF000E34F6AF789B76837BE33DAE9B9E15EC2F5 -:102C0000CF3E8B581022BA88F1293C6E612DEA37ED -:102C1000B95F5BDF5946424D88E7144D03BE031987 -:102C20004EEF2620393DF4A442F3BB24D9937347D9 -:102C3000526BFB035E0BB727D60B28D4FEF15DB1B8 -:102C40008CAFBEEDD727635E3FB7DF06AFFF558C75 -:102C5000DB68FF53F3B5DBBD8B6EA47E9B1551B5CE -:102C60008106F18E4E974C07F10F8D37534DF0D6FC -:102C7000826E71330FB6233C2C69AF7D00BD34EDFD -:102C8000EA5FAE04ACEC4BF12CA6F19D2A6ECCC7EA -:102C90007809FFFF86FA3227E19FA676A293D62B0A -:102CA000114C5124F14F7FF42B6A73FC723C077472 -:102CB000FCD7B7D78EE03BFB2C0D9DBDA0A3B52163 -:102CC0009FE9E896F33A619778B9101E0AE23ACD87 -:102CD00000FE4B1C0EAF4AF82C50E4773F4B9C355E -:102CE000B392C63DD7529416564DE3FE06782B7329 -:102CF0001577C9C0B86DFAB89DED74BC7BB2B1AEA2 -:102D00002E34EE5A7C9FF014F8AD12DC9485E7E186 -:102D1000AD809F166EF71D3E5A7316A9979B6B9454 -:102D2000E006AA7F43C7F343366A8775E914C935BD -:102D300034BE2B86AF588F76BFD39C3CEE4DC27B02 -:102D4000C99A2CD043B0BCCFBC4D09D6123C5B789D -:102D500099EF4B4451E75DB00F7C5ABC8FC6F1B779 -:102D6000B87FE465597819E7BD43DFD9B3ACBDF747 -:102D70000E40C32E8EFF7B93E440FF932748BD3364 -:102D800057C7DB95A288D7E955A28A4B5AF0272A64 -:102D9000A8DD34FA0BEB93E07E18DF74C0BED67565 -:102DA0003D4334703953B89F6FA46FBD55D3FEC6F1 -:102DB0009BA8CD644B7367BB8A754AEB368BF1DFFA -:102DC0001DE3FF76EC9B8715E0FD169263A0F79A52 -:102DD0007617C5C79314894F5AB7D9BE3C5EB7035F -:102DE0007C9688F533A69DE43FABBBC73F5B3F2491 -:102DF000181332D284F8851485E2FED3092295E6B1 -:102E0000D9D0550D3AB2A0A76FB1EEA27936903D58 -:102E1000E1C0BCFDC51D4E51FD38D2B77748F91A47 -:102E20001F2078A25F1577301F342E5F48CF5F1BBD -:102E300044F5D4FEE51A113F80E0977D366F2DF101 -:102E4000E1D8B3DA81442A2792DC0F53EBCBD2EFDF -:102E50001E03FB605C47D223117AE2B2EE6698163D -:102E60004247D0E9721DDFE3B3CD7A6722F48ED1F9 -:102E7000BE0DBD43F255057E27FB74FD7389B80472 -:102E8000FA677FF55EF129E917430F8DA61986B21F -:102E90002FAC8762EC05D7806E447F3BD6C76C2B86 -:102EA000B507BEDD5A874911EB656FBEC274F2905B -:102EB000E2B1D0FCDF38A406811FAB3F3C14F85BC5 -:102EC000FCBCC27CFA079F3617DF3B696B9C07BED0 -:102ED0006918969B28A8FF4FAA6920BD68FD563B3C -:102EE000859FD6C2916A37C347ABD3B9FCAADAC370 -:102EF000E5F1EADE5C7FB2DACBF0B3BEA20AF0C342 -:102F0000EC555F5BB56CF45FC5F6D1921AAB00BDB2 -:102F100096C42F96B0CDE98610BEADD3414B1CC1EF -:102F2000B705152FF4E2C25DC1957134AED27ABFF8 -:102F3000DD05F9D72979B40BEDEF5598EBE71DAA1C -:102F40003A88E99E7CE793AB2688D6F9969F55840C -:102F5000464BAE5B9EFFB798CF17D583785C5F5624 -:102F6000FB795CFEFAA68329F4BD63D5E3187EC71E -:102F700057548B767EF135DB1113B6355961678C6A -:102F8000F52B7ED079845F048384AFB536A957D6FC -:102F9000925E811C18D56FF2433708C87DED4ECC88 -:102FA000736AF29CB1B057270E2A66FBF5EA1F043C -:102FB000DBAF06FFFFD43AF288869399D4DF89808D -:102FC000C44FCBAEB7196EB1127E68C62FEC2A2D56 -:102FD00015641FB49C7D4B3EA7766CA7EE96ED164C -:102FE000DB64BBC5BB7F97CCCF15A55944E8BB6359 -:102FF000444741788873663EF419E1E7D8F65FA745 -:103000006B11FC752C39F4ED879093FF66F16E60BF -:103010003ED53E7D167274B99BE5CC495BE8C8038A -:1030200090B39D48AF727D55DC64E2B30ABBD09883 -:10303000EF84D617F0B15831ABC825FBF3F492CF2B -:10304000C18F3D77DCDFF5379ED6FEB684E67EF88D -:1030500000E8B0E3A3844B68BC7D541152317F215A -:10306000C711D818CBFD943D797BB29FE0AD8A683B -:1030700051594E04595EFCCE26A6A1DFDE8AD5BE8C -:103080003499FCAA3B9FCEC4BC7BA9A24AA5753942 -:10309000E7AE67329FA1F71E2359A4D2F89FB379F8 -:1030A0004FEEC5771FA2F153BF8FDD599E037958AC -:1030B000F2878597000F7F81D0223A3CF1F44EB61B -:1030C000178827BDA349AEF55BF3E2B20C6A7FE92E -:1030D000BA264B072A7D1B955A94A5DB76BE55432D -:1030E000FDE5BA2D55B05FDFF279785C39A1F51BAB -:1030F00014E8811F1EED807599BDE6EB820EE2C2D9 -:1031000076C6139DDF6F29F6B05CE0F777D74F796D -:10311000FB5A013B862C188CB7D8EE65BD46D3B65A -:10312000013FBBBAADC7FB7B2C01D65781D9D2CEAC -:10313000395114F823E65F4EED030497FB1A9A6E9B -:10314000A2FAF2A4AE2240F33F1A5C321DF5031539 -:10315000E1067E2A76DD5BD881E013C38457A1FEA9 -:1031600017EC3E5DC8FAB013D9EAF8DEAEDAB46BFC -:10317000A00FB30BF254AA2F5243DC9FA894FD5525 -:10318000D6EF740226D427ABC46749F5A3F6677A55 -:103190005AE96369BC2BCB4ADF6B47FA14E35D9BAA -:1031A00015C8A872B5EADF645FD169AC1BE1BEA7A0 -:1031B00018DFF99CC605FBEC62F5A5DD52B590C79A -:1031C000932EDC81C1ADDFED64092FC43C6875B876 -:1031D00003F49D4DEE86E9DC8EE0DF73BF9A9A938F -:1031E00007FB8AB09E2AF57B2DFA754FE90C7A5DB4 -:1031F0006CFFF7C7FD83EDB44A4B82D731A0D5CE23 -:10320000999652FB7C23D12BD85E4BCC6907FB5897 -:10321000DAC9C2EAF540EE57B7F7BB73D84E233D83 -:103220006C61FD9B9A1361379FB3DB9C17A77F43AB -:10323000EDFD1DF0BD8B6DEFD1E312E7E4F0991CBD -:10324000931CAE8DB70B1F3DAF5DE3E03886386051 -:10325000293B48FECA707CC2D2FABD25F139EDA1E6 -:103260001F6A8568135F2FD0FAD708B761D21B1A7F -:10327000C98111679B558DE544C3FEC40190B7C257 -:103280001FEF41DCC022B408FD18FD1DA2D760CCA1 -:103290006F9488135A849EF58B243BD6AD70255FBE -:1032A000E4BCC38F9AF5CFBE4723E73DACE5FD38BC -:1032B0009860848FF6282F34AFE7F579FD19F3A2D3 -:1032C00072677ED1E5A0DFF06FDC56CC6FB8755227 -:1032D000675F571EF7243C1FF18DC53CEE1F624D02 -:1032E000F0C58EFF46851C3BF0F1D7F620D65F3D3A -:1032F0006C059A47FDC2EC20D6FB1EBB0838E1F7EF -:103300004CB6B31D5C1F1F88875CAD57DC21C49F82 -:103310009EB3354C977E91706FF2817F5F7F10FC7A -:103320007F4D8B5D413CAB83431C817D25D444B1F3 -:103330002935E2FBEDDC1CE750A13772091EAC3FDA -:103340009F6EE7E7B536C17A32303D96C7B526A9FC -:10335000EAD57E54BFA626D34B2317EF8BE0AAAE47 -:10336000A8BF4565793ED4B261D37DF07B26A5B375 -:103370009E599314CEAC44FB85977803C40F7BFE13 -:10338000A1B2FE58E3F36724BB200749CE139DD7B3 -:103390004CF267C4A6A24CB360BE1D48CEF3F32C1A -:1033A0006A47E58736D9EE039D6E84E90CC8DB07D2 -:1033B0004A7A08963F390577F03AA10A27F1F35483 -:1033C0004902317DEEBDE226B4D3D4A09A05BCDC1F -:1033D00075674F82AF99ADBA11A79BBA20A649E98C -:1033E0004FA5A6861D09F4C29563FD91FEFADA1C6D -:1033F000FF1DA07379A84FB7CF22F878FADC1EBF63 -:10340000827CF884FC68F8DD77A4697FE0FEF7FA37 -:10341000B8DD5E326E7E849E707AFAB3BD5D62F86E -:1034200099E139C0EF0BCD4EB6632FC40F42789DA2 -:1034300097D0F7EFB38810F8B98BAED76B110000B7 -:103440009D4331CC07E3263BFD1CAF725936C08E3D -:103450007E84E805FD16D8ED607A91A064FADDF768 -:103460004227D64BB37439563B2D96DFABDD690B43 -:103470005A406725B87533DE7B3E86F567995DB0A7 -:10348000BF52F66C5FE6833D767FD60AF4FB82433B -:10349000EAED044F22D7FF9F1481FAE7747D5D1691 -:1034A0001BEE994474EADA4E7B0A7823BEABE2E75E -:1034B00076F9FC70B0603DD6A520FB266E04C1C233 -:1034C000BF1EF22A4076D026AFA41FC6A5D576DA55 -:1034D00080F16A340ED059DCACF27C0ED35AC6FCB3 -:1034E0000E5775E2712993C765CCA5FA4F17C771BE -:1034F000DCF570D1C133B0030EA7ABBCEE4942DDA1 -:103500003990EA49E736DC4170E5C24F5E1F484F0B -:103510002B6A3FE8BCD7D38AF719CBCAC70BE28323 -:10352000198B6E9928122EBC5E679439E053B6AEA3 -:103530006F618773276192EB4D39FE06F0C17FE41E -:10354000686FA3ACCC267B9BF8E8A4BDE161C455B1 -:103550008E7AB4BF022FA79EF962339E0B6B734F16 -:10356000E60F676321E23265161957BA2B57FB380D -:1035700087F56C02D3AF32E460FAC5653748B97895 -:10358000CBC5E983AFEA37ED51A89FD2D8FA0A2E0E -:10359000D5607FE8AB634A3841E9C6F8D5B0AE8E56 -:1035A000BBC309A08F6691F65EE996E879D250D345 -:1035B00010771342FAA921FB501AD72212BD0FB877 -:1035C000F1DCDEDA3EAB958EF41DA6A3707D3CF3F4 -:1035D0003768BFB54FCE1D84F7D2A4BD770DCD3A65 -:1035E0001F7FD1B0319FF3C7A3AF93A27002D6C99A -:1035F0003145AE93E342CAAFC096183D5E20C77115 -:10360000F299F63C8E347D1D9D54F4765B1DB21DFF -:10361000F11EEC99D23F49BEBBCFE665BD19207DB6 -:103620000279599A22E15247BA1BF656073560894A -:10363000055F560B5E2F34365E97C77664F2FB86C5 -:103640005C13454240AE95EEC8D820ED3ADD6FC61A -:1036500004A8FDA227647F8021FFBF7A3C53EF5F5F -:10366000AEA768BA46E3A15BAE8C73D5C6E7B7FFD9 -:1036700067F1CDDEE91FAD8308BACF26D775205E8E -:10368000EA11B25BD227F5C3FE84DDF4DD93F1F6D7 -:10369000597E17F629CCCF8DEF5D9AAB70BF5DA236 -:1036A000E8DE416D7E11F6927854B09C881E477E0C -:1036B000AEF4571F7FFC1C9D554977622483BF3CA5 -:1036C0008C3F61037D3EB01B74BC2193E47A29706A -:1036D000D5B5158F7B7C5A26F4C849C084EF3D4987 -:1036E0000467C3DE92FAC3800D7A44F3E9B20FE6B1 -:1036F0006536D2FB7372A57F501B93D05F24A2EC7A -:103700001C841CA821BCA29EF4E0ACA26CF8C3E30C -:10371000EEF9CCD63A9F23D57E3FA9A073F0BCB575 -:103720003E27D6E7FC753EE7EC087AD46EC93DE447 -:1037300021BC1FDF62456452D45A83770D49C5739B -:103740003514105CEF04BE8FBBF6BD8E76F3D62524 -:10375000E5A811F269FEDAB1FE92083AF4DD62A63C -:103760004BBF9019BE74AF192E27DD8EF9FDDCF723 -:103770007C61339C7BC80C3F3DA859FD11FAC9659B -:10378000093A15942DEA8F90EF4135083FA3CB2DD0 -:10379000455326107C74DD1C2FC83CFFDD65F9A065 -:1037A000DF89DDB7ED29A7F78E265BBCF0AF8E89E8 -:1037B000D05F27103DE6D5DF6DB77A305F339FEFDE -:1037C000B1E87CFBB88C032E0C9AEBCF970F357ABF -:1037D000DC49F48EE4AB68FA53BF57F96960654B76 -:1037E000A7DC03FB67C17862781ADFE0D0DD76E101 -:1037F000BA987E028C576B8208A7D3F89A6E8BE733 -:10380000F8CB90A5A3C5A7F4BD72AB3BFF3734CF6F -:10381000D94EC51D70B7C6D59B766654409F6E7253 -:103820005BBCE4E308F7A0AA839903E04F8890DB30 -:103830008BB8FEAD2BE1F72FA84A60FC2C14418E0B -:10384000CBCF5EEE68958FF4BF92D551E3591351FB -:103850004FF358B0CEDC7ED1C61F1D91B0E1970E5C -:10386000A95FAF62BE73F571AB8189AC9787E8F150 -:103870008ACFD094F4CD13DD8A76E4D27C87AC195C -:1038800025EBAD4E5DCFFAD9CF2B77D93D2CCFAC00 -:103890006FAEE4FD1D5A87D00F87E2E7FD0AF2EE16 -:1038A000B453B81D3EB4D7183E9222FD42DEB7A0F5 -:1038B000F6A7D729ACD7CB53245CFEA812440CB88A -:1038C0001C415BC08FC9386D998E0FF0893F623EF5 -:1038D000A057242CEA8CF87898FDDF8A2AE1851D10 -:1038E00020888E7E036FBC1F15B61F859E0D28A1F4 -:1038F000077CB0F7CCDFA9DCFBA323123E175F26C1 -:10390000D2D5F0F7838C47D52EFC90E3EAADB16CAD -:10391000B7930288857EB7E9F6B558156C077DB573 -:1039200006FA8ACA15BA1D1EB85BEAAB3549FE9E77 -:103930006ED4DF9DE1051EAE5174FF16767D12EC4C -:10394000EB7DDC6FB3E2766F48427B11884965FB03 -:103950005AFA09FF5059DF3593FDBE01F6BA2F140C -:10396000C678D6DC9BC5F6FA7386DEBB3346DAF33F -:10397000E7DBDD6C5F897BA4FDF8A1E0BEC555DD0A -:10398000B593B934BF396A116F46952CF367E0BB24 -:103990002593ED16D0432CB8B87D914D56D97F3381 -:1039A000CD17F1FACF94A28396483B58D70FF9056B -:1039B000FECD7A3B2FDA9558DE643C9458841BFE8A -:1039C000FCA6B3AAB012BCA9CE115C46AF9474F5A4 -:1039D000F75C9C8DF7647CEAB04FCAFBB801C21F4C -:1039E000A4D239407ED739C0622AC5181967F92C8C -:1039F00046F2E10C5154C8FB031E29EFA3E7913AAC -:103A000040EABD127B83793C1FEF67BA90CE732FDB -:103A1000037F8F9176C767D72BACCF693E3DDD041E -:103A2000E7FF2186E38B9FE9FAC8C02FF14F1EE222 -:103A30006886DC4AD2F965CDEDC1AD3184EFBB6D4E -:103A4000C437A01BF1CDA6014C77B60BD74C4F6302 -:103A5000BA5FA3D355DC19CF741B6AB1483CDF9918 -:103A6000C178A6F6E2EF786FAC47DAF317E9871171 -:103A7000DDB307E49DEF8F19F416D660DE3FDBBFA0 -:103A8000297F7AFB9E00F1FFA23FDD9B20A8DD97F6 -:103A9000D6BA342FBD5FB66945829FCAA3D640828D -:103AA0009BFAFF32A88E0BB681EF453ABEB17FA0DC -:103AB000A461DF55CAF1AF1EFFF79537D338BF5564 -:103AC0004433E463C5AEEF57DE4CF33BE87736434F -:103AD0009E1EB5361642EE2E2C7655D578B17ECD8B -:103AE00071FC458FDD9BE6617C07322DE9BCFE331E -:103AF000F15EC5469B177E5DC53BAAD783752F9A9D -:103B000057627CD1EF57863EB503FF6E8B68EE3867 -:103B1000B48D7AD1C872BE72D7EFBE5613507EF9FB -:103B200021FC8BCAA8FD8305FAFE4AF43EC2350388 -:103B3000E2538F2040AEEF5F137E388F2140E3EADF -:103B4000C1EC22E3CEB55BEFEFDF04BB61E3AB0971 -:103B50004A76EBFE81B1EFD2129AF3C8B39E0BAF57 -:103B6000CB937ADCB8956E528E79F6D2C0DA0B041C -:103B700018B82CB3851360EF97ADB7B11C29DBFEE5 -:103B8000E8E607C06F1F38BC3D3C804FDB210FCA01 -:103B9000147FB3C2F25D2428F9ADF42ADDFE79E189 -:103BA00083B0AF3354319EE8B5E8A933B2BD5F347A -:103BB000C750FBD29D4D85F00FCA345795B30D7A8F -:103BC0008D0EBD686F74B541AF505321C7A9B67E45 -:103BD000C7F4F8F20545B4CF3AFFFD05EB3FB70B4C -:103BE000E91F34A724497C41DF5586D4627BE2F982 -:103BF000EDE9FB139F1DC0F56EF82B3F45C721C0B3 -:103C000005F37BBC4882DEFED0111C0FFAEE589201 -:103C10002088FFBFB05649BE7F68451AECBC05B688 -:103C2000409A9B4BF97CC1C337323FCE57AAD2DCB6 -:103C3000D9CCEF1996413CDF0CCC73EEBAA93CCF3E -:103C40007942637E5CF0905A14A4F28C558CDBD9D7 -:103C5000C6BAF94C5F370E717D7FAC9333F425E81B -:103C6000F12F74BF3EF096F4A71D627262E47ED21B -:103C70006E5D2E0644F030F44065838DE314EA9BBC -:103C8000670AF19D1BB2AC55C8F7A0F907747C29EF -:103C90003F4AFFC583BC874AFC45FA74F49B63DB4B -:103CA0003766E3FB2DF6EBA8DF6FE0277A4DEF31A7 -:103CB000DEBED8E088552EA5324DDAEFD1F348C9E3 -:103CC00033D6BF784B44F053E5962F989F44BA2AD9 -:103CD00012D3258CFD0BF76C575522E1ED9B773EF7 -:103CE000B523FE1D48B5881E186FC3E70C0B6F3B4C -:103CF0000FDA1BDFAFDCEB10E1C875BBF1F3A87581 -:103D00006DAE17A28AF15929123DD0DF5FD89B0B07 -:103D10009F433FD4EF26EA671ED95F61937DD55C50 -:103D2000F820E4C95EBB9BE30F647F8623F8E6DCE2 -:103D3000FEA8BE2F385F9707D17888960F87A3E437 -:103D400083F1BE58D7F67E54AB5C08307DCB6C2235 -:103D5000003BA3EC0307EB8FB2ED723D0A92A73D47 -:103D6000687D1CDBB6FFAFD7C09F0DD952C773AFBC -:103D700066F9BBE0C9CF795E7308FF315EC8DFEF3B -:103D8000ECF07FD3478B66078DFFD86A9F1D7C7F41 -:103D9000DE3AA6E76DAEE3D50ACBB7FFAADC257CF9 -:103DA000DB616FFDD47A9D7F01B91B9367CE1B3A0F -:103DB00023B21387A2D25DDC85F70FA2F06BE0354A -:103DC0005A8EAE1FE09171E928394AFFFE2A22F08F -:103DD000284423F3F1B72417B10F57B1F17BD66B09 -:103DE00084D66607F17145F06B865740AF31FCE22F -:103DF0009588579E3F6F333EA3EB5F05EF139F15EA -:103E00003D6363BBA0AC5EE639D27BEC7754225EA7 -:103E1000CFADEB0E66A646C2C1283814D5DE1F050D -:103E20001745B5D7A2E02A53FBB2BDFBD9CFA2718B -:103E30009BDA39965ECE7EC8F9764590E751B9EBAC -:103E40006B7B00FCD1B1D90EB9685B2602F1F47E20 -:103E5000F3F32ADBBDA73CCD09B05356C4483BEE73 -:103E6000945B87930C58CC2AA6719C0AF47723AFF5 -:103E7000A03946C65B4E1535272445F8ED4DF56A49 -:103E80008287DA3706C5B8B6F3626A99CE8DE24208 -:103E9000F5D29E1BABFEB043E68B5A8583FA6BAC22 -:103EA000F96E07E2499F91FF04FBA5A4E6EA04EC42 -:103EB000BF9CAAEF76C534F881AFA89CF325027E9B -:103EC0003BF226E648528AA32270DF309A9F1A3FBF -:103ED000E0E073F0AF8851B0FF59B23ACABE114565 -:103EE0008961F8D36BA2F31B8276D837F349CF42AE -:103EF0001E2D5867AE5F547F8CD7CBA2A8F5A2E9E0 -:103F000071E3E8F55269AC179FF0E9F9969CD77711 -:103F1000EA90CAFCD5B2DC2656A6CABC5AE4A3B4C1 -:103F2000D4CB7C9D96BD1216013D0F485FB706DECF -:103F30008E633DF5BAB0DD727CF7BFE5FF06FCB3DA -:103F4000E7A3FE0F52797CCF073D9F03FCF47B9DD6 -:103F50003F12E7B71FFDC2F733795C2F3804C675EF -:103F6000EA85973BC3DE38F5AC83F3114E2D73B071 -:103F7000BD1E78219EE316A73A497BB8F6F9EFFA01 -:103F800037B23E5ECE747C20CF2EEDAAFA7F67FD5D -:103F9000D852EFF0601E952FC4F1BAAA7C3686F78E -:103FA000D54E3DFF5D7E643CEEBF3A1F631FFE545D -:103FB000BC98F624F857B7FF2B9F1BFC680DFCE557 -:103FC0005D2FDAE720AFE4CFFFD11FF2F5D4932FB6 -:103FD000B2FC3D696B7C18B1CD4D79E1076C831162 -:103FE000D7A38F75106244BEB83690DD165E241ECE -:103FF0004E111E302FC2CB02D8E517C2473DF0D17B -:10400000EE5F111F5FCF94726EA0C0BE4F2B5E1487 -:10401000BF7C1ECFF12A9ABF7CFEC277FD21877E2E -:104020006ABE1FFE7F36DFB3FFB2F395FC1EC8F3F6 -:10403000F038A3F9FE7CBE7EFA570CEF88F7F278D1 -:104040002F72BDA7E7FFABAEF7FF197AE7FFCBCE24 -:10405000F7A7E8FD8A4EEF7837F6414F3DFF1F9DE9 -:10406000C5CF98F7D4FFA5F336ECF902D57BC84746 -:10407000ED5F15A177BC596C95B4698F2CD3F3050E -:1040800085EE4F8DC65F1EB4CF591EC27A207B02CB -:104090007E4CAD2BE7C09B04BF4C7682CAFBB2328C -:1040A0009EF472BA2F28E3BB5502F1AC82F7E630DA -:1040B000FC9AEF1707905752A8CA78CCFE1AEFC6A1 -:1040C000069AC7FE248BA796E0311DE77CB693EADB -:1040D000DD1D5437FCB3DA8EB94E4FC4F8C6B8CCE8 -:1040E0007ED6E5517ED22F3DE6FA71E2C954ECD777 -:1040F0008DCBB6099CCF2944FB08BF52CB77F33C4C -:104100007F29EA96BB5D3F1F4FA17CE977125E785D -:10411000DF26D051D5F3E2CC7813C05B2AF092CBE6 -:10412000F67B40780FBC49B055B7AF84BEFF58E866 -:104130008CDF0C3FDA210AC24182CF78AC55686F20 -:1041400015E40FCB79B21F1D8D37A1FBD5569D0409 -:10415000633A8E0E03CF78DE25DDF43ECF3B1ACFD7 -:104160003F1FAFFB3A2E015ED3E3BD41F045C7A729 -:10417000521167AD253C2B4A2B3E0D3C45E37D0596 -:104180008D55F297C47747ABCF8A75365CB7E7C7D2 -:10419000589324DCB1412DE2F517947CFD8DD70AAC -:1041A0007B7E942B89F349857ECE42D5F7C39161FE -:1041B000C7E320FF1479B95758B5703EFCE6F16E9D -:1041C0005100BFB5408410BF55EA5FFE1EFE11CE00 -:1041D0009714F1BEE6C1F701F772BAC2F007C53A0B -:1041E000EBF1737632E2FE51E72B260EDA390AF450 -:1041F0009ABD949E218EE5F61CC47A2CBEC7E101BF -:10420000FD3A5A1BB89E7C2D77CD60EC5687188EF0 -:104210002D214B3F03ED5E1EC5ED9708B7928474C8 -:10422000BB9002D8E596F96AE4BC7E0BD8BE3CDEB2 -:10423000532BE32602FCD41D65577C5FB64F1F430A -:10424000DF43BE9BD0D85E8EEDCE9120D15529E2C2 -:10425000FDF72EDD645E44F30A07FB3BC5B775EA44 -:1042600009B934BEC01CB7CE1D28F7878D3238502F -:10427000CA11D5E24DC777662FEFC3FE971A5B547C -:10428000BE1B78DC11C77C5EBCF2BA0979F4FDE292 -:104290001D295E0CF3AB893BF365FBE937BE4BCFC1 -:1042A000B52D31FC7CFF40AD391F79068A67E66E7B -:1042B0007A307BEA7E7B3A75A185269D40DC71626F -:1042C00060E7EBD8E79C78A5CAED27EAF99F627909 -:1042D0001CEF9B4F087C6D4DA7EF4D20A706F54DB9 -:1042E00031EECED7D3F88BF578F30FBABC52638595 -:1042F000F6A40BE3EAD4B32B3D9F20643E74F4BADA -:104300001D3450B6EF32DAEB49057E9418F786017A -:10431000ADEDF11D7C77C44019E772E8A501135E8D -:10432000392E5EB2CAD1D42D01A52DDC8BCA5F0D0A -:104330002E881B48F5E3BB8AC2B5F8EE4DAAD8C05B -:10434000E36D2EE6387B7C6F0FE8A0893ACE3712FA -:104350006B7AF07E4ED328C1FCD3747796416FCE32 -:104360004F32FCB9A651DE83C8DF6A1EE5F46EF059 -:1043700022BF2514461CE5F05AB95FD3A536DC1DD3 -:1043800072B6D927F7413E5F9AEB019FCCBD774AC1 -:1043900002E4E79C356AD8017E5F6DCE5B126E2F1A -:1043A000E78DCFA91B6587FF5AE2F2DB312FFF2093 -:1043B000AD17E6619C8BBC0463C2B99FBAE2D7E03B -:1043C000F7A909B49EB1FEAC9E04F8D5D1794F95FA -:1043D0007A7E9301DF91A679F1BDD9899E1DE08F88 -:1043E0004F9676E3B86AD540297F8535DC1DF8798C -:1043F00098D602D6E7A7F992FFC627BB7BBA987F6B -:104400006304E6D56473F7043F37AD88B1004FE32A -:1044100097493EBEDD2AD757D0EFB10490C7A9F324 -:10442000EF8C1A6BD17AEAA7A35358E39385786A85 -:10443000B0E6C03826046A0EC3BF9EA3EBAB39AB0F -:10444000E5F9B12EA3255D85B5614C0A3D3FBA293A -:104450002B0779F106DF3C35B8E01703F35AE93F43 -:10446000BEC05FD88EBE33DEE269811C2EB95279A0 -:10447000B19BE483F1E867AC5ACFEBBC85E48423BD -:1044800009E7061B248C7C55C88DBAFBFDCE08BFFE -:10449000DD2E7671BDBD44E6A376B1876B38FFEAA9 -:1044A0007AE15E46F066B223AC3621B6543BB97C65 -:1044B000BC9AE45D0F21B655A733BCA3DAC365A847 -:1044C000BA373F7FB2DACBF0AEEA410CEFA9F63350 -:1044D000BCB77A1C97CF5617F1F368F933C7358FFD -:1044E000E589BB27D17AF0F97C33D343E382FC71B1 -:1044F0000AF76D38AF24A4BC4BEA2DE58FD0E55107 -:10450000D73E82CFDF54811E840FDBAA51163EEFC7 -:10451000696DCC00DF8D558F6F7F1AF18E052ECE21 -:10452000CB6A118DBC4E5A84C51B1820E58F83F8C9 -:10453000AECBADE3B222F3D4AF5DA0086B047F5DD8 -:10454000571523AC11FA69D6D224133C63E9DB2F4B -:10455000B5A7EFF7EAAAD5802E876F3DF2D07BF49E -:10456000FC915BBFEA21CFF5FEB03E32EED2229A3B -:10457000256C75F27EFC233767A4A57495DF03BD17 -:1045800066E30F0FE8D3FCE56358872B54EF3282C4 -:104590003F047D089F1FEBF4295ED16DE5AFB1AEFE -:1045A000FD4EAF42DF397C73DFC241D4FE117D3F47 -:1045B0004AAC22BC46EA9974A9BF3E81FE4A92FAEF -:1045C000AC0072342CF5D627BF4D0BDC86FAEB130A -:1045D000BC3801A1AD6A1F984FF06A9FDDAB22AED7 -:1045E000572F56226E4338967645C066D6638D1D8A -:1045F00093100F663D3612FB9E41279FD3A28EB0CB -:104600001F33BBF73E9101B954A7B8B15F83739DC7 -:10461000CE64C83785F74791077425E9CBC707AA49 -:104620004CCF23F95679DE0BC97204C7082FC76730 -:104630004A56537BC8C73A9F7D5E84FC9DAD3F9F21 -:10464000D3DBC2A5F1FC197C0FFB87AB7CD3C01F69 -:104650001D509F8D32671AC6D7C155685522F67F07 -:104660009F1A68D5FB97FD1680A8F4FE1DBDBBDA26 -:10467000E766F3F92CD65B463FB37BE7ACEC0A7DEB -:10468000BD7A14B0236A6DDEF4546A577FEE3B6E38 -:10469000195F77CAFCECB20BE80D234E77147FCA82 -:1046A00073923CDF453B9ED88173128B3E72B0FE05 -:1046B0005A74A9D44B223B983F85039AE6B8F898E0 -:1046C000274E1CBC8DC67302E79810EFDFF5A91DBD -:1046D000F9A1B46CAA123300AB4DC8338D8ECF1E36 -:1046E000D8F151429B71F15DEAC5C5C5951F12A075 -:1046F000178CF98C7DFE4C1AECAC4AE52CEF335547 -:104700003EBF22ADADFCB0E8B8F8B9F8B958FDB578 -:104710008A38F32D47DB8C9F47C7019B0746EF473D -:10472000B80A2027CE1C5283D84F6F09F648146D63 -:10473000F46FC4CF2BD7D24B2958979E44EC879D5A -:10474000BA805D9E3748DAE527F478FBA96D2AFB2D -:104750004BA7B6C507619F566CBBE720F6292B36E1 -:104760002A6C9E978B06C617E1513823F518F2DDA7 -:1047700052605C7B1221AF8CF1953E115F05BE5AF1 -:104780001852FC9B681C2D4E4F62BB8871240D9201 -:10479000EBA2D411CA67BCEAE3760C9272D068B778 -:1047A000B0FE1E8E4B53BB936CEFFC294E709EA047 -:1047B000687E1DE33BB62ED78B7DC585A19D159CDC -:1047C000DFB12DCE8D38C4577A9EB3F19D4E7A7FDE -:1047D0009D0649FBED98BE7F776C873C9F8E71628A -:1047E0003D7DA598F305BB0D92FCDF6D90B4875E0F -:1047F000D1D7B1D17E61A829A13BB5FF62EFDB5CC7 -:10480000F6D3FB59E86AE80FBDFBC5AE38DE8FFF73 -:1048100062D7838588339F088D4A05FF1BDF1F3AC7 -:10482000C826E9B04E1D077C89A0CCB329075E736A -:1048300023C799B23E9015B9CE64BED1B15D4F2564 -:1048400058B25BE958EEAC72E27C68E5AEEB8BC027 -:10485000C7AFD8243EEDBB260570ECB992D42DF439 -:1048600004AFB30C6EBFCA12D1CE61F3B3F0B3ED97 -:104870002DF6A3BD11875EBCDBC6E70B675EEAB908 -:10488000FA5AACC3576D4C87C57D3C57733E528373 -:10489000CAF9CB8BB34418F6C7929BE2D7633FCCDF -:1048A00018EFCC5CB9DECB5629C24FF32A0BAA42D3 -:1048B000A3B203D13D801CA5F4C63CE44F36650588 -:1048C0006FEF99CAE77DC31B525BF34C691DF7C4B8 -:1048D000B9C89241C93CEFFBA617B2BE3B6C1701A9 -:1048E000C885C093320FA7ACABCC8F7E007C8FFE07 -:1048F00092C33D5308AFC775BA964D0EF7445E4656 -:10490000D993199C9771DC2EF74BF11CFBC56539C7 -:10491000F43EB54BD5F379F17E52041F95CDF67A6E -:10492000D04E4DF67A7C2E8CD77D92EDD6DDF102FD -:1049300076ABE5E9783DBF2A86F3C88DF796EA7C29 -:1049400097AAD3535C23F331EFB3C97CD5FB36650B -:10495000F0FD1846FBFB6CDA74D84F9807ECF58530 -:10496000F6BA9ED87731C6BB30A18EC7795CE7F323 -:1049700085B175322F5C3F778CF6809BF43CF6E670 -:10498000AD0ECE5FF92AA3E15B8CF7ABAD7D900352 -:10499000037CCFDBCBF5643F123D173DEE08A3FE51 -:1049A000CBAD326EFDA52DF82DE4F0970FA5F0F9F3 -:1049B000A82FDB05F3393F40715B609F7DA9E8B00C -:1049C000CDCD7665173BC1D43E35565890BF336E7A -:1049D000F2DA99C86F68D9E8007B8AAF36DF9FC6E4 -:1049E0007E8DF024729ECD2155806E5F3DFEEF7D61 -:1049F00022ED17A35CB4D19C77D79425ED4AA37E12 -:104A0000ADBE2ED70E927EC7BA41524F95C785EEE6 -:104A1000EBCAF393F826FAB07F470A3E9EF327B617 -:104A2000F75020371E10C15F7D3480BD6C0FF2E659 -:104A3000CB9EDCFA3AF66BBFB28806D81FCAAD5BD4 -:104A40007E85FB3952EF4A643D24C4469EDF976E53 -:104A500079AE95162CCF7F617B092F9AB2A527E0FE -:104A600083A473145A5F8B2C0AF7BF684F3FCEB7ED -:104A7000237A58789F6CA7AA8F876C4AE06FB3CCD3 -:104A8000571E9F1CDC0C7BAFF9A16E02E7DDC7AAA5 -:104A9000EBFA837EA737C659C04FE5B70D4D1C0A08 -:104AA000BCBDA10AD81FA7ADDEF6917184687C4514 -:104AB000E7819FD0E55319AD3B9CFF2CDDF310DF60 -:104AC0002F520ABE045E1E57781FBB74E5D0FB99B7 -:104AD0004F5FB7891ED4EFF1D03D0991F4792FFAD9 -:104AE0003B762FB72FA5F6F2FD5713789C9B6D9C54 -:104AF000D7124DD78B7EFF71F5A2DE3F37FF10D95D -:104B000005FDCFC7C369D1F0AB8FE8FBDF6C8B61CC -:104B10007F903C003EC776CC169A87791FDB1EC378 -:104B2000F2EB589294135F903C0DF4C2382EFF3D87 -:104B3000F3E95B53F8BCDFFCA0F9BB46BF1FEB7287 -:104B4000BC3CC59B08BFB3FC0D290F895E57F0FB29 -:104B50006FD8F8FDE8793C87F7DA45ACD3ED71CC36 -:104B600017C73A487A1CDBD18BF55353925B30DF81 -:104B70006CB5C97A5BA833ECE063DB7BF96A23BED2 -:104B80007B2C29D4D91DF1BCC9165C3950CAD36617 -:104B9000F8C5228C583CF28B04C73F8CF74A9DAB7A -:104BA0001B60A720BF373F87CBB023F9FC3CDDF16A -:104BB000C9D29F1C3058DA0F9CB39AA6E793B3DD95 -:104BC00013B2438E6BBA7D58B62D3ACF57D6A7187D -:104BD000EFD3BA4B35F28A2D186FC89ECEF106E19D -:104BE0007992C65BBAFCFA85C81F2FADBAFB5AD8BA -:104BF0004FA55631CE4EE36A52541E47538C98351A -:104C0000197664643F11F65BE7C1E7E2B4C29DC662 -:104C1000762BEBB7AE83A5BE035C47DF2B5BAEAC58 -:104C2000C6F70DF9C281C2B4563C21AF15F93D4D0E -:104C3000A3F4FA0BCCBBC926EBA3E76D8C277FB09E -:104C400094534D599EDF0F035DFEA2F2F9AED33FA0 -:104C5000E42626B761A7B5EA7B7B6B9E2D8D1F6787 -:104C60006E595F0F96F2AE94C68771F65C67CE2BD5 -:104C7000EFBDD10C5FB2CD0C67EF32C3FDEBCDB011 -:104C8000F78019EE8B7EF3A49F8D73CBF0B351C2E6 -:104C9000CFF638A49F0D187E364AF8D9780E3F1B00 -:104CA00030FC6CC0F0B3011BF886BF0D18FE36EA6D -:104CB0006FD0F124FCE134E46B5658649E2FD1C3CD -:104CC000CFE798A6DB4DE7524E3D2FCFA5103F48CA -:104CD00079BFD0C5EBE401B4180CBD24D753EAB3B7 -:104CE0008EE032C4773DDACCC158AF6BBF9E07BEB1 -:104CF000ABE8DAC879AF4D2B5EEE790FB56B54E2B5 -:104D000005EC8A8AB55FCF841D95E6D14A06D37833 -:104D10002A631B560EE4B87D98E547638DE78D91B5 -:104D2000928E1C7F2956715306D52F486E337F28EB -:104D30003AEF5CAC36E799FF54DE79341F1876E021 -:104D400023B6E60C37FBE9C31E469C77B112EF860B -:104D50009FFE698C5886FB8302AFC83CB5964336EC -:104D60009937B05AD92022EC93653ABE0D78CED946 -:104D70005CB6C7CFC1AB158BB85488EE5A7313FC21 -:104D8000EBD30B2C6C779F5E5050D80EF61FF96555 -:104D90005813B89F2B72BCB89FCBC43F5B92A3CE75 -:104DA0004D7430B5C7FD5CE673139798EAA7ACCE97 -:104DB00035D597140D35D57717727C4B16CAF195FA -:104DC000907EF0A7005EC6798B4B403BB2533A2BE6 -:104DD00081952C97D72B7C6EDCB3745521F0729C97 -:104DE000D8197104836FE6E8FA45580376F0DD9927 -:104DF0005459FFA5D270E4367AEF84AF6E33AE4ECD -:104E000039615977DF300FF2EBD77776D33ABC416F -:104E100009A541F4FC7E80B61D7CF399B57112EFB3 -:104E200027EE6C975C03BBF350DEEB83D0DF369547 -:104E3000F3260C7EE96C9371BAF5838866644FACF7 -:104E4000AF93F9BCEBEB5262BB47ECBF18F36C01BC -:104E50001D04CA6569A91C17120D9807D9EDCB600E -:104E6000B79D3E24ED76633EDD97873B2EA1FA1B6E -:104E700076C6307E3ED3FD86E37D5EECEFC1F98DD4 -:104E8000EABD9D55D803966D9BE147B852B597B0E2 -:104E90004E16ACEFF11EEEF75AF4AE2A709EE6F312 -:104EA00035A31306D377BEDA6EF38E27F8B6BA476A -:104EB000EDF09317598376CEC3DCBADE8EBCE45F87 -:104EC0006C59CFCFE76D29E6BCCBF9A28AFDC8A308 -:104ED000FAB92C63DE0B0A94756EE2AF5E43241FB1 -:104EE0002E8895FB79C4CF2F615EA7B7283ED88F57 -:104EF0005716EDB417D3F3C33ABF7AA64D1B0BFE7A -:104F00006B09C9FB395A5E53E5BD6357AA322FE6D8 -:104F100002F7F94C399BC5FC7DE5D9BEEC674D0D18 -:104F2000F7917E6CB6941F2DF52AEFC7B5BCB63F3E -:104F3000750ABE576FE3DDBB05F60679FEDF22AAD0 -:104F4000708EC033AD41F25596A882FDB7E42F6F45 -:104F50001FC4BA5B92E5F4603D140D534DFC593902 -:104F600026CEC4BFD344B2E91CCD55482A8980AFB0 -:104F70001CDFCDD4FEEA2BFB46C9839CD67A96076C -:104F800043A2CE011698E0722A6F817C129799DEB7 -:104F90002B17935BDBC11FDE28EDD6F25D491BB0FA -:104FA0002FBEC022FDA1699A7C5EB1573E1722F642 -:104FB000DCB9749CC7477CC0746E5BDFE743BF1CE1 -:104FC0000FECD6C0719DE60C929784D1F2DE8D76FF -:104FD000C4D3C85C6E469CB43C4030FAF58BE65AAC -:104FE0009C1FB14AFCBABCEEAECB325AF9A2629712 -:104FF00039DFAAE2D0DBDCCEC8678CAE273B7D650B -:10500000078C7BBCE2E37393DB9AEC88075DA975A0 -:10501000E47B29A2EF4B2B0B35F138A7EE4D7363E0 -:10502000DFB622EA9EB485433C523FE9F17FDC3390 -:1050300024ED8406BB8CDBBAF65978FDC97B79CEAA -:10504000F1E5028BBC2F200A2FE37DEF727F1D322A -:10505000641E1AF0628DC04B341F014FD6083CCD40 -:1050600013124FF3489A0409EE003E8BC4CFCFC40D -:10507000D77CFC41F5F3F72A41E4BF45E3679ED6B0 -:10508000C8F89BA7B9AA82EEF3E75371CBFB0721BF -:105090009F7664C87B0DA3F1375F34AC84DF3B9F00 -:1050A000F4463889F9C2EE643F4DF1426F7B063514 -:1050B000DA6D529E719CB7E5B5B779DDB578695563 -:1050C000832F04D5537B97DFD3BCAC8D3CDFC967FE -:1050D00065FCE4AAB3562EAF1C6F5E7753CFA6F1E2 -:1050E000F39F8B970AE0197C8EB85E421BF7EC2188 -:1050F000CE9770FE7C8DFD10430EB7DA75E6BCE5E9 -:105100000BD97FD171C21B87E871C23C9167CA5B22 -:10511000BE80DD119DB76CE8F11697D49363D5EC92 -:10512000373C34EFE25754F6D33DD3C659F8FCF878 -:105130002BF27E3C6DC59926F0A7166F6139B83801 -:10514000BE2BDF6BA1E971BB73F6764D4A1AE27F85 -:10515000C5316ECEC72FAE518BA0BF8AA99D27A2A5 -:10516000DDCAE5DD3A432F7C727BAF8703B45E3E38 -:10517000B929350D71FF4F57D85249729E6BF7C947 -:105180008AB19D919FF1E9DD8E69C136F0F3D010AF -:10519000195729BFF57DD65B272CAF254CA3F7CB3C -:1051A00056EC4E40DA7FE98AB7F3DD6452F80668C0 -:1051B000EB86E421BEB77EB31BF872AFE7FB04B603 -:1051C00093B8043E8A57AC60BA2F52E47EF50D4A7C -:1051D000F8C8486A773CE6EE8469443F8DFE87FD57 -:1051E000C3331BE3F5F368359C37743C96EC016AD6 -:1051F0007F3446E2F3E8CE782FDF89E10D7466FF55 -:10520000AD9DDCDF29B5D45F85F14C4CD5B60FE1FF -:105210007DDEE0E67495DBF1B975ADA647625BF122 -:105220000FA3DCACEB69D8DB28616F235F06F63691 -:1052300060D8DB28616FE379E55AB3FDF6B2BE5F53 -:1052400068C483BBD436FB60EF060A44EF2AD6B3AA -:10525000E30BFE08BDF58AB4179628DE558D6C2F3A -:10526000C5D7C1EFACB54A3B3BF0B13C1745FF7A1F -:10527000433EFD5ABDC48BFDFCFBE36E7D04ED9700 -:10528000627F6800EE3D25DB2B825F479E758AC8F2 -:1052900073B7A3C8088B84473B334CEDC7BAB34CF4 -:1052A000F5BF48EF63AAFFA5C767822FEF3DD8D4AB -:1052B0007E82779409BE62D02F4DED27F92799E0C1 -:1052C00029E3A69BDA4F2D2A36D55F3D6DA1A97E35 -:1052D000BA76BD09BE76C14DA6F6D755D598EA85F2 -:1052E000A87A0CF8F107E43D6CF5F09F1CB8FFC5F7 -:1052F000C925D5FF0979CCA348D4F3BD2B7FB9F1DB -:1053000011C0FB90D74C2B6ED8684B555B71FC1FBE -:10531000747BE9EA61FE6F87B03FDDC0F7682276F3 -:105320000BBE8B1BEAD1FD5FF9BCA3D5885B35644E -:10533000F07D0951ED2FD46E58DCBED31E62B92525 -:10534000431FB8CE4AF26BD8C07DB9DD08DEFDDC64 -:10535000C7121EBAEFA9AE043F3FB4C74C862FDD7B -:10536000771AF5970F6B92F553049B262F3FB7E200 -:105370003AE4A70C1BD975B557C645DA3CDF6E94E5 -:10538000C013CE85034F28C3C4F728F711DFA33C11 -:10539000407C5F4272ED20F13DCA43E467E2F9FFD1 -:1053A000213F13E56BE467A27C9DFC4B940DE45F09 -:1053B000A27CAB7A1A97EF546BFCDE5FAB1770F9E7 -:1053C0007E75153FFFB07A29971F5707F879CFA14F -:1053D000328EE022BD03FD5E813C18E40B44DD4BC0 -:1053E0002AAADC7CFF41ADAEB744BD9E57B38FFC0B -:1053F00057E0B3D19A74C4D9BABF78617FDF2A8EDF -:1054000044D86D5758FD3943998E1DDD2CF7F5E7CB -:105410004F7AB5814389EEEF664DE991AB42DF5596 -:10542000BD944875EF5ADABE7F326EA8E497DEC3AA -:10543000FCC3F0DE70E761DE4FF76490B53A94612B -:1054400005F4577264FC72B8B5A116F5B5DF0B0F01 -:10545000FCE617E3FFCAFBE0B5642EE3FCB172562D -:10546000FA2B23F4FDFBDAEFE5FEFD088C9DEA87BD -:10547000BB657DED5CD2743ED487F8FB2370DA59AE -:105480009E6F33E5ED8C39DB309AEB5D760FF24D94 -:105490004738C3F27B4EE1467CF9C5F83DB2FFB117 -:1054A000B2FF8DDF87F9FBF03E91973DDCD93A9E44 -:1054B000653CBE06793F5DB66C5FABB71FA151FF7F -:1054C00049185F951C5F31B597E367393702DF4CA8 -:1054D00082B72DEB63D3E5F9E43167F57AAF9C6FC2 -:1054E0007BAB8471A604F599299AF0537F9999C2F0 -:1054F0008BF8DB88D4860C6EAFE733C45BE5F7121C -:10550000BDF23EAEEE7FD7E47E002100E337F2929B -:105510008C75DB29399C013BAFD3623B7F2F53DD78 -:10552000E983BCEEE3D37E0D7EB03A2D3CBF5ABF7B -:105530003C2FFFE6F39E4EB88F74926EAFFF13FAC6 -:10554000DF82F7873B5F90F4C7256F99ADB0328F4C -:10555000FE37B84DFA4B7C11BF60FE447FA607E8CA -:10556000A9D35F31F0A3D3FF1CBD9645D6EBFC71E8 -:105570003EFD4392DE3A3F8D70CABC09B407FD87F9 -:105580005B253FD4C6C87C8F17E30B1FC03D5984F1 -:105590009B22C4E7871BFC5225CF0FFF6FA5FF009E -:1055A000ABBC47CE51E6E47BEA7E8A1F66358B4270 -:1055B000DCD379CAA7C5615D179FF51C043C478CF5 -:1055C0002A84796ED49FBD40BDF64DB30DB0F1BCB9 -:1055D0004B8E6C67D45B9D6FC541EE19DF31DA8D60 -:1055E00038AF5D8E13FA62C9D8D03AE8AF7135563C -:1055F0008E5B9365C2F021D267329FD39FE04B8BC5 -:10560000CCFFF41E583C00F78BCAF35BC225ED6A51 -:105610000FFD07B95AF843D172F427D46D56F81D1F -:1056200067904F4BDF294C35DBE7E3A2F6D72FCB52 -:10563000FE82EDF1CB7EE29EEBBF0DD5CFDF64891C -:10564000ACFFE43DA35F48F97C71F78CF616F5CC0E -:1056500007638A653E17CDDF9283B88D5F54012EB4 -:10566000145556F0C1385167957EA5FF78C500F6F0 -:10567000DA193F978B303F9F400A05CAE40A621F40 -:10568000C0FBE326CEC0FDC1A3734777C7F388FBF9 -:10569000F37EC0F82A54ED6FEE88FBF3F68D91EBA4 -:1056A0006DF154196FDAE7ECD6A61DFA0AE9DBEEC4 -:1056B0003D8017C1E54BA48FBBD3BC5F267D0CF8A2 -:1056C000B2DE35BCAF5CE831E71D19EF5FEE1E2D91 -:1056D000AC2917D67797F77FA623F0FC6A52AF3133 -:1056E000A0D7AB4903C7201EFF6A527B8B2C1D76C7 -:1056F0002EFB3DDDBDADF119EBA3B5BF42EECFB83A -:105700002F784C3B795F70345E2F1321137EC7EBEB -:10571000F8FD1978ED352CEF7CBCC6E1B0631EF0C6 -:10572000F9F61E236F0AF1E4EECB1B18BEC126D793 -:1057300041F9D3130A9017BDF85D99DFF125860270 -:10574000BDBB74288F7FC4D2C1C29ACBFB5101E08C -:10575000BBCC29F17822F0627FDC6BFE528A3608DE -:10576000FD7FB14EE5F3F6279E8CE178DCD1E05366 -:1057700009C0A7C1C765AA67B517EBF05555DEB3D9 -:10578000F4C3FECEB887F4427C4DFC3C6A585E1BE5 -:10579000FCEC227EEE773E3F8B8DF21E83326761FA -:1057A0009B7436FC4E678E3F0E7CE816E1EBC1FF22 -:1057B0001542FA4715CED7E43D9504E3DC6BB45DA2 -:1057C000951F4BEDA9DEEE94F9C206BD331DF21E06 -:1057D000CBCC38E1461C4468B997705CBE9B7F1AFD -:1057E000C64F7EEDB6C8BCB511E1BEBCEF3CEE9035 -:1057F000CAF9EE2FC7CA7BDF1B891E0AD9A7BFE8EB -:105800005BE5EA4A749C99AFCD198679A93FA8E86F -:10581000F7B51E8A48E1F879AE8BFDEC9FE9AF97AA -:105820000ED3FDF5FEA2FF3FFD3D8576F2DEE1C51C -:10583000AFE40631EEC535A4D552F97731F89EB8FC -:105840005AF8E759AD726784E8C9BF97313AD5C6AF -:1058500079E6FFDB7E4F215368BCFEFEB3BFAB3061 -:105860004E3E3AEF77153213561DD0525B7F5723C9 -:10587000FA771532F5FBAC8547EA0FE3F714460AD1 -:105880003FE7E58F4D37EB95D1EE5107DC5C9AE3AE -:105890003D993F91CFF5F8305DAFFC14DDCB854EDF -:1058A0007779AE137CA0FF3E4A10FC69FC3E8A412A -:1058B00077E377526ADBC9DF49F957FB5D9468FAF1 -:1058C00044FF4E4A347DA27F37658416CB781A5D3B -:1058D000E662BE36E8348DFE637B00E77295FF7E9C -:1058E0007A3546ADD33362751EEE293D552CE5FA67 -:1058F00085F4FF835EFF11C88B6F114FC27917A724 -:105900008C87F86BAD226684C0FD849C2FFBEB5A1C -:10591000790F54AD55C603024457DC8BF75DEC3F5D -:10592000E47D8E641FD93A202E53C5EF07EC4E77E5 -:10593000AD17F44E603E59BA549E073E6CA9E3DFA2 -:10594000BB98955DA560FFF268967616FDA78BA2C1 -:105950009DF3382E5F3510F27DE69F1D9D513FB3BC -:105960008BBC3F526437E645DA233333F53CCCE158 -:10597000FA7EBC57E661A9C3655C2DDEEBE6730DCC -:10598000C5D942CF6F159D67F6031F7FCC767C8B00 -:1059900047DAD58D36798F65E01599CFB3AEEA2D0C -:1059A000B6FB37915DAB4AFB66ED9D1C674810D88E -:1059B000C77D24A63909E3EFB55698EC853E41A78B -:1059C000292FB9EF16B709EE174A37B5BF74AFC71D -:1059D00054EF0BF736D5E71EF29AE0BC8641A6F6E7 -:1059E00003DFF79BE0C18DE34CED871E2D32C3C36F -:1059F000BB4A3C8127693E3397B883F21E7D192745 -:105A0000E96297F654ED4DD29F30F2D7357D1D44B3 -:105A1000E7AF77B2CAFC757B95D46B9A4BFAB7EEB9 -:105A200064E156F95C4C03C3B81B82F3C603E63C41 -:105A3000F38E4EE95F59C648FFC3AEE799C7F696A5 -:105A4000E75E8CBC72F22BFCC07777D1389D7FEF7C -:105A500040BF4F349A9F7FA1D33D7ADC5DECF23C8E -:105A60005DED4D76DE3FD75CF62625E1FCF1540D69 -:105A700094FCBFC9D9F6BD4F53753E7B2CB768C2A5 -:105A8000702A1F26B5C5F6D779FD791B21EF6A7FED -:105A90006BE7BCF19FEA6FE6A5723E332C965993F3 -:105AA000B2D91FE4738046BF73F57E7F39526973A4 -:105AB0007E33139BF9DE359168F7807F35D74A86B0 -:105AC000DDB122496D03EFADE732649EFE75AB4355 -:105AD00077F6A271CEB0D7D9E48503411BF8617C7B -:105AE00001D991B43E5EDE33FC2117D1E3E1A55626 -:105AF0008E83950D7F6666A03BECCC66E60724A2FC -:105B0000603F11F6A79AD33AEEA611328FFC4E5C95 -:105B10002CCDE7257EE071B5E8F19116113A777E3C -:105B200022D006BF69AE837C0EC1BD58F253A78850 -:105B30007356F03FFFA7CE4B08EC90523FB63A2188 -:105B4000CF39FE04FE8C732A9EEB6D451B5C382F0B -:105B500022C6291178F866848C5BFC79B8A437DA00 -:105B6000411E5DA81DD97D89D85F68119E44F74FFD -:105B7000C4D5FF27E69F69957186CE4E795EA493C2 -:105B800055637961EFADDF73771EBFEB72438F937F -:105B900075B4CA75DFD12BD7F5F972E1007FDFAE9E -:105BA000C97BD3A2F1CBFF22E22AC6F995D83152A4 -:105BB0008E1872E1DC39941ED20FB5E9F221D8DDDE -:105BC000C27907B7C59BD771B32E1FEE31F445805C -:105BD000FCF87C939C10D8D7AB5DA1B29C2039799E -:105BE00050A37116E35E1677EBEFC3CDBD57EAB154 -:105BF00011FEA2FBB06F327B8D4DACE77D05793F86 -:105C0000EC7C3D4E5E1C88BA9F45B7C7CFAC56DCD6 -:105C1000F8DD8839ABCCF5F35D473E86FF3837FABF -:105C20009E1A63BFEE27E2008DC3757BCD2BBC7A35 -:105C3000FEFD328CEF4C50DE7B7DEEBC921EFF6988 -:105C4000093E25E15B8488FC1D09C32E30600FF6F8 -:105C5000C922EE6121FCC6F6867E5F6E6D33BFD130 -:105C6000C0EFB93C0F7D9F8ECA652BD89F91F90D6F -:105C7000240F785FEE38D5C30E3C1E38CDED8FEF84 -:105C80008AE1BC9213BE86FED8BF35F6E9BA6B72C4 -:105C90001FAB6557BCCC6F705924BC45DE63BFE8B1 -:105CA000EFC1FEF0631B034F99CE39688DE67DBED0 -:105CB000E852ABD9CDFEA66F80163382F8EA98D5AC -:105CC000EBF4127CBB6B1FDFD3359EFC47C835E479 -:105CD000A5AC4895E367F915382DF15725F17705FF -:105CE000197A909FEF0A929E88630AF26AA92C0E95 -:105CF0000FE6FE7FEE3ED894B33EB9FF7B7628BF19 -:105D0000AFAD1ACC70EF60F3A8F7A9DFAB349707FB -:105D100071A4A9B5BF1E1B0BFAFFD1B582CB4EE60D -:105D2000F30346D97B84A44BA3ADEDFA3F8E90EBF1 -:105D300063CF08A1DF5723F97D718DC2FB6A8BC148 -:105D4000E380EF94F7731AF0E93A1D1E2BE1252B3F -:105D5000240CD5043B78B6FE3B699BF5F80BE68F27 -:105D600012F3475C609B1E9FC1FC5162FE780E7966 -:105D70000518F20A30E41560C82B94905778FE7924 -:105D8000D268DED7C6BEDD9888F5847DBB3111EBC5 -:105D900003FB769130F6ED22DB63DF2EB21EFB763D -:105DA00091F5D8B78B84B16F17D91EFB7691B018D7 -:105DB000F4CB561872CD3FC9044F217F604CC47A92 -:105DC000C6BE5DE4F7B16F67FA9E76BDE9FD6BC5AF -:105DD00052D3FBD8B78B6C3F6BA962DAD72309C8C3 -:105DE0007A7DCEDA14E6A3645FD1BC1179FCBB5690 -:105DF00037DABAB27CE038C6E2F258AFA477DD38C1 -:105E0000497F8B3C1FA134F3EF0B9CBEC52EE1B143 -:105E1000E6FC6DA3C4BED7189BDCF742897D2F94A6 -:105E2000D8F742897DAF313DE4BE174AEC7BE139BA -:105E3000F6BD5062DF0B25F6BD5062DF0B25F6BDC7 -:105E40005062DF0BEF61DF0B25F6BDF01CFB5E2817 -:105E5000B1EF85E787691C2511720CF67A77939F5D -:105E6000497C68F233DD2618F67A647BD8EB91F52D -:105E7000B0D723EB61AF47C2B0D723DBC35E8F84BB -:105E80001F1BEE613D06BB3DF23DD8ED9170BFBAE0 -:105E9000C04B88AD4D5877F200CAC678E5619C3793 -:105EA0007CEC852B6659491F36C6289D9348A6DB96 -:105EB00094A9B3C640DFEAF98FFD45B305F24783E5 -:105EC000333980CF19725E69BFEF33B8FE65E35C8A -:105ED0001CFE11DD7DBB04FFEE8CB1DF6EBCEF2537 -:105EE000B58DD268DF0AB7DD2EBA7FA31DE7564510 -:105EF0008C03279A9137E3BBC595033F64B345E113 -:105F00003C93CDCB645E74345F7DACDB479B2D3B13 -:105F1000F7E11C4C73B1E2C5B98FEE751A9F33EBF4 -:105F2000374358545FEB7C7A3D92C079B50746C839 -:105F3000389F317E233E4AF282CF0F0E6B6E189D42 -:105F400048EDB5C028FE1D9CF176693790A5310457 -:105F5000FE64DF80E2DF10C1E7AFEBDFD302721C2B -:105F60008F3D3251BE172BDF7BEC9104EE7FE27246 -:105F700085F3CC866D137E9C537E4F97AF7DB7859E -:105F800055F457BC5CF6677CB7785D673BCE731BF6 -:105F9000F82A168D63709FB418A0E04E59D1D3AA89 -:105FA000B15DDA7E86DB023BE862CF410D1F9034A3 -:105FB000167988A25EF0BDA11306BC699A2FA32BA7 -:105FC0001FBF832AD837D402D75BD0EF4442400AA0 -:105FD000E2C904633E9A26AAB208BF574D2B667CDD -:105FE000F79E2114E0BBCF8CF596547AAFAFF6A2A2 -:105FF00005F65ABFBA462E8D79788725A980C7DB6A -:10600000DC6331FEF16315961FD1793CB00F185E49 -:106010006E637D6ED80F8BE3CFE5F9BC873C9FD3D1 -:10602000876C9CE7737AF919AE2FDE1DC3793DDAD0 -:106030005A85E59A613718793B65D7BF9B0FFC7C81 -:106040009515DC9CD48DF5BC7D24F269BAEE4CC06C -:10605000119CE3CB775F85A37BA797EF96BF57ABE8 -:10606000EFEF18BF7B2AB2FD9C0F66D88142ADB717 -:1060700047EEE318BF9F46F293DB9DDE6B77F3EFAD -:10608000D7E9BF776AC47D8AFF927B10782D7E485E -:10609000FEFED9EC5577174E23789EDF19C6EF62C6 -:1060A00045E7632D8CB2037FEAF74E3D23F5F84FA9 -:1060B000ABFDC7FC72E63569FF15FF65FF5469AF9C -:1060C000D838EF7F468D8CD7899D82EF3F9A513328 -:1060D000DA827BA467ECF67B154FAB1DF8866EB7B2 -:1060E0004C3E9BC9F87D5BB753A622FF94F03BBEA4 -:1060F0003146CF57CBE0F2EAB3321F75B24BAEF761 -:10610000C66704DBD32D0187CC23AC177A7EAB990D -:10611000EF7C82F883E873895FD98FB4E509B07B9F -:10612000E87BD36007A5808F8B57205F96DE66BB28 -:10613000339A8F275BC357E2FB93BD36E6AF7FC62A -:10614000C7B897E39C5C12552FE19CBFD8287FC746 -:10615000619A26F9BBAFCEDF33E3F4F8934BC697D1 -:10616000CEC59F3048C4CCC4D659C8179E89E48593 -:106170000E3C2D3FF2F5E2B365FD3523B7CE5A0E46 -:1061800067E6027109F5663BDF5FADB99CFC3B3405 -:10619000178A13203E00F978DD0D3EFBEC08F95814 -:1061A00030AA608D3F2FE2BCE3ED320F6AF1ED3D86 -:1061B000DAB775DED628E7107EB13E662636DE8871 -:1061C000F3E64B470AFF9841F27726E5BC4418797D -:1061D00098D7E8F0C63F37FC6D958BF1C1F00D7F85 -:1061E000DE330BF7C7953B1B0BC16E95D955E3907A -:1061F00077DD2A87347F6616E4D0A830E4D085E2C4 -:106200000E1B474A3A44C71FE6644BF92CF4FBC205 -:106210003FB9FDE91D90E7C6F83FB9C0EF63AC1B7D -:10622000A9EB89EAFF9E731ED1E73BDEE8A3DD35CB -:10623000B21D7E97C7DF843CFA0E6A9D9E3F2BEF0E -:10624000F530E81B53F71DC73B4AF4FBF0499EB0FD -:106250003F39DBEFF4D6408EF4162B715E68A62A28 -:106260009A79DFF83CBA4B3C3E32FDEF0B918FFB45 -:10627000C86F63E5791D1D7F33EC0D2F39B35AF1DB -:10628000F7D1D23FD8A4FC0AF7C0BEDC3555319C0B -:10629000DF5630AAE851C8BBB86C2FDF83B1C62FD8 -:1062A000F9C9DEB568339E97AF7EF161DC9750592E -:1062B0009FC5BF2B53BCD7B712E71C0B46694F6075 -:1062C0009EC52E37DF1B52B13C89F5D3CCF67ADC64 -:1062D0005534F33E9C81F7037A7CEA9E51F2FBA78A -:1062E000743F03827092A9DD85E27432FF06F939AA -:1062F000883F6AAE3D1C2770DF2CEFA9B08B776416 -:10630000FC31BDEDB841A61E6FCCF0CAF89081BF3C -:106310003B7ACF66396733E2B9E7F0673E8F69941D -:106320006EBFD4EFB36F50D85F2D59A3F2B9F2B15D -:10633000EA78BEC765F1DD8A87D7D7BDDD38DF7B58 -:10634000F1ED648D7970BECC53D87E00EE5B57DCE6 -:10635000B04B66801611F19D92B58379BD9504A965 -:106360006CE35E53A3BCF6EEFD9D9EF1808C7EDE59 -:10637000BF2C71FBEDC911EB7D4E9D62BA5FC180F0 -:10638000855FC6DB66085290348E19DD3D0AF6152E -:10639000DD7E8987EB6EC8B2E3F74866D0972D396A -:1063A00017EEFFFF95F2FF02371C2052008000001D -:1063B000000000001F8B080000000000000BE57DBE -:1063C000097854E5B9F077E6CC99992433E1640172 -:1063D0009200F1241088803861A72E1C1202130845 -:1063E000305940F086308120A1456F0497D04699FE -:1063F0009085104143890D52D461F3564B352ED709 -:1064000042C57600EB525131486B1793617169DDDB -:106410005228B5BD0FF7FABFEFFB9D93CC39990415 -:10642000B4F6FEFD9F3F3E78F29D6F7FBF777FDF22 -:10643000EF243F9DBDCC2632D6B54D90F7A4315602 -:106440002EABB6F14EC6BEC49FE98C2D6F16D4C0DC -:10645000D89E727E3A5BE68572B4EA626C1263651E -:10646000B2624B4EC3A76C8B87F7CBEF3822B14497 -:10647000C6568C604CC882F6F16E9B13C75F0DE365 -:106480000B8CDD2C0773B1FEE6B10AAB8983F67580 -:10649000593606F3F9B6F0797C8D71B66BA05C665F -:1064A000956DC3A05C12CD18B687F505B07F795005 -:1064B000B5C53B715CB6ACD0C9D71B1FB6BE326D3B -:1064C000BDE5CD71B69586F7DB2405CA4B1853DBC5 -:1064D000C2F6A73FA7AB02ED67795D416A2BACB767 -:1064E000DCEF9271DE72AB6A73E3BA705CE8B7A45A -:1064F000A5554A0BEB7F8D6AA17ED355859EF9E9A0 -:10650000C10C01F77B7B941BD7BB446E96109EF9A0 -:106510003A9C1FE4705829073370FC950E0E077DD6 -:10652000BCF2163E4FEFF5717897B794D914A8BF17 -:10653000C5EA4D6D85FEB7C03AFDF05CB2E3488612 -:1065400080CFCA28B700E7C1645FAAD7D5D3FF833D -:10655000076F4AA5FDC3FA11DE2EB7322B09D6B359 -:10656000A21916A3D093E62D9DC02ADBC2E0769334 -:106570006A656C203E2DF464CDADAA6310C083F132 -:106580009FAB6C2766E03E6AAF666C23ECC3E77C8A -:106590007E06EE53FE2E63E23458EF96B7A97E4591 -:1065A000129305A8B7B1E704ACB795431F28337F12 -:1065B000AE1ACAE4637D99CED8301C19DA3B017F4C -:1065C000FCC98C554E5168DE252CB4840D8771B6FC -:1065D00014C01CB0CEC17C9DA50358E53311E0D595 -:1065E000A2ADF766EDBC4B2CEC2516DF537FAF76E2 -:1065F000DE2588CF61FD713C1C778D5E9F1DCCB878 -:106600007D6C4F7B7DDE9278DE0FE901F1708D8627 -:1066100007D87E2DB5E7E55CD1B9B11EF6B376ABF0 -:1066200018B00BF8DC5B3F08CB4F0B6E84FBC76BDD -:106630007FFAE62278FEE907BB4B717FFA3A56FEF5 -:106640002D8B290970BE7FBB8E9EE5C1694C99D008 -:106650007B9FC7A6F8BEA74E0AC39FED3F19E983EB -:10666000F93F7EF2F50C84F31F00074480F3BFFD71 -:1066700064AFC4D27BD6BFBCF16DA9CC190E2F81FB -:10668000E0D594D94EE7B72293F75B51F7E7323C58 -:106690000FE6B4291969BDCFBFACEE69DEBECA4DA5 -:1066A000ED7DCE5FF3F34F61B2987CF9F3D6CFD78F -:1066B0007CEE8F48DE609280E7D36CA07FF3FE1FF4 -:1066C000D6D61DD0E8EF660D8F6FAED846FD963753 -:1066D00096ED1561DD4B74FA2D37BED7CFE7FC166A -:1066E00089CEE7FC968C86242CB7F1F3F98ED83648 -:1066F000EE6E68F7F19AFDB725A7E3AA03A9DE6B52 -:10670000F8F9B009FC7CF0B90ACE8725443C9FA774 -:10671000C2CF67D5A3FC7C563CF9C67B3F5308FF2C -:10672000F8FEB6DA03C87F97B73D7DEA5BF07E4995 -:10673000E336290DDAFD424DA37DE9FD575466C9C4 -:106740002C16F6D7B85B423EF00B558988E73A5CC9 -:106750009995F399472438DB38AA67427C4FFB258B -:106760004C1D8C7C84F987B2FD89BDD7FF278D8EA7 -:10677000F2D3DDB6C1C8BFEA63D81E19D751763F40 -:106780001BD7BBBDFE3C1BC5E96239CC83F47976CF -:10679000863B15E9A2C46231D09BFE3CADD1D790B7 -:1067A00098B625B8DE21094CAE0510FF305ACDB69B -:1067B000C0BC3FFC9643AE75637F9F82F57607931E -:1067C000FD00F23D16653CE1276C795332C232344C -:1067D00009F9DE8835A13FE3FA109DA2C6F3A70BA5 -:1067E000F66D9FC1F104CA6C107F1FC4E7306B1BAC -:1067F000F1A9E82A8E7F36F60E956DC0B7106FF5B9 -:106800007E43D80901DF27C35A70FEA6CCE5747E0B -:10681000D2084E2F7DEDEFCB2BDCDFD9345F80E447 -:10682000441493F7C4D1FED662B97B7F994CB5402E -:10683000FFD2EF5DB3BB09863C5BA31EB541FDD91A -:10684000F54EEAFF4DEDD7BCCF25E565867D76D3C5 -:106850004D33F0B5347C4E48C5759E77C044507FAB -:10686000F6F6280BC2FF6C1AD717180BB90AE15CB1 -:106870001EDB00BFDA19FBD106073D9FD800C834E4 -:106880008AB1031B92A8FCE406859E6D1B32E97D4C -:10689000FA0C8E7F25D16A2CCAE5AE1A97BC07E1A7 -:1068A00011E474D351359CE0007A02E7C79A5ED0B8 -:1068B00021875CF1617C1AE4C7569477AC6A38DBB7 -:1068C0000F5374349F7559C6225EF2F5E9EDEF90CF -:1068D0009AD97A6CF79010D80FE3C6DCF176EE60A7 -:1068E00094D32D695902F45B5A7581F8E152E7207F -:1068F00085A11C77FA1AA660FD8E347923748B6902 -:10690000C9EAA882FE2BEB46B9B1FD1D82D240F345 -:10691000D6086E9C177E54C764E003F81B94573961 -:106920005F1EA1F14B0BF2CB15F7AF6F4886F269F2 -:106930000BEB120134F996825958CEDF19E7AE45B8 -:10694000795BCBF7C376011F75F4F05175AAF7FA9E -:106950001970CEEC12E01B8C3F1AD6C644DC4F9B5C -:106960008AEB67A077EC67B85EAF0DFBBFA0F1CBF9 -:106970008E96D32E453B9F02A41B5FD7E94D78AE80 -:106980004E8BBB4941F9AEBCA520DC5F13D91E0577 -:10699000F187D7AF75F17A786EAC87FAB5BBC500D1 -:1069A000C223572C191442FD6B87487C71E5EEA277 -:1069B00041A86FAC8432CAAF9D3815E053434B0EEB -:1069C0006FB72DF7077EE0A7A902F3223F3A670DC4 -:1069D00015203C3EDA3D38BE06F5BD5B6B4732A85C -:1069E0002FDFBD29159F1FED8E5A8C7C7CA65C3055 -:1069F000330EF59F5D7159A2D243671533389D7DE3 -:106A0000FBD69CC128EFD6FCCFB1476490AB2B01DD -:106A1000476518F7625B4CC00F4DD66C38982A0258 -:106A20006A39137D2B106EDFB11C5E340DE5B0109A -:106A3000782C99DA2B83E54874ACEB5380C70AE0D5 -:106A4000E9ADF7BE4BE37C6A393E7F09F45F73EB37 -:106A5000B3B138CE771E3C395986F759137DFF8E76 -:106A6000E3FF49D8FD980C20613B768F43F95139FB -:106A70008371BE1AEF5DB484C3D7BD47E97BBE8A7C -:106A80008302C1532F2F0D0CB031D44B83CC26E39E -:106A90005366A4077F24B22A94EFBA5EA2BFAFD593 -:106AA000E0F2D180E6543CFFD58FB5A6A2FCF8A356 -:106AB0008B977DFB5E59F95D5887AFC52233C03B8C -:106AC0009F9591DEBBC2CFF5695601CC24B967FE14 -:106AD000AD336268FDAB774C30C83D908F34CF1F2B -:106AE000ADCC83EBB8AAB62B0BF5A7DF5B832BF1FC -:106AF0005C7F0FFAA93F0DCF89E3DFEF9BC559F803 -:106B0000DE7F87C032042C3FEB1AE1243DCC427C6F -:106B1000FD0529B01FDABB26B60591EFDDFA5CDC76 -:106B2000780463AE387630E2CFDA43D2AC215C9F92 -:106B30009271F635D6A02DD2B97D5BD3A3BACBCF57 -:106B40003D6D43BC5F7300F401A4CFE78400EA37D6 -:106B50006BDA9E7E3905C6BBED60D9049C476F7F1A -:106B6000DB731C0E512C642B0AD3ABCB32E31B8698 -:106B7000008F7C72C6BBCB1E842D95E1397D0BF84E -:106B8000D7F45FFB6A46E053A67D326B17E9E3A0BA -:106B90005FD950FEDF5AC7C7BB35B3BD219DF6553F -:106BA00090C0C2CEFFA91912F5D3FBC3BEA95FAD39 -:106BB000E3DE4743B05EB5D6CAA26E84B295FDE16E -:106BC00031841F8B95F7E33EACECDCCBF0BC5B1C57 -:106BD000C09AE0B9AB72ED7F50FB1ABB2CC2B3F682 -:106BE000D6EAA742309F22322F83FEFEEC4A1ACF0C -:106BF0006FE3F2A735E6C9876E817255B1D30DE810 -:106C00000DE55882CFE1BB2CC4E79359D7310B3C3B -:106C10000733A02200D04769BEE3C47718E7C777DF -:106C2000AF5302C88F61E502E2F9E72F7E3801D742 -:106C30007DE355A10B885752CD87BE9940FFEFCC1D -:106C400090B97E32363401DB0D3CAAF135EB099266 -:106C50008F5292128FFA4A10C7C2F5FDDD4278704A -:106C60005808EEC5797538456573FDEFEF6EDF7B2B -:106C7000B80E5590EE0C42FB0542AC1BF77B225E32 -:106C8000CC180FF4FCB9F487341CD70F682B0EE92D -:106C9000D163B3B5A5DB52A6EE40B8CC0080B2EB11 -:106CA000C196191BCFAC50BE8F59BAECB08EECAE6A -:106CB000DFEDAE81B2FCFD014C0451551B95CAB20B -:106CC000617CE1286C14F67374ECD115B8CEFBBA74 -:106CD0001C0CE1C41C463DD766490E7E0FF1B9324B -:106CE000D6CD92500EB565213F62B739DD4DD07ECD -:106CF000E9A550C6BFA35CFAFB71D2D347A5FBBE82 -:106D00009801FB4A11D5D33EA8BF4F0E0E7F00C796 -:106D1000AF8A71D77039C2C2D77F78FDDF6313A005 -:106D2000DFE75D23AD4F41BBCF55871B3458D6F10C -:106D3000DD312F5D07E5EB3579625ED7E7498A15CE -:106D4000ED8ECFBB1C41D4433E775A02028034FB08 -:106D5000F0B1770590DFD90E67508CC57ED227E160 -:106D6000F2869D1816F7C1181231EC4B80E7204DC2 -:106D70002EDD38C0683FA664733B28259BF31FAB0C -:106D8000E226389FF75B5913E2218332CE6B75C838 -:106D90004DB0BE9F3B1F5B0A94CFCEFF2D7D00CA36 -:106DA0008DF387870F6063FBE68B27519F003D6162 -:106DB000D178352D7B528F7C5DA8C125AAF9260993 -:106DC000E1510BF06802782C745A8276D8172B3672 -:106DD000C28155759522DE304BAC1BE906CF17CF2B -:106DE0005F112C5DECBADEE73DFD921CFC1E949712 -:106DF000C279225C4BCF7F70CD038CCEED1A5C073D -:106E00009C63FDB5ACE7FCFED5CE8B59DD8D780ECD -:106E1000778BAE663C875A2BD7F7FC805BFBE3A8E9 -:106E2000DB63782E77D78EA0731A540B7C02ED9417 -:106E30001A2BDB93887CA59DDAEFD7F4419659494C -:106E40007CA6B4D62E23FCBE888EA5FE0CCE554A59 -:106E500089C467385FA92A67C457968DAD14F0DCE2 -:106E6000937006D84F8725E4C27D86A2408B84E7C5 -:106E7000FAEC74A2F321C81186F373C6FE0FAF7744 -:106E8000ED417E233A863C7C0E44116BEC8A1D0D4D -:106E9000EB6A11581BED4BD2F8C76A27E9732D71C5 -:106EA00001E26F2D0B87BA71AF9F33ADBE229AF806 -:106EB000CB75160B95BB960C227BAC250E582B8EF2 -:106EC000B76434E90DCFFF8FC8EDB50CC6EBB3D86E -:106ED000C81D585F9049E3BDA0F3ABAD2E1AAFA516 -:106EE000404D8EA6FA4116EC5F9EE65B87F8912234 -:106EF000F276A07850BB9D3BD5643CCF9D85366A29 -:106F0000F703C1BB64258E738D93F4C6D092E82736 -:106F10001FE3C71944FF524715DFB74E0795533893 -:106F20003FBDCA7FFA21E41FFE6C381127CA8BCF00 -:106F300096225EAB62AC1B50B8D7397FD18DE7ACDF -:106F40000B80CB12A33BC85E573218021BCE4F6694 -:106F5000D98827C7009ED0DE2FC13927F273DE986B -:106F600088E73C7F77F839C378FEBBE1BDB036D601 -:106F70002D4CA573CEC4F1AB58B41BEDEBEEF3FB77 -:106F800079200B9FA2C59D6407583C9FEE7B307B08 -:106F9000608F1C79F83DD81FC0A5D41E9AD48CFAF6 -:106FA000B98555B445E0038F6673FB40665D12CA30 -:106FB000D7653AFE579BF03F3434EE83180DFFA19E -:106FC000DFE1C1DEDD780E9F0A2727E3CBE3FF2D4B -:106FD0002E8E34FEE39A7C792BD1FB235CDF08EB09 -:106FE000D1A1EB50DF586F27FD975D3A3614E7AD1E -:106FF0004EF3FE18C78B1AD16543FF54477297842E -:10700000FBEB58F2A761A8672DAB7A85E8F34AD766 -:10701000B731669C847233CE932585A0FF604FD62E -:107020002FF15CDAE7D9157B043FC891795386A12B -:107030003E74326FCA30E497278701C9933C75BB11 -:10704000908F4A07AF71E13A4F7A265059618A56BC -:107050002EEA97BF7E0CFC35088AC01FC15EC3E7CD -:107060008760AF0581DFBE0FF61A3ECF82BD86EF87 -:107070004F83BD86CFCE0D6E7A7FD233FC20E2C522 -:10708000C566EE4759617547D4CBD61C105950E7F9 -:107090006FF0EFDBFB620CE58A5D0986F22D2D8037 -:1070A000418E9E72F996E186B2AE7F2EAF1B637859 -:1070B000EFAB9E60286F8C2995F09CE28AD3387CD8 -:1070C0008BD308BEA7F2FA806FDE28826FFBC25115 -:1070D000C3107EED085FD48BAD8A0BE1271D5CEAFF -:1070E000423DA6BD78389501BE5B27E2789A1DD552 -:1070F0005EDC3F9CFF88701E85F07568F095099EE8 -:107100006735389F46388F42F866D2B31DE10CF5DB -:10711000B5C50067C0C78B7E941E805FD62E29A29E -:10712000FEBB4F34ECBF62578C09AE4638976F19DF -:1071300062282FAF1B6E28EB70F6551BE15CE499BB -:10714000606AC7D816907B45F80BE0F91B9366136D -:107150003F3D29B0CA0478C6C99C0F5ABD02F9DF69 -:10716000F0A719E47721FE02F463752AF5585F074A -:10717000EDBF0F6DD106463B8431B75406EF177A49 -:10718000A26494EB8B5825D1DB62D64CCF9B591B64 -:107190003D4BD8097A96324E8F9F978526E3F3F7B9 -:1071A00089BEF41CA0E7350EDFA38968BF0DF38DFF -:1071B0004A40BEE48C27FBB4AF73424D9B697CCA46 -:1071C0003959DB17FC14E3DAA15F7BCCB83BEF54F1 -:1071D0007AE6D1C787F9DC38DFA7129FE78D4953DC -:1071E0008621FE31EF40835DD5D77CDB347959E6CB -:1071F000E17042DF2D96CF2D14021BA17C649BDD34 -:10720000867E86739B254D6FBF97ECDDD3A7B87F35 -:10721000E65CFDEC54C4BF9A6DA35211DFCF494A1E -:107220007D15C0FFDC34E0E36EF2E7B8514E9CF10F -:10723000B8A83F488CD82C38B715DAFECE286EDBBC -:107240007A68BF3059647E68EFF3A7C5E2FAF57D2E -:107250009BD7BD7C8BDD80170BA61ACB0B99AD0796 -:107260004FD2F0BC6D3DF5A82F8925037CFDD8DFFA -:10727000557F58FDD64B6178F66F39AE44D46FD840 -:107280001436E54BB1A77F5FF0FD6243C55B2F4924 -:107290003DF0D5F16A528EB71CCF095EDB903F02FC -:1072A0005C2C28974F1EE470DC1673E3D6EB000EBF -:1072B00085EF888CC3B9D4FF7BC4E743DCBF6F9EE6 -:1072C00027A4D175A7C63FCBEADE263B6E597501D0 -:1072D000F19F4267D730F43F1DB907F80BF295795B -:1072E0009CBF1CCB1BF5F01D306E67BEE8B6033E9D -:1072F0001DC9BFB015CB27AB4519E7ED3C7841E37D -:10730000E35D6F4C81F57DE69188CF741EFCE7F05C -:10731000F3C2431A9F09707EBECAEA650D30EF2A98 -:10732000800BDAF3FF6CBE7E397EDE2E7973072286 -:10733000BC6A0437FAE16AF2ECA447B4037DD83999 -:107340003ED5DF81F2682AD8C132E29B7712DA9605 -:10735000270F0E1F88F0627EB53D73720FBEAFA877 -:107360005E958F7E76B6453A83FA373A45504E178A -:1073700032EB9950189EFA9E937ACA84D7D633A1DD -:1073800030BC36E3699B094F2FB24BA9B6745E7FC0 -:1073900062500FDFC39F70FE729B186C60693D786E -:1073A000FBD7BCB74B515900BEF202E2EB5DE3D311 -:1073B0005E0C09617CE50AF918E033C9BFD6981B59 -:1073C000B97EB190CBBF230B6F3AFA3B80DFC7F396 -:1073D000385E7F9CF753E21F1F839685F87A2A3F19 -:1073E0002116F1EF745D11D1994E3FE679DA357CC3 -:1073F000D3DB155A15C91D013F8B3C467CC9786EFD -:10740000E90094A77DAD5F1F576FA78F5B88718DD3 -:10741000B17D8FFB610EB74733F695F43B3E188282 -:107420003DF885FC8445F78C03E5233FB98961DC91 -:10743000F5643187CFC903A3881EDB8B75FDCA476E -:10744000F5A73C6200F5D893C513DE9888F4E39560 -:10745000484EF735EF396D5F67343DA053D303F4E1 -:107460007AF1C1858B96E0B81A5F38E5E1F8FB7ECA -:10747000CB42D23B603DE47FB2CDFC9F32F43F81F2 -:107480007DED42FED59E2F325C47615E11D9D585D8 -:10749000923230929E60DEB779BC233FB1935F0E8B -:1074A000C623BA2A9E57C41A705FC5DCFFDB8EED77 -:1074B00061BEE20779F918B69F688013F19176E012 -:1074C00023283AA4833790DEB4B2D9784E2B1A63BE -:1074D0004CF46EE417C50B399F6BCFCF191889DFB9 -:1074E0005DEEFCF4FE577AFE15D81FCAB8E62F49A8 -:1074F0004F89378C07169D69BE7453FD6853FD781C -:1075000043F972F8D8A9C991761D2FA294A5DE0877 -:10751000EB6F7FD25E119EAF317726B75FE6CED498 -:10752000E2F75F51AECE9A09FC2A86F592AB7DF563 -:10753000D7F9D3A81CEFBC99385FB048C27D5D294C -:107540003F0A93C30BA97F48B061FF6D9A9CAD6859 -:10755000E378D41A73FFCB88879F6AF6D091799C21 -:10756000DF7FA6F1FBCFFE532BFF440820DF3C76E4 -:10757000E8EE58D4DF3F3C382A16EDB1336DB5B193 -:107580005C4FF7C77E0BF0F313A0CB2698EEA3B6A3 -:107590007F8E9E5EFCB4660FFD88EBE9ABADCD91AE -:1075A000FDD4DFB09E6ED6CF73C592A3BF83757C2A -:1075B00018E07034EBEB1F2A4AAC4CF0E170F84C49 -:1075C0005262D1AF7726C0F97D5FF8A8C3E11CC233 -:1075D000218CDFF705C7B35A7FBD0CF621D92D45A5 -:1075E0000EF72F13D19FB0457063BC8A59199B0ABF -:1075F000E778A2386B6F53989E11972B12BE9CAE02 -:107600003B569A8CFC070C5DF4F7BE527D2C15FDA1 -:10761000AC650762883F9AE72DCF37F2994FEA0BA6 -:10762000B27F0FFD8ADE11030E84477E1CE75F4F99 -:107630008B0111CA9DD539B1E1FBF8D02477565999 -:107640002B239E63C52EE33916E5D7D038271F14A8 -:10765000DA8401F03C324D525CBDFB1559F9FE57FE -:107660001D10C9CFBBAAEECF6F607C7115F07B54A3 -:10767000135E69AC9D8F787DDA2B5910CF3BDB12FE -:10768000E6237CFCC5A23B03DA1F6F1C4E787EA666 -:10769000316710CEF7CB9922C9BB0F0FDA2DC2B5D7 -:1076A000F0F44A2C487E81209DE727754524AF3EA3 -:1076B00044B8903D2B135D9C98C9E30EA7611CACA8 -:1076C000B7009DA03EDC19103D8108F47162263F91 -:1076D0008FB3971E20FC7939702C16F58AD36D7CF8 -:1076E000FCB3D5722CC6A95EAF9BE0A2F5E5C3B88A -:1076F000A8F71EE272F4C33A8E8FB84EB20F1BB9D0 -:10770000FC3859B7E2FE69008F4FB788A4777EDA5C -:1077100058347F1A9EF71689CA39050B29CE713263 -:10772000C0E5D1A9C0D9523CBF0FEBE0F4A15C7316 -:10773000680AC9DD4FEA25C287F203C67359B82526 -:10774000C66CAFC66681DE558EBF29F83F7516DA66 -:1077500049CB93407E02E59ECE2F92D04F59E84F01 -:10776000308C63670512E21DEA97D86EF9C3459322 -:1077700082487F7E81E4DFB2E7009F603DD2BEEBAE -:1077800049DE9535DB0DF316561BEDA3E5267BC8C8 -:107790006C2F5D4E5E9CD6F054B73B4E4B95A59139 -:1077A000F212E45C4D2E307916C2FD0C18D64D59FC -:1077B00000CFE74415CB17EBA2887F962D3B7F8344 -:1077C000A697DE8878C0DC7E3655B7D3C3E86C79DF -:1077D0009D6892DB46F882FEFC01EAC78D099A1C7F -:1077E000F51791DF6E548E1A9F8BEBB852FBFB8A14 -:1077F000F5DB524DBF2D25FDF624EAB7B09F766C20 -:1078000012D61FF45DF2EF9C9A7713D95FA7BAFDE9 -:10781000675ECD7FC6F59453F9459A7FC7AD97074C -:10782000B07EF89CCE2FDED7CEE1ACC6274F6B7C66 -:10783000B253B3B71A347951A7C98B53F99ABD958E -:10784000C8485E58AD2ABB123E734B4B8C493E2450 -:1078500098ECA821A6F331CA8BED5EDF6C3C077B68 -:10786000D268C37B491E6FD4CFF71D263FF24585F2 -:10787000E7156D429CC0B8C9429EA7C51C6DE44780 -:107880005EE856A87E08C60BA13D9A54984FA2E325 -:10789000A7FE5E4EE4EFF5723CECBA06DBA5B551EF -:1078A000B9762163980F33421F07C051037AC21083 -:1078B000F467C33C4960A0617B1DDF87166FA37628 -:1078C000D9154C16A0DDEADC34C28724A6127F1934 -:1078D000B486A998F7C202CF52BBBDF7C23E00EFF3 -:1078E00043B5D3C92E2F72C4F2B837C8C7FEF1AC66 -:1078F00086C7773D09A4B70CB572D4EC136FB57683 -:1079000097C3DB303DE82EA20B66217FC4B6987189 -:1079100012E269A1D34B7E03C0EBA577A27EFFA242 -:107920008DFB0916723F707BDE9487D1DE1DF794C4 -:10793000937CCAED2B757F6517E1736775911FE521 -:10794000DEAF3D5CCE8D79EA130BE6BD751E646E2D -:107950002C1FAB7EF6FCAF486F17C81F74B23A8776 -:10796000F365C6BC98C779D293B391CA53C130CEE0 -:10797000427A50375A711D00D726AA5FB17512EAB4 -:107980003BC745C2DF242DDF48C6734DEE2927AA29 -:107990005A991DA472523ECF13FC99A61FB469E7F1 -:1079A000F9B8E6A7784CA39B168D6EBEAFD1CD6615 -:1079B000B3DF7917A79B9156F7D618288FF4BB48E9 -:1079C000CEBC957F96D60DF42F635C372D4F6C9A05 -:1079D00008701B630F119F2E02B1B711F63323BF3E -:1079E00086F2188B7C8CE21685C535B4BE10C6981D -:1079F000AE43BDA94610B57AE48F631282D4BED0DF -:107A0000C164EC5FE479FA08E6E32EF40168A03C77 -:107A1000B3B84620F894C178D0FE48F5761AEF54F2 -:107A2000055F47BB8BF73F59C6643F943398E7E83F -:107A30001D7C9D5E8C8B9EAA7EF608C1BB98C3FB05 -:107A4000BA8F2C067ACC0A461BE87AF4BE7843FD3E -:107A5000A81D2986F2406FBAA17D82C748EFD123C5 -:107A6000C61BEA4F7A8A2C2867753B4FF78B757ACD -:107A7000B8DC9DF194D382F058A4F90B1061D920A1 -:107A8000B4BA18F97D1B353D91350F6798C7B1F72A -:107A9000BB16CA13D85C5CEBC0FC878B6D563A2FC3 -:107AA0001897F8C8A9C3561AD7915627A01FF33EB6 -:107AB00080B318A6FF35EAF24D8B5FE07AAC61EB3C -:107AC000895718668E75B76FD1F069BBB60EE0DBCB -:107AD0003324B2C7399E24E4338B04FD071673396F -:107AE0006DA6CB36ADFFE35AFFC7347CECF4ECDD7A -:107AF000188D7059CC481FC915D76C8CC275E433EA -:107B0000A2C7B6E0D1E870FDF1677D8D533C2197A7 -:107B1000C6F1733E3A7A81501B85E7BA2BF4A7373A -:107B2000E1F9C2A70D1B6361BD4F08AC0D294AE7FF -:107B30009FBAFE7DDD678D543F7A3C986850FFC246 -:107B4000674DBCFD64A6A0BFEB679ADC69D4E8274B -:107B500063DF58F22F5EDC6123BBE7B1F9ABF6B40B -:107B6000C07A47CDBDE789E7105FE6DFF3BBE79456 -:107B70001E3DBF687E7207E6F18FDCE062C81FF42D -:107B80007933F67D924DEB96AD0CF1F4C7FB9F5F18 -:107B90008EE33DFE58B44585F17FBCC74AFCE5EA5B -:107BA000FB1EDEB383E48D492FF618EDFCC737B713 -:107BB0003E7110DF573DFBE8B9B07C9D93F3360D65 -:107BC00043BF69FB868A9699197DF3CF221BF3A1E7 -:107BD000FFC7F3C227CFBC0EF3FFC677F5F8703BA3 -:107BE00060D42CEEFF69DF50D53213ECD4D122CF14 -:107BF000576056FF4684C7E89F0E52507F0352B02D -:107C0000FA00969E39511615F6F79B807537F1816B -:107C1000399B33F03CB37F9C7FF4233CE7531ABE7F -:107C2000F7A18FE87EAAEEB2A410DCFD2F3AB87D52 -:107C3000A32AC3C83E762BC30AC3F4B9F67BF43833 -:107C40009EFB3DE4E3852531145FD6E32EA2E7CF0A -:107C5000F5C8E7974DAD9C24D3FA8DF1FC1484DF71 -:107C6000048CF7F2B8BDDF6F65941F045B433AB92B -:107C70005B1C4D7927EFAEBE8BE2F6FE1ABB9C91E2 -:107C8000487183A7B05C057CC73E91E2B901CA3751 -:107C90009EC5F3372E2CAE7DD8A6F40DFFBACB9C33 -:107CA0008FA49D8FF9FDCDDAB9D4E2B96418CEE581 -:107CB000A86F6284738975107EE9E722C636D2B94F -:107CC00030873313F33F067394C2FDBC8172A8E37F -:107CD000944872EC3725EB6AEE86F2F94B0318D222 -:107CE000851E57294DE279087424C0B724ADFF6082 -:107CF0004DEF463E867A77A91677E958CA28EEA254 -:107D00008F77B16A80CCC7BB8DF4E6D24AA07F944E -:107D100025313F27FDA27E38CF932875762DA5BC4F -:107D200055C1E2C6F8F960935EEF6795B4DEC1EF26 -:107D300088E4CFB7C46CA1FE83013C6216B6B211D1 -:107D400010A83D0A76305A31AF24055F28617A9633 -:107D500096B73BB8EAA75C3FCA819EC986F9842FD3 -:107D600069FDB5EF8BC807AAEC0AF23DCCD142BE43 -:107D70004DF04B433C6AA5FEF2B7998CF73998CA8F -:107D800094C4C9DC0F86F399D70FE371BD10F433A7 -:107D9000DCAF50CDE7DF3597DF07618799126EB70B -:107DA000B0F0F50C3794353F99B12C25D90C72EA17 -:107DB00037978A0654F6EBC733F6B728DEFEFDBECA -:107DC000156176577A4F7B3D5F4C87734A95FDB4BA -:107DD00010DB77BFED5EF5C02CC06727F366FF0AA6 -:107DE000E0E17B4724796789394EF0084571F874E2 -:107DF000EBB38BB9BE0BDA790DE55D83BCC3F3C37E -:107E00007CED9180EFCC6FCC17D0E7D5E34B1D1AFA -:107E10003F0EA58522FA058F69F4DBB9E173CA2B01 -:107E20002845FD167039B4F163C33D900105338ECA -:107E3000E1BACDF908BA5E8A7296F0D7CFE56C87C1 -:107E40007F02F19D8BCCD54CFABF99DF5819E57FA5 -:107E5000DC2D46BB9BC86F772FE58F54F9EDB21D23 -:107E60009EF3DC467FCC82A9467950A02698E48513 -:107E7000D1DFB5D06B8C138D68594FFCEB22EA4DE6 -:107E8000C4EFF87AAC5A7E9984F74C44B4D7FDF429 -:107E90003CAEF1E737353D330AF92BBC8FC1047393 -:107EA000C047170B517900A2FC704C6D5728EF3179 -:107EB00081A9541EC87C54D6F3219359809E7A9E82 -:107EC000CB3016A2F255A80F8948520A3D87A31D50 -:107ED000321CF53C7777BC87F22773D2285E50C0FE -:107EE000D4F7B05DFE844F49EEE5DFC4C80FCFFC88 -:107EF000F52B5428772CD4CA98098FF926B98C23EE -:107F0000A7BF96D7E7E9E5BA152AD6CFE0EDA5D900 -:107F10004D7BFD4EE25F5AFD265EDF5D6E583103FC -:107F2000CB9285CA715AFBC299AA6D36E62DCD66F1 -:107F30008407C11CD5317B604FB92C478D0E2FAF04 -:107F4000CB559DE1E567B3D5D8F07267B62A879720 -:107F500087E6AAF1BCCCFD4EEF48EA30B477E1E702 -:107F600047C2648E87F8F39AE44BC176EA0181E058 -:107F70006507BE8DF092981A44A60464E3C07C2283 -:107F8000E033B63BA19E8DB751DE9F25C699DA9F9F -:107F90003FD24C5F21891D443FDD02AB2F13F76DAB -:107FA000E67B82FF95BF633E0FD04336EAF9A16AB4 -:107FB000AE0784AAB93F40A713FDBD79BECBE13D12 -:107FC00053C3FCBCE93DE3F6B57E331E9FD0F4BD40 -:107FD000764DDF7B47F34B77EF37648DFBC0D143A2 -:107FE000DF7DF34F2BFB208C7FF6DEEFD9A51297B8 -:107FF0001F32CA8B8E28B638D2FDCABED6E7CC99BE -:1080000055309BECDBA132C51998CEF739BFE9C0DA -:108010005F810F8E19A0DBAF6E07C2218325CDC90A -:108020008479B77918E9AFB5338F1622FFB95802B2 -:10803000120CD675F68E7348714C788ADB13CDC35B -:1080400018ADD7952647A1BE54AFF14D3B8BCB1B46 -:1080500081EB1F6A25796B5E777D6C40C0B8624A00 -:10806000308AFB371259200AC649F1B83D94B7E26D -:1080700017650F964BD8FC4C282F6F11150F8C737A -:10808000ACA58895C3B8E55381CF51663ACFA78890 -:10809000D7F0788C9D51BE45EB4027C5ABEB368FB2 -:1080A0003AB212F966B2C832A0FDD8FAF11EF47BDA -:1080B000D63AE3E329E6A4ADA7D6E97E15EF63F847 -:1080C000650BBF4F22AB0ECC47DF7D87D583FC7C91 -:1080D000D8D31363C530F89FAD3B1F8579EE8FCAA7 -:1080E00016AA7FB43ADB718B13EF130655CA33908F -:1080F000CFA84E987727B4190CE3DD5F71A67924D9 -:10810000EB1B1F623D36039EC6B86D263FA8D16F9C -:108110002999F483E6D95AFC7B329B8CE77CED13DA -:108120009724D473973915F2A367370A949F123AAC -:10813000E24EC5733ABB7514F9CDEB1A45CD6FED20 -:1081400026BF7568184BC57B3665CD02E9C562DD73 -:108150009F6BB0DF55994A328E73D5C4AEE4707F01 -:10816000D9A3F7DC15857CB4AEC4A2F9B9198DA3E7 -:1081700028AA230DF6FF7E9DC0F3272459C0FBCC0F -:10818000AE07C5285C57A7C4FD144DC04FF19E6EC5 -:10819000D38CC27EE950FA1BAC33CC6EA94F4C8F06 -:1081A000C6797BF05725FFFAB9E609141FD9D39891 -:1081B0004DF920E671EEDBC0DAD03EA9DFE0A06722 -:1081C000AFFA546FAA1BFABFBF6D46030829F6FE2B -:1081D00091D549784F6865B39D4545C0E373DBA6EB -:1081E000D07C2BF13E33CEDB5C60433931BB6586FE -:1081F0000DE176DF06F5E9F079EE2CF0BD8C7C2FF1 -:10820000A6F969C213270BFA119EBFB8414D45FD6F -:10821000E25C068B982F796236D7335EBFC14BF78D -:108220004ADE1F16B9DD3BB3B9DF792E120BCA0F38 -:108230002B7B7315C0B90CE8A9065E9D6D9C108B55 -:10824000782BB135C4A47E5352E4477BEE02EAEDAD -:10825000C0CF1BEE59B4A31CDAD5DF3BF22D64CF9F -:10826000D7DAB8DECC7E2D125D805E5886F4F997A1 -:1082700062875C1BC67F517F540DF9825E86FA9D32 -:10828000D428066DC0CFA5C31FFC37DA3B88B76A78 -:10829000181ED3CF64CD2ED0F235922693364E3FA2 -:1082A000F5731605820CE32E2B1C789E663DBD17D8 -:1082B0009EF45A47D8F8A8E7CE646A54D83A802585 -:1082C00004C95FEEE3F376B7D3EAADC060BE0CD36A -:1082D000DFCDF5FA3E46ED30D2ABC3C3CF0BE0DBCA -:1082E0006FBCEEEA80B1DF480FA3731B2DAA473F96 -:1082F0004039DB2A527EF598561EFFBF3894919F75 -:10830000A8AFF174FE8B3FD6411A1C01AE0D8985D2 -:10831000749E7DF5B3054EA869E37AECC3AB938CEC -:10832000EBD2DB8DECDED73A16CDF5C136B4CFEC0F -:1083300001E07BE3F0794245F99DB9FB0EB9BF7DC1 -:108340009BF9D94A5669437D4D51427BEE43BED1DC -:10835000E222F983E83062325D5D24B983FDD430D6 -:10836000BEE77A706FD36858C7B95DDC1FDAB46DA9 -:10837000EF134FA0DCD915E3E671267E4EE3982E6D -:10838000FF78FECF2DACE74719A48D0FED3FD2E467 -:1083900029C350D5A09E78D50707967FF604FCFA2E -:1083A0003EAB9C8A7C4CDA5DE4B819CAE36C81244C -:1083B000E4A7B7ECB2F7AC0BFED95B8C65699FBD47 -:1083C000175E3A747C82F19A0E3DB16339CAA943B3 -:1083D0000E37A688237EF90D74124A2F007AEABC64 -:1083E000E73FE89E7EB47C7E29E5B957DBE97E97BE -:1083F00019BEFB6673BB9F69F736747A8A6A1EC51D -:10840000D0BF7846B39BCE6C013B15CA0DD536055F -:10841000BF6FD0E92E5093228C67ABB69DC67365B3 -:10842000E176627ACF3EF4F13BFDDC0FD900E30B3D -:1084300011FC7D971BEF4F5EB5C203F87FC1EBFDCA -:10844000B607D67F76CB0ADA6FD5C1EACE5FE1F9FF -:108450000EF2DD86F567B60C9F2CA023D2AAD0BD04 -:10846000BFBABA67489E344F857760CF37B759A3F4 -:1084700050FFF0D759287EDBDC96183D02E594D3F7 -:108480001231CE1AF070BED9234FBCB1E1FA50D3ED -:108490004CAE0F094F95DC9F0EF0AA3BC5F3147547 -:1084A000FD43D6F0648C5D26FE2CD7F13CB71E7DD3 -:1084B00088EBD51751AF467D6952B91C2E9FEA63F0 -:1084C000F9F730CA67BAFD781F33C7C9487E5C85A3 -:1084D0009716D06FE16481D969F8BD0C37C3FCDC15 -:1084E00078D07F14C0F8C12D5CDF89763ADD2AE2AE -:1084F000BBCAE9CA01FF213CA3335586F3584DFAA4 -:1085000085CDA43F88A6F24E8F519F50983B16E12F -:10851000ECDADA7F1E87EECF05BD89EE9BF919C034 -:108520001FF1D4E1A7F389054302ED0AA6AA4AE2A6 -:10853000A01EBD1FEFB571FF8A4CF122416D20BF17 -:10854000FDAE09DCBF91CC78DC2B45E5F6FCB8A983 -:108550007E2A83FD407128F673168D7C79BBD7F790 -:108560000CE24D9A1020FB2F7E2C1388ECBFA65EE8 -:10857000CEAAAE2CAEF4C3A3DCFF576B897647FAC4 -:108580009EC2A1B99C1EA38FC1DEA09D789383E2F9 -:1085900079B9E28146C4A79D132DE4D7DEC94EC840 -:1085A000C84F8E7B787ED125AFF7750FC565BD6945 -:1085B00008FF242B5854A0ECDA343FEEB03BD3A391 -:1085C00051D4BF9BFC3CC1C30FB0CB807FBBAB126F -:1085D000E333E1FD23551B09AECA40EE27D3EF9FDD -:1085E00027C8FC9E7F93F7BC1FEFF9FE702EBF07D4 -:1085F000145D609D930EE5ABAA4302D2DD26977B06 -:1086000031E273A3F20C9D475A9662417FD9102B39 -:108610007BD53E9EB127E3783D0A4AACFFC1D241EB -:10862000BBC3F3491ED0F6FD0321B2BEB27C2E9728 -:10863000271D87009003D03E669AFDFD7839D9CF7B -:10864000DD65801BF47FC0CFEDE73F7B1E2FF75B1E -:10865000C92ED2ECF7F672B2CF315E0AF573F2D6BC -:1086600095FBA1FC485AE47913F2397C1F794DDD62 -:108670001103F0F86B0D8F63F57DCEAA6001DE5219 -:108680003B90A5E23AEB5CB6C591BE27B3329FEFB3 -:10869000B723B18DE0C5409EC75E47F7E94DFA6A42 -:1086A00080F4E00B15E3FD536877958CE2FFC04F33 -:1086B000264DA6ABFEF4E39AC4E5A8596FD5F52B79 -:1086C0007DDEFB522B9351FF6C75A9C43F5A416F5D -:1086D000453C2BADE67A6BA9B5EB3DBC3F94729C53 -:1086E000E7BF084F8D6DC2EF1B00BC14C4BBD94E51 -:1086F0009521BF1963F7D23DA35ACC5F977BF457FE -:10870000260E3DE283F7D21091F4C418B98DF457C8 -:108710003693E7E5AAF01FF21B5D9F758EB51AF23E -:1087200077EDA6FC5EC994CF9B99A7E5C369FCC60B -:10873000356962BF7AD3CFC1DEC5751D067E83CF92 -:1087400020D8BDF83C0A76393E5F02BB1CFDDD2F08 -:108750006FC8A4E7AB1BDCF4FE571BA6D2737A6A82 -:1087600048427D9BFCCEE47C644181FC773A3E0527 -:1087700046648FC5FBC7BC7EE69C94FFF05F0FF597 -:10878000895A7BFF17849FDD65A6ACC4F6A549BC5A -:108790007C302F7525FA775E2B56B3F300CF065A3F -:1087A000BC65F85D07F65D3BC527CCFB3996A7CBCA -:1087B000EBC8F63AC34F1618FD35DEBC7EFC353FDC -:1087C00010F83A96CF5DB70FD731A0C0EA457C4D7F -:1087D0004D37C609F6E769F107ED99FAABCA878804 -:1087E0001E04A08789FDD14390213DEC74B11B91FB -:1087F0001E5A5747A6871BF2B95C6D75727B8FCDE9 -:10880000017A1802E512B3FD16A2FC8F0B557B8F7F -:10881000647C23F4A026A13CAD5B0DF214C6A93BF9 -:10882000B2FA5D92A3480FD07A30D203D247183DF6 -:10883000E077585AE3347A900302C681801E82782A -:108840005FB04EBBCF11460F02CAE16E7AA8F86640 -:10885000E9A129CF287FBF2A3DFCE28610E53174CB -:10886000A40592110E3B25EE3FFAAA74326C8E8D50 -:10887000FB8BAE7127217FA995383F9D3DF434F9DC -:10888000E1F21D6E11E58A47E178983B71027DFFA8 -:10889000E7CD3C1BFF5EC102750FE1FFA28FC8DF71 -:1088A0003AD0C2E9EBD86B7BCB112F87D5B717CC69 -:1088B00046BC582F92DEDB6B7FF334FC11F8FA4193 -:1088C000034A0E8FE7FD671EAF57D69FE4FC368E36 -:1088D000C919B09E24BF5CE8C1F8CCF516FABEC732 -:1088E0008082F6389493FA78CC5A998CF8852AA825 -:1088F000637C6F7A819F36699081DE7EDE1FBD5D6D -:108900008EBE676BF4053F9477EBD3EE2D7E55FF5B -:10891000699FFEBC6B22FB07B76872AE55E27918FF -:10892000D05AC67BFA4F797DBFCD23FFAB490F3BB1 -:108930002C07D15FC6D6C6927F37C9CAF5AE24854B -:10894000E78F0C617E82B31E07D3F53645E5793E8D -:10895000B905BEB338EE6EA61CC1EF1938DD6C3117 -:10896000C5B9407FC578F576AF7A8EE6FD9AFA589C -:108970004281FA497FF874FD22B50BC7EFAB7E4602 -:10898000C15F8E7D89718B6A9ECF6CADBE9DEE738B -:108990008960AF5830DEE969A3EF02C9B24D51C812 -:1089A000EE52E763DE62AC069F59E227A47FB7264A -:1089B00081FEEFEEF183EE4CE6714E113DDCA077C7 -:1089C000B61E77FB6F81796CC037FC788F3D1FF442 -:1089D0007428C7A09E8E634DE5FAB87EFF2566AC6D -:1089E000A6A7ABC638DCE5F4F4017334B9399E4D63 -:1089F00044F8A45A94EDD3E0FD8487724FE2F14C21 -:108A00007A7865028AB329BBEB8BF0FB57ABF7BFD3 -:108A1000BF1BFD92D37E6B6748A7AD87B89EA22E81 -:108A200060742FF90AF83CD1C90DF94F97FB472024 -:108A30007F898C77AF6B78D781789768C0BBCC394A -:108A40000323E29D1FF9F13F8077E3E718F12EDF62 -:108A5000847713E6FC6378771DAEFB138CFFC03878 -:108A6000EF2D546F98D30F1EA62E5467CCE9070F35 -:108A7000C3FCEE644F8D645551E1DF15D49F0D2882 -:108A8000E7FA89FBDB379F21B9595B95E340FDADE0 -:108A9000AEE4CC1B1847F84B955D09F713819E6730 -:108AA000D083615CE60703F6683ECF633EB6DE1E08 -:108AB0009C0EFD4A65EECF2F95DD0CF3A845679718 -:108AC000E4037EB52CC9C750BFB627597AFC12F013 -:108AD000EF5AE9843707E0DC097214CE984DBF677E -:108AE0007B22FA9B5E3B3495FC4E3A7D74C4F17157 -:108AF0006FE802F914D67FFADF406E85E1FB0C6067 -:108B0000E0E1E51C47B2A17DAE9C66A89F9D74B5CF -:108B1000A1DE3569DF4CC40BB14C8BEB6BF7CF7426 -:108B2000FD618C5D253C6BD5F4DB3C25CBD01FF57E -:108B30005CE47F5694EB503F37739A613E5DBE5FB5 -:108B40000FFF21DD8A26B96D96F356939CEFACBEDC -:108B5000108FFCBE618EF1BEDA666B289BF808E3CD -:108B6000796A575DFA05E17FA7C2F1BB4EE2F8EEE4 -:108B70009FAA7D67C5443FE36CDC6F56BBC4417E52 -:108B8000FBDA43DF7AD717E64F622CF01ADE671C58 -:108B9000171BAFA03F7E8895DBCFB2CAEDC0B1AE48 -:108BA000EFD3F86C35979F82CCBF37B90BF8027EB4 -:108BB0003F8B1D0E913DCFBE6BA3FB4EE3E6C7116D -:108BC000DEECACB0501ED60F856094301CE9562503 -:108BD00039C392985C47F9876FF3EF1432E6DE9C55 -:108BE0008CA6B44A79826CAAA3EB352D2F15ED948F -:108BF000280F736F9C867C90EF337E223F3FA79BAC -:108C000097E5EB7959B75FE3925833E6990EC1F1D6 -:108C1000A06D6215936BC94F10A4FAA11E76A2969F -:108C2000E6E7FD0797336F2394C54A55F3DFFAB49F -:108C3000787517C591D3057734F2EDE1A297E2C8B4 -:108C4000B14CA638730AABA4678C10E44CE36BF20A -:108C50008F6B010018AF67B136F2E766FFD8C9D055 -:108C6000EFD6EAB2EDA1FC9890427EB94DA7F8BDCF -:108C7000B6DAA577BD3109DA37BEC1F3F3370DF3A4 -:108C8000BF8B748D3889F742456725D50F7E5574A3 -:108C9000CF56F07D33C37BC4CB9C9600860AAEB51D -:108CA00075FD12F3EE58BC8DA13E5207FDCBA0BE60 -:108CB00073A905793143CDB4DBFF88F53778FDAF73 -:108CC000A39EFBDF03E81E3233F90D5B7D5C5F6E14 -:108CD0004DB4119DD7966427E1780D89D174DF6C6E -:108CE000F18D956F20FFA87D5B746F14781FF4A73A -:108CF00013EE613CDFE64D433DD4E6B4517E87D9A7 -:108D0000EF6763DEB726C1BEEAE26E49EA4F1FEAAB -:108D100033CE506209DA62AF3CCE507FEF4D14572C -:108D2000D0D7A9EFB3A1E4BCB45CC1DFFEC1384326 -:108D3000B51039CE10E2DFD3C8C0FA71081FEECFEC -:108D4000FEBA71861DF3BE5E9C41DFF73CEDF77CF9 -:108D5000406C2D5F82FCED746E969EF585C1711F8F -:108D6000AEAF147F53F87BF49F2FD0CA6F1C68FFFF -:108D700004FDE4C77F74F4003EA75F7AB4642DE07D -:108D800045C154EECF7FEB7B710FF2E18C7EF97918 -:108D90006EA3BF1C7F103F691D02BFE71E5E5F60B0 -:108DA0005A57B6D5E85F9FE934B69F9568ACF70C83 -:108DB0003596F5BC15F37E37C6DC4F79679BD63107 -:108DC000FA1E110B3F0FF1F265BBD21B4FC2FDE53E -:108DD000CC9D4674DFF90EA77BEF8B7F71915D9977 -:108DE0006491D10EBDB0B87ED3EB4A783CC0A322CB -:108DF0001E7DF193B16FA25F9BC9BE20E6F12DCF1E -:108E0000E1DF61EAE59FD7FCE3195547DA6686C5DD -:108E10004F9B06F96E9A0BFA4B4649A105F5878CD4 -:108E2000AA97A87ED19249FDE291AFEA98611CFC15 -:108E30009E1DDAB7BEAA97E97D5FFA8E45F1F37CF5 -:108E4000B86ABB42FE5FD3F76E7D98CF867C3E9DAD -:108E5000CB9B5A89CB273815265EC7485909DF971F -:108E600045E17CFDE2547E4F820117427EA58F676B -:108E7000968FBA1C70AA5C7FF4559BF2EF4CE36F9F -:108E8000F7FAEE990B7425381B789E5D8ED6EE307E -:108E9000D74BD91C26A35C867D46CCBBAC9BABD9FB -:108EA000997DE47B31DD0E2C7EF55DE4875FD90E84 -:108EB000EC63DCE9A9A1A591EE23EDCED3F4F1A8F2 -:108EC000D030E4C31D5264BDFDF6E2593BE6F6A383 -:108ED000D7629E6A78DE44AF7D7FCD3CD5DF7AB81D -:108EE000FF4B8F3FEAF9AACC1A188FDFCFCC74FE64 -:108EF000FA668A2BF691A7BAC9E50EA1BFAAB62CCD -:108F00008ABEF7F875FDD56734BFFB037319F78781 -:108F10009BFCF5E6751FD1FCD797BCDE20E24B5FCA -:108F20007E7ABDFDBBC991FD64C9F3F5FBF3DAFDA3 -:108F30001F0FD7FB54C9CD22D9057A7EA2F93DD89F -:108F400041EDB80EBD5C569F417EB65689E32DE5D6 -:108F5000740CE9C96775A2FE477A5433D5C75670B9 -:108F60007D50D7B3642D4E60A627A08FD3441F2514 -:108F70003CEED0A3276AF4B108E803E87228E37452 -:108F80006CD1F230873A784AF7D7D5A37ADB4D1EF9 -:108F900047A4BCD3CBDA4DF5931C643739C7BF8ADD -:108FA0007A556715BFBFD6E1EA7261DE8AFF6D911F -:108FB000BE67DB577FDD7E12E71BEDA76525DCCEA4 -:108FC0005956A2DB4F21C9E742BF30D84FE487F59D -:108FD000D9F307F6B6A3305F14CF09EC4C47FE3740 -:108FE000C11F4C7EA263985700EB3C32E23CF93F34 -:108FF000065771FFC7E02AEEFF4841FF471AFA37CC -:10900000B8BD56EBE6FE0CDD7EABD3F2BC747FC878 -:10901000551A1E8CB157727F88664FD51EEF22FB02 -:10902000C9A97DCF06E3758847B66A21802E4226FE -:109030005ECA453DD83E983E6FCA58B5D10F62CE44 -:1090400043769AFC1DE6BC816BF3353B4AF37F3CCB -:109050002228F74D83799EDD91FB3AA2ED7FEE5AEF -:109060001983FE8F9F06EAE76AFE8F87F0BEC5A1CF -:1090700077B9FFA3EE10F74BFB5081B92E12FEF526 -:109080008AFB90FF6365BE9FFC1FBA3F6999533B03 -:109090007727DF2FC297BEE7E9E165F4432804CFC5 -:1090A0004F7E8971C2BA6B782EB89D6511FCF4FBB6 -:1090B000AD3AFC772619E1ADFB9FC6D803AFE1FAC4 -:1090C0003B92AD6C23CA51F1138AD7889A1FFA9B41 -:1090D000F22BDD9C6FF42B8D7F68C276FC0EEFC403 -:1090E000878B4EE273F2EE750937C373EAFEED45E6 -:1090F000F864AF7238FE751EE75B98311DCEB796E7 -:10910000E729C44F7BE0CAFD4A3A3EF6F8E378BC53 -:10911000BBB482913FAE54ADA43B8C98E78DF8A3CD -:10912000C3A7D5849FB5C3783965666510EDDE0C9D -:1091300080A72AF7C6D7D6E36D6B89EFADB6297E37 -:1091400082DFA51AF4D3D9357BDF8C8F197EE3FD3E -:10915000E1CBE1638D096ECFEC98701FC2EBB95D76 -:1091600045AFE3F3F9C0BA1884D7C17DDBE7F60158 -:10917000B764431E3FC26D526F7C3C5EE06BCE878E -:10918000F7D3DD012BF1DB0A8CD961DEDBDA286352 -:109190005C45E7933F8AFA5A7C72F379BAD7585BF9 -:1091A0007D81FC4A7555FCBB101D2EB571E4C42BA6 -:1091B000E793D7CEE3F7D8753E99A2F99952E41018 -:1091C000D1E332A047CCFF5C56CDE30A78CC310026 -:1091D0000F31890563C87FE0207ADA89F9C3D7F6B1 -:1091E000E04F27B4B30F60BDE49399BF825C7C1E4F -:1091F000E1D5599D407ED93DDAF74555AB9BECC78B -:10920000D9C5DE8358AFC7A5B67BD543C487BFBEDB -:10921000BFF0487E98BFB0238E75FBD76A601F39B8 -:1092200055590CE34BA2DC2529E85FABDE2DA09C51 -:10923000583A87D349CAD04A9217BDFD6D5D396847 -:109240002F74E04DF12CC283B771DD1D557B090FE2 -:10925000AE5DCDFD241D55171222E3C1DF5C5FCF4B -:10926000CF389EF2837579B9B31B0F02AF4DF90A5F -:10927000F272FE3CA3BC4CD1E83EA5FAF443E89759 -:1092800016353C109DDC2F8DFC13F160701FFE47DE -:109290001D0FEA1056801775B239AEC8EFE55EA80B -:1092A000DE4B7FBEA5AFF55D3E2F548BAF633C9187 -:1092B000C7D7DF453CB556F17862C7FAD964275E57 -:1092C000A81664F437EFA9BE5DC0F39B5D1210428F -:1092D000CEF0797AE5833AE60DEC891FEAF1C2E334 -:1092E00005DE687C3F1D702A291EFD7F9A1F7D6860 -:1092F00064FF1FE077FC3CD43F0FCB244F743F3A10 -:109300009374FC561370BC71B6AE6132E1B72F098D -:10931000DB771EFA2FCA0BE8F113F23CB37FD8CFEC -:10932000556AF473ED5C6ADB43DFD763A15C8A8F17 -:10933000601C01F9F6363BE533960B0AE5FFFDB5F7 -:10934000C03796F6C1BC9467EA2B76C8E40F734D1C -:109350004E42FC286D10496EF7659FF4A6B3D3C446 -:109360005F5200AF347E437044391D158774271057 -:109370007F1181BFC4A01C44BA1B1BCE5F024B8867 -:10938000BF328B3B36F58AF84C0EC2B91F3E933B79 -:10939000CFC86766CDFB07E212C17CC6ED3A6DDF30 -:1093A000A87FD2BE357AEADE77099733A287EFBB72 -:1093B0005B2FD5F88C998ECCFBFA7F90AED6F54119 -:1093C000577722BCBF025DDD7319BABA17EBC3E849 -:1093D000AA96CEFF5F8FAE5AAF84AEC6CE63C6FCF0 -:1093E00063ED3BCA63BE63E1F98BFF97F38F13E72D -:1093F00072FBDC9C7F8CF92258CE87B3A1F3D1CAD3 -:10940000F3273205EFA7D977BFB465B4C2C70BF70E -:109410007B3293BF9399FC9B66FD2E823FD4E0FF85 -:109420003CFEC4EF8E8F865F7FFCE47F915EFBC6BF -:109430002C81E28FF3477D7118F5FD82CD6BB53C31 -:10944000F7FEFD9FFF6C7F27FE84FB57CDFBDA14F0 -:1094500073BF068FAFE6EF64EE1AFA7E7867257366 -:1094600013DC2FE3FFEC94471AF285BD2F963FB82B -:1094700010FD9FC7F977F8CC7E4F3D0FB8B5643922 -:10948000E9F96754875B8CE0F75C9EA0DC46FEDC64 -:10949000DE7ECFBF221DFCA37ECF657315C243B312 -:1094A000FFB318D8D5FC7EE2BE1D719502F2BB9CBD -:1094B0001237E5DBB14BEBE8EF39882521D2034BBE -:1094C000ABB81E38A0C0E7C2715286B27107D13E58 -:1094D000A912DC16A5375F063D33767E785EC93764 -:1094E000EC2FF867F9FB5E99FBD5EEA5BF82F09EE5 -:1094F000D4CFFD7425F430E6AD3D52E3A2EF563DE6 -:10950000A2E9D11D929A84DF397F2BEE030BF2EF93 -:10951000408B85E1BD31B35EDCF7FEB8FCEACBCF12 -:1095200024A17D34B6C73EAAEDF623B91DE17EA481 -:10953000FA0D9E43E722C049D78BB7CD37DA47A54E -:1095400025DC9E2D2D51C98F549AE861387E8A936F -:10955000B5A15C1493BA24D4539655F8C8BE37C746 -:10956000E1CD78628ECB9BE3F0E638FDFFAF71F979 -:10957000F5F38DDF651CA7E5A1206FC7EFE998E340 -:10958000F09BADDC4ED9A9C23BDCCC578CCB5F75D0 -:10959000E9011EE757B9BF3499713D2D259FFB4B5B -:1095A000CD7AC723526033DADD8FD458F4EF5618E2 -:1095B000E2FA635D3C3F7ADCFC05FB293F47D70BB1 -:1095C0002B402F14482FA4EF1C9556540A1CAFAA09 -:1095D0008EE03DD36532C7ABF9F339DD5887BA4920 -:1095E0000F16AB6F67FCDE959FDE97A6F2FB60D18E -:1095F0008867D054CCE4715FF984E8C6FB095BB19D -:10960000E934BC0FCAB81F679A85FEBE438B5099D8 -:109610008CFCF80141A627E84A748FF0C93875D050 -:1096200012F2DF58C86F7F2CB72109D7D758B32D56 -:1096300009F336DB34BFF8B6DC0FE8FB0EE2582640 -:10964000A39E02CF887FCFF39E0582F67781DA92C0 -:10965000E8FB02AC99F44931D3C6F8DFCF71075764 -:10966000201E9D73929EF08010E0F76E5C0EBADFB4 -:10967000D67CB52DB91CD6D3E4B291165177F5AC92 -:109680001369F0BE69A01C8B7180BAB474D94F7194 -:10969000EA865791BE9BD2D219E6CF37964CA67B6D -:1096A000748D9780B140CFDAD123DF9A04EF370B66 -:1096B00021FA0E8F7F9A85E2F02D57CF4A0EBFE731 -:1096C00028CA3653DC93EB95A262A17B73A216CF16 -:1096D000167BC5B38DF1E9AB1670BD4861CD8BE942 -:1096E0005EA5D326E37E4BAF1E4F79AF179D36CADA -:1096F000072A9518FF8EC6D58CCE2502BF337C571E -:109700004532AD6F3306A629FFF98155A887E31DC1 -:10971000409E9F5FC3CBDDF5DF5B85F8431FDB8198 -:10972000F2D937EF5A85F9F80AE37FF7A33693E7C2 -:109730004F96BA0A89FF964AA188DFCDBDDC7A141C -:109740001650B5F1D8FFE6789BAFB62DC67B44978F -:109750001BAFE75C02C4BFBFEAB87A3BF3B8E67E52 -:10976000FF5BEDFBDAA76581FEBD43467910A41AC5 -:109770006AF7C3503FB66AFCB0367B7220A8603EE1 -:10978000AF9FD3459C2562BE6CDFF411363E4FCEB1 -:10979000257E4BE3E3B75CAAF2826913F9FBC2A40E -:1097A0001EBAE9CEBFD0C683AA97514E6CD2F90536 -:1097B000560DEA19F7372513280F16EC0B25C11D96 -:1097C00081FEB43C0D6A9F46F7647F8B79E26C346E -:1097D000233EA2B7B76AF39AF336B66BF37ED5BCD5 -:1097E0008D73B88789246BC80EACFB6D33E52F31C0 -:1097F000FCB813FA67B364BA5F769F10A07B91FE42 -:10980000951CBEFA3944B1EE1FB27BF47C9848F93E -:109810003268BF25E9ADC3CF219DCE7204EAED9B2E -:10982000478DA3BF136965CD8F3F01CF1D0736FE5E -:1098300011F33EA2478CBB7FEA44BCC76E71E3F2D2 -:109840009CFFB6E36FA80A378C5DD98CC3ACD822D5 -:10985000A8E8D7B7CBCE3D681F318740768375FB2C -:1098600060E20B49E5C6736F15D45FE377F4FC5BE8 -:1098700005E2A3516EA35D611B6A6CBF4EA33BB3AF -:109880007DF2801039EEFDCC022E67AC686F84E962 -:109890000DDB2485BE0BBB6DB388914CB66DBD9DB1 -:1098A000F8D9CB6F15AEC2EF76DF592F11DC5B6FA5 -:1098B000B0D1DF8B6A75C98B16635993677A9CF9AF -:1098C000816B4606C2FFAED0D39A9C6DBEC146F2F4 -:1098D0008059BB92D02F6BBE6FDDCBBE32E1DDE590 -:1098E000F02C7741BC86DF01922BDD76FD280BBF83 -:1098F000573CCAF22F71AF786E373D7CB3F78AE7D9 -:10990000A2613EB027DFCFDA2BBF2795FC7BF5B3F2 -:109910006DF4FDB5AF6AEF6E5BBF8AE485FF76E656 -:10992000CE70F7CE0BF3BE3882F0476C14C90F2708 -:109930009AECD9FDF3A56EFEE308E3937A5ED07648 -:10994000ED9EEE766F03E5CFD479F83DDDA8E655C0 -:1099500064276F033D0CF3AA74BBF8CCD4F4C9029E -:10996000E5FDA87EFC4EC6996C2D2F48367E4789B2 -:1099700069F97DFA7CDBA6A6D37C756887F7830737 -:10998000568F766FD7345E37BF467B3BECEF6982EC -:10999000BD7D6E01C0FF7EA71B9D7050FF12D5B329 -:1099A00089F15774AFB2137F85761945EAC7384EEF -:1099B0005EC6243FDA7967D80086F038E772CF4276 -:1099C000B5BB43723BC2FFFE416DB3A47D8F02E67F -:1099D0001D4BF96D4B0B11EF4748C43FC4C42C7AA3 -:1099E0005FEEF25A2DB02EC19B6E884FE6B116EB9A -:1099F0005AB2AB023329FE5DCE648CB794B99A2972 -:109A0000CE928B0B8489672B33C8CEF31CE6DF59CB -:109A10009C1EF7FD449443FF0700378FAE00800083 -:109A2000000000001F8B080000000000000BAD3B91 -:109A30006B705BD599DFD5BDBA926C49BEB2652318 -:109A40001313AEED189CC43137217165089BEB47A9 -:109A5000880D29556CC749769C548140C3B4D36A9C -:109A60005BBA4D76682DC772E2386014D3D661CBED -:109A7000B622C0B6BB74C0A52FC8D08E1CB29467E6 -:109A8000715BDAC2B643454ABDA5D31FEE23E0EEB3 -:109A90006427FB7DDFB93796642571D28881C3B90D -:109AA000E79CEF9CF3BD1FC78DC78E54451B00205C -:109AB0006EFEB4BE092000E2B7DC3515695B0D30DF -:109AC000F89A6CECE32FDA643408A084641831004F -:109AD000A4A7D686325EEC7BA77F0D7E809B6600B6 -:109AE000DADD62ED19FC77DDAC1BDAEBE7FA2D0865 -:109AF00039BBDFE6AECC99BF5EABCE1997C134D28D -:109B000012C086D0D29C79BE35AB353A6FA7BE3233 -:109B1000E7FBADF5CD39EBA15D3999C1FE5AFCE704 -:109B20004C0DC1137D1EAF06F036603F6BBD025970 -:109B30007D1CAF8BF882D3C5D8F9107CE88C0CB0B3 -:109B4000118CAD10A45187F138E2A5E2983B53EC9B -:109B5000C0AE69EAC10AC4070DE9007D115CBC060C -:109B6000FBDE6907E0BC8711865C09D0A8651C9FF5 -:109B7000263C6B13127F0798184164871493E741C2 -:109B800008B404CE5B047149C3BE2F0449EA5F05E3 -:109B9000499E8FBFE483CD004BDC62BDBF0B8C07B9 -:109BA00070BCB8212E49D82FED004346785E634A39 -:109BB000A2736AB85E5E09500969EE5775C0D42079 -:109BC000C337F7D1FACA3DA00D5512D8388FA7FA7E -:109BD000204EE779040C70C9848F08402D800A312B -:109BE0006EAF06BD1491088F82B18AFA759021A4D8 -:109BF00022555312F5AF80098DFA006988ACC02652 -:109C0000A304A6DD3C05CEACC37FE957A0A59DA665 -:109C10006DBAE0E4AFDC667647107FBDDBD69444D6 -:109C2000BDE75EA7EC797EA2FDFAB9FE6804915FFC -:109C30004EDF37003450FB028F3F1589EC88E0F788 -:109C40004684EF5E75F1F86F54053E131218719C4F -:109C50009F78F696D04E1C8F3FEB36EA80F08BF85B -:109C600024BE08BB675E6A16EB891E41A407E1BBF0 -:109C7000B40124C2C1554407FCAE221D0E321D930F -:109C80000C77710C8C016B5FEA57221D882E29D04E -:109C90008A08AF72ECE2E8C03F8473C533EE4746F2 -:109CA00024C22ED2A5F6B2D0653FE1F162E9924F0F -:109CB0000FB8B70CA0F97CFBC6998E5F91D21EA994 -:109CC00096C882F4C1FB48481FC26708043D54008F -:109CD00083F05408FFD4F7AC067D1FF7C57CA2675C -:109CE000BC798EFF4B90FF455FC85700E920FA8290 -:109CF0004E419217EC872213BCBE741744EEAF247A -:109D00007A988C3C2744B975C18C446D8D6430BD04 -:109D10006AE58883FAC5525A20192949FAC00F1AF0 -:109D2000D3E74A88711B74CE4C9EC17D125E472AD0 -:109D30005E4DEDD32DB4CFE046D43028B70DBEB183 -:109D400016E6CBBB41AB43BE5BAC9AEE6AE29765CD -:109D50008A11D7B3F1B58FE1836E1E29A671870FE3 -:109D60004656CFED9B701AA124D2EB75DFF4F12893 -:109D70007E2FAA94C165CCE1F9A453DC8F60CA8B15 -:109D8000481E847C84C27896C07CFD165204DF7A1B -:109D90007723FE101F3B6800F1240D7F9FBF3FDC3F -:109DA00026F4DD8391E8EB24C7A49F187F2668A4DE -:109DB0009F3403586F3AF4F8EF64FC7E6AD8A51319 -:109DC0009F4272DC74E33E3BAD7D760EBBDE91FCC0 -:109DD00059F74CB8206DEBE71A5A1F29617E3624DB -:109DE00070372D7CDDA5F23FEC292766BB20DFB65E -:109DF0003CB5B624D370EE792AC94759F63A4127C3 -:109E00003588FCE4A5F11778FC42709C7B2673E44E -:109E1000CC86E30C45188E73CF09216F64B7909EF2 -:109E200077A1DD1A417C7FD4D454C19733FF45F626 -:109E3000FCF698DF207BCE28C2797724A5D408F2DF -:109E4000E39D1053894F25581227FAED884BC60819 -:109E50004EA939B8CBCFFE02B46B841F297DA37CF9 -:109E600066F945E0D1C2D38EF47B4EDD4778F5C16B -:109E70006FEDF19AB9F1BFF4D5BEBE4627A5EDADA1 -:109E800027FA165BF445B51D7F05CFE93C5D02233B -:109E90001A727FF1175E5B87E71BFA996CC8D5349D -:109EA0004F0513E11581B0E3C524A7B5C42F13E90D -:109EB0008F13BFED29D1E8BEF63CB0E6C5216AD2CA -:109EC0003D8B510F105C47F17DCC9FC57E55979916 -:109ED000F951E364DFC38D7C57C1A8E65FB99A4EA0 -:109EE000937C95B7BA8D815CF8D2195A8F30A1C294 -:109EF000BA87347FFF15D477F350CB196B3FD39DCE -:109F0000B55F5EDF19CAEA83188F67CF3754486799 -:109F1000E1F5ACBC5872669FDBEB5573E5256F9D90 -:109F20004D8F06A7E08F4008520378DEE1E1D2961C -:109F300062EC8F064077E1D0FE1B2A2440B96ED533 -:109F4000C43C7F15A45C12EDA38FD4B3DFE865FE9B -:109F5000F1FFDE4C7F9CF831ECD274C453E08FC625 -:109F60009489FD3B436EC3C4F1419A4FF6B50AFD97 -:109F70002C9DB7FF05F9A57758E7BD82708372F86D -:109F8000B14DC2CF927DABF7BF82F00F5C29834CFD -:109F90007BCB1B0DE2CF3B1480B252ECDFE764BFFA -:109FA0000FFD3BBE8F5A95EBF7DD79C439E717C239 -:109FB0007C3FF0AE4DB97E606C13F0BE749EB2551E -:109FC0007F3F7CE80BB2FE5CA14C39B40276D5C66B -:109FD000BFF49497F1FA8372C42BAD8388F929EC0E -:109FE000BB108FC4AFA8A8FD6B104F84439213DF42 -:109FF0009AEF7C9AE6BB4E21FFD27CD9DBFE29DCAE -:10A00000CAB908F1C4FADFC9E730F11F3A77BE3F99 -:10A01000ECCA3BA733CF7F962D3A8C107E50FEA121 -:10A02000099A083FE89FB37F00DE60413BFF5C3F39 -:10A030006A0EE4A51FF6BBB94DF76BDC1EEF0F717E -:10A040007BA25F877674AC5EE8AFE7F6C57E83BF20 -:10A05000BFDC1FE6D6C6C7B9F48DAFDCC1FEC2E1D6 -:10A060007B1D291226A5417BE95AC4C3956FC8AC54 -:10A070003EFCA07B14D4077EC48182F3AEEE505226 -:10A0800026DDC58A7FAEB0F86CB96B66D245FC5D43 -:10A0900009C63E5A08B1813B56CFC53F37CD38E699 -:10A0A000E40428DE299AB33340F14E594EBFCDBDAA -:10A0B0002867FE7AAD3667DCA6EFD79A85DC6C0898 -:10A0C0002DCF997FB8BD35FD313CAFBFD9A5119FCC -:10A0D00077EAD7E78CDF5A7F630E3C5B0E4AFB942E -:10A0E0001CFEF3E7D155DD7DFE38C8A6F38F6C3A30 -:10A0F0005B72702EFAE6F3AD8DD7D2B37815716529 -:10A1000082E24A9DEEDD20ED0C129E6DBFC4848874 -:10A110008FF480D85709637CD978F9E34B3FC59712 -:10A12000D585E2CB7735E2DF0BC6971DB9F1653EE9 -:10A130005E2F145FFE691E3E4B1784CF1D8B63AFED -:10A14000ADA178EF5599FD40B923C6F6AF6C4A36FC -:10A150003620DC72CB1FF391CCE3BC1D6B54F62F81 -:10A160000F43264476FF0109B18AFC5FD660549202 -:10A17000BE793260566CA338BFD3611CC525CFB7FA -:10A180007C39447EC7C1814742689420D8E5607D10 -:10A19000976C99DE4E72A5E8E8C749DC9AA902FEE1 -:10A1A000893DFFB3434E8E431ED8AEA6249CFF804C -:10A1B0004FEBDD4A7D6B1F4408DBDBF135D7A4C8CC -:10A1C000FF2BEFD205BF403C44F47F707B53251B2F -:10A1D0002905FB2B68BAC1767CC46798248789DF80 -:10A1E00079218E9FEE9734BF44FEEB7687F638DEFA -:10A1F00073BC63D55BBBB07FD0AB1A24F0894053EE -:10A2000025F197BC03DD1EEC8F758CBDC8725CE731 -:10A21000E07E62FB35AF93FB3C5EAE75D6509CB7DB -:10A22000BE86300DF233A7FB29AF91084C8768FD3D -:10A23000E00D62FDB9E8236B59F61C387FC1E79544 -:10A240009738D22AC2919F9BFE3F822767DB71D647 -:10A25000E3B97EC54840A52001CCAE2BFF23BE84C8 -:10A2600054B969121DC751E6094F3BB67795503C6A -:10A27000B5C399292F642F8650BFA6AFCDF237837F -:10A28000B97E423E7CFE35117EF1E7105DBDC20A0B -:10A290005DF097B8EDE6549AF006C98E1AB2CB5E1F -:10A2A000B4CB709EF8CF9B8B071B3EC3C3FFC87B0C -:10A2B0003CA6270B0F78AD34F93BBD5D12F3CD966C -:10A2C000B37C001C77D8E7523A1CBCCED60FC8C767 -:10A2D0005B27883F2CBC87D064901CDAE7885AF053 -:10A2E00076CEC103AD22EB1C6B550B9EC171F1758F -:10A2F000AA902BF885CC7EC73C3A59FE1BAFAF9E87 -:10A300001B57ACF35F7B44CDD1BF9FA1FD71DF5FD5 -:10A31000F6759F375E5E9ACA5D77B80BF8DCCB6442 -:10A32000F3F834C5B5D73A528F23A8E5D73A589EEB -:10A330004FA15F4576ED5CF06CFAB388553077A19C -:10A34000D38EFE59B08BF9FC5CEBD4D49459DD4824 -:10A35000FB426C02F96B6928F75CF6BCC367EFF54A -:10A360001928A2F3A0434EF6C8954A9BA4A75D08FE -:10A3700047C2B6FE917BB4F3DDDB0559F0119FEFC8 -:10A380004A425FC503C0F74DBC9562F98167667E9E -:10A390004BF29D585AA18FB0BC40684913F923E293 -:10A3A0005ECE3C3A8D78049CB195C24F1DB3FAF154 -:10A3B00015022E64CB29AEF7587995AF77D5F2BD4B -:10A3C00054D2334464C55C4C7CE155BE15D7901F14 -:10A3D0008ABC872180AD2BB8334EEDBAC5FA681818 -:10A3E000CF35B6D4C1766CCC177D6488F4D0526F6B -:10A3F00041F9F81EE945843F4C7CCBF113980E924D -:10A400003BC91612883A905EE3CCF9002F750544DB -:10A410003E4B4B866F473C1EB7F802EFC3EBF3E1B0 -:10A420009F980FFF31E2D784059CE0EC44382F5B06 -:10A43000720164502AACB80FF773EBC930F90BAF57 -:10A440007469425E949506DD7F2C5078BF57ACFD51 -:10A450004C474CA27957F489F5E016EB1E9066B68E -:10A460009E14F46479A2FD69BCD8C8D50FF9703D7B -:10A47000F5B9FA4AADCA9DFF96C57FF9F1D0FD52F4 -:10A48000E173FEAF75DF758B81ED11F1C5BE027C06 -:10A49000912FEF2AE53F11EE7B4407C697D03B5E34 -:10A4A00065AA95E21E6F0318ECA328937CDF7DC597 -:10A4B000B7719C3C74ABC873A88AD0DB555B110C98 -:10A4C000DAE3C80FDAE3D497EF01CD15988F878BC5 -:10A4D0008DF7C8DEC4B3D69F26FE2817F78867DD40 -:10A4E00023E9D46FA37D930765203F20B9D7B5B585 -:10A4F00090DD862EE7593DE9B6F52ED20D8C6A70B7 -:10A50000E0FA236FC89C173812DECF717122A2EADD -:10A510005235E5291E86BD38FE17D3C17EEB9E67F6 -:10A52000EEFDCDCBB8EC647B4D93E46039823B719A -:10A53000FE498C8BC96F26F9CBC9C72062DD4D73EC -:10A54000FB25DB6B78BF04EE279D47CF29118C5B81 -:10A550001BE7C33B6B8FF3F223231551BD1BEF7732 -:10A56000D86B703E52B6F3233DC105E5757448A61D -:10A57000F7905EE903C683AF730CF6523E2124E2E6 -:10A580008CE36B5C82BFF64A567C06ED60EB29FCDF -:10A590006DECD31F2A23FBF2A60BEA70BCF589579A -:10A5A00015EA8F553A9A287EBE4ECD1CBA8EC69BB0 -:10A5B0009CAC3F5A9092E91CFE48BB1C213E8F6A1E -:10A5C000B5B268D312B56DEEE21C7DBD5ECB8D3F9A -:10A5D00046678FCB25C49F1A1812E279B4C5304B59 -:10A5E00048F7189941FA3EBA5E374674F28773E32A -:10A5F00094D14E55E8D36A6177C626F587C8BF3A2D -:10A60000B0C7C3FEE7FD550E71EF2590227EE8D45A -:10A6100073E39AB1899A834B48CE924ECE977F735B -:10A6200042CCDF35B0324571A966F9ABBB2A5BD9A4 -:10A630000F852131EFD6FAE579F79FD2882F927BEB -:10A640009D40F83F5075FB30E543DF4938AF277137 -:10A65000F96EB7CE726AD36DE7D09D5C271A52614E -:10A660001B9D7F74BBCAFC3F5AFECE913B484F975F -:10A6700017319EC7B7AB95D12C7978AFDBC570C6C3 -:10A68000B70BFFA2DC01D18902E3EF750BBDF2E14C -:10A69000BB81EF43F90E1D3FE94A2CED227C5401AA -:10A6A000FC2B5D27F4EE97F8FE1D0EA8C3238E0544 -:10A6B000FBD87FCBE7B30FBAEB72CEEF0A3B72F059 -:10A6C000E87445629CE7BE1574D257ED1DD8A7F813 -:10A6D000BE4F05E23757E81EBE6729F63DD87777AB -:10A6E00024E30AF6DD4BA2D793DFFAFCDE2DC32D5F -:10A6F00041B25F0E8DF8CDD57757A49BE6AF768239 -:10A7000007C78740974274CEB804A4AF7588769087 -:10A71000BF3E16726894B7D998D8BC9BF6DF182C48 -:10A7200002A2F38E4E07EF77CA543969554E8E0652 -:10A73000E5BF2ABC6C77DF76C61EDA82F3DF467A85 -:10A74000C561EE5E8F76D7F03D3D7A6EFCEC8624D7 -:10A75000DBE1B5E6541FEDB336AC5245038E374FFF -:10A760001F217F7D7C8DCB70E1B9C69B25C6F7FB91 -:10A770006B9C293C2AFC509D9269DF1FBE8FBC5107 -:10A780005D487ECF2F37F9F347C35D6EE287FD301A -:10A79000D543F889CF8A3C54FEBC253D82FEFB118F -:10A7A0002F84E7389EB78EE2A219942B841E988DD1 -:10A7B0007C837244DBBA15D61F9FAD74C4A92E7476 -:10A7C000A053653939E08B0E57531FF99DE3A16003 -:10A7D00094F979AC32C87268EF33D6DC5B4FFCF287 -:10A7E000DA1A0FFBED7D3FFBD5DDE4B7B7CA7FFC7E -:10A7F000F653143F55A94CCF03CE48FA65E2EB4E11 -:10A80000E12F9EB8EA9F59EE86FA6E07C21BC46319 -:10A810006F52DD6A687533C3B7F30D6357897CD215 -:10A8200050F0D3F15DD84F87457EC12C3F2A01EB14 -:10A830006791576AB1F4D87257ECA53A5A77B722A4 -:10A84000EAC2725582F4816B91C8BF998A3327EEB0 -:10A85000BD6926370EBE322F0ECECF33817B6A49BB -:10A8600037DAD39F775B79372BAF445760395EED8A -:10A87000E278713C2CE2A0A43356A935CC97E31FB3 -:10A880005B7EF054BF1B3900E0A7FD1AF7FDE69F81 -:10A8900006CA10D41BFD21FEFE91B58F48D9EB46A8 -:10A8A000576F76EBAC373221829BAF2FF2F9E08EF7 -:10A8B000EE22E6038CD380E83B3A038C5F5FF3AA79 -:10A8C00034F1E9A9BF02C7A1FFD03EE5859AF9EBB3 -:10A8D000D3744E17E5BFC4394FD0395D94FF12E7EA -:10A8E0007BB15FE7F6E5FE7A6E57F680C8F3DBFAD8 -:10A8F000E06AD40788B7F62AD127F9273B5C1ABC4F -:10A900003D42FCE50A291AC9B7BB2A9996B2F4C19F -:10A91000B82FF616D9E503E55EE6BFFC73057A1C91 -:10A92000D6BD62DB08EE28C225BC3FBFF77FBE5410 -:10A930004BFBBC21335F95F6F5EE66BD837AC1C350 -:10A94000FE86D087C9722FE71DC6F7D64921ECEFE6 -:10A9500018108EEE05E51EF749E1BAE3A8AFA97F0E -:10A9600000E59CEE73A0F99D8FD33EEFFFAD882AE2 -:10A970007C48EF5FB0DCBF860148D965947B5BCE35 -:10A98000BEDFFDA4157F47B63C23EECF7A70DC37DF -:10A9900095A4FB1FF8B90C85F076A9740573617E48 -:10A9A000484A99993C132C50373445DD7070E23B8E -:10A9B000DC8F6F04A8C3FE579DA69BF8E0AB038E07 -:10A9C000F3D60DBF3A70FEBA61EA8B0E706973E779 -:10A9D000580419CEB352084F75C0211AC2B6A92720 -:10A9E0007A5B0FFBCBA2AEA83753CE81FA5A11F98E -:10A9F000CF4F45CC8FF4909F1914F9AE9032912629 -:10AA0000BB1EA27AB94EEF17E25CF7D4280C5B3973 -:10AA1000FFFE83CE4C2BDF0FA750BD32BF3E2979FE -:10AA2000BF27EAFBB5A20E69D7271BD5CCD143843B -:10AA3000A76D6EC6C3E0B337BC49F52FBB8E1FB2FE -:10AA4000EAC0DA6ED006C43D3EC6E77C4ED443E190 -:10AA500006BCC74ADA2453B36905D7373F41E31729 -:10AA60003AFF42EB861B2DFD86CC9D2279FE8D851B -:10AA70004F7BDE80258FD7A9226F0D7E95F57CEB6D -:10AA8000135E90C95FF6A947494E7642663DC9D329 -:10AA90006040F86D89C34EF6DBF6F5E8BCBE5C3568 -:10AAA000F9FD42F9BF788C01049398D4FC9447AA2D -:10AAB000EB36F7F5F039923D5D748E6199F5DDDB8B -:10AAC00075EBE3C41F9D5209CBA3A2998BB3F5E5A7 -:10AAD000A33D3539F9F84EF8A242EF5CD62D9EE938 -:10AAE000E2FD7D0EA0782BE1315ED409DF3F5018E6 -:10AAF0006E27A4DAF9BEBB346918EF39E83DC9F412 -:10AB00005957E75A49FAE951CBBE267C85E3BA7F0B -:10AB1000EB11F1E7FA4DD187E9DCB7C04C1BE937FF -:10AB2000146D23CEEF5A445EE751D29722AEB9D7C7 -:10AB3000D13497D77AC9197D94D699DF14FE842B26 -:10AB400024FC7A279869C2D7AB9BCCC7888F371271 -:10AB50009FAF6645058FAF9C7F8E27AC73F4F69848 -:10AB6000FF49F08E59FAB95133B9EEDA080E633065 -:10AB7000985557D717565797B4EF897AFA8D828F21 -:10AB8000E1B9B8E0C356D0489E90FF8ED1F9ECF7FA -:10AB9000258DC7765773DDE512EBDBEF6F328F1330 -:10ABA000BC3F442227E81E6FEFDD020C6F81EF35BA -:10ABB000D62DCE8422642F3DC26F7EB2C5D81AC96D -:10ABC000CAFF9CB2F8F79445D7E5C84E53942F506E -:10ABD0000CB6E3D740D84DFA211F7EA21F26A8EE5F -:10ABE00073AEFD9D074FBA294F3C186E75D37BB4E9 -:10ABF00084B7B584FAA3556688F61FEAEF78F6DDC8 -:10AC00003AE223C1F7F166918FD88FFA39EE9A8331 -:10AC1000F3871E99CFD5168634E5D3FD5EE117F98B -:10AC2000315ED4918FFCC130DB73FC3E41A9833F80 -:10AC3000933C51BC1D32C0A478321C05920BBF3628 -:10AC4000B79E4C5E5B380374AE73C191AB70BD9719 -:10AC5000D6C718DFE59B353E872BE4988BE361E18F -:10AC6000F8DA4FF8AA3B4FDE8DF0D5706E7C9DC5AB -:10AC7000BB2577F978F26D96F9DECF07A6F95E70FD -:10AC8000BA8DF3227E547854CF2FDB2CF48CEC3524 -:10AC900021EAA37A5994EF970864C06898C32FFA01 -:10ACA0008A8C5F59CBF03A7FD880E80AC2478CF192 -:10ACB000997FFFC663DF6827BCBDB453E8D5758AAA -:10ACC000A53F627817E4CF7FB2F41B5876A9D3234F -:10ACD000ECCE46F88957E4B5059F36A23BEE2E9D93 -:10ACE000AF5FEDF6492BAF9CFFFDE79B3D220FA028 -:10ACF0004FB07E1FEC10F07D3EE1871E1D5EC5FE4D -:10AD0000C3CD957545D9FAF172D709F3EB8217AA2D -:10AD100003CEF18DC974FF8B7632BE493F377F1C5D -:10AD2000B2E46DA8DF5D50EE0E2D8E840C92AB6602 -:10AD3000330E48B7FD814C88F86768F23DF693956D -:10AD4000576583FC4D458900CDBBB93CC3F4DF108A -:10AD50003681EA4A87FACD6F65C3FDECA668F766CF -:10AD60007A27A44D9804C70BE938D9A35BCACC58FD -:10AD7000A4001D3EBA59E4FF5EDD14D9B699F40E65 -:10AD8000E9CE55E86B45CC7FA4FE42F5D57C79EA47 -:10AD90007093BDB87479EA72D3FD46AB22FC4E6B5A -:10ADA000F42732795873FEA5254FA3CDD3AC276C79 -:10ADB000B9FADCE63CBD13B4F44ED064B9F8FC66D5 -:10ADC000DDCA0347583E9C244FD97A2668EB199375 -:10ADD000E55109DAF264C91FC9137EBFCE39D346E3 -:10ADE0007ECA1088778CF9F235BE299A203A5C57D2 -:10ADF000FEE7EE6A7DEEFDA7AE0B791AADB2F8BDA7 -:10AE0000F969E6FF53C8FFF45878D05B93C3EF7637 -:10AE1000BB7656863492E2A65989DB7F982DE6767A -:10AE2000DDAC875B73B68CDB96D900B7ADB38BB85E -:10AE30006D9BADE4B67D16F9FE7AE4FFD96A6E6FBC -:10AE40009E5DCEED86D9A5DC76CC5ECFF33A675712 -:10AE5000727BCBEC8DDCDE3ADB2CF6A19A5069419B -:10AE6000FEA772D665E07F234EF5D1A1C9BBDF24D2 -:10AE7000FC383595F328894013D77B9C4A86F9FF27 -:10AE80006858D8870D5E419F7CFE7F7553F4DB8543 -:10AE9000F87FD009CF90CB95EF27A0BFF32CF1B965 -:10AEA000E47DE16F9CFF740A3F07FD8F63CCFF9741 -:10AEB00068FFCFFA9515B97EE56879AE5F39D46C35 -:10AEC000FB95AE14D5C176493ABF137B7F53F4C7C7 -:10AED0009B59FF4676D278B4C7AD913F9508DC1CEC -:10AEE000F2627FC77E1928DF87FEC514CF43FD407D -:10AEF0007663A1F29AB6DEF7DAF31BE1A4237611AA -:10AF0000FEC9DBF4BFCD85E4BEDE734976D4D92615 -:10AF1000E45E13729FA88A0C53BE259127F7B61DD5 -:10AF2000453CE4C8FDFBB6DC5B725C1A14EF3E4A9C -:10AF300049EE919EA7CFCA7DAE1D55ACF9CE0E51FC -:10AF4000DF6A0B0ABDAA74087DA168B97614F905F9 -:10AF50007A0BF8137145F04D67DD77CFDA33B2AB7A -:10AF6000A5C18054825B6B7FCDC489FD26955A961E -:10AF7000EF7C394A68AB98CF2795362824FF0B968B -:10AF8000A3806D474CB623F9F36C791A9AEC64BC34 -:10AF9000D8766512EF6D66D9930D9AC003DA93AB3C -:10AFA0007A0BC8D3BAC5663452E09C2B7A85FFFE73 -:10AFB000CA4D11E12FA29F487E4AC259D80F58D1DD -:10AFC0002BE856DA9154086FEB758895A11EECE8D2 -:10AFD00048B7510D03E579452FC2BBC9CC0C920C83 -:10AFE0000E7AC782747E94CF463AD7A5CA67D9260F -:10AFF000AB2EB7A78CFD16BBBD10DFDBFE8ECDFFE1 -:10B00000F9F39EAC36B716C2CB915EE1AF1F1D7E41 -:10B010003A873F924AED2D865E50AF9AC665D1AB16 -:10B020000BF32B26D1CEB15E3DB75FB183E8B050B4 -:10B03000BFE2CEDEB37EC52EA2D3BA06E1571CE92D -:10B0400085CBEB2FB4D8F1CAA5F90B9FEF3DBFBF5D -:10B0500030D8ABF3B8827E35E90DBFA5372ED65F69 -:10B0600028E01F1CECE5387A46A6FA1FA2DA10F990 -:10B07000105117453D733FE10DE378F6178E7A05C1 -:10B08000BF988A6D9F220FD078D214FEC2E592033A -:10B09000F4FB1EEA2D5FB83C2C745EDD636B8733D6 -:10B0A000E4E7802F49EFA607E9BD12C58FBFF689F7 -:10B0B000770400F594F7FF9CBCCC203B375EFC8501 -:10B0C000AFD1FC3D7105E8DDE083FD22FF374AF991 -:10B0D000BF6BB1EF8C7D9DC6F70FB8B4A308EF83AB -:10B0E000227FDC813CF58167718ADE051DB3E4CDEA -:10B0F00005DB4B0AF1D5DCF9C4FB5C7ABA7286FF3A -:10B10000AEA34AE33CB98D1F350271843FB2C2C180 -:10B11000F591910F7FF3C8ED74EE0FBB0DAA3F714F -:10B12000A115FB65CB429C47476F10C25979111995 -:10B130009469CAC70FD31BF5ACFA6B7023C6D159FB -:10B140007146493892D3D721CAFB1E0E3A18EEA198 -:10B150007611171DF24EB8B502FAE5BEFEDC774A4D -:10B16000F9ADBCE60D7E273856AF70DDE7FED54B56 -:10B170003A494E0E2EE14A3114D53922A902727C89 -:10B18000DA92631D740FE1D1D3D95552C8AED8ED10 -:10B1900060DE39642D6A92BE2EAA4E46888F8BEAF5 -:10B1A00082523C0B0FBFB4E08F48F1F43A7E8F26F9 -:10B1B000EC04C5BBF44E65A8FC2EAE47BA31DE9F49 -:10B1C000C6EF6EB44BBFC5B6AC428D163A2F6C11AC -:10B1D000F99011672A42741959AA709D1279AA60D0 -:10B1E000DEEBF796BD2AAA1BE3F3419DC275A7FCCF -:10B1F00079BFB2E7A949AE631CACFB779DE4EEE0F2 -:10B2000055C0F9EDFFFEE5AE270648BFF4231D9DAE -:10B21000C4AF1DDC162DFB06E37DB451D1E81EEB57 -:10B22000E5B5035C27DA0806F927F97C50BC62898A -:10B2300087F39D1D0EF6EFF2F9A20819758AFC340A -:10B2400025C376C2092FB2DE1C3544DCA463B42AC0 -:10B25000FA825FEC7A53D0E2C7FC7B8D5A72B5DF7D -:10B26000CAAB97587F8733D6F167AEF78E2E4EB3B1 -:10B270001DB9AF251DA2BAA13FE836285439D01C0C -:10B28000E1FCF6E84A07FBADF3E0AE147A39FF3C87 -:10B29000CEE3EF09FDA888FC85BF4191C8EE7CC9CB -:10B2A0003AC70653C8931616FE9BD613030D0F5FBD -:10B2B000FE869CD2711F69D9EFE34E1C4F6E136F4F -:10B2C0008B8B54912753CD9B07C8AEFDB8520629EE -:10B2D0004C82F70983F36D1121DFF6BBEC8A1E3532 -:10B2E00027BE2F81AC3EBF53C9ED83DC77DEF76606 -:10B2F0007B7E7DF7EB27B2E0B56EC9ADB35D68FD2F -:10B3000007FDBB5F3F817C32669C5FAE6CFA24FB1D -:10B31000C342FF59FC65F31B8580F428F85CEB1FE2 -:10B320000C440BFA25FBB6083D79217DA4B9A23166 -:10B330005A7FF8A65C387759F2769705C7B558ABAF -:10B34000E479D63BA7C31ED8FA74817B8D6C517902 -:10B35000FE1C3FDB7EC08B9796875BD123E2876024 -:10B360008D87EC30E2F345D21F7F0DAA7A367F0E2F -:10B37000F972FD50DB0FF8E9162B0F575E21D1FA59 -:10B38000806EDBF1DC3C41BE1D2F72A6382F5DB410 -:10B3900054B5F50CEB830F7AEF79224EF2933EC849 -:10B3A000FE9E8AFC4BF5BC32328805E804A1DCBF66 -:10B3B00013D9B205183F65FAC4542BDEA32CA27032 -:10B3C0003D4449829126781B8BF8EF3FE877BA8994 -:10B3D000EC1C70509B6CFB24A471FE03B58AC1EF7A -:10B3E00008C1D9FC2ED9DD2A3FD7516DB9B810BD9F -:10B3F000ED73D17BB1DC77F017270F8F6DB1DE6570 -:10B400007BC023E461A36388F31D8E14BF85477955 -:10B41000579AAC9202D5FB4908703C48EF8224ABA6 -:10B420008E543B272770ABF56E73B7783FC37F5FB1 -:10B43000584B7F0F9AE1BF1BBC9A5EB7CA82AE24FD -:10B4400027A7A0CA4175E2F871493AEB1F2DA2A7C0 -:10B450008E8683D62D8108B7F9E7BE0662FCBD1E35 -:10B4600092DC2E83096E1B608ADB4698E196D41528 -:10B470009DC73821EA1DABC090E9FB6A8870DB04E8 -:10B48000316EC390E4F6CB6D9FFCD64EA4C38FE61D -:10B49000E145E0B5805CA711E8D9FBDB78FEC21678 -:10B4A0007D41723B14107993B6709AFD7AAF1EE11C -:10B4B000B8CF19147C6DC3719E234FFCF7FA4FF976 -:10B4C0007F5FF2FF519E9355203F00000000000077 -:10B4D0000000000000000000000000180000000054 -:10B4E000000000000000004000000000000000001C -:10B4F0000000002800000000000000000000001014 -:10B50000000000000000000000000020000000001B -:10B51000000000000000001000000000000000001B -:10B520000000000800000000000000000000000013 -:10B5300000000000000000000000003900000000D2 -:10B5400000000000000000380000000000000000C3 -:10B5500000000000000000000000000000000008E3 -:10B5600000000000000000000000000000000000DB -:10B57000000000000000000C0000000000000000BF -:10B580000000000E000000000000000000000004A9 -:10B590000000000000000000000000180000000093 -:10B5A000000000000000001C00000000000000007F -:10B5B0000000001C0000000000000000000000135C -:10B5C00000000000000000000000003A0000000041 -:10B5D000000000000000000100000000000000006A -:10B5E0000000000200000000000000000000000158 -:10B5F000000000000000000000000010000000003B -:10B6000000000000000000500000000000000000EA -:10B610000000000000000000000000000000000327 -:10B620000000000000000000000000AB000000006F -:10B630000000000000000008000000000000000002 -:10B640000000C00000100000000000080000C0085A -:10B6500000100000000000020000C0000010000008 -:10B660000000001000009FB0000000000000000873 -:10B670000000C08000100000000000040000C0882E -:10B6800000100000000000020000C0800010000058 -:10B6900000000010000091200000000000000008E1 -:10B6A00000009340000100040000000100009348E6 -:10B6B00000000000000000020000935000000000A5 -:10B6C0000000000800009354000000000000000289 -:10B6D00000009418000000000000000800009358CB -:10B6E000000800000000000800009AB000400000C0 -:10B6F00000000040000093980008000000000008CF -:10B70000000093D80008000000000008000094200A -:10B7100000C8000000000098000095B000980000EC -:10B7200000000028000095F00098000000000028AC -:10B730000000C480054000300000054000009D204E -:10B74000000800000000000100009D21000800002A -:10B7500000000001000020080010000000000010A0 -:10B7600000002000000000000000000800009CD83D -:10B77000000800000000000200009D18000000000A -:10B7800000000001000000010000000000000000B7 -:10B79000000000090000000000000000000000029E -:10B7A00000000000000000000000CF2000000000AA -:10B7B000000000200000CF46000000000000000153 -:10B7C0000000600000200000000000200000730066 -:10B7D000000800000000000800009FA0000000001A -:10B7E0000000000100009FA8000000000000000110 -:10B7F00000009F60000000000000001000009F6338 -:10B80000000000000000000100009F610000000037 -:10B810000000000100009F66000000000000000121 -:10B8200000009F67000000000000000000009F680B -:10B83000000000000000000400009F6C00000000F9 -:10B8400000000004000000520000000000000000A2 -:10B8500000000003000000000000000000000003E2 -:10B8600000000000000000000000000500000000D3 -:10B8700000000000000000020000000000000000C6 -:10B8800000060000000000000000002000009F7083 -:10B89000000000000000000100009F900000000078 -:10B8A000000000080000005300000000000000003D -:10B8B00000009F98000000000000000200009F9C14 -:10B8C000000000000000000100009F9D000000003B -:10B8D000000000010000000900000000000000005E -:10B8E0000000000100000000000000000000004413 -:10B8F0000000000000000000000000010000000047 -:10B9000000000000000000500000000000000000E7 -:10B91000000000890000000000000000000012C8C4 -:10B920000080000000000080000000010000000016 -:10B93000000000000000A000071000000000071039 -:10B9400000001AC800000000000000080000AEC09F -:10B9500000080000000000080000AE4000080000E1 -:10B96000000000080000AE80000800000000000891 -:10B97000000020080010000000000010000020005F -:10B9800000000000000000080000A01007100040A8 -:10B990000000004000001BF800080000000000014B -:10B9A00000001BF9000800000000000100001AD090 -:10B9B000000000000000000100001AD80000000094 -:10B9C0000000000200001ADA00000000000000027F -:10B9D0000000000000000000000000000000AF00B8 -:10B9E000000000000000002000001B78002800007C -:10B9F000000000040000E000002000000000002023 -:10BA00000000F300000800000000000800001AF029 -:10BA1000000000000000010800001B3700000000CB -:10BA20000000000100001B0F0000000000000001EA -:10BA300000001B70000000000000000400001B74E8 -:10BA400000000000000000040000005000000000A2 -:10BA500000000000000000030000000000000000E3 -:10BA600000000005000000000000000000000006CB -:10BA700000000000000000000000000700000000BF -:10BA80000000000000001BC80000000000000001D2 -:10BA900000001BE80000000000000008000000514A -:10BAA000000000000000000000001BD000000000AB -:10BAB0000000000400001BD400000000000000048F -:10BAC00000001BD8000000000000000400001BDC88 -:10BAD00000000000000000080000B0000018000096 -:10BAE000000000180000C0000040000000000040FE -:10BAF0000000C00000400002000000010000C00182 -:10BB000000400002000000000000E20000200000F1 -:10BB1000000000200000E2040002000800200002F3 -:10BB20000000000000000000000000000000E20033 -:10BB300000080020000000040000F40000280000BD -:10BB4000000000280000F540001000000000001078 -:10BB50000000F5C000200000000000200000F5C03B -:10BB600000020020000000020000F300002000009E -:10BB7000000000200000200800100000000000105D -:10BB80000000200000000000000000080000110874 -:10BB90000008000000000008000011680008000014 -:10BBA00000000008000011A80008000000000008C4 -:10BBB00000001240000800000000000100001241D7 -:10BBC0000008000000000001000040000020000408 -:10BBD00000000010000059000030001800000010A4 -:10BBE0000000590800300018000000020000570053 -:10BBF00000080000000000010000570100080000DC -:10BC000000000001000011E8000000000000000139 -:10BC1000000011F00000000000000001000011F819 -:10BC200000000000000000100000124400080000A6 -:10BC30000000000400004000002000000000002080 -:10BC40000000530000100000000000100000153834 -:10BC500000000000000000010000000300000000E0 -:10BC600000000000000000000000000000000000D4 -:10BC700000000001000000000000000000000004BF -:10BC80000000000000000000000015080000000097 -:10BC9000000000010000152800000000000000085E -:10BCA00000000050000000000000000000008308B9 -:10BCB0000080000000000080000000010000000083 -:10BCC000000000000000200800100000000000102C -:10BCD00000002000000000000000000800008410A8 -:10BCE0000008000000000008000084700008000048 -:10BCF0000000000800060000046000280000046046 -:10BD000000008520000800000000000100008521DF -:10BD1000000800000000000100000000000000001A -:10BD20000000000000008408000000000000000186 -:10BD3000000084F40008000000000002000084F607 -:10BD40000008000000000002000085040010000050 -:10BD500000000004000087600000000000000020D8 -:10BD600000006000002000000000002000007300C0 -:10BD700000080000000000080000000300000000B0 -:10BD800000000000000000050000000000000000AE -:10BD90000000000600000000000000000000000796 -:10BDA0000000000000000000000088080000000003 -:10BDB00000000001000088280000000000000008CA -:10BDC000000000500000000000000000000088108B -:10BDD00000000000000000040000881400000000C3 -:10BDE00000000004000088180000000000000004AB -:10BDF0000000881C00000000000000080000300067 -:10BE00000040000000000008000030080040000072 -:10BE1000000000280000339001C00010000000085E -:10BE20000000320000200000000000200000372049 -:10BE3000000000000000000800001020062000386C -:10BE4000000000080000A00000000000000020002A -:10BE500000003EA9000000000000000100003EC8F4 -:10BE600000000000000000020000000000000000D0 -:10BE7000000000000000600000200000000000083A -:10BE80000000400000080000000000010000400128 -:10BE9000000800000000000100004040000800040D -:10BEA00000000002000040600008000400000004E0 -:10BEB00000004000000800000000000400004004F2 -:10BEC00000080000000000040000404000000000E6 -:10BED00000000008000040480000000000000008CA -:10BEE0000000800000000000000000100000504032 -:10BEF00000010004000000010000500000000000EC -:10BF000000000020000050080010000000000004A5 -:10BF10000000500C0010000000000001000052C79B -:10BF20000000000000000001000052C600000000F8 -:10BF30000000000100003000003000180000000484 -:10BF40000000300400300018000000040000300839 -:10BF500000300018000000020000300A0030001815 -:10BF6000000000020000300C00300018000000014A -:10BF70000000300D00300018000000010000300EFD -:10BF800000300018000000010000301000300018E0 -:10BF9000000000040000301400300018000000040D -:10BFA0000000500001000080000800040000500460 -:10BFB00001000080000800040000000A00000000EA -:10BFC0000000000000005068010000800000000137 -:10BFD0000000506901000080000000010000506C6A -:10BFE00001000080000000020000506E010000808F -:10BFF00000000002000050700100008000000004FA -:10C000000000507401000080000000040000506631 -:10C010000100008000000002000050640100008068 -:10C0200000000001000050600100008000000002DC -:10C03000000050620100008000000002000050502B -:10C040000100008000000004000050540100008046 -:10C0500000000004000050580100008000000004AF -:10C060000000505C01000080000000040000507CD3 -:10C0700001000080000000010000507D01000080F0 -:10C080000000000100004018001000000000000443 -:10C0900000004090001000000000000400004098E4 -:10C0A000001000000000000400004110000000002B -:10C0B0000000000200004112000000000000000229 -:10C0C00000004114000000000000000200004116C2 -:10C0D00000000000000000020000604000080000B6 -:10C0E00000000002000060420008000000000002A2 -:10C0F00000006044000800000000000400006080B0 -:10C100000008000000000008000060C000400008B7 -:10C1100000000008000060000008000000000002AD -:10C120000000600200080000000000010000600440 -:10C13000000800000000000200006340000800004A -:10C1400000000008000063800008000000000004F8 -:10C15000000063840008000000000001000063C0CC -:10C160000008000000000002000063C40008000096 -:10C17000000000020000640000080000000000044D -:10C1800000007000001000000000000400007004B7 -:10C190000010000000000004000070080010000003 -:10C1A00000000004000090000008000000000002F1 -:10C1B0000000900200080000000000010000900450 -:10C1C000000800000000000200009040000800008D -:10C1D000000000020000904400080000000000027F -:10C1E0000000904600080000000000020000964891 -:10C1F0000008000000000008000090800008000017 -:10C20000000000020000908400080000000000020E -:10C210000000968800080000000000080000804030 -:10C22000000800000000000100008041000800003C -:10C230000000000100008042000800000000000132 -:10C2400000008043000800000000000100008000A2 -:10C25000000800000000000200008002000800004A -:10C26000000000010000800400080000000000023F -:10C27000000080C00008000000000002000080C232 -:10C280000008000000000002000080C40008000058 -:10C290000000000200008080000800000000000193 -:10C2A0000000808100080000000000010000808282 -:10C2B000000800000000000100008083000800006A -:10C2C0000000000100008084000800000000000160 -:10C2D000000080850008000000000001000080864A -:10C2E00000080000000000010000600000080000DD -:10C2F00000000002000060020008000000000001D1 -:10C30000000060040008000000000002000060421D -:10C3100000C00018000000020000604000C00018CB -:10C32000000000020000604C00C00018000000087F -:10C330000000604400C000180000000800006057C2 -:10C3400000C00018000000010000605400C0001888 -:10C35000000000020000605600C00018000000014C -:10C360000000664000080000000000080000668031 -:10C370000008000000000008000066C0000800007F -:10C38000000000080000DA4200180000000000026F -:10C390000000DE4000000000000000000000E0009F -:10C3A00000000000000000040000D0C000000000F9 -:10C3B000000000040000D0C40000000000000004E1 -:10C3C0000000D0C800000000000000040000D0CC35 -:10C3D00000000000000000040000D0D000000000B9 -:10C3E000000000040000D0D40000000000000004A1 -:10C3F0000000D0D800000000000000040000D0C001 -:10C4000000000000000000200000DB000000000031 -:10C41000000000040000DB000000000000000068D5 -:10C420000000B94800000000000000000000D0003B -:10C4300000000000000000040000B0C00000000088 -:10C44000000000040000B0C4000000000000000470 -:10C450000000B0C800000000000000040000B0C0F0 -:10C4600000000000000000100000D6B00000000036 -:10C47000000000040000D6B400000000000000042A -:10C480000000D6B800000000000000040000D6BC88 -:10C4900000000000000000040000D6B00000000012 -:10C4A000000000100000D348000000000000000859 -:10C4B0000000D358000000000000008000000010C1 -:10C4C00000000000000000000000D3580000000041 -:10C4D000000000080000000006002200000000002C -:00000001FF -- cgit v1.2.3-59-g8ed1b From 986d730a696277520084180071ac4873aac63905 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 13 Dec 2010 05:44:50 +0000 Subject: bnx2x: update version to 1.62.00-2 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 66b3b6055cef..f14c6ed62bbb 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,8 +22,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-7" -#define DRV_MODULE_RELDATE "2010/12/08" +#define DRV_MODULE_VERSION "1.62.00-2" +#define DRV_MODULE_RELDATE "2010/12/13" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE -- cgit v1.2.3-59-g8ed1b From ef306b50b983be4873aed453c1feeaab22f3a098 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:44 +0000 Subject: cxgb4: enable PCIe relaxed ordering Enable relaxed ordering for descriptor reads and packet I/O. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 14 ++++++++++++++ drivers/net/cxgb4/sge.c | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 848f89d19fb7..953d62a3403c 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3535,6 +3535,19 @@ static void __devinit print_port_info(struct adapter *adap) } } +static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev) +{ + u16 v; + int pos; + + pos = pci_pcie_cap(dev); + if (pos > 0) { + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v); + v |= PCI_EXP_DEVCTL_RELAX_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v); + } +} + /* * Free the following resources: * - memory used for tables @@ -3609,6 +3622,7 @@ static int __devinit init_one(struct pci_dev *pdev, } pci_enable_pcie_error_reporting(pdev); + enable_pcie_relaxed_ordering(pdev); pci_set_master(pdev); pci_save_state(pdev); diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 17022258ed68..cc0b9975d472 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -2014,6 +2014,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc); c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN | + FW_IQ_CMD_FL0FETCHRO(1) | + FW_IQ_CMD_FL0DATARO(1) | FW_IQ_CMD_FL0PADEN); c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) | FW_IQ_CMD_FL0FBMAX(3)); @@ -2106,6 +2108,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | + FW_EQ_ETH_CMD_FETCHRO(1) | FW_EQ_ETH_CMD_IQID(iqid)); c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) | FW_EQ_ETH_CMD_FBMAX(3) | @@ -2158,6 +2161,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, c.physeqid_pkd = htonl(0); c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) | FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) | + FW_EQ_CTRL_CMD_FETCHRO | FW_EQ_CTRL_CMD_IQID(iqid)); c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) | FW_EQ_CTRL_CMD_FBMAX(3) | @@ -2207,6 +2211,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) | + FW_EQ_OFLD_CMD_FETCHRO(1) | FW_EQ_OFLD_CMD_IQID(iqid)); c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) | FW_EQ_OFLD_CMD_FBMAX(3) | -- cgit v1.2.3-59-g8ed1b From ec16400823ce63bc0cfe89df78c6b7bf4a4d684b Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:45 +0000 Subject: cxgb4: do not read the clock frequency from VPD No need to read the clock frequency from VPD, we already get it a bit later from FW, after any potential adjustments. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/t4_hw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index e97521c801ea..6af04520fa06 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -370,7 +370,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable) static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) { int i, ret; - int ec, sn, v2; + int ec, sn; u8 vpd[VPD_LEN], csum; unsigned int vpdr_len; const struct t4_vpd_hdr *v; @@ -408,10 +408,8 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) FIND_VPD_KW(ec, "EC"); FIND_VPD_KW(sn, "SN"); - FIND_VPD_KW(v2, "V2"); #undef FIND_VPD_KW - p->cclk = simple_strtoul(vpd + v2, NULL, 10); memcpy(p->id, v->id_data, ID_LEN); strim(p->id); memcpy(p->ec, vpd + ec, EC_LEN); -- cgit v1.2.3-59-g8ed1b From a57cabe09f843a3f71277c485494496b3b9ee84a Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:46 +0000 Subject: cxgb4: set the number of queues before device registration The number of queues is known early, move the calls to netif_set_real_num_[rt]x_queues before register_netdev. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 953d62a3403c..3012a8aeff45 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2717,10 +2717,6 @@ static int cxgb_open(struct net_device *dev) return err; } - netif_set_real_num_tx_queues(dev, pi->nqsets); - err = netif_set_real_num_rx_queues(dev, pi->nqsets); - if (err) - return err; err = link_start(dev); if (!err) netif_tx_start_all_queues(dev); @@ -3733,6 +3729,10 @@ static int __devinit init_one(struct pci_dev *pdev, * register at least one net device. */ for_each_port(adapter, i) { + pi = adap2pinfo(adapter, i); + netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets); + netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets); + err = register_netdev(adapter->port[i]); if (err) dev_warn(&pdev->dev, @@ -3747,7 +3747,7 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->name = adapter->port[i]->name; __set_bit(i, &adapter->registered_device_map); - adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; + adapter->chan_map[pi->tx_chan] = i; } } if (!adapter->registered_device_map) { -- cgit v1.2.3-59-g8ed1b From 7d5e77aafa39f3210b6273a44fe07508e837c3cb Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:47 +0000 Subject: cxgb4: distinguish between 1-lane KR/KX and 4-lane KR/KX/KX4 ports And fix the supported flags ethtool reports for the two cases. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 9 +++++++-- drivers/net/cxgb4/t4fw_api.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 3012a8aeff45..3f33d515f62e 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1375,7 +1375,12 @@ static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps) } else if (type == FW_PORT_TYPE_KR) v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; else if (type == FW_PORT_TYPE_BP_AP) - v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC; + v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | + SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; + else if (type == FW_PORT_TYPE_BP4_AP) + v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | + SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | + SUPPORTED_10000baseKX4_Full; else if (type == FW_PORT_TYPE_FIBER_XFI || type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP) v |= SUPPORTED_FIBRE; @@ -3489,7 +3494,7 @@ static void __devinit print_port_info(struct adapter *adap) { static const char *base[] = { "R XFI", "R XAUI", "T SGMII", "T XFI", "T XAUI", "KX4", "CX4", - "KX", "KR", "KR SFP+", "KR FEC" + "KX", "KR", "R SFP+", "KR/KX", "KR/KX/KX4" }; int i; diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h index 940584a8a640..edcfd7ec7802 100644 --- a/drivers/net/cxgb4/t4fw_api.h +++ b/drivers/net/cxgb4/t4fw_api.h @@ -1239,6 +1239,7 @@ enum fw_port_type { FW_PORT_TYPE_KR, FW_PORT_TYPE_SFP, FW_PORT_TYPE_BP_AP, + FW_PORT_TYPE_BP4_AP, FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK }; -- cgit v1.2.3-59-g8ed1b From 118969ed21b6895045b0a5a8a32feac1c9341096 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:48 +0000 Subject: cxgb4: print port information after registering each netdev Print information about each port when its netdev is registered instead of looping separately over the ports at the end. The bulk of this patch is due to indentation change. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 54 +++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 3f33d515f62e..089b753b8a2f 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3490,50 +3490,41 @@ static int __devinit init_rss(struct adapter *adap) return 0; } -static void __devinit print_port_info(struct adapter *adap) +static void __devinit print_port_info(const struct net_device *dev) { static const char *base[] = { "R XFI", "R XAUI", "T SGMII", "T XFI", "T XAUI", "KX4", "CX4", "KX", "KR", "R SFP+", "KR/KX", "KR/KX/KX4" }; - int i; char buf[80]; + char *bufp = buf; const char *spd = ""; + const struct port_info *pi = netdev_priv(dev); + const struct adapter *adap = pi->adapter; if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_2_5GB) spd = " 2.5 GT/s"; else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) spd = " 5 GT/s"; - for_each_port(adap, i) { - struct net_device *dev = adap->port[i]; - const struct port_info *pi = netdev_priv(dev); - char *bufp = buf; - - if (!test_bit(i, &adap->registered_device_map)) - continue; - - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) - bufp += sprintf(bufp, "100/"); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) - bufp += sprintf(bufp, "1000/"); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) - bufp += sprintf(bufp, "10G/"); - if (bufp != buf) - --bufp; - sprintf(bufp, "BASE-%s", base[pi->port_type]); - - netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", - adap->params.vpd.id, adap->params.rev, - buf, is_offload(adap) ? "R" : "", - adap->params.pci.width, spd, - (adap->flags & USING_MSIX) ? " MSI-X" : - (adap->flags & USING_MSI) ? " MSI" : ""); - if (adap->name == dev->name) - netdev_info(dev, "S/N: %s, E/C: %s\n", - adap->params.vpd.sn, adap->params.vpd.ec); - } + if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) + bufp += sprintf(bufp, "100/"); + if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) + bufp += sprintf(bufp, "1000/"); + if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) + bufp += sprintf(bufp, "10G/"); + if (bufp != buf) + --bufp; + sprintf(bufp, "BASE-%s", base[pi->port_type]); + + netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", + adap->params.vpd.id, adap->params.rev, buf, + is_offload(adap) ? "R" : "", adap->params.pci.width, spd, + (adap->flags & USING_MSIX) ? " MSI-X" : + (adap->flags & USING_MSI) ? " MSI" : ""); + netdev_info(dev, "S/N: %s, E/C: %s\n", + adap->params.vpd.sn, adap->params.vpd.ec); } static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev) @@ -3753,6 +3744,7 @@ static int __devinit init_one(struct pci_dev *pdev, __set_bit(i, &adapter->registered_device_map); adapter->chan_map[pi->tx_chan] = i; + print_port_info(adapter->port[i]); } } if (!adapter->registered_device_map) { @@ -3769,8 +3761,6 @@ static int __devinit init_one(struct pci_dev *pdev, if (is_offload(adapter)) attach_ulds(adapter); - print_port_info(adapter); - sriov: #ifdef CONFIG_PCI_IOV if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) -- cgit v1.2.3-59-g8ed1b From 8cd18ac47f9642bcd0d30d4b3521359b1896c208 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:49 +0000 Subject: cxgb4: allocate more space for MSI-X interrupt names Currently MSI-X names for netdevs with long names are truncated in /proc/interrupts due to insufficient space. Use IFNAMSIZ to size the needed space. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 3d4253d311eb..f3d9f64188ff 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -497,7 +497,7 @@ struct adapter { struct { unsigned short vec; - char desc[14]; + char desc[IFNAMSIZ + 10]; } msix_info[MAX_INGQ + 1]; struct sge sge; -- cgit v1.2.3-59-g8ed1b From ba27816cd8167c64652406d86ca78bcc5989f20f Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:50 +0000 Subject: cxgb4: correct formatting of MSI-X interrupt names The last byte of the buffer for MSI-X names could not be used due to a bogus -1. Also do not explicitly clear the last byte, snprintf will do the right thing. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 089b753b8a2f..7e26fe5efbbf 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -522,39 +522,32 @@ static irqreturn_t t4_nondata_intr(int irq, void *cookie) */ static void name_msix_vecs(struct adapter *adap) { - int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1; + int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc); /* non-data interrupts */ snprintf(adap->msix_info[0].desc, n, "%s", adap->name); - adap->msix_info[0].desc[n] = 0; /* FW events */ snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name); - adap->msix_info[1].desc[n] = 0; /* Ethernet queues */ for_each_port(adap, j) { struct net_device *d = adap->port[j]; const struct port_info *pi = netdev_priv(d); - for (i = 0; i < pi->nqsets; i++, msi_idx++) { + for (i = 0; i < pi->nqsets; i++, msi_idx++) snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d", d->name, i); - adap->msix_info[msi_idx].desc[n] = 0; - } } /* offload queues */ - for_each_ofldrxq(&adap->sge, i) { - snprintf(adap->msix_info[msi_idx].desc, n, "%s-ofld%d", + for_each_ofldrxq(&adap->sge, i) + snprintf(adap->msix_info[msi_idx++].desc, n, "%s-ofld%d", adap->name, i); - adap->msix_info[msi_idx++].desc[n] = 0; - } - for_each_rdmarxq(&adap->sge, i) { - snprintf(adap->msix_info[msi_idx].desc, n, "%s-rdma%d", + + for_each_rdmarxq(&adap->sge, i) + snprintf(adap->msix_info[msi_idx++].desc, n, "%s-rdma%d", adap->name, i); - adap->msix_info[msi_idx++].desc[n] = 0; - } } static int request_msix_queue_irqs(struct adapter *adap) -- cgit v1.2.3-59-g8ed1b From b1a3c2b698ec333edc86bf8b5a636162ca309870 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:51 +0000 Subject: cxgb4: remove the name field from the adapter structure Remove a field the driver uses to keep track of the name of the first netdev it manages to register. Do this by changing the registration loop to stop the first time it fails so the first registered device is trivial to tell. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 - drivers/net/cxgb4/cxgb4_main.c | 37 +++++++++++++++---------------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index f3d9f64188ff..9caf95f086e0 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -486,7 +486,6 @@ struct adapter { unsigned int fn; unsigned int flags; - const char *name; int msg_enable; struct adapter_params params; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 7e26fe5efbbf..4d7565cf74ee 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -525,10 +525,11 @@ static void name_msix_vecs(struct adapter *adap) int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc); /* non-data interrupts */ - snprintf(adap->msix_info[0].desc, n, "%s", adap->name); + snprintf(adap->msix_info[0].desc, n, "%s", adap->port[0]->name); /* FW events */ - snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name); + snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", + adap->port[0]->name); /* Ethernet queues */ for_each_port(adap, j) { @@ -543,11 +544,11 @@ static void name_msix_vecs(struct adapter *adap) /* offload queues */ for_each_ofldrxq(&adap->sge, i) snprintf(adap->msix_info[msi_idx++].desc, n, "%s-ofld%d", - adap->name, i); + adap->port[0]->name, i); for_each_rdmarxq(&adap->sge, i) snprintf(adap->msix_info[msi_idx++].desc, n, "%s-rdma%d", - adap->name, i); + adap->port[0]->name, i); } static int request_msix_queue_irqs(struct adapter *adap) @@ -2664,7 +2665,7 @@ static int cxgb_up(struct adapter *adap) } else { err = request_irq(adap->pdev->irq, t4_intr_handler(adap), (adap->flags & USING_MSI) ? 0 : IRQF_SHARED, - adap->name, adap); + adap->port[0]->name, adap); if (err) goto irq_err; } @@ -3627,7 +3628,6 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->pdev = pdev; adapter->pdev_dev = &pdev->dev; adapter->fn = func; - adapter->name = pci_name(pdev); adapter->msg_enable = dflt_msg_enable; memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); @@ -3724,26 +3724,19 @@ static int __devinit init_one(struct pci_dev *pdev, err = register_netdev(adapter->port[i]); if (err) - dev_warn(&pdev->dev, - "cannot register net device %s, skipping\n", - adapter->port[i]->name); - else { - /* - * Change the name we use for messages to the name of - * the first successfully registered interface. - */ - if (!adapter->registered_device_map) - adapter->name = adapter->port[i]->name; - - __set_bit(i, &adapter->registered_device_map); - adapter->chan_map[pi->tx_chan] = i; - print_port_info(adapter->port[i]); - } + break; + __set_bit(i, &adapter->registered_device_map); + adapter->chan_map[pi->tx_chan] = i; + print_port_info(adapter->port[i]); } - if (!adapter->registered_device_map) { + if (i == 0) { dev_err(&pdev->dev, "could not register any net devices\n"); goto out_free_dev; } + if (err) { + dev_warn(&pdev->dev, "only %d net devices registered\n", i); + err = 0; + }; if (cxgb4_debugfs_root) { adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), -- cgit v1.2.3-59-g8ed1b From 8f3a76769ee50a839282f70d07d5f3429524b68a Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:52 +0000 Subject: cxgb4: remove a bitmap The driver keeps a bitmap of the netdevs it registered so it knows what to unregister later. Remove that and look at reg_state instead. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 - drivers/net/cxgb4/cxgb4_main.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 9caf95f086e0..01d49eaa44d2 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -482,7 +482,6 @@ struct adapter { void __iomem *regs; struct pci_dev *pdev; struct device *pdev_dev; - unsigned long registered_device_map; unsigned int fn; unsigned int flags; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 4d7565cf74ee..059c1eec8c3f 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3725,7 +3725,6 @@ static int __devinit init_one(struct pci_dev *pdev, err = register_netdev(adapter->port[i]); if (err) break; - __set_bit(i, &adapter->registered_device_map); adapter->chan_map[pi->tx_chan] = i; print_port_info(adapter->port[i]); } @@ -3785,7 +3784,7 @@ static void __devexit remove_one(struct pci_dev *pdev) detach_ulds(adapter); for_each_port(adapter, i) - if (test_bit(i, &adapter->registered_device_map)) + if (adapter->port[i]->reg_state == NETREG_REGISTERED) unregister_netdev(adapter->port[i]); if (adapter->debugfs_root) -- cgit v1.2.3-59-g8ed1b From 005b5717faac22264c1f61908ec5ac5b98108d99 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 14 Dec 2010 21:36:53 +0000 Subject: cxgb4: add const to static arrays Patch originally from Joe Perches, unmodified. Signed-off-by: Joe Perches Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/t4_hw.c | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index 6af04520fa06..c7fb549776dc 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -183,7 +183,7 @@ static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg) int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl, bool sleep_ok) { - static int delay[] = { + static const int delay[] = { 1, 1, 3, 5, 10, 10, 20, 50, 100, 200 }; @@ -917,7 +917,7 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg, */ static void pcie_intr_handler(struct adapter *adapter) { - static struct intr_info sysbus_intr_info[] = { + static const struct intr_info sysbus_intr_info[] = { { RNPP, "RXNP array parity error", -1, 1 }, { RPCP, "RXPC array parity error", -1, 1 }, { RCIP, "RXCIF array parity error", -1, 1 }, @@ -925,7 +925,7 @@ static void pcie_intr_handler(struct adapter *adapter) { RFTP, "RXFT array parity error", -1, 1 }, { 0 } }; - static struct intr_info pcie_port_intr_info[] = { + static const struct intr_info pcie_port_intr_info[] = { { TPCP, "TXPC array parity error", -1, 1 }, { TNPP, "TXNP array parity error", -1, 1 }, { TFTP, "TXFT array parity error", -1, 1 }, @@ -937,7 +937,7 @@ static void pcie_intr_handler(struct adapter *adapter) { TDUE, "Tx uncorrectable data error", -1, 1 }, { 0 } }; - static struct intr_info pcie_intr_info[] = { + static const struct intr_info pcie_intr_info[] = { { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 }, { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 }, { MSIDATAPERR, "MSI data parity error", -1, 1 }, @@ -989,7 +989,7 @@ static void pcie_intr_handler(struct adapter *adapter) */ static void tp_intr_handler(struct adapter *adapter) { - static struct intr_info tp_intr_info[] = { + static const struct intr_info tp_intr_info[] = { { 0x3fffffff, "TP parity error", -1, 1 }, { FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 }, { 0 } @@ -1006,7 +1006,7 @@ static void sge_intr_handler(struct adapter *adapter) { u64 v; - static struct intr_info sge_intr_info[] = { + static const struct intr_info sge_intr_info[] = { { ERR_CPL_EXCEED_IQE_SIZE, "SGE received CPL exceeding IQE size", -1, 1 }, { ERR_INVALID_CIDX_INC, @@ -1051,7 +1051,7 @@ static void sge_intr_handler(struct adapter *adapter) */ static void cim_intr_handler(struct adapter *adapter) { - static struct intr_info cim_intr_info[] = { + static const struct intr_info cim_intr_info[] = { { PREFDROPINT, "CIM control register prefetch drop", -1, 1 }, { OBQPARERR, "CIM OBQ parity error", -1, 1 }, { IBQPARERR, "CIM IBQ parity error", -1, 1 }, @@ -1061,7 +1061,7 @@ static void cim_intr_handler(struct adapter *adapter) { TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 }, { 0 } }; - static struct intr_info cim_upintr_info[] = { + static const struct intr_info cim_upintr_info[] = { { RSVDSPACEINT, "CIM reserved space access", -1, 1 }, { ILLTRANSINT, "CIM illegal transaction", -1, 1 }, { ILLWRINT, "CIM illegal write", -1, 1 }, @@ -1108,7 +1108,7 @@ static void cim_intr_handler(struct adapter *adapter) */ static void ulprx_intr_handler(struct adapter *adapter) { - static struct intr_info ulprx_intr_info[] = { + static const struct intr_info ulprx_intr_info[] = { { 0x1800000, "ULPRX context error", -1, 1 }, { 0x7fffff, "ULPRX parity error", -1, 1 }, { 0 } @@ -1123,7 +1123,7 @@ static void ulprx_intr_handler(struct adapter *adapter) */ static void ulptx_intr_handler(struct adapter *adapter) { - static struct intr_info ulptx_intr_info[] = { + static const struct intr_info ulptx_intr_info[] = { { PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds", -1, 0 }, { PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds", -1, @@ -1145,7 +1145,7 @@ static void ulptx_intr_handler(struct adapter *adapter) */ static void pmtx_intr_handler(struct adapter *adapter) { - static struct intr_info pmtx_intr_info[] = { + static const struct intr_info pmtx_intr_info[] = { { PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large", -1, 1 }, { PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large", -1, 1 }, { PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large", -1, 1 }, @@ -1167,7 +1167,7 @@ static void pmtx_intr_handler(struct adapter *adapter) */ static void pmrx_intr_handler(struct adapter *adapter) { - static struct intr_info pmrx_intr_info[] = { + static const struct intr_info pmrx_intr_info[] = { { ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 }, { PMRX_FRAMING_ERROR, "PMRX framing error", -1, 1 }, { OCSPI_PAR_ERROR, "PMRX ocspi parity error", -1, 1 }, @@ -1186,7 +1186,7 @@ static void pmrx_intr_handler(struct adapter *adapter) */ static void cplsw_intr_handler(struct adapter *adapter) { - static struct intr_info cplsw_intr_info[] = { + static const struct intr_info cplsw_intr_info[] = { { CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error", -1, 1 }, { CIM_OVFL_ERROR, "CPLSW CIM overflow", -1, 1 }, { TP_FRAMING_ERROR, "CPLSW TP framing error", -1, 1 }, @@ -1205,7 +1205,7 @@ static void cplsw_intr_handler(struct adapter *adapter) */ static void le_intr_handler(struct adapter *adap) { - static struct intr_info le_intr_info[] = { + static const struct intr_info le_intr_info[] = { { LIPMISS, "LE LIP miss", -1, 0 }, { LIP0, "LE 0 LIP error", -1, 0 }, { PARITYERR, "LE parity error", -1, 1 }, @@ -1223,11 +1223,11 @@ static void le_intr_handler(struct adapter *adap) */ static void mps_intr_handler(struct adapter *adapter) { - static struct intr_info mps_rx_intr_info[] = { + static const struct intr_info mps_rx_intr_info[] = { { 0xffffff, "MPS Rx parity error", -1, 1 }, { 0 } }; - static struct intr_info mps_tx_intr_info[] = { + static const struct intr_info mps_tx_intr_info[] = { { TPFIFO, "MPS Tx TP FIFO parity error", -1, 1 }, { NCSIFIFO, "MPS Tx NC-SI FIFO parity error", -1, 1 }, { TXDATAFIFO, "MPS Tx data FIFO parity error", -1, 1 }, @@ -1237,25 +1237,25 @@ static void mps_intr_handler(struct adapter *adapter) { FRMERR, "MPS Tx framing error", -1, 1 }, { 0 } }; - static struct intr_info mps_trc_intr_info[] = { + static const struct intr_info mps_trc_intr_info[] = { { FILTMEM, "MPS TRC filter parity error", -1, 1 }, { PKTFIFO, "MPS TRC packet FIFO parity error", -1, 1 }, { MISCPERR, "MPS TRC misc parity error", -1, 1 }, { 0 } }; - static struct intr_info mps_stat_sram_intr_info[] = { + static const struct intr_info mps_stat_sram_intr_info[] = { { 0x1fffff, "MPS statistics SRAM parity error", -1, 1 }, { 0 } }; - static struct intr_info mps_stat_tx_intr_info[] = { + static const struct intr_info mps_stat_tx_intr_info[] = { { 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 }, { 0 } }; - static struct intr_info mps_stat_rx_intr_info[] = { + static const struct intr_info mps_stat_rx_intr_info[] = { { 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 }, { 0 } }; - static struct intr_info mps_cls_intr_info[] = { + static const struct intr_info mps_cls_intr_info[] = { { MATCHSRAM, "MPS match SRAM parity error", -1, 1 }, { MATCHTCAM, "MPS match TCAM parity error", -1, 1 }, { HASHSRAM, "MPS hash SRAM parity error", -1, 1 }, @@ -1354,7 +1354,7 @@ static void ma_intr_handler(struct adapter *adap) */ static void smb_intr_handler(struct adapter *adap) { - static struct intr_info smb_intr_info[] = { + static const struct intr_info smb_intr_info[] = { { MSTTXFIFOPARINT, "SMB master Tx FIFO parity error", -1, 1 }, { MSTRXFIFOPARINT, "SMB master Rx FIFO parity error", -1, 1 }, { SLVFIFOPARINT, "SMB slave FIFO parity error", -1, 1 }, @@ -1370,7 +1370,7 @@ static void smb_intr_handler(struct adapter *adap) */ static void ncsi_intr_handler(struct adapter *adap) { - static struct intr_info ncsi_intr_info[] = { + static const struct intr_info ncsi_intr_info[] = { { CIM_DM_PRTY_ERR, "NC-SI CIM parity error", -1, 1 }, { MPS_DM_PRTY_ERR, "NC-SI MPS parity error", -1, 1 }, { TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error", -1, 1 }, @@ -1408,7 +1408,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port) */ static void pl_intr_handler(struct adapter *adap) { - static struct intr_info pl_intr_info[] = { + static const struct intr_info pl_intr_info[] = { { FATALPERR, "T4 fatal parity error", -1, 1 }, { PERRVFID, "PL VFID_MAP parity error", -1, 1 }, { 0 } -- cgit v1.2.3-59-g8ed1b From 23d88e1d3e4a5b807ce6725f9294b7b9dfcd89a1 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:54 +0000 Subject: cxgb4: extend VPD parsing Current code parses the VPD RO section for keywords but makes static assumptions about the location of the section. Remove them and parse the VPD to find it. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/t4_hw.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index c7fb549776dc..b9fd8a6f2cc4 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -330,18 +330,6 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) return 0; } -/* - * Partial EEPROM Vital Product Data structure. Includes only the ID and - * VPD-R header. - */ -struct t4_vpd_hdr { - u8 id_tag; - u8 id_len[2]; - u8 id_data[ID_LEN]; - u8 vpdr_tag; - u8 vpdr_len[2]; -}; - #define EEPROM_STAT_ADDR 0x7bfc #define VPD_BASE 0 #define VPD_LEN 512 @@ -372,23 +360,36 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) int i, ret; int ec, sn; u8 vpd[VPD_LEN], csum; - unsigned int vpdr_len; - const struct t4_vpd_hdr *v; + unsigned int vpdr_len, kw_offset, id_len; ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd); if (ret < 0) return ret; - v = (const struct t4_vpd_hdr *)vpd; - vpdr_len = pci_vpd_lrdt_size(&v->vpdr_tag); - if (vpdr_len + sizeof(struct t4_vpd_hdr) > VPD_LEN) { + if (vpd[0] != PCI_VPD_LRDT_ID_STRING) { + dev_err(adapter->pdev_dev, "missing VPD ID string\n"); + return -EINVAL; + } + + id_len = pci_vpd_lrdt_size(vpd); + if (id_len > ID_LEN) + id_len = ID_LEN; + + i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA); + if (i < 0) { + dev_err(adapter->pdev_dev, "missing VPD-R section\n"); + return -EINVAL; + } + + vpdr_len = pci_vpd_lrdt_size(&vpd[i]); + kw_offset = i + PCI_VPD_LRDT_TAG_SIZE; + if (vpdr_len + kw_offset > VPD_LEN) { dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len); return -EINVAL; } #define FIND_VPD_KW(var, name) do { \ - var = pci_vpd_find_info_keyword(&v->id_tag, sizeof(struct t4_vpd_hdr), \ - vpdr_len, name); \ + var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \ if (var < 0) { \ dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \ return -EINVAL; \ @@ -410,7 +411,7 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) FIND_VPD_KW(sn, "SN"); #undef FIND_VPD_KW - memcpy(p->id, v->id_data, ID_LEN); + memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len); strim(p->id); memcpy(p->ec, vpd + ec, EC_LEN); strim(p->ec); -- cgit v1.2.3-59-g8ed1b From ad6bad3efbb82206837daad8cba2bc9343d778bf Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 14 Dec 2010 21:36:55 +0000 Subject: cxgb4: NUMA-aware Tx queue allocations Allocate Tx queue memory on the node indicated by the new netdev_queue_numa_node_read. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/sge.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index cc0b9975d472..311471b439a8 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -579,6 +579,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) * @phys: the physical address of the allocated ring * @metadata: address of the array holding the SW state for the ring * @stat_size: extra space in HW ring for status information + * @node: preferred node for memory allocations * * Allocates resources for an SGE descriptor ring, such as Tx queues, * free buffer lists, or response queues. Each SGE ring requires @@ -590,7 +591,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) */ static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, size_t sw_size, dma_addr_t *phys, void *metadata, - size_t stat_size) + size_t stat_size, int node) { size_t len = nelem * elem_size + stat_size; void *s = NULL; @@ -599,7 +600,7 @@ static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, if (!p) return NULL; if (sw_size) { - s = kcalloc(nelem, sw_size, GFP_KERNEL); + s = kzalloc_node(nelem * sw_size, GFP_KERNEL, node); if (!s) { dma_free_coherent(dev, len, p, *phys); @@ -1982,7 +1983,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, iq->size = roundup(iq->size, 16); iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0, - &iq->phys_addr, NULL, 0); + &iq->phys_addr, NULL, 0, NUMA_NO_NODE); if (!iq->desc) return -ENOMEM; @@ -2008,7 +2009,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, fl->size = roundup(fl->size, 8); fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64), sizeof(struct rx_sw_desc), &fl->addr, - &fl->sdesc, STAT_LEN); + &fl->sdesc, STAT_LEN, NUMA_NO_NODE); if (!fl->desc) goto fl_nomem; @@ -2095,7 +2096,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, sizeof(struct tx_desc), sizeof(struct tx_sw_desc), - &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); + &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN, + netdev_queue_numa_node_read(netdevq)); if (!txq->q.desc) return -ENOMEM; @@ -2147,7 +2149,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, txq->q.desc = alloc_ring(adap->pdev_dev, nentries, sizeof(struct tx_desc), 0, &txq->q.phys_addr, - NULL, 0); + NULL, 0, NUMA_NO_NODE); if (!txq->q.desc) return -ENOMEM; @@ -2198,7 +2200,8 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, sizeof(struct tx_desc), sizeof(struct tx_sw_desc), - &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); + &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN, + NUMA_NO_NODE); if (!txq->q.desc) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 411204a5a1ec1a35363d8ef450c77e2b8235da4d Mon Sep 17 00:00:00 2001 From: Taku Izumi Date: Sun, 12 Dec 2010 19:03:24 +0000 Subject: bonding: migrate some macros from bond_alb.c to bond_alb.h This patch simply migrates some macros from bond_alb.c to bond_alb.h. Signed-off-by: Taku Izumi Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 36 ------------------------------------ drivers/net/bonding/bond_alb.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 26bb118c4533..f4e638c65129 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -44,42 +44,6 @@ #include "bond_alb.h" -#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */ -#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing. - * Used for division - never set - * to zero !!! - */ -#define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of - * learning packets to the switch - */ - -#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \ - * ALB_TIMER_TICKS_PER_SEC) - -#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \ - * ALB_TIMER_TICKS_PER_SEC) - -#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table. - * Note that this value MUST NOT be smaller - * because the key hash table is BYTE wide ! - */ - - -#define TLB_NULL_INDEX 0xffffffff -#define MAX_LP_BURST 3 - -/* rlb defs */ -#define RLB_HASH_TABLE_SIZE 256 -#define RLB_NULL_INDEX 0xffffffff -#define RLB_UPDATE_DELAY 2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */ -#define RLB_ARP_BURST_SIZE 2 -#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb - * rebalance interval (5 min). - */ -/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is - * promiscuous after failover - */ -#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC #ifndef __long_aligned #define __long_aligned __attribute__((aligned((sizeof(long))))) diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h index 50968f8196cf..118c28aa471e 100644 --- a/drivers/net/bonding/bond_alb.h +++ b/drivers/net/bonding/bond_alb.h @@ -31,6 +31,44 @@ struct slave; #define BOND_ALB_INFO(bond) ((bond)->alb_info) #define SLAVE_TLB_INFO(slave) ((slave)->tlb_info) +#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */ +#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing. + * Used for division - never set + * to zero !!! + */ +#define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of + * learning packets to the switch + */ + +#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \ + * ALB_TIMER_TICKS_PER_SEC) + +#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \ + * ALB_TIMER_TICKS_PER_SEC) + +#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table. + * Note that this value MUST NOT be smaller + * because the key hash table is BYTE wide ! + */ + + +#define TLB_NULL_INDEX 0xffffffff +#define MAX_LP_BURST 3 + +/* rlb defs */ +#define RLB_HASH_TABLE_SIZE 256 +#define RLB_NULL_INDEX 0xffffffff +#define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */ +#define RLB_ARP_BURST_SIZE 2 +#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb + * rebalance interval (5 min). + */ +/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is + * promiscuous after failover + */ +#define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC) + + struct tlb_client_info { struct slave *tx_slave; /* A pointer to slave used for transmiting * packets to a Client that the Hash function -- cgit v1.2.3-59-g8ed1b From caafa84251b886feb6cdf23d50e2cc99dcdaaaf3 Mon Sep 17 00:00:00 2001 From: Taku Izumi Date: Sun, 12 Dec 2010 19:04:43 +0000 Subject: bonding: add the debugfs interface to see RLB hash table This patch provices the debugfs interface to see RLB hash table like the following: # cat /sys/kernel/debug/bonding/bond0/rlb_hash_table SourceIP DestinationIP Destination MAC DEV 10.124.196.205 10.124.196.205 ff:ff:ff:ff:ff:ff eth4 10.124.196.205 10.124.196.81 00:19:99:XX:XX:XX eth3 10.124.196.205 10.124.196.1 00:21:d8:XX:XX:XX eth0 This is helpful to check if the receive load balancing works as expected. Signed-off-by: Taku Izumi Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_debugfs.c | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c index ae1eb2fc3a47..3680aa251dea 100644 --- a/drivers/net/bonding/bond_debugfs.c +++ b/drivers/net/bonding/bond_debugfs.c @@ -4,6 +4,7 @@ #include #include "bonding.h" +#include "bond_alb.h" #ifdef CONFIG_DEBUG_FS @@ -12,6 +13,52 @@ static struct dentry *bonding_debug_root; +/* + * Show RLB hash table + */ +static int bond_debug_rlb_hash_show(struct seq_file *m, void *v) +{ + struct bonding *bond = m->private; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct rlb_client_info *client_info; + u32 hash_index; + + if (bond->params.mode != BOND_MODE_ALB) + return 0; + + seq_printf(m, "SourceIP DestinationIP " + "Destination MAC DEV\n"); + + spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); + + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { + client_info = &(bond_info->rx_hashtbl[hash_index]); + seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n", + &client_info->ip_src, + &client_info->ip_dst, + &client_info->mac_dst, + client_info->slave->dev->name); + } + + spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); + + return 0; +} + +static int bond_debug_rlb_hash_open(struct inode *inode, struct file *file) +{ + return single_open(file, bond_debug_rlb_hash_show, inode->i_private); +} + +static const struct file_operations bond_debug_rlb_hash_fops = { + .owner = THIS_MODULE, + .open = bond_debug_rlb_hash_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + void bond_debug_register(struct bonding *bond) { if (!bonding_debug_root) @@ -25,6 +72,9 @@ void bond_debug_register(struct bonding *bond) bond->dev->name); return; } + + debugfs_create_file("rlb_hash_table", 0400, bond->debug_dir, + bond, &bond_debug_rlb_hash_fops); } void bond_debug_unregister(struct bonding *bond) -- cgit v1.2.3-59-g8ed1b From b236da6931e2482bfe44a7865dd4e7bb036f3496 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 14 Dec 2010 03:09:15 +0000 Subject: net: use NUMA_NO_NODE instead of the magic number -1 Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- net/core/dev.c | 2 +- net/core/net-sysfs.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 445e6825f8eb..cc916c5c3279 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -530,7 +530,7 @@ static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) return q->numa_node; #else - return -1; + return NUMA_NO_NODE; #endif } diff --git a/net/core/dev.c b/net/core/dev.c index b25dd087f06a..7ac26d2b9722 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5121,7 +5121,7 @@ static void netdev_init_one_queue(struct net_device *dev, spin_lock_init(&queue->_xmit_lock); netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); queue->xmit_lock_owner = -1; - netdev_queue_numa_node_write(queue, -1); + netdev_queue_numa_node_write(queue, NUMA_NO_NODE); queue->dev = dev; } diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 85e8b5326dd6..e23c01be5a5b 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1009,7 +1009,8 @@ static ssize_t store_xps_map(struct netdev_queue *queue, if (dev_maps) call_rcu(&dev_maps->rcu, xps_dev_maps_release); - netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : -1); + netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : + NUMA_NO_NODE); mutex_unlock(&xps_map_mutex); -- cgit v1.2.3-59-g8ed1b From c6c8fea29769d998d94fcec9b9f14d4b52b349d3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 13 Dec 2010 11:19:28 +0000 Subject: net: Add batman-adv meshing protocol B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is a routing protocol for multi-hop ad-hoc mesh networks. The networks may be wired or wireless. See http://www.open-mesh.org/ for more information and user space tools. Signed-off-by: Sven Eckelmann Signed-off-by: David S. Miller --- .../ABI/testing/sysfs-class-net-batman-adv | 14 + Documentation/ABI/testing/sysfs-class-net-mesh | 69 + Documentation/networking/batman-adv.txt | 240 ++++ MAINTAINERS | 9 + net/Kconfig | 1 + net/Makefile | 1 + net/batman-adv/Kconfig | 25 + net/batman-adv/Makefile | 39 + net/batman-adv/aggregation.c | 273 ++++ net/batman-adv/aggregation.h | 43 + net/batman-adv/bat_debugfs.c | 360 +++++ net/batman-adv/bat_debugfs.h | 33 + net/batman-adv/bat_sysfs.c | 593 +++++++++ net/batman-adv/bat_sysfs.h | 42 + net/batman-adv/bitarray.c | 201 +++ net/batman-adv/bitarray.h | 44 + net/batman-adv/gateway_client.c | 477 +++++++ net/batman-adv/gateway_client.h | 36 + net/batman-adv/gateway_common.c | 177 +++ net/batman-adv/gateway_common.h | 38 + net/batman-adv/hard-interface.c | 651 +++++++++ net/batman-adv/hard-interface.h | 53 + net/batman-adv/hash.c | 62 + net/batman-adv/hash.h | 176 +++ net/batman-adv/icmp_socket.c | 356 +++++ net/batman-adv/icmp_socket.h | 34 + net/batman-adv/main.c | 187 +++ net/batman-adv/main.h | 183 +++ net/batman-adv/originator.c | 564 ++++++++ net/batman-adv/originator.h | 64 + net/batman-adv/packet.h | 136 ++ net/batman-adv/ring_buffer.c | 52 + net/batman-adv/ring_buffer.h | 28 + net/batman-adv/routing.c | 1397 ++++++++++++++++++++ net/batman-adv/routing.h | 48 + net/batman-adv/send.c | 585 ++++++++ net/batman-adv/send.h | 41 + net/batman-adv/soft-interface.c | 697 ++++++++++ net/batman-adv/soft-interface.h | 35 + net/batman-adv/translation-table.c | 534 ++++++++ net/batman-adv/translation-table.h | 45 + net/batman-adv/types.h | 271 ++++ net/batman-adv/unicast.c | 343 +++++ net/batman-adv/unicast.h | 35 + net/batman-adv/vis.c | 949 +++++++++++++ net/batman-adv/vis.h | 37 + 46 files changed, 10278 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-net-batman-adv create mode 100644 Documentation/ABI/testing/sysfs-class-net-mesh create mode 100644 Documentation/networking/batman-adv.txt create mode 100644 net/batman-adv/Kconfig create mode 100644 net/batman-adv/Makefile create mode 100644 net/batman-adv/aggregation.c create mode 100644 net/batman-adv/aggregation.h create mode 100644 net/batman-adv/bat_debugfs.c create mode 100644 net/batman-adv/bat_debugfs.h create mode 100644 net/batman-adv/bat_sysfs.c create mode 100644 net/batman-adv/bat_sysfs.h create mode 100644 net/batman-adv/bitarray.c create mode 100644 net/batman-adv/bitarray.h create mode 100644 net/batman-adv/gateway_client.c create mode 100644 net/batman-adv/gateway_client.h create mode 100644 net/batman-adv/gateway_common.c create mode 100644 net/batman-adv/gateway_common.h create mode 100644 net/batman-adv/hard-interface.c create mode 100644 net/batman-adv/hard-interface.h create mode 100644 net/batman-adv/hash.c create mode 100644 net/batman-adv/hash.h create mode 100644 net/batman-adv/icmp_socket.c create mode 100644 net/batman-adv/icmp_socket.h create mode 100644 net/batman-adv/main.c create mode 100644 net/batman-adv/main.h create mode 100644 net/batman-adv/originator.c create mode 100644 net/batman-adv/originator.h create mode 100644 net/batman-adv/packet.h create mode 100644 net/batman-adv/ring_buffer.c create mode 100644 net/batman-adv/ring_buffer.h create mode 100644 net/batman-adv/routing.c create mode 100644 net/batman-adv/routing.h create mode 100644 net/batman-adv/send.c create mode 100644 net/batman-adv/send.h create mode 100644 net/batman-adv/soft-interface.c create mode 100644 net/batman-adv/soft-interface.h create mode 100644 net/batman-adv/translation-table.c create mode 100644 net/batman-adv/translation-table.h create mode 100644 net/batman-adv/types.h create mode 100644 net/batman-adv/unicast.c create mode 100644 net/batman-adv/unicast.h create mode 100644 net/batman-adv/vis.c create mode 100644 net/batman-adv/vis.h diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv new file mode 100644 index 000000000000..38dd762def4b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -0,0 +1,14 @@ + +What: /sys/class/net//batman-adv/mesh_iface +Date: May 2010 +Contact: Marek Lindner +Description: + The /sys/class/net//batman-adv/mesh_iface file + displays the batman mesh interface this + currently is associated with. + +What: /sys/class/net//batman-adv/iface_status +Date: May 2010 +Contact: Marek Lindner +Description: + Indicates the status of as it is seen by batman. diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh new file mode 100644 index 000000000000..748fe1701d25 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-net-mesh @@ -0,0 +1,69 @@ + +What: /sys/class/net//mesh/aggregated_ogms +Date: May 2010 +Contact: Marek Lindner +Description: + Indicates whether the batman protocol messages of the + mesh shall be aggregated or not. + +What: /sys/class/net//mesh/bonding +Date: June 2010 +Contact: Simon Wunderlich +Description: + Indicates whether the data traffic going through the + mesh will be sent using multiple interfaces at the + same time (if available). + +What: /sys/class/net//mesh/fragmentation +Date: October 2010 +Contact: Andreas Langer +Description: + Indicates whether the data traffic going through the + mesh will be fragmented or silently discarded if the + packet size exceeds the outgoing interface MTU. + +What: /sys/class/net//mesh/gw_bandwidth +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the bandwidth which is propagated by this + node if gw_mode was set to 'server'. + +What: /sys/class/net//mesh/gw_mode +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the state of the gateway features. Can be + either 'off', 'client' or 'server'. + +What: /sys/class/net//mesh/gw_sel_class +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the selection criteria this node will use + to choose a gateway if gw_mode was set to 'client'. + +What: /sys/class/net//mesh/orig_interval +Date: May 2010 +Contact: Marek Lindner +Description: + Defines the interval in milliseconds in which batman + sends its protocol messages. + +What: /sys/class/net//mesh/hop_penalty +Date: Oct 2010 +Contact: Linus Lüssing +Description: + Defines the penalty which will be applied to an + originator message's tq-field on every hop. + +What: /sys/class/net//mesh/vis_mode +Date: May 2010 +Contact: Marek Lindner +Description: + Each batman node only maintains information about its + own local neighborhood, therefore generating graphs + showing the topology of the entire mesh is not easily + feasible without having a central instance to collect + the local topologies from all nodes. This file allows + to activate the collecting (server) mode. diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt new file mode 100644 index 000000000000..77f0cdd5b0dd --- /dev/null +++ b/Documentation/networking/batman-adv.txt @@ -0,0 +1,240 @@ +[state: 21-11-2010] + +BATMAN-ADV +---------- + +Batman advanced is a new approach to wireless networking which +does no longer operate on the IP basis. Unlike the batman daemon, +which exchanges information using UDP packets and sets routing +tables, batman-advanced operates on ISO/OSI Layer 2 only and uses +and routes (or better: bridges) Ethernet Frames. It emulates a +virtual network switch of all nodes participating. Therefore all +nodes appear to be link local, thus all higher operating proto- +cols won't be affected by any changes within the network. You can +run almost any protocol above batman advanced, prominent examples +are: IPv4, IPv6, DHCP, IPX. + +Batman advanced was implemented as a Linux kernel driver to re- +duce the overhead to a minimum. It does not depend on any (other) +network driver, and can be used on wifi as well as ethernet lan, +vpn, etc ... (anything with ethernet-style layer 2). + +CONFIGURATION +------------- + +Load the batman-adv module into your kernel: + +# insmod batman-adv.ko + +The module is now waiting for activation. You must add some in- +terfaces on which batman can operate. After loading the module +batman advanced will scan your systems interfaces to search for +compatible interfaces. Once found, it will create subfolders in +the /sys directories of each supported interface, e.g. + +# ls /sys/class/net/eth0/batman_adv/ +# iface_status mesh_iface + +If an interface does not have the "batman_adv" subfolder it prob- +ably is not supported. Not supported interfaces are: loopback, +non-ethernet and batman's own interfaces. + +Note: After the module was loaded it will continuously watch for +new interfaces to verify the compatibility. There is no need to +reload the module if you plug your USB wifi adapter into your ma- +chine after batman advanced was initially loaded. + +To activate a given interface simply write "bat0" into its +"mesh_iface" file inside the batman_adv subfolder: + +# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface + +Repeat this step for all interfaces you wish to add. Now batman +starts using/broadcasting on this/these interface(s). + +By reading the "iface_status" file you can check its status: + +# cat /sys/class/net/eth0/batman_adv/iface_status +# active + +To deactivate an interface you have to write "none" into its +"mesh_iface" file: + +# echo none > /sys/class/net/eth0/batman_adv/mesh_iface + + +All mesh wide settings can be found in batman's own interface +folder: + +# ls /sys/class/net/bat0/mesh/ +# aggregated_ogms bonding fragmentation orig_interval +# vis_mode + + +There is a special folder for debugging informations: + +# ls /sys/kernel/debug/batman_adv/bat0/ +# originators socket transtable_global transtable_local +# vis_data + + +Some of the files contain all sort of status information regard- +ing the mesh network. For example, you can view the table of +originators (mesh participants) with: + +# cat /sys/kernel/debug/batman_adv/bat0/originators + +Other files allow to change batman's behaviour to better fit your +requirements. For instance, you can check the current originator +interval (value in milliseconds which determines how often batman +sends its broadcast packets): + +# cat /sys/class/net/bat0/mesh/orig_interval +# 1000 + +and also change its value: + +# echo 3000 > /sys/class/net/bat0/mesh/orig_interval + +In very mobile scenarios, you might want to adjust the originator +interval to a lower value. This will make the mesh more respon- +sive to topology changes, but will also increase the overhead. + + +USAGE +----- + +To make use of your newly created mesh, batman advanced provides +a new interface "bat0" which you should use from this point on. +All interfaces added to batman advanced are not relevant any +longer because batman handles them for you. Basically, one "hands +over" the data by using the batman interface and batman will make +sure it reaches its destination. + +The "bat0" interface can be used like any other regular inter- +face. It needs an IP address which can be either statically con- +figured or dynamically (by using DHCP or similar services): + +# NodeA: ifconfig bat0 192.168.0.1 +# NodeB: ifconfig bat0 192.168.0.2 +# NodeB: ping 192.168.0.1 + +Note: In order to avoid problems remove all IP addresses previ- +ously assigned to interfaces now used by batman advanced, e.g. + +# ifconfig eth0 0.0.0.0 + + +VISUALIZATION +------------- + +If you want topology visualization, at least one mesh node must +be configured as VIS-server: + +# echo "server" > /sys/class/net/bat0/mesh/vis_mode + +Each node is either configured as "server" or as "client" (de- +fault: "client"). Clients send their topology data to the server +next to them, and server synchronize with other servers. If there +is no server configured (default) within the mesh, no topology +information will be transmitted. With these "synchronizing +servers", there can be 1 or more vis servers sharing the same (or +at least very similar) data. + +When configured as server, you can get a topology snapshot of +your mesh: + +# cat /sys/kernel/debug/batman_adv/bat0/vis_data + +This raw output is intended to be easily parsable and convertable +with other tools. Have a look at the batctl README if you want a +vis output in dot or json format for instance and how those out- +puts could then be visualised in an image. + +The raw format consists of comma separated values per entry where +each entry is giving information about a certain source inter- +face. Each entry can/has to have the following values: +-> "mac" - mac address of an originator's source interface + (each line begins with it) +-> "TQ mac value" - src mac's link quality towards mac address + of a neighbor originator's interface which + is being used for routing +-> "HNA mac" - HNA announced by source mac +-> "PRIMARY" - this is a primary interface +-> "SEC mac" - secondary mac address of source + (requires preceding PRIMARY) + +The TQ value has a range from 4 to 255 with 255 being the best. +The HNA entries are showing which hosts are connected to the mesh +via bat0 or being bridged into the mesh network. The PRIMARY/SEC +values are only applied on primary interfaces + + +LOGGING/DEBUGGING +----------------- + +All error messages, warnings and information messages are sent to +the kernel log. Depending on your operating system distribution +this can be read in one of a number of ways. Try using the com- +mands: dmesg, logread, or looking in the files /var/log/kern.log +or /var/log/syslog. All batman-adv messages are prefixed with +"batman-adv:" So to see just these messages try + +# dmesg | grep batman-adv + +When investigating problems with your mesh network it is some- +times necessary to see more detail debug messages. This must be +enabled when compiling the batman-adv module. When building bat- +man-adv as part of kernel, use "make menuconfig" and enable the +option "B.A.T.M.A.N. debugging". + +Those additional debug messages can be accessed using a special +file in debugfs + +# cat /sys/kernel/debug/batman_adv/bat0/log + +The additional debug output is by default disabled. It can be en- +abled during run time. Following log_levels are defined: + +0 - All debug output disabled +1 - Enable messages related to routing / flooding / broadcasting +2 - Enable route or hna added / changed / deleted +3 - Enable all messages + +The debug output can be changed at runtime using the file +/sys/class/net/bat0/mesh/log_level. e.g. + +# echo 2 > /sys/class/net/bat0/mesh/log_level + +will enable debug messages for when routes or HNAs change. + + +BATCTL +------ + +As batman advanced operates on layer 2 all hosts participating in +the virtual switch are completely transparent for all protocols +above layer 2. Therefore the common diagnosis tools do not work +as expected. To overcome these problems batctl was created. At +the moment the batctl contains ping, traceroute, tcpdump and +interfaces to the kernel module settings. + +For more information, please see the manpage (man batctl). + +batctl is available on http://www.open-mesh.org/ + + +CONTACT +------- + +Please send us comments, experiences, questions, anything :) + +IRC: #batman on irc.freenode.org +Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org + (optional subscription at + https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) + +You can also contact the Authors: + +Marek Lindner +Simon Wunderlich diff --git a/MAINTAINERS b/MAINTAINERS index f16ce8f46934..2a5e60fb3b5d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1264,6 +1264,15 @@ S: Maintained F: drivers/video/backlight/ F: include/linux/backlight.h +BATMAN ADVANCED +M: Marek Lindner +M: Simon Wunderlich +M: Sven Eckelmann +L: b.a.t.m.a.n@lists.open-mesh.org +W: http://www.open-mesh.org/ +S: Maintained +F: net/batman-adv/ + BAYCOM/HDLCDRV DRIVERS FOR AX.25 M: Thomas Sailer L: linux-hams@vger.kernel.org diff --git a/net/Kconfig b/net/Kconfig index 126c2af0fc1f..ad0aafe903f8 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -214,6 +214,7 @@ source "net/ieee802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" source "net/dns_resolver/Kconfig" +source "net/batman-adv/Kconfig" config RPS boolean diff --git a/net/Makefile b/net/Makefile index 6b7bfd7f1416..a3330ebe2c53 100644 --- a/net/Makefile +++ b/net/Makefile @@ -69,3 +69,4 @@ endif obj-$(CONFIG_WIMAX) += wimax/ obj-$(CONFIG_DNS_RESOLVER) += dns_resolver/ obj-$(CONFIG_CEPH_LIB) += ceph/ +obj-$(CONFIG_BATMAN_ADV) += batman-adv/ diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig new file mode 100644 index 000000000000..6c051ad833eb --- /dev/null +++ b/net/batman-adv/Kconfig @@ -0,0 +1,25 @@ +# +# B.A.T.M.A.N meshing protocol +# + +config BATMAN_ADV + tristate "B.A.T.M.A.N. Advanced Meshing Protocol" + depends on NET + default n + ---help--- + + B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is + a routing protocol for multi-hop ad-hoc mesh networks. The + networks may be wired or wireless. See + http://www.open-mesh.org/ for more information and user space + tools. + +config BATMAN_ADV_DEBUG + bool "B.A.T.M.A.N. debugging" + depends on BATMAN_ADV != n + ---help--- + + This is an option for use by developers; most people should + say N here. This enables compilation of support for + outputting debugging information to the kernel log. The + output is controlled via the module parameter debug. diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile new file mode 100644 index 000000000000..d936aeccd194 --- /dev/null +++ b/net/batman-adv/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: +# +# Marek Lindner, Simon Wunderlich +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA +# + +obj-$(CONFIG_BATMAN_ADV) += batman-adv.o +batman-adv-y += aggregation.o +batman-adv-y += bat_debugfs.o +batman-adv-y += bat_sysfs.o +batman-adv-y += bitarray.o +batman-adv-y += gateway_client.o +batman-adv-y += gateway_common.o +batman-adv-y += hard-interface.o +batman-adv-y += hash.o +batman-adv-y += icmp_socket.o +batman-adv-y += main.o +batman-adv-y += originator.o +batman-adv-y += ring_buffer.o +batman-adv-y += routing.o +batman-adv-y += send.o +batman-adv-y += soft-interface.o +batman-adv-y += translation-table.o +batman-adv-y += unicast.o +batman-adv-y += vis.o diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c new file mode 100644 index 000000000000..3850a3ecf947 --- /dev/null +++ b/net/batman-adv/aggregation.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "aggregation.h" +#include "send.h" +#include "routing.h" + +/* calculate the size of the hna information for a given packet */ +static int hna_len(struct batman_packet *batman_packet) +{ + return batman_packet->num_hna * ETH_ALEN; +} + +/* return true if new_packet can be aggregated with forw_packet */ +static bool can_aggregate_with(struct batman_packet *new_batman_packet, + int packet_len, + unsigned long send_time, + bool directlink, + struct batman_if *if_incoming, + struct forw_packet *forw_packet) +{ + struct batman_packet *batman_packet = + (struct batman_packet *)forw_packet->skb->data; + int aggregated_bytes = forw_packet->packet_len + packet_len; + + /** + * we can aggregate the current packet to this aggregated packet + * if: + * + * - the send time is within our MAX_AGGREGATION_MS time + * - the resulting packet wont be bigger than + * MAX_AGGREGATION_BYTES + */ + + if (time_before(send_time, forw_packet->send_time) && + time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), + forw_packet->send_time) && + (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { + + /** + * check aggregation compatibility + * -> direct link packets are broadcasted on + * their interface only + * -> aggregate packet if the current packet is + * a "global" packet as well as the base + * packet + */ + + /* packets without direct link flag and high TTL + * are flooded through the net */ + if ((!directlink) && + (!(batman_packet->flags & DIRECTLINK)) && + (batman_packet->ttl != 1) && + + /* own packets originating non-primary + * interfaces leave only that interface */ + ((!forw_packet->own) || + (forw_packet->if_incoming->if_num == 0))) + return true; + + /* if the incoming packet is sent via this one + * interface only - we still can aggregate */ + if ((directlink) && + (new_batman_packet->ttl == 1) && + (forw_packet->if_incoming == if_incoming) && + + /* packets from direct neighbors or + * own secondary interface packets + * (= secondary interface packets in general) */ + (batman_packet->flags & DIRECTLINK || + (forw_packet->own && + forw_packet->if_incoming->if_num != 0))) + return true; + } + + return false; +} + +#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) +/* create a new aggregated packet and add this packet to it */ +static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, + unsigned long send_time, bool direct_link, + struct batman_if *if_incoming, + int own_packet) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct forw_packet *forw_packet_aggr; + unsigned char *skb_buff; + + /* own packet should always be scheduled */ + if (!own_packet) { + if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { + bat_dbg(DBG_BATMAN, bat_priv, + "batman packet queue full\n"); + return; + } + } + + forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); + if (!forw_packet_aggr) { + if (!own_packet) + atomic_inc(&bat_priv->batman_queue_left); + return; + } + + if ((atomic_read(&bat_priv->aggregated_ogms)) && + (packet_len < MAX_AGGREGATION_BYTES)) + forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + + sizeof(struct ethhdr)); + else + forw_packet_aggr->skb = dev_alloc_skb(packet_len + + sizeof(struct ethhdr)); + + if (!forw_packet_aggr->skb) { + if (!own_packet) + atomic_inc(&bat_priv->batman_queue_left); + kfree(forw_packet_aggr); + return; + } + skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); + + INIT_HLIST_NODE(&forw_packet_aggr->list); + + skb_buff = skb_put(forw_packet_aggr->skb, packet_len); + forw_packet_aggr->packet_len = packet_len; + memcpy(skb_buff, packet_buff, packet_len); + + forw_packet_aggr->own = own_packet; + forw_packet_aggr->if_incoming = if_incoming; + forw_packet_aggr->num_packets = 0; + forw_packet_aggr->direct_link_flags = 0; + forw_packet_aggr->send_time = send_time; + + /* save packet direct link flag status */ + if (direct_link) + forw_packet_aggr->direct_link_flags |= 1; + + /* add new packet to packet list */ + spin_lock_bh(&bat_priv->forw_bat_list_lock); + hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); + + /* start timer for this packet */ + INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, + send_outstanding_bat_packet); + queue_delayed_work(bat_event_workqueue, + &forw_packet_aggr->delayed_work, + send_time - jiffies); +} + +/* aggregate a new packet into the existing aggregation */ +static void aggregate(struct forw_packet *forw_packet_aggr, + unsigned char *packet_buff, + int packet_len, + bool direct_link) +{ + unsigned char *skb_buff; + + skb_buff = skb_put(forw_packet_aggr->skb, packet_len); + memcpy(skb_buff, packet_buff, packet_len); + forw_packet_aggr->packet_len += packet_len; + forw_packet_aggr->num_packets++; + + /* save packet direct link flag status */ + if (direct_link) + forw_packet_aggr->direct_link_flags |= + (1 << forw_packet_aggr->num_packets); +} + +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, + struct batman_if *if_incoming, char own_packet, + unsigned long send_time) +{ + /** + * _aggr -> pointer to the packet we want to aggregate with + * _pos -> pointer to the position in the queue + */ + struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; + struct hlist_node *tmp_node; + struct batman_packet *batman_packet = + (struct batman_packet *)packet_buff; + bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; + + /* find position for the packet in the forward queue */ + spin_lock_bh(&bat_priv->forw_bat_list_lock); + /* own packets are not to be aggregated */ + if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { + hlist_for_each_entry(forw_packet_pos, tmp_node, + &bat_priv->forw_bat_list, list) { + if (can_aggregate_with(batman_packet, + packet_len, + send_time, + direct_link, + if_incoming, + forw_packet_pos)) { + forw_packet_aggr = forw_packet_pos; + break; + } + } + } + + /* nothing to aggregate with - either aggregation disabled or no + * suitable aggregation packet found */ + if (!forw_packet_aggr) { + /* the following section can run without the lock */ + spin_unlock_bh(&bat_priv->forw_bat_list_lock); + + /** + * if we could not aggregate this packet with one of the others + * we hold it back for a while, so that it might be aggregated + * later on + */ + if ((!own_packet) && + (atomic_read(&bat_priv->aggregated_ogms))) + send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); + + new_aggregated_packet(packet_buff, packet_len, + send_time, direct_link, + if_incoming, own_packet); + } else { + aggregate(forw_packet_aggr, + packet_buff, packet_len, + direct_link); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); + } +} + +/* unpack the aggregated packets and process them one by one */ +void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, + int packet_len, struct batman_if *if_incoming) +{ + struct batman_packet *batman_packet; + int buff_pos = 0; + unsigned char *hna_buff; + + batman_packet = (struct batman_packet *)packet_buff; + + do { + /* network to host order for our 32bit seqno, and the + orig_interval. */ + batman_packet->seqno = ntohl(batman_packet->seqno); + + hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN; + receive_bat_packet(ethhdr, batman_packet, + hna_buff, hna_len(batman_packet), + if_incoming); + + buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); + batman_packet = (struct batman_packet *) + (packet_buff + buff_pos); + } while (aggregated_packet(buff_pos, packet_len, + batman_packet->num_hna)); +} diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h new file mode 100644 index 000000000000..71a91b3da913 --- /dev/null +++ b/net/batman-adv/aggregation.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_AGGREGATION_H_ +#define _NET_BATMAN_ADV_AGGREGATION_H_ + +#include "main.h" + +/* is there another aggregated packet here? */ +static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) +{ + int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); + + return (next_buff_pos <= packet_len) && + (next_buff_pos <= MAX_AGGREGATION_BYTES); +} + +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, + struct batman_if *if_incoming, char own_packet, + unsigned long send_time); +void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, + int packet_len, struct batman_if *if_incoming); + +#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */ diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c new file mode 100644 index 000000000000..0ae81d07f102 --- /dev/null +++ b/net/batman-adv/bat_debugfs.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" + +#include + +#include "bat_debugfs.h" +#include "translation-table.h" +#include "originator.h" +#include "hard-interface.h" +#include "gateway_common.h" +#include "gateway_client.h" +#include "soft-interface.h" +#include "vis.h" +#include "icmp_socket.h" + +static struct dentry *bat_debugfs; + +#ifdef CONFIG_BATMAN_ADV_DEBUG +#define LOG_BUFF_MASK (log_buff_len-1) +#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK]) + +static int log_buff_len = LOG_BUF_LEN; + +static void emit_log_char(struct debug_log *debug_log, char c) +{ + LOG_BUFF(debug_log->log_end) = c; + debug_log->log_end++; + + if (debug_log->log_end - debug_log->log_start > log_buff_len) + debug_log->log_start = debug_log->log_end - log_buff_len; +} + +static int fdebug_log(struct debug_log *debug_log, char *fmt, ...) +{ + int printed_len; + va_list args; + static char debug_log_buf[256]; + char *p; + + if (!debug_log) + return 0; + + spin_lock_bh(&debug_log->lock); + va_start(args, fmt); + printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), + fmt, args); + va_end(args); + + for (p = debug_log_buf; *p != 0; p++) + emit_log_char(debug_log, *p); + + spin_unlock_bh(&debug_log->lock); + + wake_up(&debug_log->queue_wait); + + return 0; +} + +int debug_log(struct bat_priv *bat_priv, char *fmt, ...) +{ + va_list args; + char tmp_log_buf[256]; + + va_start(args, fmt); + vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); + fdebug_log(bat_priv->debug_log, "[%10u] %s", + (jiffies / HZ), tmp_log_buf); + va_end(args); + + return 0; +} + +static int log_open(struct inode *inode, struct file *file) +{ + nonseekable_open(inode, file); + file->private_data = inode->i_private; + inc_module_count(); + return 0; +} + +static int log_release(struct inode *inode, struct file *file) +{ + dec_module_count(); + return 0; +} + +static ssize_t log_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct bat_priv *bat_priv = file->private_data; + struct debug_log *debug_log = bat_priv->debug_log; + int error, i = 0; + char c; + + if ((file->f_flags & O_NONBLOCK) && + !(debug_log->log_end - debug_log->log_start)) + return -EAGAIN; + + if ((!buf) || (count < 0)) + return -EINVAL; + + if (count == 0) + return 0; + + if (!access_ok(VERIFY_WRITE, buf, count)) + return -EFAULT; + + error = wait_event_interruptible(debug_log->queue_wait, + (debug_log->log_start - debug_log->log_end)); + + if (error) + return error; + + spin_lock_bh(&debug_log->lock); + + while ((!error) && (i < count) && + (debug_log->log_start != debug_log->log_end)) { + c = LOG_BUFF(debug_log->log_start); + + debug_log->log_start++; + + spin_unlock_bh(&debug_log->lock); + + error = __put_user(c, buf); + + spin_lock_bh(&debug_log->lock); + + buf++; + i++; + + } + + spin_unlock_bh(&debug_log->lock); + + if (!error) + return i; + + return error; +} + +static unsigned int log_poll(struct file *file, poll_table *wait) +{ + struct bat_priv *bat_priv = file->private_data; + struct debug_log *debug_log = bat_priv->debug_log; + + poll_wait(file, &debug_log->queue_wait, wait); + + if (debug_log->log_end - debug_log->log_start) + return POLLIN | POLLRDNORM; + + return 0; +} + +static const struct file_operations log_fops = { + .open = log_open, + .release = log_release, + .read = log_read, + .poll = log_poll, + .llseek = no_llseek, +}; + +static int debug_log_setup(struct bat_priv *bat_priv) +{ + struct dentry *d; + + if (!bat_priv->debug_dir) + goto err; + + bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC); + if (!bat_priv->debug_log) + goto err; + + spin_lock_init(&bat_priv->debug_log->lock); + init_waitqueue_head(&bat_priv->debug_log->queue_wait); + + d = debugfs_create_file("log", S_IFREG | S_IRUSR, + bat_priv->debug_dir, bat_priv, &log_fops); + if (d) + goto err; + + return 0; + +err: + return 1; +} + +static void debug_log_cleanup(struct bat_priv *bat_priv) +{ + kfree(bat_priv->debug_log); + bat_priv->debug_log = NULL; +} +#else /* CONFIG_BATMAN_ADV_DEBUG */ +static int debug_log_setup(struct bat_priv *bat_priv) +{ + bat_priv->debug_log = NULL; + return 0; +} + +static void debug_log_cleanup(struct bat_priv *bat_priv) +{ + return; +} +#endif + +static int originators_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, orig_seq_print_text, net_dev); +} + +static int gateways_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, gw_client_seq_print_text, net_dev); +} + +static int softif_neigh_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, softif_neigh_seq_print_text, net_dev); +} + +static int transtable_global_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, hna_global_seq_print_text, net_dev); +} + +static int transtable_local_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, hna_local_seq_print_text, net_dev); +} + +static int vis_data_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, vis_seq_print_text, net_dev); +} + +struct bat_debuginfo { + struct attribute attr; + const struct file_operations fops; +}; + +#define BAT_DEBUGINFO(_name, _mode, _open) \ +struct bat_debuginfo bat_debuginfo_##_name = { \ + .attr = { .name = __stringify(_name), \ + .mode = _mode, }, \ + .fops = { .owner = THIS_MODULE, \ + .open = _open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + } \ +}; + +static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); +static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); +static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); +static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); +static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); +static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); + +static struct bat_debuginfo *mesh_debuginfos[] = { + &bat_debuginfo_originators, + &bat_debuginfo_gateways, + &bat_debuginfo_softif_neigh, + &bat_debuginfo_transtable_global, + &bat_debuginfo_transtable_local, + &bat_debuginfo_vis_data, + NULL, +}; + +void debugfs_init(void) +{ + bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); + if (bat_debugfs == ERR_PTR(-ENODEV)) + bat_debugfs = NULL; +} + +void debugfs_destroy(void) +{ + if (bat_debugfs) { + debugfs_remove_recursive(bat_debugfs); + bat_debugfs = NULL; + } +} + +int debugfs_add_meshif(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_debuginfo **bat_debug; + struct dentry *file; + + if (!bat_debugfs) + goto out; + + bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs); + if (!bat_priv->debug_dir) + goto out; + + bat_socket_setup(bat_priv); + debug_log_setup(bat_priv); + + for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { + file = debugfs_create_file(((*bat_debug)->attr).name, + S_IFREG | ((*bat_debug)->attr).mode, + bat_priv->debug_dir, + dev, &(*bat_debug)->fops); + if (!file) { + bat_err(dev, "Can't add debugfs file: %s/%s\n", + dev->name, ((*bat_debug)->attr).name); + goto rem_attr; + } + } + + return 0; +rem_attr: + debugfs_remove_recursive(bat_priv->debug_dir); + bat_priv->debug_dir = NULL; +out: +#ifdef CONFIG_DEBUG_FS + return -ENOMEM; +#else + return 0; +#endif /* CONFIG_DEBUG_FS */ +} + +void debugfs_del_meshif(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + + debug_log_cleanup(bat_priv); + + if (bat_debugfs) { + debugfs_remove_recursive(bat_priv->debug_dir); + bat_priv->debug_dir = NULL; + } +} diff --git a/net/batman-adv/bat_debugfs.h b/net/batman-adv/bat_debugfs.h new file mode 100644 index 000000000000..72df532b7d5f --- /dev/null +++ b/net/batman-adv/bat_debugfs.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + +#ifndef _NET_BATMAN_ADV_DEBUGFS_H_ +#define _NET_BATMAN_ADV_DEBUGFS_H_ + +#define DEBUGFS_BAT_SUBDIR "batman_adv" + +void debugfs_init(void); +void debugfs_destroy(void); +int debugfs_add_meshif(struct net_device *dev); +void debugfs_del_meshif(struct net_device *dev); + +#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */ diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c new file mode 100644 index 000000000000..cd7bb51825f1 --- /dev/null +++ b/net/batman-adv/bat_sysfs.c @@ -0,0 +1,593 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "bat_sysfs.h" +#include "translation-table.h" +#include "originator.h" +#include "hard-interface.h" +#include "gateway_common.h" +#include "gateway_client.h" +#include "vis.h" + +#define to_dev(obj) container_of(obj, struct device, kobj) +#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent)) +#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj)) + +/* Use this, if you have customized show and store functions */ +#define BAT_ATTR(_name, _mode, _show, _store) \ +struct bat_attribute bat_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + +#define BAT_ATTR_STORE_BOOL(_name, _post_func) \ +ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff, size_t count) \ +{ \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return __store_bool_attr(buff, count, _post_func, attr, \ + &bat_priv->_name, net_dev); \ +} + +#define BAT_ATTR_SHOW_BOOL(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ +{ \ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ + return sprintf(buff, "%s\n", \ + atomic_read(&bat_priv->_name) == 0 ? \ + "disabled" : "enabled"); \ +} \ + +/* Use this, if you are going to turn a [name] in bat_priv on or off */ +#define BAT_ATTR_BOOL(_name, _mode, _post_func) \ + static BAT_ATTR_STORE_BOOL(_name, _post_func) \ + static BAT_ATTR_SHOW_BOOL(_name) \ + static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + + +#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ +ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff, size_t count) \ +{ \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return __store_uint_attr(buff, count, _min, _max, _post_func, \ + attr, &bat_priv->_name, net_dev); \ +} + +#define BAT_ATTR_SHOW_UINT(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ +{ \ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ + return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ +} \ + +/* Use this, if you are going to set [name] in bat_priv to unsigned integer + * values only */ +#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ + static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ + static BAT_ATTR_SHOW_UINT(_name) \ + static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + + +static int store_bool_attr(char *buff, size_t count, + struct net_device *net_dev, + char *attr_name, atomic_t *attr) +{ + int enabled = -1; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + if ((strncmp(buff, "1", 2) == 0) || + (strncmp(buff, "enable", 7) == 0) || + (strncmp(buff, "enabled", 8) == 0)) + enabled = 1; + + if ((strncmp(buff, "0", 2) == 0) || + (strncmp(buff, "disable", 8) == 0) || + (strncmp(buff, "disabled", 9) == 0)) + enabled = 0; + + if (enabled < 0) { + bat_info(net_dev, + "%s: Invalid parameter received: %s\n", + attr_name, buff); + return -EINVAL; + } + + if (atomic_read(attr) == enabled) + return count; + + bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, + atomic_read(attr) == 1 ? "enabled" : "disabled", + enabled == 1 ? "enabled" : "disabled"); + + atomic_set(attr, (unsigned)enabled); + return count; +} + +static inline ssize_t __store_bool_attr(char *buff, size_t count, + void (*post_func)(struct net_device *), + struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) +{ + int ret; + + ret = store_bool_attr(buff, count, net_dev, (char *)attr->name, + attr_store); + if (post_func && ret) + post_func(net_dev); + + return ret; +} + +static int store_uint_attr(char *buff, size_t count, + struct net_device *net_dev, char *attr_name, + unsigned int min, unsigned int max, atomic_t *attr) +{ + unsigned long uint_val; + int ret; + + ret = strict_strtoul(buff, 10, &uint_val); + if (ret) { + bat_info(net_dev, + "%s: Invalid parameter received: %s\n", + attr_name, buff); + return -EINVAL; + } + + if (uint_val < min) { + bat_info(net_dev, "%s: Value is too small: %lu min: %u\n", + attr_name, uint_val, min); + return -EINVAL; + } + + if (uint_val > max) { + bat_info(net_dev, "%s: Value is too big: %lu max: %u\n", + attr_name, uint_val, max); + return -EINVAL; + } + + if (atomic_read(attr) == uint_val) + return count; + + bat_info(net_dev, "%s: Changing from: %i to: %lu\n", + attr_name, atomic_read(attr), uint_val); + + atomic_set(attr, uint_val); + return count; +} + +static inline ssize_t __store_uint_attr(char *buff, size_t count, + int min, int max, + void (*post_func)(struct net_device *), + struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) +{ + int ret; + + ret = store_uint_attr(buff, count, net_dev, (char *)attr->name, + min, max, attr_store); + if (post_func && ret) + post_func(net_dev); + + return ret; +} + +static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int vis_mode = atomic_read(&bat_priv->vis_mode); + + return sprintf(buff, "%s\n", + vis_mode == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server"); +} + +static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct bat_priv *bat_priv = netdev_priv(net_dev); + unsigned long val; + int ret, vis_mode_tmp = -1; + + ret = strict_strtoul(buff, 10, &val); + + if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || + (strncmp(buff, "client", 6) == 0) || + (strncmp(buff, "off", 3) == 0)) + vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; + + if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || + (strncmp(buff, "server", 6) == 0)) + vis_mode_tmp = VIS_TYPE_SERVER_SYNC; + + if (vis_mode_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + bat_info(net_dev, + "Invalid parameter for 'vis mode' setting received: " + "%s\n", buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) + return count; + + bat_info(net_dev, "Changing vis mode from: %s to: %s\n", + atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server"); + + atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); + return count; +} + +static void post_gw_deselect(struct net_device *net_dev) +{ + struct bat_priv *bat_priv = netdev_priv(net_dev); + gw_deselect(bat_priv); +} + +static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int bytes_written; + + switch (atomic_read(&bat_priv->gw_mode)) { + case GW_MODE_CLIENT: + bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME); + break; + case GW_MODE_SERVER: + bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME); + break; + default: + bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME); + break; + } + + return bytes_written; +} + +static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct bat_priv *bat_priv = netdev_priv(net_dev); + char *curr_gw_mode_str; + int gw_mode_tmp = -1; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0) + gw_mode_tmp = GW_MODE_OFF; + + if (strncmp(buff, GW_MODE_CLIENT_NAME, + strlen(GW_MODE_CLIENT_NAME)) == 0) + gw_mode_tmp = GW_MODE_CLIENT; + + if (strncmp(buff, GW_MODE_SERVER_NAME, + strlen(GW_MODE_SERVER_NAME)) == 0) + gw_mode_tmp = GW_MODE_SERVER; + + if (gw_mode_tmp < 0) { + bat_info(net_dev, + "Invalid parameter for 'gw mode' setting received: " + "%s\n", buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) + return count; + + switch (atomic_read(&bat_priv->gw_mode)) { + case GW_MODE_CLIENT: + curr_gw_mode_str = GW_MODE_CLIENT_NAME; + break; + case GW_MODE_SERVER: + curr_gw_mode_str = GW_MODE_SERVER_NAME; + break; + default: + curr_gw_mode_str = GW_MODE_OFF_NAME; + break; + } + + bat_info(net_dev, "Changing gw mode from: %s to: %s\n", + curr_gw_mode_str, buff); + + gw_deselect(bat_priv); + atomic_set(&bat_priv->gw_mode, (unsigned)gw_mode_tmp); + return count; +} + +static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int down, up; + int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); + + gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); + return sprintf(buff, "%i%s/%i%s\n", + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + return gw_bandwidth_set(net_dev, buff, count); +} + +BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); +static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); +static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); +BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); +BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); +BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, + post_gw_deselect); +static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, + store_gw_bwidth); +#ifdef CONFIG_BATMAN_ADV_DEBUG +BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); +#endif + +static struct bat_attribute *mesh_attrs[] = { + &bat_attr_aggregated_ogms, + &bat_attr_bonding, + &bat_attr_fragmentation, + &bat_attr_vis_mode, + &bat_attr_gw_mode, + &bat_attr_orig_interval, + &bat_attr_hop_penalty, + &bat_attr_gw_sel_class, + &bat_attr_gw_bandwidth, +#ifdef CONFIG_BATMAN_ADV_DEBUG + &bat_attr_log_level, +#endif + NULL, +}; + +int sysfs_add_meshif(struct net_device *dev) +{ + struct kobject *batif_kobject = &dev->dev.kobj; + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + int err; + + bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, + batif_kobject); + if (!bat_priv->mesh_obj) { + bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, + SYSFS_IF_MESH_SUBDIR); + goto out; + } + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { + err = sysfs_create_file(bat_priv->mesh_obj, + &((*bat_attr)->attr)); + if (err) { + bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bat_attr)->attr).name); + goto rem_attr; + } + } + + return 0; + +rem_attr: + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +out: + return -ENOMEM; +} + +void sysfs_del_meshif(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +} + +static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + ssize_t length; + + if (!batman_if) + return 0; + + length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ? + "none" : batman_if->soft_iface->name); + + kref_put(&batman_if->refcount, hardif_free_ref); + + return length; +} + +static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + int status_tmp = -1; + int ret; + + if (!batman_if) + return count; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + if (strlen(buff) >= IFNAMSIZ) { + pr_err("Invalid parameter for 'mesh_iface' setting received: " + "interface name too long '%s'\n", buff); + kref_put(&batman_if->refcount, hardif_free_ref); + return -EINVAL; + } + + if (strncmp(buff, "none", 4) == 0) + status_tmp = IF_NOT_IN_USE; + else + status_tmp = IF_I_WANT_YOU; + + if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) && + (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) { + kref_put(&batman_if->refcount, hardif_free_ref); + return count; + } + + if (status_tmp == IF_NOT_IN_USE) { + rtnl_lock(); + hardif_disable_interface(batman_if); + rtnl_unlock(); + kref_put(&batman_if->refcount, hardif_free_ref); + return count; + } + + /* if the interface already is in use */ + if (batman_if->if_status != IF_NOT_IN_USE) { + rtnl_lock(); + hardif_disable_interface(batman_if); + rtnl_unlock(); + } + + ret = hardif_enable_interface(batman_if, buff); + kref_put(&batman_if->refcount, hardif_free_ref); + + return ret; +} + +static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + ssize_t length; + + if (!batman_if) + return 0; + + switch (batman_if->if_status) { + case IF_TO_BE_REMOVED: + length = sprintf(buff, "disabling\n"); + break; + case IF_INACTIVE: + length = sprintf(buff, "inactive\n"); + break; + case IF_ACTIVE: + length = sprintf(buff, "active\n"); + break; + case IF_TO_BE_ACTIVATED: + length = sprintf(buff, "enabling\n"); + break; + case IF_NOT_IN_USE: + default: + length = sprintf(buff, "not in use\n"); + break; + } + + kref_put(&batman_if->refcount, hardif_free_ref); + + return length; +} + +static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR, + show_mesh_iface, store_mesh_iface); +static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); + +static struct bat_attribute *batman_attrs[] = { + &bat_attr_mesh_iface, + &bat_attr_iface_status, + NULL, +}; + +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) +{ + struct kobject *hardif_kobject = &dev->dev.kobj; + struct bat_attribute **bat_attr; + int err; + + *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, + hardif_kobject); + + if (!*hardif_obj) { + bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, + SYSFS_IF_BAT_SUBDIR); + goto out; + } + + for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) { + err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); + if (err) { + bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR, + ((*bat_attr)->attr).name); + goto rem_attr; + } + } + + return 0; + +rem_attr: + for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); +out: + return -ENOMEM; +} + +void sysfs_del_hardif(struct kobject **hardif_obj) +{ + kobject_put(*hardif_obj); + *hardif_obj = NULL; +} diff --git a/net/batman-adv/bat_sysfs.h b/net/batman-adv/bat_sysfs.h new file mode 100644 index 000000000000..7f186c007b4f --- /dev/null +++ b/net/batman-adv/bat_sysfs.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + +#ifndef _NET_BATMAN_ADV_SYSFS_H_ +#define _NET_BATMAN_ADV_SYSFS_H_ + +#define SYSFS_IF_MESH_SUBDIR "mesh" +#define SYSFS_IF_BAT_SUBDIR "batman_adv" + +struct bat_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + char *buf, size_t count); +}; + +int sysfs_add_meshif(struct net_device *dev); +void sysfs_del_meshif(struct net_device *dev); +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); +void sysfs_del_hardif(struct kobject **hardif_obj); + +#endif /* _NET_BATMAN_ADV_SYSFS_H_ */ diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c new file mode 100644 index 000000000000..bbcd8f744cdd --- /dev/null +++ b/net/batman-adv/bitarray.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "bitarray.h" + +#include + +/* returns true if the corresponding bit in the given seq_bits indicates true + * and curr_seqno is within range of last_seqno */ +uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno, + uint32_t curr_seqno) +{ + int32_t diff, word_offset, word_num; + + diff = last_seqno - curr_seqno; + if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) { + return 0; + } else { + /* which word */ + word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE; + /* which position in the selected word */ + word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE; + + if (test_bit(word_offset, &seq_bits[word_num])) + return 1; + else + return 0; + } +} + +/* turn corresponding bit on, so we can remember that we got the packet */ +void bit_mark(unsigned long *seq_bits, int32_t n) +{ + int32_t word_offset, word_num; + + /* if too old, just drop it */ + if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) + return; + + /* which word */ + word_num = n / WORD_BIT_SIZE; + /* which position in the selected word */ + word_offset = n % WORD_BIT_SIZE; + + set_bit(word_offset, &seq_bits[word_num]); /* turn the position on */ +} + +/* shift the packet array by n places. */ +static void bit_shift(unsigned long *seq_bits, int32_t n) +{ + int32_t word_offset, word_num; + int32_t i; + + if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) + return; + + word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ + word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */ + + for (i = NUM_WORDS - 1; i > word_num; i--) { + /* going from old to new, so we don't overwrite the data we copy + * from. + * + * left is high, right is low: FEDC BA98 7654 3210 + * ^^ ^^ + * vvvv + * ^^^^ = from, vvvvv =to, we'd have word_num==1 and + * word_offset==WORD_BIT_SIZE/2 ????? in this example. + * (=24 bits) + * + * our desired output would be: 9876 5432 1000 0000 + * */ + + seq_bits[i] = + (seq_bits[i - word_num] << word_offset) + + /* take the lower port from the left half, shift it left + * to its final position */ + (seq_bits[i - word_num - 1] >> + (WORD_BIT_SIZE-word_offset)); + /* and the upper part of the right half and shift it left to + * it's position */ + /* for our example that would be: word[0] = 9800 + 0076 = + * 9876 */ + } + /* now for our last word, i==word_num, we only have the it's "left" + * half. that's the 1000 word in our example.*/ + + seq_bits[i] = (seq_bits[i - word_num] << word_offset); + + /* pad the rest with 0, if there is anything */ + i--; + + for (; i >= 0; i--) + seq_bits[i] = 0; +} + +static void bit_reset_window(unsigned long *seq_bits) +{ + int i; + for (i = 0; i < NUM_WORDS; i++) + seq_bits[i] = 0; +} + + +/* receive and process one packet within the sequence number window. + * + * returns: + * 1 if the window was moved (either new or very old) + * 0 if the window was not moved/shifted. + */ +char bit_get_packet(void *priv, unsigned long *seq_bits, + int32_t seq_num_diff, int8_t set_mark) +{ + struct bat_priv *bat_priv = (struct bat_priv *)priv; + + /* sequence number is slightly older. We already got a sequence number + * higher than this one, so we just mark it. */ + + if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { + if (set_mark) + bit_mark(seq_bits, -seq_num_diff); + return 0; + } + + /* sequence number is slightly newer, so we shift the window and + * set the mark if required */ + + if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { + bit_shift(seq_bits, seq_num_diff); + + if (set_mark) + bit_mark(seq_bits, 0); + return 1; + } + + /* sequence number is much newer, probably missed a lot of packets */ + + if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { + bat_dbg(DBG_BATMAN, bat_priv, + "We missed a lot of packets (%i) !\n", + seq_num_diff - 1); + bit_reset_window(seq_bits); + if (set_mark) + bit_mark(seq_bits, 0); + return 1; + } + + /* received a much older packet. The other host either restarted + * or the old packet got delayed somewhere in the network. The + * packet should be dropped without calling this function if the + * seqno window is protected. */ + + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + + bat_dbg(DBG_BATMAN, bat_priv, + "Other host probably restarted!\n"); + + bit_reset_window(seq_bits); + if (set_mark) + bit_mark(seq_bits, 0); + + return 1; + } + + /* never reached */ + return 0; +} + +/* count the hamming weight, how many good packets did we receive? just count + * the 1's. + */ +int bit_packet_count(unsigned long *seq_bits) +{ + int i, hamming = 0; + + for (i = 0; i < NUM_WORDS; i++) + hamming += hweight_long(seq_bits[i]); + + return hamming; +} diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h new file mode 100644 index 000000000000..ac54017601b1 --- /dev/null +++ b/net/batman-adv/bitarray.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_BITARRAY_H_ +#define _NET_BATMAN_ADV_BITARRAY_H_ + +#define WORD_BIT_SIZE (sizeof(unsigned long) * 8) + +/* returns true if the corresponding bit in the given seq_bits indicates true + * and curr_seqno is within range of last_seqno */ +uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno, + uint32_t curr_seqno); + +/* turn corresponding bit on, so we can remember that we got the packet */ +void bit_mark(unsigned long *seq_bits, int32_t n); + + +/* receive and process one packet, returns 1 if received seq_num is considered + * new, 0 if old */ +char bit_get_packet(void *priv, unsigned long *seq_bits, + int32_t seq_num_diff, int8_t set_mark); + +/* count the hamming weight, how many good packets did we receive? */ +int bit_packet_count(unsigned long *seq_bits); + +#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */ diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c new file mode 100644 index 000000000000..0065ffb8d96d --- /dev/null +++ b/net/batman-adv/gateway_client.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "gateway_client.h" +#include "gateway_common.h" +#include "hard-interface.h" +#include +#include +#include +#include + +static void gw_node_free_ref(struct kref *refcount) +{ + struct gw_node *gw_node; + + gw_node = container_of(refcount, struct gw_node, refcount); + kfree(gw_node); +} + +static void gw_node_free_rcu(struct rcu_head *rcu) +{ + struct gw_node *gw_node; + + gw_node = container_of(rcu, struct gw_node, rcu); + kref_put(&gw_node->refcount, gw_node_free_ref); +} + +void *gw_get_selected(struct bat_priv *bat_priv) +{ + struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; + + if (!curr_gateway_tmp) + return NULL; + + return curr_gateway_tmp->orig_node; +} + +void gw_deselect(struct bat_priv *bat_priv) +{ + struct gw_node *gw_node = bat_priv->curr_gw; + + bat_priv->curr_gw = NULL; + + if (gw_node) + kref_put(&gw_node->refcount, gw_node_free_ref); +} + +static struct gw_node *gw_select(struct bat_priv *bat_priv, + struct gw_node *new_gw_node) +{ + struct gw_node *curr_gw_node = bat_priv->curr_gw; + + if (new_gw_node) + kref_get(&new_gw_node->refcount); + + bat_priv->curr_gw = new_gw_node; + return curr_gw_node; +} + +void gw_election(struct bat_priv *bat_priv) +{ + struct hlist_node *node; + struct gw_node *gw_node, *curr_gw_tmp = NULL, *old_gw_node = NULL; + uint8_t max_tq = 0; + uint32_t max_gw_factor = 0, tmp_gw_factor = 0; + int down, up; + + /** + * The batman daemon checks here if we already passed a full originator + * cycle in order to make sure we don't choose the first gateway we + * hear about. This check is based on the daemon's uptime which we + * don't have. + **/ + if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) + return; + + if (bat_priv->curr_gw) + return; + + rcu_read_lock(); + if (hlist_empty(&bat_priv->gw_list)) { + rcu_read_unlock(); + + if (bat_priv->curr_gw) { + bat_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - " + "no gateway in range\n"); + gw_deselect(bat_priv); + } + + return; + } + + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (!gw_node->orig_node->router) + continue; + + if (gw_node->deleted) + continue; + + switch (atomic_read(&bat_priv->gw_sel_class)) { + case 1: /* fast connection */ + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, + &down, &up); + + tmp_gw_factor = (gw_node->orig_node->router->tq_avg * + gw_node->orig_node->router->tq_avg * + down * 100 * 100) / + (TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE * 64); + + if ((tmp_gw_factor > max_gw_factor) || + ((tmp_gw_factor == max_gw_factor) && + (gw_node->orig_node->router->tq_avg > max_tq))) + curr_gw_tmp = gw_node; + break; + + default: /** + * 2: stable connection (use best statistic) + * 3: fast-switch (use best statistic but change as + * soon as a better gateway appears) + * XX: late-switch (use best statistic but change as + * soon as a better gateway appears which has + * $routing_class more tq points) + **/ + if (gw_node->orig_node->router->tq_avg > max_tq) + curr_gw_tmp = gw_node; + break; + } + + if (gw_node->orig_node->router->tq_avg > max_tq) + max_tq = gw_node->orig_node->router->tq_avg; + + if (tmp_gw_factor > max_gw_factor) + max_gw_factor = tmp_gw_factor; + } + + if (bat_priv->curr_gw != curr_gw_tmp) { + if ((bat_priv->curr_gw) && (!curr_gw_tmp)) + bat_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - " + "no gateway in range\n"); + else if ((!bat_priv->curr_gw) && (curr_gw_tmp)) + bat_dbg(DBG_BATMAN, bat_priv, + "Adding route to gateway %pM " + "(gw_flags: %i, tq: %i)\n", + curr_gw_tmp->orig_node->orig, + curr_gw_tmp->orig_node->gw_flags, + curr_gw_tmp->orig_node->router->tq_avg); + else + bat_dbg(DBG_BATMAN, bat_priv, + "Changing route to gateway %pM " + "(gw_flags: %i, tq: %i)\n", + curr_gw_tmp->orig_node->orig, + curr_gw_tmp->orig_node->gw_flags, + curr_gw_tmp->orig_node->router->tq_avg); + + old_gw_node = gw_select(bat_priv, curr_gw_tmp); + } + + rcu_read_unlock(); + + /* the kfree() has to be outside of the rcu lock */ + if (old_gw_node) + kref_put(&old_gw_node->refcount, gw_node_free_ref); +} + +void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) +{ + struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; + uint8_t gw_tq_avg, orig_tq_avg; + + if (!curr_gateway_tmp) + return; + + if (!curr_gateway_tmp->orig_node) + goto deselect; + + if (!curr_gateway_tmp->orig_node->router) + goto deselect; + + /* this node already is the gateway */ + if (curr_gateway_tmp->orig_node == orig_node) + return; + + if (!orig_node->router) + return; + + gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; + orig_tq_avg = orig_node->router->tq_avg; + + /* the TQ value has to be better */ + if (orig_tq_avg < gw_tq_avg) + return; + + /** + * if the routing class is greater than 3 the value tells us how much + * greater the TQ value of the new gateway must be + **/ + if ((atomic_read(&bat_priv->gw_sel_class) > 3) && + (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) + return; + + bat_dbg(DBG_BATMAN, bat_priv, + "Restarting gateway selection: better gateway found (tq curr: " + "%i, tq new: %i)\n", + gw_tq_avg, orig_tq_avg); + +deselect: + gw_deselect(bat_priv); +} + +static void gw_node_add(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags) +{ + struct gw_node *gw_node; + int down, up; + + gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC); + if (!gw_node) + return; + + memset(gw_node, 0, sizeof(struct gw_node)); + INIT_HLIST_NODE(&gw_node->list); + gw_node->orig_node = orig_node; + kref_init(&gw_node->refcount); + + spin_lock_bh(&bat_priv->gw_list_lock); + hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); + spin_unlock_bh(&bat_priv->gw_list_lock); + + gw_bandwidth_to_kbit(new_gwflags, &down, &up); + bat_dbg(DBG_BATMAN, bat_priv, + "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", + orig_node->orig, new_gwflags, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +void gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags) +{ + struct hlist_node *node; + struct gw_node *gw_node; + + rcu_read_lock(); + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (gw_node->orig_node != orig_node) + continue; + + bat_dbg(DBG_BATMAN, bat_priv, + "Gateway class of originator %pM changed from " + "%i to %i\n", + orig_node->orig, gw_node->orig_node->gw_flags, + new_gwflags); + + gw_node->deleted = 0; + + if (new_gwflags == 0) { + gw_node->deleted = jiffies; + bat_dbg(DBG_BATMAN, bat_priv, + "Gateway %pM removed from gateway list\n", + orig_node->orig); + + if (gw_node == bat_priv->curr_gw) { + rcu_read_unlock(); + gw_deselect(bat_priv); + return; + } + } + + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + + if (new_gwflags == 0) + return; + + gw_node_add(bat_priv, orig_node, new_gwflags); +} + +void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) +{ + return gw_node_update(bat_priv, orig_node, 0); +} + +void gw_node_purge(struct bat_priv *bat_priv) +{ + struct gw_node *gw_node; + struct hlist_node *node, *node_tmp; + unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; + + spin_lock_bh(&bat_priv->gw_list_lock); + + hlist_for_each_entry_safe(gw_node, node, node_tmp, + &bat_priv->gw_list, list) { + if (((!gw_node->deleted) || + (time_before(jiffies, gw_node->deleted + timeout))) && + atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) + continue; + + if (bat_priv->curr_gw == gw_node) + gw_deselect(bat_priv); + + hlist_del_rcu(&gw_node->list); + call_rcu(&gw_node->rcu, gw_node_free_rcu); + } + + + spin_unlock_bh(&bat_priv->gw_list_lock); +} + +static int _write_buffer_text(struct bat_priv *bat_priv, + struct seq_file *seq, struct gw_node *gw_node) +{ + int down, up; + + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); + + return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", + (bat_priv->curr_gw == gw_node ? "=>" : " "), + gw_node->orig_node->orig, + gw_node->orig_node->router->tq_avg, + gw_node->orig_node->router->addr, + gw_node->orig_node->router->if_incoming->net_dev->name, + gw_node->orig_node->gw_flags, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +int gw_client_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct gw_node *gw_node; + struct hlist_node *node; + int gw_count = 0; + + if (!bat_priv->primary_if) { + + return seq_printf(seq, "BATMAN mesh %s disabled - please " + "specify interfaces to enable it\n", + net_dev->name); + } + + if (bat_priv->primary_if->if_status != IF_ACTIVE) { + + return seq_printf(seq, "BATMAN mesh %s disabled - " + "primary interface not active\n", + net_dev->name); + } + + seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " + "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", + "Gateway", "#", TQ_MAX_VALUE, "Nexthop", + "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, + bat_priv->primary_if->net_dev->name, + bat_priv->primary_if->net_dev->dev_addr, net_dev->name); + + rcu_read_lock(); + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (gw_node->deleted) + continue; + + if (!gw_node->orig_node->router) + continue; + + _write_buffer_text(bat_priv, seq, gw_node); + gw_count++; + } + rcu_read_unlock(); + + if (gw_count == 0) + seq_printf(seq, "No gateways in range ...\n"); + + return 0; +} + +int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) +{ + struct ethhdr *ethhdr; + struct iphdr *iphdr; + struct ipv6hdr *ipv6hdr; + struct udphdr *udphdr; + unsigned int header_len = 0; + + if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) + return 0; + + /* check for ethernet header */ + if (!pskb_may_pull(skb, header_len + ETH_HLEN)) + return 0; + ethhdr = (struct ethhdr *)skb->data; + header_len += ETH_HLEN; + + /* check for initial vlan header */ + if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { + if (!pskb_may_pull(skb, header_len + VLAN_HLEN)) + return 0; + ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); + header_len += VLAN_HLEN; + } + + /* check for ip header */ + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_IP: + if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) + return 0; + iphdr = (struct iphdr *)(skb->data + header_len); + header_len += iphdr->ihl * 4; + + /* check for udp header */ + if (iphdr->protocol != IPPROTO_UDP) + return 0; + + break; + case ETH_P_IPV6: + if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr))) + return 0; + ipv6hdr = (struct ipv6hdr *)(skb->data + header_len); + header_len += sizeof(struct ipv6hdr); + + /* check for udp header */ + if (ipv6hdr->nexthdr != IPPROTO_UDP) + return 0; + + break; + default: + return 0; + } + + if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) + return 0; + udphdr = (struct udphdr *)(skb->data + header_len); + header_len += sizeof(struct udphdr); + + /* check for bootp port */ + if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && + (ntohs(udphdr->dest) != 67)) + return 0; + + if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && + (ntohs(udphdr->dest) != 547)) + return 0; + + if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) + return -1; + + if (!bat_priv->curr_gw) + return 0; + + return 1; +} diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h new file mode 100644 index 000000000000..4585e6549844 --- /dev/null +++ b/net/batman-adv/gateway_client.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ +#define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ + +void gw_deselect(struct bat_priv *bat_priv); +void gw_election(struct bat_priv *bat_priv); +void *gw_get_selected(struct bat_priv *bat_priv); +void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); +void gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags); +void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); +void gw_node_purge(struct bat_priv *bat_priv); +int gw_client_seq_print_text(struct seq_file *seq, void *offset); +int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb); + +#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c new file mode 100644 index 000000000000..b962982f017e --- /dev/null +++ b/net/batman-adv/gateway_common.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "gateway_common.h" +#include "gateway_client.h" + +/* calculates the gateway class from kbit */ +static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) +{ + int mdown = 0, tdown, tup, difference; + uint8_t sbit, part; + + *gw_srv_class = 0; + difference = 0x0FFFFFFF; + + /* test all downspeeds */ + for (sbit = 0; sbit < 2; sbit++) { + for (part = 0; part < 16; part++) { + tdown = 32 * (sbit + 2) * (1 << part); + + if (abs(tdown - down) < difference) { + *gw_srv_class = (sbit << 7) + (part << 3); + difference = abs(tdown - down); + mdown = tdown; + } + } + } + + /* test all upspeeds */ + difference = 0x0FFFFFFF; + + for (part = 0; part < 8; part++) { + tup = ((part + 1) * (mdown)) / 8; + + if (abs(tup - up) < difference) { + *gw_srv_class = (*gw_srv_class & 0xF8) | part; + difference = abs(tup - up); + } + } +} + +/* returns the up and downspeeds in kbit, calculated from the class */ +void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) +{ + char sbit = (gw_srv_class & 0x80) >> 7; + char dpart = (gw_srv_class & 0x78) >> 3; + char upart = (gw_srv_class & 0x07); + + if (!gw_srv_class) { + *down = 0; + *up = 0; + return; + } + + *down = 32 * (sbit + 2) * (1 << dpart); + *up = ((upart + 1) * (*down)) / 8; +} + +static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, + long *up, long *down) +{ + int ret, multi = 1; + char *slash_ptr, *tmp_ptr; + + slash_ptr = strchr(buff, '/'); + if (slash_ptr) + *slash_ptr = 0; + + if (strlen(buff) > 4) { + tmp_ptr = buff + strlen(buff) - 4; + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(buff, 10, down); + if (ret) { + bat_err(net_dev, + "Download speed of gateway mode invalid: %s\n", + buff); + return false; + } + + *down *= multi; + + /* we also got some upload info */ + if (slash_ptr) { + multi = 1; + + if (strlen(slash_ptr + 1) > 4) { + tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(slash_ptr + 1, 10, up); + if (ret) { + bat_err(net_dev, + "Upload speed of gateway mode invalid: " + "%s\n", slash_ptr + 1); + return false; + } + + *up *= multi; + } + + return true; +} + +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) +{ + struct bat_priv *bat_priv = netdev_priv(net_dev); + long gw_bandwidth_tmp = 0, up = 0, down = 0; + bool ret; + + ret = parse_gw_bandwidth(net_dev, buff, &up, &down); + if (!ret) + goto end; + + if ((!down) || (down < 256)) + down = 2000; + + if (!up) + up = down / 5; + + kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); + + /** + * the gw bandwidth we guessed above might not match the given + * speeds, hence we need to calculate it back to show the number + * that is going to be propagated + **/ + gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, + (int *)&down, (int *)&up); + + gw_deselect(bat_priv); + bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' " + "(propagating: %ld%s/%ld%s)\n", + atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); + + atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); + +end: + return count; +} diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h new file mode 100644 index 000000000000..5e728d0b7959 --- /dev/null +++ b/net/batman-adv/gateway_common.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ +#define _NET_BATMAN_ADV_GATEWAY_COMMON_H_ + +enum gw_modes { + GW_MODE_OFF, + GW_MODE_CLIENT, + GW_MODE_SERVER, +}; + +#define GW_MODE_OFF_NAME "off" +#define GW_MODE_CLIENT_NAME "client" +#define GW_MODE_SERVER_NAME "server" + +void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count); + +#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c new file mode 100644 index 000000000000..4f95777ce080 --- /dev/null +++ b/net/batman-adv/hard-interface.c @@ -0,0 +1,651 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "hard-interface.h" +#include "soft-interface.h" +#include "send.h" +#include "translation-table.h" +#include "routing.h" +#include "bat_sysfs.h" +#include "originator.h" +#include "hash.h" + +#include + +/* protect update critical side of if_list - but not the content */ +static DEFINE_SPINLOCK(if_list_lock); + +static void hardif_free_rcu(struct rcu_head *rcu) +{ + struct batman_if *batman_if; + + batman_if = container_of(rcu, struct batman_if, rcu); + dev_put(batman_if->net_dev); + kref_put(&batman_if->refcount, hardif_free_ref); +} + +struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) +{ + struct batman_if *batman_if; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->net_dev == net_dev) + goto out; + } + + batman_if = NULL; + +out: + if (batman_if) + kref_get(&batman_if->refcount); + + rcu_read_unlock(); + return batman_if; +} + +static int is_valid_iface(struct net_device *net_dev) +{ + if (net_dev->flags & IFF_LOOPBACK) + return 0; + + if (net_dev->type != ARPHRD_ETHER) + return 0; + + if (net_dev->addr_len != ETH_ALEN) + return 0; + + /* no batman over batman */ +#ifdef HAVE_NET_DEVICE_OPS + if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + return 0; +#else + if (net_dev->hard_start_xmit == interface_tx) + return 0; +#endif + + /* Device is being bridged */ + /* if (net_dev->priv_flags & IFF_BRIDGE_PORT) + return 0; */ + + return 1; +} + +static struct batman_if *get_active_batman_if(struct net_device *soft_iface) +{ + struct batman_if *batman_if; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->soft_iface != soft_iface) + continue; + + if (batman_if->if_status == IF_ACTIVE) + goto out; + } + + batman_if = NULL; + +out: + if (batman_if) + kref_get(&batman_if->refcount); + + rcu_read_unlock(); + return batman_if; +} + +static void update_primary_addr(struct bat_priv *bat_priv) +{ + struct vis_packet *vis_packet; + + vis_packet = (struct vis_packet *) + bat_priv->my_vis_info->skb_packet->data; + memcpy(vis_packet->vis_orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + memcpy(vis_packet->sender_orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); +} + +static void set_primary_if(struct bat_priv *bat_priv, + struct batman_if *batman_if) +{ + struct batman_packet *batman_packet; + struct batman_if *old_if; + + if (batman_if) + kref_get(&batman_if->refcount); + + old_if = bat_priv->primary_if; + bat_priv->primary_if = batman_if; + + if (old_if) + kref_put(&old_if->refcount, hardif_free_ref); + + if (!bat_priv->primary_if) + return; + + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->flags = PRIMARIES_FIRST_HOP; + batman_packet->ttl = TTL; + + update_primary_addr(bat_priv); + + /*** + * hacky trick to make sure that we send the HNA information via + * our new primary interface + */ + atomic_set(&bat_priv->hna_local_changed, 1); +} + +static bool hardif_is_iface_up(struct batman_if *batman_if) +{ + if (batman_if->net_dev->flags & IFF_UP) + return true; + + return false; +} + +static void update_mac_addresses(struct batman_if *batman_if) +{ + memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, + batman_if->net_dev->dev_addr, ETH_ALEN); + memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, + batman_if->net_dev->dev_addr, ETH_ALEN); +} + +static void check_known_mac_addr(struct net_device *net_dev) +{ + struct batman_if *batman_if; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) + continue; + + if (batman_if->net_dev == net_dev) + continue; + + if (!compare_orig(batman_if->net_dev->dev_addr, + net_dev->dev_addr)) + continue; + + pr_warning("The newly added mac address (%pM) already exists " + "on: %s\n", net_dev->dev_addr, + batman_if->net_dev->name); + pr_warning("It is strongly recommended to keep mac addresses " + "unique to avoid problems!\n"); + } + rcu_read_unlock(); +} + +int hardif_min_mtu(struct net_device *soft_iface) +{ + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct batman_if *batman_if; + /* allow big frames if all devices are capable to do so + * (have MTU > 1500 + BAT_HEADER_LEN) */ + int min_mtu = ETH_DATA_LEN; + + if (atomic_read(&bat_priv->fragmentation)) + goto out; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) + continue; + + if (batman_if->soft_iface != soft_iface) + continue; + + min_mtu = min_t(int, batman_if->net_dev->mtu - BAT_HEADER_LEN, + min_mtu); + } + rcu_read_unlock(); +out: + return min_mtu; +} + +/* adjusts the MTU if a new interface with a smaller MTU appeared. */ +void update_min_mtu(struct net_device *soft_iface) +{ + int min_mtu; + + min_mtu = hardif_min_mtu(soft_iface); + if (soft_iface->mtu != min_mtu) + soft_iface->mtu = min_mtu; +} + +static void hardif_activate_interface(struct batman_if *batman_if) +{ + struct bat_priv *bat_priv; + + if (batman_if->if_status != IF_INACTIVE) + return; + + bat_priv = netdev_priv(batman_if->soft_iface); + + update_mac_addresses(batman_if); + batman_if->if_status = IF_TO_BE_ACTIVATED; + + /** + * the first active interface becomes our primary interface or + * the next active interface after the old primay interface was removed + */ + if (!bat_priv->primary_if) + set_primary_if(bat_priv, batman_if); + + bat_info(batman_if->soft_iface, "Interface activated: %s\n", + batman_if->net_dev->name); + + update_min_mtu(batman_if->soft_iface); + return; +} + +static void hardif_deactivate_interface(struct batman_if *batman_if) +{ + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) + return; + + batman_if->if_status = IF_INACTIVE; + + bat_info(batman_if->soft_iface, "Interface deactivated: %s\n", + batman_if->net_dev->name); + + update_min_mtu(batman_if->soft_iface); +} + +int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) +{ + struct bat_priv *bat_priv; + struct batman_packet *batman_packet; + + if (batman_if->if_status != IF_NOT_IN_USE) + goto out; + + batman_if->soft_iface = dev_get_by_name(&init_net, iface_name); + + if (!batman_if->soft_iface) { + batman_if->soft_iface = softif_create(iface_name); + + if (!batman_if->soft_iface) + goto err; + + /* dev_get_by_name() increases the reference counter for us */ + dev_hold(batman_if->soft_iface); + } + + bat_priv = netdev_priv(batman_if->soft_iface); + batman_if->packet_len = BAT_PACKET_LEN; + batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC); + + if (!batman_if->packet_buff) { + bat_err(batman_if->soft_iface, "Can't add interface packet " + "(%s): out of memory\n", batman_if->net_dev->name); + goto err; + } + + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->packet_type = BAT_PACKET; + batman_packet->version = COMPAT_VERSION; + batman_packet->flags = 0; + batman_packet->ttl = 2; + batman_packet->tq = TQ_MAX_VALUE; + batman_packet->num_hna = 0; + + batman_if->if_num = bat_priv->num_ifaces; + bat_priv->num_ifaces++; + batman_if->if_status = IF_INACTIVE; + orig_hash_add_if(batman_if, bat_priv->num_ifaces); + + batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); + batman_if->batman_adv_ptype.func = batman_skb_recv; + batman_if->batman_adv_ptype.dev = batman_if->net_dev; + kref_get(&batman_if->refcount); + dev_add_pack(&batman_if->batman_adv_ptype); + + atomic_set(&batman_if->seqno, 1); + atomic_set(&batman_if->frag_seqno, 1); + bat_info(batman_if->soft_iface, "Adding interface: %s\n", + batman_if->net_dev->name); + + if (atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < + ETH_DATA_LEN + BAT_HEADER_LEN) + bat_info(batman_if->soft_iface, + "The MTU of interface %s is too small (%i) to handle " + "the transport of batman-adv packets. Packets going " + "over this interface will be fragmented on layer2 " + "which could impact the performance. Setting the MTU " + "to %zi would solve the problem.\n", + batman_if->net_dev->name, batman_if->net_dev->mtu, + ETH_DATA_LEN + BAT_HEADER_LEN); + + if (!atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < + ETH_DATA_LEN + BAT_HEADER_LEN) + bat_info(batman_if->soft_iface, + "The MTU of interface %s is too small (%i) to handle " + "the transport of batman-adv packets. If you experience" + " problems getting traffic through try increasing the " + "MTU to %zi.\n", + batman_if->net_dev->name, batman_if->net_dev->mtu, + ETH_DATA_LEN + BAT_HEADER_LEN); + + if (hardif_is_iface_up(batman_if)) + hardif_activate_interface(batman_if); + else + bat_err(batman_if->soft_iface, "Not using interface %s " + "(retrying later): interface not active\n", + batman_if->net_dev->name); + + /* begin scheduling originator messages on that interface */ + schedule_own_packet(batman_if); + +out: + return 0; + +err: + return -ENOMEM; +} + +void hardif_disable_interface(struct batman_if *batman_if) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + + if (batman_if->if_status == IF_ACTIVE) + hardif_deactivate_interface(batman_if); + + if (batman_if->if_status != IF_INACTIVE) + return; + + bat_info(batman_if->soft_iface, "Removing interface: %s\n", + batman_if->net_dev->name); + dev_remove_pack(&batman_if->batman_adv_ptype); + kref_put(&batman_if->refcount, hardif_free_ref); + + bat_priv->num_ifaces--; + orig_hash_del_if(batman_if, bat_priv->num_ifaces); + + if (batman_if == bat_priv->primary_if) { + struct batman_if *new_if; + + new_if = get_active_batman_if(batman_if->soft_iface); + set_primary_if(bat_priv, new_if); + + if (new_if) + kref_put(&new_if->refcount, hardif_free_ref); + } + + kfree(batman_if->packet_buff); + batman_if->packet_buff = NULL; + batman_if->if_status = IF_NOT_IN_USE; + + /* delete all references to this batman_if */ + purge_orig_ref(bat_priv); + purge_outstanding_packets(bat_priv, batman_if); + dev_put(batman_if->soft_iface); + + /* nobody uses this interface anymore */ + if (!bat_priv->num_ifaces) + softif_destroy(batman_if->soft_iface); + + batman_if->soft_iface = NULL; +} + +static struct batman_if *hardif_add_interface(struct net_device *net_dev) +{ + struct batman_if *batman_if; + int ret; + + ret = is_valid_iface(net_dev); + if (ret != 1) + goto out; + + dev_hold(net_dev); + + batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); + if (!batman_if) { + pr_err("Can't add interface (%s): out of memory\n", + net_dev->name); + goto release_dev; + } + + ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev); + if (ret) + goto free_if; + + batman_if->if_num = -1; + batman_if->net_dev = net_dev; + batman_if->soft_iface = NULL; + batman_if->if_status = IF_NOT_IN_USE; + INIT_LIST_HEAD(&batman_if->list); + kref_init(&batman_if->refcount); + + check_known_mac_addr(batman_if->net_dev); + + spin_lock(&if_list_lock); + list_add_tail_rcu(&batman_if->list, &if_list); + spin_unlock(&if_list_lock); + + /* extra reference for return */ + kref_get(&batman_if->refcount); + return batman_if; + +free_if: + kfree(batman_if); +release_dev: + dev_put(net_dev); +out: + return NULL; +} + +static void hardif_remove_interface(struct batman_if *batman_if) +{ + /* first deactivate interface */ + if (batman_if->if_status != IF_NOT_IN_USE) + hardif_disable_interface(batman_if); + + if (batman_if->if_status != IF_NOT_IN_USE) + return; + + batman_if->if_status = IF_TO_BE_REMOVED; + sysfs_del_hardif(&batman_if->hardif_obj); + call_rcu(&batman_if->rcu, hardif_free_rcu); +} + +void hardif_remove_interfaces(void) +{ + struct batman_if *batman_if, *batman_if_tmp; + struct list_head if_queue; + + INIT_LIST_HEAD(&if_queue); + + spin_lock(&if_list_lock); + list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) { + list_del_rcu(&batman_if->list); + list_add_tail(&batman_if->list, &if_queue); + } + spin_unlock(&if_list_lock); + + rtnl_lock(); + list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) { + hardif_remove_interface(batman_if); + } + rtnl_unlock(); +} + +static int hard_if_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *net_dev = (struct net_device *)ptr; + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + struct bat_priv *bat_priv; + + if (!batman_if && event == NETDEV_REGISTER) + batman_if = hardif_add_interface(net_dev); + + if (!batman_if) + goto out; + + switch (event) { + case NETDEV_UP: + hardif_activate_interface(batman_if); + break; + case NETDEV_GOING_DOWN: + case NETDEV_DOWN: + hardif_deactivate_interface(batman_if); + break; + case NETDEV_UNREGISTER: + spin_lock(&if_list_lock); + list_del_rcu(&batman_if->list); + spin_unlock(&if_list_lock); + + hardif_remove_interface(batman_if); + break; + case NETDEV_CHANGEMTU: + if (batman_if->soft_iface) + update_min_mtu(batman_if->soft_iface); + break; + case NETDEV_CHANGEADDR: + if (batman_if->if_status == IF_NOT_IN_USE) + goto hardif_put; + + check_known_mac_addr(batman_if->net_dev); + update_mac_addresses(batman_if); + + bat_priv = netdev_priv(batman_if->soft_iface); + if (batman_if == bat_priv->primary_if) + update_primary_addr(bat_priv); + break; + default: + break; + }; + +hardif_put: + kref_put(&batman_if->refcount, hardif_free_ref); +out: + return NOTIFY_DONE; +} + +/* receive a packet with the batman ethertype coming on a hard + * interface */ +int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *orig_dev) +{ + struct bat_priv *bat_priv; + struct batman_packet *batman_packet; + struct batman_if *batman_if; + int ret; + + batman_if = container_of(ptype, struct batman_if, batman_adv_ptype); + skb = skb_share_check(skb, GFP_ATOMIC); + + /* skb was released by skb_share_check() */ + if (!skb) + goto err_out; + + /* packet should hold at least type and version */ + if (unlikely(!pskb_may_pull(skb, 2))) + goto err_free; + + /* expect a valid ethernet header here. */ + if (unlikely(skb->mac_len != sizeof(struct ethhdr) + || !skb_mac_header(skb))) + goto err_free; + + if (!batman_if->soft_iface) + goto err_free; + + bat_priv = netdev_priv(batman_if->soft_iface); + + if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) + goto err_free; + + /* discard frames on not active interfaces */ + if (batman_if->if_status != IF_ACTIVE) + goto err_free; + + batman_packet = (struct batman_packet *)skb->data; + + if (batman_packet->version != COMPAT_VERSION) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_packet->version); + goto err_free; + } + + /* all receive handlers return whether they received or reused + * the supplied skb. if not, we have to free the skb. */ + + switch (batman_packet->packet_type) { + /* batman originator packet */ + case BAT_PACKET: + ret = recv_bat_packet(skb, batman_if); + break; + + /* batman icmp packet */ + case BAT_ICMP: + ret = recv_icmp_packet(skb, batman_if); + break; + + /* unicast packet */ + case BAT_UNICAST: + ret = recv_unicast_packet(skb, batman_if); + break; + + /* fragmented unicast packet */ + case BAT_UNICAST_FRAG: + ret = recv_ucast_frag_packet(skb, batman_if); + break; + + /* broadcast packet */ + case BAT_BCAST: + ret = recv_bcast_packet(skb, batman_if); + break; + + /* vis packet */ + case BAT_VIS: + ret = recv_vis_packet(skb, batman_if); + break; + default: + ret = NET_RX_DROP; + } + + if (ret == NET_RX_DROP) + kfree_skb(skb); + + /* return NET_RX_SUCCESS in any case as we + * most probably dropped the packet for + * routing-logical reasons. */ + + return NET_RX_SUCCESS; + +err_free: + kfree_skb(skb); +err_out: + return NET_RX_DROP; +} + +struct notifier_block hard_if_notifier = { + .notifier_call = hard_if_event, +}; diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h new file mode 100644 index 000000000000..30ec3b8db459 --- /dev/null +++ b/net/batman-adv/hard-interface.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_ +#define _NET_BATMAN_ADV_HARD_INTERFACE_H_ + +#define IF_NOT_IN_USE 0 +#define IF_TO_BE_REMOVED 1 +#define IF_INACTIVE 2 +#define IF_ACTIVE 3 +#define IF_TO_BE_ACTIVATED 4 +#define IF_I_WANT_YOU 5 + +extern struct notifier_block hard_if_notifier; + +struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); +int hardif_enable_interface(struct batman_if *batman_if, char *iface_name); +void hardif_disable_interface(struct batman_if *batman_if); +void hardif_remove_interfaces(void); +int batman_skb_recv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev); +int hardif_min_mtu(struct net_device *soft_iface); +void update_min_mtu(struct net_device *soft_iface); + +static inline void hardif_free_ref(struct kref *refcount) +{ + struct batman_if *batman_if; + + batman_if = container_of(refcount, struct batman_if, refcount); + kfree(batman_if); +} + +#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */ diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c new file mode 100644 index 000000000000..26e623eb9def --- /dev/null +++ b/net/batman-adv/hash.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "hash.h" + +/* clears the hash */ +static void hash_init(struct hashtable_t *hash) +{ + int i; + + for (i = 0 ; i < hash->size; i++) + INIT_HLIST_HEAD(&hash->table[i]); +} + +/* free only the hashtable and the hash itself. */ +void hash_destroy(struct hashtable_t *hash) +{ + kfree(hash->table); + kfree(hash); +} + +/* allocates and clears the hash */ +struct hashtable_t *hash_new(int size) +{ + struct hashtable_t *hash; + + hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC); + + if (!hash) + return NULL; + + hash->size = size; + hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); + + if (!hash->table) { + kfree(hash); + return NULL; + } + + hash_init(hash); + + return hash; +} diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h new file mode 100644 index 000000000000..09216ade16f1 --- /dev/null +++ b/net/batman-adv/hash.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_HASH_H_ +#define _NET_BATMAN_ADV_HASH_H_ + +#include + +/* callback to a compare function. should + * compare 2 element datas for their keys, + * return 0 if same and not 0 if not + * same */ +typedef int (*hashdata_compare_cb)(void *, void *); + +/* the hashfunction, should return an index + * based on the key in the data of the first + * argument and the size the second */ +typedef int (*hashdata_choose_cb)(void *, int); +typedef void (*hashdata_free_cb)(void *, void *); + +struct element_t { + void *data; /* pointer to the data */ + struct hlist_node hlist; /* bucket list pointer */ +}; + +struct hashtable_t { + struct hlist_head *table; /* the hashtable itself, with the buckets */ + int size; /* size of hashtable */ +}; + +/* allocates and clears the hash */ +struct hashtable_t *hash_new(int size); + +/* remove element if you already found the element you want to delete and don't + * need the overhead to find it again with hash_remove(). But usually, you + * don't want to use this function, as it fiddles with hash-internals. */ +void *hash_remove_element(struct hashtable_t *hash, struct element_t *elem); + +/* free only the hashtable and the hash itself. */ +void hash_destroy(struct hashtable_t *hash); + +/* remove the hash structure. if hashdata_free_cb != NULL, this function will be + * called to remove the elements inside of the hash. if you don't remove the + * elements, memory might be leaked. */ +static inline void hash_delete(struct hashtable_t *hash, + hashdata_free_cb free_cb, void *arg) +{ + struct hlist_head *head; + struct hlist_node *walk, *safe; + struct element_t *bucket; + int i; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_safe(walk, safe, head) { + bucket = hlist_entry(walk, struct element_t, hlist); + if (free_cb) + free_cb(bucket->data, arg); + + hlist_del(walk); + kfree(bucket); + } + } + + hash_destroy(hash); +} + +/* adds data to the hashtable. returns 0 on success, -1 on error */ +static inline int hash_add(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) +{ + int index; + struct hlist_head *head; + struct hlist_node *walk, *safe; + struct element_t *bucket; + + if (!hash) + return -1; + + index = choose(data, hash->size); + head = &hash->table[index]; + + hlist_for_each_safe(walk, safe, head) { + bucket = hlist_entry(walk, struct element_t, hlist); + if (compare(bucket->data, data)) + return -1; + } + + /* no duplicate found in list, add new element */ + bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); + + if (!bucket) + return -1; + + bucket->data = data; + hlist_add_head(&bucket->hlist, head); + + return 0; +} + +/* removes data from hash, if found. returns pointer do data on success, so you + * can remove the used structure yourself, or NULL on error . data could be the + * structure you use with just the key filled, we just need the key for + * comparing. */ +static inline void *hash_remove(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) +{ + size_t index; + struct hlist_node *walk; + struct element_t *bucket; + struct hlist_head *head; + void *data_save; + + index = choose(data, hash->size); + head = &hash->table[index]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + if (compare(bucket->data, data)) { + data_save = bucket->data; + hlist_del(walk); + kfree(bucket); + return data_save; + } + } + + return NULL; +} + +/* finds data, based on the key in keydata. returns the found data on success, + * or NULL on error */ +static inline void *hash_find(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *keydata) +{ + int index; + struct hlist_head *head; + struct hlist_node *walk; + struct element_t *bucket; + + if (!hash) + return NULL; + + index = choose(keydata , hash->size); + head = &hash->table[index]; + + hlist_for_each(walk, head) { + bucket = hlist_entry(walk, struct element_t, hlist); + if (compare(bucket->data, keydata)) + return bucket->data; + } + + return NULL; +} + +#endif /* _NET_BATMAN_ADV_HASH_H_ */ diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c new file mode 100644 index 000000000000..ecf6d7ffab2e --- /dev/null +++ b/net/batman-adv/icmp_socket.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include +#include +#include "icmp_socket.h" +#include "send.h" +#include "types.h" +#include "hash.h" +#include "originator.h" +#include "hard-interface.h" + +static struct socket_client *socket_client_hash[256]; + +static void bat_socket_add_packet(struct socket_client *socket_client, + struct icmp_packet_rr *icmp_packet, + size_t icmp_len); + +void bat_socket_init(void) +{ + memset(socket_client_hash, 0, sizeof(socket_client_hash)); +} + +static int bat_socket_open(struct inode *inode, struct file *file) +{ + unsigned int i; + struct socket_client *socket_client; + + nonseekable_open(inode, file); + + socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL); + + if (!socket_client) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) { + if (!socket_client_hash[i]) { + socket_client_hash[i] = socket_client; + break; + } + } + + if (i == ARRAY_SIZE(socket_client_hash)) { + pr_err("Error - can't add another packet client: " + "maximum number of clients reached\n"); + kfree(socket_client); + return -EXFULL; + } + + INIT_LIST_HEAD(&socket_client->queue_list); + socket_client->queue_len = 0; + socket_client->index = i; + socket_client->bat_priv = inode->i_private; + spin_lock_init(&socket_client->lock); + init_waitqueue_head(&socket_client->queue_wait); + + file->private_data = socket_client; + + inc_module_count(); + return 0; +} + +static int bat_socket_release(struct inode *inode, struct file *file) +{ + struct socket_client *socket_client = file->private_data; + struct socket_packet *socket_packet; + struct list_head *list_pos, *list_pos_tmp; + + spin_lock_bh(&socket_client->lock); + + /* for all packets in the queue ... */ + list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) { + socket_packet = list_entry(list_pos, + struct socket_packet, list); + + list_del(list_pos); + kfree(socket_packet); + } + + socket_client_hash[socket_client->index] = NULL; + spin_unlock_bh(&socket_client->lock); + + kfree(socket_client); + dec_module_count(); + + return 0; +} + +static ssize_t bat_socket_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct socket_client *socket_client = file->private_data; + struct socket_packet *socket_packet; + size_t packet_len; + int error; + + if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0)) + return -EAGAIN; + + if ((!buf) || (count < sizeof(struct icmp_packet))) + return -EINVAL; + + if (!access_ok(VERIFY_WRITE, buf, count)) + return -EFAULT; + + error = wait_event_interruptible(socket_client->queue_wait, + socket_client->queue_len); + + if (error) + return error; + + spin_lock_bh(&socket_client->lock); + + socket_packet = list_first_entry(&socket_client->queue_list, + struct socket_packet, list); + list_del(&socket_packet->list); + socket_client->queue_len--; + + spin_unlock_bh(&socket_client->lock); + + error = __copy_to_user(buf, &socket_packet->icmp_packet, + socket_packet->icmp_len); + + packet_len = socket_packet->icmp_len; + kfree(socket_packet); + + if (error) + return -EFAULT; + + return packet_len; +} + +static ssize_t bat_socket_write(struct file *file, const char __user *buff, + size_t len, loff_t *off) +{ + struct socket_client *socket_client = file->private_data; + struct bat_priv *bat_priv = socket_client->bat_priv; + struct sk_buff *skb; + struct icmp_packet_rr *icmp_packet; + + struct orig_node *orig_node; + struct batman_if *batman_if; + size_t packet_len = sizeof(struct icmp_packet); + uint8_t dstaddr[ETH_ALEN]; + + if (len < sizeof(struct icmp_packet)) { + bat_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: " + "invalid packet size\n"); + return -EINVAL; + } + + if (!bat_priv->primary_if) + return -EFAULT; + + if (len >= sizeof(struct icmp_packet_rr)) + packet_len = sizeof(struct icmp_packet_rr); + + skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr)); + if (!skb) + return -ENOMEM; + + skb_reserve(skb, sizeof(struct ethhdr)); + icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len); + + if (!access_ok(VERIFY_READ, buff, packet_len)) { + len = -EFAULT; + goto free_skb; + } + + if (__copy_from_user(icmp_packet, buff, packet_len)) { + len = -EFAULT; + goto free_skb; + } + + if (icmp_packet->packet_type != BAT_ICMP) { + bat_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: " + "got bogus packet type (expected: BAT_ICMP)\n"); + len = -EINVAL; + goto free_skb; + } + + if (icmp_packet->msg_type != ECHO_REQUEST) { + bat_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: " + "got bogus message type (expected: ECHO_REQUEST)\n"); + len = -EINVAL; + goto free_skb; + } + + icmp_packet->uid = socket_client->index; + + if (icmp_packet->version != COMPAT_VERSION) { + icmp_packet->msg_type = PARAMETER_PROBLEM; + icmp_packet->ttl = COMPAT_VERSION; + bat_socket_add_packet(socket_client, icmp_packet, packet_len); + goto free_skb; + } + + if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) + goto dst_unreach; + + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, choose_orig, + icmp_packet->dst)); + + if (!orig_node) + goto unlock; + + if (!orig_node->router) + goto unlock; + + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + if (!batman_if) + goto dst_unreach; + + if (batman_if->if_status != IF_ACTIVE) + goto dst_unreach; + + memcpy(icmp_packet->orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + + if (packet_len == sizeof(struct icmp_packet_rr)) + memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN); + + + send_skb_packet(skb, batman_if, dstaddr); + + goto out; + +unlock: + spin_unlock_bh(&bat_priv->orig_hash_lock); +dst_unreach: + icmp_packet->msg_type = DESTINATION_UNREACHABLE; + bat_socket_add_packet(socket_client, icmp_packet, packet_len); +free_skb: + kfree_skb(skb); +out: + return len; +} + +static unsigned int bat_socket_poll(struct file *file, poll_table *wait) +{ + struct socket_client *socket_client = file->private_data; + + poll_wait(file, &socket_client->queue_wait, wait); + + if (socket_client->queue_len > 0) + return POLLIN | POLLRDNORM; + + return 0; +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + .open = bat_socket_open, + .release = bat_socket_release, + .read = bat_socket_read, + .write = bat_socket_write, + .poll = bat_socket_poll, + .llseek = no_llseek, +}; + +int bat_socket_setup(struct bat_priv *bat_priv) +{ + struct dentry *d; + + if (!bat_priv->debug_dir) + goto err; + + d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, + bat_priv->debug_dir, bat_priv, &fops); + if (d) + goto err; + + return 0; + +err: + return 1; +} + +static void bat_socket_add_packet(struct socket_client *socket_client, + struct icmp_packet_rr *icmp_packet, + size_t icmp_len) +{ + struct socket_packet *socket_packet; + + socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC); + + if (!socket_packet) + return; + + INIT_LIST_HEAD(&socket_packet->list); + memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); + socket_packet->icmp_len = icmp_len; + + spin_lock_bh(&socket_client->lock); + + /* while waiting for the lock the socket_client could have been + * deleted */ + if (!socket_client_hash[icmp_packet->uid]) { + spin_unlock_bh(&socket_client->lock); + kfree(socket_packet); + return; + } + + list_add_tail(&socket_packet->list, &socket_client->queue_list); + socket_client->queue_len++; + + if (socket_client->queue_len > 100) { + socket_packet = list_first_entry(&socket_client->queue_list, + struct socket_packet, list); + + list_del(&socket_packet->list); + kfree(socket_packet); + socket_client->queue_len--; + } + + spin_unlock_bh(&socket_client->lock); + + wake_up(&socket_client->queue_wait); +} + +void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, + size_t icmp_len) +{ + struct socket_client *hash = socket_client_hash[icmp_packet->uid]; + + if (hash) + bat_socket_add_packet(hash, icmp_packet, icmp_len); +} diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h new file mode 100644 index 000000000000..bf9b348cde27 --- /dev/null +++ b/net/batman-adv/icmp_socket.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_ +#define _NET_BATMAN_ADV_ICMP_SOCKET_H_ + +#include "types.h" + +#define ICMP_SOCKET "socket" + +void bat_socket_init(void); +int bat_socket_setup(struct bat_priv *bat_priv); +void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, + size_t icmp_len); + +#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */ diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c new file mode 100644 index 000000000000..b827f6a158cb --- /dev/null +++ b/net/batman-adv/main.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "bat_sysfs.h" +#include "bat_debugfs.h" +#include "routing.h" +#include "send.h" +#include "originator.h" +#include "soft-interface.h" +#include "icmp_socket.h" +#include "translation-table.h" +#include "hard-interface.h" +#include "gateway_client.h" +#include "types.h" +#include "vis.h" +#include "hash.h" + +struct list_head if_list; + +unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +struct workqueue_struct *bat_event_workqueue; + +static int __init batman_init(void) +{ + INIT_LIST_HEAD(&if_list); + + /* the name should not be longer than 10 chars - see + * http://lwn.net/Articles/23634/ */ + bat_event_workqueue = create_singlethread_workqueue("bat_events"); + + if (!bat_event_workqueue) + return -ENOMEM; + + bat_socket_init(); + debugfs_init(); + + register_netdevice_notifier(&hard_if_notifier); + + pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) " + "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, + COMPAT_VERSION); + + return 0; +} + +static void __exit batman_exit(void) +{ + debugfs_destroy(); + unregister_netdevice_notifier(&hard_if_notifier); + hardif_remove_interfaces(); + + flush_workqueue(bat_event_workqueue); + destroy_workqueue(bat_event_workqueue); + bat_event_workqueue = NULL; + + rcu_barrier(); +} + +int mesh_init(struct net_device *soft_iface) +{ + struct bat_priv *bat_priv = netdev_priv(soft_iface); + + spin_lock_init(&bat_priv->orig_hash_lock); + spin_lock_init(&bat_priv->forw_bat_list_lock); + spin_lock_init(&bat_priv->forw_bcast_list_lock); + spin_lock_init(&bat_priv->hna_lhash_lock); + spin_lock_init(&bat_priv->hna_ghash_lock); + spin_lock_init(&bat_priv->gw_list_lock); + spin_lock_init(&bat_priv->vis_hash_lock); + spin_lock_init(&bat_priv->vis_list_lock); + spin_lock_init(&bat_priv->softif_neigh_lock); + + INIT_HLIST_HEAD(&bat_priv->forw_bat_list); + INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); + INIT_HLIST_HEAD(&bat_priv->gw_list); + INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); + + if (originator_init(bat_priv) < 1) + goto err; + + if (hna_local_init(bat_priv) < 1) + goto err; + + if (hna_global_init(bat_priv) < 1) + goto err; + + hna_local_add(soft_iface, soft_iface->dev_addr); + + if (vis_init(bat_priv) < 1) + goto err; + + atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); + goto end; + +err: + pr_err("Unable to allocate memory for mesh information structures: " + "out of mem ?\n"); + mesh_free(soft_iface); + return -1; + +end: + return 0; +} + +void mesh_free(struct net_device *soft_iface) +{ + struct bat_priv *bat_priv = netdev_priv(soft_iface); + + atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING); + + purge_outstanding_packets(bat_priv, NULL); + + vis_quit(bat_priv); + + gw_node_purge(bat_priv); + originator_free(bat_priv); + + hna_local_free(bat_priv); + hna_global_free(bat_priv); + + softif_neigh_purge(bat_priv); + + atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); +} + +void inc_module_count(void) +{ + try_module_get(THIS_MODULE); +} + +void dec_module_count(void) +{ + module_put(THIS_MODULE); +} + +int is_my_mac(uint8_t *addr) +{ + struct batman_if *batman_if; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->if_status != IF_ACTIVE) + continue; + + if (compare_orig(batman_if->net_dev->dev_addr, addr)) { + rcu_read_unlock(); + return 1; + } + } + rcu_read_unlock(); + return 0; + +} + +module_init(batman_init); +module_exit(batman_exit); + +MODULE_LICENSE("GPL"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); +#ifdef REVISION_VERSION +MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION); +#else +MODULE_VERSION(SOURCE_VERSION); +#endif diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h new file mode 100644 index 000000000000..d4d9926c2201 --- /dev/null +++ b/net/batman-adv/main.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_MAIN_H_ +#define _NET_BATMAN_ADV_MAIN_H_ + +/* Kernel Programming */ +#define LINUX + +#define DRIVER_AUTHOR "Marek Lindner , " \ + "Simon Wunderlich " +#define DRIVER_DESC "B.A.T.M.A.N. advanced" +#define DRIVER_DEVICE "batman-adv" + +#define SOURCE_VERSION "next" + + +/* B.A.T.M.A.N. parameters */ + +#define TQ_MAX_VALUE 255 +#define JITTER 20 +#define TTL 50 /* Time To Live of broadcast messages */ + +#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no + * valid packet comes in -> TODO: check + * influence on TQ_LOCAL_WINDOW_SIZE */ +#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */ + +#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator + * messages in squence numbers (should be a + * multiple of our word size) */ +#define TQ_GLOBAL_WINDOW_SIZE 5 +#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 +#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 +#define TQ_TOTAL_BIDRECT_LIMIT 1 + +#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) + +#define PACKBUFF_SIZE 2000 +#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ + +#define VIS_INTERVAL 5000 /* 5 seconds */ + +/* how much worse secondary interfaces may be to + * to be considered as bonding candidates */ + +#define BONDING_TQ_THRESHOLD 50 + +#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or + * change the size of + * forw_packet->direct_link_flags */ +#define MAX_AGGREGATION_MS 100 + +#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ + +#define RESET_PROTECTION_MS 30000 +#define EXPECTED_SEQNO_RANGE 65536 +/* don't reset again within 30 seconds */ + +#define MESH_INACTIVE 0 +#define MESH_ACTIVE 1 +#define MESH_DEACTIVATING 2 + +#define BCAST_QUEUE_LEN 256 +#define BATMAN_QUEUE_LEN 256 + +/* + * Debug Messages + */ +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before + * kernel messages */ + +#define DBG_BATMAN 1 /* all messages related to routing / flooding / + * broadcasting / etc */ +#define DBG_ROUTES 2 /* route or hna added / changed / deleted */ +#define DBG_ALL 3 + +#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ + + +/* + * Vis + */ + +/* #define VIS_SUBCLUSTERS_DISABLED */ + +/* + * Kernel headers + */ + +#include /* mutex */ +#include /* needed by all modules */ +#include /* netdevice */ +#include /* ethernet address classifaction */ +#include /* ethernet header */ +#include /* poll_table */ +#include /* kernel threads */ +#include /* schedule types */ +#include /* workqueue */ +#include +#include /* struct sock */ +#include +#include +#include "types.h" + +#ifndef REVISION_VERSION +#define REVISION_VERSION_STR "" +#else +#define REVISION_VERSION_STR " "REVISION_VERSION +#endif + +extern struct list_head if_list; + +extern unsigned char broadcast_addr[]; +extern struct workqueue_struct *bat_event_workqueue; + +int mesh_init(struct net_device *soft_iface); +void mesh_free(struct net_device *soft_iface); +void inc_module_count(void); +void dec_module_count(void); +int is_my_mac(uint8_t *addr); + +#ifdef CONFIG_BATMAN_ADV_DEBUG +int debug_log(struct bat_priv *bat_priv, char *fmt, ...); + +#define bat_dbg(type, bat_priv, fmt, arg...) \ + do { \ + if (atomic_read(&bat_priv->log_level) & type) \ + debug_log(bat_priv, fmt, ## arg); \ + } \ + while (0) +#else /* !CONFIG_BATMAN_ADV_DEBUG */ +static inline void bat_dbg(char type __attribute__((unused)), + struct bat_priv *bat_priv __attribute__((unused)), + char *fmt __attribute__((unused)), ...) +{ +} +#endif + +#define bat_warning(net_dev, fmt, arg...) \ + do { \ + struct net_device *_netdev = (net_dev); \ + struct bat_priv *_batpriv = netdev_priv(_netdev); \ + bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ + pr_warning("%s: " fmt, _netdev->name, ## arg); \ + } while (0) +#define bat_info(net_dev, fmt, arg...) \ + do { \ + struct net_device *_netdev = (net_dev); \ + struct bat_priv *_batpriv = netdev_priv(_netdev); \ + bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ + pr_info("%s: " fmt, _netdev->name, ## arg); \ + } while (0) +#define bat_err(net_dev, fmt, arg...) \ + do { \ + struct net_device *_netdev = (net_dev); \ + struct bat_priv *_batpriv = netdev_priv(_netdev); \ + bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ + pr_err("%s: " fmt, _netdev->name, ## arg); \ + } while (0) + +#endif /* _NET_BATMAN_ADV_MAIN_H_ */ diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c new file mode 100644 index 000000000000..6b7fb6b7e6f9 --- /dev/null +++ b/net/batman-adv/originator.c @@ -0,0 +1,564 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +/* increase the reference counter for this originator */ + +#include "main.h" +#include "originator.h" +#include "hash.h" +#include "translation-table.h" +#include "routing.h" +#include "gateway_client.h" +#include "hard-interface.h" +#include "unicast.h" +#include "soft-interface.h" + +static void purge_orig(struct work_struct *work); + +static void start_purge_timer(struct bat_priv *bat_priv) +{ + INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); + queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); +} + +int originator_init(struct bat_priv *bat_priv) +{ + if (bat_priv->orig_hash) + return 1; + + spin_lock_bh(&bat_priv->orig_hash_lock); + bat_priv->orig_hash = hash_new(1024); + + if (!bat_priv->orig_hash) + goto err; + + spin_unlock_bh(&bat_priv->orig_hash_lock); + start_purge_timer(bat_priv); + return 1; + +err: + spin_unlock_bh(&bat_priv->orig_hash_lock); + return 0; +} + +struct neigh_node * +create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, + uint8_t *neigh, struct batman_if *if_incoming) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct neigh_node *neigh_node; + + bat_dbg(DBG_BATMAN, bat_priv, + "Creating new last-hop neighbor of originator\n"); + + neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); + if (!neigh_node) + return NULL; + + INIT_LIST_HEAD(&neigh_node->list); + + memcpy(neigh_node->addr, neigh, ETH_ALEN); + neigh_node->orig_node = orig_neigh_node; + neigh_node->if_incoming = if_incoming; + + list_add_tail(&neigh_node->list, &orig_node->neigh_list); + return neigh_node; +} + +static void free_orig_node(void *data, void *arg) +{ + struct list_head *list_pos, *list_pos_tmp; + struct neigh_node *neigh_node; + struct orig_node *orig_node = (struct orig_node *)data; + struct bat_priv *bat_priv = (struct bat_priv *)arg; + + /* for all neighbors towards this originator ... */ + list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { + neigh_node = list_entry(list_pos, struct neigh_node, list); + + list_del(list_pos); + kfree(neigh_node); + } + + frag_list_free(&orig_node->frag_list); + hna_global_del_orig(bat_priv, orig_node, "originator timed out"); + + kfree(orig_node->bcast_own); + kfree(orig_node->bcast_own_sum); + kfree(orig_node); +} + +void originator_free(struct bat_priv *bat_priv) +{ + if (!bat_priv->orig_hash) + return; + + cancel_delayed_work_sync(&bat_priv->orig_work); + + spin_lock_bh(&bat_priv->orig_hash_lock); + hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv); + bat_priv->orig_hash = NULL; + spin_unlock_bh(&bat_priv->orig_hash_lock); +} + +/* this function finds or creates an originator entry for the given + * address if it does not exits */ +struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) +{ + struct orig_node *orig_node; + int size; + int hash_added; + + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, choose_orig, + addr)); + + if (orig_node) + return orig_node; + + bat_dbg(DBG_BATMAN, bat_priv, + "Creating new originator: %pM\n", addr); + + orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); + if (!orig_node) + return NULL; + + INIT_LIST_HEAD(&orig_node->neigh_list); + + memcpy(orig_node->orig, addr, ETH_ALEN); + orig_node->router = NULL; + orig_node->hna_buff = NULL; + orig_node->bcast_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS); + orig_node->batman_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS); + + size = bat_priv->num_ifaces * sizeof(unsigned long) * NUM_WORDS; + + orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); + if (!orig_node->bcast_own) + goto free_orig_node; + + size = bat_priv->num_ifaces * sizeof(uint8_t); + orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); + + INIT_LIST_HEAD(&orig_node->frag_list); + orig_node->last_frag_packet = 0; + + if (!orig_node->bcast_own_sum) + goto free_bcast_own; + + hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, + orig_node); + if (hash_added < 0) + goto free_bcast_own_sum; + + return orig_node; +free_bcast_own_sum: + kfree(orig_node->bcast_own_sum); +free_bcast_own: + kfree(orig_node->bcast_own); +free_orig_node: + kfree(orig_node); + return NULL; +} + +static bool purge_orig_neighbors(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct neigh_node **best_neigh_node) +{ + struct list_head *list_pos, *list_pos_tmp; + struct neigh_node *neigh_node; + bool neigh_purged = false; + + *best_neigh_node = NULL; + + /* for all neighbors towards this originator ... */ + list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { + neigh_node = list_entry(list_pos, struct neigh_node, list); + + if ((time_after(jiffies, + neigh_node->last_valid + PURGE_TIMEOUT * HZ)) || + (neigh_node->if_incoming->if_status == IF_INACTIVE) || + (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { + + if (neigh_node->if_incoming->if_status == + IF_TO_BE_REMOVED) + bat_dbg(DBG_BATMAN, bat_priv, + "neighbor purge: originator %pM, " + "neighbor: %pM, iface: %s\n", + orig_node->orig, neigh_node->addr, + neigh_node->if_incoming->net_dev->name); + else + bat_dbg(DBG_BATMAN, bat_priv, + "neighbor timeout: originator %pM, " + "neighbor: %pM, last_valid: %lu\n", + orig_node->orig, neigh_node->addr, + (neigh_node->last_valid / HZ)); + + neigh_purged = true; + list_del(list_pos); + kfree(neigh_node); + } else { + if ((!*best_neigh_node) || + (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) + *best_neigh_node = neigh_node; + } + } + return neigh_purged; +} + +static bool purge_orig_node(struct bat_priv *bat_priv, + struct orig_node *orig_node) +{ + struct neigh_node *best_neigh_node; + + if (time_after(jiffies, + orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) { + + bat_dbg(DBG_BATMAN, bat_priv, + "Originator timeout: originator %pM, last_valid %lu\n", + orig_node->orig, (orig_node->last_valid / HZ)); + return true; + } else { + if (purge_orig_neighbors(bat_priv, orig_node, + &best_neigh_node)) { + update_routes(bat_priv, orig_node, + best_neigh_node, + orig_node->hna_buff, + orig_node->hna_buff_len); + /* update bonding candidates, we could have lost + * some candidates. */ + update_bonding_candidates(bat_priv, orig_node); + } + } + + return false; +} + +static void _purge_orig(struct bat_priv *bat_priv) +{ + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk, *safe; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + int i; + + if (!hash) + return; + + spin_lock_bh(&bat_priv->orig_hash_lock); + + /* for all origins... */ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { + orig_node = bucket->data; + + if (purge_orig_node(bat_priv, orig_node)) { + if (orig_node->gw_flags) + gw_node_delete(bat_priv, orig_node); + hlist_del(walk); + kfree(bucket); + free_orig_node(orig_node, bat_priv); + } + + if (time_after(jiffies, orig_node->last_frag_packet + + msecs_to_jiffies(FRAG_TIMEOUT))) + frag_list_free(&orig_node->frag_list); + } + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + gw_node_purge(bat_priv); + gw_election(bat_priv); + + softif_neigh_purge(bat_priv); +} + +static void purge_orig(struct work_struct *work) +{ + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); + struct bat_priv *bat_priv = + container_of(delayed_work, struct bat_priv, orig_work); + + _purge_orig(bat_priv); + start_purge_timer(bat_priv); +} + +void purge_orig_ref(struct bat_priv *bat_priv) +{ + _purge_orig(bat_priv); +} + +int orig_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + struct neigh_node *neigh_node; + int batman_count = 0; + int last_seen_secs; + int last_seen_msecs; + int i; + + if ((!bat_priv->primary_if) || + (bat_priv->primary_if->if_status != IF_ACTIVE)) { + if (!bat_priv->primary_if) + return seq_printf(seq, "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); + + return seq_printf(seq, "BATMAN mesh %s " + "disabled - primary interface not active\n", + net_dev->name); + } + + seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", + SOURCE_VERSION, REVISION_VERSION_STR, + bat_priv->primary_if->net_dev->name, + bat_priv->primary_if->net_dev->dev_addr, net_dev->name); + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", + "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", + "outgoingIF", "Potential nexthops"); + + spin_lock_bh(&bat_priv->orig_hash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + + if (!orig_node->router) + continue; + + if (orig_node->router->tq_avg == 0) + continue; + + last_seen_secs = jiffies_to_msecs(jiffies - + orig_node->last_valid) / 1000; + last_seen_msecs = jiffies_to_msecs(jiffies - + orig_node->last_valid) % 1000; + + neigh_node = orig_node->router; + seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", + orig_node->orig, last_seen_secs, + last_seen_msecs, neigh_node->tq_avg, + neigh_node->addr, + neigh_node->if_incoming->net_dev->name); + + list_for_each_entry(neigh_node, &orig_node->neigh_list, + list) { + seq_printf(seq, " %pM (%3i)", neigh_node->addr, + neigh_node->tq_avg); + } + + seq_printf(seq, "\n"); + batman_count++; + } + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + if ((batman_count == 0)) + seq_printf(seq, "No batman nodes in range ...\n"); + + return 0; +} + +static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) +{ + void *data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, + GFP_ATOMIC); + if (!data_ptr) { + pr_err("Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own, + (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + pr_err("Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + (max_if_num - 1) * sizeof(uint8_t)); + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + int i; + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock_bh(&bat_priv->orig_hash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + + if (orig_node_add_if(orig_node, max_if_num) == -1) + goto err; + } + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); + return 0; + +err: + spin_unlock_bh(&bat_priv->orig_hash_lock); + return -ENOMEM; +} + +static int orig_node_del_if(struct orig_node *orig_node, + int max_if_num, int del_if_num) +{ + void *data_ptr = NULL; + int chunk_size; + + /* last interface was removed */ + if (max_if_num == 0) + goto free_bcast_own; + + chunk_size = sizeof(unsigned long) * NUM_WORDS; + data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); + if (!data_ptr) { + pr_err("Can't resize orig: out of memory\n"); + return -1; + } + + /* copy first part */ + memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); + + /* copy second part */ + memcpy(data_ptr + del_if_num * chunk_size, + orig_node->bcast_own + ((del_if_num + 1) * chunk_size), + (max_if_num - del_if_num) * chunk_size); + +free_bcast_own: + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + if (max_if_num == 0) + goto free_own_sum; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + pr_err("Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + del_if_num * sizeof(uint8_t)); + + memcpy(data_ptr + del_if_num * sizeof(uint8_t), + orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), + (max_if_num - del_if_num) * sizeof(uint8_t)); + +free_own_sum: + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct batman_if *batman_if_tmp; + struct orig_node *orig_node; + int i, ret; + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock_bh(&bat_priv->orig_hash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + + ret = orig_node_del_if(orig_node, max_if_num, + batman_if->if_num); + + if (ret == -1) + goto err; + } + } + + /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { + if (batman_if_tmp->if_status == IF_NOT_IN_USE) + continue; + + if (batman_if == batman_if_tmp) + continue; + + if (batman_if->soft_iface != batman_if_tmp->soft_iface) + continue; + + if (batman_if_tmp->if_num > batman_if->if_num) + batman_if_tmp->if_num--; + } + rcu_read_unlock(); + + batman_if->if_num = -1; + spin_unlock_bh(&bat_priv->orig_hash_lock); + return 0; + +err: + spin_unlock_bh(&bat_priv->orig_hash_lock); + return -ENOMEM; +} diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h new file mode 100644 index 000000000000..d474ceb2a4eb --- /dev/null +++ b/net/batman-adv/originator.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ +#define _NET_BATMAN_ADV_ORIGINATOR_H_ + +int originator_init(struct bat_priv *bat_priv); +void originator_free(struct bat_priv *bat_priv); +void purge_orig_ref(struct bat_priv *bat_priv); +struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr); +struct neigh_node * +create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, + uint8_t *neigh, struct batman_if *if_incoming); +int orig_seq_print_text(struct seq_file *seq, void *offset); +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); + + +/* returns 1 if they are the same originator */ +static inline int compare_orig(void *data1, void *data2) +{ + return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); +} + +/* hashfunction to choose an entry in a hash table of given size */ +/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ +static inline int choose_orig(void *data, int32_t size) +{ + unsigned char *key = data; + uint32_t hash = 0; + size_t i; + + for (i = 0; i < 6; i++) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash % size; +} + +#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */ diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h new file mode 100644 index 000000000000..b49fdf70a6d5 --- /dev/null +++ b/net/batman-adv/packet.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_PACKET_H_ +#define _NET_BATMAN_ADV_PACKET_H_ + +#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ + +#define BAT_PACKET 0x01 +#define BAT_ICMP 0x02 +#define BAT_UNICAST 0x03 +#define BAT_BCAST 0x04 +#define BAT_VIS 0x05 +#define BAT_UNICAST_FRAG 0x06 + +/* this file is included by batctl which needs these defines */ +#define COMPAT_VERSION 12 +#define DIRECTLINK 0x40 +#define VIS_SERVER 0x20 +#define PRIMARIES_FIRST_HOP 0x10 + +/* ICMP message types */ +#define ECHO_REPLY 0 +#define DESTINATION_UNREACHABLE 3 +#define ECHO_REQUEST 8 +#define TTL_EXCEEDED 11 +#define PARAMETER_PROBLEM 12 + +/* vis defines */ +#define VIS_TYPE_SERVER_SYNC 0 +#define VIS_TYPE_CLIENT_UPDATE 1 + +/* fragmentation defines */ +#define UNI_FRAG_HEAD 0x01 + +struct batman_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ + uint8_t tq; + uint32_t seqno; + uint8_t orig[6]; + uint8_t prev_sender[6]; + uint8_t ttl; + uint8_t num_hna; + uint8_t gw_flags; /* flags related to gateway class */ + uint8_t align; +} __attribute__((packed)); + +#define BAT_PACKET_LEN sizeof(struct batman_packet) + +struct icmp_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t msg_type; /* see ICMP message types above */ + uint8_t ttl; + uint8_t dst[6]; + uint8_t orig[6]; + uint16_t seqno; + uint8_t uid; +} __attribute__((packed)); + +#define BAT_RR_LEN 16 + +/* icmp_packet_rr must start with all fields from imcp_packet + * as this is assumed by code that handles ICMP packets */ +struct icmp_packet_rr { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t msg_type; /* see ICMP message types above */ + uint8_t ttl; + uint8_t dst[6]; + uint8_t orig[6]; + uint16_t seqno; + uint8_t uid; + uint8_t rr_cur; + uint8_t rr[BAT_RR_LEN][ETH_ALEN]; +} __attribute__((packed)); + +struct unicast_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t dest[6]; + uint8_t ttl; +} __attribute__((packed)); + +struct unicast_frag_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t dest[6]; + uint8_t ttl; + uint8_t flags; + uint8_t orig[6]; + uint16_t seqno; +} __attribute__((packed)); + +struct bcast_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t orig[6]; + uint8_t ttl; + uint32_t seqno; +} __attribute__((packed)); + +struct vis_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t vis_type; /* which type of vis-participant sent this? */ + uint8_t entries; /* number of entries behind this struct */ + uint32_t seqno; /* sequence number */ + uint8_t ttl; /* TTL */ + uint8_t vis_orig[6]; /* originator that informs about its + * neighbors */ + uint8_t target_orig[6]; /* who should receive this packet */ + uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ +} __attribute__((packed)); + +#endif /* _NET_BATMAN_ADV_PACKET_H_ */ diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c new file mode 100644 index 000000000000..defd37c9be1f --- /dev/null +++ b/net/batman-adv/ring_buffer.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "ring_buffer.h" + +void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) +{ + lq_recv[*lq_index] = value; + *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; +} + +uint8_t ring_buffer_avg(uint8_t lq_recv[]) +{ + uint8_t *ptr; + uint16_t count = 0, i = 0, sum = 0; + + ptr = lq_recv; + + while (i < TQ_GLOBAL_WINDOW_SIZE) { + if (*ptr != 0) { + count++; + sum += *ptr; + } + + i++; + ptr++; + } + + if (count == 0) + return 0; + + return (uint8_t)(sum / count); +} diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h new file mode 100644 index 000000000000..6b0cb9aaeba5 --- /dev/null +++ b/net/batman-adv/ring_buffer.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_ +#define _NET_BATMAN_ADV_RING_BUFFER_H_ + +void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value); +uint8_t ring_buffer_avg(uint8_t lq_recv[]); + +#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c new file mode 100644 index 000000000000..8828eddd3f72 --- /dev/null +++ b/net/batman-adv/routing.c @@ -0,0 +1,1397 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "routing.h" +#include "send.h" +#include "hash.h" +#include "soft-interface.h" +#include "hard-interface.h" +#include "icmp_socket.h" +#include "translation-table.h" +#include "originator.h" +#include "types.h" +#include "ring_buffer.h" +#include "vis.h" +#include "aggregation.h" +#include "gateway_common.h" +#include "gateway_client.h" +#include "unicast.h" + +void slide_own_bcast_window(struct batman_if *batman_if) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + unsigned long *word; + int i; + size_t word_index; + + spin_lock_bh(&bat_priv->orig_hash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + word_index = batman_if->if_num * NUM_WORDS; + word = &(orig_node->bcast_own[word_index]); + + bit_get_packet(bat_priv, word, 1, 0); + orig_node->bcast_own_sum[batman_if->if_num] = + bit_packet_count(word); + } + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); +} + +static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, + unsigned char *hna_buff, int hna_buff_len) +{ + if ((hna_buff_len != orig_node->hna_buff_len) || + ((hna_buff_len > 0) && + (orig_node->hna_buff_len > 0) && + (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { + + if (orig_node->hna_buff_len > 0) + hna_global_del_orig(bat_priv, orig_node, + "originator changed hna"); + + if ((hna_buff_len > 0) && (hna_buff)) + hna_global_add_orig(bat_priv, orig_node, + hna_buff, hna_buff_len); + } +} + +static void update_route(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct neigh_node *neigh_node, + unsigned char *hna_buff, int hna_buff_len) +{ + /* route deleted */ + if ((orig_node->router) && (!neigh_node)) { + + bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", + orig_node->orig); + hna_global_del_orig(bat_priv, orig_node, + "originator timed out"); + + /* route added */ + } else if ((!orig_node->router) && (neigh_node)) { + + bat_dbg(DBG_ROUTES, bat_priv, + "Adding route towards: %pM (via %pM)\n", + orig_node->orig, neigh_node->addr); + hna_global_add_orig(bat_priv, orig_node, + hna_buff, hna_buff_len); + + /* route changed */ + } else { + bat_dbg(DBG_ROUTES, bat_priv, + "Changing route towards: %pM " + "(now via %pM - was via %pM)\n", + orig_node->orig, neigh_node->addr, + orig_node->router->addr); + } + + orig_node->router = neigh_node; +} + + +void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, + struct neigh_node *neigh_node, unsigned char *hna_buff, + int hna_buff_len) +{ + + if (!orig_node) + return; + + if (orig_node->router != neigh_node) + update_route(bat_priv, orig_node, neigh_node, + hna_buff, hna_buff_len); + /* may be just HNA changed */ + else + update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len); +} + +static int is_bidirectional_neigh(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + struct batman_packet *batman_packet, + struct batman_if *if_incoming) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; + unsigned char total_count; + + if (orig_node == orig_neigh_node) { + list_for_each_entry(tmp_neigh_node, + &orig_node->neigh_list, + list) { + + if (compare_orig(tmp_neigh_node->addr, + orig_neigh_node->orig) && + (tmp_neigh_node->if_incoming == if_incoming)) + neigh_node = tmp_neigh_node; + } + + if (!neigh_node) + neigh_node = create_neighbor(orig_node, + orig_neigh_node, + orig_neigh_node->orig, + if_incoming); + /* create_neighbor failed, return 0 */ + if (!neigh_node) + return 0; + + neigh_node->last_valid = jiffies; + } else { + /* find packet count of corresponding one hop neighbor */ + list_for_each_entry(tmp_neigh_node, + &orig_neigh_node->neigh_list, list) { + + if (compare_orig(tmp_neigh_node->addr, + orig_neigh_node->orig) && + (tmp_neigh_node->if_incoming == if_incoming)) + neigh_node = tmp_neigh_node; + } + + if (!neigh_node) + neigh_node = create_neighbor(orig_neigh_node, + orig_neigh_node, + orig_neigh_node->orig, + if_incoming); + /* create_neighbor failed, return 0 */ + if (!neigh_node) + return 0; + } + + orig_node->last_valid = jiffies; + + /* pay attention to not get a value bigger than 100 % */ + total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > + neigh_node->real_packet_count ? + neigh_node->real_packet_count : + orig_neigh_node->bcast_own_sum[if_incoming->if_num]); + + /* if we have too few packets (too less data) we set tq_own to zero */ + /* if we receive too few packets it is not considered bidirectional */ + if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || + (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) + orig_neigh_node->tq_own = 0; + else + /* neigh_node->real_packet_count is never zero as we + * only purge old information when getting new + * information */ + orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / + neigh_node->real_packet_count; + + /* + * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does + * affect the nearly-symmetric links only a little, but + * punishes asymmetric links more. This will give a value + * between 0 and TQ_MAX_VALUE + */ + orig_neigh_node->tq_asym_penalty = + TQ_MAX_VALUE - + (TQ_MAX_VALUE * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / + (TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE); + + batman_packet->tq = ((batman_packet->tq * + orig_neigh_node->tq_own * + orig_neigh_node->tq_asym_penalty) / + (TQ_MAX_VALUE * TQ_MAX_VALUE)); + + bat_dbg(DBG_BATMAN, bat_priv, + "bidirectional: " + "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " + "real recv = %2i, local tq: %3i, asym_penalty: %3i, " + "total tq: %3i\n", + orig_node->orig, orig_neigh_node->orig, total_count, + neigh_node->real_packet_count, orig_neigh_node->tq_own, + orig_neigh_node->tq_asym_penalty, batman_packet->tq); + + /* if link has the minimum required transmission quality + * consider it bidirectional */ + if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) + return 1; + + return 0; +} + +static void update_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + struct batman_if *if_incoming, + unsigned char *hna_buff, int hna_buff_len, + char is_duplicate) +{ + struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; + int tmp_hna_buff_len; + + bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " + "Searching and updating originator entry of received packet\n"); + + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && + (tmp_neigh_node->if_incoming == if_incoming)) { + neigh_node = tmp_neigh_node; + continue; + } + + if (is_duplicate) + continue; + + ring_buffer_set(tmp_neigh_node->tq_recv, + &tmp_neigh_node->tq_index, 0); + tmp_neigh_node->tq_avg = + ring_buffer_avg(tmp_neigh_node->tq_recv); + } + + if (!neigh_node) { + struct orig_node *orig_tmp; + + orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); + if (!orig_tmp) + return; + + neigh_node = create_neighbor(orig_node, orig_tmp, + ethhdr->h_source, if_incoming); + if (!neigh_node) + return; + } else + bat_dbg(DBG_BATMAN, bat_priv, + "Updating existing last-hop neighbor of originator\n"); + + orig_node->flags = batman_packet->flags; + neigh_node->last_valid = jiffies; + + ring_buffer_set(neigh_node->tq_recv, + &neigh_node->tq_index, + batman_packet->tq); + neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); + + if (!is_duplicate) { + orig_node->last_ttl = batman_packet->ttl; + neigh_node->last_ttl = batman_packet->ttl; + } + + tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? + batman_packet->num_hna * ETH_ALEN : hna_buff_len); + + /* if this neighbor already is our next hop there is nothing + * to change */ + if (orig_node->router == neigh_node) + goto update_hna; + + /* if this neighbor does not offer a better TQ we won't consider it */ + if ((orig_node->router) && + (orig_node->router->tq_avg > neigh_node->tq_avg)) + goto update_hna; + + /* if the TQ is the same and the link not more symetric we + * won't consider it either */ + if ((orig_node->router) && + ((neigh_node->tq_avg == orig_node->router->tq_avg) && + (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] + >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) + goto update_hna; + + update_routes(bat_priv, orig_node, neigh_node, + hna_buff, tmp_hna_buff_len); + goto update_gw; + +update_hna: + update_routes(bat_priv, orig_node, orig_node->router, + hna_buff, tmp_hna_buff_len); + +update_gw: + if (orig_node->gw_flags != batman_packet->gw_flags) + gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); + + orig_node->gw_flags = batman_packet->gw_flags; + + /* restart gateway selection if fast or late switching was enabled */ + if ((orig_node->gw_flags) && + (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && + (atomic_read(&bat_priv->gw_sel_class) > 2)) + gw_check_election(bat_priv, orig_node); +} + +/* checks whether the host restarted and is in the protection time. + * returns: + * 0 if the packet is to be accepted + * 1 if the packet is to be ignored. + */ +static int window_protected(struct bat_priv *bat_priv, + int32_t seq_num_diff, + unsigned long *last_reset) +{ + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + if (time_after(jiffies, *last_reset + + msecs_to_jiffies(RESET_PROTECTION_MS))) { + + *last_reset = jiffies; + bat_dbg(DBG_BATMAN, bat_priv, + "old packet received, start protection\n"); + + return 0; + } else + return 1; + } + return 0; +} + +/* processes a batman packet for all interfaces, adjusts the sequence number and + * finds out whether it is a duplicate. + * returns: + * 1 the packet is a duplicate + * 0 the packet has not yet been received + * -1 the packet is old and has been received while the seqno window + * was protected. Caller should drop it. + */ +static char count_real_packets(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + struct batman_if *if_incoming) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct orig_node *orig_node; + struct neigh_node *tmp_neigh_node; + char is_duplicate = 0; + int32_t seq_diff; + int need_update = 0; + int set_mark; + + orig_node = get_orig_node(bat_priv, batman_packet->orig); + if (!orig_node) + return 0; + + seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + + /* signalize caller that the packet is to be dropped. */ + if (window_protected(bat_priv, seq_diff, + &orig_node->batman_seqno_reset)) + return -1; + + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { + + is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, + orig_node->last_real_seqno, + batman_packet->seqno); + + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && + (tmp_neigh_node->if_incoming == if_incoming)) + set_mark = 1; + else + set_mark = 0; + + /* if the window moved, set the update flag. */ + need_update |= bit_get_packet(bat_priv, + tmp_neigh_node->real_bits, + seq_diff, set_mark); + + tmp_neigh_node->real_packet_count = + bit_packet_count(tmp_neigh_node->real_bits); + } + + if (need_update) { + bat_dbg(DBG_BATMAN, bat_priv, + "updating last_seqno: old %d, new %d\n", + orig_node->last_real_seqno, batman_packet->seqno); + orig_node->last_real_seqno = batman_packet->seqno; + } + + return is_duplicate; +} + +/* copy primary address for bonding */ +static void mark_bonding_address(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + struct batman_packet *batman_packet) + +{ + if (batman_packet->flags & PRIMARIES_FIRST_HOP) + memcpy(orig_neigh_node->primary_addr, + orig_node->orig, ETH_ALEN); + + return; +} + +/* mark possible bond.candidates in the neighbor list */ +void update_bonding_candidates(struct bat_priv *bat_priv, + struct orig_node *orig_node) +{ + int candidates; + int interference_candidate; + int best_tq; + struct neigh_node *tmp_neigh_node, *tmp_neigh_node2; + struct neigh_node *first_candidate, *last_candidate; + + /* update the candidates for this originator */ + if (!orig_node->router) { + orig_node->bond.candidates = 0; + return; + } + + best_tq = orig_node->router->tq_avg; + + /* update bond.candidates */ + + candidates = 0; + + /* mark other nodes which also received "PRIMARIES FIRST HOP" packets + * as "bonding partner" */ + + /* first, zero the list */ + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { + tmp_neigh_node->next_bond_candidate = NULL; + } + + first_candidate = NULL; + last_candidate = NULL; + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { + + /* only consider if it has the same primary address ... */ + if (memcmp(orig_node->orig, + tmp_neigh_node->orig_node->primary_addr, + ETH_ALEN) != 0) + continue; + + /* ... and is good enough to be considered */ + if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) + continue; + + /* check if we have another candidate with the same + * mac address or interface. If we do, we won't + * select this candidate because of possible interference. */ + + interference_candidate = 0; + list_for_each_entry(tmp_neigh_node2, + &orig_node->neigh_list, list) { + + if (tmp_neigh_node2 == tmp_neigh_node) + continue; + + /* we only care if the other candidate is even + * considered as candidate. */ + if (!tmp_neigh_node2->next_bond_candidate) + continue; + + + if ((tmp_neigh_node->if_incoming == + tmp_neigh_node2->if_incoming) + || (memcmp(tmp_neigh_node->addr, + tmp_neigh_node2->addr, ETH_ALEN) == 0)) { + + interference_candidate = 1; + break; + } + } + /* don't care further if it is an interference candidate */ + if (interference_candidate) + continue; + + if (!first_candidate) { + first_candidate = tmp_neigh_node; + tmp_neigh_node->next_bond_candidate = first_candidate; + } else + tmp_neigh_node->next_bond_candidate = last_candidate; + + last_candidate = tmp_neigh_node; + + candidates++; + } + + if (candidates > 0) { + first_candidate->next_bond_candidate = last_candidate; + orig_node->bond.selected = first_candidate; + } + + orig_node->bond.candidates = candidates; +} + +void receive_bat_packet(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + unsigned char *hna_buff, int hna_buff_len, + struct batman_if *if_incoming) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct batman_if *batman_if; + struct orig_node *orig_neigh_node, *orig_node; + char has_directlink_flag; + char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; + char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; + char is_duplicate; + uint32_t if_incoming_seqno; + + /* Silently drop when the batman packet is actually not a + * correct packet. + * + * This might happen if a packet is padded (e.g. Ethernet has a + * minimum frame length of 64 byte) and the aggregation interprets + * it as an additional length. + * + * TODO: A more sane solution would be to have a bit in the + * batman_packet to detect whether the packet is the last + * packet in an aggregation. Here we expect that the padding + * is always zero (or not 0x01) + */ + if (batman_packet->packet_type != BAT_PACKET) + return; + + /* could be changed by schedule_own_packet() */ + if_incoming_seqno = atomic_read(&if_incoming->seqno); + + has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); + + is_single_hop_neigh = (compare_orig(ethhdr->h_source, + batman_packet->orig) ? 1 : 0); + + bat_dbg(DBG_BATMAN, bat_priv, + "Received BATMAN packet via NB: %pM, IF: %s [%pM] " + "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " + "TTL %d, V %d, IDF %d)\n", + ethhdr->h_source, if_incoming->net_dev->name, + if_incoming->net_dev->dev_addr, batman_packet->orig, + batman_packet->prev_sender, batman_packet->seqno, + batman_packet->tq, batman_packet->ttl, batman_packet->version, + has_directlink_flag); + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->if_status != IF_ACTIVE) + continue; + + if (batman_if->soft_iface != if_incoming->soft_iface) + continue; + + if (compare_orig(ethhdr->h_source, + batman_if->net_dev->dev_addr)) + is_my_addr = 1; + + if (compare_orig(batman_packet->orig, + batman_if->net_dev->dev_addr)) + is_my_orig = 1; + + if (compare_orig(batman_packet->prev_sender, + batman_if->net_dev->dev_addr)) + is_my_oldorig = 1; + + if (compare_orig(ethhdr->h_source, broadcast_addr)) + is_broadcast = 1; + } + rcu_read_unlock(); + + if (batman_packet->version != COMPAT_VERSION) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_packet->version); + return; + } + + if (is_my_addr) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: received my own broadcast (sender: %pM" + ")\n", + ethhdr->h_source); + return; + } + + if (is_broadcast) { + bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " + "ignoring all packets with broadcast source addr (sender: %pM" + ")\n", ethhdr->h_source); + return; + } + + if (is_my_orig) { + unsigned long *word; + int offset; + + orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); + + if (!orig_neigh_node) + return; + + /* neighbor has to indicate direct link and it has to + * come via the corresponding interface */ + /* if received seqno equals last send seqno save new + * seqno for bidirectional check */ + if (has_directlink_flag && + compare_orig(if_incoming->net_dev->dev_addr, + batman_packet->orig) && + (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { + offset = if_incoming->if_num * NUM_WORDS; + word = &(orig_neigh_node->bcast_own[offset]); + bit_mark(word, 0); + orig_neigh_node->bcast_own_sum[if_incoming->if_num] = + bit_packet_count(word); + } + + bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " + "originator packet from myself (via neighbor)\n"); + return; + } + + if (is_my_oldorig) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all rebroadcast echos (sender: " + "%pM)\n", ethhdr->h_source); + return; + } + + orig_node = get_orig_node(bat_priv, batman_packet->orig); + if (!orig_node) + return; + + is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); + + if (is_duplicate == -1) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: packet within seqno protection time " + "(sender: %pM)\n", ethhdr->h_source); + return; + } + + if (batman_packet->tq == 0) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: originator packet with tq equal 0\n"); + return; + } + + /* avoid temporary routing loops */ + if ((orig_node->router) && + (orig_node->router->orig_node->router) && + (compare_orig(orig_node->router->addr, + batman_packet->prev_sender)) && + !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && + (compare_orig(orig_node->router->addr, + orig_node->router->orig_node->router->addr))) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all rebroadcast packets that " + "may make me loop (sender: %pM)\n", ethhdr->h_source); + return; + } + + /* if sender is a direct neighbor the sender mac equals + * originator mac */ + orig_neigh_node = (is_single_hop_neigh ? + orig_node : + get_orig_node(bat_priv, ethhdr->h_source)); + if (!orig_neigh_node) + return; + + /* drop packet if sender is not a direct neighbor and if we + * don't route towards it */ + if (!is_single_hop_neigh && (!orig_neigh_node->router)) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: OGM via unknown neighbor!\n"); + return; + } + + is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node, + batman_packet, if_incoming); + + /* update ranking if it is not a duplicate or has the same + * seqno and similar ttl as the non-duplicate */ + if (is_bidirectional && + (!is_duplicate || + ((orig_node->last_real_seqno == batman_packet->seqno) && + (orig_node->last_ttl - 3 <= batman_packet->ttl)))) + update_orig(bat_priv, orig_node, ethhdr, batman_packet, + if_incoming, hna_buff, hna_buff_len, is_duplicate); + + mark_bonding_address(bat_priv, orig_node, + orig_neigh_node, batman_packet); + update_bonding_candidates(bat_priv, orig_node); + + /* is single hop (direct) neighbor */ + if (is_single_hop_neigh) { + + /* mark direct link on incoming interface */ + schedule_forward_packet(orig_node, ethhdr, batman_packet, + 1, hna_buff_len, if_incoming); + + bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " + "rebroadcast neighbor packet with direct link flag\n"); + return; + } + + /* multihop originator */ + if (!is_bidirectional) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: not received via bidirectional link\n"); + return; + } + + if (is_duplicate) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: duplicate packet received\n"); + return; + } + + bat_dbg(DBG_BATMAN, bat_priv, + "Forwarding packet: rebroadcast originator packet\n"); + schedule_forward_packet(orig_node, ethhdr, batman_packet, + 0, hna_buff_len, if_incoming); +} + +int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + struct ethhdr *ethhdr; + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet)))) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with broadcast indication but unicast recipient */ + if (!is_broadcast_ether_addr(ethhdr->h_dest)) + return NET_RX_DROP; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return NET_RX_DROP; + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, 0) < 0) + return NET_RX_DROP; + + /* keep skb linear */ + if (skb_linearize(skb) < 0) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + spin_lock_bh(&bat_priv->orig_hash_lock); + receive_aggr_bat_packet(ethhdr, + skb->data, + skb_headlen(skb), + batman_if); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + kfree_skb(skb); + return NET_RX_SUCCESS; +} + +static int recv_my_icmp_packet(struct bat_priv *bat_priv, + struct sk_buff *skb, size_t icmp_len) +{ + struct orig_node *orig_node; + struct icmp_packet_rr *icmp_packet; + struct ethhdr *ethhdr; + struct batman_if *batman_if; + int ret; + uint8_t dstaddr[ETH_ALEN]; + + icmp_packet = (struct icmp_packet_rr *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* add data to device queue */ + if (icmp_packet->msg_type != ECHO_REQUEST) { + bat_socket_receive_packet(icmp_packet, icmp_len); + return NET_RX_DROP; + } + + if (!bat_priv->primary_if) + return NET_RX_DROP; + + /* answer echo request (ping) */ + /* get routing information */ + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, choose_orig, + icmp_packet->orig)); + ret = NET_RX_DROP; + + if ((orig_node) && (orig_node->router)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, sizeof(struct ethhdr)) < 0) + return NET_RX_DROP; + + icmp_packet = (struct icmp_packet_rr *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); + memcpy(icmp_packet->orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + icmp_packet->msg_type = ECHO_REPLY; + icmp_packet->ttl = TTL; + + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; + + } else + spin_unlock_bh(&bat_priv->orig_hash_lock); + + return ret; +} + +static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, + struct sk_buff *skb, size_t icmp_len) +{ + struct orig_node *orig_node; + struct icmp_packet *icmp_packet; + struct ethhdr *ethhdr; + struct batman_if *batman_if; + int ret; + uint8_t dstaddr[ETH_ALEN]; + + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* send TTL exceeded if packet is an echo request (traceroute) */ + if (icmp_packet->msg_type != ECHO_REQUEST) { + pr_debug("Warning - can't forward icmp packet from %pM to " + "%pM: ttl exceeded\n", icmp_packet->orig, + icmp_packet->dst); + return NET_RX_DROP; + } + + if (!bat_priv->primary_if) + return NET_RX_DROP; + + /* get routing information */ + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, + icmp_packet->orig)); + ret = NET_RX_DROP; + + if ((orig_node) && (orig_node->router)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, sizeof(struct ethhdr)) < 0) + return NET_RX_DROP; + + icmp_packet = (struct icmp_packet *) skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); + memcpy(icmp_packet->orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + icmp_packet->msg_type = TTL_EXCEEDED; + icmp_packet->ttl = TTL; + + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; + + } else + spin_unlock_bh(&bat_priv->orig_hash_lock); + + return ret; +} + + +int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct icmp_packet_rr *icmp_packet; + struct ethhdr *ethhdr; + struct orig_node *orig_node; + struct batman_if *batman_if; + int hdr_size = sizeof(struct icmp_packet); + int ret; + uint8_t dstaddr[ETH_ALEN]; + + /** + * we truncate all incoming icmp packets if they don't match our size + */ + if (skb->len >= sizeof(struct icmp_packet_rr)) + hdr_size = sizeof(struct icmp_packet_rr); + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with unicast indication but broadcast recipient */ + if (is_broadcast_ether_addr(ethhdr->h_dest)) + return NET_RX_DROP; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return NET_RX_DROP; + + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return NET_RX_DROP; + + icmp_packet = (struct icmp_packet_rr *)skb->data; + + /* add record route information if not full */ + if ((hdr_size == sizeof(struct icmp_packet_rr)) && + (icmp_packet->rr_cur < BAT_RR_LEN)) { + memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), + ethhdr->h_dest, ETH_ALEN); + icmp_packet->rr_cur++; + } + + /* packet for me */ + if (is_my_mac(icmp_packet->dst)) + return recv_my_icmp_packet(bat_priv, skb, hdr_size); + + /* TTL exceeded */ + if (icmp_packet->ttl < 2) + return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size); + + ret = NET_RX_DROP; + + /* get routing information */ + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, + icmp_packet->dst)); + + if ((orig_node) && (orig_node->router)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, sizeof(struct ethhdr)) < 0) + return NET_RX_DROP; + + icmp_packet = (struct icmp_packet_rr *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* decrement ttl */ + icmp_packet->ttl--; + + /* route it */ + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; + + } else + spin_unlock_bh(&bat_priv->orig_hash_lock); + + return ret; +} + +/* find a suitable router for this originator, and use + * bonding if possible. */ +struct neigh_node *find_router(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct batman_if *recv_if) +{ + struct orig_node *primary_orig_node; + struct orig_node *router_orig; + struct neigh_node *router, *first_candidate, *best_router; + static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + int bonding_enabled; + + if (!orig_node) + return NULL; + + if (!orig_node->router) + return NULL; + + /* without bonding, the first node should + * always choose the default router. */ + + bonding_enabled = atomic_read(&bat_priv->bonding); + + if ((!recv_if) && (!bonding_enabled)) + return orig_node->router; + + router_orig = orig_node->router->orig_node; + + /* if we have something in the primary_addr, we can search + * for a potential bonding candidate. */ + if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0) + return orig_node->router; + + /* find the orig_node which has the primary interface. might + * even be the same as our router_orig in many cases */ + + if (memcmp(router_orig->primary_addr, + router_orig->orig, ETH_ALEN) == 0) { + primary_orig_node = router_orig; + } else { + primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, + choose_orig, + router_orig->primary_addr); + + if (!primary_orig_node) + return orig_node->router; + } + + /* with less than 2 candidates, we can't do any + * bonding and prefer the original router. */ + + if (primary_orig_node->bond.candidates < 2) + return orig_node->router; + + + /* all nodes between should choose a candidate which + * is is not on the interface where the packet came + * in. */ + first_candidate = primary_orig_node->bond.selected; + router = first_candidate; + + if (bonding_enabled) { + /* in the bonding case, send the packets in a round + * robin fashion over the remaining interfaces. */ + do { + /* recv_if == NULL on the first node. */ + if (router->if_incoming != recv_if) + break; + + router = router->next_bond_candidate; + } while (router != first_candidate); + + primary_orig_node->bond.selected = router->next_bond_candidate; + + } else { + /* if bonding is disabled, use the best of the + * remaining candidates which are not using + * this interface. */ + best_router = first_candidate; + + do { + /* recv_if == NULL on the first node. */ + if ((router->if_incoming != recv_if) && + (router->tq_avg > best_router->tq_avg)) + best_router = router; + + router = router->next_bond_candidate; + } while (router != first_candidate); + + router = best_router; + } + + return router; +} + +static int check_unicast_packet(struct sk_buff *skb, int hdr_size) +{ + struct ethhdr *ethhdr; + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return -1; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with unicast indication but broadcast recipient */ + if (is_broadcast_ether_addr(ethhdr->h_dest)) + return -1; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return -1; + + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return -1; + + return 0; +} + +int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size) +{ + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct orig_node *orig_node; + struct neigh_node *router; + struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; + struct unicast_packet *unicast_packet; + struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); + int ret; + struct sk_buff *new_skb; + + unicast_packet = (struct unicast_packet *)skb->data; + + /* TTL exceeded */ + if (unicast_packet->ttl < 2) { + pr_debug("Warning - can't forward unicast packet from %pM to " + "%pM: ttl exceeded\n", ethhdr->h_source, + unicast_packet->dest); + return NET_RX_DROP; + } + + /* get routing information */ + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, + unicast_packet->dest)); + + router = find_router(bat_priv, orig_node, recv_if); + + if (!router) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return NET_RX_DROP; + } + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + + batman_if = router->if_incoming; + memcpy(dstaddr, router->addr, ETH_ALEN); + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, sizeof(struct ethhdr)) < 0) + return NET_RX_DROP; + + unicast_packet = (struct unicast_packet *)skb->data; + + if (unicast_packet->packet_type == BAT_UNICAST && + atomic_read(&bat_priv->fragmentation) && + skb->len > batman_if->net_dev->mtu) + return frag_send_skb(skb, bat_priv, batman_if, + dstaddr); + + if (unicast_packet->packet_type == BAT_UNICAST_FRAG && + 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) { + + ret = frag_reassemble_skb(skb, bat_priv, &new_skb); + + if (ret == NET_RX_DROP) + return NET_RX_DROP; + + /* packet was buffered for late merge */ + if (!new_skb) + return NET_RX_SUCCESS; + + skb = new_skb; + unicast_packet = (struct unicast_packet *)skb->data; + } + + /* decrement ttl */ + unicast_packet->ttl--; + + /* route it */ + send_skb_packet(skb, batman_if, dstaddr); + + return NET_RX_SUCCESS; +} + +int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct unicast_packet *unicast_packet; + int hdr_size = sizeof(struct unicast_packet); + + if (check_unicast_packet(skb, hdr_size) < 0) + return NET_RX_DROP; + + unicast_packet = (struct unicast_packet *)skb->data; + + /* packet for me */ + if (is_my_mac(unicast_packet->dest)) { + interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + return NET_RX_SUCCESS; + } + + return route_unicast_packet(skb, recv_if, hdr_size); +} + +int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct unicast_frag_packet *unicast_packet; + int hdr_size = sizeof(struct unicast_frag_packet); + struct sk_buff *new_skb = NULL; + int ret; + + if (check_unicast_packet(skb, hdr_size) < 0) + return NET_RX_DROP; + + unicast_packet = (struct unicast_frag_packet *)skb->data; + + /* packet for me */ + if (is_my_mac(unicast_packet->dest)) { + + ret = frag_reassemble_skb(skb, bat_priv, &new_skb); + + if (ret == NET_RX_DROP) + return NET_RX_DROP; + + /* packet was buffered for late merge */ + if (!new_skb) + return NET_RX_SUCCESS; + + interface_rx(recv_if->soft_iface, new_skb, recv_if, + sizeof(struct unicast_packet)); + return NET_RX_SUCCESS; + } + + return route_unicast_packet(skb, recv_if, hdr_size); +} + + +int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct orig_node *orig_node; + struct bcast_packet *bcast_packet; + struct ethhdr *ethhdr; + int hdr_size = sizeof(struct bcast_packet); + int32_t seq_diff; + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with broadcast indication but unicast recipient */ + if (!is_broadcast_ether_addr(ethhdr->h_dest)) + return NET_RX_DROP; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return NET_RX_DROP; + + /* ignore broadcasts sent by myself */ + if (is_my_mac(ethhdr->h_source)) + return NET_RX_DROP; + + bcast_packet = (struct bcast_packet *)skb->data; + + /* ignore broadcasts originated by myself */ + if (is_my_mac(bcast_packet->orig)) + return NET_RX_DROP; + + if (bcast_packet->ttl < 2) + return NET_RX_DROP; + + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, + bcast_packet->orig)); + + if (!orig_node) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return NET_RX_DROP; + } + + /* check whether the packet is a duplicate */ + if (get_bit_status(orig_node->bcast_bits, + orig_node->last_bcast_seqno, + ntohl(bcast_packet->seqno))) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return NET_RX_DROP; + } + + seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; + + /* check whether the packet is old and the host just restarted. */ + if (window_protected(bat_priv, seq_diff, + &orig_node->bcast_seqno_reset)) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return NET_RX_DROP; + } + + /* mark broadcast in flood history, update window position + * if required. */ + if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) + orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); + + spin_unlock_bh(&bat_priv->orig_hash_lock); + /* rebroadcast packet */ + add_bcast_packet_to_list(bat_priv, skb); + + /* broadcast for me */ + interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + + return NET_RX_SUCCESS; +} + +int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct vis_packet *vis_packet; + struct ethhdr *ethhdr; + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + int hdr_size = sizeof(struct vis_packet); + + /* keep skb linear */ + if (skb_linearize(skb) < 0) + return NET_RX_DROP; + + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return NET_RX_DROP; + + vis_packet = (struct vis_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return NET_RX_DROP; + + /* ignore own packets */ + if (is_my_mac(vis_packet->vis_orig)) + return NET_RX_DROP; + + if (is_my_mac(vis_packet->sender_orig)) + return NET_RX_DROP; + + switch (vis_packet->vis_type) { + case VIS_TYPE_SERVER_SYNC: + receive_server_sync_packet(bat_priv, vis_packet, + skb_headlen(skb)); + break; + + case VIS_TYPE_CLIENT_UPDATE: + receive_client_update_packet(bat_priv, vis_packet, + skb_headlen(skb)); + break; + + default: /* ignore unknown packet */ + break; + } + + /* We take a copy of the data in the packet, so we should + always free the skbuf. */ + return NET_RX_DROP; +} diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h new file mode 100644 index 000000000000..f108f230bfdb --- /dev/null +++ b/net/batman-adv/routing.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_ROUTING_H_ +#define _NET_BATMAN_ADV_ROUTING_H_ + +#include "types.h" + +void slide_own_bcast_window(struct batman_if *batman_if); +void receive_bat_packet(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + unsigned char *hna_buff, int hna_buff_len, + struct batman_if *if_incoming); +void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, + struct neigh_node *neigh_node, unsigned char *hna_buff, + int hna_buff_len); +int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size); +int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if); +struct neigh_node *find_router(struct bat_priv *bat_priv, + struct orig_node *orig_node, struct batman_if *recv_if); +void update_bonding_candidates(struct bat_priv *bat_priv, + struct orig_node *orig_node); + +#endif /* _NET_BATMAN_ADV_ROUTING_H_ */ diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c new file mode 100644 index 000000000000..b89b9f7709ae --- /dev/null +++ b/net/batman-adv/send.c @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "send.h" +#include "routing.h" +#include "translation-table.h" +#include "soft-interface.h" +#include "hard-interface.h" +#include "types.h" +#include "vis.h" +#include "aggregation.h" +#include "gateway_common.h" +#include "originator.h" + +static void send_outstanding_bcast_packet(struct work_struct *work); + +/* apply hop penalty for a normal link */ +static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv) +{ + int hop_penalty = atomic_read(&bat_priv->hop_penalty); + return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); +} + +/* when do we schedule our own packet to be sent */ +static unsigned long own_send_time(struct bat_priv *bat_priv) +{ + return jiffies + msecs_to_jiffies( + atomic_read(&bat_priv->orig_interval) - + JITTER + (random32() % 2*JITTER)); +} + +/* when do we schedule a forwarded packet to be sent */ +static unsigned long forward_send_time(struct bat_priv *bat_priv) +{ + return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); +} + +/* send out an already prepared packet to the given address via the + * specified batman interface */ +int send_skb_packet(struct sk_buff *skb, + struct batman_if *batman_if, + uint8_t *dst_addr) +{ + struct ethhdr *ethhdr; + + if (batman_if->if_status != IF_ACTIVE) + goto send_skb_err; + + if (unlikely(!batman_if->net_dev)) + goto send_skb_err; + + if (!(batman_if->net_dev->flags & IFF_UP)) { + pr_warning("Interface %s is not up - can't send packet via " + "that interface!\n", batman_if->net_dev->name); + goto send_skb_err; + } + + /* push to the ethernet header. */ + if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0) + goto send_skb_err; + + skb_reset_mac_header(skb); + + ethhdr = (struct ethhdr *) skb_mac_header(skb); + memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); + memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); + ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); + + skb_set_network_header(skb, ETH_HLEN); + skb->priority = TC_PRIO_CONTROL; + skb->protocol = __constant_htons(ETH_P_BATMAN); + + skb->dev = batman_if->net_dev; + + /* dev_queue_xmit() returns a negative result on error. However on + * congestion and traffic shaping, it drops and returns NET_XMIT_DROP + * (which is > 0). This will not be treated as an error. */ + + return dev_queue_xmit(skb); +send_skb_err: + kfree_skb(skb); + return NET_XMIT_DROP; +} + +/* Send a packet to a given interface */ +static void send_packet_to_if(struct forw_packet *forw_packet, + struct batman_if *batman_if) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + char *fwd_str; + uint8_t packet_num; + int16_t buff_pos; + struct batman_packet *batman_packet; + struct sk_buff *skb; + + if (batman_if->if_status != IF_ACTIVE) + return; + + packet_num = 0; + buff_pos = 0; + batman_packet = (struct batman_packet *)forw_packet->skb->data; + + /* adjust all flags and log packets */ + while (aggregated_packet(buff_pos, + forw_packet->packet_len, + batman_packet->num_hna)) { + + /* we might have aggregated direct link packets with an + * ordinary base packet */ + if ((forw_packet->direct_link_flags & (1 << packet_num)) && + (forw_packet->if_incoming == batman_if)) + batman_packet->flags |= DIRECTLINK; + else + batman_packet->flags &= ~DIRECTLINK; + + fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? + "Sending own" : + "Forwarding")); + bat_dbg(DBG_BATMAN, bat_priv, + "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," + " IDF %s) on interface %s [%pM]\n", + fwd_str, (packet_num > 0 ? "aggregated " : ""), + batman_packet->orig, ntohl(batman_packet->seqno), + batman_packet->tq, batman_packet->ttl, + (batman_packet->flags & DIRECTLINK ? + "on" : "off"), + batman_if->net_dev->name, batman_if->net_dev->dev_addr); + + buff_pos += sizeof(struct batman_packet) + + (batman_packet->num_hna * ETH_ALEN); + packet_num++; + batman_packet = (struct batman_packet *) + (forw_packet->skb->data + buff_pos); + } + + /* create clone because function is called more than once */ + skb = skb_clone(forw_packet->skb, GFP_ATOMIC); + if (skb) + send_skb_packet(skb, batman_if, broadcast_addr); +} + +/* send a batman packet */ +static void send_packet(struct forw_packet *forw_packet) +{ + struct batman_if *batman_if; + struct net_device *soft_iface; + struct bat_priv *bat_priv; + struct batman_packet *batman_packet = + (struct batman_packet *)(forw_packet->skb->data); + unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); + + if (!forw_packet->if_incoming) { + pr_err("Error - can't forward packet: incoming iface not " + "specified\n"); + return; + } + + soft_iface = forw_packet->if_incoming->soft_iface; + bat_priv = netdev_priv(soft_iface); + + if (forw_packet->if_incoming->if_status != IF_ACTIVE) + return; + + /* multihomed peer assumed */ + /* non-primary OGMs are only broadcasted on their interface */ + if ((directlink && (batman_packet->ttl == 1)) || + (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { + + /* FIXME: what about aggregated packets ? */ + bat_dbg(DBG_BATMAN, bat_priv, + "%s packet (originator %pM, seqno %d, TTL %d) " + "on interface %s [%pM]\n", + (forw_packet->own ? "Sending own" : "Forwarding"), + batman_packet->orig, ntohl(batman_packet->seqno), + batman_packet->ttl, + forw_packet->if_incoming->net_dev->name, + forw_packet->if_incoming->net_dev->dev_addr); + + /* skb is only used once and than forw_packet is free'd */ + send_skb_packet(forw_packet->skb, forw_packet->if_incoming, + broadcast_addr); + forw_packet->skb = NULL; + + return; + } + + /* broadcast on every interface */ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->soft_iface != soft_iface) + continue; + + send_packet_to_if(forw_packet, batman_if); + } + rcu_read_unlock(); +} + +static void rebuild_batman_packet(struct bat_priv *bat_priv, + struct batman_if *batman_if) +{ + int new_len; + unsigned char *new_buff; + struct batman_packet *batman_packet; + + new_len = sizeof(struct batman_packet) + + (bat_priv->num_local_hna * ETH_ALEN); + new_buff = kmalloc(new_len, GFP_ATOMIC); + + /* keep old buffer if kmalloc should fail */ + if (new_buff) { + memcpy(new_buff, batman_if->packet_buff, + sizeof(struct batman_packet)); + batman_packet = (struct batman_packet *)new_buff; + + batman_packet->num_hna = hna_local_fill_buffer(bat_priv, + new_buff + sizeof(struct batman_packet), + new_len - sizeof(struct batman_packet)); + + kfree(batman_if->packet_buff); + batman_if->packet_buff = new_buff; + batman_if->packet_len = new_len; + } +} + +void schedule_own_packet(struct batman_if *batman_if) +{ + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + unsigned long send_time; + struct batman_packet *batman_packet; + int vis_server; + + if ((batman_if->if_status == IF_NOT_IN_USE) || + (batman_if->if_status == IF_TO_BE_REMOVED)) + return; + + vis_server = atomic_read(&bat_priv->vis_mode); + + /** + * the interface gets activated here to avoid race conditions between + * the moment of activating the interface in + * hardif_activate_interface() where the originator mac is set and + * outdated packets (especially uninitialized mac addresses) in the + * packet queue + */ + if (batman_if->if_status == IF_TO_BE_ACTIVATED) + batman_if->if_status = IF_ACTIVE; + + /* if local hna has changed and interface is a primary interface */ + if ((atomic_read(&bat_priv->hna_local_changed)) && + (batman_if == bat_priv->primary_if)) + rebuild_batman_packet(bat_priv, batman_if); + + /** + * NOTE: packet_buff might just have been re-allocated in + * rebuild_batman_packet() + */ + batman_packet = (struct batman_packet *)batman_if->packet_buff; + + /* change sequence number to network order */ + batman_packet->seqno = + htonl((uint32_t)atomic_read(&batman_if->seqno)); + + if (vis_server == VIS_TYPE_SERVER_SYNC) + batman_packet->flags |= VIS_SERVER; + else + batman_packet->flags &= ~VIS_SERVER; + + if ((batman_if == bat_priv->primary_if) && + (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) + batman_packet->gw_flags = + (uint8_t)atomic_read(&bat_priv->gw_bandwidth); + else + batman_packet->gw_flags = 0; + + atomic_inc(&batman_if->seqno); + + slide_own_bcast_window(batman_if); + send_time = own_send_time(bat_priv); + add_bat_packet_to_list(bat_priv, + batman_if->packet_buff, + batman_if->packet_len, + batman_if, 1, send_time); +} + +void schedule_forward_packet(struct orig_node *orig_node, + struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + uint8_t directlink, int hna_buff_len, + struct batman_if *if_incoming) +{ + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + unsigned char in_tq, in_ttl, tq_avg = 0; + unsigned long send_time; + + if (batman_packet->ttl <= 1) { + bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); + return; + } + + in_tq = batman_packet->tq; + in_ttl = batman_packet->ttl; + + batman_packet->ttl--; + memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN); + + /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast + * of our best tq value */ + if ((orig_node->router) && (orig_node->router->tq_avg != 0)) { + + /* rebroadcast ogm of best ranking neighbor as is */ + if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) { + batman_packet->tq = orig_node->router->tq_avg; + + if (orig_node->router->last_ttl) + batman_packet->ttl = orig_node->router->last_ttl + - 1; + } + + tq_avg = orig_node->router->tq_avg; + } + + /* apply hop penalty */ + batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); + + bat_dbg(DBG_BATMAN, bat_priv, + "Forwarding packet: tq_orig: %i, tq_avg: %i, " + "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", + in_tq, tq_avg, batman_packet->tq, in_ttl - 1, + batman_packet->ttl); + + batman_packet->seqno = htonl(batman_packet->seqno); + + /* switch of primaries first hop flag when forwarding */ + batman_packet->flags &= ~PRIMARIES_FIRST_HOP; + if (directlink) + batman_packet->flags |= DIRECTLINK; + else + batman_packet->flags &= ~DIRECTLINK; + + send_time = forward_send_time(bat_priv); + add_bat_packet_to_list(bat_priv, + (unsigned char *)batman_packet, + sizeof(struct batman_packet) + hna_buff_len, + if_incoming, 0, send_time); +} + +static void forw_packet_free(struct forw_packet *forw_packet) +{ + if (forw_packet->skb) + kfree_skb(forw_packet->skb); + kfree(forw_packet); +} + +static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, + struct forw_packet *forw_packet, + unsigned long send_time) +{ + INIT_HLIST_NODE(&forw_packet->list); + + /* add new packet to packet list */ + spin_lock_bh(&bat_priv->forw_bcast_list_lock); + hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); + + /* start timer for this packet */ + INIT_DELAYED_WORK(&forw_packet->delayed_work, + send_outstanding_bcast_packet); + queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work, + send_time); +} + +#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) +/* add a broadcast packet to the queue and setup timers. broadcast packets + * are sent multiple times to increase probability for beeing received. + * + * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on + * errors. + * + * The skb is not consumed, so the caller should make sure that the + * skb is freed. */ +int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb) +{ + struct forw_packet *forw_packet; + struct bcast_packet *bcast_packet; + + if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { + bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); + goto out; + } + + if (!bat_priv->primary_if) + goto out; + + forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); + + if (!forw_packet) + goto out_and_inc; + + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + goto packet_free; + + /* as we have a copy now, it is safe to decrease the TTL */ + bcast_packet = (struct bcast_packet *)skb->data; + bcast_packet->ttl--; + + skb_reset_mac_header(skb); + + forw_packet->skb = skb; + forw_packet->if_incoming = bat_priv->primary_if; + + /* how often did we send the bcast packet ? */ + forw_packet->num_packets = 0; + + _add_bcast_packet_to_list(bat_priv, forw_packet, 1); + return NETDEV_TX_OK; + +packet_free: + kfree(forw_packet); +out_and_inc: + atomic_inc(&bat_priv->bcast_queue_left); +out: + return NETDEV_TX_BUSY; +} + +static void send_outstanding_bcast_packet(struct work_struct *work) +{ + struct batman_if *batman_if; + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); + struct forw_packet *forw_packet = + container_of(delayed_work, struct forw_packet, delayed_work); + struct sk_buff *skb1; + struct net_device *soft_iface = forw_packet->if_incoming->soft_iface; + struct bat_priv *bat_priv = netdev_priv(soft_iface); + + spin_lock_bh(&bat_priv->forw_bcast_list_lock); + hlist_del(&forw_packet->list); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); + + if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) + goto out; + + /* rebroadcast packet */ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->soft_iface != soft_iface) + continue; + + /* send a copy of the saved skb */ + skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); + if (skb1) + send_skb_packet(skb1, batman_if, broadcast_addr); + } + rcu_read_unlock(); + + forw_packet->num_packets++; + + /* if we still have some more bcasts to send */ + if (forw_packet->num_packets < 3) { + _add_bcast_packet_to_list(bat_priv, forw_packet, + ((5 * HZ) / 1000)); + return; + } + +out: + forw_packet_free(forw_packet); + atomic_inc(&bat_priv->bcast_queue_left); +} + +void send_outstanding_bat_packet(struct work_struct *work) +{ + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); + struct forw_packet *forw_packet = + container_of(delayed_work, struct forw_packet, delayed_work); + struct bat_priv *bat_priv; + + bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); + spin_lock_bh(&bat_priv->forw_bat_list_lock); + hlist_del(&forw_packet->list); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); + + if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) + goto out; + + send_packet(forw_packet); + + /** + * we have to have at least one packet in the queue + * to determine the queues wake up time unless we are + * shutting down + */ + if (forw_packet->own) + schedule_own_packet(forw_packet->if_incoming); + +out: + /* don't count own packet */ + if (!forw_packet->own) + atomic_inc(&bat_priv->batman_queue_left); + + forw_packet_free(forw_packet); +} + +void purge_outstanding_packets(struct bat_priv *bat_priv, + struct batman_if *batman_if) +{ + struct forw_packet *forw_packet; + struct hlist_node *tmp_node, *safe_tmp_node; + + if (batman_if) + bat_dbg(DBG_BATMAN, bat_priv, + "purge_outstanding_packets(): %s\n", + batman_if->net_dev->name); + else + bat_dbg(DBG_BATMAN, bat_priv, + "purge_outstanding_packets()\n"); + + /* free bcast list */ + spin_lock_bh(&bat_priv->forw_bcast_list_lock); + hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, + &bat_priv->forw_bcast_list, list) { + + /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); + + /** + * send_outstanding_bcast_packet() will lock the list to + * delete the item from the list + */ + cancel_delayed_work_sync(&forw_packet->delayed_work); + spin_lock_bh(&bat_priv->forw_bcast_list_lock); + } + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); + + /* free batman packet list */ + spin_lock_bh(&bat_priv->forw_bat_list_lock); + hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, + &bat_priv->forw_bat_list, list) { + + /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + + spin_unlock_bh(&bat_priv->forw_bat_list_lock); + + /** + * send_outstanding_bat_packet() will lock the list to + * delete the item from the list + */ + cancel_delayed_work_sync(&forw_packet->delayed_work); + spin_lock_bh(&bat_priv->forw_bat_list_lock); + } + spin_unlock_bh(&bat_priv->forw_bat_list_lock); +} diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h new file mode 100644 index 000000000000..c4cefa8e4f85 --- /dev/null +++ b/net/batman-adv/send.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_SEND_H_ +#define _NET_BATMAN_ADV_SEND_H_ + +#include "types.h" + +int send_skb_packet(struct sk_buff *skb, + struct batman_if *batman_if, + uint8_t *dst_addr); +void schedule_own_packet(struct batman_if *batman_if); +void schedule_forward_packet(struct orig_node *orig_node, + struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + uint8_t directlink, int hna_buff_len, + struct batman_if *if_outgoing); +int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb); +void send_outstanding_bat_packet(struct work_struct *work); +void purge_outstanding_packets(struct bat_priv *bat_priv, + struct batman_if *batman_if); + +#endif /* _NET_BATMAN_ADV_SEND_H_ */ diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c new file mode 100644 index 000000000000..e89ede192ed0 --- /dev/null +++ b/net/batman-adv/soft-interface.c @@ -0,0 +1,697 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "soft-interface.h" +#include "hard-interface.h" +#include "routing.h" +#include "send.h" +#include "bat_debugfs.h" +#include "translation-table.h" +#include "types.h" +#include "hash.h" +#include "gateway_common.h" +#include "gateway_client.h" +#include "send.h" +#include "bat_sysfs.h" +#include +#include +#include +#include +#include "unicast.h" +#include "routing.h" + + +static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); +static void bat_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info); +static u32 bat_get_msglevel(struct net_device *dev); +static void bat_set_msglevel(struct net_device *dev, u32 value); +static u32 bat_get_link(struct net_device *dev); +static u32 bat_get_rx_csum(struct net_device *dev); +static int bat_set_rx_csum(struct net_device *dev, u32 data); + +static const struct ethtool_ops bat_ethtool_ops = { + .get_settings = bat_get_settings, + .get_drvinfo = bat_get_drvinfo, + .get_msglevel = bat_get_msglevel, + .set_msglevel = bat_set_msglevel, + .get_link = bat_get_link, + .get_rx_csum = bat_get_rx_csum, + .set_rx_csum = bat_set_rx_csum +}; + +int my_skb_head_push(struct sk_buff *skb, unsigned int len) +{ + int result; + + /** + * TODO: We must check if we can release all references to non-payload + * data using skb_header_release in our skbs to allow skb_cow_header to + * work optimally. This means that those skbs are not allowed to read + * or write any data which is before the current position of skb->data + * after that call and thus allow other skbs with the same data buffer + * to write freely in that area. + */ + result = skb_cow_head(skb, len); + if (result < 0) + return result; + + skb_push(skb, len); + return 0; +} + +static void softif_neigh_free_ref(struct kref *refcount) +{ + struct softif_neigh *softif_neigh; + + softif_neigh = container_of(refcount, struct softif_neigh, refcount); + kfree(softif_neigh); +} + +static void softif_neigh_free_rcu(struct rcu_head *rcu) +{ + struct softif_neigh *softif_neigh; + + softif_neigh = container_of(rcu, struct softif_neigh, rcu); + kref_put(&softif_neigh->refcount, softif_neigh_free_ref); +} + +void softif_neigh_purge(struct bat_priv *bat_priv) +{ + struct softif_neigh *softif_neigh, *softif_neigh_tmp; + struct hlist_node *node, *node_tmp; + + spin_lock_bh(&bat_priv->softif_neigh_lock); + + hlist_for_each_entry_safe(softif_neigh, node, node_tmp, + &bat_priv->softif_neigh_list, list) { + + if ((!time_after(jiffies, softif_neigh->last_seen + + msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && + (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) + continue; + + hlist_del_rcu(&softif_neigh->list); + + if (bat_priv->softif_neigh == softif_neigh) { + bat_dbg(DBG_ROUTES, bat_priv, + "Current mesh exit point '%pM' vanished " + "(vid: %d).\n", + softif_neigh->addr, softif_neigh->vid); + softif_neigh_tmp = bat_priv->softif_neigh; + bat_priv->softif_neigh = NULL; + kref_put(&softif_neigh_tmp->refcount, + softif_neigh_free_ref); + } + + call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); + } + + spin_unlock_bh(&bat_priv->softif_neigh_lock); +} + +static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, + uint8_t *addr, short vid) +{ + struct softif_neigh *softif_neigh; + struct hlist_node *node; + + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) { + if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0) + continue; + + if (softif_neigh->vid != vid) + continue; + + softif_neigh->last_seen = jiffies; + goto found; + } + + softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); + if (!softif_neigh) + goto out; + + memcpy(softif_neigh->addr, addr, ETH_ALEN); + softif_neigh->vid = vid; + softif_neigh->last_seen = jiffies; + kref_init(&softif_neigh->refcount); + + INIT_HLIST_NODE(&softif_neigh->list); + spin_lock_bh(&bat_priv->softif_neigh_lock); + hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); + spin_unlock_bh(&bat_priv->softif_neigh_lock); + +found: + kref_get(&softif_neigh->refcount); +out: + rcu_read_unlock(); + return softif_neigh; +} + +int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct softif_neigh *softif_neigh; + struct hlist_node *node; + size_t buf_size, pos; + char *buff; + + if (!bat_priv->primary_if) { + return seq_printf(seq, "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); + } + + seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); + + buf_size = 1; + /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */ + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) + buf_size += 30; + rcu_read_unlock(); + + buff = kmalloc(buf_size, GFP_ATOMIC); + if (!buff) + return -ENOMEM; + + buff[0] = '\0'; + pos = 0; + + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) { + pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n", + bat_priv->softif_neigh == softif_neigh + ? "=>" : " ", softif_neigh->addr, + softif_neigh->vid); + } + rcu_read_unlock(); + + seq_printf(seq, "%s", buff); + kfree(buff); + return 0; +} + +static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, + short vid) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct ethhdr *ethhdr = (struct ethhdr *)skb->data; + struct batman_packet *batman_packet; + struct softif_neigh *softif_neigh, *softif_neigh_tmp; + + if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) + batman_packet = (struct batman_packet *) + (skb->data + ETH_HLEN + VLAN_HLEN); + else + batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); + + if (batman_packet->version != COMPAT_VERSION) + goto err; + + if (batman_packet->packet_type != BAT_PACKET) + goto err; + + if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) + goto err; + + if (is_my_mac(batman_packet->orig)) + goto err; + + softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); + + if (!softif_neigh) + goto err; + + if (bat_priv->softif_neigh == softif_neigh) + goto out; + + /* we got a neighbor but its mac is 'bigger' than ours */ + if (memcmp(bat_priv->primary_if->net_dev->dev_addr, + softif_neigh->addr, ETH_ALEN) < 0) + goto out; + + /* switch to new 'smallest neighbor' */ + if ((bat_priv->softif_neigh) && + (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr, + ETH_ALEN) < 0)) { + bat_dbg(DBG_ROUTES, bat_priv, + "Changing mesh exit point from %pM (vid: %d) " + "to %pM (vid: %d).\n", + bat_priv->softif_neigh->addr, + bat_priv->softif_neigh->vid, + softif_neigh->addr, softif_neigh->vid); + softif_neigh_tmp = bat_priv->softif_neigh; + bat_priv->softif_neigh = softif_neigh; + kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref); + /* we need to hold the additional reference */ + goto err; + } + + /* close own batX device and use softif_neigh as exit node */ + if ((!bat_priv->softif_neigh) && + (memcmp(softif_neigh->addr, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { + bat_dbg(DBG_ROUTES, bat_priv, + "Setting mesh exit point to %pM (vid: %d).\n", + softif_neigh->addr, softif_neigh->vid); + bat_priv->softif_neigh = softif_neigh; + /* we need to hold the additional reference */ + goto err; + } + +out: + kref_put(&softif_neigh->refcount, softif_neigh_free_ref); +err: + kfree_skb(skb); + return; +} + +static int interface_open(struct net_device *dev) +{ + netif_start_queue(dev); + return 0; +} + +static int interface_release(struct net_device *dev) +{ + netif_stop_queue(dev); + return 0; +} + +static struct net_device_stats *interface_stats(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + return &bat_priv->stats; +} + +static int interface_set_mac_addr(struct net_device *dev, void *p) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + /* only modify hna-table if it has been initialised before */ + if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { + hna_local_remove(bat_priv, dev->dev_addr, + "mac address changed"); + hna_local_add(dev, addr->sa_data); + } + + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + return 0; +} + +static int interface_change_mtu(struct net_device *dev, int new_mtu) +{ + /* check ranges */ + if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev))) + return -EINVAL; + + dev->mtu = new_mtu; + + return 0; +} + +int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) +{ + struct ethhdr *ethhdr = (struct ethhdr *)skb->data; + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct bcast_packet *bcast_packet; + struct vlan_ethhdr *vhdr; + int data_len = skb->len, ret; + short vid = -1; + bool do_bcast = false; + + if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) + goto dropped; + + soft_iface->trans_start = jiffies; + + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_8021Q: + vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + + if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + break; + + /* fall through */ + case ETH_P_BATMAN: + softif_batman_recv(skb, soft_iface, vid); + goto end; + } + + /** + * if we have a another chosen mesh exit node in range + * it will transport the packets to the mesh + */ + if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) + goto dropped; + + /* TODO: check this for locks */ + hna_local_add(soft_iface, ethhdr->h_source); + + if (is_multicast_ether_addr(ethhdr->h_dest)) { + ret = gw_is_target(bat_priv, skb); + + if (ret < 0) + goto dropped; + + if (ret == 0) + do_bcast = true; + } + + /* ethernet packet should be broadcasted */ + if (do_bcast) { + if (!bat_priv->primary_if) + goto dropped; + + if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) + goto dropped; + + bcast_packet = (struct bcast_packet *)skb->data; + bcast_packet->version = COMPAT_VERSION; + bcast_packet->ttl = TTL; + + /* batman packet type: broadcast */ + bcast_packet->packet_type = BAT_BCAST; + + /* hw address of first interface is the orig mac because only + * this mac is known throughout the mesh */ + memcpy(bcast_packet->orig, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + + /* set broadcast sequence number */ + bcast_packet->seqno = + htonl(atomic_inc_return(&bat_priv->bcast_seqno)); + + add_bcast_packet_to_list(bat_priv, skb); + + /* a copy is stored in the bcast list, therefore removing + * the original skb. */ + kfree_skb(skb); + + /* unicast packet */ + } else { + ret = unicast_send_skb(skb, bat_priv); + if (ret != 0) + goto dropped_freed; + } + + bat_priv->stats.tx_packets++; + bat_priv->stats.tx_bytes += data_len; + goto end; + +dropped: + kfree_skb(skb); +dropped_freed: + bat_priv->stats.tx_dropped++; +end: + return NETDEV_TX_OK; +} + +void interface_rx(struct net_device *soft_iface, + struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size) +{ + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct unicast_packet *unicast_packet; + struct ethhdr *ethhdr; + struct vlan_ethhdr *vhdr; + short vid = -1; + int ret; + + /* check if enough space is available for pulling, and pull */ + if (!pskb_may_pull(skb, hdr_size)) + goto dropped; + + skb_pull_rcsum(skb, hdr_size); + skb_reset_mac_header(skb); + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_8021Q: + vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + + if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + break; + + /* fall through */ + case ETH_P_BATMAN: + goto dropped; + } + + /** + * if we have a another chosen mesh exit node in range + * it will transport the packets to the non-mesh network + */ + if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) { + skb_push(skb, hdr_size); + unicast_packet = (struct unicast_packet *)skb->data; + + if ((unicast_packet->packet_type != BAT_UNICAST) && + (unicast_packet->packet_type != BAT_UNICAST_FRAG)) + goto dropped; + + skb_reset_mac_header(skb); + + memcpy(unicast_packet->dest, + bat_priv->softif_neigh->addr, ETH_ALEN); + ret = route_unicast_packet(skb, recv_if, hdr_size); + if (ret == NET_RX_DROP) + goto dropped; + + goto out; + } + + /* skb->dev & skb->pkt_type are set here */ + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + goto dropped; + skb->protocol = eth_type_trans(skb, soft_iface); + + /* should not be neccesary anymore as we use skb_pull_rcsum() + * TODO: please verify this and remove this TODO + * -- Dec 21st 2009, Simon Wunderlich */ + +/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ + + bat_priv->stats.rx_packets++; + bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr); + + soft_iface->last_rx = jiffies; + + netif_rx(skb); + return; + +dropped: + kfree_skb(skb); +out: + return; +} + +#ifdef HAVE_NET_DEVICE_OPS +static const struct net_device_ops bat_netdev_ops = { + .ndo_open = interface_open, + .ndo_stop = interface_release, + .ndo_get_stats = interface_stats, + .ndo_set_mac_address = interface_set_mac_addr, + .ndo_change_mtu = interface_change_mtu, + .ndo_start_xmit = interface_tx, + .ndo_validate_addr = eth_validate_addr +}; +#endif + +static void interface_setup(struct net_device *dev) +{ + struct bat_priv *priv = netdev_priv(dev); + char dev_addr[ETH_ALEN]; + + ether_setup(dev); + +#ifdef HAVE_NET_DEVICE_OPS + dev->netdev_ops = &bat_netdev_ops; +#else + dev->open = interface_open; + dev->stop = interface_release; + dev->get_stats = interface_stats; + dev->set_mac_address = interface_set_mac_addr; + dev->change_mtu = interface_change_mtu; + dev->hard_start_xmit = interface_tx; +#endif + dev->destructor = free_netdev; + + /** + * can't call min_mtu, because the needed variables + * have not been initialized yet + */ + dev->mtu = ETH_DATA_LEN; + dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the + * skbuff for our header */ + + /* generate random address */ + random_ether_addr(dev_addr); + memcpy(dev->dev_addr, dev_addr, ETH_ALEN); + + SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); + + memset(priv, 0, sizeof(struct bat_priv)); +} + +struct net_device *softif_create(char *name) +{ + struct net_device *soft_iface; + struct bat_priv *bat_priv; + int ret; + + soft_iface = alloc_netdev(sizeof(struct bat_priv) , name, + interface_setup); + + if (!soft_iface) { + pr_err("Unable to allocate the batman interface: %s\n", name); + goto out; + } + + ret = register_netdev(soft_iface); + if (ret < 0) { + pr_err("Unable to register the batman interface '%s': %i\n", + name, ret); + goto free_soft_iface; + } + + bat_priv = netdev_priv(soft_iface); + + atomic_set(&bat_priv->aggregated_ogms, 1); + atomic_set(&bat_priv->bonding, 0); + atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); + atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); + atomic_set(&bat_priv->gw_sel_class, 20); + atomic_set(&bat_priv->gw_bandwidth, 41); + atomic_set(&bat_priv->orig_interval, 1000); + atomic_set(&bat_priv->hop_penalty, 10); + atomic_set(&bat_priv->log_level, 0); + atomic_set(&bat_priv->fragmentation, 1); + atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); + atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN); + + atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); + atomic_set(&bat_priv->bcast_seqno, 1); + atomic_set(&bat_priv->hna_local_changed, 0); + + bat_priv->primary_if = NULL; + bat_priv->num_ifaces = 0; + bat_priv->softif_neigh = NULL; + + ret = sysfs_add_meshif(soft_iface); + if (ret < 0) + goto unreg_soft_iface; + + ret = debugfs_add_meshif(soft_iface); + if (ret < 0) + goto unreg_sysfs; + + ret = mesh_init(soft_iface); + if (ret < 0) + goto unreg_debugfs; + + return soft_iface; + +unreg_debugfs: + debugfs_del_meshif(soft_iface); +unreg_sysfs: + sysfs_del_meshif(soft_iface); +unreg_soft_iface: + unregister_netdev(soft_iface); + return NULL; + +free_soft_iface: + free_netdev(soft_iface); +out: + return NULL; +} + +void softif_destroy(struct net_device *soft_iface) +{ + debugfs_del_meshif(soft_iface); + sysfs_del_meshif(soft_iface); + mesh_free(soft_iface); + unregister_netdevice(soft_iface); +} + +/* ethtool */ +static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = 0; + cmd->advertising = 0; + cmd->speed = SPEED_10; + cmd->duplex = DUPLEX_FULL; + cmd->port = PORT_TP; + cmd->phy_address = 0; + cmd->transceiver = XCVR_INTERNAL; + cmd->autoneg = AUTONEG_DISABLE; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + + return 0; +} + +static void bat_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, "B.A.T.M.A.N. advanced"); + strcpy(info->version, SOURCE_VERSION); + strcpy(info->fw_version, "N/A"); + strcpy(info->bus_info, "batman"); +} + +static u32 bat_get_msglevel(struct net_device *dev) +{ + return -EOPNOTSUPP; +} + +static void bat_set_msglevel(struct net_device *dev, u32 value) +{ +} + +static u32 bat_get_link(struct net_device *dev) +{ + return 1; +} + +static u32 bat_get_rx_csum(struct net_device *dev) +{ + return 0; +} + +static int bat_set_rx_csum(struct net_device *dev, u32 data) +{ + return -EOPNOTSUPP; +} diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h new file mode 100644 index 000000000000..02b77334d10d --- /dev/null +++ b/net/batman-adv/soft-interface.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_ +#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ + +int my_skb_head_push(struct sk_buff *skb, unsigned int len); +int softif_neigh_seq_print_text(struct seq_file *seq, void *offset); +void softif_neigh_purge(struct bat_priv *bat_priv); +int interface_tx(struct sk_buff *skb, struct net_device *soft_iface); +void interface_rx(struct net_device *soft_iface, + struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size); +struct net_device *softif_create(char *name); +void softif_destroy(struct net_device *soft_iface); + +#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c new file mode 100644 index 000000000000..a19e16c94da5 --- /dev/null +++ b/net/batman-adv/translation-table.c @@ -0,0 +1,534 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "translation-table.h" +#include "soft-interface.h" +#include "types.h" +#include "hash.h" +#include "originator.h" + +static void hna_local_purge(struct work_struct *work); +static void _hna_global_del_orig(struct bat_priv *bat_priv, + struct hna_global_entry *hna_global_entry, + char *message); + +static void hna_local_start_timer(struct bat_priv *bat_priv) +{ + INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); + queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); +} + +int hna_local_init(struct bat_priv *bat_priv) +{ + if (bat_priv->hna_local_hash) + return 1; + + bat_priv->hna_local_hash = hash_new(1024); + + if (!bat_priv->hna_local_hash) + return 0; + + atomic_set(&bat_priv->hna_local_changed, 0); + hna_local_start_timer(bat_priv); + + return 1; +} + +void hna_local_add(struct net_device *soft_iface, uint8_t *addr) +{ + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct hna_local_entry *hna_local_entry; + struct hna_global_entry *hna_global_entry; + int required_bytes; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + hna_local_entry = + ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, + compare_orig, choose_orig, + addr)); + spin_unlock_bh(&bat_priv->hna_lhash_lock); + + if (hna_local_entry) { + hna_local_entry->last_seen = jiffies; + return; + } + + /* only announce as many hosts as possible in the batman-packet and + space in batman_packet->num_hna That also should give a limit to + MAC-flooding. */ + required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; + required_bytes += BAT_PACKET_LEN; + + if ((required_bytes > ETH_DATA_LEN) || + (atomic_read(&bat_priv->aggregated_ogms) && + required_bytes > MAX_AGGREGATION_BYTES) || + (bat_priv->num_local_hna + 1 > 255)) { + bat_dbg(DBG_ROUTES, bat_priv, + "Can't add new local hna entry (%pM): " + "number of local hna entries exceeds packet size\n", + addr); + return; + } + + bat_dbg(DBG_ROUTES, bat_priv, + "Creating new local hna entry: %pM\n", addr); + + hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); + if (!hna_local_entry) + return; + + memcpy(hna_local_entry->addr, addr, ETH_ALEN); + hna_local_entry->last_seen = jiffies; + + /* the batman interface mac address should never be purged */ + if (compare_orig(addr, soft_iface->dev_addr)) + hna_local_entry->never_purge = 1; + else + hna_local_entry->never_purge = 0; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + + hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig, + hna_local_entry); + bat_priv->num_local_hna++; + atomic_set(&bat_priv->hna_local_changed, 1); + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + + /* remove address from global hash if present */ + spin_lock_bh(&bat_priv->hna_ghash_lock); + + hna_global_entry = ((struct hna_global_entry *) + hash_find(bat_priv->hna_global_hash, + compare_orig, choose_orig, addr)); + + if (hna_global_entry) + _hna_global_del_orig(bat_priv, hna_global_entry, + "local hna received"); + + spin_unlock_bh(&bat_priv->hna_ghash_lock); +} + +int hna_local_fill_buffer(struct bat_priv *bat_priv, + unsigned char *buff, int buff_len) +{ + struct hashtable_t *hash = bat_priv->hna_local_hash; + struct hna_local_entry *hna_local_entry; + struct element_t *bucket; + int i; + struct hlist_node *walk; + struct hlist_head *head; + int count = 0; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + + if (buff_len < (count + 1) * ETH_ALEN) + break; + + hna_local_entry = bucket->data; + memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr, + ETH_ALEN); + + count++; + } + } + + /* if we did not get all new local hnas see you next time ;-) */ + if (count == bat_priv->num_local_hna) + atomic_set(&bat_priv->hna_local_changed, 0); + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + return i; +} + +int hna_local_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct hashtable_t *hash = bat_priv->hna_local_hash; + struct hna_local_entry *hna_local_entry; + int i; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + size_t buf_size, pos; + char *buff; + + if (!bat_priv->primary_if) { + return seq_printf(seq, "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); + } + + seq_printf(seq, "Locally retrieved addresses (from %s) " + "announced via HNA:\n", + net_dev->name); + + spin_lock_bh(&bat_priv->hna_lhash_lock); + + buf_size = 1; + /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each(walk, head) + buf_size += 21; + } + + buff = kmalloc(buf_size, GFP_ATOMIC); + if (!buff) { + spin_unlock_bh(&bat_priv->hna_lhash_lock); + return -ENOMEM; + } + buff[0] = '\0'; + pos = 0; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + hna_local_entry = bucket->data; + + pos += snprintf(buff + pos, 22, " * %pM\n", + hna_local_entry->addr); + } + } + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + + seq_printf(seq, "%s", buff); + kfree(buff); + return 0; +} + +static void _hna_local_del(void *data, void *arg) +{ + struct bat_priv *bat_priv = (struct bat_priv *)arg; + + kfree(data); + bat_priv->num_local_hna--; + atomic_set(&bat_priv->hna_local_changed, 1); +} + +static void hna_local_del(struct bat_priv *bat_priv, + struct hna_local_entry *hna_local_entry, + char *message) +{ + bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", + hna_local_entry->addr, message); + + hash_remove(bat_priv->hna_local_hash, compare_orig, choose_orig, + hna_local_entry->addr); + _hna_local_del(hna_local_entry, bat_priv); +} + +void hna_local_remove(struct bat_priv *bat_priv, + uint8_t *addr, char *message) +{ + struct hna_local_entry *hna_local_entry; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + + hna_local_entry = (struct hna_local_entry *) + hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, + addr); + + if (hna_local_entry) + hna_local_del(bat_priv, hna_local_entry, message); + + spin_unlock_bh(&bat_priv->hna_lhash_lock); +} + +static void hna_local_purge(struct work_struct *work) +{ + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); + struct bat_priv *bat_priv = + container_of(delayed_work, struct bat_priv, hna_work); + struct hashtable_t *hash = bat_priv->hna_local_hash; + struct hna_local_entry *hna_local_entry; + int i; + struct hlist_node *walk, *safe; + struct hlist_head *head; + struct element_t *bucket; + unsigned long timeout; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { + hna_local_entry = bucket->data; + + timeout = hna_local_entry->last_seen; + timeout += LOCAL_HNA_TIMEOUT * HZ; + + if ((!hna_local_entry->never_purge) && + time_after(jiffies, timeout)) + hna_local_del(bat_priv, hna_local_entry, + "address timed out"); + } + } + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + hna_local_start_timer(bat_priv); +} + +void hna_local_free(struct bat_priv *bat_priv) +{ + if (!bat_priv->hna_local_hash) + return; + + cancel_delayed_work_sync(&bat_priv->hna_work); + hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); + bat_priv->hna_local_hash = NULL; +} + +int hna_global_init(struct bat_priv *bat_priv) +{ + if (bat_priv->hna_global_hash) + return 1; + + bat_priv->hna_global_hash = hash_new(1024); + + if (!bat_priv->hna_global_hash) + return 0; + + return 1; +} + +void hna_global_add_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + unsigned char *hna_buff, int hna_buff_len) +{ + struct hna_global_entry *hna_global_entry; + struct hna_local_entry *hna_local_entry; + int hna_buff_count = 0; + unsigned char *hna_ptr; + + while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { + spin_lock_bh(&bat_priv->hna_ghash_lock); + + hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); + hna_global_entry = (struct hna_global_entry *) + hash_find(bat_priv->hna_global_hash, compare_orig, + choose_orig, hna_ptr); + + if (!hna_global_entry) { + spin_unlock_bh(&bat_priv->hna_ghash_lock); + + hna_global_entry = + kmalloc(sizeof(struct hna_global_entry), + GFP_ATOMIC); + + if (!hna_global_entry) + break; + + memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); + + bat_dbg(DBG_ROUTES, bat_priv, + "Creating new global hna entry: " + "%pM (via %pM)\n", + hna_global_entry->addr, orig_node->orig); + + spin_lock_bh(&bat_priv->hna_ghash_lock); + hash_add(bat_priv->hna_global_hash, compare_orig, + choose_orig, hna_global_entry); + + } + + hna_global_entry->orig_node = orig_node; + spin_unlock_bh(&bat_priv->hna_ghash_lock); + + /* remove address from local hash if present */ + spin_lock_bh(&bat_priv->hna_lhash_lock); + + hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); + hna_local_entry = (struct hna_local_entry *) + hash_find(bat_priv->hna_local_hash, compare_orig, + choose_orig, hna_ptr); + + if (hna_local_entry) + hna_local_del(bat_priv, hna_local_entry, + "global hna received"); + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + + hna_buff_count++; + } + + /* initialize, and overwrite if malloc succeeds */ + orig_node->hna_buff = NULL; + orig_node->hna_buff_len = 0; + + if (hna_buff_len > 0) { + orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); + if (orig_node->hna_buff) { + memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); + orig_node->hna_buff_len = hna_buff_len; + } + } +} + +int hna_global_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct hashtable_t *hash = bat_priv->hna_global_hash; + struct hna_global_entry *hna_global_entry; + int i; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + size_t buf_size, pos; + char *buff; + + if (!bat_priv->primary_if) { + return seq_printf(seq, "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); + } + + seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", + net_dev->name); + + spin_lock_bh(&bat_priv->hna_ghash_lock); + + buf_size = 1; + /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each(walk, head) + buf_size += 43; + } + + buff = kmalloc(buf_size, GFP_ATOMIC); + if (!buff) { + spin_unlock_bh(&bat_priv->hna_ghash_lock); + return -ENOMEM; + } + buff[0] = '\0'; + pos = 0; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + hna_global_entry = bucket->data; + + pos += snprintf(buff + pos, 44, + " * %pM via %pM\n", + hna_global_entry->addr, + hna_global_entry->orig_node->orig); + } + } + + spin_unlock_bh(&bat_priv->hna_ghash_lock); + + seq_printf(seq, "%s", buff); + kfree(buff); + return 0; +} + +static void _hna_global_del_orig(struct bat_priv *bat_priv, + struct hna_global_entry *hna_global_entry, + char *message) +{ + bat_dbg(DBG_ROUTES, bat_priv, + "Deleting global hna entry %pM (via %pM): %s\n", + hna_global_entry->addr, hna_global_entry->orig_node->orig, + message); + + hash_remove(bat_priv->hna_global_hash, compare_orig, choose_orig, + hna_global_entry->addr); + kfree(hna_global_entry); +} + +void hna_global_del_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, char *message) +{ + struct hna_global_entry *hna_global_entry; + int hna_buff_count = 0; + unsigned char *hna_ptr; + + if (orig_node->hna_buff_len == 0) + return; + + spin_lock_bh(&bat_priv->hna_ghash_lock); + + while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { + hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); + hna_global_entry = (struct hna_global_entry *) + hash_find(bat_priv->hna_global_hash, compare_orig, + choose_orig, hna_ptr); + + if ((hna_global_entry) && + (hna_global_entry->orig_node == orig_node)) + _hna_global_del_orig(bat_priv, hna_global_entry, + message); + + hna_buff_count++; + } + + spin_unlock_bh(&bat_priv->hna_ghash_lock); + + orig_node->hna_buff_len = 0; + kfree(orig_node->hna_buff); + orig_node->hna_buff = NULL; +} + +static void hna_global_del(void *data, void *arg) +{ + kfree(data); +} + +void hna_global_free(struct bat_priv *bat_priv) +{ + if (!bat_priv->hna_global_hash) + return; + + hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); + bat_priv->hna_global_hash = NULL; +} + +struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) +{ + struct hna_global_entry *hna_global_entry; + + spin_lock_bh(&bat_priv->hna_ghash_lock); + hna_global_entry = (struct hna_global_entry *) + hash_find(bat_priv->hna_global_hash, + compare_orig, choose_orig, addr); + spin_unlock_bh(&bat_priv->hna_ghash_lock); + + if (!hna_global_entry) + return NULL; + + return hna_global_entry->orig_node; +} diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h new file mode 100644 index 000000000000..10c4c5c319b6 --- /dev/null +++ b/net/batman-adv/translation-table.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ +#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ + +#include "types.h" + +int hna_local_init(struct bat_priv *bat_priv); +void hna_local_add(struct net_device *soft_iface, uint8_t *addr); +void hna_local_remove(struct bat_priv *bat_priv, + uint8_t *addr, char *message); +int hna_local_fill_buffer(struct bat_priv *bat_priv, + unsigned char *buff, int buff_len); +int hna_local_seq_print_text(struct seq_file *seq, void *offset); +void hna_local_free(struct bat_priv *bat_priv); +int hna_global_init(struct bat_priv *bat_priv); +void hna_global_add_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + unsigned char *hna_buff, int hna_buff_len); +int hna_global_seq_print_text(struct seq_file *seq, void *offset); +void hna_global_del_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, char *message); +void hna_global_free(struct bat_priv *bat_priv); +struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr); + +#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h new file mode 100644 index 000000000000..97cb23dd3e69 --- /dev/null +++ b/net/batman-adv/types.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + + +#ifndef _NET_BATMAN_ADV_TYPES_H_ +#define _NET_BATMAN_ADV_TYPES_H_ + +#include "packet.h" +#include "bitarray.h" + +#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ + sizeof(struct unicast_packet) : \ + sizeof(struct bcast_packet)))) + + +struct batman_if { + struct list_head list; + int16_t if_num; + char if_status; + struct net_device *net_dev; + atomic_t seqno; + atomic_t frag_seqno; + unsigned char *packet_buff; + int packet_len; + struct kobject *hardif_obj; + struct kref refcount; + struct packet_type batman_adv_ptype; + struct net_device *soft_iface; + struct rcu_head rcu; +}; + +/** + * orig_node - structure for orig_list maintaining nodes of mesh + * @primary_addr: hosts primary interface address + * @last_valid: when last packet from this node was received + * @bcast_seqno_reset: time when the broadcast seqno window was reset + * @batman_seqno_reset: time when the batman seqno window was reset + * @gw_flags: flags related to gateway class + * @flags: for now only VIS_SERVER flag + * @last_real_seqno: last and best known squence number + * @last_ttl: ttl of last received packet + * @last_bcast_seqno: last broadcast sequence number received by this host + * + * @candidates: how many candidates are available + * @selected: next bonding candidate + */ +struct orig_node { + uint8_t orig[ETH_ALEN]; + uint8_t primary_addr[ETH_ALEN]; + struct neigh_node *router; + unsigned long *bcast_own; + uint8_t *bcast_own_sum; + uint8_t tq_own; + int tq_asym_penalty; + unsigned long last_valid; + unsigned long bcast_seqno_reset; + unsigned long batman_seqno_reset; + uint8_t gw_flags; + uint8_t flags; + unsigned char *hna_buff; + int16_t hna_buff_len; + uint32_t last_real_seqno; + uint8_t last_ttl; + unsigned long bcast_bits[NUM_WORDS]; + uint32_t last_bcast_seqno; + struct list_head neigh_list; + struct list_head frag_list; + unsigned long last_frag_packet; + struct { + uint8_t candidates; + struct neigh_node *selected; + } bond; +}; + +struct gw_node { + struct hlist_node list; + struct orig_node *orig_node; + unsigned long deleted; + struct kref refcount; + struct rcu_head rcu; +}; + +/** + * neigh_node + * @last_valid: when last packet via this neighbor was received + */ +struct neigh_node { + struct list_head list; + uint8_t addr[ETH_ALEN]; + uint8_t real_packet_count; + uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE]; + uint8_t tq_index; + uint8_t tq_avg; + uint8_t last_ttl; + struct neigh_node *next_bond_candidate; + unsigned long last_valid; + unsigned long real_bits[NUM_WORDS]; + struct orig_node *orig_node; + struct batman_if *if_incoming; +}; + + +struct bat_priv { + atomic_t mesh_state; + struct net_device_stats stats; + atomic_t aggregated_ogms; /* boolean */ + atomic_t bonding; /* boolean */ + atomic_t fragmentation; /* boolean */ + atomic_t vis_mode; /* VIS_TYPE_* */ + atomic_t gw_mode; /* GW_MODE_* */ + atomic_t gw_sel_class; /* uint */ + atomic_t gw_bandwidth; /* gw bandwidth */ + atomic_t orig_interval; /* uint */ + atomic_t hop_penalty; /* uint */ + atomic_t log_level; /* uint */ + atomic_t bcast_seqno; + atomic_t bcast_queue_left; + atomic_t batman_queue_left; + char num_ifaces; + struct hlist_head softif_neigh_list; + struct softif_neigh *softif_neigh; + struct debug_log *debug_log; + struct batman_if *primary_if; + struct kobject *mesh_obj; + struct dentry *debug_dir; + struct hlist_head forw_bat_list; + struct hlist_head forw_bcast_list; + struct hlist_head gw_list; + struct list_head vis_send_list; + struct hashtable_t *orig_hash; + struct hashtable_t *hna_local_hash; + struct hashtable_t *hna_global_hash; + struct hashtable_t *vis_hash; + spinlock_t orig_hash_lock; /* protects orig_hash */ + spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ + spinlock_t forw_bcast_list_lock; /* protects */ + spinlock_t hna_lhash_lock; /* protects hna_local_hash */ + spinlock_t hna_ghash_lock; /* protects hna_global_hash */ + spinlock_t gw_list_lock; /* protects gw_list */ + spinlock_t vis_hash_lock; /* protects vis_hash */ + spinlock_t vis_list_lock; /* protects vis_info::recv_list */ + spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ + int16_t num_local_hna; + atomic_t hna_local_changed; + struct delayed_work hna_work; + struct delayed_work orig_work; + struct delayed_work vis_work; + struct gw_node *curr_gw; + struct vis_info *my_vis_info; +}; + +struct socket_client { + struct list_head queue_list; + unsigned int queue_len; + unsigned char index; + spinlock_t lock; /* protects queue_list, queue_len, index */ + wait_queue_head_t queue_wait; + struct bat_priv *bat_priv; +}; + +struct socket_packet { + struct list_head list; + size_t icmp_len; + struct icmp_packet_rr icmp_packet; +}; + +struct hna_local_entry { + uint8_t addr[ETH_ALEN]; + unsigned long last_seen; + char never_purge; +}; + +struct hna_global_entry { + uint8_t addr[ETH_ALEN]; + struct orig_node *orig_node; +}; + +/** + * forw_packet - structure for forw_list maintaining packets to be + * send/forwarded + */ +struct forw_packet { + struct hlist_node list; + unsigned long send_time; + uint8_t own; + struct sk_buff *skb; + uint16_t packet_len; + uint32_t direct_link_flags; + uint8_t num_packets; + struct delayed_work delayed_work; + struct batman_if *if_incoming; +}; + +/* While scanning for vis-entries of a particular vis-originator + * this list collects its interfaces to create a subgraph/cluster + * out of them later + */ +struct if_list_entry { + uint8_t addr[ETH_ALEN]; + bool primary; + struct hlist_node list; +}; + +struct debug_log { + char log_buff[LOG_BUF_LEN]; + unsigned long log_start; + unsigned long log_end; + spinlock_t lock; /* protects log_buff, log_start and log_end */ + wait_queue_head_t queue_wait; +}; + +struct frag_packet_list_entry { + struct list_head list; + uint16_t seqno; + struct sk_buff *skb; +}; + +struct vis_info { + unsigned long first_seen; + struct list_head recv_list; + /* list of server-neighbors we received a vis-packet + * from. we should not reply to them. */ + struct list_head send_list; + struct kref refcount; + struct bat_priv *bat_priv; + /* this packet might be part of the vis send queue. */ + struct sk_buff *skb_packet; + /* vis_info may follow here*/ +} __attribute__((packed)); + +struct vis_info_entry { + uint8_t src[ETH_ALEN]; + uint8_t dest[ETH_ALEN]; + uint8_t quality; /* quality = 0 means HNA */ +} __attribute__((packed)); + +struct recvlist_node { + struct list_head list; + uint8_t mac[ETH_ALEN]; +}; + +struct softif_neigh { + struct hlist_node list; + uint8_t addr[ETH_ALEN]; + unsigned long last_seen; + short vid; + struct kref refcount; + struct rcu_head rcu; +}; + +#endif /* _NET_BATMAN_ADV_TYPES_H_ */ diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c new file mode 100644 index 000000000000..dc2e28bed844 --- /dev/null +++ b/net/batman-adv/unicast.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Andreas Langer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "unicast.h" +#include "send.h" +#include "soft-interface.h" +#include "gateway_client.h" +#include "originator.h" +#include "hash.h" +#include "translation-table.h" +#include "routing.h" +#include "hard-interface.h" + + +static struct sk_buff *frag_merge_packet(struct list_head *head, + struct frag_packet_list_entry *tfp, + struct sk_buff *skb) +{ + struct unicast_frag_packet *up = + (struct unicast_frag_packet *)skb->data; + struct sk_buff *tmp_skb; + struct unicast_packet *unicast_packet; + int hdr_len = sizeof(struct unicast_packet), + uni_diff = sizeof(struct unicast_frag_packet) - hdr_len; + + /* set skb to the first part and tmp_skb to the second part */ + if (up->flags & UNI_FRAG_HEAD) { + tmp_skb = tfp->skb; + } else { + tmp_skb = skb; + skb = tfp->skb; + } + + skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); + if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) { + /* free buffered skb, skb will be freed later */ + kfree_skb(tfp->skb); + return NULL; + } + + /* move free entry to end */ + tfp->skb = NULL; + tfp->seqno = 0; + list_move_tail(&tfp->list, head); + + memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len); + kfree_skb(tmp_skb); + + memmove(skb->data + uni_diff, skb->data, hdr_len); + unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff); + unicast_packet->packet_type = BAT_UNICAST; + + return skb; +} + +static void frag_create_entry(struct list_head *head, struct sk_buff *skb) +{ + struct frag_packet_list_entry *tfp; + struct unicast_frag_packet *up = + (struct unicast_frag_packet *)skb->data; + + /* free and oldest packets stand at the end */ + tfp = list_entry((head)->prev, typeof(*tfp), list); + kfree_skb(tfp->skb); + + tfp->seqno = ntohs(up->seqno); + tfp->skb = skb; + list_move(&tfp->list, head); + return; +} + +static int frag_create_buffer(struct list_head *head) +{ + int i; + struct frag_packet_list_entry *tfp; + + for (i = 0; i < FRAG_BUFFER_SIZE; i++) { + tfp = kmalloc(sizeof(struct frag_packet_list_entry), + GFP_ATOMIC); + if (!tfp) { + frag_list_free(head); + return -ENOMEM; + } + tfp->skb = NULL; + tfp->seqno = 0; + INIT_LIST_HEAD(&tfp->list); + list_add(&tfp->list, head); + } + + return 0; +} + +static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, + struct unicast_frag_packet *up) +{ + struct frag_packet_list_entry *tfp; + struct unicast_frag_packet *tmp_up = NULL; + uint16_t search_seqno; + + if (up->flags & UNI_FRAG_HEAD) + search_seqno = ntohs(up->seqno)+1; + else + search_seqno = ntohs(up->seqno)-1; + + list_for_each_entry(tfp, head, list) { + + if (!tfp->skb) + continue; + + if (tfp->seqno == ntohs(up->seqno)) + goto mov_tail; + + tmp_up = (struct unicast_frag_packet *)tfp->skb->data; + + if (tfp->seqno == search_seqno) { + + if ((tmp_up->flags & UNI_FRAG_HEAD) != + (up->flags & UNI_FRAG_HEAD)) + return tfp; + else + goto mov_tail; + } + } + return NULL; + +mov_tail: + list_move_tail(&tfp->list, head); + return NULL; +} + +void frag_list_free(struct list_head *head) +{ + struct frag_packet_list_entry *pf, *tmp_pf; + + if (!list_empty(head)) { + + list_for_each_entry_safe(pf, tmp_pf, head, list) { + kfree_skb(pf->skb); + list_del(&pf->list); + kfree(pf); + } + } + return; +} + +/* frag_reassemble_skb(): + * returns NET_RX_DROP if the operation failed - skb is left intact + * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL) + * or the skb could be reassembled (skb_new will point to the new packet and + * skb was freed) + */ +int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb) +{ + struct orig_node *orig_node; + struct frag_packet_list_entry *tmp_frag_entry; + int ret = NET_RX_DROP; + struct unicast_frag_packet *unicast_packet = + (struct unicast_frag_packet *)skb->data; + + *new_skb = NULL; + spin_lock_bh(&bat_priv->orig_hash_lock); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, + unicast_packet->orig)); + + if (!orig_node) { + pr_debug("couldn't find originator in orig_hash\n"); + goto out; + } + + orig_node->last_frag_packet = jiffies; + + if (list_empty(&orig_node->frag_list) && + frag_create_buffer(&orig_node->frag_list)) { + pr_debug("couldn't create frag buffer\n"); + goto out; + } + + tmp_frag_entry = frag_search_packet(&orig_node->frag_list, + unicast_packet); + + if (!tmp_frag_entry) { + frag_create_entry(&orig_node->frag_list, skb); + ret = NET_RX_SUCCESS; + goto out; + } + + *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, + skb); + /* if not, merge failed */ + if (*new_skb) + ret = NET_RX_SUCCESS; +out: + spin_unlock_bh(&bat_priv->orig_hash_lock); + + return ret; +} + +int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct batman_if *batman_if, uint8_t dstaddr[]) +{ + struct unicast_packet tmp_uc, *unicast_packet; + struct sk_buff *frag_skb; + struct unicast_frag_packet *frag1, *frag2; + int uc_hdr_len = sizeof(struct unicast_packet); + int ucf_hdr_len = sizeof(struct unicast_frag_packet); + int data_len = skb->len; + + if (!bat_priv->primary_if) + goto dropped; + + unicast_packet = (struct unicast_packet *) skb->data; + + memcpy(&tmp_uc, unicast_packet, uc_hdr_len); + frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); + skb_split(skb, frag_skb, data_len / 2); + + if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || + my_skb_head_push(frag_skb, ucf_hdr_len) < 0) + goto drop_frag; + + frag1 = (struct unicast_frag_packet *)skb->data; + frag2 = (struct unicast_frag_packet *)frag_skb->data; + + memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet)); + + frag1->ttl--; + frag1->version = COMPAT_VERSION; + frag1->packet_type = BAT_UNICAST_FRAG; + + memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); + + frag1->flags |= UNI_FRAG_HEAD; + frag2->flags &= ~UNI_FRAG_HEAD; + + frag1->seqno = htons((uint16_t)atomic_inc_return( + &batman_if->frag_seqno)); + frag2->seqno = htons((uint16_t)atomic_inc_return( + &batman_if->frag_seqno)); + + send_skb_packet(skb, batman_if, dstaddr); + send_skb_packet(frag_skb, batman_if, dstaddr); + return NET_RX_SUCCESS; + +drop_frag: + kfree_skb(frag_skb); +dropped: + kfree_skb(skb); + return NET_RX_DROP; +} + +int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) +{ + struct ethhdr *ethhdr = (struct ethhdr *)skb->data; + struct unicast_packet *unicast_packet; + struct orig_node *orig_node; + struct batman_if *batman_if; + struct neigh_node *router; + int data_len = skb->len; + uint8_t dstaddr[6]; + + spin_lock_bh(&bat_priv->orig_hash_lock); + + /* get routing information */ + if (is_multicast_ether_addr(ethhdr->h_dest)) + orig_node = (struct orig_node *)gw_get_selected(bat_priv); + else + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, + choose_orig, + ethhdr->h_dest)); + + /* check for hna host */ + if (!orig_node) + orig_node = transtable_search(bat_priv, ethhdr->h_dest); + + router = find_router(bat_priv, orig_node, NULL); + + if (!router) + goto unlock; + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + + batman_if = router->if_incoming; + memcpy(dstaddr, router->addr, ETH_ALEN); + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + if (batman_if->if_status != IF_ACTIVE) + goto dropped; + + if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) + goto dropped; + + unicast_packet = (struct unicast_packet *)skb->data; + + unicast_packet->version = COMPAT_VERSION; + /* batman packet type: unicast */ + unicast_packet->packet_type = BAT_UNICAST; + /* set unicast ttl */ + unicast_packet->ttl = TTL; + /* copy the destination for faster routing */ + memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); + + if (atomic_read(&bat_priv->fragmentation) && + data_len + sizeof(struct unicast_packet) > + batman_if->net_dev->mtu) { + /* send frag skb decreases ttl */ + unicast_packet->ttl++; + return frag_send_skb(skb, bat_priv, batman_if, + dstaddr); + } + send_skb_packet(skb, batman_if, dstaddr); + return 0; + +unlock: + spin_unlock_bh(&bat_priv->orig_hash_lock); +dropped: + kfree_skb(skb); + return 1; +} diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h new file mode 100644 index 000000000000..e32b7867a9a4 --- /dev/null +++ b/net/batman-adv/unicast.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Andreas Langer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_UNICAST_H_ +#define _NET_BATMAN_ADV_UNICAST_H_ + +#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ +#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ + +int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb); +void frag_list_free(struct list_head *head); +int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); +int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct batman_if *batman_if, uint8_t dstaddr[]); + +#endif /* _NET_BATMAN_ADV_UNICAST_H_ */ diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c new file mode 100644 index 000000000000..cd4c4231fa48 --- /dev/null +++ b/net/batman-adv/vis.c @@ -0,0 +1,949 @@ +/* + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "send.h" +#include "translation-table.h" +#include "vis.h" +#include "soft-interface.h" +#include "hard-interface.h" +#include "hash.h" +#include "originator.h" + +#define MAX_VIS_PACKET_SIZE 1000 + +/* Returns the smallest signed integer in two's complement with the sizeof x */ +#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) + +/* Checks if a sequence number x is a predecessor/successor of y. + * they handle overflows/underflows and can correctly check for a + * predecessor/successor unless the variable sequence number has grown by + * more then 2**(bitwidth(x)-1)-1. + * This means that for a uint8_t with the maximum value 255, it would think: + * - when adding nothing - it is neither a predecessor nor a successor + * - before adding more than 127 to the starting value - it is a predecessor, + * - when adding 128 - it is neither a predecessor nor a successor, + * - after adding more than 127 to the starting value - it is a successor */ +#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ + _dummy > smallest_signed_int(_dummy); }) +#define seq_after(x, y) seq_before(y, x) + +static void start_vis_timer(struct bat_priv *bat_priv); + +/* free the info */ +static void free_info(struct kref *ref) +{ + struct vis_info *info = container_of(ref, struct vis_info, refcount); + struct bat_priv *bat_priv = info->bat_priv; + struct recvlist_node *entry, *tmp; + + list_del_init(&info->send_list); + spin_lock_bh(&bat_priv->vis_list_lock); + list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { + list_del(&entry->list); + kfree(entry); + } + + spin_unlock_bh(&bat_priv->vis_list_lock); + kfree_skb(info->skb_packet); +} + +/* Compare two vis packets, used by the hashing algorithm */ +static int vis_info_cmp(void *data1, void *data2) +{ + struct vis_info *d1, *d2; + struct vis_packet *p1, *p2; + d1 = data1; + d2 = data2; + p1 = (struct vis_packet *)d1->skb_packet->data; + p2 = (struct vis_packet *)d2->skb_packet->data; + return compare_orig(p1->vis_orig, p2->vis_orig); +} + +/* hash function to choose an entry in a hash table of given size */ +/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ +static int vis_info_choose(void *data, int size) +{ + struct vis_info *vis_info = data; + struct vis_packet *packet; + unsigned char *key; + uint32_t hash = 0; + size_t i; + + packet = (struct vis_packet *)vis_info->skb_packet->data; + key = packet->vis_orig; + for (i = 0; i < ETH_ALEN; i++) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash % size; +} + +/* insert interface to the list of interfaces of one originator, if it + * does not already exist in the list */ +static void vis_data_insert_interface(const uint8_t *interface, + struct hlist_head *if_list, + bool primary) +{ + struct if_list_entry *entry; + struct hlist_node *pos; + + hlist_for_each_entry(entry, pos, if_list, list) { + if (compare_orig(entry->addr, (void *)interface)) + return; + } + + /* its a new address, add it to the list */ + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + if (!entry) + return; + memcpy(entry->addr, interface, ETH_ALEN); + entry->primary = primary; + hlist_add_head(&entry->list, if_list); +} + +static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) +{ + struct if_list_entry *entry; + struct hlist_node *pos; + size_t len = 0; + + hlist_for_each_entry(entry, pos, if_list, list) { + if (entry->primary) + len += sprintf(buff + len, "PRIMARY, "); + else + len += sprintf(buff + len, "SEC %pM, ", entry->addr); + } + + return len; +} + +static size_t vis_data_count_prim_sec(struct hlist_head *if_list) +{ + struct if_list_entry *entry; + struct hlist_node *pos; + size_t count = 0; + + hlist_for_each_entry(entry, pos, if_list, list) { + if (entry->primary) + count += 9; + else + count += 23; + } + + return count; +} + +/* read an entry */ +static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, + uint8_t *src, bool primary) +{ + /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ + if (primary && entry->quality == 0) + return sprintf(buff, "HNA %pM, ", entry->dest); + else if (compare_orig(entry->src, src)) + return sprintf(buff, "TQ %pM %d, ", entry->dest, + entry->quality); + + return 0; +} + +int vis_seq_print_text(struct seq_file *seq, void *offset) +{ + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct vis_info *info; + struct vis_packet *packet; + struct vis_info_entry *entries; + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct hashtable_t *hash = bat_priv->vis_hash; + HLIST_HEAD(vis_if_list); + struct if_list_entry *entry; + struct hlist_node *pos, *n; + int i, j; + int vis_server = atomic_read(&bat_priv->vis_mode); + size_t buff_pos, buf_size; + char *buff; + int compare; + + if ((!bat_priv->primary_if) || + (vis_server == VIS_TYPE_CLIENT_UPDATE)) + return 0; + + buf_size = 1; + /* Estimate length */ + spin_lock_bh(&bat_priv->vis_hash_lock); + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + info = bucket->data; + packet = (struct vis_packet *)info->skb_packet->data; + entries = (struct vis_info_entry *) + ((char *)packet + sizeof(struct vis_packet)); + + for (j = 0; j < packet->entries; j++) { + if (entries[j].quality == 0) + continue; + compare = + compare_orig(entries[j].src, packet->vis_orig); + vis_data_insert_interface(entries[j].src, + &vis_if_list, + compare); + } + + hlist_for_each_entry(entry, pos, &vis_if_list, list) { + buf_size += 18 + 26 * packet->entries; + + /* add primary/secondary records */ + if (compare_orig(entry->addr, packet->vis_orig)) + buf_size += + vis_data_count_prim_sec(&vis_if_list); + + buf_size += 1; + } + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, + list) { + hlist_del(&entry->list); + kfree(entry); + } + } + } + + buff = kmalloc(buf_size, GFP_ATOMIC); + if (!buff) { + spin_unlock_bh(&bat_priv->vis_hash_lock); + return -ENOMEM; + } + buff[0] = '\0'; + buff_pos = 0; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + info = bucket->data; + packet = (struct vis_packet *)info->skb_packet->data; + entries = (struct vis_info_entry *) + ((char *)packet + sizeof(struct vis_packet)); + + for (j = 0; j < packet->entries; j++) { + if (entries[j].quality == 0) + continue; + compare = + compare_orig(entries[j].src, packet->vis_orig); + vis_data_insert_interface(entries[j].src, + &vis_if_list, + compare); + } + + hlist_for_each_entry(entry, pos, &vis_if_list, list) { + buff_pos += sprintf(buff + buff_pos, "%pM,", + entry->addr); + + for (i = 0; i < packet->entries; i++) + buff_pos += vis_data_read_entry( + buff + buff_pos, + &entries[i], + entry->addr, + entry->primary); + + /* add primary/secondary records */ + if (compare_orig(entry->addr, packet->vis_orig)) + buff_pos += + vis_data_read_prim_sec(buff + buff_pos, + &vis_if_list); + + buff_pos += sprintf(buff + buff_pos, "\n"); + } + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, + list) { + hlist_del(&entry->list); + kfree(entry); + } + } + } + + spin_unlock_bh(&bat_priv->vis_hash_lock); + + seq_printf(seq, "%s", buff); + kfree(buff); + + return 0; +} + +/* add the info packet to the send list, if it was not + * already linked in. */ +static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) +{ + if (list_empty(&info->send_list)) { + kref_get(&info->refcount); + list_add_tail(&info->send_list, &bat_priv->vis_send_list); + } +} + +/* delete the info packet from the send list, if it was + * linked in. */ +static void send_list_del(struct vis_info *info) +{ + if (!list_empty(&info->send_list)) { + list_del_init(&info->send_list); + kref_put(&info->refcount, free_info); + } +} + +/* tries to add one entry to the receive list. */ +static void recv_list_add(struct bat_priv *bat_priv, + struct list_head *recv_list, char *mac) +{ + struct recvlist_node *entry; + + entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); + if (!entry) + return; + + memcpy(entry->mac, mac, ETH_ALEN); + spin_lock_bh(&bat_priv->vis_list_lock); + list_add_tail(&entry->list, recv_list); + spin_unlock_bh(&bat_priv->vis_list_lock); +} + +/* returns 1 if this mac is in the recv_list */ +static int recv_list_is_in(struct bat_priv *bat_priv, + struct list_head *recv_list, char *mac) +{ + struct recvlist_node *entry; + + spin_lock_bh(&bat_priv->vis_list_lock); + list_for_each_entry(entry, recv_list, list) { + if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { + spin_unlock_bh(&bat_priv->vis_list_lock); + return 1; + } + } + spin_unlock_bh(&bat_priv->vis_list_lock); + return 0; +} + +/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, + * broken.. ). vis hash must be locked outside. is_new is set when the packet + * is newer than old entries in the hash. */ +static struct vis_info *add_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len, int *is_new, + int make_broadcast) +{ + struct vis_info *info, *old_info; + struct vis_packet *search_packet, *old_packet; + struct vis_info search_elem; + struct vis_packet *packet; + int hash_added; + + *is_new = 0; + /* sanity check */ + if (!bat_priv->vis_hash) + return NULL; + + /* see if the packet is already in vis_hash */ + search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet)); + if (!search_elem.skb_packet) + return NULL; + search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet, + sizeof(struct vis_packet)); + + memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); + old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + &search_elem); + kfree_skb(search_elem.skb_packet); + + if (old_info) { + old_packet = (struct vis_packet *)old_info->skb_packet->data; + if (!seq_after(ntohl(vis_packet->seqno), + ntohl(old_packet->seqno))) { + if (old_packet->seqno == vis_packet->seqno) { + recv_list_add(bat_priv, &old_info->recv_list, + vis_packet->sender_orig); + return old_info; + } else { + /* newer packet is already in hash. */ + return NULL; + } + } + /* remove old entry */ + hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + old_info); + send_list_del(old_info); + kref_put(&old_info->refcount, free_info); + } + + info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC); + if (!info) + return NULL; + + info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) + + vis_info_len + sizeof(struct ethhdr)); + if (!info->skb_packet) { + kfree(info); + return NULL; + } + skb_reserve(info->skb_packet, sizeof(struct ethhdr)); + packet = (struct vis_packet *)skb_put(info->skb_packet, + sizeof(struct vis_packet) + + vis_info_len); + + kref_init(&info->refcount); + INIT_LIST_HEAD(&info->send_list); + INIT_LIST_HEAD(&info->recv_list); + info->first_seen = jiffies; + info->bat_priv = bat_priv; + memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len); + + /* initialize and add new packet. */ + *is_new = 1; + + /* Make it a broadcast packet, if required */ + if (make_broadcast) + memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); + + /* repair if entries is longer than packet. */ + if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len) + packet->entries = vis_info_len / sizeof(struct vis_info_entry); + + recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); + + /* try to add it */ + hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + info); + if (hash_added < 0) { + /* did not work (for some reason) */ + kref_put(&old_info->refcount, free_info); + info = NULL; + } + + return info; +} + +/* handle the server sync packet, forward if needed. */ +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) +{ + struct vis_info *info; + int is_new, make_broadcast; + int vis_server = atomic_read(&bat_priv->vis_mode); + + make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); + + spin_lock_bh(&bat_priv->vis_hash_lock); + info = add_packet(bat_priv, vis_packet, vis_info_len, + &is_new, make_broadcast); + if (!info) + goto end; + + /* only if we are server ourselves and packet is newer than the one in + * hash.*/ + if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) + send_list_add(bat_priv, info); +end: + spin_unlock_bh(&bat_priv->vis_hash_lock); +} + +/* handle an incoming client update packet and schedule forward if needed. */ +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) +{ + struct vis_info *info; + struct vis_packet *packet; + int is_new; + int vis_server = atomic_read(&bat_priv->vis_mode); + int are_target = 0; + + /* clients shall not broadcast. */ + if (is_broadcast_ether_addr(vis_packet->target_orig)) + return; + + /* Are we the target for this VIS packet? */ + if (vis_server == VIS_TYPE_SERVER_SYNC && + is_my_mac(vis_packet->target_orig)) + are_target = 1; + + spin_lock_bh(&bat_priv->vis_hash_lock); + info = add_packet(bat_priv, vis_packet, vis_info_len, + &is_new, are_target); + + if (!info) + goto end; + /* note that outdated packets will be dropped at this point. */ + + packet = (struct vis_packet *)info->skb_packet->data; + + /* send only if we're the target server or ... */ + if (are_target && is_new) { + packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ + send_list_add(bat_priv, info); + + /* ... we're not the recipient (and thus need to forward). */ + } else if (!is_my_mac(packet->target_orig)) { + send_list_add(bat_priv, info); + } + +end: + spin_unlock_bh(&bat_priv->vis_hash_lock); +} + +/* Walk the originators and find the VIS server with the best tq. Set the packet + * address to its address and return the best_tq. + * + * Must be called with the originator hash locked */ +static int find_best_vis_server(struct bat_priv *bat_priv, + struct vis_info *info) +{ + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + struct vis_packet *packet; + int best_tq = -1, i; + + packet = (struct vis_packet *)info->skb_packet->data; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + if ((orig_node) && (orig_node->router) && + (orig_node->flags & VIS_SERVER) && + (orig_node->router->tq_avg > best_tq)) { + best_tq = orig_node->router->tq_avg; + memcpy(packet->target_orig, orig_node->orig, + ETH_ALEN); + } + } + } + + return best_tq; +} + +/* Return true if the vis packet is full. */ +static bool vis_packet_full(struct vis_info *info) +{ + struct vis_packet *packet; + packet = (struct vis_packet *)info->skb_packet->data; + + if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry) + < packet->entries + 1) + return true; + return false; +} + +/* generates a packet of own vis data, + * returns 0 on success, -1 if no packet could be generated */ +static int generate_vis_packet(struct bat_priv *bat_priv) +{ + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + struct neigh_node *neigh_node; + struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; + struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; + struct vis_info_entry *entry; + struct hna_local_entry *hna_local_entry; + int best_tq = -1, i; + + info->first_seen = jiffies; + packet->vis_type = atomic_read(&bat_priv->vis_mode); + + spin_lock_bh(&bat_priv->orig_hash_lock); + memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); + packet->ttl = TTL; + packet->seqno = htonl(ntohl(packet->seqno) + 1); + packet->entries = 0; + skb_trim(info->skb_packet, sizeof(struct vis_packet)); + + if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { + best_tq = find_best_vis_server(bat_priv, info); + + if (best_tq < 0) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return -1; + } + } + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + neigh_node = orig_node->router; + + if (!neigh_node) + continue; + + if (!compare_orig(neigh_node->addr, orig_node->orig)) + continue; + + if (neigh_node->if_incoming->if_status != IF_ACTIVE) + continue; + + if (neigh_node->tq_avg < 1) + continue; + + /* fill one entry into buffer. */ + entry = (struct vis_info_entry *) + skb_put(info->skb_packet, sizeof(*entry)); + memcpy(entry->src, + neigh_node->if_incoming->net_dev->dev_addr, + ETH_ALEN); + memcpy(entry->dest, orig_node->orig, ETH_ALEN); + entry->quality = neigh_node->tq_avg; + packet->entries++; + + if (vis_packet_full(info)) { + spin_unlock_bh(&bat_priv->orig_hash_lock); + return 0; + } + } + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); + + hash = bat_priv->hna_local_hash; + + spin_lock_bh(&bat_priv->hna_lhash_lock); + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + hna_local_entry = bucket->data; + entry = (struct vis_info_entry *) + skb_put(info->skb_packet, + sizeof(*entry)); + memset(entry->src, 0, ETH_ALEN); + memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); + entry->quality = 0; /* 0 means HNA */ + packet->entries++; + + if (vis_packet_full(info)) { + spin_unlock_bh(&bat_priv->hna_lhash_lock); + return 0; + } + } + } + + spin_unlock_bh(&bat_priv->hna_lhash_lock); + return 0; +} + +/* free old vis packets. Must be called with this vis_hash_lock + * held */ +static void purge_vis_packets(struct bat_priv *bat_priv) +{ + int i; + struct hashtable_t *hash = bat_priv->vis_hash; + struct hlist_node *walk, *safe; + struct hlist_head *head; + struct element_t *bucket; + struct vis_info *info; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { + info = bucket->data; + + /* never purge own data. */ + if (info == bat_priv->my_vis_info) + continue; + + if (time_after(jiffies, + info->first_seen + VIS_TIMEOUT * HZ)) { + hlist_del(walk); + kfree(bucket); + send_list_del(info); + kref_put(&info->refcount, free_info); + } + } + } +} + +static void broadcast_vis_packet(struct bat_priv *bat_priv, + struct vis_info *info) +{ + struct hashtable_t *hash = bat_priv->orig_hash; + struct hlist_node *walk; + struct hlist_head *head; + struct element_t *bucket; + struct orig_node *orig_node; + struct vis_packet *packet; + struct sk_buff *skb; + struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; + int i; + + + spin_lock_bh(&bat_priv->orig_hash_lock); + packet = (struct vis_packet *)info->skb_packet->data; + + /* send to all routers in range. */ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + hlist_for_each_entry(bucket, walk, head, hlist) { + orig_node = bucket->data; + + /* if it's a vis server and reachable, send it. */ + if ((!orig_node) || (!orig_node->router)) + continue; + if (!(orig_node->flags & VIS_SERVER)) + continue; + /* don't send it if we already received the packet from + * this node. */ + if (recv_list_is_in(bat_priv, &info->recv_list, + orig_node->orig)) + continue; + + memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + skb = skb_clone(info->skb_packet, GFP_ATOMIC); + if (skb) + send_skb_packet(skb, batman_if, dstaddr); + + spin_lock_bh(&bat_priv->orig_hash_lock); + } + + } + + spin_unlock_bh(&bat_priv->orig_hash_lock); +} + +static void unicast_vis_packet(struct bat_priv *bat_priv, + struct vis_info *info) +{ + struct orig_node *orig_node; + struct sk_buff *skb; + struct vis_packet *packet; + struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; + + spin_lock_bh(&bat_priv->orig_hash_lock); + packet = (struct vis_packet *)info->skb_packet->data; + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, choose_orig, + packet->target_orig)); + + if ((!orig_node) || (!orig_node->router)) + goto out; + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->router->if_incoming; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_bh(&bat_priv->orig_hash_lock); + + skb = skb_clone(info->skb_packet, GFP_ATOMIC); + if (skb) + send_skb_packet(skb, batman_if, dstaddr); + + return; + +out: + spin_unlock_bh(&bat_priv->orig_hash_lock); +} + +/* only send one vis packet. called from send_vis_packets() */ +static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) +{ + struct vis_packet *packet; + + packet = (struct vis_packet *)info->skb_packet->data; + if (packet->ttl < 2) { + pr_debug("Error - can't send vis packet: ttl exceeded\n"); + return; + } + + memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, + ETH_ALEN); + packet->ttl--; + + if (is_broadcast_ether_addr(packet->target_orig)) + broadcast_vis_packet(bat_priv, info); + else + unicast_vis_packet(bat_priv, info); + packet->ttl++; /* restore TTL */ +} + +/* called from timer; send (and maybe generate) vis packet. */ +static void send_vis_packets(struct work_struct *work) +{ + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); + struct bat_priv *bat_priv = + container_of(delayed_work, struct bat_priv, vis_work); + struct vis_info *info, *temp; + + spin_lock_bh(&bat_priv->vis_hash_lock); + purge_vis_packets(bat_priv); + + if (generate_vis_packet(bat_priv) == 0) { + /* schedule if generation was successful */ + send_list_add(bat_priv, bat_priv->my_vis_info); + } + + list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, + send_list) { + + kref_get(&info->refcount); + spin_unlock_bh(&bat_priv->vis_hash_lock); + + if (bat_priv->primary_if) + send_vis_packet(bat_priv, info); + + spin_lock_bh(&bat_priv->vis_hash_lock); + send_list_del(info); + kref_put(&info->refcount, free_info); + } + spin_unlock_bh(&bat_priv->vis_hash_lock); + start_vis_timer(bat_priv); +} + +/* init the vis server. this may only be called when if_list is already + * initialized (e.g. bat0 is initialized, interfaces have been added) */ +int vis_init(struct bat_priv *bat_priv) +{ + struct vis_packet *packet; + int hash_added; + + if (bat_priv->vis_hash) + return 1; + + spin_lock_bh(&bat_priv->vis_hash_lock); + + bat_priv->vis_hash = hash_new(256); + if (!bat_priv->vis_hash) { + pr_err("Can't initialize vis_hash\n"); + goto err; + } + + bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC); + if (!bat_priv->my_vis_info) { + pr_err("Can't initialize vis packet\n"); + goto err; + } + + bat_priv->my_vis_info->skb_packet = dev_alloc_skb( + sizeof(struct vis_packet) + + MAX_VIS_PACKET_SIZE + + sizeof(struct ethhdr)); + if (!bat_priv->my_vis_info->skb_packet) + goto free_info; + + skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr)); + packet = (struct vis_packet *)skb_put( + bat_priv->my_vis_info->skb_packet, + sizeof(struct vis_packet)); + + /* prefill the vis info */ + bat_priv->my_vis_info->first_seen = jiffies - + msecs_to_jiffies(VIS_INTERVAL); + INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); + INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); + kref_init(&bat_priv->my_vis_info->refcount); + bat_priv->my_vis_info->bat_priv = bat_priv; + packet->version = COMPAT_VERSION; + packet->packet_type = BAT_VIS; + packet->ttl = TTL; + packet->seqno = 0; + packet->entries = 0; + + INIT_LIST_HEAD(&bat_priv->vis_send_list); + + hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + bat_priv->my_vis_info); + if (hash_added < 0) { + pr_err("Can't add own vis packet into hash\n"); + /* not in hash, need to remove it manually. */ + kref_put(&bat_priv->my_vis_info->refcount, free_info); + goto err; + } + + spin_unlock_bh(&bat_priv->vis_hash_lock); + start_vis_timer(bat_priv); + return 1; + +free_info: + kfree(bat_priv->my_vis_info); + bat_priv->my_vis_info = NULL; +err: + spin_unlock_bh(&bat_priv->vis_hash_lock); + vis_quit(bat_priv); + return 0; +} + +/* Decrease the reference count on a hash item info */ +static void free_info_ref(void *data, void *arg) +{ + struct vis_info *info = data; + + send_list_del(info); + kref_put(&info->refcount, free_info); +} + +/* shutdown vis-server */ +void vis_quit(struct bat_priv *bat_priv) +{ + if (!bat_priv->vis_hash) + return; + + cancel_delayed_work_sync(&bat_priv->vis_work); + + spin_lock_bh(&bat_priv->vis_hash_lock); + /* properly remove, kill timers ... */ + hash_delete(bat_priv->vis_hash, free_info_ref, NULL); + bat_priv->vis_hash = NULL; + bat_priv->my_vis_info = NULL; + spin_unlock_bh(&bat_priv->vis_hash_lock); +} + +/* schedule packets for (re)transmission */ +static void start_vis_timer(struct bat_priv *bat_priv) +{ + INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets); + queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work, + msecs_to_jiffies(VIS_INTERVAL)); +} diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h new file mode 100644 index 000000000000..2c3b33089a9b --- /dev/null +++ b/net/batman-adv/vis.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_VIS_H_ +#define _NET_BATMAN_ADV_VIS_H_ + +#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */ + +int vis_seq_print_text(struct seq_file *seq, void *offset); +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len); +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len); +int vis_init(struct bat_priv *bat_priv); +void vis_quit(struct bat_priv *bat_priv); + +#endif /* _NET_BATMAN_ADV_VIS_H_ */ -- cgit v1.2.3-59-g8ed1b From 443457242beb6716b43db4d62fe148eab5515505 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Mon, 13 Dec 2010 12:44:07 +0000 Subject: net: factorize sync-rcu call in unregister_netdevice_many Add dev_close_many and dev_deactivate_many to factorize another sync-rcu operation on the netdevice unregister path. $ modprobe dummy numdummies=10000 $ ip link set dev dummy* up $ time rmmod dummy Without the patch With the patch real 0m 24.63s real 0m 5.15s user 0m 0.00s user 0m 0.00s sys 0m 6.05s sys 0m 5.14s Signed-off-by: Octavian Purdila Signed-off-by: David S. Miller --- include/net/sch_generic.h | 1 + net/core/dev.c | 118 +++++++++++++++++++++++++++++----------------- net/sched/sch_generic.c | 29 +++++++++--- 3 files changed, 99 insertions(+), 49 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ea1f8a83160d..786cc396cb4a 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -321,6 +321,7 @@ extern void dev_init_scheduler(struct net_device *dev); extern void dev_shutdown(struct net_device *dev); extern void dev_activate(struct net_device *dev); extern void dev_deactivate(struct net_device *dev); +extern void dev_deactivate_many(struct list_head *head); extern struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, struct Qdisc *qdisc); extern void qdisc_reset(struct Qdisc *qdisc); diff --git a/net/core/dev.c b/net/core/dev.c index 7ac26d2b9722..794b20de5d44 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1222,52 +1222,90 @@ int dev_open(struct net_device *dev) } EXPORT_SYMBOL(dev_open); -static int __dev_close(struct net_device *dev) +static int __dev_close_many(struct list_head *head) { - const struct net_device_ops *ops = dev->netdev_ops; + struct net_device *dev; ASSERT_RTNL(); might_sleep(); - /* - * Tell people we are going down, so that they can - * prepare to death, when device is still operating. - */ - call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); + list_for_each_entry(dev, head, unreg_list) { + /* + * Tell people we are going down, so that they can + * prepare to death, when device is still operating. + */ + call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); - clear_bit(__LINK_STATE_START, &dev->state); + clear_bit(__LINK_STATE_START, &dev->state); - /* Synchronize to scheduled poll. We cannot touch poll list, - * it can be even on different cpu. So just clear netif_running(). - * - * dev->stop() will invoke napi_disable() on all of it's - * napi_struct instances on this device. - */ - smp_mb__after_clear_bit(); /* Commit netif_running(). */ + /* Synchronize to scheduled poll. We cannot touch poll list, it + * can be even on different cpu. So just clear netif_running(). + * + * dev->stop() will invoke napi_disable() on all of it's + * napi_struct instances on this device. + */ + smp_mb__after_clear_bit(); /* Commit netif_running(). */ + } - dev_deactivate(dev); + dev_deactivate_many(head); - /* - * Call the device specific close. This cannot fail. - * Only if device is UP - * - * We allow it to be called even after a DETACH hot-plug - * event. - */ - if (ops->ndo_stop) - ops->ndo_stop(dev); + list_for_each_entry(dev, head, unreg_list) { + const struct net_device_ops *ops = dev->netdev_ops; - /* - * Device is now down. - */ + /* + * Call the device specific close. This cannot fail. + * Only if device is UP + * + * We allow it to be called even after a DETACH hot-plug + * event. + */ + if (ops->ndo_stop) + ops->ndo_stop(dev); + + /* + * Device is now down. + */ + + dev->flags &= ~IFF_UP; + + /* + * Shutdown NET_DMA + */ + net_dmaengine_put(); + } - dev->flags &= ~IFF_UP; + return 0; +} + +static int __dev_close(struct net_device *dev) +{ + LIST_HEAD(single); + + list_add(&dev->unreg_list, &single); + return __dev_close_many(&single); +} + +int dev_close_many(struct list_head *head) +{ + struct net_device *dev, *tmp; + LIST_HEAD(tmp_list); + + list_for_each_entry_safe(dev, tmp, head, unreg_list) + if (!(dev->flags & IFF_UP)) + list_move(&dev->unreg_list, &tmp_list); + + __dev_close_many(head); /* - * Shutdown NET_DMA + * Tell people we are down */ - net_dmaengine_put(); + list_for_each_entry(dev, head, unreg_list) { + rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); + call_netdevice_notifiers(NETDEV_DOWN, dev); + } + /* rollback_registered_many needs the complete original list */ + list_splice(&tmp_list, head); return 0; } @@ -1282,16 +1320,10 @@ static int __dev_close(struct net_device *dev) */ int dev_close(struct net_device *dev) { - if (!(dev->flags & IFF_UP)) - return 0; - - __dev_close(dev); + LIST_HEAD(single); - /* - * Tell people we are down - */ - rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); - call_netdevice_notifiers(NETDEV_DOWN, dev); + list_add(&dev->unreg_list, &single); + dev_close_many(&single); return 0; } @@ -4963,10 +4995,12 @@ static void rollback_registered_many(struct list_head *head) } BUG_ON(dev->reg_state != NETREG_REGISTERED); + } - /* If device is running, close it first. */ - dev_close(dev); + /* If device is running, close it first. */ + dev_close_many(head); + list_for_each_entry(dev, head, unreg_list) { /* And unlink it from device chain. */ unlist_netdevice(dev); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 0918834ee4a1..34dc598440a2 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -810,20 +810,35 @@ static bool some_qdisc_is_busy(struct net_device *dev) return false; } -void dev_deactivate(struct net_device *dev) +void dev_deactivate_many(struct list_head *head) { - netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); - if (dev_ingress_queue(dev)) - dev_deactivate_queue(dev, dev_ingress_queue(dev), &noop_qdisc); + struct net_device *dev; - dev_watchdog_down(dev); + list_for_each_entry(dev, head, unreg_list) { + netdev_for_each_tx_queue(dev, dev_deactivate_queue, + &noop_qdisc); + if (dev_ingress_queue(dev)) + dev_deactivate_queue(dev, dev_ingress_queue(dev), + &noop_qdisc); + + dev_watchdog_down(dev); + } /* Wait for outstanding qdisc-less dev_queue_xmit calls. */ synchronize_rcu(); /* Wait for outstanding qdisc_run calls. */ - while (some_qdisc_is_busy(dev)) - yield(); + list_for_each_entry(dev, head, unreg_list) + while (some_qdisc_is_busy(dev)) + yield(); +} + +void dev_deactivate(struct net_device *dev) +{ + LIST_HEAD(single); + + list_add(&dev->unreg_list, &single); + dev_deactivate_many(&single); } static void dev_init_scheduler_queue(struct net_device *dev, -- cgit v1.2.3-59-g8ed1b From bc2ce894e113ed95b92541134b002fdc641e8080 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 16 Dec 2010 14:08:34 -0800 Subject: tcp: relax tcp_paws_check() Some windows versions have wrong RFC1323 implementations, with SYN and SYNACKS messages containing zero tcp timestamps. We relaxed in commit fc1ad92dfc4e363 the passive connection case (Windows connects to a linux machine), but the reverse case (linux connects to a Windows machine) has an analogue problem when tsvals from windows machine are 'negative' (high order bit set) : PAWS triggers and we drops incoming messages. Fix this by making zero ts_recent value special, allowing frame to be processed. Based on a report and initial patch from Dmitiy Balakin Bugzilla reference : https://bugzilla.kernel.org/show_bug.cgi?id=24842 Reported-by: dmitriy.balakin@nicneiron.ru Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/tcp.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 3f227baee4be..2ab6c9c1c53a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1038,7 +1038,13 @@ static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, return 1; if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)) return 1; - + /* + * Some OSes send SYN and SYNACK messages with tsval=0 tsecr=0, + * then following tcp messages have valid values. Ignore 0 value, + * or else 'negative' tsval might forbid us to accept their packets. + */ + if (!rx_opt->ts_recent) + return 1; return 0; } -- cgit v1.2.3-59-g8ed1b From 04fb451eff978ca059399eab83d5594b073caf6f Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 14 Dec 2010 15:24:08 +0000 Subject: net: Introduce skb_checksum_start_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce skb_checksum_start_offset() to replace repetitive calculation. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- include/linux/skbuff.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4c4bec6316d9..20ec0a64cb9f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1355,6 +1355,11 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) } #endif /* NET_SKBUFF_DATA_USES_OFFSET */ +static inline int skb_checksum_start_offset(const struct sk_buff *skb) +{ + return skb->csum_start - skb_headroom(skb); +} + static inline int skb_transport_offset(const struct sk_buff *skb) { return skb_transport_header(skb) - skb->data; -- cgit v1.2.3-59-g8ed1b From 55508d601dab7df5cbcc7a63f4be8620eface204 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 14 Dec 2010 15:24:08 +0000 Subject: net: Use skb_checksum_start_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace skb->csum_start - skb_headroom(skb) with skb_checksum_start_offset(). Note for usb/smsc95xx: skb->data - skb->head == skb_headroom(skb). Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/atlx/atl1.c | 2 +- drivers/net/macvtap.c | 3 +-- drivers/net/tun.c | 2 +- drivers/net/usb/smsc95xx.c | 7 +++---- drivers/net/virtio_net.c | 2 +- net/core/dev.c | 6 +++--- net/core/skbuff.c | 2 +- net/ipv4/udp.c | 2 +- net/packet/af_packet.c | 3 +-- 9 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 53363108994e..def8df83359c 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2174,7 +2174,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, u8 css, cso; if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { - css = (u8) (skb->csum_start - skb_headroom(skb)); + css = skb_checksum_start_offset(skb); cso = css + (u8) skb->csum_offset; if (unlikely(css & 0x1)) { /* L1 hardware requires an even number here */ diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 42567279843e..21845affea13 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -504,8 +504,7 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, if (skb->ip_summed == CHECKSUM_PARTIAL) { vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - vnet_hdr->csum_start = skb->csum_start - - skb_headroom(skb); + vnet_hdr->csum_start = skb_checksum_start_offset(skb); vnet_hdr->csum_offset = skb->csum_offset; } /* else everything is zero */ diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 55f3a3e667a9..7599c457abd1 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -757,7 +757,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, if (skb->ip_summed == CHECKSUM_PARTIAL) { gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - gso.csum_start = skb->csum_start - skb_headroom(skb); + gso.csum_start = skb_checksum_start_offset(skb); gso.csum_offset = skb->csum_offset; } /* else everything is zero */ diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 65cb1abfbe57..bc86f4b6ecc2 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1163,9 +1163,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb) { - int len = skb->data - skb->head; - u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len); - u16 low_16 = (u16)(skb->csum_start - len); + u16 low_16 = (u16)skb_checksum_start_offset(skb); + u16 high_16 = low_16 + skb->csum_offset; return (high_16 << 16) | low_16; } @@ -1193,7 +1192,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, if (skb->len <= 45) { /* workaround - hardware tx checksum does not work * properly with extremely small packets */ - long csstart = skb->csum_start - skb_headroom(skb); + long csstart = skb_checksum_start_offset(skb); __wsum calc = csum_partial(skb->data + csstart, skb->len - csstart, 0); *((__sum16 *)(skb->data + csstart diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b6d402806ae6..90a23e410d1b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -519,7 +519,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) if (skb->ip_summed == CHECKSUM_PARTIAL) { hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - hdr->hdr.csum_start = skb->csum_start - skb_headroom(skb); + hdr->hdr.csum_start = skb_checksum_start_offset(skb); hdr->hdr.csum_offset = skb->csum_offset; } else { hdr->hdr.flags = 0; diff --git a/net/core/dev.c b/net/core/dev.c index 794b20de5d44..92d414ac0e30 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1793,7 +1793,7 @@ int skb_checksum_help(struct sk_buff *skb) goto out_set_summed; } - offset = skb->csum_start - skb_headroom(skb); + offset = skb_checksum_start_offset(skb); BUG_ON(offset >= skb_headlen(skb)); csum = skb_checksum(skb, offset, skb->len - offset, 0); @@ -2090,8 +2090,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, * checksumming here. */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - skb_set_transport_header(skb, skb->csum_start - - skb_headroom(skb)); + skb_set_transport_header(skb, + skb_checksum_start_offset(skb)); if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb)) goto out_kfree_skb; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8814a9a52f47..19d6c21220fd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1824,7 +1824,7 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) long csstart; if (skb->ip_summed == CHECKSUM_PARTIAL) - csstart = skb->csum_start - skb_headroom(skb); + csstart = skb_checksum_start_offset(skb); else csstart = skb_headlen(skb); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b37181da487c..1198adf45102 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2226,7 +2226,7 @@ struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features) /* Do software UFO. Complete and fill in the UDP checksum as HW cannot * do checksum of UDP packets sent as multiple IP fragments. */ - offset = skb->csum_start - skb_headroom(skb); + offset = skb_checksum_start_offset(skb); csum = skb_checksum(skb, offset, skb->len - offset, 0); offset += skb->csum_offset; *(__sum16 *)(skb->data + offset) = csum_fold(csum); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e79efaf06389..91cb1d71f018 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1650,8 +1650,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, if (skb->ip_summed == CHECKSUM_PARTIAL) { vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - vnet_hdr.csum_start = skb->csum_start - - skb_headroom(skb); + vnet_hdr.csum_start = skb_checksum_start_offset(skb); vnet_hdr.csum_offset = skb->csum_offset; } /* else everything is zero */ -- cgit v1.2.3-59-g8ed1b From 0d0b16727f24f8258eeb33818347ca0f4557f982 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 14 Dec 2010 15:24:08 +0000 Subject: net: Fix drivers advertising HW_CSUM feature to use csum_start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some drivers are using skb_transport_offset(skb) instead of skb->csum_start for NETIF_F_HW_CSUM offload. This does not matter now, but if someone implements checksumming of encapsulated packets then this will break silently. TSO output paths are left as they are, since they are for IP+TCP only (might be worth converting though). Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/cassini.c | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/enic/enic_main.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/ll_temac_main.c | 2 +- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/skge.c | 2 +- drivers/net/sungem.c | 2 +- drivers/net/sunhme.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 4 ++-- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 09b099bfab2b..e48ea956c51f 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2078,7 +2078,7 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, check_sum: if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { u8 css, cso; - cso = skb_transport_offset(skb); + cso = skb_checksum_start_offset(skb); if (unlikely(cso & 0x1)) { if (netif_msg_tx_err(adapter)) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index ef6349bf3b33..e28f8baf394e 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1649,7 +1649,7 @@ check_sum: if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { u8 css, cso; - cso = skb_transport_offset(skb); + cso = skb_checksum_start_offset(skb); if (unlikely(cso & 0x1)) { netdev_err(adapter->netdev, "payload offset should not ant event number\n"); diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index a8a32bc9aae6..73502fef8769 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2788,7 +2788,7 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring, ctrl = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const u64 csum_start_off = skb_transport_offset(skb); + const u64 csum_start_off = skb_checksum_start_offset(skb); const u64 csum_stuff_off = csum_start_off + skb->csum_offset; ctrl = TX_DESC_CSUM_EN | diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 491bf2a1babd..340e12d2e4a9 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2726,7 +2726,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, break; } - css = skb_transport_offset(skb); + css = skb_checksum_start_offset(skb); i = tx_ring->next_to_use; buffer_info = &tx_ring->buffer_info[i]; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 02d093d1dd5c..a45dafdf343a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4473,7 +4473,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) break; } - css = skb_transport_offset(skb); + css = skb_checksum_start_offset(skb); i = tx_ring->next_to_use; buffer_info = &tx_ring->buffer_info[i]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 77d91381a74d..9710047c12a4 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -702,7 +702,7 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic, { unsigned int head_len = skb_headlen(skb); unsigned int len_left = skb->len - head_len; - unsigned int hdr_len = skb_transport_offset(skb); + unsigned int hdr_len = skb_checksum_start_offset(skb); unsigned int csum_offset = hdr_len + skb->csum_offset; int eop = (len_left == 0); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index b021798ef49f..5639cccb4935 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1262,7 +1262,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { struct ixgb_buffer *buffer_info; - css = skb_transport_offset(skb); + css = skb_checksum_start_offset(skb); cso = css + skb->csum_offset; i = adapter->tx_ring.next_to_use; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 9f8e7027b0b3..e2c2a7202dba 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -692,7 +692,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->app0 = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - unsigned int csum_start_off = skb_transport_offset(skb); + unsigned int csum_start_off = skb_checksum_start_offset(skb); unsigned int csum_index_off = csum_start_off + skb->csum_offset; cur_p->app0 |= 1; /* TX Checksum Enabled */ diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 1ce0207e62a9..a37fcf11ab36 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2736,7 +2736,7 @@ again: odd_flag = 0; flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST); if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { - cksum_offset = skb_transport_offset(skb); + cksum_offset = skb_checksum_start_offset(skb); pseudo_hdr_offset = cksum_offset + skb->csum_offset; /* If the headers are excessively large, then we must * fall back to a software checksum */ diff --git a/drivers/net/niu.c b/drivers/net/niu.c index f64c42414bd7..2541321bad82 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -6589,7 +6589,7 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr, (ip_proto == IPPROTO_UDP ? TXHDR_CSUM_UDP : TXHDR_CSUM_SCTP)); - start = skb_transport_offset(skb) - + start = skb_checksum_start_offset(skb) - (pad_bytes + sizeof(struct tx_pkt_hdr)); stuff = start + skb->csum_offset; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8c1404b58382..50815fb963fe 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2764,7 +2764,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, td->dma_hi = map >> 32; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const int offset = skb_transport_offset(skb); + const int offset = skb_checksum_start_offset(skb); /* This seems backwards, but it is what the sk98lin * does. Looks like hardware is wrong? diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 9e992ca4f543..1c5408f83937 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1004,7 +1004,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, ctrl = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const u64 csum_start_off = skb_transport_offset(skb); + const u64 csum_start_off = skb_checksum_start_offset(skb); const u64 csum_stuff_off = csum_start_off + skb->csum_offset; ctrl = (TXDCTRL_CENAB | diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 5e28c414421a..55bbb9c15d96 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2266,7 +2266,7 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb, tx_flags = TXFLAG_OWN; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const u32 csum_start_off = skb_transport_offset(skb); + const u32 csum_start_off = skb_checksum_start_offset(skb); const u32 csum_stuff_off = csum_start_off + skb->csum_offset; tx_flags = (TXFLAG_OWN | TXFLAG_CSENABLE | diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 0169be7694a9..23154cf601e9 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -798,7 +798,7 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, { struct Vmxnet3_TxDataDesc *tdd; - if (ctx->mss) { + if (ctx->mss) { /* TSO */ ctx->eth_ip_hdr_size = skb_transport_offset(skb); ctx->l4_hdr_size = ((struct tcphdr *) skb_transport_header(skb))->doff * 4; @@ -807,7 +807,7 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, unsigned int pull_size; if (skb->ip_summed == CHECKSUM_PARTIAL) { - ctx->eth_ip_hdr_size = skb_transport_offset(skb); + ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb); if (ctx->ipv4) { struct iphdr *iph = (struct iphdr *) -- cgit v1.2.3-59-g8ed1b From 7edc3453e54432a9f1c636b6481f1107c9db19bd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Dec 2010 23:52:55 +0000 Subject: ifb: fix a lockdep splat After recent ifb changes, we must use lockless __skb_dequeue() since lock is not anymore initialized. Signed-off-by: Eric Dumazet Cc: Jamal Hadi Salim Cc: Changli Gao Acked-by: Changli Gao Signed-off-by: David S. Miller --- drivers/net/ifb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index bfa03db66691..8bcacd7c7715 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -71,7 +71,7 @@ static void ri_tasklet(unsigned long dev) } } - while ((skb = skb_dequeue(&dp->tq)) != NULL) { + while ((skb = __skb_dequeue(&dp->tq)) != NULL) { u32 from = G_TC_FROM(skb->tc_verd); skb->tc_verd = 0; -- cgit v1.2.3-59-g8ed1b From c75822a3091a899d982d59cd2b4454fe7c3e0318 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 16 Dec 2010 22:59:00 +0000 Subject: qlcnic: fix LED test when interface is down. When interface is down, create temporary context to config LED. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_ethtool.c | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index f267da42f243..4028d0c08f2c 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -925,6 +925,7 @@ struct qlcnic_ipaddr { #define QLCNIC_INTERRUPT_TEST 1 #define QLCNIC_LOOPBACK_TEST 2 +#define QLCNIC_LED_TEST 3 #define QLCNIC_FILTER_AGE 80 #define QLCNIC_READD_AGE 20 diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 0eaf31bf8a0d..1e7af709d395 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -834,16 +834,27 @@ static int qlcnic_set_tso(struct net_device *dev, u32 data) static int qlcnic_blink_led(struct net_device *dev, u32 val) { struct qlcnic_adapter *adapter = netdev_priv(dev); + int max_sds_rings = adapter->max_sds_rings; + int dev_down = 0; int ret; - if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) - return -EIO; + if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { + dev_down = 1; + if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) + return -EIO; + + ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST); + if (ret) { + clear_bit(__QLCNIC_RESETTING, &adapter->state); + return ret; + } + } ret = adapter->nic_ops->config_led(adapter, 1, 0xf); if (ret) { dev_err(&adapter->pdev->dev, "Failed to set LED blink state.\n"); - return ret; + goto done; } msleep_interruptible(val * 1000); @@ -852,10 +863,16 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val) if (ret) { dev_err(&adapter->pdev->dev, "Failed to reset LED blink state.\n"); - return ret; + goto done; } - return 0; +done: + if (dev_down) { + qlcnic_diag_free_res(dev, max_sds_rings); + clear_bit(__QLCNIC_RESETTING, &adapter->state); + } + return ret; + } static void -- cgit v1.2.3-59-g8ed1b From b5006dcb10a4b19e86f413b46787c55bd0d1277b Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Thu, 16 Dec 2010 22:59:01 +0000 Subject: qlcnic: fix ocm window register offset calculation OCM window register offset was calculated incorrectly for pci function greater than zero. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_hdr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 19328e05b75d..726ef555b6bc 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -621,7 +621,7 @@ enum { #define PCIX_INT_MASK (0x10104) #define PCIX_OCM_WINDOW (0x10800) -#define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x20 * (func)) +#define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x4 * (func)) #define PCIX_TARGET_STATUS (0x10118) #define PCIX_TARGET_STATUS_F1 (0x10160) -- cgit v1.2.3-59-g8ed1b From 1dc0f3c54ce1df957f99c17b145488fd03eb1a59 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Thu, 16 Dec 2010 22:59:02 +0000 Subject: qlcnic: reset pci function unconditionally during probe Some boot code drivers dont have cleanup routine, so pci function remains in unknown state prior to driver load. So during driver load issue FLR unconditionally. Update driver version to 5.0.14. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- drivers/net/qlcnic/qlcnic_main.c | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 4028d0c08f2c..9c2a02d204dc 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -34,8 +34,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 13 -#define QLCNIC_LINUX_VERSIONID "5.0.13" +#define _QLCNIC_LINUX_SUBVERSION 14 +#define QLCNIC_LINUX_VERSIONID "5.0.14" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 788850e2ba4e..11e3a46c0911 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1468,7 +1468,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) uint8_t revision_id; uint8_t pci_using_dac; char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; - u32 val; err = pci_enable_device(pdev); if (err) @@ -1530,9 +1529,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_out_iounmap; - val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); - if (QLC_DEV_CHECK_ACTIVE(val, adapter->portnum)) - adapter->flags |= QLCNIC_NEED_FLR; + adapter->flags |= QLCNIC_NEED_FLR; err = adapter->nic_ops->start_firmware(adapter); if (err) { -- cgit v1.2.3-59-g8ed1b From bc3ef6605ea325e41b586a76aadc3f731c317504 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 16 Dec 2010 17:42:40 +0000 Subject: ipv6: fib6_ifdown cleanup Remove (unnecessary) casts to make code cleaner. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv6/route.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d5c3b45d829e..373bd0416f69 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2009,11 +2009,11 @@ struct arg_dev_net { static int fib6_ifdown(struct rt6_info *rt, void *arg) { - struct net_device *dev = ((struct arg_dev_net *)arg)->dev; - struct net *net = ((struct arg_dev_net *)arg)->net; + const struct arg_dev_net *adn = arg; + const struct net_device *dev = adn->dev; - if (((void *)rt->rt6i_dev == dev || dev == NULL) && - rt != net->ipv6.ip6_null_entry) { + if ((rt->rt6i_dev == dev || dev == NULL) && + rt != adn->net->ipv6.ip6_null_entry) { RT6_TRACE("deleted by ifdown %p\n", rt); return -1; } -- cgit v1.2.3-59-g8ed1b From d1ed113f1669390da9898da3beddcc058d938587 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 16 Dec 2010 17:42:54 +0000 Subject: ipv6: remove duplicate neigh_ifdown When device is being set to down, neigh_ifdown was being called twice. Once from addrconf notifier and once from ndisc notifier. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 99d1888af363..5b189c97c2fc 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2672,7 +2672,6 @@ static int addrconf_ifdown(struct net_device *dev, int how) /* Flush routes if device is being removed or it is not loopback */ if (how || !(dev->flags & IFF_LOOPBACK)) rt6_ifdown(net, dev); - neigh_ifdown(&nd_tbl, dev); idev = __in6_dev_get(dev); if (idev == NULL) -- cgit v1.2.3-59-g8ed1b From 1a75972c61f2c224eb5283c183f9f6b17fb09b6b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 14 Dec 2010 22:39:58 +0000 Subject: ifb: use netif_receive_skb() instead of netif_rx() In ri_tasklet(), we run from softirq, so can directly handle packet through netif_receive_skb() instead of netif_rx(). There is no risk of recursion. Signed-off-by: Eric Dumazet Acked-by: Changli Gao Signed-off-by: David S. Miller --- drivers/net/ifb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 8bcacd7c7715..124dac4532b2 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -96,7 +96,7 @@ static void ri_tasklet(unsigned long dev) dev_queue_xmit(skb); } else if (from & AT_INGRESS) { skb_pull(skb, skb->dev->hard_header_len); - netif_rx(skb); + netif_receive_skb(skb); } else BUG(); } -- cgit v1.2.3-59-g8ed1b From 71d9dec24dce548bf699815c976cf063ad9257e2 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 15 Dec 2010 19:57:25 +0000 Subject: net: increase skb->users instead of skb_clone() In dev_queue_xmit_nit(), we have to clone skbs as we need to mangle skbs, however, we don't need to clone skbs for all the packet_types. Except for the first packet_type, we increase skb->users instead of skb_clone(). Signed-off-by: Changli Gao Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 92d414ac0e30..59877290bca7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1528,6 +1528,14 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(dev_forward_skb); +static inline int deliver_skb(struct sk_buff *skb, + struct packet_type *pt_prev, + struct net_device *orig_dev) +{ + atomic_inc(&skb->users); + return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); +} + /* * Support routine. Sends outgoing frames to any network * taps currently in use. @@ -1536,6 +1544,8 @@ EXPORT_SYMBOL_GPL(dev_forward_skb); static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) { struct packet_type *ptype; + struct sk_buff *skb2 = NULL; + struct packet_type *pt_prev = NULL; #ifdef CONFIG_NET_CLS_ACT if (!(skb->tstamp.tv64 && (G_TC_FROM(skb->tc_verd) & AT_INGRESS))) @@ -1552,7 +1562,13 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) if ((ptype->dev == dev || !ptype->dev) && (ptype->af_packet_priv == NULL || (struct sock *)ptype->af_packet_priv != skb->sk)) { - struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (pt_prev) { + deliver_skb(skb2, pt_prev, skb->dev); + pt_prev = ptype; + continue; + } + + skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) break; @@ -1574,9 +1590,11 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) skb2->transport_header = skb2->network_header; skb2->pkt_type = PACKET_OUTGOING; - ptype->func(skb2, skb->dev, ptype, skb->dev); + pt_prev = ptype; } } + if (pt_prev) + pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); rcu_read_unlock(); } @@ -2820,14 +2838,6 @@ static void net_tx_action(struct softirq_action *h) } } -static inline int deliver_skb(struct sk_buff *skb, - struct packet_type *pt_prev, - struct net_device *orig_dev) -{ - atomic_inc(&skb->users); - return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); -} - #if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \ (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)) /* This hook is defined here for ATM LANE */ -- cgit v1.2.3-59-g8ed1b From ba27d85c96c57111ae8acfa959643e5ce8e4bcbe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 15 Dec 2010 04:03:29 +0000 Subject: vxge: add missing flush of reset_task Commit 6e07ebd84 (drivers/net: remove unnecessary flush_scheduled_work() calls) incorrectly removed the flush call without replacing it with the appropriate work specific operation. Fix it by flushing vdev->reset_task explicitly. Pointed out by Jon Mason. Signed-off-by: Tejun Heo Cc: Jon Mason Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 537ad874f11c..1ac9b568f1b0 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3439,6 +3439,8 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) strncpy(buf, dev->name, IFNAMSIZ); + flush_work_sync(&vdev->reset_task); + /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); -- cgit v1.2.3-59-g8ed1b From 4c306a9291a077879fc3e933326caac3bc319caa Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Sun, 19 Dec 2010 21:59:35 -0800 Subject: net: kill unused macros These macros never be used, so remove them. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 1 - include/net/tcp.h | 2 -- net/atm/mpc.c | 2 -- net/core/neighbour.c | 1 - net/core/netpoll.c | 1 - net/netlabel/netlabel_cipso_v4.h | 1 - net/netlabel/netlabel_mgmt.h | 1 - net/netlabel/netlabel_unlabeled.h | 1 - 8 files changed, 10 deletions(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 6c93a56cc958..6ac4e3b5007f 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -132,7 +132,6 @@ struct inet_connection_sock { #define ICSK_TIME_RETRANS 1 /* Retransmit timer */ #define ICSK_TIME_DACK 2 /* Delayed ack timer */ #define ICSK_TIME_PROBE0 3 /* Zero window probe timer */ -#define ICSK_TIME_KEEPOPEN 4 /* Keepalive timer */ static inline struct inet_connection_sock *inet_csk(const struct sock *sk) { diff --git a/include/net/tcp.h b/include/net/tcp.h index 2ab6c9c1c53a..b4480300cadf 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1158,8 +1158,6 @@ struct tcp_md5sig_pool { union tcp_md5sum_block md5_blk; }; -#define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */ - /* - functions */ extern int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, struct sock *sk, struct request_sock *req, diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 74bcc662c3dd..644cdf071642 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -64,8 +64,6 @@ do { if (0) printk(KERN_CONT format, ##args); } while (0) #endif -#define MPOA_TAG_LEN 4 - /* mpc_daemon -> kernel */ static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc); static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8cc8f9a79db9..60a902913429 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -41,7 +41,6 @@ #define NEIGH_PRINTK(x...) printk(x) #define NEIGH_NOPRINTK(x...) do { ; } while(0) -#define NEIGH_PRINTK0 NEIGH_PRINTK #define NEIGH_PRINTK1 NEIGH_NOPRINTK #define NEIGH_PRINTK2 NEIGH_NOPRINTK diff --git a/net/core/netpoll.c b/net/core/netpoll.c index ee38acb6d463..72d9b50109fc 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -35,7 +35,6 @@ #define MAX_UDP_CHUNK 1460 #define MAX_SKBS 32 -#define MAX_QUEUE_DEPTH (MAX_SKBS / 2) static struct sk_buff_head skb_pool; diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h index c8a4079261f0..af7f3355103e 100644 --- a/net/netlabel/netlabel_cipso_v4.h +++ b/net/netlabel/netlabel_cipso_v4.h @@ -107,7 +107,6 @@ enum { NLBL_CIPSOV4_C_LISTALL, __NLBL_CIPSOV4_C_MAX, }; -#define NLBL_CIPSOV4_C_MAX (__NLBL_CIPSOV4_C_MAX - 1) /* NetLabel CIPSOv4 attributes */ enum { diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h index 05d96431f819..0a25838bcf45 100644 --- a/net/netlabel/netlabel_mgmt.h +++ b/net/netlabel/netlabel_mgmt.h @@ -173,7 +173,6 @@ enum { NLBL_MGMT_C_VERSION, __NLBL_MGMT_C_MAX, }; -#define NLBL_MGMT_C_MAX (__NLBL_MGMT_C_MAX - 1) /* NetLabel Management attributes */ enum { diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 7aba63595137..0bc8dc3f9e3c 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -180,7 +180,6 @@ enum { NLBL_UNLABEL_C_STATICLISTDEF, __NLBL_UNLABEL_C_MAX, }; -#define NLBL_UNLABEL_C_MAX (__NLBL_UNLABEL_C_MAX - 1) /* NetLabel Unlabeled attributes */ enum { -- cgit v1.2.3-59-g8ed1b From 58231186c4532821cb815a3a3248ca02ce5f6f0d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 20 Dec 2010 10:30:06 -0800 Subject: pktgen: Remove unnecessary prefix from pr_ Remove "pktgen: " prefix string from one pr_info. pr_fmt adds it, so this is a duplicate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/core/pktgen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 18fe20dacc60..a9e7fc4c461f 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3553,8 +3553,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) break; default: /* Drivers are not supposed to return other values! */ if (net_ratelimit()) - pr_info("pktgen: %s xmit error: %d\n", - pkt_dev->odevname, ret); + pr_info("%s xmit error: %d\n", pkt_dev->odevname, ret); pkt_dev->errors++; /* fallthru */ case NETDEV_TX_LOCKED: -- cgit v1.2.3-59-g8ed1b From 53320fe3bb1b1eef1aaff8dd47aae530ebeeb1e5 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 20 Dec 2010 10:32:03 -0800 Subject: batman-adv: Return hna count on local buffer fill hna_local_fill_buffer must return the number of added hna entries and not the last checked hash bucket. Signed-off-by: Sven Eckelmann Signed-off-by: David S. Miller --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a19e16c94da5..a633b5a435e2 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -162,7 +162,7 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv, atomic_set(&bat_priv->hna_local_changed, 0); spin_unlock_bh(&bat_priv->hna_lhash_lock); - return i; + return count; } int hna_local_seq_print_text(struct seq_file *seq, void *offset) -- cgit v1.2.3-59-g8ed1b From 782615aea84e57dc7f2f922cea823df3de635a78 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Mon, 20 Dec 2010 10:35:25 -0800 Subject: ehea: Fixing some message level Currently there are some info message that is set as error, and an error message that is set as debug. This patch just fixes it. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 0dfef6d76445..1032b5bbe238 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -740,13 +740,13 @@ static int ehea_proc_rwqes(struct net_device *dev, skb_arr_rq1_len, wqe_index); if (unlikely(!skb)) { - netif_err(port, rx_err, dev, + netif_info(port, rx_err, dev, "LL rq1: skb=NULL\n"); skb = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); if (!skb) { - netdev_info(dev, "Not enough memory to allocate skb\n"); + netdev_err(dev, "Not enough memory to allocate skb\n"); break; } } -- cgit v1.2.3-59-g8ed1b From 6561a3b12d62ed5317e6ac32182d87a03f62c8dc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 19 Dec 2010 21:11:20 -0800 Subject: ipv4: Flush per-ns routing cache more sanely. Flush the routing cache only of entries that match the network namespace in which the purge event occurred. Signed-off-by: David S. Miller Acked-by: Eric Dumazet --- include/net/route.h | 2 +- net/ipv4/fib_frontend.c | 6 ++++- net/ipv4/route.c | 64 +++++++++++++++++++------------------------------ 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 27002362944a..93e10c453f6b 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -114,7 +114,7 @@ extern int ip_rt_init(void); extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); -extern void rt_cache_flush_batch(void); +extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index d3a1112b9d9c..9f8bb68911e4 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -987,7 +987,11 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo rt_cache_flush(dev_net(dev), 0); break; case NETDEV_UNREGISTER_BATCH: - rt_cache_flush_batch(); + /* The batch unregister is only called on the first + * device in the list of devices being unregistered. + * Therefore we should not pass dev_net(dev) in here. + */ + rt_cache_flush_batch(NULL); break; } return NOTIFY_DONE; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ae520963540f..d8b4f4d0d66e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -717,13 +717,15 @@ static inline int rt_is_expired(struct rtable *rth) * Can be called by a softirq or a process. * In the later case, we want to be reschedule if necessary */ -static void rt_do_flush(int process_context) +static void rt_do_flush(struct net *net, int process_context) { unsigned int i; struct rtable *rth, *next; - struct rtable * tail; for (i = 0; i <= rt_hash_mask; i++) { + struct rtable __rcu **pprev; + struct rtable *list; + if (process_context && need_resched()) cond_resched(); rth = rcu_dereference_raw(rt_hash_table[i].chain); @@ -731,50 +733,32 @@ static void rt_do_flush(int process_context) continue; spin_lock_bh(rt_hash_lock_addr(i)); -#ifdef CONFIG_NET_NS - { - struct rtable __rcu **prev; - struct rtable *p; - rth = rcu_dereference_protected(rt_hash_table[i].chain, + list = NULL; + pprev = &rt_hash_table[i].chain; + rth = rcu_dereference_protected(*pprev, lockdep_is_held(rt_hash_lock_addr(i))); - /* defer releasing the head of the list after spin_unlock */ - for (tail = rth; tail; - tail = rcu_dereference_protected(tail->dst.rt_next, - lockdep_is_held(rt_hash_lock_addr(i)))) - if (!rt_is_expired(tail)) - break; - if (rth != tail) - rt_hash_table[i].chain = tail; - - /* call rt_free on entries after the tail requiring flush */ - prev = &rt_hash_table[i].chain; - for (p = rcu_dereference_protected(*prev, + while (rth) { + next = rcu_dereference_protected(rth->dst.rt_next, lockdep_is_held(rt_hash_lock_addr(i))); - p != NULL; - p = next) { - next = rcu_dereference_protected(p->dst.rt_next, - lockdep_is_held(rt_hash_lock_addr(i))); - if (!rt_is_expired(p)) { - prev = &p->dst.rt_next; + + if (!net || + net_eq(dev_net(rth->dst.dev), net)) { + rcu_assign_pointer(*pprev, next); + rcu_assign_pointer(rth->dst.rt_next, list); + list = rth; } else { - *prev = next; - rt_free(p); + pprev = &rth->dst.rt_next; } + rth = next; } - } -#else - rth = rcu_dereference_protected(rt_hash_table[i].chain, - lockdep_is_held(rt_hash_lock_addr(i))); - rcu_assign_pointer(rt_hash_table[i].chain, NULL); - tail = NULL; -#endif + spin_unlock_bh(rt_hash_lock_addr(i)); - for (; rth != tail; rth = next) { - next = rcu_dereference_protected(rth->dst.rt_next, 1); - rt_free(rth); + for (; list; list = next) { + next = rcu_dereference_protected(list->dst.rt_next, 1); + rt_free(list); } } } @@ -922,13 +906,13 @@ void rt_cache_flush(struct net *net, int delay) { rt_cache_invalidate(net); if (delay >= 0) - rt_do_flush(!in_softirq()); + rt_do_flush(net, !in_softirq()); } /* Flush previous cache invalidated entries from the cache */ -void rt_cache_flush_batch(void) +void rt_cache_flush_batch(struct net *net) { - rt_do_flush(!in_softirq()); + rt_do_flush(net, !in_softirq()); } static void rt_emergency_hash_rebuild(struct net *net) -- cgit v1.2.3-59-g8ed1b From f955e1415f381c7fa6ebe8630cd1fe5a694e8f4a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 Dec 2010 03:03:15 +0000 Subject: vmxnet3: locking problems in xmit There were several paths that didn't release their locks. Signed-off-by: Dan Carpenter Signed-off-by: Bhavesh Davda Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 23154cf601e9..939e5466c75e 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -980,7 +980,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, } } else { tq->stats.drop_hdr_inspect_err++; - goto drop_pkt; + goto unlock_drop_pkt; } /* fill tx descs related to addr & len */ @@ -1052,6 +1052,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, hdr_too_big: tq->stats.drop_oversized_hdr++; +unlock_drop_pkt: + spin_unlock_irqrestore(&tq->tx_lock, flags); drop_pkt: tq->stats.drop_total++; dev_kfree_skb(skb); -- cgit v1.2.3-59-g8ed1b From 24bdd9f4c9af75b33b438d60381a67626de0128d Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 16 Dec 2010 17:37:48 -0800 Subject: mac80211: Rename mesh_params to mesh_config to prepare for mesh_setup Mesh parameters can be to setup a mesh or to configure it. This patch renames the ambiguous name mesh_params to mesh_config in preparation for mesh_setup. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 15 ++++++++++----- include/net/cfg80211.h | 8 ++++---- net/mac80211/cfg.c | 8 ++++---- net/wireless/nl80211.c | 40 ++++++++++++++++++++-------------------- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 7483a89cee8f..11a1de67b618 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -172,10 +172,10 @@ * to the specified ISO/IEC 3166-1 alpha2 country code. The core will * store this as a valid request and then query userspace for it. * - * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the + * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the * interface identified by %NL80211_ATTR_IFINDEX * - * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the + * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the * interface identified by %NL80211_ATTR_IFINDEX * * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The @@ -448,8 +448,8 @@ enum nl80211_commands { NL80211_CMD_SET_REG, NL80211_CMD_REQ_SET_REG, - NL80211_CMD_GET_MESH_PARAMS, - NL80211_CMD_SET_MESH_PARAMS, + NL80211_CMD_GET_MESH_CONFIG, + NL80211_CMD_SET_MESH_CONFIG, NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, @@ -538,6 +538,10 @@ enum nl80211_commands { #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT +/* source-level API compatibility */ +#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG +#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG + /** * enum nl80211_attrs - nl80211 netlink attributes * @@ -922,7 +926,7 @@ enum nl80211_attrs { NL80211_ATTR_REG_ALPHA2, NL80211_ATTR_REG_RULES, - NL80211_ATTR_MESH_PARAMS, + NL80211_ATTR_MESH_CONFIG, NL80211_ATTR_BSS_BASIC_RATES, @@ -1058,6 +1062,7 @@ enum nl80211_attrs { /* source-level API compatibility */ #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION +#define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG /* * Allow user space programs to use #ifdef on new attributes by defining them diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6dc665a727c2..7283496c2d05 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1096,9 +1096,9 @@ struct cfg80211_pmksa { * @get_mpath: get a mesh path for the given parameters * @dump_mpath: dump mesh path callback -- resume dump at index @idx * - * @get_mesh_params: Put the current mesh parameters into *params + * @get_mesh_config: Get the current mesh configuration * - * @update_mesh_params: Update mesh parameters on a running mesh. + * @update_mesh_config: Update mesh parameters on a running mesh. * The mask is a bitfield which tells us which parameters to * set, and which to leave alone. * @@ -1246,10 +1246,10 @@ struct cfg80211_ops { int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo); - int (*get_mesh_params)(struct wiphy *wiphy, + int (*get_mesh_config)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); - int (*update_mesh_params)(struct wiphy *wiphy, + int (*update_mesh_config)(struct wiphy *wiphy, struct net_device *dev, u32 mask, const struct mesh_config *nconf); int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ea06f92801e9..1c94a2ae22ee 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -984,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int ieee80211_get_mesh_params(struct wiphy *wiphy, +static int ieee80211_get_mesh_config(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf) { @@ -1000,7 +1000,7 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) return (mask >> (parm-1)) & 0x1; } -static int ieee80211_update_mesh_params(struct wiphy *wiphy, +static int ieee80211_update_mesh_config(struct wiphy *wiphy, struct net_device *dev, u32 mask, const struct mesh_config *nconf) { @@ -1787,8 +1787,8 @@ struct cfg80211_ops mac80211_config_ops = { .change_mpath = ieee80211_change_mpath, .get_mpath = ieee80211_get_mpath, .dump_mpath = ieee80211_dump_mpath, - .update_mesh_params = ieee80211_update_mesh_params, - .get_mesh_params = ieee80211_get_mesh_params, + .update_mesh_config = ieee80211_update_mesh_config, + .get_mesh_config = ieee80211_get_mesh_config, .join_mesh = ieee80211_join_mesh, .leave_mesh = ieee80211_leave_mesh, #endif diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index aefce54d47e2..10be9350752e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = NL80211_MAX_SUPP_RATES }, [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, - [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, + [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, .len = NL80211_HT_CAPABILITY_LEN }, @@ -719,7 +719,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(add_beacon, NEW_BEACON); CMD(add_station, NEW_STATION); CMD(add_mpath, NEW_MPATH); - CMD(update_mesh_params, SET_MESH_PARAMS); + CMD(update_mesh_config, SET_MESH_CONFIG); CMD(change_bss, SET_BSS); CMD(auth, AUTHENTICATE); CMD(assoc, ASSOCIATE); @@ -2673,7 +2673,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) return r; } -static int nl80211_get_mesh_params(struct sk_buff *skb, +static int nl80211_get_mesh_config(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2688,7 +2688,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - if (!rdev->ops->get_mesh_params) + if (!rdev->ops->get_mesh_config) return -EOPNOTSUPP; wdev_lock(wdev); @@ -2696,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, if (!wdev->mesh_id_len) memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); else - err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, + err = rdev->ops->get_mesh_config(&rdev->wiphy, dev, &cur_params); wdev_unlock(wdev); @@ -2708,10 +2708,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, if (!msg) return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, - NL80211_CMD_GET_MESH_PARAMS); + NL80211_CMD_GET_MESH_CONFIG); if (!hdr) goto nla_put_failure; - pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); + pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); if (!pinfoattr) goto nla_put_failure; NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); @@ -2773,7 +2773,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, }; -static int nl80211_parse_mesh_params(struct genl_info *info, +static int nl80211_parse_mesh_config(struct genl_info *info, struct mesh_config *cfg, u32 *mask_out) { @@ -2789,10 +2789,10 @@ do {\ } while (0);\ - if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) + if (!info->attrs[NL80211_ATTR_MESH_CONFIG]) return -EINVAL; if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, - info->attrs[NL80211_ATTR_MESH_PARAMS], + info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy)) return -EINVAL; @@ -2847,7 +2847,7 @@ do {\ #undef FILL_IN_MESH_PARAM_IF_SET } -static int nl80211_update_mesh_params(struct sk_buff *skb, +static int nl80211_update_mesh_config(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2860,10 +2860,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb, if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - if (!rdev->ops->update_mesh_params) + if (!rdev->ops->update_mesh_config) return -EOPNOTSUPP; - err = nl80211_parse_mesh_params(info, &cfg, &mask); + err = nl80211_parse_mesh_config(info, &cfg, &mask); if (err) return err; @@ -2872,7 +2872,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb, err = -ENOLINK; if (!err) - err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, + err = rdev->ops->update_mesh_config(&rdev->wiphy, dev, mask, &cfg); wdev_unlock(wdev); @@ -4672,9 +4672,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) /* start with default */ memcpy(&cfg, &default_mesh_config, sizeof(cfg)); - if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { + if (info->attrs[NL80211_ATTR_MESH_CONFIG]) { /* and parse parameters if given */ - err = nl80211_parse_mesh_params(info, &cfg, NULL); + err = nl80211_parse_mesh_config(info, &cfg, NULL); if (err) return err; } @@ -4952,16 +4952,16 @@ static struct genl_ops nl80211_ops[] = { .flags = GENL_ADMIN_PERM, }, { - .cmd = NL80211_CMD_GET_MESH_PARAMS, - .doit = nl80211_get_mesh_params, + .cmd = NL80211_CMD_GET_MESH_CONFIG, + .doit = nl80211_get_mesh_config, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { - .cmd = NL80211_CMD_SET_MESH_PARAMS, - .doit = nl80211_update_mesh_params, + .cmd = NL80211_CMD_SET_MESH_CONFIG, + .doit = nl80211_update_mesh_config, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | -- cgit v1.2.3-59-g8ed1b From c80d545da3f7c0e534ccd4a780f322f80a92cff1 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 16 Dec 2010 17:37:49 -0800 Subject: mac80211: Let userspace enable and configure vendor specific path selection. Userspace will now be allowed to toggle between the default path selection algorithm (HWMP, implemented in the kernel), and a vendor specific alternative. Also in the same patch, allow userspace to add information elements to mesh beacons. This is accordance with the Extensible Path Selection Framework specified in version 7.0 of the 802.11s draft. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 25 ++++++++++++++++++ include/linux/nl80211.h | 47 +++++++++++++++++++++++++++++++--- include/net/cfg80211.h | 8 ++++++ net/mac80211/cfg.c | 39 +++++++++++++++++++++++++--- net/mac80211/ieee80211_i.h | 4 +-- net/mac80211/mesh.c | 7 ++++++ net/mac80211/mesh_plink.c | 3 ++- net/mac80211/tx.c | 3 ++- net/wireless/core.c | 22 +++++++++++----- net/wireless/core.h | 5 ++-- net/wireless/mesh.c | 24 ++++++++++-------- net/wireless/nl80211.c | 63 ++++++++++++++++++++++++++++++++++++++++++---- 12 files changed, 214 insertions(+), 36 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 7f2354534242..cd681681d211 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1291,6 +1291,31 @@ enum ieee80211_key_len { WLAN_KEY_LEN_AES_CMAC = 16, }; +/** + * enum - mesh path selection protocol identifier + * + * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol + * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will + * be specified in a vendor specific information element + */ +enum { + IEEE80211_PATH_PROTOCOL_HWMP = 0, + IEEE80211_PATH_PROTOCOL_VENDOR = 255, +}; + +/** + * enum - mesh path selection metric identifier + * + * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric + * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be + * specified in a vendor specific information element + */ +enum { + IEEE80211_PATH_METRIC_AIRTIME = 0, + IEEE80211_PATH_METRIC_VENDOR = 255, +}; + + /* * IEEE 802.11-2007 7.3.2.9 Country information element * diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 11a1de67b618..69eaccac78c4 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -872,6 +872,9 @@ enum nl80211_commands { * attributes, specifying what a key should be set as default as. * See &enum nl80211_key_default_types. * + * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be + * changed once the mesh is active. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1054,6 +1057,8 @@ enum nl80211_attrs { NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, + NL80211_ATTR_MESH_SETUP, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1564,7 +1569,8 @@ enum nl80211_mntr_flags { /** * enum nl80211_meshconf_params - mesh configuration parameters * - * Mesh configuration parameters + * Mesh configuration parameters. These can be changed while the mesh is + * active. * * @__NL80211_MESHCONF_INVALID: internal use * @@ -1587,9 +1593,6 @@ enum nl80211_mntr_flags { * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh * point. * - * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a - * source mesh point for path selection elements. - * * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically * open peer links when we detect compatible mesh peers. * @@ -1616,6 +1619,9 @@ enum nl80211_mntr_flags { * * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not * + * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a + * source mesh point for path selection elements. + * * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use @@ -1643,6 +1649,39 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 }; +/** + * enum nl80211_mesh_setup_params - mesh setup parameters + * + * Mesh setup parameters. These are used to start/join a mesh and cannot be + * changed while the mesh is active. + * + * @__NL80211_MESH_SETUP_INVALID: Internal use + * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a + * vendor specific path selection algorithm or disable it to use the default + * HWMP. + * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a + * vendor specific path metric or disable it to use the default Airtime + * metric. + * + * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information + * element that vendors will use to identify the path selection methods and + * metrics in use. + * + * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use + */ +enum nl80211_mesh_setup_params { + __NL80211_MESH_SETUP_INVALID, + NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, + NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, + NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE, + + /* keep last */ + __NL80211_MESH_SETUP_ATTR_AFTER_LAST, + NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1 +}; + /** * enum nl80211_txq_attr - TX queue parameter attributes * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7283496c2d05..924d60366233 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -649,12 +649,20 @@ struct mesh_config { * struct mesh_setup - 802.11s mesh setup configuration * @mesh_id: the mesh ID * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes + * @path_sel_proto: which path selection protocol to use + * @path_metric: which metric to use + * @vendor_ie: vendor information elements (optional) + * @vendor_ie_len: length of vendor information elements * * These parameters are fixed when the mesh is created. */ struct mesh_setup { const u8 *mesh_id; u8 mesh_id_len; + u8 path_sel_proto; + u8 path_metric; + const u8 *vendor_ie; + u8 vendor_ie_len; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1c94a2ae22ee..ae2c7127a8aa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1000,6 +1000,36 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) return (mask >> (parm-1)) & 0x1; } +static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, + const struct mesh_setup *setup) +{ + u8 *new_ie; + const u8 *old_ie; + + /* first allocate the new vendor information element */ + new_ie = NULL; + old_ie = ifmsh->vendor_ie; + + ifmsh->vendor_ie_len = setup->vendor_ie_len; + if (setup->vendor_ie_len) { + new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len, + GFP_KERNEL); + if (!new_ie) + return -ENOMEM; + } + + /* now copy the rest of the setup parameters */ + ifmsh->mesh_id_len = setup->mesh_id_len; + memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); + ifmsh->mesh_pp_id = setup->path_sel_proto; + ifmsh->mesh_pm_id = setup->path_metric; + ifmsh->vendor_ie = new_ie; + + kfree(old_ie); + + return 0; +} + static int ieee80211_update_mesh_config(struct wiphy *wiphy, struct net_device *dev, u32 mask, const struct mesh_config *nconf) @@ -1059,11 +1089,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + int err; - memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); - ifmsh->mesh_id_len = setup->mesh_id_len; - memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); - + memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config)); + err = copy_mesh_setup(ifmsh, setup); + if (err) + return err; ieee80211_start_mesh(sdata); return 0; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ce58b2a676e2..eadaa243a3da 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -484,6 +484,8 @@ struct ieee80211_if_mesh { struct mesh_config mshcfg; u32 mesh_seqnum; bool accepting_plinks; + const u8 *vendor_ie; + u8 vendor_ie_len; }; #ifdef CONFIG_MAC80211_MESH @@ -585,9 +587,7 @@ struct ieee80211_sub_if_data { struct ieee80211_if_vlan vlan; struct ieee80211_if_managed mgd; struct ieee80211_if_ibss ibss; -#ifdef CONFIG_MAC80211_MESH struct ieee80211_if_mesh mesh; -#endif u32 mntr_flags; } u; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 63e1188d5062..c326e009389d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -287,6 +287,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) *pos++ |= sdata->u.mesh.accepting_plinks ? MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; *pos++ = 0x00; + + if (sdata->u.mesh.vendor_ie) { + int len = sdata->u.mesh.vendor_ie_len; + const u8 *data = sdata->u.mesh.vendor_ie; + if (skb_tailroom(skb) > len) + memcpy(skb_put(skb, len), data, len); + } } u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 1c91f0f3c307..44b53931ba5e 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -160,7 +160,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, __le16 reason) { struct ieee80211_local *local = sdata->local; - struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); + struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + + sdata->u.mesh.vendor_ie_len); struct ieee80211_mgmt *mgmt; bool include_plid = false; static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 157bde993ef5..f4b1b624ea9f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2290,7 +2290,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, u8 *pos; /* headroom, head length, tail length and maximum TIM length */ - skb = dev_alloc_skb(local->tx_headroom + 400); + skb = dev_alloc_skb(local->tx_headroom + 400 + + sdata->u.mesh.vendor_ie_len); if (!skb) goto out; diff --git a/net/wireless/core.c b/net/wireless/core.c index 79772fcc37bc..e9a5f8ca4c27 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, cfg80211_mgd_wext_connect(rdev, wdev); break; #endif +#ifdef CONFIG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: - /* backward compat code ... */ - if (wdev->mesh_id_up_len) - __cfg80211_join_mesh(rdev, dev, wdev->ssid, - wdev->mesh_id_up_len, - &default_mesh_config); - break; + { + /* backward compat code... */ + struct mesh_setup setup; + memcpy(&setup, &default_mesh_setup, + sizeof(setup)); + /* back compat only needed for mesh_id */ + setup.mesh_id = wdev->ssid; + setup.mesh_id_len = wdev->mesh_id_up_len; + if (wdev->mesh_id_up_len) + __cfg80211_join_mesh(rdev, dev, + &setup, + &default_mesh_config); + break; + } +#endif default: break; } diff --git a/net/wireless/core.h b/net/wireless/core.h index 743203bb61ac..26a0a084e16b 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, /* mesh */ extern const struct mesh_config default_mesh_config; +extern const struct mesh_setup default_mesh_setup; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_setup *setup, const struct mesh_config *conf); int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_setup *setup, const struct mesh_config *conf); int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev); diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index e0b9747fe50a..73e39c171ffb 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = { .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, }; +const struct mesh_setup default_mesh_setup = { + .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, + .path_metric = IEEE80211_PATH_METRIC_AIRTIME, + .vendor_ie = NULL, + .vendor_ie_len = 0, +}; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_setup *setup, const struct mesh_config *conf) { struct wireless_dev *wdev = dev->ieee80211_ptr; - struct mesh_setup setup = { - .mesh_id = mesh_id, - .mesh_id_len = mesh_id_len, - }; int err; BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); @@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (wdev->mesh_id_len) return -EALREADY; - if (!mesh_id_len) + if (!setup->mesh_id_len) return -EINVAL; if (!rdev->ops->join_mesh) return -EOPNOTSUPP; - err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); + err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); if (!err) { - memcpy(wdev->ssid, mesh_id, mesh_id_len); - wdev->mesh_id_len = mesh_id_len; + memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); + wdev->mesh_id_len = setup->mesh_id_len; } return err; @@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, + const struct mesh_setup *setup, const struct mesh_config *conf) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err; wdev_lock(wdev); - err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); + err = __cfg80211_join_mesh(rdev, dev, setup, conf); wdev_unlock(wdev); return err; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 10be9350752e..eef89d0b558b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2773,6 +2773,14 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, }; +static const struct nla_policy + nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { + [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, + [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, + [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, +}; + static int nl80211_parse_mesh_config(struct genl_info *info, struct mesh_config *cfg, u32 *mask_out) @@ -2839,14 +2847,50 @@ do {\ dot11MeshHWMPRootMode, mask, NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8); - if (mask_out) *mask_out = mask; + return 0; #undef FILL_IN_MESH_PARAM_IF_SET } +static int nl80211_parse_mesh_setup(struct genl_info *info, + struct mesh_setup *setup) +{ + struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1]; + + if (!info->attrs[NL80211_ATTR_MESH_SETUP]) + return -EINVAL; + if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX, + info->attrs[NL80211_ATTR_MESH_SETUP], + nl80211_mesh_setup_params_policy)) + return -EINVAL; + + if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL]) + setup->path_sel_proto = + (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ? + IEEE80211_PATH_PROTOCOL_VENDOR : + IEEE80211_PATH_PROTOCOL_HWMP; + + if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC]) + setup->path_metric = + (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ? + IEEE80211_PATH_METRIC_VENDOR : + IEEE80211_PATH_METRIC_AIRTIME; + + if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { + struct nlattr *ieattr = + tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; + if (!is_valid_ie_attr(ieattr)) + return -EINVAL; + setup->vendor_ie = nla_data(ieattr); + setup->vendor_ie_len = nla_len(ieattr); + } + + return 0; +} + static int nl80211_update_mesh_config(struct sk_buff *skb, struct genl_info *info) { @@ -4667,10 +4711,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct mesh_config cfg; + struct mesh_setup setup; int err; /* start with default */ memcpy(&cfg, &default_mesh_config, sizeof(cfg)); + memcpy(&setup, &default_mesh_setup, sizeof(setup)); if (info->attrs[NL80211_ATTR_MESH_CONFIG]) { /* and parse parameters if given */ @@ -4683,10 +4729,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) return -EINVAL; - return cfg80211_join_mesh(rdev, dev, - nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - nla_len(info->attrs[NL80211_ATTR_MESH_ID]), - &cfg); + setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); + setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); + + if (info->attrs[NL80211_ATTR_MESH_SETUP]) { + /* parse additional setup parameters if given */ + err = nl80211_parse_mesh_setup(info, &setup); + if (err) + return err; + } + + return cfg80211_join_mesh(rdev, dev, &setup, &cfg); } static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) -- cgit v1.2.3-59-g8ed1b From c7108a7111cd9e592d6ad498be37276dbea75d2b Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 16 Dec 2010 17:37:50 -0800 Subject: mac80211: Send mesh non-HWMP path selection frames to userspace Let path selection frames for protocols other than HWMP be sent to userspace via NL80211_CMD_REGISTER_FRAME. Also allow userspace to send and receive mesh path selection frames. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 1 + net/mac80211/main.c | 4 ++++ net/mac80211/mesh.c | 13 +++---------- net/mac80211/mesh.h | 7 +++++++ net/mac80211/rx.c | 5 ++++- net/wireless/nl80211.c | 2 ++ 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ae2c7127a8aa..5892b0302454 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1670,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_MESH_POINT: if (!ieee80211_is_action(mgmt->frame_control) || mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) break; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d87eb005690f..a21d049caf19 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4), }, + [NL80211_IFTYPE_MESH_POINT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4), + }, }; struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c326e009389d..8b5906c83f93 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) ieee80211_mesh_housekeeping_timer((unsigned long) sdata); } -void mesh_ids_set_default(struct ieee80211_if_mesh *sta) -{ - sta->mesh_pp_id = 0; /* HWMP */ - sta->mesh_pm_id = 0; /* Airtime */ - sta->mesh_cc_id = 0; /* Disabled */ - sta->mesh_sp_id = 0; /* Neighbor Offset */ - sta->mesh_auth_id = 0; /* Disabled */ -} - int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) { int i; @@ -525,6 +516,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) atomic_inc(&local->iff_allmultis); ieee80211_configure_filter(local); + ifmsh->mesh_cc_id = 0; /* Disabled */ + ifmsh->mesh_sp_id = 0; /* Neighbor Offset */ + ifmsh->mesh_auth_id = 0; /* Disabled */ set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); ieee80211_mesh_root_setup(ifmsh); ieee80211_queue_work(&local->hw, &sdata->work); @@ -695,7 +689,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) /* Allocate all mesh structures when creating the first mesh interface. */ if (!mesh_allocated) ieee80211s_init(); - mesh_ids_set_default(ifmsh); setup_timer(&ifmsh->mesh_path_timer, ieee80211_mesh_path_timer, (unsigned long) sdata); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 5b828fa8c541..890dd19c2eca 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath) mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED; } +static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) +{ + return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; +} + #define for_each_mesh_entry(x, p, node, i) \ for (i = 0; i <= x->hash_mask; i++) \ hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) @@ -304,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) {} static inline void mesh_plink_quiesce(struct sta_info *sta) {} static inline void mesh_plink_restart(struct sta_info *sta) {} +static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) +{ return false; } #endif #endif /* IEEE80211S_H */ diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 4573ce1e1d15..7c5d1b2ec453 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2161,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_PLINK: - case WLAN_CATEGORY_MESH_PATH_SEL: if (!ieee80211_vif_is_mesh(&sdata->vif)) break; goto queue; + case WLAN_CATEGORY_MESH_PATH_SEL: + if (!mesh_path_sel_is_hwmp(sdata)) + break; + goto queue; } return RX_CONTINUE; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index eef89d0b558b..6a5d6fa11e46 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4445,6 +4445,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; @@ -4485,6 +4486,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; -- cgit v1.2.3-59-g8ed1b From 7f531e03abf0162df3966c4fa5fa6fdd9302cb6b Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 16 Dec 2010 11:30:22 +0900 Subject: cfg80211: Separate available antennas for RX and TX As has been pointed out by Daniel Halperin some devices (e.g. Intel IWL5100) can only TX from a subset of RX antennas, so use separate availability masks for RX and TX. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/net/cfg80211.h | 12 +++++++++--- net/wireless/nl80211.c | 17 ++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 924d60366233..bcc9f448ec4e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1482,8 +1482,13 @@ struct ieee80211_txrx_stypes { * transmitted through nl80211, points to an array indexed by interface * type * - * @available_antennas: bitmap of antennas which are available to configure. - * antenna configuration commands will be rejected unless this is set. + * @available_antennas_tx: bitmap of antennas which are available to be + * configured as TX antennas. Antenna configuration commands will be + * rejected unless this or @available_antennas_rx is set. + * + * @available_antennas_rx: bitmap of antennas which are available to be + * configured as RX antennas. Antenna configuration commands will be + * rejected unless this or @available_antennas_tx is set. * * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation * may request, if implemented. @@ -1528,7 +1533,8 @@ struct wiphy { u8 max_num_pmkids; - u32 available_antennas; + u32 available_antennas_tx; + u32 available_antennas_rx; /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6a5d6fa11e46..8d2f5f8d8080 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -605,7 +605,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); - if (dev->wiphy.available_antennas && dev->ops->get_antenna) { + if ((dev->wiphy.available_antennas_tx || + dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { u32 tx_ant = 0, rx_ant = 0; int res; res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); @@ -1107,7 +1108,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { u32 tx_ant, rx_ant; - if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) { + if ((!rdev->wiphy.available_antennas_tx && + !rdev->wiphy.available_antennas_rx) || + !rdev->ops->set_antenna) { result = -EOPNOTSUPP; goto bad_res; } @@ -1116,15 +1119,15 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); /* reject antenna configurations which don't match the - * available antenna mask, except for the "all" mask */ - if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas)) || - (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas))) { + * available antenna masks, except for the "all" mask */ + if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) || + (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) { result = -EINVAL; goto bad_res; } - tx_ant = tx_ant & rdev->wiphy.available_antennas; - rx_ant = rx_ant & rdev->wiphy.available_antennas; + tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; + rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); if (result) -- cgit v1.2.3-59-g8ed1b From 39fd5de4472b7b222c6cec78d72b069133f694e4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 16 Dec 2010 11:30:28 +0900 Subject: nl80211: Export available antennas Export the information which antennas are available for configuration as TX or RX antennas via nl80211. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- include/linux/nl80211.h | 9 +++++++++ net/wireless/nl80211.c | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 69eaccac78c4..2b89b712565b 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -858,6 +858,12 @@ enum nl80211_commands { * the hardware should not be configured to receive on this antenna. * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX. * + * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available + * for configuration as TX antennas via the above parameters. + * + * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available + * for configuration as RX antennas via the above parameters. + * * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS * * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be @@ -1059,6 +1065,9 @@ enum nl80211_attrs { NL80211_ATTR_MESH_SETUP, + NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, + NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8d2f5f8d8080..9b62710891a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -605,6 +605,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, + dev->wiphy.available_antennas_tx); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, + dev->wiphy.available_antennas_rx); + if ((dev->wiphy.available_antennas_tx || dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { u32 tx_ant = 0, rx_ant = 0; -- cgit v1.2.3-59-g8ed1b From 3de135dba9341a3d10a7a5b9533ce11cb77d4f4d Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 16 Dec 2010 11:30:33 +0900 Subject: ath5k: Set available antenna information for cfg80211 Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b3c7241a62a5..e4ec40c63396 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2351,6 +2351,10 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + /* both antennas can be configured as RX or TX */ + hw->wiphy->available_antennas_tx = 0x3; + hw->wiphy->available_antennas_rx = 0x3; + hw->extra_tx_headroom = 2; hw->channel_change_time = 5000; -- cgit v1.2.3-59-g8ed1b From 61ad5394590c5c5338ab4ec50553d809a9996d50 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 16 Dec 2010 17:23:34 -0800 Subject: mac80211: Remove unused third address from mesh address extension header. The Mesh Control header only includes 0, 1 or 2 addresses. If there is one address, it should be interpreted as Address 4. If there are 2, they are interpreted as Addresses 5 and 6 (Address 4 being the 4th address in the 802.11 header). The address extension used to hold up to 3 addresses instead of the current 2. I'm not sure which draft version changed this, but it is very unlikely that it will change again given the state of the approval process of this draft. See section 7.1.3.6.3 in current draft (8.0). Also, note that the extra address that I'm removing was not being used, so this change has no effect on over-the-air frame formats. But I thought I better remove it before someone does start using it. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 1 - net/mac80211/mesh.c | 32 +++++++++++++------------------- net/mac80211/mesh.h | 4 ++-- net/mac80211/tx.c | 4 +--- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index cd681681d211..6042228954a7 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -536,7 +536,6 @@ struct ieee80211s_hdr { __le32 seqnum; u8 eaddr1[6]; u8 eaddr2[6]; - u8 eaddr3[6]; } __attribute__ ((packed)); /* Mesh flags */ diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8b5906c83f93..ca3af4685b0a 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -410,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, * ieee80211_new_mesh_header - create a new mesh header * @meshhdr: uninitialized mesh header * @sdata: mesh interface to be used - * @addr4: addr4 of the mesh frame (1st in ae header) - * may be NULL - * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) - * may be NULL unless addr6 is present - * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) - * may be NULL unless addr5 is present + * @addr4or5: 1st address in the ae header, which may correspond to address 4 + * (if addr6 is NULL) or address 5 (if addr6 is present). It may + * be NULL. + * @addr6: 2nd address in the ae header, which corresponds to addr6 of the + * mesh frame * * Return the header length. */ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, - struct ieee80211_sub_if_data *sdata, char *addr4, - char *addr5, char *addr6) + struct ieee80211_sub_if_data *sdata, char *addr4or5, + char *addr6) { int aelen = 0; + BUG_ON(!addr4or5 && addr6); memset(meshhdr, 0, sizeof(*meshhdr)); meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); sdata->u.mesh.mesh_seqnum++; - if (addr4) { + if (addr4or5 && !addr6) { meshhdr->flags |= MESH_FLAGS_AE_A4; aelen += ETH_ALEN; - memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); - } - if (addr5 && addr6) { + memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); + } else if (addr4or5 && addr6) { meshhdr->flags |= MESH_FLAGS_AE_A5_A6; aelen += 2 * ETH_ALEN; - if (!addr4) { - memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); - memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); - } else { - memcpy(meshhdr->eaddr2, addr5, ETH_ALEN); - memcpy(meshhdr->eaddr3, addr6, ETH_ALEN); - } + memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); + memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); } return 6 + aelen; } diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 890dd19c2eca..b99e230fe31c 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -187,8 +187,8 @@ struct mesh_rmc { int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, const u8 *da, const u8 *sa); int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, - struct ieee80211_sub_if_data *sdata, char *addr4, - char *addr5, char *addr6); + struct ieee80211_sub_if_data *sdata, char *addr4or5, + char *addr6); int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, struct ieee80211_sub_if_data *sdata); bool mesh_matches_local(struct ieee802_11_elems *ie, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f4b1b624ea9f..807dcd06e268 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1811,7 +1811,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, skb->data, skb->data + ETH_ALEN); meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, - sdata, NULL, NULL, NULL); + sdata, NULL, NULL); } else { /* packet from other interface */ struct mesh_path *mppath; @@ -1844,13 +1844,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ieee80211_new_mesh_header(&mesh_hdr, sdata, skb->data + ETH_ALEN, - NULL, NULL); else meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, - NULL, skb->data, skb->data + ETH_ALEN); -- cgit v1.2.3-59-g8ed1b From 5c405b5c3e435fd332058c59ee58eaa1ac9c513a Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 16 Dec 2010 15:43:36 -0500 Subject: rtl8192ce: drop 'rtl8192c-' prefix from files Signed-off-by: John W. Linville Tested-by: Larry Finger --- drivers/net/wireless/rtlwifi/rtl8192ce/Makefile | 18 +- drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 257 ++ drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 1473 +++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 196 ++ drivers/net/wireless/rtlwifi/rtl8192ce/fw.c | 804 ++++++ drivers/net/wireless/rtlwifi/rtl8192ce/fw.h | 98 + drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2173 ++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | 57 + drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 144 ++ drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 41 + drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2676 ++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 237 ++ drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 2065 +++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 523 ++++ drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | 44 + .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h | 257 -- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c | 1473 ----------- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h | 196 -- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c | 804 ------ .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h | 98 - .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c | 2173 ---------------- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h | 57 - .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c | 144 -- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h | 41 - .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c | 2676 -------------------- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h | 237 -- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h | 2065 --------------- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c | 523 ---- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h | 44 - .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c | 282 --- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h | 37 - .../wireless/rtlwifi/rtl8192ce/rtl8192c-table.c | 1224 --------- .../wireless/rtlwifi/rtl8192ce/rtl8192c-table.h | 58 - .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c | 1031 -------- .../net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h | 714 ------ drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 282 +++ drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 37 + drivers/net/wireless/rtlwifi/rtl8192ce/table.c | 1224 +++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/table.h | 58 + drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 1031 ++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 714 ++++++ 41 files changed, 14143 insertions(+), 14143 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/def.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/dm.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/dm.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/fw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/fw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/hw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/hw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/led.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/led.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/phy.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/phy.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/reg.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rf.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rf.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/sw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/sw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/table.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/table.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/trx.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/trx.h diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile index f3d7682ff08c..0f0be7c763b8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile @@ -1,12 +1,12 @@ rtl8192ce-objs := \ - rtl8192c-dm.o \ - rtl8192c-fw.o \ - rtl8192c-hw.o \ - rtl8192c-led.o \ - rtl8192c-phy.o \ - rtl8192c-rf.o \ - rtl8192c-sw.o \ - rtl8192c-table.o \ - rtl8192c-trx.o + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o obj-$(CONFIG_RTL8192CE) += rtl8192ce.o diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h new file mode 100644 index 000000000000..83cd64895292 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -0,0 +1,257 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_DEF_H__ +#define __RTL92C_DEF_H__ + +#define HAL_RETRY_LIMIT_INFRA 48 +#define HAL_RETRY_LIMIT_AP_ADHOC 7 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +#define RESET_DELAY_8185 20 + +#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1 + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 + +#define MAX_LINES_HWCONFIG_TXT 1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT 256 + +#define SW_THREE_WIRE 0 +#define HW_THREE_WIRE 2 + +#define BT_DEMO_BOARD 0 +#define BT_QA_BOARD 1 +#define BT_FPGA 2 + +#define RX_SMOOTH_FACTOR 20 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define MAX_H2C_QUEUE_NUM 10 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 +#define AC2QUEUEID(_AC) (_AC) + +#define C2H_RX_CMD_HDR_LEN 8 +#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 0, 16) +#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 16, 8) +#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 24, 7) +#define GET_C2H_CMD_CONTINUE(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 31, 1) +#define GET_C2H_CMD_CONTENT(__prxhdr) \ + ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN) + +#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16) +#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) +#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) + +#define CHIP_VER_B BIT(4) +#define CHIP_92C_BITMASK BIT(0) +#define CHIP_92C_1T2R 0x03 +#define CHIP_92C 0x01 +#define CHIP_88C 0x00 + +enum version_8192c { + VERSION_A_CHIP_92C = 0x01, + VERSION_A_CHIP_88C = 0x00, + VERSION_B_CHIP_92C = 0x11, + VERSION_B_CHIP_88C = 0x10, + VERSION_UNKNOWN = 0x88, +}; + +#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) +#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false) + +enum rtl819x_loopback_e { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum hal_fw_c2h_cmd_id { + HAL_FW_C2H_CMD_Read_MACREG = 0, + HAL_FW_C2H_CMD_Read_BBREG = 1, + HAL_FW_C2H_CMD_Read_RFREG = 2, + HAL_FW_C2H_CMD_Read_EEPROM = 3, + HAL_FW_C2H_CMD_Read_EFUSE = 4, + HAL_FW_C2H_CMD_Read_CAM = 5, + HAL_FW_C2H_CMD_Get_BasicRate = 6, + HAL_FW_C2H_CMD_Get_DataRate = 7, + HAL_FW_C2H_CMD_Survey = 8, + HAL_FW_C2H_CMD_SurveyDone = 9, + HAL_FW_C2H_CMD_JoinBss = 10, + HAL_FW_C2H_CMD_AddSTA = 11, + HAL_FW_C2H_CMD_DelSTA = 12, + HAL_FW_C2H_CMD_AtimDone = 13, + HAL_FW_C2H_CMD_TX_Report = 14, + HAL_FW_C2H_CMD_CCX_Report = 15, + HAL_FW_C2H_CMD_DTM_Report = 16, + HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, + HAL_FW_C2H_CMD_C2HLBK = 18, + HAL_FW_C2H_CMD_C2HDBG = 19, + HAL_FW_C2H_CMD_C2HFEEDBACK = 20, + HAL_FW_C2H_CMD_MAX +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc92c_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, + DESC92C_RATEMCS15_SG = 0x1c, + DESC92C_RATEMCS32 = 0x20, +}; + +struct phy_sts_cck_8192s_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c new file mode 100644 index 000000000000..62e7c64e087b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -0,0 +1,1473 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" + +struct dig_t dm_digtable; +static struct ps_t dm_pstable; + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, + 0x788001e2, + 0x71c001c7, + 0x6b8001ae, + 0x65400195, + 0x5fc0017f, + 0x5a400169, + 0x55400155, + 0x50800142, + 0x4c000130, + 0x47c0011f, + 0x43c0010f, + 0x40000100, + 0x3c8000f2, + 0x390000e4, + 0x35c000d7, + 0x32c000cb, + 0x300000c0, + 0x2d4000b5, + 0x2ac000ab, + 0x288000a2, + 0x26000098, + 0x24000090, + 0x22000088, + 0x20000080, + 0x1e400079, + 0x1c800072, + 0x1b00006c, + 0x19800066, + 0x18000060, + 0x16c0005b, + 0x15800056, + 0x14400051, + 0x1300004c, + 0x12000048, + 0x11000044, + 0x10000040, +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} +}; + +static void rtl92c_dm_diginit(struct ieee80211_hw *hw) +{ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0x0; + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; +} + +static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long rssi_val_min = 0; + + if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + else + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || + dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + } + + return (u8) rssi_val_min; +} + +static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " + "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value_igi = dm_digtable.cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = 0x32; + + dm_digtable.cur_igvalue = value_igi; + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { + if ((dm_digtable.backoff_val - 2) < + dm_digtable.backoff_val_range_min) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_min; + else + dm_digtable.backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { + if ((dm_digtable.backoff_val + 2) > + dm_digtable.backoff_val_range_max) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_max; + else + dm_digtable.backoff_val += 2; + } + + if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > + dm_digtable.rx_gain_range_max) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; + else if ((dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val; + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 binitialized; /* initialized to false */ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + bool b_multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + b_multi_sta = true; + + if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != + DIG_STA_DISCONNECT)) { + binitialized = false; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (binitialized == false) { + binitialized = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable.rssi_lowthresh) && + (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable.dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable.rssi_highthresh) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("curmultista_connectstate = " + "%x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage)); +} + +static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("presta_connectstate = %x," + " cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate)); + + if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate + || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT + || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + + if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { + dm_digtable.rssi_val_min = + rtl92c_dm_initial_gain_min_pwdb(hw); + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable.rssi_val_min = 0; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0; + rtl92c_dm_write_dig(hw); + } +} + +static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); + + if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (dm_digtable.rssi_val_min <= 25) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } else { + if (dm_digtable.rssi_val_min <= 20) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } + } else { + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { + if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) + dm_digtable.cur_cck_fa_state = + CCK_FA_STAGE_High; + else + dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; + + if (dm_digtable.pre_cck_fa_state != + dm_digtable.cur_cck_fa_state) { + if (dm_digtable.cur_cck_fa_state == + CCK_FA_STAGE_Low) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0xcd); + + dm_digtable.pre_cck_fa_state = + dm_digtable.cur_cck_fa_state; + } + + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd7); + } else { + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd3); + } + dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); +} + +static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (mac->act_scanning == true) + return; + + if ((mac->link_state > MAC80211_NOLINK) && + (mac->link_state < MAC80211_LINKED)) + dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; + else if (mac->link_state >= MAC80211_LINKED) + dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + else + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + + rtl92c_dm_initial_gain_sta(hw); + rtl92c_dm_initial_gain_multi_sta(hw); + rtl92c_dm_cck_packet_detection_thresh(hw); + + dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; + +} + +static void rtl92c_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.b_dm_initialgain_enable == false) + return; + if (dm_digtable.dig_enable_flag == false) + return; + + rtl92c_dm_ctrl_initgain_by_twoport(hw); + +} + +static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.bdynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (!rtlpriv->dm.bdynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Not connected to any\n")); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_NORMAL\n")); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel)); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +void rtl92c_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("cur_igvalue = 0x%x, " + "pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val)); + + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + + dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + } +} + +static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + u8 h2c_parameter[3] = { 0 }; + + return; + + if (tmpentry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; + } else { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; + } + + if (tmpentry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; + } else { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; + } + + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); + h2c_parameter[0] = 0; + + rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +} + +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.bis_any_nonbepkts = false; + rtlpriv->dm.bis_cur_rdlstate = false; +} + +static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + goto dm_checkedcaturbo_exit; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.bcurrent_turbo_edca = false; + return; + } + + if (!mac->ht_enable) { /*FIX MERGE */ + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((!rtlpriv->dm.bis_any_nonbepkts) && + (!rtlpriv->dm.b_disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.bis_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.bis_cur_rdlstate = false; + } + } + rtlpriv->dm.bcurrent_turbo_edca = true; + } else { + if (rtlpriv->dm.bcurrent_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&tmp)); + rtlpriv->dm.bcurrent_turbo_edca = false; + } + } + +dm_checkedcaturbo_exit: + rtlpriv->dm.bis_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw + *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk; + long ele_a, ele_d, temp_cck, val_x, value32; + long val_y, ele_c; + u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; + int i; + bool is2t = IS_92C_SERIAL(rtlhal->version); + u8 txpwr_level[2] = {0, 0}; + u8 ofdm_min_index = 6, rf; + + rtlpriv->dm.btxpower_trackingInit = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter)); + + rtl92c_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Initial pathA ele_d reg0x%x = 0x%lx, " + "ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0])); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial pathB ele_d reg0x%x = " + "0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1])); + break; + } + } + } + + temp_cck = + rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.b_cck_inch14) { + if (memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } else { + if (memcmp((void *)&temp_cck, + (void *) + &cckswing_table_ch1ch13[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x delta 0x%x " + "delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk)); + + if (delta_lck > 1) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92c_phy_lc_calibrate(hw); + } + + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] -= delta; + rtlpriv->dm.cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] += delta; + rtlpriv->dm.cck_index += delta; + } + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index)); + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i] + + 1; + cck_index = rtlpriv->dm.cck_index + 1; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i]; + cck_index = rtlpriv->dm.cck_index; + } + + for (i = 0; i < rf; i++) { + if (txpwr_level[i] >= 0 && + txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse-> + eeprom_thermalmeter) { + ofdm_index[i] += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 + && thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > + rtlefuse->eeprom_thermalmeter + && delta > 5) { + ofdm_index[i] -= 1; + } + } + + if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse->eeprom_thermalmeter) { + cck_index += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 && + thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > rtlefuse->eeprom_thermalmeter + && delta > 5) { + cck_index -= 1; + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) + ofdm_index[i] = OFDM_TABLE_SIZE - 1; + + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], cck_index)); + } + } + + if (rtlpriv->dm.txpower_track_control && delta != 0) { + ele_d = + (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->reg_e94; + val_y = rtlphy->reg_e9c; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(29), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31) | BIT(29), 0x00); + } + + if (!rtlpriv->dm.b_cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[cck_index] + [7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[cck_index] + [7]); + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & + 0xFFC00000) >> 22; + + val_x = rtlphy->reg_eb4; + val_y = rtlphy->reg_ebc; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & + 0x00003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(25), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index + [1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27) | BIT(25), 0x00); + } + + } + } + + if (delta_iqk > 3) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92c_phy_iq_calibrate(hw, false); + } + + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + +} + +static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.btxpower_tracking = true; + rtlpriv->dm.btxpower_trackingInit = false; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("pMgntInfo->btxpower_tracking = %d\n", + rtlpriv->dm.btxpower_tracking)); +} + +static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) +{ + rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl92c_dm_check_txpower_tracking_thermal_meter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static u8 tm_trigger; + + if (!rtlpriv->dm.btxpower_tracking) + return; + + if (!tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, + 0x60); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Trigger 92S Thermal Meter!!\n")); + tm_trigger = 1; + return; + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Schedule TxPowerTracking direct call!!\n")); + rtl92c_dm_txpower_tracking_directcall(hw); + tm_trigger = 0; + } +} + +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_check_txpower_tracking_thermal_meter(hw); +} + +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.b_useramask = true; + else + rtlpriv->dm.b_useramask = false; + +} + +static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + + if (is_hal_stop(rtlhal)) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver is going to unload\n")); + return; + } + + if (!rtlpriv->dm.b_useramask) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver does not control rate adaptive mask\n")); + return; + } + + if (mac->link_state == MAC80211_LINKED) { + + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state)); + + rtlpriv->cfg->ops->update_rate_mask(hw, + p_ra->ratr_state); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + dm_pstable.pre_ccastate = CCA_MAX; + dm_pstable.cur_ccasate = CCA_MAX; + dm_pstable.pre_rfstate = RF_MAX; + dm_pstable.cur_rfstate = RF_MAX; + dm_pstable.rssi_val_min = 0; +} + +static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_ccastate == CCA_2R) { + if (dm_pstable.rssi_val_min >= 35) + dm_pstable.cur_ccasate = CCA_1R; + else + dm_pstable.cur_ccasate = CCA_2R; + } else { + if (dm_pstable.rssi_val_min <= 30) + dm_pstable.cur_ccasate = CCA_2R; + else + dm_pstable.cur_ccasate = CCA_1R; + } + } else { + dm_pstable.cur_ccasate = CCA_MAX; + } + + if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { + if (dm_pstable.cur_ccasate == CCA_1R) { + if (get_rf_type(rtlphy) == RF_2T2R) { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x13); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x23); + rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); + } + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, + 0x33); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); + } + dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; + } + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", + (dm_pstable.cur_ccasate == + 0) ? "1RCCA" : "2RCCA")); +} + +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + static u8 initialize; + static u32 reg_874, reg_c70, reg_85c, reg_a74; + + if (initialize == 0) { + reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; + + initialize = 1; + } + + if (!bforce_in_normal) { + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_rfstate == RF_NORMAL) { + if (dm_pstable.rssi_val_min >= 30) + dm_pstable.cur_rfstate = RF_SAVE; + else + dm_pstable.cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable.rssi_val_min <= 25) + dm_pstable.cur_rfstate = RF_NORMAL; + else + dm_pstable.cur_rfstate = RF_SAVE; + } + } else { + dm_pstable.cur_rfstate = RF_MAX; + } + } else { + dm_pstable.cur_rfstate = RF_NORMAL; + } + + if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { + if (dm_pstable.cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + } + + dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; + } +} + +static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + dm_pstable.rssi_val_min = 0; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("Not connected to any\n")); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + + if (IS_92C_SERIAL(rtlhal->version)) + rtl92c_dm_1r_cca(hw); +} + +void rtl92c_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl92c_dm_diginit(hw); + rtl92c_dm_init_dynamic_txpower(hw); + rtl92c_dm_init_edca_turbo(hw); + rtl92c_dm_init_rate_adaptive_mask(hw); + rtl92c_dm_initialize_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); +} + +void rtl92c_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_fw_current_inpsmode = false; + bool b_fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *) (&b_fw_ps_awake)); + + if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && + b_fw_ps_awake) + && (!ppsc->rfchange_inprogress)) { + rtl92c_dm_pwdb_monitor(hw); + rtl92c_dm_dig(hw); + rtl92c_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_bb_powersaving(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_dm_refresh_rate_adaptive_mask(hw); + rtl92c_dm_check_edca_turbo(hw); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h new file mode 100644 index 000000000000..463439e4074c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_DM_H__ +#define __RTL92C_DM_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX 0x3e +#define DM_DIG_MIN 0x1e + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RXPATHSELECTION_SS_TH_lOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVal 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + long rssi_val_min; +}; + +struct dig_t { + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + u8 cursta_connectctate; + u8 presta_connectstate; + u8 curmultista_connectstate; + u8 pre_igvalue; + u8 cur_igvalue; + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 rssi_val_min; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; +}; + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum tag_cck_packet_detection_threshold_type_definition { + CCK_PD_STAGE_LowRssi = 0, + CCK_PD_STAGE_HighRssi = 1, + CCK_FA_STAGE_Low = 2, + CCK_FA_STAGE_High = 3, + CCK_PD_STAGE_MAX = 4, +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum dm_dig_ext_port_alg_e { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_connect_e { + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MULTISTA_DISCONNECT = 3, + DIG_MULTISTA_CONNECT = 4, + DIG_CONNECT_MAX +}; + +extern struct dig_t dm_digtable; +void rtl92c_dm_init(struct ieee80211_hw *hw); +void rtl92c_dm_watchdog(struct ieee80211_hw *hw); +void rtl92c_dm_write_dig(struct ieee80211_hw *hw); +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c new file mode 100644 index 000000000000..11dd22b987e7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c @@ -0,0 +1,804 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "table.h" + +static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { + u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (enable) + value32 |= MCUFWDL_EN; + else + value32 &= ~MCUFWDL_EN; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { + u8 tmp; + if (enable) { + + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } + } +} + +static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, + const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 blockSize = sizeof(u32); + u8 *bufferPtr = (u8 *) buffer; + u32 *pu4BytePtr = (u32 *) buffer; + u32 i, offset, blockCount, remainSize; + + blockCount = size / blockSize; + remainSize = size % blockSize; + + for (i = 0; i < blockCount; i++) { + offset = i * blockSize; + rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), + *(pu4BytePtr + i)); + } + + if (remainSize) { + offset = blockCount * blockSize; + bufferPtr += offset; + for (i = 0; i < remainSize; i++) { + rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + + offset + i), *(bufferPtr + i)); + } + } +} + +static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, + u32 page, const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8) (page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + _rtl92c_fw_block_write(hw, buffer, size); +} + +static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8) (fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} + +static void _rtl92c_write_fw(struct ieee80211_hw *hw, + enum version_8192c version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_version_b; + u8 *bufferPtr = (u8 *) buffer; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + + is_version_b = IS_CHIP_VER_B(version); + if (is_version_b) { + u32 pageNums, remainSize; + u32 page, offset; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) + _rtl92c_fill_dummy(bufferPtr, &size); + + pageNums = size / FW_8192C_PAGE_SIZE; + remainSize = size % FW_8192C_PAGE_SIZE; + + if (pageNums > 4) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Page numbers should not greater then 4\n")); + } + + for (page = 0; page < pageNums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remainSize) { + offset = pageNums * FW_8192C_PAGE_SIZE; + page = pageNums; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + remainSize); + } + } else { + _rtl92c_fw_block_write(hw, buffer, size); + } +} + +static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_ChkSum_rpt))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", + value32)); + goto exit; + } + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Polling FW ready success!!" + " REG_MCUFWDL:0x%08x .\n", + value32)); + err = 0; + goto exit; + } + + mdelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + +exit: + return err; +} + +int rtl92c_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl92c_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192c version = rtlhal->version; + + const struct firmware *firmware = NULL; + + err = request_firmware(&firmware, rtlpriv->cfg->fw_name, + rtlpriv->io.dev); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to request firmware!\n")); + return 1; + } + + if (firmware->size > 0x4000) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is too big!\n")); + release_firmware(firmware); + return 1; + } + + memcpy(rtlhal->pfirmware, firmware->data, firmware->size); + fwsize = firmware->size; + release_firmware(firmware); + + pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; + pfwdata = (u8 *) rtlhal->pfirmware; + + if (IS_FW_HEADER_EXIST(pfwheader)) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + pfwheader->version, pfwheader->signature, + (uint)sizeof(struct rtl92c_firmware_header))); + + pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); + fwsize = fwsize - sizeof(struct rtl92c_firmware_header); + } + + _rtl92c_enable_fw_download(hw, true); + _rtl92c_write_fw(hw, version, pfwdata, fwsize); + _rtl92c_enable_fw_download(hw, false); + + err = _rtl92c_fw_free_to_go(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is not ready to run!\n")); + } else { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Firmware is ready to run!\n")); + } + + return 0; +} + +static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr, val_mcutst_1; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); + + if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) + result = true; + return result; +} + +static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg, box_extreg; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->b_h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("H2C set in progress! Wait to set.." + "element_id(%d).\n", element_id)); + + while (rtlhal->b_h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wait 100 us (%d times)...\n", + h2c_waitcounter)); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->b_h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Write H2C fail because no trigger " + "for FW INT!\n")); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating too long for FW read " + "clear HMEBox(%d)!\n", boxnum)); + break; + } + + udelay(10); + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating for FW read clear HMEBox(%d)!!! " + "0x1BF = %2x\n", boxnum, u1b_tmp)); + } + + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write H2C register BOX[%d] fail!!!!! " + "Fw do not read.\n", boxnum)); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id)); + + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 1); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 2); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 2); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum)); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->b_h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); +} + +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (rtlhal->bfw_ready == false) { + RT_ASSERT(false, ("return H2C cmd because of Fw " + "download fail!!!\n")); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); + _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + + return; +} + +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + u8 delay = 100; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) { + RT_ASSERT(false, ("8051 reset fail.\n")); + break; + } + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } +} + +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = {0}; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); + +} + +static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 own; + unsigned long flags; + struct sk_buff *pskb = NULL; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + pdesc = &ring->desc[0]; + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + + return true; +} + +#define BEACON_PG 0 /*->1*/ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5*/ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1RsvdPageLoc[3] = {0}; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); + + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); + + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1RsvdPageLoc, 3); + + + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + + rtstatus = _rtl92c_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Set RSVD page location to Fw.\n")); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", + u1RsvdPageLoc, 3); + rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1RsvdPageLoc), u1RsvdPageLoc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set RSVD page location to Fw FAIL!!!!!!.\n")); +} + +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = {0}; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h new file mode 100644 index 000000000000..3db33bd14666 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_SIZE 0x3000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x3FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 100 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ + (_pfwhdr->signature&0xFFF0) == 0x88C0) + +struct rtl92c_firmware_header { + u16 signature; + u8 category; + u8 function; + u16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + u16 ramcodeSize; + u16 rsvd2; + u32 svnindex; + u32 rsvd3; + u32 rsvd4; + u32 rsvd5; +}; + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + MAX_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) + +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c new file mode 100644 index 000000000000..1266dbe44176 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -0,0 +1,2173 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "hw.h" + +#define LLT_CONFIG 5 + +static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *) (val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfState; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *) (&rfState)); + if (rfState == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->b_fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *) (val)) = tsf; + + break; + } + case HW_VAR_MGT_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); + break; + case HW_VAR_CTRL_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); + break; + case HW_VAR_DATA_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (b_rate_cfg >> 8)&0xff); + while (b_rate_cfg > 0x1) { + b_rate_cfg = (b_rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *) val)); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("HW_VAR_SLOT_TIME %x\n", val[0])); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&e_aci)); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool) (*(u8 *) val); + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *((u8 *) val); + if (min_spacing_to_set <= 7) { + sec_min_space = 0; + + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg)); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *) val); + mac->min_space_cfg |= (density_to_set << 3); + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg)); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + + factor_toset = *((u8 *) val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + + } + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset)); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *) val); + u32 u4b_ac_param = 0; + + u4b_ac_param |= (u32) mac->ac[e_aci].aifs; + u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min + & 0xF) << AC_PARAM_ECW_MIN_OFFSET; + u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max & + 0xF) << AC_PARAM_ECW_MAX_OFFSET; + u4b_ac_param |= (u32) mac->ac[e_aci].tx_op + << AC_PARAM_TXOP_LIMIT_OFFSET; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("queue:%x, ac_param:%x\n", e_aci, + u4b_ac_param)); + + switch (e_aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, + u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, + u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, + u4b_ac_param); + break; + default: + RT_ASSERT(false, + ("SetHwReg8185(): invalid aci: %d !\n", + e_aci)); + break; + } + + if (rtlpci->acm_method != eAcmWay2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + (u8 *) (&e_aci)); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *) val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= AcmHw_BeqEn; + break; + case AC2_VI: + acm_ctrl |= AcmHw_ViqEn; + break; + case AC3_VO: + acm_ctrl |= AcmHw_VoqEn; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("HW_VAR_ACM_CTRL acm set " + "failed: eACI is %d\n", acm)); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~AcmHw_BeqEn); + break; + case AC2_VI: + acm_ctrl &= (~AcmHw_ViqEn); + break; + case AC3_VO: + acm_ctrl &= (~AcmHw_BeqEn); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } + + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " + "Write 0x%X\n", acm_ctrl)); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *) (val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *) val); + break; + case HW_VAR_IO_CMD: + rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + (*(u8 *) val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *) val) | BIT(7))); + } + + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = (*(u8 *) val); + + if ((psmode != FW_PS_ACTIVE_MODE) && + (!IS_92C_SERIAL(rtlhal->version))) { + rtl92c_dm_rf_saving(hw, true); + } + + rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->b_fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *) val); + u8 tmp_regcr, tmp_reg422; + bool b_recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = + rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + b_recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + + rtl92c_set_fw_rsvdpagepkt(hw, 0); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) { + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + } + + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + + break; + } + case HW_VAR_AID:{ + u16 u2btmp; + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *) (val))[0]; + + /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? + 1 : 0;*/ + + if (btype_ibss == true) + _rtl92ce_stop_tx_beacon(hw); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32)&0xffffffff)); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss == true) + _rtl92ce_resume_tx_beacon(hw); + + break; + + } + case HW_VAR_MGT_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val); + break; + case HW_VAR_CTRL_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val); + break; + case HW_VAR_DATA_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + break; + } +} + +static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to polling write LLT done at " + "address %d!\n", address)); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxPage; + bool status; + +#if LLT_CONFIG == 1 + maxPage = 255; + txpktbuf_bndy = 252; +#elif LLT_CONFIG == 2 + maxPage = 127; + txpktbuf_bndy = 124; +#elif LLT_CONFIG == 3 + maxPage = 255; + txpktbuf_bndy = 174; +#elif LLT_CONFIG == 4 + maxPage = 255; + txpktbuf_bndy = 246; +#elif LLT_CONFIG == 5 + maxPage = 255; + txpktbuf_bndy = 246; +#endif + +#if LLT_CONFIG == 1 + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c); + rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c); +#elif LLT_CONFIG == 2 + rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010); +#elif LLT_CONFIG == 3 + rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484); +#elif LLT_CONFIG == 4 + rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c); +#elif LLT_CONFIG == 5 + rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29); +#endif + + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl92ce_llt_write(hw, i, i + 1); + if (true != status) + return status; + } + + status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (true != status) + return status; + + for (i = txpktbuf_bndy; i < maxPage; i++) { + status = _rtl92ce_llt_write(hw, i, (i + 1)); + if (true != status) + return status; + } + + status = _rtl92ce_llt_write(hw, maxPage, txpktbuf_bndy); + if (true != status) + return status; + + return true; +} + +static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + + if (rtlpci->up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92ce_sw_led_on(hw, pLed0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92ce_sw_led_on(hw, pLed0); + else + rtl92ce_sw_led_off(hw, pLed0); + +} + +static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); + udelay(2); + + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + udelay(2); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(2); + + retry = 0; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), + bytetmp)); + + while ((bytetmp & BIT(0)) && retry < 1000) { + retry++; + udelay(50); + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, + 0xEC), + bytetmp)); + udelay(50); + } + + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); + + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); + udelay(2); + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (_rtl92ce_llt_table_init(hw) == false) + return false;; + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77); + else + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && (bytetmp & BIT(7))); + + _rtl92ce_gen_refresh_led_state(hw); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true;; +} + +static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_bw_opmode; + u32 reg_ratr, reg_prsr; + + reg_bw_opmode = BW_OPMODE_20MHZ; + reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); + + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); + + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + +} + +static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + + if (ppsc->b_support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm)); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " + "hw encryption\n")); + return; + } + + sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TxUseDK; + sec_reg_value |= SCR_RxUseDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The SECR-value %x\n", sec_reg_value)); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); + +} + +int rtl92ce_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + static bool iqk_initialized; /* initialized to false */ + bool rtstatus = true; + bool is92c; + int err; + u8 tmp_u1b; + + rtlpci->being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl92ce_init_mac(hw); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + err = 1; + return err; + } + + err = rtl92c_download_fw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Failed to download FW. Init HW " + "without FW now..\n")); + err = 1; + rtlhal->bfw_ready = false; + return err; + } else { + rtlhal->bfw_ready = true; + } + + rtlhal->last_hmeboxnum = 0; + rtl92c_phy_mac_config(hw); + rtl92c_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl92c_phy_rf_config(hw); + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + _rtl92ce_hw_configure(hw); + rtl_cam_reset_all_entry(hw); + rtl92ce_enable_hw_security_config(hw); + ppsc->rfpwr_state = ERFON; + tmp_u1b = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&(~BIT(3)); + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, tmp_u1b); + tmp_u1b = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + ppsc->rfoff_reason |= (tmp_u1b & BIT(3)) ? 0 : RF_CHANGE_BY_HW; + if (ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtl_ps_set_rf_state(hw, ERFOFF, ppsc->rfoff_reason, true); + else { + ppsc->rfpwr_state = ERFON; + ppsc->rfoff_reason = 0; + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); + } + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl92ce_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + if (ppsc->rfpwr_state == ERFON) { + rtl92c_phy_set_rfpath_switch(hw, 1); + if (iqk_initialized) + rtl92c_phy_iq_calibrate(hw, true); + else { + rtl92c_phy_iq_calibrate(hw, false); + iqk_initialized = true; + } + + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_phy_lc_calibrate(hw); + } + + is92c = IS_92C_SERIAL(rtlhal->version); + tmp_u1b = efuse_read_1byte(hw, 0x1FA); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); + } + + if (!(tmp_u1b & BIT(1)) && is92c) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); + } + + if (!(tmp_u1b & BIT(4))) { + tmp_u1b = rtl_read_byte(rtlpriv, 0x16); + tmp_u1b &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); + udelay(10); + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); + } + rtl92c_dm_init(hw); + rtlpci->being_init_adapter = false; + return err; +} + +static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8192c version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : + VERSION_A_CHIP_88C; + } else { + version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C : + VERSION_B_CHIP_88C; + } + + switch (version) { + case VERSION_B_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + break; + case VERSION_B_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_B_CHIP_88C.\n")); + break; + case VERSION_A_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_A_CHIP_92C.\n")); + break; + case VERSION_A_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_A_CHIP_88C.\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Chip Version ID: Unknown. Bug?\n")); + break; + } + + switch (version & 0x3) { + case CHIP_88C: + rtlphy->rf_type = RF_1T1R; + break; + case CHIP_92C: + rtlphy->rf_type = RF_2T2R; + break; + case CHIP_92C_1T2R: + rtlphy->rf_type = RF_1T2R; + break; + default: + rtlphy->rf_type = RF_1T1R; + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("ERROR RF_Type is set!!")); + break; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R")); + + return version; +} + +static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + bt_msr &= 0xfc; + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + _rtl92ce_stop_tx_beacon(hw); + _rtl92ce_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { + _rtl92ce_resume_tx_beacon(hw); + _rtl92ce_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set HW_VAR_MEDIA_STATUS: " + "No such media status(%x).\n", type)); + } + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to NO LINK!\n")); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to Ad Hoc!\n")); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to STA!\n")); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to AP!\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Network type %d not support!\n", type)); + return 1; + break; + + } + + rtl_write_byte(rtlpriv, (MSR), bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & 0xfc) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); + u8 filterout_non_associated_bssid = false; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + filterout_non_associated_bssid = true; + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_AP: + default: + break; + } + + if (filterout_non_associated_bssid == true) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *) (®_rcr)); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (filterout_non_associated_bssid == false) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *) (®_rcr)); + } +} + +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + if (_rtl92ce_set_media_status(hw, type)) + return -EOPNOTSUPP; + _rtl92ce_set_check_bssid(hw, type); + return 0; +} + +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + u32 u4b_ac_param; + + rtl92c_dm_init_edca_turbo(hw); + + u4b_ac_param = (u32) mac->ac[aci].aifs; + u4b_ac_param |= + ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; + u4b_ac_param |= + ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; + u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET; + RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, + ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", + aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min, + mac->ac[aci].cw_max, mac->ac[aci].tx_op)); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); + break; + default: + RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + break; + } +} + +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + rtlpci->irq_enabled = false; +} + +static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + rtlpriv->intf_ops->enable_aspm(hw); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready) + rtl92c_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | + (u1b_tmp << 8)); + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); +} + +void rtl92ce_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92ce_set_media_status(hw, opmode); + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl92ce_poweroff_adapter(hw); +} + +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, *p_inta); + + /* + * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); + */ +} + +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, + ("beacon_interval:%d\n", bcn_interval)); + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92ce_disable_interrupt(hw); + rtl92ce_enable_interrupt(hw); +} + +static u8 _rtl92c_get_chnl_group(u8 chnl) +{ + u8 group; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + return group; +} + +static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + + i]; + } else { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, + i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [i])); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; + + if ((rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) + > 0) { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path] + [index] - + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [index]; + } else { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; + } + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " + "[0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf0) >> 4); + } + + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i])); + } + } + + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + + index = _rtl92c_get_chnl_group((u8) i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + + if (!autoload_fail) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + + if (!autoload_fail) { + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; + } else { + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; + } + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B])); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->b_apk_thermalmeterignore = true; + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); +} + +static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u16 i, usvalue; + u8 hwinfo[HWSET_MAX_SIZE]; + u16 eeprom_id; + + if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { + rtl_efuse_shadow_map_update(hw); + + memcpy((void *)hwinfo, + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + HWSET_MAX_SIZE); + } else if (rtlefuse->epromtype == EEPROM_93C46) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("RTL819X Not boot from eeprom, check it !!")); + } + + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + hwinfo, HWSET_MAX_SIZE); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8190_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag == true) + return; + + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr))); + + _rtl92ce_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + + rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; + rtlefuse->b_txpwr_fromeprom = true; + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) + rtlhal->oem_id = RT_CID_819x_HP; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819x_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + + } + } + +} + +static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (rtlhal->oem_id) { + case RT_CID_819x_HP: + pcipriv->ledctl.bled_opendrain = true; + break; + case RT_CID_819x_Lenovo: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819x_Acer: + case RT_CID_WHQL: + default: + break; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); +} + +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92ce_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.brfpath_rxenable[0] = true; + else + rtlpriv->dm.brfpath_rxenable[0] = + rtlpriv->dm.brfpath_rxenable[1] = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", + rtlhal->version)); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + rtlefuse->epromtype = EEPROM_93C46; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + _rtl92ce_read_adapter_info(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + } + + _rtl92ce_hal_customized_behavior(hw); +} + +void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + u32 ratr_value = (u32) mac->basic_rates; + u8 *p_mcsrate = mac->mcs; + u8 ratr_index = 0; + u8 b_nmode = mac->ht_enable; + u8 mimo_ps = 1; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 b_curtxbw_40mhz = mac->bw_40; + u8 b_curshortgi_40mhz = mac->sgi_40; + u8 b_curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + + ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + b_nmode = 1; + if (mimo_ps == 0) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + ratr_value &= 0x0FFFFFFF; + + if (b_nmode && ((b_curtxbw_40mhz && + b_curshortgi_40mhz) || (!b_curtxbw_40mhz && + b_curshortgi_20mhz))) { + + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); +} + +void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 ratr_bitmap = (u32) mac->basic_rates; + u8 *p_mcsrate = mac->mcs; + u8 ratr_index; + u8 b_curtxbw_40mhz = mac->bw_40; + u8 b_curshortgi_40mhz = mac->sgi_40; + u8 b_curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + bool b_shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + u8 mimops = 1; + + ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (mimops == 0) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (b_curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (b_curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + + if ((b_curtxbw_40mhz && b_curshortgi_40mhz) || + (!b_curtxbw_40mhz && b_curshortgi_20mhz)) { + + if (macid == 0) + b_shortgi = true; + else if (macid == 1) + b_shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("ratr_bitmap :%x\n", ratr_bitmap)); + *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | + (ratr_index << 28)); + rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " + "ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4])); + rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); +} + +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; + u8 u1tmp; + bool b_actuallyset = false; + unsigned long flag; + + if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) + return false; + + if (ppsc->b_swrf_processing) + return false; + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + cur_rfstate = ppsc->rfpwr_state; + + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG)&~(BIT(3))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; + + if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio ON, RF ON\n")); + + e_rfpowerstate_toset = ERFON; + ppsc->b_hwradiooff = false; + b_actuallyset = true; + } else if ((ppsc->b_hwradiooff == false) + && (e_rfpowerstate_toset == ERFOFF)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + + e_rfpowerstate_toset = ERFOFF; + ppsc->b_hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + if (e_rfpowerstate_toset == ERFON) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + + if (e_rfpowerstate_toset == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + } + + } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + } + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + *valid = 1; + return !ppsc->b_hwradiooff; + +} + +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + key_index = PAIRWISE_KEYIDX; + entry_id = CAM_PAIRWISE_KEY_POSITION; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("delete one entry\n")); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1])); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("add one entry\n")); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwiase Key content :", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set Pairwiase key\n")); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec. + key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set group key\n")); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h new file mode 100644 index 000000000000..305c819c8c78 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_HW_H__ +#define __RTL92CE_HW_H__ + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb); +int rtl92ce_hw_init(struct ieee80211_hw *hw); +void rtl92ce_card_disable(struct ieee80211_hw *hw); +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); +void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c new file mode 100644 index 000000000000..78a0569208ea --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->b_ledon = true; +} + +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + u8 ledcfg; + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (pcipriv->ledctl.bled_opendrain == true) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->b_ledon = false; +} + +void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) +{ +} + +void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) +{ +} + +void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92ce_sw_led_on(hw, pLed0); + break; + case LED_CTL_POWER_OFF: + rtl92ce_sw_led_off(hw, pLed0); + break; + default: + break; + } +} + +void rtl92ce_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", + ledaction)); + _rtl92ce_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h new file mode 100644 index 000000000000..10da3018f4b7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); +void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); +void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c new file mode 100644 index 000000000000..45044117139a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -0,0 +1,2676 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, u32 para1, + u32 para2, u32 msdelay); +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath); +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x)\n", regaddr, + bitmask)); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " + "Addr[0x%x]=0x%x\n", bitmask, + regaddr, originalvalue)); + + return returnvalue; + +} + +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + +} + +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask)); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, regaddr); + } else { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } + + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), rfpath(%#x), " + "bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value)); + + return readback_value; +} + +void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + + _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x), data(%#x), " + "rfpath(%#x)\n", regaddr, + bitmask, data, rfpath)); +} + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + RT_ASSERT(false, ("deprecated!\n")); + return 0; +} + +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + RT_ASSERT(false, ("deprecated!\n")); +} + +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0x3f; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + mdelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + mdelay(1); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + mdelay(1); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, + BLSSIREADBACKDATA); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, + retvalue)); + return retvalue; +} + +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + return; + } + offset &= 0x3f; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, + data_and_addr)); +} + +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + return i; +} + +static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); + rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); + rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); + rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); +} + +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is92c = IS_92C_SERIAL(rtlhal->version); + bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + + if (is92c) + rtl_write_byte(rtlpriv, 0x14, 0x71); + return rtstatus; +} + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regvaldw; + u8 b_reg_hwparafile = 1; + + _rtl92c_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTn | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92c_phy_rf6052_config(hw); +} + +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + return false; + } + if (rtlphy->rf_type == RF_1T2R) { + _rtl92c_phy_bb_config_1t(hw); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + } + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + return false; + } + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + return false; + } + rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + return true; +} + +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = RTL8192CEMAC_2T_ARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Img:RTL8192CEMAC_2T_ARRAY\n")); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) +{ +} + +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + agctab_arraylen = AGCTAB_2TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_2TARRAY; + phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_2TARRAY; + } else { + agctab_arraylen = AGCTAB_1TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_1TARRAY; + phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_1TARRAY; + } + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + if (phy_regarray_table[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table[i] == 0xfb) + udelay(50); + else if (phy_regarray_table[i] == 0xfa) + udelay(5); + else if (phy_regarray_table[i] == 0xf9) + udelay(1); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The phy_regarray_table[0] is %x" + " Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1])); + } + rtl92c_phy_config_bb_external_pa(hw); + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The agctab_array_table[0] is " + "%x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1])); + } + } + return true; +} + +static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][0])); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][1])); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][6])); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][7])); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][2])); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][3])); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][4])); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][5])); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][8])); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][9])); + } + + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][14])); + } + + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][15])); + } + + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][10])); + } + + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][11])); + } + + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][12])); + } + + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][13])); + + rtlphy->pwrgroup_cnt++; + } +} + +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH; + phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + if (phy_regarray_table_pg[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table_pg[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table_pg[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table_pg[i] == 0xfb) + udelay(50); + else if (phy_regarray_table_pg[i] == 0xfa) + udelay(5); + else if (phy_regarray_table_pg[i] == 0xf9) + udelay(1); + + _rtl92c_store_pwrIndex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("configtype != BaseBand_Config_PHY_REG\n")); + } + return true; +} + +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + return true; +} + +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + + int i; + bool rtstatus = true; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + radioa_arraylen = RADIOA_2TARRAYLENGTH; + radioa_array_table = RTL8192CERADIOA_2TARRAY; + radiob_arraylen = RADIOB_2TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_2TARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + } else { + radioa_arraylen = RADIOA_1TARRAYLENGTH; + radioa_array_table = RTL8192CE_RADIOA_1TARRAY; + radiob_arraylen = RADIOB_1TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_1TARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + rtstatus = true; + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + if (radioa_array_table[i] == 0xfe) + mdelay(50); + else if (radioa_array_table[i] == 0xfd) + mdelay(5); + else if (radioa_array_table[i] == 0xfc) + mdelay(1); + else if (radioa_array_table[i] == 0xfb) + udelay(50); + else if (radioa_array_table[i] == 0xfa) + udelay(5); + else if (radioa_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + udelay(1); + } + } + _rtl92c_phy_config_rf_external_pa(hw, rfpath); + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + if (radiob_array_table[i] == 0xfe) { + mdelay(50); + } else if (radiob_array_table[i] == 0xfd) + mdelay(5); + else if (radiob_array_table[i] == 0xfc) + mdelay(1); + else if (radiob_array_table[i] == 0xfb) + udelay(50); + else if (radiob_array_table[i] == 0xfa) + udelay(5); + else if (radiob_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + udelay(1); + } + } + break; + case RF90_PATH_C: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + case RF90_PATH_D: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + return true; +} + +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->default_initialgain[0] = + (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default initial gain (c50=0x%x, " + "c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3])); + + rtlphy->framesync = (u8) rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync)); +} + +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVEB_HSPI_READBACK; + +} + +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx + + rtlefuse->legacy_ht_txpowerdiff; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (get_rf_type(rtlphy) == RF_2T2R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (rtlefuse->b_txpwr_fromeprom == false) + return; + _rtl92c_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0]); + _rtl92c_ccxpower_index_check(hw, + channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} + +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 idx; + u8 rf_path; + + u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_B, + power_indbm); + u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_N_24G, + power_indbm); + if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) + ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; + else + ofdmtxpwridx = 0; + RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, + ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx)); + for (idx = 0; idx < 14; idx++) { + for (rf_path = 0; rf_path < 2; rf_path++) { + rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; + rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = + ofdmtxpwridx; + rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = + ofdmtxpwridx; + } + } + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + return true; +} + +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) +{ +} + +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) +{ + u8 txpwridx; + long offset; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + + if ((power_indbm - offset) > 0) + txpwridx = (u8) ((power_indbm - offset) * 2); + else + txpwridx = 0; + + if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) + txpwridx = MAX_TXPWR_IDX_NMODE_92S; + + return txpwridx; +} + +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Unknown Scan Backup operation.\n")); + break; + } + } +} + +void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz")) + + if (is_hal_stop(rtlhal)) + return; + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) + rtl92c_phy_set_bw_mode_callback(hw); + else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("FALSE driver sleep or unload\n")); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 delay; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("switch to channel%d\n", rtlphy->current_channel)); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92c_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else + rtlphy->sw_chnl_inprogress = false; + break; + } while (true); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + RT_ASSERT((rtlphy->current_channel <= 14), + ("WIRELESS_MODE_G but channel>14")); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92c_phy_sw_chnl_callback(hw); + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false schdule workitem\n")); + rtlphy->sw_chnl_inprogress = false; + } else { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false driver sleep or" + " unload\n")); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + RT_ASSERT((channel >= 1 && channel <= 14), + ("illegal channel for Zebra: %d\n", channel)); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92c_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16) currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8) currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) +{ + return true; +} + +static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, + config_pathb ? 0x28160202 : 0x28160502); + + if (config_pathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); + } + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) + return; + else if (b_iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) + return; + else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *addareg, bool is_patha_on, bool is2t) +{ + u32 pathOn; + u32 i; + + pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (false == is2t) { + pathOn = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); +} + +static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_write_byte(rtlpriv, macreg[0], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8) (macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} + +static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else if (!(simularity_bitmap & 0xF0) && is2t) { + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } + +} + +static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + const u32 retrycount = 2; + + u32 bbvalue; + + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); + + _rtl92c_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } + _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + if (!rtlphy->b_rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, true); + if (t == 0) { + rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); + rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); + rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x03) { + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) + result[t][0] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & 0x3FF0000) >> + 16; + result[t][1] = + (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; + + } + + if (is2t) { + _rtl92c_phy_path_a_standby(hw); + _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92c_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); + rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + if (t != 0) { + if (!rtlphy->b_rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, false); + _rtl92c_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } +} + +static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, + char delta, bool is2t) +{ + /* This routine is deliberately dummied out for later fixes */ +#if 0 + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + u32 reg_d[PATH_NUM]; + u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; + + u32 bb_backup[APK_BB_REG_NUM]; + u32 bb_reg[APK_BB_REG_NUM] = { + 0x904, 0xc04, 0x800, 0xc08, 0x874 + }; + u32 bb_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 + }; + u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 + }; + + u32 afe_backup[APK_AFE_REG_NUM]; + u32 afe_reg[APK_AFE_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, + 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, + 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, + 0xeec + }; + + u32 mac_backup[IQK_MAC_REG_NUM]; + u32 mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; + + u32 afe_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4 + }; + + u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; + + u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; + + u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; + + u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; + + const char apk_delta_mapping[APK_BB_REG_NUM][13] = { + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + const u32 apk_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + const u32 apk_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; + + long bb_offset, delta_v, delta_offset; + + if (!is2t) + pathbound = 1; + + for (index = 0; index < PATH_NUM; index++) { + apk_offset[index] = apk_normal_offset[index]; + apk_value[index] = apk_normal_value[index]; + afe_on_off[index] = 0x6fdb25a4; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + for (path = 0; path < pathbound; path++) { + apk_rf_init_value[path][index] = + apk_normal_rf_init_value[path][index]; + apk_rf_value_0[path][index] = + apk_normal_rf_value_0[path][index]; + } + bb_ap_mode[index] = bb_normal_ap_mode[index]; + + apkbound = 6; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); + } + + _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); + + _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + if (path == RF90_PATH_A) { + offset = 0xb00; + for (index = 0; index < 11; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb00; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } else if (path == RF90_PATH_B) { + offset = 0xb70; + for (index = 0; index < 10; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + index = 11; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb60; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } + + reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, + 0xd, MASKDWORD); + + for (index = 0; index < APK_AFE_REG_NUM; index++) + rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, + afe_on_off[path]); + + if (path == RF90_PATH_A) { + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, + bb_ap_mode[index]); + } + } + + _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); + + if (path == 0) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); + } else { + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, + 0x10000); + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20103); + } + + delta_offset = ((delta + 14) / 2); + if (delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index != 1) + continue; + + tmpreg = apk_rf_init_value[path][index]; + + if (!rtlefuse->b_apk_thermalmeterignore) { + bb_offset = (tmpreg & 0xF0000) >> 16; + + if (!(tmpreg & BIT(15))) + bb_offset = -bb_offset; + + delta_v = + apk_delta_mapping[index][delta_offset]; + + bb_offset += delta_v; + + if (bb_offset < 0) { + tmpreg = tmpreg & (~BIT(15)); + bb_offset = -bb_offset; + } else { + tmpreg = tmpreg | BIT(15); + } + + tmpreg = + (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); + } + + rtl_set_rfreg(hw, (enum radio_path)path, 0xc, + MASKDWORD, 0x8992e); + rtl_set_rfreg(hw, (enum radio_path)path, 0x0, + MASKDWORD, apk_rf_value_0[path][index]); + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, tmpreg); + + i = 0; + do { + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[0]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(3); + + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[1]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(20); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + + if (path == RF90_PATH_A) + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0x03E00000); + else + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0xF8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset " + "0xbd8[25:21] %x\n", tmpreg)); + + i++; + + } while (tmpreg > apkbound && i < 4); + + apk_result[path][index] = tmpreg; + } + } + + _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); + } + + _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, reg_d[path]); + + if (path == RF90_PATH_B) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20101); + } + + if (apk_result[path][1] > 6) + apk_result[path][1] = 6; + } + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (apk_result[path][1] << 5) | + apk_result[path][1])); + + if (path == RF90_PATH_A) + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x00 << 5) | 0x05)); + else + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x02 << 5) | 0x05)); + + rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, + ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | + 0x08)); + + } + + rtlphy->b_apk_done = true; +#endif +} + +static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) { + rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); + rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); + else + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); + + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, + reg_ecc, reg_tmp = 0; + bool is12simular, is13simular, is23simular; + bool b_start_conttx = false, b_singletone = false; + u32 iqk_bb_reg[10] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + _rtl92c_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); + return; + } + if (b_start_conttx || b_singletone) + return; + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + b_pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_iq_calibrate(hw, result, i, true); + else + _rtl92c_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92c_phy_simularity_compare(hw, + result, 1, + 2); + if (is23simular) + final_candidate = 1; + else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; + rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + reg_eac = result[final_candidate][3]; + rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; + rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; + reg_ec4 = result[final_candidate][6]; + reg_ecc = result[final_candidate][7]; + b_patha_ok = b_pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ + _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (IS_92C_SERIAL(rtlhal->version)) { + if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ + _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, + result, + final_candidate, + (reg_ec4 == 0)); + } + _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); +} + +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_start_conttx = false, b_singletone = false; + + if (b_start_conttx || b_singletone) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_lc_calibrate(hw, true); + else + _rtl92c_phy_lc_calibrate(hw, false); +} + +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->b_apk_done) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_ap_calibrate(hw, delta, true); + else + _rtl92c_phy_ap_calibrate(hw, delta, false); +} + +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_set_rfpath_switch(hw, bmain, true); + else + _rtl92c_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool b_postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress)); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Resume DM after scan.\n")); + b_postprocessing = true; + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Pause DM before scan.\n")); + b_postprocessing = true; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } while (false); + if (b_postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92c_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + return true; +} + +void rtl92c_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress)); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92c_dm_write_dig(hw); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; + dm_digtable.cur_igvalue = 0x17; + rtl92c_dm_write_dig(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("<---(%#x)\n", rtlphy->current_io_type)); +} + +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + u32 u4b_tmp; + u8 delay = 5; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4b_tmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Switch RF timeout !!!.\n")); + return; + } + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + ppsc->set_rfpowerstate_inprogress = true; + switch (rfpwr_state) { + case ERFON:{ + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 InitializeCount = 0; + do { + InitializeCount++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic enable\n")); + rtstatus = rtl_ps_enable_nic(hw); + } while ((rtstatus != true) + && (InitializeCount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies))); + ppsc->last_awake_jiffies = jiffies; + rtl92ce_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + } + case ERFOFF:{ + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] " + "=%d before doze!\n", (i + 1), + queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\nERFOFF: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic disable\n")); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + } + case ERFSLEEP:{ + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] =%d before " + "doze!\n", (i + 1), queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\n ERFSLEEP: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies))); + ppsc->last_sleep_jiffies = jiffies; + _rtl92ce_phy_set_rf_sleep(hw); + break; + } + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + ppsc->set_rfpowerstate_inprogress = false; + return bresult; +} + +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h new file mode 100644 index 000000000000..ca4daee6e9a8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -0,0 +1,237 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define AntennaDiversityValue 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF90_PATH_MAX 2 +#define CHANNEL_MAX_NUMBER 14 +#define CHANNEL_GROUP_MAX 3 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 +#define CHANNEL_MAX_NUMBER 14 +#define CHANNEL_GROUP_MAX 3 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, + u16 beaconinterval); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, + u32 rfpath); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h new file mode 100644 index 000000000000..875d51465225 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -0,0 +1,2065 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_REG_H__ +#define __RTL92C_REG_H__ + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_C2HEVT_CLEAR 0x01BF +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_USTIME_TSF 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \ + | RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_C2HCMD BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +#define HWSET_MAX_SIZE 128 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x12 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8192_EEPROM_ID 0x8129 + +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_VID 0x0A +#define EEPROM_DID 0x0C +#define EEPROM_SVID 0x0E +#define EEPROM_SMID 0x10 + +#define EEPROM_MAC_ADDR 0x16 + +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F +#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 + +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 +#define EEPROM_XTAL_K 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_CHANNEL_PLAN 0x7D +#define EEPROM_VERSION 0x7E +#define EEPROM_CUSTOMER_ID 0x7F + +#define EEPROM_PWRDIFF 0x54 + +#define EEPROM_TXPOWERCCK 0x5A +#define EEPROM_TXPOWERHT40_1S 0x60 +#define EEPROM_TXPOWERHT40_2SDIFF 0x66 +#define EEPROM_TXPOWERHT20DIFF 0x69 +#define EEPROM_TXPOWER_OFDMDIFF 0x6C + +#define EEPROM_TXPWR_GROUP 0x6F + +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 + +#define EEPROM_CHANNELPLAN 0x75 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define Timer_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EnBT BIT(5) +#define EnUart BIT(8) +#define Uart_910 BIT(9) +#define EnPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EnSIC BIT(12) +#define SIC_23 BIT(13) +#define EnHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TxUseDK BIT(0) +#define SCR_RxUseDK BIT(1) +#define SCR_TxEncEnable BIT(2) +#define SCR_RxDecEnable BIT(3) +#define SCR_SKByA2 BIT(4) +#define SCR_NoSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32Er 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define rFPGA0_XAB_RFPARAMETER 0x878 +#define rFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LT F 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_Offset) \ + ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define bCCKRxRFSettle 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c new file mode 100644 index 000000000000..ffd8e04c4028 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -0,0 +1,523 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", bandwidth)); + break; + } +} + +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning == true) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32)); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + if (mac->mode == WIRELESS_MODE_B) + tmpval = tmpval & 0xff00ffff; + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32)); +} + +static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerBase0, powerBase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerBase0 = powerlevel[i] + legacy_pwrdiff; + + powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | + (powerBase0 << 8) | powerBase0; + *(ofdmbase + i) = powerBase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerBase1 = powerlevel[i]; + powerBase1 = (powerBase1 << 24) | + (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; + + *(mcsbase + i) = powerBase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + } +} + +static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerBase0, + u32 *powerBase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup, pwr_diff_limit[4]; + u32 writeVal, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 1: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + writeVal = ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, 40MHz, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + } else { + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->pwrgroup_cnt == 4) + chnlgroup++; + } + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerBase0[rf] : + powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, 20MHz, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + } + break; + case 2: + writeVal = + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Better regulatory, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 40MHz " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf][channel - + 1])); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 20MHz " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf][channel - + 1])); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> + (i * 8)); + + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht40[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht20[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit)); + + writeVal = customer_limit + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer, writeVal rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + default: + chnlgroup = 0; + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance, writeVal " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeVal = writeVal - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeVal = writeVal - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeVal; + } +} + +static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pValue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeVal; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeVal = pValue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8) ((writeVal & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Set 0x%x = %08x\n", regoffset, writeVal)); + + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + + writeVal = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + + for (i = 0; i < 3; i++) { + writeVal = (writeVal > 6) ? (writeVal - 6) : 0; + rtl_write_byte(rtlpriv, (u32) (regoffset + i), + (u8) writeVal); + } + } + } +} + +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeVal[2], powerBase0[2], powerBase1[2]; + u8 index; + + rtl92c_phy_get_power_base(hw, ppowerlevel, + channel, &powerBase0[0], &powerBase1[0]); + + for (index = 0; index < 6; index++) { + _rtl92c_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerBase0[0], + &powerBase1[0], + &writeVal[0]); + + _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]); + } +} + +bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl92c_phy_rf6052_config_parafile(hw); +} + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue; + u8 rfpath; + bool rtstatus; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio[%d] Fail!!", rfpath)); + return false; + } + + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + return rtstatus; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h new file mode 100644 index 000000000000..d3014f99bb7b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_RF_H__ +#define __RTL92C_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 + +extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h deleted file mode 100644 index 83cd64895292..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h +++ /dev/null @@ -1,257 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_DEF_H__ -#define __RTL92C_DEF_H__ - -#define HAL_RETRY_LIMIT_INFRA 48 -#define HAL_RETRY_LIMIT_AP_ADHOC 7 - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_LINKQUALITY_SLID_WIN_MAX 20 -#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 - -#define RESET_DELAY_8185 20 - -#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER) -#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) - -#define NUM_OF_FIRMWARE_QUEUE 10 -#define NUM_OF_PAGES_IN_FW 0x100 -#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07 -#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07 -#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07 -#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07 -#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0 -#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 -#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02 -#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02 -#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1 - -#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 -#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 -#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 -#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 - -#define MAX_LINES_HWCONFIG_TXT 1000 -#define MAX_BYTES_LINE_HWCONFIG_TXT 256 - -#define SW_THREE_WIRE 0 -#define HW_THREE_WIRE 2 - -#define BT_DEMO_BOARD 0 -#define BT_QA_BOARD 1 -#define BT_FPGA 2 - -#define RX_SMOOTH_FACTOR 20 - -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 - -#define MAX_H2C_QUEUE_NUM 10 - -#define RX_MPDU_QUEUE 0 -#define RX_CMD_QUEUE 1 -#define RX_MAX_QUEUE 2 -#define AC2QUEUEID(_AC) (_AC) - -#define C2H_RX_CMD_HDR_LEN 8 -#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ - LE_BITS_TO_4BYTE((__prxhdr), 0, 16) -#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \ - LE_BITS_TO_4BYTE((__prxhdr), 16, 8) -#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \ - LE_BITS_TO_4BYTE((__prxhdr), 24, 7) -#define GET_C2H_CMD_CONTINUE(__prxhdr) \ - LE_BITS_TO_4BYTE((__prxhdr), 31, 1) -#define GET_C2H_CMD_CONTENT(__prxhdr) \ - ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN) - -#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8) -#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8) -#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16) -#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5) -#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1) -#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5) -#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1) -#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) -#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ - LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) - -#define CHIP_VER_B BIT(4) -#define CHIP_92C_BITMASK BIT(0) -#define CHIP_92C_1T2R 0x03 -#define CHIP_92C 0x01 -#define CHIP_88C 0x00 - -enum version_8192c { - VERSION_A_CHIP_92C = 0x01, - VERSION_A_CHIP_88C = 0x00, - VERSION_B_CHIP_92C = 0x11, - VERSION_B_CHIP_88C = 0x10, - VERSION_UNKNOWN = 0x88, -}; - -#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) -#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false) - -enum rtl819x_loopback_e { - RTL819X_NO_LOOPBACK = 0, - RTL819X_MAC_LOOPBACK = 1, - RTL819X_DMA_LOOPBACK = 2, - RTL819X_CCK_LOOPBACK = 3, -}; - -enum rf_optype { - RF_OP_BY_SW_3WIRE = 0, - RF_OP_BY_FW, - RF_OP_MAX -}; - -enum rf_power_state { - RF_ON, - RF_OFF, - RF_SLEEP, - RF_SHUT_DOWN, -}; - -enum power_save_mode { - POWER_SAVE_MODE_ACTIVE, - POWER_SAVE_MODE_SAVE, -}; - -enum power_polocy_config { - POWERCFG_MAX_POWER_SAVINGS, - POWERCFG_GLOBAL_POWER_SAVINGS, - POWERCFG_LOCAL_POWER_SAVINGS, - POWERCFG_LENOVO, -}; - -enum interface_select_pci { - INTF_SEL1_MINICARD = 0, - INTF_SEL0_PCIE = 1, - INTF_SEL2_RSV = 2, - INTF_SEL3_RSV = 3, -}; - -enum hal_fw_c2h_cmd_id { - HAL_FW_C2H_CMD_Read_MACREG = 0, - HAL_FW_C2H_CMD_Read_BBREG = 1, - HAL_FW_C2H_CMD_Read_RFREG = 2, - HAL_FW_C2H_CMD_Read_EEPROM = 3, - HAL_FW_C2H_CMD_Read_EFUSE = 4, - HAL_FW_C2H_CMD_Read_CAM = 5, - HAL_FW_C2H_CMD_Get_BasicRate = 6, - HAL_FW_C2H_CMD_Get_DataRate = 7, - HAL_FW_C2H_CMD_Survey = 8, - HAL_FW_C2H_CMD_SurveyDone = 9, - HAL_FW_C2H_CMD_JoinBss = 10, - HAL_FW_C2H_CMD_AddSTA = 11, - HAL_FW_C2H_CMD_DelSTA = 12, - HAL_FW_C2H_CMD_AtimDone = 13, - HAL_FW_C2H_CMD_TX_Report = 14, - HAL_FW_C2H_CMD_CCX_Report = 15, - HAL_FW_C2H_CMD_DTM_Report = 16, - HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, - HAL_FW_C2H_CMD_C2HLBK = 18, - HAL_FW_C2H_CMD_C2HDBG = 19, - HAL_FW_C2H_CMD_C2HFEEDBACK = 20, - HAL_FW_C2H_CMD_MAX -}; - -enum rtl_desc_qsel { - QSLT_BK = 0x2, - QSLT_BE = 0x0, - QSLT_VI = 0x5, - QSLT_VO = 0x7, - QSLT_BEACON = 0x10, - QSLT_HIGH = 0x11, - QSLT_MGNT = 0x12, - QSLT_CMD = 0x13, -}; - -enum rtl_desc92c_rate { - DESC92C_RATE1M = 0x00, - DESC92C_RATE2M = 0x01, - DESC92C_RATE5_5M = 0x02, - DESC92C_RATE11M = 0x03, - - DESC92C_RATE6M = 0x04, - DESC92C_RATE9M = 0x05, - DESC92C_RATE12M = 0x06, - DESC92C_RATE18M = 0x07, - DESC92C_RATE24M = 0x08, - DESC92C_RATE36M = 0x09, - DESC92C_RATE48M = 0x0a, - DESC92C_RATE54M = 0x0b, - - DESC92C_RATEMCS0 = 0x0c, - DESC92C_RATEMCS1 = 0x0d, - DESC92C_RATEMCS2 = 0x0e, - DESC92C_RATEMCS3 = 0x0f, - DESC92C_RATEMCS4 = 0x10, - DESC92C_RATEMCS5 = 0x11, - DESC92C_RATEMCS6 = 0x12, - DESC92C_RATEMCS7 = 0x13, - DESC92C_RATEMCS8 = 0x14, - DESC92C_RATEMCS9 = 0x15, - DESC92C_RATEMCS10 = 0x16, - DESC92C_RATEMCS11 = 0x17, - DESC92C_RATEMCS12 = 0x18, - DESC92C_RATEMCS13 = 0x19, - DESC92C_RATEMCS14 = 0x1a, - DESC92C_RATEMCS15 = 0x1b, - DESC92C_RATEMCS15_SG = 0x1c, - DESC92C_RATEMCS32 = 0x20, -}; - -struct phy_sts_cck_8192s_t { - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -struct h2c_cmd_8192c { - u8 element_id; - u32 cmd_len; - u8 *p_cmdbuffer; -}; - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c deleted file mode 100644 index 4896899394a8..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c +++ /dev/null @@ -1,1473 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../base.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-dm.h" -#include "rtl8192c-fw.h" - -struct dig_t dm_digtable; -static struct ps_t dm_pstable; - -static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { - 0x7f8001fe, - 0x788001e2, - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1e400079, - 0x1c800072, - 0x1b00006c, - 0x19800066, - 0x18000060, - 0x16c0005b, - 0x15800056, - 0x14400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, -}; - -static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, - {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, - {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, - {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, - {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} -}; - -static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} -}; - -static void rtl92c_dm_diginit(struct ieee80211_hw *hw) -{ - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0x0; - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; - dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; - dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable.rx_gain_range_max = DM_DIG_MAX; - dm_digtable.rx_gain_range_min = DM_DIG_MIN; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; -} - -static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long rssi_val_min = 0; - - if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && - (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) - rssi_val_min = - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > - rtlpriv->dm.undecorated_smoothed_pwdb) ? - rtlpriv->dm.undecorated_smoothed_pwdb : - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - else - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || - dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.curmultista_connectstate == - DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - } - - return (u8) rssi_val_min; -} - -static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) -{ - u32 ret_value; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); - falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); - falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); - falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); - falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); - falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; - - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); - falsealm_cnt->cnt_cck_fail = ret_value; - - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); - falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; - falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + - falsealm_cnt->cnt_mcs_fail + - falsealm_cnt->cnt_cck_fail); - - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); -} - -static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value_igi = dm_digtable.cur_igvalue; - - if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) - value_igi--; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) - value_igi += 0; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) - value_igi++; - else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) - value_igi += 2; - if (value_igi > DM_DIG_FA_UPPER) - value_igi = DM_DIG_FA_UPPER; - else if (value_igi < DM_DIG_FA_LOWER) - value_igi = DM_DIG_FA_LOWER; - if (rtlpriv->falsealm_cnt.cnt_all > 10000) - value_igi = 0x32; - - dm_digtable.cur_igvalue = value_igi; - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { - if ((dm_digtable.backoff_val - 2) < - dm_digtable.backoff_val_range_min) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_min; - else - dm_digtable.backoff_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { - if ((dm_digtable.backoff_val + 2) > - dm_digtable.backoff_val_range_max) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_max; - else - dm_digtable.backoff_val += 2; - } - - if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > - dm_digtable.rx_gain_range_max) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; - else if ((dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); - - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) -{ - static u8 binitialized; /* initialized to false */ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - bool b_multi_sta = false; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - b_multi_sta = true; - - if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != - DIG_STA_DISCONNECT)) { - binitialized = false; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - return; - } else if (binitialized == false) { - binitialized = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { - if ((rssi_strength < dm_digtable.rssi_lowthresh) && - (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { - - if (dm_digtable.dig_ext_port_stage == - DIG_EXT_PORT_STAGE_2) { - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; - } else if (rssi_strength > dm_digtable.rssi_highthresh) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; - rtl92c_dm_ctrl_initgain_by_fa(hw); - } - } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); -} - -static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); - - if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate - || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT - || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - - if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { - dm_digtable.rssi_val_min = - rtl92c_dm_initial_gain_min_pwdb(hw); - rtl92c_dm_ctrl_initgain_by_rssi(hw); - } - } else { - dm_digtable.rssi_val_min = 0; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0; - rtl92c_dm_write_dig(hw); - } -} - -static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); - - if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (dm_digtable.rssi_val_min <= 25) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } else { - if (dm_digtable.rssi_val_min <= 20) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } - } else { - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; - } - - if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { - if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) - dm_digtable.cur_cck_fa_state = - CCK_FA_STAGE_High; - else - dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; - - if (dm_digtable.pre_cck_fa_state != - dm_digtable.cur_cck_fa_state) { - if (dm_digtable.cur_cck_fa_state == - CCK_FA_STAGE_Low) - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0x83); - else - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0xcd); - - dm_digtable.pre_cck_fa_state = - dm_digtable.cur_cck_fa_state; - } - - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd7); - } else { - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd3); - } - dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); -} - -static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - if (mac->act_scanning == true) - return; - - if ((mac->link_state > MAC80211_NOLINK) && - (mac->link_state < MAC80211_LINKED)) - dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; - else if (mac->link_state >= MAC80211_LINKED) - dm_digtable.cursta_connectctate = DIG_STA_CONNECT; - else - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - - rtl92c_dm_initial_gain_sta(hw); - rtl92c_dm_initial_gain_multi_sta(hw); - rtl92c_dm_cck_packet_detection_thresh(hw); - - dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; - -} - -static void rtl92c_dm_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->dm.b_dm_initialgain_enable == false) - return; - if (dm_digtable.dig_enable_flag == false) - return; - - rtl92c_dm_ctrl_initgain_by_twoport(hw); - -} - -static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.bdynamic_txpower_enable = false; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; -} - -static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undecorated_smoothed_pwdb; - - if (!rtlpriv->dm.bdynamic_txpower_enable) - return; - - if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); - - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if (mac->link_state >= MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undecorated_smoothed_pwdb = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); - } else { - undecorated_smoothed_pwdb = - rtlpriv->dm.undecorated_smoothed_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); - } - } else { - undecorated_smoothed_pwdb = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); - } - - if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); - } else if ((undecorated_smoothed_pwdb < - (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undecorated_smoothed_pwdb >= - TX_POWER_NEAR_FIELD_THRESH_LVL1)) { - - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); - } else if (undecorated_smoothed_pwdb < - (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); - } - - if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); - rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); - } - - rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; -} - -void rtl92c_dm_write_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); - - if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { - rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - - dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; - } -} - -static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; - - u8 h2c_parameter[3] = { 0 }; - - return; - - if (tmpentry_max_pwdb != 0) { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = - tmpentry_max_pwdb; - } else { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; - } - - if (tmpentry_min_pwdb != 0xff) { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = - tmpentry_min_pwdb; - } else { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; - } - - h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); - h2c_parameter[0] = 0; - - rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); -} - -void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.bcurrent_turbo_edca = false; - rtlpriv->dm.bis_any_nonbepkts = false; - rtlpriv->dm.bis_cur_rdlstate = false; -} - -static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - static u64 last_txok_cnt; - static u64 last_rxok_cnt; - u64 cur_txok_cnt; - u64 cur_rxok_cnt; - u32 edca_be_ul = 0x5ea42b; - u32 edca_be_dl = 0x5ea42b; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - goto dm_checkedcaturbo_exit; - - if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.bcurrent_turbo_edca = false; - return; - } - - if (!mac->ht_enable) { /*FIX MERGE */ - if (!(edca_be_ul & 0xffff0000)) - edca_be_ul |= 0x005e0000; - - if (!(edca_be_dl & 0xffff0000)) - edca_be_dl |= 0x005e0000; - } - - if ((!rtlpriv->dm.bis_any_nonbepkts) && - (!rtlpriv->dm.b_disable_framebursting)) { - cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; - cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; - if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_dl); - rtlpriv->dm.bis_cur_rdlstate = true; - } - } else { - if (rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_ul); - rtlpriv->dm.bis_cur_rdlstate = false; - } - } - rtlpriv->dm.bcurrent_turbo_edca = true; - } else { - if (rtlpriv->dm.bcurrent_turbo_edca) { - u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); - rtlpriv->dm.bcurrent_turbo_edca = false; - } - } - -dm_checkedcaturbo_exit: - rtlpriv->dm.bis_any_nonbepkts = false; - last_txok_cnt = rtlpriv->stats.txbytesunicast; - last_rxok_cnt = rtlpriv->stats.rxbytesunicast; -} - -static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw - *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 thermalvalue, delta, delta_lck, delta_iqk; - long ele_a, ele_d, temp_cck, val_x, value32; - long val_y, ele_c; - u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; - int i; - bool is2t = IS_92C_SERIAL(rtlhal->version); - u8 txpwr_level[2] = {0, 0}; - u8 ofdm_min_index = 6, rf; - - rtlpriv->dm.btxpower_trackingInit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); - - thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); - - rtl92c_phy_ap_calibrate(hw, (thermalvalue - - rtlefuse->eeprom_thermalmeter)); - if (is2t) - rf = 2; - else - rf = 1; - - if (thermalvalue) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - ofdm_index_old[0] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", - ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); - break; - } - } - - if (is2t) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - ofdm_index_old[1] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); - break; - } - } - } - - temp_cck = - rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; - - for (i = 0; i < CCK_TABLE_LENGTH; i++) { - if (rtlpriv->dm.b_cck_inch14) { - if (memcmp((void *)&temp_cck, - (void *)&cckswing_table_ch14[i][2], - 4) == 0) { - cck_index_old = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } else { - if (memcmp((void *)&temp_cck, - (void *) - &cckswing_table_ch1ch13[i][2], - 4) == 0) { - cck_index_old = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } - } - - if (!rtlpriv->dm.thermalvalue) { - rtlpriv->dm.thermalvalue = - rtlefuse->eeprom_thermalmeter; - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; - rtlpriv->dm.cck_index = cck_index_old; - } - - delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? - (thermalvalue - rtlpriv->dm.thermalvalue) : - (rtlpriv->dm.thermalvalue - thermalvalue); - - delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? - (thermalvalue - rtlpriv->dm.thermalvalue_lck) : - (rtlpriv->dm.thermalvalue_lck - thermalvalue); - - delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? - (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : - (rtlpriv->dm.thermalvalue_iqk - thermalvalue); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); - - if (delta_lck > 1) { - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtl92c_phy_lc_calibrate(hw); - } - - if (delta > 0 && rtlpriv->dm.txpower_track_control) { - if (thermalvalue > rtlpriv->dm.thermalvalue) { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] -= delta; - rtlpriv->dm.cck_index -= delta; - } else { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] += delta; - rtlpriv->dm.cck_index += delta; - } - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); - } - - if (thermalvalue > rtlefuse->eeprom_thermalmeter) { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i] - + 1; - cck_index = rtlpriv->dm.cck_index + 1; - } else { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i]; - cck_index = rtlpriv->dm.cck_index; - } - - for (i = 0; i < rf; i++) { - if (txpwr_level[i] >= 0 && - txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse-> - eeprom_thermalmeter) { - ofdm_index[i] += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 - && thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > - rtlefuse->eeprom_thermalmeter - && delta > 5) { - ofdm_index[i] -= 1; - } - } - - if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse->eeprom_thermalmeter) { - cck_index += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 && - thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > rtlefuse->eeprom_thermalmeter - && delta > 5) { - cck_index -= 1; - } - - for (i = 0; i < rf; i++) { - if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) - ofdm_index[i] = OFDM_TABLE_SIZE - 1; - - else if (ofdm_index[i] < ofdm_min_index) - ofdm_index[i] = ofdm_min_index; - } - - if (cck_index > CCK_TABLE_SIZE - 1) - cck_index = CCK_TABLE_SIZE - 1; - else if (cck_index < 0) - cck_index = 0; - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); - } - } - - if (rtlpriv->dm.txpower_track_control && delta != 0) { - ele_d = - (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; - val_x = rtlphy->reg_e94; - val_y = rtlphy->reg_e9c; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(29), value32); - } else { - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index[0]]); - - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31) | BIT(29), 0x00); - } - - if (!rtlpriv->dm.b_cck_inch14) { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch1ch13[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch1ch13[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch1ch13[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch1ch13[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch1ch13[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch1ch13[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch1ch13[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch1ch13[cck_index] - [7]); - } else { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch14[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch14[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch14[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch14[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch14[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch14[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch14[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch14[cck_index] - [7]); - } - - if (is2t) { - ele_d = (ofdmswing_table[ofdm_index[1]] & - 0xFFC00000) >> 22; - - val_x = rtlphy->reg_eb4; - val_y = rtlphy->reg_ebc; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & - 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & - 0x00003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(25), value32); - } else { - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index - [1]]); - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27) | BIT(25), 0x00); - } - - } - } - - if (delta_iqk > 3) { - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - rtl92c_phy_iq_calibrate(hw, false); - } - - if (rtlpriv->dm.txpower_track_control) - rtlpriv->dm.thermalvalue = thermalvalue; - } - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); - -} - -static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.btxpower_tracking = true; - rtlpriv->dm.btxpower_trackingInit = false; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->btxpower_tracking = %d\n", - rtlpriv->dm.btxpower_tracking)); -} - -static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); -} - -static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) -{ - rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); -} - -static void rtl92c_dm_check_txpower_tracking_thermal_meter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - static u8 tm_trigger; - - if (!rtlpriv->dm.btxpower_tracking) - return; - - if (!tm_trigger) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, - 0x60); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); - tm_trigger = 1; - return; - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); - rtl92c_dm_txpower_tracking_directcall(hw); - tm_trigger = 0; - } -} - -void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_check_txpower_tracking_thermal_meter(hw); -} - -void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - - p_ra->ratr_state = DM_RATR_STA_INIT; - p_ra->pre_ratr_state = DM_RATR_STA_INIT; - - if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.b_useramask = true; - else - rtlpriv->dm.b_useramask = false; - -} - -static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - u32 low_rssithresh_for_ra, high_rssithresh_for_ra; - - if (is_hal_stop(rtlhal)) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); - return; - } - - if (!rtlpriv->dm.b_useramask) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); - return; - } - - if (mac->link_state == MAC80211_LINKED) { - - switch (p_ra->pre_ratr_state) { - case DM_RATR_STA_HIGH: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_MIDDLE: - high_rssithresh_for_ra = 55; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_LOW: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 25; - break; - default: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - } - - if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)high_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_HIGH; - else if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)low_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_MIDDLE; - else - p_ra->ratr_state = DM_RATR_STA_LOW; - - if (p_ra->pre_ratr_state != p_ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); - - rtlpriv->cfg->ops->update_rate_mask(hw, - p_ra->ratr_state); - - p_ra->pre_ratr_state = p_ra->ratr_state; - } - } -} - -static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - dm_pstable.pre_ccastate = CCA_MAX; - dm_pstable.cur_ccasate = CCA_MAX; - dm_pstable.pre_rfstate = RF_MAX; - dm_pstable.cur_rfstate = RF_MAX; - dm_pstable.rssi_val_min = 0; -} - -static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_ccastate == CCA_2R) { - if (dm_pstable.rssi_val_min >= 35) - dm_pstable.cur_ccasate = CCA_1R; - else - dm_pstable.cur_ccasate = CCA_2R; - } else { - if (dm_pstable.rssi_val_min <= 30) - dm_pstable.cur_ccasate = CCA_2R; - else - dm_pstable.cur_ccasate = CCA_1R; - } - } else { - dm_pstable.cur_ccasate = CCA_MAX; - } - - if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { - if (dm_pstable.cur_ccasate == CCA_1R) { - if (get_rf_type(rtlphy) == RF_2T2R) { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x13); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x23); - rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); - } - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, - 0x33); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); - } - dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; - } - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", - (dm_pstable.cur_ccasate == - 0) ? "1RCCA" : "2RCCA")); -} - -void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) -{ - static u8 initialize; - static u32 reg_874, reg_c70, reg_85c, reg_a74; - - if (initialize == 0) { - reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - MASKDWORD) & 0x1CC000) >> 14; - - reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, - MASKDWORD) & BIT(3)) >> 3; - - reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - MASKDWORD) & 0xFF000000) >> 24; - - reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; - - initialize = 1; - } - - if (!bforce_in_normal) { - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_rfstate == RF_NORMAL) { - if (dm_pstable.rssi_val_min >= 30) - dm_pstable.cur_rfstate = RF_SAVE; - else - dm_pstable.cur_rfstate = RF_NORMAL; - } else { - if (dm_pstable.rssi_val_min <= 25) - dm_pstable.cur_rfstate = RF_NORMAL; - else - dm_pstable.cur_rfstate = RF_SAVE; - } - } else { - dm_pstable.cur_rfstate = RF_MAX; - } - } else { - dm_pstable.cur_rfstate = RF_NORMAL; - } - - if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { - if (dm_pstable.cur_rfstate == RF_SAVE) { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1C0000, 0x2); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - 0xFF000000, 0x63); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0xC000, 0x2); - rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); - } else { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1CC000, reg_874); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), - reg_c70); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, - reg_85c); - rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - } - - dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; - } -} - -static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { - dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); - } - - if (mac->link_state == MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.undecorated_smoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - - if (IS_92C_SERIAL(rtlhal->version)) - rtl92c_dm_1r_cca(hw); -} - -void rtl92c_dm_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtl92c_dm_diginit(hw); - rtl92c_dm_init_dynamic_txpower(hw); - rtl92c_dm_init_edca_turbo(hw); - rtl92c_dm_init_rate_adaptive_mask(hw); - rtl92c_dm_initialize_txpower_tracking(hw); - rtl92c_dm_init_dynamic_bb_powersaving(hw); -} - -void rtl92c_dm_watchdog(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_fw_current_inpsmode = false; - bool b_fw_ps_awake = true; - - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&b_fw_ps_awake)); - - if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && - b_fw_ps_awake) - && (!ppsc->rfchange_inprogress)) { - rtl92c_dm_pwdb_monitor(hw); - rtl92c_dm_dig(hw); - rtl92c_dm_false_alarm_counter_statistics(hw); - rtl92c_dm_dynamic_bb_powersaving(hw); - rtl92c_dm_dynamic_txpower(hw); - rtl92c_dm_check_txpower_tracking(hw); - rtl92c_dm_refresh_rate_adaptive_mask(hw); - rtl92c_dm_check_edca_turbo(hw); - } -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h deleted file mode 100644 index 463439e4074c..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_DM_H__ -#define __RTL92C_DM_H__ - -#define HAL_DM_DIG_DISABLE BIT(0) -#define HAL_DM_HIPWR_DISABLE BIT(1) - -#define OFDM_TABLE_LENGTH 37 -#define CCK_TABLE_LENGTH 33 - -#define OFDM_TABLE_SIZE 37 -#define CCK_TABLE_SIZE 33 - -#define BW_AUTO_SWITCH_HIGH_LOW 25 -#define BW_AUTO_SWITCH_LOW_HIGH 30 - -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_FALSEALARM_THRESH_LOW 400 -#define DM_FALSEALARM_THRESH_HIGH 1000 - -#define DM_DIG_MAX 0x3e -#define DM_DIG_MIN 0x1e - -#define DM_DIG_FA_UPPER 0x32 -#define DM_DIG_FA_LOWER 0x20 -#define DM_DIG_FA_TH0 0x20 -#define DM_DIG_FA_TH1 0x100 -#define DM_DIG_FA_TH2 0x200 - -#define DM_DIG_BACKOFF_MAX 12 -#define DM_DIG_BACKOFF_MIN -4 -#define DM_DIG_BACKOFF_DEFAULT 10 - -#define RXPATHSELECTION_SS_TH_lOW 30 -#define RXPATHSELECTION_DIFF_TH 18 - -#define DM_RATR_STA_INIT 0 -#define DM_RATR_STA_HIGH 1 -#define DM_RATR_STA_MIDDLE 2 -#define DM_RATR_STA_LOW 3 - -#define CTS2SELF_THVAL 30 -#define REGC38_TH 20 - -#define WAIOTTHVal 25 - -#define TXHIGHPWRLEVEL_NORMAL 0 -#define TXHIGHPWRLEVEL_LEVEL1 1 -#define TXHIGHPWRLEVEL_LEVEL2 2 -#define TXHIGHPWRLEVEL_BT1 3 -#define TXHIGHPWRLEVEL_BT2 4 - -#define DM_TYPE_BYFW 0 -#define DM_TYPE_BYDRIVER 1 - -#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 -#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 - -struct ps_t { - u8 pre_ccastate; - u8 cur_ccasate; - u8 pre_rfstate; - u8 cur_rfstate; - long rssi_val_min; -}; - -struct dig_t { - u8 dig_enable_flag; - u8 dig_ext_port_stage; - u32 rssi_lowthresh; - u32 rssi_highthresh; - u32 fa_lowthresh; - u32 fa_highthresh; - u8 cursta_connectctate; - u8 presta_connectstate; - u8 curmultista_connectstate; - u8 pre_igvalue; - u8 cur_igvalue; - char backoff_val; - char backoff_val_range_max; - char backoff_val_range_min; - u8 rx_gain_range_max; - u8 rx_gain_range_min; - u8 rssi_val_min; - u8 pre_cck_pd_state; - u8 cur_cck_pd_state; - u8 pre_cck_fa_state; - u8 cur_cck_fa_state; - u8 pre_ccastate; - u8 cur_ccasate; -}; - -struct swat_t { - u8 failure_cnt; - u8 try_flag; - u8 stop_trying; - long pre_rssi; - long trying_threshold; - u8 cur_antenna; - u8 pre_antenna; -}; - -enum tag_dynamic_init_gain_operation_type_definition { - DIG_TYPE_THRESH_HIGH = 0, - DIG_TYPE_THRESH_LOW = 1, - DIG_TYPE_BACKOFF = 2, - DIG_TYPE_RX_GAIN_MIN = 3, - DIG_TYPE_RX_GAIN_MAX = 4, - DIG_TYPE_ENABLE = 5, - DIG_TYPE_DISABLE = 6, - DIG_OP_TYPE_MAX -}; - -enum tag_cck_packet_detection_threshold_type_definition { - CCK_PD_STAGE_LowRssi = 0, - CCK_PD_STAGE_HighRssi = 1, - CCK_FA_STAGE_Low = 2, - CCK_FA_STAGE_High = 3, - CCK_PD_STAGE_MAX = 4, -}; - -enum dm_1r_cca_e { - CCA_1R = 0, - CCA_2R = 1, - CCA_MAX = 2, -}; - -enum dm_rf_e { - RF_SAVE = 0, - RF_NORMAL = 1, - RF_MAX = 2, -}; - -enum dm_sw_ant_switch_e { - ANS_ANTENNA_B = 1, - ANS_ANTENNA_A = 2, - ANS_ANTENNA_MAX = 3, -}; - -enum dm_dig_ext_port_alg_e { - DIG_EXT_PORT_STAGE_0 = 0, - DIG_EXT_PORT_STAGE_1 = 1, - DIG_EXT_PORT_STAGE_2 = 2, - DIG_EXT_PORT_STAGE_3 = 3, - DIG_EXT_PORT_STAGE_MAX = 4, -}; - -enum dm_dig_connect_e { - DIG_STA_DISCONNECT = 0, - DIG_STA_CONNECT = 1, - DIG_STA_BEFORE_CONNECT = 2, - DIG_MULTISTA_DISCONNECT = 3, - DIG_MULTISTA_CONNECT = 4, - DIG_CONNECT_MAX -}; - -extern struct dig_t dm_digtable; -void rtl92c_dm_init(struct ieee80211_hw *hw); -void rtl92c_dm_watchdog(struct ieee80211_hw *hw); -void rtl92c_dm_write_dig(struct ieee80211_hw *hw); -void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); -void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); -void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); -void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c deleted file mode 100644 index 80ee6ff9d2b8..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c +++ /dev/null @@ -1,804 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-fw.h" -#include "rtl8192c-table.h" - -static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { - u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (enable) - value32 |= MCUFWDL_EN; - else - value32 &= ~MCUFWDL_EN; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { - u8 tmp; - if (enable) { - - tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, - tmp | 0x04); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); - rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); - } else { - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); - - rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); - } - } -} - -static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blockSize = sizeof(u32); - u8 *bufferPtr = (u8 *) buffer; - u32 *pu4BytePtr = (u32 *) buffer; - u32 i, offset, blockCount, remainSize; - - blockCount = size / blockSize; - remainSize = size % blockSize; - - for (i = 0; i < blockCount; i++) { - offset = i * blockSize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - - if (remainSize) { - offset = blockCount * blockSize; - bufferPtr += offset; - for (i = 0; i < remainSize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferPtr + i)); - } - } -} - -static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl92c_fw_block_write(hw, buffer, size); -} - -static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - -static void _rtl92c_write_fw(struct ieee80211_hw *hw, - enum version_8192c version, u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - bool is_version_b; - u8 *bufferPtr = (u8 *) buffer; - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); - - is_version_b = IS_CHIP_VER_B(version); - if (is_version_b) { - u32 pageNums, remainSize; - u32 page, offset; - - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) - _rtl92c_fill_dummy(bufferPtr, &size); - - pageNums = size / FW_8192C_PAGE_SIZE; - remainSize = size % FW_8192C_PAGE_SIZE; - - if (pageNums > 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 4\n")); - } - - for (page = 0; page < pageNums; page++) { - offset = page * FW_8192C_PAGE_SIZE; - _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), - FW_8192C_PAGE_SIZE); - } - - if (remainSize) { - offset = pageNums * FW_8192C_PAGE_SIZE; - page = pageNums; - _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), - remainSize); - } - } else { - _rtl92c_fw_block_write(hw, buffer, size); - } -} - -static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int err = -EIO; - u32 counter = 0; - u32 value32; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && - (!(value32 & FWDL_ChkSum_rpt))); - - if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); - goto exit; - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); - - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - - counter = 0; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (value32 & WINTINI_RDY) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Polling FW ready success!!" - " REG_MCUFWDL:0x%08x .\n", - value32)); - err = 0; - goto exit; - } - - mdelay(FW_8192C_POLLING_DELAY); - - } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); - - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); - -exit: - return err; -} - -int rtl92c_download_fw(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl92c_firmware_header *pfwheader; - u8 *pfwdata; - u32 fwsize; - int err; - enum version_8192c version = rtlhal->version; - - const struct firmware *firmware = NULL; - - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); - return 1; - } - - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); - return 1; - } - - memcpy(rtlhal->pfirmware, firmware->data, firmware->size); - fwsize = firmware->size; - release_firmware(firmware); - - pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; - - if (IS_FW_HEADER_EXIST(pfwheader)) { - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x),Size(%d)\n", - pfwheader->version, pfwheader->signature, - (uint)sizeof(struct rtl92c_firmware_header))); - - pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); - fwsize = fwsize - sizeof(struct rtl92c_firmware_header); - } - - _rtl92c_enable_fw_download(hw, true); - _rtl92c_write_fw(hw, version, pfwdata, fwsize); - _rtl92c_enable_fw_download(hw, false); - - err = _rtl92c_fw_free_to_go(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); - } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Firmware is ready to run!\n")); - } - - return 0; -} - -static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 val_hmetfr, val_mcutst_1; - bool result = false; - - val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); - val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); - - if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) - result = true; - return result; -} - -static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 boxnum; - u16 box_reg, box_extreg; - u8 u1b_tmp; - bool isfw_read = false; - u8 buf_index; - bool bwrite_sucess = false; - u8 wait_h2c_limmit = 100; - u8 wait_writeh2c_limmit = 100; - u8 boxcontent[4], boxextcontent[2]; - u32 h2c_waitcounter = 0; - unsigned long flag; - u8 idx; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); - - while (true) { - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - if (rtlhal->b_h2c_setinprogress) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); - - while (rtlhal->b_h2c_setinprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, - flag); - h2c_waitcounter++; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); - udelay(100); - - if (h2c_waitcounter > 1000) - return; - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, - flag); - } - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - } else { - rtlhal->b_h2c_setinprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - break; - } - } - - while (!bwrite_sucess) { - wait_writeh2c_limmit--; - if (wait_writeh2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); - break; - } - - boxnum = rtlhal->last_hmeboxnum; - switch (boxnum) { - case 0: - box_reg = REG_HMEBOX_0; - box_extreg = REG_HMEBOX_EXT_0; - break; - case 1: - box_reg = REG_HMEBOX_1; - box_extreg = REG_HMEBOX_EXT_1; - break; - case 2: - box_reg = REG_HMEBOX_2; - box_extreg = REG_HMEBOX_EXT_2; - break; - case 3: - box_reg = REG_HMEBOX_3; - box_extreg = REG_HMEBOX_EXT_3; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); - while (!isfw_read) { - - wait_h2c_limmit--; - if (wait_h2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); - break; - } - - udelay(10); - - isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); - u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); - } - - if (!isfw_read) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); - break; - } - - memset(boxcontent, 0, sizeof(boxcontent)); - memset(boxextcontent, 0, sizeof(boxextcontent)); - boxcontent[0] = element_id; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); - - switch (cmd_len) { - case 1: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 1); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 2: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 2); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 3: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 3); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 4: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 2); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 5: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 3); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - bwrite_sucess = true; - - rtlhal->last_hmeboxnum = boxnum + 1; - if (rtlhal->last_hmeboxnum == 4) - rtlhal->last_hmeboxnum = 0; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); - } - - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - rtlhal->b_h2c_setinprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); -} - -void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 tmp_cmdbuf[2]; - - if (rtlhal->bfw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); - return; - } - - memset(tmp_cmdbuf, 0, 8); - memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); - _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); - - return; -} - -void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) -{ - u8 u1b_tmp; - u8 delay = 100; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); - u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - - while (u1b_tmp & BIT(2)) { - delay--; - if (delay == 0) { - RT_ASSERT(false, ("8051 reset fail.\n")); - break; - } - udelay(50); - u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - } -} - -void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 u1_h2c_set_pwrmode[3] = {0}; - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); - - SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); - SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); - SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, - ppsc->reg_max_lps_awakeintvl); - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", - u1_h2c_set_pwrmode, 3); - rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); - -} - -static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl8192_tx_ring *ring; - struct rtl_tx_desc *pdesc; - u8 own; - unsigned long flags; - struct sk_buff *pskb = NULL; - - ring = &rtlpci->tx_ring[BEACON_QUEUE]; - - pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); - - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - - pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - - rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - - __skb_queue_tail(&ring->queue, skb); - - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - - rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - - return true; -} - -#define BEACON_PG 0 /*->1*/ -#define PSPOLL_PG 2 -#define NULL_PG 3 -#define PROBERSP_PG 4 /*->5*/ - -#define TOTAL_RESERVED_PKT_LEN 768 - -static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { - /* page 0 beacon */ - 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 1 beacon */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 2 ps-poll */ - 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 3 null */ - 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 4 probe_resp */ - 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 5 probe_resp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct sk_buff *skb = NULL; - - u32 totalpacketlen; - bool rtstatus; - u8 u1RsvdPageLoc[3] = {0}; - bool b_dlok = false; - - u8 *beacon; - u8 *p_pspoll; - u8 *nullfunc; - u8 *p_probersp; - /*--------------------------------------------------------- - (1) beacon - ---------------------------------------------------------*/ - beacon = &reserved_page_packet[BEACON_PG * 128]; - SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); - SET_80211_HDR_ADDRESS3(beacon, mac->bssid); - - /*------------------------------------------------------- - (2) ps-poll - --------------------------------------------------------*/ - p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; - SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); - SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); - SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); - - SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); - - /*-------------------------------------------------------- - (3) null data - ---------------------------------------------------------*/ - nullfunc = &reserved_page_packet[NULL_PG * 128]; - SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); - SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); - SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); - - /*--------------------------------------------------------- - (4) probe response - ----------------------------------------------------------*/ - p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; - SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); - SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); - SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); - - totalpacketlen = TOTAL_RESERVED_PKT_LEN; - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - &reserved_page_packet[0], totalpacketlen); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - u1RsvdPageLoc, 3); - - - skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), - &reserved_page_packet, totalpacketlen); - - rtstatus = _rtl92c_cmd_send_packet(hw, skb); - - if (rtstatus) - b_dlok = true; - - if (b_dlok) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); - rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, - sizeof(u1RsvdPageLoc), u1RsvdPageLoc); - } else - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); -} - -void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) -{ - u8 u1_joinbssrpt_parm[1] = {0}; - - SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); - - rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h deleted file mode 100644 index 3db33bd14666..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C__FW__H__ -#define __RTL92C__FW__H__ - -#define FW_8192C_SIZE 0x3000 -#define FW_8192C_START_ADDRESS 0x1000 -#define FW_8192C_END_ADDRESS 0x3FFF -#define FW_8192C_PAGE_SIZE 4096 -#define FW_8192C_POLLING_DELAY 5 -#define FW_8192C_POLLING_TIMEOUT_COUNT 100 - -#define IS_FW_HEADER_EXIST(_pfwhdr) \ - ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ - (_pfwhdr->signature&0xFFF0) == 0x88C0) - -struct rtl92c_firmware_header { - u16 signature; - u8 category; - u8 function; - u16 version; - u8 subversion; - u8 rsvd1; - u8 month; - u8 date; - u8 hour; - u8 minute; - u16 ramcodeSize; - u16 rsvd2; - u32 svnindex; - u32 rsvd3; - u32 rsvd4; - u32 rsvd5; -}; - -enum rtl8192c_h2c_cmd { - H2C_AP_OFFLOAD = 0, - H2C_SETPWRMODE = 1, - H2C_JOINBSSRPT = 2, - H2C_RSVDPAGE = 3, - H2C_RSSI_REPORT = 5, - H2C_RA_MASK = 6, - MAX_H2CCMD -}; - -#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) - -#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) -#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) - -int rtl92c_download_fw(struct ieee80211_hw *hw); -void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, - u32 cmd_len, u8 *p_cmdbuffer); -void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); -void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); -void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c deleted file mode 100644 index c649f6555752..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c +++ /dev/null @@ -1,2173 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../efuse.h" -#include "../base.h" -#include "../cam.h" -#include "../ps.h" -#include "../pci.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-dm.h" -#include "rtl8192c-fw.h" -#include "rtl8192c-led.h" -#include "rtl8192c-hw.h" - -#define LLT_CONFIG 5 - -static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw, - u8 set_bits, u8 clear_bits) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpci->reg_bcn_ctrl_val |= set_bits; - rtlpci->reg_bcn_ctrl_val &= ~clear_bits; - - rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); -} - -static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte &= ~(BIT(0)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte |= BIT(0); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw) -{ - _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1)); -} - -static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw) -{ - _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0); -} - -void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - switch (variable) { - case HW_VAR_RCR: - *((u32 *) (val)) = rtlpci->receive_config; - break; - case HW_VAR_RF_STATE: - *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; - break; - case HW_VAR_FWLPS_RF_ON:{ - enum rf_pwrstate rfState; - u32 val_rcr; - - rtlpriv->cfg->ops->get_hw_reg(hw, - HW_VAR_RF_STATE, - (u8 *) (&rfState)); - if (rfState == ERFOFF) { - *((bool *) (val)) = true; - } else { - val_rcr = rtl_read_dword(rtlpriv, REG_RCR); - val_rcr &= 0x00070000; - if (val_rcr) - *((bool *) (val)) = false; - else - *((bool *) (val)) = true; - } - break; - } - case HW_VAR_FW_PSMODE_STATUS: - *((bool *) (val)) = ppsc->b_fw_current_inpsmode; - break; - case HW_VAR_CORRECT_TSF:{ - u64 tsf; - u32 *ptsf_low = (u32 *)&tsf; - u32 *ptsf_high = ((u32 *)&tsf) + 1; - - *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); - *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); - - *((u64 *) (val)) = tsf; - - break; - } - case HW_VAR_MGT_FILTER: - *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); - break; - case HW_VAR_CTRL_FILTER: - *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); - break; - case HW_VAR_DATA_FILTER: - *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } -} - -void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - u8 idx; - - switch (variable) { - case HW_VAR_ETHER_ADDR:{ - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_MACID + idx), - val[idx]); - } - break; - } - case HW_VAR_BASIC_RATE:{ - u16 b_rate_cfg = ((u16 *) val)[0]; - u8 rate_index = 0; - b_rate_cfg = b_rate_cfg & 0x15f; - b_rate_cfg |= 0x01; - rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); - rtl_write_byte(rtlpriv, REG_RRSR + 1, - (b_rate_cfg >> 8)&0xff); - while (b_rate_cfg > 0x1) { - b_rate_cfg = (b_rate_cfg >> 1); - rate_index++; - } - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, - rate_index); - break; - } - case HW_VAR_BSSID:{ - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_BSSID + idx), - val[idx]); - } - break; - } - case HW_VAR_SIFS:{ - rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); - rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); - - rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); - rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); - - if (!mac->ht_enable) - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - 0x0e0e); - else - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - *((u16 *) val)); - break; - } - case HW_VAR_SLOT_TIME:{ - u8 e_aci; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); - - rtl_write_byte(rtlpriv, REG_SLOT, val[0]); - - for (e_aci = 0; e_aci < AC_MAX; e_aci++) { - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&e_aci)); - } - break; - } - case HW_VAR_ACK_PREAMBLE:{ - u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); - reg_tmp = (mac->cur_40_prime_sc) << 5; - if (short_preamble) - reg_tmp |= 0x80; - - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); - break; - } - case HW_VAR_AMPDU_MIN_SPACE:{ - u8 min_spacing_to_set; - u8 sec_min_space; - - min_spacing_to_set = *((u8 *) val); - if (min_spacing_to_set <= 7) { - sec_min_space = 0; - - if (min_spacing_to_set < sec_min_space) - min_spacing_to_set = sec_min_space; - - mac->min_space_cfg = ((mac->min_space_cfg & - 0xf8) | - min_spacing_to_set); - - *val = min_spacing_to_set; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - } - break; - } - case HW_VAR_SHORTGI_DENSITY:{ - u8 density_to_set; - - density_to_set = *((u8 *) val); - mac->min_space_cfg |= (density_to_set << 3); - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - - break; - } - case HW_VAR_AMPDU_FACTOR:{ - u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; - - u8 factor_toset; - u8 *p_regtoset = NULL; - u8 index = 0; - - p_regtoset = regtoset_normal; - - factor_toset = *((u8 *) val); - if (factor_toset <= 3) { - factor_toset = (1 << (factor_toset + 2)); - if (factor_toset > 0xf) - factor_toset = 0xf; - - for (index = 0; index < 4; index++) { - if ((p_regtoset[index] & 0xf0) > - (factor_toset << 4)) - p_regtoset[index] = - (p_regtoset[index] & 0x0f) | - (factor_toset << 4); - - if ((p_regtoset[index] & 0x0f) > - factor_toset) - p_regtoset[index] = - (p_regtoset[index] & 0xf0) | - (factor_toset); - - rtl_write_byte(rtlpriv, - (REG_AGGLEN_LMT + index), - p_regtoset[index]); - - } - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); - } - break; - } - case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); - u32 u4b_ac_param = 0; - - u4b_ac_param |= (u32) mac->ac[e_aci].aifs; - u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min - & 0xF) << AC_PARAM_ECW_MIN_OFFSET; - u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max & - 0xF) << AC_PARAM_ECW_MAX_OFFSET; - u4b_ac_param |= (u32) mac->ac[e_aci].tx_op - << AC_PARAM_TXOP_LIMIT_OFFSET; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("queue:%x, ac_param:%x\n", e_aci, - u4b_ac_param)); - - switch (e_aci) { - case AC1_BK: - rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, - u4b_ac_param); - break; - case AC0_BE: - rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, - u4b_ac_param); - break; - case AC2_VI: - rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, - u4b_ac_param); - break; - case AC3_VO: - rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, - u4b_ac_param); - break; - default: - RT_ASSERT(false, - ("SetHwReg8185(): invalid aci: %d !\n", - e_aci)); - break; - } - - if (rtlpci->acm_method != eAcmWay2_SW) - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_ACM_CTRL, - (u8 *) (&e_aci)); - break; - } - case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); - union aci_aifsn *p_aci_aifsn = - (union aci_aifsn *)(&(mac->ac[0].aifs)); - u8 acm = p_aci_aifsn->f.acm; - u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); - - acm_ctrl = - acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); - - if (acm) { - switch (e_aci) { - case AC0_BE: - acm_ctrl |= AcmHw_BeqEn; - break; - case AC2_VI: - acm_ctrl |= AcmHw_ViqEn; - break; - case AC3_VO: - acm_ctrl |= AcmHw_VoqEn; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); - break; - } - } else { - switch (e_aci) { - case AC0_BE: - acm_ctrl &= (~AcmHw_BeqEn); - break; - case AC2_VI: - acm_ctrl &= (~AcmHw_ViqEn); - break; - case AC3_VO: - acm_ctrl &= (~AcmHw_BeqEn); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - } - - RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); - rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); - break; - } - case HW_VAR_RCR:{ - rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); - rtlpci->receive_config = ((u32 *) (val))[0]; - break; - } - case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; - - rtl_write_word(rtlpriv, REG_RL, - retry_limit << RETRY_LIMIT_SHORT_SHIFT | - retry_limit << RETRY_LIMIT_LONG_SHIFT); - break; - } - case HW_VAR_DUAL_TSF_RST: - rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); - break; - case HW_VAR_EFUSE_BYTES: - rtlefuse->efuse_usedbytes = *((u16 *) val); - break; - case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); - break; - case HW_VAR_IO_CMD: - rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); - break; - case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); - break; - case HW_VAR_SET_RPWM:{ - u8 rpwm_val; - - rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); - udelay(1); - - if (rpwm_val & BIT(7)) { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - (*(u8 *) val)); - } else { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - ((*(u8 *) val) | BIT(7))); - } - - break; - } - case HW_VAR_H2C_FW_PWRMODE:{ - u8 psmode = (*(u8 *) val); - - if ((psmode != FW_PS_ACTIVE_MODE) && - (!IS_92C_SERIAL(rtlhal->version))) { - rtl92c_dm_rf_saving(hw, true); - } - - rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); - break; - } - case HW_VAR_FW_PSMODE_STATUS: - ppsc->b_fw_current_inpsmode = *((bool *) val); - break; - case HW_VAR_H2C_FW_JOINBSSRPT:{ - u8 mstatus = (*(u8 *) val); - u8 tmp_regcr, tmp_reg422; - bool b_recover = false; - - if (mstatus == RT_MEDIA_CONNECT) { - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, - NULL); - - tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr | BIT(0))); - - _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); - _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); - - tmp_reg422 = - rtl_read_byte(rtlpriv, - REG_FWHW_TXQ_CTRL + 2); - if (tmp_reg422 & BIT(6)) - b_recover = true; - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, - tmp_reg422 & (~BIT(6))); - - rtl92c_set_fw_rsvdpagepkt(hw, 0); - - _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); - _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); - - if (b_recover) { - rtl_write_byte(rtlpriv, - REG_FWHW_TXQ_CTRL + 2, - tmp_reg422); - } - - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr & ~(BIT(0)))); - } - rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); - - break; - } - case HW_VAR_AID:{ - u16 u2btmp; - u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); - u2btmp &= 0xC000; - rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | - mac->assoc_id)); - - break; - } - case HW_VAR_CORRECT_TSF:{ - u8 btype_ibss = ((u8 *) (val))[0]; - - /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? - 1 : 0;*/ - - if (btype_ibss == true) - _rtl92ce_stop_tx_beacon(hw); - - _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); - - rtl_write_dword(rtlpriv, REG_TSFTR, - (u32) (mac->tsf & 0xffffffff)); - rtl_write_dword(rtlpriv, REG_TSFTR + 4, - (u32) ((mac->tsf >> 32)&0xffffffff)); - - _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); - - if (btype_ibss == true) - _rtl92ce_resume_tx_beacon(hw); - - break; - - } - case HW_VAR_MGT_FILTER: - rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val); - break; - case HW_VAR_CTRL_FILTER: - rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val); - break; - case HW_VAR_DATA_FILTER: - rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); - break; - } -} - -static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - bool status = true; - long count = 0; - u32 value = _LLT_INIT_ADDR(address) | - _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); - - rtl_write_dword(rtlpriv, REG_LLT_INIT, value); - - do { - value = rtl_read_dword(rtlpriv, REG_LLT_INIT); - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) - break; - - if (count > POLLING_LLT_THRESHOLD) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); - status = false; - break; - } - } while (++count); - - return status; -} - -static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - unsigned short i; - u8 txpktbuf_bndy; - u8 maxPage; - bool status; - -#if LLT_CONFIG == 1 - maxPage = 255; - txpktbuf_bndy = 252; -#elif LLT_CONFIG == 2 - maxPage = 127; - txpktbuf_bndy = 124; -#elif LLT_CONFIG == 3 - maxPage = 255; - txpktbuf_bndy = 174; -#elif LLT_CONFIG == 4 - maxPage = 255; - txpktbuf_bndy = 246; -#elif LLT_CONFIG == 5 - maxPage = 255; - txpktbuf_bndy = 246; -#endif - -#if LLT_CONFIG == 1 - rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c); - rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c); -#elif LLT_CONFIG == 2 - rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010); -#elif LLT_CONFIG == 3 - rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484); -#elif LLT_CONFIG == 4 - rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c); -#elif LLT_CONFIG == 5 - rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); - - rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29); -#endif - - rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); - rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_PBP, 0x11); - rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); - - for (i = 0; i < (txpktbuf_bndy - 1); i++) { - status = _rtl92ce_llt_write(hw, i, i + 1); - if (true != status) - return status; - } - - status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); - if (true != status) - return status; - - for (i = txpktbuf_bndy; i < maxPage; i++) { - status = _rtl92ce_llt_write(hw, i, (i + 1)); - if (true != status) - return status; - } - - status = _rtl92ce_llt_write(hw, maxPage, txpktbuf_bndy); - if (true != status) - return status; - - return true; -} - -static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - - if (rtlpci->up_first_time) - return; - - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) - rtl92ce_sw_led_on(hw, pLed0); - else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) - rtl92ce_sw_led_on(hw, pLed0); - else - rtl92ce_sw_led_off(hw, pLed0); - -} - -static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - unsigned char bytetmp; - unsigned short wordtmp; - u16 retry; - - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); - - bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); - udelay(2); - - rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); - udelay(2); - - bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); - udelay(2); - - retry = 0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, 0xEC), - bytetmp)); - - while ((bytetmp & BIT(0)) && retry < 1000) { - retry++; - udelay(50); - bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, - 0xEC), - bytetmp)); - udelay(50); - } - - rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); - - rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); - udelay(2); - - rtl_write_word(rtlpriv, REG_CR, 0x2ff); - - if (_rtl92ce_llt_table_init(hw) == false) - return false;; - - rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); - rtl_write_byte(rtlpriv, REG_HISRE, 0xff); - - rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); - - wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); - wordtmp &= 0xf; - wordtmp |= 0xF771; - rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); - - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); - - rtl_write_byte(rtlpriv, 0x4d0, 0x0); - - rtl_write_dword(rtlpriv, REG_BCNQ_DESA, - ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_MGQ_DESA, - (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VOQ_DESA, - (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VIQ_DESA, - (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BEQ_DESA, - (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BKQ_DESA, - (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_HQ_DESA, - (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_RX_DESA, - (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & - DMA_BIT_MASK(32)); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77); - else - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22); - - rtl_write_dword(rtlpriv, REG_INT_MIG, 0); - - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); - do { - retry++; - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - } while ((retry < 200) && (bytetmp & BIT(7))); - - _rtl92ce_gen_refresh_led_state(hw); - - rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); - - return true;; -} - -static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; - - reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); - - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - - rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); - - rtl_write_byte(rtlpriv, REG_SLOT, 0x09); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); - - rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); - - rtl_write_word(rtlpriv, REG_RL, 0x0707); - - rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); - - rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); - - rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); - rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); - - rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); - - rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); - - rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); - - rtlpci->reg_bcn_ctrl_val = 0x1f; - rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); - rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); - - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - - rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); - - rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); - - rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); - rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); - - rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); - rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); - -} - -static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - rtl_write_byte(rtlpriv, 0x34b, 0x93); - rtl_write_word(rtlpriv, 0x350, 0x870c); - rtl_write_byte(rtlpriv, 0x352, 0x1); - - if (ppsc->b_support_backdoor) - rtl_write_byte(rtlpriv, 0x349, 0x1b); - else - rtl_write_byte(rtlpriv, 0x349, 0x03); - - rtl_write_word(rtlpriv, 0x350, 0x2718); - rtl_write_byte(rtlpriv, 0x352, 0x1); -} - -void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 sec_reg_value; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); - - if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " - "hw encryption\n")); - return; - } - - sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; - - if (rtlpriv->sec.use_defaultkey) { - sec_reg_value |= SCR_TxUseDK; - sec_reg_value |= SCR_RxUseDK; - } - - sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); - - rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); - -} - -int rtl92ce_hw_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - static bool iqk_initialized; /* initialized to false */ - bool rtstatus = true; - bool is92c; - int err; - u8 tmp_u1b; - - rtlpci->being_init_adapter = true; - rtlpriv->intf_ops->disable_aspm(hw); - rtstatus = _rtl92ce_init_mac(hw); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); - err = 1; - return err; - } - - err = rtl92c_download_fw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW now..\n")); - err = 1; - rtlhal->bfw_ready = false; - return err; - } else { - rtlhal->bfw_ready = true; - } - - rtlhal->last_hmeboxnum = 0; - rtl92c_phy_mac_config(hw); - rtl92c_phy_bb_config(hw); - rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; - rtl92c_phy_rf_config(hw); - rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - _rtl92ce_hw_configure(hw); - rtl_cam_reset_all_entry(hw); - rtl92ce_enable_hw_security_config(hw); - ppsc->rfpwr_state = ERFON; - tmp_u1b = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&(~BIT(3)); - rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, tmp_u1b); - tmp_u1b = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); - ppsc->rfoff_reason |= (tmp_u1b & BIT(3)) ? 0 : RF_CHANGE_BY_HW; - if (ppsc->rfoff_reason > RF_CHANGE_BY_PS) - rtl_ps_set_rf_state(hw, ERFOFF, ppsc->rfoff_reason, true); - else { - ppsc->rfpwr_state = ERFON; - ppsc->rfoff_reason = 0; - rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); - } - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); - _rtl92ce_enable_aspm_back_door(hw); - rtlpriv->intf_ops->enable_aspm(hw); - if (ppsc->rfpwr_state == ERFON) { - rtl92c_phy_set_rfpath_switch(hw, 1); - if (iqk_initialized) - rtl92c_phy_iq_calibrate(hw, true); - else { - rtl92c_phy_iq_calibrate(hw, false); - iqk_initialized = true; - } - - rtl92c_dm_check_txpower_tracking(hw); - rtl92c_phy_lc_calibrate(hw); - } - - is92c = IS_92C_SERIAL(rtlhal->version); - tmp_u1b = efuse_read_1byte(hw, 0x1FA); - if (!(tmp_u1b & BIT(0))) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); - } - - if (!(tmp_u1b & BIT(1)) && is92c) { - rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); - } - - if (!(tmp_u1b & BIT(4))) { - tmp_u1b = rtl_read_byte(rtlpriv, 0x16); - tmp_u1b &= 0x0F; - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); - udelay(10); - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); - } - rtl92c_dm_init(hw); - rtlpci->being_init_adapter = false; - return err; -} - -static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - enum version_8192c version = VERSION_UNKNOWN; - u32 value32; - - value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); - if (value32 & TRP_VAUX_EN) { - version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : - VERSION_A_CHIP_88C; - } else { - version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C : - VERSION_B_CHIP_88C; - } - - switch (version) { - case VERSION_B_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); - break; - case VERSION_B_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_88C.\n")); - break; - case VERSION_A_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_92C.\n")); - break; - case VERSION_A_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_88C.\n")); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Chip Version ID: Unknown. Bug?\n")); - break; - } - - switch (version & 0x3) { - case CHIP_88C: - rtlphy->rf_type = RF_1T1R; - break; - case CHIP_92C: - rtlphy->rf_type = RF_2T2R; - break; - case CHIP_92C_1T2R: - rtlphy->rf_type = RF_1T2R; - break; - default: - rtlphy->rf_type = RF_1T1R; - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("ERROR RF_Type is set!!")); - break; - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); - - return version; -} - -static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 bt_msr = rtl_read_byte(rtlpriv, MSR); - enum led_ctl_mode ledaction = LED_CTL_NO_LINK; - bt_msr &= 0xfc; - - if (type == NL80211_IFTYPE_UNSPECIFIED || - type == NL80211_IFTYPE_STATION) { - _rtl92ce_stop_tx_beacon(hw); - _rtl92ce_enable_bcn_sub_func(hw); - } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { - _rtl92ce_resume_tx_beacon(hw); - _rtl92ce_disable_bcn_sub_func(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: " - "No such media status(%x).\n", type)); - } - - switch (type) { - case NL80211_IFTYPE_UNSPECIFIED: - bt_msr |= MSR_NOLINK; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); - break; - case NL80211_IFTYPE_ADHOC: - bt_msr |= MSR_ADHOC; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); - break; - case NL80211_IFTYPE_STATION: - bt_msr |= MSR_INFRA; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); - break; - case NL80211_IFTYPE_AP: - bt_msr |= MSR_AP; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); - return 1; - break; - - } - - rtl_write_byte(rtlpriv, (MSR), bt_msr); - rtlpriv->cfg->ops->led_control(hw, ledaction); - if ((bt_msr & 0xfc) == MSR_AP) - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); - else - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); - return 0; -} - -static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); - u8 filterout_non_associated_bssid = false; - - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: - filterout_non_associated_bssid = true; - break; - case NL80211_IFTYPE_UNSPECIFIED: - case NL80211_IFTYPE_AP: - default: - break; - } - - if (filterout_non_associated_bssid == true) { - reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *) (®_rcr)); - _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (filterout_non_associated_bssid == false) { - reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); - _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *) (®_rcr)); - } -} - -int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) -{ - if (_rtl92ce_set_media_status(hw, type)) - return -EOPNOTSUPP; - _rtl92ce_set_check_bssid(hw, type); - return 0; -} - -void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - u32 u4b_ac_param; - - rtl92c_dm_init_edca_turbo(hw); - - u4b_ac_param = (u32) mac->ac[aci].aifs; - u4b_ac_param |= - ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; - u4b_ac_param |= - ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; - u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET; - RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, - ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", - aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min, - mac->ac[aci].cw_max, mac->ac[aci].tx_op)); - switch (aci) { - case AC1_BK: - rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); - break; - case AC0_BE: - rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); - break; - case AC2_VI: - rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); - break; - case AC3_VO: - rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); - break; - default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); - break; - } -} - -void rtl92ce_enable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); - rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; -} - -void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); - rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - rtlpci->irq_enabled = false; -} - -static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 u1b_tmp; - - rtlpriv->intf_ops->enable_aspm(hw); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready) - rtl92c_firmware_selfreset(hw); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); - rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); - rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); - u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); - rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | - (u1b_tmp << 8)); - rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); - rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); - rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); -} - -void rtl92ce_card_disable(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - enum nl80211_iftype opmode; - - mac->link_state = MAC80211_NOLINK; - opmode = NL80211_IFTYPE_UNSPECIFIED; - _rtl92ce_set_media_status(hw, opmode); - if (rtlpci->driver_is_goingto_unload || - ppsc->rfoff_reason > RF_CHANGE_BY_PS) - rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - _rtl92ce_poweroff_adapter(hw); -} - -void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); - - /* - * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); - */ -} - -void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw) -{ - - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval, atim_window; - - bcn_interval = mac->beacon_interval; - atim_window = 2; /*FIX MERGE */ - rtl92ce_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); - rtl_write_byte(rtlpriv, 0x606, 0x30); - rtl92ce_enable_interrupt(hw); -} - -void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval = mac->beacon_interval; - - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); - rtl92ce_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl92ce_enable_interrupt(hw); -} - -void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); - if (add_msr) - rtlpci->irq_mask[0] |= add_msr; - if (rm_msr) - rtlpci->irq_mask[0] &= (~rm_msr); - rtl92ce_disable_interrupt(hw); - rtl92ce_enable_interrupt(hw); -} - -static u8 _rtl92c_get_chnl_group(u8 chnl) -{ - u8 group; - - if (chnl < 3) - group = 0; - else if (chnl < 9) - group = 1; - else - group = 2; - return group; -} - -static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, - bool autoload_fail, - u8 *hwinfo) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 rf_path, index, tempval; - u16 i; - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i] = - hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = - hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + - i]; - } else { - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - } - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; - else - tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = - (tempval & 0xf); - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = - ((tempval & 0xf0) >> 4); - } - - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl92c_get_chnl_group((u8) i); - - rtlefuse->txpwrlevel_cck[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; - rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; - - if ((rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) - > 0) { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path] - [index] - - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [index]; - } else { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; - } - } - - for (i = 0; i < 14; i++) { - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse->eeprom_pwrlimit_ht40[i] = - hwinfo[EEPROM_TXPWR_GROUP + i]; - rtlefuse->eeprom_pwrlimit_ht20[i] = - hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; - } else { - rtlefuse->eeprom_pwrlimit_ht40[i] = 0; - rtlefuse->eeprom_pwrlimit_ht20[i] = 0; - } - } - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl92c_get_chnl_group((u8) i); - - if (rf_path == RF90_PATH_A) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht20[index] - & 0xf); - rtlefuse->pwrgroup_ht40[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht40[index] - & 0xf); - } else if (rf_path == RF90_PATH_B) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht20[index] - & 0xf0) >> 4); - rtlefuse->pwrgroup_ht40[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht40[index] - & 0xf0) >> 4); - } - - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); - } - } - - for (i = 0; i < 14; i++) { - index = _rtl92c_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; - else - tempval = EEPROM_DEFAULT_HT20_DIFF; - - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; - - index = _rtl92c_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; - else - tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; - - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - } - - rtlefuse->legacy_ht_txpowerdiff = - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; - - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); - - if (!autoload_fail) - rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); - else - rtlefuse->eeprom_regulatory = 0; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); - - if (!autoload_fail) { - rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; - rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; - } else { - rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; - rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; - } - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_THERMAL_METER]; - else - tempval = EEPROM_DEFAULT_THERMALMETER; - rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); - - if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) - rtlefuse->b_apk_thermalmeterignore = true; - - rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); -} - -static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u16 i, usvalue; - u8 hwinfo[HWSET_MAX_SIZE]; - u16 eeprom_id; - - if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { - rtl_efuse_shadow_map_update(hw); - - memcpy((void *)hwinfo, - (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], - HWSET_MAX_SIZE); - } else if (rtlefuse->epromtype == EEPROM_93C46) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); - } - - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), - hwinfo, HWSET_MAX_SIZE); - - eeprom_id = *((u16 *)&hwinfo[0]); - if (eeprom_id != RTL8190_EEPROM_ID) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); - rtlefuse->autoload_failflag = true; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); - rtlefuse->autoload_failflag = false; - } - - if (rtlefuse->autoload_failflag == true) - return; - - for (i = 0; i < 6; i += 2) { - usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; - *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr))); - - _rtl92ce_read_txpower_info_from_hwpg(hw, - rtlefuse->autoload_failflag, - hwinfo); - - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; - rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; - rtlefuse->b_txpwr_fromeprom = true; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); - - if (rtlhal->oem_id == RT_CID_DEFAULT) { - switch (rtlefuse->eeprom_oemid) { - case EEPROM_CID_DEFAULT: - if (rtlefuse->eeprom_did == 0x8176) { - if ((rtlefuse->eeprom_svid == 0x103C && - rtlefuse->eeprom_smid == 0x1629)) - rtlhal->oem_id = RT_CID_819x_HP; - else - rtlhal->oem_id = RT_CID_DEFAULT; - } else { - rtlhal->oem_id = RT_CID_DEFAULT; - } - break; - case EEPROM_CID_TOSHIBA: - rtlhal->oem_id = RT_CID_TOSHIBA; - break; - case EEPROM_CID_QMI: - rtlhal->oem_id = RT_CID_819x_QMI; - break; - case EEPROM_CID_WHQL: - default: - rtlhal->oem_id = RT_CID_DEFAULT; - break; - - } - } - -} - -static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - switch (rtlhal->oem_id) { - case RT_CID_819x_HP: - pcipriv->ledctl.bled_opendrain = true; - break; - case RT_CID_819x_Lenovo: - case RT_CID_DEFAULT: - case RT_CID_TOSHIBA: - case RT_CID_CCX: - case RT_CID_819x_Acer: - case RT_CID_WHQL: - default: - break; - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); -} - -void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_u1b; - - rtlhal->version = _rtl92ce_read_chip_version(hw); - if (get_rf_type(rtlphy) == RF_1T1R) - rtlpriv->dm.brfpath_rxenable[0] = true; - else - rtlpriv->dm.brfpath_rxenable[0] = - rtlpriv->dm.brfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); - tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); - if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); - rtlefuse->epromtype = EEPROM_93C46; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); - rtlefuse->epromtype = EEPROM_BOOT_EFUSE; - } - if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); - rtlefuse->autoload_failflag = false; - _rtl92ce_read_adapter_info(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); - } - - _rtl92ce_hal_customized_behavior(hw); -} - -void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - u32 ratr_value = (u32) mac->basic_rates; - u8 *p_mcsrate = mac->mcs; - u8 ratr_index = 0; - u8 b_nmode = mac->ht_enable; - u8 mimo_ps = 1; - u16 shortgi_rate; - u32 tmp_ratr_value; - u8 b_curtxbw_40mhz = mac->bw_40; - u8 b_curshortgi_40mhz = mac->sgi_40; - u8 b_curshortgi_20mhz = mac->sgi_20; - enum wireless_mode wirelessmode = mac->mode; - - ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - if (ratr_value & 0x0000000c) - ratr_value &= 0x0000000d; - else - ratr_value &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_value &= 0x00000FF5; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - b_nmode = 1; - if (mimo_ps == 0) { - ratr_value &= 0x0007F005; - } else { - u32 ratr_mask; - - if (get_rf_type(rtlphy) == RF_1T2R || - get_rf_type(rtlphy) == RF_1T1R) - ratr_mask = 0x000ff005; - else - ratr_mask = 0x0f0ff005; - - ratr_value &= ratr_mask; - } - break; - default: - if (rtlphy->rf_type == RF_1T2R) - ratr_value &= 0x000ff0ff; - else - ratr_value &= 0x0f0ff0ff; - - break; - } - - ratr_value &= 0x0FFFFFFF; - - if (b_nmode && ((b_curtxbw_40mhz && - b_curshortgi_40mhz) || (!b_curtxbw_40mhz && - b_curshortgi_20mhz))) { - - ratr_value |= 0x10000000; - tmp_ratr_value = (ratr_value >> 12); - - for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { - if ((1 << shortgi_rate) & tmp_ratr_value) - break; - } - - shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | - (shortgi_rate << 4) | (shortgi_rate); - } - - rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); -} - -void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u32 ratr_bitmap = (u32) mac->basic_rates; - u8 *p_mcsrate = mac->mcs; - u8 ratr_index; - u8 b_curtxbw_40mhz = mac->bw_40; - u8 b_curshortgi_40mhz = mac->sgi_40; - u8 b_curshortgi_20mhz = mac->sgi_20; - enum wireless_mode wirelessmode = mac->mode; - bool b_shortgi = false; - u8 rate_mask[5]; - u8 macid = 0; - u8 mimops = 1; - - ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); - switch (wirelessmode) { - case WIRELESS_MODE_B: - ratr_index = RATR_INX_WIRELESS_B; - if (ratr_bitmap & 0x0000000c) - ratr_bitmap &= 0x0000000d; - else - ratr_bitmap &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_index = RATR_INX_WIRELESS_GB; - - if (rssi_level == 1) - ratr_bitmap &= 0x00000f00; - else if (rssi_level == 2) - ratr_bitmap &= 0x00000ff0; - else - ratr_bitmap &= 0x00000ff5; - break; - case WIRELESS_MODE_A: - ratr_index = RATR_INX_WIRELESS_A; - ratr_bitmap &= 0x00000ff0; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (mimops == 0) { - if (rssi_level == 1) - ratr_bitmap &= 0x00070000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0007f000; - else - ratr_bitmap &= 0x0007f005; - } else { - if (rtlphy->rf_type == RF_1T2R || - rtlphy->rf_type == RF_1T1R) { - if (b_curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff005; - } - } else { - if (b_curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff005; - } - } - } - - if ((b_curtxbw_40mhz && b_curshortgi_40mhz) || - (!b_curtxbw_40mhz && b_curshortgi_20mhz)) { - - if (macid == 0) - b_shortgi = true; - else if (macid == 1) - b_shortgi = false; - } - break; - default: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (rtlphy->rf_type == RF_1T2R) - ratr_bitmap &= 0x000ff0ff; - else - ratr_bitmap &= 0x0f0ff0ff; - break; - } - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x\n", ratr_bitmap)); - *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | - (ratr_index << 28)); - rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); - rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); -} - -void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 sifs_timer; - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); - if (!mac->ht_enable) - sifs_timer = 0x0a0a; - else - sifs_timer = 0x1010; - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); -} - -bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; - u8 u1tmp; - bool b_actuallyset = false; - unsigned long flag; - - if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) - return false; - - if (ppsc->b_swrf_processing) - return false; - - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); - if (ppsc->rfchange_inprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - return false; - } else { - ppsc->rfchange_inprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - } - - cur_rfstate = ppsc->rfpwr_state; - - if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { - rtlpriv->intf_ops->disable_aspm(hw); - RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); - } - - rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, - REG_MAC_PINMUX_CFG)&~(BIT(3))); - - u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); - e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; - - if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); - - e_rfpowerstate_toset = ERFON; - ppsc->b_hwradiooff = false; - b_actuallyset = true; - } else if ((ppsc->b_hwradiooff == false) - && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); - - e_rfpowerstate_toset = ERFOFF; - ppsc->b_hwradiooff = true; - b_actuallyset = true; - } - - if (b_actuallyset) { - if (e_rfpowerstate_toset == ERFON) { - if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { - rtlpriv->intf_ops->disable_aspm(hw); - RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); - } - } - - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); - ppsc->rfchange_inprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - - if (e_rfpowerstate_toset == ERFOFF) { - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { - rtlpriv->intf_ops->enable_aspm(hw); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); - } - } - - } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { - rtlpriv->intf_ops->enable_aspm(hw); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); - } - - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); - ppsc->rfchange_inprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - } else { - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); - ppsc->rfchange_inprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - } - - *valid = 1; - return !ppsc->b_hwradiooff; - -} - -void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 *macaddr = p_macaddr; - u32 entry_id = 0; - bool is_pairwise = false; - - static u8 cam_const_addr[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} - }; - static u8 cam_const_broad[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - if (clear_all) { - u8 idx = 0; - u8 cam_offset = 0; - u8 clear_number = 5; - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); - - for (idx = 0; idx < clear_number; idx++) { - rtl_cam_mark_invalid(hw, cam_offset + idx); - rtl_cam_empty_entry(hw, cam_offset + idx); - - if (idx < 5) { - memset(rtlpriv->sec.key_buf[idx], 0, - MAX_KEY_LEN); - rtlpriv->sec.key_len[idx] = 0; - } - } - - } else { - switch (enc_algo) { - case WEP40_ENCRYPTION: - enc_algo = CAM_WEP40; - break; - case WEP104_ENCRYPTION: - enc_algo = CAM_WEP104; - break; - case TKIP_ENCRYPTION: - enc_algo = CAM_TKIP; - break; - case AESCCMP_ENCRYPTION: - enc_algo = CAM_AES; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); - enc_algo = CAM_TKIP; - break; - } - - if (is_wepkey || rtlpriv->sec.use_defaultkey) { - macaddr = cam_const_addr[key_index]; - entry_id = key_index; - } else { - if (is_group) { - macaddr = cam_const_broad; - entry_id = key_index; - } else { - key_index = PAIRWISE_KEYIDX; - entry_id = CAM_PAIRWISE_KEY_POSITION; - is_pairwise = true; - } - } - - if (rtlpriv->sec.key_len[key_index] == 0) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry\n")); - rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); - if (is_pairwise) { - RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", - rtlpriv->sec.pairwise_key, - rtlpriv->sec. - key_len[PAIRWISE_KEYIDX]); - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec. - key_buf[key_index]); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); - - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - rtl_cam_add_one_entry(hw, - rtlefuse->dev_addr, - PAIRWISE_KEYIDX, - CAM_PAIRWISE_KEY_POSITION, - enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf - [entry_id]); - } - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf[entry_id]); - } - - } - } -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h deleted file mode 100644 index 305c819c8c78..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_HW_H__ -#define __RTL92CE_HW_H__ - -void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); -void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); -int rtl92ce_hw_init(struct ieee80211_hw *hw); -void rtl92ce_card_disable(struct ieee80211_hw *hw); -void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); -void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); -int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); -void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); -void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); -void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); -void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr); -void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); -void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); -void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); -bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); -void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); -void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c deleted file mode 100644 index 609108421570..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c +++ /dev/null @@ -1,144 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-led.h" - -void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - u8 ledcfg; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - rtl_write_byte(rtlpriv, - REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); - break; - case LED_PIN_LED1: - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - pled->b_ledon = true; -} - -void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - u8 ledcfg; - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - ledcfg &= 0xf0; - if (pcipriv->ledctl.bled_opendrain == true) - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(1) | BIT(5) | BIT(6))); - else - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(3) | BIT(5) | BIT(6))); - break; - case LED_PIN_LED1: - ledcfg &= 0x0f; - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - pled->b_ledon = false; -} - -void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) -{ -} - -void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) -{ -} - -void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - switch (ledaction) { - case LED_CTL_POWER_ON: - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - rtl92ce_sw_led_on(hw, pLed0); - break; - case LED_CTL_POWER_OFF: - rtl92ce_sw_led_off(hw, pLed0); - break; - default: - break; - } -} - -void rtl92ce_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && - (ledaction == LED_CTL_TX || - ledaction == LED_CTL_RX || - ledaction == LED_CTL_SITE_SURVEY || - ledaction == LED_CTL_LINK || - ledaction == LED_CTL_NO_LINK || - ledaction == LED_CTL_START_TO_LINK || - ledaction == LED_CTL_POWER_ON)) { - return; - } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); - _rtl92ce_sw_led_control(hw, ledaction); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h deleted file mode 100644 index 10da3018f4b7..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_LED_H__ -#define __RTL92CE_LED_H__ - -void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); -void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); -void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); -void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c deleted file mode 100644 index 13d7b387a96a..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c +++ /dev/null @@ -1,2676 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../ps.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-rf.h" -#include "rtl8192c-dm.h" -#include "rtl8192c-table.h" - -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, - u8 configtype); -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, - u8 configtype); -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, u32 para1, - u32 para2, u32 msdelay); -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, u8 *step, - u32 *delay); -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath); -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx); -u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 returnvalue, originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, - bitmask)); - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, - regaddr, originalvalue)); - - return returnvalue; - -} - -void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - - rtl_write_dword(rtlpriv, regaddr, data); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); - -} - -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 original_value, readback_value, bitshift; - struct rtl_phy *rtlphy = &(rtlpriv->phy); - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) { - original_value = _rtl92c_phy_rf_serial_read(hw, - rfpath, regaddr); - } else { - original_value = _rtl92c_phy_fw_rf_serial_read(hw, - rfpath, regaddr); - } - - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); - - return readback_value; -} - -void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 original_value, bitshift; - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _rtl92c_phy_rf_serial_read(hw, - rfpath, - regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); - } - - _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); - } else { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _rtl92c_phy_fw_rf_serial_read(hw, - rfpath, - regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); - } - _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); - } - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), " - "rfpath(%#x)\n", regaddr, - bitmask, data, rfpath)); -} - -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - RT_ASSERT(false, ("deprecated!\n")); - return 0; -} - -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data) -{ - RT_ASSERT(false, ("deprecated!\n")); -} - -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - u32 newoffset; - u32 tmplong, tmplong2; - u8 rfpi_enable = 0; - u32 retvalue; - - offset &= 0x3f; - newoffset = offset; - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); - return 0xFFFFFFFF; - } - tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); - if (rfpath == RF90_PATH_A) - tmplong2 = tmplong; - else - tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); - tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | - (newoffset << 23) | BLSSIREADEDGE; - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong & (~BLSSIREADEDGE)); - mdelay(1); - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); - mdelay(1); - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong | BLSSIREADEDGE); - mdelay(1); - if (rfpath == RF90_PATH_A) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - else if (rfpath == RF90_PATH_B) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, - BIT(8)); - if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, - BLSSIREADBACKDATA); - else - retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, - BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, - retvalue)); - return retvalue; -} - -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data) -{ - u32 data_and_addr; - u32 newoffset; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); - return; - } - offset &= 0x3f; - newoffset = offset; - data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; - rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, - data_and_addr)); -} - -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - -static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); - rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); - rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); - rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); -} - -bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - bool is92c = IS_92C_SERIAL(rtlhal->version); - bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); - - if (is92c) - rtl_write_byte(rtlpriv, 0x14, 0x71); - return rtstatus; -} - -bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) -{ - bool rtstatus = true; - struct rtl_priv *rtlpriv = rtl_priv(hw); - u16 regval; - u32 regvaldw; - u8 b_reg_hwparafile = 1; - - _rtl92c_phy_init_bb_rf_register_definition(hw); - regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); - rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, - regval | BIT(13) | BIT(0) | BIT(1)); - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); - rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, - FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | - FEN_BB_GLB_RSTn | FEN_BBRSTB); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); - regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); - rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); - if (b_reg_hwparafile == 1) - rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); - return rtstatus; -} - -bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) -{ - return rtl92c_phy_rf6052_config(hw); -} - -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - bool rtstatus; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, - BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); - return false; - } - if (rtlphy->rf_type == RF_1T2R) { - _rtl92c_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); - } - if (rtlefuse->autoload_failflag == false) { - rtlphy->pwrgroup_cnt = 0; - rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, - BASEBAND_CONFIG_PHY_REG); - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); - return false; - } - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, - BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); - return false; - } - rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - 0x200)); - return true; -} - -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - u32 arraylength; - u32 *ptrarray; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); - arraylength = MAC_2T_ARRAYLENGTH; - ptrarray = RTL8192CEMAC_2T_ARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); - for (i = 0; i < arraylength; i = i + 2) - rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); - return true; -} - -void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) -{ -} - -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, - u8 configtype) -{ - int i; - u32 *phy_regarray_table; - u32 *agctab_array_table; - u16 phy_reg_arraylen, agctab_arraylen; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_92C_SERIAL(rtlhal->version)) { - agctab_arraylen = AGCTAB_2TARRAYLENGTH; - agctab_array_table = RTL8192CEAGCTAB_2TARRAY; - phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH; - phy_regarray_table = RTL8192CEPHY_REG_2TARRAY; - } else { - agctab_arraylen = AGCTAB_1TARRAYLENGTH; - agctab_array_table = RTL8192CEAGCTAB_1TARRAY; - phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH; - phy_regarray_table = RTL8192CEPHY_REG_1TARRAY; - } - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_reg_arraylen; i = i + 2) { - if (phy_regarray_table[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table[i] == 0xfb) - udelay(50); - else if (phy_regarray_table[i] == 0xfa) - udelay(5); - else if (phy_regarray_table[i] == 0xf9) - udelay(1); - rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, - phy_regarray_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); - } - rtl92c_phy_config_bb_external_pa(hw); - } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { - for (i = 0; i < agctab_arraylen; i = i + 2) { - rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, - agctab_array_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); - } - } - return true; -} - -static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, - u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][0])); - } - if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][1])); - } - if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][6])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][7])); - } - if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][2])); - } - if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][3])); - } - if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][4])); - } - if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][5])); - } - if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][8])); - } - if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][9])); - } - - if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][14])); - } - - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][15])); - } - - if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][10])); - } - - if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][11])); - } - - if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][12])); - } - - if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = - data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][13])); - - rtlphy->pwrgroup_cnt++; - } -} - -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, - u8 configtype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int i; - u32 *phy_regarray_table_pg; - u16 phy_regarray_pg_len; - - phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH; - phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG; - - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_regarray_pg_len; i = i + 3) { - if (phy_regarray_table_pg[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table_pg[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table_pg[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table_pg[i] == 0xfb) - udelay(50); - else if (phy_regarray_table_pg[i] == 0xfa) - udelay(5); - else if (phy_regarray_table_pg[i] == 0xf9) - udelay(1); - - _rtl92c_store_pwrIndex_diffrate_offset(hw, - phy_regarray_table_pg[i], - phy_regarray_table_pg[i + 1], - phy_regarray_table_pg[i + 2]); - } - } else { - - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); - } - return true; -} - -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - return true; -} - -bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - - int i; - bool rtstatus = true; - u32 *radioa_array_table; - u32 *radiob_array_table; - u16 radioa_arraylen, radiob_arraylen; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_92C_SERIAL(rtlhal->version)) { - radioa_arraylen = RADIOA_2TARRAYLENGTH; - radioa_array_table = RTL8192CERADIOA_2TARRAY; - radiob_arraylen = RADIOB_2TARRAYLENGTH; - radiob_array_table = RTL8192CE_RADIOB_2TARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); - } else { - radioa_arraylen = RADIOA_1TARRAYLENGTH; - radioa_array_table = RTL8192CE_RADIOA_1TARRAY; - radiob_arraylen = RADIOB_1TARRAYLENGTH; - radiob_array_table = RTL8192CE_RADIOB_1TARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); - rtstatus = true; - switch (rfpath) { - case RF90_PATH_A: - for (i = 0; i < radioa_arraylen; i = i + 2) { - if (radioa_array_table[i] == 0xfe) - mdelay(50); - else if (radioa_array_table[i] == 0xfd) - mdelay(5); - else if (radioa_array_table[i] == 0xfc) - mdelay(1); - else if (radioa_array_table[i] == 0xfb) - udelay(50); - else if (radioa_array_table[i] == 0xfa) - udelay(5); - else if (radioa_array_table[i] == 0xf9) - udelay(1); - else { - rtl_set_rfreg(hw, rfpath, radioa_array_table[i], - RFREG_OFFSET_MASK, - radioa_array_table[i + 1]); - udelay(1); - } - } - _rtl92c_phy_config_rf_external_pa(hw, rfpath); - break; - case RF90_PATH_B: - for (i = 0; i < radiob_arraylen; i = i + 2) { - if (radiob_array_table[i] == 0xfe) { - mdelay(50); - } else if (radiob_array_table[i] == 0xfd) - mdelay(5); - else if (radiob_array_table[i] == 0xfc) - mdelay(1); - else if (radiob_array_table[i] == 0xfb) - udelay(50); - else if (radiob_array_table[i] == 0xfa) - udelay(5); - else if (radiob_array_table[i] == 0xf9) - udelay(1); - else { - rtl_set_rfreg(hw, rfpath, radiob_array_table[i], - RFREG_OFFSET_MASK, - radiob_array_table[i + 1]); - udelay(1); - } - } - break; - case RF90_PATH_C: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - case RF90_PATH_D: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - return true; -} - -void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->default_initialgain[0] = - (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[1] = - (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[2] = - (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[3] = - (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); - - rtlphy->framesync = (u8) rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR3, MASKBYTE0); - rtlphy->framesync_c34 = rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR2, MASKDWORD); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); -} - -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = - RFPGA0_XA_LSSIPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = - RFPGA0_XB_LSSIPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - - rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = - RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = - RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = - RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = - RFPGA0_XCD_SWITCHCONTROL; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = - ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = - ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = - ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = - ROFDM0_XDRXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = - ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = - ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = - ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = - ROFDM0_XDTXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = - RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = - RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = - RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = - RFPGA0_XD_LSSIREADBACK; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = - TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = - TRANSCEIVEB_HSPI_READBACK; - -} - -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 txpwr_level; - long txpwr_dbm; - - txpwr_level = rtlphy->cur_cck_txpwridx; - txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_B, txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx + - rtlefuse->legacy_ht_txpowerdiff; - if (_rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_G, - txpwr_level) > txpwr_dbm) - txpwr_dbm = - _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, - txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx; - if (_rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_N_24G, - txpwr_level) > txpwr_dbm) - txpwr_dbm = - _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, - txpwr_level); - *powerlevel = txpwr_dbm; -} - -static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, - u8 *cckpowerlevel, u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 index = (channel - 1); - - cckpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; - cckpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; - if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; - } else if (get_rf_type(rtlphy) == RF_2T2R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; - } -} - -static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, - u8 channel, u8 *cckpowerlevel, - u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; - rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; -} - -void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 cckpowerlevel[2], ofdmpowerlevel[2]; - - if (rtlefuse->b_txpwr_fromeprom == false) - return; - _rtl92c_get_txpower_index(hw, channel, - &cckpowerlevel[0], &ofdmpowerlevel[0]); - _rtl92c_ccxpower_index_check(hw, - channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); - rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); -} - -bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 idx; - u8 rf_path; - - u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, - WIRELESS_MODE_B, - power_indbm); - u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, - WIRELESS_MODE_N_24G, - power_indbm); - if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) - ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; - else - ofdmtxpwridx = 0; - RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx)); - for (idx = 0; idx < 14; idx++) { - for (rf_path = 0; rf_path < 2; rf_path++) { - rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; - rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = - ofdmtxpwridx; - rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = - ofdmtxpwridx; - } - } - rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); - return true; -} - -void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) -{ -} - -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm) -{ - u8 txpwridx; - long offset; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - - if ((power_indbm - offset) > 0) - txpwridx = (u8) ((power_indbm - offset) * 2); - else - txpwridx = 0; - - if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) - txpwridx = MAX_TXPWR_IDX_NMODE_92S; - - return txpwridx; -} - -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx) -{ - long offset; - long pwrout_dbm; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - pwrout_dbm = txpwridx / 2 + offset; - return pwrout_dbm; -} - -void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - enum io_type iotype; - - if (!is_hal_stop(rtlhal)) { - switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - - break; - case SCAN_OPT_RESTORE: - iotype = IO_CMD_RESUME_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); - break; - } - } -} - -void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u8 reg_bw_opmode; - u8 reg_prsr_rsc; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) - - if (is_hal_stop(rtlhal)) - return; - - reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); - reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - reg_bw_opmode |= BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - break; - - case HT_CHANNEL_WIDTH_20_40: - reg_bw_opmode &= ~BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - - reg_prsr_rsc = - (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); - break; - - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); - break; - } - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - break; - case HT_CHANNEL_WIDTH_20_40: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); - rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, - (mac->cur_40_prime_sc >> 1)); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); - rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), - (mac->cur_40_prime_sc == - HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); - break; - } - rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); - rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); -} - -void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_bw = rtlphy->current_chan_bw; - - if (rtlphy->set_bwmode_inprogress) - return; - rtlphy->set_bwmode_inprogress = true; - if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) - rtl92c_phy_set_bw_mode_callback(hw); - else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); - rtlphy->set_bwmode_inprogress = false; - rtlphy->current_chan_bw = tmp_bw; - } -} - -void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 delay; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); - if (is_hal_stop(rtlhal)) - return; - do { - if (!rtlphy->sw_chnl_inprogress) - break; - if (!_rtl92c_phy_sw_chnl_step_by_step - (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, - &rtlphy->sw_chnl_step, &delay)) { - if (delay > 0) - mdelay(delay); - else - continue; - } else - rtlphy->sw_chnl_inprogress = false; - break; - } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); -} - -u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->sw_chnl_inprogress) - return 0; - if (rtlphy->set_bwmode_inprogress) - return 0; - RT_ASSERT((rtlphy->current_channel <= 14), - ("WIRELESS_MODE_G but channel>14")); - rtlphy->sw_chnl_inprogress = true; - rtlphy->sw_chnl_stage = 0; - rtlphy->sw_chnl_step = 0; - if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl92c_phy_sw_chnl_callback(hw); - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem\n")); - rtlphy->sw_chnl_inprogress = false; - } else { - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or" - " unload\n")); - rtlphy->sw_chnl_inprogress = false; - } - return 1; -} - -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, u8 *step, - u32 *delay) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; - u32 precommoncmdcnt; - struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; - u32 postcommoncmdcnt; - struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; - u32 rfdependcmdcnt; - struct swchnlcmd *currentcmd = NULL; - u8 rfpath; - u8 num_total_rfpath = rtlphy->num_total_rfpath; - - precommoncmdcnt = 0; - _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, - CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); - _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); - - postcommoncmdcnt = 0; - - _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, - MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); - - rfdependcmdcnt = 0; - - RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); - - _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, - RF_CHNLBW, channel, 10); - - _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, - 0); - - do { - switch (*stage) { - case 0: - currentcmd = &precommoncmd[*step]; - break; - case 1: - currentcmd = &rfdependcmd[*step]; - break; - case 2: - currentcmd = &postcommoncmd[*step]; - break; - } - - if (currentcmd->cmdid == CMDID_END) { - if ((*stage) == 2) { - return true; - } else { - (*stage)++; - (*step) = 0; - continue; - } - } - - switch (currentcmd->cmdid) { - case CMDID_SET_TXPOWEROWER_LEVEL: - rtl92c_phy_set_txpower_level(hw, channel); - break; - case CMDID_WRITEPORT_ULONG: - rtl_write_dword(rtlpriv, currentcmd->para1, - currentcmd->para2); - break; - case CMDID_WRITEPORT_USHORT: - rtl_write_word(rtlpriv, currentcmd->para1, - (u16) currentcmd->para2); - break; - case CMDID_WRITEPORT_UCHAR: - rtl_write_byte(rtlpriv, currentcmd->para1, - (u8) currentcmd->para2); - break; - case CMDID_RF_WRITEREG: - for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { - rtlphy->rfreg_chnlval[rfpath] = - ((rtlphy->rfreg_chnlval[rfpath] & - 0xfffffc00) | currentcmd->para2); - - rtl_set_rfreg(hw, (enum radio_path)rfpath, - currentcmd->para1, - RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[rfpath]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - break; - } while (true); - - (*delay) = currentcmd->msdelay; - (*step)++; - return false; -} - -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, - u32 para1, u32 para2, u32 msdelay) -{ - struct swchnlcmd *pcmd; - - if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); - return false; - } - - if (cmdtableidx >= cmdtablesz) - return false; - - pcmd = cmdtable + cmdtableidx; - pcmd->cmdid = cmdid; - pcmd->para1 = para1; - pcmd->para2 = para2; - pcmd->msdelay = msdelay; - return true; -} - -bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) -{ - return true; -} - -static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) -{ - u32 reg_eac, reg_e94, reg_e9c, reg_ea4; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe3c, MASKDWORD, - config_pathb ? 0x28160202 : 0x28160502); - - if (config_pathb) { - rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); - } - - rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); - - mdelay(IQK_DELAY_TIME); - - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); - reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); - reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); - - if (!(reg_eac & BIT(28)) && - (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && - (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(27)) && - (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_eac & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) -{ - u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); - mdelay(IQK_DELAY_TIME); - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); - reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); - reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); - reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); - if (!(reg_eac & BIT(31)) && - (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && - (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(30)) && - (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, - bool b_iqk_ok, long result[][8], - u8 final_candidate, bool btxonly) -{ - u32 oldval_0, x, tx0_a, reg; - long y, tx0_c; - - if (final_candidate == 0xFF) - return; - else if (b_iqk_ok) { - oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][0]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx0_a = (x * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), - ((x * oldval_0 >> 7) & 0x1)); - y = result[final_candidate][1]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx0_c = (y * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, - ((tx0_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, - (tx0_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), - ((y * oldval_0 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][2]; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][3] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][3] >> 6) & 0xF; - rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); - } -} - -static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, - bool b_iqk_ok, long result[][8], - u8 final_candidate, bool btxonly) -{ - u32 oldval_1, x, tx1_a, reg; - long y, tx1_c; - - if (final_candidate == 0xFF) - return; - else if (b_iqk_ok) { - oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][4]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx1_a = (x * oldval_1) >> 8; - rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), - ((x * oldval_1 >> 7) & 0x1)); - y = result[final_candidate][5]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx1_c = (y * oldval_1) >> 8; - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, - ((tx1_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, - (tx1_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), - ((y * oldval_1 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][6]; - rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][7] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][7] >> 6) & 0xF; - rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); - } -} - -static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 registernum) -{ - u32 i; - - for (i = 0; i < registernum; i++) - addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); -} - -static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); - macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); -} - -static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 regiesternum) -{ - u32 i; - - for (i = 0; i < regiesternum; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); -} - -static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); - rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); -} - -static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, - u32 *addareg, bool is_patha_on, bool is2t) -{ - u32 pathOn; - u32 i; - - pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2t) { - pathOn = 0x0bdb25a0; - rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); - } else { - rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); - } - - for (i = 1; i < IQK_ADDA_REG_NUM; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); -} - -static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - rtl_write_byte(rtlpriv, macreg[0], 0x3F); - - for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], - (u8) (macbackup[i] & (~BIT(3)))); - rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); -} - -static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); -} - -static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) -{ - u32 mode; - - mode = pi_mode ? 0x01000100 : 0x01000000; - rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); - rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); -} - -static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, - long result[][8], u8 c1, u8 c2) -{ - u32 i, j, diff, simularity_bitmap, bound; - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - u8 final_candidate[2] = { 0xFF, 0xFF }; - bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); - - if (is2t) - bound = 8; - else - bound = 4; - - simularity_bitmap = 0; - - for (i = 0; i < bound; i++) { - diff = (result[c1][i] > result[c2][i]) ? - (result[c1][i] - result[c2][i]) : - (result[c2][i] - result[c1][i]); - - if (diff > MAX_TOLERANCE) { - if ((i == 2 || i == 6) && !simularity_bitmap) { - if (result[c1][i] + result[c1][i + 1] == 0) - final_candidate[(i / 4)] = c2; - else if (result[c2][i] + result[c2][i + 1] == 0) - final_candidate[(i / 4)] = c1; - else - simularity_bitmap = simularity_bitmap | - (1 << i); - } else - simularity_bitmap = - simularity_bitmap | (1 << i); - } - } - - if (simularity_bitmap == 0) { - for (i = 0; i < (bound / 4); i++) { - if (final_candidate[i] != 0xFF) { - for (j = i * 4; j < (i + 1) * 4 - 2; j++) - result[3][j] = - result[final_candidate[i]][j]; - bresult = false; - } - } - return bresult; - } else if (!(simularity_bitmap & 0x0F)) { - for (i = 0; i < 4; i++) - result[3][i] = result[c1][i]; - return false; - } else if (!(simularity_bitmap & 0xF0) && is2t) { - for (i = 4; i < 8; i++) - result[3][i] = result[c1][i]; - return false; - } else { - return false; - } - -} - -static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, - long result[][8], u8 t, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 i; - u8 patha_ok, pathb_ok; - u32 adda_reg[IQK_ADDA_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, - 0xe78, 0xe7c, 0xe80, 0xe84, - 0xe88, 0xe8c, 0xed0, 0xed4, - 0xed8, 0xedc, 0xee0, 0xeec - }; - - u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - - const u32 retrycount = 2; - - u32 bbvalue; - - if (t == 0) { - bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); - - _rtl92c_phy_save_adda_registers(hw, adda_reg, - rtlphy->adda_backup, 16); - _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - } - _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); - if (t == 0) { - rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - } - if (!rtlphy->b_rfpi_enable) - _rtl92c_phy_pi_mode_switch(hw, true); - if (t == 0) { - rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); - rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); - rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); - rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); - if (is2t) { - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); - } - _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); - if (is2t) - rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); - rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); - rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); - for (i = 0; i < retrycount; i++) { - patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); - if (patha_ok == 0x03) { - result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && patha_ok == 0x01) - result[t][0] = (rtl_get_bbreg(hw, 0xe94, - MASKDWORD) & 0x3FF0000) >> - 16; - result[t][1] = - (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; - - } - - if (is2t) { - _rtl92c_phy_path_a_standby(hw); - _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); - for (i = 0; i < retrycount; i++) { - pathb_ok = _rtl92c_phy_path_b_iqk(hw); - if (pathb_ok == 0x03) { - result[t][4] = (rtl_get_bbreg(hw, - 0xeb4, - MASKDWORD) & - 0x3FF0000) >> 16; - result[t][5] = - (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][6] = - (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][7] = - (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && pathb_ok == 0x01) { - result[t][4] = (rtl_get_bbreg(hw, - 0xeb4, - MASKDWORD) & - 0x3FF0000) >> 16; - } - result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - } - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); - rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); - if (is2t) - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); - if (t != 0) { - if (!rtlphy->b_rfpi_enable) - _rtl92c_phy_pi_mode_switch(hw, false); - _rtl92c_phy_reload_adda_registers(hw, adda_reg, - rtlphy->adda_backup, 16); - _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - } -} - -static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) -{ - u8 tmpreg; - u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - tmpreg = rtl_read_byte(rtlpriv, 0xd03); - - if ((tmpreg & 0x70) != 0) - rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); - else - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - - if ((tmpreg & 0x70) != 0) { - rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); - - if (is2t) - rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, - MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, - (rf_a_mode & 0x8FFFF) | 0x10000); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - (rf_b_mode & 0x8FFFF) | 0x10000); - } - lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); - - mdelay(100); - - if ((tmpreg & 0x70) != 0) { - rtl_write_byte(rtlpriv, 0xd03, tmpreg); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - rf_b_mode); - } else { - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - } -} - -static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, - char delta, bool is2t) -{ - /* This routine is deliberately dummied out for later fixes */ -#if 0 - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - - u32 reg_d[PATH_NUM]; - u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; - - u32 bb_backup[APK_BB_REG_NUM]; - u32 bb_reg[APK_BB_REG_NUM] = { - 0x904, 0xc04, 0x800, 0xc08, 0x874 - }; - u32 bb_ap_mode[APK_BB_REG_NUM] = { - 0x00000020, 0x00a05430, 0x02040000, - 0x000800e4, 0x00204000 - }; - u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { - 0x00000020, 0x00a05430, 0x02040000, - 0x000800e4, 0x22204000 - }; - - u32 afe_backup[APK_AFE_REG_NUM]; - u32 afe_reg[APK_AFE_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, - 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, - 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, - 0xeec - }; - - u32 mac_backup[IQK_MAC_REG_NUM]; - u32 mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - - u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { - {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, - {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} - }; - - u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { - {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, - {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} - }; - - u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { - {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, - {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} - }; - - u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { - {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, - {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} - }; - - u32 afe_on_off[PATH_NUM] = { - 0x04db25a4, 0x0b1b25a4 - }; - - u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; - - u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; - - u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; - - u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; - - const char apk_delta_mapping[APK_BB_REG_NUM][13] = { - {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} - }; - - const u32 apk_normal_setting_value_1[13] = { - 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, - 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, - 0x12680000, 0x00880000, 0x00880000 - }; - - const u32 apk_normal_setting_value_2[16] = { - 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, - 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, - 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, - 0x00050006 - }; - - const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; - - long bb_offset, delta_v, delta_offset; - - if (!is2t) - pathbound = 1; - - for (index = 0; index < PATH_NUM; index++) { - apk_offset[index] = apk_normal_offset[index]; - apk_value[index] = apk_normal_value[index]; - afe_on_off[index] = 0x6fdb25a4; - } - - for (index = 0; index < APK_BB_REG_NUM; index++) { - for (path = 0; path < pathbound; path++) { - apk_rf_init_value[path][index] = - apk_normal_rf_init_value[path][index]; - apk_rf_value_0[path][index] = - apk_normal_rf_value_0[path][index]; - } - bb_ap_mode[index] = bb_normal_ap_mode[index]; - - apkbound = 6; - } - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); - } - - _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); - - _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); - - for (path = 0; path < pathbound; path++) { - if (path == RF90_PATH_A) { - offset = 0xb00; - for (index = 0; index < 11; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); - - offset = 0xb68; - for (; index < 13; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); - - offset = 0xb00; - for (index = 0; index < 16; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_2 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - } else if (path == RF90_PATH_B) { - offset = 0xb70; - for (index = 0; index < 10; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); - rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); - - offset = 0xb68; - index = 11; - for (; index < 13; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); - - offset = 0xb60; - for (index = 0; index < 16; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_2 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - } - - reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, - 0xd, MASKDWORD); - - for (index = 0; index < APK_AFE_REG_NUM; index++) - rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, - afe_on_off[path]); - - if (path == RF90_PATH_A) { - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, - bb_ap_mode[index]); - } - } - - _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); - - if (path == 0) { - rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); - } else { - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, - 0x10000); - rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, - 0x1000f); - rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, - 0x20103); - } - - delta_offset = ((delta + 14) / 2); - if (delta_offset < 0) - delta_offset = 0; - else if (delta_offset > 12) - delta_offset = 12; - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index != 1) - continue; - - tmpreg = apk_rf_init_value[path][index]; - - if (!rtlefuse->b_apk_thermalmeterignore) { - bb_offset = (tmpreg & 0xF0000) >> 16; - - if (!(tmpreg & BIT(15))) - bb_offset = -bb_offset; - - delta_v = - apk_delta_mapping[index][delta_offset]; - - bb_offset += delta_v; - - if (bb_offset < 0) { - tmpreg = tmpreg & (~BIT(15)); - bb_offset = -bb_offset; - } else { - tmpreg = tmpreg | BIT(15); - } - - tmpreg = - (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); - } - - rtl_set_rfreg(hw, (enum radio_path)path, 0xc, - MASKDWORD, 0x8992e); - rtl_set_rfreg(hw, (enum radio_path)path, 0x0, - MASKDWORD, apk_rf_value_0[path][index]); - rtl_set_rfreg(hw, (enum radio_path)path, 0xd, - MASKDWORD, tmpreg); - - i = 0; - do { - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); - rtl_set_bbreg(hw, apk_offset[path], - MASKDWORD, apk_value[0]); - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset 0x%x " - "value 0x%x\n", - apk_offset[path], - rtl_get_bbreg(hw, apk_offset[path], - MASKDWORD))); - - mdelay(3); - - rtl_set_bbreg(hw, apk_offset[path], - MASKDWORD, apk_value[1]); - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset 0x%x " - "value 0x%x\n", - apk_offset[path], - rtl_get_bbreg(hw, apk_offset[path], - MASKDWORD))); - - mdelay(20); - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - - if (path == RF90_PATH_A) - tmpreg = rtl_get_bbreg(hw, 0xbd8, - 0x03E00000); - else - tmpreg = rtl_get_bbreg(hw, 0xbd8, - 0xF8000000); - - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset " - "0xbd8[25:21] %x\n", tmpreg)); - - i++; - - } while (tmpreg > apkbound && i < 4); - - apk_result[path][index] = tmpreg; - } - } - - _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); - } - - _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); - - for (path = 0; path < pathbound; path++) { - rtl_set_rfreg(hw, (enum radio_path)path, 0xd, - MASKDWORD, reg_d[path]); - - if (path == RF90_PATH_B) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, - 0x1000f); - rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, - 0x20101); - } - - if (apk_result[path][1] > 6) - apk_result[path][1] = 6; - } - - for (path = 0; path < pathbound; path++) { - rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (apk_result[path][1] << 5) | - apk_result[path][1])); - - if (path == RF90_PATH_A) - rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (0x00 << 5) | 0x05)); - else - rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (0x02 << 5) | 0x05)); - - rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, - ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | - 0x08)); - - } - - rtlphy->b_apk_done = true; -#endif -} - -static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, - bool bmain, bool is2t) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (is_hal_stop(rtlhal)) { - rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - } - if (is2t) { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x1); - else - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x2); - } else { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); - else - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); - - } -} - -#undef IQK_ADDA_REG_NUM -#undef IQK_DELAY_TIME - -void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - long result[4][8]; - u8 i, final_candidate; - bool b_patha_ok, b_pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; - bool is12simular, is13simular, is23simular; - bool b_start_conttx = false, b_singletone = false; - u32 iqk_bb_reg[10] = { - ROFDM0_XARXIQIMBALANCE, - ROFDM0_XBRXIQIMBALANCE, - ROFDM0_ECCATHRESHOLD, - ROFDM0_AGCRSSITABLE, - ROFDM0_XATXIQIMBALANCE, - ROFDM0_XBTXIQIMBALANCE, - ROFDM0_XCTXIQIMBALANCE, - ROFDM0_XCTXAFE, - ROFDM0_XDTXAFE, - ROFDM0_RXIQEXTANTA - }; - - if (b_recovery) { - _rtl92c_phy_reload_adda_registers(hw, - iqk_bb_reg, - rtlphy->iqk_bb_backup, 10); - return; - } - if (b_start_conttx || b_singletone) - return; - for (i = 0; i < 8; i++) { - result[0][i] = 0; - result[1][i] = 0; - result[2][i] = 0; - result[3][i] = 0; - } - final_candidate = 0xff; - b_patha_ok = false; - b_pathb_ok = false; - is12simular = false; - is23simular = false; - is13simular = false; - for (i = 0; i < 3; i++) { - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_iq_calibrate(hw, result, i, true); - else - _rtl92c_phy_iq_calibrate(hw, result, i, false); - if (i == 1) { - is12simular = _rtl92c_phy_simularity_compare(hw, - result, 0, - 1); - if (is12simular) { - final_candidate = 0; - break; - } - } - if (i == 2) { - is13simular = _rtl92c_phy_simularity_compare(hw, - result, 0, - 2); - if (is13simular) { - final_candidate = 0; - break; - } - is23simular = _rtl92c_phy_simularity_compare(hw, - result, 1, - 2); - if (is23simular) - final_candidate = 1; - else { - for (i = 0; i < 8; i++) - reg_tmp += result[3][i]; - - if (reg_tmp != 0) - final_candidate = 3; - else - final_candidate = 0xFF; - } - } - } - for (i = 0; i < 4; i++) { - reg_e94 = result[i][0]; - reg_e9c = result[i][1]; - reg_ea4 = result[i][2]; - reg_eac = result[i][3]; - reg_eb4 = result[i][4]; - reg_ebc = result[i][5]; - reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; - } - if (final_candidate != 0xff) { - rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; - rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; - reg_ea4 = result[final_candidate][2]; - reg_eac = result[final_candidate][3]; - rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; - rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; - reg_ec4 = result[final_candidate][6]; - reg_ecc = result[final_candidate][7]; - b_patha_ok = b_pathb_ok = true; - } else { - rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; - rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; - } - if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ - _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, - final_candidate, - (reg_ea4 == 0)); - if (IS_92C_SERIAL(rtlhal->version)) { - if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ - _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, - result, - final_candidate, - (reg_ec4 == 0)); - } - _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, - rtlphy->iqk_bb_backup, 10); -} - -void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - bool b_start_conttx = false, b_singletone = false; - - if (b_start_conttx || b_singletone) - return; - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_lc_calibrate(hw, true); - else - _rtl92c_phy_lc_calibrate(hw, false); -} - -void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->b_apk_done) - return; - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_ap_calibrate(hw, delta, true); - else - _rtl92c_phy_ap_calibrate(hw, delta, false); -} - -void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_set_rfpath_switch(hw, bmain, true); - else - _rtl92c_phy_set_rfpath_switch(hw, bmain, false); -} - -bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - bool b_postprocessing = false; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); - do { - switch (iotype) { - case IO_CMD_RESUME_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); - b_postprocessing = true; - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); - b_postprocessing = true; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - } while (false); - if (b_postprocessing && !rtlphy->set_io_inprogress) { - rtlphy->set_io_inprogress = true; - rtlphy->current_io_type = iotype; - } else { - return false; - } - rtl92c_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); - return true; -} - -void rtl92c_phy_set_io(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; - rtl92c_dm_write_dig(hw); - rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; - dm_digtable.cur_igvalue = 0x17; - rtl92c_dm_write_dig(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); -} - -void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); -} - -static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) -{ - u32 u4b_tmp; - u8 delay = 5; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - while (u4b_tmp != 0 && delay > 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - delay--; - } - if (delay == 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); - return; - } - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); -} - -static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool bresult = true; - u8 i, queue_id; - struct rtl8192_tx_ring *ring = NULL; - - ppsc->set_rfpowerstate_inprogress = true; - switch (rfpwr_state) { - case ERFON:{ - if ((ppsc->rfpwr_state == ERFOFF) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { - bool rtstatus; - u32 InitializeCount = 0; - do { - InitializeCount++; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); - rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) - && (InitializeCount < 10)); - RT_CLEAR_PS_LEVEL(ppsc, - RT_RF_OFF_LEVL_HALT_NIC); - } else { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); - ppsc->last_awake_jiffies = jiffies; - rtl92ce_phy_set_rf_on(hw); - } - if (mac->link_state == MAC80211_LINKED) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } - break; - } - case ERFOFF:{ - for (queue_id = 0, i = 0; - queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { - ring = &pcipriv->dev.tx_ring[queue_id]; - if (skb_queue_len(&ring->queue) == 0 || - queue_id == BEACON_QUEUE) { - queue_id++; - continue; - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] " - "=%d before doze!\n", (i + 1), - queue_id, - skb_queue_len(&ring->queue))); - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); - break; - } - } - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); - rtl_ps_disable_nic(hw); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - } else { - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_POWER_OFF); - } - } - break; - } - case ERFSLEEP:{ - if (ppsc->rfpwr_state == ERFOFF) - break; - for (queue_id = 0, i = 0; - queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { - ring = &pcipriv->dev.tx_ring[queue_id]; - if (skb_queue_len(&ring->queue) == 0) { - queue_id++; - continue; - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); - break; - } - } - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); - ppsc->last_sleep_jiffies = jiffies; - _rtl92ce_phy_set_rf_sleep(hw); - break; - } - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - bresult = false; - break; - } - if (bresult) - ppsc->rfpwr_state = rfpwr_state; - ppsc->set_rfpowerstate_inprogress = false; - return bresult; -} - -bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool bresult = false; - - if (rfpwr_state == ppsc->rfpwr_state) - return bresult; - bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); - return bresult; -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h deleted file mode 100644 index ca4daee6e9a8..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h +++ /dev/null @@ -1,237 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_PHY_H__ -#define __RTL92C_PHY_H__ - -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -#define MAX_DOZE_WAITING_TIMES_9x 64 - -#define RT_CANNOT_IO(hw) false -#define HIGHPOWER_RADIOA_ARRAYLEN 22 - -#define MAX_TOLERANCE 5 -#define IQK_DELAY_TIME 1 - -#define APK_BB_REG_NUM 5 -#define APK_AFE_REG_NUM 16 -#define APK_CURVE_REG_NUM 4 -#define PATH_NUM 2 - -#define LOOP_LIMIT 5 -#define MAX_STALL_TIME 50 -#define AntennaDiversityValue 0x80 -#define MAX_TXPWR_IDX_NMODE_92S 63 -#define Reset_Cnt_Limit 3 - -#define IQK_ADDA_REG_NUM 16 -#define IQK_MAC_REG_NUM 4 - -#define RF90_PATH_MAX 2 -#define CHANNEL_MAX_NUMBER 14 -#define CHANNEL_GROUP_MAX 3 - -#define CT_OFFSET_MAC_ADDR 0X16 - -#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A -#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 -#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 -#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 -#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C - -#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F -#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 - -#define CT_OFFSET_CHANNEL_PLAH 0x75 -#define CT_OFFSET_THERMAL_METER 0x78 -#define CT_OFFSET_RF_OPTION 0x79 -#define CT_OFFSET_VERSION 0x7E -#define CT_OFFSET_CUSTOMER_ID 0x7F - -#define RTL92C_MAX_PATH_NUM 2 -#define CHANNEL_MAX_NUMBER 14 -#define CHANNEL_GROUP_MAX 3 - -enum swchnlcmd_id { - CMDID_END, - CMDID_SET_TXPOWEROWER_LEVEL, - CMDID_BBREGWRITE10, - CMDID_WRITEPORT_ULONG, - CMDID_WRITEPORT_USHORT, - CMDID_WRITEPORT_UCHAR, - CMDID_RF_WRITEREG, -}; - -struct swchnlcmd { - enum swchnlcmd_id cmdid; - u32 para1; - u32 para2; - u32 msdelay; -}; - -enum hw90_block_e { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, -}; - -enum baseband_config_type { - BASEBAND_CONFIG_PHY_REG = 0, - BASEBAND_CONFIG_AGC_TAB = 1, -}; - -enum ra_offset_area { - RA_OFFSET_LEGACY_OFDM1, - RA_OFFSET_LEGACY_OFDM2, - RA_OFFSET_HT_OFDM1, - RA_OFFSET_HT_OFDM2, - RA_OFFSET_HT_OFDM3, - RA_OFFSET_HT_OFDM4, - RA_OFFSET_HT_CCK, -}; - -enum antenna_path { - ANTENNA_NONE, - ANTENNA_D, - ANTENNA_C, - ANTENNA_CD, - ANTENNA_B, - ANTENNA_BD, - ANTENNA_BC, - ANTENNA_BCD, - ANTENNA_A, - ANTENNA_AD, - ANTENNA_AC, - ANTENNA_ACD, - ANTENNA_AB, - ANTENNA_ABD, - ANTENNA_ABC, - ANTENNA_ABCD -}; - -struct r_antenna_select_ofdm { - u32 r_tx_antenna:4; - u32 r_ant_l:4; - u32 r_ant_non_ht:4; - u32 r_ant_ht1:4; - u32 r_ant_ht2:4; - u32 r_ant_ht_s1:4; - u32 r_ant_non_ht_s1:4; - u32 ofdm_txsc:2; - u32 reserved:2; -}; - -struct r_antenna_select_cck { - u8 r_cckrx_enable_2:2; - u8 r_cckrx_enable:2; - u8 r_ccktx_enable:4; -}; - -struct efuse_contents { - u8 mac_addr[ETH_ALEN]; - u8 cck_tx_power_idx[6]; - u8 ht40_1s_tx_power_idx[6]; - u8 ht40_2s_tx_power_idx_diff[3]; - u8 ht20_tx_power_idx_diff[3]; - u8 ofdm_tx_power_idx_diff[3]; - u8 ht40_max_power_offset[3]; - u8 ht20_max_power_offset[3]; - u8 channel_plan; - u8 thermal_meter; - u8 rf_option[5]; - u8 version; - u8 oem_id; - u8 regulatory; -}; - -struct tx_power_struct { - u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_txpowerdiff; - u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 pwrgroup_cnt; - u32 mcs_original_offset[4][16]; -}; - -extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, - long power_indbm); -extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, - u8 operation); -extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); -extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, - u16 beaconinterval); -void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); -void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); -void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); -bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, - u32 rfpath); -bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); -void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); -void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); -bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -void rtl92c_phy_set_io(struct ieee80211_hw *hw); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h deleted file mode 100644 index 875d51465225..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h +++ /dev/null @@ -1,2065 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_REG_H__ -#define __RTL92C_REG_H__ - -#define REG_SYS_ISO_CTRL 0x0000 -#define REG_SYS_FUNC_EN 0x0002 -#define REG_APS_FSMCO 0x0004 -#define REG_SYS_CLKR 0x0008 -#define REG_9346CR 0x000A -#define REG_EE_VPD 0x000C -#define REG_AFE_MISC 0x0010 -#define REG_SPS0_CTRL 0x0011 -#define REG_SPS_OCP_CFG 0x0018 -#define REG_RSV_CTRL 0x001C -#define REG_RF_CTRL 0x001F -#define REG_LDOA15_CTRL 0x0020 -#define REG_LDOV12D_CTRL 0x0021 -#define REG_LDOHCI12_CTRL 0x0022 -#define REG_LPLDO_CTRL 0x0023 -#define REG_AFE_XTAL_CTRL 0x0024 -#define REG_AFE_PLL_CTRL 0x0028 -#define REG_EFUSE_CTRL 0x0030 -#define REG_EFUSE_TEST 0x0034 -#define REG_PWR_DATA 0x0038 -#define REG_CAL_TIMER 0x003C -#define REG_ACLK_MON 0x003E -#define REG_GPIO_MUXCFG 0x0040 -#define REG_GPIO_IO_SEL 0x0042 -#define REG_MAC_PINMUX_CFG 0x0043 -#define REG_GPIO_PIN_CTRL 0x0044 -#define REG_GPIO_INTM 0x0048 -#define REG_LEDCFG0 0x004C -#define REG_LEDCFG1 0x004D -#define REG_LEDCFG2 0x004E -#define REG_LEDCFG3 0x004F -#define REG_FSIMR 0x0050 -#define REG_FSISR 0x0054 - -#define REG_MCUFWDL 0x0080 - -#define REG_HMEBOX_EXT_0 0x0088 -#define REG_HMEBOX_EXT_1 0x008A -#define REG_HMEBOX_EXT_2 0x008C -#define REG_HMEBOX_EXT_3 0x008E - -#define REG_BIST_SCAN 0x00D0 -#define REG_BIST_RPT 0x00D4 -#define REG_BIST_ROM_RPT 0x00D8 -#define REG_USB_SIE_INTF 0x00E0 -#define REG_PCIE_MIO_INTF 0x00E4 -#define REG_PCIE_MIO_INTD 0x00E8 -#define REG_HPON_FSM 0x00EC -#define REG_SYS_CFG 0x00F0 - -#define REG_CR 0x0100 -#define REG_PBP 0x0104 -#define REG_TRXDMA_CTRL 0x010C -#define REG_TRXFF_BNDY 0x0114 -#define REG_TRXFF_STATUS 0x0118 -#define REG_RXFF_PTR 0x011C -#define REG_HIMR 0x0120 -#define REG_HISR 0x0124 -#define REG_HIMRE 0x0128 -#define REG_HISRE 0x012C -#define REG_CPWM 0x012F -#define REG_FWIMR 0x0130 -#define REG_FWISR 0x0134 -#define REG_PKTBUF_DBG_CTRL 0x0140 -#define REG_PKTBUF_DBG_DATA_L 0x0144 -#define REG_PKTBUF_DBG_DATA_H 0x0148 - -#define REG_TC0_CTRL 0x0150 -#define REG_TC1_CTRL 0x0154 -#define REG_TC2_CTRL 0x0158 -#define REG_TC3_CTRL 0x015C -#define REG_TC4_CTRL 0x0160 -#define REG_TCUNIT_BASE 0x0164 -#define REG_MBIST_START 0x0174 -#define REG_MBIST_DONE 0x0178 -#define REG_MBIST_FAIL 0x017C -#define REG_C2HEVT_MSG_NORMAL 0x01A0 -#define REG_C2HEVT_MSG_TEST 0x01B8 -#define REG_C2HEVT_CLEAR 0x01BF -#define REG_MCUTST_1 0x01c0 -#define REG_FMETHR 0x01C8 -#define REG_HMETFR 0x01CC -#define REG_HMEBOX_0 0x01D0 -#define REG_HMEBOX_1 0x01D4 -#define REG_HMEBOX_2 0x01D8 -#define REG_HMEBOX_3 0x01DC - -#define REG_LLT_INIT 0x01E0 -#define REG_BB_ACCEESS_CTRL 0x01E8 -#define REG_BB_ACCESS_DATA 0x01EC - -#define REG_RQPN 0x0200 -#define REG_FIFOPAGE 0x0204 -#define REG_TDECTRL 0x0208 -#define REG_TXDMA_OFFSET_CHK 0x020C -#define REG_TXDMA_STATUS 0x0210 -#define REG_RQPN_NPQ 0x0214 - -#define REG_RXDMA_AGG_PG_TH 0x0280 -#define REG_RXPKT_NUM 0x0284 -#define REG_RXDMA_STATUS 0x0288 - -#define REG_PCIE_CTRL_REG 0x0300 -#define REG_INT_MIG 0x0304 -#define REG_BCNQ_DESA 0x0308 -#define REG_HQ_DESA 0x0310 -#define REG_MGQ_DESA 0x0318 -#define REG_VOQ_DESA 0x0320 -#define REG_VIQ_DESA 0x0328 -#define REG_BEQ_DESA 0x0330 -#define REG_BKQ_DESA 0x0338 -#define REG_RX_DESA 0x0340 -#define REG_DBI 0x0348 -#define REG_MDIO 0x0354 -#define REG_DBG_SEL 0x0360 -#define REG_PCIE_HRPWM 0x0361 -#define REG_PCIE_HCPWM 0x0363 -#define REG_UART_CTRL 0x0364 -#define REG_UART_TX_DESA 0x0370 -#define REG_UART_RX_DESA 0x0378 - -#define REG_HDAQ_DESA_NODEF 0x0000 -#define REG_CMDQ_DESA_NODEF 0x0000 - -#define REG_VOQ_INFORMATION 0x0400 -#define REG_VIQ_INFORMATION 0x0404 -#define REG_BEQ_INFORMATION 0x0408 -#define REG_BKQ_INFORMATION 0x040C -#define REG_MGQ_INFORMATION 0x0410 -#define REG_HGQ_INFORMATION 0x0414 -#define REG_BCNQ_INFORMATION 0x0418 - -#define REG_CPU_MGQ_INFORMATION 0x041C -#define REG_FWHW_TXQ_CTRL 0x0420 -#define REG_HWSEQ_CTRL 0x0423 -#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 -#define REG_TXPKTBUF_MGQ_BDNY 0x0425 -#define REG_MULTI_BCNQ_EN 0x0426 -#define REG_MULTI_BCNQ_OFFSET 0x0427 -#define REG_SPEC_SIFS 0x0428 -#define REG_RL 0x042A -#define REG_DARFRC 0x0430 -#define REG_RARFRC 0x0438 -#define REG_RRSR 0x0440 -#define REG_ARFR0 0x0444 -#define REG_ARFR1 0x0448 -#define REG_ARFR2 0x044C -#define REG_ARFR3 0x0450 -#define REG_AGGLEN_LMT 0x0458 -#define REG_AMPDU_MIN_SPACE 0x045C -#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D -#define REG_FAST_EDCA_CTRL 0x0460 -#define REG_RD_RESP_PKT_TH 0x0463 -#define REG_INIRTS_RATE_SEL 0x0480 -#define REG_INIDATA_RATE_SEL 0x0484 -#define REG_POWER_STATUS 0x04A4 -#define REG_POWER_STAGE1 0x04B4 -#define REG_POWER_STAGE2 0x04B8 -#define REG_PKT_LIFE_TIME 0x04C0 -#define REG_STBC_SETTING 0x04C4 -#define REG_PROT_MODE_CTRL 0x04C8 -#define REG_BAR_MODE_CTRL 0x04CC -#define REG_RA_TRY_RATE_AGG_LMT 0x04CF -#define REG_NQOS_SEQ 0x04DC -#define REG_QOS_SEQ 0x04DE -#define REG_NEED_CPU_HANDLE 0x04E0 -#define REG_PKT_LOSE_RPT 0x04E1 -#define REG_PTCL_ERR_STATUS 0x04E2 -#define REG_DUMMY 0x04FC - -#define REG_EDCA_VO_PARAM 0x0500 -#define REG_EDCA_VI_PARAM 0x0504 -#define REG_EDCA_BE_PARAM 0x0508 -#define REG_EDCA_BK_PARAM 0x050C -#define REG_BCNTCFG 0x0510 -#define REG_PIFS 0x0512 -#define REG_RDG_PIFS 0x0513 -#define REG_SIFS_CTX 0x0514 -#define REG_SIFS_TRX 0x0516 -#define REG_AGGR_BREAK_TIME 0x051A -#define REG_SLOT 0x051B -#define REG_TX_PTCL_CTRL 0x0520 -#define REG_TXPAUSE 0x0522 -#define REG_DIS_TXREQ_CLR 0x0523 -#define REG_RD_CTRL 0x0524 -#define REG_TBTT_PROHIBIT 0x0540 -#define REG_RD_NAV_NXT 0x0544 -#define REG_NAV_PROT_LEN 0x0546 -#define REG_BCN_CTRL 0x0550 -#define REG_USTIME_TSF 0x0551 -#define REG_MBID_NUM 0x0552 -#define REG_DUAL_TSF_RST 0x0553 -#define REG_BCN_INTERVAL 0x0554 -#define REG_MBSSID_BCN_SPACE 0x0554 -#define REG_DRVERLYINT 0x0558 -#define REG_BCNDMATIM 0x0559 -#define REG_ATIMWND 0x055A -#define REG_BCN_MAX_ERR 0x055D -#define REG_RXTSF_OFFSET_CCK 0x055E -#define REG_RXTSF_OFFSET_OFDM 0x055F -#define REG_TSFTR 0x0560 -#define REG_INIT_TSFTR 0x0564 -#define REG_PSTIMER 0x0580 -#define REG_TIMER0 0x0584 -#define REG_TIMER1 0x0588 -#define REG_ACMHWCTRL 0x05C0 -#define REG_ACMRSTCTRL 0x05C1 -#define REG_ACMAVG 0x05C2 -#define REG_VO_ADMTIME 0x05C4 -#define REG_VI_ADMTIME 0x05C6 -#define REG_BE_ADMTIME 0x05C8 -#define REG_EDCA_RANDOM_GEN 0x05CC -#define REG_SCH_TXCMD 0x05D0 - -#define REG_APSD_CTRL 0x0600 -#define REG_BWOPMODE 0x0603 -#define REG_TCR 0x0604 -#define REG_RCR 0x0608 -#define REG_RX_PKT_LIMIT 0x060C -#define REG_RX_DLK_TIME 0x060D -#define REG_RX_DRVINFO_SZ 0x060F - -#define REG_MACID 0x0610 -#define REG_BSSID 0x0618 -#define REG_MAR 0x0620 -#define REG_MBIDCAMCFG 0x0628 - -#define REG_USTIME_EDCA 0x0638 -#define REG_MAC_SPEC_SIFS 0x063A -#define REG_RESP_SIFS_CCK 0x063C -#define REG_RESP_SIFS_OFDM 0x063E -#define REG_ACKTO 0x0640 -#define REG_CTS2TO 0x0641 -#define REG_EIFS 0x0642 - -#define REG_NAV_CTRL 0x0650 -#define REG_BACAMCMD 0x0654 -#define REG_BACAMCONTENT 0x0658 -#define REG_LBDLY 0x0660 -#define REG_FWDLY 0x0661 -#define REG_RXERR_RPT 0x0664 -#define REG_WMAC_TRXPTCL_CTL 0x0668 - -#define REG_CAMCMD 0x0670 -#define REG_CAMWRITE 0x0674 -#define REG_CAMREAD 0x0678 -#define REG_CAMDBG 0x067C -#define REG_SECCFG 0x0680 - -#define REG_WOW_CTRL 0x0690 -#define REG_PSSTATUS 0x0691 -#define REG_PS_RX_INFO 0x0692 -#define REG_LPNAV_CTRL 0x0694 -#define REG_WKFMCAM_CMD 0x0698 -#define REG_WKFMCAM_RWD 0x069C -#define REG_RXFLTMAP0 0x06A0 -#define REG_RXFLTMAP1 0x06A2 -#define REG_RXFLTMAP2 0x06A4 -#define REG_BCN_PSR_RPT 0x06A8 -#define REG_CALB32K_CTRL 0x06AC -#define REG_PKT_MON_CTRL 0x06B4 -#define REG_BT_COEX_TABLE 0x06C0 -#define REG_WMAC_RESP_TXINFO 0x06D8 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_TEST_USB_TXQS 0xFE48 -#define REG_TEST_SIE_VID 0xFE60 -#define REG_TEST_SIE_PID 0xFE62 -#define REG_TEST_SIE_OPTIONAL 0xFE64 -#define REG_TEST_SIE_CHIRP_K 0xFE65 -#define REG_TEST_SIE_PHY 0xFE66 -#define REG_TEST_SIE_MAC_ADDR 0xFE70 -#define REG_TEST_SIE_STRING 0xFE80 - -#define REG_NORMAL_SIE_VID 0xFE60 -#define REG_NORMAL_SIE_PID 0xFE62 -#define REG_NORMAL_SIE_OPTIONAL 0xFE64 -#define REG_NORMAL_SIE_EP 0xFE65 -#define REG_NORMAL_SIE_PHY 0xFE68 -#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 -#define REG_NORMAL_SIE_STRING 0xFE80 - -#define CR9346 REG_9346CR -#define MSR (REG_CR + 2) -#define ISR REG_HISR -#define TSFR REG_TSFTR - -#define MACIDR0 REG_MACID -#define MACIDR4 (REG_MACID + 4) - -#define PBP REG_PBP - -#define IDR0 MACIDR0 -#define IDR4 MACIDR4 - -#define UNUSED_REGISTER 0x1BF -#define DCAM UNUSED_REGISTER -#define PSR UNUSED_REGISTER -#define BBADDR UNUSED_REGISTER -#define PHYDATAR UNUSED_REGISTER - -#define INVALID_BBRF_VALUE 0x12345678 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define CMDEEPROM_EN BIT(5) -#define CMDEEPROM_SEL BIT(4) -#define CMD9346CR_9356SEL BIT(4) -#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) -#define AUTOLOAD_EFUSE CMDEEPROM_EN - -#define GPIOSEL_GPIO 0 -#define GPIOSEL_ENBT BIT(5) - -#define GPIO_IN REG_GPIO_PIN_CTRL -#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) -#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) -#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) - -#define MSR_NOLINK 0x00 -#define MSR_ADHOC 0x01 -#define MSR_INFRA 0x02 -#define MSR_AP 0x03 - -#define RRSR_RSC_OFFSET 21 -#define RRSR_SHORT_OFFSET 23 -#define RRSR_RSC_BW_40M 0x600000 -#define RRSR_RSC_UPSUBCHNL 0x400000 -#define RRSR_RSC_LOWSUBCHNL 0x200000 -#define RRSR_SHORT 0x800000 -#define RRSR_1M BIT(0) -#define RRSR_2M BIT(1) -#define RRSR_5_5M BIT(2) -#define RRSR_11M BIT(3) -#define RRSR_6M BIT(4) -#define RRSR_9M BIT(5) -#define RRSR_12M BIT(6) -#define RRSR_18M BIT(7) -#define RRSR_24M BIT(8) -#define RRSR_36M BIT(9) -#define RRSR_48M BIT(10) -#define RRSR_54M BIT(11) -#define RRSR_MCS0 BIT(12) -#define RRSR_MCS1 BIT(13) -#define RRSR_MCS2 BIT(14) -#define RRSR_MCS3 BIT(15) -#define RRSR_MCS4 BIT(16) -#define RRSR_MCS5 BIT(17) -#define RRSR_MCS6 BIT(18) -#define RRSR_MCS7 BIT(19) -#define BRSR_ACKSHORTPMB BIT(23) - -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 - -#define RATE_1M BIT(0) -#define RATE_2M BIT(1) -#define RATE_5_5M BIT(2) -#define RATE_11M BIT(3) -#define RATE_6M BIT(4) -#define RATE_9M BIT(5) -#define RATE_12M BIT(6) -#define RATE_18M BIT(7) -#define RATE_24M BIT(8) -#define RATE_36M BIT(9) -#define RATE_48M BIT(10) -#define RATE_54M BIT(11) -#define RATE_MCS0 BIT(12) -#define RATE_MCS1 BIT(13) -#define RATE_MCS2 BIT(14) -#define RATE_MCS3 BIT(15) -#define RATE_MCS4 BIT(16) -#define RATE_MCS5 BIT(17) -#define RATE_MCS6 BIT(18) -#define RATE_MCS7 BIT(19) -#define RATE_MCS8 BIT(20) -#define RATE_MCS9 BIT(21) -#define RATE_MCS10 BIT(22) -#define RATE_MCS11 BIT(23) -#define RATE_MCS12 BIT(24) -#define RATE_MCS13 BIT(25) -#define RATE_MCS14 BIT(26) -#define RATE_MCS15 BIT(27) - -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \ - | RATR_24M | RATR_36M | RATR_48M | RATR_54M) -#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ - RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ - RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ - RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ - RATR_MCS14 | RATR_MCS15) - -#define BW_OPMODE_20MHZ BIT(2) -#define BW_OPMODE_5G BIT(1) -#define BW_OPMODE_11J BIT(0) - -#define CAM_VALID BIT(15) -#define CAM_NOTVALID 0x0000 -#define CAM_USEDK BIT(5) - -#define CAM_NONE 0x0 -#define CAM_WEP40 0x01 -#define CAM_TKIP 0x02 -#define CAM_AES 0x04 -#define CAM_WEP104 0x05 - -#define TOTAL_CAM_ENTRY 32 -#define HALF_CAM_ENTRY 16 - -#define CAM_WRITE BIT(16) -#define CAM_READ 0x00000000 -#define CAM_POLLINIG BIT(31) - -#define SCR_USEDK 0x01 -#define SCR_TXSEC_ENABLE 0x02 -#define SCR_RXSEC_ENABLE 0x04 - -#define WOW_PMEN BIT(0) -#define WOW_WOMEN BIT(1) -#define WOW_MAGIC BIT(2) -#define WOW_UWF BIT(3) - -#define IMR8190_DISABLED 0x0 -#define IMR_BCNDMAINT6 BIT(31) -#define IMR_BCNDMAINT5 BIT(30) -#define IMR_BCNDMAINT4 BIT(29) -#define IMR_BCNDMAINT3 BIT(28) -#define IMR_BCNDMAINT2 BIT(27) -#define IMR_BCNDMAINT1 BIT(26) -#define IMR_BCNDOK8 BIT(25) -#define IMR_BCNDOK7 BIT(24) -#define IMR_BCNDOK6 BIT(23) -#define IMR_BCNDOK5 BIT(22) -#define IMR_BCNDOK4 BIT(21) -#define IMR_BCNDOK3 BIT(20) -#define IMR_BCNDOK2 BIT(19) -#define IMR_BCNDOK1 BIT(18) -#define IMR_TIMEOUT2 BIT(17) -#define IMR_TIMEOUT1 BIT(16) -#define IMR_TXFOVW BIT(15) -#define IMR_PSTIMEOUT BIT(14) -#define IMR_BCNINT BIT(13) -#define IMR_RXFOVW BIT(12) -#define IMR_RDU BIT(11) -#define IMR_ATIMEND BIT(10) -#define IMR_BDOK BIT(9) -#define IMR_HIGHDOK BIT(8) -#define IMR_TBDOK BIT(7) -#define IMR_MGNTDOK BIT(6) -#define IMR_TBDER BIT(5) -#define IMR_BKDOK BIT(4) -#define IMR_BEDOK BIT(3) -#define IMR_VIDOK BIT(2) -#define IMR_VODOK BIT(1) -#define IMR_ROK BIT(0) - -#define IMR_TXERR BIT(11) -#define IMR_RXERR BIT(10) -#define IMR_C2HCMD BIT(9) -#define IMR_CPWM BIT(8) -#define IMR_OCPINT BIT(1) -#define IMR_WLANOFF BIT(0) - -#define HWSET_MAX_SIZE 128 - -#define EEPROM_DEFAULT_TSSI 0x0 -#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_BOARDTYPE 0x02 -#define EEPROM_DEFAULT_TXPOWER 0x1010 -#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 - -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_THERMALMETER 0x12 -#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 -#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 -#define EEPROM_DEFAULT_HT20_DIFF 2 -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 -#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 - -#define RF_OPTION1 0x79 -#define RF_OPTION2 0x7A -#define RF_OPTION3 0x7B -#define RF_OPTION4 0x7C - -#define EEPROM_DEFAULT_PID 0x1234 -#define EEPROM_DEFAULT_VID 0x5678 -#define EEPROM_DEFAULT_CUSTOMERID 0xAB -#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD -#define EEPROM_DEFAULT_VERSION 0 - -#define EEPROM_CHANNEL_PLAN_FCC 0x0 -#define EEPROM_CHANNEL_PLAN_IC 0x1 -#define EEPROM_CHANNEL_PLAN_ETSI 0x2 -#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 -#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 -#define EEPROM_CHANNEL_PLAN_MKK 0x5 -#define EEPROM_CHANNEL_PLAN_MKK1 0x6 -#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 -#define EEPROM_CHANNEL_PLAN_TELEC 0x8 -#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 -#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA -#define EEPROM_CHANNEL_PLAN_NCC 0xB -#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 - -#define EEPROM_CID_DEFAULT 0x0 -#define EEPROM_CID_TOSHIBA 0x4 -#define EEPROM_CID_CCX 0x10 -#define EEPROM_CID_QMI 0x0D -#define EEPROM_CID_WHQL 0xFE - -#define RTL8192_EEPROM_ID 0x8129 - -#define RTL8190_EEPROM_ID 0x8129 -#define EEPROM_HPON 0x02 -#define EEPROM_CLK 0x06 -#define EEPROM_TESTR 0x08 - -#define EEPROM_VID 0x0A -#define EEPROM_DID 0x0C -#define EEPROM_SVID 0x0E -#define EEPROM_SMID 0x10 - -#define EEPROM_MAC_ADDR 0x16 - -#define EEPROM_CCK_TX_PWR_INX 0x5A -#define EEPROM_HT40_1S_TX_PWR_INX 0x60 -#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 -#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 -#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C -#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F -#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 - -#define EEPROM_TSSI_A 0x76 -#define EEPROM_TSSI_B 0x77 -#define EEPROM_THERMAL_METER 0x78 -#define EEPROM_XTAL_K 0x78 -#define EEPROM_RF_OPT1 0x79 -#define EEPROM_RF_OPT2 0x7A -#define EEPROM_RF_OPT3 0x7B -#define EEPROM_RF_OPT4 0x7C -#define EEPROM_CHANNEL_PLAN 0x7D -#define EEPROM_VERSION 0x7E -#define EEPROM_CUSTOMER_ID 0x7F - -#define EEPROM_PWRDIFF 0x54 - -#define EEPROM_TXPOWERCCK 0x5A -#define EEPROM_TXPOWERHT40_1S 0x60 -#define EEPROM_TXPOWERHT40_2SDIFF 0x66 -#define EEPROM_TXPOWERHT20DIFF 0x69 -#define EEPROM_TXPOWER_OFDMDIFF 0x6C - -#define EEPROM_TXPWR_GROUP 0x6F - -#define EEPROM_TSSI_A 0x76 -#define EEPROM_TSSI_B 0x77 -#define EEPROM_THERMAL_METER 0x78 - -#define EEPROM_CHANNELPLAN 0x75 - -#define RF_OPTION1 0x79 -#define RF_OPTION2 0x7A -#define RF_OPTION3 0x7B -#define RF_OPTION4 0x7C - -#define STOPBECON BIT(6) -#define STOPHIGHT BIT(5) -#define STOPMGT BIT(4) -#define STOPVO BIT(3) -#define STOPVI BIT(2) -#define STOPBE BIT(1) -#define STOPBK BIT(0) - -#define RCR_APPFCS BIT(31) -#define RCR_APP_MIC BIT(30) -#define RCR_APP_ICV BIT(29) -#define RCR_APP_PHYST_RXFF BIT(28) -#define RCR_APP_BA_SSN BIT(27) -#define RCR_ENMBID BIT(24) -#define RCR_LSIGEN BIT(23) -#define RCR_MFBEN BIT(22) -#define RCR_HTC_LOC_CTRL BIT(14) -#define RCR_AMF BIT(13) -#define RCR_ACF BIT(12) -#define RCR_ADF BIT(11) -#define RCR_AICV BIT(9) -#define RCR_ACRC32 BIT(8) -#define RCR_CBSSID_BCN BIT(7) -#define RCR_CBSSID_DATA BIT(6) -#define RCR_CBSSID RCR_CBSSID_DATA -#define RCR_APWRMGT BIT(5) -#define RCR_ADD3 BIT(4) -#define RCR_AB BIT(3) -#define RCR_AM BIT(2) -#define RCR_APM BIT(1) -#define RCR_AAP BIT(0) -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 - -#define RSV_CTRL 0x001C -#define RD_CTRL 0x0524 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_USB_VID 0xFE60 -#define REG_USB_PID 0xFE62 -#define REG_USB_OPTIONAL 0xFE64 -#define REG_USB_CHIRP_K 0xFE65 -#define REG_USB_PHY 0xFE66 -#define REG_USB_MAC_ADDR 0xFE70 -#define REG_USB_HRPWM 0xFE58 -#define REG_USB_HCPWM 0xFE57 - -#define SW18_FPWM BIT(3) - -#define ISO_MD2PP BIT(0) -#define ISO_UA2USB BIT(1) -#define ISO_UD2CORE BIT(2) -#define ISO_PA2PCIE BIT(3) -#define ISO_PD2CORE BIT(4) -#define ISO_IP2MAC BIT(5) -#define ISO_DIOP BIT(6) -#define ISO_DIOE BIT(7) -#define ISO_EB2CORE BIT(8) -#define ISO_DIOR BIT(9) - -#define PWC_EV25V BIT(14) -#define PWC_EV12V BIT(15) - -#define FEN_BBRSTB BIT(0) -#define FEN_BB_GLB_RSTn BIT(1) -#define FEN_USBA BIT(2) -#define FEN_UPLL BIT(3) -#define FEN_USBD BIT(4) -#define FEN_DIO_PCIE BIT(5) -#define FEN_PCIEA BIT(6) -#define FEN_PPLL BIT(7) -#define FEN_PCIED BIT(8) -#define FEN_DIOE BIT(9) -#define FEN_CPUEN BIT(10) -#define FEN_DCORE BIT(11) -#define FEN_ELDR BIT(12) -#define FEN_DIO_RF BIT(13) -#define FEN_HWPDN BIT(14) -#define FEN_MREGEN BIT(15) - -#define PFM_LDALL BIT(0) -#define PFM_ALDN BIT(1) -#define PFM_LDKP BIT(2) -#define PFM_WOWL BIT(3) -#define EnPDN BIT(4) -#define PDN_PL BIT(5) -#define APFM_ONMAC BIT(8) -#define APFM_OFF BIT(9) -#define APFM_RSM BIT(10) -#define AFSM_HSUS BIT(11) -#define AFSM_PCIE BIT(12) -#define APDM_MAC BIT(13) -#define APDM_HOST BIT(14) -#define APDM_HPDN BIT(15) -#define RDY_MACON BIT(16) -#define SUS_HOST BIT(17) -#define ROP_ALD BIT(20) -#define ROP_PWR BIT(21) -#define ROP_SPS BIT(22) -#define SOP_MRST BIT(25) -#define SOP_FUSE BIT(26) -#define SOP_ABG BIT(27) -#define SOP_AMB BIT(28) -#define SOP_RCK BIT(29) -#define SOP_A8M BIT(30) -#define XOP_BTCK BIT(31) - -#define ANAD16V_EN BIT(0) -#define ANA8M BIT(1) -#define MACSLP BIT(4) -#define LOADER_CLK_EN BIT(5) -#define _80M_SSC_DIS BIT(7) -#define _80M_SSC_EN_HO BIT(8) -#define PHY_SSC_RSTB BIT(9) -#define SEC_CLK_EN BIT(10) -#define MAC_CLK_EN BIT(11) -#define SYS_CLK_EN BIT(12) -#define RING_CLK_EN BIT(13) - -#define BOOT_FROM_EEPROM BIT(4) -#define EEPROM_EN BIT(5) - -#define AFE_BGEN BIT(0) -#define AFE_MBEN BIT(1) -#define MAC_ID_EN BIT(7) - -#define WLOCK_ALL BIT(0) -#define WLOCK_00 BIT(1) -#define WLOCK_04 BIT(2) -#define WLOCK_08 BIT(3) -#define WLOCK_40 BIT(4) -#define R_DIS_PRST_0 BIT(5) -#define R_DIS_PRST_1 BIT(6) -#define LOCK_ALL_EN BIT(7) - -#define RF_EN BIT(0) -#define RF_RSTB BIT(1) -#define RF_SDMRSTB BIT(2) - -#define LDA15_EN BIT(0) -#define LDA15_STBY BIT(1) -#define LDA15_OBUF BIT(2) -#define LDA15_REG_VOS BIT(3) -#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) - -#define LDV12_EN BIT(0) -#define LDV12_SDBY BIT(1) -#define LPLDO_HSM BIT(2) -#define LPLDO_LSM_DIS BIT(3) -#define _LDV12_VADJ(x) (((x) & 0xF) << 4) - -#define XTAL_EN BIT(0) -#define XTAL_BSEL BIT(1) -#define _XTAL_BOSC(x) (((x) & 0x3) << 2) -#define _XTAL_CADJ(x) (((x) & 0xF) << 4) -#define XTAL_GATE_USB BIT(8) -#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) -#define XTAL_GATE_AFE BIT(11) -#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) -#define XTAL_RF_GATE BIT(14) -#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) -#define XTAL_GATE_DIG BIT(17) -#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) -#define XTAL_BT_GATE BIT(20) -#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) -#define _XTAL_GPIO(x) (((x) & 0x7) << 23) - -#define CKDLY_AFE BIT(26) -#define CKDLY_USB BIT(27) -#define CKDLY_DIG BIT(28) -#define CKDLY_BT BIT(29) - -#define APLL_EN BIT(0) -#define APLL_320_EN BIT(1) -#define APLL_FREF_SEL BIT(2) -#define APLL_EDGE_SEL BIT(3) -#define APLL_WDOGB BIT(4) -#define APLL_LPFEN BIT(5) - -#define APLL_REF_CLK_13MHZ 0x1 -#define APLL_REF_CLK_19_2MHZ 0x2 -#define APLL_REF_CLK_20MHZ 0x3 -#define APLL_REF_CLK_25MHZ 0x4 -#define APLL_REF_CLK_26MHZ 0x5 -#define APLL_REF_CLK_38_4MHZ 0x6 -#define APLL_REF_CLK_40MHZ 0x7 - -#define APLL_320EN BIT(14) -#define APLL_80EN BIT(15) -#define APLL_1MEN BIT(24) - -#define ALD_EN BIT(18) -#define EF_PD BIT(19) -#define EF_FLAG BIT(31) - -#define EF_TRPT BIT(7) -#define LDOE25_EN BIT(31) - -#define RSM_EN BIT(0) -#define Timer_EN BIT(4) - -#define TRSW0EN BIT(2) -#define TRSW1EN BIT(3) -#define EROM_EN BIT(4) -#define EnBT BIT(5) -#define EnUart BIT(8) -#define Uart_910 BIT(9) -#define EnPMAC BIT(10) -#define SIC_SWRST BIT(11) -#define EnSIC BIT(12) -#define SIC_23 BIT(13) -#define EnHDP BIT(14) -#define SIC_LBK BIT(15) - -#define LED0PL BIT(4) -#define LED1PL BIT(12) -#define LED0DIS BIT(7) - -#define MCUFWDL_EN BIT(0) -#define MCUFWDL_RDY BIT(1) -#define FWDL_ChkSum_rpt BIT(2) -#define MACINI_RDY BIT(3) -#define BBINI_RDY BIT(4) -#define RFINI_RDY BIT(5) -#define WINTINI_RDY BIT(6) -#define CPRST BIT(23) - -#define XCLK_VLD BIT(0) -#define ACLK_VLD BIT(1) -#define UCLK_VLD BIT(2) -#define PCLK_VLD BIT(3) -#define PCIRSTB BIT(4) -#define V15_VLD BIT(5) -#define TRP_B15V_EN BIT(7) -#define SIC_IDLE BIT(8) -#define BD_MAC2 BIT(9) -#define BD_MAC1 BIT(10) -#define IC_MACPHY_MODE BIT(11) -#define PAD_HWPD_IDN BIT(22) -#define TRP_VAUX_EN BIT(23) -#define TRP_BT_EN BIT(24) -#define BD_PKG_SEL BIT(25) -#define BD_HCI_SEL BIT(26) -#define TYPE_ID BIT(27) - -#define CHIP_VER_RTL_MASK 0xF000 -#define CHIP_VER_RTL_SHIFT 12 - -#define REG_LBMODE (REG_CR + 3) - -#define HCI_TXDMA_EN BIT(0) -#define HCI_RXDMA_EN BIT(1) -#define TXDMA_EN BIT(2) -#define RXDMA_EN BIT(3) -#define PROTOCOL_EN BIT(4) -#define SCHEDULE_EN BIT(5) -#define MACTXEN BIT(6) -#define MACRXEN BIT(7) -#define ENSWBCN BIT(8) -#define ENSEC BIT(9) - -#define _NETTYPE(x) (((x) & 0x3) << 16) -#define MASK_NETTYPE 0x30000 -#define NT_NO_LINK 0x0 -#define NT_LINK_AD_HOC 0x1 -#define NT_LINK_AP 0x2 -#define NT_AS_AP 0x3 - -#define _LBMODE(x) (((x) & 0xF) << 24) -#define MASK_LBMODE 0xF000000 -#define LOOPBACK_NORMAL 0x0 -#define LOOPBACK_IMMEDIATELY 0xB -#define LOOPBACK_MAC_DELAY 0x3 -#define LOOPBACK_PHY 0x1 -#define LOOPBACK_DMA 0x7 - -#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) -#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) -#define _PSRX_MASK 0xF -#define _PSTX_MASK 0xF0 -#define _PSRX(x) (x) -#define _PSTX(x) ((x) << 4) - -#define PBP_64 0x0 -#define PBP_128 0x1 -#define PBP_256 0x2 -#define PBP_512 0x3 -#define PBP_1024 0x4 - -#define RXDMA_ARBBW_EN BIT(0) -#define RXSHFT_EN BIT(1) -#define RXDMA_AGG_EN BIT(2) -#define QS_VO_QUEUE BIT(8) -#define QS_VI_QUEUE BIT(9) -#define QS_BE_QUEUE BIT(10) -#define QS_BK_QUEUE BIT(11) -#define QS_MANAGER_QUEUE BIT(12) -#define QS_HIGH_QUEUE BIT(13) - -#define HQSEL_VOQ BIT(0) -#define HQSEL_VIQ BIT(1) -#define HQSEL_BEQ BIT(2) -#define HQSEL_BKQ BIT(3) -#define HQSEL_MGTQ BIT(4) -#define HQSEL_HIQ BIT(5) - -#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) -#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) -#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) -#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) -#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) -#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) - -#define QUEUE_LOW 1 -#define QUEUE_NORMAL 2 -#define QUEUE_HIGH 3 - -#define _LLT_NO_ACTIVE 0x0 -#define _LLT_WRITE_ACCESS 0x1 -#define _LLT_READ_ACCESS 0x2 - -#define _LLT_INIT_DATA(x) ((x) & 0xFF) -#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) -#define _LLT_OP(x) (((x) & 0x3) << 30) -#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) - -#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) -#define BB_WRITE_EN BIT(30) -#define BB_READ_EN BIT(31) - -#define _HPQ(x) ((x) & 0xFF) -#define _LPQ(x) (((x) & 0xFF) << 8) -#define _PUBQ(x) (((x) & 0xFF) << 16) -#define _NPQ(x) ((x) & 0xFF) - -#define HPQ_PUBLIC_DIS BIT(24) -#define LPQ_PUBLIC_DIS BIT(25) -#define LD_RQPN BIT(31) - -#define BCN_VALID BIT(16) -#define BCN_HEAD(x) (((x) & 0xFF) << 8) -#define BCN_HEAD_MASK 0xFF00 - -#define BLK_DESC_NUM_SHIFT 4 -#define BLK_DESC_NUM_MASK 0xF - -#define DROP_DATA_EN BIT(9) - -#define EN_AMPDU_RTY_NEW BIT(7) - -#define _INIRTSMCS_SEL(x) ((x) & 0x3F) - -#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) -#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) - -#define RATE_REG_BITMAP_ALL 0xFFFFF - -#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) - -#define _RRSR_RSC(x) (((x) & 0x3) << 21) -#define RRSR_RSC_RESERVED 0x0 -#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 -#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 -#define RRSR_RSC_DUPLICATE_MODE 0x3 - -#define USE_SHORT_G1 BIT(20) - -#define _AGGLMT_MCS0(x) ((x) & 0xF) -#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) -#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) -#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) -#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) -#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) -#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) -#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) - -#define RETRY_LIMIT_SHORT_SHIFT 8 -#define RETRY_LIMIT_LONG_SHIFT 0 - -#define _DARF_RC1(x) ((x) & 0x1F) -#define _DARF_RC2(x) (((x) & 0x1F) << 8) -#define _DARF_RC3(x) (((x) & 0x1F) << 16) -#define _DARF_RC4(x) (((x) & 0x1F) << 24) -#define _DARF_RC5(x) ((x) & 0x1F) -#define _DARF_RC6(x) (((x) & 0x1F) << 8) -#define _DARF_RC7(x) (((x) & 0x1F) << 16) -#define _DARF_RC8(x) (((x) & 0x1F) << 24) - -#define _RARF_RC1(x) ((x) & 0x1F) -#define _RARF_RC2(x) (((x) & 0x1F) << 8) -#define _RARF_RC3(x) (((x) & 0x1F) << 16) -#define _RARF_RC4(x) (((x) & 0x1F) << 24) -#define _RARF_RC5(x) ((x) & 0x1F) -#define _RARF_RC6(x) (((x) & 0x1F) << 8) -#define _RARF_RC7(x) (((x) & 0x1F) << 16) -#define _RARF_RC8(x) (((x) & 0x1F) << 24) - -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - -#define _AIFS(x) (x) -#define _ECW_MAX_MIN(x) ((x) << 8) -#define _TXOP_LIMIT(x) ((x) << 16) - -#define _BCNIFS(x) ((x) & 0xFF) -#define _BCNECW(x) ((((x) & 0xF)) << 8) - -#define _LRL(x) ((x) & 0x3F) -#define _SRL(x) (((x) & 0x3F) << 8) - -#define _SIFS_CCK_CTX(x) ((x) & 0xFF) -#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); - -#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) -#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); - -#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) - -#define DIS_EDCA_CNT_DWN BIT(11) - -#define EN_MBSSID BIT(1) -#define EN_TXBCN_RPT BIT(2) -#define EN_BCN_FUNCTION BIT(3) - -#define TSFTR_RST BIT(0) -#define TSFTR1_RST BIT(1) - -#define STOP_BCNQ BIT(6) - -#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) -#define DIS_TSF_UDT0_TEST_CHIP BIT(5) - -#define AcmHw_HwEn BIT(0) -#define AcmHw_BeqEn BIT(1) -#define AcmHw_ViqEn BIT(2) -#define AcmHw_VoqEn BIT(3) -#define AcmHw_BeqStatus BIT(4) -#define AcmHw_ViqStatus BIT(5) -#define AcmHw_VoqStatus BIT(6) - -#define APSDOFF BIT(6) -#define APSDOFF_STATUS BIT(7) - -#define BW_20MHZ BIT(2) - -#define RATE_BITMAP_ALL 0xFFFFF - -#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 - -#define TSFRST BIT(0) -#define DIS_GCLK BIT(1) -#define PAD_SEL BIT(2) -#define PWR_ST BIT(6) -#define PWRBIT_OW_EN BIT(7) -#define ACRC BIT(8) -#define CFENDFORM BIT(9) -#define ICV BIT(10) - -#define AAP BIT(0) -#define APM BIT(1) -#define AM BIT(2) -#define AB BIT(3) -#define ADD3 BIT(4) -#define APWRMGT BIT(5) -#define CBSSID BIT(6) -#define CBSSID_DATA BIT(6) -#define CBSSID_BCN BIT(7) -#define ACRC32 BIT(8) -#define AICV BIT(9) -#define ADF BIT(11) -#define ACF BIT(12) -#define AMF BIT(13) -#define HTC_LOC_CTRL BIT(14) -#define UC_DATA_EN BIT(16) -#define BM_DATA_EN BIT(17) -#define MFBEN BIT(22) -#define LSIGEN BIT(23) -#define EnMBID BIT(24) -#define APP_BASSN BIT(27) -#define APP_PHYSTS BIT(28) -#define APP_ICV BIT(29) -#define APP_MIC BIT(30) -#define APP_FCS BIT(31) - -#define _MIN_SPACE(x) ((x) & 0x7) -#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) - -#define RXERR_TYPE_OFDM_PPDU 0 -#define RXERR_TYPE_OFDM_FALSE_ALARM 1 -#define RXERR_TYPE_OFDM_MPDU_OK 2 -#define RXERR_TYPE_OFDM_MPDU_FAIL 3 -#define RXERR_TYPE_CCK_PPDU 4 -#define RXERR_TYPE_CCK_FALSE_ALARM 5 -#define RXERR_TYPE_CCK_MPDU_OK 6 -#define RXERR_TYPE_CCK_MPDU_FAIL 7 -#define RXERR_TYPE_HT_PPDU 8 -#define RXERR_TYPE_HT_FALSE_ALARM 9 -#define RXERR_TYPE_HT_MPDU_TOTAL 10 -#define RXERR_TYPE_HT_MPDU_OK 11 -#define RXERR_TYPE_HT_MPDU_FAIL 12 -#define RXERR_TYPE_RX_FULL_DROP 15 - -#define RXERR_COUNTER_MASK 0xFFFFF -#define RXERR_RPT_RST BIT(27) -#define _RXERR_RPT_SEL(type) ((type) << 28) - -#define SCR_TxUseDK BIT(0) -#define SCR_RxUseDK BIT(1) -#define SCR_TxEncEnable BIT(2) -#define SCR_RxDecEnable BIT(3) -#define SCR_SKByA2 BIT(4) -#define SCR_NoSKMC BIT(5) -#define SCR_TXBCUSEDK BIT(6) -#define SCR_RXBCUSEDK BIT(7) - -#define USB_IS_HIGH_SPEED 0 -#define USB_IS_FULL_SPEED 1 -#define USB_SPEED_MASK BIT(5) - -#define USB_NORMAL_SIE_EP_MASK 0xF -#define USB_NORMAL_SIE_EP_SHIFT 4 - -#define USB_TEST_EP_MASK 0x30 -#define USB_TEST_EP_SHIFT 4 - -#define USB_AGG_EN BIT(3) - -#define MAC_ADDR_LEN 6 -#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 - -#define POLLING_LLT_THRESHOLD 20 -#define POLLING_READY_TIMEOUT_COUNT 1000 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) -#define EPROM_CMD_CONFIG 0x3 -#define EPROM_CMD_LOAD 1 - -#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE - -#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) - -#define RPMAC_RESET 0x100 -#define RPMAC_TXSTART 0x104 -#define RPMAC_TXLEGACYSIG 0x108 -#define RPMAC_TXHTSIG1 0x10c -#define RPMAC_TXHTSIG2 0x110 -#define RPMAC_PHYDEBUG 0x114 -#define RPMAC_TXPACKETNUM 0x118 -#define RPMAC_TXIDLE 0x11c -#define RPMAC_TXMACHEADER0 0x120 -#define RPMAC_TXMACHEADER1 0x124 -#define RPMAC_TXMACHEADER2 0x128 -#define RPMAC_TXMACHEADER3 0x12c -#define RPMAC_TXMACHEADER4 0x130 -#define RPMAC_TXMACHEADER5 0x134 -#define RPMAC_TXDADATYPE 0x138 -#define RPMAC_TXRANDOMSEED 0x13c -#define RPMAC_CCKPLCPPREAMBLE 0x140 -#define RPMAC_CCKPLCPHEADER 0x144 -#define RPMAC_CCKCRC16 0x148 -#define RPMAC_OFDMRXCRC32OK 0x170 -#define RPMAC_OFDMRXCRC32Er 0x174 -#define RPMAC_OFDMRXPARITYER 0x178 -#define RPMAC_OFDMRXCRC8ER 0x17c -#define RPMAC_CCKCRXRC16ER 0x180 -#define RPMAC_CCKCRXRC32ER 0x184 -#define RPMAC_CCKCRXRC32OK 0x188 -#define RPMAC_TXSTATUS 0x18c - -#define RFPGA0_RFMOD 0x800 - -#define RFPGA0_TXINFO 0x804 -#define RFPGA0_PSDFUNCTION 0x808 - -#define RFPGA0_TXGAINSTAGE 0x80c - -#define RFPGA0_RFTIMING1 0x810 -#define RFPGA0_RFTIMING2 0x814 - -#define RFPGA0_XA_HSSIPARAMETER1 0x820 -#define RFPGA0_XA_HSSIPARAMETER2 0x824 -#define RFPGA0_XB_HSSIPARAMETER1 0x828 -#define RFPGA0_XB_HSSIPARAMETER2 0x82c - -#define RFPGA0_XA_LSSIPARAMETER 0x840 -#define RFPGA0_XB_LSSIPARAMETER 0x844 - -#define RFPGA0_RFWAKEUPPARAMETER 0x850 -#define RFPGA0_RFSLEEPUPPARAMETER 0x854 - -#define RFPGA0_XAB_SWITCHCONTROL 0x858 -#define RFPGA0_XCD_SWITCHCONTROL 0x85c - -#define RFPGA0_XA_RFINTERFACEOE 0x860 -#define RFPGA0_XB_RFINTERFACEOE 0x864 - -#define RFPGA0_XAB_RFINTERFACESW 0x870 -#define RFPGA0_XCD_RFINTERFACESW 0x874 - -#define rFPGA0_XAB_RFPARAMETER 0x878 -#define rFPGA0_XCD_RFPARAMETER 0x87c - -#define RFPGA0_ANALOGPARAMETER1 0x880 -#define RFPGA0_ANALOGPARAMETER2 0x884 -#define RFPGA0_ANALOGPARAMETER3 0x888 -#define RFPGA0_ANALOGPARAMETER4 0x88c - -#define RFPGA0_XA_LSSIREADBACK 0x8a0 -#define RFPGA0_XB_LSSIREADBACK 0x8a4 -#define RFPGA0_XC_LSSIREADBACK 0x8a8 -#define RFPGA0_XD_LSSIREADBACK 0x8ac - -#define RFPGA0_PSDREPORT 0x8b4 -#define TRANSCEIVEA_HSPI_READBACK 0x8b8 -#define TRANSCEIVEB_HSPI_READBACK 0x8bc -#define RFPGA0_XAB_RFINTERFACERB 0x8e0 -#define RFPGA0_XCD_RFINTERFACERB 0x8e4 - -#define RFPGA1_RFMOD 0x900 - -#define RFPGA1_TXBLOCK 0x904 -#define RFPGA1_DEBUGSELECT 0x908 -#define RFPGA1_TXINFO 0x90c - -#define RCCK0_SYSTEM 0xa00 - -#define RCCK0_AFESETTING 0xa04 -#define RCCK0_CCA 0xa08 - -#define RCCK0_RXAGC1 0xa0c -#define RCCK0_RXAGC2 0xa10 - -#define RCCK0_RXHP 0xa14 - -#define RCCK0_DSPPARAMETER1 0xa18 -#define RCCK0_DSPPARAMETER2 0xa1c - -#define RCCK0_TXFILTER1 0xa20 -#define RCCK0_TXFILTER2 0xa24 -#define RCCK0_DEBUGPORT 0xa28 -#define RCCK0_FALSEALARMREPORT 0xa2c -#define RCCK0_TRSSIREPORT 0xa50 -#define RCCK0_RXREPORT 0xa54 -#define RCCK0_FACOUNTERLOWER 0xa5c -#define RCCK0_FACOUNTERUPPER 0xa58 - -#define ROFDM0_LSTF 0xc00 - -#define ROFDM0_TRXPATHENABLE 0xc04 -#define ROFDM0_TRMUXPAR 0xc08 -#define ROFDM0_TRSWISOLATION 0xc0c - -#define ROFDM0_XARXAFE 0xc10 -#define ROFDM0_XARXIQIMBALANCE 0xc14 -#define ROFDM0_XBRXAFE 0xc18 -#define ROFDM0_XBRXIQIMBALANCE 0xc1c -#define ROFDM0_XCRXAFE 0xc20 -#define ROFDM0_XCRXIQIMBANLANCE 0xc24 -#define ROFDM0_XDRXAFE 0xc28 -#define ROFDM0_XDRXIQIMBALANCE 0xc2c - -#define ROFDM0_RXDETECTOR1 0xc30 -#define ROFDM0_RXDETECTOR2 0xc34 -#define ROFDM0_RXDETECTOR3 0xc38 -#define ROFDM0_RXDETECTOR4 0xc3c - -#define ROFDM0_RXDSP 0xc40 -#define ROFDM0_CFOANDDAGC 0xc44 -#define ROFDM0_CCADROPTHRESHOLD 0xc48 -#define ROFDM0_ECCATHRESHOLD 0xc4c - -#define ROFDM0_XAAGCCORE1 0xc50 -#define ROFDM0_XAAGCCORE2 0xc54 -#define ROFDM0_XBAGCCORE1 0xc58 -#define ROFDM0_XBAGCCORE2 0xc5c -#define ROFDM0_XCAGCCORE1 0xc60 -#define ROFDM0_XCAGCCORE2 0xc64 -#define ROFDM0_XDAGCCORE1 0xc68 -#define ROFDM0_XDAGCCORE2 0xc6c - -#define ROFDM0_AGCPARAMETER1 0xc70 -#define ROFDM0_AGCPARAMETER2 0xc74 -#define ROFDM0_AGCRSSITABLE 0xc78 -#define ROFDM0_HTSTFAGC 0xc7c - -#define ROFDM0_XATXIQIMBALANCE 0xc80 -#define ROFDM0_XATXAFE 0xc84 -#define ROFDM0_XBTXIQIMBALANCE 0xc88 -#define ROFDM0_XBTXAFE 0xc8c -#define ROFDM0_XCTXIQIMBALANCE 0xc90 -#define ROFDM0_XCTXAFE 0xc94 -#define ROFDM0_XDTXIQIMBALANCE 0xc98 -#define ROFDM0_XDTXAFE 0xc9c - -#define ROFDM0_RXIQEXTANTA 0xca0 - -#define ROFDM0_RXHPPARAMETER 0xce0 -#define ROFDM0_TXPSEUDONOISEWGT 0xce4 -#define ROFDM0_FRAMESYNC 0xcf0 -#define ROFDM0_DFSREPORT 0xcf4 -#define ROFDM0_TXCOEFF1 0xca4 -#define ROFDM0_TXCOEFF2 0xca8 -#define ROFDM0_TXCOEFF3 0xcac -#define ROFDM0_TXCOEFF4 0xcb0 -#define ROFDM0_TXCOEFF5 0xcb4 -#define ROFDM0_TXCOEFF6 0xcb8 - -#define ROFDM1_LSTF 0xd00 -#define ROFDM1_TRXPATHENABLE 0xd04 - -#define ROFDM1_CF0 0xd08 -#define ROFDM1_CSI1 0xd10 -#define ROFDM1_SBD 0xd14 -#define ROFDM1_CSI2 0xd18 -#define ROFDM1_CFOTRACKING 0xd2c -#define ROFDM1_TRXMESAURE1 0xd34 -#define ROFDM1_INTFDET 0xd3c -#define ROFDM1_PSEUDONOISESTATEAB 0xd50 -#define ROFDM1_PSEUDONOISESTATECD 0xd54 -#define ROFDM1_RXPSEUDONOISEWGT 0xd58 - -#define ROFDM_PHYCOUNTER1 0xda0 -#define ROFDM_PHYCOUNTER2 0xda4 -#define ROFDM_PHYCOUNTER3 0xda8 - -#define ROFDM_SHORTCFOAB 0xdac -#define ROFDM_SHORTCFOCD 0xdb0 -#define ROFDM_LONGCFOAB 0xdb4 -#define ROFDM_LONGCFOCD 0xdb8 -#define ROFDM_TAILCF0AB 0xdbc -#define ROFDM_TAILCF0CD 0xdc0 -#define ROFDM_PWMEASURE1 0xdc4 -#define ROFDM_PWMEASURE2 0xdc8 -#define ROFDM_BWREPORT 0xdcc -#define ROFDM_AGCREPORT 0xdd0 -#define ROFDM_RXSNR 0xdd4 -#define ROFDM_RXEVMCSI 0xdd8 -#define ROFDM_SIGREPORT 0xddc - -#define RTXAGC_A_RATE18_06 0xe00 -#define RTXAGC_A_RATE54_24 0xe04 -#define RTXAGC_A_CCK1_MCS32 0xe08 -#define RTXAGC_A_MCS03_MCS00 0xe10 -#define RTXAGC_A_MCS07_MCS04 0xe14 -#define RTXAGC_A_MCS11_MCS08 0xe18 -#define RTXAGC_A_MCS15_MCS12 0xe1c - -#define RTXAGC_B_RATE18_06 0x830 -#define RTXAGC_B_RATE54_24 0x834 -#define RTXAGC_B_CCK1_55_MCS32 0x838 -#define RTXAGC_B_MCS03_MCS00 0x83c -#define RTXAGC_B_MCS07_MCS04 0x848 -#define RTXAGC_B_MCS11_MCS08 0x84c -#define RTXAGC_B_MCS15_MCS12 0x868 -#define RTXAGC_B_CCK11_A_CCK2_11 0x86c - -#define RZEBRA1_HSSIENABLE 0x0 -#define RZEBRA1_TRXENABLE1 0x1 -#define RZEBRA1_TRXENABLE2 0x2 -#define RZEBRA1_AGC 0x4 -#define RZEBRA1_CHARGEPUMP 0x5 -#define RZEBRA1_CHANNEL 0x7 - -#define RZEBRA1_TXGAIN 0x8 -#define RZEBRA1_TXLPF 0x9 -#define RZEBRA1_RXLPF 0xb -#define RZEBRA1_RXHPFCORNER 0xc - -#define RGLOBALCTRL 0 -#define RRTL8256_TXLPF 19 -#define RRTL8256_RXLPF 11 -#define RRTL8258_TXLPF 0x11 -#define RRTL8258_RXLPF 0x13 -#define RRTL8258_RSSILPF 0xa - -#define RF_AC 0x00 - -#define RF_IQADJ_G1 0x01 -#define RF_IQADJ_G2 0x02 -#define RF_POW_TRSW 0x05 - -#define RF_GAIN_RX 0x06 -#define RF_GAIN_TX 0x07 - -#define RF_TXM_IDAC 0x08 -#define RF_BS_IQGEN 0x0F - -#define RF_MODE1 0x10 -#define RF_MODE2 0x11 - -#define RF_RX_AGC_HP 0x12 -#define RF_TX_AGC 0x13 -#define RF_BIAS 0x14 -#define RF_IPA 0x15 -#define RF_POW_ABILITY 0x17 -#define RF_MODE_AG 0x18 -#define RRFCHANNEL 0x18 -#define RF_CHNLBW 0x18 -#define RF_TOP 0x19 - -#define RF_RX_G1 0x1A -#define RF_RX_G2 0x1B - -#define RF_RX_BB2 0x1C -#define RF_RX_BB1 0x1D - -#define RF_RCK1 0x1E -#define RF_RCK2 0x1F - -#define RF_TX_G1 0x20 -#define RF_TX_G2 0x21 -#define RF_TX_G3 0x22 - -#define RF_TX_BB1 0x23 -#define RF_T_METER 0x24 - -#define RF_SYN_G1 0x25 -#define RF_SYN_G2 0x26 -#define RF_SYN_G3 0x27 -#define RF_SYN_G4 0x28 -#define RF_SYN_G5 0x29 -#define RF_SYN_G6 0x2A -#define RF_SYN_G7 0x2B -#define RF_SYN_G8 0x2C - -#define RF_RCK_OS 0x30 -#define RF_TXPA_G1 0x31 -#define RF_TXPA_G2 0x32 -#define RF_TXPA_G3 0x33 - -#define BBBRESETB 0x100 -#define BGLOBALRESETB 0x200 -#define BOFDMTXSTART 0x4 -#define BCCKTXSTART 0x8 -#define BCRC32DEBUG 0x100 -#define BPMACLOOPBACK 0x10 -#define BTXLSIG 0xffffff -#define BOFDMTXRATE 0xf -#define BOFDMTXRESERVED 0x10 -#define BOFDMTXLENGTH 0x1ffe0 -#define BOFDMTXPARITY 0x20000 -#define BTXHTSIG1 0xffffff -#define BTXHTMCSRATE 0x7f -#define BTXHTBW 0x80 -#define BTXHTLENGTH 0xffff00 -#define BTXHTSIG2 0xffffff -#define BTXHTSMOOTHING 0x1 -#define BTXHTSOUNDING 0x2 -#define BTXHTRESERVED 0x4 -#define BTXHTAGGREATION 0x8 -#define BTXHTSTBC 0x30 -#define BTXHTADVANCECODING 0x40 -#define BTXHTSHORTGI 0x80 -#define BTXHTNUMBERHT_LT F 0x300 -#define BTXHTCRC8 0x3fc00 -#define BCOUNTERRESET 0x10000 -#define BNUMOFOFDMTX 0xffff -#define BNUMOFCCKTX 0xffff0000 -#define BTXIDLEINTERVAL 0xffff -#define BOFDMSERVICE 0xffff0000 -#define BTXMACHEADER 0xffffffff -#define BTXDATAINIT 0xff -#define BTXHTMODE 0x100 -#define BTXDATATYPE 0x30000 -#define BTXRANDOMSEED 0xffffffff -#define BCCKTXPREAMBLE 0x1 -#define BCCKTXSFD 0xffff0000 -#define BCCKTXSIG 0xff -#define BCCKTXSERVICE 0xff00 -#define BCCKLENGTHEXT 0x8000 -#define BCCKTXLENGHT 0xffff0000 -#define BCCKTXCRC16 0xffff -#define BCCKTXSTATUS 0x1 -#define BOFDMTXSTATUS 0x2 -#define IS_BB_REG_OFFSET_92S(_Offset) \ - ((_Offset >= 0x800) && (_Offset <= 0xfff)) - -#define BRFMOD 0x1 -#define BJAPANMODE 0x2 -#define BCCKTXSC 0x30 -#define BCCKEN 0x1000000 -#define BOFDMEN 0x2000000 - -#define BOFDMRXADCPHASE 0x10000 -#define BOFDMTXDACPHASE 0x40000 -#define BXATXAGC 0x3f - -#define BXBTXAGC 0xf00 -#define BXCTXAGC 0xf000 -#define BXDTXAGC 0xf0000 - -#define BPASTART 0xf0000000 -#define BTRSTART 0x00f00000 -#define BRFSTART 0x0000f000 -#define BBBSTART 0x000000f0 -#define BBBCCKSTART 0x0000000f -#define BPAEND 0xf -#define BTREND 0x0f000000 -#define BRFEND 0x000f0000 -#define BCCAMASK 0x000000f0 -#define BR2RCCAMASK 0x00000f00 -#define BHSSI_R2TDELAY 0xf8000000 -#define BHSSI_T2RDELAY 0xf80000 -#define BCONTXHSSI 0x400 -#define BIGFROMCCK 0x200 -#define BAGCADDRESS 0x3f -#define BRXHPTX 0x7000 -#define BRXHP2RX 0x38000 -#define BRXHPCCKINI 0xc0000 -#define BAGCTXCODE 0xc00000 -#define BAGCRXCODE 0x300000 - -#define B3WIREDATALENGTH 0x800 -#define B3WIREADDREAALENGTH 0x400 - -#define B3WIRERFPOWERDOWN 0x1 -#define B5GPAPEPOLARITY 0x40000000 -#define B2GPAPEPOLARITY 0x80000000 -#define BRFSW_TXDEFAULTANT 0x3 -#define BRFSW_TXOPTIONANT 0x30 -#define BRFSW_RXDEFAULTANT 0x300 -#define BRFSW_RXOPTIONANT 0x3000 -#define BRFSI_3WIREDATA 0x1 -#define BRFSI_3WIRECLOCK 0x2 -#define BRFSI_3WIRELOAD 0x4 -#define BRFSI_3WIRERW 0x8 -#define BRFSI_3WIRE 0xf - -#define BRFSI_RFENV 0x10 - -#define BRFSI_TRSW 0x20 -#define BRFSI_TRSWB 0x40 -#define BRFSI_ANTSW 0x100 -#define BRFSI_ANTSWB 0x200 -#define BRFSI_PAPE 0x400 -#define BRFSI_PAPE5G 0x800 -#define BBANDSELECT 0x1 -#define BHTSIG2_GI 0x80 -#define BHTSIG2_SMOOTHING 0x01 -#define BHTSIG2_SOUNDING 0x02 -#define BHTSIG2_AGGREATON 0x08 -#define BHTSIG2_STBC 0x30 -#define BHTSIG2_ADVCODING 0x40 -#define BHTSIG2_NUMOFHTLTF 0x300 -#define BHTSIG2_CRC8 0x3fc -#define BHTSIG1_MCS 0x7f -#define BHTSIG1_BANDWIDTH 0x80 -#define BHTSIG1_HTLENGTH 0xffff -#define BLSIG_RATE 0xf -#define BLSIG_RESERVED 0x10 -#define BLSIG_LENGTH 0x1fffe -#define BLSIG_PARITY 0x20 -#define BCCKRXPHASE 0x4 - -#define BLSSIREADADDRESS 0x7f800000 -#define BLSSIREADEDGE 0x80000000 - -#define BLSSIREADBACKDATA 0xfffff - -#define BLSSIREADOKFLAG 0x1000 -#define BCCKSAMPLERATE 0x8 -#define BREGULATOR0STANDBY 0x1 -#define BREGULATORPLLSTANDBY 0x2 -#define BREGULATOR1STANDBY 0x4 -#define BPLLPOWERUP 0x8 -#define BDPLLPOWERUP 0x10 -#define BDA10POWERUP 0x20 -#define BAD7POWERUP 0x200 -#define BDA6POWERUP 0x2000 -#define BXTALPOWERUP 0x4000 -#define B40MDCLKPOWERUP 0x8000 -#define BDA6DEBUGMODE 0x20000 -#define BDA6SWING 0x380000 - -#define BADCLKPHASE 0x4000000 -#define B80MCLKDELAY 0x18000000 -#define BAFEWATCHDOGENABLE 0x20000000 - -#define BXTALCAP01 0xc0000000 -#define BXTALCAP23 0x3 -#define BXTALCAP92X 0x0f000000 -#define BXTALCAP 0x0f000000 - -#define BINTDIFCLKENABLE 0x400 -#define BEXTSIGCLKENABLE 0x800 -#define BBANDGAP_MBIAS_POWERUP 0x10000 -#define BAD11SH_GAIN 0xc0000 -#define BAD11NPUT_RANGE 0x700000 -#define BAD110P_CURRENT 0x3800000 -#define BLPATH_LOOPBACK 0x4000000 -#define BQPATH_LOOPBACK 0x8000000 -#define BAFE_LOOPBACK 0x10000000 -#define BDA10_SWING 0x7e0 -#define BDA10_REVERSE 0x800 -#define BDA_CLK_SOURCE 0x1000 -#define BDA7INPUT_RANGE 0x6000 -#define BDA7_GAIN 0x38000 -#define BDA7OUTPUT_CM_MODE 0x40000 -#define BDA7INPUT_CM_MODE 0x380000 -#define BDA7CURRENT 0xc00000 -#define BREGULATOR_ADJUST 0x7000000 -#define BAD11POWERUP_ATTX 0x1 -#define BDA10PS_ATTX 0x10 -#define BAD11POWERUP_ATRX 0x100 -#define BDA10PS_ATRX 0x1000 -#define BCCKRX_AGC_FORMAT 0x200 -#define BPSDFFT_SAMPLE_POINT 0xc000 -#define BPSD_AVERAGE_NUM 0x3000 -#define BIQPATH_CONTROL 0xc00 -#define BPSD_FREQ 0x3ff -#define BPSD_ANTENNA_PATH 0x30 -#define BPSD_IQ_SWITCH 0x40 -#define BPSD_RX_TRIGGER 0x400000 -#define BPSD_TX_TRIGGER 0x80000000 -#define BPSD_SINE_TONE_SCALE 0x7f000000 -#define BPSD_REPORT 0xffff - -#define BOFDM_TXSC 0x30000000 -#define BCCK_TXON 0x1 -#define BOFDM_TXON 0x2 -#define BDEBUG_PAGE 0xfff -#define BDEBUG_ITEM 0xff -#define BANTL 0x10 -#define BANT_NONHT 0x100 -#define BANT_HT1 0x1000 -#define BANT_HT2 0x10000 -#define BANT_HT1S1 0x100000 -#define BANT_NONHTS1 0x1000000 - -#define BCCK_BBMODE 0x3 -#define BCCK_TXPOWERSAVING 0x80 -#define BCCK_RXPOWERSAVING 0x40 - -#define BCCK_SIDEBAND 0x10 - -#define BCCK_SCRAMBLE 0x8 -#define BCCK_ANTDIVERSITY 0x8000 -#define BCCK_CARRIER_RECOVERY 0x4000 -#define BCCK_TXRATE 0x3000 -#define BCCK_DCCANCEL 0x0800 -#define BCCK_ISICANCEL 0x0400 -#define BCCK_MATCH_FILTER 0x0200 -#define BCCK_EQUALIZER 0x0100 -#define BCCK_PREAMBLE_DETECT 0x800000 -#define BCCK_FAST_FALSECCA 0x400000 -#define BCCK_CH_ESTSTART 0x300000 -#define BCCK_CCA_COUNT 0x080000 -#define BCCK_CS_LIM 0x070000 -#define BCCK_BIST_MODE 0x80000000 -#define BCCK_CCAMASK 0x40000000 -#define BCCK_TX_DAC_PHASE 0x4 -#define BCCK_RX_ADC_PHASE 0x20000000 -#define BCCKR_CP_MODE 0x0100 -#define BCCK_TXDC_OFFSET 0xf0 -#define BCCK_RXDC_OFFSET 0xf -#define BCCK_CCA_MODE 0xc000 -#define BCCK_FALSECS_LIM 0x3f00 -#define BCCK_CS_RATIO 0xc00000 -#define BCCK_CORGBIT_SEL 0x300000 -#define BCCK_PD_LIM 0x0f0000 -#define BCCK_NEWCCA 0x80000000 -#define BCCK_RXHP_OF_IG 0x8000 -#define BCCK_RXIG 0x7f00 -#define BCCK_LNA_POLARITY 0x800000 -#define BCCK_RX1ST_BAIN 0x7f0000 -#define BCCK_RF_EXTEND 0x20000000 -#define BCCK_RXAGC_SATLEVEL 0x1f000000 -#define BCCK_RXAGC_SATCOUNT 0xe0 -#define bCCKRxRFSettle 0x1f -#define BCCK_FIXED_RXAGC 0x8000 -#define BCCK_ANTENNA_POLARITY 0x2000 -#define BCCK_TXFILTER_TYPE 0x0c00 -#define BCCK_RXAGC_REPORTTYPE 0x0300 -#define BCCK_RXDAGC_EN 0x80000000 -#define BCCK_RXDAGC_PERIOD 0x20000000 -#define BCCK_RXDAGC_SATLEVEL 0x1f000000 -#define BCCK_TIMING_RECOVERY 0x800000 -#define BCCK_TXC0 0x3f0000 -#define BCCK_TXC1 0x3f000000 -#define BCCK_TXC2 0x3f -#define BCCK_TXC3 0x3f00 -#define BCCK_TXC4 0x3f0000 -#define BCCK_TXC5 0x3f000000 -#define BCCK_TXC6 0x3f -#define BCCK_TXC7 0x3f00 -#define BCCK_DEBUGPORT 0xff0000 -#define BCCK_DAC_DEBUG 0x0f000000 -#define BCCK_FALSEALARM_ENABLE 0x8000 -#define BCCK_FALSEALARM_READ 0x4000 -#define BCCK_TRSSI 0x7f -#define BCCK_RXAGC_REPORT 0xfe -#define BCCK_RXREPORT_ANTSEL 0x80000000 -#define BCCK_RXREPORT_MFOFF 0x40000000 -#define BCCK_RXREPORT_SQLOSS 0x20000000 -#define BCCK_RXREPORT_PKTLOSS 0x10000000 -#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 -#define BCCK_RXREPORT_RATEERROR 0x04000000 -#define BCCK_RXREPORT_RXRATE 0x03000000 -#define BCCK_RXFA_COUNTER_LOWER 0xff -#define BCCK_RXFA_COUNTER_UPPER 0xff000000 -#define BCCK_RXHPAGC_START 0xe000 -#define BCCK_RXHPAGC_FINAL 0x1c00 -#define BCCK_RXFALSEALARM_ENABLE 0x8000 -#define BCCK_FACOUNTER_FREEZE 0x4000 -#define BCCK_TXPATH_SEL 0x10000000 -#define BCCK_DEFAULT_RXPATH 0xc000000 -#define BCCK_OPTION_RXPATH 0x3000000 - -#define BNUM_OFSTF 0x3 -#define BSHIFT_L 0xc0 -#define BGI_TH 0xc -#define BRXPATH_A 0x1 -#define BRXPATH_B 0x2 -#define BRXPATH_C 0x4 -#define BRXPATH_D 0x8 -#define BTXPATH_A 0x1 -#define BTXPATH_B 0x2 -#define BTXPATH_C 0x4 -#define BTXPATH_D 0x8 -#define BTRSSI_FREQ 0x200 -#define BADC_BACKOFF 0x3000 -#define BDFIR_BACKOFF 0xc000 -#define BTRSSI_LATCH_PHASE 0x10000 -#define BRX_LDC_OFFSET 0xff -#define BRX_QDC_OFFSET 0xff00 -#define BRX_DFIR_MODE 0x1800000 -#define BRX_DCNF_TYPE 0xe000000 -#define BRXIQIMB_A 0x3ff -#define BRXIQIMB_B 0xfc00 -#define BRXIQIMB_C 0x3f0000 -#define BRXIQIMB_D 0xffc00000 -#define BDC_DC_NOTCH 0x60000 -#define BRXNB_NOTCH 0x1f000000 -#define BPD_TH 0xf -#define BPD_TH_OPT2 0xc000 -#define BPWED_TH 0x700 -#define BIFMF_WIN_L 0x800 -#define BPD_OPTION 0x1000 -#define BMF_WIN_L 0xe000 -#define BBW_SEARCH_L 0x30000 -#define BWIN_ENH_L 0xc0000 -#define BBW_TH 0x700000 -#define BED_TH2 0x3800000 -#define BBW_OPTION 0x4000000 -#define BRADIO_TH 0x18000000 -#define BWINDOW_L 0xe0000000 -#define BSBD_OPTION 0x1 -#define BFRAME_TH 0x1c -#define BFS_OPTION 0x60 -#define BDC_SLOPE_CHECK 0x80 -#define BFGUARD_COUNTER_DC_L 0xe00 -#define BFRAME_WEIGHT_SHORT 0x7000 -#define BSUB_TUNE 0xe00000 -#define BFRAME_DC_LENGTH 0xe000000 -#define BSBD_START_OFFSET 0x30000000 -#define BFRAME_TH_2 0x7 -#define BFRAME_GI2_TH 0x38 -#define BGI2_SYNC_EN 0x40 -#define BSARCH_SHORT_EARLY 0x300 -#define BSARCH_SHORT_LATE 0xc00 -#define BSARCH_GI2_LATE 0x70000 -#define BCFOANTSUM 0x1 -#define BCFOACC 0x2 -#define BCFOSTARTOFFSET 0xc -#define BCFOLOOPBACK 0x70 -#define BCFOSUMWEIGHT 0x80 -#define BDAGCENABLE 0x10000 -#define BTXIQIMB_A 0x3ff -#define BTXIQIMB_b 0xfc00 -#define BTXIQIMB_C 0x3f0000 -#define BTXIQIMB_D 0xffc00000 -#define BTXIDCOFFSET 0xff -#define BTXIQDCOFFSET 0xff00 -#define BTXDFIRMODE 0x10000 -#define BTXPESUDO_NOISEON 0x4000000 -#define BTXPESUDO_NOISE_A 0xff -#define BTXPESUDO_NOISE_B 0xff00 -#define BTXPESUDO_NOISE_C 0xff0000 -#define BTXPESUDO_NOISE_D 0xff000000 -#define BCCA_DROPOPTION 0x20000 -#define BCCA_DROPTHRES 0xfff00000 -#define BEDCCA_H 0xf -#define BEDCCA_L 0xf0 -#define BLAMBDA_ED 0x300 -#define BRX_INITIALGAIN 0x7f -#define BRX_ANTDIV_EN 0x80 -#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 -#define BRX_HIGHPOWER_FLOW 0x8000 -#define BRX_AGC_FREEZE_THRES 0xc0000 -#define BRX_FREEZESTEP_AGC1 0x300000 -#define BRX_FREEZESTEP_AGC2 0xc00000 -#define BRX_FREEZESTEP_AGC3 0x3000000 -#define BRX_FREEZESTEP_AGC0 0xc000000 -#define BRXRSSI_CMP_EN 0x10000000 -#define BRXQUICK_AGCEN 0x20000000 -#define BRXAGC_FREEZE_THRES_MODE 0x40000000 -#define BRX_OVERFLOW_CHECKTYPE 0x80000000 -#define BRX_AGCSHIFT 0x7f -#define BTRSW_TRI_ONLY 0x80 -#define BPOWER_THRES 0x300 -#define BRXAGC_EN 0x1 -#define BRXAGC_TOGETHER_EN 0x2 -#define BRXAGC_MIN 0x4 -#define BRXHP_INI 0x7 -#define BRXHP_TRLNA 0x70 -#define BRXHP_RSSI 0x700 -#define BRXHP_BBP1 0x7000 -#define BRXHP_BBP2 0x70000 -#define BRXHP_BBP3 0x700000 -#define BRSSI_H 0x7f0000 -#define BRSSI_GEN 0x7f000000 -#define BRXSETTLE_TRSW 0x7 -#define BRXSETTLE_LNA 0x38 -#define BRXSETTLE_RSSI 0x1c0 -#define BRXSETTLE_BBP 0xe00 -#define BRXSETTLE_RXHP 0x7000 -#define BRXSETTLE_ANTSW_RSSI 0x38000 -#define BRXSETTLE_ANTSW 0xc0000 -#define BRXPROCESS_TIME_DAGC 0x300000 -#define BRXSETTLE_HSSI 0x400000 -#define BRXPROCESS_TIME_BBPPW 0x800000 -#define BRXANTENNA_POWER_SHIFT 0x3000000 -#define BRSSI_TABLE_SELECT 0xc000000 -#define BRXHP_FINAL 0x7000000 -#define BRXHPSETTLE_BBP 0x7 -#define BRXHTSETTLE_HSSI 0x8 -#define BRXHTSETTLE_RXHP 0x70 -#define BRXHTSETTLE_BBPPW 0x80 -#define BRXHTSETTLE_IDLE 0x300 -#define BRXHTSETTLE_RESERVED 0x1c00 -#define BRXHT_RXHP_EN 0x8000 -#define BRXAGC_FREEZE_THRES 0x30000 -#define BRXAGC_TOGETHEREN 0x40000 -#define BRXHTAGC_MIN 0x80000 -#define BRXHTAGC_EN 0x100000 -#define BRXHTDAGC_EN 0x200000 -#define BRXHT_RXHP_BBP 0x1c00000 -#define BRXHT_RXHP_FINAL 0xe0000000 -#define BRXPW_RADIO_TH 0x3 -#define BRXPW_RADIO_EN 0x4 -#define BRXMF_HOLD 0x3800 -#define BRXPD_DELAY_TH1 0x38 -#define BRXPD_DELAY_TH2 0x1c0 -#define BRXPD_DC_COUNT_MAX 0x600 -#define BRXPD_DELAY_TH 0x8000 -#define BRXPROCESS_DELAY 0xf0000 -#define BRXSEARCHRANGE_GI2_EARLY 0x700000 -#define BRXFRAME_FUARD_COUNTER_L 0x3800000 -#define BRXSGI_GUARD_L 0xc000000 -#define BRXSGI_SEARCH_L 0x30000000 -#define BRXSGI_TH 0xc0000000 -#define BDFSCNT0 0xff -#define BDFSCNT1 0xff00 -#define BDFSFLAG 0xf0000 -#define BMF_WEIGHT_SUM 0x300000 -#define BMINIDX_TH 0x7f000000 -#define BDAFORMAT 0x40000 -#define BTXCH_EMU_ENABLE 0x01000000 -#define BTRSW_ISOLATION_A 0x7f -#define BTRSW_ISOLATION_B 0x7f00 -#define BTRSW_ISOLATION_C 0x7f0000 -#define BTRSW_ISOLATION_D 0x7f000000 -#define BEXT_LNA_GAIN 0x7c00 - -#define BSTBC_EN 0x4 -#define BANTENNA_MAPPING 0x10 -#define BNSS 0x20 -#define BCFO_ANTSUM_ID 0x200 -#define BPHY_COUNTER_RESET 0x8000000 -#define BCFO_REPORT_GET 0x4000000 -#define BOFDM_CONTINUE_TX 0x10000000 -#define BOFDM_SINGLE_CARRIER 0x20000000 -#define BOFDM_SINGLE_TONE 0x40000000 -#define BHT_DETECT 0x100 -#define BCFOEN 0x10000 -#define BCFOVALUE 0xfff00000 -#define BSIGTONE_RE 0x3f -#define BSIGTONE_IM 0x7f00 -#define BCOUNTER_CCA 0xffff -#define BCOUNTER_PARITYFAIL 0xffff0000 -#define BCOUNTER_RATEILLEGAL 0xffff -#define BCOUNTER_CRC8FAIL 0xffff0000 -#define BCOUNTER_MCSNOSUPPORT 0xffff -#define BCOUNTER_FASTSYNC 0xffff -#define BSHORTCFO 0xfff -#define BSHORTCFOT_LENGTH 12 -#define BSHORTCFOF_LENGTH 11 -#define BLONGCFO 0x7ff -#define BLONGCFOT_LENGTH 11 -#define BLONGCFOF_LENGTH 11 -#define BTAILCFO 0x1fff -#define BTAILCFOT_LENGTH 13 -#define BTAILCFOF_LENGTH 12 -#define BNOISE_EN_PWDB 0xffff -#define BCC_POWER_DB 0xffff0000 -#define BMOISE_PWDB 0xffff -#define BPOWERMEAST_LENGTH 10 -#define BPOWERMEASF_LENGTH 3 -#define BRX_HT_BW 0x1 -#define BRXSC 0x6 -#define BRX_HT 0x8 -#define BNB_INTF_DET_ON 0x1 -#define BINTF_WIN_LEN_CFG 0x30 -#define BNB_INTF_TH_CFG 0x1c0 -#define BRFGAIN 0x3f -#define BTABLESEL 0x40 -#define BTRSW 0x80 -#define BRXSNR_A 0xff -#define BRXSNR_B 0xff00 -#define BRXSNR_C 0xff0000 -#define BRXSNR_D 0xff000000 -#define BSNR_EVMT_LENGTH 8 -#define BSNR_EVMF_LENGTH 1 -#define BCSI1ST 0xff -#define BCSI2ND 0xff00 -#define BRXEVM1ST 0xff0000 -#define BRXEVM2ND 0xff000000 -#define BSIGEVM 0xff -#define BPWDB 0xff00 -#define BSGIEN 0x10000 - -#define BSFACTOR_QMA1 0xf -#define BSFACTOR_QMA2 0xf0 -#define BSFACTOR_QMA3 0xf00 -#define BSFACTOR_QMA4 0xf000 -#define BSFACTOR_QMA5 0xf0000 -#define BSFACTOR_QMA6 0xf0000 -#define BSFACTOR_QMA7 0xf00000 -#define BSFACTOR_QMA8 0xf000000 -#define BSFACTOR_QMA9 0xf0000000 -#define BCSI_SCHEME 0x100000 - -#define BNOISE_LVL_TOP_SET 0x3 -#define BCHSMOOTH 0x4 -#define BCHSMOOTH_CFG1 0x38 -#define BCHSMOOTH_CFG2 0x1c0 -#define BCHSMOOTH_CFG3 0xe00 -#define BCHSMOOTH_CFG4 0x7000 -#define BMRCMODE 0x800000 -#define BTHEVMCFG 0x7000000 - -#define BLOOP_FIT_TYPE 0x1 -#define BUPD_CFO 0x40 -#define BUPD_CFO_OFFDATA 0x80 -#define BADV_UPD_CFO 0x100 -#define BADV_TIME_CTRL 0x800 -#define BUPD_CLKO 0x1000 -#define BFC 0x6000 -#define BTRACKING_MODE 0x8000 -#define BPHCMP_ENABLE 0x10000 -#define BUPD_CLKO_LTF 0x20000 -#define BCOM_CH_CFO 0x40000 -#define BCSI_ESTI_MODE 0x80000 -#define BADV_UPD_EQZ 0x100000 -#define BUCHCFG 0x7000000 -#define BUPDEQZ 0x8000000 - -#define BRX_PESUDO_NOISE_ON 0x20000000 -#define BRX_PESUDO_NOISE_A 0xff -#define BRX_PESUDO_NOISE_B 0xff00 -#define BRX_PESUDO_NOISE_C 0xff0000 -#define BRX_PESUDO_NOISE_D 0xff000000 -#define BRX_PESUDO_NOISESTATE_A 0xffff -#define BRX_PESUDO_NOISESTATE_B 0xffff0000 -#define BRX_PESUDO_NOISESTATE_C 0xffff -#define BRX_PESUDO_NOISESTATE_D 0xffff0000 - -#define BZEBRA1_HSSIENABLE 0x8 -#define BZEBRA1_TRXCONTROL 0xc00 -#define BZEBRA1_TRXGAINSETTING 0x07f -#define BZEBRA1_RXCOUNTER 0xc00 -#define BZEBRA1_TXCHANGEPUMP 0x38 -#define BZEBRA1_RXCHANGEPUMP 0x7 -#define BZEBRA1_CHANNEL_NUM 0xf80 -#define BZEBRA1_TXLPFBW 0x400 -#define BZEBRA1_RXLPFBW 0x600 - -#define BRTL8256REG_MODE_CTRL1 0x100 -#define BRTL8256REG_MODE_CTRL0 0x40 -#define BRTL8256REG_TXLPFBW 0x18 -#define BRTL8256REG_RXLPFBW 0x600 - -#define BRTL8258_TXLPFBW 0xc -#define BRTL8258_RXLPFBW 0xc00 -#define BRTL8258_RSSILPFBW 0xc0 - -#define BBYTE0 0x1 -#define BBYTE1 0x2 -#define BBYTE2 0x4 -#define BBYTE3 0x8 -#define BWORD0 0x3 -#define BWORD1 0xc -#define BWORD 0xf - -#define MASKBYTE0 0xff -#define MASKBYTE1 0xff00 -#define MASKBYTE2 0xff0000 -#define MASKBYTE3 0xff000000 -#define MASKHWORD 0xffff0000 -#define MASKLWORD 0x0000ffff -#define MASKDWORD 0xffffffff -#define MASK12BITS 0xfff -#define MASKH4BITS 0xf0000000 -#define MASKOFDM_D 0xffc00000 -#define MASKCCK 0x3f3f3f3f - -#define MASK4BITS 0x0f -#define MASK20BITS 0xfffff -#define RFREG_OFFSET_MASK 0xfffff - -#define BENABLE 0x1 -#define BDISABLE 0x0 - -#define LEFT_ANTENNA 0x0 -#define RIGHT_ANTENNA 0x1 - -#define TCHECK_TXSTATUS 500 -#define TUPDATE_RXCOUNTER 100 - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c deleted file mode 100644 index a2d58df5d3a0..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c +++ /dev/null @@ -1,523 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-rf.h" -#include "rtl8192c-dm.h" - -static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); - -void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - switch (bandwidth) { - case HT_CHANNEL_WIDTH_20: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff) | 0x0400); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - case HT_CHANNEL_WIDTH_20_40: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff)); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); - break; - } -} - -void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 tx_agc[2] = {0, 0}, tmpval; - bool turbo_scanoff = false; - u8 idx1, idx2; - u8 *ptr; - - if (rtlefuse->eeprom_regulatory != 0) - turbo_scanoff = true; - - if (mac->act_scanning == true) { - tx_agc[RF90_PATH_A] = 0x3f3f3f3f; - tx_agc[RF90_PATH_B] = 0x3f3f3f3f; - - if (turbo_scanoff) { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - } - } else { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - - if (rtlefuse->eeprom_regulatory == 0) { - tmpval = - (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + - (rtlphy->mcs_txpwrlevel_origoffset[0][7] << - 8); - tx_agc[RF90_PATH_A] += tmpval; - - tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + - (rtlphy->mcs_txpwrlevel_origoffset[0][15] << - 24); - tx_agc[RF90_PATH_B] += tmpval; - } - } - - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - ptr = (u8 *) (&(tx_agc[idx1])); - for (idx2 = 0; idx2 < 4; idx2++) { - if (*ptr > RF6052_MAX_TX_PWR) - *ptr = RF6052_MAX_TX_PWR; - ptr++; - } - } - - tmpval = tx_agc[RF90_PATH_A] & 0xff; - rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); - - tmpval = tx_agc[RF90_PATH_A] >> 8; - - if (mac->mode == WIRELESS_MODE_B) - tmpval = tmpval & 0xff00ffff; - - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); - - tmpval = tx_agc[RF90_PATH_B] >> 24; - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); - - tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; - rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); -} - -static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel, - u32 *ofdmbase, u32 *mcsbase) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 powerBase0, powerBase1; - u8 legacy_pwrdiff, ht20_pwrdiff; - u8 i, powerlevel[2]; - - for (i = 0; i < 2; i++) { - powerlevel[i] = ppowerlevel[i]; - legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; - powerBase0 = powerlevel[i] + legacy_pwrdiff; - - powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | - (powerBase0 << 8) | powerBase0; - *(ofdmbase + i) = powerBase0; - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); - } - - for (i = 0; i < 2; i++) { - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { - ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; - powerlevel[i] += ht20_pwrdiff; - } - powerBase1 = powerlevel[i]; - powerBase1 = (powerBase1 << 24) | - (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; - - *(mcsbase + i) = powerBase1; - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); - } -} - -static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, - u8 channel, u8 index, - u32 *powerBase0, - u32 *powerBase1, - u32 *p_outwriteval) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 i, chnlgroup, pwr_diff_limit[4]; - u32 writeVal, customer_limit, rf; - - for (rf = 0; rf < 2; rf++) { - switch (rtlefuse->eeprom_regulatory) { - case 0: - chnlgroup = 0; - - writeVal = - rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + - (rf ? 8 : 0)] - + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - break; - case 1: - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - writeVal = ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - } else { - if (rtlphy->pwrgroup_cnt == 1) - chnlgroup = 0; - if (rtlphy->pwrgroup_cnt >= 3) { - if (channel <= 3) - chnlgroup = 0; - else if (channel >= 4 && channel <= 9) - chnlgroup = 1; - else if (channel > 9) - chnlgroup = 2; - if (rtlphy->pwrgroup_cnt == 4) - chnlgroup++; - } - - writeVal = - rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] - [index + (rf ? 8 : 0)] + ((index < 2) ? - powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - } - break; - case 2: - writeVal = - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - break; - case 3: - chnlgroup = 0; - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel - - 1])); - } else { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel - - 1])); - } - for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = - (u8) ((rtlphy->mcs_txpwrlevel_origoffset - [chnlgroup][index + - (rf ? 8 : 0)] & (0x7f << (i * 8))) >> - (i * 8)); - - if (rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20_40) { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht40[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht40[rf] - [channel - 1]; - } else { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht20[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht20[rf] - [channel - 1]; - } - } - - customer_limit = (pwr_diff_limit[3] << 24) | - (pwr_diff_limit[2] << 16) | - (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); - - writeVal = customer_limit + - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - break; - default: - chnlgroup = 0; - writeVal = - rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] - [index + (rf ? 8 : 0)] - + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeVal " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); - break; - } - - if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) - writeVal = writeVal - 0x06060606; - else if (rtlpriv->dm.dynamic_txhighpower_lvl == - TXHIGHPWRLEVEL_BT2) - writeVal = writeVal - 0x0c0c0c0c; - *(p_outwriteval + rf) = writeVal; - } -} - -static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, - u8 index, u32 *pValue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - u16 regoffset_a[6] = { - RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, - RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, - RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 - }; - u16 regoffset_b[6] = { - RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, - RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, - RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 - }; - u8 i, rf, pwr_val[4]; - u32 writeVal; - u16 regoffset; - - for (rf = 0; rf < 2; rf++) { - writeVal = pValue[rf]; - for (i = 0; i < 4; i++) { - pwr_val[i] = (u8) ((writeVal & (0x7f << - (i * 8))) >> (i * 8)); - - if (pwr_val[i] > RF6052_MAX_TX_PWR) - pwr_val[i] = RF6052_MAX_TX_PWR; - } - writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | - (pwr_val[1] << 8) | pwr_val[0]; - - if (rf == 0) - regoffset = regoffset_a[index]; - else - regoffset = regoffset_b[index]; - rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); - - if (((get_rf_type(rtlphy) == RF_2T2R) && - (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS15_MCS12)) || - ((get_rf_type(rtlphy) != RF_2T2R) && - (regoffset == RTXAGC_A_MCS07_MCS04 || - regoffset == RTXAGC_B_MCS07_MCS04))) { - - writeVal = pwr_val[3]; - if (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_A_MCS07_MCS04) - regoffset = 0xc90; - if (regoffset == RTXAGC_B_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS07_MCS04) - regoffset = 0xc98; - - for (i = 0; i < 3; i++) { - writeVal = (writeVal > 6) ? (writeVal - 6) : 0; - rtl_write_byte(rtlpriv, (u32) (regoffset + i), - (u8) writeVal); - } - } - } -} - -void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel) -{ - u32 writeVal[2], powerBase0[2], powerBase1[2]; - u8 index; - - rtl92c_phy_get_power_base(hw, ppowerlevel, - channel, &powerBase0[0], &powerBase1[0]); - - for (index = 0; index < 6; index++) { - _rtl92c_get_txpower_writeval_by_regulatory(hw, - channel, index, - &powerBase0[0], - &powerBase1[0], - &writeVal[0]); - - _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]); - } -} - -bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlphy->rf_type == RF_1T1R) - rtlphy->num_total_rfpath = 1; - else - rtlphy->num_total_rfpath = 2; - - return _rtl92c_phy_rf6052_config_parafile(hw); -} - -static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 u4_regvalue; - u8 rfpath; - bool rtstatus; - struct bb_reg_def *pphyreg; - - for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { - - pphyreg = &rtlphy->phyreg_def[rfpath]; - - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV); - break; - case RF90_PATH_B: - case RF90_PATH_D: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16); - break; - } - - rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, - B3WIREADDREAALENGTH, 0x0); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); - udelay(1); - - switch (rfpath) { - case RF90_PATH_A: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, - (enum radio_path) rfpath); - break; - case RF90_PATH_B: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, - (enum radio_path) rfpath); - break; - case RF90_PATH_C: - break; - case RF90_PATH_D: - break; - } - - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV, u4_regvalue); - break; - case RF90_PATH_B: - case RF90_PATH_D: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16, u4_regvalue); - break; - } - - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); - return false; - } - - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); - return rtstatus; -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h deleted file mode 100644 index d3014f99bb7b..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_RF_H__ -#define __RTL92C_RF_H__ - -#define RF6052_MAX_TX_PWR 0x3F -#define RF6052_MAX_REG 0x3F -#define RF6052_MAX_PATH 2 - -extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw); -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c deleted file mode 100644 index 4c76ad6401be..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c +++ /dev/null @@ -1,282 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include - -#include "../wifi.h" -#include "../core.h" -#include "../pci.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-dm.h" -#include "rtl8192c-hw.h" -#include "rtl8192c-sw.h" -#include "rtl8192c-trx.h" -#include "rtl8192c-led.h" - -int rtl92c_init_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtlpriv->dm.b_dm_initialgain_enable = 1; - rtlpriv->dm.dm_flag = 0; - rtlpriv->dm.b_disable_framebursting = 0;; - rtlpriv->dm.thermalvalue = 0; - rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); - - rtlpci->receive_config = (RCR_APPFCS | - RCR_AMF | - RCR_ADF | - RCR_APP_MIC | - RCR_APP_ICV | - RCR_AICV | - RCR_ACRC32 | - RCR_AB | - RCR_AM | - RCR_APM | - RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0); - - rtlpci->irq_mask[0] = - (u32) (IMR_ROK | - IMR_VODOK | - IMR_VIDOK | - IMR_BEDOK | - IMR_BKDOK | - IMR_MGNTDOK | - IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0); - - rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); - - rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); - return 1; - } - - return 0; -} - -void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->rtlhal.pfirmware) { - vfree(rtlpriv->rtlhal.pfirmware); - rtlpriv->rtlhal.pfirmware = NULL; - } -} - -static struct rtl_hal_ops rtl8192ce_hal_ops = { - .init_sw_vars = rtl92c_init_sw_vars, - .deinit_sw_vars = rtl92c_deinit_sw_vars, - .read_eeprom_info = rtl92ce_read_eeprom_info, - .interrupt_recognized = rtl92ce_interrupt_recognized, - .hw_init = rtl92ce_hw_init, - .hw_disable = rtl92ce_card_disable, - .enable_interrupt = rtl92ce_enable_interrupt, - .disable_interrupt = rtl92ce_disable_interrupt, - .set_network_type = rtl92ce_set_network_type, - .set_qos = rtl92ce_set_qos, - .set_bcn_reg = rtl92ce_set_beacon_related_registers, - .set_bcn_intv = rtl92ce_set_beacon_interval, - .update_interrupt_mask = rtl92ce_update_interrupt_mask, - .get_hw_reg = rtl92ce_get_hw_reg, - .set_hw_reg = rtl92ce_set_hw_reg, - .update_rate_table = rtl92ce_update_hal_rate_table, - .update_rate_mask = rtl92ce_update_hal_rate_mask, - .fill_tx_desc = rtl92ce_tx_fill_desc, - .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, - .query_rx_desc = rtl92ce_rx_query_desc, - .set_channel_access = rtl92ce_update_channel_access_setting, - .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking, - .set_bw_mode = rtl92c_phy_set_bw_mode, - .switch_channel = rtl92c_phy_sw_chnl, - .dm_watchdog = rtl92c_dm_watchdog, - .scan_operation_backup = rtl92c_phy_scan_operation_backup, - .set_rf_power_state = rtl92c_phy_set_rf_power_state, - .led_control = rtl92ce_led_control, - .set_desc = rtl92ce_set_desc, - .get_desc = rtl92ce_get_desc, - .tx_polling = rtl92ce_tx_polling, - .enable_hw_sec = rtl92ce_enable_hw_security_config, - .set_key = rtl92ce_set_key, - .init_sw_leds = rtl92ce_init_sw_leds, - .deinit_sw_leds = rtl92ce_deinit_sw_leds, - .get_bbreg = rtl92c_phy_query_bb_reg, - .set_bbreg = rtl92c_phy_set_bb_reg, - .get_rfreg = rtl92c_phy_query_rf_reg, - .set_rfreg = rtl92c_phy_set_rf_reg, -}; - -static struct rtl_mod_params rtl92ce_mod_params = { - .sw_crypto = 0, -}; - -static struct rtl_hal_cfg rtl92ce_hal_cfg = { - .name = "rtl92c_pci", - .fw_name = "rtlwifi/rtl8192cfw.bin", - .ops = &rtl8192ce_hal_ops, - .mod_params = &rtl92ce_mod_params, - - .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, - .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, - .maps[SYS_CLK] = REG_SYS_CLKR, - .maps[MAC_RCR_AM] = AM, - .maps[MAC_RCR_AB] = AB, - .maps[MAC_RCR_ACRC32] = ACRC32, - .maps[MAC_RCR_ACF] = ACF, - .maps[MAC_RCR_AAP] = AAP, - - .maps[EFUSE_TEST] = REG_EFUSE_TEST, - .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_CLK] = 0, - .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_PWC_EV12V] = PWC_EV12V, - .maps[EFUSE_FEN_ELDR] = FEN_ELDR, - .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, - .maps[EFUSE_ANA8M] = EFUSE_ANA8M, - .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, - - .maps[RWCAM] = REG_CAMCMD, - .maps[WCAMI] = REG_CAMWRITE, - .maps[RCAMO] = REG_CAMREAD, - .maps[CAMDBG] = REG_CAMDBG, - .maps[SECR] = REG_SECCFG, - .maps[SEC_CAM_NONE] = CAM_NONE, - .maps[SEC_CAM_WEP40] = CAM_WEP40, - .maps[SEC_CAM_TKIP] = CAM_TKIP, - .maps[SEC_CAM_AES] = CAM_AES, - .maps[SEC_CAM_WEP104] = CAM_WEP104, - - .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, - .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, - .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, - .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, - .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, - .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, - .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, - .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, - .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, - .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, - .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, - .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, - .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, - .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, - .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, - .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, - - .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, - .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, - .maps[RTL_IMR_BcnInt] = IMR_BCNINT, - .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, - .maps[RTL_IMR_RDU] = IMR_RDU, - .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, - .maps[RTL_IMR_BDOK] = IMR_BDOK, - .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, - .maps[RTL_IMR_TBDER] = IMR_TBDER, - .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, - .maps[RTL_IMR_TBDOK] = IMR_TBDOK, - .maps[RTL_IMR_BKDOK] = IMR_BKDOK, - .maps[RTL_IMR_BEDOK] = IMR_BEDOK, - .maps[RTL_IMR_VIDOK] = IMR_VIDOK, - .maps[RTL_IMR_VODOK] = IMR_VODOK, - .maps[RTL_IMR_ROK] = IMR_ROK, - .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), - - .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, - .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, - .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, - .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, - .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, - .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, - .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, - .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, - .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, - .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, - .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, - .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, - - .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, - .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, -}; - -static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = { - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)}, - {}, -}; - -MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids); - -MODULE_AUTHOR("lizhaoming "); -MODULE_AUTHOR("Realtek WlanFAE "); -MODULE_AUTHOR("Larry Finger "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); -MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); - -module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); -MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); - -static struct pci_driver rtl92ce_driver = { - .name = KBUILD_MODNAME, - .id_table = rtl92ce_pci_ids, - .probe = rtl_pci_probe, - .remove = rtl_pci_disconnect, - -#ifdef CONFIG_PM - .suspend = rtl_pci_suspend, - .resume = rtl_pci_resume, -#endif - -}; - -static int __init rtl92ce_module_init(void) -{ - int ret; - - ret = pci_register_driver(&rtl92ce_driver); - if (ret) - RT_ASSERT(false, (": No device found\n")); - - return ret; -} - -static void __exit rtl92ce_module_exit(void) -{ - pci_unregister_driver(&rtl92ce_driver); -} - -module_init(rtl92ce_module_init); -module_exit(rtl92ce_module_exit); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h deleted file mode 100644 index de1198c38d4e..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_SW_H__ -#define __RTL92CE_SW_H__ - -int rtl92c_init_sw_vars(struct ieee80211_hw *hw); -void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); -void rtl92c_init_var_map(struct ieee80211_hw *hw); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c deleted file mode 100644 index 2a9bbbe691a4..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c +++ /dev/null @@ -1,1224 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#include "rtl8192c-table.h" - - -u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = { - 0x024, 0x0011800f, - 0x028, 0x00ffdb83, - 0x800, 0x80040002, - 0x804, 0x00000003, - 0x808, 0x0000fc00, - 0x80c, 0x0000000a, - 0x810, 0x10005388, - 0x814, 0x020c3d10, - 0x818, 0x02200385, - 0x81c, 0x00000000, - 0x820, 0x01000100, - 0x824, 0x00390004, - 0x828, 0x01000100, - 0x82c, 0x00390004, - 0x830, 0x27272727, - 0x834, 0x27272727, - 0x838, 0x27272727, - 0x83c, 0x27272727, - 0x840, 0x00010000, - 0x844, 0x00010000, - 0x848, 0x27272727, - 0x84c, 0x27272727, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x569a569a, - 0x85c, 0x0c1b25a4, - 0x860, 0x66e60230, - 0x864, 0x061f0130, - 0x868, 0x27272727, - 0x86c, 0x2b2b2b27, - 0x870, 0x07000700, - 0x874, 0x22184000, - 0x878, 0x08080808, - 0x87c, 0x00000000, - 0x880, 0xc0083070, - 0x884, 0x000004d5, - 0x888, 0x00000000, - 0x88c, 0xcc0000c0, - 0x890, 0x00000800, - 0x894, 0xfffffffe, - 0x898, 0x40302010, - 0x89c, 0x00706050, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x81121313, - 0xa00, 0x00d047c8, - 0xa04, 0x80ff000c, - 0xa08, 0x8c838300, - 0xa0c, 0x2e68120f, - 0xa10, 0x9500bb78, - 0xa14, 0x11144028, - 0xa18, 0x00881117, - 0xa1c, 0x89140f00, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00d30000, - 0xa70, 0x101fbf00, - 0xa74, 0x00000007, - 0xc00, 0x48071d40, - 0xc04, 0x03a05633, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08800000, - 0xc1c, 0x40000100, - 0xc20, 0x00000000, - 0xc24, 0x00000000, - 0xc28, 0x00000000, - 0xc2c, 0x00000000, - 0xc30, 0x69e9ac44, - 0xc34, 0x469652cf, - 0xc38, 0x49795994, - 0xc3c, 0x0a97971c, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020107, - 0xc4c, 0x007f037f, - 0xc50, 0x69543420, - 0xc54, 0x43bc0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x00000000, - 0xc64, 0x5116848b, - 0xc68, 0x47c00bff, - 0xc6c, 0x00000036, - 0xc70, 0x2c7f000d, - 0xc74, 0x018610db, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20f60000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x00121820, - 0xc94, 0x00000000, - 0xc98, 0x00121820, - 0xc9c, 0x00007f7f, - 0xca0, 0x00000000, - 0xca4, 0x00000080, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x28000000, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xce4, 0x00000000, - 0xce8, 0x37644302, - 0xcec, 0x2f97d40c, - 0xd00, 0x00080740, - 0xd04, 0x00020403, - 0xd08, 0x0000907f, - 0xd0c, 0x20010201, - 0xd10, 0xa0633333, - 0xd14, 0x3333bc43, - 0xd18, 0x7a8f5b6b, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x80608000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x00000000, - 0xd58, 0x00000000, - 0xd5c, 0x30032064, - 0xd60, 0x4653de68, - 0xd64, 0x04518a3c, - 0xd68, 0x00002101, - 0xd6c, 0x2a201c16, - 0xd70, 0x1812362e, - 0xd74, 0x322c2220, - 0xd78, 0x000e3c24, - 0xe00, 0x2a2a2a2a, - 0xe04, 0x2a2a2a2a, - 0xe08, 0x03902a2a, - 0xe10, 0x2a2a2a2a, - 0xe14, 0x2a2a2a2a, - 0xe18, 0x2a2a2a2a, - 0xe1c, 0x2a2a2a2a, - 0xe28, 0x00000000, - 0xe30, 0x1000dc1f, - 0xe34, 0x10008c1f, - 0xe38, 0x02140102, - 0xe3c, 0x681604c2, - 0xe40, 0x01007c00, - 0xe44, 0x01004800, - 0xe48, 0xfb000000, - 0xe4c, 0x000028d1, - 0xe50, 0x1000dc1f, - 0xe54, 0x10008c1f, - 0xe58, 0x02140102, - 0xe5c, 0x28160d05, - 0xe60, 0x00000010, - 0xe68, 0x001b25a4, - 0xe6c, 0x63db25a4, - 0xe70, 0x63db25a4, - 0xe74, 0x0c1b25a4, - 0xe78, 0x0c1b25a4, - 0xe7c, 0x0c1b25a4, - 0xe80, 0x0c1b25a4, - 0xe84, 0x63db25a4, - 0xe88, 0x0c1b25a4, - 0xe8c, 0x63db25a4, - 0xed0, 0x63db25a4, - 0xed4, 0x63db25a4, - 0xed8, 0x63db25a4, - 0xedc, 0x001b25a4, - 0xee0, 0x001b25a4, - 0xeec, 0x6fdb25a4, - 0xf14, 0x00000003, - 0xf4c, 0x00000000, - 0xf00, 0x00000300, -}; - -u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = { - 0x024, 0x0011800f, - 0x028, 0x00ffdb83, - 0x800, 0x80040000, - 0x804, 0x00000001, - 0x808, 0x0000fc00, - 0x80c, 0x0000000a, - 0x810, 0x10005388, - 0x814, 0x020c3d10, - 0x818, 0x02200385, - 0x81c, 0x00000000, - 0x820, 0x01000100, - 0x824, 0x00390004, - 0x828, 0x00000000, - 0x82c, 0x00000000, - 0x830, 0x00000000, - 0x834, 0x00000000, - 0x838, 0x00000000, - 0x83c, 0x00000000, - 0x840, 0x00010000, - 0x844, 0x00000000, - 0x848, 0x00000000, - 0x84c, 0x00000000, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x569a569a, - 0x85c, 0x001b25a4, - 0x860, 0x66e60230, - 0x864, 0x061f0130, - 0x868, 0x00000000, - 0x86c, 0x32323200, - 0x870, 0x07000700, - 0x874, 0x22004000, - 0x878, 0x00000808, - 0x87c, 0x00000000, - 0x880, 0xc0083070, - 0x884, 0x000004d5, - 0x888, 0x00000000, - 0x88c, 0xccc000c0, - 0x890, 0x00000800, - 0x894, 0xfffffffe, - 0x898, 0x40302010, - 0x89c, 0x00706050, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x81121111, - 0xa00, 0x00d047c8, - 0xa04, 0x80ff000c, - 0xa08, 0x8c838300, - 0xa0c, 0x2e68120f, - 0xa10, 0x9500bb78, - 0xa14, 0x11144028, - 0xa18, 0x00881117, - 0xa1c, 0x89140f00, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00d30000, - 0xa70, 0x101fbf00, - 0xa74, 0x00000007, - 0xc00, 0x48071d40, - 0xc04, 0x03a05611, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08800000, - 0xc1c, 0x40000100, - 0xc20, 0x00000000, - 0xc24, 0x00000000, - 0xc28, 0x00000000, - 0xc2c, 0x00000000, - 0xc30, 0x69e9ac44, - 0xc34, 0x469652cf, - 0xc38, 0x49795994, - 0xc3c, 0x0a97971c, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020107, - 0xc4c, 0x007f037f, - 0xc50, 0x69543420, - 0xc54, 0x43bc0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x00000000, - 0xc64, 0x5116848b, - 0xc68, 0x47c00bff, - 0xc6c, 0x00000036, - 0xc70, 0x2c7f000d, - 0xc74, 0x018610db, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20f60000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x00121820, - 0xc94, 0x00000000, - 0xc98, 0x00121820, - 0xc9c, 0x00007f7f, - 0xca0, 0x00000000, - 0xca4, 0x00000080, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x28000000, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xce4, 0x00000000, - 0xce8, 0x37644302, - 0xcec, 0x2f97d40c, - 0xd00, 0x00080740, - 0xd04, 0x00020401, - 0xd08, 0x0000907f, - 0xd0c, 0x20010201, - 0xd10, 0xa0633333, - 0xd14, 0x3333bc43, - 0xd18, 0x7a8f5b6b, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x80608000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x00000000, - 0xd58, 0x00000000, - 0xd5c, 0x30032064, - 0xd60, 0x4653de68, - 0xd64, 0x04518a3c, - 0xd68, 0x00002101, - 0xd6c, 0x2a201c16, - 0xd70, 0x1812362e, - 0xd74, 0x322c2220, - 0xd78, 0x000e3c24, - 0xe00, 0x2a2a2a2a, - 0xe04, 0x2a2a2a2a, - 0xe08, 0x03902a2a, - 0xe10, 0x2a2a2a2a, - 0xe14, 0x2a2a2a2a, - 0xe18, 0x2a2a2a2a, - 0xe1c, 0x2a2a2a2a, - 0xe28, 0x00000000, - 0xe30, 0x1000dc1f, - 0xe34, 0x10008c1f, - 0xe38, 0x02140102, - 0xe3c, 0x681604c2, - 0xe40, 0x01007c00, - 0xe44, 0x01004800, - 0xe48, 0xfb000000, - 0xe4c, 0x000028d1, - 0xe50, 0x1000dc1f, - 0xe54, 0x10008c1f, - 0xe58, 0x02140102, - 0xe5c, 0x28160d05, - 0xe60, 0x00000010, - 0xe68, 0x001b25a4, - 0xe6c, 0x631b25a0, - 0xe70, 0x631b25a0, - 0xe74, 0x081b25a0, - 0xe78, 0x081b25a0, - 0xe7c, 0x081b25a0, - 0xe80, 0x081b25a0, - 0xe84, 0x631b25a0, - 0xe88, 0x081b25a0, - 0xe8c, 0x631b25a0, - 0xed0, 0x631b25a0, - 0xed4, 0x631b25a0, - 0xed8, 0x631b25a0, - 0xedc, 0x001b25a0, - 0xee0, 0x001b25a0, - 0xeec, 0x6b1b25a0, - 0xf14, 0x00000003, - 0xf4c, 0x00000000, - 0xf00, 0x00000300, -}; - -u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = { - 0xe00, 0xffffffff, 0x0a0c0c0c, - 0xe04, 0xffffffff, 0x02040608, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x0a0c0d0e, - 0xe14, 0xffffffff, 0x02040608, - 0xe18, 0xffffffff, 0x0a0c0d0e, - 0xe1c, 0xffffffff, 0x02040608, - 0x830, 0xffffffff, 0x0a0c0c0c, - 0x834, 0xffffffff, 0x02040608, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x0a0c0d0e, - 0x848, 0xffffffff, 0x02040608, - 0x84c, 0xffffffff, 0x0a0c0d0e, - 0x868, 0xffffffff, 0x02040608, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x04040404, - 0xe04, 0xffffffff, 0x00020204, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x06060606, - 0xe14, 0xffffffff, 0x00020406, - 0xe18, 0xffffffff, 0x06060606, - 0xe1c, 0xffffffff, 0x00020406, - 0x830, 0xffffffff, 0x04040404, - 0x834, 0xffffffff, 0x00020204, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x06060606, - 0x848, 0xffffffff, 0x00020406, - 0x84c, 0xffffffff, 0x06060606, - 0x868, 0xffffffff, 0x00020406, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, -}; - -u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = { - 0x000, 0x00030159, - 0x001, 0x00031284, - 0x002, 0x00098000, - 0x003, 0x00018c63, - 0x004, 0x000210e7, - 0x009, 0x0002044f, - 0x00a, 0x0001adb0, - 0x00b, 0x00054867, - 0x00c, 0x0008992e, - 0x00d, 0x0000e52c, - 0x00e, 0x00039ce7, - 0x00f, 0x00000451, - 0x019, 0x00000000, - 0x01a, 0x00010255, - 0x01b, 0x00060a00, - 0x01c, 0x000fc378, - 0x01d, 0x000a1250, - 0x01e, 0x0004445f, - 0x01f, 0x00080001, - 0x020, 0x0000b614, - 0x021, 0x0006c000, - 0x022, 0x00000000, - 0x023, 0x00001558, - 0x024, 0x00000060, - 0x025, 0x00000483, - 0x026, 0x0004f000, - 0x027, 0x000ec7d9, - 0x028, 0x000977c0, - 0x029, 0x00004783, - 0x02a, 0x00000001, - 0x02b, 0x00021334, - 0x02a, 0x00000000, - 0x02b, 0x00000054, - 0x02a, 0x00000001, - 0x02b, 0x00000808, - 0x02b, 0x00053333, - 0x02c, 0x0000000c, - 0x02a, 0x00000002, - 0x02b, 0x00000808, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000003, - 0x02b, 0x00000808, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000004, - 0x02b, 0x00000808, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000005, - 0x02b, 0x00000808, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x00000006, - 0x02b, 0x00000709, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000007, - 0x02b, 0x00000709, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000008, - 0x02b, 0x0000060a, - 0x02b, 0x0004b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000009, - 0x02b, 0x0000060a, - 0x02b, 0x00053333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000a, - 0x02b, 0x0000060a, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000b, - 0x02b, 0x0000060a, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000c, - 0x02b, 0x0000060a, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000d, - 0x02b, 0x0000060a, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000e, - 0x02b, 0x0000050b, - 0x02b, 0x00066666, - 0x02c, 0x0000001a, - 0x02a, 0x000e0000, - 0x010, 0x0004000f, - 0x011, 0x000e31fc, - 0x010, 0x0006000f, - 0x011, 0x000ff9f8, - 0x010, 0x0002000f, - 0x011, 0x000203f9, - 0x010, 0x0003000f, - 0x011, 0x000ff500, - 0x010, 0x00000000, - 0x011, 0x00000000, - 0x010, 0x0008000f, - 0x011, 0x0003f100, - 0x010, 0x0009000f, - 0x011, 0x00023100, - 0x012, 0x00032000, - 0x012, 0x00071000, - 0x012, 0x000b0000, - 0x012, 0x000fc000, - 0x013, 0x000287af, - 0x013, 0x000244b7, - 0x013, 0x000204ab, - 0x013, 0x0001c49f, - 0x013, 0x00018493, - 0x013, 0x00014297, - 0x013, 0x00010295, - 0x013, 0x0000c298, - 0x013, 0x0000819c, - 0x013, 0x000040a8, - 0x013, 0x0000001c, - 0x014, 0x0001944c, - 0x014, 0x00059444, - 0x014, 0x0009944c, - 0x014, 0x000d9444, - 0x015, 0x0000f424, - 0x015, 0x0004f424, - 0x015, 0x0008f424, - 0x015, 0x000cf424, - 0x016, 0x000e0330, - 0x016, 0x000a0330, - 0x016, 0x00060330, - 0x016, 0x00020330, - 0x000, 0x00010159, - 0x018, 0x0000f401, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01f, 0x00080003, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01e, 0x00044457, - 0x01f, 0x00080000, - 0x000, 0x00030159, -}; - -u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = { - 0x000, 0x00030159, - 0x001, 0x00031284, - 0x002, 0x00098000, - 0x003, 0x00018c63, - 0x004, 0x000210e7, - 0x009, 0x0002044f, - 0x00a, 0x0001adb0, - 0x00b, 0x00054867, - 0x00c, 0x0008992e, - 0x00d, 0x0000e52c, - 0x00e, 0x00039ce7, - 0x00f, 0x00000451, - 0x012, 0x00032000, - 0x012, 0x00071000, - 0x012, 0x000b0000, - 0x012, 0x000fc000, - 0x013, 0x000287af, - 0x013, 0x000244b7, - 0x013, 0x000204ab, - 0x013, 0x0001c49f, - 0x013, 0x00018493, - 0x013, 0x00014297, - 0x013, 0x00010295, - 0x013, 0x0000c298, - 0x013, 0x0000819c, - 0x013, 0x000040a8, - 0x013, 0x0000001c, - 0x014, 0x0001944c, - 0x014, 0x00059444, - 0x014, 0x0009944c, - 0x014, 0x000d9444, - 0x015, 0x0000f424, - 0x015, 0x0004f424, - 0x015, 0x0008f424, - 0x015, 0x000cf424, - 0x016, 0x000e0330, - 0x016, 0x000a0330, - 0x016, 0x00060330, - 0x016, 0x00020330, -}; - -u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = { - 0x000, 0x00030159, - 0x001, 0x00031284, - 0x002, 0x00098000, - 0x003, 0x00018c63, - 0x004, 0x000210e7, - 0x009, 0x0002044f, - 0x00a, 0x0001adb0, - 0x00b, 0x00054867, - 0x00c, 0x0008992e, - 0x00d, 0x0000e52c, - 0x00e, 0x00039ce7, - 0x00f, 0x00000451, - 0x019, 0x00000000, - 0x01a, 0x00010255, - 0x01b, 0x00060a00, - 0x01c, 0x000fc378, - 0x01d, 0x000a1250, - 0x01e, 0x0004445f, - 0x01f, 0x00080001, - 0x020, 0x0000b614, - 0x021, 0x0006c000, - 0x022, 0x00000000, - 0x023, 0x00001558, - 0x024, 0x00000060, - 0x025, 0x00000483, - 0x026, 0x0004f000, - 0x027, 0x000ec7d9, - 0x028, 0x000977c0, - 0x029, 0x00004783, - 0x02a, 0x00000001, - 0x02b, 0x00021334, - 0x02a, 0x00000000, - 0x02b, 0x00000054, - 0x02a, 0x00000001, - 0x02b, 0x00000808, - 0x02b, 0x00053333, - 0x02c, 0x0000000c, - 0x02a, 0x00000002, - 0x02b, 0x00000808, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000003, - 0x02b, 0x00000808, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000004, - 0x02b, 0x00000808, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000005, - 0x02b, 0x00000808, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x00000006, - 0x02b, 0x00000709, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000007, - 0x02b, 0x00000709, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000008, - 0x02b, 0x0000060a, - 0x02b, 0x0004b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000009, - 0x02b, 0x0000060a, - 0x02b, 0x00053333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000a, - 0x02b, 0x0000060a, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000b, - 0x02b, 0x0000060a, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000c, - 0x02b, 0x0000060a, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000d, - 0x02b, 0x0000060a, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000e, - 0x02b, 0x0000050b, - 0x02b, 0x00066666, - 0x02c, 0x0000001a, - 0x02a, 0x000e0000, - 0x010, 0x0004000f, - 0x011, 0x000e31fc, - 0x010, 0x0006000f, - 0x011, 0x000ff9f8, - 0x010, 0x0002000f, - 0x011, 0x000203f9, - 0x010, 0x0003000f, - 0x011, 0x000ff500, - 0x010, 0x00000000, - 0x011, 0x00000000, - 0x010, 0x0008000f, - 0x011, 0x0003f100, - 0x010, 0x0009000f, - 0x011, 0x00023100, - 0x012, 0x00032000, - 0x012, 0x00071000, - 0x012, 0x000b0000, - 0x012, 0x000fc000, - 0x013, 0x000287af, - 0x013, 0x000244b7, - 0x013, 0x000204ab, - 0x013, 0x0001c49f, - 0x013, 0x00018493, - 0x013, 0x00014297, - 0x013, 0x00010295, - 0x013, 0x0000c298, - 0x013, 0x0000819c, - 0x013, 0x000040a8, - 0x013, 0x0000001c, - 0x014, 0x0001944c, - 0x014, 0x00059444, - 0x014, 0x0009944c, - 0x014, 0x000d9444, - 0x015, 0x0000f424, - 0x015, 0x0004f424, - 0x015, 0x0008f424, - 0x015, 0x000cf424, - 0x016, 0x000e0330, - 0x016, 0x000a0330, - 0x016, 0x00060330, - 0x016, 0x00020330, - 0x000, 0x00010159, - 0x018, 0x0000f401, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01f, 0x00080003, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01e, 0x00044457, - 0x01f, 0x00080000, - 0x000, 0x00030159, -}; - -u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = { - 0x0, -}; - -u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = { - 0x420, 0x00000080, - 0x423, 0x00000000, - 0x430, 0x00000000, - 0x431, 0x00000000, - 0x432, 0x00000000, - 0x433, 0x00000001, - 0x434, 0x00000004, - 0x435, 0x00000005, - 0x436, 0x00000006, - 0x437, 0x00000007, - 0x438, 0x00000000, - 0x439, 0x00000000, - 0x43a, 0x00000000, - 0x43b, 0x00000001, - 0x43c, 0x00000004, - 0x43d, 0x00000005, - 0x43e, 0x00000006, - 0x43f, 0x00000007, - 0x440, 0x0000005d, - 0x441, 0x00000001, - 0x442, 0x00000000, - 0x444, 0x00000015, - 0x445, 0x000000f0, - 0x446, 0x0000000f, - 0x447, 0x00000000, - 0x458, 0x00000041, - 0x459, 0x000000a8, - 0x45a, 0x00000072, - 0x45b, 0x000000b9, - 0x460, 0x00000088, - 0x461, 0x00000088, - 0x462, 0x00000006, - 0x463, 0x00000003, - 0x4c8, 0x00000004, - 0x4c9, 0x00000008, - 0x4cc, 0x00000002, - 0x4cd, 0x00000028, - 0x4ce, 0x00000001, - 0x500, 0x00000026, - 0x501, 0x000000a2, - 0x502, 0x0000002f, - 0x503, 0x00000000, - 0x504, 0x00000028, - 0x505, 0x000000a3, - 0x506, 0x0000005e, - 0x507, 0x00000000, - 0x508, 0x0000002b, - 0x509, 0x000000a4, - 0x50a, 0x0000005e, - 0x50b, 0x00000000, - 0x50c, 0x0000004f, - 0x50d, 0x000000a4, - 0x50e, 0x00000000, - 0x50f, 0x00000000, - 0x512, 0x0000001c, - 0x514, 0x0000000a, - 0x515, 0x00000010, - 0x516, 0x0000000a, - 0x517, 0x00000010, - 0x51a, 0x00000016, - 0x524, 0x0000000f, - 0x525, 0x0000004f, - 0x546, 0x00000020, - 0x547, 0x00000000, - 0x559, 0x00000002, - 0x55a, 0x00000002, - 0x55d, 0x000000ff, - 0x605, 0x00000030, - 0x608, 0x0000000e, - 0x609, 0x0000002a, - 0x652, 0x00000020, - 0x63c, 0x0000000a, - 0x63d, 0x0000000a, - 0x700, 0x00000021, - 0x701, 0x00000043, - 0x702, 0x00000065, - 0x703, 0x00000087, - 0x708, 0x00000021, - 0x709, 0x00000043, - 0x70a, 0x00000065, - 0x70b, 0x00000087, -}; - -u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = { - 0xc78, 0x7b000001, - 0xc78, 0x7b010001, - 0xc78, 0x7b020001, - 0xc78, 0x7b030001, - 0xc78, 0x7b040001, - 0xc78, 0x7b050001, - 0xc78, 0x7a060001, - 0xc78, 0x79070001, - 0xc78, 0x78080001, - 0xc78, 0x77090001, - 0xc78, 0x760a0001, - 0xc78, 0x750b0001, - 0xc78, 0x740c0001, - 0xc78, 0x730d0001, - 0xc78, 0x720e0001, - 0xc78, 0x710f0001, - 0xc78, 0x70100001, - 0xc78, 0x6f110001, - 0xc78, 0x6e120001, - 0xc78, 0x6d130001, - 0xc78, 0x6c140001, - 0xc78, 0x6b150001, - 0xc78, 0x6a160001, - 0xc78, 0x69170001, - 0xc78, 0x68180001, - 0xc78, 0x67190001, - 0xc78, 0x661a0001, - 0xc78, 0x651b0001, - 0xc78, 0x641c0001, - 0xc78, 0x631d0001, - 0xc78, 0x621e0001, - 0xc78, 0x611f0001, - 0xc78, 0x60200001, - 0xc78, 0x49210001, - 0xc78, 0x48220001, - 0xc78, 0x47230001, - 0xc78, 0x46240001, - 0xc78, 0x45250001, - 0xc78, 0x44260001, - 0xc78, 0x43270001, - 0xc78, 0x42280001, - 0xc78, 0x41290001, - 0xc78, 0x402a0001, - 0xc78, 0x262b0001, - 0xc78, 0x252c0001, - 0xc78, 0x242d0001, - 0xc78, 0x232e0001, - 0xc78, 0x222f0001, - 0xc78, 0x21300001, - 0xc78, 0x20310001, - 0xc78, 0x06320001, - 0xc78, 0x05330001, - 0xc78, 0x04340001, - 0xc78, 0x03350001, - 0xc78, 0x02360001, - 0xc78, 0x01370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7b400001, - 0xc78, 0x7b410001, - 0xc78, 0x7b420001, - 0xc78, 0x7b430001, - 0xc78, 0x7b440001, - 0xc78, 0x7b450001, - 0xc78, 0x7a460001, - 0xc78, 0x79470001, - 0xc78, 0x78480001, - 0xc78, 0x77490001, - 0xc78, 0x764a0001, - 0xc78, 0x754b0001, - 0xc78, 0x744c0001, - 0xc78, 0x734d0001, - 0xc78, 0x724e0001, - 0xc78, 0x714f0001, - 0xc78, 0x70500001, - 0xc78, 0x6f510001, - 0xc78, 0x6e520001, - 0xc78, 0x6d530001, - 0xc78, 0x6c540001, - 0xc78, 0x6b550001, - 0xc78, 0x6a560001, - 0xc78, 0x69570001, - 0xc78, 0x68580001, - 0xc78, 0x67590001, - 0xc78, 0x665a0001, - 0xc78, 0x655b0001, - 0xc78, 0x645c0001, - 0xc78, 0x635d0001, - 0xc78, 0x625e0001, - 0xc78, 0x615f0001, - 0xc78, 0x60600001, - 0xc78, 0x49610001, - 0xc78, 0x48620001, - 0xc78, 0x47630001, - 0xc78, 0x46640001, - 0xc78, 0x45650001, - 0xc78, 0x44660001, - 0xc78, 0x43670001, - 0xc78, 0x42680001, - 0xc78, 0x41690001, - 0xc78, 0x406a0001, - 0xc78, 0x266b0001, - 0xc78, 0x256c0001, - 0xc78, 0x246d0001, - 0xc78, 0x236e0001, - 0xc78, 0x226f0001, - 0xc78, 0x21700001, - 0xc78, 0x20710001, - 0xc78, 0x06720001, - 0xc78, 0x05730001, - 0xc78, 0x04740001, - 0xc78, 0x03750001, - 0xc78, 0x02760001, - 0xc78, 0x01770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x3800001e, - 0xc78, 0x3801001e, - 0xc78, 0x3802001e, - 0xc78, 0x3803001e, - 0xc78, 0x3804001e, - 0xc78, 0x3805001e, - 0xc78, 0x3806001e, - 0xc78, 0x3807001e, - 0xc78, 0x3808001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3e0a001e, - 0xc78, 0x400b001e, - 0xc78, 0x440c001e, - 0xc78, 0x480d001e, - 0xc78, 0x4c0e001e, - 0xc78, 0x500f001e, - 0xc78, 0x5210001e, - 0xc78, 0x5611001e, - 0xc78, 0x5a12001e, - 0xc78, 0x5e13001e, - 0xc78, 0x6014001e, - 0xc78, 0x6015001e, - 0xc78, 0x6016001e, - 0xc78, 0x6217001e, - 0xc78, 0x6218001e, - 0xc78, 0x6219001e, - 0xc78, 0x621a001e, - 0xc78, 0x621b001e, - 0xc78, 0x621c001e, - 0xc78, 0x621d001e, - 0xc78, 0x621e001e, - 0xc78, 0x621f001e, -}; - -u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = { - 0xc78, 0x7b000001, - 0xc78, 0x7b010001, - 0xc78, 0x7b020001, - 0xc78, 0x7b030001, - 0xc78, 0x7b040001, - 0xc78, 0x7b050001, - 0xc78, 0x7a060001, - 0xc78, 0x79070001, - 0xc78, 0x78080001, - 0xc78, 0x77090001, - 0xc78, 0x760a0001, - 0xc78, 0x750b0001, - 0xc78, 0x740c0001, - 0xc78, 0x730d0001, - 0xc78, 0x720e0001, - 0xc78, 0x710f0001, - 0xc78, 0x70100001, - 0xc78, 0x6f110001, - 0xc78, 0x6e120001, - 0xc78, 0x6d130001, - 0xc78, 0x6c140001, - 0xc78, 0x6b150001, - 0xc78, 0x6a160001, - 0xc78, 0x69170001, - 0xc78, 0x68180001, - 0xc78, 0x67190001, - 0xc78, 0x661a0001, - 0xc78, 0x651b0001, - 0xc78, 0x641c0001, - 0xc78, 0x631d0001, - 0xc78, 0x621e0001, - 0xc78, 0x611f0001, - 0xc78, 0x60200001, - 0xc78, 0x49210001, - 0xc78, 0x48220001, - 0xc78, 0x47230001, - 0xc78, 0x46240001, - 0xc78, 0x45250001, - 0xc78, 0x44260001, - 0xc78, 0x43270001, - 0xc78, 0x42280001, - 0xc78, 0x41290001, - 0xc78, 0x402a0001, - 0xc78, 0x262b0001, - 0xc78, 0x252c0001, - 0xc78, 0x242d0001, - 0xc78, 0x232e0001, - 0xc78, 0x222f0001, - 0xc78, 0x21300001, - 0xc78, 0x20310001, - 0xc78, 0x06320001, - 0xc78, 0x05330001, - 0xc78, 0x04340001, - 0xc78, 0x03350001, - 0xc78, 0x02360001, - 0xc78, 0x01370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7b400001, - 0xc78, 0x7b410001, - 0xc78, 0x7b420001, - 0xc78, 0x7b430001, - 0xc78, 0x7b440001, - 0xc78, 0x7b450001, - 0xc78, 0x7a460001, - 0xc78, 0x79470001, - 0xc78, 0x78480001, - 0xc78, 0x77490001, - 0xc78, 0x764a0001, - 0xc78, 0x754b0001, - 0xc78, 0x744c0001, - 0xc78, 0x734d0001, - 0xc78, 0x724e0001, - 0xc78, 0x714f0001, - 0xc78, 0x70500001, - 0xc78, 0x6f510001, - 0xc78, 0x6e520001, - 0xc78, 0x6d530001, - 0xc78, 0x6c540001, - 0xc78, 0x6b550001, - 0xc78, 0x6a560001, - 0xc78, 0x69570001, - 0xc78, 0x68580001, - 0xc78, 0x67590001, - 0xc78, 0x665a0001, - 0xc78, 0x655b0001, - 0xc78, 0x645c0001, - 0xc78, 0x635d0001, - 0xc78, 0x625e0001, - 0xc78, 0x615f0001, - 0xc78, 0x60600001, - 0xc78, 0x49610001, - 0xc78, 0x48620001, - 0xc78, 0x47630001, - 0xc78, 0x46640001, - 0xc78, 0x45650001, - 0xc78, 0x44660001, - 0xc78, 0x43670001, - 0xc78, 0x42680001, - 0xc78, 0x41690001, - 0xc78, 0x406a0001, - 0xc78, 0x266b0001, - 0xc78, 0x256c0001, - 0xc78, 0x246d0001, - 0xc78, 0x236e0001, - 0xc78, 0x226f0001, - 0xc78, 0x21700001, - 0xc78, 0x20710001, - 0xc78, 0x06720001, - 0xc78, 0x05730001, - 0xc78, 0x04740001, - 0xc78, 0x03750001, - 0xc78, 0x02760001, - 0xc78, 0x01770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x3800001e, - 0xc78, 0x3801001e, - 0xc78, 0x3802001e, - 0xc78, 0x3803001e, - 0xc78, 0x3804001e, - 0xc78, 0x3805001e, - 0xc78, 0x3806001e, - 0xc78, 0x3807001e, - 0xc78, 0x3808001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3e0a001e, - 0xc78, 0x400b001e, - 0xc78, 0x440c001e, - 0xc78, 0x480d001e, - 0xc78, 0x4c0e001e, - 0xc78, 0x500f001e, - 0xc78, 0x5210001e, - 0xc78, 0x5611001e, - 0xc78, 0x5a12001e, - 0xc78, 0x5e13001e, - 0xc78, 0x6014001e, - 0xc78, 0x6015001e, - 0xc78, 0x6016001e, - 0xc78, 0x6217001e, - 0xc78, 0x6218001e, - 0xc78, 0x6219001e, - 0xc78, 0x621a001e, - 0xc78, 0x621b001e, - 0xc78, 0x621c001e, - 0xc78, 0x621d001e, - 0xc78, 0x621e001e, - 0xc78, 0x621f001e, -}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h deleted file mode 100644 index 3a6e8b6aeee0..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_TABLE__H_ -#define __RTL92CE_TABLE__H_ - -#include - -#define PHY_REG_2TARRAY_LENGTH 374 -extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH]; -#define PHY_REG_1TARRAY_LENGTH 374 -extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH]; -#define PHY_REG_ARRAY_PGLENGTH 192 -extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH]; -#define RADIOA_2TARRAYLENGTH 282 -extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH]; -#define RADIOB_2TARRAYLENGTH 78 -extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH]; -#define RADIOA_1TARRAYLENGTH 282 -extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH]; -#define RADIOB_1TARRAYLENGTH 1 -extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH]; -#define MAC_2T_ARRAYLENGTH 162 -extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH]; -#define AGCTAB_2TARRAYLENGTH 320 -extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH]; -#define AGCTAB_1TARRAYLENGTH 320 -extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH]; - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c deleted file mode 100644 index cf35418c8afe..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c +++ /dev/null @@ -1,1031 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "rtl8192c-reg.h" -#include "rtl8192c-def.h" -#include "rtl8192c-phy.h" -#include "rtl8192c-trx.h" -#include "rtl8192c-led.h" - -static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc, - unsigned int - skb_queue) -{ - enum rtl_desc_qsel qsel; - - if (unlikely(ieee80211_is_beacon(fc))) { - qsel = QSLT_BEACON; - return qsel; - } - - if (ieee80211_is_mgmt(fc)) { - qsel = QSLT_MGNT; - return qsel; - } - - switch (skb_queue) { - case VO_QUEUE: - qsel = QSLT_VO; - break; - case VI_QUEUE: - qsel = QSLT_VI; - break; - case BE_QUEUE: - qsel = QSLT_BE; - break; - case BK_QUEUE: - qsel = QSLT_BK; - break; - default: - qsel = QSLT_BE; - RT_ASSERT(false, ("BE queue, skb_queue:%d," - " set qsel = 0x%X\n", skb_queue, QSLT_BE)); - break; - } - return qsel; -} - -static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) -{ - int rate_idx; - - if (first_ampdu) { - if (false == isht) { - switch (desc_rate) { - case DESC92C_RATE1M: - rate_idx = 0; - break; - case DESC92C_RATE2M: - rate_idx = 1; - break; - case DESC92C_RATE5_5M: - rate_idx = 2; - break; - case DESC92C_RATE11M: - rate_idx = 3; - break; - case DESC92C_RATE6M: - rate_idx = 4; - break; - case DESC92C_RATE9M: - rate_idx = 5; - break; - case DESC92C_RATE12M: - rate_idx = 6; - break; - case DESC92C_RATE18M: - rate_idx = 7; - break; - case DESC92C_RATE24M: - rate_idx = 8; - break; - case DESC92C_RATE36M: - rate_idx = 9; - break; - case DESC92C_RATE48M: - rate_idx = 10; - break; - case DESC92C_RATE54M: - rate_idx = 11; - break; - default: - rate_idx = 0; - break; - } - } else { - rate_idx = 11; - } - - return rate_idx; - } - - switch (desc_rate) { - case DESC92C_RATE1M: - rate_idx = 0; - break; - case DESC92C_RATE2M: - rate_idx = 1; - break; - case DESC92C_RATE5_5M: - rate_idx = 2; - break; - case DESC92C_RATE11M: - rate_idx = 3; - break; - case DESC92C_RATE6M: - rate_idx = 4; - break; - case DESC92C_RATE9M: - rate_idx = 5; - break; - case DESC92C_RATE12M: - rate_idx = 6; - break; - case DESC92C_RATE18M: - rate_idx = 7; - break; - case DESC92C_RATE24M: - rate_idx = 8; - break; - case DESC92C_RATE36M: - rate_idx = 9; - break; - case DESC92C_RATE48M: - rate_idx = 10; - break; - case DESC92C_RATE54M: - rate_idx = 11; - break; - default: - rate_idx = 11; - break; - } - return rate_idx; -} - -static u8 _rtl92c_query_rxpwrpercentage(char antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} - -static u8 _rtl92c_evm_db_to_percentage(char value) -{ - char ret_val; - ret_val = value; - - if (ret_val >= 0) - ret_val = 0; - - if (ret_val <= -33) - ret_val = -33; - - ret_val = 0 - ret_val; - ret_val *= 3; - - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} - -static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw, - u8 signal_strength_index) -{ - long signal_power; - - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - return signal_power; -} - -static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw, - long currsig) -{ - long retsig; - - if (currsig >= 61 && currsig <= 100) - retsig = 90 + ((currsig - 60) / 4); - else if (currsig >= 41 && currsig <= 60) - retsig = 78 + ((currsig - 40) / 2); - else if (currsig >= 31 && currsig <= 40) - retsig = 66 + (currsig - 30); - else if (currsig >= 21 && currsig <= 30) - retsig = 54 + (currsig - 20); - else if (currsig >= 5 && currsig <= 20) - retsig = 42 + (((currsig - 5) * 2) / 3); - else if (currsig == 4) - retsig = 36; - else if (currsig == 3) - retsig = 27; - else if (currsig == 2) - retsig = 18; - else if (currsig == 1) - retsig = 9; - else - retsig = currsig; - - return retsig; -} - -static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, - struct rtl_stats *pstats, - struct rx_desc_92c *pdesc, - struct rx_fwinfo_92c *p_drvinfo, - bool bpacket_match_bssid, - bool bpacket_toself, - bool b_packet_beacon) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct phy_sts_cck_8192s_t *cck_buf; - s8 rx_pwr_all, rx_pwr[4]; - u8 rf_rx_num, evm, pwdb_all; - u8 i, max_spatial_stream; - u32 rssi, total_rssi; - bool is_cck_rate; - - is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); - pstats->b_packet_matchbssid = bpacket_match_bssid; - pstats->b_packet_toself = bpacket_toself; - pstats->b_is_cck = is_cck_rate; - pstats->b_packet_beacon = b_packet_beacon; - pstats->b_is_cck = is_cck_rate; - pstats->rx_mimo_signalquality[0] = -1; - pstats->rx_mimo_signalquality[1] = -1; - - if (is_cck_rate) { - u8 report, cck_highpwr; - cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; - - cck_highpwr = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - BIT(9)); - if (!cck_highpwr) { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = cck_buf->cck_agc_rpt & 0xc0; - report = report >> 6; - switch (report) { - case 0x3: - rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); - break; - case 0x2: - rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); - break; - case 0x1: - rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); - break; - case 0x0: - rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); - break; - } - } else { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = p_drvinfo->cfosho[0] & 0x60; - report = report >> 5; - switch (report) { - case 0x3: - rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); - break; - } - } - - pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); - pstats->rx_pwdb_all = pwdb_all; - pstats->recvsignalpower = rx_pwr_all; - - if (bpacket_match_bssid) { - u8 sq; - if (pstats->rx_pwdb_all > 40) - sq = 100; - else { - sq = cck_buf->sq_rpt; - if (sq > 64) - sq = 0; - else if (sq < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - - pstats->signalquality = sq; - pstats->rx_mimo_signalquality[0] = sq; - pstats->rx_mimo_signalquality[1] = -1; - } - } else { - rtlpriv->dm.brfpath_rxenable[0] = - rtlpriv->dm.brfpath_rxenable[1] = true; - for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { - if (rtlpriv->dm.brfpath_rxenable[i]) - rf_rx_num++; - - rx_pwr[i] = - ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; - rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); - total_rssi += rssi; - rtlpriv->stats.rx_snr_db[i] = - (long)(p_drvinfo->rxsnr[i] / 2); - - if (bpacket_match_bssid) - pstats->rx_mimo_signalstrength[i] = (u8) rssi; - } - - rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; - pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); - pstats->rx_pwdb_all = pwdb_all; - pstats->rxpower = rx_pwr_all; - pstats->recvsignalpower = rx_pwr_all; - - if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 && - pdesc->rxmcs <= DESC92C_RATEMCS15) - max_spatial_stream = 2; - else - max_spatial_stream = 1; - - for (i = 0; i < max_spatial_stream; i++) { - evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); - - if (bpacket_match_bssid) { - if (i == 0) - pstats->signalquality = - (u8) (evm & 0xff); - pstats->rx_mimo_signalquality[i] = - (u8) (evm & 0xff); - } - } - } - - if (is_cck_rate) - pstats->signalstrength = - (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all)); - else if (rf_rx_num != 0) - pstats->signalstrength = - (u8) (_rtl92ce_signal_scale_mapping - (hw, total_rssi /= rf_rx_num)); -} - -static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, - struct rtl_stats *pstats) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 rfpath; - u32 last_rssi, tmpval; - - if (pstats->b_packet_toself || pstats->b_packet_beacon) { - rtlpriv->stats.rssi_calculate_cnt++; - - if (rtlpriv->stats.ui_rssi.total_num++ >= - PHY_RSSI_SLID_WIN_MAX) { - rtlpriv->stats.ui_rssi.total_num = - PHY_RSSI_SLID_WIN_MAX; - last_rssi = - rtlpriv->stats.ui_rssi.elements[rtlpriv-> - stats.ui_rssi.index]; - rtlpriv->stats.ui_rssi.total_val -= last_rssi; - } - - rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; - rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. - index++] = - pstats->signalstrength; - - if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) - rtlpriv->stats.ui_rssi.index = 0; - - tmpval = rtlpriv->stats.ui_rssi.total_val / - rtlpriv->stats.ui_rssi.total_num; - rtlpriv->stats.signal_strength = - _rtl92ce_translate_todbm(hw, (u8) tmpval); - pstats->rssi = rtlpriv->stats.signal_strength; - } - - if (!pstats->b_is_cck && pstats->b_packet_toself) { - for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; - rfpath++) { - - if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) - continue; - - if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - pstats->rx_mimo_signalstrength[rfpath]; - - } - - if (pstats->rx_mimo_signalstrength[rfpath] > - rtlpriv->stats.rx_rssi_percentage[rfpath]) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats. - rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - - rtlpriv->stats.rx_rssi_percentage[rfpath] = - rtlpriv->stats.rx_rssi_percentage[rfpath] + - 1; - } else { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats. - rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - } - - } - } -} - -static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw, - struct rtl_stats *pstats) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int weighting; - - if (rtlpriv->stats.recv_signal_power == 0) - rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; - - if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) - weighting = 5; - - else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) - weighting = (-5); - - rtlpriv->stats.recv_signal_power = - (rtlpriv->stats.recv_signal_power * 5 + - pstats->recvsignalpower + weighting) / 6; -} - -static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, - struct rtl_stats *pstats) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undecorated_smoothed_pwdb; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - return; - } else { - undecorated_smoothed_pwdb = - rtlpriv->dm.undecorated_smoothed_pwdb; - } - - if (pstats->b_packet_toself || pstats->b_packet_beacon) { - if (undecorated_smoothed_pwdb < 0) - undecorated_smoothed_pwdb = pstats->rx_pwdb_all; - - if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { - undecorated_smoothed_pwdb = - (((undecorated_smoothed_pwdb) * - (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - - undecorated_smoothed_pwdb = undecorated_smoothed_pwdb - + 1; - } else { - undecorated_smoothed_pwdb = - (((undecorated_smoothed_pwdb) * - (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - } - - rtlpriv->dm.undecorated_smoothed_pwdb = - undecorated_smoothed_pwdb; - _rtl92ce_update_rxsignalstatistics(hw, pstats); - } -} - -static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, - struct rtl_stats *pstats) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 last_evm, n_spatialstream, tmpval; - - if (pstats->signalquality != 0) { - if (pstats->b_packet_toself || pstats->b_packet_beacon) { - - if (rtlpriv->stats.ui_link_quality.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - rtlpriv->stats.ui_link_quality.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = - rtlpriv->stats. - ui_link_quality.elements[rtlpriv-> - stats.ui_link_quality. - index]; - rtlpriv->stats.ui_link_quality.total_val -= - last_evm; - } - - rtlpriv->stats.ui_link_quality.total_val += - pstats->signalquality; - rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats. - ui_link_quality. - index++] = - pstats->signalquality; - - if (rtlpriv->stats.ui_link_quality.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - rtlpriv->stats.ui_link_quality.index = 0; - - tmpval = rtlpriv->stats.ui_link_quality.total_val / - rtlpriv->stats.ui_link_quality.total_num; - rtlpriv->stats.signal_quality = tmpval; - - rtlpriv->stats.last_sigstrength_inpercent = tmpval; - - for (n_spatialstream = 0; n_spatialstream < 2; - n_spatialstream++) { - if (pstats-> - rx_mimo_signalquality[n_spatialstream] != - -1) { - if (rtlpriv->stats. - rx_evm_percentage[n_spatialstream] - == 0) { - rtlpriv->stats. - rx_evm_percentage - [n_spatialstream] = - pstats->rx_mimo_signalquality - [n_spatialstream]; - } - - rtlpriv->stats. - rx_evm_percentage[n_spatialstream] = - ((rtlpriv-> - stats.rx_evm_percentage - [n_spatialstream] * - (RX_SMOOTH_FACTOR - 1)) + - (pstats-> - rx_mimo_signalquality - [n_spatialstream] * 1)) / - (RX_SMOOTH_FACTOR); - } - } - } - } else { - ; - } -} - -static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, - u8 *buffer, - struct rtl_stats *pcurrent_stats) -{ - - if (!pcurrent_stats->b_packet_matchbssid && - !pcurrent_stats->b_packet_beacon) - return; - - _rtl92ce_process_ui_rssi(hw, pcurrent_stats); - _rtl92ce_process_pwdb(hw, pcurrent_stats); - _rtl92ce_process_ui_link_quality(hw, pcurrent_stats); -} - -static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct rtl_stats *pstats, - struct rx_desc_92c *pdesc, - struct rx_fwinfo_92c *p_drvinfo) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - - struct ieee80211_hdr *hdr; - u8 *tmp_buf; - u8 *praddr; - u8 *psaddr; - u16 fc, type; - bool b_packet_matchbssid, b_packet_toself, b_packet_beacon; - - tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; - - hdr = (struct ieee80211_hdr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - psaddr = hdr->addr2; - - b_packet_matchbssid = - ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, - (fc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && - (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv)); - - b_packet_toself = b_packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); - - if (ieee80211_is_beacon(fc)) - b_packet_beacon = true; - - _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, - b_packet_matchbssid, b_packet_toself, - b_packet_beacon); - - _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); -} - -bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *stats, - struct ieee80211_rx_status *rx_status, - u8 *p_desc, struct sk_buff *skb) -{ - struct rx_fwinfo_92c *p_drvinfo; - struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; - - u32 phystatus = GET_RX_DESC_PHYST(pdesc); - stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); - stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * - RX_DRV_INFO_SIZE_UNIT; - stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); - stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc); - stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc); - stats->b_hwerror = (stats->b_crc | stats->b_icv); - stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); - stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); - stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); - stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); - stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) - && (GET_RX_DESC_FAGGR(pdesc) == 1)); - stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); - stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); - - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; - - if (GET_RX_DESC_CRC32(pdesc)) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - - if (!GET_RX_DESC_SWDEC(pdesc)) - rx_status->flag |= RX_FLAG_DECRYPTED; - - if (GET_RX_DESC_BW(pdesc)) - rx_status->flag |= RX_FLAG_40MHZ; - - if (GET_RX_DESC_RXHT(pdesc)) - rx_status->flag |= RX_FLAG_HT; - - rx_status->flag |= RX_FLAG_TSFT; - - if (stats->decrypted) - rx_status->flag |= RX_FLAG_DECRYPTED; - - rx_status->rate_idx = _rtl92ce_rate_mapping((bool) - GET_RX_DESC_RXHT(pdesc), - (u8) - GET_RX_DESC_RXMCS(pdesc), - (bool) - GET_RX_DESC_PAGGR(pdesc)); - - rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus == true) { - p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + - stats->rx_bufshift); - - _rtl92ce_translate_rx_signal_stuff(hw, - skb, stats, pdesc, - p_drvinfo); - } - - /*rx_status->qual = stats->signal; */ - rx_status->signal = stats->rssi + 10; - /*rx_status->noise = -stats->noise; */ - - return true; -} - -void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, struct sk_buff *skb, - unsigned int queue_index) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_defaultadapter = true; - - struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); - - u8 *pdesc = (u8 *) pdesc_tx; - struct rtl_tcb_desc tcb_desc; - u8 *qc = ieee80211_get_qos_ctl(hdr); - u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - u16 seq_number; - u16 fc = le16_to_cpu(hdr->frame_control); - u8 rate_flag = info->control.rates[0].flags; - - enum rtl_desc_qsel fw_qsel = - _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), - queue_index); - - bool b_firstseg = ((hdr->seq_ctrl & - cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); - - bool b_lastseg = ((hdr->frame_control & - cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); - - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - - seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; - - rtl_get_tcb_desc(hw, info, skb, &tcb_desc); - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); - - if (b_firstseg) { - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); - - if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) - SET_TX_DESC_DATA_SHORTGI(pdesc, 1); - - if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && - info->flags & IEEE80211_TX_CTL_AMPDU) { - SET_TX_DESC_AGG_BREAK(pdesc, 1); - SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); - } - SET_TX_DESC_SEQ(pdesc, seq_number); - - SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable && - !tcb_desc. - b_cts_enable) ? 1 : 0)); - SET_TX_DESC_HW_RTS_ENABLE(pdesc, - ((tcb_desc.b_rts_enable - || tcb_desc.b_cts_enable) ? 1 : 0)); - SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0)); - SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0)); - - SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); - SET_TX_DESC_RTS_BW(pdesc, 0); - SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); - SET_TX_DESC_RTS_SHORT(pdesc, - ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? - (tcb_desc.b_rts_use_shortpreamble ? 1 : 0) - : (tcb_desc.b_rts_use_shortgi ? 1 : 0))); - - if (mac->bw_40) { - if (tcb_desc.b_packet_bw) { - SET_TX_DESC_DATA_BW(pdesc, 1); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - - if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { - SET_TX_DESC_TX_SUB_CARRIER(pdesc, - mac->cur_40_prime_sc); - } - } - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); - } - - SET_TX_DESC_LINIP(pdesc, 0); - SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); - - if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; - SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); - } - - if (info->control.hw_key) { - struct ieee80211_key_conf *keyconf = - info->control.hw_key; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x1); - break; - case WLAN_CIPHER_SUITE_CCMP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x3); - break; - default: - SET_TX_DESC_SEC_TYPE(pdesc, 0x0); - break; - - } - } - - SET_TX_DESC_PKT_ID(pdesc, 0); - SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); - - SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); - SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); - SET_TX_DESC_DISABLE_FB(pdesc, 0); - SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); - - if (ieee80211_is_data_qos(fc)) { - if (mac->rdg_en) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); - SET_TX_DESC_RDG_ENABLE(pdesc, 1); - SET_TX_DESC_HTC(pdesc, 1); - } - } - } - - SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0)); - SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0)); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - - if (rtlpriv->dm.b_useramask) { - SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); - SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); - } else { - SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); - SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); - } - - if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps && - ppsc->b_fwctrl_lps) { - SET_TX_DESC_HWSEQ_EN(pdesc, 1); - SET_TX_DESC_PKT_ID(pdesc, 8); - - if (!b_defaultadapter) - SET_TX_DESC_QOS(pdesc, 1); - } - - SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1)); - - if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || - is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { - SET_TX_DESC_BMC(pdesc, 1); - } - - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); -} - -void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, - u8 *pdesc, bool b_firstseg, - bool b_lastseg, struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - u8 fw_queue = QSLT_BEACON; - - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); - - if (b_firstseg) - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); - - SET_TX_DESC_SEQ(pdesc, 0); - - SET_TX_DESC_LINIP(pdesc, 0); - - SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - - SET_TX_DESC_RATE_ID(pdesc, 7); - SET_TX_DESC_MACID(pdesc, 0); - - SET_TX_DESC_OWN(pdesc, 1); - - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_OFFSET(pdesc, 0x20); - - SET_TX_DESC_USE_RATE(pdesc, 1); - - if (!ieee80211_is_data_qos(fc)) { - SET_TX_DESC_HWSEQ_EN(pdesc, 1); - SET_TX_DESC_PKT_ID(pdesc, 8); - } - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); -} - -void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) -{ - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - SET_TX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_TX_NEXTDESC_ADDR: - SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); - break; - default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); - break; - } - } else { - switch (desc_name) { - case HW_DESC_RXOWN: - SET_RX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_RXBUFF_ADDR: - SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); - break; - case HW_DESC_RXPKT_LEN: - SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); - break; - case HW_DESC_RXERO: - SET_RX_DESC_EOR(pdesc, 1); - break; - default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); - break; - } - } -} - -u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) -{ - u32 ret = 0; - - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_TX_DESC_OWN(p_desc); - break; - case HW_DESC_TXBUFF_ADDR: - ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); - break; - default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); - break; - } - } else { - struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_RX_DESC_OWN(pdesc); - break; - case HW_DESC_RXPKT_LEN: - ret = GET_RX_DESC_PKT_LEN(pdesc); - break; - default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); - break; - } - } - return ret; -} - -void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (hw_queue == BEACON_QUEUE) { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); - } else { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, - BIT(0) << (hw_queue)); - } -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h deleted file mode 100644 index 53d0e0a5af5c..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h +++ /dev/null @@ -1,714 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_TRX_H__ -#define __RTL92CE_TRX_H__ - -#define TX_DESC_SIZE 64 -#define TX_DESC_AGGR_SUBFRAME_SIZE 32 - -#define RX_DESC_SIZE 32 -#define RX_DRV_INFO_SIZE_UNIT 8 - -#define TX_DESC_NEXT_DESC_OFFSET 40 -#define USB_HWDESC_HEADER_LEN 32 -#define CRCLENGTH 4 - -#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) -#define SET_TX_DESC_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) -#define SET_TX_DESC_BMC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) -#define SET_TX_DESC_HTC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) -#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) -#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) -#define SET_TX_DESC_LINIP(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) -#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) -#define SET_TX_DESC_GF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_TX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_TX_DESC_PKT_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 16) -#define GET_TX_DESC_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 8) -#define GET_TX_DESC_BMC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 1) -#define GET_TX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 25, 1) -#define GET_TX_DESC_LAST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_TX_DESC_FIRST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_TX_DESC_LINIP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_TX_DESC_NO_ACM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_TX_DESC_GF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_TX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_TX_DESC_MACID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) -#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) -#define SET_TX_DESC_BK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) -#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) -#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) -#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) -#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) -#define SET_TX_DESC_PIFS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) -#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) -#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) -#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) -#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) -#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) - -#define GET_TX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) -#define GET_TX_DESC_AGG_BREAK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) -#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) -#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) -#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) -#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_TX_DESC_PIFS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_TX_DESC_RATE_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) -#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) -#define GET_TX_DESC_SEC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) -#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) - -#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) -#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) -#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) -#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) -#define SET_TX_DESC_RAW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) -#define SET_TX_DESC_CCX(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) -#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) -#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) -#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) -#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) -#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) -#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) - -#define GET_TX_DESC_RTS_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) -#define GET_TX_DESC_DATA_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) -#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) -#define GET_TX_DESC_MORE_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) -#define GET_TX_DESC_RAW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) -#define GET_TX_DESC_CCX(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) -#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) -#define GET_TX_DESC_ANTSEL_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) -#define GET_TX_DESC_ANTSEL_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) -#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) -#define GET_TX_DESC_TX_ANTL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) -#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) - -#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) -#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) -#define SET_TX_DESC_SEQ(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) -#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) - -#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) -#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) -#define GET_TX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) -#define GET_TX_DESC_PKT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) - -#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) -#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) -#define SET_TX_DESC_QOS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) -#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) -#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) -#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) -#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) -#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) -#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) -#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) -#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) -#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) -#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) -#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) -#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) -#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) -#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) -#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) -#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) -#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) -#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) - -#define GET_TX_DESC_RTS_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) -#define GET_TX_DESC_AP_DCFE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) -#define GET_TX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) -#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) -#define GET_TX_DESC_USE_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) -#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) -#define GET_TX_DESC_DISABLE_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) -#define GET_TX_DESC_CTS2SELF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) -#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) -#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) -#define GET_TX_DESC_PORT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) -#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) -#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) -#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) -#define GET_TX_DESC_TX_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) -#define GET_TX_DESC_DATA_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) -#define GET_TX_DESC_DATA_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) -#define GET_TX_DESC_RTS_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) -#define GET_TX_DESC_RTS_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) -#define GET_TX_DESC_RTS_SC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) -#define GET_TX_DESC_RTS_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) - -#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) -#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) -#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) -#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) -#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) -#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) -#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) -#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) - -#define GET_TX_DESC_TX_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) -#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) -#define GET_TX_DESC_CCX_TAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) -#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) -#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) -#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) -#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) -#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) - -#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) -#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) -#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) -#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) -#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) -#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) -#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) -#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) - -#define GET_TX_DESC_TXAGC_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) -#define GET_TX_DESC_TXAGC_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) -#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) -#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) -#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) -#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) -#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) -#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) -#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) -#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) -#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) -#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) - -#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) -#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) -#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) -#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) -#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) -#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) - -#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) -#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) - -#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) -#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) - -#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) -#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) - -#define GET_RX_DESC_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 14) -#define GET_RX_DESC_CRC32(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 14, 1) -#define GET_RX_DESC_ICV(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 15, 1) -#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 4) -#define GET_RX_DESC_SECURITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 20, 3) -#define GET_RX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 23, 1) -#define GET_RX_DESC_SHIFT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 2) -#define GET_RX_DESC_PHYST(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_RX_DESC_SWDEC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_RX_DESC_LS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_RX_DESC_FS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_RX_DESC_EOR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_RX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) -#define SET_RX_DESC_EOR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_RX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_RX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_RX_DESC_TID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) -#define GET_RX_DESC_HWRSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) -#define GET_RX_DESC_PAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_RX_DESC_FAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_RX_DESC_A1_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_RX_DESC_A2_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) -#define GET_RX_DESC_PAM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) -#define GET_RX_DESC_PWR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) -#define GET_RX_DESC_MD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) -#define GET_RX_DESC_MF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) -#define GET_RX_DESC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) -#define GET_RX_DESC_MC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) -#define GET_RX_DESC_BC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) -#define GET_RX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) -#define GET_RX_DESC_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) -#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) -#define GET_RX_DESC_NEXT_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) -#define GET_RX_DESC_RSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) - -#define GET_RX_DESC_RXMCS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) -#define GET_RX_DESC_RXHT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) -#define GET_RX_DESC_SPLCP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) -#define GET_RX_DESC_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) -#define GET_RX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) -#define GET_RX_DESC_HWPC_ERR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) -#define GET_RX_DESC_HWPC_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) -#define GET_RX_DESC_IV0(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) - -#define GET_RX_DESC_IV1(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) -#define GET_RX_DESC_TSFL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) - -#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) -#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) - -#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) -#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) - -#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ -do { \ - if (_size > TX_DESC_NEXT_DESC_OFFSET) \ - memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ - else \ - memset((void *)__pdesc, 0, _size); \ -} while (0); - -#define RX_HAL_IS_CCK_RATE(_pdesc)\ - (_pdesc->rxmcs == DESC92C_RATE1M || \ - _pdesc->rxmcs == DESC92C_RATE2M || \ - _pdesc->rxmcs == DESC92C_RATE5_5M || \ - _pdesc->rxmcs == DESC92C_RATE11M) - -struct rx_fwinfo_92c { - u8 gain_trsw[4]; - u8 pwdb_all; - u8 cfosho[4]; - u8 cfotail[4]; - char rxevm[2]; - char rxsnr[4]; - u8 pdsnr[2]; - u8 csi_current[2]; - u8 csi_target[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 ex_intf_flag:1; - u8 sgi_en:1; - u8 rxsc:2; - u8 reserve:4; -} __packed; - -struct tx_desc_92c { - u32 pktsize:16; - u32 offset:8; - u32 bmc:1; - u32 htc:1; - u32 lastseg:1; - u32 firstseg:1; - u32 linip:1; - u32 noacm:1; - u32 gf:1; - u32 own:1; - - u32 macid:5; - u32 agg_en:1; - u32 bk:1; - u32 rdg_en:1; - u32 queuesel:5; - u32 rd_nav_ext:1; - u32 lsig_txop_en:1; - u32 pifs:1; - u32 rateid:4; - u32 nav_usehdr:1; - u32 en_descid:1; - u32 sectype:2; - u32 pktoffset:8; - - u32 rts_rc:6; - u32 data_rc:6; - u32 rsvd0:2; - u32 bar_retryht:2; - u32 rsvd1:1; - u32 morefrag:1; - u32 raw:1; - u32 ccx:1; - u32 ampdudensity:3; - u32 rsvd2:1; - u32 ant_sela:1; - u32 ant_selb:1; - u32 txant_cck:2; - u32 txant_l:2; - u32 txant_ht:2; - - u32 nextheadpage:8; - u32 tailpage:8; - u32 seq:12; - u32 pktid:4; - - u32 rtsrate:5; - u32 apdcfe:1; - u32 qos:1; - u32 hwseq_enable:1; - u32 userrate:1; - u32 dis_rtsfb:1; - u32 dis_datafb:1; - u32 cts2self:1; - u32 rts_en:1; - u32 hwrts_en:1; - u32 portid:1; - u32 rsvd3:3; - u32 waitdcts:1; - u32 cts2ap_en:1; - u32 txsc:2; - u32 stbc:2; - u32 txshort:1; - u32 txbw:1; - u32 rtsshort:1; - u32 rtsbw:1; - u32 rtssc:2; - u32 rtsstbc:2; - - u32 txrate:6; - u32 shortgi:1; - u32 ccxt:1; - u32 txrate_fb_lmt:5; - u32 rtsrate_fb_lmt:4; - u32 retrylmt_en:1; - u32 txretrylmt:6; - u32 usb_txaggnum:8; - - u32 txagca:5; - u32 txagcb:5; - u32 usemaxlen:1; - u32 maxaggnum:5; - u32 mcsg1maxlen:4; - u32 mcsg2maxlen:4; - u32 mcsg3maxlen:4; - u32 mcs7sgimaxlen:4; - - u32 txbuffersize:16; - u32 mcsg4maxlen:4; - u32 mcsg5maxlen:4; - u32 mcsg6maxlen:4; - u32 mcsg15sgimaxlen:4; - - u32 txbuffaddr; - u32 txbufferaddr64; - u32 nextdescaddress; - u32 nextdescaddress64; - - u32 reserve_pass_pcie_mm_limit[4]; -} __packed; - -struct rx_desc_92c { - u32 length:14; - u32 crc32:1; - u32 icverror:1; - u32 drv_infosize:4; - u32 security:3; - u32 qos:1; - u32 shift:2; - u32 phystatus:1; - u32 swdec:1; - u32 lastseg:1; - u32 firstseg:1; - u32 eor:1; - u32 own:1; - - u32 macid:5; - u32 tid:4; - u32 hwrsvd:5; - u32 paggr:1; - u32 faggr:1; - u32 a1_fit:4; - u32 a2_fit:4; - u32 pam:1; - u32 pwr:1; - u32 moredata:1; - u32 morefrag:1; - u32 type:2; - u32 mc:1; - u32 bc:1; - - u32 seq:12; - u32 frag:4; - u32 nextpktlen:14; - u32 nextind:1; - u32 rsvd:1; - - u32 rxmcs:6; - u32 rxht:1; - u32 amsdu:1; - u32 splcp:1; - u32 bandwidth:1; - u32 htc:1; - u32 tcpchk_rpt:1; - u32 ipcchk_rpt:1; - u32 tcpchk_valid:1; - u32 hwpcerr:1; - u32 hwpcind:1; - u32 iv0:16; - - u32 iv1; - - u32 tsfl; - - u32 bufferaddress; - u32 bufferaddress64; - -} __packed; - -void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, - u8 *pdesc, struct ieee80211_tx_info *info, - struct sk_buff *skb, unsigned int qsel); -bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *stats, - struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb); -void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); -u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); -void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); -void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, - bool b_firstseg, bool b_lastseg, - struct sk_buff *skb); -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c new file mode 100644 index 000000000000..b366e8862929 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -0,0 +1,282 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "sw.h" +#include "trx.h" +#include "led.h" + +int rtl92c_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtlpriv->dm.b_dm_initialgain_enable = 1; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.b_disable_framebursting = 0;; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + rtlpci->receive_config = (RCR_APPFCS | + RCR_AMF | + RCR_ADF | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0); + + rtlpci->irq_mask[0] = + (u32) (IMR_ROK | + IMR_VODOK | + IMR_VIDOK | + IMR_BEDOK | + IMR_BKDOK | + IMR_MGNTDOK | + IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0); + + rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); + + rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000); + if (!rtlpriv->rtlhal.pfirmware) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't alloc buffer for fw.\n")); + return 1; + } + + return 0; +} + +void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +static struct rtl_hal_ops rtl8192ce_hal_ops = { + .init_sw_vars = rtl92c_init_sw_vars, + .deinit_sw_vars = rtl92c_deinit_sw_vars, + .read_eeprom_info = rtl92ce_read_eeprom_info, + .interrupt_recognized = rtl92ce_interrupt_recognized, + .hw_init = rtl92ce_hw_init, + .hw_disable = rtl92ce_card_disable, + .enable_interrupt = rtl92ce_enable_interrupt, + .disable_interrupt = rtl92ce_disable_interrupt, + .set_network_type = rtl92ce_set_network_type, + .set_qos = rtl92ce_set_qos, + .set_bcn_reg = rtl92ce_set_beacon_related_registers, + .set_bcn_intv = rtl92ce_set_beacon_interval, + .update_interrupt_mask = rtl92ce_update_interrupt_mask, + .get_hw_reg = rtl92ce_get_hw_reg, + .set_hw_reg = rtl92ce_set_hw_reg, + .update_rate_table = rtl92ce_update_hal_rate_table, + .update_rate_mask = rtl92ce_update_hal_rate_mask, + .fill_tx_desc = rtl92ce_tx_fill_desc, + .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, + .query_rx_desc = rtl92ce_rx_query_desc, + .set_channel_access = rtl92ce_update_channel_access_setting, + .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking, + .set_bw_mode = rtl92c_phy_set_bw_mode, + .switch_channel = rtl92c_phy_sw_chnl, + .dm_watchdog = rtl92c_dm_watchdog, + .scan_operation_backup = rtl92c_phy_scan_operation_backup, + .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .led_control = rtl92ce_led_control, + .set_desc = rtl92ce_set_desc, + .get_desc = rtl92ce_get_desc, + .tx_polling = rtl92ce_tx_polling, + .enable_hw_sec = rtl92ce_enable_hw_security_config, + .set_key = rtl92ce_set_key, + .init_sw_leds = rtl92ce_init_sw_leds, + .deinit_sw_leds = rtl92ce_deinit_sw_leds, + .get_bbreg = rtl92c_phy_query_bb_reg, + .set_bbreg = rtl92c_phy_set_bb_reg, + .get_rfreg = rtl92c_phy_query_rf_reg, + .set_rfreg = rtl92c_phy_set_rf_reg, +}; + +static struct rtl_mod_params rtl92ce_mod_params = { + .sw_crypto = 0, +}; + +static struct rtl_hal_cfg rtl92ce_hal_cfg = { + .name = "rtl92c_pci", + .fw_name = "rtlwifi/rtl8192cfw.bin", + .ops = &rtl8192ce_hal_ops, + .mod_params = &rtl92ce_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BcnInt] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); + +module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); +MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); + +static struct pci_driver rtl92ce_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92ce_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + +#ifdef CONFIG_PM + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, +#endif + +}; + +static int __init rtl92ce_module_init(void) +{ + int ret; + + ret = pci_register_driver(&rtl92ce_driver); + if (ret) + RT_ASSERT(false, (": No device found\n")); + + return ret; +} + +static void __exit rtl92ce_module_exit(void) +{ + pci_unregister_driver(&rtl92ce_driver); +} + +module_init(rtl92ce_module_init); +module_exit(rtl92ce_module_exit); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h new file mode 100644 index 000000000000..de1198c38d4e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_SW_H__ +#define __RTL92CE_SW_H__ + +int rtl92c_init_sw_vars(struct ieee80211_hw *hw); +void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); +void rtl92c_init_var_map(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c new file mode 100644 index 000000000000..ba938b91aa6f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c @@ -0,0 +1,1224 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Created on 2010/ 5/18, 1:41 + * + * Larry Finger + * + *****************************************************************************/ + +#include "table.h" + + +u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x2b2b2b27, + 0x870, 0x07000700, + 0x874, 0x22184000, + 0x878, 0x08080808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c1b25a4, + 0xe78, 0x0c1b25a4, + 0xe7c, 0x0c1b25a4, + 0xe80, 0x0c1b25a4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c1b25a4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000700, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x0a0c0c0c, + 0xe04, 0xffffffff, 0x02040608, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0e, + 0xe14, 0xffffffff, 0x02040608, + 0xe18, 0xffffffff, 0x0a0c0d0e, + 0xe1c, 0xffffffff, 0x02040608, + 0x830, 0xffffffff, 0x0a0c0c0c, + 0x834, 0xffffffff, 0x02040608, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0a0c0d0e, + 0x848, 0xffffffff, 0x02040608, + 0x84c, 0xffffffff, 0x0a0c0d0e, + 0x868, 0xffffffff, 0x02040608, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x06060606, + 0xe1c, 0xffffffff, 0x00020406, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x06060606, + 0x868, 0xffffffff, 0x00020406, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, +}; + +u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = { + 0x0, +}; + +u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000088, + 0x461, 0x00000088, + 0x462, 0x00000006, + 0x463, 0x00000003, + 0x4c8, 0x00000004, + 0x4c9, 0x00000008, + 0x4cc, 0x00000002, + 0x4cd, 0x00000028, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000020, + 0x547, 0x00000000, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h new file mode 100644 index 000000000000..3a6e8b6aeee0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Created on 2010/ 5/18, 1:41 + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_TABLE__H_ +#define __RTL92CE_TABLE__H_ + +#include + +#define PHY_REG_2TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH]; +#define PHY_REG_1TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH]; +#define PHY_REG_ARRAY_PGLENGTH 192 +extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH]; +#define RADIOA_2TARRAYLENGTH 282 +extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH]; +#define RADIOB_2TARRAYLENGTH 78 +extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH]; +#define RADIOA_1TARRAYLENGTH 282 +extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH]; +#define RADIOB_1TARRAYLENGTH 1 +extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 162 +extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_2TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH]; +#define AGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c new file mode 100644 index 000000000000..bf5852f2d634 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -0,0 +1,1031 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" + +static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc, + unsigned int + skb_queue) +{ + enum rtl_desc_qsel qsel; + + if (unlikely(ieee80211_is_beacon(fc))) { + qsel = QSLT_BEACON; + return qsel; + } + + if (ieee80211_is_mgmt(fc)) { + qsel = QSLT_MGNT; + return qsel; + } + + switch (skb_queue) { + case VO_QUEUE: + qsel = QSLT_VO; + break; + case VI_QUEUE: + qsel = QSLT_VI; + break; + case BE_QUEUE: + qsel = QSLT_BE; + break; + case BK_QUEUE: + qsel = QSLT_BK; + break; + default: + qsel = QSLT_BE; + RT_ASSERT(false, ("BE queue, skb_queue:%d," + " set qsel = 0x%X\n", skb_queue, QSLT_BE)); + break; + } + return qsel; +} + +static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) +{ + int rate_idx; + + if (first_ampdu) { + if (false == isht) { + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 0; + break; + } + } else { + rate_idx = 11; + } + + return rate_idx; + } + + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 11; + break; + } + return rate_idx; +} + +static u8 _rtl92c_query_rxpwrpercentage(char antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +static u8 _rtl92c_evm_db_to_percentage(char value) +{ + char ret_val; + ret_val = value; + + if (ret_val >= 0) + ret_val = 0; + + if (ret_val <= -33) + ret_val = -33; + + ret_val = 0 - ret_val; + ret_val *= 3; + + if (ret_val == 99) + ret_val = 100; + + return ret_val; +} + +static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw, + long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} + +static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, + bool b_packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_sts_cck_8192s_t *cck_buf; + s8 rx_pwr_all, rx_pwr[4]; + u8 rf_rx_num, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi; + bool is_cck_rate; + + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); + pstats->b_packet_matchbssid = bpacket_match_bssid; + pstats->b_packet_toself = bpacket_toself; + pstats->b_is_cck = is_cck_rate; + pstats->b_packet_beacon = b_packet_beacon; + pstats->b_is_cck = is_cck_rate; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; + + if (is_cck_rate) { + u8 report, cck_highpwr; + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + + cck_highpwr = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + + if (bpacket_match_bssid) { + u8 sq; + if (pstats->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstats->signalquality = sq; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; + } + } else { + rtlpriv->dm.brfpath_rxenable[0] = + rtlpriv->dm.brfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + if (rtlpriv->dm.brfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = + ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; + rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + if (bpacket_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + + if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 && + pdesc->rxmcs <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (bpacket_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); + } + } + } + + if (is_cck_rate) + pstats->signalstrength = + (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = + (u8) (_rtl92ce_signal_scale_mapping + (hw, total_rssi /= rf_rx_num)); +} + +static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + u32 last_rssi, tmpval; + + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + rtlpriv->stats.rssi_calculate_cnt++; + + if (rtlpriv->stats.ui_rssi.total_num++ >= + PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = + PHY_RSSI_SLID_WIN_MAX; + last_rssi = + rtlpriv->stats.ui_rssi.elements[rtlpriv-> + stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + + rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. + index++] = + pstats->signalstrength; + + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = + _rtl92ce_translate_todbm(hw, (u8) tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + } + + if (!pstats->b_is_cck && pstats->b_packet_toself) { + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + + if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) + continue; + + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + + } + + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + + } + } +} + +static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + + rtlpriv->stats.recv_signal_power = + (rtlpriv->stats.recv_signal_power * 5 + + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + return; + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + } + + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; + } else { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + _rtl92ce_update_rxsignalstatistics(hw, pstats); + } +} + +static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, n_spatialstream, tmpval; + + if (pstats->signalquality != 0) { + if (pstats->b_packet_toself || pstats->b_packet_beacon) { + + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = + rtlpriv->stats. + ui_link_quality.elements[rtlpriv-> + stats.ui_link_quality. + index]; + rtlpriv->stats.ui_link_quality.total_val -= + last_evm; + } + + rtlpriv->stats.ui_link_quality.total_val += + pstats->signalquality; + rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats. + ui_link_quality. + index++] = + pstats->signalquality; + + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + + for (n_spatialstream = 0; n_spatialstream < 2; + n_spatialstream++) { + if (pstats-> + rx_mimo_signalquality[n_spatialstream] != + -1) { + if (rtlpriv->stats. + rx_evm_percentage[n_spatialstream] + == 0) { + rtlpriv->stats. + rx_evm_percentage + [n_spatialstream] = + pstats->rx_mimo_signalquality + [n_spatialstream]; + } + + rtlpriv->stats. + rx_evm_percentage[n_spatialstream] = + ((rtlpriv-> + stats.rx_evm_percentage + [n_spatialstream] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats-> + rx_mimo_signalquality + [n_spatialstream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } + } + } else { + ; + } +} + +static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + + if (!pcurrent_stats->b_packet_matchbssid && + !pcurrent_stats->b_packet_beacon) + return; + + _rtl92ce_process_ui_rssi(hw, pcurrent_stats); + _rtl92ce_process_pwdb(hw, pcurrent_stats); + _rtl92ce_process_ui_link_quality(hw, pcurrent_stats); +} + +static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + u16 fc, type; + bool b_packet_matchbssid, b_packet_toself, b_packet_beacon; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_control); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + psaddr = hdr->addr2; + + b_packet_matchbssid = + ((IEEE80211_FTYPE_CTL != type) && + (!compare_ether_addr(mac->bssid, + (fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && + (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv)); + + b_packet_toself = b_packet_matchbssid && + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(fc)) + b_packet_beacon = true; + + _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + b_packet_matchbssid, b_packet_toself, + b_packet_beacon); + + _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb) +{ + struct rx_fwinfo_92c *p_drvinfo; + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + + u32 phystatus = GET_RX_DESC_PHYST(pdesc); + stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); + stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); + stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc); + stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc); + stats->b_hwerror = (stats->b_crc | stats->b_icv); + stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); + stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); + stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); + stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); + stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) + && (GET_RX_DESC_FAGGR(pdesc) == 1)); + stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); + stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); + + rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + + if (GET_RX_DESC_CRC32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (!GET_RX_DESC_SWDEC(pdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + + if (GET_RX_DESC_BW(pdesc)) + rx_status->flag |= RX_FLAG_40MHZ; + + if (GET_RX_DESC_RXHT(pdesc)) + rx_status->flag |= RX_FLAG_HT; + + rx_status->flag |= RX_FLAG_TSFT; + + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + + rx_status->rate_idx = _rtl92ce_rate_mapping((bool) + GET_RX_DESC_RXHT(pdesc), + (u8) + GET_RX_DESC_RXMCS(pdesc), + (bool) + GET_RX_DESC_PAGGR(pdesc)); + + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + + stats->rx_bufshift); + + _rtl92ce_translate_rx_signal_stuff(hw, + skb, stats, pdesc, + p_drvinfo); + } + + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ + + return true; +} + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, struct sk_buff *skb, + unsigned int queue_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_defaultadapter = true; + + struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); + + u8 *pdesc = (u8 *) pdesc_tx; + struct rtl_tcb_desc tcb_desc; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u16 seq_number; + u16 fc = le16_to_cpu(hdr->frame_control); + u8 rate_flag = info->control.rates[0].flags; + + enum rtl_desc_qsel fw_qsel = + _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), + queue_index); + + bool b_firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + + bool b_lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, + skb->data, skb->len, + PCI_DMA_TODEVICE); + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + rtl_get_tcb_desc(hw, info, skb, &tcb_desc); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); + + if (b_firstseg) { + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + + SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); + + if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) + SET_TX_DESC_DATA_SHORTGI(pdesc, 1); + + if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && + info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_BREAK(pdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); + } + SET_TX_DESC_SEQ(pdesc, seq_number); + + SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable && + !tcb_desc. + b_cts_enable) ? 1 : 0)); + SET_TX_DESC_HW_RTS_ENABLE(pdesc, + ((tcb_desc.b_rts_enable + || tcb_desc.b_cts_enable) ? 1 : 0)); + SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0)); + SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0)); + + SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); + SET_TX_DESC_RTS_BW(pdesc, 0); + SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); + SET_TX_DESC_RTS_SHORT(pdesc, + ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? + (tcb_desc.b_rts_use_shortpreamble ? 1 : 0) + : (tcb_desc.b_rts_use_shortgi ? 1 : 0))); + + if (mac->bw_40) { + if (tcb_desc.b_packet_bw) { + SET_TX_DESC_DATA_BW(pdesc, 1); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { + SET_TX_DESC_TX_SUB_CARRIER(pdesc, + mac->cur_40_prime_sc); + } + } + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); + } + + SET_TX_DESC_LINIP(pdesc, 0); + SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); + + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); + } + + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pdesc, 0x0); + break; + + } + } + + SET_TX_DESC_PKT_ID(pdesc, 0); + SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); + + SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); + SET_TX_DESC_DISABLE_FB(pdesc, 0); + SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("Enable RDG function.\n")); + SET_TX_DESC_RDG_ENABLE(pdesc, 1); + SET_TX_DESC_HTC(pdesc, 1); + } + } + } + + SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0)); + SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0)); + + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); + + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + + if (rtlpriv->dm.b_useramask) { + SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); + SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); + } else { + SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); + SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); + } + + if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps && + ppsc->b_fwctrl_lps) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + + if (!b_defaultadapter) + SET_TX_DESC_QOS(pdesc, 1); + } + + SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1)); + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + SET_TX_DESC_BMC(pdesc, 1); + } + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); +} + +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, + u8 *pdesc, bool b_firstseg, + bool b_lastseg, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, + skb->data, skb->len, + PCI_DMA_TODEVICE); + + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); + + if (b_firstseg) + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + + SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); + + SET_TX_DESC_SEQ(pdesc, 0); + + SET_TX_DESC_LINIP(pdesc, 0); + + SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); + + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); + + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + + SET_TX_DESC_OWN(pdesc, 1); + + SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + + SET_TX_DESC_OFFSET(pdesc, 0x20); + + SET_TX_DESC_USE_RATE(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", + pdesc, TX_DESC_SIZE); +} + +void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +{ + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + SET_TX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d" + " not process\n", desc_name)); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + SET_RX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); + break; + case HW_DESC_RXPKT_LEN: + SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); + break; + case HW_DESC_RXERO: + SET_RX_DESC_EOR(pdesc, 1); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } +} + +u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) +{ + u32 ret = 0; + + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_TX_DESC_OWN(p_desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d " + "not process\n", desc_name)); + break; + } + } else { + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_RX_DESC_OWN(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = GET_RX_DESC_PKT_LEN(pdesc); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } + return ret; +} + +void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h new file mode 100644 index 000000000000..53d0e0a5af5c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -0,0 +1,714 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_TRX_H__ +#define __RTL92CE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) +#define SET_TX_DESC_OFFSET(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) +#define SET_TX_DESC_BMC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) +#define SET_TX_DESC_HTC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) +#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) +#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) +#define SET_TX_DESC_LINIP(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) +#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) +#define SET_TX_DESC_GF(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_TX_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_TX_DESC_PKT_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 0, 16) +#define GET_TX_DESC_OFFSET(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 16, 8) +#define GET_TX_DESC_BMC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 24, 1) +#define GET_TX_DESC_HTC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 25, 1) +#define GET_TX_DESC_LAST_SEG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_TX_DESC_FIRST_SEG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_TX_DESC_LINIP(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_TX_DESC_NO_ACM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_TX_DESC_GF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_TX_DESC_OWN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_TX_DESC_MACID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) +#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) +#define SET_TX_DESC_BK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) +#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) +#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) +#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) +#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) +#define SET_TX_DESC_PIFS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) +#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) +#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) +#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) +#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) +#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) + +#define GET_TX_DESC_MACID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) +#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) +#define GET_TX_DESC_AGG_BREAK(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) +#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) +#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) +#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) +#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) +#define GET_TX_DESC_PIFS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) +#define GET_TX_DESC_RATE_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) +#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) +#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) +#define GET_TX_DESC_SEC_TYPE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) +#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) + +#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) +#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) +#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) +#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) +#define SET_TX_DESC_RAW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) +#define SET_TX_DESC_CCX(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) +#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) +#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) +#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) +#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) +#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) +#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) + +#define GET_TX_DESC_RTS_RC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) +#define GET_TX_DESC_DATA_RC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) +#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) +#define GET_TX_DESC_MORE_FRAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) +#define GET_TX_DESC_RAW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) +#define GET_TX_DESC_CCX(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) +#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) +#define GET_TX_DESC_ANTSEL_A(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) +#define GET_TX_DESC_ANTSEL_B(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) +#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) +#define GET_TX_DESC_TX_ANTL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) +#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) + +#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) +#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) +#define SET_TX_DESC_SEQ(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) +#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) + +#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) +#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) +#define GET_TX_DESC_SEQ(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) +#define GET_TX_DESC_PKT_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) + +#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) +#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) +#define SET_TX_DESC_QOS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) +#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) +#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) +#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) +#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) +#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) +#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) +#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) +#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) +#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) +#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) +#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) +#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) +#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) +#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) +#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) +#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) +#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) +#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) + +#define GET_TX_DESC_RTS_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) +#define GET_TX_DESC_AP_DCFE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) +#define GET_TX_DESC_QOS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) +#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) +#define GET_TX_DESC_USE_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) +#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) +#define GET_TX_DESC_DISABLE_FB(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) +#define GET_TX_DESC_CTS2SELF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) +#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) +#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) +#define GET_TX_DESC_PORT_ID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) +#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) +#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) +#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) +#define GET_TX_DESC_TX_STBC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) +#define GET_TX_DESC_DATA_SHORT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) +#define GET_TX_DESC_DATA_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) +#define GET_TX_DESC_RTS_SHORT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) +#define GET_TX_DESC_RTS_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) +#define GET_TX_DESC_RTS_SC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) +#define GET_TX_DESC_RTS_STBC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) + +#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) +#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) +#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) +#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) + +#define GET_TX_DESC_TX_RATE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) +#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) +#define GET_TX_DESC_CCX_TAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) +#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) +#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) +#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) +#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) +#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) + +#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) +#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) +#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) +#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) +#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) +#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) +#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) +#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) + +#define GET_TX_DESC_TXAGC_A(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) +#define GET_TX_DESC_TXAGC_B(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) +#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) +#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) +#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) +#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) +#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) +#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) +#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) +#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) +#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) +#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) + +#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) +#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) +#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) +#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) +#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) +#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) + +#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) +#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) + +#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) +#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) + +#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) +#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) + +#define GET_RX_DESC_PKT_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 0, 14) +#define GET_RX_DESC_CRC32(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 14, 1) +#define GET_RX_DESC_ICV(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 15, 1) +#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 16, 4) +#define GET_RX_DESC_SECURITY(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 20, 3) +#define GET_RX_DESC_QOS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 23, 1) +#define GET_RX_DESC_SHIFT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 24, 2) +#define GET_RX_DESC_PHYST(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_RX_DESC_SWDEC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_RX_DESC_LS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_RX_DESC_FS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_RX_DESC_EOR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_RX_DESC_OWN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) +#define SET_RX_DESC_EOR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_RX_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_RX_DESC_MACID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) +#define GET_RX_DESC_TID(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) +#define GET_RX_DESC_HWRSVD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) +#define GET_RX_DESC_PAGGR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) +#define GET_RX_DESC_FAGGR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) +#define GET_RX_DESC_A1_FIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) +#define GET_RX_DESC_A2_FIT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) +#define GET_RX_DESC_PAM(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) +#define GET_RX_DESC_PWR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) +#define GET_RX_DESC_MD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) +#define GET_RX_DESC_MF(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) +#define GET_RX_DESC_TYPE(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) +#define GET_RX_DESC_MC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) +#define GET_RX_DESC_BC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) +#define GET_RX_DESC_SEQ(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) +#define GET_RX_DESC_FRAG(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) +#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) +#define GET_RX_DESC_NEXT_IND(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) +#define GET_RX_DESC_RSVD(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) + +#define GET_RX_DESC_RXMCS(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) +#define GET_RX_DESC_RXHT(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) +#define GET_RX_DESC_SPLCP(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) +#define GET_RX_DESC_BW(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) +#define GET_RX_DESC_HTC(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) +#define GET_RX_DESC_HWPC_ERR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) +#define GET_RX_DESC_HWPC_IND(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) +#define GET_RX_DESC_IV0(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) + +#define GET_RX_DESC_IV1(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) +#define GET_RX_DESC_TSFL(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) + +#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) +#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ + LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) + +#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) +#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ +do { \ + if (_size > TX_DESC_NEXT_DESC_OFFSET) \ + memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ + else \ + memset((void *)__pdesc, 0, _size); \ +} while (0); + +#define RX_HAL_IS_CCK_RATE(_pdesc)\ + (_pdesc->rxmcs == DESC92C_RATE1M || \ + _pdesc->rxmcs == DESC92C_RATE2M || \ + _pdesc->rxmcs == DESC92C_RATE5_5M || \ + _pdesc->rxmcs == DESC92C_RATE11M) + +struct rx_fwinfo_92c { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + char rxevm[2]; + char rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_92c { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_92c { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + u8 *pdesc, struct ieee80211_tx_info *info, + struct sk_buff *skb, unsigned int qsel); +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); +void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + bool b_firstseg, bool b_lastseg, + struct sk_buff *skb); +#endif -- cgit v1.2.3-59-g8ed1b From 4b3ba66a47311770b21e7aba481f4f2a90ba3084 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 17 Dec 2010 00:57:00 +0100 Subject: ath9k: fix queue depth check for forming new aggregates To improve aggregation length, there should not be more than two fully formed A-MPDU frames in the hardware queue. To ensure this, the code checks the tx queue length before forming new A-MPDUs. This can reduce the throughput (or maybe even starve out A-MPDU traffic) when too many non-aggregated frames are in the queue. Fix this by keeping track of pending A-MPDU frames (even when they're sent out as single frames), but exclude rate control probing frames to improve performance. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b0b1216dae0a..9fd95191eebc 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -189,6 +189,7 @@ struct ath_txq { struct list_head axq_q; spinlock_t axq_lock; u32 axq_depth; + u32 axq_ampdu_depth; bool stopped; bool axq_tx_inprogress; struct list_head axq_acq; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 966236953e77..332d1feb5c18 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -838,7 +838,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_tx_txqaddbuf(sc, txq, &bf_q); TX_STAT_INC(txq->axq_qnum, a_aggr); - } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && + } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && status != ATH_AGGR_BAW_CLOSED); } @@ -999,6 +999,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) INIT_LIST_HEAD(&txq->axq_acq); spin_lock_init(&txq->axq_lock); txq->axq_depth = 0; + txq->axq_ampdu_depth = 0; txq->axq_tx_inprogress = false; sc->tx.txqsetup |= 1<bf_mpdu); + return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); +} + /* * Drain a given TX queue (could be Beacon or Data) * @@ -1126,7 +1133,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) } txq->axq_depth--; - + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; spin_unlock_bh(&txq->axq_lock); if (bf_isampdu(bf)) @@ -1316,6 +1324,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, ath9k_hw_txstart(ah, txq->axq_qnum); } txq->axq_depth++; + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth++; } static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, @@ -1336,7 +1346,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, */ if (!list_empty(&tid->buf_q) || tid->paused || !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) || - txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { + txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) { /* * Add this frame to software queue for scheduling later * for aggregation. @@ -2040,6 +2050,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) txq->axq_tx_inprogress = false; if (bf_held) list_del(&bf_held->list); + + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; spin_unlock_bh(&txq->axq_lock); if (bf_held) @@ -2168,6 +2181,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); txq->axq_depth--; txq->axq_tx_inprogress = false; + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; spin_unlock_bh(&txq->axq_lock); txok = !(txs.ts_status & ATH9K_TXERR_MASK); -- cgit v1.2.3-59-g8ed1b From 55821324dc6a10fab36871534a322bad159fad79 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 17 Dec 2010 00:57:01 +0100 Subject: ath9k_hw: remove baseband rfsilent support When rfkill is enabled, ath9k_hw unnecessarily configured the baseband to turn off based on GPIO input, however that code was hardcoded to GPIO 0 instead of ah->rfkill_gpio. Since ath9k uses software rfkill anyway, this code is completely unnecessary and should be removed in case anything else ever uses GPIO 0. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 13 ------------- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 23 ----------------------- drivers/net/wireless/ath/ath9k/hw-ops.h | 5 ----- drivers/net/wireless/ath/ath9k/hw.c | 2 +- drivers/net/wireless/ath/ath9k/hw.h | 1 - 5 files changed, 1 insertion(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 059330aac645..ffcf44a4058b 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -961,18 +961,6 @@ static void ar5008_hw_rfbus_done(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); } -static void ar5008_hw_enable_rfkill(struct ath_hw *ah) -{ - REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, - AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); - - REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, - AR_GPIO_INPUT_MUX2_RFSILENT); - - ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); - REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); -} - static void ar5008_restore_chainmask(struct ath_hw *ah) { int rx_chainmask = ah->rxchainmask; @@ -1629,7 +1617,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->set_delta_slope = ar5008_hw_set_delta_slope; priv_ops->rfbus_req = ar5008_hw_rfbus_req; priv_ops->rfbus_done = ar5008_hw_rfbus_done; - priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; priv_ops->restore_chainmask = ar5008_restore_chainmask; priv_ops->set_diversity = ar5008_set_diversity; priv_ops->do_getnf = ar5008_hw_do_getnf; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 07b44cec7739..8d60f4f09acc 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -745,28 +745,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); } -/* - * Set the interrupt and GPIO values so the ISR can disable RF - * on a switch signal. Assumes GPIO port and interrupt polarity - * are set prior to call. - */ -static void ar9003_hw_enable_rfkill(struct ath_hw *ah) -{ - /* Connect rfsilent_bb_l to baseband */ - REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, - AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); - /* Set input mux for rfsilent_bb_l to GPIO #0 */ - REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, - AR_GPIO_INPUT_MUX2_RFSILENT); - - /* - * Configure the desired GPIO port for input and - * enable baseband rf silence. - */ - ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); - REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); -} - static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) { u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); @@ -1203,7 +1181,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; priv_ops->rfbus_req = ar9003_hw_rfbus_req; priv_ops->rfbus_done = ar9003_hw_rfbus_done; - priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; priv_ops->set_diversity = ar9003_hw_set_diversity; priv_ops->ani_control = ar9003_hw_ani_control; priv_ops->do_getnf = ar9003_hw_do_getnf; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 0a4ad348b699..c8f254fe0f0b 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -223,11 +223,6 @@ static inline void ath9k_hw_rfbus_done(struct ath_hw *ah) return ath9k_hw_private_ops(ah)->rfbus_done(ah); } -static inline void ath9k_enable_rfkill(struct ath_hw *ah) -{ - return ath9k_hw_private_ops(ah)->enable_rfkill(ah); -} - static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah) { if (!ath9k_hw_private_ops(ah)->restore_chainmask) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ddda76fcd180..4b51ed47fe69 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1385,7 +1385,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_init_qos(ah); if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) - ath9k_enable_rfkill(ah); + ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); ath9k_hw_init_global_settings(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 21e37d157d3a..b98053f0640a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -576,7 +576,6 @@ struct ath_hw_private_ops { void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan); bool (*rfbus_req)(struct ath_hw *ah); void (*rfbus_done)(struct ath_hw *ah); - void (*enable_rfkill)(struct ath_hw *ah); void (*restore_chainmask)(struct ath_hw *ah); void (*set_diversity)(struct ath_hw *ah, bool value); u32 (*compute_pll_control)(struct ath_hw *ah, -- cgit v1.2.3-59-g8ed1b From 18db45c46eae31cee7cfdfd7e671b0201dcdbcd8 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Fri, 17 Dec 2010 11:45:01 +0100 Subject: rtl8192ce: Fix typo in Kconfig description Signed-off-by: Anisse Astier Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index d712026eb763..7f6573f7f470 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -7,7 +7,7 @@ config RTL8192CE This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe wireless network adapters. - If you choose to build it as a module, it will be calledrtl8192ce. + If you choose to build it as a module, it will be called rtl8192ce config RTLWIFI tristate -- cgit v1.2.3-59-g8ed1b From b1c1d0003d6d07c3b269340b8ac3fd2b42fd5ebe Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 17 Dec 2010 20:44:36 +0530 Subject: ath9k: Properly initialize channel table for 2GHz ath9k channel table for 2Ghz does not seems to initialize the 'band' parameter.Though it does not seems to cause any visible issue it looks odd when we initialize the 'band' parameter for 5Ghz channel table while not so for 2Ghz. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 12387950b449..b0e5e716b167 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -48,6 +48,7 @@ MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); /* We use the hw_value as an index into our private channel structure */ #define CHAN2G(_freq, _idx) { \ + .band = IEEE80211_BAND_2GHZ, \ .center_freq = (_freq), \ .hw_value = (_idx), \ .max_power = 20, \ -- cgit v1.2.3-59-g8ed1b From f0b3e4b7307f02a203029441b0473a84aebc6435 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 17 Dec 2010 16:04:11 -0600 Subject: MAINTAINERS: Fix typo in rtl8192ce entry Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 43ab5fa42a73..94c129f7240c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5052,7 +5052,7 @@ W: http://linuxwireless.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/rtlwifi/ -F: drivers/net/wireless/rtl8192ce/ +F: drivers/net/wireless/rtlwifi/rtl8192ce/ S3 SAVAGE FRAMEBUFFER DRIVER M: Antonino Daplas -- cgit v1.2.3-59-g8ed1b From d704300fa546a613ec3821b908528b20685cb92a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 17 Dec 2010 19:36:25 -0600 Subject: rtlwifi: Fix use of mutex in interrupt code A previous conversion from semaphoreto mutexes missed the fact that one of the semaphores was used in interrupt code. Fixed by changing to a spinlock. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/ps.c | 5 +++-- drivers/net/wireless/rtlwifi/wifi.h | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 87530eaa88bd..77fa59af63d8 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -309,8 +309,8 @@ int rtl_init_core(struct ieee80211_hw *hw) } /* <4> locks */ - mutex_init(&rtlpriv->locks.ips_mutex); mutex_init(&rtlpriv->locks.conf_mutex); + spin_lock_init(&rtlpriv->locks.ips_lock); spin_lock_init(&rtlpriv->locks.irq_th_lock); spin_lock_init(&rtlpriv->locks.h2c_lock); spin_lock_init(&rtlpriv->locks.rf_ps_lock); diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 22c293e5b88c..d2326c13449e 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -286,8 +286,9 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); enum rf_pwrstate rtstate; + unsigned long flags; - mutex_lock(&rtlpriv->locks.ips_mutex); + spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); if (ppsc->b_inactiveps) { rtstate = ppsc->rfpwr_state; @@ -303,7 +304,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) } } - mutex_unlock(&rtlpriv->locks.ips_mutex); + spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); } /*for FW LPS*/ diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 77d5fa370bdc..d44d79613d2d 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1192,11 +1192,11 @@ struct rtl_hal_cfg { }; struct rtl_locks { - /*sem */ - struct mutex ips_mutex; + /* mutex */ struct mutex conf_mutex; /*spin lock */ + spinlock_t ips_lock; spinlock_t irq_th_lock; spinlock_t h2c_lock; spinlock_t rf_ps_lock; -- cgit v1.2.3-59-g8ed1b From ae29fbb189c7a80677500c718c9ce08095ccde01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 18 Dec 2010 11:52:10 +0300 Subject: wl1251: wl12xx_get_platform_data() returns an ERR_PTR wl12xx_get_platform_data() returns an ERR_PTR on failure and it never returns a NULL. Signed-off-by: Dan Carpenter Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 596d90ecba33..d550b5e68d3c 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -252,7 +252,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl->if_ops = &wl1251_sdio_ops; wl12xx_board_data = wl12xx_get_platform_data(); - if (wl12xx_board_data != NULL) { + if (!IS_ERR(wl12xx_board_data)) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; wl->use_eeprom = wl12xx_board_data->use_eeprom; -- cgit v1.2.3-59-g8ed1b From 489ee9195a7de9e6bc833d639ff6b553ffdad90e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 18 Dec 2010 19:30:48 +0100 Subject: mac80211: fix initialization of skb->cb in ieee80211_subif_start_xmit The change 'mac80211: Fix BUG in pskb_expand_head when transmitting shared skbs' added a check for copying the skb if it's shared, however the tx info variable still points at the cb of the old skb Signed-off-by: Felix Fietkau Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 807dcd06e268..8d01d21dff1e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1739,7 +1739,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_info *info; int ret = NETDEV_TX_BUSY, head_need; u16 ethertype, hdrlen, meshhdrlen = 0; __le16 fc; @@ -2028,6 +2028,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, skb_set_network_header(skb, nh_pos); skb_set_transport_header(skb, h_pos); + info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); dev->trans_start = jiffies; -- cgit v1.2.3-59-g8ed1b From 4cd06a344db752f513437138953af191cbe9a691 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 18 Dec 2010 19:30:49 +0100 Subject: mac80211: skip unnecessary pskb_expand_head calls If the skb is not cloned and we don't need any extra headroom, there is no point in reallocating the skb head. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8d01d21dff1e..90ee23550033 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1546,8 +1546,10 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, if (skb_header_cloned(skb)) I802_DEBUG_INC(local->tx_expand_skb_head_cloned); - else + else if (head_need || tail_need) I802_DEBUG_INC(local->tx_expand_skb_head); + else + return 0; if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { wiphy_debug(local->hw.wiphy, -- cgit v1.2.3-59-g8ed1b From f8a0a781488ec7288d1049e5d2022850aa98f7b6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 18 Dec 2010 19:30:50 +0100 Subject: mac80211: fix potentially redundant skb data copying When an skb is shared, it needs to be duplicated, along with its data buffer. If the skb does not have enough headroom, using skb_copy might cause the data buffer to be copied twice (once by skb_copy and once by pskb_expand_head). Fix this by using skb_clone initially and letting ieee80211_skb_resize sort out the rest. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 90ee23550033..d2b4b67a7b53 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1934,7 +1934,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ if (skb_shared(skb)) { tmp_skb = skb; - skb = skb_copy(skb, GFP_ATOMIC); + skb = skb_clone(skb, GFP_ATOMIC); kfree_skb(tmp_skb); if (!skb) { -- cgit v1.2.3-59-g8ed1b From f1a8abb0459e96765bd1d300f434256d8dfac73d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 19 Dec 2010 00:31:54 +0100 Subject: ath9k_hw: fix PA predistortion HT40 mask The commit 'ath9k_hw: Disable PAPRD for rates with low Tx power' changed the code that sets the PAPRD rate masks to use only either the HT20 mask or the HT40 mask. This is wrong, as the hardware can still use HT20 rates even when configured for HT40, and the operating channel mode does not affect PAPRD operation. The register for the HT40 rate mask is applied as a mask on top of the other registers to selectively disable PAPRD for specific rates on HT40 packets only. This patch changes the code back to the old behavior which matches the intended use of these registers. While with current cards this should not make any practical difference (according to Atheros, the HT20 and HT40 mask should always be equal), it is more correct that way, and maybe the HT40 mask will be used for some rare corner cases in the future. Cc: Vasanthakumar Thiagarajan Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 19 +++++++++++-------- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 2 +- drivers/net/wireless/ath/ath9k/hw.h | 1 + 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index f80ec7497d0f..d7deae85d980 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4762,6 +4762,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + struct ar9300_modal_eep_header *modal_hdr; u8 targetPowerValT2[ar9300RateSize]; u8 target_power_val_t2_eep[ar9300RateSize]; unsigned int i = 0, paprd_scale_factor = 0; @@ -4771,15 +4772,17 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { if (IS_CHAN_2GHZ(chan)) - ah->paprd_ratemask = (IS_CHAN_HT40(chan) ? - le32_to_cpu(eep->modalHeader2G.papdRateMaskHt40) : - le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20)) - & AR9300_PAPRD_RATE_MASK; + modal_hdr = &eep->modalHeader2G; else - ah->paprd_ratemask = (IS_CHAN_HT40(chan) ? - le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40) : - le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)) - & AR9300_PAPRD_RATE_MASK; + modal_hdr = &eep->modalHeader5G; + + ah->paprd_ratemask = + le32_to_cpu(modal_hdr->papdRateMaskHt20) & + AR9300_PAPRD_RATE_MASK; + + ah->paprd_ratemask_ht40 = + le32_to_cpu(modal_hdr->papdRateMaskHt40) & + AR9300_PAPRD_RATE_MASK; paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 : diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 79554c524b68..356d2fd78822 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -134,7 +134,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, ah->paprd_ratemask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, - AR_PHY_PAPRD_HT40_MASK); + ah->paprd_ratemask_ht40); for (i = 0; i < ah->caps.max_txchains; i++) { REG_RMW_FIELD(ah, ctrl0[i], diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b98053f0640a..b8ffaa5dc650 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -835,6 +835,7 @@ struct ath_hw { unsigned int paprd_target_power; unsigned int paprd_training_power; unsigned int paprd_ratemask; + unsigned int paprd_ratemask_ht40; bool paprd_table_write_done; u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; -- cgit v1.2.3-59-g8ed1b From d4d5dc3d6f86cc70f08e45b840f3e681588d2718 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 19 Dec 2010 00:31:55 +0100 Subject: ath9k: do not limit the chainmask to 1 for legacy mode Restricting the chainmask to 1 for legacy mode disables useful features such as MRC, and it reduces the available transmit power. I can't think of a good reason to do this in legacy mode, so let's just get rid of that code. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 32 -------------------------------- drivers/net/wireless/ath/ath9k/virtual.c | 1 - 3 files changed, 34 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9fd95191eebc..2c31f5142eda 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -675,7 +675,6 @@ void ath9k_deinit_device(struct ath_softc *sc); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *ichan); -void ath_update_chainmask(struct ath_softc *sc, int is_ht); int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *hchan); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cb53fbb951f1..8a1691db166d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -538,32 +538,6 @@ set_timer: } } -/* - * Update tx/rx chainmask. For legacy association, - * hard code chainmask to 1x1, for 11n association, use - * the chainmask configuration, for bt coexistence, use - * the chainmask configuration even in legacy mode. - */ -void ath_update_chainmask(struct ath_softc *sc, int is_ht) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - - if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht || - (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { - common->tx_chainmask = ah->caps.tx_chainmask; - common->rx_chainmask = ah->caps.rx_chainmask; - } else { - common->tx_chainmask = 1; - common->rx_chainmask = 1; - } - - ath_dbg(common, ATH_DBG_CONFIG, - "tx chmask: %d, rx chmask: %d\n", - common->tx_chainmask, - common->rx_chainmask); -} - static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) { struct ath_node *an; @@ -1679,8 +1653,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) /* XXX: remove me eventualy */ ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); - ath_update_chainmask(sc, conf_is_ht(conf)); - /* update survey stats for the old channel before switching */ spin_lock_irqsave(&common->cc_lock, flags); ath_update_survey_stats(sc); @@ -1912,10 +1884,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, /* Set aggregation protection mode parameters */ sc->config.ath_aggr_prot = 0; - /* Only legacy IBSS for now */ - if (vif->type == NL80211_IFTYPE_ADHOC) - ath_update_chainmask(sc, 0); - ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", common->curbssid, common->curaid); diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index fbfbc8239971..2dc7095e56d1 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -288,7 +288,6 @@ void ath9k_wiphy_chan_work(struct work_struct *work) /* sync hw configuration for hw code */ common->hw = aphy->hw; - ath_update_chainmask(sc, sc->chan_is_ht); if (ath_set_channel(sc, aphy->hw, &sc->sc_ah->channels[sc->chan_idx]) < 0) { printk(KERN_DEBUG "ath9k: Failed to set channel for new " -- cgit v1.2.3-59-g8ed1b From 3d986b25b5faa50ba6afd94f60f270b6c3061e5e Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 16 Dec 2010 14:59:49 -0500 Subject: rtlwifi: use alloc_workqueue create_workqueue is deprecated. The workqueue usage does not seem to demand any special treatment, so do not set any flags either. Signed-off-by: John W. Linville Tested-by: Larry Finger Acked-by: Tejun Heo --- drivers/net/wireless/rtlwifi/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 77fa59af63d8..f6cc07369d75 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -225,7 +225,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) /* <2> work queue */ rtlpriv->works.hw = hw; - rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name); + rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0); INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, -- cgit v1.2.3-59-g8ed1b From c4266263249f22479eb1abb1a1709c38240b1597 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Dec 2010 08:18:36 +0000 Subject: net_sched: sch_sfq: add backlog info in sfq_dump_class_stats() We currently return for each active SFQ slot the number of packets in queue. We can also give number of bytes accounted for these packets. tc -s class show dev ifb0 Before patch : class sfq 11:3d9 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 3p requeues 0 allot 1266 After patch : class sfq 11:3e4 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 4380b 3p requeues 0 allot 1212 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 3cf478d012dd..cb331dea7fe0 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -548,8 +548,13 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, { struct sfq_sched_data *q = qdisc_priv(sch); sfq_index idx = q->ht[cl-1]; - struct gnet_stats_queue qs = { .qlen = q->qs[idx].qlen }; + struct sk_buff_head *list = &q->qs[idx]; + struct gnet_stats_queue qs = { .qlen = list->qlen }; struct tc_sfq_xstats xstats = { .allot = q->allot[idx] }; + struct sk_buff *skb; + + skb_queue_walk(list, skb) + qs.backlog += qdisc_pkt_len(skb); if (gnet_stats_copy_queue(d, &qs) < 0) return -1; -- cgit v1.2.3-59-g8ed1b From eda83e3b63e88351310c13c99178eb4634f137b2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Dec 2010 12:54:58 +0000 Subject: net_sched: sch_sfq: better struct layouts Here is a respin of patch. I'll send a short patch to make SFQ more fair in presence of large packets as well. Thanks [PATCH v3 net-next-2.6] net_sched: sch_sfq: better struct layouts This patch shrinks sizeof(struct sfq_sched_data) from 0x14f8 (or more if spinlocks are bigger) to 0x1180 bytes, and reduce text size as well. text data bss dec hex filename 4821 152 0 4973 136d old/net/sched/sch_sfq.o 4627 136 0 4763 129b new/net/sched/sch_sfq.o All data for a slot/flow is now grouped in a compact and cache friendly structure, instead of being spreaded in many different points. struct sfq_slot { struct sk_buff *skblist_next; struct sk_buff *skblist_prev; sfq_index qlen; /* number of skbs in skblist */ sfq_index next; /* next slot in sfq chain */ struct sfq_head dep; /* anchor in dep[] chains */ unsigned short hash; /* hash value (index in ht[]) */ short allot; /* credit for this slot */ }; Signed-off-by: Eric Dumazet Cc: Jarek Poplawski Cc: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 260 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 162 insertions(+), 98 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 42396c965dd6..13322e8a0456 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -67,27 +67,42 @@ IMPLEMENTATION: This implementation limits maximal queue length to 128; - maximal mtu to 2^15-1; number of hash buckets to 1024. + maximal mtu to 2^15-1; max 128 flows, number of hash buckets to 1024. The only goal of this restrictions was that all data - fit into one 4K page :-). Struct sfq_sched_data is - organized in anti-cache manner: all the data for a bucket - are scattered over different locations. This is not good, - but it allowed me to put it into 4K. + fit into one 4K page on 32bit arches. It is easy to increase these values, but not in flight. */ -#define SFQ_DEPTH 128 +#define SFQ_DEPTH 128 /* max number of packets per flow */ +#define SFQ_SLOTS 128 /* max number of flows */ +#define SFQ_EMPTY_SLOT 255 #define SFQ_HASH_DIVISOR 1024 -/* This type should contain at least SFQ_DEPTH*2 values */ +/* This type should contain at least SFQ_DEPTH + SFQ_SLOTS values */ typedef unsigned char sfq_index; +/* + * We dont use pointers to save space. + * Small indexes [0 ... SFQ_SLOTS - 1] are 'pointers' to slots[] array + * while following values [SFQ_SLOTS ... SFQ_SLOTS + SFQ_DEPTH - 1] + * are 'pointers' to dep[] array + */ struct sfq_head { sfq_index next; sfq_index prev; }; +struct sfq_slot { + struct sk_buff *skblist_next; + struct sk_buff *skblist_prev; + sfq_index qlen; /* number of skbs in skblist */ + sfq_index next; /* next slot in sfq chain */ + struct sfq_head dep; /* anchor in dep[] chains */ + unsigned short hash; /* hash value (index in ht[]) */ + short allot; /* credit for this slot */ +}; + struct sfq_sched_data { /* Parameters */ @@ -99,17 +114,24 @@ struct sfq_sched_data struct tcf_proto *filter_list; struct timer_list perturb_timer; u32 perturbation; - sfq_index tail; /* Index of current slot in round */ - sfq_index max_depth; /* Maximal depth */ + sfq_index cur_depth; /* depth of longest slot */ + struct sfq_slot *tail; /* current slot in round */ sfq_index ht[SFQ_HASH_DIVISOR]; /* Hash table */ - sfq_index next[SFQ_DEPTH]; /* Active slots link */ - short allot[SFQ_DEPTH]; /* Current allotment per slot */ - unsigned short hash[SFQ_DEPTH]; /* Hash value indexed by slots */ - struct sk_buff_head qs[SFQ_DEPTH]; /* Slot queue */ - struct sfq_head dep[SFQ_DEPTH*2]; /* Linked list of slots, indexed by depth */ + struct sfq_slot slots[SFQ_SLOTS]; + struct sfq_head dep[SFQ_DEPTH]; /* Linked list of slots, indexed by depth */ }; +/* + * sfq_head are either in a sfq_slot or in dep[] array + */ +static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index val) +{ + if (val < SFQ_SLOTS) + return &q->slots[val].dep; + return &q->dep[val - SFQ_SLOTS]; +} + static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) { return jhash_2words(h, h1, q->perturbation) & (SFQ_HASH_DIVISOR - 1); @@ -200,30 +222,41 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, return 0; } +/* + * x : slot number [0 .. SFQ_SLOTS - 1] + */ static inline void sfq_link(struct sfq_sched_data *q, sfq_index x) { sfq_index p, n; - int d = q->qs[x].qlen + SFQ_DEPTH; + int qlen = q->slots[x].qlen; + + p = qlen + SFQ_SLOTS; + n = q->dep[qlen].next; - p = d; - n = q->dep[d].next; - q->dep[x].next = n; - q->dep[x].prev = p; - q->dep[p].next = q->dep[n].prev = x; + q->slots[x].dep.next = n; + q->slots[x].dep.prev = p; + + q->dep[qlen].next = x; /* sfq_dep_head(q, p)->next = x */ + sfq_dep_head(q, n)->prev = x; } +#define sfq_unlink(q, x, n, p) \ + n = q->slots[x].dep.next; \ + p = q->slots[x].dep.prev; \ + sfq_dep_head(q, p)->next = n; \ + sfq_dep_head(q, n)->prev = p + + static inline void sfq_dec(struct sfq_sched_data *q, sfq_index x) { sfq_index p, n; + int d; - n = q->dep[x].next; - p = q->dep[x].prev; - q->dep[p].next = n; - q->dep[n].prev = p; - - if (n == p && q->max_depth == q->qs[x].qlen + 1) - q->max_depth--; + sfq_unlink(q, x, n, p); + d = q->slots[x].qlen--; + if (n == p && q->cur_depth == d) + q->cur_depth--; sfq_link(q, x); } @@ -232,34 +265,72 @@ static inline void sfq_inc(struct sfq_sched_data *q, sfq_index x) sfq_index p, n; int d; - n = q->dep[x].next; - p = q->dep[x].prev; - q->dep[p].next = n; - q->dep[n].prev = p; - d = q->qs[x].qlen; - if (q->max_depth < d) - q->max_depth = d; + sfq_unlink(q, x, n, p); + d = ++q->slots[x].qlen; + if (q->cur_depth < d) + q->cur_depth = d; sfq_link(q, x); } +/* helper functions : might be changed when/if skb use a standard list_head */ + +/* remove one skb from tail of slot queue */ +static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot) +{ + struct sk_buff *skb = slot->skblist_prev; + + slot->skblist_prev = skb->prev; + skb->next = skb->prev = NULL; + return skb; +} + +/* remove one skb from head of slot queue */ +static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot) +{ + struct sk_buff *skb = slot->skblist_next; + + slot->skblist_next = skb->next; + skb->next = skb->prev = NULL; + return skb; +} + +static inline void slot_queue_init(struct sfq_slot *slot) +{ + slot->skblist_prev = slot->skblist_next = (struct sk_buff *)slot; +} + +/* add skb to slot queue (tail add) */ +static inline void slot_queue_add(struct sfq_slot *slot, struct sk_buff *skb) +{ + skb->prev = slot->skblist_prev; + skb->next = (struct sk_buff *)slot; + slot->skblist_prev->next = skb; + slot->skblist_prev = skb; +} + +#define slot_queue_walk(slot, skb) \ + for (skb = slot->skblist_next; \ + skb != (struct sk_buff *)slot; \ + skb = skb->next) + static unsigned int sfq_drop(struct Qdisc *sch) { struct sfq_sched_data *q = qdisc_priv(sch); - sfq_index d = q->max_depth; + sfq_index x, d = q->cur_depth; struct sk_buff *skb; unsigned int len; + struct sfq_slot *slot; - /* Queue is full! Find the longest slot and - drop a packet from it */ - + /* Queue is full! Find the longest slot and drop tail packet from it */ if (d > 1) { - sfq_index x = q->dep[d + SFQ_DEPTH].next; - skb = q->qs[x].prev; + x = q->dep[d].next; + slot = &q->slots[x]; +drop: + skb = slot_dequeue_tail(slot); len = qdisc_pkt_len(skb); - __skb_unlink(skb, &q->qs[x]); - kfree_skb(skb); sfq_dec(q, x); + kfree_skb(skb); sch->q.qlen--; sch->qstats.drops++; sch->qstats.backlog -= len; @@ -268,18 +339,11 @@ static unsigned int sfq_drop(struct Qdisc *sch) if (d == 1) { /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ - d = q->next[q->tail]; - q->next[q->tail] = q->next[d]; - skb = q->qs[d].prev; - len = qdisc_pkt_len(skb); - __skb_unlink(skb, &q->qs[d]); - kfree_skb(skb); - sfq_dec(q, d); - sch->q.qlen--; - q->ht[q->hash[d]] = SFQ_DEPTH; - sch->qstats.drops++; - sch->qstats.backlog -= len; - return len; + x = q->tail->next; + slot = &q->slots[x]; + q->tail->next = slot->next; + q->ht[slot->hash] = SFQ_EMPTY_SLOT; + goto drop; } return 0; @@ -291,6 +355,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) struct sfq_sched_data *q = qdisc_priv(sch); unsigned int hash; sfq_index x; + struct sfq_slot *slot; int uninitialized_var(ret); hash = sfq_classify(skb, sch, &ret); @@ -303,30 +368,33 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) hash--; x = q->ht[hash]; - if (x == SFQ_DEPTH) { - q->ht[hash] = x = q->dep[SFQ_DEPTH].next; - q->hash[x] = hash; + slot = &q->slots[x]; + if (x == SFQ_EMPTY_SLOT) { + x = q->dep[0].next; /* get a free slot */ + q->ht[hash] = x; + slot = &q->slots[x]; + slot->hash = hash; + slot_queue_init(slot); } - /* If selected queue has length q->limit, this means that - * all another queues are empty and that we do simple tail drop, + /* If selected queue has length q->limit, do simple tail drop, * i.e. drop _this_ packet. */ - if (q->qs[x].qlen >= q->limit) + if (slot->qlen >= q->limit) return qdisc_drop(skb, sch); sch->qstats.backlog += qdisc_pkt_len(skb); - __skb_queue_tail(&q->qs[x], skb); + slot_queue_add(slot, skb); sfq_inc(q, x); - if (q->qs[x].qlen == 1) { /* The flow is new */ - if (q->tail == SFQ_DEPTH) { /* It is the first flow */ - q->next[x] = x; + if (slot->qlen == 1) { /* The flow is new */ + if (q->tail == NULL) { /* It is the first flow */ + slot->next = x; } else { - q->next[x] = q->next[q->tail]; - q->next[q->tail] = x; + slot->next = q->tail->next; + q->tail->next = x; } - q->tail = x; - q->allot[x] = q->quantum; + q->tail = slot; + slot->allot = q->quantum; } if (++sch->q.qlen <= q->limit) { sch->bstats.bytes += qdisc_pkt_len(skb); @@ -342,14 +410,12 @@ static struct sk_buff * sfq_peek(struct Qdisc *sch) { struct sfq_sched_data *q = qdisc_priv(sch); - sfq_index a; /* No active slots */ - if (q->tail == SFQ_DEPTH) + if (q->tail == NULL) return NULL; - a = q->next[q->tail]; - return skb_peek(&q->qs[a]); + return q->slots[q->tail->next].skblist_next; } static struct sk_buff * @@ -358,31 +424,31 @@ sfq_dequeue(struct Qdisc *sch) struct sfq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; sfq_index a, next_a; + struct sfq_slot *slot; /* No active slots */ - if (q->tail == SFQ_DEPTH) + if (q->tail == NULL) return NULL; - a = q->next[q->tail]; - - /* Grab packet */ - skb = __skb_dequeue(&q->qs[a]); + a = q->tail->next; + slot = &q->slots[a]; + skb = slot_dequeue_head(slot); sfq_dec(q, a); sch->q.qlen--; sch->qstats.backlog -= qdisc_pkt_len(skb); /* Is the slot empty? */ - if (q->qs[a].qlen == 0) { - q->ht[q->hash[a]] = SFQ_DEPTH; - next_a = q->next[a]; + if (slot->qlen == 0) { + q->ht[slot->hash] = SFQ_EMPTY_SLOT; + next_a = slot->next; if (a == next_a) { - q->tail = SFQ_DEPTH; + q->tail = NULL; /* no more active slots */ return skb; } - q->next[q->tail] = next_a; - } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { - q->allot[a] += q->quantum; - q->tail = a; + q->tail->next = next_a; + } else if ((slot->allot -= qdisc_pkt_len(skb)) <= 0) { + q->tail = slot; + slot->allot += q->quantum; } return skb; } @@ -446,17 +512,16 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) init_timer_deferrable(&q->perturb_timer); for (i = 0; i < SFQ_HASH_DIVISOR; i++) - q->ht[i] = SFQ_DEPTH; + q->ht[i] = SFQ_EMPTY_SLOT; for (i = 0; i < SFQ_DEPTH; i++) { - skb_queue_head_init(&q->qs[i]); - q->dep[i + SFQ_DEPTH].next = i + SFQ_DEPTH; - q->dep[i + SFQ_DEPTH].prev = i + SFQ_DEPTH; + q->dep[i].next = i + SFQ_SLOTS; + q->dep[i].prev = i + SFQ_SLOTS; } q->limit = SFQ_DEPTH - 1; - q->max_depth = 0; - q->tail = SFQ_DEPTH; + q->cur_depth = 0; + q->tail = NULL; if (opt == NULL) { q->quantum = psched_mtu(qdisc_dev(sch)); q->perturb_period = 0; @@ -467,7 +532,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) return err; } - for (i = 0; i < SFQ_DEPTH; i++) + for (i = 0; i < SFQ_SLOTS; i++) sfq_link(q, i); return 0; } @@ -543,13 +608,12 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct gnet_dump *d) { struct sfq_sched_data *q = qdisc_priv(sch); - sfq_index idx = q->ht[cl-1]; - struct sk_buff_head *list = &q->qs[idx]; - struct gnet_stats_queue qs = { .qlen = list->qlen }; - struct tc_sfq_xstats xstats = { .allot = q->allot[idx] }; + const struct sfq_slot *slot = &q->slots[q->ht[cl - 1]]; + struct gnet_stats_queue qs = { .qlen = slot->qlen }; + struct tc_sfq_xstats xstats = { .allot = slot->allot }; struct sk_buff *skb; - skb_queue_walk(list, skb) + slot_queue_walk(slot, skb) qs.backlog += qdisc_pkt_len(skb); if (gnet_stats_copy_queue(d, &qs) < 0) @@ -566,7 +630,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) return; for (i = 0; i < SFQ_HASH_DIVISOR; i++) { - if (q->ht[i] == SFQ_DEPTH || + if (q->ht[i] == SFQ_EMPTY_SLOT || arg->count < arg->skip) { arg->count++; continue; -- cgit v1.2.3-59-g8ed1b From 356f039822b8d802138f7121c80d2a9286976dbd Mon Sep 17 00:00:00 2001 From: Nandita Dukkipati Date: Mon, 20 Dec 2010 14:15:56 +0000 Subject: TCP: increase default initial receive window. This patch changes the default initial receive window to 10 mss (defined constant). The default window is limited to the maximum of 10*1460 and 2*mss (when mss > 1460). draft-ietf-tcpm-initcwnd-00 is a proposal to the IETF that recommends increasing TCP's initial congestion window to 10 mss or about 15KB. Leading up to this proposal were several large-scale live Internet experiments with an initial congestion window of 10 mss (IW10), where we showed that the average latency of HTTP responses improved by approximately 10%. This was accompanied by a slight increase in retransmission rate (0.5%), most of which is coming from applications opening multiple simultaneous connections. To understand the extreme worst case scenarios, and fairness issues (IW10 versus IW3), we further conducted controlled testbed experiments. We came away finding minimal negative impact even under low link bandwidths (dial-ups) and small buffers. These results are extremely encouraging to adopting IW10. However, an initial congestion window of 10 mss is useless unless a TCP receiver advertises an initial receive window of at least 10 mss. Fortunately, in the large-scale Internet experiments we found that most widely used operating systems advertised large initial receive windows of 64KB, allowing us to experiment with a wide range of initial congestion windows. Linux systems were among the few exceptions that advertised a small receive window of 6KB. The purpose of this patch is to fix this shortcoming. References: 1. A comprehensive list of all IW10 references to date. http://code.google.com/speed/protocols/tcpm-IW10.html 2. Paper describing results from large-scale Internet experiments with IW10. http://ccr.sigcomm.org/drupal/?q=node/621 3. Controlled testbed experiments under worst case scenarios and a fairness study. http://www.ietf.org/proceedings/79/slides/tcpm-0.pdf 4. Raw test data from testbed experiments (Linux senders/receivers) with initial congestion and receive windows of both 10 mss. http://research.csc.ncsu.edu/netsrv/?q=content/iw10 5. Internet-Draft. Increasing TCP's Initial Window. https://datatracker.ietf.org/doc/draft-ietf-tcpm-initcwnd/ Signed-off-by: Nandita Dukkipati Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/tcp.h | 3 +++ net/ipv4/tcp_output.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index b4480300cadf..38509f047382 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -60,6 +60,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); */ #define MAX_TCP_WINDOW 32767U +/* Offer an initial receive window of 10 mss. */ +#define TCP_DEFAULT_INIT_RCVWND 10 + /* Minimal accepted MSS. It is (60+60+8) - (20+20). */ #define TCP_MIN_MSS 88U diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2d390669d406..dc7c096ddfef 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -228,10 +228,15 @@ void tcp_select_initial_window(int __space, __u32 mss, } } - /* Set initial window to value enough for senders, following RFC5681. */ + /* Set initial window to a value enough for senders starting with + * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place + * a limit on the initial window when mss is larger than 1460. + */ if (mss > (1 << *rcv_wscale)) { - int init_cwnd = rfc3390_bytes_to_packets(mss); - + int init_cwnd = TCP_DEFAULT_INIT_RCVWND; + if (mss > 1460) + init_cwnd = + max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2); /* when initializing use the value from init_rcv_wnd * rather than the default from above */ -- cgit v1.2.3-59-g8ed1b From 895950c2a6565d9eefda4a38b00fa28537e39fcb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 02:16:08 -0800 Subject: tg3: Use DEFINE_PCI_DEVICE_TABLE Moves the PCI tables to the right read-only section. Signed-off-by: Joe Perches --- drivers/net/tg3.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 57e19fb1324f..92fc29910c2d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13086,17 +13086,15 @@ static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) return 512; } +DEFINE_PCI_DEVICE_TABLE(write_reorder_chipsets) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) }, + { }, +}; + static int __devinit tg3_get_invariants(struct tg3 *tp) { - static struct pci_device_id write_reorder_chipsets[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, - PCI_DEVICE_ID_AMD_FE_GATE_700C) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, - PCI_DEVICE_ID_AMD_8131_BRIDGE) }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_8385_0) }, - { }, - }; u32 misc_ctrl_reg; u32 pci_state_reg, grc_misc_cfg; u32 val; @@ -14229,6 +14227,11 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm #define TEST_BUFFER_SIZE 0x2000 +DEFINE_PCI_DEVICE_TABLE(dma_wait_state_chipsets) = { + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, + { }, +}; + static int __devinit tg3_test_dma(struct tg3 *tp) { dma_addr_t buf_dma; @@ -14398,11 +14401,6 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != DMA_RWCTRL_WRITE_BNDRY_16) { - static struct pci_device_id dma_wait_state_chipsets[] = { - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, - PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, - { }, - }; /* DMA test passed without adjusting DMA boundary, * now look for chipsets that are known to expose the -- cgit v1.2.3-59-g8ed1b From b6bc765067ece933cc3dc7f5e95665a89100b1d5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 02:16:08 -0800 Subject: drivers/net/*.c: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. Signed-off-by: Joe Perches --- drivers/net/3c501.c | 4 ++-- drivers/net/3c503.c | 4 ++-- drivers/net/3c507.c | 4 ++-- drivers/net/3c527.c | 6 +++--- drivers/net/at1700.c | 6 +++--- drivers/net/bnx2.c | 46 ++++++++++++++++++++++++---------------------- drivers/net/e2100.c | 2 +- drivers/net/eepro.c | 9 +++++---- drivers/net/eexpress.c | 2 +- drivers/net/gianfar.c | 10 ++++++---- drivers/net/hp.c | 6 +++--- drivers/net/jme.c | 4 ++-- drivers/net/ksz884x.c | 20 ++++++++++---------- drivers/net/ni52.c | 4 ++-- drivers/net/ni65.c | 4 ++-- drivers/net/r8169.c | 2 +- drivers/net/skge.c | 4 ++-- drivers/net/smc-ultra.c | 8 ++++++-- drivers/net/wd.c | 2 +- 19 files changed, 78 insertions(+), 69 deletions(-) diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 1776ab61b05f..9e1c03eb97ae 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -158,8 +158,8 @@ static int mem_start; struct net_device * __init el1_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); - static unsigned ports[] = { 0x280, 0x300, 0}; - unsigned *port; + static const unsigned ports[] = { 0x280, 0x300, 0}; + const unsigned *port; int err = 0; if (!dev) diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index 4777a1cbcd8d..d84f6e8903a5 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -392,8 +392,8 @@ el2_open(struct net_device *dev) int retval; if (dev->irq < 2) { - int irqlist[] = {5, 9, 3, 4, 0}; - int *irqp = irqlist; + static const int irqlist[] = {5, 9, 3, 4, 0}; + const int *irqp = irqlist; outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */ do { diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 475a66d95b34..1e945551c144 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -311,8 +311,8 @@ static int mem_start; struct net_device * __init el16_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); - static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0}; - unsigned *port; + static const unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0}; + const unsigned *port; int err = -ENODEV; if (!dev) diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 013b7c396663..8c094bae8bf3 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -317,13 +317,13 @@ static int __init mc32_probe1(struct net_device *dev, int slot) u8 POS; u32 base; struct mc32_local *lp = netdev_priv(dev); - static u16 mca_io_bases[]={ + static const u16 mca_io_bases[] = { 0x7280,0x7290, 0x7680,0x7690, 0x7A80,0x7A90, 0x7E80,0x7E90 }; - static u32 mca_mem_bases[]={ + static const u32 mca_mem_bases[] = { 0x00C0000, 0x00C4000, 0x00C8000, @@ -333,7 +333,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) 0x00D8000, 0x00DC000 }; - static char *failures[]={ + static const char * const failures[] = { "Processor instruction", "Processor data bus", "Processor data bus", diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 871b1633f543..f4744fc89768 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -270,9 +270,9 @@ static const struct net_device_ops at1700_netdev_ops = { static int __init at1700_probe1(struct net_device *dev, int ioaddr) { - char fmv_irqmap[4] = {3, 7, 10, 15}; - char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; - char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; + static const char fmv_irqmap[4] = {3, 7, 10, 15}; + static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; + static const char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0; int slot, ret = -ENODEV; struct net_local *lp = netdev_priv(dev); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5c811f3fa11a..819b55cbd492 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6811,28 +6811,30 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) u32 *p = _p, i, offset; u8 *orig_p = _p; struct bnx2 *bp = netdev_priv(dev); - u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c, - 0x0800, 0x0880, 0x0c00, 0x0c10, - 0x0c30, 0x0d08, 0x1000, 0x101c, - 0x1040, 0x1048, 0x1080, 0x10a4, - 0x1400, 0x1490, 0x1498, 0x14f0, - 0x1500, 0x155c, 0x1580, 0x15dc, - 0x1600, 0x1658, 0x1680, 0x16d8, - 0x1800, 0x1820, 0x1840, 0x1854, - 0x1880, 0x1894, 0x1900, 0x1984, - 0x1c00, 0x1c0c, 0x1c40, 0x1c54, - 0x1c80, 0x1c94, 0x1d00, 0x1d84, - 0x2000, 0x2030, 0x23c0, 0x2400, - 0x2800, 0x2820, 0x2830, 0x2850, - 0x2b40, 0x2c10, 0x2fc0, 0x3058, - 0x3c00, 0x3c94, 0x4000, 0x4010, - 0x4080, 0x4090, 0x43c0, 0x4458, - 0x4c00, 0x4c18, 0x4c40, 0x4c54, - 0x4fc0, 0x5010, 0x53c0, 0x5444, - 0x5c00, 0x5c18, 0x5c80, 0x5c90, - 0x5fc0, 0x6000, 0x6400, 0x6428, - 0x6800, 0x6848, 0x684c, 0x6860, - 0x6888, 0x6910, 0x8000 }; + static const u32 reg_boundaries[] = { + 0x0000, 0x0098, 0x0400, 0x045c, + 0x0800, 0x0880, 0x0c00, 0x0c10, + 0x0c30, 0x0d08, 0x1000, 0x101c, + 0x1040, 0x1048, 0x1080, 0x10a4, + 0x1400, 0x1490, 0x1498, 0x14f0, + 0x1500, 0x155c, 0x1580, 0x15dc, + 0x1600, 0x1658, 0x1680, 0x16d8, + 0x1800, 0x1820, 0x1840, 0x1854, + 0x1880, 0x1894, 0x1900, 0x1984, + 0x1c00, 0x1c0c, 0x1c40, 0x1c54, + 0x1c80, 0x1c94, 0x1d00, 0x1d84, + 0x2000, 0x2030, 0x23c0, 0x2400, + 0x2800, 0x2820, 0x2830, 0x2850, + 0x2b40, 0x2c10, 0x2fc0, 0x3058, + 0x3c00, 0x3c94, 0x4000, 0x4010, + 0x4080, 0x4090, 0x43c0, 0x4458, + 0x4c00, 0x4c18, 0x4c40, 0x4c54, + 0x4fc0, 0x5010, 0x53c0, 0x5444, + 0x5c00, 0x5c18, 0x5c80, 0x5c90, + 0x5fc0, 0x6000, 0x6400, 0x6428, + 0x6800, 0x6848, 0x684c, 0x6860, + 0x6888, 0x6910, 0x8000 + }; regs->version = 0; diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index 06e72fbef862..94ec973b2bdc 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -216,7 +216,7 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr) printk(" %02X", station_addr[i]); if (dev->irq < 2) { - int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4}; + static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4}; for (i = 0; i < ARRAY_SIZE(irqlist); i++) if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) { dev->irq = irqlist[i]; diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 9e19fbc2f176..4fa8d2a4aef3 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -891,12 +891,13 @@ err: there is non-reboot way to recover if something goes wrong. */ -static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1}; -static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1}; +static const char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1}; +static const char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1}; static int eepro_grab_irq(struct net_device *dev) { - int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 }; - int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr; + static const int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 }; + const int *irqp = irqlist; + int temp_reg, ioaddr = dev->base_addr; eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */ diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 12c37d264108..48ee51bb9e50 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -1103,7 +1103,7 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr) dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i]; { - static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0}; + static const char irqmap[] = { 0, 9, 3, 4, 5, 10, 11, 0 }; unsigned short setupval = eexp_hw_readeeprom(ioaddr,0); /* Use the IRQ from EEPROM if none was given */ diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index d1bec6269173..45c4b7bfcf39 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -143,7 +143,8 @@ void gfar_halt(struct net_device *dev); static void gfar_halt_nodisable(struct net_device *dev); void gfar_start(struct net_device *dev); static void gfar_clear_exact_match(struct net_device *dev); -static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); +static void gfar_set_mac_for_addr(struct net_device *dev, int num, + const u8 *addr); static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); MODULE_AUTHOR("Freescale Semiconductor, Inc"); @@ -3094,10 +3095,10 @@ static void gfar_set_multi(struct net_device *dev) static void gfar_clear_exact_match(struct net_device *dev) { int idx; - u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0}; + static const u8 zero_arr[MAC_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; for(idx = 1;idx < GFAR_EM_NUM + 1;idx++) - gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr); + gfar_set_mac_for_addr(dev, idx, zero_arr); } /* Set the appropriate hash bit for the given addr */ @@ -3132,7 +3133,8 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr) /* There are multiple MAC Address register pairs on some controllers * This function sets the numth pair to a given address */ -static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr) +static void gfar_set_mac_for_addr(struct net_device *dev, int num, + const u8 *addr) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = priv->gfargrp[0].regs; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index d15d2f2ba78e..ef2014375e62 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -162,9 +162,9 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) /* Snarf the interrupt now. Someday this could be moved to open(). */ if (dev->irq < 2) { - int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0}; - int irq_8list[] = { 7, 5, 3, 4, 9, 0}; - int *irqp = wordmode ? irq_16list : irq_8list; + static const int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0}; + static const int irq_8list[] = { 7, 5, 3, 4, 9, 0}; + const int *irqp = wordmode ? irq_16list : irq_8list; do { int irq = *irqp; if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) { diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 2411e72ba572..e97ebef3cf47 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -135,7 +135,7 @@ jme_reset_phy_processor(struct jme_adapter *jme) static void jme_setup_wakeup_frame(struct jme_adapter *jme, - u32 *mask, u32 crc, int fnr) + const u32 *mask, u32 crc, int fnr) { int i; @@ -163,7 +163,7 @@ jme_setup_wakeup_frame(struct jme_adapter *jme, static inline void jme_reset_mac_processor(struct jme_adapter *jme) { - u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0}; + static const u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0}; u32 crc = 0xCDCDCDCD; u32 gpreg0; int i; diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 37504a398906..49ea8708d6d0 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -3570,7 +3570,7 @@ static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set) * This routine is used to program Wake-on-LAN pattern. */ static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, - u8 *mask, uint frame_size, u8 *pattern) + const u8 *mask, uint frame_size, const u8 *pattern) { int bits; int from; @@ -3626,9 +3626,9 @@ static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, * * This routine is used to add ARP pattern for waking up the host. */ -static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr) +static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr) { - u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 }; + static const u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 }; u8 pattern[42] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3651,8 +3651,8 @@ static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr) */ static void hw_add_wol_bcast(struct ksz_hw *hw) { - u8 mask[] = { 0x3F }; - u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + static const u8 mask[] = { 0x3F }; + static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern); } @@ -3669,7 +3669,7 @@ static void hw_add_wol_bcast(struct ksz_hw *hw) */ static void hw_add_wol_mcast(struct ksz_hw *hw) { - u8 mask[] = { 0x3F }; + static const u8 mask[] = { 0x3F }; u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 }; memcpy(&pattern[3], &hw->override_addr[3], 3); @@ -3687,7 +3687,7 @@ static void hw_add_wol_mcast(struct ksz_hw *hw) */ static void hw_add_wol_ucast(struct ksz_hw *hw) { - u8 mask[] = { 0x3F }; + static const u8 mask[] = { 0x3F }; hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr); } @@ -3700,7 +3700,7 @@ static void hw_add_wol_ucast(struct ksz_hw *hw) * * This routine is used to enable Wake-on-LAN depending on driver settings. */ -static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, u8 *net_addr) +static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr) { hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC)); hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST)); @@ -6208,7 +6208,7 @@ static int netdev_set_wol(struct net_device *dev, struct dev_info *hw_priv = priv->adapter; /* Need to find a way to retrieve the device IP address. */ - u8 net_addr[] = { 192, 168, 1, 1 }; + static const u8 net_addr[] = { 192, 168, 1, 1 }; if (wol->wolopts & ~hw_priv->wol_support) return -EINVAL; @@ -7241,7 +7241,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state) struct ksz_hw *hw = &hw_priv->hw; /* Need to find a way to retrieve the device IP address. */ - u8 net_addr[] = { 192, 168, 1, 1 }; + static const u8 net_addr[] = { 192, 168, 1, 1 }; for (i = 0; i < hw->dev_count; i++) { if (info->netdev[i]) { diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 33618edc61f9..d973fc6c6b88 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -388,9 +388,9 @@ static long memend; /* e.g 0xd4000 */ struct net_device * __init ni52_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct priv)); - static int ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0}; + static const int ports[] = {0x300, 0x280, 0x360, 0x320, 0x340, 0}; + const int *port; struct priv *p; - int *port; int err = 0; if (!dev) diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index da228a0dd6cd..c75ae85eb918 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -361,8 +361,8 @@ static int dma; struct net_device * __init ni65_probe(int unit) { struct net_device *dev = alloc_etherdev(0); - static int ports[] = {0x360,0x300,0x320,0x340, 0}; - int *port; + static const int ports[] = { 0x360, 0x300, 0x320, 0x340, 0 }; + const int *port; int err = 0; if (!dev) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4e745af96cf1..e165d96ec7df 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2526,7 +2526,7 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr) val = mdio_read(ioaddr, 0x0d); if ((val & 0x00ff) != 0x006c) { - u32 set[] = { + static const u32 set[] = { 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c }; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 50815fb963fe..c149e48a0f57 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -1191,7 +1191,7 @@ static void genesis_init(struct skge_hw *hw) static void genesis_reset(struct skge_hw *hw, int port) { - const u8 zero[8] = { 0 }; + static const u8 zero[8] = { 0 }; u32 reg; skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); @@ -1557,7 +1557,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN; int i; u32 r; - const u8 zero[6] = { 0 }; + static const u8 zero[6] = { 0 }; for (i = 0; i < 10; i++) { skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index d2dd8e6113ab..235a3c6c9f91 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -277,8 +277,12 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; { - int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000}; - short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff}; + static const int addr_tbl[4] = { + 0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000 + }; + static const short num_pages_tbl[4] = { + 0x20, 0x40, 0x80, 0xff + }; dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ; num_pages = num_pages_tbl[(addr >> 4) & 3]; diff --git a/drivers/net/wd.c b/drivers/net/wd.c index f1549fff0edc..8831a3393ecf 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -275,7 +275,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr+WD_NIC_OFFSET; if (dev->irq < 2) { - int irqmap[] = {9,3,5,7,10,11,15,4}; + static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4}; int reg1 = inb(ioaddr+1); int reg4 = inb(ioaddr+4); if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */ -- cgit v1.2.3-59-g8ed1b From 5591c75dc345d93d353d2ab2962824648a73efe4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 02:16:09 -0800 Subject: usb: Use static const, consolidate code Using static const generally increases object text and decreases data size. It also generally decreases overall object size. Consolidate duplicated code into new fix_crc_bug function and declare data in that function static const. Signed-off-by: Joe Perches --- drivers/net/usb/hso.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index ebcaaebf6b41..bed8fcedff49 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -997,6 +997,18 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, } } +static void fix_crc_bug(struct urb *urb, __le16 max_packet_size) +{ + static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; + u32 rest = urb->actual_length % le16_to_cpu(max_packet_size); + + if (((rest == 5) || (rest == 6)) && + !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4, + crc_check, 4)) { + urb->actual_length -= 4; + } +} + /* Moving data from usb to kernel (in interrupt state) */ static void read_bulk_callback(struct urb *urb) { @@ -1025,17 +1037,8 @@ static void read_bulk_callback(struct urb *urb) return; } - if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { - u32 rest; - u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = urb->actual_length % - le16_to_cpu(odev->in_endp->wMaxPacketSize); - if (((rest == 5) || (rest == 6)) && - !memcmp(((u8 *) urb->transfer_buffer) + - urb->actual_length - 4, crc_check, 4)) { - urb->actual_length -= 4; - } - } + if (odev->parent->port_spec & HSO_INFO_CRC_BUG) + fix_crc_bug(urb, odev->in_endp->wMaxPacketSize); /* do we even have a packet? */ if (urb->actual_length) { @@ -1227,18 +1230,8 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) return; if (status == 0) { - if (serial->parent->port_spec & HSO_INFO_CRC_BUG) { - u32 rest; - u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = - urb->actual_length % - le16_to_cpu(serial->in_endp->wMaxPacketSize); - if (((rest == 5) || (rest == 6)) && - !memcmp(((u8 *) urb->transfer_buffer) + - urb->actual_length - 4, crc_check, 4)) { - urb->actual_length -= 4; - } - } + if (serial->parent->port_spec & HSO_INFO_CRC_BUG) + fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); /* Valid data, handle RX data */ spin_lock(&serial->serial_lock); serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; -- cgit v1.2.3-59-g8ed1b From 75a84eb5d144dc761e1bb0f7dcacbf2b5cee562c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 02:16:09 -0800 Subject: tulip: Use DEFINE_PCI_DEVICE_TABLE and static const Moves the PCI table to the right read-only section. Using static const generally increases object text and decreases data size. It also generally decreases overall object size. Signed-off-by: Joe Perches --- drivers/net/tulip/tulip_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 2c39f2591216..5c01e260f1ba 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1302,17 +1302,18 @@ static const struct net_device_ops tulip_netdev_ops = { #endif }; +DEFINE_PCI_DEVICE_TABLE(early_486_chipsets) = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) }, + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) }, + { }, +}; + static int __devinit tulip_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct tulip_private *tp; /* See note below on the multiport cards. */ static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; - static struct pci_device_id early_486_chipsets[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) }, - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) }, - { }, - }; static int last_irq; static int multiport_cnt; /* For four-port boards w/one EEPROM */ int i, irq; @@ -1682,7 +1683,9 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, tp->full_duplex_lock = 1; if (tulip_media_cap[tp->default_port] & MediaIsMII) { - u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; + static const u16 media2advert[] = { + 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 + }; tp->mii_advertise = media2advert[tp->default_port - 9]; tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ } -- cgit v1.2.3-59-g8ed1b From 215faf9c5f6e319e97edea9e178123e07825c14d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 02:16:10 -0800 Subject: drivers/net/*/: Use static const Using static const generally increases object text and decreases data size. It also generally decreases overall object size. Signed-off-by: Joe Perches --- drivers/net/benet/be_ethtool.c | 4 +++- drivers/net/benet/be_main.c | 10 +++++----- drivers/net/bnx2x/bnx2x_main.c | 6 ++++-- drivers/net/can/sja1000/plx_pci.c | 2 +- drivers/net/chelsio/sge.c | 10 ++++------ drivers/net/cxgb3/ael1002.c | 24 ++++++++++++------------ drivers/net/cxgb3/t3_hw.c | 2 +- drivers/net/cxgb4vf/t4vf_hw.c | 2 +- drivers/net/irda/act200l-sir.c | 2 +- drivers/net/irda/donauboe.c | 4 ++-- drivers/net/netxen/netxen_nic_hw.c | 16 ++++++++++------ drivers/net/pcmcia/nmclan_cs.c | 2 +- drivers/net/qlcnic/qlcnic_hw.c | 15 +++++++++------ drivers/net/qlge/qlge_main.c | 13 +++++++------ drivers/net/skfp/smt.c | 4 ++-- drivers/net/tokenring/ibmtr.c | 5 +++-- drivers/net/tulip/de2104x.c | 18 ++++++++++++------ drivers/net/vmxnet3/vmxnet3_drv.c | 4 +++- drivers/net/wan/dscc4.c | 6 +++--- 19 files changed, 84 insertions(+), 65 deletions(-) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 0f46366ecc48..b4be0271efe0 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -549,7 +549,9 @@ be_test_ddr_dma(struct be_adapter *adapter) { int ret, i; struct be_dma_mem ddrdma_cmd; - u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL}; + static const u64 pattern[2] = { + 0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL + }; ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 88ce68d63bca..de40d3b7152f 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2398,10 +2398,10 @@ static int be_flash_data(struct be_adapter *adapter, int num_bytes; const u8 *p = fw->data; struct be_cmd_write_flashrom *req = flash_cmd->va; - struct flash_comp *pflashcomp; + const struct flash_comp *pflashcomp; int num_comp; - struct flash_comp gen3_flash_types[9] = { + static const struct flash_comp gen3_flash_types[9] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, FLASH_IMAGE_MAX_SIZE_g3}, { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, @@ -2421,7 +2421,7 @@ static int be_flash_data(struct be_adapter *adapter, { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, FLASH_NCSI_IMAGE_MAX_SIZE_g3} }; - struct flash_comp gen2_flash_types[8] = { + static const struct flash_comp gen2_flash_types[8] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, FLASH_IMAGE_MAX_SIZE_g2}, { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT, @@ -2443,11 +2443,11 @@ static int be_flash_data(struct be_adapter *adapter, if (adapter->generation == BE_GEN3) { pflashcomp = gen3_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g3); - num_comp = 9; + num_comp = ARRAY_SIZE(gen3_flash_types); } else { pflashcomp = gen2_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g2); - num_comp = 8; + num_comp = ARRAY_SIZE(gen2_flash_types); } for (i = 0; i < num_comp; i++) { if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index bdc3fc26b31a..cf54427a8d80 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6208,7 +6208,7 @@ static int bnx2x_func_stop(struct bnx2x *bp) * @param cam_offset offset in a CAM to use * @param is_bcast is the set MAC a broadcast address (for E1 only) */ -static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, +static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, u32 cl_bit_vec, u8 cam_offset, u8 is_bcast) { @@ -6400,7 +6400,9 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) if (CHIP_IS_E1(bp)) { /* broadcast MAC */ - u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static const u8 bcast[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); } } diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 437b5c716a24..231385b8e08f 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -383,7 +383,7 @@ static void plx_pci_reset_marathon(struct pci_dev *pdev) { void __iomem *reset_addr; int i; - int reset_bar[2] = {3, 5}; + static const int reset_bar[2] = {3, 5}; plx_pci_reset_common(pdev); diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 70221ca32683..f778b15ad3fd 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -273,6 +273,10 @@ struct sge { struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp; }; +static const u8 ch_mac_addr[ETH_ALEN] = { + 0x0, 0x7, 0x43, 0x0, 0x0, 0x0 +}; + /* * stop tasklet and free all pending skb's */ @@ -2012,10 +2016,6 @@ static void espibug_workaround_t204(unsigned long data) continue; if (!skb->cb[0]) { - u8 ch_mac_addr[ETH_ALEN] = { - 0x0, 0x7, 0x43, 0x0, 0x0, 0x0 - }; - skb_copy_to_linear_data_offset(skb, sizeof(struct cpl_tx_pkt), ch_mac_addr, @@ -2048,8 +2048,6 @@ static void espibug_workaround(unsigned long data) if ((seop & 0xfff0fff) == 0xfff && skb) { if (!skb->cb[0]) { - u8 ch_mac_addr[ETH_ALEN] = - {0x0, 0x7, 0x43, 0x0, 0x0, 0x0}; skb_copy_to_linear_data_offset(skb, sizeof(struct cpl_tx_pkt), ch_mac_addr, diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index 35cd36729155..2028da95afa1 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c @@ -292,7 +292,7 @@ unknown: */ static int ael2005_setup_sr_edc(struct cphy *phy) { - static struct reg_val regs[] = { + static const struct reg_val regs[] = { { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, @@ -324,11 +324,11 @@ static int ael2005_setup_sr_edc(struct cphy *phy) static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) { - static struct reg_val regs[] = { + static const struct reg_val regs[] = { { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, { 0, 0, 0, 0 } }; - static struct reg_val preemphasis[] = { + static const struct reg_val preemphasis[] = { { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, { 0, 0, 0, 0 } @@ -393,7 +393,7 @@ static int ael2005_intr_clear(struct cphy *phy) static int ael2005_reset(struct cphy *phy, int wait) { - static struct reg_val regs0[] = { + static const struct reg_val regs0[] = { { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, @@ -403,7 +403,7 @@ static int ael2005_reset(struct cphy *phy, int wait) { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, { 0, 0, 0, 0 } }; - static struct reg_val regs1[] = { + static const struct reg_val regs1[] = { { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, { 0, 0, 0, 0 } @@ -522,7 +522,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, */ static int ael2020_setup_sr_edc(struct cphy *phy) { - static struct reg_val regs[] = { + static const struct reg_val regs[] = { /* set CDR offset to 10 */ { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a }, @@ -551,20 +551,20 @@ static int ael2020_setup_sr_edc(struct cphy *phy) static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) { /* set uC to 40MHz */ - static struct reg_val uCclock40MHz[] = { + static const struct reg_val uCclock40MHz[] = { { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 }, { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 }, { 0, 0, 0, 0 } }; /* activate uC clock */ - static struct reg_val uCclockActivate[] = { + static const struct reg_val uCclockActivate[] = { { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 }, { 0, 0, 0, 0 } }; /* set PC to start of SRAM and activate uC */ - static struct reg_val uCactivate[] = { + static const struct reg_val uCactivate[] = { { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 }, { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 }, { 0, 0, 0, 0 } @@ -624,7 +624,7 @@ static int ael2020_get_module_type(struct cphy *phy, int delay_ms) */ static int ael2020_intr_enable(struct cphy *phy) { - struct reg_val regs[] = { + static const struct reg_val regs[] = { /* output Module's Loss Of Signal (LOS) to LED */ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, 0xffff, 0x4 }, @@ -664,7 +664,7 @@ static int ael2020_intr_enable(struct cphy *phy) */ static int ael2020_intr_disable(struct cphy *phy) { - struct reg_val regs[] = { + static const struct reg_val regs[] = { /* reset "link status" LED to "off" */ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) }, @@ -701,7 +701,7 @@ static int ael2020_intr_clear(struct cphy *phy) return err ? err : t3_phy_lasi_intr_clear(phy); } -static struct reg_val ael2020_reset_regs[] = { +static const struct reg_val ael2020_reset_regs[] = { /* Erratum #2: CDRLOL asserted, causing PMA link down status */ { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 }, diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 3a6adf0b3e9d..ec8579a0a808 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -1562,7 +1562,7 @@ static void tp_intr_handler(struct adapter *adapter) {0} }; - static struct intr_info tp_intr_info_t3c[] = { + static const struct intr_info tp_intr_info_t3c[] = { {0x1fffffff, "TP parity error", -1, 1}, {F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1}, {F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1}, diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 35fc803a6a04..e4bec78c8e3f 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -116,7 +116,7 @@ static void dump_mbox(struct adapter *adapter, const char *tag, u32 mbox_data) int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, void *rpl, bool sleep_ok) { - static int delay[] = { + static const int delay[] = { 1, 1, 3, 5, 10, 10, 20, 50, 100 }; diff --git a/drivers/net/irda/act200l-sir.c b/drivers/net/irda/act200l-sir.c index 37ab8c855719..8ff084f1d236 100644 --- a/drivers/net/irda/act200l-sir.c +++ b/drivers/net/irda/act200l-sir.c @@ -199,7 +199,7 @@ static int act200l_reset(struct sir_dev *dev) { unsigned state = dev->fsm.substate; unsigned delay = 0; - u8 control[9] = { + static const u8 control[9] = { ACT200L_REG15, ACT200L_REG13 | ACT200L_SHDW, ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index b626cccbccd1..f81d944fc360 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -818,9 +818,9 @@ toshoboe_probe (struct toshoboe_cb *self) { int i, j, n; #ifdef USE_MIR - int bauds[] = { 9600, 115200, 4000000, 1152000 }; + static const int bauds[] = { 9600, 115200, 4000000, 1152000 }; #else - int bauds[] = { 9600, 115200, 4000000 }; + static const int bauds[] = { 9600, 115200, 4000000 }; #endif unsigned long flags; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 37d3ebd65be8..e42d26e03af5 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -655,7 +655,7 @@ nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op) } static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, - u8 *addr, struct list_head *del_list) + const u8 *addr, struct list_head *del_list) { struct list_head *head; nx_mac_list_t *cur; @@ -686,7 +686,9 @@ static void netxen_p3_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; - u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static const u8 bcast_addr[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; u32 mode = VPORT_MISS_MODE_DROP; LIST_HEAD(del_list); struct list_head *head; @@ -869,9 +871,11 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) u64 word; int i, rv; - u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, - 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, - 0x255b0ec26d5a56daULL }; + static const u64 key[] = { + 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, + 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, + 0x255b0ec26d5a56daULL + }; memset(&req, 0, sizeof(nx_nic_req_t)); @@ -895,7 +899,7 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) ((u64)(enable & 0x1) << 8) | ((0x7ULL) << 48); req.words[0] = cpu_to_le64(word); - for (i = 0; i < 5; i++) + for (i = 0; i < ARRAY_SIZE(key); i++) req.words[i+1] = cpu_to_le64(key[i]); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 0a2b0f9cdf33..76683d97d83b 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1291,7 +1291,7 @@ updateCRC static void updateCRC(int *CRC, int bit) { - int poly[]={ + static const int poly[]={ 1,1,1,0, 1,1,0,1, 1,0,1,1, 1,0,0,0, 1,0,0,0, 0,0,1,1, diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index c9c4bf1458a8..616940f0a8d0 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -381,7 +381,7 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } -static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) +static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr) { struct list_head *head; struct qlcnic_mac_list_s *cur; @@ -415,7 +415,9 @@ void qlcnic_set_multi(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; - u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static const u8 bcast_addr[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; u32 mode = VPORT_MISS_MODE_DROP; if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) @@ -621,10 +623,11 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) u64 word; int i, rv; - const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, - 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, - 0x255b0ec26d5a56daULL }; - + static const u64 key[] = { + 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, + 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, + 0x255b0ec26d5a56daULL + }; memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 3af30c452b88..49bfa5813068 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3548,12 +3548,13 @@ err_irq: static int ql_start_rss(struct ql_adapter *qdev) { - u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, - 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, - 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, - 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, - 0xbe, 0xac, 0x01, 0xfa}; + static const u8 init_hash_seed[] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa + }; struct ricb *ricb = &qdev->ricb; int status = 0; int i; diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c index 2d9941c045bc..1e1bd0c201c8 100644 --- a/drivers/net/skfp/smt.c +++ b/drivers/net/skfp/smt.c @@ -1263,7 +1263,7 @@ void smt_set_timestamp(struct s_smc *smc, u_char *p) static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy) { int i ; - u_char *map ; + const u_char *map ; u_short in ; u_short out ; @@ -1271,7 +1271,7 @@ static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy) * MIB para 101b (fddiSMTConnectionPolicy) coding * is different from 0005 coding */ - static u_char ansi_weirdness[16] = { + static const u_char ansi_weirdness[16] = { 0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15 } ; SMTSETPARA(policy,SMT_P_POLICY) ; diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 91e6c78271a3..4786497de03e 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -657,8 +657,9 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr) #ifndef PCMCIA /* finish figuring the shared RAM address */ if (cardpresent == TR_ISA) { - static __u32 ram_bndry_mask[] = - { 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 }; + static const __u32 ram_bndry_mask[] = { + 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 + }; __u32 new_base, rrr_32, chk_base, rbm; rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03; diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index c78a50586c1d..b13c6b040be3 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -964,7 +964,7 @@ static void de_set_media (struct de_private *de) dw32(MacMode, macmode); } -static void de_next_media (struct de_private *de, u32 *media, +static void de_next_media (struct de_private *de, const u32 *media, unsigned int n_media) { unsigned int i; @@ -1008,10 +1008,10 @@ static void de21040_media_timer (unsigned long data) return; if (de->media_type == DE_MEDIA_AUI) { - u32 next_state = DE_MEDIA_TP; + static const u32 next_state = DE_MEDIA_TP; de_next_media(de, &next_state, 1); } else { - u32 next_state = DE_MEDIA_AUI; + static const u32 next_state = DE_MEDIA_AUI; de_next_media(de, &next_state, 1); } @@ -1136,13 +1136,19 @@ static void de21041_media_timer (unsigned long data) * simply resets the PHY and reloads the current media settings. */ if (de->media_type == DE_MEDIA_AUI) { - u32 next_states[] = { DE_MEDIA_BNC, DE_MEDIA_TP_AUTO }; + static const u32 next_states[] = { + DE_MEDIA_BNC, DE_MEDIA_TP_AUTO + }; de_next_media(de, next_states, ARRAY_SIZE(next_states)); } else if (de->media_type == DE_MEDIA_BNC) { - u32 next_states[] = { DE_MEDIA_TP_AUTO, DE_MEDIA_AUI }; + static const u32 next_states[] = { + DE_MEDIA_TP_AUTO, DE_MEDIA_AUI + }; de_next_media(de, next_states, ARRAY_SIZE(next_states)); } else { - u32 next_states[] = { DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO }; + static const u32 next_states[] = { + DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO + }; de_next_media(de, next_states, ARRAY_SIZE(next_states)); } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 939e5466c75e..d143e8b72b5b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1131,7 +1131,9 @@ static int vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter, int quota) { - static u32 rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2}; + static const u32 rxprod_reg[2] = { + VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 + }; u32 num_rxd = 0; struct Vmxnet3_RxCompDesc *rcd; struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index d45b08d1dbc9..34cff6ce6d27 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -1358,7 +1358,7 @@ static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return ret; } -static int dscc4_match(struct thingie *p, int value) +static int dscc4_match(const struct thingie *p, int value) { int i; @@ -1403,7 +1403,7 @@ done: static int dscc4_encoding_setting(struct dscc4_dev_priv *dpriv, struct net_device *dev) { - struct thingie encoding[] = { + static const struct thingie encoding[] = { { ENCODING_NRZ, 0x00000000 }, { ENCODING_NRZI, 0x00200000 }, { ENCODING_FM_MARK, 0x00400000 }, @@ -1442,7 +1442,7 @@ static int dscc4_loopback_setting(struct dscc4_dev_priv *dpriv, static int dscc4_crc_setting(struct dscc4_dev_priv *dpriv, struct net_device *dev) { - struct thingie crc[] = { + static const struct thingie crc[] = { { PARITY_CRC16_PR0_CCITT, 0x00000010 }, { PARITY_CRC16_PR1_CCITT, 0x00000000 }, { PARITY_CRC32_PR0_CCITT, 0x00000011 }, -- cgit v1.2.3-59-g8ed1b From 70978182d431e0348e6ef711d0f962d12c03bc46 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Dec 2010 21:22:51 +0000 Subject: net: timestamp cloned packet in dev_queue_xmit_nit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le vendredi 17 décembre 2010 à 10:26 +0100, Eric Dumazet a écrit : > > I think we can add this after latest Changli patch : > > He does one skb_clone() before calling the sniffers. > We could set timestamp on this clone, instead of original skb. > > Problem solved. > [PATCH net-next-2.6] net: timestamp cloned packet in dev_queue_xmit_nit Now we do one clone of skb if at least one sniffer might take packet, we also can do the skb timestamping on the clone and let original packet unchanged. This is a generalization of commit 8caf153974f2 (net: sch_netem: Fix an inconsistency in ingress netem timestamps.) This way, we can have a good idea when packets are delivered to our stack (tcpdump -i ifb0), while a tcpdump on original device gives timestamps right before ingressing. This also speedup our stack, avoiding taking timestamps if not needed. Signed-off-by: Eric Dumazet Cc: Changli Gao Cc: Patrick McHardy Cc: Jarek Poplawski Acked-by: Changli Gao Signed-off-by: David S. Miller --- net/core/dev.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 59877290bca7..a215269d2e35 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1547,13 +1547,6 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *skb2 = NULL; struct packet_type *pt_prev = NULL; -#ifdef CONFIG_NET_CLS_ACT - if (!(skb->tstamp.tv64 && (G_TC_FROM(skb->tc_verd) & AT_INGRESS))) - net_timestamp_set(skb); -#else - net_timestamp_set(skb); -#endif - rcu_read_lock(); list_for_each_entry_rcu(ptype, &ptype_all, list) { /* Never send packets back to the socket @@ -1572,6 +1565,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) if (!skb2) break; + net_timestamp_set(skb2); + /* skb->nh should be correctly set by sender, so that the second statement is just protection against buggy protocols. -- cgit v1.2.3-59-g8ed1b From 4b97f8e10893e2c8f64a2795901bdb447a3308f4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 Dec 2010 21:04:02 +0000 Subject: bnx2x: remove bogus check We dereferenced params on the line before so it's too late to check if params is NULL. In fact, params can never be NULL and strict_cos is either 0 or 1 so that part of the check is bogus too. Let's remove it. Signed-off-by: Dan Carpenter Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 97cbee2927fc..43b0de24f391 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -354,9 +354,6 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) struct bnx2x *bp = params->bp; u32 val = 0; - if ((1 < strict_cos) && (NULL == params)) - return -EINVAL; - DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n"); /** * Bitmap of 5bits length. Each bit specifies whether the entry behaves -- cgit v1.2.3-59-g8ed1b From 34a52f363ab6bcf6d50a65c153dec03f3fb32653 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 Dec 2010 21:34:56 +0000 Subject: stmmac: unwind properly in stmmac_dvr_probe() The original code had a several problems: *) It had potential null dereferences of "priv" and "res". *) It released the memory region before it was aquired. *) It didn't free "ndev" after it was allocated. *) It didn't call unregister_netdev() after calling stmmac_probe(). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 50 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 20f803df8681..34a0af3837f9 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1647,10 +1647,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev) pr_info("STMMAC driver:\n\tplatform registration... "); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto out; - } + if (!res) + return -ENODEV; pr_info("\tdone!\n"); if (!request_mem_region(res->start, resource_size(res), @@ -1658,22 +1656,21 @@ static int stmmac_dvr_probe(struct platform_device *pdev) pr_err("%s: ERROR: memory allocation failed" "cannot get the I/O addr 0x%x\n", __func__, (unsigned int)res->start); - ret = -EBUSY; - goto out; + return -EBUSY; } addr = ioremap(res->start, resource_size(res)); if (!addr) { pr_err("%s: ERROR: memory mapping failed\n", __func__); ret = -ENOMEM; - goto out; + goto out_release_region; } ndev = alloc_etherdev(sizeof(struct stmmac_priv)); if (!ndev) { pr_err("%s: ERROR: allocating the device\n", __func__); ret = -ENOMEM; - goto out; + goto out_unmap; } SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1683,8 +1680,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (ndev->irq == -ENXIO) { pr_err("%s: ERROR: MAC IRQ configuration " "information not found\n", __func__); - ret = -ENODEV; - goto out; + ret = -ENXIO; + goto out_free_ndev; } priv = netdev_priv(ndev); @@ -1711,18 +1708,18 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (priv->plat->init) { ret = priv->plat->init(pdev); if (unlikely(ret)) - goto out; + goto out_free_ndev; } /* MAC HW revice detection */ ret = stmmac_mac_device_setup(ndev); if (ret < 0) - goto out; + goto out_plat_exit; /* Network Device Registration */ ret = stmmac_probe(ndev); if (ret < 0) - goto out; + goto out_plat_exit; /* associate a PHY - it is provided by another platform bus */ if (!driver_for_each_device @@ -1730,7 +1727,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) stmmac_associate_phy)) { pr_err("No PHY device is associated with this MAC!\n"); ret = -ENODEV; - goto out; + goto out_unregister; } pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" @@ -1741,19 +1738,22 @@ static int stmmac_dvr_probe(struct platform_device *pdev) pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id); ret = stmmac_mdio_register(ndev); if (ret < 0) - goto out; + goto out_unregister; pr_debug("registered!\n"); + return 0; -out: - if (ret < 0) { - if (priv->plat->exit) - priv->plat->exit(pdev); - - platform_set_drvdata(pdev, NULL); - release_mem_region(res->start, resource_size(res)); - if (addr != NULL) - iounmap(addr); - } +out_unregister: + unregister_netdev(ndev); +out_plat_exit: + if (priv->plat->exit) + priv->plat->exit(pdev); +out_free_ndev: + free_netdev(ndev); + platform_set_drvdata(pdev, NULL); +out_unmap: + iounmap(addr); +out_release_region: + release_mem_region(res->start, resource_size(res)); return ret; } -- cgit v1.2.3-59-g8ed1b From cb8f404893bab40431f7eeb2511454031b07e7df Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Dec 2010 06:09:59 +0000 Subject: bnx2: remove cancel_work_sync() from remove_one Michael pointed out that bnx2_close() already cancels bp->reset_task and thus it is guaranteed to be idle when bnx2_remove_one() is called. Remove the unnecessary cancel_work_sync() in remove_one. Signed-off-by: Tejun Heo Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5c811f3fa11a..85fc2c88af8e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -8393,8 +8393,6 @@ bnx2_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = netdev_priv(dev); - cancel_work_sync(&bp->reset_task); - unregister_netdev(dev); if (bp->mips_firmware) -- cgit v1.2.3-59-g8ed1b From 12b16dadbc2406144d408754f96d0f44aa016239 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Dec 2010 19:45:28 +0000 Subject: filter: optimize accesses to ancillary data We can translate pseudo load instructions at filter check time to dedicated instructions to speed up filtering and avoid one switch(). libpcap currently uses SKF_AD_PROTOCOL, but custom filters probably use other ancillary accesses. Note : I made the assertion that ancillary data was always accessed with BPF_LD|BPF_?|BPF_ABS instructions, not with BPF_LD|BPF_?|BPF_IND ones (offset given by K constant, not by K + X register) On x86_64, this saves a few bytes of text : # size net/core/filter.o.* text data bss dec hex filename 4864 0 0 4864 1300 net/core/filter.o.new 4944 0 0 4944 1350 net/core/filter.o.old Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/filter.c | 72 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index e8a6ac411ffb..2b27d4efdd48 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -85,6 +85,17 @@ enum { BPF_S_JMP_JGT_X, BPF_S_JMP_JSET_K, BPF_S_JMP_JSET_X, + /* Ancillary data */ + BPF_S_ANC_PROTOCOL, + BPF_S_ANC_PKTTYPE, + BPF_S_ANC_IFINDEX, + BPF_S_ANC_NLATTR, + BPF_S_ANC_NLATTR_NEST, + BPF_S_ANC_MARK, + BPF_S_ANC_QUEUE, + BPF_S_ANC_HATYPE, + BPF_S_ANC_RXHASH, + BPF_S_ANC_CPU, }; /* No hurry in this branch */ @@ -107,11 +118,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k, { if (k >= 0) return skb_header_pointer(skb, k, size, buffer); - else { - if (k >= SKF_AD_OFF) - return NULL; - return __load_pointer(skb, k, size); - } + return __load_pointer(skb, k, size); } /** @@ -269,7 +276,7 @@ load_w: A = get_unaligned_be32(ptr); continue; } - break; + return 0; case BPF_S_LD_H_ABS: k = K; load_h: @@ -278,7 +285,7 @@ load_h: A = get_unaligned_be16(ptr); continue; } - break; + return 0; case BPF_S_LD_B_ABS: k = K; load_b: @@ -287,7 +294,7 @@ load_b: A = *(u8 *)ptr; continue; } - break; + return 0; case BPF_S_LD_W_LEN: A = skb->len; continue; @@ -338,45 +345,35 @@ load_b: case BPF_S_STX: mem[K] = X; continue; - default: - WARN_ON(1); - return 0; - } - - /* - * Handle ancillary data, which are impossible - * (or very difficult) to get parsing packet contents. - */ - switch (k-SKF_AD_OFF) { - case SKF_AD_PROTOCOL: + case BPF_S_ANC_PROTOCOL: A = ntohs(skb->protocol); continue; - case SKF_AD_PKTTYPE: + case BPF_S_ANC_PKTTYPE: A = skb->pkt_type; continue; - case SKF_AD_IFINDEX: + case BPF_S_ANC_IFINDEX: if (!skb->dev) return 0; A = skb->dev->ifindex; continue; - case SKF_AD_MARK: + case BPF_S_ANC_MARK: A = skb->mark; continue; - case SKF_AD_QUEUE: + case BPF_S_ANC_QUEUE: A = skb->queue_mapping; continue; - case SKF_AD_HATYPE: + case BPF_S_ANC_HATYPE: if (!skb->dev) return 0; A = skb->dev->type; continue; - case SKF_AD_RXHASH: + case BPF_S_ANC_RXHASH: A = skb->rxhash; continue; - case SKF_AD_CPU: + case BPF_S_ANC_CPU: A = raw_smp_processor_id(); continue; - case SKF_AD_NLATTR: { + case BPF_S_ANC_NLATTR: { struct nlattr *nla; if (skb_is_nonlinear(skb)) @@ -392,7 +389,7 @@ load_b: A = 0; continue; } - case SKF_AD_NLATTR_NEST: { + case BPF_S_ANC_NLATTR_NEST: { struct nlattr *nla; if (skb_is_nonlinear(skb)) @@ -412,6 +409,7 @@ load_b: continue; } default: + WARN_ON(1); return 0; } } @@ -600,6 +598,24 @@ int sk_chk_filter(struct sock_filter *filter, int flen) pc + ftest->jf + 1 >= flen) return -EINVAL; break; + case BPF_S_LD_W_ABS: + case BPF_S_LD_H_ABS: + case BPF_S_LD_B_ABS: +#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \ + code = BPF_S_ANC_##CODE; \ + break + switch (ftest->k) { + ANCILLARY(PROTOCOL); + ANCILLARY(PKTTYPE); + ANCILLARY(IFINDEX); + ANCILLARY(NLATTR); + ANCILLARY(NLATTR_NEST); + ANCILLARY(MARK); + ANCILLARY(QUEUE); + ANCILLARY(HATYPE); + ANCILLARY(RXHASH); + ANCILLARY(CPU); + } } ftest->code = code; } -- cgit v1.2.3-59-g8ed1b From 24de5285dce378e4170e068f2662236d2b46c033 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Tue, 21 Dec 2010 02:01:36 +0000 Subject: sundance: Wrap up acceess to ASICCtrl high word with a macro Wrap up acceess to ASICCtrl high word with a macro Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 3ed2a67bd6d3..8916f29301d6 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -294,6 +294,9 @@ enum alta_offsets { /* Aliased and bogus values! */ RxStatus = 0x0c, }; + +#define ASIC_HI_WORD(x) ((x) + 2) + enum ASICCtrl_HiWord_bit { GlobalReset = 0x0001, RxReset = 0x0002, @@ -1772,10 +1775,10 @@ static int netdev_close(struct net_device *dev) } iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset, - ioaddr +ASICCtrl + 2); + ioaddr + ASIC_HI_WORD(ASICCtrl)); for (i = 2000; i > 0; i--) { - if ((ioread16(ioaddr + ASICCtrl +2) & ResetBusy) == 0) + if ((ioread16(ioaddr + ASIC_HI_WORD(ASICCtrl)) & ResetBusy) == 0) break; mdelay(1); } -- cgit v1.2.3-59-g8ed1b From 4b4f54670859074cf7670cc6fa96fe34a65846d9 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Tue, 21 Dec 2010 02:02:26 +0000 Subject: sundance: Program station address into HW Program adapter's StationAddress register when changing device MAC address Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 8916f29301d6..e5662962c7bf 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -434,6 +434,7 @@ static void netdev_error(struct net_device *dev, int intr_status); static void netdev_error(struct net_device *dev, int intr_status); static void set_rx_mode(struct net_device *dev); static int __set_mac_addr(struct net_device *dev); +static int sundance_set_mac_addr(struct net_device *dev, void *data); static struct net_device_stats *get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int netdev_close(struct net_device *dev); @@ -467,7 +468,7 @@ static const struct net_device_ops netdev_ops = { .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = tx_timeout, .ndo_change_mtu = change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = sundance_set_mac_addr, .ndo_validate_addr = eth_validate_addr, }; @@ -1595,6 +1596,19 @@ static int __set_mac_addr(struct net_device *dev) return 0; } +/* Invoked with rtnl_lock held */ +static int sundance_set_mac_addr(struct net_device *dev, void *data) +{ + const struct sockaddr *addr = data; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + __set_mac_addr(dev); + + return 0; +} + static const struct { const char name[ETH_GSTRING_LEN]; } sundance_stats[] = { -- cgit v1.2.3-59-g8ed1b From 3cfeb0c33f5cbcc6dde371392877ef3101b8f805 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 20 Dec 2010 15:16:53 -0500 Subject: rtl818x: move rtl8180 and rtl8187 to separate subdirectories These drivers share one header file, but nothing else. Worse, both drivers use the rtl8225 part with different register settings. The results has been some ugly naming -- let's simplify that. Signed-off-by: John W. Linville Acked-by: Hin-Tak Leung Acked-by: Larry Finger Acked-by: Herton Ronaldo Krzesinski --- MAINTAINERS | 4 +- drivers/net/wireless/rtl818x/Makefile | 9 +- drivers/net/wireless/rtl818x/rtl8180.h | 130 -- drivers/net/wireless/rtl818x/rtl8180/Makefile | 5 + drivers/net/wireless/rtl818x/rtl8180/dev.c | 1188 ++++++++++++++++++ drivers/net/wireless/rtl818x/rtl8180/grf5101.c | 190 +++ drivers/net/wireless/rtl818x/rtl8180/grf5101.h | 28 + drivers/net/wireless/rtl818x/rtl8180/max2820.c | 169 +++ drivers/net/wireless/rtl818x/rtl8180/max2820.h | 28 + drivers/net/wireless/rtl818x/rtl8180/rtl8180.h | 130 ++ drivers/net/wireless/rtl818x/rtl8180/rtl8225.c | 791 ++++++++++++ drivers/net/wireless/rtl818x/rtl8180/rtl8225.h | 23 + drivers/net/wireless/rtl818x/rtl8180/sa2400.c | 228 ++++ drivers/net/wireless/rtl818x/rtl8180/sa2400.h | 36 + drivers/net/wireless/rtl818x/rtl8180_dev.c | 1188 ------------------ drivers/net/wireless/rtl818x/rtl8180_grf5101.c | 190 --- drivers/net/wireless/rtl818x/rtl8180_grf5101.h | 28 - drivers/net/wireless/rtl818x/rtl8180_max2820.c | 169 --- drivers/net/wireless/rtl818x/rtl8180_max2820.h | 28 - drivers/net/wireless/rtl818x/rtl8180_rtl8225.c | 791 ------------ drivers/net/wireless/rtl818x/rtl8180_rtl8225.h | 23 - drivers/net/wireless/rtl818x/rtl8180_sa2400.c | 228 ---- drivers/net/wireless/rtl818x/rtl8180_sa2400.h | 36 - drivers/net/wireless/rtl818x/rtl8187.h | 271 ---- drivers/net/wireless/rtl818x/rtl8187/Makefile | 5 + drivers/net/wireless/rtl818x/rtl8187/dev.c | 1591 ++++++++++++++++++++++++ drivers/net/wireless/rtl818x/rtl8187/leds.c | 245 ++++ drivers/net/wireless/rtl818x/rtl8187/leds.h | 59 + drivers/net/wireless/rtl818x/rtl8187/rfkill.c | 64 + drivers/net/wireless/rtl818x/rtl8187/rfkill.h | 8 + drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 271 ++++ drivers/net/wireless/rtl818x/rtl8187/rtl8225.c | 961 ++++++++++++++ drivers/net/wireless/rtl818x/rtl8187/rtl8225.h | 44 + drivers/net/wireless/rtl818x/rtl8187_dev.c | 1591 ------------------------ drivers/net/wireless/rtl818x/rtl8187_leds.c | 245 ---- drivers/net/wireless/rtl818x/rtl8187_leds.h | 59 - drivers/net/wireless/rtl818x/rtl8187_rfkill.c | 64 - drivers/net/wireless/rtl818x/rtl8187_rfkill.h | 8 - drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | 961 -------------- drivers/net/wireless/rtl818x/rtl8187_rtl8225.h | 44 - 40 files changed, 6068 insertions(+), 6063 deletions(-) delete mode 100644 drivers/net/wireless/rtl818x/rtl8180.h create mode 100644 drivers/net/wireless/rtl818x/rtl8180/Makefile create mode 100644 drivers/net/wireless/rtl818x/rtl8180/dev.c create mode 100644 drivers/net/wireless/rtl818x/rtl8180/grf5101.c create mode 100644 drivers/net/wireless/rtl818x/rtl8180/grf5101.h create mode 100644 drivers/net/wireless/rtl818x/rtl8180/max2820.c create mode 100644 drivers/net/wireless/rtl818x/rtl8180/max2820.h create mode 100644 drivers/net/wireless/rtl818x/rtl8180/rtl8180.h create mode 100644 drivers/net/wireless/rtl818x/rtl8180/rtl8225.c create mode 100644 drivers/net/wireless/rtl818x/rtl8180/rtl8225.h create mode 100644 drivers/net/wireless/rtl818x/rtl8180/sa2400.c create mode 100644 drivers/net/wireless/rtl818x/rtl8180/sa2400.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_dev.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_grf5101.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_grf5101.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_max2820.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_max2820.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_rtl8225.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_rtl8225.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_sa2400.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8180_sa2400.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8187.h create mode 100644 drivers/net/wireless/rtl818x/rtl8187/Makefile create mode 100644 drivers/net/wireless/rtl818x/rtl8187/dev.c create mode 100644 drivers/net/wireless/rtl818x/rtl8187/leds.c create mode 100644 drivers/net/wireless/rtl818x/rtl8187/leds.h create mode 100644 drivers/net/wireless/rtl818x/rtl8187/rfkill.c create mode 100644 drivers/net/wireless/rtl818x/rtl8187/rfkill.h create mode 100644 drivers/net/wireless/rtl818x/rtl8187/rtl8187.h create mode 100644 drivers/net/wireless/rtl818x/rtl8187/rtl8225.c create mode 100644 drivers/net/wireless/rtl818x/rtl8187/rtl8225.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_dev.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_leds.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_leds.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_rfkill.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_rfkill.h delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_rtl8225.c delete mode 100644 drivers/net/wireless/rtl818x/rtl8187_rtl8225.h diff --git a/MAINTAINERS b/MAINTAINERS index 94c129f7240c..ff19c305d1c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5032,7 +5032,7 @@ L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained -F: drivers/net/wireless/rtl818x/rtl8180* +F: drivers/net/wireless/rtl818x/rtl8180/ RTL8187 WIRELESS DRIVER M: Herton Ronaldo Krzesinski @@ -5042,7 +5042,7 @@ L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained -F: drivers/net/wireless/rtl818x/rtl8187* +F: drivers/net/wireless/rtl818x/rtl8187/ RTL8192CE WIRELESS DRIVER M: Larry Finger diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile index 93cbfbedb46d..997569076923 100644 --- a/drivers/net/wireless/rtl818x/Makefile +++ b/drivers/net/wireless/rtl818x/Makefile @@ -1,7 +1,2 @@ -rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o -rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o - -obj-$(CONFIG_RTL8180) += rtl8180.o -obj-$(CONFIG_RTL8187) += rtl8187.o - - +obj-$(CONFIG_RTL8180) += rtl8180/ +obj-$(CONFIG_RTL8187) += rtl8187/ diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h deleted file mode 100644 index 30523314da43..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef RTL8180_H -#define RTL8180_H - -#include "rtl818x.h" - -#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD - -#define RF_PARAM_ANALOGPHY (1 << 0) -#define RF_PARAM_ANTBDEFAULT (1 << 1) -#define RF_PARAM_CARRIERSENSE1 (1 << 2) -#define RF_PARAM_CARRIERSENSE2 (1 << 3) - -#define BB_ANTATTEN_CHAN14 0x0C -#define BB_ANTENNA_B 0x40 - -#define BB_HOST_BANG (1 << 30) -#define BB_HOST_BANG_EN (1 << 2) -#define BB_HOST_BANG_CLK (1 << 1) -#define BB_HOST_BANG_DATA 1 - -#define ANAPARAM_TXDACOFF_SHIFT 27 -#define ANAPARAM_PWR0_SHIFT 28 -#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT) -#define ANAPARAM_PWR1_SHIFT 20 -#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) - -struct rtl8180_tx_desc { - __le32 flags; - __le16 rts_duration; - __le16 plcp_len; - __le32 tx_buf; - __le32 frame_len; - __le32 next_tx_desc; - u8 cw; - u8 retry_limit; - u8 agc; - u8 flags2; - u32 reserved[2]; -} __packed; - -struct rtl8180_rx_desc { - __le32 flags; - __le32 flags2; - union { - __le32 rx_buf; - __le64 tsft; - }; -} __packed; - -struct rtl8180_tx_ring { - struct rtl8180_tx_desc *desc; - dma_addr_t dma; - unsigned int idx; - unsigned int entries; - struct sk_buff_head queue; -}; - -struct rtl8180_vif { - struct ieee80211_hw *dev; - - /* beaconing */ - struct delayed_work beacon_work; - bool enable_beacon; -}; - -struct rtl8180_priv { - /* common between rtl818x drivers */ - struct rtl818x_csr __iomem *map; - const struct rtl818x_rf_ops *rf; - struct ieee80211_vif *vif; - - /* rtl8180 driver specific */ - spinlock_t lock; - struct rtl8180_rx_desc *rx_ring; - dma_addr_t rx_ring_dma; - unsigned int rx_idx; - struct sk_buff *rx_buf[32]; - struct rtl8180_tx_ring tx_ring[4]; - struct ieee80211_channel channels[14]; - struct ieee80211_rate rates[12]; - struct ieee80211_supported_band band; - struct pci_dev *pdev; - u32 rx_conf; - - int r8185; - u32 anaparam; - u16 rfparam; - u8 csthreshold; - - /* sequence # */ - u16 seqno; -}; - -void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); -void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); - -static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr) -{ - return ioread8(addr); -} - -static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr) -{ - return ioread16(addr); -} - -static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr) -{ - return ioread32(addr); -} - -static inline void rtl818x_iowrite8(struct rtl8180_priv *priv, - u8 __iomem *addr, u8 val) -{ - iowrite8(val, addr); -} - -static inline void rtl818x_iowrite16(struct rtl8180_priv *priv, - __le16 __iomem *addr, u16 val) -{ - iowrite16(val, addr); -} - -static inline void rtl818x_iowrite32(struct rtl8180_priv *priv, - __le32 __iomem *addr, u32 val) -{ - iowrite32(val, addr); -} - -#endif /* RTL8180_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180/Makefile b/drivers/net/wireless/rtl818x/rtl8180/Makefile new file mode 100644 index 000000000000..cb4fb8596f0b --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/Makefile @@ -0,0 +1,5 @@ +rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o + +obj-$(CONFIG_RTL8180) += rtl8180.o + +ccflags-y += -Idrivers/net/wireless/rtl818x diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c new file mode 100644 index 000000000000..5851cbc1e957 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -0,0 +1,1188 @@ + +/* + * Linux device driver for RTL8180 / RTL8185 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rtl8180.h" +#include "rtl8225.h" +#include "sa2400.h" +#include "max2820.h" +#include "grf5101.h" + +MODULE_AUTHOR("Michael Wu "); +MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver"); +MODULE_LICENSE("GPL"); + +static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { + /* rtl8185 */ + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, + { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, + { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) }, + + /* rtl8180 */ + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) }, + { PCI_DEVICE(0x1799, 0x6001) }, + { PCI_DEVICE(0x1799, 0x6020) }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, + { } +}; + +MODULE_DEVICE_TABLE(pci, rtl8180_table); + +static const struct ieee80211_rate rtl818x_rates[] = { + { .bitrate = 10, .hw_value = 0, }, + { .bitrate = 20, .hw_value = 1, }, + { .bitrate = 55, .hw_value = 2, }, + { .bitrate = 110, .hw_value = 3, }, + { .bitrate = 60, .hw_value = 4, }, + { .bitrate = 90, .hw_value = 5, }, + { .bitrate = 120, .hw_value = 6, }, + { .bitrate = 180, .hw_value = 7, }, + { .bitrate = 240, .hw_value = 8, }, + { .bitrate = 360, .hw_value = 9, }, + { .bitrate = 480, .hw_value = 10, }, + { .bitrate = 540, .hw_value = 11, }, +}; + +static const struct ieee80211_channel rtl818x_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + + +void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + int i = 10; + u32 buf; + + buf = (data << 8) | addr; + + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80); + while (i--) { + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf); + if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF)) + return; + } +} + +static void rtl8180_handle_rx(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + unsigned int count = 32; + u8 signal, agc, sq; + + while (count--) { + struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; + struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; + u32 flags = le32_to_cpu(entry->flags); + + if (flags & RTL818X_RX_DESC_FLAG_OWN) + return; + + if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | + RTL818X_RX_DESC_FLAG_FOF | + RTL818X_RX_DESC_FLAG_RX_ERR))) + goto done; + else { + u32 flags2 = le32_to_cpu(entry->flags2); + struct ieee80211_rx_status rx_status = {0}; + struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); + + if (unlikely(!new_skb)) + goto done; + + pci_unmap_single(priv->pdev, + *((dma_addr_t *)skb->cb), + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); + skb_put(skb, flags & 0xFFF); + + rx_status.antenna = (flags2 >> 15) & 1; + rx_status.rate_idx = (flags >> 20) & 0xF; + agc = (flags2 >> 17) & 0x7F; + if (priv->r8185) { + if (rx_status.rate_idx > 3) + signal = 90 - clamp_t(u8, agc, 25, 90); + else + signal = 95 - clamp_t(u8, agc, 30, 95); + } else { + sq = flags2 & 0xff; + signal = priv->rf->calc_rssi(agc, sq); + } + rx_status.signal = signal; + rx_status.freq = dev->conf.channel->center_freq; + rx_status.band = dev->conf.channel->band; + rx_status.mactime = le64_to_cpu(entry->tsft); + rx_status.flag |= RX_FLAG_TSFT; + if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(dev, skb); + + skb = new_skb; + priv->rx_buf[priv->rx_idx] = skb; + *((dma_addr_t *) skb->cb) = + pci_map_single(priv->pdev, skb_tail_pointer(skb), + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); + } + + done: + entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); + entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | + MAX_RX_SIZE); + if (priv->rx_idx == 31) + entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); + priv->rx_idx = (priv->rx_idx + 1) % 32; + } +} + +static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u32 flags = le32_to_cpu(entry->flags); + + if (flags & RTL818X_TX_DESC_FLAG_OWN) + return; + + ring->idx = (ring->idx + 1) % ring->entries; + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), + skb->len, PCI_DMA_TODEVICE); + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && + (flags & RTL818X_TX_DESC_FLAG_TX_OK)) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = (flags & 0xFF) + 1; + info->status.rates[1].idx = -1; + + ieee80211_tx_status_irqsafe(dev, skb); + if (ring->entries - skb_queue_len(&ring->queue) == 2) + ieee80211_wake_queue(dev, prio); + } +} + +static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) +{ + struct ieee80211_hw *dev = dev_id; + struct rtl8180_priv *priv = dev->priv; + u16 reg; + + spin_lock(&priv->lock); + reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); + if (unlikely(reg == 0xFFFF)) { + spin_unlock(&priv->lock); + return IRQ_HANDLED; + } + + rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); + + if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) + rtl8180_handle_tx(dev, 3); + + if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) + rtl8180_handle_tx(dev, 2); + + if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) + rtl8180_handle_tx(dev, 1); + + if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) + rtl8180_handle_tx(dev, 0); + + if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) + rtl8180_handle_rx(dev); + + spin_unlock(&priv->lock); + + return IRQ_HANDLED; +} + +static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring; + struct rtl8180_tx_desc *entry; + unsigned long flags; + unsigned int idx, prio; + dma_addr_t mapping; + u32 tx_flags; + u8 rc_flags; + u16 plcp_len = 0; + __le16 rts_duration = 0; + + prio = skb_get_queue_mapping(skb); + ring = &priv->tx_ring[prio]; + + mapping = pci_map_single(priv->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); + + tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | + RTL818X_TX_DESC_FLAG_LS | + (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | + skb->len; + + if (priv->r8185) + tx_flags |= RTL818X_TX_DESC_FLAG_DMA | + RTL818X_TX_DESC_FLAG_NO_ENC; + + rc_flags = info->control.rates[0].flags; + if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { + tx_flags |= RTL818X_TX_DESC_FLAG_RTS; + tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + tx_flags |= RTL818X_TX_DESC_FLAG_CTS; + tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + } + + if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) + rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, + info); + + if (!priv->r8185) { + unsigned int remainder; + + plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), + (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); + remainder = (16 * (skb->len + 4)) % + ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); + if (remainder <= 6) + plcp_len |= 1 << 15; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) + priv->seqno += 0x10; + hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(priv->seqno); + } + + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + entry = &ring->desc[idx]; + + entry->rts_duration = rts_duration; + entry->plcp_len = cpu_to_le16(plcp_len); + entry->tx_buf = cpu_to_le32(mapping); + entry->frame_len = cpu_to_le32(skb->len); + entry->flags2 = info->control.rates[1].idx >= 0 ? + ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; + entry->retry_limit = info->control.rates[0].count; + entry->flags = cpu_to_le32(tx_flags); + __skb_queue_tail(&ring->queue, skb); + if (ring->entries - skb_queue_len(&ring->queue) < 2) + ieee80211_stop_queue(dev, prio); + + spin_unlock_irqrestore(&priv->lock, flags); + + rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); + + return 0; +} + +void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) +{ + u8 reg; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); +} + +static int rtl8180_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg; + + rtl818x_iowrite8(priv, &priv->map->CMD, 0); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(10); + + /* reset */ + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + rtl818x_ioread8(priv, &priv->map->CMD); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= (1 << 1); + reg |= RTL818X_CMD_RESET; + rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(200); + + /* check success of reset */ + if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { + wiphy_err(dev->wiphy, "reset timeout!\n"); + return -ETIMEDOUT; + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(200); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { + /* For cardbus */ + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + reg |= 1 << 1; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + reg = rtl818x_ioread16(priv, &priv->map->FEMR); + reg |= (1 << 15) | (1 << 14) | (1 << 4); + rtl818x_iowrite16(priv, &priv->map->FEMR, reg); + } + + rtl818x_iowrite8(priv, &priv->map->MSR, 0); + + if (!priv->r8185) + rtl8180_set_anaparam(priv, priv->anaparam); + + rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); + rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); + rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); + rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); + rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); + + /* TODO: necessary? specs indicate not */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); + if (priv->r8185) { + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); + } + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */ + + /* TODO: turn off hw wep on rtl8180 */ + + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + + if (priv->r8185) { + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); + + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + + /* TODO: set ClkRun enable? necessary? */ + reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + } else { + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1); + rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); + + rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); + } + + priv->rf->init(dev); + if (priv->r8185) + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + return 0; +} + +static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_rx_desc *entry; + int i; + + priv->rx_ring = pci_alloc_consistent(priv->pdev, + sizeof(*priv->rx_ring) * 32, + &priv->rx_ring_dma); + + if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { + wiphy_err(dev->wiphy, "Cannot allocate RX ring\n"); + return -ENOMEM; + } + + memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32); + priv->rx_idx = 0; + + for (i = 0; i < 32; i++) { + struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); + dma_addr_t *mapping; + entry = &priv->rx_ring[i]; + if (!skb) + return 0; + + priv->rx_buf[i] = skb; + mapping = (dma_addr_t *)skb->cb; + *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); + entry->rx_buf = cpu_to_le32(*mapping); + entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | + MAX_RX_SIZE); + } + entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); + return 0; +} + +static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + for (i = 0; i < 32; i++) { + struct sk_buff *skb = priv->rx_buf[i]; + if (!skb) + continue; + + pci_unmap_single(priv->pdev, + *((dma_addr_t *)skb->cb), + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); + kfree_skb(skb); + } + + pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32, + priv->rx_ring, priv->rx_ring_dma); + priv->rx_ring = NULL; +} + +static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, + unsigned int prio, unsigned int entries) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_desc *ring; + dma_addr_t dma; + int i; + + ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); + if (!ring || (unsigned long)ring & 0xFF) { + wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n", + prio); + return -ENOMEM; + } + + memset(ring, 0, sizeof(*ring)*entries); + priv->tx_ring[prio].desc = ring; + priv->tx_ring[prio].dma = dma; + priv->tx_ring[prio].idx = 0; + priv->tx_ring[prio].entries = entries; + skb_queue_head_init(&priv->tx_ring[prio].queue); + + for (i = 0; i < entries; i++) + ring[i].next_tx_desc = + cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); + + return 0; +} + +static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; +} + +static int rtl8180_start(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int ret, i; + u32 reg; + + ret = rtl8180_init_rx_ring(dev); + if (ret) + return ret; + + for (i = 0; i < 4; i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) + goto err_free_rings; + + ret = rtl8180_init_hw(dev); + if (ret) + goto err_free_rings; + + rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); + rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); + rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); + rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); + rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); + + ret = request_irq(priv->pdev->irq, rtl8180_interrupt, + IRQF_SHARED, KBUILD_MODNAME, dev); + if (ret) { + wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); + goto err_free_rings; + } + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); + + reg = RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + (7 << 8 /* MAX RX DMA */) | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC; + + if (priv->r8185) + reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; + else { + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) + ? RTL818X_RX_CONF_CSDM1 : 0; + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) + ? RTL818X_RX_CONF_CSDM2 : 0; + } + + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + if (priv->r8185) { + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; + reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; + reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + /* disable early TX */ + rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f); + } + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg |= (6 << 21 /* MAX TX DMA */) | + RTL818X_TX_CONF_NO_ICV; + + if (priv->r8185) + reg &= ~RTL818X_TX_CONF_PROBE_DTS; + else + reg &= ~RTL818X_TX_CONF_HW_SEQNUM; + + /* different meaning, same value on both rtl8185 and rtl8180 */ + reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg |= RTL818X_CMD_RX_ENABLE; + reg |= RTL818X_CMD_TX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + return 0; + + err_free_rings: + rtl8180_free_rx_ring(dev); + for (i = 0; i < 4; i++) + if (priv->tx_ring[i].desc) + rtl8180_free_tx_ring(dev, i); + + return ret; +} + +static void rtl8180_stop(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u8 reg; + int i; + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= ~RTL818X_CMD_TX_ENABLE; + reg &= ~RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + priv->rf->stop(dev); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + free_irq(priv->pdev->irq, dev); + + rtl8180_free_rx_ring(dev); + for (i = 0; i < 4; i++) + rtl8180_free_tx_ring(dev, i); +} + +static u64 rtl8180_get_tsf(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + +static void rtl8180_beacon_work(struct work_struct *work) +{ + struct rtl8180_vif *vif_priv = + container_of(work, struct rtl8180_vif, beacon_work.work); + struct ieee80211_vif *vif = + container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); + struct ieee80211_hw *dev = vif_priv->dev; + struct ieee80211_mgmt *mgmt; + struct sk_buff *skb; + int err = 0; + + /* don't overflow the tx ring */ + if (ieee80211_queue_stopped(dev, 0)) + goto resched; + + /* grab a fresh beacon */ + skb = ieee80211_beacon_get(dev, vif); + if (!skb) + goto resched; + + /* + * update beacon timestamp w/ TSF value + * TODO: make hardware update beacon timestamp + */ + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev)); + + /* TODO: use actual beacon queue */ + skb_set_queue_mapping(skb, 0); + + err = rtl8180_tx(dev, skb); + WARN_ON(err); + +resched: + /* + * schedule next beacon + * TODO: use hardware support for beacon timing + */ + schedule_delayed_work(&vif_priv->beacon_work, + usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); +} + +static int rtl8180_add_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_vif *vif_priv; + + /* + * We only support one active interface at a time. + */ + if (priv->vif) + return -EBUSY; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + break; + default: + return -EOPNOTSUPP; + } + + priv->vif = vif; + + /* Initialize driver private area */ + vif_priv = (struct rtl8180_vif *)&vif->drv_priv; + vif_priv->dev = dev; + INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work); + vif_priv->enable_beacon = false; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], + le32_to_cpu(*(__le32 *)vif->addr)); + rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], + le16_to_cpu(*(__le16 *)(vif->addr + 4))); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + return 0; +} + +static void rtl8180_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8180_priv *priv = dev->priv; + priv->vif = NULL; +} + +static int rtl8180_config(struct ieee80211_hw *dev, u32 changed) +{ + struct rtl8180_priv *priv = dev->priv; + struct ieee80211_conf *conf = &dev->conf; + + priv->rf->set_chan(dev, conf); + + return 0; +} + +static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_vif *vif_priv; + int i; + u8 reg; + + vif_priv = (struct rtl8180_vif *)&vif->drv_priv; + + if (changed & BSS_CHANGED_BSSID) { + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->BSSID[i], + info->bssid[i]); + + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg = RTL818X_MSR_ADHOC; + else + reg = RTL818X_MSR_INFRA; + } else + reg = RTL818X_MSR_NO_LINK; + rtl818x_iowrite8(priv, &priv->map->MSR, reg); + } + + if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) + priv->rf->conf_erp(dev, info); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + vif_priv->enable_beacon = info->enable_beacon; + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { + cancel_delayed_work_sync(&vif_priv->beacon_work); + if (vif_priv->enable_beacon) + schedule_work(&vif_priv->beacon_work.work); + } +} + +static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, + struct netdev_hw_addr_list *mc_list) +{ + return netdev_hw_addr_list_count(mc_list); +} + +static void rtl8180_configure_filter(struct ieee80211_hw *dev, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct rtl8180_priv *priv = dev->priv; + + if (changed_flags & FIF_FCSFAIL) + priv->rx_conf ^= RTL818X_RX_CONF_FCS; + if (changed_flags & FIF_CONTROL) + priv->rx_conf ^= RTL818X_RX_CONF_CTRL; + if (changed_flags & FIF_OTHER_BSS) + priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; + if (*total_flags & FIF_ALLMULTI || multicast > 0) + priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; + else + priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; + + *total_flags = 0; + + if (priv->rx_conf & RTL818X_RX_CONF_FCS) + *total_flags |= FIF_FCSFAIL; + if (priv->rx_conf & RTL818X_RX_CONF_CTRL) + *total_flags |= FIF_CONTROL; + if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) + *total_flags |= FIF_OTHER_BSS; + if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) + *total_flags |= FIF_ALLMULTI; + + rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); +} + +static const struct ieee80211_ops rtl8180_ops = { + .tx = rtl8180_tx, + .start = rtl8180_start, + .stop = rtl8180_stop, + .add_interface = rtl8180_add_interface, + .remove_interface = rtl8180_remove_interface, + .config = rtl8180_config, + .bss_info_changed = rtl8180_bss_info_changed, + .prepare_multicast = rtl8180_prepare_multicast, + .configure_filter = rtl8180_configure_filter, + .get_tsf = rtl8180_get_tsf, +}; + +static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8180_priv *priv = dev->priv; + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8180_priv *priv = dev->priv; + u8 reg = 2 << 6; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); +} + +static int __devinit rtl8180_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct ieee80211_hw *dev; + struct rtl8180_priv *priv; + unsigned long mem_addr, mem_len; + unsigned int io_addr, io_len; + int err, i; + struct eeprom_93cx6 eeprom; + const char *chip_name, *rf_name = NULL; + u32 reg; + u16 eeprom_val; + u8 mac_addr[ETH_ALEN]; + + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n", + pci_name(pdev)); + return err; + } + + err = pci_request_regions(pdev, KBUILD_MODNAME); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n", + pci_name(pdev)); + return err; + } + + io_addr = pci_resource_start(pdev, 0); + io_len = pci_resource_len(pdev, 0); + mem_addr = pci_resource_start(pdev, 1); + mem_len = pci_resource_len(pdev, 1); + + if (mem_len < sizeof(struct rtl818x_csr) || + io_len < sizeof(struct rtl818x_csr)) { + printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n", + pci_name(pdev)); + err = -ENOMEM; + goto err_free_reg; + } + + if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) || + (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) { + printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n", + pci_name(pdev)); + goto err_free_reg; + } + + pci_set_master(pdev); + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops); + if (!dev) { + printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n", + pci_name(pdev)); + err = -ENOMEM; + goto err_free_reg; + } + + priv = dev->priv; + priv->pdev = pdev; + + dev->max_rates = 2; + SET_IEEE80211_DEV(dev, &pdev->dev); + pci_set_drvdata(pdev, dev); + + priv->map = pci_iomap(pdev, 1, mem_len); + if (!priv->map) + priv->map = pci_iomap(pdev, 0, io_len); + + if (!priv->map) { + printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n", + pci_name(pdev)); + goto err_free_dev; + } + + BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); + BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); + + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); + + priv->band.band = IEEE80211_BAND_2GHZ; + priv->band.channels = priv->channels; + priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); + priv->band.bitrates = priv->rates; + priv->band.n_bitrates = 4; + dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; + + dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_UNSPEC; + dev->vif_data_size = sizeof(struct rtl8180_vif); + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + dev->queues = 1; + dev->max_signal = 65; + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg &= RTL818X_TX_CONF_HWVER_MASK; + switch (reg) { + case RTL818X_TX_CONF_R8180_ABCD: + chip_name = "RTL8180"; + break; + case RTL818X_TX_CONF_R8180_F: + chip_name = "RTL8180vF"; + break; + case RTL818X_TX_CONF_R8185_ABC: + chip_name = "RTL8185"; + break; + case RTL818X_TX_CONF_R8185_D: + chip_name = "RTL8185vD"; + break; + default: + printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", + pci_name(pdev), reg >> 25); + goto err_iounmap; + } + + priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; + if (priv->r8185) { + priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); + pci_try_set_mwi(pdev); + } + + eeprom.data = dev; + eeprom.register_read = rtl8180_eeprom_register_read; + eeprom.register_write = rtl8180_eeprom_register_write; + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) + eeprom.width = PCI_EEPROM_WIDTH_93C66; + else + eeprom.width = PCI_EEPROM_WIDTH_93C46; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); + eeprom_val &= 0xFF; + switch (eeprom_val) { + case 1: rf_name = "Intersil"; + break; + case 2: rf_name = "RFMD"; + break; + case 3: priv->rf = &sa2400_rf_ops; + break; + case 4: priv->rf = &max2820_rf_ops; + break; + case 5: priv->rf = &grf5101_rf_ops; + break; + case 9: priv->rf = rtl8180_detect_rf(dev); + break; + case 10: + rf_name = "RTL8255"; + break; + default: + printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", + pci_name(pdev), eeprom_val); + goto err_iounmap; + } + + if (!priv->rf) { + printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n", + pci_name(pdev), rf_name); + goto err_iounmap; + } + + eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); + priv->csthreshold = eeprom_val >> 8; + if (!priv->r8185) { + __le32 anaparam; + eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); + priv->anaparam = le32_to_cpu(anaparam); + eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); + } + + eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3); + if (!is_valid_ether_addr(mac_addr)) { + printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" + " randomly generated MAC addr\n", pci_name(pdev)); + random_ether_addr(mac_addr); + } + SET_IEEE80211_PERM_ADDR(dev, mac_addr); + + /* CCK TX power */ + for (i = 0; i < 14; i += 2) { + u16 txpwr; + eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); + priv->channels[i].hw_value = txpwr & 0xFF; + priv->channels[i + 1].hw_value = txpwr >> 8; + } + + /* OFDM TX power */ + if (priv->r8185) { + for (i = 0; i < 14; i += 2) { + u16 txpwr; + eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); + priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; + priv->channels[i + 1].hw_value |= txpwr & 0xFF00; + } + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + spin_lock_init(&priv->lock); + + err = ieee80211_register_hw(dev); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot register device\n", + pci_name(pdev)); + goto err_iounmap; + } + + wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", + mac_addr, chip_name, priv->rf->name); + + return 0; + + err_iounmap: + iounmap(priv->map); + + err_free_dev: + pci_set_drvdata(pdev, NULL); + ieee80211_free_hw(dev); + + err_free_reg: + pci_release_regions(pdev); + pci_disable_device(pdev); + return err; +} + +static void __devexit rtl8180_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *dev = pci_get_drvdata(pdev); + struct rtl8180_priv *priv; + + if (!dev) + return; + + ieee80211_unregister_hw(dev); + + priv = dev->priv; + + pci_iounmap(pdev, priv->map); + pci_release_regions(pdev); + pci_disable_device(pdev); + ieee80211_free_hw(dev); +} + +#ifdef CONFIG_PM +static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return 0; +} + +static int rtl8180_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + return 0; +} + +#endif /* CONFIG_PM */ + +static struct pci_driver rtl8180_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8180_table, + .probe = rtl8180_probe, + .remove = __devexit_p(rtl8180_remove), +#ifdef CONFIG_PM + .suspend = rtl8180_suspend, + .resume = rtl8180_resume, +#endif /* CONFIG_PM */ +}; + +static int __init rtl8180_init(void) +{ + return pci_register_driver(&rtl8180_driver); +} + +static void __exit rtl8180_exit(void) +{ + pci_unregister_driver(&rtl8180_driver); +} + +module_init(rtl8180_init); +module_exit(rtl8180_exit); diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c new file mode 100644 index 000000000000..5ee7589dd546 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c @@ -0,0 +1,190 @@ + +/* + * Radio tuning for GCT GRF5101 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "rtl8180.h" +#include "grf5101.h" + +static const int grf5101_encode[] = { + 0x0, 0x8, 0x4, 0xC, + 0x2, 0xA, 0x6, 0xE, + 0x1, 0x9, 0x5, 0xD, + 0x3, 0xB, 0x7, 0xF +}; + +static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + phy_config = grf5101_encode[(data >> 8) & 0xF]; + phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4; + phy_config |= grf5101_encode[data & 0xF] << 8; + phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12; + phy_config |= (addr & 1) << 16; + phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24; + + /* MAC will bang bits to the chip */ + phy_config |= 0x90000000; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(3); +} + +static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant = GRF5101_ANTENNA; + + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); +} + +static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) +{ + if (agc > 60) + return 65; + + /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ + return 65 * agc / 60; +} + +static void grf5101_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; + u32 chan = channel - 1; + + /* set TX power */ + write_grf5101(dev, 0x15, 0x0); + write_grf5101(dev, 0x06, txpw); + write_grf5101(dev, 0x15, 0x10); + write_grf5101(dev, 0x15, 0x0); + + /* set frequency */ + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x0B, chan); + write_grf5101(dev, 0x07, 0x1000); + + grf5101_write_phy_antenna(dev, channel); +} + +static void grf5101_rf_stop(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u32 anaparam; + + anaparam = priv->anaparam; + anaparam &= 0x000fffff; + anaparam |= 0x3f900000; + rtl8180_set_anaparam(priv, anaparam); + + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x1f, 0x45); + write_grf5101(dev, 0x1f, 0x5); + write_grf5101(dev, 0x00, 0x8e4); +} + +static void grf5101_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + rtl8180_set_anaparam(priv, priv->anaparam); + + write_grf5101(dev, 0x1f, 0x0); + write_grf5101(dev, 0x1f, 0x0); + write_grf5101(dev, 0x1f, 0x40); + write_grf5101(dev, 0x1f, 0x60); + write_grf5101(dev, 0x1f, 0x61); + write_grf5101(dev, 0x1f, 0x61); + write_grf5101(dev, 0x00, 0xae4); + write_grf5101(dev, 0x1f, 0x1); + write_grf5101(dev, 0x1f, 0x41); + write_grf5101(dev, 0x1f, 0x61); + + write_grf5101(dev, 0x01, 0x1a23); + write_grf5101(dev, 0x02, 0x4971); + write_grf5101(dev, 0x03, 0x41de); + write_grf5101(dev, 0x04, 0x2d80); + write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */ + write_grf5101(dev, 0x06, 0x0); + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x08, 0x7533); + write_grf5101(dev, 0x09, 0xc401); + write_grf5101(dev, 0x0a, 0x0); + write_grf5101(dev, 0x0c, 0x1c7); + write_grf5101(dev, 0x0d, 0x29d3); + write_grf5101(dev, 0x0e, 0x2e8); + write_grf5101(dev, 0x10, 0x192); + write_grf5101(dev, 0x11, 0x248); + write_grf5101(dev, 0x12, 0x0); + write_grf5101(dev, 0x13, 0x20c4); + write_grf5101(dev, 0x14, 0xf4fc); + write_grf5101(dev, 0x15, 0x0); + write_grf5101(dev, 0x16, 0x1500); + + write_grf5101(dev, 0x07, 0x1000); + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0xa8); + rtl8180_write_phy(dev, 3, 0x0); + rtl8180_write_phy(dev, 4, 0xc0); + rtl8180_write_phy(dev, 5, 0x90); + rtl8180_write_phy(dev, 6, 0x1e); + rtl8180_write_phy(dev, 7, 0x64); + + grf5101_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x88); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */ + else + rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */ + + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); + + rtl8180_write_phy(dev, 0x19, 0x0); + rtl8180_write_phy(dev, 0x1a, 0xa0); + rtl8180_write_phy(dev, 0x1b, 0x44); +} + +const struct rtl818x_rf_ops grf5101_rf_ops = { + .name = "GCT", + .init = grf5101_rf_init, + .stop = grf5101_rf_stop, + .set_chan = grf5101_rf_set_channel, + .calc_rssi = grf5101_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.h b/drivers/net/wireless/rtl818x/rtl8180/grf5101.h new file mode 100644 index 000000000000..76647111bcff --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.h @@ -0,0 +1,28 @@ +#ifndef RTL8180_GRF5101_H +#define RTL8180_GRF5101_H + +/* + * Radio tuning for GCT GRF5101 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define GRF5101_ANTENNA 0xA3 + +extern const struct rtl818x_rf_ops grf5101_rf_ops; + +#endif /* RTL8180_GRF5101_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c new file mode 100644 index 000000000000..667b3363d437 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c @@ -0,0 +1,169 @@ +/* + * Radio tuning for Maxim max2820 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "rtl8180.h" +#include "max2820.h" + +static const u32 max2820_chan[] = { + 12, /* CH 1 */ + 17, + 22, + 27, + 32, + 37, + 42, + 47, + 52, + 57, + 62, + 67, + 72, + 84, /* CH 14 */ +}; + +static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + phy_config = 0x90 + (data & 0xf); + phy_config <<= 16; + phy_config += addr; + phy_config <<= 8; + phy_config += (data >> 4) & 0xff; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(1); +} + +static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant; + + ant = MAXIM_ANTENNA; + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); +} + +static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) +{ + bool odd; + + odd = !!(agc & 1); + + agc >>= 1; + if (odd) + agc += 76; + else + agc += 66; + + /* TODO: change addends above to avoid mult / div below */ + return 65 * agc / 100; +} + +static void max2820_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = conf ? + ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; + unsigned int chan_idx = channel - 1; + u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; + u32 chan = max2820_chan[chan_idx]; + + /* While philips SA2400 drive the PA bias from + * sa2400, for MAXIM we do this directly from BB */ + rtl8180_write_phy(dev, 3, txpw); + + max2820_write_phy_antenna(dev, channel); + write_max2820(dev, 3, chan); +} + +static void max2820_rf_stop(struct ieee80211_hw *dev) +{ + rtl8180_write_phy(dev, 3, 0x8); + write_max2820(dev, 1, 0); +} + + +static void max2820_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + /* MAXIM from netbsd driver */ + write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */ + write_max2820(dev, 1, 0x01e); /* enable register */ + write_max2820(dev, 2, 0x001); /* synt register */ + + max2820_rf_set_channel(dev, NULL); + + write_max2820(dev, 4, 0x313); /* rx register */ + + /* PA is driven directly by the BB, we keep the MAXIM bias + * at the highest value in case that setting it to lower + * values may introduce some further attenuation somewhere.. + */ + write_max2820(dev, 5, 0x00f); + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0x88); /* sys1 */ + rtl8180_write_phy(dev, 3, 0x08); /* txagc */ + rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */ + rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */ + rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */ + rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */ + + max2820_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x88); /* trl */ + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc7); + else + rtl8180_write_phy(dev, 0x12, 0x47); + + rtl8180_write_phy(dev, 0x13, 0x9b); + + rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */ + rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */ + + max2820_rf_set_channel(dev, NULL); +} + +const struct rtl818x_rf_ops max2820_rf_ops = { + .name = "Maxim", + .init = max2820_rf_init, + .stop = max2820_rf_stop, + .set_chan = max2820_rf_set_channel, + .calc_rssi = max2820_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.h b/drivers/net/wireless/rtl818x/rtl8180/max2820.h new file mode 100644 index 000000000000..61cf6d1e7d57 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.h @@ -0,0 +1,28 @@ +#ifndef RTL8180_MAX2820_H +#define RTL8180_MAX2820_H + +/* + * Radio tuning for Maxim max2820 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define MAXIM_ANTENNA 0xb3 + +extern const struct rtl818x_rf_ops max2820_rf_ops; + +#endif /* RTL8180_MAX2820_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h new file mode 100644 index 000000000000..30523314da43 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h @@ -0,0 +1,130 @@ +#ifndef RTL8180_H +#define RTL8180_H + +#include "rtl818x.h" + +#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD + +#define RF_PARAM_ANALOGPHY (1 << 0) +#define RF_PARAM_ANTBDEFAULT (1 << 1) +#define RF_PARAM_CARRIERSENSE1 (1 << 2) +#define RF_PARAM_CARRIERSENSE2 (1 << 3) + +#define BB_ANTATTEN_CHAN14 0x0C +#define BB_ANTENNA_B 0x40 + +#define BB_HOST_BANG (1 << 30) +#define BB_HOST_BANG_EN (1 << 2) +#define BB_HOST_BANG_CLK (1 << 1) +#define BB_HOST_BANG_DATA 1 + +#define ANAPARAM_TXDACOFF_SHIFT 27 +#define ANAPARAM_PWR0_SHIFT 28 +#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT) +#define ANAPARAM_PWR1_SHIFT 20 +#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) + +struct rtl8180_tx_desc { + __le32 flags; + __le16 rts_duration; + __le16 plcp_len; + __le32 tx_buf; + __le32 frame_len; + __le32 next_tx_desc; + u8 cw; + u8 retry_limit; + u8 agc; + u8 flags2; + u32 reserved[2]; +} __packed; + +struct rtl8180_rx_desc { + __le32 flags; + __le32 flags2; + union { + __le32 rx_buf; + __le64 tsft; + }; +} __packed; + +struct rtl8180_tx_ring { + struct rtl8180_tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; +}; + +struct rtl8180_vif { + struct ieee80211_hw *dev; + + /* beaconing */ + struct delayed_work beacon_work; + bool enable_beacon; +}; + +struct rtl8180_priv { + /* common between rtl818x drivers */ + struct rtl818x_csr __iomem *map; + const struct rtl818x_rf_ops *rf; + struct ieee80211_vif *vif; + + /* rtl8180 driver specific */ + spinlock_t lock; + struct rtl8180_rx_desc *rx_ring; + dma_addr_t rx_ring_dma; + unsigned int rx_idx; + struct sk_buff *rx_buf[32]; + struct rtl8180_tx_ring tx_ring[4]; + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_supported_band band; + struct pci_dev *pdev; + u32 rx_conf; + + int r8185; + u32 anaparam; + u16 rfparam; + u8 csthreshold; + + /* sequence # */ + u16 seqno; +}; + +void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); +void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); + +static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr) +{ + return ioread8(addr); +} + +static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr) +{ + return ioread16(addr); +} + +static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr) +{ + return ioread32(addr); +} + +static inline void rtl818x_iowrite8(struct rtl8180_priv *priv, + u8 __iomem *addr, u8 val) +{ + iowrite8(val, addr); +} + +static inline void rtl818x_iowrite16(struct rtl8180_priv *priv, + __le16 __iomem *addr, u16 val) +{ + iowrite16(val, addr); +} + +static inline void rtl818x_iowrite32(struct rtl8180_priv *priv, + __le32 __iomem *addr, u32 val) +{ + iowrite32(val, addr); +} + +#endif /* RTL8180_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c new file mode 100644 index 000000000000..7c4574ba9d75 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c @@ -0,0 +1,791 @@ + +/* + * Radio tuning for RTL8225 on RTL8180 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8180 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "rtl8180.h" +#include "rtl8225.h" + +static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg80, reg84, reg82; + u32 bangdata; + int i; + + bangdata = (data << 4) | (addr & 0xf); + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); + + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + for (i = 15; i >= 0; i--) { + u16 reg = reg80; + + if (bangdata & (1 << i)) + reg |= 1; + + if (i & 1) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + + if (!(i & 1)) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); +} + +static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg80, reg82, reg84, out; + int i; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400; + + reg80 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(4); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(5); + + for (i = 4; i >= 0; i--) { + u16 reg = reg80 | ((addr >> i) & 1); + + if (!(i & 1)) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + if (i & 1) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + } + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + out = 0; + for (i = 11; i >= 0; i--) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) + out |= 1 << i; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); + + return out; +} + +static const u16 rtl8225bcd_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb +}; + +static const u8 rtl8225_agc[] = { + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const u8 rtl8225_gain[] = { + 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */ + 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */ + 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */ + 0x33, 0x80, 0x79, 0xc5, /* -78dbm */ + 0x43, 0x78, 0x76, 0xc5, /* -74dbm */ + 0x53, 0x60, 0x73, 0xc5, /* -70dbm */ + 0x63, 0x58, 0x70, 0xc5, /* -66dbm */ +}; + +static const u8 rtl8225_threshold[] = { + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd +}; + +static const u8 rtl8225_tx_gain_cck_ofdm[] = { + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e +}; + +static const u8 rtl8225_tx_power_cck[] = { + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 +}; + +static const u8 rtl8225_tx_power_cck_ch14[] = { + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225_tx_power_ofdm[] = { + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 +}; + +static const u32 rtl8225_chan[] = { + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 +}; + +static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xFF; + ofdm_power = priv->channels[channel - 1].hw_value >> 8; + + cck_power = min(cck_power, (u8)35); + ofdm_power = min(ofdm_power, (u8)35); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); + + if (channel == 14) + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; + else + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + msleep(1); /* FIXME: optional? */ + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1); + + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; + + rtl8225_write_phy_ofdm(dev, 5, *tmp); + rtl8225_write_phy_ofdm(dev, 7, *tmp); + + msleep(1); +} + +static void rtl8225_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); + + /* host_pci_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(200); /* FIXME: ehh?? */ + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); + + /* TODO: check if we need really to change BRSR to do RF config */ + rtl818x_ioread16(priv, &priv->map->BRSR); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write(dev, 0x0, 0x067); + rtl8225_write(dev, 0x1, 0xFE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8BE); + rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */ + rtl8225_write(dev, 0x6, 0xAE6); + rtl8225_write(dev, 0x7, rtl8225_chan[0]); + rtl8225_write(dev, 0x8, 0x01F); + rtl8225_write(dev, 0x9, 0x334); + rtl8225_write(dev, 0xA, 0xFD4); + rtl8225_write(dev, 0xB, 0x391); + rtl8225_write(dev, 0xC, 0x050); + rtl8225_write(dev, 0xD, 0x6DB); + rtl8225_write(dev, 0xE, 0x029); + rtl8225_write(dev, 0xF, 0x914); msleep(1); + + rtl8225_write(dev, 0x2, 0xC4D); msleep(100); + + rtl8225_write(dev, 0x0, 0x127); + + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x027); + rtl8225_write(dev, 0x0, 0x22F); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1); + + rtl8225_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + rtl8225_write(dev, 0x0c, 0x50); + /* set OFDM initial gain */ + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]); + /* set CCK threshold */ + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]); +} + +static const u8 rtl8225z2_tx_power_cck_ch14[] = { + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225z2_tx_power_cck_B[] = { + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 +}; + +static const u8 rtl8225z2_tx_power_cck_A[] = { + 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 +}; + +static const u8 rtl8225z2_tx_power_cck[] = { + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 +}; + +static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xFF; + ofdm_power = priv->channels[channel - 1].hw_value >> 8; + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else if (cck_power == 12) + tmp = rtl8225z2_tx_power_cck_B; + else if (cck_power == 13) + tmp = rtl8225z2_tx_power_cck_A; + else + tmp = rtl8225z2_tx_power_cck; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + cck_power = min(cck_power, (u8)35); + if (cck_power == 13 || cck_power == 14) + cck_power = 12; + if (cck_power >= 15) + cck_power -= 2; + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power); + rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK); + msleep(1); + + ofdm_power = min(ofdm_power, (u8)35); + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power); + + rtl8225_write_phy_ofdm(dev, 2, 0x62); + rtl8225_write_phy_ofdm(dev, 5, 0x00); + rtl8225_write_phy_ofdm(dev, 6, 0x40); + rtl8225_write_phy_ofdm(dev, 7, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x40); + + msleep(1); +} + +static const u16 rtl8225z2_rxgain[] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009, + 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141, + 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183, + 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244, + 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288, + 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345, + 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389, + 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393, + 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb +}; + +static void rtl8225z2_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); + + /* host_pci_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(200); /* FIXME: ehh?? */ + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008); + + /* TODO: check if we need really to change BRSR to do RF config */ + rtl818x_ioread16(priv, &priv->map->BRSR); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + rtl8225_write(dev, 0x0, 0x0B7); msleep(1); + rtl8225_write(dev, 0x1, 0xEE0); msleep(1); + rtl8225_write(dev, 0x2, 0x44D); msleep(1); + rtl8225_write(dev, 0x3, 0x441); msleep(1); + rtl8225_write(dev, 0x4, 0x8C3); msleep(1); + rtl8225_write(dev, 0x5, 0xC72); msleep(1); + rtl8225_write(dev, 0x6, 0x0E6); msleep(1); + rtl8225_write(dev, 0x7, 0x82A); msleep(1); + rtl8225_write(dev, 0x8, 0x03F); msleep(1); + rtl8225_write(dev, 0x9, 0x335); msleep(1); + rtl8225_write(dev, 0xa, 0x9D4); msleep(1); + rtl8225_write(dev, 0xb, 0x7BB); msleep(1); + rtl8225_write(dev, 0xc, 0x850); msleep(1); + rtl8225_write(dev, 0xd, 0xCDF); msleep(1); + rtl8225_write(dev, 0xe, 0x02B); msleep(1); + rtl8225_write(dev, 0xf, 0x114); msleep(100); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0C4D); + msleep(200); + rtl8225_write(dev, 0x02, 0x044D); + msleep(100); + /* TODO: readd calibration failure message when the calibration + check works */ + } + + rtl8225_write(dev, 0x0, 0x1B7); + rtl8225_write(dev, 0x3, 0x002); + rtl8225_write(dev, 0x5, 0x004); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x0B7); msleep(100); + rtl8225_write(dev, 0x2, 0xC4D); + + msleep(200); + rtl8225_write(dev, 0x2, 0x44D); + msleep(100); + + rtl8225_write(dev, 0x00, 0x2BF); + rtl8225_write(dev, 0xFF, 0xFFFF); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */ + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1); + + rtl8225z2_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); +} + +static void rtl8225_rf_stop(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u8 reg; + + rtl8225_write(dev, 0x4, 0x1f); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); +} + +static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); + + if (priv->rf->init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, chan); + else + rtl8225z2_rf_set_tx_power(dev, chan); + + rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); + msleep(10); +} + +static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev, + struct ieee80211_bss_conf *info) +{ + struct rtl8180_priv *priv = dev->priv; + + if (info->use_short_slot) { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); + rtl818x_iowrite8(priv, &priv->map->EIFS, 81); + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); + } else { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); + rtl818x_iowrite8(priv, &priv->map->EIFS, 81); + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); + } +} + +static const struct rtl818x_rf_ops rtl8225_ops = { + .name = "rtl8225", + .init = rtl8225_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel, + .conf_erp = rtl8225_rf_conf_erp, +}; + +static const struct rtl818x_rf_ops rtl8225z2_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel, + .conf_erp = rtl8225_rf_conf_erp, +}; + +const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg8, reg9; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(100); + + rtl8225_write(dev, 0, 0x1B7); + + reg8 = rtl8225_read(dev, 8); + reg9 = rtl8225_read(dev, 9); + + rtl8225_write(dev, 0, 0x0B7); + + if (reg8 != 0x588 || reg9 != 0x700) + return &rtl8225_ops; + + return &rtl8225z2_ops; +} diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h new file mode 100644 index 000000000000..310013a2d726 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h @@ -0,0 +1,23 @@ +#ifndef RTL8180_RTL8225_H +#define RTL8180_RTL8225_H + +#define RTL8225_ANAPARAM_ON 0xa0000b59 +#define RTL8225_ANAPARAM2_ON 0x860dec11 +#define RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8225_ANAPARAM2_OFF 0x840dec11 + +const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *); + +static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data); +} + +static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data | 0x10000); +} + +#endif /* RTL8180_RTL8225_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c new file mode 100644 index 000000000000..44771a6286af --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c @@ -0,0 +1,228 @@ + +/* + * Radio tuning for Philips SA2400 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "rtl8180.h" +#include "sa2400.h" + +static const u32 sa2400_chan[] = { + 0x00096c, /* ch1 */ + 0x080970, + 0x100974, + 0x180978, + 0x000980, + 0x080984, + 0x100988, + 0x18098c, + 0x000994, + 0x080998, + 0x10099c, + 0x1809a0, + 0x0009a8, + 0x0009b4, /* ch 14 */ +}; + +static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */ + phy_config = 0xb0000000; + + phy_config |= ((u32)(addr & 0xf)) << 24; + phy_config |= data & 0xffffff; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(3); +} + +static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant = SA2400_ANTENNA; + + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); + +} + +static u8 sa2400_rf_rssi_map[] = { + 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, + 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, + 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, + 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, + 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, + 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, + 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, + 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, + 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, + 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, +}; + +static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) +{ + if (sq == 0x80) + return 1; + + if (sq > 78) + return 32; + + /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ + return 65 * sa2400_rf_rssi_map[sq] / 100; +} + +static void sa2400_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; + u32 chan = sa2400_chan[channel - 1]; + + write_sa2400(dev, 7, txpw); + + sa2400_write_phy_antenna(dev, channel); + + write_sa2400(dev, 0, chan); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); +} + +static void sa2400_rf_stop(struct ieee80211_hw *dev) +{ + write_sa2400(dev, 4, 0); +} + +static void sa2400_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u32 anaparam, txconf; + u8 firdac; + int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY; + + anaparam = priv->anaparam; + anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT); + anaparam &= ~ANAPARAM_PWR1_MASK; + anaparam &= ~ANAPARAM_PWR0_MASK; + + if (analogphy) { + anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT; + firdac = 0; + } else { + anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT); + anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT); + firdac = 1 << SA2400_REG4_FIRDAC_SHIFT; + } + + rtl8180_set_anaparam(priv, anaparam); + + write_sa2400(dev, 0, sa2400_chan[0]); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); + write_sa2400(dev, 4, 0x19340 | firdac); + write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15); + write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */ + + if (!analogphy) + write_sa2400(dev, 4, 0x1938c); /*???*/ + + write_sa2400(dev, 4, 0x19340 | firdac); + + write_sa2400(dev, 0, sa2400_chan[0]); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); + write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */ + + /* new from rtl8180 embedded driver (rtl8181 project) */ + write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */ + write_sa2400(dev, 8, 0); /* VCO */ + + if (analogphy) { + rtl8180_set_anaparam(priv, anaparam | + (1 << ANAPARAM_TXDACOFF_SHIFT)); + + txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + txconf | RTL818X_TX_CONF_LOOPBACK_CONT); + + write_sa2400(dev, 4, 0x19341); /* calibrates DC */ + + /* a 5us sleep is required here, + * we rely on the 3ms delay introduced in write_sa2400 */ + write_sa2400(dev, 4, 0x19345); + + /* a 20us sleep is required here, + * we rely on the 3ms delay introduced in write_sa2400 */ + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf); + + rtl8180_set_anaparam(priv, anaparam); + } + /* end new code */ + + write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */ + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0x98); + rtl8180_write_phy(dev, 3, 0x38); + rtl8180_write_phy(dev, 4, 0xe0); + rtl8180_write_phy(dev, 5, 0x90); + rtl8180_write_phy(dev, 6, 0x1a); + rtl8180_write_phy(dev, 7, 0x64); + + sa2400_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x80); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */ + else + rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */ + + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); + + rtl8180_write_phy(dev, 0x19, 0x0); + rtl8180_write_phy(dev, 0x1a, 0xa0); +} + +const struct rtl818x_rf_ops sa2400_rf_ops = { + .name = "Philips", + .init = sa2400_rf_init, + .stop = sa2400_rf_stop, + .set_chan = sa2400_rf_set_channel, + .calc_rssi = sa2400_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.h b/drivers/net/wireless/rtl818x/rtl8180/sa2400.h new file mode 100644 index 000000000000..a4aaa0d413f1 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.h @@ -0,0 +1,36 @@ +#ifndef RTL8180_SA2400_H +#define RTL8180_SA2400_H + +/* + * Radio tuning for Philips SA2400 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define SA2400_ANTENNA 0x91 +#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8 +#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28 +#define SA2400_ANAPARAM_PWR0_ON 0x3 + +/* RX sensitivity in dbm */ +#define SA2400_MAX_SENS 85 + +#define SA2400_REG4_FIRDAC_SHIFT 7 + +extern const struct rtl818x_rf_ops sa2400_rf_ops; + +#endif /* RTL8180_SA2400_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c deleted file mode 100644 index 707c688da618..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ /dev/null @@ -1,1188 +0,0 @@ - -/* - * Linux device driver for RTL8180 / RTL8185 - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Thanks to Realtek for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "rtl8180.h" -#include "rtl8180_rtl8225.h" -#include "rtl8180_sa2400.h" -#include "rtl8180_max2820.h" -#include "rtl8180_grf5101.h" - -MODULE_AUTHOR("Michael Wu "); -MODULE_AUTHOR("Andrea Merello "); -MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver"); -MODULE_LICENSE("GPL"); - -static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { - /* rtl8185 */ - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, - { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, - { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) }, - - /* rtl8180 */ - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) }, - { PCI_DEVICE(0x1799, 0x6001) }, - { PCI_DEVICE(0x1799, 0x6020) }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, - { } -}; - -MODULE_DEVICE_TABLE(pci, rtl8180_table); - -static const struct ieee80211_rate rtl818x_rates[] = { - { .bitrate = 10, .hw_value = 0, }, - { .bitrate = 20, .hw_value = 1, }, - { .bitrate = 55, .hw_value = 2, }, - { .bitrate = 110, .hw_value = 3, }, - { .bitrate = 60, .hw_value = 4, }, - { .bitrate = 90, .hw_value = 5, }, - { .bitrate = 120, .hw_value = 6, }, - { .bitrate = 180, .hw_value = 7, }, - { .bitrate = 240, .hw_value = 8, }, - { .bitrate = 360, .hw_value = 9, }, - { .bitrate = 480, .hw_value = 10, }, - { .bitrate = 540, .hw_value = 11, }, -}; - -static const struct ieee80211_channel rtl818x_channels[] = { - { .center_freq = 2412 }, - { .center_freq = 2417 }, - { .center_freq = 2422 }, - { .center_freq = 2427 }, - { .center_freq = 2432 }, - { .center_freq = 2437 }, - { .center_freq = 2442 }, - { .center_freq = 2447 }, - { .center_freq = 2452 }, - { .center_freq = 2457 }, - { .center_freq = 2462 }, - { .center_freq = 2467 }, - { .center_freq = 2472 }, - { .center_freq = 2484 }, -}; - - -void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) -{ - struct rtl8180_priv *priv = dev->priv; - int i = 10; - u32 buf; - - buf = (data << 8) | addr; - - rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80); - while (i--) { - rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf); - if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF)) - return; - } -} - -static void rtl8180_handle_rx(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - unsigned int count = 32; - u8 signal, agc, sq; - - while (count--) { - struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; - struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; - u32 flags = le32_to_cpu(entry->flags); - - if (flags & RTL818X_RX_DESC_FLAG_OWN) - return; - - if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | - RTL818X_RX_DESC_FLAG_FOF | - RTL818X_RX_DESC_FLAG_RX_ERR))) - goto done; - else { - u32 flags2 = le32_to_cpu(entry->flags2); - struct ieee80211_rx_status rx_status = {0}; - struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); - - if (unlikely(!new_skb)) - goto done; - - pci_unmap_single(priv->pdev, - *((dma_addr_t *)skb->cb), - MAX_RX_SIZE, PCI_DMA_FROMDEVICE); - skb_put(skb, flags & 0xFFF); - - rx_status.antenna = (flags2 >> 15) & 1; - rx_status.rate_idx = (flags >> 20) & 0xF; - agc = (flags2 >> 17) & 0x7F; - if (priv->r8185) { - if (rx_status.rate_idx > 3) - signal = 90 - clamp_t(u8, agc, 25, 90); - else - signal = 95 - clamp_t(u8, agc, 30, 95); - } else { - sq = flags2 & 0xff; - signal = priv->rf->calc_rssi(agc, sq); - } - rx_status.signal = signal; - rx_status.freq = dev->conf.channel->center_freq; - rx_status.band = dev->conf.channel->band; - rx_status.mactime = le64_to_cpu(entry->tsft); - rx_status.flag |= RX_FLAG_TSFT; - if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; - - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(dev, skb); - - skb = new_skb; - priv->rx_buf[priv->rx_idx] = skb; - *((dma_addr_t *) skb->cb) = - pci_map_single(priv->pdev, skb_tail_pointer(skb), - MAX_RX_SIZE, PCI_DMA_FROMDEVICE); - } - - done: - entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); - entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | - MAX_RX_SIZE); - if (priv->rx_idx == 31) - entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); - priv->rx_idx = (priv->rx_idx + 1) % 32; - } -} - -static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - u32 flags = le32_to_cpu(entry->flags); - - if (flags & RTL818X_TX_DESC_FLAG_OWN) - return; - - ring->idx = (ring->idx + 1) % ring->entries; - skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), - skb->len, PCI_DMA_TODEVICE); - - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (flags & RTL818X_TX_DESC_FLAG_TX_OK)) - info->flags |= IEEE80211_TX_STAT_ACK; - - info->status.rates[0].count = (flags & 0xFF) + 1; - info->status.rates[1].idx = -1; - - ieee80211_tx_status_irqsafe(dev, skb); - if (ring->entries - skb_queue_len(&ring->queue) == 2) - ieee80211_wake_queue(dev, prio); - } -} - -static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) -{ - struct ieee80211_hw *dev = dev_id; - struct rtl8180_priv *priv = dev->priv; - u16 reg; - - spin_lock(&priv->lock); - reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); - if (unlikely(reg == 0xFFFF)) { - spin_unlock(&priv->lock); - return IRQ_HANDLED; - } - - rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); - - if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) - rtl8180_handle_tx(dev, 3); - - if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) - rtl8180_handle_tx(dev, 2); - - if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) - rtl8180_handle_tx(dev, 1); - - if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) - rtl8180_handle_tx(dev, 0); - - if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) - rtl8180_handle_rx(dev); - - spin_unlock(&priv->lock); - - return IRQ_HANDLED; -} - -static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_ring *ring; - struct rtl8180_tx_desc *entry; - unsigned long flags; - unsigned int idx, prio; - dma_addr_t mapping; - u32 tx_flags; - u8 rc_flags; - u16 plcp_len = 0; - __le16 rts_duration = 0; - - prio = skb_get_queue_mapping(skb); - ring = &priv->tx_ring[prio]; - - mapping = pci_map_single(priv->pdev, skb->data, - skb->len, PCI_DMA_TODEVICE); - - tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | - RTL818X_TX_DESC_FLAG_LS | - (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | - skb->len; - - if (priv->r8185) - tx_flags |= RTL818X_TX_DESC_FLAG_DMA | - RTL818X_TX_DESC_FLAG_NO_ENC; - - rc_flags = info->control.rates[0].flags; - if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { - tx_flags |= RTL818X_TX_DESC_FLAG_RTS; - tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; - } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - tx_flags |= RTL818X_TX_DESC_FLAG_CTS; - tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; - } - - if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) - rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, - info); - - if (!priv->r8185) { - unsigned int remainder; - - plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), - (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); - remainder = (16 * (skb->len + 4)) % - ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); - if (remainder <= 6) - plcp_len |= 1 << 15; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) - priv->seqno += 0x10; - hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(priv->seqno); - } - - idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; - entry = &ring->desc[idx]; - - entry->rts_duration = rts_duration; - entry->plcp_len = cpu_to_le16(plcp_len); - entry->tx_buf = cpu_to_le32(mapping); - entry->frame_len = cpu_to_le32(skb->len); - entry->flags2 = info->control.rates[1].idx >= 0 ? - ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; - entry->retry_limit = info->control.rates[0].count; - entry->flags = cpu_to_le32(tx_flags); - __skb_queue_tail(&ring->queue, skb); - if (ring->entries - skb_queue_len(&ring->queue) < 2) - ieee80211_stop_queue(dev, prio); - - spin_unlock_irqrestore(&priv->lock, flags); - - rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); - - return 0; -} - -void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) -{ - u8 reg; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); -} - -static int rtl8180_init_hw(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u16 reg; - - rtl818x_iowrite8(priv, &priv->map->CMD, 0); - rtl818x_ioread8(priv, &priv->map->CMD); - msleep(10); - - /* reset */ - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); - rtl818x_ioread8(priv, &priv->map->CMD); - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg &= (1 << 1); - reg |= RTL818X_CMD_RESET; - rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET); - rtl818x_ioread8(priv, &priv->map->CMD); - msleep(200); - - /* check success of reset */ - if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { - wiphy_err(dev->wiphy, "reset timeout!\n"); - return -ETIMEDOUT; - } - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); - rtl818x_ioread8(priv, &priv->map->CMD); - msleep(200); - - if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { - /* For cardbus */ - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg |= 1 << 1; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - reg = rtl818x_ioread16(priv, &priv->map->FEMR); - reg |= (1 << 15) | (1 << 14) | (1 << 4); - rtl818x_iowrite16(priv, &priv->map->FEMR, reg); - } - - rtl818x_iowrite8(priv, &priv->map->MSR, 0); - - if (!priv->r8185) - rtl8180_set_anaparam(priv, priv->anaparam); - - rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); - rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); - rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); - rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); - rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); - - /* TODO: necessary? specs indicate not */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); - rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); - if (priv->r8185) { - reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); - rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); - } - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */ - - /* TODO: turn off hw wep on rtl8180 */ - - rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); - - if (priv->r8185) { - rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); - rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); - rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); - - rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); - - /* TODO: set ClkRun enable? necessary? */ - reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - } else { - rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1); - rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); - - rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); - rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); - } - - priv->rf->init(dev); - if (priv->r8185) - rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); - return 0; -} - -static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_rx_desc *entry; - int i; - - priv->rx_ring = pci_alloc_consistent(priv->pdev, - sizeof(*priv->rx_ring) * 32, - &priv->rx_ring_dma); - - if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { - wiphy_err(dev->wiphy, "Cannot allocate RX ring\n"); - return -ENOMEM; - } - - memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32); - priv->rx_idx = 0; - - for (i = 0; i < 32; i++) { - struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); - dma_addr_t *mapping; - entry = &priv->rx_ring[i]; - if (!skb) - return 0; - - priv->rx_buf[i] = skb; - mapping = (dma_addr_t *)skb->cb; - *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), - MAX_RX_SIZE, PCI_DMA_FROMDEVICE); - entry->rx_buf = cpu_to_le32(*mapping); - entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | - MAX_RX_SIZE); - } - entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); - return 0; -} - -static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - int i; - - for (i = 0; i < 32; i++) { - struct sk_buff *skb = priv->rx_buf[i]; - if (!skb) - continue; - - pci_unmap_single(priv->pdev, - *((dma_addr_t *)skb->cb), - MAX_RX_SIZE, PCI_DMA_FROMDEVICE); - kfree_skb(skb); - } - - pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32, - priv->rx_ring, priv->rx_ring_dma); - priv->rx_ring = NULL; -} - -static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, - unsigned int prio, unsigned int entries) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_desc *ring; - dma_addr_t dma; - int i; - - ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); - if (!ring || (unsigned long)ring & 0xFF) { - wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n", - prio); - return -ENOMEM; - } - - memset(ring, 0, sizeof(*ring)*entries); - priv->tx_ring[prio].desc = ring; - priv->tx_ring[prio].dma = dma; - priv->tx_ring[prio].idx = 0; - priv->tx_ring[prio].entries = entries; - skb_queue_head_init(&priv->tx_ring[prio].queue); - - for (i = 0; i < entries; i++) - ring[i].next_tx_desc = - cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); - - return 0; -} - -static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb = __skb_dequeue(&ring->queue); - - pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), - skb->len, PCI_DMA_TODEVICE); - kfree_skb(skb); - ring->idx = (ring->idx + 1) % ring->entries; - } - - pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, - ring->desc, ring->dma); - ring->desc = NULL; -} - -static int rtl8180_start(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - int ret, i; - u32 reg; - - ret = rtl8180_init_rx_ring(dev); - if (ret) - return ret; - - for (i = 0; i < 4; i++) - if ((ret = rtl8180_init_tx_ring(dev, i, 16))) - goto err_free_rings; - - ret = rtl8180_init_hw(dev); - if (ret) - goto err_free_rings; - - rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); - rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); - rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); - rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); - rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); - - ret = request_irq(priv->pdev->irq, rtl8180_interrupt, - IRQF_SHARED, KBUILD_MODNAME, dev); - if (ret) { - wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); - goto err_free_rings; - } - - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); - - rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); - rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); - - reg = RTL818X_RX_CONF_ONLYERLPKT | - RTL818X_RX_CONF_RX_AUTORESETPHY | - RTL818X_RX_CONF_MGMT | - RTL818X_RX_CONF_DATA | - (7 << 8 /* MAX RX DMA */) | - RTL818X_RX_CONF_BROADCAST | - RTL818X_RX_CONF_NICMAC; - - if (priv->r8185) - reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; - else { - reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) - ? RTL818X_RX_CONF_CSDM1 : 0; - reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) - ? RTL818X_RX_CONF_CSDM2 : 0; - } - - priv->rx_conf = reg; - rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); - - if (priv->r8185) { - reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); - reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; - reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; - rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; - reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; - rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); - - /* disable early TX */ - rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f); - } - - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); - reg |= (6 << 21 /* MAX TX DMA */) | - RTL818X_TX_CONF_NO_ICV; - - if (priv->r8185) - reg &= ~RTL818X_TX_CONF_PROBE_DTS; - else - reg &= ~RTL818X_TX_CONF_HW_SEQNUM; - - /* different meaning, same value on both rtl8185 and rtl8180 */ - reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; - - rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg |= RTL818X_CMD_RX_ENABLE; - reg |= RTL818X_CMD_TX_ENABLE; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - - return 0; - - err_free_rings: - rtl8180_free_rx_ring(dev); - for (i = 0; i < 4; i++) - if (priv->tx_ring[i].desc) - rtl8180_free_tx_ring(dev, i); - - return ret; -} - -static void rtl8180_stop(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u8 reg; - int i; - - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg &= ~RTL818X_CMD_TX_ENABLE; - reg &= ~RTL818X_CMD_RX_ENABLE; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - - priv->rf->stop(dev); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); - rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - free_irq(priv->pdev->irq, dev); - - rtl8180_free_rx_ring(dev); - for (i = 0; i < 4; i++) - rtl8180_free_tx_ring(dev, i); -} - -static u64 rtl8180_get_tsf(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - - return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | - (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; -} - -static void rtl8180_beacon_work(struct work_struct *work) -{ - struct rtl8180_vif *vif_priv = - container_of(work, struct rtl8180_vif, beacon_work.work); - struct ieee80211_vif *vif = - container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); - struct ieee80211_hw *dev = vif_priv->dev; - struct ieee80211_mgmt *mgmt; - struct sk_buff *skb; - int err = 0; - - /* don't overflow the tx ring */ - if (ieee80211_queue_stopped(dev, 0)) - goto resched; - - /* grab a fresh beacon */ - skb = ieee80211_beacon_get(dev, vif); - if (!skb) - goto resched; - - /* - * update beacon timestamp w/ TSF value - * TODO: make hardware update beacon timestamp - */ - mgmt = (struct ieee80211_mgmt *)skb->data; - mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev)); - - /* TODO: use actual beacon queue */ - skb_set_queue_mapping(skb, 0); - - err = rtl8180_tx(dev, skb); - WARN_ON(err); - -resched: - /* - * schedule next beacon - * TODO: use hardware support for beacon timing - */ - schedule_delayed_work(&vif_priv->beacon_work, - usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); -} - -static int rtl8180_add_interface(struct ieee80211_hw *dev, - struct ieee80211_vif *vif) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_vif *vif_priv; - - /* - * We only support one active interface at a time. - */ - if (priv->vif) - return -EBUSY; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - break; - default: - return -EOPNOTSUPP; - } - - priv->vif = vif; - - /* Initialize driver private area */ - vif_priv = (struct rtl8180_vif *)&vif->drv_priv; - vif_priv->dev = dev; - INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work); - vif_priv->enable_beacon = false; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], - le32_to_cpu(*(__le32 *)vif->addr)); - rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], - le16_to_cpu(*(__le16 *)(vif->addr + 4))); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - return 0; -} - -static void rtl8180_remove_interface(struct ieee80211_hw *dev, - struct ieee80211_vif *vif) -{ - struct rtl8180_priv *priv = dev->priv; - priv->vif = NULL; -} - -static int rtl8180_config(struct ieee80211_hw *dev, u32 changed) -{ - struct rtl8180_priv *priv = dev->priv; - struct ieee80211_conf *conf = &dev->conf; - - priv->rf->set_chan(dev, conf); - - return 0; -} - -static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u32 changed) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_vif *vif_priv; - int i; - u8 reg; - - vif_priv = (struct rtl8180_vif *)&vif->drv_priv; - - if (changed & BSS_CHANGED_BSSID) { - for (i = 0; i < ETH_ALEN; i++) - rtl818x_iowrite8(priv, &priv->map->BSSID[i], - info->bssid[i]); - - if (is_valid_ether_addr(info->bssid)) { - if (vif->type == NL80211_IFTYPE_ADHOC) - reg = RTL818X_MSR_ADHOC; - else - reg = RTL818X_MSR_INFRA; - } else - reg = RTL818X_MSR_NO_LINK; - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - } - - if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) - priv->rf->conf_erp(dev, info); - - if (changed & BSS_CHANGED_BEACON_ENABLED) - vif_priv->enable_beacon = info->enable_beacon; - - if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { - cancel_delayed_work_sync(&vif_priv->beacon_work); - if (vif_priv->enable_beacon) - schedule_work(&vif_priv->beacon_work.work); - } -} - -static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, - struct netdev_hw_addr_list *mc_list) -{ - return netdev_hw_addr_list_count(mc_list); -} - -static void rtl8180_configure_filter(struct ieee80211_hw *dev, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) -{ - struct rtl8180_priv *priv = dev->priv; - - if (changed_flags & FIF_FCSFAIL) - priv->rx_conf ^= RTL818X_RX_CONF_FCS; - if (changed_flags & FIF_CONTROL) - priv->rx_conf ^= RTL818X_RX_CONF_CTRL; - if (changed_flags & FIF_OTHER_BSS) - priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; - if (*total_flags & FIF_ALLMULTI || multicast > 0) - priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; - else - priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; - - *total_flags = 0; - - if (priv->rx_conf & RTL818X_RX_CONF_FCS) - *total_flags |= FIF_FCSFAIL; - if (priv->rx_conf & RTL818X_RX_CONF_CTRL) - *total_flags |= FIF_CONTROL; - if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) - *total_flags |= FIF_OTHER_BSS; - if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) - *total_flags |= FIF_ALLMULTI; - - rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); -} - -static const struct ieee80211_ops rtl8180_ops = { - .tx = rtl8180_tx, - .start = rtl8180_start, - .stop = rtl8180_stop, - .add_interface = rtl8180_add_interface, - .remove_interface = rtl8180_remove_interface, - .config = rtl8180_config, - .bss_info_changed = rtl8180_bss_info_changed, - .prepare_multicast = rtl8180_prepare_multicast, - .configure_filter = rtl8180_configure_filter, - .get_tsf = rtl8180_get_tsf, -}; - -static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) -{ - struct ieee80211_hw *dev = eeprom->data; - struct rtl8180_priv *priv = dev->priv; - u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - - eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; - eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; - eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; - eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; -} - -static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) -{ - struct ieee80211_hw *dev = eeprom->data; - struct rtl8180_priv *priv = dev->priv; - u8 reg = 2 << 6; - - if (eeprom->reg_data_in) - reg |= RTL818X_EEPROM_CMD_WRITE; - if (eeprom->reg_data_out) - reg |= RTL818X_EEPROM_CMD_READ; - if (eeprom->reg_data_clock) - reg |= RTL818X_EEPROM_CMD_CK; - if (eeprom->reg_chip_select) - reg |= RTL818X_EEPROM_CMD_CS; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(10); -} - -static int __devinit rtl8180_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct ieee80211_hw *dev; - struct rtl8180_priv *priv; - unsigned long mem_addr, mem_len; - unsigned int io_addr, io_len; - int err, i; - struct eeprom_93cx6 eeprom; - const char *chip_name, *rf_name = NULL; - u32 reg; - u16 eeprom_val; - u8 mac_addr[ETH_ALEN]; - - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n", - pci_name(pdev)); - return err; - } - - err = pci_request_regions(pdev, KBUILD_MODNAME); - if (err) { - printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n", - pci_name(pdev)); - return err; - } - - io_addr = pci_resource_start(pdev, 0); - io_len = pci_resource_len(pdev, 0); - mem_addr = pci_resource_start(pdev, 1); - mem_len = pci_resource_len(pdev, 1); - - if (mem_len < sizeof(struct rtl818x_csr) || - io_len < sizeof(struct rtl818x_csr)) { - printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n", - pci_name(pdev)); - err = -ENOMEM; - goto err_free_reg; - } - - if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) || - (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) { - printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n", - pci_name(pdev)); - goto err_free_reg; - } - - pci_set_master(pdev); - - dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops); - if (!dev) { - printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n", - pci_name(pdev)); - err = -ENOMEM; - goto err_free_reg; - } - - priv = dev->priv; - priv->pdev = pdev; - - dev->max_rates = 2; - SET_IEEE80211_DEV(dev, &pdev->dev); - pci_set_drvdata(pdev, dev); - - priv->map = pci_iomap(pdev, 1, mem_len); - if (!priv->map) - priv->map = pci_iomap(pdev, 0, io_len); - - if (!priv->map) { - printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n", - pci_name(pdev)); - goto err_free_dev; - } - - BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); - BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); - - memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); - memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); - - priv->band.band = IEEE80211_BAND_2GHZ; - priv->band.channels = priv->channels; - priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); - priv->band.bitrates = priv->rates; - priv->band.n_bitrates = 4; - dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; - - dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_SIGNAL_UNSPEC; - dev->vif_data_size = sizeof(struct rtl8180_vif); - dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); - dev->queues = 1; - dev->max_signal = 65; - - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); - reg &= RTL818X_TX_CONF_HWVER_MASK; - switch (reg) { - case RTL818X_TX_CONF_R8180_ABCD: - chip_name = "RTL8180"; - break; - case RTL818X_TX_CONF_R8180_F: - chip_name = "RTL8180vF"; - break; - case RTL818X_TX_CONF_R8185_ABC: - chip_name = "RTL8185"; - break; - case RTL818X_TX_CONF_R8185_D: - chip_name = "RTL8185vD"; - break; - default: - printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", - pci_name(pdev), reg >> 25); - goto err_iounmap; - } - - priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; - if (priv->r8185) { - priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); - pci_try_set_mwi(pdev); - } - - eeprom.data = dev; - eeprom.register_read = rtl8180_eeprom_register_read; - eeprom.register_write = rtl8180_eeprom_register_write; - if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) - eeprom.width = PCI_EEPROM_WIDTH_93C66; - else - eeprom.width = PCI_EEPROM_WIDTH_93C46; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(10); - - eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); - eeprom_val &= 0xFF; - switch (eeprom_val) { - case 1: rf_name = "Intersil"; - break; - case 2: rf_name = "RFMD"; - break; - case 3: priv->rf = &sa2400_rf_ops; - break; - case 4: priv->rf = &max2820_rf_ops; - break; - case 5: priv->rf = &grf5101_rf_ops; - break; - case 9: priv->rf = rtl8180_detect_rf(dev); - break; - case 10: - rf_name = "RTL8255"; - break; - default: - printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", - pci_name(pdev), eeprom_val); - goto err_iounmap; - } - - if (!priv->rf) { - printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n", - pci_name(pdev), rf_name); - goto err_iounmap; - } - - eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); - priv->csthreshold = eeprom_val >> 8; - if (!priv->r8185) { - __le32 anaparam; - eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); - priv->anaparam = le32_to_cpu(anaparam); - eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); - } - - eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3); - if (!is_valid_ether_addr(mac_addr)) { - printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" - " randomly generated MAC addr\n", pci_name(pdev)); - random_ether_addr(mac_addr); - } - SET_IEEE80211_PERM_ADDR(dev, mac_addr); - - /* CCK TX power */ - for (i = 0; i < 14; i += 2) { - u16 txpwr; - eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); - priv->channels[i].hw_value = txpwr & 0xFF; - priv->channels[i + 1].hw_value = txpwr >> 8; - } - - /* OFDM TX power */ - if (priv->r8185) { - for (i = 0; i < 14; i += 2) { - u16 txpwr; - eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); - priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; - priv->channels[i + 1].hw_value |= txpwr & 0xFF00; - } - } - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - spin_lock_init(&priv->lock); - - err = ieee80211_register_hw(dev); - if (err) { - printk(KERN_ERR "%s (rtl8180): Cannot register device\n", - pci_name(pdev)); - goto err_iounmap; - } - - wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", - mac_addr, chip_name, priv->rf->name); - - return 0; - - err_iounmap: - iounmap(priv->map); - - err_free_dev: - pci_set_drvdata(pdev, NULL); - ieee80211_free_hw(dev); - - err_free_reg: - pci_release_regions(pdev); - pci_disable_device(pdev); - return err; -} - -static void __devexit rtl8180_remove(struct pci_dev *pdev) -{ - struct ieee80211_hw *dev = pci_get_drvdata(pdev); - struct rtl8180_priv *priv; - - if (!dev) - return; - - ieee80211_unregister_hw(dev); - - priv = dev->priv; - - pci_iounmap(pdev, priv->map); - pci_release_regions(pdev); - pci_disable_device(pdev); - ieee80211_free_hw(dev); -} - -#ifdef CONFIG_PM -static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state) -{ - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int rtl8180_resume(struct pci_dev *pdev) -{ - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - return 0; -} - -#endif /* CONFIG_PM */ - -static struct pci_driver rtl8180_driver = { - .name = KBUILD_MODNAME, - .id_table = rtl8180_table, - .probe = rtl8180_probe, - .remove = __devexit_p(rtl8180_remove), -#ifdef CONFIG_PM - .suspend = rtl8180_suspend, - .resume = rtl8180_resume, -#endif /* CONFIG_PM */ -}; - -static int __init rtl8180_init(void) -{ - return pci_register_driver(&rtl8180_driver); -} - -static void __exit rtl8180_exit(void) -{ - pci_unregister_driver(&rtl8180_driver); -} - -module_init(rtl8180_init); -module_exit(rtl8180_exit); diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c deleted file mode 100644 index 5cab9dfa8c07..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c +++ /dev/null @@ -1,190 +0,0 @@ - -/* - * Radio tuning for GCT GRF5101 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include "rtl8180.h" -#include "rtl8180_grf5101.h" - -static const int grf5101_encode[] = { - 0x0, 0x8, 0x4, 0xC, - 0x2, 0xA, 0x6, 0xE, - 0x1, 0x9, 0x5, 0xD, - 0x3, 0xB, 0x7, 0xF -}; - -static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data) -{ - struct rtl8180_priv *priv = dev->priv; - u32 phy_config; - - phy_config = grf5101_encode[(data >> 8) & 0xF]; - phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4; - phy_config |= grf5101_encode[data & 0xF] << 8; - phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12; - phy_config |= (addr & 1) << 16; - phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24; - - /* MAC will bang bits to the chip */ - phy_config |= 0x90000000; - - rtl818x_iowrite32(priv, - (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); - - msleep(3); -} - -static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) -{ - struct rtl8180_priv *priv = dev->priv; - u8 ant = GRF5101_ANTENNA; - - if (priv->rfparam & RF_PARAM_ANTBDEFAULT) - ant |= BB_ANTENNA_B; - - if (chan == 14) - ant |= BB_ANTATTEN_CHAN14; - - rtl8180_write_phy(dev, 0x10, ant); -} - -static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) -{ - if (agc > 60) - return 65; - - /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ - return 65 * agc / 60; -} - -static void grf5101_rf_set_channel(struct ieee80211_hw *dev, - struct ieee80211_conf *conf) -{ - struct rtl8180_priv *priv = dev->priv; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; - u32 chan = channel - 1; - - /* set TX power */ - write_grf5101(dev, 0x15, 0x0); - write_grf5101(dev, 0x06, txpw); - write_grf5101(dev, 0x15, 0x10); - write_grf5101(dev, 0x15, 0x0); - - /* set frequency */ - write_grf5101(dev, 0x07, 0x0); - write_grf5101(dev, 0x0B, chan); - write_grf5101(dev, 0x07, 0x1000); - - grf5101_write_phy_antenna(dev, channel); -} - -static void grf5101_rf_stop(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u32 anaparam; - - anaparam = priv->anaparam; - anaparam &= 0x000fffff; - anaparam |= 0x3f900000; - rtl8180_set_anaparam(priv, anaparam); - - write_grf5101(dev, 0x07, 0x0); - write_grf5101(dev, 0x1f, 0x45); - write_grf5101(dev, 0x1f, 0x5); - write_grf5101(dev, 0x00, 0x8e4); -} - -static void grf5101_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - - rtl8180_set_anaparam(priv, priv->anaparam); - - write_grf5101(dev, 0x1f, 0x0); - write_grf5101(dev, 0x1f, 0x0); - write_grf5101(dev, 0x1f, 0x40); - write_grf5101(dev, 0x1f, 0x60); - write_grf5101(dev, 0x1f, 0x61); - write_grf5101(dev, 0x1f, 0x61); - write_grf5101(dev, 0x00, 0xae4); - write_grf5101(dev, 0x1f, 0x1); - write_grf5101(dev, 0x1f, 0x41); - write_grf5101(dev, 0x1f, 0x61); - - write_grf5101(dev, 0x01, 0x1a23); - write_grf5101(dev, 0x02, 0x4971); - write_grf5101(dev, 0x03, 0x41de); - write_grf5101(dev, 0x04, 0x2d80); - write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */ - write_grf5101(dev, 0x06, 0x0); - write_grf5101(dev, 0x07, 0x0); - write_grf5101(dev, 0x08, 0x7533); - write_grf5101(dev, 0x09, 0xc401); - write_grf5101(dev, 0x0a, 0x0); - write_grf5101(dev, 0x0c, 0x1c7); - write_grf5101(dev, 0x0d, 0x29d3); - write_grf5101(dev, 0x0e, 0x2e8); - write_grf5101(dev, 0x10, 0x192); - write_grf5101(dev, 0x11, 0x248); - write_grf5101(dev, 0x12, 0x0); - write_grf5101(dev, 0x13, 0x20c4); - write_grf5101(dev, 0x14, 0xf4fc); - write_grf5101(dev, 0x15, 0x0); - write_grf5101(dev, 0x16, 0x1500); - - write_grf5101(dev, 0x07, 0x1000); - - /* baseband configuration */ - rtl8180_write_phy(dev, 0, 0xa8); - rtl8180_write_phy(dev, 3, 0x0); - rtl8180_write_phy(dev, 4, 0xc0); - rtl8180_write_phy(dev, 5, 0x90); - rtl8180_write_phy(dev, 6, 0x1e); - rtl8180_write_phy(dev, 7, 0x64); - - grf5101_write_phy_antenna(dev, 1); - - rtl8180_write_phy(dev, 0x11, 0x88); - - if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & - RTL818X_CONFIG2_ANTENNA_DIV) - rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */ - else - rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */ - - rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); - - rtl8180_write_phy(dev, 0x19, 0x0); - rtl8180_write_phy(dev, 0x1a, 0xa0); - rtl8180_write_phy(dev, 0x1b, 0x44); -} - -const struct rtl818x_rf_ops grf5101_rf_ops = { - .name = "GCT", - .init = grf5101_rf_init, - .stop = grf5101_rf_stop, - .set_chan = grf5101_rf_set_channel, - .calc_rssi = grf5101_rf_calc_rssi, -}; diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.h b/drivers/net/wireless/rtl818x/rtl8180_grf5101.h deleted file mode 100644 index 76647111bcff..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef RTL8180_GRF5101_H -#define RTL8180_GRF5101_H - -/* - * Radio tuning for GCT GRF5101 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define GRF5101_ANTENNA 0xA3 - -extern const struct rtl818x_rf_ops grf5101_rf_ops; - -#endif /* RTL8180_GRF5101_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c deleted file mode 100644 index 16c4655181c0..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_max2820.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Radio tuning for Maxim max2820 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include "rtl8180.h" -#include "rtl8180_max2820.h" - -static const u32 max2820_chan[] = { - 12, /* CH 1 */ - 17, - 22, - 27, - 32, - 37, - 42, - 47, - 52, - 57, - 62, - 67, - 72, - 84, /* CH 14 */ -}; - -static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data) -{ - struct rtl8180_priv *priv = dev->priv; - u32 phy_config; - - phy_config = 0x90 + (data & 0xf); - phy_config <<= 16; - phy_config += addr; - phy_config <<= 8; - phy_config += (data >> 4) & 0xff; - - rtl818x_iowrite32(priv, - (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); - - msleep(1); -} - -static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) -{ - struct rtl8180_priv *priv = dev->priv; - u8 ant; - - ant = MAXIM_ANTENNA; - if (priv->rfparam & RF_PARAM_ANTBDEFAULT) - ant |= BB_ANTENNA_B; - if (chan == 14) - ant |= BB_ANTATTEN_CHAN14; - - rtl8180_write_phy(dev, 0x10, ant); -} - -static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) -{ - bool odd; - - odd = !!(agc & 1); - - agc >>= 1; - if (odd) - agc += 76; - else - agc += 66; - - /* TODO: change addends above to avoid mult / div below */ - return 65 * agc / 100; -} - -static void max2820_rf_set_channel(struct ieee80211_hw *dev, - struct ieee80211_conf *conf) -{ - struct rtl8180_priv *priv = dev->priv; - int channel = conf ? - ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; - unsigned int chan_idx = channel - 1; - u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; - u32 chan = max2820_chan[chan_idx]; - - /* While philips SA2400 drive the PA bias from - * sa2400, for MAXIM we do this directly from BB */ - rtl8180_write_phy(dev, 3, txpw); - - max2820_write_phy_antenna(dev, channel); - write_max2820(dev, 3, chan); -} - -static void max2820_rf_stop(struct ieee80211_hw *dev) -{ - rtl8180_write_phy(dev, 3, 0x8); - write_max2820(dev, 1, 0); -} - - -static void max2820_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - - /* MAXIM from netbsd driver */ - write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */ - write_max2820(dev, 1, 0x01e); /* enable register */ - write_max2820(dev, 2, 0x001); /* synt register */ - - max2820_rf_set_channel(dev, NULL); - - write_max2820(dev, 4, 0x313); /* rx register */ - - /* PA is driven directly by the BB, we keep the MAXIM bias - * at the highest value in case that setting it to lower - * values may introduce some further attenuation somewhere.. - */ - write_max2820(dev, 5, 0x00f); - - /* baseband configuration */ - rtl8180_write_phy(dev, 0, 0x88); /* sys1 */ - rtl8180_write_phy(dev, 3, 0x08); /* txagc */ - rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */ - rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */ - rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */ - rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */ - - max2820_write_phy_antenna(dev, 1); - - rtl8180_write_phy(dev, 0x11, 0x88); /* trl */ - - if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & - RTL818X_CONFIG2_ANTENNA_DIV) - rtl8180_write_phy(dev, 0x12, 0xc7); - else - rtl8180_write_phy(dev, 0x12, 0x47); - - rtl8180_write_phy(dev, 0x13, 0x9b); - - rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */ - rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */ - - max2820_rf_set_channel(dev, NULL); -} - -const struct rtl818x_rf_ops max2820_rf_ops = { - .name = "Maxim", - .init = max2820_rf_init, - .stop = max2820_rf_stop, - .set_chan = max2820_rf_set_channel, - .calc_rssi = max2820_rf_calc_rssi, -}; diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.h b/drivers/net/wireless/rtl818x/rtl8180_max2820.h deleted file mode 100644 index 61cf6d1e7d57..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_max2820.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef RTL8180_MAX2820_H -#define RTL8180_MAX2820_H - -/* - * Radio tuning for Maxim max2820 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define MAXIM_ANTENNA 0xb3 - -extern const struct rtl818x_rf_ops max2820_rf_ops; - -#endif /* RTL8180_MAX2820_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c deleted file mode 100644 index 69e4d4745dae..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c +++ /dev/null @@ -1,791 +0,0 @@ - -/* - * Radio tuning for RTL8225 on RTL8180 - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8180 driver, which is: - * Copyright 2005 Andrea Merello , et al. - * - * Thanks to Realtek for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include "rtl8180.h" -#include "rtl8180_rtl8225.h" - -static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) -{ - struct rtl8180_priv *priv = dev->priv; - u16 reg80, reg84, reg82; - u32 bangdata; - int i; - - bangdata = (data << 4) | (addr & 0xf); - - reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; - reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); - - reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(10); - - for (i = 15; i >= 0; i--) { - u16 reg = reg80; - - if (bangdata & (1 << i)) - reg |= 1; - - if (i & 1) - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); - - if (!(i & 1)) - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); -} - -static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) -{ - struct rtl8180_priv *priv = dev->priv; - u16 reg80, reg82, reg84, out; - int i; - - reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); - reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); - reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400; - - reg80 &= ~0xF; - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(4); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(5); - - for (i = 4; i >= 0; i--) { - u16 reg = reg80 | ((addr >> i) & 1); - - if (!(i & 1)) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(1); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - - if (i & 1) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(1); - } - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - - out = 0; - for (i = 11; i >= 0; i--) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(1); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - - if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) - out |= 1 << i; - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 2)); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - udelay(2); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); - - return out; -} - -static const u16 rtl8225bcd_rxgain[] = { - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, - 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, - 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, - 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, - 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, - 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, - 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, - 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, - 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, - 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, - 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, - 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb -}; - -static const u8 rtl8225_agc[] = { - 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, - 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, - 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, - 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, - 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, - 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, - 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, - 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, - 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, - 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, - 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, - 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, - 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -}; - -static const u8 rtl8225_gain[] = { - 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */ - 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */ - 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */ - 0x33, 0x80, 0x79, 0xc5, /* -78dbm */ - 0x43, 0x78, 0x76, 0xc5, /* -74dbm */ - 0x53, 0x60, 0x73, 0xc5, /* -70dbm */ - 0x63, 0x58, 0x70, 0xc5, /* -66dbm */ -}; - -static const u8 rtl8225_threshold[] = { - 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd -}; - -static const u8 rtl8225_tx_gain_cck_ofdm[] = { - 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e -}; - -static const u8 rtl8225_tx_power_cck[] = { - 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, - 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, - 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, - 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, - 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, - 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 -}; - -static const u8 rtl8225_tx_power_cck_ch14[] = { - 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, - 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, - 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 -}; - -static const u8 rtl8225_tx_power_ofdm[] = { - 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 -}; - -static const u32 rtl8225_chan[] = { - 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, - 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 -}; - -static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) -{ - struct rtl8180_priv *priv = dev->priv; - u8 cck_power, ofdm_power; - const u8 *tmp; - u32 reg; - int i; - - cck_power = priv->channels[channel - 1].hw_value & 0xFF; - ofdm_power = priv->channels[channel - 1].hw_value >> 8; - - cck_power = min(cck_power, (u8)35); - ofdm_power = min(ofdm_power, (u8)35); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, - rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); - - if (channel == 14) - tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; - else - tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; - - for (i = 0; i < 8; i++) - rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); - - msleep(1); /* FIXME: optional? */ - - /* anaparam2 on */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, - rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1); - - tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; - - rtl8225_write_phy_ofdm(dev, 5, *tmp); - rtl8225_write_phy_ofdm(dev, 7, *tmp); - - msleep(1); -} - -static void rtl8225_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - int i; - - rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); - - /* host_pci_init */ - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - msleep(200); /* FIXME: ehh?? */ - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); - - rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); - - /* TODO: check if we need really to change BRSR to do RF config */ - rtl818x_ioread16(priv, &priv->map->BRSR); - rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); - rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl8225_write(dev, 0x0, 0x067); - rtl8225_write(dev, 0x1, 0xFE0); - rtl8225_write(dev, 0x2, 0x44D); - rtl8225_write(dev, 0x3, 0x441); - rtl8225_write(dev, 0x4, 0x8BE); - rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */ - rtl8225_write(dev, 0x6, 0xAE6); - rtl8225_write(dev, 0x7, rtl8225_chan[0]); - rtl8225_write(dev, 0x8, 0x01F); - rtl8225_write(dev, 0x9, 0x334); - rtl8225_write(dev, 0xA, 0xFD4); - rtl8225_write(dev, 0xB, 0x391); - rtl8225_write(dev, 0xC, 0x050); - rtl8225_write(dev, 0xD, 0x6DB); - rtl8225_write(dev, 0xE, 0x029); - rtl8225_write(dev, 0xF, 0x914); msleep(1); - - rtl8225_write(dev, 0x2, 0xC4D); msleep(100); - - rtl8225_write(dev, 0x0, 0x127); - - for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { - rtl8225_write(dev, 0x1, i + 1); - rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); - } - - rtl8225_write(dev, 0x0, 0x027); - rtl8225_write(dev, 0x0, 0x22F); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - - for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { - rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); - msleep(1); - rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); - msleep(1); - } - - msleep(1); - - rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); - - rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); - rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); - rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); - rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); - rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); - rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); - rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); - rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); - rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); - rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); - rtl8225_write_phy_cck(dev, 0x13, 0xd0); - rtl8225_write_phy_cck(dev, 0x19, 0x00); - rtl8225_write_phy_cck(dev, 0x1a, 0xa0); - rtl8225_write_phy_cck(dev, 0x1b, 0x08); - rtl8225_write_phy_cck(dev, 0x40, 0x86); - rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); - rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); - rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); - rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1); - rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1); - rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1); - rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1); - rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1); - rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1); - rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1); - rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1); - rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); - - rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1); - - rtl8225_rf_set_tx_power(dev, 1); - - /* RX antenna default to A */ - rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ - - rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ - msleep(1); - rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - - rtl8225_write(dev, 0x0c, 0x50); - /* set OFDM initial gain */ - rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]); - rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]); - rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]); - rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]); - /* set CCK threshold */ - rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]); -} - -static const u8 rtl8225z2_tx_power_cck_ch14[] = { - 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 -}; - -static const u8 rtl8225z2_tx_power_cck_B[] = { - 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 -}; - -static const u8 rtl8225z2_tx_power_cck_A[] = { - 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 -}; - -static const u8 rtl8225z2_tx_power_cck[] = { - 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 -}; - -static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) -{ - struct rtl8180_priv *priv = dev->priv; - u8 cck_power, ofdm_power; - const u8 *tmp; - int i; - - cck_power = priv->channels[channel - 1].hw_value & 0xFF; - ofdm_power = priv->channels[channel - 1].hw_value >> 8; - - if (channel == 14) - tmp = rtl8225z2_tx_power_cck_ch14; - else if (cck_power == 12) - tmp = rtl8225z2_tx_power_cck_B; - else if (cck_power == 13) - tmp = rtl8225z2_tx_power_cck_A; - else - tmp = rtl8225z2_tx_power_cck; - - for (i = 0; i < 8; i++) - rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); - - cck_power = min(cck_power, (u8)35); - if (cck_power == 13 || cck_power == 14) - cck_power = 12; - if (cck_power >= 15) - cck_power -= 2; - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power); - rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK); - msleep(1); - - ofdm_power = min(ofdm_power, (u8)35); - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power); - - rtl8225_write_phy_ofdm(dev, 2, 0x62); - rtl8225_write_phy_ofdm(dev, 5, 0x00); - rtl8225_write_phy_ofdm(dev, 6, 0x40); - rtl8225_write_phy_ofdm(dev, 7, 0x00); - rtl8225_write_phy_ofdm(dev, 8, 0x40); - - msleep(1); -} - -static const u16 rtl8225z2_rxgain[] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009, - 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141, - 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183, - 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244, - 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288, - 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345, - 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389, - 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393, - 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, - 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9, - 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, - 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb -}; - -static void rtl8225z2_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - int i; - - rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); - - /* host_pci_init */ - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - msleep(200); /* FIXME: ehh?? */ - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); - - rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008); - - /* TODO: check if we need really to change BRSR to do RF config */ - rtl818x_ioread16(priv, &priv->map->BRSR); - rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); - rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - - rtl8225_write(dev, 0x0, 0x0B7); msleep(1); - rtl8225_write(dev, 0x1, 0xEE0); msleep(1); - rtl8225_write(dev, 0x2, 0x44D); msleep(1); - rtl8225_write(dev, 0x3, 0x441); msleep(1); - rtl8225_write(dev, 0x4, 0x8C3); msleep(1); - rtl8225_write(dev, 0x5, 0xC72); msleep(1); - rtl8225_write(dev, 0x6, 0x0E6); msleep(1); - rtl8225_write(dev, 0x7, 0x82A); msleep(1); - rtl8225_write(dev, 0x8, 0x03F); msleep(1); - rtl8225_write(dev, 0x9, 0x335); msleep(1); - rtl8225_write(dev, 0xa, 0x9D4); msleep(1); - rtl8225_write(dev, 0xb, 0x7BB); msleep(1); - rtl8225_write(dev, 0xc, 0x850); msleep(1); - rtl8225_write(dev, 0xd, 0xCDF); msleep(1); - rtl8225_write(dev, 0xe, 0x02B); msleep(1); - rtl8225_write(dev, 0xf, 0x114); msleep(100); - - if (!(rtl8225_read(dev, 6) & (1 << 7))) { - rtl8225_write(dev, 0x02, 0x0C4D); - msleep(200); - rtl8225_write(dev, 0x02, 0x044D); - msleep(100); - /* TODO: readd calibration failure message when the calibration - check works */ - } - - rtl8225_write(dev, 0x0, 0x1B7); - rtl8225_write(dev, 0x3, 0x002); - rtl8225_write(dev, 0x5, 0x004); - - for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { - rtl8225_write(dev, 0x1, i + 1); - rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); - } - - rtl8225_write(dev, 0x0, 0x0B7); msleep(100); - rtl8225_write(dev, 0x2, 0xC4D); - - msleep(200); - rtl8225_write(dev, 0x2, 0x44D); - msleep(100); - - rtl8225_write(dev, 0x00, 0x2BF); - rtl8225_write(dev, 0xFF, 0xFFFF); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - - for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { - rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); - msleep(1); - rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); - msleep(1); - } - - msleep(1); - - rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); - rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */ - rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); - rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); - - rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); - rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); - rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); - rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); - rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); - rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); - rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); - rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); - rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); - rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); - rtl8225_write_phy_cck(dev, 0x13, 0xd0); - rtl8225_write_phy_cck(dev, 0x19, 0x00); - rtl8225_write_phy_cck(dev, 0x1a, 0xa0); - rtl8225_write_phy_cck(dev, 0x1b, 0x08); - rtl8225_write_phy_cck(dev, 0x40, 0x86); - rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1); - rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); - rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); - rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1); - rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1); - rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1); - rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1); - rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1); - rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1); - rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1); - rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1); - rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); - - rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1); - - rtl8225z2_rf_set_tx_power(dev, 1); - - /* RX antenna default to A */ - rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ - - rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ - msleep(1); - rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); -} - -static void rtl8225_rf_stop(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u8 reg; - - rtl8225_write(dev, 0x4, 0x1f); msleep(1); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); -} - -static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, - struct ieee80211_conf *conf) -{ - struct rtl8180_priv *priv = dev->priv; - int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); - - if (priv->rf->init == rtl8225_rf_init) - rtl8225_rf_set_tx_power(dev, chan); - else - rtl8225z2_rf_set_tx_power(dev, chan); - - rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); - msleep(10); -} - -static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev, - struct ieee80211_bss_conf *info) -{ - struct rtl8180_priv *priv = dev->priv; - - if (info->use_short_slot) { - rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); - rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); - rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); - rtl818x_iowrite8(priv, &priv->map->EIFS, 81); - rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); - } else { - rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); - rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44); - rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); - rtl818x_iowrite8(priv, &priv->map->EIFS, 81); - rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); - } -} - -static const struct rtl818x_rf_ops rtl8225_ops = { - .name = "rtl8225", - .init = rtl8225_rf_init, - .stop = rtl8225_rf_stop, - .set_chan = rtl8225_rf_set_channel, - .conf_erp = rtl8225_rf_conf_erp, -}; - -static const struct rtl818x_rf_ops rtl8225z2_ops = { - .name = "rtl8225z2", - .init = rtl8225z2_rf_init, - .stop = rtl8225_rf_stop, - .set_chan = rtl8225_rf_set_channel, - .conf_erp = rtl8225_rf_conf_erp, -}; - -const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u16 reg8, reg9; - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - msleep(100); - - rtl8225_write(dev, 0, 0x1B7); - - reg8 = rtl8225_read(dev, 8); - reg9 = rtl8225_read(dev, 9); - - rtl8225_write(dev, 0, 0x0B7); - - if (reg8 != 0x588 || reg9 != 0x700) - return &rtl8225_ops; - - return &rtl8225z2_ops; -} diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h deleted file mode 100644 index 310013a2d726..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef RTL8180_RTL8225_H -#define RTL8180_RTL8225_H - -#define RTL8225_ANAPARAM_ON 0xa0000b59 -#define RTL8225_ANAPARAM2_ON 0x860dec11 -#define RTL8225_ANAPARAM_OFF 0xa00beb59 -#define RTL8225_ANAPARAM2_OFF 0x840dec11 - -const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *); - -static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, - u8 addr, u8 data) -{ - rtl8180_write_phy(dev, addr, data); -} - -static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, - u8 addr, u8 data) -{ - rtl8180_write_phy(dev, addr, data | 0x10000); -} - -#endif /* RTL8180_RTL8225_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c deleted file mode 100644 index d064fcc5ec08..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c +++ /dev/null @@ -1,228 +0,0 @@ - -/* - * Radio tuning for Philips SA2400 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include "rtl8180.h" -#include "rtl8180_sa2400.h" - -static const u32 sa2400_chan[] = { - 0x00096c, /* ch1 */ - 0x080970, - 0x100974, - 0x180978, - 0x000980, - 0x080984, - 0x100988, - 0x18098c, - 0x000994, - 0x080998, - 0x10099c, - 0x1809a0, - 0x0009a8, - 0x0009b4, /* ch 14 */ -}; - -static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data) -{ - struct rtl8180_priv *priv = dev->priv; - u32 phy_config; - - /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */ - phy_config = 0xb0000000; - - phy_config |= ((u32)(addr & 0xf)) << 24; - phy_config |= data & 0xffffff; - - rtl818x_iowrite32(priv, - (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); - - msleep(3); -} - -static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) -{ - struct rtl8180_priv *priv = dev->priv; - u8 ant = SA2400_ANTENNA; - - if (priv->rfparam & RF_PARAM_ANTBDEFAULT) - ant |= BB_ANTENNA_B; - - if (chan == 14) - ant |= BB_ANTATTEN_CHAN14; - - rtl8180_write_phy(dev, 0x10, ant); - -} - -static u8 sa2400_rf_rssi_map[] = { - 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, - 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, - 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, - 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, - 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, - 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, - 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, - 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, - 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, - 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, -}; - -static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) -{ - if (sq == 0x80) - return 1; - - if (sq > 78) - return 32; - - /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ - return 65 * sa2400_rf_rssi_map[sq] / 100; -} - -static void sa2400_rf_set_channel(struct ieee80211_hw *dev, - struct ieee80211_conf *conf) -{ - struct rtl8180_priv *priv = dev->priv; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; - u32 chan = sa2400_chan[channel - 1]; - - write_sa2400(dev, 7, txpw); - - sa2400_write_phy_antenna(dev, channel); - - write_sa2400(dev, 0, chan); - write_sa2400(dev, 1, 0xbb50); - write_sa2400(dev, 2, 0x80); - write_sa2400(dev, 3, 0); -} - -static void sa2400_rf_stop(struct ieee80211_hw *dev) -{ - write_sa2400(dev, 4, 0); -} - -static void sa2400_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8180_priv *priv = dev->priv; - u32 anaparam, txconf; - u8 firdac; - int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY; - - anaparam = priv->anaparam; - anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT); - anaparam &= ~ANAPARAM_PWR1_MASK; - anaparam &= ~ANAPARAM_PWR0_MASK; - - if (analogphy) { - anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT; - firdac = 0; - } else { - anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT); - anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT); - firdac = 1 << SA2400_REG4_FIRDAC_SHIFT; - } - - rtl8180_set_anaparam(priv, anaparam); - - write_sa2400(dev, 0, sa2400_chan[0]); - write_sa2400(dev, 1, 0xbb50); - write_sa2400(dev, 2, 0x80); - write_sa2400(dev, 3, 0); - write_sa2400(dev, 4, 0x19340 | firdac); - write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15); - write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */ - - if (!analogphy) - write_sa2400(dev, 4, 0x1938c); /*???*/ - - write_sa2400(dev, 4, 0x19340 | firdac); - - write_sa2400(dev, 0, sa2400_chan[0]); - write_sa2400(dev, 1, 0xbb50); - write_sa2400(dev, 2, 0x80); - write_sa2400(dev, 3, 0); - write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */ - - /* new from rtl8180 embedded driver (rtl8181 project) */ - write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */ - write_sa2400(dev, 8, 0); /* VCO */ - - if (analogphy) { - rtl8180_set_anaparam(priv, anaparam | - (1 << ANAPARAM_TXDACOFF_SHIFT)); - - txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF); - rtl818x_iowrite32(priv, &priv->map->TX_CONF, - txconf | RTL818X_TX_CONF_LOOPBACK_CONT); - - write_sa2400(dev, 4, 0x19341); /* calibrates DC */ - - /* a 5us sleep is required here, - * we rely on the 3ms delay introduced in write_sa2400 */ - write_sa2400(dev, 4, 0x19345); - - /* a 20us sleep is required here, - * we rely on the 3ms delay introduced in write_sa2400 */ - - rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf); - - rtl8180_set_anaparam(priv, anaparam); - } - /* end new code */ - - write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */ - - /* baseband configuration */ - rtl8180_write_phy(dev, 0, 0x98); - rtl8180_write_phy(dev, 3, 0x38); - rtl8180_write_phy(dev, 4, 0xe0); - rtl8180_write_phy(dev, 5, 0x90); - rtl8180_write_phy(dev, 6, 0x1a); - rtl8180_write_phy(dev, 7, 0x64); - - sa2400_write_phy_antenna(dev, 1); - - rtl8180_write_phy(dev, 0x11, 0x80); - - if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & - RTL818X_CONFIG2_ANTENNA_DIV) - rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */ - else - rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */ - - rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); - - rtl8180_write_phy(dev, 0x19, 0x0); - rtl8180_write_phy(dev, 0x1a, 0xa0); -} - -const struct rtl818x_rf_ops sa2400_rf_ops = { - .name = "Philips", - .init = sa2400_rf_init, - .stop = sa2400_rf_stop, - .set_chan = sa2400_rf_set_channel, - .calc_rssi = sa2400_rf_calc_rssi, -}; diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.h b/drivers/net/wireless/rtl818x/rtl8180_sa2400.h deleted file mode 100644 index a4aaa0d413f1..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef RTL8180_SA2400_H -#define RTL8180_SA2400_H - -/* - * Radio tuning for Philips SA2400 on RTL8180 - * - * Copyright 2007 Andrea Merello - * - * Code from the BSD driver and the rtl8181 project have been - * very useful to understand certain things - * - * I want to thanks the Authors of such projects and the Ndiswrapper - * project Authors. - * - * A special Big Thanks also is for all people who donated me cards, - * making possible the creation of the original rtl8180 driver - * from which this code is derived! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define SA2400_ANTENNA 0x91 -#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8 -#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28 -#define SA2400_ANAPARAM_PWR0_ON 0x3 - -/* RX sensitivity in dbm */ -#define SA2400_MAX_SENS 85 - -#define SA2400_REG4_FIRDAC_SHIFT 7 - -extern const struct rtl818x_rf_ops sa2400_rf_ops; - -#endif /* RTL8180_SA2400_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h deleted file mode 100644 index 98878160a65a..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Definitions for RTL8187 hardware - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8187 driver, which is: - * Copyright 2005 Andrea Merello , et al. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef RTL8187_H -#define RTL8187_H - -#include "rtl818x.h" -#include "rtl8187_leds.h" - -#define RTL8187_EEPROM_TXPWR_BASE 0x05 -#define RTL8187_EEPROM_MAC_ADDR 0x07 -#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ -#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ -#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ -#define RTL8187_EEPROM_SELECT_GPIO 0x3B - -#define RTL8187_REQT_READ 0xC0 -#define RTL8187_REQT_WRITE 0x40 -#define RTL8187_REQ_GET_REG 0x05 -#define RTL8187_REQ_SET_REG 0x05 - -#define RTL8187_MAX_RX 0x9C4 - -#define RFKILL_MASK_8187_89_97 0x2 -#define RFKILL_MASK_8198 0x4 - -struct rtl8187_rx_info { - struct urb *urb; - struct ieee80211_hw *dev; -}; - -struct rtl8187_rx_hdr { - __le32 flags; - u8 noise; - u8 signal; - u8 agc; - u8 reserved; - __le64 mac_time; -} __packed; - -struct rtl8187b_rx_hdr { - __le32 flags; - __le64 mac_time; - u8 sq; - u8 rssi; - u8 agc; - u8 flags2; - __le16 snr_long2end; - s8 pwdb_g12; - u8 fot; -} __packed; - -/* {rtl8187,rtl8187b}_tx_info is in skb */ - -struct rtl8187_tx_hdr { - __le32 flags; - __le16 rts_duration; - __le16 len; - __le32 retry; -} __packed; - -struct rtl8187b_tx_hdr { - __le32 flags; - __le16 rts_duration; - __le16 len; - __le32 unused_1; - __le16 unused_2; - __le16 tx_duration; - __le32 unused_3; - __le32 retry; - __le32 unused_4[2]; -} __packed; - -enum { - DEVICE_RTL8187, - DEVICE_RTL8187B -}; - -struct rtl8187_priv { - /* common between rtl818x drivers */ - struct rtl818x_csr *map; - const struct rtl818x_rf_ops *rf; - struct ieee80211_vif *vif; - - /* The mutex protects the TX loopback state. - * Any attempt to set channels concurrently locks the device. - */ - struct mutex conf_mutex; - - /* rtl8187 specific */ - struct ieee80211_channel channels[14]; - struct ieee80211_rate rates[12]; - struct ieee80211_supported_band band; - struct usb_device *udev; - u32 rx_conf; - struct usb_anchor anchored; - struct delayed_work work; - struct ieee80211_hw *dev; -#ifdef CONFIG_RTL8187_LEDS - struct rtl8187_led led_radio; - struct rtl8187_led led_tx; - struct rtl8187_led led_rx; - struct delayed_work led_on; - struct delayed_work led_off; -#endif - u16 txpwr_base; - u8 asic_rev; - u8 is_rtl8187b; - enum { - RTL8187BvB, - RTL8187BvD, - RTL8187BvE - } hw_rev; - struct sk_buff_head rx_queue; - u8 signal; - u8 noise; - u8 slot_time; - u8 aifsn[4]; - u8 rfkill_mask; - struct { - __le64 buf; - struct sk_buff_head queue; - } b_tx_status; /* This queue is used by both -b and non-b devices */ - struct mutex io_mutex; - union { - u8 bits8; - __le16 bits16; - __le32 bits32; - } *io_dmabuf; - bool rfkill_off; -}; - -void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); - -static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, - u8 *addr, u8 idx) -{ - u8 val; - - mutex_lock(&priv->io_mutex); - usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), - RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); - - val = priv->io_dmabuf->bits8; - mutex_unlock(&priv->io_mutex); - - return val; -} - -static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr) -{ - return rtl818x_ioread8_idx(priv, addr, 0); -} - -static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, - __le16 *addr, u8 idx) -{ - __le16 val; - - mutex_lock(&priv->io_mutex); - usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), - RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); - - val = priv->io_dmabuf->bits16; - mutex_unlock(&priv->io_mutex); - - return le16_to_cpu(val); -} - -static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr) -{ - return rtl818x_ioread16_idx(priv, addr, 0); -} - -static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, - __le32 *addr, u8 idx) -{ - __le32 val; - - mutex_lock(&priv->io_mutex); - usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), - RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); - - val = priv->io_dmabuf->bits32; - mutex_unlock(&priv->io_mutex); - - return le32_to_cpu(val); -} - -static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) -{ - return rtl818x_ioread32_idx(priv, addr, 0); -} - -static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, - u8 *addr, u8 val, u8 idx) -{ - mutex_lock(&priv->io_mutex); - - priv->io_dmabuf->bits8 = val; - usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), - RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); - - mutex_unlock(&priv->io_mutex); -} - -static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) -{ - rtl818x_iowrite8_idx(priv, addr, val, 0); -} - -static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, - __le16 *addr, u16 val, u8 idx) -{ - mutex_lock(&priv->io_mutex); - - priv->io_dmabuf->bits16 = cpu_to_le16(val); - usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), - RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); - - mutex_unlock(&priv->io_mutex); -} - -static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, - u16 val) -{ - rtl818x_iowrite16_idx(priv, addr, val, 0); -} - -static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, - __le32 *addr, u32 val, u8 idx) -{ - mutex_lock(&priv->io_mutex); - - priv->io_dmabuf->bits32 = cpu_to_le32(val); - usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), - RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); - - mutex_unlock(&priv->io_mutex); -} - -static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, - u32 val) -{ - rtl818x_iowrite32_idx(priv, addr, val, 0); -} - -#endif /* RTL8187_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187/Makefile b/drivers/net/wireless/rtl818x/rtl8187/Makefile new file mode 100644 index 000000000000..7b6299268ecf --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/Makefile @@ -0,0 +1,5 @@ +rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o + +obj-$(CONFIG_RTL8187) += rtl8187.o + +ccflags-y += -Idrivers/net/wireless/rtl818x diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c new file mode 100644 index 000000000000..6b82cac37ee3 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -0,0 +1,1591 @@ +/* + * Linux device driver for RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * The driver was extended to the RTL8187B in 2008 by: + * Herton Ronaldo Krzesinski + * Hin-Tak Leung + * Larry Finger + * + * Magic delays and register offsets below are taken from the original + * r8187 driver sources. Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8225.h" +#ifdef CONFIG_RTL8187_LEDS +#include "leds.h" +#endif +#include "rfkill.h" + +MODULE_AUTHOR("Michael Wu "); +MODULE_AUTHOR("Andrea Merello "); +MODULE_AUTHOR("Herton Ronaldo Krzesinski "); +MODULE_AUTHOR("Hin-Tak Leung "); +MODULE_AUTHOR("Larry Finger "); +MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); +MODULE_LICENSE("GPL"); + +static struct usb_device_id rtl8187_table[] __devinitdata = { + /* Asus */ + {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, + /* Belkin */ + {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B}, + /* Realtek */ + {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, + /* Surecom */ + {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, + /* Logitech */ + {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, + /* Netgear */ + {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B}, + /* HP */ + {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B}, + /* Sphairon Access Systems GmbH */ + {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, + /* Dick Smith Electronics */ + {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, + /* Abocom */ + {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, + /* Qcom */ + {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, + /* AirLive */ + {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, + /* Linksys */ + {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8187_table); + +static const struct ieee80211_rate rtl818x_rates[] = { + { .bitrate = 10, .hw_value = 0, }, + { .bitrate = 20, .hw_value = 1, }, + { .bitrate = 55, .hw_value = 2, }, + { .bitrate = 110, .hw_value = 3, }, + { .bitrate = 60, .hw_value = 4, }, + { .bitrate = 90, .hw_value = 5, }, + { .bitrate = 120, .hw_value = 6, }, + { .bitrate = 180, .hw_value = 7, }, + { .bitrate = 240, .hw_value = 8, }, + { .bitrate = 360, .hw_value = 9, }, + { .bitrate = 480, .hw_value = 10, }, + { .bitrate = 540, .hw_value = 11, }, +}; + +static const struct ieee80211_channel rtl818x_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + +static void rtl8187_iowrite_async_cb(struct urb *urb) +{ + kfree(urb->context); +} + +static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, + void *data, u16 len) +{ + struct usb_ctrlrequest *dr; + struct urb *urb; + struct rtl8187_async_write_data { + u8 data[4]; + struct usb_ctrlrequest dr; + } *buf; + int rc; + + buf = kmalloc(sizeof(*buf), GFP_ATOMIC); + if (!buf) + return; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree(buf); + return; + } + + dr = &buf->dr; + + dr->bRequestType = RTL8187_REQT_WRITE; + dr->bRequest = RTL8187_REQ_SET_REG; + dr->wValue = addr; + dr->wIndex = 0; + dr->wLength = cpu_to_le16(len); + + memcpy(buf, data, len); + + usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), + (unsigned char *)dr, buf, len, + rtl8187_iowrite_async_cb, buf); + usb_anchor_urb(urb, &priv->anchored); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + kfree(buf); + usb_unanchor_urb(urb); + } + usb_free_urb(urb); +} + +static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, + __le32 *addr, u32 val) +{ + __le32 buf = cpu_to_le32(val); + + rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr), + &buf, sizeof(buf)); +} + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8187_priv *priv = dev->priv; + + data <<= 8; + data |= addr | 0x80; + + rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF); +} + +static void rtl8187_tx_cb(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = info->rate_driver_data[0]; + struct rtl8187_priv *priv = hw->priv; + + skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : + sizeof(struct rtl8187_tx_hdr)); + ieee80211_tx_info_clear_status(info); + + if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + if (priv->is_rtl8187b) { + skb_queue_tail(&priv->b_tx_status.queue, skb); + + /* queue is "full", discard last items */ + while (skb_queue_len(&priv->b_tx_status.queue) > 5) { + struct sk_buff *old_skb; + + dev_dbg(&priv->udev->dev, + "transmit status queue full\n"); + + old_skb = skb_dequeue(&priv->b_tx_status.queue); + ieee80211_tx_status_irqsafe(hw, old_skb); + } + return; + } else { + info->flags |= IEEE80211_TX_STAT_ACK; + } + } + if (priv->is_rtl8187b) + ieee80211_tx_status_irqsafe(hw, skb); + else { + /* Retry information for the RTI8187 is only available by + * reading a register in the device. We are in interrupt mode + * here, thus queue the skb and finish on a work queue. */ + skb_queue_tail(&priv->b_tx_status.queue, skb); + ieee80211_queue_delayed_work(hw, &priv->work, 0); + } +} + +static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +{ + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int ep; + void *buf; + struct urb *urb; + __le16 rts_dur = 0; + u32 flags; + int rc; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + + flags = skb->len; + flags |= RTL818X_TX_DESC_FLAG_NO_ENC; + + flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; + if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) + flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + flags |= RTL818X_TX_DESC_FLAG_RTS; + flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + rts_dur = ieee80211_rts_duration(dev, priv->vif, + skb->len, info); + } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + flags |= RTL818X_TX_DESC_FLAG_CTS; + flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + } + + if (!priv->is_rtl8187b) { + struct rtl8187_tx_hdr *hdr = + (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); + hdr->flags = cpu_to_le32(flags); + hdr->len = 0; + hdr->rts_duration = rts_dur; + hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); + buf = hdr; + + ep = 2; + } else { + /* fc needs to be calculated before skb_push() */ + unsigned int epmap[4] = { 6, 7, 5, 4 }; + struct ieee80211_hdr *tx_hdr = + (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(tx_hdr->frame_control); + + struct rtl8187b_tx_hdr *hdr = + (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr)); + struct ieee80211_rate *txrate = + ieee80211_get_tx_rate(dev, info); + memset(hdr, 0, sizeof(*hdr)); + hdr->flags = cpu_to_le32(flags); + hdr->rts_duration = rts_dur; + hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); + hdr->tx_duration = + ieee80211_generic_frame_duration(dev, priv->vif, + skb->len, txrate); + buf = hdr; + + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) + ep = 12; + else + ep = epmap[skb_get_queue_mapping(skb)]; + } + + info->rate_driver_data[0] = dev; + info->rate_driver_data[1] = urb; + + usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), + buf, skb->len, rtl8187_tx_cb, skb); + urb->transfer_flags |= URB_ZERO_PACKET; + usb_anchor_urb(urb, &priv->anchored); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + usb_unanchor_urb(urb); + kfree_skb(skb); + } + usb_free_urb(urb); + + return NETDEV_TX_OK; +} + +static void rtl8187_rx_cb(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; + struct ieee80211_hw *dev = info->dev; + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_rx_status rx_status = { 0 }; + int rate, signal; + u32 flags; + unsigned long f; + + spin_lock_irqsave(&priv->rx_queue.lock, f); + __skb_unlink(skb, &priv->rx_queue); + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + + if (unlikely(urb->status)) { + dev_kfree_skb_irq(skb); + return; + } + + if (!priv->is_rtl8187b) { + struct rtl8187_rx_hdr *hdr = + (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling + * constants are derived from the output of p54usb. + */ + signal = -4 - ((27 * hdr->agc) >> 6); + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { + struct rtl8187b_rx_hdr *hdr = + (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. + * In testing, none of these quantities show qualitative + * agreement with AP signal strength, except for the AGC, + * which is inversely proportional to the strength of the + * signal. In the following, the signal strength + * is derived from the AGC. The arbitrary scaling constants + * are chosen to make the results close to the values obtained + * for a BCM4312 using b43 as the driver. The noise is ignored + * for now. + */ + flags = le32_to_cpu(hdr->flags); + signal = 14 - hdr->agc / 2; + rx_status.antenna = (hdr->rssi >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } + + rx_status.signal = signal; + priv->signal = signal; + rate = (flags >> 20) & 0xF; + skb_trim(skb, flags & 0x0FFF); + rx_status.rate_idx = rate; + rx_status.freq = dev->conf.channel->center_freq; + rx_status.band = dev->conf.channel->band; + rx_status.flag |= RX_FLAG_TSFT; + if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(dev, skb); + + skb = dev_alloc_skb(RTL8187_MAX_RX); + if (unlikely(!skb)) { + /* TODO check rx queue length and refill *somewhere* */ + return; + } + + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = urb; + info->dev = dev; + urb->transfer_buffer = skb_tail_pointer(skb); + urb->context = skb; + skb_queue_tail(&priv->rx_queue, skb); + + usb_anchor_urb(urb, &priv->anchored); + if (usb_submit_urb(urb, GFP_ATOMIC)) { + usb_unanchor_urb(urb); + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } +} + +static int rtl8187_init_urbs(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct urb *entry = NULL; + struct sk_buff *skb; + struct rtl8187_rx_info *info; + int ret = 0; + + while (skb_queue_len(&priv->rx_queue) < 16) { + skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err; + } + entry = usb_alloc_urb(0, GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto err; + } + usb_fill_bulk_urb(entry, priv->udev, + usb_rcvbulkpipe(priv->udev, + priv->is_rtl8187b ? 3 : 1), + skb_tail_pointer(skb), + RTL8187_MAX_RX, rtl8187_rx_cb, skb); + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = entry; + info->dev = dev; + skb_queue_tail(&priv->rx_queue, skb); + usb_anchor_urb(entry, &priv->anchored); + ret = usb_submit_urb(entry, GFP_KERNEL); + if (ret) { + skb_unlink(skb, &priv->rx_queue); + usb_unanchor_urb(entry); + goto err; + } + usb_free_urb(entry); + } + return ret; + +err: + usb_free_urb(entry); + kfree_skb(skb); + usb_kill_anchored_urbs(&priv->anchored); + return ret; +} + +static void rtl8187b_status_cb(struct urb *urb) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)urb->context; + struct rtl8187_priv *priv = hw->priv; + u64 val; + unsigned int cmd_type; + + if (unlikely(urb->status)) + return; + + /* + * Read from status buffer: + * + * bits [30:31] = cmd type: + * - 0 indicates tx beacon interrupt + * - 1 indicates tx close descriptor + * + * In the case of tx beacon interrupt: + * [0:9] = Last Beacon CW + * [10:29] = reserved + * [30:31] = 00b + * [32:63] = Last Beacon TSF + * + * If it's tx close descriptor: + * [0:7] = Packet Retry Count + * [8:14] = RTS Retry Count + * [15] = TOK + * [16:27] = Sequence No + * [28] = LS + * [29] = FS + * [30:31] = 01b + * [32:47] = unused (reserved?) + * [48:63] = MAC Used Time + */ + val = le64_to_cpu(priv->b_tx_status.buf); + + cmd_type = (val >> 30) & 0x3; + if (cmd_type == 1) { + unsigned int pkt_rc, seq_no; + bool tok; + struct sk_buff *skb; + struct ieee80211_hdr *ieee80211hdr; + unsigned long flags; + + pkt_rc = val & 0xFF; + tok = val & (1 << 15); + seq_no = (val >> 16) & 0xFFF; + + spin_lock_irqsave(&priv->b_tx_status.queue.lock, flags); + skb_queue_reverse_walk(&priv->b_tx_status.queue, skb) { + ieee80211hdr = (struct ieee80211_hdr *)skb->data; + + /* + * While testing, it was discovered that the seq_no + * doesn't actually contains the sequence number. + * Instead of returning just the 12 bits of sequence + * number, hardware is returning entire sequence control + * (fragment number plus sequence number) in a 12 bit + * only field overflowing after some time. As a + * workaround, just consider the lower bits, and expect + * it's unlikely we wrongly ack some sent data + */ + if ((le16_to_cpu(ieee80211hdr->seq_ctrl) + & 0xFFF) == seq_no) + break; + } + if (skb != (struct sk_buff *) &priv->b_tx_status.queue) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + __skb_unlink(skb, &priv->b_tx_status.queue); + if (tok) + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.rates[0].count = pkt_rc + 1; + + ieee80211_tx_status_irqsafe(hw, skb); + } + spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags); + } + + usb_anchor_urb(urb, &priv->anchored); + if (usb_submit_urb(urb, GFP_ATOMIC)) + usb_unanchor_urb(urb); +} + +static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct urb *entry; + int ret = 0; + + entry = usb_alloc_urb(0, GFP_KERNEL); + if (!entry) + return -ENOMEM; + + usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9), + &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf), + rtl8187b_status_cb, dev); + + usb_anchor_urb(entry, &priv->anchored); + ret = usb_submit_urb(entry, GFP_KERNEL); + if (ret) + usb_unanchor_urb(entry); + usb_free_urb(entry); + + return ret; +} + +static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon) +{ + u32 anaparam, anaparam2; + u8 anaparam3, reg; + + if (!priv->is_rtl8187b) { + if (rfon) { + anaparam = RTL8187_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON; + } else { + anaparam = RTL8187_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF; + } + } else { + if (rfon) { + anaparam = RTL8187B_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON; + } else { + anaparam = RTL8187B_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF; + } + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); + if (priv->is_rtl8187b) + rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3); + reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + +static int rtl8187_cmd_reset(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u8 reg; + int i; + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= (1 << 1); + reg |= RTL818X_CMD_RESET; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + i = 10; + do { + msleep(2); + if (!(rtl818x_ioread8(priv, &priv->map->CMD) & + RTL818X_CMD_RESET)) + break; + } while (--i); + + if (!i) { + wiphy_err(dev->wiphy, "Reset timeout!\n"); + return -ETIMEDOUT; + } + + /* reload registers from eeprom */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); + + i = 10; + do { + msleep(4); + if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) & + RTL818X_EEPROM_CMD_CONFIG)) + break; + } while (--i); + + if (!i) { + wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int rtl8187_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u8 reg; + int res; + + /* reset */ + rtl8187_set_anaparam(priv, true); + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + msleep(200); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00); + msleep(200); + + res = rtl8187_cmd_reset(dev); + if (res) + return res; + + rtl8187_set_anaparam(priv, true); + + /* setup card */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); + + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 1); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + + rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); + reg &= 0x3F; + reg |= 0x80; + rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0); + + // TODO: set RESP_RATE and BRSR properly + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + + /* host_usb_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); + reg = rtl818x_ioread8(priv, (u8 *)0xFE53); + rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80); + msleep(100); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); + msleep(100); + + priv->rf->init(dev); + + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); + rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); + rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); + rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + + return 0; +} + +static const u8 rtl8187b_reg_table[][3] = { + {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0}, + {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0}, + {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0}, + {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0}, + + {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1}, + {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1}, + {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, + {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, + {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1}, + + {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2}, + {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2}, + {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2}, + {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2}, + {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2}, + {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2}, + {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, + + {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0}, + {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, + {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, + {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, + {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, + + {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, + {0x8F, 0x00, 0} +}; + +static int rtl8187b_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int res, i; + u8 reg; + + rtl8187_set_anaparam(priv, true); + + /* Reset PLL sequence on 8187B. Realtek note: reduces power + * consumption about 30 mA */ + rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); + reg = rtl818x_ioread8(priv, (u8 *)0xFF62); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); + + res = rtl8187_cmd_reset(dev); + if (res) + return res; + + rtl8187_set_anaparam(priv, true); + + /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as + * RESP_RATE on 8187L in Realtek sources: each bit should be each + * one of the 12 rates, all are enabled */ + rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF); + + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + /* Auto Rate Fallback Register (ARFR): 1M-54M setting */ + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1); + + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); + rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) { + rtl818x_iowrite8_idx(priv, + (u8 *)(uintptr_t) + (rtl8187b_reg_table[i][0] | 0xFF00), + rtl8187b_reg_table[i][1], + rtl8187b_reg_table[i][2]); + } + + rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50); + rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0); + + rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1); + rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001); + + /* RFSW_CTRL register */ + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + msleep(100); + + priv->rf->init(dev); + + reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4); + rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); + rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); + + reg = rtl818x_ioread8(priv, (u8 *)0xFFDB); + rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2)); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3); + rtl818x_iowrite8(priv, (u8 *)0xFF61, 0); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1); + rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2); + + rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B); + + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1); + + priv->slot_time = 0x9; + priv->aifsn[0] = 2; /* AIFSN[AC_VO] */ + priv->aifsn[1] = 2; /* AIFSN[AC_VI] */ + priv->aifsn[2] = 7; /* AIFSN[AC_BK] */ + priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ + rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); + + /* ENEDCA flag must always be set, transmit issues? */ + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); + + return 0; +} + +static void rtl8187_work(struct work_struct *work) +{ + /* The RTL8187 returns the retry count through register 0xFFFA. In + * addition, it appears to be a cumulative retry count, not the + * value for the current TX packet. When multiple TX entries are + * queued, the retry count will be valid for the last one in the queue. + * The "error" should not matter for purposes of rate setting. */ + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + work.work); + struct ieee80211_tx_info *info; + struct ieee80211_hw *dev = priv->dev; + static u16 retry; + u16 tmp; + + mutex_lock(&priv->conf_mutex); + tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); + while (skb_queue_len(&priv->b_tx_status.queue) > 0) { + struct sk_buff *old_skb; + + old_skb = skb_dequeue(&priv->b_tx_status.queue); + info = IEEE80211_SKB_CB(old_skb); + info->status.rates[0].count = tmp - retry + 1; + ieee80211_tx_status_irqsafe(dev, old_skb); + } + retry = tmp; + mutex_unlock(&priv->conf_mutex); +} + +static int rtl8187_start(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u32 reg; + int ret; + + mutex_lock(&priv->conf_mutex); + + ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : + rtl8187b_init_hw(dev); + if (ret) + goto rtl8187_start_exit; + + init_usb_anchor(&priv->anchored); + priv->dev = dev; + + if (priv->is_rtl8187b) { + reg = RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC | + RTL818X_RX_CONF_BSSID | + (7 << 13 /* RX FIFO threshold NONE */) | + (7 << 10 /* MAX RX DMA */) | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_MULTICAST; + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + RTL818X_TX_CONF_HW_SEQNUM | + RTL818X_TX_CONF_DISREQQSIZE | + (7 << 8 /* short retry limit */) | + (7 << 0 /* long retry limit */) | + (7 << 21 /* MAX TX DMA */)); + rtl8187_init_urbs(dev); + rtl8187b_init_status_urb(dev); + goto rtl8187_start_exit; + } + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); + + rtl8187_init_urbs(dev); + + reg = RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_BSSID | + RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + (7 << 13 /* RX FIFO threshold NONE */) | + (7 << 10 /* MAX RX DMA */) | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC; + + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; + reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + reg = RTL818X_TX_CONF_CW_MIN | + (7 << 21 /* MAX TX DMA */) | + RTL818X_TX_CONF_NO_ICV; + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg |= RTL818X_CMD_TX_ENABLE; + reg |= RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + INIT_DELAYED_WORK(&priv->work, rtl8187_work); + +rtl8187_start_exit: + mutex_unlock(&priv->conf_mutex); + return ret; +} + +static void rtl8187_stop(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct sk_buff *skb; + u32 reg; + + mutex_lock(&priv->conf_mutex); + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= ~RTL818X_CMD_TX_ENABLE; + reg &= ~RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + priv->rf->stop(dev); + rtl8187_set_anaparam(priv, false); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + while ((skb = skb_dequeue(&priv->b_tx_status.queue))) + dev_kfree_skb_any(skb); + + usb_kill_anchored_urbs(&priv->anchored); + mutex_unlock(&priv->conf_mutex); + + if (!priv->is_rtl8187b) + cancel_delayed_work_sync(&priv->work); +} + +static int rtl8187_add_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + int ret = -EOPNOTSUPP; + + mutex_lock(&priv->conf_mutex); + if (priv->vif) + goto exit; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + break; + default: + goto exit; + } + + ret = 0; + priv->vif = vif; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->MAC[i], + ((u8 *)vif->addr)[i]); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + +exit: + mutex_unlock(&priv->conf_mutex); + return ret; +} + +static void rtl8187_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + mutex_lock(&priv->conf_mutex); + priv->vif = NULL; + mutex_unlock(&priv->conf_mutex); +} + +static int rtl8187_config(struct ieee80211_hw *dev, u32 changed) +{ + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_conf *conf = &dev->conf; + u32 reg; + + mutex_lock(&priv->conf_mutex); + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + /* Enable TX loopback on MAC level to avoid TX during channel + * changes, as this has be seen to causes problems and the + * card will stop work until next reset + */ + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + reg | RTL818X_TX_CONF_LOOPBACK_MAC); + priv->rf->set_chan(dev, conf); + msleep(10); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); + rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); + mutex_unlock(&priv->conf_mutex); + return 0; +} + +/* + * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for + * example. Thus we have to use raw values for AC_*_PARAM register addresses. + */ +static __le32 *rtl8187b_ac_addr[4] = { + (__le32 *) 0xFFF0, /* AC_VO */ + (__le32 *) 0xFFF4, /* AC_VI */ + (__le32 *) 0xFFFC, /* AC_BK */ + (__le32 *) 0xFFF8, /* AC_BE */ +}; + +#define SIFS_TIME 0xa + +static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, + bool use_short_preamble) +{ + if (priv->is_rtl8187b) { + u8 difs, eifs; + u16 ack_timeout; + int queue; + + if (use_short_slot) { + priv->slot_time = 0x9; + difs = 0x1c; + eifs = 0x53; + } else { + priv->slot_time = 0x14; + difs = 0x32; + eifs = 0x5b; + } + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); + rtl818x_iowrite8(priv, &priv->map->DIFS, difs); + + /* + * BRSR+1 on 8187B is in fact EIFS register + * Value in units of 4 us + */ + rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs); + + /* + * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout + * register. In units of 4 us like eifs register + * ack_timeout = ack duration + plcp + difs + preamble + */ + ack_timeout = 112 + 48 + difs; + if (use_short_preamble) + ack_timeout += 72; + else + ack_timeout += 144; + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, + DIV_ROUND_UP(ack_timeout, 4)); + + for (queue = 0; queue < 4; queue++) + rtl818x_iowrite8(priv, (u8 *) rtl8187b_ac_addr[queue], + priv->aifsn[queue] * priv->slot_time + + SIFS_TIME); + } else { + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + if (use_short_slot) { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); + } else { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); + } + } +} + +static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + u8 reg; + + if (changed & BSS_CHANGED_BSSID) { + mutex_lock(&priv->conf_mutex); + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->BSSID[i], + info->bssid[i]); + + if (priv->is_rtl8187b) + reg = RTL818X_MSR_ENEDCA; + else + reg = 0; + + if (is_valid_ether_addr(info->bssid)) + reg |= RTL818X_MSR_INFRA; + else + reg |= RTL818X_MSR_NO_LINK; + + rtl818x_iowrite8(priv, &priv->map->MSR, reg); + + mutex_unlock(&priv->conf_mutex); + } + + if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) + rtl8187_conf_erp(priv, info->use_short_slot, + info->use_short_preamble); +} + +static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, + struct netdev_hw_addr_list *mc_list) +{ + return netdev_hw_addr_list_count(mc_list); +} + +static void rtl8187_configure_filter(struct ieee80211_hw *dev, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct rtl8187_priv *priv = dev->priv; + + if (changed_flags & FIF_FCSFAIL) + priv->rx_conf ^= RTL818X_RX_CONF_FCS; + if (changed_flags & FIF_CONTROL) + priv->rx_conf ^= RTL818X_RX_CONF_CTRL; + if (changed_flags & FIF_OTHER_BSS) + priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; + if (*total_flags & FIF_ALLMULTI || multicast > 0) + priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; + else + priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; + + *total_flags = 0; + + if (priv->rx_conf & RTL818X_RX_CONF_FCS) + *total_flags |= FIF_FCSFAIL; + if (priv->rx_conf & RTL818X_RX_CONF_CTRL) + *total_flags |= FIF_CONTROL; + if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) + *total_flags |= FIF_OTHER_BSS; + if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) + *total_flags |= FIF_ALLMULTI; + + rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); +} + +static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cw_min, cw_max; + + if (queue > 3) + return -EINVAL; + + cw_min = fls(params->cw_min); + cw_max = fls(params->cw_max); + + if (priv->is_rtl8187b) { + priv->aifsn[queue] = params->aifs; + + /* + * This is the structure of AC_*_PARAM registers in 8187B: + * - TXOP limit field, bit offset = 16 + * - ECWmax, bit offset = 12 + * - ECWmin, bit offset = 8 + * - AIFS, bit offset = 0 + */ + rtl818x_iowrite32(priv, rtl8187b_ac_addr[queue], + (params->txop << 16) | (cw_max << 12) | + (cw_min << 8) | (params->aifs * + priv->slot_time + SIFS_TIME)); + } else { + if (queue != 0) + return -EINVAL; + + rtl818x_iowrite8(priv, &priv->map->CW_VAL, + cw_min | (cw_max << 4)); + } + return 0; +} + +static u64 rtl8187_get_tsf(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + +static const struct ieee80211_ops rtl8187_ops = { + .tx = rtl8187_tx, + .start = rtl8187_start, + .stop = rtl8187_stop, + .add_interface = rtl8187_add_interface, + .remove_interface = rtl8187_remove_interface, + .config = rtl8187_config, + .bss_info_changed = rtl8187_bss_info_changed, + .prepare_multicast = rtl8187_prepare_multicast, + .configure_filter = rtl8187_configure_filter, + .conf_tx = rtl8187_conf_tx, + .rfkill_poll = rtl8187_rfkill_poll, + .get_tsf = rtl8187_get_tsf, +}; + +static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = RTL818X_EEPROM_CMD_PROGRAM; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); + udelay(10); +} + +static int __devinit rtl8187_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct ieee80211_hw *dev; + struct rtl8187_priv *priv; + struct eeprom_93cx6 eeprom; + struct ieee80211_channel *channel; + const char *chip_name; + u16 txpwr, reg; + u16 product_id = le16_to_cpu(udev->descriptor.idProduct); + int err, i; + u8 mac_addr[ETH_ALEN]; + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); + if (!dev) { + printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n"); + return -ENOMEM; + } + + priv = dev->priv; + priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); + + /* allocate "DMA aware" buffer for register accesses */ + priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL); + if (!priv->io_dmabuf) { + err = -ENOMEM; + goto err_free_dev; + } + mutex_init(&priv->io_mutex); + + SET_IEEE80211_DEV(dev, &intf->dev); + usb_set_intfdata(intf, dev); + priv->udev = udev; + + usb_get_dev(udev); + + skb_queue_head_init(&priv->rx_queue); + + BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); + BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); + + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); + priv->map = (struct rtl818x_csr *)0xFF00; + + priv->band.band = IEEE80211_BAND_2GHZ; + priv->band.channels = priv->channels; + priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); + priv->band.bitrates = priv->rates; + priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); + dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; + + + dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_RX_INCLUDES_FCS; + + eeprom.data = dev; + eeprom.register_read = rtl8187_eeprom_register_read; + eeprom.register_write = rtl8187_eeprom_register_write; + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) + eeprom.width = PCI_EEPROM_WIDTH_93C66; + else + eeprom.width = PCI_EEPROM_WIDTH_93C46; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + udelay(10); + + eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, + (__le16 __force *)mac_addr, 3); + if (!is_valid_ether_addr(mac_addr)) { + printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " + "generated MAC address\n"); + random_ether_addr(mac_addr); + } + SET_IEEE80211_PERM_ADDR(dev, mac_addr); + + channel = priv->channels; + for (i = 0; i < 3; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, + &priv->txpwr_base); + + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); + /* 0 means asic B-cut, we should use SW 3 wire + * bit-by-bit banging for radio. 1 means we can use + * USB specific request to write radio registers */ + priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + if (!priv->is_rtl8187b) { + u32 reg32; + reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg32 &= RTL818X_TX_CONF_HWVER_MASK; + switch (reg32) { + case RTL818X_TX_CONF_R8187vD_B: + /* Some RTL8187B devices have a USB ID of 0x8187 + * detect them here */ + chip_name = "RTL8187BvB(early)"; + priv->is_rtl8187b = 1; + priv->hw_rev = RTL8187BvB; + break; + case RTL818X_TX_CONF_R8187vD: + chip_name = "RTL8187vD"; + break; + default: + chip_name = "RTL8187vB (default)"; + } + } else { + /* + * Force USB request to write radio registers for 8187B, Realtek + * only uses it in their sources + */ + /*if (priv->asic_rev == 0) { + printk(KERN_WARNING "rtl8187: Forcing use of USB " + "requests to write to radio registers\n"); + priv->asic_rev = 1; + }*/ + switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) { + case RTL818X_R8187B_B: + chip_name = "RTL8187BvB"; + priv->hw_rev = RTL8187BvB; + break; + case RTL818X_R8187B_D: + chip_name = "RTL8187BvD"; + priv->hw_rev = RTL8187BvD; + break; + case RTL818X_R8187B_E: + chip_name = "RTL8187BvE"; + priv->hw_rev = RTL8187BvE; + break; + default: + chip_name = "RTL8187BvB (default)"; + priv->hw_rev = RTL8187BvB; + } + } + + if (!priv->is_rtl8187b) { + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, + RTL8187_EEPROM_TXPWR_CHAN_6 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + } else { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + + eeprom_93cx6_read(&eeprom, 0x0A, &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + + eeprom_93cx6_read(&eeprom, 0x1C, &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + /* Handle the differing rfkill GPIO bit in different models */ + priv->rfkill_mask = RFKILL_MASK_8187_89_97; + if (product_id == 0x8197 || product_id == 0x8198) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®); + if (reg & 0xFF00) + priv->rfkill_mask = RFKILL_MASK_8198; + } + + /* + * XXX: Once this driver supports anything that requires + * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. + */ + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) + printk(KERN_INFO "rtl8187: inconsistency between id with OEM" + " info!\n"); + + priv->rf = rtl8187_detect_rf(dev); + dev->extra_tx_headroom = (!priv->is_rtl8187b) ? + sizeof(struct rtl8187_tx_hdr) : + sizeof(struct rtl8187b_tx_hdr); + if (!priv->is_rtl8187b) + dev->queues = 1; + else + dev->queues = 4; + + err = ieee80211_register_hw(dev); + if (err) { + printk(KERN_ERR "rtl8187: Cannot register device\n"); + goto err_free_dmabuf; + } + mutex_init(&priv->conf_mutex); + skb_queue_head_init(&priv->b_tx_status.queue); + + wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", + mac_addr, chip_name, priv->asic_rev, priv->rf->name, + priv->rfkill_mask); + +#ifdef CONFIG_RTL8187_LEDS + eeprom_93cx6_read(&eeprom, 0x3F, ®); + reg &= 0xFF; + rtl8187_leds_init(dev, reg); +#endif + rtl8187_rfkill_init(dev); + + return 0; + + err_free_dmabuf: + kfree(priv->io_dmabuf); + err_free_dev: + ieee80211_free_hw(dev); + usb_set_intfdata(intf, NULL); + usb_put_dev(udev); + return err; +} + +static void __devexit rtl8187_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *dev = usb_get_intfdata(intf); + struct rtl8187_priv *priv; + + if (!dev) + return; + +#ifdef CONFIG_RTL8187_LEDS + rtl8187_leds_exit(dev); +#endif + rtl8187_rfkill_exit(dev); + ieee80211_unregister_hw(dev); + + priv = dev->priv; + usb_reset_device(priv->udev); + usb_put_dev(interface_to_usbdev(intf)); + kfree(priv->io_dmabuf); + ieee80211_free_hw(dev); +} + +static struct usb_driver rtl8187_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8187_table, + .probe = rtl8187_probe, + .disconnect = __devexit_p(rtl8187_disconnect), +}; + +static int __init rtl8187_init(void) +{ + return usb_register(&rtl8187_driver); +} + +static void __exit rtl8187_exit(void) +{ + usb_deregister(&rtl8187_driver); +} + +module_init(rtl8187_init); +module_exit(rtl8187_exit); diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c new file mode 100644 index 000000000000..2e0de2f5f0f9 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c @@ -0,0 +1,245 @@ +/* + * Linux LED driver for RTL8187 + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifdef CONFIG_RTL8187_LEDS + +#include +#include +#include + +#include "rtl8187.h" +#include "leds.h" + +static void led_turn_on(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_on.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +static void led_turn_off(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_off.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +/* Callback from the LED subsystem. */ +static void rtl8187_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, + led_dev); + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv; + static bool radio_on; + + if (!hw) + return; + priv = hw->priv; + if (led->is_radio) { + if (brightness == LED_FULL) { + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + radio_on = true; + } else if (radio_on) { + radio_on = false; + cancel_delayed_work_sync(&priv->led_on); + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + } + } else if (radio_on) { + if (brightness == LED_OFF) { + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + /* The LED is off for 1/20 sec - it just blinks. */ + ieee80211_queue_delayed_work(hw, &priv->led_on, + HZ / 20); + } else + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + } +} + +static int rtl8187_register_led(struct ieee80211_hw *dev, + struct rtl8187_led *led, const char *name, + const char *default_trigger, u8 ledpin, + bool is_radio) +{ + int err; + struct rtl8187_priv *priv = dev->priv; + + if (led->dev) + return -EEXIST; + if (!default_trigger) + return -EINVAL; + led->dev = dev; + led->ledpin = ledpin; + led->is_radio = is_radio; + strncpy(led->name, name, sizeof(led->name)); + + led->led_dev.name = led->name; + led->led_dev.default_trigger = default_trigger; + led->led_dev.brightness_set = rtl8187_led_brightness_set; + + err = led_classdev_register(&priv->udev->dev, &led->led_dev); + if (err) { + printk(KERN_INFO "LEDs: Failed to register %s\n", name); + led->dev = NULL; + return err; + } + return 0; +} + +static void rtl8187_unregister_led(struct rtl8187_led *led) +{ + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv = hw->priv; + + led_classdev_unregister(&led->led_dev); + flush_delayed_work(&priv->led_off); + led->dev = NULL; +} + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) +{ + struct rtl8187_priv *priv = dev->priv; + char name[RTL8187_LED_MAX_NAME_LEN + 1]; + u8 ledpin; + int err; + + /* According to the vendor driver, the LED operation depends on the + * customer ID encoded in the EEPROM + */ + printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid); + switch (custid) { + case EEPROM_CID_RSVD0: + case EEPROM_CID_RSVD1: + case EEPROM_CID_SERCOMM_PS: + case EEPROM_CID_QMI: + case EEPROM_CID_DELL: + case EEPROM_CID_TOSHIBA: + ledpin = LED_PIN_GPIO0; + break; + case EEPROM_CID_ALPHA0: + ledpin = LED_PIN_LED0; + break; + case EEPROM_CID_HW: + ledpin = LED_PIN_HW; + break; + default: + ledpin = LED_PIN_GPIO0; + } + + INIT_DELAYED_WORK(&priv->led_on, led_turn_on); + INIT_DELAYED_WORK(&priv->led_off, led_turn_off); + + snprintf(name, sizeof(name), + "rtl8187-%s::radio", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_radio, name, + ieee80211_get_radio_led_name(dev), ledpin, true); + if (err) + return; + + snprintf(name, sizeof(name), + "rtl8187-%s::tx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_tx, name, + ieee80211_get_tx_led_name(dev), ledpin, false); + if (err) + goto err_tx; + + snprintf(name, sizeof(name), + "rtl8187-%s::rx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_rx, name, + ieee80211_get_rx_led_name(dev), ledpin, false); + if (!err) + return; + + /* registration of RX LED failed - unregister */ + rtl8187_unregister_led(&priv->led_tx); +err_tx: + rtl8187_unregister_led(&priv->led_radio); +} + +void rtl8187_leds_exit(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + + rtl8187_unregister_led(&priv->led_radio); + rtl8187_unregister_led(&priv->led_rx); + rtl8187_unregister_led(&priv->led_tx); + cancel_delayed_work_sync(&priv->led_off); + cancel_delayed_work_sync(&priv->led_on); +} +#endif /* def CONFIG_RTL8187_LEDS */ + diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.h b/drivers/net/wireless/rtl818x/rtl8187/leds.h new file mode 100644 index 000000000000..d743c96d4a20 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/leds.h @@ -0,0 +1,59 @@ +/* + * Definitions for RTL8187 leds + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. 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 version 2 as + * published by the Free Software Foundation. + */ + +#ifndef RTL8187_LED_H +#define RTL8187_LED_H + +#ifdef CONFIG_RTL8187_LEDS + +#define RTL8187_LED_MAX_NAME_LEN 21 + +#include +#include + +enum { + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_GPIO0, + LED_PIN_HW +}; + +enum { + EEPROM_CID_RSVD0 = 0x00, + EEPROM_CID_RSVD1 = 0xFF, + EEPROM_CID_ALPHA0 = 0x01, + EEPROM_CID_SERCOMM_PS = 0x02, + EEPROM_CID_HW = 0x03, + EEPROM_CID_TOSHIBA = 0x04, + EEPROM_CID_QMI = 0x07, + EEPROM_CID_DELL = 0x08 +}; + +struct rtl8187_led { + struct ieee80211_hw *dev; + /* The LED class device */ + struct led_classdev led_dev; + /* The pin/method used to control the led */ + u8 ledpin; + /* The unique name string for this LED device. */ + char name[RTL8187_LED_MAX_NAME_LEN + 1]; + /* If the LED is radio or tx/rx */ + bool is_radio; +}; + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); +void rtl8187_leds_exit(struct ieee80211_hw *dev); + +#endif /* def CONFIG_RTL8187_LEDS */ + +#endif /* RTL8187_LED_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.c b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c new file mode 100644 index 000000000000..34116719974a --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c @@ -0,0 +1,64 @@ +/* + * Linux RFKILL support for RTL8187 + * + * Copyright (c) 2009 Herton Ronaldo Krzesinski + * + * Based on the RFKILL handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "rtl8187.h" +#include "rfkill.h" + +static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) +{ + u8 gpio; + + gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask); + gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); + + return gpio & priv->rfkill_mask; +} + +void rtl8187_rfkill_init(struct ieee80211_hw *hw) +{ + struct rtl8187_priv *priv = hw->priv; + + priv->rfkill_off = rtl8187_is_radio_enabled(priv); + printk(KERN_INFO "rtl8187: wireless switch is %s\n", + priv->rfkill_off ? "on" : "off"); + wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off); + wiphy_rfkill_start_polling(hw->wiphy); +} + +void rtl8187_rfkill_poll(struct ieee80211_hw *hw) +{ + bool enabled; + struct rtl8187_priv *priv = hw->priv; + + mutex_lock(&priv->conf_mutex); + enabled = rtl8187_is_radio_enabled(priv); + if (unlikely(enabled != priv->rfkill_off)) { + priv->rfkill_off = enabled; + printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n", + enabled ? "on" : "off"); + wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); + } + mutex_unlock(&priv->conf_mutex); +} + +void rtl8187_rfkill_exit(struct ieee80211_hw *hw) +{ + wiphy_rfkill_stop_polling(hw->wiphy); +} diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.h b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h new file mode 100644 index 000000000000..e12575e96d11 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h @@ -0,0 +1,8 @@ +#ifndef RTL8187_RFKILL_H +#define RTL8187_RFKILL_H + +void rtl8187_rfkill_init(struct ieee80211_hw *hw); +void rtl8187_rfkill_poll(struct ieee80211_hw *hw); +void rtl8187_rfkill_exit(struct ieee80211_hw *hw); + +#endif /* RTL8187_RFKILL_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h new file mode 100644 index 000000000000..0d7b1423f77b --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h @@ -0,0 +1,271 @@ +/* + * Definitions for RTL8187 hardware + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef RTL8187_H +#define RTL8187_H + +#include "rtl818x.h" +#include "leds.h" + +#define RTL8187_EEPROM_TXPWR_BASE 0x05 +#define RTL8187_EEPROM_MAC_ADDR 0x07 +#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ +#define RTL8187_EEPROM_SELECT_GPIO 0x3B + +#define RTL8187_REQT_READ 0xC0 +#define RTL8187_REQT_WRITE 0x40 +#define RTL8187_REQ_GET_REG 0x05 +#define RTL8187_REQ_SET_REG 0x05 + +#define RTL8187_MAX_RX 0x9C4 + +#define RFKILL_MASK_8187_89_97 0x2 +#define RFKILL_MASK_8198 0x4 + +struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +}; + +struct rtl8187_rx_hdr { + __le32 flags; + u8 noise; + u8 signal; + u8 agc; + u8 reserved; + __le64 mac_time; +} __packed; + +struct rtl8187b_rx_hdr { + __le32 flags; + __le64 mac_time; + u8 sq; + u8 rssi; + u8 agc; + u8 flags2; + __le16 snr_long2end; + s8 pwdb_g12; + u8 fot; +} __packed; + +/* {rtl8187,rtl8187b}_tx_info is in skb */ + +struct rtl8187_tx_hdr { + __le32 flags; + __le16 rts_duration; + __le16 len; + __le32 retry; +} __packed; + +struct rtl8187b_tx_hdr { + __le32 flags; + __le16 rts_duration; + __le16 len; + __le32 unused_1; + __le16 unused_2; + __le16 tx_duration; + __le32 unused_3; + __le32 retry; + __le32 unused_4[2]; +} __packed; + +enum { + DEVICE_RTL8187, + DEVICE_RTL8187B +}; + +struct rtl8187_priv { + /* common between rtl818x drivers */ + struct rtl818x_csr *map; + const struct rtl818x_rf_ops *rf; + struct ieee80211_vif *vif; + + /* The mutex protects the TX loopback state. + * Any attempt to set channels concurrently locks the device. + */ + struct mutex conf_mutex; + + /* rtl8187 specific */ + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_supported_band band; + struct usb_device *udev; + u32 rx_conf; + struct usb_anchor anchored; + struct delayed_work work; + struct ieee80211_hw *dev; +#ifdef CONFIG_RTL8187_LEDS + struct rtl8187_led led_radio; + struct rtl8187_led led_tx; + struct rtl8187_led led_rx; + struct delayed_work led_on; + struct delayed_work led_off; +#endif + u16 txpwr_base; + u8 asic_rev; + u8 is_rtl8187b; + enum { + RTL8187BvB, + RTL8187BvD, + RTL8187BvE + } hw_rev; + struct sk_buff_head rx_queue; + u8 signal; + u8 noise; + u8 slot_time; + u8 aifsn[4]; + u8 rfkill_mask; + struct { + __le64 buf; + struct sk_buff_head queue; + } b_tx_status; /* This queue is used by both -b and non-b devices */ + struct mutex io_mutex; + union { + u8 bits8; + __le16 bits16; + __le32 bits32; + } *io_dmabuf; + bool rfkill_off; +}; + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); + +static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 idx) +{ + u8 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits8; + mutex_unlock(&priv->io_mutex); + + return val; +} + +static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr) +{ + return rtl818x_ioread8_idx(priv, addr, 0); +} + +static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, + __le16 *addr, u8 idx) +{ + __le16 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits16; + mutex_unlock(&priv->io_mutex); + + return le16_to_cpu(val); +} + +static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr) +{ + return rtl818x_ioread16_idx(priv, addr, 0); +} + +static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, + __le32 *addr, u8 idx) +{ + __le32 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits32; + mutex_unlock(&priv->io_mutex); + + return le32_to_cpu(val); +} + +static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) +{ + return rtl818x_ioread32_idx(priv, addr, 0); +} + +static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits8 = val; + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); +} + +static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) +{ + rtl818x_iowrite8_idx(priv, addr, val, 0); +} + +static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, + __le16 *addr, u16 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits16 = cpu_to_le16(val); + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); +} + +static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, + u16 val) +{ + rtl818x_iowrite16_idx(priv, addr, val, 0); +} + +static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, + __le32 *addr, u32 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits32 = cpu_to_le32(val); + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); +} + +static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, + u32 val) +{ + rtl818x_iowrite32_idx(priv, addr, val, 0); +} + +#endif /* RTL8187_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c new file mode 100644 index 000000000000..908903f721f5 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c @@ -0,0 +1,961 @@ +/* + * Radio tuning for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Magic delays, register offsets, and phy value tables below are + * taken from the original r8187 driver sources. Thanks to Realtek + * for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8225.h" + +static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg84, reg82; + u32 bangdata; + int i; + + bangdata = (data << 4) | (addr & 0xf); + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); + + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + for (i = 15; i >= 0; i--) { + u16 reg = reg80 | (bangdata & (1 << i)) >> i; + + if (i & 1) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + + if (!(i & 1)) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); +} + +static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~(0x3 << 2); + reg84 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits16 = data; + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), + HZ / 2); + + mutex_unlock(&priv->io_mutex); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); +} + +static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + + if (priv->asic_rev) + rtl8225_write_8051(dev, addr, cpu_to_le16(data)); + else + rtl8225_write_bitbang(dev, addr, data); +} + +static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84, out; + int i; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(4); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(5); + + for (i = 4; i >= 0; i--) { + u16 reg = reg80 | ((addr >> i) & 1); + + if (!(i & 1)) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + + if (i & 1) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + + out = 0; + for (i = 11; i >= 0; i--) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(1); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) + out |= 1 << i; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); + + return out; +} + +static const u16 rtl8225bcd_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb +}; + +static const u8 rtl8225_agc[] = { + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const u8 rtl8225_gain[] = { + 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */ + 0x33, 0x80, 0x79, 0xc5, /* -78dBm */ + 0x43, 0x78, 0x76, 0xc5, /* -74dBm */ + 0x53, 0x60, 0x73, 0xc5, /* -70dBm */ + 0x63, 0x58, 0x70, 0xc5, /* -66dBm */ +}; + +static const u8 rtl8225_threshold[] = { + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd +}; + +static const u8 rtl8225_tx_gain_cck_ofdm[] = { + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e +}; + +static const u8 rtl8225_tx_power_cck[] = { + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 +}; + +static const u8 rtl8225_tx_power_cck_ch14[] = { + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225_tx_power_ofdm[] = { + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 +}; + +static const u32 rtl8225_chan[] = { + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 +}; + +static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power = min(cck_power, (u8)11); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); + + if (channel == 14) + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; + else + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + msleep(1); // FIXME: optional? + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, + RTL8187_RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 6, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x00); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1); + + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; + + rtl8225_write_phy_ofdm(dev, 5, *tmp); + rtl8225_write_phy_ofdm(dev, 7, *tmp); + + msleep(1); +} + +static void rtl8225_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x067); + rtl8225_write(dev, 0x1, 0xFE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x486); + rtl8225_write(dev, 0x5, 0xBC0); + rtl8225_write(dev, 0x6, 0xAE6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x01F); + rtl8225_write(dev, 0x9, 0x334); + rtl8225_write(dev, 0xA, 0xFD4); + rtl8225_write(dev, 0xB, 0x391); + rtl8225_write(dev, 0xC, 0x050); + rtl8225_write(dev, 0xD, 0x6DB); + rtl8225_write(dev, 0xE, 0x029); + rtl8225_write(dev, 0xF, 0x914); msleep(100); + + rtl8225_write(dev, 0x2, 0xC4D); msleep(200); + rtl8225_write(dev, 0x2, 0x44D); msleep(200); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0c4d); + msleep(200); + rtl8225_write(dev, 0x02, 0x044d); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", + rtl8225_read(dev, 6)); + } + + rtl8225_write(dev, 0x0, 0x127); + + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x027); + rtl8225_write(dev, 0x0, 0x22F); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); + + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); + rtl8225_write_phy_cck(dev, 0x03, 0x20); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); + rtl8225_write_phy_cck(dev, 0x05, 0x12); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); + rtl8225_write_phy_cck(dev, 0x07, 0x78); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); + rtl8225_write_phy_cck(dev, 0x11, 0x88); + rtl8225_write_phy_cck(dev, 0x12, 0x47); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); + rtl8225_write_phy_cck(dev, 0x42, 0x15); + rtl8225_write_phy_cck(dev, 0x43, 0x18); + rtl8225_write_phy_cck(dev, 0x44, 0x1f); + rtl8225_write_phy_cck(dev, 0x45, 0x1e); + rtl8225_write_phy_cck(dev, 0x46, 0x1a); + rtl8225_write_phy_cck(dev, 0x47, 0x15); + rtl8225_write_phy_cck(dev, 0x48, 0x10); + rtl8225_write_phy_cck(dev, 0x49, 0x0a); + rtl8225_write_phy_cck(dev, 0x4a, 0x05); + rtl8225_write_phy_cck(dev, 0x4b, 0x02); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); + + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); + + rtl8225_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); + + /* set sensitivity */ + rtl8225_write(dev, 0x0c, 0x50); + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); +} + +static const u8 rtl8225z2_agc[] = { + 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f, + 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37, + 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, + 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07, + 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, + 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, + 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 +}; +static const u8 rtl8225z2_ofdm[] = { + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26, + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3, + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f, + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, + 0x6d, 0x3c, 0xfb, 0x07 +}; + +static const u8 rtl8225z2_tx_power_cck_ch14[] = { + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225z2_tx_power_cck[] = { + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04, + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 +}; + +static const u8 rtl8225z2_tx_power_ofdm[] = { + 0x42, 0x00, 0x40, 0x00, 0x40 +}; + +static const u8 rtl8225z2_tx_gain_cck_ofdm[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 +}; + +static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power = min(cck_power, (u8)15); + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; + ofdm_power += priv->txpwr_base >> 4; + ofdm_power = min(ofdm_power, (u8)35); + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else + tmp = rtl8225z2_tx_power_cck; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225z2_tx_gain_cck_ofdm[cck_power]); + msleep(1); + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, + RTL8187_RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 5, 0x00); + rtl8225_write_phy_ofdm(dev, 6, 0x40); + rtl8225_write_phy_ofdm(dev, 7, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x40); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225z2_tx_gain_cck_ofdm[ofdm_power]); + msleep(1); +} + +static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + if (cck_power > 15) + cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22; + else + cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + + if (ofdm_power > 15) + ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25; + else + ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10; + ofdm_power += (priv->txpwr_base >> 4) & 0xF; + ofdm_power = min(ofdm_power, (u8)35); + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else + tmp = rtl8225z2_tx_power_cck; + + if (priv->hw_rev == RTL8187BvB) { + if (cck_power <= 6) + ; /* do nothing */ + else if (cck_power <= 11) + tmp += 8; + else + tmp += 16; + } else { + if (cck_power <= 5) + ; /* do nothing */ + else if (cck_power <= 11) + tmp += 8; + else if (cck_power <= 17) + tmp += 16; + else + tmp += 24; + } + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1); + msleep(1); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1); + if (priv->hw_rev == RTL8187BvB) { + if (ofdm_power <= 11) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x60); + rtl8225_write_phy_ofdm(dev, 0x89, 0x60); + } else { + rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); + rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); + } + } else { + if (ofdm_power <= 11) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); + rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); + } else if (ofdm_power <= 17) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x54); + rtl8225_write_phy_ofdm(dev, 0x89, 0x54); + } else { + rtl8225_write_phy_ofdm(dev, 0x87, 0x50); + rtl8225_write_phy_ofdm(dev, 0x89, 0x50); + } + } + msleep(1); +} + +static const u16 rtl8225z2_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb +}; + +static const u8 rtl8225z2_gain_bg[] = { + 0x23, 0x15, 0xa5, /* -82-1dBm */ + 0x23, 0x15, 0xb5, /* -82-2dBm */ + 0x23, 0x15, 0xc5, /* -82-3dBm */ + 0x33, 0x15, 0xc5, /* -78dBm */ + 0x43, 0x15, 0xc5, /* -74dBm */ + 0x53, 0x15, 0xc5, /* -70dBm */ + 0x63, 0x15, 0xc5 /* -66dBm */ +}; + +static void rtl8225z2_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x2BF); + rtl8225_write(dev, 0x1, 0xEE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8C3); + rtl8225_write(dev, 0x5, 0xC72); + rtl8225_write(dev, 0x6, 0x0E6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x03F); + rtl8225_write(dev, 0x9, 0x335); + rtl8225_write(dev, 0xa, 0x9D4); + rtl8225_write(dev, 0xb, 0x7BB); + rtl8225_write(dev, 0xc, 0x850); + rtl8225_write(dev, 0xd, 0xCDF); + rtl8225_write(dev, 0xe, 0x02B); + rtl8225_write(dev, 0xf, 0x114); + msleep(100); + + rtl8225_write(dev, 0x0, 0x1B7); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x3, 0x080); + rtl8225_write(dev, 0x5, 0x004); + rtl8225_write(dev, 0x0, 0x0B7); + rtl8225_write(dev, 0x2, 0xc4D); + + msleep(200); + rtl8225_write(dev, 0x2, 0x44D); + msleep(100); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0C4D); + msleep(200); + rtl8225_write(dev, 0x02, 0x044D); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", + rtl8225_read(dev, 6)); + } + + msleep(200); + + rtl8225_write(dev, 0x0, 0x2BF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); + rtl8225_write_phy_ofdm(dev, 0x11, 0x07); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); + rtl8225_write_phy_ofdm(dev, 0x21, 0x17); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); + rtl8225_write_phy_ofdm(dev, 0x25, 0x00); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); + + rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); + rtl8225_write_phy_ofdm(dev, 0x21, 0x37); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); + rtl8225_write_phy_cck(dev, 0x03, 0x20); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); + rtl8225_write_phy_cck(dev, 0x05, 0x12); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); + rtl8225_write_phy_cck(dev, 0x07, 0x78); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); + rtl8225_write_phy_cck(dev, 0x11, 0x88); + rtl8225_write_phy_cck(dev, 0x12, 0x47); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); + rtl8225_write_phy_cck(dev, 0x42, 0x15); + rtl8225_write_phy_cck(dev, 0x43, 0x18); + rtl8225_write_phy_cck(dev, 0x44, 0x36); + rtl8225_write_phy_cck(dev, 0x45, 0x35); + rtl8225_write_phy_cck(dev, 0x46, 0x2e); + rtl8225_write_phy_cck(dev, 0x47, 0x25); + rtl8225_write_phy_cck(dev, 0x48, 0x1c); + rtl8225_write_phy_cck(dev, 0x49, 0x12); + rtl8225_write_phy_cck(dev, 0x4a, 0x09); + rtl8225_write_phy_cck(dev, 0x4b, 0x04); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); + + rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); + + rtl8225z2_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); +} + +static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x0B7); + rtl8225_write(dev, 0x1, 0xEE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8C3); + rtl8225_write(dev, 0x5, 0xC72); + rtl8225_write(dev, 0x6, 0x0E6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x03F); + rtl8225_write(dev, 0x9, 0x335); + rtl8225_write(dev, 0xa, 0x9D4); + rtl8225_write(dev, 0xb, 0x7BB); + rtl8225_write(dev, 0xc, 0x850); + rtl8225_write(dev, 0xd, 0xCDF); + rtl8225_write(dev, 0xe, 0x02B); + rtl8225_write(dev, 0xf, 0x114); + + rtl8225_write(dev, 0x0, 0x1B7); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x3, 0x080); + rtl8225_write(dev, 0x5, 0x004); + rtl8225_write(dev, 0x0, 0x0B7); + + rtl8225_write(dev, 0x2, 0xC4D); + + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x0, 0x2BF); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03); + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07); + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); + + rtl8225_write_phy_ofdm(dev, 0x80, 0x12); + for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i); + rtl8225_write_phy_ofdm(dev, 0xE, 0); + } + rtl8225_write_phy_ofdm(dev, 0x80, 0x10); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) + rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]); + + rtl8225_write_phy_ofdm(dev, 0x97, 0x46); + rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); + rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); + rtl8225_write_phy_cck(dev, 0xc1, 0x88); +} + +static void rtl8225_rf_stop(struct ieee80211_hw *dev) +{ + rtl8225_write(dev, 0x4, 0x1f); +} + +static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); + + if (priv->rf->init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, chan); + else if (priv->rf->init == rtl8225z2_rf_init) + rtl8225z2_rf_set_tx_power(dev, chan); + else + rtl8225z2_b_rf_set_tx_power(dev, chan); + + rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); + msleep(10); +} + +static const struct rtl818x_rf_ops rtl8225_ops = { + .name = "rtl8225", + .init = rtl8225_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +static const struct rtl818x_rf_ops rtl8225z2_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +static const struct rtl818x_rf_ops rtl8225z2_b_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_b_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) +{ + u16 reg8, reg9; + struct rtl8187_priv *priv = dev->priv; + + if (!priv->is_rtl8187b) { + rtl8225_write(dev, 0, 0x1B7); + + reg8 = rtl8225_read(dev, 8); + reg9 = rtl8225_read(dev, 9); + + rtl8225_write(dev, 0, 0x0B7); + + if (reg8 != 0x588 || reg9 != 0x700) + return &rtl8225_ops; + + return &rtl8225z2_ops; + } else + return &rtl8225z2_b_ops; +} diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h new file mode 100644 index 000000000000..20c5b6ead0f6 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h @@ -0,0 +1,44 @@ +/* + * Radio tuning definitions for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef RTL8187_RTL8225_H +#define RTL8187_RTL8225_H + +#define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59 +#define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312 +#define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11 + +#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658 +#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52 +#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00 +#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658 +#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50 +#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00 + +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); + +static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data); +} + +static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data | 0x10000); +} + +#endif /* RTL8187_RTL8225_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c deleted file mode 100644 index eeee244fcaab..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ /dev/null @@ -1,1591 +0,0 @@ -/* - * Linux device driver for RTL8187 - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8187 driver, which is: - * Copyright 2005 Andrea Merello , et al. - * - * The driver was extended to the RTL8187B in 2008 by: - * Herton Ronaldo Krzesinski - * Hin-Tak Leung - * Larry Finger - * - * Magic delays and register offsets below are taken from the original - * r8187 driver sources. Thanks to Realtek for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "rtl8187.h" -#include "rtl8187_rtl8225.h" -#ifdef CONFIG_RTL8187_LEDS -#include "rtl8187_leds.h" -#endif -#include "rtl8187_rfkill.h" - -MODULE_AUTHOR("Michael Wu "); -MODULE_AUTHOR("Andrea Merello "); -MODULE_AUTHOR("Herton Ronaldo Krzesinski "); -MODULE_AUTHOR("Hin-Tak Leung "); -MODULE_AUTHOR("Larry Finger "); -MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); -MODULE_LICENSE("GPL"); - -static struct usb_device_id rtl8187_table[] __devinitdata = { - /* Asus */ - {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, - /* Belkin */ - {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B}, - /* Realtek */ - {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, - {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, - {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, - {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, - /* Surecom */ - {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, - /* Logitech */ - {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, - /* Netgear */ - {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, - {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, - {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B}, - /* HP */ - {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, - /* Sitecom */ - {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, - {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, - {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B}, - /* Sphairon Access Systems GmbH */ - {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, - /* Dick Smith Electronics */ - {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, - /* Abocom */ - {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, - /* Qcom */ - {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, - /* AirLive */ - {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, - /* Linksys */ - {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, - {} -}; - -MODULE_DEVICE_TABLE(usb, rtl8187_table); - -static const struct ieee80211_rate rtl818x_rates[] = { - { .bitrate = 10, .hw_value = 0, }, - { .bitrate = 20, .hw_value = 1, }, - { .bitrate = 55, .hw_value = 2, }, - { .bitrate = 110, .hw_value = 3, }, - { .bitrate = 60, .hw_value = 4, }, - { .bitrate = 90, .hw_value = 5, }, - { .bitrate = 120, .hw_value = 6, }, - { .bitrate = 180, .hw_value = 7, }, - { .bitrate = 240, .hw_value = 8, }, - { .bitrate = 360, .hw_value = 9, }, - { .bitrate = 480, .hw_value = 10, }, - { .bitrate = 540, .hw_value = 11, }, -}; - -static const struct ieee80211_channel rtl818x_channels[] = { - { .center_freq = 2412 }, - { .center_freq = 2417 }, - { .center_freq = 2422 }, - { .center_freq = 2427 }, - { .center_freq = 2432 }, - { .center_freq = 2437 }, - { .center_freq = 2442 }, - { .center_freq = 2447 }, - { .center_freq = 2452 }, - { .center_freq = 2457 }, - { .center_freq = 2462 }, - { .center_freq = 2467 }, - { .center_freq = 2472 }, - { .center_freq = 2484 }, -}; - -static void rtl8187_iowrite_async_cb(struct urb *urb) -{ - kfree(urb->context); -} - -static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, - void *data, u16 len) -{ - struct usb_ctrlrequest *dr; - struct urb *urb; - struct rtl8187_async_write_data { - u8 data[4]; - struct usb_ctrlrequest dr; - } *buf; - int rc; - - buf = kmalloc(sizeof(*buf), GFP_ATOMIC); - if (!buf) - return; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - kfree(buf); - return; - } - - dr = &buf->dr; - - dr->bRequestType = RTL8187_REQT_WRITE; - dr->bRequest = RTL8187_REQ_SET_REG; - dr->wValue = addr; - dr->wIndex = 0; - dr->wLength = cpu_to_le16(len); - - memcpy(buf, data, len); - - usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), - (unsigned char *)dr, buf, len, - rtl8187_iowrite_async_cb, buf); - usb_anchor_urb(urb, &priv->anchored); - rc = usb_submit_urb(urb, GFP_ATOMIC); - if (rc < 0) { - kfree(buf); - usb_unanchor_urb(urb); - } - usb_free_urb(urb); -} - -static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, - __le32 *addr, u32 val) -{ - __le32 buf = cpu_to_le32(val); - - rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr), - &buf, sizeof(buf)); -} - -void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) -{ - struct rtl8187_priv *priv = dev->priv; - - data <<= 8; - data |= addr | 0x80; - - rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF); - rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF); - rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF); - rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF); -} - -static void rtl8187_tx_cb(struct urb *urb) -{ - struct sk_buff *skb = (struct sk_buff *)urb->context; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hw *hw = info->rate_driver_data[0]; - struct rtl8187_priv *priv = hw->priv; - - skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : - sizeof(struct rtl8187_tx_hdr)); - ieee80211_tx_info_clear_status(info); - - if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - if (priv->is_rtl8187b) { - skb_queue_tail(&priv->b_tx_status.queue, skb); - - /* queue is "full", discard last items */ - while (skb_queue_len(&priv->b_tx_status.queue) > 5) { - struct sk_buff *old_skb; - - dev_dbg(&priv->udev->dev, - "transmit status queue full\n"); - - old_skb = skb_dequeue(&priv->b_tx_status.queue); - ieee80211_tx_status_irqsafe(hw, old_skb); - } - return; - } else { - info->flags |= IEEE80211_TX_STAT_ACK; - } - } - if (priv->is_rtl8187b) - ieee80211_tx_status_irqsafe(hw, skb); - else { - /* Retry information for the RTI8187 is only available by - * reading a register in the device. We are in interrupt mode - * here, thus queue the skb and finish on a work queue. */ - skb_queue_tail(&priv->b_tx_status.queue, skb); - ieee80211_queue_delayed_work(hw, &priv->work, 0); - } -} - -static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) -{ - struct rtl8187_priv *priv = dev->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int ep; - void *buf; - struct urb *urb; - __le16 rts_dur = 0; - u32 flags; - int rc; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - - flags = skb->len; - flags |= RTL818X_TX_DESC_FLAG_NO_ENC; - - flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; - if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) - flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - flags |= RTL818X_TX_DESC_FLAG_RTS; - flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; - rts_dur = ieee80211_rts_duration(dev, priv->vif, - skb->len, info); - } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - flags |= RTL818X_TX_DESC_FLAG_CTS; - flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; - } - - if (!priv->is_rtl8187b) { - struct rtl8187_tx_hdr *hdr = - (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); - hdr->flags = cpu_to_le32(flags); - hdr->len = 0; - hdr->rts_duration = rts_dur; - hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); - buf = hdr; - - ep = 2; - } else { - /* fc needs to be calculated before skb_push() */ - unsigned int epmap[4] = { 6, 7, 5, 4 }; - struct ieee80211_hdr *tx_hdr = - (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(tx_hdr->frame_control); - - struct rtl8187b_tx_hdr *hdr = - (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr)); - struct ieee80211_rate *txrate = - ieee80211_get_tx_rate(dev, info); - memset(hdr, 0, sizeof(*hdr)); - hdr->flags = cpu_to_le32(flags); - hdr->rts_duration = rts_dur; - hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); - hdr->tx_duration = - ieee80211_generic_frame_duration(dev, priv->vif, - skb->len, txrate); - buf = hdr; - - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) - ep = 12; - else - ep = epmap[skb_get_queue_mapping(skb)]; - } - - info->rate_driver_data[0] = dev; - info->rate_driver_data[1] = urb; - - usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), - buf, skb->len, rtl8187_tx_cb, skb); - urb->transfer_flags |= URB_ZERO_PACKET; - usb_anchor_urb(urb, &priv->anchored); - rc = usb_submit_urb(urb, GFP_ATOMIC); - if (rc < 0) { - usb_unanchor_urb(urb); - kfree_skb(skb); - } - usb_free_urb(urb); - - return NETDEV_TX_OK; -} - -static void rtl8187_rx_cb(struct urb *urb) -{ - struct sk_buff *skb = (struct sk_buff *)urb->context; - struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; - struct ieee80211_hw *dev = info->dev; - struct rtl8187_priv *priv = dev->priv; - struct ieee80211_rx_status rx_status = { 0 }; - int rate, signal; - u32 flags; - unsigned long f; - - spin_lock_irqsave(&priv->rx_queue.lock, f); - __skb_unlink(skb, &priv->rx_queue); - spin_unlock_irqrestore(&priv->rx_queue.lock, f); - skb_put(skb, urb->actual_length); - - if (unlikely(urb->status)) { - dev_kfree_skb_irq(skb); - return; - } - - if (!priv->is_rtl8187b) { - struct rtl8187_rx_hdr *hdr = - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); - flags = le32_to_cpu(hdr->flags); - /* As with the RTL8187B below, the AGC is used to calculate - * signal strength. In this case, the scaling - * constants are derived from the output of p54usb. - */ - signal = -4 - ((27 * hdr->agc) >> 6); - rx_status.antenna = (hdr->signal >> 7) & 1; - rx_status.mactime = le64_to_cpu(hdr->mac_time); - } else { - struct rtl8187b_rx_hdr *hdr = - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); - /* The Realtek datasheet for the RTL8187B shows that the RX - * header contains the following quantities: signal quality, - * RSSI, AGC, the received power in dB, and the measured SNR. - * In testing, none of these quantities show qualitative - * agreement with AP signal strength, except for the AGC, - * which is inversely proportional to the strength of the - * signal. In the following, the signal strength - * is derived from the AGC. The arbitrary scaling constants - * are chosen to make the results close to the values obtained - * for a BCM4312 using b43 as the driver. The noise is ignored - * for now. - */ - flags = le32_to_cpu(hdr->flags); - signal = 14 - hdr->agc / 2; - rx_status.antenna = (hdr->rssi >> 7) & 1; - rx_status.mactime = le64_to_cpu(hdr->mac_time); - } - - rx_status.signal = signal; - priv->signal = signal; - rate = (flags >> 20) & 0xF; - skb_trim(skb, flags & 0x0FFF); - rx_status.rate_idx = rate; - rx_status.freq = dev->conf.channel->center_freq; - rx_status.band = dev->conf.channel->band; - rx_status.flag |= RX_FLAG_TSFT; - if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(dev, skb); - - skb = dev_alloc_skb(RTL8187_MAX_RX); - if (unlikely(!skb)) { - /* TODO check rx queue length and refill *somewhere* */ - return; - } - - info = (struct rtl8187_rx_info *)skb->cb; - info->urb = urb; - info->dev = dev; - urb->transfer_buffer = skb_tail_pointer(skb); - urb->context = skb; - skb_queue_tail(&priv->rx_queue, skb); - - usb_anchor_urb(urb, &priv->anchored); - if (usb_submit_urb(urb, GFP_ATOMIC)) { - usb_unanchor_urb(urb); - skb_unlink(skb, &priv->rx_queue); - dev_kfree_skb_irq(skb); - } -} - -static int rtl8187_init_urbs(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - struct urb *entry = NULL; - struct sk_buff *skb; - struct rtl8187_rx_info *info; - int ret = 0; - - while (skb_queue_len(&priv->rx_queue) < 16) { - skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); - if (!skb) { - ret = -ENOMEM; - goto err; - } - entry = usb_alloc_urb(0, GFP_KERNEL); - if (!entry) { - ret = -ENOMEM; - goto err; - } - usb_fill_bulk_urb(entry, priv->udev, - usb_rcvbulkpipe(priv->udev, - priv->is_rtl8187b ? 3 : 1), - skb_tail_pointer(skb), - RTL8187_MAX_RX, rtl8187_rx_cb, skb); - info = (struct rtl8187_rx_info *)skb->cb; - info->urb = entry; - info->dev = dev; - skb_queue_tail(&priv->rx_queue, skb); - usb_anchor_urb(entry, &priv->anchored); - ret = usb_submit_urb(entry, GFP_KERNEL); - if (ret) { - skb_unlink(skb, &priv->rx_queue); - usb_unanchor_urb(entry); - goto err; - } - usb_free_urb(entry); - } - return ret; - -err: - usb_free_urb(entry); - kfree_skb(skb); - usb_kill_anchored_urbs(&priv->anchored); - return ret; -} - -static void rtl8187b_status_cb(struct urb *urb) -{ - struct ieee80211_hw *hw = (struct ieee80211_hw *)urb->context; - struct rtl8187_priv *priv = hw->priv; - u64 val; - unsigned int cmd_type; - - if (unlikely(urb->status)) - return; - - /* - * Read from status buffer: - * - * bits [30:31] = cmd type: - * - 0 indicates tx beacon interrupt - * - 1 indicates tx close descriptor - * - * In the case of tx beacon interrupt: - * [0:9] = Last Beacon CW - * [10:29] = reserved - * [30:31] = 00b - * [32:63] = Last Beacon TSF - * - * If it's tx close descriptor: - * [0:7] = Packet Retry Count - * [8:14] = RTS Retry Count - * [15] = TOK - * [16:27] = Sequence No - * [28] = LS - * [29] = FS - * [30:31] = 01b - * [32:47] = unused (reserved?) - * [48:63] = MAC Used Time - */ - val = le64_to_cpu(priv->b_tx_status.buf); - - cmd_type = (val >> 30) & 0x3; - if (cmd_type == 1) { - unsigned int pkt_rc, seq_no; - bool tok; - struct sk_buff *skb; - struct ieee80211_hdr *ieee80211hdr; - unsigned long flags; - - pkt_rc = val & 0xFF; - tok = val & (1 << 15); - seq_no = (val >> 16) & 0xFFF; - - spin_lock_irqsave(&priv->b_tx_status.queue.lock, flags); - skb_queue_reverse_walk(&priv->b_tx_status.queue, skb) { - ieee80211hdr = (struct ieee80211_hdr *)skb->data; - - /* - * While testing, it was discovered that the seq_no - * doesn't actually contains the sequence number. - * Instead of returning just the 12 bits of sequence - * number, hardware is returning entire sequence control - * (fragment number plus sequence number) in a 12 bit - * only field overflowing after some time. As a - * workaround, just consider the lower bits, and expect - * it's unlikely we wrongly ack some sent data - */ - if ((le16_to_cpu(ieee80211hdr->seq_ctrl) - & 0xFFF) == seq_no) - break; - } - if (skb != (struct sk_buff *) &priv->b_tx_status.queue) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - __skb_unlink(skb, &priv->b_tx_status.queue); - if (tok) - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.rates[0].count = pkt_rc + 1; - - ieee80211_tx_status_irqsafe(hw, skb); - } - spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags); - } - - usb_anchor_urb(urb, &priv->anchored); - if (usb_submit_urb(urb, GFP_ATOMIC)) - usb_unanchor_urb(urb); -} - -static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - struct urb *entry; - int ret = 0; - - entry = usb_alloc_urb(0, GFP_KERNEL); - if (!entry) - return -ENOMEM; - - usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9), - &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf), - rtl8187b_status_cb, dev); - - usb_anchor_urb(entry, &priv->anchored); - ret = usb_submit_urb(entry, GFP_KERNEL); - if (ret) - usb_unanchor_urb(entry); - usb_free_urb(entry); - - return ret; -} - -static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon) -{ - u32 anaparam, anaparam2; - u8 anaparam3, reg; - - if (!priv->is_rtl8187b) { - if (rfon) { - anaparam = RTL8187_RTL8225_ANAPARAM_ON; - anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON; - } else { - anaparam = RTL8187_RTL8225_ANAPARAM_OFF; - anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF; - } - } else { - if (rfon) { - anaparam = RTL8187B_RTL8225_ANAPARAM_ON; - anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON; - anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON; - } else { - anaparam = RTL8187B_RTL8225_ANAPARAM_OFF; - anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF; - anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF; - } - } - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); - if (priv->is_rtl8187b) - rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3); - reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; - rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); -} - -static int rtl8187_cmd_reset(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - u8 reg; - int i; - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg &= (1 << 1); - reg |= RTL818X_CMD_RESET; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - - i = 10; - do { - msleep(2); - if (!(rtl818x_ioread8(priv, &priv->map->CMD) & - RTL818X_CMD_RESET)) - break; - } while (--i); - - if (!i) { - wiphy_err(dev->wiphy, "Reset timeout!\n"); - return -ETIMEDOUT; - } - - /* reload registers from eeprom */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); - - i = 10; - do { - msleep(4); - if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) & - RTL818X_EEPROM_CMD_CONFIG)) - break; - } while (--i); - - if (!i) { - wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); - return -ETIMEDOUT; - } - - return 0; -} - -static int rtl8187_init_hw(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - u8 reg; - int res; - - /* reset */ - rtl8187_set_anaparam(priv, true); - - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); - - msleep(200); - rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10); - rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11); - rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00); - msleep(200); - - res = rtl8187_cmd_reset(dev); - if (res) - return res; - - rtl8187_set_anaparam(priv, true); - - /* setup card */ - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); - rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); - - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); - rtl818x_iowrite8(priv, &priv->map->GPIO0, 1); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - - rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); - reg &= 0x3F; - reg |= 0x80; - rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); - rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); - rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0); - - // TODO: set RESP_RATE and BRSR properly - rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); - rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); - - /* host_usb_init */ - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); - rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); - reg = rtl818x_ioread8(priv, (u8 *)0xFE53); - rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); - rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80); - msleep(100); - - rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); - rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); - rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); - msleep(100); - - priv->rf->init(dev); - - rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); - rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); - rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); - rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - - return 0; -} - -static const u8 rtl8187b_reg_table[][3] = { - {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0}, - {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0}, - {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0}, - {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0}, - - {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1}, - {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1}, - {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, - {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, - {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1}, - - {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2}, - {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2}, - {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2}, - {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2}, - {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2}, - {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2}, - {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, - - {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0}, - {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, - {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, - {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, - {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, - - {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, - {0x8F, 0x00, 0} -}; - -static int rtl8187b_init_hw(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - int res, i; - u8 reg; - - rtl8187_set_anaparam(priv, true); - - /* Reset PLL sequence on 8187B. Realtek note: reduces power - * consumption about 30 mA */ - rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); - reg = rtl818x_ioread8(priv, (u8 *)0xFF62); - rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); - rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); - - res = rtl8187_cmd_reset(dev); - if (res) - return res; - - rtl8187_set_anaparam(priv, true); - - /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as - * RESP_RATE on 8187L in Realtek sources: each bit should be each - * one of the 12 rates, all are enabled */ - rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF); - - reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); - reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; - rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); - - /* Auto Rate Fallback Register (ARFR): 1M-54M setting */ - rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); - rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1); - - rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); - rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, - RTL818X_EEPROM_CMD_NORMAL); - - rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); - for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) { - rtl818x_iowrite8_idx(priv, - (u8 *)(uintptr_t) - (rtl8187b_reg_table[i][0] | 0xFF00), - rtl8187b_reg_table[i][1], - rtl8187b_reg_table[i][2]); - } - - rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50); - rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0); - - rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1); - rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1); - rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1); - - rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001); - - /* RFSW_CTRL register */ - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); - msleep(100); - - priv->rf->init(dev); - - reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); - - rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4); - rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00); - rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); - rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); - rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F); - rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); - rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); - - reg = rtl818x_ioread8(priv, (u8 *)0xFFDB); - rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2)); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3); - rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3); - rtl818x_iowrite8(priv, (u8 *)0xFF61, 0); - rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1); - rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1); - rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10); - rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2); - - rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B); - - rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1); - - priv->slot_time = 0x9; - priv->aifsn[0] = 2; /* AIFSN[AC_VO] */ - priv->aifsn[1] = 2; /* AIFSN[AC_VI] */ - priv->aifsn[2] = 7; /* AIFSN[AC_BK] */ - priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ - rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); - - /* ENEDCA flag must always be set, transmit issues? */ - rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); - - return 0; -} - -static void rtl8187_work(struct work_struct *work) -{ - /* The RTL8187 returns the retry count through register 0xFFFA. In - * addition, it appears to be a cumulative retry count, not the - * value for the current TX packet. When multiple TX entries are - * queued, the retry count will be valid for the last one in the queue. - * The "error" should not matter for purposes of rate setting. */ - struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, - work.work); - struct ieee80211_tx_info *info; - struct ieee80211_hw *dev = priv->dev; - static u16 retry; - u16 tmp; - - mutex_lock(&priv->conf_mutex); - tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); - while (skb_queue_len(&priv->b_tx_status.queue) > 0) { - struct sk_buff *old_skb; - - old_skb = skb_dequeue(&priv->b_tx_status.queue); - info = IEEE80211_SKB_CB(old_skb); - info->status.rates[0].count = tmp - retry + 1; - ieee80211_tx_status_irqsafe(dev, old_skb); - } - retry = tmp; - mutex_unlock(&priv->conf_mutex); -} - -static int rtl8187_start(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - u32 reg; - int ret; - - mutex_lock(&priv->conf_mutex); - - ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : - rtl8187b_init_hw(dev); - if (ret) - goto rtl8187_start_exit; - - init_usb_anchor(&priv->anchored); - priv->dev = dev; - - if (priv->is_rtl8187b) { - reg = RTL818X_RX_CONF_MGMT | - RTL818X_RX_CONF_DATA | - RTL818X_RX_CONF_BROADCAST | - RTL818X_RX_CONF_NICMAC | - RTL818X_RX_CONF_BSSID | - (7 << 13 /* RX FIFO threshold NONE */) | - (7 << 10 /* MAX RX DMA */) | - RTL818X_RX_CONF_RX_AUTORESETPHY | - RTL818X_RX_CONF_ONLYERLPKT | - RTL818X_RX_CONF_MULTICAST; - priv->rx_conf = reg; - rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; - reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; - rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); - - rtl818x_iowrite32(priv, &priv->map->TX_CONF, - RTL818X_TX_CONF_HW_SEQNUM | - RTL818X_TX_CONF_DISREQQSIZE | - (7 << 8 /* short retry limit */) | - (7 << 0 /* long retry limit */) | - (7 << 21 /* MAX TX DMA */)); - rtl8187_init_urbs(dev); - rtl8187b_init_status_urb(dev); - goto rtl8187_start_exit; - } - - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); - - rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); - rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); - - rtl8187_init_urbs(dev); - - reg = RTL818X_RX_CONF_ONLYERLPKT | - RTL818X_RX_CONF_RX_AUTORESETPHY | - RTL818X_RX_CONF_BSSID | - RTL818X_RX_CONF_MGMT | - RTL818X_RX_CONF_DATA | - (7 << 13 /* RX FIFO threshold NONE */) | - (7 << 10 /* MAX RX DMA */) | - RTL818X_RX_CONF_BROADCAST | - RTL818X_RX_CONF_NICMAC; - - priv->rx_conf = reg; - rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); - reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; - reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; - rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; - reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; - reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; - rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); - - reg = RTL818X_TX_CONF_CW_MIN | - (7 << 21 /* MAX TX DMA */) | - RTL818X_TX_CONF_NO_ICV; - rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg |= RTL818X_CMD_TX_ENABLE; - reg |= RTL818X_CMD_RX_ENABLE; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - INIT_DELAYED_WORK(&priv->work, rtl8187_work); - -rtl8187_start_exit: - mutex_unlock(&priv->conf_mutex); - return ret; -} - -static void rtl8187_stop(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - struct sk_buff *skb; - u32 reg; - - mutex_lock(&priv->conf_mutex); - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); - - reg = rtl818x_ioread8(priv, &priv->map->CMD); - reg &= ~RTL818X_CMD_TX_ENABLE; - reg &= ~RTL818X_CMD_RX_ENABLE; - rtl818x_iowrite8(priv, &priv->map->CMD, reg); - - priv->rf->stop(dev); - rtl8187_set_anaparam(priv, false); - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); - rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - while ((skb = skb_dequeue(&priv->b_tx_status.queue))) - dev_kfree_skb_any(skb); - - usb_kill_anchored_urbs(&priv->anchored); - mutex_unlock(&priv->conf_mutex); - - if (!priv->is_rtl8187b) - cancel_delayed_work_sync(&priv->work); -} - -static int rtl8187_add_interface(struct ieee80211_hw *dev, - struct ieee80211_vif *vif) -{ - struct rtl8187_priv *priv = dev->priv; - int i; - int ret = -EOPNOTSUPP; - - mutex_lock(&priv->conf_mutex); - if (priv->vif) - goto exit; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - default: - goto exit; - } - - ret = 0; - priv->vif = vif; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - for (i = 0; i < ETH_ALEN; i++) - rtl818x_iowrite8(priv, &priv->map->MAC[i], - ((u8 *)vif->addr)[i]); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - -exit: - mutex_unlock(&priv->conf_mutex); - return ret; -} - -static void rtl8187_remove_interface(struct ieee80211_hw *dev, - struct ieee80211_vif *vif) -{ - struct rtl8187_priv *priv = dev->priv; - mutex_lock(&priv->conf_mutex); - priv->vif = NULL; - mutex_unlock(&priv->conf_mutex); -} - -static int rtl8187_config(struct ieee80211_hw *dev, u32 changed) -{ - struct rtl8187_priv *priv = dev->priv; - struct ieee80211_conf *conf = &dev->conf; - u32 reg; - - mutex_lock(&priv->conf_mutex); - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); - /* Enable TX loopback on MAC level to avoid TX during channel - * changes, as this has be seen to causes problems and the - * card will stop work until next reset - */ - rtl818x_iowrite32(priv, &priv->map->TX_CONF, - reg | RTL818X_TX_CONF_LOOPBACK_MAC); - priv->rf->set_chan(dev, conf); - msleep(10); - rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); - - rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); - rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); - rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); - rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); - mutex_unlock(&priv->conf_mutex); - return 0; -} - -/* - * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for - * example. Thus we have to use raw values for AC_*_PARAM register addresses. - */ -static __le32 *rtl8187b_ac_addr[4] = { - (__le32 *) 0xFFF0, /* AC_VO */ - (__le32 *) 0xFFF4, /* AC_VI */ - (__le32 *) 0xFFFC, /* AC_BK */ - (__le32 *) 0xFFF8, /* AC_BE */ -}; - -#define SIFS_TIME 0xa - -static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, - bool use_short_preamble) -{ - if (priv->is_rtl8187b) { - u8 difs, eifs; - u16 ack_timeout; - int queue; - - if (use_short_slot) { - priv->slot_time = 0x9; - difs = 0x1c; - eifs = 0x53; - } else { - priv->slot_time = 0x14; - difs = 0x32; - eifs = 0x5b; - } - rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); - rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); - rtl818x_iowrite8(priv, &priv->map->DIFS, difs); - - /* - * BRSR+1 on 8187B is in fact EIFS register - * Value in units of 4 us - */ - rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs); - - /* - * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout - * register. In units of 4 us like eifs register - * ack_timeout = ack duration + plcp + difs + preamble - */ - ack_timeout = 112 + 48 + difs; - if (use_short_preamble) - ack_timeout += 72; - else - ack_timeout += 144; - rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, - DIV_ROUND_UP(ack_timeout, 4)); - - for (queue = 0; queue < 4; queue++) - rtl818x_iowrite8(priv, (u8 *) rtl8187b_ac_addr[queue], - priv->aifsn[queue] * priv->slot_time + - SIFS_TIME); - } else { - rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); - if (use_short_slot) { - rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); - rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); - rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); - } else { - rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); - rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); - rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); - } - } -} - -static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u32 changed) -{ - struct rtl8187_priv *priv = dev->priv; - int i; - u8 reg; - - if (changed & BSS_CHANGED_BSSID) { - mutex_lock(&priv->conf_mutex); - for (i = 0; i < ETH_ALEN; i++) - rtl818x_iowrite8(priv, &priv->map->BSSID[i], - info->bssid[i]); - - if (priv->is_rtl8187b) - reg = RTL818X_MSR_ENEDCA; - else - reg = 0; - - if (is_valid_ether_addr(info->bssid)) - reg |= RTL818X_MSR_INFRA; - else - reg |= RTL818X_MSR_NO_LINK; - - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - - mutex_unlock(&priv->conf_mutex); - } - - if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) - rtl8187_conf_erp(priv, info->use_short_slot, - info->use_short_preamble); -} - -static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, - struct netdev_hw_addr_list *mc_list) -{ - return netdev_hw_addr_list_count(mc_list); -} - -static void rtl8187_configure_filter(struct ieee80211_hw *dev, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) -{ - struct rtl8187_priv *priv = dev->priv; - - if (changed_flags & FIF_FCSFAIL) - priv->rx_conf ^= RTL818X_RX_CONF_FCS; - if (changed_flags & FIF_CONTROL) - priv->rx_conf ^= RTL818X_RX_CONF_CTRL; - if (changed_flags & FIF_OTHER_BSS) - priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; - if (*total_flags & FIF_ALLMULTI || multicast > 0) - priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; - else - priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; - - *total_flags = 0; - - if (priv->rx_conf & RTL818X_RX_CONF_FCS) - *total_flags |= FIF_FCSFAIL; - if (priv->rx_conf & RTL818X_RX_CONF_CTRL) - *total_flags |= FIF_CONTROL; - if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) - *total_flags |= FIF_OTHER_BSS; - if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) - *total_flags |= FIF_ALLMULTI; - - rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); -} - -static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct rtl8187_priv *priv = dev->priv; - u8 cw_min, cw_max; - - if (queue > 3) - return -EINVAL; - - cw_min = fls(params->cw_min); - cw_max = fls(params->cw_max); - - if (priv->is_rtl8187b) { - priv->aifsn[queue] = params->aifs; - - /* - * This is the structure of AC_*_PARAM registers in 8187B: - * - TXOP limit field, bit offset = 16 - * - ECWmax, bit offset = 12 - * - ECWmin, bit offset = 8 - * - AIFS, bit offset = 0 - */ - rtl818x_iowrite32(priv, rtl8187b_ac_addr[queue], - (params->txop << 16) | (cw_max << 12) | - (cw_min << 8) | (params->aifs * - priv->slot_time + SIFS_TIME)); - } else { - if (queue != 0) - return -EINVAL; - - rtl818x_iowrite8(priv, &priv->map->CW_VAL, - cw_min | (cw_max << 4)); - } - return 0; -} - -static u64 rtl8187_get_tsf(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - - return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | - (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; -} - -static const struct ieee80211_ops rtl8187_ops = { - .tx = rtl8187_tx, - .start = rtl8187_start, - .stop = rtl8187_stop, - .add_interface = rtl8187_add_interface, - .remove_interface = rtl8187_remove_interface, - .config = rtl8187_config, - .bss_info_changed = rtl8187_bss_info_changed, - .prepare_multicast = rtl8187_prepare_multicast, - .configure_filter = rtl8187_configure_filter, - .conf_tx = rtl8187_conf_tx, - .rfkill_poll = rtl8187_rfkill_poll, - .get_tsf = rtl8187_get_tsf, -}; - -static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) -{ - struct ieee80211_hw *dev = eeprom->data; - struct rtl8187_priv *priv = dev->priv; - u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); - - eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; - eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; - eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; - eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; -} - -static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom) -{ - struct ieee80211_hw *dev = eeprom->data; - struct rtl8187_priv *priv = dev->priv; - u8 reg = RTL818X_EEPROM_CMD_PROGRAM; - - if (eeprom->reg_data_in) - reg |= RTL818X_EEPROM_CMD_WRITE; - if (eeprom->reg_data_out) - reg |= RTL818X_EEPROM_CMD_READ; - if (eeprom->reg_data_clock) - reg |= RTL818X_EEPROM_CMD_CK; - if (eeprom->reg_chip_select) - reg |= RTL818X_EEPROM_CMD_CS; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); - udelay(10); -} - -static int __devinit rtl8187_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct ieee80211_hw *dev; - struct rtl8187_priv *priv; - struct eeprom_93cx6 eeprom; - struct ieee80211_channel *channel; - const char *chip_name; - u16 txpwr, reg; - u16 product_id = le16_to_cpu(udev->descriptor.idProduct); - int err, i; - u8 mac_addr[ETH_ALEN]; - - dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); - if (!dev) { - printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n"); - return -ENOMEM; - } - - priv = dev->priv; - priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); - - /* allocate "DMA aware" buffer for register accesses */ - priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL); - if (!priv->io_dmabuf) { - err = -ENOMEM; - goto err_free_dev; - } - mutex_init(&priv->io_mutex); - - SET_IEEE80211_DEV(dev, &intf->dev); - usb_set_intfdata(intf, dev); - priv->udev = udev; - - usb_get_dev(udev); - - skb_queue_head_init(&priv->rx_queue); - - BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); - BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); - - memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); - memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); - priv->map = (struct rtl818x_csr *)0xFF00; - - priv->band.band = IEEE80211_BAND_2GHZ; - priv->band.channels = priv->channels; - priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); - priv->band.bitrates = priv->rates; - priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); - dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; - - - dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_RX_INCLUDES_FCS; - - eeprom.data = dev; - eeprom.register_read = rtl8187_eeprom_register_read; - eeprom.register_write = rtl8187_eeprom_register_write; - if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) - eeprom.width = PCI_EEPROM_WIDTH_93C66; - else - eeprom.width = PCI_EEPROM_WIDTH_93C46; - - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - udelay(10); - - eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, - (__le16 __force *)mac_addr, 3); - if (!is_valid_ether_addr(mac_addr)) { - printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " - "generated MAC address\n"); - random_ether_addr(mac_addr); - } - SET_IEEE80211_PERM_ADDR(dev, mac_addr); - - channel = priv->channels; - for (i = 0; i < 3; i++) { - eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, - &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - (*channel++).hw_value = txpwr >> 8; - } - for (i = 0; i < 2; i++) { - eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, - &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - (*channel++).hw_value = txpwr >> 8; - } - - eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, - &priv->txpwr_base); - - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); - /* 0 means asic B-cut, we should use SW 3 wire - * bit-by-bit banging for radio. 1 means we can use - * USB specific request to write radio registers */ - priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - if (!priv->is_rtl8187b) { - u32 reg32; - reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF); - reg32 &= RTL818X_TX_CONF_HWVER_MASK; - switch (reg32) { - case RTL818X_TX_CONF_R8187vD_B: - /* Some RTL8187B devices have a USB ID of 0x8187 - * detect them here */ - chip_name = "RTL8187BvB(early)"; - priv->is_rtl8187b = 1; - priv->hw_rev = RTL8187BvB; - break; - case RTL818X_TX_CONF_R8187vD: - chip_name = "RTL8187vD"; - break; - default: - chip_name = "RTL8187vB (default)"; - } - } else { - /* - * Force USB request to write radio registers for 8187B, Realtek - * only uses it in their sources - */ - /*if (priv->asic_rev == 0) { - printk(KERN_WARNING "rtl8187: Forcing use of USB " - "requests to write to radio registers\n"); - priv->asic_rev = 1; - }*/ - switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) { - case RTL818X_R8187B_B: - chip_name = "RTL8187BvB"; - priv->hw_rev = RTL8187BvB; - break; - case RTL818X_R8187B_D: - chip_name = "RTL8187BvD"; - priv->hw_rev = RTL8187BvD; - break; - case RTL818X_R8187B_E: - chip_name = "RTL8187BvE"; - priv->hw_rev = RTL8187BvE; - break; - default: - chip_name = "RTL8187BvB (default)"; - priv->hw_rev = RTL8187BvB; - } - } - - if (!priv->is_rtl8187b) { - for (i = 0; i < 2; i++) { - eeprom_93cx6_read(&eeprom, - RTL8187_EEPROM_TXPWR_CHAN_6 + i, - &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - (*channel++).hw_value = txpwr >> 8; - } - } else { - eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6, - &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - - eeprom_93cx6_read(&eeprom, 0x0A, &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - - eeprom_93cx6_read(&eeprom, 0x1C, &txpwr); - (*channel++).hw_value = txpwr & 0xFF; - (*channel++).hw_value = txpwr >> 8; - } - /* Handle the differing rfkill GPIO bit in different models */ - priv->rfkill_mask = RFKILL_MASK_8187_89_97; - if (product_id == 0x8197 || product_id == 0x8198) { - eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®); - if (reg & 0xFF00) - priv->rfkill_mask = RFKILL_MASK_8198; - } - - /* - * XXX: Once this driver supports anything that requires - * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. - */ - dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - - if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) - printk(KERN_INFO "rtl8187: inconsistency between id with OEM" - " info!\n"); - - priv->rf = rtl8187_detect_rf(dev); - dev->extra_tx_headroom = (!priv->is_rtl8187b) ? - sizeof(struct rtl8187_tx_hdr) : - sizeof(struct rtl8187b_tx_hdr); - if (!priv->is_rtl8187b) - dev->queues = 1; - else - dev->queues = 4; - - err = ieee80211_register_hw(dev); - if (err) { - printk(KERN_ERR "rtl8187: Cannot register device\n"); - goto err_free_dmabuf; - } - mutex_init(&priv->conf_mutex); - skb_queue_head_init(&priv->b_tx_status.queue); - - wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", - mac_addr, chip_name, priv->asic_rev, priv->rf->name, - priv->rfkill_mask); - -#ifdef CONFIG_RTL8187_LEDS - eeprom_93cx6_read(&eeprom, 0x3F, ®); - reg &= 0xFF; - rtl8187_leds_init(dev, reg); -#endif - rtl8187_rfkill_init(dev); - - return 0; - - err_free_dmabuf: - kfree(priv->io_dmabuf); - err_free_dev: - ieee80211_free_hw(dev); - usb_set_intfdata(intf, NULL); - usb_put_dev(udev); - return err; -} - -static void __devexit rtl8187_disconnect(struct usb_interface *intf) -{ - struct ieee80211_hw *dev = usb_get_intfdata(intf); - struct rtl8187_priv *priv; - - if (!dev) - return; - -#ifdef CONFIG_RTL8187_LEDS - rtl8187_leds_exit(dev); -#endif - rtl8187_rfkill_exit(dev); - ieee80211_unregister_hw(dev); - - priv = dev->priv; - usb_reset_device(priv->udev); - usb_put_dev(interface_to_usbdev(intf)); - kfree(priv->io_dmabuf); - ieee80211_free_hw(dev); -} - -static struct usb_driver rtl8187_driver = { - .name = KBUILD_MODNAME, - .id_table = rtl8187_table, - .probe = rtl8187_probe, - .disconnect = __devexit_p(rtl8187_disconnect), -}; - -static int __init rtl8187_init(void) -{ - return usb_register(&rtl8187_driver); -} - -static void __exit rtl8187_exit(void) -{ - usb_deregister(&rtl8187_driver); -} - -module_init(rtl8187_init); -module_exit(rtl8187_exit); diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c deleted file mode 100644 index 4637337d5ce6..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Linux LED driver for RTL8187 - * - * Copyright 2009 Larry Finger - * - * Based on the LED handling in the r8187 driver, which is: - * Copyright (c) Realtek Semiconductor Corp. All rights reserved. - * - * Thanks to Realtek for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifdef CONFIG_RTL8187_LEDS - -#include -#include -#include - -#include "rtl8187.h" -#include "rtl8187_leds.h" - -static void led_turn_on(struct work_struct *work) -{ - /* As this routine does read/write operations on the hardware, it must - * be run from a work queue. - */ - u8 reg; - struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, - led_on.work); - struct rtl8187_led *led = &priv->led_tx; - - /* Don't change the LED, when the device is down. */ - if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) - return ; - - /* Skip if the LED is not registered. */ - if (!led->dev) - return; - mutex_lock(&priv->conf_mutex); - switch (led->ledpin) { - case LED_PIN_GPIO0: - rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); - break; - case LED_PIN_LED0: - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4); - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - break; - case LED_PIN_LED1: - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5); - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - break; - case LED_PIN_HW: - default: - break; - } - mutex_unlock(&priv->conf_mutex); -} - -static void led_turn_off(struct work_struct *work) -{ - /* As this routine does read/write operations on the hardware, it must - * be run from a work queue. - */ - u8 reg; - struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, - led_off.work); - struct rtl8187_led *led = &priv->led_tx; - - /* Don't change the LED, when the device is down. */ - if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) - return ; - - /* Skip if the LED is not registered. */ - if (!led->dev) - return; - mutex_lock(&priv->conf_mutex); - switch (led->ledpin) { - case LED_PIN_GPIO0: - rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); - rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); - break; - case LED_PIN_LED0: - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4); - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - break; - case LED_PIN_LED1: - reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5); - rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); - break; - case LED_PIN_HW: - default: - break; - } - mutex_unlock(&priv->conf_mutex); -} - -/* Callback from the LED subsystem. */ -static void rtl8187_led_brightness_set(struct led_classdev *led_dev, - enum led_brightness brightness) -{ - struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, - led_dev); - struct ieee80211_hw *hw = led->dev; - struct rtl8187_priv *priv; - static bool radio_on; - - if (!hw) - return; - priv = hw->priv; - if (led->is_radio) { - if (brightness == LED_FULL) { - ieee80211_queue_delayed_work(hw, &priv->led_on, 0); - radio_on = true; - } else if (radio_on) { - radio_on = false; - cancel_delayed_work_sync(&priv->led_on); - ieee80211_queue_delayed_work(hw, &priv->led_off, 0); - } - } else if (radio_on) { - if (brightness == LED_OFF) { - ieee80211_queue_delayed_work(hw, &priv->led_off, 0); - /* The LED is off for 1/20 sec - it just blinks. */ - ieee80211_queue_delayed_work(hw, &priv->led_on, - HZ / 20); - } else - ieee80211_queue_delayed_work(hw, &priv->led_on, 0); - } -} - -static int rtl8187_register_led(struct ieee80211_hw *dev, - struct rtl8187_led *led, const char *name, - const char *default_trigger, u8 ledpin, - bool is_radio) -{ - int err; - struct rtl8187_priv *priv = dev->priv; - - if (led->dev) - return -EEXIST; - if (!default_trigger) - return -EINVAL; - led->dev = dev; - led->ledpin = ledpin; - led->is_radio = is_radio; - strncpy(led->name, name, sizeof(led->name)); - - led->led_dev.name = led->name; - led->led_dev.default_trigger = default_trigger; - led->led_dev.brightness_set = rtl8187_led_brightness_set; - - err = led_classdev_register(&priv->udev->dev, &led->led_dev); - if (err) { - printk(KERN_INFO "LEDs: Failed to register %s\n", name); - led->dev = NULL; - return err; - } - return 0; -} - -static void rtl8187_unregister_led(struct rtl8187_led *led) -{ - struct ieee80211_hw *hw = led->dev; - struct rtl8187_priv *priv = hw->priv; - - led_classdev_unregister(&led->led_dev); - flush_delayed_work(&priv->led_off); - led->dev = NULL; -} - -void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) -{ - struct rtl8187_priv *priv = dev->priv; - char name[RTL8187_LED_MAX_NAME_LEN + 1]; - u8 ledpin; - int err; - - /* According to the vendor driver, the LED operation depends on the - * customer ID encoded in the EEPROM - */ - printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid); - switch (custid) { - case EEPROM_CID_RSVD0: - case EEPROM_CID_RSVD1: - case EEPROM_CID_SERCOMM_PS: - case EEPROM_CID_QMI: - case EEPROM_CID_DELL: - case EEPROM_CID_TOSHIBA: - ledpin = LED_PIN_GPIO0; - break; - case EEPROM_CID_ALPHA0: - ledpin = LED_PIN_LED0; - break; - case EEPROM_CID_HW: - ledpin = LED_PIN_HW; - break; - default: - ledpin = LED_PIN_GPIO0; - } - - INIT_DELAYED_WORK(&priv->led_on, led_turn_on); - INIT_DELAYED_WORK(&priv->led_off, led_turn_off); - - snprintf(name, sizeof(name), - "rtl8187-%s::radio", wiphy_name(dev->wiphy)); - err = rtl8187_register_led(dev, &priv->led_radio, name, - ieee80211_get_radio_led_name(dev), ledpin, true); - if (err) - return; - - snprintf(name, sizeof(name), - "rtl8187-%s::tx", wiphy_name(dev->wiphy)); - err = rtl8187_register_led(dev, &priv->led_tx, name, - ieee80211_get_tx_led_name(dev), ledpin, false); - if (err) - goto err_tx; - - snprintf(name, sizeof(name), - "rtl8187-%s::rx", wiphy_name(dev->wiphy)); - err = rtl8187_register_led(dev, &priv->led_rx, name, - ieee80211_get_rx_led_name(dev), ledpin, false); - if (!err) - return; - - /* registration of RX LED failed - unregister */ - rtl8187_unregister_led(&priv->led_tx); -err_tx: - rtl8187_unregister_led(&priv->led_radio); -} - -void rtl8187_leds_exit(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - - rtl8187_unregister_led(&priv->led_radio); - rtl8187_unregister_led(&priv->led_rx); - rtl8187_unregister_led(&priv->led_tx); - cancel_delayed_work_sync(&priv->led_off); - cancel_delayed_work_sync(&priv->led_on); -} -#endif /* def CONFIG_RTL8187_LEDS */ - diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h deleted file mode 100644 index d743c96d4a20..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Definitions for RTL8187 leds - * - * Copyright 2009 Larry Finger - * - * Based on the LED handling in the r8187 driver, which is: - * Copyright (c) Realtek Semiconductor Corp. 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 version 2 as - * published by the Free Software Foundation. - */ - -#ifndef RTL8187_LED_H -#define RTL8187_LED_H - -#ifdef CONFIG_RTL8187_LEDS - -#define RTL8187_LED_MAX_NAME_LEN 21 - -#include -#include - -enum { - LED_PIN_LED0, - LED_PIN_LED1, - LED_PIN_GPIO0, - LED_PIN_HW -}; - -enum { - EEPROM_CID_RSVD0 = 0x00, - EEPROM_CID_RSVD1 = 0xFF, - EEPROM_CID_ALPHA0 = 0x01, - EEPROM_CID_SERCOMM_PS = 0x02, - EEPROM_CID_HW = 0x03, - EEPROM_CID_TOSHIBA = 0x04, - EEPROM_CID_QMI = 0x07, - EEPROM_CID_DELL = 0x08 -}; - -struct rtl8187_led { - struct ieee80211_hw *dev; - /* The LED class device */ - struct led_classdev led_dev; - /* The pin/method used to control the led */ - u8 ledpin; - /* The unique name string for this LED device. */ - char name[RTL8187_LED_MAX_NAME_LEN + 1]; - /* If the LED is radio or tx/rx */ - bool is_radio; -}; - -void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); -void rtl8187_leds_exit(struct ieee80211_hw *dev); - -#endif /* def CONFIG_RTL8187_LEDS */ - -#endif /* RTL8187_LED_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c deleted file mode 100644 index 03555e1e0cab..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Linux RFKILL support for RTL8187 - * - * Copyright (c) 2009 Herton Ronaldo Krzesinski - * - * Based on the RFKILL handling in the r8187 driver, which is: - * Copyright (c) Realtek Semiconductor Corp. All rights reserved. - * - * Thanks to Realtek for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#include "rtl8187.h" -#include "rtl8187_rfkill.h" - -static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) -{ - u8 gpio; - - gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); - rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask); - gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); - - return gpio & priv->rfkill_mask; -} - -void rtl8187_rfkill_init(struct ieee80211_hw *hw) -{ - struct rtl8187_priv *priv = hw->priv; - - priv->rfkill_off = rtl8187_is_radio_enabled(priv); - printk(KERN_INFO "rtl8187: wireless switch is %s\n", - priv->rfkill_off ? "on" : "off"); - wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off); - wiphy_rfkill_start_polling(hw->wiphy); -} - -void rtl8187_rfkill_poll(struct ieee80211_hw *hw) -{ - bool enabled; - struct rtl8187_priv *priv = hw->priv; - - mutex_lock(&priv->conf_mutex); - enabled = rtl8187_is_radio_enabled(priv); - if (unlikely(enabled != priv->rfkill_off)) { - priv->rfkill_off = enabled; - printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n", - enabled ? "on" : "off"); - wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); - } - mutex_unlock(&priv->conf_mutex); -} - -void rtl8187_rfkill_exit(struct ieee80211_hw *hw) -{ - wiphy_rfkill_stop_polling(hw->wiphy); -} diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h b/drivers/net/wireless/rtl818x/rtl8187_rfkill.h deleted file mode 100644 index e12575e96d11..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RTL8187_RFKILL_H -#define RTL8187_RFKILL_H - -void rtl8187_rfkill_init(struct ieee80211_hw *hw); -void rtl8187_rfkill_poll(struct ieee80211_hw *hw); -void rtl8187_rfkill_exit(struct ieee80211_hw *hw); - -#endif /* RTL8187_RFKILL_H */ diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c deleted file mode 100644 index 5c6666f09ac1..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ /dev/null @@ -1,961 +0,0 @@ -/* - * Radio tuning for RTL8225 on RTL8187 - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8187 driver, which is: - * Copyright 2005 Andrea Merello , et al. - * - * Magic delays, register offsets, and phy value tables below are - * taken from the original r8187 driver sources. Thanks to Realtek - * for their support! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#include "rtl8187.h" -#include "rtl8187_rtl8225.h" - -static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data) -{ - struct rtl8187_priv *priv = dev->priv; - u16 reg80, reg84, reg82; - u32 bangdata; - int i; - - bangdata = (data << 4) | (addr & 0xf); - - reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; - reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); - - reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); - udelay(10); - - for (i = 15; i >= 0; i--) { - u16 reg = reg80 | (bangdata & (1 << i)) >> i; - - if (i & 1) - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); - - if (!(i & 1)) - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); -} - -static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) -{ - struct rtl8187_priv *priv = dev->priv; - u16 reg80, reg82, reg84; - - reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); - reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); - reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); - - reg80 &= ~(0x3 << 2); - reg84 &= ~0xF; - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - udelay(2); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); - udelay(10); - - mutex_lock(&priv->io_mutex); - - priv->io_dmabuf->bits16 = data; - usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), - RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), - HZ / 2); - - mutex_unlock(&priv->io_mutex); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - udelay(10); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); -} - -static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) -{ - struct rtl8187_priv *priv = dev->priv; - - if (priv->asic_rev) - rtl8225_write_8051(dev, addr, cpu_to_le16(data)); - else - rtl8225_write_bitbang(dev, addr, data); -} - -static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) -{ - struct rtl8187_priv *priv = dev->priv; - u16 reg80, reg82, reg84, out; - int i; - - reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); - reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); - reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); - - reg80 &= ~0xF; - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); - udelay(4); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); - udelay(5); - - for (i = 4; i >= 0; i--) { - u16 reg = reg80 | ((addr >> i) & 1); - - if (!(i & 1)) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - udelay(1); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg | (1 << 1)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg | (1 << 1)); - udelay(2); - - if (i & 1) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); - udelay(1); - } - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - udelay(2); - - out = 0; - for (i = 11; i >= 0; i--) { - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - udelay(1); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - udelay(2); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 1)); - udelay(2); - - if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) - out |= 1 << i; - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3)); - udelay(2); - } - - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, - reg80 | (1 << 3) | (1 << 2)); - udelay(2); - - rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); - rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); - rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); - - return out; -} - -static const u16 rtl8225bcd_rxgain[] = { - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, - 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, - 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, - 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, - 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, - 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, - 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, - 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, - 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, - 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, - 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, - 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb -}; - -static const u8 rtl8225_agc[] = { - 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, - 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, - 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, - 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, - 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, - 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, - 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, - 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, - 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, - 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, - 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, - 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, - 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -}; - -static const u8 rtl8225_gain[] = { - 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */ - 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */ - 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */ - 0x33, 0x80, 0x79, 0xc5, /* -78dBm */ - 0x43, 0x78, 0x76, 0xc5, /* -74dBm */ - 0x53, 0x60, 0x73, 0xc5, /* -70dBm */ - 0x63, 0x58, 0x70, 0xc5, /* -66dBm */ -}; - -static const u8 rtl8225_threshold[] = { - 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd -}; - -static const u8 rtl8225_tx_gain_cck_ofdm[] = { - 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e -}; - -static const u8 rtl8225_tx_power_cck[] = { - 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, - 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, - 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, - 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, - 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, - 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 -}; - -static const u8 rtl8225_tx_power_cck_ch14[] = { - 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, - 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, - 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 -}; - -static const u8 rtl8225_tx_power_ofdm[] = { - 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 -}; - -static const u32 rtl8225_chan[] = { - 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, - 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 -}; - -static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) -{ - struct rtl8187_priv *priv = dev->priv; - u8 cck_power, ofdm_power; - const u8 *tmp; - u32 reg; - int i; - - cck_power = priv->channels[channel - 1].hw_value & 0xF; - ofdm_power = priv->channels[channel - 1].hw_value >> 4; - - cck_power = min(cck_power, (u8)11); - if (ofdm_power > (u8)15) - ofdm_power = 25; - else - ofdm_power += 10; - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, - rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); - - if (channel == 14) - tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; - else - tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; - - for (i = 0; i < 8; i++) - rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); - - msleep(1); // FIXME: optional? - - /* anaparam2 on */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187_RTL8225_ANAPARAM2_ON); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl8225_write_phy_ofdm(dev, 2, 0x42); - rtl8225_write_phy_ofdm(dev, 6, 0x00); - rtl8225_write_phy_ofdm(dev, 8, 0x00); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, - rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1); - - tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; - - rtl8225_write_phy_ofdm(dev, 5, *tmp); - rtl8225_write_phy_ofdm(dev, 7, *tmp); - - msleep(1); -} - -static void rtl8225_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - int i; - - rtl8225_write(dev, 0x0, 0x067); - rtl8225_write(dev, 0x1, 0xFE0); - rtl8225_write(dev, 0x2, 0x44D); - rtl8225_write(dev, 0x3, 0x441); - rtl8225_write(dev, 0x4, 0x486); - rtl8225_write(dev, 0x5, 0xBC0); - rtl8225_write(dev, 0x6, 0xAE6); - rtl8225_write(dev, 0x7, 0x82A); - rtl8225_write(dev, 0x8, 0x01F); - rtl8225_write(dev, 0x9, 0x334); - rtl8225_write(dev, 0xA, 0xFD4); - rtl8225_write(dev, 0xB, 0x391); - rtl8225_write(dev, 0xC, 0x050); - rtl8225_write(dev, 0xD, 0x6DB); - rtl8225_write(dev, 0xE, 0x029); - rtl8225_write(dev, 0xF, 0x914); msleep(100); - - rtl8225_write(dev, 0x2, 0xC4D); msleep(200); - rtl8225_write(dev, 0x2, 0x44D); msleep(200); - - if (!(rtl8225_read(dev, 6) & (1 << 7))) { - rtl8225_write(dev, 0x02, 0x0c4d); - msleep(200); - rtl8225_write(dev, 0x02, 0x044d); - msleep(100); - if (!(rtl8225_read(dev, 6) & (1 << 7))) - wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", - rtl8225_read(dev, 6)); - } - - rtl8225_write(dev, 0x0, 0x127); - - for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { - rtl8225_write(dev, 0x1, i + 1); - rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); - } - - rtl8225_write(dev, 0x0, 0x027); - rtl8225_write(dev, 0x0, 0x22F); - - for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { - rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); - rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); - } - - msleep(1); - - rtl8225_write_phy_ofdm(dev, 0x00, 0x01); - rtl8225_write_phy_ofdm(dev, 0x01, 0x02); - rtl8225_write_phy_ofdm(dev, 0x02, 0x42); - rtl8225_write_phy_ofdm(dev, 0x03, 0x00); - rtl8225_write_phy_ofdm(dev, 0x04, 0x00); - rtl8225_write_phy_ofdm(dev, 0x05, 0x00); - rtl8225_write_phy_ofdm(dev, 0x06, 0x40); - rtl8225_write_phy_ofdm(dev, 0x07, 0x00); - rtl8225_write_phy_ofdm(dev, 0x08, 0x40); - rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); - rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); - rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); - rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); - rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); - rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); - rtl8225_write_phy_ofdm(dev, 0x10, 0x84); - rtl8225_write_phy_ofdm(dev, 0x11, 0x06); - rtl8225_write_phy_ofdm(dev, 0x12, 0x20); - rtl8225_write_phy_ofdm(dev, 0x13, 0x20); - rtl8225_write_phy_ofdm(dev, 0x14, 0x00); - rtl8225_write_phy_ofdm(dev, 0x15, 0x40); - rtl8225_write_phy_ofdm(dev, 0x16, 0x00); - rtl8225_write_phy_ofdm(dev, 0x17, 0x40); - rtl8225_write_phy_ofdm(dev, 0x18, 0xef); - rtl8225_write_phy_ofdm(dev, 0x19, 0x19); - rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); - rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); - rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); - rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); - rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); - rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); - rtl8225_write_phy_ofdm(dev, 0x21, 0x27); - rtl8225_write_phy_ofdm(dev, 0x22, 0x16); - rtl8225_write_phy_ofdm(dev, 0x24, 0x46); - rtl8225_write_phy_ofdm(dev, 0x25, 0x20); - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); - rtl8225_write_phy_ofdm(dev, 0x27, 0x88); - - rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); - rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); - rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); - rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); - - rtl8225_write_phy_cck(dev, 0x00, 0x98); - rtl8225_write_phy_cck(dev, 0x03, 0x20); - rtl8225_write_phy_cck(dev, 0x04, 0x7e); - rtl8225_write_phy_cck(dev, 0x05, 0x12); - rtl8225_write_phy_cck(dev, 0x06, 0xfc); - rtl8225_write_phy_cck(dev, 0x07, 0x78); - rtl8225_write_phy_cck(dev, 0x08, 0x2e); - rtl8225_write_phy_cck(dev, 0x10, 0x9b); - rtl8225_write_phy_cck(dev, 0x11, 0x88); - rtl8225_write_phy_cck(dev, 0x12, 0x47); - rtl8225_write_phy_cck(dev, 0x13, 0xd0); - rtl8225_write_phy_cck(dev, 0x19, 0x00); - rtl8225_write_phy_cck(dev, 0x1a, 0xa0); - rtl8225_write_phy_cck(dev, 0x1b, 0x08); - rtl8225_write_phy_cck(dev, 0x40, 0x86); - rtl8225_write_phy_cck(dev, 0x41, 0x8d); - rtl8225_write_phy_cck(dev, 0x42, 0x15); - rtl8225_write_phy_cck(dev, 0x43, 0x18); - rtl8225_write_phy_cck(dev, 0x44, 0x1f); - rtl8225_write_phy_cck(dev, 0x45, 0x1e); - rtl8225_write_phy_cck(dev, 0x46, 0x1a); - rtl8225_write_phy_cck(dev, 0x47, 0x15); - rtl8225_write_phy_cck(dev, 0x48, 0x10); - rtl8225_write_phy_cck(dev, 0x49, 0x0a); - rtl8225_write_phy_cck(dev, 0x4a, 0x05); - rtl8225_write_phy_cck(dev, 0x4b, 0x02); - rtl8225_write_phy_cck(dev, 0x4c, 0x05); - - rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); - - rtl8225_rf_set_tx_power(dev, 1); - - /* RX antenna default to A */ - rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ - - rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ - msleep(1); - rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); - - /* set sensitivity */ - rtl8225_write(dev, 0x0c, 0x50); - rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); - rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); - rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); - rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); - rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); -} - -static const u8 rtl8225z2_agc[] = { - 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f, - 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37, - 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, - 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07, - 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, - 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, - 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -}; -static const u8 rtl8225z2_ofdm[] = { - 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60, - 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, - 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26, - 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3, - 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f, - 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, - 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, - 0x6d, 0x3c, 0xfb, 0x07 -}; - -static const u8 rtl8225z2_tx_power_cck_ch14[] = { - 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 -}; - -static const u8 rtl8225z2_tx_power_cck[] = { - 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04, - 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, - 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03, - 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 -}; - -static const u8 rtl8225z2_tx_power_ofdm[] = { - 0x42, 0x00, 0x40, 0x00, 0x40 -}; - -static const u8 rtl8225z2_tx_gain_cck_ofdm[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 -}; - -static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) -{ - struct rtl8187_priv *priv = dev->priv; - u8 cck_power, ofdm_power; - const u8 *tmp; - u32 reg; - int i; - - cck_power = priv->channels[channel - 1].hw_value & 0xF; - ofdm_power = priv->channels[channel - 1].hw_value >> 4; - - cck_power = min(cck_power, (u8)15); - cck_power += priv->txpwr_base & 0xF; - cck_power = min(cck_power, (u8)35); - - if (ofdm_power > (u8)15) - ofdm_power = 25; - else - ofdm_power += 10; - ofdm_power += priv->txpwr_base >> 4; - ofdm_power = min(ofdm_power, (u8)35); - - if (channel == 14) - tmp = rtl8225z2_tx_power_cck_ch14; - else - tmp = rtl8225z2_tx_power_cck; - - for (i = 0; i < 8; i++) - rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, - rtl8225z2_tx_gain_cck_ofdm[cck_power]); - msleep(1); - - /* anaparam2 on */ - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); - reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg | RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, - RTL8187_RTL8225_ANAPARAM2_ON); - rtl818x_iowrite8(priv, &priv->map->CONFIG3, - reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); - rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - - rtl8225_write_phy_ofdm(dev, 2, 0x42); - rtl8225_write_phy_ofdm(dev, 5, 0x00); - rtl8225_write_phy_ofdm(dev, 6, 0x40); - rtl8225_write_phy_ofdm(dev, 7, 0x00); - rtl8225_write_phy_ofdm(dev, 8, 0x40); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, - rtl8225z2_tx_gain_cck_ofdm[ofdm_power]); - msleep(1); -} - -static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel) -{ - struct rtl8187_priv *priv = dev->priv; - u8 cck_power, ofdm_power; - const u8 *tmp; - int i; - - cck_power = priv->channels[channel - 1].hw_value & 0xF; - ofdm_power = priv->channels[channel - 1].hw_value >> 4; - - if (cck_power > 15) - cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22; - else - cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; - cck_power += priv->txpwr_base & 0xF; - cck_power = min(cck_power, (u8)35); - - if (ofdm_power > 15) - ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25; - else - ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10; - ofdm_power += (priv->txpwr_base >> 4) & 0xF; - ofdm_power = min(ofdm_power, (u8)35); - - if (channel == 14) - tmp = rtl8225z2_tx_power_cck_ch14; - else - tmp = rtl8225z2_tx_power_cck; - - if (priv->hw_rev == RTL8187BvB) { - if (cck_power <= 6) - ; /* do nothing */ - else if (cck_power <= 11) - tmp += 8; - else - tmp += 16; - } else { - if (cck_power <= 5) - ; /* do nothing */ - else if (cck_power <= 11) - tmp += 8; - else if (cck_power <= 17) - tmp += 16; - else - tmp += 24; - } - - for (i = 0; i < 8; i++) - rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, - rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1); - msleep(1); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, - rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1); - if (priv->hw_rev == RTL8187BvB) { - if (ofdm_power <= 11) { - rtl8225_write_phy_ofdm(dev, 0x87, 0x60); - rtl8225_write_phy_ofdm(dev, 0x89, 0x60); - } else { - rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); - rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); - } - } else { - if (ofdm_power <= 11) { - rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); - rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); - } else if (ofdm_power <= 17) { - rtl8225_write_phy_ofdm(dev, 0x87, 0x54); - rtl8225_write_phy_ofdm(dev, 0x89, 0x54); - } else { - rtl8225_write_phy_ofdm(dev, 0x87, 0x50); - rtl8225_write_phy_ofdm(dev, 0x89, 0x50); - } - } - msleep(1); -} - -static const u16 rtl8225z2_rxgain[] = { - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, - 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, - 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, - 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, - 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, - 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, - 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, - 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, - 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, - 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, - 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, - 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb -}; - -static const u8 rtl8225z2_gain_bg[] = { - 0x23, 0x15, 0xa5, /* -82-1dBm */ - 0x23, 0x15, 0xb5, /* -82-2dBm */ - 0x23, 0x15, 0xc5, /* -82-3dBm */ - 0x33, 0x15, 0xc5, /* -78dBm */ - 0x43, 0x15, 0xc5, /* -74dBm */ - 0x53, 0x15, 0xc5, /* -70dBm */ - 0x63, 0x15, 0xc5 /* -66dBm */ -}; - -static void rtl8225z2_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - int i; - - rtl8225_write(dev, 0x0, 0x2BF); - rtl8225_write(dev, 0x1, 0xEE0); - rtl8225_write(dev, 0x2, 0x44D); - rtl8225_write(dev, 0x3, 0x441); - rtl8225_write(dev, 0x4, 0x8C3); - rtl8225_write(dev, 0x5, 0xC72); - rtl8225_write(dev, 0x6, 0x0E6); - rtl8225_write(dev, 0x7, 0x82A); - rtl8225_write(dev, 0x8, 0x03F); - rtl8225_write(dev, 0x9, 0x335); - rtl8225_write(dev, 0xa, 0x9D4); - rtl8225_write(dev, 0xb, 0x7BB); - rtl8225_write(dev, 0xc, 0x850); - rtl8225_write(dev, 0xd, 0xCDF); - rtl8225_write(dev, 0xe, 0x02B); - rtl8225_write(dev, 0xf, 0x114); - msleep(100); - - rtl8225_write(dev, 0x0, 0x1B7); - - for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { - rtl8225_write(dev, 0x1, i + 1); - rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); - } - - rtl8225_write(dev, 0x3, 0x080); - rtl8225_write(dev, 0x5, 0x004); - rtl8225_write(dev, 0x0, 0x0B7); - rtl8225_write(dev, 0x2, 0xc4D); - - msleep(200); - rtl8225_write(dev, 0x2, 0x44D); - msleep(100); - - if (!(rtl8225_read(dev, 6) & (1 << 7))) { - rtl8225_write(dev, 0x02, 0x0C4D); - msleep(200); - rtl8225_write(dev, 0x02, 0x044D); - msleep(100); - if (!(rtl8225_read(dev, 6) & (1 << 7))) - wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", - rtl8225_read(dev, 6)); - } - - msleep(200); - - rtl8225_write(dev, 0x0, 0x2BF); - - for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { - rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); - rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); - } - - msleep(1); - - rtl8225_write_phy_ofdm(dev, 0x00, 0x01); - rtl8225_write_phy_ofdm(dev, 0x01, 0x02); - rtl8225_write_phy_ofdm(dev, 0x02, 0x42); - rtl8225_write_phy_ofdm(dev, 0x03, 0x00); - rtl8225_write_phy_ofdm(dev, 0x04, 0x00); - rtl8225_write_phy_ofdm(dev, 0x05, 0x00); - rtl8225_write_phy_ofdm(dev, 0x06, 0x40); - rtl8225_write_phy_ofdm(dev, 0x07, 0x00); - rtl8225_write_phy_ofdm(dev, 0x08, 0x40); - rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); - rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); - rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); - rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); - rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); - rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); - rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); - rtl8225_write_phy_ofdm(dev, 0x10, 0x84); - rtl8225_write_phy_ofdm(dev, 0x11, 0x07); - rtl8225_write_phy_ofdm(dev, 0x12, 0x20); - rtl8225_write_phy_ofdm(dev, 0x13, 0x20); - rtl8225_write_phy_ofdm(dev, 0x14, 0x00); - rtl8225_write_phy_ofdm(dev, 0x15, 0x40); - rtl8225_write_phy_ofdm(dev, 0x16, 0x00); - rtl8225_write_phy_ofdm(dev, 0x17, 0x40); - rtl8225_write_phy_ofdm(dev, 0x18, 0xef); - rtl8225_write_phy_ofdm(dev, 0x19, 0x19); - rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); - rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); - rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); - rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); - rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); - rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); - rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); - rtl8225_write_phy_ofdm(dev, 0x21, 0x17); - rtl8225_write_phy_ofdm(dev, 0x22, 0x16); - rtl8225_write_phy_ofdm(dev, 0x23, 0x80); - rtl8225_write_phy_ofdm(dev, 0x24, 0x46); - rtl8225_write_phy_ofdm(dev, 0x25, 0x00); - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); - rtl8225_write_phy_ofdm(dev, 0x27, 0x88); - - rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); - rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); - rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); - rtl8225_write_phy_ofdm(dev, 0x21, 0x37); - - rtl8225_write_phy_cck(dev, 0x00, 0x98); - rtl8225_write_phy_cck(dev, 0x03, 0x20); - rtl8225_write_phy_cck(dev, 0x04, 0x7e); - rtl8225_write_phy_cck(dev, 0x05, 0x12); - rtl8225_write_phy_cck(dev, 0x06, 0xfc); - rtl8225_write_phy_cck(dev, 0x07, 0x78); - rtl8225_write_phy_cck(dev, 0x08, 0x2e); - rtl8225_write_phy_cck(dev, 0x10, 0x9b); - rtl8225_write_phy_cck(dev, 0x11, 0x88); - rtl8225_write_phy_cck(dev, 0x12, 0x47); - rtl8225_write_phy_cck(dev, 0x13, 0xd0); - rtl8225_write_phy_cck(dev, 0x19, 0x00); - rtl8225_write_phy_cck(dev, 0x1a, 0xa0); - rtl8225_write_phy_cck(dev, 0x1b, 0x08); - rtl8225_write_phy_cck(dev, 0x40, 0x86); - rtl8225_write_phy_cck(dev, 0x41, 0x8d); - rtl8225_write_phy_cck(dev, 0x42, 0x15); - rtl8225_write_phy_cck(dev, 0x43, 0x18); - rtl8225_write_phy_cck(dev, 0x44, 0x36); - rtl8225_write_phy_cck(dev, 0x45, 0x35); - rtl8225_write_phy_cck(dev, 0x46, 0x2e); - rtl8225_write_phy_cck(dev, 0x47, 0x25); - rtl8225_write_phy_cck(dev, 0x48, 0x1c); - rtl8225_write_phy_cck(dev, 0x49, 0x12); - rtl8225_write_phy_cck(dev, 0x4a, 0x09); - rtl8225_write_phy_cck(dev, 0x4b, 0x04); - rtl8225_write_phy_cck(dev, 0x4c, 0x05); - - rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); - - rtl8225z2_rf_set_tx_power(dev, 1); - - /* RX antenna default to A */ - rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ - rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ - - rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ - msleep(1); - rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); -} - -static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) -{ - struct rtl8187_priv *priv = dev->priv; - int i; - - rtl8225_write(dev, 0x0, 0x0B7); - rtl8225_write(dev, 0x1, 0xEE0); - rtl8225_write(dev, 0x2, 0x44D); - rtl8225_write(dev, 0x3, 0x441); - rtl8225_write(dev, 0x4, 0x8C3); - rtl8225_write(dev, 0x5, 0xC72); - rtl8225_write(dev, 0x6, 0x0E6); - rtl8225_write(dev, 0x7, 0x82A); - rtl8225_write(dev, 0x8, 0x03F); - rtl8225_write(dev, 0x9, 0x335); - rtl8225_write(dev, 0xa, 0x9D4); - rtl8225_write(dev, 0xb, 0x7BB); - rtl8225_write(dev, 0xc, 0x850); - rtl8225_write(dev, 0xd, 0xCDF); - rtl8225_write(dev, 0xe, 0x02B); - rtl8225_write(dev, 0xf, 0x114); - - rtl8225_write(dev, 0x0, 0x1B7); - - for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { - rtl8225_write(dev, 0x1, i + 1); - rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); - } - - rtl8225_write(dev, 0x3, 0x080); - rtl8225_write(dev, 0x5, 0x004); - rtl8225_write(dev, 0x0, 0x0B7); - - rtl8225_write(dev, 0x2, 0xC4D); - - rtl8225_write(dev, 0x2, 0x44D); - rtl8225_write(dev, 0x0, 0x2BF); - - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03); - rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07); - rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); - - rtl8225_write_phy_ofdm(dev, 0x80, 0x12); - for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) { - rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]); - rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i); - rtl8225_write_phy_ofdm(dev, 0xE, 0); - } - rtl8225_write_phy_ofdm(dev, 0x80, 0x10); - - for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) - rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]); - - rtl8225_write_phy_ofdm(dev, 0x97, 0x46); - rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); - rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); - rtl8225_write_phy_cck(dev, 0xc1, 0x88); -} - -static void rtl8225_rf_stop(struct ieee80211_hw *dev) -{ - rtl8225_write(dev, 0x4, 0x1f); -} - -static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, - struct ieee80211_conf *conf) -{ - struct rtl8187_priv *priv = dev->priv; - int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); - - if (priv->rf->init == rtl8225_rf_init) - rtl8225_rf_set_tx_power(dev, chan); - else if (priv->rf->init == rtl8225z2_rf_init) - rtl8225z2_rf_set_tx_power(dev, chan); - else - rtl8225z2_b_rf_set_tx_power(dev, chan); - - rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); - msleep(10); -} - -static const struct rtl818x_rf_ops rtl8225_ops = { - .name = "rtl8225", - .init = rtl8225_rf_init, - .stop = rtl8225_rf_stop, - .set_chan = rtl8225_rf_set_channel -}; - -static const struct rtl818x_rf_ops rtl8225z2_ops = { - .name = "rtl8225z2", - .init = rtl8225z2_rf_init, - .stop = rtl8225_rf_stop, - .set_chan = rtl8225_rf_set_channel -}; - -static const struct rtl818x_rf_ops rtl8225z2_b_ops = { - .name = "rtl8225z2", - .init = rtl8225z2_b_rf_init, - .stop = rtl8225_rf_stop, - .set_chan = rtl8225_rf_set_channel -}; - -const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) -{ - u16 reg8, reg9; - struct rtl8187_priv *priv = dev->priv; - - if (!priv->is_rtl8187b) { - rtl8225_write(dev, 0, 0x1B7); - - reg8 = rtl8225_read(dev, 8); - reg9 = rtl8225_read(dev, 9); - - rtl8225_write(dev, 0, 0x0B7); - - if (reg8 != 0x588 || reg9 != 0x700) - return &rtl8225_ops; - - return &rtl8225z2_ops; - } else - return &rtl8225z2_b_ops; -} diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h deleted file mode 100644 index 20c5b6ead0f6..000000000000 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Radio tuning definitions for RTL8225 on RTL8187 - * - * Copyright 2007 Michael Wu - * Copyright 2007 Andrea Merello - * - * Based on the r8187 driver, which is: - * Copyright 2005 Andrea Merello , et al. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef RTL8187_RTL8225_H -#define RTL8187_RTL8225_H - -#define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59 -#define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312 -#define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59 -#define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11 - -#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658 -#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52 -#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00 -#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658 -#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50 -#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00 - -const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); - -static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, - u8 addr, u32 data) -{ - rtl8187_write_phy(dev, addr, data); -} - -static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, - u8 addr, u32 data) -{ - rtl8187_write_phy(dev, addr, data | 0x10000); -} - -#endif /* RTL8187_RTL8225_H */ -- cgit v1.2.3-59-g8ed1b From fe67c913f1ec2a01aaa9176c80ef36eaf87d705d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 27 Nov 2010 20:02:59 +0100 Subject: mac80211: make LED trigger names available early The throughput trigger will require doing LED classdev/trigger handling before register_hw(), so drivers should have access to the trigger names before it. If trigger registration fails, this will still make the trigger name available, but that's not a big problem since the default trigger will the simply not be found. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/led.c | 36 ++++++++++++++++-------------------- net/mac80211/led.h | 4 ++++ net/mac80211/main.c | 2 ++ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/net/mac80211/led.c b/net/mac80211/led.c index 063aad944246..740a1d4e0a9c 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -54,12 +54,22 @@ void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) led_trigger_event(local->radio_led, LED_OFF); } +void ieee80211_led_names(struct ieee80211_local *local) +{ + snprintf(local->rx_led_name, sizeof(local->rx_led_name), + "%srx", wiphy_name(local->hw.wiphy)); + snprintf(local->tx_led_name, sizeof(local->tx_led_name), + "%stx", wiphy_name(local->hw.wiphy)); + snprintf(local->assoc_led_name, sizeof(local->assoc_led_name), + "%sassoc", wiphy_name(local->hw.wiphy)); + snprintf(local->radio_led_name, sizeof(local->radio_led_name), + "%sradio", wiphy_name(local->hw.wiphy)); +} + void ieee80211_led_init(struct ieee80211_local *local) { local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); if (local->rx_led) { - snprintf(local->rx_led_name, sizeof(local->rx_led_name), - "%srx", wiphy_name(local->hw.wiphy)); local->rx_led->name = local->rx_led_name; if (led_trigger_register(local->rx_led)) { kfree(local->rx_led); @@ -69,8 +79,6 @@ void ieee80211_led_init(struct ieee80211_local *local) local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); if (local->tx_led) { - snprintf(local->tx_led_name, sizeof(local->tx_led_name), - "%stx", wiphy_name(local->hw.wiphy)); local->tx_led->name = local->tx_led_name; if (led_trigger_register(local->tx_led)) { kfree(local->tx_led); @@ -80,8 +88,6 @@ void ieee80211_led_init(struct ieee80211_local *local) local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); if (local->assoc_led) { - snprintf(local->assoc_led_name, sizeof(local->assoc_led_name), - "%sassoc", wiphy_name(local->hw.wiphy)); local->assoc_led->name = local->assoc_led_name; if (led_trigger_register(local->assoc_led)) { kfree(local->assoc_led); @@ -91,8 +97,6 @@ void ieee80211_led_init(struct ieee80211_local *local) local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); if (local->radio_led) { - snprintf(local->radio_led_name, sizeof(local->radio_led_name), - "%sradio", wiphy_name(local->hw.wiphy)); local->radio_led->name = local->radio_led_name; if (led_trigger_register(local->radio_led)) { kfree(local->radio_led); @@ -125,9 +129,7 @@ char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - if (local->radio_led) - return local->radio_led_name; - return NULL; + return local->radio_led_name; } EXPORT_SYMBOL(__ieee80211_get_radio_led_name); @@ -135,9 +137,7 @@ char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - if (local->assoc_led) - return local->assoc_led_name; - return NULL; + return local->assoc_led_name; } EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); @@ -145,9 +145,7 @@ char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - if (local->tx_led) - return local->tx_led_name; - return NULL; + return local->tx_led_name; } EXPORT_SYMBOL(__ieee80211_get_tx_led_name); @@ -155,8 +153,6 @@ char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - if (local->rx_led) - return local->rx_led_name; - return NULL; + return local->rx_led_name; } EXPORT_SYMBOL(__ieee80211_get_rx_led_name); diff --git a/net/mac80211/led.h b/net/mac80211/led.h index 77b1e1ba6039..8320cbac61c6 100644 --- a/net/mac80211/led.h +++ b/net/mac80211/led.h @@ -18,6 +18,7 @@ extern void ieee80211_led_assoc(struct ieee80211_local *local, bool associated); extern void ieee80211_led_radio(struct ieee80211_local *local, bool enabled); +extern void ieee80211_led_names(struct ieee80211_local *local); extern void ieee80211_led_init(struct ieee80211_local *local); extern void ieee80211_led_exit(struct ieee80211_local *local); #else @@ -35,6 +36,9 @@ static inline void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) { } +static inline void ieee80211_led_names(struct ieee80211_local *local) +{ +} static inline void ieee80211_led_init(struct ieee80211_local *local) { } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a21d049caf19..bbe8e0ac6e52 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -605,6 +605,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, /* init dummy netdev for use w/ NAPI */ init_dummy_netdev(&local->napi_dev); + ieee80211_led_names(local); + return local_to_hw(local); } EXPORT_SYMBOL(ieee80211_alloc_hw); -- cgit v1.2.3-59-g8ed1b From e1e5406854378dfada3f33c7192b012083a5b8e0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 08:58:45 +0100 Subject: mac80211: add throughput based LED blink trigger iwlwifi and other drivers like to blink their LED based on throughput. Implement this generically in mac80211, based on a throughput table the driver specifies. That way, drivers can set the blink frequencies depending on their desired behaviour and max throughput. All the drivers need to do is provide an LED class device, best with blink hardware offload. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 38 ++++++++++++++ net/mac80211/ieee80211_i.h | 13 +++++ net/mac80211/iface.c | 1 + net/mac80211/led.c | 121 +++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/led.h | 44 +++++++++++++---- net/mac80211/rx.c | 3 ++ net/mac80211/tx.c | 3 ++ net/mac80211/util.c | 2 + 8 files changed, 216 insertions(+), 9 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 69ded1ee49ce..40a93d582c79 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1852,11 +1852,26 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, */ int ieee80211_register_hw(struct ieee80211_hw *hw); +/** + * struct ieee80211_tpt_blink - throughput blink description + * @throughput: throughput in Kbit/sec + * @blink_time: blink time in milliseconds + * (full cycle, ie. one off + one on period) + */ +struct ieee80211_tpt_blink { + int throughput; + int blink_time; +}; + #ifdef CONFIG_MAC80211_LEDS extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); +extern char *__ieee80211_create_tpt_led_trigger( + struct ieee80211_hw *hw, + const struct ieee80211_tpt_blink *blink_table, + unsigned int blink_table_len); #endif /** * ieee80211_get_tx_led_name - get name of TX LED @@ -1934,6 +1949,29 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) #endif } +/** + * ieee80211_create_tpt_led_trigger - create throughput LED trigger + * @hw: the hardware to create the trigger for + * @blink_table: the blink table -- needs to be ordered by throughput + * @blink_table_len: size of the blink table + * + * This function returns %NULL (in case of error, or if no LED + * triggers are configured) or the name of the new trigger. + * This function must be called before ieee80211_register_hw(). + */ +static inline char * +ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, + const struct ieee80211_tpt_blink *blink_table, + unsigned int blink_table_len) +{ +#ifdef CONFIG_MAC80211_LEDS + return __ieee80211_create_tpt_led_trigger(hw, blink_table, + blink_table_len); +#else + return NULL; +#endif +} + /** * ieee80211_unregister_hw - Unregister a hardware device * diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eadaa243a3da..523b90be8dc5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -630,6 +631,17 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_SKB_ADD, }; +struct tpt_led_trigger { + struct led_trigger trig; + char name[32]; + const struct ieee80211_tpt_blink *blink_table; + unsigned int blink_table_len; + struct timer_list timer; + bool running; + unsigned long prev_traffic; + unsigned long tx_bytes, rx_bytes; +}; + /** * mac80211 scan flags - currently active scan mode * @@ -838,6 +850,7 @@ struct ieee80211_local { #ifdef CONFIG_MAC80211_LEDS int tx_led_counter, rx_led_counter; struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; + struct tpt_led_trigger *tpt_led_trigger; char tx_led_name[32], rx_led_name[32], assoc_led_name[32], radio_led_name[32]; #endif diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index f0f11bb794af..989df7065c21 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -220,6 +220,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) /* we're brought up, everything changes */ hw_reconf_flags = ~0; ieee80211_led_radio(local, true); + ieee80211_start_tpt_led_trig(local); } /* diff --git a/net/mac80211/led.c b/net/mac80211/led.c index 740a1d4e0a9c..79b13090aed7 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -103,6 +103,13 @@ void ieee80211_led_init(struct ieee80211_local *local) local->radio_led = NULL; } } + + if (local->tpt_led_trigger) { + if (led_trigger_register(&local->tpt_led_trigger->trig)) { + kfree(local->tpt_led_trigger); + local->tpt_led_trigger = NULL; + } + } } void ieee80211_led_exit(struct ieee80211_local *local) @@ -123,6 +130,11 @@ void ieee80211_led_exit(struct ieee80211_local *local) led_trigger_unregister(local->rx_led); kfree(local->rx_led); } + + if (local->tpt_led_trigger) { + led_trigger_unregister(&local->tpt_led_trigger->trig); + kfree(local->tpt_led_trigger); + } } char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) @@ -156,3 +168,112 @@ char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw) return local->rx_led_name; } EXPORT_SYMBOL(__ieee80211_get_rx_led_name); + +static unsigned long tpt_trig_traffic(struct ieee80211_local *local, + struct tpt_led_trigger *tpt_trig) +{ + unsigned long traffic, delta; + + traffic = tpt_trig->tx_bytes + tpt_trig->rx_bytes; + + delta = traffic - tpt_trig->prev_traffic; + tpt_trig->prev_traffic = traffic; + return DIV_ROUND_UP(delta, 1024 / 8); +} + +static void tpt_trig_timer(unsigned long data) +{ + struct ieee80211_local *local = (void *)data; + struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; + struct led_classdev *led_cdev; + unsigned long on, off, tpt; + int i; + + if (!tpt_trig->running) + return; + + mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); + + tpt = tpt_trig_traffic(local, tpt_trig); + + /* default to just solid on */ + on = 1; + off = 0; + + for (i = tpt_trig->blink_table_len - 1; i >= 0; i--) { + if (tpt_trig->blink_table[i].throughput < 0 || + tpt > tpt_trig->blink_table[i].throughput) { + off = tpt_trig->blink_table[i].blink_time / 2; + on = tpt_trig->blink_table[i].blink_time - off; + break; + } + } + + read_lock(&tpt_trig->trig.leddev_list_lock); + list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list) + led_blink_set(led_cdev, &on, &off); + read_unlock(&tpt_trig->trig.leddev_list_lock); +} + +extern char *__ieee80211_create_tpt_led_trigger( + struct ieee80211_hw *hw, + const struct ieee80211_tpt_blink *blink_table, + unsigned int blink_table_len) +{ + struct ieee80211_local *local = hw_to_local(hw); + struct tpt_led_trigger *tpt_trig; + + if (WARN_ON(local->tpt_led_trigger)) + return NULL; + + tpt_trig = kzalloc(sizeof(struct tpt_led_trigger), GFP_KERNEL); + if (!tpt_trig) + return NULL; + + snprintf(tpt_trig->name, sizeof(tpt_trig->name), + "%stpt", wiphy_name(local->hw.wiphy)); + + tpt_trig->trig.name = tpt_trig->name; + + tpt_trig->blink_table = blink_table; + tpt_trig->blink_table_len = blink_table_len; + + setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local); + + local->tpt_led_trigger = tpt_trig; + + return tpt_trig->name; +} +EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger); + +void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) +{ + struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; + + if (!tpt_trig) + return; + + /* reset traffic */ + tpt_trig_traffic(local, tpt_trig); + tpt_trig->running = true; + + tpt_trig_timer((unsigned long)local); + mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); +} + +void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) +{ + struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; + struct led_classdev *led_cdev; + + if (!tpt_trig) + return; + + tpt_trig->running = false; + del_timer_sync(&tpt_trig->timer); + + read_lock(&tpt_trig->trig.leddev_list_lock); + list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list) + led_brightness_set(led_cdev, LED_OFF); + read_unlock(&tpt_trig->trig.leddev_list_lock); +} diff --git a/net/mac80211/led.h b/net/mac80211/led.h index 8320cbac61c6..6c215dc0fc96 100644 --- a/net/mac80211/led.h +++ b/net/mac80211/led.h @@ -12,15 +12,17 @@ #include "ieee80211_i.h" #ifdef CONFIG_MAC80211_LEDS -extern void ieee80211_led_rx(struct ieee80211_local *local); -extern void ieee80211_led_tx(struct ieee80211_local *local, int q); -extern void ieee80211_led_assoc(struct ieee80211_local *local, - bool associated); -extern void ieee80211_led_radio(struct ieee80211_local *local, - bool enabled); -extern void ieee80211_led_names(struct ieee80211_local *local); -extern void ieee80211_led_init(struct ieee80211_local *local); -extern void ieee80211_led_exit(struct ieee80211_local *local); +void ieee80211_led_rx(struct ieee80211_local *local); +void ieee80211_led_tx(struct ieee80211_local *local, int q); +void ieee80211_led_assoc(struct ieee80211_local *local, + bool associated); +void ieee80211_led_radio(struct ieee80211_local *local, + bool enabled); +void ieee80211_led_names(struct ieee80211_local *local); +void ieee80211_led_init(struct ieee80211_local *local); +void ieee80211_led_exit(struct ieee80211_local *local); +void ieee80211_start_tpt_led_trig(struct ieee80211_local *local); +void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local); #else static inline void ieee80211_led_rx(struct ieee80211_local *local) { @@ -45,4 +47,28 @@ static inline void ieee80211_led_init(struct ieee80211_local *local) static inline void ieee80211_led_exit(struct ieee80211_local *local) { } +static inline void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) +{ +} +static inline void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) +{ +} +#endif + +static inline void +ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes) +{ +#ifdef CONFIG_MAC80211_LEDS + if (local->tpt_led_trigger && ieee80211_is_data(fc)) + local->tpt_led_trigger->tx_bytes += bytes; #endif +} + +static inline void +ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes) +{ +#ifdef CONFIG_MAC80211_LEDS + if (local->tpt_led_trigger && ieee80211_is_data(fc)) + local->tpt_led_trigger->rx_bytes += bytes; +#endif +} diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7c5d1b2ec453..01a3f2630eaf 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2928,6 +2928,9 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) return; } + ieee80211_tpt_led_trig_rx(local, + ((struct ieee80211_hdr *)skb->data)->frame_control, + skb->len); __ieee80211_rx_handle_packet(hw, skb); rcu_read_unlock(); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d2b4b67a7b53..68c2fbd16ebb 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1297,6 +1297,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, while (skb) { int q = skb_get_queue_mapping(skb); + __le16 fc; spin_lock_irqsave(&local->queue_stop_reason_lock, flags); ret = IEEE80211_TX_OK; @@ -1339,6 +1340,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, else info->control.sta = NULL; + fc = ((struct ieee80211_hdr *)skb->data)->frame_control; ret = drv_tx(local, skb); if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { dev_kfree_skb(skb); @@ -1349,6 +1351,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, return IEEE80211_TX_AGAIN; } + ieee80211_tpt_led_trig_tx(local, fc, len); *skbp = skb = next; ieee80211_led_tx(local, 1); fragm = true; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e497476174ce..48306415a1cb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1116,6 +1116,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, void ieee80211_stop_device(struct ieee80211_local *local) { ieee80211_led_radio(local, false); + ieee80211_stop_tpt_led_trig(local); cancel_work_sync(&local->reconfig_filter); @@ -1150,6 +1151,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) } ieee80211_led_radio(local, true); + ieee80211_start_tpt_led_trig(local); } /* add interfaces */ -- cgit v1.2.3-59-g8ed1b From 67408c8c7b9daf28b50e33be3541334c07d15789 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 08:59:23 +0100 Subject: mac80211: selective throughput LED trigger active The throughput LED trigger was always active when the radio was enabled. In most cases that's likely the desired behaviour, but iwlwifi requires it to be only active when one of the virtual interfaces is actually "connected" in some way. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 20 +++++++++++++++++--- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/iface.c | 16 +++++++++++++++- net/mac80211/led.c | 39 ++++++++++++++++++++++++++++++++++----- net/mac80211/led.h | 11 +++++------ net/mac80211/util.c | 5 +++-- 6 files changed, 76 insertions(+), 18 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 40a93d582c79..479c35e160e3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1863,13 +1863,26 @@ struct ieee80211_tpt_blink { int blink_time; }; +/** + * enum ieee80211_tpt_led_trigger_flags - throughput trigger flags + * @IEEE80211_TPT_LEDTRIG_FL_RADIO: enable blinking with radio + * @IEEE80211_TPT_LEDTRIG_FL_WORK: enable blinking when working + * @IEEE80211_TPT_LEDTRIG_FL_CONNECTED: enable blinking when at least one + * interface is connected in some way, including being an AP + */ +enum ieee80211_tpt_led_trigger_flags { + IEEE80211_TPT_LEDTRIG_FL_RADIO = BIT(0), + IEEE80211_TPT_LEDTRIG_FL_WORK = BIT(1), + IEEE80211_TPT_LEDTRIG_FL_CONNECTED = BIT(2), +}; + #ifdef CONFIG_MAC80211_LEDS extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); extern char *__ieee80211_create_tpt_led_trigger( - struct ieee80211_hw *hw, + struct ieee80211_hw *hw, unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len); #endif @@ -1952,6 +1965,7 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) /** * ieee80211_create_tpt_led_trigger - create throughput LED trigger * @hw: the hardware to create the trigger for + * @flags: trigger flags, see &enum ieee80211_tpt_led_trigger_flags * @blink_table: the blink table -- needs to be ordered by throughput * @blink_table_len: size of the blink table * @@ -1960,12 +1974,12 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) * This function must be called before ieee80211_register_hw(). */ static inline char * -ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, +ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len) { #ifdef CONFIG_MAC80211_LEDS - return __ieee80211_create_tpt_led_trigger(hw, blink_table, + return __ieee80211_create_tpt_led_trigger(hw, flags, blink_table, blink_table_len); #else return NULL; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 523b90be8dc5..3810c72ac062 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -637,9 +637,10 @@ struct tpt_led_trigger { const struct ieee80211_tpt_blink *blink_table; unsigned int blink_table_len; struct timer_list timer; - bool running; unsigned long prev_traffic; unsigned long tx_bytes, rx_bytes; + unsigned int active, want; + bool running; }; /** diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 989df7065c21..b6db237672ff 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -220,7 +220,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) /* we're brought up, everything changes */ hw_reconf_flags = ~0; ieee80211_led_radio(local, true); - ieee80211_start_tpt_led_trig(local); + ieee80211_mod_tpt_led_trig(local, + IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); } /* @@ -1265,6 +1266,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) int count = 0; bool working = false, scanning = false; struct ieee80211_work *wk; + unsigned int led_trig_start = 0, led_trig_stop = 0; #ifdef CONFIG_PROVE_LOCKING WARN_ON(debug_locks && !lockdep_rtnl_is_held() && @@ -1314,6 +1316,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); } + if (working || scanning) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; + + if (count) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + + ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); + if (working) return ieee80211_idle_off(local, "working"); if (scanning) diff --git a/net/mac80211/led.c b/net/mac80211/led.c index 79b13090aed7..4905eb8af572 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -216,7 +216,7 @@ static void tpt_trig_timer(unsigned long data) } extern char *__ieee80211_create_tpt_led_trigger( - struct ieee80211_hw *hw, + struct ieee80211_hw *hw, unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len) { @@ -237,6 +237,7 @@ extern char *__ieee80211_create_tpt_led_trigger( tpt_trig->blink_table = blink_table; tpt_trig->blink_table_len = blink_table_len; + tpt_trig->want = flags; setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local); @@ -246,11 +247,11 @@ extern char *__ieee80211_create_tpt_led_trigger( } EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger); -void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) +static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) { struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; - if (!tpt_trig) + if (tpt_trig->running) return; /* reset traffic */ @@ -261,12 +262,12 @@ void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); } -void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) +static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) { struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; struct led_classdev *led_cdev; - if (!tpt_trig) + if (!tpt_trig->running) return; tpt_trig->running = false; @@ -277,3 +278,31 @@ void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) led_brightness_set(led_cdev, LED_OFF); read_unlock(&tpt_trig->trig.leddev_list_lock); } + +void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, + unsigned int types_on, unsigned int types_off) +{ + struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; + bool allowed; + + WARN_ON(types_on & types_off); + + if (!tpt_trig) + return; + + tpt_trig->active &= ~types_off; + tpt_trig->active |= types_on; + + /* + * Regardless of wanted state, we shouldn't blink when + * the radio is disabled -- this can happen due to some + * code ordering issues with __ieee80211_recalc_idle() + * being called before the radio is started. + */ + allowed = tpt_trig->active & IEEE80211_TPT_LEDTRIG_FL_RADIO; + + if (!allowed || !(tpt_trig->active & tpt_trig->want)) + ieee80211_stop_tpt_led_trig(local); + else + ieee80211_start_tpt_led_trig(local); +} diff --git a/net/mac80211/led.h b/net/mac80211/led.h index 6c215dc0fc96..e0275d9befa8 100644 --- a/net/mac80211/led.h +++ b/net/mac80211/led.h @@ -21,8 +21,8 @@ void ieee80211_led_radio(struct ieee80211_local *local, void ieee80211_led_names(struct ieee80211_local *local); void ieee80211_led_init(struct ieee80211_local *local); void ieee80211_led_exit(struct ieee80211_local *local); -void ieee80211_start_tpt_led_trig(struct ieee80211_local *local); -void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local); +void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, + unsigned int types_on, unsigned int types_off); #else static inline void ieee80211_led_rx(struct ieee80211_local *local) { @@ -47,10 +47,9 @@ static inline void ieee80211_led_init(struct ieee80211_local *local) static inline void ieee80211_led_exit(struct ieee80211_local *local) { } -static inline void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) -{ -} -static inline void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) +static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, + unsigned int types_on, + unsigned int types_off) { } #endif diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 48306415a1cb..cf68700abffa 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1116,7 +1116,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, void ieee80211_stop_device(struct ieee80211_local *local) { ieee80211_led_radio(local, false); - ieee80211_stop_tpt_led_trig(local); + ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO); cancel_work_sync(&local->reconfig_filter); @@ -1151,7 +1151,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) } ieee80211_led_radio(local, true); - ieee80211_start_tpt_led_trig(local); + ieee80211_mod_tpt_led_trig(local, + IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); } /* add interfaces */ -- cgit v1.2.3-59-g8ed1b From 65a6538a56d4c7ae8465f2a8420ddc65877b6779 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 21 Dec 2010 16:02:17 +0200 Subject: mac80211: check for CONFIG_MAC80211_LEDS in the tpt_led_trigger declaration If CONFIG_MAC80211_LEDS is not set, ieee80211_i.h was failing to compile, because struct led_trigger is only declared when CONFIG_LEDS_TRIGGERS is set. This patch adds ifdefs around the tpt_led_trigger declaration in ieee80211_i.h to avoid the problem. Signed-off-by: Luciano Coelho Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3810c72ac062..a05893a238b7 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -631,6 +631,7 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_SKB_ADD, }; +#ifdef CONFIG_MAC80211_LEDS struct tpt_led_trigger { struct led_trigger trig; char name[32]; @@ -642,6 +643,7 @@ struct tpt_led_trigger { unsigned int active, want; bool running; }; +#endif /** * mac80211 scan flags - currently active scan mode -- cgit v1.2.3-59-g8ed1b From ee09b3c1cff0335137dc1b146488e4352f640f13 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 22 Dec 2010 11:39:59 -0800 Subject: sfq: fix sfq class stats handling sfq_walk() runs without qdisc lock. By the time it selects a non empty hash slot and sfq_dump_class_stats() is run (with lock held), slot might have been freed : We then access q->slots[SFQ_EMPTY_SLOT], out of bounds, and crash in slot_queue_walk() On previous kernels, bug is here but out of bounds qs[SFQ_DEPTH] and allot[SFQ_DEPTH] are located in struct sfq_sched_data, so no illegal memory access happens, only possibly wrong data reported to user. Also, slot_dequeue_tail() should make sure slot skb chain is correctly terminated, or sfq_dump_class_stats() can access freed skbs. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 13322e8a0456..6a2f88fea6d8 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -281,6 +281,7 @@ static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot) struct sk_buff *skb = slot->skblist_prev; slot->skblist_prev = skb->prev; + skb->prev->next = (struct sk_buff *)slot; skb->next = skb->prev = NULL; return skb; } @@ -608,14 +609,19 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct gnet_dump *d) { struct sfq_sched_data *q = qdisc_priv(sch); - const struct sfq_slot *slot = &q->slots[q->ht[cl - 1]]; - struct gnet_stats_queue qs = { .qlen = slot->qlen }; - struct tc_sfq_xstats xstats = { .allot = slot->allot }; + sfq_index idx = q->ht[cl - 1]; + struct gnet_stats_queue qs = { 0 }; + struct tc_sfq_xstats xstats = { 0 }; struct sk_buff *skb; - slot_queue_walk(slot, skb) - qs.backlog += qdisc_pkt_len(skb); + if (idx != SFQ_EMPTY_SLOT) { + const struct sfq_slot *slot = &q->slots[idx]; + xstats.allot = slot->allot; + qs.qlen = slot->qlen; + slot_queue_walk(slot, skb) + qs.backlog += qdisc_pkt_len(skb); + } if (gnet_stats_copy_queue(d, &qs) < 0) return -1; return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); -- cgit v1.2.3-59-g8ed1b From 97dcec5715a381362c88d1542e52c63147764d3c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 20 Dec 2010 08:02:42 +0530 Subject: ath9k_htc: Fix warning on device removal The commit "ath9k_hw: warn if we cannot change the power to the chip" introduced a new warning to indicate chip powerup failures, but this is not required for devices that have been removed. Handle USB device removal properly by checking for unplugged status. For PCI devices, this warning will still be seen when the card is pulled out, not sure how to check for card removal. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.h | 2 -- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 +++--- drivers/net/wireless/ath/ath9k/htc.h | 5 ++--- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 5 +---- drivers/net/wireless/ath/ath9k/hw.c | 4 +++- drivers/net/wireless/ath/ath9k/hw.h | 4 ++++ drivers/net/wireless/ath/ath9k/wmi.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index f6f09d1378f4..58e2ddc927a9 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -23,8 +23,6 @@ #include #include "ar9003_eeprom.h" -#define AH_USE_EEPROM 0x1 - #ifdef __BIG_ENDIAN #define AR5416_EEPROM_MAGIC 0x5aa5 #else diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 22b68b3c8566..c20c8c8201a2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -993,16 +993,16 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) { struct usb_device *udev = interface_to_usbdev(interface); struct hif_device_usb *hif_dev = usb_get_intfdata(interface); + bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false; if (hif_dev) { - ath9k_htc_hw_deinit(hif_dev->htc_handle, - (udev->state == USB_STATE_NOTATTACHED) ? true : false); + ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); usb_set_intfdata(interface, NULL); } - if (hif_dev->flags & HIF_USB_START) + if (!unplugged && (hif_dev->flags & HIF_USB_START)) ath9k_hif_usb_reboot(udev); kfree(hif_dev); diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index fdf9d5fe8cc0..e6c2f0aad28f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -339,9 +339,8 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_ASSOCIATED BIT(7) #define OP_ENABLE_BEACON BIT(8) #define OP_LED_DEINIT BIT(9) -#define OP_UNPLUGGED BIT(10) -#define OP_BT_PRIORITY_DETECTED BIT(11) -#define OP_BT_SCAN BIT(12) +#define OP_BT_PRIORITY_DETECTED BIT(10) +#define OP_BT_SCAN BIT(11) struct ath9k_htc_priv { struct device *dev; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 0f6be350fd3c..724f5451a415 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -851,9 +851,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, if (ret) goto err_init; - /* The device may have been unplugged earlier. */ - priv->op_flags &= ~OP_UNPLUGGED; - ret = ath9k_init_device(priv, devid, product, drv_info); if (ret) goto err_init; @@ -873,7 +870,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) /* Check if the device has been yanked out. */ if (hotunplug) - htc_handle->drv_priv->op_flags |= OP_UNPLUGGED; + htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(htc_handle->drv_priv); ath9k_deinit_wmi(htc_handle->drv_priv); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 4b51ed47fe69..fde978665e07 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1615,7 +1615,9 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) * simply keep the ATH_DBG_WARN_ON_ONCE() but make * ath9k_hw_setpower() return type void. */ - ATH_DBG_WARN_ON_ONCE(!status); + + if (!(ah->ah_flags & AH_UNPLUGGED)) + ATH_DBG_WARN_ON_ONCE(!status); return status; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b8ffaa5dc650..5a3dfec45e96 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -646,6 +646,10 @@ struct ath_nf_limits { s16 nominal; }; +/* ah_flags */ +#define AH_USE_EEPROM 0x1 +#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ + struct ath_hw { struct ieee80211_hw *hw; struct ath_common common; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 8f42ea78198c..573daca135fd 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -250,7 +250,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, int time_left, ret = 0; unsigned long flags; - if (wmi->drv_priv->op_flags & OP_UNPLUGGED) + if (ah->ah_flags & AH_UNPLUGGED) return 0; skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); -- cgit v1.2.3-59-g8ed1b From d584747be838775cebbf5937c20b24da6899e3e8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 20 Dec 2010 14:39:51 +0530 Subject: ath9k: Fix warnings on card removal The recently added warning message on power change failure is not needed on device removal. ath: Failed to wakeup in 500us ------------[ cut here ]------------ WARNING: at drivers/net/wireless/ath/ath9k/hw.c:1618 ath9k_hw_setpower+0x61f/0x630 [ath9k_hw]() Hardware name: 64756D6 Pid: 540, comm: kworker/u:3 Not tainted 2.6.37-rc6-wl #37 Call Trace: [] warn_slowpath_common+0x7a/0xb0 [] ? ath9k_iowrite32+0x0/0x90 [ath9k] [] warn_slowpath_null+0x15/0x20 [] ath9k_hw_setpower+0x61f/0x630 [ath9k_hw] [] ath9k_ps_wakeup+0x85/0xd0 [ath9k] [] ath9k_configure_filter+0x25/0x80 [ath9k] [] ieee80211_configure_filter+0x133/0x190 [mac80211] [] ieee80211_do_stop+0x132/0x540 [mac80211] [] ? _raw_spin_unlock_bh+0x1f/0x30 [] ? dev_deactivate+0x1c3/0x1e0 [] ieee80211_stop+0x15/0x20 [mac80211] [] __dev_close+0x56/0x90 Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/ath9k/pci.c | 2 ++ drivers/net/wireless/ath/ath9k/recv.c | 3 ++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 2c31f5142eda..d9bda275ec21 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -667,6 +667,7 @@ extern struct ieee80211_ops ath9k_ops; extern int modparam_nohwcrypt; extern int led_blink; extern int ath9k_pm_qos_value; +extern bool is_ath9k_unloaded; irqreturn_t ath_isr(int irq, void *dev); int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b0e5e716b167..9efc77d82563 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -45,6 +45,7 @@ int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); +bool is_ath9k_unloaded; /* We use the hw_value as an index into our private channel structure */ #define CHAN2G(_freq, _idx) { \ @@ -899,6 +900,7 @@ module_init(ath9k_init); static void __exit ath9k_exit(void) { + is_ath9k_unloaded = true; ath_ahb_exit(); ath_pci_exit(); ath_rate_control_unregister(); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 7ca8499249ec..3eb938d7a012 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -264,6 +264,8 @@ static void ath_pci_remove(struct pci_dev *pdev) struct ath_softc *sc = aphy->sc; void __iomem *mem = sc->mem; + if (!is_ath9k_unloaded) + sc->sc_ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(sc); free_irq(sc->irq, sc); ieee80211_free_hw(sc->hw); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 00ebed3f9158..b2497b8601e5 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -528,7 +528,8 @@ bool ath_stoprecv(struct ath_softc *sc) sc->rx.rxlink = NULL; spin_unlock_bh(&sc->rx.rxbuflock); - if (unlikely(!stopped)) { + if (!(ah->ah_flags & AH_UNPLUGGED) && + unlikely(!stopped)) { ath_err(ath9k_hw_common(sc->sc_ah), "Could not stop RX, we could be " "confusing the DMA engine when we start RX up\n"); -- cgit v1.2.3-59-g8ed1b From afe68d0a8f5961652e26cea39d74e2cc820de841 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Dec 2010 11:29:59 -0500 Subject: ath9k: fix aphy / wiphy idle mismatch ath9k supports its own set of virtual wiphys, and it uses the mac80211 idle notifications to know when a device needs to be idle or not. We recently changed ath9k to force idle on driver stop() and on resume but forgot to take into account ath9k's own virtual wiphy idle states. These are used internally by ath9k to check if the device's radio should be powered down on each idle call. Without this change its possible that the device could have been forced off but the virtual wiphy idle was left on. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + drivers/net/wireless/ath/ath9k/pci.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8a1691db166d..0348731accae 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1328,6 +1328,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_ps_restore(sc); sc->ps_idle = true; + ath9k_set_wiphy_idle(aphy, true); ath_radio_disable(sc, hw); sc->sc_flags |= SC_OP_INVALID; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 3eb938d7a012..10563334bb09 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -312,6 +312,7 @@ static int ath_pci_resume(struct device *device) ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); sc->ps_idle = true; + ath9k_set_wiphy_idle(aphy, true); ath_radio_disable(sc, hw); return 0; -- cgit v1.2.3-59-g8ed1b From 63d9faf665ba27c65f0cf118df05a412d3dfd39d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:50 +0100 Subject: wl1251: remove unnecessary import No function declared in gpio.h is used here. Signed-off-by: Hauke Mehrtens Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/boot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/wl1251/boot.c index 61572dfa1f60..d729daf8e841 100644 --- a/drivers/net/wireless/wl1251/boot.c +++ b/drivers/net/wireless/wl1251/boot.c @@ -19,7 +19,6 @@ * */ -#include #include #include "reg.h" -- cgit v1.2.3-59-g8ed1b From 750de29109770f6b50daecc4c44aaa50a9e0075b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:51 +0100 Subject: wl12xx: remove unnecessary import No function declared in gpio.h is used here. Signed-off-by: Hauke Mehrtens Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/boot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 4a9f929725fd..4df04f84d7f1 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -21,7 +21,6 @@ * */ -#include #include #include "acx.h" -- cgit v1.2.3-59-g8ed1b From 6b740aaa005474a7b135d3c554b9295c73eaab95 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:52 +0100 Subject: ssb: Use pci_is_pcie() Use function pci_is_pcie() instead of accessing struct member directly. CC: Michael Buesch Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/ssb/scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index ee079ab9fb28..5a0985d4ce15 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -405,10 +405,10 @@ int ssb_bus_scan(struct ssb_bus *bus, /* Ignore PCI cores on PCI-E cards. * Ignore PCI-E cores on PCI cards. */ if (dev->id.coreid == SSB_DEV_PCI) { - if (bus->host_pci->is_pcie) + if (pci_is_pcie(bus->host_pci)) continue; } else { - if (!bus->host_pci->is_pcie) + if (!pci_is_pcie(bus->host_pci)) continue; } } -- cgit v1.2.3-59-g8ed1b From 2cdb9a42f3b4c97088ea0768dbee55ee8863f233 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:53 +0100 Subject: rt2x00: Use pci_is_pcie() Use function pci_is_pcie() instead of accessing struct member directly. Signed-off-by: Hauke Mehrtens Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 28e6ff1a6694..73631c6fbb30 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -286,7 +286,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) rt2x00dev->irq = pci_dev->irq; rt2x00dev->name = pci_name(pci_dev); - if (pci_dev->is_pcie) + if (pci_is_pcie(pci_dev)) rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); else rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); -- cgit v1.2.3-59-g8ed1b From e98b06b09be0fc459806aa4d2c301cfaf268c570 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:54 +0100 Subject: ath5k: Use pci_is_pcie() Use function pci_is_pcie() instead of accessing struct member directly. CC: Luis R. Rodriguez Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 2 +- drivers/net/wireless/ath/ath5k/reset.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 9dbc1fa81795..cdac5cff0177 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -276,7 +276,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) /* * Write PCI-E power save settings */ - if ((ah->ah_version == AR5K_AR5212) && pdev && (pdev->is_pcie)) { + if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) { ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index bc84aaa31446..7297d7b77043 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -537,7 +537,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ - bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; + bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; if (ah->ah_version == AR5K_AR5210) { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | @@ -594,7 +594,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ - bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; + bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; if (ah->ah_version == AR5K_AR5210) { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | -- cgit v1.2.3-59-g8ed1b From e40b5faabc34f61fdf17b40d2e31837461ddc467 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:55 +0100 Subject: ath9k: Use pci_is_pcie() Use function pci_is_pcie() instead of accessing struct member directly. CC: Luis R. Rodriguez Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 10563334bb09..545aa1c650cf 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -96,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) struct pci_dev *pdev = to_pci_dev(sc->dev); u8 aspm; - if (!pdev->is_pcie) + if (!pci_is_pcie(pdev)) return; pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm); -- cgit v1.2.3-59-g8ed1b From 8d6a686a0d20d39c202fdfc6fa7f1daf1d6e3b35 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Dec 2010 02:01:56 +0100 Subject: rtlwifi: Use pci_pcie_cap() Use function pci_pcie_cap() instead of accessing struct member directly. Signed-off-by: Hauke Mehrtens Tested-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index bf3b5748ee19..353e20358885 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1608,7 +1608,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, pcipriv->ndis_adapter.pcibridge_funcnum = PCI_FUNC(bridge_pdev->devfn); pcipriv->ndis_adapter.pcibridge_pciehdr_offset = - bridge_pdev->pcie_cap; + pci_pcie_cap(bridge_pdev); pcipriv->ndis_adapter.pcicfg_addrport = (pcipriv->ndis_adapter.pcibridge_busnum << 16) | (pcipriv->ndis_adapter.pcibridge_devnum << 11) | -- cgit v1.2.3-59-g8ed1b From 6dab55bf7eb52ca21d5e6c97b97f70875fe41ddc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 Dec 2010 06:59:06 +0300 Subject: ath9k: unlock on error path in ath9k_change_interface() There is a missing unlock when we hit the "No beacon slot available" error condition. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0348731accae..c5cf8639e721 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1456,6 +1456,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); + int ret = 0; ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); mutex_lock(&sc->mutex); @@ -1465,7 +1466,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_ADHOC: if (sc->nbcnvifs >= ATH_BCBUF) { ath_err(common, "No beacon slot available\n"); - return -ENOBUFS; + ret = -ENOBUFS; + goto out; } break; case NL80211_IFTYPE_STATION: @@ -1479,14 +1481,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, default: ath_err(common, "Interface type %d not yet supported\n", vif->type); - mutex_unlock(&sc->mutex); - return -ENOTSUPP; + ret = -ENOTSUPP; + goto out; } vif->type = new_type; vif->p2p = p2p; +out: mutex_unlock(&sc->mutex); - return 0; + return ret; } static void ath9k_remove_interface(struct ieee80211_hw *hw, -- cgit v1.2.3-59-g8ed1b From 26c7fc436422de5d6d2b491f777e965e96f5c3a2 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 21 Dec 2010 17:30:20 +0900 Subject: ath5k: Simplify powertable recalculation Let ath5k_hw_txpower() decide if it can re-use the powertable or if it has to be recalculated instead of passing a 'fast' flag from the outside. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/phy.c | 35 +++++++++++++--------------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index d6e744088bc6..e6491bf359c0 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1113,6 +1113,7 @@ struct ath5k_hw { s16 txp_cck_ofdm_gainf_delta; /* Value in dB units */ s16 txp_cck_ofdm_pwr_delta; + bool txp_setup; } ah_txpower; struct { diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index f84afb420bd8..7c6d7dc62f3a 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3004,6 +3004,8 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, return -EINVAL; } + ah->ah_txpower.txp_setup = true; + return 0; } @@ -3105,9 +3107,10 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, */ static int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 ee_mode, u8 txpower, bool fast) + u8 ee_mode, u8 txpower) { struct ath5k_rate_pcal_info rate_info; + struct ieee80211_channel *curr_channel = ah->ah_current_channel; u8 type; int ret; @@ -3138,10 +3141,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - /* If fast is set it means we are on the same channel/mode - * so there is no need to recalculate the powertable, we 'll - * just use the cached one */ - if (!fast) { + /* + * If we don't change channel/mode skip tx powertable calculation + * and use the cached one. + */ + if (!ah->ah_txpower.txp_setup || + (channel->hw_value != curr_channel->hw_value) || + (channel->center_freq != curr_channel->center_freq)) { /* Reset TX power values */ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; @@ -3159,8 +3165,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, else ath5k_setup_pcdac_table(ah); - - /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); @@ -3238,7 +3242,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, "changing txpower to %d\n", txpower); - return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true); + return ath5k_hw_txpower(ah, channel, ee_mode, txpower); } /*************\ @@ -3251,7 +3255,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, struct ieee80211_channel *curr_channel; int ret, i; u32 phy_tst1; - bool fast_txp; ret = 0; /* @@ -3281,17 +3284,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EIO; } - /* - * If we don't change channel/mode skip - * tx powertable calculation and use the - * cached one. - */ - if ((channel->hw_value == curr_channel->hw_value) && - (channel->center_freq == curr_channel->center_freq)) - fast_txp = true; - else - fast_txp = false; - /* * Set TX power * @@ -3300,8 +3292,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, * properly set curve indices. */ ret = ath5k_hw_txpower(ah, channel, ee_mode, - ah->ah_txpower.txp_max_pwr / 2, - fast_txp); + ah->ah_txpower.txp_max_pwr / 2); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 56bd29d361a53f3bf6b815b5bf570a23bdc55b35 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 21 Dec 2010 17:30:26 +0900 Subject: ath5k: Separate powertable setup and writing And rename functions which write the powertable to make it clearer. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 7c6d7dc62f3a..6f0cf3a09b2c 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -2593,7 +2593,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, /* Write PCDAC values on hw */ static void -ath5k_setup_pcdac_table(struct ath5k_hw *ah) +ath5k_write_pcdac_table(struct ath5k_hw *ah) { u8 *pcdac_out = ah->ah_txpower.txp_pd_table; int i; @@ -2742,7 +2742,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, /* Write PDADC values on hw */ static void -ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) +ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u8 *pdadc_out = ah->ah_txpower.txp_pd_table; @@ -2957,8 +2957,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, (s16) pcinfo_R->freq, pcinfo_L->max_pwr, pcinfo_R->max_pwr); - /* We are ready to go, fill PCDAC/PDADC - * table and write settings on hardware */ + /* Fill PCDAC/PDADC table */ switch (type) { case AR5K_PWRTABLE_LINEAR_PCDAC: /* For RF5112 we can have one or two curves @@ -2971,9 +2970,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, * match max power value with max * table index */ ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); - - /* Write settings on hw */ - ath5k_setup_pcdac_table(ah); break; case AR5K_PWRTABLE_PWR_TO_PCDAC: /* We are done for RF5111 since it has only @@ -2983,9 +2979,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, /* No rate powertable adjustment for RF5111 */ ah->ah_txpower.txp_min_idx = 0; ah->ah_txpower.txp_offset = 0; - - /* Write settings on hw */ - ath5k_setup_pcdac_table(ah); break; case AR5K_PWRTABLE_PWR_TO_PDADC: /* Set PDADC boundaries and fill @@ -2993,9 +2986,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, ee->ee_pd_gains[ee_mode]); - /* Write settings on hw */ - ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); - /* Set txp.offset, note that table_min * can be negative */ ah->ah_txpower.txp_offset = table_min[0]; @@ -3009,6 +2999,15 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, return 0; } +/* Write power table for current channel to hw */ +static void +ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type) +{ + if (type == AR5K_PWRTABLE_PWR_TO_PDADC) + ath5k_write_pwr_to_pdadc_table(ah, ee_mode); + else + ath5k_write_pcdac_table(ah); +} /* * Per-rate tx power setting @@ -3159,11 +3158,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, ee_mode, type); if (ret) return ret; - /* Write cached table on hw */ - } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC) - ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); - else - ath5k_setup_pcdac_table(ah); + } + + /* Write table on hw */ + ath5k_write_channel_powertable(ah, ee_mode, type); /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); -- cgit v1.2.3-59-g8ed1b From 51f00622e5664ae77fd6c8670ddd402d9b77ccc8 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 21 Dec 2010 17:30:32 +0900 Subject: ath5k: Track current TX power separately from max TX power Add a new variable to keep track of the currently configured tx power. Before max_pwr was re-used for keeping the maximum allowed power as well as the current configuration. Doing a min() on it allows you to lower the txpower, but how would you be able to make it higher again? This patch fixes that by adding a new variable ah_cur_pwr which is used instead of txp_max_pwr to keep the current configuration. txp_max_pwr is used to check if we are within the limits. Another problem fixed by this patch is that it avoids setting a zero txpower when things are initialized first and the current power is not yet set. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/phy.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e6491bf359c0..342da280c987 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1107,6 +1107,7 @@ struct ath5k_hw { /* Values in 0.25dB units */ s16 txp_min_pwr; s16 txp_max_pwr; + s16 txp_cur_pwr; /* Values in 0.5dB units */ s16 txp_offset; s16 txp_ofdm; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6f0cf3a09b2c..18c58cdfde46 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3096,7 +3096,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, /* Min/max in 0.25dB units */ ah->ah_txpower.txp_min_pwr = 2 * rates[7]; - ah->ah_txpower.txp_max_pwr = 2 * rates[0]; + ah->ah_txpower.txp_cur_pwr = 2 * rates[0]; ah->ah_txpower.txp_ofdm = rates[7]; } @@ -3150,8 +3150,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Reset TX power values */ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; - ah->ah_txpower.txp_min_pwr = 0; - ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; /* Calculate the powertable */ ret = ath5k_setup_channel_powertable(ah, channel, @@ -3290,7 +3288,8 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, * properly set curve indices. */ ret = ath5k_hw_txpower(ah, channel, ee_mode, - ah->ah_txpower.txp_max_pwr / 2); + ah->ah_txpower.txp_cur_pwr ? + ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 26a51ad7f285236ca593c57cffcaadd40514084a Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 21 Dec 2010 17:30:37 +0900 Subject: ath5k: Remove ATH5K_INI_RFGAIN defines, use band instead Remove redundant defines. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 6 +----- drivers/net/wireless/ath/ath5k/phy.c | 18 ++++++------------ drivers/net/wireless/ath/ath5k/reset.c | 11 +++-------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 342da280c987..5de852017651 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -154,10 +154,6 @@ udelay(1); \ } while (0) -/* Register dumps are done per operation mode */ -#define AR5K_INI_RFGAIN_5GHZ 0 -#define AR5K_INI_RFGAIN_2GHZ 1 - /* * Some tuneable values (these should be changeable by the user) * TODO: Make use of them and add more options OR use debug/configfs @@ -1322,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); /* Init function */ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, u8 freq, bool fast); + u8 mode, u8 ee_mode, bool fast); /* * Functions used internaly diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 18c58cdfde46..b6e96213e924 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -609,10 +609,10 @@ done: /* Write initial RF gain table to set the RF sensitivity * this one works on all RF chips and has nothing to do * with gain_F calibration */ -static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) +static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band) { const struct ath5k_ini_rfgain *ath5k_rfg; - unsigned int i, size; + unsigned int i, size, index; switch (ah->ah_radio) { case AR5K_RF5111: @@ -644,17 +644,11 @@ static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) return -EINVAL; } - switch (freq) { - case AR5K_INI_RFGAIN_2GHZ: - case AR5K_INI_RFGAIN_5GHZ: - break; - default: - return -EINVAL; - } + index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0; for (i = 0; i < size; i++) { AR5K_REG_WAIT(i); - ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq], + ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index], (u32)ath5k_rfg[i].rfg_register); } @@ -3246,7 +3240,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) \*************/ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, u8 freq, bool fast) + u8 mode, u8 ee_mode, bool fast) { struct ieee80211_channel *curr_channel; int ret, i; @@ -3305,7 +3299,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, * Write initial RF gain settings * This should work for both 5111/5112 */ - ret = ath5k_hw_rfgain_init(ah, freq); + ret = ath5k_hw_rfgain_init(ah, channel->band); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 7297d7b77043..e360e73b3260 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1020,13 +1020,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool fast, bool skip_pcu) { u32 s_seq[10], s_led[3], tsf_up, tsf_lo; - u8 mode, freq, ee_mode; + u8 mode, ee_mode; int i, ret; ee_mode = 0; tsf_up = 0; tsf_lo = 0; - freq = 0; mode = 0; /* @@ -1071,7 +1070,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: mode = AR5K_MODE_11A; - freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: @@ -1083,7 +1081,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, } mode = AR5K_MODE_11G; - freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_B: @@ -1095,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, } mode = AR5K_MODE_11B; - freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11B; break; case CHANNEL_XR: @@ -1105,7 +1101,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, return -EINVAL; } mode = AR5K_MODE_XR; - freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; break; default: @@ -1120,7 +1115,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, */ if (fast) { ret = ath5k_hw_phy_init(ah, channel, mode, - ee_mode, freq, true); + ee_mode, true); if (ret) { ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, "fast chan change failed, falling back to normal reset\n"); @@ -1256,7 +1251,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* * Initialize PHY */ - ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false); + ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false); if (ret) { ATH5K_ERR(ah->ah_sc, "failed to initialize PHY (%i) !\n", ret); -- cgit v1.2.3-59-g8ed1b From 0207c0c51a37659a92232e665f2a7fadec170556 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 21 Dec 2010 17:30:43 +0900 Subject: ath5k: Use helper function to get eeprom mode from channel Introduce a helper function to get the EEPROM mode from channel and remove multiple similar switch statements. Also since it's now easy to get the EEPROM mode from the channel, use them inside the functions which need it, instead of passing a redundant ee_mode parameter. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/eeprom.c | 16 ++++++++ drivers/net/wireless/ath/ath5k/eeprom.h | 2 + drivers/net/wireless/ath/ath5k/phy.c | 68 ++++++++------------------------- drivers/net/wireless/ath/ath5k/reset.c | 19 ++++----- 5 files changed, 42 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 5de852017651..407e39c2b10b 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1318,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); /* Init function */ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, bool fast); + u8 mode, bool fast); /* * Functions used internaly diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 97eaa9a4415e..80e625608bac 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1802,3 +1802,19 @@ ath5k_eeprom_detach(struct ath5k_hw *ah) for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) ath5k_eeprom_free_pcal_info(ah, mode); } + +int +ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) +{ + switch (channel->hw_value & CHANNEL_MODES) { + case CHANNEL_A: + case CHANNEL_XR: + return AR5K_EEPROM_MODE_11A; + case CHANNEL_G: + return AR5K_EEPROM_MODE_11G; + case CHANNEL_B: + return AR5K_EEPROM_MODE_11B; + default: + return -1; + } +} diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 0017006be841..7c09e150dbdc 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -517,3 +517,5 @@ struct ath5k_eeprom_info { u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; }; +int +ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel); diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index b6e96213e924..9306d5fda675 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1355,20 +1355,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) return; } - switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { - case CHANNEL_A: - case CHANNEL_XR: - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_G: - ee_mode = AR5K_EEPROM_MODE_11G; - break; - default: - case CHANNEL_B: - ee_mode = AR5K_EEPROM_MODE_11B; - break; - } - + ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); /* completed NF calibration, test threshold */ nf = ath5k_hw_read_measured_noise_floor(ah); @@ -1941,18 +1928,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) def_ant = ah->ah_def_ant; - switch (channel->hw_value & CHANNEL_MODES) { - case CHANNEL_A: - case CHANNEL_XR: - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_G: - ee_mode = AR5K_EEPROM_MODE_11G; - break; - case CHANNEL_B: - ee_mode = AR5K_EEPROM_MODE_11B; - break; - default: + ee_mode = ath5k_eeprom_mode_from_channel(channel); + if (ee_mode < 0) { ATH5K_ERR(ah->ah_sc, "invalid channel: %d\n", channel->center_freq); return; @@ -3100,11 +3077,11 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, */ static int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 ee_mode, u8 txpower) + u8 txpower) { struct ath5k_rate_pcal_info rate_info; struct ieee80211_channel *curr_channel = ah->ah_current_channel; - u8 type; + u8 type, ee_mode; int ret; if (txpower > AR5K_TUNE_MAX_TXPOWER) { @@ -3112,6 +3089,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } + ee_mode = ath5k_eeprom_mode_from_channel(channel); + if (ee_mode < 0) { + ATH5K_ERR(ah->ah_sc, + "invalid channel: %d\n", channel->center_freq); + return -EINVAL; + } + /* Initialize TX power table */ switch (ah->ah_radio) { case AR5K_RF5110: @@ -3208,31 +3192,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) { - /*Just a try M.F.*/ - struct ieee80211_channel *channel = ah->ah_current_channel; - u8 ee_mode; - - switch (channel->hw_value & CHANNEL_MODES) { - case CHANNEL_A: - case CHANNEL_XR: - ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_G: - ee_mode = AR5K_EEPROM_MODE_11G; - break; - case CHANNEL_B: - ee_mode = AR5K_EEPROM_MODE_11B; - break; - default: - ATH5K_ERR(ah->ah_sc, - "invalid channel: %d\n", channel->center_freq); - return -EINVAL; - } - ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, "changing txpower to %d\n", txpower); - return ath5k_hw_txpower(ah, channel, ee_mode, txpower); + return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower); } /*************\ @@ -3240,7 +3203,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) \*************/ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, u8 ee_mode, bool fast) + u8 mode, bool fast) { struct ieee80211_channel *curr_channel; int ret, i; @@ -3281,8 +3244,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, * RF buffer settings on 5211/5212+ so that we * properly set curve indices. */ - ret = ath5k_hw_txpower(ah, channel, ee_mode, - ah->ah_txpower.txp_cur_pwr ? + ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ? ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index e360e73b3260..84206898f77d 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -866,15 +866,18 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, } static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, - struct ieee80211_channel *channel, u8 ee_mode) + struct ieee80211_channel *channel) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; s16 cck_ofdm_pwr_delta; + u8 ee_mode; /* TODO: Add support for AR5210 EEPROM */ if (ah->ah_version == AR5K_AR5210) return; + ee_mode = ath5k_eeprom_mode_from_channel(channel); + /* Adjust power delta for channel 14 */ if (channel->center_freq == 2484) cck_ofdm_pwr_delta = @@ -1020,10 +1023,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool fast, bool skip_pcu) { u32 s_seq[10], s_led[3], tsf_up, tsf_lo; - u8 mode, ee_mode; + u8 mode; int i, ret; - ee_mode = 0; tsf_up = 0; tsf_lo = 0; mode = 0; @@ -1070,7 +1072,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: mode = AR5K_MODE_11A; - ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: @@ -1081,7 +1082,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, } mode = AR5K_MODE_11G; - ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_B: @@ -1092,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, } mode = AR5K_MODE_11B; - ee_mode = AR5K_EEPROM_MODE_11B; break; case CHANNEL_XR: if (ah->ah_version == AR5K_AR5211) { @@ -1101,7 +1100,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, return -EINVAL; } mode = AR5K_MODE_XR; - ee_mode = AR5K_EEPROM_MODE_11A; break; default: ATH5K_ERR(ah->ah_sc, @@ -1114,8 +1112,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * go on. If it fails continue with a normal reset. */ if (fast) { - ret = ath5k_hw_phy_init(ah, channel, mode, - ee_mode, true); + ret = ath5k_hw_phy_init(ah, channel, mode, true); if (ret) { ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, "fast chan change failed, falling back to normal reset\n"); @@ -1212,7 +1209,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_tweak_initval_settings(ah, channel); /* Commit values from EEPROM */ - ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode); + ath5k_hw_commit_eeprom_settings(ah, channel); /* @@ -1251,7 +1248,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* * Initialize PHY */ - ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false); + ret = ath5k_hw_phy_init(ah, channel, mode, false); if (ret) { ATH5K_ERR(ah->ah_sc, "failed to initialize PHY (%i) !\n", ret); -- cgit v1.2.3-59-g8ed1b From d0ce2d170585b7061a08af061d64ebb08c6782dd Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 21 Dec 2010 01:42:43 -0800 Subject: ath9k_hw: Fix bug in eeprom data length validation for AR9485 The size of the eeprom data is 1088 bytes for AR9485. But a sanity check is done against 4K which would result in a 'potential read past the end of the buffer' smatch complaint. Reported-by: Dan Carpenter Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index d7deae85d980..5d81c5360b9c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -59,6 +59,8 @@ #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) +#define EEPROM_DATA_LEN_9485 1088 + static int ar9003_hw_power_interpolate(int32_t x, int32_t *px, int32_t *py, u_int16_t np); @@ -3367,7 +3369,7 @@ found: "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", cptr, code, reference, length, major, minor); if ((!AR_SREV_9485(ah) && length >= 1024) || - (AR_SREV_9485(ah) && length >= (4 * 1024))) { + (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) { ath_dbg(common, ATH_DBG_EEPROM, "Skipping bad header\n"); cptr -= COMP_HDR_LEN; -- cgit v1.2.3-59-g8ed1b From e41596a118a5cb15a045ef773dc117b2596e6a86 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 11:50:19 +0100 Subject: b43: use correct firmware for newer cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1aec160e3d2f..5fb0bc6710f6 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2121,8 +2121,10 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) filename = "ucode13"; else if (rev == 14) filename = "ucode14"; - else if (rev >= 15) + else if (rev == 15) filename = "ucode15"; + else if ((rev >= 16) && (rev <= 20)) + filename = "ucode16_mimo"; else goto err_no_ucode; err = b43_do_request_fw(ctx, filename, &fw->ucode); @@ -2165,7 +2167,9 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) goto err_no_initvals; break; case B43_PHYTYPE_N: - if ((rev >= 11) && (rev <= 12)) + if (rev >= 16) + filename = "n0initvals16"; + else if ((rev >= 11) && (rev <= 12)) filename = "n0initvals11"; else goto err_no_initvals; @@ -2209,7 +2213,9 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) goto err_no_initvals; break; case B43_PHYTYPE_N: - if ((rev >= 11) && (rev <= 12)) + if (rev >= 16) + filename = "n0bsinitvals16"; + else if ((rev >= 11) && (rev <= 12)) filename = "n0bsinitvals11"; else goto err_no_initvals; -- cgit v1.2.3-59-g8ed1b From ea7ee14b8a6371f006d73333ef2b7fe929b6dab0 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 17:13:44 +0100 Subject: b43: N-PHY: implement radio 2056 init steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 33 ++++++++++++++- drivers/net/wireless/b43/radio_2056.c | 77 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2056.h | 3 ++ 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index a1aa5700b631..6b91cb353f23 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -401,16 +401,45 @@ static void b43_radio_init2055(struct b43_wldev *dev) b43_radio_init2055_post(dev); } +static void b43_radio_init2056_pre(struct b43_wldev *dev) +{ + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, + ~B43_NPHY_RFCTL_CMD_CHIP0PU); + /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */ + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_CMD_OEPORFORCE); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, + ~B43_NPHY_RFCTL_CMD_OEPORFORCE); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_CMD_CHIP0PU); +} + +static void b43_radio_init2056_post(struct b43_wldev *dev) +{ + b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB); + b43_radio_set(dev, B2056_SYN_COM_PU, 0x2); + b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2); + msleep(1); + b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2); + b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC); + b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1); + /* + if (nphy->init_por) + Call Radio 2056 Recalibrate + */ +} + /* * Initialize a Broadcom 2056 N-radio * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init */ static void b43_radio_init2056(struct b43_wldev *dev) { - /* TODO */ + b43_radio_init2056_pre(dev); + b2056_upload_inittabs(dev, 0, 0); + b43_radio_init2056_post(dev); } - /* * Upload the N-PHY tables. * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index 0cdf6a46ba4b..1752d52ab40e 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -24,6 +24,39 @@ #include "radio_2056.h" #include "phy_common.h" +struct b2056_inittab_entry { + /* Value to write if we use the 5GHz band. */ + u16 ghz5; + /* Value to write if we use the 2.4GHz band. */ + u16 ghz2; + /* Flags */ + u8 flags; +}; +#define B2056_INITTAB_ENTRY_OK 0x01 +#define B2056_INITTAB_UPLOAD 0x02 +#define UPLOAD .flags = B2056_INITTAB_ENTRY_OK | B2056_INITTAB_UPLOAD +#define NOUPLOAD .flags = B2056_INITTAB_ENTRY_OK + +struct b2056_inittabs_pts { + const struct b2056_inittab_entry *syn; + unsigned int syn_length; + const struct b2056_inittab_entry *tx; + unsigned int tx_length; + const struct b2056_inittab_entry *rx; + unsigned int rx_length; +}; + +#define INITTABSPTS(prefix) \ + .syn = prefix##_syn, \ + .syn_length = ARRAY_SIZE(prefix##_syn), \ + .tx = prefix##_tx, \ + .tx_length = ARRAY_SIZE(prefix##_tx), \ + .rx = prefix##_rx, \ + .rx_length = ARRAY_SIZE(prefix##_rx) + +struct b2056_inittabs_pts b2056_inittabs[] = { +}; + #define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ @@ -6045,6 +6078,50 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = }, }; +static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5, + bool ignore_uploadflag, u16 routing, + const struct b2056_inittab_entry *e, + unsigned int length) +{ + unsigned int i; + u16 value; + + for (i = 0; i < length; i++, e++) { + if (!(e->flags & B2056_INITTAB_ENTRY_OK)) + continue; + if ((e->flags & B2056_INITTAB_UPLOAD) || ignore_uploadflag) { + if (ghz5) + value = e->ghz5; + else + value = e->ghz2; + b43_radio_write(dev, routing | i, value); + } + } +} + +void b2056_upload_inittabs(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag) +{ + struct b2056_inittabs_pts *pts; + + if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { + B43_WARN_ON(1); + return; + } + pts = &b2056_inittabs[dev->phy.rev]; + + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, + B2056_SYN, pts->syn, pts->syn_length); + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, + B2056_TX0, pts->tx, pts->tx_length); + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, + B2056_TX1, pts->tx, pts->tx_length); + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, + B2056_RX0, pts->rx, pts->rx_length); + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, + B2056_RX1, pts->rx, pts->rx_length); +} + /* TODO: add support for rev4+ devices by searching in rev4+ tables */ const struct b43_nphy_channeltab_entry_rev3 * b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index 302600c0afa4..d601f6e7e313 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -1114,4 +1114,7 @@ struct b43_nphy_channeltab_entry_rev3 { struct b43_phy_n_sfo_cfg phy_regs; }; +void b2056_upload_inittabs(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag); + #endif /* B43_RADIO_2056_H_ */ -- cgit v1.2.3-59-g8ed1b From 94a5b0452410f8bdff27aa13592bec046fb6095d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 11:50:21 +0100 Subject: b43: N-PHY: add init tables for 2056 radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.c | 2931 +++++++++++++++++++++++++++++++++ 1 file changed, 2931 insertions(+) diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index 1752d52ab40e..3cb98da8ae96 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -46,6 +46,2930 @@ struct b2056_inittabs_pts { unsigned int rx_length; }; +static const struct b2056_inittab_entry b2056_inittab_rev3_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev3_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev3_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0099, .ghz2 = 0x0099, NOUPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0044, .ghz2 = 0x0044, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0099, .ghz2 = 0x0099, NOUPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x0057, .ghz2 = 0x0057, NOUPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x0057, .ghz2 = 0x0057, NOUPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev4_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev4_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev4_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0044, .ghz2 = 0x0044, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x002f, .ghz2 = 0x002f, UPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev5_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev5_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, }, + [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, }, + [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, }, + [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0073, .ghz2 = 0x0073, UPLOAD, }, + [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, }, + [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev5_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev6_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev6_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev7_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev7_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, }, + [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, }, + [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, }, + [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0073, .ghz2 = 0x0073, UPLOAD, }, + [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, }, + [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev7_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev8_syn[] = { + [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, }, + [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, }, + [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, }, + [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, }, + [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, }, + [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, }, + [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev8_tx[] = { + [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, }, + [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, }, + [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, }, + [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, }, + [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, }, + [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, }, + [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, }, + [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, }, + [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, }, + [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, }, + [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, +}; + +static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = { + [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, }, + [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, }, + [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, }, + [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, }, + [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, }, + [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, }, + [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, }, + [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, }, + [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, }, + [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, }, + [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, }, + [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, }, + [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, }, + [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, }, + [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, }, + [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, }, + [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, }, + [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, }, + [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, }, + [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, }, + [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + #define INITTABSPTS(prefix) \ .syn = prefix##_syn, \ .syn_length = ARRAY_SIZE(prefix##_syn), \ @@ -55,6 +2979,13 @@ struct b2056_inittabs_pts { .rx_length = ARRAY_SIZE(prefix##_rx) struct b2056_inittabs_pts b2056_inittabs[] = { + [3] = { INITTABSPTS(b2056_inittab_rev3) }, + [4] = { INITTABSPTS(b2056_inittab_rev4) }, + [5] = { INITTABSPTS(b2056_inittab_rev5) }, + [6] = { INITTABSPTS(b2056_inittab_rev6) }, + [7] = { INITTABSPTS(b2056_inittab_rev7) }, + [8] = { INITTABSPTS(b2056_inittab_rev8) }, + [9] = { INITTABSPTS(b2056_inittab_rev7) }, }; #define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ -- cgit v1.2.3-59-g8ed1b From aca434d36f38754392f53e7b16f90eab66ae95e0 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 11:50:22 +0100 Subject: b43: N-PHY: avoid PHY hangs for rev 3 and 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 6b91cb353f23..f6e90a10c0dc 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3667,6 +3667,7 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev) memset(nphy, 0, sizeof(*nphy)); + nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4); nphy->gain_boost = true; /* this way we follow wl, assume it is true */ nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */ -- cgit v1.2.3-59-g8ed1b From d41446467320b7cbe550a85c44fd9d3cb12c119d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 19:40:18 +0100 Subject: b43: N-PHY: use correct channel tables for rev4+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 1 - drivers/net/wireless/b43/radio_2056.c | 37 +++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f6e90a10c0dc..dded2318ddf4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3607,7 +3607,6 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, if (dev->phy.rev >= 3) { tabent_r3 = b43_nphy_get_chantabent_rev3(dev, channel->center_freq); - tabent_r3 = NULL; if (!tabent_r3) return -ESRCH; } else { diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index 3cb98da8ae96..8890df067029 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -9053,15 +9053,44 @@ void b2056_upload_inittabs(struct b43_wldev *dev, B2056_RX1, pts->rx, pts->rx_length); } -/* TODO: add support for rev4+ devices by searching in rev4+ tables */ const struct b43_nphy_channeltab_entry_rev3 * b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) { const struct b43_nphy_channeltab_entry_rev3 *e; - unsigned int i; + unsigned int length, i; - for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) { - e = &(b43_nphy_channeltab_rev3[i]); + switch (dev->phy.rev) { + case 3: + e = b43_nphy_channeltab_rev3; + length = ARRAY_SIZE(b43_nphy_channeltab_rev3); + break; + case 4: + e = b43_nphy_channeltab_rev4; + length = ARRAY_SIZE(b43_nphy_channeltab_rev4); + break; + case 5: + e = b43_nphy_channeltab_rev5; + length = ARRAY_SIZE(b43_nphy_channeltab_rev5); + break; + case 6: + e = b43_nphy_channeltab_rev6; + length = ARRAY_SIZE(b43_nphy_channeltab_rev6); + break; + case 7: + case 9: + e = b43_nphy_channeltab_rev7_9; + length = ARRAY_SIZE(b43_nphy_channeltab_rev7_9); + break; + case 8: + e = b43_nphy_channeltab_rev8; + length = ARRAY_SIZE(b43_nphy_channeltab_rev8); + break; + default: + B43_WARN_ON(1); + return NULL; + } + + for (i = 0; i < length; i++, e++) { if (e->freq == freq) return e; } -- cgit v1.2.3-59-g8ed1b From d4814e69eec24f46a9f0a6d57b80e0a6add594c7 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 23:57:48 +0100 Subject: b43: N-PHY: update 2056 radio on channel switch on rev3+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 95 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index dded2318ddf4..ab81ed8b19d7 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -139,6 +139,99 @@ static void b43_chantab_radio_upload(struct b43_wldev *dev, b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); } +static void b43_chantab_radio_2056_upload(struct b43_wldev *dev, + const struct b43_nphy_channeltab_entry_rev3 *e) +{ + b43_radio_write(dev, B2056_SYN_PLL_VCOCAL1, e->radio_syn_pll_vcocal1); + b43_radio_write(dev, B2056_SYN_PLL_VCOCAL2, e->radio_syn_pll_vcocal2); + b43_radio_write(dev, B2056_SYN_PLL_REFDIV, e->radio_syn_pll_refdiv); + b43_radio_write(dev, B2056_SYN_PLL_MMD2, e->radio_syn_pll_mmd2); + b43_radio_write(dev, B2056_SYN_PLL_MMD1, e->radio_syn_pll_mmd1); + b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, + e->radio_syn_pll_loopfilter1); + b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, + e->radio_syn_pll_loopfilter2); + b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER3, + e->radio_syn_pll_loopfilter3); + b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, + e->radio_syn_pll_loopfilter4); + b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER5, + e->radio_syn_pll_loopfilter5); + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR27, + e->radio_syn_reserved_addr27); + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR28, + e->radio_syn_reserved_addr28); + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR29, + e->radio_syn_reserved_addr29); + b43_radio_write(dev, B2056_SYN_LOGEN_VCOBUF1, + e->radio_syn_logen_vcobuf1); + b43_radio_write(dev, B2056_SYN_LOGEN_MIXER2, e->radio_syn_logen_mixer2); + b43_radio_write(dev, B2056_SYN_LOGEN_BUF3, e->radio_syn_logen_buf3); + b43_radio_write(dev, B2056_SYN_LOGEN_BUF4, e->radio_syn_logen_buf4); + + b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA_TUNE, + e->radio_rx0_lnaa_tune); + b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG_TUNE, + e->radio_rx0_lnag_tune); + + b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAA_BOOST_TUNE, + e->radio_tx0_intpaa_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAG_BOOST_TUNE, + e->radio_tx0_intpag_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE, + e->radio_tx0_pada_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE, + e->radio_tx0_padg_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE, + e->radio_tx0_pgaa_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE, + e->radio_tx0_pgag_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE, + e->radio_tx0_mixa_boost_tune); + b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE, + e->radio_tx0_mixg_boost_tune); + + b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA_TUNE, + e->radio_rx1_lnaa_tune); + b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG_TUNE, + e->radio_rx1_lnag_tune); + + b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAA_BOOST_TUNE, + e->radio_tx1_intpaa_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAG_BOOST_TUNE, + e->radio_tx1_intpag_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE, + e->radio_tx1_pada_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE, + e->radio_tx1_padg_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE, + e->radio_tx1_pgaa_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE, + e->radio_tx1_pgag_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE, + e->radio_tx1_mixa_boost_tune); + b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE, + e->radio_tx1_mixg_boost_tune); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */ +static void b43_radio_2056_setup(struct b43_wldev *dev, + const struct b43_nphy_channeltab_entry_rev3 *e) +{ + B43_WARN_ON(dev->phy.rev < 3); + + b43_chantab_radio_2056_upload(dev, e); + /* TODO */ + udelay(50); + /* VCO calibration */ + b43_radio_write(dev, B2056_SYN_PLL_VCOCAL12, 0x00); + b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38); + b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x18); + b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38); + b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x39); + udelay(300); +} + static void b43_chantab_phy_upload(struct b43_wldev *dev, const struct b43_phy_n_sfo_cfg *e) { @@ -3635,7 +3728,7 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, if (dev->phy.rev >= 3) { tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0; b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); - /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */ + b43_radio_2056_setup(dev, tabent_r3); b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel); } else { tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050; -- cgit v1.2.3-59-g8ed1b From ab72efdf107e5b0e0a05efb8f24cc6c598ae31ea Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 21 Dec 2010 21:29:44 +0100 Subject: b43: N-PHY: enable support for PHYs rev 3 and higher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5fb0bc6710f6..22bc9f17f634 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4056,7 +4056,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) break; #ifdef CONFIG_B43_PHY_N case B43_PHYTYPE_N: - if (phy_rev > 2) + if (phy_rev > 9) unsupported = 1; break; #endif -- cgit v1.2.3-59-g8ed1b From bfe3850b0cfca6ba64395e2705d9a51cd044f374 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:05 +0200 Subject: rndis_wlan: scanning, workaround device returning incorrect bssid-list item count. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes device returns wrong number of items in bssid-list. Appears that some specific beacons trigger this problem and leads to very poor scanning results. Workaround by ignoring num_items received from device and walkthrough full bssid-list buffer. v2: Fix buffer range checks and reading next item length. Old code read behind buffer on last item but didn't use those values as 'count' would also reach zero. Also fix resizing of buffer if device has larger buffer, old code assumed that BSSID-list OID would return same buffer size when it really can return yet another new larger length. Tested-by: Luís Picciochi Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 80 ++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 4a4f00591447..de4c05019f1e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1967,8 +1967,8 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, int ie_len, bssid_len; u8 *ie; - netdev_dbg(usbdev->net, " found bssid: '%.32s' [%pM]\n", - bssid->ssid.essid, bssid->mac); + netdev_dbg(usbdev->net, " found bssid: '%.32s' [%pM], len: %d\n", + bssid->ssid.essid, bssid->mac, le32_to_cpu(bssid->length)); /* parse bssid structure */ bssid_len = le32_to_cpu(bssid->length); @@ -2002,54 +2002,98 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, GFP_KERNEL); } +static struct ndis_80211_bssid_ex *next_bssid_list_item( + struct ndis_80211_bssid_ex *bssid, + int *bssid_len, void *buf, int len) +{ + void *buf_end, *bssid_end; + + buf_end = (char *)buf + len; + bssid_end = (char *)bssid + *bssid_len; + + if ((int)(buf_end - bssid_end) < sizeof(bssid->length)) { + *bssid_len = 0; + return NULL; + } else { + bssid = (void *)((char *)bssid + *bssid_len); + *bssid_len = le32_to_cpu(bssid->length); + return bssid; + } +} + +static bool check_bssid_list_item(struct ndis_80211_bssid_ex *bssid, + int bssid_len, void *buf, int len) +{ + void *buf_end, *bssid_end; + + if (!bssid || bssid_len <= 0 || bssid_len > len) + return false; + + buf_end = (char *)buf + len; + bssid_end = (char *)bssid + bssid_len; + + return (int)(buf_end - bssid_end) >= 0 && (int)(bssid_end - buf) >= 0; +} + static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, bool *matched) { void *buf = NULL; struct ndis_80211_bssid_list_ex *bssid_list; struct ndis_80211_bssid_ex *bssid; - int ret = -EINVAL, len, count, bssid_len; - bool resized = false; + int ret = -EINVAL, len, count, bssid_len, real_count, new_len; - netdev_dbg(usbdev->net, "check_bssid_list\n"); + netdev_dbg(usbdev->net, "%s()\n", __func__); len = CONTROL_BUFFER_SIZE; resize_buf: - buf = kmalloc(len, GFP_KERNEL); + buf = kzalloc(len, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out; } - ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); - if (ret != 0) + /* BSSID-list might have got bigger last time we checked, keep + * resizing until it won't get any bigger. + */ + new_len = len; + ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &new_len); + if (ret != 0 || new_len < sizeof(struct ndis_80211_bssid_list_ex)) goto out; - if (!resized && len > CONTROL_BUFFER_SIZE) { - resized = true; + if (new_len > len) { + len = new_len; kfree(buf); goto resize_buf; } + len = new_len; + bssid_list = buf; - bssid = bssid_list->bssid; - bssid_len = le32_to_cpu(bssid->length); count = le32_to_cpu(bssid_list->num_items); - netdev_dbg(usbdev->net, "check_bssid_list: %d BSSIDs found (buflen: %d)\n", - count, len); + real_count = 0; + netdev_dbg(usbdev->net, "%s(): buflen: %d\n", __func__, len); + + bssid_len = 0; + bssid = next_bssid_list_item(bssid_list->bssid, &bssid_len, buf, len); - while (count && ((void *)bssid + bssid_len) <= (buf + len)) { + /* Device returns incorrect 'num_items'. Workaround by ignoring the + * received 'num_items' and walking through full bssid buffer instead. + */ + while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { if (compare_ether_addr(bssid->mac, match_bssid)) *matched = true; } - bssid = (void *)bssid + bssid_len; - bssid_len = le32_to_cpu(bssid->length); - count--; + real_count++; + bssid = next_bssid_list_item(bssid, &bssid_len, buf, len); } + netdev_dbg(usbdev->net, "%s(): num_items from device: %d, really found:" + " %d\n", __func__, count, real_count); + out: kfree(buf); return ret; -- cgit v1.2.3-59-g8ed1b From 0b578021745b61b2ff89f6bacbac5db08a9a8089 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:12 +0200 Subject: rndis_wlan: do not set default_key if not WEP key rndis_set_default_key did call add_wep_key to set default key on device, even if key is WPA. This caused rndis_wlan not work with wpa_supplicant in nl80211 mode (causing disconnect from AP). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index de4c05019f1e..9e6105cd54a5 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2435,6 +2435,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, priv->encr_tx_key_index = key_index; + if (is_wpa_key(priv, key_index)) + return 0; + key = priv->encr_keys[key_index]; return add_wep_key(usbdev, key.material, key.len, key_index); -- cgit v1.2.3-59-g8ed1b From 21b27beca73ad7d2829fe9cc3e48054f69e3d9d3 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:20 +0200 Subject: rndis_wlan: turn radio off before interface is bring up Radio should be off when interface is down. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9e6105cd54a5..42e19e85fa68 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -3398,9 +3398,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) rndis_set_wiphy_params(wiphy, WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD); - /* turn radio on */ - priv->radio_on = true; - disassociate(usbdev, true); + /* turn radio off on init */ + priv->radio_on = false; + disassociate(usbdev, false); netif_carrier_off(usbdev->net); return 0; -- cgit v1.2.3-59-g8ed1b From c2aa413279cde7c867fc90b07f83fff3c1e9e98d Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:27 +0200 Subject: rndis_wlan: constify rndis_config_ops Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 42e19e85fa68..d0992fcac7b6 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -570,7 +570,7 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); -static struct cfg80211_ops rndis_config_ops = { +static const struct cfg80211_ops rndis_config_ops = { .change_virtual_intf = rndis_change_virtual_intf, .scan = rndis_scan, .set_wiphy_params = rndis_set_wiphy_params, -- cgit v1.2.3-59-g8ed1b From a3463a1fdc9aa0881760e54efbd62742275601a5 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:34 +0200 Subject: rndis_wlan: remove unused variable from priv structure Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0992fcac7b6..aa21d867f0ee 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -503,7 +503,6 @@ struct rndis_wlan_private { int infra_mode; bool connected; u8 bssid[ETH_ALEN]; - struct ndis_80211_ssid essid; __le32 current_command_oid; /* encryption stuff */ @@ -1026,7 +1025,6 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) return ret; } if (ret == 0) { - memcpy(&priv->essid, ssid, sizeof(priv->essid)); priv->radio_on = true; netdev_dbg(usbdev->net, "%s(): radio_on = true\n", __func__); } -- cgit v1.2.3-59-g8ed1b From 49b35bd3f5bbc6997b24b04e9d4896f00cee3528 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:42 +0200 Subject: rndis_wlan: add support for set_cqm_rssi_config Device poller already reads current RSSI, so add support for set_cqm_rssi_config there. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 51 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index aa21d867f0ee..0cd971a4dd94 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -478,6 +478,9 @@ struct rndis_wlan_private { struct mutex command_lock; unsigned long work_pending; int last_qual; + s32 cqm_rssi_thold; + u32 cqm_rssi_hyst; + int last_cqm_event_rssi; struct ieee80211_supported_band band; struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)]; @@ -569,6 +572,10 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); +static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, + struct net_device *dev, + s32 rssi_thold, u32 rssi_hyst); + static const struct cfg80211_ops rndis_config_ops = { .change_virtual_intf = rndis_change_virtual_intf, .scan = rndis_scan, @@ -588,6 +595,7 @@ static const struct cfg80211_ops rndis_config_ops = { .set_pmksa = rndis_set_pmksa, .del_pmksa = rndis_del_pmksa, .flush_pmksa = rndis_flush_pmksa, + .set_cqm_rssi_config = rndis_set_cqm_rssi_config, }; static void *rndis_wiphy_privid = &rndis_wiphy_privid; @@ -2566,6 +2574,19 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); } +static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, + struct net_device *dev, + s32 rssi_thold, u32 rssi_hyst) +{ + struct rndis_wlan_private *priv = wiphy_priv(wiphy); + + priv->cqm_rssi_thold = rssi_thold; + priv->cqm_rssi_hyst = rssi_hyst; + priv->last_cqm_event_rssi = 0; + + return 0; +} + static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, struct ndis_80211_assoc_info *info) { @@ -3095,6 +3116,32 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy) return retval; } +static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi) +{ + struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + enum nl80211_cqm_rssi_threshold_event event; + int thold, hyst, last_event; + + if (priv->cqm_rssi_thold >= 0 || rssi >= 0) + return; + if (priv->infra_mode != NDIS_80211_INFRA_INFRA) + return; + + last_event = priv->last_cqm_event_rssi; + thold = priv->cqm_rssi_thold; + hyst = priv->cqm_rssi_hyst; + + if (rssi < thold && (last_event == 0 || rssi < last_event - hyst)) + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + else if (rssi > thold && (last_event == 0 || rssi > last_event + hyst)) + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + else + return; + + priv->last_cqm_event_rssi = rssi; + cfg80211_cqm_rssi_notify(usbdev->net, event, GFP_KERNEL); +} + #define DEVICE_POLLER_JIFFIES (HZ) static void rndis_device_poller(struct work_struct *work) { @@ -3129,8 +3176,10 @@ static void rndis_device_poller(struct work_struct *work) len = sizeof(rssi); ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); - if (ret == 0) + if (ret == 0) { priv->last_qual = level_to_qual(le32_to_cpu(rssi)); + rndis_do_cqm(usbdev, le32_to_cpu(rssi)); + } netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); -- cgit v1.2.3-59-g8ed1b From 40d70dd12200ffeacfe9caaa8242e3ad2995bb5d Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Dec 2010 22:44:49 +0200 Subject: rndis_wlan: add support for set_power_mgmt Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0cd971a4dd94..848cc2cce247 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -129,6 +129,7 @@ MODULE_PARM_DESC(workaround_interval, #define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a) #define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e) #define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211) +#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216) #define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217) @@ -239,6 +240,12 @@ enum ndis_80211_addwep_bits { NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) }; +enum ndis_80211_power_mode { + NDIS_80211_POWER_MODE_CAM, + NDIS_80211_POWER_MODE_MAX_PSP, + NDIS_80211_POWER_MODE_FAST_PSP, +}; + struct ndis_80211_auth_request { __le32 length; u8 bssid[6]; @@ -503,6 +510,7 @@ struct rndis_wlan_private { /* hardware state */ bool radio_on; + int power_mode; int infra_mode; bool connected; u8 bssid[ETH_ALEN]; @@ -572,6 +580,9 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); +static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout); + static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst); @@ -595,6 +606,7 @@ static const struct cfg80211_ops rndis_config_ops = { .set_pmksa = rndis_set_pmksa, .del_pmksa = rndis_del_pmksa, .flush_pmksa = rndis_flush_pmksa, + .set_power_mgmt = rndis_set_power_mgmt, .set_cqm_rssi_config = rndis_set_cqm_rssi_config, }; @@ -694,6 +706,7 @@ static const char *oid_to_string(__le32 oid) OID_STR(OID_802_11_ADD_KEY); OID_STR(OID_802_11_REMOVE_KEY); OID_STR(OID_802_11_ASSOCIATION_INFORMATION); + OID_STR(OID_802_11_CAPABILITY); OID_STR(OID_802_11_PMKID); OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED); OID_STR(OID_802_11_NETWORK_TYPE_IN_USE); @@ -704,6 +717,7 @@ static const char *oid_to_string(__le32 oid) OID_STR(OID_802_11_RTS_THRESHOLD); OID_STR(OID_802_11_SUPPORTED_RATES); OID_STR(OID_802_11_CONFIGURATION); + OID_STR(OID_802_11_POWER_MODE); OID_STR(OID_802_11_BSSID_LIST); #undef OID_STR } @@ -2574,6 +2588,38 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); } +static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct rndis_wlan_private *priv = wiphy_priv(wiphy); + struct usbnet *usbdev = priv->usbdev; + int power_mode; + __le32 mode; + int ret; + + netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__, + enabled ? "enabled" : "disabled", + timeout); + + if (enabled) + power_mode = NDIS_80211_POWER_MODE_FAST_PSP; + else + power_mode = NDIS_80211_POWER_MODE_CAM; + + if (power_mode == priv->power_mode) + return 0; + + priv->power_mode = power_mode; + + mode = cpu_to_le32(power_mode); + ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode)); + + netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n", + __func__, ret); + + return ret; +} + static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) @@ -3441,6 +3487,8 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) set_default_iw_params(usbdev); + priv->power_mode = -1; + /* set default rts/frag */ rndis_set_wiphy_params(wiphy, WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD); -- cgit v1.2.3-59-g8ed1b From e6d8a817d00793eecd063b1548bbc954ab62b124 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 21 Dec 2010 19:40:40 -0600 Subject: rtlwifi: rtl8192ce: Fix driver problem when radio switch off at module load If the radio enable switch is off when the driver is loaded, it is not possible to get radio output until the driver is unloaded and reloaded with the switch on. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 12 +++++------- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 11 ----------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index f6cc07369d75..cf0b73e51fc2 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -251,16 +251,14 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) bool blocked; u8 valid = 0; - /*set init state to rf on */ - rtlpriv->rfkill.rfkill_state = 1; - radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); - if (valid) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - (KERN_INFO "wireless switch is %s\n", - rtlpriv->rfkill.rfkill_state ? "on" : "off")); + /*set init state to that of switch */ + rtlpriv->rfkill.rfkill_state = radio_state; + printk(KERN_INFO "rtlwifi: wireless switch is %s\n", + rtlpriv->rfkill.rfkill_state ? "on" : "off"); + if (valid) { rtlpriv->rfkill.rfkill_state = radio_state; blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 1266dbe44176..1c41a0c93506 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -962,17 +962,6 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtl_cam_reset_all_entry(hw); rtl92ce_enable_hw_security_config(hw); ppsc->rfpwr_state = ERFON; - tmp_u1b = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&(~BIT(3)); - rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, tmp_u1b); - tmp_u1b = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); - ppsc->rfoff_reason |= (tmp_u1b & BIT(3)) ? 0 : RF_CHANGE_BY_HW; - if (ppsc->rfoff_reason > RF_CHANGE_BY_PS) - rtl_ps_set_rf_state(hw, ERFOFF, ppsc->rfoff_reason, true); - else { - ppsc->rfpwr_state = ERFON; - ppsc->rfoff_reason = 0; - rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); - } rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); _rtl92ce_enable_aspm_back_door(hw); rtlpriv->intf_ops->enable_aspm(hw); -- cgit v1.2.3-59-g8ed1b From db7ec38d8e99f449856c11ffaef363a8eb5af90f Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 22 Dec 2010 12:20:12 +0530 Subject: ath9k: Reset keycache on resume It looks like some hardware registers are left into undefined state after suspend/resume. At minimum, this can cause odd issues related to key cache and hardware trying to encrypt/decrypt frames unexpectedly. This seems to happen even when there is no keys configured, i.e., hardware can end up touching TX frames just based of invalid key cache context even if the driver is not asking a specific entry to be used. In addition, RX can likely be affected. This patch fixes this issue. Signed-off-by: Jouni Malinen Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 2 +- drivers/net/wireless/ath/ath9k/pci.c | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d9bda275ec21..fcc087ce3bc3 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -670,6 +670,7 @@ extern int ath9k_pm_qos_value; extern bool is_ath9k_unloaded; irqreturn_t ath_isr(int irq, void *dev); +void ath9k_init_crypto(struct ath_softc *sc); int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops); void ath9k_deinit_device(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 9efc77d82563..efb778d4356a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -373,7 +373,7 @@ fail: #undef DS2PHYS } -static void ath9k_init_crypto(struct ath_softc *sc) +void ath9k_init_crypto(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 545aa1c650cf..78ef1f13386f 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -311,6 +311,14 @@ static int ath_pci_resume(struct device *device) AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + /* + * Reset key cache to sane defaults (all entries cleared) instead of + * semi-random values after suspend/resume. + */ + ath9k_ps_wakeup(sc); + ath9k_init_crypto(sc); + ath9k_ps_restore(sc); + sc->ps_idle = true; ath9k_set_wiphy_idle(aphy, true); ath_radio_disable(sc, hw); -- cgit v1.2.3-59-g8ed1b From 172128468f61e16e1427238278b9ad775584aa89 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Dec 2010 10:15:30 +0100 Subject: mac80211: cleanup select_queue There's a redundant rcu_read_lock/unlock pair, a redundant variable, and a few redundant accesses to the 1d_to_ac array. Fix this to make the code neater and easier to follow. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/wme.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 58e75bbc1f91..28bc084dbfb9 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -59,26 +59,22 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct sta_info *sta = NULL; - u32 sta_flags = 0; const u8 *ra = NULL; bool qos = false; if (local->hw.queues < 4 || skb->len < 6) { skb->priority = 0; /* required for correct WPA/11i MIC */ - return min_t(u16, local->hw.queues - 1, - ieee802_1d_to_ac[skb->priority]); + return min_t(u16, local->hw.queues - 1, IEEE80211_AC_BE); } rcu_read_lock(); switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: - rcu_read_lock(); sta = rcu_dereference(sdata->u.vlan.sta); - if (sta) - sta_flags = get_sta_flags(sta); - rcu_read_unlock(); - if (sta) + if (sta) { + qos = get_sta_flags(sta) & WLAN_STA_WME; break; + } case NL80211_IFTYPE_AP: ra = skb->data; break; @@ -107,17 +103,13 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, if (!sta && ra && !is_multicast_ether_addr(ra)) { sta = sta_info_get(sdata, ra); if (sta) - sta_flags = get_sta_flags(sta); + qos = get_sta_flags(sta) & WLAN_STA_WME; } - - if (sta_flags & WLAN_STA_WME) - qos = true; - rcu_read_unlock(); if (!qos) { skb->priority = 0; /* required for correct WPA/11i MIC */ - return ieee802_1d_to_ac[skb->priority]; + return IEEE80211_AC_BE; } /* use the data classifier to determine what 802.1d tag the -- cgit v1.2.3-59-g8ed1b From 5c4bc1ce917d93ce8f7dd498fbec6881b3d7743a Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Wed, 22 Dec 2010 10:56:02 -0600 Subject: rtlwifi: Fix large packet issue An RX buffer is set to 9100 bytes to receive 8K AMSDU; however, an skb of this size fails in the kernel. Signed-off-by: Chaoming Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 353e20358885..0fa36aa6701a 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -612,10 +612,22 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) num_rx_inperiod++; } - if (unlikely(!rtl_action_proc(hw, skb, false))) + if (unlikely(!rtl_action_proc(hw, skb, + false))) { dev_kfree_skb_any(skb); - else - ieee80211_rx_irqsafe(hw, skb); + } else { + struct sk_buff *uskb = NULL; + u8 *pdata; + uskb = dev_alloc_skb(skb->len + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), + &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + dev_kfree_skb_any(skb); + + ieee80211_rx_irqsafe(hw, uskb); + } } else { dev_kfree_skb_any(skb); } -- cgit v1.2.3-59-g8ed1b From f622691c91cd1bb27d03a5caa8a43822572c62bc Mon Sep 17 00:00:00 2001 From: Tomoya Date: Wed, 22 Dec 2010 03:00:39 +0000 Subject: pch_can: Fix array miss-pointing issue Signed-off-by: Tomoya MORINAGA Signed-off-by: David S. Miller --- drivers/net/can/pch_can.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 8d45fdd0180d..c42e97268248 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1078,15 +1078,17 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Tx buffer enable state */ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) - priv->tx_enable[i] = pch_can_get_rxtx_ir(priv, i, PCH_TX_IFREG); + priv->tx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i, + PCH_TX_IFREG); /* Disable all Transmit buffers */ pch_can_set_tx_all(priv, 0); /* Save Rx buffer enable state */ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { - priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i, PCH_RX_IFREG); - priv->rx_link[i] = pch_can_get_rx_buffer_link(priv, i); + priv->rx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i, + PCH_RX_IFREG); + priv->rx_link[i - 1] = pch_can_get_rx_buffer_link(priv, i); } /* Disable all Receive buffers */ @@ -1139,15 +1141,15 @@ static int pch_can_resume(struct pci_dev *pdev) /* Enabling the transmit buffer. */ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) - pch_can_set_rxtx(priv, i, priv->tx_enable[i], PCH_TX_IFREG); + pch_can_set_rxtx(priv, i, priv->tx_enable[i - 1], PCH_TX_IFREG); /* Configuring the receive buffer and enabling them. */ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { /* Restore buffer link */ - pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i]); + pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i - 1]); /* Restore buffer enables */ - pch_can_set_rxtx(priv, i, priv->rx_enable[i], PCH_RX_IFREG); + pch_can_set_rxtx(priv, i, priv->rx_enable[i - 1], PCH_RX_IFREG); } /* Enable CAN Interrupts */ -- cgit v1.2.3-59-g8ed1b From e41d8b4e131a41f2a3b74aaa783b16aa46376d8e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 13 Dec 2010 21:07:03 +0200 Subject: Bluetooth: Add error handling for managment command handlers The command handlers for bluetooth management messaging should be able to report errors (such as memory allocation failures) to the higher levels in the call stack. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d15bf676c350..7ea5489e7977 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -29,7 +29,7 @@ #include #include -static void cmd_status(struct sock *sk, u16 cmd, u8 status) +static int cmd_status(struct sock *sk, u16 cmd, u8 status) { struct sk_buff *skb; struct mgmt_hdr *hdr; @@ -39,7 +39,7 @@ static void cmd_status(struct sock *sk, u16 cmd, u8 status) skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); if (!skb) - return; + return -ENOMEM; hdr = (void *) skb_put(skb, sizeof(*hdr)); @@ -52,6 +52,8 @@ static void cmd_status(struct sock *sk, u16 cmd, u8 status) if (sock_queue_rcv_skb(sk, skb) < 0) kfree_skb(skb); + + return 0; } int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) @@ -87,10 +89,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) switch (opcode) { default: BT_DBG("Unknown op %u", opcode); - cmd_status(sk, opcode, 0x01); + err = cmd_status(sk, opcode, 0x01); break; } + if (err < 0) + goto done; + err = msglen; done: -- cgit v1.2.3-59-g8ed1b From 02d981292ad3149e8e5f37cffbccedab1a8576d8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 13 Dec 2010 21:07:04 +0200 Subject: Bluetooth: Add read_version management command This patch implements the initial read_version command that userspace will use before any other management interface operations. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/mgmt.h | 6 ++++++ net/bluetooth/mgmt.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 95974daa725e..d353d64bfffb 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -27,6 +27,12 @@ struct mgmt_hdr { } __packed; #define MGMT_HDR_SIZE 4 +#define MGMT_OP_READ_VERSION 0x0001 +struct mgmt_rp_read_version { + __u8 version; + __le16 revision; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 7ea5489e7977..3e24c0bf18e7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -29,6 +29,39 @@ #include #include +#define MGMT_VERSION 0 +#define MGMT_REVISION 1 + +static int read_version(struct sock *sk) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + struct mgmt_ev_cmd_complete *ev; + struct mgmt_rp_read_version *rp; + + BT_DBG("sock %p", sk); + + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); + + ev = (void *) skb_put(skb, sizeof(*ev)); + put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode); + + rp = (void *) skb_put(skb, sizeof(*rp)); + rp->version = MGMT_VERSION; + put_unaligned_le16(MGMT_REVISION, &rp->revision); + + if (sock_queue_rcv_skb(sk, skb) < 0) + kfree_skb(skb); + + return 0; +} + static int cmd_status(struct sock *sk, u16 cmd, u8 status) { struct sk_buff *skb; @@ -87,6 +120,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } switch (opcode) { + case MGMT_OP_READ_VERSION: + err = read_version(sk); + break; default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, opcode, 0x01); -- cgit v1.2.3-59-g8ed1b From faba42eb2a8cf905ed26d540c3c93d429e327224 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 13 Dec 2010 21:07:05 +0200 Subject: Bluetooth: Add read_index_list management command This patch implements the read_index_list command through which userspace can get a list of current adapter indices. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/mgmt.h | 6 +++++ net/bluetooth/mgmt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index d353d64bfffb..c2b4c83ab175 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -33,6 +33,12 @@ struct mgmt_rp_read_version { __le16 revision; } __packed; +#define MGMT_OP_READ_INDEX_LIST 0x0003 +struct mgmt_rp_read_index_list { + __le16 num_controllers; + __le16 index[0]; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3e24c0bf18e7..7a8e321875c9 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -62,6 +62,56 @@ static int read_version(struct sock *sk) return 0; } +static int read_index_list(struct sock *sk) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + struct mgmt_ev_cmd_complete *ev; + struct mgmt_rp_read_index_list *rp; + struct list_head *p; + size_t body_len; + u16 count; + int i; + + BT_DBG("sock %p", sk); + + read_lock(&hci_dev_list_lock); + + count = 0; + list_for_each(p, &hci_dev_list) { + count++; + } + + body_len = sizeof(*ev) + sizeof(*rp) + (2 * count); + skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->len = cpu_to_le16(body_len); + + ev = (void *) skb_put(skb, sizeof(*ev)); + put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode); + + rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count)); + put_unaligned_le16(count, &rp->num_controllers); + + i = 0; + list_for_each(p, &hci_dev_list) { + struct hci_dev *d = list_entry(p, struct hci_dev, list); + put_unaligned_le16(d->id, &rp->index[i++]); + BT_DBG("Added hci%u", d->id); + } + + read_unlock(&hci_dev_list_lock); + + if (sock_queue_rcv_skb(sk, skb) < 0) + kfree_skb(skb); + + return 0; +} + static int cmd_status(struct sock *sk, u16 cmd, u8 status) { struct sk_buff *skb; @@ -123,6 +173,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) case MGMT_OP_READ_VERSION: err = read_version(sk); break; + case MGMT_OP_READ_INDEX_LIST: + err = read_index_list(sk); + break; default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, opcode, 0x01); -- cgit v1.2.3-59-g8ed1b From f7b64e69c7c75c8e9f2d5e23edec8de1ce883bcc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 13 Dec 2010 21:07:06 +0200 Subject: Bluetooth: Add read_info management command This patch implements the read_info command which is used to fetch basic info about an adapter. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/mgmt.h | 19 ++++++++++ net/bluetooth/mgmt.c | 90 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 8 deletions(-) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index c2b4c83ab175..70985aacc14b 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -39,6 +39,25 @@ struct mgmt_rp_read_index_list { __le16 index[0]; } __packed; +#define MGMT_OP_READ_INFO 0x0004 +struct mgmt_cp_read_info { + __le16 index; +} __packed; +struct mgmt_rp_read_info { + __le16 index; + __u8 type; + __u8 powered; + __u8 discoverable; + __u8 pairable; + __u8 sec_mode; + bdaddr_t bdaddr; + __u8 dev_class[3]; + __u8 features[8]; + __u16 manufacturer; + __u8 hci_ver; + __u16 hci_rev; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 7a8e321875c9..d6c5a32de0b6 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -32,6 +32,33 @@ #define MGMT_VERSION 0 #define MGMT_REVISION 1 +static int cmd_status(struct sock *sk, u16 cmd, u8 status) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + struct mgmt_ev_cmd_status *ev; + + BT_DBG("sock %p", sk); + + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); + hdr->len = cpu_to_le16(sizeof(*ev)); + + ev = (void *) skb_put(skb, sizeof(*ev)); + ev->status = status; + put_unaligned_le16(cmd, &ev->opcode); + + if (sock_queue_rcv_skb(sk, skb) < 0) + kfree_skb(skb); + + return 0; +} + static int read_version(struct sock *sk) { struct sk_buff *skb; @@ -112,26 +139,70 @@ static int read_index_list(struct sock *sk) return 0; } -static int cmd_status(struct sock *sk, u16 cmd, u8 status) +static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) { struct sk_buff *skb; struct mgmt_hdr *hdr; - struct mgmt_ev_cmd_status *ev; + struct mgmt_ev_cmd_complete *ev; + struct mgmt_rp_read_info *rp; + struct mgmt_cp_read_info *cp; + struct hci_dev *hdev; + u16 dev_id; BT_DBG("sock %p", sk); - skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); + if (len != 2) + return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); + + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); if (!skb) return -ENOMEM; hdr = (void *) skb_put(skb, sizeof(*hdr)); - - hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); - hdr->len = cpu_to_le16(sizeof(*ev)); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); ev = (void *) skb_put(skb, sizeof(*ev)); - ev->status = status; - put_unaligned_le16(cmd, &ev->opcode); + put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode); + + rp = (void *) skb_put(skb, sizeof(*rp)); + + cp = (void *) data; + dev_id = get_unaligned_le16(&cp->index); + + BT_DBG("request for hci%u", dev_id); + + hdev = hci_dev_get(dev_id); + if (!hdev) { + kfree_skb(skb); + return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); + } + + hci_dev_lock_bh(hdev); + + put_unaligned_le16(hdev->id, &rp->index); + rp->type = hdev->dev_type; + + rp->powered = test_bit(HCI_UP, &hdev->flags); + rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags); + rp->pairable = test_bit(HCI_PSCAN, &hdev->flags); + + if (test_bit(HCI_AUTH, &hdev->flags)) + rp->sec_mode = 3; + else if (hdev->ssp_mode > 0) + rp->sec_mode = 4; + else + rp->sec_mode = 2; + + bacpy(&rp->bdaddr, &hdev->bdaddr); + memcpy(rp->features, hdev->features, 8); + memcpy(rp->dev_class, hdev->dev_class, 3); + put_unaligned_le16(hdev->manufacturer, &rp->manufacturer); + rp->hci_ver = hdev->hci_ver; + put_unaligned_le16(hdev->hci_rev, &rp->hci_rev); + + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); if (sock_queue_rcv_skb(sk, skb) < 0) kfree_skb(skb); @@ -176,6 +247,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) case MGMT_OP_READ_INDEX_LIST: err = read_index_list(sk); break; + case MGMT_OP_READ_INFO: + err = read_controller_info(sk, buf + sizeof(*hdr), len); + break; default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, opcode, 0x01); -- cgit v1.2.3-59-g8ed1b From c71e97bfaadfa727669fcfcf12301744fd169091 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 13 Dec 2010 21:07:07 +0200 Subject: Bluetooth: Add management events for controller addition & removal This patch adds Bluetooth Management interface events for controller addition and removal. The events correspond to the existing HCI_DEV_REG and HCI_DEV_UNREG stack internal events. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 2 ++ include/net/bluetooth/mgmt.h | 10 ++++++++++ net/bluetooth/hci_core.c | 2 ++ net/bluetooth/mgmt.c | 41 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 1992fac7e921..3786ee83604e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -662,6 +662,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); /* Management interface */ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); +int mgmt_index_added(u16 index); +int mgmt_index_removed(u16 index); /* HCI info for socket */ #define hci_pi(sk) ((struct hci_pinfo *) sk) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 70985aacc14b..ca29c1367ffd 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -75,3 +75,13 @@ struct mgmt_ev_controller_error { __le16 index; __u8 error_code; } __packed; + +#define MGMT_EV_INDEX_ADDED 0x0004 +struct mgmt_ev_index_added { + __le16 index; +} __packed; + +#define MGMT_EV_INDEX_REMOVED 0x0005 +struct mgmt_ev_index_removed { + __le16 index; +} __packed; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 51c61f75a797..1a4ec97d5ac4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -960,6 +960,7 @@ int hci_register_dev(struct hci_dev *hdev) } } + mgmt_index_added(hdev->id); hci_notify(hdev, HCI_DEV_REG); return id; @@ -989,6 +990,7 @@ int hci_unregister_dev(struct hci_dev *hdev) for (i = 0; i < NUM_REASSEMBLY; i++) kfree_skb(hdev->reassembly[i]); + mgmt_index_removed(hdev->id); hci_notify(hdev, HCI_DEV_UNREG); if (hdev->rfkill) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d6c5a32de0b6..f827fd908380 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -265,3 +265,44 @@ done: kfree(buf); return err; } + +static int mgmt_event(u16 event, void *data, u16 data_len) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + + skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + bt_cb(skb)->channel = HCI_CHANNEL_CONTROL; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + hdr->opcode = cpu_to_le16(event); + hdr->len = cpu_to_le16(data_len); + + memcpy(skb_put(skb, data_len), data, data_len); + + hci_send_to_sock(NULL, skb); + kfree_skb(skb); + + return 0; +} + +int mgmt_index_added(u16 index) +{ + struct mgmt_ev_index_added ev; + + put_unaligned_le16(index, &ev.index); + + return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev)); +} + +int mgmt_index_removed(u16 index) +{ + struct mgmt_ev_index_added ev; + + put_unaligned_le16(index, &ev.index); + + return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev)); +} -- cgit v1.2.3-59-g8ed1b From 23bb57633df97ede067ea26f3cdc8a7ba2cd8109 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 21 Dec 2010 23:01:27 +0200 Subject: Bluetooth: Fix __hci_request synchronization for hci_open_dev The initialization function used by hci_open_dev (hci_init_req) sends many different HCI commands. The __hci_request function should only return when all of these commands have completed (or a timeout occurs). Several of these commands cause hci_req_complete to be called which causes __hci_request to return prematurely. This patch fixes the issue by adding a new hdev->req_last_cmd variable which is set during the initialization procedure. The hci_req_complete function will no longer mark the request as complete until the command matching hdev->req_last_cmd completes. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 3 ++- net/bluetooth/hci_core.c | 15 ++++++++++++--- net/bluetooth/hci_event.c | 33 +++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3786ee83604e..a29feb01854e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -129,6 +129,7 @@ struct hci_dev { wait_queue_head_t req_wait_q; __u32 req_status; __u32 req_result; + __u16 req_last_cmd; struct inquiry_cache inq_cache; struct hci_conn_hash conn_hash; @@ -693,6 +694,6 @@ struct hci_sec_filter { #define hci_req_lock(d) mutex_lock(&d->req_lock) #define hci_req_unlock(d) mutex_unlock(&d->req_lock) -void hci_req_complete(struct hci_dev *hdev, int result); +void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); #endif /* __HCI_CORE_H */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 1a4ec97d5ac4..8b602d881fd7 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -91,9 +91,16 @@ static void hci_notify(struct hci_dev *hdev, int event) /* ---- HCI requests ---- */ -void hci_req_complete(struct hci_dev *hdev, int result) +void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) { - BT_DBG("%s result 0x%2.2x", hdev->name, result); + BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); + + /* If the request has set req_last_cmd (typical for multi-HCI + * command requests) check if the completed command matches + * this, and if not just return. Single HCI command requests + * typically leave req_last_cmd as 0 */ + if (hdev->req_last_cmd && cmd != hdev->req_last_cmd) + return; if (hdev->req_status == HCI_REQ_PEND) { hdev->req_result = result; @@ -149,7 +156,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, break; } - hdev->req_status = hdev->req_result = 0; + hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0; BT_DBG("%s end: err %d", hdev->name, err); @@ -252,6 +259,8 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) /* Connection accept timeout ~20 secs */ param = cpu_to_le16(0x7d00); hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); + + hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT; } static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8923b36a67a2..38100170d380 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -58,7 +58,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_INQUIRY, &hdev->flags); - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); hci_conn_check_pending(hdev); } @@ -174,7 +174,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *s if (!status) hdev->link_policy = get_unaligned_le16(sent); - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status); } static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) @@ -183,7 +183,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_RESET, status); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) @@ -235,7 +235,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_AUTH, &hdev->flags); } - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status); } static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) @@ -258,7 +258,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_ENCRYPT, &hdev->flags); } - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status); } static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) @@ -285,7 +285,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) set_bit(HCI_PSCAN, &hdev->flags); } - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); } static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) @@ -383,7 +383,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); } static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) @@ -536,7 +536,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) if (!rp->status) bacpy(&hdev->bdaddr, &rp->bdaddr); - hci_req_complete(hdev, rp->status); + hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); +} + +static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) +{ + __u8 status = *((__u8 *) skb->data); + + BT_DBG("%s status 0x%x", hdev->name, status); + + hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); } static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) @@ -544,7 +553,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) BT_DBG("%s status 0x%x", hdev->name, status); if (status) { - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_INQUIRY, status); hci_conn_check_pending(hdev); } else @@ -871,7 +880,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff clear_bit(HCI_INQUIRY, &hdev->flags); - hci_req_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_INQUIRY, status); hci_conn_check_pending(hdev); } @@ -1379,6 +1388,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk hci_cc_read_bd_addr(hdev, skb); break; + case HCI_OP_WRITE_CA_TIMEOUT: + hci_cc_write_ca_timeout(hdev, skb); + break; + default: BT_DBG("%s opcode 0x%x", hdev->name, opcode); break; -- cgit v1.2.3-59-g8ed1b From 17f9cc3124c97f50a19a7597e5f29f915b5b835c Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 22 Dec 2010 23:00:34 -0200 Subject: Bluetooth: Improve handling of HCI control channel in bind Does not allow any channel different of HCI_CHANNEL_RAW and HCI_CHANNEL_CONTROL to bind. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_sock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index f6c18abab797..29827c77f6ce 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -380,7 +380,10 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le if (haddr.hci_family != AF_BLUETOOTH) return -EINVAL; - if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt) + if (haddr.hci_channel > HCI_CHANNEL_CONTROL) + return -EINVAL; + + if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt) return -EINVAL; lock_sock(sk); -- cgit v1.2.3-59-g8ed1b From d9f4fbaf7053af43e6c72909c2aff18654717aed Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 22 Dec 2010 23:23:38 +0000 Subject: tcp: cleanup of cwnd initialization in tcp_init_metrics() Commit 86bcebafc5e7f5 ("tcp: fix >2 iw selection") fixed a case when congestion window initialization has been mistakenly omitted by introducing cwnd label and putting backwards goto from the end of the function. This makes the code unnecessarily tricky to read and understand on a first sight. Shuffle the code around a little bit to make it more obvious. Signed-off-by: Jiri Kosina Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 824e8c8a17ad..2549b29b062d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -916,25 +916,20 @@ static void tcp_init_metrics(struct sock *sk) tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); } tcp_set_rto(sk); - if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp) - goto reset; - -cwnd: - tp->snd_cwnd = tcp_init_cwnd(tp, dst); - tp->snd_cwnd_stamp = tcp_time_stamp; - return; - + if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp) { reset: - /* Play conservative. If timestamps are not - * supported, TCP will fail to recalculate correct - * rtt, if initial rto is too small. FORGET ALL AND RESET! - */ - if (!tp->rx_opt.saw_tstamp && tp->srtt) { - tp->srtt = 0; - tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT; - inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT; + /* Play conservative. If timestamps are not + * supported, TCP will fail to recalculate correct + * rtt, if initial rto is too small. FORGET ALL AND RESET! + */ + if (!tp->rx_opt.saw_tstamp && tp->srtt) { + tp->srtt = 0; + tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT; + inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT; + } } - goto cwnd; + tp->snd_cwnd = tcp_init_cwnd(tp, dst); + tp->snd_cwnd_stamp = tcp_time_stamp; } static void tcp_update_reordering(struct sock *sk, const int metric, -- cgit v1.2.3-59-g8ed1b From 9b09336072796378dac46df63bcd43291b24fd12 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:42:56 +0000 Subject: cnic: Fix iSCSI TCP port endian order. Pass the TCP port parameter for iSCSI connections to the firmware in proper endian order. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 23 +++++++++++++---------- drivers/net/cnic.h | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 594ca9c2c10a..9c2e7860b18e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2883,7 +2883,7 @@ static void cnic_cm_cleanup(struct cnic_sock *csk) struct cnic_dev *dev = csk->dev; struct cnic_local *cp = dev->cnic_priv; - cnic_free_id(&cp->csk_port_tbl, csk->src_port); + cnic_free_id(&cp->csk_port_tbl, be16_to_cpu(csk->src_port)); csk->src_port = 0; } } @@ -3014,7 +3014,8 @@ static int cnic_get_route(struct cnic_sock *csk, struct cnic_sockaddr *saddr) int is_v6, rc = 0; struct dst_entry *dst = NULL; struct net_device *realdev; - u32 local_port; + __be16 local_port; + u32 port_id; if (saddr->local.v6.sin6_family == AF_INET6 && saddr->remote.v6.sin6_family == AF_INET6) @@ -3054,19 +3055,21 @@ static int cnic_get_route(struct cnic_sock *csk, struct cnic_sockaddr *saddr) } } - if (local_port >= CNIC_LOCAL_PORT_MIN && - local_port < CNIC_LOCAL_PORT_MAX) { - if (cnic_alloc_id(&cp->csk_port_tbl, local_port)) - local_port = 0; + port_id = be16_to_cpu(local_port); + if (port_id >= CNIC_LOCAL_PORT_MIN && + port_id < CNIC_LOCAL_PORT_MAX) { + if (cnic_alloc_id(&cp->csk_port_tbl, port_id)) + port_id = 0; } else - local_port = 0; + port_id = 0; - if (!local_port) { - local_port = cnic_alloc_new_id(&cp->csk_port_tbl); - if (local_port == -1) { + if (!port_id) { + port_id = cnic_alloc_new_id(&cp->csk_port_tbl); + if (port_id == -1) { rc = -ENOMEM; goto err_out; } + local_port = cpu_to_be16(port_id); } csk->src_port = local_port; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 6a4a0ae5cfe3..bf38e5788d3f 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -82,7 +82,7 @@ struct cnic_redirect_entry { #define MAX_ISCSI_TBL_SZ 256 #define CNIC_LOCAL_PORT_MIN 60000 -#define CNIC_LOCAL_PORT_MAX 61000 +#define CNIC_LOCAL_PORT_MAX 61024 #define CNIC_LOCAL_PORT_RANGE (CNIC_LOCAL_PORT_MAX - CNIC_LOCAL_PORT_MIN) #define KWQE_CNT (BCM_PAGE_SIZE / sizeof(struct kwqe)) -- cgit v1.2.3-59-g8ed1b From 8adc9240f98a816f7e9b3d93b9446a790110e062 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:42:57 +0000 Subject: cnic: Prevent "scheduling while atomic" when calling ->cnic_init() cnic_dev_list is protected by rtnl_lock and cnic_dev_lock spin_lock during modifications. When looping on cnic_dev_list and calling ->cnic_init(), we should just hold rtnl_lock since ->cnic_init() may sleep. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 9c2e7860b18e..3a7d3ce6db7b 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -59,6 +59,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II CNIC Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(CNIC_MODULE_VERSION); +/* cnic_dev_list modifications are protected by both rtnl and cnic_dev_lock */ static LIST_HEAD(cnic_dev_list); static LIST_HEAD(cnic_udev_list); static DEFINE_RWLOCK(cnic_dev_lock); @@ -445,14 +446,12 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) /* Prevent race conditions with netdev_event */ rtnl_lock(); - read_lock(&cnic_dev_lock); list_for_each_entry(dev, &cnic_dev_list, list) { struct cnic_local *cp = dev->cnic_priv; if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[ulp_type])) ulp_ops->cnic_init(dev); } - read_unlock(&cnic_dev_lock); rtnl_unlock(); return 0; -- cgit v1.2.3-59-g8ed1b From 939b82e5bde56a98c72eccde2e3a88d32bffad4a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:42:58 +0000 Subject: cnic: Improve ->iscsi_nl_msg_send() 1. Change first parameter from cnic_dev to ulp_handle which is the hba pointer. All other similar upcalls are using hba pointer. The callee can then directly reference the hba without conversion. 2. Change return value from void to int so that an error code can be passed back. This allows the operation to be retried. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 21 ++++++++++++++++----- drivers/net/cnic_if.h | 2 +- drivers/scsi/bnx2i/bnx2i_hwi.c | 14 ++++++++------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 3a7d3ce6db7b..9f80fb40380a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -279,6 +279,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, u32 msg_type = ISCSI_KEVENT_IF_DOWN; struct cnic_ulp_ops *ulp_ops; struct cnic_uio_dev *udev = cp->udev; + int rc = 0, retry = 0; if (!udev || udev->uio_dev == -1) return -ENODEV; @@ -303,11 +304,21 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, path_req.pmtu = csk->mtu; } - rcu_read_lock(); - ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); - if (ulp_ops) - ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len); - rcu_read_unlock(); + while (retry < 3) { + rc = 0; + rcu_read_lock(); + ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); + if (ulp_ops) + rc = ulp_ops->iscsi_nl_send_msg( + cp->ulp_handle[CNIC_ULP_ISCSI], + msg_type, buf, len); + rcu_read_unlock(); + if (rc == 0 || msg_type != ISCSI_KEVENT_PATH_REQ) + break; + + msleep(100); + retry++; + } return 0; } diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 0dbeaec4f03a..33333e735f95 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -301,7 +301,7 @@ struct cnic_ulp_ops { void (*cm_abort_complete)(struct cnic_sock *); void (*cm_remote_close)(struct cnic_sock *); void (*cm_remote_abort)(struct cnic_sock *); - void (*iscsi_nl_send_msg)(struct cnic_dev *dev, u32 msg_type, + int (*iscsi_nl_send_msg)(void *ulp_ctx, u32 msg_type, char *data, u16 data_size); struct module *owner; atomic_t ref_count; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 8d9dbb33972f..2f9622ebbd84 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2346,19 +2346,21 @@ static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk) } -static void bnx2i_send_nl_mesg(struct cnic_dev *dev, u32 msg_type, +static int bnx2i_send_nl_mesg(void *context, u32 msg_type, char *buf, u16 buflen) { - struct bnx2i_hba *hba; + struct bnx2i_hba *hba = context; + int rc; - hba = bnx2i_find_hba_for_cnic(dev); if (!hba) - return; + return -ENODEV; - if (iscsi_offload_mesg(hba->shost, &bnx2i_iscsi_transport, - msg_type, buf, buflen)) + rc = iscsi_offload_mesg(hba->shost, &bnx2i_iscsi_transport, + msg_type, buf, buflen); + if (rc) printk(KERN_ALERT "bnx2i: private nl message send error\n"); + return rc; } -- cgit v1.2.3-59-g8ed1b From 5159fdc1e6cb4000f482faebeeba0be91611276d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:42:59 +0000 Subject: cnic: Use proper client and connection IDs on iSCSI ring Use the IDs specified by the bnx2x driver when initializing the ring. We don't have to make code changes when these IDs change in the future. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 21 ++++++++++++--------- drivers/net/cnic.h | 5 ----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 9f80fb40380a..9bd133d3a5aa 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4119,7 +4119,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int port = CNIC_PORT(cp); int i; - int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cli = cp->ethdev->iscsi_l2_client_id; u32 val; memset(txbd, 0, BCM_PAGE_SIZE); @@ -4180,7 +4180,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; int port = CNIC_PORT(cp); - int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cli = cp->ethdev->iscsi_l2_client_id; int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; dma_addr_t ring_map = udev->l2_ring_map; @@ -4244,6 +4244,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, cp->rx_cons_ptr = &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; + cp->rx_cons = *cp->rx_cons_ptr; } static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) @@ -4437,7 +4438,8 @@ static void cnic_init_rings(struct cnic_dev *dev) cnic_init_bnx2_rx_ring(dev); set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cli = cp->ethdev->iscsi_l2_client_id; + u32 cid = cp->ethdev->iscsi_l2_cid; u32 cl_qzone_id, type; struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; @@ -4478,7 +4480,7 @@ static void cnic_init_rings(struct cnic_dev *dev) set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, - BNX2X_ISCSI_L2_CID, type, &l5_data); + cid, type, &l5_data); i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && @@ -4489,7 +4491,7 @@ static void cnic_init_rings(struct cnic_dev *dev) netdev_err(dev->netdev, "iSCSI CLIENT_SETUP did not complete\n"); cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); - cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); + cnic_ring_ctl(dev, cid, cli, 1); } } @@ -4504,19 +4506,20 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) cnic_shutdown_bnx2_rx_ring(dev); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { struct cnic_local *cp = dev->cnic_priv; - u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cli = cp->ethdev->iscsi_l2_client_id; + u32 cid = cp->ethdev->iscsi_l2_cid; union l5cm_specific_data l5_data; int i; u32 type; - cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0); + cnic_ring_ctl(dev, cid, cli, 0); set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); l5_data.phy_address.lo = cli; l5_data.phy_address.hi = 0; cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_HALT, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); + cid, ETH_CONNECTION_TYPE, &l5_data); i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && ++i < 10) @@ -4533,7 +4536,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & SPE_HDR_FUNCTION_ID); cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, - BNX2X_ISCSI_L2_CID, type, &l5_data); + cid, type, &l5_data); msleep(10); } clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index bf38e5788d3f..8e947b7e0700 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -356,11 +356,6 @@ struct bnx2x_bd_chain_next { #define BNX2X_CONTEXT_MEM_SIZE 1024 #define BNX2X_FCOE_CID 16 -/* iSCSI client IDs are 17, 19, 21, 23 */ -#define BNX2X_ISCSI_BASE_CL_ID 17 -#define BNX2X_ISCSI_CL_ID(vn) (BNX2X_ISCSI_BASE_CL_ID + ((vn) << 1)) - -#define BNX2X_ISCSI_L2_CID 17 #define BNX2X_ISCSI_START_CID 18 #define BNX2X_ISCSI_NUM_CONNECTIONS 128 #define BNX2X_ISCSI_TASK_CONTEXT_SIZE 128 -- cgit v1.2.3-59-g8ed1b From 4aacb7afb6afd78efe26427e74fa56a5fc72fad3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:43:01 +0000 Subject: cnic: Support NIC Partition mode Add a common function cnic_read_bnx2x_iscsi_mac() to read the iSCSI MAC address at any specified shared memory location. In NIC Partition mode, we need to get the MAC address from the MF_CFG area of shared memory. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 84 ++++++++++++++++++++++++++++++++++++++++++------------ drivers/net/cnic.h | 3 ++ 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 9bd133d3a5aa..bf4a804e4787 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4247,10 +4247,36 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, cp->rx_cons = *cp->rx_cons_ptr; } +static int cnic_read_bnx2x_iscsi_mac(struct cnic_dev *dev, u32 upper_addr, + u32 lower_addr) +{ + u32 val; + u8 mac[6]; + + val = CNIC_RD(dev, upper_addr); + + mac[0] = (u8) (val >> 8); + mac[1] = (u8) val; + + val = CNIC_RD(dev, lower_addr); + + mac[2] = (u8) (val >> 24); + mac[3] = (u8) (val >> 16); + mac[4] = (u8) (val >> 8); + mac[5] = (u8) val; + + if (is_valid_ether_addr(mac)) { + memcpy(dev->mac_addr, mac, 6); + return 0; + } else { + return -EINVAL; + } +} + static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u32 base, base2, addr, val; + u32 base, base2, addr, addr1, val; int port = CNIC_PORT(cp); dev->max_iscsi_conn = 0; @@ -4263,20 +4289,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) addr = BNX2X_SHMEM_ADDR(base, dev_info.port_hw_config[port].iscsi_mac_upper); - val = CNIC_RD(dev, addr); - - dev->mac_addr[0] = (u8) (val >> 8); - dev->mac_addr[1] = (u8) val; - - addr = BNX2X_SHMEM_ADDR(base, + addr1 = BNX2X_SHMEM_ADDR(base, dev_info.port_hw_config[port].iscsi_mac_lower); - val = CNIC_RD(dev, addr); - - dev->mac_addr[2] = (u8) (val >> 24); - dev->mac_addr[3] = (u8) (val >> 16); - dev->mac_addr[4] = (u8) (val >> 8); - dev->mac_addr[5] = (u8) val; + cnic_read_bnx2x_iscsi_mac(dev, addr, addr1); addr = BNX2X_SHMEM_ADDR(base, validity_map[port]); val = CNIC_RD(dev, addr); @@ -4302,21 +4318,53 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) else mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; - addr = mf_cfg_addr + - offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + /* Must determine if the MF is SD vs SI mode */ + addr = BNX2X_SHMEM_ADDR(base, + dev_info.shared_feature_config.config); + val = CNIC_RD(dev, addr); + if ((val & SHARED_FEAT_CFG_FORCE_SF_MODE_MASK) == + SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT) { + int rc; + + /* MULTI_FUNCTION_SI mode */ + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, + func_ext_config[func].func_cfg); + val = CNIC_RD(dev, addr); + if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD)) + dev->max_iscsi_conn = 0; + + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, + func_ext_config[func]. + iscsi_mac_addr_upper); + addr1 = BNX2X_MF_CFG_ADDR(mf_cfg_addr, + func_ext_config[func]. + iscsi_mac_addr_lower); + rc = cnic_read_bnx2x_iscsi_mac(dev, addr, + addr1); + if (rc && func > 1) + dev->max_iscsi_conn = 0; + + return; + } + } + + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, + func_mf_config[func].e1hov_tag); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - addr = mf_cfg_addr + - offsetof(struct mf_cfg, - func_mf_config[func].config); + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, + func_mf_config[func].config); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_PROTOCOL_MASK; if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) dev->max_iscsi_conn = 0; } } + if (!is_valid_ether_addr(dev->mac_addr)) + dev->max_iscsi_conn = 0; } static int cnic_start_bnx2x_hw(struct cnic_dev *dev) diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 8e947b7e0700..fb3b7531ea25 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -422,6 +422,9 @@ struct bnx2x_bd_chain_next { (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \ offsetof(struct shmem2_region, field))) +#define BNX2X_MF_CFG_ADDR(base, field) \ + ((base) + offsetof(struct mf_cfg, field)) + #define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) #define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ -- cgit v1.2.3-59-g8ed1b From eaaa6e9c222d5c398488ed4216f0fd94e4b81759 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 08:38:30 +0000 Subject: cnic: Check device state before reading the kcq pointer in IRQ If the device is down, the kcq pointer may be NULL. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index bf4a804e4787..1240deaf2420 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2352,11 +2352,12 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) static int cnic_service_bnx2(void *data, void *status_blk) { struct cnic_dev *dev = data; - struct cnic_local *cp = dev->cnic_priv; - u32 status_idx = *cp->kcq1.status_idx_ptr; - if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) - return status_idx; + if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) { + struct status_block *sblk = status_blk; + + return sblk->status_idx; + } return cnic_service_bnx2_queues(dev); } @@ -2375,9 +2376,10 @@ static void cnic_service_bnx2_msix(unsigned long data) static void cnic_doirq(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u16 prod = cp->kcq1.sw_prod_idx & MAX_KCQ_IDX; if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) { + u16 prod = cp->kcq1.sw_prod_idx & MAX_KCQ_IDX; + prefetch(cp->status_blk.gen); prefetch(&cp->kcq1.kcq[KCQ_PG(prod)][KCQ_IDX(prod)]); -- cgit v1.2.3-59-g8ed1b From 42ecbb8426aa229167d7f9d4b4e20f24bf42cb24 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Thu, 23 Dec 2010 07:43:02 +0000 Subject: cnic: Call cm_connect_complete() immediately on error If we get a path_resp error from userspace, call cm_connect_complete() immediately with error so that bnx2i can react to the error faster. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 1240deaf2420..36c1578a1b1e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -322,6 +322,8 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, return 0; } +static void cnic_cm_upcall(struct cnic_local *, struct cnic_sock *, u8); + static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, char *buf, u16 len) { @@ -351,7 +353,9 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, } csk = &cp->csk_tbl[l5_cid]; csk_hold(csk); - if (cnic_in_use(csk)) { + if (cnic_in_use(csk) && + test_bit(SK_F_CONNECT_START, &csk->flags)) { + memcpy(csk->ha, path_resp->mac_addr, 6); if (test_bit(SK_F_IPV6, &csk->flags)) memcpy(&csk->src_ip[0], &path_resp->src.v6_addr, @@ -359,8 +363,16 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, else memcpy(&csk->src_ip[0], &path_resp->src.v4_addr, sizeof(struct in_addr)); - if (is_valid_ether_addr(csk->ha)) + + if (is_valid_ether_addr(csk->ha)) { cnic_cm_set_pg(csk); + } else if (!test_bit(SK_F_OFFLD_SCHED, &csk->flags) && + !test_bit(SK_F_OFFLD_COMPLETE, &csk->flags)) { + + cnic_cm_upcall(cp, csk, + L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE); + clear_bit(SK_F_CONNECT_START, &csk->flags); + } } csk_put(csk); rcu_read_unlock(); -- cgit v1.2.3-59-g8ed1b From e21ba414eed8a233eadb79bb6b158ac7ceb35025 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:43:03 +0000 Subject: cnic: Add kcq2 support on 57712 The kcq2 (2nd kernel work queue) is used by FCoE on 57712 devices. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 76 +++++++++++++++++++++++++++++++++++++++--------------- drivers/net/cnic.h | 1 + 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 36c1578a1b1e..6ce739859ac3 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -843,6 +843,7 @@ static void cnic_free_resc(struct cnic_dev *dev) cnic_free_dma(dev, &cp->conn_buf_info); cnic_free_dma(dev, &cp->kwq_info); cnic_free_dma(dev, &cp->kwq_16_data_info); + cnic_free_dma(dev, &cp->kcq2.dma); cnic_free_dma(dev, &cp->kcq1.dma); kfree(cp->iscsi_tbl); cp->iscsi_tbl = NULL; @@ -1183,6 +1184,12 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) if (ret) goto error; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + ret = cnic_alloc_kcq(dev, &cp->kcq2); + if (ret) + goto error; + } + pages = PAGE_ALIGN(BNX2X_ISCSI_NUM_CONNECTIONS * BNX2X_ISCSI_CONN_BUF_SIZE) / PAGE_SIZE; ret = cnic_alloc_dma(dev, &cp->conn_buf_info, pages, 1); @@ -2493,12 +2500,19 @@ static void cnic_service_bnx2x_bh(unsigned long data) status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - if (BNX2X_CHIP_IS_E2(cp->chip_id)) + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + + CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + + MAX_KCQ_IDX); + cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, status_idx, IGU_INT_ENABLE, 1); - else + } else { cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, status_idx, IGU_INT_ENABLE, 1); + } } static int cnic_service_bnx2x(void *data, void *status_blk) @@ -4381,6 +4395,44 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) dev->max_iscsi_conn = 0; } +static void cnic_init_bnx2x_kcq(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + u32 pfid = cp->pfid; + + cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + + CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); + cp->kcq1.sw_prod_idx = 0; + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + struct host_hc_status_block_e2 *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } else { + struct host_hc_status_block_e1x *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + struct host_hc_status_block_e2 *sb = cp->status_blk.gen; + + cp->kcq2.io_addr = BAR_USTRORM_INTMEM + + USTORM_FCOE_EQ_PROD_OFFSET(pfid); + cp->kcq2.sw_prod_idx = 0; + cp->kcq2.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS]; + cp->kcq2.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } +} + static int cnic_start_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -4413,25 +4465,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2; - cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); - cp->kcq1.sw_prod_idx = 0; - - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - struct host_hc_status_block_e2 *sb = cp->status_blk.gen; - - cp->kcq1.hw_prod_idx_ptr = - &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; - cp->kcq1.status_idx_ptr = - &sb->sb.running_index[SM_RX_ID]; - } else { - struct host_hc_status_block_e1x *sb = cp->status_blk.gen; - - cp->kcq1.hw_prod_idx_ptr = - &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; - cp->kcq1.status_idx_ptr = - &sb->sb.running_index[SM_RX_ID]; - } + cnic_init_bnx2x_kcq(dev); cnic_get_bnx2x_iscsi_info(dev); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index fb3b7531ea25..e46b4c121948 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -258,6 +258,7 @@ struct cnic_local { u16 kwq_con_idx; struct kcq_info kcq1; + struct kcq_info kcq2; union { void *gen; -- cgit v1.2.3-59-g8ed1b From e1928c86c4829703b800c81cc9edc939b5634e6f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 23 Dec 2010 07:43:04 +0000 Subject: cnic: Add FCoE support on 57712 - Connection ID (cid) management - Slow-path command and response support - Update version to 2.2.11. Reviewed-by: Bhanu Prakash Gollapudi Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 466 ++++++++++- drivers/net/cnic.h | 16 +- drivers/net/cnic_defs.h | 2099 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/cnic_if.h | 22 +- 4 files changed, 2587 insertions(+), 16 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 6ce739859ac3..4a9c628ab2a6 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -850,6 +850,7 @@ static void cnic_free_resc(struct cnic_dev *dev) kfree(cp->ctx_tbl); cp->ctx_tbl = NULL; + cnic_free_id_tbl(&cp->fcoe_cid_tbl); cnic_free_id_tbl(&cp->cid_tbl); } @@ -1137,12 +1138,22 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->iro_arr = ethdev->iro_arr; - cp->max_cid_space = MAX_ISCSI_TBL_SZ; + cp->max_cid_space = MAX_ISCSI_TBL_SZ + BNX2X_FCOE_NUM_CONNECTIONS; cp->iscsi_start_cid = start_cid; + cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ; + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + cp->max_cid_space += BNX2X_FCOE_NUM_CONNECTIONS; + cp->fcoe_init_cid = ethdev->fcoe_init_cid; + if (!cp->fcoe_init_cid) + cp->fcoe_init_cid = 0x10; + } + if (start_cid < BNX2X_ISCSI_START_CID) { u32 delta = BNX2X_ISCSI_START_CID - start_cid; cp->iscsi_start_cid = BNX2X_ISCSI_START_CID; + cp->fcoe_start_cid += delta; cp->max_cid_space += delta; } @@ -1161,6 +1172,9 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_ISCSI; } + for (i = MAX_ISCSI_TBL_SZ; i < cp->max_cid_space; i++) + cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_FCOE; + pages = PAGE_ALIGN(cp->max_cid_space * CNIC_KWQ16_DATA_SIZE) / PAGE_SIZE; @@ -1454,8 +1468,11 @@ static void cnic_free_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid) cnic_free_dma(dev, &iscsi->hq_info); cnic_free_dma(dev, &iscsi->r2tq_info); cnic_free_dma(dev, &iscsi->task_array_info); + cnic_free_id(&cp->cid_tbl, ctx->cid); + } else { + cnic_free_id(&cp->fcoe_cid_tbl, ctx->cid); } - cnic_free_id(&cp->cid_tbl, ctx->cid); + ctx->cid = 0; } @@ -1467,6 +1484,16 @@ static int cnic_alloc_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid) struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; struct cnic_iscsi *iscsi = ctx->proto.iscsi; + if (ctx->ulp_proto_id == CNIC_ULP_FCOE) { + cid = cnic_alloc_new_id(&cp->fcoe_cid_tbl); + if (cid == -1) { + ret = -ENOMEM; + goto error; + } + ctx->cid = cid; + return 0; + } + cid = cnic_alloc_new_id(&cp->cid_tbl); if (cid == -1) { ret = -ENOMEM; @@ -2107,8 +2134,307 @@ static int cnic_bnx2x_update_pg(struct cnic_dev *dev, struct kwqe *kwqe) return 0; } -static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], - u32 num_wqes) +static int cnic_bnx2x_fcoe_stat(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct fcoe_kwqe_stat *req; + struct fcoe_stat_ramrod_params *fcoe_stat; + union l5cm_specific_data l5_data; + struct cnic_local *cp = dev->cnic_priv; + int ret; + u32 cid; + + req = (struct fcoe_kwqe_stat *) kwqe; + cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); + + fcoe_stat = cnic_get_kwqe_16_data(cp, BNX2X_FCOE_L5_CID_BASE, &l5_data); + if (!fcoe_stat) + return -ENOMEM; + + memset(fcoe_stat, 0, sizeof(*fcoe_stat)); + memcpy(&fcoe_stat->stat_kwqe, req, sizeof(*req)); + + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_STAT, cid, + FCOE_CONNECTION_TYPE, &l5_data); + return ret; +} + +static int cnic_bnx2x_fcoe_init1(struct cnic_dev *dev, struct kwqe *wqes[], + u32 num, int *work) +{ + int ret; + struct cnic_local *cp = dev->cnic_priv; + u32 cid; + struct fcoe_init_ramrod_params *fcoe_init; + struct fcoe_kwqe_init1 *req1; + struct fcoe_kwqe_init2 *req2; + struct fcoe_kwqe_init3 *req3; + union l5cm_specific_data l5_data; + + if (num < 3) { + *work = num; + return -EINVAL; + } + req1 = (struct fcoe_kwqe_init1 *) wqes[0]; + req2 = (struct fcoe_kwqe_init2 *) wqes[1]; + req3 = (struct fcoe_kwqe_init3 *) wqes[2]; + if (req2->hdr.op_code != FCOE_KWQE_OPCODE_INIT2) { + *work = 1; + return -EINVAL; + } + if (req3->hdr.op_code != FCOE_KWQE_OPCODE_INIT3) { + *work = 2; + return -EINVAL; + } + + if (sizeof(*fcoe_init) > CNIC_KWQ16_DATA_SIZE) { + netdev_err(dev->netdev, "fcoe_init size too big\n"); + return -ENOMEM; + } + fcoe_init = cnic_get_kwqe_16_data(cp, BNX2X_FCOE_L5_CID_BASE, &l5_data); + if (!fcoe_init) + return -ENOMEM; + + memset(fcoe_init, 0, sizeof(*fcoe_init)); + memcpy(&fcoe_init->init_kwqe1, req1, sizeof(*req1)); + memcpy(&fcoe_init->init_kwqe2, req2, sizeof(*req2)); + memcpy(&fcoe_init->init_kwqe3, req3, sizeof(*req3)); + fcoe_init->eq_addr.lo = cp->kcq2.dma.pg_map_arr[0] & 0xffffffff; + fcoe_init->eq_addr.hi = (u64) cp->kcq2.dma.pg_map_arr[0] >> 32; + fcoe_init->eq_next_page_addr.lo = + cp->kcq2.dma.pg_map_arr[1] & 0xffffffff; + fcoe_init->eq_next_page_addr.hi = + (u64) cp->kcq2.dma.pg_map_arr[1] >> 32; + + fcoe_init->sb_num = cp->status_blk_num; + fcoe_init->eq_prod = MAX_KCQ_IDX; + fcoe_init->sb_id = HC_INDEX_FCOE_EQ_CONS; + cp->kcq2.sw_prod_idx = 0; + + cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); + printk(KERN_ERR "bdbg: submitting INIT RAMROD \n"); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_INIT, cid, + FCOE_CONNECTION_TYPE, &l5_data); + *work = 3; + return ret; +} + +static int cnic_bnx2x_fcoe_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], + u32 num, int *work) +{ + int ret = 0; + u32 cid = -1, l5_cid; + struct cnic_local *cp = dev->cnic_priv; + struct fcoe_kwqe_conn_offload1 *req1; + struct fcoe_kwqe_conn_offload2 *req2; + struct fcoe_kwqe_conn_offload3 *req3; + struct fcoe_kwqe_conn_offload4 *req4; + struct fcoe_conn_offload_ramrod_params *fcoe_offload; + struct cnic_context *ctx; + struct fcoe_context *fctx; + struct regpair ctx_addr; + union l5cm_specific_data l5_data; + struct fcoe_kcqe kcqe; + struct kcqe *cqes[1]; + + if (num < 4) { + *work = num; + return -EINVAL; + } + req1 = (struct fcoe_kwqe_conn_offload1 *) wqes[0]; + req2 = (struct fcoe_kwqe_conn_offload2 *) wqes[1]; + req3 = (struct fcoe_kwqe_conn_offload3 *) wqes[2]; + req4 = (struct fcoe_kwqe_conn_offload4 *) wqes[3]; + + *work = 4; + + l5_cid = req1->fcoe_conn_id; + if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS) + goto err_reply; + + l5_cid += BNX2X_FCOE_L5_CID_BASE; + + ctx = &cp->ctx_tbl[l5_cid]; + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + goto err_reply; + + ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid); + if (ret) { + ret = 0; + goto err_reply; + } + cid = ctx->cid; + + fctx = cnic_get_bnx2x_ctx(dev, cid, 1, &ctx_addr); + if (fctx) { + u32 hw_cid = BNX2X_HW_CID(cp, cid); + u32 val; + + val = CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_XCM_AG, + FCOE_CONNECTION_TYPE); + fctx->xstorm_ag_context.cdu_reserved = val; + val = CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_UCM_AG, + FCOE_CONNECTION_TYPE); + fctx->ustorm_ag_context.cdu_usage = val; + } + if (sizeof(*fcoe_offload) > CNIC_KWQ16_DATA_SIZE) { + netdev_err(dev->netdev, "fcoe_offload size too big\n"); + goto err_reply; + } + fcoe_offload = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data); + if (!fcoe_offload) + goto err_reply; + + memset(fcoe_offload, 0, sizeof(*fcoe_offload)); + memcpy(&fcoe_offload->offload_kwqe1, req1, sizeof(*req1)); + memcpy(&fcoe_offload->offload_kwqe2, req2, sizeof(*req2)); + memcpy(&fcoe_offload->offload_kwqe3, req3, sizeof(*req3)); + memcpy(&fcoe_offload->offload_kwqe4, req4, sizeof(*req4)); + + cid = BNX2X_HW_CID(cp, cid); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, cid, + FCOE_CONNECTION_TYPE, &l5_data); + if (!ret) + set_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + + return ret; + +err_reply: + if (cid != -1) + cnic_free_bnx2x_conn_resc(dev, l5_cid); + + memset(&kcqe, 0, sizeof(kcqe)); + kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN; + kcqe.fcoe_conn_id = req1->fcoe_conn_id; + kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE; + + cqes[0] = (struct kcqe *) &kcqe; + cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_FCOE, cqes, 1); + return ret; +} + +static int cnic_bnx2x_fcoe_enable(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct fcoe_kwqe_conn_enable_disable *req; + struct fcoe_conn_enable_disable_ramrod_params *fcoe_enable; + union l5cm_specific_data l5_data; + int ret; + u32 cid, l5_cid; + struct cnic_local *cp = dev->cnic_priv; + + req = (struct fcoe_kwqe_conn_enable_disable *) kwqe; + cid = req->context_id; + l5_cid = req->conn_id + BNX2X_FCOE_L5_CID_BASE; + + if (sizeof(*fcoe_enable) > CNIC_KWQ16_DATA_SIZE) { + netdev_err(dev->netdev, "fcoe_enable size too big\n"); + return -ENOMEM; + } + fcoe_enable = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data); + if (!fcoe_enable) + return -ENOMEM; + + memset(fcoe_enable, 0, sizeof(*fcoe_enable)); + memcpy(&fcoe_enable->enable_disable_kwqe, req, sizeof(*req)); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_ENABLE_CONN, cid, + FCOE_CONNECTION_TYPE, &l5_data); + return ret; +} + +static int cnic_bnx2x_fcoe_disable(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct fcoe_kwqe_conn_enable_disable *req; + struct fcoe_conn_enable_disable_ramrod_params *fcoe_disable; + union l5cm_specific_data l5_data; + int ret; + u32 cid, l5_cid; + struct cnic_local *cp = dev->cnic_priv; + + req = (struct fcoe_kwqe_conn_enable_disable *) kwqe; + cid = req->context_id; + l5_cid = req->conn_id; + if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS) + return -EINVAL; + + l5_cid += BNX2X_FCOE_L5_CID_BASE; + + if (sizeof(*fcoe_disable) > CNIC_KWQ16_DATA_SIZE) { + netdev_err(dev->netdev, "fcoe_disable size too big\n"); + return -ENOMEM; + } + fcoe_disable = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data); + if (!fcoe_disable) + return -ENOMEM; + + memset(fcoe_disable, 0, sizeof(*fcoe_disable)); + memcpy(&fcoe_disable->enable_disable_kwqe, req, sizeof(*req)); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DISABLE_CONN, cid, + FCOE_CONNECTION_TYPE, &l5_data); + return ret; +} + +static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct fcoe_kwqe_conn_destroy *req; + union l5cm_specific_data l5_data; + int ret; + u32 cid, l5_cid; + struct cnic_local *cp = dev->cnic_priv; + struct cnic_context *ctx; + struct fcoe_kcqe kcqe; + struct kcqe *cqes[1]; + + req = (struct fcoe_kwqe_conn_destroy *) kwqe; + cid = req->context_id; + l5_cid = req->conn_id; + if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS) + return -EINVAL; + + l5_cid += BNX2X_FCOE_L5_CID_BASE; + + ctx = &cp->ctx_tbl[l5_cid]; + + init_waitqueue_head(&ctx->waitq); + ctx->wait_cond = 0; + + memset(&l5_data, 0, sizeof(l5_data)); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_TERMINATE_CONN, cid, + FCOE_CONNECTION_TYPE, &l5_data); + if (ret == 0) { + wait_event(ctx->waitq, ctx->wait_cond); + set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags); + queue_delayed_work(cnic_wq, &cp->delete_task, + msecs_to_jiffies(2000)); + } + + memset(&kcqe, 0, sizeof(kcqe)); + kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN; + kcqe.fcoe_conn_id = req->conn_id; + kcqe.fcoe_conn_context_id = cid; + + cqes[0] = (struct kcqe *) &kcqe; + cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_FCOE, cqes, 1); + return ret; +} + +static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct fcoe_kwqe_destroy *req; + union l5cm_specific_data l5_data; + struct cnic_local *cp = dev->cnic_priv; + int ret; + u32 cid; + + req = (struct fcoe_kwqe_destroy *) kwqe; + cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); + + memset(&l5_data, 0, sizeof(l5_data)); + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DESTROY, cid, + FCOE_CONNECTION_TYPE, &l5_data); + return ret; +} + +static int cnic_submit_bnx2x_iscsi_kwqes(struct cnic_dev *dev, + struct kwqe *wqes[], u32 num_wqes) { int i, work, ret; u32 opcode; @@ -2172,6 +2498,98 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], return 0; } +static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev, + struct kwqe *wqes[], u32 num_wqes) +{ + struct cnic_local *cp = dev->cnic_priv; + int i, work, ret; + u32 opcode; + struct kwqe *kwqe; + + if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) + return -EAGAIN; /* bnx2 is down */ + + if (BNX2X_CHIP_NUM(cp->chip_id) == BNX2X_CHIP_NUM_57710) + return -EINVAL; + + for (i = 0; i < num_wqes; ) { + kwqe = wqes[i]; + opcode = KWQE_OPCODE(kwqe->kwqe_op_flag); + work = 1; + + switch (opcode) { + case FCOE_KWQE_OPCODE_INIT1: + ret = cnic_bnx2x_fcoe_init1(dev, &wqes[i], + num_wqes - i, &work); + break; + case FCOE_KWQE_OPCODE_OFFLOAD_CONN1: + ret = cnic_bnx2x_fcoe_ofld1(dev, &wqes[i], + num_wqes - i, &work); + break; + case FCOE_KWQE_OPCODE_ENABLE_CONN: + ret = cnic_bnx2x_fcoe_enable(dev, kwqe); + break; + case FCOE_KWQE_OPCODE_DISABLE_CONN: + ret = cnic_bnx2x_fcoe_disable(dev, kwqe); + break; + case FCOE_KWQE_OPCODE_DESTROY_CONN: + ret = cnic_bnx2x_fcoe_destroy(dev, kwqe); + break; + case FCOE_KWQE_OPCODE_DESTROY: + ret = cnic_bnx2x_fcoe_fw_destroy(dev, kwqe); + break; + case FCOE_KWQE_OPCODE_STAT: + ret = cnic_bnx2x_fcoe_stat(dev, kwqe); + break; + default: + ret = 0; + netdev_err(dev->netdev, "Unknown type of KWQE(0x%x)\n", + opcode); + break; + } + if (ret < 0) + netdev_err(dev->netdev, "KWQE(0x%x) failed\n", + opcode); + i += work; + } + return 0; +} + +static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], + u32 num_wqes) +{ + int ret = -EINVAL; + u32 layer_code; + + if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) + return -EAGAIN; /* bnx2x is down */ + + if (!num_wqes) + return 0; + + layer_code = wqes[0]->kwqe_op_flag & KWQE_LAYER_MASK; + switch (layer_code) { + case KWQE_FLAGS_LAYER_MASK_L5_ISCSI: + case KWQE_FLAGS_LAYER_MASK_L4: + case KWQE_FLAGS_LAYER_MASK_L2: + ret = cnic_submit_bnx2x_iscsi_kwqes(dev, wqes, num_wqes); + break; + + case KWQE_FLAGS_LAYER_MASK_L5_FCOE: + ret = cnic_submit_bnx2x_fcoe_kwqes(dev, wqes, num_wqes); + break; + } + return ret; +} + +static inline u32 cnic_get_kcqe_layer_mask(u32 opflag) +{ + if (unlikely(KCQE_OPCODE(opflag) == FCOE_RAMROD_CMD_ID_TERMINATE_CONN)) + return KCQE_FLAGS_LAYER_MASK_L4; + + return opflag & KCQE_FLAGS_LAYER_MASK; +} + static void service_kcqes(struct cnic_dev *dev, int num_cqes) { struct cnic_local *cp = dev->cnic_priv; @@ -2183,7 +2601,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) struct cnic_ulp_ops *ulp_ops; int ulp_type; u32 kcqe_op_flag = cp->completed_kcq[i]->kcqe_op_flag; - u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK; + u32 kcqe_layer = cnic_get_kcqe_layer_mask(kcqe_op_flag); if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION)) comp++; @@ -2191,7 +2609,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) while (j < num_cqes) { u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag; - if ((next_op & KCQE_FLAGS_LAYER_MASK) != kcqe_layer) + if (cnic_get_kcqe_layer_mask(next_op) != kcqe_layer) break; if (unlikely(next_op & KCQE_RAMROD_COMPLETION)) @@ -2203,6 +2621,8 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) ulp_type = CNIC_ULP_RDMA; else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L5_ISCSI) ulp_type = CNIC_ULP_ISCSI; + else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L5_FCOE) + ulp_type = CNIC_ULP_FCOE; else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L4) ulp_type = CNIC_ULP_L4; else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L2) @@ -3249,6 +3669,18 @@ done: csk_put(csk); } +static void cnic_process_fcoe_term_conn(struct cnic_dev *dev, struct kcqe *kcqe) +{ + struct cnic_local *cp = dev->cnic_priv; + struct fcoe_kcqe *fc_kcqe = (struct fcoe_kcqe *) kcqe; + u32 l5_cid = fc_kcqe->fcoe_conn_id + BNX2X_FCOE_L5_CID_BASE; + struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + + ctx->timestamp = jiffies; + ctx->wait_cond = 1; + wake_up(&ctx->waitq); +} + static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) { struct cnic_local *cp = dev->cnic_priv; @@ -3257,6 +3689,10 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) u32 l5_cid; struct cnic_sock *csk; + if (opcode == FCOE_RAMROD_CMD_ID_TERMINATE_CONN) { + cnic_process_fcoe_term_conn(dev, kcqe); + return; + } if (opcode == L4_KCQE_OPCODE_VALUE_OFFLOAD_PG || opcode == L4_KCQE_OPCODE_VALUE_UPDATE_PG) { cnic_cm_process_offld_pg(dev, l4kcqe); @@ -3893,7 +4329,7 @@ static void cnic_shutdown_bnx2_rx_ring(struct cnic_dev *dev) memset(&l2kwqe, 0, sizeof(l2kwqe)); wqes[0] = &l2kwqe; - l2kwqe.kwqe_op_flag = (L2_LAYER_CODE << KWQE_FLAGS_LAYER_SHIFT) | + l2kwqe.kwqe_op_flag = (L2_LAYER_CODE << KWQE_LAYER_SHIFT) | (L2_KWQE_OPCODE_VALUE_FLUSH << KWQE_OPCODE_SHIFT) | 2; dev->submit_kwqes(dev, wqes, 1); @@ -4336,6 +4772,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) val16 ^= 0x1e1e; dev->max_iscsi_conn = val16; } + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) + dev->max_fcoe_conn = BNX2X_FCOE_NUM_CONNECTIONS; + if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) { int func = CNIC_FUNC(cp); u32 mf_cfg_addr; @@ -4362,6 +4802,9 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD)) dev->max_iscsi_conn = 0; + if (!(val & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)) + dev->max_fcoe_conn = 0; + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, func_ext_config[func]. iscsi_mac_addr_upper); @@ -4463,6 +4906,15 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return -ENOMEM; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + ret = cnic_init_id_tbl(&cp->fcoe_cid_tbl, + BNX2X_FCOE_NUM_CONNECTIONS, + cp->fcoe_start_cid); + + if (ret) + return -ENOMEM; + } + cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2; cnic_init_bnx2x_kcq(dev); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index e46b4c121948..b328f6c924c3 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -291,6 +291,10 @@ struct cnic_local { atomic_t iscsi_conn; u32 iscsi_start_cid; + u32 fcoe_init_cid; + u32 fcoe_start_cid; + struct cnic_id_tbl fcoe_cid_tbl; + u32 max_cid_space; /* per connection parameters */ @@ -368,6 +372,10 @@ struct bnx2x_bd_chain_next { #define BNX2X_ISCSI_PBL_NOT_CACHED 0xff #define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff +#define BNX2X_FCOE_NUM_CONNECTIONS 128 + +#define BNX2X_FCOE_L5_CID_BASE MAX_ISCSI_TBL_SZ + #define BNX2X_CHIP_NUM_57710 0x164e #define BNX2X_CHIP_NUM_57711 0x164f #define BNX2X_CHIP_NUM_57711E 0x1650 @@ -426,6 +434,10 @@ struct bnx2x_bd_chain_next { #define BNX2X_MF_CFG_ADDR(base, field) \ ((base) + offsetof(struct mf_cfg, field)) +#ifndef ETH_MAX_RX_CLIENTS_E2 +#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H +#endif + #define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) #define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ @@ -438,7 +450,9 @@ struct bnx2x_bd_chain_next { #define BNX2X_SW_CID(x) (x & 0x1ffff) #define BNX2X_CL_QZONE_ID(cp, cli) \ - (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H)) + (cli + (CNIC_PORT(cp) * (BNX2X_CHIP_IS_E2(cp->chip_id) ?\ + ETH_MAX_RX_CLIENTS_E2 : \ + ETH_MAX_RX_CLIENTS_E1H))) #define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4) #endif diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h index 328e8b2765a3..fdbc00415603 100644 --- a/drivers/net/cnic_defs.h +++ b/drivers/net/cnic_defs.h @@ -35,6 +35,40 @@ #define L5CM_RAMROD_CMD_ID_SEARCHER_DELETE (L5CM_RAMROD_CMD_ID_BASE + 14) #define L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD (L5CM_RAMROD_CMD_ID_BASE + 15) +#define FCOE_KCQE_OPCODE_INIT_FUNC (0x10) +#define FCOE_KCQE_OPCODE_DESTROY_FUNC (0x11) +#define FCOE_KCQE_OPCODE_STAT_FUNC (0x12) +#define FCOE_KCQE_OPCODE_OFFLOAD_CONN (0x15) +#define FCOE_KCQE_OPCODE_ENABLE_CONN (0x16) +#define FCOE_KCQE_OPCODE_DISABLE_CONN (0x17) +#define FCOE_KCQE_OPCODE_DESTROY_CONN (0x18) +#define FCOE_KCQE_OPCODE_CQ_EVENT_NOTIFICATION (0x20) +#define FCOE_KCQE_OPCODE_FCOE_ERROR (0x21) + +#define FCOE_RAMROD_CMD_ID_INIT (FCOE_KCQE_OPCODE_INIT_FUNC) +#define FCOE_RAMROD_CMD_ID_DESTROY (FCOE_KCQE_OPCODE_DESTROY_FUNC) +#define FCOE_RAMROD_CMD_ID_OFFLOAD_CONN (FCOE_KCQE_OPCODE_OFFLOAD_CONN) +#define FCOE_RAMROD_CMD_ID_ENABLE_CONN (FCOE_KCQE_OPCODE_ENABLE_CONN) +#define FCOE_RAMROD_CMD_ID_DISABLE_CONN (FCOE_KCQE_OPCODE_DISABLE_CONN) +#define FCOE_RAMROD_CMD_ID_DESTROY_CONN (FCOE_KCQE_OPCODE_DESTROY_CONN) +#define FCOE_RAMROD_CMD_ID_STAT (FCOE_KCQE_OPCODE_STAT_FUNC) +#define FCOE_RAMROD_CMD_ID_TERMINATE_CONN (0x81) + +#define FCOE_KWQE_OPCODE_INIT1 (0) +#define FCOE_KWQE_OPCODE_INIT2 (1) +#define FCOE_KWQE_OPCODE_INIT3 (2) +#define FCOE_KWQE_OPCODE_OFFLOAD_CONN1 (3) +#define FCOE_KWQE_OPCODE_OFFLOAD_CONN2 (4) +#define FCOE_KWQE_OPCODE_OFFLOAD_CONN3 (5) +#define FCOE_KWQE_OPCODE_OFFLOAD_CONN4 (6) +#define FCOE_KWQE_OPCODE_ENABLE_CONN (7) +#define FCOE_KWQE_OPCODE_DISABLE_CONN (8) +#define FCOE_KWQE_OPCODE_DESTROY_CONN (9) +#define FCOE_KWQE_OPCODE_DESTROY (10) +#define FCOE_KWQE_OPCODE_STAT (11) + +#define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3) + /* KCQ (kernel completion queue) response op codes */ #define L4_KCQE_OPCODE_VALUE_CLOSE_COMP (53) #define L4_KCQE_OPCODE_VALUE_RESET_COMP (54) @@ -677,9 +711,1499 @@ struct cstorm_iscsi_ag_context { u16 __aux2_th; u16 __cq_u_prod3; #elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod3; - u16 __aux2_th; + u16 __cq_u_prod3; + u16 __aux2_th; +#endif +}; + +/* + * Parameters initialized during offloaded according to FLOGI/PLOGI/PRLI and used in FCoE context section + */ +struct ustorm_fcoe_params { +#if defined(__BIG_ENDIAN) + u16 fcoe_conn_id; + u16 flags; +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) +#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 +#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) +#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 +#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7) +#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7 +#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8) +#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8 +#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9) +#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9 +#elif defined(__LITTLE_ENDIAN) + u16 flags; +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) +#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 +#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) +#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 +#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7) +#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7 +#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8) +#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8 +#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9) +#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9 + u16 fcoe_conn_id; +#endif +#if defined(__BIG_ENDIAN) + u8 hc_csdm_byte_en; + u8 func_id; + u8 port_id; + u8 vnic_id; +#elif defined(__LITTLE_ENDIAN) + u8 vnic_id; + u8 port_id; + u8 func_id; + u8 hc_csdm_byte_en; +#endif +#if defined(__BIG_ENDIAN) + u16 rx_total_conc_seqs; + u16 rx_max_fc_pay_len; +#elif defined(__LITTLE_ENDIAN) + u16 rx_max_fc_pay_len; + u16 rx_total_conc_seqs; +#endif +#if defined(__BIG_ENDIAN) + u16 ox_id; + u16 rx_max_conc_seqs; +#elif defined(__LITTLE_ENDIAN) + u16 rx_max_conc_seqs; + u16 ox_id; +#endif +}; + +/* + * FCoE 16-bits index structure + */ +struct fcoe_idx16_fields { + u16 fields; +#define FCOE_IDX16_FIELDS_IDX (0x7FFF<<0) +#define FCOE_IDX16_FIELDS_IDX_SHIFT 0 +#define FCOE_IDX16_FIELDS_MSB (0x1<<15) +#define FCOE_IDX16_FIELDS_MSB_SHIFT 15 +}; + +/* + * FCoE 16-bits index union + */ +union fcoe_idx16_field_union { + struct fcoe_idx16_fields fields; + u16 val; +}; + +/* + * 4 regs size + */ +struct fcoe_bd_ctx { + u32 buf_addr_hi; + u32 buf_addr_lo; +#if defined(__BIG_ENDIAN) + u16 rsrv0; + u16 buf_len; +#elif defined(__LITTLE_ENDIAN) + u16 buf_len; + u16 rsrv0; +#endif +#if defined(__BIG_ENDIAN) + u16 rsrv1; + u16 flags; +#elif defined(__LITTLE_ENDIAN) + u16 flags; + u16 rsrv1; +#endif +}; + +/* + * Parameters required for placement according to SGL + */ +struct ustorm_fcoe_data_place { +#if defined(__BIG_ENDIAN) + u16 cached_sge_off; + u8 cached_num_sges; + u8 cached_sge_idx; +#elif defined(__LITTLE_ENDIAN) + u8 cached_sge_idx; + u8 cached_num_sges; + u16 cached_sge_off; +#endif + struct fcoe_bd_ctx cached_sge[3]; +}; + +struct fcoe_task_ctx_entry_txwr_rxrd { +#if defined(__BIG_ENDIAN) + u16 verify_tx_seq; + u8 init_flags; +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 + u8 tx_flags; +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 +#elif defined(__LITTLE_ENDIAN) + u8 tx_flags; +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 + u8 init_flags; +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) +#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 + u16 verify_tx_seq; +#endif +}; + +struct fcoe_fcp_cmd_payload { + u32 opaque[8]; +}; + +struct fcoe_fc_hdr { +#if defined(__BIG_ENDIAN) + u8 cs_ctl; + u8 s_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 s_id[3]; + u8 cs_ctl; +#endif +#if defined(__BIG_ENDIAN) + u8 r_ctl; + u8 d_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 d_id[3]; + u8 r_ctl; +#endif +#if defined(__BIG_ENDIAN) + u8 seq_id; + u8 df_ctl; + u16 seq_cnt; +#elif defined(__LITTLE_ENDIAN) + u16 seq_cnt; + u8 df_ctl; + u8 seq_id; +#endif +#if defined(__BIG_ENDIAN) + u8 type; + u8 f_ctl[3]; +#elif defined(__LITTLE_ENDIAN) + u8 f_ctl[3]; + u8 type; +#endif + u32 parameters; +#if defined(__BIG_ENDIAN) + u16 ox_id; + u16 rx_id; +#elif defined(__LITTLE_ENDIAN) + u16 rx_id; + u16 ox_id; +#endif +}; + +struct fcoe_fc_frame { + struct fcoe_fc_hdr fc_hdr; + u32 reserved0[2]; +}; + +union fcoe_cmd_flow_info { + struct fcoe_fcp_cmd_payload fcp_cmd_payload; + struct fcoe_fc_frame mp_fc_frame; +}; + +struct fcoe_read_flow_info { + struct fcoe_fc_hdr fc_data_in_hdr; + u32 reserved[2]; +}; + +struct fcoe_fcp_xfr_rdy_payload { + u32 burst_len; + u32 data_ro; +}; + +struct fcoe_write_flow_info { + struct fcoe_fc_hdr fc_data_out_hdr; + struct fcoe_fcp_xfr_rdy_payload fcp_xfr_payload; +}; + +struct fcoe_fcp_rsp_flags { + u8 flags; +#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID (0x1<<0) +#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID_SHIFT 0 +#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID (0x1<<1) +#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID_SHIFT 1 +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER (0x1<<2) +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER_SHIFT 2 +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER (0x1<<3) +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER_SHIFT 3 +#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ (0x1<<4) +#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ_SHIFT 4 +#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS (0x7<<5) +#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS_SHIFT 5 +}; + +struct fcoe_fcp_rsp_payload { + struct regpair reserved0; + u32 fcp_resid; +#if defined(__BIG_ENDIAN) + u16 retry_delay_timer; + struct fcoe_fcp_rsp_flags fcp_flags; + u8 scsi_status_code; +#elif defined(__LITTLE_ENDIAN) + u8 scsi_status_code; + struct fcoe_fcp_rsp_flags fcp_flags; + u16 retry_delay_timer; +#endif + u32 fcp_rsp_len; + u32 fcp_sns_len; +}; + +/* + * Fixed size structure in order to plant it in Union structure + */ +struct fcoe_fcp_rsp_union { + struct fcoe_fcp_rsp_payload payload; + struct regpair reserved0; +}; + +/* + * Fixed size structure in order to plant it in Union structure + */ +struct fcoe_abts_rsp_union { + u32 r_ctl; + u32 abts_rsp_payload[7]; +}; + +union fcoe_rsp_flow_info { + struct fcoe_fcp_rsp_union fcp_rsp; + struct fcoe_abts_rsp_union abts_rsp; +}; + +struct fcoe_cleanup_flow_info { +#if defined(__BIG_ENDIAN) + u16 reserved1; + u16 task_id; +#elif defined(__LITTLE_ENDIAN) + u16 task_id; + u16 reserved1; +#endif + u32 reserved2[7]; +}; + +/* + * 32 bytes used for general purposes + */ +union fcoe_general_task_ctx { + union fcoe_cmd_flow_info cmd_info; + struct fcoe_read_flow_info read_info; + struct fcoe_write_flow_info write_info; + union fcoe_rsp_flow_info rsp_info; + struct fcoe_cleanup_flow_info cleanup_info; + u32 comp_info[8]; +}; + +struct fcoe_s_stat_ctx { + u8 flags; +#define FCOE_S_STAT_CTX_ACTIVE (0x1<<0) +#define FCOE_S_STAT_CTX_ACTIVE_SHIFT 0 +#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND (0x1<<1) +#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND_SHIFT 1 +#define FCOE_S_STAT_CTX_ABTS_PERFORMED (0x1<<2) +#define FCOE_S_STAT_CTX_ABTS_PERFORMED_SHIFT 2 +#define FCOE_S_STAT_CTX_SEQ_TIMEOUT (0x1<<3) +#define FCOE_S_STAT_CTX_SEQ_TIMEOUT_SHIFT 3 +#define FCOE_S_STAT_CTX_P_RJT (0x1<<4) +#define FCOE_S_STAT_CTX_P_RJT_SHIFT 4 +#define FCOE_S_STAT_CTX_ACK_EOFT (0x1<<5) +#define FCOE_S_STAT_CTX_ACK_EOFT_SHIFT 5 +#define FCOE_S_STAT_CTX_RSRV1 (0x3<<6) +#define FCOE_S_STAT_CTX_RSRV1_SHIFT 6 +}; + +/* + * Common section. Both TX and RX processing might write and read from it in different flows + */ +struct fcoe_task_ctx_entry_tx_rx_cmn { + u32 data_2_trns; + union fcoe_general_task_ctx general; +#if defined(__BIG_ENDIAN) + u16 tx_low_seq_cnt; + struct fcoe_s_stat_ctx tx_s_stat; + u8 tx_seq_id; +#elif defined(__LITTLE_ENDIAN) + u8 tx_seq_id; + struct fcoe_s_stat_ctx tx_s_stat; + u16 tx_low_seq_cnt; +#endif + u32 common_flags; +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID (0xFFFFFF<<0) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID (0x1<<24) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT 24 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT (0x1<<25) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT_SHIFT 25 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER (0x1<<26) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER_SHIFT 26 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF (0x1<<27) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF_SHIFT 27 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME (0x1<<28) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT 28 +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV (0x7<<29) +#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV_SHIFT 29 +}; + +struct fcoe_task_ctx_entry_rxwr_txrd { +#if defined(__BIG_ENDIAN) + u16 rx_id; + u16 rx_flags; +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 +#elif defined(__LITTLE_ENDIAN) + u16 rx_flags; +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) +#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 + u16 rx_id; +#endif +}; + +struct fcoe_seq_ctx { +#if defined(__BIG_ENDIAN) + u16 low_seq_cnt; + struct fcoe_s_stat_ctx s_stat; + u8 seq_id; +#elif defined(__LITTLE_ENDIAN) + u8 seq_id; + struct fcoe_s_stat_ctx s_stat; + u16 low_seq_cnt; +#endif +#if defined(__BIG_ENDIAN) + u16 err_seq_cnt; + u16 high_seq_cnt; +#elif defined(__LITTLE_ENDIAN) + u16 high_seq_cnt; + u16 err_seq_cnt; +#endif + u32 low_exp_ro; + u32 high_exp_ro; +}; + +struct fcoe_single_sge_ctx { + struct regpair cur_buf_addr; +#if defined(__BIG_ENDIAN) + u16 reserved0; + u16 cur_buf_rem; +#elif defined(__LITTLE_ENDIAN) + u16 cur_buf_rem; + u16 reserved0; +#endif +}; + +struct fcoe_mul_sges_ctx { + struct regpair cur_sge_addr; +#if defined(__BIG_ENDIAN) + u8 sgl_size; + u8 cur_sge_idx; + u16 cur_sge_off; +#elif defined(__LITTLE_ENDIAN) + u16 cur_sge_off; + u8 cur_sge_idx; + u8 sgl_size; +#endif +}; + +union fcoe_sgl_ctx { + struct fcoe_single_sge_ctx single_sge; + struct fcoe_mul_sges_ctx mul_sges; +}; + +struct fcoe_task_ctx_entry_rx_only { + struct fcoe_seq_ctx seq_ctx; + struct fcoe_seq_ctx ooo_seq_ctx; + u32 rsrv3; + union fcoe_sgl_ctx sgl_ctx; +}; + +struct ustorm_fcoe_task_ctx_entry_rd { + struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; + struct fcoe_task_ctx_entry_tx_rx_cmn cmn; + struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; + struct fcoe_task_ctx_entry_rx_only rx_wr; + u32 reserved; +}; + +/* + * Ustorm FCoE Storm Context + */ +struct ustorm_fcoe_st_context { + struct ustorm_fcoe_params fcoe_params; + struct regpair task_addr; + struct regpair cq_base_addr; + struct regpair rq_pbl_base; + struct regpair rq_cur_page_addr; + struct regpair confq_pbl_base_addr; + struct regpair conn_db_base; + struct regpair xfrq_base_addr; + struct regpair lcq_base_addr; +#if defined(__BIG_ENDIAN) + union fcoe_idx16_field_union rq_cons; + union fcoe_idx16_field_union rq_prod; +#elif defined(__LITTLE_ENDIAN) + union fcoe_idx16_field_union rq_prod; + union fcoe_idx16_field_union rq_cons; +#endif +#if defined(__BIG_ENDIAN) + u16 xfrq_prod; + u16 cq_cons; +#elif defined(__LITTLE_ENDIAN) + u16 cq_cons; + u16 xfrq_prod; +#endif +#if defined(__BIG_ENDIAN) + u16 lcq_cons; + u16 hc_cram_address; +#elif defined(__LITTLE_ENDIAN) + u16 hc_cram_address; + u16 lcq_cons; +#endif +#if defined(__BIG_ENDIAN) + u16 sq_xfrq_lcq_confq_size; + u16 confq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 confq_prod; + u16 sq_xfrq_lcq_confq_size; +#endif +#if defined(__BIG_ENDIAN) + u8 hc_csdm_agg_int; + u8 flags; +#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0) +#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0 +#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1) +#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1 +#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2) +#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2 +#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3) +#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3 + u8 available_rqes; + u8 sp_q_flush_cnt; +#elif defined(__LITTLE_ENDIAN) + u8 sp_q_flush_cnt; + u8 available_rqes; + u8 flags; +#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0) +#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0 +#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1) +#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1 +#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2) +#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2 +#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3) +#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3 + u8 hc_csdm_agg_int; +#endif + struct ustorm_fcoe_data_place data_place; + struct ustorm_fcoe_task_ctx_entry_rd tce; +}; + +/* + * The FCoE non-aggregative context of Tstorm + */ +struct tstorm_fcoe_st_context { + struct regpair reserved0; + struct regpair reserved1; +}; + +/* + * The fcoe aggregative context section of Xstorm + */ +struct xstorm_fcoe_extra_ag_context_section { +#if defined(__BIG_ENDIAN) + u8 tcp_agg_vars1; +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51 (0x3<<0) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7 + u8 __reserved_da_cnt; + u16 __mtu; +#elif defined(__LITTLE_ENDIAN) + u16 __mtu; + u8 __reserved_da_cnt; + u8 tcp_agg_vars1; +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51 (0x3<<0) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7 +#endif + u32 __task_addr_lo; + u32 __task_addr_hi; + u32 __reserved55; + u32 __tx_prods; +#if defined(__BIG_ENDIAN) + u8 __agg_val8_th; + u8 __agg_val8; + u16 tcp_agg_vars2; +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57_SHIFT 0 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58 (0x1<<1) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58_SHIFT 1 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59 (0x1<<2) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59_SHIFT 2 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60 (0x1<<5) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 +#elif defined(__LITTLE_ENDIAN) + u16 tcp_agg_vars2; +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57_SHIFT 0 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58 (0x1<<1) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58_SHIFT 1 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59 (0x1<<2) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59_SHIFT 2 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60 (0x1<<5) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 + u8 __agg_val8; + u8 __agg_val8_th; +#endif + u32 __sq_base_addr_lo; + u32 __sq_base_addr_hi; + u32 __xfrq_base_addr_lo; + u32 __xfrq_base_addr_hi; +#if defined(__BIG_ENDIAN) + u16 __xfrq_cons; + u16 __xfrq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 __xfrq_prod; + u16 __xfrq_cons; +#endif +#if defined(__BIG_ENDIAN) + u8 __tcp_agg_vars5; + u8 __tcp_agg_vars4; + u8 __tcp_agg_vars3; + u8 __reserved_force_pure_ack_cnt; +#elif defined(__LITTLE_ENDIAN) + u8 __reserved_force_pure_ack_cnt; + u8 __tcp_agg_vars3; + u8 __tcp_agg_vars4; + u8 __tcp_agg_vars5; +#endif + u32 __tcp_agg_vars6; +#if defined(__BIG_ENDIAN) + u16 __agg_misc6; + u16 __tcp_agg_vars7; +#elif defined(__LITTLE_ENDIAN) + u16 __tcp_agg_vars7; + u16 __agg_misc6; +#endif + u32 __agg_val10; + u32 __agg_val10_th; +#if defined(__BIG_ENDIAN) + u16 __reserved3; + u8 __reserved2; + u8 __da_only_cnt; +#elif defined(__LITTLE_ENDIAN) + u8 __da_only_cnt; + u8 __reserved2; + u16 __reserved3; +#endif +}; + +/* + * The fcoe aggregative context of Xstorm + */ +struct xstorm_fcoe_ag_context { +#if defined(__BIG_ENDIAN) + u16 agg_val1; + u8 agg_vars1; +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51 (0x1<<2) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51_SHIFT 2 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52 (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN_SHIFT 7 + u8 __state; +#elif defined(__LITTLE_ENDIAN) + u8 __state; + u8 agg_vars1; +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51 (0x1<<2) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51_SHIFT 2 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52 (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN_SHIFT 7 + u16 agg_val1; +#endif +#if defined(__BIG_ENDIAN) + u8 cdu_reserved; + u8 __agg_vars4; + u8 agg_vars3; +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF (0x3<<6) +#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF_SHIFT 6 + u8 agg_vars2; +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF (0x3<<0) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 +#elif defined(__LITTLE_ENDIAN) + u8 agg_vars2; +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF (0x3<<0) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u8 agg_vars3; +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF (0x3<<6) +#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF_SHIFT 6 + u8 __agg_vars4; + u8 cdu_reserved; +#endif + u32 more_to_send; +#if defined(__BIG_ENDIAN) + u16 agg_vars5; +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE (0x3<<14) +#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE_SHIFT 14 + u16 sq_cons; +#elif defined(__LITTLE_ENDIAN) + u16 sq_cons; + u16 agg_vars5; +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE (0x3<<14) +#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE_SHIFT 14 +#endif + struct xstorm_fcoe_extra_ag_context_section __extra_section; +#if defined(__BIG_ENDIAN) + u16 agg_vars7; +#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF (0x3<<4) +#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62 (0x1<<10) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62_SHIFT 10 +#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG (0x1<<15) +#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG_SHIFT 15 + u8 agg_val3_th; + u8 agg_vars6; +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE (0x7<<3) +#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE (0x3<<6) +#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE_SHIFT 6 +#elif defined(__LITTLE_ENDIAN) + u8 agg_vars6; +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE (0x7<<3) +#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE (0x3<<6) +#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE_SHIFT 6 + u8 agg_val3_th; + u16 agg_vars7; +#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF (0x3<<4) +#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF_SHIFT 4 +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62 (0x1<<10) +#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62_SHIFT 10 +#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG (0x1<<15) +#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#endif +#if defined(__BIG_ENDIAN) + u16 __agg_val11_th; + u16 __agg_val11; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_val11; + u16 __agg_val11_th; +#endif +#if defined(__BIG_ENDIAN) + u8 __reserved1; + u8 __agg_val6_th; + u16 __confq_tx_prod; +#elif defined(__LITTLE_ENDIAN) + u16 __confq_tx_prod; + u8 __agg_val6_th; + u8 __reserved1; +#endif +#if defined(__BIG_ENDIAN) + u16 confq_cons; + u16 confq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 confq_prod; + u16 confq_cons; +#endif + u32 agg_vars8; +#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX (0xFFFFFF<<0) +#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX_SHIFT 0 +#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3 (0xFF<<24) +#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3_SHIFT 24 +#if defined(__BIG_ENDIAN) + u16 ox_id; + u16 sq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 sq_prod; + u16 ox_id; +#endif +#if defined(__BIG_ENDIAN) + u8 agg_val3; + u8 agg_val6; + u8 agg_val5_th; + u8 agg_val5; +#elif defined(__LITTLE_ENDIAN) + u8 agg_val5; + u8 agg_val5_th; + u8 agg_val6; + u8 agg_val3; +#endif +#if defined(__BIG_ENDIAN) + u16 __pbf_tx_seq_ack; + u16 agg_limit1; +#elif defined(__LITTLE_ENDIAN) + u16 agg_limit1; + u16 __pbf_tx_seq_ack; +#endif + u32 completion_seq; + u32 confq_pbl_base_lo; + u32 confq_pbl_base_hi; +}; + +/* + * The fcoe extra aggregative context section of Tstorm + */ +struct tstorm_fcoe_extra_ag_context_section { + u32 __agg_val1; +#if defined(__BIG_ENDIAN) + u8 __tcp_agg_vars2; + u8 __agg_val3; + u16 __agg_val2; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_val2; + u8 __agg_val3; + u8 __tcp_agg_vars2; +#endif +#if defined(__BIG_ENDIAN) + u16 __agg_val5; + u8 __agg_val6; + u8 __tcp_agg_vars3; +#elif defined(__LITTLE_ENDIAN) + u8 __tcp_agg_vars3; + u8 __agg_val6; + u16 __agg_val5; +#endif + u32 __lcq_prod; + u32 rtt_seq; + u32 rtt_time; + u32 __reserved66; + u32 wnd_right_edge; + u32 tcp_agg_vars1; +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN (0x1<<9) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN_SHIFT 9 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28 + u32 snd_max; + u32 __lcq_cons; + u32 __reserved2; +}; + +/* + * The fcoe aggregative context of Tstorm + */ +struct tstorm_fcoe_ag_context { +#if defined(__BIG_ENDIAN) + u16 ulp_credit; + u8 agg_vars1; +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 + u8 state; +#elif defined(__LITTLE_ENDIAN) + u8 state; + u8 agg_vars1; +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 + u16 ulp_credit; +#endif +#if defined(__BIG_ENDIAN) + u16 __agg_val4; + u16 agg_vars2; +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 +#elif defined(__LITTLE_ENDIAN) + u16 agg_vars2; +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 + u16 __agg_val4; +#endif + struct tstorm_fcoe_extra_ag_context_section __extra_section; +}; + +/* + * The fcoe aggregative context of Ustorm + */ +struct ustorm_fcoe_ag_context { +#if defined(__BIG_ENDIAN) + u8 __aux_counter_flags; + u8 agg_vars2; +#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 agg_vars1; +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 state; +#elif defined(__LITTLE_ENDIAN) + u8 state; + u8 agg_vars1; +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 agg_vars2; +#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 __aux_counter_flags; +#endif +#if defined(__BIG_ENDIAN) + u8 cdu_usage; + u8 agg_misc2; + u16 pbf_tx_seq_ack; +#elif defined(__LITTLE_ENDIAN) + u16 pbf_tx_seq_ack; + u8 agg_misc2; + u8 cdu_usage; +#endif + u32 agg_misc4; +#if defined(__BIG_ENDIAN) + u8 agg_val3_th; + u8 agg_val3; + u16 agg_misc3; +#elif defined(__LITTLE_ENDIAN) + u16 agg_misc3; + u8 agg_val3; + u8 agg_val3_th; +#endif + u32 expired_task_id; + u32 agg_misc4_th; +#if defined(__BIG_ENDIAN) + u16 cq_prod; + u16 cq_cons; +#elif defined(__LITTLE_ENDIAN) + u16 cq_cons; + u16 cq_prod; +#endif +#if defined(__BIG_ENDIAN) + u16 __reserved2; + u8 decision_rules; +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 + u8 decision_rule_enable_bits; +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 +#elif defined(__LITTLE_ENDIAN) + u8 decision_rule_enable_bits; +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u8 decision_rules; +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 + u16 __reserved2; +#endif +}; + +/* + * Ethernet context section + */ +struct xstorm_fcoe_eth_context_section { +#if defined(__BIG_ENDIAN) + u8 remote_addr_4; + u8 remote_addr_5; + u8 local_addr_0; + u8 local_addr_1; +#elif defined(__LITTLE_ENDIAN) + u8 local_addr_1; + u8 local_addr_0; + u8 remote_addr_5; + u8 remote_addr_4; +#endif +#if defined(__BIG_ENDIAN) + u8 remote_addr_0; + u8 remote_addr_1; + u8 remote_addr_2; + u8 remote_addr_3; +#elif defined(__LITTLE_ENDIAN) + u8 remote_addr_3; + u8 remote_addr_2; + u8 remote_addr_1; + u8 remote_addr_0; +#endif +#if defined(__BIG_ENDIAN) + u16 reserved_vlan_type; + u16 params; +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 +#elif defined(__LITTLE_ENDIAN) + u16 params; +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 + u16 reserved_vlan_type; +#endif +#if defined(__BIG_ENDIAN) + u8 local_addr_2; + u8 local_addr_3; + u8 local_addr_4; + u8 local_addr_5; +#elif defined(__LITTLE_ENDIAN) + u8 local_addr_5; + u8 local_addr_4; + u8 local_addr_3; + u8 local_addr_2; +#endif +}; + +/* + * Flags used in FCoE context section - 1 byte + */ +struct xstorm_fcoe_context_flags { + u8 flags; +#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q (0x3<<0) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q_SHIFT 0 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ (0x1<<2) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ_SHIFT 2 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED (0x1<<3) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED_SHIFT 3 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT (0x1<<4) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT_SHIFT 4 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE (0x1<<5) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE_SHIFT 5 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE (0x1<<6) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE_SHIFT 6 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED (0x1<<7) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED_SHIFT 7 +}; + +/* + * FCoE SQ element + */ +struct fcoe_sqe { + u16 wqe; +#define FCOE_SQE_TASK_ID (0x7FFF<<0) +#define FCOE_SQE_TASK_ID_SHIFT 0 +#define FCOE_SQE_TOGGLE_BIT (0x1<<15) +#define FCOE_SQE_TOGGLE_BIT_SHIFT 15 +}; + +/* + * FCoE XFRQ element + */ +struct fcoe_xfrqe { + u16 wqe; +#define FCOE_XFRQE_TASK_ID (0x7FFF<<0) +#define FCOE_XFRQE_TASK_ID_SHIFT 0 +#define FCOE_XFRQE_TOGGLE_BIT (0x1<<15) +#define FCOE_XFRQE_TOGGLE_BIT_SHIFT 15 +}; + +/* + * FCoE SQ\XFRQ element + */ +struct fcoe_cached_wqe { +#if defined(__BIG_ENDIAN) + struct fcoe_xfrqe xfrqe; + struct fcoe_sqe sqe; +#elif defined(__LITTLE_ENDIAN) + struct fcoe_sqe sqe; + struct fcoe_xfrqe xfrqe; +#endif +}; + +struct fcoe_task_ctx_entry_tx_only { + union fcoe_sgl_ctx sgl_ctx; +}; + +struct xstorm_fcoe_task_ctx_entry_rd { + struct fcoe_task_ctx_entry_tx_only tx_wr; + struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; + struct fcoe_task_ctx_entry_tx_rx_cmn cmn; + struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; +}; + +/* + * Cached SGEs + */ +struct common_fcoe_sgl { + struct fcoe_bd_ctx sge[2]; +}; + +/* + * FCP_DATA parameters required for transmission + */ +struct xstorm_fcoe_fcp_data { + u32 io_rem; +#if defined(__BIG_ENDIAN) + u16 cached_sge_off; + u8 cached_num_sges; + u8 cached_sge_idx; +#elif defined(__LITTLE_ENDIAN) + u8 cached_sge_idx; + u8 cached_num_sges; + u16 cached_sge_off; +#endif + struct common_fcoe_sgl cached_sgl; +}; + +/* + * FCoE context section + */ +struct xstorm_fcoe_context_section { +#if defined(__BIG_ENDIAN) + u8 vlan_flag; + u8 s_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 s_id[3]; + u8 vlan_flag; +#endif +#if defined(__BIG_ENDIAN) + u8 func_id; + u8 d_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 d_id[3]; + u8 func_id; +#endif +#if defined(__BIG_ENDIAN) + u16 sq_xfrq_lcq_confq_size; + u16 tx_max_fc_pay_len; +#elif defined(__LITTLE_ENDIAN) + u16 tx_max_fc_pay_len; + u16 sq_xfrq_lcq_confq_size; +#endif + u32 lcq_prod; +#if defined(__BIG_ENDIAN) + u8 port_id; + u8 tx_max_conc_seqs_c3; + u8 seq_id; + struct xstorm_fcoe_context_flags tx_flags; +#elif defined(__LITTLE_ENDIAN) + struct xstorm_fcoe_context_flags tx_flags; + u8 seq_id; + u8 tx_max_conc_seqs_c3; + u8 port_id; +#endif +#if defined(__BIG_ENDIAN) + u16 verify_tx_seq; + u8 func_mode; + u8 vnic_id; +#elif defined(__LITTLE_ENDIAN) + u8 vnic_id; + u8 func_mode; + u16 verify_tx_seq; +#endif + struct regpair confq_curr_page_addr; + struct fcoe_cached_wqe cached_wqe[8]; + struct regpair lcq_base_addr; + struct xstorm_fcoe_task_ctx_entry_rd tce; + struct xstorm_fcoe_fcp_data fcp_data; +#if defined(__BIG_ENDIAN) + u16 fcoe_tx_stat_params_ram_addr; + u16 cmng_port_ram_addr; +#elif defined(__LITTLE_ENDIAN) + u16 cmng_port_ram_addr; + u16 fcoe_tx_stat_params_ram_addr; +#endif +#if defined(__BIG_ENDIAN) + u8 fcp_cmd_pb_cmd_size; + u8 eth_hdr_size; + u16 pbf_addr; +#elif defined(__LITTLE_ENDIAN) + u16 pbf_addr; + u8 eth_hdr_size; + u8 fcp_cmd_pb_cmd_size; +#endif +#if defined(__BIG_ENDIAN) + u8 reserved2[2]; + u8 cos; + u8 dcb_version; +#elif defined(__LITTLE_ENDIAN) + u8 dcb_version; + u8 cos; + u8 reserved2[2]; #endif + u32 reserved3; + struct regpair reserved4[2]; +}; + +/* + * Xstorm FCoE Storm Context + */ +struct xstorm_fcoe_st_context { + struct xstorm_fcoe_eth_context_section eth; + struct xstorm_fcoe_context_section fcoe; +}; + +/* + * Fcoe connection context + */ +struct fcoe_context { + struct ustorm_fcoe_st_context ustorm_st_context; + struct tstorm_fcoe_st_context tstorm_st_context; + struct xstorm_fcoe_ag_context xstorm_ag_context; + struct tstorm_fcoe_ag_context tstorm_ag_context; + struct ustorm_fcoe_ag_context ustorm_ag_context; + struct timers_block_context timers_context; + struct xstorm_fcoe_st_context xstorm_st_context; }; /* @@ -2267,6 +3791,577 @@ struct iscsi_context { struct cstorm_iscsi_st_context cstorm_st_context; }; +/* + * FCoE KCQ CQE parameters + */ +union fcoe_kcqe_params { + u32 reserved0[4]; +}; + +/* + * FCoE KCQ CQE + */ +struct fcoe_kcqe { + u32 fcoe_conn_id; + u32 completion_status; + u32 fcoe_conn_context_id; + union fcoe_kcqe_params params; +#if defined(__BIG_ENDIAN) + u8 flags; +#define FCOE_KCQE_RESERVED0 (0x7<<0) +#define FCOE_KCQE_RESERVED0_SHIFT 0 +#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) +#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 +#define FCOE_KCQE_LAYER_CODE (0x7<<4) +#define FCOE_KCQE_LAYER_CODE_SHIFT 4 +#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) +#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 + u8 op_code; + u16 qe_self_seq; +#elif defined(__LITTLE_ENDIAN) + u16 qe_self_seq; + u8 op_code; + u8 flags; +#define FCOE_KCQE_RESERVED0 (0x7<<0) +#define FCOE_KCQE_RESERVED0_SHIFT 0 +#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) +#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 +#define FCOE_KCQE_LAYER_CODE (0x7<<4) +#define FCOE_KCQE_LAYER_CODE_SHIFT 4 +#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) +#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 +#endif +}; + +/* + * FCoE KWQE header + */ +struct fcoe_kwqe_header { +#if defined(__BIG_ENDIAN) + u8 flags; +#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) +#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 +#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) +#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 +#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) +#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 + u8 op_code; +#elif defined(__LITTLE_ENDIAN) + u8 op_code; + u8 flags; +#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) +#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 +#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) +#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 +#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) +#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 +#endif +}; + +/* + * FCoE firmware init request 1 + */ +struct fcoe_kwqe_init1 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 num_tasks; +#elif defined(__LITTLE_ENDIAN) + u16 num_tasks; + struct fcoe_kwqe_header hdr; +#endif + u32 task_list_pbl_addr_lo; + u32 task_list_pbl_addr_hi; + u32 dummy_buffer_addr_lo; + u32 dummy_buffer_addr_hi; +#if defined(__BIG_ENDIAN) + u16 rq_num_wqes; + u16 sq_num_wqes; +#elif defined(__LITTLE_ENDIAN) + u16 sq_num_wqes; + u16 rq_num_wqes; +#endif +#if defined(__BIG_ENDIAN) + u16 cq_num_wqes; + u16 rq_buffer_log_size; +#elif defined(__LITTLE_ENDIAN) + u16 rq_buffer_log_size; + u16 cq_num_wqes; +#endif +#if defined(__BIG_ENDIAN) + u8 flags; +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 +#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) +#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 + u8 num_sessions_log; + u16 mtu; +#elif defined(__LITTLE_ENDIAN) + u16 mtu; + u8 num_sessions_log; + u8 flags; +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 +#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) +#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 +#endif +}; + +/* + * FCoE firmware init request 2 + */ +struct fcoe_kwqe_init2 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u32 hash_tbl_pbl_addr_lo; + u32 hash_tbl_pbl_addr_hi; + u32 t2_hash_tbl_addr_lo; + u32 t2_hash_tbl_addr_hi; + u32 t2_ptr_hash_tbl_addr_lo; + u32 t2_ptr_hash_tbl_addr_hi; + u32 free_list_count; +}; + +/* + * FCoE firmware init request 3 + */ +struct fcoe_kwqe_init3 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u32 error_bit_map_lo; + u32 error_bit_map_hi; +#if defined(__BIG_ENDIAN) + u8 reserved21[3]; + u8 cached_session_enable; +#elif defined(__LITTLE_ENDIAN) + u8 cached_session_enable; + u8 reserved21[3]; +#endif + u32 reserved2[4]; +}; + +/* + * FCoE connection offload request 1 + */ +struct fcoe_kwqe_conn_offload1 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 fcoe_conn_id; +#elif defined(__LITTLE_ENDIAN) + u16 fcoe_conn_id; + struct fcoe_kwqe_header hdr; +#endif + u32 sq_addr_lo; + u32 sq_addr_hi; + u32 rq_pbl_addr_lo; + u32 rq_pbl_addr_hi; + u32 rq_first_pbe_addr_lo; + u32 rq_first_pbe_addr_hi; +#if defined(__BIG_ENDIAN) + u16 reserved0; + u16 rq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 rq_prod; + u16 reserved0; +#endif +}; + +/* + * FCoE connection offload request 2 + */ +struct fcoe_kwqe_conn_offload2 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 tx_max_fc_pay_len; +#elif defined(__LITTLE_ENDIAN) + u16 tx_max_fc_pay_len; + struct fcoe_kwqe_header hdr; +#endif + u32 cq_addr_lo; + u32 cq_addr_hi; + u32 xferq_addr_lo; + u32 xferq_addr_hi; + u32 conn_db_addr_lo; + u32 conn_db_addr_hi; + u32 reserved1; +}; + +/* + * FCoE connection offload request 3 + */ +struct fcoe_kwqe_conn_offload3 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 vlan_tag; +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) +#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 +#elif defined(__LITTLE_ENDIAN) + u16 vlan_tag; +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) +#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 + struct fcoe_kwqe_header hdr; +#endif +#if defined(__BIG_ENDIAN) + u8 tx_max_conc_seqs_c3; + u8 s_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 s_id[3]; + u8 tx_max_conc_seqs_c3; +#endif +#if defined(__BIG_ENDIAN) + u8 flags; +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 + u8 d_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 d_id[3]; + u8 flags; +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 +#endif + u32 reserved; + u32 confq_first_pbe_addr_lo; + u32 confq_first_pbe_addr_hi; +#if defined(__BIG_ENDIAN) + u16 rx_max_fc_pay_len; + u16 tx_total_conc_seqs; +#elif defined(__LITTLE_ENDIAN) + u16 tx_total_conc_seqs; + u16 rx_max_fc_pay_len; +#endif +#if defined(__BIG_ENDIAN) + u8 rx_open_seqs_exch_c3; + u8 rx_max_conc_seqs_c3; + u16 rx_total_conc_seqs; +#elif defined(__LITTLE_ENDIAN) + u16 rx_total_conc_seqs; + u8 rx_max_conc_seqs_c3; + u8 rx_open_seqs_exch_c3; +#endif +}; + +/* + * FCoE connection offload request 4 + */ +struct fcoe_kwqe_conn_offload4 { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u8 reserved2; + u8 e_d_tov_timer_val; +#elif defined(__LITTLE_ENDIAN) + u8 e_d_tov_timer_val; + u8 reserved2; + struct fcoe_kwqe_header hdr; +#endif + u8 src_mac_addr_lo32[4]; +#if defined(__BIG_ENDIAN) + u8 dst_mac_addr_hi16[2]; + u8 src_mac_addr_hi16[2]; +#elif defined(__LITTLE_ENDIAN) + u8 src_mac_addr_hi16[2]; + u8 dst_mac_addr_hi16[2]; +#endif + u8 dst_mac_addr_lo32[4]; + u32 lcq_addr_lo; + u32 lcq_addr_hi; + u32 confq_pbl_base_addr_lo; + u32 confq_pbl_base_addr_hi; +}; + +/* + * FCoE connection enable request + */ +struct fcoe_kwqe_conn_enable_disable { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u8 src_mac_addr_lo32[4]; +#if defined(__BIG_ENDIAN) + u16 vlan_tag; +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 + u8 src_mac_addr_hi16[2]; +#elif defined(__LITTLE_ENDIAN) + u8 src_mac_addr_hi16[2]; + u16 vlan_tag; +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 +#endif + u8 dst_mac_addr_lo32[4]; +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 dst_mac_addr_hi16[2]; +#elif defined(__LITTLE_ENDIAN) + u8 dst_mac_addr_hi16[2]; + u16 reserved1; +#endif +#if defined(__BIG_ENDIAN) + u8 vlan_flag; + u8 s_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 s_id[3]; + u8 vlan_flag; +#endif +#if defined(__BIG_ENDIAN) + u8 reserved3; + u8 d_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 d_id[3]; + u8 reserved3; +#endif + u32 context_id; + u32 conn_id; + u32 reserved4; +}; + +/* + * FCoE connection destroy request + */ +struct fcoe_kwqe_conn_destroy { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u32 context_id; + u32 conn_id; + u32 reserved1[5]; +}; + +/* + * FCoe destroy request + */ +struct fcoe_kwqe_destroy { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u32 reserved1[7]; +}; + +/* + * FCoe statistics request + */ +struct fcoe_kwqe_stat { +#if defined(__BIG_ENDIAN) + struct fcoe_kwqe_header hdr; + u16 reserved0; +#elif defined(__LITTLE_ENDIAN) + u16 reserved0; + struct fcoe_kwqe_header hdr; +#endif + u32 stat_params_addr_lo; + u32 stat_params_addr_hi; + u32 reserved1[5]; +}; + +/* + * FCoE KWQ WQE + */ +union fcoe_kwqe { + struct fcoe_kwqe_init1 init1; + struct fcoe_kwqe_init2 init2; + struct fcoe_kwqe_init3 init3; + struct fcoe_kwqe_conn_offload1 conn_offload1; + struct fcoe_kwqe_conn_offload2 conn_offload2; + struct fcoe_kwqe_conn_offload3 conn_offload3; + struct fcoe_kwqe_conn_offload4 conn_offload4; + struct fcoe_kwqe_conn_enable_disable conn_enable_disable; + struct fcoe_kwqe_conn_destroy conn_destroy; + struct fcoe_kwqe_destroy destroy; + struct fcoe_kwqe_stat statistics; +}; + +struct fcoe_task_ctx_entry { + struct fcoe_task_ctx_entry_tx_only tx_wr_only; + struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; + struct fcoe_task_ctx_entry_tx_rx_cmn cmn; + struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; + struct fcoe_task_ctx_entry_rx_only rx_wr_only; + u32 reserved[4]; +}; + +/* + * FCoE connection enable\disable params passed by driver to FW in FCoE enable ramrod + */ +struct fcoe_conn_enable_disable_ramrod_params { + struct fcoe_kwqe_conn_enable_disable enable_disable_kwqe; +}; + + +/* + * FCoE connection offload params passed by driver to FW in FCoE offload ramrod + */ +struct fcoe_conn_offload_ramrod_params { + struct fcoe_kwqe_conn_offload1 offload_kwqe1; + struct fcoe_kwqe_conn_offload2 offload_kwqe2; + struct fcoe_kwqe_conn_offload3 offload_kwqe3; + struct fcoe_kwqe_conn_offload4 offload_kwqe4; +}; + +/* + * FCoE init params passed by driver to FW in FCoE init ramrod + */ +struct fcoe_init_ramrod_params { + struct fcoe_kwqe_init1 init_kwqe1; + struct fcoe_kwqe_init2 init_kwqe2; + struct fcoe_kwqe_init3 init_kwqe3; + struct regpair eq_addr; + struct regpair eq_next_page_addr; +#if defined(__BIG_ENDIAN) + u16 sb_num; + u16 eq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 eq_prod; + u16 sb_num; +#endif +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 reserved0; + u8 sb_id; +#elif defined(__LITTLE_ENDIAN) + u8 sb_id; + u8 reserved0; + u16 reserved1; +#endif +}; + + +/* + * FCoE statistics params buffer passed by driver to FW in FCoE statistics ramrod + */ +struct fcoe_stat_ramrod_params { + struct fcoe_kwqe_stat stat_kwqe; +}; + + +/* + * FCoE 16-bits vlan structure + */ +struct fcoe_vlan_fields { + u16 fields; +#define FCOE_VLAN_FIELDS_VID (0xFFF<<0) +#define FCOE_VLAN_FIELDS_VID_SHIFT 0 +#define FCOE_VLAN_FIELDS_CLI (0x1<<12) +#define FCOE_VLAN_FIELDS_CLI_SHIFT 12 +#define FCOE_VLAN_FIELDS_PRI (0x7<<13) +#define FCOE_VLAN_FIELDS_PRI_SHIFT 13 +}; + + +/* + * FCoE 16-bits vlan union + */ +union fcoe_vlan_field_union { + struct fcoe_vlan_fields fields; + u16 val; +}; + +/* + * Parameters used for Class 2 verifications + */ +struct ustorm_fcoe_c2_params { +#if defined(__BIG_ENDIAN) + u16 e2e_credit; + u16 con_seq; +#elif defined(__LITTLE_ENDIAN) + u16 con_seq; + u16 e2e_credit; +#endif +#if defined(__BIG_ENDIAN) + u16 ackq_prod; + u16 open_seq_per_exch; +#elif defined(__LITTLE_ENDIAN) + u16 open_seq_per_exch; + u16 ackq_prod; +#endif + struct regpair ackq_pbl_base; + struct regpair ackq_cur_seg; +}; + +/* + * Parameters used for Class 2 verifications + */ +struct xstorm_fcoe_c2_params { +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 ackq_x_prod; + u8 max_conc_seqs_c2; +#elif defined(__LITTLE_ENDIAN) + u8 max_conc_seqs_c2; + u8 ackq_x_prod; + u16 reserved0; +#endif + struct regpair ackq_pbl_base; + struct regpair ackq_cur_seg; +}; + /* * Buffer per connection, used in Tstorm */ diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 33333e735f95..ccd814068c4d 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,22 +12,31 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.6" -#define CNIC_MODULE_RELDATE "Oct 12, 2010" +#define CNIC_MODULE_VERSION "2.2.11" +#define CNIC_MODULE_RELDATE "Dec 22, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -#define CNIC_ULP_L4 2 -#define MAX_CNIC_ULP_TYPE_EXT 2 -#define MAX_CNIC_ULP_TYPE 3 +#define CNIC_ULP_FCOE 2 +#define CNIC_ULP_L4 3 +#define MAX_CNIC_ULP_TYPE_EXT 3 +#define MAX_CNIC_ULP_TYPE 4 struct kwqe { u32 kwqe_op_flag; +#define KWQE_QID_SHIFT 8 #define KWQE_OPCODE_MASK 0x00ff0000 #define KWQE_OPCODE_SHIFT 16 -#define KWQE_FLAGS_LAYER_SHIFT 28 #define KWQE_OPCODE(x) ((x & KWQE_OPCODE_MASK) >> KWQE_OPCODE_SHIFT) +#define KWQE_LAYER_MASK 0x70000000 +#define KWQE_LAYER_SHIFT 28 +#define KWQE_FLAGS_LAYER_MASK_L2 (2<<28) +#define KWQE_FLAGS_LAYER_MASK_L3 (3<<28) +#define KWQE_FLAGS_LAYER_MASK_L4 (4<<28) +#define KWQE_FLAGS_LAYER_MASK_L5_RDMA (5<<28) +#define KWQE_FLAGS_LAYER_MASK_L5_ISCSI (6<<28) +#define KWQE_FLAGS_LAYER_MASK_L5_FCOE (7<<28) u32 kwqe_info0; u32 kwqe_info1; @@ -62,6 +71,7 @@ struct kcqe { #define KCQE_FLAGS_LAYER_MASK_L4 (4<<28) #define KCQE_FLAGS_LAYER_MASK_L5_RDMA (5<<28) #define KCQE_FLAGS_LAYER_MASK_L5_ISCSI (6<<28) + #define KCQE_FLAGS_LAYER_MASK_L5_FCOE (7<<28) #define KCQE_FLAGS_NEXT (1<<31) #define KCQE_FLAGS_OPCODE_MASK (0xff<<16) #define KCQE_FLAGS_OPCODE_SHIFT (16) -- cgit v1.2.3-59-g8ed1b From 68f20d948c86bd6bbc075052f6b6c45b8f56957e Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 17 Dec 2010 12:14:34 +0000 Subject: Documentation/networking: Update Intel Wired LAN docs - Update the Intel Wired LAN documentation with the latest URL for ethtool. - replace "Ethtool" with "ethtool" Signed-off-by: Jeff Kirsher Tested-by: Emil Tantilov --- Documentation/networking/e100.txt | 19 +++++-------------- Documentation/networking/e1000.txt | 6 +++--- Documentation/networking/e1000e.txt | 14 +++++++------- Documentation/networking/igb.txt | 6 +++--- Documentation/networking/igbvf.txt | 4 ++-- Documentation/networking/ixgb.txt | 10 +++++----- Documentation/networking/ixgbe.txt | 8 ++++---- 7 files changed, 29 insertions(+), 38 deletions(-) diff --git a/Documentation/networking/e100.txt b/Documentation/networking/e100.txt index 944aa55e79f8..162f323a7a1f 100644 --- a/Documentation/networking/e100.txt +++ b/Documentation/networking/e100.txt @@ -72,7 +72,7 @@ Tx Descriptors: Number of transmit descriptors. A transmit descriptor is a data ethtool -G eth? tx n, where n is the number of desired tx descriptors. Speed/Duplex: The driver auto-negotiates the link speed and duplex settings by - default. Ethtool can be used as follows to force speed/duplex. + default. The ethtool utility can be used as follows to force speed/duplex. ethtool -s eth? autoneg off speed {10|100} duplex {full|half} @@ -126,30 +126,21 @@ Additional Configurations ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. Ethtool + diagnostics, as well as displaying statistical information. The ethtool version 1.6 or later is required for this functionality. The latest release of ethtool can be found from - http://sourceforge.net/projects/gkernel. - - NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support - for a more complete ethtool feature set can be enabled by upgrading - ethtool to ethtool-1.8.1. - + http://ftp.kernel.org/pub/software/network/ethtool/ Enabling Wake on LAN* (WoL) --------------------------- - WoL is provided through the Ethtool* utility. Ethtool is included with Red - Hat* 8.0. For other Linux distributions, download and install Ethtool from - the following website: http://sourceforge.net/projects/gkernel. - - For instructions on enabling WoL with Ethtool, refer to the Ethtool man page. + WoL is provided through the ethtool* utility. For instructions on enabling + WoL with ethtool, refer to the ethtool man page. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e100 driver must be loaded when shutting down or rebooting the system. - NAPI ---- diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt index 6cb13e9e1346..71ca95855671 100644 --- a/Documentation/networking/e1000.txt +++ b/Documentation/networking/e1000.txt @@ -431,15 +431,15 @@ Additional Configurations Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. Ethtool + diagnostics, as well as displaying statistical information. The ethtool version 1.6 or later is required for this functionality. The latest release of ethtool can be found from - http://sourceforge.net/projects/gkernel. + http://ftp.kernel.org/pub/software/network/ethtool/ Enabling Wake on LAN* (WoL) --------------------------- - WoL is configured through the Ethtool* utility. + WoL is configured through the ethtool* utility. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e1000 driver must be diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt index 81a66e69a127..97b5ba942ebf 100644 --- a/Documentation/networking/e1000e.txt +++ b/Documentation/networking/e1000e.txt @@ -269,26 +269,26 @@ Additional Configurations ------- The driver utilizes the ethtool interface for driver configuration and diagnostics, as well as displaying statistical information. We - strongly recommend downloading the latest version of Ethtool at: + strongly recommend downloading the latest version of ethtool at: - http://sourceforge.net/projects/gkernel. + http://ftp.kernel.org/pub/software/network/ethtool/ Speed and Duplex ---------------- - Speed and Duplex are configured through the Ethtool* utility. For - instructions, refer to the Ethtool man page. + Speed and Duplex are configured through the ethtool* utility. For + instructions, refer to the ethtool man page. Enabling Wake on LAN* (WoL) --------------------------- - WoL is configured through the Ethtool* utility. For instructions on - enabling WoL with Ethtool, refer to the Ethtool man page. + WoL is configured through the ethtool* utility. For instructions on + enabling WoL with ethtool, refer to the ethtool man page. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e1000e driver must be loaded when shutting down or rebooting the system. In most cases Wake On LAN is only supported on port A for multiple port - adapters. To verify if a port supports Wake on Lan run Ethtool eth. + adapters. To verify if a port supports Wake on Lan run ethtool eth. Support ======= diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt index 4a5e29c19bd1..98953c0d5342 100644 --- a/Documentation/networking/igb.txt +++ b/Documentation/networking/igb.txt @@ -62,15 +62,15 @@ Additional Configurations ------- The driver utilizes the ethtool interface for driver configuration and diagnostics, as well as displaying statistical information. The latest - version of Ethtool can be found at: + version of ethtool can be found at: http://ftp.kernel.org/pub/software/network/ethtool/ Enabling Wake on LAN* (WoL) --------------------------- - WoL is configured through the Ethtool* utility. + WoL is configured through the ethtool* utility. - For instructions on enabling WoL with Ethtool, refer to the Ethtool man page. + For instructions on enabling WoL with ethtool, refer to the ethtool man page. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the igb driver must be diff --git a/Documentation/networking/igbvf.txt b/Documentation/networking/igbvf.txt index 694817b17a9c..cbfe4ee65533 100644 --- a/Documentation/networking/igbvf.txt +++ b/Documentation/networking/igbvf.txt @@ -58,11 +58,11 @@ Additional Configurations Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. Ethtool + diagnostics, as well as displaying statistical information. The ethtool version 3.0 or later is required for this functionality, although we strongly recommend downloading the latest version at: - http://sourceforge.net/projects/gkernel. + http://ftp.kernel.org/pub/software/network/ethtool/ Support ======= diff --git a/Documentation/networking/ixgb.txt b/Documentation/networking/ixgb.txt index a0d0ffb5e584..e196f16df313 100644 --- a/Documentation/networking/ixgb.txt +++ b/Documentation/networking/ixgb.txt @@ -309,15 +309,15 @@ Additional Configurations Ethtool ------- The driver utilizes the ethtool interface for driver configuration and - diagnostics, as well as displaying statistical information. Ethtool + diagnostics, as well as displaying statistical information. The ethtool version 1.6 or later is required for this functionality. The latest release of ethtool can be found from - http://sourceforge.net/projects/gkernel + http://ftp.kernel.org/pub/software/network/ethtool/ - NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support - for a more complete ethtool feature set can be enabled by upgrading - to the latest version. + NOTE: The ethtool version 1.6 only supports a limited set of ethtool options. + Support for a more complete ethtool feature set can be enabled by + upgrading to the latest version. NAPI diff --git a/Documentation/networking/ixgbe.txt b/Documentation/networking/ixgbe.txt index 9ade2806d82c..af77ed3c4172 100644 --- a/Documentation/networking/ixgbe.txt +++ b/Documentation/networking/ixgbe.txt @@ -34,7 +34,7 @@ is an Intel(R) Ethernet Server Adapter X520-2, then it only supports Intel optics and/or the direct attach cables listed below. When 82599-based SFP+ devices are connected back to back, they should be set to -the same Speed setting via Ethtool. Results may vary if you mix speed settings. +the same Speed setting via ethtool. Results may vary if you mix speed settings. 82598-based adapters support all passive direct attach cables that comply with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach cables are not supported. @@ -110,7 +110,7 @@ threshold. When rx is enabled, the transmit unit will halt for the time delay specified when a PAUSE frame is received. Flow Control is enabled by default. If you want to disable a flow control -capable link partner, use Ethtool: +capable link partner, use ethtool: ethtool -A eth? autoneg off RX off TX off @@ -181,10 +181,10 @@ Additional Configurations ------- The driver utilizes the ethtool interface for driver configuration and diagnostics, as well as displaying statistical information. The latest - Ethtool version is required for this functionality. + ethtool version is required for this functionality. The latest release of ethtool can be found from - http://sourceforge.net/projects/gkernel. + http://ftp.kernel.org/pub/software/network/ethtool/ FCoE ---- -- cgit v1.2.3-59-g8ed1b From f0f1a172b2a9e26319b9aa95fa6c322ebb01089d Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 11 Dec 2010 05:53:32 +0000 Subject: e1000e: checkpatch error - macro panethesis ERROR: Macros with complex values should be enclosed in parenthesis Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 114 ++++++++++++++++++++++--------------------- drivers/net/e1000e/netdev.c | 2 +- 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 39349d6dcd0b..15c63304bd91 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -45,63 +45,67 @@ struct e1000_stats { int stat_offset; }; -#define E1000_STAT(m) E1000_STATS, \ - sizeof(((struct e1000_adapter *)0)->m), \ - offsetof(struct e1000_adapter, m) -#define E1000_NETDEV_STAT(m) NETDEV_STATS, \ - sizeof(((struct net_device *)0)->m), \ - offsetof(struct net_device, m) +#define E1000_STAT(str, m) { \ + .stat_string = str, \ + .type = E1000_STATS, \ + .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ + .stat_offset = offsetof(struct e1000_adapter, m) } +#define E1000_NETDEV_STAT(str, m) { \ + .stat_string = str, \ + .type = NETDEV_STATS, \ + .sizeof_stat = sizeof(((struct net_device *)0)->m), \ + .stat_offset = offsetof(struct net_device, m) } static const struct e1000_stats e1000_gstrings_stats[] = { - { "rx_packets", E1000_STAT(stats.gprc) }, - { "tx_packets", E1000_STAT(stats.gptc) }, - { "rx_bytes", E1000_STAT(stats.gorc) }, - { "tx_bytes", E1000_STAT(stats.gotc) }, - { "rx_broadcast", E1000_STAT(stats.bprc) }, - { "tx_broadcast", E1000_STAT(stats.bptc) }, - { "rx_multicast", E1000_STAT(stats.mprc) }, - { "tx_multicast", E1000_STAT(stats.mptc) }, - { "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) }, - { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) }, - { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) }, - { "multicast", E1000_STAT(stats.mprc) }, - { "collisions", E1000_STAT(stats.colc) }, - { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) }, - { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) }, - { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, - { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) }, - { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, - { "rx_missed_errors", E1000_STAT(stats.mpc) }, - { "tx_aborted_errors", E1000_STAT(stats.ecol) }, - { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, - { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) }, - { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) }, - { "tx_window_errors", E1000_STAT(stats.latecol) }, - { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, - { "tx_deferred_ok", E1000_STAT(stats.dc) }, - { "tx_single_coll_ok", E1000_STAT(stats.scc) }, - { "tx_multi_coll_ok", E1000_STAT(stats.mcc) }, - { "tx_timeout_count", E1000_STAT(tx_timeout_count) }, - { "tx_restart_queue", E1000_STAT(restart_queue) }, - { "rx_long_length_errors", E1000_STAT(stats.roc) }, - { "rx_short_length_errors", E1000_STAT(stats.ruc) }, - { "rx_align_errors", E1000_STAT(stats.algnerrc) }, - { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) }, - { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) }, - { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) }, - { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) }, - { "tx_flow_control_xon", E1000_STAT(stats.xontxc) }, - { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) }, - { "rx_long_byte_count", E1000_STAT(stats.gorc) }, - { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, - { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, - { "rx_header_split", E1000_STAT(rx_hdr_split) }, - { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, - { "tx_smbus", E1000_STAT(stats.mgptc) }, - { "rx_smbus", E1000_STAT(stats.mgprc) }, - { "dropped_smbus", E1000_STAT(stats.mgpdc) }, - { "rx_dma_failed", E1000_STAT(rx_dma_failed) }, - { "tx_dma_failed", E1000_STAT(tx_dma_failed) }, + E1000_STAT("rx_packets", stats.gprc), + E1000_STAT("tx_packets", stats.gptc), + E1000_STAT("rx_bytes", stats.gorc), + E1000_STAT("tx_bytes", stats.gotc), + E1000_STAT("rx_broadcast", stats.bprc), + E1000_STAT("tx_broadcast", stats.bptc), + E1000_STAT("rx_multicast", stats.mprc), + E1000_STAT("tx_multicast", stats.mptc), + E1000_NETDEV_STAT("rx_errors", stats.rx_errors), + E1000_NETDEV_STAT("tx_errors", stats.tx_errors), + E1000_NETDEV_STAT("tx_dropped", stats.tx_dropped), + E1000_STAT("multicast", stats.mprc), + E1000_STAT("collisions", stats.colc), + E1000_NETDEV_STAT("rx_length_errors", stats.rx_length_errors), + E1000_NETDEV_STAT("rx_over_errors", stats.rx_over_errors), + E1000_STAT("rx_crc_errors", stats.crcerrs), + E1000_NETDEV_STAT("rx_frame_errors", stats.rx_frame_errors), + E1000_STAT("rx_no_buffer_count", stats.rnbc), + E1000_STAT("rx_missed_errors", stats.mpc), + E1000_STAT("tx_aborted_errors", stats.ecol), + E1000_STAT("tx_carrier_errors", stats.tncrs), + E1000_NETDEV_STAT("tx_fifo_errors", stats.tx_fifo_errors), + E1000_NETDEV_STAT("tx_heartbeat_errors", stats.tx_heartbeat_errors), + E1000_STAT("tx_window_errors", stats.latecol), + E1000_STAT("tx_abort_late_coll", stats.latecol), + E1000_STAT("tx_deferred_ok", stats.dc), + E1000_STAT("tx_single_coll_ok", stats.scc), + E1000_STAT("tx_multi_coll_ok", stats.mcc), + E1000_STAT("tx_timeout_count", tx_timeout_count), + E1000_STAT("tx_restart_queue", restart_queue), + E1000_STAT("rx_long_length_errors", stats.roc), + E1000_STAT("rx_short_length_errors", stats.ruc), + E1000_STAT("rx_align_errors", stats.algnerrc), + E1000_STAT("tx_tcp_seg_good", stats.tsctc), + E1000_STAT("tx_tcp_seg_failed", stats.tsctfc), + E1000_STAT("rx_flow_control_xon", stats.xonrxc), + E1000_STAT("rx_flow_control_xoff", stats.xoffrxc), + E1000_STAT("tx_flow_control_xon", stats.xontxc), + E1000_STAT("tx_flow_control_xoff", stats.xofftxc), + E1000_STAT("rx_long_byte_count", stats.gorc), + E1000_STAT("rx_csum_offload_good", hw_csum_good), + E1000_STAT("rx_csum_offload_errors", hw_csum_err), + E1000_STAT("rx_header_split", rx_hdr_split), + E1000_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed), + E1000_STAT("tx_smbus", stats.mgptc), + E1000_STAT("rx_smbus", stats.mgprc), + E1000_STAT("dropped_smbus", stats.mgpdc), + E1000_STAT("rx_dma_failed", rx_dma_failed), + E1000_STAT("tx_dma_failed", tx_dma_failed), }; #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index a45dafdf343a..ec7b77fea98b 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1325,7 +1325,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, goto next_desc; } -#define rxtop rx_ring->rx_skb_top +#define rxtop (rx_ring->rx_skb_top) if (!(status & E1000_RXD_STAT_EOP)) { /* this descriptor is only the beginning (or middle) */ if (!rxtop) { -- cgit v1.2.3-59-g8ed1b From 184125a389cf2c81980de5d5f365c786cc76d229 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 11 Dec 2010 05:53:37 +0000 Subject: e1000e: checkpatch error - trailing statements ERROR: trailing statements should be on next line Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/es2lan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 24f8ac9cf703..79da6466b8b6 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -426,8 +426,8 @@ static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; - while (e1000e_get_hw_semaphore(hw) != 0); - /* Empty */ + while (e1000e_get_hw_semaphore(hw) != 0) + ; /* Empty */ swfw_sync = er32(SW_FW_SYNC); swfw_sync &= ~mask; -- cgit v1.2.3-59-g8ed1b From 6480641eb741cabbba8e196d4f17db7fb80d101c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 11 Dec 2010 05:53:42 +0000 Subject: e1000e: checkpatch error - open braces ERROR: that open brace { should be on the previous line Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/es2lan.c | 4 ++-- drivers/net/e1000e/ethtool.c | 4 ++-- drivers/net/e1000e/phy.c | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 79da6466b8b6..b18c644e13d1 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -100,8 +100,8 @@ * with a lower bound at "index" and the upper bound at * "index + 5". */ -static const u16 e1000_gg82563_cable_length_table[] = - { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; +static const u16 e1000_gg82563_cable_length_table[] = { + 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_gg82563_cable_length_table) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 15c63304bd91..affcacf6f5a9 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -753,8 +753,8 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg, int offset, u32 mask, u32 write) { u32 pat, val; - static const u32 test[] = - {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + static const u32 test[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; for (pat = 0; pat < ARRAY_SIZE(test); pat++) { E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, (test[pat] & write)); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 95da38693b77..e297a23963a5 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -42,20 +42,20 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read); /* Cable length tables */ -static const u16 e1000_m88_cable_length_table[] = - { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; +static const u16 e1000_m88_cable_length_table[] = { + 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_m88_cable_length_table) -static const u16 e1000_igp_2_cable_length_table[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3, - 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22, - 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40, - 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61, - 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82, - 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95, - 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, - 124}; +static const u16 e1000_igp_2_cable_length_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3, + 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22, + 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40, + 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61, + 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82, + 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95, + 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, + 124}; #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_igp_2_cable_length_table) -- cgit v1.2.3-59-g8ed1b From b1cdfead0e532d7614b5d5b97044df94cc8945ae Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 11 Dec 2010 05:53:47 +0000 Subject: e1000e: checkpatch warnings - braces WARNING: braces {} are not necessary for any arm of this statement WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Bruce Allan Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 5 ++--- drivers/net/e1000e/lib.c | 6 ++---- drivers/net/e1000e/netdev.c | 19 +++++++------------ drivers/net/e1000e/phy.c | 3 +-- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 5080372b0fd7..d86cc0832720 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -2309,11 +2309,10 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, */ if (ret_val == 0) { flash_data = er32flash(ICH_FLASH_FDATA0); - if (size == 1) { + if (size == 1) *data = (u8)(flash_data & 0x000000FF); - } else if (size == 2) { + else if (size == 2) *data = (u16)(flash_data & 0x0000FFFF); - } break; } else { /* diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 8377523c054a..7e55170a601e 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -493,9 +493,8 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) * different link partner. */ ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { + if (ret_val) e_dbg("Error configuring flow control\n"); - } return ret_val; } @@ -1496,9 +1495,8 @@ s32 e1000e_setup_led_generic(struct e1000_hw *hw) { u32 ledctl; - if (hw->mac.ops.setup_led != e1000e_setup_led_generic) { + if (hw->mac.ops.setup_led != e1000e_setup_led_generic) return -E1000_ERR_CONFIG; - } if (hw->phy.media_type == e1000_media_type_fiber) { ledctl = er32(LEDCTL); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index ec7b77fea98b..fe50242aa9e6 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1806,9 +1806,8 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) err = pci_enable_msix(adapter->pdev, adapter->msix_entries, adapter->num_vectors); - if (err == 0) { + if (err == 0) return; - } } /* MSI-X failed, so fall through and try MSI */ e_err("Failed to initialize MSI-X interrupts. " @@ -2198,9 +2197,8 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) e1000_clean_rx_ring(adapter); - for (i = 0; i < rx_ring->count; i++) { + for (i = 0; i < rx_ring->count; i++) kfree(rx_ring->buffer_info[i].ps_pages); - } vfree(rx_ring->buffer_info); rx_ring->buffer_info = NULL; @@ -2240,20 +2238,18 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, /* handle TSO and jumbo frames */ if (bytes/packets > 8000) retval = bulk_latency; - else if ((packets < 5) && (bytes > 512)) { + else if ((packets < 5) && (bytes > 512)) retval = low_latency; - } break; case low_latency: /* 50 usec aka 20000 ints/s */ if (bytes > 10000) { /* this if handles the TSO accounting */ - if (bytes/packets > 8000) { + if (bytes/packets > 8000) retval = bulk_latency; - } else if ((packets < 10) || ((bytes/packets) > 1200)) { + else if ((packets < 10) || ((bytes/packets) > 1200)) retval = bulk_latency; - } else if ((packets > 35)) { + else if ((packets > 35)) retval = lowest_latency; - } } else if (bytes/packets > 2000) { retval = bulk_latency; } else if (packets <= 2 && bytes < 512) { @@ -2262,9 +2258,8 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, break; case bulk_latency: /* 250 usec aka 4000 ints/s */ if (bytes > 25000) { - if (packets > 35) { + if (packets > 35) retval = low_latency; - } } else if (bytes < 6000) { retval = low_latency; } diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index e297a23963a5..1781efeb55e3 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -1057,9 +1057,8 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - if (phy->autoneg_mask & ADVERTISE_1000_FULL) { + if (phy->autoneg_mask & ADVERTISE_1000_FULL) ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); - } return ret_val; } -- cgit v1.2.3-59-g8ed1b From 8fa7e0f739b70db14e788efba4960bfc1873d550 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Sat, 6 Nov 2010 05:43:21 +0000 Subject: igb: Fix overwrite of the VF's flags The vf flags were being overwritten causing the flag that indicates that the PF has set the VF MAC address to get cleared. This would allow the VF to override the MAC address assigned by the Host VMM using the ip link set command. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 62348fc60e53..be426a4a7240 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1654,7 +1654,7 @@ void igb_reset(struct igb_adapter *adapter) if (adapter->vfs_allocated_count) { int i; for (i = 0 ; i < adapter->vfs_allocated_count; i++) - adapter->vf_data[i].flags = 0; + adapter->vf_data[i].flags &= IGB_VF_FLAG_PF_SET_MAC; /* ping all the active vfs to let them know we are going down */ igb_ping_all_vfs(adapter); @@ -4971,8 +4971,8 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) { - /* clear flags */ - adapter->vf_data[vf].flags &= ~(IGB_VF_FLAG_PF_SET_MAC); + /* clear flags - except flag that indicates PF has set the MAC */ + adapter->vf_data[vf].flags &= IGB_VF_FLAG_PF_SET_MAC; adapter->vf_data[vf].last_nack = jiffies; /* reset offloads to defaults */ @@ -5026,7 +5026,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) reg = rd32(E1000_VFRE); wr32(E1000_VFRE, reg | (1 << vf)); - adapter->vf_data[vf].flags = IGB_VF_FLAG_CTS; + adapter->vf_data[vf].flags |= IGB_VF_FLAG_CTS; /* reply to reset with ack and vf mac address */ msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; -- cgit v1.2.3-59-g8ed1b From a6b5ea353845b3f3d9ac4317c0b3be9cc37c259b Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Sat, 6 Nov 2010 05:42:59 +0000 Subject: igb: Warn on attempt to override administratively set MAC/VLAN Print a warning message to the system log when the VF attempts to override administratively set MAC/VLAN configuration. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index be426a4a7240..c9aac7f15cd2 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5105,7 +5105,14 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) switch ((msgbuf[0] & 0xFFFF)) { case E1000_VF_SET_MAC_ADDR: - retval = igb_set_vf_mac_addr(adapter, msgbuf, vf); + retval = -EINVAL; + if (!(vf_data->flags & IGB_VF_FLAG_PF_SET_MAC)) + retval = igb_set_vf_mac_addr(adapter, msgbuf, vf); + else + dev_warn(&pdev->dev, + "VF %d attempted to override administratively " + "set MAC address\nReload the VF driver to " + "resume operations\n", vf); break; case E1000_VF_SET_PROMISC: retval = igb_set_vf_promisc(adapter, msgbuf, vf); @@ -5117,8 +5124,12 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf); break; case E1000_VF_SET_VLAN: - if (adapter->vf_data[vf].pf_vlan) - retval = -1; + retval = -1; + if (vf_data->pf_vlan) + dev_warn(&pdev->dev, + "VF %d attempted to override administratively " + "set VLAN tag\nReload the VF driver to " + "resume operations\n", vf); else retval = igb_set_vf_vlan(adapter, msgbuf, vf); break; -- cgit v1.2.3-59-g8ed1b From 1b5dda331ff8646a70d247cace45a60035937a9b Mon Sep 17 00:00:00 2001 From: "Gasparakis, Joseph" Date: Thu, 9 Dec 2010 01:41:01 +0000 Subject: igb: Some fine tuning This patch does the following: 1. Changes the existing supported device id's so now DH89xxCC is not supported when EEPROM is not read. 2. Adds two more device ids for DH89xxCC in backplane mode and SFP. 3. Driver now initializes previously possibly uninitialized value in igb_reset_mdicnfg_82580(). Signed-off-by: Joseph Gasparakis Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 4 +++- drivers/net/igb/e1000_hw.h | 6 ++++-- drivers/net/igb/igb_main.c | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index bc183f5487cb..50f6e9649845 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -134,6 +134,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_82580_COPPER_DUAL: case E1000_DEV_ID_DH89XXCC_SGMII: case E1000_DEV_ID_DH89XXCC_SERDES: + case E1000_DEV_ID_DH89XXCC_BACKPLANE: + case E1000_DEV_ID_DH89XXCC_SFP: mac->type = e1000_82580; break; case E1000_DEV_ID_I350_COPPER: @@ -1578,7 +1580,7 @@ static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw) { s32 ret_val = 0; u32 mdicnfg; - u16 nvm_data; + u16 nvm_data = 0; if (hw->mac.type != e1000_82580) goto out; diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index c0b017f8d782..e2638afb8cdc 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -54,8 +54,10 @@ struct e1000_hw; #define E1000_DEV_ID_82580_SERDES 0x1510 #define E1000_DEV_ID_82580_SGMII 0x1511 #define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 -#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436 -#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438 +#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438 +#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A +#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C +#define E1000_DEV_ID_DH89XXCC_SFP 0x0440 #define E1000_DEV_ID_I350_COPPER 0x1521 #define E1000_DEV_ID_I350_FIBER 0x1522 #define E1000_DEV_ID_I350_SERDES 0x1523 diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index c9aac7f15cd2..a364ae69ab37 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -73,6 +73,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_BACKPLANE), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SFP), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 }, -- cgit v1.2.3-59-g8ed1b From 13800469d40bf4dc9fbed17f4692b2ebe94d4526 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Sat, 6 Nov 2010 02:08:26 +0000 Subject: igb: Add Anti-spoofing feature support Add support for the anti-spoofing feature in the HW. Packets from VF devices with spoofed MAC addresses or VLAN tags will be blocked and an event generated. When the watchdog task runs it will call a function to check if any spoof events occurred. If an event was detected then a warning message is dumped to the system log. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 33 ++++++++++++++++++++++++++++++ drivers/net/igb/e1000_82575.h | 5 +++++ drivers/net/igb/e1000_regs.h | 1 + drivers/net/igb/igb.h | 1 + drivers/net/igb/igb_main.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 50f6e9649845..0a2368fa6bc6 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1479,6 +1479,39 @@ out: return ret_val; } +/** + * igb_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing + * @hw: pointer to the hardware struct + * @enable: state to enter, either enabled or disabled + * @pf: Physical Function pool - do not set anti-spoofing for the PF + * + * enables/disables L2 switch anti-spoofing functionality. + **/ +void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf) +{ + u32 dtxswc; + + switch (hw->mac.type) { + case e1000_82576: + case e1000_i350: + dtxswc = rd32(E1000_DTXSWC); + if (enable) { + dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + /* The PF can spoof - it has to in order to + * support emulation mode NICs */ + dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); + } else { + dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + } + wr32(E1000_DTXSWC, dtxswc); + break; + default: + break; + } +} + /** * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback * @hw: pointer to the hardware struct diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index cbd1e1259e4d..1d01af2472e7 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -194,6 +194,10 @@ struct e1000_adv_tx_context_desc { #define E1000_NVM_APME_82575 0x0400 #define MAX_NUM_VFS 8 +#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */ +#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */ +#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */ +#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 #define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ /* Easy defines for setting default pool, would normally be left a zero */ @@ -243,6 +247,7 @@ struct e1000_adv_tx_context_desc { /* RX packet buffer size defines */ #define E1000_RXPBS_SIZE_MASK_82576 0x0000007F +void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int); void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); u16 igb_rxpbs_adjust_82580(u32 data); diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index abb7333a1fbf..8ac83c5190d5 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -301,6 +301,7 @@ #define E1000_VFTE 0x00C90 /* VF Transmit Enables */ #define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ #define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ +#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */ #define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ #define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ #define E1000_IOVTCL 0x05BBC /* IOV Control Register */ diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index edab9c442399..92a4ef09e55c 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -324,6 +324,7 @@ struct igb_adapter { unsigned int vfs_allocated_count; struct vf_data_storage *vf_data; u32 rss_queues; + u32 wvbr; }; #define IGB_FLAG_HAS_MSI (1 << 0) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index a364ae69ab37..58c665b7513d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3366,6 +3366,45 @@ static void igb_set_rx_mode(struct net_device *netdev) igb_restore_vf_multicasts(adapter); } +static void igb_check_wvbr(struct igb_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 wvbr = 0; + + switch (hw->mac.type) { + case e1000_82576: + case e1000_i350: + if (!(wvbr = rd32(E1000_WVBR))) + return; + break; + default: + break; + } + + adapter->wvbr |= wvbr; +} + +#define IGB_STAGGERED_QUEUE_OFFSET 8 + +static void igb_spoof_check(struct igb_adapter *adapter) +{ + int j; + + if (!adapter->wvbr) + return; + + for(j = 0; j < adapter->vfs_allocated_count; j++) { + if (adapter->wvbr & (1 << j) || + adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) { + dev_warn(&adapter->pdev->dev, + "Spoof event(s) detected on VF %d\n", j); + adapter->wvbr &= + ~((1 << j) | + (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))); + } + } +} + /* Need to wait a few seconds after link up to get diagnostic information from * the phy */ static void igb_update_phy_info(unsigned long data) @@ -3525,6 +3564,8 @@ static void igb_watchdog_task(struct work_struct *work) wr32(E1000_ICS, E1000_ICS_RXDMT0); } + igb_spoof_check(adapter); + /* Reset the timer */ if (!test_bit(__IGB_DOWN, &adapter->state)) mod_timer(&adapter->watchdog_timer, @@ -4521,6 +4562,10 @@ static irqreturn_t igb_msix_other(int irq, void *data) if (icr & E1000_ICR_DOUTSYNC) { /* HW is reporting DMA is out of sync */ adapter->stats.doosync++; + /* The DMA Out of Sync is also indication of a spoof event + * in IOV mode. Check the Wrong VM Behavior register to + * see if it is really a spoof event. */ + igb_check_wvbr(adapter); } /* Check for a mailbox event */ @@ -6595,6 +6640,8 @@ static void igb_vmm_control(struct igb_adapter *adapter) if (adapter->vfs_allocated_count) { igb_vmdq_set_loopback_pf(hw, true); igb_vmdq_set_replication_pf(hw, true); + igb_vmdq_set_anti_spoofing_pf(hw, true, + adapter->vfs_allocated_count); } else { igb_vmdq_set_loopback_pf(hw, false); igb_vmdq_set_replication_pf(hw, false); -- cgit v1.2.3-59-g8ed1b From 0e512bfc2c0cd6072387092f8d1ac8e1a758965b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 18 Nov 2010 03:12:30 +0000 Subject: igbvf: force link checking when mailbox timeout has occurred This change forces the link down when a mailbox timeout has occurred. Previously it was possible for a mailbox timeout to occur but for the interface to stay up. The problem with this was that it became possible for an interface to stay up and miss multiple requests resulting in a possible issue since the interface will be running in an unknown state. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/vf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index 0cc13c6ed418..74486a8b009a 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -362,8 +362,8 @@ static s32 e1000_check_for_link_vf(struct e1000_hw *hw) * or a virtual function reset */ - /* If we were hit with a reset drop the link */ - if (!mbx->ops.check_for_rst(hw)) + /* If we were hit with a reset or timeout drop the link */ + if (!mbx->ops.check_for_rst(hw) || !mbx->timeout) mac->get_link_status = true; if (!mac->get_link_status) -- cgit v1.2.3-59-g8ed1b From 031d7952ee63e1aa679f7e87700e3281f4de4ba2 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Thu, 9 Dec 2010 03:23:56 +0000 Subject: igbvf: add support for i350 VF device Add support to igbvf for the new i350 virtual function device. Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/igbvf.h | 1 + drivers/net/igbvf/netdev.c | 9 +++++++++ drivers/net/igbvf/vf.h | 2 ++ 3 files changed, 12 insertions(+) diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index 9d4d63e536d4..990c329e6c3b 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -97,6 +97,7 @@ struct igbvf_adapter; enum igbvf_boards { board_vf, + board_i350_vf, }; struct igbvf_queue_stats { diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 4fb023bce785..6352c8158e6d 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -64,8 +64,16 @@ static struct igbvf_info igbvf_vf_info = { .init_ops = e1000_init_function_pointers_vf, }; +static struct igbvf_info igbvf_i350_vf_info = { + .mac = e1000_vfadapt_i350, + .flags = 0, + .pba = 10, + .init_ops = e1000_init_function_pointers_vf, +}; + static const struct igbvf_info *igbvf_info_tbl[] = { [board_vf] = &igbvf_vf_info, + [board_i350_vf] = &igbvf_i350_vf_info, }; /** @@ -2865,6 +2873,7 @@ static struct pci_error_handlers igbvf_err_handler = { static DEFINE_PCI_DEVICE_TABLE(igbvf_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_VF), board_i350_vf }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl); diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h index c36ea21f17fa..d7ed58fcd9bb 100644 --- a/drivers/net/igbvf/vf.h +++ b/drivers/net/igbvf/vf.h @@ -39,6 +39,7 @@ struct e1000_hw; #define E1000_DEV_ID_82576_VF 0x10CA +#define E1000_DEV_ID_I350_VF 0x1520 #define E1000_REVISION_0 0 #define E1000_REVISION_1 1 #define E1000_REVISION_2 2 @@ -133,6 +134,7 @@ struct e1000_adv_tx_context_desc { enum e1000_mac_type { e1000_undefined = 0, e1000_vfadapt, + e1000_vfadapt_i350, e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ }; -- cgit v1.2.3-59-g8ed1b From d3306c2974481ff9c539de22a37bb667e8694be2 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 18 Nov 2010 03:03:23 +0000 Subject: ixgbe: Warn on VF attempt to override Administratively set MAC/VLAN Print warnings to the system log when the VF attempts to override MAC/VLAN settings that were configured by the VMM Host administrator using the ip link set commands. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_sriov.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 6e3e94b5a5f6..e01d0db8b517 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -227,6 +227,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) int entries; u16 *hash_list; int add, vid; + u8 *new_mac; retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); @@ -244,15 +245,22 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) if (msgbuf[0] == IXGBE_VF_RESET) { unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; - u8 *addr = (u8 *)(&msgbuf[1]); + new_mac = (u8 *)(&msgbuf[1]); e_info(probe, "VF Reset msg received from vf %d\n", vf); adapter->vfinfo[vf].clear_to_send = false; ixgbe_vf_reset_msg(adapter, vf); adapter->vfinfo[vf].clear_to_send = true; + if (is_valid_ether_addr(new_mac) && + !adapter->vfinfo[vf].pf_set_mac) + ixgbe_set_vf_mac(adapter, vf, vf_mac); + else + ixgbe_set_vf_mac(adapter, + vf, adapter->vfinfo[vf].vf_mac_addresses); + /* reply to reset with ack and vf mac address */ msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; - memcpy(addr, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); + memcpy(new_mac, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); /* * Piggyback the multicast filter type so VF can compute the * correct vectors @@ -271,14 +279,16 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) switch ((msgbuf[0] & 0xFFFF)) { case IXGBE_VF_SET_MAC_ADDR: - { - u8 *new_mac = ((u8 *)(&msgbuf[1])); - if (is_valid_ether_addr(new_mac) && - !adapter->vfinfo[vf].pf_set_mac) - ixgbe_set_vf_mac(adapter, vf, new_mac); - else - ixgbe_set_vf_mac(adapter, - vf, adapter->vfinfo[vf].vf_mac_addresses); + new_mac = ((u8 *)(&msgbuf[1])); + if (is_valid_ether_addr(new_mac) && + !adapter->vfinfo[vf].pf_set_mac) { + ixgbe_set_vf_mac(adapter, vf, new_mac); + } else if (memcmp(adapter->vfinfo[vf].vf_mac_addresses, + new_mac, ETH_ALEN)) { + e_warn(drv, "VF %d attempted to override " + "administratively set MAC address\nReload " + "the VF driver to resume operations\n", vf); + retval = -1; } break; case IXGBE_VF_SET_MULTICAST: @@ -295,7 +305,15 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); - retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); + if (adapter->vfinfo[vf].pf_vlan) { + e_warn(drv, "VF %d attempted to override " + "administratively set VLAN configuration\n" + "Reload the VF driver to resume operations\n", + vf); + retval = -1; + } else { + retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); + } break; default: e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); -- cgit v1.2.3-59-g8ed1b From 3377eba79e15671799876f82d30446e656aac5ad Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 7 Dec 2010 08:16:45 +0000 Subject: ixgbe: Add SR-IOV feature support to X540 Add X540 specific feature support to X540 Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbe/ixgbe_mbx.c | 4 +++- drivers/net/ixgbe/ixgbe_x540.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index ca9036de49f9..c90562530202 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6889,7 +6889,7 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; int err; - if (hw->mac.type != ixgbe_mac_82599EB || !max_vfs) + if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs) return; /* The 82599 supports up to 64 VFs per physical function diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index 027c628c3aae..ea82c5a1cd3e 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -321,9 +321,11 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) switch (hw->mac.type) { case ixgbe_mac_82599EB: - case ixgbe_mac_X540: vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); break; + case ixgbe_mac_X540: + vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); + break; default: break; } diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index cf88515c0ef8..3a8923993ce3 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -685,6 +685,8 @@ static struct ixgbe_mac_operations mac_ops_X540 = { .fc_enable = &ixgbe_fc_enable_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic, .setup_sfp = NULL, + .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, + .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, }; static struct ixgbe_eeprom_operations eeprom_ops_X540 = { -- cgit v1.2.3-59-g8ed1b From a985b6c31ff230a1246d921afbfc0f6a1386be83 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 18 Nov 2010 03:02:52 +0000 Subject: ixgbe: Add anti-spoofing feature support Add support for the anti-spoofing feature in the HW. Packets from VF devices with spoofed MAC addresses or VLAN tags will be blocked and a counter incremented. During the watchdog timer the spoofed packet dropped counter is read and if it is non-zero then a warning message is displayed on the host VMM's console. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 2 ++ drivers/net/ixgbe/ixgbe_common.c | 64 ++++++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 2 ++ drivers/net/ixgbe/ixgbe_main.c | 24 +++++++++++++++ drivers/net/ixgbe/ixgbe_sriov.c | 12 ++++++-- drivers/net/ixgbe/ixgbe_type.h | 13 +++++++- 6 files changed, 114 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 6827dddc383e..bfd3c227cd4a 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -2165,6 +2165,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .fc_enable = &ixgbe_fc_enable_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic, .setup_sfp = &ixgbe_setup_sfp_modules_82599, + .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, + .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, }; static struct ixgbe_eeprom_operations eeprom_ops_82599 = { diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index cc11e422ce9b..d5ede2df3e42 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2809,3 +2809,67 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, wwn_prefix_out: return 0; } + +/** + * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for anti-spoofing + * @pf: Physical Function pool - do not enable anti-spoofing for the PF + * + **/ +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) +{ + int j; + int pf_target_reg = pf >> 3; + int pf_target_shift = pf % 8; + u32 pfvfspoof = 0; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + if (enable) + pfvfspoof = IXGBE_SPOOF_MACAS_MASK; + + /* + * PFVFSPOOF register array is size 8 with 8 bits assigned to + * MAC anti-spoof enables in each register array element. + */ + for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); + + /* If not enabling anti-spoofing then done */ + if (!enable) + return; + + /* + * The PF should be allowed to spoof so that it can support + * emulation mode NICs. Reset the bit assigned to the PF + */ + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg)); + pfvfspoof ^= (1 << pf_target_shift); + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof); +} + +/** + * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for VLAN anti-spoofing + * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing + * + **/ +void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) +{ + int vf_target_reg = vf >> 3; + int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT; + u32 pfvfspoof; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); + if (enable) + pfvfspoof |= (1 << vf_target_shift); + else + pfvfspoof &= ~(1 << vf_target_shift); + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index e1f980a8a09d..66ed045a8cf0 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -88,6 +88,8 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); +void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c90562530202..38ab4f3f8197 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3132,6 +3132,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) /* enable Tx loopback for VF/PF communication */ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + /* Enable MAC Anti-Spoofing */ + hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), + adapter->num_vfs); } static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) @@ -5960,6 +5963,26 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work) netif_tx_start_all_queues(adapter->netdev); } +static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) +{ + u32 ssvpc; + + /* Do not perform spoof check for 82598 */ + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + return; + + ssvpc = IXGBE_READ_REG(&adapter->hw, IXGBE_SSVPC); + + /* + * ssvpc register is cleared on read, if zero then no + * spoofed packets in the last interval. + */ + if (!ssvpc) + return; + + e_warn(drv, "%d Spoofed packets detected\n", ssvpc); +} + static DEFINE_MUTEX(ixgbe_watchdog_lock); /** @@ -6080,6 +6103,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) } } + ixgbe_spoof_check(adapter); ixgbe_update_stats(adapter); mutex_unlock(&ixgbe_watchdog_lock); } diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index e01d0db8b517..47b15738b009 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -215,6 +215,11 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) reg |= (reg | (1 << vf_shift)); IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); + /* Enable counting of spoofed packets in the SSVPC register */ + reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset)); + reg |= (1 << vf_shift); + IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg); + ixgbe_vf_reset_event(adapter, vf); } @@ -412,6 +417,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) { int err = 0; struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) return -EINVAL; @@ -420,7 +426,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) if (err) goto out; ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); - ixgbe_set_vmolr(&adapter->hw, vf, false); + ixgbe_set_vmolr(hw, vf, false); + hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); adapter->vfinfo[vf].pf_vlan = vlan; adapter->vfinfo[vf].pf_qos = qos; dev_info(&adapter->pdev->dev, @@ -437,7 +444,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) err = ixgbe_set_vf_vlan(adapter, false, adapter->vfinfo[vf].pf_vlan, vf); ixgbe_set_vmvir(adapter, vlan, vf); - ixgbe_set_vmolr(&adapter->hw, vf, true); + ixgbe_set_vmolr(hw, vf, true); + hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); adapter->vfinfo[vf].pf_vlan = 0; adapter->vfinfo[vf].pf_qos = 0; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 59f6d0afe0fe..446f3467d3c7 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -230,6 +230,7 @@ #define IXGBE_VT_CTL 0x051B0 #define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) #define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) +#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4)) #define IXGBE_QDE 0x2F04 #define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */ #define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4)) @@ -284,7 +285,8 @@ #define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40)) #define IXGBE_DTXCTL 0x07E00 -#define IXGBE_DMATXCTL 0x04A80 +#define IXGBE_DMATXCTL 0x04A80 +#define IXGBE_PFVFSPOOF(_i) (0x08200 + ((_i) * 4)) /* 8 of these 0 - 7 */ #define IXGBE_PFDTXGSWC 0x08220 #define IXGBE_DTXMXSZRQ 0x08100 #define IXGBE_DTXTCPFLGL 0x04A88 @@ -298,6 +300,13 @@ #define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */ #define IXGBE_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */ + +/* Anti-spoofing defines */ +#define IXGBE_SPOOF_MACAS_MASK 0xFF +#define IXGBE_SPOOF_VLANAS_MASK 0xFF00 +#define IXGBE_SPOOF_VLANAS_SHIFT 8 +#define IXGBE_PFVFSPOOF_REG_COUNT 8 + #define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */ /* Tx DCA Control register : 128 of these (0-127) */ #define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40)) @@ -2482,6 +2491,8 @@ struct ixgbe_mac_operations { s32 (*clear_vfta)(struct ixgbe_hw *); s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); s32 (*init_uta_tables)(struct ixgbe_hw *); + void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int); + void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int); /* Flow Control */ s32 (*fc_enable)(struct ixgbe_hw *, s32); -- cgit v1.2.3-59-g8ed1b From 2316aa2aee254c126e688b53a3a105b82bc3f368 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 2 Dec 2010 07:12:26 +0000 Subject: ixgbevf: Add X540 VF device support to the ixgbevf driver The X540 introduces a new Virtual Function device ID so that the X540 VF device can be distinguished from the 82599 VF device. The X540 VF device will have additional capability over the 82599 VF device so it is necessary to be able to discern the difference. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/defines.h | 1 + drivers/net/ixgbevf/ixgbevf.h | 4 +++- drivers/net/ixgbevf/ixgbevf_main.c | 7 +++++-- drivers/net/ixgbevf/vf.c | 6 +++++- drivers/net/ixgbevf/vf.h | 1 + 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbevf/defines.h b/drivers/net/ixgbevf/defines.h index f8a807d606c7..de643eb2ada6 100644 --- a/drivers/net/ixgbevf/defines.h +++ b/drivers/net/ixgbevf/defines.h @@ -30,6 +30,7 @@ /* Device IDs */ #define IXGBE_DEV_ID_82599_VF 0x10ED +#define IXGBE_DEV_ID_X540_VF 0x1515 #define IXGBE_VF_IRQ_CLEAR_MASK 7 #define IXGBE_VF_MAX_TX_QUEUES 1 diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index 0cd6abcf9306..a63efcb2cf1b 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -275,9 +275,11 @@ enum ixbgevf_state_t { enum ixgbevf_boards { board_82599_vf, + board_X540_vf, }; -extern struct ixgbevf_info ixgbevf_vf_info; +extern struct ixgbevf_info ixgbevf_82599_vf_info; +extern struct ixgbevf_info ixgbevf_X540_vf_info; extern struct ixgbe_mac_operations ixgbevf_mbx_ops; /* needed by ethtool.c */ diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 809e38ce8a13..464e6c9d3fc2 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -51,13 +51,14 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 82599 Virtual Function"; -#define DRV_VERSION "1.0.12-k0" +#define DRV_VERSION "1.0.19-k0" const char ixgbevf_driver_version[] = DRV_VERSION; static char ixgbevf_copyright[] = "Copyright (c) 2009 - 2010 Intel Corporation."; static const struct ixgbevf_info *ixgbevf_info_tbl[] = { - [board_82599_vf] = &ixgbevf_vf_info, + [board_82599_vf] = &ixgbevf_82599_vf_info, + [board_X540_vf] = &ixgbevf_X540_vf_info, }; /* ixgbevf_pci_tbl - PCI Device ID Table @@ -71,6 +72,8 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = { static struct pci_device_id ixgbevf_pci_tbl[] = { {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), + board_X540_vf}, /* required last entry */ {0, } diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c index 971019d819b4..eecd3bf6833f 100644 --- a/drivers/net/ixgbevf/vf.c +++ b/drivers/net/ixgbevf/vf.c @@ -381,8 +381,12 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = { .set_vfta = ixgbevf_set_vfta_vf, }; -struct ixgbevf_info ixgbevf_vf_info = { +struct ixgbevf_info ixgbevf_82599_vf_info = { .mac = ixgbe_mac_82599_vf, .mac_ops = &ixgbevf_mac_ops, }; +struct ixgbevf_info ixgbevf_X540_vf_info = { + .mac = ixgbe_mac_X540_vf, + .mac_ops = &ixgbevf_mac_ops, +}; diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 144c99d5363a..23eb114c149f 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h @@ -73,6 +73,7 @@ struct ixgbe_mac_operations { enum ixgbe_mac_type { ixgbe_mac_unknown = 0, ixgbe_mac_82599_vf, + ixgbe_mac_X540_vf, ixgbe_num_macs }; -- cgit v1.2.3-59-g8ed1b From be7fa3263a15d3f278c3bfbf606ec169aaa3a920 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:01 +0000 Subject: bna: TxRx and datapath fix Change Details: - Check HW ready condition before accessing h/w register in data-path - Postpone clean-up of data buffers to the data-path restart path and wait in the cleanup routines for in-flight DMA to complete - Separate out Tx completion processing from Rx poll routine Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 353 +++++++++++++++++++++++-------------------------- drivers/net/bna/bnad.h | 22 +-- 2 files changed, 178 insertions(+), 197 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 7e839b9cec22..3c405022d2bb 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -70,6 +70,8 @@ do { \ (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \ } while (0) +#define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */ + /* * Reinitialize completions in CQ, once Rx is taken down */ @@ -130,7 +132,9 @@ bnad_free_all_txbufs(struct bnad *bnad, PCI_DMA_TODEVICE); pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); - unmap_cons++; + if (++unmap_cons >= unmap_q->q_depth) + break; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { pci_unmap_page(bnad->pcidev, pci_unmap_addr(&unmap_array[unmap_cons], @@ -139,7 +143,8 @@ bnad_free_all_txbufs(struct bnad *bnad, PCI_DMA_TODEVICE); pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); - unmap_cons++; + if (++unmap_cons >= unmap_q->q_depth) + break; } dev_kfree_skb_any(skb); } @@ -167,11 +172,11 @@ bnad_free_txbufs(struct bnad *bnad, /* * Just return if TX is stopped. This check is useful * when bnad_free_txbufs() runs out of a tasklet scheduled - * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit + * before bnad_cb_tx_cleanup() cleared BNAD_TXQ_TX_STARTED bit * but this routine runs actually after the cleanup has been * executed. */ - if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) + if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) return 0; updated_hw_cons = *(tcb->hw_consumer_index); @@ -252,7 +257,9 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr) (!test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))) { acked = bnad_free_txbufs(bnad, tcb); - bna_ib_ack(tcb->i_dbell, acked); + if (likely(test_bit(BNAD_TXQ_TX_STARTED, + &tcb->flags))) + bna_ib_ack(tcb->i_dbell, acked); smp_mb__before_clear_bit(); clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); } @@ -264,7 +271,7 @@ static u32 bnad_tx(struct bnad *bnad, struct bna_tcb *tcb) { struct net_device *netdev = bnad->netdev; - u32 sent; + u32 sent = 0; if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) return 0; @@ -275,12 +282,15 @@ bnad_tx(struct bnad *bnad, struct bna_tcb *tcb) netif_carrier_ok(netdev) && BNA_QE_FREE_CNT(tcb, tcb->q_depth) >= BNAD_NETIF_WAKE_THRESHOLD) { - netif_wake_queue(netdev); - BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) { + netif_wake_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } } + } + + if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) bna_ib_ack(tcb->i_dbell, sent); - } else - bna_ib_ack(tcb->i_dbell, 0); smp_mb__before_clear_bit(); clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); @@ -313,25 +323,26 @@ bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb) } static void -bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) +bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) { struct bnad_unmap_q *unmap_q; struct sk_buff *skb; + int unmap_cons; unmap_q = rcb->unmap_q; - while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) { - skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; - BUG_ON(!(skb)); - unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; + for (unmap_cons = 0; unmap_cons < unmap_q->q_depth; unmap_cons++) { + skb = unmap_q->unmap_array[unmap_cons].skb; + if (!skb) + continue; + BUG_ON(!(pci_unmap_addr( + &unmap_q->unmap_array[unmap_cons], dma_addr))); + unmap_q->unmap_array[unmap_cons].skb = NULL; pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q-> - unmap_array[unmap_q->consumer_index], - dma_addr), rcb->rxq->buffer_size + - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + unmap_array[unmap_cons], + dma_addr), rcb->rxq->buffer_size, + PCI_DMA_FROMDEVICE); dev_kfree_skb(skb); - BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); - BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); } - bnad_reset_rcb(bnad, rcb); } @@ -385,41 +396,9 @@ finishing: unmap_q->producer_index = unmap_prod; rcb->producer_index = unmap_prod; smp_mb(); - bna_rxq_prod_indx_doorbell(rcb); - } -} - -/* - * Locking is required in the enable path - * because it is called from a napi poll - * context, where the bna_lock is not held - * unlike the IRQ context. - */ -static void -bnad_enable_txrx_irqs(struct bnad *bnad) -{ - struct bna_tcb *tcb; - struct bna_ccb *ccb; - int i, j; - unsigned long flags; - - spin_lock_irqsave(&bnad->bna_lock, flags); - for (i = 0; i < bnad->num_tx; i++) { - for (j = 0; j < bnad->num_txq_per_tx; j++) { - tcb = bnad->tx_info[i].tcb[j]; - bna_ib_coalescing_timer_set(tcb->i_dbell, - tcb->txq->ib->ib_config.coalescing_timeo); - bna_ib_ack(tcb->i_dbell, 0); - } - } - - for (i = 0; i < bnad->num_rx; i++) { - for (j = 0; j < bnad->num_rxp_per_rx; j++) { - ccb = bnad->rx_info[i].rx_ctrl[j].ccb; - bnad_enable_rx_irq_unsafe(ccb); - } + if (likely(test_bit(BNAD_RXQ_STARTED, &rcb->flags))) + bna_rxq_prod_indx_doorbell(rcb); } - spin_unlock_irqrestore(&bnad->bna_lock, flags); } static inline void @@ -448,6 +427,9 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) u32 qid0 = ccb->rcb[0]->rxq->rxq_id; struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate; + if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) + return 0; + prefetch(bnad->netdev); BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl, wi_range); @@ -544,12 +526,15 @@ next: BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); if (likely(ccb)) { - bna_ib_ack(ccb->i_dbell, packets); + if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) + bna_ib_ack(ccb->i_dbell, packets); bnad_refill_rxq(bnad, ccb->rcb[0]); if (ccb->rcb[1]) bnad_refill_rxq(bnad, ccb->rcb[1]); - } else - bna_ib_ack(ccb->i_dbell, 0); + } else { + if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) + bna_ib_ack(ccb->i_dbell, 0); + } return packets; } @@ -557,6 +542,9 @@ next: static void bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) { + if (unlikely(!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) + return; + bna_ib_coalescing_timer_set(ccb->i_dbell, 0); bna_ib_ack(ccb->i_dbell, 0); } @@ -575,9 +563,11 @@ static void bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb) { struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl); - if (likely(napi_schedule_prep((&rx_ctrl->napi)))) { + struct napi_struct *napi = &rx_ctrl->napi; + + if (likely(napi_schedule_prep(napi))) { bnad_disable_rx_irq(bnad, ccb); - __napi_schedule((&rx_ctrl->napi)); + __napi_schedule(napi); } BNAD_UPDATE_CTR(bnad, netif_rx_schedule); } @@ -602,12 +592,11 @@ bnad_msix_mbox_handler(int irq, void *data) { u32 intr_status; unsigned long flags; - struct net_device *netdev = data; - struct bnad *bnad; + struct bnad *bnad = (struct bnad *)data; - bnad = netdev_priv(netdev); + if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))) + return IRQ_HANDLED; - /* BNA_ISR_GET(bnad); Inc Ref count */ spin_lock_irqsave(&bnad->bna_lock, flags); bna_intr_status_get(&bnad->bna, intr_status); @@ -617,7 +606,6 @@ bnad_msix_mbox_handler(int irq, void *data) spin_unlock_irqrestore(&bnad->bna_lock, flags); - /* BNAD_ISR_PUT(bnad); Dec Ref count */ return IRQ_HANDLED; } @@ -627,8 +615,7 @@ bnad_isr(int irq, void *data) int i, j; u32 intr_status; unsigned long flags; - struct net_device *netdev = data; - struct bnad *bnad = netdev_priv(netdev); + struct bnad *bnad = (struct bnad *)data; struct bnad_rx_info *rx_info; struct bnad_rx_ctrl *rx_ctrl; @@ -642,16 +629,21 @@ bnad_isr(int irq, void *data) spin_lock_irqsave(&bnad->bna_lock, flags); - if (BNA_IS_MBOX_ERR_INTR(intr_status)) { + if (BNA_IS_MBOX_ERR_INTR(intr_status)) bna_mbox_handler(&bnad->bna, intr_status); - if (!BNA_IS_INTX_DATA_INTR(intr_status)) { - spin_unlock_irqrestore(&bnad->bna_lock, flags); - goto done; - } - } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (!BNA_IS_INTX_DATA_INTR(intr_status)) + return IRQ_HANDLED; + /* Process data interrupts */ + /* Tx processing */ + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) + bnad_tx(bnad, bnad->tx_info[i].tcb[j]); + } + /* Rx processing */ for (i = 0; i < bnad->num_rx; i++) { rx_info = &bnad->rx_info[i]; if (!rx_info->rx) @@ -663,7 +655,6 @@ bnad_isr(int irq, void *data) rx_ctrl->ccb); } } -done: return IRQ_HANDLED; } @@ -674,11 +665,7 @@ done: static void bnad_enable_mbox_irq(struct bnad *bnad) { - int irq = BNAD_GET_MBOX_IRQ(bnad); - - if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) - if (bnad->cfg_flags & BNAD_CF_MSIX) - enable_irq(irq); + clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags); BNAD_UPDATE_CTR(bnad, mbox_intr_enabled); } @@ -690,14 +677,19 @@ bnad_enable_mbox_irq(struct bnad *bnad) static void bnad_disable_mbox_irq(struct bnad *bnad) { - int irq = BNAD_GET_MBOX_IRQ(bnad); + set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags); + BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); +} - if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) - if (bnad->cfg_flags & BNAD_CF_MSIX) - disable_irq_nosync(irq); +static void +bnad_set_netdev_perm_addr(struct bnad *bnad) +{ + struct net_device *netdev = bnad->netdev; - BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); + memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len); + if (is_zero_ether_addr(netdev->dev_addr)) + memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len); } /* Control Path Handlers */ @@ -755,11 +747,14 @@ bnad_cb_port_link_status(struct bnad *bnad, if (link_up) { if (!netif_carrier_ok(bnad->netdev)) { + struct bna_tcb *tcb = bnad->tx_info[0].tcb[0]; + if (!tcb) + return; pr_warn("bna: %s link up\n", bnad->netdev->name); netif_carrier_on(bnad->netdev); BNAD_UPDATE_CTR(bnad, link_toggle); - if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) { + if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) { /* Force an immediate Transmit Schedule */ pr_info("bna: %s TX_STARTED\n", bnad->netdev->name); @@ -807,6 +802,18 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb) { struct bnad_tx_info *tx_info = (struct bnad_tx_info *)tcb->txq->tx->priv; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + + while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + cpu_relax(); + + bnad_free_all_txbufs(bnad, tcb); + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); tx_info->tcb[tcb->id] = NULL; } @@ -821,6 +828,12 @@ bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb) unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH; } +static void +bnad_cb_rcb_destroy(struct bnad *bnad, struct bna_rcb *rcb) +{ + bnad_free_all_rxbufs(bnad, rcb); +} + static void bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb) { @@ -849,7 +862,7 @@ bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb) if (tx_info != &bnad->tx_info[0]) return; - clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags); + clear_bit(BNAD_TXQ_TX_STARTED, &tcb->flags); netif_stop_queue(bnad->netdev); pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name); } @@ -857,30 +870,15 @@ bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb) static void bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb) { - if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) - return; - - if (netif_carrier_ok(bnad->netdev)) { - pr_info("bna: %s TX_STARTED\n", bnad->netdev->name); - netif_wake_queue(bnad->netdev); - BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); - } -} - -static void -bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) -{ - struct bnad_unmap_q *unmap_q; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; - if (!tcb || (!tcb->unmap_q)) + if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) return; - unmap_q = tcb->unmap_q; - if (!unmap_q->unmap_array) - return; + clear_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags); - if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) - return; + while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + cpu_relax(); bnad_free_all_txbufs(bnad, tcb); @@ -889,21 +887,45 @@ bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) smp_mb__before_clear_bit(); clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + + /* + * Workaround for first device enable failure & we + * get a 0 MAC address. We try to get the MAC address + * again here. + */ + if (is_zero_ether_addr(&bnad->perm_addr.mac[0])) { + bna_port_mac_get(&bnad->bna.port, &bnad->perm_addr); + bnad_set_netdev_perm_addr(bnad); + } + + set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags); + + if (netif_carrier_ok(bnad->netdev)) { + pr_info("bna: %s TX_STARTED\n", bnad->netdev->name); + netif_wake_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } +} + +static void +bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) +{ + /* Delay only once for the whole Tx Path Shutdown */ + if (!test_and_set_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags)) + mdelay(BNAD_TXRX_SYNC_MDELAY); } static void bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_ccb *ccb) { - bnad_cq_cmpl_init(bnad, ccb); - - bnad_free_rxbufs(bnad, ccb->rcb[0]); clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags); - if (ccb->rcb[1]) { - bnad_free_rxbufs(bnad, ccb->rcb[1]); + if (ccb->rcb[1]) clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags); - } + + if (!test_and_set_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags)) + mdelay(BNAD_TXRX_SYNC_MDELAY); } static void @@ -911,6 +933,13 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb) { struct bnad_unmap_q *unmap_q = rcb->unmap_q; + clear_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags); + + if (rcb == rcb->cq->ccb->rcb[0]) + bnad_cq_cmpl_init(bnad, rcb->cq->ccb); + + bnad_free_all_rxbufs(bnad, rcb); + set_bit(BNAD_RXQ_STARTED, &rcb->flags); /* Now allocate & post buffers for this RCB */ @@ -1047,7 +1076,7 @@ bnad_mbox_irq_free(struct bnad *bnad, spin_unlock_irqrestore(&bnad->bna_lock, flags); irq = BNAD_GET_MBOX_IRQ(bnad); - free_irq(irq, bnad->netdev); + free_irq(irq, bnad); kfree(intr_info->idl); } @@ -1061,7 +1090,7 @@ static int bnad_mbox_irq_alloc(struct bnad *bnad, struct bna_intr_info *intr_info) { - int err; + int err = 0; unsigned long flags; u32 irq; irq_handler_t irq_handler; @@ -1096,22 +1125,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad, */ set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags); + BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); + err = request_irq(irq, irq_handler, flags, - bnad->mbox_irq_name, bnad->netdev); + bnad->mbox_irq_name, bnad); if (err) { kfree(intr_info->idl); intr_info->idl = NULL; - return err; } - spin_lock_irqsave(&bnad->bna_lock, flags); - - if (bnad->cfg_flags & BNAD_CF_MSIX) - disable_irq_nosync(irq); - - spin_unlock_irqrestore(&bnad->bna_lock, flags); - return 0; + return err; } static void @@ -1555,62 +1579,19 @@ poll_exit: return rcvd; } -static int -bnad_napi_poll_txrx(struct napi_struct *napi, int budget) -{ - struct bnad_rx_ctrl *rx_ctrl = - container_of(napi, struct bnad_rx_ctrl, napi); - struct bna_ccb *ccb; - struct bnad *bnad; - int rcvd = 0; - int i, j; - - ccb = rx_ctrl->ccb; - - bnad = ccb->bnad; - - if (!netif_carrier_ok(bnad->netdev)) - goto poll_exit; - - /* Handle Tx Completions, if any */ - for (i = 0; i < bnad->num_tx; i++) { - for (j = 0; j < bnad->num_txq_per_tx; j++) - bnad_tx(bnad, bnad->tx_info[i].tcb[j]); - } - - /* Handle Rx Completions */ - rcvd = bnad_poll_cq(bnad, ccb, budget); - if (rcvd == budget) - return rcvd; -poll_exit: - napi_complete((napi)); - - BNAD_UPDATE_CTR(bnad, netif_rx_complete); - - bnad_enable_txrx_irqs(bnad); - return rcvd; -} - static void bnad_napi_enable(struct bnad *bnad, u32 rx_id) { - int (*napi_poll) (struct napi_struct *, int); struct bnad_rx_ctrl *rx_ctrl; int i; - unsigned long flags; - - spin_lock_irqsave(&bnad->bna_lock, flags); - if (bnad->cfg_flags & BNAD_CF_MSIX) - napi_poll = bnad_napi_poll_rx; - else - napi_poll = bnad_napi_poll_txrx; - spin_unlock_irqrestore(&bnad->bna_lock, flags); /* Initialize & enable NAPI */ for (i = 0; i < bnad->num_rxp_per_rx; i++) { rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i]; + netif_napi_add(bnad->netdev, &rx_ctrl->napi, - napi_poll, 64); + bnad_napi_poll_rx, 64); + napi_enable(&rx_ctrl->napi); } } @@ -1825,6 +1806,7 @@ bnad_setup_rx(struct bnad *bnad, uint rx_id) /* Initialize the Rx event handlers */ rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup; + rx_cbfn.rcb_destroy_cbfn = bnad_cb_rcb_destroy; rx_cbfn.rcb_destroy_cbfn = NULL; rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup; rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy; @@ -2152,16 +2134,6 @@ bnad_q_num_adjust(struct bnad *bnad, int msix_vectors) bnad->num_rxp_per_rx = 1; } -static void -bnad_set_netdev_perm_addr(struct bnad *bnad) -{ - struct net_device *netdev = bnad->netdev; - - memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len); - if (is_zero_ether_addr(netdev->dev_addr)) - memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len); -} - /* Enable / disable device */ static void bnad_device_disable(struct bnad *bnad) @@ -2433,21 +2405,21 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } + tx_id = 0; + + tx_info = &bnad->tx_info[tx_id]; + tcb = tx_info->tcb[tx_id]; + unmap_q = tcb->unmap_q; + /* * Takes care of the Tx that is scheduled between clearing the flag * and the netif_stop_queue() call. */ - if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) { + if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) { dev_kfree_skb(skb); return NETDEV_TX_OK; } - tx_id = 0; - - tx_info = &bnad->tx_info[tx_id]; - tcb = tx_info->tcb[tx_id]; - unmap_q = tcb->unmap_q; - vectors = 1 + skb_shinfo(skb)->nr_frags; if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) { dev_kfree_skb(skb); @@ -2462,7 +2434,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) tcb->consumer_index && !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) { acked = bnad_free_txbufs(bnad, tcb); - bna_ib_ack(tcb->i_dbell, acked); + if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) + bna_ib_ack(tcb->i_dbell, acked); smp_mb__before_clear_bit(); clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); } else { @@ -2624,6 +2597,10 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) tcb->producer_index = txq_prod; smp_mb(); + + if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) + return NETDEV_TX_OK; + bna_txq_prod_indx_doorbell(tcb); if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index) @@ -3066,7 +3043,7 @@ bnad_pci_probe(struct pci_dev *pdev, /* * PCI initialization * Output : using_dac = 1 for 64 bit DMA - * = 0 for 32 bit DMA + * = 0 for 32 bit DMA */ err = bnad_pci_init(bnad, pdev, &using_dac); if (err) diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index ebc3a9078642..f59685a5543d 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -51,6 +51,7 @@ */ struct bnad_rx_ctrl { struct bna_ccb *ccb; + unsigned long flags; struct napi_struct napi; }; @@ -82,6 +83,7 @@ struct bnad_rx_ctrl { /* Bit positions for tcb->flags */ #define BNAD_TXQ_FREE_SENT 0 +#define BNAD_TXQ_TX_STARTED 1 /* Bit positions for rcb->flags */ #define BNAD_RXQ_REFILL 0 @@ -199,12 +201,12 @@ struct bnad_unmap_q { /* Set, tested & cleared using xxx_bit() functions */ /* Values indicated bit positions */ #define BNAD_RF_CEE_RUNNING 1 -#define BNAD_RF_HW_ERROR 2 -#define BNAD_RF_MBOX_IRQ_DISABLED 3 -#define BNAD_RF_TX_STARTED 4 -#define BNAD_RF_RX_STARTED 5 -#define BNAD_RF_DIM_TIMER_RUNNING 6 -#define BNAD_RF_STATS_TIMER_RUNNING 7 +#define BNAD_RF_MBOX_IRQ_DISABLED 2 +#define BNAD_RF_RX_STARTED 3 +#define BNAD_RF_DIM_TIMER_RUNNING 4 +#define BNAD_RF_STATS_TIMER_RUNNING 5 +#define BNAD_RF_TX_SHUTDOWN_DELAYED 6 +#define BNAD_RF_RX_SHUTDOWN_DELAYED 7 struct bnad { struct net_device *netdev; @@ -320,9 +322,11 @@ extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 #define bnad_enable_rx_irq_unsafe(_ccb) \ { \ - bna_ib_coalescing_timer_set((_ccb)->i_dbell, \ - (_ccb)->rx_coalescing_timeo); \ - bna_ib_ack((_ccb)->i_dbell, 0); \ + if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) {\ + bna_ib_coalescing_timer_set((_ccb)->i_dbell, \ + (_ccb)->rx_coalescing_timeo); \ + bna_ib_ack((_ccb)->i_dbell, 0); \ + } \ } #define bnad_dim_timer_running(_bnad) \ -- cgit v1.2.3-59-g8ed1b From 0613ecfc94b13e86c9ff1252fd63e35a94475cd6 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:02 +0000 Subject: bna: Port enable disable sync and txq priority fix Change Details: - Fixed port enable/disable sync through a change in LL port state machine - Change txq->priority masking to 0x7 (3 bits) from 0x3 (2 bits) Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bna.h | 4 +- drivers/net/bna/bna_ctrl.c | 136 ++++++++++++++++++++++++++++++++++---------- drivers/net/bna/bna_txrx.c | 8 +-- drivers/net/bna/bna_types.h | 7 ++- 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h index df6676bbc84e..fd93f7652639 100644 --- a/drivers/net/bna/bna.h +++ b/drivers/net/bna/bna.h @@ -390,8 +390,8 @@ void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe); /* API for RX */ int bna_port_mtu_get(struct bna_port *port); -void bna_llport_admin_up(struct bna_llport *llport); -void bna_llport_admin_down(struct bna_llport *llport); +void bna_llport_rx_started(struct bna_llport *llport); +void bna_llport_rx_stopped(struct bna_llport *llport); /* API for BNAD */ void bna_port_enable(struct bna_port *port); diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index 07b26598546e..68e4c5eced53 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -59,14 +59,70 @@ bna_port_cb_link_down(struct bna_port *port, int status) port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN); } +static inline int +llport_can_be_up(struct bna_llport *llport) +{ + int ready = 0; + if (llport->type == BNA_PORT_T_REGULAR) + ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) && + (llport->flags & BNA_LLPORT_F_RX_STARTED) && + (llport->flags & BNA_LLPORT_F_PORT_ENABLED)); + else + ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) && + (llport->flags & BNA_LLPORT_F_RX_STARTED) && + !(llport->flags & BNA_LLPORT_F_PORT_ENABLED)); + return ready; +} + +#define llport_is_up llport_can_be_up + +enum bna_llport_event { + LLPORT_E_START = 1, + LLPORT_E_STOP = 2, + LLPORT_E_FAIL = 3, + LLPORT_E_UP = 4, + LLPORT_E_DOWN = 5, + LLPORT_E_FWRESP_UP_OK = 6, + LLPORT_E_FWRESP_UP_FAIL = 7, + LLPORT_E_FWRESP_DOWN = 8 +}; + +static void +bna_llport_cb_port_enabled(struct bna_llport *llport) +{ + llport->flags |= BNA_LLPORT_F_PORT_ENABLED; + + if (llport_can_be_up(llport)) + bfa_fsm_send_event(llport, LLPORT_E_UP); +} + +static void +bna_llport_cb_port_disabled(struct bna_llport *llport) +{ + int llport_up = llport_is_up(llport); + + llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED; + + if (llport_up) + bfa_fsm_send_event(llport, LLPORT_E_DOWN); +} + /** * MBOX */ static int bna_is_aen(u8 msg_id) { - return msg_id == BFI_LL_I2H_LINK_DOWN_AEN || - msg_id == BFI_LL_I2H_LINK_UP_AEN; + switch (msg_id) { + case BFI_LL_I2H_LINK_DOWN_AEN: + case BFI_LL_I2H_LINK_UP_AEN: + case BFI_LL_I2H_PORT_ENABLE_AEN: + case BFI_LL_I2H_PORT_DISABLE_AEN: + return 1; + + default: + return 0; + } } static void @@ -81,6 +137,12 @@ bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg) case BFI_LL_I2H_LINK_DOWN_AEN: bna_port_cb_link_down(&bna->port, aen->reason); break; + case BFI_LL_I2H_PORT_ENABLE_AEN: + bna_llport_cb_port_enabled(&bna->port.llport); + break; + case BFI_LL_I2H_PORT_DISABLE_AEN: + bna_llport_cb_port_disabled(&bna->port.llport); + break; default: break; } @@ -251,16 +313,6 @@ static void bna_llport_start(struct bna_llport *llport); static void bna_llport_stop(struct bna_llport *llport); static void bna_llport_fail(struct bna_llport *llport); -enum bna_llport_event { - LLPORT_E_START = 1, - LLPORT_E_STOP = 2, - LLPORT_E_FAIL = 3, - LLPORT_E_UP = 4, - LLPORT_E_DOWN = 5, - LLPORT_E_FWRESP_UP = 6, - LLPORT_E_FWRESP_DOWN = 7 -}; - enum bna_llport_state { BNA_LLPORT_STOPPED = 1, BNA_LLPORT_DOWN = 2, @@ -320,7 +372,7 @@ bna_llport_sm_stopped(struct bna_llport *llport, /* No-op */ break; - case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_UP_OK: case LLPORT_E_FWRESP_DOWN: /** * These events are received due to flushing of mbox when @@ -366,6 +418,7 @@ bna_llport_sm_down(struct bna_llport *llport, static void bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport) { + BUG_ON(!llport_can_be_up(llport)); /** * NOTE: Do not call bna_fw_llport_up() here. That will over step * mbox due to down_resp_wait -> up_resp_wait transition on event @@ -390,10 +443,14 @@ bna_llport_sm_up_resp_wait(struct bna_llport *llport, bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait); break; - case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_UP_OK: bfa_fsm_set_state(llport, bna_llport_sm_up); break; + case LLPORT_E_FWRESP_UP_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_down); + break; + case LLPORT_E_FWRESP_DOWN: /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */ bna_fw_llport_up(llport); @@ -431,11 +488,12 @@ bna_llport_sm_down_resp_wait(struct bna_llport *llport, bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait); break; - case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_UP_OK: /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */ bna_fw_llport_down(llport); break; + case LLPORT_E_FWRESP_UP_FAIL: case LLPORT_E_FWRESP_DOWN: bfa_fsm_set_state(llport, bna_llport_sm_down); break; @@ -496,11 +554,12 @@ bna_llport_sm_last_resp_wait(struct bna_llport *llport, /* No-op */ break; - case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_UP_OK: /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */ bna_fw_llport_down(llport); break; + case LLPORT_E_FWRESP_UP_FAIL: case LLPORT_E_FWRESP_DOWN: bfa_fsm_set_state(llport, bna_llport_sm_stopped); break; @@ -541,7 +600,14 @@ bna_fw_cb_llport_up(void *arg, int status) struct bna_llport *llport = (struct bna_llport *)arg; bfa_q_qe_init(&llport->mbox_qe.qe); - bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP); + if (status == BFI_LL_CMD_FAIL) { + if (llport->type == BNA_PORT_T_REGULAR) + llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED; + else + llport->flags &= ~BNA_LLPORT_F_ADMIN_UP; + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_FAIL); + } else + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_OK); } static void @@ -588,13 +654,14 @@ bna_port_cb_llport_stopped(struct bna_port *port, static void bna_llport_init(struct bna_llport *llport, struct bna *bna) { - llport->flags |= BNA_LLPORT_F_ENABLED; + llport->flags |= BNA_LLPORT_F_ADMIN_UP; + llport->flags |= BNA_LLPORT_F_PORT_ENABLED; llport->type = BNA_PORT_T_REGULAR; llport->bna = bna; llport->link_status = BNA_LINK_DOWN; - llport->admin_up_count = 0; + llport->rx_started_count = 0; llport->stop_cbfn = NULL; @@ -606,7 +673,8 @@ bna_llport_init(struct bna_llport *llport, struct bna *bna) static void bna_llport_uninit(struct bna_llport *llport) { - llport->flags &= ~BNA_LLPORT_F_ENABLED; + llport->flags &= ~BNA_LLPORT_F_ADMIN_UP; + llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED; llport->bna = NULL; } @@ -628,6 +696,8 @@ bna_llport_stop(struct bna_llport *llport) static void bna_llport_fail(struct bna_llport *llport) { + /* Reset the physical port status to enabled */ + llport->flags |= BNA_LLPORT_F_PORT_ENABLED; bfa_fsm_send_event(llport, LLPORT_E_FAIL); } @@ -638,25 +708,31 @@ bna_llport_state_get(struct bna_llport *llport) } void -bna_llport_admin_up(struct bna_llport *llport) +bna_llport_rx_started(struct bna_llport *llport) { - llport->admin_up_count++; + llport->rx_started_count++; + + if (llport->rx_started_count == 1) { + + llport->flags |= BNA_LLPORT_F_RX_STARTED; - if (llport->admin_up_count == 1) { - llport->flags |= BNA_LLPORT_F_RX_ENABLED; - if (llport->flags & BNA_LLPORT_F_ENABLED) + if (llport_can_be_up(llport)) bfa_fsm_send_event(llport, LLPORT_E_UP); } } void -bna_llport_admin_down(struct bna_llport *llport) +bna_llport_rx_stopped(struct bna_llport *llport) { - llport->admin_up_count--; + int llport_up = llport_is_up(llport); + + llport->rx_started_count--; + + if (llport->rx_started_count == 0) { + + llport->flags &= ~BNA_LLPORT_F_RX_STARTED; - if (llport->admin_up_count == 0) { - llport->flags &= ~BNA_LLPORT_F_RX_ENABLED; - if (llport->flags & BNA_LLPORT_F_ENABLED) + if (llport_up) bfa_fsm_send_event(llport, LLPORT_E_DOWN); } } diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c index ad93fdb0f427..fb6cf1f19c99 100644 --- a/drivers/net/bna/bna_txrx.c +++ b/drivers/net/bna/bna_txrx.c @@ -1947,7 +1947,7 @@ bna_rx_sm_started_entry(struct bna_rx *rx) bna_ib_ack(&rxp->cq.ib->door_bell, 0); } - bna_llport_admin_up(&rx->bna->port.llport); + bna_llport_rx_started(&rx->bna->port.llport); } void @@ -1955,13 +1955,13 @@ bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event) { switch (event) { case RX_E_FAIL: - bna_llport_admin_down(&rx->bna->port.llport); + bna_llport_rx_stopped(&rx->bna->port.llport); bfa_fsm_set_state(rx, bna_rx_sm_stopped); rx_ib_fail(rx); bna_rxf_fail(&rx->rxf); break; case RX_E_STOP: - bna_llport_admin_down(&rx->bna->port.llport); + bna_llport_rx_stopped(&rx->bna->port.llport); bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait); break; default: @@ -3373,7 +3373,7 @@ __bna_txq_start(struct bna_tx *tx, struct bna_txq *txq) txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE; txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) | - (txq->priority & 0x3)); + (txq->priority & 0x7)); txq_cfg.wvc_n_cquota_n_rquota = ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) | (BFI_TX_MAX_WRR_QUOTA & 0xfff)); diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h index 6877310f6ef4..d79fd98921b8 100644 --- a/drivers/net/bna/bna_types.h +++ b/drivers/net/bna/bna_types.h @@ -249,8 +249,9 @@ enum bna_link_status { }; enum bna_llport_flags { - BNA_LLPORT_F_ENABLED = 1, - BNA_LLPORT_F_RX_ENABLED = 2 + BNA_LLPORT_F_ADMIN_UP = 1, + BNA_LLPORT_F_PORT_ENABLED = 2, + BNA_LLPORT_F_RX_STARTED = 4 }; enum bna_port_flags { @@ -405,7 +406,7 @@ struct bna_llport { enum bna_link_status link_status; - int admin_up_count; + int rx_started_count; void (*stop_cbfn)(struct bna_port *, enum bna_cb_status); -- cgit v1.2.3-59-g8ed1b From 815f41e74031d6dc6d6dd988f58c03a1d72d02b9 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:03 +0000 Subject: bna: Fix ethtool register dump and reordered an API Change Details: - Removed semaphore register dump from ethtool - Moved netif_carrier_off() call to before calling bna_init() Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 8 +++----- drivers/net/bna/bnad_ethtool.c | 4 ---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 3c405022d2bb..5e7a0307f853 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -3061,6 +3061,9 @@ bnad_pci_probe(struct pci_dev *pdev, /* Initialize netdev structure, set up ethtool ops */ bnad_netdev_init(bnad, using_dac); + /* Set link to down state */ + netif_carrier_off(netdev); + bnad_enable_msix(bnad); /* Get resource requirement form bna */ @@ -3114,11 +3117,6 @@ bnad_pci_probe(struct pci_dev *pdev, mutex_unlock(&bnad->conf_mutex); - /* - * Make sure the link appears down to the stack - */ - netif_carrier_off(netdev); - /* Finally, reguister with net_device layer */ err = register_netdev(netdev); if (err) { diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index 11fa2ea842c1..3011110c2023 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -330,10 +330,6 @@ do { \ BNAD_GET_REG(PCIE_MISC_REG); - BNAD_GET_REG(HOST_SEM0_REG); - BNAD_GET_REG(HOST_SEM1_REG); - BNAD_GET_REG(HOST_SEM2_REG); - BNAD_GET_REG(HOST_SEM3_REG); BNAD_GET_REG(HOST_SEM0_INFO_REG); BNAD_GET_REG(HOST_SEM1_INFO_REG); BNAD_GET_REG(HOST_SEM2_INFO_REG); -- cgit v1.2.3-59-g8ed1b From 886f7fedb0cee56acca7620d89186669273d3d56 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:04 +0000 Subject: bna: Enable pure priority tagged packet reception and rxf uninit cleanup fix Change Details: - Enable reception of pure priority tagged packets by default by turning on VLAN Id = 0 - Clear the promiscuous mode, all multicast mode flags when bna_rxf_uninit is called Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bna_txrx.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c index fb6cf1f19c99..50766181d585 100644 --- a/drivers/net/bna/bna_txrx.c +++ b/drivers/net/bna/bna_txrx.c @@ -1441,12 +1441,16 @@ bna_rxf_init(struct bna_rxf *rxf, memset(rxf->vlan_filter_table, 0, (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32))); + /* Set up VLAN 0 for pure priority tagged packets */ + rxf->vlan_filter_table[0] |= 1; + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); } static void bna_rxf_uninit(struct bna_rxf *rxf) { + struct bna *bna = rxf->rx->bna; struct bna_mac *mac; bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment); @@ -1473,6 +1477,27 @@ bna_rxf_uninit(struct bna_rxf *rxf) bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); } + /* Turn off pending promisc mode */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* system promisc state should be pending */ + BUG_ON(!(bna->rxf_promisc_id == rxf->rxf_id)); + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + bna->rxf_promisc_id = BFI_MAX_RXF; + } + /* Promisc mode should not be active */ + BUG_ON(rxf->rxmode_active & BNA_RXMODE_PROMISC); + + /* Turn off pending all-multi mode */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + } + /* Allmulti mode should not be active */ + BUG_ON(rxf->rxmode_active & BNA_RXMODE_ALLMULTI); + rxf->rx = NULL; } -- cgit v1.2.3-59-g8ed1b From f7c0fa4cd5dcf58dd95b216d2c33444a3b4a44e0 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:05 +0000 Subject: bna: Fix for TX queue Change Details: - Call netif_wake_queue() if we have freed up sufficient elements at the end of completion processing - Add netif_queue_stopped counter back to bnad_drv_stats {} - Get netif_queue_stopped value from stack - Remove BUG_ON() on value returned by pci_unmap_addr() Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 20 ++++++++++++++++---- drivers/net/bna/bnad.h | 7 +++++-- drivers/net/bna/bnad_ethtool.c | 4 ++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 5e7a0307f853..f77593638c57 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -109,7 +109,7 @@ static void bnad_free_all_txbufs(struct bnad *bnad, struct bna_tcb *tcb) { - u16 unmap_cons; + u32 unmap_cons; struct bnad_unmap_q *unmap_q = tcb->unmap_q; struct bnad_skb_unmap *unmap_array; struct sk_buff *skb = NULL; @@ -244,7 +244,7 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr) { struct bnad *bnad = (struct bnad *)bnad_ptr; struct bna_tcb *tcb; - u32 acked; + u32 acked = 0; int i, j; for (i = 0; i < bnad->num_tx; i++) { @@ -263,6 +263,20 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr) smp_mb__before_clear_bit(); clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); } + if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, + &tcb->flags))) + continue; + if (netif_queue_stopped(bnad->netdev)) { + if (acked && netif_carrier_ok(bnad->netdev) && + BNA_QE_FREE_CNT(tcb, tcb->q_depth) >= + BNAD_NETIF_WAKE_THRESHOLD) { + netif_wake_queue(bnad->netdev); + /* TODO */ + /* Counters for individual TxQs? */ + BNAD_UPDATE_CTR(bnad, + netif_queue_wakeup); + } + } } } } @@ -334,8 +348,6 @@ bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) skb = unmap_q->unmap_array[unmap_cons].skb; if (!skb) continue; - BUG_ON(!(pci_unmap_addr( - &unmap_q->unmap_array[unmap_cons], dma_addr))); unmap_q->unmap_array[unmap_cons].skb = NULL; pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q-> unmap_array[unmap_cons], diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index f59685a5543d..1954dea4cbf2 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -126,6 +126,7 @@ struct bnad_completion { struct bnad_drv_stats { u64 netif_queue_stop; u64 netif_queue_wakeup; + u64 netif_queue_stopped; u64 tso4; u64 tso6; u64 tso_err; @@ -308,8 +309,10 @@ extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id); extern void bnad_dim_timer_start(struct bnad *bnad); /* Statistics */ -extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); -extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); +extern void bnad_netdev_qstats_fill(struct bnad *bnad, + struct rtnl_link_stats64 *stats); +extern void bnad_netdev_hwstats_fill(struct bnad *bnad, + struct rtnl_link_stats64 *stats); /** * MACROS diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index 3011110c2023..99be5ae91991 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -68,6 +68,7 @@ static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { "netif_queue_stop", "netif_queue_wakeup", + "netif_queue_stopped", "tso4", "tso6", "tso_err", @@ -1180,6 +1181,9 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, bi = sizeof(*net_stats64) / sizeof(u64); + /* Get netif_queue_stopped from stack */ + bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev); + /* Fill driver stats into ethtool buffers */ stats64 = (u64 *)&bnad->stats.drv_stats; for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++) -- cgit v1.2.3-59-g8ed1b From 2c7d38210ff8e65f8961699bce92c273c77d113c Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:06 +0000 Subject: bna: IOC uninit check and misc cleanup Change Details: - Added a check in ioc firmware lock function to see if IOC is in BFI_IOC_UNINIT state or not. If it is not in UNINIT state and the last IOC boot was not done by OS driver, force IOC state to BFI_IOC_UNINIT - Unused macro and API cleanup Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bfa_defs_mfg_comm.h | 22 ------------------ drivers/net/bna/bfa_ioc.c | 45 ++----------------------------------- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h index 987978fcb3fe..fdd677618361 100644 --- a/drivers/net/bna/bfa_defs_mfg_comm.h +++ b/drivers/net/bna/bfa_defs_mfg_comm.h @@ -95,28 +95,6 @@ enum { (type) == BFA_MFG_TYPE_CNA10P1 || \ bfa_mfg_is_mezz(type))) -/** - * Check if the card having old wwn/mac handling - */ -#define bfa_mfg_is_old_wwn_mac_model(type) (( \ - (type) == BFA_MFG_TYPE_FC8P2 || \ - (type) == BFA_MFG_TYPE_FC8P1 || \ - (type) == BFA_MFG_TYPE_FC4P2 || \ - (type) == BFA_MFG_TYPE_FC4P1 || \ - (type) == BFA_MFG_TYPE_CNA10P2 || \ - (type) == BFA_MFG_TYPE_CNA10P1 || \ - (type) == BFA_MFG_TYPE_JAYHAWK || \ - (type) == BFA_MFG_TYPE_WANCHESE)) - -#define bfa_mfg_increment_wwn_mac(m, i) \ -do { \ - u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \ - t += (i); \ - (m)[0] = (t >> 16) & 0xFF; \ - (m)[1] = (t >> 8) & 0xFF; \ - (m)[2] = t & 0xFF; \ -} while (0) - #define bfa_mfg_adapter_prop_init_flash(card_type, prop) \ do { \ switch ((card_type)) { \ diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index e94e5aa97515..8ed147e803c3 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -58,9 +58,6 @@ #define bfa_ioc_notify_hbfail(__ioc) \ ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) -#define bfa_ioc_is_optrom(__ioc) \ - (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ) - #define bfa_ioc_mbox_cmd_pending(__ioc) \ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ readl((__ioc)->ioc_regs.hfn_mbox_cmd)) @@ -101,7 +98,6 @@ static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer); static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); -static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc); /** * IOC state machine events @@ -865,12 +861,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc) { struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; - /** - * If bios/efi boot (flash based) -- return true - */ - if (bfa_ioc_is_optrom(ioc)) - return true; - bfa_nw_ioc_fwver_get(ioc, &fwhdr); drv_fwhdr = (struct bfi_ioc_image_hdr *) bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); @@ -934,13 +924,8 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) /** * If IOC function is disabled and firmware version is same, * just re-enable IOC. - * - * If option rom, IOC must not be in operational state. With - * convergence, IOC will be in operational state when 2nd driver - * is loaded. */ - if (ioc_fwstate == BFI_IOC_DISABLED || - (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) { + if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { /** * When using MSI-X any pending firmware ready event should * be flushed. Otherwise MSI-X interrupts are not delivered. @@ -1078,11 +1063,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, */ bfa_ioc_lmem_init(ioc); - /** - * Flash based firmware boot - */ - if (bfa_ioc_is_optrom(ioc)) - boot_type = BFI_BOOT_TYPE_FLASH; fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); pgnum = bfa_ioc_smem_pgnum(ioc, loff); @@ -1689,28 +1669,7 @@ bfa_ioc_get_pwwn(struct bfa_ioc *ioc) mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc) { - /* - * Currently mfg mac is used as FCoE enode mac (not configured by PBC) - */ - if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) - return bfa_ioc_get_mfg_mac(ioc); - else - return ioc->attr->mac; -} - -static mac_t -bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc) -{ - mac_t m; - - m = ioc->attr->mfg_mac; - if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) - m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); - else - bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), - bfa_ioc_pcifn(ioc)); - - return m; + return ioc->attr->mac; } /** -- cgit v1.2.3-59-g8ed1b From ce9b9f383775e6de74ca4c93d5c643dc3d76dd3c Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:07 +0000 Subject: bna: Removed unused code Change Details: - Remove unused APIs and code cleanup Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bna_ctrl.c | 241 +------------------------------------------- drivers/net/bna/bna_txrx.c | 11 +- drivers/net/bna/bna_types.h | 4 +- 3 files changed, 3 insertions(+), 253 deletions(-) diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index 68e4c5eced53..e1527472b961 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -2132,37 +2132,6 @@ rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status) bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); } -static void -__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status) -{ - struct bna_rx_fndb_ram *rx_fndb_ram; - u32 ctrl_flags; - int i; - - rx_fndb_ram = (struct bna_rx_fndb_ram *) - BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva, - RX_FNDB_RAM_BASE_OFFSET); - - for (i = 0; i < BFI_MAX_RXF; i++) { - if (status == BNA_STATUS_T_ENABLED) { - if (i == rxf->rxf_id) - continue; - - ctrl_flags = - readl(&rx_fndb_ram[i].control_flags); - ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; - writel(ctrl_flags, - &rx_fndb_ram[i].control_flags); - } else { - ctrl_flags = - readl(&rx_fndb_ram[i].control_flags); - ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; - writel(ctrl_flags, - &rx_fndb_ram[i].control_flags); - } - } -} - int rxf_process_packet_filter_ucast(struct bna_rxf *rxf) { @@ -2228,46 +2197,6 @@ rxf_process_packet_filter_promisc(struct bna_rxf *rxf) return 0; } -int -rxf_process_packet_filter_default(struct bna_rxf *rxf) -{ - struct bna *bna = rxf->rx->bna; - - /* Enable/disable default mode */ - if (is_default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask)) { - /* move default configuration from pending -> active */ - default_inactive(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active |= BNA_RXMODE_DEFAULT; - - /* Disable VLAN filter to allow all VLANs */ - __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED); - /* Redirect all other RxF vlan filtering to this one */ - __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED); - rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, - BNA_STATUS_T_ENABLED); - return 1; - } else if (is_default_disable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask)) { - /* move default configuration from pending -> active */ - default_inactive(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; - bna->rxf_default_id = BFI_MAX_RXF; - - /* Revert VLAN filter */ - __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); - /* Stop RxF vlan filter table redirection */ - __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); - rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, - BNA_STATUS_T_DISABLED); - return 1; - } - - return 0; -} - int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf) { @@ -2364,48 +2293,6 @@ rxf_clear_packet_filter_promisc(struct bna_rxf *rxf) return 0; } -int -rxf_clear_packet_filter_default(struct bna_rxf *rxf) -{ - struct bna *bna = rxf->rx->bna; - - /* 8. Execute pending default mode disable command */ - if (is_default_disable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask)) { - /* move default configuration from pending -> active */ - default_inactive(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; - bna->rxf_default_id = BFI_MAX_RXF; - - /* Revert VLAN filter */ - __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); - /* Stop RxF vlan filter table redirection */ - __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); - rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, - BNA_STATUS_T_DISABLED); - return 1; - } - - /* 9. Clear active default mode; move it to pending enable */ - if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { - /* move default configuration from active -> pending */ - default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; - - /* Revert VLAN filter */ - __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); - /* Stop RxF vlan filter table redirection */ - __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); - rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, - BNA_STATUS_T_DISABLED); - return 1; - } - - return 0; -} - int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf) { @@ -2480,28 +2367,6 @@ rxf_reset_packet_filter_promisc(struct bna_rxf *rxf) } -void -rxf_reset_packet_filter_default(struct bna_rxf *rxf) -{ - struct bna *bna = rxf->rx->bna; - - /* 8. Clear pending default mode disable */ - if (is_default_disable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask)) { - default_inactive(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; - bna->rxf_default_id = BFI_MAX_RXF; - } - - /* 9. Move default mode config from active -> pending */ - if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { - default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; - } -} - void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf) { @@ -2591,76 +2456,6 @@ rxf_promisc_disable(struct bna_rxf *rxf) return ret; } -/** - * Should only be called by bna_rxf_mode_set. - * Helps deciding if h/w configuration is needed or not. - * Returns: - * 0 = no h/w change - * 1 = need h/w change - */ -static int -rxf_default_enable(struct bna_rxf *rxf) -{ - struct bna *bna = rxf->rx->bna; - int ret = 0; - - /* There can not be any pending disable command */ - - /* Do nothing if pending enable or already enabled */ - if (is_default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask) || - (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) { - /* Schedule enable */ - } else { - /* Default mode should not be active in the system */ - default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - bna->rxf_default_id = rxf->rxf_id; - ret = 1; - } - - return ret; -} - -/** - * Should only be called by bna_rxf_mode_set. - * Helps deciding if h/w configuration is needed or not. - * Returns: - * 0 = no h/w change - * 1 = need h/w change - */ -static int -rxf_default_disable(struct bna_rxf *rxf) -{ - struct bna *bna = rxf->rx->bna; - int ret = 0; - - /* There can not be any pending disable */ - - /* Turn off pending enable command , if any */ - if (is_default_enable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask)) { - /* Promisc mode should not be active */ - /* system default state should be pending */ - default_inactive(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - /* Remove the default state from the system */ - bna->rxf_default_id = BFI_MAX_RXF; - - /* Schedule disable */ - } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { - /* Default mode should be active in the system */ - default_disable(rxf->rxmode_pending, - rxf->rxmode_pending_bitmask); - ret = 1; - - /* Do nothing if already disabled */ - } else { - } - - return ret; -} - /** * Should only be called by bna_rxf_mode_set. * Helps deciding if h/w configuration is needed or not. @@ -2730,38 +2525,13 @@ bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode, struct bna_rxf *rxf = &rx->rxf; int need_hw_config = 0; - /* Error checks */ + /* Process the commands */ if (is_promisc_enable(new_mode, bitmask)) { /* If promisc mode is already enabled elsewhere in the system */ if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) && (rx->bna->rxf_promisc_id != rxf->rxf_id)) goto err_return; - - /* If default mode is already enabled in the system */ - if (rx->bna->rxf_default_id != BFI_MAX_RXF) - goto err_return; - - /* Trying to enable promiscuous and default mode together */ - if (is_default_enable(new_mode, bitmask)) - goto err_return; - } - - if (is_default_enable(new_mode, bitmask)) { - /* If default mode is already enabled elsewhere in the system */ - if ((rx->bna->rxf_default_id != BFI_MAX_RXF) && - (rx->bna->rxf_default_id != rxf->rxf_id)) { - goto err_return; - } - - /* If promiscuous mode is already enabled in the system */ - if (rx->bna->rxf_promisc_id != BFI_MAX_RXF) - goto err_return; - } - - /* Process the commands */ - - if (is_promisc_enable(new_mode, bitmask)) { if (rxf_promisc_enable(rxf)) need_hw_config = 1; } else if (is_promisc_disable(new_mode, bitmask)) { @@ -2769,14 +2539,6 @@ bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode, need_hw_config = 1; } - if (is_default_enable(new_mode, bitmask)) { - if (rxf_default_enable(rxf)) - need_hw_config = 1; - } else if (is_default_disable(new_mode, bitmask)) { - if (rxf_default_disable(rxf)) - need_hw_config = 1; - } - if (is_allmulti_enable(new_mode, bitmask)) { if (rxf_allmulti_enable(rxf)) need_hw_config = 1; @@ -3202,7 +2964,6 @@ bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev, bna_mcam_mod_init(&bna->mcam_mod, bna, res_info); - bna->rxf_default_id = BFI_MAX_RXF; bna->rxf_promisc_id = BFI_MAX_RXF; /* Mbox q element for posting stat request to f/w */ diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c index 50766181d585..58c7664040dc 100644 --- a/drivers/net/bna/bna_txrx.c +++ b/drivers/net/bna/bna_txrx.c @@ -1226,8 +1226,7 @@ rxf_process_packet_filter_vlan(struct bna_rxf *rxf) /* Apply the VLAN filter */ if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) { rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING; - if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) && - !(rxf->rxmode_active & BNA_RXMODE_DEFAULT)) + if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC)) __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); } @@ -1276,9 +1275,6 @@ rxf_process_packet_filter(struct bna_rxf *rxf) if (rxf_process_packet_filter_promisc(rxf)) return 1; - if (rxf_process_packet_filter_default(rxf)) - return 1; - if (rxf_process_packet_filter_allmulti(rxf)) return 1; @@ -1340,9 +1336,6 @@ rxf_clear_packet_filter(struct bna_rxf *rxf) if (rxf_clear_packet_filter_promisc(rxf)) return 1; - if (rxf_clear_packet_filter_default(rxf)) - return 1; - if (rxf_clear_packet_filter_allmulti(rxf)) return 1; @@ -1389,8 +1382,6 @@ rxf_reset_packet_filter(struct bna_rxf *rxf) rxf_reset_packet_filter_promisc(rxf); - rxf_reset_packet_filter_default(rxf); - rxf_reset_packet_filter_allmulti(rxf); } diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h index d79fd98921b8..b9c134f7ad31 100644 --- a/drivers/net/bna/bna_types.h +++ b/drivers/net/bna/bna_types.h @@ -165,8 +165,7 @@ enum bna_rxp_type { enum bna_rxmode { BNA_RXMODE_PROMISC = 1, - BNA_RXMODE_DEFAULT = 2, - BNA_RXMODE_ALLMULTI = 4 + BNA_RXMODE_ALLMULTI = 2 }; enum bna_rx_event { @@ -1118,7 +1117,6 @@ struct bna { struct bna_rit_mod rit_mod; - int rxf_default_id; int rxf_promisc_id; struct bna_mbox_qe mbox_qe; -- cgit v1.2.3-59-g8ed1b From aad75b66f1d3784514351f06bc589c55d5325bc8 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:08 +0000 Subject: bna: Restore VLAN filter table Change Details: - Retrieve the VLAN configuration from the networking stack and apply it to the base interface during ifconfig up Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index f77593638c57..140ea95b9150 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -566,7 +566,8 @@ bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) { unsigned long flags; - spin_lock_irqsave(&bnad->bna_lock, flags); /* Because of polling context */ + /* Because of polling context */ + spin_lock_irqsave(&bnad->bna_lock, flags); bnad_enable_rx_irq_unsafe(ccb); spin_unlock_irqrestore(&bnad->bna_lock, flags); } @@ -1962,6 +1963,27 @@ bnad_enable_default_bcast(struct bnad *bnad) return 0; } +/* Called with bnad_conf_lock() held */ +static void +bnad_restore_vlans(struct bnad *bnad, u32 rx_id) +{ + u16 vlan_id; + unsigned long flags; + + if (!bnad->vlan_grp) + return; + + BUG_ON(!(VLAN_N_VID == (BFI_MAX_VLAN + 1))); + + for (vlan_id = 0; vlan_id < VLAN_N_VID; vlan_id++) { + if (!vlan_group_get_device(bnad->vlan_grp, vlan_id)) + continue; + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vlan_id); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + } +} + /* Statistics utilities */ void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats) @@ -2337,6 +2359,9 @@ bnad_open(struct net_device *netdev) /* Enable broadcast */ bnad_enable_default_bcast(bnad); + /* Restore VLANs, if any */ + bnad_restore_vlans(bnad, 0); + /* Set the UCAST address */ spin_lock_irqsave(&bnad->bna_lock, flags); bnad_mac_addr_set_locked(bnad, netdev->dev_addr); @@ -3021,7 +3046,7 @@ static int __devinit bnad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pcidev_id) { - bool using_dac; + bool using_dac = false; int err; struct bnad *bnad; struct bna *bna; -- cgit v1.2.3-59-g8ed1b From 1d32f7696286eef9e5644eb57e79a36756274357 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:09 +0000 Subject: bna: IOC failure auto recovery fix Change Details: - Made IOC auto_recovery synchronized and not timer based. - Only one PCI function will attempt to recover and reinitialize the ASIC on a failure, that too after all the active PCI functions acknowledge the IOC failure. Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bfa_defs.h | 22 +- drivers/net/bna/bfa_ioc.c | 1178 +++++++++++++++++++++++++++++++----------- drivers/net/bna/bfa_ioc.h | 49 +- drivers/net/bna/bfa_ioc_ct.c | 102 +++- drivers/net/bna/bfi_ctreg.h | 41 +- drivers/net/bna/bna.h | 2 - drivers/net/bna/bnad.c | 21 +- 7 files changed, 1063 insertions(+), 352 deletions(-) diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h index 29c1b8de2c2d..2ea0dfe1cedc 100644 --- a/drivers/net/bna/bfa_defs.h +++ b/drivers/net/bna/bfa_defs.h @@ -112,16 +112,18 @@ struct bfa_ioc_pci_attr { * IOC states */ enum bfa_ioc_state { - BFA_IOC_RESET = 1, /*!< IOC is in reset state */ - BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ - BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */ - BFA_IOC_GETATTR = 4, /*!< IOC is being configured */ - BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */ - BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */ - BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */ - BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */ - BFA_IOC_DISABLED = 9, /*!< IOC is disabled */ - BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */ + BFA_IOC_UNINIT = 1, /*!< IOC is in uninit state */ + BFA_IOC_RESET = 2, /*!< IOC is in reset state */ + BFA_IOC_SEMWAIT = 3, /*!< Waiting for IOC h/w semaphore */ + BFA_IOC_HWINIT = 4, /*!< IOC h/w is being initialized */ + BFA_IOC_GETATTR = 5, /*!< IOC is being configured */ + BFA_IOC_OPERATIONAL = 6, /*!< IOC is operational */ + BFA_IOC_INITFAIL = 7, /*!< IOC hardware failure */ + BFA_IOC_FAIL = 8, /*!< IOC heart-beat failure */ + BFA_IOC_DISABLING = 9, /*!< IOC is being disabled */ + BFA_IOC_DISABLED = 10, /*!< IOC is disabled */ + BFA_IOC_FWMISMATCH = 11, /*!< IOC f/w different from drivers */ + BFA_IOC_ENABLING = 12, /*!< IOC is being enabled */ }; /** diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index 8ed147e803c3..34933cb9569f 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -26,25 +26,6 @@ * IOC local definitions */ -#define bfa_ioc_timer_start(__ioc) \ - mod_timer(&(__ioc)->ioc_timer, jiffies + \ - msecs_to_jiffies(BFA_IOC_TOV)) -#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer) - -#define bfa_ioc_recovery_timer_start(__ioc) \ - mod_timer(&(__ioc)->ioc_timer, jiffies + \ - msecs_to_jiffies(BFA_IOC_TOV_RECOVER)) - -#define bfa_sem_timer_start(__ioc) \ - mod_timer(&(__ioc)->sem_timer, jiffies + \ - msecs_to_jiffies(BFA_IOC_HWSEM_TOV)) -#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer) - -#define bfa_hb_timer_start(__ioc) \ - mod_timer(&(__ioc)->hb_timer, jiffies + \ - msecs_to_jiffies(BFA_IOC_HB_TOV)) -#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer) - /** * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. */ @@ -55,8 +36,16 @@ ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) -#define bfa_ioc_notify_hbfail(__ioc) \ - ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) +#define bfa_ioc_notify_fail(__ioc) \ + ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) +#define bfa_ioc_sync_join(__ioc) \ + ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) +#define bfa_ioc_sync_leave(__ioc) \ + ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc)) +#define bfa_ioc_sync_ack(__ioc) \ + ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) +#define bfa_ioc_sync_complete(__ioc) \ + ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) #define bfa_ioc_mbox_cmd_pending(__ioc) \ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ @@ -82,6 +71,12 @@ static void bfa_ioc_recover(struct bfa_ioc *ioc); static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc); static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); +static void bfa_ioc_fail_notify(struct bfa_ioc *ioc); +static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc); +static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc); +static void bfa_ioc_pf_initfailed(struct bfa_ioc *ioc); +static void bfa_ioc_pf_failed(struct bfa_ioc *ioc); +static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc); static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param); static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); @@ -100,69 +95,171 @@ static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); /** - * IOC state machine events + * IOC state machine definitions/declarations */ enum ioc_event { - IOC_E_ENABLE = 1, /*!< IOC enable request */ - IOC_E_DISABLE = 2, /*!< IOC disable request */ - IOC_E_TIMEOUT = 3, /*!< f/w response timeout */ - IOC_E_FWREADY = 4, /*!< f/w initialization done */ - IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */ - IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */ - IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */ - IOC_E_HBFAIL = 8, /*!< heartbeat failure */ - IOC_E_HWERROR = 9, /*!< hardware error interrupt */ - IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ - IOC_E_DETACH = 11, /*!< driver detach cleanup */ + IOC_E_RESET = 1, /*!< IOC reset request */ + IOC_E_ENABLE = 2, /*!< IOC enable request */ + IOC_E_DISABLE = 3, /*!< IOC disable request */ + IOC_E_DETACH = 4, /*!< driver detach cleanup */ + IOC_E_ENABLED = 5, /*!< f/w enabled */ + IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */ + IOC_E_DISABLED = 7, /*!< f/w disabled */ + IOC_E_INITFAILED = 8, /*!< failure notice by iocpf sm */ + IOC_E_PFAILED = 9, /*!< failure notice by iocpf sm */ + IOC_E_HBFAIL = 10, /*!< heartbeat failure */ + IOC_E_HWERROR = 11, /*!< hardware error interrupt */ + IOC_E_TIMEOUT = 12, /*!< timeout */ }; +bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event); -bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); static struct bfa_sm_table ioc_sm_table[] = { + {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, - {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH}, - {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH}, - {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT}, - {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT}, - {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT}, + {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, - {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL}, - {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL}, + {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL}, + {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, }; +/** + * IOCPF state machine definitions/declarations + */ + +/* + * Forward declareations for iocpf state machine + */ +static void bfa_iocpf_enable(struct bfa_ioc *ioc); +static void bfa_iocpf_disable(struct bfa_ioc *ioc); +static void bfa_iocpf_fail(struct bfa_ioc *ioc); +static void bfa_iocpf_initfail(struct bfa_ioc *ioc); +static void bfa_iocpf_getattrfail(struct bfa_ioc *ioc); +static void bfa_iocpf_stop(struct bfa_ioc *ioc); + +/** + * IOCPF state machine events + */ +enum iocpf_event { + IOCPF_E_ENABLE = 1, /*!< IOCPF enable request */ + IOCPF_E_DISABLE = 2, /*!< IOCPF disable request */ + IOCPF_E_STOP = 3, /*!< stop on driver detach */ + IOCPF_E_FWREADY = 4, /*!< f/w initialization done */ + IOCPF_E_FWRSP_ENABLE = 5, /*!< enable f/w response */ + IOCPF_E_FWRSP_DISABLE = 6, /*!< disable f/w response */ + IOCPF_E_FAIL = 7, /*!< failure notice by ioc sm */ + IOCPF_E_INITFAIL = 8, /*!< init fail notice by ioc sm */ + IOCPF_E_GETATTRFAIL = 9, /*!< init fail notice by ioc sm */ + IOCPF_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ + IOCPF_E_TIMEOUT = 11, /*!< f/w response timeout */ +}; + +/** + * IOCPF states + */ +enum bfa_iocpf_state { + BFA_IOCPF_RESET = 1, /*!< IOC is in reset state */ + BFA_IOCPF_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ + BFA_IOCPF_HWINIT = 3, /*!< IOC h/w is being initialized */ + BFA_IOCPF_READY = 4, /*!< IOCPF is initialized */ + BFA_IOCPF_INITFAIL = 5, /*!< IOCPF failed */ + BFA_IOCPF_FAIL = 6, /*!< IOCPF failed */ + BFA_IOCPF_DISABLING = 7, /*!< IOCPF is being disabled */ + BFA_IOCPF_DISABLED = 8, /*!< IOCPF is disabled */ + BFA_IOCPF_FWMISMATCH = 9, /*!< IOC f/w different from drivers */ +}; + +bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf, + enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf, enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf, + enum iocpf_event); +bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event); + +static struct bfa_sm_table iocpf_sm_table[] = { + {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, + {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, + {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, + {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT}, + {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT}, + {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT}, + {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY}, + {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL}, + {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL}, + {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL}, + {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL}, + {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING}, + {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING}, + {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED}, +}; + +/** + * IOC State Machine + */ + +/** + * Beginning state. IOC uninit state. + */ +static void +bfa_ioc_sm_uninit_entry(struct bfa_ioc *ioc) +{ +} + +/** + * IOC is in uninit state. + */ +static void +bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_RESET: + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + /** * Reset entry actions -- initialize state machine */ static void bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) { - ioc->retry_count = 0; - ioc->auto_recover = bfa_nw_auto_recover; + bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset); } /** - * Beginning state. IOC is in reset state. + * IOC is in reset state. */ static void bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) { switch (event) { case IOC_E_ENABLE: - bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); break; case IOC_E_DISABLE: @@ -170,6 +267,51 @@ bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) break; case IOC_E_DETACH: + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) +{ + bfa_iocpf_enable(ioc); +} + +/** + * Host IOC function is being enabled, awaiting response from firmware. + * Semaphore is acquired. + */ +static void +bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLED: + bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); + break; + + case IOC_E_PFAILED: + /* !!! fall through !!! */ + case IOC_E_HWERROR: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); + if (event != IOC_E_PFAILED) + bfa_iocpf_initfail(ioc); + break; + + case IOC_E_DISABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_DETACH: + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + bfa_iocpf_stop(ioc); + break; + + case IOC_E_ENABLE: break; default: @@ -181,38 +323,310 @@ bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) * Semaphore should be acquired for version check. */ static void -bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc) +bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) +{ + mod_timer(&ioc->ioc_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV)); + bfa_ioc_send_getattr(ioc); +} + +/** + * IOC configuration in progress. Timer is active. + */ +static void +bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_GETATTR: + del_timer(&ioc->ioc_timer); + bfa_ioc_check_attr_wwns(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_op); + break; + + case IOC_E_PFAILED: + case IOC_E_HWERROR: + del_timer(&ioc->ioc_timer); + /* fall through */ + case IOC_E_TIMEOUT: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); + if (event != IOC_E_PFAILED) + bfa_iocpf_getattrfail(ioc); + break; + + case IOC_E_DISABLE: + del_timer(&ioc->ioc_timer); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_ENABLE: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) +{ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); + bfa_ioc_hb_monitor(ioc); +} + +static void +bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + break; + + case IOC_E_DISABLE: + bfa_ioc_hb_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_PFAILED: + case IOC_E_HWERROR: + bfa_ioc_hb_stop(ioc); + /* !!! fall through !!! */ + case IOC_E_HBFAIL: + bfa_ioc_fail_notify(ioc); + if (ioc->iocpf.auto_recover) + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); + else + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); + + if (event != IOC_E_PFAILED) + bfa_iocpf_fail(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) +{ + bfa_iocpf_disable(ioc); +} + +/** + * IOC is being desabled + */ +static void +bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_DISABLED: + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_HWERROR: + /* + * No state change. Will move to disabled state + * after iocpf sm completes failure processing and + * moves to disabled state. + */ + bfa_iocpf_fail(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * IOC desable completion entry. + */ +static void +bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_disable_comp(ioc); +} + +static void +bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); + break; + + case IOC_E_DISABLE: + ioc->cbfn->disable_cbfn(ioc->bfa); + break; + + case IOC_E_DETACH: + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + bfa_iocpf_stop(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_fail_retry_entry(struct bfa_ioc *ioc) +{ +} + +/** + * Hardware initialization retry. + */ +static void +bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLED: + bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); + break; + + case IOC_E_PFAILED: + case IOC_E_HWERROR: + /** + * Initialization retry failed. + */ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + if (event != IOC_E_PFAILED) + bfa_iocpf_initfail(ioc); + break; + + case IOC_E_INITFAILED: + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); + break; + + case IOC_E_ENABLE: + break; + + case IOC_E_DISABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_DETACH: + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + bfa_iocpf_stop(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_fail_entry(struct bfa_ioc *ioc) { - bfa_ioc_hw_sem_get(ioc); +} + +/** + * IOC failure. + */ +static void +bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + break; + + case IOC_E_DISABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_DETACH: + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + bfa_iocpf_stop(ioc); + break; + + case IOC_E_HWERROR: + /* HB failure notification, ignore. */ + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * IOCPF State Machine + */ + +/** + * Reset entry actions -- initialize state machine + */ +static void +bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf) +{ + iocpf->retry_count = 0; + iocpf->auto_recover = bfa_nw_auto_recover; +} + +/** + * Beginning state. IOC is in reset state. + */ +static void +bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event) +{ + switch (event) { + case IOCPF_E_ENABLE: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); + break; + + case IOCPF_E_STOP: + break; + + default: + bfa_sm_fault(iocpf->ioc, event); + } +} + +/** + * Semaphore should be acquired for version check. + */ +static void +bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf) +{ + bfa_ioc_hw_sem_get(iocpf->ioc); } /** * Awaiting h/w semaphore to continue with version check. */ static void -bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_SEMLOCKED: + case IOCPF_E_SEMLOCKED: if (bfa_ioc_firmware_lock(ioc)) { - ioc->retry_count = 0; - bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + if (bfa_ioc_sync_complete(ioc)) { + iocpf->retry_count = 0; + bfa_ioc_sync_join(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); + } else { + bfa_ioc_firmware_unlock(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + mod_timer(&ioc->sem_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); + } } else { bfa_nw_ioc_hw_sem_release(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch); } break; - case IOC_E_DISABLE: - bfa_ioc_disable_comp(ioc); - /* fall through */ - - case IOC_E_DETACH: + case IOCPF_E_DISABLE: bfa_ioc_hw_sem_get_cancel(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); + bfa_ioc_pf_disabled(ioc); break; - case IOC_E_FWREADY: + case IOCPF_E_STOP: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); break; default: @@ -221,41 +635,42 @@ bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event) } /** - * Notify enable completion callback and generate mismatch AEN. + * Notify enable completion callback */ static void -bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf) { - /** - * Provide enable completion callback and AEN notification only once. - */ - if (ioc->retry_count == 0) - ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); - ioc->retry_count++; - bfa_ioc_timer_start(ioc); + /* Call only the first time sm enters fwmismatch state. */ + if (iocpf->retry_count == 0) + bfa_ioc_pf_fwmismatch(iocpf->ioc); + + iocpf->retry_count++; + mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV)); } /** * Awaiting firmware version match. */ static void -bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_TIMEOUT: - bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + case IOCPF_E_TIMEOUT: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); break; - case IOC_E_DISABLE: - bfa_ioc_disable_comp(ioc); - /* fall through */ - - case IOC_E_DETACH: - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + case IOCPF_E_DISABLE: + del_timer(&ioc->iocpf_timer); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); + bfa_ioc_pf_disabled(ioc); break; - case IOC_E_FWREADY: + case IOCPF_E_STOP: + del_timer(&ioc->iocpf_timer); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); break; default: @@ -267,26 +682,34 @@ bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event) * Request for semaphore. */ static void -bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_semwait_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_hw_sem_get(ioc); + bfa_ioc_hw_sem_get(iocpf->ioc); } /** * Awaiting semaphore for h/w initialzation. */ static void -bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_SEMLOCKED: - ioc->retry_count = 0; - bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + case IOCPF_E_SEMLOCKED: + if (bfa_ioc_sync_complete(ioc)) { + bfa_ioc_sync_join(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); + } else { + bfa_nw_ioc_hw_sem_release(ioc); + mod_timer(&ioc->sem_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); + } break; - case IOC_E_DISABLE: + case IOCPF_E_DISABLE: bfa_ioc_hw_sem_get_cancel(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); break; default: @@ -295,46 +718,46 @@ bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_timer_start(ioc); - bfa_ioc_reset(ioc, false); + mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV)); + bfa_ioc_reset(iocpf->ioc, 0); } /** - * @brief * Hardware is being initialized. Interrupts are enabled. * Holding hardware semaphore lock. */ static void -bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_FWREADY: - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); + case IOCPF_E_FWREADY: + del_timer(&ioc->iocpf_timer); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); break; - case IOC_E_HWERROR: - bfa_ioc_timer_stop(ioc); - /* fall through */ - - case IOC_E_TIMEOUT: - ioc->retry_count++; - if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { - bfa_ioc_timer_start(ioc); - bfa_ioc_reset(ioc, true); - break; - } + case IOCPF_E_INITFAIL: + del_timer(&ioc->iocpf_timer); + /* + * !!! fall through !!! + */ + case IOCPF_E_TIMEOUT: bfa_nw_ioc_hw_sem_release(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + if (event == IOCPF_E_TIMEOUT) + bfa_ioc_pf_failed(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); break; - case IOC_E_DISABLE: + case IOCPF_E_DISABLE: + del_timer(&ioc->iocpf_timer); + bfa_ioc_sync_leave(ioc); bfa_nw_ioc_hw_sem_release(ioc); - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); break; default: @@ -343,10 +766,11 @@ bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_timer_start(ioc); - bfa_ioc_send_enable(ioc); + mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV)); + bfa_ioc_send_enable(iocpf->ioc); } /** @@ -354,39 +778,36 @@ bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) * Semaphore is acquired. */ static void -bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_FWRSP_ENABLE: - bfa_ioc_timer_stop(ioc); + case IOCPF_E_FWRSP_ENABLE: + del_timer(&ioc->iocpf_timer); bfa_nw_ioc_hw_sem_release(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready); break; - case IOC_E_HWERROR: - bfa_ioc_timer_stop(ioc); - /* fall through */ - - case IOC_E_TIMEOUT: - ioc->retry_count++; - if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { - writel(BFI_IOC_UNINIT, - ioc->ioc_regs.ioc_fwstate); - bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); - break; - } - + case IOCPF_E_INITFAIL: + del_timer(&ioc->iocpf_timer); + /* + * !!! fall through !!! + */ + case IOCPF_E_TIMEOUT: bfa_nw_ioc_hw_sem_release(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + if (event == IOCPF_E_TIMEOUT) + bfa_ioc_pf_failed(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); break; - case IOC_E_DISABLE: - bfa_ioc_timer_stop(ioc); + case IOCPF_E_DISABLE: + del_timer(&ioc->iocpf_timer); bfa_nw_ioc_hw_sem_release(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); break; - case IOC_E_FWREADY: + case IOCPF_E_FWREADY: bfa_ioc_send_enable(ioc); break; @@ -395,38 +816,42 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) } } +static bool +bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) +{ + return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); +} + static void -bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_timer_start(ioc); - bfa_ioc_send_getattr(ioc); + bfa_ioc_pf_enabled(iocpf->ioc); } -/** - * @brief - * IOC configuration in progress. Timer is active. - */ static void -bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_FWRSP_GETATTR: - bfa_ioc_timer_stop(ioc); - bfa_ioc_check_attr_wwns(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_op); + case IOCPF_E_DISABLE: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); break; - case IOC_E_HWERROR: - bfa_ioc_timer_stop(ioc); - /* fall through */ + case IOCPF_E_GETATTRFAIL: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); + break; - case IOC_E_TIMEOUT: - bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + case IOCPF_E_FAIL: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); break; - case IOC_E_DISABLE: - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + case IOCPF_E_FWREADY: + bfa_ioc_pf_failed(ioc); + if (bfa_nw_ioc_is_operational(ioc)) + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); + else + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); break; default: @@ -435,35 +860,40 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf) { - ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); - bfa_ioc_hb_monitor(ioc); + mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV)); + bfa_ioc_send_disable(iocpf->ioc); } +/** + * IOC is being disabled + */ static void -bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event) { - switch (event) { - case IOC_E_ENABLE: - break; + struct bfa_ioc *ioc = iocpf->ioc; - case IOC_E_DISABLE: - bfa_ioc_hb_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + switch (event) { + case IOCPF_E_FWRSP_DISABLE: + case IOCPF_E_FWREADY: + del_timer(&ioc->iocpf_timer); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); break; - case IOC_E_HWERROR: - case IOC_E_FWREADY: - /** - * Hard error or IOC recovery by other function. - * Treat it same as heartbeat failure. + case IOCPF_E_FAIL: + del_timer(&ioc->iocpf_timer); + /* + * !!! fall through !!! */ - bfa_ioc_hb_stop(ioc); - /* !!! fall through !!! */ - case IOC_E_HBFAIL: - bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail); + case IOCPF_E_TIMEOUT: + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); + break; + + case IOCPF_E_FWRSP_ENABLE: break; default: @@ -472,33 +902,27 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_timer_start(ioc); - bfa_ioc_send_disable(ioc); + bfa_ioc_hw_sem_get(iocpf->ioc); } /** - * IOC is being disabled + * IOC hb ack request is being removed. */ static void -bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_FWRSP_DISABLE: - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + case IOCPF_E_SEMLOCKED: + bfa_ioc_sync_leave(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); break; - case IOC_E_HWERROR: - bfa_ioc_timer_stop(ioc); - /* - * !!! fall through !!! - */ - - case IOC_E_TIMEOUT: - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + case IOCPF_E_FAIL: break; default: @@ -510,29 +934,25 @@ bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) * IOC disable completion entry. */ static void -bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf) { - bfa_ioc_disable_comp(ioc); + bfa_ioc_pf_disabled(iocpf->ioc); } static void -bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event) { - switch (event) { - case IOC_E_ENABLE: - bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); - break; - - case IOC_E_DISABLE: - ioc->cbfn->disable_cbfn(ioc->bfa); - break; + struct bfa_ioc *ioc = iocpf->ioc; - case IOC_E_FWREADY: + switch (event) { + case IOCPF_E_ENABLE: + iocpf->retry_count = 0; + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); break; - case IOC_E_DETACH: + case IOCPF_E_STOP: bfa_ioc_firmware_unlock(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); break; default: @@ -541,33 +961,50 @@ bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf *iocpf) { - ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); - bfa_ioc_timer_start(ioc); + bfa_ioc_hw_sem_get(iocpf->ioc); } /** - * @brief * Hardware initialization failed. */ static void -bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) { + struct bfa_ioc *ioc = iocpf->ioc; + switch (event) { - case IOC_E_DISABLE: - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + case IOCPF_E_SEMLOCKED: + bfa_ioc_notify_fail(ioc); + bfa_ioc_sync_ack(ioc); + iocpf->retry_count++; + if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) { + bfa_ioc_sync_leave(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); + } else { + if (bfa_ioc_sync_complete(ioc)) + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); + else { + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); + } + } break; - case IOC_E_DETACH: - bfa_ioc_timer_stop(ioc); + case IOCPF_E_DISABLE: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); + break; + + case IOCPF_E_STOP: + bfa_ioc_hw_sem_get_cancel(ioc); bfa_ioc_firmware_unlock(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); break; - case IOC_E_TIMEOUT: - bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + case IOCPF_E_FAIL: break; default: @@ -576,80 +1013,108 @@ bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event) } static void -bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc) +bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf) { - struct list_head *qe; - struct bfa_ioc_hbfail_notify *notify; + bfa_ioc_pf_initfailed(iocpf->ioc); +} - /** - * Mark IOC as failed in hardware and stop firmware. - */ - bfa_ioc_lpu_stop(ioc); - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); +/** + * Hardware initialization failed. + */ +static void +bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event) +{ + struct bfa_ioc *ioc = iocpf->ioc; - /** - * Notify other functions on HB failure. - */ - bfa_ioc_notify_hbfail(ioc); + switch (event) { + case IOCPF_E_DISABLE: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); + break; - /** - * Notify driver and common modules registered for notification. - */ - ioc->cbfn->hbfail_cbfn(ioc->bfa); - list_for_each(qe, &ioc->hb_notify_q) { - notify = (struct bfa_ioc_hbfail_notify *) qe; - notify->cbfn(notify->cbarg); + case IOCPF_E_STOP: + bfa_ioc_firmware_unlock(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); + break; + + default: + bfa_sm_fault(ioc, event); } +} +static void +bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf) +{ /** - * Flush any queued up mailbox requests. + * Mark IOC as failed in hardware and stop firmware. */ - bfa_ioc_mbox_hbfail(ioc); + bfa_ioc_lpu_stop(iocpf->ioc); /** - * Trigger auto-recovery after a delay. + * Flush any queued up mailbox requests. */ - if (ioc->auto_recover) - mod_timer(&ioc->ioc_timer, jiffies + - msecs_to_jiffies(BFA_IOC_TOV_RECOVER)); + bfa_ioc_mbox_hbfail(iocpf->ioc); + bfa_ioc_hw_sem_get(iocpf->ioc); } /** - * @brief - * IOC heartbeat failure. + * IOC is in failed state. */ static void -bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event) +bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) { - switch (event) { + struct bfa_ioc *ioc = iocpf->ioc; - case IOC_E_ENABLE: - ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + switch (event) { + case IOCPF_E_SEMLOCKED: + iocpf->retry_count = 0; + bfa_ioc_sync_ack(ioc); + bfa_ioc_notify_fail(ioc); + if (!iocpf->auto_recover) { + bfa_ioc_sync_leave(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); + } else { + if (bfa_ioc_sync_complete(ioc)) + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); + else { + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); + } + } break; - case IOC_E_DISABLE: - if (ioc->auto_recover) - bfa_ioc_timer_stop(ioc); - bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + case IOCPF_E_DISABLE: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); break; - case IOC_E_TIMEOUT: - bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + case IOCPF_E_FAIL: break; - case IOC_E_FWREADY: - /** - * Recovery is already initiated by other function. - */ - break; + default: + bfa_sm_fault(ioc, event); + } +} - case IOC_E_HWERROR: - /* - * HB failure notification, ignore. - */ +static void +bfa_iocpf_sm_fail_entry(struct bfa_iocpf *iocpf) +{ +} + +/** + * @brief + * IOC is in failed state. + */ +static void +bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event) +{ + switch (event) { + case IOCPF_E_DISABLE: + bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); break; + default: - bfa_sm_fault(ioc, event); + bfa_sm_fault(iocpf->ioc, event); } } @@ -674,14 +1139,6 @@ bfa_ioc_disable_comp(struct bfa_ioc *ioc) } } -void -bfa_nw_ioc_sem_timeout(void *ioc_arg) -{ - struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; - - bfa_ioc_hw_sem_get(ioc); -} - bool bfa_nw_ioc_sem_get(void __iomem *sem_reg) { @@ -721,7 +1178,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) */ r32 = readl(ioc->ioc_regs.ioc_sem_reg); if (r32 == 0) { - bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED); + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); return; } @@ -932,7 +1389,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) */ bfa_ioc_msgflush(ioc); ioc->cbfn->reset_cbfn(ioc->bfa); - bfa_fsm_send_event(ioc, IOC_E_FWREADY); + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); return; } @@ -1018,7 +1475,6 @@ bfa_nw_ioc_hb_check(void *cbarg) hb_count = readl(ioc->ioc_regs.heartbeat); if (ioc->hb_count == hb_count) { - pr_crit("Firmware heartbeat failure at %d", hb_count); bfa_ioc_recover(ioc); return; } else { @@ -1189,6 +1645,55 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) bfa_q_deq(&mod->cmd_q, &cmd); } +static void +bfa_ioc_fail_notify(struct bfa_ioc *ioc) +{ + struct list_head *qe; + struct bfa_ioc_hbfail_notify *notify; + + /** + * Notify driver and common modules registered for notification. + */ + ioc->cbfn->hbfail_cbfn(ioc->bfa); + list_for_each(qe, &ioc->hb_notify_q) { + notify = (struct bfa_ioc_hbfail_notify *) qe; + notify->cbfn(notify->cbarg); + } +} + +static void +bfa_ioc_pf_enabled(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_ENABLED); +} + +static void +bfa_ioc_pf_disabled(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_DISABLED); +} + +static void +bfa_ioc_pf_initfailed(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_INITFAILED); +} + +static void +bfa_ioc_pf_failed(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_PFAILED); +} + +static void +bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc) +{ + /** + * Provide enable completion callback and AEN notification. + */ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); +} + /** * IOC public */ @@ -1284,6 +1789,7 @@ static void bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) { union bfi_ioc_i2h_msg_u *msg; + struct bfa_iocpf *iocpf = &ioc->iocpf; msg = (union bfi_ioc_i2h_msg_u *) m; @@ -1294,15 +1800,15 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) break; case BFI_IOC_I2H_READY_EVENT: - bfa_fsm_send_event(ioc, IOC_E_FWREADY); + bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY); break; case BFI_IOC_I2H_ENABLE_REPLY: - bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE); + bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); break; case BFI_IOC_I2H_DISABLE_REPLY: - bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE); + bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); break; case BFI_IOC_I2H_GETATTR_REPLY: @@ -1328,11 +1834,13 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) ioc->fcmode = false; ioc->pllinit = false; ioc->dbg_fwsave_once = true; + ioc->iocpf.ioc = ioc; bfa_ioc_mbox_attach(ioc); INIT_LIST_HEAD(&ioc->hb_notify_q); - bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); + bfa_fsm_send_event(ioc, IOC_E_RESET); } /** @@ -1637,7 +2145,40 @@ bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) static enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc *ioc) { - return bfa_sm_to_state(ioc_sm_table, ioc->fsm); + enum bfa_iocpf_state iocpf_st; + enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); + + if (ioc_st == BFA_IOC_ENABLING || + ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { + + iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); + + switch (iocpf_st) { + case BFA_IOCPF_SEMWAIT: + ioc_st = BFA_IOC_SEMWAIT; + break; + + case BFA_IOCPF_HWINIT: + ioc_st = BFA_IOC_HWINIT; + break; + + case BFA_IOCPF_FWMISMATCH: + ioc_st = BFA_IOC_FWMISMATCH; + break; + + case BFA_IOCPF_FAIL: + ioc_st = BFA_IOC_FAIL; + break; + + case BFA_IOCPF_INITFAIL: + ioc_st = BFA_IOC_INITFAIL; + break; + + default: + break; + } + } + return ioc_st; } void @@ -1678,8 +2219,13 @@ bfa_nw_ioc_get_mac(struct bfa_ioc *ioc) static void bfa_ioc_recover(struct bfa_ioc *ioc) { - bfa_ioc_stats(ioc, ioc_hbfails); - bfa_fsm_send_event(ioc, IOC_E_HBFAIL); + u16 bdf; + + bdf = (ioc->pcidev.pci_slot << 8 | ioc->pcidev.pci_func << 3 | + ioc->pcidev.device_id); + + pr_crit("Firmware heartbeat failure at %d", bdf); + BUG_ON(1); } static void @@ -1687,5 +2233,61 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc) { if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) return; +} + +/** + * @dg hal_iocpf_pvt BFA IOC PF private functions + * @{ + */ + +static void +bfa_iocpf_enable(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE); +} + +static void +bfa_iocpf_disable(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); +} + +static void +bfa_iocpf_fail(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); +} + +static void +bfa_iocpf_initfail(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); +} + +static void +bfa_iocpf_getattrfail(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); +} + +static void +bfa_iocpf_stop(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); +} + +void +bfa_nw_iocpf_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); +} +void +bfa_nw_iocpf_sem_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_ioc_hw_sem_get(ioc); } diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h index a73d84ec808c..e4974bc24ef6 100644 --- a/drivers/net/bna/bfa_ioc.h +++ b/drivers/net/bna/bfa_ioc.h @@ -26,16 +26,7 @@ #define BFA_IOC_TOV 3000 /* msecs */ #define BFA_IOC_HWSEM_TOV 500 /* msecs */ #define BFA_IOC_HB_TOV 500 /* msecs */ -#define BFA_IOC_HWINIT_MAX 2 -#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV - -/** - * Generic Scatter Gather Element used by driver - */ -struct bfa_sge { - u32 sg_len; - void *sg_addr; -}; +#define BFA_IOC_HWINIT_MAX 5 /** * PCI device information required by IOC @@ -64,19 +55,6 @@ struct bfa_dma { #define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */ #define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */ -/** - * @brief BFA dma address assignment macro - */ -#define bfa_dma_addr_set(dma_addr, pa) \ - __bfa_dma_addr_set(&dma_addr, (u64)pa) - -static inline void -__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa) -{ - dma_addr->a32.addr_lo = (u32) pa; - dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa)); -} - /** * @brief BFA dma address assignment macro. (big endian format) */ @@ -105,8 +83,11 @@ struct bfa_ioc_regs { void __iomem *host_page_num_fn; void __iomem *heartbeat; void __iomem *ioc_fwstate; + void __iomem *alt_ioc_fwstate; void __iomem *ll_halt; + void __iomem *alt_ll_halt; void __iomem *err_set; + void __iomem *ioc_fail_sync; void __iomem *shirq_isr_next; void __iomem *shirq_msk_next; void __iomem *smem_page_start; @@ -165,16 +146,22 @@ struct bfa_ioc_hbfail_notify { (__notify)->cbarg = (__cbarg); \ } while (0) +struct bfa_iocpf { + bfa_fsm_t fsm; + struct bfa_ioc *ioc; + u32 retry_count; + bool auto_recover; +}; + struct bfa_ioc { bfa_fsm_t fsm; struct bfa *bfa; struct bfa_pcidev pcidev; - struct bfa_timer_mod *timer_mod; struct timer_list ioc_timer; + struct timer_list iocpf_timer; struct timer_list sem_timer; struct timer_list hb_timer; u32 hb_count; - u32 retry_count; struct list_head hb_notify_q; void *dbg_fwsave; int dbg_fwsave_len; @@ -182,7 +169,6 @@ struct bfa_ioc { enum bfi_mclass ioc_mc; struct bfa_ioc_regs ioc_regs; struct bfa_ioc_drv_stats stats; - bool auto_recover; bool fcmode; bool ctdev; bool cna; @@ -195,6 +181,7 @@ struct bfa_ioc { struct bfa_ioc_cbfn *cbfn; struct bfa_ioc_mbox_mod mbox_mod; struct bfa_ioc_hwif *ioc_hwif; + struct bfa_iocpf iocpf; }; struct bfa_ioc_hwif { @@ -205,8 +192,12 @@ struct bfa_ioc_hwif { void (*ioc_map_port) (struct bfa_ioc *ioc); void (*ioc_isr_mode_set) (struct bfa_ioc *ioc, bool msix); - void (*ioc_notify_hbfail) (struct bfa_ioc *ioc); + void (*ioc_notify_fail) (struct bfa_ioc *ioc); void (*ioc_ownership_reset) (struct bfa_ioc *ioc); + void (*ioc_sync_join) (struct bfa_ioc *ioc); + void (*ioc_sync_leave) (struct bfa_ioc *ioc); + void (*ioc_sync_ack) (struct bfa_ioc *ioc); + bool (*ioc_sync_complete) (struct bfa_ioc *ioc); }; #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) @@ -271,7 +262,6 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc); void bfa_nw_ioc_disable(struct bfa_ioc *ioc); void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc); - void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, struct bfa_ioc_hbfail_notify *notify); @@ -289,7 +279,8 @@ mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc); */ void bfa_nw_ioc_timeout(void *ioc); void bfa_nw_ioc_hb_check(void *ioc); -void bfa_nw_ioc_sem_timeout(void *ioc); +void bfa_nw_iocpf_timeout(void *ioc); +void bfa_nw_iocpf_sem_timeout(void *ioc); /* * F/W Image Size & Chunk diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c index 121cfd6d48b1..469997c4ffd1 100644 --- a/drivers/net/bna/bfa_ioc_ct.c +++ b/drivers/net/bna/bfa_ioc_ct.c @@ -22,6 +22,15 @@ #include "bfi_ctreg.h" #include "bfa_defs.h" +#define bfa_ioc_ct_sync_pos(__ioc) \ + ((u32) (1 << bfa_ioc_pcifn(__ioc))) +#define BFA_IOC_SYNC_REQD_SH 16 +#define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff) +#define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000) +#define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH) +#define bfa_ioc_ct_sync_reqd_pos(__ioc) \ + (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH) + /* * forward declarations */ @@ -30,8 +39,12 @@ static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc); static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc); static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc); static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix); -static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc); +static void bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc); static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); +static void bfa_ioc_ct_sync_join(struct bfa_ioc *ioc); +static void bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc); +static void bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc); +static bool bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc); static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); static struct bfa_ioc_hwif nw_hwif_ct; @@ -48,8 +61,12 @@ bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc) nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; - nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail; + nw_hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail; nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; + nw_hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join; + nw_hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave; + nw_hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack; + nw_hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete; ioc->ioc_hwif = &nw_hwif_ct; } @@ -86,6 +103,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) if (usecnt == 0) { writel(1, ioc->ioc_regs.ioc_usage_reg); bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + writel(0, ioc->ioc_regs.ioc_fail_sync); return true; } @@ -149,12 +167,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc) * Notify other functions on HB failure. */ static void -bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc) +bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc) { if (ioc->cna) { writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt); + writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt); /* Wait for halt to take effect */ readl(ioc->ioc_regs.ll_halt); + readl(ioc->ioc_regs.alt_ll_halt); } else { writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set); readl(ioc->ioc_regs.err_set); @@ -206,15 +226,19 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc) if (ioc->port_id == 0) { ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; + ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG; ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; + ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1; } else { ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); + ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG; ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; + ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0; } /* @@ -232,6 +256,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc) ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); + ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC); /** * sram memory access @@ -317,6 +342,77 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) bfa_nw_ioc_hw_sem_release(ioc); } +/** + * Synchronized IOC failure processing routines + */ +static void +bfa_ioc_ct_sync_join(struct bfa_ioc *ioc) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync); + u32 sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc); + + writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync); +} + +static void +bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync); + u32 sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) | + bfa_ioc_ct_sync_pos(ioc); + + writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync); +} + +static void +bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync); + + writel((r32 | bfa_ioc_ct_sync_pos(ioc)), ioc->ioc_regs.ioc_fail_sync); +} + +static bool +bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync); + u32 sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); + u32 sync_ackd = bfa_ioc_ct_get_sync_ackd(r32); + u32 tmp_ackd; + + if (sync_ackd == 0) + return true; + + /** + * The check below is to see whether any other PCI fn + * has reinitialized the ASIC (reset sync_ackd bits) + * and failed again while this IOC was waiting for hw + * semaphore (in bfa_iocpf_sm_semwait()). + */ + tmp_ackd = sync_ackd; + if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) && + !(sync_ackd & bfa_ioc_ct_sync_pos(ioc))) + sync_ackd |= bfa_ioc_ct_sync_pos(ioc); + + if (sync_reqd == sync_ackd) { + writel(bfa_ioc_ct_clear_sync_ackd(r32), + ioc->ioc_regs.ioc_fail_sync); + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate); + return true; + } + + /** + * If another PCI fn reinitialized and failed again while + * this IOC was waiting for hw sem, the sync_ackd bit for + * this IOC need to be set again to allow reinitialization. + */ + if (tmp_ackd != sync_ackd) + writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync); + + return false; +} + static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode) { diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h index 404ea351d4a1..5130d7918660 100644 --- a/drivers/net/bna/bfi_ctreg.h +++ b/drivers/net/bna/bfi_ctreg.h @@ -535,6 +535,7 @@ enum { #define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG #define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG #define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG +#define BFA_IOC_FAIL_SYNC HOST_SEM5_INFO_REG #define CPE_DEPTH_Q(__n) \ (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0)) @@ -552,22 +553,30 @@ enum { (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0)) #define RME_CI_PTR_Q(__n) \ (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0)) -#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \ - * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0)) -#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \ - * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0)) -#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \ - * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0)) -#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \ - * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0)) -#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \ - * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1)) -#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \ - * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1)) -#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \ - * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1)) -#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \ - * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1)) +#define HQM_QSET_RXQ_DRBL_P0(__n) \ + (HQM_QSET0_RXQ_DRBL_P0 + (__n) * \ + (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0)) +#define HQM_QSET_TXQ_DRBL_P0(__n) \ + (HQM_QSET0_TXQ_DRBL_P0 + (__n) * \ + (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0)) +#define HQM_QSET_IB_DRBL_1_P0(__n) \ + (HQM_QSET0_IB_DRBL_1_P0 + (__n) * \ + (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0)) +#define HQM_QSET_IB_DRBL_2_P0(__n) \ + (HQM_QSET0_IB_DRBL_2_P0 + (__n) * \ + (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0)) +#define HQM_QSET_RXQ_DRBL_P1(__n) \ + (HQM_QSET0_RXQ_DRBL_P1 + (__n) * \ + (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1)) +#define HQM_QSET_TXQ_DRBL_P1(__n) \ + (HQM_QSET0_TXQ_DRBL_P1 + (__n) * \ + (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1)) +#define HQM_QSET_IB_DRBL_1_P1(__n) \ + (HQM_QSET0_IB_DRBL_1_P1 + (__n) * \ + (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1)) +#define HQM_QSET_IB_DRBL_2_P1(__n) \ + (HQM_QSET0_IB_DRBL_2_P1 + (__n) * \ + (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1)) #define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) #define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h index fd93f7652639..a287f89b0289 100644 --- a/drivers/net/bna/bna.h +++ b/drivers/net/bna/bna.h @@ -32,8 +32,6 @@ extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX]; /* Log string size */ #define BNA_MESSAGE_SIZE 256 -#define bna_device_timer(_dev) bfa_timer_beat(&((_dev)->timer_mod)) - /* MBOX API for PORT, TX, RX */ #define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \ do { \ diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 140ea95b9150..fad912656fe4 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -1425,13 +1425,24 @@ bnad_ioc_hb_check(unsigned long data) } static void -bnad_ioc_sem_timeout(unsigned long data) +bnad_iocpf_timeout(unsigned long data) { struct bnad *bnad = (struct bnad *)data; unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); - bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc); + bfa_nw_iocpf_timeout((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_iocpf_sem_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_nw_iocpf_sem_timeout((void *) &bnad->bna.device.ioc); spin_unlock_irqrestore(&bnad->bna_lock, flags); } @@ -3132,11 +3143,13 @@ bnad_pci_probe(struct pci_dev *pdev, ((unsigned long)bnad)); setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check, ((unsigned long)bnad)); - setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout, + setup_timer(&bnad->bna.device.ioc.iocpf_timer, bnad_iocpf_timeout, + ((unsigned long)bnad)); + setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_iocpf_sem_timeout, ((unsigned long)bnad)); /* Now start the timer before calling IOC */ - mod_timer(&bnad->bna.device.ioc.ioc_timer, + mod_timer(&bnad->bna.device.ioc.iocpf_timer, jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ)); /* -- cgit v1.2.3-59-g8ed1b From a1a5da57d0884017b8c3a011a28d4f5e08a2ea4f Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Thu, 23 Dec 2010 21:45:10 +0000 Subject: bna: Update the driver version to 2.3.2.3 Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index 1954dea4cbf2..8b1d51557def 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -65,7 +65,7 @@ struct bnad_rx_ctrl { #define BNAD_NAME "bna" #define BNAD_NAME_LEN 64 -#define BNAD_VERSION "2.3.2.0" +#define BNAD_VERSION "2.3.2.3" #define BNAD_MAILBOX_MSIX_VECTORS 1 -- cgit v1.2.3-59-g8ed1b From e88735d711948a580741fd337afd4ec11c395174 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 11 Dec 2010 08:46:56 -0800 Subject: iwlwifi: remove extra string For "led_mode" module parameters, string "led_mode" is duplicated twice, remove one. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 516e5577ed2a..46ccdf406e8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -45,7 +45,7 @@ /* default: IWL_LED_BLINK(0) using blinking index table */ static int led_mode; module_param(led_mode, int, S_IRUGO); -MODULE_PARM_DESC(led_mode, "led mode: 0=system default, " +MODULE_PARM_DESC(led_mode, "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); static const struct { -- cgit v1.2.3-59-g8ed1b From bdb84fec61aab7047b1b108b6b6824c003bc4d11 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Dec 2010 06:07:56 -0800 Subject: iwlagn: fix FH error # iw wlan0 interface add moni0 type monitor flags control # ip link set moni0 up causes a continuous spew of FH_ERROR from the device. Fix this by not setting the CTL2HOST filter by itself -- CTL + promisc works fine. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d4075476670a..b54d74daaea4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3634,7 +3634,8 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw, changed_flags, *total_flags); CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); - CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); + /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ + CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); #undef CHK -- cgit v1.2.3-59-g8ed1b From 003ea98195eebdfcf476317b517e8c29a25b9d10 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 15 Dec 2010 08:06:23 -0800 Subject: iwlwifi: remove reference to Gen2 The correct name should be used for the newer devices, remove reference to Gen2 Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b54d74daaea4..5f11dc25a9bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4412,7 +4412,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, -/* 6x00 Series Gen2a */ +/* 6x05 Series */ {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, @@ -4421,7 +4421,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, -/* 6x00 Series Gen2b */ +/* 6x30 Series */ {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, @@ -4447,7 +4447,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, -/* 6x50 WiFi/WiMax Series Gen2 */ +/* 6150 WiFi/WiMax Series */ {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)}, {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, -- cgit v1.2.3-59-g8ed1b From a7dd6027e55992dd7c409a71a4a2b576fda2f7c2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 23 Dec 2010 20:15:39 +0000 Subject: vxge: remove duplicated part of check This is just a cleanup to make the static checkers happy. We don't need to check "own" twice. Signed-off-by: Dan Carpenter Acked-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-traffic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 42cc29843ac7..4c10d6c4075f 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -1240,7 +1240,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_next_completed( *t_code = (u8)VXGE_HW_RING_RXD_T_CODE_GET(control_0); /* check whether it is not the end */ - if (!own || ((*t_code == VXGE_HW_RING_T_CODE_FRM_DROP) && own)) { + if (!own || *t_code == VXGE_HW_RING_T_CODE_FRM_DROP) { vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control != 0); -- cgit v1.2.3-59-g8ed1b From 3e29027af43728c2a91fe3f735ab2822edaf54a8 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 30 Dec 2010 09:25:46 +0000 Subject: dcbnl: add support for ieee8021Qaz attributes The IEEE8021Qaz is the IEEE standard version of CEE. The standard has had enough significant changes from the CEE version that many of the CEE attributes have no meaning in the new spec or do not easily map to IEEE standards. Rather then attempt to create a complicated mapping between CEE and IEEE standards this patch adds a nested IEEE attribute to the list of DCB attributes. The policy is, [DCB_ATTR_IFNAME] [DCB_ATTR_STATE] ... [DCB_ATTR_IEEE] [DCB_ATTR_IEEE_ETS] [DCB_ATTR_IEEE_PFC] [DCB_ATTR_IEEE_APP_TABLE] [DCB_ATTR_IEEE_APP] ... The following dcbnl_rtnl_ops routines were added to handle the IEEE standard, int (*ieee_getets) (struct net_device *, struct ieee_ets *); int (*ieee_setets) (struct net_device *, struct ieee_ets *); int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_getapp) (struct net_device *, struct dcb_app *); int (*ieee_setapp) (struct net_device *, struct dcb_app *); Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- include/linux/dcbnl.h | 106 ++++++++++++++++++++++++++++++++++++++++ include/net/dcbnl.h | 11 +++++ net/dcb/dcbnl.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 8723491f7dfd..287b5618e296 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h @@ -22,6 +22,87 @@ #include +/* IEEE 802.1Qaz std supported values */ +#define IEEE_8021QAZ_MAX_TCS 8 + +/* This structure contains the IEEE 802.1Qaz ETS managed object + * + * @willing: willing bit in ETS configuratin TLV + * @ets_cap: indicates supported capacity of ets feature + * @cbs: credit based shaper ets algorithm supported + * @tc_tx_bw: tc tx bandwidth indexed by traffic class + * @tc_rx_bw: tc rx bandwidth indexed by traffic class + * @tc_tsa: TSA Assignment table, indexed by traffic class + * @prio_tc: priority assignment table mapping 8021Qp to traffic class + * @tc_reco_bw: recommended tc bandwidth indexed by traffic class for TLV + * @tc_reco_tsa: recommended tc bandwidth indexed by traffic class for TLV + * @reco_prio_tc: recommended tc tx bandwidth indexed by traffic class for TLV + * + * Recommended values are used to set fields in the ETS recommendation TLV + * with hardware offloaded LLDP. + * + * ---- + * TSA Assignment 8 bit identifiers + * 0 strict priority + * 1 credit-based shaper + * 2 enhanced transmission selection + * 3-254 reserved + * 255 vendor specific + */ +struct ieee_ets { + __u8 willing; + __u8 ets_cap; + __u8 cbs; + __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS]; + __u8 tc_rx_bw[IEEE_8021QAZ_MAX_TCS]; + __u8 tc_tsa[IEEE_8021QAZ_MAX_TCS]; + __u8 prio_tc[IEEE_8021QAZ_MAX_TCS]; + __u8 tc_reco_bw[IEEE_8021QAZ_MAX_TCS]; + __u8 tc_reco_tsa[IEEE_8021QAZ_MAX_TCS]; + __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS]; +}; + +/* This structure contains the IEEE 802.1Qaz PFC managed object + * + * @pfc_cap: Indicates the number of traffic classes on the local device + * that may simultaneously have PFC enabled. + * @pfc_en: bitmap indicating pfc enabled traffic classes + * @mbc: enable macsec bypass capability + * @delay: the allowance made for a round-trip propagation delay of the + * link in bits. + * @requests: count of the sent pfc frames + * @indications: count of the received pfc frames + */ +struct ieee_pfc { + __u8 pfc_cap; + __u8 pfc_en; + __u8 mbc; + __u16 delay; + __u64 requests[IEEE_8021QAZ_MAX_TCS]; + __u64 indications[IEEE_8021QAZ_MAX_TCS]; +}; + +/* This structure contains the IEEE 802.1Qaz APP managed object + * + * @selector: protocol identifier type + * @protocol: protocol of type indicated + * @priority: 3-bit unsigned integer indicating priority + * + * ---- + * Selector field values + * 0 Reserved + * 1 Ethertype + * 2 Well known port number over TCP or SCTP + * 3 Well known port number over UDP or DCCP + * 4 Well known port number over TCP, SCTP, UDP, or DCCP + * 5-7 Reserved + */ +struct dcb_app { + __u8 selector; + __u32 protocol; + __u8 priority; +}; + struct dcbmsg { __u8 dcb_family; __u8 cmd; @@ -50,6 +131,8 @@ struct dcbmsg { * @DCB_CMD_SBCN: get backward congestion notification configration. * @DCB_CMD_GAPP: get application protocol configuration * @DCB_CMD_SAPP: set application protocol configuration + * @DCB_CMD_IEEE_SET: set IEEE 802.1Qaz configuration + * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration */ enum dcbnl_commands { DCB_CMD_UNDEFINED, @@ -83,6 +166,9 @@ enum dcbnl_commands { DCB_CMD_GAPP, DCB_CMD_SAPP, + DCB_CMD_IEEE_SET, + DCB_CMD_IEEE_GET, + __DCB_CMD_ENUM_MAX, DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, }; @@ -102,6 +188,7 @@ enum dcbnl_commands { * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED) * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED) * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED) + * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) */ enum dcbnl_attrs { DCB_ATTR_UNDEFINED, @@ -119,10 +206,29 @@ enum dcbnl_attrs { DCB_ATTR_BCN, DCB_ATTR_APP, + /* IEEE std attributes */ + DCB_ATTR_IEEE, + __DCB_ATTR_ENUM_MAX, DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, }; +enum ieee_attrs { + DCB_ATTR_IEEE_UNSPEC, + DCB_ATTR_IEEE_ETS, + DCB_ATTR_IEEE_PFC, + DCB_ATTR_IEEE_APP_TABLE, + __DCB_ATTR_IEEE_MAX +}; +#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) + +enum ieee_attrs_app { + DCB_ATTR_IEEE_APP_UNSPEC, + DCB_ATTR_IEEE_APP, + __DCB_ATTR_IEEE_APP_MAX +}; +#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) + /** * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs * diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index b36ac7e0914d..e2d841e963b3 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -20,11 +20,22 @@ #ifndef __NET_DCBNL_H__ #define __NET_DCBNL_H__ +#include + /* * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through * the netdevice struct. */ struct dcbnl_rtnl_ops { + /* IEEE 802.1Qaz std */ + int (*ieee_getets) (struct net_device *, struct ieee_ets *); + int (*ieee_setets) (struct net_device *, struct ieee_ets *); + int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); + int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); + int (*ieee_getapp) (struct net_device *, struct dcb_app *); + int (*ieee_setapp) (struct net_device *, struct dcb_app *); + + /* CEE std */ u8 (*getstate)(struct net_device *); u8 (*setstate)(struct net_device *, u8); void (*getpermhwaddr)(struct net_device *, u8 *); diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 19ac2b985485..2ff908498924 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -66,6 +66,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, [DCB_ATTR_BCN] = {.type = NLA_NESTED}, [DCB_ATTR_APP] = {.type = NLA_NESTED}, + [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, }; /* DCB priority flow control to User Priority nested attributes */ @@ -167,6 +168,17 @@ static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, }; +/* IEEE 802.1Qaz nested attributes. */ +static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { + [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, + [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, + [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, +}; + +static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { + [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, +}; + /* standard netlink reply call */ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, u32 seq, u16 flags) @@ -1118,6 +1130,117 @@ err: return ret; } +/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not + * be completed the entire msg is aborted and error value is returned. + * No attempt is made to reconcile the case where only part of the + * cmd can be completed. + */ +static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; + struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; + int err = -EOPNOTSUPP; + + if (!ops) + goto err; + + err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, + tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); + if (err) + goto err; + + if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { + struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); + err = ops->ieee_setets(netdev, ets); + if (err) + goto err; + } + + if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) { + struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); + err = ops->ieee_setpfc(netdev, pfc); + if (err) + goto err; + } + + if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) { + struct nlattr *attr; + int rem; + + nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { + struct dcb_app *app_data; + if (nla_type(attr) != DCB_ATTR_IEEE_APP) + continue; + app_data = nla_data(attr); + err = ops->ieee_setapp(netdev, app_data); + if (err) + goto err; + } + } + +err: + dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, + pid, seq, flags); + return err; +} + + +/* Handle IEEE 802.1Qaz GET commands. */ +static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + struct dcbmsg *dcb; + struct nlattr *ieee; + const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; + int err; + + if (!ops) + return -EOPNOTSUPP; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); + + dcb = NLMSG_DATA(nlh); + dcb->dcb_family = AF_UNSPEC; + dcb->cmd = DCB_CMD_IEEE_GET; + + NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); + + ieee = nla_nest_start(skb, DCB_ATTR_IEEE); + if (!ieee) + goto nla_put_failure; + + if (ops->ieee_getets) { + struct ieee_ets ets; + err = ops->ieee_getets(netdev, &ets); + if (!err) + NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets); + } + + if (ops->ieee_getpfc) { + struct ieee_pfc pfc; + err = ops->ieee_getpfc(netdev, &pfc); + if (!err) + NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc); + } + + nla_nest_end(skb, ieee); + nlmsg_end(skb, nlh); + + return rtnl_unicast(skb, &init_net, pid); +nla_put_failure: + nlmsg_cancel(skb, nlh); +nlmsg_failure: + kfree_skb(skb); + return -1; +} + static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); @@ -1223,6 +1346,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; + case DCB_CMD_IEEE_SET: + ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; + case DCB_CMD_IEEE_GET: + ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; default: goto errout; } -- cgit v1.2.3-59-g8ed1b From 9ab933ab2cc80f04690d6aa385b1110075c5e507 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 30 Dec 2010 09:26:31 +0000 Subject: dcbnl: add appliction tlv handlers This patch adds application tlv handlers. Networking stacks may use the application priority to set the skb priority of their stack using the negoatiated dcbx priority. This patch provides the dcb_{get|set}app() routines for the stack to query these parameters. Notice lower layer drivers can use the dcbnl_ops routines if additional handling is needed. Perhaps in the firmware case for example Signed-off-by: John Fastabend Signed-off-by: Shmulik Ravid Signed-off-by: David S. Miller --- include/linux/dcbnl.h | 4 +- include/net/dcbnl.h | 9 ++++ net/dcb/dcbnl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 135 insertions(+), 11 deletions(-) diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 287b5618e296..775bdb4465bf 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h @@ -82,7 +82,9 @@ struct ieee_pfc { __u64 indications[IEEE_8021QAZ_MAX_TCS]; }; -/* This structure contains the IEEE 802.1Qaz APP managed object +/* This structure contains the IEEE 802.1Qaz APP managed object. This + * object is also used for the CEE std as well. There is no difference + * between the objects. * * @selector: protocol identifier type * @protocol: protocol of type indicated diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index e2d841e963b3..ab7d623a2793 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -22,6 +22,15 @@ #include +struct dcb_app_type { + char name[IFNAMSIZ]; + struct dcb_app app; + struct list_head list; +}; + +u8 dcb_setapp(struct net_device *, struct dcb_app *); +u8 dcb_getapp(struct net_device *, struct dcb_app *); + /* * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through * the netdevice struct. diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 2ff908498924..cfd731faf6c6 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -179,6 +179,9 @@ static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, }; +static LIST_HEAD(dcb_app_list); +static DEFINE_SPINLOCK(dcb_lock); + /* standard netlink reply call */ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, u32 seq, u16 flags) @@ -634,12 +637,12 @@ out: static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, u32 pid, u32 seq, u16 flags) { - int ret = -EINVAL; + int err, ret = -EINVAL; u16 id; u8 up, idtype; struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; - if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp) + if (!tb[DCB_ATTR_APP]) goto out; ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], @@ -663,9 +666,18 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); - ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up), - RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, - pid, seq, flags); + if (netdev->dcbnl_ops->setapp) { + err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); + } else { + struct dcb_app app; + app.selector = idtype; + app.protocol = id; + app.priority = up; + err = dcb_setapp(netdev, &app); + } + + ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, + pid, seq, flags); out: return ret; } @@ -1164,7 +1176,7 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, goto err; } - if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) { + if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { struct nlattr *attr; int rem; @@ -1173,7 +1185,10 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, if (nla_type(attr) != DCB_ATTR_IEEE_APP) continue; app_data = nla_data(attr); - err = ops->ieee_setapp(netdev, app_data); + if (ops->ieee_setapp) + err = ops->ieee_setapp(netdev, app_data); + else + err = dcb_setapp(netdev, app_data); if (err) goto err; } @@ -1193,7 +1208,8 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, struct sk_buff *skb; struct nlmsghdr *nlh; struct dcbmsg *dcb; - struct nlattr *ieee; + struct nlattr *ieee, *app; + struct dcb_app_type *itr; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; int err; @@ -1230,6 +1246,19 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc); } + app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); + if (!app) + goto nla_put_failure; + + spin_lock(&dcb_lock); + list_for_each_entry(itr, &dcb_app_list, list) { + if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0) + NLA_PUT(skb, DCB_ATTR_IEEE_APP, + sizeof(itr->app), &itr->app); + } + spin_unlock(&dcb_lock); + nla_nest_end(skb, app); + nla_nest_end(skb, ieee); nlmsg_end(skb, nlh); @@ -1364,8 +1393,93 @@ out: return ret; } +/** + * dcb_getapp - retrieve the DCBX application user priority + * + * On success returns a non-zero 802.1p user priority bitmap + * otherwise returns 0 as the invalid user priority bitmap to + * indicate an error. + */ +u8 dcb_getapp(struct net_device *dev, struct dcb_app *app) +{ + struct dcb_app_type *itr; + u8 prio = 0; + + spin_lock(&dcb_lock); + list_for_each_entry(itr, &dcb_app_list, list) { + if (itr->app.selector == app->selector && + itr->app.protocol == app->protocol && + (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) { + prio = itr->app.priority; + break; + } + } + spin_unlock(&dcb_lock); + + return prio; +} +EXPORT_SYMBOL(dcb_getapp); + +/** + * ixgbe_dcbnl_setapp - add dcb application data to app list + * + * Priority 0 is the default priority this removes applications + * from the app list if the priority is set to zero. + */ +u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) +{ + struct dcb_app_type *itr; + + spin_lock(&dcb_lock); + /* Search for existing match and replace */ + list_for_each_entry(itr, &dcb_app_list, list) { + if (itr->app.selector == new->selector && + itr->app.protocol == new->protocol && + (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) { + if (new->priority) + itr->app.priority = new->priority; + else { + list_del(&itr->list); + kfree(itr); + } + goto out; + } + } + /* App type does not exist add new application type */ + if (new->priority) { + struct dcb_app_type *entry; + entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); + if (!entry) { + spin_unlock(&dcb_lock); + return -ENOMEM; + } + + memcpy(&entry->app, new, sizeof(*new)); + strncpy(entry->name, dev->name, IFNAMSIZ); + list_add(&entry->list, &dcb_app_list); + } +out: + spin_unlock(&dcb_lock); + return 0; +} +EXPORT_SYMBOL(dcb_setapp); + +void dcb_flushapp(void) +{ + struct dcb_app_type *app; + + spin_lock(&dcb_lock); + list_for_each_entry(app, &dcb_app_list, list) { + list_del(&app->list); + kfree(app); + } + spin_unlock(&dcb_lock); +} + static int __init dcbnl_init(void) { + INIT_LIST_HEAD(&dcb_app_list); + rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL); rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL); @@ -1377,7 +1491,6 @@ static void __exit dcbnl_exit(void) { rtnl_unregister(PF_UNSPEC, RTM_GETDCB); rtnl_unregister(PF_UNSPEC, RTM_SETDCB); + dcb_flushapp(); } module_exit(dcbnl_exit); - - -- cgit v1.2.3-59-g8ed1b From 96b99684e365f28d49bdb1221ca022b75cb91a98 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 30 Dec 2010 09:26:37 +0000 Subject: net_dcb: add application notifiers DCBx applications priorities can be changed dynamically. If application stacks are expected to keep the skb priority consistent with the dcbx priority the stack will need to be notified when these changes occur. This patch adds application notifiers for the stack to register with. Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- include/net/dcbevent.h | 31 +++++++++++++++++++++++++++++++ net/dcb/Makefile | 2 +- net/dcb/dcbevent.c | 40 ++++++++++++++++++++++++++++++++++++++++ net/dcb/dcbnl.c | 2 ++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 include/net/dcbevent.h create mode 100644 net/dcb/dcbevent.c diff --git a/include/net/dcbevent.h b/include/net/dcbevent.h new file mode 100644 index 000000000000..bc1e7ef40171 --- /dev/null +++ b/include/net/dcbevent.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Author: John Fastabend + */ + +#ifndef _DCB_EVENT_H +#define _DCB_EVENT_H + +enum dcbevent_notif_type { + DCB_APP_EVENT = 1, +}; + +extern int register_dcbevent_notifier(struct notifier_block *nb); +extern int unregister_dcbevent_notifier(struct notifier_block *nb); +extern int call_dcbevent_notifiers(unsigned long val, void *v); + +#endif diff --git a/net/dcb/Makefile b/net/dcb/Makefile index 9930f4cde818..c1282c9e64fa 100644 --- a/net/dcb/Makefile +++ b/net/dcb/Makefile @@ -1 +1 @@ -obj-$(CONFIG_DCB) += dcbnl.o +obj-$(CONFIG_DCB) += dcbnl.o dcbevent.o diff --git a/net/dcb/dcbevent.c b/net/dcb/dcbevent.c new file mode 100644 index 000000000000..665a8802105a --- /dev/null +++ b/net/dcb/dcbevent.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Author: John Fastabend + */ + +#include +#include + +static ATOMIC_NOTIFIER_HEAD(dcbevent_notif_chain); + +int register_dcbevent_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&dcbevent_notif_chain, nb); +} +EXPORT_SYMBOL(register_dcbevent_notifier); + +int unregister_dcbevent_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&dcbevent_notif_chain, nb); +} +EXPORT_SYMBOL(unregister_dcbevent_notifier); + +int call_dcbevent_notifiers(unsigned long val, void *v) +{ + return atomic_notifier_call_chain(&dcbevent_notif_chain, val, v); +} diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index cfd731faf6c6..69144125fc4f 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1460,6 +1461,7 @@ u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) } out: spin_unlock(&dcb_lock); + call_dcbevent_notifiers(DCB_APP_EVENT, new); return 0; } EXPORT_SYMBOL(dcb_setapp); -- cgit v1.2.3-59-g8ed1b From 6241b6259b16aa390ff4bf50f520685b3801200b Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Thu, 30 Dec 2010 06:26:48 +0000 Subject: dcbnl: adding DCBX engine capability Adding an optional DCBX capability and a pair for get-set routines for setting the device DCBX mode. The DCBX capability is a bit field of supported attributes. The user is expected to set the DCBX mode with a subset of the advertised attributes. This patch is dependent on the following patches: [net-next-2.6 PATCH 1/3] dcbnl: add support for ieee8021Qaz attributes [net-next-2.6 PATCH 2/3] dcbnl: add appliction tlv handlers [net-next-2.6 PATCH 3/3] net_dcb: add application notifiers Signed-off-by: Shmulik Ravid Acked-by: John Fastabend Signed-off-by: David S. Miller --- include/linux/dcbnl.h | 43 +++++++++++++++++++++++++++++++++++++++++++ include/net/dcbnl.h | 5 +++++ net/dcb/dcbnl.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 775bdb4465bf..16eea36d8934 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h @@ -135,6 +135,8 @@ struct dcbmsg { * @DCB_CMD_SAPP: set application protocol configuration * @DCB_CMD_IEEE_SET: set IEEE 802.1Qaz configuration * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration + * @DCB_CMD_GDCBX: get DCBX engine configuration + * @DCB_CMD_SDCBX: set DCBX engine configuration */ enum dcbnl_commands { DCB_CMD_UNDEFINED, @@ -171,6 +173,9 @@ enum dcbnl_commands { DCB_CMD_IEEE_SET, DCB_CMD_IEEE_GET, + DCB_CMD_GDCBX, + DCB_CMD_SDCBX, + __DCB_CMD_ENUM_MAX, DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, }; @@ -191,6 +196,7 @@ enum dcbnl_commands { * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED) * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED) * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) + * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) */ enum dcbnl_attrs { DCB_ATTR_UNDEFINED, @@ -211,6 +217,8 @@ enum dcbnl_attrs { /* IEEE std attributes */ DCB_ATTR_IEEE, + DCB_ATTR_DCBX, + __DCB_ATTR_ENUM_MAX, DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, }; @@ -370,6 +378,8 @@ enum dcbnl_tc_attrs { * @DCB_CAP_ATTR_GSP: (NLA_U8) device supports group strict priority * @DCB_CAP_ATTR_BCN: (NLA_U8) device supports Backwards Congestion * Notification + * @DCB_CAP_ATTR_DCBX: (NLA_U8) device supports DCBX engine + * */ enum dcbnl_cap_attrs { DCB_CAP_ATTR_UNDEFINED, @@ -381,11 +391,44 @@ enum dcbnl_cap_attrs { DCB_CAP_ATTR_PFC_TCS, DCB_CAP_ATTR_GSP, DCB_CAP_ATTR_BCN, + DCB_CAP_ATTR_DCBX, __DCB_CAP_ATTR_ENUM_MAX, DCB_CAP_ATTR_MAX = __DCB_CAP_ATTR_ENUM_MAX - 1, }; +/** + * DCBX capability flags + * + * @DCB_CAP_DCBX_HOST: DCBX negotiation is performed by the host LLDP agent. + * 'set' routines are used to configure the device with + * the negotiated parameters + * + * @DCB_CAP_DCBX_LLD_MANAGED: DCBX negotiation is not performed in the host but + * by another entity + * 'get' routines are used to retrieve the + * negotiated parameters + * 'set' routines can be used to set the initial + * negotiation configuration + * + * @DCB_CAP_DCBX_VER_CEE: for a non-host DCBX engine, indicates the engine + * supports the CEE protocol flavor + * + * @DCB_CAP_DCBX_VER_IEEE: for a non-host DCBX engine, indicates the engine + * supports the IEEE protocol flavor + * + * @DCB_CAP_DCBX_STATIC: for a non-host DCBX engine, indicates the engine + * supports static configuration (i.e no actual + * negotiation is performed negotiated parameters equal + * the initial configuration) + * + */ +#define DCB_CAP_DCBX_HOST 0x01 +#define DCB_CAP_DCBX_LLD_MANAGED 0x02 +#define DCB_CAP_DCBX_VER_CEE 0x04 +#define DCB_CAP_DCBX_VER_IEEE 0x08 +#define DCB_CAP_DCBX_STATIC 0x10 + /** * enum dcbnl_numtcs_attrs - number of traffic classes * diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index ab7d623a2793..c65347b3cbbf 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -70,6 +70,11 @@ struct dcbnl_rtnl_ops { void (*setbcnrp)(struct net_device *, int, u8); u8 (*setapp)(struct net_device *, u8, u16, u8); u8 (*getapp)(struct net_device *, u8, u16); + + /* DCBX configuration */ + u8 (*getdcbx)(struct net_device *); + u8 (*setdcbx)(struct net_device *, u8); + }; #endif /* __NET_DCBNL_H__ */ diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 69144125fc4f..8f83ad859d9b 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -68,6 +68,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { [DCB_ATTR_BCN] = {.type = NLA_NESTED}, [DCB_ATTR_APP] = {.type = NLA_NESTED}, [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, + [DCB_ATTR_DCBX] = {.type = NLA_U8}, }; /* DCB priority flow control to User Priority nested attributes */ @@ -124,6 +125,7 @@ static const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, + [DCB_CAP_ATTR_DCBX] = {.type = NLA_U8}, }; /* DCB capabilities nested attributes. */ @@ -1271,6 +1273,39 @@ nlmsg_failure: return -1; } +/* DCBX configuration */ +static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + int ret = -EINVAL; + + if (!netdev->dcbnl_ops->getdcbx) + return ret; + + ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, + DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); + + return ret; +} + +static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + int ret = -EINVAL; + u8 value; + + if (!tb[DCB_ATTR_DCBX] || !netdev->dcbnl_ops->setdcbx) + return ret; + + value = nla_get_u8(tb[DCB_ATTR_DCBX]); + + ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), + RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, + pid, seq, flags); + + return ret; +} + static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); @@ -1384,6 +1419,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; + case DCB_CMD_GDCBX: + ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; + case DCB_CMD_SDCBX: + ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; default: goto errout; } -- cgit v1.2.3-59-g8ed1b From ea45fe4e176a42d2396878f530cfdc8265bef37b Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Thu, 30 Dec 2010 06:26:55 +0000 Subject: dcbnl: adding DCBX feature flags get-set Adding a pair of set-get routines to dcbnl for setting the negotiation flags of the various DCB features. Conforms to the CEE flavor of DCBX The user sets these flags (enable, advertise, willing) for each feature to be used by the DCBX engine. The 'get' routine returns which of the features is enabled after the negotiation. This patch is dependent on the following patches: [net-next-2.6 PATCH 1/3] dcbnl: add support for ieee8021Qaz attributes [net-next-2.6 PATCH 2/3] dcbnl: add appliction tlv handlers [net-next-2.6 PATCH 3/3] net_dcb: add application notifiers Signed-off-by: Shmulik Ravid Signed-off-by: David S. Miller --- include/linux/dcbnl.h | 33 +++++++++++++ include/net/dcbnl.h | 3 ++ net/dcb/dcbnl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 16eea36d8934..68cd248f6d3e 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h @@ -137,6 +137,8 @@ struct dcbmsg { * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration * @DCB_CMD_GDCBX: get DCBX engine configuration * @DCB_CMD_SDCBX: set DCBX engine configuration + * @DCB_CMD_GFEATCFG: get DCBX features flags + * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags */ enum dcbnl_commands { DCB_CMD_UNDEFINED, @@ -176,6 +178,9 @@ enum dcbnl_commands { DCB_CMD_GDCBX, DCB_CMD_SDCBX, + DCB_CMD_GFEATCFG, + DCB_CMD_SFEATCFG, + __DCB_CMD_ENUM_MAX, DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, }; @@ -197,6 +202,7 @@ enum dcbnl_commands { * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED) * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) + * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED) */ enum dcbnl_attrs { DCB_ATTR_UNDEFINED, @@ -218,6 +224,7 @@ enum dcbnl_attrs { DCB_ATTR_IEEE, DCB_ATTR_DCBX, + DCB_ATTR_FEATCFG, __DCB_ATTR_ENUM_MAX, DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, @@ -506,4 +513,30 @@ enum dcbnl_app_attrs { DCB_APP_ATTR_MAX = __DCB_APP_ATTR_ENUM_MAX - 1, }; +/** + * enum dcbnl_featcfg_attrs - features conifiguration flags + * + * @DCB_FEATCFG_ATTR_UNDEFINED: unspecified attribute to catch errors + * @DCB_FEATCFG_ATTR_ALL: (NLA_FLAG) all features configuration attributes + * @DCB_FEATCFG_ATTR_PG: (NLA_U8) configuration flags for priority groups + * @DCB_FEATCFG_ATTR_PFC: (NLA_U8) configuration flags for priority + * flow control + * @DCB_FEATCFG_ATTR_APP: (NLA_U8) configuration flags for application TLV + * + */ +#define DCB_FEATCFG_ERROR 0x01 /* error in feature resolution */ +#define DCB_FEATCFG_ENABLE 0x02 /* enable feature */ +#define DCB_FEATCFG_WILLING 0x04 /* feature is willing */ +#define DCB_FEATCFG_ADVERTISE 0x08 /* advertise feature */ +enum dcbnl_featcfg_attrs { + DCB_FEATCFG_ATTR_UNDEFINED, + DCB_FEATCFG_ATTR_ALL, + DCB_FEATCFG_ATTR_PG, + DCB_FEATCFG_ATTR_PFC, + DCB_FEATCFG_ATTR_APP, + + __DCB_FEATCFG_ATTR_ENUM_MAX, + DCB_FEATCFG_ATTR_MAX = __DCB_FEATCFG_ATTR_ENUM_MAX - 1, +}; + #endif /* __LINUX_DCBNL_H__ */ diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index c65347b3cbbf..a8e7852b10ab 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -70,11 +70,14 @@ struct dcbnl_rtnl_ops { void (*setbcnrp)(struct net_device *, int, u8); u8 (*setapp)(struct net_device *, u8, u16, u8); u8 (*getapp)(struct net_device *, u8, u16); + u8 (*getfeatcfg)(struct net_device *, int, u8 *); + u8 (*setfeatcfg)(struct net_device *, int, u8); /* DCBX configuration */ u8 (*getdcbx)(struct net_device *); u8 (*setdcbx)(struct net_device *, u8); + }; #endif /* __NET_DCBNL_H__ */ diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 8f83ad859d9b..075af0a08d84 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -69,6 +69,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { [DCB_ATTR_APP] = {.type = NLA_NESTED}, [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, [DCB_ATTR_DCBX] = {.type = NLA_U8}, + [DCB_ATTR_FEATCFG] = {.type = NLA_NESTED}, }; /* DCB priority flow control to User Priority nested attributes */ @@ -182,6 +183,14 @@ static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, }; +/* DCB number of traffic classes nested attributes. */ +static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { + [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, + [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, + [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, + [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, +}; + static LIST_HEAD(dcb_app_list); static DEFINE_SPINLOCK(dcb_lock); @@ -1306,6 +1315,122 @@ static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, return ret; } +static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + struct sk_buff *dcbnl_skb; + struct nlmsghdr *nlh; + struct dcbmsg *dcb; + struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; + u8 value; + int ret = -EINVAL; + int i; + int getall = 0; + + if (!tb[DCB_ATTR_FEATCFG] || !netdev->dcbnl_ops->getfeatcfg) + return ret; + + ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], + dcbnl_featcfg_nest); + if (ret) { + ret = -EINVAL; + goto err_out; + } + + dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!dcbnl_skb) { + ret = -EINVAL; + goto err_out; + } + + nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); + + dcb = NLMSG_DATA(nlh); + dcb->dcb_family = AF_UNSPEC; + dcb->cmd = DCB_CMD_GFEATCFG; + + nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); + if (!nest) { + ret = -EINVAL; + goto err; + } + + if (data[DCB_FEATCFG_ATTR_ALL]) + getall = 1; + + for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { + if (!getall && !data[i]) + continue; + + ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); + if (!ret) { + ret = nla_put_u8(dcbnl_skb, i, value); + + if (ret) { + nla_nest_cancel(dcbnl_skb, nest); + ret = -EINVAL; + goto err; + } + } else + goto err; + } + nla_nest_end(dcbnl_skb, nest); + + nlmsg_end(dcbnl_skb, nlh); + + ret = rtnl_unicast(dcbnl_skb, &init_net, pid); + if (ret) { + ret = -EINVAL; + goto err_out; + } + + return 0; +nlmsg_failure: +err: + kfree_skb(dcbnl_skb); +err_out: + return ret; +} + +static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, + u32 pid, u32 seq, u16 flags) +{ + struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; + int ret = -EINVAL; + u8 value; + int i; + + if (!tb[DCB_ATTR_FEATCFG] || !netdev->dcbnl_ops->setfeatcfg) + return ret; + + ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], + dcbnl_featcfg_nest); + + if (ret) { + ret = -EINVAL; + goto err; + } + + for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { + if (data[i] == NULL) + continue; + + value = nla_get_u8(data[i]); + + ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); + + if (ret) + goto operr; + } + +operr: + ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SFEATCFG, + DCB_ATTR_FEATCFG, pid, seq, flags); + +err: + return ret; +} + static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); @@ -1427,6 +1552,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; + case DCB_CMD_GFEATCFG: + ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; + case DCB_CMD_SFEATCFG: + ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags); + goto out; default: goto errout; } -- cgit v1.2.3-59-g8ed1b From 785b9b1aebcb748fb7627ad4c12dffb7f4f91b55 Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Thu, 30 Dec 2010 06:27:03 +0000 Subject: bnx2x: adding dcbnl support Adding dcbnl implementation to bnx2x allowing users to manage the embedded DCBX engine. This patch is dependent on the following patches: [net-next-2.6 PATCH 1/3] dcbnl: add support for ieee8021Qaz attributes [net-next-2.6 PATCH 2/3] dcbnl: add appliction tlv handlers [net-next-2.6 PATCH 3/3] net_dcb: add application notifiers Signed-off-by: Shmulik Ravid Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 23 +- drivers/net/bnx2x/bnx2x_dcb.c | 663 +++++++++++++++++++++++++++++++++++++++-- drivers/net/bnx2x/bnx2x_dcb.h | 9 +- drivers/net/bnx2x/bnx2x_main.c | 8 +- 4 files changed, 677 insertions(+), 26 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index f14c6ed62bbb..77d6c8d6d86b 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,15 +22,17 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.00-2" -#define DRV_MODULE_RELDATE "2010/12/13" +#define DRV_MODULE_VERSION "1.62.00-3" +#define DRV_MODULE_RELDATE "2010/12/21" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE #define BNX2X_NEW_NAPI - +#if defined(CONFIG_DCB) +#define BCM_DCB +#endif #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" @@ -1186,7 +1188,20 @@ struct bnx2x { /* LLDP params */ struct bnx2x_config_lldp_params lldp_config_params; - /* DCBX params */ + /* DCB support on/off */ + u16 dcb_state; +#define BNX2X_DCB_STATE_OFF 0 +#define BNX2X_DCB_STATE_ON 1 + + /* DCBX engine mode */ + int dcbx_enabled; +#define BNX2X_DCBX_ENABLED_OFF 0 +#define BNX2X_DCBX_ENABLED_ON_NEG_OFF 1 +#define BNX2X_DCBX_ENABLED_ON_NEG_ON 2 +#define BNX2X_DCBX_ENABLED_INVALID (-1) + + bool dcbx_mode_uset; + struct bnx2x_config_dcbx_params dcbx_config_params; struct bnx2x_dcbx_port_params dcbx_port_params; diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 0b86480379ff..fb60021f81fb 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -619,13 +619,10 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) *buff = REG_RD(bp, (offset + i)); - - if (BNX2X_DCBX_CONFIG_INV_VALUE != dp->admin_dcbx_enable) { - if (dp->admin_dcbx_enable) - SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); - else - RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); - } + if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == dp->overwrite_settings)) { @@ -734,12 +731,26 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, REG_WR(bp, (offset + i), *buff); } -/* default */ +void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) +{ + if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp)) { + bp->dcb_state = dcb_on; + bp->dcbx_enabled = dcbx_enabled; + } else { + bp->dcb_state = false; + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_INVALID; + } + DP(NETIF_MSG_LINK, "DCB state [%s:%s]\n", + dcb_on ? "ON" : "OFF", + dcbx_enabled == BNX2X_DCBX_ENABLED_OFF ? "user-mode" : + dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF ? "on-chip static" : + dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON ? + "on-chip with negotiation" : "invalid"); +} + void bnx2x_dcbx_init_params(struct bnx2x *bp) { bp->dcbx_config_params.admin_dcbx_version = 0x0; /* 0 - CEE; 1 - IEEE */ - bp->dcbx_config_params.dcb_enable = 1; - bp->dcbx_config_params.admin_dcbx_enable = 1; bp->dcbx_config_params.admin_ets_willing = 1; bp->dcbx_config_params.admin_pfc_willing = 1; bp->dcbx_config_params.overwrite_settings = 1; @@ -807,23 +818,27 @@ void bnx2x_dcbx_init_params(struct bnx2x *bp) void bnx2x_dcbx_init(struct bnx2x *bp) { u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; + + if (bp->dcbx_enabled <= 0) + return; + /* validate: * chip of good for dcbx version, * dcb is wanted * the function is pmf * shmem2 contains DCBX support fields */ - DP(NETIF_MSG_LINK, "dcb_enable %d bp->port.pmf %d\n", - bp->dcbx_config_params.dcb_enable, bp->port.pmf); + DP(NETIF_MSG_LINK, "dcb_state %d bp->port.pmf %d\n", + bp->dcb_state, bp->port.pmf); - if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp) && - bp->dcbx_config_params.dcb_enable && - bp->port.pmf && + if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf && SHMEM2_HAS(bp, dcbx_lldp_params_offset)) { - dcbx_lldp_params_offset = SHMEM2_RD(bp, - dcbx_lldp_params_offset); + dcbx_lldp_params_offset = + SHMEM2_RD(bp, dcbx_lldp_params_offset); + DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", dcbx_lldp_params_offset); + if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { bnx2x_dcbx_lldp_updated_params(bp, dcbx_lldp_params_offset); @@ -1452,7 +1467,7 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, ******************************************************************************/ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) { - struct flow_control_configuration *pfc_fw_cfg = 0; + struct flow_control_configuration *pfc_fw_cfg = NULL; u16 pri_bit = 0; u8 cos = 0, pri = 0; struct priority_cos *tt2cos; @@ -1489,3 +1504,615 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) } bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg); } +/* DCB netlink */ +#ifdef BCM_DCB +#include + +#define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \ + DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC) + +static inline bool bnx2x_dcbnl_set_valid(struct bnx2x *bp) +{ + /* validate dcbnl call that may change HW state: + * DCB is on and DCBX mode was SUCCESSFULLY set by the user. + */ + return bp->dcb_state && bp->dcbx_mode_uset; +} + +static u8 bnx2x_dcbnl_get_state(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %d\n", bp->dcb_state); + return bp->dcb_state; +} + +static u8 bnx2x_dcbnl_set_state(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off"); + + bnx2x_dcbx_set_state(bp, (state ? true : false), bp->dcbx_enabled); + return 0; +} + +static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev, + u8 *perm_addr) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "GET-PERM-ADDR\n"); + + /* first the HW mac address */ + memcpy(perm_addr, netdev->dev_addr, netdev->addr_len); + +#ifdef BCM_CNIC + /* second SAN address */ + memcpy(perm_addr+netdev->addr_len, bp->fip_mac, netdev->addr_len); +#endif +} + +static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio, + u8 prio_type, u8 pgid, u8 bw_pct, + u8 up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + + DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, pgid); + if (!bnx2x_dcbnl_set_valid(bp) || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES) + return; + + /** + * bw_pct ingnored - band-width percentage devision between user + * priorities within the same group is not + * standard and hence not supported + * + * prio_type igonred - priority levels within the same group are not + * standard and hence are not supported. According + * to the standard pgid 15 is dedicated to strict + * prioirty traffic (on the port level). + * + * up_map ignored + */ + + bp->dcbx_config_params.admin_configuration_ets_pg[prio] = pgid; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; +} + +static void bnx2x_dcbnl_set_pg_bwgcfg_tx(struct net_device *netdev, + int pgid, u8 bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "pgid[%d] = %d\n", pgid, bw_pct); + + if (!bnx2x_dcbnl_set_valid(bp) || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES) + return; + + bp->dcbx_config_params.admin_configuration_bw_precentage[pgid] = bw_pct; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; +} + +static void bnx2x_dcbnl_set_pg_tccfg_rx(struct net_device *netdev, int prio, + u8 prio_type, u8 pgid, u8 bw_pct, + u8 up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n"); +} + +static void bnx2x_dcbnl_set_pg_bwgcfg_rx(struct net_device *netdev, + int pgid, u8 bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n"); +} + +static void bnx2x_dcbnl_get_pg_tccfg_tx(struct net_device *netdev, int prio, + u8 *prio_type, u8 *pgid, u8 *bw_pct, + u8 *up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio = %d\n", prio); + + /** + * bw_pct ingnored - band-width percentage devision between user + * priorities within the same group is not + * standard and hence not supported + * + * prio_type igonred - priority levels within the same group are not + * standard and hence are not supported. According + * to the standard pgid 15 is dedicated to strict + * prioirty traffic (on the port level). + * + * up_map ignored + */ + *up_map = *bw_pct = *prio_type = *pgid = 0; + + if (!bp->dcb_state || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES) + return; + + *pgid = DCBX_PRI_PG_GET(bp->dcbx_local_feat.ets.pri_pg_tbl, prio); +} + +static void bnx2x_dcbnl_get_pg_bwgcfg_tx(struct net_device *netdev, + int pgid, u8 *bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "pgid = %d\n", pgid); + + *bw_pct = 0; + + if (!bp->dcb_state || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES) + return; + + *bw_pct = DCBX_PG_BW_GET(bp->dcbx_local_feat.ets.pg_bw_tbl, pgid); +} + +static void bnx2x_dcbnl_get_pg_tccfg_rx(struct net_device *netdev, int prio, + u8 *prio_type, u8 *pgid, u8 *bw_pct, + u8 *up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n"); + + *prio_type = *pgid = *bw_pct = *up_map = 0; +} + +static void bnx2x_dcbnl_get_pg_bwgcfg_rx(struct net_device *netdev, + int pgid, u8 *bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n"); + + *bw_pct = 0; +} + +static void bnx2x_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, + u8 setting) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, setting); + + if (!bnx2x_dcbnl_set_valid(bp) || prio >= MAX_PFC_PRIORITIES) + return; + + bp->dcbx_config_params.admin_pfc_bitmap |= ((setting ? 1 : 0) << prio); + + if (setting) + bp->dcbx_config_params.admin_pfc_tx_enable = 1; +} + +static void bnx2x_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, + u8 *setting) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio = %d\n", prio); + + *setting = 0; + + if (!bp->dcb_state || prio >= MAX_PFC_PRIORITIES) + return; + + *setting = (bp->dcbx_local_feat.pfc.pri_en_bitmap >> prio) & 0x1; +} + +static u8 bnx2x_dcbnl_set_all(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + int rc = 0; + + DP(NETIF_MSG_LINK, "SET-ALL\n"); + + if (!bnx2x_dcbnl_set_valid(bp)) + return 1; + + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + netdev_err(bp->dev, "Handling parity error recovery. " + "Try again later\n"); + return 1; + } + if (netif_running(bp->dev)) { + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); + } + DP(NETIF_MSG_LINK, "set_dcbx_params done (%d)\n", rc); + if (rc) + return 1; + + return 0; +} + +static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + if (bp->dcb_state) { + switch (capid) { + case DCB_CAP_ATTR_PG: + *cap = true; + break; + case DCB_CAP_ATTR_PFC: + *cap = true; + break; + case DCB_CAP_ATTR_UP2TC: + *cap = false; + break; + case DCB_CAP_ATTR_PG_TCS: + *cap = 0x80; /* 8 priorities for PGs */ + break; + case DCB_CAP_ATTR_PFC_TCS: + *cap = 0x80; /* 8 priorities for PFC */ + break; + case DCB_CAP_ATTR_GSP: + *cap = true; + break; + case DCB_CAP_ATTR_BCN: + *cap = false; + break; + case DCB_CAP_ATTR_DCBX: + *cap = BNX2X_DCBX_CAPS; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + DP(NETIF_MSG_LINK, "capid %d:%x\n", capid, *cap); + return rval; +} + +static u8 bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "tcid %d\n", tcid); + + if (bp->dcb_state) { + switch (tcid) { + case DCB_NUMTCS_ATTR_PG: + *num = E2_NUM_OF_COS; + break; + case DCB_NUMTCS_ATTR_PFC: + *num = E2_NUM_OF_COS; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +static u8 bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "num tcs = %d; Not supported\n", num); + return -EINVAL; +} + +static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %d\n", bp->dcbx_local_feat.pfc.enabled); + + if (!bp->dcb_state) + return 0; + + return bp->dcbx_local_feat.pfc.enabled; +} + +static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off"); + + if (!bnx2x_dcbnl_set_valid(bp)) + return; + + bp->dcbx_config_params.admin_pfc_tx_enable = + bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0); +} + +static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent, + u8 idtype, u16 idval) +{ + if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID)) + return false; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != + DCBX_APP_SF_ETH_TYPE) + return false; + break; + case DCB_APP_IDTYPE_PORTNUM: + if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != + DCBX_APP_SF_PORT) + return false; + break; + default: + return false; + } + if (app_ent->app_id != idval) + return false; + + return true; +} + +static void bnx2x_admin_app_set_ent( + struct bnx2x_admin_priority_app_table *app_ent, + u8 idtype, u16 idval, u8 up) +{ + app_ent->valid = 1; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + app_ent->traffic_type = TRAFFIC_TYPE_ETH; + break; + case DCB_APP_IDTYPE_PORTNUM: + app_ent->traffic_type = TRAFFIC_TYPE_PORT; + break; + default: + break; /* never gets here */ + } + app_ent->app_id = idval; + app_ent->priority = up; +} + +static bool bnx2x_admin_app_is_equal( + struct bnx2x_admin_priority_app_table *app_ent, + u8 idtype, u16 idval) +{ + if (!app_ent->valid) + return false; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + if (app_ent->traffic_type != TRAFFIC_TYPE_ETH) + return false; + break; + case DCB_APP_IDTYPE_PORTNUM: + if (app_ent->traffic_type != TRAFFIC_TYPE_PORT) + return false; + break; + default: + return false; + } + if (app_ent->app_id != idval) + return false; + + return true; +} + +static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up) +{ + int i, ff; + + /* iterate over the app entries looking for idtype and idval */ + for (i = 0, ff = -1; i < 4; i++) { + struct bnx2x_admin_priority_app_table *app_ent = + &bp->dcbx_config_params.admin_priority_app_table[i]; + if (bnx2x_admin_app_is_equal(app_ent, idtype, idval)) + break; + + if (ff < 0 && !app_ent->valid) + ff = i; + } + if (i < 4) + /* if found overwrite up */ + bp->dcbx_config_params. + admin_priority_app_table[i].priority = up; + else if (ff >= 0) + /* not found use first-free */ + bnx2x_admin_app_set_ent( + &bp->dcbx_config_params.admin_priority_app_table[ff], + idtype, idval, up); + else + /* app table is full */ + return -EBUSY; + + /* up configured, if not 0 make sure feature is enabled */ + if (up) + bp->dcbx_config_params.admin_application_priority_tx_enable = 1; + + return 0; +} + +static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype, + u16 idval, u8 up) +{ + struct bnx2x *bp = netdev_priv(netdev); + + DP(NETIF_MSG_LINK, "app_type %d, app_id %x, prio bitmap %d\n", + idtype, idval, up); + + if (!bnx2x_dcbnl_set_valid(bp)) + return -EINVAL; + + /* verify idtype */ + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + case DCB_APP_IDTYPE_PORTNUM: + break; + default: + return -EINVAL; + } + return bnx2x_set_admin_app_up(bp, idtype, idval, up); +} + +static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype, + u16 idval) +{ + int i; + u8 up = 0; + + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval); + + /* iterate over the app entries looking for idtype and idval */ + for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) + if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i], + idtype, idval)) + break; + + if (i < DCBX_MAX_APP_PROTOCOL) + /* if found return up */ + up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap; + else + DP(NETIF_MSG_LINK, "app not found\n"); + + return up; +} + +static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 state; + + state = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE; + + if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF) + state |= DCB_CAP_DCBX_STATIC; + + return state; +} + +static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %02x\n", state); + + /* set dcbx mode */ + + if ((state & BNX2X_DCBX_CAPS) != state) { + BNX2X_ERR("Requested DCBX mode %x is beyond advertised " + "capabilities\n", state); + return 1; + } + + if (bp->dcb_state != BNX2X_DCB_STATE_ON) { + BNX2X_ERR("DCB turned off, DCBX configuration is invalid\n"); + return 1; + } + + if (state & DCB_CAP_DCBX_STATIC) + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_OFF; + else + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_ON; + + bp->dcbx_mode_uset = true; + return 0; +} + + +static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid, + u8 *flags) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "featid %d\n", featid); + + if (bp->dcb_state) { + *flags = 0; + switch (featid) { + case DCB_FEATCFG_ATTR_PG: + if (bp->dcbx_local_feat.ets.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & DCBX_LOCAL_ETS_ERROR) + *flags |= DCB_FEATCFG_ERROR; + break; + case DCB_FEATCFG_ATTR_PFC: + if (bp->dcbx_local_feat.pfc.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR | + DCBX_LOCAL_PFC_MISMATCH)) + *flags |= DCB_FEATCFG_ERROR; + break; + case DCB_FEATCFG_ATTR_APP: + if (bp->dcbx_local_feat.app.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR | + DCBX_LOCAL_APP_MISMATCH)) + *flags |= DCB_FEATCFG_ERROR; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid, + u8 flags) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "featid = %d flags = %02x\n", featid, flags); + + /* ignore the 'advertise' flag */ + if (bnx2x_dcbnl_set_valid(bp)) { + switch (featid) { + case DCB_FEATCFG_ATTR_PG: + bp->dcbx_config_params.admin_ets_enable = + flags & DCB_FEATCFG_ENABLE ? 1 : 0; + bp->dcbx_config_params.admin_ets_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + case DCB_FEATCFG_ATTR_PFC: + bp->dcbx_config_params.admin_pfc_enable = + flags & DCB_FEATCFG_ENABLE ? 1 : 0; + bp->dcbx_config_params.admin_pfc_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + case DCB_FEATCFG_ATTR_APP: + /* ignore enable, always enabled */ + bp->dcbx_config_params.admin_app_priority_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = { + .getstate = bnx2x_dcbnl_get_state, + .setstate = bnx2x_dcbnl_set_state, + .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr, + .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx, + .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx, + .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx, + .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx, + .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx, + .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx, + .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx, + .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx, + .setpfccfg = bnx2x_dcbnl_set_pfc_cfg, + .getpfccfg = bnx2x_dcbnl_get_pfc_cfg, + .setall = bnx2x_dcbnl_set_all, + .getcap = bnx2x_dcbnl_get_cap, + .getnumtcs = bnx2x_dcbnl_get_numtcs, + .setnumtcs = bnx2x_dcbnl_set_numtcs, + .getpfcstate = bnx2x_dcbnl_get_pfc_state, + .setpfcstate = bnx2x_dcbnl_set_pfc_state, + .getapp = bnx2x_dcbnl_get_app_up, + .setapp = bnx2x_dcbnl_set_app_up, + .getdcbx = bnx2x_dcbnl_get_dcbx, + .setdcbx = bnx2x_dcbnl_set_dcbx, + .getfeatcfg = bnx2x_dcbnl_get_featcfg, + .setfeatcfg = bnx2x_dcbnl_set_featcfg, +}; + +#endif /* BCM_DCB */ diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index 8dea56b511f5..f650f98e4092 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -51,7 +51,6 @@ struct bnx2x_dcbx_pfc_params { }; struct bnx2x_dcbx_port_params { - u32 dcbx_enabled; struct bnx2x_dcbx_pfc_params pfc; struct bnx2x_dcbx_pg_params ets; struct bnx2x_dcbx_app_params app; @@ -88,8 +87,6 @@ struct bnx2x_admin_priority_app_table { * DCBX protocol configuration parameters. ******************************************************************************/ struct bnx2x_config_dcbx_params { - u32 dcb_enable; - u32 admin_dcbx_enable; u32 overwrite_settings; u32 admin_dcbx_version; u32 admin_ets_enable; @@ -182,6 +179,7 @@ struct bnx2x; void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp); void bnx2x_dcbx_update(struct work_struct *work); void bnx2x_dcbx_init_params(struct bnx2x *bp); +void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled); enum { BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1, @@ -190,4 +188,9 @@ enum { }; void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); +/* DCB netlink */ +#ifdef BCM_DCB +extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops; +#endif /* BCM_DCB */ + #endif /* BNX2X_DCB_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index cf54427a8d80..489a5512a04d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3107,7 +3107,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) bnx2x_pmf_update(bp); if (bp->port.pmf && - (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS)) + (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) && + bp->dcbx_enabled > 0) /* start dcbx state machine */ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_NEG_RECEIVED); @@ -8795,6 +8796,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2x_timer; + bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); bnx2x_dcbx_init_params(bp); return rc; @@ -9146,6 +9148,10 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; +#ifdef BCM_DCB + dev->dcbnl_ops = &bnx2x_dcbnl_ops; +#endif + /* get_port_hwinfo() will set prtad and mmds properly */ bp->mdio.prtad = MDIO_PRTAD_NONE; bp->mdio.mmds = 0; -- cgit v1.2.3-59-g8ed1b From 7c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6 Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Thu, 30 Dec 2010 06:27:10 +0000 Subject: dcbnl: cleanup A couple of small cleanups for patches: [net-next-2.6 PATCH 1/3] dcbnl: add support for ieee8021Qaz attributes [net-next-2.6 PATCH 2/3] dcbnl: add appliction tlv handlers [net-next-2.6 PATCH 3/3] net_dcb: add application notifiers Signed-off-by: Shmulik Ravid Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 075af0a08d84..ff3c12d2cd72 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1642,7 +1642,7 @@ out: } EXPORT_SYMBOL(dcb_setapp); -void dcb_flushapp(void) +static void dcb_flushapp(void) { struct dcb_app_type *app; -- cgit v1.2.3-59-g8ed1b From 0438a1b24437cf007ed0e0f5f6b414d5b49468dc Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Fri, 31 Dec 2010 10:55:38 -0800 Subject: netxen: update module description This driver supports only Intelligent Ethernet Adapters. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index ceeaac989df2..58a3643948c3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -38,7 +38,7 @@ #include #include -MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); +MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Intelligent Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); -- cgit v1.2.3-59-g8ed1b From a29ba9d2d84889686a3af1c5a6023f28be75ccba Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 31 Dec 2010 11:03:14 -0800 Subject: bnx2: Free IRQ before freeing status block memory When changing ring size, we free all memory including status block memory. If we're in INTA mode and sharing IRQ, the IRQ handler can be called and it will reference the NULL status block pointer. Because of the lockless design of the IRQ handler, there is no simple way to synchronize and prevent this. So we avoid this problem by freeing the IRQ handler before freeing the status block memory. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 6fa798468ad4..44aed3b0da60 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6096,7 +6096,7 @@ bnx2_request_irq(struct bnx2 *bp) } static void -bnx2_free_irq(struct bnx2 *bp) +__bnx2_free_irq(struct bnx2 *bp) { struct bnx2_irq *irq; int i; @@ -6107,6 +6107,13 @@ bnx2_free_irq(struct bnx2 *bp) free_irq(irq->vector, &bp->bnx2_napi[i]); irq->requested = 0; } +} + +static void +bnx2_free_irq(struct bnx2 *bp) +{ + + __bnx2_free_irq(bp); if (bp->flags & BNX2_FLAG_USING_MSI) pci_disable_msi(bp->pdev); else if (bp->flags & BNX2_FLAG_USING_MSIX) @@ -7092,6 +7099,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) bnx2_netif_stop(bp, true); bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); + __bnx2_free_irq(bp); bnx2_free_skbs(bp); bnx2_free_mem(bp); } @@ -7103,6 +7111,9 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) int rc; rc = bnx2_alloc_mem(bp); + if (!rc) + rc = bnx2_request_irq(bp); + if (!rc) rc = bnx2_init_nic(bp, 0); -- cgit v1.2.3-59-g8ed1b From 0268102d53c872b42e214f95492065c8058b042e Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 31 Dec 2010 11:04:02 -0800 Subject: bnx2: Update firmware and version Update MIPS firmware to 6.2.1, with improved small packet performance in RSS mode, and iSCSI CID allocation bug fix on 5708. Update driver version to 2.0.21. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 8 +- firmware/Makefile | 4 +- firmware/WHENCE | 4 +- firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex | 5815 ------------------------- firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex | 5818 +++++++++++++++++++++++++ firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex | 6488 ---------------------------- firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex | 6526 +++++++++++++++++++++++++++++ 7 files changed, 12352 insertions(+), 12311 deletions(-) delete mode 100644 firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex create mode 100644 firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex delete mode 100644 firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex create mode 100644 firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 44aed3b0da60..df99edf3464a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,11 +56,11 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.20" -#define DRV_MODULE_RELDATE "Nov 24, 2010" -#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" +#define DRV_MODULE_VERSION "2.0.21" +#define DRV_MODULE_RELDATE "Dec 23, 2010" +#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" -#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" +#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1.fw" #define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw" #define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw" diff --git a/firmware/Makefile b/firmware/Makefile index 69779d1637e1..0a9d1e28ad23 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,10 +35,10 @@ fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.5.0.fw \ bnx2x/bnx2x-e1h-6.2.5.0.fw \ bnx2x/bnx2x-e2-6.2.5.0.fw -fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \ +fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1.fw \ bnx2/bnx2-rv2p-09-6.0.17.fw \ bnx2/bnx2-rv2p-09ax-6.0.17.fw \ - bnx2/bnx2-mips-06-6.0.15.fw \ + bnx2/bnx2-mips-06-6.2.1.fw \ bnx2/bnx2-rv2p-06-6.0.15.fw fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin diff --git a/firmware/WHENCE b/firmware/WHENCE index f22c4dfd0733..14aaee85d062 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -699,9 +699,9 @@ Found in hex form in kernel source. Driver: BNX2 - Broadcom NetXtremeII -File: bnx2/bnx2-mips-06-6.0.15.fw +File: bnx2/bnx2-mips-06-6.2.1.fw File: bnx2/bnx2-rv2p-06-6.0.15.fw -File: bnx2/bnx2-mips-09-6.0.17.fw +File: bnx2/bnx2-mips-09-6.2.1.fw File: bnx2/bnx2-rv2p-09-6.0.17.fw File: bnx2/bnx2-rv2p-09ax-6.0.17.fw diff --git a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex deleted file mode 100644 index e9bbdc3b0397..000000000000 --- a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex +++ /dev/null @@ -1,5815 +0,0 @@ -:10000000080001180800000000004A68000000C84D -:1000100000000000000000000000000008004A6826 -:100020000000001400004B30080000A00800000091 -:100030000000568800004B4408005800000000846F -:100040000000A1CC08005688000001580000A25012 -:100050000800321008000000000072D00000A3A8C1 -:10006000000000000000000000000000080072D046 -:100070000000002400011678080004900800040025 -:10008000000017D40001169C0000000000000000D2 -:100090000000000000000000000000000000000060 -:1000A000080000A80800000000003BFC00012E70C2 -:1000B0000000000000000000000000000000000040 -:0800C000000000000000000038 -:0800C8000A00004600000000E0 -:1000D000000000000000000D636F6D362E302E31E1 -:1000E0003500000006000F020000000000000003C1 -:1000F000000000C800000032000000030000000003 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E0000000000010000003000000000000000DEF -:1001F0000000000D3C02080024424AA03C03080015 -:1002000024634B9CAC4000000043202B1480FFFD76 -:10021000244200043C1D080037BD7FFC03A0F021F0 -:100220003C100800261001183C1C0800279C4AA01E -:100230000E000168000000000000000D27470100CB -:1002400090E3000B2402001A94E5000814620028D1 -:10025000000020218CE200003C0308008C63004475 -:1002600094E60014000211C20002104030A4000203 -:10027000005A10212463000130A50004A446008028 -:100280003C010800AC23004410A000190004202BFE -:100290008F4202B804410008240400013C02080017 -:1002A0008C420060244200013C010800AC22006046 -:1002B00003E00008008010218CE2002094E3001687 -:1002C00000002021AF4202808CE20004A743028498 -:1002D000AF4202883C021000AF4202B83C02080064 -:1002E0008C42005C244200013C010800AC22005C0E -:1002F00003E00008008010212747010090E3000B75 -:100300002402000394E50008146200280000202164 -:100310008CE200003C0308008C63004494E6001467 -:10032000000211C20002104030A40002005A102145 -:100330002463000130A50004A44600803C010800AD -:10034000AC23004410A000190004202B8F4202B8F7 -:1003500004410008240400013C0208008C420060B3 -:10036000244200013C010800AC22006003E00008C8 -:10037000008010218CE2002094E300160000202170 -:10038000AF4202808CE20004A7430284AF4202889D -:100390003C021000AF4202B83C0208008C42005CF4 -:1003A000244200013C010800AC22005C03E000088C -:1003B000008010218F4301002402010050620003DD -:1003C000000311C20000000D000311C20002104022 -:1003D000005A1021A440008003E000080000102112 -:1003E0009362000003E00008AF80000003E0000813 -:1003F0000000102103E00008000010212402010089 -:1004000014820008000000003C0208008C4200FC3E -:10041000244200013C010800AC2200FC0A0000DD7F -:1004200030A200203C0208008C42008424420001DB -:100430003C010800AC22008430A2002010400008DB -:1004400030A300103C0208008C4201082442000145 -:100450003C010800AC22010803E000080000000095 -:1004600010600008000000003C0208008C420104FB -:10047000244200013C010800AC22010403E0000812 -:10048000000000003C0208008C42010024420001F0 -:100490003C010800AC22010003E00008000000005D -:1004A00027BDFFE8AFBF0010274401009483000878 -:1004B000306200041040001B306600028F4202B818 -:1004C00004410008240500013C0208008C42006041 -:1004D000244200013C010800AC2200600A0001290E -:1004E0008FBF00108C82002094830016000028210A -:1004F000AF4202808C820004A7430284AF4202888C -:100500003C021000AF4202B83C0208008C42005C82 -:10051000244200013C010800AC22005C0A000129D1 -:100520008FBF001010C00006006028218F4401001A -:100530000E0000CD000000000A0001282405000183 -:100540008F8200088F4301045043000700002821D8 -:100550008F4401000E0000CD000000008F42010416 -:10056000AF820008000028218FBF001000A01021DA -:1005700003E0000827BD001827BDFFE8AFBF001447 -:10058000AFB00010974201083043700024022000F1 -:100590001062000B286220011440002F000010217F -:1005A00024024000106200250000000024026000C8 -:1005B00010620026000010210A0001658FBF0014A0 -:1005C00027500100920200091040001A2403000184 -:1005D0003C0208008C420020104000160000182148 -:1005E0000E00049300000000960300083C0608007B -:1005F00094C64B5E8E0400188F8200209605000C76 -:1006000000031C0000661825AC440000AC45000443 -:1006100024040001AC400008AC40000CAC400010C9 -:10062000AC400014AC4000180E0004B8AC43001CF1 -:10063000000018210A000164006010210E0003254B -:10064000000000000A000164000010210E000EE905 -:1006500000000000000010218FBF00148FB00010B8 -:1006600003E0000827BD001827BDFFE0AFB2001867 -:100670003C036010AFBF001CAFB10014AFB000105E -:100680008C6450002402FF7F3C1A800000822024EA -:100690003484380C24020037AC6450003C1208004B -:1006A00026524AD8AF42000824020C80AF420024F0 -:1006B0003C1B80083C06080024C60324024010218D -:1006C0002404001D2484FFFFAC4600000481FFFDCC -:1006D000244200043C020800244204B03C0108000B -:1006E000AC224AE03C020800244202303C010800EF -:1006F000AC224AE43C020800244201743C03080096 -:100700002463032C3C040800248403D83C0508001F -:1007100024A538F03C010800AC224B403C02080004 -:10072000244202EC3C010800AC264B243C010800AA -:10073000AC254B343C010800AC234B3C3C01080089 -:10074000AC244B443C010800AC224B483C0108005F -:10075000AC234ADC3C010800AC204AE83C0108001C -:10076000AC204AEC3C010800AC204AF03C010800F7 -:10077000AC204AF43C010800AC204AF83C010800D7 -:10078000AC204AFC3C010800AC204B003C010800B6 -:10079000AC244B043C010800AC204B083C01080091 -:1007A000AC204B0C3C010800AC204B103C01080075 -:1007B000AC204B143C010800AC204B183C01080055 -:1007C000AC264B1C3C010800AC264B203C01080029 -:1007D000AC254B303C010800AC234B380E000623FF -:1007E000000000003C028000344200708C42000097 -:1007F000AF8200143C0308008C6300208F82000449 -:10080000104300043C0280000E00045BAF83000430 -:100810003C028000344600703C0308008C6300A05A -:100820003C0208008C4200A4104300048F84001492 -:100830003C010800AC2300A4A743009E8CCA000022 -:100840003C0308008C6300BC3C0208008C4200B8EA -:100850000144202300641821000040210064202B63 -:1008600000481021004410213C010800AC2300BCCA -:100870003C010800AC2200B88F5100003222000772 -:100880001040FFDCAF8A00148CC600003C05080055 -:100890008CA500BC3C0408008C8400B800CA30233E -:1008A00000A628210000102100A6302B0082202164 -:1008B00000862021322700013C010800AC2500BC45 -:1008C0003C010800AC2400B810E0001F32220002F6 -:1008D0008F420100AF4200208F420104AF4200A8C6 -:1008E0009342010B0E0000C6305000FF2E02001E86 -:1008F00054400004001010800E0000C90A000213CA -:1009000000000000005210218C4200000040F80955 -:1009100000000000104000053C0240008F4301042D -:100920003C026020AC4300143C024000AF4201385E -:100930003C0208008C420034244200013C010800C3 -:10094000AC220034322200021040000E3222000499 -:100950008F4201400E0000C6AF4200200E000295FB -:10096000000000003C024000AF4201783C02080059 -:100970008C420038244200013C010800AC220038BF -:10098000322200041040FF983C0280008F42018018 -:100990000E0000C6AF4200208F43018024020F00EA -:1009A00014620005000000008F420188A742009CED -:1009B0000A0002483C0240009362000024030050F9 -:1009C000304200FF144300083C0240000E00027B4E -:1009D00000000000544000043C0240000E000D7571 -:1009E000000000003C024000AF4201B83C02080099 -:1009F0008C42003C244200013C010800AC22003C37 -:100A00000A0001C83C0280003C0290003442000110 -:100A100000822025AF4400208F4200200440FFFECA -:100A20000000000003E00008000000003C0280001D -:100A3000344200010082202503E00008AF4400207A -:100A400027BDFFE0AFB10014AFB0001000808821D7 -:100A5000AFBF00180E00025030B000FF9362007D5F -:100A60000220202102028025A370007D8F70007477 -:100A70003C0280000E000259020280241600000988 -:100A80008FBF00188F4201F80440FFFE24020002CD -:100A9000AF5101C0A34201C43C021000AF4201F8B3 -:100AA0008FBF00188FB100148FB0001003E0000852 -:100AB00027BD002027BDFFE8AFBF0010974201848B -:100AC0008F440188304202001040000500002821B8 -:100AD0000E000FAA000000000A00028D240500018C -:100AE0003C02FF0004800005008218243C02040040 -:100AF000506200019362003E240500018FBF001088 -:100B000000A0102103E0000827BD0018A360002208 -:100B10008F4401400A00025E2405000127BDFFE862 -:100B2000AFBF0014AFB0001093620000304400FF6C -:100B300038830020388200300003182B0002102B6D -:100B40000062182410600003240200501482008008 -:100B50008FBF001493620005304200011040007CFA -:100B60008FBF0014934201482443FFFF2C6200050D -:100B7000104000788FB00010000310803C03080084 -:100B800024634A68004310218C42000000400008A2 -:100B9000000000000E0002508F4401408F70000CD6 -:100BA0008F4201441602000224020001AF62000CD1 -:100BB0000E0002598F4401408F420144145000043A -:100BC0008FBF00148FB000100A000F2027BD00183F -:100BD0008F62000C0A0003040000000097620010FE -:100BE0008F4301443042FFFF1462001A00000000EE -:100BF00024020001A76200108F4202380443001053 -:100C00008F4201403C02003F3446F0003C0560004A -:100C10003C04FFC08CA22BBC0044182400461024C6 -:100C20000002130200031D82106200390000000060 -:100C30008F4202380440FFF7000000008F4201405D -:100C4000AF4202003C021000AF4202380A00032209 -:100C50008FBF0014976200100A0003040000000018 -:100C60000E0002508F440140976200128F430144EE -:100C70003050FFFF1603000224020001A762001299 -:100C80000E0002598F4401408F42014416020004B5 -:100C90008FBF00148FB000100A00029127BD00180A -:100CA000976200120A00030400000000976200141B -:100CB0008F4301443042FFFF14620006240200010A -:100CC0008FBF00148FB00010A76200140A00124AF0 -:100CD00027BD0018976200141440001D8FBF001438 -:100CE0000A00031C00000000976200168F430144B5 -:100CF0003042FFFF1462000B240200018FBF00147A -:100D00008FB00010A76200160A000B1227BD001852 -:100D10009742007824420004A76200100A000322D0 -:100D20008FBF001497620016240300013042FFFFBA -:100D3000144300078FBF00143C0208008C4200706F -:100D4000244200013C010800AC2200708FBF001457 -:100D50008FB0001003E0000827BD001827BDFFE892 -:100D6000AFBF0014AFB000108F50010093620000BD -:100D700093430109304400FF2402001F106200A5C4 -:100D80002862002010400018240200382862000A5F -:100D90001040000C2402000B286200081040002CB8 -:100DA00000000000046000E52862000214400028F2 -:100DB00024020006106200268FBF00140A00041FE0 -:100DC0008FB000101062005E2862000B144000DC3F -:100DD0008FBF00142402000E106200738FB0001049 -:100DE0000A00041F00000000106200C028620039E1 -:100DF0001040000A2402008024020036106200CA5B -:100E000028620037104000B424020035106200C18F -:100E10008FBF00140A00041F8FB000101062002B57 -:100E20002862008110400006240200C82402003914 -:100E3000106200B48FBF00140A00041F8FB00010AE -:100E4000106200998FBF00140A00041F8FB00010B9 -:100E50003C0208008C420020104000B98FBF0014F3 -:100E60000E000493000000008F4201008F830020D9 -:100E70009745010C97460108AC6200008F420104BF -:100E80003C04080094844B5E00052C00AC62000416 -:100E90008F4201180006340000C43025AC620008FF -:100EA0008F42011C24040001AC62000C9342010A31 -:100EB00000A22825AC650010AC600014AC600018DE -:100EC000AC66001C0A0003F58FBF00143C0208004A -:100ED0008C4200201040009A8FBF00140E00049333 -:100EE00000000000974401083C03080094634B5E37 -:100EF0009745010C000422029746010E8F820020C4 -:100F0000000426000083202500052C003C030080FF -:100F100000A6282500832025AC400000AC4000043A -:100F2000AC400008AC40000CAC450010AC400014D4 -:100F3000AC400018AC44001C0A0003F42404000177 -:100F40009742010C14400015000000009362000558 -:100F50003042001014400011000000000E0002504A -:100F6000020020219362000502002021344200107B -:100F70000E000259A36200059362000024030020C2 -:100F8000304200FF1043006D020020218FBF00148B -:100F90008FB000100A000FC027BD00180000000D20 -:100FA0000A00041E8FBF00143C0208008C4200207F -:100FB000104000638FBF00140E0004930000000077 -:100FC0008F4201048F8300209744010C3C050800E8 -:100FD00094A54B5EAC6200009762002C00042400D4 -:100FE0003042FFFF008220253C02400E00A228254F -:100FF000AC640004AC600008AC60000CAC60001095 -:10100000AC600014AC600018AC65001C0A0003F46E -:10101000240400010E00025002002021A7600008F5 -:101020000E00025902002021020020210E00025E63 -:10103000240500013C0208008C42002010400040C2 -:101040008FBF00140E000493000000009742010CB3 -:101050008F8300203C05080094A54B5E000214001D -:10106000AC700000AC620004AC6000088F64004CFF -:101070003C02401F00A22825AC64000C8F62005087 -:1010800024040001AC6200108F620054AC620014B2 -:10109000AC600018AC65001C8FBF00148FB000104E -:1010A0000A0004B827BD0018240200205082002541 -:1010B0008FB000100E000F0A020020211040002007 -:1010C0008FBF0014020020218FB0001000002821E3 -:1010D0000A00025E27BD0018020020218FBF001405 -:1010E0008FB000100A00058027BD00189745010C3D -:1010F000020020218FBF00148FB000100A0005A04D -:1011000027BD0018020020218FB000100A0005C57D -:1011100027BD00189345010D020020218FB000105B -:101120000A00060F27BD0018020020218FBF0014FF -:101130008FB000100A0005EB27BD00188FBF001408 -:101140008FB0001003E0000827BD00188F4202781E -:101150000440FFFE2402000234840080AF440240B9 -:10116000A34202443C02100003E00008AF420278B0 -:101170003C04080094844B6A3C0208008C424B7487 -:101180003083FFFF000318C000431021AF42003C32 -:101190003C0208008C424B70AF4200383C020050C9 -:1011A00034420008AF4200300000000000000000A0 -:1011B000000000008F420000304200201040FFFD80 -:1011C000000000008F4204003C010800AC224B608C -:1011D0008F4204043C010800AC224B643C02002016 -:1011E000AF420030000000003C02080094424B680F -:1011F0003C03080094634B6C3C05080094A54B6EBF -:1012000024840001004310213083FFFF3C010800CB -:10121000A4224B683C010800A4244B6A1465000317 -:10122000000000003C010800A4204B6A03E0000815 -:10123000000000003C05000A27BDFFE80345282107 -:101240003C04080024844B50AFBF00100E00051D65 -:101250002406000A3C02080094424B523C0308005A -:1012600094634B6E3042000F244200030043180485 -:1012700024027FFF0043102B10400002AF83001CAC -:101280000000000D0E00042A000000003C020800CF -:1012900094424B5A8FBF001027BD001803E000088E -:1012A000A74200A23C02000A034210219443000618 -:1012B0003C02080094424B5A3C010800A4234B56C0 -:1012C000004310238F83001C00021400000214034B -:1012D0000043102B03E000083842000127BDFFE85F -:1012E000AFBF00103C02000A0342102194420006E6 -:1012F0003C010800A4224B560E00047700000000B9 -:101300005440FFF93C02000A8FBF001003E00008C0 -:1013100027BD001827BDFFE8AFBF00100E000477FF -:101320000000000010400003000000000E000485D3 -:10133000000000003C0208008C424B608FBF001090 -:1013400027430400AF4200383C0208008C424B6443 -:1013500027BD0018AF830020AF42003C3C020005CF -:10136000AF42003003E00008AF8000188F82001801 -:101370003C0300060002114000431025AF4200303C -:101380000000000000000000000000008F4200008C -:10139000304200101040FFFD27420400AF820020C1 -:1013A00003E00008AF8000183C0608008CC64B64C0 -:1013B0008F8500188F8300203C02080094424B5A0E -:1013C00027BDFFE024A50001246300202442000182 -:1013D00024C70020AFB10014AFB00010AFBF001899 -:1013E000AF850018AF8300203C010800A4224B5AAF -:1013F000309000FF3C010800AC274B6404C100089A -:101400000000882104E00006000000003C02080003 -:101410008C424B60244200013C010800AC224B602E -:101420003C02080094424B5A3C03080094634B680A -:101430000010202B004310262C42000100441025F0 -:10144000144000048F830018240200101462000F5F -:10145000000000000E0004A9241100013C03080054 -:1014600094634B5A3C02080094424B681462000398 -:10147000000000000E00042A000000001600000317 -:10148000000000000E000493000000003C03080070 -:1014900094634B5E3C02080094424B5C2463000161 -:1014A0003064FFFF3C010800A4234B5E148200035C -:1014B000000000003C010800A4204B5E1200000662 -:1014C000000000003C02080094424B5AA74200A2D0 -:1014D0000A00050B022010210E0004770000000016 -:1014E00010400004022010210E00048500000000BE -:1014F000022010218FBF00188FB100148FB0001090 -:1015000003E0000827BD00203084FFFF30A5FFFF67 -:101510000000182110800007000000003082000148 -:101520001040000200042042006518210A00051343 -:101530000005284003E000080060102110C00006EC -:1015400024C6FFFF8CA2000024A50004AC8200008A -:101550000A00051D2484000403E0000800000000C8 -:1015600010A0000824A3FFFFAC86000000000000CC -:10157000000000002402FFFF2463FFFF1462FFFA53 -:101580002484000403E0000800000000240200019D -:10159000AF62000CA7620010A7620012A7620014DD -:1015A00003E00008A76200163082007F034210218A -:1015B0003C08000E004818213C0208008C42002024 -:1015C00027BDFFD82407FF80AFB3001CAFB20018BF -:1015D000AFB10014AFB00010AFBF00200080802179 -:1015E00030B100FF0087202430D200FF1040002FD0 -:1015F00000009821AF44002C9062000024030050AA -:10160000304200FF1443000E000000003C020800BE -:101610008C4200E00202102100471024AF42002C4F -:101620003C0208008C4200E0020210213042007FA0 -:101630000342102100481021944200D43053FFFF90 -:101640000E000493000000003C02080094424B5E30 -:101650008F8300200011340000C2302500122C00BE -:101660003C02400000C2302534A50001AC700000EF -:101670008FBF0020AC6000048FB20018AC7300086C -:101680008FB10014AC60000C8FB3001CAC6500106F -:101690008FB00010AC60001424040001AC6000188E -:1016A00027BD00280A0004B8AC66001C8FBF0020CC -:1016B0008FB3001C8FB200188FB100148FB00010D0 -:1016C00003E0000827BD00289343010F2402001007 -:1016D0001062000E2865001110A0000724020012FD -:1016E000240200082405003A1062000600003021A0 -:1016F00003E0000800000000240500351462FFFC30 -:10170000000030210A000538000000008F420074FC -:1017100024420FA003E00008AF62000C27BDFFE8E1 -:10172000AFBF00100E00025E240500018FBF001045 -:1017300024020001A762001227BD00182402000144 -:1017400003E00008A360002227BDFFE0AFB1001452 -:10175000AFB00010AFBF001830B1FFFF0E00025055 -:10176000008080219362003F24030004304200FF88 -:101770001443000C02002021122000082402000A59 -:101780000E00053100000000936200052403FFFEF7 -:1017900000431024A362000524020012A362003F4C -:1017A000020020210E000259A360008116200003D0 -:1017B000020020210E0005950000000002002021FB -:1017C000322600FF8FBF00188FB100148FB00010B9 -:1017D000240500380A00053827BD002027BDFFE09A -:1017E000AFBF001CAFB20018AFB10014AFB0001013 -:1017F0000E000250008080210E0005310000000024 -:101800009362003F24120018305100FF123200038F -:101810000200202124020012A362003F936200050F -:101820002403FFFE004310240E000259A3620005AA -:10183000020020212405002016320007000030217C -:101840008FBF001C8FB200188FB100148FB0001032 -:101850000A00025E27BD00208FBF001C8FB2001857 -:101860008FB100148FB00010240500390A0005382C -:1018700027BD002027BDFFE8AFB00010AFBF0014A8 -:101880009742010C2405003600808021144000108E -:10189000304600FF0E00025000000000240200123B -:1018A000A362003F93620005344200100E00053130 -:1018B000A36200050E00025902002021020020212F -:1018C0000E00025E240500200A000604000000004D -:1018D0000E000538000000000E000250020020211A -:1018E000936200232403FF9F020020210043102461 -:1018F0008FBF00148FB00010A36200230A000259AA -:1019000027BD001827BDFFE0AFBF0018AFB100141E -:10191000AFB0001030B100FF0E00025000808021F7 -:10192000240200120E000531A362003F0E0002598E -:101930000200202102002021022030218FBF001848 -:101940008FB100148FB00010240500350A0005384F -:1019500027BD0020A380002C03E00008A380002DF9 -:101960008F4202780440FFFE8F820034AF42024073 -:1019700024020002A34202443C02100003E00008DB -:10198000AF4202783C0360008C6254003042000891 -:101990001440FFFD000000008C625408AF82000C70 -:1019A00024020052AC605408AC645430AC6254342D -:1019B0002402000803E00008AC6254003C0260000E -:1019C0008C42540030420008104000053C03600087 -:1019D0008C625400304200081440FFFD00000000FB -:1019E0008F83000C3C02600003E00008AC43540805 -:1019F00090A3000024020005008040213063003FD6 -:101A000000004821146200050000502190A2001C33 -:101A100094A3001E304900FF306AFFFFAD00000CA8 -:101A2000AD000010AD000024950200148D05001CCF -:101A30008D0400183042FFFF0049102300021100FE -:101A4000000237C3004038210086202300A2102B5B -:101A50000082202300A72823AD05001CAD04001838 -:101A6000A5090014A5090020A50A001603E0000836 -:101A7000A50A00228F4201F80440FFFE2402000262 -:101A8000AF4401C0A34201C43C02100003E00008BF -:101A9000AF4201F83C0208008C4200B427BDFFE8C9 -:101AA000AFBF001424420001AFB000103C01080099 -:101AB000AC2200B48F4300243C02001F30AA00FF78 -:101AC0003442FF8030D800FF006280240080F8217B -:101AD00030EF00FF1158003B01405821240CFF80DB -:101AE0003C19000A3163007F000310C00003194055 -:101AF000006218213C0208008C4200DC25680001CD -:101B0000310D007F03E21021004310213043007F9C -:101B100003431821004C102400794821AF420024CF -:101B20008D220024016C1824006C7026AD22000C5C -:101B30008D220024310800FFAD22001095220014F0 -:101B4000952300208D27001C3042FFFF3063FFFFEC -:101B50008D2600180043102300021100000227C345 -:101B60000040282100C4302300E2102B00C23023A3 -:101B700000E53823AD27001CAD2600189522002073 -:101B8000A522001495220022154B000AA52200165A -:101B90008D2300248D220008254600013145008058 -:101BA0001462000430C4007F108F000238AA008045 -:101BB00000C0502151AF000131C800FF1518FFC906 -:101BC000010058218F8400343082007F03421821A5 -:101BD0003C02000A006218212402FF8000822024B7 -:101BE000AF440024A06A0079A06A00838C62005090 -:101BF0008F840034AC6200708C6500743C027FFFFF -:101C00003442FFFF00A228240E00066BAC6500746E -:101C1000AF5000248FBF00148FB0001003E0000805 -:101C200027BD001827BDFFC0AFBE0038AFB70034D6 -:101C3000AFB5002CAFB20020AFB1001CAFB00018A0 -:101C4000AFBF003CAFB60030AFB40028AFB3002444 -:101C50008F4500248F4600288F43002C3C02001F34 -:101C60003442FF800062182400C230240080A82182 -:101C7000AFA3001400A2F0240E00062FAFA60010A0 -:101C80003C0208008C4200E02410FF8003608821A1 -:101C900002A2102100501024AF4200243C02080090 -:101CA0008C4200E002A210213042007F0342182142 -:101CB0003C02000A00629021924200D293630084A9 -:101CC000305700FF306300FF24020001106200342F -:101CD000036020212402000214620036000000008C -:101CE0000E001216024028219223008392220083C4 -:101CF0003063007F3042007F000210C000031940B3 -:101D0000006218213C0208008C4200DC02A2102173 -:101D10000043382100F01024AF42002892250078BB -:101D20009224008330E2007F034218213C02000C21 -:101D300014850007006280212402FFFFA24200F107 -:101D40002402FFFFA64200F20A0007272402FFFF39 -:101D500096020020A24200F196020022A64200F262 -:101D60008E020024AE4200F492220083A24200F0D0 -:101D70008E4200C8AE4200FC8E4200C4AE4200F863 -:101D80008E220050AE4201008E4200CCAE420104D1 -:101D9000922200853042003F0A0007823442004010 -:101DA0000E00123902402821922200850A00078283 -:101DB0003042003F936200852403FFDF3042003F42 -:101DC000A36200859362008500431024A36200850E -:101DD0009363008393620078307400FF304200FF09 -:101DE00010540036240AFF803C0C000C3283007F24 -:101DF000000310C000031940006218213C020800D3 -:101E00008C4200DC268800013109007F02A21021EB -:101E10000043382130E2007F0342182100EA1024F9 -:101E2000AF420028006C80218E020024028A182410 -:101E3000006A5826AE02000C8E020024310800FF12 -:101E4000AE02001096020014960300208E07001CBC -:101E50003042FFFF3063FFFF8E060018004310235F -:101E600000021100000227C30040282100C43023D3 -:101E700000E2102B00C2302300E53823AE07001C1F -:101E8000AE06001896020020A60200149602002258 -:101E9000A602001692220079304200FF105400077B -:101EA0000000000051370001316800FF92220078E5 -:101EB000304200FF1448FFCD0100A0219222008390 -:101EC000A22200798E2200500A0007E2AE220070A2 -:101ED000A22200858E22004C2405FF80AE42010C18 -:101EE0009222008534420020A2220085924200D135 -:101EF0003C0308008C6300DC305400FF3C02080007 -:101F00008C4200E400143140001420C002A31821C8 -:101F100000C4202102A210210064382100461021B3 -:101F20000045182400E52824AF450028AF43002CC5 -:101F30003042007F924400D030E3007F03422821EA -:101F4000034318213C02000C006280213C02000E79 -:101F5000309600FF00A298211296002A000000008F -:101F60008E02000C02002021026028211040002572 -:101F7000261000280E00064A000000009262000DA4 -:101F800026830001307400FF3042007FA262000D02 -:101F90002404FF801697FFF0267300203C020800FF -:101FA0008C4200DC0000A02102A210210044102479 -:101FB000AF4200283C0208008C4200E43C030800C9 -:101FC0008C6300DC02A2102100441024AF42002CDC -:101FD0003C0208008C4200E402A318213063007F19 -:101FE00002A210213042007F034220210343182126 -:101FF0003C02000C006280213C02000E0A0007A493 -:10200000008298218E4200D8AE2200508E4200D825 -:10201000AE22007092250083924600D19223008365 -:10202000924400D12402FF8000A228243063007F64 -:10203000308400FF00A628250064182A10600002E2 -:1020400030A500FF38A50080A2250083A2250079D5 -:102050000E00063D000000009222007E02A020211A -:10206000A222007A8E2300743C027FFF3442FFFFDD -:10207000006218240E00066BAE2300748FA20010BD -:10208000AF5E00248FBF003CAF4200288FBE0038F7 -:102090008FA200148FB700348FB600308FB5002C9C -:1020A0008FB400288FB300248FB200208FB1001CA2 -:1020B0008FB0001827BD004003E00008AF42002C9D -:1020C00090A2000024420001A0A200003C030800EE -:1020D0008C6300F4304200FF1443000F0080302175 -:1020E000A0A000003C0208008C4200E48F84003471 -:1020F000008220213082007F034218213C02000C24 -:10210000006218212402FF8000822024ACC300005A -:1021100003E00008AF4400288C8200002442002025 -:1021200003E00008AC82000094C200003C080800F4 -:10213000950800CA30E7FFFF008048210102102106 -:10214000A4C2000094C200003042FFFF00E2102B46 -:1021500054400001A4C7000094A200003C03080002 -:102160008C6300CC24420001A4A2000094A20000D1 -:102170003042FFFF544300078F8600280107102BD1 -:10218000A4A000005440000101003821A4C70000B1 -:102190008F8600288CC4001CAF44003C94A2000031 -:1021A0008F43003C3042FFFF000210C00062182144 -:1021B000AF43003C8F42003C008220231880000483 -:1021C000000000008CC200180A00084324420001ED -:1021D0008CC20018AF4200383C020050344200105C -:1021E000AF420030000000000000000000000000CE -:1021F0008F420000304200201040FFFD0000000030 -:102200008F420404AD2200048F420400AD2200007E -:102210003C020020AF42003003E000080000000054 -:1022200027BDFFE0AFB20018AFB10014AFB000108F -:10223000AFBF001C94C2000000C080213C12080007 -:10224000965200C624420001A60200009603000038 -:1022500094E2000000E03021144300058FB100300B -:102260000E000818024038210A000875000000001E -:102270008C8300048C820004244200400461000727 -:10228000AC8200048C8200040440000400000000C2 -:102290008C82000024420001AC8200009602000003 -:1022A0003042FFFF50520001A600000096220000BD -:1022B00024420001A62200008F82002896230000FD -:1022C00094420016144300048FBF001C2402000136 -:1022D000A62200008FBF001C8FB200188FB100141F -:1022E0008FB0001003E0000827BD00208F89002870 -:1022F00027BDFFE0AFBF00188D220028274804004B -:1023000030E700FFAF4200388D22002CAF8800304C -:10231000AF42003C3C020005AF420030000000002C -:1023200000000000000000000000000000000000AD -:10233000000000008C82000C8C82000CAD020000BA -:102340008C820010AD0200048C820018AD020008DF -:102350008C82001CAD02000C8CA20014AD02001097 -:102360008C820020AD02001490820005304200FFF4 -:1023700000021200AD0200188CA20018AD02001C71 -:102380008CA2000CAD0200208CA20010AD02002433 -:102390008CA2001CAD0200288CA20020AD02002CF3 -:1023A000AD060030AD000034978300263402FFFFF5 -:1023B00014620002006020213404FFFF10E00011CD -:1023C000AD04003895230036952400362402000120 -:1023D0003063FFFF000318C20069182190650040B8 -:1023E000308400070082100400451025A0620040E0 -:1023F0008F820028944200563042FFFF0A0008DC1A -:10240000AD02003C952300369524003624020001DD -:102410003063FFFF000318C2006918219065004077 -:1024200030840007008210040002102700451024A9 -:10243000A0620040AD00003C000000000000000071 -:10244000000000003C02000634420040AF42003071 -:102450000000000000000000000000008F420000AB -:10246000304200101040FFFD8F860028AF880030FA -:1024700024C2005624C7003C24C4002824C50032CE -:1024800024C600360E000856AFA200108FBF0018F9 -:1024900003E0000827BD00208F8300243C060800CD -:1024A0008CC600E88F82003430633FFF0003198040 -:1024B00000461021004310212403FF803046007F96 -:1024C00000431024AF420028034618213C02000CB0 -:1024D0000062302190C2000D30A500FF00003821BD -:1024E00034420010A0C2000D8F8900288F8A00247A -:1024F00095230036000A13823048000324020001AD -:10250000A4C3000E1102000B2902000210400005B6 -:10251000240200021100000C240300010A0009201B -:102520000000182111020006000000000A00092026 -:10253000000018218CC2002C0A000920244300014D -:102540008CC20014244300018CC200180043102BDD -:1025500050400009240700012402002714A20003B0 -:10256000000000000A00092C240700019522003E0B -:1025700024420001A522003E000A138230430003DA -:102580002C62000210400009008028211460000421 -:102590000000000094C200360A00093C3046FFFFEC -:1025A0008CC600380A00093C008028210000302138 -:1025B0003C04080024844B780A00088900000000CD -:1025C000274901008D22000C9523000601202021BF -:1025D000000216023046003F3063FFFF240200274E -:1025E00000C0282128C7002810C2000EAF83002495 -:1025F00010E00008240200312402002110C200096A -:102600002402002510C200079382002D0A00095BF6 -:102610000000000010C200059382002D0A00095B33 -:10262000000000000A0008F4000000000A0006266E -:102630000000000095230006912400058D25000C64 -:102640008D2600108D2700188D28001C8D29002054 -:10265000244200013C010800A4234B7E3C010800F9 -:10266000A0244B7D3C010800AC254B843C010800B4 -:10267000AC264B883C010800AC274B903C0108007D -:10268000AC284B943C010800AC294B9803E00008AF -:10269000A382002D8F87002827BDFFC0AFB3003471 -:1026A000AFB20030AFB1002CAFB00028AFBF0038E0 -:1026B0003C0208008C4200D094E3003030B0FFFFB1 -:1026C000005010073045FFFF3063FFFF00C0982126 -:1026D000A7A200103C110800963100C614A3000602 -:1026E0003092FFFF8CE2002424420030AF42003CD5 -:1026F0000A0009948CE2002094E200323042FFFF8D -:1027000054A2000827A400188CE2002C24420030B8 -:10271000AF42003C8CE20028AF4200380A0009A218 -:102720008F84002827A5001027A60020022038212A -:102730000E000818A7A000208FA200182442003025 -:10274000AF4200388FA2001CAF42003C8F840028AB -:102750003C020005AF42003094820034274304005D -:102760003042FFFF0202102B14400007AF830030FD -:1027700094820054948300340202102100431023F9 -:102780000A0009B63043FFFF94830054948200345A -:102790000223182100501023006218233063FFFF2A -:1027A000948200163042FFFF144300030000000033 -:1027B0000A0009C424030001948200163042FFFF7E -:1027C0000043102B104000058F82003094820016C9 -:1027D000006210233043FFFF8F820030AC530000B3 -:1027E000AC400004AC520008AC43000C3C020006B4 -:1027F00034420010AF420030000000000000000032 -:10280000000000008F420000304200101040FFFD29 -:10281000001018C2006418219065004032040007BF -:10282000240200018FBF00388FB300348FB2003014 -:102830008FB1002C8FB000280082100400451025B5 -:1028400027BD004003E00008A062004027BDFFA8AC -:10285000AFB60050AFB5004CAFB40048AFB30044C2 -:10286000AFB1003CAFBF0054AFB20040AFB00038D2 -:102870008C9000003C0208008C4200E88F860034F7 -:10288000960300022413FF8000C2302130633FFF13 -:102890000003198000C3382100F3102490B2000017 -:1028A000AF42002C9203000230E2007F034230214D -:1028B0003C02000E00C28821306300C024020040A8 -:1028C0000080A82100A0B021146200260000A021F1 -:1028D0008E3400388E2200181440000224020001B9 -:1028E000AE2200189202000D304200201440001564 -:1028F0008F8200343C0308008C6300DC001238C077 -:10290000001231400043102100C730210046382119 -:1029100030E300073C02008030E6007800C230253A -:102920000343182100F31024AF4208002463090078 -:10293000AF4608108E2200188C6300080043102157 -:10294000AE2200188E22002C8E2300182442000193 -:102950000062182B1060003D000000000A000A7899 -:1029600000000000920300022402FFC00043102474 -:10297000304200FF1440000524020001AE2200187E -:10298000962200360A000A613054FFFF8E2200149E -:1029900024420001AE22001892020000000216003C -:1029A0000002160304410029000000009602000204 -:1029B00027A4001000802821A7A20016960200027A -:1029C00024070001000030213042FFFFAF820024C5 -:1029D0000E000889AFA0001C960300023C0408000A -:1029E0008C8400E88F82003430633FFF000319803D -:1029F00000441021004310213043007F3C05000CAF -:102A00000053102403431821AF4200280065182109 -:102A10009062000D001221403042007FA062000D44 -:102A20003C0308008C6300E48F82003400431021D3 -:102A30000044382130E2007F03421021004510217C -:102A400000F31824AF430028AEA200009222000D2C -:102A5000304200101040001302A020218F83002874 -:102A60008EA40000028030219462003E2442FFFFC9 -:102A7000A462003E948400029625000E3084FFFF7D -:102A80000E00097330A5FFFF8F82002894430034A5 -:102A90009622000E1443000302A02021240200010C -:102AA000A382002C02C028210E0007FE00000000B7 -:102AB0008FBF00548FB600508FB5004C8FB40048C4 -:102AC0008FB300448FB200408FB1003C8FB000380C -:102AD00003E0000827BD00588F82002827BDFFD0E3 -:102AE000AFB40028AFB20020AFBF002CAFB30024BA -:102AF000AFB1001CAFB00018904400D0904300D19B -:102B00000000A021309200FFA3A30010306300FF5B -:102B10008C5100D88C5300DC1072002B2402000171 -:102B20003C0308008C6300E493A400108F820034FF -:102B30002406FF800004214000431021004410219E -:102B40003043007F00461024AF4200280343182181 -:102B50003C02000C006218218C62000427A40014BF -:102B600027A50010022280210270102304400015C6 -:102B7000AFA300149062000D00C21024304200FF89 -:102B800014400007020088219062000D344200408A -:102B90000E0007FEA062000D0A000ABD93A20010FD -:102BA0000E0009E1241400018F830028AC7000D8C6 -:102BB00093A20010A06200D193A200101452FFD87B -:102BC0000000000024020001168200048FBF002CC8 -:102BD0000E000626000000008FBF002C8FB40028D6 -:102BE0008FB300248FB200208FB1001C8FB000186B -:102BF00003E0000827BD003027BDFFD8AFB3001C9D -:102C0000AFB20018AFB10014AFB00010AFBF0020DA -:102C10000080982100E0802130B1FFFF0E00049376 -:102C200030D200FF000000000000000000000000A3 -:102C30008F820020AC510000AC520004AC5300085D -:102C4000AC40000CAC400010AC400014AC4000188C -:102C50003C03080094634B5E02038025AC50001CCB -:102C6000000000000000000000000000240400013B -:102C70008FBF00208FB3001C8FB200188FB10014DB -:102C80008FB000100A0004B827BD002827BDFFE858 -:102C9000AFB00010AFBF001430A5FFFF30C600FF7B -:102CA0000080802124020C80AF420024000000003C -:102CB0000000000000000000000000000000000014 -:102CC0000E000ACC000000003C040800248400E050 -:102CD0008C8200002403FF808FBF001402021021A9 -:102CE00000431024AF4200248C8200003C03000A01 -:102CF000020280213210007F035010218FB000109B -:102D00000043102127BD001803E00008AF8200280F -:102D100027BDFFE8AFBF00108F4401403C0308000F -:102D20008C6300E02402FF80AF840034008318210C -:102D300000621024AF4200243C02000803424021FC -:102D4000950500023063007F3C02000A034318210E -:102D50000062182130A5FFFF3402FFFF0000302180 -:102D60003C07602010A20006AF8300282402FFFF6A -:102D7000A5020002946500D40E000AF130A5FFFF01 -:102D80008FBF001024020C8027BD001803E000084C -:102D9000AF4200243C020008034240219502000299 -:102DA0003C0A0800954A00C63046FFFF14C00007E1 -:102DB0003402FFFF8F8200288F8400343C0760209C -:102DC000944500D40A000B5A30A5FFFF10C200241E -:102DD0008F87002894E2005494E400163045FFFFEA -:102DE00000A6102300A6182B3089FFFF10600004F6 -:102DF0003044FFFF00C51023012210233044FFFFA1 -:102E0000008A102B1040000C012A1023240200011C -:102E1000A50200162402FFFFA502000294E500D4DB -:102E20008F8400340000302130A5FFFF3C07602074 -:102E30000A000AF1000000000044102A10400008B7 -:102E4000000000009502001630420001104000040E -:102E5000000000009742007E24420014A5020016E4 -:102E600003E00008000000008F84002827BDFFE079 -:102E7000AFBF0018948200349483003E1060001AA3 -:102E80003048FFFF9383002C2402000114620027C6 -:102E90008FBF00188F820028000818C23108000771 -:102EA000006218212447003A244900542444002099 -:102EB000244500302446003490620040304200FF38 -:102EC0000102100730420001104000168FBF0018A9 -:102ED0000E000856AFA900108F82002894420034DB -:102EE0000A000B733048FFFF94830036948200344D -:102EF0001043000E8FBF001894820036A482003465 -:102F000094820056A48200548C82002CAC8200244F -:102F100094820032A48200309482003CA482003A61 -:102F20008FBF00180A000B3327BD002003E0000804 -:102F300027BD002027BDFFE8AFBF00108F4A01006A -:102F40003C0508008CA500E03C02080090424B8440 -:102F50003C0C0800958C4B7E01452821304B003FEE -:102F600030A2007F03424021396900323C02000A4E -:102F70003963003F2C630001010240212D2900012B -:102F80002402FF8000A2282401234825AF8A0034B0 -:102F900000801821AF450024000030210080282146 -:102FA00024070001AF8800283C04080024844B78E3 -:102FB000AF8C002415200007A380002D24020020E0 -:102FC0005562000F006020213402FFFF5582000C83 -:102FD000006020212402002015620005000000008E -:102FE0008C6300142402FFFF106200070000000041 -:102FF0000E000889000000000A000BD0000000004D -:103000000E0008F4016028210E000B68000000008B -:103010008FBF001024020C8027BD001803E00008B9 -:10302000AF4200243C0208008C4200E027BDFFA014 -:10303000AFB1003C008210212411FF80AFBE0058C8 -:10304000AFB70054AFB20040AFB00038AFBF005CC4 -:10305000AFB60050AFB5004CAFB40048AFB30044BA -:10306000005110248F4800248F4900288F470028E2 -:10307000AF4200243C0208008C4200E00080902116 -:1030800024060006008210213042007F03421821EE -:103090003C02000A006280213C02001F3442FF8093 -:1030A00000E2382427A40010260500F00122F024B5 -:1030B0000102B8240E00051DAFA700308FA2001832 -:1030C000AE0200C48FA2001CAE0200C88FA2002472 -:1030D000AE0200CC93A40010920300D12402FF8022 -:1030E0000082102400431025304900FF3083007F08 -:1030F0003122007F0062102A10400004000310C03B -:1031000001311026304900FF000310C000031940B0 -:10311000006218213C0208008C4200DC920400D2BC -:10312000024210210043102100511024AF42002818 -:1031300093A300103063007F000310C00003194008 -:10314000006218213C0208008C4200DC024210217F -:10315000004310213042007F034218213C02000C42 -:10316000006240218FA300142402FFFF1062003090 -:10317000309500FF93A2001195030014304400FF26 -:103180003063FFFF0064182B1060000D000000008A -:10319000950400148D07001C8D0600183084FFFF75 -:1031A00000442023000421000000102100E4382105 -:1031B00000E4202B00C230210A000C4A00C4302158 -:1031C000950400148D07001C8D0600183084FFFF45 -:1031D000008220230004210000001021008018211B -:1031E00000C2302300E4202B00C4302300E3382346 -:1031F000AD07001CAD06001893A20011A502001433 -:1032000097A20012A50200168FA20014AD020010B2 -:103210008FA20014AD02000C93A20011A5020020A1 -:1032200097A20012A50200228FA20014AD02002472 -:103230002406FF80024610243256007FAF4200244D -:10324000035618213C02000A006280218E02004CC5 -:103250008FA200203124007F000428C0AE0200505D -:103260008FA200200004214000852821AE020070BA -:1032700093A2001001208821A202008393A20010D3 -:10328000A2020079920200853042003FA20200852E -:103290003C0208008C4200DC024210210045102153 -:1032A00000461024AF42002C3C0208008C4200E48F -:1032B0003C0308008C6300DC024210210044102112 -:1032C00000461024AF4200283C0208008C4200E473 -:1032D00002431821006518210242102100441021E8 -:1032E0003042007F3063007F93A50010034220210D -:1032F000034318213C02000E006240213C02000CF6 -:1033000010B1008C008248213233007F1660001912 -:103310002404FF803C0208008C4200DC02421021A1 -:1033200000441024AF42002C3C0208008C4200E410 -:103330003C0308008C6300DC02421021004410248E -:10334000AF4200283C0208008C4200E402431821EE -:103350003063007F024210213042007F034220216F -:10336000034318213C02000E006240213C02000C85 -:10337000008248219124000D2414FF8000001021B8 -:1033800000942025A124000D950400029505001449 -:103390008D07001C3084FFFF30A5FFFF8D0600184D -:1033A000008520230004210000E4382100C23021E0 -:1033B00000E4202B00C43021AD07001CAD0600182E -:1033C00095020002A5020014A50000168D02000857 -:1033D000AD0200108D020008AD02000C9502000243 -:1033E000A5020020A50000228D020008AD020024E5 -:1033F0009122000D30420040104000422622000180 -:103400003C0208008C4200E0A3B300283C10000AF4 -:103410000242102100541024AF4200243C02080054 -:103420008C4200E0A380002C27A4002C0242102133 -:103430003042007F03421821007018218C6200D8AE -:103440008D26000427A50028AFA9002C00461021D6 -:10345000AC6200D80E0009E1AF83002893A30028D6 -:103460008F8200280E000626A04300D10E000B68B4 -:103470000000000002541024AF4200243C02080067 -:103480008C4200DC00132940001320C000A420213E -:10349000024210210044102100541024AF42002C9D -:1034A0003C0208008C4200E43C0308008C6300DC12 -:1034B00003563021024210210045102100541024EF -:1034C000AF4200283C0208008C4200E4024318216D -:1034D0000064182102421021004510213042007F73 -:1034E0003063007F03422021034318213C02000E79 -:1034F000006240213C02000C00D080210082482163 -:10350000262200013043007F14750005304400FF7F -:103510002403FF800223102400431026304400FFC0 -:1035200093A2001000808821250800281444FF760B -:103530002529002093A400108FA300142402FFFF6C -:103540001062000A308900FF2482000124830001F8 -:103550003042007F14550005306900FF2403FF80CE -:103560000083102400431026304900FF92020078A7 -:10357000305300FF11330032012088213C02080043 -:103580008C4200DC3225007F000520C00005294068 -:1035900000A42021024210212406FF8000441021B3 -:1035A00000461024AF42002C3C0308008C6300DC72 -:1035B0003C0208008C4200E4024318210242102120 -:1035C0000045102100641821004610243063007F5C -:1035D000AF420028034318213C02000E0062402144 -:1035E0003C0208008C4200E48D06000C0100202102 -:1035F00002421021004510213042007F0342182171 -:103600003C02000C0062482110C0000D012028215E -:103610000E00064A000000002402FF800222182447 -:1036200026240001006228263082007F1455000203 -:10363000308300FF30A300FF1473FFD000608821A7 -:103640008E0300743C027FFF3442FFFF00621824A7 -:10365000AE0300740E00066B02402021AF57002419 -:103660008FA20030AF5E00288FBF005C8FBE005875 -:103670008FB700548FB600508FB5004C8FB4004800 -:103680008FB300448FB200408FB1003C8FB0003840 -:1036900027BD006003E00008AF42002C27BDFFD823 -:1036A000AFB1001CAFBF0020AFB000182751018898 -:1036B000922200032408FF803C03000A3047007F69 -:1036C000A3A700108F4601803C0208008C4200E056 -:1036D000AF86003400C2282100A81024AF42002485 -:1036E0009224000030A2007F0342102100431021E9 -:1036F000AF8200283084007F24020002148200255B -:10370000000719403C0208008C4200E400C210216E -:103710000043282130A2007F0342182100A8102472 -:10372000AF4200283C02000C006218219062000D9C -:10373000AFA3001400481025A062000D8FA3001451 -:103740009062000D304200405040006A8FBF002060 -:103750008F860028A380002C27A400148CC200D8D8 -:103760008C63000427A50010004310210E0009E11E -:10377000ACC200D893A300108F8200280E0006264A -:10378000A04300D10E000B68000000000A000E0BE1 -:103790008FBF00200E00062F00C020210E00063D26 -:1037A000000000003C020008034280219223000137 -:1037B0009202007B1443004F8FBF00209222000032 -:1037C0003044007F24020004108200172882000584 -:1037D00010400006240200052402000310820007A6 -:1037E0008FB1001C0A000E0C0000000010820012B5 -:1037F0008FBF00200A000E0C8FB1001C92050083C1 -:10380000920600788E0700748F84003430A500FF84 -:1038100000073E0230C600FF0E00067330E7007F4F -:103820000A000E0B8FBF00200E000BD78F840034D0 -:103830000A000E0B8FBF002024020C80AF42002430 -:103840009202003E30420040104000200000000084 -:103850009202003E00021600000216030441000618 -:10386000000000008F8400340E0005A024050093A2 -:103870000A000E0B8FBF00209202003F24030018A5 -:10388000304200FF1443000C8F84003424050039BB -:103890000E000538000030210E0002508F840034E5 -:1038A00024020012A202003F0E0002598F8400344D -:1038B0000A000E0B8FBF0020240500360E000538CD -:1038C000000030210A000E0B8FBF00200E000250B6 -:1038D0008F8400349202000534420020A2020005C9 -:1038E0000E0002598F8400340E000FC08F84003404 -:1038F0008FBF00208FB1001C8FB0001824020C80F5 -:1039000027BD002803E00008AF42002427BDFFE8E0 -:10391000AFB00010AFBF001427430100946200084D -:103920000002140000021403044100020000802180 -:103930002410000194620008304200801040001AF8 -:10394000020010219462000830422000104000164E -:10395000020010218C6300183C021C2D344219ED2A -:10396000240600061062000F3C0760213C0208009C -:103970008C4200D4104000078F8200288F830028DB -:10398000906200623042000F34420040A062006248 -:103990008F8200288F840034944500D40E000AF1F1 -:1039A00030A5FFFF020010218FBF00148FB0001060 -:1039B00003E0000827BD001827BDFFE0AFB10014E9 -:1039C000AFB00010A380002CAFBF00188F450100DE -:1039D0003C0308008C6300E02402FF80AF850034C4 -:1039E00000A318213064007F0344202100621824C2 -:1039F0003C02000A00822021AF430024275001002E -:103A00008E0200148C8300DCAF8400280043102356 -:103A100018400004000088218E0200140E000A8461 -:103A2000AC8200DC9202000B24030002304200FF53 -:103A30001443002F0000000096020008304300FFEE -:103A40002402008214620005240200840E00093E54 -:103A5000000000000A000E97000000001462000938 -:103A6000240200818F8200288F8400343C0760216B -:103A7000944500D49206000530A5FFFF0A000E868B -:103A800030C600FF14620027000000009202000A06 -:103A9000304300FF306200201040000430620040DC -:103AA0008F8400340A000E82240600401040000477 -:103AB000000316008F8400340A000E8224060041A1 -:103AC00000021603044100178F84003424060042CC -:103AD0008F8200283C076019944500D430A5FFFF71 -:103AE0000E000AF1000000000A000E97000000001E -:103AF0009202000B24030016304200FF1043000620 -:103B0000000000009202000B24030017304200FF67 -:103B100014430004000000000E000E11000000001D -:103B2000004088210E000B68000000009202000A8D -:103B3000304200081040000624020C808F850028C7 -:103B40003C0400080E0011EE0344202124020C80E6 -:103B5000AF4200248FBF0018022010218FB0001048 -:103B60008FB1001403E0000827BD002027BDFFE847 -:103B7000AFBF0014AFB000108F5000243C0308000A -:103B80008C6300E08F4501002402FF8000A3182110 -:103B90003064007F03442021006218243C02000AA4 -:103BA00000822021AF850034AF4300249082006260 -:103BB000AF8400283042000F34420050A0820062DF -:103BC0003C02001F3442FF800E00062602028024C1 -:103BD000AF5000248FBF00148FB0001003E0000826 -:103BE00027BD00183C0208008C4200201040001D38 -:103BF0002745010090A300093C0200080342202150 -:103C000024020018546200033C0200080A000ED887 -:103C10002402000803422021240200161462000539 -:103C20002402001724020012A082003F0A000EE2C4 -:103C300094A700085462000694A700089362000548 -:103C40002403FFFE00431024A362000594A700088C -:103C500090A6001B8CA4000094A500060A000ACCC4 -:103C600000073C0003E000080000000027440100BA -:103C700094820008304500FF38A3008238A20084F7 -:103C80002C6300012C420001006218251060000620 -:103C9000240200839382002D1040000D00000000DC -:103CA0000A000B9B0000000014A2000524A2FF8064 -:103CB0008F4301043C02602003E00008AC43001481 -:103CC000304200FF2C420002104000032402002278 -:103CD0000A000E3C0000000014A2000300000000D7 -:103CE0000A000EA9000000000A000EC70000000034 -:103CF0009363007E9362007A144300090000202140 -:103D00009362000024030050304200FF144300047B -:103D1000240400019362007E24420001A362007E1D -:103D200003E00008008010218F4201F80440FFFEEC -:103D300024020002AF4401C0A34201C43C021000AF -:103D400003E00008AF4201F827BDFFE8AFBF001055 -:103D50009362003F2403000A304200FF14430046F0 -:103D6000000000008F6300548F62004C1062007DE1 -:103D7000036030219362000024030050304200FFB2 -:103D80001443002F000000008F4401403C02080053 -:103D90008C4200E02403FF800082102100431024A5 -:103DA000AF4200243C0208008C4200E08F650054C2 -:103DB0003C03000A008220213084007F034410214C -:103DC00000431021AC4501089762003C8F63004C12 -:103DD0003042FFFF0002104000621821AF63005C18 -:103DE0008F6300548F64004C9762003C006418237A -:103DF0003042FFFF00031843000210400043102A26 -:103E000010400006000000008F6200548F63004CD9 -:103E1000004310230A000F58000210439762003C31 -:103E20003042FFFF00021040ACC2006424020001D7 -:103E3000A0C0007CA0C2008424020C80AF420024F9 -:103E40000E000F0A8F440140104000478FBF001042 -:103E50008F4301408F4201F80440FFFE240200021C -:103E6000AF4301C0A34201C43C021000AF4201F8BD -:103E70000A000FA88FBF00109362003F24030010B8 -:103E8000304200FF14430004000000008F44014052 -:103E90000A000F94000028219362003F24030016BB -:103EA000304200FF1443000424020014A362003FC8 -:103EB0000A000FA2000000008F62004C8F630050C8 -:103EC00000431023044100288FBF0010936200813B -:103ED00024420001A3620081936200812C4200040D -:103EE00014400010000000009362003F240300040F -:103EF000304200FF14430006000000008F440140E0 -:103F00008FBF0010240500930A0005A027BD0018EC -:103F10008F440140240500938FBF00100A00060F54 -:103F200027BD00188F4401400E0002500000000021 -:103F30008F6200542442FFFFAF6200548F62005032 -:103F40002442FFFFAF6200500E0002598F4401402F -:103F50008F4401408FBF0010240500040A00025E58 -:103F600027BD00188FBF001003E0000827BD001810 -:103F70008F4201889363007E00021402304400FFE8 -:103F8000306300FF1464000D0000000093620080A5 -:103F9000304200FF1044000900000000A3640080CC -:103FA0009362000024030050304200FF14430004D9 -:103FB000000000000A0006D78F440180A36400803F -:103FC00003E000080000000027BDFFE8AFB00010CC -:103FD000AFBF00149362000524030030304200306C -:103FE00014430089008080213C0208008C4200209C -:103FF00010400080020020210E0004930000000009 -:104000008F850020ACB000009362003E9363003FB8 -:10401000304200FF00021200306300FF0043102511 -:10402000ACA2000493620082000216000002160394 -:1040300004410005000000003C0308008C630048B8 -:104040000A000FE6000000009362003E304200408C -:10405000144000030000182193620081304300FFE8 -:104060009362008200031E00304200FF0002140031 -:1040700000621825ACA300088F620040ACA2000CBF -:104080008F620048ACA200108F62004CACA20014FA -:104090008F6200508F63004C0043102304410003E3 -:1040A000000000000A000FFA8F62004C8F6200507F -:1040B000ACA200183C02080094424B5E3C03C00BCB -:1040C00000002021004310250E0004B8ACA2001C03 -:1040D0008F6200548F840020AC8200008F620058F1 -:1040E000AC8200048F62005CAC8200088F620060CA -:1040F0008F43007400431021AC82000C8F62006477 -:10410000AC820010976300689762006A00031C008D -:104110003042FFFF00621825AC83001493620082D6 -:1041200024030080304200FF14430003000000001D -:104130000A00102EAC8000188F63000C24020001CE -:104140001062000E2402FFFF9362003E30420040E6 -:104150001440000A2402FFFF8F63000C8F4200749A -:10416000006218233C020800006210241440000280 -:10417000000028210060282100051043AC820018AF -:104180003C02080094424B5E3C03C00C000020211E -:10419000004310258F8300200E0004B8AC62001C81 -:1041A0008F6200188F8300203C05080094A54B5EA9 -:1041B00024040001AC620000AC6000048F66006C57 -:1041C0003C02400D00A22825AC6600088F6200DC8E -:1041D000AC62000CAC600010936200050002160097 -:1041E000AC620014AC6000180E0004B8AC65001C92 -:1041F000020020218FBF00148FB00010A3600005C3 -:104200000A00042127BD00188FBF00148FB00010D2 -:1042100003E0000827BD00189742007C30C600FF6D -:10422000A08600843047FFFF2402000514C2000B63 -:1042300024E3465090A201122C42000710400007D0 -:1042400024E30A0090A30112240200140062100467 -:1042500000E210210A0010663047FFFF3067FFFFC1 -:1042600003E00008A4870014AC87004C8CA201086E -:104270000080402100A0482100E2102330C600FF4A -:104280001840000393AA001324E2FFFCACA201082B -:1042900030C2000110400008000000008D020050F4 -:1042A00000E2102304410013240600058D0200548F -:1042B00010E20010000000008D02005414E2001A09 -:1042C000000000003C0208008C4200D83042002070 -:1042D0001040000A2402000191030078910200833B -:1042E000144300062402000101002021012028219E -:1042F000240600040A00105400000000A1000084FD -:1043000011400009A50200148F4301008F4201F8FB -:104310000440FFFE24020002AF4301C0A34201C4D7 -:104320003C021000AF4201F803E00008000000006A -:1043300027BDFFE88FA90028AFBF001000804021F3 -:1043400000E918231860007330C600FFA080007CCD -:10435000A08000818CA2010800E210230440004DDF -:10436000000000008C8200509483003C8C84006428 -:10437000004748233063FFFF012318210083202BCF -:1043800010800004000000008D0200640A0010B7D5 -:1043900000E210219502003C3042FFFF0122102173 -:1043A00000E21021AD02005C9502003C8D03005C30 -:1043B0003042FFFF0002104000E210210043102BAA -:1043C00010400003000000000A0010C68D02005CCF -:1043D0009502003C3042FFFF0002104000E2102135 -:1043E000AD02005CA1000084AD07004C8CA2010866 -:1043F00000E210231840000224E2FFFCACA20108F6 -:1044000030C200011040000A000000008D02005080 -:1044100000E2102304410004010020218D02005419 -:1044200014E20003000000000A0010E82406000562 -:104430008D02005414E200478FBF00103C020800B8 -:104440008C4200D8304200201040000A24020001B3 -:1044500091030078910200831443000624020001B6 -:1044600001002021240600048FBF00100A00105410 -:1044700027BD0018A1000084A50200148F4301008D -:104480008F4201F80440FFFE240200020A00110DD1 -:10449000000000008C82005C004910230043102BB8 -:1044A00054400001AC87005C9502003C3042FFFFA5 -:1044B0000062102B14400007240200029502003C09 -:1044C0008D03005C3042FFFF00621821AD03005CE9 -:1044D00024020002AD07004CA10200840E000F0A66 -:1044E0008F4401001040001B8FBF00108F4301005C -:1044F0008F4201F80440FFFE24020002AF4301C0D6 -:10450000A34201C43C021000AF4201F80A0011238B -:104510008FBF001030C200101040000E8FBF00107F -:104520008C83005C9482003C006918233042FFFFBA -:10453000006218213C023FFF3444FFFF0083102B30 -:10454000544000010080182101231021AD02005CBD -:104550008FBF001003E0000827BD001827BDFFE84B -:104560008FAA0028AFBF00100080402100EA482336 -:104570001920002130C600FF8C83005C8C8200640F -:10458000006A18230043102B5040001000691821C6 -:1045900094A2011001221021A4A2011094A20110E2 -:1045A0003042FFFF0043102B1440000A3C023FFF43 -:1045B00094A2011000431023A4A201109482003C95 -:1045C0003042FFFF0A00114200621821A4A001102E -:1045D0003C023FFF3444FFFF0083102B5440000196 -:1045E0000080182100671021AD02005CA100007C52 -:1045F0000A00118AA100008130C200101040003C66 -:10460000000000008C820050004A1023184000383F -:10461000000000009082007C24420001A082007C07 -:104620009082007C3C0308008C630024304200FF31 -:104630000043102B1440005C8FBF00108CA20108B7 -:1046400000E2102318400058000000008C83005442 -:104650009482003C006A18233042FFFF0003184395 -:10466000000210400043102A104000050000000026 -:104670008C820054004A10230A001171000210437A -:104680009482003C3042FFFF00021040AD02006403 -:104690009502003C8D0400649503003C3042FFFF0E -:1046A00000021040008220213063FFFF00831821A8 -:1046B00001431021AD02005C8D020054ACA2010840 -:1046C00024020002A10200840E000F0A8F440100A0 -:1046D000104000358FBF00108F4301008F4201F85A -:1046E0000440FFFE240200020A0011B30000000093 -:1046F000AD07004C8CA2010800E210231840000214 -:1047000024E2FFFCACA2010830C200011040000A04 -:10471000000000008D02005000E21023044100045C -:10472000010020218D02005414E20003000000006B -:104730000A0011AA240600058D02005414E2001A92 -:104740008FBF00103C0208008C4200D8304200208D -:104750001040000A240200019103007891020083B6 -:104760001443000624020001010020212406000455 -:104770008FBF00100A00105427BD0018A10000844C -:10478000A50200148F4301008F4201F80440FFFE90 -:1047900024020002AF4301C0A34201C43C02100046 -:1047A000AF4201F88FBF001003E0000827BD0018DA -:1047B0008FAA00108C8200500080402130C600FF7C -:1047C000004A102300A048211840000700E01821EB -:1047D00024020001A0800084A0A00112A482001481 -:1047E0000A001125AFAA0010A0800081AD07004C7F -:1047F0008CA2010800E210231840000224E2FFFC12 -:10480000ACA2010830C20001104000080000000006 -:104810008D0200500062102304410013240600059D -:104820008D02005410620010000000008D02005440 -:1048300014620011000000003C0208008C4200D805 -:10484000304200201040000A240200019103007849 -:10485000910200831443000624020001010020217C -:1048600001202821240600040A0010540000000042 -:10487000A1000084A502001403E00008000000006D -:1048800027BDFFE0AFBF0018274201009046000A95 -:104890008C4800148C8B004C9082008430C900FF3F -:1048A00001681823304A00FF1C60001A2D460006DC -:1048B000240200010142100410C00016304300031E -:1048C000012030210100382114600007304C000C19 -:1048D00015800009304200301440000B8FBF0018D3 -:1048E0000A001214000000000E001125AFAB0010EA -:1048F0000A0012148FBF00180E00109AAFAB001000 -:104900000A0012148FBF0018AFAB00100E0011BACE -:10491000AFAA00148FBF001803E0000827BD0020D5 -:1049200024020003A08200848C82005403E000086B -:10493000ACA201083C0200080342182190620081E9 -:10494000240600433C07601924420001A062008154 -:10495000906300813C0208008C4200C0306300FF7D -:10496000146200102403FF803C0208008C4200E027 -:104970000082102100431024AF4200243C020800B2 -:104980008C4200E03C03000A008210213042007F8C -:104990000342102100431021944500D40A000AF17B -:1049A00030A5FFFF03E000080000000027BDFFE086 -:1049B000AFBF0018AFB10014AFB000108F4201803C -:1049C0000080802100A088210E00121B00402021C1 -:1049D000A20000848E0200548FBF00188FB0001018 -:1049E000AE2201088FB1001403E0000827BD0020AB -:1049F00027BDFFE03C020008AFB00010AFBF0018B9 -:104A0000AFB10014034280218F5101409203008412 -:104A10008E0400508E02004C14820040306600FF6D -:104A20003C0208008C4200E02403FF800222102197 -:104A300000431024AF4200243C0208008C4200E0F6 -:104A40009744007C92050081022210213042007FB1 -:104A5000034218213C02000A0062182114A0000B36 -:104A60003084FFFF2402000554C20014248205DCB8 -:104A70009062011224420001A062011224020C8003 -:104A8000AF4200240A00127324020005A060011244 -:104A90002402000514C20009248205DC9202008170 -:104AA0002C4200075040000524820A009203008136 -:104AB0002402001400621004008210213044FFFF21 -:104AC000A60400140E00121B022020219602003CB6 -:104AD0008E03004C022020213042FFFF00021040D4 -:104AE000006218210E000250AE03005C9202007DAD -:104AF00002202021344200400E000259A202007D13 -:104B00008F4201F80440FFFE24020002AF5101C0B1 -:104B1000A34201C43C021000AF4201F88FBF00184D -:104B20008FB100148FB0001003E0000827BD0020F3 -:104B300008000ACC08000B1408000B9808000BE4CE -:044B400008000C203D -:0C4B44000A000028000000000000000033 -:104B50000000000D6370362E302E3135000000004D -:104B600006000F040000000000000000000000002C -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000002005 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000001F4 -:104BC0000000002B000000000000000400030D4066 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000001000000300000000B2 -:104BF0000000000D0000000D3C0208002442588413 -:104C00003C03080024635F50AC4000000043202BAD -:104C10001480FFFD244200043C1D080037BD7FFCCA -:104C200003A0F0213C100800261000A03C1C080046 -:104C3000279C58840E0001AC000000000000000D0D -:104C400027BDFFE83C096018AFBF00108D2C500055 -:104C5000240DFF7F24080031018D5824356A380C5B -:104C600024070C003C1A8000AD2A50003C04800A46 -:104C7000AF4800083C1B8008AF4700240E00091510 -:104C8000AF8400100E0008D8000000000E000825B8 -:104C9000000000000E001252000000003C046016EC -:104CA0008C8500003C06FFFF3C02535300A61824ED -:104CB0001062004734867C0094C201F2A780002C69 -:104CC00010400003A78000CC38581E1EA798002C67 -:104CD00094C201F810400004978300CC38591E1E7E -:104CE000A79900CC978300CC2C7F006753E000018C -:104CF000240300669784002C2C82040114400002D7 -:104D000000602821240404003C0760008CE904387A -:104D10002403103C3128FFFF1103001F30B9FFFFAF -:104D200057200010A38000CE24020050A38200CEA2 -:104D3000939F00CE53E0000FA78500CCA78000CC46 -:104D4000978500CC8FBF0010A780002CA78000346F -:104D5000A78000E63C010800AC25008003E00008C5 -:104D600027BD0018939F00CE57E0FFF5A78000CC29 -:104D7000A78500CC978500CC8FBF0010A784002C9E -:104D8000A7800034A78000E63C010800AC25008025 -:104D900003E0000827BD0018A38000CE8CCB003CA8 -:104DA000316A00011140000E0000000030A7FFFF33 -:104DB00010E0FFDE240200508CCC00C831860001D8 -:104DC00014C0FFDC939F00CE0A00007A2402005139 -:104DD0008C8F00043C0E60000A00005D01EE302163 -:104DE0008CEF0808240D5708000F740211CD000441 -:104DF00030B8FFFF240500660A00007B240404008D -:104E00001700FFCC939F00CE0A00007A24020050C6 -:104E10008F8600103089FFFF000939408CC30010D5 -:104E20003C08005000E82025AF4300388CC5001432 -:104E300027420400AF82001CAF45003CAF44003065 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60008F4B0000316A00201140FFFD0000000060 -:104E700003E00008000000008F840010948A001AEC -:104E80008C8700243149FFFF000940C000E8302131 -:104E9000AF46003C8C8500248F43003C00A31023C8 -:104EA00018400029000000008C8B002025620001C2 -:104EB0003C0D005035AC0008AF420038AF4C00301C -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE0008F4F000031EE002011C0FFFD00000000D8 -:104EF0008F4A04003C080020AC8A00108F4904044B -:104F0000AC890014AF4800300000000094860018FF -:104F10009487001C00C71821A48300189485001AE8 -:104F200024A20001A482001A9498001A9499001EE9 -:104F3000133800030000000003E000080000000038 -:104F400003E00008A480001A8C8200200A0000DC24 -:104F50003C0D00500A0000CD000000003C0308009A -:104F60008C6300208F82001827BDFFE810620008C4 -:104F7000AFBF00100E000104AF8300183C0308000F -:104F80008C63002024040001106400048F89001049 -:104F90008FBF001003E0000827BD00188FBF00106E -:104FA0003C076012A520000A9528000A34E500108D -:104FB00027BD00183106FFFF03E00008ACA60090F3 -:104FC0003C0208008C42002027BDFFC8AFBF003460 -:104FD000AFBE0030AFB7002CAFB60028AFB500248D -:104FE000AFB40020AFB3001CAFB20018AFB10014D3 -:104FF00010400050AFB000108F840010948600065F -:105000009483000A00C3282330B6FFFF12C0004A71 -:105010008FBF003494890018948A000A012A402323 -:105020003102FFFF02C2382B14E0000202C020212F -:10503000004020212C8C0005158000020080A0215A -:10504000241400040E0000B3028020218F8700107A -:1050500002809821AF80001494ED000A028088211C -:105060001280004E31B2FFFF3C1770003C1540002B -:105070003C1E60008F8F001C8DEE000001D71824AD -:10508000507500500220202102A3802B160000350D -:105090003C182000507800470220202124100001F5 -:1050A0008F83001414600039029158230230F823D2 -:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D -:1050C0008F8700103C110020AF510030000000001D -:1050D00094E6000A3C1E601237D5001002662821B3 -:1050E000A4E5000A94E2000A94F2000A94F400187D -:1050F0003057FFFF1292003BAEB700908CED0014CA -:105100008CE400100013714001AE4021000E5FC31B -:10511000010E502B008B4821012A1821ACE8001405 -:10512000ACE3001002D3382330F6FFFF16C0FFB9FE -:105130008F8400108FBF00348FBE00308FB7002CDB -:105140008FB600288FB500248FB400208FB3001CC9 -:105150008FB200188FB100148FB0001003E0000868 -:1051600027BD0038107E001B000000001477FFCC24 -:10517000241000010E001598000000008F83001419 -:105180001060FFCB0230F823029158238F87001064 -:10519000017020210A0001973093FFFF8F830014D4 -:1051A0001460FFCB3C110020AF5100300A000163B6 -:1051B000000000000E00077D024028210A00015770 -:1051C000004080210E00033A024028210A000157C6 -:1051D000004080210E001460022020210A000157A7 -:1051E000004080210E0000CD000000000A0001797F -:1051F00002D3382327BDFFE8AFB00010AFBF0014C3 -:105200000E00003F000000003C028000345000709F -:105210000A0001BA8E0600008F4F000039EE00012F -:1052200031C20001104000248F8600A88E070000C4 -:105230003C0C08008D8C003C3C0908008D2900388E -:1052400000E66823018D28210000502100AD302B9D -:10525000012A4021010620213C010800AC25003C28 -:10526000AF8700A83C010800AC2400380E000106FE -:10527000000000003C0308008C6300701060FFE633 -:10528000006020213C0508008CA500683C06080051 -:105290008CC6006C0E001527000000003C010800C1 -:1052A000AC2000708F4F000039EE000131C20001C8 -:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6 -:1052C0003C0508008CA5003C3C0408008C84003898 -:1052D000014B482300A938210082182100E9402B06 -:1052E000006810213C010800AC27003C3C0108008C -:1052F000AC2200388F5F01002419FF0024180C0035 -:1053000003F9202410980012AF840000AF4400205D -:10531000936D0000240C002031A600FF10CC001279 -:10532000240E005010CE00043C194000AF59013843 -:105330000A0001B3000000000E0011C800000000C8 -:105340003C194000AF5901380A0001B300000000C9 -:105350000E00011F000000003C194000AF59013849 -:105360000A0001B3000000008F58010000802821CE -:10537000330F00FF01E020210E0002F1AF8F000487 -:105380003C194000AF5901380A0001B30000000089 -:1053900000A4102B2403000110400009000030215C -:1053A0000005284000A4102B04A0000300031840AF -:1053B0005440FFFC000528405060000A0004182BF0 -:1053C0000085382B54E000040003184200C3302548 -:1053D00000852023000318421460FFF900052842CD -:1053E0000004182B03E0000800C310218F4201B80D -:1053F0000440FFFE00000000AF4401803C031000A9 -:1054000024040040AF450184A3440188A3460189D8 -:10541000A747018A03E00008AF4301B83084FFFFCB -:105420000080382130A5FFFF000020210A00022A59 -:10543000240600803087FFFF8CA40000240600387B -:105440000A00022A000028218F8300388F8600304E -:105450001066000B008040213C07080024E759F843 -:10546000000328C000A710218C4400002463000121 -:10547000108800053063000F5466FFFA000328C04F -:1054800003E00008000010213C07080024E759FC55 -:1054900000A7302103E000088CC200003C0390000C -:1054A0003462000100822025AF4400208F45002097 -:1054B00004A0FFFE0000000003E000080000000060 -:1054C0003C038000346200010082202503E00008D4 -:1054D000AF44002027BDFFE0AFB100143091FFFFC3 -:1054E000AFB00010AFBF00181220001300A0802141 -:1054F0008CA2000024040002240601401040000F8A -:10550000004028210E000C5C00000000000010216B -:10551000AE000000022038218FBF00188FB10014A8 -:105520008FB0001000402021000028210000302111 -:105530000A00022A27BD00208CA200000220382188 -:105540008FBF00188FB100148FB0001000402021D1 -:1055500000002821000030210A00022A27BD002077 -:1055600000A010213087FFFF8CA500048C440000B0 -:105570000A00022A2406000627BDFFE0AFB0001093 -:10558000AFBF0018AFB100149363003E00808021CC -:105590000080282130620040000020211040000FD0 -:1055A0008E1100000E000851022020219367000098 -:1055B0002404005030E500FF50A400128E0F0000BC -:1055C000022020218FBF00188FB100148FB000106F -:1055D000A762013C0A00091127BD00200E000287C6 -:1055E000000000000E0008510220202193670000F7 -:1055F0002404005030E500FF14A4FFF20220202113 -:105600008E0F00003C1008008E1000503C0D000C66 -:10561000240BFF8001F05021314E007F01DA602120 -:10562000018D4021014B4824AF4900280220202150 -:105630008FBF00188FB100148FB00010A50200D6E4 -:1056400027BD00200A000911AF8800D027BDFFE068 -:10565000AFBF0018AFB10014AFB0001093660001E7 -:10566000008080210E00025630D1000493640005B2 -:10567000001029C2A765000034830040A363000521 -:105680000E00025F020020210E00091302002021FB -:1056900024020001AF62000C02002821A762001062 -:1056A00024040002A762001224060140A76200142D -:1056B0000E000C5CA76200161620000F8FBF0018AA -:1056C000978C00343C0B08008D6B00782588FFFF19 -:1056D0003109FFFF256A0001012A382B10E000067E -:1056E000A78800343C0F6006240E001635ED00102C -:1056F000ADAE00508FBF00188FB100148FB00010F6 -:1057000003E0000827BD002027BDFFE0AFB1001473 -:10571000AFBF0018AFB0001000A088211080000AB1 -:105720003C03600024020080108200120000000090 -:105730000000000D8FBF00188FB100148FB0001053 -:1057400003E0000827BD00208C682BF80500FFFE51 -:1057500000000000AC712BC08FBF00188FB1001487 -:105760008FB000103C09100027BD002003E00008A6 -:10577000AC692BF80E00025600A0202193650005AD -:10578000022020210E00025F30B000FF2403003E03 -:105790001603FFE7000000008F4401780480FFFE3D -:1057A000240700073C061000AF51014002202021D1 -:1057B000A34701448FBF00188FB100148FB00010B1 -:1057C000AF4601780A0002C227BD002027BDFFE8CE -:1057D000AFBF0014AFB000108F50002000000000D9 -:1057E0000E000913AF440020AF5000208FBF0014FB -:1057F0008FB0001003E0000827BD00183084FFFFC1 -:10580000008038212406003500A020210A00022A49 -:10581000000028213084FFFF008038212406003654 -:1058200000A020210A00022A0000282127BDFFD065 -:10583000AFB3001C3093FFFFAFB50024AFB2001828 -:10584000AFBF0028AFB40020AFB10014AFB000105C -:1058500030B5FFFF12600027000090218F90001CE0 -:105860008E0300003C0680002402004000033E023C -:1058700000032C0230E4007F006688241482001D9F -:1058800030A500FF8F8300282C68000A510000100B -:105890008F910014000358803C0C0800258C56881A -:1058A000016C50218D49000001200008000000001B -:1058B00002B210213045FFFF0E000236240400849E -:1058C000162000028F90001CAF8000288F910014DA -:1058D000260C002026430001018080213072FFFF4A -:1058E00016200004AF8C001C0253502B1540FFDC27 -:1058F00000000000024010218FBF00288FB5002457 -:105900008FB400208FB3001C8FB200188FB1001429 -:105910008FB0001003E0000827BD0030240E0034D3 -:1059200014AE00F9000000009203000E241F168040 -:105930003C07000CA36300219202000D0347C8211D -:105940003C066000A3620020961100123C0A7FFF13 -:10595000354CFFFFA771003C960B00102403000597 -:105960003168FFFFAF6800848E05001CAF5F002820 -:105970008F3800008CC4444803057826008F3021FE -:10598000AF66004C8F69004C24CE00013C057F00BF -:10599000AF6900508F740050AF740054AF66007050 -:1059A000AF6E00588F6D005824140050AF6D005C2E -:1059B000A3600023AF6C0064A36300378E02001461 -:1059C000AF6200488F710048AF7100248E0B001841 -:1059D000AF6B006C9208000CA3680036937F003E0A -:1059E00037F90020A379003E8F78007403058024E6 -:1059F000360F4000AF6F007493640000308900FFE1 -:105A0000513402452404FF803C04080024845A7861 -:105A10000E00028D000000003C1008008E105A7825 -:105A20000E00025602002021240600042407000173 -:105A3000A366007D020020210E00025FA36700051F -:105A40008F5F017807E0FFFE240B0002AF5001409A -:105A5000A34B01448F90001C3C081000AF48017814 -:105A60000A000362AF8000282CAD003751A0FF98D8 -:105A70008F9100140005A0803C180800271856B02C -:105A8000029878218DEE000001C00008000000009F -:105A90002418000614B80011000000003C0808009B -:105AA0008D085A7824040005AF4800208E1F001886 -:105AB000AF7F00188F79004CAF79001C8F650050C4 -:105AC000122000C0AF6500700A000362AF84002896 -:105AD0002406000710A60083240300063C050800E6 -:105AE00024A55A780E000264240400818F90001CC3 -:105AF0000011102B0A000362AF8200282407000463 -:105B000014A7FFF6240500503C1808008F185A7897 -:105B1000AF5800208E0F0008AF6F00408E090008BC -:105B2000AF6900448E14000CAF7400488E0E001054 -:105B3000AF6E004C8E0D0010AF6D00848E0A001405 -:105B4000AF6A00508E0C0018AF6C00548E04001C1D -:105B5000AF64005893630000306B00FF116501D8FB -:105B6000000000008F7400488F6900400289702394 -:105B700005C000042404008C1620FFDE240200036C -:105B8000240400823C05080024A55A780E000287F0 -:105B9000000000008F90001C000010210A0003622A -:105BA000AF820028240F000514AFFFCC240520008D -:105BB0003C0708008CE75A78AF4700208E060004A7 -:105BC000AF66005C9208000824100008A36800215A -:105BD0008F9F001C93F90009A37900208F86001C79 -:105BE00090D8000A330400FF10900011000000005C -:105BF0002885000914A0006924020002240A00205C -:105C0000108A000B34058000288D002115A00008A3 -:105C100024054000240E0040108E00053C050001C4 -:105C200024140080109400023C050002240540006A -:105C30008F7800743C19FF00031980240205782531 -:105C4000AF6F007490C4000BA36400818F84001CAC -:105C50009489000C11200192000000009490000C27 -:105C60002406FFBF24050004A770003C908F000E9F -:105C7000A36F003E8F84001C9089000FA369003F32 -:105C80008F8B001C8D6E00108F54007401D468231C -:105C9000AF6D00608D6A0014AF6A0064956C0018E7 -:105CA000A76C00689563001AA763006A8D62001CE8 -:105CB000AF62006C9167000EA367003E9368003EE0 -:105CC0000106F8241220014BA37F003E8F90001C98 -:105CD0000A000362AF8500282407002214A7FF7F73 -:105CE000240300073C0B08008D6B5A781220000C2F -:105CF000AF4B00200A000362AF830028240C00335E -:105D000010AC0014240A00283C05080024A55A7889 -:105D10000E00023C240400810A0003EB8F90001C5B -:105D20003C04080024845A780E00028D0000000014 -:105D30009363000024110050306200FF10510135C0 -:105D4000000000008F90001C000018210A00036270 -:105D5000AF8300283C0D08008DAD5A7824040081E3 -:105D6000AF4D00203C05080024A55A780E00023CE7 -:105D7000A36A00348F90001C240200090A00036209 -:105D8000AF82002802B288213225FFFF0E000236C2 -:105D9000240400840A0003628F90001C1082FFA478 -:105DA00024050400288B000311600170240C0004FA -:105DB000240300015483FF9E240540000A00043B95 -:105DC000240501003C04080024845A788F62004CAA -:105DD0000E00028D8F6300508F90001C0000202168 -:105DE0000A000362AF8400288E1000042404008A95 -:105DF000AF50002093790005333800021700015F8F -:105E0000020028219368002302002821311F00206E -:105E100017E0015A2404008D9367003F2406001206 -:105E200030E200FF10460155240400810E000256A6 -:105E30000200202193630023240500040200202196 -:105E4000346B0042A36B00230E00025FA365007D4C -:105E50008F4401780480FFFE240A0002AF50014005 -:105E6000A34A01448F90001C3C0C1000AF4C0178F9 -:105E70000A0003EC0011102B8E1000042404008A89 -:105E8000AF500020936E000531CD000215A0001622 -:105E900002002821936F003F2414000402002821EF -:105EA00031E900FF11340010240400810E00025675 -:105EB000020020219362002324080012241FFFFE09 -:105EC00034460020A3660023A368003F93790005B1 -:105ED00002002021033FC0240E00025FA3780005CA -:105EE00002002821000020210E00033400000000E1 -:105EF0000A0003EB8F90001C8E1000043C03000886 -:105F00000343A021AF500020928B000024050050D5 -:105F1000316400FF10850161240700880200202100 -:105F2000000028210E00022A2406000E928D000097 -:105F3000240EFF800200282101AE8025A2900000DF -:105F4000240400040E000C5C240600300A0003EB5D -:105F50008F90001C8E0800043C14080026945A7888 -:105F60003C010800AC285A78AF480020921F00037B -:105F700033F9000413200002240200122402000658 -:105F8000A362003F920B001B2404FFC03165003F59 -:105F900000A43825A367003E9206000330C200012A -:105FA00014400132000000008E020008AE8200089A -:105FB0003C0208008C425A8010400131000249C264 -:105FC000A76900088E14000C240C0001240300149F -:105FD000AF74002C8E0E0010AF6E0030960D0016C0 -:105FE000A76D0038960A0014A76A003AAF6C000C3F -:105FF000A76C0010A76C0012A76C0014A76C001609 -:1060000012200136A3630034920F000331F0000226 -:106010002E1100018F90001C262200080A00036246 -:10602000AF8200288E0400043C0E0008034E30218D -:10603000AF4400208E05000890CD0000240C0050D5 -:1060400031AA00FF114C00862407008824060009AD -:106050000E00022A000000000A0003EB8F90001CD3 -:106060008E04001C0E00024100000000104000F4ED -:10607000004050218F89001C240700890140202105 -:106080008D25001C240600010E00022A00000000DD -:106090000A0003EB8F90001C960D00023C140800D0 -:1060A00026945A7831AA0004514000B83C10600090 -:1060B0008E0E001C3C010800AC2E5A78AF4E00201A -:1060C000920700102408001430E200FF144800D6A4 -:1060D00000000000960B00023163000114600165AE -:1060E000000000008E020004AE8200083C1408008C -:1060F0008E945A801280015B000000008F7400743F -:106100003C0380002404000102835825AF6B007417 -:10611000A3600005AF64000C3C0708008CE75A80C0 -:106120008F86001CA7640010000711C2A76400122C -:10613000A7640014A7640016A76200088CC80008B2 -:1061400024040002AF68002C8CC5000CAF65003041 -:1061500090DF0010A37F00348F99001C9330001152 -:10616000A37000358F98001C930F0012A36F0036A8 -:106170008F89001C912E0013A36E00378F90001C96 -:10618000960D0014A76D0038960A0016A76A003A0B -:106190008E0C0018AF6C00245620FDCCAF84002874 -:1061A0003C05080024A55A780E0002640000202156 -:1061B0008F90001C0A0004A7000020218E1000040C -:1061C00024070081AF500020936900233134001070 -:1061D000128000170000000002002021000028218A -:1061E0002406001F0E00022A000000000A0003EB34 -:1061F0008F90001C3C05080024A55A780E000287E9 -:10620000240400828F90001C000028210A000362F1 -:10621000AF8500283C0408008C845A780E0014E5F1 -:10622000000000008F90001C0A000482000018216A -:106230000E00025602002021937800230200202144 -:10624000370F00100E00025FA36F002300003821FB -:1062500002002021000028210A0005A82406001FB2 -:10626000920F000C31E90001112000030000000032 -:106270009618000EA4D8002C921F000C33F90002CF -:1062800013200005000038218E0200149608001229 -:10629000ACC2001CA4C8001A0A0005432406000969 -:1062A0003C05080024A55A780E0002872404008BC0 -:1062B0008F90001C0011282B0A000362AF85002874 -:1062C000AF6000843C0A08008D4A5A783C0D0800F3 -:1062D0008DAD0050240CFF803C02000C014D1821B4 -:1062E000006C2024AF4400288E070014306B007F20 -:1062F000017A282100A2C821AF2700D88E060014F9 -:10630000AF9900D0AF2600DC8E080010251FFFFEDD -:106310000A000408AF3F01083C0508008CA55A7824 -:106320003C1908008F39005024CCFFFE00B9C02171 -:1063300003047824AF4F00283C1408008E945A7848 -:106340003C0908008D2900500289702131CD007F61 -:1063500001BA502101478021AE0600D8AF9000D08D -:10636000AE0000DC0A0003B1AE0C0108548CFE3014 -:10637000240540000A00043B240510000E00032EF3 -:10638000000000000A0003EB8F90001C8E0F442CCD -:106390003C186C62370979703C010800AC205A78CF -:1063A00015E9000824050140979F00349786002CCA -:1063B0000280282103E6C82B132000112404009238 -:1063C000240501400E000C7A240400023C01080060 -:1063D000AC225A78AF4200203C0508008CA55A78C0 -:1063E00010A00005240400830E00084500000000F2 -:1063F00010400009240400833C05080024A55A78B5 -:106400000E000264000000008F90001C0011202B81 -:106410000A000362AF8400280E0008490000000053 -:106420000A00055F8F90001C0E00084D0000000060 -:106430003C05080024A55A780A00062F2404008B86 -:10644000240400040E000C7A240500301440002AB5 -:10645000004050218F89001C240700830140202127 -:106460008D25001C0A000551240600018E04000839 -:106470000E000241000000000A00051BAE82000869 -:106480003C05080024A55A780E00023C240400872D -:106490008F90001C0A0005360011102B8F830038E6 -:1064A0008F8600301066FE9D000038213C070800F2 -:1064B00024E759FC000320C0008728218CAC000091 -:1064C00011900061246A00013143000F5466FFFA05 -:1064D000000320C00A0004F6000038213C05080033 -:1064E00024A55A780E000287240400828F90001C95 -:1064F0000A000536000010213C0B0008034B202148 -:106500002403005024070001AF420020A0830000B4 -:10651000A08700018F82001C90480004A08800180A -:106520008F85001C90A60005A08600198F9F001C77 -:1065300093F90006A099001A8F90001C921800078A -:10654000A098001B8F94001C928F0008A08F001C45 -:106550008F89001C912E0009A08E001D8F8D001CBC -:1065600091AC000AA08C001E8F8B001C3C0C080014 -:10657000258C59FC9163000B3C0B0800256B59F8E6 -:10658000A083001F8F87001C90E8000CA0880020CB -:106590008F82001C9045000D24024646A0850021F4 -:1065A0008F86001C90DF000EA09F00228F99001C98 -:1065B0009330000FA09000238F98001C93140010BC -:1065C000A09400248F8F001C91E90011A089002560 -:1065D0008F89001C8F8E00308F900038952D00140D -:1065E000000E18C025C80001A48D002895270016AC -:1065F000006C3021006BC821A487002A9525001863 -:106600003108000FA485002CA482002E8D3F001CB1 -:10661000ACCA0000AF88003011100006AF3F000088 -:10662000000038218D25001C014020210A00055161 -:1066300024060001250C00013184000F00003821E0 -:106640000A0006B8AF8400383C07080024E759F870 -:106650000087302100003821ACA000000A0004F6B9 -:10666000ACC000003C05080024A55A780A00062F9B -:10667000240400878E0400040E0002410000000084 -:106680000A00056AAE8200083084FFFF30C600FFB2 -:106690008F4201B80440FFFE00064400010430258B -:1066A0003C07200000C720253C031000AF400180BC -:1066B000AF450184AF44018803E00008AF4301B84F -:1066C00027BDFFE8AFB00010AFBF00143C0760006B -:1066D000240600021080000600A080210010102B6C -:1066E0008FBF00148FB0001003E0000827BD001812 -:1066F0003C09600EAD2000348CE5201C8F82001C0C -:106700002408FFFC00A81824ACE3201C0E0006D1CE -:106710008C45000C0010102B8FBF00148FB00010A0 -:1067200003E0000827BD00183C02600E344701005A -:1067300024090018274A040000000000000000009F -:10674000000000003C06005034C30200AF44003893 -:10675000AF45003CAF430030014018218F4B000093 -:10676000316800201100FFFD2406007F2408FFFF90 -:106770008C6C000024C6FFFF24630004ACEC000016 -:1067800014C8FFFB24E70004000000000000000024 -:10679000000000003C0F0020AF4F00300000000060 -:1067A00024AD020001A5702B2529FFFF008E2021BA -:1067B0001520FFE101A0282103E0000800000000EF -:1067C00027BDFFE0AFB10014AFBF0018AFB000109D -:1067D0003C05600E8CA20034008088211440000625 -:1067E0003C0460008C87201C2408FFFC00E8302457 -:1067F00034C30001AC83201C8F8B001C24090001D2 -:10680000ACA90034956900028D6500148D70000CF0 -:106810002D2400818D6700048D660008108000071C -:106820008D6A00102D2C00041580000E30CE00075C -:10683000312D000311A0000B000000002404008B88 -:10684000020028210E0006D1240600030011102B9F -:106850008FBF00188FB100148FB0001003E0000844 -:1068600027BD002015C0FFF62404008B3C03002048 -:10687000AF4300300000000024020001AF8200148A -:106880000000000000000000000000003C1F01505C -:10689000013FC825253800033C0F600EAF47003884 -:1068A00000181882AF46003C35E8003CAF59003074 -:1068B000274704008F4400003086002010C0FFFDF1 -:1068C00000000000106000082466FFFF2403FFFFA3 -:1068D0008CEB000024C6FFFF24E70004AD0B000092 -:1068E00014C3FFFB250800043C08600EAD09003806 -:1068F0000000000000000000000000003C07002035 -:10690000AF470030000000000E0006F901402021D2 -:1069100002002821000020210E0006D124060003D9 -:106920000011102B8FBF00188FB100148FB0001012 -:1069300003E0000827BD002027BDFFE0AFB200182C -:106940003092FFFFAFB10014AFBF001CAFB000101A -:106950001640000D000088210A0007AA022010211D -:1069600024050001508500278CE5000C0000000D77 -:10697000262300013071FFFF24E200200232382B71 -:1069800010E00019AF82001C8F8200141440001622 -:106990008F87001C3C0670003C0320008CE5000043 -:1069A00000A62024148300108F84003C00054402BC -:1069B0003C09800000A980241480FFE9310600FF13 -:1069C0002CCA00095140FFEB262300010006688015 -:1069D0003C0E080025CE578C01AE60218D8B000047 -:1069E0000160000800000000022010218FBF001C81 -:1069F0008FB200188FB100148FB0001003E00008B0 -:106A000027BD00200E0006D1240400841600FFD804 -:106A10008F87001C0A00078BAF80003C90EF0002BC -:106A200000002021240600090E0006D1000F2E00D0 -:106A30008F87001C0010102B0A00078BAF82003CD0 -:106A4000020028210E0006DF240400018F87001CAD -:106A50000A00078BAF82003C020028210E0006DFEF -:106A6000000020210A0007C38F87001C0E00071FAB -:106A7000020020210A0007C38F87001C30B0FFFFEF -:106A8000001019C08F5801B80700FFFE3C1F2004FA -:106A90003C191000AF430180AF400184AF5F018813 -:106AA000AF5901B80A00078C262300013082FFFF8E -:106AB00014400003000018210004240224030010E5 -:106AC000308500FF14A000053087000F2466000801 -:106AD0000004220230C300FF3087000F14E00005DD -:106AE000308900032468000400042102310300FF00 -:106AF0003089000315200005388B0001246A00024C -:106B000000042082314300FF388B00013164000112 -:106B100010800002246C0001318300FF03E00008B4 -:106B200000601021308BFFFF000B394230E600FF80 -:106B30003C09080025295978000640800109602198 -:106B40008D8700003164001F240A0001008A1804A8 -:106B500030A500FF00E3202514A000020003102749 -:106B600000E22024240F000100CF700401096821F5 -:106B7000000E282714800005ADA400008F86000CAD -:106B800000A6102403E00008AF82000C8F88000CE0 -:106B900001C8102503E00008AF82000C3C06001F6E -:106BA0003C0360003084FFFF34C5FF8024020020D6 -:106BB000AC602008AC60200CAC602010AC652014E8 -:106BC000AC642018AC62200000000000000000004F -:106BD00003E000080000000027BDFFE82402FFFFDB -:106BE000AFBF0010AF82000C000020213C0608005F -:106BF00024C659782405FFFF248900010004408041 -:106C00003124FFFF010618212C87002014E0FFFA31 -:106C1000AC6500000E0008160000202124020001CF -:106C20003C04600024050020AC822018AC852000C4 -:106C3000000000000000000000000000244A0001E5 -:106C40003142FFFF2C46040014C0FFF78FBF001035 -:106C500003E0000827BD00188F8300082C620400A1 -:106C600003E00008384200018F830008246200011D -:106C700003E00008AF8200088F8300082462FFFF52 -:106C800003E00008AF82000827BDFFE0AFB10014A9 -:106C9000AFBF0018AFB000108F6B00303C06600033 -:106CA00000808821ACCB20088F6A002C3C02800039 -:106CB00024030008ACCA200C9769003A9768003892 -:106CC00000092C003107FFFF00A72025ACC42010CD -:106CD000ACC22014ACC32000000000000000000083 -:106CE000000000003C0360008C6D200031AC000807 -:106CF0001580FFF9000000008C6E201405C00020F4 -:106D0000000000000E0007DA8F84000C00024080B3 -:106D10003C09080025295978010938218CE4000034 -:106D20000E0007DA00028140020220213090FFFFAE -:106D3000020020210E0007F8000028213C0C8000F2 -:106D4000022C58253210FFFF3C116000240A00205D -:106D5000AE2B2014AE302018AE2A20000000000018 -:106D60000000000000000000020010218FBF00188A -:106D70008FB100148FB0001003E0000827BD002081 -:106D80008C6620143C02001F3443FF803C1FFFE848 -:106D900000C3C02437F9080003198021001079C20C -:106DA0003C0C8000022C582531F0FFFF3C116000A4 -:106DB000240A0020AE2B2014AE302018AE2A20006A -:106DC0000000000000000000000000000200102190 -:106DD0008FBF00188FB100148FB0001003E00008BF -:106DE00027BD002027BDFFE8AFB000103402FFFF31 -:106DF0003090FFFFAFBF00141202000602002021F6 -:106E00000E00081600000000020020210E0007F806 -:106E1000240500018F8400088FBF00148FB000107C -:106E20002483FFFF27BD001803E00008AF8300089C -:106E3000000439C230E6003F00043B42000718401E -:106E4000240210002CC4002024C8FFE0AF42002C14 -:106E5000246300011480000330A900FF00071840DC -:106E6000310600FF0003608024080001019A5821C8 -:106E70003C0A000E00C82804016A382111200005D0 -:106E8000000530278CE900000125302503E00008CB -:106E9000ACE600008CEE000001C6682403E00008A8 -:106EA000ACED000027BDFFE8AFBF0014AFB000108D -:106EB0003C0460008C8508083403F00030A2F00028 -:106EC00050430006240200018C8708083404E000C7 -:106ED00030E6F00010C4001E24020002AF82004021 -:106EE0003C1060003C0A0200AE0A0814240910009D -:106EF0003C08000E8E03440003482021AF49002CBB -:106F0000240501200E000CC0000030218F830040BA -:106F1000106000043C021691240B0001106B000E5F -:106F20003C023D2C344F0090AE0F44088FBF00143C -:106F30008FB000103C0C6000240E10003C0D0200CD -:106F400027BD0018AD8E442003E00008AD8D081069 -:106F50000A0008E7AF8000403C0218DA344F009086 -:106F6000AE0F44088FBF00148FB000103C0C6000BF -:106F7000240E10003C0D020027BD0018AD8E4420E9 -:106F800003E00008AD8D08100A0008BB24050001CD -:106F90000A0008BB000028213C08080025085D8481 -:106FA0002404FFFF010018212402001E2442FFFFD9 -:106FB000AC6400000441FFFD246300043C070800AA -:106FC00024E75E008CE5FFFC2404001C240600017D -:106FD000308A001F0146480424840001000910275C -:106FE0002C8300201460FFFA00A22824ACE5FFFCEB -:106FF0003C05666634A4616E3C06080024C65EC08B -:10700000AF840058AF88009C2404FFFF00C0182103 -:107010002402001F2442FFFFAC6400000441FFFD76 -:10702000246300043C0766663C05080024A55E80D6 -:10703000AF86004834E6616EAF8600982404FFFFF7 -:1070400000A018212402000F2442FFFFAC640000BE -:107050000441FFFD246300043C0B66663C06080007 -:1070600024C65E003568616EAF8500A4AF880070ED -:107070002404FFFF00C018212402001F2442FFFF48 -:10708000AC6400000441FFFD246300043C0D66660F -:107090003C0A0800254A5F4035AC616EAF8600901F -:1070A000AF8C005C2404FFFF014018212402000380 -:1070B0002442FFFFAC6400000441FFFD2463000490 -:1070C0003C09080025295F508D27FFFC2404000699 -:1070D000240500013099001F0325C0042484000109 -:1070E000001878272C8E002015C0FFFA00EF3824F6 -:1070F000AD27FFFC3C09666624030400240403DC7E -:1071000024050200240600663522616E3C08080052 -:1071100025085A84AF820074AF830044AF83006CAB -:10712000AF830050AF830084AF8A008CAF840064CB -:10713000AF85004CAF860054AF840078AF85006007 -:10714000AF86008001001821240200022442FFFFC4 -:10715000AC6000000441FFFD24630004240400032C -:107160002403000C3C0A0800254A5A90AF8A0068A4 -:107170000A00098E2405FFFF000418802484000102 -:10718000006858212C8700C014E0FFFBAD650000AB -:107190003C0E666635CD616E240C17A024081800DD -:1071A000AF8D0088AF8C009403E00008AF88007CAE -:1071B0002484007F000421C200004021000030210F -:1071C00000003821000028210A0009A5AF8400A092 -:1071D0001060000624E7000100C4302124A500014E -:1071E0002CC20BF51440FFFA2CA300663C090800E2 -:1071F00025295F4001201821240200032442FFFFBB -:10720000AC6000000441FFFD2463000410E0001A9C -:1072100024E3FFFF0003294210A0000A0000202100 -:107220002406FFFF3C03080024635F402484000120 -:107230000085502BAC660000250800011540FFFBBF -:107240002463000430E2001F10400008000868803A -:10725000240C0001004C38040008588001692821E2 -:1072600024E6FFFF03E00008ACA6000001A94021CE -:107270002409FFFFAD09000003E000080000000042 -:10728000AF4400283C04000C034420210005288260 -:107290000A000CC000003021000421803C03600083 -:1072A000AC6410080000000000052980AC65100CDB -:1072B0000000000003E000088C62100C27BDFFE80E -:1072C0000080282124040038AFBF00140E0009D527 -:1072D000AFB0001024040E00AF4400283C10000C96 -:1072E00003502021240500100E000CC000003021A6 -:1072F00003501021AC400000AC40000424040038CE -:107300008FBF00148FB0001024053FFF27BD001869 -:107310000A0009D58C430000000421803C03600072 -:10732000AC641008000000008C62100C03E0000840 -:107330000002118227BDFFC8AFB400208F940068FF -:10734000AFBE0030AFB7002CAFB600280000B821A8 -:107350000080B021241E00C0AFBF0034AFB50024B0 -:10736000AFB3001CAFB20018AFB10014AFB0001043 -:107370000A000A12AFA5003C504000018F9400683B -:1073800027DEFFFF13C00028269400048E92000021 -:107390003C03080024635D801240FFF70283102B3A -:1073A0003C04080024845A84028410230002A8C0EC -:1073B000000098210A000A212411000100118840D0 -:1073C000122000260000000002B380210251282470 -:1073D0000200202110A0FFF9267300010E0009DE33 -:1073E000000000000016684032EC000101AC2021D2 -:1073F0000E0009D5020028218F89009426F700018C -:107400008FA6003C3AEB0001316A00012528FFFFFE -:107410000011382702CAB021AF88009416E6FFE7B2 -:1074200002479024AE92000002E010218FBF00348A -:107430008FBE00308FB7002C8FB600288FB5002488 -:107440008FB400208FB3001C8FB200188FB10014CE -:107450008FB0001003E0000827BD00383C0E080084 -:1074600025CE5D80028E102B0A000A0DAE92000020 -:1074700027BDFFD8AFB10014AFB00010AFBF0020E0 -:10748000AFB3001CAFB2001800A0882110A0001FED -:10749000000480403C13080026735A840A000A5AEC -:1074A0002412000112200019261000010E0009F517 -:1074B00002002021000231422444FFA0000618806F -:1074C0003045001F2C8217A1007318212631FFFFC1 -:1074D0001040FFF400B230048C690000020020214B -:1074E00024053FFF012640241500FFEE0126382524 -:1074F0000E0009D5AC6700008F8A009426100001A9 -:10750000254700011620FFE9AF8700948FBF0020B8 -:107510008FB3001C8FB200188FB100148FB0001011 -:1075200003E0000827BD00288F85009C00805821BB -:107530000000402100004821240A001F3C0C0800E4 -:10754000258C5DFC3C0D080025AD5D848CA60000FB -:1075500050C000140000402100AD1023000238C0CC -:10756000240300010A000A930000202115000003F3 -:1075700000E410212448202400004821252900018E -:10758000512B00132506DFDC106000062484000167 -:1075900000C3702415C0FFF5000318400A000A91CB -:1075A0000000402110AC002624A300040060282124 -:1075B000254AFFFF1540FFE5AF85009C512B0004D5 -:1075C0002506DFDC0000402103E000080100102157 -:1075D0000006614230C5001F000C50803C070800C7 -:1075E00024E75D8424040001014730211120000FAD -:1075F00000A420043C05080024A55E0014800005BA -:107600002529FFFF24C6000410C50011000000005A -:10761000240400018CCF00000004C0270004204097 -:1076200001F868241520FFF5ACCD00008F99007893 -:1076300001001021032B482303E00008AF890078E4 -:107640003C05080024A55D840A000A9B0000402137 -:107650003C06080024C65D840A000AB42404000124 -:10766000308800FF240200021102000A24030003F4 -:107670001103005C8F8900A4240400041104005F3E -:1076800024050005110500670000182103E000082B -:10769000006010218F8900483C0C0800258C5EC0DA -:1076A0003C04080024845F40240300201060000F85 -:1076B00000005821240D0002240E00033C0F080096 -:1076C00025EF5EC08D27000014E0000B30F9FFFFAE -:1076D000252900040124C02B53000001018048210A -:1076E0002463FFFF5460FFF88D270000016018211C -:1076F00003E0000800601021132000323C0500FF69 -:1077000030E200FF004030211040004200005021D4 -:1077100024050001000020210005C84000A6C02467 -:1077200017000003332500FF14A0FFFB2484000191 -:10773000012CC023001828C000AA6021008C502111 -:107740003144001F240C0001008C18040003102792 -:1077500000E23024110D0041AD260000110E004C56 -:10776000000A1840110D00368F87006C510E00562C -:107770008F8C0060240D0004110D005A8F8E008440 -:10778000240E0005150EFFDA01601821240B1430B9 -:1077900011400006000018218F8400A0246300011E -:1077A000006A402B1500FFFD016458218F8A00807C -:1077B000AF89008C016018212549FFFF0A000AEB00 -:1077C000AF89008000E52024000736021080FFD03A -:1077D000240A001800075402314600FF0A000AF389 -:1077E000240A00103C0C0800258C5E803C04080034 -:1077F00024845EC00A000ADA240300103C0C08004E -:10780000258C5E003C04080024845E800A000AD9AE -:107810008F89009000071A02306600FF0A000AF301 -:10782000240A00088F89008C3C0C0800258C5F40DE -:107830003C04080024845F500A000ADA2403000490 -:10784000000A4080250B003024E6FFFF016018216C -:10785000AF8900480A000AEBAF86006C000AC982B3 -:10786000001978803C07080024E75E8001E72021AA -:10787000000A18428C8F00003079001F032C380456 -:107880000007C02701F860240A000B08AC8C000038 -:10789000000331420006288000AF28213062001F1B -:1078A0008CB8000024630001004CC804000321428E -:1078B000001938270004108003073024004F2021CE -:1078C0000A000B4CACA60000000A68C025AB0032D1 -:1078D000258AFFFF01601821AF8900A40A000AEB86 -:1078E000AF8A0060254B1030AF89009001601821ED -:1078F00025C9FFFF0A000AEBAF8900843086000724 -:107900002CC2000610400014000000000006408059 -:107910003C030800246357B0010338218CE40000C5 -:1079200000800008000000002409000310A9000ED8 -:1079300000000000240A000510AA000B000000004F -:10794000240B000110AB0008000000008F8C00A089 -:1079500010AC00050000000003E00008000010214A -:107960000A000A7900A020210A000AC700C02021CD -:1079700027BDFFE8308400FF240300021083000BC2 -:10798000AFBF0010240600031086003A240800044C -:1079900010880068240E0005108E007F2CAF143074 -:1079A0008FBF001003E0000827BD00182CA2003094 -:1079B0001440FFFC8FBF001024A5FFD0000531C28A -:1079C000000668803C07080024E75EC001A730215C -:1079D0008CC900000005288230AC001F240B000178 -:1079E000018B50048F840048012A4025ACC8000058 -:1079F0008C83000050600001AF8600488F98006CB7 -:107A000030AE000124A6FFFF270F000115C00002C1 -:107A1000AF8F006C24A600010006414200082080C0 -:107A2000008718218C79000030C2001F2406000155 -:107A30000046F804033F382410E0FFDA8FBF00103F -:107A40000005C182001870803C0F080025EF5E80A1 -:107A500001CF48218D2B00000005684231A5001F91 -:107A600000A66004016C502527BD001803E0000843 -:107A7000AD2A00002CA7003014E0FFCA8FBF001011 -:107A800030B900071723FFC724A8FFCE00086A02F9 -:107A9000000D60803C0B0800256B5E80018B30215F -:107AA0008CC40000000828C230AA001F240800016E -:107AB000014848048F8200A400891825ACC3000047 -:107AC0008C5F000053E00001AF8600A40005704009 -:107AD000000E7942000F28803C04080024845EC018 -:107AE00000A418218C6B000025DF000131CD001FA0 -:107AF000001F514201A86004016C4825000A108053 -:107B0000AC690000004428218CA600008F9800601A -:107B100033F9001F8FBF00100328380400C77825F1 -:107B2000270E000127BD0018ACAF000003E00008DD -:107B3000AF8E006024A5EFD02CB804001300FF998D -:107B40008FBF001000053142000658803C0A080033 -:107B5000254A5E00016A30218CC4000030A3001F5A -:107B600024090001006910048F9900900082F82513 -:107B7000ACDF00008F27000050E00001AF860090CE -:107B80008F8D00848FBF001027BD001825AC000129 -:107B900003E00008AF8C008415E0FF828FBF001067 -:107BA0008F8600A0000610400046F821001F21002B -:107BB00003E4C8210019384024F8143000B8402BE1 -:107BC0001100FF788FBF001024A4EBD00E00021329 -:107BD00000C0282100027942000F70803C0D08008F -:107BE00025AD5F4001CD20218C8B0000304C001F63 -:107BF00024060001018618048F89008C016350253A -:107C0000AC8A00008D25000050A00001AF84008CDC -:107C10008F9800808FBF001027BD00182708000133 -:107C200003E00008AF88008030A5000724030003AC -:107C300010A3001028A2000414400008240700022A -:107C40002403000410A300152408000510A8000F49 -:107C50008F8500A003E000080000000014A7FFFDCE -:107C60000080282114C3FFFB240400020A000B8BB0 -:107C700000000000240900050080282110C9FFFB36 -:107C80002404000303E000080000000014C5FFF115 -:107C9000008028210A000B8B24040005240A00011F -:107CA0000080282110CAFFF12404000403E000082A -:107CB0000000000027BDFFE0AFB00010000581C24A -:107CC0002603FFD024C5003F2C6223D024C6007FAA -:107CD000AFB20018AFB10014AFBF001C309100FF6D -:107CE000000691C2000529820200202110400008F0 -:107CF0002403FFFF0E000A4B0000000002002021B9 -:107D0000022028210E000C390240302100001821E9 -:107D10008FBF001C8FB200188FB100148FB00010FD -:107D20000060102103E0000827BD002027BDFFD818 -:107D300024A2007FAFB3001CAFB20018000299C2AA -:107D4000309200FF24A3003F02402021026028213E -:107D5000AFB10014AFB00010AFBF00200E000B6E2B -:107D60000003898200408021004020210220282138 -:107D700014400009000018218FBF00208FB3001CA1 -:107D80008FB200188FB100148FB000100060102166 -:107D900003E0000827BD00280E0009FC00000000D9 -:107DA00000402821020020211051FFF3001019C0CB -:107DB0000E000A4B00000000020020210240282192 -:107DC0000E000C39026030218FBF00208FB3001CE1 -:107DD0008FB200188FB100148FB00010000018216E -:107DE0000060102103E0000827BD00283084FFFF59 -:107DF00030A5FFFF1080000700001821308200012D -:107E00001040000200042042006518211480FFFB8E -:107E10000005284003E000080060102110C00007A2 -:107E2000000000008CA2000024C6FFFF24A500046F -:107E3000AC82000014C0FFFB2484000403E00008AF -:107E40000000000010A0000824A3FFFFAC86000083 -:107E500000000000000000002402FFFF2463FFFF79 -:107E60001462FFFA2484000403E00008000000000C -:107E700030A5FFFF8F4201B80440FFFE3C076015AC -:107E800000A730253C031000AF440180AF400184BF -:107E9000AF46018803E00008AF4301B88F8500D0EA -:107EA0002C864000008018218CA700840087102BAE -:107EB00014400010000000008CA800842D06400033 -:107EC00050C0000F240340008CAA0084008A482B75 -:107ED000512000018CA3008400035A42000B208033 -:107EE0003C05080024A558000085182103E000087F -:107EF0008C62000014C0FFF4000000002403400066 -:107F000000035A42000B20803C05080024A55800BD -:107F10000085182103E000088C6200008F8300D0E8 -:107F2000906600D024C50001A06500D08F8500D0E8 -:107F3000906400D090A200D210440017000000000E -:107F4000936C00788F8B00BC318A00FFA16A000C13 -:107F500025490001938700C4312200FF3048007F8B -:107F60001107000B00026827A36200788F4E01788A -:107F700005C0FFFE8F9900B0241800023C0F1000CE -:107F8000AF590140A358014403E00008AF4F017806 -:107F90000A000D0931A20080A0A000D00A000CFF49 -:107FA000000000008F8700D027BDFFC8AFBF0030A2 -:107FB000AFB7002CAFB60028AFB50024AFB4002097 -:107FC000AFB3001CAFB20018AFB10014AFB00010D7 -:107FD00094E300E094E200E2104300D72405FFFFA1 -:107FE0003C047FFF3497FFFF2415FF800A000DF04B -:107FF0003C16000E108A00D18FBF00308F9100B068 -:108000003C1808008F18005C001230C0001291402C -:108010000311702101D57824AF4F002C94EC00E2BD -:1080200031CD007F01BA5821318A7FFF0176482186 -:10803000000A804002091021945300003C08080007 -:108040008D0800580246C02132733FFF001319808B -:10805000010320210224282130BF007F03FAC82118 -:1080600000B5A024AF54002C0336A0218E87001049 -:108070008E8F003003785821256D008800EF702323 -:10808000240C0002AE8E0010AF8D00ACA16C0088F5 -:10809000976A003C8E8400308F9100AC0E000CD6A5 -:1080A0003150FFFF00024B80020940253C02420094 -:1080B00001022025AE2400048E8300048F8D00ACC5 -:1080C0008E860000240E0008ADA3001CADA600188B -:1080D000ADA0000CADA00010929F000A33F900FF84 -:1080E000A5B90014968500083C1F000CA5A5001634 -:1080F0009298000A331100FFA5B100209690000865 -:1081000024180005A5B00022ADA00024928F000B1A -:108110002410C00031E700FFA5A70002A1AE0001B6 -:108120008E8C00308F8B00AC8F8400B0AD6C00085B -:108130003C0A08008D4A005401444821013540247E -:10814000AF4800283C0208008C4200540044302113 -:1081500030C3007F007AC821033F282102458821CF -:10816000AF9100BCAF8500C0A23800008F8A00BC70 -:108170002403FFBF2418FFDF954F000201F03824CD -:1081800000F37025A54E0002914D000231AC003F76 -:10819000358B0040A14B00028F8600BC8F8900D038 -:1081A000ACC000048D28007C3C098000ACC80008ED -:1081B00090C4000D3082007FA0C2000D8F8500BCEE -:1081C00090BF000D03E3C824A0B9000D8F9100BC3F -:1081D0009233000D02789024A232000D8E9000346C -:1081E0008F8B00BCAD7000108E87002C8E8F0030FE -:1081F00000EF7023AD6E0014916D001831AC007F5C -:10820000A16C00188F9F00BC8E8A00308FE8001888 -:10821000015720240109302400C41025AFE20018C2 -:108220009283000AA3E3001C969900088F8500BC86 -:108230008F9800D0A4B9001E8E9000308E8400303C -:108240000E0002138F0500848F8500D0000291403C -:108250000002990090AF00BC0253882100403021F9 -:1082600031E7000210E0000302118021000290803B -:108270000212802190B900BC3327000410E00002F4 -:108280000006F880021F80218E9800308F8B00BC82 -:1082900024068000330F0003000F702331CD00034C -:1082A000020D6021AD6C000494A400E294AA00E2E7 -:1082B00094B000E231497FFF2522000130537FFF57 -:1082C0000206182400734025A4A800E294A400E24A -:1082D0003C1408008E94006030917FFF123400221D -:1082E000000000000E000CF6000000008F8700D098 -:1082F0000000282194F300E094F000E21213000F34 -:108300008FBF003090E900D090E800D1313200FFFB -:10831000310400FF0244302B14C0FF36264A00010E -:1083200090EE00D2264B000131CD00FF008D602180 -:10833000158BFF338F9100B08FBF00308FB7002CAB -:108340008FB600288FB500248FB400208FB3001C97 -:108350008FB200188FB100148FB0001000A0102150 -:1083600003E0000827BD003894A300E20066402423 -:10837000A4A800E290A400E290B900E2309100FFCE -:108380000011A1C20014F827001F39C03332007F4A -:10839000024730250A000DE8A0A600E23084FFFF66 -:1083A00030A5FFFFAF440018AF45001C03E00008F4 -:1083B0008F42001427BDFFB8AFB000208F9000D0CF -:1083C0003084FFFFAFA40010AFBF0044AFBE004039 -:1083D000AFB7003CAFB60038AFB50034AFB4003033 -:1083E000AFB3002CAFB20028AFB10024A7A0001893 -:1083F000920600D1920500D030C400FF30A300FFE8 -:108400000064102B10400122AFA00014920900D08C -:108410008FB50010312800FF0088382324F4FFFFB7 -:108420000014882B0015982B02339024524001260B -:108430008FB40014961E0012961F00108FB7001004 -:1084400003DFC823001714000019C400000224032E -:108450000018140302E2B02A52C00001004020219B -:108460000284282B10A0000200801821028018210D -:1084700000033C0000071C033064FFFF2C8600094A -:1084800014C000020060B821241700088E0A0008FA -:10849000001769808E09000C31ABFFFF3C0C001007 -:1084A000016C402527520400AF4A0038AF9200B853 -:1084B000AF49003CAF480030000000000000000061 -:1084C00000000000000000000000000000000000AC -:1084D00000000000000000008F4F000031EE00207F -:1084E00011C0FFFD0017982A027110240A000E83A4 -:1084F0000000B02155E001019258000131130080C5 -:10850000126001CF012020219655001232A5FFFFF5 -:108510000E000CCBA7B500188F9000D00291A023BD -:1085200026CD00018F9100B8000DB4000016B403F1 -:108530002638004002D7582A0014882B2405000151 -:108540000300902101711024AF9800B8AFA500146A -:10855000104001BC8F8900B03C0C08008D8C005489 -:10856000240BFF80921E00D001895021014B28244A -:10857000921900D0AF4500288E4700103C08080033 -:108580008D0800583C1808008F18005430E33FFF56 -:108590000003218001043021012658212402FF809C -:1085A0000162F824920C00D0AF5F002C92480000CA -:1085B00033D100FF333500FF0309982100117140CA -:1085C000001578C0326D007F01CF382101BA282113 -:1085D000318300FF3164007F3C0A000C00AA88212F -:1085E0000367F02100033140009A10213108003F59 -:1085F0003C1F000E00D1C021005F982127D90088C0 -:108600002D150008AF9100C0AF9900ACAF9800BC29 -:10861000AF9300B412A0018A00008821240E00014B -:10862000010E4004310D005D11A0FFB2310F0002B8 -:108630008E4A00283C0300803C04FFEFAE6A000035 -:108640008E450024A260000A3488FFFFAE65000456 -:108650009247002C3C1FFF9F37FEFFFFA267000CD4 -:108660008E62000C3C180040A267000B00433025CE -:1086700000C8C824033E88240238A825AE75000C23 -:108680008E490004AE6000183C0F00FFAE69001474 -:108690008E4D002C35EEFFFF8F8B00B001AE6024B5 -:1086A000AE6C00108E470008A660000896450012C8 -:1086B000AE6700208E42000C30B03FFF00105180AA -:1086C000AE6200248E5E0014014B182130A400011C -:1086D000AE7E00288E590018000331C2000443808A -:1086E000AE79002C8E51001C00C8F821A67F001C1A -:1086F000AE710030965800028E550020A678001EFC -:10870000AE75003492490033313000045600000544 -:10871000925000008F8C00D08D8B007CAE6B0030AF -:10872000925000008F8F00BCA1F00000924E0033E9 -:1087300031CD000251A00007925E00018F8900BC7C -:108740002418FF80913100000311A825A1350000F5 -:10875000925E00018F9900BC2409FFBF240BFFDF4C -:10876000A33E00018F9500BC92B8000D3311007F2D -:10877000A2B1000D8F8E00BC91D0000D02097824AB -:10878000A1CF000D8F8800BC8E6D0014910A000DE2 -:108790002DAC0001000C2940014B382400E51825C0 -:1087A000A103000D964200128F8800BC8F8700D075 -:1087B000A50200028E45000490FF00BC30A4000317 -:1087C0000004302330DE000300BE102133F9000224 -:1087D00017200002244400342444003090E200BCFE -:1087E00000A2302430DF000417E0000224830004DC -:1087F000008018218F8F00AC24090002AD03000413 -:10880000A1E90000924E003F8F8D00ACA1AE0001A7 -:108810008F9500AC924C003F8E440004A6AC000241 -:10882000976B003C0E000CD63170FFFF00025380A6 -:10883000020A38253C05420000E51825AEA30004D5 -:108840008F8600AC8E480038ACC800188E440034C7 -:10885000ACC4001CACC0000CACC00010A4C0001420 -:10886000A4C00016A4C00020A4C00022ACC00024F4 -:108870008E6400145080000124040001ACC4000880 -:108880000E000CF6241100010A000E768F9000D025 -:10889000920F00D2920E00D08FB5001031EB00FF86 -:1088A00031CD00FF008D6023016C50212554FFFF66 -:1088B0000014882B0015982B023390241640FEDDFF -:1088C000000000008FB400148FBF00448FBE004032 -:1088D0003A8200018FB7003C8FB600388FB5003464 -:1088E0008FB400308FB3002C8FB200288FB10024DA -:1088F0008FB0002003E0000827BD0048331100209E -:10890000122000EF24150001921E00BC241F00015C -:108910000000A82133D900011320000DAFBF001CB7 -:108920008E4400148E0800840088102B144000022E -:10893000008030218E0600848E03006400C3A82BC3 -:1089400016A0000200C020218E0400640080A8212F -:108950008E4700148E05006400E5302B14C0000221 -:1089600000E020218E0400640095F02313C0000471 -:108970008FAC001C240A0002AFAA001C8FAC001CA4 -:10898000028C582B156000A8000018218E4F00386B -:108990008E6D000C3C0E0080AE6F00008E4A0034DD -:1089A0003C10FF9F01AE5825AE6A00049246003F7E -:1089B000360CFFFF016C38243C0500203C03FFEF20 -:1089C000A266000B00E510253468FFFF8F8700B812 -:1089D0000048F8243C04000803E4C825AE79000CE4 -:1089E0008CF80014AE60001802BE7821AE78001436 -:1089F0008CF10018AE71001C8CE90008AE690024EF -:108A00008CEE000CAE6F002CAE600028AE6E002025 -:108A1000A6600038A660003A8CED001401B58023F2 -:108A2000021E902312400011AE72001090EA003D29 -:108A30008E6500048E640000000A310000A6C82183 -:108A4000000010210326402B0082F82103E8C021FA -:108A5000AE790004AE78000090F1003DA271000AEA -:108A60008F8900B895320006A67200088F9800AC76 -:108A70002419000202A02021A31900009769003CDC -:108A80008F9200AC0E000CD63131FFFF00027B80CC -:108A90008F8500B8022F68253C0E420001AE80256C -:108AA000AE5000048F8400AC8CAC0038AC8C001845 -:108AB0008CAB0034AC8B001CAC80000CAC80001084 -:108AC000A4800014A4800016A4800020A4800022AA -:108AD000AC80002490A7003FA487000212A00135BB -:108AE0002403000153C0000290A2003D90A2003E6A -:108AF00024480001A08800018F9F00ACAFF500085A -:108B00008F8300D024070034906600BC30C500027B -:108B100050A00001240700308F9200B88F8A00BC5B -:108B2000906D00BC924B00002412C00032A50003DF -:108B3000A14B00008F8600B88F8800BC240200047F -:108B400090C400010045182330790003A1040001FE -:108B50008F8A00BC8F9F00B800F53821955800021D -:108B600097E9001200F9382103128824312F3FFFC2 -:108B7000022F7025A54E00029150000231A800047A -:108B8000320C003F358B0040A14B000212A00002C6 -:108B90008F8500BC00E838218F8E00D0ACA7000480 -:108BA000240BFFBF8DCD007C2EA400012403FFDF2A -:108BB000ACAD000890B0000D00044140320C007FC5 -:108BC000A0AC000D8F8600BC90CA000D014B102494 -:108BD000A0C2000D8F8700BC90E5000D00A3F82413 -:108BE00003E8C825A0F9000D8F9100B88F8D00BC57 -:108BF0008E380020ADB800108E290024ADA90014D5 -:108C00008E2F0028ADAF00188E2E002C0E000CF613 -:108C1000ADAE001C8FB0001C240C0002120C00EE44 -:108C20008F9000D08FA3001C006088211460000288 -:108C30000060A8210000A02156A0FE390291A023C7 -:108C40000014882B8FA90010960700103C1E0020EE -:108C50000136402302C750213112FFFFA60A00103F -:108C6000AFB20010AF5E0030000000009617001099 -:108C7000961300121277008F000000008E05000C82 -:108C80008E0B00080016698000AD7021000DC7C36F -:108C900001CDA82B0178782101F56021AE0E000CE2 -:108CA000AE0C00088FB300100013B82B02378024DD -:108CB0001200FF048F9000D00A000E3C000000005C -:108CC0008E4D0038A6600008240B0003AE6D000036 -:108CD0008E500034A260000A8F9800B8AE70000475 -:108CE0003C0500809311003FA26B000C8E6F000CBE -:108CF0003C0EFF9FA271000B01E5102535CCFFFF54 -:108D00003C03FFEF8F9200B8004C30243464FFFF27 -:108D100000C4F824AE7F000C8E590014964800124F -:108D20008F8A00B0AE7900108E490014AE60001832 -:108D3000AE600020AE690014AE6000248E470018BB -:108D400031093FFF0009F180AE6700288E4D000811 -:108D500003CA802131180001AE6D00308E4F000C27 -:108D60008F8C00AC001089C200185B80022B282178 -:108D7000240E0002A665001CA6600036AE6F002C13 -:108D8000A18E00009763003C8F8A00AC3C04420037 -:108D90003062FFFF00443025AD4600048F9F00B8CD -:108DA000240700012411C0008FF30038240600348A -:108DB000AD5300188FF90034AD59001CAD40000CC4 -:108DC000AD400010A5400014A5400016A5400020AD -:108DD000A5400022AD400024A5550002A147000196 -:108DE0008F9E00AC8F8800B88F9200BCAFD5000872 -:108DF000910D0000A24D00008F9000B88F8B00BC39 -:108E000092180001A17800018F8400BC94850002B3 -:108E100000B1782401E97025A48E0002908C000234 -:108E20003183003FA08300028F8300D08F8400BC79 -:108E3000906200BC305300025260000124060030F2 -:108E4000AC8600048C6F007C2403FFBF02A0882145 -:108E5000AC8F0008908E000D31CC007FA08C000DEF -:108E60008F8600BC90C2000D00432024A0C4000DDA -:108E70008F8900BC913F000D37F90020A139000D0A -:108E80008F8800B88F9300BC8D070020AE6700105C -:108E90008D0A0024AE6A00148D1E0028AE7E0018D4 -:108EA0008D12002C0E000CF6AE72001C0A00103D54 -:108EB0008F9000D0960E00148E03000431CCFFFF7B -:108EC000000C10C000622021AF44003C8E1F000443 -:108ED0008F46003C03E6C8231B20003C0000000036 -:108EE0008E0F000025E200013C05001034B500089B -:108EF000AF420038AF550030000000000000000015 -:108F00000000000000000000000000000000000061 -:108F100000000000000000008F580000330B00200C -:108F20001160FFFD000000008F5304003C0D002085 -:108F3000AE1300088F570404AE17000CAF4D00307D -:108F4000000000003C0608008CC600442416000106 -:108F500010D600BD00000000961F00123C0508005E -:108F60008CA5004000BFC821A61900129609001464 -:108F700025270001A6070014960A00143144FFFFBC -:108F80005486FF498FB30010A60000140E000E1681 -:108F900030A5FFFF3C0408008C84002496030012D7 -:108FA0000044102300623023A60600120A00105964 -:108FB0008FB30010A08300018F8200AC2404000155 -:108FC000AC4400080A000FF08F8300D08E0200002E -:108FD0000A0010EA3C0500108F8200C08FA7001C19 -:108FE000921800D0920B00D0920E00D0331100FFE7 -:108FF000316900FF00117940000928C001E56021B6 -:1090000031C300FF036C50210003314000C2C8216E -:10901000255F0088AF9F00ACAF9900BCA1470088D6 -:109020009768003C03C020218F9100AC0E000CD645 -:109030003110FFFF00026B80020DC0253C0442008E -:109040008F8D00B803045825AE2B00048DA900387D -:109050008F8B00AC0000882100118100AD690018E1 -:109060008DAF00343C087FFF3504FFFFAD6F001C5F -:1090700091AC003E8D65001C8D660018000C190037 -:10908000000C770200A33821020E102500E3F82B14 -:1090900000C2C821033F5021AD67001CAD6A001813 -:1090A000AD60000CAD60001091B8003E24050005D5 -:1090B00003C45024A578001495A9000403C02021FE -:1090C000A569001691AF003EA56F002095B1000480 -:1090D000A5710022AD60002491AE003FA56E000294 -:1090E00091B0003E91AC003D01901023244300015B -:1090F000A16300018F8600AC8F9F00BCACDE00082E -:10910000A3E500008F9000BC8F9900B82405FFBF35 -:1091100096070002973800120247782433093FFF70 -:1091200001E98825A6110002921200022418FFDF2F -:10913000324E003F35CD0040A20D00028F8600BCAC -:109140008F8C00D02412FFFFACC000048D8B007CFC -:109150003C0C8000ACCB000890C2000D3043007F77 -:10916000A0C3000D8F8700BC90FF000D03E5C8244D -:10917000A0F9000D8F9100BC9229000D01387824D0 -:10918000A22F000D8F9000BCAE120010AE1500147F -:10919000920E00182415FF8002AE6825A20D00185B -:1091A0008F8500BC8F8300B88CAB0018016C102435 -:1091B000004A3025ACA600189068003EA0A8001C0C -:1091C0008F9F00B88F8700BC8F9800D097F900045C -:1091D000A4F9001E0E0002138F0500848F8600D0B4 -:1091E000000279400002490090D200BC01E98821C8 -:1091F000004028213255000212A0000303D1202193 -:109200000002A8800095202190CD00BC31B200045E -:109210001240000333DF0003000540800088202156 -:10922000240600048F9E00BC00DFC8233327000300 -:1092300000875021AFCA00040E000CF6A665003866 -:109240000A0010388F9000D0961E00123C080800CB -:109250008D080024011E9021A61200120A00105948 -:109260008FB3001027BDFFE03C1808008F18005096 -:10927000AFB00010AFBF0018AFB10014AF8400B0A2 -:1092800093710074030478212410FF8031EE007F75 -:109290003225007F01F0582401DA68213C0C000AD5 -:1092A000A38500C401AC2821AF4B002494A9001071 -:1092B0009768000690A600620080382124020030E2 -:1092C0000109202330C300F0AF8500D010620019DF -:1092D0003090FFFF90AE0062240DFFF0240A005092 -:1092E00001AE6024318B00FF116A002F00000000E6 -:1092F00016000007241F0C00AF5F00248FB100147C -:109300008FBF00188FB0001003E0000827BD0020B9 -:109310000E000E1C02002021241F0C00AF5F002451 -:109320008FB100148FBF00188FB0001003E0000849 -:1093300027BD002094A200E094A400E290BF011396 -:10934000008218263079FFFF33E700C014E00009DF -:109350002F31000116000038000000005620FFE603 -:10936000241F0C000E000D18000000000A0011ED73 -:10937000241F0C001620FFDE000000000E000D1858 -:10938000000000001440FFDC241F0C001600002227 -:109390008F8300D0906901133122003FA062011336 -:1093A0000A0011ED241F0C0094AF00D48F8600D466 -:1093B00000E02821240400050E000C5C31F0FFFFC2 -:1093C0001440000524030003979100E600001821D3 -:1093D0002625FFFFA78500E68F5801B80700FFFE8E -:1093E0003C196013AF400180241F0C00AF50018472 -:1093F000007938253C101000AF4701888FB1001468 -:10940000AF5001B8AF5F00248FB000108FBF0018BD -:1094100003E0000827BD00200E000E1C02002021E2 -:109420005040FFB5241F0C008F8300D090690113BA -:109430000A0012163122003F0E000E1C02002021ED -:109440001440FFAD241F0C00122000078F8300D0B2 -:10945000906801133106003F34C20040A06201133E -:109460000A0011ED241F0C000E000D180000000072 -:109470005040FFA1241F0C008F8300D0906801137F -:109480003106003F0A00124634C20040AF9B00C8BC -:1094900003E00008AF8000EC3089FFFF0009404284 -:1094A0002D020041000929801440000200095040AB -:1094B00024080040000879400008C0C001F8582185 -:1094C000256701A800EF702125CC007F240DFF80C7 -:1094D000018D18240065302100CA282125640088E8 -:1094E000240A00883C010800AC2A004C3C0108001A -:1094F000AC240050AF8500D43C010800AC290060CA -:109500003C010800AC2800643C010800AC27005472 -:109510003C010800AC2300583C010800AC26005C6C -:1095200003E0000800000000308300FF30C6FFFFAA -:1095300030E400FF8F4201B80440FFFE00034C00FE -:10954000012438253C08600000E820253C03100079 -:10955000AF450180AF460184AF44018803E00008B5 -:10956000AF4301B88F86001C3C09601235270010FC -:109570008CCB00043C0C600E35850010316A00066F -:109580002D480001ACE800C48CC40004ACA43180B8 -:109590008CC2000894C30002ACA2318403E000082E -:1095A000A78300E43C0308008C6300508F8400E82C -:1095B0008F86001C2402FF800064C0210302C8249F -:1095C000AF5900288CCD00043305007F00BA782104 -:1095D0003C0E000C01EE2821ACAD00588CC80008F0 -:1095E000AF8500D03C076012ACA8005C8CCC0010AA -:1095F00034E80010ACAC000C8CCB000CACAB000819 -:1096000094AA00143C0208008C4200442549000141 -:10961000A4A9001494A400143083FFFF1062001763 -:109620008F8400D03C0A08008D4A0040A4AA001292 -:109630008CCE0018AC8E00248CCD0014AC8D002094 -:109640008CC70018AC87002C8CCC001424060001B9 -:10965000AC8C00288D0B00BC5166001A8D0200B442 -:109660008D0200B8A482003A948F003AA48F003C87 -:10967000948800D403E000083102FFFF3C09080091 -:109680008D290024A4A000148F8400D0A4A9001266 -:109690008CCE0018AC8E00248CCD0014AC8D002034 -:1096A0008CC70018AC87002C8CCC00142406000159 -:1096B000AC8C00288D0B00BC5566FFEA8D0200B80B -:1096C0008D0200B4A482003A948F003AA48F003C2B -:1096D000948800D403E000083102FFFF8F86001C4D -:1096E0003C0C08008D8C0050240BFF808CCD0008B2 -:1096F0003C03000C000D51C0018A4021010B48249D -:10970000AF8A00E8AF49002890C700073105007F05 -:1097100000BA10210043282130E4000410800039F1 -:10972000AF8500D090CF000731EE000811C000389F -:10973000000000008CD9000C8CC400140324C02B42 -:1097400013000030000000008CC2000CACA20064CA -:109750008CCD00182402FFF8ACAD00688CCC001052 -:10976000ACAC00808CCB000CACAB00848CCA001C71 -:10977000ACAA007C90A900BC01224024A0A800BC97 -:1097800090C300073067000810E000048F8500D008 -:1097900090AF00BC35EE0001A0AE00BC90D9000730 -:1097A00033380001130000088F8300D08F8700D06A -:1097B0002404003490E800BC35030002A0E300BCA0 -:1097C0008F8300D0AC6400C090C90007312600022E -:1097D00010C0000500000000906A00BC3542000483 -:1097E000A06200BC8F8300D09065011330AD003FB4 -:1097F000A06D01138F8C00D0958B00D403E000087E -:109800003162FFFF8CC200140A0013020000000046 -:109810000A001303ACA0006427BDFFD8AFB000104E -:109820008F90001CAFBF0024AFB40020AFB200186F -:10983000AFB10014AFB3001C9613000E3C07600AD2 -:109840003C1460063264FFFF369300100E00125580 -:1098500034F404108F8400D43C11600E0E00099B78 -:1098600036310010920E00153C0708008CE70060AE -:109870003C12601231CD000FA38D00F08E0E00045B -:109880008E0D000896080012961F00109619001AF7 -:109890009618001E960F001C310CFFFF33EBFFFFE4 -:1098A000332AFFFF3309FFFF31E6FFFF3C010800C9 -:1098B000AC2B00403C010800AC2C00243C0108000B -:1098C000AC2A0044AE293178AE26317C92020015D4 -:1098D0009603001636520010304400FF3065FFFF3B -:1098E0003C0608008CC60064AE243188AE4500B446 -:1098F0009208001496190018241F0001011FC004CB -:10990000332FFFFF3C0508008CA50058AE5800B867 -:10991000AE4F00BC920C0014AF8E00D8AF8D00DCAF -:10992000318B00FFAE4B00C0920A0015AE670048B5 -:10993000AE66004C314900FFAE4900C8AE65007C00 -:109940003C0308008C6300503C0408008C84004CED -:109950003C0808008D0800543C0208008C42005C62 -:109960008FBF0024AE6300808FB00010AE83007400 -:109970008FB3001CAE22319CAE4200DCAE2731A07A -:10998000AE2631A4AE24318CAE233190AE28319472 -:10999000AE253198AE870050AE860054AE8500707B -:1099A0008FB10014AE4700E0AE4600E4AE4400CCF8 -:1099B000AE4300D0AE4800D4AE4500D88FB40020EE -:1099C0008FB2001803E0000827BD002827BDFFE084 -:1099D000AFB10014AFBF0018241100010E000845FC -:1099E000AFB0001010510005978400E6978300CCBB -:1099F0000083102B144000088F8500D42407000238 -:109A00008FBF00188FB100148FB0001000E010213C -:109A100003E0000827BD00200E000C7A2404000596 -:109A2000AF8200E81040FFF6240700020E0008494C -:109A30008F90001C979F00E68F9900E88F8D00C8DB -:109A400027EF0001240E0050AF590020A78F00E639 -:109A5000A1AE00003C0C08008D8C00648F8600C80D -:109A6000240A8000000C5E00ACCB0074A4C0000689 -:109A700094C9000A241FFF803C0D000C012AC02459 -:109A8000A4D8000A90C8000A24182000011F182535 -:109A9000A0C3000A8F8700C8A0E000788F8500C8A7 -:109AA00000003821A0A000833C0208008C42005036 -:109AB0008F8400E80044782101FFC824AF590028B2 -:109AC000960B000231EE007F01DA6021018D30211A -:109AD000A4CB00D4960A0002AF8600D03C0E00044E -:109AE00025492401A4C900E68E080004ACC800047E -:109AF0008E030008ACC30000A4C00010A4C0001472 -:109B0000A0C000D08F8500D02403FFBFA0A000D14B -:109B10003C0408008C8400648F8200D0A04400D2F2 -:109B20008E1F000C8F8A00D0978F00E4AD5F001C61 -:109B30008E19001024100030AD590018A5400030D7 -:109B4000A5510054A5510056A54F0016AD4E006812 -:109B5000AD580080AD580084914D006231AC000FCB -:109B6000358B0010A14B00628F8600D090C9006336 -:109B70003128007FA0C800638F8400D02406FFFF37 -:109B80009085006300A31024A08200638F9100D011 -:109B900000E01021923F00BC37F90001A23900BC5F -:109BA0008F8A00D0938F00F0AD580064AD5000C094 -:109BB000914E00D3000F690031CC000F018D582564 -:109BC000A14B00D38F8500D08F8900DCACA900E8C1 -:109BD0008F8800D88FBF00188FB100148FB000108D -:109BE00027BD0020ACA800ECA4A600D6A4A000E0ED -:109BF000A4A000E203E000080000000027BDFFE091 -:109C0000AFB000108F90001CAFB10014AFBF0018B0 -:109C10008E1900043C1808008F180050240FFF8094 -:109C2000001989C00238702131CD007F01CF602436 -:109C300001BA50213C0B000CAF4C0028014B4021D5 -:109C4000950900D4950400D68E0700043131FFFF3A -:109C5000AF8800D00E000913000721C08E06000453 -:109C60008F8300C8000629C0AF4500209064003EE5 -:109C700030820040144000068F8400D0341FFFFF64 -:109C8000948300D63062FFFF145F000400000000E0 -:109C9000948400D60E0008A83084FFFF8E050004CF -:109CA000022030218FBF00188FB100148FB0001038 -:109CB0002404002200003821000529C00A0012797E -:109CC00027BD002027BDFFE0AFB100143091FFFF9A -:109CD000AFB00010AFBF00181220001D000080219F -:109CE0008F86001C8CC500002403000600053F027F -:109CF0000005140230E4000714830015304500FF0E -:109D00002CA800061100004D000558803C0C0800EE -:109D1000258C57C8016C50218D4900000120000896 -:109D2000000000008F8E00EC240D000111CD0059C1 -:109D300000000000260B00013170FFFF24CA002044 -:109D40000211202B014030211480FFE6AF8A001C55 -:109D5000020010218FBF00188FB100148FB00010C7 -:109D600003E0000827BD0020938700CE14E00038F0 -:109D7000240400140E001335000000008F86001C20 -:109D8000240200010A00147CAF8200EC8F8900ECF1 -:109D9000240800021128003B24040013000028219D -:109DA00000003021240700010E001279000000009D -:109DB0000A00147C8F86001C8F8700EC24050002AB -:109DC00014E5FFF6240400120E0012E60000000065 -:109DD0008F8500E800403021240400120E00127923 -:109DE000000038210A00147C8F86001C8F8300EC51 -:109DF000241F0003147FFFD0260B00010E001298D1 -:109E0000000000008F8500E800403021240200029D -:109E10002404001000003821AF8200EC0E001279FB -:109E2000000000000A00147C8F86001C8F8F00EC5D -:109E30002406000211E6000B0000000024040010BC -:109E400000002821000030210A0014992407000195 -:109E5000000028210E001279000030210A00147C35 -:109E60008F86001C0E0013A2000000001440001298 -:109E70008F99001C8F86001C240200030A00147CAA -:109E8000AF8200EC0E00142E000000000A00147CCB -:109E90008F86001C0E0012880000000024020002C1 -:109EA0002404001400002821000030210000382183 -:109EB0000A0014B6AF8200EC0040382124040010E0 -:109EC00097380002000028210E0012793306FFFFA8 -:109ED0000A00147C8F86001C8F8400C83C077FFF1B -:109EE00034E6FFFF8C8500742402000100A61824CC -:109EF000AC83007403E00008A082000510A00036C7 -:109F00002CA20080274A04003C0B00052409008095 -:109F1000104000072408008030A6000F00C5402133 -:109F20002D0300811460000200A048212408008055 -:109F3000AF4B0030000000000000000000000000F7 -:109F40001100000900003821014030218C8D0000F3 -:109F500024E7000400E8602BACCD0000248400045A -:109F60001580FFFA24C60004000000000000000075 -:109F7000000000003C0E0006010E3825AF470030FF -:109F80000000000000000000000000008F4F0000F3 -:109F900031E800101100FFFD000000008F42003C7E -:109FA0008F43003C0049C8210323C02B1300000449 -:109FB000000000008F4C003825860001AF460038B5 -:109FC0008F47003C00A9282300E96821AF4D003CE1 -:109FD00014A0FFCE2CA2008003E0000800000000C7 -:109FE00027BDFFD03C020002AFB100143C11000CB1 -:109FF000AF450038AFB3001CAF46003C008098214D -:10A00000AF42003024050088AF44002803512021CE -:10A01000AFBF0028AFB50024AFB40020AFB2001826 -:10A020000E0014EEAFB000103C1F08008FFF004C74 -:10A030003C1808008F1800642410FF8003F3A82147 -:10A0400032B9007F02B078240018A0C0033A702112 -:10A050000018914001D12021AF4F00280E0014EECE -:10A06000025428213C0D08008DAD0050240501202C -:10A0700001B35821316C007F01705024019A4821AE -:10A08000013120210E0014EEAF4A00283C080800E0 -:10A090008D0800543C0508008CA50064011338218C -:10A0A00030E6007F00F0182400DA20210091202102 -:10A0B000AF4300280E0014EE000529403C020800C2 -:10A0C0008C4200583C1008008E1000601200001CEA -:10A0D000005388212415FF800A0015713C14000CE0 -:10A0E0003226007F0235182400DA20210240282180 -:10A0F000AF430028009420210E0014EE2610FFC06C -:10A100001200000F023288212E05004110A0FFF43A -:10A11000241210003226007F00109180023518248E -:10A1200000DA202102402821AF430028009420219A -:10A130000E0014EE000080211600FFF30232882189 -:10A140003C0B08008D6B005C240AFF802405000294 -:10A1500001734021010A4824AF4900283C0408004B -:10A16000948400623110007F021A88213C07000CA1 -:10A170000E000CAA0227982100402821026020210D -:10A180008FBF00288FB500248FB400208FB3001C30 -:10A190008FB200188FB100148FB000100A0014EEB7 -:10A1A00027BD00308F83001C8C6200041040000328 -:10A1B0000000000003E00008000000008C640010B4 -:0CA1C0008C6500080A0015278C66000C56 -:04A1CC00000000008F -:10A1D0000000001B0000000F0000000A0000000843 -:10A1E000000000060000000500000005000000045B -:10A1F0000000000400000003000000030000000352 -:10A200000000000300000003000000020000000244 -:10A210000000000200000002000000020000000236 -:10A220000000000200000002000000020000000226 -:10A230000000000200000002000000020000000216 -:10A240000000000200000001000000010000000109 -:10A2500008000F2408000D6C08000FB808001060FB -:10A2600008000F4C08000F8C0800119408000D889E -:10A27000080011B808000DD8080015540800151C76 -:10A2800008000D8808000D8808000D88080012409D -:10A290000800124008000D8808000D88080014E02E -:10A2A00008000D8808000D8808000D8808000D883A -:10A2B000080013B408000D8808000D8808000D88F8 -:10A2C00008000D8808000D8808000D8808000D881A -:10A2D00008000D8808000D8808000D8808000D880A -:10A2E00008000D8808000D8808000D8808000FACD4 -:10A2F00008000D8808000D880800167808000D88F1 -:10A3000008000D8808000D8808000D8808000D88D9 -:10A3100008000D8808000D8808000D8808000D88C9 -:10A3200008000D8808000D8808000D8808000D88B9 -:10A3300008000D8808000D8808000D8808000D88A9 -:10A340000800141008000D8808000D880800133458 -:10A35000080012A408001E2C08001EFC08001F1490 -:10A3600008001F2808001F3808001E2C08001E2C9B -:10A3700008001E2C08001ED808002E1408002E1CF1 -:10A3800008002DE408002DF008002DFC08002E0820 -:10A39000080052E8080052A8080052740800524809 -:08A3A00008005224080051E0FE -:08A3A8000A000C840000000013 -:10A3B000000000000000000D727870362E302E3143 -:10A3C0003500000006000F0300000000000000013F -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000080000000001B -:10D59000000000000000000000000000000000008B -:10D5A0000000000000000000000000000000000A71 -:10D5B0000000000000000000000000001000000358 -:10D5C000000000000000000D0000000D3C020800FB -:10D5D000244273203C030800246377ACAC40000075 -:10D5E0000043202B1480FFFD244200043C1D080052 -:10D5F00037BD7FFC03A0F0213C100800261032103C -:10D600003C1C0800279C73200E0010FE0000000048 -:10D610000000000D30A5FFFF30C600FF274301804A -:10D620008F4201B80440FFFE24020002AC640000F7 -:10D63000A4650008A066000AA062000B3C0210006E -:10D64000AC67001803E00008AF4201B83C0360007B -:10D650008C624FF80440FFFE3C020200AC644FC0F5 -:10D66000AC624FC43C02100003E00008AC624FF80B -:10D670009482000C2486001400A0382100021302BA -:10D68000000210800082402100C8102B104000577B -:10D690000000000090C300002C62000950400051BF -:10D6A00090C20001000310803C030800246372D084 -:10D6B000004310218C4200000040000800000000E0 -:10D6C00090C300012402000A1462003A0000000026 -:10D6D000010610232C42000A1440003624C6000222 -:10D6E0008CE2000034420100ACE2000090C2000075 -:10D6F00090C3000190C4000290C5000300031C0009 -:10D7000000021600004310250004220000441025EA -:10D710000045102524C60004ACE2000490C20000BD -:10D7200090C3000190C4000290C5000300021600DF -:10D7300000031C00004310250004220000441025B3 -:10D740000045102524C600040A000CB8ACE200080D -:10D7500090C30001240200041462001624C60002D3 -:10D7600090C2000090C400018CE30000000212008F -:10D77000004410253463000424C60002ACE2000C0F -:10D780000A000CB8ACE3000090C3000124020003BF -:10D790001462000824C600028CE2000090C300005E -:10D7A00024C6000134420008A0E300100A000CB8AF -:10D7B000ACE2000003E000082402000190C3000175 -:10D7C000240200021062000224C400020100202191 -:10D7D0000A000CB8008030210A000CB824C60001F1 -:10D7E00090C200010A000CB800C2302103E000081A -:10D7F0000000102127BDFFE8AFBF0014AFB000103C -:10D800000E00130200808021936200052403FFFEB6 -:10D8100002002021004310248FBF00148FB000109D -:10D82000A36200050A00130B27BD001827BDFFE8FF -:10D83000AFB00010AFBF00140E000F3C008080217D -:10D840009362000024030050304200FF14430004A0 -:10D8500024020100AF4201800A000D3002002021A5 -:10D86000AF400180020020218FBF00148FB0001054 -:10D870000A000FE727BD001827BDFF80AFBE007864 -:10D88000AFB70074AFB20060AFBF007CAFB600703E -:10D89000AFB5006CAFB40068AFB30064AFB1005C6B -:10D8A000AFB000588F5001283C0208008C4231A0D4 -:10D8B0002403FF809365003F0202102100431024DF -:10D8C000AF4200243C0208008C4231A09364000562 -:10D8D00030B200FF020210213042007F03421821C3 -:10D8E000000420273C02000A006218213084000155 -:10D8F000AF8300140000F0210000B8211480005311 -:10D90000AFA0005093430116934401128F450104C8 -:10D91000306300FF3C020001308400FF00A2282495 -:10D92000034310210344182124564000246740007B -:10D9300014A001CD2402000193620000304300FFD7 -:10D94000240200201062000524020050106200062C -:10D95000000000000A000D74000000000000000D2F -:10D960000A000D7DAFA000303C1E080027DE736C5E -:10D970000A000D7DAFA000303C0208008C4200DCA4 -:10D98000244200013C010800AC2200DC0E00139F81 -:10D99000000000000A000F318FBF007C8F4201049D -:10D9A0003C03002092D3000D004310240002202BE2 -:10D9B00000042140AFA400308F4301043C0200402A -:10D9C0000062182414600002348500400080282181 -:10D9D00032620020AFA500301440000234A600805F -:10D9E00000A0302110C0000BAFA6003093C5000886 -:10D9F0008F67004C0200202100052B0034A5008118 -:10DA000030A5F0810E000C9B30C600FF0A000F2EDF -:10DA1000000000009362003E304200401040000FC2 -:10DA200024020004564200072402001202002021B2 -:10DA300000E028210E0013F702C030210A000F3148 -:10DA40008FBF007C16420005000000000E000D2173 -:10DA5000000020210A000F318FBF007C9743011A7C -:10DA600096C4000E93620035326500043075FFFFE6 -:10DA700000442004AFA400548ED1000410A000156F -:10DA80008ED400089362003E3042004010400007F0 -:10DA9000000000000E0013E0022020211040000DC5 -:10DAA000000000000A000F2E000000008F620044FA -:10DAB000022210230440016A000000008F62004827 -:10DAC0000222102304410166240400160A000E21DC -:10DAD0008FC200048F620048022210230440000815 -:10DAE000000000003C0208008C423100244200018A -:10DAF0003C010800AC2231000A000F2300000000A6 -:10DB00008F62004002221023184000128F840014FC -:10DB10003C0208008C423100327300FC0000A82156 -:10DB2000244200013C010800AC2231008F63004018 -:10DB30009482011C022318233042FFFF0043102A65 -:10DB4000504000102402000C8F6200400A000DF2C9 -:10DB5000022210239483011C9762003C0043102B87 -:10DB600010400006000000009482011C00551023A4 -:10DB7000A482011C0A000DF72402000CA480011CE1 -:10DB80002402000CAFA200308F620040005120231D -:10DB90001880000D02A4102A144001260000000085 -:10DBA0001495000602A410233A62000130420001DD -:10DBB000144001200000000002A410230224882148 -:10DBC0000A000E093055FFFF0000202132620002DA -:10DBD0001040001A326200109362003E3042004052 -:10DBE000504000118FC200040E00130202002021D9 -:10DBF00024020018A362003F936200052403FFFE85 -:10DC000002002021004310240E00130BA362000524 -:10DC100024040039000028210E0013C9240600182E -:10DC20000A000F3024020001240400170040F80904 -:10DC3000000000000A000F3024020001104001081B -:10DC4000000000008F63004C8F620054028210239A -:10DC50001C40010302831023044200010060A02144 -:10DC6000AFA40018AFB10010AFB50014934201206B -:10DC70008F6500409763003C304200FF0342102153 -:10DC8000004410218FA400543063FFFF2442400061 -:10DC90000083182B8FA40030AFA20020AFA500286E -:10DCA00000832025AFA40030AFA50024AFA0002C36 -:10DCB000AFB400349362003E30420008504000117F -:10DCC0008FC2000002C0202127A500380E000CB230 -:10DCD000AFA000385440000B8FC200008FA2003864 -:10DCE00030420100504000078FC200008FA3003C6B -:10DCF0008F6200600062102304430001AF63006084 -:10DD00008FC200000040F80927A400108FA2003045 -:10DD10003042000254400001327300FE9362003E24 -:10DD200030420040104000378FA200248F62005420 -:10DD30001682001A326200012402001412420010FE -:10DD40002A42001510400006240200162402000C8E -:10DD500012420007326200010A000E7D000000003E -:10DD600012420005326200010A000E7D0000000030 -:10DD70000A000E782417000E0A000E7824170010EF -:10DD80000A000E7C24170012936200232403FFBDB7 -:10DD900000431024A36200233262000110400019E6 -:10DDA0008FA200242402000C1242000E2A42000D11 -:10DDB000104000062402000E2402000A124200074E -:10DDC0008FA200240A000E9524420001124200088E -:10DDD0008FA200240A000E95244200010A000E932F -:10DDE000241700082402000E16E200022417001671 -:10DDF000241700108FA2002424420001AFA20024A7 -:10DE00008FA200248FA300148F76004000431021BE -:10DE1000AF6200408F8200149442011C1040000940 -:10DE2000000000008F6200488F6400409763003C50 -:10DE3000004410233063FFFF0043102A1040000805 -:10DE40008FA20054936400368F6300403402FFFCBD -:10DE50000082100400621821AF6300488FA20054B2 -:10DE60008FA600300282902130C200081040000EC0 -:10DE7000000000008F6200581642000430C600FF08 -:10DE80009742011A5040000134C6001093C50008A3 -:10DE90008FA700340200202100052B0034A500804C -:10DEA0000E000C9B30A5F0808F62004000561023BE -:10DEB0001840001B8FA200183C0208008C423198C9 -:10DEC000304200101040000D2402000197620068EB -:10DED0001440000A240200018F8200149442011CA5 -:10DEE0001440000624020001A76200689742007AED -:10DEF000244200640A000EE9A7620012A762001221 -:10DF00000E001302020020219362007D2403000111 -:10DF100002002021344200010A000EE7AFA30050A6 -:10DF20001840000A000000000E0013020200202129 -:10DF30009362007D2403000102002021AFA3005062 -:10DF4000344200040E00130BA362007D9362003E76 -:10DF5000304200401440000C326200011040000AC0 -:10DF6000000000008F6300408FC2000424040018EA -:10DF7000246300010040F809AF6300408FA2003025 -:10DF80000A000F30304200048F6200581052001017 -:10DF9000000000008F620018022210231C400008BD -:10DFA000240400018F6200181622000900000000FE -:10DFB0008F62001C02821023044000050000000054 -:10DFC000AF720058AFA40050AF710018AF74001CBE -:10DFD00012E0000B8FA200500E001302020020215D -:10DFE000A377003F0E00130B0200202102E0302136 -:10DFF000240400370E0013C9000028218FA200500E -:10E0000010400003000000000E000CA902002021B7 -:10E0100012A00005000018218FA200303042000439 -:10E020005040001100601021240300010A000F304D -:10E03000006010210E001302020020219362007D77 -:10E0400002002021344200040E00130BA362007D65 -:10E050000E000CA9020020210A000F30240200014A -:10E06000AF400044240200018FBF007C8FBE0078C7 -:10E070008FB700748FB600708FB5006C8FB40068D6 -:10E080008FB300648FB200608FB1005C8FB0005816 -:10E0900003E0000827BD00808F4201B80440FFFE66 -:10E0A00024020800AF4201B803E0000800000000AD -:10E0B0003C02000803421021944200483084FFFFD4 -:10E0C000248400123045FFFF10A0001700A4102B7D -:10E0D0001040001624020003934201202403001A7A -:10E0E000A343018B304200FF2446FFFE8F820000D5 -:10E0F00000A6182B3863000100021382004310248D -:10E10000104000058F84000434820001A74601946A -:10E1100003E00008AF8200042402FFFE0082102406 -:10E1200003E00008AF8200042402000303E00008BB -:10E13000A342018B27BDFFE0AFB10014AFB00010C8 -:10E14000AFBF001830B0FFFF30D1FFFF8F4201B8E2 -:10E150000440FFFE00000000AF440180AF440020F7 -:10E160000E000F42020020218F8300008F840004E4 -:10E17000A750019AA750018EA74301908F830008F2 -:10E1800030828000AF4301A8A75101881040000EE3 -:10E190008F82000493420116304200FC24420004A6 -:10E1A000005A10218C4240003042FFFF144000060C -:10E1B0008F8200043C02FFFF34427FFF0082102464 -:10E1C000AF8200048F8200042403BFFF00431024A9 -:10E1D000A74201A69743010C8F42010400031C00D3 -:10E1E0003042FFFF00621825AF4301AC3C02100033 -:10E1F000AF4201B88FBF00188FB100148FB000106C -:10E2000003E0000827BD00208F47007093420112F1 -:10E210008F83000027BDFFF0304200FF00022882FC -:10E2200030620100000030211040004324A40003AC -:10E230003062400010400010306220000004108066 -:10E24000005A10218C43400024A4000400041080D4 -:10E25000AFA30000005A10218C424000AFA200047E -:10E2600093420116304200FC005A10218C424000BB -:10E270000A000FC0AFA200081040002F000030219C -:10E2800000041080005A10218C43400024A4000494 -:10E2900000041080AFA30000005A10218C424000FF -:10E2A000AFA00008AFA200048FA800080000302132 -:10E2B00000002021240A00083C090800252901004B -:10E2C00003A41021148A000300042A001100000A8C -:10E2D0000000000090420000248400012C83000C08 -:10E2E00000A2102100021080004910218C42000081 -:10E2F0001460FFF300C230263C0408008C84310413 -:10E300008F4200702C8300201060000900473823E2 -:10E310003C030800246331080004108000431021EE -:10E3200024830001AC4700003C010800AC23310409 -:10E33000AF8600082406000100C0102103E0000899 -:10E3400027BD00103C0208008C42003827BDFFD0DA -:10E35000AFB50024AFB40020AFB10014AFBF0028A8 -:10E36000AFB3001CAFB20018AFB00010000088219E -:10E370003C15080026B50038144000022454FFFF65 -:10E380000000A0219742010E8F8400003042FFFF61 -:10E39000308340001060000A245200043C02002038 -:10E3A0000082102450400007308280008F820004D9 -:10E3B0002403BFFF008318240A0010103442100009 -:10E3C000308280001040000A3C02002000821024AD -:10E3D000104000078F8200043C03FFFF34637FFF7F -:10E3E0000083182434428000AF820004AF83000011 -:10E3F0000E000F980000000014400007000000000D -:10E400009743011E9742011C3063FFFF0002140076 -:10E4100000621825AF8300089742010C8F4340002B -:10E420003045FFFF3402FFFF1462000300000000CC -:10E430000A001028241100208F42400030420100C1 -:10E4400054400001241100108F840000308210001D -:10E450005040001436310001308200201440000B7F -:10E460003C021000008210245040000E36310001A2 -:10E470003C030E003C020DFF008318243442FFFFD2 -:10E480000043102B50400007363100013C020800C9 -:10E490008C42002C244200013C010800AC22002CDC -:10E4A000363100053C0608008CC6003454C00023F9 -:10E4B0008F8500008F820004304240005440001FCE -:10E4C0008F8500003C021F01008210243C031000D5 -:10E4D0005443001A8F85000030A202001440001738 -:10E4E0008F8500003250FFFF363100028F4201B8A5 -:10E4F0000440FFFE00000000AF4001800200202128 -:10E500000E000F42AF4000208F8300042402BFFFA3 -:10E51000A750019A006218248F820000A750018E34 -:10E52000A7510188A74301A6A74201903C02100011 -:10E53000AF4201B80A0010F5000010213C021000A3 -:10E5400000A210241040003A0000000010C0000F8C -:10E550000000000030A201001040000C3C0302004B -:10E560003C020F0000A2102410430008000000002D -:10E570008F8200080054102400551021904200049E -:10E58000244200040A00109F000221C00000000085 -:10E59000000516023050000F3A0300022E4203EF2E -:10E5A000384200012C6300010062182414600073DB -:10E5B000240200013C0308008C6300D02E06000CEE -:10E5C000386200012C42000100461024144000155E -:10E5D000001021C02602FFFC2C4200045440001110 -:10E5E00000002021386200022C4200010046102465 -:10E5F00010400003000512420A00109F0000202175 -:10E600000010182B0043102450400006001021C0B9 -:10E61000000020213245FFFF0E000F633226FFFB72 -:10E62000001021C03245FFFF0A0010F2362600021A -:10E630008F4240003C0308008C63002430420100FC -:10E640001040004630620001322200043070000D9C -:10E65000144000022413000424130002000512C217 -:10E66000384200012E4303EF3042000138630001BD -:10E6700000431025104000033231FFFB2402FFFB52 -:10E680000202802410C000183202000130A20100F2 -:10E6900010400015320200013C020F0000A21024BD -:10E6A0003C0302001043000F8F8200082403FFFE8A -:10E6B00002038024005410240055102190420004CD -:10E6C000023330252442000412000002000221C05F -:10E6D0003226FFFF0E000F633245FFFF12000027B6 -:10E6E00000001021320200011040000D320200042F -:10E6F0002402000112020002023330253226FFFFFD -:10E70000000020210E000F633245FFFF2402FFFEB0 -:10E7100002028024120000190000102132020004BD -:10E72000104000162402000124020004120200021C -:10E73000023330253226FFFF3245FFFF0E000F6304 -:10E74000240401002402FFFB020280241200000BBB -:10E75000000010210A0010F52402000110400007FB -:10E76000000010213245FFFF362600020000202164 -:10E770000E000F6300000000000010218FBF002872 -:10E780008FB500248FB400208FB3001C8FB2001807 -:10E790008FB100148FB0001003E0000827BD0030D7 -:10E7A00027BDFFD0AFB000103C04600CAFBF002C01 -:10E7B000AFB60028AFB50024AFB40020AFB3001C43 -:10E7C000AFB20018AFB100148C8250002403FF7F59 -:10E7D0003C1A8000004310243442380CAC825000B4 -:10E7E000240200033C106000AF4200088E020808BB -:10E7F0003C1B80083C010800AC2000203042FFF0A8 -:10E80000384200102C4200010E001B85AF82001818 -:10E810003C04FFFF3C020400348308063442000C31 -:10E82000AE021948AE03194C3C0560168E021980E1 -:10E830008CA300003442020000641824AE02198048 -:10E840003C0253531462000334A47C008CA20004E5 -:10E85000005020218C82007C8C830078AF820010D5 -:10E86000AF83000C8F55000032A200031040FFFD63 -:10E8700032A200011040013D32A200028F42012865 -:10E88000AF4200208F4201048F430100AF8200009D -:10E890000E000F3CAF8300043C0208008C4200C015 -:10E8A000104000088F8400003C0208008C4200C425 -:10E8B000244200013C010800AC2200C40A00126995 -:10E8C000000000003C020010008210241440010CE3 -:10E8D0008F8300043C0208008C4200203C030800A7 -:10E8E0008C63003800008821244200013C010800AC -:10E8F000AC2200203C16080026D600381460000226 -:10E900002474FFFF0000A0219742010E30834000D5 -:10E910003042FFFF1060000A245200043C02002035 -:10E920000082102450400007308280008F82000453 -:10E930002403BFFF008318240A0011703442100022 -:10E94000308280001040000A3C0200200082102427 -:10E95000104000078F8200043C03FFFF34637FFFF9 -:10E960000083182434428000AF820004AF8300008B -:10E970000E000F9800000000144000070000000087 -:10E980009743011E9742011C3063FFFF00021400F1 -:10E9900000621825AF8300089742010C8F434000A6 -:10E9A0003045FFFF3402FFFF146200030000000047 -:10E9B0000A001188241100208F42400030420100DB -:10E9C00054400001241100108F8400003082100098 -:10E9D0005040001436310001308200201440000BFA -:10E9E0003C021000008210245040000E363100011D -:10E9F0003C030E003C020DFF008318243442FFFF4D -:10EA00000043102B50400007363100013C02080043 -:10EA10008C42002C244200013C010800AC22002C56 -:10EA2000363100053C0608008CC6003454C0002373 -:10EA30008F8500008F820004304240005440001F48 -:10EA40008F8500003C021F01008210243C0310004F -:10EA50005443001A8F85000030A2020014400017B2 -:10EA60008F8500003250FFFF363100028F4201B81F -:10EA70000440FFFE00000000AF40018002002021A2 -:10EA80000E000F42AF4000208F8300042402BFFF1E -:10EA9000A750019A006218248F820000A750018EAF -:10EAA000A7510188A74301A6A74201903C0210008C -:10EAB000AF4201B80A001267000010213C021000AA -:10EAC00000A210241040003A0000000010C0000F07 -:10EAD0000000000030A201001040000C3C030200C6 -:10EAE0003C020F0000A210241043000800000000A8 -:10EAF0008F82000800541024005610219042000418 -:10EB0000244200040A0011FF000221C0000000009E -:10EB1000000516023050000F3A0300022E4203EFA8 -:10EB2000384200012C630001006218241460008543 -:10EB3000240200013C0308008C6300D02E06000C68 -:10EB4000386200012C4200010046102414400015D8 -:10EB5000001021C02602FFFC2C420004544000118A -:10EB600000002021386200022C42000100461024DF -:10EB700050400003000512420A0011FF000020214E -:10EB80000010182B0043102450400006001021C034 -:10EB9000000020213245FFFF0E000F633226FFFBED -:10EBA000001021C03245FFFF0A0012523626000233 -:10EBB0008F4240003C0308008C6300243042010077 -:10EBC0001040004630620001322200043070000D17 -:10EBD000144000022413000424130002000512C292 -:10EBE000384200012E4303EF304200013863000138 -:10EBF00000431025104000033231FFFB2402FFFBCD -:10EC00000202802410C000183202000130A201006C -:10EC100010400015320200013C020F0000A2102437 -:10EC20003C0302001043000F8F8200082403FFFE04 -:10EC30000203802400541024005610219042000446 -:10EC4000023330252442000412000002000221C0D9 -:10EC50003226FFFF0E000F633245FFFF120000391E -:10EC600000001021320200011040000D32020004A9 -:10EC70002402000112020002023330253226FFFF77 -:10EC8000000020210E000F633245FFFF2402FFFE2B -:10EC9000020280241200002B000010213202000426 -:10ECA0001040002824020001240200041202000285 -:10ECB000023330253226FFFF3245FFFF0E000F637F -:10ECC000240401002402FFFB020280241200001D24 -:10ECD000000010210A0012672402000150400019B0 -:10ECE000000010213245FFFF3626000200002021DF -:10ECF0000E000F63000000000A00126700001021E0 -:10ED00002402BFFF00621024104000080000000031 -:10ED1000240287FF00621024144000083C020060B7 -:10ED20000082102410400005000000000E000D3489 -:10ED3000000000000A001267000000000E0012C769 -:10ED400000000000104000063C0240008F430124F8 -:10ED50003C026020AC430014000000003C02400074 -:10ED6000AF4201380000000032A200021040FEBD98 -:10ED7000000000008F4201403C044000AF420020F0 -:10ED80008F4301483C027000006218241064004266 -:10ED9000000000000083102B144000063C026000BD -:10EDA0003C022000106200073C0240000A0012C32F -:10EDB000000000001062003C3C0240000A0012C348 -:10EDC000000000008F4501408F4601448F420148FA -:10EDD00000021402304300FF240200041462000AFF -:10EDE000274401808F4201B80440FFFE2402001C2A -:10EDF000AC850000A082000B3C021000AF4201B8BD -:10EE00000A0012C33C0240002402000914620012EE -:10EE100000061602000229C0AF4500208F4201B84B -:10EE20000440FFFE2402000124030003AF450180DB -:10EE3000A343018BA740018EA740019AA7400190F0 -:10EE4000AF4001A8A7420188A74201A6AF4001AC8C -:10EE50003C021000AF4201B88F4201B80440FFFEEF -:10EE600000000000AC8500008F420148000214023F -:10EE7000A482000824020002A082000B8F420148F5 -:10EE8000A48200103C021000AC860024AF4201B8FE -:10EE90000A0012C33C0240000E00131000000000E4 -:10EEA0000A0012C33C0240000E001BBA0000000022 -:10EEB0003C024000AF420178000000000A00112F20 -:10EEC000000000008F4201003042003E144000115B -:10EED00024020001AF4000488F420100304207C0C9 -:10EEE0001040000500000000AF40004CAF40005053 -:10EEF00003E0000824020001AF400054AF4000408E -:10EF00008F4201003042380054400001AF400044BD -:10EF10002402000103E00008000000008F4201B855 -:10EF20000440FFFE24020001AF440180AF40018491 -:10EF3000A7450188A342018A24020002A342018B53 -:10EF40009742014A14C00004A7420190AF4001A4B7 -:10EF50000A0012EF3C0210008F420144AF4201A4AC -:10EF60003C021000AF4001A803E00008AF4201B826 -:10EF70008F4201B80440FFFE24020002AF4401802A -:10EF8000AF440184A7450188A342018AA342018BB3 -:10EF90009742014AA7420190AF4001A48F42014429 -:10EFA000AF4201A83C02100003E00008AF4201B8E4 -:10EFB0003C0290003442000100822025AF44002032 -:10EFC0008F4200200440FFFE0000000003E0000824 -:10EFD000000000003C028000344200010082202535 -:10EFE00003E00008AF44002027BDFFE8AFBF0014D6 -:10EFF000AFB000108F500140934301499342014844 -:10F0000093440148306300FF304200FF00021200C9 -:10F0100000622825240200191062007630840080E6 -:10F020002862001A1040001C24020020240200085C -:10F0300010620077286200091040000E2402000BC5 -:10F0400024020001106200342862000250400005D2 -:10F050002402000650600034020020210A00139AA6 -:10F060000000000010620030020020210A00139A04 -:10F07000000000001062003B2862000C50400002BB -:10F080002402000E24020009106200560200202112 -:10F090000A00139A00000000106200562862002146 -:10F0A0001040000F240200382402001C1062005897 -:10F0B0002862001D104000062402001F2402001BCD -:10F0C0001062004C000000000A00139A00000000CB -:10F0D0001062004A020020210A00139A000000007A -:10F0E00010620045286200391040000724020080A9 -:10F0F0002462FFCB2C420002104000450200202178 -:10F100000A00139600003021106200090000000080 -:10F110000A00139A000000001480003D0200202124 -:10F120000A0013908FBF00140A00139624060001F2 -:10F130008F4201B80440FFFE24020002A342018B6B -:10F14000A74501889742014AA74201908F42014496 -:10F15000A74201923C021000AF4201B80A00139C82 -:10F160008FBF00149742014A14400029000000009C -:10F1700093620005304200041440002500000000A6 -:10F180000E001302020020219362000502002021DC -:10F19000344200040E00130BA362000593620005C5 -:10F1A0003042000414400002000000000000000D86 -:10F1B0009362000024030020304200FF1443001437 -:10F1C000000000008F4201B80440FFFE2402000549 -:10F1D000AF500180A342018B3C0210000A00139A39 -:10F1E000AF4201B88FBF00148FB000100A0012F2B6 -:10F1F00027BD00180000000D020020210000302172 -:10F200008FBF00148FB000100A0012DD27BD001858 -:10F210000000000D8FBF00148FB0001003E0000845 -:10F2200027BD001827BDFFE8AFBF00100E000F3C40 -:10F2300000000000AF4001808FBF001000002021BF -:10F240000A000FE727BD00183084FFFF30A5FFFF3D -:10F25000000018211080000700000000308200012B -:10F260001040000200042042006518210A0013AB80 -:10F270000005284003E000080060102110C00006CF -:10F2800024C6FFFF8CA2000024A50004AC8200006D -:10F290000A0013B52484000403E000080000000005 -:10F2A00010A0000824A3FFFFAC86000000000000AF -:10F2B000000000002402FFFF2463FFFF1462FFFA36 -:10F2C0002484000403E0000800000000308300FFF5 -:10F2D00030A500FF30C600FF274701808F4201B8EC -:10F2E0000440FFFE000000008F420128346340000C -:10F2F000ACE2000024020001ACE00004A4E300083A -:10F30000A0E2000A24020002A0E2000B3C0210006E -:10F31000A4E50010ACE00024ACE00028A4E6001254 -:10F3200003E00008AF4201B827BDFFE8AFBF0010FF -:10F330009362003F24030012304200FF1043000D8F -:10F34000008030218F620044008210230440000AB4 -:10F350008FBF00108F62004824040039000028216C -:10F3600000C2102304410004240600120E0013C939 -:10F37000000000008FBF00102402000103E000081D -:10F3800027BD001827BDFFC8AFB20030AFB1002CB9 -:10F39000AFBF0034AFB0002890C5000D00809021B1 -:10F3A00030A400101080000B00C088218CC300081E -:10F3B0008F6200541062000730A20005144000B5AF -:10F3C000240400010E000D21000020210A0014BBBE -:10F3D0000040202130A200051040000930A3001297 -:10F3E000108000AC240400018E2300088F620054BA -:10F3F000146200A98FBF00340A00142C24040038C2 -:10F4000024020012146200A324040001022020211F -:10F4100027A500100E000CB2AFA000101040001184 -:10F42000024020218E220008AF620084AF600040BD -:10F430000E001302000000009362007D02402021B4 -:10F44000344200200E00130BA362007D0E000CA9B5 -:10F4500002402021240400382405008D0A0014B83D -:10F46000240600129362003E304200081040000F54 -:10F470008FA2001030420100104000078FA300143B -:10F480008F6200600062102304430008AF630060D5 -:10F490000A00144100000000AF6000609362003E6B -:10F4A0002403FFF700431024A362003E9362003E52 -:10F4B00030420008144000022406000300003021FE -:10F4C00093620034936300378F640084304200FFFE -:10F4D000306300FF006618210003188000432821D4 -:10F4E00000A4202B1080000B000000009763003C5C -:10F4F0008F6200843063FFFF004510230062182BE9 -:10F5000014600004000000008F6200840A00145D93 -:10F51000004580239762003C3050FFFF8FA300100E -:10F520003062000410400004000628808FA2001CF6 -:10F530000A0014650202102B2E020218504000032C -:10F54000240202180A00146E02051023306300041E -:10F5500010600003004510238FA2001C00451023FB -:10F56000004080212C420080544000012410008083 -:10F570000E0013020240202124020001AF62000CA1 -:10F580009362003E001020403042007FA362003EA4 -:10F590008E22000424420001AF620040A770003CAC -:10F5A0008F6200509623000E00431021AF62005876 -:10F5B0008F62005000441021AF62005C8E22000474 -:10F5C000AF6200188E220008AF62001C8FA20010EC -:10F5D000304200085440000A93A20020A360003685 -:10F5E000936200362403FFDFA36200359362003E7E -:10F5F00000431024A362003E0A0014988E220008E3 -:10F60000A36200358E220008AF62004C8F62002496 -:10F610008F63004000431021AF62004893620000F6 -:10F6200024030050304200FF144300122403FF80E3 -:10F630003C0208008C4231A00242102100431024F9 -:10F64000AF4200283C0208008C4231A08E24000802 -:10F650003C03000C024210213042007F0342102183 -:10F6600000431021AC4400D88E230008AF82001460 -:10F67000AC4300DC0E00130B0240202124040038B0 -:10F68000000028212406000A0E0013C90000000013 -:10F69000240400018FBF00348FB200308FB1002CE2 -:10F6A0008FB000280080102103E0000827BD00383B -:10F6B00027BDFFF827420180AFA20000308A00FF7B -:10F6C0008F4201B80440FFFE000000008F46012871 -:10F6D0003C0208008C4231A02403FF80AF86004822 -:10F6E00000C2102100431024AF4200243C02080055 -:10F6F0008C4231A08FA900008FA8000000C2102109 -:10F700003042007F034218213C02000A00621821A7 -:10F71000946400D48FA700008FA50000240200028B -:10F72000AF830014A0A2000B8FA30000354260003D -:10F730003084FFFFA4E200083C021000AD26000068 -:10F74000AD040004AC60002427BD0008AF4201B83E -:10F7500003E00008240200018F88003C9382002807 -:10F760008F8300143C07080024E7777800481023B3 -:10F77000304200FF304900FC246500888F8600403D -:10F78000304A0003112000090000202124820004D7 -:10F790008CA30000304400FF0089102AACE3000075 -:10F7A00024A500041440FFF924E7000411400009D7 -:10F7B000000020212482000190A30000304400FFBB -:10F7C000008A102BA0E3000024A500011440FFF9DB -:10F7D00024E7000130C20003144000048F85003C80 -:10F7E000310200031040000D0000000010A00009CD -:10F7F000000020212482000190C30000304400FF5B -:10F800000085102BA0E3000024C600011440FFF97E -:10F8100024E7000103E00008000000001100FFFDE4 -:10F8200000002021248200048CC30000304400FF2B -:10F830000088102BACE3000024C600041440FFF93C -:10F8400024E7000403E00008000000008F83003C70 -:10F850009382002830C600FF30A500FF004310232C -:10F86000304300FF8F8200140080382100431021B4 -:10F8700014C00002244800880083382130E20003CD -:10F880001440000530A2000314400003306200035E -:10F890001040000D0000000010A000090000202111 -:10F8A0002482000190E30000304400FF0085102B0B -:10F8B000A103000024E700011440FFF9250800011E -:10F8C00003E000080000000010A0FFFD0000202160 -:10F8D000248200048CE30000304400FF0085102BDC -:10F8E000AD03000024E700041440FFF925080004DC -:10F8F00003E00008000000000080482130AAFFFF5C -:10F9000030C600FF30E7FFFF274801808F4201B873 -:10F910000440FFFE8F820048AD0200008F420124A8 -:10F92000AD0200048D220020A5070008A102000AF4 -:10F9300024020016A102000B934301208D2200082F -:10F940008D240004306300FF004310219783003AA8 -:10F95000004410218D250024004310233C0308009F -:10F960008C6331A08F840014A502000C246300E88E -:10F970002402FFFFA50A000EA5030010A506001231 -:10F98000AD050018AD020024948201142403FFF792 -:10F990003042FFFFAD0200288C820118AD02002C1E -:10F9A0003C021000AD000030AF4201B88D220020B3 -:10F9B0000043102403E00008AD2200208F820014D1 -:10F9C00030E7FFFF00804821904200D330A5FFFFC1 -:10F9D00030C600FF0002110030420F0000E238255F -:10F9E000274801808F4201B80440FFFE8F82004803 -:10F9F000AD0200008F420124AD0200048D220020E0 -:10FA0000A5070008A102000A24020017A102000BAA -:10FA1000934301208D2200088D240004306300FFF1 -:10FA2000004310219783003A004410218F84001472 -:10FA3000004310233C0308008C6331A0A502000C96 -:10FA4000A505000E246300E8A5030010A50600121A -:10FA5000AD0000148D220024AD0200188C82005CE1 -:10FA6000AD02001C8C820058AD0200202402FFFF72 -:10FA7000AD020024948200E63042FFFFAD02002870 -:10FA800094820060948300BE30427FFF3063FFFFAA -:10FA90000002120000431021AD02002C3C021000B5 -:10FAA000AD000030AF4201B8948200BE2403FFF7DE -:10FAB00000A21021A48200BE8D2200200043102449 -:10FAC00003E00008AD220020274301808F4201B8E7 -:10FAD0000440FFFE8F8200249442001C3042FFFF4E -:10FAE000000211C0AC62000024020019A062000BE9 -:10FAF0003C021000AC60003003E00008AF4201B8E7 -:10FB00008F87002C30C300FF8F4201B80440FFFEF6 -:10FB10008F82004834636000ACA2000093820044EE -:10FB2000A0A200058CE20010A4A20006A4A3000875 -:10FB30008C8200202403FFF7A0A2000A2402000206 -:10FB4000A0A2000B8CE20000ACA200108CE200042A -:10FB5000ACA200148CE2001CACA200248CE20020B9 -:10FB6000ACA200288CE2002CACA2002C8C820024D9 -:10FB7000ACA200183C021000AF4201B88C820020F9 -:10FB80000043102403E00008AC8200208F8600149C -:10FB900027BDFFE8AFBF0014AFB0001090C20063F4 -:10FBA000304200201040000830A500FF8CC2007CCD -:10FBB0002403FFDF24420001ACC2007C90C200633A -:10FBC00000431024A0C2006310A000238F83001400 -:10FBD00027500180020028210E0015D6240600823D -:10FBE0008F82001490420063304200405040001960 -:10FBF000A38000448F83002C8F4201B80440FFFE95 -:10FC00008F820048AE02000024026082A602000833 -:10FC100024020002A202000B8C620008AE02001057 -:10FC20008C62000CAE0200148C620014AE0200184C -:10FC30008C620018AE0200248C620024AE02002800 -:10FC40008C620028AE02002C3C021000AF4201B8CA -:10FC5000A38000448F8300148FBF00148FB0001066 -:10FC60009062006327BD00183042007FA0620063ED -:10FC70009782003A8F86003C8F850014938300287A -:10FC800000461023A782003AA4A000E490A40063D9 -:10FC90008F820040AF83003C2403FFBF0046102149 -:10FCA00000832024AF820040A0A400638F82001450 -:10FCB000A04000BD8F82001403E00008A44000BEF5 -:10FCC0008F8A001427BDFFE0AFB10014AFB0001061 -:10FCD0008F88003CAFBF00189389001C954200E458 -:10FCE00030D100FF0109182B0080802130AC00FFCB -:10FCF0003047FFFF0000582114600003310600FF69 -:10FD000001203021010958239783003A0068102B05 -:10FD10001440003C000000001468000724020001A9 -:10FD20008E0200202403FFFB34E7800000431024F0 -:10FD3000AE0200202402000134E70880158200058D -:10FD40003165FFFF0E001554020020210A001691B4 -:10FD5000020020210E001585020020218F8400481A -:10FD6000274301808F4201B80440FFFE240200189F -:10FD7000AC640000A062000B8F840014948200E643 -:10FD8000A46200103C021000AC600030AF4201B829 -:10FD90009482006024420001A4820060948200608A -:10FDA0003C0308008C63318830427FFF5443000FCE -:10FDB000020020219482006024038000004310246C -:10FDC000A48200609082006090830060304200FF57 -:10FDD000000211C200021027000211C03063007F30 -:10FDE00000621825A0830060020020210220282143 -:10FDF0008FBF00188FB100148FB000100A0015F9E2 -:10FE000027BD0020914200632403FF80004310259A -:10FE1000A14200639782003A3048FFFF11000020A2 -:10FE20009383001C8F840014004B1023304600FF86 -:10FE3000948300E42402EFFF0168282B0062182459 -:10FE4000A48300E414A000038E02002001005821C6 -:10FE5000000030212403FFFB34E78000004310241E -:10FE6000AE02002024020001158200053165FFFF6B -:10FE70000E001554020020210A0016B99783003A9B -:10FE80000E001585020020219783003A8F82003CE6 -:10FE9000A780003A00431023AF82003C9383001CEC -:10FEA0008F8200148FBF00188FB100148FB0001024 -:10FEB00027BD002003E00008A04300BD938200445A -:10FEC0002403000127BDFFE8004330042C4200203A -:10FED000AFB00010AFBF00142410FFFE10400005AB -:10FEE000274501803C0208008C4231900A0016D65A -:10FEF000004610243C0208008C4231940046102435 -:10FF000014400007240600848F8300142410FFFF90 -:10FF1000906200623042000F34420040A0620062F2 -:10FF20000E0015D600000000020010218FBF001443 -:10FF30008FB0001003E0000827BD00188F83002455 -:10FF400027BDFFE0AFB20018AFB10014AFB0001092 -:10FF5000AFBF001C9062000D00A0902130D100FFC7 -:10FF60003042007FA062000D8F8500148E43001880 -:10FF7000008080218CA2007C146200052402000E07 -:10FF800090A20063344200200A0016FFA0A2006382 -:10FF90000E0016C5A38200442403FFFF1043004750 -:10FFA0002404FFFF52200045000020218E43000062 -:10FFB0003C02001000621024504000043C02000883 -:10FFC000020020210A00170E2402001500621024EE -:10FFD000504000098E450000020020212402001438 -:10FFE0000E0016C5A38200442403FFFF1043003314 -:10FFF0002404FFFF8E4500003C02000200A21024F2 -:020000040001F9 -:10000000104000163C0200048F8600248CC20014AD -:100010008CC300108CC40014004310230044102B28 -:1000200050400005020020218E43002C8CC200109D -:1000300010620003020020210A00173F2402001270 -:100040003C02000400A210245040001C00002021AB -:10005000020020210A00173F2402001300A21024EE -:10006000104000068F8300248C6200105040001363 -:10007000000020210A001739020020218C620010A4 -:10008000504000048E42002C020020210A00173F3D -:10009000240200115040000900002021020020210C -:1000A000240200170E0016C5A38200442403FFFF9C -:1000B000104300022404FFFF000020218FBF001C1A -:1000C0008FB200188FB100148FB000100080102183 -:1000D00003E0000827BD00208F83001427BDFFD850 -:1000E000AFB40020AFB3001CAFB20018AFB1001422 -:1000F000AFB00010AFBF0024906200638F91002C5E -:100100002412FFFF3442004092250000A0620063E9 -:100110008E2200100080982130B0003F105200065F -:100120000360A0212402000D0E0016C5A382004426 -:10013000105200542404FFFF8F8300148E220018F5 -:100140008C63007C10430007026020212402000E13 -:100150000E0016C5A38200442403FFFF104300498C -:100160002404FFFF24040020120400048F830014E1 -:100170009062006334420020A06200638F850034E7 -:1001800010A0002000000000560400048F8200141C -:10019000026020210A0017902402000A9683000AB8 -:1001A000944200603042FFFF144300048F8200201D -:1001B0002404FFFD0A0017B7AF82003C3C02080090 -:1001C0008C42318C0045102B144000060260202127 -:1001D000000028210E001646240600010A0017B769 -:1001E000000020212402002D0E0016C5A382004429 -:1001F0002403FFFF104300232404FFFF0A0017B766 -:1002000000002021160400058F8400148E230014A2 -:100210002402FFFF506200180260202194820060D7 -:1002200024420001A4820060948200603C03080024 -:100230008C63318830427FFF5443000F02602021DD -:10024000948200602403800000431024A482006094 -:100250009082006090830060304200FF000211C273 -:1002600000021027000211C03063007F00621825D1 -:10027000A0830060026020210E0015F92405000112 -:10028000000020218FBF00248FB400208FB3001CFA -:100290008FB200188FB100148FB0001000801021B1 -:1002A00003E0000827BD00288F83001427BDFFE866 -:1002B000AFB00010AFBF0014906200638F87002CB6 -:1002C00000808021344200408CE60010A062006370 -:1002D0003C0308008C6331B030C23FFF0043102B59 -:1002E0001040004E8F8500302402FF8090A3000D47 -:1002F00000431024304200FF5040004902002021FA -:100300000006138230480003240200025502004414 -:100310000200202194A2001C8F85001424030023D6 -:10032000A4A201148CE60000000616023042003F31 -:10033000104300103C0300838CE300188CA2007C67 -:10034000106200062402000E0E0016C5A3820044AF -:100350002403FFFF104300382404FFFF8F830014A1 -:100360009062006334420020A06200630A0017FC20 -:100370008F83002400C31024144300078F830024BC -:1003800090A200623042000F34420020A0A200621E -:10039000A38800388F8300249062000D3042007FD4 -:1003A000A062000D8F83003410600018020020212D -:1003B0008F8400308C8200100043102B1040000905 -:1003C00024020018020020210E0016C5A38200445A -:1003D0002403FFFF104300182404FFFF0A00182421 -:1003E000000020218C820010240500010200202141 -:1003F000004310238F830024240600010E001646BC -:10040000AC6200100A001824000020210E0015F92B -:10041000240500010A0018240000202102002021E8 -:100420002402000D8FBF00148FB0001027BD0018EC -:100430000A0016C5A38200448FBF00148FB00010BD -:100440000080102103E0000827BD001827BDFFC869 -:10045000AFB20020AFBF0034AFB60030AFB5002C54 -:10046000AFB40028AFB30024AFB1001CAFB0001888 -:100470008F4601283C0308008C6331A02402FF80D2 -:10048000AF86004800C318213065007F034528214E -:10049000006218243C02000AAF43002400A2282175 -:1004A00090A2006200809021AF850014304200FFCE -:1004B00000021102A382003890A200BC3042000268 -:1004C0001440000224030034240300308F820014FF -:1004D000A3830028938300388C4200C0A38000448B -:1004E000AF82003C24020004106203148F84003C9D -:1004F0008E440004508003118F84003C8E42001013 -:100500003083FFFFA784003A106002F7AF820040FB -:100510008F8400142403FF80908200630062102403 -:10052000304200FF144002C79785003A9383003899 -:100530002402000230B6FFFF14620005000088218B -:10054000938200282403FFFD0A001B11AF82003CA8 -:100550008F82003C02C2102B144002998F8400400D -:100560000E0014EC00000000938300283C040800F7 -:1005700024847778240200341462002EAF84002C87 -:100580003C0A08008D4A77A82402FFFFAFA20010A2 -:10059000008038212405002F3C09080025297378A4 -:1005A000240800FF2406FFFF90E2000024A3FFFFC1 -:1005B0000006220200C21026304200FF0002108016 -:1005C000004910218C420000306500FF24E7000143 -:1005D00014A8FFF50082302600061027AFA20014F1 -:1005E000AFA200100000282127A7001027A60014A2 -:1005F00000C510239044000324A2000100A7182185 -:10060000304500FF2CA200041440FFF9A064000054 -:100610008FA2001011420007240200050240202191 -:100620000E0016C5A38200442403FFFF104300649C -:100630002404FFFF3C0208009042777C1040000930 -:100640008F820014024020212402000C0E0016C5E7 -:10065000A38200442403FFFF104300592404FFFF3A -:100660008F820014A380001C3C0308008C63777CFD -:100670008C4400803C0200FF3442FFFF00621824DB -:100680000083202B10800008AF830034024020211B -:10069000240200190E0016C5A38200442403FFFFA4 -:1006A000104300472404FFFF8F87003C9782003AE5 -:1006B0008F850034AF8700200047202310A0003B27 -:1006C000A784003A8F86001430A200030002102392 -:1006D00090C300BC3050000300B0282100031882F2 -:1006E000307300010013108000A228213C03080091 -:1006F0008C6331A08F8200483084FFFF0085202B5F -:100700000043102110800011244200888F84002CA7 -:100710001082000E3C033F013C0208008C427778B7 -:10072000004310243C0325001443000630E500FF7D -:100730008C820000ACC200888C8200100A0018E98C -:10074000ACC200980E001529000030219382001CD5 -:100750008F8500148F830040020238218F82003C75 -:10076000A387001C94A400E4006218218F82003447 -:1007700034841000AF83004000503021A4A400E472 -:100780001260000EAF86003C24E20004A382001C2D -:1007900094A200E424C30004AF83003C3442200050 -:1007A000A4A200E40A001906000020218F82004064 -:1007B000AF80003C00471021AF82004000002021A4 -:1007C0002414FFFF109402092403FFFF3C080800D3 -:1007D0008D0877883C0208008C4231B03C03080049 -:1007E0009063777831043FFF0082102B1040001B8C -:1007F0003067003F3C0208008C4231A88F830048DC -:100800000004218000621821006418213062007FFA -:10081000034228213C02000C00A228213C02008057 -:10082000344200013066007800C230252402FF8087 -:1008300000621024AF42002830640007AF42080471 -:100840008F8200140344202124840940AF460814F9 -:10085000AF850024AF840030AC4301189383003887 -:1008600024020003146201C72402000124020026AE -:1008700010E201C928E200271040001324020032D0 -:100880002402002210E201C428E2002310400008E4 -:10089000240200242402002010E201B024020021DE -:1008A00010E2013F024020210A001AF32402000B4B -:1008B00010E201B92402002510E2001002402021BC -:1008C0000A001AF32402000B10E201A628E200330A -:1008D000104000062402003F2402003110E2009282 -:1008E000024020210A001AF32402000B10E2019DAD -:1008F000024020210A001AF32402000B8F90002CE2 -:100900003C0308008C6331B08F8500308E040010EA -:100910000000A8218CB3001430823FFF0043102B4D -:100920008CB10020504001870240202190A3000D8F -:100930002402FF8000431024304200FF5040018118 -:100940000240202100041382304200031440017D44 -:100950000240202194A3001C8F8200148E040028E2 -:10096000A44301148CA20010026218231064000337 -:10097000024020210A00197C2402001F8F820034CB -:10098000006210210262102B104000088F830024A7 -:1009900002402021240200180E0016C5A382004444 -:1009A0001054016C2404FFFF8F8300248F840034D3 -:1009B0008C6200100224882100441023AC620010D5 -:1009C0008F820014AC7100208C4200680051102B03 -:1009D000104000098F830030024020212402001DB6 -:1009E0000E0016C5A38200442403FFFF10430159E3 -:1009F0002404FFFF8F8300308E0200248C630024C8 -:100A000010430007024020212402001C0E0016C5DE -:100A1000A38200442403FFFF1043014E2404FFFF80 -:100A20008F8400248C82002424420001AC820024A4 -:100A3000123300048F8200148C4200685622000E8C -:100A40008E0200008E0200003C0300800043102450 -:100A50001440000D2402001A024020210E0016C589 -:100A6000A38200442403FFFF1043013A2404FFFF44 -:100A70000A0019BA8E0200143C03008000431024BF -:100A8000504000038E020014AC8000208E0200143F -:100A90002411FFFF105100062402001B02402021F8 -:100AA0000E0016C5A38200441051012A2404FFFF42 -:100AB0008E0300003C02000100621024104000126E -:100AC0003C020080006210241440000802402021F3 -:100AD0002402001A0E0016C5A38200442403FFFF5F -:100AE0001043011C2404FFFF0240202102002821A2 -:100AF0000E0016E5240600012403FFFF1043011534 -:100B00002404FFFF241500018F83002402A030215C -:100B10000240202194620036240500012442000195 -:100B20000A001AD7A46200368F90002C3C030800FC -:100B30008C6331B08E13001032623FFF0043102BE4 -:100B4000104000898F8400302402FF809083000DC4 -:100B500000431024304200FF104000842402000DA6 -:100B60000013138230420003240300011443007F6A -:100B70002402000D9082000D304200085440000411 -:100B80008F820034024020210A001A082402002427 -:100B9000504000048E03000C024020210A001A0875 -:100BA000240200278C82002054620006024020218B -:100BB0008E0300088C820024506200098E0200140B -:100BC00002402021240200200E0016C5A38200440A -:100BD000105400712403FFFF0A001A3D8F84002483 -:100BE0002411FFFF145100048F86001402402021BD -:100BF0000A001A38240200258E0300188CC2007CDB -:100C0000106200032402000E0A001A38024020215C -:100C10008E0300248C82002810620003240200212D -:100C20000A001A38024020218E0500288C82002CF0 -:100C300010A200032402001F0A001A3802402021DB -:100C40008E03002C14600003240200230A001A38CB -:100C5000024020218CC200680043102B104000038A -:100C6000240200260A001A38024020218C82001437 -:100C7000006518210043102B104000088F840024C9 -:100C800002402021240200220E0016C5A382004447 -:100C9000105100412403FFFF8F8400242403FFF739 -:100CA0009082000D00431024A082000D8F86001456 -:100CB0003C0308008C6331AC8F82004894C400E090 -:100CC0008F8500240043102130847FFF00042040E2 -:100CD000004410213043007F034320213C03000ED9 -:100CE000008320212403FF8000431024AF42002C06 -:100CF000A49300008CA2002824420001ACA200288A -:100D00008CA2002C8E03002C00431021ACA2002CDE -:100D10008E02002CACA200308E020014ACA2003473 -:100D200094A2003A24420001A4A2003A94C600E032 -:100D30003C0208008C4231B024C4000130837FFFA4 -:100D40001462000F008030212402800000823024D1 -:100D500030C2FFFF000213C2304200FF0002102722 -:100D60000A001A76000233C02402000D024020213E -:100D70000E0016C5A38200440A001A7C0040182108 -:100D80008F82001402402021240500010E0015F975 -:100D9000A44600E0000018210A001B0E0060882114 -:100DA0008F90002C3C0308008C6331B08E0500103E -:100DB00030A23FFF0043102B104000612402FF804F -:100DC0008F8400309083000D00431024304200FFD8 -:100DD0005040005C024020218F8200341040000B04 -:100DE000000513828F8200149763000A944200600A -:100DF0003042FFFF14430005000513828F8200205C -:100E00002404FFFD0A001AEBAF82003C30420003CD -:100E10001440000E00000000920200021040000585 -:100E20008E03002450600015920300030A001AA7E5 -:100E3000024020218C8200245062001092030003A3 -:100E4000024020210A001AAF2402000F9082000DF8 -:100E50003042000854400009920300030240202160 -:100E6000240200100E0016C5A38200442403FFFFD5 -:100E7000104300382404FFFF920300032402000201 -:100E80005462000C920200038F8200345440000927 -:100E900092020003024020212402002C0E0016C5FD -:100EA000A38200442403FFFF1043002A2404FFFF11 -:100EB000920200030200282102402021384600103F -:100EC0002CC600012C4200010E0016E5004630251C -:100ED0002410FFFF1050001F2404FFFF8F830034F5 -:100EE00010600013024020213C0208008C42318C2B -:100EF0000043102B144000070000000000002821D0 -:100F0000240600010E001646000000000A001AEB3D -:100F1000000020212402002D0E0016C5A3820044EB -:100F20001050000C2404FFFF0A001AEB00002021DF -:100F30000E0015F9240500010A001AEB000020211B -:100F4000024020212402000D0E0016C5A382004499 -:100F5000004020210A001B0E008088211514000E7D -:100F6000000000000E00174C024020210A001B0E5A -:100F7000004088210E0016C5A38200440A001B0E03 -:100F80000040882114620017022018212402002347 -:100F900014E200052402000B0E0017C002402021BD -:100FA0000A001B0E0040882102402021A382004439 -:100FB0000E0016C52411FFFF0A001B0F0220182186 -:100FC00030A500FF0E001529240600019783003A82 -:100FD0008F82003CA780003A00431023AF82003C80 -:100FE000022018211220003E9782003A2402FFFDC1 -:100FF0005462003E8E4300208E4200048F83001412 -:1010000000561023AE420004906200633042007F1D -:10101000A06200638E4200208F840014A780003AF3 -:1010200034420002AE420020A48000E490820063BB -:101030002403FFBF00431024A08200630A001B5159 -:101040008E4300209082006300621024304200FF33 -:10105000104000239782003A90820088908300BD60 -:10106000248500883042003F2444FFE02C82002089 -:10107000A383001C10400019AF85002C240200013E -:1010800000821804306200191440000C3C028000F9 -:1010900034420002006210241440000B3062002031 -:1010A0001040000F9782003A90A6000102402021D4 -:1010B000240500010A001B4B30C60001024020211C -:1010C0000A001B4A240500010240202100002821BB -:1010D000240600010E001646000000009782003A28 -:1010E0001440FD0C8F8400148E43002030620004F5 -:1010F000104000128F84003C2402FFFB0062102489 -:10110000AE420020274301808F4201B80440FFFE19 -:101110008F820048AC6200008F420124AC62000460 -:1011200024026083A462000824020002A062000B73 -:101130003C021000AF4201B88F84003C8F83001442 -:101140008FBF00348FB600308FB5002C8FB40028CD -:101150008FB300248FB200208FB1001C8FB0001815 -:101160002402000127BD003803E00008AC6400C081 -:1011700030A500FF2403000124A900010069102B01 -:101180001040000C00004021240A000100A310239D -:10119000004A380424630001308200010069302BCA -:1011A00010400002000420420107402554C0FFF80F -:1011B00000A3102303E00008010010213C020800F6 -:1011C000244260A43C010800AC22736C3C0208007D -:1011D000244253083C010800AC227370240200062C -:1011E00027BDFFE03C010800A02273743C021EDC16 -:1011F000AFB20018AFB10014AFBF001CAFB0001009 -:1012000034526F4100008821240500080E001B7233 -:1012100002202021001180803C07080024E7737819 -:101220000002160002071821AC620000000028210D -:1012300024A200013045FFFF8C6200002CA60008AC -:1012400004410002000220400092202614C0FFF852 -:10125000AC640000020780218E0400000E001B72A7 -:1012600024050020262300013071FFFF2E230100FA -:101270001460FFE5AE0200008FBF001C8FB20018A3 -:101280008FB100148FB0001003E0000827BD0020CC -:1012900027BDFFD8AFB3001CAFB20018AFBF00200E -:1012A000AFB10014AFB000108F5101408F4801481A -:1012B00000089402324300FF311300FF8F4201B84F -:1012C0000440FFFE27500180AE1100008F42014410 -:1012D000AE02000424020002A6120008A202000BC3 -:1012E00024020014AE1300241062002528620015A9 -:1012F0001040000824020015240200101062003083 -:1013000024020012106200098FBF00200A001CADE9 -:101310008FB3001C1062007024020022106200379C -:101320008FBF00200A001CAD8FB3001C3C020800D8 -:101330008C4231A02403FF8002221021004310249C -:10134000AF4200243C0208008C4231A0022210214E -:101350003042007F034218213C02000A006218213B -:10136000166000BCAF830014906200623042000F30 -:1013700034420030A06200620A001CAC8FBF002023 -:101380003C0460008C832C083C02F0033442FFFFD5 -:1013900000621824AC832C083C0208008C4231A067 -:1013A0008C832C08244200740002108200021480F6 -:1013B00000621825AC832C080A001CAC8FBF0020EB -:1013C0003C0208008C4231A02403FF80022210213D -:1013D00000431024AF4200243C0208008C4231A09C -:1013E0003C03000A022210213042007F03421021F8 -:1013F000004310210A001CABAF8200143C0208001D -:101400008C4231A02405FF800222102100451024C7 -:10141000AF4200243C0208008C4231A0022210217D -:101420003042007F034218213C02000A006218216A -:101430009062006300A21024304200FF104000853B -:10144000AF83001424620088944300123C02080019 -:101450008C4231A830633FFF000319800222102123 -:10146000004310213043007F034320210045102416 -:101470003C03000C00832021AF4200289082000D25 -:1014800000A21024304200FF10400072AF840024FC -:101490009082000D304200101440006F8FBF00207A -:1014A0000E0015C8000000008F4201B80440FFFE86 -:1014B00000000000AE1100008F420144AE020004A3 -:1014C00024020002A6120008A202000BAE130024A0 -:1014D0000A001CAC8FBF00202406FF8002261024C7 -:1014E000AF4200203C0208008C4231A031043FFF93 -:1014F000000421800222102100461024AF42002463 -:101500003C0308008C6331A83C0208008C4231A0E7 -:101510003227007F022318210222102100641821A3 -:101520003042007F3064007F034228213C02000AE1 -:101530000066182400A22821034420213C02000C4C -:1015400000822021AF4300283C02000803471821F5 -:1015500000629021AF850014AF8400240E0015C8EE -:10156000010080218F4201B80440FFFE8F820024D9 -:101570008F840014274501809042000DACB100001B -:10158000A4B0000600021600000216030002102795 -:10159000000237C214C00016248200889442001250 -:1015A00032033FFF30423FFF1443001224026082A7 -:1015B000908300632402FF8000431024304200FF28 -:1015C0005040000C24026082908200623042000F82 -:1015D00034420040A082006224026084A4A2000879 -:1015E0002402000DA0A200050A001C963C02270060 -:1015F00024026082A4A20008A0A000053C022700EB -:1016000000061C000062182524020002A0A2000BA4 -:10161000ACA30010ACA00014ACA00024ACA0002827 -:10162000ACA0002C8E42004C8F840024ACA2001889 -:101630009083000D2402FF8000431024304200FFFD -:10164000104000058FBF00209082000D3042007FC7 -:10165000A082000D8FBF00208FB3001C8FB2001836 -:101660008FB100148FB000103C02100027BD00287D -:0816700003E00008AF4201B8DD -:08167800080034300800343092 -:10168000080033A8080033E0080034140800343898 -:0C16900008003438080034380800331813 -:04169C000A0001241B -:1016A00000000000000000000000000D74706136B2 -:1016B0002E302E313500000006000F010000000022 -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300010000003000000000000000D0000000D7C -:101740003C02080024421C003C030800246320944F -:10175000AC4000000043202B1480FFFD2442000415 -:101760003C1D080037BD2FFC03A0F0213C100800F1 -:10177000261004903C1C0800279C1C000E00015CF5 -:10178000000000000000000D3084FFFF30820007E1 -:101790008F85001810400002248300073064FFF892 -:1017A0000085302130C41FFF03441821247B4000F2 -:1017B000AF85001CAF84001803E00008AF4400842C -:1017C0003084FFFF308200078F8500208F8600283D -:1017D00010400002248300073064FFF800852021B8 -:1017E0000086182B14600002AF8500240086202399 -:1017F0000344282134068000AF840020AF440080D9 -:1018000000A6202103E00008AF84003827BDFFD8E0 -:10181000AFB3001CAFB20018AFB00010AFBF0024D0 -:10182000AFB40020AFB100143C0860088D14500024 -:101830002418FF7F3C1A8000029898243672380CD6 -:10184000AD1250008F5100083C07601C3C0860003E -:1018500036300001AF500008AF800018AF40008064 -:10186000AF4000848CE600088D0F08083C07601626 -:101870008CEC000031EEFFF039CA00103C0DFFFF88 -:10188000340B80003C030080034B48212D440001B1 -:10189000018D28243C0253533C010800AC23042052 -:1018A000AF890038AF860028AF840010275B400066 -:1018B00014A2000334E37C008CF9000403281821EF -:1018C0008C7F007C8C6500783C0280003C0B08001B -:1018D0008D6B048C3C0A08008D4A048834520070D9 -:1018E000AF85003CAF9F00403C13080026731C44AA -:1018F0000240A0218E4800008F46000038C300013E -:101900003064000110800017AF8800340280482145 -:101910008D2F00003C0508008CA5045C3C180800D5 -:101920008F18045801E8102300A280210000C8216C -:101930000202402B03198821022838213C010800AB -:10194000AC30045C3C010800AC2704588F4E00000A -:1019500039CD000131AC00011580FFED01E04021DF -:10196000AF8F00348E5100003C0708008CE7045C08 -:101970003C0D08008DAD04580228802300F0602142 -:10198000000070210190302B01AE1821006620214B -:101990003C010800AC2C045C3C010800AC24045859 -:1019A0008F4601088F47010030C92000AF86000034 -:1019B000AF87000C1120000A00C040213C1808002D -:1019C0008F18042C270800013C010800AC28042CC7 -:1019D0003C184000AF5801380A0001960000000092 -:1019E0009749010400002821014550213122FFFFC1 -:1019F000016258210162F82B015F502130D90200A9 -:101A00003C010800AC2B048C3C010800AC2A048883 -:101A10001720001524040F0010E40013000000003C -:101A200024080D0010E8023B30CD000611A0FFE9AC -:101A30003C184000936E00002409001031C400F0EF -:101A40001089027124020070108202E58F88001450 -:101A5000250F0001AF8F00143C184000AF5801382B -:101A60000A00019600000000974C01041180FFD984 -:101A70003C18400030C34000146000A1000000008A -:101A80008F46017804C0FFFE8F87003824100800BD -:101A9000240F00088CE30008AF500178A74F0140E5 -:101AA000A7400142974E01048F86000031C9FFFF15 -:101AB00030CD000111A002E1012040212531FFFEBF -:101AC00024180002A75801463228FFFFA7510148F9 -:101AD0003C1908008F39043C172002D08F8C000C71 -:101AE00030DF002017E00002240400092404000174 -:101AF00030C20C0024050400504500013484000469 -:101B0000A744014A3C1108008E3104203C180048CB -:101B10003C1000010238182530CF00020070282543 -:101B200011E00004000018213C19010000B928252B -:101B30002403000130DF000453E00005AF830008F8 -:101B40003C06001000A6282524030001AF830008EE -:101B5000AF45100000000000000000000000000081 -:101B6000000000008F8300081060002300000000C8 -:101B70008F45100004A1FFFE000000001060001E51 -:101B8000000000008F4410003C0C0020008C10244A -:101B9000104000198F8E000031CD000211A00016F8 -:101BA00000000000974F101415E000130000000023 -:101BB000975910083338FFFF2711000600111882CB -:101BC0000003308000C72821323000013223000397 -:101BD0001200032C8CA200000000000D00C7F821A9 -:101BE000AFE200003C0508008CA5043024A60001EB -:101BF0003C010800AC2604308F6D00003402FFFF6A -:101C0000AF8D00048CEC0000118202A600002021A0 -:101C10008CED000031AC01001180028A0000000050 -:101C20003C0208008C4204743C0308008C63044CA2 -:101C30003C1F08008FFF04703C1808008F180448F0 -:101C4000004838210068802100E8282B03E4302177 -:101C50000208402B0304882100C570210228782146 -:101C60003C010800AC30044C3C010800AC2F044897 -:101C70003C010800AC2704743C010800AC2E047041 -:101C80008F8400180120302131290007249F00088B -:101C900033F91FFF03594021AF84001CAF9900188E -:101CA000251B4000AF590084112000038F830020C2 -:101CB00024C200073046FFF88F84002800C3282183 -:101CC00000A4302B14C00002AF83002400A42823FA -:101CD00003456021340D8000018D10213C0F100060 -:101CE000AF850020AF820038AF450080AF4F01784C -:101CF0008F880014250F00010A0001EFAF8F001438 -:101D00008F6200088F67000024050030000776020C -:101D100031C300F0106500A7240F0040546FFF4C42 -:101D20008F8800148F4B01780560FFFE00000000D3 -:101D300030CA020015400003000612820000000DA8 -:101D400000061282304D0003000D4900012D1821BC -:101D500000038080020D40210008608001938021F3 -:101D60008E1F000017E00002000000000000000DC0 -:101D70008F6E000405C202BD92070006920E000598 -:101D8000920200043C090001000E18800070F82146 -:101D90008FED0018277100082448000501A9602173 -:101DA00000083082AFEC0018022020210E00059EB2 -:101DB00026050014920A00068F7900043C0B7FFF71 -:101DC000000A2080009178218DF800043566FFFF1D -:101DD0000326282403053821ADE70004920E0005F0 -:101DE000920D0004960C0008000E10800051C821CE -:101DF0008F230000974901043C07FFFF0067582428 -:101E00003128FFFF010DF82103EC50233144FFFF7F -:101E100001643025AF26000092030007241800015A -:101E200010780275240F0003106F02850000000077 -:101E30008E0500102419000AA7590140A745014248 -:101E4000921800048F860000240F0001A758014457 -:101E5000A74001469747010430D100023C050041EC -:101E6000A747014800001821A74F014A122000038C -:101E700030CB00043C050141240300015160000502 -:101E8000AF8300083C06001000A6282524030001AB -:101E9000AF830008AF451000000000000000000004 -:101EA00000000000000000008F8A000811400004BC -:101EB000000000008F4410000481FFFE00000000BD -:101EC0008F6B0000920800043C1108008E3104441E -:101ED000AF8B000497590104311800FF3C0E080035 -:101EE0008DCE04403325FFFF0305382102276021F2 -:101EF00000001021250F000A31E8FFFF0187482B61 -:101F000001C2682101A9F821311000073C01080035 -:101F1000AC2C04443C010800AC3F04401200000318 -:101F20008F8C00182506000730C8FFF8010C6821C7 -:101F300031BF1FFFAF8C001CAF9F0018AF5F008444 -:101F400097440104035F80213084FFFF308A00073B -:101F500011400003261B4000248900073124FFF8AC -:101F60008F8200208F850028008220210085702B21 -:101F700015C00002AF820024008520233C0B08001E -:101F80008D6B048C3C0A08008D4A04880344882128 -:101F900034038000022310213C0F1000AF84002086 -:101FA000AF820038AF440080AF4F01780A0002963C -:101FB0008F8800148F5001780600FFFE30D1020098 -:101FC00016200003000612820000000D0006128297 -:101FD000305F0003001F1900007F302100062080C1 -:101FE000009FC82100194880013380218E1800000D -:101FF00013000002000000000000000D8F6C000CB8 -:10200000058001FB8F870038240E0001AE0E000012 -:102010008CE30008A20000078F650004000554024D -:10202000314D00FF25A80005000830822CCB00416F -:1020300015600002A20A00040000000D8F78000461 -:102040003C03FFFF00E02821330BFFFF256C000B52 -:10205000000C108200022080008748218D3F000084 -:1020600026040014A618000803E3C8240E00059EE9 -:10207000AD3900008F4F01083C11100001F13824E8 -:1020800010E001AB00000000974D0104920800072A -:1020900025AAFFEC350600023144FFFFA206000727 -:1020A000960600082CC7001354E0000592030007B1 -:1020B00092110007362F0001A20F000792030007BC -:1020C00024180001107801C224090003106901D509 -:1020D0008F88003830CBFFFF257100020011788314 -:1020E00031E400FF00042880A20F000500A8482169 -:1020F0008D2D0000974A01043C0EFFFF01AEF8242D -:102100003143FFFF006B1023244CFFFE03ECC82576 -:10211000AD390000920600053C03FFF63462FFFF74 -:1021200030D800FF0018388000F08821922F00146A -:102130003C04FF7F3487FFFF31EE000F01C65821BA -:10214000316500FF00055080015068218DAC0020F2 -:102150000148F821A20B00060182C824AE0C000C35 -:10216000AFF9000C920900068E11000C03277824A9 -:102170000009C0800310702195C60026030828219D -:1021800002272024AE04000CADCF0020ADC60024F1 -:10219000ACA600108F8800003C0B08008D6B048CEF -:1021A0003C0A08008D4A0488241F001024190002EC -:1021B000A75F0140A7400142A7400144A75901463B -:1021C0009749010424070001310600022538FFFE6B -:1021D000A75801483C050009A747014A10C0000361 -:1021E000000018213C05010924030001310C000402 -:1021F00051800005AF8300083C08001000A8282586 -:1022000024030001AF830008AF4510000000000068 -:102210000000000000000000000000009205000423 -:1022200024AE000231CD0007000D182330620007F4 -:10223000AE0200108F9000081200000400000000A1 -:102240008F4F100005E1FFFE000000008F710000BD -:102250008F8E00183C0308008C630444AF91000487 -:102260009745010425CF001031E61FFF30A2FFFF84 -:10227000AF8E001CAF860018AF4600842449FFFED5 -:102280003C0C08008D8C0440974D010401208021F6 -:10229000000947C30070C02131A9FFFF0310F82BCC -:1022A0000188C821033F202103463821313100072E -:1022B0003C010800AC3804443C010800AC24044054 -:1022C0001220000324FB40002527000730E9FFF817 -:1022D0008F8600208F8400280126382100E4C02B3F -:1022E00017000002AF86002400E4382303472021B2 -:1022F00034198000009910213C0F1000AF87002096 -:10230000AF820038AF470080AF4F01780A000296D5 -:102310008F8800149747010410E0FDAE3C18400080 -:102320008F5801780700FFFE30C5400010A0000361 -:102330003C1F00080000000D3C1F0008AF5F01407B -:10234000241008008F860000AF50017897440104E4 -:1023500030D90001132000ED3086FFFF24CCFFFEB2 -:10236000240D0002A74D0146A74C01488F9100188B -:102370002408000DA748014A8F630000262F00089B -:1023800031E21FFF0342702130C90007AF83000410 -:10239000AF91001CAF82001800C03821AF4200840A -:1023A0001120000325DB400024D800073307FFF885 -:1023B0008F8500208F84002800E5302100C4382B51 -:1023C00014E00002AF85002400C430238F84001481 -:1023D0000346F821340C8000AF86002003EC8021F6 -:1023E000AF460080249900013C0610003C184000D4 -:1023F000AF460178AF900038AF990014AF5801385C -:102400000A000196000000008F630000975101044C -:102410003067FFFF3228FFFF8F4F017805E0FFFE96 -:1024200030EC0007000CF82333F0000724F9FFFE1E -:102430002404000AA7440140A7500142A7590144BF -:10244000A7400146A74801488F45010830B8002041 -:1024500017000002240300092403000130CD00020C -:10246000A743014A3C04004111A0000300001821C9 -:102470003C0401412403000130C90004512000053F -:10248000AF8300083C0600100086202524030001CD -:10249000AF830008AF4410000000000000000000FF -:1024A00000000000000000008F8E000811C0000432 -:1024B000000000008F4210000441FFFE00000000F9 -:1024C0008F7F0000276400088F91003CAF9F0004BD -:1024D000948500089490000A9499000C30AFFFFF97 -:1024E0000010C4003323FFFF11F100A603032025D1 -:1024F0003C0E08008DCE04443C0C08008D8C04403A -:1025000000E888212626FFFE01C628210000682158 -:1025100000A6F82B018D2021009F80213C0108009E -:10252000AC2504443C010800AC30044024E200081F -:102530003042FFFF3047000710E000038F83001890 -:10254000244F000731E2FFF83106FFFF30C80007D3 -:102550000043802132191FFF0359C021AF83001CA3 -:10256000AF990018271B4000AF59008411000003E9 -:102570008F8C002024C5000730A6FFF88F84002828 -:1025800000CC282100A4F82B17E00002AF8C002417 -:1025900000A42823AF850020AF4500803C0408003C -:1025A0008C84043403454821340E8000012E6821B8 -:1025B00010800005AF8D0038939100172406000E9F -:1025C000122600112407043F3C021000AF4201789C -:1025D0008F880014250F00010A0001EFAF8F00144F -:1025E0000E0005C400E020218F8800143C0B080079 -:1025F0008D6B048C3C0A08008D4A0488250F00016D -:102600000A0001EFAF8F00143C021000A7470148F9 -:10261000AF4201780A0004CE8F88001424040F0012 -:102620001184003D30CE002015C0000224030009B3 -:10263000240300010A00021AA743014A0A00020DFE -:10264000A740014694EF000894F1000A94F0000CB2 -:102650008F8C003C001174003207FFFF31EDFFFF4B -:1026600011AC003701C720253C1808008F1804441E -:102670003C0F08008DEF0440000080210308682112 -:1026800001A8382B01F0702101C760213C0108002E -:10269000AC2D04443C010800AC2C04400A00027A32 -:1026A0008F8400183C0208008C42047C3C03080024 -:1026B0008C6304543C1F08008FFF04783C1808000A -:1026C0008F180450004838210068802100E8282B2A -:1026D00003E430210208402B0304882100C5702147 -:1026E000022878213C010800AC3004543C01080069 -:1026F000AC2F04503C010800AC27047C3C010800CE -:10270000AC2E04780A00027A8F840018A740014694 -:102710000A0004358F91001830CD002015A0FFC5A8 -:102720002403000D240300050A00021AA743014AEE -:10273000974E010425C5FFF00A00038130A4FFFF76 -:102740008F9800401498FFC8000010213C05080035 -:102750008CA5046C3C1F08008FFF046800A8C821EA -:102760000328302B03E22021008640213C01080091 -:10277000AC39046C3C010800AC2804680A00027AF9 -:102780008F8400188F8C0040148CFF5900E8C821FA -:102790003C1808008F18046C3C1108008E31046846 -:1027A0002723FFFE03034821000010210123302BC3 -:1027B0000222702101C668213C010800AC29046C8A -:1027C0003C010800AC2D04680A0004A524E20008BE -:1027D0008F8800383C03FFFF8D02000C0043F82473 -:1027E00003E4C825AD19000C0A00038F30CBFFFFAE -:1027F0000A0003C3AE000000974A010492040004DB -:102800008E26000C014458212579FFF200C7C02410 -:102810003325FFFF03053825AE27000C0A0002E62A -:102820008E0500103C0DFFFF8D0A0010014D58244D -:1028300001646025AD0C00100A00038F30CBFFFF50 -:1028400097430104920E00048E290010006E10219F -:10285000244DFFEE0127602431A8FFFF0188F825F1 -:10286000AE3F00100A0002E68E0500108E0F000C2D -:10287000AE00000000078880023028210A0002B85C -:10288000ACAF00201460000D3058FFFF3C04FFFF88 -:102890000044682401A47026000E602B000D102B4C -:1028A000004CF82413E00002000000000000000DBE -:1028B0008CAF00000A00025001E410253B03FFFF2B -:1028C0000003882B0018802B0211202410800002A6 -:1028D000000000000000000D8CB900000A0002504A -:1028E0003722FFFF3084FFFF30A5FFFF1080000775 -:1028F0000000182130820001104000020004204234 -:10290000006518211480FFFB0005284003E0000843 -:102910000060102110C00007000000008CA2000021 -:1029200024C6FFFF24A50004AC82000014C0FFFBF6 -:102930002484000403E000080000000010A0000848 -:1029400024A3FFFFAC860000000000000000000090 -:102950002402FFFF2463FFFF1462FFFA24840004B3 -:1029600003E0000800000000308EFFFF30D8FFFFBA -:1029700000057C0001F8602539CDFFFF01AC502136 -:10298000014C582B014B4821000944023127FFFF1D -:1029900000E830210006240230C5FFFF00A4182102 -:1029A0003862FFFF03E000083042FFFF3C0C0800E4 -:1029B0008D8C0484240BFF8027BDFFD0018450211F -:1029C000014B4824AF4900203C0808008D080484CE -:1029D000AFB20020AFB00018AFBF0028AFB30024E3 -:1029E000AFB1001C936600040104382130E4007F7D -:1029F000009A10213C0300080043902130C50020BC -:102A0000036080213C080111277B000814A000020C -:102A1000264600702646006C92130004975101046C -:102A2000920F00043267000F322EFFFF31ED00409D -:102A300001C7282311A0000500004821925900BCBD -:102A4000333800041700009000000000924300BCDF -:102A5000307F000413E0000F0000000010A0000D04 -:102A600000000000960E0002240AFF8000A76021EB -:102A700025CDFFFEA74D1016920B0004014B20241C -:102A8000308200FF10400085010C40253C0F0400FF -:102A9000010F40258F5301780660FFFE2404000AD1 -:102AA000A7440140960D00022404000931AC000740 -:102AB000000C5823316A0007A74A0142960200021F -:102AC0002443FFFEA7430144A7400146975F01044A -:102AD000A75F01488F5901083338002053000001D7 -:102AE00024040001920F000431EE001015C0000212 -:102AF0003483001000801821A743014A0000000021 -:102B0000000000000000000000000000AF481000BE -:102B100000000000000000000000000000000000B5 -:102B20008F5110000621FFFE3113FFFF12600003DA -:102B3000000000008F481018ACC800009603000683 -:102B4000307FFFFF27F90002001998820013888068 -:102B5000023B30218CD800001520005700183402A9 -:102B6000920300042405FF8000A3F82433F100FF42 -:102B70001220002C00000000924700BC30F200023E -:102B80001240002800000000974B100C2562FFFE49 -:102B9000A7421016000000003C0A0400354900302E -:102BA000AF4910000000000000000000000000001D -:102BB000000000008F4C10000581FFFE00000000A7 -:102BC0009749100C8F51101C00C020213127FFFFA6 -:102BD00024F20030001218820003288000BBF82184 -:102BE0003226FFFFAFF100000E0005B300112C02EA -:102BF0000013C880033B98218E7800000002740007 -:102C0000AFB800108FA80010310FFFFFAFAF00105A -:102C10008FA4001001C46825AFAD00108FA600106E -:102C2000AE66000097730008976D000A9766000C67 -:102C30008F8A003C000D5C0030CCFFFF3262FFFF4A -:102C4000104A0036016C2025960600023C10100048 -:102C500024D300080E00013B3264FFFF974C0104AF -:102C60000E0001493184FFFFAF5001788FBF00286B -:102C70008FB300248FB200208FB1001C8FB00018DA -:102C800003E0000827BD003010A0FF700000000026 -:102C900024A5FFFC0A0005EC240900048CD10000E7 -:102CA000AF5110188F5301780660FF7A2404000A90 -:102CB0000A0006010000000000A7C8218F88003824 -:102CC0008F4E101C0019C0820018788001E8202166 -:102CD000AC8E0000000E2C0200C020210E0005B3B7 -:102CE00031C6FFFF023B28218CAD000000025400DA -:102CF00000403021AFAD00108FAC0010318BFFFFD2 -:102D0000AFAB00108FA2001001424825AFA9001000 -:102D10008FA700100A000631ACA700008F8F00407B -:102D2000148FFFC90000000097420104960B0002B7 -:102D30003C0508008CA5046C3049FFFF316AFFFF99 -:102D40003C1108008E310468012A382124F2FFFE6C -:102D500000B240210012FFC30112C82B023FC02164 -:102D6000031920213C010800AC28046C3C01080038 -:102D7000AC2404680A00066B0000000000A4102BBD -:102D800010400009240300010005284000A4102B76 -:102D900004A00003000318405440FFFC0005284035 -:102DA00010600007000000000085302B14C00002F6 -:102DB00000031842008520231460FFFB0005284211 -:102DC00003E00008008010218F85002C27BDFFE85C -:102DD000000530272CC300012CA40002008310251D -:102DE00010400003AFBF00102405007FAF85002C0A -:102DF0000005282730A5FFFF0E000592240426F5C4 -:102E00008F830030240402BD004030210083382B22 -:102E100010E0000924050001000420400083102B6D -:102E200004800003000528405440FFFC00042040BB -:102E300010A0000800C350210064402B15000002C0 -:102E4000000528420064182314A0FFFB0004204260 -:102E500000C350218FBF0010000A4C02312200FF36 -:102E600027BD0018AF8A002C03E00008AF890030AE -:102E70000A00002A00000000000000000000000D11 -:102E8000747870362E302E313500000006000F00A9 -:102E900000000000000001360000EA6000000000B1 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000016000000000000000000000000DC -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F00000000000000000000000013880000000026 -:102F1000000005DC000000000000000010000003BD -:102F2000000000000000000D0000000D3C02080041 -:102F300024423C203C03080024633DD4AC40000004 -:102F40000043202B1480FFFD244200043C1D080098 -:102F500037BD7FFC03A0F0213C100800261000A81C -:102F60003C1C0800279C3C200E0002BA0000000018 -:102F70000000000D8F8300383C088000350700708A -:102F80008CE50000008330253C02900000C2202523 -:102F9000AF850030AF4400208F4900200520FFFEA0 -:102FA0003C038000346200708C4500008F86003046 -:102FB0003C1908008F39007C3C0E08008DCE00784B -:102FC00000A6202303245821000078210164682BE7 -:102FD00001CF6021018D50213C010800AC2B007C09 -:102FE0003C010800AC2A007803E000080000000063 -:102FF0000A000041240400018F8400383C05800051 -:1030000034A200010082182503E00008AF4300202D -:1030100003E00008000010213084FFFF30A5FFFF0F -:1030200010800007000018213082000110400002CB -:1030300000042042006518211480FFFB0005284091 -:1030400003E000080060102110C00007000000002D -:103050008CA2000024C6FFFF24A50004AC8200005F -:1030600014C0FFFB2484000403E0000800000000FB -:1030700010A0000824A3FFFFAC86000000000000A1 -:10308000000000002402FFFF2463FFFF1462FFFA28 -:103090002484000403E0000800000000308AFFFFE1 -:1030A00093A80013A74A014497490E1630C600FFA3 -:1030B0003C021000A7490146AF450148A346015212 -:1030C000A748015AAF4701608FA400188FA30014CE -:1030D000A7440158AF43015403E00008AF42017810 -:1030E00003E00008000000003C0380003462007030 -:1030F0008C4900008F8800002484000727BDFFF85A -:103100003084FFF8AF890030974D008A31ACFFFF63 -:10311000AFAC00008FAB0000016850232547FFFFD4 -:1031200030E61FFF00C4282B14A0FFF73C0C8000E2 -:10313000358B00708D6A00003C0708008CE7008426 -:103140003C0608008CC60080000810820149182344 -:103150000002788000E370210000202101C3C82B09 -:1031600000C4C02101FA4021031948212502400072 -:1031700027BD00083C010800AC2E00843C0108007B -:10318000AC29008003E00008000000008F820000EE -:103190002486000730C5FFF800A2182130641FFF05 -:1031A00003E00008AF8400008F8700388F8A00405A -:1031B00027BDFFB88F860044AFB60040AFBF0044C4 -:1031C000AFB5003CAFB40038AFB30034AFB200309D -:1031D000AFB1002CAFB000288F4501048D4900AC81 -:1031E000AF4700808CC8002000A938230000B02120 -:1031F000AF480E108F440E1000004821AF440E144B -:103200008CC20024AF420E188F430E18AF430E1C21 -:1032100010E001252D230001936B0008116000D4FC -:1032200000000000976E001031CDFFFF00ED602B15 -:10323000158000CF0000000097700010320FFFFFD4 -:10324000AF4F0E008F520000325100081220FFFDD8 -:103250000000000097540E088F460E043285FFFFD1 -:1032600030B3000112600132000000000000000DC8 -:1032700030B8A04024150040131500C030A9A000AC -:103280001120012D00000000937F000813E00008CA -:103290000000000097630010306BFFFF00CB402B55 -:1032A0001100000330AC0040118001230000000039 -:1032B000A785003CAF8600349366000800E0282113 -:1032C000AFA7002014C0012427B30020AF60000C7A -:1032D0009782003C3047400014E0000224030016AF -:1032E0002403000E24194007A363000AAF790014D9 -:1032F000938A003E8F740014315800070018AA40CA -:1033000002959025AF7200149784003C8F700014D2 -:103310003091001002117825AF6F0014978E003C99 -:1033200031CD000811A00147000028218F6700144B -:103330003C0210003C0C810000E22825AF6500141F -:1033400097460E0A2408000E3405FFFC30C3FFFF29 -:10335000006C5825AF6B0004A3680002937F000A3D -:1033600027E90004A369000A9786003C9363000ADA -:1033700030CC1F00000C598301634021251F002819 -:10338000A37F000997490E0CA769001093790009E3 -:10339000272A0002315800070018A82332B100077D -:1033A000A371000B93740009976400108F9100348F -:1033B000978F003C329200FF024480210205702169 -:1033C00031ED004011A0000531C4FFFF0091282B12 -:1033D0003C12800010A000140000A0210224382B11 -:1033E00014E0011B8FA500208F4D0E14AF4D0E1061 -:1033F0008F420E1CAF420E18AF440E008F4F0000DC -:1034000031EE000811C0FFFD0000000097540E08C7 -:103410000080882100009021A794003C8F500E046A -:1034200024140001AF900034976400103095FFFF22 -:103430008E6800000111F82317E00009AE7F00003C -:103440008F6500148F8B004434A60040AF660014D3 -:103450008F4C0E10AD6C00208F430E18AD6300240E -:103460009367000814E000D2000000000E00009EE8 -:10347000240400108F8900483C08320000402821B5 -:10348000312600FF0006FC0003E850252539000125 -:10349000AF990048AC4A0000937800099370000A85 -:1034A000330400FF00047400320F00FF01CF6825D1 -:1034B000AC4D00048F820048064000EAACA2000830 -:1034C000ACA0000C9783003C306B00081560000234 -:1034D0002628000626280002974E0E148F450E1C43 -:1034E0008F670004936D000231C4FFFF31A200FF1B -:1034F000AFA200108F6C0014AFA800180E00008B54 -:10350000AFAC0014240400100E0000C7000000003F -:103510008E72000016400005000000008F64001449 -:103520002405FFBF00859824AF7300148F79000C29 -:1035300003353821AF67000C9375000816A000080A -:103540000000000012800006000000008F7F0014C1 -:103550003C0BEFFF3568FFFE03E84824AF69001419 -:10356000A37400088FA500200A0002460220202133 -:10357000AF470E000A0000F5000000008F590178E7 -:103580000720FFFE241F08008F840000AF5F017832 -:10359000974B008A316AFFFF014448232528FFFF2B -:1035A00031021FFF2C4300081460FFF900000000E7 -:1035B0008F8E00488F8D003800C0482103442021A1 -:1035C00025C60001240C0F00AF86004800E938230F -:1035D0002486400031CA00FF11AC00052408000118 -:1035E0009391003E3230000700107A4035E8000128 -:1035F000000AAC003C18010002B8A025AC944000C1 -:103600008F93004830B2003630A40008ACD30004D9 -:103610001080009701123025974E0E0A8F8D000002 -:103620003C02810031CCFFFF25AB00080182402520 -:103630003C03100031651FFF25390006241F000ED2 -:10364000AF48016000C33025A75F015AAF85000075 -:10365000A759015814E0000A8F93003824120F0074 -:10366000527200022416000134C600408F580E101A -:103670008F940044AE9800208F550E18AE9500240C -:103680008F450E14AF4501448F590E1CAF590148A8 -:10369000A34A01523C0A1000AF460154AF4A0178D8 -:1036A00014E0FEDD2D2300010076A0251280001716 -:1036B0008FBF00448F84003824160F0010960084BA -:1036C000000000008F45017804A0FFFE24150F00C4 -:1036D0001095006E000000008F470E142402024077 -:1036E0003C1F1000AF4701448F440E1CAF440148FB -:1036F000A3400152A740015AAF400160A7400158C2 -:10370000AF420154AF5F01788FBF00448FB60040D5 -:103710008FB5003C8FB400388FB300348FB20030C7 -:103720008FB1002C8FB0002803E0000827BD0048AF -:1037300014C0FED030B8A0408F420E148F840044D5 -:1037400000004821AC8200208F510E1CAC91002457 -:103750000A00020E2D2300018F910034978A003C4D -:103760003C1280000220A821315800401700FF3091 -:103770000000A021976900108F9200343139FFFFBB -:103780001332003500002021008048211480FEA063 -:1037900000A038218F420E148F840044AC82002098 -:1037A0008F510E1CAC9100240A00020E2D23000143 -:1037B000936A00099378000B315000FF330F00FF2C -:1037C000020F702125C2000A3050FFFF0E00009E3C -:1037D000020020218F8600483C1F410024CD0001BB -:1037E000AF8D0048936C000930C600FF000644000E -:1037F000318300FF246B0002010B4825013FC825DF -:10380000AC5900008F67000C97440E1400F2282575 -:10381000AC4500048F450E1C8F670004936A0002BC -:103820003084FFFF315800FFAFB800108F6F0014D5 -:10383000AFB100180E00008BAFAF00140A0001A654 -:1038400002002021AF6000040A00013EA3600002D4 -:103850000A00024600002021000090210A000170A9 -:10386000241400013C1280000A000195ACB2000C47 -:103870008F91000025240002A7440158263000083B -:10388000320F1FFF0A0001F9AF8F0000AF40014C5B -:103890001120002C000000008F590E10AF59014478 -:1038A0008F430E18240200403C1F1000AF43014814 -:1038B000A3400152A740015AAF400160A740015800 -:1038C000AF420154AF5F01780A0002278FBF004466 -:1038D000112000060000000097460E0830CC004082 -:1038E00015800002000000000000000D8F4D0178DF -:1038F00005A0FFFE0000000097530E103C120500CB -:10390000240E2000326AFFFF0152C025AF58014C3F -:103910008F4F0E143C021000AF4F01448F500E1C0D -:10392000AF500148A34001528F840038A740015A8C -:10393000AF400160A7400158AF4E01540A00021584 -:10394000AF4201788F490E14AF4901448F430E1CDA -:103950000A00028E240200403C0E20FF27BDFFE03B -:103960003C1A80003C0F800835CDFFFDAFBF001C26 -:10397000AFB20018AFB10014AFB00010AF8F00406D -:10398000AF4D0E000000000000000000000000002D -:1039900000000000000000003C0C00FF358BFFFD24 -:1039A000AF4B0E003C0660048CC95000240AFF7F18 -:1039B0003C116000012A40243507380CACC7500088 -:1039C0008E24043824050009AF4500083083FFFF2A -:1039D00038622F712450C0B3AF8000480E000068D9 -:1039E000AF80000052000001AE20442C0E000435D0 -:1039F0003C1180000E000ED9363000708F8A0040D6 -:103A00003C12080026523C88020088218E080000E3 -:103A10008F5F00003BF900013338000113000017ED -:103A2000AF880030022048218D2700003C0F08009D -:103A30008DEF006C3C0C08008D8C006800E8C02302 -:103A400001F828210000682100B8302B018D582191 -:103A5000016640213C010800AC25006C3C010800D7 -:103A6000AC2800688F4400003883000130620001F8 -:103A70001440FFED00E04021AF8700308E0C0000C5 -:103A80003C0508008CA5006C3C0408008C84006890 -:103A90000188302300A638210000102100E6402BC9 -:103AA000008218210068F8213C010800AC27006C56 -:103AB0003C010800AC3F00688F490100255900888F -:103AC000AF990044AF890038AF4900208E0700004D -:103AD000AF8700308F4D017805A0FFFE0000000089 -:103AE0008E0600003C0B08008D6B00743C0408003F -:103AF0008C84007000C728230165F8210000102184 -:103B000003E5402B0082382100E8C8212409080081 -:103B10003C010800AC3F00743C010800AC39007067 -:103B2000AF49017893580108A398003E938F003E57 -:103B300031EE000115C000158F830038240E0D00F2 -:103B4000106E0019240F0F00106F001D0000000000 -:103B50009159000024180050332900FF1138000447 -:103B60003C1F4000AF5F01380A0002E70000000080 -:103B70000E00090E000000008F8A00403C1F40002C -:103B8000AF5F01380A0002E700000000938D003E9D -:103B900031AC0006000C51000E0000CE0152D821BD -:103BA0000A0003438F8A00403C1B0800277B3D0826 -:103BB0000E0000CE000000000A0003438F8A004080 -:103BC0003C1B0800277B3D280E0000CE00000000B3 -:103BD0000A0003438F8A004090AA00018FAB0010B7 -:103BE0008CAC00103C0300FF8D680004AD6C00201D -:103BF0008CAD001400E060213462FFFFAD6D002445 -:103C00008CA700183C09FF000109C024AD670028FB -:103C10008CAE001C0182C82403197825AD6F000406 -:103C2000AD6E002C8CAD0008314A00FFAD6D001C5C -:103C300094A900023128FFFFAD68001090A7000092 -:103C4000A5600002A1600004A167000090A300022B -:103C5000306200FF00021982106000052405000197 -:103C60001065000E0000000003E00008A16A0001DA -:103C70008CD80028354A0080AD7800188CCF00140D -:103C8000AD6F00148CCE0030AD6E00088CC4002CDB -:103C9000A16A000103E00008AD64000C8CCD001C9B -:103CA000AD6D00188CC90014AD6900148CC80024D7 -:103CB000AD6800088CC70020AD67000C8CC20014F2 -:103CC0008C8300640043C82B132000070000000011 -:103CD0008CC20014144CFFE400000000354A008040 -:103CE00003E00008A16A00018C8200640A000399C5 -:103CF0000000000090AA000027BDFFF88FA9001C5B -:103D0000A3AA00008FAE00003C0FFF808FA8001810 -:103D100035E2FFFF8CCD002C01C26024AFAC000067 -:103D2000A120000400E06021A7A000028FB80000DD -:103D30008D2700040188182100A0582100C05021BF -:103D4000006D28263C06FF7F3C0F00FF2CAD0001D4 -:103D500035EEFFFF34D9FFFF3C02FF00031930248A -:103D6000000D1DC0010EC82400E2C02400C3702550 -:103D700003197825AD2E0000AD2F00048D450024D9 -:103D8000AFAE0000AD2500088D4D00202405FFFFDB -:103D9000AD2D000C956800023107FFFFAD27001024 -:103DA0009166001830C200FF000219C25060000185 -:103DB0008D450034AD2500148D67000827BD00082F -:103DC000AD27001C8C8B00CCAD2C0028AD20002C26 -:103DD000AD2B0024AD20001803E00008AD2000202A -:103DE00027BDFFE0AFB20018AFB10014AFB00010B4 -:103DF000AFBF001C9098000000C088213C0D00FF60 -:103E0000330F007FA0CF0000908E000135ACFFFF84 -:103E10003C0AFF00A0CE000194A6001EA2200004D0 -:103E20008CAB00148E29000400A08021016C282492 -:103E3000012A40240080902101052025A6260002A9 -:103E4000AE24000426050020262400080E0000767B -:103E500024060002924700002605002826240014AC -:103E600000071E000003160324060004044000039C -:103E70002403FFFF965900023323FFFF0E00007654 -:103E8000AE230010262400248FBF001C8FB2001820 -:103E90008FB100148FB00010240500030000302102 -:103EA0000A00008027BD002027BDFFD8AFB1001C4D -:103EB000AFB00018AFBF002090A80000240200019E -:103EC0008FB0003C3103003F008088211062001455 -:103ED0008FAA0038240B0005506B0016AFAA001003 -:103EE00000A0202100C028210E0003DC02003021A8 -:103EF000922400BC308300021060000326060030CC -:103F0000ACC0000024C600048FBF00208FB1001C8D -:103F10008FB0001800C0102103E0000827BD002862 -:103F2000014038210E00035AAFB000100A000420EF -:103F3000000000000E0003A1AFB000140A0004202E -:103F4000000000003C02000A034218213C04080063 -:103F500024843D6C2405001A000030210A000080F2 -:103F6000AF8300543C038000346200708C48000032 -:103F700000A0582100C04821308A00FFAF880030DF -:103F80008F4401780480FFFE3C0C80003586007071 -:103F90008CC500003C0308008C6300743C180800CA -:103FA0008F18007000A82023006468210000C82139 -:103FB00001A4782B0319702101CF60213C01080076 -:103FC000AC2D00743C010800AC2C00708F480E141E -:103FD000AF480144AF47014CA34A0152A74B0158D7 -:103FE0009346010830C5000854A00001352910008F -:103FF000934B090024070050316A00FF1147000766 -:10400000000000008F450E1CAF450148AF49015428 -:104010003C09100003E00008AF490178934D010806 -:1040200031A800081100001000000000934F0108A3 -:1040300031EE001051C00001352900083C04080091 -:1040400090843DD0A34401508F4309A4AF4301485D -:104050008F4209A0AF420144AF4901543C0910000E -:1040600003E00008AF4901783C1908008F393D8C06 -:10407000333800085700FFF1352900080A0004739F -:104080000000000024070040AF470814AF400810AC -:104090008F4209448F4309508F4409548F45095C6E -:1040A0008F46094CAF820064AF830050AF84004C50 -:1040B000AF85005C03E00008AF860060934601090D -:1040C00030C5007F000518C0000521400083102185 -:1040D00003E00008244200883C09080091293D9132 -:1040E00024A800023C05110000093C0000E830252E -:1040F00000C5182524820008AC83000003E00008F6 -:10410000AC8000049347010B8F4A002C974F09089D -:104110003C18000E0358482131EEFFFF000E41C04D -:10412000AF48002C97430908952C001A00804021C5 -:1041300024030001318BFFFFAC8B00008D2D001C90 -:1041400000A0582100C06021AC8D00048D24002007 -:1041500030E70040AD04000891220019304400030C -:10416000108300482885000214A000622406000283 -:104170001086005624190003109900660000000004 -:1041800010E0003A000000003C07080094E73D867C -:1041900024E20001934F0934934709219525002A11 -:1041A00031EE00FF000E488230ED00FF9787005887 -:1041B00000093600000D1C003044FFFF00C310252D -:1041C0000044C02500A778213C1940000319702540 -:1041D000000F4C00AD090004AD0E0000934D092006 -:1041E0003C03000625090014000D360000C32025FD -:1041F000AD0400088F59092C24E5000130A27FFF8F -:10420000AD19000C8F580930A782005825020028EC -:10421000AD1800108F4F0938AD0F0014AD2B0004FE -:104220008F4E0940AD2E0008934D09373C0508001C -:1042300090A53D908F4409488F46094031A700FF63 -:1042400000EC1821008678230003C7000005CC008D -:104250000319602531E8FFFC01885825AD2B000CBF -:10426000AD20001003E00008AF4A002C3C0D080010 -:1042700095AD3D863C0E080095CE3D800A0004C9F0 -:1042800001AE10213C05080094A53D8A3C060800BB -:1042900094C63D803C18080097183D7C952E00245C -:1042A00000A6782101F86823000E240025A2FFF261 -:1042B0000082182524190800AD03000CAD19001464 -:1042C000AD0000100A0004C425080018952600243B -:1042D000952500280006C40000057C00370E8100EB -:1042E00035ED0800AD0E000CAD0D00100A0004C441 -:1042F000250800141480FFA200000000952400246B -:104300000004140034430800AD03000C0A0004C488 -:10431000250800103C03080094633D8A3C05080012 -:1043200094A53D803C06080094C63D7C9539002448 -:1043300095380028006520210086782300196C003C -:104340000018740025E2FFEE01C2202535A381008C -:1043500024190800AD03000CAD040010AD190018BD -:10436000AD0000140A0004C42508001C03E0000886 -:10437000240201F427BDFFE8AFB00010AFBF001466 -:104380000E0000600080802124050040AF45081425 -:104390008F8300508F84004C8F85005C0070182143 -:1043A0000064102318400004AF830050AF63005432 -:1043B0008F660054AF86004C1200000C0000000015 -:1043C0008F440074936800813409FA002D070007B8 -:1043D00010E0000500891021936C0081240B01F48A -:1043E000018B500401441021AF62000C8F4E095C18 -:1043F00001C5682319A000048FBF00148F4F095C0A -:10440000AF8F005C8FBF00148FB000100A000062F5 -:1044100027BD00188F8400648F8300508F82004C6A -:10442000AF640044AF63005003E00008AF62005483 -:104430003C038000346200708C43000027BDFFF80D -:10444000308700FF30A900FF30C800FFAF83003085 -:104450008F4401780480FFFE3C02800034590070D4 -:104460008F380000A3A700033C0708008CE7007406 -:104470008FAC00003C0608008CC600700303782354 -:104480003C0E7FFF00EFC82135CDFFFF000050211B -:10449000018D282400CA1821000847C0032F202BB3 -:1044A00000A810250064C021AFA200003C01080054 -:1044B000AC3900743C010800AC380070934F010A1D -:1044C000A3A000023C0E80FFA3AF00018FAC000050 -:1044D000312B007F35CDFFFF018D4824000B5600A6 -:1044E000012A4025240730002406FF803C051000E7 -:1044F00027BD0008AF48014CAF470154A740015801 -:10450000A346015203E00008AF45017827BDFFE84C -:10451000AFBF0014AFB000108F6500743C06800080 -:10452000309000FF00A620250E000060AF640074EC -:1045300093630005346200080E000062A362000568 -:10454000020020218FBF00148FB000102405000549 -:10455000240600010A00057027BD001827BDFFE0F2 -:104560003C038000AFB00010AFBF0018AFB1001423 -:10457000346200708C470000309000FF30A800FFCC -:10458000AF8700308F4401780480FFFE3C18800024 -:10459000371100708E2F00003C0D08008DAD0074A7 -:1045A0003C0A08008D4A007001E7702301AE282103 -:1045B0000000582100AE302B014B48210126382144 -:1045C0003C010800AC250074000088213C01080073 -:1045D000AC2700701100000F000000008F62007413 -:1045E0002619FFFF3208007F0002FE0233E5007F3C -:1045F00015000006332200FF2407FF800207202653 -:1046000024A3FFFF00838025320200FF00408021A9 -:10461000241110080E000060000000008F490818E7 -:104620003125000414A0FFFD3218007F001878C067 -:104630000018714001CF682125AC0088AF4C0818E4 -:10464000274A09808D4B0020AF4B01448D46002442 -:10465000AF460148A35001500E000062A740015828 -:10466000022010218FBF00188FB100148FB00010EE -:1046700003E0000827BD002027BDFFE8308400FFCD -:10468000AFBF00100E0005BB30A500FF8F830050A8 -:104690008FBF0010344500402404FF903C021000FE -:1046A00027BD0018AF43014CA3440152AF4501544C -:1046B00003E00008AF4201789343093E30620008EE -:1046C0001040000D3C0901013528080AAC880000A3 -:1046D0008F470074AC8700043C06080090C63D90EC -:1046E00030C5001050A00006AC8000088F6A006042 -:1046F000AC8A00082484000C03E00008008010212C -:104700000A0006222484000C27BDFFE8AFBF001476 -:10471000AFB000109346093F00A05021000528804B -:104720000085382330C200FF240300063C0908003E -:1047300095293D8624E8FFD824050004104300375E -:10474000240600029750093C3C0F02040006340086 -:10475000320EFFFF01CF6825AC8D0000934C093E5F -:10476000318B0020116000080000000093430936DF -:104770003C020103345F0300307900FF033FC02592 -:1047800024050008AC980004934309349359092187 -:104790000005F882306200FF0002C082332F00FF64 -:1047A00000186E00000F740001AE602501892025FD -:1047B0003C09400000898025ACF0FFD893430937BD -:1047C0008F4F09488F580940306200FF004AC821C6 -:1047D000033F702101F86023000E6F0001A65025F1 -:1047E0003185FFFC001F58800145482501683821AC -:1047F000AD0900200E00006024F00028240400040D -:104800000E000062A364003F020010218FBF00145D -:104810008FB0001003E0000827BD00180A0006351D -:104820002406001227BDFFD024090010AFB60028CF -:10483000AFB50024AFB40020AFB10014AFB000108A -:104840003C010800A0293D90AFBF002CAFB3001C75 -:10485000AFB2001897480908309400FF3C02000EE0 -:104860003107FFFF000731C0AF46002C974409080D -:104870009344010B30B500FF0342802130830030A8 -:104880000000B0211060012500008821240C0004E4 -:104890003C010800A02C3D90934B093E000B5600B4 -:1048A000000A2E0304A0016000000000AF40004891 -:1048B000934F010B31EE002011C0000600000000F4 -:1048C0009358093E00189E00001396030640018984 -:1048D000000000009344010B30830040106000038F -:1048E0008F9300508F8200502453FFFF9347093E5F -:1048F00030E6000814C000022412000300009021DA -:104900009619002C93580934934F0937A7990058EA -:10491000330C00FF31EE00FF024E6821000D58807D -:10492000016C5021015140213C010800A4283D8622 -:104930009205001830A900FF010918213C01080068 -:10494000A4233D88921100181620000200000000E8 -:104950000000000D3C010800A4233D8A3C01080032 -:10496000A4203D803C010800A4203D7C935F010B06 -:104970003063FFFF33F00040120000022464000A9D -:104980002464000B3091FFFF0E00009E02202021C6 -:104990009358010B3C08080095083D8A00402021EF -:1049A00000185982316700010E00049A010728217E -:1049B000934C010B8F4B002C974E09083C0F000EB7 -:1049C000034F402131CDFFFF000D51C0AF4A002CF5 -:1049D000974309089505001A004038212404000176 -:1049E00030A9FFFFAC4900008D06001C00404821A3 -:1049F000318A0040AC4600048D020020ACE2000881 -:104A00009103001930630003106400EC2879000260 -:104A100017200118241000021070010C241F00033D -:104A2000107F011E00000000114000DE00000000A9 -:104A30003C09080095293D8625220001935F093431 -:104A4000934E09219504002A33F900FF0019C08212 -:104A500031CF00FF978E005800184600000F6C0001 -:104A6000010D80253045FFFF02051025008E5021E5 -:104A70003C03400000433025000A6400ACEC000415 -:104A8000ACE60000935F09203C19000624EC0014FA -:104A9000001FC60003197825ACEF00088F48092CC9 -:104AA00025CD000131A57FFFACE8000C8F50093007 -:104AB000A785005824E80028ACF000108F4409387E -:104AC00001008021ACE40014AD9300048F53094031 -:104AD000AD930008934A09373C19080093393D907B -:104AE0008F4309488F460940314200FF0052F821A8 -:104AF00000667023001F7F000019C40001F82825FC -:104B000031CDFFFC00AD2025AD84000CAD80001040 -:104B1000AF4B002C934B093E317300081260000D1F -:104B20003C06010134CC080AACEC00288F53007419 -:104B3000AD1300043C0B0800916B3D9031670010F1 -:104B400050E00003AD0000088F6A0060AD0A000865 -:104B50002510000C12C0003D000000009343093FE7 -:104B60002416000624060004306200FF105600C917 -:104B7000240700029758093C3C0F0204330DFFFF45 -:104B800001AF4025AE0800009345093E30A4002047 -:104B90001080000800000000935309363C0B01030D -:104BA000357F0300327900FF033F7025AE0E00040D -:104BB00024060008934F093493480921312AFFFF46 -:104BC00031ED00FF000D1082310300FF0002B6003E -:104BD00000032C0002C56025018A98250012208060 -:104BE0003C0940000204502302695825AD4BFFD810 -:104BF000935F09378F4F09488F58094033F900FFF9 -:104C0000033270210006B08201D6682100074400FB -:104C100001F82823000D1F000068302530A2FFFC9A -:104C20002547FFD800C26025001680800207482172 -:104C3000ACEC0020253000280E0000602412000497 -:104C4000A372003F0E000062000000009347010BBA -:104C500030F20040124000053C1900FF8E180000A1 -:104C6000372EFFFF030E3024AE0600000E0000C7F3 -:104C7000022020213C10080092103D9032110003C8 -:104C80001220000F02A028218F8900502533000137 -:104C9000AF930050AF7300508F6B00540173F82333 -:104CA0001BE00002026020218F640054AF640054B6 -:104CB0008F4C0074258401F4AF64000C02A02821FD -:104CC00002802021A76000680E0005BB3C14100084 -:104CD0008F85005034550006AF45014C8F8A00483F -:104CE0008FBF002C8FB3001C25560001AF960048E3 -:104CF0008FB20018A34A01528FB60028AF55015455 -:104D00008FB10014AF5401788FB500248FB4002008 -:104D10008FB0001003E0000827BD00309358093E13 -:104D200000189E000013960306420036241100026C -:104D300093440923308300021060FEDD8F860060FB -:104D40008F82005014C2FEDA000000000E000060E6 -:104D5000000000009369003F24070016312800FF7F -:104D60001107000C240500083C0C0800918C3D90B4 -:104D7000358B00013C010800A02B3D90936A003F59 -:104D8000314300FF10650065240D000A106D005EC0 -:104D90002402000C0E000062000000000A000690D1 -:104DA000000000003C09080095293D863C0A0800E7 -:104DB000954A3D800A0006F3012A10213C090800AB -:104DC00095293D8A3C04080094843D803C060800F7 -:104DD00094C63D7C95030024012410210046F8234D -:104DE0000003CC0027F0FFF20330C025240F080099 -:104DF000ACF8000CACEF0014ACE000100A0006EEBA -:104E000024E700183C010800A0313D90935F093E63 -:104E10002416000133F900201720FEA524110008F4 -:104E20000A000690241100048F6E00848F4D094003 -:104E300011A0FE9EAF8E0050240F00143C0108000C -:104E4000A02F3D900A00068F00000000950E002460 -:104E5000950D0028000E6400000D2C00358981009E -:104E600034A60800ACE9000CACE600100A0006EE1F -:104E700024E700141460FEEC0000000095020024FA -:104E800000021C0034640800ACE4000C0A0006EECA -:104E900024E700100A000741240700123C02080022 -:104EA00094423D8A3C06080094C63D803C030800BD -:104EB00094633D7C95100024951900280046F82144 -:104EC00003E3C02300106C0000197400270FFFEEED -:104ED00001CF282535AC8100ACEC000CACE500100E -:104EE00024070800AD2700182527001C0A0006EE3D -:104EF000AD2000148F7F004CAF7F00548F79005499 -:104F00000A000699AF790050A362003F0E000062CC -:104F1000000000000A0006900000000024020014B7 -:104F20000A000827A362003F27BDFFE8308400FF86 -:104F3000AFBF00100E0005BB30A500FF9378007EC8 -:104F40009379007F936E00809368007A332F00FF7F -:104F500000186600000F6C0031CB00FF018D482562 -:104F6000000B52008FBF0010012A3825310600FFC8 -:104F70003444700000E628252402FF813C03100021 -:104F800027BD0018AF45014CAF440154A342015264 -:104F900003E00008AF43017827BDFFD8AFB2001887 -:104FA000AFB10014AFB00010AFBF0020AFB3001C12 -:104FB00093420109308600FF30B000FF000618C29E -:104FC000320400023071000114800005305200FFED -:104FD0009367000530E5000810A0000D30C80010F0 -:104FE000024020210E0005A70220282124040001F0 -:104FF0008FBF00208FB3001C8FB200188FB1001438 -:105000008FB000100080102103E0000827BD0028A9 -:105010001500003200000000934301090000282120 -:105020003062007F000220C00002F94003E49821B2 -:1050300026790088033B98218E7800248E6F000823 -:10504000130F0046000000008F6400842418000243 -:105050000004FD8233F900031338007C00000000D7 -:1050600093660083934A0109514600043205007C8F -:1050700010A00060000000003205007C14A0005366 -:105080000240202116200006320400018E7F0024F9 -:105090008F59010417F9FFD60000202132040001C6 -:1050A0001080000A024020218F4209408F93006443 -:1050B00010530006000000000E00066D022028219B -:1050C0008F430940AF630044024020210E000602D6 -:1050D000022028210A000860240400013C0908007D -:1050E0008D290064252600013C010800AC260064DF -:1050F00016000012000000008F6D00843C0E00C0FE -:1051000001AE602415800005024020210E00082E0B -:10511000022028210A00086024040001240500045C -:105120000E00057024060001024020210E00082E0A -:10513000022028210A000860240400010E0000411A -:1051400024040001936B007D020B50250E000062C9 -:10515000A36A007D0A0008A38F6D00848F66007427 -:105160008F4801048E67002400064E021507FFB623 -:105170003126007F936B008326440001308A007F34 -:1051800011460043316300FF5464FFB08F64008414 -:105190002645000130B1007F30A200FF1226000436 -:1051A00024050001004090210A0008762411000126 -:1051B000240FFF80024F702401CF9026324200FF5F -:1051C000004090210A000876241100010E00066DAF -:1051D00002202821321800301300FFAA321000826A -:1051E000024020210E0005A7022028210A000860A5 -:1051F000240400018F6E00743C0F8000240500031E -:1052000001CF9025AF7200749371008324060001D2 -:105210000E000570322400FF0E000041240400013E -:10522000936D007D020D60250E000062A36C007D71 -:105230003C0B08008D6B0054257000013C010800F8 -:10524000AC3000540A000860240400018F68007428 -:105250003C0980002405000401093825AF6700746B -:1052600093630083240600010E000570306400FF84 -:105270000E000041240400019362007D0202982583 -:105280000E000062A373007D0A0008602404000180 -:10529000324D008039AC0080546CFF6C8F64008408 -:1052A0000A0008C92645000127BDFFC83C0A0008BE -:1052B000AFBF0030AFB5002CAFB40028AFB30024AF -:1052C000AFB20020AFB1001CAFB00018034AD82124 -:1052D00024090040AF490814AF4008108F42094428 -:1052E0008F4309508F4609548F47095C8F48094CFA -:1052F000934401089345010BAF820064308400FFA2 -:1053000030A500FFAF830050AF86004CAF87005C34 -:105310000E00084AAF8800601440017D8FBF003046 -:10532000A7600068934D0900240B00503C1508004D -:1053300026B53D4831AC00FF3C12080026523D58CE -:10534000118B0003000000000000A8210000902144 -:10535000935101098F9F005024040010322E007FCA -:10536000000E68C0000E6140018D282124B4008821 -:10537000AF5408188F4901048F4A09A43C0B000E52 -:10538000034BC021012A10233C010800AC223D6CD4 -:105390008F4309583C010800A0243D909747090815 -:1053A000007F30233C010800AC263D7030E8FFFF51 -:1053B0000008C9C03C010800AC3F3D94AF59002C27 -:1053C000974209089710002C8EB10000930F001827 -:1053D00003749821A7900058AF9300440220F80965 -:1053E00031F000FF304E000215C001B2304F000115 -:1053F00011E0014F000000009343093E30660008B1 -:1054000014C00002241400030000A0218F5809A436 -:10541000241300013C010800AC383D98934F093437 -:105420009351093731EC00FF322E00FF028E6821C4 -:10543000000D288000AC5021015058213C0108008B -:10544000A42B3D883C010800A42A3D8693490934D9 -:10545000312200FF02022021249000103C010800AC -:10546000A4303D84240700068F9F00503C010800B3 -:10547000AC273D8C8F88005C8F5909580000802133 -:10548000011F282304A00149033F20230480014772 -:1054900000A4302B10C00149000000003C010800AE -:1054A000AC253D708E4200000040F809000000006D -:1054B00030430002146000F80040882130440001AD -:1054C000548000108E4200043C0908008D293D7470 -:1054D0003C0AC000012A8025AF500E008F45000015 -:1054E00030AB00081160FFFD00000000974D0E0872 -:1054F00024100001A78D003C8F4C0E04AF8C0034AB -:105500008E4200040040F8090000000002228825B5 -:10551000322E000215C00180000000003C09080086 -:1055200095293D7C3C06080094C63D883C0A08004D -:10553000954A3D7E3C1908008F393D740126602153 -:105540003C1808008F183D983C03080094633D9276 -:10555000018A20218F4E09400329F821248F00025F -:1055600003E32821031968213C010800A42C3D8A8B -:10557000AF8E00643C010800AC2D3D983C01080052 -:10558000A4253D800E00009E31E4FFFF8F87004878 -:10559000004020213C010800A0273D918E420008D8 -:1055A00024E80001AF8800480040F809000000002E -:1055B0009344010B8F4C002C974A09083C0B000EBA -:1055C000034B40213149FFFF000919C08F8B005068 -:1055D000AF43002C974309089506001A0040382174 -:1055E000308A004030DFFFFFAC5F00008D19001CE7 -:1055F00000404821AC5900048D180020AC58000828 -:10560000910F001931E30003107300F00000000057 -:10561000286200021440010924050002106500FD03 -:10562000240D0003106D010D00000000114000D991 -:10563000000000003C0A0800954A3D862542000112 -:10564000934D093493580921950E002A31A300FF88 -:1056500000032082331F00FF9798005800047E004B -:10566000001FCC0001F940253049FFFF010910253A -:1056700001D830213C0540000045502500066C0053 -:10568000ACED0004ACEA0000934309203C040006A2 -:1056900024ED00140003FE0003E4C825ACF9000863 -:1056A0008F49092C270F000131EE7FFFACE9000C78 -:1056B0008F480930A78E005824E90028ACE8001074 -:1056C0008F45093801204021ACE50014ADAB000442 -:1056D0008F420940ADA20008934B09373C1F0800D8 -:1056E00093FF3D908F4309488F4A0940316600FF80 -:1056F00000D42021006A78230004C700001FCC00DA -:105700000319282531EEFFFC00AE1025ADA2000CD8 -:10571000ADA00010AF4C002C934C093E318B00081B -:105720005160000F8E58000C3C06010134CA080A73 -:10573000ACEA00288F4B0074AD2B00043C0C080031 -:10574000918C3D903187001050E00003AD2000089F -:105750008F620060AD2200082528000C8E58000CD6 -:105760000300F809010020213C19080097393D8AFF -:105770003C1F080097FF3D7E033F782125E900028A -:105780000E0000C73124FFFF3C0E08008DCE3D6C9B -:105790003C0808008D083D7401C828233C0108001E -:1057A000AC253D6C14A00006000000003C0308007E -:1057B0008C633D8C346400403C010800AC243D8C7B -:1057C000120000708F8C00448F470E108F900044A1 -:1057D000AE0700208F4D0E18AE0D00243C100800BF -:1057E00096103D800E000060000000002402004082 -:1057F000AF4208148F8600508F8A004C00D01821C9 -:10580000006A582319600004AF830050AF6300544E -:105810008F650054AF85004C1200000C00000000A2 -:105820008F440074936800813409FA002D0E00073C -:1058300011C0000500891821937F0081241901F40B -:1058400003F9780401E41821AF63000C8F44095C6C -:105850008F83005C0083C0231B0000030000000056 -:105860008F50095CAF90005C0E00006200000000E9 -:105870008F8C00508E4700103C010800AC2C3D94EA -:1058800000E0F809000000003C0D08008DAD3D6C03 -:1058900055A0FEF5240700068F45002497590908F6 -:1058A0008F8B00648F9400503C0F001F978200582C -:1058B0008F8600548F93004C3328FFFF35E9FF801B -:1058C00000A95024000871C032320100AF4E0024FC -:1058D000A4C2002CAF4A0024AF6B0044AF74005048 -:1058E000AF73005416400080323800105700008615 -:1058F0008EA40004322300405460001B8EB10008C7 -:105900008EB0000C0200F809000000008FBF0030CC -:105910008FB5002C8FB400288FB300248FB20020E5 -:105920008FB1001C8FB0001803E0000827BD0038BD -:10593000934701098F8800380007FE0003E8C82557 -:10594000AF5900808F5809A08F5309A4AFB8001039 -:10595000AF580E148FB40010AF540E10AF530E1C7E -:105960000A000962AF530E180220F8090000000077 -:105970008EB0000C0200F809000000000A000AA81E -:105980008FBF0030A5800020A59300220A000A5B8B -:10599000AD9300243C09080095293D863C0608008B -:1059A00094C63D800A0009F4012610213C0108003C -:1059B000AC203D700A00098E8E4200003C010800B8 -:1059C000AC243D700A00098E8E4200003C030800A2 -:1059D00094633D8A3C04080094843D803C1F080089 -:1059E00097FF3D7C951800240064C821033F78236D -:1059F00000186C0025EEFFF201AE2825AC45000C26 -:105A000024020800ACE20014ACE000100A0009EF28 -:105A100024E70018950600249509002800062400B4 -:105A200000091C00349F810034790800ACFF000C91 -:105A3000ACF900100A0009EF24E700141460FEFB23 -:105A4000000000009518002400187C0035EE0800C6 -:105A5000ACEE000C0A0009EF24E700103C07080038 -:105A600094E73D803C04080094843D8A3C03080090 -:105A700094633D7C95190024951800280087F8212F -:105A800003E378232407080000192C0000186C0099 -:105A900025EEFFEE01AE302534A28100AD270018BF -:105AA0002527001CAD22000CAD2600100A0009EFCE -:105AB000AD20001493520109000028210E000602B7 -:105AC000324400FF8FBF00308FB5002C8FB4002808 -:105AD0008FB300248FB200208FB1001C8FB000184C -:105AE00003E0000827BD0038935F010933E400FF9D -:105AF0000E00066D00002821323800105300FF7E92 -:105B0000322300408EA400040080F8090000000049 -:105B10000A000AA2322300401200FF5F00000000CA -:105B20008F540E148F920044AE5400208F530E1CDD -:105B30000A000A8AAE5300248F82001C0080402194 -:105B40003C0401009047008530E30020106000090C -:105B5000000000003C0708008CE73D948F8300188C -:105B600000E32023048000089389000414E3000369 -:105B70000100202103E00008008010213C04010006 -:105B800003E00008008010211120000B006738237B -:105B90008F8C002024090034918B00BC316A0002F4 -:105BA000514000012409003000E9682B15A0FFF1E5 -:105BB0000100202100E938232419FFFC00B9C0248A -:105BC00000F9782400F8702B15C0FFEA01E82021C5 -:105BD00030C200030002182314C000123069000311 -:105BE0000000302100A9702101C6682100ED602B62 -:105BF0001180FFE03C0401002D2F00010006482B1E -:105C00000105382101E9302414C0FFDA24E4FFFC47 -:105C10002419FFFC00B9C0240308202103E0000878 -:105C2000008010218F8B002024060004916A00BCA4 -:105C3000314400041480FFEC00A970210A000B5EBF -:105C40000000302127BDFFE8AFBF00108F460100E4 -:105C5000934A01093C1F08008FFF00902407FF8032 -:105C6000314F00FF31E8007F0008614003E6C821A2 -:105C7000032CC02127090120012770243C010800C2 -:105C8000A02F3DD0AF4E080C3C0D08008DAD00900C -:105C90003C0400803482000301A65821016C1821C5 -:105CA0002465012030AA007801424025AF48081C35 -:105CB0003C1F08008FFF00908F88004003E6C02142 -:105CC0003319000703074824033A7821AF49002815 -:105CD00025E909C0952E00023C0D08008DAD008C11 -:105CE0003C0A08008D4A009031CC3FFF01A61821E4 -:105CF000000C5980006B282100A72024AF44002C01 -:105D0000952200023C1F08008FFF008C9107008540 -:105D100030593FFF03E678210019C1800146702108 -:105D200001F8682131CC007F31AB007F019A282136 -:105D3000017A50213C03000C3C04000E00A32821F2 -:105D40000144102130E6002027470980AF82002C53 -:105D5000AF88001CAF890024AF85002010C000066A -:105D6000AF8700288D0200508CA4010C0044302322 -:105D700018C0007700000000910C0085240DFFDFA3 -:105D8000018D3824A10700858F8B001C8F8900248A -:105D90008F8700288D65004CAF850018912F000D6E -:105DA00031EE002011C0001700000000240900019E -:105DB000A3890004AF80000C8CE400248F85000CC4 -:105DC000240A0008AF800008AF8000103C010800E2 -:105DD000A42A3D7E3C010800A4203D920E000B3217 -:105DE000000030218F8500248FBF0010AF82001487 -:105DF00090A8000D27BD00180008394203E00008F4 -:105E000030E20001913F00022418000133F900FF45 -:105E10000019218210980039240800021088005BC4 -:105E20008F86002C8CE5002414A0001B8F9F00207F -:105E300091220000240A00053046003F10CA0047A6 -:105E4000240400018F860008A3840004AF8600109C -:105E5000AF86000C8CE400248F85000C240A000817 -:105E60003C010800A42A3D7E3C010800A4203D928C -:105E70000E000B32000000008F8500248FBF001041 -:105E8000AF82001490A8000D27BD00180008394209 -:105E900003E0000830E200018CF800088CF90024CF -:105EA0008FEE00C4A38000048CE40024AF8E000CAD -:105EB0008F85000C8F86000803197823240A0008B8 -:105EC000AF8F00103C010800A42A3D7E3C01080071 -:105ED000A4203D920E000B32000000008F850024AC -:105EE0008FBF0010AF82001490A8000D27BD0018CE -:105EF0000008394203E0000830E20001912300006D -:105F00003062003F104400278F8500208CE400247D -:105F100014800021000000008D2E00183C187FFF27 -:105F20008F850020370FFFFF01CF1824AF830008B3 -:105F30008F9F00088CA8008403E8C82B172000025C -:105F400003E020218CA400840A000BEDAF8400083C -:105F50008CA3010C0A000BCBAF8300188D2C00180A -:105F60008F8600083C0D7FFF8F89002035A3FFFF3F -:105F70000183582424040001AF8B0010AD2000CC15 -:105F8000A38400040A000BF9AF86000C8CCA00142D -:105F90000A000BEDAF8A00088CA300C80A000C3081 -:105FA000AF8300088F84002C8CAC00648C8D0014AF -:105FB000018D582B11600004000000008CA20064C9 -:105FC0000A000C30AF8200088C8200140A000C30EA -:105FD000AF8200088F85000C27BDFFE0AFBF00181F -:105FE000AFB1001414A00007AFB000108F860024DA -:105FF0002402000590C400003083003F106200B608 -:106000008F8400208F91000800A080218F8C0028B1 -:106010003C0508008CA53D708D8B000431663FFF68 -:1060200000C5502B5540000100C02821938D00046D -:1060300011A0007300B0F82B8F98002024040034C6 -:10604000930F00BC31EE000251C000012404003067 -:1060500000A4C82B172000D10000000000A42823B2 -:1060600000B0F82B3C010800A4243D7C17E0006838 -:10607000020020213C0308008C633D6C0083102B40 -:1060800054400001008018218F8800243C01080042 -:10609000AC233D74000048219104000D30830020A2 -:1060A000506000018F490E188F8300140123382B94 -:1060B00010E00059000000003C0408008C843D748E -:1060C00000895821006B502B114000560090602B26 -:1060D0000069302300C020213C010800AC263D743B -:1060E00012000003241FFFFC1090008A32270003D7 -:1060F000009FC8243C010800AC393D743C010800F5 -:10610000A4203D928F84000C120400078F8300208E -:10611000AF910008020020218C7100CCAF90000CE0 -:1061200026300001AC7000CC3C0208008C423D746B -:106130008F8A0010240700180082202301422823A0 -:10614000AF84000C10800002AF85001024070010FF -:106150008F86001C3C010800A0273D9024070040CA -:1061600090CC0085318B00C0116700408F8D0014EA -:1061700014A0001500002021934A01098F420974E0 -:10618000314500FF0002260224A300013090007F69 -:106190003071007F1230007A2407FF80A0C3008393 -:1061A0003C0908008D293D8C8F880024240D0002B5 -:1061B000352C00083C010800A02D3DD13C01080011 -:1061C000AC2C3D8C24040010910E000D31C6002033 -:1061D00010C0000500801821240800013C010800BF -:1061E000AC283D74348300018FBF00188FB10014B8 -:1061F0008FB000100060102103E0000827BD0020D0 -:106200003C010800A4203D7C13E0FF9A02002021FD -:106210000A000C8100A020213C0408008C843D74FD -:106220000090602B1180FFAE000000003C0F0800C2 -:1062300095EF3D7C01E4702101C6682B11A0000799 -:106240002C8200043C1F60008FF954043338003F57 -:106250001700FFE5240300422C8200041040FFA039 -:10626000240300420A000CDF8FBF0018152DFFC069 -:10627000000000008CDF00743C0380002405FF80D8 -:1062800003E3C825ACD9007490D80085240E00041F -:1062900024040010330F003F01E54025A0C800850D -:1062A0008F8800243C010800A02E3DD1240300016A -:1062B0009106000D30C900201520000300000000E9 -:1062C0003C0308008C633D743C010800AC233D6C2A -:1062D0000A000CD6000000008F8700108C88008414 -:1062E00000E8282B14A0000200E088218C91008493 -:1062F00024090001A38900048F440E1802202821DC -:106300000E000B3202203021022080210A000C678F -:10631000AF82001400071823306600033C01080018 -:10632000A4263D92122000058F8C0020918B00BC8A -:10633000316A00041540001524CD00043C0F08000C -:1063400095EF3D9201E4702100AE302B50C0FF6EFE -:106350008F84000C2C85000514A0FFA324030042A9 -:106360003098000317000002009818232483FFFCD4 -:106370003C010800AC233D740A000CA3000000009F -:1063800000A758240A000CCB016718263C0108001E -:10639000A42D3D920A000D33000000003C010800CE -:1063A000AC203D740A000CDE240300428F830010F1 -:1063B00014600007000010218F88002424050005C8 -:1063C0009106000030C400FF1085000300000000AB -:1063D00003E0000800000000910A0018314900FFA6 -:1063E000000939C214E0FFFA8F85001C3C04080044 -:1063F00094843D7C3C0308008C633D943C19080068 -:106400008F393D743C0F080095EF3D920064C02128 -:106410008CAD00540319702101CF6021018D5823E8 -:106420001960001D00000000910E001C8F8C002CD4 -:10643000974B0E1031CD00FF8D850004016D302388 -:106440008D88000030CEFFFF000E510000AAC82149 -:106450000000382101072021032A182B0083C021C6 -:10646000AD990004AD980000918F000A01CF68211A -:10647000A18D000A8F88002C974B0E12A50B0008E7 -:10648000950A003825490001A50900389107000D3B -:1064900034E60008A106000D03E00008000000003B -:1064A00027BDFFE0938700048F8F00248FAD001479 -:1064B0003C0E7FFF8F89000C35C8FFFFAFBF001C6B -:1064C000AFB0001801A8182491EA000D000717C00A -:1064D0003C1FBFFF006258252D2E00018F90001831 -:1064E00037F9FFFF3C1808008F183D943C0F080057 -:1064F00095EF3D8A01796824000E47803C07EFFF45 -:106500003C05F0FF01A818253149002034E2FFFFC7 -:1065100034ACFFFF0310582327A500102406000207 -:1065200025EA000200621824008080211520000264 -:10653000000040218F480E1CA7AA001205600037FA -:106540002407000030FF00FF001FCF008F8B001CCE -:1065500000793825AFA70014916F00853C0808002A -:1065600091083D913C18DFFF31EE00C0370AFFFF74 -:10657000000E182B3C1F080097FF3D8400EA68249A -:10658000A3A800110003174001A248258FB90010ED -:10659000AFA900143C0A0800914A3D93A7BF00161A -:1065A0008FA80014032CC0243C0B01003C0F0FFFEC -:1065B000030B18253147000335EEFFFF010C68245B -:1065C00000071600006EF8243C09700001A2C825DF -:1065D00003E95825AFB90014AFAB00100E000076E8 -:1065E000A3A000158F8C0024260200089186000DC0 -:1065F00030C40020108000068FBF001C3C0508003E -:1066000094A53D8024B0FFFF3C010800A4303D80EC -:106610008FB0001803E0000827BD00208F980014F9 -:106620000118502B5540FFC7240700010A000DB682 -:1066300030FF00FF9382000427BDFFE0AFBF0018CA -:106640001040000F008050218F880024240B00058B -:106650008F890008910700008F8400200100282105 -:1066600030E3003F8F86002C106B000800003821BB -:10667000AFA900100E00040EAFAA0014A3800004FE -:106680008FBF001803E0000827BD00208D190018F7 -:106690003C0F08008DEF3D748F9800103C027FFF87 -:1066A0008D080014345FFFFF033F682401F8702158 -:1066B00001AE602301883821AFA900100E00040E3E -:1066C000AFAA00140A000E04A38000048F870024E0 -:1066D0003C05080094A53D923C0208008C423D8C8C -:1066E00090E6000D0005240030C300201060002C4F -:1066F000004440258F85001C00006021240B000110 -:1067000090A3008500004821240A00013C0F80006E -:1067100035EE00708DC70000AF8700308F580178CC -:106720000700FFFE3C038000347900708F380000C2 -:106730003C0508008CA500743C0D08008DAD007070 -:106740000307782300AF38210000102100EF302B21 -:1067500001A22021008618213C010800AC2700740A -:106760003C010800AC230070AF4B01483C19080005 -:106770008F393D94A7490144A74A0146AF59014CBE -:106780003C0B0800916B3D91A34B0152AF48015463 -:106790003C081000A74C015803E00008AF480178FE -:1067A0008F4B0E1C3C0A08008D4A3D7497490E160B -:1067B000974D0E1401456021312AFFFF0A000E2774 -:1067C00031A9FFFF8F8300249064000D30820020E8 -:1067D0001040002900000000000048210000502166 -:1067E000000040213C07800034EB00708D67000002 -:1067F000AF8700308F4C01780580FFFE3C0D800094 -:1068000035AC00708D8B00003C0508008CA5007431 -:106810003C0408008C8400700167302300A67821B6 -:106820000000102101E6C82B0082C021031970214D -:106830003C010800AC2F00743C010800AC2E007035 -:10684000AF4901483C0D08008DAD3D94A748014477 -:1068500024090040A74A01463C081000240AFF9181 -:10686000AF4D014CA34A0152AF490154A740015812 -:1068700003E00008AF4801788F490E1897460E12C2 -:1068800097450E1030CAFFFF0A000E5D30A8FFFFCB -:106890008F83002427BDFFF89064000D3082002014 -:1068A0001040003A00000000240B000100004821C5 -:1068B000240A00013C088000350700708CE30000CA -:1068C000AF8300308F4C01780580FFFE3C0E8000C6 -:1068D0003C04080090843DD035C700708CEC00006B -:1068E0003C0508008CA50074A3A400033C19080013 -:1068F0008F3900708FAD00000183302300A638214E -:10690000000010210322782100E6C02B01F860214D -:1069100001AE4025AFA800003C010800AC27007480 -:106920003C010800AC2C00709346010A3C040800AE -:1069300090843DD1A3A00002A3A600018FA3000074 -:106940003C0580FF3099007F34A2FFFF006278246D -:106950000019C60001F87025240D3000AF4E014C1F -:1069600027BD0008AF4D0154A7400158AF4B014867 -:10697000A7490144A74A01463C091000240AFF80A8 -:10698000A34A015203E00008AF4901788F4B0E186B -:1069900097460E1297450E1030CAFFFF0A000E915F -:1069A00030A9FFFF8F85001C2402008090A4008581 -:1069B000308300C0106200058F8600208F88000899 -:1069C0008F87000CACC800C8ACC700C403E0000847 -:1069D000000000003C0A0800254A39543C09080020 -:1069E00025293A203C08080025082DD43C0708003A -:1069F00024E73B343C06080024C637C43C050800A5 -:106A000024A5353C3C040800248431643C03080080 -:106A10002463385C3C020800244236303C01080004 -:106A2000AC2A3D503C010800AC293D4C3C0108001B -:106A3000AC283D483C010800AC273D543C0108000F -:106A4000AC263D643C010800AC253D5C3C010800DF -:106A5000AC243D583C010800AC233D683C010800D3 -:0C6A6000AC223D6003E0000800000000D4 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex new file mode 100644 index 000000000000..4c43b26af0a6 --- /dev/null +++ b/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex @@ -0,0 +1,5818 @@ +:10000000080001180800000000004A68000000C84D +:1000100000000000000000000000000008004A6826 +:100020000000001400004B30080000A00800000091 +:100030000000569400004B44080058200000008443 +:100040000000A1D808005694000001580000A25CEE +:100050000800321008000000000072D00000A3B4B5 +:10006000000000000000000000000000080072D046 +:100070000000002400011684080004900800040019 +:10008000000017D4000116A80000000000000000C6 +:100090000000000000000000000000000000000060 +:1000A000080000A80800000000003BFC00012E7CB6 +:1000B0000000000000000000000000000000000040 +:0800C000000000000000000038 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E322E31DF +:1000E0000000000006020102000000000000000302 +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C02080024424AA03C03080015 +:1002000024634B9CAC4000000043202B1480FFFD76 +:10021000244200043C1D080037BD7FFC03A0F021F0 +:100220003C100800261001183C1C0800279C4AA01E +:100230000E000168000000000000000D27470100CB +:1002400090E3000B2402001A94E5000814620028D1 +:10025000000020218CE200003C0308008C63004475 +:1002600094E60014000211C20002104030A4000203 +:10027000005A10212463000130A50004A446008028 +:100280003C010800AC23004410A000190004202BFE +:100290008F4202B804410008240400013C02080017 +:1002A0008C420060244200013C010800AC22006046 +:1002B00003E00008008010218CE2002094E3001687 +:1002C00000002021AF4202808CE20004A743028498 +:1002D000AF4202883C021000AF4202B83C02080064 +:1002E0008C42005C244200013C010800AC22005C0E +:1002F00003E00008008010212747010090E3000B75 +:100300002402000394E50008146200280000202164 +:100310008CE200003C0308008C63004494E6001467 +:10032000000211C20002104030A40002005A102145 +:100330002463000130A50004A44600803C010800AD +:10034000AC23004410A000190004202B8F4202B8F7 +:1003500004410008240400013C0208008C420060B3 +:10036000244200013C010800AC22006003E00008C8 +:10037000008010218CE2002094E300160000202170 +:10038000AF4202808CE20004A7430284AF4202889D +:100390003C021000AF4202B83C0208008C42005CF4 +:1003A000244200013C010800AC22005C03E000088C +:1003B000008010218F4301002402010050620003DD +:1003C000000311C20000000D000311C20002104022 +:1003D000005A1021A440008003E000080000102112 +:1003E0009362000003E00008AF80000003E0000813 +:1003F0000000102103E00008000010212402010089 +:1004000014820008000000003C0208008C4200FC3E +:10041000244200013C010800AC2200FC0A0000DD7F +:1004200030A200203C0208008C42008424420001DB +:100430003C010800AC22008430A2002010400008DB +:1004400030A300103C0208008C4201082442000145 +:100450003C010800AC22010803E000080000000095 +:1004600010600008000000003C0208008C420104FB +:10047000244200013C010800AC22010403E0000812 +:10048000000000003C0208008C42010024420001F0 +:100490003C010800AC22010003E00008000000005D +:1004A00027BDFFE8AFBF0010274401009483000878 +:1004B000306200041040001B306600028F4202B818 +:1004C00004410008240500013C0208008C42006041 +:1004D000244200013C010800AC2200600A0001290E +:1004E0008FBF00108C82002094830016000028210A +:1004F000AF4202808C820004A7430284AF4202888C +:100500003C021000AF4202B83C0208008C42005C82 +:10051000244200013C010800AC22005C0A000129D1 +:100520008FBF001010C00006006028218F4401001A +:100530000E0000CD000000000A0001282405000183 +:100540008F8200088F4301045043000700002821D8 +:100550008F4401000E0000CD000000008F42010416 +:10056000AF820008000028218FBF001000A01021DA +:1005700003E0000827BD001827BDFFE8AFBF001447 +:10058000AFB00010974201083043700024022000F1 +:100590001062000B286220011440002F000010217F +:1005A00024024000106200250000000024026000C8 +:1005B00010620026000010210A0001658FBF0014A0 +:1005C00027500100920200091040001A2403000184 +:1005D0003C0208008C420020104000160000182148 +:1005E0000E00049300000000960300083C0608007B +:1005F00094C64B5E8E0400188F8200209605000C76 +:1006000000031C0000661825AC440000AC45000443 +:1006100024040001AC400008AC40000CAC400010C9 +:10062000AC400014AC4000180E0004B8AC43001CF1 +:10063000000018210A000164006010210E0003254B +:10064000000000000A000164000010210E000EE905 +:1006500000000000000010218FBF00148FB00010B8 +:1006600003E0000827BD001827BDFFE0AFB2001867 +:100670003C036010AFBF001CAFB10014AFB000105E +:100680008C6450002402FF7F3C1A800000822024EA +:100690003484380C24020037AC6450003C1208004B +:1006A00026524AD8AF42000824020C80AF420024F0 +:1006B0003C1B80083C06080024C60324024010218D +:1006C0002404001D2484FFFFAC4600000481FFFDCC +:1006D000244200043C020800244204B03C0108000B +:1006E000AC224AE03C020800244202303C010800EF +:1006F000AC224AE43C020800244201743C03080096 +:100700002463032C3C040800248403D83C0508001F +:1007100024A538F03C010800AC224B403C02080004 +:10072000244202EC3C010800AC264B243C010800AA +:10073000AC254B343C010800AC234B3C3C01080089 +:10074000AC244B443C010800AC224B483C0108005F +:10075000AC234ADC3C010800AC204AE83C0108001C +:10076000AC204AEC3C010800AC204AF03C010800F7 +:10077000AC204AF43C010800AC204AF83C010800D7 +:10078000AC204AFC3C010800AC204B003C010800B6 +:10079000AC244B043C010800AC204B083C01080091 +:1007A000AC204B0C3C010800AC204B103C01080075 +:1007B000AC204B143C010800AC204B183C01080055 +:1007C000AC264B1C3C010800AC264B203C01080029 +:1007D000AC254B303C010800AC234B380E000623FF +:1007E000000000003C028000344200708C42000097 +:1007F000AF8200143C0308008C6300208F82000449 +:10080000104300043C0280000E00045BAF83000430 +:100810003C028000344600703C0308008C6300A05A +:100820003C0208008C4200A4104300048F84001492 +:100830003C010800AC2300A4A743009E8CCA000022 +:100840003C0308008C6300BC3C0208008C4200B8EA +:100850000144202300641821000040210064202B63 +:1008600000481021004410213C010800AC2300BCCA +:100870003C010800AC2200B88F5100003222000772 +:100880001040FFDCAF8A00148CC600003C05080055 +:100890008CA500BC3C0408008C8400B800CA30233E +:1008A00000A628210000102100A6302B0082202164 +:1008B00000862021322700013C010800AC2500BC45 +:1008C0003C010800AC2400B810E0001F32220002F6 +:1008D0008F420100AF4200208F420104AF4200A8C6 +:1008E0009342010B0E0000C6305000FF2E02001E86 +:1008F00054400004001010800E0000C90A000213CA +:1009000000000000005210218C4200000040F80955 +:1009100000000000104000053C0240008F4301042D +:100920003C026020AC4300143C024000AF4201385E +:100930003C0208008C420034244200013C010800C3 +:10094000AC220034322200021040000E3222000499 +:100950008F4201400E0000C6AF4200200E000295FB +:10096000000000003C024000AF4201783C02080059 +:100970008C420038244200013C010800AC220038BF +:10098000322200041040FF983C0280008F42018018 +:100990000E0000C6AF4200208F43018024020F00EA +:1009A00014620005000000008F420188A742009CED +:1009B0000A0002483C0240009362000024030050F9 +:1009C000304200FF144300083C0240000E00027B4E +:1009D00000000000544000043C0240000E000D7571 +:1009E000000000003C024000AF4201B83C02080099 +:1009F0008C42003C244200013C010800AC22003C37 +:100A00000A0001C83C0280003C0290003442000110 +:100A100000822025AF4400208F4200200440FFFECA +:100A20000000000003E00008000000003C0280001D +:100A3000344200010082202503E00008AF4400207A +:100A400027BDFFE0AFB10014AFB0001000808821D7 +:100A5000AFBF00180E00025030B000FF9362007D5F +:100A60000220202102028025A370007D8F70007477 +:100A70003C0280000E000259020280241600000988 +:100A80008FBF00188F4201F80440FFFE24020002CD +:100A9000AF5101C0A34201C43C021000AF4201F8B3 +:100AA0008FBF00188FB100148FB0001003E0000852 +:100AB00027BD002027BDFFE8AFBF0010974201848B +:100AC0008F440188304202001040000500002821B8 +:100AD0000E000FAA000000000A00028D240500018C +:100AE0003C02FF0004800005008218243C02040040 +:100AF000506200019362003E240500018FBF001088 +:100B000000A0102103E0000827BD0018A360002208 +:100B10008F4401400A00025E2405000127BDFFE862 +:100B2000AFBF0014AFB0001093620000304400FF6C +:100B300038830020388200300003182B0002102B6D +:100B40000062182410600003240200501482008008 +:100B50008FBF001493620005304200011040007CFA +:100B60008FBF0014934201482443FFFF2C6200050D +:100B7000104000788FB00010000310803C03080084 +:100B800024634A68004310218C42000000400008A2 +:100B9000000000000E0002508F4401408F70000CD6 +:100BA0008F4201441602000224020001AF62000CD1 +:100BB0000E0002598F4401408F420144145000043A +:100BC0008FBF00148FB000100A000F2027BD00183F +:100BD0008F62000C0A0003040000000097620010FE +:100BE0008F4301443042FFFF1462001A00000000EE +:100BF00024020001A76200108F4202380443001053 +:100C00008F4201403C02003F3446F0003C0560004A +:100C10003C04FFC08CA22BBC0044182400461024C6 +:100C20000002130200031D82106200390000000060 +:100C30008F4202380440FFF7000000008F4201405D +:100C4000AF4202003C021000AF4202380A00032209 +:100C50008FBF0014976200100A0003040000000018 +:100C60000E0002508F440140976200128F430144EE +:100C70003050FFFF1603000224020001A762001299 +:100C80000E0002598F4401408F42014416020004B5 +:100C90008FBF00148FB000100A00029127BD00180A +:100CA000976200120A00030400000000976200141B +:100CB0008F4301443042FFFF14620006240200010A +:100CC0008FBF00148FB00010A76200140A00124AF0 +:100CD00027BD0018976200141440001D8FBF001438 +:100CE0000A00031C00000000976200168F430144B5 +:100CF0003042FFFF1462000B240200018FBF00147A +:100D00008FB00010A76200160A000B1227BD001852 +:100D10009742007824420004A76200100A000322D0 +:100D20008FBF001497620016240300013042FFFFBA +:100D3000144300078FBF00143C0208008C4200706F +:100D4000244200013C010800AC2200708FBF001457 +:100D50008FB0001003E0000827BD001827BDFFE892 +:100D6000AFBF0014AFB000108F50010093620000BD +:100D700093430109304400FF2402001F106200A5C4 +:100D80002862002010400018240200382862000A5F +:100D90001040000C2402000B286200081040002CB8 +:100DA00000000000046000E52862000214400028F2 +:100DB00024020006106200268FBF00140A00041FE0 +:100DC0008FB000101062005E2862000B144000DC3F +:100DD0008FBF00142402000E106200738FB0001049 +:100DE0000A00041F00000000106200C028620039E1 +:100DF0001040000A2402008024020036106200CA5B +:100E000028620037104000B424020035106200C18F +:100E10008FBF00140A00041F8FB000101062002B57 +:100E20002862008110400006240200C82402003914 +:100E3000106200B48FBF00140A00041F8FB00010AE +:100E4000106200998FBF00140A00041F8FB00010B9 +:100E50003C0208008C420020104000B98FBF0014F3 +:100E60000E000493000000008F4201008F830020D9 +:100E70009745010C97460108AC6200008F420104BF +:100E80003C04080094844B5E00052C00AC62000416 +:100E90008F4201180006340000C43025AC620008FF +:100EA0008F42011C24040001AC62000C9342010A31 +:100EB00000A22825AC650010AC600014AC600018DE +:100EC000AC66001C0A0003F58FBF00143C0208004A +:100ED0008C4200201040009A8FBF00140E00049333 +:100EE00000000000974401083C03080094634B5E37 +:100EF0009745010C000422029746010E8F820020C4 +:100F0000000426000083202500052C003C030080FF +:100F100000A6282500832025AC400000AC4000043A +:100F2000AC400008AC40000CAC450010AC400014D4 +:100F3000AC400018AC44001C0A0003F42404000177 +:100F40009742010C14400015000000009362000558 +:100F50003042001014400011000000000E0002504A +:100F6000020020219362000502002021344200107B +:100F70000E000259A36200059362000024030020C2 +:100F8000304200FF1043006D020020218FBF00148B +:100F90008FB000100A000FC027BD00180000000D20 +:100FA0000A00041E8FBF00143C0208008C4200207F +:100FB000104000638FBF00140E0004930000000077 +:100FC0008F4201048F8300209744010C3C050800E8 +:100FD00094A54B5EAC6200009762002C00042400D4 +:100FE0003042FFFF008220253C02400E00A228254F +:100FF000AC640004AC600008AC60000CAC60001095 +:10100000AC600014AC600018AC65001C0A0003F46E +:10101000240400010E00025002002021A7600008F5 +:101020000E00025902002021020020210E00025E63 +:10103000240500013C0208008C42002010400040C2 +:101040008FBF00140E000493000000009742010CB3 +:101050008F8300203C05080094A54B5E000214001D +:10106000AC700000AC620004AC6000088F64004CFF +:101070003C02401F00A22825AC64000C8F62005087 +:1010800024040001AC6200108F620054AC620014B2 +:10109000AC600018AC65001C8FBF00148FB000104E +:1010A0000A0004B827BD0018240200205082002541 +:1010B0008FB000100E000F0A020020211040002007 +:1010C0008FBF0014020020218FB0001000002821E3 +:1010D0000A00025E27BD0018020020218FBF001405 +:1010E0008FB000100A00058027BD00189745010C3D +:1010F000020020218FBF00148FB000100A0005A04D +:1011000027BD0018020020218FB000100A0005C57D +:1011100027BD00189345010D020020218FB000105B +:101120000A00060F27BD0018020020218FBF0014FF +:101130008FB000100A0005EB27BD00188FBF001408 +:101140008FB0001003E0000827BD00188F4202781E +:101150000440FFFE2402000234840080AF440240B9 +:10116000A34202443C02100003E00008AF420278B0 +:101170003C04080094844B6A3C0208008C424B7487 +:101180003083FFFF000318C000431021AF42003C32 +:101190003C0208008C424B70AF4200383C020050C9 +:1011A00034420008AF4200300000000000000000A0 +:1011B000000000008F420000304200201040FFFD80 +:1011C000000000008F4204003C010800AC224B608C +:1011D0008F4204043C010800AC224B643C02002016 +:1011E000AF420030000000003C02080094424B680F +:1011F0003C03080094634B6C3C05080094A54B6EBF +:1012000024840001004310213083FFFF3C010800CB +:10121000A4224B683C010800A4244B6A1465000317 +:10122000000000003C010800A4204B6A03E0000815 +:10123000000000003C05000A27BDFFE80345282107 +:101240003C04080024844B50AFBF00100E00051D65 +:101250002406000A3C02080094424B523C0308005A +:1012600094634B6E3042000F244200030043180485 +:1012700024027FFF0043102B10400002AF83001CAC +:101280000000000D0E00042A000000003C020800CF +:1012900094424B5A8FBF001027BD001803E000088E +:1012A000A74200A23C02000A034210219443000618 +:1012B0003C02080094424B5A3C010800A4234B56C0 +:1012C000004310238F83001C00021400000214034B +:1012D0000043102B03E000083842000127BDFFE85F +:1012E000AFBF00103C02000A0342102194420006E6 +:1012F0003C010800A4224B560E00047700000000B9 +:101300005440FFF93C02000A8FBF001003E00008C0 +:1013100027BD001827BDFFE8AFBF00100E000477FF +:101320000000000010400003000000000E000485D3 +:10133000000000003C0208008C424B608FBF001090 +:1013400027430400AF4200383C0208008C424B6443 +:1013500027BD0018AF830020AF42003C3C020005CF +:10136000AF42003003E00008AF8000188F82001801 +:101370003C0300060002114000431025AF4200303C +:101380000000000000000000000000008F4200008C +:10139000304200101040FFFD27420400AF820020C1 +:1013A00003E00008AF8000183C0608008CC64B64C0 +:1013B0008F8500188F8300203C02080094424B5A0E +:1013C00027BDFFE024A50001246300202442000182 +:1013D00024C70020AFB10014AFB00010AFBF001899 +:1013E000AF850018AF8300203C010800A4224B5AAF +:1013F000309000FF3C010800AC274B6404C100089A +:101400000000882104E00006000000003C02080003 +:101410008C424B60244200013C010800AC224B602E +:101420003C02080094424B5A3C03080094634B680A +:101430000010202B004310262C42000100441025F0 +:10144000144000048F830018240200101462000F5F +:10145000000000000E0004A9241100013C03080054 +:1014600094634B5A3C02080094424B681462000398 +:10147000000000000E00042A000000001600000317 +:10148000000000000E000493000000003C03080070 +:1014900094634B5E3C02080094424B5C2463000161 +:1014A0003064FFFF3C010800A4234B5E148200035C +:1014B000000000003C010800A4204B5E1200000662 +:1014C000000000003C02080094424B5AA74200A2D0 +:1014D0000A00050B022010210E0004770000000016 +:1014E00010400004022010210E00048500000000BE +:1014F000022010218FBF00188FB100148FB0001090 +:1015000003E0000827BD00203084FFFF30A5FFFF67 +:101510000000182110800007000000003082000148 +:101520001040000200042042006518210A00051343 +:101530000005284003E000080060102110C00006EC +:1015400024C6FFFF8CA2000024A50004AC8200008A +:101550000A00051D2484000403E0000800000000C8 +:1015600010A0000824A3FFFFAC86000000000000CC +:10157000000000002402FFFF2463FFFF1462FFFA53 +:101580002484000403E0000800000000240200019D +:10159000AF62000CA7620010A7620012A7620014DD +:1015A00003E00008A76200163082007F034210218A +:1015B0003C08000E004818213C0208008C42002024 +:1015C00027BDFFD82407FF80AFB3001CAFB20018BF +:1015D000AFB10014AFB00010AFBF00200080802179 +:1015E00030B100FF0087202430D200FF1040002FD0 +:1015F00000009821AF44002C9062000024030050AA +:10160000304200FF1443000E000000003C020800BE +:101610008C4200E00202102100471024AF42002C4F +:101620003C0208008C4200E0020210213042007FA0 +:101630000342102100481021944200D43053FFFF90 +:101640000E000493000000003C02080094424B5E30 +:101650008F8300200011340000C2302500122C00BE +:101660003C02400000C2302534A50001AC700000EF +:101670008FBF0020AC6000048FB20018AC7300086C +:101680008FB10014AC60000C8FB3001CAC6500106F +:101690008FB00010AC60001424040001AC6000188E +:1016A00027BD00280A0004B8AC66001C8FBF0020CC +:1016B0008FB3001C8FB200188FB100148FB00010D0 +:1016C00003E0000827BD00289343010F2402001007 +:1016D0001062000E2865001110A0000724020012FD +:1016E000240200082405003A1062000600003021A0 +:1016F00003E0000800000000240500351462FFFC30 +:10170000000030210A000538000000008F420074FC +:1017100024420FA003E00008AF62000C27BDFFE8E1 +:10172000AFBF00100E00025E240500018FBF001045 +:1017300024020001A762001227BD00182402000144 +:1017400003E00008A360002227BDFFE0AFB1001452 +:10175000AFB00010AFBF001830B1FFFF0E00025055 +:10176000008080219362003F24030004304200FF88 +:101770001443000C02002021122000082402000A59 +:101780000E00053100000000936200052403FFFEF7 +:1017900000431024A362000524020012A362003F4C +:1017A000020020210E000259A360008116200003D0 +:1017B000020020210E0005950000000002002021FB +:1017C000322600FF8FBF00188FB100148FB00010B9 +:1017D000240500380A00053827BD002027BDFFE09A +:1017E000AFBF001CAFB20018AFB10014AFB0001013 +:1017F0000E000250008080210E0005310000000024 +:101800009362003F24120018305100FF123200038F +:101810000200202124020012A362003F936200050F +:101820002403FFFE004310240E000259A3620005AA +:10183000020020212405002016320007000030217C +:101840008FBF001C8FB200188FB100148FB0001032 +:101850000A00025E27BD00208FBF001C8FB2001857 +:101860008FB100148FB00010240500390A0005382C +:1018700027BD002027BDFFE8AFB00010AFBF0014A8 +:101880009742010C2405003600808021144000108E +:10189000304600FF0E00025000000000240200123B +:1018A000A362003F93620005344200100E00053130 +:1018B000A36200050E00025902002021020020212F +:1018C0000E00025E240500200A000604000000004D +:1018D0000E000538000000000E000250020020211A +:1018E000936200232403FF9F020020210043102461 +:1018F0008FBF00148FB00010A36200230A000259AA +:1019000027BD001827BDFFE0AFBF0018AFB100141E +:10191000AFB0001030B100FF0E00025000808021F7 +:10192000240200120E000531A362003F0E0002598E +:101930000200202102002021022030218FBF001848 +:101940008FB100148FB00010240500350A0005384F +:1019500027BD0020A380002C03E00008A380002DF9 +:101960008F4202780440FFFE8F820034AF42024073 +:1019700024020002A34202443C02100003E00008DB +:10198000AF4202783C0360008C6254003042000891 +:101990001440FFFD000000008C625408AF82000C70 +:1019A00024020052AC605408AC645430AC6254342D +:1019B0002402000803E00008AC6254003C0260000E +:1019C0008C42540030420008104000053C03600087 +:1019D0008C625400304200081440FFFD00000000FB +:1019E0008F83000C3C02600003E00008AC43540805 +:1019F00090A3000024020005008040213063003FD6 +:101A000000004821146200050000502190A2001C33 +:101A100094A3001E304900FF306AFFFFAD00000CA8 +:101A2000AD000010AD000024950200148D05001CCF +:101A30008D0400183042FFFF0049102300021100FE +:101A4000000237C3004038210086202300A2102B5B +:101A50000082202300A72823AD05001CAD04001838 +:101A6000A5090014A5090020A50A001603E0000836 +:101A7000A50A00228F4201F80440FFFE2402000262 +:101A8000AF4401C0A34201C43C02100003E00008BF +:101A9000AF4201F83C0208008C4200B427BDFFE8C9 +:101AA000AFBF001424420001AFB000103C01080099 +:101AB000AC2200B48F4300243C02001F30AA00FF78 +:101AC0003442FF8030D800FF006280240080F8217B +:101AD00030EF00FF1158003B01405821240CFF80DB +:101AE0003C19000A3163007F000310C00003194055 +:101AF000006218213C0208008C4200DC25680001CD +:101B0000310D007F03E21021004310213043007F9C +:101B100003431821004C102400794821AF420024CF +:101B20008D220024016C1824006C7026AD22000C5C +:101B30008D220024310800FFAD22001095220014F0 +:101B4000952300208D27001C3042FFFF3063FFFFEC +:101B50008D2600180043102300021100000227C345 +:101B60000040282100C4302300E2102B00C23023A3 +:101B700000E53823AD27001CAD2600189522002073 +:101B8000A522001495220022154B000AA52200165A +:101B90008D2300248D220008254600013145008058 +:101BA0001462000430C4007F108F000238AA008045 +:101BB00000C0502151AF000131C800FF1518FFC906 +:101BC000010058218F8400343082007F03421821A5 +:101BD0003C02000A006218212402FF8000822024B7 +:101BE000AF440024A06A0079A06A00838C62005090 +:101BF0008F840034AC6200708C6500743C027FFFFF +:101C00003442FFFF00A228240E00066BAC6500746E +:101C1000AF5000248FBF00148FB0001003E0000805 +:101C200027BD001827BDFFC0AFBE0038AFB70034D6 +:101C3000AFB5002CAFB20020AFB1001CAFB00018A0 +:101C4000AFBF003CAFB60030AFB40028AFB3002444 +:101C50008F4500248F4600288F43002C3C02001F34 +:101C60003442FF800062182400C230240080A82182 +:101C7000AFA3001400A2F0240E00062FAFA60010A0 +:101C80003C0208008C4200E02410FF8003608821A1 +:101C900002A2102100501024AF4200243C02080090 +:101CA0008C4200E002A210213042007F0342182142 +:101CB0003C02000A00629021924200D293630084A9 +:101CC000305700FF306300FF24020001106200342F +:101CD000036020212402000214620036000000008C +:101CE0000E001216024028219223008392220083C4 +:101CF0003063007F3042007F000210C000031940B3 +:101D0000006218213C0208008C4200DC02A2102173 +:101D10000043382100F01024AF42002892250078BB +:101D20009224008330E2007F034218213C02000C21 +:101D300014850007006280212402FFFFA24200F107 +:101D40002402FFFFA64200F20A0007272402FFFF39 +:101D500096020020A24200F196020022A64200F262 +:101D60008E020024AE4200F492220083A24200F0D0 +:101D70008E4200C8AE4200FC8E4200C4AE4200F863 +:101D80008E220050AE4201008E4200CCAE420104D1 +:101D9000922200853042003F0A0007823442004010 +:101DA0000E00123902402821922200850A00078283 +:101DB0003042003F936200852403FFDF3042003F42 +:101DC000A36200859362008500431024A36200850E +:101DD0009363008393620078307400FF304200FF09 +:101DE00010540036240AFF803C0C000C3283007F24 +:101DF000000310C000031940006218213C020800D3 +:101E00008C4200DC268800013109007F02A21021EB +:101E10000043382130E2007F0342182100EA1024F9 +:101E2000AF420028006C80218E020024028A182410 +:101E3000006A5826AE02000C8E020024310800FF12 +:101E4000AE02001096020014960300208E07001CBC +:101E50003042FFFF3063FFFF8E060018004310235F +:101E600000021100000227C30040282100C43023D3 +:101E700000E2102B00C2302300E53823AE07001C1F +:101E8000AE06001896020020A60200149602002258 +:101E9000A602001692220079304200FF105400077B +:101EA0000000000051370001316800FF92220078E5 +:101EB000304200FF1448FFCD0100A0219222008390 +:101EC000A22200798E2200500A0007E2AE220070A2 +:101ED000A22200858E22004C2405FF80AE42010C18 +:101EE0009222008534420020A2220085924200D135 +:101EF0003C0308008C6300DC305400FF3C02080007 +:101F00008C4200E400143140001420C002A31821C8 +:101F100000C4202102A210210064382100461021B3 +:101F20000045182400E52824AF450028AF43002CC5 +:101F30003042007F924400D030E3007F03422821EA +:101F4000034318213C02000C006280213C02000E79 +:101F5000309600FF00A298211296002A000000008F +:101F60008E02000C02002021026028211040002572 +:101F7000261000280E00064A000000009262000DA4 +:101F800026830001307400FF3042007FA262000D02 +:101F90002404FF801697FFF0267300203C020800FF +:101FA0008C4200DC0000A02102A210210044102479 +:101FB000AF4200283C0208008C4200E43C030800C9 +:101FC0008C6300DC02A2102100441024AF42002CDC +:101FD0003C0208008C4200E402A318213063007F19 +:101FE00002A210213042007F034220210343182126 +:101FF0003C02000C006280213C02000E0A0007A493 +:10200000008298218E4200D8AE2200508E4200D825 +:10201000AE22007092250083924600D19223008365 +:10202000924400D12402FF8000A228243063007F64 +:10203000308400FF00A628250064182A10600002E2 +:1020400030A500FF38A50080A2250083A2250079D5 +:102050000E00063D000000009222007E02A020211A +:10206000A222007A8E2300743C027FFF3442FFFFDD +:10207000006218240E00066BAE2300748FA20010BD +:10208000AF5E00248FBF003CAF4200288FBE0038F7 +:102090008FA200148FB700348FB600308FB5002C9C +:1020A0008FB400288FB300248FB200208FB1001CA2 +:1020B0008FB0001827BD004003E00008AF42002C9D +:1020C00090A2000024420001A0A200003C030800EE +:1020D0008C6300F4304200FF1443000F0080302175 +:1020E000A0A000003C0208008C4200E48F84003471 +:1020F000008220213082007F034218213C02000C24 +:10210000006218212402FF8000822024ACC300005A +:1021100003E00008AF4400288C8200002442002025 +:1021200003E00008AC82000094C200003C080800F4 +:10213000950800CA30E7FFFF008048210102102106 +:10214000A4C2000094C200003042FFFF00E2102B46 +:1021500054400001A4C7000094A200003C03080002 +:102160008C6300CC24420001A4A2000094A20000D1 +:102170003042FFFF544300078F8600280107102BD1 +:10218000A4A000005440000101003821A4C70000B1 +:102190008F8600288CC4001CAF44003C94A2000031 +:1021A0008F43003C3042FFFF000210C00062182144 +:1021B000AF43003C8F42003C008220231880000483 +:1021C000000000008CC200180A00084324420001ED +:1021D0008CC20018AF4200383C020050344200105C +:1021E000AF420030000000000000000000000000CE +:1021F0008F420000304200201040FFFD0000000030 +:102200008F420404AD2200048F420400AD2200007E +:102210003C020020AF42003003E000080000000054 +:1022200027BDFFE0AFB20018AFB10014AFB000108F +:10223000AFBF001C94C2000000C080213C12080007 +:10224000965200C624420001A60200009603000038 +:1022500094E2000000E03021144300058FB100300B +:102260000E000818024038210A000875000000001E +:102270008C8300048C820004244200400461000727 +:10228000AC8200048C8200040440000400000000C2 +:102290008C82000024420001AC8200009602000003 +:1022A0003042FFFF50520001A600000096220000BD +:1022B00024420001A62200008F82002896230000FD +:1022C00094420016144300048FBF001C2402000136 +:1022D000A62200008FBF001C8FB200188FB100141F +:1022E0008FB0001003E0000827BD00208F89002870 +:1022F00027BDFFE0AFBF00188D220028274804004B +:1023000030E700FFAF4200388D22002CAF8800304C +:10231000AF42003C3C020005AF420030000000002C +:1023200000000000000000000000000000000000AD +:10233000000000008C82000C8C82000CAD020000BA +:102340008C820010AD0200048C820018AD020008DF +:102350008C82001CAD02000C8CA20014AD02001097 +:102360008C820020AD02001490820005304200FFF4 +:1023700000021200AD0200188CA20018AD02001C71 +:102380008CA2000CAD0200208CA20010AD02002433 +:102390008CA2001CAD0200288CA20020AD02002CF3 +:1023A000AD060030AD000034978300263402FFFFF5 +:1023B00014620002006020213404FFFF10E00011CD +:1023C000AD04003895230036952400362402000120 +:1023D0003063FFFF000318C20069182190650040B8 +:1023E000308400070082100400451025A0620040E0 +:1023F0008F820028944200563042FFFF0A0008DC1A +:10240000AD02003C952300369524003624020001DD +:102410003063FFFF000318C2006918219065004077 +:1024200030840007008210040002102700451024A9 +:10243000A0620040AD00003C000000000000000071 +:10244000000000003C02000634420040AF42003071 +:102450000000000000000000000000008F420000AB +:10246000304200101040FFFD8F860028AF880030FA +:1024700024C2005624C7003C24C4002824C50032CE +:1024800024C600360E000856AFA200108FBF0018F9 +:1024900003E0000827BD00208F8300243C060800CD +:1024A0008CC600E88F82003430633FFF0003198040 +:1024B00000461021004310212403FF803046007F96 +:1024C00000431024AF420028034618213C02000CB0 +:1024D0000062302190C2000D30A500FF00003821BD +:1024E00034420010A0C2000D8F8900288F8A00247A +:1024F00095230036000A13823048000324020001AD +:10250000A4C3000E1102000B2902000210400005B6 +:10251000240200021100000C240300010A0009201B +:102520000000182111020006000000000A00092026 +:10253000000018218CC2002C0A000920244300014D +:102540008CC20014244300018CC200180043102BDD +:1025500050400009240700012402002714A20003B0 +:10256000000000000A00092C240700019522003E0B +:1025700024420001A522003E000A138230430003DA +:102580002C62000210400009008028211460000421 +:102590000000000094C200360A00093C3046FFFFEC +:1025A0008CC600380A00093C008028210000302138 +:1025B0003C04080024844B780A00088900000000CD +:1025C000274901008D22000C9523000601202021BF +:1025D000000216023046003F3063FFFF240200274E +:1025E00000C0282128C7002810C2000EAF83002495 +:1025F00010E00008240200312402002110C200096A +:102600002402002510C200079382002D0A00095BF6 +:102610000000000010C200059382002D0A00095B33 +:10262000000000000A0008F4000000000A0006266E +:102630000000000095230006912400058D25000C64 +:102640008D2600108D2700188D28001C8D29002054 +:10265000244200013C010800A4234B7E3C010800F9 +:10266000A0244B7D3C010800AC254B843C010800B4 +:10267000AC264B883C010800AC274B903C0108007D +:10268000AC284B943C010800AC294B9803E00008AF +:10269000A382002D8F87002827BDFFC0AFB3003471 +:1026A000AFB20030AFB1002CAFB00028AFBF0038E0 +:1026B0003C0208008C4200D094E3003030B0FFFFB1 +:1026C000005010073045FFFF3063FFFF00C0982126 +:1026D000A7A200103C110800963100C614A3000602 +:1026E0003092FFFF8CE2002424420030AF42003CD5 +:1026F0000A0009948CE2002094E200323042FFFF8D +:1027000054A2000827A400188CE2002C24420030B8 +:10271000AF42003C8CE20028AF4200380A0009A218 +:102720008F84002827A5001027A60020022038212A +:102730000E000818A7A000208FA200182442003025 +:10274000AF4200388FA2001CAF42003C8F840028AB +:102750003C020005AF42003094820034274304005D +:102760003042FFFF0202102B14400007AF830030FD +:1027700094820054948300340202102100431023F9 +:102780000A0009B63043FFFF94830054948200345A +:102790000223182100501023006218233063FFFF2A +:1027A000948200163042FFFF144300030000000033 +:1027B0000A0009C424030001948200163042FFFF7E +:1027C0000043102B104000058F82003094820016C9 +:1027D000006210233043FFFF8F820030AC530000B3 +:1027E000AC400004AC520008AC43000C3C020006B4 +:1027F00034420010AF420030000000000000000032 +:10280000000000008F420000304200101040FFFD29 +:10281000001018C2006418219065004032040007BF +:10282000240200018FBF00388FB300348FB2003014 +:102830008FB1002C8FB000280082100400451025B5 +:1028400027BD004003E00008A062004027BDFFA8AC +:10285000AFB60050AFB5004CAFB40048AFB30044C2 +:10286000AFB1003CAFBF0054AFB20040AFB00038D2 +:102870008C9000003C0208008C4200E88F860034F7 +:10288000960300022413FF8000C2302130633FFF13 +:102890000003198000C3382100F3102490B2000017 +:1028A000AF42002C9203000230E2007F034230214D +:1028B0003C02000E00C28821306300C024020040A8 +:1028C0000080A82100A0B021146200260000A021F1 +:1028D0008E3400388E2200181440000224020001B9 +:1028E000AE2200189202000D304200201440001564 +:1028F0008F8200343C0308008C6300DC001238C077 +:10290000001231400043102100C730210046382119 +:1029100030E300073C02008030E6007800C230253A +:102920000343182100F31024AF4208002463090078 +:10293000AF4608108E2200188C6300080043102157 +:10294000AE2200188E22002C8E2300182442000193 +:102950000062182B1060003D000000000A000A7899 +:1029600000000000920300022402FFC00043102474 +:10297000304200FF1440000524020001AE2200187E +:10298000962200360A000A613054FFFF8E2200149E +:1029900024420001AE22001892020000000216003C +:1029A0000002160304410029000000009602000204 +:1029B00027A4001000802821A7A20016960200027A +:1029C00024070001000030213042FFFFAF820024C5 +:1029D0000E000889AFA0001C960300023C0408000A +:1029E0008C8400E88F82003430633FFF000319803D +:1029F00000441021004310213043007F3C05000CAF +:102A00000053102403431821AF4200280065182109 +:102A10009062000D001221403042007FA062000D44 +:102A20003C0308008C6300E48F82003400431021D3 +:102A30000044382130E2007F03421021004510217C +:102A400000F31824AF430028AEA200009222000D2C +:102A5000304200101040001302A020218F83002874 +:102A60008EA40000028030219462003E2442FFFFC9 +:102A7000A462003E948400029625000E3084FFFF7D +:102A80000E00097330A5FFFF8F82002894430034A5 +:102A90009622000E1443000302A02021240200010C +:102AA000A382002C02C028210E0007FE00000000B7 +:102AB0008FBF00548FB600508FB5004C8FB40048C4 +:102AC0008FB300448FB200408FB1003C8FB000380C +:102AD00003E0000827BD00588F82002827BDFFD0E3 +:102AE000AFB40028AFB20020AFBF002CAFB30024BA +:102AF000AFB1001CAFB00018904400D0904300D19B +:102B00000000A021309200FFA3A30010306300FF5B +:102B10008C5100D88C5300DC1072002B2402000171 +:102B20003C0308008C6300E493A400108F820034FF +:102B30002406FF800004214000431021004410219E +:102B40003043007F00461024AF4200280343182181 +:102B50003C02000C006218218C62000427A40014BF +:102B600027A50010022280210270102304400015C6 +:102B7000AFA300149062000D00C21024304200FF89 +:102B800014400007020088219062000D344200408A +:102B90000E0007FEA062000D0A000ABD93A20010FD +:102BA0000E0009E1241400018F830028AC7000D8C6 +:102BB00093A20010A06200D193A200101452FFD87B +:102BC0000000000024020001168200048FBF002CC8 +:102BD0000E000626000000008FBF002C8FB40028D6 +:102BE0008FB300248FB200208FB1001C8FB000186B +:102BF00003E0000827BD003027BDFFD8AFB3001C9D +:102C0000AFB20018AFB10014AFB00010AFBF0020DA +:102C10000080982100E0802130B1FFFF0E00049376 +:102C200030D200FF000000000000000000000000A3 +:102C30008F820020AC510000AC520004AC5300085D +:102C4000AC40000CAC400010AC400014AC4000188C +:102C50003C03080094634B5E02038025AC50001CCB +:102C6000000000000000000000000000240400013B +:102C70008FBF00208FB3001C8FB200188FB10014DB +:102C80008FB000100A0004B827BD002827BDFFE858 +:102C9000AFB00010AFBF001430A5FFFF30C600FF7B +:102CA0000080802124020C80AF420024000000003C +:102CB0000000000000000000000000000000000014 +:102CC0000E000ACC000000003C040800248400E050 +:102CD0008C8200002403FF808FBF001402021021A9 +:102CE00000431024AF4200248C8200003C03000A01 +:102CF000020280213210007F035010218FB000109B +:102D00000043102127BD001803E00008AF8200280F +:102D100027BDFFE8AFBF00108F4401403C0308000F +:102D20008C6300E02402FF80AF840034008318210C +:102D300000621024AF4200243C02000803424021FC +:102D4000950500023063007F3C02000A034318210E +:102D50000062182130A5FFFF3402FFFF0000302180 +:102D60003C07602010A20006AF8300282402FFFF6A +:102D7000A5020002946500D40E000AF130A5FFFF01 +:102D80008FBF001024020C8027BD001803E000084C +:102D9000AF4200243C020008034240219502000299 +:102DA0003C0A0800954A00C63046FFFF14C00007E1 +:102DB0003402FFFF8F8200288F8400343C0760209C +:102DC000944500D40A000B5A30A5FFFF10C200241E +:102DD0008F87002894E2005494E400163045FFFFEA +:102DE00000A6102300A6182B3089FFFF10600004F6 +:102DF0003044FFFF00C51023012210233044FFFFA1 +:102E0000008A102B1040000C012A1023240200011C +:102E1000A50200162402FFFFA502000294E500D4DB +:102E20008F8400340000302130A5FFFF3C07602074 +:102E30000A000AF1000000000044102A10400008B7 +:102E4000000000009502001630420001104000040E +:102E5000000000009742007E24420014A5020016E4 +:102E600003E00008000000008F84002827BDFFE079 +:102E7000AFBF0018948200349483003E1060001AA3 +:102E80003048FFFF9383002C2402000114620027C6 +:102E90008FBF00188F820028000818C23108000771 +:102EA000006218212447003A244900542444002099 +:102EB000244500302446003490620040304200FF38 +:102EC0000102100730420001104000168FBF0018A9 +:102ED0000E000856AFA900108F82002894420034DB +:102EE0000A000B733048FFFF94830036948200344D +:102EF0001043000E8FBF001894820036A482003465 +:102F000094820056A48200548C82002CAC8200244F +:102F100094820032A48200309482003CA482003A61 +:102F20008FBF00180A000B3327BD002003E0000804 +:102F300027BD002027BDFFE8AFBF00108F4A01006A +:102F40003C0508008CA500E03C02080090424B8440 +:102F50003C0C0800958C4B7E01452821304B003FEE +:102F600030A2007F03424021396900323C02000A4E +:102F70003963003F2C630001010240212D2900012B +:102F80002402FF8000A2282401234825AF8A0034B0 +:102F900000801821AF450024000030210080282146 +:102FA00024070001AF8800283C04080024844B78E3 +:102FB000AF8C002415200007A380002D24020020E0 +:102FC0005562000F006020213402FFFF5582000C83 +:102FD000006020212402002015620005000000008E +:102FE0008C6300142402FFFF106200070000000041 +:102FF0000E000889000000000A000BD0000000004D +:103000000E0008F4016028210E000B68000000008B +:103010008FBF001024020C8027BD001803E00008B9 +:10302000AF4200243C0208008C4200E027BDFFA014 +:10303000AFB1003C008210212411FF80AFBE0058C8 +:10304000AFB70054AFB20040AFB00038AFBF005CC4 +:10305000AFB60050AFB5004CAFB40048AFB30044BA +:10306000005110248F4800248F4900288F470028E2 +:10307000AF4200243C0208008C4200E00080902116 +:1030800024060006008210213042007F03421821EE +:103090003C02000A006280213C02001F3442FF8093 +:1030A00000E2382427A40010260500F00122F024B5 +:1030B0000102B8240E00051DAFA700308FA2001832 +:1030C000AE0200C48FA2001CAE0200C88FA2002472 +:1030D000AE0200CC93A40010920300D12402FF8022 +:1030E0000082102400431025304900FF3083007F08 +:1030F0003122007F0062102A10400004000310C03B +:1031000001311026304900FF000310C000031940B0 +:10311000006218213C0208008C4200DC920400D2BC +:10312000024210210043102100511024AF42002818 +:1031300093A300103063007F000310C00003194008 +:10314000006218213C0208008C4200DC024210217F +:10315000004310213042007F034218213C02000C42 +:10316000006240218FA300142402FFFF1062003090 +:10317000309500FF93A2001195030014304400FF26 +:103180003063FFFF0064182B1060000D000000008A +:10319000950400148D07001C8D0600183084FFFF75 +:1031A00000442023000421000000102100E4382105 +:1031B00000E4202B00C230210A000C4A00C4302158 +:1031C000950400148D07001C8D0600183084FFFF45 +:1031D000008220230004210000001021008018211B +:1031E00000C2302300E4202B00C4302300E3382346 +:1031F000AD07001CAD06001893A20011A502001433 +:1032000097A20012A50200168FA20014AD020010B2 +:103210008FA20014AD02000C93A20011A5020020A1 +:1032200097A20012A50200228FA20014AD02002472 +:103230002406FF80024610243256007FAF4200244D +:10324000035618213C02000A006280218E02004CC5 +:103250008FA200203124007F000428C0AE0200505D +:103260008FA200200004214000852821AE020070BA +:1032700093A2001001208821A202008393A20010D3 +:10328000A2020079920200853042003FA20200852E +:103290003C0208008C4200DC024210210045102153 +:1032A00000461024AF42002C3C0208008C4200E48F +:1032B0003C0308008C6300DC024210210044102112 +:1032C00000461024AF4200283C0208008C4200E473 +:1032D00002431821006518210242102100441021E8 +:1032E0003042007F3063007F93A50010034220210D +:1032F000034318213C02000E006240213C02000CF6 +:1033000010B1008C008248213233007F1660001912 +:103310002404FF803C0208008C4200DC02421021A1 +:1033200000441024AF42002C3C0208008C4200E410 +:103330003C0308008C6300DC02421021004410248E +:10334000AF4200283C0208008C4200E402431821EE +:103350003063007F024210213042007F034220216F +:10336000034318213C02000E006240213C02000C85 +:10337000008248219124000D2414FF8000001021B8 +:1033800000942025A124000D950400029505001449 +:103390008D07001C3084FFFF30A5FFFF8D0600184D +:1033A000008520230004210000E4382100C23021E0 +:1033B00000E4202B00C43021AD07001CAD0600182E +:1033C00095020002A5020014A50000168D02000857 +:1033D000AD0200108D020008AD02000C9502000243 +:1033E000A5020020A50000228D020008AD020024E5 +:1033F0009122000D30420040104000422622000180 +:103400003C0208008C4200E0A3B300283C10000AF4 +:103410000242102100541024AF4200243C02080054 +:103420008C4200E0A380002C27A4002C0242102133 +:103430003042007F03421821007018218C6200D8AE +:103440008D26000427A50028AFA9002C00461021D6 +:10345000AC6200D80E0009E1AF83002893A30028D6 +:103460008F8200280E000626A04300D10E000B68B4 +:103470000000000002541024AF4200243C02080067 +:103480008C4200DC00132940001320C000A420213E +:10349000024210210044102100541024AF42002C9D +:1034A0003C0208008C4200E43C0308008C6300DC12 +:1034B00003563021024210210045102100541024EF +:1034C000AF4200283C0208008C4200E4024318216D +:1034D0000064182102421021004510213042007F73 +:1034E0003063007F03422021034318213C02000E79 +:1034F000006240213C02000C00D080210082482163 +:10350000262200013043007F14750005304400FF7F +:103510002403FF800223102400431026304400FFC0 +:1035200093A2001000808821250800281444FF760B +:103530002529002093A400108FA300142402FFFF6C +:103540001062000A308900FF2482000124830001F8 +:103550003042007F14550005306900FF2403FF80CE +:103560000083102400431026304900FF92020078A7 +:10357000305300FF11330032012088213C02080043 +:103580008C4200DC3225007F000520C00005294068 +:1035900000A42021024210212406FF8000441021B3 +:1035A00000461024AF42002C3C0308008C6300DC72 +:1035B0003C0208008C4200E4024318210242102120 +:1035C0000045102100641821004610243063007F5C +:1035D000AF420028034318213C02000E0062402144 +:1035E0003C0208008C4200E48D06000C0100202102 +:1035F00002421021004510213042007F0342182171 +:103600003C02000C0062482110C0000D012028215E +:103610000E00064A000000002402FF800222182447 +:1036200026240001006228263082007F1455000203 +:10363000308300FF30A300FF1473FFD000608821A7 +:103640008E0300743C027FFF3442FFFF00621824A7 +:10365000AE0300740E00066B02402021AF57002419 +:103660008FA20030AF5E00288FBF005C8FBE005875 +:103670008FB700548FB600508FB5004C8FB4004800 +:103680008FB300448FB200408FB1003C8FB0003840 +:1036900027BD006003E00008AF42002C27BDFFD823 +:1036A000AFB1001CAFBF0020AFB000182751018898 +:1036B000922200032408FF803C03000A3047007F69 +:1036C000A3A700108F4601803C0208008C4200E056 +:1036D000AF86003400C2282100A81024AF42002485 +:1036E0009224000030A2007F0342102100431021E9 +:1036F000AF8200283084007F24020002148200255B +:10370000000719403C0208008C4200E400C210216E +:103710000043282130A2007F0342182100A8102472 +:10372000AF4200283C02000C006218219062000D9C +:10373000AFA3001400481025A062000D8FA3001451 +:103740009062000D304200405040006A8FBF002060 +:103750008F860028A380002C27A400148CC200D8D8 +:103760008C63000427A50010004310210E0009E11E +:10377000ACC200D893A300108F8200280E0006264A +:10378000A04300D10E000B68000000000A000E0BE1 +:103790008FBF00200E00062F00C020210E00063D26 +:1037A000000000003C020008034280219223000137 +:1037B0009202007B1443004F8FBF00209222000032 +:1037C0003044007F24020004108200172882000584 +:1037D00010400006240200052402000310820007A6 +:1037E0008FB1001C0A000E0C0000000010820012B5 +:1037F0008FBF00200A000E0C8FB1001C92050083C1 +:10380000920600788E0700748F84003430A500FF84 +:1038100000073E0230C600FF0E00067330E7007F4F +:103820000A000E0B8FBF00200E000BD78F840034D0 +:103830000A000E0B8FBF002024020C80AF42002430 +:103840009202003E30420040104000200000000084 +:103850009202003E00021600000216030441000618 +:10386000000000008F8400340E0005A024050093A2 +:103870000A000E0B8FBF00209202003F24030018A5 +:10388000304200FF1443000C8F84003424050039BB +:103890000E000538000030210E0002508F840034E5 +:1038A00024020012A202003F0E0002598F8400344D +:1038B0000A000E0B8FBF0020240500360E000538CD +:1038C000000030210A000E0B8FBF00200E000250B6 +:1038D0008F8400349202000534420020A2020005C9 +:1038E0000E0002598F8400340E000FC08F84003404 +:1038F0008FBF00208FB1001C8FB0001824020C80F5 +:1039000027BD002803E00008AF42002427BDFFE8E0 +:10391000AFB00010AFBF001427430100946200084D +:103920000002140000021403044100020000802180 +:103930002410000194620008304200801040001AF8 +:10394000020010219462000830422000104000164E +:10395000020010218C6300183C021C2D344219ED2A +:10396000240600061062000F3C0760213C0208009C +:103970008C4200D4104000078F8200288F830028DB +:10398000906200623042000F34420040A062006248 +:103990008F8200288F840034944500D40E000AF1F1 +:1039A00030A5FFFF020010218FBF00148FB0001060 +:1039B00003E0000827BD001827BDFFE0AFB10014E9 +:1039C000AFB00010A380002CAFBF00188F450100DE +:1039D0003C0308008C6300E02402FF80AF850034C4 +:1039E00000A318213064007F0344202100621824C2 +:1039F0003C02000A00822021AF430024275001002E +:103A00008E0200148C8300DCAF8400280043102356 +:103A100018400004000088218E0200140E000A8461 +:103A2000AC8200DC9202000B24030002304200FF53 +:103A30001443002F0000000096020008304300FFEE +:103A40002402008214620005240200840E00093E54 +:103A5000000000000A000E97000000001462000938 +:103A6000240200818F8200288F8400343C0760216B +:103A7000944500D49206000530A5FFFF0A000E868B +:103A800030C600FF14620027000000009202000A06 +:103A9000304300FF306200201040000430620040DC +:103AA0008F8400340A000E82240600401040000477 +:103AB000000316008F8400340A000E8224060041A1 +:103AC00000021603044100178F84003424060042CC +:103AD0008F8200283C076019944500D430A5FFFF71 +:103AE0000E000AF1000000000A000E97000000001E +:103AF0009202000B24030016304200FF1043000620 +:103B0000000000009202000B24030017304200FF67 +:103B100014430004000000000E000E11000000001D +:103B2000004088210E000B68000000009202000A8D +:103B3000304200081040000624020C808F850028C7 +:103B40003C0400080E0011EE0344202124020C80E6 +:103B5000AF4200248FBF0018022010218FB0001048 +:103B60008FB1001403E0000827BD002027BDFFE847 +:103B7000AFBF0014AFB000108F5000243C0308000A +:103B80008C6300E08F4501002402FF8000A3182110 +:103B90003064007F03442021006218243C02000AA4 +:103BA00000822021AF850034AF4300249082006260 +:103BB000AF8400283042000F34420050A0820062DF +:103BC0003C02001F3442FF800E00062602028024C1 +:103BD000AF5000248FBF00148FB0001003E0000826 +:103BE00027BD00183C0208008C4200201040001D38 +:103BF0002745010090A300093C0200080342202150 +:103C000024020018546200033C0200080A000ED887 +:103C10002402000803422021240200161462000539 +:103C20002402001724020012A082003F0A000EE2C4 +:103C300094A700085462000694A700089362000548 +:103C40002403FFFE00431024A362000594A700088C +:103C500090A6001B8CA4000094A500060A000ACCC4 +:103C600000073C0003E000080000000027440100BA +:103C700094820008304500FF38A3008238A20084F7 +:103C80002C6300012C420001006218251060000620 +:103C9000240200839382002D1040000D00000000DC +:103CA0000A000B9B0000000014A2000524A2FF8064 +:103CB0008F4301043C02602003E00008AC43001481 +:103CC000304200FF2C420002104000032402002278 +:103CD0000A000E3C0000000014A2000300000000D7 +:103CE0000A000EA9000000000A000EC70000000034 +:103CF0009363007E9362007A144300090000202140 +:103D00009362000024030050304200FF144300047B +:103D1000240400019362007E24420001A362007E1D +:103D200003E00008008010218F4201F80440FFFEEC +:103D300024020002AF4401C0A34201C43C021000AF +:103D400003E00008AF4201F827BDFFE8AFBF001055 +:103D50009362003F2403000A304200FF14430046F0 +:103D6000000000008F6300548F62004C1062007DE1 +:103D7000036030219362000024030050304200FFB2 +:103D80001443002F000000008F4401403C02080053 +:103D90008C4200E02403FF800082102100431024A5 +:103DA000AF4200243C0208008C4200E08F650054C2 +:103DB0003C03000A008220213084007F034410214C +:103DC00000431021AC4501089762003C8F63004C12 +:103DD0003042FFFF0002104000621821AF63005C18 +:103DE0008F6300548F64004C9762003C006418237A +:103DF0003042FFFF00031843000210400043102A26 +:103E000010400006000000008F6200548F63004CD9 +:103E1000004310230A000F58000210439762003C31 +:103E20003042FFFF00021040ACC2006424020001D7 +:103E3000A0C0007CA0C2008424020C80AF420024F9 +:103E40000E000F0A8F440140104000478FBF001042 +:103E50008F4301408F4201F80440FFFE240200021C +:103E6000AF4301C0A34201C43C021000AF4201F8BD +:103E70000A000FA88FBF00109362003F24030010B8 +:103E8000304200FF14430004000000008F44014052 +:103E90000A000F94000028219362003F24030016BB +:103EA000304200FF1443000424020014A362003FC8 +:103EB0000A000FA2000000008F62004C8F630050C8 +:103EC00000431023044100288FBF0010936200813B +:103ED00024420001A3620081936200812C4200040D +:103EE00014400010000000009362003F240300040F +:103EF000304200FF14430006000000008F440140E0 +:103F00008FBF0010240500930A0005A027BD0018EC +:103F10008F440140240500938FBF00100A00060F54 +:103F200027BD00188F4401400E0002500000000021 +:103F30008F6200542442FFFFAF6200548F62005032 +:103F40002442FFFFAF6200500E0002598F4401402F +:103F50008F4401408FBF0010240500040A00025E58 +:103F600027BD00188FBF001003E0000827BD001810 +:103F70008F4201889363007E00021402304400FFE8 +:103F8000306300FF1464000D0000000093620080A5 +:103F9000304200FF1044000900000000A3640080CC +:103FA0009362000024030050304200FF14430004D9 +:103FB000000000000A0006D78F440180A36400803F +:103FC00003E000080000000027BDFFE8AFB00010CC +:103FD000AFBF00149362000524030030304200306C +:103FE00014430089008080213C0208008C4200209C +:103FF00010400080020020210E0004930000000009 +:104000008F850020ACB000009362003E9363003FB8 +:10401000304200FF00021200306300FF0043102511 +:10402000ACA2000493620082000216000002160394 +:1040300004410005000000003C0308008C630048B8 +:104040000A000FE6000000009362003E304200408C +:10405000144000030000182193620081304300FFE8 +:104060009362008200031E00304200FF0002140031 +:1040700000621825ACA300088F620040ACA2000CBF +:104080008F620048ACA200108F62004CACA20014FA +:104090008F6200508F63004C0043102304410003E3 +:1040A000000000000A000FFA8F62004C8F6200507F +:1040B000ACA200183C02080094424B5E3C03C00BCB +:1040C00000002021004310250E0004B8ACA2001C03 +:1040D0008F6200548F840020AC8200008F620058F1 +:1040E000AC8200048F62005CAC8200088F620060CA +:1040F0008F43007400431021AC82000C8F62006477 +:10410000AC820010976300689762006A00031C008D +:104110003042FFFF00621825AC83001493620082D6 +:1041200024030080304200FF14430003000000001D +:104130000A00102EAC8000188F63000C24020001CE +:104140001062000E2402FFFF9362003E30420040E6 +:104150001440000A2402FFFF8F63000C8F4200749A +:10416000006218233C020800006210241440000280 +:10417000000028210060282100051043AC820018AF +:104180003C02080094424B5E3C03C00C000020211E +:10419000004310258F8300200E0004B8AC62001C81 +:1041A0008F6200188F8300203C05080094A54B5EA9 +:1041B00024040001AC620000AC6000048F66006C57 +:1041C0003C02400D00A22825AC6600088F6200DC8E +:1041D000AC62000CAC600010936200050002160097 +:1041E000AC620014AC6000180E0004B8AC65001C92 +:1041F000020020218FBF00148FB00010A3600005C3 +:104200000A00042127BD00188FBF00148FB00010D2 +:1042100003E0000827BD00189742007C30C600FF6D +:10422000A08600843047FFFF2402000514C2000B63 +:1042300024E3465090A201122C42000710400007D0 +:1042400024E30A0090A30112240200140062100467 +:1042500000E210210A0010663047FFFF3067FFFFC1 +:1042600003E00008A4870014AC87004C8CA201086E +:104270000080402100A0482100E2102330C600FF4A +:104280001840000393AA001324E2FFFCACA201082B +:1042900030C2000110400008000000008D020050F4 +:1042A00000E2102304410013240600058D0200548F +:1042B00010E20010000000008D02005414E2001A09 +:1042C000000000003C0208008C4200D83042002070 +:1042D0001040000A2402000191030078910200833B +:1042E000144300062402000101002021012028219E +:1042F000240600040A00105400000000A1000084FD +:1043000011400009A50200148F4301008F4201F8FB +:104310000440FFFE24020002AF4301C0A34201C4D7 +:104320003C021000AF4201F803E00008000000006A +:1043300027BDFFE88FA90028AFBF001000804021F3 +:1043400000E918231860007330C600FFA080007CCD +:10435000A08000818CA2010800E210230440004DDF +:10436000000000008C8200509483003C8C84006428 +:10437000004748233063FFFF012318210083202BCF +:1043800010800004000000008D0200640A0010B7D5 +:1043900000E210219502003C3042FFFF0122102173 +:1043A00000E21021AD02005C9502003C8D03005C30 +:1043B0003042FFFF0002104000E210210043102BAA +:1043C00010400003000000000A0010C68D02005CCF +:1043D0009502003C3042FFFF0002104000E2102135 +:1043E000AD02005CA1000084AD07004C8CA2010866 +:1043F00000E210231840000224E2FFFCACA20108F6 +:1044000030C200011040000A000000008D02005080 +:1044100000E2102304410004010020218D02005419 +:1044200014E20003000000000A0010E82406000562 +:104430008D02005414E200478FBF00103C020800B8 +:104440008C4200D8304200201040000A24020001B3 +:1044500091030078910200831443000624020001B6 +:1044600001002021240600048FBF00100A00105410 +:1044700027BD0018A1000084A50200148F4301008D +:104480008F4201F80440FFFE240200020A00110DD1 +:10449000000000008C82005C004910230043102BB8 +:1044A00054400001AC87005C9502003C3042FFFFA5 +:1044B0000062102B14400007240200029502003C09 +:1044C0008D03005C3042FFFF00621821AD03005CE9 +:1044D00024020002AD07004CA10200840E000F0A66 +:1044E0008F4401001040001B8FBF00108F4301005C +:1044F0008F4201F80440FFFE24020002AF4301C0D6 +:10450000A34201C43C021000AF4201F80A0011238B +:104510008FBF001030C200101040000E8FBF00107F +:104520008C83005C9482003C006918233042FFFFBA +:10453000006218213C023FFF3444FFFF0083102B30 +:10454000544000010080182101231021AD02005CBD +:104550008FBF001003E0000827BD001827BDFFE84B +:104560008FAA0028AFBF00100080402100EA482336 +:104570001920002130C600FF8C83005C8C8200640F +:10458000006A18230043102B5040001000691821C6 +:1045900094A2011001221021A4A2011094A20110E2 +:1045A0003042FFFF0043102B1440000A3C023FFF43 +:1045B00094A2011000431023A4A201109482003C95 +:1045C0003042FFFF0A00114200621821A4A001102E +:1045D0003C023FFF3444FFFF0083102B5440000196 +:1045E0000080182100671021AD02005CA100007C52 +:1045F0000A00118AA100008130C200101040003C66 +:10460000000000008C820050004A1023184000383F +:10461000000000009082007C24420001A082007C07 +:104620009082007C3C0308008C630024304200FF31 +:104630000043102B1440005C8FBF00108CA20108B7 +:1046400000E2102318400058000000008C83005442 +:104650009482003C006A18233042FFFF0003184395 +:10466000000210400043102A104000050000000026 +:104670008C820054004A10230A001171000210437A +:104680009482003C3042FFFF00021040AD02006403 +:104690009502003C8D0400649503003C3042FFFF0E +:1046A00000021040008220213063FFFF00831821A8 +:1046B00001431021AD02005C8D020054ACA2010840 +:1046C00024020002A10200840E000F0A8F440100A0 +:1046D000104000358FBF00108F4301008F4201F85A +:1046E0000440FFFE240200020A0011B30000000093 +:1046F000AD07004C8CA2010800E210231840000214 +:1047000024E2FFFCACA2010830C200011040000A04 +:10471000000000008D02005000E21023044100045C +:10472000010020218D02005414E20003000000006B +:104730000A0011AA240600058D02005414E2001A92 +:104740008FBF00103C0208008C4200D8304200208D +:104750001040000A240200019103007891020083B6 +:104760001443000624020001010020212406000455 +:104770008FBF00100A00105427BD0018A10000844C +:10478000A50200148F4301008F4201F80440FFFE90 +:1047900024020002AF4301C0A34201C43C02100046 +:1047A000AF4201F88FBF001003E0000827BD0018DA +:1047B0008FAA00108C8200500080402130C600FF7C +:1047C000004A102300A048211840000700E01821EB +:1047D00024020001A0800084A0A00112A482001481 +:1047E0000A001125AFAA0010A0800081AD07004C7F +:1047F0008CA2010800E210231840000224E2FFFC12 +:10480000ACA2010830C20001104000080000000006 +:104810008D0200500062102304410013240600059D +:104820008D02005410620010000000008D02005440 +:1048300014620011000000003C0208008C4200D805 +:10484000304200201040000A240200019103007849 +:10485000910200831443000624020001010020217C +:1048600001202821240600040A0010540000000042 +:10487000A1000084A502001403E00008000000006D +:1048800027BDFFE0AFBF0018274201009046000A95 +:104890008C4800148C8B004C9082008430C900FF3F +:1048A00001681823304A00FF1C60001A2D460006DC +:1048B000240200010142100410C00016304300031E +:1048C000012030210100382114600007304C000C19 +:1048D00015800009304200301440000B8FBF0018D3 +:1048E0000A001214000000000E001125AFAB0010EA +:1048F0000A0012148FBF00180E00109AAFAB001000 +:104900000A0012148FBF0018AFAB00100E0011BACE +:10491000AFAA00148FBF001803E0000827BD0020D5 +:1049200024020003A08200848C82005403E000086B +:10493000ACA201083C0200080342182190620081E9 +:10494000240600433C07601924420001A062008154 +:10495000906300813C0208008C4200C0306300FF7D +:10496000146200102403FF803C0208008C4200E027 +:104970000082102100431024AF4200243C020800B2 +:104980008C4200E03C03000A008210213042007F8C +:104990000342102100431021944500D40A000AF17B +:1049A00030A5FFFF03E000080000000027BDFFE086 +:1049B000AFBF0018AFB10014AFB000108F4201803C +:1049C0000080802100A088210E00121B00402021C1 +:1049D000A20000848E0200548FBF00188FB0001018 +:1049E000AE2201088FB1001403E0000827BD0020AB +:1049F00027BDFFE03C020008AFB00010AFBF0018B9 +:104A0000AFB10014034280218F5101409203008412 +:104A10008E0400508E02004C14820040306600FF6D +:104A20003C0208008C4200E02403FF800222102197 +:104A300000431024AF4200243C0208008C4200E0F6 +:104A40009744007C92050081022210213042007FB1 +:104A5000034218213C02000A0062182114A0000B36 +:104A60003084FFFF2402000554C20014248205DCB8 +:104A70009062011224420001A062011224020C8003 +:104A8000AF4200240A00127324020005A060011244 +:104A90002402000514C20009248205DC9202008170 +:104AA0002C4200075040000524820A009203008136 +:104AB0002402001400621004008210213044FFFF21 +:104AC000A60400140E00121B022020219602003CB6 +:104AD0008E03004C022020213042FFFF00021040D4 +:104AE000006218210E000250AE03005C9202007DAD +:104AF00002202021344200400E000259A202007D13 +:104B00008F4201F80440FFFE24020002AF5101C0B1 +:104B1000A34201C43C021000AF4201F88FBF00184D +:104B20008FB100148FB0001003E0000827BD0020F3 +:104B300008000ACC08000B1408000B9808000BE4CE +:044B400008000C203D +:0C4B44000A000028000000000000000033 +:104B50000000000D6370362E322E31000000000080 +:104B60000602010400000000000000000000000038 +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000002005 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000001F4 +:104BC0000000002B000000000000000400030D4066 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000001000000300000000B2 +:104BF0000000000D0000000D3C020800244258A4F3 +:104C00003C03080024635F70AC4000000043202B8D +:104C10001480FFFD244200043C1D080037BD7FFCCA +:104C200003A0F0213C100800261000A03C1C080046 +:104C3000279C58A40E0001AC000000000000000DED +:104C400027BDFFE83C096018AFBF00108D2C500055 +:104C5000240DFF7F24080031018D5824356A380C5B +:104C600024070C003C1A8000AD2A50003C04800A46 +:104C7000AF4800083C1B8008AF4700240E00091510 +:104C8000AF8400100E0008D8000000000E000825B8 +:104C9000000000000E001252000000003C046016EC +:104CA0008C8500003C06FFFF3C02535300A61824ED +:104CB0001062004734867C0094C201F2A780002C69 +:104CC00010400003A78000CC38581E1EA798002C67 +:104CD00094C201F810400004978300CC38591E1E7E +:104CE000A79900CC978300CC2C7F006753E000018C +:104CF000240300669784002C2C82040114400002D7 +:104D000000602821240404003C0760008CE904387A +:104D10002403103C3128FFFF1103001F30B9FFFFAF +:104D200057200010A38000CE24020050A38200CEA2 +:104D3000939F00CE53E0000FA78500CCA78000CC46 +:104D4000978500CC8FBF0010A780002CA78000346F +:104D5000A78000E63C010800AC25008003E00008C5 +:104D600027BD0018939F00CE57E0FFF5A78000CC29 +:104D7000A78500CC978500CC8FBF0010A784002C9E +:104D8000A7800034A78000E63C010800AC25008025 +:104D900003E0000827BD0018A38000CE8CCB003CA8 +:104DA000316A00011140000E0000000030A7FFFF33 +:104DB00010E0FFDE240200508CCC00C831860001D8 +:104DC00014C0FFDC939F00CE0A00007A2402005139 +:104DD0008C8F00043C0E60000A00005D01EE302163 +:104DE0008CEF0808240D5708000F740211CD000441 +:104DF00030B8FFFF240500660A00007B240404008D +:104E00001700FFCC939F00CE0A00007A24020050C6 +:104E10008F8600103089FFFF000939408CC30010D5 +:104E20003C08005000E82025AF4300388CC5001432 +:104E300027420400AF82001CAF45003CAF44003065 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60008F4B0000316A00201140FFFD0000000060 +:104E700003E00008000000008F840010948A001AEC +:104E80008C8700243149FFFF000940C000E8302131 +:104E9000AF46003C8C8500248F43003C00A31023C8 +:104EA00018400029000000008C8B002025620001C2 +:104EB0003C0D005035AC0008AF420038AF4C00301C +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE0008F4F000031EE002011C0FFFD00000000D8 +:104EF0008F4A04003C080020AC8A00108F4904044B +:104F0000AC890014AF4800300000000094860018FF +:104F10009487001C00C71821A48300189485001AE8 +:104F200024A20001A482001A9498001A9499001EE9 +:104F3000133800030000000003E000080000000038 +:104F400003E00008A480001A8C8200200A0000DC24 +:104F50003C0D00500A0000CD000000003C0308009A +:104F60008C6300208F82001827BDFFE810620008C4 +:104F7000AFBF00100E000104AF8300183C0308000F +:104F80008C63002024040001106400048F89001049 +:104F90008FBF001003E0000827BD00188FBF00106E +:104FA0003C076012A520000A9528000A34E500108D +:104FB00027BD00183106FFFF03E00008ACA60090F3 +:104FC0003C0208008C42002027BDFFC8AFBF003460 +:104FD000AFBE0030AFB7002CAFB60028AFB500248D +:104FE000AFB40020AFB3001CAFB20018AFB10014D3 +:104FF00010400050AFB000108F840010948600065F +:105000009483000A00C3282330B6FFFF12C0004A71 +:105010008FBF003494890018948A000A012A402323 +:105020003102FFFF02C2382B14E0000202C020212F +:10503000004020212C8C0005158000020080A0215A +:10504000241400040E0000B3028020218F8700107A +:1050500002809821AF80001494ED000A028088211C +:105060001280004E31B2FFFF3C1770003C1540002B +:105070003C1E60008F8F001C8DEE000001D71824AD +:10508000507500500220202102A3802B160000350D +:105090003C182000507800470220202124100001F5 +:1050A0008F83001414600039029158230230F823D2 +:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D +:1050C0008F8700103C110020AF510030000000001D +:1050D00094E6000A3C1E601237D5001002662821B3 +:1050E000A4E5000A94E2000A94F2000A94F400187D +:1050F0003057FFFF1292003BAEB700908CED0014CA +:105100008CE400100013714001AE4021000E5FC31B +:10511000010E502B008B4821012A1821ACE8001405 +:10512000ACE3001002D3382330F6FFFF16C0FFB9FE +:105130008F8400108FBF00348FBE00308FB7002CDB +:105140008FB600288FB500248FB400208FB3001CC9 +:105150008FB200188FB100148FB0001003E0000868 +:1051600027BD0038107E001B000000001477FFCC24 +:10517000241000010E00159B000000008F83001416 +:105180001060FFCB0230F823029158238F87001064 +:10519000017020210A0001973093FFFF8F830014D4 +:1051A0001460FFCB3C110020AF5100300A000163B6 +:1051B000000000000E00077D024028210A00015770 +:1051C000004080210E00033A024028210A000157C6 +:1051D000004080210E001463022020210A000157A4 +:1051E000004080210E0000CD000000000A0001797F +:1051F00002D3382327BDFFE8AFB00010AFBF0014C3 +:105200000E00003F000000003C028000345000709F +:105210000A0001BA8E0600008F4F000039EE00012F +:1052200031C20001104000248F8600A88E070000C4 +:105230003C0C08008D8C003C3C0908008D2900388E +:1052400000E66823018D28210000502100AD302B9D +:10525000012A4021010620213C010800AC25003C28 +:10526000AF8700A83C010800AC2400380E000106FE +:10527000000000003C0308008C6300701060FFE633 +:10528000006020213C0508008CA500683C06080051 +:105290008CC6006C0E00152A000000003C010800BE +:1052A000AC2000708F4F000039EE000131C20001C8 +:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6 +:1052C0003C0508008CA5003C3C0408008C84003898 +:1052D000014B482300A938210082182100E9402B06 +:1052E000006810213C010800AC27003C3C0108008C +:1052F000AC2200388F5F01002419FF0024180C0035 +:1053000003F9202410980012AF840000AF4400205D +:10531000936D0000240C002031A600FF10CC001279 +:10532000240E005010CE00043C194000AF59013843 +:105330000A0001B3000000000E0011C800000000C8 +:105340003C194000AF5901380A0001B300000000C9 +:105350000E00011F000000003C194000AF59013849 +:105360000A0001B3000000008F58010000802821CE +:10537000330F00FF01E020210E0002F1AF8F000487 +:105380003C194000AF5901380A0001B30000000089 +:1053900000A4102B2403000110400009000030215C +:1053A0000005284000A4102B04A0000300031840AF +:1053B0005440FFFC000528405060000A0004182BF0 +:1053C0000085382B54E000040003184200C3302548 +:1053D00000852023000318421460FFF900052842CD +:1053E0000004182B03E0000800C310218F4201B80D +:1053F0000440FFFE00000000AF4401803C031000A9 +:1054000024040040AF450184A3440188A3460189D8 +:10541000A747018A03E00008AF4301B83084FFFFCB +:105420000080382130A5FFFF000020210A00022A59 +:10543000240600803087FFFF8CA40000240600387B +:105440000A00022A000028218F8300388F8600304E +:105450001066000B008040213C07080024E75A1822 +:10546000000328C000A710218C4400002463000121 +:10547000108800053063000F5466FFFA000328C04F +:1054800003E00008000010213C07080024E75A1C34 +:1054900000A7302103E000088CC200003C0390000C +:1054A0003462000100822025AF4400208F45002097 +:1054B00004A0FFFE0000000003E000080000000060 +:1054C0003C038000346200010082202503E00008D4 +:1054D000AF44002027BDFFE0AFB100143091FFFFC3 +:1054E000AFB00010AFBF00181220001300A0802141 +:1054F0008CA2000024040002240601401040000F8A +:10550000004028210E000C5C00000000000010216B +:10551000AE000000022038218FBF00188FB10014A8 +:105520008FB0001000402021000028210000302111 +:105530000A00022A27BD00208CA200000220382188 +:105540008FBF00188FB100148FB0001000402021D1 +:1055500000002821000030210A00022A27BD002077 +:1055600000A010213087FFFF8CA500048C440000B0 +:105570000A00022A2406000627BDFFE0AFB0001093 +:10558000AFBF0018AFB100149363003E00808021CC +:105590000080282130620040000020211040000FD0 +:1055A0008E1100000E000851022020219367000098 +:1055B0002404005030E500FF50A400128E0F0000BC +:1055C000022020218FBF00188FB100148FB000106F +:1055D000A762013C0A00091127BD00200E000287C6 +:1055E000000000000E0008510220202193670000F7 +:1055F0002404005030E500FF14A4FFF20220202113 +:105600008E0F00003C1008008E1000503C0D000C66 +:10561000240BFF8001F05021314E007F01DA602120 +:10562000018D4021014B4824AF4900280220202150 +:105630008FBF00188FB100148FB00010A50200D6E4 +:1056400027BD00200A000911AF8800D027BDFFE068 +:10565000AFBF0018AFB10014AFB0001093660001E7 +:10566000008080210E00025630D1000493640005B2 +:10567000001029C2A765000034830040A363000521 +:105680000E00025F020020210E00091302002021FB +:1056900024020001AF62000C02002821A762001062 +:1056A00024040002A762001224060140A76200142D +:1056B0000E000C5CA76200161620000F8FBF0018AA +:1056C000978C00343C0B08008D6B00782588FFFF19 +:1056D0003109FFFF256A0001012A382B10E000067E +:1056E000A78800343C0F6006240E001635ED00102C +:1056F000ADAE00508FBF00188FB100148FB00010F6 +:1057000003E0000827BD002027BDFFE0AFB1001473 +:10571000AFBF0018AFB0001000A088211080000AB1 +:105720003C03600024020080108200120000000090 +:105730000000000D8FBF00188FB100148FB0001053 +:1057400003E0000827BD00208C682BF80500FFFE51 +:1057500000000000AC712BC08FBF00188FB1001487 +:105760008FB000103C09100027BD002003E00008A6 +:10577000AC692BF80E00025600A0202193650005AD +:10578000022020210E00025F30B000FF2403003E03 +:105790001603FFE7000000008F4401780480FFFE3D +:1057A000240700073C061000AF51014002202021D1 +:1057B000A34701448FBF00188FB100148FB00010B1 +:1057C000AF4601780A0002C227BD002027BDFFE8CE +:1057D000AFBF0014AFB000108F50002000000000D9 +:1057E0000E000913AF440020AF5000208FBF0014FB +:1057F0008FB0001003E0000827BD00183084FFFFC1 +:10580000008038212406003500A020210A00022A49 +:10581000000028213084FFFF008038212406003654 +:1058200000A020210A00022A0000282127BDFFD065 +:10583000AFB3001C3093FFFFAFB50024AFB2001828 +:10584000AFBF0028AFB40020AFB10014AFB000105C +:1058500030B5FFFF12600027000090218F90001CE0 +:105860008E0300003C0680002402004000033E023C +:1058700000032C0230E4007F006688241482001D9F +:1058800030A500FF8F8300282C68000A510000100B +:105890008F910014000358803C0C0800258C56940E +:1058A000016C50218D49000001200008000000001B +:1058B00002B210213045FFFF0E000236240400849E +:1058C000162000028F90001CAF8000288F910014DA +:1058D000260C002026430001018080213072FFFF4A +:1058E00016200004AF8C001C0253502B1540FFDC27 +:1058F00000000000024010218FBF00288FB5002457 +:105900008FB400208FB3001C8FB200188FB1001429 +:105910008FB0001003E0000827BD0030240E0034D3 +:1059200014AE00F9000000009203000E241F168040 +:105930003C07000CA36300219202000D0347C8211D +:105940003C066000A3620020961100123C0A7FFF13 +:10595000354CFFFFA771003C960B00102403000597 +:105960003168FFFFAF6800848E05001CAF5F002820 +:105970008F3800008CC4444803057826008F3021FE +:10598000AF66004C8F69004C24CE00013C057F00BF +:10599000AF6900508F740050AF740054AF66007050 +:1059A000AF6E00588F6D005824140050AF6D005C2E +:1059B000A3600023AF6C0064A36300378E02001461 +:1059C000AF6200488F710048AF7100248E0B001841 +:1059D000AF6B006C9208000CA3680036937F003E0A +:1059E00037F90020A379003E8F78007403058024E6 +:1059F000360F4000AF6F007493640000308900FFE1 +:105A0000513402452404FF803C04080024845A9841 +:105A10000E00028D000000003C1008008E105A9805 +:105A20000E00025602002021240600042407000173 +:105A3000A366007D020020210E00025FA36700051F +:105A40008F5F017807E0FFFE240B0002AF5001409A +:105A5000A34B01448F90001C3C081000AF48017814 +:105A60000A000362AF8000282CAD003751A0FF98D8 +:105A70008F9100140005A0803C180800271856BC20 +:105A8000029878218DEE000001C00008000000009F +:105A90002418000614B80011000000003C0808009B +:105AA0008D085A9824040005AF4800208E1F001866 +:105AB000AF7F00188F79004CAF79001C8F650050C4 +:105AC000122000C0AF6500700A000362AF84002896 +:105AD0002406000710A60083240300063C050800E6 +:105AE00024A55A980E000264240400818F90001CA3 +:105AF0000011102B0A000362AF8200282407000463 +:105B000014A7FFF6240500503C1808008F185A9877 +:105B1000AF5800208E0F0008AF6F00408E090008BC +:105B2000AF6900448E14000CAF7400488E0E001054 +:105B3000AF6E004C8E0D0010AF6D00848E0A001405 +:105B4000AF6A00508E0C0018AF6C00548E04001C1D +:105B5000AF64005893630000306B00FF116501D8FB +:105B6000000000008F7400488F6900400289702394 +:105B700005C000042404008C1620FFDE240200036C +:105B8000240400823C05080024A55A980E000287D0 +:105B9000000000008F90001C000010210A0003622A +:105BA000AF820028240F000514AFFFCC240520008D +:105BB0003C0708008CE75A98AF4700208E06000487 +:105BC000AF66005C9208000824100008A36800215A +:105BD0008F9F001C93F90009A37900208F86001C79 +:105BE00090D8000A330400FF10900011000000005C +:105BF0002885000914A0006924020002240A00205C +:105C0000108A000B34058000288D002115A00008A3 +:105C100024054000240E0040108E00053C050001C4 +:105C200024140080109400023C050002240540006A +:105C30008F7800743C19FF00031980240205782531 +:105C4000AF6F007490C4000BA36400818F84001CAC +:105C50009489000C11200192000000009490000C27 +:105C60002406FFBF24050004A770003C908F000E9F +:105C7000A36F003E8F84001C9089000FA369003F32 +:105C80008F8B001C8D6E00108F54007401D468231C +:105C9000AF6D00608D6A0014AF6A0064956C0018E7 +:105CA000A76C00689563001AA763006A8D62001CE8 +:105CB000AF62006C9167000EA367003E9368003EE0 +:105CC0000106F8241220014BA37F003E8F90001C98 +:105CD0000A000362AF8500282407002214A7FF7F73 +:105CE000240300073C0B08008D6B5A981220000C0F +:105CF000AF4B00200A000362AF830028240C00335E +:105D000010AC0014240A00283C05080024A55A9869 +:105D10000E00023C240400810A0003EB8F90001C5B +:105D20003C04080024845A980E00028D00000000F4 +:105D30009363000024110050306200FF10510135C0 +:105D4000000000008F90001C000018210A00036270 +:105D5000AF8300283C0D08008DAD5A9824040081C3 +:105D6000AF4D00203C05080024A55A980E00023CC7 +:105D7000A36A00348F90001C240200090A00036209 +:105D8000AF82002802B288213225FFFF0E000236C2 +:105D9000240400840A0003628F90001C1082FFA478 +:105DA00024050400288B000311600170240C0004FA +:105DB000240300015483FF9E240540000A00043B95 +:105DC000240501003C04080024845A988F62004C8A +:105DD0000E00028D8F6300508F90001C0000202168 +:105DE0000A000362AF8400288E1000042404008A95 +:105DF000AF50002093790005333800021700015F8F +:105E0000020028219368002302002821311F00206E +:105E100017E0015A2404008D9367003F2406001206 +:105E200030E200FF10460155240400810E000256A6 +:105E30000200202193630023240500040200202196 +:105E4000346B0042A36B00230E00025FA365007D4C +:105E50008F4401780480FFFE240A0002AF50014005 +:105E6000A34A01448F90001C3C0C1000AF4C0178F9 +:105E70000A0003EC0011102B8E1000042404008A89 +:105E8000AF500020936E000531CD000215A0001622 +:105E900002002821936F003F2414000402002821EF +:105EA00031E900FF11340010240400810E00025675 +:105EB000020020219362002324080012241FFFFE09 +:105EC00034460020A3660023A368003F93790005B1 +:105ED00002002021033FC0240E00025FA3780005CA +:105EE00002002821000020210E00033400000000E1 +:105EF0000A0003EB8F90001C8E1000043C03000886 +:105F00000343A021AF500020928B000024050050D5 +:105F1000316400FF10850161240700880200202100 +:105F2000000028210E00022A2406000E928D000097 +:105F3000240EFF800200282101AE8025A2900000DF +:105F4000240400040E000C5C240600300A0003EB5D +:105F50008F90001C8E0800043C14080026945A9868 +:105F60003C010800AC285A98AF480020921F00035B +:105F700033F9000413200002240200122402000658 +:105F8000A362003F920B001B2404FFC03165003F59 +:105F900000A43825A367003E9206000330C200012A +:105FA00014400132000000008E020008AE8200089A +:105FB0003C0208008C425AA010400131000249C244 +:105FC000A76900088E14000C240C0001240300149F +:105FD000AF74002C8E0E0010AF6E0030960D0016C0 +:105FE000A76D0038960A0014A76A003AAF6C000C3F +:105FF000A76C0010A76C0012A76C0014A76C001609 +:1060000012200136A3630034920F000331F0000226 +:106010002E1100018F90001C262200080A00036246 +:10602000AF8200288E0400043C0E0008034E30218D +:10603000AF4400208E05000890CD0000240C0050D5 +:1060400031AA00FF114C00862407008824060009AD +:106050000E00022A000000000A0003EB8F90001CD3 +:106060008E04001C0E00024100000000104000F4ED +:10607000004050218F89001C240700890140202105 +:106080008D25001C240600010E00022A00000000DD +:106090000A0003EB8F90001C960D00023C140800D0 +:1060A00026945A9831AA0004514000B83C10600070 +:1060B0008E0E001C3C010800AC2E5A98AF4E0020FA +:1060C000920700102408001430E200FF144800D6A4 +:1060D00000000000960B00023163000114600165AE +:1060E000000000008E020004AE8200083C1408008C +:1060F0008E945AA01280015B000000008F7400741F +:106100003C0380002404000102835825AF6B007417 +:10611000A3600005AF64000C3C0708008CE75AA0A0 +:106120008F86001CA7640010000711C2A76400122C +:10613000A7640014A7640016A76200088CC80008B2 +:1061400024040002AF68002C8CC5000CAF65003041 +:1061500090DF0010A37F00348F99001C9330001152 +:10616000A37000358F98001C930F0012A36F0036A8 +:106170008F89001C912E0013A36E00378F90001C96 +:10618000960D0014A76D0038960A0016A76A003A0B +:106190008E0C0018AF6C00245620FDCCAF84002874 +:1061A0003C05080024A55A980E0002640000202136 +:1061B0008F90001C0A0004A7000020218E1000040C +:1061C00024070081AF500020936900233134001070 +:1061D000128000170000000002002021000028218A +:1061E0002406001F0E00022A000000000A0003EB34 +:1061F0008F90001C3C05080024A55A980E000287C9 +:10620000240400828F90001C000028210A000362F1 +:10621000AF8500283C0408008C845A980E0014E8CE +:10622000000000008F90001C0A000482000018216A +:106230000E00025602002021937800230200202144 +:10624000370F00100E00025FA36F002300003821FB +:1062500002002021000028210A0005A82406001FB2 +:10626000920F000C31E90001112000030000000032 +:106270009618000EA4D8002C921F000C33F90002CF +:1062800013200005000038218E0200149608001229 +:10629000ACC2001CA4C8001A0A0005432406000969 +:1062A0003C05080024A55A980E0002872404008BA0 +:1062B0008F90001C0011282B0A000362AF85002874 +:1062C000AF6000843C0A08008D4A5A983C0D0800D3 +:1062D0008DAD0050240CFF803C02000C014D1821B4 +:1062E000006C2024AF4400288E070014306B007F20 +:1062F000017A282100A2C821AF2700D88E060014F9 +:10630000AF9900D0AF2600DC8E080010251FFFFEDD +:106310000A000408AF3F01083C0508008CA55A9804 +:106320003C1908008F39005024CCFFFE00B9C02171 +:1063300003047824AF4F00283C1408008E945A9828 +:106340003C0908008D2900500289702131CD007F61 +:1063500001BA502101478021AE0600D8AF9000D08D +:10636000AE0000DC0A0003B1AE0C0108548CFE3014 +:10637000240540000A00043B240510000E00032EF3 +:10638000000000000A0003EB8F90001C8E0F442CCD +:106390003C186C62370979703C010800AC205A98AF +:1063A00015E9000824050140979F00349786002CCA +:1063B0000280282103E6C82B132000112404009238 +:1063C000240501400E000C7A240400023C01080060 +:1063D000AC225A98AF4200203C0508008CA55A9880 +:1063E00010A00005240400830E00084500000000F2 +:1063F00010400009240400833C05080024A55A9895 +:106400000E000264000000008F90001C0011202B81 +:106410000A000362AF8400280E0008490000000053 +:106420000A00055F8F90001C0E00084D0000000060 +:106430003C05080024A55A980A00062F2404008B66 +:10644000240400040E000C7A240500301440002AB5 +:10645000004050218F89001C240700830140202127 +:106460008D25001C0A000551240600018E04000839 +:106470000E000241000000000A00051BAE82000869 +:106480003C05080024A55A980E00023C240400870D +:106490008F90001C0A0005360011102B8F830038E6 +:1064A0008F8600301066FE9D000038213C070800F2 +:1064B00024E75A1C000320C0008728218CAC000070 +:1064C00011900061246A00013143000F5466FFFA05 +:1064D000000320C00A0004F6000038213C05080033 +:1064E00024A55A980E000287240400828F90001C75 +:1064F0000A000536000010213C0B0008034B202148 +:106500002403005024070001AF420020A0830000B4 +:10651000A08700018F82001C90480004A08800180A +:106520008F85001C90A60005A08600198F9F001C77 +:1065300093F90006A099001A8F90001C921800078A +:10654000A098001B8F94001C928F0008A08F001C45 +:106550008F89001C912E0009A08E001D8F8D001CBC +:1065600091AC000AA08C001E8F8B001C3C0C080014 +:10657000258C5A1C9163000B3C0B0800256B5A18A4 +:10658000A083001F8F87001C90E8000CA0880020CB +:106590008F82001C9045000D24024646A0850021F4 +:1065A0008F86001C90DF000EA09F00228F99001C98 +:1065B0009330000FA09000238F98001C93140010BC +:1065C000A09400248F8F001C91E90011A089002560 +:1065D0008F89001C8F8E00308F900038952D00140D +:1065E000000E18C025C80001A48D002895270016AC +:1065F000006C3021006BC821A487002A9525001863 +:106600003108000FA485002CA482002E8D3F001CB1 +:10661000ACCA0000AF88003011100006AF3F000088 +:10662000000038218D25001C014020210A00055161 +:1066300024060001250C00013184000F00003821E0 +:106640000A0006B8AF8400383C07080024E75A184F +:106650000087302100003821ACA000000A0004F6B9 +:10666000ACC000003C05080024A55A980A00062F7B +:10667000240400878E0400040E0002410000000084 +:106680000A00056AAE8200083084FFFF30C600FFB2 +:106690008F4201B80440FFFE00064400010430258B +:1066A0003C07200000C720253C031000AF400180BC +:1066B000AF450184AF44018803E00008AF4301B84F +:1066C00027BDFFE8AFB00010AFBF00143C0760006B +:1066D000240600021080000600A080210010102B6C +:1066E0008FBF00148FB0001003E0000827BD001812 +:1066F0003C09600EAD2000348CE5201C8F82001C0C +:106700002408FFFC00A81824ACE3201C0E0006D1CE +:106710008C45000C0010102B8FBF00148FB00010A0 +:1067200003E0000827BD00183C02600E344701005A +:1067300024090018274A040000000000000000009F +:10674000000000003C06005034C30200AF44003893 +:10675000AF45003CAF430030014018218F4B000093 +:10676000316800201100FFFD2406007F2408FFFF90 +:106770008C6C000024C6FFFF24630004ACEC000016 +:1067800014C8FFFB24E70004000000000000000024 +:10679000000000003C0F0020AF4F00300000000060 +:1067A00024AD020001A5702B2529FFFF008E2021BA +:1067B0001520FFE101A0282103E0000800000000EF +:1067C00027BDFFE0AFB10014AFBF0018AFB000109D +:1067D0003C05600E8CA20034008088211440000625 +:1067E0003C0460008C87201C2408FFFC00E8302457 +:1067F00034C30001AC83201C8F8B001C24090001D2 +:10680000ACA90034956900028D6500148D70000CF0 +:106810002D2400818D6700048D660008108000071C +:106820008D6A00102D2C00041580000E30CE00075C +:10683000312D000311A0000B000000002404008B88 +:10684000020028210E0006D1240600030011102B9F +:106850008FBF00188FB100148FB0001003E0000844 +:1068600027BD002015C0FFF62404008B3C03002048 +:10687000AF4300300000000024020001AF8200148A +:106880000000000000000000000000003C1F01505C +:10689000013FC825253800033C0F600EAF47003884 +:1068A00000181882AF46003C35E8003CAF59003074 +:1068B000274704008F4400003086002010C0FFFDF1 +:1068C00000000000106000082466FFFF2403FFFFA3 +:1068D0008CEB000024C6FFFF24E70004AD0B000092 +:1068E00014C3FFFB250800043C08600EAD09003806 +:1068F0000000000000000000000000003C07002035 +:10690000AF470030000000000E0006F901402021D2 +:1069100002002821000020210E0006D124060003D9 +:106920000011102B8FBF00188FB100148FB0001012 +:1069300003E0000827BD002027BDFFE0AFB200182C +:106940003092FFFFAFB10014AFBF001CAFB000101A +:106950001640000D000088210A0007AA022010211D +:1069600024050001508500278CE5000C0000000D77 +:10697000262300013071FFFF24E200200232382B71 +:1069800010E00019AF82001C8F8200141440001622 +:106990008F87001C3C0670003C0320008CE5000043 +:1069A00000A62024148300108F84003C00054402BC +:1069B0003C09800000A980241480FFE9310600FF13 +:1069C0002CCA00095140FFEB262300010006688015 +:1069D0003C0E080025CE579801AE60218D8B00003B +:1069E0000160000800000000022010218FBF001C81 +:1069F0008FB200188FB100148FB0001003E00008B0 +:106A000027BD00200E0006D1240400841600FFD804 +:106A10008F87001C0A00078BAF80003C90EF0002BC +:106A200000002021240600090E0006D1000F2E00D0 +:106A30008F87001C0010102B0A00078BAF82003CD0 +:106A4000020028210E0006DF240400018F87001CAD +:106A50000A00078BAF82003C020028210E0006DFEF +:106A6000000020210A0007C38F87001C0E00071FAB +:106A7000020020210A0007C38F87001C30B0FFFFEF +:106A8000001019C08F5801B80700FFFE3C1F2004FA +:106A90003C191000AF430180AF400184AF5F018813 +:106AA000AF5901B80A00078C262300013082FFFF8E +:106AB00014400003000018210004240224030010E5 +:106AC000308500FF14A000053087000F2466000801 +:106AD0000004220230C300FF3087000F14E00005DD +:106AE000308900032468000400042102310300FF00 +:106AF0003089000315200005388B0001246A00024C +:106B000000042082314300FF388B00013164000112 +:106B100010800002246C0001318300FF03E00008B4 +:106B200000601021308BFFFF000B394230E600FF80 +:106B30003C09080025295998000640800109602178 +:106B40008D8700003164001F240A0001008A1804A8 +:106B500030A500FF00E3202514A000020003102749 +:106B600000E22024240F000100CF700401096821F5 +:106B7000000E282714800005ADA400008F86000CAD +:106B800000A6102403E00008AF82000C8F88000CE0 +:106B900001C8102503E00008AF82000C3C06001F6E +:106BA0003C0360003084FFFF34C5FF8024020020D6 +:106BB000AC602008AC60200CAC602010AC652014E8 +:106BC000AC642018AC62200000000000000000004F +:106BD00003E000080000000027BDFFE82402FFFFDB +:106BE000AFBF0010AF82000C000020213C0608005F +:106BF00024C659982405FFFF248900010004408021 +:106C00003124FFFF010618212C87002014E0FFFA31 +:106C1000AC6500000E0008160000202124020001CF +:106C20003C04600024050020AC822018AC852000C4 +:106C3000000000000000000000000000244A0001E5 +:106C40003142FFFF2C46040014C0FFF78FBF001035 +:106C500003E0000827BD00188F8300082C620400A1 +:106C600003E00008384200018F830008246200011D +:106C700003E00008AF8200088F8300082462FFFF52 +:106C800003E00008AF82000827BDFFE0AFB10014A9 +:106C9000AFBF0018AFB000108F6B00303C06600033 +:106CA00000808821ACCB20088F6A002C3C02800039 +:106CB00024030008ACCA200C9769003A9768003892 +:106CC00000092C003107FFFF00A72025ACC42010CD +:106CD000ACC22014ACC32000000000000000000083 +:106CE000000000003C0360008C6D200031AC000807 +:106CF0001580FFF9000000008C6E201405C00020F4 +:106D0000000000000E0007DA8F84000C00024080B3 +:106D10003C09080025295998010938218CE4000014 +:106D20000E0007DA00028140020220213090FFFFAE +:106D3000020020210E0007F8000028213C0C8000F2 +:106D4000022C58253210FFFF3C116000240A00205D +:106D5000AE2B2014AE302018AE2A20000000000018 +:106D60000000000000000000020010218FBF00188A +:106D70008FB100148FB0001003E0000827BD002081 +:106D80008C6620143C02001F3443FF803C1FFFE848 +:106D900000C3C02437F9080003198021001079C20C +:106DA0003C0C8000022C582531F0FFFF3C116000A4 +:106DB000240A0020AE2B2014AE302018AE2A20006A +:106DC0000000000000000000000000000200102190 +:106DD0008FBF00188FB100148FB0001003E00008BF +:106DE00027BD002027BDFFE8AFB000103402FFFF31 +:106DF0003090FFFFAFBF00141202000602002021F6 +:106E00000E00081600000000020020210E0007F806 +:106E1000240500018F8400088FBF00148FB000107C +:106E20002483FFFF27BD001803E00008AF8300089C +:106E3000000439C230E6003F00043B42000718401E +:106E4000240210002CC4002024C8FFE0AF42002C14 +:106E5000246300011480000330A900FF00071840DC +:106E6000310600FF0003608024080001019A5821C8 +:106E70003C0A000E00C82804016A382111200005D0 +:106E8000000530278CE900000125302503E00008CB +:106E9000ACE600008CEE000001C6682403E00008A8 +:106EA000ACED000027BDFFE8AFBF0014AFB000108D +:106EB0003C0460008C8508083403F00030A2F00028 +:106EC00050430006240200018C8708083404E000C7 +:106ED00030E6F00010C4001E24020002AF82004021 +:106EE0003C1060003C0A0200AE0A0814240910009D +:106EF0003C08000E8E03440003482021AF49002CBB +:106F0000240501200E000CC0000030218F830040BA +:106F1000106000043C021691240B0001106B000E5F +:106F20003C023D2C344F0090AE0F44088FBF00143C +:106F30008FB000103C0C6000240E10003C0D0200CD +:106F400027BD0018AD8E442003E00008AD8D081069 +:106F50000A0008E7AF8000403C0218DA344F009086 +:106F6000AE0F44088FBF00148FB000103C0C6000BF +:106F7000240E10003C0D020027BD0018AD8E4420E9 +:106F800003E00008AD8D08100A0008BB24050001CD +:106F90000A0008BB000028213C08080025085DA461 +:106FA0002404FFFF010018212402001E2442FFFFD9 +:106FB000AC6400000441FFFD246300043C070800AA +:106FC00024E75E208CE5FFFC2404001C240600015D +:106FD000308A001F0146480424840001000910275C +:106FE0002C8300201460FFFA00A22824ACE5FFFCEB +:106FF0003C05666634A4616E3C06080024C65EE06B +:10700000AF840058AF88009C2404FFFF00C0182103 +:107010002402001F2442FFFFAC6400000441FFFD76 +:10702000246300043C0766663C05080024A55EA0B6 +:10703000AF86004834E6616EAF8600982404FFFFF7 +:1070400000A018212402000F2442FFFFAC640000BE +:107050000441FFFD246300043C0B66663C06080007 +:1070600024C65E203568616EAF8500A4AF880070CD +:107070002404FFFF00C018212402001F2442FFFF48 +:10708000AC6400000441FFFD246300043C0D66660F +:107090003C0A0800254A5F6035AC616EAF860090FF +:1070A000AF8C005C2404FFFF014018212402000380 +:1070B0002442FFFFAC6400000441FFFD2463000490 +:1070C0003C09080025295F708D27FFFC2404000679 +:1070D000240500013099001F0325C0042484000109 +:1070E000001878272C8E002015C0FFFA00EF3824F6 +:1070F000AD27FFFC3C09666624030400240403DC7E +:1071000024050200240600663522616E3C08080052 +:1071100025085AA4AF820074AF830044AF83006C8B +:10712000AF830050AF830084AF8A008CAF840064CB +:10713000AF85004CAF860054AF840078AF85006007 +:10714000AF86008001001821240200022442FFFFC4 +:10715000AC6000000441FFFD24630004240400032C +:107160002403000C3C0A0800254A5AB0AF8A006884 +:107170000A00098E2405FFFF000418802484000102 +:10718000006858212C8700C014E0FFFBAD650000AB +:107190003C0E666635CD616E240C17A024081800DD +:1071A000AF8D0088AF8C009403E00008AF88007CAE +:1071B0002484007F000421C200004021000030210F +:1071C00000003821000028210A0009A5AF8400A092 +:1071D0001060000624E7000100C4302124A500014E +:1071E0002CC20BF51440FFFA2CA300663C090800E2 +:1071F00025295F6001201821240200032442FFFF9B +:10720000AC6000000441FFFD2463000410E0001A9C +:1072100024E3FFFF0003294210A0000A0000202100 +:107220002406FFFF3C03080024635F602484000100 +:107230000085502BAC660000250800011540FFFBBF +:107240002463000430E2001F10400008000868803A +:10725000240C0001004C38040008588001692821E2 +:1072600024E6FFFF03E00008ACA6000001A94021CE +:107270002409FFFFAD09000003E000080000000042 +:10728000AF4400283C04000C034420210005288260 +:107290000A000CC000003021000421803C03600083 +:1072A000AC6410080000000000052980AC65100CDB +:1072B0000000000003E000088C62100C27BDFFE80E +:1072C0000080282124040038AFBF00140E0009D527 +:1072D000AFB0001024040E00AF4400283C10000C96 +:1072E00003502021240500100E000CC000003021A6 +:1072F00003501021AC400000AC40000424040038CE +:107300008FBF00148FB0001024053FFF27BD001869 +:107310000A0009D58C430000000421803C03600072 +:10732000AC641008000000008C62100C03E0000840 +:107330000002118227BDFFC8AFB400208F940068FF +:10734000AFBE0030AFB7002CAFB600280000B821A8 +:107350000080B021241E00C0AFBF0034AFB50024B0 +:10736000AFB3001CAFB20018AFB10014AFB0001043 +:107370000A000A12AFA5003C504000018F9400683B +:1073800027DEFFFF13C00028269400048E92000021 +:107390003C03080024635DA01240FFF70283102B1A +:1073A0003C04080024845AA4028410230002A8C0CC +:1073B000000098210A000A212411000100118840D0 +:1073C000122000260000000002B380210251282470 +:1073D0000200202110A0FFF9267300010E0009DE33 +:1073E000000000000016684032EC000101AC2021D2 +:1073F0000E0009D5020028218F89009426F700018C +:107400008FA6003C3AEB0001316A00012528FFFFFE +:107410000011382702CAB021AF88009416E6FFE7B2 +:1074200002479024AE92000002E010218FBF00348A +:107430008FBE00308FB7002C8FB600288FB5002488 +:107440008FB400208FB3001C8FB200188FB10014CE +:107450008FB0001003E0000827BD00383C0E080084 +:1074600025CE5DA0028E102B0A000A0DAE92000000 +:1074700027BDFFD8AFB10014AFB00010AFBF0020E0 +:10748000AFB3001CAFB2001800A0882110A0001FED +:10749000000480403C13080026735AA40A000A5ACC +:1074A0002412000112200019261000010E0009F517 +:1074B00002002021000231422444FFA0000618806F +:1074C0003045001F2C8217A1007318212631FFFFC1 +:1074D0001040FFF400B230048C690000020020214B +:1074E00024053FFF012640241500FFEE0126382524 +:1074F0000E0009D5AC6700008F8A009426100001A9 +:10750000254700011620FFE9AF8700948FBF0020B8 +:107510008FB3001C8FB200188FB100148FB0001011 +:1075200003E0000827BD00288F85009C00805821BB +:107530000000402100004821240A001F3C0C0800E4 +:10754000258C5E1C3C0D080025AD5DA48CA60000BA +:1075500050C000140000402100AD1023000238C0CC +:10756000240300010A000A930000202115000003F3 +:1075700000E410212448202400004821252900018E +:10758000512B00132506DFDC106000062484000167 +:1075900000C3702415C0FFF5000318400A000A91CB +:1075A0000000402110AC002624A300040060282124 +:1075B000254AFFFF1540FFE5AF85009C512B0004D5 +:1075C0002506DFDC0000402103E000080100102157 +:1075D0000006614230C5001F000C50803C070800C7 +:1075E00024E75DA424040001014730211120000F8D +:1075F00000A420043C05080024A55E20148000059A +:107600002529FFFF24C6000410C50011000000005A +:10761000240400018CCF00000004C0270004204097 +:1076200001F868241520FFF5ACCD00008F99007893 +:1076300001001021032B482303E00008AF890078E4 +:107640003C05080024A55DA40A000A9B0000402117 +:107650003C06080024C65DA40A000AB42404000104 +:10766000308800FF240200021102000A24030003F4 +:107670001103005C8F8900A4240400041104005F3E +:1076800024050005110500670000182103E000082B +:10769000006010218F8900483C0C0800258C5EE0BA +:1076A0003C04080024845F60240300201060000F65 +:1076B00000005821240D0002240E00033C0F080096 +:1076C00025EF5EE08D27000014E0000B30F9FFFF8E +:1076D000252900040124C02B53000001018048210A +:1076E0002463FFFF5460FFF88D270000016018211C +:1076F00003E0000800601021132000323C0500FF69 +:1077000030E200FF004030211040004200005021D4 +:1077100024050001000020210005C84000A6C02467 +:1077200017000003332500FF14A0FFFB2484000191 +:10773000012CC023001828C000AA6021008C502111 +:107740003144001F240C0001008C18040003102792 +:1077500000E23024110D0041AD260000110E004C56 +:10776000000A1840110D00368F87006C510E00562C +:107770008F8C0060240D0004110D005A8F8E008440 +:10778000240E0005150EFFDA01601821240B1430B9 +:1077900011400006000018218F8400A0246300011E +:1077A000006A402B1500FFFD016458218F8A00807C +:1077B000AF89008C016018212549FFFF0A000AEB00 +:1077C000AF89008000E52024000736021080FFD03A +:1077D000240A001800075402314600FF0A000AF389 +:1077E000240A00103C0C0800258C5EA03C04080014 +:1077F00024845EE00A000ADA240300103C0C08002E +:10780000258C5E203C04080024845EA00A000AD96E +:107810008F89009000071A02306600FF0A000AF301 +:10782000240A00088F89008C3C0C0800258C5F60BE +:107830003C04080024845F700A000ADA2403000470 +:10784000000A4080250B003024E6FFFF016018216C +:10785000AF8900480A000AEBAF86006C000AC982B3 +:10786000001978803C07080024E75EA001E720218A +:10787000000A18428C8F00003079001F032C380456 +:107880000007C02701F860240A000B08AC8C000038 +:10789000000331420006288000AF28213062001F1B +:1078A0008CB8000024630001004CC804000321428E +:1078B000001938270004108003073024004F2021CE +:1078C0000A000B4CACA60000000A68C025AB0032D1 +:1078D000258AFFFF01601821AF8900A40A000AEB86 +:1078E000AF8A0060254B1030AF89009001601821ED +:1078F00025C9FFFF0A000AEBAF8900843086000724 +:107900002CC2000610400014000000000006408059 +:107910003C030800246357BC010338218CE40000B9 +:1079200000800008000000002409000310A9000ED8 +:1079300000000000240A000510AA000B000000004F +:10794000240B000110AB0008000000008F8C00A089 +:1079500010AC00050000000003E00008000010214A +:107960000A000A7900A020210A000AC700C02021CD +:1079700027BDFFE8308400FF240300021083000BC2 +:10798000AFBF0010240600031086003A240800044C +:1079900010880068240E0005108E007F2CAF143074 +:1079A0008FBF001003E0000827BD00182CA2003094 +:1079B0001440FFFC8FBF001024A5FFD0000531C28A +:1079C000000668803C07080024E75EE001A730213C +:1079D0008CC900000005288230AC001F240B000178 +:1079E000018B50048F840048012A4025ACC8000058 +:1079F0008C83000050600001AF8600488F98006CB7 +:107A000030AE000124A6FFFF270F000115C00002C1 +:107A1000AF8F006C24A600010006414200082080C0 +:107A2000008718218C79000030C2001F2406000155 +:107A30000046F804033F382410E0FFDA8FBF00103F +:107A40000005C182001870803C0F080025EF5EA081 +:107A500001CF48218D2B00000005684231A5001F91 +:107A600000A66004016C502527BD001803E0000843 +:107A7000AD2A00002CA7003014E0FFCA8FBF001011 +:107A800030B900071723FFC724A8FFCE00086A02F9 +:107A9000000D60803C0B0800256B5EA0018B30213F +:107AA0008CC40000000828C230AA001F240800016E +:107AB000014848048F8200A400891825ACC3000047 +:107AC0008C5F000053E00001AF8600A40005704009 +:107AD000000E7942000F28803C04080024845EE0F8 +:107AE00000A418218C6B000025DF000131CD001FA0 +:107AF000001F514201A86004016C4825000A108053 +:107B0000AC690000004428218CA600008F9800601A +:107B100033F9001F8FBF00100328380400C77825F1 +:107B2000270E000127BD0018ACAF000003E00008DD +:107B3000AF8E006024A5EFD02CB804001300FF998D +:107B40008FBF001000053142000658803C0A080033 +:107B5000254A5E20016A30218CC4000030A3001F3A +:107B600024090001006910048F9900900082F82513 +:107B7000ACDF00008F27000050E00001AF860090CE +:107B80008F8D00848FBF001027BD001825AC000129 +:107B900003E00008AF8C008415E0FF828FBF001067 +:107BA0008F8600A0000610400046F821001F21002B +:107BB00003E4C8210019384024F8143000B8402BE1 +:107BC0001100FF788FBF001024A4EBD00E00021329 +:107BD00000C0282100027942000F70803C0D08008F +:107BE00025AD5F6001CD20218C8B0000304C001F43 +:107BF00024060001018618048F89008C016350253A +:107C0000AC8A00008D25000050A00001AF84008CDC +:107C10008F9800808FBF001027BD00182708000133 +:107C200003E00008AF88008030A5000724030003AC +:107C300010A3001028A2000414400008240700022A +:107C40002403000410A300152408000510A8000F49 +:107C50008F8500A003E000080000000014A7FFFDCE +:107C60000080282114C3FFFB240400020A000B8BB0 +:107C700000000000240900050080282110C9FFFB36 +:107C80002404000303E000080000000014C5FFF115 +:107C9000008028210A000B8B24040005240A00011F +:107CA0000080282110CAFFF12404000403E000082A +:107CB0000000000027BDFFE0AFB00010000581C24A +:107CC0002603FFD024C5003F2C6223D024C6007FAA +:107CD000AFB20018AFB10014AFBF001C309100FF6D +:107CE000000691C2000529820200202110400008F0 +:107CF0002403FFFF0E000A4B0000000002002021B9 +:107D0000022028210E000C390240302100001821E9 +:107D10008FBF001C8FB200188FB100148FB00010FD +:107D20000060102103E0000827BD002027BDFFD818 +:107D300024A2007FAFB3001CAFB20018000299C2AA +:107D4000309200FF24A3003F02402021026028213E +:107D5000AFB10014AFB00010AFBF00200E000B6E2B +:107D60000003898200408021004020210220282138 +:107D700014400009000018218FBF00208FB3001CA1 +:107D80008FB200188FB100148FB000100060102166 +:107D900003E0000827BD00280E0009FC00000000D9 +:107DA00000402821020020211051FFF3001019C0CB +:107DB0000E000A4B00000000020020210240282192 +:107DC0000E000C39026030218FBF00208FB3001CE1 +:107DD0008FB200188FB100148FB00010000018216E +:107DE0000060102103E0000827BD00283084FFFF59 +:107DF00030A5FFFF1080000700001821308200012D +:107E00001040000200042042006518211480FFFB8E +:107E10000005284003E000080060102110C00007A2 +:107E2000000000008CA2000024C6FFFF24A500046F +:107E3000AC82000014C0FFFB2484000403E00008AF +:107E40000000000010A0000824A3FFFFAC86000083 +:107E500000000000000000002402FFFF2463FFFF79 +:107E60001462FFFA2484000403E00008000000000C +:107E700030A5FFFF8F4201B80440FFFE3C076015AC +:107E800000A730253C031000AF440180AF400184BF +:107E9000AF46018803E00008AF4301B88F8500D0EA +:107EA0002C864000008018218CA700840087102BAE +:107EB00014400010000000008CA800842D06400033 +:107EC00050C0000F240340008CAA0084008A482B75 +:107ED000512000018CA3008400035A42000B208033 +:107EE0003C05080024A558200085182103E000085F +:107EF0008C62000014C0FFF4000000002403400066 +:107F000000035A42000B20803C05080024A558209D +:107F10000085182103E000088C6200008F8300D0E8 +:107F2000906600D024C50001A06500D08F8500D0E8 +:107F3000906400D090A200D210440017000000000E +:107F4000936C00788F8B00BC318A00FFA16A000C13 +:107F500025490001938700C4312200FF3048007F8B +:107F60001107000B00026827A36200788F4E01788A +:107F700005C0FFFE8F9900B0241800023C0F1000CE +:107F8000AF590140A358014403E00008AF4F017806 +:107F90000A000D0931A20080A0A000D00A000CFF49 +:107FA000000000008F8700D027BDFFC8AFBF0030A2 +:107FB000AFB7002CAFB60028AFB50024AFB4002097 +:107FC000AFB3001CAFB20018AFB10014AFB00010D7 +:107FD00094E300E094E200E2104300D72405FFFFA1 +:107FE0003C047FFF3497FFFF2415FF800A000DF04B +:107FF0003C16000E108A00D18FBF00308F9100B068 +:108000003C1808008F18005C001230C0001291402C +:108010000311702101D57824AF4F002C94EC00E2BD +:1080200031CD007F01BA5821318A7FFF0176482186 +:10803000000A804002091021945300003C08080007 +:108040008D0800580246C02132733FFF001319808B +:10805000010320210224282130BF007F03FAC82118 +:1080600000B5A024AF54002C0336A0218E87001049 +:108070008E8F003003785821256D008800EF702323 +:10808000240C0002AE8E0010AF8D00ACA16C0088F5 +:10809000976A003C8E8400308F9100AC0E000CD6A5 +:1080A0003150FFFF00024B80020940253C02420094 +:1080B00001022025AE2400048E8300048F8D00ACC5 +:1080C0008E860000240E0008ADA3001CADA600188B +:1080D000ADA0000CADA00010929F000A33F900FF84 +:1080E000A5B90014968500083C1F000CA5A5001634 +:1080F0009298000A331100FFA5B100209690000865 +:1081000024180005A5B00022ADA00024928F000B1A +:108110002410C00031E700FFA5A70002A1AE0001B6 +:108120008E8C00308F8B00AC8F8400B0AD6C00085B +:108130003C0A08008D4A005401444821013540247E +:10814000AF4800283C0208008C4200540044302113 +:1081500030C3007F007AC821033F282102458821CF +:10816000AF9100BCAF8500C0A23800008F8A00BC70 +:108170002403FFBF2418FFDF954F000201F03824CD +:1081800000F37025A54E0002914D000231AC003F76 +:10819000358B0040A14B00028F8600BC8F8900D038 +:1081A000ACC000048D28007C3C098000ACC80008ED +:1081B00090C4000D3082007FA0C2000D8F8500BCEE +:1081C00090BF000D03E3C824A0B9000D8F9100BC3F +:1081D0009233000D02789024A232000D8E9000346C +:1081E0008F8B00BCAD7000108E87002C8E8F0030FE +:1081F00000EF7023AD6E0014916D001831AC007F5C +:10820000A16C00188F9F00BC8E8A00308FE8001888 +:10821000015720240109302400C41025AFE20018C2 +:108220009283000AA3E3001C969900088F8500BC86 +:108230008F9800D0A4B9001E8E9000308E8400303C +:108240000E0002138F0500848F8500D0000291403C +:108250000002990090AF00BC0253882100403021F9 +:1082600031E7000210E0000302118021000290803B +:108270000212802190B900BC3327000410E00002F4 +:108280000006F880021F80218E9800308F8B00BC82 +:1082900024068000330F0003000F702331CD00034C +:1082A000020D6021AD6C000494A400E294AA00E2E7 +:1082B00094B000E231497FFF2522000130537FFF57 +:1082C0000206182400734025A4A800E294A400E24A +:1082D0003C1408008E94006030917FFF123400221D +:1082E000000000000E000CF6000000008F8700D098 +:1082F0000000282194F300E094F000E21213000F34 +:108300008FBF003090E900D090E800D1313200FFFB +:10831000310400FF0244302B14C0FF36264A00010E +:1083200090EE00D2264B000131CD00FF008D602180 +:10833000158BFF338F9100B08FBF00308FB7002CAB +:108340008FB600288FB500248FB400208FB3001C97 +:108350008FB200188FB100148FB0001000A0102150 +:1083600003E0000827BD003894A300E20066402423 +:10837000A4A800E290A400E290B900E2309100FFCE +:108380000011A1C20014F827001F39C03332007F4A +:10839000024730250A000DE8A0A600E23084FFFF66 +:1083A00030A5FFFFAF440018AF45001C03E00008F4 +:1083B0008F42001427BDFFB8AFB000208F9000D0CF +:1083C0003084FFFFAFA40010AFBF0044AFBE004039 +:1083D000AFB7003CAFB60038AFB50034AFB4003033 +:1083E000AFB3002CAFB20028AFB10024A7A0001893 +:1083F000920600D1920500D030C400FF30A300FFE8 +:108400000064102B10400122AFA00014920900D08C +:108410008FB50010312800FF0088382324F4FFFFB7 +:108420000014882B0015982B02339024524001260B +:108430008FB40014961E0012961F00108FB7001004 +:1084400003DFC823001714000019C400000224032E +:108450000018140302E2B02A52C00001004020219B +:108460000284282B10A0000200801821028018210D +:1084700000033C0000071C033064FFFF2C8600094A +:1084800014C000020060B821241700088E0A0008FA +:10849000001769808E09000C31ABFFFF3C0C001007 +:1084A000016C402527520400AF4A0038AF9200B853 +:1084B000AF49003CAF480030000000000000000061 +:1084C00000000000000000000000000000000000AC +:1084D00000000000000000008F4F000031EE00207F +:1084E00011C0FFFD0017982A027110240A000E83A4 +:1084F0000000B02155E001019258000131130080C5 +:10850000126001CF012020219655001232A5FFFFF5 +:108510000E000CCBA7B500188F9000D00291A023BD +:1085200026CD00018F9100B8000DB4000016B403F1 +:108530002638004002D7582A0014882B2405000151 +:108540000300902101711024AF9800B8AFA500146A +:10855000104001BC8F8900B03C0C08008D8C005489 +:10856000240BFF80921E00D001895021014B28244A +:10857000921900D0AF4500288E4700103C08080033 +:108580008D0800583C1808008F18005430E33FFF56 +:108590000003218001043021012658212402FF809C +:1085A0000162F824920C00D0AF5F002C92480000CA +:1085B00033D100FF333500FF0309982100117140CA +:1085C000001578C0326D007F01CF382101BA282113 +:1085D000318300FF3164007F3C0A000C00AA88212F +:1085E0000367F02100033140009A10213108003F59 +:1085F0003C1F000E00D1C021005F982127D90088C0 +:108600002D150008AF9100C0AF9900ACAF9800BC29 +:10861000AF9300B412A0018A00008821240E00014B +:10862000010E4004310D005D11A0FFB2310F0002B8 +:108630008E4A00283C0300803C04FFEFAE6A000035 +:108640008E450024A260000A3488FFFFAE65000456 +:108650009247002C3C1FFF9F37FEFFFFA267000CD4 +:108660008E62000C3C180040A267000B00433025CE +:1086700000C8C824033E88240238A825AE75000C23 +:108680008E490004AE6000183C0F00FFAE69001474 +:108690008E4D002C35EEFFFF8F8B00B001AE6024B5 +:1086A000AE6C00108E470008A660000896450012C8 +:1086B000AE6700208E42000C30B03FFF00105180AA +:1086C000AE6200248E5E0014014B182130A400011C +:1086D000AE7E00288E590018000331C2000443808A +:1086E000AE79002C8E51001C00C8F821A67F001C1A +:1086F000AE710030965800028E550020A678001EFC +:10870000AE75003492490033313000045600000544 +:10871000925000008F8C00D08D8B007CAE6B0030AF +:10872000925000008F8F00BCA1F00000924E0033E9 +:1087300031CD000251A00007925E00018F8900BC7C +:108740002418FF80913100000311A825A1350000F5 +:10875000925E00018F9900BC2409FFBF240BFFDF4C +:10876000A33E00018F9500BC92B8000D3311007F2D +:10877000A2B1000D8F8E00BC91D0000D02097824AB +:10878000A1CF000D8F8800BC8E6D0014910A000DE2 +:108790002DAC0001000C2940014B382400E51825C0 +:1087A000A103000D964200128F8800BC8F8700D075 +:1087B000A50200028E45000490FF00BC30A4000317 +:1087C0000004302330DE000300BE102133F9000224 +:1087D00017200002244400342444003090E200BCFE +:1087E00000A2302430DF000417E0000224830004DC +:1087F000008018218F8F00AC24090002AD03000413 +:10880000A1E90000924E003F8F8D00ACA1AE0001A7 +:108810008F9500AC924C003F8E440004A6AC000241 +:10882000976B003C0E000CD63170FFFF00025380A6 +:10883000020A38253C05420000E51825AEA30004D5 +:108840008F8600AC8E480038ACC800188E440034C7 +:10885000ACC4001CACC0000CACC00010A4C0001420 +:10886000A4C00016A4C00020A4C00022ACC00024F4 +:108870008E6400145080000124040001ACC4000880 +:108880000E000CF6241100010A000E768F9000D025 +:10889000920F00D2920E00D08FB5001031EB00FF86 +:1088A00031CD00FF008D6023016C50212554FFFF66 +:1088B0000014882B0015982B023390241640FEDDFF +:1088C000000000008FB400148FBF00448FBE004032 +:1088D0003A8200018FB7003C8FB600388FB5003464 +:1088E0008FB400308FB3002C8FB200288FB10024DA +:1088F0008FB0002003E0000827BD0048331100209E +:10890000122000EF24150001921E00BC241F00015C +:108910000000A82133D900011320000DAFBF001CB7 +:108920008E4400148E0800840088102B144000022E +:10893000008030218E0600848E03006400C3A82BC3 +:1089400016A0000200C020218E0400640080A8212F +:108950008E4700148E05006400E5302B14C0000221 +:1089600000E020218E0400640095F02313C0000471 +:108970008FAC001C240A0002AFAA001C8FAC001CA4 +:10898000028C582B156000A8000018218E4F00386B +:108990008E6D000C3C0E0080AE6F00008E4A0034DD +:1089A0003C10FF9F01AE5825AE6A00049246003F7E +:1089B000360CFFFF016C38243C0500203C03FFEF20 +:1089C000A266000B00E510253468FFFF8F8700B812 +:1089D0000048F8243C04000803E4C825AE79000CE4 +:1089E0008CF80014AE60001802BE7821AE78001436 +:1089F0008CF10018AE71001C8CE90008AE690024EF +:108A00008CEE000CAE6F002CAE600028AE6E002025 +:108A1000A6600038A660003A8CED001401B58023F2 +:108A2000021E902312400011AE72001090EA003D29 +:108A30008E6500048E640000000A310000A6C82183 +:108A4000000010210326402B0082F82103E8C021FA +:108A5000AE790004AE78000090F1003DA271000AEA +:108A60008F8900B895320006A67200088F9800AC76 +:108A70002419000202A02021A31900009769003CDC +:108A80008F9200AC0E000CD63131FFFF00027B80CC +:108A90008F8500B8022F68253C0E420001AE80256C +:108AA000AE5000048F8400AC8CAC0038AC8C001845 +:108AB0008CAB0034AC8B001CAC80000CAC80001084 +:108AC000A4800014A4800016A4800020A4800022AA +:108AD000AC80002490A7003FA487000212A00135BB +:108AE0002403000153C0000290A2003D90A2003E6A +:108AF00024480001A08800018F9F00ACAFF500085A +:108B00008F8300D024070034906600BC30C500027B +:108B100050A00001240700308F9200B88F8A00BC5B +:108B2000906D00BC924B00002412C00032A50003DF +:108B3000A14B00008F8600B88F8800BC240200047F +:108B400090C400010045182330790003A1040001FE +:108B50008F8A00BC8F9F00B800F53821955800021D +:108B600097E9001200F9382103128824312F3FFFC2 +:108B7000022F7025A54E00029150000231A800047A +:108B8000320C003F358B0040A14B000212A00002C6 +:108B90008F8500BC00E838218F8E00D0ACA7000480 +:108BA000240BFFBF8DCD007C2EA400012403FFDF2A +:108BB000ACAD000890B0000D00044140320C007FC5 +:108BC000A0AC000D8F8600BC90CA000D014B102494 +:108BD000A0C2000D8F8700BC90E5000D00A3F82413 +:108BE00003E8C825A0F9000D8F9100B88F8D00BC57 +:108BF0008E380020ADB800108E290024ADA90014D5 +:108C00008E2F0028ADAF00188E2E002C0E000CF613 +:108C1000ADAE001C8FB0001C240C0002120C00EE44 +:108C20008F9000D08FA3001C006088211460000288 +:108C30000060A8210000A02156A0FE390291A023C7 +:108C40000014882B8FA90010960700103C1E0020EE +:108C50000136402302C750213112FFFFA60A00103F +:108C6000AFB20010AF5E0030000000009617001099 +:108C7000961300121277008F000000008E05000C82 +:108C80008E0B00080016698000AD7021000DC7C36F +:108C900001CDA82B0178782101F56021AE0E000CE2 +:108CA000AE0C00088FB300100013B82B02378024DD +:108CB0001200FF048F9000D00A000E3C000000005C +:108CC0008E4D0038A6600008240B0003AE6D000036 +:108CD0008E500034A260000A8F9800B8AE70000475 +:108CE0003C0500809311003FA26B000C8E6F000CBE +:108CF0003C0EFF9FA271000B01E5102535CCFFFF54 +:108D00003C03FFEF8F9200B8004C30243464FFFF27 +:108D100000C4F824AE7F000C8E590014964800124F +:108D20008F8A00B0AE7900108E490014AE60001832 +:108D3000AE600020AE690014AE6000248E470018BB +:108D400031093FFF0009F180AE6700288E4D000811 +:108D500003CA802131180001AE6D00308E4F000C27 +:108D60008F8C00AC001089C200185B80022B282178 +:108D7000240E0002A665001CA6600036AE6F002C13 +:108D8000A18E00009763003C8F8A00AC3C04420037 +:108D90003062FFFF00443025AD4600048F9F00B8CD +:108DA000240700012411C0008FF30038240600348A +:108DB000AD5300188FF90034AD59001CAD40000CC4 +:108DC000AD400010A5400014A5400016A5400020AD +:108DD000A5400022AD400024A5550002A147000196 +:108DE0008F9E00AC8F8800B88F9200BCAFD5000872 +:108DF000910D0000A24D00008F9000B88F8B00BC39 +:108E000092180001A17800018F8400BC94850002B3 +:108E100000B1782401E97025A48E0002908C000234 +:108E20003183003FA08300028F8300D08F8400BC79 +:108E3000906200BC305300025260000124060030F2 +:108E4000AC8600048C6F007C2403FFBF02A0882145 +:108E5000AC8F0008908E000D31CC007FA08C000DEF +:108E60008F8600BC90C2000D00432024A0C4000DDA +:108E70008F8900BC913F000D37F90020A139000D0A +:108E80008F8800B88F9300BC8D070020AE6700105C +:108E90008D0A0024AE6A00148D1E0028AE7E0018D4 +:108EA0008D12002C0E000CF6AE72001C0A00103D54 +:108EB0008F9000D0960E00148E03000431CCFFFF7B +:108EC000000C10C000622021AF44003C8E1F000443 +:108ED0008F46003C03E6C8231B20003C0000000036 +:108EE0008E0F000025E200013C05001034B500089B +:108EF000AF420038AF550030000000000000000015 +:108F00000000000000000000000000000000000061 +:108F100000000000000000008F580000330B00200C +:108F20001160FFFD000000008F5304003C0D002085 +:108F3000AE1300088F570404AE17000CAF4D00307D +:108F4000000000003C0608008CC600442416000106 +:108F500010D600BD00000000961F00123C0508005E +:108F60008CA5004000BFC821A61900129609001464 +:108F700025270001A6070014960A00143144FFFFBC +:108F80005486FF498FB30010A60000140E000E1681 +:108F900030A5FFFF3C0408008C84002496030012D7 +:108FA0000044102300623023A60600120A00105964 +:108FB0008FB30010A08300018F8200AC2404000155 +:108FC000AC4400080A000FF08F8300D08E0200002E +:108FD0000A0010EA3C0500108F8200C08FA7001C19 +:108FE000921800D0920B00D0920E00D0331100FFE7 +:108FF000316900FF00117940000928C001E56021B6 +:1090000031C300FF036C50210003314000C2C8216E +:10901000255F0088AF9F00ACAF9900BCA1470088D6 +:109020009768003C03C020218F9100AC0E000CD645 +:109030003110FFFF00026B80020DC0253C0442008E +:109040008F8D00B803045825AE2B00048DA900387D +:109050008F8B00AC0000882100118100AD690018E1 +:109060008DAF00343C087FFF3504FFFFAD6F001C5F +:1090700091AC003E8D65001C8D660018000C190037 +:10908000000C770200A33821020E102500E3F82B14 +:1090900000C2C821033F5021AD67001CAD6A001813 +:1090A000AD60000CAD60001091B8003E24050005D5 +:1090B00003C45024A578001495A9000403C02021FE +:1090C000A569001691AF003EA56F002095B1000480 +:1090D000A5710022AD60002491AE003FA56E000294 +:1090E00091B0003E91AC003D01901023244300015B +:1090F000A16300018F8600AC8F9F00BCACDE00082E +:10910000A3E500008F9000BC8F9900B82405FFBF35 +:1091100096070002973800120247782433093FFF70 +:1091200001E98825A6110002921200022418FFDF2F +:10913000324E003F35CD0040A20D00028F8600BCAC +:109140008F8C00D02412FFFFACC000048D8B007CFC +:109150003C0C8000ACCB000890C2000D3043007F77 +:10916000A0C3000D8F8700BC90FF000D03E5C8244D +:10917000A0F9000D8F9100BC9229000D01387824D0 +:10918000A22F000D8F9000BCAE120010AE1500147F +:10919000920E00182415FF8002AE6825A20D00185B +:1091A0008F8500BC8F8300B88CAB0018016C102435 +:1091B000004A3025ACA600189068003EA0A8001C0C +:1091C0008F9F00B88F8700BC8F9800D097F900045C +:1091D000A4F9001E0E0002138F0500848F8600D0B4 +:1091E000000279400002490090D200BC01E98821C8 +:1091F000004028213255000212A0000303D1202193 +:109200000002A8800095202190CD00BC31B200045E +:109210001240000333DF0003000540800088202156 +:10922000240600048F9E00BC00DFC8233327000300 +:1092300000875021AFCA00040E000CF6A665003866 +:109240000A0010388F9000D0961E00123C080800CB +:109250008D080024011E9021A61200120A00105948 +:109260008FB3001027BDFFE03C1808008F18005096 +:10927000AFB00010AFBF0018AFB10014AF8400B0A2 +:1092800093710074030478212410FF8031EE007F75 +:109290003225007F01F0582401DA68213C0C000AD5 +:1092A000A38500C401AC2821AF4B002494A9001071 +:1092B0009768000690A600620080382124020030E2 +:1092C0000109202330C300F0AF8500D010620019DF +:1092D0003090FFFF90AE0062240DFFF0240A005092 +:1092E00001AE6024318B00FF116A002F00000000E6 +:1092F00016000007241F0C00AF5F00248FB100147C +:109300008FBF00188FB0001003E0000827BD0020B9 +:109310000E000E1C02002021241F0C00AF5F002451 +:109320008FB100148FBF00188FB0001003E0000849 +:1093300027BD002094A200E094A400E290BF011396 +:10934000008218263079FFFF33E700C014E00009DF +:109350002F31000116000038000000005620FFE603 +:10936000241F0C000E000D18000000000A0011ED73 +:10937000241F0C001620FFDE000000000E000D1858 +:10938000000000001440FFDC241F0C001600002227 +:109390008F8300D0906901133122003FA062011336 +:1093A0000A0011ED241F0C0094AF00D48F8600D466 +:1093B00000E02821240400050E000C5C31F0FFFFC2 +:1093C0001440000524030003979100E600001821D3 +:1093D0002625FFFFA78500E68F5801B80700FFFE8E +:1093E0003C196013AF400180241F0C00AF50018472 +:1093F000007938253C101000AF4701888FB1001468 +:10940000AF5001B8AF5F00248FB000108FBF0018BD +:1094100003E0000827BD00200E000E1C02002021E2 +:109420005040FFB5241F0C008F8300D090690113BA +:109430000A0012163122003F0E000E1C02002021ED +:109440001440FFAD241F0C00122000078F8300D0B2 +:10945000906801133106003F34C20040A06201133E +:109460000A0011ED241F0C000E000D180000000072 +:109470005040FFA1241F0C008F8300D0906801137F +:109480003106003F0A00124634C20040AF9B00C8BC +:1094900003E00008AF8000EC3089FFFF0009404284 +:1094A0002D020041000921801440000200095040B3 +:1094B00024080040000830C0000811400046582130 +:1094C000256701A800E2C821272F007F2418FF800C +:1094D00001F818240064302100CA702125CC00FF57 +:1094E000240DFF00018D202425650088240A0088B2 +:1094F0003C010800AC2A004C3C010800AC2500509F +:10950000AF8400D43C010800AC2900603C01080095 +:10951000AC2800643C010800AC2700543C01080062 +:10952000AC2300583C010800AC26005C03E00008B6 +:1095300000000000308300FF30C6FFFF30E400FF72 +:109540008F4201B80440FFFE00034C00012438257F +:109550003C08600000E820253C031000AF45018076 +:10956000AF460184AF44018803E00008AF4301B86F +:109570008F86001C3C096012352700108CCB00043C +:109580003C0C600E35850010316A00062D48000144 +:10959000ACE800C48CC40004ACA431808CC20008C8 +:1095A00094C30002ACA2318403E00008A78300E466 +:1095B0003C0308008C6300508F8400E88F86001CF9 +:1095C0002402FF800064C0210302C824AF59002890 +:1095D0008CCD00043305007F00BA78213C0E000CCE +:1095E00001EE2821ACAD00588CC80008AF8500D032 +:1095F0003C076012ACA8005C8CCC001034E8001072 +:10960000ACAC000C8CCB000CACAB000894AA0014E2 +:109610003C0208008C42004425490001A4A9001422 +:1096200094A400143083FFFF106200178F8400D0D1 +:109630003C0A08008D4A0040A4AA00128CCE0018F3 +:10964000AC8E00248CCD0014AC8D00208CC700188B +:10965000AC87002C8CCC001424060001AC8C0028B4 +:109660008D0B00BC5166001A8D0200B48D0200B84B +:10967000A482003A948F003AA48F003C948800D4CE +:1096800003E000083102FFFF3C0908008D29002497 +:10969000A4A000148F8400D0A4A900128CCE0018BE +:1096A000AC8E00248CCD0014AC8D00208CC700182B +:1096B000AC87002C8CCC001424060001AC8C002854 +:1096C0008D0B00BC5566FFEA8D0200B88D0200B418 +:1096D000A482003A948F003AA48F003C948800D46E +:1096E00003E000083102FFFF8F86001C3C0C0800DD +:1096F0008D8C0050240BFF808CCD00083C03000CA7 +:10970000000D51C0018A4021010B4824AF8A00E8B6 +:10971000AF49002890C700073105007F00BA10212B +:109720000043282130E4000410800039AF8500D0C8 +:1097300090CF000731EE000811C000380000000093 +:109740008CD9000C8CC400140324C02B13000030EF +:10975000000000008CC2000CACA200648CCD00188C +:109760002402FFF8ACAD00688CCC0010ACAC0080DB +:109770008CCB000CACAB00848CCA001CACAA007C67 +:1097800090A900BC01224024A0A800BC90C30007FF +:109790003067000810E000048F8500D090AF00BC57 +:1097A00035EE0001A0AE00BC90D9000733380001AF +:1097B000130000088F8300D08F8700D0240400346A +:1097C00090E800BC35030002A0E300BC8F8300D00A +:1097D000AC6400C090C900073126000210C000052B +:1097E00000000000906A00BC35420004A06200BC8A +:1097F0008F8300D09065011330AD003FA06D011341 +:109800008F8C00D0958B00D403E000083162FFFFFD +:109810008CC200140A001305000000000A001306A1 +:10982000ACA0006427BDFFD8AFB000108F90001C23 +:10983000AFBF0024AFB40020AFB20018AFB1001426 +:10984000AFB3001C9613000E3C07600A3C14600680 +:109850003264FFFF369300100E00125534F40410EA +:109860008F8400D43C11600E0E00099B363100102D +:10987000920E00153C0708008CE700603C12601255 +:1098800031CD000FA38D00F08E0E00048E0D000868 +:1098900096080012961F00109619001A9618001EBE +:1098A000960F001C310CFFFF33EBFFFF332AFFFF45 +:1098B0003309FFFF31E6FFFF3C010800AC2B0040FD +:1098C0003C010800AC2C00243C010800AC2A0044F8 +:1098D000AE293178AE26317C92020015960300162F +:1098E00036520010304400FF3065FFFF3C06080090 +:1098F0008CC60064AE243188AE4500B492080014D2 +:1099000096190018241F0001011FC004332FFFFF08 +:109910003C0508008CA50058AE5800B8AE4F00BCFE +:10992000920C0014AF8E00D8AF8D00DC318B00FF9D +:10993000AE4B00C0920A0015AE670048AE66004C00 +:10994000314900FFAE4900C8AE65007C3C03080009 +:109950008C6300503C0408008C84004C3C080800D8 +:109960008D0800543C0208008C42005C8FBF00242C +:10997000AE6300808FB00010AE8300748FB3001C04 +:10998000AE22319CAE4200DCAE2731A0AE2631A41F +:10999000AE24318CAE233190AE283194AE2531986F +:1099A000AE870050AE860054AE8500708FB10014B3 +:1099B000AE4700E0AE4600E4AE4400CCAE4300D07B +:1099C000AE4800D4AE4500D88FB400208FB2001846 +:1099D00003E0000827BD002827BDFFE0AFB1001459 +:1099E000AFBF0018241100010E000845AFB00010F1 +:1099F00010510005978400E6978300CC0083102B5C +:109A0000144000088F8500D4240700028FBF00187F +:109A10008FB100148FB0001000E0102103E00008A7 +:109A200027BD00200E000C7A24040005AF8200E858 +:109A30001040FFF6240700020E0008498F90001C1A +:109A4000979F00E68F9900E88F8D00C827EF0001EF +:109A5000240E0050AF590020A78F00E6A1AE0000F1 +:109A60003C0C08008D8C00648F8600C8240A80009E +:109A7000000C5E00ACCB0074A4C0000694C9000AC0 +:109A8000241FFF803C0D000C012AC024A4D8000A2A +:109A900090C8000A24182000011F1825A0C3000A3E +:109AA0008F8700C8A0E000788F8500C800003821AB +:109AB000A0A000833C0208008C4200508F8400E884 +:109AC0000044782101FFC824AF590028960B0002FA +:109AD00031EE007F01DA6021018D3021A4CB00D46A +:109AE000960A0002AF8600D03C0E000425492401EE +:109AF000A4C900E68E080004ACC800048E03000868 +:109B0000ACC30000A4C00010A4C00014A0C000D0CA +:109B10008F8500D02403FFBFA0A000D13C04080023 +:109B20008C8400648F8200D0A04400D28E1F000C71 +:109B30008F8A00D0978F00E4AD5F001C8E19001053 +:109B400024100030AD590018A5400030A551005434 +:109B5000A5510056A54F0016AD4E0068AD580080C7 +:109B6000AD580084914D006231AC000F358B001070 +:109B7000A14B00628F8600D090C900633128007F1E +:109B8000A0C800638F8400D02406FFFF9085006387 +:109B900000A31024A08200638F9100D000E0102168 +:109BA000923F00BC37F90001A23900BC8F8A00D077 +:109BB000938F00F0AD580064AD5000C0914E00D3BB +:109BC000000F690031CC000F018D5825A14B00D347 +:109BD0008F8500D08F8900DCACA900E88F8800D881 +:109BE0008FBF00188FB100148FB0001027BD002068 +:109BF000ACA800ECA4A600D6A4A000E0A4A000E2BB +:109C000003E000080000000027BDFFE0AFB0001037 +:109C10008F90001CAFB10014AFBF00188E19000464 +:109C20003C1808008F180050240FFF80001989C0CD +:109C30000238702131CD007F01CF602401BA50215C +:109C40003C0B000CAF4C0028014B4021950900D47F +:109C5000950400D68E0700043131FFFFAF8800D095 +:109C60000E000913000721C08E0600048F8300C870 +:109C7000000629C0AF4500209064003E30820040BD +:109C8000144000068F8400D0341FFFFF948300D659 +:109C90003062FFFF145F000400000000948400D6CF +:109CA0000E0008A83084FFFF8E050004022030213A +:109CB0008FBF00188FB100148FB000102404002251 +:109CC00000003821000529C00A00127C27BD0020B1 +:109CD00027BDFFE0AFB100143091FFFFAFB000101F +:109CE000AFBF00181220001D000080218F86001CCD +:109CF0008CC500002403000600053F020005140285 +:109D000030E4000714830015304500FF2CA800063E +:109D10001100004D000558803C0C0800258C57D4DC +:109D2000016C50218D490000012000080000000056 +:109D30008F8E00EC240D000111CD005900000000B1 +:109D4000260B00013170FFFF24CA00200211202BD6 +:109D5000014030211480FFE6AF8A001C0200102170 +:109D60008FBF00188FB100148FB0001003E00008FF +:109D700027BD0020938700CE14E00038240400148F +:109D80000E001338000000008F86001C2402000122 +:109D90000A00147FAF8200EC8F8900EC24080002D7 +:109DA0001128003B2404001300002821000030216A +:109DB000240700010E00127C000000000A00147F3E +:109DC0008F86001C8F8700EC2405000214E5FFF647 +:109DD000240400120E0012E9000000008F8500E844 +:109DE00000403021240400120E00127C00003821B3 +:109DF0000A00147F8F86001C8F8300EC241F000351 +:109E0000147FFFD0260B00010E00129B0000000003 +:109E10008F8500E800403021240200022404001055 +:109E200000003821AF8200EC0E00127C0000000020 +:109E30000A00147F8F86001C8F8F00EC240600021E +:109E400011E6000B0000000024040010000028218F +:109E5000000030210A00149C240700010000282182 +:109E60000E00127C000030210A00147F8F86001C37 +:109E70000E0013A500000000144000128F99001C72 +:109E80008F86001C240200030A00147FAF8200ECBE +:109E90000E001431000000000A00147F8F86001CA1 +:109EA0000E00128B000000002402000224040014A3 +:109EB0000000282100003021000038210A0014B9D8 +:109EC000AF8200EC004038212404001097380002D3 +:109ED000000028210E00127C3306FFFF0A00147FC9 +:109EE0008F86001C8F8400C83C077FFF34E6FFFF8D +:109EF0008C8500742402000100A61824AC83007431 +:109F000003E00008A082000510A000362CA200800B +:109F1000274A04003C0B000524090080104000077C +:109F20002408008030A6000F00C540212D030081C9 +:109F30001460000200A0482124080080AF4B0030CC +:109F400000000000000000000000000011000009F7 +:109F500000003821014030218C8D000024E70004EE +:109F600000E8602BACCD0000248400041580FFFACB +:109F700024C60004000000000000000000000000F3 +:109F80003C0E0006010E3825AF47003000000000EF +:109F900000000000000000008F4F000031E80010BA +:109FA0001100FFFD000000008F42003C8F43003C89 +:109FB0000049C8210323C02B130000040000000047 +:109FC0008F4C003825860001AF4600388F47003C93 +:109FD00000A9282300E96821AF4D003C14A0FFCE62 +:109FE0002CA2008003E000080000000027BDFFD085 +:109FF0003C020002AFB100143C11000CAF45003828 +:10A00000AFB3001CAF46003C00809821AF42003047 +:10A0100024050088AF44002803512021AFBF002849 +:10A02000AFB50024AFB40020AFB200180E0014F199 +:10A03000AFB000103C1F08008FFF004C3C18080018 +:10A040008F1800642410FF8003F3A82132B9007F29 +:10A0500002B078240018A0C0033A70210018914083 +:10A0600001D12021AF4F00280E0014F10254282105 +:10A070003C0D08008DAD00502405012001B358218E +:10A08000316C007F01705024019A48210131202158 +:10A090000E0014F1AF4A00283C0808008D08005457 +:10A0A0003C0508008CA500640113382130E6007FD0 +:10A0B00000F0182400DA202100912021AF4300286D +:10A0C0000E0014F1000529403C0208008C420058A3 +:10A0D0003C1008008E1000601200001C0053882104 +:10A0E0002415FF800A0015743C14000C3226007FF2 +:10A0F0000235182400DA202102402821AF4300282D +:10A10000009420210E0014F12610FFC01200000F51 +:10A11000023288212E05004110A0FFF42412100005 +:10A120003226007F001091800235182400DA2021A9 +:10A1300002402821AF430028009420210E0014F192 +:10A14000000080211600FFF3023288213C0B08003A +:10A150008D6B005C240AFF802405000201734021FE +:10A16000010A4824AF4900283C0408009484006296 +:10A170003110007F021A88213C07000C0E000CAA47 +:10A180000227982100402821026020218FBF00284B +:10A190008FB500248FB400208FB3001C8FB200183D +:10A1A0008FB100148FB000100A0014F127BD0030E9 +:10A1B0008F83001C8C62000410400003000000002C +:10A1C00003E00008000000008C6400108C650008AB +:08A1D0000A00152A8C66000C40 +:08A1D800000000000000001B64 +:10A1E0000000000F0000000A000000080000000648 +:10A1F000000000050000000500000004000000044D +:10A200000000000300000003000000030000000342 +:10A210000000000300000002000000020000000235 +:10A220000000000200000002000000020000000226 +:10A230000000000200000002000000020000000216 +:10A240000000000200000002000000020000000206 +:0CA25000000000010000000100000001FF +:04A25C0008000F24C3 +:10A2600008000D6C08000FB80800106008000F4CC3 +:10A2700008000F8C0800119408000D88080011B820 +:10A2800008000DD8080015540800151C08000D889A +:10A2900008000D8808000D880800124008001240D0 +:10A2A00008000D8808000D88080014E008000D88DB +:10A2B00008000D8808000D8808000D88080013B4F8 +:10A2C00008000D8808000D8808000D8808000D881A +:10A2D00008000D8808000D8808000D8808000D880A +:10A2E00008000D8808000D8808000D8808000D88FA +:10A2F00008000D8808000D8808000FAC08000D88C4 +:10A3000008000D880800167808000D8808000D88E0 +:10A3100008000D8808000D8808000D8808000D88C9 +:10A3200008000D8808000D8808000D8808000D88B9 +:10A3300008000D8808000D8808000D8808000D88A9 +:10A3400008000D8808000D8808000D88080014100A +:10A3500008000D8808000D8808001334080012A4B6 +:10A3600008001E2C08001EFC08001F1408001F28EF +:10A3700008001F3808001E2C08001E2C08001E2C88 +:10A3800008001ED808002E1408002E1C08002DE41A +:10A3900008002DF008002DFC08002E08080052F4DB +:10A3A000080052B40800528008005254080052308D +:04A3B000080051EC64 +:0CA3B4000A000C84000000000000000003 +:10A3C0000000000D727870362E322E310000000031 +:10A3D0000602010300000000000000010000000070 +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000008000000000000000000B +:10D5A000000000000000000000000000000000007B +:10D5B00000000000000000000000000A0000000061 +:10D5C0000000000000000000100000030000000048 +:10D5D0000000000D0000000D3C02080024427320F2 +:10D5E0003C030800246377ACAC4000000043202BD0 +:10D5F0001480FFFD244200043C1D080037BD7FFC61 +:10D6000003A0F0213C100800261032103C1C08003A +:10D61000279C73200E0010FE000000000000000D8B +:10D6200030A5FFFF30C600FF274301808F4201B8BD +:10D630000440FFFE24020002AC640000A465000860 +:10D64000A066000AA062000B3C021000AC67001844 +:10D6500003E00008AF4201B83C0360008C624FF861 +:10D660000440FFFE3C020200AC644FC0AC624FC4F9 +:10D670003C02100003E00008AC624FF89482000CFA +:10D680002486001400A0382100021302000210803A +:10D690000082402100C8102B1040005700000000FD +:10D6A00090C300002C6200095040005190C200015C +:10D6B000000310803C030800246372D00043102153 +:10D6C0008C420000004000080000000090C30001F0 +:10D6D0002402000A1462003A000000000106102330 +:10D6E0002C42000A1440003624C600028CE20000DE +:10D6F00034420100ACE2000090C2000090C300017F +:10D7000090C4000290C5000300031C000002160034 +:10D710000043102500042200004410250045102578 +:10D7200024C60004ACE2000490C2000090C30001D3 +:10D7300090C4000290C500030002160000031C0004 +:10D740000043102500042200004410250045102548 +:10D7500024C600040A000CB8ACE2000890C3000123 +:10D76000240200041462001624C6000290C20000C5 +:10D7700090C400018CE30000000212000044102558 +:10D780003463000424C60002ACE2000C0A000CB8AA +:10D79000ACE3000090C300012402000314620008FF +:10D7A00024C600028CE2000090C3000024C60001E1 +:10D7B00034420008A0E300100A000CB8ACE20000FC +:10D7C00003E000082402000190C3000124020002CB +:10D7D0001062000224C40002010020210A000CB8DB +:10D7E000008030210A000CB824C6000190C200015C +:10D7F0000A000CB800C2302103E00008000010212C +:10D8000027BDFFE8AFBF0014AFB000100E00130239 +:10D8100000808021936200052403FFFE0200202186 +:10D82000004310248FBF00148FB00010A3620005C6 +:10D830000A00130B27BD001827BDFFE8AFB000108A +:10D84000AFBF00140E000F3C0080802193620000E7 +:10D8500024030050304200FF14430004240201005E +:10D86000AF4201800A000D3002002021AF4001804C +:10D87000020020218FBF00148FB000100A000FE7B4 +:10D8800027BD001827BDFF80AFBE0078AFB700747A +:10D89000AFB20060AFBF007CAFB60070AFB5006C38 +:10D8A000AFB40068AFB30064AFB1005CAFB0005874 +:10D8B0008F5001283C0208008C4231A02403FF80D5 +:10D8C0009365003F0202102100431024AF42002460 +:10D8D0003C0208008C4231A09364000530B200FF86 +:10D8E000020210213042007F034218210004202749 +:10D8F0003C02000A0062182130840001AF8300144A +:10D900000000F0210000B82114800053AFA00050A7 +:10D9100093430116934401128F450104306300FFC5 +:10D920003C020001308400FF00A2282403431021A0 +:10D9300003441821245640002467400014A001CD60 +:10D940002402000193620000304300FF2402002003 +:10D950001062000524020050106200060000000062 +:10D960000A000D74000000000000000D0A000D7D8B +:10D97000AFA000303C1E080027DE736C0A000D7D4E +:10D98000AFA000303C0208008C4200DC24420001C1 +:10D990003C010800AC2200DC0E00139F00000000D8 +:10D9A0000A000F318FBF007C8F4201043C0300202E +:10D9B00092D3000D004310240002202B00042140CC +:10D9C000AFA400308F4301043C02004000621824E1 +:10D9D000146000023485004000802821326200205B +:10D9E000AFA500301440000234A6008000A0302112 +:10D9F00010C0000BAFA6003093C500088F67004C25 +:10DA00000200202100052B0034A5008130A5F08103 +:10DA10000E000C9B30C600FF0A000F2E0000000015 +:10DA20009362003E304200401040000F2402000488 +:10DA300056420007240200120200202100E02821A3 +:10DA40000E0013F702C030210A000F318FBF007C97 +:10DA500016420005000000000E000D2100002021EC +:10DA60000A000F318FBF007C9743011A96C4000E45 +:10DA700093620035326500043075FFFF00442004D6 +:10DA8000AFA400548ED1000410A000158ED400085D +:10DA90009362003E3042004010400007000000004A +:10DAA0000E0013E0022020211040000D00000000B5 +:10DAB0000A000F2E000000008F6200440222102393 +:10DAC0000440016A000000008F6200480222102317 +:10DAD00004410166240400160A000E218FC20004CE +:10DAE0008F6200480222102304400008000000005A +:10DAF0003C0208008C423100244200013C01080035 +:10DB0000AC2231000A000F23000000008F620040A9 +:10DB100002221023184000128F8400143C020800D7 +:10DB20008C423100327300FC0000A8212442000125 +:10DB30003C010800AC2231008F6300409482011C3C +:10DB4000022318233042FFFF0043102A50400010E8 +:10DB50002402000C8F6200400A000DF20222102302 +:10DB60009483011C9762003C0043102B1040000678 +:10DB7000000000009482011C00551023A482011CA7 +:10DB80000A000DF72402000CA480011C2402000CE2 +:10DB9000AFA200308F620040005120231880000D9A +:10DBA00002A4102A1440012600000000149500066B +:10DBB00002A410233A620001304200011440012007 +:10DBC0000000000002A41023022488210A000E098C +:10DBD0003055FFFF00002021326200021040001A81 +:10DBE000326200109362003E30420040504000110B +:10DBF0008FC200040E00130202002021240200182C +:10DC0000A362003F936200052403FFFE020020216F +:10DC1000004310240E00130BA362000524040039F6 +:10DC2000000028210E0013C9240600180A000F3036 +:10DC300024020001240400170040F809000000003D +:10DC40000A000F302402000110400108000000000B +:10DC50008F63004C8F620054028210231C4001032A +:10DC600002831023044200010060A021AFA4001829 +:10DC7000AFB10010AFB50014934201208F65004092 +:10DC80009763003C304200FF034210210044102102 +:10DC90008FA400543063FFFF244240000083182B00 +:10DCA0008FA40030AFA20020AFA50028008320255C +:10DCB000AFA40030AFA50024AFA0002CAFB4003457 +:10DCC0009362003E30420008504000118FC20000B5 +:10DCD00002C0202127A500380E000CB2AFA00038EA +:10DCE0005440000B8FC200008FA200383042010068 +:10DCF000504000078FC200008FA3003C8F6200607D +:10DD00000062102304430001AF6300608FC2000073 +:10DD10000040F80927A400108FA200303042000212 +:10DD200054400001327300FE9362003E30420040D6 +:10DD3000104000378FA200248F6200541682001A10 +:10DD40003262000124020014124200102A4200151F +:10DD500010400006240200162402000C12420007A4 +:10DD6000326200010A000E7D000000001242000530 +:10DD7000326200010A000E7D000000000A000E78E9 +:10DD80002417000E0A000E78241700100A000E7CDB +:10DD900024170012936200232403FFBD00431024C4 +:10DDA000A362002332620001104000198FA20024F8 +:10DDB0002402000C1242000E2A42000D1040000600 +:10DDC0002402000E2402000A124200078FA200243F +:10DDD0000A000E9524420001124200088FA200247E +:10DDE0000A000E95244200010A000E932417000831 +:10DDF0002402000E16E20002241700162417001059 +:10DE00008FA2002424420001AFA200248FA200248C +:10DE10008FA300148F76004000431021AF620040B2 +:10DE20008F8200149442011C104000090000000081 +:10DE30008F6200488F6400409763003C00441023C9 +:10DE40003063FFFF0043102A104000088FA20054E7 +:10DE5000936400368F6300403402FFFC008210049C +:10DE600000621821AF6300488FA200548FA60030D3 +:10DE70000282902130C200081040000E0000000015 +:10DE80008F6200581642000430C600FF9742011A04 +:10DE90005040000134C6001093C500088FA700341D +:10DEA0000200202100052B0034A500800E000C9BF1 +:10DEB00030A5F0808F620040005610231840001BF0 +:10DEC0008FA200183C0208008C42319830420010AA +:10DED0001040000D24020001976200681440000AFF +:10DEE000240200018F8200149442011C1440000699 +:10DEF00024020001A76200689742007A244200646D +:10DF00000A000EE9A7620012A76200120E001302B7 +:10DF1000020020219362007D2403000102002021E1 +:10DF2000344200010A000EE7AFA300501840000A77 +:10DF3000000000000E001302020020219362007D09 +:10DF40002403000102002021AFA30050344200044A +:10DF50000E00130BA362007D9362003E304200402E +:10DF60001440000C326200011040000A0000000062 +:10DF70008F6300408FC20004240400182463000152 +:10DF80000040F809AF6300408FA200300A000F3054 +:10DF9000304200048F620058105200100000000050 +:10DFA0008F620018022210231C4000082404000184 +:10DFB0008F62001816220009000000008F62001C0A +:10DFC000028210230440000500000000AF720058D8 +:10DFD000AFA40050AF710018AF74001C12E0000B2A +:10DFE0008FA200500E00130202002021A377003FF1 +:10DFF0000E00130B0200202102E030212404003720 +:10E000000E0013C9000028218FA200501040000309 +:10E01000000000000E000CA90200202112A0000543 +:10E02000000018218FA2003030420004504000113F +:10E0300000601021240300010A000F30006010214D +:10E040000E001302020020219362007D02002021B5 +:10E05000344200040E00130BA362007D0E000CA9D5 +:10E06000020020210A000F3024020001AF400044CA +:10E07000240200018FBF007C8FBE00788FB7007430 +:10E080008FB600708FB5006C8FB400688FB30064DA +:10E090008FB200608FB1005C8FB0005803E00008C1 +:10E0A00027BD00808F4201B80440FFFE2402080013 +:10E0B000AF4201B803E00008000000003C02000885 +:10E0C00003421021944200483084FFFF2484001250 +:10E0D0003045FFFF10A0001700A4102B10400016C1 +:10E0E00024020003934201202403001AA343018B5E +:10E0F000304200FF2446FFFE8F82000000A6182B4E +:10E100003863000100021382004310241040000510 +:10E110008F84000434820001A746019403E00008C4 +:10E12000AF8200042402FFFE0082102403E00008F6 +:10E13000AF8200042402000303E00008A342018B25 +:10E1400027BDFFE0AFB10014AFB00010AFBF0018A3 +:10E1500030B0FFFF30D1FFFF8F4201B80440FFFE17 +:10E1600000000000AF440180AF4400200E000F42C9 +:10E17000020020218F8300008F840004A750019AA1 +:10E18000A750018EA74301908F8300083082800042 +:10E19000AF4301A8A75101881040000E8F820004F0 +:10E1A00093420116304200FC24420004005A102120 +:10E1B0008C4240003042FFFF144000068F82000472 +:10E1C0003C02FFFF34427FFF00821024AF82000434 +:10E1D0008F8200042403BFFF00431024A74201A63E +:10E1E0009743010C8F42010400031C003042FFFFE3 +:10E1F00000621825AF4301AC3C021000AF4201B8E9 +:10E200008FBF00188FB100148FB0001003E000081A +:10E2100027BD00208F470070934201128F830000BA +:10E2200027BDFFF0304200FF00022882306201006B +:10E23000000030211040004324A40003306240005D +:10E24000104000103062200000041080005A10219D +:10E250008C43400024A4000400041080AFA30000FD +:10E26000005A10218C424000AFA2000493420116D4 +:10E27000304200FC005A10218C4240000A000FC0BE +:10E28000AFA200081040002F0000302100041080D1 +:10E29000005A10218C43400024A400040004108084 +:10E2A000AFA30000005A10218C424000AFA000082C +:10E2B000AFA200048FA80008000030210000202138 +:10E2C000240A00083C0908002529010003A41021A4 +:10E2D000148A000300042A001100000A0000000054 +:10E2E00090420000248400012C83000C00A2102125 +:10E2F00000021080004910218C4200001460FFF3DE +:10E3000000C230263C0408008C8431048F42007027 +:10E310002C83002010600009004738233C030800CC +:10E32000246331080004108000431021248300017D +:10E33000AC4700003C010800AC233104AF86000864 +:10E340002406000100C0102103E0000827BD0010D2 +:10E350003C0208008C42003827BDFFD0AFB5002436 +:10E36000AFB40020AFB10014AFBF0028AFB3001CA2 +:10E37000AFB20018AFB00010000088213C150800B3 +:10E3800026B50038144000022454FFFF0000A021ED +:10E390009742010E8F8400003042FFFF308340001F +:10E3A0001060000A245200043C0200200082102465 +:10E3B00050400007308280008F8200042403BFFF9A +:10E3C000008318240A0010103442100030828000AC +:10E3D0001040000A3C020020008210241040000778 +:10E3E0008F8200043C03FFFF34637FFF0083182407 +:10E3F00034428000AF820004AF8300000E000F980B +:10E400000000000014400007000000009743011EB8 +:10E410009742011C3063FFFF0002140000621825C0 +:10E42000AF8300089742010C8F4340003045FFFF47 +:10E430003402FFFF14620003000000000A001028ED +:10E44000241100208F42400030420100544000015E +:10E45000241100108F8400003082100050400014FE +:10E4600036310001308200201440000B3C021000C5 +:10E47000008210245040000E363100013C030E0093 +:10E480003C020DFF008318243442FFFF0043102B91 +:10E4900050400007363100013C0208008C42002C3D +:10E4A000244200013C010800AC22002C363100055A +:10E4B0003C0608008CC6003454C000238F85000041 +:10E4C0008F820004304240005440001F8F850000BE +:10E4D0003C021F01008210243C0310005443001A28 +:10E4E0008F85000030A20200144000178F850000C5 +:10E4F0003250FFFF363100028F4201B80440FFFE68 +:10E5000000000000AF400180020020210E000F42F9 +:10E51000AF4000208F8300042402BFFFA750019A60 +:10E52000006218248F820000A750018EA751018835 +:10E53000A74301A6A74201903C021000AF4201B8D8 +:10E540000A0010F5000010213C02100000A2102467 +:10E550001040003A0000000010C0000F0000000052 +:10E5600030A201001040000C3C0302003C020F00EE +:10E5700000A2102410430008000000008F82000851 +:10E58000005410240055102190420004244200043D +:10E590000A00109F000221C00000000000051602C2 +:10E5A0003050000F3A0300022E4203EF38420001C0 +:10E5B0002C6300010062182414600073240200011F +:10E5C0003C0308008C6300D02E06000C386200016A +:10E5D0002C4200010046102414400015001021C0F8 +:10E5E0002602FFFC2C4200045440001100002021B0 +:10E5F000386200022C420001004610241040000343 +:10E60000000512420A00109F000020210010182B64 +:10E610000043102450400006001021C000002021BB +:10E620003245FFFF0E000F633226FFFB001021C0B2 +:10E630003245FFFF0A0010F2362600028F424000EA +:10E640003C0308008C630024304201001040004667 +:10E6500030620001322200043070000D14400002CC +:10E660002413000424130002000512C238420001E2 +:10E670002E4303EF304200013863000100431025B0 +:10E68000104000033231FFFB2402FFFB0202802412 +:10E6900010C000183202000130A201001040001525 +:10E6A000320200013C020F0000A210243C030200D1 +:10E6B0001043000F8F8200082403FFFE0203802412 +:10E6C00000541024005510219042000402333025DC +:10E6D0002442000412000002000221C03226FFFF83 +:10E6E0000E000F633245FFFF1200002700001021CB +:10E6F000320200011040000D320200042402000129 +:10E7000012020002023330253226FFFF00002021D2 +:10E710000E000F633245FFFF2402FFFE0202802439 +:10E7200012000019000010213202000410400016EF +:10E7300024020001240200041202000202333025E8 +:10E740003226FFFF3245FFFF0E000F632404010055 +:10E750002402FFFB020280241200000B00001021A3 +:10E760000A0010F5240200011040000700001021EB +:10E770003245FFFF36260002000020210E000F6305 +:10E7800000000000000010218FBF00288FB500247A +:10E790008FB400208FB3001C8FB200188FB100140B +:10E7A0008FB0001003E0000827BD003027BDFFD068 +:10E7B000AFB000103C04600CAFBF002CAFB6002817 +:10E7C000AFB50024AFB40020AFB3001CAFB2001847 +:10E7D000AFB100148C8250002403FF7F3C1A8000EC +:10E7E000004310243442380CAC8250002402000351 +:10E7F0003C106000AF4200088E0208083C1B8008F5 +:10E800003C010800AC2000203042FFF038420010EC +:10E810002C4200010E001B85AF8200183C04FFFF54 +:10E820003C020400348308063442000CAE0219484E +:10E83000AE03194C3C0560168E0219808CA30000B3 +:10E840003442020000641824AE0219803C02535383 +:10E850001462000334A47C008CA200040050202128 +:10E860008C82007C8C830078AF820010AF83000C18 +:10E870008F55000032A200031040FFFD32A20001BC +:10E880001040013D32A200028F420128AF42002019 +:10E890008F4201048F430100AF8200000E000F3C45 +:10E8A000AF8300043C0208008C4200C01040000806 +:10E8B0008F8400003C0208008C4200C42442000106 +:10E8C0003C010800AC2200C40A00126900000000EC +:10E8D0003C020010008210241440010C8F830004BD +:10E8E0003C0208008C4200203C0308008C63003886 +:10E8F00000008821244200013C010800AC220020D5 +:10E900003C16080026D60038146000022474FFFF6D +:10E910000000A0219742010E308340003042FFFFEB +:10E920001060000A245200043C02002000821024DF +:10E9300050400007308280008F8200042403BFFF14 +:10E94000008318240A0011703442100030828000C5 +:10E950001040000A3C0200200082102410400007F2 +:10E960008F8200043C03FFFF34637FFF0083182481 +:10E9700034428000AF820004AF8300000E000F9885 +:10E980000000000014400007000000009743011E33 +:10E990009742011C3063FFFF00021400006218253B +:10E9A000AF8300089742010C8F4340003045FFFFC2 +:10E9B0003402FFFF14620003000000000A00118807 +:10E9C000241100208F4240003042010054400001D9 +:10E9D000241100108F840000308210005040001479 +:10E9E00036310001308200201440000B3C02100040 +:10E9F000008210245040000E363100013C030E000E +:10EA00003C020DFF008318243442FFFF0043102B0B +:10EA100050400007363100013C0208008C42002CB7 +:10EA2000244200013C010800AC22002C36310005D4 +:10EA30003C0608008CC6003454C000238F850000BB +:10EA40008F820004304240005440001F8F85000038 +:10EA50003C021F01008210243C0310005443001AA2 +:10EA60008F85000030A20200144000178F8500003F +:10EA70003250FFFF363100028F4201B80440FFFEE2 +:10EA800000000000AF400180020020210E000F4274 +:10EA9000AF4000208F8300042402BFFFA750019ADB +:10EAA000006218248F820000A750018EA7510188B0 +:10EAB000A74301A6A74201903C021000AF4201B853 +:10EAC0000A001267000010213C02100000A210246E +:10EAD0001040003A0000000010C0000F00000000CD +:10EAE00030A201001040000C3C0302003C020F0069 +:10EAF00000A2102410430008000000008F820008CC +:10EB000000541024005610219042000424420004B6 +:10EB10000A0011FF000221C00000000000051602DB +:10EB20003050000F3A0300022E4203EF384200013A +:10EB30002C63000100621824146000852402000187 +:10EB40003C0308008C6300D02E06000C38620001E4 +:10EB50002C4200010046102414400015001021C072 +:10EB60002602FFFC2C42000454400011000020212A +:10EB7000386200022C42000100461024504000037D +:10EB8000000512420A0011FF000020210010182B7E +:10EB90000043102450400006001021C00000202136 +:10EBA0003245FFFF0E000F633226FFFB001021C02D +:10EBB0003245FFFF0A001252362600028F42400003 +:10EBC0003C0308008C6300243042010010400046E2 +:10EBD00030620001322200043070000D1440000247 +:10EBE0002413000424130002000512C2384200015D +:10EBF0002E4303EF3042000138630001004310252B +:10EC0000104000033231FFFB2402FFFB020280248C +:10EC100010C000183202000130A20100104000159F +:10EC2000320200013C020F0000A210243C0302004B +:10EC30001043000F8F8200082403FFFE020380248C +:10EC40000054102400561021904200040233302555 +:10EC50002442000412000002000221C03226FFFFFD +:10EC60000E000F633245FFFF120000390000102133 +:10EC7000320200011040000D3202000424020001A3 +:10EC800012020002023330253226FFFF000020214D +:10EC90000E000F633245FFFF2402FFFE02028024B4 +:10ECA0001200002B00001021320200041040002846 +:10ECB0002402000124020004120200020233302563 +:10ECC0003226FFFF3245FFFF0E000F6324040100D0 +:10ECD0002402FFFB020280241200001D000010210C +:10ECE0000A001267240200015040001900001021A0 +:10ECF0003245FFFF36260002000020210E000F6380 +:10ED0000000000000A001267000010212402BFFF6B +:10ED1000006210241040000800000000240287FF59 +:10ED200000621024144000083C020060008210249D +:10ED300010400005000000000E000D34000000002F +:10ED40000A001267000000000E0012C70000000059 +:10ED5000104000063C0240008F4301243C0260202A +:10ED6000AC430014000000003C024000AF420138F8 +:10ED70000000000032A200021040FEBD00000000B2 +:10ED80008F4201403C044000AF4200208F430148C5 +:10ED90003C02700000621824106400420000000071 +:10EDA0000083102B144000063C0260003C0220004F +:10EDB000106200073C0240000A0012C3000000007D +:10EDC0001062003C3C0240000A0012C30000000038 +:10EDD0008F4501408F4601448F42014800021402D2 +:10EDE000304300FF240200041462000A274401801B +:10EDF0008F4201B80440FFFE2402001CAC850000D5 +:10EE0000A082000B3C021000AF4201B80A0012C3FE +:10EE10003C0240002402000914620012000616029F +:10EE2000000229C0AF4500208F4201B80440FFFE18 +:10EE30002402000124030003AF450180A343018B9A +:10EE4000A740018EA740019AA7400190AF4001A8BA +:10EE5000A7420188A74201A6AF4001AC3C021000C6 +:10EE6000AF4201B88F4201B80440FFFE000000002D +:10EE7000AC8500008F42014800021402A482000801 +:10EE800024020002A082000B8F420148A4820010DD +:10EE90003C021000AC860024AF4201B80A0012C345 +:10EEA0003C0240000E001310000000000A0012C3D4 +:10EEB0003C0240000E001BBA000000003C02400073 +:10EEC000AF420178000000000A00112F000000008E +:10EED0008F4201003042003E144000112402000124 +:10EEE000AF4000488F420100304207C0104000058B +:10EEF00000000000AF40004CAF40005003E00008AD +:10EF000024020001AF400054AF4000408F42010096 +:10EF10003042380054400001AF4000442402000158 +:10EF200003E00008000000008F4201B80440FFFE2B +:10EF300024020001AF440180AF400184A74501884D +:10EF4000A342018A24020002A342018B9742014A94 +:10EF500014C00004A7420190AF4001A40A0012EFC0 +:10EF60003C0210008F420144AF4201A43C02100059 +:10EF7000AF4001A803E00008AF4201B88F4201B8DA +:10EF80000440FFFE24020002AF440180AF4401842C +:10EF9000A7450188A342018AA342018B9742014AF7 +:10EFA000A7420190AF4001A48F420144AF4201A8A3 +:10EFB0003C02100003E00008AF4201B83C029000A0 +:10EFC0003442000100822025AF4400208F420020FF +:10EFD0000440FFFE0000000003E000080000000005 +:10EFE0003C028000344200010082202503E000083A +:10EFF000AF44002027BDFFE8AFBF0014AFB0001042 +:10F000008F50014093430149934201489344014882 +:10F01000306300FF304200FF00021200006228252A +:10F020002402001910620076308400802862001AE1 +:10F030001040001C24020020240200081062007707 +:10F04000286200091040000E2402000B2402000177 +:10F0500010620034286200025040000524020006BD +:10F0600050600034020020210A00139A00000000C2 +:10F0700010620030020020210A00139A00000000F4 +:10F080001062003B2862000C504000022402000E77 +:10F090002402000910620056020020210A00139A7F +:10F0A0000000000010620056286200211040000F8E +:10F0B000240200382402001C106200582862001D3F +:10F0C000104000062402001F2402001B1062004CA6 +:10F0D000000000000A00139A000000001062004ABD +:10F0E000020020210A00139A00000000106200456F +:10F0F0002862003910400007240200802462FFCB00 +:10F100002C42000210400045020020210A00139604 +:10F110000000302110620009000000000A00139A6C +:10F12000000000001480003D020020210A0013901E +:10F130008FBF00140A001396240600018F4201B805 +:10F140000440FFFE24020002A342018BA745018870 +:10F150009742014AA74201908F420144A74201927F +:10F160003C021000AF4201B80A00139C8FBF00148C +:10F170009742014A144000290000000093620005F4 +:10F180003042000414400025000000000E0013026D +:10F190000200202193620005020020213442000475 +:10F1A0000E00130BA36200059362000530420004B9 +:10F1B00014400002000000000000000D93620000F7 +:10F1C00024030020304200FF14430014000000001C +:10F1D0008F4201B80440FFFE24020005AF500180B9 +:10F1E000A342018B3C0210000A00139AAF4201B8FF +:10F1F0008FBF00148FB000100A0012F227BD001854 +:10F200000000000D02002021000030218FBF0014FB +:10F210008FB000100A0012DD27BD00180000000D9D +:10F220008FBF00148FB0001003E0000827BD001846 +:10F2300027BDFFE8AFBF00100E000F3C000000002C +:10F24000AF4001808FBF0010000020210A000FE7AF +:10F2500027BD00183084FFFF30A5FFFF00001821F4 +:10F260001080000700000000308200011040000202 +:10F2700000042042006518210A0013AB0005284055 +:10F2800003E000080060102110C0000624C6FFFF44 +:10F290008CA2000024A50004AC8200000A0013B573 +:10F2A0002484000403E000080000000010A000080F +:10F2B00024A3FFFFAC860000000000000000000057 +:10F2C0002402FFFF2463FFFF1462FFFA248400047A +:10F2D00003E0000800000000308300FF30A500FFBD +:10F2E00030C600FF274701808F4201B80440FFFE6F +:10F2F000000000008F42012834634000ACE20000AF +:10F3000024020001ACE00004A4E30008A0E2000A2B +:10F3100024020002A0E2000B3C021000A4E5001051 +:10F32000ACE00024ACE00028A4E6001203E00008F2 +:10F33000AF4201B827BDFFE8AFBF00109362003FA6 +:10F3400024030012304200FF1043000D00803021E2 +:10F350008F620044008210230440000A8FBF001017 +:10F360008F620048240400390000282100C21023C5 +:10F3700004410004240600120E0013C9000000001E +:10F380008FBF00102402000103E0000827BD001811 +:10F3900027BDFFC8AFB20030AFB1002CAFBF003403 +:10F3A000AFB0002890C5000D0080902130A400105F +:10F3B0001080000B00C088218CC300088F620054AD +:10F3C0001062000730A20005144000B524040001BB +:10F3D0000E000D21000020210A0014BB0040202156 +:10F3E00030A200051040000930A30012108000ACCC +:10F3F000240400018E2300088F620054146200A9C7 +:10F400008FBF00340A00142C240400382402001298 +:10F41000146200A3240400010220202127A500106B +:10F420000E000CB2AFA000101040001102402021CD +:10F430008E220008AF620084AF6000400E0013020D +:10F44000000000009362007D024020213442002031 +:10F450000E00130BA362007D0E000CA902402021B8 +:10F46000240400382405008D0A0014B82406001274 +:10F470009362003E304200081040000F8FA200103F +:10F4800030420100104000078FA300148F6200601B +:10F490000062102304430008AF6300600A001441B7 +:10F4A00000000000AF6000609362003E2403FFF79D +:10F4B00000431024A362003E9362003E30420008E5 +:10F4C000144000022406000300003021936200343F +:10F4D000936300378F640084304200FF306300FF85 +:10F4E00000661821000318800043282100A4202B67 +:10F4F0001080000B000000009763003C8F620084C6 +:10F500003063FFFF004510230062182B14600004D5 +:10F51000000000008F6200840A00145D0045802313 +:10F520009762003C3050FFFF8FA300103062000450 +:10F5300010400004000628808FA2001C0A001465F9 +:10F540000202102B2E02021850400003240202185F +:10F550000A00146E020510233063000410600003DB +:10F56000004510238FA2001C00451023004080217D +:10F570002C42008054400001241000800E00130231 +:10F580000240202124020001AF62000C9362003E81 +:10F59000001020403042007FA362003E8E22000413 +:10F5A00024420001AF620040A770003C8F6200500F +:10F5B0009623000E00431021AF6200588F62005066 +:10F5C00000441021AF62005C8E220004AF6200187C +:10F5D0008E220008AF62001C8FA20010304200088B +:10F5E0005440000A93A20020A360003693620036C4 +:10F5F0002403FFDFA36200359362003E0043102422 +:10F60000A362003E0A0014988E220008A36200350F +:10F610008E220008AF62004C8F6200248F6300408E +:10F6200000431021AF6200489362000024030050A1 +:10F63000304200FF144300122403FF803C02080004 +:10F640008C4231A00242102100431024AF42002816 +:10F650003C0208008C4231A08E2400083C03000CC0 +:10F66000024210213042007F03421021004310214A +:10F67000AC4400D88E230008AF820014AC4300DCF9 +:10F680000E00130B02402021240400380000282122 +:10F690002406000A0E0013C9000000002404000123 +:10F6A0008FBF00348FB200308FB1002C8FB0002894 +:10F6B0000080102103E0000827BD003827BDFFF8B7 +:10F6C00027420180AFA20000308A00FF8F4201B8BC +:10F6D0000440FFFE000000008F4601283C020800A5 +:10F6E0008C4231A02403FF80AF86004800C2102165 +:10F6F00000431024AF4200243C0208008C4231A099 +:10F700008FA900008FA8000000C210213042007FA6 +:10F71000034218213C02000A00621821946400D4BC +:10F720008FA700008FA5000024020002AF83001401 +:10F73000A0A2000B8FA30000354260003084FFFFC1 +:10F74000A4E200083C021000AD260000AD04000455 +:10F75000AC60002427BD0008AF4201B803E00008F8 +:10F76000240200018F88003C938200288F830014BC +:10F770003C07080024E7777800481023304200FF58 +:10F78000304900FC246500888F860040304A000321 +:10F790001120000900002021248200048CA3000015 +:10F7A000304400FF0089102AACE3000024A50004C7 +:10F7B0001440FFF924E70004114000090000202153 +:10F7C0002482000190A30000304400FF008A102B27 +:10F7D000A0E3000024A500011440FFF924E7000184 +:10F7E00030C20003144000048F85003C3102000346 +:10F7F0001040000D0000000010A0000900002021B2 +:10F800002482000190C30000304400FF0085102BCB +:10F81000A0E3000024C600011440FFF924E7000122 +:10F8200003E00008000000001100FFFD000020219F +:10F83000248200048CC30000304400FF0088102B99 +:10F84000ACE3000024C600041440FFF924E70004E0 +:10F8500003E00008000000008F83003C9382002832 +:10F8600030C600FF30A500FF00431023304300FFE7 +:10F870008F820014008038210043102114C0000240 +:10F88000244800880083382130E20003144000053A +:10F8900030A2000314400003306200031040000D4A +:10F8A0000000000010A000090000202124820001B7 +:10F8B00090E30000304400FF0085102BA1030000FE +:10F8C00024E700011440FFF92508000103E00008C7 +:10F8D0000000000010A0FFFD000020212482000491 +:10F8E0008CE30000304400FF0085102BAD030000C6 +:10F8F00024E700041440FFF92508000403E0000891 +:10F90000000000000080482130AAFFFF30C600FF41 +:10F9100030E7FFFF274801808F4201B80440FFFE17 +:10F920008F820048AD0200008F420124AD02000426 +:10F930008D220020A5070008A102000A240200165B +:10F94000A102000B934301208D2200088D240004A6 +:10F95000306300FF004310219783003A00441021D8 +:10F960008D250024004310233C0308008C6331A044 +:10F970008F840014A502000C246300E82402FFFF1A +:10F98000A50A000EA5030010A5060012AD0500187B +:10F99000AD020024948201142403FFF73042FFFFDC +:10F9A000AD0200288C820118AD02002C3C02100030 +:10F9B000AD000030AF4201B88D220020004310247A +:10F9C00003E00008AD2200208F82001430E7FFFF23 +:10F9D00000804821904200D330A5FFFF30C600FFD1 +:10F9E0000002110030420F0000E238252748018054 +:10F9F0008F4201B80440FFFE8F820048AD02000034 +:10FA00008F420124AD0200048D220020A5070008CA +:10FA1000A102000A24020017A102000B9343012057 +:10FA20008D2200088D240004306300FF0043102164 +:10FA30009783003A004410218F8400140043102360 +:10FA40003C0308008C6331A0A502000CA505000E44 +:10FA5000246300E8A5030010A5060012AD00001401 +:10FA60008D220024AD0200188C82005CAD02001CC7 +:10FA70008C820058AD0200202402FFFFAD0200245A +:10FA8000948200E63042FFFFAD02002894820060BD +:10FA9000948300BE30427FFF3063FFFF00021200FC +:10FAA00000431021AD02002C3C021000AD000030DC +:10FAB000AF4201B8948200BE2403FFF700A21021D8 +:10FAC000A48200BE8D2200200043102403E0000821 +:10FAD000AD220020274301808F4201B80440FFFE81 +:10FAE0008F8200249442001C3042FFFF000211C0AC +:10FAF000AC62000024020019A062000B3C0210005E +:10FB0000AC60003003E00008AF4201B88F87002CE2 +:10FB100030C300FF8F4201B80440FFFE8F820048CF +:10FB200034636000ACA2000093820044A0A20005F0 +:10FB30008CE20010A4A20006A4A300088C8200207E +:10FB40002403FFF7A0A2000A24020002A0A2000BD7 +:10FB50008CE20000ACA200108CE20004ACA2001405 +:10FB60008CE2001CACA200248CE20020ACA2002895 +:10FB70008CE2002CACA2002C8C820024ACA20018D9 +:10FB80003C021000AF4201B88C82002000431024D8 +:10FB900003E00008AC8200208F86001427BDFFE838 +:10FBA000AFBF0014AFB0001090C20063304200201D +:10FBB0001040000830A500FF8CC2007C2403FFDF4A +:10FBC00024420001ACC2007C90C2006300431024B8 +:10FBD000A0C2006310A000238F830014275001806F +:10FBE000020028210E0015D6240600828F82001400 +:10FBF000904200633042004050400019A38000440E +:10FC00008F83002C8F4201B80440FFFE8F82004892 +:10FC1000AE02000024026082A60200082402000254 +:10FC2000A202000B8C620008AE0200108C62000C75 +:10FC3000AE0200148C620014AE0200188C62001830 +:10FC4000AE0200248C620024AE0200288C620028E0 +:10FC5000AE02002C3C021000AF4201B8A380004469 +:10FC60008F8300148FBF00148FB000109062006368 +:10FC700027BD00183042007FA06200639782003ADF +:10FC80008F86003C8F850014938300280046102344 +:10FC9000A782003AA4A000E490A400638F820040F1 +:10FCA000AF83003C2403FFBF0046102100832024C3 +:10FCB000AF820040A0A400638F820014A04000BD6A +:10FCC0008F82001403E00008A44000BE8F8A001455 +:10FCD00027BDFFE0AFB10014AFB000108F88003C2B +:10FCE000AFBF00189389001C954200E430D100FF9B +:10FCF0000109182B0080802130AC00FF3047FFFF46 +:10FD00000000582114600003310600FF012030215B +:10FD1000010958239783003A0068102B1440003CD7 +:10FD20000000000014680007240200018E02002079 +:10FD30002403FFFB34E7800000431024AE020020C0 +:10FD40002402000134E70880158200053165FFFFB9 +:10FD50000E001554020020210A00169102002021F5 +:10FD60000E001585020020218F8400482743018062 +:10FD70008F4201B80440FFFE24020018AC6400006A +:10FD8000A062000B8F840014948200E6A46200102D +:10FD90003C021000AC600030AF4201B894820060B9 +:10FDA00024420001A4820060948200603C030800A9 +:10FDB0008C63318830427FFF5443000F02002021C2 +:10FDC000948200602403800000431024A482006019 +:10FDD0009082006090830060304200FF000211C2F8 +:10FDE00000021027000211C03063007F0062182556 +:10FDF000A083006002002021022028218FBF00186C +:10FE00008FB100148FB000100A0015F927BD002033 +:10FE1000914200632403FF8000431025A142006348 +:10FE20009782003A3048FFFF110000209383001CA6 +:10FE30008F840014004B1023304600FF948300E4AD +:10FE40002402EFFF0168282B00621824A48300E439 +:10FE500014A000038E020020010058210000302170 +:10FE60002403FFFB34E7800000431024AE0200208F +:10FE700024020001158200053165FFFF0E001554B4 +:10FE8000020020210A0016B99783003A0E0015855A +:10FE9000020020219783003A8F82003CA780003A1D +:10FEA00000431023AF82003C9383001C8F82001418 +:10FEB0008FBF00188FB100148FB0001027BD002035 +:10FEC00003E00008A04300BD938200442403000126 +:10FED00027BDFFE8004330042C420020AFB00010E3 +:10FEE000AFBF00142410FFFE10400005274501801D +:10FEF0003C0208008C4231900A0016D600461024BD +:10FF00003C0208008C423194004610241440000743 +:10FF1000240600848F8300142410FFFF9062006287 +:10FF20003042000F34420040A06200620E0015D63D +:10FF300000000000020010218FBF00148FB00010DD +:10FF400003E0000827BD00188F83002427BDFFE0D1 +:10FF5000AFB20018AFB10014AFB00010AFBF001CBB +:10FF60009062000D00A0902130D100FF3042007F50 +:10FF7000A062000D8F8500148E4300180080802140 +:10FF80008CA2007C146200052402000E90A2006383 +:10FF9000344200200A0016FFA0A200630E0016C51E +:10FFA000A38200442403FFFF104300472404FFFF03 +:10FFB00052200045000020218E4300003C0200102A +:10FFC00000621024504000043C020008020020217E +:10FFD0000A00170E24020015006210245040000988 +:10FFE0008E45000002002021240200140E0016C5D8 +:10FFF000A38200442403FFFF104300332404FFFFC7 +:020000040001F9 +:100000008E4500003C02000200A2102410400016A1 +:100010003C0200048F8600248CC200148CC30010A4 +:100020008CC40014004310230044102B50400005E2 +:10003000020020218E43002C8CC2001010620003AD +:10004000020020210A00173F240200123C02000493 +:1000500000A210245040001C00002021020020219A +:100060000A00173F2402001300A2102410400006CB +:100070008F8300248C620010504000130000202168 +:100080000A001739020020218C6200105040000441 +:100090008E42002C020020210A00173F240200118A +:1000A00050400009000020210200202124020017F6 +:1000B0000E0016C5A38200442403FFFF1043000274 +:1000C0002404FFFF000020218FBF001C8FB2001806 +:1000D0008FB100148FB000100080102103E00008E1 +:1000E00027BD00208F83001427BDFFD8AFB40020A8 +:1000F000AFB3001CAFB20018AFB10014AFB0001026 +:10010000AFBF0024906200638F91002C2412FFFF88 +:100110003442004092250000A06200638E2200104D +:100120000080982130B0003F105200060360A021EB +:100130002402000D0E0016C5A38200441052005484 +:100140002404FFFF8F8300148E2200188C63007C30 +:1001500010430007026020212402000E0E0016C585 +:10016000A38200442403FFFF104300492404FFFF3F +:1001700024040020120400048F83001490620063A2 +:1001800034420020A06200638F85003410A000205C +:1001900000000000560400048F8200140260202139 +:1001A0000A0017902402000A9683000A9442006015 +:1001B0003042FFFF144300048F8200202404FFFD1F +:1001C0000A0017B7AF82003C3C0208008C42318C19 +:1001D0000045102B14400006026020210000282159 +:1001E0000E001646240600010A0017B70000202161 +:1001F0002402002D0E0016C5A38200442403FFFF35 +:10020000104300232404FFFF0A0017B70000202139 +:10021000160400058F8400148E2300142402FFFFAF +:100220005062001802602021948200602442000184 +:10023000A4820060948200603C0308008C633188D3 +:1002400030427FFF5443000F0260202194820060FF +:100250002403800000431024A48200609082006088 +:1002600090830060304200FF000211C2000210279C +:10027000000211C03063007F00621825A083006077 +:10028000026020210E0015F9240500010000202144 +:100290008FBF00248FB400208FB3001C8FB20018D2 +:1002A0008FB100148FB000100080102103E000080F +:1002B00027BD00288F83001427BDFFE8AFB00010D2 +:1002C000AFBF0014906200638F87002C00808021F4 +:1002D000344200408CE60010A06200633C0308003A +:1002E0008C6331B030C23FFF0043102B1040004EF2 +:1002F0008F8500302402FF8090A3000D004310245E +:10030000304200FF504000490200202100061382C5 +:10031000304800032402000255020044020020215C +:1003200094A2001C8F85001424030023A4A20114AE +:100330008CE60000000616023042003F1043001019 +:100340003C0300838CE300188CA2007C1062000642 +:100350002402000E0E0016C5A38200442403FFFFF2 +:10036000104300382404FFFF8F8300149062006361 +:1003700034420020A06200630A0017FC8F8300242F +:1003800000C31024144300078F83002490A200624E +:100390003042000F34420020A0A20062A38800383F +:1003A0008F8300249062000D3042007FA062000D18 +:1003B0008F83003410600018020020218F840030E9 +:1003C0008C8200100043102B1040000924020018FA +:1003D000020020210E0016C5A38200442403FFFF63 +:1003E000104300182404FFFF0A00182400002021F5 +:1003F0008C820010240500010200202100431023FC +:100400008F830024240600010E001646AC62001003 +:100410000A001824000020210E0015F9240500010F +:100420000A00182400002021020020212402000DCF +:100430008FBF00148FB0001027BD00180A0016C52A +:10044000A38200448FBF00148FB0001000801021E1 +:1004500003E0000827BD001827BDFFC8AFB2002089 +:10046000AFBF0034AFB60030AFB5002CAFB400283A +:10047000AFB30024AFB1001CAFB000188F46012805 +:100480003C0308008C6331A02402FF80AF86004843 +:1004900000C318213065007F03452821006218241D +:1004A0003C02000AAF43002400A2282190A200626F +:1004B00000809021AF850014304200FF000211023D +:1004C000A382003890A200BC304200021440000217 +:1004D00024030034240300308F820014A3830028F7 +:1004E000938300388C4200C0A3800044AF82003C5C +:1004F00024020004106203148F84003C8E44000424 +:10050000508003118F84003C8E4200103083FFFF27 +:10051000A784003A106002F7AF8200408F84001475 +:100520002403FF809082006300621024304200FFA9 +:10053000144002C79785003A9383003824020002D2 +:1005400030B6FFFF14620005000088219382002866 +:100550002403FFFD0A001B11AF82003C8F82003C88 +:1005600002C2102B144002998F8400400E0014EC3C +:1005700000000000938300283C040800248477785E +:10058000240200341462002EAF84002C3C0A0800C0 +:100590008D4A77A82402FFFFAFA200100080382107 +:1005A0002405002F3C09080025297378240800FF42 +:1005B0002406FFFF90E2000024A3FFFF00062202B2 +:1005C00000C21026304200FF0002108000491021B6 +:1005D0008C420000306500FF24E7000114A8FFF5FD +:1005E0000082302600061027AFA20014AFA2001030 +:1005F0000000282127A7001027A6001400C51023FB +:100600009044000324A2000100A71821304500FFF8 +:100610002CA200041440FFF9A06400008FA2001077 +:100620001142000724020005024020210E0016C5D9 +:10063000A38200442403FFFF104300642404FFFF4F +:100640003C0208009042777C104000098F82001421 +:10065000024020212402000C0E0016C5A382004493 +:100660002403FFFF104300592404FFFF8F8200146E +:10067000A380001C3C0308008C63777C8C440080C2 +:100680003C0200FF3442FFFF006218240083202B4D +:1006900010800008AF83003402402021240200199A +:1006A0000E0016C5A38200442403FFFF1043004739 +:1006B0002404FFFF8F87003C9782003A8F85003427 +:1006C000AF8700200047202310A0003BA784003AFA +:1006D0008F86001430A200030002102390C300BCD8 +:1006E0003050000300B0282100031882307300014D +:1006F0000013108000A228213C0308008C6331A065 +:100700008F8200483084FFFF0085202B004310219A +:1007100010800011244200888F84002C1082000E6B +:100720003C033F013C0208008C42777800431024D0 +:100730003C0325001443000630E500FF8C820000D6 +:10074000ACC200888C8200100A0018E9ACC2009884 +:100750000E001529000030219382001C8F850014A3 +:100760008F830040020238218F82003CA387001C47 +:1007700094A400E4006218218F82003434841000B5 +:10078000AF83004000503021A4A400E41260000EAA +:10079000AF86003C24E20004A382001C94A200E483 +:1007A00024C30004AF83003C34422000A4A200E430 +:1007B0000A001906000020218F820040AF80003C13 +:1007C00000471021AF820040000020212414FFFFC9 +:1007D000109402092403FFFF3C0808008D08778865 +:1007E0003C0208008C4231B03C03080090637778EB +:1007F00031043FFF0082102B1040001B3067003F88 +:100800003C0208008C4231A88F83004800042180FC +:1008100000621821006418213062007F0342282101 +:100820003C02000C00A228213C020080344200015E +:100830003066007800C230252402FF800062102458 +:10084000AF42002830640007AF4208048F820014D2 +:100850000344202124840940AF460814AF850024B6 +:10086000AF840030AC4301189383003824020003A6 +:10087000146201C7240200012402002610E201C90B +:1008800028E2002710400013240200322402002234 +:1008900010E201C428E200231040000824020024D2 +:1008A0002402002010E201B02402002110E2013FE6 +:1008B000024020210A001AF32402000B10E201B9C1 +:1008C0002402002510E20010024020210A001AF341 +:1008D0002402000B10E201A628E2003310400006BB +:1008E0002402003F2402003110E200920240202145 +:1008F0000A001AF32402000B10E2019D024020219D +:100900000A001AF32402000B8F90002C3C0308000D +:100910008C6331B08F8500308E0400100000A82158 +:100920008CB3001430823FFF0043102B8CB10020A9 +:10093000504001870240202190A3000D2402FF8037 +:1009400000431024304200FF50400181024020212A +:1009500000041382304200031440017D0240202134 +:1009600094A3001C8F8200148E040028A443011459 +:100970008CA20010026218231064000302402021A0 +:100980000A00197C2402001F8F82003400621021AB +:100990000262102B104000088F83002402402021A7 +:1009A000240200180E0016C5A38200441054016CE6 +:1009B0002404FFFF8F8300248F8400348C62001096 +:1009C0000224882100441023AC6200108F8200149E +:1009D000AC7100208C4200680051102B10400009BF +:1009E0008F830030024020212402001D0E0016C516 +:1009F000A38200442403FFFF104301592404FFFF96 +:100A00008F8300308E0200248C6300241043000783 +:100A1000024020212402001C0E0016C5A3820044BF +:100A20002403FFFF1043014E2404FFFF8F840024A2 +:100A30008C82002424420001AC8200241233000482 +:100A40008F8200148C4200685622000E8E02000035 +:100A50008E0200003C030080004310241440000D6F +:100A60002402001A024020210E0016C5A382004471 +:100A70002403FFFF1043013A2404FFFF0A0019BAC0 +:100A80008E0200143C0300800043102450400003F9 +:100A90008E020014AC8000208E0200142411FFFF8F +:100AA000105100062402001B024020210E0016C532 +:100AB000A38200441051012A2404FFFF8E0300008A +:100AC0003C02000100621024104000123C02008031 +:100AD0000062102414400008024020212402001A61 +:100AE0000E0016C5A38200442403FFFF1043011C1F +:100AF0002404FFFF02402021020028210E0016E5F9 +:100B0000240600012403FFFF104301152404FFFF06 +:100B1000241500018F83002402A0302102402021EF +:100B20009462003624050001244200010A001AD70D +:100B3000A46200368F90002C3C0308008C6331B017 +:100B40008E13001032623FFF0043102B10400089CB +:100B50008F8400302402FF809083000D0043102416 +:100B6000304200FF104000842402000D0013138265 +:100B700030420003240300011443007F2402000DCF +:100B80009082000D30420008544000048F820034EF +:100B9000024020210A001A082402002450400004C8 +:100BA0008E03000C024020210A001A0824020027AC +:100BB0008C82002054620006024020218E0300082F +:100BC0008C820024506200098E0200140240202111 +:100BD000240200200E0016C5A382004410540071A8 +:100BE0002403FFFF0A001A3D8F8400242411FFFF15 +:100BF000145100048F860014024020210A001A3884 +:100C0000240200258E0300188CC2007C10620003B1 +:100C10002402000E0A001A38024020218E0300240C +:100C20008C82002810620003240200210A001A3876 +:100C3000024020218E0500288C82002C10A2000387 +:100C40002402001F0A001A38024020218E03002CC3 +:100C500014600003240200230A001A3802402021F5 +:100C60008CC200680043102B1040000324020026B1 +:100C70000A001A38024020218C82001400651821D5 +:100C80000043102B104000088F84002402402021D4 +:100C9000240200220E0016C5A38200441051004118 +:100CA0002403FFFF8F8400242403FFF79082000DAC +:100CB00000431024A082000D8F8600143C0308001E +:100CC0008C6331AC8F82004894C400E08F8500248F +:100CD0000043102130847FFF000420400044102195 +:100CE0003043007F034320213C03000E008320217A +:100CF0002403FF8000431024AF42002CA493000083 +:100D00008CA2002824420001ACA200288CA2002C56 +:100D10008E03002C00431021ACA2002C8E02002C6C +:100D2000ACA200308E020014ACA2003494A2003AAF +:100D300024420001A4A2003A94C600E03C0208004C +:100D40008C4231B024C4000130837FFF1462000F55 +:100D500000803021240280000082302430C2FFFF56 +:100D6000000213C2304200FF000210270A001A7668 +:100D7000000233C02402000D024020210E0016C5DF +:100D8000A38200440A001A7C004018218F820014BC +:100D900002402021240500010E0015F9A44600E0C0 +:100DA000000018210A001B0E006088218F90002C83 +:100DB0003C0308008C6331B08E05001030A23FFF69 +:100DC0000043102B104000612402FF808F8400300C +:100DD0009083000D00431024304200FF5040005C1F +:100DE000024020218F8200341040000B0005138246 +:100DF0008F8200149763000A944200603042FFFF24 +:100E000014430005000513828F8200202404FFFD97 +:100E10000A001AEBAF82003C304200031440000E7F +:100E20000000000092020002104000058E03002422 +:100E300050600015920300030A001AA70240202107 +:100E40008C82002450620010920300030240202193 +:100E50000A001AAF2402000F9082000D30420008F1 +:100E60005440000992030003024020212402001094 +:100E70000E0016C5A38200442403FFFF1043003870 +:100E80002404FFFF92030003240200025462000CBA +:100E9000920200038F820034544000099202000342 +:100EA000024020212402002C0E0016C5A38200441B +:100EB0002403FFFF1043002A2404FFFF92020003D3 +:100EC0000200282102402021384600102CC60001D3 +:100ED0002C4200010E0016E5004630252410FFFFCD +:100EE0001050001F2404FFFF8F8300341060001394 +:100EF000024020213C0208008C42318C0043102B20 +:100F00001440000700000000000028212406000112 +:100F10000E001646000000000A001AEB0000202117 +:100F20002402002D0E0016C5A38200441050000CB0 +:100F30002404FFFF0A001AEB000020210E0015F91F +:100F4000240500010A001AEB0000202102402021A4 +:100F50002402000D0E0016C5A3820044004020218B +:100F60000A001B0E008088211514000E00000000EE +:100F70000E00174C024020210A001B0E0040882161 +:100F80000E0016C5A38200440A001B0E00408821F3 +:100F900014620017022018212402002314E2000525 +:100FA0002402000B0E0017C0024020210A001B0E75 +:100FB0000040882102402021A38200440E0016C573 +:100FC0002411FFFF0A001B0F0220182130A500FF8B +:100FD0000E001529240600019783003A8F82003CF9 +:100FE000A780003A00431023AF82003C0220182162 +:100FF0001220003E9782003A2402FFFD5462003E18 +:101000008E4300208E4200048F830014005610236C +:10101000AE420004906200633042007FA062006331 +:101020008E4200208F840014A780003A34420002D0 +:10103000AE420020A48000E4908200632403FFBF3E +:1010400000431024A08200630A001B518E4300203D +:101050009082006300621024304200FF10400023A1 +:101060009782003A90820088908300BD2485008892 +:101070003042003F2444FFE02C820020A383001C68 +:1010800010400019AF85002C2402000100821804D2 +:10109000306200191440000C3C028000344200020F +:1010A000006210241440000B306200201040000F3A +:1010B0009782003A90A600010240202124050001F9 +:1010C0000A001B4B30C60001024020210A001B4AC7 +:1010D00024050001024020210000282124060001EF +:1010E0000E001646000000009782003A1440FD0CE6 +:1010F0008F8400148E4300203062000410400012E0 +:101100008F84003C2402FFFB00621024AE420020CA +:10111000274301808F4201B80440FFFE8F820048C0 +:10112000AC6200008F420124AC62000424026083A0 +:10113000A462000824020002A062000B3C0210001E +:10114000AF4201B88F84003C8F8300148FBF0034FE +:101150008FB600308FB5002C8FB400288FB30024D9 +:101160008FB200208FB1001C8FB000182402000144 +:1011700027BD003803E00008AC6400C030A500FFC4 +:101180002403000124A900010069102B1040000C69 +:1011900000004021240A000100A31023004A380463 +:1011A00024630001308200010069302B10400002EE +:1011B000000420420107402554C0FFF800A310237B +:1011C00003E00008010010213C020800244260A452 +:1011D0003C010800AC22736C3C0208002442530816 +:1011E0003C010800AC2273702402000627BDFFE01A +:1011F0003C010800A02273743C021EDCAFB2001850 +:10120000AFB10014AFBF001CAFB0001034526F413B +:1012100000008821240500080E001B7202202021F6 +:10122000001180803C07080024E773780002160054 +:1012300002071821AC6200000000282124A200014E +:101240003045FFFF8C6200002CA60008044100021C +:10125000000220400092202614C0FFF8AC64000079 +:10126000020780218E0400000E001B72240500205E +:10127000262300013071FFFF2E2301001460FFE5DB +:10128000AE0200008FBF001C8FB200188FB1001497 +:101290008FB0001003E0000827BD002027BDFFD855 +:1012A000AFB3001CAFB20018AFBF0020AFB1001445 +:1012B000AFB000108F5101408F48014800089402E0 +:1012C000324300FF311300FF8F4201B80440FFFE9C +:1012D00027500180AE1100008F420144AE0200048D +:1012E00024020002A6120008A202000B240200142D +:1012F000AE1300241062002528620015104000087B +:101300002402001524020010106200302402001292 +:10131000106200098FBF00200A001CAD8FB3001CB3 +:101320001062007024020022106200378FBF00207C +:101330000A001CAD8FB3001C3C0208008C4231A097 +:101340002403FF800222102100431024AF42002416 +:101350003C0208008C4231A0022210213042007F62 +:10136000034218213C02000A00621821166000BCEA +:10137000AF830014906200623042000F34420030AC +:10138000A06200620A001CAC8FBF00203C04600019 +:101390008C832C083C02F0033442FFFF00621824C7 +:1013A000AC832C083C0208008C4231A08C832C08B2 +:1013B000244200740002108200021480006218258A +:1013C000AC832C080A001CAC8FBF00203C02080034 +:1013D0008C4231A02403FF800222102100431024FC +:1013E000AF4200243C0208008C4231A03C03000ABA +:1013F000022210213042007F0342102100431021BD +:101400000A001CABAF8200143C0208008C4231A0E1 +:101410002405FF800222102100451024AF42002441 +:101420003C0208008C4231A0022210213042007F91 +:10143000034218213C02000A0062182190620063F6 +:1014400000A21024304200FF10400085AF8300143A +:1014500024620088944300123C0208008C4231A8A8 +:1014600030633FFF00031980022210210043102146 +:101470003043007F03432021004510243C03000C2F +:1014800000832021AF4200289082000D00A210248A +:10149000304200FF10400072AF8400249082000DA3 +:1014A000304200101440006F8FBF00200E0015C89E +:1014B000000000008F4201B80440FFFE0000000061 +:1014C000AE1100008F420144AE020004240200026B +:1014D000A6120008A202000BAE1300240A001CACE6 +:1014E0008FBF00202406FF8002261024AF42002078 +:1014F0003C0208008C4231A031043FFF00042180EF +:101500000222102100461024AF4200243C030800B0 +:101510008C6331A83C0208008C4231A03227007F46 +:101520000223182102221021006418213042007F7A +:101530003064007F034228213C02000A0066182420 +:1015400000A22821034420213C02000C008220211B +:10155000AF4300283C020008034718210062902195 +:10156000AF850014AF8400240E0015C8010080214F +:101570008F4201B80440FFFE8F8200248F84001444 +:10158000274501809042000DACB10000A4B00006D8 +:10159000000216000002160300021027000237C2E4 +:1015A00014C00016248200889442001232033FFFC8 +:1015B00030423FFF14430012240260829083006394 +:1015C0002402FF8000431024304200FF5040000CF2 +:1015D00024026082908200623042000F3442004058 +:1015E000A082006224026084A4A200082402000DEC +:1015F000A0A200050A001C963C022700240260827B +:10160000A4A20008A0A000053C02270000061C00C0 +:101610000062182524020002A0A2000BACA3001057 +:10162000ACA00014ACA00024ACA00028ACA0002CFE +:101630008E42004C8F840024ACA200189083000DD1 +:101640002402FF8000431024304200FF10400005B8 +:101650008FBF00209082000D3042007FA082000DDD +:101660008FBF00208FB3001C8FB200188FB1001401 +:101670008FB000103C02100027BD002803E00008D6 +:04168000AF4201B8BC +:0C1684000800343008003430080033A89F +:10169000080033E0080034140800343808003438F7 +:0816A00008003438080033187B +:0816A8000A000124000000000B +:1016B000000000000000000D747061362E322E31E3 +:1016C0000000000006020101000000000000000010 +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:101730000000000000000000000000001000000396 +:10174000000000000000000D0000000D3C02080039 +:1017500024421C003C03080024632094AC40000099 +:101760000043202B1480FFFD244200043C1D080090 +:1017700037BD2FFC03A0F0213C1008002610049078 +:101780003C1C0800279C1C000E00015C00000000AF +:101790000000000D3084FFFF308200078F850018A5 +:1017A00010400002248300073064FFF800853021D8 +:1017B00030C41FFF03441821247B4000AF85001C68 +:1017C000AF84001803E00008AF4400843084FFFFBA +:1017D000308200078F8500208F860028104000028D +:1017E000248300073064FFF8008520210086182B31 +:1017F00014600002AF8500240086202303442821C2 +:1018000034068000AF840020AF44008000A6202171 +:1018100003E00008AF84003827BDFFD8AFB3001C39 +:10182000AFB20018AFB00010AFBF0024AFB40020BB +:10183000AFB100143C0860088D1450002418FF7FDD +:101840003C1A8000029898243672380CAD12500071 +:101850008F5100083C07601C3C08600036300001D6 +:10186000AF500008AF800018AF400080AF40008448 +:101870008CE600088D0F08083C0760168CEC000011 +:1018800031EEFFF039CA00103C0DFFFF340B800031 +:101890003C030080034B48212D440001018D282486 +:1018A0003C0253533C010800AC230420AF890038AC +:1018B000AF860028AF840010275B400014A200030D +:1018C00034E37C008CF90004032818218C7F007C11 +:1018D0008C6500783C0280003C0B08008D6B048C0A +:1018E0003C0A08008D4A048834520070AF85003CE1 +:1018F000AF9F00403C13080026731C440240A02107 +:101900008E4800008F46000038C30001306400019B +:1019100010800017AF880034028048218D2F00000E +:101920003C0508008CA5045C3C1808008F1804587E +:1019300001E8102300A280210000C8210202402BF0 +:1019400003198821022838213C010800AC30045CCE +:101950003C010800AC2704588F4E000039CD00012F +:1019600031AC00011580FFED01E04021AF8F003464 +:101970008E5100003C0708008CE7045C3C0D080019 +:101980008DAD04580228802300F0602100007021F2 +:101990000190302B01AE1821006620213C01080087 +:1019A000AC2C045C3C010800AC2404588F460108B0 +:1019B0008F47010030C92000AF860000AF87000CC0 +:1019C0001120000A00C040213C1808008F18042C88 +:1019D000270800013C010800AC28042C3C184000FA +:1019E000AF5801380A000196000000009749010431 +:1019F00000002821014550213122FFFF01625821BA +:101A00000162F82B015F502130D902003C0108002F +:101A1000AC2B048C3C010800AC2A0488172000156C +:101A200024040F0010E400130000000024080D003F +:101A300010E8023B30CD000611A0FFE93C18400041 +:101A4000936E00002409001031C400F01089027167 +:101A500024020070108202E58F880014250F000117 +:101A6000AF8F00143C184000AF5801380A000196AF +:101A700000000000974C01041180FFD93C18400081 +:101A800030C34000146000A1000000008F460178C0 +:101A900004C0FFFE8F87003824100800240F0008C0 +:101AA0008CE30008AF500178A74F0140A7400142E6 +:101AB000974E01048F86000031C9FFFF30CD000131 +:101AC00011A002E1012040212531FFFE241800026F +:101AD000A75801463228FFFFA75101483C190800CA +:101AE0008F39043C172002D08F8C000C30DF00208F +:101AF00017E00002240400092404000130C20C0095 +:101B0000240504005045000134840004A744014A20 +:101B10003C1108008E3104203C1800483C100001A4 +:101B20000238182530CF00020070282511E000048B +:101B3000000018213C19010000B9282524030001E8 +:101B400030DF000453E00005AF8300083C060010BE +:101B500000A6282524030001AF830008AF4510002C +:101B60000000000000000000000000000000000075 +:101B70008F83000810600023000000008F451000D4 +:101B800004A1FFFE000000001060001E0000000025 +:101B90008F4410003C0C0020008C102410400019D1 +:101BA0008F8E000031CD000211A000160000000051 +:101BB000974F101415E0001300000000975910080B +:101BC0003338FFFF27110006001118820003308010 +:101BD00000C7282132300001322300031200032CF9 +:101BE0008CA200000000000D00C7F821AFE2000049 +:101BF0003C0508008CA5043024A600013C01080027 +:101C0000AC2604308F6D00003402FFFFAF8D00045E +:101C10008CEC0000118202A6000020218CED000057 +:101C200031AC01001180028A000000003C02080073 +:101C30008C4204743C0308008C63044C3C1F080075 +:101C40008FFF04703C1808008F18044800483821A2 +:101C50000068802100E8282B03E430210208402B93 +:101C60000304882100C57021022878213C01080066 +:101C7000AC30044C3C010800AC2F04483C01080087 +:101C8000AC2704743C010800AC2E04708F8400184B +:101C90000120302131290007249F000833F91FFF5C +:101CA00003594021AF84001CAF990018251B400048 +:101CB000AF590084112000038F83002024C2000745 +:101CC0003046FFF88F84002800C3282100A4302B61 +:101CD00014C00002AF83002400A428230345602120 +:101CE000340D8000018D10213C0F1000AF850020C5 +:101CF000AF820038AF450080AF4F01788F88001465 +:101D0000250F00010A0001EFAF8F00148F62000859 +:101D10008F670000240500300007760231C300F011 +:101D2000106500A7240F0040546FFF4C8F880014EB +:101D30008F4B01780560FFFE0000000030CA0200F2 +:101D400015400003000612820000000D00061282FA +:101D5000304D0003000D4900012D18210003808043 +:101D6000020D402100086080019380218E1F000039 +:101D700017E00002000000000000000D8F6E00045C +:101D800005C202BD92070006920E000592020004F1 +:101D90003C090001000E18800070F8218FED00183A +:101DA000277100082448000501A96021000830823D +:101DB000AFEC0018022020210E00059E260500141D +:101DC000920A00068F7900043C0B7FFF000A2080F6 +:101DD000009178218DF800043566FFFF0326282442 +:101DE00003053821ADE70004920E0005920D0004B2 +:101DF000960C0008000E10800051C8218F230000AF +:101E0000974901043C07FFFF006758243128FFFF72 +:101E1000010DF82103EC50233144FFFF016430250C +:101E2000AF26000092030007241800011078027505 +:101E3000240F0003106F0285000000008E050010C3 +:101E40002419000AA7590140A7450142921800042D +:101E50008F860000240F0001A7580144A7400146C7 +:101E60009747010430D100023C050041A7470148D3 +:101E700000001821A74F014A1220000330CB0004B4 +:101E80003C0501412403000151600005AF830008B7 +:101E90003C06001000A6282524030001AF8300089B +:101EA000AF4510000000000000000000000000002E +:101EB000000000008F8A00081140000400000000AC +:101EC0008F4410000481FFFE000000008F6B0000B3 +:101ED000920800043C1108008E310444AF8B0004CA +:101EE00097590104311800FF3C0E08008DCE0440C4 +:101EF0003325FFFF03053821022760210000102150 +:101F0000250F000A31E8FFFF0187482B01C2682135 +:101F100001A9F821311000073C010800AC2C044451 +:101F20003C010800AC3F0440120000038F8C0018F5 +:101F30002506000730C8FFF8010C682131BF1FFFDC +:101F4000AF8C001CAF9F0018AF5F00849744010462 +:101F5000035F80213084FFFF308A000711400003B7 +:101F6000261B4000248900073124FFF88F820020BF +:101F70008F850028008220210085702B15C000026B +:101F8000AF820024008520233C0B08008D6B048C5D +:101F90003C0A08008D4A04880344882134038000E9 +:101FA000022310213C0F1000AF840020AF820038C4 +:101FB000AF440080AF4F01780A0002968F8800146A +:101FC0008F5001780600FFFE30D10200162000037A +:101FD000000612820000000D00061282305F00032E +:101FE000001F1900007F302100062080009FC821BB +:101FF00000194880013380218E1800001300000270 +:10200000000000000000000D8F6C000C058001FB3B +:102010008F870038240E0001AE0E00008CE300080C +:10202000A20000078F65000400055402314D00FF37 +:1020300025A80005000830822CCB00411560000265 +:10204000A20A00040000000D8F7800043C03FFFF8B +:1020500000E02821330BFFFF256C000B000C1082E1 +:1020600000022080008748218D3F000026040014D4 +:10207000A618000803E3C8240E00059EAD39000031 +:102080008F4F01083C11100001F1382410E001AB22 +:1020900000000000974D01049208000725AAFFECFC +:1020A000350600023144FFFFA2060007960600082D +:1020B0002CC7001354E0000592030007921100079B +:1020C000362F0001A20F0007920300072418000119 +:1020D000107801C224090003106901D58F880038E7 +:1020E00030CBFFFF257100020011788331E400FF3F +:1020F00000042880A20F000500A848218D2D0000B3 +:10210000974A01043C0EFFFF01AEF8243143FFFF64 +:10211000006B1023244CFFFE03ECC825AD390000F2 +:10212000920600053C03FFF63462FFFF30D800FF43 +:102130000018388000F08821922F00143C04FF7FA3 +:102140003487FFFF31EE000F01C65821316500FFD3 +:1021500000055080015068218DAC00200148F82115 +:10216000A20B00060182C824AE0C000CAFF9000CD3 +:10217000920900068E11000C032778240009C08004 +:102180000310702195C60026030828210227202469 +:10219000AE04000CADCF0020ADC60024ACA60010EC +:1021A0008F8800003C0B08008D6B048C3C0A0800F3 +:1021B0008D4A0488241F001024190002A75F0140E3 +:1021C000A7400142A7400144A7590146974901048D +:1021D00024070001310600022538FFFEA7580148F8 +:1021E0003C050009A747014A10C000030000182160 +:1021F0003C05010924030001310C00045180000555 +:10220000AF8300083C08001000A828252403000123 +:10221000AF830008AF451000000000000000000080 +:1022200000000000000000009205000424AE00023F +:1022300031CD0007000D182330620007AE020010F8 +:102240008F90000812000004000000008F4F100063 +:1022500005E1FFFE000000008F7100008F8E001866 +:102260003C0308008C630444AF91000497450104CB +:1022700025CF001031E61FFF30A2FFFFAF8E001CFC +:10228000AF860018AF4600842449FFFE3C0C0800CE +:102290008D8C0440974D010401208021000947C323 +:1022A0000070C02131A9FFFF0310F82B0188C8215D +:1022B000033F202103463821313100073C0108004B +:1022C000AC3804443C010800AC2404401220000354 +:1022D00024FB40002527000730E9FFF88F86002007 +:1022E0008F8400280126382100E4C02B170000024B +:1022F000AF86002400E438230347202134198000EE +:10230000009910213C0F1000AF870020AF820038E9 +:10231000AF470080AF4F01780A0002968F88001403 +:102320009747010410E0FDAE3C1840008F5801783B +:102330000700FFFE30C5400010A000033C1F00084E +:102340000000000D3C1F0008AF5F01402410080092 +:102350008F860000AF5001789744010430D9000106 +:10236000132000ED3086FFFF24CCFFFE240D000279 +:10237000A74D0146A74C01488F9100182408000D75 +:10238000A748014A8F630000262F000831E21FFF93 +:102390000342702130C90007AF830004AF91001CD5 +:1023A000AF82001800C03821AF4200841120000322 +:1023B00025DB400024D800073307FFF88F85002075 +:1023C0008F84002800E5302100C4382B14E000027F +:1023D000AF85002400C430238F8400140346F82105 +:1023E000340C8000AF86002003EC8021AF460080D3 +:1023F000249900013C0610003C184000AF460178CB +:10240000AF900038AF990014AF5801380A00019618 +:10241000000000008F630000975101043067FFFF48 +:102420003228FFFF8F4F017805E0FFFE30EC0007F8 +:10243000000CF82333F0000724F9FFFE2404000AFF +:10244000A7440140A7500142A7590144A7400146B3 +:10245000A74801488F45010830B800201700000246 +:10246000240300092403000130CD0002A743014AE0 +:102470003C04004111A00003000018213C0401416C +:102480002403000130C9000451200005AF83000877 +:102490003C0600100086202524030001AF830008BD +:1024A000AF44100000000000000000000000000029 +:1024B000000000008F8E000811C000040000000022 +:1024C0008F4210000441FFFE000000008F7F0000DB +:1024D000276400088F91003CAF9F0004948500089A +:1024E0009490000A9499000C30AFFFFF0010C400D4 +:1024F0003323FFFF11F100A6030320253C0E080043 +:102500008DCE04443C0C08008D8C044000E88821EA +:102510002626FFFE01C628210000682100A6F82B10 +:10252000018D2021009F80213C010800AC2504443E +:102530003C010800AC30044024E200083042FFFFB8 +:102540003047000710E000038F830018244F000776 +:1025500031E2FFF83106FFFF30C800070043802159 +:1025600032191FFF0359C021AF83001CAF99001817 +:10257000271B4000AF590084110000038F8C0020FE +:1025800024C5000730A6FFF88F84002800CC28213E +:1025900000A4F82B17E00002AF8C002400A428232D +:1025A000AF850020AF4500803C0408008C840434D3 +:1025B00003454821340E8000012E6821108000055B +:1025C000AF8D0038939100172406000E12260011DB +:1025D0002407043F3C021000AF4201788F880014AA +:1025E000250F00010A0001EFAF8F00140E0005C493 +:1025F00000E020218F8800143C0B08008D6B048CB8 +:102600003C0A08008D4A0488250F00010A0001EFEA +:10261000AF8F00143C021000A7470148AF42017879 +:102620000A0004CE8F88001424040F001184003D9A +:1026300030CE002015C0000224030009240300014D +:102640000A00021AA743014A0A00020DA7400146E8 +:1026500094EF000894F1000A94F0000C8F8C003C79 +:10266000001174003207FFFF31EDFFFF11AC00379E +:1026700001C720253C1808008F1804443C0F0800AF +:102680008DEF0440000080210308682101A8382B49 +:1026900001F0702101C760213C010800AC2D044409 +:1026A0003C010800AC2C04400A00027A8F84001818 +:1026B0003C0208008C42047C3C0308008C630454F8 +:1026C0003C1F08008FFF04783C1808008F18045046 +:1026D000004838210068802100E8282B03E43021DD +:1026E0000208402B0304882100C5702102287821AC +:1026F0003C010800AC3004543C010800AC2F0450ED +:102700003C010800AC27047C3C010800AC2E047896 +:102710000A00027A8F840018A74001460A00043597 +:102720008F91001830CD002015A0FFC52403000DA7 +:10273000240300050A00021AA743014A974E010428 +:1027400025C5FFF00A00038130A4FFFF8F980040E9 +:102750001498FFC8000010213C0508008CA5046CEB +:102760003C1F08008FFF046800A8C8210328302BF5 +:1027700003E22021008640213C010800AC39046CB2 +:102780003C010800AC2804680A00027A8F84001813 +:102790008F8C0040148CFF5900E8C8213C180800B9 +:1027A0008F18046C3C1108008E3104682723FFFE4B +:1027B00003034821000010210123302B0222702145 +:1027C00001C668213C010800AC29046C3C010800EA +:1027D000AC2D04680A0004A524E200088F880038A4 +:1027E0003C03FFFF8D02000C0043F82403E4C825DE +:1027F000AD19000C0A00038F30CBFFFF0A0003C3A2 +:10280000AE000000974A0104920400048E26000CDA +:10281000014458212579FFF200C7C0243325FFFF6A +:1028200003053825AE27000C0A0002E68E050010CD +:102830003C0DFFFF8D0A0010014D582401646025F6 +:10284000AD0C00100A00038F30CBFFFF974301044B +:10285000920E00048E290010006E1021244DFFEE10 +:102860000127602431A8FFFF0188F825AE3F001042 +:102870000A0002E68E0500108E0F000CAE0000006C +:1028800000078880023028210A0002B8ACAF00207F +:102890001460000D3058FFFF3C04FFFF0044682423 +:1028A00001A47026000E602B000D102B004CF824A4 +:1028B00013E00002000000000000000D8CAF0000DB +:1028C0000A00025001E410253B03FFFF0003882BA0 +:1028D0000018802B0211202410800002000000004C +:1028E0000000000D8CB900000A0002503722FFFFE3 +:1028F0003084FFFF30A5FFFF108000070000182183 +:1029000030820001104000020004204200651821BE +:102910001480FFFB0005284003E000080060102140 +:1029200010C00007000000008CA2000024C6FFFFBA +:1029300024A50004AC82000014C0FFFB2484000422 +:1029400003E000080000000010A0000824A3FFFF1F +:10295000AC86000000000000000000002402FFFF21 +:102960002463FFFF1462FFFA2484000403E00008DC +:1029700000000000308EFFFF30D8FFFF00057C0014 +:1029800001F8602539CDFFFF01AC5021014C582BD7 +:10299000014B4821000944023127FFFF00E83021A4 +:1029A0000006240230C5FFFF00A418213862FFFF93 +:1029B00003E000083042FFFF3C0C08008D8C0484CB +:1029C000240BFF8027BDFFD001845021014B4824F8 +:1029D000AF4900203C0808008D080484AFB20020F5 +:1029E000AFB00018AFBF0028AFB30024AFB1001CD8 +:1029F000936600040104382130E4007F009A10211E +:102A00003C0300080043902130C500200360802172 +:102A10003C080111277B000814A000022646007024 +:102A20002646006C9213000497510104920F000493 +:102A30003267000F322EFFFF31ED004001C728231F +:102A400011A0000500004821925900BC3338000451 +:102A50001700009000000000924300BC307F00048B +:102A600013E0000F0000000010A0000D00000000A7 +:102A7000960E0002240AFF8000A7602125CDFFFEEC +:102A8000A74D1016920B0004014B2024308200FF4A +:102A900010400085010C40253C0F0400010F40252B +:102AA0008F5301780660FFFE2404000AA74401400A +:102AB000960D00022404000931AC0007000C5823D5 +:102AC000316A0007A74A0142960200022443FFFE32 +:102AD000A7430144A7400146975F0104A75F01484F +:102AE0008F590108333800205300000124040001ED +:102AF000920F000431EE001015C000023483001064 +:102B000000801821A743014A0000000000000000D7 +:102B10000000000000000000AF48100000000000AE +:102B20000000000000000000000000008F511000B5 +:102B30000621FFFE3113FFFF1260000300000000BA +:102B40008F481018ACC8000096030006307FFFFFC6 +:102B500027F900020019988200138880023B302177 +:102B60008CD800001520005700183402920300048E +:102B70002405FF8000A3F82433F100FF1220002C6D +:102B800000000000924700BC30F200021240002812 +:102B900000000000974B100C2562FFFEA7421016A4 +:102BA000000000003C0A040035490030AF49100025 +:102BB0000000000000000000000000000000000015 +:102BC0008F4C10000581FFFE000000009749100C9B +:102BD0008F51101C00C020213127FFFF24F200304C +:102BE000001218820003288000BBF8213226FFFF64 +:102BF000AFF100000E0005B300112C020013C880D5 +:102C0000033B98218E78000000027400AFB80010DA +:102C10008FA80010310FFFFFAFAF00108FA400107E +:102C200001C46825AFAD00108FA60010AE6600008D +:102C300097730008976D000A9766000C8F8A003C16 +:102C4000000D5C0030CCFFFF3262FFFF104A0036FF +:102C5000016C2025960600023C10100024D30008C9 +:102C60000E00013B3264FFFF974C01040E00014946 +:102C70003184FFFFAF5001788FBF00288FB300244D +:102C80008FB200208FB1001C8FB0001803E0000845 +:102C900027BD003010A0FF700000000024A5FFFC3D +:102CA0000A0005EC240900048CD10000AF51101873 +:102CB0008F5301780660FF7A2404000A0A00060197 +:102CC0000000000000A7C8218F8800388F4E101C1C +:102CD0000019C0820018788001E82021AC8E000025 +:102CE000000E2C0200C020210E0005B331C6FFFFEC +:102CF000023B28218CAD000000025400004030212E +:102D0000AFAD00108FAC0010318BFFFFAFAB0010E8 +:102D10008FA2001001424825AFA900108FA7001014 +:102D20000A000631ACA700008F8F0040148FFFC946 +:102D30000000000097420104960B00023C050800C9 +:102D40008CA5046C3049FFFF316AFFFF3C1108007D +:102D50008E310468012A382124F2FFFE00B240219E +:102D60000012FFC30112C82B023FC021031920210A +:102D70003C010800AC28046C3C010800AC24046849 +:102D80000A00066B0000000000A4102B1040000990 +:102D9000240300010005284000A4102B04A0000318 +:102DA000000318405440FFFC000528401060000755 +:102DB000000000000085302B14C000020003184200 +:102DC000008520231460FFFB0005284203E0000873 +:102DD000008010218F85002C27BDFFE800053027DB +:102DE0002CC300012CA40002008310251040000316 +:102DF000AFBF00102405007FAF85002C00052827F9 +:102E000030A5FFFF0E000592240426F58F830030C5 +:102E1000240402BD004030210083382B10E000095B +:102E200024050001000420400083102B04800003CF +:102E3000000528405440FFFC0004204010A000087A +:102E400000C350210064402B1500000200052842F9 +:102E50000064182314A0FFFB0004204200C350218B +:102E60008FBF0010000A4C02312200FF27BD00185E +:0C2E7000AF8A002C03E00008AF8900309E +:042E7C000A00002A1E +:102E800000000000000000000000000D74787036A3 +:102E90002E322E310000000006020100000000006A +:102EA000000001360000EA600000000000000000A1 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000000000000000000000000000016DC +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000000000000000000000000000000000C1 +:102F1000000000000000138800000000000005DC35 +:102F2000000000000000000010000003000000008E +:102F30000000000D0000000D3C02080024423C206F +:102F40003C03080024633DD4AC4000000043202B28 +:102F50001480FFFD244200043C1D080037BD7FFCA7 +:102F600003A0F0213C100800261000A83C1C08001B +:102F7000279C3C200E0002BA000000000000000D5B +:102F80008F8300383C088000350700708CE5000016 +:102F9000008330253C02900000C22025AF85003020 +:102FA000AF4400208F4900200520FFFE3C03800035 +:102FB000346200708C4500008F8600303C19080098 +:102FC0008F39007C3C0E08008DCE007800A62023AF +:102FD00003245821000078210164682B01CF60216F +:102FE000018D50213C010800AC2B007C3C01080005 +:102FF000AC2A007803E00008000000000A0000414D +:10300000240400018F8400383C05800034A20001B4 +:103010000082182503E00008AF43002003E0000809 +:10302000000010213084FFFF30A5FFFF1080000753 +:1030300000001821308200011040000200042042EC +:10304000006518211480FFFB0005284003E00008FC +:103050000060102110C00007000000008CA20000DA +:1030600024C6FFFF24A50004AC82000014C0FFFBAF +:103070002484000403E000080000000010A0000801 +:1030800024A3FFFFAC860000000000000000000049 +:103090002402FFFF2463FFFF1462FFFA248400046C +:1030A00003E0000800000000308AFFFF93A800132F +:1030B000A74A014497490E1630C600FF3C02100093 +:1030C000A7490146AF450148A3460152A748015A06 +:1030D000AF4701608FA400188FA30014A7440158C4 +:1030E000AF43015403E00008AF42017803E0000859 +:1030F000000000003C038000346200708C49000036 +:103100008F8800002484000727BDFFF83084FFF873 +:10311000AF890030974D008A31ACFFFFAFAC0000A3 +:103120008FAB0000016850232547FFFF30E61FFFEB +:1031300000C4282B14A0FFF73C0C8000358B0070D6 +:103140008D6A00003C0708008CE700843C060800FC +:103150008CC6008000081082014918230002788084 +:1031600000E370210000202101C3C82B00C4C0214E +:1031700001FA4021031948212502400027BD00081B +:103180003C010800AC2E00843C010800AC29008002 +:1031900003E00008000000008F8200002486000782 +:1031A00030C5FFF800A2182130641FFF03E00008BB +:1031B000AF8400008F8700388F8A004027BDFFB89A +:1031C0008F860044AFB60040AFBF0044AFB5003CAF +:1031D000AFB40038AFB30034AFB20030AFB1002CA1 +:1031E000AFB000288F4501048D4900ACAF47008087 +:1031F0008CC8002000A938230000B021AF480E1071 +:103200008F440E1000004821AF440E148CC20024DD +:10321000AF420E188F430E18AF430E1C10E001256D +:103220002D230001936B0008116000D40000000002 +:10323000976E001031CDFFFF00ED602B158000CFA1 +:103240000000000097700010320FFFFFAF4F0E001C +:103250008F520000325100081220FFFD00000000D4 +:1032600097540E088F460E043285FFFF30B30001DD +:1032700012600132000000000000000D30B8A040D4 +:1032800024150040131500C030A9A0001120012D05 +:1032900000000000937F000813E000080000000019 +:1032A00097630010306BFFFF00CB402B1100000331 +:1032B00030AC00401180012300000000A785003CD5 +:1032C000AF8600349366000800E02821AFA70020F5 +:1032D00014C0012427B30020AF60000C9782003C8B +:1032E0003047400014E00002240300162403000EBF +:1032F00024194007A363000AAF790014938A003EA3 +:103300008F740014315800070018AA4002959025C8 +:10331000AF7200149784003C8F700014309100103D +:1033200002117825AF6F0014978E003C31CD000854 +:1033300011A00147000028218F6700143C021000F3 +:103340003C0C810000E22825AF65001497460E0A68 +:103350002408000E3405FFFC30C3FFFF006C582525 +:10336000AF6B0004A3680002937F000A27E9000402 +:10337000A369000A9786003C9363000A30CC1F00C3 +:10338000000C598301634021251F0028A37F0009F9 +:1033900097490E0CA769001093790009272A0002AB +:1033A000315800070018A82332B10007A371000BA1 +:1033B00093740009976400108F910034978F003C3C +:1033C000329200FF024480210205702131ED00405D +:1033D00011A0000531C4FFFF0091282B3C12800092 +:1033E00010A000140000A0210224382B14E0011BBF +:1033F0008FA500208F4D0E14AF4D0E108F420E1C66 +:10340000AF420E18AF440E008F4F000031EE00089F +:1034100011C0FFFD0000000097540E0800808821B5 +:1034200000009021A794003C8F500E04241400014A +:10343000AF900034976400103095FFFF8E68000055 +:103440000111F82317E00009AE7F00008F6500141A +:103450008F8B004434A60040AF6600148F4C0E10D2 +:10346000AD6C00208F430E18AD63002493670008F5 +:1034700014E000D2000000000E00009E24040010A2 +:103480008F8900483C08320000402821312600FF87 +:103490000006FC0003E8502525390001AF990048DB +:1034A000AC4A0000937800099370000A330400FFCF +:1034B00000047400320F00FF01CF6825AC4D0004FA +:1034C0008F820048064000EAACA20008ACA0000CC5 +:1034D0009783003C306B0008156000022628000628 +:1034E00026280002974E0E148F450E1C8F6700048D +:1034F000936D000231C4FFFF31A200FFAFA20010A4 +:103500008F6C0014AFA800180E00008BAFAC001435 +:10351000240400100E0000C7000000008E7200009E +:1035200016400005000000008F6400142405FFBF52 +:1035300000859824AF7300148F79000C033538216F +:10354000AF67000C9375000816A00008000000008B +:1035500012800006000000008F7F00143C0BEFFF7C +:103560003568FFFE03E84824AF690014A37400081F +:103570008FA500200A00024602202021AF470E003E +:103580000A0000F5000000008F5901780720FFFEB7 +:10359000241F08008F840000AF5F0178974B008ADA +:1035A000316AFFFF014448232528FFFF31021FFF36 +:1035B0002C4300081460FFF9000000008F8E0048C3 +:1035C0008F8D003800C048210344202125C600010A +:1035D000240C0F00AF86004800E938232486400001 +:1035E00031CA00FF11AC0005240800019391003E90 +:1035F0003230000700107A4035E80001000AAC00C4 +:103600003C18010002B8A025AC9440008F930048FC +:1036100030B2003630A40008ACD30004108000970C +:1036200001123025974E0E0A8F8D00003C0281005A +:1036300031CCFFFF25AB0008018240253C03100080 +:1036400031651FFF25390006241F000EAF480160B9 +:1036500000C33025A75F015AAF850000A759015864 +:1036600014E0000A8F93003824120F0052720002F7 +:103670002416000134C600408F580E108F94004469 +:10368000AE9800208F550E18AE9500248F450E146D +:10369000AF4501448F590E1CAF590148A34A01524E +:1036A0003C0A1000AF460154AF4A017814E0FEDD39 +:1036B0002D2300010076A025128000178FBF004443 +:1036C0008F84003824160F0010960084000000003C +:1036D0008F45017804A0FFFE24150F001095006EA1 +:1036E000000000008F470E14240202403C1F10000F +:1036F000AF4701448F440E1CAF440148A340015220 +:10370000A740015AAF400160A7400158AF420154A1 +:10371000AF5F01788FBF00448FB600408FB5003C8B +:103720008FB400388FB300348FB200308FB1002CCB +:103730008FB0002803E0000827BD004814C0FED069 +:1037400030B8A0408F420E148F84004400004821FE +:10375000AC8200208F510E1CAC9100240A00020E96 +:103760002D2300018F910034978A003C3C12800089 +:103770000220A821315800401700FF300000A0218E +:10378000976900108F9200343139FFFF13320035F2 +:1037900000002021008048211480FEA000A03821D4 +:1037A0008F420E148F840044AC8200208F510E1C77 +:1037B000AC9100240A00020E2D230001936A000937 +:1037C0009378000B315000FF330F00FF020F702180 +:1037D00025C2000A3050FFFF0E00009E020020218B +:1037E0008F8600483C1F410024CD0001AF8D00486A +:1037F000936C000930C600FF00064400318300FFCF +:10380000246B0002010B4825013FC825AC5900007C +:103810008F67000C97440E1400F22825AC45000475 +:103820008F450E1C8F670004936A00023084FFFFEF +:10383000315800FFAFB800108F6F0014AFB10018FF +:103840000E00008BAFAF00140A0001A60200202179 +:10385000AF6000040A00013EA36000020A000246B5 +:1038600000002021000090210A00017024140001B2 +:103870003C1280000A000195ACB2000C8F91000050 +:1038800025240002A744015826300008320F1FFFEC +:103890000A0001F9AF8F0000AF40014C1120002C4D +:1038A000000000008F590E10AF5901448F430E18CD +:1038B000240200403C1F1000AF430148A3400152C6 +:1038C000A740015AAF400160A7400158AF420154E0 +:1038D000AF5F01780A0002278FBF00441120000665 +:1038E0000000000097460E0830CC00401580000212 +:1038F000000000000000000D8F4D017805A0FFFEC4 +:103900000000000097530E103C120500240E20000A +:10391000326AFFFF0152C025AF58014C8F4F0E1481 +:103920003C021000AF4F01448F500E1CAF500148B5 +:10393000A34001528F840038A740015AAF40016074 +:10394000A7400158AF4E01540A000215AF4201785A +:103950008F490E14AF4901448F430E1C0A00028E9A +:10396000240200403C0E20FF27BDFFE03C1A8000EF +:103970003C0F800835CDFFFDAFBF001CAFB2001873 +:10398000AFB10014AFB00010AF8F0040AF4D0E00CC +:103990000000000000000000000000000000000027 +:1039A000000000003C0C00FF358BFFFDAF4B0E000C +:1039B0003C0660048CC95000240AFF7F3C11600063 +:1039C000012A40243507380CACC750008E24043837 +:1039D00024050009AF4500083083FFFF38622F71CE +:1039E0002450C0B3AF8000480E000068AF800000D4 +:1039F00052000001AE20442C0E0004353C11800022 +:103A00000E000ED9363000708F8A00403C1208003C +:103A100026523C88020088218E0800008F5F00003B +:103A20003BF900013338000113000017AF88003064 +:103A3000022048218D2700003C0F08008DEF006C0C +:103A40003C0C08008D8C006800E8C02301F8282198 +:103A50000000682100B8302B018D582101664021FB +:103A60003C010800AC25006C3C010800AC28006853 +:103A70008F44000038830001306200011440FFEDE4 +:103A800000E04021AF8700308E0C00003C050800AC +:103A90008CA5006C3C0408008C84006801883023ED +:103AA00000A638210000102100E6402B00821821DA +:103AB0000068F8213C010800AC27006C3C010800BC +:103AC000AC3F00688F49010025590088AF99004438 +:103AD000AF890038AF4900208E070000AF87003063 +:103AE0008F4D017805A0FFFE000000008E0600004B +:103AF0003C0B08008D6B00743C0408008C84007043 +:103B000000C728230165F8210000102103E5402BA0 +:103B10000082382100E8C821240908003C0108007F +:103B2000AC3F00743C010800AC390070AF4901782B +:103B300093580108A398003E938F003E31EE000198 +:103B400015C000158F830038240E0D00106E00196B +:103B5000240F0F00106F001D00000000915900009D +:103B600024180050332900FF113800043C1F400086 +:103B7000AF5F01380A0002E7000000000E00090EE6 +:103B8000000000008F8A00403C1F4000AF5F0138FA +:103B90000A0002E700000000938D003E31AC0006F1 +:103BA000000C51000E0000CE0152D8210A00034340 +:103BB0008F8A00403C1B0800277B3D080E0000CE8A +:103BC000000000000A0003438F8A00403C1B0800ED +:103BD000277B3D280E0000CE000000000A000343B2 +:103BE0008F8A004090AA00018FAB00108CAC0010AF +:103BF0003C0300FF8D680004AD6C00208CAD001408 +:103C000000E060213462FFFFAD6D00248CA7001836 +:103C10003C09FF000109C024AD6700288CAE001CE0 +:103C20000182C82403197825AD6F0004AD6E002C05 +:103C30008CAD0008314A00FFAD6D001C94A9000254 +:103C40003128FFFFAD68001090A70000A5600002BA +:103C5000A1600004A167000090A30002306200FF91 +:103C60000002198210600005240500011065000E95 +:103C70000000000003E00008A16A00018CD80028C1 +:103C8000354A0080AD7800188CCF0014AD6F001459 +:103C90008CCE0030AD6E00088CC4002CA16A0001EF +:103CA00003E00008AD64000C8CCD001CAD6D001865 +:103CB0008CC90014AD6900148CC80024AD680008DC +:103CC0008CC70020AD67000C8CC200148C8300648C +:103CD0000043C82B13200007000000008CC2001412 +:103CE000144CFFE400000000354A008003E00008A7 +:103CF000A16A00018C8200640A00039900000000A0 +:103D000090AA000027BDFFF88FA9001CA3AA0000FD +:103D10008FAE00003C0FFF808FA8001835E2FFFF38 +:103D20008CCD002C01C26024AFAC0000A1200004A7 +:103D300000E06021A7A000028FB800008D270004DA +:103D40000188182100A0582100C05021006D2826AC +:103D50003C06FF7F3C0F00FF2CAD000135EEFFFF5E +:103D600034D9FFFF3C02FF0003193024000D1DC0B1 +:103D7000010EC82400E2C02400C370250319782571 +:103D8000AD2E0000AD2F00048D450024AFAE000025 +:103D9000AD2500088D4D00202405FFFFAD2D000C42 +:103DA000956800023107FFFFAD27001091660018EB +:103DB00030C200FF000219C2506000018D4500347E +:103DC000AD2500148D67000827BD0008AD27001C35 +:103DD0008C8B00CCAD2C0028AD20002CAD2B00240A +:103DE000AD20001803E00008AD20002027BDFFE053 +:103DF000AFB20018AFB10014AFB00010AFBF001CDD +:103E00009098000000C088213C0D00FF330F007F18 +:103E1000A0CF0000908E000135ACFFFF3C0AFF00F0 +:103E2000A0CE000194A6001EA22000048CAB0014BA +:103E30008E29000400A08021016C2824012A40243E +:103E40000080902101052025A6260002AE24000452 +:103E500026050020262400080E0000762406000215 +:103E600092470000260500282624001400071E00A3 +:103E70000003160324060004044000032403FFFF8C +:103E8000965900023323FFFF0E000076AE23001088 +:103E9000262400248FBF001C8FB200188FB100149D +:103EA0008FB0001024050003000030210A000080BC +:103EB00027BD002027BDFFD8AFB1001CAFB0001850 +:103EC000AFBF002090A80000240200018FB0003C8A +:103ED0003103003F00808821106200148FAA00384F +:103EE000240B0005506B0016AFAA001000A0202183 +:103EF00000C028210E0003DC02003021922400BC07 +:103F0000308300021060000326060030ACC00000C1 +:103F100024C600048FBF00208FB1001C8FB0001892 +:103F200000C0102103E0000827BD0028014038210F +:103F30000E00035AAFB000100A0004200000000079 +:103F40000E0003A1AFB000140A000420000000001E +:103F50003C02000A034218213C04080024843D6C02 +:103F60002405001A000030210A000080AF830054AD +:103F70003C038000346200708C48000000A058218F +:103F800000C04821308A00FFAF8800308F4401789C +:103F90000480FFFE3C0C8000358600708CC500005C +:103FA0003C0308008C6300743C1808008F180070F4 +:103FB00000A82023006468210000C82101A4782BF8 +:103FC0000319702101CF60213C010800AC2D007461 +:103FD0003C010800AC2C00708F480E14AF4801441F +:103FE000AF47014CA34A0152A74B01589346010821 +:103FF00030C5000854A0000135291000934B09007A +:1040000024070050316A00FF11470007000000003C +:104010008F450E1CAF450148AF4901543C091000C3 +:1040200003E00008AF490178934D010831A800086A +:104030001100001000000000934F010831EE001045 +:1040400051C00001352900083C04080090843DD08F +:10405000A34401508F4309A4AF4301488F4209A0F4 +:10406000AF420144AF4901543C09100003E000088D +:10407000AF4901783C1908008F393D8C333800086E +:104080005700FFF1352900080A0004730000000002 +:1040900024070040AF470814AF4008108F4209447E +:1040A0008F4309508F4409548F45095C8F46094C52 +:1040B000AF820064AF830050AF84004CAF85005CDA +:1040C00003E00008AF8600609346010930C5007F19 +:1040D000000518C0000521400083102103E00008FE +:1040E000244200883C09080091293D9124A800023F +:1040F0003C05110000093C0000E8302500C51825EA +:1041000024820008AC83000003E00008AC800004B7 +:104110009347010B8F4A002C974F09083C18000E5B +:104120000358482131EEFFFF000E41C0AF48002C7C +:1041300097430908952C001A0080402124030001B0 +:10414000318BFFFFAC8B00008D2D001C00A058218F +:1041500000C06021AC8D00048D24002030E70040B9 +:10416000AD04000891220019304400031083004878 +:104170002885000214A00062240600021086005662 +:1041800024190003109900660000000010E0003AB6 +:10419000000000003C07080094E73D8624E200018F +:1041A000934F0934934709219525002A31EE00FFEA +:1041B000000E488230ED00FF978700580009360056 +:1041C000000D1C003044FFFF00C310250044C02533 +:1041D00000A778213C19400003197025000F4C00FE +:1041E000AD090004AD0E0000934D09203C0300060C +:1041F00025090014000D360000C32025AD04000879 +:104200008F59092C24E5000130A27FFFAD19000C65 +:104210008F580930A782005825020028AD180010D9 +:104220008F4F0938AD0F0014AD2B00048F4E09409D +:10423000AD2E0008934D09373C05080090A53D9030 +:104240008F4409488F46094031A700FF00EC182130 +:10425000008678230003C7000005CC000319602501 +:1042600031E8FFFC01885825AD2B000CAD20001073 +:1042700003E00008AF4A002C3C0D080095AD3D86D8 +:104280003C0E080095CE3D800A0004C901AE102105 +:104290003C05080094A53D8A3C06080094C63D8074 +:1042A0003C18080097183D7C952E002400A6782124 +:1042B00001F86823000E240025A2FFF200821825D1 +:1042C00024190800AD03000CAD190014AD00001056 +:1042D0000A0004C425080018952600249525002806 +:1042E0000006C40000057C00370E810035ED080093 +:1042F000AD0E000CAD0D00100A0004C4250800141A +:104300001480FFA200000000952400240004140083 +:1043100034430800AD03000C0A0004C42508001053 +:104320003C03080094633D8A3C05080094A53D8049 +:104330003C06080094C63D7C953900249538002839 +:10434000006520210086782300196C000018740095 +:1043500025E2FFEE01C2202535A3810024190800C3 +:10436000AD03000CAD040010AD190018AD00001431 +:104370000A0004C42508001C03E00008240201F41C +:1043800027BDFFE8AFB00010AFBF00140E00006003 +:104390000080802124050040AF4508148F83005021 +:1043A0008F84004C8F85005C0070182100641023FE +:1043B00018400004AF830050AF6300548F66005470 +:1043C000AF86004C1200000C000000008F44007407 +:1043D000936800813409FA002D07000710E00005FA +:1043E00000891021936C0081240B01F4018B50048F +:1043F00001441021AF62000C8F4E095C01C5682397 +:1044000019A000048FBF00148F4F095CAF8F005CB0 +:104410008FBF00148FB000100A00006227BD001883 +:104420008F8400648F8300508F82004CAF640044FF +:10443000AF63005003E00008AF6200543C0380000B +:10444000346200708C43000027BDFFF8308700FF06 +:1044500030A900FF30C800FFAF8300308F440178DF +:104460000480FFFE3C028000345900708F38000049 +:10447000A3A700033C0708008CE700748FAC000082 +:104480003C0608008CC60070030378233C0E7FFFB7 +:1044900000EFC82135CDFFFF00005021018D2824F9 +:1044A00000CA1821000847C0032F202B00A81025A0 +:1044B0000064C021AFA200003C010800AC390074C8 +:1044C0003C010800AC380070934F010AA3A0000221 +:1044D0003C0E80FFA3AF00018FAC0000312B007FAA +:1044E00035CDFFFF018D4824000B5600012A4025E1 +:1044F000240730002406FF803C05100027BD00087B +:10450000AF48014CAF470154A7400158A3460152A0 +:1045100003E00008AF45017827BDFFE8AFBF0014F6 +:10452000AFB000108F6500743C068000309000FF33 +:1045300000A620250E000060AF64007493630005A0 +:10454000346200080E000062A36200050200202110 +:104550008FBF00148FB00010240500052406000151 +:104560000A00057027BD001827BDFFE03C0380004E +:10457000AFB00010AFBF0018AFB1001434620070CC +:104580008C470000309000FF30A800FFAF8700305C +:104590008F4401780480FFFE3C18800037110070C2 +:1045A0008E2F00003C0D08008DAD00743C0A080001 +:1045B0008D4A007001E7702301AE282100005821C8 +:1045C00000AE302B014B4821012638213C01080068 +:1045D000AC250074000088213C010800AC27007065 +:1045E0001100000F000000008F6200742619FFFF09 +:1045F0003208007F0002FE0233E5007F150000064E +:10460000332200FF2407FF800207202624A3FFFF98 +:1046100000838025320200FF004080212411100811 +:104620000E000060000000008F49081831250004CA +:1046300014A0FFFD3218007F001878C000187140E8 +:1046400001CF682125AC0088AF4C0818274A0980A3 +:104650008D4B0020AF4B01448D460024AF460148EE +:10466000A35001500E000062A74001580220102103 +:104670008FBF00188FB100148FB0001003E0000846 +:1046800027BD002027BDFFE8308400FFAFBF00102A +:104690000E0005BB30A500FF8F8300508FBF0010B8 +:1046A000344500402404FF903C02100027BD001850 +:1046B000AF43014CA3440152AF45015403E000084D +:1046C000AF4201789343093E306200081040000D6C +:1046D0003C0901013528080AAC8800008F470074A6 +:1046E000AC8700043C06080090C63D9030C5001021 +:1046F00050A00006AC8000088F6A0060AC8A0008F9 +:104700002484000C03E00008008010210A00062227 +:104710002484000C27BDFFE8AFBF0014AFB0001029 +:104720009346093F00A050210005288000853823CA +:1047300030C200FF240300063C09080095293D868D +:1047400024E8FFD8240500041043003724060002A3 +:104750009750093C3C0F020400063400320EFFFF64 +:1047600001CF6825AC8D0000934C093E318B0020B1 +:104770001160000800000000934309363C02010369 +:10478000345F0300307900FF033FC0252405000893 +:10479000AC98000493430934935909210005F88229 +:1047A000306200FF0002C082332F00FF00186E004D +:1047B000000F740001AE6025018920253C094000EE +:1047C00000898025ACF0FFD8934309378F4F094803 +:1047D0008F580940306200FF004AC821033F702112 +:1047E00001F86023000E6F0001A650253185FFFC03 +:1047F000001F58800145482501683821AD09002077 +:104800000E00006024F00028240400040E00006262 +:10481000A364003F020010218FBF00148FB000106E +:1048200003E0000827BD00180A0006352406001220 +:1048300027BDFFD024090010AFB60028AFB5002473 +:10484000AFB40020AFB10014AFB000103C010800BD +:10485000A0293D90AFBF002CAFB3001CAFB2001831 +:1048600097480908309400FF3C02000E3107FFFF13 +:10487000000731C0AF46002C974409089344010B50 +:1048800030B500FF03428021308300300000B021AA +:104890001060012500008821240C00043C01080060 +:1048A000A02C3D90934B093E000B5600000A2E03AE +:1048B00004A0016000000000AF400048934F010BCE +:1048C00031EE002011C00006000000009358093EA0 +:1048D00000189E00001396030640018900000000A6 +:1048E0009344010B30830040106000038F9300500D +:1048F0008F8200502453FFFF9347093E30E60008A3 +:1049000014C0000224120003000090219619002C0C +:1049100093580934934F0937A7990058330C00FF77 +:1049200031EE00FF024E6821000D5880016C5021CD +:10493000015140213C010800A4283D869205001841 +:1049400030A900FF010918213C010800A4233D887B +:104950009211001816200002000000000000000D57 +:104960003C010800A4233D8A3C010800A4203D80AE +:104970003C010800A4203D7C935F010B3063FFFFE6 +:1049800033F00040120000022464000A2464000B8B +:104990003091FFFF0E00009E022020219358010B52 +:1049A0003C08080095083D8A0040202100185982E3 +:1049B000316700010E00049A01072821934C010B76 +:1049C0008F4B002C974E09083C0F000E034F4021DF +:1049D00031CDFFFF000D51C0AF4A002C97430908AD +:1049E0009505001A004038212404000130A9FFFF7A +:1049F000AC4900008D06001C00404821318A00406F +:104A0000AC4600048D020020ACE2000891030019BE +:104A100030630003106400EC2879000217200118AD +:104A2000241000021070010C241F0003107F011ECF +:104A300000000000114000DE000000003C090800FA +:104A400095293D8625220001935F0934934E092163 +:104A50009504002A33F900FF0019C08231CF00FF0E +:104A6000978E005800184600000F6C00010D80253D +:104A70003045FFFF02051025008E50213C03400009 +:104A800000433025000A6400ACEC0004ACE60000F2 +:104A9000935F09203C19000624EC0014001FC60097 +:104AA00003197825ACEF00088F48092C25CD0001AB +:104AB00031A57FFFACE8000C8F500930A785005866 +:104AC00024E80028ACF000108F4409380100802150 +:104AD000ACE40014AD9300048F530940AD9300087B +:104AE000934A09373C19080093393D908F43094890 +:104AF0008F460940314200FF0052F82100667023C2 +:104B0000001F7F000019C40001F8282531CDFFFCEB +:104B100000AD2025AD84000CAD800010AF4B002C03 +:104B2000934B093E317300081260000D3C060101F1 +:104B300034CC080AACEC00288F530074AD13000489 +:104B40003C0B0800916B3D903167001050E0000372 +:104B5000AD0000088F6A0060AD0A00082510000C47 +:104B600012C0003D000000009343093F24160006D8 +:104B700024060004306200FF105600C9240700021A +:104B80009758093C3C0F0204330DFFFF01AF40254D +:104B9000AE0800009345093E30A4002010800008B4 +:104BA00000000000935309363C0B0103357F0300DE +:104BB000327900FF033F7025AE0E00042406000882 +:104BC000934F093493480921312AFFFF31ED00FF4B +:104BD000000D1082310300FF0002B60000032C001C +:104BE00002C56025018A9825001220803C094000FA +:104BF0000204502302695825AD4BFFD8935F093753 +:104C00008F4F09488F58094033F900FF0332702154 +:104C10000006B08201D668210007440001F828236D +:104C2000000D1F000068302530A2FFFC2547FFD88B +:104C300000C260250016808002074821ACEC0020ED +:104C4000253000280E00006024120004A372003FEB +:104C50000E000062000000009347010B30F200409C +:104C6000124000053C1900FF8E180000372EFFFF90 +:104C7000030E3024AE0600000E0000C702202021E3 +:104C80003C10080092103D90321100031220000FDA +:104C900002A028218F89005025330001AF930050D6 +:104CA000AF7300508F6B00540173F8231BE00002B8 +:104CB000026020218F640054AF6400548F4C007454 +:104CC000258401F4AF64000C02A028210280202179 +:104CD000A76000680E0005BB3C1410008F850050D3 +:104CE00034550006AF45014C8F8A00488FBF002C19 +:104CF0008FB3001C25560001AF9600488FB20018F4 +:104D0000A34A01528FB60028AF5501548FB1001449 +:104D1000AF5401788FB500248FB400208FB00010FD +:104D200003E0000827BD00309358093E00189E009C +:104D3000001396030642003624110002934409230F +:104D4000308300021060FEDD8F8600608F8200508D +:104D500014C2FEDA000000000E0000600000000037 +:104D60009369003F24070016312800FF1107000C4B +:104D7000240500083C0C0800918C3D90358B000107 +:104D80003C010800A02B3D90936A003F314300FF97 +:104D900010650065240D000A106D005E2402000CF1 +:104DA0000E000062000000000A00069000000000F3 +:104DB0003C09080095293D863C0A0800954A3D803B +:104DC0000A0006F3012A10213C09080095293D8AB2 +:104DD0003C04080094843D803C06080094C63D7C59 +:104DE00095030024012410210046F8230003CC0081 +:104DF00027F0FFF20330C025240F0800ACF8000CA8 +:104E0000ACEF0014ACE000100A0006EE24E7001836 +:104E10003C010800A0313D90935F093E241600013B +:104E200033F900201720FEA5241100080A0006907F +:104E3000241100048F6E00848F4D094011A0FE9E46 +:104E4000AF8E0050240F00143C010800A02F3D90AD +:104E50000A00068F00000000950E0024950D002822 +:104E6000000E6400000D2C003589810034A6080076 +:104E7000ACE9000CACE600100A0006EE24E70014D2 +:104E80001460FEEC000000009502002400021C00EB +:104E900034640800ACE4000C0A0006EE24E70010BD +:104EA0000A000741240700123C02080094423D8A90 +:104EB0003C06080094C63D803C03080094633D7C9A +:104EC00095100024951900280046F82103E3C0231B +:104ED00000106C0000197400270FFFEE01CF282589 +:104EE00035AC8100ACEC000CACE5001024070800E8 +:104EF000AD2700182527001C0A0006EEAD2000147F +:104F00008F7F004CAF7F00548F7900540A000699C0 +:104F1000AF790050A362003F0E0000620000000065 +:104F20000A00069000000000240200140A0008276E +:104F3000A362003F27BDFFE8308400FFAFBF001031 +:104F40000E0005BB30A500FF9378007E9379007FAB +:104F5000936E00809368007A332F00FF001866007C +:104F6000000F6C0031CB00FF018D4825000B520073 +:104F70008FBF0010012A3825310600FF344470002D +:104F800000E628252402FF813C03100027BD0018FD +:104F9000AF45014CAF440154A342015203E0000865 +:104FA000AF43017827BDFFD8AFB20018AFB10014EE +:104FB000AFB00010AFBF0020AFB3001C9342010997 +:104FC000308600FF30B000FF000618C23204000235 +:104FD0003071000114800005305200FF9367000516 +:104FE00030E5000810A0000D30C80010024020215C +:104FF0000E0005A702202821240400018FBF0020F5 +:105000008FB3001C8FB200188FB100148FB0001046 +:105010000080102103E0000827BD002815000032A1 +:105020000000000093430109000028213062007F46 +:10503000000220C00002F94003E49821267900888C +:10504000033B98218E7800248E6F0008130F0046D2 +:10505000000000008F640084241800020004FD8218 +:1050600033F900031338007C0000000093660083CE +:10507000934A0109514600043205007C10A00060EB +:10508000000000003205007C14A0005302402021E3 +:1050900016200006320400018E7F00248F5901047F +:1050A00017F9FFD600002021320400011080000A09 +:1050B000024020218F4209408F9300641053000664 +:1050C000000000000E00066D022028218F430940D9 +:1050D000AF630044024020210E0006020220282176 +:1050E0000A000860240400013C0908008D290064BE +:1050F000252600013C010800AC26006416000012C1 +:10510000000000008F6D00843C0E00C001AE6024E2 +:1051100015800005024020210E00082E02202821C3 +:105120000A00086024040001240500040E00057034 +:1051300024060001024020210E00082E0220282112 +:105140000A000860240400010E000041240400014C +:10515000936B007D020B50250E000062A36A007D58 +:105160000A0008A38F6D00848F6600748F480104C5 +:105170008E67002400064E021507FFB63126007F19 +:10518000936B008326440001308A007F1146004360 +:10519000316300FF5464FFB08F6400842645000132 +:1051A00030B1007F30A200FF122600042405000168 +:1051B000004090210A00087624110001240FFF808E +:1051C000024F702401CF9026324200FF0040902110 +:1051D0000A000876241100010E00066D0220282125 +:1051E000321800301300FFAA321000820240202142 +:1051F0000E0005A7022028210A00086024040001EF +:105200008F6E00743C0F80002405000301CF9025B1 +:10521000AF72007493710083240600010E000570C4 +:10522000322400FF0E00004124040001936D007D34 +:10523000020D60250E000062A36C007D3C0B08008F +:105240008D6B0054257000013C010800AC30005407 +:105250000A000860240400018F6800743C09800083 +:105260002405000401093825AF67007493630083A7 +:10527000240600010E000570306400FF0E0000419E +:10528000240400019362007D020298250E00006252 +:10529000A373007D0A00086024040001324D0080E1 +:1052A00039AC0080546CFF6C8F6400840A0008C91C +:1052B0002645000127BDFFC83C0A0008AFBF0030EB +:1052C000AFB5002CAFB40028AFB30024AFB20020BC +:1052D000AFB1001CAFB00018034AD8212409004028 +:1052E000AF490814AF4008108F4209448F4309505A +:1052F0008F4609548F47095C8F48094C9344010835 +:105300009345010BAF820064308400FF30A500FF9D +:10531000AF830050AF86004CAF87005C0E00084A98 +:10532000AF8800601440017D8FBF0030A760006827 +:10533000934D0900240B00503C15080026B53D484C +:1053400031AC00FF3C12080026523D58118B00037F +:10535000000000000000A8210000902193510109E5 +:105360008F9F005024040010322E007F000E68C072 +:10537000000E6140018D282124B40088AF54081824 +:105380008F4901048F4A09A43C0B000E034BC02136 +:10539000012A10233C010800AC223D6C8F430958C0 +:1053A0003C010800A0243D9097470908007F302366 +:1053B0003C010800AC263D7030E8FFFF0008C9C082 +:1053C0003C010800AC3F3D94AF59002C97420908BE +:1053D0009710002C8EB10000930F001803749821D1 +:1053E000A7900058AF9300440220F80931F000FF65 +:1053F000304E000215C001B2304F000111E0014FE4 +:10540000000000009343093E3066000814C000020B +:10541000241400030000A0218F5809A424130001C4 +:105420003C010800AC383D98934F0934935109373B +:1054300031EC00FF322E00FF028E6821000D288023 +:1054400000AC5021015058213C010800A42B3D889C +:105450003C010800A42A3D8693490934312200FF0B +:1054600002022021249000103C010800A4303D8459 +:10547000240700068F9F00503C010800AC273D8C9C +:105480008F88005C8F59095800008021011F282354 +:1054900004A00149033F20230480014700A4302BCE +:1054A00010C00149000000003C010800AC253D701F +:1054B0008E4200000040F809000000003043000266 +:1054C000146000F80040882130440001548000102E +:1054D0008E4200043C0908008D293D743C0AC0003E +:1054E000012A8025AF500E008F45000030AB000828 +:1054F0001160FFFD00000000974D0E082410000110 +:10550000A78D003C8F4C0E04AF8C00348E420004FB +:105510000040F8090000000002228825322E000217 +:1055200015C00180000000003C09080095293D7C61 +:105530003C06080094C63D883C0A0800954A3D7E1A +:105540003C1908008F393D74012660213C18080081 +:105550008F183D983C03080094633D92018A2021F6 +:105560008F4E09400329F821248F000203E32821EC +:10557000031968213C010800A42C3D8AAF8E006409 +:105580003C010800AC2D3D983C010800A4253D805D +:105590000E00009E31E4FFFF8F870048004020216D +:1055A0003C010800A0273D918E42000824E800013C +:1055B000AF8800480040F809000000009344010B48 +:1055C0008F4C002C974A09083C0B000E034B4021DE +:1055D0003149FFFF000919C08F8B0050AF43002CE9 +:1055E000974309089506001A00403821308A004088 +:1055F00030DFFFFFAC5F00008D19001C0040482128 +:10560000AC5900048D180020AC580008910F001907 +:1056100031E30003107300F0000000002862000274 +:105620001440010924050002106500FD240D00034B +:10563000106D010D00000000114000D900000000B5 +:105640003C0A0800954A3D8625420001934D0934E5 +:1056500093580921950E002A31A300FF00032082F0 +:10566000331F00FF9798005800047E00001FCC00F5 +:1056700001F940253049FFFF0109102501D83021EB +:105680003C0540000045502500066C00ACED0004D0 +:10569000ACEA0000934309203C04000624ED00140A +:1056A0000003FE0003E4C825ACF900088F49092C6B +:1056B000270F000131EE7FFFACE9000C8F48093065 +:1056C000A78E005824E90028ACE800108F4509385F +:1056D00001204021ACE50014ADAB00048F4209402D +:1056E000ADA20008934B09373C1F080093FF3D9083 +:1056F0008F4309488F4A0940316600FF00D42021BA +:10570000006A78230004C700001FCC000319282575 +:1057100031EEFFFC00AE1025ADA2000CADA00010D4 +:10572000AF4C002C934C093E318B00085160000FA8 +:105730008E58000C3C06010134CA080AACEA002865 +:105740008F4B0074AD2B00043C0C0800918C3D90F5 +:105750003187001050E00003AD2000088F62006028 +:10576000AD2200082528000C8E58000C0300F80913 +:10577000010020213C19080097393D8A3C1F080090 +:1057800097FF3D7E033F782125E900020E0000C708 +:105790003124FFFF3C0E08008DCE3D6C3C08080014 +:1057A0008D083D7401C828233C010800AC253D6CE0 +:1057B00014A00006000000003C0308008C633D8C30 +:1057C000346400403C010800AC243D8C12000070A1 +:1057D0008F8C00448F470E108F900044AE0700203E +:1057E0008F4D0E18AE0D00243C10080096103D8021 +:1057F0000E0000600000000024020040AF420814C8 +:105800008F8600508F8A004C00D01821006A5823E0 +:1058100019600004AF830050AF6300548F650054DB +:10582000AF85004C1200000C000000008F44007493 +:10583000936800813409FA002D0E000711C000059D +:1058400000891821937F0081241901F403F9780459 +:1058500001E41821AF63000C8F44095C8F83005C66 +:105860000083C0231B000003000000008F50095C70 +:10587000AF90005C0E000062000000008F8C0050B2 +:105880008E4700103C010800AC2C3D9400E0F80964 +:10589000000000003C0D08008DAD3D6C55A0FEF5EC +:1058A000240700068F450024975909088F8B006450 +:1058B0008F9400503C0F001F978200588F86005431 +:1058C0008F93004C3328FFFF35E9FF8000A9502457 +:1058D000000871C032320100AF4E0024A4C2002C77 +:1058E000AF4A0024AF6B0044AF740050AF73005454 +:1058F0001640008032380010570000868EA4000445 +:10590000322300405460001B8EB100088EB0000CA2 +:105910000200F809000000008FBF00308FB5002C96 +:105920008FB400288FB300248FB200208FB1001CE9 +:105930008FB0001803E0000827BD00389347010925 +:105940008F8800380007FE0003E8C825AF590080A3 +:105950008F5809A08F5309A4AFB80010AF580E1488 +:105960008FB40010AF540E10AF530E1C0A00096222 +:10597000AF530E180220F809000000008EB0000C92 +:105980000200F809000000000A000AA88FBF0030DA +:10599000A5800020A59300220A000A5BAD93002495 +:1059A0003C09080095293D863C06080094C63D80C8 +:1059B0000A0009F4012610213C010800AC203D70CA +:1059C0000A00098E8E4200003C010800AC243D70A4 +:1059D0000A00098E8E4200003C03080094633D8A51 +:1059E0003C04080094843D803C1F080097FF3D7CE8 +:1059F000951800240064C821033F782300186C0028 +:105A000025EEFFF201AE2825AC45000C240208006B +:105A1000ACE20014ACE000100A0009EF24E7001823 +:105A200095060024950900280006240000091C00A2 +:105A3000349F810034790800ACFF000CACF90010F1 +:105A40000A0009EF24E700141460FEFB00000000C8 +:105A50009518002400187C0035EE0800ACEE000C10 +:105A60000A0009EF24E700103C07080094E73D8096 +:105A70003C04080094843D8A3C03080094633D7C08 +:105A800095190024951800280087F82103E378234E +:105A90002407080000192C0000186C0025EEFFEE0A +:105AA00001AE302534A28100AD2700182527001C47 +:105AB000AD22000CAD2600100A0009EFAD20001445 +:105AC00093520109000028210E000602324400FF13 +:105AD0008FBF00308FB5002C8FB400288FB3002407 +:105AE0008FB200208FB1001C8FB0001803E00008B7 +:105AF00027BD0038935F010933E400FF0E00066DF7 +:105B000000002821323800105300FF7E322300406D +:105B10008EA400040080F809000000000A000AA218 +:105B2000322300401200FF5F000000008F540E146B +:105B30008F920044AE5400208F530E1C0A000A8A34 +:105B4000AE5300248F82001C008040213C040100E1 +:105B50009047008530E3002010600009000000003D +:105B60003C0708008CE73D948F83001800E3202356 +:105B7000048000089389000414E30003010020213D +:105B800003E00008008010213C04010003E000084D +:105B9000008010211120000B006738238F8C00201B +:105BA00024090034918B00BC316A0002514000018D +:105BB0002409003000E9682B15A0FFF10100202125 +:105BC00000E938232419FFFC00B9C02400F9782427 +:105BD00000F8702B15C0FFEA01E8202130C2000355 +:105BE0000002182314C000123069000300003021A5 +:105BF00000A9702101C6682100ED602B1180FFE033 +:105C00003C0401002D2F00010006482B010538211E +:105C100001E9302414C0FFDA24E4FFFC2419FFFC5E +:105C200000B9C0240308202103E0000800801021EF +:105C30008F8B002024060004916A00BC31440004CC +:105C40001480FFEC00A970210A000B5E00003021D7 +:105C500027BDFFE8AFBF00108F460100934A01093E +:105C60003C1F08008FFF00902407FF80314F00FF8A +:105C700031E8007F0008614003E6C821032CC02101 +:105C800027090120012770243C010800A02F3DD0E6 +:105C9000AF4E080C3C0D08008DAD00903C04008018 +:105CA0003482000301A65821016C182124650120CB +:105CB00030AA007801424025AF48081C3C1F08006C +:105CC0008FFF00908F88004003E6C0213319000742 +:105CD00003074824033A7821AF49002825E909C081 +:105CE000952E00023C0D08008DAD008C3C0A08008A +:105CF0008D4A009031CC3FFF01A61821000C59803D +:105D0000006B282100A72024AF44002C952200021C +:105D10003C1F08008FFF008C9107008530593FFF22 +:105D200003E678210019C1800146702101F868213D +:105D300031CC007F31AB007F019A2821017A5021BC +:105D40003C03000C3C04000E00A328210144102158 +:105D500030E6002027470980AF82002CAF88001C66 +:105D6000AF890024AF85002010C00006AF8700284F +:105D70008D0200508CA4010C0044302318C0007721 +:105D800000000000910C0085240DFFDF018D3824F8 +:105D9000A10700858F8B001C8F8900248F87002826 +:105DA0008D65004CAF850018912F000D31EE00205D +:105DB00011C000170000000024090001A38900049D +:105DC000AF80000C8CE400248F85000C240A0008AE +:105DD000AF800008AF8000103C010800A42A3D7E7F +:105DE0003C010800A4203D920E000B32000030213F +:105DF0008F8500248FBF0010AF82001490A8000D83 +:105E000027BD00180008394203E0000830E2000115 +:105E1000913F00022418000133F900FF001921828C +:105E200010980039240800021088005B8F86002C2F +:105E30008CE5002414A0001B8F9F002091220000FD +:105E4000240A00053046003F10CA00472404000120 +:105E50008F860008A3840004AF860010AF86000C74 +:105E60008CE400248F85000C240A00083C01080003 +:105E7000A42A3D7E3C010800A4203D920E000B3276 +:105E8000000000008F8500248FBF0010AF82001437 +:105E900090A8000D27BD00180008394203E0000853 +:105EA00030E200018CF800088CF900248FEE00C469 +:105EB000A38000048CE40024AF8E000C8F85000CBE +:105EC0008F86000803197823240A0008AF8F00107A +:105ED0003C010800A42A3D7E3C010800A4203D921C +:105EE0000E000B32000000008F8500248FBF0010D1 +:105EF000AF82001490A8000D27BD00180008394299 +:105F000003E0000830E20001912300003062003F0E +:105F1000104400278F8500208CE400241480002189 +:105F2000000000008D2E00183C187FFF8F85002098 +:105F3000370FFFFF01CF1824AF8300088F9F0008A1 +:105F40008CA8008403E8C82B1720000203E020215E +:105F50008CA400840A000BEDAF8400088CA3010C14 +:105F60000A000BCBAF8300188D2C00188F86000819 +:105F70003C0D7FFF8F89002035A3FFFF018358244C +:105F800024040001AF8B0010AD2000CCA3840004DA +:105F90000A000BF9AF86000C8CCA00140A000BED46 +:105FA000AF8A00088CA300C80A000C30AF83000839 +:105FB0008F84002C8CAC00648C8D0014018D582BC8 +:105FC00011600004000000008CA200640A000C3084 +:105FD000AF8200088C8200140A000C30AF820008E7 +:105FE0008F85000C27BDFFE0AFBF0018AFB10014D4 +:105FF00014A00007AFB000108F8600242402000513 +:1060000090C400003083003F106200B68F840020EF +:106010008F91000800A080218F8C00283C0508008B +:106020008CA53D708D8B000431663FFF00C5502B61 +:106030005540000100C02821938D000411A0007379 +:1060400000B0F82B8F98002024040034930F00BC7C +:1060500031EE000251C000012404003000A4C82B1E +:10606000172000D10000000000A4282300B0F82B66 +:106070003C010800A4243D7C17E0006802002021B8 +:106080003C0308008C633D6C0083102B54400001DE +:10609000008018218F8800243C010800AC233D7447 +:1060A000000048219104000D308300205060000161 +:1060B0008F490E188F8300140123382B10E00059EC +:1060C000000000003C0408008C843D7400895821C5 +:1060D000006B502B114000560090602B006930235C +:1060E00000C020213C010800AC263D7412000003D2 +:1060F000241FFFFC1090008A32270003009FC82451 +:106100003C010800AC393D743C010800A4203D92DC +:106110008F84000C120400078F830020AF910008C9 +:10612000020020218C7100CCAF90000C26300001C1 +:10613000AC7000CC3C0208008C423D748F8A001089 +:10614000240700180082202301422823AF84000C7A +:1061500010800002AF850010240700108F86001CFD +:106160003C010800A0273D902407004090CC00850A +:10617000318B00C0116700408F8D001414A00015F2 +:1061800000002021934A01098F420974314500FF24 +:106190000002260224A300013090007F3071007FAE +:1061A0001230007A2407FF80A0C300833C09080056 +:1061B0008D293D8C8F880024240D0002352C000889 +:1061C0003C010800A02D3DD13C010800AC2C3D8CC9 +:1061D00024040010910E000D31C6002010C00005EF +:1061E00000801821240800013C010800AC283D74FF +:1061F000348300018FBF00188FB100148FB00010DE +:106200000060102103E0000827BD00203C010800C9 +:10621000A4203D7C13E0FF9A020020210A000C819B +:1062200000A020213C0408008C843D740090602B69 +:106230001180FFAE000000003C0F080095EF3D7C90 +:1062400001E4702101C6682B11A000072C82000414 +:106250003C1F60008FF954043338003F1700FFE5FE +:10626000240300422C8200041040FFA024030042BB +:106270000A000CDF8FBF0018152DFFC000000000C2 +:106280008CDF00743C0380002405FF8003E3C825F5 +:10629000ACD9007490D80085240E000424040010AA +:1062A000330F003F01E54025A0C800858F880024FA +:1062B0003C010800A02E3DD1240300019106000DF1 +:1062C00030C9002015200003000000003C03080036 +:1062D0008C633D743C010800AC233D6C0A000CD675 +:1062E000000000008F8700108C88008400E8282BB5 +:1062F00014A0000200E088218C9100842409000190 +:10630000A38900048F440E18022028210E000B32AE +:1063100002203021022080210A000C67AF82001485 +:1063200000071823306600033C010800A4263D92B4 +:10633000122000058F8C0020918B00BC316A000474 +:106340001540001524CD00043C0F080095EF3D9248 +:1063500001E4702100AE302B50C0FF6E8F84000C22 +:106360002C85000514A0FFA32403004230980003ED +:1063700017000002009818232483FFFC3C0108004A +:10638000AC233D740A000CA30000000000A75824B1 +:106390000A000CCB016718263C010800A42D3D9291 +:1063A0000A000D33000000003C010800AC203D74E1 +:1063B0000A000CDE240300428F83001014600007E3 +:1063C000000010218F88002424050005910600009C +:1063D00030C400FF108500030000000003E0000847 +:1063E00000000000910A0018314900FF000939C27D +:1063F00014E0FFFA8F85001C3C04080094843D7C67 +:106400003C0308008C633D943C1908008F393D74AF +:106410003C0F080095EF3D920064C0218CAD005404 +:106420000319702101CF6021018D58231960001DCF +:1064300000000000910E001C8F8C002C974B0E105A +:1064400031CD00FF8D850004016D30238D88000063 +:1064500030CEFFFF000E510000AAC82100003821F5 +:1064600001072021032A182B0083C021AD990004C5 +:10647000AD980000918F000A01CF6821A18D000A1C +:106480008F88002C974B0E12A50B0008950A003838 +:1064900025490001A50900389107000D34E60008E0 +:1064A000A106000D03E000080000000027BDFFE08A +:1064B000938700048F8F00248FAD00143C0E7FFF64 +:1064C0008F89000C35C8FFFFAFBF001CAFB00018AC +:1064D00001A8182491EA000D000717C03C1FBFFF58 +:1064E000006258252D2E00018F90001837F9FFFF0C +:1064F0003C1808008F183D943C0F080095EF3D8A2A +:1065000001796824000E47803C07EFFF3C05F0FF4F +:1065100001A818253149002034E2FFFF34ACFFFF09 +:106520000310582327A500102406000225EA0002C4 +:106530000062182400808021152000020000402104 +:106540008F480E1CA7AA0012056000372407000020 +:1065500030FF00FF001FCF008F8B001C0079382513 +:10656000AFA70014916F00853C08080091083D9189 +:106570003C18DFFF31EE00C0370AFFFF000E182B7A +:106580003C1F080097FF3D8400EA6824A3A800117F +:106590000003174001A248258FB90010AFA90014CD +:1065A0003C0A0800914A3D93A7BF00168FA800142B +:1065B000032CC0243C0B01003C0F0FFF030B1825DC +:1065C0003147000335EEFFFF010C68240007160079 +:1065D000006EF8243C09700001A2C82503E9582583 +:1065E000AFB90014AFAB00100E000076A3A00015E9 +:1065F0008F8C0024260200089186000D30C40020F4 +:10660000108000068FBF001C3C05080094A53D804B +:1066100024B0FFFF3C010800A4303D808FB000187B +:1066200003E0000827BD00208F9800140118502BAC +:106630005540FFC7240700010A000DB630FF00FFD8 +:106640009382000427BDFFE0AFBF00181040000F89 +:10665000008050218F880024240B00058F890008BA +:10666000910700008F8400200100282130E3003FC3 +:106670008F86002C106B000800003821AFA9001095 +:106680000E00040EAFAA0014A38000048FBF0018F0 +:1066900003E0000827BD00208D1900183C0F0800FA +:1066A0008DEF3D748F9800103C027FFF8D08001421 +:1066B000345FFFFF033F682401F8702101AE6023BF +:1066C00001883821AFA900100E00040EAFAA0014F3 +:1066D0000A000E04A38000048F8700243C050800F4 +:1066E00094A53D923C0208008C423D8C90E6000D42 +:1066F0000005240030C300201060002C0044402519 +:106700008F85001C00006021240B000190A30085F0 +:1067100000004821240A00013C0F800035EE007083 +:106720008DC70000AF8700308F5801780700FFFE4B +:106730003C038000347900708F3800003C0508006D +:106740008CA500743C0D08008DAD00700307782304 +:1067500000AF38210000102100EF302B01A22021D2 +:10676000008618213C010800AC2700743C01080099 +:10677000AC230070AF4B01483C1908008F393D94A1 +:10678000A7490144A74A0146AF59014C3C0B0800F8 +:10679000916B3D91A34B0152AF4801543C0810004E +:1067A000A74C015803E00008AF4801788F4B0E1C3E +:1067B0003C0A08008D4A3D7497490E16974D0E14F9 +:1067C00001456021312AFFFF0A000E2731A9FFFF92 +:1067D0008F8300249064000D308200201040002937 +:1067E000000000000000482100005021000040216E +:1067F0003C07800034EB00708D670000AF870030ED +:106800008F4C01780580FFFE3C0D800035AC007098 +:106810008D8B00003C0508008CA500743C0408002A +:106820008C8400700167302300A6782100001021BD +:1068300001E6C82B0082C021031970213C01080029 +:10684000AC2F00743C010800AC2E0070AF49014829 +:106850003C0D08008DAD3D94A7480144240900403B +:10686000A74A01463C081000240AFF91AF4D014C95 +:10687000A34A0152AF490154A740015803E0000860 +:10688000AF4801788F490E1897460E1297450E10A3 +:1068900030CAFFFF0A000E5D30A8FFFF8F8300247F +:1068A00027BDFFF89064000D308200201040003AB0 +:1068B00000000000240B000100004821240A000110 +:1068C0003C088000350700708CE30000AF83003087 +:1068D0008F4C01780580FFFE3C0E80003C040800D0 +:1068E00090843DD035C700708CEC00003C0508005A +:1068F0008CA50074A3A400033C1908008F39007014 +:106900008FAD00000183302300A638210000102144 +:106910000322782100E6C02B01F8602101AE40255A +:10692000AFA800003C010800AC2700743C0108003F +:10693000AC2C00709346010A3C04080090843DD1C1 +:10694000A3A00002A3A600018FA300003C0580FFC6 +:106950003099007F34A2FFFF006278240019C6003E +:1069600001F87025240D3000AF4E014C27BD000802 +:10697000AF4D0154A7400158AF4B0148A74901440E +:10698000A74A01463C091000240AFF80A34A01528D +:1069900003E00008AF4901788F4B0E1897460E129E +:1069A00097450E1030CAFFFF0A000E9130A9FFFF75 +:1069B0008F85001C2402008090A40085308300C0D5 +:1069C000106200058F8600208F8800088F87000CDA +:1069D000ACC800C8ACC700C403E000080000000059 +:1069E0003C0A0800254A39543C09080025293A2068 +:1069F0003C08080025082DD43C07080024E73B3458 +:106A00003C06080024C637C43C05080024A5353CD4 +:106A10003C040800248431643C0308002463385C8F +:106A20003C020800244236303C010800AC2A3D50AC +:106A30003C010800AC293D4C3C010800AC283D4815 +:106A40003C010800AC273D543C010800AC263D64E5 +:106A50003C010800AC253D5C3C010800AC243D58DD +:106A60003C010800AC233D683C010800AC223D60BD +:086A700003E000080000000033 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex deleted file mode 100644 index 7f39b4a7f331..000000000000 --- a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex +++ /dev/null @@ -1,6488 +0,0 @@ -:10000000080001180800000000005594000000C816 -:1000100000000000000000000000000008005594EF -:10002000000000380000565C080000A00800000036 -:100030000000574400005694080059200000008436 -:100040000000ADD808005744000001C00000AE5CBD -:100050000800321008000000000090900000B01C62 -:100060000000000000000000000000000800909068 -:100070000000033C000140AC0800049008000400AC -:10008000000012FC000143E8000000000000000036 -:1000900000000000080016FC00000004000156E407 -:1000A000080000A80800000000003D28000156E8F4 -:1000B00000000000000000000000000008003D28D3 -:0800C000000000300001941063 -:0800C8000A00004600000000E0 -:1000D000000000000000000D636F6D362E302E31E1 -:1000E00037000000060011020000000000000003BD -:1000F000000000C800000032000000030000000003 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E0000000000010000003000000000000000DEF -:1001F0000000000D3C020800244256083C030800A1 -:1002000024635754AC4000000043202B1480FFFDB2 -:10021000244200043C1D080037BD9FFC03A0F021D0 -:100220003C100800261001183C1C0800279C5608AA -:100230000E000256000000000000000D27BDFFB4B4 -:10024000AFA10000AFA20004AFA30008AFA4000C50 -:10025000AFA50010AFA60014AFA70018AFA8001CF0 -:10026000AFA90020AFAA0024AFAB0028AFAC002C90 -:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 -:10028000AFB90040AFBC0044AFBF00480E001544FA -:10029000000000008FBF00488FBC00448FB90040B1 -:1002A0008FB8003C8FAF00388FAE00348FAD003078 -:1002B0008FAC002C8FAB00288FAA00248FA90020C0 -:1002C0008FA8001C8FA700188FA600148FA5001000 -:1002D0008FA4000C8FA300088FA200048FA1000040 -:1002E00027BD004C3C1B60108F7A5030377B502864 -:1002F00003400008AF7A00008F82002427BDFFE092 -:10030000AFB00010AFBF0018AFB100148C42000CAA -:100310003C1080008E110100104000348FBF001887 -:100320000E000D84000000008F85002024047FFF54 -:100330000091202BACB100008E030104960201084D -:1003400000031C003042FFFF00621825ACA300042C -:100350009202010A96030114304200FF3063FFFF4E -:100360000002140000431025ACA200089603010C03 -:100370009602010E00031C003042FFFF00621825A8 -:10038000ACA3000C960301109602011200031C009E -:100390003042FFFF00621825ACA300108E02011846 -:1003A000ACA200148E02011CACA20018148000083C -:1003B0008F820024978200003C0420050044182509 -:1003C00024420001ACA3001C0A0000C6A782000062 -:1003D0003C0340189442001E00431025ACA2001CB0 -:1003E0000E000DB8240400018FBF00188FB1001457 -:1003F0008FB000100000102103E0000827BD00208E -:100400003C0780008CE202B834E50100044100089A -:10041000240300013C0208008C42006024420001D9 -:100420003C010800AC22006003E0000800601021DD -:100430003C0208008C42005C8CA4002094A30016AF -:100440008CA6000494A5000E24420001ACE40280B6 -:100450002463FFFC3C010800AC22005C3C0210005D -:10046000A4E30284A4E5028600001821ACE6028819 -:10047000ACE202B803E000080060102127BDFFE0F5 -:100480003C028000AFB0001034420100AFBF001C3E -:10049000AFB20018AFB100148C43000094450008BF -:1004A0002462FE002C42038110400003000381C23D -:1004B0000A00010226100004240201001462000553 -:1004C0003C1180003C02800890420004305000FF44 -:1004D0003C11800036320100964300143202000FB6 -:1004E00000021500004310253C0308008C63004403 -:1004F00030A40004AE220080246300013C01080007 -:10050000AC2300441080000730A200028FBF001C03 -:100510008FB200188FB100148FB000100A0000CE07 -:1005200027BD00201040002D0000182130A20080BF -:1005300010400005362200708E44001C0E000C672F -:10054000240500A0362200708C4400008F82000C2D -:10055000008210232C43012C10600004AF82001095 -:10056000240300010A000145AF84000C8E42000400 -:100570003C036020AF84000CAC6200143C02080015 -:100580008C42005850400015000018218C62000475 -:10059000240301FE304203FF144300100000182121 -:1005A0002E020004104000032E0200080A00014041 -:1005B0000000802114400003000000000A000140F8 -:1005C0002610FFF90000000D2402000202021004B0 -:1005D0003C036000AC626914000018218FBF001C4E -:1005E0008FB200188FB100148FB00010006010217E -:1005F00003E0000827BD00203C0480008C8301003C -:1006000024020100506200033C0280080000000D3B -:100610003C02800890430004000010213063000F6A -:1006200000031D0003E00008AC8300800004188074 -:100630002782FF9C00621821000410C00044102390 -:100640008C640000000210C03C030800246356E4E0 -:10065000004310213C038000AC64009003E00008DC -:10066000AF8200243C0208008C42011410400019A3 -:100670003084400030A2007F000231C03C02020002 -:100680001080001400A218253C026020AC43001426 -:100690003C0408008C8456B83C0308008C630110AD -:1006A0003C02800024050900AC4500200086202182 -:1006B000246300013C028008AC4400643C01080053 -:1006C000AC2301103C010800AC2456B803E000083C -:1006D000000000003C02602003E00008AC4500146C -:1006E00003E000080000102103E0000800001021D2 -:1006F00030A2000810400008240201003C0208005B -:100700008C42010C244200013C010800AC22010C87 -:1007100003E0000800000000148200080000000050 -:100720003C0208008C4200FC244200013C0108000D -:10073000AC2200FC0A0001A330A200203C02080009 -:100740008C420084244200013C010800AC22008459 -:1007500030A200201040000830A200103C02080027 -:100760008C420108244200013C010800AC2201082F -:1007700003E0000800000000104000080000000036 -:100780003C0208008C420104244200013C010800A4 -:10079000AC22010403E00008000000003C02080055 -:1007A0008C420100244200013C010800AC220100FF -:1007B00003E000080000000027BDFFE0AFB1001417 -:1007C0003C118000AFB20018AFBF001CAFB00010EA -:1007D0003632010096500008320200041040000733 -:1007E000320300028FBF001C8FB200188FB10014BB -:1007F0008FB000100A0000CE27BD00201060000B53 -:10080000020028218E2401000E00018A0000000051 -:100810003202008010400003240500A10E000C6786 -:100820008E44001C0A0001E3240200018E2301040F -:100830008F82000810430006020028218E24010048 -:100840000E00018A000000008E220104AF82000821 -:10085000000010218FBF001C8FB200188FB1001450 -:100860008FB0001003E0000827BD00202C82000498 -:1008700014400002000018212483FFFD240200021E -:10088000006210043C03600003E00008AC626914DD -:1008900027BDFFE0AFBF001CAFB20018AFB100141E -:1008A000AFB000103C048000948201083043700017 -:1008B000240220001062000A2862200154400052E5 -:1008C0008FBF001C24024000106200482402600018 -:1008D0001062004A8FBF001C0A0002518FB200183C -:1008E00034820100904300098C5000189451000C90 -:1008F000240200091062001C0000902128620009F7 -:10090000144000218F8200242402000A5062001249 -:10091000323100FF2402000B1062000F00000000C3 -:100920002402000C146200188F8200243C0208008C -:100930008C4256B824030900AC83002000501021DB -:100940003C038008AC6200643C010800AC2256B84D -:100950000A0002508FBF001C0E0001E900102602A1 -:100960000A0002308F8200240E0001E900102602E6 -:100970003C0380089462001A8C72000C3042FFFF26 -:10098000020280258F8200248C42000C5040001E01 -:100990008FBF001C0E000D84000000003C02800090 -:1009A00034420100944300088F82002400031C009D -:1009B0009444001E8F82002000641825AC50000073 -:1009C00024040001AC510004AC520008AC40000CFF -:1009D000AC400010AC400014AC4000180E000DB844 -:1009E000AC43001C0A0002508FBF001C0E000440E4 -:1009F000000000000A0002508FBF001C0E000C9F78 -:100A0000000000008FBF001C8FB200188FB10014CF -:100A10008FB000100000102103E0000827BD002067 -:100A200027BDFFD8AFB400203C036010AFBF002447 -:100A3000AFB3001CAFB20018AFB10014AFB00010DC -:100A40008C6450002402FF7F3C1408002694563822 -:100A5000008220243484380CAC6450003C028000B6 -:100A6000240300370E0014B0AC4300083C07080014 -:100A700024E70618028010212404001D2484FFFFAF -:100A8000AC4700000481FFFD244200043C02080042 -:100A9000244207C83C010800AC2256403C02080032 -:100AA000244202303C030800246306203C04080072 -:100AB000248403B43C05080024A506F03C06080085 -:100AC00024C62C9C3C010800AC2256803C02080045 -:100AD000244205303C010800AC2756843C01080044 -:100AE000AC2656943C010800AC23569C3C010800FF -:100AF000AC2456A03C010800AC2556A43C010800DB -:100B0000AC2256A83C010800AC23563C3C0108002E -:100B1000AC2456443C010800AC2056603C0108005F -:100B2000AC2556643C010800AC2056703C0108001E -:100B3000AC27567C3C010800AC2656903C010800CE -:100B4000AC2356980E00056E00000000AF80000C2C -:100B50003C0280008C5300008F8300043C0208009C -:100B60008C420020106200213262000700008821C0 -:100B70002792FF9C3C100800261056E43C02080017 -:100B80008C42002024050001022518040043202483 -:100B90008F820004004310245044000C26310001D1 -:100BA00010800008AF9000248E4300003C028000BB -:100BB000AC4300900E000D4BAE05000C0A0002C1C4 -:100BC00026310001AE00000C263100012E22000269 -:100BD000261000381440FFE9265200043C020800A9 -:100BE0008C420020AF820004326200071040FFD91F -:100BF0003C028000326200011040002D326200028F -:100C00003C0580008CA2010000002021ACA2002045 -:100C10008CA301042C42078110400008ACA300A85B -:100C200094A2010824032000304270001443000302 -:100C30003C02800890420005304400FF0E0001593C -:100C4000000000003C0280009042010B304300FF96 -:100C50002C62001E54400004000310800E00018628 -:100C60000A0002EC00000000005410218C42000039 -:100C70000040F80900000000104000043C02800021 -:100C80008C4301043C026020AC4300143C02080089 -:100C90008C4200343C0440003C03800024420001AC -:100CA000AC6401383C010800AC220034326200021E -:100CB00010400010326200043C1080008E0201409F -:100CC000000020210E000159AE0200200E00038317 -:100CD000000000003C024000AE0201783C02080027 -:100CE0008C420038244200013C010800AC2200384C -:100CF000326200041040FF973C0280003C108000EC -:100D00008E020180000020210E000159AE02002059 -:100D10008E03018024020F00546200073C02800809 -:100D20008E0201883C0300E03042FFFF00431025A3 -:100D30000A000328AE020080344200809042000086 -:100D400024030050304200FF14430007000000005D -:100D50000E000362000000001440000300000000C9 -:100D60000E000971000000003C0208008C42003CAB -:100D70003C0440003C03800024420001AC6401B804 -:100D80003C010800AC22003C0A0002A33C028000A7 -:100D90003C02900034420001008220253C02800089 -:100DA000AC4400203C0380008C6200200440FFFE25 -:100DB0000000000003E00008000000003C0280008A -:100DC000344300010083202503E00008AC440020E8 -:100DD00027BDFFE0AFB10014AFB000100080882144 -:100DE000AFBF00180E00033230B000FF8F83FF94B6 -:100DF000022020219062002502028025A07000259B -:100E00008C7000183C0280000E00033D020280241A -:100E10001600000B8FBF00183C0480008C8201F884 -:100E20000440FFFE348201C024030002AC510000E4 -:100E3000A04300043C021000AC8201F88FBF0018F0 -:100E40008FB100148FB0001003E0000827BD002010 -:100E500027BDFFE83C028000AFBF00103442018094 -:100E6000944300048C4400083063020010600005C5 -:100E7000000028210E00100C000000000A0003787A -:100E8000240500013C02FF000480000700821824B2 -:100E90003C02040014620004240500018F82FF94C8 -:100EA00090420008240500018FBF001000A010210F -:100EB00003E0000827BD00188F82FF982405000179 -:100EC000A040001A3C028000344201400A00034264 -:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E -:100EE000AFB20018AFB10014AFB0001090A2000074 -:100EF000304400FF38830020388200300003182B74 -:100F00000002102B0062182410600003240200501D -:100F1000148200A88FBF001C90A20005304200017F -:100F2000104000A48FBF001C3C02800034420140EE -:100F3000904200082443FFFF2C6200051040009EF1 -:100F40008FB20018000310803C030800246355ACE6 -:100F5000004310218C420000004000080000000007 -:100F60003C028000345101400E0003328E24000008 -:100F70008F92FF948E2200048E50000C1602000205 -:100F800024020001AE42000C0E00033D8E2400003E -:100F90008E220004145000068FBF001C8FB2001870 -:100FA0008FB100148FB000100A000F7827BD002009 -:100FB0008E42000C0A000419000000003C0480006E -:100FC0003482014094A300108C4200043063FFFF80 -:100FD0001443001C0000000024020001A4A2001021 -:100FE0008C8202380441000F3C0380003C02003F29 -:100FF0003448F0003C0760003C06FFC08CE22BBC8C -:1010000000461824004810240002130200031D8229 -:10101000106200583C0280008C8202380440FFF7C6 -:101020003C038000346201408C44000034620200C2 -:10103000AC4400003C021000AC6202380A00043BE1 -:101040008FBF001C94A200100A00041900000000C9 -:10105000240200201482000F3C0280003C03800028 -:1010600094A20012346301408C6300043042FFFFFD -:10107000146200050000000024020001A4A2001276 -:101080000A0004028FBF001C94A200120A00041977 -:1010900000000000345101400E0003328E24000095 -:1010A0008F92FF948E230004964200123050FFFF6F -:1010B0001603000224020001A64200120E00033DA6 -:1010C0008E2400008E220004160200068FBF001C32 -:1010D0008FB200188FB100148FB000100A00037C8B -:1010E00027BD0020964200120A00041900000000EB -:1010F0003C03800094A20014346301408C6300041C -:101100003042FFFF14620008240200018FBF001C60 -:101110008FB200188FB100148FB00010A4A2001479 -:101120000A00146327BD002094A20014144000217B -:101130008FBF001C0A000435000000003C03800043 -:1011400094A20016346301408C6300043042FFFF18 -:101150001462000D240200018FBF001C8FB2001822 -:101160008FB100148FB00010A4A200160A000B1457 -:1011700027BD00209442007824420004A4A200105D -:101180000A00043B8FBF001C94A200162403000138 -:101190003042FFFF144300078FBF001C3C020800D1 -:1011A0008C420070244200013C010800AC22007017 -:1011B0008FBF001C8FB200188FB100148FB00010C9 -:1011C00003E0000827BD002027BDFFD8AFB20018FC -:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB -:1011E000AFB000103C028000345101008C5001006F -:1011F0009242000092230009304400FF2402001FA5 -:10120000106200AB28620020104000192402003850 -:101210002862000A1040000D2402000B286200081A -:101220001040002E8F820024046001042862000216 -:101230001440002A8F820024240200061062002637 -:101240008FBF00200A00055F8FB3001C1062006092 -:101250002862000B144000FA8FBF00202402000E09 -:10126000106200788F8200240A00055F8FB3001C93 -:10127000106200D2286200391040000A2402008067 -:1012800024020036106200E528620037104000C3D7 -:1012900024020035106200D98FBF00200A00055FCC -:1012A0008FB3001C1062002D2862008110400006E0 -:1012B000240200C824020039106200C98FBF002038 -:1012C0000A00055F8FB3001C106200A28FBF0020D0 -:1012D0000A00055F8FB3001C8F8200248C42000C33 -:1012E000104000D78FBF00200E000D8400000000CA -:1012F0003C038000346301008C6200008F85002075 -:10130000946700089466000CACA200008C64000492 -:101310008F82002400063400ACA400049448001E10 -:101320008C62001800073C0000E83825ACA20008D9 -:101330008C62001C24040001ACA2000C9062000A24 -:1013400000C23025ACA60010ACA00014ACA0001860 -:10135000ACA7001C0A00051D8FBF00208F8200244F -:101360008C42000C104000B68FBF00200E000D8490 -:10137000000000008F820024962400089625000CAF -:101380009443001E000422029626000E8F82002045 -:10139000000426000083202500052C003C0300806B -:1013A00000A6282500832025AC400000AC400004A6 -:1013B000AC400008AC40000CAC450010AC40001440 -:1013C000AC400018AC44001C0A00051C24040001B9 -:1013D0009622000C14400018000000009242000504 -:1013E0003042001014400014000000000E000332D0 -:1013F0000200202192420005020020213442001008 -:101400000E00033DA242000592420000240300208A -:10141000304200FF10430089020020218FBF0020CE -:101420008FB3001C8FB200188FB100148FB0001062 -:101430000A00107527BD00280000000D0A00055E97 -:101440008FBF00208C42000C1040007D8FBF002019 -:101450000E000D84000000008E2200048F84002006 -:101460009623000CAC8200003C0280089445002CBE -:101470008F82002400031C0030A5FFFF9446001E4D -:101480003C02400E0065182500C23025AC830004E4 -:10149000AC800008AC80000CAC800010AC80001464 -:1014A000AC800018AC86001C0A00051C2404000156 -:1014B0000E000332020020218F93FF9802002021AA -:1014C0000E00033DA660000C020020210E00034226 -:1014D000240500018F8200248C42000C104000582B -:1014E0008FBF00200E000D84000000009622000C2B -:1014F0008F83002000021400AC700000AC62000476 -:10150000AC6000088E4400388F820024AC64000C6C -:101510008E46003C9445001E3C02401FAC66001005 -:1015200000A228258E62000424040001AC6200148D -:10153000AC600018AC65001C8FBF00208FB3001C8E -:101540008FB200188FB100148FB000100A000DB8D0 -:1015500027BD0028240200201082003A8FB3001C0F -:101560000E000F5E00000000104000358FBF00200D -:101570003C0480008C8201F80440FFFE348201C0EC -:1015800024030002AC500000A04300043C02100001 -:10159000AC8201F80A00055E8FBF00200200202106 -:1015A0008FBF00208FB3001C8FB200188FB10014C2 -:1015B0008FB000100A000EA727BD00289625000C4A -:1015C000020020218FBF00208FB3001C8FB20018B3 -:1015D0008FB100148FB000100A000ECC27BD002878 -:1015E000020020218FB3001C8FB200188FB10014AD -:1015F0008FB000100A000EF727BD00289225000DBD -:10160000020020218FB3001C8FB200188FB100148C -:101610008FB000100A000F4827BD002802002021CB -:101620008FBF00208FB3001C8FB200188FB1001441 -:101630008FB000100A000F1F27BD00288FBF0020A9 -:101640008FB3001C8FB200188FB100148FB0001040 -:1016500003E0000827BD00283C0580008CA202782A -:101660000440FFFE34A2024024030002AC44000008 -:10167000A04300043C02100003E00008ACA2027882 -:10168000A380001803E00008A38000193C03800039 -:101690008C6202780440FFFE8F82001CAC62024024 -:1016A00024020002A06202443C02100003E0000891 -:1016B000AC6202783C02600003E000088C425404F3 -:1016C0009083003024020005008040213063003FF9 -:1016D0000000482114620005000050219082004C57 -:1016E0009483004E304900FF306AFFFFAD00000CCC -:1016F000AD000010AD000024950200148D05001C03 -:101700008D0400183042FFFF004910230002110031 -:10171000000237C3004038210086202300A2102B8E -:101720000082202300A72823AD05001CAD0400186B -:10173000A5090014A5090020A50A001603E0000869 -:10174000A50A002203E000080000000027BDFFD822 -:10175000AFB200183C128008AFB40020AFB3001C39 -:10176000AFB10014AFBF0024AFB00010365101007C -:101770003C0260008C4254049222000C3C1408008D -:10178000929400F7304300FF2402000110620032FF -:101790000080982124020002146200353650008037 -:1017A0000E00143D000000009202004C2403FF8054 -:1017B0003C0480003042007F000211C024420240FD -:1017C0000262102100431824AC8300949245000863 -:1017D0009204004C3042007F3C03800614850007D1 -:1017E000004380212402FFFFA22200112402FFFFF8 -:1017F000A62200120A0005D22402FFFF9602002052 -:10180000A222001196020022A62200128E020024BB -:101810003C048008AE2200143485008090A2004C65 -:1018200034830100A06200108CA2003CAC6200185E -:101830008C820068AC6200F48C820064AC6200F0C0 -:101840008C82006CAC6200F824020001A0A2006847 -:101850000A0005EE3C0480080E001456000000004B -:1018600036420080A04000680A0005EE3C04800873 -:10187000A2000068A20000690A0006293C02800854 -:10188000348300808C62003834850100AC62006CC7 -:1018900024020001A062006990A200D59083000894 -:1018A000305100FF3072007F12320019001111C058 -:1018B00024420240026210212403FF8000431824C6 -:1018C0003C048000AC8300943042007F3C038006DF -:1018D000004380218E02000C1040000D02002021E8 -:1018E0000E00057E0000000026220001305100FF9E -:1018F0009203003C023410260002102B0002102339 -:101900003063007F022288240A0005F8A203003C0D -:101910003C088008350401008C8200E03507008017 -:10192000ACE2003C8C8200E0AD02000090E5004C8F -:10193000908600D590E3004C908400D52402FF806F -:1019400000A228243063007F308400FF00A62825F1 -:101950000064182A1060000230A500FF38A500803E -:10196000A0E5004CA10500093C0280089043000E50 -:10197000344400803C058000A043000A8C8300189A -:101980003C027FFF3442FFFF00621824AC83001842 -:101990008CA201F80440FFFE00000000ACB301C0BF -:1019A0008FBF00248FB400208FB3001C8FB20018AB -:1019B0008FB100148FB0001024020002A0A201C455 -:1019C00027BD00283C02100003E00008ACA201F88B -:1019D00090A2000024420001A0A200003C030800E5 -:1019E0008C6300F4304200FF144300020080302179 -:1019F000A0A0000090A200008F84001C000211C073 -:101A00002442024024830040008220212402FF80DF -:101A1000008220243063007F3C02800A006218218B -:101A20003C028000AC44002403E00008ACC300008A -:101A300094820006908300058C85000C8C86001033 -:101A40008C8700188C88001C8C8400203C010800C6 -:101A5000A42256C63C010800A02356C53C0108003C -:101A6000AC2556CC3C010800AC2656D03C01080001 -:101A7000AC2756D83C010800AC2856DC3C010800D5 -:101A8000AC2456E003E00008000000003C0280089F -:101A9000344201008C4400343C038000346504006F -:101AA000AC6400388C420038AF850028AC62003C42 -:101AB0003C020005AC6200300000000000000000A5 -:101AC00003E00008000000003C020006308400FF34 -:101AD000008220253C028000AC4400300000000061 -:101AE00000000000000000003C0380008C62000049 -:101AF000304200101040FFFD3462040003E0000893 -:101B0000AF82002894C200003C080800950800CA73 -:101B100030E7FFFF0080482101021021A4C200002D -:101B200094C200003042FFFF00E2102B544000013D -:101B3000A4C7000094A200003C0308008C6300CC02 -:101B400024420001A4A2000094A200003042FFFF42 -:101B5000144300073C0280080107102BA4A00000DA -:101B60005440000101003821A4C700003C02800855 -:101B7000344601008CC3002894A200003C0480007D -:101B80003042FFFE000210C000621021AC82003C17 -:101B90008C82003C006218231860000400000000E2 -:101BA0008CC200240A0006BA244200018CC2002420 -:101BB000AC8200383C020050344200103C038000EC -:101BC000AC620030000000000000000000000000D7 -:101BD0008C620000304200201040FFFD0000000039 -:101BE00094A200003C04800030420001000210C0BA -:101BF000004410218C430400AD2300008C420404F7 -:101C0000AD2200043C02002003E00008AC8200305A -:101C100027BDFFE0AFB20018AFB10014AFB00010A5 -:101C2000AFBF001C94C2000000C080213C1208001D -:101C3000965200C624420001A6020000960300004E -:101C400094E2000000E03021144300058FB1003021 -:101C50000E00068F024038210A0006F10000000045 -:101C60008C8300048C82000424420040046100073D -:101C7000AC8200048C8200040440000400000000D8 -:101C80008C82000024420001AC8200009602000019 -:101C90003042FFFF50520001A600000096220000D3 -:101CA00024420001A62200003C02800834420100C8 -:101CB000962300009442003C144300048FBF001C94 -:101CC00024020001A62200008FBF001C8FB2001862 -:101CD0008FB100148FB0001003E0000827BD002072 -:101CE00027BDFFE03C028008AFBF0018344201006E -:101CF0008C4800343C03800034690400AC68003830 -:101D00008C42003830E700FFAF890028AC62003C0D -:101D10003C020005AC620030000000000000000042 -:101D200000000000000000000000000000000000B3 -:101D30008C82000C8C82000C97830016AD22000070 -:101D40008C82001000604021AD2200048C820018BB -:101D5000AD2200088C82001CAD22000C8CA2001465 -:101D6000AD2200108C820020AD220014908200056C -:101D7000304200FF00021200AD2200188CA20018B1 -:101D8000AD22001C8CA2000CAD2200208CA2001001 -:101D9000AD2200248CA2001CAD2200288CA20020C1 -:101DA000AD22002C3402FFFFAD260030AD20003400 -:101DB000506200013408FFFFAD28003850E00011E8 -:101DC0003C0280083C048008348401009482005066 -:101DD0003042FFFFAD22003C9483004494850044D0 -:101DE000240200013063FFFF000318C200641821C1 -:101DF0009064006430A5000700A210040A00075C8C -:101E00000044102534420100AD20003C94430044BE -:101E1000944400443063FFFF000318C2006218219D -:101E200030840007906500642402000100821004E1 -:101E30000002102700451024A0620064000000008A -:101E400000000000000000003C0200063442004098 -:101E50003C038000AC620030000000000000000085 -:101E6000000000008C620000304200101040FFFDB6 -:101E70003C06800834C201503463040034C7014A70 -:101E800034C4013434C5014034C60144AFA200104B -:101E90000E0006D2AF8300288FBF001803E00008B1 -:101EA00027BD00208F8300143C0608008CC600E884 -:101EB0008F82001C30633FFF000319800046102111 -:101EC000004310212403FF80004318243C068000B7 -:101ED000ACC300283042007F3C03800C004330211B -:101EE00090C2000D30A500FF0000382134420010E0 -:101EF000A0C2000D8F8900143C028008344201000A -:101F00009443004400091382304800032402000176 -:101F1000A4C3000E1102000B2902000210400005AC -:101F2000240200021100000C240300010A0007A48F -:101F30000000182111020006000000000A0007A49A -:101F4000000018218CC2002C0A0007A424430001C1 -:101F50008CC20014244300018CC200180043102BD3 -:101F60005040000A240700012402002714A20003A5 -:101F70003C0380080A0007B1240700013463010014 -:101F80009462004C24420001A462004C00091382B8 -:101F9000304300032C620002104000090080282119 -:101FA000146000040000000094C200340A0007C15D -:101FB0003046FFFF8CC600380A0007C10080282188 -:101FC000000030213C040800248456C00A000706A3 -:101FD0000000000027BDFF90AFB60068AFB50064F9 -:101FE000AFB40060AFB3005CAFB20058AFB1005403 -:101FF000AFBF006CAFB000508C9000000080B021EB -:102000003C0208008C4200E8960400328F83001CDA -:102010002414FF8030843FFF0062182100042180D7 -:1020200000641821007410243C13800000A090214B -:1020300090A50000AE620028920400323C02800CA1 -:102040003063007F00628821308400C02402004099 -:10205000148200320000A8218E3500388E2200182C -:102060001440000224020001AE2200189202003C3B -:10207000304200201440000E8F83001C000511C068 -:102080002442024000621821306400783C02008043 -:102090000082202500741824AE630800AE64081086 -:1020A0008E2200188E03000800431021AE22001873 -:1020B0008E22002C8E230018244200010062182B6F -:1020C0001060004300000000924200002442000122 -:1020D000A24200003C0308008C6300F4304200FF81 -:1020E00050430001A2400000924200008F84001C77 -:1020F000000211C024420240248300403063007F6C -:10210000008220213C02800A0094202400621821D1 -:10211000AE6400240A0008D2AEC30000920300326D -:102120002402FFC000431024304200FF1440000589 -:1021300024020001AE220018962200340A00084250 -:102140003055FFFF8E22001424420001AE220018F9 -:102150009202003000021600000216030441001C27 -:10216000000000009602003227A400100080282101 -:10217000A7A20016960200320000302124070001B9 -:102180003042FFFFAF8200140E000706AFA0001C14 -:10219000960200328F83001C3C0408008C8400E807 -:1021A00030423FFF000211800064182100621821B4 -:1021B00000741024AE62002C3063007F3C02800E5D -:1021C000006218219062000D3042007FA062000D75 -:1021D0009222000D304200105040007892420000E0 -:1021E0003C028008344401009482004C8EC30000FD -:1021F0003C130800967300C62442FFFFA482004CE3 -:10220000946200329623000E3054FFFF3070FFFFBF -:102210003C0308008C6300D000701807A7A30038A7 -:102220009482003E3063FFFF3042FFFF14620007DC -:10223000000000008C8200303C038000244200300B -:10224000AC62003C0A00086A8C82002C9482004038 -:102250003042FFFF5462000927A400408C820038FE -:102260003C03800024420030AC62003C8C8200348D -:10227000AC6200380A0008793C03800027A50038CA -:1022800027A60048026038210E00068FA7A000484C -:102290008FA300403C02800024630030AC43003830 -:1022A0008FA30044AC43003C3C0380003C0200058B -:1022B000AC6200303C028008344401009482004249 -:1022C000346304003042FFFF0202102B1440000769 -:1022D000AF8300289482004E9483004202021021B2 -:1022E000004310230A00088F3043FFFF9483004E01 -:1022F00094820042026318210050102300621823C8 -:102300003063FFFF3C028008344401009482003CAB -:102310003042FFFF14430003000000000A00089F42 -:10232000240300019482003C3042FFFF0062102B26 -:10233000144000058F8200289482003C0062102324 -:102340003043FFFF8F820028AC550000AC400004F2 -:10235000AC540008AC43000C3C02000634420010B0 -:102360003C038000AC620030000000000000000070 -:10237000000000008C620000304200101040FFFDA1 -:102380003C04800834840100001018C20064182145 -:102390009065006432020007240600010046100424 -:1023A00000451025A0620064948300429622000E2E -:1023B00050430001A386001892420000244200010D -:1023C000A24200003C0308008C6300F4304200FF8E -:1023D00050430001A2400000924200008F84001C84 -:1023E000000211C0244202402483004000822021C8 -:1023F0002402FF80008220243063007F3C02800A98 -:10240000006218213C028000AC440024AEC30000EE -:102410008FBF006C8FB600688FB500648FB400600A -:102420008FB3005C8FB200588FB100548FB0005052 -:1024300003E0000827BD007027BDFFD8AFB3001C24 -:10244000AFB20018AFB10014AFB00010AFBF0020A2 -:102450000080982100E0802130B1FFFF0E000D8444 -:1024600030D200FF0000000000000000000000006B -:102470008F8200208F830024AC510000AC520004F6 -:10248000AC530008AC40000CAC400010AC40001451 -:10249000AC4000189463001E02038025AC50001C61 -:1024A0000000000000000000000000002404000103 -:1024B0008FBF00208FB3001C8FB200188FB10014A3 -:1024C0008FB000100A000DB827BD002830A5FFFF0F -:1024D0000A0008DC30C600FF3C02800834430100DB -:1024E0009462000E3C080800950800C63046FFFFC5 -:1024F00014C000043402FFFF946500EA0A000929B1 -:102500008F84001C10C20027000000009462004E5F -:102510009464003C3045FFFF00A6102300A6182B52 -:102520003087FFFF106000043044FFFF00C5102318 -:1025300000E210233044FFFF0088102B1040000EF3 -:1025400000E810233C028008344401002403000109 -:1025500034420080A44300162402FFFFA482000E30 -:10256000948500EA8F84001C0000302130A5FFFF15 -:102570000A0009013C0760200044102A10400009AD -:102580003C0280083443008094620016304200010F -:10259000104000043C0280009442007E244200145B -:1025A000A462001603E000080000000027BDFFE061 -:1025B0003C028008AFBF001CAFB0001834420100DD -:1025C000944300429442004C104000193068FFFFD1 -:1025D0009383001824020001146200298FBF001C9D -:1025E0003C06800834D00100000810C200501021C1 -:1025F000904200643103000734C70148304200FFB5 -:10260000006210073042000134C9014E34C4012C6D -:1026100034C5013E1040001634C601420E0006D2F9 -:10262000AFA90010960200420A0009463048FFFF99 -:102630003C028008344401009483004494820042A8 -:102640001043000F8FBF001C94820044A4820042FC -:1026500094820050A482004E8C820038AC820030FC -:1026600094820040A482003E9482004AA4820048E2 -:102670008FBF001C8FB000180A00090427BD00207E -:102680008FB0001803E0000827BD002027BDFFA081 -:10269000AFB1004C3C118000AFBF0058AFB3005445 -:1026A000AFB20050AFB000483626018890C2000398 -:1026B0003044007FA3A400108E32018090C200003D -:1026C0003043007F240200031062003BAF92001CE5 -:1026D00028620004104000062402000424020002C4 -:1026E000106200098FBF00580A000B0F8FB300540F -:1026F0001062004D240200051062014E8FBF005889 -:102700000A000B0F8FB30054000411C002421021C5 -:102710002404FF8024420240004410242643004049 -:10272000AE2200243063007F3C02800A0062182140 -:102730009062003CAFA3003C00441025A062003C26 -:102740008FA3003C9062003C304200401040016C7E -:102750008FBF00583C108008A3800018361001007D -:102760008E0200E08C63003427A4003C27A50010F3 -:10277000004310210E0007C3AE0200E093A2001038 -:102780003C038000A20200D58C6202780440FFFE68 -:102790008F82001CAC62024024020002A06202444C -:1027A0003C021000AC6202780E0009390000000003 -:1027B0000A000B0E8FBF00583C05800890C3000133 -:1027C00090A2000B1443014E8FBF005834A4008028 -:1027D0008C8200189082004C90A200083C0260009D -:1027E0008C4254048C8300183C027FFF3442FFFF6C -:1027F000006218243C0208008C4200B4AC8300182C -:102800003C038000244200013C010800AC2200B4DB -:102810008C6201F80440FFFE8F82001CAC6201C094 -:102820000A000AD6240200023C10800890C300016E -:102830009202000B144301328FBF005827A40018E6 -:1028400036050110240600033C0260008C4254044B -:102850000E000E470000000027A40028360501F0F6 -:102860000E000E47240600038FA200283603010045 -:10287000AE0200648FA2002CAE0200688FA200306E -:10288000AE02006C93A40018906300D52402FF8070 -:102890000082102400431025304900FF3084007F5F -:1028A0003122007F0082102A544000013929008023 -:1028B000000411C0244202402403FF800242102180 -:1028C00000431024AE220094264200403042007F94 -:1028D0003C038006004340218FA3001C2402FFFF1D -:1028E000AFA800403C130800927300F71062003359 -:1028F00093A2001995030014304400FF3063FFFFDA -:102900000064182B106000100000000095040014F3 -:102910008D07001C8D0600183084FFFF0044202323 -:102920000004210000E438210000102100E4202BE5 -:1029300000C2302100C43021AD07001CAD060018D4 -:102940000A000A2F93A20019950400148D07001C99 -:102950008D0600183084FFFF008220230004210030 -:10296000000010210080182100C2302300E4202B39 -:1029700000C4302300E33823AD07001CAD06001867 -:1029800093A200198FA30040A462001497A2001A1A -:10299000A46200168FA2001CAC6200108FA2001C63 -:1029A000AC62000C93A20019A462002097A2001A46 -:1029B000A46200228FA2001CAC6200243C048008A8 -:1029C000348300808C6200388FA20020012088218F -:1029D000AC62003C8FA20020AC82000093A20018E1 -:1029E000A062004C93A20018A0820009A0600068B9 -:1029F00093A20018105100512407FF803229007F54 -:102A0000000911C024420240024210213046007FDA -:102A10003C03800000471024AC6200943C02800616 -:102A200000C2302190C2003CAFA60040000020212F -:102A300000471025A0C2003C8FA80040950200026C -:102A4000950300148D07001C3042FFFF3063FFFF29 -:102A50008D060018004310230002110000E2382107 -:102A600000E2102B00C4302100C23021AD07001C51 -:102A7000AD06001895020002A5020014A50000167C -:102A80008D020008AD0200108D020008AD02000C9E -:102A900095020002A5020020A50000228D02000878 -:102AA000AD0200249102003C304200401040001A68 -:102AB000262200013C108008A3A90038A38000183A -:102AC000361001008E0200E08D03003427A4004080 -:102AD00027A50038004310210E0007C3AE0200E016 -:102AE00093A200383C038000A20200D58C620278D9 -:102AF0000440FFFE8F82001CAC62024024020002F0 -:102B0000A06202443C021000AC6202780E00093957 -:102B100000000000262200013043007F14730004EF -:102B2000004020212403FF8002231024004320269C -:102B300093A200180A000A4B309100FF93A40018DA -:102B40008FA3001C2402FFFF1062000A308900FFDF -:102B500024820001248300013042007F14530005C9 -:102B6000306900FF2403FF800083102400431026F7 -:102B7000304900FF3C028008904200080120882173 -:102B8000305000FF123000193222007F000211C0C5 -:102B900002421021244202402403FF8000431824F3 -:102BA0003C048000AC8300943042007F3C038006EC -:102BB000004310218C43000C004020211060000BCA -:102BC000AFA200400E00057E000000002623000199 -:102BD0002405FF803062007F145300020225202468 -:102BE000008518260A000AAF307100FF3C048008F7 -:102BF000348400808C8300183C027FFF3442FFFF46 -:102C000000621824AC8300183C0380008C6201F839 -:102C10000440FFFE00000000AC7201C0240200026C -:102C2000A06201C43C021000AC6201F80A000B0E65 -:102C30008FBF00583C04800890C300019082000BB5 -:102C40001443002F8FBF0058349000809202000878 -:102C500030420040104000200000000092020008B6 -:102C60000002160000021603044100050240202164 -:102C70000E000ECC240500930A000B0E8FBF0058E7 -:102C80009202000924030018304200FF1443000D93 -:102C900002402021240500390E000E64000030217E -:102CA0000E0003328F84001C8F82FF9424030012D5 -:102CB000A04300090E00033D8F84001C0A000B0E88 -:102CC0008FBF0058240500360E000E64000030212E -:102CD0000A000B0E8FBF00580E0003320240202165 -:102CE000920200058F84001C344200200E00033D38 -:102CF000A20200050E0010758F84001C8FBF0058C3 -:102D00008FB300548FB200508FB1004C8FB0004889 -:102D100003E0000827BD00603C0280083445010044 -:102D20003C0280008C42014094A3000E0000302140 -:102D300000402021AF82001C3063FFFF3402FFFF00 -:102D4000106200063C0760202402FFFFA4A2000ED0 -:102D500094A500EA0A00090130A5FFFF03E000087E -:102D60000000000027BDFFC83C0280003C06800830 -:102D7000AFB5002CAFB1001CAFBF0030AFB400281E -:102D8000AFB30024AFB20020AFB00018345101003F -:102D900034C501008C4301008E2200148CA400E491 -:102DA0000000A821AF83001C0044102318400052EB -:102DB000A38000188E22001400005021ACA200E471 -:102DC00090C3000890A200D53073007FA3A200102A -:102DD0008CB200E08CB400E4304200FF1053003BA2 -:102DE00093A200108F83001C2407FF80000211C0F3 -:102DF0000062102124420240246300400047102456 -:102E00003063007F3C0980003C08800A006818217C -:102E1000AD2200248C62003427A4001427A50010E2 -:102E2000024280210290102304400028AFA3001426 -:102E30009062003C00E21024304200FF1440001970 -:102E4000020090219062003C34420040A062003CAD -:102E50008F86001C93A3001024C200403042007FE4 -:102E6000004828213C0208008C4200F42463000141 -:102E7000306400FF14820002A3A30010A3A000107E -:102E800093A20010AFA50014000211C0244202401A -:102E900000C2102100471024AD2200240A000B4577 -:102EA00093A200100E0007C3000000003C0280083F -:102EB00034420100AC5000E093A30010240A00014A -:102EC000A04300D50A000B4593A200102402000184 -:102ED000154200093C0380008C6202780440FFFE2A -:102EE0008F82001CAC62024024020002A0620244F5 -:102EF0003C021000AC6202789222000B2403000214 -:102F0000304200FF144300720000000096220008C7 -:102F1000304300FF24020082146200402402008437 -:102F20003C028000344901008D22000C95230006EC -:102F3000000216023063FFFF3045003F24020027E5 -:102F400010A2000FAF83001428A200281040000830 -:102F5000240200312402002110A2000924020025CD -:102F600010A20007938200190A000BBD00000000A8 -:102F700010A20007938200190A000BBD0000000098 -:102F80000E000777012020210A000C3D0000000000 -:102F90003C0380008C6202780440FFFE8F82001C9C -:102FA000AC62024024020002A06202443C02100013 -:102FB000AC6202780A000C3D000000009523000678 -:102FC000912400058D25000C8D2600108D270018FA -:102FD0008D28001C8D290020244200013C0108009E -:102FE000A42356C63C010800A02456C53C01080095 -:102FF000AC2556CC3C010800AC2656D03C0108005C -:10300000AC2756D83C010800AC2856DC3C0108002F -:10301000AC2956E00A000C3DA38200191462000A94 -:10302000240200813C02800834420100944500EAF9 -:10303000922600058F84001C30A5FFFF30C600FFDC -:103040000A000BFE3C0760211462005C00000000D7 -:103050009222000A304300FF306200201040000737 -:10306000306200403C02800834420100944500EA8E -:103070008F84001C0A000BFC24060040104000074F -:10308000000316003C02800834420100944500EA27 -:103090008F84001C0A000BFC24060041000216036A -:1030A000044100463C02800834420100944500EA95 -:1030B0008F84001C2406004230A5FFFF3C076019E6 -:1030C0000E000901000000000A000C3D0000000095 -:1030D0009222000B24040016304200FF1044000628 -:1030E0003C0680009222000B24030017304200FFB0 -:1030F000144300320000000034C5010090A2000B10 -:10310000304200FF1444000B000080218CA20020FC -:103110008CA400202403FF800043102400021140EF -:103120003084007F004410253C032000004310251C -:10313000ACC2083094A2000800021400000214037C -:10314000044200012410000194A2000830420080D3 -:103150005040001A0200A82194A20008304220002A -:10316000504000160200A8218CA300183C021C2D20 -:10317000344219ED106200110200A8213C0208003F -:103180008C4200D4104000053C0280082403000457 -:1031900034420100A04300FC3C028008344201009C -:1031A000944500EA8F84001C2406000630A5FFFF2A -:1031B0000E0009013C0760210200A8210E00093918 -:1031C000000000009222000A304200081040000473 -:1031D00002A010210E0013790000000002A01021AF -:1031E0008FBF00308FB5002C8FB400288FB3002420 -:1031F0008FB200208FB1001C8FB0001803E00008D0 -:1032000027BD00382402FF80008220243C02900069 -:1032100034420007008220253C028000AC4400209C -:103220003C0380008C6200200440FFFE0000000090 -:1032300003E00008000000003C0380002402FF803F -:10324000008220243462000700822025AC64002024 -:103250008C6200200440FFFE0000000003E0000834 -:103260000000000027BDFFD8AFB3001CAFB10014B1 -:10327000AFB00010AFBF0020AFB200183C1180000B -:103280003C0280088E32002034530100AE2400201E -:10329000966300EA000514003C074000004738250B -:1032A00000A08021000030210E0009013065FFFFE1 -:1032B000240200A1160200022402FFFFA2620009FC -:1032C000AE3200208FBF00208FB3001C8FB20018D9 -:1032D0008FB100148FB0001003E0000827BD002854 -:1032E0003C0280082403000527BDFFE834420100AA -:1032F000A04300FCAFBF00103C0280008C420100E4 -:10330000240500A1004020210E000C67AF82001CA4 -:103310003C0380008C6202780440FFFE8F82001C18 -:103320008FBF001027BD0018AC62024024020002CB -:10333000A06202443C021000AC62027803E0000884 -:103340000000000027BDFFE83C068000AFBF001072 -:1033500034C7010094E20008304400FF3883008243 -:10336000388200842C6300012C4200010062182581 -:103370001060002D24020083938200195040003B0E -:103380008FBF00103C020800904256CC8CC4010054 -:103390003C06080094C656C63045003F38A30032AC -:1033A00038A2003F2C6300012C4200010062182566 -:1033B000AF84001CAF860014A380001914600007BE -:1033C00000E020212402002014A2001200000000CE -:1033D0003402FFFF14C2000F00000000240200208E -:1033E00014A2000500E028218CE300142402FFFF52 -:1033F0005062000B8FBF00103C040800248456C0AC -:10340000000030210E000706240700010A000CD638 -:103410008FBF00100E000777000000008FBF001064 -:103420000A00093927BD001814820004240200850F -:103430008CC501040A000CE1000020211482000662 -:103440002482FF808CC50104240440008FBF00103B -:103450000A00016727BD0018304200FF2C4200021D -:1034600010400004240200228FBF00100A000B2726 -:1034700027BD0018148200048F8200248FBF001023 -:103480000A000C8627BD00188C42000C1040001E5C -:1034900000E0282190E300092402001814620003D0 -:1034A000240200160A000CFC240300081462000722 -:1034B00024020017240300123C02800834420080DA -:1034C000A04300090A000D0994A7000854620007F0 -:1034D00094A700088F82FF942404FFFE9043000508 -:1034E00000641824A043000594A7000890A6001BC0 -:1034F0008CA4000094A500068FBF001000073C00BC -:103500000A0008DC27BD00188FBF001003E0000888 -:1035100027BD00188F8500243C04800094A2002A57 -:103520008CA30034000230C02402FFF000C210243B -:1035300000621821AC83003C8CA200303C03800068 -:10354000AC8200383C02005034420010AC620030C3 -:103550000000000000000000000000008C6200007D -:10356000304200201040FFFD30C20008104000062D -:103570003C0280008C620408ACA200208C62040C27 -:103580000A000D34ACA200248C430400ACA300203C -:103590008C420404ACA200243C0300203C028000C6 -:1035A000AC4300303C0480008C8200300043102487 -:1035B0001440FFFD8F8600243C020040AC820030A6 -:1035C00094C3002A94C2002894C4002C94C5002EF1 -:1035D00024630001004410213064FFFFA4C20028CE -:1035E00014850002A4C3002AA4C0002A03E0000836 -:1035F000000000008F84002427BDFFE83C05800404 -:1036000024840010AFBF00100E000E472406000AED -:103610008F840024948200129483002E3042000F85 -:10362000244200030043180424027FFF0043102BB0 -:1036300010400002AC8300000000000D0E000D13CE -:10364000000000008F8300248FBF001027BD0018EA -:10365000946200149463001A3042000F00021500B7 -:10366000006218253C02800003E00008AC4300A083 -:103670008F8300243C028004944400069462001A64 -:103680008C650000A4640016004410233042FFFF44 -:103690000045102B03E00008384200018F8400240D -:1036A0003C0780049486001A8C85000094E2000692 -:1036B000A482001694E3000600C310233042FFFFEB -:1036C0000045102B384200011440FFF8A483001677 -:1036D00003E00008000000008F8400243C02800406 -:1036E000944200069483001A8C850000A482001680 -:1036F000006210233042FFFF0045102B38420001CA -:103700005040000D8F850024006030213C0780046C -:1037100094E20006A482001694E3000600C310237E -:103720003042FFFF0045102B384200011440FFF8E3 -:10373000A48300168F8500243C03800034620400BB -:103740008CA40020AF820020AC6400388CA200243E -:10375000AC62003C3C020005AC62003003E00008B3 -:10376000ACA000048F8400243C0300068C8200047B -:1037700000021140004310253C038000AC62003081 -:103780000000000000000000000000008C6200004B -:10379000304200101040FFFD34620400AC80000491 -:1037A00003E00008AF8200208F86002427BDFFE0E1 -:1037B000AFB10014AFB00010AFBF00188CC300044D -:1037C0008CC500248F820020309000FF94C4001A22 -:1037D00024630001244200202484000124A7002047 -:1037E000ACC30004AF820020A4C4001AACC70024FC -:1037F00004A100060000882104E2000594C2001A1A -:103800008CC2002024420001ACC2002094C2001AE5 -:1038100094C300282E040001004310262C4200010E -:10382000004410245040000594C2001A24020001F4 -:10383000ACC2000894C2001A94C300280010202BC8 -:10384000004310262C4200010044102514400007BC -:10385000000000008CC20008144000042402001084 -:103860008CC300041462000F8F8500240E000DA786 -:10387000241100018F820024944300289442001AEE -:1038800014430003000000000E000D1300000000B0 -:10389000160000048F8500240E000D840000000037 -:1038A0008F85002494A2001E94A4001C24420001D1 -:1038B0003043FFFF14640002A4A2001EA4A0001E57 -:1038C0001200000A3C02800494A2001494A3001A7F -:1038D0003042000F00021500006218253C028000F3 -:1038E000AC4300A00A000E1EACA0000894420006E3 -:1038F00094A3001A8CA40000A4A200160062102356 -:103900003042FFFF0044102B384200011040000DF0 -:1039100002201021006030213C07800494E2000660 -:10392000A4A2001694E3000600C310233042FFFF58 -:103930000044102B384200011440FFF8A4A30016E5 -:10394000022010218FBF00188FB100148FB000101B -:1039500003E0000827BD002003E00008000000008D -:103960008F82002C3C03000600021140004310250A -:103970003C038000AC62003000000000000000004A -:10398000000000008C620000304200101040FFFD7B -:1039900034620400AF82002803E00008AF80002CEE -:1039A00003E000080000102103E000080000000010 -:1039B0003084FFFF30A5FFFF0000182110800007B2 -:1039C000000000003082000110400002000420428C -:1039D000006518210A000E3D0005284003E000089C -:1039E0000060102110C0000624C6FFFF8CA200005A -:1039F00024A50004AC8200000A000E4724840004C1 -:103A000003E000080000000010A0000824A3FFFF4E -:103A1000AC86000000000000000000002402FFFF50 -:103A20002463FFFF1462FFFA2484000403E000080B -:103A3000000000003C0280083442008024030001A2 -:103A4000AC43000CA4430010A4430012A443001490 -:103A500003E00008A44300168F82002427BDFFD88E -:103A6000AFB3001CAFB20018AFB10014AFB000107C -:103A7000AFBF00208C47000C248200802409FF8007 -:103A80003C08800E3043007F008080213C0A80008B -:103A9000004920240068182130B100FF30D200FF17 -:103AA00010E000290000982126020100AD44002CFE -:103AB000004928243042007F004820219062000005 -:103AC00024030050304200FF1443000400000000B3 -:103AD000AD45002C948200EA3053FFFF0E000D84A8 -:103AE000000000008F8200248F83002000112C0032 -:103AF0009442001E001224003484000100A22825F4 -:103B00003C02400000A22825AC7000008FBF0020BE -:103B1000AC6000048FB20018AC7300088FB10014C1 -:103B2000AC60000C8FB3001CAC6400108FB00010B0 -:103B3000AC60001424040001AC60001827BD00280C -:103B40000A000DB8AC65001C8FBF00208FB3001CAD -:103B50008FB200188FB100148FB0001003E000087E -:103B600027BD00283C06800034C201009043000FAE -:103B7000240200101062000E2865001110A000073A -:103B800024020012240200082405003A10620006F4 -:103B90000000302103E0000800000000240500358B -:103BA0001462FFFC000030210A000E6400000000D7 -:103BB0008CC200748F83FF9424420FA003E000089E -:103BC000AC62000C27BDFFE8AFBF00100E0003423F -:103BD000240500013C0480088FBF0010240200016E -:103BE00034830080A462001227BD00182402000163 -:103BF00003E00008A080001A27BDFFE0AFB2001864 -:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 -:103C10000E000332008088213C028008345000806E -:103C20009202000924030004304200FF1443000CF8 -:103C30003C028008124000082402000A0E000E5BBD -:103C400000000000920200052403FFFE0043102440 -:103C5000A202000524020012A20200093C02800810 -:103C600034420080022020210E00033DA0400027A6 -:103C700016400003022020210E000EBF00000000AD -:103C800002202021324600FF8FBF001C8FB2001897 -:103C90008FB100148FB00010240500380A000E64A4 -:103CA00027BD002027BDFFE0AFBF001CAFB200184A -:103CB000AFB10014AFB000100E00033200808021BD -:103CC0000E000E5B000000003C02800834450080BE -:103CD00090A2000924120018305100FF1232000394 -:103CE0000200202124020012A0A2000990A20005D7 -:103CF0002403FFFE004310240E00033DA0A2000594 -:103D00000200202124050020163200070000302187 -:103D10008FBF001C8FB200188FB100148FB000103D -:103D20000A00034227BD00208FBF001C8FB200187D -:103D30008FB100148FB00010240500390A000E6402 -:103D400027BD002027BDFFE83C028000AFB0001077 -:103D5000AFBF0014344201009442000C2405003629 -:103D60000080802114400012304600FF0E00033214 -:103D7000000000003C02800834420080240300124E -:103D8000A043000990430005346300100E000E5B51 -:103D9000A04300050E00033D020020210200202167 -:103DA0000E000342240500200A000F3C0000000022 -:103DB0000E000E64000000000E00033202002021FD -:103DC0003C0280089043001B2405FF9F0200202135 -:103DD000006518248FBF00148FB00010A043001B93 -:103DE0000A00033D27BD001827BDFFE0AFBF001844 -:103DF000AFB10014AFB0001030B100FF0E000332BD -:103E0000008080213C02800824030012344200809C -:103E10000E000E5BA04300090E00033D02002021AE -:103E200002002021022030218FBF00188FB1001422 -:103E30008FB00010240500350A000E6427BD002055 -:103E40003C0480089083000E9082000A1443000B0B -:103E5000000028218F82FF942403005024050001D4 -:103E600090420000304200FF1443000400000000B4 -:103E70009082000E24420001A082000E03E00008A0 -:103E800000A010213C0380008C6201F80440FFFE7A -:103E900024020002AC6401C0A06201C43C02100014 -:103EA00003E00008AC6201F827BDFFE0AFB20018E4 -:103EB0003C128008AFB10014AFBF001CAFB00010BF -:103EC00036510080922200092403000A304200FF8C -:103ED0001443003E000000008E4300048E22003890 -:103EE000506200808FBF001C92220000240300500B -:103EF000304200FF144300253C0280008C42014008 -:103F00008E4300043642010002202821AC43001CED -:103F10009622005C8E2300383042FFFF00021040E2 -:103F200000621821AE23001C8E4300048E2400384A -:103F30009622005C006418233042FFFF0003184300 -:103F4000000210400043102A10400006000000004C -:103F50008E4200048E230038004310230A000FAA6B -:103F6000000220439622005C3042FFFF0002204006 -:103F70003C0280083443010034420080ACA4002C91 -:103F8000A040002424020001A062000C0E000F5E7D -:103F900000000000104000538FBF001C3C02800056 -:103FA0008C4401403C0380008C6201F80440FFFE19 -:103FB00024020002AC6401C0A06201C43C021000F3 -:103FC000AC6201F80A0010078FBF001C92220009A2 -:103FD00024030010304200FF144300043C02800020 -:103FE0008C4401400A000FEE0000282192220009B3 -:103FF00024030016304200FF14430006240200147C -:10400000A22200093C0280008C4401400A001001F9 -:104010008FBF001C8E2200388E23003C00431023EB -:10402000044100308FBF001C92220027244200016F -:10403000A2220027922200272C42000414400016DE -:104040003C1080009222000924030004304200FF4B -:10405000144300093C0280008C4401408FBF001CC7 -:104060008FB200188FB100148FB000102405009398 -:104070000A000ECC27BD00208C440140240500938B -:104080008FBF001C8FB200188FB100148FB00010CA -:104090000A000F4827BD00208E0401400E000332A5 -:1040A000000000008E4200042442FFFFAE420004E4 -:1040B0008E22003C2442FFFFAE22003C0E00033D56 -:1040C0008E0401408E0401408FBF001C8FB2001887 -:1040D0008FB100148FB00010240500040A000342C1 -:1040E00027BD00208FB200188FB100148FB00010D0 -:1040F00003E0000827BD00203C0680008CC2018838 -:104100003C038008346500809063000E00021402B6 -:10411000304400FF306300FF1464000E3C0280084E -:1041200090A20026304200FF104400098F82FF94C5 -:10413000A0A400262403005090420000304200FF5B -:1041400014430006000000000A0005A18CC4018091 -:104150003C02800834420080A044002603E00008AE -:104160000000000027BDFFE030E700FFAFB20018FD -:10417000AFBF001CAFB10014AFB0001000809021A1 -:1041800014E0000630C600FF000000000000000D33 -:10419000000000000A001060240001163C038008A3 -:1041A0009062000E304200FF14460023346200800B -:1041B00090420026304200FF1446001F000000001D -:1041C0009062000F304200FF1446001B0000000008 -:1041D0009062000A304200FF144600038F90FF9463 -:1041E0000000000D8F90FF948F82FF983C1180009B -:1041F000AE05003CAC450000A066000A0E0003328C -:104200008E240100A20000240E00033D8E24010034 -:104210003C0380008C6201F80440FFFE240200028F -:10422000AC7201C0A06201C43C021000AC6201F893 -:104230000A0010618FBF001C000000000000000D8C -:10424000000000002400013F8FBF001C8FB2001847 -:104250008FB100148FB0001003E0000827BD0020CC -:104260008F83FF943C0280008C44010034420100A3 -:104270008C65003C9046001B0A00102724070001B3 -:104280003C0280089043000E9042000A0043102632 -:10429000304200FF03E000080002102B27BDFFE0C2 -:1042A0003C028008AFB10014AFB00010AFBF0018DF -:1042B0003450008092020005240300303042003068 -:1042C00014430085008088218F8200248C42000CDA -:1042D000104000828FBF00180E000D840000000007 -:1042E0008F860020ACD100009202000892030009E2 -:1042F000304200FF00021200306300FF004310252F -:10430000ACC200049202004D000216000002160327 -:1043100004410005000000003C0308008C630048D5 -:104320000A00109F3C1080089202000830420040B2 -:10433000144000030000182192020027304300FFC0 -:104340003C108008361100809222004D00031E00B0 -:10435000304200FF0002140000621825ACC30008C0 -:104360008E2400308F820024ACC4000C8E250034D3 -:104370009443001E3C02C00BACC50010006218251F -:104380008E22003800002021ACC200148E22003C96 -:10439000ACC200180E000DB8ACC3001C8E020004A5 -:1043A0008F8400203C058000AC8200008E2200201B -:1043B000AC8200048E22001CAC8200088E220058C1 -:1043C0008CA3007400431021AC82000C8E22002CC0 -:1043D000AC8200108E2200408E23004400021400A4 -:1043E00000431025AC8200149222004D240300806B -:1043F000304200FF1443000400000000AC800018AD -:104400000A0010E38F8200248E23000C2402000196 -:104410001062000E2402FFFF92220008304200408A -:104420001440000A2402FFFF8E23000C8CA20074AB -:10443000006218233C0208000062102414400002AD -:10444000000028210060282100051043AC820018DC -:104450008F820024000020219443001E3C02C00CE7 -:10446000006218258F8200200E000DB8AC43001C9E -:104470003C038008346201008C4200008F850020DC -:10448000346300808FBF0018ACA20000ACA0000411 -:104490008C6400488F8200248FB10014ACA4000803 -:1044A000ACA0000CACA00010906300059446001E68 -:1044B0003C02400D00031E0000C23025ACA30014D6 -:1044C0008FB00010ACA0001824040001ACA6001CA2 -:1044D0000A000DB827BD00208FBF00188FB100144F -:1044E0008FB0001003E0000827BD00203C028000D0 -:1044F0009443007C3C02800834460100308400FF75 -:104500003065FFFF2402000524A34650A0C4000C20 -:104510005482000C3065FFFF90C2000D2C42000752 -:104520001040000724A30A0090C3000D24020014C9 -:104530000062100400A210210A00111F3045FFFF85 -:104540003065FFFF3C0280083442008003E0000831 -:10455000A44500143C03800834680080AD05003891 -:10456000346701008CE2001C308400FF00A210239D -:104570001840000330C600FF24A2FFFCACE2001C80 -:1045800030820001504000083C0380088D02003C4E -:1045900000A2102304410012240400058C620004D0 -:1045A00010A2000F3C0380088C62000414A2001EBD -:1045B000000000003C0208008C4200D8304200207D -:1045C000104000093C0280083462008090630008BB -:1045D0009042004C144300043C0280082404000470 -:1045E0000A00110900000000344300803442010039 -:1045F000A040000C24020001A462001410C0000AB4 -:104600003C0280008C4401003C0380008C6201F875 -:104610000440FFFE24020002AC6401C0A06201C499 -:104620003C021000AC6201F803E00008000000004A -:1046300027BDFFE800A61823AFBF00101860008058 -:10464000308800FF3C02800834470080A0E000244E -:1046500034440100A0E000278C82001C00A210233B -:1046600004400056000000008CE2003C94E3005C33 -:104670008CE4002C004530233063FFFF00C3182179 -:104680000083202B1080000400E018218CE2002C15 -:104690000A00117800A2102194E2005C3042FFFF72 -:1046A00000C2102100A21021AC62001C3C02800854 -:1046B000344400809482005C8C83001C3042FFFFF5 -:1046C0000002104000A210210043102B10400004F3 -:1046D000000000008C82001C0A00118B3C06800840 -:1046E0009482005C3042FFFF0002104000A21021C3 -:1046F0003C06800834C3010034C70080AC82001C33 -:10470000A060000CACE500388C62001C00A21023F5 -:104710001840000224A2FFFCAC62001C3102000120 -:10472000104000083C0380088CE2003C00A21023EB -:1047300004410012240400058CC2000410A20010E1 -:104740008FBF00108C62000414A2004F8FBF0010B6 -:104750003C0208008C4200D8304200201040000A81 -:104760003C02800834620080906300089042004C54 -:10477000144300053C028008240400048FBF00108D -:104780000A00110927BD001834430080344201009B -:10479000A040000C24020001A46200143C0280002E -:1047A0008C4401003C0380008C6201F80440FFFE51 -:1047B000240200020A0011D8000000008CE2001C54 -:1047C000004610230043102B54400001ACE5001CB0 -:1047D00094E2005C3042FFFF0062102B144000079F -:1047E0002402000294E2005C8CE3001C3042FFFFD4 -:1047F00000621821ACE3001C24020002ACE5003882 -:104800000E000F5EA082000C1040001F8FBF001032 -:104810003C0280008C4401003C0380008C6201F863 -:104820000440FFFE24020002AC6401C0A06201C487 -:104830003C021000AC6201F80A0011F08FBF0010BA -:1048400031020010104000108FBF00103C028008A1 -:10485000344500808CA3001C94A2005C00661823E1 -:104860003042FFFF006218213C023FFF3444FFFF4B -:104870000083102B544000010080182100C3102138 -:10488000ACA2001C8FBF001003E0000827BD001879 -:1048900027BDFFE800C0402100A63023AFBF0010B5 -:1048A00018C00026308A00FF3C028008344900808E -:1048B0008D24001C8D23002C008820230064182BDD -:1048C0001060000F344701008CE2002000461021E8 -:1048D000ACE200208CE200200044102B1440000BBE -:1048E0003C023FFF8CE2002000441023ACE2002099 -:1048F0009522005C3042FFFF0A0012100082202146 -:10490000ACE00020008620213C023FFF3443FFFF43 -:104910000064102B54400001006020213C028008FC -:104920003442008000851821AC43001CA0400024C4 -:10493000A04000270A0012623C03800831420010A8 -:10494000104000433C0380083C06800834C40080CB -:104950008C82003C004810235840003E34660080A2 -:104960009082002424420001A0820024908200242E -:104970003C0308008C630024304200FF0043102BEE -:10498000144000688FBF001034C201008C42001C2C -:1049900000A2102318400063000000008CC3000434 -:1049A0009482005C006818233042FFFF0003184324 -:1049B000000210400043102A1040000500000000D3 -:1049C0008CC20004004810230A0012450002104364 -:1049D0009482005C3042FFFF000210403C068008D9 -:1049E000AC82002C34C5008094A2005C8CA4002C06 -:1049F00094A3005C3042FFFF00021040008220219F -:104A00003063FFFF0083202101041021ACA2001CB1 -:104A10008CC2000434C60100ACC2001C2402000297 -:104A20000E000F5EA0C2000C1040003E8FBF0010B1 -:104A30003C0280008C4401003C0380008C6201F841 -:104A40000440FFFE240200020A001292000000004F -:104A500034660080ACC50038346401008C82001CD0 -:104A600000A210231840000224A2FFFCAC82001C0C -:104A7000314200015040000A3C0380088CC2003CD7 -:104A800000A2102304430014240400058C620004D7 -:104A900014A200033C0380080A00128424040005C9 -:104AA0008C62000414A2001F8FBF00103C0208009B -:104AB0008C4200D8304200201040000A3C0280089E -:104AC00034620080906300089042004C144300055B -:104AD0003C028008240400048FBF00100A00110962 -:104AE00027BD00183443008034420100A040000C70 -:104AF00024020001A46200143C0280008C440100E6 -:104B00003C0380008C6201F80440FFFE2402000296 -:104B1000AC6401C0A06201C43C021000AC6201F8A8 -:104B20008FBF001003E0000827BD001827BDFFE875 -:104B30003C0A8008AFBF0010354900808D22003C40 -:104B400000C04021308400FF004610231840009D23 -:104B500030E700FF354701002402000100A63023A2 -:104B6000A0E0000CA0E0000DA522001418C0002455 -:104B7000308200108D23001C8D22002C0068182329 -:104B80000043102B1040000F000000008CE20020BA -:104B900000461021ACE200208CE200200043102BE4 -:104BA0001440000B3C023FFF8CE200200043102326 -:104BB000ACE200209522005C3042FFFF0A0012C1E7 -:104BC00000621821ACE00020006618213C023FFF83 -:104BD0003446FFFF00C3102B5440000100C01821D1 -:104BE0003C0280083442008000651821AC43001C60 -:104BF000A0400024A04000270A00130F3C038008B7 -:104C0000104000403C0380088D22003C00481023E7 -:104C10005840003D34670080912200242442000166 -:104C2000A1220024912200243C0308008C6300246C -:104C3000304200FF0043102B1440009A8FBF001039 -:104C40008CE2001C00A21023184000960000000017 -:104C50008D4300049522005C006818233042FFFF5A -:104C600000031843000210400043102A10400005C2 -:104C7000012020218D420004004810230A0012F276 -:104C8000000210439522005C3042FFFF00021040FA -:104C90003C068008AC82002C34C5008094A2005CE5 -:104CA0008CA4002C94A3005C3042FFFF0002104053 -:104CB000008220213063FFFF0083182101031021AF -:104CC000ACA2001C8CC2000434C60100ACC2001CA3 -:104CD000240200020E000F5EA0C2000C1040007102 -:104CE0008FBF00103C0280008C4401003C03800018 -:104CF0008C6201F80440FFFE240200020A0013390E -:104D00000000000034670080ACE500383466010024 -:104D10008CC2001C00A210231840000224A2FFFC39 -:104D2000ACC2001C30820001504000083C038008E7 -:104D30008CE2003C00A2102304430051240400052F -:104D40008C62000410A2003E3C0380088C620004C8 -:104D500054A200548FBF00103C0208008C4200D8BF -:104D600030420020104000063C028008346200807F -:104D7000906300089042004C104300403C028008C1 -:104D80003443008034420100A040000C24020001A2 -:104D9000A46200143C0280008C4401003C038000AB -:104DA0008C6201F80440FFFE24020002AC6401C0E2 -:104DB000A06201C43C021000AC6201F80A00137743 -:104DC0008FBF001024020005A120002714E2000A72 -:104DD0003C038008354301009062000D2C42000620 -:104DE000504000053C0380089062000D2442000101 -:104DF000A062000D3C03800834670080ACE50038F9 -:104E0000346601008CC2001C00A21023184000026E -:104E100024A2FFFCACC2001C308200015040000AFA -:104E20003C0380088CE2003C00A2102304410014E3 -:104E3000240400058C62000414A200033C038008D3 -:104E40000A00136E240400058C62000414A20015ED -:104E50008FBF00103C0208008C4200D83042002076 -:104E60001040000A3C028008346200809063000811 -:104E70009042004C144300053C02800824040004C6 -:104E80008FBF00100A00110927BD001834430080AD -:104E900034420100A040000C24020001A46200146E -:104EA0008FBF001003E0000827BD00183C0B8008EE -:104EB00027BDFFE83C028000AFBF00103442010074 -:104EC000356A00809044000A356901008C45001461 -:104ED0008D4800389123000C308400FF0105102319 -:104EE0001C4000B3306700FF2CE20006504000B1C8 -:104EF0008FBF00102402000100E2300430C2000322 -:104F00005440000800A8302330C2000C144000A117 -:104F100030C20030144000A38FBF00100A00143BC1 -:104F20000000000018C00024308200108D43001CD7 -:104F30008D42002C006818230043102B1040000FF6 -:104F4000000000008D22002000461021AD2200202C -:104F50008D2200200043102B1440000B3C023FFF29 -:104F60008D22002000431023AD2200209542005CDA -:104F70003042FFFF0A0013AF00621821AD2000206D -:104F8000006618213C023FFF3446FFFF00C3102B90 -:104F90005440000100C018213C02800834420080C7 -:104FA00000651821AC43001CA0400024A04000274D -:104FB0000A0013FD3C038008104000403C038008B9 -:104FC0008D42003C004810231840003D34670080AB -:104FD0009142002424420001A14200249142002475 -:104FE0003C0308008C630024304200FF0043102B78 -:104FF000144000708FBF00108D22001C00A21023EF -:105000001840006C000000008D6300049542005CB5 -:10501000006818233042FFFF0003184300021040CD -:105020000043102A10400005014020218D62000439 -:10503000004810230A0013E0000210439542005C70 -:105040003042FFFF000210403C068008AC82002C7A -:1050500034C5008094A2005C8CA4002C94A3005C56 -:105060003042FFFF00021040008220213063FFFF2A -:105070000083182101031021ACA2001C8CC2000483 -:1050800034C60100ACC2001C240200020E000F5EF8 -:10509000A0C2000C104000478FBF00103C028000EF -:1050A0008C4401003C0380008C6201F80440FFFE48 -:1050B000240200020A00142D000000003467008062 -:1050C000ACE50038346601008CC2001C00A210233D -:1050D0001840000224A2FFFCACC2001C3082000178 -:1050E0005040000A3C0380088CE2003C00A21023E0 -:1050F00004430014240400058C62000414A200037D -:105100003C0380080A00141F240400058C6200047C -:1051100014A200288FBF00103C0208008C4200D867 -:10512000304200201040000A3C02800834620080B7 -:10513000906300089042004C144300053C02800834 -:10514000240400048FBF00100A00110927BD0018B5 -:105150003443008034420100A040000C24020001CE -:10516000A46200143C0280008C4401003C038000D7 -:105170008C6201F80440FFFE24020002AC6401C00E -:10518000A06201C43C021000AC6201F80A00143BAA -:105190008FBF00108FBF0010010030210A00115A8C -:1051A00027BD0018010030210A00129927BD001800 -:1051B0008FBF001003E0000827BD00183C038008E3 -:1051C0003464010024020003A082000C8C620004FD -:1051D00003E00008AC82001C3C05800834A300807A -:1051E0009062002734A501002406004324420001F8 -:1051F000A0620027906300273C0208008C42004810 -:10520000306300FF146200043C07602194A500EAAB -:105210000A00090130A5FFFF03E0000800000000BC -:1052200027BDFFE8AFBF00103C0280000E00144411 -:105230008C4401803C02800834430100A060000CD3 -:105240008C4200048FBF001027BD001803E0000847 -:10525000AC62001C27BDFFE03C028008AFBF001815 -:10526000AFB10014AFB000103445008034460100E7 -:105270003C0880008D09014090C3000C8CA4003CC8 -:105280008CA200381482003B306700FF9502007C3E -:1052900090A30027146000093045FFFF2402000599 -:1052A00054E200083C04800890C2000D2442000132 -:1052B000A0C2000D0A00147F3C048008A0C0000DAD -:1052C0003C048008348201009042000C2403000555 -:1052D000304200FF1443000A24A205DC348300801E -:1052E000906200272C4200075040000524A20A00CB -:1052F00090630027240200140062100400A2102111 -:105300003C108008361000803045FFFF012020212E -:105310000E001444A60500149602005C8E030038AB -:105320003C1180003042FFFF000210400062182153 -:10533000AE03001C0E0003328E24014092020025B1 -:1053400034420040A20200250E00033D8E2401409D -:105350008E2401403C0380008C6201F80440FFFE73 -:1053600024020002AC6401C0A06201C43C0210002F -:10537000AC6201F88FBF00188FB100148FB000101D -:1053800003E0000827BD00203C0360103C02080039 -:1053900024420174AC62502C8C6250003C048000AA -:1053A00034420080AC6250003C0208002442547C2D -:1053B0003C010800AC2256003C020800244254384C -:1053C0003C010800AC2256043C020002AC840008F8 -:1053D000AC82000C03E000082402000100A0302190 -:1053E0003C1C0800279C56083C0200023C050400B7 -:1053F00000852826008220260004102B2CA5000101 -:105400002C840001000210803C0308002463560035 -:105410000085202500431821108000030000102182 -:10542000AC6600002402000103E000080000000058 -:105430003C1C0800279C56083C0200023C05040066 -:1054400000852826008220260004102B2CA50001B0 -:105450002C840001000210803C03080024635600E5 -:105460000085202500431821108000050000102130 -:105470003C02080024425438AC62000024020001BF -:1054800003E00008000000003C0200023C030400AE -:1054900000821026008318262C4200012C63000194 -:1054A000004310251040000B000028213C1C080080 -:1054B000279C56083C0380008C62000824050001EC -:1054C00000431025AC6200088C62000C00441025DB -:1054D000AC62000C03E0000800A010213C1C080096 -:1054E000279C56083C0580008CA3000C0004202754 -:1054F000240200010064182403E00008ACA3000C9F -:105500003C020002148200063C0560008CA208D018 -:105510002403FFFE0043102403E00008ACA208D0DF -:105520003C02040014820005000000008CA208D098 -:105530002403FFFD00431024ACA208D003E00008C0 -:10554000000000003C02601A344200108C430080CE -:1055500027BDFFF88C440084AFA3000093A3000094 -:10556000240200041462001AAFA4000493A20001F4 -:105570001040000797A300023062FFFC3C0380004C -:10558000004310218C4200000A001536AFA200042F -:105590003062FFFC3C03800000431021AC4400005B -:1055A000A3A000003C0560008CA208D02403FFFEED -:1055B0003C04601A00431024ACA208D08FA300045E -:1055C0008FA2000034840010AC830084AC82008081 -:1055D00003E0000827BD000827BDFFE8AFBF0010AB -:1055E0003C1C0800279C56083C0280008C43000CA1 -:1055F0008C420004004318243C0200021060001496 -:10560000006228243C0204003C04000210A00005B3 -:10561000006210243C0208008C4256000A00155B10 -:1056200000000000104000073C0404003C02080099 -:105630008C4256040040F809000000000A00156082 -:10564000000000000000000D3C1C0800279C5608CC -:0C5650008FBF001003E0000827BD001809 -:04565C008008024080 -:1056600080080100800800808008000000000C8095 -:105670000000320008000E9808000EF408000F88A1 -:1056800008001028080010748008010080080080BD -:04569000800800008E -:0C5694000A0000280000000000000000D8 -:1056A0000000000D6370362E302E313700000000F0 -:1056B00006001104000000000000000000000000CF -:1056C000000000000000000038003C000000000066 -:1056D00000000000000000000000000000000020AA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:10570000000000000000000021003800000000013F -:105710000000002B000000000000000400030D400A -:105720000000000000000000000000000000000079 -:105730000000000000000000100000030000000056 -:105740000000000D0000000D3C020800244259AC8E -:105750003C03080024635BF4AC4000000043202BB2 -:105760001480FFFD244200043C1D080037BD9FFC4F -:1057700003A0F0213C100800261000A03C1C0800EB -:10578000279C59AC0E0002F6000000000000000D3E -:1057900027BDFFB4AFA10000AFA20004AFA3000873 -:1057A000AFA4000CAFA50010AFA60014AFA700185F -:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF -:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F -:1057D000AFB8003CAFB90040AFBC0044AFBF004819 -:1057E0000E000820000000008FBF00488FBC00445E -:1057F0008FB900408FB8003C8FAF00388FAE0034B7 -:105800008FAD00308FAC002C8FAB00288FAA002406 -:105810008FA900208FA8001C8FA700188FA6001446 -:105820008FA500108FA4000C8FA300088FA2000486 -:105830008FA1000027BD004C3C1B60188F7A5030B0 -:10584000377B502803400008AF7A000000A01821E1 -:1058500000801021008028213C0460003C0760008B -:105860002406000810600006348420788C42000072 -:10587000ACE220088C63000003E00008ACE3200CDD -:105880000A000F8100000000240300403C02600079 -:1058900003E00008AC4320003C0760008F86000452 -:1058A0008CE520740086102100A2182B14600007DC -:1058B000000028218F8AFDA024050001A1440013C7 -:1058C0008F89000401244021AF88000403E0000810 -:1058D00000A010218F84FDA08F8500049086001306 -:1058E00030C300FF00A31023AF82000403E00008D0 -:1058F000A08000138F84FDA027BDFFE8AFB000108B -:10590000AFBF001490890011908700112402002875 -:10591000312800FF3906002830E300FF2485002CE1 -:105920002CD00001106200162484001C0E00006EB2 -:10593000000000008F8FFDA03C05600024020204DF -:1059400095EE003E95ED003C000E5C0031ACFFFF93 -:10595000016C5025ACAA2010520000012402000462 -:10596000ACA22000000000000000000000000000C9 -:105970008FBF00148FB0001003E0000827BD00188F -:105980000A0000A6000028218F85FDA027BDFFD8B2 -:10599000AFBF0020AFB3001CAFB20018AFB100140E -:1059A000AFB000100080982190A4001124B0001C1A -:1059B00024B1002C308300FF386200280E000090D4 -:1059C0002C5200010E00009800000000020020216F -:1059D0001240000202202821000028210E00006E43 -:1059E000000000008F8DFDA03C0880003C05600099 -:1059F00095AC003E95AB003C02683025000C4C0095 -:105A0000316AFFFF012A3825ACA7201024020202C8 -:105A1000ACA6201452400001240200028FBF0020D7 -:105A20008FB3001C8FB200188FB100148FB000101C -:105A300027BD002803E00008ACA2200027BDFFE03E -:105A4000AFB20018AFB10014AFB00010AFBF001C70 -:105A50003C1160008E2320748F82000430D0FFFF41 -:105A600030F2FFFF1062000C2406008F0E00006E63 -:105A7000000000003C06801F0010440034C5FF00F9 -:105A80000112382524040002AE2720100000302126 -:105A9000AE252014AE2420008FBF001C8FB200184A -:105AA0008FB100148FB0001000C0102103E0000877 -:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 -:105AC000AFBF0018AFB100140E00006E30F1FFFF41 -:105AD00000102400009180253C036000AC70201071 -:105AE0008FBF00188FB100148FB000102402000483 -:105AF000AC62200027BD002003E000080000102158 -:105B000027BDFFE03C046018AFBF0018AFB1001420 -:105B1000AFB000108C8850002403FF7F34028071E6 -:105B20000103382434E5380C241F00313C1980006F -:105B3000AC8550003C11800AAC8253BCAF3F0008DA -:105B40000E00054CAF9100400E00050A3C116000AC -:105B50000E00007D000000008E3008083C0F570941 -:105B60002418FFF00218602435EEE00035EDF00057 -:105B7000018E5026018D58262D4600012D69000109 -:105B8000AF86004C0E000D09AF8900503C06601630 -:105B90008CC700003C0860148D0500A03C03FFFF8B -:105BA00000E320243C02535300052FC2108200550D -:105BB00034D07C00960201F2A780006C10400003F4 -:105BC000A780007C384B1E1EA78B006C960201F844 -:105BD000104000048F8D0050384C1E1EA78C007C96 -:105BE0008F8D005011A000058F83004C240E0020E3 -:105BF000A78E007CA78E006C8F83004C1060000580 -:105C00009785007C240F0020A78F007CA78F006C55 -:105C10009785007C2CB8008153000001240500808A -:105C20009784006C2C91040152200001240404008C -:105C30001060000B3C0260008FBF00188FB1001491 -:105C40008FB0001027BD0020A784006CA785007CC2 -:105C5000A380007EA780007403E00008A780009264 -:105C60008C4704382419103C30FFFFFF13F9000360 -:105C700030A8FFFF1100004624030050A380007EDF -:105C80009386007E50C00024A785007CA780007CFE -:105C90009798007CA780006CA7800074A780009272 -:105CA0003C010800AC3800800E00078700000000AF -:105CB0003C0F60008DED0808240EFFF03C0B600ED9 -:105CC000260C0388356A00100000482100002821B6 -:105CD00001AE20243C105709AF8C0010AF8A004859 -:105CE000AF89001810900023AF8500148FBF0018F3 -:105CF0008FB100148FB0001027BD002003E0000812 -:105D0000AF80005400055080014648218D260004D4 -:105D10000A00014800D180219798007CA784006C7C -:105D2000A7800074A78000923C010800AC38008076 -:105D30000E000787000000003C0F60008DED080892 -:105D4000240EFFF03C0B600E260C0388356A001011 -:105D5000000048210000282101AE20243C105709F2 -:105D6000AF8C0010AF8A0048AF8900181490FFDF95 -:105D7000AF85001424110001AF9100548FBF0018AB -:105D80008FB100148FB0001003E0000827BD002081 -:105D90000A00017BA383007E3083FFFF8F880040D1 -:105DA0008F87003C000321403C0580003C020050EE -:105DB000008248253C0660003C0A010034AC040027 -:105DC0008CCD08E001AA58241160000500000000F5 -:105DD0008CCF08E024E7000101EA7025ACCE08E092 -:105DE0008D19001001805821ACB900388D180014AD -:105DF000ACB8003CACA9003000000000000000007E -:105E00000000000000000000000000000000000092 -:105E100000000000000000003C0380008C640000D3 -:105E2000308200201040FFFD3C0F60008DED08E047 -:105E30003C0E010001AE18241460FFE100000000D8 -:105E4000AF87003C03E00008AF8B00588F8500400F -:105E5000240BFFF03C06800094A7001A8CA90024B4 -:105E600030ECFFFF000C38C000EB5024012A402129 -:105E7000ACC8003C8CA400248CC3003C00831023DD -:105E800018400033000000008CAD002025A2000166 -:105E90003C0F0050ACC2003835EE00103C068000CC -:105EA000ACCE003000000000000000000000000048 -:105EB00000000000000000000000000000000000E2 -:105EC000000000003C0480008C9900003338002062 -:105ED0001300FFFD30E20008104000173C0980006D -:105EE0008C880408ACA800108C83040CACA30014AC -:105EF0003C1900203C188000AF19003094AE001807 -:105F000094AF001C01CF3021A4A6001894AD001A54 -:105F100025A70001A4A7001A94AB001A94AC001E98 -:105F2000118B00030000000003E0000800000000E7 -:105F300003E00008A4A0001A8D2A0400ACAA0010F7 -:105F40008D240404ACA400140A0002183C1900209B -:105F50008CA200200A0002003C0F00500A0001EE53 -:105F60000000000027BDFFE8AFBF00100E000232A6 -:105F7000000000008F8900408FBF00103C038000AC -:105F8000A520000A9528000A9527000427BD0018BF -:105F90003105FFFF30E6000F0006150000A22025A6 -:105FA00003E00008AC6400803C0508008CA50020DC -:105FB0008F83000C27BDFFE8AFB00010AFBF001407 -:105FC00010A300100000802124040001020430040A -:105FD00000A6202400C3102450440006261000010F -:105FE000001018802787FDA41480000A006718217C -:105FF000261000012E0900025520FFF38F83000CAC -:10600000AF85000C8FBF00148FB0001003E00008B4 -:1060100027BD00188C6800003C058000ACA8002457 -:106020000E000234261000013C0508008CA500205B -:106030000A0002592E0900022405000100851804F7 -:106040003C0408008C84002027BDFFC8AFBF00348B -:1060500000831024AFBE0030AFB7002CAFB60028CD -:10606000AFB50024AFB40020AFB3001CAFB200182E -:10607000AFB1001410400051AFB000108F84004049 -:10608000948700069488000A00E8302330D5FFFF8B -:1060900012A0004B8FBF0034948B0018948C000A20 -:1060A000016C50233142FFFF02A2482B1520000251 -:1060B00002A02021004020212C8F000515E00002C5 -:1060C00000809821241300040E0001C102602021E9 -:1060D0008F87004002609021AF80004494F4000A52 -:1060E000026080211260004E3291FFFF3C1670006A -:1060F0003C1440003C1E20003C1760008F99005863 -:106100008F380000031618241074004F0283F82BF8 -:1061100017E0003600000000107E00478F86004424 -:1061200014C0003A2403000102031023022320219B -:106130003050FFFF1600FFF13091FFFF8F870040C6 -:106140003C1100203C108000AE11003094EB000A9E -:106150003C178000024B5021A4EA000A94E9000A8F -:1061600094E800043123FFFF3106000F00062D00E4 -:106170000065F025AEFE008094F3000A94F6001846 -:1061800012D30036001221408CFF00148CF4001052 -:1061900003E468210000C02101A4782B029870213B -:1061A00001CF6021ACED0014ACEC001002B238233A -:1061B00030F5FFFF16A0FFB88F8400408FBF00347A -:1061C0008FBE00308FB7002C8FB600288FB500240B -:1061D0008FB400208FB3001C8FB200188FB1001451 -:1061E0008FB0001003E0000827BD00381477FFCC03 -:1061F0008F8600440E000EE202002021004018218C -:106200008F86004410C0FFC9020310230270702360 -:106210008F87004001C368210A0002E431B2FFFF0A -:106220008F86004414C0FFC93C1100203C10800040 -:106230000A0002AEAE1100300E00046602002021FA -:106240000A0002DB00401821020020210E0009395B -:10625000022028210A0002DB004018210E0001EE76 -:10626000000000000A0002C702B2382327BDFFC8A1 -:10627000AFB7002CAFB60028AFB50024AFB40020F4 -:10628000AFB3001CAFB20018AFB10014AFB0001034 -:10629000AFBF00300E00011B241300013C047FFF40 -:1062A0003C0380083C0220003C010800AC20007048 -:1062B0003496FFFF34770080345200033C1512C03F -:1062C000241400013C1080002411FF800E000245C0 -:1062D000000000008F8700488F8B00188F89001402 -:1062E0008CEA00EC8CE800E8014B302B01092823F4 -:1062F00000A6102314400006014B18231440000E82 -:106300003C05800002A3602B1180000B0000000000 -:106310003C0560008CEE00EC8CED00E88CA4180CC1 -:10632000AF8E001804800053AF8D00148F8F0010C3 -:10633000ADF400003C0580008CBF00003BF900017B -:10634000333800011700FFE13C0380008C6201003C -:1063500024060C0010460009000000008C680100B3 -:106360002D043080548000103C0480008C690100B2 -:106370002D2331811060000C3C0480008CAA0100A8 -:1063800011460004000020218CA6010024C5FF81D5 -:1063900030A400FF8E0B01000E000269AE0B00243A -:1063A0000A00034F3C0480008C8D01002DAC3300AB -:1063B00011800022000000003C0708008CE70098D4 -:1063C00024EE00013C010800AC2E00983C04800043 -:1063D0008C8201001440000300000000566000148D -:1063E0003C0440008C9F01008C9801000000982123 -:1063F00003F1C82400193940330F007F00EF7025E6 -:1064000001D26825AC8D08308C8C01008C85010090 -:10641000258B0100017130240006514030A3007F1C -:106420000143482501324025AC8808303C04400037 -:10643000AE0401380A00030E000000008C99010030 -:10644000240F0020AC99002092F80000330300FFD5 -:10645000106F000C241F0050547FFFDD3C048000AF -:106460008C8401000E00154E000000000A00034F4E -:106470003C04800000963824ACA7180C0A000327BF -:106480008F8F00108C8501000E0008F72404008017 -:106490000A00034F3C04800000A4102B24030001D9 -:1064A00010400009000030210005284000A4102BF6 -:1064B00004A00003000318405440FFFC00052840DE -:1064C0005060000A0004182B0085382B54E00004AB -:1064D0000003184200C33025008520230003184222 -:1064E0001460FFF9000528420004182B03E000089F -:1064F00000C310213084FFFF30C600FF3C0780003E -:106500008CE201B80440FFFE00064C000124302557 -:106510003C08200000C820253C031000ACE00180AE -:10652000ACE50184ACE4018803E00008ACE301B809 -:106530003C0660008CC5201C2402FFF03083020062 -:10654000308601001060000E00A2282434A500014E -:106550003087300010E0000530830C0034A50004C3 -:106560003C04600003E00008AC85201C1060FFFDC7 -:106570003C04600034A5000803E00008AC85201C42 -:1065800054C0FFF334A500020A0003B03087300086 -:1065900027BDFFE8AFB00010AFBF00143C0760009C -:1065A000240600021080001100A080218F83005873 -:1065B0000E0003A78C6400188F8200580000202171 -:1065C000240600018C45000C0E000398000000001A -:1065D0001600000224020003000010218FBF0014E7 -:1065E0008FB0001003E0000827BD00188CE8201CC5 -:1065F0002409FFF001092824ACE5201C8F870058EE -:106600000A0003CD8CE5000C3C02600E00804021A6 -:1066100034460100240900180000000000000000BA -:10662000000000003C0A00503C0380003547020097 -:10663000AC68003834640400AC65003CAC670030E2 -:106640008C6C0000318B00201160FFFD2407FFFFE0 -:106650002403007F8C8D00002463FFFF248400044A -:10666000ACCD00001467FFFB24C60004000000004E -:10667000000000000000000024A402000085282B78 -:106680003C0300203C0E80002529FFFF010540212E -:10669000ADC300301520FFE00080282103E0000892 -:1066A000000000008F82005827BDFFD8AFB3001C48 -:1066B000AFBF0020AFB20018AFB10014AFB00010F0 -:1066C00094460002008098218C5200182CC300814F -:1066D0008C4800048C4700088C51000C8C49001039 -:1066E000106000078C4A00142CC4000414800013AE -:1066F00030EB000730C5000310A0001000000000C0 -:106700002410008B02002021022028210E00039873 -:10671000240600031660000224020003000010217A -:106720008FBF00208FB3001C8FB200188FB10014F0 -:106730008FB0001003E0000827BD00281560FFF1AE -:106740002410008B3C0C80003C030020241F00011F -:10675000AD830030AF9F0044000000000000000047 -:10676000000000002419FFF024D8000F031978243A -:106770003C1000D0AD88003801F0702524CD000316 -:106780003C08600EAD87003C35850400AD8E0030BE -:10679000000D38823504003C3C0380008C6B000007 -:1067A000316200201040FFFD0000000010E00008F2 -:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 -:1067C00024A50004AC8800001467FFFB24840004A7 -:1067D0003C05600EACA60038000000000000000080 -:1067E000000000008F8600543C0400203C0780001D -:1067F000ACE4003054C000060120202102402021DA -:106800000E0003A7000080210A00041D02002021C1 -:106810000E0003DD01402821024020210E0003A7C5 -:10682000000080210A00041D0200202127BDFFE096 -:10683000AFB200183092FFFFAFB10014AFBF001C21 -:10684000AFB000101640000D000088210A0004932C -:106850000220102124050003508500278CE5000C40 -:106860000000000D262800013111FFFF24E2002066 -:106870000232802B12000019AF8200588F82004430 -:10688000144000168F8700583C0670003C0320001F -:106890008CE5000000A62024148300108F84006083 -:1068A000000544023C09800000A980241480FFE90F -:1068B000310600FF2CCA000B5140FFEB26280001D7 -:1068C000000668803C0E080025CE575801AE6021B6 -:1068D0008D8B0000016000080000000002201021E4 -:1068E0008FBF001C8FB200188FB100148FB0001042 -:1068F00003E0000827BD00200E0003982404008454 -:106900001600FFD88F8700580A000474AF8000601B -:10691000020028210E0003BF240400018F870058C5 -:106920000A000474AF820060020028210E0003BF39 -:10693000000020210A0004A38F8700580E000404E1 -:10694000020020218F8700580A000474AF82006083 -:1069500030AFFFFF000F19C03C0480008C9001B8DD -:106960000600FFFE3C1920043C181000AC83018097 -:10697000AC800184AC990188AC9801B80A00047518 -:106980002628000190E2000390E30002000020218D -:106990000002FE0000033A0000FF2825240600083C -:1069A0000E000398000000001600FFDC2402000324 -:1069B0008F870058000010210A000474AF82006025 -:1069C00090E8000200002021240600090A0004C308 -:1069D00000082E0090E4000C240900FF308500FF21 -:1069E00010A900150000302190F9000290F8000372 -:1069F000308F00FF94EB000400196E000018740043 -:106A0000000F62000186202501AE5025014B28258C -:106A10003084FF8B0A0004C32406000A90E30002BE -:106A200090FF0004000020210003360000DF28252D -:106A30000A0004C32406000B0A0004D52406008BB8 -:106A4000000449C23127003F000443423C02800059 -:106A500000082040240316802CE60020AC43002CC4 -:106A600024EAFFE02482000114C0000330A900FFE3 -:106A700000801021314700FF000260803C0D800043 -:106A8000240A0001018D20213C0B000E00EA28049D -:106A9000008B302111200005000538278CCE000026 -:106AA00001C5382503E00008ACC700008CD8000001 -:106AB0000307782403E00008ACCF000027BDFFE007 -:106AC000AFB10014AFB00010AFBF00183C076000BA -:106AD0008CE408083402F0003C1160003083F000C0 -:106AE000240501C03C04800E000030211062000625 -:106AF000241000018CEA08083149F0003928E00030 -:106B00000008382B000780403C0D0200AE2D081411 -:106B1000240C16803C0B80008E2744000E000F8B47 -:106B2000AD6C002C120000043C02169124050001FB -:106B3000120500103C023D2C345800E0AE384408E9 -:106B40003C1108008E31007C8FBF00183C066000AD -:106B500000118540360F16808FB100148FB00010E1 -:106B60003C0E020027BD0020ACCF442003E000080B -:106B7000ACCE08103C0218DA345800E0AE384408B5 -:106B80003C1108008E31007C8FBF00183C0660006D -:106B900000118540360F16808FB100148FB00010A1 -:106BA0003C0E020027BD0020ACCF442003E00008CB -:106BB000ACCE08100A0004EB240500010A0004EB27 -:106BC0000000282124020400A7820024A780001CC2 -:106BD000000020213C06080024C65A582405FFFF67 -:106BE00024890001000440803124FFFF01061821A0 -:106BF0002C87002014E0FFFAAC6500002404040098 -:106C0000A7840026A780001E000020213C06080063 -:106C100024C65AD82405FFFF248D0001000460809B -:106C200031A4FFFF018658212C8A00201540FFFA6D -:106C3000AD650000A7800028A7800020A780002263 -:106C4000000020213C06080024C65B582405FFFFF5 -:106C5000249900010004C0803324FFFF030678213B -:106C60002C8E000415C0FFFAADE500003C05600065 -:106C70008CA73D002403E08F00E31024344601403C -:106C800003E00008ACA63D002487007F000731C266 -:106C900024C5FFFF000518C2246400013082FFFFF5 -:106CA000000238C0A78400303C010800AC27003047 -:106CB000AF80002C0000282100002021000030219E -:106CC0002489000100A728213124FFFF2CA81701E7 -:106CD000110000032C8300801460FFF924C600011A -:106CE00000C02821AF86002C10C0001DA786002AF6 -:106CF00024CAFFFF000A11423C08080025085B581F -:106D00001040000A00002021004030212407FFFF2E -:106D1000248E00010004688031C4FFFF01A86021B7 -:106D20000086582B1560FFFAAD87000030A2001FC7 -:106D30005040000800043080240300010043C804D0 -:106D400000041080004878212738FFFF03E0000886 -:106D5000ADF8000000C820212405FFFFAC8500002D -:106D600003E000080000000030A5FFFF30C6FFFF71 -:106D700030A8001F0080602130E700FF0005294295 -:106D80000000502110C0001D24090001240B000147 -:106D900025180001010B2004330800FF0126782686 -:106DA000390E00202DED00012DC2000101A2182591 -:106DB0001060000D014450250005C880032C4021BF -:106DC0000100182110E0000F000A20278D040000A8 -:106DD000008A1825AD03000024AD00010000402109 -:106DE0000000502131A5FFFF252E000131C9FFFF12 -:106DF00000C9102B1040FFE72518000103E0000830 -:106E0000000000008D0A0000014440240A0005D162 -:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC -:106E2000AFB00010AFBF001430E7FFFF00005021EB -:106E30003410FFFF0000602124AF001F00C0482174 -:106E4000241800012419002005E0001601E010219B -:106E50000002F943019F682A0009702B01AE40240B -:106E600011000017000C18800064102110E00005CC -:106E70008C4B000000F840040008382301675824B8 -:106E800000003821154000410000402155600016E7 -:106E90003169FFFF258B0001316CFFFF05E1FFEC3D -:106EA00001E0102124A2003E0002F943019F682A5C -:106EB0000009702B01AE40241500FFEB000C188078 -:106EC000154600053402FFFF020028210E0005B51B -:106ED00000003821020010218FBF00148FB0001075 -:106EE00003E0000827BD00181520000301601821E9 -:106EF000000B1C0224080010306A00FF154000053A -:106F0000306E000F250D000800031A0231A800FFA3 -:106F1000306E000F15C00005307F000325100004FF -:106F200000031902320800FF307F000317E000055C -:106F3000386900012502000200031882304800FF72 -:106F4000386900013123000110600004310300FFA3 -:106F5000250A0001314800FF310300FF000C6940A1 -:106F600001A34021240A000110CAFFD53110FFFF00 -:106F7000246E000131C800FF1119FFC638C9000195 -:106F80002D1F002053E0001C258B0001240D000163 -:106F90000A000648240E002051460017258B0001E8 -:106FA00025090001312800FF2D0900205120001281 -:106FB000258B000125430001010D5004014B1024D5 -:106FC000250900011440FFF4306AFFFF3127FFFF5D -:106FD00010EE000C2582FFFF304CFFFF0000502117 -:106FE0003410FFFF312800FF2D0900205520FFF24B -:106FF00025430001258B0001014648260A000602B0 -:10700000316CFFFF00003821000050210A000654B7 -:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 -:10702000AFB10014001039423211FFE000071080A8 -:10703000AFB3001C00B1282330D3FFFFAFB200185C -:1070400030A5FFFF00809021026030210044202104 -:10705000AFBF00200E0005E03207001F022288218A -:107060003403FFFF0240202102002821026030216A -:1070700000003821104300093231FFFF02201021A7 -:107080008FBF00208FB3001C8FB200188FB1001487 -:107090008FB0001003E0000827BD00280E0005E0B7 -:1070A0000000000000408821022010218FBF002036 -:1070B0008FB3001C8FB200188FB100148FB0001076 -:1070C00003E0000827BD0028000424003C03600002 -:1070D000AC603D0810A00002348210063482101605 -:1070E00003E00008AC623D0427BDFFE0AFB0001034 -:1070F000309000FF2E020006AFBF001810400008BD -:10710000AFB10014001030803C03080024635784A2 -:1071100000C328218CA400000080000800000000AB -:10712000000020218FBF00188FB100148FB0001015 -:107130000080102103E0000827BD00209791002A5D -:1071400016200051000020213C020800904200332C -:107150000A0006BB00000000978D002615A0003134 -:10716000000020210A0006BB2402000897870024A3 -:1071700014E0001A00001821006020212402000100 -:107180001080FFE98FBF0018000429C2004530219C -:1071900000A6582B1160FFE43C0880003C0720004B -:1071A000000569C001A76025AD0C00203C038008E4 -:1071B0002402001F2442FFFFAC6000000441FFFDD9 -:1071C0002463000424A5000100A6702B15C0FFF560 -:1071D000000569C00A0006A58FBF00189787001C2C -:1071E0003C04080024845A58240504000E0006605C -:1071F00024060001978B002424440001308AFFFFFD -:107200002569FFFF2D48040000402821150000409B -:10721000A789002424AC3800000C19C00A0006B964 -:10722000A780001C9787001E3C04080024845AD8BD -:10723000240504000E00066024060001979900262C -:10724000244400013098FFFF272FFFFF2F0E04007A -:107250000040882115C0002CA78F0026A780001EA3 -:107260003A020003262401003084FFFF0E00068D41 -:107270002C4500010011F8C027F00100001021C0CA -:107280000A0006BB240200089785002E978700227B -:107290003C04080024845B580E00066024060001AC -:1072A0009787002A8F89002C2445000130A8FFFF12 -:1072B00024E3FFFF0109302B0040802114C0001897 -:1072C000A783002AA7800022978500300E000F7543 -:1072D00002002021244A05003144FFFF0E00068DE4 -:1072E000240500013C05080094A500320E000F752E -:1072F00002002021244521003C0208009042003376 -:107300000A0006BB000521C00A0006F3A784001E80 -:1073100024AC3800000C19C00A0006B9A784001C70 -:107320000A00070DA7850022308400FF27BDFFE873 -:107330002C820006AFBF0014AFB000101040001543 -:1073400000A03821000440803C0308002463579CBF -:10735000010328218CA40000008000080000000028 -:1073600024CC007F000751C2000C59C23170FFFFCE -:107370002547C40030E5FFFF2784001C02003021B0 -:107380000E0005B52407000197860028020620217B -:10739000A78400288FBF00148FB0001003E00008FE -:1073A00027BD00183C0508008CA50030000779C2F5 -:1073B0000E00038125E4DF003045FFFF3C04080098 -:1073C00024845B58240600010E0005B52407000143 -:1073D000978E002A8FBF00148FB0001025CD0001BA -:1073E00027BD001803E00008A78D002A0007C9C2C6 -:1073F0002738FF00001878C231F0FFFF3C04080076 -:1074000024845AD802002821240600010E0005B564 -:1074100024070001978D0026260E0100000E84002F -:1074200025AC00013C0B6000A78C0026AD603D0838 -:1074300036040006000030213C0760008CE23D0469 -:10744000305F000617E0FFFD24C9000100061B00A5 -:10745000312600FF006440252CC50004ACE83D0443 -:1074600014A0FFF68FBF00148FB0001003E00008D7 -:1074700027BD0018000751C22549C8002406000195 -:10748000240700013C04080024845A580E0005B566 -:107490003125FFFF978700248FBF00148FB00010A5 -:1074A00024E6000127BD001803E00008A786002499 -:1074B0003C0660183C090800252900FCACC9502C8A -:1074C0008CC850003C0580003C020002350700805B -:1074D000ACC750003C04080024841FE03C030800B3 -:1074E00024631F98ACA50008ACA2000C3C01080066 -:1074F000AC2459A43C010800AC2359A803E00008BF -:107500002402000100A030213C1C0800279C59AC3B -:107510003C0C04003C0B0002008B3826008C4026FB -:107520002CE200010007502B2D050001000A4880C5 -:107530003C030800246359A4004520250123182199 -:107540001080000300001021AC660000240200013E -:1075500003E00008000000003C1C0800279C59AC18 -:107560003C0B04003C0A0002008A3026008B3826BF -:107570002CC200010006482B2CE5000100094080C8 -:107580003C030800246359A4004520250103182169 -:1075900010800005000010213C0C0800258C1F986D -:1075A000AC6C00002402000103E0000800000000B1 -:1075B0003C0900023C080400008830260089382677 -:1075C0002CC30001008028212CE400010083102539 -:1075D0001040000B000030213C1C0800279C59ACD7 -:1075E0003C0A80008D4E00082406000101CA68256F -:1075F000AD4D00088D4C000C01855825AD4B000C9D -:1076000003E0000800C010213C1C0800279C59AC76 -:107610003C0580008CA6000C0004202724020001F9 -:1076200000C4182403E00008ACA3000C3C020002D4 -:107630001082000B3C0560003C070400108700032B -:107640000000000003E00008000000008CA908D042 -:10765000240AFFFD012A402403E00008ACA808D05A -:107660008CA408D02406FFFE0086182403E000083E -:10767000ACA308D03C05601A34A600108CC300806F -:1076800027BDFFF88CC50084AFA3000093A40000C1 -:107690002402001010820003AFA5000403E00008DC -:1076A00027BD000893A7000114E0001497AC000266 -:1076B00097B800023C0F8000330EFFFC01CF682119 -:1076C000ADA50000A3A000003C0660008CC708D058 -:1076D0002408FFFE3C04601A00E82824ACC508D04A -:1076E0008FA300048FA200003499001027BD00086A -:1076F000AF22008003E00008AF2300843C0B800031 -:10770000318AFFFC014B48218D2800000A00080C3B -:10771000AFA8000427BDFFE8AFBF00103C1C080065 -:10772000279C59AC3C0580008CA4000C8CA2000462 -:107730003C0300020044282410A0000A00A31824DF -:107740003C0604003C0400021460000900A610245A -:107750001440000F3C0404000000000D3C1C080015 -:10776000279C59AC8FBF001003E0000827BD00180C -:107770003C0208008C4259A40040F80900000000B7 -:107780003C1C0800279C59AC0A0008358FBF00102C -:107790003C0208008C4259A80040F8090000000093 -:1077A0000A00083B000000003C0880008D0201B880 -:1077B0000440FFFE35090180AD2400003C031000A9 -:1077C00024040040AD250004A1240008A1260009DE -:1077D000A527000A03E00008AD0301B83084FFFFCD -:1077E0000080382130A5FFFF000020210A00084555 -:1077F000240600803087FFFF8CA400002406003898 -:107800000A000845000028218F8300788F860070C9 -:107810001066000B008040213C07080024E75B68ED -:10782000000328C000A710218C440000246300013D -:10783000108800053063000F5466FFFA000328C06B -:1078400003E00008000010213C07080024E75B6CFF -:1078500000A7302103E000088CC200003C03900028 -:1078600034620001008220253C038000AC640020CB -:107870008C65002004A0FFFE0000000003E000086B -:10788000000000003C0280003443000100832025FA -:1078900003E00008AC44002027BDFFE0AFB10014B6 -:1078A0003091FFFFAFB00010AFBF001812200013DF -:1078B00000A080218CA20000240400022406020003 -:1078C0001040000F004028210E0007250000000096 -:1078D00000001021AE000000022038218FBF0018E8 -:1078E0008FB100148FB0001000402021000028212B -:1078F000000030210A00084527BD00208CA20000AE -:10790000022038218FBF00188FB100148FB00010F3 -:107910000040202100002821000030210A000845F5 -:1079200027BD002000A010213087FFFF8CA5000498 -:107930008C4400000A000845240600068F83FD9C45 -:1079400027BDFFE8AFBF0014AFB00010906700087C -:10795000008010210080282130E600400000202116 -:1079600010C000088C5000000E0000BD0200202155 -:10797000020020218FBF00148FB000100A000548BC -:1079800027BD00180E0008A4000000000E0000BD76 -:1079900002002021020020218FBF00148FB00010B0 -:1079A0000A00054827BD001827BDFFE0AFB0001052 -:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 -:1079C00092060001008088210E00087230D2000467 -:1079D00092040005001129C2A6050000348300406E -:1079E000A20300050E00087C022020210E00054A9B -:1079F0000220202124020001AE02000C02202821D6 -:107A0000A602001024040002A602001224060200AE -:107A1000A60200140E000725A60200161640000F4D -:107A20008FBF001C978C00743C0B08008D6B007896 -:107A30002588FFFF3109FFFF256A0001012A382B45 -:107A400010E00006A78800743C0F6006240E0016A4 -:107A500035ED0010ADAE00508FBF001C8FB2001886 -:107A60008FB100148FB0001003E0000827BD002084 -:107A700027BDFFE0AFB10014AFBF0018AFB00010DA -:107A80001080000400A088212402008010820007DA -:107A9000000000000000000D8FBF00188FB100141F -:107AA0008FB0001003E0000827BD00200E00087210 -:107AB00000A020218F86FD9C0220202190C500057A -:107AC0000E00087C30B000FF2403003E1603FFF1D7 -:107AD0003C0680008CC401780480FFFE34C801405D -:107AE000240900073C071000AD11000002202021EE -:107AF000A10900048FBF00188FB100148FB00010CF -:107B0000ACC701780A0008C527BD002027BDFFE0EB -:107B1000AFB00010AFBF0018AFB100143C10800030 -:107B20008E110020000000000E00054AAE04002067 -:107B3000AE1100208FBF00188FB100148FB000105D -:107B400003E0000827BD00203084FFFF00803821BB -:107B50002406003500A020210A0008450000282145 -:107B60003084FFFF008038212406003600A0202149 -:107B70000A0008450000282127BDFFD0AFB500242A -:107B80003095FFFFAFB60028AFB40020AFBF002C88 -:107B9000AFB3001CAFB20018AFB10014AFB000100B -:107BA00030B6FFFF12A000270000A0218F920058DE -:107BB0008E4300003C0680002402004000033E0289 -:107BC00000032C0230E4007F006698241482001D1C -:107BD00030A500FF8F8300682C68000A1100001098 -:107BE0008F8D0044000358803C0C0800258C57B84A -:107BF000016C50218D4900000120000800000000A8 -:107C000002D4302130C5FFFF0E0008522404008446 -:107C1000166000028F920058AF8000688F8D00447C -:107C20002659002026980001032090213314FFFFDD -:107C300015A00004AF9900580295202B1480FFDC9A -:107C400000000000028010218FBF002C8FB600289A -:107C50008FB500248FB400208FB3001C8FB20018A2 -:107C60008FB100148FB0001003E0000827BD003072 -:107C70002407003414A70149000000009247000EB9 -:107C80008F9FFDA08F90FD9C24181600A3E700197C -:107C90009242000D3C0880003C07800CA3E20018D3 -:107CA000964A00123C0D60003C117FFFA60A005C62 -:107CB000964400103623FFFF240200053099FFFF91 -:107CC000AE1900548E46001CAD1800288CEF000041 -:107CD0008DAE444801E6482601C93021AE06003881 -:107CE0008E05003824CB00013C0E7F00AE05003C21 -:107CF0008E0C003CAFEC0004AE0B00208E13002075 -:107D0000AE13001CA3E0001BAE03002CA3E2001284 -:107D10008E4A001424130050AE0A00348E0400343E -:107D2000AFE400148E590018AE1900489258000CA8 -:107D3000A218004E920D000835AF0020A20F0008D7 -:107D40008E090018012E282434AC4000AE0C001817 -:107D5000920B0000317200FF1253027F2403FF8058 -:107D60003C04080024845BE80E0008AA0000000020 -:107D70003C1108008E315BE80E00087202202021C1 -:107D80002405000424080001A2050025022020216A -:107D90000E00087CA20800053C0580008CB001782C -:107DA0000600FFFE8F92005834AE0140240F0002FF -:107DB0003C091000ADD10000A1CF0004ACA90178AE -:107DC0000A000962AF8000682CAD003751A0FF9413 -:107DD0008F8D0044000580803C110800263157E05B -:107DE000021178218DEE000001C0000800000000A3 -:107DF0002411000414B1008C3C0780003C080800EA -:107E00008D085BE88F86FD9CACE800208E4500085D -:107E10008F99FDA0240D0050ACC500308E4C000899 -:107E2000ACCC00508E4B000CACCB00348E43001019 -:107E3000ACC300388E4A0010ACCA00548E42001405 -:107E4000ACC2003C8E5F0018AF3F00048E50001C97 -:107E5000ACD0002090C40000309800FF130D024AFF -:107E6000000000008CC400348CD00030009030231F -:107E700004C000F12404008C126000EE2402000310 -:107E80000A000962AF8200682419000514B900666F -:107E90003C0580003C0808008D085BE88F86FD9C4F -:107EA000ACA800208E4C00048F8AFDA0240720007F -:107EB000ACCC001C924B000824120008A14B001906 -:107EC0008F82005890430009A14300188F85005805 -:107ED00090BF000A33E400FF1092001028890009C7 -:107EE000152000BA240E0002240D0020108D000B76 -:107EF000340780002898002117000008240740005C -:107F000024100040109000053C0700012419008057 -:107F1000109900023C070002240740008CC20018A0 -:107F20003C03FF00004350240147F825ACDF001854 -:107F300090B2000BA0D200278F8300589464000CED -:107F4000108001FE000000009467000C3C1F8000C0 -:107F50002405FFBFA4C7005C9063000E2407000443 -:107F6000A0C300088F820058904A000FA0CA0009E1 -:107F70008F8900588D3200108FE400740244C823AA -:107F8000ACD900588D300014ACD0002C95380018B6 -:107F9000330DFFFFACCD00409531001A322FFFFFAB -:107FA000ACCF00448D2E001CACCE00489128000EB2 -:107FB000A0C8000890CC000801855824126001B6C2 -:107FC000A0CB00088F9200580A000962AF870068B2 -:107FD0002406000614A600143C0E80003C0F080086 -:107FE0008DEF5BE88F85FD98ADCF00208E4900189E -:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B -:1080000024040005ACA800048CCC003C1260008164 -:10801000AD6C00000A000962AF84006824110007FB -:1080200010B1004B240400063C05080024A55BE8C1 -:108030000E000881240400818F9200580013102B39 -:108040000A000962AF820068241F002314BFFFF6F4 -:108050003C0C80003C0508008CA55BE88F8BFDA0E4 -:10806000AD8500208F91FD9C8E4600042564002084 -:1080700026450014AE260028240600030E000F81BA -:10808000257000308F87005802002021240600034D -:108090000E000F8124E500083C04080024845BE8FE -:1080A0000E0008AA0000000092230000240A0050DD -:1080B000306200FF544AFFE18F9200580E000F6CAF -:1080C000000000000A000A6A8F920058240800335A -:1080D00014A800323C0380003C1108008E315BE89C -:1080E0008F8FFDA0AC7100208E420008240D002867 -:1080F0008F89FD9CADE200308E4A000C24060009F9 -:10810000ADEA00348E5F0010ADFF00388E440014DD -:10811000ADE400208E590018ADF900248E58001CE3 -:10812000ADF80028A1ED00118E4E00041260003160 -:10813000AD2E00288F9200580A000962AF860068B1 -:10814000240D002214ADFFB8000000002404000735 -:108150003C1008008E105BE83C188000AF10002037 -:108160005660FEAEAF8400683C04080024845BE8DF -:108170000E0008AA241300508F84FD9C90920000EA -:10818000325900FF1333014B000000008F9200585A -:10819000000020210A000962AF8400683C05080045 -:1081A00024A55BE80E000858240400810A000A6A2E -:1081B0008F92005802D498213265FFFF0E000852BA -:1081C000240400840A0009628F920058108EFF5325 -:1081D000240704002887000310E00179241100041B -:1081E000240F0001548FFF4D240740000A000A228B -:1081F000240701003C05080024A55BE80E0008A444 -:10820000240400828F920058000030210A00096285 -:10821000AF8600683C04080024845BE88CC2003808 -:108220000E0008AA8CC3003C8F9200580A000AC0B6 -:1082300000002021240400823C05080024A55BE8FE -:108240000E0008A4000000008F92005800001021CA -:108250000A000962AF8200688E5000048F91FD9C75 -:108260003C078000ACF00020922C00050200282181 -:10827000318B0002156001562404008A8F92FDA004 -:108280002404008D9245001B30A6002014C001502C -:1082900002002821922E00092408001231C900FF93 -:1082A0001128014B240400810E00087202002021D5 -:1082B0009258001B240F000402002021370D0042B9 -:1082C000A24D001B0E00087CA22F00253C0580005B -:1082D0008CA401780480FFFE34B90140241F000201 -:1082E000AF300000A33F00048F9200583C101000F4 -:1082F000ACB001780A000A6B0013102B8E500004FA -:108300008F91FD9C3C038000AC700020922A0005F8 -:108310000200282131420002144000172404008A80 -:10832000922C00092412000402002821318B00FF46 -:1083300011720011240400810E0008720200202135 -:108340008F89FDA0240800122405FFFE912F001B39 -:108350000200202135EE0020A12E001BA2280009DA -:108360009226000500C538240E00087CA2270005CF -:1083700002002821000020210E0009330000000027 -:108380000A000A6A8F9200588E4C00043C07800055 -:108390003C10080026105BE8ACEC00203C01080013 -:1083A000AC2C5BE8924B0003317100041220013BBE -:1083B0008F84FD9C24020006A0820009924F001BBE -:1083C000240EFFC031E9003F012E4025A08800089F -:1083D0009245000330A6000114C0013200000000E5 -:1083E0008E420008AE0200083C0208008C425BF09E -:1083F000104001318F90FDA0000219C28F8DFD9CAD -:10840000A603000C8E4A000C24180001240400145A -:10841000AE0A002C8E420010AE02001C965F0016C1 -:10842000A61F003C96590014A619003EADB8000CDA -:10843000A5B80010A5B80012A5B80014A5B800167C -:1084400012600144A2040011925100033232000272 -:108450002E5300018F920058266200080A0009621C -:10846000AF8200688E4400043C1980003C068008FE -:10847000AF2400208E45000890D80000240D005045 -:10848000331100FF122D009C2407008824060009E8 -:108490000E000845000000000A000A6A8F9200588A -:1084A0008E5000043C0980003C118008AD30002053 -:1084B0009228000024050050310400FF10850110AF -:1084C0002407008802002021000028210E00084512 -:1084D0002406000E922D00002418FF80020028219F -:1084E00001B8802524040004240600300E0007256E -:1084F000A23000000A000A6A8F9200588E500004D1 -:108500008F91FDA03C028000AC500020923F001BE8 -:1085100033F900101320006C240700810200202191 -:10852000000028212406001F0E000845000000005E -:108530000A000A6A8F9200588E44001C0E00085DE3 -:1085400000000000104000E3004048218F880058E0 -:1085500024070089012020218D05001C240600012C -:108560000E000845000000000A000A6A8F920058B9 -:10857000964900023C10080026105BE831280004F0 -:10858000110000973C0460008E4E001C3C0F8000E0 -:10859000ADEE00203C010800AC2E5BE896470002DF -:1085A00030E40001148000E6000000008E42000468 -:1085B000AE0200083C1008008E105BF0120000ECC8 -:1085C0003C0F80008F92FD9C241000018E4E0018FD -:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 -:1085E000A2400005AE50000C3C0808008D085BF06E -:1085F0008F840058A6500010000839C2A6500012FF -:10860000A6500014A6500016A5A7000C8C8C0008DC -:108610008F8B00588F8A0058ADAC002C8D63000CF6 -:1086200024070002ADA3001C91460010A1A6001172 -:108630008F82005890450011A3E500088F990058DB -:1086400093380012A258004E8F910058922F0013B9 -:10865000A1AF00128F920058964E0014A5AE003CB8 -:1086600096490016A5A9003E8E480018ADA8001432 -:108670005660FD6AAF8700683C05080024A55BE8EA -:108680000E000881000020218F9200580000382140 -:108690000A000962AF8700683C05080024A55BE872 -:1086A0000E0008A4240400828F9200580A000A4D8C -:1086B000000038210E000F6C000000008F9200585F -:1086C0000A000AC0000020210E00087202002021CA -:1086D0009223001B02002021346A00100E00087C47 -:1086E000A22A001B000038210200202100002821BE -:1086F0000A000BA52406001F9242000C305F000107 -:1087000013E0000300000000964A000EA4CA002CEB -:10871000924B000C316300025060000600003821CB -:108720008E470014964C0012ACC7001CA4CC001A53 -:10873000000038210A000B7F240600093C050800D0 -:1087400024A55BE80E0008A42404008B8F92005837 -:108750000A000A4D0013382B3C0C08008D8C5BE896 -:1087600024DFFFFE25930100326B007F016790211B -:1087700002638824AD110028AE4600E0AE4000E45C -:108780000A0009B3AE5F001CACC000543C0D0800E9 -:108790008DAD5BE83C18800C37090100ACED00287A -:1087A0008E510014AD3100E08E4F0014AD2F00E467 -:1087B0008E4E001025C7FFFE0A0009F4AD27001CED -:1087C0005491FDD6240740000A000A222407100015 -:1087D0000E00092D000000000A000A6A8F9200585E -:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 -:1087F000AC205BE810710062000000003C196C6264 -:1088000037387970147800082404000297850074C2 -:108810009782006C2404009200A2F82B13E0001948 -:1088200002002821240400020E00069524050200FF -:108830003C068000ACC200203C010800AC225BE892 -:108840001040000D8F8C0058240A002824040003D7 -:10885000918B0010316300FF546A00012404000171 -:108860000E0000810000000010400004240400837A -:108870000A000BC28F920058240400833C050800B4 -:1088800024A55BE80E000881000000008F920058CC -:108890000013382B0A000962AF8700680A000B49F1 -:1088A000240200128E4400080E00085D0000000043 -:1088B0000A000B55AE0200083C05080024A55BE841 -:1088C0000E000858240400878F9200580A000B728B -:1088D0000013102B240400040E000695240500301C -:1088E0001440002A004048218F8800582407008344 -:1088F000012020218D05001C0A000BB32406000175 -:108900008F8300788F8600701066FEEE000038219D -:108910003C07080024E75B6C000320C00087282187 -:108920008CAE000011D0005D246F000131E3000F18 -:108930005466FFFA000320C00A000B8C00003821A7 -:108940008E4400040E00085D000000000A000BC801 -:10895000AE0200083C05080024A55BE80E0008A450 -:10896000240400828F9200580A000B72000010212C -:108970003C05080024A55BE80A000C7C2404008761 -:108980008C83442C0A000C5B3C196C628F88005865 -:108990003C0780083C0C8000240B0050240A000196 -:1089A000AD820020A0EB0000A0EA000191030004CA -:1089B000A0E3001891040005A0E400199106000648 -:1089C0003C04080024845B6CA0E6001A91020007B6 -:1089D0003C06080024C65B68A0E2001B9105000865 -:1089E000A0E5001C911F0009A0FF001D9119000ABD -:1089F000A0F9001E9118000BA0F8001F9112000CA6 -:108A0000A0F200209111000DA0F100219110000EA4 -:108A1000A0F00022910F000FA0EF0023910E001094 -:108A2000A0EE0024910D0011A0ED0025950C00147E -:108A3000A4EC0028950B00168F8A00708F920078A6 -:108A4000A4EB002A95030018000A10C02545000178 -:108A5000A4E3002C8D1F001C0044C0210046C82147 -:108A600030A5000FAF3F0000AF09000010B20006B4 -:108A7000AF850070000038218D05001C01202021E9 -:108A80000A000BB32406000124AD000131A7000F3A -:108A9000AF8700780A000CF9000038213C06080076 -:108AA00024C65B680086902100003821ACA000003D -:108AB0000A000B8CAE4000003C0482013C036000C5 -:108AC00034820E02AC603D68AF80009803E000087D -:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 -:108AE000001018422C620041AFBF00141440000275 -:108AF00024040080240300403C010800AC300060E6 -:108B00003C010800AC2300640E000F7500602821B2 -:108B1000244802BF2409FF8001092824001039805D -:108B2000001030408FBF00148FB0001000A720212C -:108B300000861821AF8300803C010800AC25005856 -:108B40003C010800AC24005C03E0000827BD0018CD -:108B5000308300FF30C6FFFF30E400FF3C08800098 -:108B60008D0201B80440FFFE000354000144382583 -:108B70003C09600000E920253C031000AD050180A0 -:108B8000AD060184AD04018803E00008AD0301B81F -:108B90008F8500583C0A6012354800108CAC0004E8 -:108BA0003C0D600E35A60010318B00062D690001CA -:108BB000AD0900C48CA70004ACC731808CA20008AA -:108BC00094A40002ACC231848CA3001C0460000396 -:108BD000A784009003E00008000000008CAF00189C -:108BE000ACCF31D08CAE001C03E00008ACCE31D449 -:108BF0008F8500588F87FF288F86FF308CAE00044A -:108C00003C0F601235E80010ACEE00788CAD000827 -:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 -:108C2000ACCB004894CA00543C0208008C4200447B -:108C300025490001A4C9005494C400543083FFFFA7 -:108C400010620017000000003C0208008C42004047 -:108C5000A4C200528CA30018ACE300308CA2001414 -:108C6000ACE2002C8CB90018ACF900388CB80014B8 -:108C700024050001ACF800348D0600BC50C5001975 -:108C80008D0200B48D0200B8A4E2004894E40048CC -:108C9000A4E4004A94E800EA03E000083102FFFF80 -:108CA0003C0208008C420024A4C00054A4C200521C -:108CB0008CA30018ACE300308CA20014ACE2002CB2 -:108CC0008CB90018ACF900388CB8001424050001E8 -:108CD000ACF800348D0600BC54C5FFEB8D0200B823 -:108CE0008D0200B4A4E2004894E40048A4E4004AE1 -:108CF00094E800EA03E000083102FFFF8F86005885 -:108D00003C0480008CC900088CC80008000929C0F8 -:108D1000000839C0AC87002090C30007306200040F -:108D20001040003EAF85009490CB0007316A0008E8 -:108D30001140003D8F87FF2C8CCD000C8CCE001491 -:108D400001AE602B11800036000000008CC2000CC8 -:108D5000ACE200708CCB00188F85FF288F88FF3025 -:108D6000ACEB00748CCA00102402FFF8ACAA00D847 -:108D70008CC9000CAD0900608CC4001CACA400D0F0 -:108D800090E3007C0062C824A0F9007C90D8000722 -:108D9000330F000811E000040000000090ED007C9B -:108DA00035AC0001A0EC007C90CF000731EE000153 -:108DB00011C000060000000090E3007C241800347D -:108DC00034790002A0F9007CACB800DC90C2000746 -:108DD0003046000210C000040000000090E8007C53 -:108DE00035040004A0E4007C90ED007D3C0B600E97 -:108DF000356A001031AC003FA0EC007D8D4931D4C4 -:108E00003127000110E00002240E0001A0AE00098D -:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 -:108E20000A000DAF8CC200140A000DB0ACE0007057 -:108E30008F8C005827BDFFD8AFB3001CAFB200180D -:108E4000AFB00010AFBF0020AFB10014918F00157C -:108E50003C13600E3673001031EB000FA38B009CA7 -:108E60008D8F00048D8B0008959F0012959900103E -:108E70009584001A9598001E958E001C33EDFFFF17 -:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 -:108E90003C010800AC2D00243C010800AC29004432 -:108EA0003C010800AC2A0040AE683178AE67317CE6 -:108EB00091850015959100163C12601236520010F3 -:108EC00030A200FF3230FFFFAE623188AE5000B4F6 -:108ED00091830014959F0018240600010066C804C1 -:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 -:108EF000AF8F00843C08600631CD00FFAE4D00C04E -:108F0000918A00159584000E3C07600A314900FFE4 -:108F1000AF8B00883084FFFFAE4900C835110010C8 -:108F20000E000D1034F004103C0208008C4200606A -:108F30003C0308008C6300643C0608008CC60058A3 -:108F40003C0508008CA5005C8F8400808FBF00204A -:108F5000AE23004CAE65319CAE030054AE4500DC40 -:108F6000AE6231A0AE6331A4AE663198AE22004845 -:108F70008FB3001CAE0200508FB10014AE4200E06F -:108F8000AE4300E4AE4600D88FB000108FB2001898 -:108F90000A00057D27BD0028978500929783007CF5 -:108FA00027BDFFE8AFB0001000A3102BAFBF001427 -:108FB000240400058F900058104000552409000239 -:108FC0000E0006958F850080AF8200942404000374 -:108FD0001040004F240900023C0680000E00008172 -:108FE000ACC2002024070001240820001040004DDE -:108FF00024040005978E00928F8AFF2C24090050CC -:1090000025C50001A7850092A14900003C0D08007C -:109010008DAD0064240380008F84FF28000D66005E -:10902000AD4C0018A5400006954B000A8F85FF3017 -:109030002402FF8001633024A546000A915F000AE4 -:109040000000482103E2C825A159000AA0A0000899 -:10905000A140004CA08000D5961800029783009094 -:109060003C020004A49800EA960F00022418FFBFF7 -:1090700025EE2401A48E00BE8E0D0004ACAD00448C -:109080008E0C0008ACAC0040A4A00050A4A000547A -:109090008E0B000C240C0030AC8B00288E060010C8 -:1090A000AC860024A480003EA487004EA487005014 -:1090B000A483003CAD420074AC8800D8ACA800602A -:1090C000A08700FC909F00D433F9007FA09900D4C2 -:1090D000909000D402187824A08F00D4914E007C88 -:1090E00035CD0001A14D007C938B009CAD480070F4 -:1090F000AC8C00DCA08B00D68F8800888F87008422 -:10910000AC8800C4AC8700C8A5400078A540007AB0 -:109110008FBF00148FB000100120102103E0000861 -:1091200027BD00188F8500940E0007258F860080CC -:109130000A000E9F2409000227BDFFE0AFB0001017 -:109140008F900058AFB10014AFBF00188E09000413 -:109150000E00054A000921C08E0800048F84FF28F4 -:109160008F82FF30000839C03C068000ACC7002069 -:10917000948500EA904300131460001C30B1FFFF97 -:109180008F8CFF2C918B0008316A00401540000B3A -:10919000000000008E0D0004022030218FBF001857 -:1091A0008FB100148FB00010240400220000382179 -:1091B000000D29C00A000D2F27BD00200E000098C9 -:1091C000000000008E0D0004022030218FBF001827 -:1091D0008FB100148FB00010240400220000382149 -:1091E000000D29C00A000D2F27BD00200E000090A1 -:1091F000000000008E0D0004022030218FBF0018F7 -:109200008FB100148FB00010240400220000382118 -:10921000000D29C00A000D2F27BD002027BDFFE04B -:10922000AFB200183092FFFFAFB00010AFBF001C0C -:10923000AFB100141240001E000080218F8600583C -:109240008CC500002403000600053F02000514023F -:1092500030E4000714830016304500FF2CA80006F8 -:1092600011000040000558803C0C0800258C58BCBB -:10927000016C50218D490000012000080000000011 -:109280008F8E0098240D000111CD005024020002A1 -:10929000AF820098260900013130FFFF24C800206A -:1092A0000212202B010030211480FFE5AF88005806 -:1092B000020010218FBF001C8FB200188FB1001464 -:1092C0008FB0001003E0000827BD00209387007EC8 -:1092D00054E00034000030210E000DE700000000D3 -:1092E0008F8600580A000EFF240200018F87009825 -:1092F0002405000210E50031240400130000282199 -:1093000000003021240700010E000D2F0000000096 -:109310000A000F008F8600588F83009824020002F5 -:109320001462FFF6240400120E000D9A00000000E3 -:109330008F85009400403021240400120E000D2F70 -:10934000000038210A000F008F8600588F83009894 -:109350002411000310710029241F0002107FFFCE8A -:1093600026090001240400100000282100003021FB -:109370000A000F1D240700018F91009824060002A7 -:109380001626FFF9240400100E000E410000000014 -:10939000144000238F9800588F8600580A000EFF53 -:1093A00024020003240400140E000D2F00002821C5 -:1093B0008F8600580A000EFF240200020E000EA93C -:1093C000000000000A000F008F8600580E000D3FBD -:1093D00000000000241900022404001400002821C9 -:1093E0000000302100003821AF9900980E000D2FA9 -:1093F000000000000A000F008F8600580E000D5775 -:10940000000000008F8500942419000200403021E4 -:1094100024040010000038210A000F56AF9900986C -:109420000040382124040010970F0002000028217A -:109430000E000D2F31E6FFFF8F8600580A000F0047 -:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D -:109450008C8500182402000100A61824AC83001893 -:1094600003E00008A08200053084FFFF30A5FFFF65 -:109470001080000700001821308200011040000217 -:1094800000042042006518211480FFFB00052840DD -:1094900003E000080060102110C000070000000079 -:1094A0008CA2000024C6FFFF24A50004AC820000AB -:1094B00014C0FFFB2484000403E000080000000047 -:1094C00010A0000824A3FFFFAC86000000000000ED -:1094D000000000002402FFFF2463FFFF1462FFFA74 -:1094E0002484000403E0000800000000000411C010 -:1094F00003E000082442024027BDFFE8AFB000109F -:1095000000808021AFBF00140E000F9600A0202124 -:1095100000504821240AFF808FBF00148FB0001034 -:10952000012A30243127007F3C08800A3C042100B6 -:1095300000E8102100C428253C03800027BD001846 -:10954000AC650024AF820038AC400000AC6500245C -:1095500003E00008AC4000403C0D08008DAD005811 -:1095600000056180240AFF8001A45821016C482174 -:10957000012A30243127007F3C08800C3C04210064 -:1095800000E8102100C428253C038000AC650028B9 -:10959000AF82003403E00008AC40002430A5FFFF98 -:1095A0003C0680008CC201B80440FFFE3C086015F8 -:1095B00000A838253C031000ACC40180ACC0018475 -:1095C000ACC7018803E00008ACC301B83C0D08003B -:1095D0008DAD005800056180240AFF8001A4582148 -:1095E000016C4021010A4824000931403107007F05 -:1095F00000C728253C04200000A418253C02800058 -:10960000AC43083003E00008AF80003427BDFFE81A -:10961000AFB0001000808021AFBF00140E000F9685 -:1096200000A0202100504821240BFF80012B502452 -:10963000000A39403128007F3C0620008FBF00140B -:109640008FB0001000E8282534C2000100A21825C0 -:109650003C04800027BD0018AC83083003E00008FC -:10966000AF8000383C0580088CA700603C0680086D -:109670000087102B144000112C8340008CA8006040 -:109680002D0340001060000F240340008CC90060CF -:109690000089282B14A00002008018218CC30060D0 -:1096A00000035A42000B30803C0A0800254A59202A -:1096B00000CA202103E000088C8200001460FFF340 -:1096C0002403400000035A42000B30803C0A08008B -:1096D000254A592000CA202103E000088C8200009E -:1096E0003C05800890A60008938400AB24C20001CA -:1096F000304200FF3043007F1064000C0002382726 -:10970000A0A200083C0480008C85017804A0FFFE24 -:109710008F8A00A0240900023C081000AC8A014096 -:10972000A089014403E00008AC8801780A00101BFE -:1097300030E2008027BDFFD8AFB200188F9200A49E -:10974000AFBF0020AFB3001CAFB00010AFB100142A -:109750008F9300348E5900283C1000803C0EFFEFA0 -:10976000AE7900008E580024A260000A35CDFFFFBC -:10977000AE7800049251002C3C0BFF9F356AFFFF2E -:10978000A271000C8E6F000C3C080040A271000B0F -:1097900001F06025018D4824012A382400E8302595 -:1097A000AE66000C8E450004AE6000183C0400FF5D -:1097B000AE6500148E43002C3482FFFFA6600008C3 -:1097C0000062F824AE7F00108E5900088F9000A030 -:1097D000964E0012AE7900208E51000C31D83FFF1A -:1097E00000187980AE7100248E4D001401F06021C4 -:1097F00031CB0001AE6D00288E4A0018000C41C22A -:10980000000B4B80AE6A002C8E46001C01093821EB -:10981000A667001CAE660030964500028E4400200C -:10982000A665001EAE64003492430033306200042B -:1098300054400006924700003C0280083443010077 -:109840008C7F00D0AE7F0030924700008F860038BA -:10985000A0C700309245003330A4000250800007BA -:10986000925100018F880038240BFF80910A00304C -:10987000014B4825A1090030925100018F9000381A -:10988000240CFFBF2404FFDFA21100318F8D0038AC -:109890003C1880083711008091AF003C31EE007F0A -:1098A000A1AE003C8F890038912B003C016C502404 -:1098B000A12A003C8F9F00388E68001493E6003C7C -:1098C0002D0700010007114000C4282400A218251C -:1098D000A3E3003C8F87003896590012A4F90032A8 -:1098E0008E450004922E007C30B0000300107823D7 -:1098F00031ED000300AD102131CC000215800002D3 -:1099000024460034244600303C0280083443008062 -:10991000907F007C00BFC824333800041700000289 -:1099200024C2000400C010218F98003824190002BE -:10993000ACE20034A3190000924F003F8F8E003834 -:109940003C0C8008358B0080A1CF00018F9100383E -:10995000924D003F8E440004A62D0002956A005CE3 -:109960000E000FF43150FFFF00024B800209382532 -:109970003C08420000E82825AE2500048E4400384B -:109980008F850038ACA400188E460034ACA6001CAD -:10999000ACA0000CACA00010A4A00014A4A0001661 -:1099A000A4A00020A4A00022ACA000248E62001479 -:1099B00050400001240200018FBF00208FB3001C23 -:1099C0008FB200188FB100148FB00010ACA2000845 -:1099D0000A00101327BD002827BDFFC83C058008DA -:1099E00034A40080AFBF0034AFBE0030AFB7002C4E -:1099F000AFB60028AFB50024AFB40020AFB3001C51 -:109A0000AFB20018AFB10014AFB00010948300786B -:109A10009482007A104300512405FFFF0080F0215A -:109A20000A0011230080B821108B004D8FBF003435 -:109A30008F8600A03C1808008F18005C2411FF805E -:109A40003C1680000306782101F18024AED0002C62 -:109A500096EE007A31EC007F3C0D800E31CB7FFF1B -:109A6000018D5021000B4840012AA82196A4000036 -:109A70003C0808008D0800582405FF8030953FFF02 -:109A800001061821001539800067C8210325F82434 -:109A90003C02010003E290253338007F3C11800C2A -:109AA000AED20028031190219250000D320F000415 -:109AB00011E0003702E0982196E3007A96E8007AF8 -:109AC00096E5007A2404800031077FFF24E300013B -:109AD00030627FFF00A4F82403E2C825A6F9007ACB -:109AE00096E6007A3C1408008E94006030D67FFF22 -:109AF00012D400C1000000008E5800188F8400A00E -:109B000002A028212713FFFF0E000FCEAE53002C1A -:109B100097D5007897D4007A12950010000028217C -:109B20003C098008352401003C0A8008914800085F -:109B3000908700D53114007F30E400FF0284302B81 -:109B400014C0FFB9268B0001938E00AB268C000158 -:109B5000008E682115ACFFB78F8600A08FBF003440 -:109B60008FBE00308FB7002C8FB600288FB5002431 -:109B70008FB400208FB3001C8FB200188FB1001477 -:109B80008FB0001000A0102103E0000827BD0038AE -:109B900000C020210E000F99028028218E4B00105A -:109BA0008E4C00308F84003824090002016C502351 -:109BB000AE4A0010A089000096E3005C8E4400309D -:109BC0008F9100380E000FF43070FFFF00024380C9 -:109BD000020838253C02420000E22825AE25000498 -:109BE0008E5F00048F8A00388E590000240B000815 -:109BF000AD5F001CAD590018AD40000CAD40001029 -:109C00009246000A240400052408C00030D000FF5A -:109C1000A550001496580008A55800169251000A45 -:109C20003C188008322F00FFA54F0020964E0008F8 -:109C300037110100A54E0022AD400024924D000BCB -:109C400031AC00FFA54C0002A14B00018E49003051 -:109C50008F830038240BFFBFAC690008A06400307C -:109C60008F9000382403FFDF9607003200E8282495 -:109C700000B51025A6020032921F003233F9003FD2 -:109C800037260040A20600328F8C0038AD800034A9 -:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F -:109CA00031CD007FA18D003C8F84003835EEFFFF61 -:109CB000908A003C014B4824A089003C8F850038E5 -:109CC00090A8003C01033824A0A7003C8E42003439 -:109CD0008F9100383C038008AE2200408E59002C42 -:109CE0008E5F0030033F3023AE26004492300048A0 -:109CF0003218007FA23800488F8800388E4D00301F -:109D00008D0C004801AE582401965024014B482583 -:109D1000AD0900489244000AA104004C964700088F -:109D20008F850038A4A7004E8E5000308E4400303E -:109D30000E0003818C65006092F9007C0002F940FE -:109D4000004028210002110003E2302133360002D6 -:109D500012C00003020680210005B0800216802197 -:109D6000926D007C31B30004126000020005708027 -:109D7000020E80218E4B00308F8800382405800031 -:109D8000316A0003000A4823312400030204182129 -:109D9000AD03003496E4007A96F0007A96F1007AEA -:109DA00032027FFF2447000130FF7FFF0225C824D5 -:109DB000033F3025A6E6007A96F8007A3C120800A8 -:109DC0008E520060330F7FFF11F200180000000078 -:109DD0008F8400A00E000FCE02A028218F8400A047 -:109DE0000E000FDE028028210E001013000000007C -:109DF0000A00111F0000000096F1007A022480245E -:109E0000A6F0007A92EF007A92EB007A31EE00FF32 -:109E1000000E69C2000D6027000C51C03169007F3F -:109E2000012A20250A001119A2E4007A96E6007A98 -:109E300000C5C024A6F8007A92EF007A92F3007A67 -:109E400031F200FF001271C2000E6827000DB1C090 -:109E5000326C007F01962825A2E5007A0A0011D015 -:109E60008F8400A03C0380003084FFFF30A5FFFFFB -:109E7000AC640018AC65001C03E000088C620014A0 -:109E800027BDFFA03C068008AFBF005CAFBE0058F6 -:109E9000AFB70054AFB60050AFB5004CAFB40048F8 -:109EA000AFB30044AFB20040AFB1003CAFB0003838 -:109EB00034C80100910500D590C700083084FFFF29 -:109EC00030A500FF30E2007F0045182AAFA4001043 -:109ED000A7A00018A7A0002610600055AFA000148E -:109EE00090CA00083149007F00A9302324D3FFFF26 -:109EF0000013802B8FB400100014902B02128824C2 -:109F0000522000888FB300143C03800894790052DB -:109F1000947E00508FB60010033EC0230018BC0092 -:109F2000001714030016FC0002C2A82A16A00002A3 -:109F3000001F2C030040282100133C0000072403CD -:109F400000A4102A5440000100A020212885000907 -:109F500014A000020080A021241400083C0C8008FA -:109F60008D860048001459808D88004C3C03800089 -:109F70003169FFFF3C0A0010012A202534710400DA -:109F8000AC660038AF9100A4AC68003CAC64003013 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB0008C6E000031CD002011A0FFFD0014782A26 -:109FC00001F01024104000390000A8213C16800840 -:109FD00092D700083C1280008E44010032F6007FC8 -:109FE0000E000F9902C028218E3900108E44010006 -:109FF0000000902133373FFF0E000FB102E028210F -:10A00000923800003302003F2C500008520000102C -:10A0100000008821000210803C030800246358E4FB -:10A020000043F8218FFE000003C00008000000007C -:10A0300090CF0008938C00AB31EE007F00AE682318 -:10A04000018D58210A0012172573FFFF0000882197 -:10A050003C1E80008FC401000E000FCE02E02821BC -:10A060008FC401000E000FDE02C028211220000F55 -:10A070000013802B8F8B00A426A400010004AC00E9 -:10A08000027298230015AC032578004002B4B02A70 -:10A090000013802B241700010300882102D0102414 -:10A0A000AF9800A41440FFC9AFB700143C07800864 -:10A0B00094E200508FAE00103C05800002A288217F -:10A0C0003C060020A4F10050ACA6003094F40050EF -:10A0D00094EF005201D51823306CFFFF11F4001EDD -:10A0E000AFAC00108CEF004C001561808CF500487F -:10A0F00001EC28210000202100AC582B02A4C02133 -:10A10000030BB021ACE5004CACF600488FB4001056 -:10A110000014902B021288241620FF7C3C03800838 -:10A120008FB300148FBF005C8FBE00583A620001ED -:10A130008FB700548FB600508FB5004C8FB40048D5 -:10A140008FB300448FB200408FB1003C8FB0003815 -:10A1500003E0000827BD006094FE00548CF2004428 -:10A1600033C9FFFE0009C8C00259F821ACBF003C4A -:10A170008CE800448CAD003C010D50231940003B9D -:10A18000000000008CF7004026E20001ACA200387D -:10A190003C05005034A700103C038000AC67003041 -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C0008C7800003316002012C0FFFD3C1180087F -:10A1D000962200543C1580003C068008304E000159 -:10A1E000000E18C0007578218DEC04003C070800B3 -:10A1F0008CE700443C040020ACCC00488DF40404FF -:10A20000240B0001ACD4004C10EB0260AEA4003073 -:10A21000963900523C0508008CA5004000B99021F9 -:10A22000A6320052963F005427ED0001A62D00549F -:10A230009626005430C4FFFF5487FF2F8FB40010C0 -:10A2400030A5FFFF0E0011F4A62000543C070800C3 -:10A250008CE70024963E00520047B82303D74823DA -:10A26000A62900520A0012198FB400108CE2004097 -:10A270000A0012BE00000000922400012407000121 -:10A280003085007F14A7001C97AD00268E2B00148C -:10A29000240CC000316A3FFF01AC48243C06080092 -:10A2A0008CC60060012A402531043FFF0086882BC0 -:10A2B00012200011A7A800263C0508008CA5005814 -:10A2C0008F9100A0000439802402FF8000B1182182 -:10A2D0000067F82103E2F02433F8007F3C1280008D -:10A2E0003C19800EAE5E002C0319702191D0000D38 -:10A2F000360F0004A1CF000D0E001028241200011B -:10A30000241100013C1E80008FC401000E000FCEFE -:10A3100002E028218FC401000E000FDE02C02821B8 -:10A320001620FF558F8B00A40A0012860013802B85 -:10A330008F8600A490C80001310400201080019194 -:10A34000241000013C048008348B0080916A007C5A -:10A350008F9E0034AFA0002C314900011120000F66 -:10A36000AFB000288CCD00148C8E006001AE602B45 -:10A370001580000201A038218C8700603C188008FD -:10A38000370300808C70007000F0782B15E000021D -:10A3900000E020218C640070AFA4002C3C028008F7 -:10A3A000344500808CD200148CBF0070025FC82B33 -:10A3B00017200002024020218CA400708FA7002CDF -:10A3C0000087182310600003AFA3003024050002AB -:10A3D000AFA500288FA400280264882B162000BA9D -:10A3E000000018218CD000388FCE000C3C0F00806C -:10A3F000AFD000008CCD00343C0CFF9F01CF58251E -:10A40000AFCD000490CA003F3586FFFF01662024CF -:10A410003C0900203C08FFEFA3CA000B0089382547 -:10A420003511FFFF00F118243C0500088F8700A4B8 -:10A430000065C825AFD9000C8CE20014AFC000182D -:10A440008FA60030AFC200148CF800188FB0002C1B -:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A -:10A4600003326824AFCF00248CEC000C020670216C -:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B -:10A48000AFCC0020AFC000288CEA00148FAB002CAA -:10A49000014B48230126402311000011AFC80010D2 -:10A4A00090EB003D8FC900048FC80000000B5100E5 -:10A4B000012A28210000102100AA882B010218215E -:10A4C0000071F821AFC50004AFDF000090F2003D3D -:10A4D000A3D2000A8F9900A497380006A7D80008D5 -:10A4E0008F910038240800023C038008A228000055 -:10A4F0003465008094BF005C8FA4002C33F0FFFF14 -:10A500000E000FF48F9200380002CB808F8500A4DC -:10A51000021978253C18420001F87025AE4E00045F -:10A520008F8400388CAD0038AC8D00188CAC0034B2 -:10A53000AC8C001CAC80000CAC800010A48000141B -:10A54000A4800016A4800020A4800022AC800024F7 -:10A5500090A6003F8FA7002CA486000250E0019235 -:10A56000240700018FA200305040000290A2003D5D -:10A5700090A2003E244A0001A08A00018F84003886 -:10A580008FA9002CAC8900083C128008364D008051 -:10A5900091AC007C3186000214C000022407003414 -:10A5A000240700308F8500A43C198008373F0080C5 -:10A5B00090B0000093F9007C240E0004A0900030BD -:10A5C0008F8F00A48FB8002C8F8D003891F200017E -:10A5D0003304000301C46023A1B200318F8E003820 -:10A5E0008F8600A42402C00095CA003294C90012CC -:10A5F0008FAB002C0142402431233FFF010388250B -:10A60000A5D1003291D000323185000300EBF82152 -:10A610003218003F370F0040A1CF00328FA4002C2A -:10A6200003E5382133280004108000028F850038AC -:10A6300000E838213C0A8008ACA700343549010005 -:10A640008D2800D08FA3002C2419FFBFACA80038A0 -:10A6500090B1003C2C640001240FFFDF3227007F03 -:10A66000A0A7003C8F98003800049140931F003C45 -:10A6700003F98024A310003C8F8C0038918E003C9D -:10A6800001CF682401B23025A186003C8F8900A447 -:10A690008F8800388D2B0020AD0B00408D220024C8 -:10A6A000AD0200448D2A0028AD0A00488D23002CFD -:10A6B0000E001013AD03004C8FB1002824070002D8 -:10A6C000122700118FA300280003282B00058023E8 -:10A6D0000270982400608021006090210A00126FAF -:10A6E0000010882B962900128F8400A00000902172 -:10A6F0003125FFFFA7A900180E000FC22411000189 -:10A700000A00131D3C1E80003C0B80003C12800898 -:10A710008D640100924900088F92FF340E000F995A -:10A720003125007F8F9900388FA700288FA4003033 -:10A73000A3270000965F005C33F0FFFF0E000FF4CC -:10A740008F91003800026B80020D80253C0842008A -:10A750008F8D00A402085025AE2A00048DA5003874 -:10A760008F8A003800007821000F1100AD450018D5 -:10A770008DB800343C047FFF3488FFFFAD58001CC7 -:10A7800091A6003E8D4C001C8D4900180006190052 -:10A79000000677020183C821004E58250323882B29 -:10A7A000012B382100F1F821AD59001CAD5F0018D4 -:10A7B000AD40000CAD40001091B0003E8FA40030C1 -:10A7C00024090005A550001495A500042419C00013 -:10A7D00000884024A545001691B8003EA5580020E9 -:10A7E00095AF0004A54F0022AD40002491AE003F7C -:10A7F000A54E000291A6003E91AC003D01861023BB -:10A80000244B0001A14B00018F9100388FA3003031 -:10A810003C028008344B0100AE230008A22900301E -:10A820008F8C00388F8700A4959F003294F000121F -:10A830002407FFBF033FC02432053FFF03057825EF -:10A84000A58F0032918E00322418FFDF31CD003FFA -:10A8500035A60040A18600328F910038240DFFFFFD -:10A86000240CFF80AE2000348D6A00D0AE2A003860 -:10A870009223003C3069007FA229003C8F90003871 -:10A880003C0380009219003C0327F824A21F003CDF -:10A890008F8E003891C5003C00B87824A1CF003CD1 -:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA -:10A8B000AD46004491420048004C5825A14B004849 -:10A8C0008F9000388F9900A48E09004801238824B6 -:10A8D00002283825AE070048933F003EA21F004CD7 -:10A8E0008F9800A48F8F003897050004A5E5004ECF -:10A8F0000E0003818DC500609246007C8FAC003055 -:10A9000000026940000291000040282130CB000283 -:10A9100001B21021156000AA018230213C0E80088E -:10A9200035C20080904C007C31830004106000032D -:10A930008FB900300005788000CF3021241F00043B -:10A940008F910038332D000303ED8023320800037C -:10A9500000C85021AE2A00343C188000A7C500383A -:10A960003C0680088F04010090DE00080E000FDE18 -:10A9700033C5007F0E001013000000000A00140D04 -:10A980008FA300288F9800348CC90038241F00033F -:10A99000A7000008AF0900008CC50034A300000A1E -:10A9A0008F9900A4AF0500043C080080932D003F60 -:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D -:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E -:10A9D00003D170243646FFFF01C61824AF03000CD4 -:10A9E0008F2C0014972900128F8400A0AF0C001048 -:10A9F0008F2F0014AF000018AF000020AF0F00141D -:10AA0000AF0000248F270018312F3FFF000F59801F -:10AA1000AF0700288F2500080164F821312D0001BF -:10AA2000AF0500308F31000C8F920038001F51C2EB -:10AA3000000D438001481021241E00023C068008BE -:10AA4000A702001CA7000034AF11002CA25E00007A -:10AA500034D20080964E005C8F9900383C0342004F -:10AA600031CCFFFF01833825AF2700048F8B00A472 -:10AA7000240500012402C0008D640038240700343E -:10AA8000AF2400188D690034AF29001CAF20000CE2 -:10AA9000AF200010A7200014A7200016A720002038 -:10AAA000A7200022AF200024A7300002A325000128 -:10AAB0008F8800388F9F00A4AD10000893ED000030 -:10AAC000A10D00308F8A00A48F98003891510001A9 -:10AAD000A31100318F8B0038957E003203C27024A1 -:10AAE00001CF6025A56C0032916300323064003FD5 -:10AAF000A16400329249007C3125000214A00002BA -:10AB00008F840038240700303C198008AC8700345B -:10AB1000373201008E5F00D0240AFFBF020090216F -:10AB2000AC9F0038908D003C31A8007FA088003C8D -:10AB30008F9E003893C2003C004A8824A3D1003C79 -:10AB40008F8300380010882B9066003C34CE0020A4 -:10AB5000A06E003C8F8400A48F9800388C8C00205D -:10AB6000AF0C00408C8F0024AF0F00448C8700286E -:10AB7000AF0700488C8B002CAF0B004C0E0010135D -:10AB80003C1E80000A0012700000000094C80052B1 -:10AB90003C0A08008D4A002401488821A4D10052B3 -:10ABA0000A0012198FB40010A08700018F840038AA -:10ABB000240B0001AC8B00080A0013BE3C12800875 -:10ABC000000520800A0014A200C4302127BDFFE048 -:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 -:10ABE000AFB1001435B200808E4C001835A80100BA -:10ABF000964B000695A70050910900FC000C5602E8 -:10AC0000016728233143007F312600FF240200031F -:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC -:10AC2000910600FC2412000530C200FF10520033D0 -:10AC300000000000160000098FBF001C8FB2001832 -:10AC40008FB100148FB00010240D0C003C0C80005C -:10AC500027BD002003E00008AD8D00240E0011FB8D -:10AC6000020020218FBF001C8FB200188FB100148A -:10AC70008FB00010240D0C003C0C800027BD00207C -:10AC800003E00008AD8D0024965800789651007AB4 -:10AC9000924E007D0238782631E8FFFF31C400C0B3 -:10ACA000148000092D11000116000037000000007B -:10ACB0005620FFE28FBF001C0E0010D100000000E4 -:10ACC0000A00156A8FBF001C1620FFDA0000000082 -:10ACD0000E0010D1000000001440FFD88FBF001CF0 -:10ACE0001600002200000000925F007D33E2003F6A -:10ACF000A242007D0A00156A8FBF001C950900EA78 -:10AD00008F86008000802821240400050E0007257E -:10AD10003130FFFF978300923C0480002465FFFFE1 -:10AD2000A78500928C8A01B80540FFFE0000000054 -:10AD3000AC8001808FBF001CAC9001848FB20018E2 -:10AD40008FB100148FB000103C0760133C0B100053 -:10AD5000240D0C003C0C800027BD0020AC8701882E -:10AD6000AC8B01B803E00008AD8D00240E0011FB90 -:10AD7000020020215040FFB18FBF001C925F007D78 -:10AD80000A00159733E2003F0E0011FB020020215C -:10AD90001440FFAA8FBF001C122000070000000013 -:10ADA0009259007D3330003F36020040A242007DC0 -:10ADB0000A00156A8FBF001C0E0010D100000000B1 -:10ADC0005040FF9E8FBF001C9259007D3330003FE2 -:08ADD0000A0015C6360200401E -:08ADD800000000000000001B58 -:10ADE0000000000F0000000A00000008000000063C -:10ADF0000000000500000005000000040000000441 -:10AE00000000000300000003000000030000000336 -:10AE10000000000300000002000000020000000229 -:10AE2000000000020000000200000002000000021A -:10AE3000000000020000000200000002000000020A -:10AE400000000002000000020000000200000002FA -:0CAE5000000000010000000100000001F3 -:04AE5C008008010069 -:10AE6000800800808008000000000C000000308096 -:10AE7000080011D00800127C08001294080012A8E3 -:10AE8000080012BC080011D0080011D0080012F010 -:10AE90000800132C080013400800138808001A8CBF -:10AEA00008001A8C08001AC408001AC408001AD82E -:10AEB00008001AA808001D0008001CCC08001D5836 -:10AEC00008001D5808001DE008001D108008024001 -:10AED000080027340800256C0800275C080027F4C8 -:10AEE0000800293C0800298808002AAC080029B479 -:10AEF00008002A38080025DC08002EDC08002EA4F3 -:10AF000008002588080025880800258808002B20CF -:10AF100008002B20080025880800258808002DD06F -:10AF2000080025880800258808002588080025884D -:10AF300008002E0C080025880800258808002588B0 -:10AF4000080025880800258808002588080025882D -:10AF5000080025880800258808002588080025881D -:10AF6000080025880800258808002588080029A8E9 -:10AF7000080025880800258808002E680800258814 -:10AF800008002588080025880800258808002588ED -:10AF900008002588080025880800258808002588DD -:10AFA00008002588080025880800258808002588CD -:10AFB00008002588080025880800258808002588BD -:10AFC00008002CF4080025880800258808002C6853 -:10AFD00008002BC408003CE408003CB808003C848E -:10AFE00008003C5808003C3808003BEC8008010091 -:10AFF00080080080800800008008008008004C6401 -:10B0000008004C9C08004BE408004C6408004C64A9 -:0CB01000080049B808004C6408005050CB -:04B01C000A000C8496 -:10B0200000000000000000000000000D7278703683 -:10B030002E302E3137000000060011030000000002 -:10B0400000000001000000000000000000000000FF -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000809F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E220000000000A000000000000000000000000E4 -:10E2300010000003000000000000000D0000000DB1 -:10E240003C020801244294003C03080124639634F4 -:10E25000AC4000000043202B1480FFFD244200044A -:10E260003C1D080037BD9FFC03A0F0213C100800B6 -:10E27000261032103C1C0801279C94000E001274DA -:10E28000000000000000000D3C02800030A5FFFFF0 -:10E2900030C600FF344301803C0880008D0901B87E -:10E2A0000520FFFE00000000AC6400002404000212 -:10E2B000A4650008A066000AA064000BAC67001803 -:10E2C0003C03100003E00008AD0301B83C0560000A -:10E2D0008CA24FF80440FFFE00000000ACA44FC029 -:10E2E0003C0310003C040200ACA44FC403E000084F -:10E2F000ACA34FF89486000C00A050212488001491 -:10E3000000062B0200051080004448210109182B4B -:10E310001060001100000000910300002C6400094F -:10E320005080000991190001000360803C0D080134 -:10E3300025AD9090018D58218D67000000E0000808 -:10E340000000000091190001011940210109302B42 -:10E3500054C0FFF29103000003E000080000102108 -:10E360000A000CCC25080001910F0001240E000AC0 -:10E3700015EE00400128C8232F38000A1700003D81 -:10E38000250D00028D580000250F0006370E0100F4 -:10E39000AD4E0000910C000291AB000191A400026F -:10E3A00091A60003000C2E00000B3C0000A71025D6 -:10E3B00000041A000043C8250326C025AD580004F8 -:10E3C000910E000691ED000191E7000291E5000336 -:10E3D000000E5E00000D6400016C30250007220075 -:10E3E00000C41025004518252508000A0A000CCC99 -:10E3F000AD430008910F000125040002240800022B -:10E4000055E80001012020210A000CCC00804021A9 -:10E41000910C0001240B0003158B00160000000076 -:10E420008D580000910E000225080003370D0008EA -:10E43000A14E00100A000CCCAD4D00009119000156 -:10E44000240F0004172F000B0000000091070002AA -:10E45000910400038D43000000072A0000A410254A -:10E460003466000425080004AD42000C0A000CCC00 -:10E47000AD46000003E000082402000127BDFFE8CC -:10E48000AFBF0014AFB000100E0015E50080802172 -:10E490003C0480083485008090A600052403FFFE1C -:10E4A0000200202100C310248FBF00148FB0001081 -:10E4B000A0A200050A0015EF27BD001827BDFFE840 -:10E4C000AFB00010AFBF00140E000FD40080802149 -:10E4D0003C06800834C5008090A40000240200504F -:10E4E000308300FF106200073C09800002002021F9 -:10E4F0008FBF00148FB00010AD2001800A0010A65D -:10E5000027BD0018240801003C07800002002021DC -:10E510008FBF00148FB00010ACE801800A0010A675 -:10E5200027BD001827BDFF783C058008AFBE0080DE -:10E53000AFB7007CAFB3006CAFB10064AFBF008475 -:10E54000AFB60078AFB50074AFB40070AFB200687A -:10E55000AFB0006034A600803C0580008CB201287A -:10E5600090C400098CA701043C020001309100FF17 -:10E5700000E218240000B8210000F021106000071C -:10E58000000098213C0908008D2931F02413000176 -:10E59000252800013C010800AC2831F0ACA0008423 -:10E5A00090CC0005000C5827316A0001154000721C -:10E5B000AFA0005090CD00002406002031A400FF41 -:10E5C00010860018240E0050108E009300000000EA -:10E5D0003C1008008E1000DC260F00013C010800F2 -:10E5E000AC2F00DC0E00165E000000000040182179 -:10E5F0008FBF00848FBE00808FB7007C8FB60078FD -:10E600008FB500748FB400708FB3006C8FB2006848 -:10E610008FB100648FB000600060102103E000083B -:10E6200027BD00880000000D3C1F8000AFA0003017 -:10E6300097E501168FE201043C04002030B9FFFF8A -:10E64000004438240007182B00033140AFA60030E7 -:10E650008FF5010437F80C003C1600400338802188 -:10E6600002B6A02434C40040128000479215000D69 -:10E6700032A800201500000234860080008030217E -:10E6800014C0009FAFA600303C0D800835A6008066 -:10E6900090CC0008318B0040516000063C06800899 -:10E6A000240E0004122E00A8240F0012122F003294 -:10E6B0003C06800834C401003C0280009447011AE3 -:10E6C0009619000E909F00088E18000830E3FFFF97 -:10E6D00003F9B00432B40004AFB6005CAFA3005835 -:10E6E0008E1600041280002EAFB8005434C3008090 -:10E6F000906800083105004014A0002500000000CB -:10E700008C70005002D090230640000500000000ED -:10E710008C71003402D1A82306A201678EE20008A2 -:10E72000126000063C1280003C1508008EB531F4E2 -:10E7300026B600013C010800AC3631F4AE4000447E -:10E74000240300018FBF00848FBE00808FB7007C40 -:10E750008FB600788FB500748FB400708FB3006CE3 -:10E760008FB200688FB100648FB00060006010212C -:10E7700003E0000827BD00880E000D2800002021BE -:10E780000A000D75004018210A000D9500C02021D7 -:10E790000E0016AE02C020211440FFE10000000070 -:10E7A0003C0B8008356400808C8A003402CA482300 -:10E7B0000520001D000000003C1E08008FDE310017 -:10E7C00027D700013C010800AC3731001260000679 -:10E7D000024020213C1408008E9431F42690000160 -:10E7E0003C010800AC3031F40E0015E53C1E8008F9 -:10E7F00037CD008091B700250240202136EE00047D -:10E800000E0015EFA1AE00250E000CAC0240202139 -:10E810000A000DCA240300013C17080126F794F8EA -:10E820000A000D843C1F80008C86003002C66023E5 -:10E830001980000C2419000C908F004F3C14080024 -:10E840008E94310032B500FC35ED0001268E0001BA -:10E850003C010800AC2E3100A08D004FAFA0005845 -:10E860002419000CAFB900308C9800300316A02397 -:10E870001A80010B8FA300580074F82A17E0FFD309 -:10E88000000000001074002A8FA5005802D4B021A7 -:10E8900000B410233044FFFFAFA4005832A8000298 -:10E8A0001100002E32AB00103C15800836B00080FD -:10E8B0009216000832D30040526000FB8EE200083E -:10E8C0000E0015E502402021240A0018A20A0009C2 -:10E8D000921100052409FFFE024020210229902404 -:10E8E0000E0015EFA21200052404003900002821B3 -:10E8F0000E001689240600180A000DCA2403000120 -:10E9000092FE000C3C0A800835490080001EBB00C6 -:10E910008D27003836F10081024020213225F08118 -:10E920000E000C9B30C600FF0A000DC10000000065 -:10E930003AA7000130E300011460FFA402D4B02123 -:10E940000A000E1D00000000024020210E0016CB20 -:10E95000020028210A000D75004018211160FF7087 -:10E960003C0F80083C0D800835EE00808DC40038D7 -:10E970008FA300548DA60004006660231D80FF68ED -:10E98000000000000064C02307020001AFA400548F -:10E990003C1F08008FFF31E433F9000113200015FC -:10E9A0008FAC00583C07800094E3011A10600012FD -:10E9B0003C0680080E0020F8024020213C0308019C -:10E9C0009063952930640002148001450000000026 -:10E9D000306C0004118000078FAC0058306600FBDB -:10E9E0003C010801A026952932B500FCAFA00058D3 -:10E9F0008FAC00583C06800834D30080AFB40018B8 -:10EA0000AFB60010AFAC00143C088000950B01209D -:10EA10008E6F0030966A005C8FA3005C8FBF003061 -:10EA20003169FFFF3144FFFF8FAE005401341021E4 -:10EA3000350540000064382B0045C82103E7C02598 -:10EA4000AFB90020AFAF0028AFB80030AFAF00249F -:10EA5000AFA0002CAFAE0034926D000831B40008B6 -:10EA6000168000BB020020218EE200040040F8095D -:10EA700027A400108FAF003031F300025660000170 -:10EA800032B500FE3C048008349F008093F90008F2 -:10EA900033380040530000138FA400248C850004F9 -:10EAA0008FA7005410A700D52404001432B0000131 -:10EAB0001200000C8FA400242414000C1234011A3C -:10EAC0002A2D000D11A001022413000E240E000AAD -:10EAD000522E0001241E00088FAF002425E40001FF -:10EAE000AFA400248FAA00143C0B80083565008079 -:10EAF000008A48218CB10030ACA9003090A4004EAF -:10EB00008CA700303408FFFC0088180400E3F821CB -:10EB1000ACBF00348FA600308FB900548FB8005CB2 -:10EB200030C200081040000B033898218CAC002044 -:10EB3000119300D330C600FF92EE000C8FA7003473 -:10EB400002402021000E6B0035B400800E000C9BAB -:10EB50003285F0803C028008345000808E0F0030F7 -:10EB600001F1302318C00097264800803C070800B8 -:10EB70008CE731E42404FF80010418243118007F5D -:10EB80003C1F80003C19800430F10001AFE300908D -:10EB900012200006031928213C03080190639529DF -:10EBA00030690008152000C6306A00F73C10800864 -:10EBB00036040080908C004F318B000115600042BC -:10EBC000000000003C0608008CC6319830CE0010D2 -:10EBD00051C0004230F9000190AF006B55E0003F9A -:10EBE00030F9000124180001A0B8006B3C1180002E -:10EBF0009622007A24470064A48700123C0D800806 -:10EC000035A5008090B40008329000401600000442 -:10EC10003C03800832AE000115C0008B00000000EC -:10EC2000346400808C86002010D3000A3463010015 -:10EC30008C67000002C7782319E000978FBF00544B -:10EC4000AC93002024130001AC760000AFB3005059 -:10EC5000AC7F000417C0004E000000008FA90050D8 -:10EC60001520000B000000003C030801906395296B -:10EC7000306A00011140002E8FAB0058306400FE56 -:10EC80003C010801A02495290A000D7500001821F7 -:10EC90000E000CAC024020210A000F1300000000FF -:10ECA0000A000E200000A0210040F80924040017EB -:10ECB0000A000DCA240300010040F80924040016CC -:10ECC0000A000DCA240300019094004F240DFFFE9A -:10ECD000028D2824A085004F30F900011320000682 -:10ECE0003C0480083C03080190639529307F0010A4 -:10ECF00017E00051306800EF34900080240A0001D2 -:10ED0000024020210E0015E5A60A001292030025FC -:10ED100024090001AFA90050346200010240202103 -:10ED20000E0015EFA20200250A000EF93C0D800826 -:10ED30001160FE83000018218FA5003030AC000464 -:10ED40001180FE2C8FBF00840A000DCB240300012C -:10ED500027A500380E000CB6AFA000385440FF4382 -:10ED60008EE200048FB40038329001005200FF3F61 -:10ED70008EE200048FA3003C8E6E0058006E682364 -:10ED800005A3FF39AE6300580A000E948EE200041A -:10ED90000E0015E5024020213C0380083468008005 -:10EDA000024020210E0015EFA11E000903C03021F2 -:10EDB000240400370E001689000028210A000F11D4 -:10EDC0008FA900508FAB00185960FF8D3C0D800853 -:10EDD0000E0015E502402021920C002524050001BB -:10EDE000AFA5005035820004024020210E0015EF2F -:10EDF000A20200250A000EF93C0D800812240059D9 -:10EE00002A2300151060004D240900162408000C68 -:10EE10005628FF2732B000013C0A8008914C001BA5 -:10EE20002406FFBD241E000E01865824A14B001BA2 -:10EE30000A000EA532B000013C010801A028952966 -:10EE40000A000EF93C0D80088CB500308EFE0008DB -:10EE50002404001826B6000103C0F809ACB600303F -:10EE60003C030801906395293077000116E0FF818B -:10EE7000306A00018FB200300A000D753243000481 -:10EE80003C1080009605011A50A0FF2B34C60010DC -:10EE90000A000EC892EE000C8C6200001456FF6D42 -:10EEA000000000008C7800048FB9005403388823D8 -:10EEB0000621FF638FBF00540A000F0E0000000000 -:10EEC0003C010801A02A95290A000F3030F9000101 -:10EED0001633FF028FAF00240A000EB0241E00106C -:10EEE0000E0015E5024020213C0B800835680080AB -:10EEF00091090025240A0001AFAA0050353300040F -:10EF0000024020210E0015EFA11300253C05080149 -:10EF100090A5952930A200FD3C010801A022952969 -:10EF20000A000E6D004018212411000E53D1FEEA94 -:10EF3000241E00100A000EAF241E00165629FEDC07 -:10EF400032B000013C0A8008914C001B2406FFBD32 -:10EF5000241E001001865824A14B001B0A000EA598 -:10EF600032B000010A000EA4241E00123C038000EF -:10EF70008C6201B80440FFFE24040800AC6401B8B0 -:10EF800003E00008000000000080502130A5FFFFD2 -:10EF900030C6FFFF3C0480008C8201B80440FFFEB5 -:10EFA00034880180AD0A00003C078008AC8A00204C -:10EFB00094E300483067FFFF10E000423C0D800002 -:10EFC00024AB001200EB482B5120003F2404000327 -:10EFD00034820100945900208F8900002404001A13 -:10EFE0003338FFFF270BFFFE00EB782B39EE0001D3 -:10EFF00000096B8201AE6024A104000B518000491E -:10F000008F8B00048F830004A50B0014346800016B -:10F01000AF88000430CE004015C000333C048000AF -:10F020003C02800034420180A445000E3C07800071 -:10F0300034EC0180A585001A8F85000C310B80000F -:10F04000A5890010AD850028A58600081160000F75 -:10F050008F85001434EA0100954E001631CDFFFC77 -:10F0600025A40004008718218C67400030E6FFFFCC -:10F0700014C000073C0480003C18FFFF370F7FFFDF -:10F08000010F4024AF8800048F8500143C048000E9 -:10F090002402BFFF348301800102C824A479002622 -:10F0A00010A00004AC69002C00054402A465001007 -:10F0B000A46800263C091000AC8901B803E00008F0 -:10F0C000000000002404000335AC018030CE004075 -:10F0D0008F8900008F880004A184000B51C0FFD1EC -:10F0E0003C0280003C048000AC8A00203C0F800879 -:10F0F00095EA00403143FFFF5060000834820180F0 -:10F1000000A3C02B5700000100A0182134990180F2 -:10F11000A723000E0A0010053C0780000A00100318 -:10F1200030C6FFBF2407FFFE016740240A000FFE20 -:10F13000AF88000427BDFFE88FA2002830A5FFFF9D -:10F1400030C6FFFFAFBF0010AF87000CAF820014C6 -:10F15000AF8000040E000FDBAF8000008FBF0010F7 -:10F1600027BD001803E00008AF8000143C068000B3 -:10F1700034C4007034C701008C8A000090E500128E -:10F180008F84000027BDFFF030A300FF000318822A -:10F190003082400010400037246500030005C8801D -:10F1A0000326C0218F0E4000246F0004000F6880EA -:10F1B000AFAE000001A660218D8B4000AFAB000414 -:10F1C00094E900163128FFFC010638218CE6400046 -:10F1D000AFA600088FA900080000302100002821F8 -:10F1E0003C07080024E701000A00107E24080008FC -:10F1F0009059000024A500012CAC000C0079C0211E -:10F200000018788001E770218DCD00001180000684 -:10F2100000CD302603A5102114A8FFF500051A0023 -:10F220005520FFF4905900003C04800034870070A2 -:10F230003C0508008CA531048CE300002CA20020C2 -:10F2400010400009006A3823000548803C0B080084 -:10F25000256B3108012B402124AA0001AD070000D5 -:10F260003C010800AC2A310400C0102103E0000872 -:10F2700027BD0010308220001040000B0005588090 -:10F28000016648218D24400024680004000838806D -:10F29000AFA4000000E618218C654000AFA0000874 -:10F2A0000A00106EAFA500040000000D0A00106FE8 -:10F2B0008FA9000827BDFFD83C058000AFB100141E -:10F2C000AFB00010AFBF0024AFB40020AFB3001C3C -:10F2D000AFB200188F87000034A401009483000EA1 -:10F2E00030E2400000008021104000103071FFFF2C -:10F2F0003C08002000E8302410C0000D30EB8000F6 -:10F300008F890004240ABFFF00EA38243523100047 -:10F31000AF87000030F320001660000B3C1800049B -:10F320002419FFBF0A0010CF0079102430EB8000B1 -:10F330001560004D3C0D002030F320001260FFF8F6 -:10F340008F8300043C18000400F8A0241280FFF50D -:10F350002419FFBF3462004030FF010013E00010A9 -:10F36000AF8200048F820028104000063C0E80000F -:10F370003C04002000E41824146000CE3C06000485 -:10F380003C0E800035CD010095AC001E95AB001CF5 -:10F390003189FFFF000B5400012A4025AF88000C83 -:10F3A0003C138000367401009692000C8E6340007E -:10F3B000340FFFFF106F00843244FFFF30780100EC -:10F3C000570000012410001030F9100053200008ED -:10F3D0003612000130FF002017E000733C031000DC -:10F3E00000E310241440006A3C0A0C0036120001AD -:10F3F00030EC01001580000B3C0600018F880004F2 -:10F40000310D400015A0000800E628243C131F0120 -:10F4100000F378243C0E100011EE00AE3094020090 -:10F420003C06000100E6282410A000193C19100039 -:10F430003C0408008C84002430940002168000D91B -:10F44000240300018FBF00248FB400208FB3001C61 -:10F450008FB200188FB100148FB00010006010211F -:10F4600003E0000827BD002800ED60241180FFB3F1 -:10F4700030F320008F8E00043C12FFFF364F7FFFD9 -:10F4800000EF382435C380000A0010BEAF870000AB -:10F4900000F9C0241700004E00002021AF800010AA -:10F4A0003C0380003465010094AE000E8F91001083 -:10F4B00031CAFFFF108000C62553000430EF010061 -:10F4C00015E000703C180F003A2800022E7003EF80 -:10F4D0002D1900013A1F0001033F282414A0002227 -:10F4E000240400013C0308008C6300D02E25000C8E -:10F4F000001121C0386C00012D8B00010165102422 -:10F50000144000143270FFFF262DFFFC2DA40004D0 -:10F510001480010300002021386A00022D460001FA -:10F5200000C51824546000FF02002821262FFFF890 -:10F530002DEE000415C00007000000000007A242E5 -:10F540000011C02B0298482415200109020028212F -:10F55000001121C002002821364600020E000FDBF8 -:10F560000000000000002021008018218FBF00242F -:10F570008FB400208FB3001C8FB200188FB100141D -:10F580008FB000100060102103E0000827BD0028A4 -:10F590003C090BFF00EA40243526FFFF00C8282B5A -:10F5A00050A0FF93361200013C0B08008D6B002C1D -:10F5B00036120005257000013C010800AC30002C1B -:10F5C0000A0010F630EC01000A0010EB24100020B5 -:10F5D00000071602305F000F001F80C03C030801C7 -:10F5E00024639478020320211080FFADAF9F0010A8 -:10F5F000908800005100FFAB3C0380003C0D800070 -:10F6000035A90100952C000E240B00030240302187 -:10F61000318AFFFF25450004110B00D9000050215D -:10F620009088000124140002311100FF123400BF41 -:10F6300030F80040310300FF24080001106800C8C2 -:10F6400030E200408C8A00048F8B00245560000655 -:10F6500034C60002254DFE002DAC0381558000010B -:10F660003646004034C600020140202130A5FFFF8D -:10F670000E000FDB30C6FFFF000040210A00110A18 -:10F680000100182100F8A0243C0902001289FF8F14 -:10F690003A28000290B100133270FFFF02002821C7 -:10F6A000322700FF24F30004001321C00A00115088 -:10F6B0003646000200E6282414A0FF323C0E8000EB -:10F6C0000E0010543C1380008F8700000A0010E2E7 -:10F6D000AF82000C1680FF533C0600012624000474 -:10F6E0003085FFFF364600023C0380008C7101B874 -:10F6F0000620FFFE8F890008346A0180AD400000BB -:10F70000112000B23C0D800024B800120138902B6B -:10F71000124000AF240C0003347001009603002057 -:10F720002402001A30F94000307FFFFFA142000B95 -:10F73000132000AB27E3FFFE0123582B156000A91F -:10F740002409FFFE35080001A5430014AF8800041A -:10F750003C0E80002413BFFF0113782435C80180BC -:10F76000A505000EA505001AA5060008A50F002690 -:10F77000A50700103C071000ADC701B80000182114 -:10F780008FBF00248FB400208FB3001C8FB20018ED -:10F790008FB100148FB000100060102103E000084A -:10F7A00027BD00283C1208008E5200D802202821D4 -:10F7B00024040080265100013C010800AC3100D82F -:10F7C0000E000FDB240600030A0011D900001821E7 -:10F7D0008C65400030B1010012200046325900040F -:10F7E0003C1F08008FFF002424140004172000028F -:10F7F00033F0000D2414000200076AC239A400018E -:10F800002E6C03EF30820001398B0001004B402544 -:10F81000110000033251FFFB2412FFFB021280246F -:10F8200030E3010050600015321F00013C0A0F0058 -:10F8300000EA30243C07020010C7000F3C1980008A -:10F840003725010090A900132418FFFE0218802418 -:10F85000312F00FF25EE0004000E21C0120000022F -:10F86000023430253226FFFF0E000FDB3265FFFF2A -:10F870001200FF3D00002021321F000113E0000DA7 -:10F88000320B000424080001120800020234302563 -:10F890003226FFFF000020210E000FDB3265FFFF44 -:10F8A0002402FFFE020280241200FF2F000020210C -:10F8B000320B00045160000D240400010234302595 -:10F8C00024140004561400013226FFFF2411FFFB0C -:10F8D0003265FFFF240401000E000FDB02119824A3 -:10F8E0001260FF2100002021240400010A001154AD -:10F8F000008018213C0C08008D8C00243190000100 -:10F900005200FF19000020213265FFFF3646000239 -:10F910000E000FDB000020210A00115300002021FF -:10F92000020028210A00115036460002130000068A -:10F930000000000095300010949F000232190FFF64 -:10F9400013F9FF3D310300FF3C04080190849479D2 -:10F950001080FF3D240800010A00110A010018214F -:10F960005040FF398C8A00040A00124B000000004E -:10F970000E000FDB3246FFFB0A00114E001121C0C2 -:10F9800090830001240E0001106EFF3C240800014A -:10F99000240F0002106F000430F30040240800011F -:10F9A0000A00110A010018215260FFFD240800011D -:10F9B000952500109487000230A9FFFF50E9FEA1B1 -:10F9C000010018210A00126124080001240C000320 -:10F9D00035AA0180A14C000B0A0011CE3C0E80001C -:10F9E0002409FFFE0A0011CC0109402427BDFFC0F5 -:10F9F000AFB00018AFBF003C3C10600CAFBE003889 -:10FA0000AFB70034AFB60030AFB5002CAFB40028AC -:10FA1000AFB30024AFB20020AFB1001C8E0E500077 -:10FA2000240FFF7F3C06800001CF682435AC380CE2 -:10FA3000240B0003AE0C5000ACCB00083C010800C6 -:10FA4000AC2000200E0017B0000000003C0A00109F -:10FA5000354980513C066016AE09537C8CC70000C6 -:10FA60003C0860148D0500A03C03FFFF00E3202448 -:10FA70003C02535300051FC21082029B34C57C0018 -:10FA80008CBF007C8CA200783C1E600037C4202014 -:10FA90003C05080124A590C0AF820018AF9F001C50 -:10FAA0000E0016742406000A3C19000127399478C8 -:10FAB0003C010800AC3931DC0E00206BAF80001433 -:10FAC0008FD708082418FFF03C15570902F8B02416 -:10FAD00012D5028B24040001AF8000283C14800062 -:10FAE0003697010002E0F0218E90000032050003FD -:10FAF00010A0FFFD3207000114E0005D3206000295 -:10FB000010C0FFF93C07800034E501408CB90000CB -:10FB100024100040ACF9002090B8000833030070B6 -:10FB20001070010B286900411120000824080060B2 -:10FB3000241F0020107F000E3C0B40003C0680007C -:10FB4000ACCB01780A0012B3000000001468FFFB80 -:10FB50003C0B40000E001F88000000003C0B4000E2 -:10FB60003C068000ACCB01780A0012B30000000014 -:10FB700090AB0009241100048CA70000316800FF3D -:10FB80001111015D2512FFFA2E53000612600016B6 -:10FB90003C0680008CAA00048F86002494A3000AEF -:10FBA000000A3E02310500FF10C000053064FFFF6F -:10FBB0002CEC00081580000224E700042407000351 -:10FBC000240E000910AE01A128AF000A11E0018443 -:10FBD0002410000A2404000810A4001A000749C0D9 -:10FBE000012038213C0680008CD001B80600FFFEC1 -:10FBF00034C40180AC87000034C5014090B60008D1 -:10FC0000241900023C0B400032C200FF00028A00AF -:10FC10000228F825A49F0008A099000B94A7000AC9 -:10FC20003C081000A48700108CB80004AC98002495 -:10FC3000ACC801B83C068000ACCB01780A0012B316 -:10FC400000000000000AC202330300FF2405000187 -:10FC50005465FFE4012038218F990020AF830024F0 -:10FC600027270001AF8700200A0012F20120382167 -:10FC70008FD100283C0B8008AE9100208FC6000475 -:10FC80008FCA000095690048AF860000AF8A000463 -:10FC90003128FFFF0E000FD4AF8800083C03080096 -:10FCA0008C6300C0106000258F8700003C0E0800A8 -:10FCB0008DCE00C425CD00013C010800AC2D00C450 -:10FCC0003C1F800037E901008D3900243C0760208B -:10FCD000ACF90014000000003C0680003C08400025 -:10FCE000ACC80138000000005220FF853206000237 -:10FCF000262D0140262E00802404FF8001A4282404 -:10FD000001C47824000F194031CC007F00059940D0 -:10FD100031B2007F3C15200036A20002006C502555 -:10FD20000272B02502C2882501425825ACCB0830AA -:10FD3000ACD108300A0012B9320600023C120010A1 -:10FD400000F2782415E000708F8300043C1808004E -:10FD50008F18002097D6000E30F5400027130001C1 -:10FD60003C010800AC3300200000902112A000816B -:10FD700032D3FFFF3C1F002000FFC8241320007E69 -:10FD800030E580008F8200042404BFFF00E43824A3 -:10FD900034431000AF87000030EB20001160007387 -:10FDA000240EFFBF3C0D000400ED60241180000212 -:10FDB000006E10243462004030EF010011E00010AA -:10FDC000AF8200048F95002812A000073C18002085 -:10FDD00000F8B02412C000043C1F000400FFC82437 -:10FDE0001320016D0000000096E3001E96E8001C41 -:10FDF0003065FFFF0008140000A22025AF84000C2E -:10FE000096EA000C8E8440003409FFFF10890085BB -:10FE10003145FFFF3086010054C00001241200105C -:10FE200030EB1000116000133656000130EC00205A -:10FE30001580000A3C0E100000EE682411A0000D91 -:10FE40003C190C003C180BFF00F9B0243715FFFFDC -:10FE500002B6782B11E00007365600013C1F08005F -:10FE60008FFF002C3656000527F200013C010800E8 -:10FE7000AC32002C30E401001480000B3C06000181 -:10FE80008F880004310240005440000800E6282416 -:10FE90003C0A1F0100EA48243C0310001123010919 -:10FEA00030A602003C06000100E6282410A0003E17 -:10FEB0003C1810003C0D08008DAD002431AC000250 -:10FEC0001580000624030001006010211040FF830C -:10FED0003C0680000A00132A3C1F80003C0F0800EB -:10FEE0008DEF00D8026028212404008025EE000157 -:10FEF0003C010800AC2E00D80E000FDB24060003E6 -:10FF00000A0013AB000018212405BFFF0065682418 -:10FF100011A00007240F87FF006F702415C0000890 -:10FF20003C18006000F8202410800005000000004C -:10FF30000E000D42000000000A0013AC000000009B -:10FF40000E00159C000000000A0013AC0000000029 -:10FF50000E0015F4000000003C0B40003C06800041 -:10FF6000ACCB01780A0012B3000000000A0013674E -:10FF7000006E102430E5800010A0FF878F830004FE -:10FF80003C08002000E818245060FF838F830004A1 -:10FF90008F8900043C06FFFF34CA7FFF00EA382443 -:10FFA0000A00135E3523800000F8A82416A0001F65 -:10FFB00000004021AF8000103C0380003464010049 -:10FFC0009486000E8F93001030C5FFFF1100014E84 -:10FFD00024B5000430EA0100114000553A7F0002C8 -:10FFE0003C0E0F0000EE68243C0C020011AC0051E6 -:10FFF0002EB203EF908F001332B2FFFF31E400FF07 -:020000040001F9 -:1000000024870004000721C00240282136C60002D0 -:100010000E000FDB00000000000020210A0013ABDF -:10002000008018210A0013812412002000072602F4 -:100030003099000F0019F8C03C120801265294783C -:1000400003F240211100FFDCAF990010910900007C -:100050001120FFDA3C0380003C138000366A010067 -:10006000954B000E2403000302C030213162FFFFD4 -:1000700024450004112300EC000020219109000117 -:10008000240D0002312E00FF11CD00FA313200FFA5 -:10009000240900011249001030FF00408D040004C3 -:1000A0008F8300241460000634D30002248BFE00EA -:1000B0002D6203815440000136C6004034D3000253 -:1000C00030A5FFFF0E000FDB3266FFFF0000482166 -:1000D0000A0013AB0120182153E0FFF18D04000446 -:1000E0003C080801910894791100FFED24090001F2 -:1000F0000A0013AB012018213C0480008C8A01B84F -:100100000540FFFE349601802415001CAEC7000098 -:10011000A2D5000B3C021000AC8201B83C0B4000A1 -:100120003C068000ACCB01780A0012B3000000004E -:100130002EB203EF2FF900013A4900010329C02430 -:100140001700FFB6240400013C0308008C6300D0B4 -:100150002E65000C001321C0386B00012D620001D8 -:10016000004540241500FFA832B2FFFF266AFFFCBD -:100170002D46000414C0001300002021386D000239 -:100180002DAC0001018518241460000F02402821C5 -:10019000266EFFF82DC5000414A0FF9B0000000090 -:1001A00000077A420013382B01E7A82456A0000864 -:1001B00002402821001321C0024028210A0013FD1B -:1001C00036C60002024028210A0013FD36C600028E -:1001D0000E000FDB32C6FFFB0A001467001321C0BC -:1001E00010B0007200045A022406000B14A6FE7C14 -:1001F000000749C0314600FF00065600000A5E03B2 -:10020000056200B030C6007F000670C03C0F0801D8 -:1002100025EF947801CFA821A2A00001A2A00000A0 -:100220003C1360008E631820240D000100CD4804AB -:1002300000096027000749C0006C90240120382184 -:10024000AE7218200A0012F2A6A0000214C0004BE1 -:100250008F8C0020000749C03C0B8000AD69002056 -:100260003C118008963F004013E000022405000185 -:10027000240500413C0480008C8A01B80540FFFE43 -:100280003496018024120003AEC90000A2D2000BF4 -:10029000A6C0000EA6C0001AA6C00010AEC000285E -:1002A000A6C5000896D3002636750001A6D50026FF -:1002B000AEC0002C3C021000AC8201B80A0012F261 -:1002C0000120382114C0FEF83C060001266B000412 -:1002D0003165FFFF36C600023C0380008C7301B815 -:1002E0000660FFFE8F8900083C0D800035AC018060 -:1002F000AD800000512000DD3C09800024AF0012D9 -:10030000012F702B51C000D93C09800096F20020CB -:100310003C1980002418001A3256FFFF372A01804A -:1003200030F54000A158000B12A000D526C3FFFEF7 -:100330000123F82B17E000D32404FFFE3508000149 -:10034000A5430014AF8800042413BFFF3C0B8000BA -:100350000113502435680180A505000EA505001A7B -:10036000A5060008A50A0026A50700103C071000F6 -:10037000AE8701B80A0013AB00001821000749C07E -:100380002583FFFF1460FE16AF8300200120382173 -:100390000A0012F2AF8000240E001054000000008A -:1003A0008F8700000A001379AF82000C240300FF3E -:1003B0001163FE0B000749C010C00038000B760027 -:1003C000000B20C03C0908012529947800891821D8 -:1003D00024020001A06200003C16080126D6947891 -:1003E0003C0208012442947C00962821000749C061 -:1003F00000828821000AFC02AE290000A0BF000193 -:100400003C0460008C9818202419000101793804FC -:100410000307302501203821A4AA0002AC86182049 -:100420000A0012F33C06800091030001241600012B -:100430001076FF272409000124050002106500043E -:1004400030E60040240900010A0013AB0120182106 -:1004500050C0FFFD24090001954C0010950A0002D0 -:100460003187FFFF5147FE98012018210A00150B24 -:100470002409000130EF004011E0FF1900000000E6 -:10048000955900109518000233350FFF1715FF140A -:10049000313200FF0A00141E24090001000E6E0311 -:1004A00005A2000F316B007F10E30008000B20C095 -:1004B0003C10080126109478009018210A0014EED0 -:1004C000240200020A00147BAF8000203C0F0801C8 -:1004D00025EF9478008F18210A0014EE24020003FF -:1004E0000A001523AF8B00200003A080028698210C -:1004F0008E7200043C1160000A00129902512821FA -:100500000A0012B0AF8400288C64400030930100D0 -:100510001260004B240900043C1908008F390024A4 -:1005200032D80004AFA90010170000033332000DC9 -:10053000241F0002AFBF001000071AC2386A000172 -:100540002EA603EF3142000138CB0001004B4025BD -:100550001100000332D3FFFB2416FFFB0256902448 -:1005600030EC010011800016324800013C0E0F00F3 -:1005700000EE28243C0D020010AD00113C1F80004D -:1005800037E90100913800138FAF00102419FFFEE6 -:10059000330400FF2487000402599024000721C07F -:1005A00012400002026F30253266FFFF0E000FDBA3 -:1005B00032A5FFFF1240FE990000202132480001C1 -:1005C0001100000E324A00048FAB0010240200011B -:1005D00012420002026B30253266FFFF000020212C -:1005E0000E000FDB32A5FFFF2406FFFE024690241B -:1005F0001240FE8A00002021324A00045140000EC1 -:10060000240400018FB600102403000412430002EA -:10061000027630253266FFFF2413FFFB32A5FFFF71 -:10062000240401000E000FDB0253A82412A0FE7B5D -:1006300000002021240400010A0013AB00801821CF -:100640003C0C08008D8C0024319200015240FE7356 -:100650000000202132A5FFFF36C600020E000FDB8E -:10066000000020210A0014000000202124020003C1 -:1006700035230180A062000B0A0014CC2413BFFFB5 -:100680002404FFFE0A0014CA010440243C03800035 -:10069000346401008C85000030A2003E1440000844 -:1006A00000000000AC6000488C87000030E607C006 -:1006B00010C0000500000000AC60004CAC600050B1 -:1006C00003E0000824020001AC600054AC6000406C -:1006D0008C880000310438001080FFF90000000011 -:1006E0002402000103E00008AC6000443C038000E9 -:1006F0008C6201B80440FFFE34670180ACE4000066 -:1007000024080001ACE00004A4E500082405000270 -:10071000A0E8000A34640140A0E5000B9483000ABD -:1007200014C00008A4E30010ACE000243C078000E3 -:1007300034E901803C041000AD20002803E00008EB -:10074000ACE401B88C8600043C041000ACE6002444 -:100750003C07800034E90180AD20002803E0000858 -:10076000ACE401B83C0680008CC201B80440FFFE36 -:1007700034C7018024090002ACE40000ACE40004AA -:10078000A4E50008A0E9000A34C50140A0E9000B77 -:1007900094A8000A3C041000A4E80010ACE0002477 -:1007A0008CA30004ACE3002803E00008ACC401B84B -:1007B0003C03900034620001008220253C0380004D -:1007C000AC6400208C65002004A0FFFE0000000047 -:1007D00003E00008000000003C02800034430001F8 -:1007E0000083202503E00008AC44002027BDFFE083 -:1007F0003C098000AFBF0018AFB10014AFB00010CB -:10080000352801408D10000091040009910700086F -:1008100091050008308400FF30E600FF00061A0052 -:100820002C820081008330251040002A30A50080F2 -:10083000000460803C0D080125AD90E8018D582131 -:100840008D6A000001400008000000003C038000A9 -:10085000346201409445000A14A0001E8F91FCB838 -:100860009227000530E6000414C0001A00000000C2 -:100870000E0015E502002021922A00050200202129 -:10088000354900040E0015EFA22900059228000545 -:100890003104000414800002000000000000000D7C -:1008A000922D0000240B002031AC00FF158B0009B5 -:1008B0003C0580008CAE01B805C0FFFE34B101805C -:1008C000AE3000003C0F100024100005A230000BD9 -:1008D000ACAF01B80000000D8FBF00188FB100143D -:1008E0008FB0001003E0000827BD00200200202187 -:1008F00000C028218FBF00188FB100148FB00010E6 -:10090000240600010A0015B427BD00200000000DD8 -:100910000200202100C028218FBF00188FB10014D1 -:100920008FB00010000030210A0015B427BD002050 -:1009300014A0FFE800000000020020218FBF001873 -:100940008FB100148FB0001000C028210A0015D20A -:1009500027BD00203C0780008CEE01B805C0FFFEDB -:1009600034F00180241F0002A21F000B34F8014064 -:10097000A60600089719000A3C0F1000A6190010DF -:100980008F110004A6110012ACEF01B80A00163056 -:100990008FBF001827BDFFE8AFBF00100E000FD4B7 -:1009A000000000003C0280008FBF001000002021EA -:1009B000AC4001800A0010A627BD00183084FFFF5C -:1009C00030A5FFFF108000070000182130820001D1 -:1009D0001040000200042042006518211480FFFB33 -:1009E0000005284003E000080060102110C0000747 -:1009F000000000008CA2000024C6FFFF24A5000414 -:100A0000AC82000014C0FFFB2484000403E0000853 -:100A10000000000010A0000824A3FFFFAC86000027 -:100A200000000000000000002402FFFF2463FFFF1D -:100A30001462FFFA2484000403E0000800000000B0 -:100A40003C03800027BDFFF834620180AFA20000A4 -:100A5000308C00FF30AD00FF30CE00FF3C0B80003B -:100A60008D6401B80480FFFE000000008FA9000023 -:100A70008D6801288FAA00008FA700008FA40000B6 -:100A80002405000124020002A085000A8FA30000B3 -:100A9000359940003C051000A062000B8FB80000A3 -:100AA0008FAC00008FA600008FAF000027BD0008AC -:100AB000AD280000AD400004AD800024ACC000288B -:100AC000A4F90008A70D0010A5EE001203E000082D -:100AD000AD6501B83C06800827BDFFE834C500803D -:100AE000AFBF001090A700092402001230E300FFFE -:100AF0001062000B008030218CA800500088202359 -:100B0000048000088FBF00108CAA00342404003930 -:100B10000000282100CA48230520000524060012F1 -:100B20008FBF00102402000103E0000827BD001859 -:100B30000E001689000000008FBF00102402000183 -:100B400003E0000827BD001827BDFFC8AFB2003082 -:100B5000AFB00028AFBF0034AFB1002C00A080219F -:100B600090A5000D30A6001010C00010008090214C -:100B70003C0280088C4400048E0300081064000CC2 -:100B800030A7000530A6000510C000932404000122 -:100B90008FBF00348FB200308FB1002C8FB000288F -:100BA0000080102103E0000827BD003830A70005B1 -:100BB00010E0000F30AB001210C00006240400014A -:100BC0003C0980088E0800088D2500045105009C12 -:100BD000240400388FBF00348FB200308FB1002C56 -:100BE0008FB000280080102103E0000827BD0038E6 -:100BF000240A0012156AFFE62404000102002021E5 -:100C000027A500100E000CB6AFA000101440007C09 -:100C10003C198008372400809098000833110008A0 -:100C20001220000A8FA7001030FF010013E000A47B -:100C30008FA300148C860058006610230440000423 -:100C40003C0A8008AC8300588FA700103C0A80083B -:100C50003548008091090008312400081480000202 -:100C600024080003000040213C1F800893F100117C -:100C700093F9001237E600808CCC0054333800FF23 -:100C800003087821322D00FF000F708001AE28216B -:100C900000AC582B1160006F0000000094CA005C8B -:100CA0008CC900543144FFFF012510230082182B0A -:100CB00014600068000000008CCB0054016518230C -:100CC00030EC00041180006C000830808FA8001CFC -:100CD0000068102B1040006230ED00040066102305 -:100CE0002C46008010C000020040882124110080A2 -:100CF0000E0015E5024020213C0D800835A600803D -:100D000024070001ACC7000C90C80008001148403F -:100D100035A70100310C007FA0CC00088E0500042F -:100D200024AB0001ACCB0030A4D1005C8CCA003CE9 -:100D30009602000E01422021ACC400208CC3003C6E -:100D40000069F821ACDF001C8E190004ACF900002A -:100D50008E180008ACF800048FB10010322F000884 -:100D600055E0004793A60020A0C0004E90D8004E4A -:100D70002411FFDFA0F8000890CF000801F17024D3 -:100D8000A0CE00088E0500083C0B80083569008065 -:100D9000AD2500388D6A00148D22003024190050D2 -:100DA00001422021AD24003491230000307F00FF58 -:100DB00013F90036264F01000E0015EF02402021E6 -:100DC00024040038000028210E0016892406000A99 -:100DD0000A0016EE240400010E000D280000202158 -:100DE0008FBF00348FB200308FB1002C8FB000283D -:100DF000004020210080102103E0000827BD0038BA -:100E00008E0E00083C0F800835F00080AE0E0054B6 -:100E100002402021AE0000300E0015E50000000069 -:100E2000920D00250240202135AC00200E0015EF68 -:100E3000A20C00250E000CAC024020212404003836 -:100E40002405008D0E001689240600120A0016EEF5 -:100E50002404000194C5005C0A00172930A3FFFF99 -:100E60002407021811A0FF9E00E610238FAE001C7D -:100E70000A00173101C610230A00172E2C6202182F -:100E8000A0E600080A00175B8E0500082406FF8014 -:100E900001E6C0243C118000AE3800288E0D000809 -:100EA00031E7007F3C0E800C00EE6021AD8D00E04C -:100EB0008E080008AF8C00340A001767AD8800E484 -:100EC000AC800058908500082403FFF700A3382465 -:100ED000A08700080A00170C8FA700103C05080027 -:100EE00024A55F043C04080024846E503C020800E2 -:100EF00024425F0C240300063C010801AC2594F851 -:100F00003C010801AC2494FC3C010801AC22950092 -:100F10003C010801A023950403E000080000000044 -:100F200003E00008240200013C028000308800FF3A -:100F3000344701803C0680008CC301B80460FFFE8A -:100F4000000000008CC501282418FF803C0D800A99 -:100F500024AF010001F8702431EC007FACCE0024F6 -:100F6000018D2021ACE50000948B00EA350960007A -:100F700024080002316AFFFFACEA000424020001E9 -:100F8000A4E90008A0E8000BACE000243C07100036 -:100F9000ACC701B8AF84003403E00008AF85006837 -:100FA000938800448F89005C8F82003430C600FF34 -:100FB0000109382330E900FF0122182130A500FF84 -:100FC0002468008810C000020124382100803821E4 -:100FD00030E400031480000330AA00031140000D28 -:100FE000312B000310A000090000102190ED00003B -:100FF000244E000131C200FF0045602BA10D00000E -:1010000024E700011580FFF92508000103E000082E -:10101000000000001560FFF30000000010A0FFFBBF -:10102000000010218CF8000024590004332200FF36 -:101030000045782BAD18000024E7000415E0FFF907 -:101040002508000403E00008000000009385004428 -:10105000938800548F87005C000432003103007FC6 -:1010600000E5102B30C47F001040000F00642825DD -:101070008F8400343C0980008C8A00ECAD2A00A4E7 -:101080003C03800000A35825AC6B00A08C6C00A032 -:101090000580FFFE000000008C6D00ACAC8D00EC04 -:1010A00003E000088C6200A80A0018198F8400343D -:1010B000938800553C02800000805021310300FEDF -:1010C000A383005530ABFFFF30CC00FF30E7FFFFBC -:1010D000344801803C0980008D2401B80480FFFE63 -:1010E0008F8D006824180016AD0D00008D2201249C -:1010F0008F8D0034AD0200048D590020A507000833 -:10110000240201C4A119000AA118000B952F012087 -:101110008D4E00088D470004978300588D59002498 -:1011200001CF302100C7282100A320232418FFFF6E -:10113000A504000CA50B000EA5020010A50C0012C2 -:10114000AD190018AD18002495AF00E83C0B100055 -:101150002407FFF731EEFFFFAD0E00288DAC0084B1 -:10116000AD0C002CAD2B01B88D46002000C7282403 -:1011700003E00008AD4500208F880034008058212E -:1011800030E7FFFF910900D63C02800030A5FFFF49 -:10119000312400FF00041A000067502530C600FF0C -:1011A000344701803C0980008D2C01B80580FFFE8A -:1011B0008F820068240F0017ACE200008D390124F3 -:1011C000ACF900048D780020A4EA0008241901C4B9 -:1011D000A0F8000AA0EF000B952301208D6E0008F7 -:1011E0008D6D00049784005801C35021014D60218A -:1011F00001841023A4E2000CA4E5000EA4F9001061 -:10120000A4E60012ACE000148D780024240DFFFF4A -:10121000ACF800188D0F007CACEF001C8D0E007830 -:101220003C0F1000ACEE0020ACED0024950A00BE8F -:10123000240DFFF73146FFFFACE60028950C008037 -:101240009504008231837FFF0003CA003082FFFFD4 -:101250000322C021ACF8002CAD2F01B8950E0082FE -:101260008D6A002000AE3021014D2824A5060082A1 -:1012700003E00008AD6500203C0280003445018099 -:101280003C0480008C8301B80460FFFE8F8A00401C -:10129000240600199549001C3128FFFF000839C0B9 -:1012A000ACA70000A0A6000B3C05100003E000085E -:1012B000AC8501B88F8700480080402130C400FF12 -:1012C0003C0680008CC201B80440FFFE8F89006894 -:1012D0009383006434996000ACA90000A0A30005CA -:1012E0008CE20010240F00022403FFF7A4A20006E2 -:1012F000A4B900088D180020A0B8000AA0AF000B08 -:101300008CEE0000ACAE00108CED0004ACAD00140F -:101310008CEC001CACAC00248CEB0020ACAB0028A7 -:101320008CEA002C3C071000ACAA002C8D0900248C -:10133000ACA90018ACC701B88D05002000A320247B -:1013400003E00008AD0400208F86003427BDFFE0D5 -:10135000AFB10014AFBF0018AFB0001090C300D4FD -:1013600030A500FF30620020104000080080882176 -:101370008CCB00D02409FFDF256A0001ACCA00D065 -:1013800090C800D401093824A0C700D414A000409C -:101390003C0C80008F840034908700D42418FFBF59 -:1013A0002406FFEF30E3007FA08300D4979F00580E -:1013B0008F82005C8F8D003403E2C823A799005808 -:1013C000A5A000BC91AF00D401F87024A1AE00D458 -:1013D0008F8C0034A18000D78F8A0034A540008212 -:1013E000AD4000EC914500D400A65824A14B00D498 -:1013F0008F9000308F84005C97860058020428216B -:1014000010C0000FAF850030A38000543C0780005F -:101410008E2C000894ED01208E2B0004018D5021AC -:10142000014B8021020620233086FFFF30C8000FC9 -:10143000390900013131000116200009A388005448 -:10144000938600448FBF00188FB100148FB0001036 -:1014500027BD0020AF85006003E00008AF86005C78 -:1014600000C870238FBF0018938600448FB100140A -:101470008FB0001034EF0C00010F282127BD002091 -:10148000ACEE0084AF85006003E00008AF86005C2E -:1014900035900180020028210E0018A62406008243 -:1014A0008F840034908600D430C5004050A0FFBA2D -:1014B000A38000648F8500483C0680008CCD01B875 -:1014C00005A0FFFE8F8900682408608224070002BF -:1014D000AE090000A6080008A207000B8CA30008B4 -:1014E0003C0E1000AE0300108CA2000CAE020014E3 -:1014F0008CBF0014AE1F00188CB90018AE19002460 -:101500008CB80024AE1800288CAF0028AE0F002C39 -:10151000ACCE01B80A0018DFA38000648F8A0034C3 -:1015200027BDFFE0AFB10014AFB000108F88005CA2 -:10153000AFBF001893890038954200BC30D100FF3E -:101540000109182B0080802130AC00FF3047FFFFDD -:101550000000582114600003310600FF01203021F3 -:1015600001095823978300580068202B1480002716 -:101570000000000010680056241900011199006352 -:1015800034E708803165FFFF0E0018570200202164 -:101590008F8300683C07800034E601803C058000B2 -:1015A0008CAB01B80560FFFE240A00188F8400345C -:1015B000ACC30000A0CA000B948900BE3C08100018 -:1015C000A4C90010ACC00030ACA801B8948200805F -:1015D00024430001A4830080949F00803C060800FF -:1015E0008CC6318833EC7FFF1186005E000000005E -:1015F00002002021022028218FBF00188FB1001483 -:101600008FB000100A0018CB27BD0020914400D4F1 -:101610002403FF8000838825A15100D497840058BB -:101620003088FFFF51000023938C00388F850034F1 -:101630002402EFFF008B782394AE00BC0168502B8E -:1016400031E900FF01C26824A4AD00BC514000395B -:10165000010058213C1F800037E601008CD80004AF -:101660003C190001031940245500000134E74000F3 -:101670008E0A00202403FFFB2411000101432024D3 -:10168000AE0400201191002D34E7800002002021DB -:10169000012030210E0018573165FFFF9787005851 -:1016A0008F89005CA780005801278023AF90005CE1 -:1016B000938C00388F8B00348FBF00188FB10014CB -:1016C0008FB0001027BD002003E00008A16C00D7F8 -:1016D0003C0D800035AA01008D4800043C09000142 -:1016E0000109282454A0000134E740008E0F002097 -:1016F0002418FFFB34E7800001F87024241900014E -:10170000AE0E00201599FF9F34E7088002002021CB -:101710000E0018253165FFFF02002021022028213C -:101720008FBF00188FB100148FB000100A0018CBC3 -:1017300027BD00200A00198E000048210200202148 -:10174000012030210E0018253165FFFF97870058D2 -:101750008F89005CA7800058012780230A0019A503 -:10176000AF90005C948C0080241F8000019F302487 -:10177000A4860080908B0080908F0080316700FFEE -:101780000007C9C20019C027001871C031ED007FE1 -:1017900001AE2825A08500800A00197602002021CC -:1017A000938500642403000127BDFFE800A33004F3 -:1017B0002CA20020AFB00010AFBF001400C0182151 -:1017C000104000132410FFFE3C0708008CE7319006 -:1017D00000E610243C088000350501801440000517 -:1017E000240600848F890034240A00042410FFFF9B -:1017F000A12A00FC0E0018A6000000000200102123 -:101800008FBF00148FB0001003E0000827BD001840 -:101810003C0608008CC631940A0019EE00C310245F -:101820008F87004027BDFFE0AFB20018AFB10014B2 -:10183000AFB00010AFBF001C30D000FF90E6000D2D -:1018400000A088210080902130C5007FA0E5000D18 -:101850008F8500348E2300188CA200D01062002ED9 -:10186000240A000E0E0019E1A38A00642409FFFF78 -:10187000104900222404FFFF520000200000202114 -:101880008E2600003C0C001000CC58241560003956 -:101890003C0E000800CE682455A0003F02402021E5 -:1018A0003C18000200D880241200001F3C0A0004EB -:1018B0008F8700408CE200148CE300108CE500144C -:1018C0000043F82303E5C82B132000050240202124 -:1018D0008E24002C8CF10010109100310240202148 -:1018E00024020012A38200640E0019E12412FFFFFB -:1018F000105200022404FFFF000020218FBF001CB3 -:101900008FB200188FB100148FB00010008010212A -:1019100003E0000827BD002090A800D43504002073 -:101920000A001A17A0A400D400CA48241520000BEE -:101930008F8B00408F8D00408DAC00101580000B08 -:10194000024020218E2E002C51C0FFEC00002021EF -:10195000024020210A001A32240200178D6600106E -:1019600050C0FFE600002021024020210A001A3268 -:101970002402001102402021240200150E0019E16A -:10198000A3820064240FFFFF104FFFDC2404FFFF3D -:101990000A001A218E2600000A001A582402001498 -:1019A0003C08000400C8382450E0FFD40000202187 -:1019B000024020210A001A32240200138F850034CD -:1019C00027BDFFD8AFB3001CAFB20018AFB10014F1 -:1019D000AFB00010AFBF002090A700D48F90004898 -:1019E0002412FFFF34E2004092060000A0A200D4BF -:1019F0008E030010008098211072000630D1003F45 -:101A00002408000D0E0019E1A3880064105200257F -:101A10002404FFFF8F8A00348E0900188D4400D003 -:101A20001124000702602021240C000E0E0019E191 -:101A3000A38C0064240BFFFF104B001A2404FFFF4B -:101A400024040020122400048F8D003491AF00D4B0 -:101A500035EE0020A1AE00D48F85005010A00019F3 -:101A6000000000001224004A8F9800348F92FCB8C6 -:101A7000971000809651000A523000488F93003C26 -:101A80003C1F08008FFF318C03E5C82B1720001E78 -:101A900002602021000028210E00194024060001C8 -:101AA000000020218FBF00208FB3001C8FB20018D0 -:101AB0008FB100148FB000100080102103E00008E7 -:101AC00027BD00285224002A8E0500148F8400347C -:101AD000948A008025490001A489008094880080B0 -:101AE0003C0208008C42318831077FFF10E2000E73 -:101AF00000000000026020210E0018CB2405000128 -:101B00000A001AA2000020212402002D0E0019E173 -:101B1000A38200642403FFFF1443FFE12404FFFFBA -:101B20000A001AA38FBF002094990080241F800010 -:101B300024050001033FC024A498008090920080F7 -:101B4000908E0080325100FF001181C20010782772 -:101B5000000F69C031CC007F018D5825A08B00801B -:101B60000E0018CB026020210A001AA200002021DA -:101B70002406FFFF54A6FFD68F8400340260202184 -:101B80000E0018CB240500010A001AA20000202133 -:101B9000026020210A001ABC2402000A2404FFFD6E -:101BA0000A001AA2AF93005C8F88003427BDFFE8BB -:101BB000AFB00010AFBF0014910A00D48F87004867 -:101BC00000808021354900408CE60010A10900D436 -:101BD0003C0208008C4231B030C53FFF00A2182BF8 -:101BE000106000078F85004C240DFF8090AE000D23 -:101BF00001AE6024318B00FF156000080006C3822F -:101C0000020020212403000D8FBF00148FB00010AC -:101C100027BD00180A0019E1A383006433060003FE -:101C2000240F000254CFFFF70200202194A2001CD1 -:101C30008F85003424190023A4A200E88CE800005A -:101C400000081E02307F003F13F900353C0A008374 -:101C50008CE800188CA600D01106000800000000D7 -:101C60002405000E0E0019E1A38500642407FFFF80 -:101C7000104700182404FFFF8F85003490A900D47A -:101C800035240020A0A400D48F8C0040918E000D3C -:101C900031CD007FA18D000D8F8300501060001C9E -:101CA000020020218F84004C8C9800100303782BB5 -:101CB00011E0000D2419001802002021A3990064EE -:101CC0000E0019E12410FFFF105000022404FFFF52 -:101CD000000020218FBF00148FB000100080102161 -:101CE00003E0000827BD00188C8600108F9F00407D -:101CF0000200202100C31023AFE2001024050001E0 -:101D00000E001940240600010A001B2E00002021AD -:101D10000E0018CB240500010A001B2E0000202114 -:101D2000010A5824156AFFD98F8C0040A0A600FC38 -:101D30000A001B1BA386005630A500FF24060001E5 -:101D400024A9000100C9102B1040000C0000402104 -:101D5000240A000100A61823308B000124C60001CC -:101D6000006A3804000420421160000200C9182BE8 -:101D7000010740251460FFF800A6182303E00008BF -:101D80000100102127BDFFD8AFB000188F90004888 -:101D9000AFB1001CAFBF00202403FFFF2411002FB0 -:101DA000AFA30010920600002405000826100001D1 -:101DB000006620260E001B47308400FF00021E0034 -:101DC0003C021EDC34466F410A001B6F00001021EC -:101DD00010A00009008018212445000130A2FFFF57 -:101DE0002C4500080461FFFA0003204000862026ED -:101DF00014A0FFF9008018210E001B4724050020C5 -:101E00008FA300102629FFFF313100FF000342029B -:101E1000240700FF1627FFE20102182600035027BF -:101E2000AFAA0014AFAA00100000302127A80010AC -:101E300027A7001400E6782391ED000324CE0001CB -:101E400000C8602131C600FF2CCB00041560FFF9EB -:101E5000A18D00008FA200108FBF00208FB1001C49 -:101E60008FB0001803E0000827BD002827BDFFD071 -:101E7000AFB3001CAFB00010AFBF0028AFB5002457 -:101E8000AFB40020AFB20018AFB100143C0C80001A -:101E90008D880128240FFF803C06800A2510010050 -:101EA000250B0080020F68243205007F016F70242B -:101EB000AD8E009000A62821AD8D002490A600FCD8 -:101EC0003169007F3C0A8004012A1821A38600564C -:101ED0009067007C00809821AF83002C30E20002E4 -:101EE000AF880068AF85003400A0182114400002BC -:101EF0002404003424040030A38400448C7200DCE9 -:101F000030D100FF24040004AF92005C12240004CE -:101F1000A38000648E7400041680001E3C088000BC -:101F20009386005530C7000150E0000F8F86005C9B -:101F30008CA400848CA800842413FF800093602468 -:101F4000000C49403110007F013078253C192000F9 -:101F500001F9682530DF00FE3C038000AC6D0830DD -:101F6000A39F00558F86005C8FBF00288FB500248B -:101F70008FB400208FB3001C8FB200188FB10014F3 -:101F80008FB000102402000127BD003003E00008DC -:101F9000ACA600DC8E7F0008950201208E67001041 -:101FA00003E2C8213326FFFF30D8000F33150001AC -:101FB000AF87003016A00058A398005435090C00D4 -:101FC0000309382100D81823AD030084AF870060CF -:101FD0008E6A00043148FFFF1100007EA78A005876 -:101FE00090AC00D42407FF8000EC302430CB00FFFD -:101FF0001560004B97860058938E0056240D000202 -:1020000030D5FFFF11CD02A20000A0218F85005C1A -:1020100002A5802B160000BC938800443C11800070 -:1020200096240120310400FF148500888F8400600D -:102030008F980030331200035640008530A500FF12 -:102040008F900060310C00FF24060034118600954B -:10205000AF90004892040004148001198F8E003460 -:10206000A38000388E0D00048DC800D83C0600FF08 -:1020700034CCFFFF01AC30240106182B1460012181 -:10208000AF8600508F87005C97980058AF87003C60 -:102090000307402310C000C7A78800588F91002C69 -:1020A00030C3000300035823922A007C31710003DF -:1020B00002261021000A208230920001001248807E -:1020C00000492821311FFFFF03E5C82B1320012001 -:1020D0008F8800348F8500308F8800601105025A88 -:1020E0003C0E3F018E0600003C0C250000CE68240B -:1020F00011AC01638F84004830E500FF0E0017E14A -:10210000000030218F8800348F87005C8F8500307D -:102110000A001D4E8F8600500A001BEDAF8700603D -:1021200090AC00D400EC2024309000FF1200001688 -:102130009386005590B5008890B400D724A80088F5 -:1021400032A2003F2446FFE02CD10020A3940038A7 -:102150001220000CAF880048240E000100CE20049D -:10216000308A00191540012B3C06800034D800024B -:10217000009858241560022E309200201640023438 -:10218000000000009386005530CE000111C0000F02 -:10219000978800588CA900848CAF00842410FF809D -:1021A0000130C8240019194031ED007F006D382539 -:1021B0003C1F200000FF902530CB00FE3C18800023 -:1021C000AF120830A38B0055978800581500FF8484 -:1021D000000000008E630020306C00041180FF516D -:1021E000938600552404FFFB006430243C038000E8 -:1021F000AE660020346601808C7301B80660FFFE75 -:102200008F8E0068346A01003C150001ACCE0000DE -:102210008C62012424076085ACC200048D54000444 -:1022200002958824522000012407608324120002B2 -:102230003C1810003C0B8000A4C70008A0D2000B83 -:10224000AD7801B80A001BC29386005530A500FF87 -:102250000E0017E1240600018F8800683C0580000D -:1022600034A909002502018893880044304A0007F8 -:10227000304B00783C0340802407FF800163C82571 -:10228000014980210047F824310C00FF2406003466 -:10229000ACBF0800AF900048ACB908105586FF6E7F -:1022A000920400048F8400348E110030908E00D48C -:1022B00031CD001015A000108F83005C2C6F00053D -:1022C00015E000E400000000909800D42465FFFCB5 -:1022D000331200101640000830A400FF8F9F0060EA -:1022E0008F99003013F900043887000130E20001B3 -:1022F000144001C8000000000E001B5A000000003E -:102300000A001D8F000000008F84006030C500FFB0 -:102310000E0017E124060001938E0044240A0034C5 -:1023200011CA00A08F8500348F86005C9783005807 -:102330003062FFFF00C28823AF91005CA780005885 -:102340001280FF90028018212414FFFD5474FFA214 -:102350008E6300208E6900042403FFBF240BFFEF6F -:102360000135C823AE79000490AF00D431ED007F71 -:10237000A0AD00D48E6600208F980034A78000584E -:1023800034DF0002AE7F0020A70000BC931200D40F -:1023900002434024A30800D48F950034AEA000EC83 -:1023A00092AE00D401CB5024A2AA00D40A001C6E25 -:1023B0008F8500348F910030AF80005C0227582158 -:1023C000AF8B0030000020212403FFFF108301B4F5 -:1023D0008F8500348E0C00103C0D08008DAD31B09F -:1023E0009208000031843FFF008D802B12000023F3 -:1023F000310D003F3C1908008F3931A88F9F0068CC -:10240000000479802408FF80033F2021008FC82129 -:10241000938500550328F8243C0600803C0F80007B -:1024200034D80001001F91403331007F8F86003483 -:102430000251502535EE0940332B00783330000728 -:102440003C0310003C02800C01789025020E4821CC -:102450000143C0250222382134AE0001ADFF08043B -:10246000AF89004CADF20814AF870040ADFF0028E3 -:10247000ACD90084ADF80830A38E00559383005684 -:10248000240700035067002825A3FFE0240C000167 -:10249000146CFFAB8F8500342411002311B100842C -:1024A000000000002402000B026020210E0019E150 -:1024B000A38200640040A0210A001CC98F8500345B -:1024C00002602021240B000C0E0019E1A38B006494 -:1024D000240AFFFF104AFFBC2404FFFF8F8E003444 -:1024E000A38000388E0D00048DC800D83C0600FF84 -:1024F00034CCFFFF01AC30240106182B1060FEE144 -:10250000AF86005002602021241200190E0019E14C -:10251000A3920064240FFFFF104FFFAB2404FFFFC2 -:102520000A001C1A8F8600502C7400201280FFDED7 -:102530002402000B000328803C110801263192EC94 -:1025400000B148218D2D000001A00008000000000E -:102550008F85003000A7102193850038AF820030AE -:1025600002251821A3830038951F00BC02262821CC -:1025700037F91000A51900BC5240FF92AF85005CEE -:10258000246A0004A38A0038950900BC24A400042E -:10259000AF84005C35322000A51200BC0A001CEBA1 -:1025A000000020218F86005C2CCB00051560FF60A9 -:1025B000978300583072FFFF00D240232D1800058A -:1025C00013000003306400FF24DFFFFC33E400FF4E -:1025D0008F8500608F86003010A60004388F0001C0 -:1025E00031ED000115A00138000000008F84003497 -:1025F000908C00D435870010A08700D48F850034DC -:102600008F86005C97830058ACA000EC0A001CC6C3 -:102610003062FFFF8CAA00848CB500843C0410005B -:10262000014710240002894032B4007F0234302573 -:1026300000C460253C0880002405000102602021C0 -:10264000240600010E001940AD0C08300A001C5A87 -:102650008F8500348C8200EC1222FE7E02602021E5 -:1026600024090005A38900640E0019E12411FFFF6D -:102670001451FE782404FFFF0A001CEC2403FFFF22 -:102680008F8F00488F8800348DF80000AD180088C7 -:102690008DE70010AD0700988F87005C0A001D4E83 -:1026A0008F8600502407FFFF1187000500000000FF -:1026B0000E001AE3026020210A001D270040A0211D -:1026C0000E001A68026020210A001D270040A02188 -:1026D0008F9000483C0908008D2931B08E11001000 -:1026E00032323FFF0249682B11A0000C240AFF8000 -:1026F0008F85004C90AE000D014E1024304C00FF31 -:1027000011800007026020210011C38233030003FF -:10271000240B0001106B0105000000000260202165 -:102720002418000D0E0019E1A39800640040202138 -:102730008F8500340A001CC90080A0218F900048BA -:102740003C0A08008D4A31B08F85004C8E04001081 -:102750000000A0218CB1001430823FFF004A602BA2 -:102760008CB200205180FFEE0260202190B8000D55 -:10277000240BFF800178702431C300FF5060FFE814 -:1027800002602021000443823106000314C0FFE4EC -:102790000260202194BF001C8F9900348E0600280F -:1027A000A73F00E88CAF0010022F202314C401398A -:1027B000026020218F83005000C36821022D382B36 -:1027C00014E00135240200188F8A00408F82002C0B -:1027D000024390218D4B001001637023AD4E001019 -:1027E000AD5200208C4C00740192282B14A001568D -:1027F000026020218F84004C8E0800248C860024E7 -:1028000011060007026020212419001C0E0019E1A6 -:10281000A3990064240FFFFF104FFFC52404FFFF9E -:102820008F8400408C87002424FF0001AC9F00248B -:10283000125101338F8D002C8DB100741232013092 -:102840003C0B00808E0E000001CB5024154000751B -:10285000000000008E0300142411FFFF1071000619 -:10286000026020212418001B0E0019E1A3980064C7 -:102870001051FFAF2404FFFF8E0300003C0800014D -:102880000068302410C000133C0400800064A024C1 -:102890001680000902002821026020212419001A54 -:1028A0000E0019E1A3990064240FFFFF104FFFA051 -:1028B0002404FFFF02002821026020210E001A01DB -:1028C000240600012410FFFF1050FF992404FFFF8D -:1028D000241400018F9F00400260202102803021DB -:1028E00097F100342405000126270001A7E70034F2 -:1028F0000E00194000000000000020218F850034E8 -:102900000A001CC90080A0218F9000483C140800D8 -:102910008E9431B08E07001030E83FFF0114302B49 -:1029200010C000618F86004C241FFF8090C5000DF1 -:1029300003E52024309200FF5240005C0260202119 -:102940008F8D005011A0000700078B828F85003407 -:102950008F89FCB894AF00809539000A132F00F6D8 -:102960008F87003C322C00031580006300000000BC -:1029700092020002104000D7000000008E0A0024DE -:10298000154000D8026020219204000324060002B2 -:10299000308800FF15060005308500FF8F94005039 -:1029A000528000F202602021308500FF38AD001017 -:1029B0002DA400012CBF000103E4302502002821D2 -:1029C0000E001A01026020212410FFFF105000BEEB -:1029D0008F8500348F830050106000C424050001EF -:1029E0003C1908008F39318C0323782B15E000B196 -:1029F0002409002D02602021000028210E0019402A -:102A0000240600018F850034000018210A001CC92B -:102A10000060A0210E00180C000000000A001D8FAD -:102A200000000000AC8000200A001E0F8E0300147E -:102A300000002821026020210E0019402406000118 -:102A40000A001C5A8F8500340A001D4E8F880034FE -:102A50008CB000848CB900843C0310000207482429 -:102A600000096940332F007F01AFF82503E32825D3 -:102A7000ACC5083091070001240500010260202147 -:102A80000E00194030E600010A001C5A8F85003400 -:102A9000938F00442403FFFD0A001CCBAF8F005C22 -:102AA0000A001CCB2403FFFF026020212410000D2C -:102AB0000E0019E1A3900064004018218F850034B6 -:102AC0000A001CC90060A0210E00180C00000000C4 -:102AD000978300588F86005C3070FFFF00D048233A -:102AE0002D3900051320FE128F850034ACA200ECB6 -:102AF0000A001CC63062FFFF90C3000D307800084A -:102B00005700FFA29204000302602021240200105B -:102B10000E0019E1A38200642403FFFF5443FF9BCE -:102B2000920400030A001EA98F85003490A8000DAE -:102B30003106000810C000958F9400501680009E4A -:102B4000026020218E0F000C8CA4002055E40005AB -:102B5000026020218E1F00088CB9002413F9003A6E -:102B600002602021240200200E0019E1A3820064EB -:102B70002405FFFF1045FEEE2404FFFF8F8F004069 -:102B8000240CFFF72403FF8091E9000D3C14800E14 -:102B90003C0B8000012CC824A1F9000D8F8F002C64 -:102BA0003C0708008CE731AC8F8D006895E5007814 -:102BB0008F99004000ED902130BF7FFF001F204023 -:102BC0000244302130C8007F00C3C02401147021AA -:102BD000AD78002CA5D100008F2A002825420001E5 -:102BE000AF2200288F29002C8E0C002C012C68218C -:102BF000AF2D002C8E07002CAF2700308E0500145F -:102C0000AF250034973F003A27E40001A724003A9B -:102C100095F200783C1008008E1031B02643000178 -:102C200030717FFF1230005C006030218F83002CF8 -:102C300002602021240500010E0018CBA466007854 -:102C40000A001E38000020218E0700142412FFFF06 -:102C500010F200638F8C00348E0900188D8D00D027 -:102C6000152D005D026020218E0A00248CA2002810 -:102C700011420053240200210E0019E1A3820064D6 -:102C80001452FFBE2404FFFF8F8500340A001CC9C4 -:102C90000080A0212402001F0E0019E1A38200641D -:102CA0002409FFFF1049FEA22404FFFF0A001DEBC8 -:102CB0008F830050026020210E0019E1A389006477 -:102CC0001450FF518F8500342403FFFF0A001CC9F4 -:102CD0000060A0218CCE00248E0B0024116EFF2AF0 -:102CE000026020210A001EBD2402000F0E0018CB36 -:102CF000026020218F8500340A001E7C000018210C -:102D00008E0900003C050080012590241640FF45F7 -:102D10002402001A026020210E0019E1A38200643F -:102D2000240CFFFF144CFECB2404FFFF8F850034DE -:102D30000A001CC90080A0212403FFFD0060A0211F -:102D40000A001CC9AF87005C2418001D0E0019E1A1 -:102D5000A39800642403FFFF1443FEA62404FFFF8E -:102D60008F8500340A001CC90080A0212412002C89 -:102D70000E0019E1A39200642403FFFF1043FF50EB -:102D80008F8500340A001E63920400030260202134 -:102D90000A001ED324020024240B8000006B702440 -:102DA00031CAFFFF000A13C2305100FF0011802713 -:102DB0000A001F04001033C00A001ED3240200279B -:102DC0008E0600288CAE002C10CE00080260202158 -:102DD0000A001F172402001F0A001F172402000EFA -:102DE000026020210A001F17240200258E04002CF7 -:102DF0001080000D8F83002C8C7800740304582BF6 -:102E00005560000C026020218CA800140086A021CF -:102E10000114302B10C0FF5A8F8F00400260202118 -:102E20000A001F1724020022026020210A001F1737 -:102E3000240200230A001F172402002627BDFFD802 -:102E4000AFB3001CAFB10014AFBF0020AFB2001889 -:102E5000AFB000103C0280008C5201408C4B014806 -:102E60003C048000000B8C02322300FF317300FF12 -:102E70008C8501B804A0FFFE34900180AE120000E2 -:102E80008C8701442464FFF0240600022C83001385 -:102E9000AE070004A6110008A206000BAE13002422 -:102EA0001060004F8FBF0020000448803C0A0801DA -:102EB000254A936C012A40218D04000000800008FF -:102EC000000000003C0308008C6331A831693FFF1B -:102ED0000009998000728021021370212405FF806F -:102EE000264D0100264C00803C02800031B1007F5D -:102EF0003198007F31CA007F3C1F800A3C19800452 -:102F00003C0F800C01C5202401A530240185382404 -:102F1000014F1821AC460024023F402103194821EB -:102F2000AC470090AC440028AF830040AF88003429 -:102F3000AF89002C0E001897016080213C038000AF -:102F40008C6B01B80560FFFE8F8700408F860034D0 -:102F50003465018090E8000DACB20000A4B000061A -:102F6000000826000004160300029027001227C262 -:102F70001080008124C20088241F6082A4BF000842 -:102F8000A0A0000524020002A0A2000B8F8B002C41 -:102F9000000424003C08270000889025ACB20010F3 -:102FA000ACA00014ACA00024ACA00028ACA0002C65 -:102FB0008D6900382413FF80ACA9001890E3000D40 -:102FC00002638024320500FF10A000058FBF00209F -:102FD00090ED000D31AC007FA0EC000D8FBF002004 -:102FE0008FB3001C8FB200188FB100148FB0001087 -:102FF0003C0A10003C0E800027BD002803E00008BA -:10300000ADCA01B8265F01002405FF8033F8007FB8 -:103010003C06800003E578243C19800A031920212E -:10302000ACCF0024908E00D400AE682431AC00FFF9 -:1030300011800024AF840034248E008895CD0012C6 -:103040003C0C08008D8C31A831AB3FFF0192482128 -:10305000000B5180012A402101052024ACC4002826 -:103060003107007F3C06800C00E620219083000D94 -:1030700000A31024304500FF10A0FFD8AF8400400B -:103080009098000D330F001015E0FFD58FBF002082 -:103090000E001897000000003C0380008C7901B8F6 -:1030A0000720FFFE00000000AE1200008C7F0144EC -:1030B000AE1F0004A611000824110002A211000B8B -:1030C000AE1300243C13080192739528327000015E -:1030D0005200FFC38FBF00200E0020D402402021E9 -:1030E0000A001FF18FBF00203C1260008E452C08A3 -:1030F0003C03F0033462FFFF00A2F824AE5F2C080B -:103100008E582C083C1901C003199825AE532C0881 -:103110000A001FF18FBF0020264D010031AF007F54 -:103120003C10800A240EFF8001F0282101AE6024AB -:103130003C0B8000AD6C00241660FFA8AF85003406 -:1031400024110003A0B100FC0A001FF18FBF002072 -:1031500026480100310A007F3C0B800A2409FF80C9 -:10316000014B3021010920243C078000ACE40024FD -:103170000A001FF0AF860034944E0012320C3FFF5D -:1031800031CD3FFF15ACFF7D241F608290D900D464 -:103190002418FF800319782431EA00FF1140FF77DB -:1031A0000000000024070004A0C700FC8F87004037 -:1031B000241160842406000DA4B10008A0A6000517 -:1031C0000A001FDB240200023C0400012484951441 -:1031D00024030014240200FE3C010800AC2431EC5E -:1031E0003C010800AC2331E83C010801A4229530E1 -:1031F0003C0408012484953000001821006430212B -:10320000A0C30004246300012C6500FF54A0FFFC50 -:10321000006430213C07080024E7010003E00008B7 -:10322000AF87007400A058210080482100001021C1 -:1032300014A00012000050210A0020D0000000005D -:103240003C010801A42095303C05080194A5953067 -:103250008F8200743C0C0801258C953000E2182107 -:1032600000AC2021014B302BA0890004000010216C -:10327000A460000810C00039010048218F86007446 -:103280000009384000E940210008388000E6282184 -:1032900090A8000B90B9000A000820400088102177 -:1032A000000218800066C021A319000A8F850074EF -:1032B00000E5782191EE000A91E6000B000E6840CF -:1032C00001AE6021000C208000851021A046000B7B -:1032D0003C0308019063952A106000222462FFFFDE -:1032E0008F8300343C010801A022952A906C00FFD6 -:1032F0001180000400000000906E00FF25CDFFFF4C -:10330000A06D00FF3C190801973995302723000173 -:103310003078FFFF2F0F00FF11E0FFC9254A0001A1 -:103320003C010801A42395303C05080194A5953083 -:103330008F8200743C0C0801258C953000E2182126 -:1033400000AC2021014B302BA0890004000010218B -:10335000A460000814C0FFC90100482103E0000870 -:103360000000000003E000082402000227BDFFE087 -:10337000248501002407FF80AFB00010AFBF001804 -:10338000AFB1001400A718243C10800030A4007FC7 -:103390003C06800A008628218E110024AE030024FA -:1033A00090A200FF14400008AF850034A0A00009DF -:1033B0008FBF0018AE1100248FB100148FB0001021 -:1033C00003E0000827BD002090A900FD90A800FFA1 -:1033D000312400FF0E002082310500FF8F8500346C -:1033E0008FBF0018A0A00009AE1100248FB10014F7 -:1033F0008FB0001003E0000827BD002027BDFFD0DC -:10340000AFB20020AFB1001CAFB00018AFBF002CAE -:10341000AFB40028AFB300243C09800095330116F7 -:1034200035320C00952F011A3271FFFF02328021D4 -:103430008E08000431EEFFFF248B0100010E68218D -:10344000240CFF8025A5FFFF016C50243166007F0E -:103450003C07800AAD2A002400C73021AF850070E8 -:10346000AF88006C3C010801A020952990C3000999 -:103470000200D02100809821306300FF28620005FF -:1034800010400048AF860034286400021480008E8B -:1034900024140001240D00053C010801A02D950D08 -:1034A00090CC00FD3C010801A020950E3C010801D4 -:1034B000A020950F90CB000A240AFF80318500FFE1 -:1034C000014B4824312700FF10E0000C0000582178 -:1034D0003C128008365100808E2F00308CD0005C6A -:1034E00001F0702305C0018E8F87006C90D4000A14 -:1034F0003284007FA0C4000A8F8600343C1180080B -:10350000363000808E0F00308F87006C00EF702304 -:1035100019C000EE0000000090D40009241200023F -:10352000328400FF10920247000000008CC2005855 -:1035300000E2F82327F9FFFF1B2001300000000004 -:1035400090C500092408000430A300FF106800574C -:10355000240A00013C010801A02A950D90C900FF32 -:10356000252700013C010801A027950C3C03080118 -:103570009063950D240600051066006A2C780005FE -:10358000130000C4000090210003F8803C040801EF -:10359000248493B803E4C8218F25000000A000080C -:1035A00000000000241800FF1078005C00000000FC -:1035B00090CC000A90CA00093C080801910895299E -:1035C0003187008000EA48253C010801A0299514B4 -:1035D00090C500FD3C1408019294952A3111000118 -:1035E0003C010801A025951590DF00FE3C01080173 -:1035F000A03F951690D200FF3C010801A03295171C -:103600008CD900543C010801AC3995188CD0005875 -:103610003C010801AC30951C8CC3005C3C010801E6 -:10362000AC3495243C010801AC23952016200008F9 -:103630008FBF002C8FB400288FB300248FB20020DE -:103640008FB1001C8FB0001803E0000827BD0030C8 -:103650003C1180009624010E0E000FD43094FFFF21 -:103660003C0B08018D6B952C0260382102802821CB -:10367000AE2B01803C1308018E73950C0160202154 -:10368000240600830E001046AFB300108FBF002C3D -:103690008FB400288FB300248FB200208FB1001C9C -:1036A0008FB0001803E0000827BD00303C18080068 -:1036B0008F1831FC270F00013C010800AC2F31FCB2 -:1036C0000A002165000000001474FFB9000000002A -:1036D000A0C000FF3C0508008CA531E43C030800B5 -:1036E0008C6331E03C0208008C4232048F99003434 -:1036F00034A80001241F00023C010801AC23952CD2 -:103700003C010801A02895283C010801A022952B26 -:10371000A33F00090A00211E8F8600340E0020D42A -:10372000000000000A0021658F8600343C1F08015C -:1037300093FF950C2419000113F902298F87006C5F -:103740003C100801921095103C06080190C6950E99 -:1037500010C000050200A0213C04080190849511CE -:10376000109001E48F870074001088408F9F0074D0 -:10377000023048210009C880033F702195D8000815 -:10378000270F0001A5CF00083C0408019084951183 -:103790003C05080190A5950E0E0020820000000057 -:1037A0008F870074023020210004308000C7202160 -:1037B0008C8500048F82007000A240230502000661 -:1037C000AC8200048C8A00008F83006C01431023BC -:1037D0005C400001AC8300008F86003490CB00FF7A -:1037E0002D6C00025580002D241400010230F821B8 -:1037F000001F40800107282190B9000B8CAE000407 -:103800000019C04003197821000F188000671021AB -:103810008C4D000001AE88232630FFFF5E00001FA4 -:10382000241400018C4400048CAA0000008A482360 -:1038300019200019240E00043C010801A02E950D4A -:1038400090AD000B8CAB0004000D8840022D802150 -:1038500000101080004710218C4400040164602394 -:10386000058202009443000890DF00FE90B9000B2F -:1038700033E500FF54B900040107A021A0D400FEE5 -:103880008F8700740107A0219284000B0E00208214 -:10389000240500018F860034241400011254009680 -:1038A0002E500001160000423C08FFFF24190002C0 -:1038B0001659FF3F00000000A0C000FF8F860034B3 -:1038C000A0D200090A0021658F86003490C7000944 -:1038D0002404000230E300FF1064016F2409000497 -:1038E000106901528F8800708CCE0054010E68233D -:1038F00025B1000106200175241800043C010801CF -:10390000A038950D3C010801A020950C90D400FD35 -:1039100090D200FF2E4F000215E0FF14328400FF0A -:10392000000438408F89007490DF00FF00E410210C -:10393000000220800089C8212FE500029324000B9B -:1039400014A0FF0A2407000200041840006480212C -:1039500000105880016928218CAC0004010C502310 -:103960000540FF02000000003C0308019063950E33 -:1039700014600005246F00013C010801A02495118A -:103980003C010801A027950F3C010801A02F950ECE -:1039900090CE00FF24E7000131CD00FF01A7882B66 -:1039A0001220FFE990A4000B0A002154000000003F -:1039B0003C0508018CA5950C3C12000400A8F824D5 -:1039C00013F20006240200053C0908019129950D17 -:1039D0001520000224020003240200053C01080116 -:1039E000A022952990C700FF14E0012024020002C4 -:1039F000A0C200090A0021658F86003490CC00FF28 -:103A00001180FEDA240A00018F8C00708F89007407 -:103A1000240F0003018068211160001E240E0002A3 -:103A2000000540400105A02100142080008990215C -:103A30008E510004019180230600FECC000000009E -:103A40003C0208019042950E1440000524580001E4 -:103A50003C010801A02A950F3C010801A025951101 -:103A60003C010801A038950E90DF00FF01051021F0 -:103A70000002C88033E500FF254A00010329202108 -:103A800000AA402B1500FEB99085000B1560FFE5DC -:103A9000000540400005404001051821000310804A -:103AA0003C010801A02A950C3C010801A0259510B5 -:103AB000004918218C64000400E4F82327F9FFFF73 -:103AC0001F20FFE9000000008C63000000E3582382 -:103AD0000560013A01A3882310E301170184C02384 -:103AE0001B00FEA2000000003C010801A02E950D65 -:103AF0000A002293240B0001240E0004A0CE00092A -:103B00003C0D08008DAD31F88F86003425A20001F0 -:103B10003C010800AC2231F80A00216500000000D9 -:103B20008CD9005C00F9C0231F00FE7B0000000060 -:103B30008CDF005C10FFFF658F8400708CC3005C1D -:103B400000834023250200011C40FF6000000000AC -:103B50008CC9005C2487000100E9282B10A0FE948A -:103B60003C0D80008DAB01043C0C0001016C502425 -:103B70001140FE8F240200103C010801A02295296B -:103B80000A002165000000008F9100708F860034CC -:103B900026220001ACC2005C0A002220241400018D -:103BA0008F8700342404FF800000882190E9000AF8 -:103BB0002414000101243025A0E6000A3C05080178 -:103BC00090A5950E3C040801908495110E0020826A -:103BD000000000008F8600348F85007490C800FDBF -:103BE000310700FF000740400107F821001FC08097 -:103BF0000305C8219323000BA0C300FD8F8500742B -:103C00008F86003403056021918F000B000F7040F8 -:103C100001CF6821000D8080020510218C4B00002F -:103C2000ACCB00548D8400048F830070006450235B -:103C3000194000022482000124620001010748218A -:103C4000ACC2005C0009308000C5402100E02021AA -:103C5000240500010E0020829110000B8F86003495 -:103C600090C500FF10A0FF0C001070408F850074FD -:103C700001D06821000D1080004558218D6400009E -:103C80008F8C0070018450232547000104E0FF025F -:103C9000263100013C0308019063950E2E2F00028F -:103CA000247800013C010801A038950E3C01080170 -:103CB000A034950F11E0FEF8020038210A0022F32B -:103CC000000740408F8400348F8300708C8500583B -:103CD00000A340230502FE9AAC8300580A0021C9C4 -:103CE000000000003C07080190E7952A240200FF2D -:103CF00010E200BE8F8600343C11080196319532E7 -:103D00003C03080124639530262500013230FFFF73 -:103D100030ABFFFF020360212D6A00FF1540008DCC -:103D2000918700043C010801A42095328F8800345B -:103D30000007484001272821911800FF0005308026 -:103D40002405000127140001A11400FF3C12080102 -:103D50009252952A8F8800748F8E006C264F000136 -:103D600000C820213C010801A02F952AAC8E00003C -:103D70008F8D0070A4850008AC8D00043C03080101 -:103D80009063950C14600077000090213C010801BD -:103D9000A025950CA087000B8F8C007400CC5021BF -:103DA000A147000A8F820034A04700FD8F840034B1 -:103DB000A08700FE8F8600348F9F006CACDF00541C -:103DC0008F990070ACD900588F8D00740127C021E5 -:103DD00000185880016DA021928F000A000F7040DA -:103DE00001CF182100038880022D8021A207000B3B -:103DF0008F86007401666021918A000B000A1040D2 -:103E0000004A20210004288000A64021A107000AC2 -:103E10003C07800834E900808D2200308F86003412 -:103E2000ACC2005C0A0022202414000190CA00FFEA -:103E30001540FEAD8F880070A0C400090A002165FE -:103E40008F860034A0C000FD8F9800342406000146 -:103E5000A30000FE3C010801A026950D3C010801CD -:103E6000A020950C0A0021540000000090CB00FF18 -:103E70003C0408019084952B316C00FF0184502B89 -:103E80001540000F2402000324020004A0C2000910 -:103E90000A0021658F86003490C3000A2410FF8039 -:103EA00002035824316C00FF1180FDC100000000A6 -:103EB0003C010801A020950D0A00215400000000DB -:103EC000A0C200090A0021658F86003490D4000A40 -:103ED0002412FF8002544824312800FF1500FFF40B -:103EE000240200083C010801A02295290A0021654E -:103EF00000000000001088408F8B006C02301821F9 -:103F00000003688001A72021AC8B00008F8A00701D -:103F1000240C0001A48C0008AC8A00043C050801B4 -:103F200090A5950E2402000110A2FE1E24A5FFFFFD -:103F30000A0021DF9084000B0184A0231A80FD8BEE -:103F4000000000003C010801A02E950D0A002293FC -:103F5000240B00013C010801A42595320A002345E9 -:103F60008F880034240B0001106B00228F980034DE -:103F70008F85003490BF00FF33F900FF1079002BCC -:103F8000000000003C1F080193FF9510001FC8406F -:103F9000033FC0210018A0800288782191EE000A1A -:103FA000A08E000A8F8D00743C0308019063951069 -:103FB00000CD88210A00236BA223000B26300001CC -:103FC0000600003101A490230640002B24020003C8 -:103FD0003C010801A02F950D0A002293240B00013B -:103FE0008F8900340A0021C9AD2700540A00221F1E -:103FF00024120001931400FDA094000B8F8800345C -:104000008F8F0074910E00FE00CF6821A1AE000AD0 -:104010008F910034A22700FD8F83006C8F900034B5 -:10402000AE0300540A00236C8F8D007490B000FE24 -:10403000A090000A8F8B00348F8C0074916A00FD71 -:1040400000CC1021A04A000B8F840034A08700FE12 -:104050008F8600708F850034ACA600580A00236C50 -:104060008F8D007494B80008ACA400040303782179 -:104070000A002213A4AF00083C010801A022950DFC -:104080000A0021540000000090CF0009240D000414 -:1040900031EE00FF11CDFD85240200013C01080135 -:0C40A000A022950D0A0021540000000031 -:0440AC000800334491 -:1040B0000800334408003420080033F4080033D8E3 -:1040C0000800332808003328080033280800334C40 -:1040D0008008010080080080800800005F86543757 -:1040E000E4AC62CC50103A4536621985BF14C0E882 -:1040F0001BC27A1E84F4B556094EA6FE7DDA01E78E -:10410000C04D7481080058D008005914080058B8F0 -:10411000080058B8080058B8080058B8080058D027 -:10412000080058B8080058B80800591C080058B8CA -:1041300008005830080058B8080058B80800591C42 -:10414000080058B8080058B8080058B8080058B80F -:10415000080058B8080058B8080058B8080058B8FF -:10416000080058B8080058B8080058F0080058B8B7 -:10417000080058F0080058B8080058B8080058B8A7 -:10418000080058F4080058F0080058B8080058B85B -:10419000080058B8080058B8080058B8080058B8BF -:1041A000080058B8080058B8080058B8080058B8AF -:1041B000080058B8080058B8080058B8080058B89F -:1041C000080058B8080058B8080058B8080058B88F -:1041D000080058B8080058B8080058F4080058F407 -:1041E000080058B8080058F4080058B8080058B833 -:1041F000080058B8080058B8080058B8080058B85F -:10420000080058B8080058B8080058B8080058B84E -:10421000080058B8080058B8080058B8080058B83E -:10422000080058B8080058B8080058B8080058B82E -:10423000080058B8080058B8080058B8080058B81E -:10424000080058B8080058B8080058B8080058B80E -:10425000080058B8080058B8080058B8080058B8FE -:10426000080058B8080058B8080058B8080058B8EE -:10427000080058B8080058B8080058B8080058B8DE -:10428000080058B8080058B8080058B8080058B8CE -:10429000080058B8080058B8080058B8080058B8BE -:1042A000080058B8080058B8080058B8080058B8AE -:1042B000080058B8080058B8080058B8080058B89E -:1042C000080058B8080058B8080058B8080058B88E -:1042D000080058B8080058B8080058B8080058B87E -:1042E000080058B8080058B8080058B8080058B86E -:1042F000080058B8080058B8080058B8080058B85E -:10430000080058B80800593808007688080078EC8A -:1043100008007694080074880800769408007720D6 -:10432000080076940800748808007488080074886F -:10433000080074880800748808007488080074886D -:10434000080074880800748808007488080076B42F -:10435000080076A40800748808007488080074882F -:10436000080074880800748808007488080074883D -:10437000080074880800748808007488080074882D -:1043800008007488080076A40800813408007FC003 -:10439000080080FC08007FC0080080CC08007EA8D0 -:1043A00008007FC008007FC008007FC008007FC0F1 -:1043B00008007FC008007FC008007FC008007FC0E1 -:1043C00008007FC008007FC008007FC008007FC0D1 -:1043D00008007FE808008B6C08008CC808008CA8D7 -:0843E0000800871008008B841F -:0843E8000A000124000000009E -:1043F000000000000000000D747061362E302E3178 -:10440000370000000600110100000000000000005D -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:104470000000000000000000000000001000000329 -:10448000000000000000000D0000000D3C020800CC -:10449000244217203C03080024632A10AC4000008B -:1044A0000043202B1480FFFD244200043C1D080023 -:1044B00037BD2FFC03A0F0213C100800261004900B -:1044C0003C1C0800279C17200E0002620000000020 -:1044D0000000000D2402FF8027BDFFE000821024B1 -:1044E000AFB00010AF420020AFBF0018AFB1001452 -:1044F000936500043084007F034418213C020008C7 -:104500000062182130A50020036080213C080111C1 -:10451000277B000814A000022466005C2466005873 -:104520009202000497430104920400043047000FF4 -:104530003063FFFF308400400067282310800009AB -:10454000000048219202000530420004104000059E -:104550000000000010A000030000000024A5FFFCE4 -:1045600024090004920200053042000410400012A9 -:104570000000000010A000100000000096020002E1 -:1045800000A72021010440252442FFFEA742101667 -:10459000920300042402FF8000431024304200FFF5 -:1045A000104000033C0204000A000174010240258F -:1045B0008CC20000AF4210188F4201780440FFFE09 -:1045C0002402000AA74201409602000224040009C6 -:1045D000304200070002102330420007A742014288 -:1045E000960200022442FFFEA7420144A740014672 -:1045F00097420104A74201488F420108304200203F -:1046000050400001240400019202000430420010D6 -:10461000144000023483001000801821A743014A8F -:10462000000000000000000000000000000000008A -:10463000AF48100000000000000000000000000073 -:10464000000000008F4210000441FFFE3102FFFF16 -:1046500010400007000000009202000430420040B9 -:1046600014400003000000008F421018ACC200008C -:10467000960200063042FFFF24420002000210436F -:104680000002104003628821962200001120000DD4 -:104690003044FFFF00A710218F8300388F45101C86 -:1046A000000210820002108000431021AC4500007F -:1046B00030A6FFFF0E00058D00052C0200402021D2 -:1046C000A6220000920300042402FF80004310246D -:1046D000304200FF1040001F000000009202000561 -:1046E000304200021040001B000000009742100CF6 -:1046F0002442FFFEA7421016000000003C02040006 -:1047000034420030AF421000000000000000000002 -:1047100000000000000000008F4210000441FFFE76 -:10472000000000009742100C8F45101C3042FFFF24 -:10473000244200300002108200021080005B102131 -:10474000AC45000030A6FFFF0E00058D00052C02D1 -:10475000A622000096040002248400080E0001E94D -:104760003084FFFF974401040E0001F73084FFFFFF -:104770008FBF00188FB100148FB000103C021000E2 -:1047800027BD002003E00008AF4201783084FFFF1E -:10479000308200078F850024104000022483000728 -:1047A0003064FFF800A4102130421FFF034218219B -:1047B000247B4000AF850028AF82002403E000087E -:1047C000AF4200843084FFFF3082000F8F85002CC1 -:1047D0008F860034104000022483000F3064FFF005 -:1047E00000A410210046182BAF850030004620237E -:1047F00014600002AF82002CAF84002C8F82002C4A -:10480000340480000342182100641821AF8300386B -:1048100003E00008AF4200808F82001410400008BF -:104820008F8200048F82FFDC144000058F82000419 -:104830003C02FFBF3442FFFF008220248F8200042D -:1048400030430006240200021062000F3C02010106 -:104850002C62000350400005240200041060000F89 -:104860003C0200010A000230000000001062000556 -:10487000240200061462000C3C0201110A00022905 -:10488000008210253C02001100821025AF4210006A -:10489000240200010A000230AF82000C00821025C1 -:1048A000AF421000AF80000C0000000000000000CC -:1048B0000000000003E00008000000008F82000CF0 -:1048C00010400004000000008F4210000441FFFE71 -:1048D0000000000003E00008000000008F820010CC -:1048E0002443F800000231C224C2FFF02C6303010C -:1048F00010600003000210420A000257AC82000060 -:104900008F85001800C5102B1440000B00001821E3 -:1049100000C51023244700018F82001C00A2102133 -:104920002442FFFF0046102B544000042402FFFFE6 -:104930000A000257AC8700002402FFFF0A00026051 -:10494000AC8200008C820000000219400062182135 -:104950000003188000621821000318803C02080040 -:104960002442175C0062182103E000080060102157 -:1049700027BDFFD8AFBF0020AFB1001CAFB00018FB -:104980003C0460088C8250002403FF7F3C066000DA -:10499000004310243442380CAC8250008CC24C1CB2 -:1049A0003C1A8000000216023042000F104000073F -:1049B000AF82001C8CC34C1C3C02001F3442FC0024 -:1049C00000621824000319C2AF8300188F42000848 -:1049D000275B400034420001AF420008AF80002452 -:1049E0003C02601CAF400080AF4000848C45000852 -:1049F0008CC3080834028000034220212402FFF007 -:104A0000006218243C0200803C010800AC22042013 -:104A10003C025709AF84003814620004AF850034AB -:104A2000240200010A000292AF820014AF80001439 -:104A30008F42000038420001304200011440FFFC68 -:104A40008F820014104000160000000097420104FD -:104A5000104000058F830000146000072462FFFFF0 -:104A60000A0002A72C62000A2C62001050400004C9 -:104A70008F83000024620001AF8200008F8300005A -:104A80002C62000A144000032C6200070A0002AEE8 -:104A9000AF80FFDC1040000224020001AF82FFDC87 -:104AA0008F4301088F44010030622000AF8300046F -:104AB00010400008AF8400103C0208008C42042C17 -:104AC000244200013C010800AC22042C0A00058AA3 -:104AD0003C0240003065020014A0000324020F00D5 -:104AE0001482026024020D0097420104104002C8A3 -:104AF0003C02400030624000144000AD8F8200381C -:104B00008C4400088F4201780440FFFE2402080014 -:104B1000AF42017824020008A7420140A7400142A9 -:104B2000974201048F8400043051FFFF308200015E -:104B300010400007022080212623FFFE24020002ED -:104B40003070FFFFA74201460A0002DBA74301487D -:104B5000A74001463C0208008C42043C1440000D72 -:104B60008F830010308200201440000224030009CB -:104B700024030001006020218F830010240209001B -:104B80005062000134840004A744014A0A0002F67E -:104B90000000000024020F00146200053082002093 -:104BA000144000062403000D0A0002F5240300054A -:104BB000144000022403000924030001A743014A12 -:104BC0003C0208008C4204203C0400480E00020C09 -:104BD000004420250E000235000000008F82000CEA -:104BE0001040003E000000008F4210003C030020F7 -:104BF00000431024104000398F820004304200022C -:104C0000104000360000000097421014144000339A -:104C100000000000974210088F8800383042FFFFE4 -:104C200024420006000218820003388000E8302188 -:104C3000304300018CC400001060000430420003C7 -:104C40000000000D0A00033700E810215440001056 -:104C50003084FFFF3C05FFFF0085202400851826D7 -:104C60000003182B0004102B0043102410400005F3 -:104C700000000000000000000000000D0000000027 -:104C8000240002228CC200000A00033600452025C1 -:104C90003883FFFF0003182B0004102B004310245F -:104CA0001040000500000000000000000000000DA2 -:104CB000000000002400022B8CC200003444FFFFDF -:104CC00000E81021AC4400003C0208008C42043093 -:104CD000244200013C010800AC2204308F62000035 -:104CE0008F840038AF8200088C8300003402FFFFFD -:104CF0001462000F000010213C0508008CA504542C -:104D00003C0408008C84045000B0282100B0302BF3 -:104D100000822021008620213C010800AC2504549B -:104D20003C010800AC2404500A000580240400085B -:104D30008C820000304201001040000F0000102162 -:104D40003C0508008CA5044C3C0408008C840448F5 -:104D500000B0282100B0302B0082202100862021C5 -:104D60003C010800AC25044C3C010800AC2404487C -:104D70000A000580240400083C0508008CA50444B2 -:104D80003C0408008C84044000B0282100B0302B83 -:104D900000822021008620213C010800AC2504442B -:104DA0003C010800AC2404400A00058024040008EB -:104DB0008F6200088F62000000021602304300F08C -:104DC000240200301062000524020040106200E05E -:104DD0008F8200200A0005882442000114A00005EB -:104DE00000000000000000000000000D00000000B6 -:104DF000240002568F4201780440FFFE00000000AC -:104E00000E00023D27A40010144000050040802140 -:104E1000000000000000000D000000002400025D02 -:104E20008E0200001040000500000000000000009D -:104E30000000000D00000000240002608F62000CE2 -:104E400004430003240200010A00042EAE00000007 -:104E5000AE0200008F8200388C480008A2000007D4 -:104E60008F65000C8F64000430A3FFFF0004240250 -:104E700000852023308200FF0043102124420005DA -:104E8000000230832CC20081A605000A14400005F0 -:104E9000A2040004000000000000000D000000005B -:104EA000240002788F8500380E0005AB260400141C -:104EB0008F6200048F430108A60200083C02100024 -:104EC00000621824106000080000000097420104EE -:104ED000920300072442FFEC346300023045FFFFD9 -:104EE0000A0003C3A2030007974201042442FFF013 -:104EF0003045FFFF960600082CC200135440000501 -:104F0000920300079202000734420001A202000748 -:104F1000920300072402000110620005240200032E -:104F20001062000B8F8200380A0003E030C6FFFFDA -:104F30008F8200383C04FFFF8C43000C006418246F -:104F400000651825AC43000C0A0003E030C6FFFFE3 -:104F50003C04FFFF8C4300100064182400651825F2 -:104F6000AC43001030C6FFFF24C2000200021083D1 -:104F7000A20200058F830038304200FF000210803B -:104F8000004328218CA800008CA200002403000408 -:104F900000021702144300120000000097420104AF -:104FA0003C03FFFF010318243042FFFF004610239B -:104FB0002442FFFE00624025ACA8000092030005D9 -:104FC000306200FF00021080005010219042001457 -:104FD0003042000F004310210A000415A20200060F -:104FE0008CA40004974201049603000A3088FFFF56 -:104FF0003042FFFF004610232442FFD60002140077 -:1050000001024025ACA800049202000792040005AA -:10501000246300280003188300641821344200042C -:10502000A2030006A20200078F8200042403FFFBF4 -:105030003442000200431024AF82000492030006B1 -:105040008F87003800031880007010218C440020E6 -:105050003C02FFF63442FFFF008240240067182123 -:10506000AE04000CAC68000C920500063C03FF7F08 -:105070008E02000C0005288000B020213463FFFF61 -:10508000010330249488002600A72821004310241F -:10509000AE02000CAC860020AC880024ACA8001046 -:1050A00024020010A742014024020002A74001424E -:1050B000A7400144A7420146974201043C0400086E -:1050C0002442FFFEA7420148240200010E00020C08 -:1050D000A742014A9603000A9202000400431021ED -:1050E0002442000230420007000210233042000731 -:1050F0000E000235AE0200108F6200003C03080073 -:105100008C63044424040010AF8200089742010419 -:105110003042FFFF2442FFFE00403821000237C327 -:105120003C0208008C420440006718210067282BCD -:1051300000461021004510213C010800AC23044426 -:105140003C010800AC2204400A00051500000000E4 -:1051500014A0000500000000000000000000000D89 -:10516000000000002400030A8F4201780440FFFE83 -:10517000000000000E00023D27A4001414400005AA -:1051800000408021000000000000000D0000000031 -:10519000240003118E020000544000069202000712 -:1051A000000000000000000D000000002400031CAF -:1051B0009202000730420004104000058F82000474 -:1051C0002403FFFB3442000200431024AF8200049A -:1051D0008F62000404430008920200079202000656 -:1051E0008E03000CAE000000000210800050102161 -:1051F000AC430020920200073042000454400009F2 -:105200009602000A920200053C0300010002108091 -:10521000005010218C46001800C33021AC46001805 -:105220009602000A9206000427710008022020213D -:1052300000C2302124C60005260500140E0005AB6F -:1052400000063082920400068F6500043C027FFF56 -:1052500000042080009120218C8300043442FFFF51 -:1052600000A2282400651821AC83000492020007E4 -:105270009204000592030004304200041040001420 -:1052800096070008308400FF000420800091202150 -:105290008C860004974201049605000A306300FFE3 -:1052A0003042FFFF004310210045102130E3FFFF93 -:1052B000004310232442FFD830C6FFFF0002140031 -:1052C00000C23025AC8600040A0004C9920300071E -:1052D000308500FF0005288000B128218CA4000043 -:1052E00097420104306300FF3042FFFF004310216A -:1052F000004710233C03FFFF008320243042FFFFC0 -:1053000000822025ACA400009203000724020001C3 -:105310001062000600000000240200031062001169 -:10532000000000000A0004EC8E0300109742010404 -:10533000920300049605000A8E24000C00431021FD -:10534000004510212442FFF23C03FFFF008320248C -:105350003042FFFF00822025AE24000C0A0004EC3E -:105360008E03001097420104920300049605000A80 -:105370008E24001000431021004510212442FFEE2E -:105380003C03FFFF008320243042FFFF00822025E2 -:10539000AE2400108E0300102402000AA742014030 -:1053A000A74301429603000A920200043C04004015 -:1053B00000431021A7420144A7400146974201043F -:1053C000A7420148240200010E00020CA742014A34 -:1053D0000E000235000000008F62000092030004FE -:1053E00000002021AF820008974201049606000ABF -:1053F0003042FFFF00621821006028213C030800B2 -:105400008C6304443C0208008C420440006518216F -:10541000004410210065382B004710213C01080092 -:10542000AC2304443C010800AC2204409204000474 -:10543000008620212484000A3084FFFF0E0001E949 -:1054400000000000974401043084FFFF0E0001F7C4 -:10545000000000003C021000AF4201780A000587FE -:105460008F820020148200273062000697420104D8 -:10547000104000673C0240003062400010400005D0 -:1054800000000000000000000000000D000000000F -:10549000240004208F4201780440FFFE240208000B -:1054A000AF42017824020008A7420140A740014210 -:1054B0008F8200049743010430420001104000072E -:1054C0003070FFFF2603FFFE24020002A7420146C0 -:1054D000A74301480A00053F2402000DA7400146EA -:1054E0002402000DA742014A8F6200002404000834 -:1054F000AF8200080E0001E9000000000A00051953 -:1055000002002021104000423C0240009362000053 -:10551000304300F0240200101062000524020070E5 -:10552000106200358F8200200A00058824420001A5 -:105530008F620000974301043050FFFF3071FFFF7E -:105540008F4201780440FFFE320200070002102360 -:10555000304200072403000A2604FFFEA74301404F -:10556000A7420142A7440144A7400146A751014870 -:105570008F42010830420020144000022403000939 -:1055800024030001A743014A0E00020C3C04004022 -:105590000E000235000000003C0708008CE70444C0 -:1055A000021110212442FFFE3C0608008CC6044074 -:1055B0000040182100E33821000010218F65000011 -:1055C00000E3402B00C230212604000800C830212F -:1055D0003084FFFFAF8500083C010800AC2704447D -:1055E0003C010800AC2604400E0001E90000000068 -:1055F0000A000519022020210E00013B00000000D6 -:105600008F82002024420001AF8200203C02400033 -:10561000AF4201380A000292000000003084FFFF10 -:1056200030C6FFFF00052C0000A628253882FFFFAA -:10563000004510210045282B0045102100021C02C6 -:105640003042FFFF0043102100021C023042FFFFE6 -:10565000004310213842FFFF03E000083042FFFF03 -:105660003084FFFF30A5FFFF0000182110800007E5 -:1056700000000000308200011040000200042042BF -:10568000006518210A0005A10005284003E0000874 -:105690000060102110C0000624C6FFFF8CA200008D -:1056A00024A50004AC8200000A0005AB2484000499 -:1056B00003E000080000000010A0000824A3FFFF82 -:1056C000AC86000000000000000000002402FFFF84 -:1056D0002463FFFF1462FFFA2484000403E000083F -:0456E00000000000C6 -:0456E40000000001C1 -:0856E8000A00002A0000000086 -:1056F000000000000000000D747870362E302E314E -:105700003700000006001100000000000000013614 -:105710000000EA600000000000000000000000003F -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000160000000043 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000138800000000000005DC000000009D -:105790000000000010000003000000000000000DE9 -:1057A0000000000D3C02080024423D883C03080034 -:1057B0002463403CAC4000000043202B1480FFFDDC -:1057C000244200043C1D080037BD7FFC03A0F021EB -:1057D0003C100800261000A83C1C0800279C3D88AF -:1057E0000E00044E000000000000000D27BDFFB4B5 -:1057F000AFA10000AFA20004AFA30008AFA4000C4B -:10580000AFA50010AFA60014AFA70018AFA8001CEA -:10581000AFA90020AFAA0024AFAB0028AFAC002C8A -:10582000AFAD0030AFAE0034AFAF0038AFB8003C22 -:10583000AFB90040AFBC0044AFBF00480E000591B7 -:10584000000000008FBF00488FBC00448FB90040AB -:105850008FB8003C8FAF00388FAE00348FAD003072 -:105860008FAC002C8FAB00288FAA00248FA90020BA -:105870008FA8001C8FA700188FA600148FA50010FA -:105880008FA4000C8FA300088FA200048FA100003A -:1058900027BD004C3C1B60048F7A5030377B50286A -:1058A00003400008AF7A00008F86003C3C03900064 -:1058B0003C0280000086282500A32025AC4400205F -:1058C0003C0380008C67002004E0FFFE0000000025 -:1058D00003E00008000000000A000070240400013A -:1058E0008F85003C3C0480003483000100A3102518 -:1058F00003E00008AC82002003E000080000102153 -:105900003084FFFF30A5FFFF108000070000182142 -:10591000308200011040000200042042006518217E -:105920001480FFFB0005284003E000080060102100 -:1059300010C00007000000008CA2000024C6FFFF7A -:1059400024A50004AC82000014C0FFFB24840004E2 -:1059500003E000080000000010A0000824A3FFFFDF -:10596000AC86000000000000000000002402FFFFE1 -:105970002463FFFF1462FFFA2484000403E000089C -:105980000000000090AA00318FAB00108CAC0040EA -:105990003C0300FF8D680004AD6C00208CAD00441A -:1059A00000E060213462FFFFAD6D00248CA7004849 -:1059B0003C09FF000109C024AD6700288CAE004CF3 -:1059C0000182C82403197825AD6F0004AD6E002C48 -:1059D0008CAD0038314A00FFAD6D001C94A9003237 -:1059E0003128FFFFAD68001090A70030A5600002CD -:1059F000A1600004A167000090A30032306200FFA4 -:105A00000002198210600005240500011065000ED7 -:105A10000000000003E00008A16A00018CD8002803 -:105A2000354A0080AD7800188CCF0014AD6F00149B -:105A30008CCE0030AD6E00088CC4002CA16A000131 -:105A400003E00008AD64000C8CCD001CAD6D0018A7 -:105A50008CC90014AD6900148CC80024AD6800081E -:105A60008CC70020AD67000C8CC200148C830070C2 -:105A70000043C82B13200007000000008CC2001454 -:105A8000144CFFE400000000354A008003E00008E9 -:105A9000A16A00018C8200700A0000E6000000008C -:105AA0009089003027BDFFF88FA8001CA3A9000033 -:105AB0008FA300003C0DFF8035A2FFFF8CAC002CB3 -:105AC00000625824AFAB0000A100000400C05821C0 -:105AD000A7A000028D06000400A048210167C8218C -:105AE0008FA50000008050213C18FF7F032C20264A -:105AF0003C0E00FF2C8C0001370FFFFF35CDFFFF60 -:105B00003C02FF0000AFC82400EDC02400C278248E -:105B1000000C1DC00323682501F87025AD0D0000A1 -:105B2000AD0E00048D240024AFAD0000AD040008CC -:105B30008D2C00202404FFFFAD0C000C9547003293 -:105B400030E6FFFFAD0600109145004830A200FF8F -:105B5000000219C2506000018D240034AD0400140D -:105B60008D4700388FAA001827BD0008AD0B00280C -:105B7000AD0A0024AD07001CAD00002CAD000018DC -:105B800003E00008AD00002027BDFFE0AFB2001821 -:105B9000AFB10014AFB00010AFBF001C9098003040 -:105BA00000C088213C0D00FF330F007FA0CF000014 -:105BB000908E003135ACFFFF3C0AFF00A0CE000103 -:105BC00094A6001EA22000048CAB00148E290004B1 -:105BD00000A08021016C2824012A4024008090210B -:105BE00001052025A6260002AE240004260500207B -:105BF000262400080E00009224060002924700307E -:105C0000260500282624001400071E0000031603A2 -:105C100024060004044000032403FFFF96590032C9 -:105C20003323FFFF0E000092AE2300102624002431 -:105C30008FBF001C8FB200188FB100148FB00010FE -:105C400024050003000030210A00009C27BD00202D -:105C500027BDFFD8AFB1001CAFB00018AFBF002008 -:105C600090A900302402000100E050213123003FC0 -:105C700000A040218FB000400080882100C0482152 -:105C8000106200148FA70038240B000500A020210B -:105C900000C02821106B0013020030210E000128E3 -:105CA000000000009225007C30A400021080000358 -:105CB00026030030AE000030260300348FBF0020E2 -:105CC0008FB1001C8FB000180060102103E00008A5 -:105CD00027BD00280E0000A7AFB000100A00016F1A -:105CE000000000008FA3003C01002021012028219A -:105CF00001403021AFA300100E0000EEAFB0001441 -:105D00000A00016F000000003C06800034C20E0053 -:105D10008C4400108F850044ACA400208C430018F4 -:105D200003E00008ACA300243C06800034C20E004F -:105D30008C4400148F850044ACA400208C43001CCC -:105D400003E00008ACA300249382000C1040001B69 -:105D50002483000F2404FFF00064382410E00019AD -:105D6000978B00109784000E9389000D3C0A601CED -:105D70000A0001AC01644023010370210064282360 -:105D80001126000231C2FFFF30A2FFFF0047302B77 -:105D900050C0000E00E448218D4D000C31A3FFFFE0 -:105DA00000036400000C2C0304A1FFF30000302169 -:105DB00030637FFF0A0001A42406000103E000080D -:105DC000000000009784000E00E448213123FFFF0B -:105DD0003168FFFF0068382B54E0FFF8A783000EFE -:105DE000938A000D11400005240F0001006BC023B1 -:105DF000A380000D03E00008A798000E006BC023ED -:105E0000A38F000D03E00008A798000E03E0000830 -:105E10000000000027BDFFE8AFB000103C1080007C -:105E200036030140308BFFFF93AA002BAFBF001455 -:105E3000A46B000436040E009488001630C600FFE0 -:105E40008FA90030A4680006AC650008A0660012A7 -:105E5000A46A001AAC6700208FA5002CA469001862 -:105E6000012020210E000198AC6500143C021000B6 -:105E7000AE0201788FBF00148FB0001003E000085D -:105E800027BD00188F8500002484000727BDFFF878 -:105E90003084FFF83C06800094CB008A316AFFFF13 -:105EA000AFAA00008FA90000012540232507FFFFAE -:105EB00030E31FFF0064102B1440FFF700056882D9 -:105EC000000D288034CC400000AC102103E0000815 -:105ED00027BD00088F8200002486000730C5FFF828 -:105EE00000A2182130641FFF03E00008AF84000007 -:105EF0008F87003C8F84004427BDFFB0AFB70044BC -:105F0000AFB40038AFB1002CAFBF0048AFB600400F -:105F1000AFB5003CAFB30034AFB20030AFB0002833 -:105F20003C0B80008C860024AD6700808C8A0020AA -:105F300035670E0035690100ACEA00108C8800243A -:105F40008D2500040000B821ACE800188CE3001097 -:105F500000A688230000A021ACE300148CE2001806 -:105F6000ACE2001C122000FE00E0B021936C00089F -:105F7000118000F400000000976F001031EEFFFF69 -:105F8000022E682B15A000EF000000009772001091 -:105F90003250FFFFAED000003C0380008C74000044 -:105FA000329300081260FFFD0000000096D8000840 -:105FB0008EC700043305FFFF30B5000112A000E4D6 -:105FC000000000000000000D30BFA0402419004078 -:105FD00013F9011B30B4A000128000DF00000000A4 -:105FE000937300081260000800000000976D001015 -:105FF00031ACFFFF00EC202B1080000330AE0040DE -:1060000011C000D500000000A7850040AF87003810 -:106010009363000802202821AFB10020146000F52E -:1060200027B40020AF60000C978F004031F1400092 -:1060300016200002240300162403000E2405400746 -:10604000A363000AAF650014938A00428F700014A6 -:10605000315500010015124002024825AF690014B5 -:10606000979F00408F78001433F9001003194025E2 -:10607000AF680014979200403247000810E0016EAC -:10608000000000008F6700143C1210003C118000DB -:1060900000F27825AF6F001436230E00946E000ACC -:1060A0003C0D81002406000E31CCFFFF018D202520 -:1060B000AF640004A36600029373000A3406FFFC79 -:1060C000266B0004A36B000A979800403308200059 -:1060D0001100015F000000003C05800034A90E00A3 -:1060E000979900409538000C97870040001940426E -:1060F0003312C0003103000300127B0330F11000A3 -:10610000006F68250011720301AE6025000C20C0ED -:10611000A764001297930040936A000A0013598203 -:106120003175003C02AA10212450003CA3700009E4 -:10613000953F000C33F93FFFA779001097700012CC -:10614000936900090130F82127E5000230B9000702 -:106150000019C02333080007A368000B93710009DE -:1061600097720012976F0010322700FF8F9100384E -:10617000978D004000F21821006F702101C6602148 -:1061800031A6004010C000053185FFFF00B1102B83 -:106190003C12800010400017000098210225A82B17 -:1061A00056A0013E8FA500203C048000348A0E00DA -:1061B0008D5300143C068000AD5300108D4B001C25 -:1061C000AD4B0018AD4500008CCD000031AC00088F -:1061D0001180FFFD34CE0E0095C3000800A0882179 -:1061E00000009021A78300408DC600042413000105 -:1061F000AF860038976F001031F5FFFF8E9F0000CB -:1062000003F1282310A0011FAE850000936200084F -:10621000144000DD000000000E0001E7240400101F -:106220008F900048004028213C023200320600FFD7 -:10623000000654000142F82526090001AF890048F4 -:10624000ACBF00009379000997780012936F000AA1 -:10625000332800FF3303FFFF0103382100076C00E0 -:1062600031EE00FF01AE6025ACAC00048F84004825 -:10627000978B0040316A20001140010AACA400084D -:1062800097640012308BFFFF06400108ACAB000C96 -:10629000978E004031C5000814A000022628000691 -:1062A000262800023C1F800037E70E0094F90014F6 -:1062B0008CE5001C8F670004937800023324FFFFF5 -:1062C000330300FFAFA300108F6F0014AFA80018B6 -:1062D0000E0001CBAFAF0014240400100E0001FB30 -:1062E000000000008E920000164000050000000033 -:1062F0008F7800142403FFBF0303A024AF7400149D -:106300008F67000C00F5C821AF79000C9375000869 -:1063100016A0000800000000126000060000000047 -:106320008F6800143C0AEFFF3549FFFE0109F8248D -:10633000AF7F0014A37300088FA500200A00034F4D -:1063400002202021AED100000A00022D3C03800073 -:1063500014E0FF1E30BFA0400E0001900000A021FD -:106360002E9100010237B02512C000188FBF0048DF -:106370008F87003C24170F0010F700D43C068000E4 -:106380008CD901780720FFFE241F0F0010FF00F6B4 -:1063900034CA0E008D56001434C701402408024050 -:1063A000ACF600048D49001C3C141000ACE9000858 -:1063B000A0E00012A4E0001AACE00020A4E0001865 -:1063C000ACE80014ACD401788FBF00488FB700440C -:1063D0008FB600408FB5003C8FB400388FB30034C7 -:1063E0008FB200308FB1002C8FB0002803E000087E -:1063F00027BD00508F910038978800403C128000E4 -:106400000220A8213107004014E0FF7C0000982101 -:10641000977900108F9200383338FFFF131200A8CD -:10642000000020210080A021108000F300A088211E -:106430001620FECE000000000A00031F2E9100016E -:106440003C0380008C6201780440FFFE24080800B1 -:106450008F860000AC6801783C038000946D008A50 -:1064600031ACFFFF01865823256AFFFF31441FFF2F -:106470002C8900081520FFF9000000008F8F0048CC -:10648000347040008F83003C00E0A021240E0F00F8 -:1064900025E70001AF87004800D03021023488236F -:1064A0003C08800031F500FF106E00052407000154 -:1064B00093980042331300010013924036470001C5 -:1064C000001524003C0A0100008A4825ACC90000E0 -:1064D0008F82004830BF003630B90008ACC20004DB -:1064E0001320009900FF982535120E009650000ADF -:1064F0008F8700003C0F81003203FFFF24ED00086E -:1065000035060140006F60253C0E100031AB1FFFC7 -:10651000269200062405000EACCC0020026E9825C1 -:10652000A4C5001AAF8B0000A4D2001816200008E2 -:106530003C1080008F89003C24020F005122000291 -:1065400024170001367300400E0001883C108000C3 -:1065500036060E008CCB0014360A01400240202182 -:10656000AD4B00048CC5001CAD450008A1550012C0 -:10657000AD5300140E0001983C151000AE150178C3 -:106580000A00035200000000936F0009976E00128A -:10659000936D000B31E500FF00AE202131AC00FF10 -:1065A000008C80212602000A3050FFFF0E0001E718 -:1065B000020020218F8600483C0341003C058000FA -:1065C00024CB0001AF8B0048936A00099769001241 -:1065D00030C600FF315F00FF3128FFFF03E838219C -:1065E00024F900020006C4000319782501E3702590 -:1065F000AC4E00008F6D000C34A40E00948B001480 -:1066000001B26025AC4C00048C85001C8F6700042F -:10661000936A00023164FFFF314900FFAFA9001007 -:106620008F680014AFB100180E0001CBAFA80014A2 -:106630000A0002FD02002021AF600004A3600002F6 -:1066400097980040330820001500FEA30000302179 -:10665000A760001297840040936B000A3C108000F2 -:1066600030931F0000135183014BA82126A200285C -:10667000A362000936090E00953F000C0A0002953E -:10668000A77F00108F700014360900400E000188AB -:10669000AF6900140A0002C9000000000A00034F9D -:1066A000000020210641FEFAACA0000C8CAC000CCE -:1066B0003C0D8000018D90250A0002EAACB2000C6E -:1066C000000090210A0002C5241300011280000777 -:1066D0003C028000344B0E009566000830D3004029 -:1066E00012600049000000003C0680008CD0017858 -:1066F0000600FFFE34C50E0094B500103C030500F3 -:1067000034CC014032B8FFFF03039025AD92000C5A -:106710008CAF0014240D20003C041000AD8F000449 -:106720008CAE001CAD8E0008A1800012A580001A5E -:10673000AD800020A5800018AD8D0014ACC4017898 -:106740000A0003263C0680008F9F00003518014098 -:106750002692000227F9000833281FFFA71200180D -:106760000A000391AF8800003C02800034450140DC -:10677000ACA0000C1280001B34530E0034510E00EC -:106780008E370010ACB700048E2400183C0B80003C -:10679000ACA400083570014024040040A20000129F -:1067A0008FBF0048A600001A8FB70044AE0000203B -:1067B0008FB60040A60000188FB5003CAE04001450 -:1067C0008FB400388FB300348FB200308FB1002CFB -:1067D0008FB000283C02100027BD005003E00008E5 -:1067E000AD6201788E660014ACA600048E64001CB5 -:1067F0000A00042A3C0B80000E0001902E9100013B -:106800000A0003200237B025000000000000000D40 -:1068100000000000240003690A0004013C06800017 -:1068200027BDFFD8AFBF00203C0980003C1F20FFE0 -:10683000AFB200183C07600035320E002402001091 -:1068400037F9FFFDACE23008AFB3001CAFB1001464 -:10685000AFB00010AE5900000000000000000000C2 -:106860000000000000000000000000003C1800FFD5 -:106870003713FFFDAE5300003C0B60048D705000D9 -:106880002411FF7F3C0E00020211782435EC380CF5 -:1068900035CD0109ACED4C18240A0009AD6C50004F -:1068A0008CE80438AD2A0008AD2000148CE54C1C9F -:1068B0003106FFFF38C42F7100051E023062000F41 -:1068C0002486C0B310400007AF8200088CE54C1C42 -:1068D0003C09001F3528FC0000A81824000321C231 -:1068E000AF8400048CF108083C0F57092412F00013 -:1068F0000232702435F0001001D0602601CF6826E6 -:106900002DAA00012D8B0001014B382550E0000914 -:10691000A380000C3C1F601C8FF8000824190001A4 -:10692000A399000C33137C00A7930010A780000EDE -:10693000A380000DAF80004814C00003AF800000AA -:106940003C066000ACC0442C0E0005B93C10800031 -:106950000E000F24361101003C12080026523DF0B3 -:106960003C13080026733E708E030000386400015B -:10697000308200011440FFFC3C0B800A8E26000090 -:106980002407FF8024C90240312A007F014B4021A7 -:1069900001272824AE060020AF880044AE0500245D -:1069A0003C048000AF86003C8C8C01780580FFFEA3 -:1069B00024180800922F0008AC980178A38F004299 -:1069C000938E004231CD000111A0000F24050D006F -:1069D00024DFF8002FF903011320001C000629C250 -:1069E00024A4FFF000041042000231400E00020215 -:1069F00000D2D8213C0240003C068000ACC20138E5 -:106A00000A0004A00000000010C50023240D0F00A0 -:106A100010CD00273C1F800837F900809338000014 -:106A2000240E0050330F00FF15EEFFF33C02400030 -:106A30000E000A40000000003C0240003C068000BE -:106A4000ACC201380A0004A0000000008F830004DB -:106A500000A3402B1500000B8F8B0008006B50210A -:106A60002547FFFF00E5482B1520000600A3602303 -:106A7000000C19400E0002020073D8210A0004C461 -:106A80003C0240000000000D0E0002020000000069 -:106A90000A0004C43C0240003C1B0800277B3F70F6 -:106AA0000E000202000000000A0004C43C02400084 -:106AB0003C1B0800277B3F900E00020200000000F4 -:106AC0000A0004C43C0240003C0660043C09080083 -:106AD00025290104ACC9502C8CC850003C0580000D -:106AE0003C02000235070080ACC750003C0408009F -:106AF000248415A43C0308002463155CACA500089D -:106B0000ACA2000C3C010800AC243D803C01080014 -:106B1000AC233D8403E000082402000100A03021E2 -:106B20003C1C0800279C3D883C0C04003C0B0002E8 -:106B3000008B3826008C40262CE200010007502BE9 -:106B40002D050001000A48803C03080024633D80B5 -:106B5000004520250123182110800003000010218A -:106B6000AC6600002402000103E000080000000001 -:106B70003C1C0800279C3D883C0B04003C0A00029A -:106B8000008A3026008B38262CC200010006482BD4 -:106B90002CE50001000940803C03080024633D808F -:106BA0000045202501031821108000050000102158 -:106BB0003C0C0800258C155CAC6C00002402000124 -:106BC00003E00008000000003C0900023C0804004B -:106BD00000883026008938262CC300010080282137 -:106BE0002CE40001008310251040000B0000302130 -:106BF0003C1C0800279C3D883C0A80008D4E000804 -:106C00002406000101CA6825AD4D00088D4C000C1A -:106C100001855825AD4B000C03E0000800C0102191 -:106C20003C1C0800279C3D883C0580008CA6000C7D -:106C3000000420272402000100C4182403E00008F7 -:106C4000ACA3000C3C0200021082000B3C0560006B -:106C50003C070400108700030000000003E0000868 -:106C6000000000008CA908D0240AFFFD012A40245E -:106C700003E00008ACA808D08CA408D02406FFFECE -:106C80000086182403E00008ACA308D03C05601A75 -:106C900034A600108CC3008027BDFFF88CC500848B -:106CA000AFA3000093A4000024020001108200039F -:106CB000AFA5000403E0000827BD000893A700016A -:106CC00014E0001497AC000297B800023C0F80005B -:106CD000330EFFFC01CF6821ADA50000A3A000008A -:106CE0003C0660008CC708D02408FFFE3C04601AF4 -:106CF00000E82824ACC508D08FA300048FA20000B0 -:106D00003499001027BD0008AF22008003E000087E -:106D1000AF2300843C0B8000318AFFFC014B4821EB -:106D20008D2800000A00057DAFA8000427BDFFE8FC -:106D3000AFBF00103C1C0800279C3D883C0580002C -:106D40008CA4000C8CA200043C0300020044282404 -:106D500010A0000A00A318243C0604003C04000212 -:106D60001460000900A610241440000F3C04040025 -:106D70000000000D3C1C0800279C3D888FBF0010C0 -:106D800003E0000827BD00183C0208008C423D804B -:106D90000040F809000000003C1C0800279C3D88CA -:106DA0000A0005A68FBF00103C0208008C423D84FB -:106DB0000040F809000000000A0005AC00000000D7 -:106DC000000411C003E00008244202403C04080013 -:106DD00024843FD42405001A0A00009C00003021BE -:106DE00027BDFFE0AFB000103C108000AFBF00181F -:106DF000AFB1001436110100922200090E0005B651 -:106E00003044007F8E3F00008F89003C3C0F0080A3 -:106E100003E26021258800400049F821240DFF800D -:106E2000310E00783198007835F9000135F1000213 -:106E30000319382501D14825010D302403ED5824CC -:106E4000018D2824240A004024040080240300C06B -:106E5000AE0B0024AE000810AE0A0814AE040818E9 -:106E6000AE03081CAE050804AE070820AE060808ED -:106E7000AE090824360909009539000C3605098049 -:106E800033ED007F3338FFFF001889C0AE110800D2 -:106E9000AE0F0828952C000C8FBF00188FB100147E -:106EA000318BFFFF000B51C0AE0A002C8CA40050A8 -:106EB0008FB000108CA3003C8D2700048CA8001C10 -:106EC0008CA600383C0E800A01AE102127BD0020A0 -:106ED000AF820044AF840050AF830054AF87004CB2 -:106EE000AF88005C03E00008AF8600603C09080042 -:106EF00091293FF924A800023C05110000093C003B -:106F000000E8302500C5182524820008AC83000065 -:106F100003E00008AC8000043C0980003523090030 -:106F20009128010B906A001124020028008048215A -:106F3000314700FF00A0702100C0682131080040E7 -:106F400010E20002340C86DD240C08003C0A8000AC -:106F500035420A9A94470000354B0A9C35460AA0F0 -:106F600030F9FFFFAD3900008D780000354B0A8005 -:106F700024040001AD3800048CCF0000AD2F0008C0 -:106F80009165001930A300031064009A2864000280 -:106F9000148000B924050002106500A8240F000326 -:106FA000106F00BE35450AA4240A0800118A004D5E -:106FB00000000000510000423C0B80003C048000B7 -:106FC000348309009067001230E200FF004D782101 -:106FD000000FC880272400013C0A8000354F0900BB -:106FE00091E50019354C09808D87002830A300FFFA -:106FF00000031500004758250004C4003C19600038 -:1070000001793025370806FFAD260000AD280004C1 -:107010008DEA002C25280028AD2A00088DEC0030D0 -:10702000AD2C000C8DE50034AD2500108DE400384A -:10703000AD2400148DE3001CAD2300188DE7002063 -:10704000AD27001C8DE20024AD2200208DF9002820 -:10705000AD3900243C0980003526093C8CCF000066 -:10706000352A0100AD0E0004AD0F00008D4E000C5E -:107070003523090035250980AD0E0008906C0012FB -:107080008D47000C8CB900343C18080093183FF869 -:10709000318200FF004D582103277823000B370071 -:1070A0000018240000C4702531E9FFFC01C96825DF -:1070B00025020014AD0D000C03E00008AD00001027 -:1070C00035780900930600123C05080094A53FE8B6 -:1070D00030C800FF010D5021000A60800A00063C04 -:1070E0000185202115000060000000003C08080018 -:1070F00095083FEE3C06080094C63FE801061021C3 -:107100003C0B80003579090093380011932A00194F -:1071100035660A80330800FF94CF002A0008608299 -:10712000314500FF978A0058000C1E00000524001E -:107130003047FFFF006410250047C02501EA3021D9 -:107140003C0B4000030B402500066400AD28000006 -:10715000AD2C0004932500183C03000625280014DC -:1071600000053E0000E31025AD2200088F24002C0E -:10717000254F000131EB7FFFAD24000C8F38001C40 -:10718000A78B0058AD3800103C0980003526093C1B -:107190008CCF0000352A0100AD0E0004AD0F0000B9 -:1071A0008D4E000C3523090035250980AD0E0008F1 -:1071B000906C00128D47000C8CB900343C1808000C -:1071C00093183FF8318200FF004D582103277823A0 -:1071D000000B37000018240000C4702531E9FFFCC3 -:1071E00001C9682525020014AD0D000C03E000085C -:1071F000AD0000103C02080094423FF23C0508003C -:1072000094A53FE835440AA43C07080094E73FE40E -:10721000948B00000045C8210327C023000B1C00ED -:107220002706FFF200665025AD2A000CAD200010A5 -:10723000AD2C00140A00063025290018354F0AA489 -:1072400095E50000956400280005140000043C004A -:107250003459810000EC5825AD39000CAD2B0010DD -:107260000A000630252900143C0C0800958C3FEEDE -:107270000A000686258200015460FF4C240A08009B -:1072800035580AA49706000000061C00006C502523 -:10729000AD2A000C0A000630252900103C03080026 -:1072A00094633FF23C07080094E73FE83C0F080076 -:1072B00095EF3FE494A40000957900280067102121 -:1072C000004F582300041C00001934002578FFEEFD -:1072D00000D87825346A8100AD2A000CAD2F00104B -:1072E000AD200014AD2C00180A0006302529001C22 -:1072F00003E00008240207D027BDFFE0AFB200186A -:10730000AFB10014AFB00010AFBF001C0E00007C86 -:10731000008088218F8800548F87004C3C058008AE -:1073200034B20080011128213C108000240200802A -:10733000240300C000A72023AE0208183C068008E2 -:10734000AE03081C18800004AF850054ACC50004CF -:107350008CC90004AF89004C122000093604098052 -:107360000E00070200000000924C00278E0B0074F4 -:1073700001825004014B3021AE46000C36040980D6 -:107380008C8E001C8F8F005C01CF682319A0000435 -:107390008FBF001C8C90001CAF90005C8FBF001C46 -:1073A0008FB200188FB100148FB000100A00007E59 -:1073B00027BD00208F8600508F8300548F82004CA1 -:1073C0003C05800834A40080AC860050AC83003CAF -:1073D00003E00008ACA200043C0308008C630054E6 -:1073E00027BDFFF8308400FF2462000130A500FFB4 -:1073F0003C010800AC22005430C600FF3C0780006E -:107400008CE801780500FFFE3C0C7FFFA3A400037D -:107410008FAA0000358BFFFF014B4824000627C0D0 -:1074200001244025AFA8000034E201009043000A87 -:10743000A3A000023C1980FFA3A300018FAF0000AE -:1074400030AE007F3738FFFF01F86024000E6E0079 -:107450003C0A002034E50140018D582535492000C3 -:107460002406FF803C04100027BD0008ACAB000CD4 -:10747000ACA90014A4A00018A0A6001203E0000804 -:10748000ACE40178308800FF30A700FF3C038000A7 -:107490008C6201780440FFFE3C0C8000358A0A00B3 -:1074A0008D4B00203584014035850980AC8B00046C -:1074B0008D4900240007302B00061540AC890008D8 -:1074C000A088001090A3004CA083002D03E00008CA -:1074D000A480001827BDFFE8308400FFAFBF001074 -:1074E0000E00076730A500FF8F8300548FBF001088 -:1074F0003C06800034C50140344700402404FF901E -:107500003C02100027BD0018ACA3000CA0A4001280 -:10751000ACA7001403E00008ACC2017827BDFFE06F -:107520003C088008AFBF001CAFB20018AFB1001418 -:10753000AFB00010351000808E0600183C078000A8 -:10754000309200FF00C72025AE0400180E00007C1A -:1075500030B100FF92030005346200080E00007E87 -:10756000A2020005024020210E00077B02202821F4 -:10757000024020218FBF001C8FB200188FB1001471 -:107580008FB0001024050005240600010A00073C06 -:1075900027BD00203C05800034A3098090660008C8 -:1075A00030C200081040000F3C0A01013549080AAA -:1075B000AC8900008CA80074AC8800043C0708006B -:1075C00090E73FF830E5001050A00008AC800008BC -:1075D0003C0D800835AC00808D8B0058AC8B0008CA -:1075E0002484000C03E00008008010210A0007BF7B -:1075F0002484000C27BDFFE83C098000AFB00010D8 -:10760000AFBF00143526098090C800092402000687 -:1076100000A05821310300FF352709000080802198 -:10762000240500041062007B2408000294CF005C53 -:107630003C0E020431EDFFFF01AE6025AE0C0000F0 -:1076400090CA0008314400201080000800000000AB -:1076500090C2004E3C1F010337F90300305800FF71 -:107660000319302524050008AE06000490F9001126 -:1076700090E6001290E40011333800FF0018708289 -:1076800030CF00FF01CF5021014B6821308900FF2E -:1076900031AAFFFF39230028000A60801460002C03 -:1076A000020C482390E400123C198000372F01009F -:1076B000308C00FF018B1821000310800045F82159 -:1076C000001F8400360706FFAD270004373F09007E -:1076D00093EC001193EE0012372609800005C0825A -:1076E0008DE4000C8CC5003431CD00FF01AB1021BE -:1076F0000058182100A4F8230008840000033F006C -:1077000000F0302533F9FFFF318F00FC00D97025E0 -:107710000158202101E9682100045080ADAE000C21 -:107720000E00007C012A80213C088008240B000404 -:10773000350500800E00007EA0AB0009020010217C -:107740008FBF00148FB0001003E0000827BD0018A1 -:1077500090EC001190E300193C18080097183FEED8 -:10776000318200FF0002F882307000FF001FCE005F -:1077700000103C000327302500D870253C0F400046 -:1077800001CF68253C198000AD2D0000373F09006E -:1077900093EC001193EE0012372F01003726098079 -:1077A0000005C0828DE4000C8CC5003431CD00FF93 -:1077B00001AB10210058182100A4F8230008840010 -:1077C00000033F0000F0302533F9FFFF318F00FC4C -:1077D00000D970250158202101E96821000450805A -:1077E000ADAE000C0E00007C012A80213C08800810 -:1077F000240B0004350500800E00007EA0AB0009BC -:10780000020010218FBF00148FB0001003E00008A9 -:1078100027BD00180A0007D12408001227BDFFD099 -:107820003C038000AFB60028AFB50024AFB4002001 -:10783000AFB10014AFBF002CAFB3001CAFB2001843 -:10784000AFB000103467010090E6000B309400FFE9 -:1078500030B500FF30C200300000B0211040009968 -:1078600000008821346409809088000800082E00F8 -:1078700000051E03046000C0240400048F86005429 -:107880003C010800A0243FF83C0C8000AD8000487B -:107890003C048000348E010091CD000B31A5002006 -:1078A00010A000073C078000349309809272000802 -:1078B0000012860000107E0305E000C43C1F800813 -:1078C00034EC0100918A000B34EB098091690008C7 -:1078D000314400400004402B3123000800C89823A5 -:1078E0001460000224120003000090213C1080006C -:1078F00036180A8036040900970E002C9083001178 -:107900009089001293050018307F00FF312800FF96 -:10791000024810210002C880930D0018033F78210F -:1079200001F1302130B100FF00D11821A78E00589D -:107930003C010800A4263FEE3C010800A4233FF0D0 -:1079400015A00002000000000000000D920B010BCA -:107950003065FFFF3C010800A4233FF2316A00407C -:107960003C010800A4203FE83C010800A4203FE4BB -:107970001140000224A4000A24A4000B3091FFFF50 -:107980000E0001E7022020219206010B3C0C0800AA -:10799000958C3FF2004020210006698231A700014A -:1079A0000E000601018728210040202102602821C5 -:1079B0000E00060C024030210E0007AB00402021D3 -:1079C00016C00069004020219212010B325600407F -:1079D00012C000053C0500FF8C93000034AEFFFF91 -:1079E000026E8024AC9000000E0001FB02202021DA -:1079F0003C0F080091EF3FF831F100031220001610 -:107A00003C1380088F8200543C0980083528008090 -:107A1000245F0001AD1F003C3C0580088CB90004C8 -:107A200003E02021033FC0231B000002AF9F00544E -:107A30008CA400040E000702ACA400043C078000E4 -:107A40008CEB00743C04800834830080004B502190 -:107A5000AC6A000C3C138008367000800280202144 -:107A600002A02821A200006B0E0007673C148000D2 -:107A70008F920054368C0140AD92000C8F860048E6 -:107A80003C151000344D000624D60001AF96004886 -:107A90008FBF002CA18600128FB60028AD8D001478 -:107AA0008FB3001CAE9501788FB200188FB50024FB -:107AB0008FB400208FB100148FB0001003E00008D5 -:107AC00027BD003034640980908F0008000F7600D5 -:107AD000000E6E0305A00033347F090093F8001BED -:107AE000241900103C010800A0393FF833130002AC -:107AF0001260FF678F8600548F8200601446FF6516 -:107B00003C0480000E00007C000000003C04800863 -:107B10003485008090A8000924060016310300FF78 -:107B20001066000D0000000090AB00093C07080043 -:107B300090E73FF824090008316400FF34EA0001AF -:107B40003C010800A02A3FF81089002F240C000AED -:107B5000108C00282402000C0E00007E00000000A3 -:107B60000A00086A8F8600540E0007C302402821CD -:107B70000A0008B8004020213C0B8008356A0080CC -:107B80008D4600548CE9000C1120FF3DAF86005457 -:107B9000240700143C010800A0273FF80A000869E8 -:107BA0003C0C800090910008241200023C01080067 -:107BB000A0323FF8323000201200000B24160001E2 -:107BC0008F8600540A00086A2411000837F80080E4 -:107BD0008F020038AFE200048FF90004AF19003CB7 -:107BE0000A0008763C0780008F8600540A00086A65 -:107BF00024110004A0A200090E00007E0000000075 -:107C00000A00086A8F860054240200140A000944FE -:107C1000A0A2000927BDFFE8AFB000103C10800013 -:107C2000AFBF001436020100904400090E00076740 -:107C3000240500013C0480089099000E34830080E4 -:107C4000909F000F906F00269089000A33F800FF84 -:107C500000196E000018740031EC00FF01AE5025D1 -:107C6000000C5A00014B3825312800FF3603014033 -:107C70003445600000E830252402FF813C041000F8 -:107C8000AC66000C8FBF0014AC650014A06200123B -:107C9000AE0401788FB0001003E0000827BD001883 -:107CA00027BDFFE8308400FFAFBF00100E0007675C -:107CB00030A500FF3C05800034A40140344700405B -:107CC0002406FF92AC870014A08600128F83005414 -:107CD0008FBF00103C02100027BD0018AC83000CC1 -:107CE00003E00008ACA2017827BDFFD8AFB00010B8 -:107CF000308400FF30B000FF3C058000AFB10014BD -:107D0000AFBF0020AFB3001CAFB20018000410C218 -:107D100034A6010032030002305100011460000754 -:107D200090D200093C098008353300809268000534 -:107D30003107000810E0000C308A001002402021BA -:107D40000E00078D02202821240200018FBF002091 -:107D50008FB3001C8FB200188FB100148FB00010C9 -:107D600003E0000827BD00281540003434A50A00B0 -:107D70008CB800248CAF0008130F004B0000382192 -:107D80003C0D800835B30080926C00682406000228 -:107D9000318B00FF116600843C06800034C2010074 -:107DA0009263004C90590009307F00FF53F90004A2 -:107DB0003213007C10E00069000000003213007CE8 -:107DC0005660005C0240202116200009320D00019F -:107DD0003C0C800035840100358B0A008D65002441 -:107DE0008C86000414A6FFD900001021320D00017A -:107DF00011A0000E024020213C1880003710010025 -:107E00008E0F000C8F8E005011EE00080000000055 -:107E10000E00084D022028218E19000C3C1F8008FE -:107E200037F00080AE190050024020210E00077B81 -:107E3000022028210A000999240200013C050800BB -:107E40008CA5006424A400013C010800AC2400645B -:107E50001600000D00000000022028210E00077B04 -:107E600002402021926E0068240C000231CD00FFF8 -:107E700011AC0022024020210E00094B000000003E -:107E80000A000999240200010E0000702404000178 -:107E9000926B0025020B30250E00007EA2660025A5 -:107EA0000A0009DD022028218E6200188CDF000400 -:107EB0008CB9002400021E0217F9FFB13065007F63 -:107EC0009268004C264400013093007F1265004008 -:107ED000310300FF1464FFAB3C0D8008264700010E -:107EE00030F1007F30E200FF1225000B2407000173 -:107EF000004090210A0009A6241100012405000475 -:107F00000E00073C240600010E00094B0000000093 -:107F10000A000999240200012405FF80024520245B -:107F200000859026324200FF004090210A0009A6F9 -:107F3000241100010E00084D0220282132070030D4 -:107F400010E0FFA132100082024020210E00078DB8 -:107F5000022028210A000999240200018E690018D4 -:107F60000240202102202821012640250E00096E12 -:107F7000AE6800189264004C24050003240600013A -:107F80000E00073C308400FF0E0000702404000146 -:107F900092710025021150250E00007EA26A002574 -:107FA0000A000999240200018E6F00183C18800015 -:107FB0000240202101F87025022028210E00077BB5 -:107FC000AE6E00189264004C0A000A2524050004D5 -:107FD000324A0080394900801469FF6A3C0D8008EC -:107FE0000A0009FE2647000127BDFFC0AFB00018F8 -:107FF0003C108000AFBF0038AFB70034AFB60030E0 -:10800000AFB5002CAFB40028AFB30024AFB200204E -:108010000E0005BEAFB1001C360201009045000BFA -:108020000E00098090440008144000E78FBF00381C -:108030003C08800835070080A0E0006B3606098008 -:1080400090C50000240300503C17080026F73FB0FD -:1080500030A400FF3C13080026733FC010830003C8 -:108060003C1080000000B82100009821241F00105F -:108070003611010036120A00361509808E58002488 -:108080008E3400048EAF00208F8C00543C01080019 -:10809000A03F3FF836190A80972B002C8EF600007F -:1080A000932A00180298702301EC68233C01080011 -:1080B000AC2E3FD43C010800AC2D3FD83C01080059 -:1080C000AC2C3FFCA78B005802C0F809315400FFCC -:1080D00030490002152000E930420001504000C440 -:1080E0009227000992A90008312800081500000213 -:1080F000241500030000A8213C0A80003543090034 -:1081000035440A008C8D002490720011907000128A -:10811000907F0011325900FF321100FF02B110218F -:108120000002C08033EF00FF0319B021028F7021DD -:1081300002D4602125CB00103C010800A4363FEE9C -:108140003C010800AC2D40003C010800A42C3FF08D -:108150003C010800A42B3FEC355601003554098042 -:1081600035510E008F8700548F89005C8E8500206A -:1081700024080006012730233C010800AC283FF406 -:1081800000A7282304C000B50000902104A000B37C -:1081900000C5502B114000B5000000003C01080054 -:1081A000AC263FD88E6200000040F80900000000B5 -:1081B0003046000214C0007400408021304B0001A2 -:1081C000556000118E6200043C0D08008DAD3FDC4F -:1081D0003C0EC0003C04800001AE6025AE2C0000C7 -:1081E0008C980000330F000811E0FFFD0000000034 -:1081F000963F000824120001A79F00408E3900041A -:10820000AF9900388E6200040040F80900000000B9 -:108210000202802532030002146000B30000000057 -:108220003C09080095293FE43C06080094C63FF04D -:108230003C0A0800954A3FE63C0708008CE73FDC13 -:10824000012670213C0308008C6340003C080800B4 -:1082500095083FFA01CA20218ED9000C00E9282197 -:10826000249F000200A878210067C02133E4FFFFAB -:10827000AF9900503C010800AC3840003C010800B8 -:10828000A42F3FE83C010800A42E3FF20E0001E7B6 -:10829000000000008F8D0048004020213C010800B4 -:1082A000A02D3FF98E62000825AC0001AF8C00487C -:1082B0000040F809000000008F85005402A0302122 -:1082C0000E00060C004020210E0007AB00402021CC -:1082D0008E6B000C0160F809004020213C0A080068 -:1082E000954A3FF23C06080094C63FE60146482105 -:1082F000252800020E0001FB3104FFFF3C050800A9 -:108300008CA53FD43C0708008CE73FDC00A7202366 -:108310003C010800AC243FD414800006000000009B -:108320003C0208008C423FF4344B00403C01080002 -:10833000AC2B3FF4124000438F8E00448E2D001072 -:108340008F920044AE4D00208E2C0018AE4C0024BD -:108350003C04080094843FE80E000704000000007D -:108360008F9F00548E6700103C010800AC3F3FFC1B -:1083700000E0F809000000003C1908008F393FD4E4 -:108380001720FF798F870054979300583C11800E77 -:10839000321601000E000733A633002C16C000452C -:1083A000320300105460004C8EE500043208004097 -:1083B0005500001D8EF000088EE4000C0080F809C6 -:1083C000000000008FBF00388FB700348FB6003038 -:1083D0008FB5002C8FB400288FB300248FB20020FB -:1083E0008FB1001C8FB0001803E0000827BD0040CB -:1083F0008F86003C36110E0000072E0000A62025B7 -:10840000AE0400808E4300208E500024AFA30010E5 -:10841000AE2300148FB20010AE320010AE30001C3C -:108420000A000A7FAE3000180200F80900000000C0 -:108430008EE4000C0080F809000000000A000B38F0 -:108440008FBF003824180001240F0001A5C00020B0 -:10845000A5D800220A000B1AADCF00243C01080069 -:10846000AC203FD80A000AB08E6200003C01080030 -:10847000AC253FD80A000AB08E62000092240009A1 -:108480000E00077B000028218FBF00388FB7003413 -:108490008FB600308FB5002C8FB400288FB3002426 -:1084A0008FB200208FB1001C8FB0001803E00008CD -:1084B00027BD00403C14800092950109000028214E -:1084C0000E00084D32A400FF320300105060FFB8C8 -:1084D000320800408EE5000400A0F809000000000A -:1084E0000A000B32320800405240FFA89793005810 -:1084F0008E3400148F930044AE7400208E35001C1F -:10850000AE7500240A000B29979300588F8200143F -:108510000004218003E00008008210213C0780084D -:1085200034E200809043006900804021106000091F -:108530003C0401003C0708008CE73FFC8F830030BF -:1085400000E32023048000089389001C14E3000347 -:108550000100202103E00008008010213C040100FC -:1085600003E00008008010211120000B0067382371 -:108570003C0D800035AC0980918B007C316A000293 -:10858000114000202409003400E9702B15C0FFF1D0 -:108590000100202100E938232403FFFC00A3C824A4 -:1085A00000E3C02400F9782B15E0FFEA030820213E -:1085B00030C400030004102314C000143049000329 -:1085C0000000302100A9782101E6702100EE682B1F -:1085D00011A0FFE03C0401002D3800010006C82B6B -:1085E000010548210319382414E0FFDA2524FFFC93 -:1085F0002402FFFC00A218240068202103E00008E8 -:10860000008010210A000BA8240900303C0C8000D7 -:108610003586098090CB007C316A00041540FFE963 -:10862000240600040A000BB7000030213C030800B8 -:108630008C63005C8F82001827BDFFE0AFBF00187D -:10864000AFB1001410620005AFB00010000329C0E4 -:1086500024A40280AF840014AF8300183C10800073 -:1086600036020A0094450032361101000E000B89D3 -:1086700030A43FFF8E240000241FFF803C110080A7 -:108680000082C021031F60243309007F000CC94011 -:1086900003294025330E0078362F00033C0D1000CF -:1086A000010D502501CF5825AE0C00283608098051 -:1086B000AE0C080CAE0B082CAE0A08309103006912 -:1086C0003C06800C0126382110600006AF8700347C -:1086D0008D09003C8D03006C0123382318E00082D3 -:1086E000000000003C0B8008356A00803C108000D0 -:1086F000A1400069360609808CC200383C06800023 -:1087000034C50A0090A8003C310C00201180001AEA -:10871000AF820030240D00013C0E800035D10A00EC -:10872000A38D001CAF8000248E2400248F8500249C -:10873000240D0008AF800020AF8000283C01080015 -:10874000A42D3FE63C010800A4203FFA0E000B8D4B -:10875000000030219228003C8FBF00188FB1001418 -:108760008FB0001000086142AF82002C27BD0020AE -:1087700003E000083182000190B80032240E0001AD -:10878000330F00FF000F2182108E004124190002D8 -:108790001099006434C40AC03C03800034640A00A9 -:1087A0008C8F002415E0001E34660900909F003075 -:1087B0002418000533F9003F1338004E240300014C -:1087C0008F860020A383001CAF860028AF8600247C -:1087D0003C0E800035D10A008E2400248F850024B1 -:1087E000240D00083C010800A42D3FE63C010800D0 -:1087F000A4203FFA0E000B8D000000009228003CE0 -:108800008FBF00188FB100148FB0001000086142B4 -:10881000AF82002C27BD002003E000083182000158 -:108820008C8A00088C8B00248CD000643C0E800065 -:1088300035D10A00014B2823AF900024A380001CEF -:10884000AF8500288E2400248F8600208F85002489 -:10885000240D00083C010800A42D3FE63C0108005F -:10886000A4203FFA0E000B8D000000009228003C6F -:108870008FBF00188FB100148FB000100008614244 -:10888000AF82002C27BD002003E0000831820001E8 -:1088900090A200303051003F5224002834C50AC055 -:1088A0008CB000241600002234CB09008CA60048AE -:1088B0003C0A7FFF3545FFFF00C510243C0E8000B9 -:1088C000AF82002035C509008F8800208CAD006084 -:1088D000010D602B15800002010020218CA4006096 -:1088E0000A000C2CAF8400208D02006C0A000C06DC -:1088F0003C0680008C8200488F8600203C097FFF68 -:108900003527FFFF004788243C048008240300012A -:10891000AF910028AC80006CA383001C0A000C3AC5 -:10892000AF8600248C9F00140A000C2CAF9F0020FF -:108930008D6200680A000C763C0E800034C4098009 -:108940008C8900708CA300140123382B10E00004E4 -:10895000000000008C8200700A000C763C0E800043 -:108960008CA200140A000C763C0E80008F85002437 -:1089700027BDFFE0AFBF0018AFB1001414A000087E -:10898000AFB000103C04800034870A0090E600304D -:108990002402000530C3003F106200B9348409008E -:1089A0008F91002000A080213C048000348E0A00BA -:1089B0008DCD00043C0608008CC63FD831A73FFF90 -:1089C00000E6602B5580000100E03021938F001CF1 -:1089D00011E0007800D0282B349F098093F9007CA7 -:1089E00033380002130000792403003400C3102B35 -:1089F000144000D90000000000C3302300D0282B11 -:108A00003C010800A4233FE414A0006E02001821DA -:108A10003C0408008C843FD40064402B55000001C6 -:108A2000006020213C05800034A90A00912A003C06 -:108A30003C010800AC243FDC3143002014600003FB -:108A40000000482134AB0E008D6900188F88002C7F -:108A50000128202B1080005F000000003C0508006A -:108A60008CA53FDC00A96821010D602B1180005C02 -:108A700000B0702B0109382300E028213C010800D8 -:108A8000AC273FDC12000003240AFFFC10B0008D6D -:108A90003224000300AA18243C010800A4203FFA55 -:108AA0003C010800AC233FDC006028218F840024B7 -:108AB000120400063C0B80088D6C006C0200202123 -:108AC000AF91002025900001AD70006C8F8D0028C3 -:108AD00000858823AF91002401A52023AF840028BE -:108AE0001220000224070018240700103C188008F8 -:108AF0003706008090CF00683C010800A0273FF8AF -:108B00002407000131EE00FF11C7004700000000FC -:108B100014800018000028213C06800034D1098010 -:108B200034CD010091A600098E2C001824C4000148 -:108B3000000C86023205007F308B007F1165007FBC -:108B40002407FF803C19800837290080A124004CAD -:108B50003C0808008D083FF4241800023C0108007E -:108B6000A0384039350F00083C010800AC2F3FF415 -:108B7000240500103C02800034440A009083003C2D -:108B8000307F002013E0000500A02021240A00010E -:108B90003C010800AC2A3FDC34A400018FBF001860 -:108BA0008FB100148FB000100080102103E0000886 -:108BB00027BD00203C010800A4203FE410A0FF9442 -:108BC000020018210A000CCA00C018210A000CC1BA -:108BD000240300303C0508008CA53FDC00B0702B5E -:108BE00011C0FFA8000000003C19080097393FE4BD -:108BF0000325C0210307782B11E000072CAA0004ED -:108C00003C0360008C625404305F003F17E0FFE3D8 -:108C1000240400422CAA00041140FF9A24040042BC -:108C20000A000D2E8FBF00181528FFB900000000A4 -:108C30008CCA00183C1F800024020002015F182526 -:108C4000ACC3001837F90A00A0C200689329003CA1 -:108C50002404000400A01021312800203C01080059 -:108C6000A024403911000002240500102402000154 -:108C70003C010800AC223FD40A000D243C028000D5 -:108C80008F8800288C8900600109282B14A000021D -:108C9000010088218C9100603C048000348B0E0020 -:108CA0008D640018240A00010220282102203021AE -:108CB000A38A001C0E000B8D022080210A000CB03C -:108CC000AF82002C000458231220000731640003F7 -:108CD0003C0E800035C7098090ED007C31AC00046B -:108CE00015800019248F00043C010800A4243FFAD9 -:108CF0003C1F080097FF3FFA03E5C82100D9C02BAD -:108D00001300FF6B8F8400242CA6000514C0FFA362 -:108D10002404004230A200031440000200A21823E1 -:108D200024A3FFFC3C010800AC233FDC3C0108000D -:108D3000A4203FFA0A000CF10060282100C770242B -:108D40000A000D1701C720263C010800A42F3FFA96 -:108D50000A000D82000000003C010800AC203FDC4E -:108D60000A000D2D240400428F8300283C0580005A -:108D700034AA0A0014600006000010219147003058 -:108D80002406000530E400FF108600030000000008 -:108D900003E0000800000000914B0048316900FF2B -:108DA000000941C21500FFFA3C0680083C04080097 -:108DB00094843FE43C0308008C633FFC3C190800AA -:108DC0008F393FDC3C0F080095EF3FFA0064C0216B -:108DD0008CCD00040319702101CF602134AB0E004B -:108DE000018D282318A0001D00000000914F004CA9 -:108DF0008F8C0034956D001031EE00FF8D890004DA -:108E000001AE30238D8A000030CEFFFF000E290016 -:108E10000125C82100003821014720210325182BF6 -:108E20000083C021AD990004AD980000918F000A25 -:108E300001CF6821A18D000A956500128F8A003448 -:108E4000A5450008954B003825690001A549003863 -:108E50009148000D35070008A147000D03E0000808 -:108E60000000000027BDFFD8AFB000189388001C99 -:108E70008FB000143C0A80003C197FFF8F870024CC -:108E80003738FFFFAFBF0020AFB1001C355F0A00CD -:108E90000218182493EB003C00087FC03C02BFFF7F -:108EA000006F60252CF000013449FFFF3C1F0800D3 -:108EB0008FFF3FFC8F9900303C18080097183FF255 -:108EC00001897824001047803C07EFFF3C05F0FF44 -:108ED00001E818253C1180003169002034E2FFFFD1 -:108EE00034ADFFFF362E098027A5001024060002AE -:108EF00003F96023270B0002354A0E000062182494 -:108F00000080802115200002000040218D48001CB7 -:108F1000A7AB0012058000392407000030E800FFED -:108F200000083F00006758253C028008AFAB0014E2 -:108F3000344F008091EA00683C08080091083FF92E -:108F40003C09DFFF352CFFFF000AF82B3C0208002C -:108F500094423FECA3A80011016CC024001FCF4035 -:108F6000031918258FA70010AFA300143C0C0800AC -:108F7000918C3FFBA7A200168FAB001400ED482494 -:108F80003C0F01003C0A0FFF012FC8253198000358 -:108F9000355FFFFF016D40243C027000033F382421 -:108FA00000181E0000E2482501037825AFAF001429 -:108FB000AFA9001091CC007C0E000092A3AC00156C -:108FC000362D0A0091A6003C30C400201080000617 -:108FD000260200083C11080096313FE8262EFFFFCC -:108FE0003C010800A42E3FE88FBF00208FB1001C79 -:108FF0008FB0001803E0000827BD00288F8B002CDD -:10900000010B502B5540FFC5240700010A000E0E2E -:1090100030E800FF9383001C3C02800027BDFFD88E -:1090200034480A0000805021AFBF002034460AC0F7 -:10903000010028211060000E34440980910700309F -:10904000240B00058F89002030EC003F118B000BB2 -:1090500000003821AFA900103C0B80088D69006C1E -:10906000AFAA00180E00015AAFA90014A380001C7B -:109070008FBF002003E0000827BD00288D1F004897 -:109080003C1808008F183FDC8F9900283C027FFFB6 -:109090008D0800443443FFFFAFA900103C0B80084B -:1090A0008D69006C03E370240319782101CF6823D4 -:1090B00001A83821AFAA00180E00015AAFA9001468 -:1090C0000A000E62A380001C3C05800034A60A0042 -:1090D00090C7003C3C06080094C63FFA3C020800DA -:1090E0008C423FF430E30020000624001060001E94 -:1090F000004438253C0880083505008090A30068AE -:109100000000482124080001000028212404000157 -:109110003C0680008CCD017805A0FFFE34CF0140D5 -:10912000ADE800083C0208008C423FFCA5E50004C5 -:10913000A5E40006ADE2000C3C04080090843FF971 -:109140003C03800834790080A1E40012ADE70014EC -:10915000A5E900189338004C3C0E1000A1F8002D32 -:1091600003E00008ACCE017834A90E008D28001C65 -:109170003C0C08008D8C3FDC952B0016952A0014C2 -:10918000018648213164FFFF0A000E8A3145FFFF46 -:109190003C04800034830A009065003C30A200202B -:1091A0001040001934870E000000402100003821D3 -:1091B000000020213C0680008CC901780520FFFEBC -:1091C00034CA014034CF010091EB0009AD480008DA -:1091D0003C0E08008DCE3FFC240DFF91240C004076 -:1091E0003C081000A5440004A5470006AD4E000C45 -:1091F000A14D0012AD4C0014A5400018A14B002D4C -:1092000003E00008ACC801788CE8001894E600126E -:1092100094E4001030C7FFFF0A000EB33084FFFF54 -:109220003C04800034830A009065003C30A200209A -:109230001040002727BDFFF8240900010000382155 -:10924000240800013C0680008CCA01780540FFFE1E -:109250003C0280FF34C40100908D00093C0C0800E2 -:10926000918C4039A3AD00038FAB00003185007FA6 -:109270003459FFFF01665025AFAA00009083000A11 -:10928000A3A0000200057E00A3A300018FB8000088 -:1092900034CB0140240C30000319702401CF682521 -:1092A000AD6D000C27BD0008AD6C0014A560001862 -:1092B000AD690008A56700042409FF80A5680006C1 -:1092C0003C081000A169001203E00008ACC8017856 -:1092D00034870E008CE9001894E6001294E4001024 -:1092E00030C8FFFF0A000ED73087FFFF27BDFFE021 -:1092F000AFB100143C118000AFB00010AFBF001838 -:1093000036380A00970F0032363001000E000B8904 -:1093100031E43FFF8E0E0000240DFF803C0420004E -:1093200001C25821016D6024000C4940316A007F60 -:10933000012A4025010438253C048008AE27083066 -:109340003486008090C500682403000230A200FF2C -:10935000104300048F9F00208F990024AC9F006869 -:10936000AC9900648FBF00188FB100148FB000104B -:1093700003E0000827BD00203C0A0800254A3AA85F -:109380003C09080025293B383C08080025082F44E3 -:109390003C07080024E73C043C06080024C6392C9E -:1093A0003C05080024A536803C040800248432844F -:1093B0003C030800246339E03C0208002442377C67 -:1093C0003C010800AC2A3FB83C010800AC293FB47E -:1093D0003C010800AC283FB03C010800AC273FBC72 -:1093E0003C010800AC263FCC3C010800AC253FC442 -:1093F0003C010800AC243FC03C010800AC233FD036 -:109400003C010800AC223FC803E000080000000057 -:109410008000094080000900800801008008008069 -:1094200080080000800E0000800800808008000096 -:1094300080000A8080000A00800009808000090006 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex new file mode 100644 index 000000000000..68279b53e102 --- /dev/null +++ b/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex @@ -0,0 +1,6526 @@ +:10000000080001180800000000005594000000C816 +:1000100000000000000000000000000008005594EF +:10002000000000380000565C080000A00800000036 +:100030000000574400005694080059200000008436 +:100040000000ADD808005744000001C00000AE5CBD +:100050000800321008000000000092F80000B01CF8 +:10006000000000000000000000000000080092F8FE +:100070000000033C00014314080004900800040041 +:10008000000012FC000146500000000000000000CB +:1000900000000000080016FC000000040001594C9C +:1000A000080000A80800000000003D280001595089 +:1000B00000000000000000000000000008003D28D3 +:0800C0000000003000019678F9 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E322E31DF +:1000E0000000000006020102000000000000000302 +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C020800244256083C030800A1 +:1002000024635754AC4000000043202B1480FFFDB2 +:10021000244200043C1D080037BD9FFC03A0F021D0 +:100220003C100800261001183C1C0800279C5608AA +:100230000E000256000000000000000D27BDFFB4B4 +:10024000AFA10000AFA20004AFA30008AFA4000C50 +:10025000AFA50010AFA60014AFA70018AFA8001CF0 +:10026000AFA90020AFAA0024AFAB0028AFAC002C90 +:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 +:10028000AFB90040AFBC0044AFBF00480E001544FA +:10029000000000008FBF00488FBC00448FB90040B1 +:1002A0008FB8003C8FAF00388FAE00348FAD003078 +:1002B0008FAC002C8FAB00288FAA00248FA90020C0 +:1002C0008FA8001C8FA700188FA600148FA5001000 +:1002D0008FA4000C8FA300088FA200048FA1000040 +:1002E00027BD004C3C1B60108F7A5030377B502864 +:1002F00003400008AF7A00008F82002427BDFFE092 +:10030000AFB00010AFBF0018AFB100148C42000CAA +:100310003C1080008E110100104000348FBF001887 +:100320000E000D84000000008F85002024047FFF54 +:100330000091202BACB100008E030104960201084D +:1003400000031C003042FFFF00621825ACA300042C +:100350009202010A96030114304200FF3063FFFF4E +:100360000002140000431025ACA200089603010C03 +:100370009602010E00031C003042FFFF00621825A8 +:10038000ACA3000C960301109602011200031C009E +:100390003042FFFF00621825ACA300108E02011846 +:1003A000ACA200148E02011CACA20018148000083C +:1003B0008F820024978200003C0420050044182509 +:1003C00024420001ACA3001C0A0000C6A782000062 +:1003D0003C0340189442001E00431025ACA2001CB0 +:1003E0000E000DB8240400018FBF00188FB1001457 +:1003F0008FB000100000102103E0000827BD00208E +:100400003C0780008CE202B834E50100044100089A +:10041000240300013C0208008C42006024420001D9 +:100420003C010800AC22006003E0000800601021DD +:100430003C0208008C42005C8CA4002094A30016AF +:100440008CA6000494A5000E24420001ACE40280B6 +:100450002463FFFC3C010800AC22005C3C0210005D +:10046000A4E30284A4E5028600001821ACE6028819 +:10047000ACE202B803E000080060102127BDFFE0F5 +:100480003C028000AFB0001034420100AFBF001C3E +:10049000AFB20018AFB100148C43000094450008BF +:1004A0002462FE002C42038110400003000381C23D +:1004B0000A00010226100004240201001462000553 +:1004C0003C1180003C02800890420004305000FF44 +:1004D0003C11800036320100964300143202000FB6 +:1004E00000021500004310253C0308008C63004403 +:1004F00030A40004AE220080246300013C01080007 +:10050000AC2300441080000730A200028FBF001C03 +:100510008FB200188FB100148FB000100A0000CE07 +:1005200027BD00201040002D0000182130A20080BF +:1005300010400005362200708E44001C0E000C672F +:10054000240500A0362200708C4400008F82000C2D +:10055000008210232C43012C10600004AF82001095 +:10056000240300010A000145AF84000C8E42000400 +:100570003C036020AF84000CAC6200143C02080015 +:100580008C42005850400015000018218C62000475 +:10059000240301FE304203FF144300100000182121 +:1005A0002E020004104000032E0200080A00014041 +:1005B0000000802114400003000000000A000140F8 +:1005C0002610FFF90000000D2402000202021004B0 +:1005D0003C036000AC626914000018218FBF001C4E +:1005E0008FB200188FB100148FB00010006010217E +:1005F00003E0000827BD00203C0480008C8301003C +:1006000024020100506200033C0280080000000D3B +:100610003C02800890430004000010213063000F6A +:1006200000031D0003E00008AC8300800004188074 +:100630002782FF9C00621821000410C00044102390 +:100640008C640000000210C03C030800246356E4E0 +:10065000004310213C038000AC64009003E00008DC +:10066000AF8200243C0208008C42011410400019A3 +:100670003084400030A2007F000231C03C02020002 +:100680001080001400A218253C026020AC43001426 +:100690003C0408008C8456B83C0308008C630110AD +:1006A0003C02800024050900AC4500200086202182 +:1006B000246300013C028008AC4400643C01080053 +:1006C000AC2301103C010800AC2456B803E000083C +:1006D000000000003C02602003E00008AC4500146C +:1006E00003E000080000102103E0000800001021D2 +:1006F00030A2000810400008240201003C0208005B +:100700008C42010C244200013C010800AC22010C87 +:1007100003E0000800000000148200080000000050 +:100720003C0208008C4200FC244200013C0108000D +:10073000AC2200FC0A0001A330A200203C02080009 +:100740008C420084244200013C010800AC22008459 +:1007500030A200201040000830A200103C02080027 +:100760008C420108244200013C010800AC2201082F +:1007700003E0000800000000104000080000000036 +:100780003C0208008C420104244200013C010800A4 +:10079000AC22010403E00008000000003C02080055 +:1007A0008C420100244200013C010800AC220100FF +:1007B00003E000080000000027BDFFE0AFB1001417 +:1007C0003C118000AFB20018AFBF001CAFB00010EA +:1007D0003632010096500008320200041040000733 +:1007E000320300028FBF001C8FB200188FB10014BB +:1007F0008FB000100A0000CE27BD00201060000B53 +:10080000020028218E2401000E00018A0000000051 +:100810003202008010400003240500A10E000C6786 +:100820008E44001C0A0001E3240200018E2301040F +:100830008F82000810430006020028218E24010048 +:100840000E00018A000000008E220104AF82000821 +:10085000000010218FBF001C8FB200188FB1001450 +:100860008FB0001003E0000827BD00202C82000498 +:1008700014400002000018212483FFFD240200021E +:10088000006210043C03600003E00008AC626914DD +:1008900027BDFFE0AFBF001CAFB20018AFB100141E +:1008A000AFB000103C048000948201083043700017 +:1008B000240220001062000A2862200154400052E5 +:1008C0008FBF001C24024000106200482402600018 +:1008D0001062004A8FBF001C0A0002518FB200183C +:1008E00034820100904300098C5000189451000C90 +:1008F000240200091062001C0000902128620009F7 +:10090000144000218F8200242402000A5062001249 +:10091000323100FF2402000B1062000F00000000C3 +:100920002402000C146200188F8200243C0208008C +:100930008C4256B824030900AC83002000501021DB +:100940003C038008AC6200643C010800AC2256B84D +:100950000A0002508FBF001C0E0001E900102602A1 +:100960000A0002308F8200240E0001E900102602E6 +:100970003C0380089462001A8C72000C3042FFFF26 +:10098000020280258F8200248C42000C5040001E01 +:100990008FBF001C0E000D84000000003C02800090 +:1009A00034420100944300088F82002400031C009D +:1009B0009444001E8F82002000641825AC50000073 +:1009C00024040001AC510004AC520008AC40000CFF +:1009D000AC400010AC400014AC4000180E000DB844 +:1009E000AC43001C0A0002508FBF001C0E000440E4 +:1009F000000000000A0002508FBF001C0E000C9F78 +:100A0000000000008FBF001C8FB200188FB10014CF +:100A10008FB000100000102103E0000827BD002067 +:100A200027BDFFD8AFB400203C036010AFBF002447 +:100A3000AFB3001CAFB20018AFB10014AFB00010DC +:100A40008C6450002402FF7F3C1408002694563822 +:100A5000008220243484380CAC6450003C028000B6 +:100A6000240300370E0014B0AC4300083C07080014 +:100A700024E70618028010212404001D2484FFFFAF +:100A8000AC4700000481FFFD244200043C02080042 +:100A9000244207C83C010800AC2256403C02080032 +:100AA000244202303C030800246306203C04080072 +:100AB000248403B43C05080024A506F03C06080085 +:100AC00024C62C9C3C010800AC2256803C02080045 +:100AD000244205303C010800AC2756843C01080044 +:100AE000AC2656943C010800AC23569C3C010800FF +:100AF000AC2456A03C010800AC2556A43C010800DB +:100B0000AC2256A83C010800AC23563C3C0108002E +:100B1000AC2456443C010800AC2056603C0108005F +:100B2000AC2556643C010800AC2056703C0108001E +:100B3000AC27567C3C010800AC2656903C010800CE +:100B4000AC2356980E00056E00000000AF80000C2C +:100B50003C0280008C5300008F8300043C0208009C +:100B60008C420020106200213262000700008821C0 +:100B70002792FF9C3C100800261056E43C02080017 +:100B80008C42002024050001022518040043202483 +:100B90008F820004004310245044000C26310001D1 +:100BA00010800008AF9000248E4300003C028000BB +:100BB000AC4300900E000D4BAE05000C0A0002C1C4 +:100BC00026310001AE00000C263100012E22000269 +:100BD000261000381440FFE9265200043C020800A9 +:100BE0008C420020AF820004326200071040FFD91F +:100BF0003C028000326200011040002D326200028F +:100C00003C0580008CA2010000002021ACA2002045 +:100C10008CA301042C42078110400008ACA300A85B +:100C200094A2010824032000304270001443000302 +:100C30003C02800890420005304400FF0E0001593C +:100C4000000000003C0280009042010B304300FF96 +:100C50002C62001E54400004000310800E00018628 +:100C60000A0002EC00000000005410218C42000039 +:100C70000040F80900000000104000043C02800021 +:100C80008C4301043C026020AC4300143C02080089 +:100C90008C4200343C0440003C03800024420001AC +:100CA000AC6401383C010800AC220034326200021E +:100CB00010400010326200043C1080008E0201409F +:100CC000000020210E000159AE0200200E00038317 +:100CD000000000003C024000AE0201783C02080027 +:100CE0008C420038244200013C010800AC2200384C +:100CF000326200041040FF973C0280003C108000EC +:100D00008E020180000020210E000159AE02002059 +:100D10008E03018024020F00546200073C02800809 +:100D20008E0201883C0300E03042FFFF00431025A3 +:100D30000A000328AE020080344200809042000086 +:100D400024030050304200FF14430007000000005D +:100D50000E000362000000001440000300000000C9 +:100D60000E000971000000003C0208008C42003CAB +:100D70003C0440003C03800024420001AC6401B804 +:100D80003C010800AC22003C0A0002A33C028000A7 +:100D90003C02900034420001008220253C02800089 +:100DA000AC4400203C0380008C6200200440FFFE25 +:100DB0000000000003E00008000000003C0280008A +:100DC000344300010083202503E00008AC440020E8 +:100DD00027BDFFE0AFB10014AFB000100080882144 +:100DE000AFBF00180E00033230B000FF8F83FF94B6 +:100DF000022020219062002502028025A07000259B +:100E00008C7000183C0280000E00033D020280241A +:100E10001600000B8FBF00183C0480008C8201F884 +:100E20000440FFFE348201C024030002AC510000E4 +:100E3000A04300043C021000AC8201F88FBF0018F0 +:100E40008FB100148FB0001003E0000827BD002010 +:100E500027BDFFE83C028000AFBF00103442018094 +:100E6000944300048C4400083063020010600005C5 +:100E7000000028210E00100C000000000A0003787A +:100E8000240500013C02FF000480000700821824B2 +:100E90003C02040014620004240500018F82FF94C8 +:100EA00090420008240500018FBF001000A010210F +:100EB00003E0000827BD00188F82FF982405000179 +:100EC000A040001A3C028000344201400A00034264 +:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E +:100EE000AFB20018AFB10014AFB0001090A2000074 +:100EF000304400FF38830020388200300003182B74 +:100F00000002102B0062182410600003240200501D +:100F1000148200A88FBF001C90A20005304200017F +:100F2000104000A48FBF001C3C02800034420140EE +:100F3000904200082443FFFF2C6200051040009EF1 +:100F40008FB20018000310803C030800246355ACE6 +:100F5000004310218C420000004000080000000007 +:100F60003C028000345101400E0003328E24000008 +:100F70008F92FF948E2200048E50000C1602000205 +:100F800024020001AE42000C0E00033D8E2400003E +:100F90008E220004145000068FBF001C8FB2001870 +:100FA0008FB100148FB000100A000F7827BD002009 +:100FB0008E42000C0A000419000000003C0480006E +:100FC0003482014094A300108C4200043063FFFF80 +:100FD0001443001C0000000024020001A4A2001021 +:100FE0008C8202380441000F3C0380003C02003F29 +:100FF0003448F0003C0760003C06FFC08CE22BBC8C +:1010000000461824004810240002130200031D8229 +:10101000106200583C0280008C8202380440FFF7C6 +:101020003C038000346201408C44000034620200C2 +:10103000AC4400003C021000AC6202380A00043BE1 +:101040008FBF001C94A200100A00041900000000C9 +:10105000240200201482000F3C0280003C03800028 +:1010600094A20012346301408C6300043042FFFFFD +:10107000146200050000000024020001A4A2001276 +:101080000A0004028FBF001C94A200120A00041977 +:1010900000000000345101400E0003328E24000095 +:1010A0008F92FF948E230004964200123050FFFF6F +:1010B0001603000224020001A64200120E00033DA6 +:1010C0008E2400008E220004160200068FBF001C32 +:1010D0008FB200188FB100148FB000100A00037C8B +:1010E00027BD0020964200120A00041900000000EB +:1010F0003C03800094A20014346301408C6300041C +:101100003042FFFF14620008240200018FBF001C60 +:101110008FB200188FB100148FB00010A4A2001479 +:101120000A00146327BD002094A20014144000217B +:101130008FBF001C0A000435000000003C03800043 +:1011400094A20016346301408C6300043042FFFF18 +:101150001462000D240200018FBF001C8FB2001822 +:101160008FB100148FB00010A4A200160A000B1457 +:1011700027BD00209442007824420004A4A200105D +:101180000A00043B8FBF001C94A200162403000138 +:101190003042FFFF144300078FBF001C3C020800D1 +:1011A0008C420070244200013C010800AC22007017 +:1011B0008FBF001C8FB200188FB100148FB00010C9 +:1011C00003E0000827BD002027BDFFD8AFB20018FC +:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB +:1011E000AFB000103C028000345101008C5001006F +:1011F0009242000092230009304400FF2402001FA5 +:10120000106200AB28620020104000192402003850 +:101210002862000A1040000D2402000B286200081A +:101220001040002E8F820024046001042862000216 +:101230001440002A8F820024240200061062002637 +:101240008FBF00200A00055F8FB3001C1062006092 +:101250002862000B144000FA8FBF00202402000E09 +:10126000106200788F8200240A00055F8FB3001C93 +:10127000106200D2286200391040000A2402008067 +:1012800024020036106200E528620037104000C3D7 +:1012900024020035106200D98FBF00200A00055FCC +:1012A0008FB3001C1062002D2862008110400006E0 +:1012B000240200C824020039106200C98FBF002038 +:1012C0000A00055F8FB3001C106200A28FBF0020D0 +:1012D0000A00055F8FB3001C8F8200248C42000C33 +:1012E000104000D78FBF00200E000D8400000000CA +:1012F0003C038000346301008C6200008F85002075 +:10130000946700089466000CACA200008C64000492 +:101310008F82002400063400ACA400049448001E10 +:101320008C62001800073C0000E83825ACA20008D9 +:101330008C62001C24040001ACA2000C9062000A24 +:1013400000C23025ACA60010ACA00014ACA0001860 +:10135000ACA7001C0A00051D8FBF00208F8200244F +:101360008C42000C104000B68FBF00200E000D8490 +:10137000000000008F820024962400089625000CAF +:101380009443001E000422029626000E8F82002045 +:10139000000426000083202500052C003C0300806B +:1013A00000A6282500832025AC400000AC400004A6 +:1013B000AC400008AC40000CAC450010AC40001440 +:1013C000AC400018AC44001C0A00051C24040001B9 +:1013D0009622000C14400018000000009242000504 +:1013E0003042001014400014000000000E000332D0 +:1013F0000200202192420005020020213442001008 +:101400000E00033DA242000592420000240300208A +:10141000304200FF10430089020020218FBF0020CE +:101420008FB3001C8FB200188FB100148FB0001062 +:101430000A00107527BD00280000000D0A00055E97 +:101440008FBF00208C42000C1040007D8FBF002019 +:101450000E000D84000000008E2200048F84002006 +:101460009623000CAC8200003C0280089445002CBE +:101470008F82002400031C0030A5FFFF9446001E4D +:101480003C02400E0065182500C23025AC830004E4 +:10149000AC800008AC80000CAC800010AC80001464 +:1014A000AC800018AC86001C0A00051C2404000156 +:1014B0000E000332020020218F93FF9802002021AA +:1014C0000E00033DA660000C020020210E00034226 +:1014D000240500018F8200248C42000C104000582B +:1014E0008FBF00200E000D84000000009622000C2B +:1014F0008F83002000021400AC700000AC62000476 +:10150000AC6000088E4400388F820024AC64000C6C +:101510008E46003C9445001E3C02401FAC66001005 +:1015200000A228258E62000424040001AC6200148D +:10153000AC600018AC65001C8FBF00208FB3001C8E +:101540008FB200188FB100148FB000100A000DB8D0 +:1015500027BD0028240200201082003A8FB3001C0F +:101560000E000F5E00000000104000358FBF00200D +:101570003C0480008C8201F80440FFFE348201C0EC +:1015800024030002AC500000A04300043C02100001 +:10159000AC8201F80A00055E8FBF00200200202106 +:1015A0008FBF00208FB3001C8FB200188FB10014C2 +:1015B0008FB000100A000EA727BD00289625000C4A +:1015C000020020218FBF00208FB3001C8FB20018B3 +:1015D0008FB100148FB000100A000ECC27BD002878 +:1015E000020020218FB3001C8FB200188FB10014AD +:1015F0008FB000100A000EF727BD00289225000DBD +:10160000020020218FB3001C8FB200188FB100148C +:101610008FB000100A000F4827BD002802002021CB +:101620008FBF00208FB3001C8FB200188FB1001441 +:101630008FB000100A000F1F27BD00288FBF0020A9 +:101640008FB3001C8FB200188FB100148FB0001040 +:1016500003E0000827BD00283C0580008CA202782A +:101660000440FFFE34A2024024030002AC44000008 +:10167000A04300043C02100003E00008ACA2027882 +:10168000A380001803E00008A38000193C03800039 +:101690008C6202780440FFFE8F82001CAC62024024 +:1016A00024020002A06202443C02100003E0000891 +:1016B000AC6202783C02600003E000088C425404F3 +:1016C0009083003024020005008040213063003FF9 +:1016D0000000482114620005000050219082004C57 +:1016E0009483004E304900FF306AFFFFAD00000CCC +:1016F000AD000010AD000024950200148D05001C03 +:101700008D0400183042FFFF004910230002110031 +:10171000000237C3004038210086202300A2102B8E +:101720000082202300A72823AD05001CAD0400186B +:10173000A5090014A5090020A50A001603E0000869 +:10174000A50A002203E000080000000027BDFFD822 +:10175000AFB200183C128008AFB40020AFB3001C39 +:10176000AFB10014AFBF0024AFB00010365101007C +:101770003C0260008C4254049222000C3C1408008D +:10178000929400F7304300FF2402000110620032FF +:101790000080982124020002146200353650008037 +:1017A0000E00143D000000009202004C2403FF8054 +:1017B0003C0480003042007F000211C024420240FD +:1017C0000262102100431824AC8300949245000863 +:1017D0009204004C3042007F3C03800614850007D1 +:1017E000004380212402FFFFA22200112402FFFFF8 +:1017F000A62200120A0005D22402FFFF9602002052 +:10180000A222001196020022A62200128E020024BB +:101810003C048008AE2200143485008090A2004C65 +:1018200034830100A06200108CA2003CAC6200185E +:101830008C820068AC6200F48C820064AC6200F0C0 +:101840008C82006CAC6200F824020001A0A2006847 +:101850000A0005EE3C0480080E001456000000004B +:1018600036420080A04000680A0005EE3C04800873 +:10187000A2000068A20000690A0006293C02800854 +:10188000348300808C62003834850100AC62006CC7 +:1018900024020001A062006990A200D59083000894 +:1018A000305100FF3072007F12320019001111C058 +:1018B00024420240026210212403FF8000431824C6 +:1018C0003C048000AC8300943042007F3C038006DF +:1018D000004380218E02000C1040000D02002021E8 +:1018E0000E00057E0000000026220001305100FF9E +:1018F0009203003C023410260002102B0002102339 +:101900003063007F022288240A0005F8A203003C0D +:101910003C088008350401008C8200E03507008017 +:10192000ACE2003C8C8200E0AD02000090E5004C8F +:10193000908600D590E3004C908400D52402FF806F +:1019400000A228243063007F308400FF00A62825F1 +:101950000064182A1060000230A500FF38A500803E +:10196000A0E5004CA10500093C0280089043000E50 +:10197000344400803C058000A043000A8C8300189A +:101980003C027FFF3442FFFF00621824AC83001842 +:101990008CA201F80440FFFE00000000ACB301C0BF +:1019A0008FBF00248FB400208FB3001C8FB20018AB +:1019B0008FB100148FB0001024020002A0A201C455 +:1019C00027BD00283C02100003E00008ACA201F88B +:1019D00090A2000024420001A0A200003C030800E5 +:1019E0008C6300F4304200FF144300020080302179 +:1019F000A0A0000090A200008F84001C000211C073 +:101A00002442024024830040008220212402FF80DF +:101A1000008220243063007F3C02800A006218218B +:101A20003C028000AC44002403E00008ACC300008A +:101A300094820006908300058C85000C8C86001033 +:101A40008C8700188C88001C8C8400203C010800C6 +:101A5000A42256C63C010800A02356C53C0108003C +:101A6000AC2556CC3C010800AC2656D03C01080001 +:101A7000AC2756D83C010800AC2856DC3C010800D5 +:101A8000AC2456E003E00008000000003C0280089F +:101A9000344201008C4400343C038000346504006F +:101AA000AC6400388C420038AF850028AC62003C42 +:101AB0003C020005AC6200300000000000000000A5 +:101AC00003E00008000000003C020006308400FF34 +:101AD000008220253C028000AC4400300000000061 +:101AE00000000000000000003C0380008C62000049 +:101AF000304200101040FFFD3462040003E0000893 +:101B0000AF82002894C200003C080800950800CA73 +:101B100030E7FFFF0080482101021021A4C200002D +:101B200094C200003042FFFF00E2102B544000013D +:101B3000A4C7000094A200003C0308008C6300CC02 +:101B400024420001A4A2000094A200003042FFFF42 +:101B5000144300073C0280080107102BA4A00000DA +:101B60005440000101003821A4C700003C02800855 +:101B7000344601008CC3002894A200003C0480007D +:101B80003042FFFE000210C000621021AC82003C17 +:101B90008C82003C006218231860000400000000E2 +:101BA0008CC200240A0006BA244200018CC2002420 +:101BB000AC8200383C020050344200103C038000EC +:101BC000AC620030000000000000000000000000D7 +:101BD0008C620000304200201040FFFD0000000039 +:101BE00094A200003C04800030420001000210C0BA +:101BF000004410218C430400AD2300008C420404F7 +:101C0000AD2200043C02002003E00008AC8200305A +:101C100027BDFFE0AFB20018AFB10014AFB00010A5 +:101C2000AFBF001C94C2000000C080213C1208001D +:101C3000965200C624420001A6020000960300004E +:101C400094E2000000E03021144300058FB1003021 +:101C50000E00068F024038210A0006F10000000045 +:101C60008C8300048C82000424420040046100073D +:101C7000AC8200048C8200040440000400000000D8 +:101C80008C82000024420001AC8200009602000019 +:101C90003042FFFF50520001A600000096220000D3 +:101CA00024420001A62200003C02800834420100C8 +:101CB000962300009442003C144300048FBF001C94 +:101CC00024020001A62200008FBF001C8FB2001862 +:101CD0008FB100148FB0001003E0000827BD002072 +:101CE00027BDFFE03C028008AFBF0018344201006E +:101CF0008C4800343C03800034690400AC68003830 +:101D00008C42003830E700FFAF890028AC62003C0D +:101D10003C020005AC620030000000000000000042 +:101D200000000000000000000000000000000000B3 +:101D30008C82000C8C82000C97830016AD22000070 +:101D40008C82001000604021AD2200048C820018BB +:101D5000AD2200088C82001CAD22000C8CA2001465 +:101D6000AD2200108C820020AD220014908200056C +:101D7000304200FF00021200AD2200188CA20018B1 +:101D8000AD22001C8CA2000CAD2200208CA2001001 +:101D9000AD2200248CA2001CAD2200288CA20020C1 +:101DA000AD22002C3402FFFFAD260030AD20003400 +:101DB000506200013408FFFFAD28003850E00011E8 +:101DC0003C0280083C048008348401009482005066 +:101DD0003042FFFFAD22003C9483004494850044D0 +:101DE000240200013063FFFF000318C200641821C1 +:101DF0009064006430A5000700A210040A00075C8C +:101E00000044102534420100AD20003C94430044BE +:101E1000944400443063FFFF000318C2006218219D +:101E200030840007906500642402000100821004E1 +:101E30000002102700451024A0620064000000008A +:101E400000000000000000003C0200063442004098 +:101E50003C038000AC620030000000000000000085 +:101E6000000000008C620000304200101040FFFDB6 +:101E70003C06800834C201503463040034C7014A70 +:101E800034C4013434C5014034C60144AFA200104B +:101E90000E0006D2AF8300288FBF001803E00008B1 +:101EA00027BD00208F8300143C0608008CC600E884 +:101EB0008F82001C30633FFF000319800046102111 +:101EC000004310212403FF80004318243C068000B7 +:101ED000ACC300283042007F3C03800C004330211B +:101EE00090C2000D30A500FF0000382134420010E0 +:101EF000A0C2000D8F8900143C028008344201000A +:101F00009443004400091382304800032402000176 +:101F1000A4C3000E1102000B2902000210400005AC +:101F2000240200021100000C240300010A0007A48F +:101F30000000182111020006000000000A0007A49A +:101F4000000018218CC2002C0A0007A424430001C1 +:101F50008CC20014244300018CC200180043102BD3 +:101F60005040000A240700012402002714A20003A5 +:101F70003C0380080A0007B1240700013463010014 +:101F80009462004C24420001A462004C00091382B8 +:101F9000304300032C620002104000090080282119 +:101FA000146000040000000094C200340A0007C15D +:101FB0003046FFFF8CC600380A0007C10080282188 +:101FC000000030213C040800248456C00A000706A3 +:101FD0000000000027BDFF90AFB60068AFB50064F9 +:101FE000AFB40060AFB3005CAFB20058AFB1005403 +:101FF000AFBF006CAFB000508C9000000080B021EB +:102000003C0208008C4200E8960400328F83001CDA +:102010002414FF8030843FFF0062182100042180D7 +:1020200000641821007410243C13800000A090214B +:1020300090A50000AE620028920400323C02800CA1 +:102040003063007F00628821308400C02402004099 +:10205000148200320000A8218E3500388E2200182C +:102060001440000224020001AE2200189202003C3B +:10207000304200201440000E8F83001C000511C068 +:102080002442024000621821306400783C02008043 +:102090000082202500741824AE630800AE64081086 +:1020A0008E2200188E03000800431021AE22001873 +:1020B0008E22002C8E230018244200010062182B6F +:1020C0001060004300000000924200002442000122 +:1020D000A24200003C0308008C6300F4304200FF81 +:1020E00050430001A2400000924200008F84001C77 +:1020F000000211C024420240248300403063007F6C +:10210000008220213C02800A0094202400621821D1 +:10211000AE6400240A0008D2AEC30000920300326D +:102120002402FFC000431024304200FF1440000589 +:1021300024020001AE220018962200340A00084250 +:102140003055FFFF8E22001424420001AE220018F9 +:102150009202003000021600000216030441001C27 +:10216000000000009602003227A400100080282101 +:10217000A7A20016960200320000302124070001B9 +:102180003042FFFFAF8200140E000706AFA0001C14 +:10219000960200328F83001C3C0408008C8400E807 +:1021A00030423FFF000211800064182100621821B4 +:1021B00000741024AE62002C3063007F3C02800E5D +:1021C000006218219062000D3042007FA062000D75 +:1021D0009222000D304200105040007892420000E0 +:1021E0003C028008344401009482004C8EC30000FD +:1021F0003C130800967300C62442FFFFA482004CE3 +:10220000946200329623000E3054FFFF3070FFFFBF +:102210003C0308008C6300D000701807A7A30038A7 +:102220009482003E3063FFFF3042FFFF14620007DC +:10223000000000008C8200303C038000244200300B +:10224000AC62003C0A00086A8C82002C9482004038 +:102250003042FFFF5462000927A400408C820038FE +:102260003C03800024420030AC62003C8C8200348D +:10227000AC6200380A0008793C03800027A50038CA +:1022800027A60048026038210E00068FA7A000484C +:102290008FA300403C02800024630030AC43003830 +:1022A0008FA30044AC43003C3C0380003C0200058B +:1022B000AC6200303C028008344401009482004249 +:1022C000346304003042FFFF0202102B1440000769 +:1022D000AF8300289482004E9483004202021021B2 +:1022E000004310230A00088F3043FFFF9483004E01 +:1022F00094820042026318210050102300621823C8 +:102300003063FFFF3C028008344401009482003CAB +:102310003042FFFF14430003000000000A00089F42 +:10232000240300019482003C3042FFFF0062102B26 +:10233000144000058F8200289482003C0062102324 +:102340003043FFFF8F820028AC550000AC400004F2 +:10235000AC540008AC43000C3C02000634420010B0 +:102360003C038000AC620030000000000000000070 +:10237000000000008C620000304200101040FFFDA1 +:102380003C04800834840100001018C20064182145 +:102390009065006432020007240600010046100424 +:1023A00000451025A0620064948300429622000E2E +:1023B00050430001A386001892420000244200010D +:1023C000A24200003C0308008C6300F4304200FF8E +:1023D00050430001A2400000924200008F84001C84 +:1023E000000211C0244202402483004000822021C8 +:1023F0002402FF80008220243063007F3C02800A98 +:10240000006218213C028000AC440024AEC30000EE +:102410008FBF006C8FB600688FB500648FB400600A +:102420008FB3005C8FB200588FB100548FB0005052 +:1024300003E0000827BD007027BDFFD8AFB3001C24 +:10244000AFB20018AFB10014AFB00010AFBF0020A2 +:102450000080982100E0802130B1FFFF0E000D8444 +:1024600030D200FF0000000000000000000000006B +:102470008F8200208F830024AC510000AC520004F6 +:10248000AC530008AC40000CAC400010AC40001451 +:10249000AC4000189463001E02038025AC50001C61 +:1024A0000000000000000000000000002404000103 +:1024B0008FBF00208FB3001C8FB200188FB10014A3 +:1024C0008FB000100A000DB827BD002830A5FFFF0F +:1024D0000A0008DC30C600FF3C02800834430100DB +:1024E0009462000E3C080800950800C63046FFFFC5 +:1024F00014C000043402FFFF946500EA0A000929B1 +:102500008F84001C10C20027000000009462004E5F +:102510009464003C3045FFFF00A6102300A6182B52 +:102520003087FFFF106000043044FFFF00C5102318 +:1025300000E210233044FFFF0088102B1040000EF3 +:1025400000E810233C028008344401002403000109 +:1025500034420080A44300162402FFFFA482000E30 +:10256000948500EA8F84001C0000302130A5FFFF15 +:102570000A0009013C0760200044102A10400009AD +:102580003C0280083443008094620016304200010F +:10259000104000043C0280009442007E244200145B +:1025A000A462001603E000080000000027BDFFE061 +:1025B0003C028008AFBF001CAFB0001834420100DD +:1025C000944300429442004C104000193068FFFFD1 +:1025D0009383001824020001146200298FBF001C9D +:1025E0003C06800834D00100000810C200501021C1 +:1025F000904200643103000734C70148304200FFB5 +:10260000006210073042000134C9014E34C4012C6D +:1026100034C5013E1040001634C601420E0006D2F9 +:10262000AFA90010960200420A0009463048FFFF99 +:102630003C028008344401009483004494820042A8 +:102640001043000F8FBF001C94820044A4820042FC +:1026500094820050A482004E8C820038AC820030FC +:1026600094820040A482003E9482004AA4820048E2 +:102670008FBF001C8FB000180A00090427BD00207E +:102680008FB0001803E0000827BD002027BDFFA081 +:10269000AFB1004C3C118000AFBF0058AFB3005445 +:1026A000AFB20050AFB000483626018890C2000398 +:1026B0003044007FA3A400108E32018090C200003D +:1026C0003043007F240200031062003BAF92001CE5 +:1026D00028620004104000062402000424020002C4 +:1026E000106200098FBF00580A000B0F8FB300540F +:1026F0001062004D240200051062014E8FBF005889 +:102700000A000B0F8FB30054000411C002421021C5 +:102710002404FF8024420240004410242643004049 +:10272000AE2200243063007F3C02800A0062182140 +:102730009062003CAFA3003C00441025A062003C26 +:102740008FA3003C9062003C304200401040016C7E +:102750008FBF00583C108008A3800018361001007D +:102760008E0200E08C63003427A4003C27A50010F3 +:10277000004310210E0007C3AE0200E093A2001038 +:102780003C038000A20200D58C6202780440FFFE68 +:102790008F82001CAC62024024020002A06202444C +:1027A0003C021000AC6202780E0009390000000003 +:1027B0000A000B0E8FBF00583C05800890C3000133 +:1027C00090A2000B1443014E8FBF005834A4008028 +:1027D0008C8200189082004C90A200083C0260009D +:1027E0008C4254048C8300183C027FFF3442FFFF6C +:1027F000006218243C0208008C4200B4AC8300182C +:102800003C038000244200013C010800AC2200B4DB +:102810008C6201F80440FFFE8F82001CAC6201C094 +:102820000A000AD6240200023C10800890C300016E +:102830009202000B144301328FBF005827A40018E6 +:1028400036050110240600033C0260008C4254044B +:102850000E000E470000000027A40028360501F0F6 +:102860000E000E47240600038FA200283603010045 +:10287000AE0200648FA2002CAE0200688FA200306E +:10288000AE02006C93A40018906300D52402FF8070 +:102890000082102400431025304900FF3084007F5F +:1028A0003122007F0082102A544000013929008023 +:1028B000000411C0244202402403FF800242102180 +:1028C00000431024AE220094264200403042007F94 +:1028D0003C038006004340218FA3001C2402FFFF1D +:1028E000AFA800403C130800927300F71062003359 +:1028F00093A2001995030014304400FF3063FFFFDA +:102900000064182B106000100000000095040014F3 +:102910008D07001C8D0600183084FFFF0044202323 +:102920000004210000E438210000102100E4202BE5 +:1029300000C2302100C43021AD07001CAD060018D4 +:102940000A000A2F93A20019950400148D07001C99 +:102950008D0600183084FFFF008220230004210030 +:10296000000010210080182100C2302300E4202B39 +:1029700000C4302300E33823AD07001CAD06001867 +:1029800093A200198FA30040A462001497A2001A1A +:10299000A46200168FA2001CAC6200108FA2001C63 +:1029A000AC62000C93A20019A462002097A2001A46 +:1029B000A46200228FA2001CAC6200243C048008A8 +:1029C000348300808C6200388FA20020012088218F +:1029D000AC62003C8FA20020AC82000093A20018E1 +:1029E000A062004C93A20018A0820009A0600068B9 +:1029F00093A20018105100512407FF803229007F54 +:102A0000000911C024420240024210213046007FDA +:102A10003C03800000471024AC6200943C02800616 +:102A200000C2302190C2003CAFA60040000020212F +:102A300000471025A0C2003C8FA80040950200026C +:102A4000950300148D07001C3042FFFF3063FFFF29 +:102A50008D060018004310230002110000E2382107 +:102A600000E2102B00C4302100C23021AD07001C51 +:102A7000AD06001895020002A5020014A50000167C +:102A80008D020008AD0200108D020008AD02000C9E +:102A900095020002A5020020A50000228D02000878 +:102AA000AD0200249102003C304200401040001A68 +:102AB000262200013C108008A3A90038A38000183A +:102AC000361001008E0200E08D03003427A4004080 +:102AD00027A50038004310210E0007C3AE0200E016 +:102AE00093A200383C038000A20200D58C620278D9 +:102AF0000440FFFE8F82001CAC62024024020002F0 +:102B0000A06202443C021000AC6202780E00093957 +:102B100000000000262200013043007F14730004EF +:102B2000004020212403FF8002231024004320269C +:102B300093A200180A000A4B309100FF93A40018DA +:102B40008FA3001C2402FFFF1062000A308900FFDF +:102B500024820001248300013042007F14530005C9 +:102B6000306900FF2403FF800083102400431026F7 +:102B7000304900FF3C028008904200080120882173 +:102B8000305000FF123000193222007F000211C0C5 +:102B900002421021244202402403FF8000431824F3 +:102BA0003C048000AC8300943042007F3C038006EC +:102BB000004310218C43000C004020211060000BCA +:102BC000AFA200400E00057E000000002623000199 +:102BD0002405FF803062007F145300020225202468 +:102BE000008518260A000AAF307100FF3C048008F7 +:102BF000348400808C8300183C027FFF3442FFFF46 +:102C000000621824AC8300183C0380008C6201F839 +:102C10000440FFFE00000000AC7201C0240200026C +:102C2000A06201C43C021000AC6201F80A000B0E65 +:102C30008FBF00583C04800890C300019082000BB5 +:102C40001443002F8FBF0058349000809202000878 +:102C500030420040104000200000000092020008B6 +:102C60000002160000021603044100050240202164 +:102C70000E000ECC240500930A000B0E8FBF0058E7 +:102C80009202000924030018304200FF1443000D93 +:102C900002402021240500390E000E64000030217E +:102CA0000E0003328F84001C8F82FF9424030012D5 +:102CB000A04300090E00033D8F84001C0A000B0E88 +:102CC0008FBF0058240500360E000E64000030212E +:102CD0000A000B0E8FBF00580E0003320240202165 +:102CE000920200058F84001C344200200E00033D38 +:102CF000A20200050E0010758F84001C8FBF0058C3 +:102D00008FB300548FB200508FB1004C8FB0004889 +:102D100003E0000827BD00603C0280083445010044 +:102D20003C0280008C42014094A3000E0000302140 +:102D300000402021AF82001C3063FFFF3402FFFF00 +:102D4000106200063C0760202402FFFFA4A2000ED0 +:102D500094A500EA0A00090130A5FFFF03E000087E +:102D60000000000027BDFFC83C0280003C06800830 +:102D7000AFB5002CAFB1001CAFBF0030AFB400281E +:102D8000AFB30024AFB20020AFB00018345101003F +:102D900034C501008C4301008E2200148CA400E491 +:102DA0000000A821AF83001C0044102318400052EB +:102DB000A38000188E22001400005021ACA200E471 +:102DC00090C3000890A200D53073007FA3A200102A +:102DD0008CB200E08CB400E4304200FF1053003BA2 +:102DE00093A200108F83001C2407FF80000211C0F3 +:102DF0000062102124420240246300400047102456 +:102E00003063007F3C0980003C08800A006818217C +:102E1000AD2200248C62003427A4001427A50010E2 +:102E2000024280210290102304400028AFA3001426 +:102E30009062003C00E21024304200FF1440001970 +:102E4000020090219062003C34420040A062003CAD +:102E50008F86001C93A3001024C200403042007FE4 +:102E6000004828213C0208008C4200F42463000141 +:102E7000306400FF14820002A3A30010A3A000107E +:102E800093A20010AFA50014000211C0244202401A +:102E900000C2102100471024AD2200240A000B4577 +:102EA00093A200100E0007C3000000003C0280083F +:102EB00034420100AC5000E093A30010240A00014A +:102EC000A04300D50A000B4593A200102402000184 +:102ED000154200093C0380008C6202780440FFFE2A +:102EE0008F82001CAC62024024020002A0620244F5 +:102EF0003C021000AC6202789222000B2403000214 +:102F0000304200FF144300720000000096220008C7 +:102F1000304300FF24020082146200402402008437 +:102F20003C028000344901008D22000C95230006EC +:102F3000000216023063FFFF3045003F24020027E5 +:102F400010A2000FAF83001428A200281040000830 +:102F5000240200312402002110A2000924020025CD +:102F600010A20007938200190A000BBD00000000A8 +:102F700010A20007938200190A000BBD0000000098 +:102F80000E000777012020210A000C3D0000000000 +:102F90003C0380008C6202780440FFFE8F82001C9C +:102FA000AC62024024020002A06202443C02100013 +:102FB000AC6202780A000C3D000000009523000678 +:102FC000912400058D25000C8D2600108D270018FA +:102FD0008D28001C8D290020244200013C0108009E +:102FE000A42356C63C010800A02456C53C01080095 +:102FF000AC2556CC3C010800AC2656D03C0108005C +:10300000AC2756D83C010800AC2856DC3C0108002F +:10301000AC2956E00A000C3DA38200191462000A94 +:10302000240200813C02800834420100944500EAF9 +:10303000922600058F84001C30A5FFFF30C600FFDC +:103040000A000BFE3C0760211462005C00000000D7 +:103050009222000A304300FF306200201040000737 +:10306000306200403C02800834420100944500EA8E +:103070008F84001C0A000BFC24060040104000074F +:10308000000316003C02800834420100944500EA27 +:103090008F84001C0A000BFC24060041000216036A +:1030A000044100463C02800834420100944500EA95 +:1030B0008F84001C2406004230A5FFFF3C076019E6 +:1030C0000E000901000000000A000C3D0000000095 +:1030D0009222000B24040016304200FF1044000628 +:1030E0003C0680009222000B24030017304200FFB0 +:1030F000144300320000000034C5010090A2000B10 +:10310000304200FF1444000B000080218CA20020FC +:103110008CA400202403FF800043102400021140EF +:103120003084007F004410253C032000004310251C +:10313000ACC2083094A2000800021400000214037C +:10314000044200012410000194A2000830420080D3 +:103150005040001A0200A82194A20008304220002A +:10316000504000160200A8218CA300183C021C2D20 +:10317000344219ED106200110200A8213C0208003F +:103180008C4200D4104000053C0280082403000457 +:1031900034420100A04300FC3C028008344201009C +:1031A000944500EA8F84001C2406000630A5FFFF2A +:1031B0000E0009013C0760210200A8210E00093918 +:1031C000000000009222000A304200081040000473 +:1031D00002A010210E0013790000000002A01021AF +:1031E0008FBF00308FB5002C8FB400288FB3002420 +:1031F0008FB200208FB1001C8FB0001803E00008D0 +:1032000027BD00382402FF80008220243C02900069 +:1032100034420007008220253C028000AC4400209C +:103220003C0380008C6200200440FFFE0000000090 +:1032300003E00008000000003C0380002402FF803F +:10324000008220243462000700822025AC64002024 +:103250008C6200200440FFFE0000000003E0000834 +:103260000000000027BDFFD8AFB3001CAFB10014B1 +:10327000AFB00010AFBF0020AFB200183C1180000B +:103280003C0280088E32002034530100AE2400201E +:10329000966300EA000514003C074000004738250B +:1032A00000A08021000030210E0009013065FFFFE1 +:1032B000240200A1160200022402FFFFA2620009FC +:1032C000AE3200208FBF00208FB3001C8FB20018D9 +:1032D0008FB100148FB0001003E0000827BD002854 +:1032E0003C0280082403000527BDFFE834420100AA +:1032F000A04300FCAFBF00103C0280008C420100E4 +:10330000240500A1004020210E000C67AF82001CA4 +:103310003C0380008C6202780440FFFE8F82001C18 +:103320008FBF001027BD0018AC62024024020002CB +:10333000A06202443C021000AC62027803E0000884 +:103340000000000027BDFFE83C068000AFBF001072 +:1033500034C7010094E20008304400FF3883008243 +:10336000388200842C6300012C4200010062182581 +:103370001060002D24020083938200195040003B0E +:103380008FBF00103C020800904256CC8CC4010054 +:103390003C06080094C656C63045003F38A30032AC +:1033A00038A2003F2C6300012C4200010062182566 +:1033B000AF84001CAF860014A380001914600007BE +:1033C00000E020212402002014A2001200000000CE +:1033D0003402FFFF14C2000F00000000240200208E +:1033E00014A2000500E028218CE300142402FFFF52 +:1033F0005062000B8FBF00103C040800248456C0AC +:10340000000030210E000706240700010A000CD638 +:103410008FBF00100E000777000000008FBF001064 +:103420000A00093927BD001814820004240200850F +:103430008CC501040A000CE1000020211482000662 +:103440002482FF808CC50104240440008FBF00103B +:103450000A00016727BD0018304200FF2C4200021D +:1034600010400004240200228FBF00100A000B2726 +:1034700027BD0018148200048F8200248FBF001023 +:103480000A000C8627BD00188C42000C1040001E5C +:1034900000E0282190E300092402001814620003D0 +:1034A000240200160A000CFC240300081462000722 +:1034B00024020017240300123C02800834420080DA +:1034C000A04300090A000D0994A7000854620007F0 +:1034D00094A700088F82FF942404FFFE9043000508 +:1034E00000641824A043000594A7000890A6001BC0 +:1034F0008CA4000094A500068FBF001000073C00BC +:103500000A0008DC27BD00188FBF001003E0000888 +:1035100027BD00188F8500243C04800094A2002A57 +:103520008CA30034000230C02402FFF000C210243B +:1035300000621821AC83003C8CA200303C03800068 +:10354000AC8200383C02005034420010AC620030C3 +:103550000000000000000000000000008C6200007D +:10356000304200201040FFFD30C20008104000062D +:103570003C0280008C620408ACA200208C62040C27 +:103580000A000D34ACA200248C430400ACA300203C +:103590008C420404ACA200243C0300203C028000C6 +:1035A000AC4300303C0480008C8200300043102487 +:1035B0001440FFFD8F8600243C020040AC820030A6 +:1035C00094C3002A94C2002894C4002C94C5002EF1 +:1035D00024630001004410213064FFFFA4C20028CE +:1035E00014850002A4C3002AA4C0002A03E0000836 +:1035F000000000008F84002427BDFFE83C05800404 +:1036000024840010AFBF00100E000E472406000AED +:103610008F840024948200129483002E3042000F85 +:10362000244200030043180424027FFF0043102BB0 +:1036300010400002AC8300000000000D0E000D13CE +:10364000000000008F8300248FBF001027BD0018EA +:10365000946200149463001A3042000F00021500B7 +:10366000006218253C02800003E00008AC4300A083 +:103670008F8300243C028004944400069462001A64 +:103680008C650000A4640016004410233042FFFF44 +:103690000045102B03E00008384200018F8400240D +:1036A0003C0780049486001A8C85000094E2000692 +:1036B000A482001694E3000600C310233042FFFFEB +:1036C0000045102B384200011440FFF8A483001677 +:1036D00003E00008000000008F8400243C02800406 +:1036E000944200069483001A8C850000A482001680 +:1036F000006210233042FFFF0045102B38420001CA +:103700005040000D8F850024006030213C0780046C +:1037100094E20006A482001694E3000600C310237E +:103720003042FFFF0045102B384200011440FFF8E3 +:10373000A48300168F8500243C03800034620400BB +:103740008CA40020AF820020AC6400388CA200243E +:10375000AC62003C3C020005AC62003003E00008B3 +:10376000ACA000048F8400243C0300068C8200047B +:1037700000021140004310253C038000AC62003081 +:103780000000000000000000000000008C6200004B +:10379000304200101040FFFD34620400AC80000491 +:1037A00003E00008AF8200208F86002427BDFFE0E1 +:1037B000AFB10014AFB00010AFBF00188CC300044D +:1037C0008CC500248F820020309000FF94C4001A22 +:1037D00024630001244200202484000124A7002047 +:1037E000ACC30004AF820020A4C4001AACC70024FC +:1037F00004A100060000882104E2000594C2001A1A +:103800008CC2002024420001ACC2002094C2001AE5 +:1038100094C300282E040001004310262C4200010E +:10382000004410245040000594C2001A24020001F4 +:10383000ACC2000894C2001A94C300280010202BC8 +:10384000004310262C4200010044102514400007BC +:10385000000000008CC20008144000042402001084 +:103860008CC300041462000F8F8500240E000DA786 +:10387000241100018F820024944300289442001AEE +:1038800014430003000000000E000D1300000000B0 +:10389000160000048F8500240E000D840000000037 +:1038A0008F85002494A2001E94A4001C24420001D1 +:1038B0003043FFFF14640002A4A2001EA4A0001E57 +:1038C0001200000A3C02800494A2001494A3001A7F +:1038D0003042000F00021500006218253C028000F3 +:1038E000AC4300A00A000E1EACA0000894420006E3 +:1038F00094A3001A8CA40000A4A200160062102356 +:103900003042FFFF0044102B384200011040000DF0 +:1039100002201021006030213C07800494E2000660 +:10392000A4A2001694E3000600C310233042FFFF58 +:103930000044102B384200011440FFF8A4A30016E5 +:10394000022010218FBF00188FB100148FB000101B +:1039500003E0000827BD002003E00008000000008D +:103960008F82002C3C03000600021140004310250A +:103970003C038000AC62003000000000000000004A +:10398000000000008C620000304200101040FFFD7B +:1039900034620400AF82002803E00008AF80002CEE +:1039A00003E000080000102103E000080000000010 +:1039B0003084FFFF30A5FFFF0000182110800007B2 +:1039C000000000003082000110400002000420428C +:1039D000006518210A000E3D0005284003E000089C +:1039E0000060102110C0000624C6FFFF8CA200005A +:1039F00024A50004AC8200000A000E4724840004C1 +:103A000003E000080000000010A0000824A3FFFF4E +:103A1000AC86000000000000000000002402FFFF50 +:103A20002463FFFF1462FFFA2484000403E000080B +:103A3000000000003C0280083442008024030001A2 +:103A4000AC43000CA4430010A4430012A443001490 +:103A500003E00008A44300168F82002427BDFFD88E +:103A6000AFB3001CAFB20018AFB10014AFB000107C +:103A7000AFBF00208C47000C248200802409FF8007 +:103A80003C08800E3043007F008080213C0A80008B +:103A9000004920240068182130B100FF30D200FF17 +:103AA00010E000290000982126020100AD44002CFE +:103AB000004928243042007F004820219062000005 +:103AC00024030050304200FF1443000400000000B3 +:103AD000AD45002C948200EA3053FFFF0E000D84A8 +:103AE000000000008F8200248F83002000112C0032 +:103AF0009442001E001224003484000100A22825F4 +:103B00003C02400000A22825AC7000008FBF0020BE +:103B1000AC6000048FB20018AC7300088FB10014C1 +:103B2000AC60000C8FB3001CAC6400108FB00010B0 +:103B3000AC60001424040001AC60001827BD00280C +:103B40000A000DB8AC65001C8FBF00208FB3001CAD +:103B50008FB200188FB100148FB0001003E000087E +:103B600027BD00283C06800034C201009043000FAE +:103B7000240200101062000E2865001110A000073A +:103B800024020012240200082405003A10620006F4 +:103B90000000302103E0000800000000240500358B +:103BA0001462FFFC000030210A000E6400000000D7 +:103BB0008CC200748F83FF9424420FA003E000089E +:103BC000AC62000C27BDFFE8AFBF00100E0003423F +:103BD000240500013C0480088FBF0010240200016E +:103BE00034830080A462001227BD00182402000163 +:103BF00003E00008A080001A27BDFFE0AFB2001864 +:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 +:103C10000E000332008088213C028008345000806E +:103C20009202000924030004304200FF1443000CF8 +:103C30003C028008124000082402000A0E000E5BBD +:103C400000000000920200052403FFFE0043102440 +:103C5000A202000524020012A20200093C02800810 +:103C600034420080022020210E00033DA0400027A6 +:103C700016400003022020210E000EBF00000000AD +:103C800002202021324600FF8FBF001C8FB2001897 +:103C90008FB100148FB00010240500380A000E64A4 +:103CA00027BD002027BDFFE0AFBF001CAFB200184A +:103CB000AFB10014AFB000100E00033200808021BD +:103CC0000E000E5B000000003C02800834450080BE +:103CD00090A2000924120018305100FF1232000394 +:103CE0000200202124020012A0A2000990A20005D7 +:103CF0002403FFFE004310240E00033DA0A2000594 +:103D00000200202124050020163200070000302187 +:103D10008FBF001C8FB200188FB100148FB000103D +:103D20000A00034227BD00208FBF001C8FB200187D +:103D30008FB100148FB00010240500390A000E6402 +:103D400027BD002027BDFFE83C028000AFB0001077 +:103D5000AFBF0014344201009442000C2405003629 +:103D60000080802114400012304600FF0E00033214 +:103D7000000000003C02800834420080240300124E +:103D8000A043000990430005346300100E000E5B51 +:103D9000A04300050E00033D020020210200202167 +:103DA0000E000342240500200A000F3C0000000022 +:103DB0000E000E64000000000E00033202002021FD +:103DC0003C0280089043001B2405FF9F0200202135 +:103DD000006518248FBF00148FB00010A043001B93 +:103DE0000A00033D27BD001827BDFFE0AFBF001844 +:103DF000AFB10014AFB0001030B100FF0E000332BD +:103E0000008080213C02800824030012344200809C +:103E10000E000E5BA04300090E00033D02002021AE +:103E200002002021022030218FBF00188FB1001422 +:103E30008FB00010240500350A000E6427BD002055 +:103E40003C0480089083000E9082000A1443000B0B +:103E5000000028218F82FF942403005024050001D4 +:103E600090420000304200FF1443000400000000B4 +:103E70009082000E24420001A082000E03E00008A0 +:103E800000A010213C0380008C6201F80440FFFE7A +:103E900024020002AC6401C0A06201C43C02100014 +:103EA00003E00008AC6201F827BDFFE0AFB20018E4 +:103EB0003C128008AFB10014AFBF001CAFB00010BF +:103EC00036510080922200092403000A304200FF8C +:103ED0001443003E000000008E4300048E22003890 +:103EE000506200808FBF001C92220000240300500B +:103EF000304200FF144300253C0280008C42014008 +:103F00008E4300043642010002202821AC43001CED +:103F10009622005C8E2300383042FFFF00021040E2 +:103F200000621821AE23001C8E4300048E2400384A +:103F30009622005C006418233042FFFF0003184300 +:103F4000000210400043102A10400006000000004C +:103F50008E4200048E230038004310230A000FAA6B +:103F6000000220439622005C3042FFFF0002204006 +:103F70003C0280083443010034420080ACA4002C91 +:103F8000A040002424020001A062000C0E000F5E7D +:103F900000000000104000538FBF001C3C02800056 +:103FA0008C4401403C0380008C6201F80440FFFE19 +:103FB00024020002AC6401C0A06201C43C021000F3 +:103FC000AC6201F80A0010078FBF001C92220009A2 +:103FD00024030010304200FF144300043C02800020 +:103FE0008C4401400A000FEE0000282192220009B3 +:103FF00024030016304200FF14430006240200147C +:10400000A22200093C0280008C4401400A001001F9 +:104010008FBF001C8E2200388E23003C00431023EB +:10402000044100308FBF001C92220027244200016F +:10403000A2220027922200272C42000414400016DE +:104040003C1080009222000924030004304200FF4B +:10405000144300093C0280008C4401408FBF001CC7 +:104060008FB200188FB100148FB000102405009398 +:104070000A000ECC27BD00208C440140240500938B +:104080008FBF001C8FB200188FB100148FB00010CA +:104090000A000F4827BD00208E0401400E000332A5 +:1040A000000000008E4200042442FFFFAE420004E4 +:1040B0008E22003C2442FFFFAE22003C0E00033D56 +:1040C0008E0401408E0401408FBF001C8FB2001887 +:1040D0008FB100148FB00010240500040A000342C1 +:1040E00027BD00208FB200188FB100148FB00010D0 +:1040F00003E0000827BD00203C0680008CC2018838 +:104100003C038008346500809063000E00021402B6 +:10411000304400FF306300FF1464000E3C0280084E +:1041200090A20026304200FF104400098F82FF94C5 +:10413000A0A400262403005090420000304200FF5B +:1041400014430006000000000A0005A18CC4018091 +:104150003C02800834420080A044002603E00008AE +:104160000000000027BDFFE030E700FFAFB20018FD +:10417000AFBF001CAFB10014AFB0001000809021A1 +:1041800014E0000630C600FF000000000000000D33 +:10419000000000000A001060240001163C038008A3 +:1041A0009062000E304200FF14460023346200800B +:1041B00090420026304200FF1446001F000000001D +:1041C0009062000F304200FF1446001B0000000008 +:1041D0009062000A304200FF144600038F90FF9463 +:1041E0000000000D8F90FF948F82FF983C1180009B +:1041F000AE05003CAC450000A066000A0E0003328C +:104200008E240100A20000240E00033D8E24010034 +:104210003C0380008C6201F80440FFFE240200028F +:10422000AC7201C0A06201C43C021000AC6201F893 +:104230000A0010618FBF001C000000000000000D8C +:10424000000000002400013F8FBF001C8FB2001847 +:104250008FB100148FB0001003E0000827BD0020CC +:104260008F83FF943C0280008C44010034420100A3 +:104270008C65003C9046001B0A00102724070001B3 +:104280003C0280089043000E9042000A0043102632 +:10429000304200FF03E000080002102B27BDFFE0C2 +:1042A0003C028008AFB10014AFB00010AFBF0018DF +:1042B0003450008092020005240300303042003068 +:1042C00014430085008088218F8200248C42000CDA +:1042D000104000828FBF00180E000D840000000007 +:1042E0008F860020ACD100009202000892030009E2 +:1042F000304200FF00021200306300FF004310252F +:10430000ACC200049202004D000216000002160327 +:1043100004410005000000003C0308008C630048D5 +:104320000A00109F3C1080089202000830420040B2 +:10433000144000030000182192020027304300FFC0 +:104340003C108008361100809222004D00031E00B0 +:10435000304200FF0002140000621825ACC30008C0 +:104360008E2400308F820024ACC4000C8E250034D3 +:104370009443001E3C02C00BACC50010006218251F +:104380008E22003800002021ACC200148E22003C96 +:10439000ACC200180E000DB8ACC3001C8E020004A5 +:1043A0008F8400203C058000AC8200008E2200201B +:1043B000AC8200048E22001CAC8200088E220058C1 +:1043C0008CA3007400431021AC82000C8E22002CC0 +:1043D000AC8200108E2200408E23004400021400A4 +:1043E00000431025AC8200149222004D240300806B +:1043F000304200FF1443000400000000AC800018AD +:104400000A0010E38F8200248E23000C2402000196 +:104410001062000E2402FFFF92220008304200408A +:104420001440000A2402FFFF8E23000C8CA20074AB +:10443000006218233C0208000062102414400002AD +:10444000000028210060282100051043AC820018DC +:104450008F820024000020219443001E3C02C00CE7 +:10446000006218258F8200200E000DB8AC43001C9E +:104470003C038008346201008C4200008F850020DC +:10448000346300808FBF0018ACA20000ACA0000411 +:104490008C6400488F8200248FB10014ACA4000803 +:1044A000ACA0000CACA00010906300059446001E68 +:1044B0003C02400D00031E0000C23025ACA30014D6 +:1044C0008FB00010ACA0001824040001ACA6001CA2 +:1044D0000A000DB827BD00208FBF00188FB100144F +:1044E0008FB0001003E0000827BD00203C028000D0 +:1044F0009443007C3C02800834460100308400FF75 +:104500003065FFFF2402000524A34650A0C4000C20 +:104510005482000C3065FFFF90C2000D2C42000752 +:104520001040000724A30A0090C3000D24020014C9 +:104530000062100400A210210A00111F3045FFFF85 +:104540003065FFFF3C0280083442008003E0000831 +:10455000A44500143C03800834680080AD05003891 +:10456000346701008CE2001C308400FF00A210239D +:104570001840000330C600FF24A2FFFCACE2001C80 +:1045800030820001504000083C0380088D02003C4E +:1045900000A2102304410012240400058C620004D0 +:1045A00010A2000F3C0380088C62000414A2001EBD +:1045B000000000003C0208008C4200D8304200207D +:1045C000104000093C0280083462008090630008BB +:1045D0009042004C144300043C0280082404000470 +:1045E0000A00110900000000344300803442010039 +:1045F000A040000C24020001A462001410C0000AB4 +:104600003C0280008C4401003C0380008C6201F875 +:104610000440FFFE24020002AC6401C0A06201C499 +:104620003C021000AC6201F803E00008000000004A +:1046300027BDFFE800A61823AFBF00101860008058 +:10464000308800FF3C02800834470080A0E000244E +:1046500034440100A0E000278C82001C00A210233B +:1046600004400056000000008CE2003C94E3005C33 +:104670008CE4002C004530233063FFFF00C3182179 +:104680000083202B1080000400E018218CE2002C15 +:104690000A00117800A2102194E2005C3042FFFF72 +:1046A00000C2102100A21021AC62001C3C02800854 +:1046B000344400809482005C8C83001C3042FFFFF5 +:1046C0000002104000A210210043102B10400004F3 +:1046D000000000008C82001C0A00118B3C06800840 +:1046E0009482005C3042FFFF0002104000A21021C3 +:1046F0003C06800834C3010034C70080AC82001C33 +:10470000A060000CACE500388C62001C00A21023F5 +:104710001840000224A2FFFCAC62001C3102000120 +:10472000104000083C0380088CE2003C00A21023EB +:1047300004410012240400058CC2000410A20010E1 +:104740008FBF00108C62000414A2004F8FBF0010B6 +:104750003C0208008C4200D8304200201040000A81 +:104760003C02800834620080906300089042004C54 +:10477000144300053C028008240400048FBF00108D +:104780000A00110927BD001834430080344201009B +:10479000A040000C24020001A46200143C0280002E +:1047A0008C4401003C0380008C6201F80440FFFE51 +:1047B000240200020A0011D8000000008CE2001C54 +:1047C000004610230043102B54400001ACE5001CB0 +:1047D00094E2005C3042FFFF0062102B144000079F +:1047E0002402000294E2005C8CE3001C3042FFFFD4 +:1047F00000621821ACE3001C24020002ACE5003882 +:104800000E000F5EA082000C1040001F8FBF001032 +:104810003C0280008C4401003C0380008C6201F863 +:104820000440FFFE24020002AC6401C0A06201C487 +:104830003C021000AC6201F80A0011F08FBF0010BA +:1048400031020010104000108FBF00103C028008A1 +:10485000344500808CA3001C94A2005C00661823E1 +:104860003042FFFF006218213C023FFF3444FFFF4B +:104870000083102B544000010080182100C3102138 +:10488000ACA2001C8FBF001003E0000827BD001879 +:1048900027BDFFE800C0402100A63023AFBF0010B5 +:1048A00018C00026308A00FF3C028008344900808E +:1048B0008D24001C8D23002C008820230064182BDD +:1048C0001060000F344701008CE2002000461021E8 +:1048D000ACE200208CE200200044102B1440000BBE +:1048E0003C023FFF8CE2002000441023ACE2002099 +:1048F0009522005C3042FFFF0A0012100082202146 +:10490000ACE00020008620213C023FFF3443FFFF43 +:104910000064102B54400001006020213C028008FC +:104920003442008000851821AC43001CA0400024C4 +:10493000A04000270A0012623C03800831420010A8 +:10494000104000433C0380083C06800834C40080CB +:104950008C82003C004810235840003E34660080A2 +:104960009082002424420001A0820024908200242E +:104970003C0308008C630024304200FF0043102BEE +:10498000144000688FBF001034C201008C42001C2C +:1049900000A2102318400063000000008CC3000434 +:1049A0009482005C006818233042FFFF0003184324 +:1049B000000210400043102A1040000500000000D3 +:1049C0008CC20004004810230A0012450002104364 +:1049D0009482005C3042FFFF000210403C068008D9 +:1049E000AC82002C34C5008094A2005C8CA4002C06 +:1049F00094A3005C3042FFFF00021040008220219F +:104A00003063FFFF0083202101041021ACA2001CB1 +:104A10008CC2000434C60100ACC2001C2402000297 +:104A20000E000F5EA0C2000C1040003E8FBF0010B1 +:104A30003C0280008C4401003C0380008C6201F841 +:104A40000440FFFE240200020A001292000000004F +:104A500034660080ACC50038346401008C82001CD0 +:104A600000A210231840000224A2FFFCAC82001C0C +:104A7000314200015040000A3C0380088CC2003CD7 +:104A800000A2102304430014240400058C620004D7 +:104A900014A200033C0380080A00128424040005C9 +:104AA0008C62000414A2001F8FBF00103C0208009B +:104AB0008C4200D8304200201040000A3C0280089E +:104AC00034620080906300089042004C144300055B +:104AD0003C028008240400048FBF00100A00110962 +:104AE00027BD00183443008034420100A040000C70 +:104AF00024020001A46200143C0280008C440100E6 +:104B00003C0380008C6201F80440FFFE2402000296 +:104B1000AC6401C0A06201C43C021000AC6201F8A8 +:104B20008FBF001003E0000827BD001827BDFFE875 +:104B30003C0A8008AFBF0010354900808D22003C40 +:104B400000C04021308400FF004610231840009D23 +:104B500030E700FF354701002402000100A63023A2 +:104B6000A0E0000CA0E0000DA522001418C0002455 +:104B7000308200108D23001C8D22002C0068182329 +:104B80000043102B1040000F000000008CE20020BA +:104B900000461021ACE200208CE200200043102BE4 +:104BA0001440000B3C023FFF8CE200200043102326 +:104BB000ACE200209522005C3042FFFF0A0012C1E7 +:104BC00000621821ACE00020006618213C023FFF83 +:104BD0003446FFFF00C3102B5440000100C01821D1 +:104BE0003C0280083442008000651821AC43001C60 +:104BF000A0400024A04000270A00130F3C038008B7 +:104C0000104000403C0380088D22003C00481023E7 +:104C10005840003D34670080912200242442000166 +:104C2000A1220024912200243C0308008C6300246C +:104C3000304200FF0043102B1440009A8FBF001039 +:104C40008CE2001C00A21023184000960000000017 +:104C50008D4300049522005C006818233042FFFF5A +:104C600000031843000210400043102A10400005C2 +:104C7000012020218D420004004810230A0012F276 +:104C8000000210439522005C3042FFFF00021040FA +:104C90003C068008AC82002C34C5008094A2005CE5 +:104CA0008CA4002C94A3005C3042FFFF0002104053 +:104CB000008220213063FFFF0083182101031021AF +:104CC000ACA2001C8CC2000434C60100ACC2001CA3 +:104CD000240200020E000F5EA0C2000C1040007102 +:104CE0008FBF00103C0280008C4401003C03800018 +:104CF0008C6201F80440FFFE240200020A0013390E +:104D00000000000034670080ACE500383466010024 +:104D10008CC2001C00A210231840000224A2FFFC39 +:104D2000ACC2001C30820001504000083C038008E7 +:104D30008CE2003C00A2102304430051240400052F +:104D40008C62000410A2003E3C0380088C620004C8 +:104D500054A200548FBF00103C0208008C4200D8BF +:104D600030420020104000063C028008346200807F +:104D7000906300089042004C104300403C028008C1 +:104D80003443008034420100A040000C24020001A2 +:104D9000A46200143C0280008C4401003C038000AB +:104DA0008C6201F80440FFFE24020002AC6401C0E2 +:104DB000A06201C43C021000AC6201F80A00137743 +:104DC0008FBF001024020005A120002714E2000A72 +:104DD0003C038008354301009062000D2C42000620 +:104DE000504000053C0380089062000D2442000101 +:104DF000A062000D3C03800834670080ACE50038F9 +:104E0000346601008CC2001C00A21023184000026E +:104E100024A2FFFCACC2001C308200015040000AFA +:104E20003C0380088CE2003C00A2102304410014E3 +:104E3000240400058C62000414A200033C038008D3 +:104E40000A00136E240400058C62000414A20015ED +:104E50008FBF00103C0208008C4200D83042002076 +:104E60001040000A3C028008346200809063000811 +:104E70009042004C144300053C02800824040004C6 +:104E80008FBF00100A00110927BD001834430080AD +:104E900034420100A040000C24020001A46200146E +:104EA0008FBF001003E0000827BD00183C0B8008EE +:104EB00027BDFFE83C028000AFBF00103442010074 +:104EC000356A00809044000A356901008C45001461 +:104ED0008D4800389123000C308400FF0105102319 +:104EE0001C4000B3306700FF2CE20006504000B1C8 +:104EF0008FBF00102402000100E2300430C2000322 +:104F00005440000800A8302330C2000C144000A117 +:104F100030C20030144000A38FBF00100A00143BC1 +:104F20000000000018C00024308200108D43001CD7 +:104F30008D42002C006818230043102B1040000FF6 +:104F4000000000008D22002000461021AD2200202C +:104F50008D2200200043102B1440000B3C023FFF29 +:104F60008D22002000431023AD2200209542005CDA +:104F70003042FFFF0A0013AF00621821AD2000206D +:104F8000006618213C023FFF3446FFFF00C3102B90 +:104F90005440000100C018213C02800834420080C7 +:104FA00000651821AC43001CA0400024A04000274D +:104FB0000A0013FD3C038008104000403C038008B9 +:104FC0008D42003C004810231840003D34670080AB +:104FD0009142002424420001A14200249142002475 +:104FE0003C0308008C630024304200FF0043102B78 +:104FF000144000708FBF00108D22001C00A21023EF +:105000001840006C000000008D6300049542005CB5 +:10501000006818233042FFFF0003184300021040CD +:105020000043102A10400005014020218D62000439 +:10503000004810230A0013E0000210439542005C70 +:105040003042FFFF000210403C068008AC82002C7A +:1050500034C5008094A2005C8CA4002C94A3005C56 +:105060003042FFFF00021040008220213063FFFF2A +:105070000083182101031021ACA2001C8CC2000483 +:1050800034C60100ACC2001C240200020E000F5EF8 +:10509000A0C2000C104000478FBF00103C028000EF +:1050A0008C4401003C0380008C6201F80440FFFE48 +:1050B000240200020A00142D000000003467008062 +:1050C000ACE50038346601008CC2001C00A210233D +:1050D0001840000224A2FFFCACC2001C3082000178 +:1050E0005040000A3C0380088CE2003C00A21023E0 +:1050F00004430014240400058C62000414A200037D +:105100003C0380080A00141F240400058C6200047C +:1051100014A200288FBF00103C0208008C4200D867 +:10512000304200201040000A3C02800834620080B7 +:10513000906300089042004C144300053C02800834 +:10514000240400048FBF00100A00110927BD0018B5 +:105150003443008034420100A040000C24020001CE +:10516000A46200143C0280008C4401003C038000D7 +:105170008C6201F80440FFFE24020002AC6401C00E +:10518000A06201C43C021000AC6201F80A00143BAA +:105190008FBF00108FBF0010010030210A00115A8C +:1051A00027BD0018010030210A00129927BD001800 +:1051B0008FBF001003E0000827BD00183C038008E3 +:1051C0003464010024020003A082000C8C620004FD +:1051D00003E00008AC82001C3C05800834A300807A +:1051E0009062002734A501002406004324420001F8 +:1051F000A0620027906300273C0208008C42004810 +:10520000306300FF146200043C07602194A500EAAB +:105210000A00090130A5FFFF03E0000800000000BC +:1052200027BDFFE8AFBF00103C0280000E00144411 +:105230008C4401803C02800834430100A060000CD3 +:105240008C4200048FBF001027BD001803E0000847 +:10525000AC62001C27BDFFE03C028008AFBF001815 +:10526000AFB10014AFB000103445008034460100E7 +:105270003C0880008D09014090C3000C8CA4003CC8 +:105280008CA200381482003B306700FF9502007C3E +:1052900090A30027146000093045FFFF2402000599 +:1052A00054E200083C04800890C2000D2442000132 +:1052B000A0C2000D0A00147F3C048008A0C0000DAD +:1052C0003C048008348201009042000C2403000555 +:1052D000304200FF1443000A24A205DC348300801E +:1052E000906200272C4200075040000524A20A00CB +:1052F00090630027240200140062100400A2102111 +:105300003C108008361000803045FFFF012020212E +:105310000E001444A60500149602005C8E030038AB +:105320003C1180003042FFFF000210400062182153 +:10533000AE03001C0E0003328E24014092020025B1 +:1053400034420040A20200250E00033D8E2401409D +:105350008E2401403C0380008C6201F80440FFFE73 +:1053600024020002AC6401C0A06201C43C0210002F +:10537000AC6201F88FBF00188FB100148FB000101D +:1053800003E0000827BD00203C0360103C02080039 +:1053900024420174AC62502C8C6250003C048000AA +:1053A00034420080AC6250003C0208002442547C2D +:1053B0003C010800AC2256003C020800244254384C +:1053C0003C010800AC2256043C020002AC840008F8 +:1053D000AC82000C03E000082402000100A0302190 +:1053E0003C1C0800279C56083C0200023C050400B7 +:1053F00000852826008220260004102B2CA5000101 +:105400002C840001000210803C0308002463560035 +:105410000085202500431821108000030000102182 +:10542000AC6600002402000103E000080000000058 +:105430003C1C0800279C56083C0200023C05040066 +:1054400000852826008220260004102B2CA50001B0 +:105450002C840001000210803C03080024635600E5 +:105460000085202500431821108000050000102130 +:105470003C02080024425438AC62000024020001BF +:1054800003E00008000000003C0200023C030400AE +:1054900000821026008318262C4200012C63000194 +:1054A000004310251040000B000028213C1C080080 +:1054B000279C56083C0380008C62000824050001EC +:1054C00000431025AC6200088C62000C00441025DB +:1054D000AC62000C03E0000800A010213C1C080096 +:1054E000279C56083C0580008CA3000C0004202754 +:1054F000240200010064182403E00008ACA3000C9F +:105500003C020002148200063C0560008CA208D018 +:105510002403FFFE0043102403E00008ACA208D0DF +:105520003C02040014820005000000008CA208D098 +:105530002403FFFD00431024ACA208D003E00008C0 +:10554000000000003C02601A344200108C430080CE +:1055500027BDFFF88C440084AFA3000093A3000094 +:10556000240200041462001AAFA4000493A20001F4 +:105570001040000797A300023062FFFC3C0380004C +:10558000004310218C4200000A001536AFA200042F +:105590003062FFFC3C03800000431021AC4400005B +:1055A000A3A000003C0560008CA208D02403FFFEED +:1055B0003C04601A00431024ACA208D08FA300045E +:1055C0008FA2000034840010AC830084AC82008081 +:1055D00003E0000827BD000827BDFFE8AFBF0010AB +:1055E0003C1C0800279C56083C0280008C43000CA1 +:1055F0008C420004004318243C0200021060001496 +:10560000006228243C0204003C04000210A00005B3 +:10561000006210243C0208008C4256000A00155B10 +:1056200000000000104000073C0404003C02080099 +:105630008C4256040040F809000000000A00156082 +:10564000000000000000000D3C1C0800279C5608CC +:0C5650008FBF001003E0000827BD001809 +:04565C008008024080 +:1056600080080100800800808008000000000C8095 +:105670000000320008000E9808000EF408000F88A1 +:1056800008001028080010748008010080080080BD +:04569000800800008E +:0C5694000A0000280000000000000000D8 +:1056A0000000000D6370362E322E31000000000025 +:1056B00006020104000000000000000000000000DD +:1056C000000000000000000038003C000000000066 +:1056D00000000000000000000000000000000020AA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:10570000000000000000000021003800000000013F +:105710000000002B000000000000000400030D400A +:105720000000000000000000000000000000000079 +:105730000000000000000000100000030000000056 +:105740000000000D0000000D3C020800244259AC8E +:105750003C03080024635BF4AC4000000043202BB2 +:105760001480FFFD244200043C1D080037BD9FFC4F +:1057700003A0F0213C100800261000A03C1C0800EB +:10578000279C59AC0E0002F6000000000000000D3E +:1057900027BDFFB4AFA10000AFA20004AFA3000873 +:1057A000AFA4000CAFA50010AFA60014AFA700185F +:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF +:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F +:1057D000AFB8003CAFB90040AFBC0044AFBF004819 +:1057E0000E000820000000008FBF00488FBC00445E +:1057F0008FB900408FB8003C8FAF00388FAE0034B7 +:105800008FAD00308FAC002C8FAB00288FAA002406 +:105810008FA900208FA8001C8FA700188FA6001446 +:105820008FA500108FA4000C8FA300088FA2000486 +:105830008FA1000027BD004C3C1B60188F7A5030B0 +:10584000377B502803400008AF7A000000A01821E1 +:1058500000801021008028213C0460003C0760008B +:105860002406000810600006348420788C42000072 +:10587000ACE220088C63000003E00008ACE3200CDD +:105880000A000F8100000000240300403C02600079 +:1058900003E00008AC4320003C0760008F86000452 +:1058A0008CE520740086102100A2182B14600007DC +:1058B000000028218F8AFDA024050001A1440013C7 +:1058C0008F89000401244021AF88000403E0000810 +:1058D00000A010218F84FDA08F8500049086001306 +:1058E00030C300FF00A31023AF82000403E00008D0 +:1058F000A08000138F84FDA027BDFFE8AFB000108B +:10590000AFBF001490890011908700112402002875 +:10591000312800FF3906002830E300FF2485002CE1 +:105920002CD00001106200162484001C0E00006EB2 +:10593000000000008F8FFDA03C05600024020204DF +:1059400095EE003E95ED003C000E5C0031ACFFFF93 +:10595000016C5025ACAA2010520000012402000462 +:10596000ACA22000000000000000000000000000C9 +:105970008FBF00148FB0001003E0000827BD00188F +:105980000A0000A6000028218F85FDA027BDFFD8B2 +:10599000AFBF0020AFB3001CAFB20018AFB100140E +:1059A000AFB000100080982190A4001124B0001C1A +:1059B00024B1002C308300FF386200280E000090D4 +:1059C0002C5200010E00009800000000020020216F +:1059D0001240000202202821000028210E00006E43 +:1059E000000000008F8DFDA03C0880003C05600099 +:1059F00095AC003E95AB003C02683025000C4C0095 +:105A0000316AFFFF012A3825ACA7201024020202C8 +:105A1000ACA6201452400001240200028FBF0020D7 +:105A20008FB3001C8FB200188FB100148FB000101C +:105A300027BD002803E00008ACA2200027BDFFE03E +:105A4000AFB20018AFB10014AFB00010AFBF001C70 +:105A50003C1160008E2320748F82000430D0FFFF41 +:105A600030F2FFFF1062000C2406008F0E00006E63 +:105A7000000000003C06801F0010440034C5FF00F9 +:105A80000112382524040002AE2720100000302126 +:105A9000AE252014AE2420008FBF001C8FB200184A +:105AA0008FB100148FB0001000C0102103E0000877 +:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 +:105AC000AFBF0018AFB100140E00006E30F1FFFF41 +:105AD00000102400009180253C036000AC70201071 +:105AE0008FBF00188FB100148FB000102402000483 +:105AF000AC62200027BD002003E000080000102158 +:105B000027BDFFE03C046018AFBF0018AFB1001420 +:105B1000AFB000108C8850002403FF7F34028071E6 +:105B20000103382434E5380C241F00313C1980006F +:105B3000AC8550003C11800AAC8253BCAF3F0008DA +:105B40000E00054CAF9100400E00050A3C116000AC +:105B50000E00007D000000008E3008083C0F570941 +:105B60002418FFF00218602435EEE00035EDF00057 +:105B7000018E5026018D58262D4600012D69000109 +:105B8000AF86004C0E000D09AF8900503C06601630 +:105B90008CC700003C0860148D0500A03C03FFFF8B +:105BA00000E320243C02535300052FC2108200550D +:105BB00034D07C00960201F2A780006C10400003F4 +:105BC000A780007C384B1E1EA78B006C960201F844 +:105BD000104000048F8D0050384C1E1EA78C007C96 +:105BE0008F8D005011A000058F83004C240E0020E3 +:105BF000A78E007CA78E006C8F83004C1060000580 +:105C00009785007C240F0020A78F007CA78F006C55 +:105C10009785007C2CB8008153000001240500808A +:105C20009784006C2C91040152200001240404008C +:105C30001060000B3C0260008FBF00188FB1001491 +:105C40008FB0001027BD0020A784006CA785007CC2 +:105C5000A380007EA780007403E00008A780009264 +:105C60008C4704382419103C30FFFFFF13F9000360 +:105C700030A8FFFF1100004624030050A380007EDF +:105C80009386007E50C00024A785007CA780007CFE +:105C90009798007CA780006CA7800074A780009272 +:105CA0003C010800AC3800800E00078700000000AF +:105CB0003C0F60008DED0808240EFFF03C0B600ED9 +:105CC000260C0388356A00100000482100002821B6 +:105CD00001AE20243C105709AF8C0010AF8A004859 +:105CE000AF89001810900023AF8500148FBF0018F3 +:105CF0008FB100148FB0001027BD002003E0000812 +:105D0000AF80005400055080014648218D260004D4 +:105D10000A00014800D180219798007CA784006C7C +:105D2000A7800074A78000923C010800AC38008076 +:105D30000E000787000000003C0F60008DED080892 +:105D4000240EFFF03C0B600E260C0388356A001011 +:105D5000000048210000282101AE20243C105709F2 +:105D6000AF8C0010AF8A0048AF8900181490FFDF95 +:105D7000AF85001424110001AF9100548FBF0018AB +:105D80008FB100148FB0001003E0000827BD002081 +:105D90000A00017BA383007E3083FFFF8F880040D1 +:105DA0008F87003C000321403C0580003C020050EE +:105DB000008248253C0660003C0A010034AC040027 +:105DC0008CCD08E001AA58241160000500000000F5 +:105DD0008CCF08E024E7000101EA7025ACCE08E092 +:105DE0008D19001001805821ACB900388D180014AD +:105DF000ACB8003CACA9003000000000000000007E +:105E00000000000000000000000000000000000092 +:105E100000000000000000003C0380008C640000D3 +:105E2000308200201040FFFD3C0F60008DED08E047 +:105E30003C0E010001AE18241460FFE100000000D8 +:105E4000AF87003C03E00008AF8B00588F8500400F +:105E5000240BFFF03C06800094A7001A8CA90024B4 +:105E600030ECFFFF000C38C000EB5024012A402129 +:105E7000ACC8003C8CA400248CC3003C00831023DD +:105E800018400033000000008CAD002025A2000166 +:105E90003C0F0050ACC2003835EE00103C068000CC +:105EA000ACCE003000000000000000000000000048 +:105EB00000000000000000000000000000000000E2 +:105EC000000000003C0480008C9900003338002062 +:105ED0001300FFFD30E20008104000173C0980006D +:105EE0008C880408ACA800108C83040CACA30014AC +:105EF0003C1900203C188000AF19003094AE001807 +:105F000094AF001C01CF3021A4A6001894AD001A54 +:105F100025A70001A4A7001A94AB001A94AC001E98 +:105F2000118B00030000000003E0000800000000E7 +:105F300003E00008A4A0001A8D2A0400ACAA0010F7 +:105F40008D240404ACA400140A0002183C1900209B +:105F50008CA200200A0002003C0F00500A0001EE53 +:105F60000000000027BDFFE8AFBF00100E000232A6 +:105F7000000000008F8900408FBF00103C038000AC +:105F8000A520000A9528000A9527000427BD0018BF +:105F90003105FFFF30E6000F0006150000A22025A6 +:105FA00003E00008AC6400803C0508008CA50020DC +:105FB0008F83000C27BDFFE8AFB00010AFBF001407 +:105FC00010A300100000802124040001020430040A +:105FD00000A6202400C3102450440006261000010F +:105FE000001018802787FDA41480000A006718217C +:105FF000261000012E0900025520FFF38F83000CAC +:10600000AF85000C8FBF00148FB0001003E00008B4 +:1060100027BD00188C6800003C058000ACA8002457 +:106020000E000234261000013C0508008CA500205B +:106030000A0002592E0900022405000100851804F7 +:106040003C0408008C84002027BDFFC8AFBF00348B +:1060500000831024AFBE0030AFB7002CAFB60028CD +:10606000AFB50024AFB40020AFB3001CAFB200182E +:10607000AFB1001410400051AFB000108F84004049 +:10608000948700069488000A00E8302330D5FFFF8B +:1060900012A0004B8FBF0034948B0018948C000A20 +:1060A000016C50233142FFFF02A2482B1520000251 +:1060B00002A02021004020212C8F000515E00002C5 +:1060C00000809821241300040E0001C102602021E9 +:1060D0008F87004002609021AF80004494F4000A52 +:1060E000026080211260004E3291FFFF3C1670006A +:1060F0003C1440003C1E20003C1760008F99005863 +:106100008F380000031618241074004F0283F82BF8 +:1061100017E0003600000000107E00478F86004424 +:1061200014C0003A2403000102031023022320219B +:106130003050FFFF1600FFF13091FFFF8F870040C6 +:106140003C1100203C108000AE11003094EB000A9E +:106150003C178000024B5021A4EA000A94E9000A8F +:1061600094E800043123FFFF3106000F00062D00E4 +:106170000065F025AEFE008094F3000A94F6001846 +:1061800012D30036001221408CFF00148CF4001052 +:1061900003E468210000C02101A4782B029870213B +:1061A00001CF6021ACED0014ACEC001002B238233A +:1061B00030F5FFFF16A0FFB88F8400408FBF00347A +:1061C0008FBE00308FB7002C8FB600288FB500240B +:1061D0008FB400208FB3001C8FB200188FB1001451 +:1061E0008FB0001003E0000827BD00381477FFCC03 +:1061F0008F8600440E000EE202002021004018218C +:106200008F86004410C0FFC9020310230270702360 +:106210008F87004001C368210A0002E431B2FFFF0A +:106220008F86004414C0FFC93C1100203C10800040 +:106230000A0002AEAE1100300E00046602002021FA +:106240000A0002DB00401821020020210E0009395B +:10625000022028210A0002DB004018210E0001EE76 +:10626000000000000A0002C702B2382327BDFFC8A1 +:10627000AFB7002CAFB60028AFB50024AFB40020F4 +:10628000AFB3001CAFB20018AFB10014AFB0001034 +:10629000AFBF00300E00011B241300013C047FFF40 +:1062A0003C0380083C0220003C010800AC20007048 +:1062B0003496FFFF34770080345200033C1512C03F +:1062C000241400013C1080002411FF800E000245C0 +:1062D000000000008F8700488F8B00188F89001402 +:1062E0008CEA00EC8CE800E8014B302B01092823F4 +:1062F00000A6102314400006014B18231440000E82 +:106300003C05800002A3602B1180000B0000000000 +:106310003C0560008CEE00EC8CED00E88CA4180CC1 +:10632000AF8E001804800053AF8D00148F8F0010C3 +:10633000ADF400003C0580008CBF00003BF900017B +:10634000333800011700FFE13C0380008C6201003C +:1063500024060C0010460009000000008C680100B3 +:106360002D043080548000103C0480008C690100B2 +:106370002D2331811060000C3C0480008CAA0100A8 +:1063800011460004000020218CA6010024C5FF81D5 +:1063900030A400FF8E0B01000E000269AE0B00243A +:1063A0000A00034F3C0480008C8D01002DAC3300AB +:1063B00011800022000000003C0708008CE70098D4 +:1063C00024EE00013C010800AC2E00983C04800043 +:1063D0008C8201001440000300000000566000148D +:1063E0003C0440008C9F01008C9801000000982123 +:1063F00003F1C82400193940330F007F00EF7025E6 +:1064000001D26825AC8D08308C8C01008C85010090 +:10641000258B0100017130240006514030A3007F1C +:106420000143482501324025AC8808303C04400037 +:10643000AE0401380A00030E000000008C99010030 +:10644000240F0020AC99002092F80000330300FFD5 +:10645000106F000C241F0050547FFFDD3C048000AF +:106460008C8401000E00154E000000000A00034F4E +:106470003C04800000963824ACA7180C0A000327BF +:106480008F8F00108C8501000E0008F72404008017 +:106490000A00034F3C04800000A4102B24030001D9 +:1064A00010400009000030210005284000A4102BF6 +:1064B00004A00003000318405440FFFC00052840DE +:1064C0005060000A0004182B0085382B54E00004AB +:1064D0000003184200C33025008520230003184222 +:1064E0001460FFF9000528420004182B03E000089F +:1064F00000C310213084FFFF30C600FF3C0780003E +:106500008CE201B80440FFFE00064C000124302557 +:106510003C08200000C820253C031000ACE00180AE +:10652000ACE50184ACE4018803E00008ACE301B809 +:106530003C0660008CC5201C2402FFF03083020062 +:10654000308601001060000E00A2282434A500014E +:106550003087300010E0000530830C0034A50004C3 +:106560003C04600003E00008AC85201C1060FFFDC7 +:106570003C04600034A5000803E00008AC85201C42 +:1065800054C0FFF334A500020A0003B03087300086 +:1065900027BDFFE8AFB00010AFBF00143C0760009C +:1065A000240600021080001100A080218F83005873 +:1065B0000E0003A78C6400188F8200580000202171 +:1065C000240600018C45000C0E000398000000001A +:1065D0001600000224020003000010218FBF0014E7 +:1065E0008FB0001003E0000827BD00188CE8201CC5 +:1065F0002409FFF001092824ACE5201C8F870058EE +:106600000A0003CD8CE5000C3C02600E00804021A6 +:1066100034460100240900180000000000000000BA +:10662000000000003C0A00503C0380003547020097 +:10663000AC68003834640400AC65003CAC670030E2 +:106640008C6C0000318B00201160FFFD2407FFFFE0 +:106650002403007F8C8D00002463FFFF248400044A +:10666000ACCD00001467FFFB24C60004000000004E +:10667000000000000000000024A402000085282B78 +:106680003C0300203C0E80002529FFFF010540212E +:10669000ADC300301520FFE00080282103E0000892 +:1066A000000000008F82005827BDFFD8AFB3001C48 +:1066B000AFBF0020AFB20018AFB10014AFB00010F0 +:1066C00094460002008098218C5200182CC300814F +:1066D0008C4800048C4700088C51000C8C49001039 +:1066E000106000078C4A00142CC4000414800013AE +:1066F00030EB000730C5000310A0001000000000C0 +:106700002410008B02002021022028210E00039873 +:10671000240600031660000224020003000010217A +:106720008FBF00208FB3001C8FB200188FB10014F0 +:106730008FB0001003E0000827BD00281560FFF1AE +:106740002410008B3C0C80003C030020241F00011F +:10675000AD830030AF9F0044000000000000000047 +:10676000000000002419FFF024D8000F031978243A +:106770003C1000D0AD88003801F0702524CD000316 +:106780003C08600EAD87003C35850400AD8E0030BE +:10679000000D38823504003C3C0380008C6B000007 +:1067A000316200201040FFFD0000000010E00008F2 +:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 +:1067C00024A50004AC8800001467FFFB24840004A7 +:1067D0003C05600EACA60038000000000000000080 +:1067E000000000008F8600543C0400203C0780001D +:1067F000ACE4003054C000060120202102402021DA +:106800000E0003A7000080210A00041D02002021C1 +:106810000E0003DD01402821024020210E0003A7C5 +:10682000000080210A00041D0200202127BDFFE096 +:10683000AFB200183092FFFFAFB10014AFBF001C21 +:10684000AFB000101640000D000088210A0004932C +:106850000220102124050003508500278CE5000C40 +:106860000000000D262800013111FFFF24E2002066 +:106870000232802B12000019AF8200588F82004430 +:10688000144000168F8700583C0670003C0320001F +:106890008CE5000000A62024148300108F84006083 +:1068A000000544023C09800000A980241480FFE90F +:1068B000310600FF2CCA000B5140FFEB26280001D7 +:1068C000000668803C0E080025CE575801AE6021B6 +:1068D0008D8B0000016000080000000002201021E4 +:1068E0008FBF001C8FB200188FB100148FB0001042 +:1068F00003E0000827BD00200E0003982404008454 +:106900001600FFD88F8700580A000474AF8000601B +:10691000020028210E0003BF240400018F870058C5 +:106920000A000474AF820060020028210E0003BF39 +:10693000000020210A0004A38F8700580E000404E1 +:10694000020020218F8700580A000474AF82006083 +:1069500030AFFFFF000F19C03C0480008C9001B8DD +:106960000600FFFE3C1920043C181000AC83018097 +:10697000AC800184AC990188AC9801B80A00047518 +:106980002628000190E2000390E30002000020218D +:106990000002FE0000033A0000FF2825240600083C +:1069A0000E000398000000001600FFDC2402000324 +:1069B0008F870058000010210A000474AF82006025 +:1069C00090E8000200002021240600090A0004C308 +:1069D00000082E0090E4000C240900FF308500FF21 +:1069E00010A900150000302190F9000290F8000372 +:1069F000308F00FF94EB000400196E000018740043 +:106A0000000F62000186202501AE5025014B28258C +:106A10003084FF8B0A0004C32406000A90E30002BE +:106A200090FF0004000020210003360000DF28252D +:106A30000A0004C32406000B0A0004D52406008BB8 +:106A4000000449C23127003F000443423C02800059 +:106A500000082040240316802CE60020AC43002CC4 +:106A600024EAFFE02482000114C0000330A900FFE3 +:106A700000801021314700FF000260803C0D800043 +:106A8000240A0001018D20213C0B000E00EA28049D +:106A9000008B302111200005000538278CCE000026 +:106AA00001C5382503E00008ACC700008CD8000001 +:106AB0000307782403E00008ACCF000027BDFFE007 +:106AC000AFB10014AFB00010AFBF00183C076000BA +:106AD0008CE408083402F0003C1160003083F000C0 +:106AE000240501C03C04800E000030211062000625 +:106AF000241000018CEA08083149F0003928E00030 +:106B00000008382B000780403C0D0200AE2D081411 +:106B1000240C16803C0B80008E2744000E000F8B47 +:106B2000AD6C002C120000043C02169124050001FB +:106B3000120500103C023D2C345800E0AE384408E9 +:106B40003C1108008E31007C8FBF00183C066000AD +:106B500000118540360F16808FB100148FB00010E1 +:106B60003C0E020027BD0020ACCF442003E000080B +:106B7000ACCE08103C0218DA345800E0AE384408B5 +:106B80003C1108008E31007C8FBF00183C0660006D +:106B900000118540360F16808FB100148FB00010A1 +:106BA0003C0E020027BD0020ACCF442003E00008CB +:106BB000ACCE08100A0004EB240500010A0004EB27 +:106BC0000000282124020400A7820024A780001CC2 +:106BD000000020213C06080024C65A582405FFFF67 +:106BE00024890001000440803124FFFF01061821A0 +:106BF0002C87002014E0FFFAAC6500002404040098 +:106C0000A7840026A780001E000020213C06080063 +:106C100024C65AD82405FFFF248D0001000460809B +:106C200031A4FFFF018658212C8A00201540FFFA6D +:106C3000AD650000A7800028A7800020A780002263 +:106C4000000020213C06080024C65B582405FFFFF5 +:106C5000249900010004C0803324FFFF030678213B +:106C60002C8E000415C0FFFAADE500003C05600065 +:106C70008CA73D002403E08F00E31024344601403C +:106C800003E00008ACA63D002487007F000731C266 +:106C900024C5FFFF000518C2246400013082FFFFF5 +:106CA000000238C0A78400303C010800AC27003047 +:106CB000AF80002C0000282100002021000030219E +:106CC0002489000100A728213124FFFF2CA81701E7 +:106CD000110000032C8300801460FFF924C600011A +:106CE00000C02821AF86002C10C0001DA786002AF6 +:106CF00024CAFFFF000A11423C08080025085B581F +:106D00001040000A00002021004030212407FFFF2E +:106D1000248E00010004688031C4FFFF01A86021B7 +:106D20000086582B1560FFFAAD87000030A2001FC7 +:106D30005040000800043080240300010043C804D0 +:106D400000041080004878212738FFFF03E0000886 +:106D5000ADF8000000C820212405FFFFAC8500002D +:106D600003E000080000000030A5FFFF30C6FFFF71 +:106D700030A8001F0080602130E700FF0005294295 +:106D80000000502110C0001D24090001240B000147 +:106D900025180001010B2004330800FF0126782686 +:106DA000390E00202DED00012DC2000101A2182591 +:106DB0001060000D014450250005C880032C4021BF +:106DC0000100182110E0000F000A20278D040000A8 +:106DD000008A1825AD03000024AD00010000402109 +:106DE0000000502131A5FFFF252E000131C9FFFF12 +:106DF00000C9102B1040FFE72518000103E0000830 +:106E0000000000008D0A0000014440240A0005D162 +:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC +:106E2000AFB00010AFBF001430E7FFFF00005021EB +:106E30003410FFFF0000602124AF001F00C0482174 +:106E4000241800012419002005E0001601E010219B +:106E50000002F943019F682A0009702B01AE40240B +:106E600011000017000C18800064102110E00005CC +:106E70008C4B000000F840040008382301675824B8 +:106E800000003821154000410000402155600016E7 +:106E90003169FFFF258B0001316CFFFF05E1FFEC3D +:106EA00001E0102124A2003E0002F943019F682A5C +:106EB0000009702B01AE40241500FFEB000C188078 +:106EC000154600053402FFFF020028210E0005B51B +:106ED00000003821020010218FBF00148FB0001075 +:106EE00003E0000827BD00181520000301601821E9 +:106EF000000B1C0224080010306A00FF154000053A +:106F0000306E000F250D000800031A0231A800FFA3 +:106F1000306E000F15C00005307F000325100004FF +:106F200000031902320800FF307F000317E000055C +:106F3000386900012502000200031882304800FF72 +:106F4000386900013123000110600004310300FFA3 +:106F5000250A0001314800FF310300FF000C6940A1 +:106F600001A34021240A000110CAFFD53110FFFF00 +:106F7000246E000131C800FF1119FFC638C9000195 +:106F80002D1F002053E0001C258B0001240D000163 +:106F90000A000648240E002051460017258B0001E8 +:106FA00025090001312800FF2D0900205120001281 +:106FB000258B000125430001010D5004014B1024D5 +:106FC000250900011440FFF4306AFFFF3127FFFF5D +:106FD00010EE000C2582FFFF304CFFFF0000502117 +:106FE0003410FFFF312800FF2D0900205520FFF24B +:106FF00025430001258B0001014648260A000602B0 +:10700000316CFFFF00003821000050210A000654B7 +:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 +:10702000AFB10014001039423211FFE000071080A8 +:10703000AFB3001C00B1282330D3FFFFAFB200185C +:1070400030A5FFFF00809021026030210044202104 +:10705000AFBF00200E0005E03207001F022288218A +:107060003403FFFF0240202102002821026030216A +:1070700000003821104300093231FFFF02201021A7 +:107080008FBF00208FB3001C8FB200188FB1001487 +:107090008FB0001003E0000827BD00280E0005E0B7 +:1070A0000000000000408821022010218FBF002036 +:1070B0008FB3001C8FB200188FB100148FB0001076 +:1070C00003E0000827BD0028000424003C03600002 +:1070D000AC603D0810A00002348210063482101605 +:1070E00003E00008AC623D0427BDFFE0AFB0001034 +:1070F000309000FF2E020006AFBF001810400008BD +:10710000AFB10014001030803C03080024635784A2 +:1071100000C328218CA400000080000800000000AB +:10712000000020218FBF00188FB100148FB0001015 +:107130000080102103E0000827BD00209791002A5D +:1071400016200051000020213C020800904200332C +:107150000A0006BB00000000978D002615A0003134 +:10716000000020210A0006BB2402000897870024A3 +:1071700014E0001A00001821006020212402000100 +:107180001080FFE98FBF0018000429C2004530219C +:1071900000A6582B1160FFE43C0880003C0720004B +:1071A000000569C001A76025AD0C00203C038008E4 +:1071B0002402001F2442FFFFAC6000000441FFFDD9 +:1071C0002463000424A5000100A6702B15C0FFF560 +:1071D000000569C00A0006A58FBF00189787001C2C +:1071E0003C04080024845A58240504000E0006605C +:1071F00024060001978B002424440001308AFFFFFD +:107200002569FFFF2D48040000402821150000409B +:10721000A789002424AC3800000C19C00A0006B964 +:10722000A780001C9787001E3C04080024845AD8BD +:10723000240504000E00066024060001979900262C +:10724000244400013098FFFF272FFFFF2F0E04007A +:107250000040882115C0002CA78F0026A780001EA3 +:107260003A020003262401003084FFFF0E00068D41 +:107270002C4500010011F8C027F00100001021C0CA +:107280000A0006BB240200089785002E978700227B +:107290003C04080024845B580E00066024060001AC +:1072A0009787002A8F89002C2445000130A8FFFF12 +:1072B00024E3FFFF0109302B0040802114C0001897 +:1072C000A783002AA7800022978500300E000F7543 +:1072D00002002021244A05003144FFFF0E00068DE4 +:1072E000240500013C05080094A500320E000F752E +:1072F00002002021244521003C0208009042003376 +:107300000A0006BB000521C00A0006F3A784001E80 +:1073100024AC3800000C19C00A0006B9A784001C70 +:107320000A00070DA7850022308400FF27BDFFE873 +:107330002C820006AFBF0014AFB000101040001543 +:1073400000A03821000440803C0308002463579CBF +:10735000010328218CA40000008000080000000028 +:1073600024CC007F000751C2000C59C23170FFFFCE +:107370002547C40030E5FFFF2784001C02003021B0 +:107380000E0005B52407000197860028020620217B +:10739000A78400288FBF00148FB0001003E00008FE +:1073A00027BD00183C0508008CA50030000779C2F5 +:1073B0000E00038125E4DF003045FFFF3C04080098 +:1073C00024845B58240600010E0005B52407000143 +:1073D000978E002A8FBF00148FB0001025CD0001BA +:1073E00027BD001803E00008A78D002A0007C9C2C6 +:1073F0002738FF00001878C231F0FFFF3C04080076 +:1074000024845AD802002821240600010E0005B564 +:1074100024070001978D0026260E0100000E84002F +:1074200025AC00013C0B6000A78C0026AD603D0838 +:1074300036040006000030213C0760008CE23D0469 +:10744000305F000617E0FFFD24C9000100061B00A5 +:10745000312600FF006440252CC50004ACE83D0443 +:1074600014A0FFF68FBF00148FB0001003E00008D7 +:1074700027BD0018000751C22549C8002406000195 +:10748000240700013C04080024845A580E0005B566 +:107490003125FFFF978700248FBF00148FB00010A5 +:1074A00024E6000127BD001803E00008A786002499 +:1074B0003C0660183C090800252900FCACC9502C8A +:1074C0008CC850003C0580003C020002350700805B +:1074D000ACC750003C04080024841FE03C030800B3 +:1074E00024631F98ACA50008ACA2000C3C01080066 +:1074F000AC2459A43C010800AC2359A803E00008BF +:107500002402000100A030213C1C0800279C59AC3B +:107510003C0C04003C0B0002008B3826008C4026FB +:107520002CE200010007502B2D050001000A4880C5 +:107530003C030800246359A4004520250123182199 +:107540001080000300001021AC660000240200013E +:1075500003E00008000000003C1C0800279C59AC18 +:107560003C0B04003C0A0002008A3026008B3826BF +:107570002CC200010006482B2CE5000100094080C8 +:107580003C030800246359A4004520250103182169 +:1075900010800005000010213C0C0800258C1F986D +:1075A000AC6C00002402000103E0000800000000B1 +:1075B0003C0900023C080400008830260089382677 +:1075C0002CC30001008028212CE400010083102539 +:1075D0001040000B000030213C1C0800279C59ACD7 +:1075E0003C0A80008D4E00082406000101CA68256F +:1075F000AD4D00088D4C000C01855825AD4B000C9D +:1076000003E0000800C010213C1C0800279C59AC76 +:107610003C0580008CA6000C0004202724020001F9 +:1076200000C4182403E00008ACA3000C3C020002D4 +:107630001082000B3C0560003C070400108700032B +:107640000000000003E00008000000008CA908D042 +:10765000240AFFFD012A402403E00008ACA808D05A +:107660008CA408D02406FFFE0086182403E000083E +:10767000ACA308D03C05601A34A600108CC300806F +:1076800027BDFFF88CC50084AFA3000093A40000C1 +:107690002402001010820003AFA5000403E00008DC +:1076A00027BD000893A7000114E0001497AC000266 +:1076B00097B800023C0F8000330EFFFC01CF682119 +:1076C000ADA50000A3A000003C0660008CC708D058 +:1076D0002408FFFE3C04601A00E82824ACC508D04A +:1076E0008FA300048FA200003499001027BD00086A +:1076F000AF22008003E00008AF2300843C0B800031 +:10770000318AFFFC014B48218D2800000A00080C3B +:10771000AFA8000427BDFFE8AFBF00103C1C080065 +:10772000279C59AC3C0580008CA4000C8CA2000462 +:107730003C0300020044282410A0000A00A31824DF +:107740003C0604003C0400021460000900A610245A +:107750001440000F3C0404000000000D3C1C080015 +:10776000279C59AC8FBF001003E0000827BD00180C +:107770003C0208008C4259A40040F80900000000B7 +:107780003C1C0800279C59AC0A0008358FBF00102C +:107790003C0208008C4259A80040F8090000000093 +:1077A0000A00083B000000003C0880008D0201B880 +:1077B0000440FFFE35090180AD2400003C031000A9 +:1077C00024040040AD250004A1240008A1260009DE +:1077D000A527000A03E00008AD0301B83084FFFFCD +:1077E0000080382130A5FFFF000020210A00084555 +:1077F000240600803087FFFF8CA400002406003898 +:107800000A000845000028218F8300788F860070C9 +:107810001066000B008040213C07080024E75B68ED +:10782000000328C000A710218C440000246300013D +:10783000108800053063000F5466FFFA000328C06B +:1078400003E00008000010213C07080024E75B6CFF +:1078500000A7302103E000088CC200003C03900028 +:1078600034620001008220253C038000AC640020CB +:107870008C65002004A0FFFE0000000003E000086B +:10788000000000003C0280003443000100832025FA +:1078900003E00008AC44002027BDFFE0AFB10014B6 +:1078A0003091FFFFAFB00010AFBF001812200013DF +:1078B00000A080218CA20000240400022406020003 +:1078C0001040000F004028210E0007250000000096 +:1078D00000001021AE000000022038218FBF0018E8 +:1078E0008FB100148FB0001000402021000028212B +:1078F000000030210A00084527BD00208CA20000AE +:10790000022038218FBF00188FB100148FB00010F3 +:107910000040202100002821000030210A000845F5 +:1079200027BD002000A010213087FFFF8CA5000498 +:107930008C4400000A000845240600068F83FD9C45 +:1079400027BDFFE8AFBF0014AFB00010906700087C +:10795000008010210080282130E600400000202116 +:1079600010C000088C5000000E0000BD0200202155 +:10797000020020218FBF00148FB000100A000548BC +:1079800027BD00180E0008A4000000000E0000BD76 +:1079900002002021020020218FBF00148FB00010B0 +:1079A0000A00054827BD001827BDFFE0AFB0001052 +:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 +:1079C00092060001008088210E00087230D2000467 +:1079D00092040005001129C2A6050000348300406E +:1079E000A20300050E00087C022020210E00054A9B +:1079F0000220202124020001AE02000C02202821D6 +:107A0000A602001024040002A602001224060200AE +:107A1000A60200140E000725A60200161640000F4D +:107A20008FBF001C978C00743C0B08008D6B007896 +:107A30002588FFFF3109FFFF256A0001012A382B45 +:107A400010E00006A78800743C0F6006240E0016A4 +:107A500035ED0010ADAE00508FBF001C8FB2001886 +:107A60008FB100148FB0001003E0000827BD002084 +:107A700027BDFFE0AFB10014AFBF0018AFB00010DA +:107A80001080000400A088212402008010820007DA +:107A9000000000000000000D8FBF00188FB100141F +:107AA0008FB0001003E0000827BD00200E00087210 +:107AB00000A020218F86FD9C0220202190C500057A +:107AC0000E00087C30B000FF2403003E1603FFF1D7 +:107AD0003C0680008CC401780480FFFE34C801405D +:107AE000240900073C071000AD11000002202021EE +:107AF000A10900048FBF00188FB100148FB00010CF +:107B0000ACC701780A0008C527BD002027BDFFE0EB +:107B1000AFB00010AFBF0018AFB100143C10800030 +:107B20008E110020000000000E00054AAE04002067 +:107B3000AE1100208FBF00188FB100148FB000105D +:107B400003E0000827BD00203084FFFF00803821BB +:107B50002406003500A020210A0008450000282145 +:107B60003084FFFF008038212406003600A0202149 +:107B70000A0008450000282127BDFFD0AFB500242A +:107B80003095FFFFAFB60028AFB40020AFBF002C88 +:107B9000AFB3001CAFB20018AFB10014AFB000100B +:107BA00030B6FFFF12A000270000A0218F920058DE +:107BB0008E4300003C0680002402004000033E0289 +:107BC00000032C0230E4007F006698241482001D1C +:107BD00030A500FF8F8300682C68000A1100001098 +:107BE0008F8D0044000358803C0C0800258C57B84A +:107BF000016C50218D4900000120000800000000A8 +:107C000002D4302130C5FFFF0E0008522404008446 +:107C1000166000028F920058AF8000688F8D00447C +:107C20002659002026980001032090213314FFFFDD +:107C300015A00004AF9900580295202B1480FFDC9A +:107C400000000000028010218FBF002C8FB600289A +:107C50008FB500248FB400208FB3001C8FB20018A2 +:107C60008FB100148FB0001003E0000827BD003072 +:107C70002407003414A70149000000009247000EB9 +:107C80008F9FFDA08F90FD9C24181600A3E700197C +:107C90009242000D3C0880003C07800CA3E20018D3 +:107CA000964A00123C0D60003C117FFFA60A005C62 +:107CB000964400103623FFFF240200053099FFFF91 +:107CC000AE1900548E46001CAD1800288CEF000041 +:107CD0008DAE444801E6482601C93021AE06003881 +:107CE0008E05003824CB00013C0E7F00AE05003C21 +:107CF0008E0C003CAFEC0004AE0B00208E13002075 +:107D0000AE13001CA3E0001BAE03002CA3E2001284 +:107D10008E4A001424130050AE0A00348E0400343E +:107D2000AFE400148E590018AE1900489258000CA8 +:107D3000A218004E920D000835AF0020A20F0008D7 +:107D40008E090018012E282434AC4000AE0C001817 +:107D5000920B0000317200FF1253027F2403FF8058 +:107D60003C04080024845BE80E0008AA0000000020 +:107D70003C1108008E315BE80E00087202202021C1 +:107D80002405000424080001A2050025022020216A +:107D90000E00087CA20800053C0580008CB001782C +:107DA0000600FFFE8F92005834AE0140240F0002FF +:107DB0003C091000ADD10000A1CF0004ACA90178AE +:107DC0000A000962AF8000682CAD003751A0FF9413 +:107DD0008F8D0044000580803C110800263157E05B +:107DE000021178218DEE000001C0000800000000A3 +:107DF0002411000414B1008C3C0780003C080800EA +:107E00008D085BE88F86FD9CACE800208E4500085D +:107E10008F99FDA0240D0050ACC500308E4C000899 +:107E2000ACCC00508E4B000CACCB00348E43001019 +:107E3000ACC300388E4A0010ACCA00548E42001405 +:107E4000ACC2003C8E5F0018AF3F00048E50001C97 +:107E5000ACD0002090C40000309800FF130D024AFF +:107E6000000000008CC400348CD00030009030231F +:107E700004C000F12404008C126000EE2402000310 +:107E80000A000962AF8200682419000514B900666F +:107E90003C0580003C0808008D085BE88F86FD9C4F +:107EA000ACA800208E4C00048F8AFDA0240720007F +:107EB000ACCC001C924B000824120008A14B001906 +:107EC0008F82005890430009A14300188F85005805 +:107ED00090BF000A33E400FF1092001028890009C7 +:107EE000152000BA240E0002240D0020108D000B76 +:107EF000340780002898002117000008240740005C +:107F000024100040109000053C0700012419008057 +:107F1000109900023C070002240740008CC20018A0 +:107F20003C03FF00004350240147F825ACDF001854 +:107F300090B2000BA0D200278F8300589464000CED +:107F4000108001FE000000009467000C3C1F8000C0 +:107F50002405FFBFA4C7005C9063000E2407000443 +:107F6000A0C300088F820058904A000FA0CA0009E1 +:107F70008F8900588D3200108FE400740244C823AA +:107F8000ACD900588D300014ACD0002C95380018B6 +:107F9000330DFFFFACCD00409531001A322FFFFFAB +:107FA000ACCF00448D2E001CACCE00489128000EB2 +:107FB000A0C8000890CC000801855824126001B6C2 +:107FC000A0CB00088F9200580A000962AF870068B2 +:107FD0002406000614A600143C0E80003C0F080086 +:107FE0008DEF5BE88F85FD98ADCF00208E4900189E +:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B +:1080000024040005ACA800048CCC003C1260008164 +:10801000AD6C00000A000962AF84006824110007FB +:1080200010B1004B240400063C05080024A55BE8C1 +:108030000E000881240400818F9200580013102B39 +:108040000A000962AF820068241F002314BFFFF6F4 +:108050003C0C80003C0508008CA55BE88F8BFDA0E4 +:10806000AD8500208F91FD9C8E4600042564002084 +:1080700026450014AE260028240600030E000F81BA +:10808000257000308F87005802002021240600034D +:108090000E000F8124E500083C04080024845BE8FE +:1080A0000E0008AA0000000092230000240A0050DD +:1080B000306200FF544AFFE18F9200580E000F6CAF +:1080C000000000000A000A6A8F920058240800335A +:1080D00014A800323C0380003C1108008E315BE89C +:1080E0008F8FFDA0AC7100208E420008240D002867 +:1080F0008F89FD9CADE200308E4A000C24060009F9 +:10810000ADEA00348E5F0010ADFF00388E440014DD +:10811000ADE400208E590018ADF900248E58001CE3 +:10812000ADF80028A1ED00118E4E00041260003160 +:10813000AD2E00288F9200580A000962AF860068B1 +:10814000240D002214ADFFB8000000002404000735 +:108150003C1008008E105BE83C188000AF10002037 +:108160005660FEAEAF8400683C04080024845BE8DF +:108170000E0008AA241300508F84FD9C90920000EA +:10818000325900FF1333014B000000008F9200585A +:10819000000020210A000962AF8400683C05080045 +:1081A00024A55BE80E000858240400810A000A6A2E +:1081B0008F92005802D498213265FFFF0E000852BA +:1081C000240400840A0009628F920058108EFF5325 +:1081D000240704002887000310E00179241100041B +:1081E000240F0001548FFF4D240740000A000A228B +:1081F000240701003C05080024A55BE80E0008A444 +:10820000240400828F920058000030210A00096285 +:10821000AF8600683C04080024845BE88CC2003808 +:108220000E0008AA8CC3003C8F9200580A000AC0B6 +:1082300000002021240400823C05080024A55BE8FE +:108240000E0008A4000000008F92005800001021CA +:108250000A000962AF8200688E5000048F91FD9C75 +:108260003C078000ACF00020922C00050200282181 +:10827000318B0002156001562404008A8F92FDA004 +:108280002404008D9245001B30A6002014C001502C +:1082900002002821922E00092408001231C900FF93 +:1082A0001128014B240400810E00087202002021D5 +:1082B0009258001B240F000402002021370D0042B9 +:1082C000A24D001B0E00087CA22F00253C0580005B +:1082D0008CA401780480FFFE34B90140241F000201 +:1082E000AF300000A33F00048F9200583C101000F4 +:1082F000ACB001780A000A6B0013102B8E500004FA +:108300008F91FD9C3C038000AC700020922A0005F8 +:108310000200282131420002144000172404008A80 +:10832000922C00092412000402002821318B00FF46 +:1083300011720011240400810E0008720200202135 +:108340008F89FDA0240800122405FFFE912F001B39 +:108350000200202135EE0020A12E001BA2280009DA +:108360009226000500C538240E00087CA2270005CF +:1083700002002821000020210E0009330000000027 +:108380000A000A6A8F9200588E4C00043C07800055 +:108390003C10080026105BE8ACEC00203C01080013 +:1083A000AC2C5BE8924B0003317100041220013BBE +:1083B0008F84FD9C24020006A0820009924F001BBE +:1083C000240EFFC031E9003F012E4025A08800089F +:1083D0009245000330A6000114C0013200000000E5 +:1083E0008E420008AE0200083C0208008C425BF09E +:1083F000104001318F90FDA0000219C28F8DFD9CAD +:10840000A603000C8E4A000C24180001240400145A +:10841000AE0A002C8E420010AE02001C965F0016C1 +:10842000A61F003C96590014A619003EADB8000CDA +:10843000A5B80010A5B80012A5B80014A5B800167C +:1084400012600144A2040011925100033232000272 +:108450002E5300018F920058266200080A0009621C +:10846000AF8200688E4400043C1980003C068008FE +:10847000AF2400208E45000890D80000240D005045 +:10848000331100FF122D009C2407008824060009E8 +:108490000E000845000000000A000A6A8F9200588A +:1084A0008E5000043C0980003C118008AD30002053 +:1084B0009228000024050050310400FF10850110AF +:1084C0002407008802002021000028210E00084512 +:1084D0002406000E922D00002418FF80020028219F +:1084E00001B8802524040004240600300E0007256E +:1084F000A23000000A000A6A8F9200588E500004D1 +:108500008F91FDA03C028000AC500020923F001BE8 +:1085100033F900101320006C240700810200202191 +:10852000000028212406001F0E000845000000005E +:108530000A000A6A8F9200588E44001C0E00085DE3 +:1085400000000000104000E3004048218F880058E0 +:1085500024070089012020218D05001C240600012C +:108560000E000845000000000A000A6A8F920058B9 +:10857000964900023C10080026105BE831280004F0 +:10858000110000973C0460008E4E001C3C0F8000E0 +:10859000ADEE00203C010800AC2E5BE896470002DF +:1085A00030E40001148000E6000000008E42000468 +:1085B000AE0200083C1008008E105BF0120000ECC8 +:1085C0003C0F80008F92FD9C241000018E4E0018FD +:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 +:1085E000A2400005AE50000C3C0808008D085BF06E +:1085F0008F840058A6500010000839C2A6500012FF +:10860000A6500014A6500016A5A7000C8C8C0008DC +:108610008F8B00588F8A0058ADAC002C8D63000CF6 +:1086200024070002ADA3001C91460010A1A6001172 +:108630008F82005890450011A3E500088F990058DB +:1086400093380012A258004E8F910058922F0013B9 +:10865000A1AF00128F920058964E0014A5AE003CB8 +:1086600096490016A5A9003E8E480018ADA8001432 +:108670005660FD6AAF8700683C05080024A55BE8EA +:108680000E000881000020218F9200580000382140 +:108690000A000962AF8700683C05080024A55BE872 +:1086A0000E0008A4240400828F9200580A000A4D8C +:1086B000000038210E000F6C000000008F9200585F +:1086C0000A000AC0000020210E00087202002021CA +:1086D0009223001B02002021346A00100E00087C47 +:1086E000A22A001B000038210200202100002821BE +:1086F0000A000BA52406001F9242000C305F000107 +:1087000013E0000300000000964A000EA4CA002CEB +:10871000924B000C316300025060000600003821CB +:108720008E470014964C0012ACC7001CA4CC001A53 +:10873000000038210A000B7F240600093C050800D0 +:1087400024A55BE80E0008A42404008B8F92005837 +:108750000A000A4D0013382B3C0C08008D8C5BE896 +:1087600024DFFFFE25930100326B007F016790211B +:1087700002638824AD110028AE4600E0AE4000E45C +:108780000A0009B3AE5F001CACC000543C0D0800E9 +:108790008DAD5BE83C18800C37090100ACED00287A +:1087A0008E510014AD3100E08E4F0014AD2F00E467 +:1087B0008E4E001025C7FFFE0A0009F4AD27001CED +:1087C0005491FDD6240740000A000A222407100015 +:1087D0000E00092D000000000A000A6A8F9200585E +:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 +:1087F000AC205BE810710062000000003C196C6264 +:1088000037387970147800082404000297850074C2 +:108810009782006C2404009200A2F82B13E0001948 +:1088200002002821240400020E00069524050200FF +:108830003C068000ACC200203C010800AC225BE892 +:108840001040000D8F8C0058240A002824040003D7 +:10885000918B0010316300FF546A00012404000171 +:108860000E0000810000000010400004240400837A +:108870000A000BC28F920058240400833C050800B4 +:1088800024A55BE80E000881000000008F920058CC +:108890000013382B0A000962AF8700680A000B49F1 +:1088A000240200128E4400080E00085D0000000043 +:1088B0000A000B55AE0200083C05080024A55BE841 +:1088C0000E000858240400878F9200580A000B728B +:1088D0000013102B240400040E000695240500301C +:1088E0001440002A004048218F8800582407008344 +:1088F000012020218D05001C0A000BB32406000175 +:108900008F8300788F8600701066FEEE000038219D +:108910003C07080024E75B6C000320C00087282187 +:108920008CAE000011D0005D246F000131E3000F18 +:108930005466FFFA000320C00A000B8C00003821A7 +:108940008E4400040E00085D000000000A000BC801 +:10895000AE0200083C05080024A55BE80E0008A450 +:10896000240400828F9200580A000B72000010212C +:108970003C05080024A55BE80A000C7C2404008761 +:108980008C83442C0A000C5B3C196C628F88005865 +:108990003C0780083C0C8000240B0050240A000196 +:1089A000AD820020A0EB0000A0EA000191030004CA +:1089B000A0E3001891040005A0E400199106000648 +:1089C0003C04080024845B6CA0E6001A91020007B6 +:1089D0003C06080024C65B68A0E2001B9105000865 +:1089E000A0E5001C911F0009A0FF001D9119000ABD +:1089F000A0F9001E9118000BA0F8001F9112000CA6 +:108A0000A0F200209111000DA0F100219110000EA4 +:108A1000A0F00022910F000FA0EF0023910E001094 +:108A2000A0EE0024910D0011A0ED0025950C00147E +:108A3000A4EC0028950B00168F8A00708F920078A6 +:108A4000A4EB002A95030018000A10C02545000178 +:108A5000A4E3002C8D1F001C0044C0210046C82147 +:108A600030A5000FAF3F0000AF09000010B20006B4 +:108A7000AF850070000038218D05001C01202021E9 +:108A80000A000BB32406000124AD000131A7000F3A +:108A9000AF8700780A000CF9000038213C06080076 +:108AA00024C65B680086902100003821ACA000003D +:108AB0000A000B8CAE4000003C0482013C036000C5 +:108AC00034820E02AC603D68AF80009803E000087D +:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 +:108AE000001018422C620041AFBF00141440000275 +:108AF00024040080240300403C010800AC300060E6 +:108B00003C010800AC2300640E000F7500602821B2 +:108B1000244802BF2409FF8001092824001039805D +:108B2000001030408FBF00148FB0001000A720212C +:108B300000861821AF8300803C010800AC25005856 +:108B40003C010800AC24005C03E0000827BD0018CD +:108B5000308300FF30C6FFFF30E400FF3C08800098 +:108B60008D0201B80440FFFE000354000144382583 +:108B70003C09600000E920253C031000AD050180A0 +:108B8000AD060184AD04018803E00008AD0301B81F +:108B90008F8500583C0A6012354800108CAC0004E8 +:108BA0003C0D600E35A60010318B00062D690001CA +:108BB000AD0900C48CA70004ACC731808CA20008AA +:108BC00094A40002ACC231848CA3001C0460000396 +:108BD000A784009003E00008000000008CAF00189C +:108BE000ACCF31D08CAE001C03E00008ACCE31D449 +:108BF0008F8500588F87FF288F86FF308CAE00044A +:108C00003C0F601235E80010ACEE00788CAD000827 +:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 +:108C2000ACCB004894CA00543C0208008C4200447B +:108C300025490001A4C9005494C400543083FFFFA7 +:108C400010620017000000003C0208008C42004047 +:108C5000A4C200528CA30018ACE300308CA2001414 +:108C6000ACE2002C8CB90018ACF900388CB80014B8 +:108C700024050001ACF800348D0600BC50C5001975 +:108C80008D0200B48D0200B8A4E2004894E40048CC +:108C9000A4E4004A94E800EA03E000083102FFFF80 +:108CA0003C0208008C420024A4C00054A4C200521C +:108CB0008CA30018ACE300308CA20014ACE2002CB2 +:108CC0008CB90018ACF900388CB8001424050001E8 +:108CD000ACF800348D0600BC54C5FFEB8D0200B823 +:108CE0008D0200B4A4E2004894E40048A4E4004AE1 +:108CF00094E800EA03E000083102FFFF8F86005885 +:108D00003C0480008CC900088CC80008000929C0F8 +:108D1000000839C0AC87002090C30007306200040F +:108D20001040003EAF85009490CB0007316A0008E8 +:108D30001140003D8F87FF2C8CCD000C8CCE001491 +:108D400001AE602B11800036000000008CC2000CC8 +:108D5000ACE200708CCB00188F85FF288F88FF3025 +:108D6000ACEB00748CCA00102402FFF8ACAA00D847 +:108D70008CC9000CAD0900608CC4001CACA400D0F0 +:108D800090E3007C0062C824A0F9007C90D8000722 +:108D9000330F000811E000040000000090ED007C9B +:108DA00035AC0001A0EC007C90CF000731EE000153 +:108DB00011C000060000000090E3007C241800347D +:108DC00034790002A0F9007CACB800DC90C2000746 +:108DD0003046000210C000040000000090E8007C53 +:108DE00035040004A0E4007C90ED007D3C0B600E97 +:108DF000356A001031AC003FA0EC007D8D4931D4C4 +:108E00003127000110E00002240E0001A0AE00098D +:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 +:108E20000A000DAF8CC200140A000DB0ACE0007057 +:108E30008F8C005827BDFFD8AFB3001CAFB200180D +:108E4000AFB00010AFBF0020AFB10014918F00157C +:108E50003C13600E3673001031EB000FA38B009CA7 +:108E60008D8F00048D8B0008959F0012959900103E +:108E70009584001A9598001E958E001C33EDFFFF17 +:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 +:108E90003C010800AC2D00243C010800AC29004432 +:108EA0003C010800AC2A0040AE683178AE67317CE6 +:108EB00091850015959100163C12601236520010F3 +:108EC00030A200FF3230FFFFAE623188AE5000B4F6 +:108ED00091830014959F0018240600010066C804C1 +:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 +:108EF000AF8F00843C08600631CD00FFAE4D00C04E +:108F0000918A00159584000E3C07600A314900FFE4 +:108F1000AF8B00883084FFFFAE4900C835110010C8 +:108F20000E000D1034F004103C0208008C4200606A +:108F30003C0308008C6300643C0608008CC60058A3 +:108F40003C0508008CA5005C8F8400808FBF00204A +:108F5000AE23004CAE65319CAE030054AE4500DC40 +:108F6000AE6231A0AE6331A4AE663198AE22004845 +:108F70008FB3001CAE0200508FB10014AE4200E06F +:108F8000AE4300E4AE4600D88FB000108FB2001898 +:108F90000A00057D27BD0028978500929783007CF5 +:108FA00027BDFFE8AFB0001000A3102BAFBF001427 +:108FB000240400058F900058104000552409000239 +:108FC0000E0006958F850080AF8200942404000374 +:108FD0001040004F240900023C0680000E00008172 +:108FE000ACC2002024070001240820001040004DDE +:108FF00024040005978E00928F8AFF2C24090050CC +:1090000025C50001A7850092A14900003C0D08007C +:109010008DAD0064240380008F84FF28000D66005E +:10902000AD4C0018A5400006954B000A8F85FF3017 +:109030002402FF8001633024A546000A915F000AE4 +:109040000000482103E2C825A159000AA0A0000899 +:10905000A140004CA08000D5961800029783009094 +:109060003C020004A49800EA960F00022418FFBFF7 +:1090700025EE2401A48E00BE8E0D0004ACAD00448C +:109080008E0C0008ACAC0040A4A00050A4A000547A +:109090008E0B000C240C0030AC8B00288E060010C8 +:1090A000AC860024A480003EA487004EA487005014 +:1090B000A483003CAD420074AC8800D8ACA800602A +:1090C000A08700FC909F00D433F9007FA09900D4C2 +:1090D000909000D402187824A08F00D4914E007C88 +:1090E00035CD0001A14D007C938B009CAD480070F4 +:1090F000AC8C00DCA08B00D68F8800888F87008422 +:10910000AC8800C4AC8700C8A5400078A540007AB0 +:109110008FBF00148FB000100120102103E0000861 +:1091200027BD00188F8500940E0007258F860080CC +:109130000A000E9F2409000227BDFFE0AFB0001017 +:109140008F900058AFB10014AFBF00188E09000413 +:109150000E00054A000921C08E0800048F84FF28F4 +:109160008F82FF30000839C03C068000ACC7002069 +:10917000948500EA904300131460001C30B1FFFF97 +:109180008F8CFF2C918B0008316A00401540000B3A +:10919000000000008E0D0004022030218FBF001857 +:1091A0008FB100148FB00010240400220000382179 +:1091B000000D29C00A000D2F27BD00200E000098C9 +:1091C000000000008E0D0004022030218FBF001827 +:1091D0008FB100148FB00010240400220000382149 +:1091E000000D29C00A000D2F27BD00200E000090A1 +:1091F000000000008E0D0004022030218FBF0018F7 +:109200008FB100148FB00010240400220000382118 +:10921000000D29C00A000D2F27BD002027BDFFE04B +:10922000AFB200183092FFFFAFB00010AFBF001C0C +:10923000AFB100141240001E000080218F8600583C +:109240008CC500002403000600053F02000514023F +:1092500030E4000714830016304500FF2CA80006F8 +:1092600011000040000558803C0C0800258C58BCBB +:10927000016C50218D490000012000080000000011 +:109280008F8E0098240D000111CD005024020002A1 +:10929000AF820098260900013130FFFF24C800206A +:1092A0000212202B010030211480FFE5AF88005806 +:1092B000020010218FBF001C8FB200188FB1001464 +:1092C0008FB0001003E0000827BD00209387007EC8 +:1092D00054E00034000030210E000DE700000000D3 +:1092E0008F8600580A000EFF240200018F87009825 +:1092F0002405000210E50031240400130000282199 +:1093000000003021240700010E000D2F0000000096 +:109310000A000F008F8600588F83009824020002F5 +:109320001462FFF6240400120E000D9A00000000E3 +:109330008F85009400403021240400120E000D2F70 +:10934000000038210A000F008F8600588F83009894 +:109350002411000310710029241F0002107FFFCE8A +:1093600026090001240400100000282100003021FB +:109370000A000F1D240700018F91009824060002A7 +:109380001626FFF9240400100E000E410000000014 +:10939000144000238F9800588F8600580A000EFF53 +:1093A00024020003240400140E000D2F00002821C5 +:1093B0008F8600580A000EFF240200020E000EA93C +:1093C000000000000A000F008F8600580E000D3FBD +:1093D00000000000241900022404001400002821C9 +:1093E0000000302100003821AF9900980E000D2FA9 +:1093F000000000000A000F008F8600580E000D5775 +:10940000000000008F8500942419000200403021E4 +:1094100024040010000038210A000F56AF9900986C +:109420000040382124040010970F0002000028217A +:109430000E000D2F31E6FFFF8F8600580A000F0047 +:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D +:109450008C8500182402000100A61824AC83001893 +:1094600003E00008A08200053084FFFF30A5FFFF65 +:109470001080000700001821308200011040000217 +:1094800000042042006518211480FFFB00052840DD +:1094900003E000080060102110C000070000000079 +:1094A0008CA2000024C6FFFF24A50004AC820000AB +:1094B00014C0FFFB2484000403E000080000000047 +:1094C00010A0000824A3FFFFAC86000000000000ED +:1094D000000000002402FFFF2463FFFF1462FFFA74 +:1094E0002484000403E0000800000000000411C010 +:1094F00003E000082442024027BDFFE8AFB000109F +:1095000000808021AFBF00140E000F9600A0202124 +:1095100000504821240AFF808FBF00148FB0001034 +:10952000012A30243127007F3C08800A3C042100B6 +:1095300000E8102100C428253C03800027BD001846 +:10954000AC650024AF820038AC400000AC6500245C +:1095500003E00008AC4000403C0D08008DAD005811 +:1095600000056180240AFF8001A45821016C482174 +:10957000012A30243127007F3C08800C3C04210064 +:1095800000E8102100C428253C038000AC650028B9 +:10959000AF82003403E00008AC40002430A5FFFF98 +:1095A0003C0680008CC201B80440FFFE3C086015F8 +:1095B00000A838253C031000ACC40180ACC0018475 +:1095C000ACC7018803E00008ACC301B83C0D08003B +:1095D0008DAD005800056180240AFF8001A4582148 +:1095E000016C4021010A4824000931403107007F05 +:1095F00000C728253C04200000A418253C02800058 +:10960000AC43083003E00008AF80003427BDFFE81A +:10961000AFB0001000808021AFBF00140E000F9685 +:1096200000A0202100504821240BFF80012B502452 +:10963000000A39403128007F3C0620008FBF00140B +:109640008FB0001000E8282534C2000100A21825C0 +:109650003C04800027BD0018AC83083003E00008FC +:10966000AF8000383C0580088CA700603C0680086D +:109670000087102B144000112C8340008CA8006040 +:109680002D0340001060000F240340008CC90060CF +:109690000089282B14A00002008018218CC30060D0 +:1096A00000035A42000B30803C0A0800254A59202A +:1096B00000CA202103E000088C8200001460FFF340 +:1096C0002403400000035A42000B30803C0A08008B +:1096D000254A592000CA202103E000088C8200009E +:1096E0003C05800890A60008938400AB24C20001CA +:1096F000304200FF3043007F1064000C0002382726 +:10970000A0A200083C0480008C85017804A0FFFE24 +:109710008F8A00A0240900023C081000AC8A014096 +:10972000A089014403E00008AC8801780A00101BFE +:1097300030E2008027BDFFD8AFB200188F9200A49E +:10974000AFBF0020AFB3001CAFB00010AFB100142A +:109750008F9300348E5900283C1000803C0EFFEFA0 +:10976000AE7900008E580024A260000A35CDFFFFBC +:10977000AE7800049251002C3C0BFF9F356AFFFF2E +:10978000A271000C8E6F000C3C080040A271000B0F +:1097900001F06025018D4824012A382400E8302595 +:1097A000AE66000C8E450004AE6000183C0400FF5D +:1097B000AE6500148E43002C3482FFFFA6600008C3 +:1097C0000062F824AE7F00108E5900088F9000A030 +:1097D000964E0012AE7900208E51000C31D83FFF1A +:1097E00000187980AE7100248E4D001401F06021C4 +:1097F00031CB0001AE6D00288E4A0018000C41C22A +:10980000000B4B80AE6A002C8E46001C01093821EB +:10981000A667001CAE660030964500028E4400200C +:10982000A665001EAE64003492430033306200042B +:1098300054400006924700003C0280083443010077 +:109840008C7F00D0AE7F0030924700008F860038BA +:10985000A0C700309245003330A4000250800007BA +:10986000925100018F880038240BFF80910A00304C +:10987000014B4825A1090030925100018F9000381A +:10988000240CFFBF2404FFDFA21100318F8D0038AC +:109890003C1880083711008091AF003C31EE007F0A +:1098A000A1AE003C8F890038912B003C016C502404 +:1098B000A12A003C8F9F00388E68001493E6003C7C +:1098C0002D0700010007114000C4282400A218251C +:1098D000A3E3003C8F87003896590012A4F90032A8 +:1098E0008E450004922E007C30B0000300107823D7 +:1098F00031ED000300AD102131CC000215800002D3 +:1099000024460034244600303C0280083443008062 +:10991000907F007C00BFC824333800041700000289 +:1099200024C2000400C010218F98003824190002BE +:10993000ACE20034A3190000924F003F8F8E003834 +:109940003C0C8008358B0080A1CF00018F9100383E +:10995000924D003F8E440004A62D0002956A005CE3 +:109960000E000FF43150FFFF00024B800209382532 +:109970003C08420000E82825AE2500048E4400384B +:109980008F850038ACA400188E460034ACA6001CAD +:10999000ACA0000CACA00010A4A00014A4A0001661 +:1099A000A4A00020A4A00022ACA000248E62001479 +:1099B00050400001240200018FBF00208FB3001C23 +:1099C0008FB200188FB100148FB00010ACA2000845 +:1099D0000A00101327BD002827BDFFC83C058008DA +:1099E00034A40080AFBF0034AFBE0030AFB7002C4E +:1099F000AFB60028AFB50024AFB40020AFB3001C51 +:109A0000AFB20018AFB10014AFB00010948300786B +:109A10009482007A104300512405FFFF0080F0215A +:109A20000A0011230080B821108B004D8FBF003435 +:109A30008F8600A03C1808008F18005C2411FF805E +:109A40003C1680000306782101F18024AED0002C62 +:109A500096EE007A31EC007F3C0D800E31CB7FFF1B +:109A6000018D5021000B4840012AA82196A4000036 +:109A70003C0808008D0800582405FF8030953FFF02 +:109A800001061821001539800067C8210325F82434 +:109A90003C02010003E290253338007F3C11800C2A +:109AA000AED20028031190219250000D320F000415 +:109AB00011E0003702E0982196E3007A96E8007AF8 +:109AC00096E5007A2404800031077FFF24E300013B +:109AD00030627FFF00A4F82403E2C825A6F9007ACB +:109AE00096E6007A3C1408008E94006030D67FFF22 +:109AF00012D400C1000000008E5800188F8400A00E +:109B000002A028212713FFFF0E000FCEAE53002C1A +:109B100097D5007897D4007A12950010000028217C +:109B20003C098008352401003C0A8008914800085F +:109B3000908700D53114007F30E400FF0284302B81 +:109B400014C0FFB9268B0001938E00AB268C000158 +:109B5000008E682115ACFFB78F8600A08FBF003440 +:109B60008FBE00308FB7002C8FB600288FB5002431 +:109B70008FB400208FB3001C8FB200188FB1001477 +:109B80008FB0001000A0102103E0000827BD0038AE +:109B900000C020210E000F99028028218E4B00105A +:109BA0008E4C00308F84003824090002016C502351 +:109BB000AE4A0010A089000096E3005C8E4400309D +:109BC0008F9100380E000FF43070FFFF00024380C9 +:109BD000020838253C02420000E22825AE25000498 +:109BE0008E5F00048F8A00388E590000240B000815 +:109BF000AD5F001CAD590018AD40000CAD40001029 +:109C00009246000A240400052408C00030D000FF5A +:109C1000A550001496580008A55800169251000A45 +:109C20003C188008322F00FFA54F0020964E0008F8 +:109C300037110100A54E0022AD400024924D000BCB +:109C400031AC00FFA54C0002A14B00018E49003051 +:109C50008F830038240BFFBFAC690008A06400307C +:109C60008F9000382403FFDF9607003200E8282495 +:109C700000B51025A6020032921F003233F9003FD2 +:109C800037260040A20600328F8C0038AD800034A9 +:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F +:109CA00031CD007FA18D003C8F84003835EEFFFF61 +:109CB000908A003C014B4824A089003C8F850038E5 +:109CC00090A8003C01033824A0A7003C8E42003439 +:109CD0008F9100383C038008AE2200408E59002C42 +:109CE0008E5F0030033F3023AE26004492300048A0 +:109CF0003218007FA23800488F8800388E4D00301F +:109D00008D0C004801AE582401965024014B482583 +:109D1000AD0900489244000AA104004C964700088F +:109D20008F850038A4A7004E8E5000308E4400303E +:109D30000E0003818C65006092F9007C0002F940FE +:109D4000004028210002110003E2302133360002D6 +:109D500012C00003020680210005B0800216802197 +:109D6000926D007C31B30004126000020005708027 +:109D7000020E80218E4B00308F8800382405800031 +:109D8000316A0003000A4823312400030204182129 +:109D9000AD03003496E4007A96F0007A96F1007AEA +:109DA00032027FFF2447000130FF7FFF0225C824D5 +:109DB000033F3025A6E6007A96F8007A3C120800A8 +:109DC0008E520060330F7FFF11F200180000000078 +:109DD0008F8400A00E000FCE02A028218F8400A047 +:109DE0000E000FDE028028210E001013000000007C +:109DF0000A00111F0000000096F1007A022480245E +:109E0000A6F0007A92EF007A92EB007A31EE00FF32 +:109E1000000E69C2000D6027000C51C03169007F3F +:109E2000012A20250A001119A2E4007A96E6007A98 +:109E300000C5C024A6F8007A92EF007A92F3007A67 +:109E400031F200FF001271C2000E6827000DB1C090 +:109E5000326C007F01962825A2E5007A0A0011D015 +:109E60008F8400A03C0380003084FFFF30A5FFFFFB +:109E7000AC640018AC65001C03E000088C620014A0 +:109E800027BDFFA03C068008AFBF005CAFBE0058F6 +:109E9000AFB70054AFB60050AFB5004CAFB40048F8 +:109EA000AFB30044AFB20040AFB1003CAFB0003838 +:109EB00034C80100910500D590C700083084FFFF29 +:109EC00030A500FF30E2007F0045182AAFA4001043 +:109ED000A7A00018A7A0002610600055AFA000148E +:109EE00090CA00083149007F00A9302324D3FFFF26 +:109EF0000013802B8FB400100014902B02128824C2 +:109F0000522000888FB300143C03800894790052DB +:109F1000947E00508FB60010033EC0230018BC0092 +:109F2000001714030016FC0002C2A82A16A00002A3 +:109F3000001F2C030040282100133C0000072403CD +:109F400000A4102A5440000100A020212885000907 +:109F500014A000020080A021241400083C0C8008FA +:109F60008D860048001459808D88004C3C03800089 +:109F70003169FFFF3C0A0010012A202534710400DA +:109F8000AC660038AF9100A4AC68003CAC64003013 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB0008C6E000031CD002011A0FFFD0014782A26 +:109FC00001F01024104000390000A8213C16800840 +:109FD00092D700083C1280008E44010032F6007FC8 +:109FE0000E000F9902C028218E3900108E44010006 +:109FF0000000902133373FFF0E000FB102E028210F +:10A00000923800003302003F2C500008520000102C +:10A0100000008821000210803C030800246358E4FB +:10A020000043F8218FFE000003C00008000000007C +:10A0300090CF0008938C00AB31EE007F00AE682318 +:10A04000018D58210A0012172573FFFF0000882197 +:10A050003C1E80008FC401000E000FCE02E02821BC +:10A060008FC401000E000FDE02C028211220000F55 +:10A070000013802B8F8B00A426A400010004AC00E9 +:10A08000027298230015AC032578004002B4B02A70 +:10A090000013802B241700010300882102D0102414 +:10A0A000AF9800A41440FFC9AFB700143C07800864 +:10A0B00094E200508FAE00103C05800002A288217F +:10A0C0003C060020A4F10050ACA6003094F40050EF +:10A0D00094EF005201D51823306CFFFF11F4001EDD +:10A0E000AFAC00108CEF004C001561808CF500487F +:10A0F00001EC28210000202100AC582B02A4C02133 +:10A10000030BB021ACE5004CACF600488FB4001056 +:10A110000014902B021288241620FF7C3C03800838 +:10A120008FB300148FBF005C8FBE00583A620001ED +:10A130008FB700548FB600508FB5004C8FB40048D5 +:10A140008FB300448FB200408FB1003C8FB0003815 +:10A1500003E0000827BD006094FE00548CF2004428 +:10A1600033C9FFFE0009C8C00259F821ACBF003C4A +:10A170008CE800448CAD003C010D50231940003B9D +:10A18000000000008CF7004026E20001ACA200387D +:10A190003C05005034A700103C038000AC67003041 +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C0008C7800003316002012C0FFFD3C1180087F +:10A1D000962200543C1580003C068008304E000159 +:10A1E000000E18C0007578218DEC04003C070800B3 +:10A1F0008CE700443C040020ACCC00488DF40404FF +:10A20000240B0001ACD4004C10EB0260AEA4003073 +:10A21000963900523C0508008CA5004000B99021F9 +:10A22000A6320052963F005427ED0001A62D00549F +:10A230009626005430C4FFFF5487FF2F8FB40010C0 +:10A2400030A5FFFF0E0011F4A62000543C070800C3 +:10A250008CE70024963E00520047B82303D74823DA +:10A26000A62900520A0012198FB400108CE2004097 +:10A270000A0012BE00000000922400012407000121 +:10A280003085007F14A7001C97AD00268E2B00148C +:10A29000240CC000316A3FFF01AC48243C06080092 +:10A2A0008CC60060012A402531043FFF0086882BC0 +:10A2B00012200011A7A800263C0508008CA5005814 +:10A2C0008F9100A0000439802402FF8000B1182182 +:10A2D0000067F82103E2F02433F8007F3C1280008D +:10A2E0003C19800EAE5E002C0319702191D0000D38 +:10A2F000360F0004A1CF000D0E001028241200011B +:10A30000241100013C1E80008FC401000E000FCEFE +:10A3100002E028218FC401000E000FDE02C02821B8 +:10A320001620FF558F8B00A40A0012860013802B85 +:10A330008F8600A490C80001310400201080019194 +:10A34000241000013C048008348B0080916A007C5A +:10A350008F9E0034AFA0002C314900011120000F66 +:10A36000AFB000288CCD00148C8E006001AE602B45 +:10A370001580000201A038218C8700603C188008FD +:10A38000370300808C70007000F0782B15E000021D +:10A3900000E020218C640070AFA4002C3C028008F7 +:10A3A000344500808CD200148CBF0070025FC82B33 +:10A3B00017200002024020218CA400708FA7002CDF +:10A3C0000087182310600003AFA3003024050002AB +:10A3D000AFA500288FA400280264882B162000BA9D +:10A3E000000018218CD000388FCE000C3C0F00806C +:10A3F000AFD000008CCD00343C0CFF9F01CF58251E +:10A40000AFCD000490CA003F3586FFFF01662024CF +:10A410003C0900203C08FFEFA3CA000B0089382547 +:10A420003511FFFF00F118243C0500088F8700A4B8 +:10A430000065C825AFD9000C8CE20014AFC000182D +:10A440008FA60030AFC200148CF800188FB0002C1B +:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A +:10A4600003326824AFCF00248CEC000C020670216C +:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B +:10A48000AFCC0020AFC000288CEA00148FAB002CAA +:10A49000014B48230126402311000011AFC80010D2 +:10A4A00090EB003D8FC900048FC80000000B5100E5 +:10A4B000012A28210000102100AA882B010218215E +:10A4C0000071F821AFC50004AFDF000090F2003D3D +:10A4D000A3D2000A8F9900A497380006A7D80008D5 +:10A4E0008F910038240800023C038008A228000055 +:10A4F0003465008094BF005C8FA4002C33F0FFFF14 +:10A500000E000FF48F9200380002CB808F8500A4DC +:10A51000021978253C18420001F87025AE4E00045F +:10A520008F8400388CAD0038AC8D00188CAC0034B2 +:10A53000AC8C001CAC80000CAC800010A48000141B +:10A54000A4800016A4800020A4800022AC800024F7 +:10A5500090A6003F8FA7002CA486000250E0019235 +:10A56000240700018FA200305040000290A2003D5D +:10A5700090A2003E244A0001A08A00018F84003886 +:10A580008FA9002CAC8900083C128008364D008051 +:10A5900091AC007C3186000214C000022407003414 +:10A5A000240700308F8500A43C198008373F0080C5 +:10A5B00090B0000093F9007C240E0004A0900030BD +:10A5C0008F8F00A48FB8002C8F8D003891F200017E +:10A5D0003304000301C46023A1B200318F8E003820 +:10A5E0008F8600A42402C00095CA003294C90012CC +:10A5F0008FAB002C0142402431233FFF010388250B +:10A60000A5D1003291D000323185000300EBF82152 +:10A610003218003F370F0040A1CF00328FA4002C2A +:10A6200003E5382133280004108000028F850038AC +:10A6300000E838213C0A8008ACA700343549010005 +:10A640008D2800D08FA3002C2419FFBFACA80038A0 +:10A6500090B1003C2C640001240FFFDF3227007F03 +:10A66000A0A7003C8F98003800049140931F003C45 +:10A6700003F98024A310003C8F8C0038918E003C9D +:10A6800001CF682401B23025A186003C8F8900A447 +:10A690008F8800388D2B0020AD0B00408D220024C8 +:10A6A000AD0200448D2A0028AD0A00488D23002CFD +:10A6B0000E001013AD03004C8FB1002824070002D8 +:10A6C000122700118FA300280003282B00058023E8 +:10A6D0000270982400608021006090210A00126FAF +:10A6E0000010882B962900128F8400A00000902172 +:10A6F0003125FFFFA7A900180E000FC22411000189 +:10A700000A00131D3C1E80003C0B80003C12800898 +:10A710008D640100924900088F92FF340E000F995A +:10A720003125007F8F9900388FA700288FA4003033 +:10A73000A3270000965F005C33F0FFFF0E000FF4CC +:10A740008F91003800026B80020D80253C0842008A +:10A750008F8D00A402085025AE2A00048DA5003874 +:10A760008F8A003800007821000F1100AD450018D5 +:10A770008DB800343C047FFF3488FFFFAD58001CC7 +:10A7800091A6003E8D4C001C8D4900180006190052 +:10A79000000677020183C821004E58250323882B29 +:10A7A000012B382100F1F821AD59001CAD5F0018D4 +:10A7B000AD40000CAD40001091B0003E8FA40030C1 +:10A7C00024090005A550001495A500042419C00013 +:10A7D00000884024A545001691B8003EA5580020E9 +:10A7E00095AF0004A54F0022AD40002491AE003F7C +:10A7F000A54E000291A6003E91AC003D01861023BB +:10A80000244B0001A14B00018F9100388FA3003031 +:10A810003C028008344B0100AE230008A22900301E +:10A820008F8C00388F8700A4959F003294F000121F +:10A830002407FFBF033FC02432053FFF03057825EF +:10A84000A58F0032918E00322418FFDF31CD003FFA +:10A8500035A60040A18600328F910038240DFFFFFD +:10A86000240CFF80AE2000348D6A00D0AE2A003860 +:10A870009223003C3069007FA229003C8F90003871 +:10A880003C0380009219003C0327F824A21F003CDF +:10A890008F8E003891C5003C00B87824A1CF003CD1 +:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA +:10A8B000AD46004491420048004C5825A14B004849 +:10A8C0008F9000388F9900A48E09004801238824B6 +:10A8D00002283825AE070048933F003EA21F004CD7 +:10A8E0008F9800A48F8F003897050004A5E5004ECF +:10A8F0000E0003818DC500609246007C8FAC003055 +:10A9000000026940000291000040282130CB000283 +:10A9100001B21021156000AA018230213C0E80088E +:10A9200035C20080904C007C31830004106000032D +:10A930008FB900300005788000CF3021241F00043B +:10A940008F910038332D000303ED8023320800037C +:10A9500000C85021AE2A00343C188000A7C500383A +:10A960003C0680088F04010090DE00080E000FDE18 +:10A9700033C5007F0E001013000000000A00140D04 +:10A980008FA300288F9800348CC90038241F00033F +:10A99000A7000008AF0900008CC50034A300000A1E +:10A9A0008F9900A4AF0500043C080080932D003F60 +:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D +:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E +:10A9D00003D170243646FFFF01C61824AF03000CD4 +:10A9E0008F2C0014972900128F8400A0AF0C001048 +:10A9F0008F2F0014AF000018AF000020AF0F00141D +:10AA0000AF0000248F270018312F3FFF000F59801F +:10AA1000AF0700288F2500080164F821312D0001BF +:10AA2000AF0500308F31000C8F920038001F51C2EB +:10AA3000000D438001481021241E00023C068008BE +:10AA4000A702001CA7000034AF11002CA25E00007A +:10AA500034D20080964E005C8F9900383C0342004F +:10AA600031CCFFFF01833825AF2700048F8B00A472 +:10AA7000240500012402C0008D640038240700343E +:10AA8000AF2400188D690034AF29001CAF20000CE2 +:10AA9000AF200010A7200014A7200016A720002038 +:10AAA000A7200022AF200024A7300002A325000128 +:10AAB0008F8800388F9F00A4AD10000893ED000030 +:10AAC000A10D00308F8A00A48F98003891510001A9 +:10AAD000A31100318F8B0038957E003203C27024A1 +:10AAE00001CF6025A56C0032916300323064003FD5 +:10AAF000A16400329249007C3125000214A00002BA +:10AB00008F840038240700303C198008AC8700345B +:10AB1000373201008E5F00D0240AFFBF020090216F +:10AB2000AC9F0038908D003C31A8007FA088003C8D +:10AB30008F9E003893C2003C004A8824A3D1003C79 +:10AB40008F8300380010882B9066003C34CE0020A4 +:10AB5000A06E003C8F8400A48F9800388C8C00205D +:10AB6000AF0C00408C8F0024AF0F00448C8700286E +:10AB7000AF0700488C8B002CAF0B004C0E0010135D +:10AB80003C1E80000A0012700000000094C80052B1 +:10AB90003C0A08008D4A002401488821A4D10052B3 +:10ABA0000A0012198FB40010A08700018F840038AA +:10ABB000240B0001AC8B00080A0013BE3C12800875 +:10ABC000000520800A0014A200C4302127BDFFE048 +:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 +:10ABE000AFB1001435B200808E4C001835A80100BA +:10ABF000964B000695A70050910900FC000C5602E8 +:10AC0000016728233143007F312600FF240200031F +:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC +:10AC2000910600FC2412000530C200FF10520033D0 +:10AC300000000000160000098FBF001C8FB2001832 +:10AC40008FB100148FB00010240D0C003C0C80005C +:10AC500027BD002003E00008AD8D00240E0011FB8D +:10AC6000020020218FBF001C8FB200188FB100148A +:10AC70008FB00010240D0C003C0C800027BD00207C +:10AC800003E00008AD8D0024965800789651007AB4 +:10AC9000924E007D0238782631E8FFFF31C400C0B3 +:10ACA000148000092D11000116000037000000007B +:10ACB0005620FFE28FBF001C0E0010D100000000E4 +:10ACC0000A00156A8FBF001C1620FFDA0000000082 +:10ACD0000E0010D1000000001440FFD88FBF001CF0 +:10ACE0001600002200000000925F007D33E2003F6A +:10ACF000A242007D0A00156A8FBF001C950900EA78 +:10AD00008F86008000802821240400050E0007257E +:10AD10003130FFFF978300923C0480002465FFFFE1 +:10AD2000A78500928C8A01B80540FFFE0000000054 +:10AD3000AC8001808FBF001CAC9001848FB20018E2 +:10AD40008FB100148FB000103C0760133C0B100053 +:10AD5000240D0C003C0C800027BD0020AC8701882E +:10AD6000AC8B01B803E00008AD8D00240E0011FB90 +:10AD7000020020215040FFB18FBF001C925F007D78 +:10AD80000A00159733E2003F0E0011FB020020215C +:10AD90001440FFAA8FBF001C122000070000000013 +:10ADA0009259007D3330003F36020040A242007DC0 +:10ADB0000A00156A8FBF001C0E0010D100000000B1 +:10ADC0005040FF9E8FBF001C9259007D3330003FE2 +:08ADD0000A0015C6360200401E +:08ADD800000000000000001B58 +:10ADE0000000000F0000000A00000008000000063C +:10ADF0000000000500000005000000040000000441 +:10AE00000000000300000003000000030000000336 +:10AE10000000000300000002000000020000000229 +:10AE2000000000020000000200000002000000021A +:10AE3000000000020000000200000002000000020A +:10AE400000000002000000020000000200000002FA +:0CAE5000000000010000000100000001F3 +:04AE5C008008010069 +:10AE6000800800808008000000000C000000308096 +:10AE7000080011D00800127C08001294080012A8E3 +:10AE8000080012BC080011D0080011D0080012F010 +:10AE90000800132C080013400800138808001A8CBF +:10AEA00008001A8C08001AC408001AC408001AD82E +:10AEB00008001AA808001D0008001CCC08001D5836 +:10AEC00008001D5808001DE008001D108008024001 +:10AED000080027340800256C0800275C080027F4C8 +:10AEE0000800293C0800298808002AAC080029B479 +:10AEF00008002A38080025DC08002EDC08002EA4F3 +:10AF000008002588080025880800258808002B20CF +:10AF100008002B20080025880800258808002DD06F +:10AF2000080025880800258808002588080025884D +:10AF300008002E0C080025880800258808002588B0 +:10AF4000080025880800258808002588080025882D +:10AF5000080025880800258808002588080025881D +:10AF6000080025880800258808002588080029A8E9 +:10AF7000080025880800258808002E680800258814 +:10AF800008002588080025880800258808002588ED +:10AF900008002588080025880800258808002588DD +:10AFA00008002588080025880800258808002588CD +:10AFB00008002588080025880800258808002588BD +:10AFC00008002CF4080025880800258808002C6853 +:10AFD00008002BC408003CE408003CB808003C848E +:10AFE00008003C5808003C3808003BEC8008010091 +:10AFF00080080080800800008008008008004C6401 +:10B0000008004C9C08004BE408004C6408004C64A9 +:0CB01000080049B808004C6408005050CB +:04B01C000A000C8496 +:10B0200000000000000000000000000D7278703683 +:10B030002E322E3100000000060201030000000045 +:10B0400000000001000000000000000000000000FF +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000809F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E220000000000A000000000000000000000000E4 +:10E2300010000003000000000000000D0000000DB1 +:10E240003C020801244296603C0308012463989C28 +:10E25000AC4000000043202B1480FFFD244200044A +:10E260003C1D080037BD9FFC03A0F0213C100800B6 +:10E27000261032103C1C0801279C96600E0012BE2E +:10E28000000000000000000D3C02800030A5FFFFF0 +:10E2900030C600FF344301803C0880008D0901B87E +:10E2A0000520FFFE00000000AC6400002404000212 +:10E2B000A4650008A066000AA064000BAC67001803 +:10E2C0003C03100003E00008AD0301B83C0560000A +:10E2D0008CA24FF80440FFFE00000000ACA44FC029 +:10E2E0003C0310003C040200ACA44FC403E000084F +:10E2F000ACA34FF89486000C00A050212488001491 +:10E3000000062B0200051080004448210109182B4B +:10E310001060001100000000910300002C6400094F +:10E320005080000991190001000360803C0D080134 +:10E3300025AD92F8018D58218D67000000E000089E +:10E340000000000091190001011940210109302B42 +:10E3500054C0FFF29103000003E000080000102108 +:10E360000A000CCC25080001910F0001240E000AC0 +:10E3700015EE00400128C8232F38000A1700003D81 +:10E38000250D00028D580000250F0006370E0100F4 +:10E39000AD4E0000910C000291AB000191A400026F +:10E3A00091A60003000C2E00000B3C0000A71025D6 +:10E3B00000041A000043C8250326C025AD580004F8 +:10E3C000910E000691ED000191E7000291E5000336 +:10E3D000000E5E00000D6400016C30250007220075 +:10E3E00000C41025004518252508000A0A000CCC99 +:10E3F000AD430008910F000125040002240800022B +:10E4000055E80001012020210A000CCC00804021A9 +:10E41000910C0001240B0003158B00160000000076 +:10E420008D580000910E000225080003370D0008EA +:10E43000A14E00100A000CCCAD4D00009119000156 +:10E44000240F0004172F000B0000000091070002AA +:10E45000910400038D43000000072A0000A410254A +:10E460003466000425080004AD42000C0A000CCC00 +:10E47000AD46000003E000082402000127BDFFE8CC +:10E48000AFBF0014AFB000100E00167F00808021D7 +:10E490003C0480083485008090A600052403FFFE1C +:10E4A0000200202100C310248FBF00148FB0001081 +:10E4B000A0A200050A00168927BD001827BDFFE8A5 +:10E4C000AFB00010AFBF00140E000FD40080802149 +:10E4D0003C06800834C5008090A40000240200504F +:10E4E000308300FF106200073C09800002002021F9 +:10E4F0008FBF00148FB00010AD2001800A00108F74 +:10E5000027BD0018240801003C07800002002021DC +:10E510008FBF00148FB00010ACE801800A00108F8C +:10E5200027BD001827BDFF783C058008AFBE0080DE +:10E53000AFB7007CAFB3006CAFB10064AFBF008475 +:10E54000AFB60078AFB50074AFB40070AFB200687A +:10E55000AFB0006034A600803C0580008CB201287A +:10E5600090C400098CA701043C020001309100FF17 +:10E5700000E218240000B8210000F021106000071C +:10E58000000098213C0908008D2931F02413000176 +:10E59000252800013C010800AC2831F0ACA0008423 +:10E5A00090CC0005000C5827316A0001154000721C +:10E5B000AFA0005090CD00002406002031A400FF41 +:10E5C00010860018240E0050108E009300000000EA +:10E5D0003C1008008E1000DC260F00013C010800F2 +:10E5E000AC2F00DC0E0016F80000000000401821DF +:10E5F0008FBF00848FBE00808FB7007C8FB60078FD +:10E600008FB500748FB400708FB3006C8FB2006848 +:10E610008FB100648FB000600060102103E000083B +:10E6200027BD00880000000D3C1F8000AFA0003017 +:10E6300097E501168FE201043C04002030B9FFFF8A +:10E64000004438240007182B00033140AFA60030E7 +:10E650008FF5010437F80C003C1600400338802188 +:10E6600002B6A02434C40040128000479215000D69 +:10E6700032A800201500000234860080008030217E +:10E6800014C0009FAFA600303C0D800835A6008066 +:10E6900090CC0008318B0040516000063C06800899 +:10E6A000240E0004122E00A8240F0012122F003294 +:10E6B0003C06800834C401003C0280009447011AE3 +:10E6C0009619000E909F00088E18000830E3FFFF97 +:10E6D00003F9B00432B40004AFB6005CAFA3005835 +:10E6E0008E1600041280002EAFB8005434C3008090 +:10E6F000906800083105004014A0002500000000CB +:10E700008C70005002D090230640000500000000ED +:10E710008C71003402D1A82306A201678EE20008A2 +:10E72000126000063C1280003C1508008EB531F4E2 +:10E7300026B600013C010800AC3631F4AE4000447E +:10E74000240300018FBF00848FBE00808FB7007C40 +:10E750008FB600788FB500748FB400708FB3006CE3 +:10E760008FB200688FB100648FB00060006010212C +:10E7700003E0000827BD00880E000D2800002021BE +:10E780000A000D75004018210A000D9500C02021D7 +:10E790000E00174802C020211440FFE100000000D5 +:10E7A0003C0B8008356400808C8A003402CA482300 +:10E7B0000520001D000000003C1E08008FDE310017 +:10E7C00027D700013C010800AC3731001260000679 +:10E7D000024020213C1408008E9431F42690000160 +:10E7E0003C010800AC3031F40E00167F3C1E80085E +:10E7F00037CD008091B700250240202136EE00047D +:10E800000E001689A1AE00250E000CAC024020219E +:10E810000A000DCA240300013C17080126F797607F +:10E820000A000D843C1F80008C86003002C66023E5 +:10E830001980000C2419000C908F004F3C14080024 +:10E840008E94310032B500FC35ED0001268E0001BA +:10E850003C010800AC2E3100A08D004FAFA0005845 +:10E860002419000CAFB900308C9800300316A02397 +:10E870001A80010B8FA300580074F82A17E0FFD309 +:10E88000000000001074002A8FA5005802D4B021A7 +:10E8900000B410233044FFFFAFA4005832A8000298 +:10E8A0001100002E32AB00103C15800836B00080FD +:10E8B0009216000832D30040526000FB8EE200083E +:10E8C0000E00167F02402021240A0018A20A000927 +:10E8D000921100052409FFFE024020210229902404 +:10E8E0000E001689A2120005240400390000282118 +:10E8F0000E001723240600180A000DCA2403000185 +:10E9000092FE000C3C0A800835490080001EBB00C6 +:10E910008D27003836F10081024020213225F08118 +:10E920000E000C9B30C600FF0A000DC10000000065 +:10E930003AA7000130E300011460FFA402D4B02123 +:10E940000A000E1D00000000024020210E00176585 +:10E95000020028210A000D75004018211160FF7087 +:10E960003C0F80083C0D800835EE00808DC40038D7 +:10E970008FA300548DA60004006660231D80FF68ED +:10E98000000000000064C02307020001AFA400548F +:10E990003C1F08008FFF31E433F9000113200015FC +:10E9A0008FAC00583C07800094E3011A10600012FD +:10E9B0003C0680080E002192024020213C03080101 +:10E9C00090639791306400021480014500000000BC +:10E9D000306C0004118000078FAC0058306600FBDB +:10E9E0003C010801A026979132B500FCAFA0005869 +:10E9F0008FAC00583C06800834D30080AFB40018B8 +:10EA0000AFB60010AFAC00143C088000950B01209D +:10EA10008E6F0030966A005C8FA3005C8FBF003061 +:10EA20003169FFFF3144FFFF8FAE005401341021E4 +:10EA3000350540000064382B0045C82103E7C02598 +:10EA4000AFB90020AFAF0028AFB80030AFAF00249F +:10EA5000AFA0002CAFAE0034926D000831B40008B6 +:10EA6000168000BB020020218EE200040040F8095D +:10EA700027A400108FAF003031F300025660000170 +:10EA800032B500FE3C048008349F008093F90008F2 +:10EA900033380040530000138FA400248C850004F9 +:10EAA0008FA7005410A700D52404001432B0000131 +:10EAB0001200000C8FA400242414000C1234011A3C +:10EAC0002A2D000D11A001022413000E240E000AAD +:10EAD000522E0001241E00088FAF002425E40001FF +:10EAE000AFA400248FAA00143C0B80083565008079 +:10EAF000008A48218CB10030ACA9003090A4004EAF +:10EB00008CA700303408FFFC0088180400E3F821CB +:10EB1000ACBF00348FA600308FB900548FB8005CB2 +:10EB200030C200081040000B033898218CAC002044 +:10EB3000119300D330C600FF92EE000C8FA7003473 +:10EB400002402021000E6B0035B400800E000C9BAB +:10EB50003285F0803C028008345000808E0F0030F7 +:10EB600001F1302318C00097264800803C070800B8 +:10EB70008CE731E42404FF80010418243118007F5D +:10EB80003C1F80003C19800430F10001AFE300908D +:10EB900012200006031928213C0308019063979175 +:10EBA00030690008152000C6306A00F73C10800864 +:10EBB00036040080908C004F318B000115600042BC +:10EBC000000000003C0608008CC6319830CE0010D2 +:10EBD00051C0004230F9000190AF006B55E0003F9A +:10EBE00030F9000124180001A0B8006B3C1180002E +:10EBF0009622007A24470064A48700123C0D800806 +:10EC000035A5008090B40008329000401600000442 +:10EC10003C03800832AE000115C0008B00000000EC +:10EC2000346400808C86002010D3000A3463010015 +:10EC30008C67000002C7782319E000978FBF00544B +:10EC4000AC93002024130001AC760000AFB3005059 +:10EC5000AC7F000417C0004E000000008FA90050D8 +:10EC60001520000B000000003C0308019063979101 +:10EC7000306A00011140002E8FAB0058306400FE56 +:10EC80003C010801A02497910A000D75000018218D +:10EC90000E000CAC024020210A000F1300000000FF +:10ECA0000A000E200000A0210040F80924040017EB +:10ECB0000A000DCA240300010040F80924040016CC +:10ECC0000A000DCA240300019094004F240DFFFE9A +:10ECD000028D2824A085004F30F900011320000682 +:10ECE0003C0480083C03080190639791307F00103A +:10ECF00017E00051306800EF34900080240A0001D2 +:10ED0000024020210E00167FA60A00129203002561 +:10ED100024090001AFA90050346200010240202103 +:10ED20000E001689A20200250A000EF93C0D80088B +:10ED30001160FE83000018218FA5003030AC000464 +:10ED40001180FE2C8FBF00840A000DCB240300012C +:10ED500027A500380E000CB6AFA000385440FF4382 +:10ED60008EE200048FB40038329001005200FF3F61 +:10ED70008EE200048FA3003C8E6E0058006E682364 +:10ED800005A3FF39AE6300580A000E948EE200041A +:10ED90000E00167F024020213C038008346800806A +:10EDA000024020210E001689A11E000903C0302157 +:10EDB000240400370E001723000028210A000F1139 +:10EDC0008FA900508FAB00185960FF8D3C0D800853 +:10EDD0000E00167F02402021920C00252405000120 +:10EDE000AFA5005035820004024020210E00168994 +:10EDF000A20200250A000EF93C0D800812240059D9 +:10EE00002A2300151060004D240900162408000C68 +:10EE10005628FF2732B000013C0A8008914C001BA5 +:10EE20002406FFBD241E000E01865824A14B001BA2 +:10EE30000A000EA532B000013C010801A0289791FC +:10EE40000A000EF93C0D80088CB500308EFE0008DB +:10EE50002404001826B6000103C0F809ACB600303F +:10EE60003C030801906397913077000116E0FF8121 +:10EE7000306A00018FB200300A000D753243000481 +:10EE80003C1080009605011A50A0FF2B34C60010DC +:10EE90000A000EC892EE000C8C6200001456FF6D42 +:10EEA000000000008C7800048FB9005403388823D8 +:10EEB0000621FF638FBF00540A000F0E0000000000 +:10EEC0003C010801A02A97910A000F3030F9000197 +:10EED0001633FF028FAF00240A000EB0241E00106C +:10EEE0000E00167F024020213C0B80083568008010 +:10EEF00091090025240A0001AFAA0050353300040F +:10EF0000024020210E001689A11300253C050801AE +:10EF100090A5979130A200FD3C010801A022979195 +:10EF20000A000E6D004018212411000E53D1FEEA94 +:10EF3000241E00100A000EAF241E00165629FEDC07 +:10EF400032B000013C0A8008914C001B2406FFBD32 +:10EF5000241E001001865824A14B001B0A000EA598 +:10EF600032B000010A000EA4241E00123C038000EF +:10EF70008C6201B80440FFFE24040800AC6401B8B0 +:10EF800003E000080000000030A5FFFF30C6FFFFCF +:10EF90003C0780008CE201B80440FFFE34EA0180A7 +:10EFA000AD440000ACE400203C0480089483004899 +:10EFB0003068FFFF11000016AF88000824AB001274 +:10EFC000010B482B512000133C04800034EF01005A +:10EFD00095EE00208F890000240D001A31CCFFFF30 +:10EFE00031274000A14D000B10E000362583FFFEC5 +:10EFF0000103C02B170000348F9900048F88000490 +:10F00000A5430014350700010A001003AF87000470 +:10F010003C04800024030003348201808F890000B7 +:10F020008F870004A043000B3C088000350C018052 +:10F03000A585000EA585001A8F85000C30EB800099 +:10F04000A5890010AD850028A58600081160000F75 +:10F050008F85001435190100972A00163158FFFCDE +:10F06000270F000401E870218DCD400031A6FFFF7D +:10F0700014C000072403BFFF3C02FFFF34487FFF9A +:10F0800000E83824AF8700048F8500142403BFFFF5 +:10F090003C04800000E3582434830180A46B0026E4 +:10F0A000AC69002C10A0000300054C02A465001000 +:10F0B000A46900263C071000AC8701B803E00008F3 +:10F0C000000000008F990004240AFFFE032A382460 +:10F0D0000A001003AF87000427BDFFE88FA20028B5 +:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99 +:10F0F000AF820014AF8000040E000FDBAF80000071 +:10F100008FBF001027BD001803E00008AF80001477 +:10F110003C06800034C4007034C701008C8A0000B3 +:10F1200090E500128F84000027BDFFF030A300FFA0 +:10F13000000318823082400010400037246500032D +:10F140000005C8800326C0218F0E4000246F0004F4 +:10F15000000F6880AFAE000001A660218D8B4000DB +:10F16000AFAB000494E900163128FFFC01063821FA +:10F170008CE64000AFA600088FA9000800003021EF +:10F18000000028213C07080024E701000A0010675E +:10F19000240800089059000024A500012CAC000CA4 +:10F1A0000079C0210018788001E770218DCD000022 +:10F1B0001180000600CD302603A5102114A8FFF50C +:10F1C00000051A005520FFF4905900003C0480000F +:10F1D000348700703C0508008CA531048CE30000E6 +:10F1E0002CA2002010400009006A38230005488046 +:10F1F0003C0B0800256B3108012B402124AA00019B +:10F20000AD0700003C010800AC2A310400C0102109 +:10F2100003E0000827BD0010308220001040000BE2 +:10F2200000055880016648218D24400024680004B0 +:10F2300000083880AFA4000000E618218C6540006B +:10F24000AFA000080A001057AFA500040000000D91 +:10F250000A0010588FA9000827BDFFE03C07800076 +:10F2600034E60100AFBF001CAFB20018AFB100140C +:10F27000AFB0001094C5000E8F87000030A4FFFFD0 +:10F280002483000430E2400010400010AF83002CC3 +:10F290003C09002000E940241100000D30EC800002 +:10F2A0008F8A0004240BBFFF00EB38243543100085 +:10F2B000AF87000030F220001640000B3C1900041C +:10F2C000241FFFBF0A0010B7007F102430EC80001D +:10F2D000158000423C0E002030F220001240FFF862 +:10F2E0008F8300043C19000400F9C0241300FFF5CB +:10F2F000241FFFBF34620040AF82000430E20100EF +:10F300001040001130F010008F83003010600006B4 +:10F310003C0F80003C05002000E52024148000C044 +:10F320003C0800043C0F800035EE010095CD001E26 +:10F3300095CC001C31AAFFFF000C5C00014B482556 +:10F34000AF89000C30F010001200000824110001F9 +:10F3500030F100201620008B3C18100000F890249B +:10F36000164000823C040C002411000130E801002A +:10F370001500000B3C0900018F85000430A94000F6 +:10F38000152000073C0900013C0C1F0100EC58242B +:10F390003C0A1000116A01183C1080003C09000171 +:10F3A00000E9302410C000173C0B10003C18080086 +:10F3B0008F1800243307000214E0014024030001E9 +:10F3C0008FBF001C8FB200188FB100148FB00010D7 +:10F3D0000060102103E0000827BD002000EE682433 +:10F3E00011A0FFBE30F220008F8F00043C11FFFF00 +:10F3F00036307FFF00F0382435E380000A0010A685 +:10F40000AF87000000EB102450400065AF8000285B +:10F410008F8C00303C0D0F0000ED18241580008803 +:10F42000AF83001030E8010011000086938F0010B8 +:10F430003C0A0200106A00833C1280003650010032 +:10F44000920500139789002E3626000230AF00FF88 +:10F4500025EE0004000E19C03C0480008C9801B811 +:10F460000700FFFE34880180AD0300003C198008CE +:10F47000AC830020973100483225FFFF10A0015CCB +:10F48000AF8500082523001200A3F82B53E0015993 +:10F490008F850004348D010095AC00202402001AF1 +:10F4A00030E44000318BFFFFA102000B108001927D +:10F4B0002563FFFE00A3502B154001908F8F0004A1 +:10F4C000A50300148F88000435050001AF850004F2 +:10F4D0003C08800035190180A729000EA729001AD1 +:10F4E0008F89000C30B18000A7270010AF290028B9 +:10F4F000A72600081220000E3C04800035020100FF +:10F50000944C0016318BFFFC256400040088182100 +:10F510008C7F400033E6FFFF14C000053C048000F0 +:10F520003C0AFFFF354D7FFF00AD2824AF85000466 +:10F53000240EBFFF00AE402434850180A4A800261D +:10F54000ACA7002C3C071000AC8701B800001821C4 +:10F550008FBF001C8FB200188FB100148FB0001045 +:10F560000060102103E0000827BD00203C020BFFD3 +:10F5700000E41824345FFFFF03E3C82B5320FF7B14 +:10F58000241100013C0608008CC6002C24C5000193 +:10F590003C010800AC25002C0A0010D42411000501 +:10F5A0008F85002810A0002FAF80001090A30000CE +:10F5B000146000792419000310A0002A30E601002D +:10F5C00010C000CC8F860010241F000210DF00C97D +:10F5D0008F8B000C3C0708008CE7003824E4FFFF09 +:10F5E00014E0000201641824000018213C0D0800FA +:10F5F00025AD0038006D1021904C00048F85002C43 +:10F6000025830004000321C030A5FFFF3626000239 +:10F610000E000FDB000000000A00114D0000182151 +:10F6200000E8302414C0FF403C0F80000E00103D65 +:10F63000000000008F8700000A0010CAAF82000C93 +:10F64000938F00103C180801271896E0000F90C017 +:10F6500002588021AF9000288F85002814A0FFD386 +:10F66000AF8F00103C0480008C86400030C5010044 +:10F6700010A000BC322300043C0C08008D8C002438 +:10F6800024120004106000C23190000D3C04800080 +:10F690008C8D40003402FFFF11A201003231FFFBCC +:10F6A0008C884000310A01005540000124110010EF +:10F6B00030EE080011C000BE2419FFFB8F98002C0B +:10F6C0002F0F03EF51E000010219802430E90100FF +:10F6D00011200014320800018F87003014E000FB75 +:10F6E0008F8C000C3C05800034AB0100917F00132F +:10F6F00033E300FF246A00042403FFFE0203802496 +:10F70000000A21C012000002023230253226FFFF1B +:10F710000E000FDB9785002E1200FF290000182134 +:10F72000320800011100000D32180004240E0001FF +:10F73000120E0002023230253226FFFF9785002E7E +:10F740000E000FDB00002021240FFFFE020F80249B +:10F750001200FF1B00001821321800045300FF188C +:10F760002403000102323025241200045612000145 +:10F770003226FFFF9785002E0E000FDB24040100C8 +:10F780002419FFFB021988241220FF0D0000182104 +:10F790000A0010E9240300011079009C00003021C8 +:10F7A00090AD00012402000211A200BE30EA004028 +:10F7B00090B90001241800011338007F30E900409F +:10F7C0008CA600049785002E00C020210E000FDBC0 +:10F7D0003626000200004021010018218FBF001CC6 +:10F7E0008FB200188FB100148FB00010006010218C +:10F7F00003E0000827BD0020360F010095EE000C45 +:10F8000031CD020015A0FEE63C0900013C1880083D +:10F81000971200489789002E362600023248FFFFD3 +:10F82000AF8800083C0380008C7101B80620FFFE01 +:10F83000346A0180AD4000001100008E3C0F800052 +:10F84000253F0012011FC82B1320008B240E00033C +:10F85000346C0100958B00202402001A30E4400033 +:10F860003163FFFFA142000B108000A72463FFFE5D +:10F870000103682B15A000A52408FFFE34A5000194 +:10F88000A5430014AF8500043C0480002412BFFF90 +:10F8900000B2802434850180A4A9000EA4A9001A16 +:10F8A000A4A60008A4B00026A4A700103C071000DE +:10F8B000AC8701B80A00114D000018213C038000FC +:10F8C00034640100949F000E3C1908008F3900D861 +:10F8D0002404008033E5FFFF273100013C010800CC +:10F8E000AC3100D80E000FDB240600030A00114DD6 +:10F8F00000001821240A000210CA00598F85002C2C +:10F900003C0308008C6300D0240E0001106E005EE2 +:10F910002CCF000C24D2FFFC2E5000041600002136 +:10F9200000002021241800021078001B2CD9000CA4 +:10F9300024DFFFF82FE900041520FF330000202109 +:10F9400030EB020051600004000621C054C00022C8 +:10F9500030A5FFFF000621C030A5FFFF0A00117D82 +:10F96000362600023C0908008D29002431300001B0 +:10F970005200FEF7000018219785002E362600025F +:10F980000E000FDB000020210A00114D000018219D +:10F990000A00119C241200021320FFE624DFFFF866 +:10F9A0000000202130A5FFFF0A00117D362600024D +:10F9B0000A0011AC021980245120FF828CA6000499 +:10F9C0003C05080190A596E110A0FF7E24080001E7 +:10F9D0000A0011F0010018210E000FDB3226000191 +:10F9E0008F8600108F85002C0A00124F000621C060 +:10F9F0008F8500043C18800024120003371001801A +:10FA0000A212000B0A00112E3C08800090A30001F6 +:10FA1000241100011071FF70240800012409000264 +:10FA20005069000430E60040240800010A0011F08B +:10FA30000100182150C0FFFD240800013C0C80008B +:10FA4000358B01009563001094A40002307FFFFF06 +:10FA5000509FFF62010018210A001284240800014F +:10FA60002CA803EF1100FE56240300010A001239EE +:10FA700000000000240E000335EA0180A14E000BB7 +:10FA80000A00121C3C04800011E0FFA2000621C005 +:10FA900030A5FFFF0A00117D362600020A0011A5DD +:10FAA000241100201140FFC63C1280003650010096 +:10FAB000960F001094AE000231E80FFF15C8FFC08A +:10FAC000000000000A0011E690B900013C060800A1 +:10FAD0008CC6003824C4FFFF14C00002018418241F +:10FAE000000018213C0D080025AD0038006D1021E4 +:10FAF0000A0011B6904300048F8F0004240EFFFE0D +:10FB00000A00112C01EE28242408FFFE0A00121A14 +:10FB100000A8282427BDFFC8AFB00010AFBF003435 +:10FB20003C10600CAFBE0030AFB7002CAFB6002861 +:10FB3000AFB50024AFB40020AFB3001CAFB20018C3 +:10FB4000AFB100148E0E5000240FFF7F3C068000E2 +:10FB500001CF682435AC380C240B0003AE0C5000E8 +:10FB6000ACCB00083C010800AC2000200E00184A75 +:10FB7000000000003C0A0010354980513C06601628 +:10FB8000AE09537C8CC700003C0860148D0500A0B2 +:10FB90003C03FFFF00E320243C02535300051FC237 +:10FBA0001482000634C57C000003A08002869821E0 +:10FBB0008E7200043C116000025128218CBF007C31 +:10FBC0008CA200783C1E600037C420203C05080150 +:10FBD00024A59328AF820018AF9F001C0E00170EBB +:10FBE0002406000A3C190001273996E03C01080070 +:10FBF000AC3931DC0E002105AF8000148FD7080826 +:10FC00002418FFF03C15570902F8B02412D503243C +:10FC100024040001AF8000303C148000369701803E +:10FC20003C1E080127DE96E0369301008E9000000E +:10FC30003205000310A0FFFD3207000110E000882C +:10FC4000320600028E7100283C048000AE91002034 +:10FC50008E6500048E66000000A0382100C040219F +:10FC60008C8301B80460FFFE3C0B0010240A0800DE +:10FC700000AB4824AC8A01B8552000E2240ABFFF3B +:10FC80009675000E3C1208008E52002030AC4000E9 +:10FC900032AFFFFF264E000125ED00043C010800B5 +:10FCA000AC2E0020118000EAAF8D002C3C18002003 +:10FCB00000B8B02412C000E730B980002408BFFFAC +:10FCC00000A8382434C81000AF87000030E62000B8 +:10FCD00010C000EB2409FFBF3C03000400E328240C +:10FCE00010A00002010910243502004030EA010092 +:10FCF00011400010AF8200048F8B003011600007AC +:10FD00003C0D002000ED6024118000043C0F000435 +:10FD100000EF702411C00239000000009668001E38 +:10FD20009678001C3115FFFF0018B40002B690252C +:10FD3000AF92000C30F910001320001324150001BD +:10FD400030FF002017E0000A3C04100000E41024FB +:10FD50001040000D3C0A0C003C090BFF00EA18247F +:10FD60003525FFFF00A3302B10C0000830ED010047 +:10FD70003C0C08008D8C002C24150005258B0001FF +:10FD80003C010800AC2B002C30ED010015A0000B4D +:10FD90003C0500018F85000430AE400055C00007CF +:10FDA0003C0500013C161F0100F690243C0F10009A +:10FDB000124F01CE000000003C05000100E5302498 +:10FDC00010C000B13C0C10003C1F08008FFF002445 +:10FDD00033E90002152000732403000100601021A4 +:10FDE000104000083C0680003C188000370F0100DE +:10FDF0008DEE00243C056020ACAE00140000000035 +:10FE00003C0680003C084000ACC8013800000000FF +:10FE10005220001332060002262A0140262B0080C1 +:10FE2000240DFF80014D2024016D6024000C194039 +:10FE30003162007F0004A9403152007F3C1620004F +:10FE400036C900020062F82502B2382500E988258B +:10FE500003E9C825ACD90830ACD10830320600021D +:10FE600010C0FF723C0F800035E501408CB80000E7 +:10FE700024100040ADF8002090AE000831C300709F +:10FE8000107000D628680041510000082405006069 +:10FE9000241100201071000E3C0B40003C06800035 +:10FEA000ACCB01780A001304000000001465FFFBCE +:10FEB0003C0B40000E002022000000003C0B4000E4 +:10FEC0003C068000ACCB01780A001304000000005F +:10FED00090BF0009241900048CA7000033E900FF3B +:10FEE000113901B22523FFFA2C72000612400016C8 +:10FEF0003C0680008CAB00048F86002494A2000A8C +:10FF0000000B5602312500FF10C000053044FFFFF2 +:10FF10002D4C000815800002254A0004240A000325 +:10FF20002410000910B001F828AE000A11C001DC4D +:10FF3000240F000A2404000810A40028000A41C06D +:10FF4000010038213C0680008CC801B80500FFFE86 +:10FF500034D00180AE07000034C401409085000811 +:10FF6000240A00023C0B400030B900FF00198A004F +:10FF70000229C025A6180008A20A000B948F000AC7 +:10FF80003C091000A60F00108C8E0004AE0E002459 +:10FF9000ACC901B83C068000ACCB01780A00130460 +:10FFA000000000003C0A8000354401009483000EEC +:10FFB0003C0208008C4200D8240400803065FFFF1A +:10FFC000245500013C010800AC3500D80E000FDBC1 +:10FFD000240600030A00137000001821000BC2025F +:10FFE000330300FF240A0001146AFFD60100382100 +:10FFF0008F910020AF830024262B00010A0013CA32 +:020000040001F9 +:10000000AF8B002000CA2024AF85000010800008BC +:10001000AF860004240C87FF00CC5824156000082C +:100020003C0D006000AD302410C000050000000051 +:100030000E000D42000000000A00137100000000D5 +:100040000E001636000000000A00137100000000C8 +:1000500030B980005320FF1DAF8500003C02002016 +:1000600000A2F82453E0FF19AF8500003C07FFFF12 +:1000700034E47FFF00A438240A00132B34C8800026 +:100080000A0013340109102400EC58245160005A6E +:10009000AF8000288F8D00303C0E0F0000EE18243A +:1000A00015A00075AF83001030EF010011E0007360 +:1000B000939800103C120200107200703C06800001 +:1000C00034D90100932800139789002E36A6000228 +:1000D000311800FF27160004001619C03C048000E8 +:1000E0008C8501B804A0FFFE34880180AD030000B8 +:1000F0003C158008AC83002096BF004833E5FFFF25 +:1001000010A001EBAF8500082523001200A3102BDF +:10011000504001E88F850004348D010095AC00202B +:10012000240B001A30E44000318AFFFFA10B000BC2 +:10013000108001E92543FFFE00A3702B15C001E7E5 +:100140008F9600048F8F0004A503001435E500018D +:10015000AF8500043C08800035150180A6A9000E7B +:10016000A6A9001A8F89000C30BF8000A6A7001036 +:10017000AEA90028A6A6000813E0000F3C0F8000DF +:10018000350C0100958B0016316AFFFC25440004F4 +:10019000008818218C6240003046FFFF14C0000721 +:1001A0002416BFFF3C0EFFFF35CD7FFF00AD282496 +:1001B000AF8500043C0F80002416BFFF00B69024DA +:1001C00035E50180A4B20026ACA7002C3C07100046 +:1001D000ADE701B80A001370000018210E00168E5A +:1001E000000000003C0B40003C068000ACCB0178D6 +:1001F0000A001304000000008F85002810A00025CD +:10020000AF80001090A3000010600072241F000354 +:10021000107F00FF0000302190AD0001240C00028F +:1002200011AC015930EE004090BF000124190001CB +:1002300013F9000930E900408CA600049785002ED0 +:1002400000C020210E000FDB36A600020000402176 +:100250000A001370010018215120FFF88CA6000439 +:100260003C07080190E796E110E0FFF42408000144 +:100270000A00137001001821939800100018C8C0DC +:10028000033E4021AF8800288F85002814A0FFDDA1 +:10029000AF9800103C0480008C86400030C50100FF +:1002A00010A0008732AA00043C0B08008D6B0024CC +:1002B00024160004154000033172000D24160002BC +:1002C0003C0480008C8D4000340CFFFF11AC012CED +:1002D00032B5FFFB8C8F400031EE010055C00001AC +:1002E0002415001030F8080013000038241FFFFB0D +:1002F0008F99002C2F2803EF51000001025F9024FA +:1003000030E9010011200014325900018F870030BC +:1003100014E001278F8B000C3C0480003486010020 +:1003200090C5001330A300FF24620004000221C026 +:100330002408FFFE024890241240000202B6302535 +:1003400032A6FFFF0E000FDB9785002E1240FEA3A2 +:1003500000001821325900011320000D324700041B +:10036000241F0001125F000202B6302532A6FFFFF3 +:100370009785002E0E000FDB000020212409FFFED0 +:10038000024990241240FE950000182132470004D3 +:1003900050E0FE922403000102B63025241600042A +:1003A0005656000132A6FFFF9785002E0E000FDB88 +:1003B000240401002402FFFB0242A82412A0FE87AD +:1003C000000018210A001370240300010A0014B968 +:1003D000025F902410A0FFAF30E5010010A00017CD +:1003E0008F8600102402000210C200148F84000CBB +:1003F0003C0608008CC6003824C3FFFF14C000026E +:1004000000831024000010213C0D080025AD0038A9 +:10041000004D6021918B00048F85002C256A00041B +:10042000000A21C030A5FFFF36A600020E000FDB38 +:10043000000000000A00137000001821240E0002C2 +:1004400010CE0088241200013C0308008C6300D009 +:100450001072008D8F85002C24C8FFFC2D1800041D +:100460001700006300002021241900021079005DAC +:100470002CDF000C24C2FFF82C4900041520FFE9F2 +:100480000000202130E3020050600004000621C07B +:1004900054C0000530A5FFFF000621C030A5FFFFB6 +:1004A0000A00150436A600020E000FDB32A600017A +:1004B0008F8600108F85002C0A001520000621C0B1 +:1004C0003C0308008C630024307200015240FE435C +:1004D000000018219785002E36A600020E000FDBC3 +:1004E000000020210A001370000018219668000CFB +:1004F000311802005700FE313C0500013C1F800806 +:1005000097F900489789002E36A600023328FFFF8E +:10051000AF8800083C0380008C7501B806A0FFFE80 +:100520003C04800034820180AC400000110000E7F0 +:1005300024180003252A0012010A182B106000E37A +:1005400000000000966F00203C0E8000240D001A71 +:1005500031ECFFFF35CA018030EB4000A14D000BAC +:10056000116000E12583FFFE0103902B164000DFA0 +:100570002416FFFE34A50001A5430014AF85000436 +:100580002419BFFF00B94024A6E9000EA6E9001A0D +:10059000A6E60008A6E80026A6E700103C07100023 +:1005A000AE8701B80A001370000018213C048000D7 +:1005B0008C8901B80520FFFE349601802415001CAB +:1005C000AEC70000A2D5000B3C071000AC8701B8F5 +:1005D0003C0B40003C068000ACCB01780A001304C1 +:1005E0000000000013E0FFA424C2FFF80000202157 +:1005F00030A5FFFF0A00150436A600020E00103DCC +:10060000000000008F8700000A001346AF82000C34 +:1006100090A30001241500011075FF0D24080001AE +:10062000240900021069000430E60040240800019B +:100630000A0013700100182150C0FFFD24080001BA +:100640003C0B8000356A01009543001094A4000221 +:100650003062FFFF5082FDE1010018210A0015857C +:10066000240800018F85002C2CAF03EF11E0FDDB87 +:10067000240300013C0308008C6300D02412000115 +:100680001472FF7624C8FFFC2CD6000C12C0FF7237 +:10069000000621C030A5FFFF0A00150436A600029F +:1006A00010AF005700043A022406000B14A6FE24E3 +:1006B000000A41C0316600FF0006FE00001F5E0315 +:1006C0000562007230C6007F000668C001BE382196 +:1006D000A0E00001A0E000003C1660008ED21820CF +:1006E000240C000100CC100400021827000A41C0AD +:1006F0000243A824A4E0000201003821AED518204E +:100700000A0013CB3C06800014C000368F8D0020F9 +:10071000000A41C03C1F80003C058008AFE8002073 +:1007200094B9004013200002240500012405004173 +:100730003C0480008C8701B804E0FFFE3495018002 +:1007400024020003AEA80000A2A2000BA6A0000E87 +:10075000A6A0001AA6A00010AEA00028A6A500081A +:1007600096A3002634720001A6B20026AEA0002C8B +:100770003C161000AC9601B80A0013CA01003821DB +:100780000A0014B22415002011C0FEB53C088000F8 +:10079000351801009716001094B2000232CF0FFFF7 +:1007A000164FFEAF000000000A00148490BF000145 +:1007B0003C0A08008D4A0038254CFFFF1540000216 +:1007C000016C1024000010213C1808002718003884 +:1007D0000058782191EE000425CD00040A0014C5CC +:1007E000000D21C0000A41C025ACFFFF1580FDD4DB +:1007F000AF8C0020010038210A0013CAAF8000240A +:10080000240300FF10E3FDCE000A41C010C0001712 +:1008100000078600000720C0009E18212402000166 +:100820003C05080124A596E4009E7821000A41C0F9 +:100830000085C821000B8C02A0620000AF280000D8 +:10084000A1F100013C0E60008DC6182024180001A3 +:1008500000F8500400CA202501003821A5EB000251 +:10086000ADC418200A0013CB3C06800000104603DC +:100870000502000D30E7007F11430006000720C08D +:10088000009E18210A001601240200020A0015AB7E +:10089000AF800020009E18210A00160124020003E8 +:1008A0000A0012FFAF8400300A001617AF8700203D +:1008B0008F8500043C19800024080003373801802C +:1008C000A308000B0A00144F3C088000A2F8000B9C +:1008D0000A00155A2419BFFF8F9600042412FFFE48 +:1008E0000A00144D02D228242416FFFE0A001558CF +:1008F00000B628243C038000346401008C8500008D +:1009000030A2003E1440000800000000AC60004827 +:100910008C87000030E607C010C000050000000012 +:10092000AC60004CAC60005003E000082402000101 +:10093000AC600054AC6000408C880000310438008A +:100940001080FFF9000000002402000103E000080D +:10095000AC6000443C0380008C6201B80440FFFEA0 +:1009600034670180ACE4000024080001ACE000041E +:10097000A4E5000824050002A0E8000A3464014050 +:10098000A0E5000B9483000A14C00008A4E3001043 +:10099000ACE000243C07800034E901803C041000F6 +:1009A000AD20002803E00008ACE401B88C86000408 +:1009B0003C041000ACE600243C07800034E90180D0 +:1009C000AD20002803E00008ACE401B83C0680003C +:1009D0008CC201B80440FFFE34C701802409000224 +:1009E000ACE40000ACE40004A4E50008A0E9000ABF +:1009F00034C50140A0E9000B94A8000A3C04100093 +:100A0000A4E80010ACE000248CA30004ACE30028B0 +:100A100003E00008ACC401B83C039000346200015C +:100A2000008220253C038000AC6400208C650020FF +:100A300004A0FFFE0000000003E00008000000002A +:100A40003C028000344300010083202503E00008BD +:100A5000AC44002027BDFFE03C098000AFBF001878 +:100A6000AFB10014AFB00010352801408D10000068 +:100A7000910400099107000891050008308400FFE7 +:100A800030E600FF00061A002C820081008330252A +:100A90001040002A30A50080000460803C0D080151 +:100AA00025AD9350018D58218D6A0000014000084A +:100AB000000000003C038000346201409445000ABD +:100AC00014A0001E8F91FCC09227000530E60004A0 +:100AD00014C0001A000000000E00167F0200202142 +:100AE000922A000502002021354900040E001689D3 +:100AF000A229000592280005310400041480000298 +:100B0000000000000000000D922D0000240B0020CA +:100B100031AC00FF158B00093C0580008CAE01B89C +:100B200005C0FFFE34B10180AE3000003C0F100064 +:100B300024100005A230000BACAF01B80000000D7E +:100B40008FBF00188FB100148FB0001003E00008B1 +:100B500027BD00200200202100C028218FBF0018DF +:100B60008FB100148FB00010240600010A00164E49 +:100B700027BD00200000000D0200202100C0282118 +:100B80008FBF00188FB100148FB00010000030210B +:100B90000A00164E27BD002014A0FFE80000000048 +:100BA000020020218FBF00188FB100148FB00010F9 +:100BB00000C028210A00166C27BD00203C078000D9 +:100BC0008CEE01B805C0FFFE34F00180241F000246 +:100BD000A21F000B34F80140A60600089719000A6E +:100BE0003C0F1000A61900108F110004A61100126E +:100BF000ACEF01B80A0016CA8FBF001827BDFFE886 +:100C0000AFBF00100E000FD4000000003C028000B7 +:100C10008FBF001000002021AC4001800A00108F1F +:100C200027BD00183084FFFF30A5FFFF10800007AC +:100C30000000182130820001104000020004204210 +:100C4000006518211480FFFB0005284003E0000820 +:100C50000060102110C00007000000008CA20000FE +:100C600024C6FFFF24A50004AC82000014C0FFFBD3 +:100C70002484000403E000080000000010A0000825 +:100C800024A3FFFFAC86000000000000000000006D +:100C90002402FFFF2463FFFF1462FFFA2484000490 +:100CA00003E00008000000003C03800027BDFFF8BF +:100CB00034620180AFA20000308C00FF30AD00FF35 +:100CC00030CE00FF3C0B80008D6401B80480FFFE35 +:100CD000000000008FA900008D6801288FAA000085 +:100CE0008FA700008FA40000240500012402000249 +:100CF000A085000A8FA30000359940003C05100034 +:100D0000A062000B8FB800008FAC00008FA600001F +:100D10008FAF000027BD0008AD280000AD400004E3 +:100D2000AD800024ACC00028A4F90008A70D001075 +:100D3000A5EE001203E00008AD6501B83C0680088E +:100D400027BDFFE834C50080AFBF001090A70009A1 +:100D50002402001230E300FF1062000B00803021FB +:100D60008CA8005000882023048000088FBF00104A +:100D70008CAA0034240400390000282100CA48232A +:100D800005200005240600128FBF00102402000178 +:100D900003E0000827BD00180E0017230000000024 +:100DA0008FBF00102402000103E0000827BD0018D7 +:100DB00027BDFFC8AFB20030AFB00028AFBF0034CE +:100DC000AFB1002C00A0802190A5000D30A600102E +:100DD00010C00010008090213C0280088C44000468 +:100DE0008E0300081064000C30A7000530A6000533 +:100DF00010C00093240400018FBF00348FB2003074 +:100E00008FB1002C8FB000280080102103E0000873 +:100E100027BD003830A7000510E0000F30AB0012EE +:100E200010C00006240400013C0980088E08000858 +:100E30008D2500045105009C240400388FBF003428 +:100E40008FB200308FB1002C8FB0002800801021AD +:100E500003E0000827BD0038240A0012156AFFE6E7 +:100E6000240400010200202127A500100E000CB66A +:100E7000AFA000101440007C3C198008372400808B +:100E800090980008331100081220000A8FA7001064 +:100E900030FF010013E000A48FA300148C860058DB +:100EA00000661023044000043C0A8008AC8300580C +:100EB0008FA700103C0A800835480080910900087F +:100EC000312400081480000224080003000040219F +:100ED0003C1F800893F1001193F9001237E600805F +:100EE0008CCC0054333800FF03087821322D00FFEA +:100EF000000F708001AE282100AC582B1160006FEC +:100F00000000000094CA005C8CC900543144FFFF0B +:100F1000012510230082182B1460006800000000D7 +:100F20008CCB00540165182330EC00041180006C58 +:100F3000000830808FA8001C0068102B1040006251 +:100F400030ED0004006610232C46008010C0000223 +:100F500000408821241100800E00167F02402021CD +:100F60003C0D800835A6008024070001ACC7000CAA +:100F700090C800080011484035A70100310C007FDF +:100F8000A0CC00088E05000424AB0001ACCB0030DF +:100F9000A4D1005C8CCA003C9602000E01422021C4 +:100FA000ACC400208CC3003C0069F821ACDF001CFD +:100FB0008E190004ACF900008E180008ACF800048B +:100FC0008FB10010322F000855E0004793A6002093 +:100FD000A0C0004E90D8004E2411FFDFA0F80008FA +:100FE00090CF000801F17024A0CE00088E05000803 +:100FF0003C0B800835690080AD2500388D6A0014EF +:101000008D2200302419005001422021AD240034EB +:1010100091230000307F00FF13F90036264F0100B6 +:101020000E001689024020212404003800002821E7 +:101030000E0017232406000A0A0017882404000162 +:101040000E000D28000020218FBF00348FB2003029 +:101050008FB1002C8FB0002800402021008010218B +:1010600003E0000827BD00388E0E00083C0F800802 +:1010700035F00080AE0E005402402021AE0000305A +:101080000E00167F00000000920D00250240202176 +:1010900035AC00200E001689A20C00250E000CAC09 +:1010A00002402021240400382405008D0E0017235F +:1010B000240600120A0017882404000194C5005C6D +:1010C0000A0017C330A3FFFF2407021811A0FF9ED8 +:1010D00000E610238FAE001C0A0017CB01C61023B8 +:1010E0000A0017C82C620218A0E600080A0017F5CB +:1010F0008E0500082406FF8001E6C0243C11800014 +:10110000AE3800288E0D000831E7007F3C0E800CC1 +:1011100000EE6021AD8D00E08E080008AF8C003C31 +:101120000A001801AD8800E4AC80005890850008E2 +:101130002403FFF700A33824A08700080A0017A69D +:101140008FA700103C05080024A5616C3C04080032 +:10115000248470B83C020800244261742403000611 +:101160003C010801AC2597603C010801AC24976460 +:101170003C010801AC2297683C010801A023976C50 +:1011800003E000080000000003E000082402000162 +:101190003C028000308800FF344701803C0680001C +:1011A0008CC301B80460FFFE000000008CC501285C +:1011B0002418FF803C0D800A24AF010001F8702440 +:1011C00031EC007FACCE0024018D2021ACE5000085 +:1011D000948B00EA3509600024080002316AFFFFA1 +:1011E000ACEA000424020001A4E90008A0E8000B16 +:1011F000ACE000243C071000ACC701B8AF84003C51 +:1012000003E00008AF8500709388004C8F8900646C +:101210008F82003C30C600FF0109382330E900FF0F +:101220000122182130A500FF2468008810C00002A8 +:10123000012438210080382130E4000314800003A9 +:1012400030AA00031140000D312B000310A000094B +:101250000000102190ED0000244E000131C200FF7B +:101260000045602BA10D000024E700011580FFF967 +:101270002508000103E00008000000001560FFF3EE +:101280000000000010A0FFFB000010218CF80000FF +:1012900024590004332200FF0045782BAD180000CC +:1012A00024E7000415E0FFF92508000403E0000826 +:1012B000000000009385004C9388005C8F870064D9 +:1012C000000432003103007F00E5102B30C47F00A2 +:1012D0001040000F006428258F84003C3C098000EA +:1012E0008C8A00ECAD2A00A43C03800000A35825A2 +:1012F000AC6B00A08C6C00A00580FFFE000000001D +:101300008C6D00ACAC8D00EC03E000088C6200A892 +:101310000A0018B38F84003C9388005D3C02800073 +:1013200000805021310300FEA383005D30ABFFFF3E +:1013300030CC00FF30E7FFFF344801803C098000DB +:101340008D2401B80480FFFE8F8D007024180016D4 +:10135000AD0D00008D2201248F8D003CAD020004F4 +:101360008D590020A5070008240201C4A119000A14 +:10137000A118000B952F01208D4E00088D47000409 +:10138000978300608D59002401CF302100C72821A8 +:1013900000A320232418FFFFA504000CA50B000EBA +:1013A000A5020010A50C0012AD190018AD180024FC +:1013B00095AF00E83C0B10002407FFF731EEFFFF6C +:1013C000AD0E00288DAC0084AD0C002CAD2B01B807 +:1013D0008D46002000C7282403E00008AD4500200A +:1013E0008F88003C0080582130E7FFFF910900D62C +:1013F0003C02800030A5FFFF312400FF00041A00EA +:101400000067502530C600FF344701803C0980004A +:101410008D2C01B80580FFFE8F820070240F00170D +:10142000ACE200008D390124ACF900048D78002075 +:10143000A4EA0008241901C4A0F8000AA0EF000BD8 +:10144000952301208D6E00088D6D00049784006047 +:1014500001C35021014D602101841023A4E2000C3E +:10146000A4E5000EA4F90010A4E60012ACE00014FC +:101470008D780024240DFFFFACF800188D0F007C40 +:10148000ACEF001C8D0E00783C0F1000ACEE00207D +:10149000ACED0024950A00BE240DFFF73146FFFF96 +:1014A000ACE60028950C00809504008231837FFF14 +:1014B0000003CA003082FFFF0322C021ACF8002CD9 +:1014C000AD2F01B8950E00828D6A002000AE30214C +:1014D000014D2824A506008203E00008AD65002028 +:1014E0003C028000344501803C0480008C8301B8BC +:1014F0000460FFFE8F8A0048240600199549001CED +:101500003128FFFF000839C0ACA70000A0A6000BDF +:101510003C05100003E00008AC8501B88F8700503F +:101520000080402130C400FF3C0680008CC201B81E +:101530000440FFFE8F8900709383006C3499600033 +:10154000ACA90000A0A300058CE20010240F00024B +:101550002403FFF7A4A20006A4B900088D180020F8 +:10156000A0B8000AA0AF000B8CEE0000ACAE0010DB +:101570008CED0004ACAD00148CEC001CACAC002471 +:101580008CEB0020ACAB00288CEA002C3C07100050 +:10159000ACAA002C8D090024ACA90018ACC701B876 +:1015A0008D05002000A3202403E00008AD040020E6 +:1015B0008F86003C27BDFFE0AFB10014AFBF00181D +:1015C000AFB0001090C300D430A500FF30620020FF +:1015D00010400008008088218CCB00D02409FFDF58 +:1015E000256A0001ACCA00D090C800D40109382493 +:1015F000A0C700D414A000403C0C80008F84003CA5 +:10160000908700D42418FFBF2406FFEF30E3007F4B +:10161000A08300D4979F00608F8200648F8D003C70 +:1016200003E2C823A7990060A5A000BC91AF00D435 +:1016300001F87024A1AE00D48F8C003CA18000D7AB +:101640008F8A003CA5400082AD4000EC914500D45B +:1016500000A65824A14B00D48F9000388F840064DA +:10166000978600600204282110C0000FAF85003863 +:10167000A380005C3C0780008E2C000894ED0120C4 +:101680008E2B0004018D5021014B80210206202366 +:101690003086FFFF30C8000F3909000131310001E9 +:1016A00016200009A388005C9386004C8FBF0018A9 +:1016B0008FB100148FB0001027BD0020AF850068E7 +:1016C00003E00008AF86006400C870238FBF0018D5 +:1016D0009386004C8FB100148FB0001034EF0C00D3 +:1016E000010F282127BD0020ACEE0084AF850068E3 +:1016F00003E00008AF8600643590018002002821D5 +:101700000E001940240600828F84003C908600D48D +:1017100030C5004050A0FFBAA380006C8F850050F8 +:101720003C0680008CCD01B805A0FFFE8F890070BB +:101730002408608224070002AE090000A608000801 +:10174000A207000B8CA300083C0E1000AE03001093 +:101750008CA2000CAE0200148CBF0014AE1F001847 +:101760008CB90018AE1900248CB80024AE180028DB +:101770008CAF0028AE0F002CACCE01B80A0019794E +:10178000A380006C8F8A003C27BDFFE0AFB100143E +:10179000AFB000108F880064AFBF0018938900407D +:1017A000954200BC30D100FF0109182B0080802138 +:1017B00030AC00FF3047FFFF0000582114600003E9 +:1017C000310600FF01203021010958239783006072 +:1017D0000068202B148000270000000010680056CD +:1017E000241900011199006334E708803165FFFF77 +:1017F0000E0018F1020020218F8300703C0780004A +:1018000034E601803C0580008CAB01B80560FFFE2A +:10181000240A00188F84003CACC30000A0CA000B4F +:10182000948900BE3C081000A4C90010ACC0003070 +:10183000ACA801B89482008024430001A4830080F6 +:10184000949F00803C0608008CC6318833EC7FFFF3 +:101850001186005E000000000200202102202821E5 +:101860008FBF00188FB100148FB000100A001965E7 +:1018700027BD0020914400D42403FF8000838825E5 +:10188000A15100D4978400603088FFFF51000023ED +:10189000938C00408F85003C2402EFFF008B78235F +:1018A00094AE00BC0168502B31E900FF01C26824EE +:1018B000A4AD00BC51400039010058213C1F8000FC +:1018C00037E601008CD800043C19000103194024BC +:1018D0005500000134E740008E0A00202403FFFB7E +:1018E0002411000101432024AE0400201191002D99 +:1018F00034E7800002002021012030210E0018F181 +:101900003165FFFF978700608F890064A7800060C2 +:1019100001278023AF900064938C00408F8B003CA4 +:101920008FBF00188FB100148FB0001027BD0020AA +:1019300003E00008A16C00D73C0D800035AA01002F +:101940008D4800043C0900010109282454A000012D +:1019500034E740008E0F00202418FFFB34E780009E +:1019600001F8702424190001AE0E00201599FF9F84 +:1019700034E70880020020210E0018BF3165FFFF08 +:1019800002002021022028218FBF00188FB10014EF +:101990008FB000100A00196527BD00200A001A2820 +:1019A0000000482102002021012030210E0018BF34 +:1019B0003165FFFF978700608F890064A780006012 +:1019C000012780230A001A3FAF900064948C0080A6 +:1019D000241F8000019F3024A4860080908B00800B +:1019E000908F0080316700FF0007C9C20019C0272F +:1019F000001871C031ED007F01AE2825A085008060 +:101A00000A001A10020020219385006C24030001B3 +:101A100027BDFFE800A330042CA20020AFB00010C7 +:101A2000AFBF001400C01821104000132410FFFEA7 +:101A30003C0708008CE7319000E610243C08800049 +:101A40003505018014400005240600848F89003C80 +:101A5000240A00042410FFFFA12A00FC0E001940F4 +:101A600000000000020010218FBF00148FB0001092 +:101A700003E0000827BD00183C0608008CC631941E +:101A80000A001A8800C310248F87004827BDFFE092 +:101A9000AFB20018AFB10014AFB00010AFBF001C60 +:101AA00030D000FF90E6000D00A08821008090213A +:101AB00030C5007FA0E5000D8F85003C8E23001807 +:101AC0008CA200D01062002E240A000E0E001A7B99 +:101AD000A38A006C2409FFFF104900222404FFFFA1 +:101AE00052000020000020218E2600003C0C001037 +:101AF00000CC5824156000393C0E000800CE682444 +:101B000055A0003F024020213C18000200D880244C +:101B10001200001F3C0A00048F8700488CE200146A +:101B20008CE300108CE500140043F82303E5C82B78 +:101B300013200005024020218E24002C8CF100107F +:101B4000109100310240202124020012A382006C77 +:101B50000E001A7B2412FFFF105200022404FFFF24 +:101B6000000020218FBF001C8FB200188FB100141D +:101B70008FB000100080102103E0000827BD002076 +:101B800090A800D4350400200A001AB1A0A400D403 +:101B900000CA48241520000B8F8B00488F8D004809 +:101BA0008DAC00101580000B024020218E2E002CE1 +:101BB00051C0FFEC00002021024020210A001ACC75 +:101BC000240200178D66001050C0FFE6000020219F +:101BD000024020210A001ACC2402001102402021D8 +:101BE000240200150E001A7BA382006C240FFFFF55 +:101BF000104FFFDC2404FFFF0A001ABB8E260000F2 +:101C00000A001AF2240200143C08000400C8382418 +:101C100050E0FFD400002021024020210A001ACC0D +:101C2000240200138F85003C27BDFFD8AFB3001CF2 +:101C3000AFB20018AFB10014AFB00010AFBF0020BA +:101C400090A700D48F9000502412FFFF34E2004090 +:101C500092060000A0A200D48E03001000809821FC +:101C60001072000630D1003F2408000D0E001A7BD0 +:101C7000A388006C105200252404FFFF8F8A003CCB +:101C80008E0900188D4400D0112400070260202125 +:101C9000240C000E0E001A7BA38C006C240BFFFF9B +:101CA000104B001A2404FFFF240400201224000417 +:101CB0008F8D003C91AF00D435EE0020A1AE00D452 +:101CC0008F85005810A00019000000001224004A5F +:101CD0008F98003C8F92FCC0971000809651000AAC +:101CE000523000488F9300443C1F08008FFF318C16 +:101CF00003E5C82B1720001E0260202100002821C8 +:101D00000E0019DA24060001000020218FBF0020F8 +:101D10008FB3001C8FB200188FB100148FB0001069 +:101D20000080102103E0000827BD00285224002A6B +:101D30008E0500148F84003C948A008025490001A0 +:101D4000A4890080948800803C0208008C4231887D +:101D500031077FFF10E2000E00000000026020212A +:101D60000E001965240500010A001B3C000020211B +:101D70002402002D0E001A7BA382006C2403FFFFB7 +:101D80001443FFE12404FFFF0A001B3D8FBF002026 +:101D900094990080241F800024050001033FC02483 +:101DA000A498008090920080908E0080325100FFB5 +:101DB000001181C200107827000F69C031CC007F6C +:101DC000018D5825A08B00800E001965026020212E +:101DD0000A001B3C000020212406FFFF54A6FFD66A +:101DE0008F84003C026020210E001965240500014B +:101DF0000A001B3C00002021026020210A001B5623 +:101E00002402000A2404FFFD0A001B3CAF93006477 +:101E10008F88003C27BDFFE8AFB00010AFBF0014B3 +:101E2000910A00D48F8700500080802135490040FE +:101E30008CE60010A10900D43C0208008C4231B0AD +:101E400030C53FFF00A2182B106000078F8500549B +:101E5000240DFF8090AE000D01AE6024318B00FF99 +:101E6000156000080006C382020020212403000D33 +:101E70008FBF00148FB0001027BD00180A001A7B16 +:101E8000A383006C33060003240F000254CFFFF736 +:101E90000200202194A2001C8F85003C24190023FD +:101EA000A4A200E88CE8000000081E02307F003F7A +:101EB00013F900353C0A00838CE800188CA600D08A +:101EC00011060008000000002405000E0E001A7B19 +:101ED000A385006C2407FFFF104700182404FFFFB0 +:101EE0008F85003C90A900D435240020A0A400D404 +:101EF0008F8C0048918E000D31CD007FA18D000D9B +:101F00008F8300581060001C020020218F84005431 +:101F10008C9800100303782B11E0000D2419001891 +:101F200002002021A399006C0E001A7B2410FFFFF1 +:101F3000105000022404FFFF000020218FBF001476 +:101F40008FB000100080102103E0000827BD0018AA +:101F50008C8600108F9F00480200202100C31023B0 +:101F6000AFE20010240500010E0019DA240600017A +:101F70000A001BC8000020210E001965240500017D +:101F80000A001BC800002021010A5824156AFFD945 +:101F90008F8C0048A0A600FC0A001BB5A386005E3B +:101FA00030A500FF2406000124A9000100C9102B60 +:101FB0001040000C00004021240A000100A6182354 +:101FC000308B000124C60001006A3804000420425E +:101FD0001160000200C9182B010740251460FFF8AA +:101FE00000A6182303E000080100102127BDFFD838 +:101FF000AFB000188F900050AFB1001CAFBF0020F1 +:102000002403FFFF2411002FAFA30010920600004D +:102010002405000826100001006620260E001BE1A2 +:10202000308400FF00021E003C021EDC34466F417B +:102030000A001C090000102110A0000900801821CE +:102040002445000130A2FFFF2C4500080461FFFA7F +:10205000000320400086202614A0FFF900801821EC +:102060000E001BE1240500208FA300102629FFFF8E +:10207000313100FF00034202240700FF1627FFE270 +:102080000102182600035027AFAA0014AFAA0010BF +:102090000000302127A8001027A7001400E67823AD +:1020A00091ED000324CE000100C8602131C600FF7D +:1020B0002CCB00041560FFF9A18D00008FA2001049 +:1020C0008FBF00208FB1001C8FB0001803E0000804 +:1020D00027BD002827BDFFD0AFB3001CAFB0001054 +:1020E000AFBF0028AFB50024AFB40020AFB20018D6 +:1020F000AFB100143C0C80008D880128240FFF80B4 +:102100003C06800A25100100250B0080020F682480 +:102110003205007F016F7024AD8E009000A628214B +:10212000AD8D002490A600FC3169007F3C0A80043C +:10213000012A1821A386005E9067007C0080982108 +:10214000AF83003430E20002AF880070AF85003CFE +:1021500000A018211440000224040034240400309C +:10216000A384004C8C7200DC30D100FF24040004F6 +:10217000AF92006412240004A380006C8E740004EB +:102180001680001E3C0880009386005D30C7000169 +:1021900050E0000F8F8600648CA400848CA800841B +:1021A0002413FF8000936024000C49403110007F0D +:1021B000013078253C19200001F9682530DF00FE48 +:1021C0003C038000AC6D0830A39F005D8F860064E7 +:1021D0008FBF00288FB500248FB400208FB3001C60 +:1021E0008FB200188FB100148FB0001024020001CC +:1021F00027BD003003E00008ACA600DC8E7F00089D +:10220000950201208E67001003E2C8213326FFFFEC +:1022100030D8000F33150001AF87003816A00058E2 +:10222000A398005C35090C000309382100D8182355 +:10223000AD030084AF8700688E6A00043148FFFF59 +:102240001100007EA78A006090AC00D42407FF80B4 +:1022500000EC302430CB00FF1560004B9786006007 +:10226000938E005E240D000230D5FFFF11CD02A237 +:102270000000A0218F85006402A5802B160000BC01 +:102280009388004C3C11800096240120310400FF0B +:10229000148500888F8400688F98003833120003FB +:1022A0005640008530A500FF8F900068310C00FF7C +:1022B0002406003411860095AF900050920400046B +:1022C000148001198F8E003CA38000408E0D000405 +:1022D0008DC800D83C0600FF34CCFFFF01AC302491 +:1022E0000106182B14600121AF8600588F87006407 +:1022F00097980060AF8700440307402310C000C7D1 +:10230000A78800608F91003430C300030003582376 +:10231000922A007C3171000302261021000A2082DB +:10232000309200010012488000492821311FFFFF30 +:1023300003E5C82B132001208F88003C8F850038CF +:102340008F8800681105025A3C0E3F018E0600007E +:102350003C0C250000CE682411AC01638F84005032 +:1023600030E500FF0E00187B000030218F88003C14 +:102370008F8700648F8500380A001DE88F8600581B +:102380000A001C87AF87006890AC00D400EC2024C2 +:10239000309000FF120000169386005D90B5008813 +:1023A00090B400D724A8008832A2003F2446FFE062 +:1023B0002CD10020A39400401220000CAF880050C4 +:1023C000240E000100CE2004308A00191540012B94 +:1023D0003C06800034D80002009858241560022E74 +:1023E0003092002016400234000000009386005D09 +:1023F00030CE000111C0000F978800608CA90084C6 +:102400008CAF00842410FF800130C82400191940CB +:1024100031ED007F006D38253C1F200000FF902526 +:1024200030CB00FE3C188000AF120830A38B005D5B +:10243000978800601500FF84000000008E63002074 +:10244000306C00041180FF519386005D2404FFFB73 +:10245000006430243C038000AE66002034660180B6 +:102460008C7301B80660FFFE8F8E0070346A010025 +:102470003C150001ACCE00008C620124240760856D +:10248000ACC200048D54000402958824522000013F +:1024900024076083241200023C1810003C0B8000CB +:1024A000A4C70008A0D2000BAD7801B80A001C5CDC +:1024B0009386005D30A500FF0E00187B2406000106 +:1024C0008F8800703C05800034A90900250201882E +:1024D0009388004C304A0007304B00783C03408022 +:1024E0002407FF800163C825014980210047F824A3 +:1024F000310C00FF24060034ACBF0800AF90005040 +:10250000ACB908105586FF6E920400048F84003C1D +:102510008E110030908E00D431CD001015A0001027 +:102520008F8300642C6F000515E000E400000000BC +:10253000909800D42465FFFC331200101640000868 +:1025400030A400FF8F9F00688F99003813F90004B2 +:102550003887000130E20001144001C8000000008B +:102560000E001BF4000000000A001E2900000000FD +:102570008F84006830C500FF0E00187B2406000120 +:10258000938E004C240A003411CA00A08F85003CB1 +:102590008F860064978300603062FFFF00C288234B +:1025A000AF910064A78000601280FF900280182124 +:1025B0002414FFFD5474FFA28E6300208E69000472 +:1025C0002403FFBF240BFFEF0135C823AE790004BD +:1025D00090AF00D431ED007FA0AD00D48E66002016 +:1025E0008F98003CA780006034DF0002AE7F00209F +:1025F000A70000BC931200D402434024A30800D4D7 +:102600008F95003CAEA000EC92AE00D401CB5024DC +:10261000A2AA00D40A001D088F85003C8F910038C3 +:10262000AF80006402275821AF8B003800002021C2 +:102630002403FFFF108301B48F85003C8E0C001033 +:102640003C0D08008DAD31B09208000031843FFF91 +:10265000008D802B12000023310D003F3C19080033 +:102660008F3931A88F9F0070000479802408FF8083 +:10267000033F2021008FC8219385005D0328F824A3 +:102680003C0600803C0F800034D80001001F9140C0 +:102690003331007F8F86003C0251502535EE0940D2 +:1026A000332B0078333000073C0310003C02800CD1 +:1026B00001789025020E48210143C02502223821CD +:1026C00034AE0001ADFF0804AF890054ADF2081428 +:1026D000AF870048ADFF0028ACD90084ADF80830C2 +:1026E000A38E005D9383005E2407000350670028DB +:1026F00025A3FFE0240C0001146CFFAB8F85003C88 +:102700002411002311B10084000000002402000BFA +:10271000026020210E001A7BA382006C0040A021E1 +:102720000A001D638F85003C02602021240B000CF1 +:102730000E001A7BA38B006C240AFFFF104AFFBC1B +:102740002404FFFF8F8E003CA38000408E0D000408 +:102750008DC800D83C0600FF34CCFFFF01AC30240C +:102760000106182B1060FEE1AF86005802602021A0 +:10277000241200190E001A7BA392006C240FFFFF95 +:10278000104FFFAB2404FFFF0A001CB48F860058D3 +:102790002C7400201280FFDE2402000B000328802E +:1027A0003C1108012631955400B148218D2D0000BF +:1027B00001A00008000000008F85003800A710214C +:1027C00093850040AF82003802251821A383004082 +:1027D000951F00BC0226282137F91000A51900BC5E +:1027E0005240FF92AF850064246A0004A38A00402F +:1027F000950900BC24A40004AF8400643532200095 +:10280000A51200BC0A001D85000020218F860064EF +:102810002CCB00051560FF60978300603072FFFFCE +:1028200000D240232D18000513000003306400FF80 +:1028300024DFFFFC33E400FF8F8500688F860038BB +:1028400010A60004388F000131ED000115A00138F9 +:10285000000000008F84003C908C00D4358700106D +:10286000A08700D48F85003C8F860064978300602A +:10287000ACA000EC0A001D603062FFFF8CAA00844F +:102880008CB500843C0410000147102400028940EC +:1028900032B4007F0234302500C460253C0880003B +:1028A0002405000102602021240600010E0019DA2F +:1028B000AD0C08300A001CF48F85003C8C8200ECC3 +:1028C0001222FE7E0260202124090005A389006CEB +:1028D0000E001A7B2411FFFF1451FE782404FFFF21 +:1028E0000A001D862403FFFF8F8F00508F88003C55 +:1028F0008DF80000AD1800888DE70010AD07009836 +:102900008F8700640A001DE88F8600582407FFFFA8 +:1029100011870005000000000E001B7D02602021D1 +:102920000A001DC10040A0210E001B0202602021F0 +:102930000A001DC10040A0218F9000503C090800F2 +:102940008D2931B08E11001032323FFF0249682BC1 +:1029500011A0000C240AFF808F85005490AE000D5A +:10296000014E1024304C00FF11800007026020212E +:102970000011C38233030003240B0001106B010517 +:1029800000000000026020212418000D0E001A7BB8 +:10299000A398006C004020218F85003C0A001D6335 +:1029A0000080A0218F9000503C0A08008D4A31B071 +:1029B0008F8500548E0400100000A0218CB10014FB +:1029C00030823FFF004A602B8CB200205180FFEE26 +:1029D0000260202190B8000D240BFF800178702444 +:1029E00031C300FF5060FFE80260202100044382F1 +:1029F0003106000314C0FFE40260202194BF001CD4 +:102A00008F99003C8E060028A73F00E88CAF00108D +:102A1000022F202314C40139026020218F83005823 +:102A200000C36821022D382B14E001352402001860 +:102A30008F8A00488F820034024390218D4B001012 +:102A400001637023AD4E0010AD5200208C4C007419 +:102A50000192282B14A00156026020218F8400547B +:102A60008E0800248C8600241106000702602021B5 +:102A70002419001C0E001A7BA399006C240FFFFF81 +:102A8000104FFFC52404FFFF8F8400488C8700246B +:102A900024FF0001AC9F0024125101338F8D0034BC +:102AA0008DB10074123201303C0B00808E0E00009C +:102AB00001CB502415400075000000008E03001467 +:102AC0002411FFFF10710006026020212418001B52 +:102AD0000E001A7BA398006C1051FFAF2404FFFF77 +:102AE0008E0300003C0800010068302410C0001371 +:102AF0003C0400800064A024168000090200282104 +:102B0000026020212419001A0E001A7BA399006C80 +:102B1000240FFFFF104FFFA02404FFFF0200282115 +:102B2000026020210E001A9B240600012410FFFFE2 +:102B30001050FF992404FFFF241400018F9F0048C8 +:102B4000026020210280302197F100342405000129 +:102B500026270001A7E700340E0019DA0000000064 +:102B6000000020218F85003C0A001D630080A02109 +:102B70008F9000503C1408008E9431B08E070010E6 +:102B800030E83FFF0114302B10C000618F860054E5 +:102B9000241FFF8090C5000D03E52024309200FF24 +:102BA0005240005C026020218F8D005811A0000768 +:102BB00000078B828F85003C8F89FCC094AF00801A +:102BC0009539000A132F00F68F870044322C00033A +:102BD000158000630000000092020002104000D740 +:102BE000000000008E0A0024154000D80260202159 +:102BF0009204000324060002308800FF1506000539 +:102C0000308500FF8F940058528000F2026020212E +:102C1000308500FF38AD00102DA400012CBF00014D +:102C200003E43025020028210E001A9B02602021B7 +:102C30002410FFFF105000BE8F85003C8F8300588A +:102C4000106000C4240500013C1908008F39318C44 +:102C50000323782B15E000B12409002D0260202108 +:102C6000000028210E0019DA240600018F85003C9F +:102C7000000018210A001D630060A0210E0018A6A4 +:102C8000000000000A001E2900000000AC800020A7 +:102C90000A001EA98E0300140000282102602021D2 +:102CA0000E0019DA240600010A001CF48F85003C8E +:102CB0000A001DE88F88003C8CB000848CB9008429 +:102CC0003C0310000207482400096940332F007FAD +:102CD00001AFF82503E32825ACC5083091070001B2 +:102CE00024050001026020210E0019DA30E60001FF +:102CF0000A001CF48F85003C938F004C2403FFFDD9 +:102D00000A001D65AF8F00640A001D652403FFFFE4 +:102D1000026020212410000D0E001A7BA390006C8D +:102D2000004018218F85003C0A001D630060A0212F +:102D30000E0018A600000000978300608F860064D4 +:102D40003070FFFF00D048232D3900051320FE12FC +:102D50008F85003CACA200EC0A001D603062FFFFD2 +:102D600090C3000D307800085700FFA292040003C2 +:102D700002602021240200100E001A7BA382006C46 +:102D80002403FFFF5443FF9B920400030A001F43E8 +:102D90008F85003C90A8000D3106000810C00095FA +:102DA0008F9400581680009E026020218E0F000C28 +:102DB0008CA4002055E40005026020218E1F00082D +:102DC0008CB9002413F9003A02602021240200206B +:102DD0000E001A7BA382006C2405FFFF1045FEEE57 +:102DE0002404FFFF8F8F0048240CFFF72403FF808B +:102DF00091E9000D3C14800E3C0B8000012CC8248E +:102E0000A1F9000D8F8F00343C0708008CE731AC2E +:102E10008F8D007095E500788F99004800ED902126 +:102E200030BF7FFF001F20400244302130C8007FA8 +:102E300000C3C02401147021AD78002CA5D100007E +:102E40008F2A002825420001AF2200288F29002C5C +:102E50008E0C002C012C6821AF2D002C8E07002C2D +:102E6000AF2700308E050014AF250034973F003A9D +:102E700027E40001A724003A95F200783C100800EE +:102E80008E1031B02643000130717FFF1230005C9C +:102E9000006030218F83003402602021240500016E +:102EA0000E001965A46600780A001ED200002021D9 +:102EB0008E0700142412FFFF10F200638F8C003C79 +:102EC0008E0900188D8D00D0152D005D0260202127 +:102ED0008E0A00248CA200281142005324020021F3 +:102EE0000E001A7BA382006C1452FFBE2404FFFF65 +:102EF0008F85003C0A001D630080A0212402001F72 +:102F00000E001A7BA382006C2409FFFF1049FEA269 +:102F10002404FFFF0A001E858F83005802602021D1 +:102F20000E001A7BA389006C1450FF518F85003C62 +:102F30002403FFFF0A001D630060A0218CCE002443 +:102F40008E0B0024116EFF2A026020210A001F57F9 +:102F50002402000F0E001965026020218F85003CBD +:102F60000A001F16000018218E0900003C05008091 +:102F7000012590241640FF452402001A02602021FA +:102F80000E001A7BA382006C240CFFFF144CFECBB6 +:102F90002404FFFF8F85003C0A001D630080A021F0 +:102FA0002403FFFD0060A0210A001D63AF870064B9 +:102FB0002418001D0E001A7BA398006C2403FFFF49 +:102FC0001443FEA62404FFFF8F85003C0A001D6306 +:102FD0000080A0212412002C0E001A7BA392006C0A +:102FE0002403FFFF1043FF508F85003C0A001EFDA5 +:102FF00092040003026020210A001F6D24020024B5 +:10300000240B8000006B702431CAFFFF000A13C23A +:10301000305100FF001180270A001F9E001033C0AE +:103020000A001F6D240200278E0600288CAE002C9B +:1030300010CE0008026020210A001FB12402001FE8 +:103040000A001FB12402000E026020210A001FB1F5 +:10305000240200258E04002C1080000D8F83003484 +:103060008C7800740304582B5560000C02602021FA +:103070008CA800140086A0210114302B10C0FF5A28 +:103080008F8F0048026020210A001FB12402002215 +:10309000026020210A001FB1240200230A001FB190 +:1030A0002402002627BDFFD8AFB3001CAFB1001427 +:1030B000AFBF0020AFB20018AFB000103C028000DC +:1030C0008C5201408C4B01483C048000000B8C0268 +:1030D000322300FF317300FF8C8501B804A0FFFE8E +:1030E00034900180AE1200008C8701442464FFF00C +:1030F000240600022C830013AE070004A61100086A +:10310000A206000BAE1300241060004F8FBF0020FA +:10311000000448803C0A0801254A95D4012A402130 +:103120008D04000000800008000000003C0308003F +:103130008C6331A831693FFF0009998000728021BA +:10314000021370212405FF80264D0100264C0080CB +:103150003C02800031B1007F3198007F31CA007F8E +:103160003C1F800A3C1980043C0F800C01C52024C0 +:1031700001A5302401853824014F1821AC460024D4 +:10318000023F402103194821AC470090AC4400287D +:10319000AF830048AF88003CAF8900340E0019317E +:1031A000016080213C0380008C6B01B80560FFFE4C +:1031B0008F8700488F86003C3465018090E8000DC1 +:1031C000ACB20000A4B000060008260000041603FC +:1031D00000029027001227C21080008124C20088BC +:1031E000241F6082A4BF0008A0A0000524020002E2 +:1031F000A0A2000B8F8B0034000424003C082700A1 +:1032000000889025ACB20010ACA00014ACA0002443 +:10321000ACA00028ACA0002C8D6900382413FF80DE +:10322000ACA9001890E3000D02638024320500FF72 +:1032300010A000058FBF002090ED000D31AC007F85 +:10324000A0EC000D8FBF00208FB3001C8FB20018C0 +:103250008FB100148FB000103C0A10003C0E8000AB +:1032600027BD002803E00008ADCA01B8265F0100B1 +:103270002405FF8033F8007F3C06800003E57824B6 +:103280003C19800A03192021ACCF0024908E00D471 +:1032900000AE682431AC00FF11800024AF84003CF4 +:1032A000248E008895CD00123C0C08008D8C31A82E +:1032B00031AB3FFF01924821000B5180012A402190 +:1032C00001052024ACC400283107007F3C06800C97 +:1032D00000E620219083000D00A31024304500FF5C +:1032E00010A0FFD8AF8400489098000D330F001055 +:1032F00015E0FFD58FBF00200E001931000000003F +:103300003C0380008C7901B80720FFFE000000001C +:10331000AE1200008C7F0144AE1F0004A61100080D +:1033200024110002A211000BAE1300243C1308016B +:1033300092739790327000015200FFC38FBF00203C +:103340000E00216E024020210A00208B8FBF00203A +:103350003C1260008E452C083C03F0033462FFFFF2 +:1033600000A2F824AE5F2C088E582C083C1901C02E +:1033700003199825AE532C080A00208B8FBF00201C +:10338000264D010031AF007F3C10800A240EFF80E3 +:1033900001F0282101AE60243C0B8000AD6C0024BC +:1033A0001660FFA8AF85003C24110003A0B100FC0B +:1033B0000A00208B8FBF002026480100310A007FC1 +:1033C0003C0B800A2409FF80014B30210109202495 +:1033D0003C078000ACE400240A00208AAF86003C51 +:1033E000944E0012320C3FFF31CD3FFF15ACFF7DF4 +:1033F000241F608290D900D42418FF8003197824F8 +:1034000031EA00FF1140FF770000000024070004AC +:10341000A0C700FC8F870048241160842406000D9B +:10342000A4B10008A0A600050A002075240200022D +:103430003C0400012484977C24030014240200FE31 +:103440003C010800AC2431EC3C010800AC2331E81D +:103450003C010801A42297983C0408012484979811 +:103460000000182100643021A0C30004246300017F +:103470002C6500FF54A0FFFC006430213C070800CD +:1034800024E7010003E00008AF87007C00A058217A +:10349000008048210000102114A0001200005021DB +:1034A0000A00216A000000003C010801A42097984E +:1034B0003C05080194A597988F82007C3C0C08017C +:1034C000258C979800E2182100AC2021014B302B6D +:1034D000A089000400001021A460000810C0003979 +:1034E000010048218F86007C0009384000E9402116 +:1034F0000008388000E6282190A8000B90B9000A47 +:103500000008204000881021000218800066C021B9 +:10351000A319000A8F85007C00E5782191EE000A4E +:1035200091E6000B000E684001AE6021000C208087 +:1035300000851021A046000B3C0308019063979280 +:10354000106000222462FFFF8F83003C3C010801D1 +:10355000A0229792906C00FF1180000400000000F0 +:10356000906E00FF25CDFFFFA06D00FF3C19080104 +:1035700097399798272300013078FFFF2F0F00FF1E +:1035800011E0FFC9254A00013C010801A4239798D6 +:103590003C05080194A597988F82007C3C0C08019B +:1035A000258C979800E2182100AC2021014B302B8C +:1035B000A089000400001021A460000814C0FFC905 +:1035C0000100482103E000080000000003E00008BB +:1035D0002402000227BDFFE0248501002407FF80AC +:1035E000AFB00010AFBF0018AFB1001400A718248F +:1035F0003C10800030A4007F3C06800A0086282111 +:103600008E110024AE03002490A200FF1440000895 +:10361000AF85003CA0A000098FBF0018AE110024A8 +:103620008FB100148FB0001003E0000827BD002008 +:1036300090A900FD90A800FF312400FF0E00211C7E +:10364000310500FF8F85003C8FBF0018A0A0000946 +:10365000AE1100248FB100148FB0001003E00008F9 +:1036600027BD002027BDFFD0AFB20020AFB1001CA6 +:10367000AFB00018AFBF002CAFB40028AFB3002428 +:103680003C0980009533011635320C00952F011A44 +:103690003271FFFF023280218E08000431EEFFFFFD +:1036A000248B0100010E6821240CFF8025A5FFFF5B +:1036B000016C50243166007F3C07800AAD2A00244B +:1036C00000C73021AF850078AF8800743C01080145 +:1036D000A020979190C300090200D021008098217A +:1036E000306300FF2862000510400048AF86003CB0 +:1036F000286400021480008E24140001240D0005AB +:103700003C010801A02D977590CC00FD3C010801FB +:10371000A02097763C010801A020977790CB000A63 +:10372000240AFF80318500FF014B4824312700FF28 +:1037300010E0000C000058213C1280083651008037 +:103740008E2F00308CD0005C01F0702305C0018EFC +:103750008F87007490D4000A3284007FA0C4000ACE +:103760008F86003C3C118008363000808E0F003080 +:103770008F87007400EF702319C000EE0000000076 +:1037800090D4000924120002328400FF10920247F4 +:10379000000000008CC2005800E2F82327F9FFFF68 +:1037A0001B2001300000000090C50009240800041F +:1037B00030A300FF10680057240A00013C010801F3 +:1037C000A02A977590C900FF252700013C01080138 +:1037D000A02797743C0308019063977524060005A1 +:1037E0001066006A2C780005130000C400009021C8 +:1037F0000003F8803C0408012484962003E4C821D7 +:103800008F25000000A0000800000000241800FF21 +:103810001078005C0000000090CC000A90CA0009FB +:103820003C080801910897913187008000EA4825FB +:103830003C010801A029977C90C500FD3C140801BB +:1038400092949792311100013C010801A025977DC7 +:1038500090DF00FE3C010801A03F977E90D200FF60 +:103860003C010801A032977F8CD900543C0108012B +:10387000AC3997808CD000583C010801AC3097845B +:103880008CC3005C3C010801AC34978C3C010801FE +:10389000AC239788162000088FBF002C8FB4002817 +:1038A0008FB300248FB200208FB1001C8FB000189E +:1038B00003E0000827BD00303C1180009624010E73 +:1038C0000E000FD43094FFFF3C0B08018D6B9794D2 +:1038D0000260382102802821AE2B01803C130801B0 +:1038E0008E73977401602021240600830E00102F30 +:1038F000AFB300108FBF002C8FB400288FB300240B +:103900008FB200208FB1001C8FB0001803E00008B8 +:1039100027BD00303C1808008F1831FC270F00012C +:103920003C010800AC2F31FC0A0021FF0000000020 +:103930001474FFB900000000A0C000FF3C0508009F +:103940008CA531E43C0308008C6331E03C020800A4 +:103950008C4232048F99003C34A80001241F0002DD +:103960003C010801AC2397943C010801A0289790E2 +:103970003C010801A0229793A33F00090A0021B847 +:103980008F86003C0E00216E000000000A0021FF1F +:103990008F86003C3C1F080193FF97742419000197 +:1039A00013F902298F8700743C1008019210977850 +:1039B0003C06080190C6977610C000050200A021C1 +:1039C0003C04080190849779109001E48F87007C73 +:1039D000001088408F9F007C023048210009C88079 +:1039E000033F702195D80008270F0001A5CF0008DC +:1039F0003C040801908497793C05080190A59776CE +:103A00000E00211C000000008F87007C0230202166 +:103A10000004308000C720218C8500048F8200784C +:103A200000A2402305020006AC8200048C8A00003C +:103A30008F830074014310235C400001AC830000BD +:103A40008F86003C90CB00FF2D6C00025580002D2E +:103A5000241400010230F821001F408001072821B2 +:103A600090B9000B8CAE00040019C04003197821F6 +:103A7000000F1880006710218C4D000001AE8823D4 +:103A80002630FFFF5E00001F241400018C44000458 +:103A90008CAA0000008A482319200019240E000473 +:103AA0003C010801A02E977590AD000B8CAB000473 +:103AB000000D8840022D8021001010800047102149 +:103AC0008C440004016460230582020094430008D2 +:103AD00090DF00FE90B9000B33E500FF54B90004FD +:103AE0000107A021A0D400FE8F87007C0107A02140 +:103AF0009284000B0E00211C240500018F86003CDF +:103B000024140001125400962E50000116000042A9 +:103B10003C08FFFF241900021659FF3F0000000077 +:103B2000A0C000FF8F86003CA0D200090A0021FF40 +:103B30008F86003C90C700092404000230E300FF98 +:103B40001064016F24090004106901528F88007805 +:103B50008CCE0054010E682325B1000106200175AA +:103B6000241800043C010801A03897753C010801A5 +:103B7000A020977490D400FD90D200FF2E4F000239 +:103B800015E0FF14328400FF000438408F89007C68 +:103B900090DF00FF00E41021000220800089C8218E +:103BA0002FE500029324000B14A0FF0A2407000253 +:103BB0000004184000648021001058800169282109 +:103BC0008CAC0004010C50230540FF0200000000F3 +:103BD0003C0308019063977614600005246F000190 +:103BE0003C010801A02497793C010801A0279777A0 +:103BF0003C010801A02F977690CE00FF24E700013A +:103C000031CD00FF01A7882B1220FFE990A4000B03 +:103C10000A0021EE000000003C0508018CA5977405 +:103C20003C12000400A8F82413F200062402000548 +:103C30003C09080191299775152000022402000310 +:103C4000240200053C010801A022979190C700FFC3 +:103C500014E0012024020002A0C200090A0021FF92 +:103C60008F86003C90CC00FF1180FEDA240A000110 +:103C70008F8C00788F89007C240F000301806821DD +:103C80001160001E240E0002000540400105A02125 +:103C900000142080008990218E510004019180231E +:103CA0000600FECC000000003C020801904297761E +:103CB00014400005245800013C010801A02A977710 +:103CC0003C010801A02597793C010801A0389776AE +:103CD00090DF00FF010510210002C88033E500FFDE +:103CE000254A00010329202100AA402B1500FEB916 +:103CF0009085000B1560FFE5000540400005404041 +:103D000001051821000310803C010801A02A9774C6 +:103D10003C010801A0259778004918218C64000413 +:103D200000E4F82327F9FFFF1F20FFE9000000004F +:103D30008C63000000E358230560013A01A3882347 +:103D400010E301170184C0231B00FEA20000000045 +:103D50003C010801A02E97750A00232D240B0001B9 +:103D6000240E0004A0CE00093C0D08008DAD31F8F2 +:103D70008F86003C25A200013C010800AC2231F8EE +:103D80000A0021FF000000008CD9005C00F9C0236C +:103D90001F00FE7B000000008CDF005C10FFFF6551 +:103DA0008F8400788CC3005C0083402325020001CF +:103DB0001C40FF60000000008CC9005C24870001EB +:103DC00000E9282B10A0FE943C0D80008DAB01046F +:103DD0003C0C0001016C50241140FE8F24020010A5 +:103DE0003C010801A02297910A0021FF0000000079 +:103DF0008F9100788F86003C26220001ACC2005CC7 +:103E00000A0022BA241400018F87003C2404FF809A +:103E10000000882190E9000A2414000101243025C3 +:103E2000A0E6000A3C05080190A597763C0408012D +:103E3000908497790E00211C000000008F86003CC2 +:103E40008F85007C90C800FD310700FF00074040CF +:103E50000107F821001FC0800305C8219323000B30 +:103E6000A0C300FD8F85007C8F86003C0305602188 +:103E7000918F000B000F704001CF6821000D8080F2 +:103E8000020510218C4B0000ACCB00548D84000443 +:103E90008F830078006450231940000224820001BF +:103EA0002462000101074821ACC2005C0009308097 +:103EB00000C5402100E02021240500010E00211C46 +:103EC0009110000B8F86003C90C500FF10A0FF0CE6 +:103ED000001070408F85007C01D06821000D10809B +:103EE000004558218D6400008F8C00780184502398 +:103EF0002547000104E0FF02263100013C030801D0 +:103F0000906397762E2F0002247800013C0108016F +:103F1000A03897763C010801A034977711E0FEF8AD +:103F2000020038210A00238D000740408F84003CA6 +:103F30008F8300788C85005800A340230502FE9AE9 +:103F4000AC8300580A002263000000003C0708010F +:103F500090E79792240200FF10E200BE8F86003C9B +:103F60003C1108019631979A3C0308012463979805 +:103F7000262500013230FFFF30ABFFFF0203602136 +:103F80002D6A00FF1540008D918700043C01080157 +:103F9000A420979A8F88003C0007484001272821D9 +:103FA000911800FF0005308024050001271400014E +:103FB000A11400FF3C120801925297928F88007C56 +:103FC0008F8E0074264F000100C820213C0108019B +:103FD000A02F9792AC8E00008F8D0078A4850008EA +:103FE000AC8D00043C030801906397741460007763 +:103FF000000090213C010801A0259774A087000BC8 +:104000008F8C007C00CC5021A147000A8F82003C9D +:10401000A04700FD8F84003CA08700FE8F86003CF7 +:104020008F9F0074ACDF00548F990078ACD9005892 +:104030008F8D007C0127C02100185880016DA021C0 +:10404000928F000A000F704001CF18210003888072 +:10405000022D8021A207000B8F86007C0166602163 +:10406000918A000B000A1040004A20210004288099 +:1040700000A64021A107000A3C07800834E900801F +:104080008D2200308F86003CACC2005C0A0022BA50 +:104090002414000190CA00FF1540FEAD8F880078FF +:1040A000A0C400090A0021FF8F86003CA0C000FDCB +:1040B0008F98003C24060001A30000FE3C0108018B +:1040C000A02697753C010801A02097740A0021EEF4 +:1040D0000000000090CB00FF3C04080190849793FF +:1040E000316C00FF0184502B1540000F24020003A7 +:1040F00024020004A0C200090A0021FF8F86003CB0 +:1041000090C3000A2410FF8002035824316C00FF82 +:104110001180FDC1000000003C010801A02097753E +:104120000A0021EE00000000A0C200090A0021FFE1 +:104130008F86003C90D4000A2412FF800254482449 +:10414000312800FF1500FFF4240200083C0108019B +:10415000A02297910A0021FF000000000010884073 +:104160008F8B0074023018210003688001A7202182 +:10417000AC8B00008F8A0078240C0001A48C00080E +:10418000AC8A00043C05080190A597762402000142 +:1041900010A2FE1E24A5FFFF0A0022799084000BC6 +:1041A0000184A0231A80FD8B000000003C0108015F +:1041B000A02E97750A00232D240B00013C01080155 +:1041C000A425979A0A0023DF8F88003C240B000166 +:1041D000106B00228F98003C8F85003C90BF00FF41 +:1041E00033F900FF1079002B000000003C1F08018C +:1041F00093FF9778001FC840033FC0210018A0809C +:104200000288782191EE000AA08E000A8F8D007C32 +:104210003C0308019063977800CD88210A002405AB +:10422000A223000B263000010600003101A49023D8 +:104230000640002B240200033C010801A02F9775C3 +:104240000A00232D240B00018F89003C0A00226301 +:10425000AD2700540A0022B924120001931400FD76 +:10426000A094000B8F88003C8F8F007C910E00FE85 +:1042700000CF6821A1AE000A8F91003CA22700FD6B +:104280008F8300748F90003CAE0300540A00240614 +:104290008F8D007C90B000FEA090000A8F8B003CB8 +:1042A0008F8C007C916A00FD00CC1021A04A000B8D +:1042B0008F84003CA08700FE8F8600788F85003CAD +:1042C000ACA600580A0024068F8D007C94B8000824 +:1042D000ACA40004030378210A0022ADA4AF0008B7 +:1042E0003C010801A02297750A0021EE00000000A1 +:1042F00090CF0009240D000431EE00FF11CDFD85A3 +:10430000240200013C010801A02297750A0021EE59 +:0443100000000000A9 +:0C43140008003344080033440800342043 +:10432000080033F4080033D8080033280800332885 +:10433000080033280800334C800801008008008002 +:10434000800800005F865437E4AC62CC50103A45D8 +:1043500036621985BF14C0E81BC27A1E84F4B556B4 +:10436000094EA6FE7DDA01E7C04D748108005B3876 +:1043700008005B7C08005B2008005B2008005B20D5 +:1043800008005B2008005B3808005B2008005B2009 +:1043900008005B8408005B2008005A9808005B2036 +:1043A00008005B2008005B8408005B2008005B209D +:1043B00008005B2008005B2008005B2008005B20F1 +:1043C00008005B2008005B2008005B2008005B20E1 +:1043D00008005B5808005B2008005B5808005B2061 +:1043E00008005B2008005B2008005B5C08005B584D +:1043F00008005B2008005B2008005B2008005B20B1 +:1044000008005B2008005B2008005B2008005B20A0 +:1044100008005B2008005B2008005B2008005B2090 +:1044200008005B2008005B2008005B2008005B2080 +:1044300008005B2008005B2008005B2008005B2070 +:1044400008005B5C08005B5C08005B2008005B5CAC +:1044500008005B2008005B2008005B2008005B2050 +:1044600008005B2008005B2008005B2008005B2040 +:1044700008005B2008005B2008005B2008005B2030 +:1044800008005B2008005B2008005B2008005B2020 +:1044900008005B2008005B2008005B2008005B2010 +:1044A00008005B2008005B2008005B2008005B2000 +:1044B00008005B2008005B2008005B2008005B20F0 +:1044C00008005B2008005B2008005B2008005B20E0 +:1044D00008005B2008005B2008005B2008005B20D0 +:1044E00008005B2008005B2008005B2008005B20C0 +:1044F00008005B2008005B2008005B2008005B20B0 +:1045000008005B2008005B2008005B2008005B209F +:1045100008005B2008005B2008005B2008005B208F +:1045200008005B2008005B2008005B2008005B207F +:1045300008005B2008005B2008005B2008005B206F +:1045400008005B2008005B2008005B2008005B205F +:1045500008005B2008005B2008005B2008005B204F +:1045600008005B2008005B2008005B2008005BA0BF +:10457000080078F008007B54080078FC080076F00A +:10458000080078FC08007988080078FC080076F0BC +:10459000080076F0080076F0080076F0080076F063 +:1045A000080076F0080076F0080076F0080076F053 +:1045B000080076F00800791C0800790C080076F0F5 +:1045C000080076F0080076F0080076F0080076F033 +:1045D000080076F0080076F0080076F0080076F023 +:1045E000080076F0080076F0080076F00800790CF4 +:1045F0000800839C08008228080083640800822841 +:1046000008008334080081100800822808008228EE +:1046100008008228080082280800822808008228D2 +:1046200008008228080082280800822808008228C2 +:1046300008008228080082280800825008008DD4D3 +:1046400008008F3008008F100800897808008DEC72 +:104650000A00012400000000000000000000000D1E +:10466000747061362E322E31000000000602010106 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E0000000000010000003000000000000000DAA +:1046F0000000000D3C020800244217203C03080083 +:1047000024632A10AC4000000043202B1480FFFDDE +:10471000244200043C1D080037BD2FFC03A0F021FB +:104720003C100800261004903C1C0800279C172011 +:104730000E000262000000000000000D2402FF8055 +:1047400027BDFFE000821024AFB00010AF42002070 +:10475000AFBF0018AFB10014936500043084007F30 +:10476000034418213C0200080062182130A50020F3 +:10477000036080213C080111277B000814A000027F +:104780002466005C246600589202000497430104EA +:10479000920400043047000F3063FFFF3084004074 +:1047A00000672823108000090000482192020005BC +:1047B00030420004104000050000000010A000037B +:1047C0000000000024A5FFFC24090004920200055B +:1047D00030420004104000120000000010A0001041 +:1047E000000000009602000200A7202101044025DD +:1047F0002442FFFEA7421016920300042402FF8009 +:1048000000431024304200FF104000033C0204002B +:104810000A000174010240258CC20000AF4210184A +:104820008F4201780440FFFE2402000AA7420140A3 +:1048300096020002240400093042000700021023FF +:1048400030420007A7420142960200022442FFFEC6 +:10485000A7420144A740014697420104A7420148EC +:104860008F42010830420020504000012404000122 +:104870009202000430420010144000023483001001 +:1048800000801821A743014A00000000000000003A +:104890000000000000000000AF4810000000000011 +:1048A0000000000000000000000000008F42100027 +:1048B0000441FFFE3102FFFF10400007000000002E +:1048C0009202000430420040144000030000000047 +:1048D0008F421018ACC20000960200063042FFFF63 +:1048E00024420002000210430002104003628821AB +:1048F000962200001120000D3044FFFF00A7102178 +:104900008F8300388F45101C000210820002108037 +:1049100000431021AC45000030A6FFFF0E00058DBE +:1049200000052C0200402021A62200009203000472 +:104930002402FF8000431024304200FF1040001F7B +:104940000000000092020005304200021040001BEF +:10495000000000009742100C2442FFFEA7421016F0 +:10496000000000003C02040034420030AF4210005E +:104970000000000000000000000000000000000037 +:104980008F4210000441FFFE000000009742100C0F +:104990008F45101C3042FFFF24420030000210827D +:1049A00000021080005B1021AC45000030A6FFFF24 +:1049B0000E00058D00052C02A622000096040002C0 +:1049C000248400080E0001E93084FFFF97440104AD +:1049D0000E0001F73084FFFF8FBF00188FB1001465 +:1049E0008FB000103C02100027BD002003E000083B +:1049F000AF4201783084FFFF308200078F850024AA +:104A000010400002248300073064FFF800A4102146 +:104A100030421FFF03421821247B4000AF8500284D +:104A2000AF82002403E00008AF4200843084FFFF1F +:104A30003082000F8F85002C8F86003410400002DA +:104A40002483000F3064FFF000A410210046182BCF +:104A5000AF8500300046202314600002AF82002C96 +:104A6000AF84002C8F82002C340480000342182174 +:104A700000641821AF83003803E00008AF420080D3 +:104A80008F820014104000088F8200048F82FFDCA8 +:104A9000144000058F8200043C02FFBF3442FFFF38 +:104AA000008220248F82000430430006240200028A +:104AB0001062000F3C0201012C620003504000050F +:104AC000240200041060000F3C0200010A000230C2 +:104AD0000000000010620005240200061462000CB1 +:104AE0003C0201110A000229008210253C0200113B +:104AF00000821025AF421000240200010A0002309B +:104B0000AF82000C00821025AF421000AF80000C75 +:104B100000000000000000000000000003E00008AA +:104B2000000000008F82000C104000040000000014 +:104B30008F4210000441FFFE0000000003E0000867 +:104B4000000000008F8200102443F800000231C2F0 +:104B500024C2FFF02C630301106000030002104226 +:104B60000A000257AC8200008F85001800C5102B88 +:104B70001440000B0000182100C510232447000139 +:104B80008F82001C00A210212442FFFF0046102B40 +:104B9000544000042402FFFF0A000257AC870000C3 +:104BA0002402FFFF0A000260AC8200008C82000039 +:104BB00000021940006218210003188000621821C9 +:104BC000000318803C0208002442175C0062182190 +:104BD00003E000080060102127BDFFD8AFBF002010 +:104BE000AFB1001CAFB000183C0460088C825000CC +:104BF0002403FF7F3C066000004310243442380C3D +:104C0000AC8250008CC24C1C3C1A80000002160280 +:104C10003042000F10400007AF82001C8CC34C1CB8 +:104C20003C02001F3442FC0000621824000319C239 +:104C3000AF8300188F420008275B40003442000118 +:104C4000AF420008AF8000243C02601CAF400080EF +:104C5000AF4000848C4500088CC3080834028000F3 +:104C6000034220212402FFF0006218243C0200804D +:104C70003C010800AC2204203C025709AF840038F4 +:104C800014620004AF850034240200010A0002927D +:104C9000AF820014AF8000148F4200003842000140 +:104CA000304200011440FFFC8F82001410400016B7 +:104CB0000000000097420104104000058F830000AF +:104CC000146000072462FFFF0A0002A72C62000A9A +:104CD0002C620010504000048F8300002462000109 +:104CE000AF8200008F8300002C62000A1440000392 +:104CF0002C6200070A0002AEAF80FFDC1040000209 +:104D000024020001AF82FFDC8F4301088F440100C1 +:104D100030622000AF83000410400008AF84001010 +:104D20003C0208008C42042C244200013C01080093 +:104D3000AC22042C0A00058A3C02400030650200C7 +:104D400014A0000324020F001482026024020D004C +:104D500097420104104002C83C024000306240000B +:104D6000144000AD8F8200388C4400088F420178D7 +:104D70000440FFFE24020800AF420178240200082C +:104D8000A7420140A7400142974201048F840004DA +:104D90003051FFFF308200011040000702208021C7 +:104DA0002623FFFE240200023070FFFFA7420146C7 +:104DB0000A0002DBA7430148A74001463C02080065 +:104DC0008C42043C1440000D8F8300103082002080 +:104DD0001440000224030009240300010060202184 +:104DE0008F83001024020900506200013484000403 +:104DF000A744014A0A0002F60000000024020F0046 +:104E00001462000530820020144000062403000DC7 +:104E10000A0002F5240300051440000224030009DF +:104E200024030001A743014A3C0208008C420420ED +:104E30003C0400480E00020C004420250E00023500 +:104E4000000000008F82000C1040003E00000000B7 +:104E50008F4210003C030020004310241040003912 +:104E60008F82000430420002104000360000000033 +:104E700097421014144000330000000097421008BD +:104E80008F8800383042FFFF24420006000218825B +:104E90000003388000E83021304300018CC400005A +:104EA00010600004304200030000000D0A000337C8 +:104EB00000E81021544000103084FFFF3C05FFFF44 +:104EC00000852024008518260003182B0004102BD1 +:104ED0000043102410400005000000000000000006 +:104EE0000000000D00000000240002228CC200001F +:104EF0000A000336004520253883FFFF0003182BE6 +:104F00000004102B00431024104000050000000096 +:104F1000000000000000000D000000002400022B33 +:104F20008CC200003444FFFF00E81021AC440000B4 +:104F30003C0208008C420430244200013C0108007D +:104F4000AC2204308F6200008F840038AF820008EA +:104F50008C8300003402FFFF1462000F0000102158 +:104F60003C0508008CA504543C0408008C840450C3 +:104F700000B0282100B0302B0082202100862021A3 +:104F80003C010800AC2504543C010800AC2404504A +:104F90000A000580240400088C82000030420100D1 +:104FA0001040000F000010213C0508008CA5044CA7 +:104FB0003C0408008C84044800B0282100B0302B49 +:104FC00000822021008620213C010800AC25044CF1 +:104FD0003C010800AC2404480A00058024040008B1 +:104FE0003C0508008CA504443C0408008C84044063 +:104FF00000B0282100B0302B008220210086202123 +:105000003C010800AC2504443C010800AC240440E9 +:105010000A000580240400088F6200088F620000E7 +:1050200000021602304300F0240200301062000536 +:1050300024020040106200E08F8200200A000588F0 +:105040002442000114A00005000000000000000040 +:105050000000000D00000000240002568F4201787D +:105060000440FFFE000000000E00023D27A40010D7 +:105070001440000500408021000000000000000DE9 +:10508000000000002400025D8E02000010400005B8 +:1050900000000000000000000000000D0000000003 +:1050A000240002608F62000C04430003240200010C +:1050B0000A00042EAE000000AE0200008F8200380D +:1050C0008C480008A20000078F65000C8F64000464 +:1050D00030A3FFFF0004240200852023308200FF5C +:1050E0000043102124420005000230832CC20081BD +:1050F000A605000A14400005A204000400000000F8 +:105100000000000D00000000240002788F850038A8 +:105110000E0005AB260400148F6200048F430108C3 +:10512000A60200083C02100000621824106000086B +:105130000000000097420104920300072442FFECA4 +:10514000346300023045FFFF0A0003C3A2030007D7 +:10515000974201042442FFF03045FFFF9606000805 +:105160002CC200135440000592030007920200076E +:1051700034420001A202000792030007240200014A +:1051800010620005240200031062000B8F820038B9 +:105190000A0003E030C6FFFF8F8200383C04FFFFA7 +:1051A0008C43000C0064182400651825AC43000CE7 +:1051B0000A0003E030C6FFFF3C04FFFF8C430010F1 +:1051C0000064182400651825AC43001030C6FFFFAA +:1051D00024C2000200021083A20200058F8300385F +:1051E000304200FF00021080004328218CA80000FC +:1051F0008CA20000240300040002170214430012D2 +:1052000000000000974201043C03FFFF0103182443 +:105210003042FFFF004610232442FFFE006240257B +:10522000ACA8000092030005306200FF000210806D +:1052300000501021904200143042000F0043102112 +:105240000A000415A20200068CA40004974201047F +:105250009603000A3088FFFF3042FFFF004610230C +:105260002442FFD60002140001024025ACA800042D +:1052700092020007920400052463002800031883AB +:105280000064182134420004A2030006A2020007B1 +:105290008F8200042403FFFB3442000200431024E9 +:1052A000AF820004920300068F8700380003188045 +:1052B000007010218C4400203C02FFF63442FFFFB6 +:1052C0000082402400671821AE04000CAC68000C7A +:1052D000920500063C03FF7F8E02000C000528802B +:1052E00000B020213463FFFF01033024948800269E +:1052F00000A7282100431024AE02000CAC86002039 +:10530000AC880024ACA8001024020010A742014081 +:1053100024020002A7400142A7400144A7420146DF +:10532000974201043C0400082442FFFEA7420148C2 +:10533000240200010E00020CA742014A9603000A53 +:105340009202000400431021244200023042000770 +:1053500000021023304200070E000235AE0200109A +:105360008F6200003C0308008C6304442404001096 +:10537000AF820008974201043042FFFF2442FFFE43 +:1053800000403821000237C33C0208008C42044030 +:10539000006718210067282B0046102100451021C6 +:1053A0003C010800AC2304443C010800AC2204404A +:1053B0000A0005150000000014A000050000000010 +:1053C000000000000000000D000000002400030A9F +:1053D0008F4201780440FFFE000000000E00023DF5 +:1053E00027A40014144000050040802100000000A4 +:1053F0000000000D00000000240003118E020000D8 +:105400005440000692020007000000000000000D5A +:10541000000000002400031C920200073042000438 +:10542000104000058F8200042403FFFB3442000279 +:1054300000431024AF8200048F620004044300087C +:1054400092020007920200068E03000CAE000000DC +:105450000002108000501021AC430020920200078F +:1054600030420004544000099602000A92020005EE +:105470003C03000100021080005010218C460018EF +:1054800000C33021AC4600189602000A92060004C0 +:10549000277100080220202100C2302124C6000507 +:1054A000260500140E0005AB0006308292040006AB +:1054B0008F6500043C027FFF0004208000912021C2 +:1054C0008C8300043442FFFF00A2282400651821C9 +:1054D000AC830004920200079204000592030004CA +:1054E000304200041040001496070008308400FF8A +:1054F00000042080009120218C8600049742010442 +:105500009605000A306300FF3042FFFF0043102180 +:105510000045102130E3FFFF004310232442FFD851 +:1055200030C6FFFF0002140000C23025AC86000424 +:105530000A0004C992030007308500FF0005288097 +:1055400000B128218CA4000097420104306300FFC1 +:105550003042FFFF00431021004710233C03FFFFB0 +:10556000008320243042FFFF00822025ACA40000ED +:1055700092030007240200011062000600000000F0 +:105580002402000310620011000000000A0004EC75 +:105590008E03001097420104920300049605000A4E +:1055A0008E24000C00431021004510212442FFF2FC +:1055B0003C03FFFF008320243042FFFF00822025B0 +:1055C000AE24000C0A0004EC8E0300109742010484 +:1055D000920300049605000A8E2400100043102157 +:1055E000004510212442FFEE3C03FFFF00832024EE +:1055F0003042FFFF00822025AE2400108E030010F1 +:105600002402000AA7420140A74301429603000A70 +:10561000920200043C04004000431021A7420144D0 +:10562000A740014697420104A74201482402000115 +:105630000E00020CA742014A0E00023500000000D5 +:105640008F6200009203000400002021AF82000856 +:10565000974201049606000A3042FFFF00621821BB +:10566000006028213C0308008C6304443C020800CD +:105670008C42044000651821004410210065382B3D +:10568000004710213C010800AC2304443C01080001 +:10569000AC22044092040004008620212484000AE5 +:1056A0003084FFFF0E0001E9000000009744010470 +:1056B0003084FFFF0E0001F7000000003C021000E4 +:1056C000AF4201780A0005878F82002014820027EC +:1056D0003062000697420104104000673C0240001F +:1056E0003062400010400005000000000000000093 +:1056F0000000000D00000000240004208F4201780B +:105700000440FFFE24020800AF4201782402000892 +:10571000A7420140A74001428F8200049743010441 +:1057200030420001104000073070FFFF2603FFFEEB +:1057300024020002A7420146A74301480A00053F90 +:105740002402000DA74001462402000DA742014A91 +:105750008F62000024040008AF8200080E0001E9F7 +:10576000000000000A00051902002021104000423C +:105770003C02400093620000304300F0240200101D +:105780001062000524020070106200358F82002034 +:105790000A000588244200018F620000974301043B +:1057A0003050FFFF3071FFFF8F4201780440FFFE51 +:1057B0003202000700021023304200072403000ACF +:1057C0002604FFFEA7430140A7420142A74401442B +:1057D000A7400146A75101488F42010830420020EE +:1057E000144000022403000924030001A743014AD6 +:1057F0000E00020C3C0400400E00023500000000C8 +:105800003C0708008CE70444021110212442FFFEEB +:105810003C0608008CC604400040182100E33821F3 +:10582000000010218F65000000E3402B00C23021F2 +:105830002604000800C830213084FFFFAF8500082F +:105840003C010800AC2704443C010800AC2604409D +:105850000E0001E9000000000A00051902202021C5 +:105860000E00013B000000008F8200202442000156 +:10587000AF8200203C024000AF4201380A00029291 +:10588000000000003084FFFF30C6FFFF00052C0041 +:1058900000A628253882FFFF004510210045282B4F +:1058A0000045102100021C023042FFFF004310217E +:1058B00000021C023042FFFF004310213842FFFF6C +:1058C00003E000083042FFFF3084FFFF30A5FFFFF8 +:1058D0000000182110800007000000003082000145 +:1058E0001040000200042042006518210A0005A1B2 +:1058F0000005284003E000080060102110C00006E9 +:1059000024C6FFFF8CA2000024A50004AC82000086 +:105910000A0005AB2484000403E000080000000036 +:1059200010A0000824A3FFFFAC86000000000000C8 +:10593000000000002402FFFF2463FFFF1462FFFA4F +:0C5940002484000403E0000800000000C4 +:04594C000000000156 +:105950000A00002A00000000000000000000000D06 +:10596000747870362E322E310000000006020100DD +:1059700000000000000001360000EA6000000000A6 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000016000000000000000000000000D1 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E000000000000000000000001388000000001C +:1059F000000005DC000000000000000010000003B3 +:105A0000000000000000000D0000000D3C02080036 +:105A100024423D883C0308002463403CAC40000025 +:105A20000043202B1480FFFD244200043C1D08008D +:105A300037BD7FFC03A0F0213C100800261000A811 +:105A40003C1C0800279C3D880E00044E000000000E +:105A50000000000D27BDFFB4AFA10000AFA20004FD +:105A6000AFA30008AFA4000CAFA50010AFA60014B0 +:105A7000AFA70018AFA8001CAFA90020AFAA002450 +:105A8000AFAB0028AFAC002CAFAD0030AFAE0034F0 +:105A9000AFAF0038AFB8003CAFB90040AFBC004476 +:105AA000AFBF00480E000591000000008FBF004806 +:105AB0008FBC00448FB900408FB8003C8FAF0038D6 +:105AC0008FAE00348FAD00308FAC002C8FAB002830 +:105AD0008FAA00248FA900208FA8001C8FA7001870 +:105AE0008FA600148FA500108FA4000C8FA30008B0 +:105AF0008FA200048FA1000027BD004C3C1B600456 +:105B00008F7A5030377B502803400008AF7A00006E +:105B10008F86003C3C0390003C02800000862825D4 +:105B200000A32025AC4400203C0380008C670020AB +:105B300004E0FFFE0000000003E000080000000099 +:105B40000A000070240400018F85003C3C048000A2 +:105B50003483000100A3102503E00008AC8200207C +:105B600003E00008000010213084FFFF30A5FFFF94 +:105B70001080000700001821308200011040000250 +:105B800000042042006518211480FFFB0005284016 +:105B900003E000080060102110C0000700000000B2 +:105BA0008CA2000024C6FFFF24A50004AC820000E4 +:105BB00014C0FFFB2484000403E000080000000080 +:105BC00010A0000824A3FFFFAC8600000000000026 +:105BD000000000002402FFFF2463FFFF1462FFFAAD +:105BE0002484000403E000080000000090AA0031B3 +:105BF0008FAB00108CAC00403C0300FF8D680004AC +:105C0000AD6C00208CAD004400E060213462FFFFE9 +:105C1000AD6D00248CA700483C09FF000109C02499 +:105C2000AD6700288CAE004C0182C824031978258A +:105C3000AD6F0004AD6E002C8CAD0038314A00FF12 +:105C4000AD6D001C94A900323128FFFFAD68001033 +:105C500090A70030A5600002A1600004A1670000C9 +:105C600090A30032306200FF00021982106000052C +:105C7000240500011065000E0000000003E000088C +:105C8000A16A00018CD80028354A0080AD78001840 +:105C90008CCF0014AD6F00148CCE0030AD6E0008B8 +:105CA0008CC4002CA16A000103E00008AD64000C64 +:105CB0008CCD001CAD6D00188CC90014AD690014AA +:105CC0008CC80024AD6800088CC70020AD67000CAC +:105CD0008CC200148C8300700043C82B1320000773 +:105CE000000000008CC20014144CFFE4000000000F +:105CF000354A008003E00008A16A00018C82007030 +:105D00000A0000E6000000009089003027BDFFF87F +:105D10008FA8001CA3A900008FA300003C0DFF80EA +:105D200035A2FFFF8CAC002C00625824AFAB000002 +:105D3000A100000400C05821A7A000028D060004A5 +:105D400000A048210167C8218FA5000000805021D4 +:105D50003C18FF7F032C20263C0E00FF2C8C0001FA +:105D6000370FFFFF35CDFFFF3C02FF0000AFC82417 +:105D700000EDC02400C27824000C1DC00323682558 +:105D800001F87025AD0D0000AD0E00048D24002437 +:105D9000AFAD0000AD0400088D2C00202404FFFFEF +:105DA000AD0C000C9547003230E6FFFFAD06001049 +:105DB0009145004830A200FF000219C25060000166 +:105DC0008D240034AD0400148D4700388FAA0018CC +:105DD00027BD0008AD0B0028AD0A0024AD07001C4C +:105DE000AD00002CAD00001803E00008AD0000205D +:105DF00027BDFFE0AFB20018AFB10014AFB0001084 +:105E0000AFBF001C9098003000C088213C0D00FFFF +:105E1000330F007FA0CF0000908E003135ACFFFF24 +:105E20003C0AFF00A0CE000194A6001EA2200004A0 +:105E30008CAB00148E29000400A08021016C282462 +:105E4000012A40240080902101052025A626000279 +:105E5000AE24000426050020262400080E0000922F +:105E6000240600029247003026050028262400144C +:105E700000071E000003160324060004044000036C +:105E80002403FFFF965900323323FFFF0E000092D8 +:105E9000AE230010262400248FBF001C8FB20018F0 +:105EA0008FB100148FB000102405000300003021D2 +:105EB0000A00009C27BD002027BDFFD8AFB1001C01 +:105EC000AFB00018AFBF002090A90030240200013D +:105ED00000E050213123003F00A040218FB000405E +:105EE0000080882100C04821106200148FA700386C +:105EF000240B000500A0202100C02821106B0013F6 +:105F0000020030210E000128000000009225007CD4 +:105F100030A400021080000326030030AE000030E1 +:105F2000260300348FBF00208FB1001C8FB00018F3 +:105F30000060102103E0000827BD00280E0000A724 +:105F4000AFB000100A00016F000000008FA3003CFA +:105F5000010020210120282101403021AFA30010A1 +:105F60000E0000EEAFB000140A00016F0000000048 +:105F70003C06800034C20E008C4400108F85004423 +:105F8000ACA400208C43001803E00008ACA300245C +:105F90003C06800034C20E008C4400148F850044FF +:105FA000ACA400208C43001C03E00008ACA3002438 +:105FB0009382000C1040001B2483000F2404FFF088 +:105FC0000064382410E00019978B00109784000EAD +:105FD0009389000D3C0A601C0A0001AC0164402357 +:105FE00001037021006428231126000231C2FFFF43 +:105FF00030A2FFFF0047302B50C0000E00E44821C4 +:106000008D4D000C31A3FFFF00036400000C2C0336 +:1060100004A1FFF30000302130637FFF0A0001A4D8 +:106020002406000103E00008000000009784000E31 +:1060300000E448213123FFFF3168FFFF0068382B5F +:1060400054E0FFF8A783000E938A000D114000056D +:10605000240F0001006BC023A380000D03E00008A3 +:10606000A798000E006BC023A38F000D03E000086B +:10607000A798000E03E000080000000027BDFFE81D +:10608000AFB000103C10800036030140308BFFFFA2 +:1060900093AA002BAFBF0014A46B000436040E00BB +:1060A0009488001630C600FF8FA90030A46800064F +:1060B000AC650008A0660012A46A001AAC67002054 +:1060C0008FA5002CA4690018012020210E00019842 +:1060D000AC6500143C021000AE0201788FBF0014C2 +:1060E0008FB0001003E0000827BD00188F85000066 +:1060F0002484000727BDFFF83084FFF83C068000A9 +:1061000094CB008A316AFFFFAFAA00008FA900007C +:10611000012540232507FFFF30E31FFF0064102BFC +:106120001440FFF700056882000D288034CC400041 +:1061300000AC102103E0000827BD00088F8200009A +:106140002486000730C5FFF800A2182130641FFF25 +:1061500003E00008AF8400008F87003C8F84004478 +:1061600027BDFFB0AFB70044AFB40038AFB1002CCB +:10617000AFBF0048AFB60040AFB5003CAFB300348E +:10618000AFB20030AFB000283C0B80008C860024FA +:10619000AD6700808C8A002035670E0035690100EC +:1061A000ACEA00108C8800248D2500040000B82182 +:1061B000ACE800188CE3001000A688230000A021A2 +:1061C000ACE300148CE20018ACE2001C122000FECC +:1061D00000E0B021936C0008118000F40000000082 +:1061E000976F001031EEFFFF022E682B15A000EF15 +:1061F00000000000977200103250FFFFAED0000088 +:106200003C0380008C740000329300081260FFFD94 +:106210000000000096D800088EC700043305FFFF79 +:1062200030B5000112A000E4000000000000000DE5 +:1062300030BFA0402419004013F9011B30B4A00066 +:10624000128000DF00000000937300081260000855 +:1062500000000000976D001031ACFFFF00EC202B18 +:106260001080000330AE004011C000D500000000D7 +:10627000A7850040AF8700389363000802202821DB +:10628000AFB10020146000F527B40020AF60000C0F +:10629000978F004031F140001620000224030016C1 +:1062A0002403000E24054007A363000AAF65001411 +:1062B000938A00428F70001431550001001512407E +:1062C00002024825AF690014979F00408F780014A0 +:1062D00033F9001003194025AF680014979200406D +:1062E0003247000810E0016E000000008F670014C4 +:1062F0003C1210003C11800000F27825AF6F0014B2 +:1063000036230E00946E000A3C0D81002406000E18 +:1063100031CCFFFF018D2025AF640004A36600028D +:106320009373000A3406FFFC266B0004A36B000A7B +:1063300097980040330820001100015F0000000022 +:106340003C05800034A90E00979900409538000C58 +:1063500097870040001940423312C0003103000308 +:1063600000127B0330F11000006F682500117203EA +:1063700001AE6025000C20C0A76400129793004076 +:10638000936A000A001359823175003C02AA102159 +:106390002450003CA3700009953F000C33F93FFFE7 +:1063A000A779001097700012936900090130F82155 +:1063B00027E5000230B900070019C02333080007A1 +:1063C000A368000B9371000997720012976F001079 +:1063D000322700FF8F910038978D004000F218217E +:1063E000006F702101C6602131A6004010C0000579 +:1063F0003185FFFF00B1102B3C12800010400017C8 +:10640000000098210225A82B56A0013E8FA5002050 +:106410003C048000348A0E008D5300143C0680003A +:10642000AD5300108D4B001CAD4B0018AD45000066 +:106430008CCD000031AC00081180FFFD34CE0E0081 +:1064400095C3000800A0882100009021A783004088 +:106450008DC6000424130001AF860038976F00102A +:1064600031F5FFFF8E9F000003F1282310A0011FCC +:10647000AE85000093620008144000DD00000000BB +:106480000E0001E7240400108F90004800402821EE +:106490003C023200320600FF000654000142F8259B +:1064A00026090001AF890048ACBF000093790009BC +:1064B00097780012936F000A332800FF3303FFFF21 +:1064C0000103382100076C0031EE00FF01AE6025AA +:1064D000ACAC00048F840048978B0040316A2000E8 +:1064E0001140010AACA4000897640012308BFFFF32 +:1064F00006400108ACAB000C978E004031C5000887 +:1065000014A0000226280006262800023C1F800056 +:1065100037E70E0094F900148CE5001C8F67000427 +:10652000937800023324FFFF330300FFAFA3001072 +:106530008F6F0014AFA800180E0001CBAFAF00148E +:10654000240400100E0001FB000000008E920000E9 +:1065500016400005000000008F7800142403FFBFE0 +:106560000303A024AF7400148F67000C00F5C8214A +:10657000AF79000C9375000816A000080000000019 +:1065800012600006000000008F6800143C0AEFFF54 +:106590003549FFFE0109F824AF7F0014A3730008FA +:1065A0008FA500200A00034F02202021AED1000059 +:1065B0000A00022D3C03800014E0FF1E30BFA04003 +:1065C0000E0001900000A0212E9100010237B0259D +:1065D00012C000188FBF00488F87003C24170F009F +:1065E00010F700D43C0680008CD901780720FFFE0C +:1065F000241F0F0010FF00F634CA0E008D56001441 +:1066000034C7014024080240ACF600048D49001C48 +:106610003C141000ACE90008A0E00012A4E0001A4D +:10662000ACE00020A4E00018ACE80014ACD4017881 +:106630008FBF00488FB700448FB600408FB5003C35 +:106640008FB400388FB300348FB200308FB1002C7C +:106650008FB0002803E0000827BD00508F9100385C +:10666000978800403C1280000220A821310700409A +:1066700014E0FF7C00009821977900108F92003879 +:106680003338FFFF131200A8000020210080A02152 +:10669000108000F300A088211620FECE000000002C +:1066A0000A00031F2E9100013C0380008C620178D8 +:1066B0000440FFFE240808008F860000AC680178C3 +:1066C0003C038000946D008A31ACFFFF01865823A3 +:1066D000256AFFFF31441FFF2C8900081520FFF9B0 +:1066E000000000008F8F0048347040008F83003C12 +:1066F00000E0A021240E0F0025E70001AF8700482D +:1067000000D03021023488233C08800031F500FF9E +:10671000106E000524070001939800423313000116 +:106720000013924036470001001524003C0A010086 +:10673000008A4825ACC900008F82004830BF00366F +:1067400030B90008ACC200041320009900FF98255E +:1067500035120E009650000A8F8700003C0F810012 +:106760003203FFFF24ED000835060140006F60256D +:106770003C0E100031AB1FFF269200062405000ED0 +:10678000ACCC0020026E9825A4C5001AAF8B000087 +:10679000A4D20018162000083C1080008F89003C0D +:1067A00024020F005122000224170001367300401A +:1067B0000E0001883C10800036060E008CCB0014C1 +:1067C000360A014002402021AD4B00048CC5001C5C +:1067D000AD450008A1550012AD5300140E000198FC +:1067E0003C151000AE1501780A00035200000000AD +:1067F000936F0009976E0012936D000B31E500FF57 +:1068000000AE202131AC00FF008C80212602000A5E +:106810003050FFFF0E0001E7020020218F86004864 +:106820003C0341003C05800024CB0001AF8B0048B5 +:10683000936A00099769001230C600FF315F00FFBC +:106840003128FFFF03E8382124F900020006C400C4 +:106850000319782501E37025AC4E00008F6D000C04 +:1068600034A40E00948B001401B26025AC4C0004DB +:106870008C85001C8F670004936A00023164FFFF5F +:10688000314900FFAFA900108F680014AFB10018A4 +:106890000E0001CBAFA800140A0002FD0200202167 +:1068A000AF600004A3600002979800403308200006 +:1068B0001500FEA300003021A7600012978400405D +:1068C000936B000A3C10800030931F00001351832B +:1068D000014BA82126A20028A362000936090E0058 +:1068E000953F000C0A000295A77F00108F700014DE +:1068F000360900400E000188AF6900140A0002C981 +:10690000000000000A00034F000020210641FEFAAB +:10691000ACA0000C8CAC000C3C0D8000018D9025CF +:106920000A0002EAACB2000C000090210A0002C585 +:1069300024130001128000073C028000344B0E003B +:106940009566000830D30040126000490000000046 +:106950003C0680008CD001780600FFFE34C50E0096 +:1069600094B500103C03050034CC014032B8FFFF61 +:1069700003039025AD92000C8CAF0014240D200071 +:106980003C041000AD8F00048CAE001CAD8E0008DE +:10699000A1800012A580001AAD800020A5800018FB +:1069A000AD8D0014ACC401780A0003263C068000BB +:1069B0008F9F0000351801402692000227F9000839 +:1069C00033281FFFA71200180A000391AF880000A8 +:1069D0003C02800034450140ACA0000C1280001B3A +:1069E00034530E0034510E008E370010ACB7000443 +:1069F0008E2400183C0B8000ACA4000835700140C8 +:106A000024040040A20000128FBF0048A600001A14 +:106A10008FB70044AE0000208FB60040A6000018DB +:106A20008FB5003CAE0400148FB400388FB300342F +:106A30008FB200308FB1002C8FB000283C021000C4 +:106A400027BD005003E00008AD6201788E66001497 +:106A5000ACA600048E64001C0A00042A3C0B8000D3 +:106A60000E0001902E9100010A0003200237B0258C +:106A7000000000000000000D000000002400036979 +:106A80000A0004013C06800027BDFFD8AFBF0020EC +:106A90003C0980003C1F20FFAFB200183C0760009B +:106AA00035320E002402001037F9FFFDACE2300849 +:106AB000AFB3001CAFB10014AFB00010AE5900006E +:106AC00000000000000000000000000000000000C6 +:106AD000000000003C1800FF3713FFFDAE5300001C +:106AE0003C0B60048D7050002411FF7F3C0E0002AF +:106AF0000211782435EC380C35CD0109ACED4C1879 +:106B0000240A0009AD6C50008CE80438AD2A000856 +:106B1000AD2000148CE54C1C3106FFFF38C42F71EA +:106B200000051E023062000F2486C0B3104000072B +:106B3000AF8200088CE54C1C3C09001F3528FC0086 +:106B400000A81824000321C2AF8400048CF10808B7 +:106B50003C0F57092412F0000232702435F0001067 +:106B600001D0602601CF68262DAA00012D8B0001DF +:106B7000014B382550E00009A380000C3C1F601C2D +:106B80008FF8000824190001A399000C33137C002E +:106B9000A7930010A780000EA380000DAF800048CF +:106BA00014C00003AF8000003C066000ACC0442C61 +:106BB0000E0005B93C1080000E000F2436110100B4 +:106BC0003C12080026523DF03C13080026733E702C +:106BD0008E03000038640001308200011440FFFC85 +:106BE0003C0B800A8E2600002407FF8024C9024047 +:106BF000312A007F014B402101272824AE060020C6 +:106C0000AF880044AE0500243C048000AF86003C01 +:106C10008C8C01780580FFFE24180800922F000854 +:106C2000AC980178A38F0042938E004231CD0001D1 +:106C300011A0000F24050D0024DFF8002FF9030137 +:106C40001320001C000629C224A4FFF000041042F7 +:106C5000000231400E00020200D2D8213C02400066 +:106C60003C068000ACC201380A0004A0000000000D +:106C700010C50023240D0F0010CD00273C1F8008F5 +:106C800037F9008093380000240E0050330F00FFC6 +:106C900015EEFFF33C0240000E000A400000000029 +:106CA0003C0240003C068000ACC201380A0004A04F +:106CB000000000008F83000400A3402B1500000B90 +:106CC0008F8B0008006B50212547FFFF00E5482B04 +:106CD0001520000600A36023000C19400E000202DC +:106CE0000073D8210A0004C43C0240000000000DDB +:106CF0000E000202000000000A0004C43C02400032 +:106D00003C1B0800277B3F700E00020200000000C1 +:106D10000A0004C43C0240003C1B0800277B3F9053 +:106D20000E000202000000000A0004C43C02400001 +:106D30003C0660043C09080025290104ACC9502C1C +:106D40008CC850003C0580003C02000235070080E2 +:106D5000ACC750003C040800248415A43C03080080 +:106D60002463155CACA50008ACA2000C3C01080033 +:106D7000AC243D803C010800AC233D8403E00008C6 +:106D80002402000100A030213C1C0800279C3D8803 +:106D90003C0C04003C0B0002008B3826008C402683 +:106DA0002CE200010007502B2D050001000A48804D +:106DB0003C03080024633D80004520250123182161 +:106DC0001080000300001021AC66000024020001C6 +:106DD00003E00008000000003C1C0800279C3D88E0 +:106DE0003C0B04003C0A0002008A3026008B382647 +:106DF0002CC200010006482B2CE500010009408050 +:106E00003C03080024633D80004520250103182130 +:106E100010800005000010213C0C0800258C155C3A +:106E2000AC6C00002402000103E000080000000038 +:106E30003C0900023C0804000088302600893826FE +:106E40002CC30001008028212CE4000100831025C0 +:106E50001040000B000030213C1C0800279C3D889E +:106E60003C0A80008D4E00082406000101CA6825F6 +:106E7000AD4D00088D4C000C01855825AD4B000C24 +:106E800003E0000800C010213C1C0800279C3D883E +:106E90003C0580008CA6000C000420272402000181 +:106EA00000C4182403E00008ACA3000C3C0200025C +:106EB0001082000B3C0560003C07040010870003B3 +:106EC0000000000003E00008000000008CA908D0CA +:106ED000240AFFFD012A402403E00008ACA808D0E2 +:106EE0008CA408D02406FFFE0086182403E00008C6 +:106EF000ACA308D03C05601A34A600108CC30080F7 +:106F000027BDFFF88CC50084AFA3000093A4000048 +:106F10002402000110820003AFA5000403E0000872 +:106F200027BD000893A7000114E0001497AC0002ED +:106F300097B800023C0F8000330EFFFC01CF6821A0 +:106F4000ADA50000A3A000003C0660008CC708D0DF +:106F50002408FFFE3C04601A00E82824ACC508D0D1 +:106F60008FA300048FA200003499001027BD0008F1 +:106F7000AF22008003E00008AF2300843C0B8000B8 +:106F8000318AFFFC014B48218D2800000A00057D55 +:106F9000AFA8000427BDFFE8AFBF00103C1C0800ED +:106FA000279C3D883C0580008CA4000C8CA200042A +:106FB0003C0300020044282410A0000A00A3182467 +:106FC0003C0604003C0400021460000900A61024E2 +:106FD0001440000F3C0404000000000D3C1C08009D +:106FE000279C3D888FBF001003E0000827BD0018D4 +:106FF0003C0208008C423D800040F809000000007F +:107000003C1C0800279C3D880A0005A68FBF001085 +:107010003C0208008C423D840040F809000000005A +:107020000A0005AC00000000000411C003E00008E5 +:10703000244202403C04080024843FD42405001A62 +:107040000A00009C0000302127BDFFE0AFB0001017 +:107050003C108000AFBF0018AFB100143611010022 +:10706000922200090E0005B63044007F8E3F0000DA +:107070008F89003C3C0F008003E26021258800409E +:107080000049F821240DFF80310E007831980078F6 +:1070900035F9000135F100020319382501D14825E1 +:1070A000010D302403ED5824018D2824240A0040CA +:1070B00024040080240300C0AE0B0024AE0008109E +:1070C000AE0A0814AE040818AE03081CAE05080486 +:1070D000AE070820AE060808AE09082436090900E4 +:1070E0009539000C3605098033ED007F3338FFFFFA +:1070F000001889C0AE110800AE0F0828952C000CAE +:107100008FBF00188FB10014318BFFFF000B51C0EF +:10711000AE0A002C8CA400508FB000108CA3003C51 +:107120008D2700048CA8001C8CA600383C0E800A19 +:1071300001AE102127BD0020AF820044AF84005073 +:10714000AF830054AF87004CAF88005C03E00008B9 +:10715000AF8600603C09080091293FF924A800028D +:107160003C05110000093C0000E8302500C5182549 +:1071700024820008AC83000003E00008AC80000417 +:107180003C098000352309009128010B906A001109 +:107190002402002800804821314700FF00A0702110 +:1071A00000C068213108004010E20002340C86DD86 +:1071B000240C08003C0A800035420A9A94470000DB +:1071C000354B0A9C35460AA030F9FFFFAD39000067 +:1071D0008D780000354B0A8024040001AD3800048E +:1071E0008CCF0000AD2F00089165001930A300037B +:1071F0001064009A28640002148000B9240500027B +:10720000106500A8240F0003106F00BE35450AA4C6 +:10721000240A0800118A004D0000000051000042BD +:107220003C0B80003C04800034830900906700120E +:1072300030E200FF004D7821000FC88027240001B4 +:107240003C0A8000354F090091E50019354C098052 +:107250008D87002830A300FF000315000047582544 +:107260000004C4003C19600001793025370806FF8E +:10727000AD260000AD2800048DEA002C252800284A +:10728000AD2A00088DEC0030AD2C000C8DE50034EB +:10729000AD2500108DE40038AD2400148DE3001CF2 +:1072A000AD2300188DE70020AD27001C8DE20024DF +:1072B000AD2200208DF90028AD3900243C09800062 +:1072C0003526093C8CCF0000352A0100AD0E0004A4 +:1072D000AD0F00008D4E000C3523090035250980C7 +:1072E000AD0E0008906C00128D47000C8CB9003474 +:1072F0003C18080093183FF8318200FF004D5821D8 +:1073000003277823000B37000018240000C47025E1 +:1073100031E9FFFC01C9682525020014AD0D000C00 +:1073200003E00008AD000010357809009306001254 +:107330003C05080094A53FE830C800FF010D50212E +:10734000000A60800A00063C0185202115000060CB +:10735000000000003C08080095083FEE3C060800CD +:1073600094C63FE8010610213C0B800035790900E6 +:1073700093380011932A001935660A80330800FFFC +:1073800094CF002A00086082314500FF978A005898 +:10739000000C1E00000524003047FFFF006410258C +:1073A0000047C02501EA30213C0B4000030B40257B +:1073B00000066400AD280000AD2C000493250018E1 +:1073C0003C0300062528001400053E0000E31025BC +:1073D000AD2200088F24002C254F000131EB7FFFE8 +:1073E000AD24000C8F38001CA78B0058AD3800105E +:1073F0003C0980003526093C8CCF0000352A01006D +:10740000AD0E0004AD0F00008D4E000C35230900B9 +:1074100035250980AD0E0008906C00128D47000CD8 +:107420008CB900343C18080093183FF8318200FFF3 +:10743000004D582103277823000B37000018240043 +:1074400000C4702531E9FFFC01C96825250200143C +:10745000AD0D000C03E00008AD0000103C02080078 +:1074600094423FF23C05080094A53FE835440AA445 +:107470003C07080094E73FE4948B00000045C821D6 +:107480000327C023000B1C002706FFF200665025CF +:10749000AD2A000CAD200010AD2C00140A000630FF +:1074A00025290018354F0AA495E5000095640028A9 +:1074B0000005140000043C003459810000EC5825FC +:1074C000AD39000CAD2B00100A0006302529001440 +:1074D0003C0C0800958C3FEE0A00068625820001D0 +:1074E0005460FF4C240A080035580AA4970600008F +:1074F00000061C00006C5025AD2A000C0A00063066 +:10750000252900103C03080094633FF23C07080063 +:1075100094E73FE83C0F080095EF3FE494A4000097 +:107520009579002800671021004F582300041C00A3 +:10753000001934002578FFEE00D87825346A8100E0 +:10754000AD2A000CAD2F0010AD200014AD2C00189A +:107550000A0006302529001C03E00008240207D099 +:1075600027BDFFE0AFB20018AFB10014AFB00010FC +:10757000AFBF001C0E00007C008088218F88005463 +:107580008F87004C3C05800834B20080011128210F +:107590003C10800024020080240300C000A72023A8 +:1075A000AE0208183C068008AE03081C18800004D0 +:1075B000AF850054ACC500048CC90004AF89004CF1 +:1075C00012200009360409800E00070200000000A6 +:1075D000924C00278E0B007401825004014B302125 +:1075E000AE46000C360409808C8E001C8F8F005C28 +:1075F00001CF682319A000048FBF001C8C90001CD1 +:10760000AF90005C8FBF001C8FB200188FB10014C8 +:107610008FB000100A00007E27BD00208F8600502A +:107620008F8300548F82004C3C05800834A4008076 +:10763000AC860050AC83003C03E00008ACA2000420 +:107640003C0308008C63005427BDFFF8308400FF22 +:107650002462000130A500FF3C010800AC22005468 +:1076600030C600FF3C0780008CE801780500FFFE73 +:107670003C0C7FFFA3A400038FAA0000358BFFFF03 +:10768000014B4824000627C001244025AFA8000074 +:1076900034E201009043000AA3A000023C1980FFDD +:1076A000A3A300018FAF000030AE007F3738FFFF8B +:1076B00001F86024000E6E003C0A002034E5014011 +:1076C000018D5825354920002406FF803C04100018 +:1076D00027BD0008ACAB000CACA90014A4A0001896 +:1076E000A0A6001203E00008ACE40178308800FF97 +:1076F00030A700FF3C0380008C6201780440FFFE4D +:107700003C0C8000358A0A008D4B002035840140F6 +:1077100035850980AC8B00048D4900240007302B8F +:1077200000061540AC890008A088001090A3004C0A +:10773000A083002D03E00008A480001827BDFFE807 +:10774000308400FFAFBF00100E00076730A500FFB8 +:107750008F8300548FBF00103C06800034C5014069 +:10776000344700402404FF903C02100027BD00185D +:10777000ACA3000CA0A40012ACA7001403E0000806 +:10778000ACC2017827BDFFE03C088008AFBF001CF9 +:10779000AFB20018AFB10014AFB0001035100080C8 +:1077A0008E0600183C078000309200FF00C720259D +:1077B000AE0400180E00007C30B100FF92030005FB +:1077C000346200080E00007EA20200050240202163 +:1077D0000E00077B02202821024020218FBF001CC1 +:1077E0008FB200188FB100148FB00010240500056F +:1077F000240600010A00073C27BD00203C0580004C +:1078000034A309809066000830C200081040000FC1 +:107810003C0A01013549080AAC8900008CA80074B3 +:10782000AC8800043C07080090E73FF830E5001002 +:1078300050A00008AC8000083C0D800835AC0080EA +:107840008D8B0058AC8B00082484000C03E00008EA +:10785000008010210A0007BF2484000C27BDFFE828 +:107860003C098000AFB00010AFBF0014352609807E +:1078700090C800092402000600A05821310300FF2F +:107880003527090000808021240500041062007B58 +:107890002408000294CF005C3C0E020431EDFFFF8F +:1078A00001AE6025AE0C000090CA000831440020F3 +:1078B000108000080000000090C2004E3C1F010331 +:1078C00037F90300305800FF03193025240500085C +:1078D000AE06000490F9001190E6001290E4001149 +:1078E000333800FF0018708230CF00FF01CF5021E5 +:1078F000014B6821308900FF31AAFFFF392300289E +:10790000000A60801460002C020C482390E40012EE +:107910003C198000372F0100308C00FF018B1821AB +:10792000000310800045F821001F8400360706FF81 +:10793000AD270004373F090093EC001193EE0012CD +:10794000372609800005C0828DE4000C8CC5003408 +:1079500031CD00FF01AB10210058182100A4F823FD +:107960000008840000033F0000F0302533F9FFFFDA +:10797000318F00FC00D970250158202101E96821D0 +:1079800000045080ADAE000C0E00007C012A802166 +:107990003C088008240B0004350500800E00007EA2 +:1079A000A0AB0009020010218FBF00148FB000109F +:1079B00003E0000827BD001890EC001190E30019C7 +:1079C0003C18080097183FEE318200FF0002F88251 +:1079D000307000FF001FCE0000103C000327302550 +:1079E00000D870253C0F400001CF68253C1980006D +:1079F000AD2D0000373F090093EC001193EE00120B +:107A0000372F0100372609800005C0828DE4000C65 +:107A10008CC5003431CD00FF01AB10210058182176 +:107A200000A4F8230008840000033F0000F0302584 +:107A300033F9FFFF318F00FC00D970250158202158 +:107A400001E9682100045080ADAE000C0E00007CFE +:107A5000012A80213C088008240B000435050080A1 +:107A60000E00007EA0AB0009020010218FBF0014A1 +:107A70008FB0001003E0000827BD00180A0007D1EE +:107A80002408001227BDFFD03C038000AFB60028B9 +:107A9000AFB50024AFB40020AFB10014AFBF002CCD +:107AA000AFB3001CAFB20018AFB0001034670100D4 +:107AB00090E6000B309400FF30B500FF30C200307C +:107AC0000000B02110400099000088213464098032 +:107AD0009088000800082E0000051E03046000C006 +:107AE000240400048F8600543C010800A0243FF8C1 +:107AF0003C0C8000AD8000483C048000348E0100C6 +:107B000091CD000B31A5002010A000073C0780009C +:107B100034930980927200080012860000107E03E0 +:107B200005E000C43C1F800834EC0100918A000B82 +:107B300034EB098091690008314400400004402B77 +:107B40003123000800C898231460000224120003A7 +:107B5000000090213C10800036180A80360409008D +:107B6000970E002C90830011908900129305001845 +:107B7000307F00FF312800FF024810210002C8803A +:107B8000930D0018033F782101F1302130B100FF3F +:107B900000D11821A78E00583C010800A4263FEE12 +:107BA0003C010800A4233FF015A0000200000000E3 +:107BB0000000000D920B010B3065FFFF3C01080037 +:107BC000A4233FF2316A00403C010800A4203FE8B2 +:107BD0003C010800A4203FE41140000224A4000A54 +:107BE00024A4000B3091FFFF0E0001E702202021AA +:107BF0009206010B3C0C0800958C3FF200402021BE +:107C00000006698231A700010E00060101872821C4 +:107C100000402021026028210E00060C0240302185 +:107C20000E0007AB0040202116C000690040202153 +:107C30009212010B3256004012C000053C0500FFB5 +:107C40008C93000034AEFFFF026E8024AC900000E5 +:107C50000E0001FB022020213C0F080091EF3FF8AD +:107C600031F10003122000163C1380088F8200546B +:107C70003C09800835280080245F0001AD1F003CCE +:107C80003C0580088CB9000403E02021033FC02399 +:107C90001B000002AF9F00548CA400040E000702DA +:107CA000ACA400043C0780008CEB00743C0480080A +:107CB00034830080004B5021AC6A000C3C138008D8 +:107CC000367000800280202102A02821A200006BD3 +:107CD0000E0007673C1480008F920054368C0140E0 +:107CE000AD92000C8F8600483C151000344D000604 +:107CF00024D60001AF9600488FBF002CA186001249 +:107D00008FB60028AD8D00148FB3001CAE9501789E +:107D10008FB200188FB500248FB400208FB10014EB +:107D20008FB0001003E0000827BD003034640980E4 +:107D3000908F0008000F7600000E6E0305A0003340 +:107D4000347F090093F8001B241900103C0108003F +:107D5000A0393FF8331300021260FF678F8600548A +:107D60008F8200601446FF653C0480000E00007C9A +:107D7000000000003C0480083485008090A80009C1 +:107D800024060016310300FF1066000D00000000FD +:107D900090AB00093C07080090E73FF82409000871 +:107DA000316400FF34EA00013C010800A02A3FF8DA +:107DB0001089002F240C000A108C00282402000CCB +:107DC0000E00007E000000000A00086A8F86005442 +:107DD0000E0007C3024028210A0008B800402021F5 +:107DE0003C0B8008356A00808D4600548CE9000CFD +:107DF0001120FF3DAF860054240700143C01080009 +:107E0000A0273FF80A0008693C0C80009091000808 +:107E1000241200023C010800A0323FF8323000205A +:107E20001200000B241600018F8600540A00086A15 +:107E30002411000837F800808F020038AFE20004F8 +:107E40008FF90004AF19003C0A0008763C07800057 +:107E50008F8600540A00086A24110004A0A20009B9 +:107E60000E00007E000000000A00086A8F860054A1 +:107E7000240200140A000944A0A2000927BDFFE85B +:107E8000AFB000103C108000AFBF001436020100FC +:107E9000904400090E000767240500013C04800897 +:107EA0009099000E34830080909F000F906F002601 +:107EB0009089000A33F800FF00196E000018740062 +:107EC00031EC00FF01AE5025000C5A00014B382563 +:107ED000312800FF360301403445600000E83025BA +:107EE0002402FF813C041000AC66000C8FBF00141C +:107EF000AC650014A0620012AE0401788FB00010CF +:107F000003E0000827BD001827BDFFE8308400FF0C +:107F1000AFBF00100E00076730A500FF3C058000D2 +:107F200034A40140344700402406FF92AC8700147B +:107F3000A08600128F8300548FBF00103C021000F7 +:107F400027BD0018AC83000C03E00008ACA2017848 +:107F500027BDFFD8AFB00010308400FF30B000FF65 +:107F60003C058000AFB10014AFBF0020AFB3001CD0 +:107F7000AFB20018000410C234A6010032030002A0 +:107F8000305100011460000790D200093C098008BC +:107F900035330080926800053107000810E0000CBE +:107FA000308A0010024020210E00078D0220282177 +:107FB000240200018FBF00208FB3001C8FB2001875 +:107FC0008FB100148FB0001003E0000827BD002817 +:107FD0001540003434A50A008CB800248CAF00088A +:107FE000130F004B000038213C0D800835B3008092 +:107FF000926C006824060002318B00FF1166008439 +:108000003C06800034C201009263004C9059000984 +:10801000307F00FF53F900043213007C10E0006948 +:10802000000000003213007C5660005C02402021FA +:1080300016200009320D00013C0C8000358401003F +:10804000358B0A008D6500248C86000414A6FFD9A8 +:1080500000001021320D000111A0000E024020216D +:108060003C188000371001008E0F000C8F8E0050DE +:1080700011EE0008000000000E00084D022028212B +:108080008E19000C3C1F800837F00080AE1900509C +:10809000024020210E00077B022028210A000999B6 +:1080A000240200013C0508008CA5006424A4000102 +:1080B0003C010800AC2400641600000D0000000024 +:1080C000022028210E00077B02402021926E0068CA +:1080D000240C000231CD00FF11AC0022024020210F +:1080E0000E00094B000000000A000999240200015B +:1080F0000E00007024040001926B0025020B302555 +:108100000E00007EA26600250A0009DD022028215B +:108110008E6200188CDF00048CB9002400021E025D +:1081200017F9FFB13065007F9268004C26440001CA +:108130003093007F12650040310300FF1464FFABF1 +:108140003C0D80082647000130F1007F30E200FF3F +:108150001225000B24070001004090210A0009A607 +:1081600024110001240500040E00073C2406000130 +:108170000E00094B000000000A00099924020001CA +:108180002405FF800245202400859026324200FF0E +:10819000004090210A0009A6241100010E00084D9C +:1081A000022028213207003010E0FFA132100082A7 +:1081B000024020210E00078D022028210A00099983 +:1081C000240200018E69001802402021022028218B +:1081D000012640250E00096EAE6800189264004C1E +:1081E00024050003240600010E00073C308400FF34 +:1081F0000E00007024040001927100250211502528 +:108200000E00007EA26A00250A00099924020001DE +:108210008E6F00183C1880000240202101F8702564 +:10822000022028210E00077BAE6E00189264004CDD +:108230000A000A2524050004324A008039490080DA +:108240001469FF6A3C0D80080A0009FE26470001F8 +:1082500027BDFFC0AFB000183C108000AFBF003892 +:10826000AFB70034AFB60030AFB5002CAFB40028C4 +:10827000AFB30024AFB200200E0005BEAFB1001CAA +:10828000360201009045000B0E0009809044000862 +:10829000144000E78FBF00383C0880083507008095 +:1082A000A0E0006B3606098090C500002403005052 +:1082B0003C17080026F73FB030A400FF3C1308002D +:1082C00026733FC0108300033C1080000000B821DB +:1082D00000009821241F00103611010036120A00F8 +:1082E000361509808E5800248E3400048EAF00208D +:1082F0008F8C00543C010800A03F3FF836190A80DB +:10830000972B002C8EF60000932A001802987023F9 +:1083100001EC68233C010800AC2E3FD43C0108006E +:10832000AC2D3FD83C010800AC2C3FFCA78B00587B +:1083300002C0F809315400FF30490002152000E95D +:1083400030420001504000C49227000992A9000861 +:108350003128000815000002241500030000A821A0 +:108360003C0A80003543090035440A008C8D002406 +:108370009072001190700012907F0011325900FF2E +:10838000321100FF02B110210002C08033EF00FF64 +:108390000319B021028F702102D4602125CB001077 +:1083A0003C010800A4363FEE3C010800AC2D400023 +:1083B0003C010800A42C3FF03C010800A42B3FEC3A +:1083C000355601003554098035510E008F87005411 +:1083D0008F89005C8E850020240800060127302349 +:1083E0003C010800AC283FF400A7282304C000B5D6 +:1083F0000000902104A000B300C5502B114000B52F +:10840000000000003C010800AC263FD88E6200004E +:108410000040F809000000003046000214C000745B +:1084200000408021304B0001556000118E62000435 +:108430003C0D08008DAD3FDC3C0EC0003C048000CC +:1084400001AE6025AE2C00008C980000330F0008B0 +:1084500011E0FFFD00000000963F0008241200011B +:10846000A79F00408E390004AF9900388E62000447 +:108470000040F809000000000202802532030002DB +:10848000146000B3000000003C09080095293FE497 +:108490003C06080094C63FF03C0A0800954A3FE6B7 +:1084A0003C0708008CE73FDC012670213C030800F4 +:1084B0008C6340003C08080095083FFA01CA20215F +:1084C0008ED9000C00E92821249F000200A8782101 +:1084D0000067C02133E4FFFFAF9900503C01080062 +:1084E000AC3840003C010800A42F3FE83C010800E4 +:1084F000A42E3FF20E0001E7000000008F8D00481F +:10850000004020213C010800A02D3FF98E620008A8 +:1085100025AC0001AF8C00480040F80900000000C5 +:108520008F85005402A030210E00060C004020214F +:108530000E0007AB004020218E6B000C0160F80993 +:10854000004020213C0A0800954A3FF23C06080002 +:1085500094C63FE601464821252800020E0001FB93 +:108560003104FFFF3C0508008CA53FD43C07080000 +:108570008CE73FDC00A720233C010800AC243FD45B +:1085800014800006000000003C0208008C423FF40A +:10859000344B00403C010800AC2B3FF41240004338 +:1085A0008F8E00448E2D00108F920044AE4D00201F +:1085B0008E2C0018AE4C00243C04080094843FE844 +:1085C0000E000704000000008F9F00548E6700100B +:1085D0003C010800AC3F3FFC00E0F809000000004F +:1085E0003C1908008F393FD41720FF798F8700543A +:1085F000979300583C11800E321601000E0007338D +:10860000A633002C16C00045320300105460004C05 +:108610008EE50004320800405500001D8EF0000871 +:108620008EE4000C0080F809000000008FBF0038C5 +:108630008FB700348FB600308FB5002C8FB4002870 +:108640008FB300248FB200208FB1001C8FB00018B0 +:1086500003E0000827BD00408F86003C36110E0065 +:1086600000072E0000A62025AE0400808E430020C7 +:108670008E500024AFA30010AE2300148FB2001060 +:10868000AE320010AE30001C0A000A7FAE30001877 +:108690000200F809000000008EE4000C0080F809D8 +:1086A000000000000A000B388FBF003824180001BA +:1086B000240F0001A5C00020A5D800220A000B1A33 +:1086C000ADCF00243C010800AC203FD80A000AB01E +:1086D0008E6200003C010800AC253FD80A000AB0B9 +:1086E0008E620000922400090E00077B0000282102 +:1086F0008FBF00388FB700348FB600308FB5002C95 +:108700008FB400288FB300248FB200208FB1001CDB +:108710008FB0001803E0000827BD00403C14800023 +:1087200092950109000028210E00084D32A400FF97 +:10873000320300105060FFB8320800408EE500049C +:1087400000A0F809000000000A000B3232080040C7 +:108750005240FFA8979300588E3400148F93004422 +:10876000AE7400208E35001CAE7500240A000B2963 +:10877000979300588F8200140004218003E00008C2 +:10878000008210213C07800834E200809043006999 +:1087900000804021106000093C0401003C070800F3 +:1087A0008CE73FFC8F83003000E320230480000827 +:1087B0009389001C14E300030100202103E000085A +:1087C000008010213C04010003E00008008010211B +:1087D0001120000B006738233C0D800035AC098068 +:1087E000918B007C316A0002114000202409003482 +:1087F00000E9702B15C0FFF10100202100E93823AA +:108800002403FFFC00A3C82400E3C02400F9782B54 +:1088100015E0FFEA0308202130C400030004102300 +:1088200014C00014304900030000302100A9782151 +:1088300001E6702100EE682B11A0FFE03C0401006E +:108840002D3800010006C82B0105482103193824E2 +:1088500014E0FFDA2524FFFC2402FFFC00A2182408 +:108860000068202103E00008008010210A000BA806 +:10887000240900303C0C80003586098090CB007CB8 +:10888000316A00041540FFE9240600040A000BB712 +:10889000000030213C0308008C63005C8F820018CC +:1088A00027BDFFE0AFBF0018AFB100141062000594 +:1088B000AFB00010000329C024A40280AF840014CC +:1088C000AF8300183C10800036020A009445003245 +:1088D000361101000E000B8930A43FFF8E240000EA +:1088E000241FFF803C1100800082C021031F6024F0 +:1088F0003309007F000CC94003294025330E00785E +:10890000362F00033C0D1000010D502501CF5825D6 +:10891000AE0C002836080980AE0C080CAE0B082CF3 +:10892000AE0A0830910300693C06800C012638210C +:1089300010600006AF8700348D09003C8D03006C89 +:108940000123382318E00082000000003C0B80085F +:10895000356A00803C108000A1400069360609801D +:108960008CC200383C06800034C50A0090A8003C48 +:10897000310C00201180001AAF820030240D00015C +:108980003C0E800035D10A00A38D001CAF8000246E +:108990008E2400248F850024240D0008AF80002041 +:1089A000AF8000283C010800A42D3FE63C010800F0 +:1089B000A4203FFA0E000B8D000030219228003CCD +:1089C0008FBF00188FB100148FB0001000086142F3 +:1089D000AF82002C27BD002003E000083182000197 +:1089E00090B80032240E0001330F00FF000F2182E7 +:1089F000108E0041241900021099006434C40AC08A +:108A00003C03800034640A008C8F002415E0001EB3 +:108A100034660900909F00302418000533F9003FA8 +:108A20001338004E240300018F860020A383001C0E +:108A3000AF860028AF8600243C0E800035D10A00A6 +:108A40008E2400248F850024240D00083C0108009A +:108A5000A42D3FE63C010800A4203FFA0E000B8D38 +:108A6000000000009228003C8FBF00188FB1001456 +:108A70008FB0001000086142AF82002C27BD00209B +:108A800003E00008318200018C8A00088C8B0024EE +:108A90008CD000643C0E800035D10A00014B2823A5 +:108AA000AF900024A380001CAF8500288E240024F2 +:108AB0008F8600208F850024240D00083C010800CB +:108AC000A42D3FE63C010800A4203FFA0E000B8DC8 +:108AD000000000009228003C8FBF00188FB10014E6 +:108AE0008FB0001000086142AF82002C27BD00202B +:108AF00003E000083182000190A200303051003FB5 +:108B00005224002834C50AC08CB00024160000226C +:108B100034CB09008CA600483C0A7FFF3545FFFF97 +:108B200000C510243C0E8000AF82002035C509002E +:108B30008F8800208CAD0060010D602B1580000235 +:108B4000010020218CA400600A000C2CAF840020BE +:108B50008D02006C0A000C063C0680008C820048E6 +:108B60008F8600203C097FFF3527FFFF00478824C0 +:108B70003C04800824030001AF910028AC80006C05 +:108B8000A383001C0A000C3AAF8600248C9F0014BB +:108B90000A000C2CAF9F00208D6200680A000C7642 +:108BA0003C0E800034C409808C8900708CA30014B2 +:108BB0000123382B10E00004000000008C820070BC +:108BC0000A000C763C0E80008CA200140A000C7681 +:108BD0003C0E80008F85002427BDFFE0AFBF00184A +:108BE000AFB1001414A00008AFB000103C04800026 +:108BF00034870A0090E600302402000530C3003FAD +:108C0000106200B9348409008F91002000A08021F7 +:108C10003C048000348E0A008DCD00043C06080020 +:108C20008CC63FD831A73FFF00E6602B558000017E +:108C300000E03021938F001C11E0007800D0282B39 +:108C4000349F098093F9007C3338000213000079C7 +:108C50002403003400C3102B144000D9000000008E +:108C600000C3302300D0282B3C010800A4233FE49C +:108C700014A0006E020018213C0408008C843FD42C +:108C80000064402B55000001006020213C0580005D +:108C900034A90A00912A003C3C010800AC243FDCC6 +:108CA00031430020146000030000482134AB0E0063 +:108CB0008D6900188F88002C0128202B1080005F00 +:108CC000000000003C0508008CA53FDC00A96821DD +:108CD000010D602B1180005C00B0702B010938235E +:108CE00000E028213C010800AC273FDC1200000313 +:108CF000240AFFFC10B0008D3224000300AA1824BF +:108D00003C010800A4203FFA3C010800AC233FDCF2 +:108D1000006028218F840024120400063C0B800888 +:108D20008D6C006C02002021AF9100202590000185 +:108D3000AD70006C8F8D002800858823AF910024D2 +:108D400001A52023AF840028122000022407001868 +:108D5000240700103C1880083706008090CF006878 +:108D60003C010800A0273FF82407000131EE00FF76 +:108D700011C70047000000001480001800002821DF +:108D80003C06800034D1098034CD010091A6000951 +:108D90008E2C001824C40001000C86023205007FCE +:108DA000308B007F1165007F2407FF803C1980080D +:108DB00037290080A124004C3C0808008D083FF4AE +:108DC000241800023C010800A0384039350F000883 +:108DD0003C010800AC2F3FF4240500103C02800049 +:108DE00034440A009083003C307F002013E00005EB +:108DF00000A02021240A00013C010800AC2A3FDC2D +:108E000034A400018FBF00188FB100148FB0001080 +:108E10000080102103E0000827BD00203C0108006D +:108E2000A4203FE410A0FF94020018210A000CCAFD +:108E300000C018210A000CC1240300303C050800C2 +:108E40008CA53FDC00B0702B11C0FFA80000000013 +:108E50003C19080097393FE40325C0210307782B0C +:108E600011E000072CAA00043C0360008C6254044B +:108E7000305F003F17E0FFE3240400422CAA000407 +:108E80001140FF9A240400420A000D2E8FBF0018E3 +:108E90001528FFB9000000008CCA00183C1F800094 +:108EA00024020002015F1825ACC3001837F90A003C +:108EB000A0C200689329003C2404000400A01021F3 +:108EC000312800203C010800A02440391100000294 +:108ED00024050010240200013C010800AC223FD40C +:108EE0000A000D243C0280008F8800288C890060D5 +:108EF0000109282B14A00002010088218C91006038 +:108F00003C048000348B0E008D640018240A00019C +:108F10000220282102203021A38A001C0E000B8D84 +:108F2000022080210A000CB0AF82002C00045823DC +:108F300012200007316400033C0E800035C7098011 +:108F400090ED007C31AC000415800019248F0004E2 +:108F50003C010800A4243FFA3C1F080097FF3FFA99 +:108F600003E5C82100D9C02B1300FF6B8F840024B8 +:108F70002CA6000514C0FFA32404004230A2000365 +:108F80001440000200A2182324A3FFFC3C010800A7 +:108F9000AC233FDC3C010800A4203FFA0A000CF19E +:108FA0000060282100C770240A000D1701C7202681 +:108FB0003C010800A42F3FFA0A000D8200000000C7 +:108FC0003C010800AC203FDC0A000D2D24040042C7 +:108FD0008F8300283C05800034AA0A001460000634 +:108FE00000001021914700302406000530E400FF06 +:108FF000108600030000000003E0000800000000ED +:10900000914B0048316900FF000941C21500FFFA89 +:109010003C0680083C04080094843FE43C030800BC +:109020008C633FFC3C1908008F393FDC3C0F080083 +:1090300095EF3FFA0064C0218CCD00040319702124 +:1090400001CF602134AB0E00018D282318A0001D34 +:1090500000000000914F004C8F8C0034956D001083 +:1090600031EE00FF8D89000401AE30238D8A0000AF +:1090700030CEFFFF000E29000125C8210000382155 +:10908000014720210325182B0083C021AD9900043E +:10909000AD980000918F000A01CF6821A18D000AD0 +:1090A000956500128F8A0034A5450008954B00385D +:1090B00025690001A54900389148000D35070008D1 +:1090C000A147000D03E000080000000027BDFFD805 +:1090D000AFB000189388001C8FB000143C0A8000C9 +:1090E0003C197FFF8F8700243738FFFFAFBF002078 +:1090F000AFB1001C355F0A000218182493EB003C46 +:1091000000087FC03C02BFFF006F60252CF000010B +:109110003449FFFF3C1F08008FFF3FFC8F99003050 +:109120003C18080097183FF2018978240010478006 +:109130003C07EFFF3C05F0FF01E818253C118000DB +:109140003169002034E2FFFF34ADFFFF362E098085 +:1091500027A500102406000203F96023270B000254 +:10916000354A0E000062182400808021152000027C +:10917000000040218D48001CA7AB0012058000397B +:109180002407000030E800FF00083F000067582572 +:109190003C028008AFAB0014344F008091EA0068B5 +:1091A0003C08080091083FF93C09DFFF352CFFFF20 +:1091B000000AF82B3C02080094423FECA3A80011DF +:1091C000016CC024001FCF40031918258FA7001081 +:1091D000AFA300143C0C0800918C3FFBA7A2001623 +:1091E0008FAB001400ED48243C0F01003C0A0FFF38 +:1091F000012FC82531980003355FFFFF016D402422 +:109200003C027000033F382400181E0000E248258D +:1092100001037825AFAF0014AFA9001091CC007CFA +:109220000E000092A3AC0015362D0A0091A6003C5A +:1092300030C4002010800006260200083C110800FF +:1092400096313FE8262EFFFF3C010800A42E3FE8A0 +:109250008FBF00208FB1001C8FB0001803E0000802 +:1092600027BD00288F8B002C010B502B5540FFC5CC +:10927000240700010A000E0E30E800FF9383001C53 +:109280003C02800027BDFFD834480A0000805021EE +:10929000AFBF002034460AC0010028211060000E34 +:1092A0003444098091070030240B00058F89002089 +:1092B00030EC003F118B000B00003821AFA90010EB +:1092C0003C0B80088D69006CAFAA00180E00015A93 +:1092D000AFA90014A380001C8FBF002003E000088A +:1092E00027BD00288D1F00483C1808008F183FDC60 +:1092F0008F9900283C027FFF8D0800443443FFFF14 +:10930000AFA900103C0B80088D69006C03E370244A +:109310000319782101CF682301A83821AFAA0018CA +:109320000E00015AAFA900140A000E62A380001CAF +:109330003C05800034A60A0090C7003C3C060800AB +:1093400094C63FFA3C0208008C423FF430E3002010 +:10935000000624001060001E004438253C088008E8 +:109360003505008090A30068000048212408000112 +:1093700000002821240400013C0680008CCD0178E7 +:1093800005A0FFFE34CF0140ADE800083C02080014 +:109390008C423FFCA5E50004A5E40006ADE2000C0C +:1093A0003C04080090843FF93C0380083479008035 +:1093B000A1E40012ADE70014A5E900189338004CB1 +:1093C0003C0E1000A1F8002D03E00008ACCE01789F +:1093D00034A90E008D28001C3C0C08008D8C3FDC4D +:1093E000952B0016952A0014018648213164FFFF51 +:1093F0000A000E8A3145FFFF3C04800034830A00D6 +:109400009065003C30A200201040001934870E0007 +:109410000000402100003821000020213C0680008F +:109420008CC901780520FFFE34CA014034CF010009 +:1094300091EB0009AD4800083C0E08008DCE3FFCC2 +:10944000240DFF91240C00403C081000A5440004AA +:10945000A5470006AD4E000CA14D0012AD4C001406 +:10946000A5400018A14B002D03E00008ACC801780E +:109470008CE8001894E6001294E4001030C7FFFF57 +:109480000A000EB33084FFFF3C04800034830A00DE +:109490009065003C30A200201040002727BDFFF857 +:1094A0002409000100003821240800013C06800046 +:1094B0008CCA01780540FFFE3C0280FF34C40100E5 +:1094C000908D00093C0C0800918C4039A3AD00033D +:1094D0008FAB00003185007F3459FFFF01665025B6 +:1094E000AFAA00009083000AA3A0000200057E003E +:1094F000A3A300018FB8000034CB0140240C30003E +:109500000319702401CF6825AD6D000C27BD00083C +:10951000AD6C0014A5600018AD690008A5670004D3 +:109520002409FF80A56800063C081000A16900120C +:1095300003E00008ACC8017834870E008CE90018FD +:1095400094E6001294E4001030C8FFFF0A000ED722 +:109550003087FFFF27BDFFE0AFB100143C11800052 +:10956000AFB00010AFBF001836380A00970F0032B6 +:10957000363001000E000B8931E43FFF8E0E0000F3 +:10958000240DFF803C04200001C25821016D60249D +:10959000000C4940316A007F012A4025010438252A +:1095A0003C048008AE2708303486008090C50068EF +:1095B0002403000230A200FF104300048F9F00200C +:1095C0008F990024AC9F0068AC9900648FBF00188D +:1095D0008FB100148FB0001003E0000827BD0020F9 +:1095E0003C0A0800254A3AA83C09080025293B38CE +:1095F0003C08080025082F443C07080024E73C04E9 +:109600003C06080024C6392C3C05080024A53680F9 +:109610003C040800248432843C030800246339E0BD +:109620003C0208002442377C3C010800AC2A3FB8C9 +:109630003C010800AC293FB43C010800AC283FB015 +:109640003C010800AC273FBC3C010800AC263FCCE5 +:109650003C010800AC253FC43C010800AC243FC0DD +:109660003C010800AC233FD03C010800AC223FC8BD +:0896700003E000080000000007 +:08967800800009408000090098 +:10968000800801008008008080080000800E000033 +:10969000800800808008000080000A8080000A00A6 +:0896A000800009808000090030 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ -- cgit v1.2.3-59-g8ed1b From f5260f02e7903bb10e45b1bf3500eab6425edf5c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 25 Dec 2010 12:23:42 +0000 Subject: USB: cdc_ether: remove unneeded check We already verified that "dev->udev->actconfig->extralen" was non-zero so "len" is non-zero here as well. Signed-off-by: Dan Carpenter Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index b3fe0de40469..9a60e415d76b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -99,9 +99,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) */ buf = dev->udev->actconfig->extra; len = dev->udev->actconfig->extralen; - if (len) - dev_dbg(&intf->dev, - "CDC descriptors on config\n"); + dev_dbg(&intf->dev, "CDC descriptors on config\n"); } /* Maybe CDC descriptors are after the endpoint? This bug has -- cgit v1.2.3-59-g8ed1b From c866b7eac073198cef03ea6bac2dc978635a9f5c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 25 Dec 2010 12:56:23 +0000 Subject: tg3: Do not use legacy PCI power management The tg3 driver uses the legacy PCI power management, so it has to do some PCI-specific things in its ->suspend() and ->resume() callbacks, which isn't necessary and should better be done by the PCI sybsystem-level power management code. Convert tg3 to the new PCI power management framework and make it let the PCI subsystem take care of all the PCI-specific aspects of device handling during system power transitions. Tested on HP nx6325 with a NetXtreme BCM5788 adapter. Signed-off-by: Rafael J. Wysocki Signed-off-by: David S. Miller --- drivers/net/tg3.c | 101 +++++++++++++++++++++++------------------------------- 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 92fc29910c2d..6137869799a4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2551,39 +2551,35 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) tw32(MAC_TX_BACKOFF_SEED, addr_high); } -static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) +static void tg3_enable_register_access(struct tg3 *tp) { - u32 misc_host_ctrl; - bool device_should_wake, do_low_power; - - /* Make sure register accesses (indirect or otherwise) - * will function correctly. + /* + * Make sure register accesses (indirect or otherwise) will function + * correctly. */ pci_write_config_dword(tp->pdev, - TG3PCI_MISC_HOST_CTRL, - tp->misc_host_ctrl); + TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); +} - switch (state) { - case PCI_D0: - pci_enable_wake(tp->pdev, state, false); - pci_set_power_state(tp->pdev, PCI_D0); +static int tg3_power_up(struct tg3 *tp) +{ + tg3_enable_register_access(tp); - /* Switch out of Vaux if it is a NIC */ - if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); + pci_set_power_state(tp->pdev, PCI_D0); - return 0; + /* Switch out of Vaux if it is a NIC */ + if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); - case PCI_D1: - case PCI_D2: - case PCI_D3hot: - break; + return 0; +} - default: - netdev_err(tp->dev, "Invalid power state (D%d) requested\n", - state); - return -EINVAL; - } +static int tg3_power_down_prepare(struct tg3 *tp) +{ + u32 misc_host_ctrl; + bool device_should_wake, do_low_power; + + tg3_enable_register_access(tp); /* Restore the CLKREQ setting. */ if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) { @@ -2602,8 +2598,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) tw32(TG3PCI_MISC_HOST_CTRL, misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); - device_should_wake = pci_pme_capable(tp->pdev, state) && - device_may_wakeup(&tp->pdev->dev) && + device_should_wake = device_may_wakeup(&tp->pdev->dev) && (tp->tg3_flags & TG3_FLAG_WOL_ENABLE); if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { @@ -2823,13 +2818,15 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); - if (device_should_wake) - pci_enable_wake(tp->pdev, state, true); + return 0; +} - /* Finally, set the new power state. */ - pci_set_power_state(tp->pdev, state); +static void tg3_power_down(struct tg3 *tp) +{ + tg3_power_down_prepare(tp); - return 0; + pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE); + pci_set_power_state(tp->pdev, PCI_D3hot); } static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex) @@ -9137,7 +9134,7 @@ static int tg3_open(struct net_device *dev) netif_carrier_off(tp->dev); - err = tg3_set_power_state(tp, PCI_D0); + err = tg3_power_up(tp); if (err) return err; @@ -9302,7 +9299,7 @@ static int tg3_close(struct net_device *dev) tg3_free_consistent(tp); - tg3_set_power_state(tp, PCI_D3hot); + tg3_power_down(tp); netif_carrier_off(tp->dev); @@ -11104,7 +11101,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, struct tg3 *tp = netdev_priv(dev); if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) - tg3_set_power_state(tp, PCI_D0); + tg3_power_up(tp); memset(data, 0, sizeof(u64) * TG3_NUM_TEST); @@ -11172,7 +11169,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, tg3_phy_start(tp); } if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) - tg3_set_power_state(tp, PCI_D3hot); + tg3_power_down(tp); } @@ -13621,7 +13618,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; - /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). + /* Set up tp->grc_local_ctrl before calling tg_power_up(). * GPIO1 driven high will bring 5700's external PHY out of reset. * It is also used as eeprom write protect on LOMs. */ @@ -13652,7 +13649,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } /* Force the chip into D0. */ - err = tg3_set_power_state(tp, PCI_D0); + err = tg3_power_up(tp); if (err) { dev_err(&tp->pdev->dev, "Transition to D0 failed\n"); return err; @@ -15055,19 +15052,13 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) } } -static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) +static int tg3_suspend(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); struct tg3 *tp = netdev_priv(dev); - pci_power_t target_state; int err; - /* PCI register 4 needs to be saved whether netif_running() or not. - * MSI address and data need to be saved if using MSI and - * netif_running(). - */ - pci_save_state(pdev); - if (!netif_running(dev)) return 0; @@ -15088,9 +15079,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tg3_full_unlock(tp); - target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot; - - err = tg3_set_power_state(tp, target_state); + err = tg3_power_down_prepare(tp); if (err) { int err2; @@ -15117,21 +15106,16 @@ out: return err; } -static int tg3_resume(struct pci_dev *pdev) +static int tg3_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); struct tg3 *tp = netdev_priv(dev); int err; - pci_restore_state(tp->pdev); - if (!netif_running(dev)) return 0; - err = tg3_set_power_state(tp, PCI_D0); - if (err) - return err; - netif_device_attach(dev); tg3_full_lock(tp, 0); @@ -15155,13 +15139,14 @@ out: return err; } +static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); + static struct pci_driver tg3_driver = { .name = DRV_MODULE_NAME, .id_table = tg3_pci_tbl, .probe = tg3_init_one, .remove = __devexit_p(tg3_remove_one), - .suspend = tg3_suspend, - .resume = tg3_resume + .driver.pm = &tg3_pm_ops, }; static int __init tg3_init(void) -- cgit v1.2.3-59-g8ed1b From 0f333d10e3f689640b229c8cf00b16ea51ce4951 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 26 Dec 2010 08:44:32 +0000 Subject: sky2: Do not use legacy PCI power management The sky2 driver uses the legacy PCI power management, so it has to do some PCI-specific things in its ->suspend() and ->resume() callbacks, which isn't necessary and should better be done by the PCI sybsystem-level power management code. Moreover, it uses device_set_wakeup_enable() incorrectly (that function should be used when the WoL setting is changed rather than during suspend). Convert sky2 to the new PCI power management framework and make it let the PCI subsystem take care of all the PCI-specific aspects of device handling during system power transitions. Tested on a desktop machine with a Marvell 88E8056 PCI-E adapter. Signed-off-by: Rafael J. Wysocki Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d6577084ce70..0d4a236c3bb3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3398,12 +3398,24 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; + bool enable_wakeup = false; + int i; if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) || !device_can_wakeup(&hw->pdev->dev)) return -EOPNOTSUPP; sky2->wol = wol->wolopts; + + for (i = 0; i < hw->ports; i++) { + struct net_device *dev = hw->dev[i]; + struct sky2_port *sky2 = netdev_priv(dev); + + if (sky2->wol) + enable_wakeup = true; + } + device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup); + return 0; } @@ -4920,10 +4932,11 @@ static void __devexit sky2_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) +static int sky2_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct sky2_hw *hw = pci_get_drvdata(pdev); - int i, wol = 0; + int i; if (!hw) return 0; @@ -4940,41 +4953,24 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) if (sky2->wol) sky2_wol_init(sky2); - - wol |= sky2->wol; } - device_set_wakeup_enable(&pdev->dev, wol != 0); - sky2_power_aux(hw); rtnl_unlock(); - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; } #ifdef CONFIG_PM -static int sky2_resume(struct pci_dev *pdev) +static int sky2_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct sky2_hw *hw = pci_get_drvdata(pdev); int err; if (!hw) return 0; - err = pci_set_power_state(pdev, PCI_D0); - if (err) - goto out; - - err = pci_restore_state(pdev); - if (err) - goto out; - - pci_enable_wake(pdev, PCI_D0, 0); - /* Re-enable all clocks */ err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0); if (err) { @@ -4994,11 +4990,20 @@ out: pci_disable_device(pdev); return err; } + +static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume); +#define SKY2_PM_OPS (&sky2_pm_ops) + +#else + +#define SKY2_PM_OPS NULL #endif static void sky2_shutdown(struct pci_dev *pdev) { - sky2_suspend(pdev, PMSG_SUSPEND); + sky2_suspend(&pdev->dev); + pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); + pci_set_power_state(pdev, PCI_D3hot); } static struct pci_driver sky2_driver = { @@ -5006,11 +5011,8 @@ static struct pci_driver sky2_driver = { .id_table = sky2_id_table, .probe = sky2_probe, .remove = __devexit_p(sky2_remove), -#ifdef CONFIG_PM - .suspend = sky2_suspend, - .resume = sky2_resume, -#endif .shutdown = sky2_shutdown, + .driver.pm = SKY2_PM_OPS, }; static int __init sky2_init_module(void) -- cgit v1.2.3-59-g8ed1b From eeaeb068f1393b4db4861481bf594bcd1c3eda7a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Dec 2010 21:53:33 +0000 Subject: sch_sfq: allow big packets and be fair SFQ is currently 'limited' to small packets, because it uses a 15bit allotment number per flow. Introduce a scale by 8, so that we can handle full size TSO/GRO packets. Use appropriate handling to make sure allot is positive before a new packet is dequeued, so that fairness is respected. Signed-off-by: Eric Dumazet Acked-by: Jarek Poplawski Cc: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 6a2f88fea6d8..b76d46b71466 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -67,7 +67,7 @@ IMPLEMENTATION: This implementation limits maximal queue length to 128; - maximal mtu to 2^15-1; max 128 flows, number of hash buckets to 1024. + max mtu to 2^18-1; max 128 flows, number of hash buckets to 1024. The only goal of this restrictions was that all data fit into one 4K page on 32bit arches. @@ -77,6 +77,11 @@ #define SFQ_SLOTS 128 /* max number of flows */ #define SFQ_EMPTY_SLOT 255 #define SFQ_HASH_DIVISOR 1024 +/* We use 16 bits to store allot, and want to handle packets up to 64K + * Scale allot by 8 (1<<3) so that no overflow occurs. + */ +#define SFQ_ALLOT_SHIFT 3 +#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT) /* This type should contain at least SFQ_DEPTH + SFQ_SLOTS values */ typedef unsigned char sfq_index; @@ -115,7 +120,7 @@ struct sfq_sched_data struct timer_list perturb_timer; u32 perturbation; sfq_index cur_depth; /* depth of longest slot */ - + unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */ struct sfq_slot *tail; /* current slot in round */ sfq_index ht[SFQ_HASH_DIVISOR]; /* Hash table */ struct sfq_slot slots[SFQ_SLOTS]; @@ -395,7 +400,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) q->tail->next = x; } q->tail = slot; - slot->allot = q->quantum; + slot->allot = q->scaled_quantum; } if (++sch->q.qlen <= q->limit) { sch->bstats.bytes += qdisc_pkt_len(skb); @@ -431,8 +436,14 @@ sfq_dequeue(struct Qdisc *sch) if (q->tail == NULL) return NULL; +next_slot: a = q->tail->next; slot = &q->slots[a]; + if (slot->allot <= 0) { + q->tail = slot; + slot->allot += q->scaled_quantum; + goto next_slot; + } skb = slot_dequeue_head(slot); sfq_dec(q, a); sch->q.qlen--; @@ -447,9 +458,8 @@ sfq_dequeue(struct Qdisc *sch) return skb; } q->tail->next = next_a; - } else if ((slot->allot -= qdisc_pkt_len(skb)) <= 0) { - q->tail = slot; - slot->allot += q->quantum; + } else { + slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb)); } return skb; } @@ -485,6 +495,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) sch_tree_lock(sch); q->quantum = ctl->quantum ? : psched_mtu(qdisc_dev(sch)); + q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); q->perturb_period = ctl->perturb_period * HZ; if (ctl->limit) q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1); @@ -525,6 +536,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) q->tail = NULL; if (opt == NULL) { q->quantum = psched_mtu(qdisc_dev(sch)); + q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); q->perturb_period = 0; q->perturbation = net_random(); } else { @@ -617,7 +629,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, if (idx != SFQ_EMPTY_SLOT) { const struct sfq_slot *slot = &q->slots[idx]; - xstats.allot = slot->allot; + xstats.allot = slot->allot << SFQ_ALLOT_SHIFT; qs.qlen = slot->qlen; slot_queue_walk(slot, skb) qs.backlog += qdisc_pkt_len(skb); -- cgit v1.2.3-59-g8ed1b From 18c8d82ae5b802c5d82e0dfbcc08b1b568955f46 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 31 Dec 2010 12:48:55 -0800 Subject: sfq: fix slot_dequeue_head() slot_dequeue_head() should make sure slot skb chain is correct in both ways, or we can crash if all possible flows are in use. Jarek pointed out slot_queue_init() can now be done in sfq_init() once, instead each time a flow is setup. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index b76d46b71466..d54ac94066c2 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -297,6 +297,7 @@ static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot) struct sk_buff *skb = slot->skblist_next; slot->skblist_next = skb->next; + skb->next->prev = (struct sk_buff *)slot; skb->next = skb->prev = NULL; return skb; } @@ -380,7 +381,6 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) q->ht[hash] = x; slot = &q->slots[x]; slot->hash = hash; - slot_queue_init(slot); } /* If selected queue has length q->limit, do simple tail drop, @@ -545,8 +545,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) return err; } - for (i = 0; i < SFQ_SLOTS; i++) + for (i = 0; i < SFQ_SLOTS; i++) { + slot_queue_init(&q->slots[i]); sfq_link(q, i); + } return 0; } -- cgit v1.2.3-59-g8ed1b From 7dbf6acdbad2fbc6eea72b58404461dcb7c6d9d2 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 30 Dec 2010 08:52:29 +0000 Subject: skge: Do not use legacy PCI power management The skge driver used the legacy PCI power management, and did its own PCI callbacks. Use the same code model as Rafael's changes to sky2. Let the PCI subsystem take care of all the PCI-specific aspects of device handling during system power transitions. Compile tested only (so far). Signed-off-by: Stephen Hemminger Acked-by: Rafael J. Wysocki Signed-off-by: David S. Miller --- drivers/net/skge.c | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index c149e48a0f57..42daf98ba736 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -4042,53 +4042,40 @@ static void __devexit skge_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int skge_suspend(struct pci_dev *pdev, pm_message_t state) +static int skge_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct skge_hw *hw = pci_get_drvdata(pdev); - int i, err, wol = 0; + int i; if (!hw) return 0; - err = pci_save_state(pdev); - if (err) - return err; - for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; struct skge_port *skge = netdev_priv(dev); if (netif_running(dev)) skge_down(dev); + if (skge->wol) skge_wol_init(skge); - - wol |= skge->wol; } skge_write32(hw, B0_IMSK, 0); - pci_prepare_to_sleep(pdev); - return 0; } -static int skge_resume(struct pci_dev *pdev) +static int skge_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct skge_hw *hw = pci_get_drvdata(pdev); int i, err; if (!hw) return 0; - err = pci_back_from_sleep(pdev); - if (err) - goto out; - - err = pci_restore_state(pdev); - if (err) - goto out; - err = skge_reset(hw); if (err) goto out; @@ -4109,12 +4096,19 @@ static int skge_resume(struct pci_dev *pdev) out: return err; } + +static SIMPLE_DEV_PM_OPS(skge_pm_ops, skge_suspend, skge_resume); +#define SKGE_PM_OPS (&skge_pm_ops) + +#else + +#define SKGE_PM_OPS NULL #endif static void skge_shutdown(struct pci_dev *pdev) { struct skge_hw *hw = pci_get_drvdata(pdev); - int i, wol = 0; + int i; if (!hw) return; @@ -4125,15 +4119,10 @@ static void skge_shutdown(struct pci_dev *pdev) if (skge->wol) skge_wol_init(skge); - wol |= skge->wol; } - if (pci_enable_wake(pdev, PCI_D3cold, wol)) - pci_enable_wake(pdev, PCI_D3hot, wol); - - pci_disable_device(pdev); + pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); pci_set_power_state(pdev, PCI_D3hot); - } static struct pci_driver skge_driver = { @@ -4141,11 +4130,8 @@ static struct pci_driver skge_driver = { .id_table = skge_id_table, .probe = skge_probe, .remove = __devexit_p(skge_remove), -#ifdef CONFIG_PM - .suspend = skge_suspend, - .resume = skge_resume, -#endif .shutdown = skge_shutdown, + .driver.pm = SKGE_PM_OPS, }; static struct dmi_system_id skge_32bit_dma_boards[] = { -- cgit v1.2.3-59-g8ed1b From aa6027cacdd912ce884953714fcc7392b6155bc6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 1 Jan 2011 05:22:46 +0000 Subject: tg3: fix warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case CONFIG_PM_SLEEP is disabled, we dont need tg3_suspend() and tg3_resume(). drivers/net/tg3.c:15056: warning: ‘tg3_suspend’ defined but not used drivers/net/tg3.c:15110: warning: ‘tg3_resume’ defined but not used Signed-off-by: Eric Dumazet Cc: Rafael J. Wysocki Cc: Michael Chan Cc: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6137869799a4..e3d80c9fb86f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -15052,6 +15052,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) } } +#ifdef CONFIG_PM_SLEEP static int tg3_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); @@ -15140,13 +15141,20 @@ out: } static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); +#define TG3_PM_OPS (&tg3_pm_ops) + +#else + +#define TG3_PM_OPS NULL + +#endif /* CONFIG_PM_SLEEP */ static struct pci_driver tg3_driver = { .name = DRV_MODULE_NAME, .id_table = tg3_pci_tbl, .probe = tg3_init_one, .remove = __devexit_p(tg3_remove_one), - .driver.pm = &tg3_pm_ops, + .driver.pm = TG3_PM_OPS, }; static int __init tg3_init(void) -- cgit v1.2.3-59-g8ed1b From 51f98a8d70583b18cb08b19353aeed5efb0244af Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:16 +0000 Subject: tipc: Remove prototype code for supporting multiple zones Eliminates routines, data structures, and files that were intended to allows TIPC to support a network containing multiple zones. Currently, TIPC supports only networks consisting of a single cluster within a single zone, so this code is unnecessary. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/linux/tipc_config.h | 4 +- net/tipc/Kconfig | 12 ---- net/tipc/Makefile | 2 +- net/tipc/addr.c | 4 -- net/tipc/cluster.c | 14 +--- net/tipc/cluster.h | 12 ++-- net/tipc/config.c | 30 ++------- net/tipc/core.c | 6 -- net/tipc/core.h | 1 - net/tipc/net.c | 41 +++++++----- net/tipc/net.h | 8 ++- net/tipc/node.c | 7 +- net/tipc/node.h | 1 - net/tipc/zone.c | 159 -------------------------------------------- net/tipc/zone.h | 70 ------------------- 15 files changed, 46 insertions(+), 325 deletions(-) delete mode 100644 net/tipc/zone.c delete mode 100644 net/tipc/zone.h diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h index 9cde86c32412..fa3aeaafeab1 100644 --- a/include/linux/tipc_config.h +++ b/include/linux/tipc_config.h @@ -94,7 +94,7 @@ #define TIPC_CMD_GET_MAX_PORTS 0x4004 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_PUBL 0x4005 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_SUBSCR 0x4006 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_ZONES 0x4007 /* tx none, rx unsigned */ +#define TIPC_CMD_GET_MAX_ZONES 0x4007 /* obsoleted */ #define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_SLAVES 0x400A /* tx none, rx unsigned */ @@ -130,7 +130,7 @@ #define TIPC_CMD_SET_MAX_PORTS 0x8004 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_PUBL 0x8005 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_SUBSCR 0x8006 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_ZONES 0x8007 /* tx unsigned, rx none */ +#define TIPC_CMD_SET_MAX_ZONES 0x8007 /* obsoleted */ #define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */ diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index b74f78d0c033..06d32908fcfb 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -29,18 +29,6 @@ config TIPC_ADVANCED Saying Y here will open some advanced configuration for TIPC. Most users do not need to bother; if unsure, just say N. -config TIPC_ZONES - int "Maximum number of zones in a network" - depends on TIPC_ADVANCED - range 1 255 - default "3" - help - Specifies how many zones can be supported in a TIPC network. - Can range from 1 to 255 zones; default is 3. - - Setting this to a smaller value saves some memory; - setting it to a higher value allows for more zones. - config TIPC_CLUSTERS int "Maximum number of clusters in a zone" depends on TIPC_ADVANCED diff --git a/net/tipc/Makefile b/net/tipc/Makefile index dceb7027946c..3d936f0560c7 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -8,6 +8,6 @@ tipc-y += addr.o bcast.o bearer.o config.o cluster.o \ core.o handler.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ netlink.o node.o node_subscr.o port.o ref.o \ - socket.o user_reg.o zone.o dbg.o eth_media.o + socket.o user_reg.o dbg.o eth_media.o # End of file diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 886715a75259..3d0f97da5b5f 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -35,8 +35,6 @@ */ #include "core.h" -#include "addr.h" -#include "zone.h" #include "cluster.h" /** @@ -61,8 +59,6 @@ int tipc_addr_domain_valid(u32 addr) return 0; if (c > tipc_max_clusters) return 0; - if (z > tipc_max_zones) - return 0; if (n && (!z || !c)) return 0; diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 405be87157ba..996b2b67687e 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -47,7 +47,6 @@ u32 tipc_highest_allowed_slave = 0; struct cluster *tipc_cltr_create(u32 addr) { - struct _zone *z_ptr; struct cluster *c_ptr; int max_nodes; @@ -75,18 +74,7 @@ struct cluster *tipc_cltr_create(u32 addr) c_ptr->highest_slave = LOWEST_SLAVE - 1; c_ptr->highest_node = 0; - z_ptr = tipc_zone_find(tipc_zone(addr)); - if (!z_ptr) { - z_ptr = tipc_zone_create(addr); - } - if (!z_ptr) { - kfree(c_ptr->nodes); - kfree(c_ptr); - return NULL; - } - - tipc_zone_attach_cluster(z_ptr, c_ptr); - c_ptr->owner = z_ptr; + tipc_net.clusters[1] = c_ptr; return c_ptr; } diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h index 32636d98c9c6..21493f7beb95 100644 --- a/net/tipc/cluster.h +++ b/net/tipc/cluster.h @@ -38,14 +38,13 @@ #define _TIPC_CLUSTER_H #include "addr.h" -#include "zone.h" +#include "net.h" #define LOWEST_SLAVE 2048u /** * struct cluster - TIPC cluster structure * @addr: network address of cluster - * @owner: pointer to zone that cluster belongs to * @nodes: array of pointers to all nodes within cluster * @highest_node: id of highest numbered node within cluster * @highest_slave: (used for secondary node support) @@ -53,7 +52,6 @@ struct cluster { u32 addr; - struct _zone *owner; struct tipc_node **nodes; u32 highest_node; u32 highest_slave; @@ -82,11 +80,9 @@ void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi) static inline struct cluster *tipc_cltr_find(u32 addr) { - struct _zone *z_ptr = tipc_zone_find(addr); - - if (z_ptr) - return z_ptr->clusters[1]; - return NULL; + if (!in_own_cluster(addr)) + return NULL; + return tipc_net.clusters[1]; } #endif diff --git a/net/tipc/config.c b/net/tipc/config.c index bdde39f0436b..8de97ddb0427 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -269,25 +269,6 @@ static struct sk_buff *cfg_set_max_ports(void) return tipc_cfg_reply_none(); } -static struct sk_buff *cfg_set_max_zones(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (value == tipc_max_zones) - return tipc_cfg_reply_none(); - if (value != delimit(value, 1, 255)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max zones must be 1-255)"); - if (tipc_mode == TIPC_NET_MODE) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change max zones once TIPC has joined a network)"); - tipc_max_zones = value; - return tipc_cfg_reply_none(); -} - static struct sk_buff *cfg_set_max_clusters(void) { u32 value; @@ -452,9 +433,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SET_MAX_SUBSCR: rep_tlv_buf = cfg_set_max_subscriptions(); break; - case TIPC_CMD_SET_MAX_ZONES: - rep_tlv_buf = cfg_set_max_zones(); - break; case TIPC_CMD_SET_MAX_CLUSTERS: rep_tlv_buf = cfg_set_max_clusters(); break; @@ -479,9 +457,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_GET_MAX_SUBSCR: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); break; - case TIPC_CMD_GET_MAX_ZONES: - rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones); - break; case TIPC_CMD_GET_MAX_CLUSTERS: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters); break; @@ -498,6 +473,11 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); break; + case TIPC_CMD_SET_MAX_ZONES: + case TIPC_CMD_GET_MAX_ZONES: + rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED + " (obsolete command)"); + break; default: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (unknown command)"); diff --git a/net/tipc/core.c b/net/tipc/core.c index f5d62c174de2..13946331bd4d 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -48,10 +48,6 @@ #include "config.h" -#ifndef CONFIG_TIPC_ZONES -#define CONFIG_TIPC_ZONES 3 -#endif - #ifndef CONFIG_TIPC_CLUSTERS #define CONFIG_TIPC_CLUSTERS 1 #endif @@ -84,7 +80,6 @@ const char tipc_alphabet[] = /* configurable TIPC parameters */ u32 tipc_own_addr; -int tipc_max_zones; int tipc_max_clusters; int tipc_max_nodes; int tipc_max_slaves; @@ -209,7 +204,6 @@ static int __init tipc_init(void) tipc_max_publications = 10000; tipc_max_subscriptions = 2000; tipc_max_ports = CONFIG_TIPC_PORTS; - tipc_max_zones = CONFIG_TIPC_ZONES; tipc_max_clusters = CONFIG_TIPC_CLUSTERS; tipc_max_nodes = CONFIG_TIPC_NODES; tipc_max_slaves = CONFIG_TIPC_SLAVE_NODES; diff --git a/net/tipc/core.h b/net/tipc/core.h index ca7e171c1043..9403a226a570 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -184,7 +184,6 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); */ extern u32 tipc_own_addr; -extern int tipc_max_zones; extern int tipc_max_clusters; extern int tipc_max_nodes; extern int tipc_max_slaves; diff --git a/net/tipc/net.c b/net/tipc/net.c index c2b4b86c2e6a..a25f8bb1e1d9 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -36,7 +36,6 @@ #include "core.h" #include "net.h" -#include "zone.h" #include "name_table.h" #include "name_distr.h" #include "subscr.h" @@ -111,46 +110,56 @@ */ DEFINE_RWLOCK(tipc_net_lock); -static struct _zone *tipc_zones[256] = { NULL, }; -struct network tipc_net = { tipc_zones }; +struct network tipc_net; struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref) { - return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref); + struct cluster *c_ptr; + + c_ptr = tipc_net.clusters[1]; + if (!c_ptr) + return NULL; + return tipc_cltr_select_node(c_ptr, ref); } u32 tipc_net_select_router(u32 addr, u32 ref) { - return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref); + struct cluster *c_ptr; + + c_ptr = tipc_net.clusters[1]; + if (!c_ptr) + return 0; + return tipc_cltr_select_router(c_ptr, ref); } void tipc_net_remove_as_router(u32 router) { - u32 z_num; + u32 c_num; - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { - if (!tipc_net.zones[z_num]) + for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { + if (!tipc_net.clusters[c_num]) continue; - tipc_zone_remove_as_router(tipc_net.zones[z_num], router); + tipc_cltr_remove_as_router(tipc_net.clusters[c_num], router); } } void tipc_net_send_external_routes(u32 dest) { - u32 z_num; + u32 c_num; - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { - if (tipc_net.zones[z_num]) - tipc_zone_send_external_routes(tipc_net.zones[z_num], dest); + for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { + if (tipc_net.clusters[c_num]) + tipc_cltr_send_ext_routes(tipc_net.clusters[c_num], + dest); } } static void net_stop(void) { - u32 z_num; + u32 c_num; - for (z_num = 1; z_num <= tipc_max_zones; z_num++) - tipc_zone_delete(tipc_net.zones[z_num]); + for (c_num = 1; c_num <= tipc_max_clusters; c_num++) + tipc_cltr_delete(tipc_net.clusters[c_num]); } static void net_route_named_msg(struct sk_buff *buf) diff --git a/net/tipc/net.h b/net/tipc/net.h index de2b9ad8f646..786c94007470 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h @@ -37,15 +37,17 @@ #ifndef _TIPC_NET_H #define _TIPC_NET_H -struct _zone; +struct cluster; /** * struct network - TIPC network structure - * @zones: array of pointers to all zones within network + * @clusters: array of pointers to all clusters within zone + * @links: number of (unicast) links to cluster */ struct network { - struct _zone **zones; + struct cluster *clusters[2]; /* currently limited to just 1 cluster */ + u32 links; }; diff --git a/net/tipc/node.c b/net/tipc/node.c index df71dfc3a9ae..c20bd851a44a 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -257,7 +257,7 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr) if (!n_ptr->links[bearer_id]) { n_ptr->links[bearer_id] = l_ptr; - tipc_net.zones[tipc_zone(l_ptr->addr)]->links++; + tipc_net.links++; n_ptr->link_cnt++; return n_ptr; } @@ -271,7 +271,7 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr) void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) { n_ptr->links[l_ptr->b_ptr->identity] = NULL; - tipc_net.zones[tipc_zone(l_ptr->addr)]->links--; + tipc_net.links--; n_ptr->link_cnt--; } @@ -656,8 +656,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) /* Get space for all unicast links + multicast link */ - payload_size = TLV_SPACE(sizeof(link_info)) * - (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); + payload_size = TLV_SPACE(sizeof(link_info)) * (tipc_net.links + 1); if (payload_size > 32768u) { read_unlock_bh(&tipc_net_lock); return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED diff --git a/net/tipc/node.h b/net/tipc/node.h index fff331b2d26c..7bfaf5e8c201 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -38,7 +38,6 @@ #define _TIPC_NODE_H #include "node_subscr.h" -#include "addr.h" #include "cluster.h" #include "bearer.h" diff --git a/net/tipc/zone.c b/net/tipc/zone.c deleted file mode 100644 index 1b61ca8c48ef..000000000000 --- a/net/tipc/zone.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * net/tipc/zone.c: TIPC zone management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "zone.h" -#include "cluster.h" -#include "node.h" - -struct _zone *tipc_zone_create(u32 addr) -{ - struct _zone *z_ptr; - u32 z_num; - - if (!tipc_addr_domain_valid(addr)) { - err("Zone creation failed, invalid domain 0x%x\n", addr); - return NULL; - } - - z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC); - if (!z_ptr) { - warn("Zone creation failed, insufficient memory\n"); - return NULL; - } - - z_num = tipc_zone(addr); - z_ptr->addr = tipc_addr(z_num, 0, 0); - tipc_net.zones[z_num] = z_ptr; - return z_ptr; -} - -void tipc_zone_delete(struct _zone *z_ptr) -{ - u32 c_num; - - if (!z_ptr) - return; - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - tipc_cltr_delete(z_ptr->clusters[c_num]); - } - kfree(z_ptr); -} - -void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr) -{ - u32 c_num = tipc_cluster(c_ptr->addr); - - assert(c_ptr->addr); - assert(c_num <= tipc_max_clusters); - assert(z_ptr->clusters[c_num] == NULL); - z_ptr->clusters[c_num] = c_ptr; -} - -void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (z_ptr->clusters[c_num]) { - tipc_cltr_remove_as_router(z_ptr->clusters[c_num], - router); - } - } -} - -void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (z_ptr->clusters[c_num]) { - if (in_own_cluster(z_ptr->addr)) - continue; - tipc_cltr_send_ext_routes(z_ptr->clusters[c_num], dest); - } - } -} - -struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref) -{ - struct cluster *c_ptr; - struct tipc_node *n_ptr; - u32 c_num; - - if (!z_ptr) - return NULL; - c_ptr = z_ptr->clusters[tipc_cluster(addr)]; - if (!c_ptr) - return NULL; - n_ptr = tipc_cltr_select_node(c_ptr, ref); - if (n_ptr) - return n_ptr; - - /* Links to any other clusters within this zone ? */ - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - c_ptr = z_ptr->clusters[c_num]; - if (!c_ptr) - return NULL; - n_ptr = tipc_cltr_select_node(c_ptr, ref); - if (n_ptr) - return n_ptr; - } - return NULL; -} - -u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref) -{ - struct cluster *c_ptr; - u32 c_num; - u32 router; - - if (!z_ptr) - return 0; - c_ptr = z_ptr->clusters[tipc_cluster(addr)]; - router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0; - if (router) - return router; - - /* Links to any other clusters within the zone? */ - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - c_ptr = z_ptr->clusters[c_num]; - router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0; - if (router) - return router; - } - return 0; -} diff --git a/net/tipc/zone.h b/net/tipc/zone.h deleted file mode 100644 index bd1c20ce9d06..000000000000 --- a/net/tipc/zone.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * net/tipc/zone.h: Include file for TIPC zone management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005-2006, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_ZONE_H -#define _TIPC_ZONE_H - -#include "node_subscr.h" -#include "net.h" - - -/** - * struct _zone - TIPC zone structure - * @addr: network address of zone - * @clusters: array of pointers to all clusters within zone - * @links: number of (unicast) links to zone - */ - -struct _zone { - u32 addr; - struct cluster *clusters[2]; /* currently limited to just 1 cluster */ - u32 links; -}; - -struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref); -u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref); -void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router); -void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest); -struct _zone *tipc_zone_create(u32 addr); -void tipc_zone_delete(struct _zone *z_ptr); -void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr); - -static inline struct _zone *tipc_zone_find(u32 addr) -{ - return tipc_net.zones[tipc_zone(addr)]; -} - -#endif -- cgit v1.2.3-59-g8ed1b From 08c80e9a031df0a8f0269477a32f5eae47d7a146 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:17 +0000 Subject: tipc: Remove prototype code for supporting slave nodes Simplifies routines and data structures that were intended to allow TIPC to support slave nodes (i.e. nodes that did not have links to all of the other nodes in its cluster, forcing TIPC to route messages that it could not deliver directly through a non-slave node). Currently, TIPC supports only networks containing non-slave nodes, so this code is unnecessary. Note: The latest edition of the TIPC 2.0 Specification has eliminated the concept of slave nodes entirely. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/linux/tipc_config.h | 4 +- net/tipc/addr.c | 2 - net/tipc/addr.h | 10 --- net/tipc/cluster.c | 166 ++++++-------------------------------------- net/tipc/cluster.h | 7 -- net/tipc/config.c | 21 +----- net/tipc/core.c | 6 -- net/tipc/core.h | 1 - net/tipc/discover.c | 4 -- net/tipc/msg.h | 2 +- net/tipc/node.c | 59 ++++------------ net/tipc/port.c | 5 +- 12 files changed, 40 insertions(+), 247 deletions(-) diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h index fa3aeaafeab1..dcc2b8796d0a 100644 --- a/include/linux/tipc_config.h +++ b/include/linux/tipc_config.h @@ -97,7 +97,7 @@ #define TIPC_CMD_GET_MAX_ZONES 0x4007 /* obsoleted */ #define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_SLAVES 0x400A /* tx none, rx unsigned */ +#define TIPC_CMD_GET_MAX_SLAVES 0x400A /* obsoleted */ #define TIPC_CMD_GET_NETID 0x400B /* tx none, rx unsigned */ #define TIPC_CMD_ENABLE_BEARER 0x4101 /* tx bearer_config, rx none */ @@ -133,7 +133,7 @@ #define TIPC_CMD_SET_MAX_ZONES 0x8007 /* obsoleted */ #define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */ +#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* obsoleted */ #define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */ /* diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 3d0f97da5b5f..8823e03e52e0 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -53,8 +53,6 @@ int tipc_addr_domain_valid(u32 addr) u32 z = tipc_zone(addr); u32 max_nodes = tipc_max_nodes; - if (is_slave(addr)) - max_nodes = LOWEST_SLAVE + tipc_max_slaves; if (n > max_nodes) return 0; if (c > tipc_max_clusters) diff --git a/net/tipc/addr.h b/net/tipc/addr.h index c1cc5724d8cc..a16c6c87208e 100644 --- a/net/tipc/addr.h +++ b/net/tipc/addr.h @@ -57,16 +57,6 @@ static inline int in_own_cluster(u32 addr) return !((addr ^ tipc_own_addr) >> 12); } -static inline int is_slave(u32 addr) -{ - return addr & 0x800; -} - -static inline int may_route(u32 addr) -{ - return(addr ^ tipc_own_addr) >> 11; -} - /** * addr_domain - convert 2-bit scope value to equivalent message lookup domain * diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 996b2b67687e..6bc9f07be945 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -43,7 +43,6 @@ static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, struct tipc_node **tipc_local_nodes = NULL; struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}}; -u32 tipc_highest_allowed_slave = 0; struct cluster *tipc_cltr_create(u32 addr) { @@ -57,10 +56,7 @@ struct cluster *tipc_cltr_create(u32 addr) } c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); - if (in_own_cluster(addr)) - max_nodes = LOWEST_SLAVE + tipc_max_slaves; - else - max_nodes = tipc_max_nodes + 1; + max_nodes = tipc_max_nodes + 1; c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC); if (c_ptr->nodes == NULL) { @@ -71,7 +67,6 @@ struct cluster *tipc_cltr_create(u32 addr) if (in_own_cluster(addr)) tipc_local_nodes = c_ptr->nodes; - c_ptr->highest_slave = LOWEST_SLAVE - 1; c_ptr->highest_node = 0; tipc_net.clusters[1] = c_ptr; @@ -87,9 +82,6 @@ void tipc_cltr_delete(struct cluster *c_ptr) for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { tipc_node_delete(c_ptr->nodes[n_num]); } - for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) { - tipc_node_delete(c_ptr->nodes[n_num]); - } kfree(c_ptr->nodes); kfree(c_ptr); } @@ -100,8 +92,6 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr) u32 n_num = tipc_node(n_ptr->addr); u32 max_n_num = tipc_max_nodes; - if (in_own_cluster(n_ptr->addr)) - max_n_num = tipc_highest_allowed_slave; assert(n_num > 0); assert(n_num <= max_n_num); assert(c_ptr->nodes[n_num] == NULL); @@ -237,41 +227,6 @@ void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, } } -void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_slave; - u32 n_num; - int send = 0; - - assert(!is_slave(dest)); - assert(in_own_cluster(dest)); - assert(in_own_cluster(c_ptr->addr)); - if (highest <= LOWEST_SLAVE) - return; - buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1, - c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, SLAVE_ROUTING_TABLE); - for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - tipc_node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - tipc_link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of lost route failed\n"); - } -} - void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest) { struct sk_buff *buf; @@ -282,7 +237,6 @@ void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest) if (in_own_cluster(c_ptr->addr)) return; - assert(!is_slave(dest)); assert(in_own_cluster(dest)); highest = c_ptr->highest_node; buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr); @@ -306,37 +260,6 @@ void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest) } } -void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_node; - u32 n_num; - int send = 0; - - assert(is_slave(dest)); - assert(in_own_cluster(c_ptr->addr)); - buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, LOCAL_ROUTING_TABLE); - for (n_num = 1; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - tipc_node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - tipc_link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of local route failed\n"); - } -} - void tipc_cltr_recv_routing_table(struct sk_buff *buf) { struct tipc_msg *msg = buf_msg(buf); @@ -366,8 +289,6 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf) c_num = tipc_cluster(rem_node); switch (msg_type(msg)) { - case LOCAL_ROUTING_TABLE: - assert(is_slave(tipc_own_addr)); case EXT_ROUTING_TABLE: for (n_num = 1; n_num < table_size; n_num++) { if (node_table[n_num]) { @@ -382,29 +303,10 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf) } break; case SLAVE_ROUTING_TABLE: - assert(!is_slave(tipc_own_addr)); assert(in_own_cluster(c_ptr->addr)); - for (n_num = 1; n_num < table_size; n_num++) { - if (node_table[n_num]) { - u32 slave_num = n_num + LOWEST_SLAVE; - u32 addr = tipc_addr(z_num, c_num, slave_num); - n_ptr = c_ptr->nodes[slave_num]; - if (!n_ptr) { - n_ptr = tipc_node_create(addr); - } - if (n_ptr) - tipc_node_add_router(n_ptr, router); - } - } break; case ROUTE_ADDITION: - if (!is_slave(tipc_own_addr)) { - assert(!in_own_cluster(c_ptr->addr) || - is_slave(rem_node)); - } else { - assert(in_own_cluster(c_ptr->addr) && - !is_slave(rem_node)); - } + assert(!in_own_cluster(c_ptr->addr)); n_ptr = c_ptr->nodes[tipc_node(rem_node)]; if (!n_ptr) n_ptr = tipc_node_create(rem_node); @@ -412,13 +314,7 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf) tipc_node_add_router(n_ptr, router); break; case ROUTE_REMOVAL: - if (!is_slave(tipc_own_addr)) { - assert(!in_own_cluster(c_ptr->addr) || - is_slave(rem_node)); - } else { - assert(in_own_cluster(c_ptr->addr) && - !is_slave(rem_node)); - } + assert(!in_own_cluster(c_ptr->addr)); n_ptr = c_ptr->nodes[tipc_node(rem_node)]; if (n_ptr) tipc_node_remove_router(n_ptr, router); @@ -431,22 +327,12 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf) void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router) { - u32 start_entry; - u32 tstop; u32 n_num; - if (is_slave(router)) - return; /* Slave nodes can not be routers */ - - if (in_own_cluster(c_ptr->addr)) { - start_entry = LOWEST_SLAVE; - tstop = c_ptr->highest_slave; - } else { - start_entry = 1; - tstop = c_ptr->highest_node; - } + if (in_own_cluster(c_ptr->addr)) + return; - for (n_num = start_entry; n_num <= tstop; n_num++) { + for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { if (c_ptr->nodes[n_num]) { tipc_node_remove_router(c_ptr->nodes[n_num], router); } @@ -466,13 +352,11 @@ static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, u32 tstop; assert(lower <= upper); - assert(((lower >= 1) && (lower <= tipc_max_nodes)) || - ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave))); - assert(((upper >= 1) && (upper <= tipc_max_nodes)) || - ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave))); + assert((lower >= 1) && (lower <= tipc_max_nodes)); + assert((upper >= 1) && (upper <= tipc_max_nodes)); assert(in_own_cluster(c_ptr->addr)); - tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node; + tstop = c_ptr->highest_node; if (tstop > upper) tstop = upper; for (n_num = lower; n_num <= tstop; n_num++) { @@ -498,32 +382,23 @@ void tipc_cltr_broadcast(struct sk_buff *buf) struct cluster *c_ptr; struct tipc_node *n_ptr; u32 n_num; - u32 tstart; - u32 tstop; - u32 node_type; if (tipc_mode == TIPC_NET_MODE) { c_ptr = tipc_cltr_find(tipc_own_addr); assert(in_own_cluster(c_ptr->addr)); /* For now */ - /* Send to standard nodes, then repeat loop sending to slaves */ - tstart = 1; - tstop = c_ptr->highest_node; - for (node_type = 1; node_type <= 2; node_type++) { - for (n_num = tstart; n_num <= tstop; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) { - buf_copy = skb_copy(buf, GFP_ATOMIC); - if (buf_copy == NULL) - goto exit; - msg_set_destnode(buf_msg(buf_copy), - n_ptr->addr); - tipc_link_send(buf_copy, n_ptr->addr, - n_ptr->addr); - } + /* Send to nodes */ + for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { + n_ptr = c_ptr->nodes[n_num]; + if (n_ptr && tipc_node_has_active_links(n_ptr)) { + buf_copy = skb_copy(buf, GFP_ATOMIC); + if (buf_copy == NULL) + goto exit; + msg_set_destnode(buf_msg(buf_copy), + n_ptr->addr); + tipc_link_send(buf_copy, n_ptr->addr, + n_ptr->addr); } - tstart = LOWEST_SLAVE; - tstop = c_ptr->highest_slave; } } exit: @@ -532,7 +407,6 @@ exit: int tipc_cltr_init(void) { - tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM; } diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h index 21493f7beb95..aa1fd6ab4d11 100644 --- a/net/tipc/cluster.h +++ b/net/tipc/cluster.h @@ -40,26 +40,21 @@ #include "addr.h" #include "net.h" -#define LOWEST_SLAVE 2048u - /** * struct cluster - TIPC cluster structure * @addr: network address of cluster * @nodes: array of pointers to all nodes within cluster * @highest_node: id of highest numbered node within cluster - * @highest_slave: (used for secondary node support) */ struct cluster { u32 addr; struct tipc_node **nodes; u32 highest_node; - u32 highest_slave; }; extern struct tipc_node **tipc_local_nodes; -extern u32 tipc_highest_allowed_slave; extern struct tipc_node_map tipc_cltr_bcast_nodes; void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router); @@ -70,12 +65,10 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf); struct cluster *tipc_cltr_create(u32 addr); void tipc_cltr_delete(struct cluster *c_ptr); void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); -void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_broadcast(struct sk_buff *buf); int tipc_cltr_init(void); void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); -void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); static inline struct cluster *tipc_cltr_find(u32 addr) diff --git a/net/tipc/config.c b/net/tipc/config.c index 8de97ddb0427..05dc102300ae 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -301,19 +301,6 @@ static struct sk_buff *cfg_set_max_nodes(void) return tipc_cfg_reply_none(); } -static struct sk_buff *cfg_set_max_slaves(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (value != 0) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (max secondary nodes fixed at 0)"); - return tipc_cfg_reply_none(); -} - static struct sk_buff *cfg_set_netid(void) { u32 value; @@ -439,9 +426,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SET_MAX_NODES: rep_tlv_buf = cfg_set_max_nodes(); break; - case TIPC_CMD_SET_MAX_SLAVES: - rep_tlv_buf = cfg_set_max_slaves(); - break; case TIPC_CMD_SET_NETID: rep_tlv_buf = cfg_set_netid(); break; @@ -463,9 +447,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_GET_MAX_NODES: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes); break; - case TIPC_CMD_GET_MAX_SLAVES: - rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves); - break; case TIPC_CMD_GET_NETID: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); break; @@ -475,6 +456,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area break; case TIPC_CMD_SET_MAX_ZONES: case TIPC_CMD_GET_MAX_ZONES: + case TIPC_CMD_SET_MAX_SLAVES: + case TIPC_CMD_GET_MAX_SLAVES: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (obsolete command)"); break; diff --git a/net/tipc/core.c b/net/tipc/core.c index 13946331bd4d..8b7af893971e 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -56,10 +56,6 @@ #define CONFIG_TIPC_NODES 255 #endif -#ifndef CONFIG_TIPC_SLAVE_NODES -#define CONFIG_TIPC_SLAVE_NODES 0 -#endif - #ifndef CONFIG_TIPC_PORTS #define CONFIG_TIPC_PORTS 8191 #endif @@ -82,7 +78,6 @@ const char tipc_alphabet[] = u32 tipc_own_addr; int tipc_max_clusters; int tipc_max_nodes; -int tipc_max_slaves; int tipc_max_ports; int tipc_max_subscriptions; int tipc_max_publications; @@ -206,7 +201,6 @@ static int __init tipc_init(void) tipc_max_ports = CONFIG_TIPC_PORTS; tipc_max_clusters = CONFIG_TIPC_CLUSTERS; tipc_max_nodes = CONFIG_TIPC_NODES; - tipc_max_slaves = CONFIG_TIPC_SLAVE_NODES; tipc_net_id = 4711; if ((res = tipc_core_start())) diff --git a/net/tipc/core.h b/net/tipc/core.h index 9403a226a570..8313a1689565 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -186,7 +186,6 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); extern u32 tipc_own_addr; extern int tipc_max_clusters; extern int tipc_max_nodes; -extern int tipc_max_slaves; extern int tipc_max_ports; extern int tipc_max_subscriptions; extern int tipc_max_publications; diff --git a/net/tipc/discover.c b/net/tipc/discover.c index f2ce36baf42e..80799f6ba892 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -149,10 +149,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) } if (!tipc_in_scope(dest, tipc_own_addr)) return; - if (is_slave(tipc_own_addr) && is_slave(orig)) - return; - if (is_slave(orig) && !in_own_cluster(orig)) - return; if (in_own_cluster(orig)) { /* Always accept link here */ struct sk_buff *rbuf; diff --git a/net/tipc/msg.h b/net/tipc/msg.h index aee53864d7a0..c1b6217838e6 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -850,7 +850,7 @@ static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) * Routing table message types */ #define EXT_ROUTING_TABLE 0 -#define LOCAL_ROUTING_TABLE 1 +#define LOCAL_ROUTING_TABLE 1 /* obsoleted */ #define SLAVE_ROUTING_TABLE 2 #define ROUTE_ADDITION 3 #define ROUTE_REMOVAL 4 diff --git a/net/tipc/node.c b/net/tipc/node.c index c20bd851a44a..8ffbdb33b2cb 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -333,8 +333,6 @@ static void node_established_contact(struct tipc_node *n_ptr) /* Syncronize broadcast acks */ n_ptr->bclink.acked = tipc_bclink_get_last_sent(); - if (is_slave(tipc_own_addr)) - return; if (!in_own_cluster(n_ptr->addr)) { /* Usage case 1 (see above) */ c_ptr = tipc_cltr_find(tipc_own_addr); @@ -347,13 +345,6 @@ static void node_established_contact(struct tipc_node *n_ptr) } c_ptr = n_ptr->owner; - if (is_slave(n_ptr->addr)) { - /* Usage case 2 (see above) */ - tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes); - tipc_cltr_send_local_routes(c_ptr, n_ptr->addr); - return; - } - if (n_ptr->bclink.supported) { tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); if (n_ptr->addr < tipc_own_addr) @@ -362,9 +353,6 @@ static void node_established_contact(struct tipc_node *n_ptr) /* Case 3 (see above) */ tipc_net_send_external_routes(n_ptr->addr); - tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr); - tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE, - tipc_highest_allowed_slave); } static void node_cleanup_finished(unsigned long node_addr) @@ -404,33 +392,20 @@ static void node_lost_contact(struct tipc_node *n_ptr) } /* Update routing tables */ - if (is_slave(tipc_own_addr)) { - tipc_net_remove_as_router(n_ptr->addr); + if (!in_own_cluster(n_ptr->addr)) { + /* Case 4 (see above) */ + c_ptr = tipc_cltr_find(tipc_own_addr); + tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1, + tipc_max_nodes); } else { - if (!in_own_cluster(n_ptr->addr)) { - /* Case 4 (see above) */ - c_ptr = tipc_cltr_find(tipc_own_addr); - tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - } else { - /* Case 5 (see above) */ - c_ptr = tipc_cltr_find(n_ptr->addr); - if (is_slave(n_ptr->addr)) { - tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - } else { - if (n_ptr->bclink.supported) { - tipc_nmap_remove(&tipc_cltr_bcast_nodes, - n_ptr->addr); - if (n_ptr->addr < tipc_own_addr) - tipc_own_tag--; - } - tipc_net_remove_as_router(n_ptr->addr); - tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, - LOWEST_SLAVE, - tipc_highest_allowed_slave); - } + /* Case 5 (see above) */ + c_ptr = tipc_cltr_find(n_ptr->addr); + if (n_ptr->bclink.supported) { + tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr); + if (n_ptr->addr < tipc_own_addr) + tipc_own_tag--; } + tipc_net_remove_as_router(n_ptr->addr); } if (tipc_node_has_active_routes(n_ptr)) return; @@ -482,7 +457,7 @@ struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector) return n_ptr; /* Cluster local system nodes *must* have direct links */ - if (!is_slave(addr) && in_own_cluster(addr)) + if (in_own_cluster(addr)) return NULL; /* Look for cluster local router with direct link to node */ @@ -490,11 +465,6 @@ struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector) if (router_addr) return tipc_node_select(router_addr, selector); - /* Slave nodes can only be accessed within own cluster via a - known router with direct link -- if no router was found,give up */ - if (is_slave(addr)) - return NULL; - /* Inter zone/cluster -- find any direct link to remote cluster */ addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); n_ptr = tipc_net_select_remote_node(addr, selector); @@ -603,8 +573,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) return tipc_cfg_reply_none(); } - /* For now, get space for all other nodes - (will need to modify this when slave nodes are supported */ + /* For now, get space for all other nodes */ payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); if (payload_size > 32768u) { diff --git a/net/tipc/port.c b/net/tipc/port.c index 7873283f4965..c033cb87b964 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -1110,10 +1110,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) msg_set_origport(msg, p_ptr->publ.ref); msg_set_transp_seqno(msg, 42); msg_set_type(msg, TIPC_CONN_MSG); - if (!may_route(peer->node)) - msg_set_hdr_sz(msg, SHORT_H_SIZE); - else - msg_set_hdr_sz(msg, LONG_H_SIZE); + msg_set_hdr_sz(msg, SHORT_H_SIZE); p_ptr->probing_interval = PROBING_INTERVAL; p_ptr->probing_state = CONFIRMED; -- cgit v1.2.3-59-g8ed1b From 51a8e4dee7653698ba4c6e7de71053665f075273 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:18 +0000 Subject: tipc: Remove prototype code for supporting inter-cluster routing Eliminates routines and data structures that were intended to allow TIPC to route messages to other clusters. Currently, TIPC supports only networks consisting of a single cluster within a single zone, so this code is unnecessary. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/linux/tipc_config.h | 5 - net/tipc/addr.h | 15 --- net/tipc/cluster.c | 279 +------------------------------------------- net/tipc/cluster.h | 8 -- net/tipc/link.c | 13 +-- net/tipc/msg.h | 7 +- net/tipc/net.c | 45 ------- net/tipc/net.h | 4 - net/tipc/node.c | 166 ++------------------------ net/tipc/node.h | 21 ---- 10 files changed, 15 insertions(+), 548 deletions(-) diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h index dcc2b8796d0a..1f38df1202ba 100644 --- a/include/linux/tipc_config.h +++ b/include/linux/tipc_config.h @@ -254,11 +254,6 @@ struct tipc_link_create { struct tipc_media_addr peer_addr; char bearer_name[TIPC_MAX_BEARER_NAME]; }; - -struct tipc_route_info { - __u32 dest; - __u32 router; -}; #endif /* diff --git a/net/tipc/addr.h b/net/tipc/addr.h index a16c6c87208e..2490fadd0caf 100644 --- a/net/tipc/addr.h +++ b/net/tipc/addr.h @@ -37,21 +37,6 @@ #ifndef _TIPC_ADDR_H #define _TIPC_ADDR_H -static inline u32 own_node(void) -{ - return tipc_node(tipc_own_addr); -} - -static inline u32 own_cluster(void) -{ - return tipc_cluster(tipc_own_addr); -} - -static inline u32 own_zone(void) -{ - return tipc_zone(tipc_own_addr); -} - static inline int in_own_cluster(u32 addr) { return !((addr ^ tipc_own_addr) >> 12); diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 6bc9f07be945..ba6f5bfa0cdb 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -38,9 +38,6 @@ #include "cluster.h" #include "link.h" -static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, - u32 lower, u32 upper); - struct tipc_node **tipc_local_nodes = NULL; struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}}; @@ -65,8 +62,7 @@ struct cluster *tipc_cltr_create(u32 addr) return NULL; } - if (in_own_cluster(addr)) - tipc_local_nodes = c_ptr->nodes; + tipc_local_nodes = c_ptr->nodes; c_ptr->highest_node = 0; tipc_net.clusters[1] = c_ptr; @@ -100,278 +96,6 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr) c_ptr->highest_node = n_num; } -/** - * tipc_cltr_select_router - select router to a cluster - * - * Uses deterministic and fair algorithm. - */ - -u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref) -{ - u32 n_num; - u32 ulim = c_ptr->highest_node; - u32 mask; - u32 tstart; - - assert(!in_own_cluster(c_ptr->addr)); - if (!ulim) - return 0; - - /* Start entry must be random */ - mask = tipc_max_nodes; - while (mask > ulim) - mask >>= 1; - tstart = ref & mask; - n_num = tstart; - - /* Lookup upwards with wrap-around */ - do { - if (tipc_node_is_up(c_ptr->nodes[n_num])) - break; - } while (++n_num <= ulim); - if (n_num > ulim) { - n_num = 1; - do { - if (tipc_node_is_up(c_ptr->nodes[n_num])) - break; - } while (++n_num < tstart); - if (n_num == tstart) - return 0; - } - assert(n_num <= ulim); - return tipc_node_select_router(c_ptr->nodes[n_num], ref); -} - -/** - * tipc_cltr_select_node - select destination node within a remote cluster - * - * Uses deterministic and fair algorithm. - */ - -struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector) -{ - u32 n_num; - u32 mask = tipc_max_nodes; - u32 start_entry; - - assert(!in_own_cluster(c_ptr->addr)); - if (!c_ptr->highest_node) - return NULL; - - /* Start entry must be random */ - while (mask > c_ptr->highest_node) { - mask >>= 1; - } - start_entry = (selector & mask) ? selector & mask : 1u; - assert(start_entry <= c_ptr->highest_node); - - /* Lookup upwards with wrap-around */ - for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) { - if (tipc_node_has_active_links(c_ptr->nodes[n_num])) - return c_ptr->nodes[n_num]; - } - for (n_num = 1; n_num < start_entry; n_num++) { - if (tipc_node_has_active_links(c_ptr->nodes[n_num])) - return c_ptr->nodes[n_num]; - } - return NULL; -} - -/* - * Routing table management: See description in node.c - */ - -static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest) -{ - u32 size = INT_H_SIZE + data_size; - struct sk_buff *buf = tipc_buf_acquire(size); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - memset((char *)msg, 0, size); - tipc_msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest); - } - return buf; -} - -void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, - u32 lower, u32 upper) -{ - struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, dest); - msg_set_type(msg, ROUTE_ADDITION); - tipc_cltr_multicast(c_ptr, buf, lower, upper); - } else { - warn("Memory squeeze: broadcast of new route failed\n"); - } -} - -void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, - u32 lower, u32 upper) -{ - struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, dest); - msg_set_type(msg, ROUTE_REMOVAL); - tipc_cltr_multicast(c_ptr, buf, lower, upper); - } else { - warn("Memory squeeze: broadcast of lost route failed\n"); - } -} - -void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_node; - u32 n_num; - int send = 0; - - if (in_own_cluster(c_ptr->addr)) - return; - assert(in_own_cluster(dest)); - highest = c_ptr->highest_node; - buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, EXT_ROUTING_TABLE); - for (n_num = 1; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - tipc_node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - tipc_link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of external route failed\n"); - } -} - -void tipc_cltr_recv_routing_table(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - struct cluster *c_ptr; - struct tipc_node *n_ptr; - unchar *node_table; - u32 table_size; - u32 router; - u32 rem_node = msg_remote_node(msg); - u32 z_num; - u32 c_num; - u32 n_num; - - c_ptr = tipc_cltr_find(rem_node); - if (!c_ptr) { - c_ptr = tipc_cltr_create(rem_node); - if (!c_ptr) { - buf_discard(buf); - return; - } - } - - node_table = buf->data + msg_hdr_sz(msg); - table_size = msg_size(msg) - msg_hdr_sz(msg); - router = msg_prevnode(msg); - z_num = tipc_zone(rem_node); - c_num = tipc_cluster(rem_node); - - switch (msg_type(msg)) { - case EXT_ROUTING_TABLE: - for (n_num = 1; n_num < table_size; n_num++) { - if (node_table[n_num]) { - u32 addr = tipc_addr(z_num, c_num, n_num); - n_ptr = c_ptr->nodes[n_num]; - if (!n_ptr) { - n_ptr = tipc_node_create(addr); - } - if (n_ptr) - tipc_node_add_router(n_ptr, router); - } - } - break; - case SLAVE_ROUTING_TABLE: - assert(in_own_cluster(c_ptr->addr)); - break; - case ROUTE_ADDITION: - assert(!in_own_cluster(c_ptr->addr)); - n_ptr = c_ptr->nodes[tipc_node(rem_node)]; - if (!n_ptr) - n_ptr = tipc_node_create(rem_node); - if (n_ptr) - tipc_node_add_router(n_ptr, router); - break; - case ROUTE_REMOVAL: - assert(!in_own_cluster(c_ptr->addr)); - n_ptr = c_ptr->nodes[tipc_node(rem_node)]; - if (n_ptr) - tipc_node_remove_router(n_ptr, router); - break; - default: - assert(!"Illegal routing manager message received\n"); - } - buf_discard(buf); -} - -void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router) -{ - u32 n_num; - - if (in_own_cluster(c_ptr->addr)) - return; - - for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { - if (c_ptr->nodes[n_num]) { - tipc_node_remove_router(c_ptr->nodes[n_num], router); - } - } -} - -/** - * tipc_cltr_multicast - multicast message to local nodes - */ - -static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, - u32 lower, u32 upper) -{ - struct sk_buff *buf_copy; - struct tipc_node *n_ptr; - u32 n_num; - u32 tstop; - - assert(lower <= upper); - assert((lower >= 1) && (lower <= tipc_max_nodes)); - assert((upper >= 1) && (upper <= tipc_max_nodes)); - assert(in_own_cluster(c_ptr->addr)); - - tstop = c_ptr->highest_node; - if (tstop > upper) - tstop = upper; - for (n_num = lower; n_num <= tstop; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) { - buf_copy = skb_copy(buf, GFP_ATOMIC); - if (buf_copy == NULL) - break; - msg_set_destnode(buf_msg(buf_copy), n_ptr->addr); - tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr); - } - } - buf_discard(buf); -} - /** * tipc_cltr_broadcast - broadcast message to all nodes within cluster */ @@ -385,7 +109,6 @@ void tipc_cltr_broadcast(struct sk_buff *buf) if (tipc_mode == TIPC_NET_MODE) { c_ptr = tipc_cltr_find(tipc_own_addr); - assert(in_own_cluster(c_ptr->addr)); /* For now */ /* Send to nodes */ for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h index aa1fd6ab4d11..e4b6e4e27371 100644 --- a/net/tipc/cluster.h +++ b/net/tipc/cluster.h @@ -57,20 +57,12 @@ struct cluster { extern struct tipc_node **tipc_local_nodes; extern struct tipc_node_map tipc_cltr_bcast_nodes; -void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router); -void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest); -struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector); -u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref); -void tipc_cltr_recv_routing_table(struct sk_buff *buf); struct cluster *tipc_cltr_create(u32 addr); void tipc_cltr_delete(struct cluster *c_ptr); void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); void tipc_cltr_broadcast(struct sk_buff *buf); int tipc_cltr_init(void); -void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); -void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); - static inline struct cluster *tipc_cltr_find(u32 addr) { if (!in_own_cluster(addr)) diff --git a/net/tipc/link.c b/net/tipc/link.c index cf414cf05e72..671ffd3c0e53 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1061,7 +1061,7 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) int res = -ELINKCONG; read_lock_bh(&tipc_net_lock); - n_ptr = tipc_node_select(dest, selector); + n_ptr = tipc_node_find(dest); if (n_ptr) { tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector & 1]; @@ -1137,7 +1137,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) return tipc_port_recv_msg(buf); read_lock_bh(&tipc_net_lock); - n_ptr = tipc_node_select(destnode, selector); + n_ptr = tipc_node_find(destnode); if (likely(n_ptr)) { tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector]; @@ -1186,7 +1186,7 @@ again: !sender->user_port, &buf); read_lock_bh(&tipc_net_lock); - node = tipc_node_select(destaddr, selector); + node = tipc_node_find(destaddr); if (likely(node)) { tipc_node_lock(node); l_ptr = node->active_links[selector]; @@ -1376,7 +1376,7 @@ error: * Now we have a buffer chain. Select a link and check * that packet size is still OK */ - node = tipc_node_select(destaddr, sender->publ.ref & 1); + node = tipc_node_find(destaddr); if (likely(node)) { tipc_node_lock(node); l_ptr = node->active_links[sender->publ.ref & 1]; @@ -1893,7 +1893,7 @@ deliver: continue; case ROUTE_DISTRIBUTOR: tipc_node_unlock(n_ptr); - tipc_cltr_recv_routing_table(buf); + buf_discard(buf); continue; case NAME_DISTRIBUTOR: tipc_node_unlock(n_ptr); @@ -2852,7 +2852,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window) l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; l_ptr->queue_limit[CONN_MANAGER] = 1200; - l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200; l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; /* FRAGMENT and LAST_FRAGMENT packets */ @@ -3154,7 +3153,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) return MAX_MSG_SIZE; read_lock_bh(&tipc_net_lock); - n_ptr = tipc_node_select(dest, selector); + n_ptr = tipc_node_find(dest); if (n_ptr) { tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector & 1]; diff --git a/net/tipc/msg.h b/net/tipc/msg.h index c1b6217838e6..68b65ef3e74b 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -540,7 +540,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) #define MSG_BUNDLER 6 #define LINK_PROTOCOL 7 #define CONN_MANAGER 8 -#define ROUTE_DISTRIBUTOR 9 +#define ROUTE_DISTRIBUTOR 9 /* obsoleted */ #define CHANGEOVER_PROTOCOL 10 #define NAME_DISTRIBUTOR 11 #define MSG_FRAGMENTER 12 @@ -819,11 +819,6 @@ static inline void msg_set_remote_node(struct tipc_msg *m, u32 a) msg_set_word(m, msg_hdr_sz(m)/4, a); } -static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) -{ - msg_data(m)[pos + 4] = 1; -} - /* * Segmentation message types */ diff --git a/net/tipc/net.c b/net/tipc/net.c index a25f8bb1e1d9..3967f1f6d97f 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -112,48 +112,6 @@ DEFINE_RWLOCK(tipc_net_lock); struct network tipc_net; -struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref) -{ - struct cluster *c_ptr; - - c_ptr = tipc_net.clusters[1]; - if (!c_ptr) - return NULL; - return tipc_cltr_select_node(c_ptr, ref); -} - -u32 tipc_net_select_router(u32 addr, u32 ref) -{ - struct cluster *c_ptr; - - c_ptr = tipc_net.clusters[1]; - if (!c_ptr) - return 0; - return tipc_cltr_select_router(c_ptr, ref); -} - -void tipc_net_remove_as_router(u32 router) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (!tipc_net.clusters[c_num]) - continue; - tipc_cltr_remove_as_router(tipc_net.clusters[c_num], router); - } -} - -void tipc_net_send_external_routes(u32 dest) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (tipc_net.clusters[c_num]) - tipc_cltr_send_ext_routes(tipc_net.clusters[c_num], - dest); - } -} - static void net_stop(void) { u32 c_num; @@ -225,9 +183,6 @@ void tipc_net_route_msg(struct sk_buff *buf) return; } switch (msg_user(msg)) { - case ROUTE_DISTRIBUTOR: - tipc_cltr_recv_routing_table(buf); - break; case NAME_DISTRIBUTOR: tipc_named_recv(buf); break; diff --git a/net/tipc/net.h b/net/tipc/net.h index 786c94007470..6e402d9b33e0 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h @@ -54,11 +54,7 @@ struct network { extern struct network tipc_net; extern rwlock_t tipc_net_lock; -void tipc_net_remove_as_router(u32 router); -void tipc_net_send_external_routes(u32 dest); void tipc_net_route_msg(struct sk_buff *buf); -struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref); -u32 tipc_net_select_router(u32 addr, u32 ref); int tipc_net_start(u32 addr); void tipc_net_stop(void); diff --git a/net/tipc/node.c b/net/tipc/node.c index 8ffbdb33b2cb..c47cc69eb575 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -95,11 +95,10 @@ struct tipc_node *tipc_node_create(u32 addr) } n_ptr->addr = addr; - spin_lock_init(&n_ptr->lock); + spin_lock_init(&n_ptr->lock); INIT_LIST_HEAD(&n_ptr->nsub); n_ptr->owner = c_ptr; tipc_cltr_attach_node(c_ptr, n_ptr); - n_ptr->last_router = -1; /* Insert node into ordered list */ for (curr_node = &tipc_nodes; *curr_node; @@ -229,14 +228,9 @@ int tipc_node_has_redundant_links(struct tipc_node *n_ptr) return n_ptr->working_links > 1; } -static int tipc_node_has_active_routes(struct tipc_node *n_ptr) -{ - return n_ptr && (n_ptr->last_router >= 0); -} - int tipc_node_is_up(struct tipc_node *n_ptr) { - return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); + return tipc_node_has_active_links(n_ptr); } struct tipc_node *tipc_node_attach_link(struct link *l_ptr) @@ -323,36 +317,17 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) static void node_established_contact(struct tipc_node *n_ptr) { - struct cluster *c_ptr; - dbg("node_established_contact:-> %x\n", n_ptr->addr); - if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) { - tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); - } + tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); /* Syncronize broadcast acks */ n_ptr->bclink.acked = tipc_bclink_get_last_sent(); - if (!in_own_cluster(n_ptr->addr)) { - /* Usage case 1 (see above) */ - c_ptr = tipc_cltr_find(tipc_own_addr); - if (!c_ptr) - c_ptr = tipc_cltr_create(tipc_own_addr); - if (c_ptr) - tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - return; - } - - c_ptr = n_ptr->owner; if (n_ptr->bclink.supported) { tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); if (n_ptr->addr < tipc_own_addr) tipc_own_tag++; } - - /* Case 3 (see above) */ - tipc_net_send_external_routes(n_ptr->addr); } static void node_cleanup_finished(unsigned long node_addr) @@ -371,7 +346,6 @@ static void node_cleanup_finished(unsigned long node_addr) static void node_lost_contact(struct tipc_node *n_ptr) { - struct cluster *c_ptr; struct tipc_node_subscr *ns, *tns; char addr_string[16]; u32 i; @@ -392,23 +366,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) } /* Update routing tables */ - if (!in_own_cluster(n_ptr->addr)) { - /* Case 4 (see above) */ - c_ptr = tipc_cltr_find(tipc_own_addr); - tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - } else { - /* Case 5 (see above) */ - c_ptr = tipc_cltr_find(n_ptr->addr); - if (n_ptr->bclink.supported) { - tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr); - if (n_ptr->addr < tipc_own_addr) - tipc_own_tag--; - } - tipc_net_remove_as_router(n_ptr->addr); + if (n_ptr->bclink.supported) { + tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr); + if (n_ptr->addr < tipc_own_addr) + tipc_own_tag--; } - if (tipc_node_has_active_routes(n_ptr)) - return; info("Lost contact with %s\n", tipc_addr_string_fill(addr_string, n_ptr->addr)); @@ -437,120 +399,6 @@ static void node_lost_contact(struct tipc_node *n_ptr) tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); } -/** - * tipc_node_select_next_hop - find the next-hop node for a message - * - * Called by when cluster local lookup has failed. - */ - -struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector) -{ - struct tipc_node *n_ptr; - u32 router_addr; - - if (!tipc_addr_domain_valid(addr)) - return NULL; - - /* Look for direct link to destination processsor */ - n_ptr = tipc_node_find(addr); - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr; - - /* Cluster local system nodes *must* have direct links */ - if (in_own_cluster(addr)) - return NULL; - - /* Look for cluster local router with direct link to node */ - router_addr = tipc_node_select_router(n_ptr, selector); - if (router_addr) - return tipc_node_select(router_addr, selector); - - /* Inter zone/cluster -- find any direct link to remote cluster */ - addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); - n_ptr = tipc_net_select_remote_node(addr, selector); - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr; - - /* Last resort -- look for any router to anywhere in remote zone */ - router_addr = tipc_net_select_router(addr, selector); - if (router_addr) - return tipc_node_select(router_addr, selector); - - return NULL; -} - -/** - * tipc_node_select_router - select router to reach specified node - * - * Uses a deterministic and fair algorithm for selecting router node. - */ - -u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref) -{ - u32 ulim; - u32 mask; - u32 start; - u32 r; - - if (!n_ptr) - return 0; - - if (n_ptr->last_router < 0) - return 0; - ulim = ((n_ptr->last_router + 1) * 32) - 1; - - /* Start entry must be random */ - mask = tipc_max_nodes; - while (mask > ulim) - mask >>= 1; - start = ref & mask; - r = start; - - /* Lookup upwards with wrap-around */ - do { - if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1) - break; - } while (++r <= ulim); - if (r > ulim) { - r = 1; - do { - if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1) - break; - } while (++r < start); - assert(r != start); - } - assert(r && (r <= ulim)); - return tipc_addr(own_zone(), own_cluster(), r); -} - -void tipc_node_add_router(struct tipc_node *n_ptr, u32 router) -{ - u32 r_num = tipc_node(router); - - n_ptr->routers[r_num / 32] = - ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]); - n_ptr->last_router = tipc_max_nodes / 32; - while ((--n_ptr->last_router >= 0) && - !n_ptr->routers[n_ptr->last_router]); -} - -void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router) -{ - u32 r_num = tipc_node(router); - - if (n_ptr->last_router < 0) - return; /* No routes */ - - n_ptr->routers[r_num / 32] = - ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32])); - n_ptr->last_router = tipc_max_nodes / 32; - while ((--n_ptr->last_router >= 0) && - !n_ptr->routers[n_ptr->last_router]); - - if (!tipc_node_is_up(n_ptr)) - node_lost_contact(n_ptr); -} - struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) { u32 domain; diff --git a/net/tipc/node.h b/net/tipc/node.h index 7bfaf5e8c201..3abaaa24c77d 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -54,8 +54,6 @@ * @cleanup_required: non-zero if cleaning up after a prior loss of contact * @link_cnt: number of links to node * @permit_changeover: non-zero if node has redundant links to this system - * @routers: bitmap (used for multicluster communication) - * @last_router: (used for multicluster communication) * @bclink: broadcast-related info * @supported: non-zero if node supports TIPC b'cast capability * @acked: sequence # of last outbound b'cast message acknowledged by node @@ -80,8 +78,6 @@ struct tipc_node { int working_links; int cleanup_required; int permit_changeover; - u32 routers[512/32]; - int last_router; struct { int supported; u32 acked; @@ -105,11 +101,7 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr); void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); int tipc_node_has_active_links(struct tipc_node *n_ptr); int tipc_node_has_redundant_links(struct tipc_node *n_ptr); -u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref); -struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector); int tipc_node_is_up(struct tipc_node *n_ptr); -void tipc_node_add_router(struct tipc_node *n_ptr, u32 router); -void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router); struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); @@ -117,22 +109,9 @@ static inline struct tipc_node *tipc_node_find(u32 addr) { if (likely(in_own_cluster(addr))) return tipc_local_nodes[tipc_node(addr)]; - else if (tipc_addr_domain_valid(addr)) { - struct cluster *c_ptr = tipc_cltr_find(addr); - - if (c_ptr) - return c_ptr->nodes[tipc_node(addr)]; - } return NULL; } -static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector) -{ - if (likely(in_own_cluster(addr))) - return tipc_local_nodes[tipc_node(addr)]; - return tipc_node_select_next_hop(addr, selector); -} - static inline void tipc_node_lock(struct tipc_node *n_ptr) { spin_lock_bh(&n_ptr->lock); -- cgit v1.2.3-59-g8ed1b From 8f92df6ad49da958d97e171762d0a97a3dc738f1 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:19 +0000 Subject: tipc: Remove prototype code for supporting multiple clusters Eliminates routines, data structures, and files that were intended to allow TIPC to support a network containing multiple clusters. Currently, TIPC supports only networks consisting of a single cluster within a single zone, so this code is unnecessary. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/linux/tipc_config.h | 4 +- net/tipc/Kconfig | 10 ---- net/tipc/Makefile | 2 +- net/tipc/addr.c | 5 +- net/tipc/bcast.c | 9 ++- net/tipc/bcast.h | 1 + net/tipc/cluster.c | 135 -------------------------------------------- net/tipc/cluster.h | 73 ------------------------ net/tipc/config.c | 21 +------ net/tipc/core.c | 6 -- net/tipc/core.h | 1 - net/tipc/name_distr.c | 28 +++++++-- net/tipc/net.c | 25 ++++++-- net/tipc/net.h | 8 ++- net/tipc/node.c | 37 ++++++------ net/tipc/node.h | 7 +-- 16 files changed, 83 insertions(+), 289 deletions(-) delete mode 100644 net/tipc/cluster.c delete mode 100644 net/tipc/cluster.h diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h index 1f38df1202ba..677aa13dc5d7 100644 --- a/include/linux/tipc_config.h +++ b/include/linux/tipc_config.h @@ -95,7 +95,7 @@ #define TIPC_CMD_GET_MAX_PUBL 0x4005 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_SUBSCR 0x4006 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_ZONES 0x4007 /* obsoleted */ -#define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* tx none, rx unsigned */ +#define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* obsoleted */ #define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */ #define TIPC_CMD_GET_MAX_SLAVES 0x400A /* obsoleted */ #define TIPC_CMD_GET_NETID 0x400B /* tx none, rx unsigned */ @@ -131,7 +131,7 @@ #define TIPC_CMD_SET_MAX_PUBL 0x8005 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_SUBSCR 0x8006 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_ZONES 0x8007 /* obsoleted */ -#define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* tx unsigned, rx none */ +#define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* obsoleted */ #define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */ #define TIPC_CMD_SET_MAX_SLAVES 0x800A /* obsoleted */ #define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */ diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index 06d32908fcfb..c02d3e9c156d 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -29,16 +29,6 @@ config TIPC_ADVANCED Saying Y here will open some advanced configuration for TIPC. Most users do not need to bother; if unsure, just say N. -config TIPC_CLUSTERS - int "Maximum number of clusters in a zone" - depends on TIPC_ADVANCED - range 1 1 - default "1" - help - Specifies how many clusters can be supported in a TIPC zone. - - *** Currently TIPC only supports a single cluster per zone. *** - config TIPC_NODES int "Maximum number of nodes in a cluster" depends on TIPC_ADVANCED diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 3d936f0560c7..849d819bfc74 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_TIPC) := tipc.o -tipc-y += addr.o bcast.o bearer.o config.o cluster.o \ +tipc-y += addr.o bcast.o bearer.o config.o \ core.o handler.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ netlink.o node.o node_subscr.o port.o ref.o \ diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 8823e03e52e0..483868a75b88 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -35,7 +35,8 @@ */ #include "core.h" -#include "cluster.h" +#include "node.h" +#include "addr.h" /** * tipc_addr_domain_valid - validates a network domain address @@ -55,8 +56,6 @@ int tipc_addr_domain_valid(u32 addr) if (n > max_nodes) return 0; - if (c > tipc_max_clusters) - return 0; if (n && (!z || !c)) return 0; diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 6d828d9eda42..110829eab96a 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -111,6 +111,9 @@ static struct bclink *bclink = NULL; static struct link *bcl = NULL; static DEFINE_SPINLOCK(bc_lock); +/* broadcast-capable node map */ +struct tipc_node_map tipc_bcast_nmap; + const char tipc_bclink_name[] = "broadcast-link"; static void tipc_nmap_diff(struct tipc_node_map *nm_a, @@ -566,8 +569,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, if (likely(!msg_non_seq(buf_msg(buf)))) { struct tipc_msg *msg; - assert(tipc_cltr_bcast_nodes.count != 0); - bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); + assert(tipc_bcast_nmap.count != 0); + bcbuf_set_acks(buf, tipc_bcast_nmap.count); msg = buf_msg(buf); msg_set_non_seq(msg, 1); msg_set_mc_netid(msg, tipc_net_id); @@ -576,7 +579,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, /* Send buffer over bearers until all targets reached */ - bcbearer->remains = tipc_cltr_bcast_nodes; + bcbearer->remains = tipc_bcast_nmap; for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { struct bearer *p = bcbearer->bpairs[bp_index].primary; diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index 011c03f0a4ab..51f8c5326ce6 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -51,6 +51,7 @@ struct tipc_node_map { u32 map[MAX_NODES / WSIZE]; }; +extern struct tipc_node_map tipc_bcast_nmap; #define PLSIZE 32 diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c deleted file mode 100644 index ba6f5bfa0cdb..000000000000 --- a/net/tipc/cluster.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * net/tipc/cluster.c: TIPC cluster management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "cluster.h" -#include "link.h" - -struct tipc_node **tipc_local_nodes = NULL; -struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}}; - -struct cluster *tipc_cltr_create(u32 addr) -{ - struct cluster *c_ptr; - int max_nodes; - - c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC); - if (c_ptr == NULL) { - warn("Cluster creation failure, no memory\n"); - return NULL; - } - - c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); - max_nodes = tipc_max_nodes + 1; - - c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC); - if (c_ptr->nodes == NULL) { - warn("Cluster creation failure, no memory for node area\n"); - kfree(c_ptr); - return NULL; - } - - tipc_local_nodes = c_ptr->nodes; - c_ptr->highest_node = 0; - - tipc_net.clusters[1] = c_ptr; - return c_ptr; -} - -void tipc_cltr_delete(struct cluster *c_ptr) -{ - u32 n_num; - - if (!c_ptr) - return; - for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { - tipc_node_delete(c_ptr->nodes[n_num]); - } - kfree(c_ptr->nodes); - kfree(c_ptr); -} - - -void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr) -{ - u32 n_num = tipc_node(n_ptr->addr); - u32 max_n_num = tipc_max_nodes; - - assert(n_num > 0); - assert(n_num <= max_n_num); - assert(c_ptr->nodes[n_num] == NULL); - c_ptr->nodes[n_num] = n_ptr; - if (n_num > c_ptr->highest_node) - c_ptr->highest_node = n_num; -} - -/** - * tipc_cltr_broadcast - broadcast message to all nodes within cluster - */ - -void tipc_cltr_broadcast(struct sk_buff *buf) -{ - struct sk_buff *buf_copy; - struct cluster *c_ptr; - struct tipc_node *n_ptr; - u32 n_num; - - if (tipc_mode == TIPC_NET_MODE) { - c_ptr = tipc_cltr_find(tipc_own_addr); - - /* Send to nodes */ - for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) { - buf_copy = skb_copy(buf, GFP_ATOMIC); - if (buf_copy == NULL) - goto exit; - msg_set_destnode(buf_msg(buf_copy), - n_ptr->addr); - tipc_link_send(buf_copy, n_ptr->addr, - n_ptr->addr); - } - } - } -exit: - buf_discard(buf); -} - -int tipc_cltr_init(void) -{ - return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM; -} - diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h deleted file mode 100644 index e4b6e4e27371..000000000000 --- a/net/tipc/cluster.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * net/tipc/cluster.h: Include file for TIPC cluster management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_CLUSTER_H -#define _TIPC_CLUSTER_H - -#include "addr.h" -#include "net.h" - -/** - * struct cluster - TIPC cluster structure - * @addr: network address of cluster - * @nodes: array of pointers to all nodes within cluster - * @highest_node: id of highest numbered node within cluster - */ - -struct cluster { - u32 addr; - struct tipc_node **nodes; - u32 highest_node; -}; - - -extern struct tipc_node **tipc_local_nodes; -extern struct tipc_node_map tipc_cltr_bcast_nodes; - -struct cluster *tipc_cltr_create(u32 addr); -void tipc_cltr_delete(struct cluster *c_ptr); -void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); -void tipc_cltr_broadcast(struct sk_buff *buf); -int tipc_cltr_init(void); - -static inline struct cluster *tipc_cltr_find(u32 addr) -{ - if (!in_own_cluster(addr)) - return NULL; - return tipc_net.clusters[1]; -} - -#endif diff --git a/net/tipc/config.c b/net/tipc/config.c index 05dc102300ae..bc512102eebd 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -269,19 +269,6 @@ static struct sk_buff *cfg_set_max_ports(void) return tipc_cfg_reply_none(); } -static struct sk_buff *cfg_set_max_clusters(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (value != delimit(value, 1, 1)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max clusters fixed at 1)"); - return tipc_cfg_reply_none(); -} - static struct sk_buff *cfg_set_max_nodes(void) { u32 value; @@ -420,9 +407,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SET_MAX_SUBSCR: rep_tlv_buf = cfg_set_max_subscriptions(); break; - case TIPC_CMD_SET_MAX_CLUSTERS: - rep_tlv_buf = cfg_set_max_clusters(); - break; case TIPC_CMD_SET_MAX_NODES: rep_tlv_buf = cfg_set_max_nodes(); break; @@ -441,9 +425,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_GET_MAX_SUBSCR: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); break; - case TIPC_CMD_GET_MAX_CLUSTERS: - rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters); - break; case TIPC_CMD_GET_MAX_NODES: rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes); break; @@ -458,6 +439,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_GET_MAX_ZONES: case TIPC_CMD_SET_MAX_SLAVES: case TIPC_CMD_GET_MAX_SLAVES: + case TIPC_CMD_SET_MAX_CLUSTERS: + case TIPC_CMD_GET_MAX_CLUSTERS: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (obsolete command)"); break; diff --git a/net/tipc/core.c b/net/tipc/core.c index 8b7af893971e..b9a3ef13f7e7 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -48,10 +48,6 @@ #include "config.h" -#ifndef CONFIG_TIPC_CLUSTERS -#define CONFIG_TIPC_CLUSTERS 1 -#endif - #ifndef CONFIG_TIPC_NODES #define CONFIG_TIPC_NODES 255 #endif @@ -76,7 +72,6 @@ const char tipc_alphabet[] = /* configurable TIPC parameters */ u32 tipc_own_addr; -int tipc_max_clusters; int tipc_max_nodes; int tipc_max_ports; int tipc_max_subscriptions; @@ -199,7 +194,6 @@ static int __init tipc_init(void) tipc_max_publications = 10000; tipc_max_subscriptions = 2000; tipc_max_ports = CONFIG_TIPC_PORTS; - tipc_max_clusters = CONFIG_TIPC_CLUSTERS; tipc_max_nodes = CONFIG_TIPC_NODES; tipc_net_id = 4711; diff --git a/net/tipc/core.h b/net/tipc/core.h index 8313a1689565..c44f955bd54a 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -184,7 +184,6 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); */ extern u32 tipc_own_addr; -extern int tipc_max_clusters; extern int tipc_max_nodes; extern int tipc_max_ports; extern int tipc_max_subscriptions; diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 10ff48be3c01..c4583fe888d8 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -35,7 +35,7 @@ */ #include "core.h" -#include "cluster.h" +#include "addr.h" #include "link.h" #include "name_distr.h" @@ -107,6 +107,26 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) return buf; } +static void named_cluster_distribute(struct sk_buff *buf) +{ + struct sk_buff *buf_copy; + struct tipc_node *n_ptr; + u32 n_num; + + for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { + n_ptr = tipc_net.nodes[n_num]; + if (n_ptr && tipc_node_has_active_links(n_ptr)) { + buf_copy = skb_copy(buf, GFP_ATOMIC); + if (!buf_copy) + break; + msg_set_destnode(buf_msg(buf_copy), n_ptr->addr); + tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr); + } + } + + buf_discard(buf); +} + /** * tipc_named_publish - tell other nodes about a new publication by this node */ @@ -127,8 +147,8 @@ void tipc_named_publish(struct publication *publ) item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); - dbg("tipc_named_withdraw: broadcasting publish msg\n"); - tipc_cltr_broadcast(buf); + dbg("tipc_named_publish: broadcasting publish msg\n"); + named_cluster_distribute(buf); } /** @@ -152,7 +172,7 @@ void tipc_named_withdraw(struct publication *publ) item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); dbg("tipc_named_withdraw: broadcasting withdraw msg\n"); - tipc_cltr_broadcast(buf); + named_cluster_distribute(buf); } /** diff --git a/net/tipc/net.c b/net/tipc/net.c index 3967f1f6d97f..3baf55ee0985 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -112,12 +112,23 @@ DEFINE_RWLOCK(tipc_net_lock); struct network tipc_net; +static int net_start(void) +{ + tipc_net.nodes = kcalloc(tipc_max_nodes + 1, + sizeof(*tipc_net.nodes), GFP_ATOMIC); + tipc_net.highest_node = 0; + + return tipc_net.nodes ? 0 : -ENOMEM; +} + static void net_stop(void) { - u32 c_num; + u32 n_num; - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) - tipc_cltr_delete(tipc_net.clusters[c_num]); + for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) + tipc_node_delete(tipc_net.nodes[n_num]); + kfree(tipc_net.nodes); + tipc_net.nodes = NULL; } static void net_route_named_msg(struct sk_buff *buf) @@ -218,10 +229,12 @@ int tipc_net_start(u32 addr) tipc_named_reinit(); tipc_port_reinit(); - if ((res = tipc_cltr_init()) || - (res = tipc_bclink_init())) { + res = net_start(); + if (res) + return res; + res = tipc_bclink_init(); + if (res) return res; - } tipc_k_signal((Handler)tipc_subscr_start, 0); tipc_k_signal((Handler)tipc_cfg_init, 0); diff --git a/net/tipc/net.h b/net/tipc/net.h index 6e402d9b33e0..4ae59ad04893 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h @@ -37,16 +37,18 @@ #ifndef _TIPC_NET_H #define _TIPC_NET_H -struct cluster; +struct tipc_node; /** * struct network - TIPC network structure - * @clusters: array of pointers to all clusters within zone + * @nodes: array of pointers to all nodes within cluster + * @highest_node: id of highest numbered node within cluster * @links: number of (unicast) links to cluster */ struct network { - struct cluster *clusters[2]; /* currently limited to just 1 cluster */ + struct tipc_node **nodes; + u32 highest_node; u32 links; }; diff --git a/net/tipc/node.c b/net/tipc/node.c index c47cc69eb575..58e189bf5c96 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -62,9 +62,9 @@ u32 tipc_own_tag = 0; struct tipc_node *tipc_node_create(u32 addr) { - struct cluster *c_ptr; struct tipc_node *n_ptr; struct tipc_node **curr_node; + u32 n_num; spin_lock_bh(&node_create_lock); @@ -84,21 +84,14 @@ struct tipc_node *tipc_node_create(u32 addr) return NULL; } - c_ptr = tipc_cltr_find(addr); - if (!c_ptr) { - c_ptr = tipc_cltr_create(addr); - } - if (!c_ptr) { - spin_unlock_bh(&node_create_lock); - kfree(n_ptr); - return NULL; - } - n_ptr->addr = addr; spin_lock_init(&n_ptr->lock); INIT_LIST_HEAD(&n_ptr->nsub); - n_ptr->owner = c_ptr; - tipc_cltr_attach_node(c_ptr, n_ptr); + + n_num = tipc_node(addr); + tipc_net.nodes[n_num] = n_ptr; + if (n_num > tipc_net.highest_node) + tipc_net.highest_node = n_num; /* Insert node into ordered list */ for (curr_node = &tipc_nodes; *curr_node; @@ -115,11 +108,19 @@ struct tipc_node *tipc_node_create(u32 addr) void tipc_node_delete(struct tipc_node *n_ptr) { + u32 n_num; + if (!n_ptr) return; dbg("node %x deleted\n", n_ptr->addr); + n_num = tipc_node(n_ptr->addr); + tipc_net.nodes[n_num] = NULL; kfree(n_ptr); + + while (!tipc_net.nodes[tipc_net.highest_node]) + if (--tipc_net.highest_node == 0) + break; } @@ -324,7 +325,7 @@ static void node_established_contact(struct tipc_node *n_ptr) n_ptr->bclink.acked = tipc_bclink_get_last_sent(); if (n_ptr->bclink.supported) { - tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); + tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr); if (n_ptr->addr < tipc_own_addr) tipc_own_tag++; } @@ -361,13 +362,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) buf_discard(n_ptr->bclink.defragm); n_ptr->bclink.defragm = NULL; } - if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) { - tipc_bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000)); - } - /* Update routing tables */ if (n_ptr->bclink.supported) { - tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr); + tipc_bclink_acknowledge(n_ptr, + mod(n_ptr->bclink.acked + 10000)); + tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr); if (n_ptr->addr < tipc_own_addr) tipc_own_tag--; } diff --git a/net/tipc/node.h b/net/tipc/node.h index 3abaaa24c77d..206a8efa410e 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -38,14 +38,14 @@ #define _TIPC_NODE_H #include "node_subscr.h" -#include "cluster.h" +#include "addr.h" +#include "net.h" #include "bearer.h" /** * struct tipc_node - TIPC node structure * @addr: network address of node * @lock: spinlock governing access to structure - * @owner: pointer to cluster that node belongs to * @next: pointer to next node in sorted list of cluster's nodes * @nsub: list of "node down" subscriptions monitoring node * @active_links: pointers to active links to node @@ -69,7 +69,6 @@ struct tipc_node { u32 addr; spinlock_t lock; - struct cluster *owner; struct tipc_node *next; struct list_head nsub; struct link *active_links[2]; @@ -108,7 +107,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) static inline struct tipc_node *tipc_node_find(u32 addr) { if (likely(in_own_cluster(addr))) - return tipc_local_nodes[tipc_node(addr)]; + return tipc_net.nodes[tipc_node(addr)]; return NULL; } -- cgit v1.2.3-59-g8ed1b From 7a488fd3d40a127d0d6057ecd2696f39e11e63c3 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:20 +0000 Subject: tipc: Eliminate use of user registry by configuration service Simplifies TIPC's configuration service so that it no longer registers its port with the user registry, since the service doesn't take advantage of any of the registry's capabilities. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/config.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index bc512102eebd..322367b2618f 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -38,15 +38,9 @@ #include "port.h" #include "link.h" #include "name_table.h" -#include "user_reg.h" #include "config.h" -struct manager { - u32 user_ref; - u32 port_ref; -}; - -static struct manager mng = { 0}; +static u32 config_port_ref; static DEFINE_SPINLOCK(config_lock); @@ -506,20 +500,16 @@ int tipc_cfg_init(void) struct tipc_name_seq seq; int res; - res = tipc_attach(&mng.user_ref); - if (res) - goto failed; - - res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE, + res = tipc_createport(0, NULL, TIPC_CRITICAL_IMPORTANCE, NULL, NULL, NULL, NULL, cfg_named_msg_event, NULL, - NULL, &mng.port_ref); + NULL, &config_port_ref); if (res) goto failed; seq.type = TIPC_CFG_SRV; seq.lower = seq.upper = tipc_own_addr; - res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq); + res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq); if (res) goto failed; @@ -527,15 +517,13 @@ int tipc_cfg_init(void) failed: err("Unable to create configuration service\n"); - tipc_detach(mng.user_ref); - mng.user_ref = 0; return res; } void tipc_cfg_stop(void) { - if (mng.user_ref) { - tipc_detach(mng.user_ref); - mng.user_ref = 0; + if (config_port_ref) { + tipc_deleteport(config_port_ref); + config_port_ref = 0; } } -- cgit v1.2.3-59-g8ed1b From aa70200e001fc4d76552c974c94f65ab26020203 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:21 +0000 Subject: tipc: Eliminate use of user registry by topology service Simplifies TIPC's network topology service so that it no longer registers its ports with the user registry, since the service doesn't take advantage of any of the registry's capabilities. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/subscr.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 23f43d03980c..21abf1765b02 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -36,7 +36,7 @@ #include "core.h" #include "name_table.h" -#include "user_reg.h" +#include "port.h" #include "subscr.h" /** @@ -64,7 +64,6 @@ struct subscriber { */ struct top_srv { - u32 user_ref; u32 setup_port; atomic_t subscription_count; struct list_head subscriber_list; @@ -494,7 +493,7 @@ static void subscr_named_msg_event(void *usr_handle, /* Create server port & establish connection to subscriber */ - tipc_createport(topsrv.user_ref, + tipc_createport(0, subscriber, importance, NULL, @@ -549,13 +548,7 @@ int tipc_subscr_start(void) INIT_LIST_HEAD(&topsrv.subscriber_list); spin_lock_bh(&topsrv.lock); - res = tipc_attach(&topsrv.user_ref); - if (res) { - spin_unlock_bh(&topsrv.lock); - return res; - } - - res = tipc_createport(topsrv.user_ref, + res = tipc_createport(0, NULL, TIPC_CRITICAL_IMPORTANCE, NULL, @@ -570,16 +563,17 @@ int tipc_subscr_start(void) goto failed; res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); - if (res) + if (res) { + tipc_deleteport(topsrv.setup_port); + topsrv.setup_port = 0; goto failed; + } spin_unlock_bh(&topsrv.lock); return 0; failed: err("Failed to create subscription service\n"); - tipc_detach(topsrv.user_ref); - topsrv.user_ref = 0; spin_unlock_bh(&topsrv.lock); return res; } @@ -590,8 +584,10 @@ void tipc_subscr_stop(void) struct subscriber *subscriber_temp; spinlock_t *subscriber_lock; - if (topsrv.user_ref) { + if (topsrv.setup_port) { tipc_deleteport(topsrv.setup_port); + topsrv.setup_port = 0; + list_for_each_entry_safe(subscriber, subscriber_temp, &topsrv.subscriber_list, subscriber_list) { @@ -600,7 +596,5 @@ void tipc_subscr_stop(void) subscr_terminate(subscriber); spin_unlock_bh(subscriber_lock); } - tipc_detach(topsrv.user_ref); - topsrv.user_ref = 0; } } -- cgit v1.2.3-59-g8ed1b From b0c1e928c85023c73780b5d9873406ccf1cd8019 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:22 +0000 Subject: tipc: Remove user registry subsystem Eliminates routines, data structures, and files that make up TIPC's user registry. The user registry is no longer needed since the native API routines that utilized it no longer exist and there are no longer any internal TIPC services that use it. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/Makefile | 2 +- net/tipc/config.c | 2 +- net/tipc/core.c | 3 - net/tipc/port.c | 11 +-- net/tipc/port.h | 6 +- net/tipc/subscr.c | 6 +- net/tipc/user_reg.c | 218 ---------------------------------------------------- net/tipc/user_reg.h | 51 ------------ 8 files changed, 7 insertions(+), 292 deletions(-) delete mode 100644 net/tipc/user_reg.c delete mode 100644 net/tipc/user_reg.h diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 849d819bfc74..d41cd110fe7d 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -8,6 +8,6 @@ tipc-y += addr.o bcast.o bearer.o config.o \ core.o handler.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ netlink.o node.o node_subscr.o port.o ref.o \ - socket.o user_reg.o dbg.o eth_media.o + socket.o dbg.o eth_media.o # End of file diff --git a/net/tipc/config.c b/net/tipc/config.c index 322367b2618f..afa6e853c04b 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -500,7 +500,7 @@ int tipc_cfg_init(void) struct tipc_name_seq seq; int res; - res = tipc_createport(0, NULL, TIPC_CRITICAL_IMPORTANCE, + res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE, NULL, NULL, NULL, NULL, cfg_named_msg_event, NULL, NULL, &config_port_ref); diff --git a/net/tipc/core.c b/net/tipc/core.c index b9a3ef13f7e7..a02bc490caae 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -42,7 +42,6 @@ #include "core.h" #include "ref.h" #include "net.h" -#include "user_reg.h" #include "name_table.h" #include "subscr.h" #include "config.h" @@ -144,7 +143,6 @@ static void tipc_core_stop(void) tipc_handler_stop(); tipc_cfg_stop(); tipc_subscr_stop(); - tipc_reg_stop(); tipc_nametbl_stop(); tipc_ref_table_stop(); tipc_socket_stop(); @@ -167,7 +165,6 @@ static int tipc_core_start(void) if ((res = tipc_handler_start()) || (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || - (res = tipc_reg_start()) || (res = tipc_nametbl_init()) || (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || diff --git a/net/tipc/port.c b/net/tipc/port.c index c033cb87b964..33d0b3b7175f 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -38,7 +38,6 @@ #include "config.h" #include "port.h" #include "name_table.h" -#include "user_reg.h" /* Connection management: */ #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ @@ -272,7 +271,6 @@ int tipc_deleteport(u32 ref) tipc_nodesub_unsubscribe(&p_ptr->subscription); } if (p_ptr->user_port) { - tipc_reg_remove_port(p_ptr->user_port); kfree(p_ptr->user_port); } @@ -934,12 +932,10 @@ void tipc_acknowledge(u32 ref, u32 ack) } /* - * tipc_createport(): user level call. Will add port to - * registry if non-zero user_ref. + * tipc_createport(): user level call. */ -int tipc_createport(u32 user_ref, - void *usr_handle, +int tipc_createport(void *usr_handle, unsigned int importance, tipc_msg_err_event error_cb, tipc_named_msg_err_event named_error_cb, @@ -966,7 +962,6 @@ int tipc_createport(u32 user_ref, } p_ptr->user_port = up_ptr; - up_ptr->user_ref = user_ref; up_ptr->usr_handle = usr_handle; up_ptr->ref = p_ptr->publ.ref; up_ptr->err_cb = error_cb; @@ -976,8 +971,6 @@ int tipc_createport(u32 user_ref, up_ptr->named_msg_cb = named_msg_cb; up_ptr->conn_msg_cb = conn_msg_cb; up_ptr->continue_event_cb = continue_event_cb; - INIT_LIST_HEAD(&up_ptr->uport_list); - tipc_reg_add_port(up_ptr); *portref = p_ptr->publ.ref; tipc_port_unlock(p_ptr); return 0; diff --git a/net/tipc/port.h b/net/tipc/port.h index 3a807fcec2be..da607a8a2f35 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -77,15 +77,12 @@ typedef void (*tipc_continue_event) (void *usr_handle, u32 portref); /** * struct user_port - TIPC user port (used with native API) - * @user_ref: id of user who created user port * @usr_handle: user-specified field * @ref: object reference to associated TIPC port * - * @uport_list: adjacent user ports in list of ports held by user */ struct user_port { - u32 user_ref; void *usr_handle; u32 ref; tipc_msg_err_event err_cb; @@ -95,7 +92,6 @@ struct user_port { tipc_named_msg_event named_msg_cb; tipc_conn_msg_event conn_msg_cb; tipc_continue_event continue_event_cb; - struct list_head uport_list; }; /** @@ -181,7 +177,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode); void tipc_acknowledge(u32 port_ref, u32 ack); -int tipc_createport(unsigned int tipc_user, void *usr_handle, +int tipc_createport(void *usr_handle, unsigned int importance, tipc_msg_err_event error_cb, tipc_named_msg_err_event named_error_cb, tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb, diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 21abf1765b02..c5ba323dba47 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -493,8 +493,7 @@ static void subscr_named_msg_event(void *usr_handle, /* Create server port & establish connection to subscriber */ - tipc_createport(0, - subscriber, + tipc_createport(subscriber, importance, NULL, NULL, @@ -548,8 +547,7 @@ int tipc_subscr_start(void) INIT_LIST_HEAD(&topsrv.subscriber_list); spin_lock_bh(&topsrv.lock); - res = tipc_createport(0, - NULL, + res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE, NULL, NULL, diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c deleted file mode 100644 index 2e2702e2049c..000000000000 --- a/net/tipc/user_reg.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * net/tipc/user_reg.c: TIPC user registry code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "user_reg.h" - -/* - * TIPC user registry keeps track of users of the tipc_port interface. - * - * The registry utilizes an array of "TIPC user" entries; - * a user's ID is the index of their associated array entry. - * Array entry 0 is not used, so userid 0 is not valid; - * TIPC sometimes uses this value to denote an anonymous user. - * The list of free entries is initially chained from last entry to entry 1. - */ - -/** - * struct tipc_user - registered TIPC user info - * @next: index of next free registry entry (or -1 for an allocated entry) - * @ports: list of user ports owned by the user - */ - -struct tipc_user { - int next; - struct list_head ports; -}; - -#define MAX_USERID 64 -#define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user)) - -static struct tipc_user *users = NULL; -static u32 next_free_user = MAX_USERID + 1; -static DEFINE_SPINLOCK(reg_lock); - -/** - * reg_init - create TIPC user registry (but don't activate it) - * - * If registry has been pre-initialized it is left "as is". - * NOTE: This routine may be called when TIPC is inactive. - */ - -static int reg_init(void) -{ - u32 i; - - spin_lock_bh(®_lock); - if (!users) { - users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC); - if (users) { - for (i = 1; i <= MAX_USERID; i++) { - users[i].next = i - 1; - } - next_free_user = MAX_USERID; - } - } - spin_unlock_bh(®_lock); - return users ? 0 : -ENOMEM; -} - -/** - * tipc_reg_start - activate TIPC user registry - */ - -int tipc_reg_start(void) -{ - return reg_init(); -} - -/** - * tipc_reg_stop - shut down & delete TIPC user registry - */ - -void tipc_reg_stop(void) -{ - if (!users) - return; - - kfree(users); - users = NULL; -} - -/** - * tipc_attach - register a TIPC user - * - * NOTE: This routine may be called when TIPC is inactive. - */ - -int tipc_attach(u32 *userid) -{ - struct tipc_user *user_ptr; - - if (!users) - reg_init(); - - spin_lock_bh(®_lock); - if (!next_free_user) { - spin_unlock_bh(®_lock); - return -EBUSY; - } - user_ptr = &users[next_free_user]; - *userid = next_free_user; - next_free_user = user_ptr->next; - user_ptr->next = -1; - spin_unlock_bh(®_lock); - - INIT_LIST_HEAD(&user_ptr->ports); - atomic_inc(&tipc_user_count); - - return 0; -} - -/** - * tipc_detach - deregister a TIPC user - */ - -void tipc_detach(u32 userid) -{ - struct tipc_user *user_ptr; - struct list_head ports_temp; - struct user_port *up_ptr, *temp_up_ptr; - - if ((userid == 0) || (userid > MAX_USERID)) - return; - - spin_lock_bh(®_lock); - if ((!users) || (users[userid].next >= 0)) { - spin_unlock_bh(®_lock); - return; - } - - user_ptr = &users[userid]; - INIT_LIST_HEAD(&ports_temp); - list_splice(&user_ptr->ports, &ports_temp); - user_ptr->next = next_free_user; - next_free_user = userid; - spin_unlock_bh(®_lock); - - atomic_dec(&tipc_user_count); - - list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) { - tipc_deleteport(up_ptr->ref); - } -} - -/** - * tipc_reg_add_port - register a user's driver port - */ - -int tipc_reg_add_port(struct user_port *up_ptr) -{ - struct tipc_user *user_ptr; - - if (up_ptr->user_ref == 0) - return 0; - if (up_ptr->user_ref > MAX_USERID) - return -EINVAL; - if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) - return -ENOPROTOOPT; - - spin_lock_bh(®_lock); - user_ptr = &users[up_ptr->user_ref]; - list_add(&up_ptr->uport_list, &user_ptr->ports); - spin_unlock_bh(®_lock); - return 0; -} - -/** - * tipc_reg_remove_port - deregister a user's driver port - */ - -int tipc_reg_remove_port(struct user_port *up_ptr) -{ - if (up_ptr->user_ref == 0) - return 0; - if (up_ptr->user_ref > MAX_USERID) - return -EINVAL; - if (!users ) - return -ENOPROTOOPT; - - spin_lock_bh(®_lock); - list_del_init(&up_ptr->uport_list); - spin_unlock_bh(®_lock); - return 0; -} - diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h deleted file mode 100644 index 109eed0d6de3..000000000000 --- a/net/tipc/user_reg.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * net/tipc/user_reg.h: Include file for TIPC user registry code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_USER_REG_H -#define _TIPC_USER_REG_H - -#include "port.h" - -int tipc_reg_start(void); -void tipc_reg_stop(void); - -int tipc_attach(unsigned int *userref); -void tipc_detach(unsigned int userref); - -int tipc_reg_add_port(struct user_port *up_ptr); -int tipc_reg_remove_port(struct user_port *up_ptr); - -#endif -- cgit v1.2.3-59-g8ed1b From 5af5479296fba0ace5d5cab84045de5b19bde3fe Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:23 +0000 Subject: tipc: Remove internal linked list of node objects Eliminates a sorted list TIPC uses to keep track of the neighboring nodes it has links to, since this duplicates information already present in the internal array of node object pointers. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/node.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/net/tipc/node.c b/net/tipc/node.c index 58e189bf5c96..31dcca98201a 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -43,9 +43,6 @@ static void node_lost_contact(struct tipc_node *n_ptr); static void node_established_contact(struct tipc_node *n_ptr); -/* sorted list of nodes within cluster */ -static struct tipc_node *tipc_nodes = NULL; - static DEFINE_SPINLOCK(node_create_lock); u32 tipc_own_tag = 0; @@ -63,21 +60,17 @@ u32 tipc_own_tag = 0; struct tipc_node *tipc_node_create(u32 addr) { struct tipc_node *n_ptr; - struct tipc_node **curr_node; u32 n_num; spin_lock_bh(&node_create_lock); - for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { - if (addr < n_ptr->addr) - break; - if (addr == n_ptr->addr) { - spin_unlock_bh(&node_create_lock); - return n_ptr; - } + n_ptr = tipc_node_find(addr); + if (n_ptr) { + spin_unlock_bh(&node_create_lock); + return n_ptr; } - n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); + n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC); if (!n_ptr) { spin_unlock_bh(&node_create_lock); warn("Node creation failed, no memory\n"); @@ -93,15 +86,6 @@ struct tipc_node *tipc_node_create(u32 addr) if (n_num > tipc_net.highest_node) tipc_net.highest_node = n_num; - /* Insert node into ordered list */ - for (curr_node = &tipc_nodes; *curr_node; - curr_node = &(*curr_node)->next) { - if (addr < (*curr_node)->addr) { - n_ptr->next = *curr_node; - break; - } - } - (*curr_node) = n_ptr; spin_unlock_bh(&node_create_lock); return n_ptr; } @@ -405,6 +389,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) struct tipc_node *n_ptr; struct tipc_node_info node_info; u32 payload_size; + u32 n_num; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); @@ -415,14 +400,15 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) " (network address)"); read_lock_bh(&tipc_net_lock); - if (!tipc_nodes) { + if (!tipc_net.nodes) { read_unlock_bh(&tipc_net_lock); return tipc_cfg_reply_none(); } /* For now, get space for all other nodes */ - payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); + payload_size = TLV_SPACE(sizeof(node_info)) * + (tipc_net.highest_node - 1); if (payload_size > 32768u) { read_unlock_bh(&tipc_net_lock); return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED @@ -436,8 +422,9 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) /* Add TLVs for all nodes in scope */ - for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { - if (!tipc_in_scope(domain, n_ptr->addr)) + for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { + n_ptr = tipc_net.nodes[n_num]; + if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) continue; node_info.addr = htonl(n_ptr->addr); node_info.up = htonl(tipc_node_is_up(n_ptr)); @@ -456,6 +443,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) struct tipc_node *n_ptr; struct tipc_link_info link_info; u32 payload_size; + u32 n_num; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); @@ -493,10 +481,11 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) /* Add TLVs for any other links in scope */ - for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { + for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { u32 i; - if (!tipc_in_scope(domain, n_ptr->addr)) + n_ptr = tipc_net.nodes[n_num]; + if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) continue; tipc_node_lock(n_ptr); for (i = 0; i < MAX_BEARERS; i++) { -- cgit v1.2.3-59-g8ed1b From f5e75269f59f7c3816f23314b924895e4ecf8409 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:24 +0000 Subject: tipc: rename dbg.[ch] to log.[ch] As the first step in removing obsolete debugging code from TIPC the files that implement TIPC's non-debug-related log buffer subsystem are renamed to better reflect their true nature. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/Makefile | 2 +- net/tipc/core.h | 2 +- net/tipc/dbg.c | 432 ------------------------------------------------------ net/tipc/dbg.h | 67 --------- net/tipc/link.h | 2 +- net/tipc/log.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++ net/tipc/log.h | 67 +++++++++ 7 files changed, 498 insertions(+), 502 deletions(-) delete mode 100644 net/tipc/dbg.c delete mode 100644 net/tipc/dbg.h create mode 100644 net/tipc/log.c create mode 100644 net/tipc/log.h diff --git a/net/tipc/Makefile b/net/tipc/Makefile index d41cd110fe7d..521d24d04ab2 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -8,6 +8,6 @@ tipc-y += addr.o bcast.o bearer.o config.o \ core.o handler.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ netlink.o node.o node_subscr.o port.o ref.o \ - socket.o dbg.o eth_media.o + socket.o log.o eth_media.o # End of file diff --git a/net/tipc/core.h b/net/tipc/core.h index c44f955bd54a..17f3670ed95d 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -59,7 +59,7 @@ #define TIPC_MOD_VER "2.0.0" struct tipc_msg; /* msg.h */ -struct print_buf; /* dbg.h */ +struct print_buf; /* log.h */ /* * TIPC sanity test macros diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c deleted file mode 100644 index 46f51d208e5e..000000000000 --- a/net/tipc/dbg.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * net/tipc/dbg.c: TIPC print buffer routines for debugging - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2005-2007, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "dbg.h" - -/* - * TIPC pre-defines the following print buffers: - * - * TIPC_NULL : null buffer (i.e. print nowhere) - * TIPC_CONS : system console - * TIPC_LOG : TIPC log buffer - * - * Additional user-defined print buffers are also permitted. - */ - -static struct print_buf null_buf = { NULL, 0, NULL, 0 }; -struct print_buf *const TIPC_NULL = &null_buf; - -static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; -static struct print_buf *const TIPC_CONS = &cons_buf; - -static struct print_buf log_buf = { NULL, 0, NULL, 1 }; -struct print_buf *const TIPC_LOG = &log_buf; - -/* - * Locking policy when using print buffers. - * - * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to - * 'print_string' when writing to a print buffer. This also protects against - * concurrent writes to the print buffer being written to. - * - * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned - * use of 'print_lock' to protect against all types of concurrent operations - * on their associated print buffer (not just write operations). - * - * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely - * on the caller to prevent simultaneous use of the print buffer(s) being - * manipulated. - */ - -static char print_string[TIPC_PB_MAX_STR]; -static DEFINE_SPINLOCK(print_lock); - -static void tipc_printbuf_reset(struct print_buf *pb); -static int tipc_printbuf_empty(struct print_buf *pb); -static void tipc_printbuf_move(struct print_buf *pb_to, - struct print_buf *pb_from); - -#define FORMAT(PTR,LEN,FMT) \ -{\ - va_list args;\ - va_start(args, FMT);\ - LEN = vsprintf(PTR, FMT, args);\ - va_end(args);\ - *(PTR + LEN) = '\0';\ -} - -/** - * tipc_printbuf_init - initialize print buffer to empty - * @pb: pointer to print buffer structure - * @raw: pointer to character array used by print buffer - * @size: size of character array - * - * Note: If the character array is too small (or absent), the print buffer - * becomes a null device that discards anything written to it. - */ - -void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) -{ - pb->buf = raw; - pb->crs = raw; - pb->size = size; - pb->echo = 0; - - if (size < TIPC_PB_MIN_SIZE) { - pb->buf = NULL; - } else if (raw) { - pb->buf[0] = 0; - pb->buf[size - 1] = ~0; - } -} - -/** - * tipc_printbuf_reset - reinitialize print buffer to empty state - * @pb: pointer to print buffer structure - */ - -static void tipc_printbuf_reset(struct print_buf *pb) -{ - if (pb->buf) { - pb->crs = pb->buf; - pb->buf[0] = 0; - pb->buf[pb->size - 1] = ~0; - } -} - -/** - * tipc_printbuf_empty - test if print buffer is in empty state - * @pb: pointer to print buffer structure - * - * Returns non-zero if print buffer is empty. - */ - -static int tipc_printbuf_empty(struct print_buf *pb) -{ - return !pb->buf || (pb->crs == pb->buf); -} - -/** - * tipc_printbuf_validate - check for print buffer overflow - * @pb: pointer to print buffer structure - * - * Verifies that a print buffer has captured all data written to it. - * If data has been lost, linearize buffer and prepend an error message - * - * Returns length of print buffer data string (including trailing NUL) - */ - -int tipc_printbuf_validate(struct print_buf *pb) -{ - char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; - char *cp_buf; - struct print_buf cb; - - if (!pb->buf) - return 0; - - if (pb->buf[pb->size - 1] == 0) { - cp_buf = kmalloc(pb->size, GFP_ATOMIC); - if (cp_buf) { - tipc_printbuf_init(&cb, cp_buf, pb->size); - tipc_printbuf_move(&cb, pb); - tipc_printbuf_move(pb, &cb); - kfree(cp_buf); - memcpy(pb->buf, err, strlen(err)); - } else { - tipc_printbuf_reset(pb); - tipc_printf(pb, err); - } - } - return pb->crs - pb->buf + 1; -} - -/** - * tipc_printbuf_move - move print buffer contents to another print buffer - * @pb_to: pointer to destination print buffer structure - * @pb_from: pointer to source print buffer structure - * - * Current contents of destination print buffer (if any) are discarded. - * Source print buffer becomes empty if a successful move occurs. - */ - -static void tipc_printbuf_move(struct print_buf *pb_to, - struct print_buf *pb_from) -{ - int len; - - /* Handle the cases where contents can't be moved */ - - if (!pb_to->buf) - return; - - if (!pb_from->buf) { - tipc_printbuf_reset(pb_to); - return; - } - - if (pb_to->size < pb_from->size) { - strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); - pb_to->buf[pb_to->size - 1] = ~0; - pb_to->crs = strchr(pb_to->buf, 0); - return; - } - - /* Copy data from char after cursor to end (if used) */ - - len = pb_from->buf + pb_from->size - pb_from->crs - 2; - if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) { - strcpy(pb_to->buf, pb_from->crs + 1); - pb_to->crs = pb_to->buf + len; - } else - pb_to->crs = pb_to->buf; - - /* Copy data from start to cursor (always) */ - - len = pb_from->crs - pb_from->buf; - strcpy(pb_to->crs, pb_from->buf); - pb_to->crs += len; - - tipc_printbuf_reset(pb_from); -} - -/** - * tipc_printf - append formatted output to print buffer - * @pb: pointer to print buffer - * @fmt: formatted info to be printed - */ - -void tipc_printf(struct print_buf *pb, const char *fmt, ...) -{ - int chars_to_add; - int chars_left; - char save_char; - - spin_lock_bh(&print_lock); - - FORMAT(print_string, chars_to_add, fmt); - if (chars_to_add >= TIPC_PB_MAX_STR) - strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); - - if (pb->buf) { - chars_left = pb->buf + pb->size - pb->crs - 1; - if (chars_to_add <= chars_left) { - strcpy(pb->crs, print_string); - pb->crs += chars_to_add; - } else if (chars_to_add >= (pb->size - 1)) { - strcpy(pb->buf, print_string + chars_to_add + 1 - - pb->size); - pb->crs = pb->buf + pb->size - 1; - } else { - strcpy(pb->buf, print_string + chars_left); - save_char = print_string[chars_left]; - print_string[chars_left] = 0; - strcpy(pb->crs, print_string); - print_string[chars_left] = save_char; - pb->crs = pb->buf + chars_to_add - chars_left; - } - } - - if (pb->echo) - printk("%s", print_string); - - spin_unlock_bh(&print_lock); -} - -#ifdef CONFIG_TIPC_DEBUG - -/** - * print_to_console - write string of bytes to console in multiple chunks - */ - -static void print_to_console(char *crs, int len) -{ - int rest = len; - - while (rest > 0) { - int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; - char c = crs[sz]; - - crs[sz] = 0; - printk((const char *)crs); - crs[sz] = c; - rest -= sz; - crs += sz; - } -} - -/** - * printbuf_dump - write print buffer contents to console - */ - -static void printbuf_dump(struct print_buf *pb) -{ - int len; - - if (!pb->buf) { - printk("*** PRINT BUFFER NOT ALLOCATED ***"); - return; - } - - /* Dump print buffer from char after cursor to end (if used) */ - - len = pb->buf + pb->size - pb->crs - 2; - if ((pb->buf[pb->size - 1] == 0) && (len > 0)) - print_to_console(pb->crs + 1, len); - - /* Dump print buffer from start to cursor (always) */ - - len = pb->crs - pb->buf; - print_to_console(pb->buf, len); -} - -/** - * tipc_dump_dbg - dump (non-console) print buffer to console - * @pb: pointer to print buffer - */ - -void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...) -{ - int len; - - if (pb == TIPC_CONS) - return; - - spin_lock_bh(&print_lock); - - FORMAT(print_string, len, fmt); - printk(print_string); - - printk("\n---- Start of %s log dump ----\n\n", - (pb == TIPC_LOG) ? "global" : "local"); - printbuf_dump(pb); - tipc_printbuf_reset(pb); - printk("\n---- End of dump ----\n"); - - spin_unlock_bh(&print_lock); -} - -#endif - -/** - * tipc_log_resize - change the size of the TIPC log buffer - * @log_size: print buffer size to use - */ - -int tipc_log_resize(int log_size) -{ - int res = 0; - - spin_lock_bh(&print_lock); - if (TIPC_LOG->buf) { - kfree(TIPC_LOG->buf); - TIPC_LOG->buf = NULL; - } - if (log_size) { - if (log_size < TIPC_PB_MIN_SIZE) - log_size = TIPC_PB_MIN_SIZE; - res = TIPC_LOG->echo; - tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), - log_size); - TIPC_LOG->echo = res; - res = !TIPC_LOG->buf; - } - spin_unlock_bh(&print_lock); - - return res; -} - -/** - * tipc_log_resize_cmd - reconfigure size of TIPC log buffer - */ - -struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (value != delimit(value, 0, 32768)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (log size must be 0-32768)"); - if (tipc_log_resize(value)) - return tipc_cfg_reply_error_string( - "unable to create specified log (log size is now 0)"); - return tipc_cfg_reply_none(); -} - -/** - * tipc_log_dump - capture TIPC log buffer contents in configuration message - */ - -struct sk_buff *tipc_log_dump(void) -{ - struct sk_buff *reply; - - spin_lock_bh(&print_lock); - if (!TIPC_LOG->buf) { - spin_unlock_bh(&print_lock); - reply = tipc_cfg_reply_ultra_string("log not activated\n"); - } else if (tipc_printbuf_empty(TIPC_LOG)) { - spin_unlock_bh(&print_lock); - reply = tipc_cfg_reply_ultra_string("log is empty\n"); - } - else { - struct tlv_desc *rep_tlv; - struct print_buf pb; - int str_len; - - str_len = min(TIPC_LOG->size, 32768u); - spin_unlock_bh(&print_lock); - reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); - if (reply) { - rep_tlv = (struct tlv_desc *)reply->data; - tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); - spin_lock_bh(&print_lock); - tipc_printbuf_move(&pb, TIPC_LOG); - spin_unlock_bh(&print_lock); - str_len = strlen(TLV_DATA(rep_tlv)) + 1; - skb_put(reply, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - } - } - return reply; -} - diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h deleted file mode 100644 index 3ba6ba8b434a..000000000000 --- a/net/tipc/dbg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * net/tipc/dbg.h: Include file for TIPC print buffer routines - * - * Copyright (c) 1997-2006, Ericsson AB - * Copyright (c) 2005-2007, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_DBG_H -#define _TIPC_DBG_H - -/** - * struct print_buf - TIPC print buffer structure - * @buf: pointer to character array containing print buffer contents - * @size: size of character array - * @crs: pointer to first unused space in character array (i.e. final NUL) - * @echo: echo output to system console if non-zero - */ - -struct print_buf { - char *buf; - u32 size; - char *crs; - int echo; -}; - -#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ -#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ - -void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); -int tipc_printbuf_validate(struct print_buf *pb); - -int tipc_log_resize(int log_size); - -struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, - int req_tlv_space); -struct sk_buff *tipc_log_dump(void); - -#endif diff --git a/net/tipc/link.h b/net/tipc/link.h index c562888d25da..eeb0c015dba9 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -37,7 +37,7 @@ #ifndef _TIPC_LINK_H #define _TIPC_LINK_H -#include "dbg.h" +#include "log.h" #include "msg.h" #include "node.h" diff --git a/net/tipc/log.c b/net/tipc/log.c new file mode 100644 index 000000000000..9d99f7097d2d --- /dev/null +++ b/net/tipc/log.c @@ -0,0 +1,428 @@ +/* + * net/tipc/log.c: TIPC print buffer routines for debugging + * + * Copyright (c) 1996-2006, Ericsson AB + * Copyright (c) 2005-2007, Wind River Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "core.h" +#include "config.h" +#include "log.h" + +/* + * TIPC pre-defines the following print buffers: + * + * TIPC_NULL : null buffer (i.e. print nowhere) + * TIPC_CONS : system console + * TIPC_LOG : TIPC log buffer + * + * Additional user-defined print buffers are also permitted. + */ + +static struct print_buf null_buf = { NULL, 0, NULL, 0 }; +struct print_buf *const TIPC_NULL = &null_buf; + +static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; +static struct print_buf *const TIPC_CONS = &cons_buf; + +static struct print_buf log_buf = { NULL, 0, NULL, 1 }; +struct print_buf *const TIPC_LOG = &log_buf; + +/* + * Locking policy when using print buffers. + * + * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to + * 'print_string' when writing to a print buffer. This also protects against + * concurrent writes to the print buffer being written to. + * + * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned + * use of 'print_lock' to protect against all types of concurrent operations + * on their associated print buffer (not just write operations). + * + * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely + * on the caller to prevent simultaneous use of the print buffer(s) being + * manipulated. + */ + +static char print_string[TIPC_PB_MAX_STR]; +static DEFINE_SPINLOCK(print_lock); + +static void tipc_printbuf_reset(struct print_buf *pb); +static int tipc_printbuf_empty(struct print_buf *pb); +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from); + +#define FORMAT(PTR, LEN, FMT) \ +{\ + va_list args;\ + va_start(args, FMT);\ + LEN = vsprintf(PTR, FMT, args);\ + va_end(args);\ + *(PTR + LEN) = '\0';\ +} + +/** + * tipc_printbuf_init - initialize print buffer to empty + * @pb: pointer to print buffer structure + * @raw: pointer to character array used by print buffer + * @size: size of character array + * + * Note: If the character array is too small (or absent), the print buffer + * becomes a null device that discards anything written to it. + */ + +void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) +{ + pb->buf = raw; + pb->crs = raw; + pb->size = size; + pb->echo = 0; + + if (size < TIPC_PB_MIN_SIZE) { + pb->buf = NULL; + } else if (raw) { + pb->buf[0] = 0; + pb->buf[size - 1] = ~0; + } +} + +/** + * tipc_printbuf_reset - reinitialize print buffer to empty state + * @pb: pointer to print buffer structure + */ + +static void tipc_printbuf_reset(struct print_buf *pb) +{ + if (pb->buf) { + pb->crs = pb->buf; + pb->buf[0] = 0; + pb->buf[pb->size - 1] = ~0; + } +} + +/** + * tipc_printbuf_empty - test if print buffer is in empty state + * @pb: pointer to print buffer structure + * + * Returns non-zero if print buffer is empty. + */ + +static int tipc_printbuf_empty(struct print_buf *pb) +{ + return !pb->buf || (pb->crs == pb->buf); +} + +/** + * tipc_printbuf_validate - check for print buffer overflow + * @pb: pointer to print buffer structure + * + * Verifies that a print buffer has captured all data written to it. + * If data has been lost, linearize buffer and prepend an error message + * + * Returns length of print buffer data string (including trailing NUL) + */ + +int tipc_printbuf_validate(struct print_buf *pb) +{ + char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; + char *cp_buf; + struct print_buf cb; + + if (!pb->buf) + return 0; + + if (pb->buf[pb->size - 1] == 0) { + cp_buf = kmalloc(pb->size, GFP_ATOMIC); + if (cp_buf) { + tipc_printbuf_init(&cb, cp_buf, pb->size); + tipc_printbuf_move(&cb, pb); + tipc_printbuf_move(pb, &cb); + kfree(cp_buf); + memcpy(pb->buf, err, strlen(err)); + } else { + tipc_printbuf_reset(pb); + tipc_printf(pb, err); + } + } + return pb->crs - pb->buf + 1; +} + +/** + * tipc_printbuf_move - move print buffer contents to another print buffer + * @pb_to: pointer to destination print buffer structure + * @pb_from: pointer to source print buffer structure + * + * Current contents of destination print buffer (if any) are discarded. + * Source print buffer becomes empty if a successful move occurs. + */ + +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from) +{ + int len; + + /* Handle the cases where contents can't be moved */ + + if (!pb_to->buf) + return; + + if (!pb_from->buf) { + tipc_printbuf_reset(pb_to); + return; + } + + if (pb_to->size < pb_from->size) { + strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); + pb_to->buf[pb_to->size - 1] = ~0; + pb_to->crs = strchr(pb_to->buf, 0); + return; + } + + /* Copy data from char after cursor to end (if used) */ + + len = pb_from->buf + pb_from->size - pb_from->crs - 2; + if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) { + strcpy(pb_to->buf, pb_from->crs + 1); + pb_to->crs = pb_to->buf + len; + } else + pb_to->crs = pb_to->buf; + + /* Copy data from start to cursor (always) */ + + len = pb_from->crs - pb_from->buf; + strcpy(pb_to->crs, pb_from->buf); + pb_to->crs += len; + + tipc_printbuf_reset(pb_from); +} + +/** + * tipc_printf - append formatted output to print buffer + * @pb: pointer to print buffer + * @fmt: formatted info to be printed + */ + +void tipc_printf(struct print_buf *pb, const char *fmt, ...) +{ + int chars_to_add; + int chars_left; + char save_char; + + spin_lock_bh(&print_lock); + + FORMAT(print_string, chars_to_add, fmt); + if (chars_to_add >= TIPC_PB_MAX_STR) + strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); + + if (pb->buf) { + chars_left = pb->buf + pb->size - pb->crs - 1; + if (chars_to_add <= chars_left) { + strcpy(pb->crs, print_string); + pb->crs += chars_to_add; + } else if (chars_to_add >= (pb->size - 1)) { + strcpy(pb->buf, print_string + chars_to_add + 1 + - pb->size); + pb->crs = pb->buf + pb->size - 1; + } else { + strcpy(pb->buf, print_string + chars_left); + save_char = print_string[chars_left]; + print_string[chars_left] = 0; + strcpy(pb->crs, print_string); + print_string[chars_left] = save_char; + pb->crs = pb->buf + chars_to_add - chars_left; + } + } + + if (pb->echo) + printk("%s", print_string); + + spin_unlock_bh(&print_lock); +} + +#ifdef CONFIG_TIPC_DEBUG + +/** + * print_to_console - write string of bytes to console in multiple chunks + */ + +static void print_to_console(char *crs, int len) +{ + int rest = len; + + while (rest > 0) { + int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; + char c = crs[sz]; + + crs[sz] = 0; + printk((const char *)crs); + crs[sz] = c; + rest -= sz; + crs += sz; + } +} + +/** + * printbuf_dump - write print buffer contents to console + */ + +static void printbuf_dump(struct print_buf *pb) +{ + int len; + + if (!pb->buf) { + printk("*** PRINT BUFFER NOT ALLOCATED ***"); + return; + } + + /* Dump print buffer from char after cursor to end (if used) */ + + len = pb->buf + pb->size - pb->crs - 2; + if ((pb->buf[pb->size - 1] == 0) && (len > 0)) + print_to_console(pb->crs + 1, len); + + /* Dump print buffer from start to cursor (always) */ + + len = pb->crs - pb->buf; + print_to_console(pb->buf, len); +} + +/** + * tipc_dump_dbg - dump (non-console) print buffer to console + * @pb: pointer to print buffer + */ + +void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...) +{ + int len; + + if (pb == TIPC_CONS) + return; + + spin_lock_bh(&print_lock); + + FORMAT(print_string, len, fmt); + printk(print_string); + + printk("\n---- Start of %s log dump ----\n\n", + (pb == TIPC_LOG) ? "global" : "local"); + printbuf_dump(pb); + tipc_printbuf_reset(pb); + printk("\n---- End of dump ----\n"); + + spin_unlock_bh(&print_lock); +} + +#endif + +/** + * tipc_log_resize - change the size of the TIPC log buffer + * @log_size: print buffer size to use + */ + +int tipc_log_resize(int log_size) +{ + int res = 0; + + spin_lock_bh(&print_lock); + kfree(TIPC_LOG->buf); + TIPC_LOG->buf = NULL; + if (log_size) { + if (log_size < TIPC_PB_MIN_SIZE) + log_size = TIPC_PB_MIN_SIZE; + res = TIPC_LOG->echo; + tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), + log_size); + TIPC_LOG->echo = res; + res = !TIPC_LOG->buf; + } + spin_unlock_bh(&print_lock); + + return res; +} + +/** + * tipc_log_resize_cmd - reconfigure size of TIPC log buffer + */ + +struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space) +{ + u32 value; + + if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) + return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); + + value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); + if (value != delimit(value, 0, 32768)) + return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE + " (log size must be 0-32768)"); + if (tipc_log_resize(value)) + return tipc_cfg_reply_error_string( + "unable to create specified log (log size is now 0)"); + return tipc_cfg_reply_none(); +} + +/** + * tipc_log_dump - capture TIPC log buffer contents in configuration message + */ + +struct sk_buff *tipc_log_dump(void) +{ + struct sk_buff *reply; + + spin_lock_bh(&print_lock); + if (!TIPC_LOG->buf) { + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_ultra_string("log not activated\n"); + } else if (tipc_printbuf_empty(TIPC_LOG)) { + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_ultra_string("log is empty\n"); + } else { + struct tlv_desc *rep_tlv; + struct print_buf pb; + int str_len; + + str_len = min(TIPC_LOG->size, 32768u); + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); + if (reply) { + rep_tlv = (struct tlv_desc *)reply->data; + tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); + spin_lock_bh(&print_lock); + tipc_printbuf_move(&pb, TIPC_LOG); + spin_unlock_bh(&print_lock); + str_len = strlen(TLV_DATA(rep_tlv)) + 1; + skb_put(reply, TLV_SPACE(str_len)); + TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); + } + } + return reply; +} diff --git a/net/tipc/log.h b/net/tipc/log.h new file mode 100644 index 000000000000..f4343bb9e429 --- /dev/null +++ b/net/tipc/log.h @@ -0,0 +1,67 @@ +/* + * net/tipc/log.h: Include file for TIPC print buffer routines + * + * Copyright (c) 1997-2006, Ericsson AB + * Copyright (c) 2005-2007, Wind River Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIPC_DBG_H +#define _TIPC_DBG_H + +/** + * struct print_buf - TIPC print buffer structure + * @buf: pointer to character array containing print buffer contents + * @size: size of character array + * @crs: pointer to first unused space in character array (i.e. final NUL) + * @echo: echo output to system console if non-zero + */ + +struct print_buf { + char *buf; + u32 size; + char *crs; + int echo; +}; + +#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ +#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ + +void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); +int tipc_printbuf_validate(struct print_buf *pb); + +int tipc_log_resize(int log_size); + +struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, + int req_tlv_space); +struct sk_buff *tipc_log_dump(void); + +#endif -- cgit v1.2.3-59-g8ed1b From b29f14284989b3d0b3a5ce268b5b1fc4df9c5795 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:25 +0000 Subject: tipc: remove calls to dbg() and msg_dbg() Eliminates obsolete calls to two of TIPC's main debugging macros, as well as a pair of associated debugging routines that are no longer required. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 3 -- net/tipc/bearer.c | 1 - net/tipc/config.c | 4 +- net/tipc/core.h | 4 -- net/tipc/discover.c | 4 -- net/tipc/link.c | 119 ++------------------------------------------------ net/tipc/name_distr.c | 14 ------ net/tipc/name_table.c | 33 +------------- net/tipc/net.c | 10 ----- net/tipc/node.c | 3 -- net/tipc/port.c | 10 ----- net/tipc/port.h | 1 - net/tipc/socket.c | 39 +++++------------ net/tipc/subscr.c | 4 -- 14 files changed, 16 insertions(+), 233 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 110829eab96a..cb817d503c14 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -436,8 +436,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) u32 seqno; struct sk_buff *deferred; - msg_dbg(msg, "bclink.supported || (msg_mc_netid(msg) != tipc_net_id))) { buf_discard(buf); @@ -445,7 +443,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) } if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { - msg_dbg(msg, "priority = bearer_priority; m_ptr->tolerance = link_tolerance; m_ptr->window = send_window_limit; - dbg("Media <%s> registered\n", name); res = 0; exit: write_unlock_bh(&tipc_net_lock); diff --git a/net/tipc/config.c b/net/tipc/config.c index afa6e853c04b..a7894ff77ae9 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -65,10 +65,8 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); int new_tlv_space = TLV_SPACE(tlv_data_size); - if (skb_tailroom(buf) < new_tlv_space) { - dbg("tipc_cfg_append_tlv unable to append TLV\n"); + if (skb_tailroom(buf) < new_tlv_space) return 0; - } skb_put(buf, new_tlv_space); tlv->tlv_type = htons(tlv_type); tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); diff --git a/net/tipc/core.h b/net/tipc/core.h index 17f3670ed95d..b4e54f8dd43b 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -243,7 +243,6 @@ u32 tipc_k_signal(Handler routine, unsigned long argument); static inline void k_init_timer(struct timer_list *timer, Handler routine, unsigned long argument) { - dbg("initializing timer %p\n", timer); setup_timer(timer, routine, argument); } @@ -263,7 +262,6 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine, static inline void k_start_timer(struct timer_list *timer, unsigned long msec) { - dbg("starting timer %p for %u\n", timer, msec); mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1); } @@ -280,7 +278,6 @@ static inline void k_start_timer(struct timer_list *timer, unsigned long msec) static inline void k_cancel_timer(struct timer_list *timer) { - dbg("cancelling timer %p\n", timer); del_timer_sync(timer); } @@ -298,7 +295,6 @@ static inline void k_cancel_timer(struct timer_list *timer) static inline void k_term_timer(struct timer_list *timer) { - dbg("terminating timer %p\n", timer); } diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 80799f6ba892..e7223789d150 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -133,7 +133,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) u32 type = msg_type(msg); msg_get_media_addr(msg,&media_addr); - msg_dbg(msg, "RECV:"); buf_discard(buf); if (net_id != tipc_net_id) @@ -156,7 +155,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) struct tipc_node *n_ptr = tipc_node_find(orig); int link_fully_up; - dbg(" in own cluster\n"); if (n_ptr == NULL) { n_ptr = tipc_node_create(orig); if (!n_ptr) @@ -173,7 +171,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) link = n_ptr->links[b_ptr->identity]; if (!link) { - dbg("creating link\n"); link = tipc_link_create(b_ptr, orig, &media_addr); if (!link) { spin_unlock_bh(&n_ptr->lock); @@ -198,7 +195,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) return; rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); if (rbuf != NULL) { - msg_dbg(buf_msg(rbuf),"SEND:"); b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); buf_discard(rbuf); } diff --git a/net/tipc/link.c b/net/tipc/link.c index 671ffd3c0e53..cb10d20caef3 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -153,18 +153,6 @@ static void dbg_print_link(struct link *l_ptr, const char *str) link_print(l_ptr, DBG_OUTPUT, str); } -static void dbg_print_buf_chain(struct sk_buff *root_buf) -{ - if (DBG_OUTPUT != TIPC_NULL) { - struct sk_buff *buf = root_buf; - - while (buf) { - msg_dbg(buf_msg(buf), "In chain: "); - buf = buf->next; - } - } -} - /* * Simple link routines */ @@ -433,9 +421,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, list_add_tail(&l_ptr->link_list, &b_ptr->links); tipc_k_signal((Handler)link_start, (unsigned long)l_ptr); - dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", - l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit); - return l_ptr; } @@ -455,8 +440,6 @@ void tipc_link_delete(struct link *l_ptr) return; } - dbg("tipc_link_delete()\n"); - k_cancel_timer(&l_ptr->timer); tipc_node_lock(l_ptr->owner); @@ -473,7 +456,6 @@ void tipc_link_delete(struct link *l_ptr) static void link_start(struct link *l_ptr) { - dbg("link_start %x\n", l_ptr); link_state_event(l_ptr, STARTING_EVT); } @@ -926,9 +908,6 @@ static int link_bundle_buf(struct link *l_ptr, skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); msg_set_size(bundler_msg, to_pos + size); msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); - dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n", - msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg)); - msg_dbg(msg, "PACKD:"); buf_discard(buf); l_ptr->stats.sent_bundled++; return 1; @@ -977,7 +956,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) return link_schedule_port(l_ptr, msg_origport(msg), size); } - msg_dbg(msg, "TIPC: Congestion, throwing away\n"); buf_discard(buf); if (imp > CONN_MANAGER) { warn("Resetting link <%s>, send queue full", l_ptr->name); @@ -1066,17 +1044,12 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector & 1]; if (l_ptr) { - dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest); res = tipc_link_send_buf(l_ptr, buf); } else { - dbg("Attempt to send msg to unreachable node:\n"); - msg_dbg(buf_msg(buf),">>>"); buf_discard(buf); } tipc_node_unlock(n_ptr); } else { - dbg("Attempt to send msg to unknown node:\n"); - msg_dbg(buf_msg(buf),">>>"); buf_discard(buf); } read_unlock_bh(&tipc_net_lock); @@ -1103,10 +1076,8 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf, if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) { l_ptr->unacked_window = 0; - msg_dbg(msg,"SENT_FAST:"); return res; } - dbg("failed sent fast...\n"); tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); l_ptr->stats.bearer_congs++; l_ptr->next_out = buf; @@ -1141,8 +1112,6 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) if (likely(n_ptr)) { tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector]; - dbg("send_fast: buf %x selected %x, destnode = %x\n", - buf, l_ptr, destnode); if (likely(l_ptr)) { res = link_send_buf_fast(l_ptr, buf, &dummy); tipc_node_unlock(n_ptr); @@ -1292,7 +1261,6 @@ again: /* Prepare reusable fragment header: */ - msg_dbg(hdr, ">FRAGMENTING>"); tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(hdr)); msg_set_link_selector(&fragm_hdr, sender->publ.ref); @@ -1308,7 +1276,6 @@ again: skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); hsz = msg_hdr_sz(hdr); skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); - msg_dbg(buf_msg(buf), ">BUILD>"); /* Chop up message: */ @@ -1367,7 +1334,6 @@ error: skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); fragm_crs = INT_H_SIZE; fragm_rest = fragm_sz; - msg_dbg(buf_msg(buf)," >BUILD>"); } } while (rest > 0); @@ -1417,7 +1383,6 @@ reject: l_ptr->stats.sent_fragments++; msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); link_add_to_outqueue(l_ptr, buf, msg); - msg_dbg(msg, ">ADD>"); buf = next; } @@ -1459,14 +1424,12 @@ u32 tipc_link_push_packet(struct link *l_ptr) msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - msg_dbg(buf_msg(buf), ">DEF-RETR>"); l_ptr->retransm_queue_head = mod(++r_q_head); l_ptr->retransm_queue_size = --r_q_size; l_ptr->stats.retransmitted++; return 0; } else { l_ptr->stats.bearer_congs++; - msg_dbg(buf_msg(buf), "|>DEF-RETR>"); return PUSH_FAILED; } } @@ -1478,13 +1441,11 @@ u32 tipc_link_push_packet(struct link *l_ptr) msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - msg_dbg(buf_msg(buf), ">DEF-PROT>"); l_ptr->unacked_window = 0; buf_discard(buf); l_ptr->proto_msg_queue = NULL; return 0; } else { - msg_dbg(buf_msg(buf), "|>DEF-PROT>"); l_ptr->stats.bearer_congs++; return PUSH_FAILED; } @@ -1504,11 +1465,9 @@ u32 tipc_link_push_packet(struct link *l_ptr) if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { if (msg_user(msg) == MSG_BUNDLER) msg_set_type(msg, CLOSED_MSG); - msg_dbg(msg, ">PUSH-DATA>"); l_ptr->next_out = buf->next; return 0; } else { - msg_dbg(msg, "|PUSH-DATA|"); l_ptr->stats.bearer_congs++; return PUSH_FAILED; } @@ -1571,7 +1530,6 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) struct tipc_msg *msg = buf_msg(buf); warn("Retransmission failure on link <%s>\n", l_ptr->name); - tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>"); if (l_ptr->addr) { @@ -1621,11 +1579,8 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, msg = buf_msg(buf); - dbg("Retransmitting %u in link %x\n", retransmits, l_ptr); - if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { if (l_ptr->retransm_queue_size == 0) { - msg_dbg(msg, ">NO_RETR->BCONG>"); dbg_print_link(l_ptr, " "); l_ptr->retransm_queue_head = msg_seqno(msg); l_ptr->retransm_queue_size = retransmits; @@ -1653,7 +1608,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - msg_dbg(buf_msg(buf), ">RETR>"); buf = buf->next; retransmits--; l_ptr->stats.retransmitted++; @@ -1939,12 +1893,10 @@ deliver: tipc_node_unlock(n_ptr); continue; } - msg_dbg(msg,"NSEQnext = head; head = buf; tipc_node_unlock(n_ptr); @@ -2026,9 +1978,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr, return; } - dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n", - seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no); - /* Record OOS packet arrival (force mismatch on next timeout) */ l_ptr->checkpoint--; @@ -2146,8 +2095,6 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, /* Message can be sent */ - msg_dbg(msg, ">>"); - buf = tipc_buf_acquire(msg_size); if (!buf) return; @@ -2181,8 +2128,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) u32 msg_tol; struct tipc_msg *msg = buf_msg(buf); - dbg("AT(%u):", jiffies_to_msecs(jiffies)); - msg_dbg(msg, "<<"); if (link_blocked(l_ptr)) goto exit; @@ -2201,11 +2146,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) case RESET_MSG: if (!link_working_unknown(l_ptr) && (l_ptr->peer_session != INVALID_SESSION)) { - if (msg_session(msg) == l_ptr->peer_session) { - dbg("Duplicate RESET: %u<->%u\n", - msg_session(msg), l_ptr->peer_session); + if (msg_session(msg) == l_ptr->peer_session) break; /* duplicate: ignore */ - } } /* fall thru' */ case ACTIVATE_MSG: @@ -2266,8 +2208,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) max_pkt_ack = msg_max_pkt(msg); if (max_pkt_ack > l_ptr->max_pkt) { - dbg("Link <%s> updated MTU %u -> %u\n", - l_ptr->name, l_ptr->max_pkt, max_pkt_ack); l_ptr->max_pkt = max_pkt_ack; l_ptr->max_pkt_probes = 0; } @@ -2289,14 +2229,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) 0, rec_gap, 0, 0, max_pkt_ack); } if (msg_seq_gap(msg)) { - msg_dbg(msg, "With Gap:"); l_ptr->stats.recv_nacks++; tipc_link_retransmit(l_ptr, l_ptr->first_out, msg_seq_gap(msg)); } break; - default: - msg_dbg(buf_msg(buf), "%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); - msg_dbg(buf_msg(buf), ">SEND>"); tipc_link_send_buf(tunnel, buf); } @@ -2364,7 +2299,6 @@ void tipc_link_changeover(struct link *l_ptr) ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); msg_set_msgcnt(&tunnel_hdr, msgcount); - dbg("Link changeover requires %u tunnel messages\n", msgcount); if (!l_ptr->first_out) { struct sk_buff *buf; @@ -2373,9 +2307,6 @@ void tipc_link_changeover(struct link *l_ptr) if (buf) { skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); msg_set_size(&tunnel_hdr, INT_H_SIZE); - dbg("%c->%c:", l_ptr->b_ptr->net_plane, - tunnel->b_ptr->net_plane); - msg_dbg(&tunnel_hdr, "EMPTY>SEND>"); tipc_link_send_buf(tunnel, buf); } else { warn("Link changeover error, " @@ -2439,9 +2370,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, length); - dbg("%c->%c:", l_ptr->b_ptr->net_plane, - tunnel->b_ptr->net_plane); - msg_dbg(buf_msg(outbuf), ">SEND>"); tipc_link_send_buf(tunnel, outbuf); if (!tipc_link_is_up(l_ptr)) return; @@ -2488,31 +2416,24 @@ static int link_recv_changeover_msg(struct link **l_ptr, u32 msg_count = msg_msgcnt(tunnel_msg); dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; - if (!dest_link) { - msg_dbg(tunnel_msg, "NOLINK/\n", (*l_ptr)->name); goto exit; } - dbg("%c<-%c:", dest_link->b_ptr->net_plane, - (*l_ptr)->b_ptr->net_plane); *l_ptr = dest_link; msg = msg_get_wrapped(tunnel_msg); if (msg_typ == DUPLICATE_MSG) { - if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { - msg_dbg(tunnel_msg, "DROP/next_in_no))) goto exit; - } *buf = buf_extract(tunnel_buf,INT_H_SIZE); if (*buf == NULL) { warn("Link changeover error, duplicate msg dropped\n"); goto exit; } - msg_dbg(tunnel_msg, "TNL, changeover initiated by peer\n", dest_link->name); tipc_link_reset(dest_link); dest_link->exp_msg_count = msg_count; - dbg("Expecting %u tunnelled messages\n", msg_count); if (!msg_count) goto exit; } else if (dest_link->exp_msg_count == START_CHANGEOVER) { - msg_dbg(tunnel_msg, "BLK/FIRST/exp_msg_count = msg_count; - dbg("Expecting %u tunnelled messages\n", msg_count); if (!msg_count) goto exit; } @@ -2541,18 +2458,15 @@ static int link_recv_changeover_msg(struct link **l_ptr, if (dest_link->exp_msg_count == 0) { warn("Link switchover error, " "got too many tunnelled messages\n"); - msg_dbg(tunnel_msg, "OVERDUE/DROP/exp_msg_count--; if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { - msg_dbg(tunnel_msg, "DROP/DUPL/ max) { - msg_dbg(fragm,"defragm_buf); if (prev) prev->next = buf->next; else @@ -3165,19 +3066,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) return res; } -static void link_dump_send_queue(struct link *l_ptr) -{ - if (l_ptr->next_out) { - info("\nContents of unsent queue:\n"); - dbg_print_buf_chain(l_ptr->next_out); - } - info("\nContents of send queue:\n"); - if (l_ptr->first_out) { - dbg_print_buf_chain(l_ptr->first_out); - } - info("Empty send queue\n"); -} - static void link_print(struct link *l_ptr, struct print_buf *buf, const char *str) { @@ -3203,7 +3091,6 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, tipc_printf(buf, "first_out= %x ", l_ptr->first_out); tipc_printf(buf, "next_out= %x ", l_ptr->next_out); tipc_printf(buf, "last_out= %x ", l_ptr->last_out); - link_dump_send_queue(l_ptr); } } else tipc_printf(buf, "[]"); diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index c4583fe888d8..0dd648ec0809 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -87,7 +87,6 @@ static void publ_to_item(struct distr_item *i, struct publication *p) i->upper = htonl(p->upper); i->ref = htonl(p->ref); i->key = htonl(p->key); - dbg("publ_to_item: %u, %u, %u\n", p->type, p->lower, p->upper); } /** @@ -147,7 +146,6 @@ void tipc_named_publish(struct publication *publ) item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); - dbg("tipc_named_publish: broadcasting publish msg\n"); named_cluster_distribute(buf); } @@ -171,7 +169,6 @@ void tipc_named_withdraw(struct publication *publ) item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); - dbg("tipc_named_withdraw: broadcasting withdraw msg\n"); named_cluster_distribute(buf); } @@ -209,9 +206,6 @@ void tipc_named_node_up(unsigned long node) left -= ITEM_SIZE; if (!left) { msg_set_link_selector(buf_msg(buf), node); - dbg("tipc_named_node_up: sending publish msg to " - "<%u.%u.%u>\n", tipc_zone(node), - tipc_cluster(node), tipc_node(node)); tipc_link_send(buf, node, node); buf = NULL; } @@ -236,8 +230,6 @@ static void node_is_down(struct publication *publ) struct publication *p; write_lock_bh(&tipc_nametbl_lock); - dbg("node_is_down: withdrawing %u, %u, %u\n", - publ->type, publ->lower, publ->upper); publ->key += 1222345; p = tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, publ->ref, publ->key); @@ -268,9 +260,6 @@ void tipc_named_recv(struct sk_buff *buf) write_lock_bh(&tipc_nametbl_lock); while (count--) { if (msg_type(msg) == PUBLICATION) { - dbg("tipc_named_recv: got publication for %u, %u, %u\n", - ntohl(item->type), ntohl(item->lower), - ntohl(item->upper)); publ = tipc_nametbl_insert_publ(ntohl(item->type), ntohl(item->lower), ntohl(item->upper), @@ -285,9 +274,6 @@ void tipc_named_recv(struct sk_buff *buf) (net_ev_handler)node_is_down); } } else if (msg_type(msg) == WITHDRAWAL) { - dbg("tipc_named_recv: got withdrawl for %u, %u, %u\n", - ntohl(item->type), ntohl(item->lower), - ntohl(item->upper)); publ = tipc_nametbl_remove_publ(ntohl(item->type), ntohl(item->lower), msg_orignode(msg), diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index d5adb0456746..ddc2ad4c2d32 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -172,8 +172,6 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea spin_lock_init(&nseq->lock); nseq->type = type; nseq->sseqs = sseq; - dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n", - nseq, type, nseq->sseqs, nseq->first_free); nseq->alloc = 1; INIT_HLIST_NODE(&nseq->ns_list); INIT_LIST_HEAD(&nseq->subscriptions); @@ -251,8 +249,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, int created_subseq = 0; sseq = nameseq_find_subseq(nseq, lower); - dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n", - nseq, type, lower, sseq); if (sseq) { /* Lower end overlaps existing entry => need an exact match */ @@ -289,18 +285,15 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, type, lower, upper); return NULL; } - dbg("Allocated %u more sseqs\n", nseq->alloc); memcpy(sseqs, nseq->sseqs, nseq->alloc * sizeof(struct sub_seq)); kfree(nseq->sseqs); nseq->sseqs = sseqs; nseq->alloc *= 2; } - dbg("Have %u sseqs for type %u\n", nseq->alloc, type); /* Insert new sub-sequence */ - dbg("ins in pos %u, ff = %u\n", inspos, nseq->first_free); sseq = &nseq->sseqs[inspos]; freesseq = &nseq->sseqs[nseq->first_free]; memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq)); @@ -310,17 +303,12 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, sseq->upper = upper; created_subseq = 1; } - dbg("inserting {%u,%u,%u} from <0x%x:%u> into sseq %p(%u,%u) of seq %p\n", - type, lower, upper, node, port, sseq, - sseq->lower, sseq->upper, nseq); /* Insert a publication: */ publ = publ_create(type, lower, upper, scope, node, port, key); if (!publ) return NULL; - dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", - publ, node, publ->node, publ->subscr.node); sseq->zone_list_size++; if (!sseq->zone_list) @@ -355,7 +343,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, * Any subscriptions waiting for notification? */ list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { - dbg("calling report_overlap()\n"); tipc_subscr_report_overlap(s, publ->lower, publ->upper, @@ -393,9 +380,6 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i if (!sseq) return NULL; - dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n", - nseq, sseq, nseq->type, inst, key); - /* Remove publication from zone scope list */ prev = sseq->zone_list; @@ -549,15 +533,10 @@ static struct name_seq *nametbl_find_seq(u32 type) struct hlist_node *seq_node; struct name_seq *ns; - dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n", - type, htonl(type), type, table.types, hash(type)); - seq_head = &table.types[hash(type)]; hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { - if (ns->type == type) { - dbg("found %p\n", ns); + if (ns->type == type) return ns; - } } return NULL; @@ -568,18 +547,14 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, { struct name_seq *seq = nametbl_find_seq(type); - dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq); if (lower > upper) { warn("Failed to publish illegal {%u,%u,%u}\n", type, lower, upper); return NULL; } - dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node); - if (!seq) { + if (!seq) seq = tipc_nameseq_create(type, &table.types[hash(type)]); - dbg("tipc_nametbl_insert_publ: created %p\n", seq); - } if (!seq) return NULL; @@ -596,7 +571,6 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, if (!seq) return NULL; - dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node); publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); if (!seq->first_free && list_empty(&seq->subscriptions)) { @@ -792,7 +766,6 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) { struct publication *publ; - dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key); write_lock_bh(&tipc_nametbl_lock); publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); if (likely(publ)) { @@ -827,8 +800,6 @@ void tipc_nametbl_subscribe(struct subscription *s) } if (seq){ spin_lock_bh(&seq->lock); - dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n", - seq, type, s->seq.lower, s->seq.upper); tipc_nameseq_subscribe(seq, s); spin_unlock_bh(&seq->lock); } else { diff --git a/net/tipc/net.c b/net/tipc/net.c index 3baf55ee0985..6290becd35be 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -138,22 +138,18 @@ static void net_route_named_msg(struct sk_buff *buf) u32 dport; if (!msg_named(msg)) { - msg_dbg(msg, "tipc_net->drop_nam:"); buf_discard(buf); return; } dnode = addr_domain(msg_lookup_scope(msg)); dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode); - dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n", - msg_nametype(msg), msg_nameinst(msg), dport, dnode); if (dport) { msg_set_destnode(msg, dnode); msg_set_destport(msg, dport); tipc_net_route_msg(buf); return; } - msg_dbg(msg, "tipc_net->rej:NO NAME: "); tipc_reject_msg(buf, TIPC_ERR_NO_NAME); } @@ -169,18 +165,14 @@ void tipc_net_route_msg(struct sk_buff *buf) msg_incr_reroute_cnt(msg); if (msg_reroute_cnt(msg) > 6) { if (msg_errcode(msg)) { - msg_dbg(msg, "NET>DISC>:"); buf_discard(buf); } else { - msg_dbg(msg, "NET>REJ>:"); tipc_reject_msg(buf, msg_destport(msg) ? TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); } return; } - msg_dbg(msg, "tipc_net->rout: "); - /* Handle message for this node */ dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); if (tipc_in_scope(dnode, tipc_own_addr)) { @@ -201,14 +193,12 @@ void tipc_net_route_msg(struct sk_buff *buf) tipc_port_recv_proto_msg(buf); break; default: - msg_dbg(msg,"DROP/NET/SEND>: "); skb_trim(buf, msg_size(msg)); tipc_link_send(buf, dnode, msg_link_selector(msg)); } diff --git a/net/tipc/node.c b/net/tipc/node.c index 31dcca98201a..fb54719679a6 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -97,7 +97,6 @@ void tipc_node_delete(struct tipc_node *n_ptr) if (!n_ptr) return; - dbg("node %x deleted\n", n_ptr->addr); n_num = tipc_node(n_ptr->addr); tipc_net.nodes[n_num] = NULL; kfree(n_ptr); @@ -124,7 +123,6 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr) l_ptr->name, l_ptr->b_ptr->net_plane); if (!active[0]) { - dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]); active[0] = active[1] = l_ptr; node_established_contact(n_ptr); return; @@ -302,7 +300,6 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) static void node_established_contact(struct tipc_node *n_ptr) { - dbg("node_established_contact:-> %x\n", n_ptr->addr); tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); /* Syncronize broadcast acks */ diff --git a/net/tipc/port.c b/net/tipc/port.c index 33d0b3b7175f..8bacd572a9fb 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -188,7 +188,6 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) if (b == NULL) { warn("Unable to deliver multicast message(s)\n"); - msg_dbg(msg, "LOST:"); goto exit; } if ((index == 0) && (cnt != 0)) { @@ -280,7 +279,6 @@ int tipc_deleteport(u32 ref) spin_unlock_bh(&tipc_port_list_lock); k_term_timer(&p_ptr->timer); kfree(p_ptr); - dbg("Deleted port %u\n", ref); tipc_net_route_msg(buf); return 0; } @@ -366,7 +364,6 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, msg_set_orignode(msg, orignode); msg_set_transp_seqno(msg, seqno); msg_set_msgcnt(msg, ack); - msg_dbg(msg, "PORT>SEND>:"); } return buf; } @@ -384,7 +381,6 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) data_sz = MAX_REJECT_SIZE; if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) imp++; - msg_dbg(msg, "port->rej: "); /* discard rejected message if it shouldn't be returned to sender */ if (msg_errcode(msg) || msg_dest_droppable(msg)) { @@ -547,8 +543,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) struct sk_buff *r_buf = NULL; struct sk_buff *abort_buf = NULL; - msg_dbg(msg, "PORTpubl.connected) { @@ -1015,9 +1009,6 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) if (!p_ptr) return -EINVAL; - dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " - "lower = %u, upper = %u\n", - ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); if (p_ptr->publ.connected) goto exit; if (seq->lower > seq->upper) @@ -1357,7 +1348,6 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, skb_push(buf, DIR_MSG_H_SIZE); skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); - msg_dbg(msg, "buf2port: "); p_ptr->sent++; if (dest->node == tipc_own_addr) return tipc_port_recv_msg(buf); diff --git a/net/tipc/port.h b/net/tipc/port.h index da607a8a2f35..a9c528799f2f 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -316,7 +316,6 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf) err = TIPC_ERR_NO_PORT; } reject: - dbg("port->rejecting, err = %x..\n",err); return tipc_reject_msg(buf, err); } diff --git a/net/tipc/socket.c b/net/tipc/socket.c index cd0bb77f2673..7a21a5ee43e8 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1226,42 +1226,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) */ if (sock->state == SS_READY) { - if (msg_connected(msg)) { - msg_dbg(msg, "dispatch filter 1\n"); + if (msg_connected(msg)) return TIPC_ERR_NO_PORT; - } } else { - if (msg_mcast(msg)) { - msg_dbg(msg, "dispatch filter 2\n"); + if (msg_mcast(msg)) return TIPC_ERR_NO_PORT; - } if (sock->state == SS_CONNECTED) { - if (!msg_connected(msg)) { - msg_dbg(msg, "dispatch filter 3\n"); + if (!msg_connected(msg)) return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_CONNECTING) { - if (!msg_connected(msg) && (msg_errcode(msg) == 0)) { - msg_dbg(msg, "dispatch filter 4\n"); + } else if (sock->state == SS_CONNECTING) { + if (!msg_connected(msg) && (msg_errcode(msg) == 0)) return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_LISTENING) { - if (msg_connected(msg) || msg_errcode(msg)) { - msg_dbg(msg, "dispatch filter 5\n"); + } else if (sock->state == SS_LISTENING) { + if (msg_connected(msg) || msg_errcode(msg)) return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_DISCONNECTING) { - msg_dbg(msg, "dispatch filter 6\n"); + } else if (sock->state == SS_DISCONNECTING) { return TIPC_ERR_NO_PORT; - } - else /* (sock->state == SS_UNCONNECTED) */ { - if (msg_connected(msg) || msg_errcode(msg)) { - msg_dbg(msg, "dispatch filter 7\n"); + } else /* (sock->state == SS_UNCONNECTED) */ { + if (msg_connected(msg) || msg_errcode(msg)) return TIPC_ERR_NO_PORT; - } } } @@ -1280,7 +1263,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) /* Enqueue message (finally!) */ - msg_dbg(msg, "handle = msg_data(msg); atomic_inc(&tipc_queue_size); __skb_queue_tail(&sk->sk_receive_queue, buf); @@ -1588,7 +1570,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) * Respond to 'SYN+' by queuing it on new socket. */ - msg_dbg(msg,"timer); k_term_timer(&sub->timer); } - dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n", - sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); subscr_del(sub); } @@ -307,8 +305,6 @@ static void subscr_cancel(struct tipc_subscr *s, k_term_timer(&sub->timer); spin_lock_bh(subscriber->lock); } - dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", - sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); subscr_del(sub); } -- cgit v1.2.3-59-g8ed1b From 7ced6890bf81d311ab2ea846f92d5f3d0951c08c Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:26 +0000 Subject: tipc: remove dump() and tipc_dump_dbg() Eliminates calls to two debugging macros that are being completely obsoleted, as well as any associated debugging routines that are no longer required. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/core.h | 8 ------ net/tipc/log.c | 81 +++------------------------------------------------------ 2 files changed, 3 insertions(+), 86 deletions(-) diff --git a/net/tipc/core.h b/net/tipc/core.h index b4e54f8dd43b..3af0b36e3f1a 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -145,23 +145,15 @@ void tipc_printf(struct print_buf *, const char *fmt, ...); if (DBG_OUTPUT != TIPC_NULL) \ tipc_msg_dbg(DBG_OUTPUT, msg, txt); \ } while (0) -#define dump(fmt, arg...) \ - do { \ - if (DBG_OUTPUT != TIPC_NULL) \ - tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \ - } while (0) void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); -void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); #else #define dbg(fmt, arg...) do {} while (0) #define msg_dbg(msg, txt) do {} while (0) -#define dump(fmt, arg...) do {} while (0) #define tipc_msg_dbg(...) do {} while (0) -#define tipc_dump_dbg(...) do {} while (0) #endif diff --git a/net/tipc/log.c b/net/tipc/log.c index 9d99f7097d2d..2796044f9941 100644 --- a/net/tipc/log.c +++ b/net/tipc/log.c @@ -64,9 +64,9 @@ struct print_buf *const TIPC_LOG = &log_buf; * 'print_string' when writing to a print buffer. This also protects against * concurrent writes to the print buffer being written to. * - * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned - * use of 'print_lock' to protect against all types of concurrent operations - * on their associated print buffer (not just write operations). + * 2) tipc_log_XXX() leverages the aforementioned use of 'print_lock' to + * protect against all types of concurrent operations on their associated + * print buffer (not just write operations). * * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely * on the caller to prevent simultaneous use of the print buffer(s) being @@ -268,81 +268,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) spin_unlock_bh(&print_lock); } -#ifdef CONFIG_TIPC_DEBUG - -/** - * print_to_console - write string of bytes to console in multiple chunks - */ - -static void print_to_console(char *crs, int len) -{ - int rest = len; - - while (rest > 0) { - int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; - char c = crs[sz]; - - crs[sz] = 0; - printk((const char *)crs); - crs[sz] = c; - rest -= sz; - crs += sz; - } -} - -/** - * printbuf_dump - write print buffer contents to console - */ - -static void printbuf_dump(struct print_buf *pb) -{ - int len; - - if (!pb->buf) { - printk("*** PRINT BUFFER NOT ALLOCATED ***"); - return; - } - - /* Dump print buffer from char after cursor to end (if used) */ - - len = pb->buf + pb->size - pb->crs - 2; - if ((pb->buf[pb->size - 1] == 0) && (len > 0)) - print_to_console(pb->crs + 1, len); - - /* Dump print buffer from start to cursor (always) */ - - len = pb->crs - pb->buf; - print_to_console(pb->buf, len); -} - -/** - * tipc_dump_dbg - dump (non-console) print buffer to console - * @pb: pointer to print buffer - */ - -void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...) -{ - int len; - - if (pb == TIPC_CONS) - return; - - spin_lock_bh(&print_lock); - - FORMAT(print_string, len, fmt); - printk(print_string); - - printk("\n---- Start of %s log dump ----\n\n", - (pb == TIPC_LOG) ? "global" : "local"); - printbuf_dump(pb); - tipc_printbuf_reset(pb); - printk("\n---- End of dump ----\n"); - - spin_unlock_bh(&print_lock); -} - -#endif - /** * tipc_log_resize - change the size of the TIPC log buffer * @log_size: print buffer size to use -- cgit v1.2.3-59-g8ed1b From 8d64a5ba58157dedc61f3f1f51e1c5d66f32a484 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:27 +0000 Subject: tipc: Prune down link-specific debugging code Eliminates most link-specific debugging code in TIPC, which is now largely unnecessary. All calls to the link-specific debugging macros have been removed, as are the macros themselves; in addition, the optional allocation of print buffers to hold debugging information for each link endpoint has been removed. The ability for TIPC to print out helpful diagnostic information when link retransmit failures occur has been retained for the time being, as an aid in tracking down the cause of such failures. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 13 ----- net/tipc/link.c | 167 ++++++++++++------------------------------------------- net/tipc/link.h | 3 - 3 files changed, 36 insertions(+), 147 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index cb817d503c14..22a10fadc8c6 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -45,8 +45,6 @@ #define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ -#define BCLINK_LOG_BUF_SIZE 0 - /* * Loss rate for incoming broadcast frames; used to test retransmission code. * Set to N to cause every N'th frame to be discarded; 0 => don't discard any. @@ -774,7 +772,6 @@ int tipc_bclink_init(void) bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); if (!bcbearer || !bclink) { - nomem: warn("Multicast link creation failed, no memory\n"); kfree(bcbearer); bcbearer = NULL; @@ -799,14 +796,6 @@ int tipc_bclink_init(void) bcl->state = WORKING_WORKING; strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); - if (BCLINK_LOG_BUF_SIZE) { - char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC); - - if (!pb) - goto nomem; - tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); - } - return 0; } @@ -815,8 +804,6 @@ void tipc_bclink_stop(void) spin_lock_bh(&bc_lock); if (bcbearer) { tipc_link_stop(bcl); - if (BCLINK_LOG_BUF_SIZE) - kfree(bcl->print_buf.buf); bcl = NULL; kfree(bclink); bclink = NULL; diff --git a/net/tipc/link.c b/net/tipc/link.c index cb10d20caef3..647f2ecfde50 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -96,63 +96,10 @@ static int link_send_sections_long(struct port *sender, static void link_check_defragm_bufs(struct link *l_ptr); static void link_state_event(struct link *l_ptr, u32 event); static void link_reset_statistics(struct link *l_ptr); -static void link_print(struct link *l_ptr, struct print_buf *buf, - const char *str); +static void link_print(struct link *l_ptr, const char *str); static void link_start(struct link *l_ptr); static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); - -/* - * Debugging code used by link routines only - * - * When debugging link problems on a system that has multiple links, - * the standard TIPC debugging routines may not be useful since they - * allow the output from multiple links to be intermixed. For this reason - * routines of the form "dbg_link_XXX()" have been created that will capture - * debug info into a link's personal print buffer, which can then be dumped - * into the TIPC system log (TIPC_LOG) upon request. - * - * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size - * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, - * the dbg_link_XXX() routines simply send their output to the standard - * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful - * when there is only a single link in the system being debugged. - * - * Notes: - * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE - * - "l_ptr" must be valid when using dbg_link_XXX() macros - */ - -#define LINK_LOG_BUF_SIZE 0 - -#define dbg_link(fmt, arg...) \ - do { \ - if (LINK_LOG_BUF_SIZE) \ - tipc_printf(&l_ptr->print_buf, fmt, ## arg); \ - } while (0) -#define dbg_link_msg(msg, txt) \ - do { \ - if (LINK_LOG_BUF_SIZE) \ - tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \ - } while (0) -#define dbg_link_state(txt) \ - do { \ - if (LINK_LOG_BUF_SIZE) \ - link_print(l_ptr, &l_ptr->print_buf, txt); \ - } while (0) -#define dbg_link_dump() do { \ - if (LINK_LOG_BUF_SIZE) { \ - tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ - tipc_printbuf_move(LOG, &l_ptr->print_buf); \ - } \ -} while (0) - -static void dbg_print_link(struct link *l_ptr, const char *str) -{ - if (DBG_OUTPUT != TIPC_NULL) - link_print(l_ptr, DBG_OUTPUT, str); -} - /* * Simple link routines */ @@ -366,17 +313,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, return NULL; } - if (LINK_LOG_BUF_SIZE) { - char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); - - if (!pb) { - kfree(l_ptr); - warn("Link creation failed, no memory for print buffer\n"); - return NULL; - } - tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); - } - l_ptr->addr = peer; if_name = strchr(b_ptr->publ.name, ':') + 1; sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", @@ -411,8 +347,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, l_ptr->owner = tipc_node_attach_link(l_ptr); if (!l_ptr->owner) { - if (LINK_LOG_BUF_SIZE) - kfree(l_ptr->print_buf.buf); kfree(l_ptr); return NULL; } @@ -447,8 +381,6 @@ void tipc_link_delete(struct link *l_ptr) tipc_node_detach_link(l_ptr->owner, l_ptr); tipc_link_stop(l_ptr); list_del_init(&l_ptr->link_list); - if (LINK_LOG_BUF_SIZE) - kfree(l_ptr->print_buf.buf); tipc_node_unlock(l_ptr->owner); k_term_timer(&l_ptr->timer); kfree(l_ptr); @@ -607,7 +539,6 @@ void tipc_link_reset(struct link *l_ptr) link_init_max_pkt(l_ptr); l_ptr->state = RESET_UNKNOWN; - dbg_link_state("Resetting Link\n"); if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) return; @@ -686,20 +617,14 @@ static void link_state_event(struct link *l_ptr, unsigned event) } return; /* Changeover going on */ } - dbg_link("STATE_EV: <%s> ", l_ptr->name); switch (l_ptr->state) { case WORKING_WORKING: - dbg_link("WW/"); switch (event) { case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); - /* fall through */ case ACTIVATE_MSG: - dbg_link("ACT\n"); break; case TIMEOUT_EVT: - dbg_link("TIM "); if (l_ptr->next_in_no != l_ptr->checkpoint) { l_ptr->checkpoint = l_ptr->next_in_no; if (tipc_bclink_acks_missing(l_ptr->owner)) { @@ -714,7 +639,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv); break; } - dbg_link(" -> WU\n"); l_ptr->state = WORKING_UNKNOWN; l_ptr->fsm_msg_cnt = 0; tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); @@ -722,7 +646,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv / 4); break; case RESET_MSG: - dbg_link("RES -> RR\n"); info("Resetting link <%s>, requested by peer\n", l_ptr->name); tipc_link_reset(l_ptr); @@ -737,18 +660,14 @@ static void link_state_event(struct link *l_ptr, unsigned event) } break; case WORKING_UNKNOWN: - dbg_link("WU/"); switch (event) { case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); case ACTIVATE_MSG: - dbg_link("ACT -> WW\n"); l_ptr->state = WORKING_WORKING; l_ptr->fsm_msg_cnt = 0; link_set_timer(l_ptr, cont_intv); break; case RESET_MSG: - dbg_link("RES -> RR\n"); info("Resetting link <%s>, requested by peer " "while probing\n", l_ptr->name); tipc_link_reset(l_ptr); @@ -759,9 +678,7 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv); break; case TIMEOUT_EVT: - dbg_link("TIM "); if (l_ptr->next_in_no != l_ptr->checkpoint) { - dbg_link("-> WW\n"); l_ptr->state = WORKING_WORKING; l_ptr->fsm_msg_cnt = 0; l_ptr->checkpoint = l_ptr->next_in_no; @@ -772,16 +689,11 @@ static void link_state_event(struct link *l_ptr, unsigned event) } link_set_timer(l_ptr, cont_intv); } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { - dbg_link("Probing %u/%u,timer = %u ms)\n", - l_ptr->fsm_msg_cnt, l_ptr->abort_limit, - cont_intv / 4); tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); l_ptr->fsm_msg_cnt++; link_set_timer(l_ptr, cont_intv / 4); } else { /* Link has failed */ - dbg_link("-> RU (%u probes unanswered)\n", - l_ptr->fsm_msg_cnt); warn("Resetting link <%s>, peer not responding\n", l_ptr->name); tipc_link_reset(l_ptr); @@ -798,18 +710,13 @@ static void link_state_event(struct link *l_ptr, unsigned event) } break; case RESET_UNKNOWN: - dbg_link("RU/"); switch (event) { case TRAFFIC_MSG_EVT: - dbg_link("TRF-\n"); break; case ACTIVATE_MSG: other = l_ptr->owner->active_links[0]; - if (other && link_working_unknown(other)) { - dbg_link("ACT\n"); + if (other && link_working_unknown(other)) break; - } - dbg_link("ACT -> WW\n"); l_ptr->state = WORKING_WORKING; l_ptr->fsm_msg_cnt = 0; link_activate(l_ptr); @@ -818,8 +725,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv); break; case RESET_MSG: - dbg_link("RES\n"); - dbg_link(" -> RR\n"); l_ptr->state = RESET_RESET; l_ptr->fsm_msg_cnt = 0; tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); @@ -827,11 +732,9 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv); break; case STARTING_EVT: - dbg_link("START-"); l_ptr->started = 1; /* fall through */ case TIMEOUT_EVT: - dbg_link("TIM\n"); tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); l_ptr->fsm_msg_cnt++; link_set_timer(l_ptr, cont_intv); @@ -841,18 +744,12 @@ static void link_state_event(struct link *l_ptr, unsigned event) } break; case RESET_RESET: - dbg_link("RR/ "); switch (event) { case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); - /* fall through */ case ACTIVATE_MSG: other = l_ptr->owner->active_links[0]; - if (other && link_working_unknown(other)) { - dbg_link("ACT\n"); + if (other && link_working_unknown(other)) break; - } - dbg_link("ACT -> WW\n"); l_ptr->state = WORKING_WORKING; l_ptr->fsm_msg_cnt = 0; link_activate(l_ptr); @@ -861,14 +758,11 @@ static void link_state_event(struct link *l_ptr, unsigned event) link_set_timer(l_ptr, cont_intv); break; case RESET_MSG: - dbg_link("RES\n"); break; case TIMEOUT_EVT: - dbg_link("TIM\n"); tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); l_ptr->fsm_msg_cnt++; link_set_timer(l_ptr, cont_intv); - dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt); break; default: err("Unknown link event %u in RR state\n", event); @@ -1515,8 +1409,7 @@ static void link_reset_all(unsigned long addr) for (i = 0; i < MAX_BEARERS; i++) { if (n_ptr->links[i]) { - link_print(n_ptr->links[i], TIPC_OUTPUT, - "Resetting link\n"); + link_print(n_ptr->links[i], "Resetting link\n"); tipc_link_reset(n_ptr->links[i]); } } @@ -1535,7 +1428,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) /* Handle failure on standard link */ - link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n"); + link_print(l_ptr, "Resetting link\n"); tipc_link_reset(l_ptr); } else { @@ -1545,21 +1438,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) struct tipc_node *n_ptr; char addr_string[16]; - tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); - tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n", - (unsigned long) TIPC_SKB_CB(buf)->handle); + info("Msg seq number: %u, ", msg_seqno(msg)); + info("Outstanding acks: %lu\n", + (unsigned long) TIPC_SKB_CB(buf)->handle); n_ptr = l_ptr->owner->next; tipc_node_lock(n_ptr); tipc_addr_string_fill(addr_string, n_ptr->addr); - tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string); - tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported); - tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked); - tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in); - tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after); - tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to); - tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync); + info("Multicast link info for %s\n", addr_string); + info("Supported: %d, ", n_ptr->bclink.supported); + info("Acked: %u\n", n_ptr->bclink.acked); + info("Last in: %u, ", n_ptr->bclink.last_in); + info("Gap after: %u, ", n_ptr->bclink.gap_after); + info("Gap to: %u\n", n_ptr->bclink.gap_to); + info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync); tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); @@ -1581,7 +1474,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { if (l_ptr->retransm_queue_size == 0) { - dbg_print_link(l_ptr, " "); l_ptr->retransm_queue_head = msg_seqno(msg); l_ptr->retransm_queue_size = retransmits; } else { @@ -2458,7 +2350,6 @@ static int link_recv_changeover_msg(struct link **l_ptr, if (dest_link->exp_msg_count == 0) { warn("Link switchover error, " "got too many tunnelled messages\n"); - dbg_print_link(dest_link, "LINK:"); goto exit; } dest_link->exp_msg_count--; @@ -3066,14 +2957,22 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) return res; } -static void link_print(struct link *l_ptr, struct print_buf *buf, - const char *str) +static void link_print(struct link *l_ptr, const char *str) { + char print_area[256]; + struct print_buf pb; + struct print_buf *buf = &pb; + + tipc_printbuf_init(buf, print_area, sizeof(print_area)); + tipc_printf(buf, str); - if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) - return; tipc_printf(buf, "Link %x<%s>:", l_ptr->addr, l_ptr->b_ptr->publ.name); + +#ifdef CONFIG_TIPC_DEBUG + if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) + goto print_state; + tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); tipc_printf(buf, "SQUE"); @@ -3104,14 +3003,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, l_ptr->deferred_inqueue_sz); } } +print_state: +#endif + if (link_working_unknown(l_ptr)) tipc_printf(buf, ":WU"); - if (link_reset_reset(l_ptr)) + else if (link_reset_reset(l_ptr)) tipc_printf(buf, ":RR"); - if (link_reset_unknown(l_ptr)) + else if (link_reset_unknown(l_ptr)) tipc_printf(buf, ":RU"); - if (link_working_working(l_ptr)) + else if (link_working_working(l_ptr)) tipc_printf(buf, ":WW"); tipc_printf(buf, "\n"); + + tipc_printbuf_validate(buf); + info("%s", print_area); } diff --git a/net/tipc/link.h b/net/tipc/link.h index eeb0c015dba9..eca19c247b79 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -107,7 +107,6 @@ * @long_msg_seq_no: next identifier to use for outbound fragmented messages * @defragm_buf: list of partially reassembled inbound message fragments * @stats: collects statistics regarding link activity - * @print_buf: print buffer used to log link activity */ struct link { @@ -210,8 +209,6 @@ struct link { u32 msg_lengths_total; u32 msg_length_profile[7]; } stats; - - struct print_buf print_buf; }; struct port; -- cgit v1.2.3-59-g8ed1b From 6e7e309c62ab584348e0fef90c8e3e48f634dba1 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:28 +0000 Subject: tipc: Finish streamlining of debugging code Completes the simplification of TIPC's debugging capabilities. By default TIPC includes no debugging code, and any debugging code added by developers that calls the dbg() and dbg_macros() is compiled out. If debugging support is enabled, TIPC prints out some additional data about its internal state when certain abnormal conditions occur, and any developer-added calls to the TIPC debug macros are compiled in. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/Kconfig | 11 +++++++---- net/tipc/core.h | 47 +++++++++-------------------------------------- net/tipc/log.c | 4 +--- net/tipc/msg.c | 1 + 4 files changed, 18 insertions(+), 45 deletions(-) diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index c02d3e9c156d..0e7ce30fd567 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -67,12 +67,15 @@ config TIPC_LOG managed remotely via TIPC. config TIPC_DEBUG - bool "Enable debug messages" + bool "Enable debugging support" default n help - This enables debugging of TIPC. + Saying Y here enables TIPC debugging capabilities used by developers. + Most users do not need to bother; if unsure, just say N. - Only say Y here if you are having trouble with TIPC. It will - enable the display of detailed information about what is going on. + Enabling debugging support causes TIPC to display data about its + internal state when certain abnormal conditions occur. It also + makes it easy for developers to capture additional information of + interest using the dbg() or msg_dbg() macros. endif # TIPC diff --git a/net/tipc/core.h b/net/tipc/core.h index 3af0b36e3f1a..997158546e25 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -83,6 +83,7 @@ struct print_buf; /* log.h */ * user-defined buffers can be configured to do the same thing. */ extern struct print_buf *const TIPC_NULL; +extern struct print_buf *const TIPC_CONS; extern struct print_buf *const TIPC_LOG; void tipc_printf(struct print_buf *, const char *fmt, ...); @@ -95,56 +96,26 @@ void tipc_printf(struct print_buf *, const char *fmt, ...); #define TIPC_OUTPUT TIPC_LOG #endif -/* - * TIPC can be configured to send system messages to TIPC_OUTPUT - * or to the system console only. - */ - -#ifdef CONFIG_TIPC_DEBUG - #define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ - KERN_ERR "TIPC: " fmt, ## arg) + KERN_ERR "TIPC: " fmt, ## arg) #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ - KERN_WARNING "TIPC: " fmt, ## arg) + KERN_WARNING "TIPC: " fmt, ## arg) #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ - KERN_NOTICE "TIPC: " fmt, ## arg) - -#else + KERN_NOTICE "TIPC: " fmt, ## arg) -#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) -#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) -#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) - -#endif +#ifdef CONFIG_TIPC_DEBUG /* * DBG_OUTPUT is the destination print buffer for debug messages. - * It defaults to the the null print buffer, but can be redefined - * (typically in the individual .c files being debugged) to allow - * selected debug messages to be generated where needed. */ #ifndef DBG_OUTPUT -#define DBG_OUTPUT TIPC_NULL +#define DBG_OUTPUT TIPC_LOG #endif -/* - * TIPC can be configured to send debug messages to the specified print buffer - * (typically DBG_OUTPUT) or to suppress them entirely. - */ - -#ifdef CONFIG_TIPC_DEBUG +#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg); -#define dbg(fmt, arg...) \ - do { \ - if (DBG_OUTPUT != TIPC_NULL) \ - tipc_printf(DBG_OUTPUT, fmt, ## arg); \ - } while (0) -#define msg_dbg(msg, txt) \ - do { \ - if (DBG_OUTPUT != TIPC_NULL) \ - tipc_msg_dbg(DBG_OUTPUT, msg, txt); \ - } while (0) +#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt); void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); @@ -153,7 +124,7 @@ void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); #define dbg(fmt, arg...) do {} while (0) #define msg_dbg(msg, txt) do {} while (0) -#define tipc_msg_dbg(...) do {} while (0) +#define tipc_msg_dbg(buf, msg, txt) do {} while (0) #endif diff --git a/net/tipc/log.c b/net/tipc/log.c index 2796044f9941..952c39f643e6 100644 --- a/net/tipc/log.c +++ b/net/tipc/log.c @@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 }; struct print_buf *const TIPC_NULL = &null_buf; static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; -static struct print_buf *const TIPC_CONS = &cons_buf; +struct print_buf *const TIPC_CONS = &cons_buf; static struct print_buf log_buf = { NULL, 0, NULL, 1 }; struct print_buf *const TIPC_LOG = &log_buf; @@ -76,8 +76,6 @@ struct print_buf *const TIPC_LOG = &log_buf; static char print_string[TIPC_PB_MAX_STR]; static DEFINE_SPINLOCK(print_lock); -static void tipc_printbuf_reset(struct print_buf *pb); -static int tipc_printbuf_empty(struct print_buf *pb); static void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ee6b4c68d4a4..a029cdc2df6d 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -138,6 +138,7 @@ int tipc_msg_build(struct tipc_msg *hdr, void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) { u32 usr = msg_user(msg); + tipc_printf(buf, KERN_DEBUG); tipc_printf(buf, str); switch (usr) { -- cgit v1.2.3-59-g8ed1b From 886ef52a8ce6930a9d0c58267d5b5038ac3e8d30 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:29 +0000 Subject: tipc: remove redundant #includes Eliminates a number of #include statements that no longer serve any useful purpose. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/addr.c | 1 - net/tipc/bcast.c | 1 - net/tipc/bearer.c | 1 - net/tipc/config.c | 1 - net/tipc/core.c | 6 ------ net/tipc/discover.c | 2 -- net/tipc/eth_media.c | 4 ---- net/tipc/msg.c | 1 - net/tipc/name_distr.c | 1 - net/tipc/net.c | 2 -- net/tipc/node.c | 1 - net/tipc/socket.c | 11 ----------- 12 files changed, 32 deletions(-) diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 483868a75b88..88463d9a6f12 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -35,7 +35,6 @@ */ #include "core.h" -#include "node.h" #include "addr.h" /** diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 22a10fadc8c6..c0f3b096e7f5 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -38,7 +38,6 @@ #include "core.h" #include "link.h" #include "port.h" -#include "name_distr.h" #include "bcast.h" #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 24dc6c2c75ad..040f3ed32ec8 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -37,7 +37,6 @@ #include "core.h" #include "config.h" #include "bearer.h" -#include "port.h" #include "discover.h" #define MAX_ADDR_STR 32 diff --git a/net/tipc/config.c b/net/tipc/config.c index a7894ff77ae9..6c67132f8652 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -36,7 +36,6 @@ #include "core.h" #include "port.h" -#include "link.h" #include "name_table.h" #include "config.h" diff --git a/net/tipc/core.c b/net/tipc/core.c index a02bc490caae..60b85ec6d106 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -34,14 +34,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include - #include "core.h" #include "ref.h" -#include "net.h" #include "name_table.h" #include "subscr.h" #include "config.h" diff --git a/net/tipc/discover.c b/net/tipc/discover.c index e7223789d150..be28f5adc770 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -37,8 +37,6 @@ #include "core.h" #include "link.h" #include "discover.h" -#include "port.h" -#include "name_table.h" #define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ #define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index ee683cc8f4b1..101d9cb6a559 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -34,10 +34,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include - #include "core.h" #include "bearer.h" diff --git a/net/tipc/msg.c b/net/tipc/msg.c index a029cdc2df6d..2571ffb4d350 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -35,7 +35,6 @@ */ #include "core.h" -#include "addr.h" #include "msg.h" u32 tipc_msg_tot_importance(struct tipc_msg *m) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 0dd648ec0809..376a30b9fd72 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -35,7 +35,6 @@ */ #include "core.h" -#include "addr.h" #include "link.h" #include "name_distr.h" diff --git a/net/tipc/net.c b/net/tipc/net.c index 6290becd35be..9bacfd00b91e 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -36,10 +36,8 @@ #include "core.h" #include "net.h" -#include "name_table.h" #include "name_distr.h" #include "subscr.h" -#include "link.h" #include "port.h" #include "config.h" diff --git a/net/tipc/node.c b/net/tipc/node.c index fb54719679a6..126d774883dd 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -37,7 +37,6 @@ #include "core.h" #include "config.h" #include "node.h" -#include "port.h" #include "name_distr.h" static void node_lost_contact(struct tipc_node *n_ptr); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 7a21a5ee43e8..f972c0b4a719 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -34,17 +34,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -- cgit v1.2.3-59-g8ed1b From e83504f72456809cdbdbc91700d3ba6370c9da1c Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:30 +0000 Subject: tipc: remove pointless check for NULL prior to kfree It is acceptable to call kfree() with NULL, so these checks are not serving any useful purpose. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/name_distr.c | 4 +--- net/tipc/port.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 376a30b9fd72..a6c989fd4988 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -240,9 +240,7 @@ static void node_is_down(struct publication *publ) publ->type, publ->lower, publ->node, publ->ref, publ->key); } - if (p) { - kfree(p); - } + kfree(p); } /** diff --git a/net/tipc/port.c b/net/tipc/port.c index 8bacd572a9fb..db14b7e0afdc 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -269,9 +269,7 @@ int tipc_deleteport(u32 ref) buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); tipc_nodesub_unsubscribe(&p_ptr->subscription); } - if (p_ptr->user_port) { - kfree(p_ptr->user_port); - } + kfree(p_ptr->user_port); spin_lock_bh(&tipc_port_list_lock); list_del(&p_ptr->port_list); -- cgit v1.2.3-59-g8ed1b From 25860c3bd5bd1db236d4fd5826d76127d677dc28 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 31 Dec 2010 18:59:31 +0000 Subject: tipc: recode getsockopt error handling for better readability The existing code for the copy to user and error handling at the end of getsockopt isn't easy to follow, due to the excessive use of if/else. By simply using return where appropriate, it can be made smaller and easier to follow at the same time. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/socket.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f972c0b4a719..1a2eb23c6223 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1755,20 +1755,16 @@ static int getsockopt(struct socket *sock, release_sock(sk); - if (res) { - /* "get" failed */ - } - else if (len < sizeof(value)) { - res = -EINVAL; - } - else if (copy_to_user(ov, &value, sizeof(value))) { - res = -EFAULT; - } - else { - res = put_user(sizeof(value), ol); - } + if (res) + return res; /* "get" failed */ - return res; + if (len < sizeof(value)) + return -EINVAL; + + if (copy_to_user(ov, &value, sizeof(value))) + return -EFAULT; + + return put_user(sizeof(value), ol); } /** -- cgit v1.2.3-59-g8ed1b From 0e65967e33be61e5f67727edd4ea829b47676fc0 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:32 +0000 Subject: tipc: cleanup various cosmetic whitespace issues Cleans up TIPC's source code to eliminate deviations from generally accepted coding conventions relating to leading/trailing white space and white space around commas, braces, cases, and sizeof. These changes are purely cosmetic and do not alter the operation of TIPC in any way. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/linux/tipc.h | 18 +++++++------- include/linux/tipc_config.h | 59 ++++++++++++++++++++++----------------------- net/tipc/Kconfig | 2 +- net/tipc/bcast.c | 2 +- net/tipc/config.c | 3 +-- net/tipc/discover.c | 2 +- net/tipc/eth_media.c | 5 ++-- net/tipc/link.c | 31 +++++++++++------------- net/tipc/link.h | 4 +-- net/tipc/msg.c | 56 +++++++++++++++++++++--------------------- net/tipc/msg.h | 8 +++--- net/tipc/name_table.c | 14 +++++------ net/tipc/name_table.h | 2 +- net/tipc/node.c | 2 +- net/tipc/port.c | 15 ++++++------ net/tipc/port.h | 2 +- net/tipc/ref.c | 6 ++--- net/tipc/socket.c | 24 +++++++++--------- net/tipc/subscr.c | 2 +- 19 files changed, 124 insertions(+), 133 deletions(-) diff --git a/include/linux/tipc.h b/include/linux/tipc.h index d10614b29d59..1eefa3f6d1f4 100644 --- a/include/linux/tipc.h +++ b/include/linux/tipc.h @@ -1,6 +1,6 @@ /* * include/linux/tipc.h: Include file for TIPC socket interface - * + * * Copyright (c) 2003-2006, Ericsson AB * Copyright (c) 2005, Wind River Systems * All rights reserved. @@ -42,7 +42,7 @@ /* * TIPC addressing primitives */ - + struct tipc_portid { __u32 ref; __u32 node; @@ -89,7 +89,7 @@ static inline unsigned int tipc_node(__u32 addr) #define TIPC_TOP_SRV 1 /* topology service name type */ #define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */ -/* +/* * Publication scopes when binding port names and port name sequences */ @@ -112,7 +112,7 @@ static inline unsigned int tipc_node(__u32 addr) #define TIPC_HIGH_IMPORTANCE 2 #define TIPC_CRITICAL_IMPORTANCE 3 -/* +/* * Msg rejection/connection shutdown reasons */ @@ -127,9 +127,9 @@ static inline unsigned int tipc_node(__u32 addr) * TIPC topology subscription service definitions */ -#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ -#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ -#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ +#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ +#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ +#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ #if 0 /* The following filter options are not currently implemented */ #define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ @@ -137,12 +137,12 @@ static inline unsigned int tipc_node(__u32 addr) #define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */ #endif -#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */ +#define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */ struct tipc_subscr { struct tipc_name_seq seq; /* name sequence of interest */ __u32 timeout; /* subscription duration (in ms) */ - __u32 filter; /* bitmask of filter options */ + __u32 filter; /* bitmask of filter options */ char usr_handle[8]; /* available for subscriber use */ }; diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h index 677aa13dc5d7..7d42460a5e3c 100644 --- a/include/linux/tipc_config.h +++ b/include/linux/tipc_config.h @@ -1,6 +1,6 @@ /* * include/linux/tipc_config.h: Include file for TIPC configuration interface - * + * * Copyright (c) 2003-2006, Ericsson AB * Copyright (c) 2005-2007, Wind River Systems * All rights reserved. @@ -54,19 +54,19 @@ * which specify parameters or results for the operation. * * For many operations, the request and reply messages have a fixed number - * of TLVs (usually zero or one); however, some reply messages may return + * of TLVs (usually zero or one); however, some reply messages may return * a variable number of TLVs. A failed request is denoted by the presence * of an "error string" TLV in the reply message instead of the TLV(s) the * reply should contain if the request succeeds. */ - -/* + +/* * Public commands: * May be issued by any process. - * Accepted by own node, or by remote node only if remote management enabled. + * Accepted by own node, or by remote node only if remote management enabled. */ - -#define TIPC_CMD_NOOP 0x0000 /* tx none, rx none */ + +#define TIPC_CMD_NOOP 0x0000 /* tx none, rx none */ #define TIPC_CMD_GET_NODES 0x0001 /* tx net_addr, rx node_info(s) */ #define TIPC_CMD_GET_MEDIA_NAMES 0x0002 /* tx none, rx media_name(s) */ #define TIPC_CMD_GET_BEARER_NAMES 0x0003 /* tx none, rx bearer_name(s) */ @@ -83,11 +83,11 @@ #define TIPC_CMD_GET_LINK_PEER 0x000D /* tx link_name, rx ? */ #endif -/* +/* * Protected commands: * May only be issued by "network administration capable" process. * Accepted by own node, or by remote node only if remote management enabled - * and this node is zone manager. + * and this node is zone manager. */ #define TIPC_CMD_GET_REMOTE_MNG 0x4003 /* tx none, rx unsigned */ @@ -116,10 +116,10 @@ #define TIPC_CMD_UNBLOCK_LINK 0x4106 /* tx link_name, rx none */ #endif -/* +/* * Private commands: * May only be issued by "network administration capable" process. - * Accepted by own node only; cannot be used on a remote node. + * Accepted by own node only; cannot be used on a remote node. */ #define TIPC_CMD_SET_NODE_ADDR 0x8001 /* tx net_addr, rx none */ @@ -156,20 +156,20 @@ #define TIPC_TLV_ULTRA_STRING 5 /* char[32768] (max) */ #define TIPC_TLV_ERROR_STRING 16 /* char[128] containing "error code" */ -#define TIPC_TLV_NET_ADDR 17 /* 32-bit integer denoting */ +#define TIPC_TLV_NET_ADDR 17 /* 32-bit integer denoting */ #define TIPC_TLV_MEDIA_NAME 18 /* char[TIPC_MAX_MEDIA_NAME] */ #define TIPC_TLV_BEARER_NAME 19 /* char[TIPC_MAX_BEARER_NAME] */ #define TIPC_TLV_LINK_NAME 20 /* char[TIPC_MAX_LINK_NAME] */ #define TIPC_TLV_NODE_INFO 21 /* struct tipc_node_info */ #define TIPC_TLV_LINK_INFO 22 /* struct tipc_link_info */ -#define TIPC_TLV_BEARER_CONFIG 23 /* struct tipc_bearer_config */ -#define TIPC_TLV_LINK_CONFIG 24 /* struct tipc_link_config */ +#define TIPC_TLV_BEARER_CONFIG 23 /* struct tipc_bearer_config */ +#define TIPC_TLV_LINK_CONFIG 24 /* struct tipc_link_config */ #define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */ -#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */ +#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */ /* * Maximum sizes of TIPC bearer-related names (including terminating NUL) - */ + */ #define TIPC_MAX_MEDIA_NAME 16 /* format = media */ #define TIPC_MAX_IF_NAME 16 /* format = interface */ @@ -234,7 +234,7 @@ struct tipc_name_table_query { }; /* - * The error string TLV is a null-terminated string describing the cause + * The error string TLV is a null-terminated string describing the cause * of the request failure. To simplify error processing (and to save space) * the first character of the string can be a special error code character * (lying by the range 0x80 to 0xFF) which represents a pre-defined reason. @@ -258,7 +258,7 @@ struct tipc_link_create { /* * A TLV consists of a descriptor, followed by the TLV value. - * TLV descriptor fields are stored in network byte order; + * TLV descriptor fields are stored in network byte order; * TLV values must also be stored in network byte order (where applicable). * TLV descriptors must be aligned to addresses which are multiple of 4, * so up to 3 bytes of padding may exist at the end of the TLV value area. @@ -294,7 +294,7 @@ static inline int TLV_OK(const void *tlv, __u16 space) static inline int TLV_CHECK(const void *tlv, __u16 space, __u16 exp_type) { - return TLV_OK(tlv, space) && + return TLV_OK(tlv, space) && (ntohs(((struct tlv_desc *)tlv)->tlv_type) == exp_type); } @@ -313,7 +313,7 @@ static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len) } /* - * A TLV list descriptor simplifies processing of messages + * A TLV list descriptor simplifies processing of messages * containing multiple TLVs. */ @@ -322,15 +322,15 @@ struct tlv_list_desc { __u32 tlv_space; /* # bytes from curr TLV to list end */ }; -static inline void TLV_LIST_INIT(struct tlv_list_desc *list, +static inline void TLV_LIST_INIT(struct tlv_list_desc *list, void *data, __u32 space) { list->tlv_ptr = (struct tlv_desc *)data; list->tlv_space = space; } - + static inline int TLV_LIST_EMPTY(struct tlv_list_desc *list) -{ +{ return (list->tlv_space == 0); } @@ -348,7 +348,7 @@ static inline void TLV_LIST_STEP(struct tlv_list_desc *list) { __u16 tlv_space = TLV_ALIGN(ntohs(list->tlv_ptr->tlv_len)); - list->tlv_ptr = (struct tlv_desc *)((char *)list->tlv_ptr + tlv_space); + list->tlv_ptr = (struct tlv_desc *)((char *)list->tlv_ptr + tlv_space); list->tlv_space -= tlv_space; } @@ -372,15 +372,14 @@ struct tipc_genlmsghdr { #define TIPC_GENL_HDRLEN NLMSG_ALIGN(sizeof(struct tipc_genlmsghdr)) /* - * Configuration messages exchanged via TIPC sockets use the TIPC configuration - * message header, which is defined below. This structure is analogous - * to the Netlink message header, but fields are stored in network byte order - * and no padding is permitted between the header and the message data + * Configuration messages exchanged via TIPC sockets use the TIPC configuration + * message header, which is defined below. This structure is analogous + * to the Netlink message header, but fields are stored in network byte order + * and no padding is permitted between the header and the message data * that follows. */ -struct tipc_cfg_msg_hdr -{ +struct tipc_cfg_msg_hdr { __be32 tcm_len; /* Message length (including header) */ __be16 tcm_type; /* Command type */ __be16 tcm_flags; /* Additional flags */ diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index 0e7ce30fd567..0436927369f3 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -50,7 +50,7 @@ config TIPC_PORTS Specifies how many ports can be supported by a node. Can range from 127 to 65535 ports; default is 8191. - Setting this to a smaller value saves some memory, + Setting this to a smaller value saves some memory, setting it to higher allows for more ports. config TIPC_LOG diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index c0f3b096e7f5..9de32564984a 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -428,7 +428,7 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) static int rx_count = 0; #endif struct tipc_msg *msg = buf_msg(buf); - struct tipc_node* node = tipc_node_find(msg_prevnode(msg)); + struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); u32 next_in; u32 seqno; struct sk_buff *deferred; diff --git a/net/tipc/config.c b/net/tipc/config.c index 6c67132f8652..e16750dcf3c1 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -322,8 +322,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area } else if (!tipc_remote_management) { rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE); goto exit; - } - else if (cmd >= 0x4000) { + } else if (cmd >= 0x4000) { u32 domain = 0; if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || diff --git a/net/tipc/discover.c b/net/tipc/discover.c index be28f5adc770..fa026bd91a68 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -130,7 +130,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) u32 net_id = msg_bc_netid(msg); u32 type = msg_type(msg); - msg_get_media_addr(msg,&media_addr); + msg_get_media_addr(msg, &media_addr); buf_discard(buf); if (net_id != tipc_net_id) diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 101d9cb6a559..5dfe66357794 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -144,7 +144,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) /* Find device with specified name */ - for_each_netdev(&init_net, pdev){ + for_each_netdev(&init_net, pdev) { if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { dev = pdev; break; @@ -155,7 +155,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) /* Find Ethernet bearer for device (or create one) */ - for (;(eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev); eb_ptr++); + while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev)) + eb_ptr++; if (eb_ptr == stop) return -EDQUOT; if (!eb_ptr->dev) { diff --git a/net/tipc/link.c b/net/tipc/link.c index 647f2ecfde50..ef203a1581cd 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -977,8 +977,7 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf, l_ptr->next_out = buf; return res; } - } - else + } else *used_max_pkt = l_ptr->max_pkt; } return tipc_link_send_buf(l_ptr, buf); /* All other cases */ @@ -1132,10 +1131,10 @@ static int link_send_sections_long(struct port *sender, struct tipc_node *node; struct tipc_msg *hdr = &sender->publ.phdr; u32 dsz = msg_data_sz(hdr); - u32 max_pkt,fragm_sz,rest; + u32 max_pkt, fragm_sz, rest; struct tipc_msg fragm_hdr; - struct sk_buff *buf,*buf_chain,*prev; - u32 fragm_crs,fragm_rest,hsz,sect_rest; + struct sk_buff *buf, *buf_chain, *prev; + u32 fragm_crs, fragm_rest, hsz, sect_rest; const unchar *sect_crs; int curr_sect; u32 fragm_no; @@ -1212,7 +1211,7 @@ error: /* Initiate new fragment: */ if (rest <= fragm_sz) { fragm_sz = rest; - msg_set_type(&fragm_hdr,LAST_FRAGMENT); + msg_set_type(&fragm_hdr, LAST_FRAGMENT); } else { msg_set_type(&fragm_hdr, FRAGMENT); } @@ -1229,8 +1228,7 @@ error: fragm_crs = INT_H_SIZE; fragm_rest = fragm_sz; } - } - while (rest > 0); + } while (rest > 0); /* * Now we have a buffer chain. Select a link and check @@ -1333,7 +1331,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) buf = l_ptr->proto_msg_queue; if (buf) { msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); + msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { l_ptr->unacked_window = 0; buf_discard(buf); @@ -1847,8 +1845,7 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, } prev = crs; crs = crs->next; - } - while (crs); + } while (crs); /* Message is a duplicate of an existing message */ @@ -2215,11 +2212,11 @@ void tipc_link_changeover(struct link *l_ptr) if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { struct tipc_msg *m = msg_get_wrapped(msg); - unchar* pos = (unchar*)m; + unchar *pos = (unchar *)m; msgcount = msg_msgcnt(msg); while (msgcount--) { - msg_set_seqno(m,msg_seqno(msg)); + msg_set_seqno(m, msg_seqno(msg)); tipc_link_tunnel(l_ptr, &tunnel_hdr, m, msg_link_selector(m)); pos += align(msg_size(m)); @@ -2321,7 +2318,7 @@ static int link_recv_changeover_msg(struct link **l_ptr, if (msg_typ == DUPLICATE_MSG) { if (less(msg_seqno(msg), mod(dest_link->next_in_no))) goto exit; - *buf = buf_extract(tunnel_buf,INT_H_SIZE); + *buf = buf_extract(tunnel_buf, INT_H_SIZE); if (*buf == NULL) { warn("Link changeover error, duplicate msg dropped\n"); goto exit; @@ -2552,8 +2549,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, /* Prepare buffer for subsequent fragments. */ set_long_msg_seqno(pbuf, long_msg_seq_no); - set_fragm_size(pbuf,fragm_sz); - set_expected_frags(pbuf,exp_fragm_cnt - 1); + set_fragm_size(pbuf, fragm_sz); + set_expected_frags(pbuf, exp_fragm_cnt - 1); } else { warn("Link unable to reassemble fragmented message\n"); } @@ -2580,7 +2577,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, *m = buf_msg(pbuf); return 1; } - set_expected_frags(pbuf,exp_frags); + set_expected_frags(pbuf, exp_frags); return 0; } buf_discard(fbuf); diff --git a/net/tipc/link.h b/net/tipc/link.h index eca19c247b79..70967e637027 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -229,8 +229,8 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_ void tipc_link_reset(struct link *l_ptr); int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); -u32 tipc_link_get_max_pkt(u32 dest,u32 selector); -int tipc_link_send_sections_fast(struct port* sender, +u32 tipc_link_get_max_pkt(u32 dest, u32 selector); +int tipc_link_send_sections_fast(struct port *sender, struct iovec const *msg_sect, const u32 num_sect, u32 destnode); diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 2571ffb4d350..e81d43a8ea3d 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -91,7 +91,7 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, - int max_size, int usrmem, struct sk_buff** buf) + int max_size, int usrmem, struct sk_buff **buf) { int dsz, sz, hsz, pos, res, cnt; @@ -161,10 +161,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "LAST:"); break; default: - tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); } - tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), + tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg), msg_fragm_no(msg)); break; case TIPC_LOW_IMPORTANCE: @@ -190,7 +190,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "DIR:"); break; default: - tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); } if (msg_routed(msg) && !msg_non_seq(msg)) tipc_printf(buf, "ROUT:"); @@ -208,7 +208,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "WDRW:"); break; default: - tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); } if (msg_routed(msg)) tipc_printf(buf, "ROUT:"); @@ -227,39 +227,39 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) break; case CONN_ACK: tipc_printf(buf, "CONN_ACK:"); - tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); + tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg)); break; default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); } if (msg_routed(msg)) tipc_printf(buf, "ROUT:"); if (msg_reroute_cnt(msg)) - tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); + tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); break; case LINK_PROTOCOL: - tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg)); + tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg)); switch (msg_type(msg)) { case STATE_MSG: tipc_printf(buf, "STATE:"); - tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); - tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); - tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); - tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); + tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : ""); + tipc_printf(buf, "NXS(%u):", msg_next_sent(msg)); + tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg)); + tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg)); break; case RESET_MSG: tipc_printf(buf, "RESET:"); if (msg_size(msg) != msg_hdr_sz(msg)) - tipc_printf(buf, "BEAR:%s:",msg_data(msg)); + tipc_printf(buf, "BEAR:%s:", msg_data(msg)); break; case ACTIVATE_MSG: tipc_printf(buf, "ACTIVATE:"); break; default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); } - tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); - tipc_printf(buf, "SESS(%u):",msg_session(msg)); + tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg)); + tipc_printf(buf, "SESS(%u):", msg_session(msg)); break; case CHANGEOVER_PROTOCOL: tipc_printf(buf, "TUNL:"); @@ -269,10 +269,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) break; case ORIGINAL_MSG: tipc_printf(buf, "ORIG:"); - tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); + tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg)); break; default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); } break; case ROUTE_DISTRIBUTOR: @@ -280,26 +280,26 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) switch (msg_type(msg)) { case EXT_ROUTING_TABLE: tipc_printf(buf, "EXT_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); + tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); break; case LOCAL_ROUTING_TABLE: tipc_printf(buf, "LOCAL_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); + tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); break; case SLAVE_ROUTING_TABLE: tipc_printf(buf, "DP_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); + tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); break; case ROUTE_ADDITION: tipc_printf(buf, "ADD:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); + tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); break; case ROUTE_REMOVAL: tipc_printf(buf, "REMOVE:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); + tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); break; default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); } break; case LINK_CONFIG: @@ -312,7 +312,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "DSC_RESP:"); break; default: - tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); + tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg)); break; } break; @@ -393,8 +393,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) } if (msg_user(msg) == LINK_CONFIG) { - u32* raw = (u32*)msg; - struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; + u32 *raw = (u32 *)msg; + struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5]; tipc_printf(buf, ":REQL(%u):", msg_req_links(msg)); tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 68b65ef3e74b..92c4c4fd7b3f 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -174,7 +174,7 @@ static inline u32 msg_hdr_sz(struct tipc_msg *m) return msg_bits(m, 0, 21, 0xf) << 2; } -static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) +static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n) { msg_set_bits(m, 0, 21, 0xf, n>>2); } @@ -425,7 +425,7 @@ static inline u32 msg_routed(struct tipc_msg *m) { if (likely(msg_short(m))) return 0; - return(msg_destnode(m) ^ msg_orignode(m)) >> 11; + return (msg_destnode(m) ^ msg_orignode(m)) >> 11; } static inline u32 msg_nametype(struct tipc_msg *m) @@ -863,7 +863,7 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, - int max_size, int usrmem, struct sk_buff** buf); + int max_size, int usrmem, struct sk_buff **buf); static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) { @@ -872,7 +872,7 @@ static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) { - memcpy(a, &((int*)m)[5], sizeof(*a)); + memcpy(a, &((int *)m)[5], sizeof(*a)); } #endif diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index ddc2ad4c2d32..46b2f31f96a1 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -296,8 +296,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, sseq = &nseq->sseqs[inspos]; freesseq = &nseq->sseqs[nseq->first_free]; - memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq)); - memset(sseq, 0, sizeof (*sseq)); + memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq)); + memset(sseq, 0, sizeof(*sseq)); nseq->first_free++; sseq->lower = lower; sseq->upper = upper; @@ -471,7 +471,7 @@ end_node: if (!sseq->zone_list) { free = &nseq->sseqs[nseq->first_free--]; - memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); + memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); removed_subseq = 1; } @@ -507,7 +507,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s while (sseq != &nseq->sseqs[nseq->first_free]) { struct publication *zl = sseq->zone_list; - if (zl && tipc_subscr_overlap(s,sseq->lower,sseq->upper)) { + if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { struct publication *crs = zl; int must_report = 1; @@ -798,7 +798,7 @@ void tipc_nametbl_subscribe(struct subscription *s) if (!seq) { seq = tipc_nameseq_create(type, &table.types[hash(type)]); } - if (seq){ + if (seq) { spin_lock_bh(&seq->lock); tipc_nameseq_subscribe(seq, s); spin_unlock_bh(&seq->lock); @@ -819,7 +819,7 @@ void tipc_nametbl_unsubscribe(struct subscription *s) write_lock_bh(&tipc_nametbl_lock); seq = nametbl_find_seq(s->seq.type); - if (seq != NULL){ + if (seq != NULL) { spin_lock_bh(&seq->lock); list_del_init(&s->nameseq_list); spin_unlock_bh(&seq->lock); @@ -852,7 +852,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, } do { - sprintf (portIdStr, "<%u.%u.%u:%u>", + sprintf(portIdStr, "<%u.%u.%u:%u>", tipc_zone(publ->node), tipc_cluster(publ->node), tipc_node(publ->node), publ->ref); tipc_printf(buf, "%-26s ", portIdStr); diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index 139882d4ed00..d228bd682655 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h @@ -46,7 +46,7 @@ struct port_list; * TIPC name types reserved for internal TIPC use (both current and planned) */ -#define TIPC_ZM_SRV 3 /* zone master service name type */ +#define TIPC_ZM_SRV 3 /* zone master service name type */ /** diff --git a/net/tipc/node.c b/net/tipc/node.c index 126d774883dd..2ed162f91a08 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -334,7 +334,7 @@ static void node_lost_contact(struct tipc_node *n_ptr) /* Clean up broadcast reception remains */ n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; while (n_ptr->bclink.deferred_head) { - struct sk_buff* buf = n_ptr->bclink.deferred_head; + struct sk_buff *buf = n_ptr->bclink.deferred_head; n_ptr->bclink.deferred_head = buf->next; buf_discard(buf); } diff --git a/net/tipc/port.c b/net/tipc/port.c index db14b7e0afdc..78fcb75bb082 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -54,8 +54,8 @@ static DEFINE_SPINLOCK(queue_lock); static LIST_HEAD(ports); static void port_handle_node_down(unsigned long ref); -static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err); -static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err); +static struct sk_buff *port_build_self_abort_msg(struct port *, u32 err); +static struct sk_buff *port_build_peer_abort_msg(struct port *, u32 err); static void port_timeout(unsigned long ref); @@ -155,7 +155,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) { - struct tipc_msg* msg; + struct tipc_msg *msg; struct port_list dports = {0, NULL, }; struct port_list *item = dp; int cnt = 0; @@ -193,7 +193,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) if ((index == 0) && (cnt != 0)) { item = item->next; } - msg_set_destport(buf_msg(b),item->ports[index]); + msg_set_destport(buf_msg(b), item->ports[index]); tipc_port_recv_msg(b); } } @@ -484,7 +484,7 @@ static void port_timeout(unsigned long ref) static void port_handle_node_down(unsigned long ref) { struct port *p_ptr = tipc_port_lock(ref); - struct sk_buff* buf = NULL; + struct sk_buff *buf = NULL; if (!p_ptr) return; @@ -620,8 +620,7 @@ static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) tipc_printf(buf, " via {%u,%u}", p_ptr->publ.conn_type, p_ptr->publ.conn_instance); - } - else if (p_ptr->publ.published) { + } else if (p_ptr->publ.published) { tipc_printf(buf, " bound to"); list_for_each_entry(publ, &p_ptr->publications, pport_list) { if (publ->lower == publ->upper) @@ -1099,7 +1098,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) p_ptr->publ.connected = 1; k_start_timer(&p_ptr->timer, p_ptr->probing_interval); - tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, + tipc_nodesub_subscribe(&p_ptr->subscription, peer->node, (void *)(unsigned long)ref, (net_ev_handler)port_handle_node_down); res = 0; diff --git a/net/tipc/port.h b/net/tipc/port.h index a9c528799f2f..8e84b989949c 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -258,7 +258,7 @@ static inline void tipc_port_unlock(struct port *p_ptr) spin_unlock_bh(p_ptr->publ.lock); } -static inline struct port* tipc_port_deref(u32 ref) +static inline struct port *tipc_port_deref(u32 ref) { return (struct port *)tipc_ref_deref(ref); } diff --git a/net/tipc/ref.c b/net/tipc/ref.c index ab8ad32d8c20..3974529a66e7 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -178,14 +178,12 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) next_plus_upper = entry->ref; tipc_ref_table.first_free = next_plus_upper & index_mask; ref = (next_plus_upper & ~index_mask) + index; - } - else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { + } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { index = tipc_ref_table.init_point++; entry = &(tipc_ref_table.entries[index]); spin_lock_init(&entry->lock); ref = tipc_ref_table.start_mask + index; - } - else { + } else { ref = 0; } write_unlock_bh(&ref_table_lock); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1a2eb23c6223..e9fc5df79eb0 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -375,7 +375,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) * * NOTE: This routine doesn't need to take the socket lock since it only * accesses socket information that is unchanging (or which changes in - * a completely predictable manner). + * a completely predictable manner). */ static int get_name(struct socket *sock, struct sockaddr *uaddr, @@ -570,14 +570,12 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, dest->addr.name.domain, m->msg_iovlen, m->msg_iov); - } - else if (dest->addrtype == TIPC_ADDR_ID) { + } else if (dest->addrtype == TIPC_ADDR_ID) { res = tipc_send2port(tport->ref, &dest->addr.id, m->msg_iovlen, m->msg_iov); - } - else if (dest->addrtype == TIPC_ADDR_MCAST) { + } else if (dest->addrtype == TIPC_ADDR_MCAST) { if (needs_conn) { res = -EOPNOTSUPP; break; @@ -812,8 +810,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) addr->addrtype = TIPC_ADDR_ID; addr->addr.id.ref = msg_origport(msg); addr->addr.id.node = msg_orignode(msg); - addr->addr.name.domain = 0; /* could leave uninitialized */ - addr->scope = 0; /* could leave uninitialized */ + addr->addr.name.domain = 0; /* could leave uninitialized */ + addr->scope = 0; /* could leave uninitialized */ m->msg_namelen = sizeof(struct sockaddr_tipc); } } @@ -1743,10 +1741,10 @@ static int getsockopt(struct socket *sock, value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); /* no need to set "res", since already 0 at this point */ break; - case TIPC_NODE_RECVQ_DEPTH: + case TIPC_NODE_RECVQ_DEPTH: value = (u32)atomic_read(&tipc_queue_size); break; - case TIPC_SOCK_RECVQ_DEPTH: + case TIPC_SOCK_RECVQ_DEPTH: value = skb_queue_len(&sk->sk_receive_queue); break; default: @@ -1772,7 +1770,7 @@ static int getsockopt(struct socket *sock, */ static const struct proto_ops msg_ops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .family = AF_TIPC, .release = release, .bind = bind, @@ -1793,7 +1791,7 @@ static const struct proto_ops msg_ops = { }; static const struct proto_ops packet_ops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .family = AF_TIPC, .release = release, .bind = bind, @@ -1814,7 +1812,7 @@ static const struct proto_ops packet_ops = { }; static const struct proto_ops stream_ops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .family = AF_TIPC, .release = release, .bind = bind, @@ -1835,7 +1833,7 @@ static const struct proto_ops stream_ops = { }; static const struct net_proto_family tipc_family_ops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .family = AF_TIPC, .create = tipc_create }; diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 510271152165..acc30e1833c9 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -538,7 +538,7 @@ int tipc_subscr_start(void) struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; int res; - memset(&topsrv, 0, sizeof (topsrv)); + memset(&topsrv, 0, sizeof(topsrv)); spin_lock_init(&topsrv.lock); INIT_LIST_HEAD(&topsrv.subscriber_list); -- cgit v1.2.3-59-g8ed1b From 2db9983a4318818845193bd577879c0620705e82 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:33 +0000 Subject: tipc: split variable assignments out of conditional expressions Cleans up TIPC's source code to eliminate assigning values to variables within conditional expressions, improving code readability and reducing warnings from various code checker tools. These changes are purely cosmetic and do not alter the operation of TIPC in any way. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bearer.c | 3 ++- net/tipc/core.c | 33 +++++++++++++++++++++------------ net/tipc/link.c | 16 ++++++++++------ net/tipc/socket.c | 36 +++++++++++++++++++++++------------- 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 040f3ed32ec8..e9136f0abe60 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -251,7 +251,8 @@ static int bearer_name_validate(const char *name, /* ensure all component parts of bearer name are present */ media_name = name_copy; - if ((if_name = strchr(media_name, ':')) == NULL) + if_name = strchr(media_name, ':'); + if (if_name == NULL) return 0; *(if_name++) = 0; media_len = if_name - media_name; diff --git a/net/tipc/core.c b/net/tipc/core.c index 60b85ec6d106..e071579e0850 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -115,10 +115,11 @@ int tipc_core_start_net(unsigned long addr) { int res; - if ((res = tipc_net_start(addr)) || - (res = tipc_eth_media_start())) { + res = tipc_net_start(addr); + if (!res) + res = tipc_eth_media_start(); + if (res) tipc_core_stop_net(); - } return res; } @@ -157,15 +158,22 @@ static int tipc_core_start(void) get_random_bytes(&tipc_random, sizeof(tipc_random)); tipc_mode = TIPC_NODE_MODE; - if ((res = tipc_handler_start()) || - (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || - (res = tipc_nametbl_init()) || - (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || - (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || - (res = tipc_netlink_start()) || - (res = tipc_socket_init())) { + res = tipc_handler_start(); + if (!res) + res = tipc_ref_table_init(tipc_max_ports, tipc_random); + if (!res) + res = tipc_nametbl_init(); + if (!res) + res = tipc_k_signal((Handler)tipc_subscr_start, 0); + if (!res) + res = tipc_k_signal((Handler)tipc_cfg_init, 0); + if (!res) + res = tipc_netlink_start(); + if (!res) + res = tipc_socket_init(); + if (res) tipc_core_stop(); - } + return res; } @@ -188,7 +196,8 @@ static int __init tipc_init(void) tipc_max_nodes = CONFIG_TIPC_NODES; tipc_net_id = 4711; - if ((res = tipc_core_start())) + res = tipc_core_start(); + if (res) err("Unable to start in single node mode\n"); else info("Started in single node mode\n"); diff --git a/net/tipc/link.c b/net/tipc/link.c index ef203a1581cd..de9d49108d41 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -187,14 +187,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts) /* ensure all component parts of link name are present */ addr_local = name_copy; - if ((if_local = strchr(addr_local, ':')) == NULL) + if_local = strchr(addr_local, ':'); + if (if_local == NULL) return 0; *(if_local++) = 0; - if ((addr_peer = strchr(if_local, '-')) == NULL) + addr_peer = strchr(if_local, '-'); + if (addr_peer == NULL) return 0; *(addr_peer++) = 0; if_local_len = addr_peer - if_local; - if ((if_peer = strchr(addr_peer, ':')) == NULL) + if_peer = strchr(addr_peer, ':'); + if (if_peer == NULL) return 0; *(if_peer++) = 0; if_peer_len = strlen(if_peer) + 1; @@ -2044,8 +2047,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); - if ((msg_tol = msg_link_tolerance(msg)) && - (msg_tol > l_ptr->tolerance)) + msg_tol = msg_link_tolerance(msg); + if (msg_tol > l_ptr->tolerance) link_set_supervision_props(l_ptr, msg_tol); if (msg_linkprio(msg) > l_ptr->priority) @@ -2074,7 +2077,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) break; case STATE_MSG: - if ((msg_tol = msg_link_tolerance(msg))) + msg_tol = msg_link_tolerance(msg); + if (msg_tol) link_set_supervision_props(l_ptr, msg_tol); if (msg_linkprio(msg) && diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e9fc5df79eb0..0895dec2967c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -563,7 +563,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, do { if (dest->addrtype == TIPC_ADDR_NAME) { - if ((res = dest_name_check(dest, m))) + res = dest_name_check(dest, m); + if (res) break; res = tipc_send2name(tport->ref, &dest->addr.name.name, @@ -580,7 +581,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, res = -EOPNOTSUPP; break; } - if ((res = dest_name_check(dest, m))) + res = dest_name_check(dest, m); + if (res) break; res = tipc_multicast(tport->ref, &dest->addr.nameseq, @@ -750,7 +752,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, bytes_to_send = curr_left; my_iov.iov_base = curr_start; my_iov.iov_len = bytes_to_send; - if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { + res = send_packet(NULL, sock, &my_msg, 0); + if (res < 0) { if (bytes_sent) res = bytes_sent; goto exit; @@ -845,12 +848,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, if (unlikely(err)) { anc_data[0] = err; anc_data[1] = msg_data_sz(msg); - if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) - return res; - if (anc_data[1] && - (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], - msg_data(msg)))) + res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data); + if (res) return res; + if (anc_data[1]) { + res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], + msg_data(msg)); + if (res) + return res; + } } /* Optionally capture message destination object */ @@ -878,9 +884,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, default: has_name = 0; } - if (has_name && - (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) - return res; + if (has_name) { + res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data); + if (res) + return res; + } return 0; } @@ -1664,7 +1672,8 @@ static int setsockopt(struct socket *sock, return -ENOPROTOOPT; if (ol < sizeof(value)) return -EINVAL; - if ((res = get_user(value, (u32 __user *)ov))) + res = get_user(value, (u32 __user *)ov); + if (res) return res; lock_sock(sk); @@ -1722,7 +1731,8 @@ static int getsockopt(struct socket *sock, return put_user(0, ol); if (lvl != SOL_TIPC) return -ENOPROTOOPT; - if ((res = get_user(len, ol))) + res = get_user(len, ol); + if (res) return res; lock_sock(sk); -- cgit v1.2.3-59-g8ed1b From e3ec9c7d5eea9adf2c604c623c987360cc700b88 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:34 +0000 Subject: tipc: remove zeroing assignments to static global variables Cleans up TIPC's source code to eliminate the needless initialization of static variables to zero. These changes are purely cosmetic and do not alter the operation of TIPC in any way. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 8 ++++---- net/tipc/bearer.c | 2 +- net/tipc/eth_media.c | 2 +- net/tipc/handler.c | 2 +- net/tipc/name_distr.c | 2 +- net/tipc/name_table.c | 2 +- net/tipc/node.c | 2 +- net/tipc/port.c | 4 ++-- net/tipc/ref.c | 2 +- net/tipc/socket.c | 2 +- net/tipc/subscr.c | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 9de32564984a..99a1469e300a 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -103,9 +103,9 @@ struct bclink { }; -static struct bcbearer *bcbearer = NULL; -static struct bclink *bclink = NULL; -static struct link *bcl = NULL; +static struct bcbearer *bcbearer; +static struct bclink *bclink; +static struct link *bcl; static DEFINE_SPINLOCK(bc_lock); /* broadcast-capable node map */ @@ -425,7 +425,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf) void tipc_bclink_recv_pkt(struct sk_buff *buf) { #if (TIPC_BCAST_LOSS_RATE) - static int rx_count = 0; + static int rx_count; #endif struct tipc_msg *msg = buf_msg(buf); struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index e9136f0abe60..68e729045424 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -42,7 +42,7 @@ #define MAX_ADDR_STR 32 static struct media media_list[MAX_MEDIA]; -static u32 media_count = 0; +static u32 media_count; struct bearer tipc_bearers[MAX_BEARERS]; diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 5dfe66357794..b69092eb95d8 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -56,7 +56,7 @@ struct eth_bearer { }; static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; -static int eth_started = 0; +static int eth_started; static struct notifier_block notifier; /** diff --git a/net/tipc/handler.c b/net/tipc/handler.c index 0c70010a7dfe..274c98e164b7 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c @@ -45,7 +45,7 @@ struct queue_item { static struct kmem_cache *tipc_queue_item_cache; static struct list_head signal_queue_head; static DEFINE_SPINLOCK(qitem_lock); -static int handler_enabled = 0; +static int handler_enabled; static void process_signal_queue(unsigned long dummy); diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index a6c989fd4988..483c226c9581 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -73,7 +73,7 @@ struct distr_item { */ static LIST_HEAD(publ_root); -static u32 publ_cnt = 0; +static u32 publ_cnt; /** * publ_to_item - add publication info to a publication message diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 46b2f31f96a1..ea3e94e9d939 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -104,7 +104,7 @@ struct name_table { u32 local_publ_count; }; -static struct name_table table = { NULL } ; +static struct name_table table; static atomic_t rsv_publ_ok = ATOMIC_INIT(0); DEFINE_RWLOCK(tipc_nametbl_lock); diff --git a/net/tipc/node.c b/net/tipc/node.c index 2ed162f91a08..3af53e327f49 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -44,7 +44,7 @@ static void node_established_contact(struct tipc_node *n_ptr); static DEFINE_SPINLOCK(node_create_lock); -u32 tipc_own_tag = 0; +u32 tipc_own_tag; /** * tipc_node_create - create neighboring node diff --git a/net/tipc/port.c b/net/tipc/port.c index 78fcb75bb082..c23f3380d0a7 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -46,8 +46,8 @@ #define MAX_REJECT_SIZE 1024 -static struct sk_buff *msg_queue_head = NULL; -static struct sk_buff *msg_queue_tail = NULL; +static struct sk_buff *msg_queue_head; +static struct sk_buff *msg_queue_tail; DEFINE_SPINLOCK(tipc_port_list_lock); static DEFINE_SPINLOCK(queue_lock); diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 3974529a66e7..83116892528b 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -89,7 +89,7 @@ struct ref_table { * have a reference value of 0 (although this is unlikely). */ -static struct ref_table tipc_ref_table = { NULL }; +static struct ref_table tipc_ref_table; static DEFINE_RWLOCK(ref_table_lock); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 0895dec2967c..18aad573f551 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -68,7 +68,7 @@ static const struct proto_ops msg_ops; static struct proto tipc_proto; -static int sockets_enabled = 0; +static int sockets_enabled; static atomic_t tipc_queue_size = ATOMIC_INIT(0); diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index acc30e1833c9..ca04479c3d42 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -70,7 +70,7 @@ struct top_srv { spinlock_t lock; }; -static struct top_srv topsrv = { 0 }; +static struct top_srv topsrv; /** * htohl - convert value to endianness used by destination -- cgit v1.2.3-59-g8ed1b From a016892cd6eb8d3dd9769021b088917ac7371abd Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 31 Dec 2010 18:59:35 +0000 Subject: tipc: remove extraneous braces from single statements Cleans up TIPC's source code to eliminate the presence of unnecessary use of {} around single statements. These changes are purely cosmetic and do not alter the operation of TIPC in any way. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 6 ++---- net/tipc/bearer.c | 3 +-- net/tipc/link.c | 25 +++++++++---------------- net/tipc/msg.c | 15 ++++++--------- net/tipc/name_table.c | 6 ++---- net/tipc/port.c | 6 ++---- net/tipc/socket.c | 14 +++++--------- 7 files changed, 27 insertions(+), 48 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 99a1469e300a..70ab5ef48766 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -196,9 +196,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to) struct sk_buff *buf; buf = bcl->first_out; - while (buf && less_eq(buf_seqno(buf), after)) { + while (buf && less_eq(buf_seqno(buf), after)) buf = buf->next; - } tipc_link_retransmit(bcl, buf, mod(to - after)); } @@ -224,9 +223,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) /* Skip over packets that node has previously acknowledged */ crs = bcl->first_out; - while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { + while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) crs = crs->next; - } /* Update packets that node is now acknowledging */ diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 68e729045424..837b7a467885 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -194,9 +194,8 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) unchar *addr = (unchar *)&a->dev_addr; tipc_printf(pb, "UNKNOWN(%u)", media_type); - for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { + for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) tipc_printf(pb, "-%02x", addr[i]); - } } } diff --git a/net/tipc/link.c b/net/tipc/link.c index de9d49108d41..18702f58d111 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -615,9 +615,8 @@ static void link_state_event(struct link *l_ptr, unsigned event) return; /* Not yet. */ if (link_blocked(l_ptr)) { - if (event == TIMEOUT_EVT) { + if (event == TIMEOUT_EVT) link_set_timer(l_ptr, cont_intv); - } return; /* Changeover going on */ } @@ -940,11 +939,10 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) if (n_ptr) { tipc_node_lock(n_ptr); l_ptr = n_ptr->active_links[selector & 1]; - if (l_ptr) { + if (l_ptr) res = tipc_link_send_buf(l_ptr, buf); - } else { + else buf_discard(buf); - } tipc_node_unlock(n_ptr); } else { buf_discard(buf); @@ -1626,9 +1624,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) /* Ensure message data is a single contiguous unit */ - if (unlikely(buf_linearize(buf))) { + if (unlikely(buf_linearize(buf))) goto cont; - } /* Handle arrival of a non-unicast link message */ @@ -1843,9 +1840,8 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, *head = buf; return 1; } - if (seq_no == msg_seqno(msg)) { + if (seq_no == msg_seqno(msg)) break; - } prev = crs; crs = crs->next; } while (crs); @@ -1959,11 +1955,10 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, msg_set_max_pkt(msg, l_ptr->max_pkt_target); } - if (tipc_node_has_redundant_links(l_ptr->owner)) { + if (tipc_node_has_redundant_links(l_ptr->owner)) msg_set_redundant_link(msg); - } else { + else msg_clear_redundant_link(msg); - } msg_set_linkprio(msg, l_ptr->priority); /* Ensure sequence number will not fit : */ @@ -2071,9 +2066,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) l_ptr->peer_bearer_id = msg_bearer_id(msg); /* Synchronize broadcast sequence numbers */ - if (!tipc_node_has_redundant_links(l_ptr->owner)) { + if (!tipc_node_has_redundant_links(l_ptr->owner)) l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); - } break; case STATE_MSG: @@ -2108,9 +2102,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) max_pkt_ack = 0; if (msg_probe(msg)) { l_ptr->stats.recv_probes++; - if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { + if (msg_size(msg) > sizeof(l_ptr->proto_msg)) max_pkt_ack = msg_size(msg); - } } /* Protocol message before retransmits, reduce loss risk */ diff --git a/net/tipc/msg.c b/net/tipc/msg.c index e81d43a8ea3d..bb6180c4fcbb 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -348,7 +348,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "UNKNOWN ERROR(%x):", msg_errcode(msg)); } - default:{} + default: + break; } tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); @@ -357,9 +358,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) if (msg_non_seq(msg)) tipc_printf(buf, "NOSEQ:"); - else { + else tipc_printf(buf, "ACK(%u):", msg_ack(msg)); - } tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); @@ -387,9 +387,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) if (msg_user(msg) == NAME_DISTRIBUTOR) { tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); - if (msg_routed(msg)) { + if (msg_routed(msg)) tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg)); - } } if (msg_user(msg) == LINK_CONFIG) { @@ -405,12 +404,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); } tipc_printf(buf, "\n"); - if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { + if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); - } - if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { + if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); - } } #endif diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index ea3e94e9d939..205ed4a4e186 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -751,9 +751,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, table.local_publ_count++; publ = tipc_nametbl_insert_publ(type, lower, upper, scope, tipc_own_addr, port_ref, key); - if (publ && (scope != TIPC_NODE_SCOPE)) { + if (publ && (scope != TIPC_NODE_SCOPE)) tipc_named_publish(publ); - } write_unlock_bh(&tipc_nametbl_lock); return publ; } @@ -795,9 +794,8 @@ void tipc_nametbl_subscribe(struct subscription *s) write_lock_bh(&tipc_nametbl_lock); seq = nametbl_find_seq(type); - if (!seq) { + if (!seq) seq = tipc_nameseq_create(type, &table.types[hash(type)]); - } if (seq) { spin_lock_bh(&seq->lock); tipc_nameseq_subscribe(seq, s); diff --git a/net/tipc/port.c b/net/tipc/port.c index c23f3380d0a7..067bab2a0b98 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -131,9 +131,8 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, } } res = tipc_bclink_send_msg(buf); - if ((res < 0) && (dports.count != 0)) { + if ((res < 0) && (dports.count != 0)) buf_discard(ibuf); - } } else { ibuf = buf; } @@ -190,9 +189,8 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) warn("Unable to deliver multicast message(s)\n"); goto exit; } - if ((index == 0) && (cnt != 0)) { + if ((index == 0) && (cnt != 0)) item = item->next; - } msg_set_destport(buf_msg(b), item->ports[index]); tipc_port_recv_msg(b); } diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 18aad573f551..2b02a3a80313 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -590,9 +590,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, m->msg_iov); } if (likely(res != -ELINKCONG)) { - if (needs_conn && (res >= 0)) { + if (needs_conn && (res >= 0)) sock->state = SS_CONNECTING; - } break; } if (m->msg_flags & MSG_DONTWAIT) { @@ -651,9 +650,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, } res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); - if (likely(res != -ELINKCONG)) { + if (likely(res != -ELINKCONG)) break; - } if (m->msg_flags & MSG_DONTWAIT) { res = -EWOULDBLOCK; break; @@ -1418,9 +1416,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, m.msg_name = dest; m.msg_namelen = destlen; res = send_msg(NULL, sock, &m, 0); - if (res < 0) { + if (res < 0) goto exit; - } /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ @@ -1442,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, advance_rx_queue(sk); } } else { - if (sock->state == SS_CONNECTED) { + if (sock->state == SS_CONNECTED) res = -EISCONN; - } else { + else res = -ECONNREFUSED; - } } } else { if (res == 0) -- cgit v1.2.3-59-g8ed1b From 0885a30b699a2c96d892b61cc48e8ba68fe87bfc Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 31 Dec 2010 15:34:27 +0000 Subject: sky2: implement 64 bit stats This implements 64 bit statistics support and fixes races when reading counter values. The PHY counters can only be accessed 16 bits at a time, so they are subject to carry races. NB: * TX/RX counters are maintained in software because the the hardware packet count is only a 32 bit value. * Error counters are really only 32 bit. * Old 32 bit counter fields in dev->stats still used for some software counters Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 103 ++++++++++++++++++++++++++++++++++------------------- drivers/net/sky2.h | 42 ++++++++++++++++++++++ 2 files changed, 109 insertions(+), 36 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 0d4a236c3bb3..39996bf3b247 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1917,8 +1917,10 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) netif_printk(sky2, tx_done, KERN_DEBUG, dev, "tx done %u\n", idx); - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + u64_stats_update_begin(&sky2->tx_stats.syncp); + ++sky2->tx_stats.packets; + sky2->tx_stats.bytes += skb->len; + u64_stats_update_end(&sky2->tx_stats.syncp); re->skb = NULL; dev_kfree_skb_any(skb); @@ -2460,7 +2462,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev, /* if length reported by DMA does not match PHY, packet was truncated */ if (length != count) - goto len_error; + goto error; okay: if (length < copybreak) @@ -2475,34 +2477,13 @@ resubmit: return skb; -len_error: - /* Truncation of overlength packets - causes PHY length to not match MAC length */ - ++dev->stats.rx_length_errors; - if (net_ratelimit()) - netif_info(sky2, rx_err, dev, - "rx length error: status %#x length %d\n", - status, length); - goto resubmit; - error: ++dev->stats.rx_errors; - if (status & GMR_FS_RX_FF_OV) { - dev->stats.rx_over_errors++; - goto resubmit; - } if (net_ratelimit()) netif_info(sky2, rx_err, dev, "rx error, status 0x%x length %d\n", status, length); - if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) - dev->stats.rx_length_errors++; - if (status & GMR_FS_FRAGMENT) - dev->stats.rx_frame_errors++; - if (status & GMR_FS_CRC_ERR) - dev->stats.rx_crc_errors++; - goto resubmit; } @@ -2543,14 +2524,19 @@ static inline void sky2_skb_rx(const struct sky2_port *sky2, static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port, unsigned packets, unsigned bytes) { - if (packets) { - struct net_device *dev = hw->dev[port]; + struct net_device *dev = hw->dev[port]; + struct sky2_port *sky2 = netdev_priv(dev); - dev->stats.rx_packets += packets; - dev->stats.rx_bytes += bytes; - dev->last_rx = jiffies; - sky2_rx_update(netdev_priv(dev), rxqaddr[port]); - } + if (packets == 0) + return; + + u64_stats_update_begin(&sky2->rx_stats.syncp); + sky2->rx_stats.packets += packets; + sky2->rx_stats.bytes += bytes; + u64_stats_update_end(&sky2->rx_stats.syncp); + + dev->last_rx = jiffies; + sky2_rx_update(netdev_priv(dev), rxqaddr[port]); } static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) @@ -3626,13 +3612,11 @@ static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count) unsigned port = sky2->port; int i; - data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32 - | (u64) gma_read32(hw, port, GM_TXO_OK_LO); - data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32 - | (u64) gma_read32(hw, port, GM_RXO_OK_LO); + data[0] = get_stats64(hw, port, GM_TXO_OK_LO); + data[1] = get_stats64(hw, port, GM_RXO_OK_LO); for (i = 2; i < count; i++) - data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset); + data[i] = get_stats32(hw, port, sky2_stats[i].offset); } static void sky2_set_msglevel(struct net_device *netdev, u32 value) @@ -3750,6 +3734,51 @@ static void sky2_set_multicast(struct net_device *dev) gma_write16(hw, port, GM_RX_CTRL, reg); } +static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + unsigned int start; + u64 _bytes, _packets; + + do { + start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp); + _bytes = sky2->rx_stats.bytes; + _packets = sky2->rx_stats.packets; + } while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start)); + + stats->rx_packets = _packets; + stats->rx_bytes = _bytes; + + do { + start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp); + _bytes = sky2->tx_stats.bytes; + _packets = sky2->tx_stats.packets; + } while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start)); + + stats->tx_packets = _packets; + stats->tx_bytes = _bytes; + + stats->multicast = get_stats32(hw, port, GM_RXF_MC_OK) + + get_stats32(hw, port, GM_RXF_BC_OK); + + stats->collisions = get_stats32(hw, port, GM_TXF_COL); + + stats->rx_length_errors = get_stats32(hw, port, GM_RXF_LNG_ERR); + stats->rx_crc_errors = get_stats32(hw, port, GM_RXF_FCS_ERR); + stats->rx_frame_errors = get_stats32(hw, port, GM_RXF_SHT) + + get_stats32(hw, port, GM_RXE_FRAG); + stats->rx_over_errors = get_stats32(hw, port, GM_RXE_FIFO_OV); + + stats->rx_dropped = dev->stats.rx_dropped; + stats->rx_fifo_errors = dev->stats.rx_fifo_errors; + stats->tx_fifo_errors = dev->stats.tx_fifo_errors; + + return stats; +} + /* Can have one global because blinking is controlled by * ethtool and that is always under RTNL mutex */ @@ -4524,6 +4553,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_set_multicast_list = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, .ndo_tx_timeout = sky2_tx_timeout, + .ndo_get_stats64 = sky2_get_stats, #ifdef SKY2_VLAN_TAG_USED .ndo_vlan_rx_register = sky2_vlan_rx_register, #endif @@ -4541,6 +4571,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_set_multicast_list = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, .ndo_tx_timeout = sky2_tx_timeout, + .ndo_get_stats64 = sky2_get_stats, #ifdef SKY2_VLAN_TAG_USED .ndo_vlan_rx_register = sky2_vlan_rx_register, #endif diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 61891a6cacc2..80bdc404f1ea 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2200,6 +2200,12 @@ enum flow_control { FC_BOTH = 3, }; +struct sky2_stats { + struct u64_stats_sync syncp; + u64 packets; + u64 bytes; +}; + struct sky2_port { struct sky2_hw *hw; struct net_device *netdev; @@ -2209,6 +2215,8 @@ struct sky2_port { struct tx_ring_info *tx_ring; struct sky2_tx_le *tx_le; + struct sky2_stats tx_stats; + u16 tx_ring_size; u16 tx_cons; /* next le to check */ u16 tx_prod; /* next le to use */ @@ -2221,6 +2229,7 @@ struct sky2_port { struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; struct sky2_rx_le *rx_le; + struct sky2_stats rx_stats; u16 rx_next; /* next re to check */ u16 rx_put; /* next le index to use */ @@ -2346,6 +2355,39 @@ static inline u32 gma_read32(struct sky2_hw *hw, unsigned port, unsigned reg) | (u32) sky2_read16(hw, base+4) << 16; } +static inline u64 gma_read64(struct sky2_hw *hw, unsigned port, unsigned reg) +{ + unsigned base = SK_GMAC_REG(port, reg); + + return (u64) sky2_read16(hw, base) + | (u64) sky2_read16(hw, base+4) << 16 + | (u64) sky2_read16(hw, base+8) << 32 + | (u64) sky2_read16(hw, base+12) << 48; +} + +/* There is no way to atomically read32 bit values from PHY, so retry */ +static inline u32 get_stats32(struct sky2_hw *hw, unsigned port, unsigned reg) +{ + u32 val; + + do { + val = gma_read32(hw, port, reg); + } while (gma_read32(hw, port, reg) != val); + + return val; +} + +static inline u64 get_stats64(struct sky2_hw *hw, unsigned port, unsigned reg) +{ + u64 val; + + do { + val = gma_read64(hw, port, reg); + } while (gma_read64(hw, port, reg) != val); + + return val; +} + static inline void gma_write16(const struct sky2_hw *hw, unsigned port, int r, u16 v) { sky2_write16(hw, SK_GMAC_REG(port,r), v); -- cgit v1.2.3-59-g8ed1b From 40cd201e37073b3e2281cf2c73fcf5674f22267f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 1 Jan 2011 14:56:18 -0800 Subject: tipc: update log.h re-include protection to reflect new name The tipc/dbg.h file was recently renamed to tipc/log.h, but the re-include define was not updated accordingly. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tipc/log.h b/net/tipc/log.h index f4343bb9e429..2248d96238e6 100644 --- a/net/tipc/log.h +++ b/net/tipc/log.h @@ -34,8 +34,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _TIPC_DBG_H -#define _TIPC_DBG_H +#ifndef _TIPC_LOG_H +#define _TIPC_LOG_H /** * struct print_buf - TIPC print buffer structure -- cgit v1.2.3-59-g8ed1b From f08c3117c349ea56bd57be347b0b5f8be8c3143c Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 1 Jan 2011 13:15:01 +0000 Subject: net/Space: delete orphaned externs from deleted drivers The drivers associated with the prototypes in this commit have been deleted some time ago, but the externs escaped detection. Using a simple "git grep" shows that these references are historical artefacts, only mentioned by the deleted lines. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- drivers/net/Space.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 9bb405bd664e..068c3563e00f 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -55,8 +55,6 @@ extern struct net_device *eth16i_probe(int unit); extern struct net_device *i82596_probe(int unit); extern struct net_device *ewrk3_probe(int unit); extern struct net_device *el1_probe(int unit); -extern struct net_device *wavelan_probe(int unit); -extern struct net_device *arlan_probe(int unit); extern struct net_device *el16_probe(int unit); extern struct net_device *elmc_probe(int unit); extern struct net_device *elplus_probe(int unit); @@ -68,7 +66,6 @@ extern struct net_device *ni5010_probe(int unit); extern struct net_device *ni52_probe(int unit); extern struct net_device *ni65_probe(int unit); extern struct net_device *sonic_probe(int unit); -extern struct net_device *SK_init(int unit); extern struct net_device *seeq8005_probe(int unit); extern struct net_device *smc_init(int unit); extern struct net_device *atarilance_probe(int unit); @@ -76,8 +73,6 @@ extern struct net_device *sun3lance_probe(int unit); extern struct net_device *sun3_82586_probe(int unit); extern struct net_device *apne_probe(int unit); extern struct net_device *cs89x0_probe(int unit); -extern struct net_device *hplance_probe(int unit); -extern struct net_device *bagetlance_probe(int unit); extern struct net_device *mvme147lance_probe(int unit); extern struct net_device *tc515_probe(int unit); extern struct net_device *lance_probe(int unit); -- cgit v1.2.3-59-g8ed1b From 0cf445ceaf43be31c5fc70b0e2d5fdccb291c925 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 1 Jan 2011 13:28:30 +0000 Subject: netdev: Update status of 8390 based drivers in MAINTAINERS With the original 8 bit ISA ne1000 card being over 20 years old, it only makes sense to consider ne.c and all the other toplevel 8390 based driver files as legacy for obsolete hardware. The most recent thing made in large quantities that was 8390 based were those crazy PCI ne2k clones - and even they are now 10+ years old. Also remove myself as maintainer, since the only changes to these drivers going forward will be the generic API type changes that touch all drivers. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4641289fc072..aa835f7c97d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -166,9 +166,8 @@ F: drivers/serial/8250* F: include/linux/serial_8250.h 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] -M: Paul Gortmaker L: netdev@vger.kernel.org -S: Maintained +S: Orphan / Obsolete F: drivers/net/*8390* F: drivers/net/ax88796.c -- cgit v1.2.3-59-g8ed1b From e4baaf719807ffc87c6321f3914b93dd512b64c4 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Sun, 2 Jan 2011 21:58:44 +0000 Subject: netxen: enable LRO based on NETIF_F_LRO o Enable/disable LRO in device based on NETIF_F_LRO flag, instead of using driver private flag. o Disable LRO, if rx csum offloading is off. David Miller, You should use netdev_info() instead of dev_info(). Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 1 + drivers/net/netxen/netxen_nic_ethtool.c | 26 ++++++++++++++++++++++++-- drivers/net/netxen/netxen_nic_hw.c | 5 ----- drivers/net/netxen/netxen_nic_main.c | 4 +--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 8e8a97839cb0..4e545873a2b9 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1132,6 +1132,7 @@ typedef struct { #define NETXEN_NIC_MSI_ENABLED 0x02 #define NETXEN_NIC_MSIX_ENABLED 0x04 #define NETXEN_NIC_LRO_ENABLED 0x08 +#define NETXEN_NIC_LRO_DISABLED 0x00 #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_IS_MSI_FAMILY(adapter) \ diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index b30de24f4a52..587498e140bb 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -720,7 +720,21 @@ static u32 netxen_nic_get_rx_csum(struct net_device *dev) static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data) { struct netxen_adapter *adapter = netdev_priv(dev); - adapter->rx_csum = !!data; + + if (data) { + adapter->rx_csum = data; + return 0; + } + + if (dev->features & NETIF_F_LRO) { + if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED)) + return -EIO; + + dev->features &= ~NETIF_F_LRO; + netxen_send_lro_cleanup(adapter); + netdev_info(dev, "disabling LRO as rx_csum is off\n"); + } + adapter->rx_csum = data; return 0; } @@ -893,11 +907,19 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data) if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) return -EINVAL; + if (!adapter->rx_csum) { + netdev_info(netdev, "rx csum is off, cannot toggle LRO\n"); + return -EINVAL; + } + + if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO)) + return 0; + if (data & ETH_FLAG_LRO) { hw_lro = NETXEN_NIC_LRO_ENABLED; netdev->features |= NETIF_F_LRO; } else { - hw_lro = 0; + hw_lro = NETXEN_NIC_LRO_DISABLED; netdev->features &= ~NETIF_F_LRO; } diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index e42d26e03af5..5cef718fe35f 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -809,9 +809,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable) u64 word; int rv = 0; - if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable) - return 0; - memset(&req, 0, sizeof(nx_nic_req_t)); req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); @@ -827,8 +824,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable) "configure hw lro request\n"); } - adapter->flags ^= NETXEN_NIC_LRO_ENABLED; - return rv; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 58a3643948c3..33fac32e0d9f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -762,8 +762,6 @@ netxen_check_options(struct netxen_adapter *adapter) if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1); - adapter->flags &= ~NETXEN_NIC_LRO_ENABLED; - if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; @@ -990,7 +988,7 @@ __netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) netxen_config_intr_coalesce(adapter); - if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO) + if (netdev->features & NETIF_F_LRO) netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED); netxen_napi_enable(adapter); -- cgit v1.2.3-59-g8ed1b From 9f84f8886b98a9411ee20a10ca390487507037b9 Mon Sep 17 00:00:00 2001 From: amit salecha Date: Sun, 2 Jan 2011 21:58:45 +0000 Subject: netxen: update driver version 4.0.75 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 4e545873a2b9..a11380544e6c 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 74 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.74" +#define _NETXEN_NIC_LINUX_SUBVERSION 75 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.75" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) -- cgit v1.2.3-59-g8ed1b From 68763c890eb2a60f9b50a061502f94e0cf20fdfe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sun, 2 Jan 2011 22:54:09 +0000 Subject: trivial: Fix typo fault in netdevice.h Signed-off-by: Michal Simek Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cc916c5c3279..0f6b1c965815 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -732,7 +732,7 @@ struct xps_dev_maps { * neither operation. * * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp); - * If device support VLAN receive accleration + * If device support VLAN receive acceleration * (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called * when vlan groups for the device changes. Note: grp is NULL * if no vlan's groups are being used. -- cgit v1.2.3-59-g8ed1b From 87e609760b5304ef0c0c53cf4d0b29fde9812e1b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 3 Jan 2011 00:32:36 +0000 Subject: ll_temac: Fix section mismatch from the temac_of_probe Replace __init by __devinit. Warning message: WARNING: vmlinux.o(.data+0xbc14): Section mismatch in reference from the variable temac_of_driver to the function .init.text:temac_of_probe() The variable temac_of_driver references the function __init temac_of_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Signed-off-by: Michal Simek Acked-by: Grant Likely Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index e2c2a7202dba..183765cb7f25 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -952,7 +952,7 @@ static const struct attribute_group temac_attr_group = { .attrs = temac_device_attrs, }; -static int __init +static int __devinit temac_of_probe(struct platform_device *op, const struct of_device_id *match) { struct device_node *np; -- cgit v1.2.3-59-g8ed1b From 7f891cf1fc0d5d5c5b359caec77e5383e1d55986 Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Mon, 3 Jan 2011 08:04:59 +0000 Subject: dcbnl: more informed return values for new dcbnl routines More accurate return values for the following (new) dcbnl routines: dcbnl_getdcbx() dcbnl_setdcbx() dcbnl_getfeatcfg() dcbnl_setfeatcfg() Signed-off-by: Shmulik Ravid Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 81 ++++++++++++++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index ff3c12d2cd72..9399af565715 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1286,10 +1286,10 @@ nlmsg_failure: static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, u32 pid, u32 seq, u16 flags) { - int ret = -EINVAL; + int ret; if (!netdev->dcbnl_ops->getdcbx) - return ret; + return -EOPNOTSUPP; ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); @@ -1300,11 +1300,14 @@ static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, u32 pid, u32 seq, u16 flags) { - int ret = -EINVAL; + int ret; u8 value; - if (!tb[DCB_ATTR_DCBX] || !netdev->dcbnl_ops->setdcbx) - return ret; + if (!netdev->dcbnl_ops->setdcbx) + return -EOPNOTSUPP; + + if (!tb[DCB_ATTR_DCBX]) + return -EINVAL; value = nla_get_u8(tb[DCB_ATTR_DCBX]); @@ -1323,23 +1326,23 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, struct dcbmsg *dcb; struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; u8 value; - int ret = -EINVAL; - int i; + int ret, i; int getall = 0; - if (!tb[DCB_ATTR_FEATCFG] || !netdev->dcbnl_ops->getfeatcfg) - return ret; + if (!netdev->dcbnl_ops->getfeatcfg) + return -EOPNOTSUPP; + + if (!tb[DCB_ATTR_FEATCFG]) + return -EINVAL; ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest); - if (ret) { - ret = -EINVAL; + if (ret) goto err_out; - } dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!dcbnl_skb) { - ret = -EINVAL; + ret = -ENOBUFS; goto err_out; } @@ -1351,8 +1354,8 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); if (!nest) { - ret = -EINVAL; - goto err; + ret = -EMSGSIZE; + goto nla_put_failure; } if (data[DCB_FEATCFG_ATTR_ALL]) @@ -1363,30 +1366,22 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, continue; ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); - if (!ret) { + if (!ret) ret = nla_put_u8(dcbnl_skb, i, value); - if (ret) { - nla_nest_cancel(dcbnl_skb, nest); - ret = -EINVAL; - goto err; - } - } else - goto err; + if (ret) { + nla_nest_cancel(dcbnl_skb, nest); + goto nla_put_failure; + } } nla_nest_end(dcbnl_skb, nest); nlmsg_end(dcbnl_skb, nlh); - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) { - ret = -EINVAL; - goto err_out; - } - - return 0; + return rtnl_unicast(dcbnl_skb, &init_net, pid); +nla_put_failure: + nlmsg_cancel(dcbnl_skb, nlh); nlmsg_failure: -err: kfree_skb(dcbnl_skb); err_out: return ret; @@ -1396,20 +1391,20 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, u32 pid, u32 seq, u16 flags) { struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; - int ret = -EINVAL; + int ret, i; u8 value; - int i; - if (!tb[DCB_ATTR_FEATCFG] || !netdev->dcbnl_ops->setfeatcfg) - return ret; + if (!netdev->dcbnl_ops->setfeatcfg) + return -ENOTSUPP; + + if (!tb[DCB_ATTR_FEATCFG]) + return -EINVAL; ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest); - if (ret) { - ret = -EINVAL; + if (ret) goto err; - } for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { if (data[i] == NULL) @@ -1420,14 +1415,12 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); if (ret) - goto operr; + goto err; } - -operr: - ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SFEATCFG, - DCB_ATTR_FEATCFG, pid, seq, flags); - err: + dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, + pid, seq, flags); + return ret; } -- cgit v1.2.3-59-g8ed1b From 0dfb33a0d7e2d9316eb4441a065ddd173f87223e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 3 Jan 2011 08:11:38 +0000 Subject: sch_red: report backlog information Provide child qdisc backlog (byte count) information so that "tc -s qdisc" can report it to user. packet count is already correctly provided. qdisc red 11: parent 1:11 limit 60Kb min 15Kb max 45Kb ecn Sent 3116427684 bytes 1415782 pkt (dropped 8, overlimits 7866 requeues 0) rate 242385Kbit 13630pps backlog 13560b 8p requeues 0 marked 7865 early 1 pdrop 7 other 0 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_red.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 8d42bb3ba540..a67ba3c5a0cc 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -239,6 +239,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) .Scell_log = q->parms.Scell_log, }; + sch->qstats.backlog = q->qdisc->qstats.backlog; opts = nla_nest_start(skb, TCA_OPTIONS); if (opts == NULL) goto nla_put_failure; -- cgit v1.2.3-59-g8ed1b From 39980292fda20b38baf95bfa577db8b678eecc86 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 3 Jan 2011 10:35:22 +0000 Subject: ifb: add performance flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le lundi 03 janvier 2011 à 11:40 -0800, David Miller a écrit : > From: Jarek Poplawski > Date: Mon, 3 Jan 2011 20:37:03 +0100 > > > On Sun, Jan 02, 2011 at 09:24:36PM +0100, Eric Dumazet wrote: > >> Le mercredi 29 décembre 2010 ?? 00:07 +0100, Jarek Poplawski a écrit : > >> > >> > Ingress is before vlans handler so these features and the > >> > NETIF_F_HW_VLAN_TX flag seem useful for ifb considering > >> > dev_hard_start_xmit() checks. > >> > >> OK, here is v2 of the patch then, thanks everybody. > >> > >> > >> [PATCH v2 net-next-2.6] ifb: add performance flags > >> > >> IFB can use the full set of features flags (NETIF_F_SG | > >> NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) to > >> avoid unnecessary split of some packets (GRO for example) > >> > >> Changli suggested to also set vlan_features, > > > > He also suggested more GSO flags of which especially NETIF_F_TSO6 > > seems interesting (wrt GRO)? > > I think at least TSO6 would very much be appropriate here. Yes, why not, I am only wondering why loopback / dummy (and others ?) only set NETIF_F_TSO :) Since I want to play with ECN, I might also add NETIF_F_TSO_ECN ;) For other flags, I really doubt it can matter on ifb ? [PATCH v3 net-next-2.6] ifb: add performance flags IFB can use the full set of features flags (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) to avoid unnecessary split of some packets (GRO for example) Changli suggested to also set vlan_features, NETIF_F_TSO6, NETIF_F_TSO_ECN. Jarek suggested to add NETIF_F_HW_VLAN_TX as well. Signed-off-by: Eric Dumazet Cc: Changli Gao Cc: Jarek Poplawski Cc: Pawel Staszewski Signed-off-by: David S. Miller --- drivers/net/ifb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 124dac4532b2..e07d487f015a 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -126,6 +126,10 @@ static const struct net_device_ops ifb_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; +#define IFB_FEATURES (NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ + NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \ + NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_TX) + static void ifb_setup(struct net_device *dev) { /* Initialize the device structure. */ @@ -136,6 +140,9 @@ static void ifb_setup(struct net_device *dev) ether_setup(dev); dev->tx_queue_len = TX_Q_LIMIT; + dev->features |= IFB_FEATURES; + dev->vlan_features |= IFB_FEATURES; + dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; -- cgit v1.2.3-59-g8ed1b From cbad832239e70b91502a5e6ce1fc53a464ad6345 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Mon, 3 Jan 2011 11:06:58 +0000 Subject: ksz884x: Fix section mismatch derived from pcidev_init() This fixes the following warning: WARNING: drivers/net/ksz884x.o(.data+0x18): Section mismatch in reference from the variable pci_device_driver to the function .init.text:pcidev_init() The variable pci_device_driver references the function __init pcidev_init() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Tested with linux-next (next-20101231) Signed-off-by: Sedat Dilek Signed-off-by: David S. Miller --- drivers/net/ksz884x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 49ea8708d6d0..540a8dcbcc46 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -6953,7 +6953,7 @@ static void read_other_addr(struct ksz_hw *hw) #define PCI_VENDOR_ID_MICREL_KS 0x16c6 #endif -static int __init pcidev_init(struct pci_dev *pdev, +static int __devinit pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; -- cgit v1.2.3-59-g8ed1b From 1170bed04e2acf720de9ccceabe40ff8c56c9c79 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Mon, 3 Jan 2011 11:15:58 +0000 Subject: smsc-ircc2: Fix section mismatch derived from smsc_ircc_pnp_probe() This fixes the following warning: drivers/net/irda/smsc-ircc2.o(.data+0x18): Section mismatch in reference from the variable smsc_ircc_pnp_driver to the function .init.text:smsc_ircc_pnp_probe() The variable smsc_ircc_pnp_driver references the function __init smsc_ircc_pnp_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Tested with linux-next (next-20101231) Signed-off-by: Sedat Dilek Signed-off-by: David S. Miller --- drivers/net/irda/smsc-ircc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 8c57bfb5f098..1c1677cfea29 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -376,7 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); static int pnp_driver_registered; #ifdef CONFIG_PNP -static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, +static int __devinit smsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { unsigned int firbase, sirbase; -- cgit v1.2.3-59-g8ed1b From ebd80880c55364d2850e1ff569869245142318e0 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Mon, 3 Jan 2011 11:22:15 +0000 Subject: depca: Fix section mismatch derived from depca_isa_probe() This fixes the following warning: WARNING: drivers/net/depca.o(.data+0x0): Section mismatch in reference from the variable depca_isa_driver to the function .init.text:depca_isa_probe() The variable depca_isa_driver references the function __init depca_isa_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Tested with linux-next (next-20101231) Signed-off-by: Sedat Dilek Signed-off-by: David S. Miller --- drivers/net/depca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 91b3846ffc8a..1b48b68ad4fd 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1513,7 +1513,7 @@ static enum depca_type __init depca_shmem_probe (ulong *mem_start) return adapter; } -static int __init depca_isa_probe (struct platform_device *device) +static int __devinit depca_isa_probe (struct platform_device *device) { struct net_device *dev; struct depca_private *lp; -- cgit v1.2.3-59-g8ed1b From 1a9180a20f3a314fda3e96b77570cad3864b2896 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 3 Jan 2011 11:08:58 +0000 Subject: net/bridge: fix trivial sparse errors net/bridge//br_stp_if.c:148:66: warning: conversion of net/bridge//br_stp_if.c:148:66: int to net/bridge//br_stp_if.c:148:66: int enum umh_wait net/bridge//netfilter/ebtables.c:1150:30: warning: Using plain integer as NULL pointer Signed-off-by: Tomas Winkler Signed-off-by: David S. Miller --- net/bridge/br_stp_if.c | 2 +- net/bridge/netfilter/ebtables.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 1d8826914cbf..79372d4a4055 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -145,7 +145,7 @@ static void br_stp_stop(struct net_bridge *br) char *envp[] = { NULL }; if (br->stp_enabled == BR_USER_STP) { - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1); + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); br_info(br, "userspace STP stopped, return code %d\n", r); /* To start timers on any ports left in blocking */ diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index cbc9f395ab1e..16df0532d4b9 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1147,7 +1147,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) void *p; if (input_table == NULL || (repl = input_table->table) == NULL || - repl->entries == 0 || repl->entries_size == 0 || + repl->entries == NULL || repl->entries_size == 0 || repl->counters != NULL || input_table->private != NULL) { BUGPRINT("Bad table data for ebt_register_table!!!\n"); return ERR_PTR(-EINVAL); -- cgit v1.2.3-59-g8ed1b From 57045c996fb4e035f1d152b7e04315fc223352e9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 3 Jan 2011 15:21:45 +0000 Subject: cnic: Do not allow iSCSI and FCoE on bnx2x multi-function mode Because the hardware does not yet support these in this mode. Reviewed-by: Benjamin Li Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 4a9c628ab2a6..41957fa2d010 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4826,12 +4826,8 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, - func_mf_config[func].config); - val = CNIC_RD(dev, addr); - val &= FUNC_MF_CFG_PROTOCOL_MASK; - if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) - dev->max_iscsi_conn = 0; + dev->max_fcoe_conn = 0; + dev->max_iscsi_conn = 0; } } if (!is_valid_ether_addr(dev->mac_addr)) -- cgit v1.2.3-59-g8ed1b From 42bb8d56953a06de50941d6d3df89dc3023bb92d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 3 Jan 2011 15:21:46 +0000 Subject: cnic: Do not call bnx2i when bnx2i is calling cnic_unregister_driver() We should call bnx2i to send the iSCSI netlink message earlier in cnic_unregister_device(). By the time cnic_unregister_driver() is called, bnx2i may have freed data structures used by the upcalls. Update version to 2.2.12. Reviewed-by: Benjamin Li Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 19 +++---------------- drivers/net/cnic_if.h | 6 +++--- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 41957fa2d010..6dfa56440ac0 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -426,19 +426,6 @@ static int cnic_abort_prep(struct cnic_sock *csk) return 0; } -static void cnic_uio_stop(void) -{ - struct cnic_dev *dev; - - read_lock(&cnic_dev_lock); - list_for_each_entry(dev, &cnic_dev_list, list) { - struct cnic_local *cp = dev->cnic_priv; - - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); - } - read_unlock(&cnic_dev_lock); -} - int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) { struct cnic_dev *dev; @@ -510,9 +497,6 @@ int cnic_unregister_driver(int ulp_type) } read_unlock(&cnic_dev_lock); - if (ulp_type == CNIC_ULP_ISCSI) - cnic_uio_stop(); - rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL); mutex_unlock(&cnic_lock); @@ -596,6 +580,9 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) } mutex_unlock(&cnic_lock); + if (ulp_type == CNIC_ULP_ISCSI) + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + synchronize_rcu(); while (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]) && diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index ccd814068c4d..9f44e0ffe003 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -1,6 +1,6 @@ /* cnic_if.h: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2010 Broadcom Corporation + * Copyright (c) 2006-2011 Broadcom Corporation * * 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 @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.11" -#define CNIC_MODULE_RELDATE "Dec 22, 2010" +#define CNIC_MODULE_VERSION "2.2.12" +#define CNIC_MODULE_RELDATE "Jan 03, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3-59-g8ed1b From bca03d5f32c8ee9b5cfa1d32640a63fded6cb3c0 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:07:31 +0000 Subject: r8169: remove the firmware of RTL8111D. The binary file of the firmware is moved to linux-firmware repository. The firmwares are rtl_nic/rtl8168d-1.fw and rtl_nic/rtl8168d-2.fw. The driver goes along if the firmware couldn't be found. However, it is suggested to be done with the suitable firmware. Some wrong PHY parameters are directly corrected in the driver. Simple firmware checking added per Ben Hutchings suggestion. Signed-off-by: Hayes Wang Signed-off-by: Francois Romieu Cc: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + drivers/net/r8169.c | 812 +++++++++------------------------------------------- 2 files changed, 134 insertions(+), 679 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 89be23340ee4..3fda24a28d2f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2233,6 +2233,7 @@ config YELLOWFIN config R8169 tristate "Realtek 8169 gigabit ethernet support" depends on PCI + select FW_LOADER select CRC32 select MII ---help--- diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index e165d96ec7df..312446234509 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,9 @@ #define MODULENAME "r8169" #define PFX MODULENAME ": " +#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" +#define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" + #ifdef RTL8169_DEBUG #define assert(expr) \ if (!(expr)) { \ @@ -514,6 +518,8 @@ module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); +MODULE_FIRMWARE(FIRMWARE_8168D_1); +MODULE_FIRMWARE(FIRMWARE_8168D_2); static int rtl8169_open(struct net_device *dev); static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -1393,6 +1399,65 @@ static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int } } +#define PHY_READ 0x00000000 +#define PHY_DATA_OR 0x10000000 +#define PHY_DATA_AND 0x20000000 +#define PHY_BJMPN 0x30000000 +#define PHY_READ_EFUSE 0x40000000 +#define PHY_READ_MAC_BYTE 0x50000000 +#define PHY_WRITE_MAC_BYTE 0x60000000 +#define PHY_CLEAR_READCOUNT 0x70000000 +#define PHY_WRITE 0x80000000 +#define PHY_READCOUNT_EQ_SKIP 0x90000000 +#define PHY_COMP_EQ_SKIPN 0xa0000000 +#define PHY_COMP_NEQ_SKIPN 0xb0000000 +#define PHY_WRITE_PREVIOUS 0xc0000000 +#define PHY_SKIPN 0xd0000000 +#define PHY_DELAY_MS 0xe0000000 +#define PHY_WRITE_ERI_WORD 0xf0000000 + +static void +rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) +{ + void __iomem *ioaddr = tp->mmio_addr; + __le32 *phytable = (__le32 *)fw->data; + struct net_device *dev = tp->dev; + size_t i; + + if (fw->size % sizeof(*phytable)) { + netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size); + return; + } + + for (i = 0; i < fw->size / sizeof(*phytable); i++) { + u32 action = le32_to_cpu(phytable[i]); + + if (!action) + break; + + if ((action & 0xf0000000) != PHY_WRITE) { + netif_err(tp, probe, dev, + "unknown action 0x%08x\n", action); + return; + } + } + + while (i-- != 0) { + u32 action = le32_to_cpu(*phytable); + u32 data = action & 0x0000ffff; + u32 reg = (action & 0x0fff0000) >> 16; + + switch(action & 0xf0000000) { + case PHY_WRITE: + mdio_write(ioaddr, reg, data); + phytable++; + break; + default: + BUG(); + } + } +} + static void rtl8169s_hw_phy_config(void __iomem *ioaddr) { static const struct phy_reg phy_reg_init[] = { @@ -1725,9 +1790,10 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr) rtl8168c_3_hw_phy_config(ioaddr); } -static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr) +static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init_0[] = { + /* Channel Estimation */ { 0x1f, 0x0001 }, { 0x06, 0x4064 }, { 0x07, 0x2863 }, @@ -1744,379 +1810,41 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr) { 0x12, 0xf49f }, { 0x13, 0x070b }, { 0x1a, 0x05ad }, - { 0x14, 0x94c0 } - }; - static const struct phy_reg phy_reg_init_1[] = { + { 0x14, 0x94c0 }, + + /* + * Tx Error Issue + * enhance line driver power + */ { 0x1f, 0x0002 }, { 0x06, 0x5561 }, { 0x1f, 0x0005 }, { 0x05, 0x8332 }, - { 0x06, 0x5561 } - }; - static const struct phy_reg phy_reg_init_2[] = { - { 0x1f, 0x0005 }, - { 0x05, 0xffc2 }, - { 0x1f, 0x0005 }, - { 0x05, 0x8000 }, - { 0x06, 0xf8f9 }, - { 0x06, 0xfaef }, - { 0x06, 0x59ee }, - { 0x06, 0xf8ea }, - { 0x06, 0x00ee }, - { 0x06, 0xf8eb }, - { 0x06, 0x00e0 }, - { 0x06, 0xf87c }, - { 0x06, 0xe1f8 }, - { 0x06, 0x7d59 }, - { 0x06, 0x0fef }, - { 0x06, 0x0139 }, - { 0x06, 0x029e }, - { 0x06, 0x06ef }, - { 0x06, 0x1039 }, - { 0x06, 0x089f }, - { 0x06, 0x2aee }, - { 0x06, 0xf8ea }, - { 0x06, 0x00ee }, - { 0x06, 0xf8eb }, - { 0x06, 0x01e0 }, - { 0x06, 0xf87c }, - { 0x06, 0xe1f8 }, - { 0x06, 0x7d58 }, - { 0x06, 0x409e }, - { 0x06, 0x0f39 }, - { 0x06, 0x46aa }, - { 0x06, 0x0bbf }, - { 0x06, 0x8290 }, - { 0x06, 0xd682 }, - { 0x06, 0x9802 }, - { 0x06, 0x014f }, - { 0x06, 0xae09 }, - { 0x06, 0xbf82 }, - { 0x06, 0x98d6 }, - { 0x06, 0x82a0 }, - { 0x06, 0x0201 }, - { 0x06, 0x4fef }, - { 0x06, 0x95fe }, - { 0x06, 0xfdfc }, - { 0x06, 0x05f8 }, - { 0x06, 0xf9fa }, - { 0x06, 0xeef8 }, - { 0x06, 0xea00 }, - { 0x06, 0xeef8 }, - { 0x06, 0xeb00 }, - { 0x06, 0xe2f8 }, - { 0x06, 0x7ce3 }, - { 0x06, 0xf87d }, - { 0x06, 0xa511 }, - { 0x06, 0x1112 }, - { 0x06, 0xd240 }, - { 0x06, 0xd644 }, - { 0x06, 0x4402 }, - { 0x06, 0x8217 }, - { 0x06, 0xd2a0 }, - { 0x06, 0xd6aa }, - { 0x06, 0xaa02 }, - { 0x06, 0x8217 }, - { 0x06, 0xae0f }, - { 0x06, 0xa544 }, - { 0x06, 0x4402 }, - { 0x06, 0xae4d }, - { 0x06, 0xa5aa }, - { 0x06, 0xaa02 }, - { 0x06, 0xae47 }, - { 0x06, 0xaf82 }, - { 0x06, 0x13ee }, - { 0x06, 0x834e }, - { 0x06, 0x00ee }, - { 0x06, 0x834d }, - { 0x06, 0x0fee }, - { 0x06, 0x834c }, - { 0x06, 0x0fee }, - { 0x06, 0x834f }, - { 0x06, 0x00ee }, - { 0x06, 0x8351 }, - { 0x06, 0x00ee }, - { 0x06, 0x834a }, - { 0x06, 0xffee }, - { 0x06, 0x834b }, - { 0x06, 0xffe0 }, - { 0x06, 0x8330 }, - { 0x06, 0xe183 }, - { 0x06, 0x3158 }, - { 0x06, 0xfee4 }, - { 0x06, 0xf88a }, - { 0x06, 0xe5f8 }, - { 0x06, 0x8be0 }, - { 0x06, 0x8332 }, - { 0x06, 0xe183 }, - { 0x06, 0x3359 }, - { 0x06, 0x0fe2 }, - { 0x06, 0x834d }, - { 0x06, 0x0c24 }, - { 0x06, 0x5af0 }, - { 0x06, 0x1e12 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x8ce5 }, - { 0x06, 0xf88d }, - { 0x06, 0xaf82 }, - { 0x06, 0x13e0 }, - { 0x06, 0x834f }, - { 0x06, 0x10e4 }, - { 0x06, 0x834f }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x009f }, - { 0x06, 0x0ae0 }, - { 0x06, 0x834f }, - { 0x06, 0xa010 }, - { 0x06, 0xa5ee }, - { 0x06, 0x834e }, - { 0x06, 0x01e0 }, - { 0x06, 0x834e }, - { 0x06, 0x7805 }, - { 0x06, 0x9e9a }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x049e }, - { 0x06, 0x10e0 }, - { 0x06, 0x834e }, - { 0x06, 0x7803 }, - { 0x06, 0x9e0f }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x019e }, - { 0x06, 0x05ae }, - { 0x06, 0x0caf }, - { 0x06, 0x81f8 }, - { 0x06, 0xaf81 }, - { 0x06, 0xa3af }, - { 0x06, 0x81dc }, - { 0x06, 0xaf82 }, - { 0x06, 0x13ee }, - { 0x06, 0x8348 }, - { 0x06, 0x00ee }, - { 0x06, 0x8349 }, - { 0x06, 0x00e0 }, - { 0x06, 0x8351 }, - { 0x06, 0x10e4 }, - { 0x06, 0x8351 }, - { 0x06, 0x5801 }, - { 0x06, 0x9fea }, - { 0x06, 0xd000 }, - { 0x06, 0xd180 }, - { 0x06, 0x1f66 }, - { 0x06, 0xe2f8 }, - { 0x06, 0xeae3 }, - { 0x06, 0xf8eb }, - { 0x06, 0x5af8 }, - { 0x06, 0x1e20 }, - { 0x06, 0xe6f8 }, - { 0x06, 0xeae5 }, - { 0x06, 0xf8eb }, - { 0x06, 0xd302 }, - { 0x06, 0xb3fe }, - { 0x06, 0xe2f8 }, - { 0x06, 0x7cef }, - { 0x06, 0x325b }, - { 0x06, 0x80e3 }, - { 0x06, 0xf87d }, - { 0x06, 0x9e03 }, - { 0x06, 0x7dff }, - { 0x06, 0xff0d }, - { 0x06, 0x581c }, - { 0x06, 0x551a }, - { 0x06, 0x6511 }, - { 0x06, 0xa190 }, - { 0x06, 0xd3e2 }, - { 0x06, 0x8348 }, - { 0x06, 0xe383 }, - { 0x06, 0x491b }, - { 0x06, 0x56ab }, - { 0x06, 0x08ef }, - { 0x06, 0x56e6 }, - { 0x06, 0x8348 }, - { 0x06, 0xe783 }, - { 0x06, 0x4910 }, - { 0x06, 0xd180 }, - { 0x06, 0x1f66 }, - { 0x06, 0xa004 }, - { 0x06, 0xb9e2 }, - { 0x06, 0x8348 }, - { 0x06, 0xe383 }, - { 0x06, 0x49ef }, - { 0x06, 0x65e2 }, - { 0x06, 0x834a }, - { 0x06, 0xe383 }, - { 0x06, 0x4b1b }, - { 0x06, 0x56aa }, - { 0x06, 0x0eef }, - { 0x06, 0x56e6 }, - { 0x06, 0x834a }, - { 0x06, 0xe783 }, - { 0x06, 0x4be2 }, - { 0x06, 0x834d }, - { 0x06, 0xe683 }, - { 0x06, 0x4ce0 }, - { 0x06, 0x834d }, - { 0x06, 0xa000 }, - { 0x06, 0x0caf }, - { 0x06, 0x81dc }, - { 0x06, 0xe083 }, - { 0x06, 0x4d10 }, - { 0x06, 0xe483 }, - { 0x06, 0x4dae }, - { 0x06, 0x0480 }, - { 0x06, 0xe483 }, - { 0x06, 0x4de0 }, - { 0x06, 0x834e }, - { 0x06, 0x7803 }, - { 0x06, 0x9e0b }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x049e }, - { 0x06, 0x04ee }, - { 0x06, 0x834e }, - { 0x06, 0x02e0 }, - { 0x06, 0x8332 }, - { 0x06, 0xe183 }, - { 0x06, 0x3359 }, - { 0x06, 0x0fe2 }, - { 0x06, 0x834d }, - { 0x06, 0x0c24 }, - { 0x06, 0x5af0 }, - { 0x06, 0x1e12 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x8ce5 }, - { 0x06, 0xf88d }, - { 0x06, 0xe083 }, - { 0x06, 0x30e1 }, - { 0x06, 0x8331 }, - { 0x06, 0x6801 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x8ae5 }, - { 0x06, 0xf88b }, - { 0x06, 0xae37 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e03 }, - { 0x06, 0xe083 }, - { 0x06, 0x4ce1 }, - { 0x06, 0x834d }, - { 0x06, 0x1b01 }, - { 0x06, 0x9e04 }, - { 0x06, 0xaaa1 }, - { 0x06, 0xaea8 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e04 }, - { 0x06, 0xee83 }, - { 0x06, 0x4f00 }, - { 0x06, 0xaeab }, - { 0x06, 0xe083 }, - { 0x06, 0x4f78 }, - { 0x06, 0x039f }, - { 0x06, 0x14ee }, - { 0x06, 0x834e }, - { 0x06, 0x05d2 }, - { 0x06, 0x40d6 }, - { 0x06, 0x5554 }, - { 0x06, 0x0282 }, - { 0x06, 0x17d2 }, - { 0x06, 0xa0d6 }, - { 0x06, 0xba00 }, - { 0x06, 0x0282 }, - { 0x06, 0x17fe }, - { 0x06, 0xfdfc }, - { 0x06, 0x05f8 }, - { 0x06, 0xe0f8 }, - { 0x06, 0x60e1 }, - { 0x06, 0xf861 }, - { 0x06, 0x6802 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x60e5 }, - { 0x06, 0xf861 }, - { 0x06, 0xe0f8 }, - { 0x06, 0x48e1 }, - { 0x06, 0xf849 }, - { 0x06, 0x580f }, - { 0x06, 0x1e02 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x48e5 }, - { 0x06, 0xf849 }, - { 0x06, 0xd000 }, - { 0x06, 0x0282 }, - { 0x06, 0x5bbf }, - { 0x06, 0x8350 }, - { 0x06, 0xef46 }, - { 0x06, 0xdc19 }, - { 0x06, 0xddd0 }, - { 0x06, 0x0102 }, - { 0x06, 0x825b }, - { 0x06, 0x0282 }, - { 0x06, 0x77e0 }, - { 0x06, 0xf860 }, - { 0x06, 0xe1f8 }, - { 0x06, 0x6158 }, - { 0x06, 0xfde4 }, - { 0x06, 0xf860 }, - { 0x06, 0xe5f8 }, - { 0x06, 0x61fc }, - { 0x06, 0x04f9 }, - { 0x06, 0xfafb }, - { 0x06, 0xc6bf }, - { 0x06, 0xf840 }, - { 0x06, 0xbe83 }, - { 0x06, 0x50a0 }, - { 0x06, 0x0101 }, - { 0x06, 0x071b }, - { 0x06, 0x89cf }, - { 0x06, 0xd208 }, - { 0x06, 0xebdb }, - { 0x06, 0x19b2 }, - { 0x06, 0xfbff }, - { 0x06, 0xfefd }, - { 0x06, 0x04f8 }, - { 0x06, 0xe0f8 }, - { 0x06, 0x48e1 }, - { 0x06, 0xf849 }, - { 0x06, 0x6808 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x48e5 }, - { 0x06, 0xf849 }, - { 0x06, 0x58f7 }, - { 0x06, 0xe4f8 }, - { 0x06, 0x48e5 }, - { 0x06, 0xf849 }, - { 0x06, 0xfc04 }, - { 0x06, 0x4d20 }, - { 0x06, 0x0002 }, - { 0x06, 0x4e22 }, - { 0x06, 0x0002 }, - { 0x06, 0x4ddf }, - { 0x06, 0xff01 }, - { 0x06, 0x4edd }, - { 0x06, 0xff01 }, - { 0x05, 0x83d4 }, - { 0x06, 0x8000 }, - { 0x05, 0x83d8 }, - { 0x06, 0x8051 }, - { 0x02, 0x6010 }, - { 0x03, 0xdc00 }, - { 0x05, 0xfff6 }, - { 0x06, 0x00fc }, - { 0x1f, 0x0000 }, + { 0x06, 0x5561 }, + + /* + * Can not link to 1Gbps with bad cable + * Decrease SNR threshold form 21.07dB to 19.04dB + */ + { 0x1f, 0x0001 }, + { 0x17, 0x0cc0 }, { 0x1f, 0x0000 }, - { 0x0d, 0xf880 }, - { 0x1f, 0x0000 } + { 0x0d, 0xf880 } }; + void __iomem *ioaddr = tp->mmio_addr; + const struct firmware *fw; rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); + /* + * Rx Error Issue + * Fine Tune Switching regulator parameter + */ mdio_write(ioaddr, 0x1f, 0x0002); mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef); mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00); - rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1)); - if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, @@ -2157,20 +1885,33 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr) rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } + /* RSET couple improve */ mdio_write(ioaddr, 0x1f, 0x0002); mdio_patch(ioaddr, 0x0d, 0x0300); mdio_patch(ioaddr, 0x0f, 0x0010); + /* Fine tune PLL performance */ mdio_write(ioaddr, 0x1f, 0x0002); mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600); mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000); - rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2)); + mdio_write(ioaddr, 0x1f, 0x0005); + mdio_write(ioaddr, 0x05, 0x001b); + if (mdio_read(ioaddr, 0x06) == 0xbf00 && + request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) { + rtl_phy_write_fw(tp, fw); + release_firmware(fw); + } else { + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + } + + mdio_write(ioaddr, 0x1f, 0x0000); } -static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr) +static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init_0[] = { + /* Channel Estimation */ { 0x1f, 0x0001 }, { 0x06, 0x4064 }, { 0x07, 0x2863 }, @@ -2189,324 +1930,28 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr) { 0x1a, 0x05ad }, { 0x14, 0x94c0 }, + /* + * Tx Error Issue + * enhance line driver power + */ { 0x1f, 0x0002 }, { 0x06, 0x5561 }, { 0x1f, 0x0005 }, { 0x05, 0x8332 }, - { 0x06, 0x5561 } - }; - static const struct phy_reg phy_reg_init_1[] = { - { 0x1f, 0x0005 }, - { 0x05, 0xffc2 }, - { 0x1f, 0x0005 }, - { 0x05, 0x8000 }, - { 0x06, 0xf8f9 }, - { 0x06, 0xfaee }, - { 0x06, 0xf8ea }, - { 0x06, 0x00ee }, - { 0x06, 0xf8eb }, - { 0x06, 0x00e2 }, - { 0x06, 0xf87c }, - { 0x06, 0xe3f8 }, - { 0x06, 0x7da5 }, - { 0x06, 0x1111 }, - { 0x06, 0x12d2 }, - { 0x06, 0x40d6 }, - { 0x06, 0x4444 }, - { 0x06, 0x0281 }, - { 0x06, 0xc6d2 }, - { 0x06, 0xa0d6 }, - { 0x06, 0xaaaa }, - { 0x06, 0x0281 }, - { 0x06, 0xc6ae }, - { 0x06, 0x0fa5 }, - { 0x06, 0x4444 }, - { 0x06, 0x02ae }, - { 0x06, 0x4da5 }, - { 0x06, 0xaaaa }, - { 0x06, 0x02ae }, - { 0x06, 0x47af }, - { 0x06, 0x81c2 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e00 }, - { 0x06, 0xee83 }, - { 0x06, 0x4d0f }, - { 0x06, 0xee83 }, - { 0x06, 0x4c0f }, - { 0x06, 0xee83 }, - { 0x06, 0x4f00 }, - { 0x06, 0xee83 }, - { 0x06, 0x5100 }, - { 0x06, 0xee83 }, - { 0x06, 0x4aff }, - { 0x06, 0xee83 }, - { 0x06, 0x4bff }, - { 0x06, 0xe083 }, - { 0x06, 0x30e1 }, - { 0x06, 0x8331 }, - { 0x06, 0x58fe }, - { 0x06, 0xe4f8 }, - { 0x06, 0x8ae5 }, - { 0x06, 0xf88b }, - { 0x06, 0xe083 }, - { 0x06, 0x32e1 }, - { 0x06, 0x8333 }, - { 0x06, 0x590f }, - { 0x06, 0xe283 }, - { 0x06, 0x4d0c }, - { 0x06, 0x245a }, - { 0x06, 0xf01e }, - { 0x06, 0x12e4 }, - { 0x06, 0xf88c }, - { 0x06, 0xe5f8 }, - { 0x06, 0x8daf }, - { 0x06, 0x81c2 }, - { 0x06, 0xe083 }, - { 0x06, 0x4f10 }, - { 0x06, 0xe483 }, - { 0x06, 0x4fe0 }, - { 0x06, 0x834e }, - { 0x06, 0x7800 }, - { 0x06, 0x9f0a }, - { 0x06, 0xe083 }, - { 0x06, 0x4fa0 }, - { 0x06, 0x10a5 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e01 }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x059e }, - { 0x06, 0x9ae0 }, - { 0x06, 0x834e }, - { 0x06, 0x7804 }, - { 0x06, 0x9e10 }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x039e }, - { 0x06, 0x0fe0 }, - { 0x06, 0x834e }, - { 0x06, 0x7801 }, - { 0x06, 0x9e05 }, - { 0x06, 0xae0c }, - { 0x06, 0xaf81 }, - { 0x06, 0xa7af }, - { 0x06, 0x8152 }, - { 0x06, 0xaf81 }, - { 0x06, 0x8baf }, - { 0x06, 0x81c2 }, - { 0x06, 0xee83 }, - { 0x06, 0x4800 }, - { 0x06, 0xee83 }, - { 0x06, 0x4900 }, - { 0x06, 0xe083 }, - { 0x06, 0x5110 }, - { 0x06, 0xe483 }, - { 0x06, 0x5158 }, - { 0x06, 0x019f }, - { 0x06, 0xead0 }, - { 0x06, 0x00d1 }, - { 0x06, 0x801f }, - { 0x06, 0x66e2 }, - { 0x06, 0xf8ea }, - { 0x06, 0xe3f8 }, - { 0x06, 0xeb5a }, - { 0x06, 0xf81e }, - { 0x06, 0x20e6 }, - { 0x06, 0xf8ea }, - { 0x06, 0xe5f8 }, - { 0x06, 0xebd3 }, - { 0x06, 0x02b3 }, - { 0x06, 0xfee2 }, - { 0x06, 0xf87c }, - { 0x06, 0xef32 }, - { 0x06, 0x5b80 }, - { 0x06, 0xe3f8 }, - { 0x06, 0x7d9e }, - { 0x06, 0x037d }, - { 0x06, 0xffff }, - { 0x06, 0x0d58 }, - { 0x06, 0x1c55 }, - { 0x06, 0x1a65 }, - { 0x06, 0x11a1 }, - { 0x06, 0x90d3 }, - { 0x06, 0xe283 }, - { 0x06, 0x48e3 }, - { 0x06, 0x8349 }, - { 0x06, 0x1b56 }, - { 0x06, 0xab08 }, - { 0x06, 0xef56 }, - { 0x06, 0xe683 }, - { 0x06, 0x48e7 }, - { 0x06, 0x8349 }, - { 0x06, 0x10d1 }, - { 0x06, 0x801f }, - { 0x06, 0x66a0 }, - { 0x06, 0x04b9 }, - { 0x06, 0xe283 }, - { 0x06, 0x48e3 }, - { 0x06, 0x8349 }, - { 0x06, 0xef65 }, - { 0x06, 0xe283 }, - { 0x06, 0x4ae3 }, - { 0x06, 0x834b }, - { 0x06, 0x1b56 }, - { 0x06, 0xaa0e }, - { 0x06, 0xef56 }, - { 0x06, 0xe683 }, - { 0x06, 0x4ae7 }, - { 0x06, 0x834b }, - { 0x06, 0xe283 }, - { 0x06, 0x4de6 }, - { 0x06, 0x834c }, - { 0x06, 0xe083 }, - { 0x06, 0x4da0 }, - { 0x06, 0x000c }, - { 0x06, 0xaf81 }, - { 0x06, 0x8be0 }, - { 0x06, 0x834d }, - { 0x06, 0x10e4 }, - { 0x06, 0x834d }, - { 0x06, 0xae04 }, - { 0x06, 0x80e4 }, - { 0x06, 0x834d }, - { 0x06, 0xe083 }, - { 0x06, 0x4e78 }, - { 0x06, 0x039e }, - { 0x06, 0x0be0 }, - { 0x06, 0x834e }, - { 0x06, 0x7804 }, - { 0x06, 0x9e04 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e02 }, - { 0x06, 0xe083 }, - { 0x06, 0x32e1 }, - { 0x06, 0x8333 }, - { 0x06, 0x590f }, - { 0x06, 0xe283 }, - { 0x06, 0x4d0c }, - { 0x06, 0x245a }, - { 0x06, 0xf01e }, - { 0x06, 0x12e4 }, - { 0x06, 0xf88c }, - { 0x06, 0xe5f8 }, - { 0x06, 0x8de0 }, - { 0x06, 0x8330 }, - { 0x06, 0xe183 }, - { 0x06, 0x3168 }, - { 0x06, 0x01e4 }, - { 0x06, 0xf88a }, - { 0x06, 0xe5f8 }, - { 0x06, 0x8bae }, - { 0x06, 0x37ee }, - { 0x06, 0x834e }, - { 0x06, 0x03e0 }, - { 0x06, 0x834c }, - { 0x06, 0xe183 }, - { 0x06, 0x4d1b }, - { 0x06, 0x019e }, - { 0x06, 0x04aa }, - { 0x06, 0xa1ae }, - { 0x06, 0xa8ee }, - { 0x06, 0x834e }, - { 0x06, 0x04ee }, - { 0x06, 0x834f }, - { 0x06, 0x00ae }, - { 0x06, 0xabe0 }, - { 0x06, 0x834f }, - { 0x06, 0x7803 }, - { 0x06, 0x9f14 }, - { 0x06, 0xee83 }, - { 0x06, 0x4e05 }, - { 0x06, 0xd240 }, - { 0x06, 0xd655 }, - { 0x06, 0x5402 }, - { 0x06, 0x81c6 }, - { 0x06, 0xd2a0 }, - { 0x06, 0xd6ba }, - { 0x06, 0x0002 }, - { 0x06, 0x81c6 }, - { 0x06, 0xfefd }, - { 0x06, 0xfc05 }, - { 0x06, 0xf8e0 }, - { 0x06, 0xf860 }, - { 0x06, 0xe1f8 }, - { 0x06, 0x6168 }, - { 0x06, 0x02e4 }, - { 0x06, 0xf860 }, - { 0x06, 0xe5f8 }, - { 0x06, 0x61e0 }, - { 0x06, 0xf848 }, - { 0x06, 0xe1f8 }, - { 0x06, 0x4958 }, - { 0x06, 0x0f1e }, - { 0x06, 0x02e4 }, - { 0x06, 0xf848 }, - { 0x06, 0xe5f8 }, - { 0x06, 0x49d0 }, - { 0x06, 0x0002 }, - { 0x06, 0x820a }, - { 0x06, 0xbf83 }, - { 0x06, 0x50ef }, - { 0x06, 0x46dc }, - { 0x06, 0x19dd }, - { 0x06, 0xd001 }, - { 0x06, 0x0282 }, - { 0x06, 0x0a02 }, - { 0x06, 0x8226 }, - { 0x06, 0xe0f8 }, - { 0x06, 0x60e1 }, - { 0x06, 0xf861 }, - { 0x06, 0x58fd }, - { 0x06, 0xe4f8 }, - { 0x06, 0x60e5 }, - { 0x06, 0xf861 }, - { 0x06, 0xfc04 }, - { 0x06, 0xf9fa }, - { 0x06, 0xfbc6 }, - { 0x06, 0xbff8 }, - { 0x06, 0x40be }, - { 0x06, 0x8350 }, - { 0x06, 0xa001 }, - { 0x06, 0x0107 }, - { 0x06, 0x1b89 }, - { 0x06, 0xcfd2 }, - { 0x06, 0x08eb }, - { 0x06, 0xdb19 }, - { 0x06, 0xb2fb }, - { 0x06, 0xfffe }, - { 0x06, 0xfd04 }, - { 0x06, 0xf8e0 }, - { 0x06, 0xf848 }, - { 0x06, 0xe1f8 }, - { 0x06, 0x4968 }, - { 0x06, 0x08e4 }, - { 0x06, 0xf848 }, - { 0x06, 0xe5f8 }, - { 0x06, 0x4958 }, - { 0x06, 0xf7e4 }, - { 0x06, 0xf848 }, - { 0x06, 0xe5f8 }, - { 0x06, 0x49fc }, - { 0x06, 0x044d }, - { 0x06, 0x2000 }, - { 0x06, 0x024e }, - { 0x06, 0x2200 }, - { 0x06, 0x024d }, - { 0x06, 0xdfff }, - { 0x06, 0x014e }, - { 0x06, 0xddff }, - { 0x06, 0x0100 }, - { 0x05, 0x83d8 }, - { 0x06, 0x8000 }, - { 0x03, 0xdc00 }, - { 0x05, 0xfff6 }, - { 0x06, 0x00fc }, - { 0x1f, 0x0000 }, + { 0x06, 0x5561 }, + + /* + * Can not link to 1Gbps with bad cable + * Decrease SNR threshold form 21.07dB to 19.04dB + */ + { 0x1f, 0x0001 }, + { 0x17, 0x0cc0 }, { 0x1f, 0x0000 }, - { 0x0d, 0xf880 }, - { 0x1f, 0x0000 } + { 0x0d, 0xf880 } }; + void __iomem *ioaddr = tp->mmio_addr; + const struct firmware *fw; rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); @@ -2550,17 +1995,26 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr) rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } + /* Fine tune PLL performance */ mdio_write(ioaddr, 0x1f, 0x0002); mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600); mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000); - mdio_write(ioaddr, 0x1f, 0x0001); - mdio_write(ioaddr, 0x17, 0x0cc0); - + /* Switching regulator Slew rate */ mdio_write(ioaddr, 0x1f, 0x0002); mdio_patch(ioaddr, 0x0f, 0x0017); - rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1)); + mdio_write(ioaddr, 0x1f, 0x0005); + mdio_write(ioaddr, 0x05, 0x001b); + if (mdio_read(ioaddr, 0x06) == 0xb300 && + request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) { + rtl_phy_write_fw(tp, fw); + release_firmware(fw); + } else { + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + } + + mdio_write(ioaddr, 0x1f, 0x0000); } static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr) @@ -2698,10 +2152,10 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8168cp_2_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_25: - rtl8168d_1_hw_phy_config(ioaddr); + rtl8168d_1_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_26: - rtl8168d_2_hw_phy_config(ioaddr); + rtl8168d_2_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_27: rtl8168d_3_hw_phy_config(ioaddr); -- cgit v1.2.3-59-g8ed1b From f0298f8143e89ac4da306e14b9aa1927e93916d0 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:07:42 +0000 Subject: r8169: identify different registers. Documentation (sort of). The location are the same, the values are the same but it is just accidental. Note that the 810x could cope with a smaller value as it does not support jumbo frames. Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 312446234509..33c3fbf227f4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -67,7 +67,6 @@ static const int multicast_filter_limit = 32; #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -231,7 +230,14 @@ enum rtl_registers { IntrMitigate = 0xe2, RxDescAddrLow = 0xe4, RxDescAddrHigh = 0xe8, - EarlyTxThres = 0xec, + EarlyTxThres = 0xec, /* 8169. Unit of 32 bytes. */ + +#define NoEarlyTx 0x3f /* Max value : no early transmit. */ + + MaxTxPacketSize = 0xec, /* 8101/8168. Unit of 128 bytes. */ + +#define TxPacketMax (8064 >> 7) + FuncEvent = 0xf0, FuncEventMask = 0xf4, FuncPresetState = 0xf8, @@ -2901,7 +2907,7 @@ static void rtl_hw_start_8169(struct net_device *dev) (tp->mac_version == RTL_GIGA_MAC_VER_04)) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(EarlyTxThres, NoEarlyTx); rtl_set_rx_max_size(ioaddr, rx_buf_sz); @@ -3036,7 +3042,7 @@ static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev) { rtl_hw_start_8168bb(ioaddr, pdev); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(MaxTxPacketSize, TxPacketMax); RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); } @@ -3091,7 +3097,7 @@ static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev) /* Magic. */ RTL_W8(DBG_REG, 0x20); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(MaxTxPacketSize, TxPacketMax); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); @@ -3147,7 +3153,7 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) rtl_disable_clock_request(pdev); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(MaxTxPacketSize, TxPacketMax); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); @@ -3162,7 +3168,7 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Unlock); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(MaxTxPacketSize, TxPacketMax); rtl_set_rx_max_size(ioaddr, rx_buf_sz); @@ -3342,7 +3348,7 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Unlock); - RTL_W8(EarlyTxThres, EarlyTxThld); + RTL_W8(MaxTxPacketSize, TxPacketMax); rtl_set_rx_max_size(ioaddr, rx_buf_sz); -- cgit v1.2.3-59-g8ed1b From 4da19633429f67c794b013488348550f457298c4 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:07:55 +0000 Subject: r8169: use device dependent methods to access the MII registers. Current mdio_{read/write} needs device specific information to work correctly with newer chipsets. Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 307 +++++++++++++++++++++++++++------------------------- 1 file changed, 157 insertions(+), 150 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 33c3fbf227f4..b5ced5ebb60e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -502,9 +502,9 @@ struct rtl8169_private { #endif int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); int (*get_settings)(struct net_device *, struct ethtool_cmd *); - void (*phy_reset_enable)(void __iomem *); + void (*phy_reset_enable)(struct rtl8169_private *tp); void (*hw_start)(struct net_device *); - unsigned int (*phy_reset_pending)(void __iomem *); + unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); unsigned int (*link_ok)(void __iomem *); int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); int pcie_cap; @@ -547,7 +547,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget); static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); -static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) +static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) { int i; @@ -569,7 +569,7 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) udelay(20); } -static int mdio_read(void __iomem *ioaddr, int reg_addr) +static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr) { int i, value = -1; @@ -595,34 +595,42 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr) return value; } -static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value) +static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) { - mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value); + r8169_mdio_write(tp->mmio_addr, location, val); } -static void mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m) +static int rtl_readphy(struct rtl8169_private *tp, int location) +{ + return r8169_mdio_read(tp->mmio_addr, location); +} + +static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) +{ + rtl_writephy(tp, reg_addr, rtl_readphy(tp, reg_addr) | value); +} + +static void rtl_w1w0_phy(struct rtl8169_private *tp, int reg_addr, int p, int m) { int val; - val = mdio_read(ioaddr, reg_addr); - mdio_write(ioaddr, reg_addr, (val | p) & ~m); + val = rtl_readphy(tp, reg_addr); + rtl_writephy(tp, reg_addr, (val | p) & ~m); } static void rtl_mdio_write(struct net_device *dev, int phy_id, int location, int val) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - mdio_write(ioaddr, location, val); + rtl_writephy(tp, location, val); } static int rtl_mdio_read(struct net_device *dev, int phy_id, int location) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - return mdio_read(ioaddr, location); + return rtl_readphy(tp, location); } static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value) @@ -723,14 +731,16 @@ static void rtl8169_asic_down(void __iomem *ioaddr) RTL_R16(CPlusCmd); } -static unsigned int rtl8169_tbi_reset_pending(void __iomem *ioaddr) +static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) { + void __iomem *ioaddr = tp->mmio_addr; + return RTL_R32(TBICSR) & TBIReset; } -static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr) +static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp) { - return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET; + return rtl_readphy(tp, MII_BMCR) & BMCR_RESET; } static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr) @@ -743,17 +753,19 @@ static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr) return RTL_R8(PHYstatus) & LinkStatus; } -static void rtl8169_tbi_reset_enable(void __iomem *ioaddr) +static void rtl8169_tbi_reset_enable(struct rtl8169_private *tp) { + void __iomem *ioaddr = tp->mmio_addr; + RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset); } -static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) +static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp) { unsigned int val; - val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET; - mdio_write(ioaddr, MII_BMCR, val & 0xffff); + val = rtl_readphy(tp, MII_BMCR) | BMCR_RESET; + rtl_writephy(tp, MII_BMCR, val & 0xffff); } static void __rtl8169_check_link_status(struct net_device *dev, @@ -917,18 +929,17 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, u8 autoneg, u16 speed, u8 duplex) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; int giga_ctrl, bmcr; if (autoneg == AUTONEG_ENABLE) { int auto_nego; - auto_nego = mdio_read(ioaddr, MII_ADVERTISE); + auto_nego = rtl_readphy(tp, MII_ADVERTISE); auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL); auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; - giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); + giga_ctrl = rtl_readphy(tp, MII_CTRL1000); giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); /* The 8100e/8101e/8102e do Fast Ethernet only. */ @@ -956,12 +967,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, * Vendor specific (0x1f) and reserved (0x0e) MII * registers. */ - mdio_write(ioaddr, 0x1f, 0x0000); - mdio_write(ioaddr, 0x0e, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0e, 0x0000); } - mdio_write(ioaddr, MII_ADVERTISE, auto_nego); - mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); + rtl_writephy(tp, MII_ADVERTISE, auto_nego); + rtl_writephy(tp, MII_CTRL1000, giga_ctrl); } else { giga_ctrl = 0; @@ -975,21 +986,21 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, if (duplex == DUPLEX_FULL) bmcr |= BMCR_FULLDPLX; - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); } tp->phy_1000_ctrl_reg = giga_ctrl; - mdio_write(ioaddr, MII_BMCR, bmcr); + rtl_writephy(tp, MII_BMCR, bmcr); if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03)) { if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) { - mdio_write(ioaddr, 0x17, 0x2138); - mdio_write(ioaddr, 0x0e, 0x0260); + rtl_writephy(tp, 0x17, 0x2138); + rtl_writephy(tp, 0x0e, 0x0260); } else { - mdio_write(ioaddr, 0x17, 0x2108); - mdio_write(ioaddr, 0x0e, 0x0000); + rtl_writephy(tp, 0x17, 0x2108); + rtl_writephy(tp, 0x0e, 0x0000); } } @@ -1397,10 +1408,11 @@ struct phy_reg { u16 val; }; -static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int len) +static void rtl_writephy_batch(struct rtl8169_private *tp, + const struct phy_reg *regs, int len) { while (len-- > 0) { - mdio_write(ioaddr, regs->reg, regs->val); + rtl_writephy(tp, regs->reg, regs->val); regs++; } } @@ -1425,7 +1437,6 @@ static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int static void rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) { - void __iomem *ioaddr = tp->mmio_addr; __le32 *phytable = (__le32 *)fw->data; struct net_device *dev = tp->dev; size_t i; @@ -1455,7 +1466,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) switch(action & 0xf0000000) { case PHY_WRITE: - mdio_write(ioaddr, reg, data); + rtl_writephy(tp, reg, data); phytable++; break; default: @@ -1464,7 +1475,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) } } -static void rtl8169s_hw_phy_config(void __iomem *ioaddr) +static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1528,10 +1539,10 @@ static void rtl8169s_hw_phy_config(void __iomem *ioaddr) { 0x00, 0x9200 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8169sb_hw_phy_config(void __iomem *ioaddr) +static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, @@ -1539,11 +1550,10 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp) { struct pci_dev *pdev = tp->pci_dev; u16 vendor_id, device_id; @@ -1554,13 +1564,12 @@ static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp, if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000)) return; - mdio_write(ioaddr, 0x1f, 0x0001); - mdio_write(ioaddr, 0x10, 0xf01b); - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_writephy(tp, 0x1f, 0x0001); + rtl_writephy(tp, 0x10, 0xf01b); + rtl_writephy(tp, 0x1f, 0x0000); } -static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1602,12 +1611,12 @@ static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp, { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - rtl8169scd_hw_phy_config_quirk(tp, ioaddr); + rtl8169scd_hw_phy_config_quirk(tp); } -static void rtl8169sce_hw_phy_config(void __iomem *ioaddr) +static void rtl8169sce_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1657,23 +1666,23 @@ static void rtl8169sce_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8168bb_hw_phy_config(void __iomem *ioaddr) +static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x10, 0xf41b }, { 0x1f, 0x0000 } }; - mdio_write(ioaddr, 0x1f, 0x0001); - mdio_patch(ioaddr, 0x16, 1 << 0); + rtl_writephy(tp, 0x1f, 0x0001); + rtl_patchphy(tp, 0x16, 1 << 0); - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8168bef_hw_phy_config(void __iomem *ioaddr) +static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1681,10 +1690,10 @@ static void rtl8168bef_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr) +static void rtl8168cp_1_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0000 }, @@ -1694,10 +1703,10 @@ static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr) +static void rtl8168cp_2_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1705,14 +1714,14 @@ static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - mdio_write(ioaddr, 0x1f, 0x0000); - mdio_patch(ioaddr, 0x14, 1 << 5); - mdio_patch(ioaddr, 0x0d, 1 << 5); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_patchphy(tp, 0x14, 1 << 5); + rtl_patchphy(tp, 0x0d, 1 << 5); - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr) +static void rtl8168c_1_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1734,14 +1743,14 @@ static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr) { 0x09, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - mdio_patch(ioaddr, 0x14, 1 << 5); - mdio_patch(ioaddr, 0x0d, 1 << 5); - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_patchphy(tp, 0x14, 1 << 5); + rtl_patchphy(tp, 0x0d, 1 << 5); + rtl_writephy(tp, 0x1f, 0x0000); } -static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr) +static void rtl8168c_2_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1761,15 +1770,15 @@ static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - mdio_patch(ioaddr, 0x16, 1 << 0); - mdio_patch(ioaddr, 0x14, 1 << 5); - mdio_patch(ioaddr, 0x0d, 1 << 5); - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_patchphy(tp, 0x16, 1 << 0); + rtl_patchphy(tp, 0x14, 1 << 5); + rtl_patchphy(tp, 0x0d, 1 << 5); + rtl_writephy(tp, 0x1f, 0x0000); } -static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr) +static void rtl8168c_3_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, @@ -1783,17 +1792,17 @@ static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - mdio_patch(ioaddr, 0x16, 1 << 0); - mdio_patch(ioaddr, 0x14, 1 << 5); - mdio_patch(ioaddr, 0x0d, 1 << 5); - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_patchphy(tp, 0x16, 1 << 0); + rtl_patchphy(tp, 0x14, 1 << 5); + rtl_patchphy(tp, 0x0d, 1 << 5); + rtl_writephy(tp, 0x1f, 0x0000); } -static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr) +static void rtl8168c_4_hw_phy_config(struct rtl8169_private *tp) { - rtl8168c_3_hw_phy_config(ioaddr); + rtl8168c_3_hw_phy_config(tp); } static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) @@ -1841,15 +1850,15 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; const struct firmware *fw; - rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); + rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); /* * Rx Error Issue * Fine Tune Switching regulator parameter */ - mdio_write(ioaddr, 0x1f, 0x0002); - mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef); - mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef); + rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00); if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { static const struct phy_reg phy_reg_init[] = { @@ -1862,9 +1871,9 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) }; int val; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - val = mdio_read(ioaddr, 0x0d); + val = rtl_readphy(tp, 0x0d); if ((val & 0x00ff) != 0x006c) { static const u32 set[] = { @@ -1873,11 +1882,11 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) }; int i; - mdio_write(ioaddr, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0002); val &= 0xff00; for (i = 0; i < ARRAY_SIZE(set); i++) - mdio_write(ioaddr, 0x0d, val | set[i]); + rtl_writephy(tp, 0x0d, val | set[i]); } } else { static const struct phy_reg phy_reg_init[] = { @@ -1888,22 +1897,22 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) { 0x06, 0x6662 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } /* RSET couple improve */ - mdio_write(ioaddr, 0x1f, 0x0002); - mdio_patch(ioaddr, 0x0d, 0x0300); - mdio_patch(ioaddr, 0x0f, 0x0010); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_patchphy(tp, 0x0d, 0x0300); + rtl_patchphy(tp, 0x0f, 0x0010); /* Fine tune PLL performance */ - mdio_write(ioaddr, 0x1f, 0x0002); - mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600); - mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_w1w0_phy(tp, 0x02, 0x0100, 0x0600); + rtl_w1w0_phy(tp, 0x03, 0x0000, 0xe000); - mdio_write(ioaddr, 0x1f, 0x0005); - mdio_write(ioaddr, 0x05, 0x001b); - if (mdio_read(ioaddr, 0x06) == 0xbf00 && + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x001b); + if (rtl_readphy(tp, 0x06) == 0xbf00 && request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) { rtl_phy_write_fw(tp, fw); release_firmware(fw); @@ -1911,7 +1920,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); } - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); } static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) @@ -1959,7 +1968,7 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; const struct firmware *fw; - rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); + rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { static const struct phy_reg phy_reg_init[] = { @@ -1973,9 +1982,9 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) }; int val; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - val = mdio_read(ioaddr, 0x0d); + val = rtl_readphy(tp, 0x0d); if ((val & 0x00ff) != 0x006c) { static const u32 set[] = { 0x0065, 0x0066, 0x0067, 0x0068, @@ -1983,11 +1992,11 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) }; int i; - mdio_write(ioaddr, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0002); val &= 0xff00; for (i = 0; i < ARRAY_SIZE(set); i++) - mdio_write(ioaddr, 0x0d, val | set[i]); + rtl_writephy(tp, 0x0d, val | set[i]); } } else { static const struct phy_reg phy_reg_init[] = { @@ -1998,21 +2007,21 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) { 0x06, 0x2642 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } /* Fine tune PLL performance */ - mdio_write(ioaddr, 0x1f, 0x0002); - mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600); - mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_w1w0_phy(tp, 0x02, 0x0100, 0x0600); + rtl_w1w0_phy(tp, 0x03, 0x0000, 0xe000); /* Switching regulator Slew rate */ - mdio_write(ioaddr, 0x1f, 0x0002); - mdio_patch(ioaddr, 0x0f, 0x0017); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_patchphy(tp, 0x0f, 0x0017); - mdio_write(ioaddr, 0x1f, 0x0005); - mdio_write(ioaddr, 0x05, 0x001b); - if (mdio_read(ioaddr, 0x06) == 0xb300 && + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x001b); + if (rtl_readphy(tp, 0x06) == 0xb300 && request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) { rtl_phy_write_fw(tp, fw); release_firmware(fw); @@ -2020,10 +2029,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); } - mdio_write(ioaddr, 0x1f, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); } -static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr) +static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, @@ -2081,10 +2090,10 @@ static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } -static void rtl8102e_hw_phy_config(void __iomem *ioaddr) +static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0003 }, @@ -2093,18 +2102,17 @@ static void rtl8102e_hw_phy_config(void __iomem *ioaddr) { 0x1f, 0x0000 } }; - mdio_write(ioaddr, 0x1f, 0x0000); - mdio_patch(ioaddr, 0x11, 1 << 12); - mdio_patch(ioaddr, 0x19, 1 << 13); - mdio_patch(ioaddr, 0x10, 1 << 15); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_patchphy(tp, 0x11, 1 << 12); + rtl_patchphy(tp, 0x19, 1 << 13); + rtl_patchphy(tp, 0x10, 1 << 15); - rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; rtl8169_print_mac_version(tp); @@ -2113,49 +2121,49 @@ static void rtl_hw_phy_config(struct net_device *dev) break; case RTL_GIGA_MAC_VER_02: case RTL_GIGA_MAC_VER_03: - rtl8169s_hw_phy_config(ioaddr); + rtl8169s_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_04: - rtl8169sb_hw_phy_config(ioaddr); + rtl8169sb_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_05: - rtl8169scd_hw_phy_config(tp, ioaddr); + rtl8169scd_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_06: - rtl8169sce_hw_phy_config(ioaddr); + rtl8169sce_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_07: case RTL_GIGA_MAC_VER_08: case RTL_GIGA_MAC_VER_09: - rtl8102e_hw_phy_config(ioaddr); + rtl8102e_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_11: - rtl8168bb_hw_phy_config(ioaddr); + rtl8168bb_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_12: - rtl8168bef_hw_phy_config(ioaddr); + rtl8168bef_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_17: - rtl8168bef_hw_phy_config(ioaddr); + rtl8168bef_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_18: - rtl8168cp_1_hw_phy_config(ioaddr); + rtl8168cp_1_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_19: - rtl8168c_1_hw_phy_config(ioaddr); + rtl8168c_1_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_20: - rtl8168c_2_hw_phy_config(ioaddr); + rtl8168c_2_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_21: - rtl8168c_3_hw_phy_config(ioaddr); + rtl8168c_3_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_22: - rtl8168c_4_hw_phy_config(ioaddr); + rtl8168c_4_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: - rtl8168cp_2_hw_phy_config(ioaddr); + rtl8168cp_2_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_25: rtl8168d_1_hw_phy_config(tp); @@ -2164,7 +2172,7 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8168d_2_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_27: - rtl8168d_3_hw_phy_config(ioaddr); + rtl8168d_3_hw_phy_config(tp); break; default: @@ -2187,7 +2195,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) spin_lock_irq(&tp->lock); - if (tp->phy_reset_pending(ioaddr)) { + if (tp->phy_reset_pending(tp)) { /* * A busy loop could burn quite a few cycles on nowadays CPU. * Let's delay the execution of the timer for a few ticks. @@ -2201,7 +2209,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) netif_warn(tp, link, dev, "PHY reset until link up\n"); - tp->phy_reset_enable(ioaddr); + tp->phy_reset_enable(tp); out_mod_timer: mod_timer(timer, jiffies + timeout); @@ -2261,12 +2269,11 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, static void rtl8169_phy_reset(struct net_device *dev, struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; unsigned int i; - tp->phy_reset_enable(ioaddr); + tp->phy_reset_enable(tp); for (i = 0; i < 100; i++) { - if (!tp->phy_reset_pending(ioaddr)) + if (!tp->phy_reset_pending(tp)) return; msleep(1); } @@ -2293,7 +2300,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); RTL_W8(0x82, 0x01); dprintk("Set PHY Reg 0x0bh = 0x00h\n"); - mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 + rtl_writephy(tp, 0x0b, 0x0000); //w 0x0b 15 0 0 } rtl8169_phy_reset(dev, tp); @@ -2363,11 +2370,11 @@ static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *dat return 0; case SIOCGMIIREG: - data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f); + data->val_out = rtl_readphy(tp, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: - mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in); + rtl_writephy(tp, data->reg_num & 0x1f, data->val_in); return 0; } return -EOPNOTSUPP; -- cgit v1.2.3-59-g8ed1b From c0e45c1ca3162acb2e77b3d9e152ce6e7b6fa3f5 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:08:04 +0000 Subject: r8169: 8168DP specific MII registers access methods. Adapted from version 8.019.00 of Realtek's r8168 driver and amended per Hayes Wang's correction : - OCPDR_GPHY_REG_SHIFT must be 16, not 12 - the reg should be at bit 16 ~ 22, whence OCPDR_REG_MASK Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b5ced5ebb60e..3a63363e47cc 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -277,6 +277,20 @@ enum rtl8168_8101_registers { #define EFUSEAR_DATA_MASK 0xff }; +enum rtl8168_registers { + EPHY_RXER_NUM = 0x7c, + OCPDR = 0xb0, /* OCP GPHY access */ +#define OCPDR_WRITE_CMD 0x80000000 +#define OCPDR_READ_CMD 0x00000000 +#define OCPDR_REG_MASK 0x7f +#define OCPDR_GPHY_REG_SHIFT 16 +#define OCPDR_DATA_MASK 0xffff + OCPAR = 0xb4, +#define OCPAR_FLAG 0x80000000 +#define OCPAR_GPHY_WRITE_CMD 0x8000f060 +#define OCPAR_GPHY_READ_CMD 0x0000f060 +}; + enum rtl_register_content { /* InterruptStatusBits */ SYSErr = 0x8000, @@ -500,6 +514,12 @@ struct rtl8169_private { #ifdef CONFIG_R8169_VLAN struct vlan_group *vlgrp; #endif + + struct mdio_ops { + void (*write)(void __iomem *, int, int); + int (*read)(void __iomem *, int); + } mdio_ops; + int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); int (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(struct rtl8169_private *tp); @@ -595,14 +615,55 @@ static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr) return value; } +static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data) +{ + int i; + + RTL_W32(OCPDR, data | + ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); + RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD); + RTL_W32(EPHY_RXER_NUM, 0); + + for (i = 0; i < 100; i++) { + mdelay(1); + if (!(RTL_R32(OCPAR) & OCPAR_FLAG)) + break; + } +} + +static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +{ + r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD | + (value & OCPDR_DATA_MASK)); +} + +static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr) +{ + int i; + + r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD); + + mdelay(1); + RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD); + RTL_W32(EPHY_RXER_NUM, 0); + + for (i = 0; i < 100; i++) { + mdelay(1); + if (RTL_R32(OCPAR) & OCPAR_FLAG) + break; + } + + return RTL_R32(OCPDR) & OCPDR_DATA_MASK; +} + static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) { - r8169_mdio_write(tp->mmio_addr, location, val); + tp->mdio_ops.write(tp->mmio_addr, location, val); } static int rtl_readphy(struct rtl8169_private *tp, int location) { - return r8169_mdio_read(tp->mmio_addr, location); + return tp->mdio_ops.read(tp->mmio_addr, location); } static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) @@ -2474,6 +2535,22 @@ static const struct net_device_ops rtl8169_netdev_ops = { }; +static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) +{ + struct mdio_ops *ops = &tp->mdio_ops; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_27: + ops->write = r8168dp_1_mdio_write; + ops->read = r8168dp_1_mdio_read; + break; + default: + ops->write = r8169_mdio_write; + ops->read = r8169_mdio_read; + break; + } +} + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2592,6 +2669,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* Identify chip attached to board */ rtl8169_get_mac_version(tp, ioaddr); + rtl_init_mdio_ops(tp); + /* Use appropriate default if unknown */ if (tp->mac_version == RTL_GIGA_MAC_NONE) { netif_notice(tp, probe, dev, -- cgit v1.2.3-59-g8ed1b From 065c27c184d64aeb9ae107c0ef7026ea3642b15b Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:08:12 +0000 Subject: r8169: phy power ops Bits from : - version 8.019.00 of Realtek's 8168 driver - version 1.019.00 of Realtek's 8101 driver Plain old 8169 (PCI) devices do not seem to need anything akin to it. Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 3a63363e47cc..0ec47f463157 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -258,7 +258,7 @@ enum rtl8168_8101_registers { #define CSIAR_BYTE_ENABLE 0x0f #define CSIAR_BYTE_ENABLE_SHIFT 12 #define CSIAR_ADDR_MASK 0x0fff - + PMCH = 0x6f, EPHYAR = 0x80, #define EPHYAR_FLAG 0x80000000 #define EPHYAR_WRITE_CMD 0x80000000 @@ -520,6 +520,11 @@ struct rtl8169_private { int (*read)(void __iomem *, int); } mdio_ops; + struct pll_power_ops { + void (*down)(struct rtl8169_private *); + void (*up)(struct rtl8169_private *); + } pll_power_ops; + int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); int (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(struct rtl8169_private *tp); @@ -2551,6 +2556,152 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) } } +static void r810x_phy_power_down(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, BMCR_PDOWN); +} + +static void r810x_phy_power_up(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE); +} + +static void r810x_pll_power_down(struct rtl8169_private *tp) +{ + if (__rtl8169_get_wol(tp) & WAKE_ANY) { + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + return; + } + + r810x_phy_power_down(tp); +} + +static void r810x_pll_power_up(struct rtl8169_private *tp) +{ + r810x_phy_power_up(tp); +} + +static void r8168_phy_power_up(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0e, 0x0000); + rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE); +} + +static void r8168_phy_power_down(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0e, 0x0200); + rtl_writephy(tp, MII_BMCR, BMCR_PDOWN); +} + +static void r8168_pll_power_down(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + if (tp->mac_version == RTL_GIGA_MAC_VER_27) + return; + + if (((tp->mac_version == RTL_GIGA_MAC_VER_23) || + (tp->mac_version == RTL_GIGA_MAC_VER_24)) && + (RTL_R16(CPlusCmd) & ASF)) { + return; + } + + if (__rtl8169_get_wol(tp) & WAKE_ANY) { + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + + RTL_W32(RxConfig, RTL_R32(RxConfig) | + AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + return; + } + + r8168_phy_power_down(tp); + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25: + case RTL_GIGA_MAC_VER_26: + RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); + break; + } +} + +static void r8168_pll_power_up(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + if (tp->mac_version == RTL_GIGA_MAC_VER_27) + return; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25: + case RTL_GIGA_MAC_VER_26: + RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); + break; + } + + r8168_phy_power_up(tp); +} + +static void rtl_pll_power_op(struct rtl8169_private *tp, + void (*op)(struct rtl8169_private *)) +{ + if (op) + op(tp); +} + +static void rtl_pll_power_down(struct rtl8169_private *tp) +{ + rtl_pll_power_op(tp, tp->pll_power_ops.down); +} + +static void rtl_pll_power_up(struct rtl8169_private *tp) +{ + rtl_pll_power_op(tp, tp->pll_power_ops.up); +} + +static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) +{ + struct pll_power_ops *ops = &tp->pll_power_ops; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_07: + case RTL_GIGA_MAC_VER_08: + case RTL_GIGA_MAC_VER_09: + case RTL_GIGA_MAC_VER_10: + case RTL_GIGA_MAC_VER_16: + ops->down = r810x_pll_power_down; + ops->up = r810x_pll_power_up; + break; + + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_18: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_25: + case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_27: + ops->down = r8168_pll_power_down; + ops->up = r8168_pll_power_up; + break; + + default: + ops->down = NULL; + ops->up = NULL; + break; + } +} + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2670,6 +2821,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl8169_get_mac_version(tp, ioaddr); rtl_init_mdio_ops(tp); + rtl_init_pll_power_ops(tp); /* Use appropriate default if unknown */ if (tp->mac_version == RTL_GIGA_MAC_NONE) { @@ -2849,6 +3001,8 @@ static int rtl8169_open(struct net_device *dev) napi_enable(&tp->napi); + rtl_pll_power_up(tp); + rtl_hw_start(dev); rtl8169_request_timer(dev); @@ -4257,6 +4411,8 @@ static void rtl8169_down(struct net_device *dev) rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); + + rtl_pll_power_down(tp); } static int rtl8169_close(struct net_device *dev) @@ -4361,9 +4517,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) static void rtl8169_net_suspend(struct net_device *dev) { + struct rtl8169_private *tp = netdev_priv(dev); + if (!netif_running(dev)) return; + rtl_pll_power_down(tp); + netif_device_detach(dev); netif_stop_queue(dev); } @@ -4382,7 +4542,12 @@ static int rtl8169_suspend(struct device *device) static void __rtl8169_resume(struct net_device *dev) { + struct rtl8169_private *tp = netdev_priv(dev); + netif_device_attach(dev); + + rtl_pll_power_up(tp); + rtl8169_schedule_work(dev, rtl8169_reset_task); } -- cgit v1.2.3-59-g8ed1b From b646d90053f887c1bc243191e693a9b02d09f2c2 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:08:21 +0000 Subject: r8169: magic. Adapted from version 8.019.00 of Realtek's r8168 driver. Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0ec47f463157..a73dd287fdba 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -278,6 +278,18 @@ enum rtl8168_8101_registers { }; enum rtl8168_registers { + ERIDR = 0x70, + ERIAR = 0x74, +#define ERIAR_FLAG 0x80000000 +#define ERIAR_WRITE_CMD 0x80000000 +#define ERIAR_READ_CMD 0x00000000 +#define ERIAR_ADDR_BYTE_ALIGN 4 +#define ERIAR_EXGMAC 0 +#define ERIAR_MSIX 1 +#define ERIAR_ASF 2 +#define ERIAR_TYPE_SHIFT 16 +#define ERIAR_BYTEEN 0x0f +#define ERIAR_BYTEEN_SHIFT 12 EPHY_RXER_NUM = 0x7c, OCPDR = 0xb0, /* OCP GPHY access */ #define OCPDR_WRITE_CMD 0x80000000 @@ -572,6 +584,81 @@ static int rtl8169_poll(struct napi_struct *napi, int budget); static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); +static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) +{ + void __iomem *ioaddr = tp->mmio_addr; + int i; + + RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); + for (i = 0; i < 20; i++) { + udelay(100); + if (RTL_R32(OCPAR) & OCPAR_FLAG) + break; + } + return RTL_R32(OCPDR); +} + +static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data) +{ + void __iomem *ioaddr = tp->mmio_addr; + int i; + + RTL_W32(OCPDR, data); + RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); + for (i = 0; i < 20; i++) { + udelay(100); + if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0) + break; + } +} + +static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) +{ + int i; + + RTL_W8(ERIDR, cmd); + RTL_W32(ERIAR, 0x800010e8); + msleep(2); + for (i = 0; i < 5; i++) { + udelay(100); + if (!(RTL_R32(ERIDR) & ERIAR_FLAG)) + break; + } + + ocp_write(ioaddr, 0x1, 0x30, 0x00000001); +} + +#define OOB_CMD_RESET 0x00 +#define OOB_CMD_DRIVER_START 0x05 +#define OOB_CMD_DRIVER_STOP 0x06 + +static void rtl8168_driver_start(struct rtl8169_private *tp) +{ + int i; + + rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START); + + for (i = 0; i < 10; i++) { + msleep(10); + if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800) + break; + } +} + +static void rtl8168_driver_stop(struct rtl8169_private *tp) +{ + int i; + + rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); + + for (i = 0; i < 10; i++) { + msleep(10); + if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0) + break; + } +} + + static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) { int i; @@ -2913,6 +3000,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->base_addr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); + if (tp->mac_version == RTL_GIGA_MAC_VER_27) + rtl8168_driver_start(tp); + rtl8169_init_phy(dev, tp); /* @@ -2948,6 +3038,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); + if (tp->mac_version == RTL_GIGA_MAC_VER_27) + rtl8168_driver_stop(tp); + cancel_delayed_work_sync(&tp->task); unregister_netdev(dev); -- cgit v1.2.3-59-g8ed1b From 650e8d5d1fdd5e55869136e2df54287a4432d87f Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:08:29 +0000 Subject: r8169: rtl_csi_access_enable rename. Newer 8168 needs a slightly different rtl_csi_access_enable. This patch separates some noise from the real thing. No functional change. Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a73dd287fdba..a468ee98ab9e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3310,12 +3310,17 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) } } -static void rtl_csi_access_enable(void __iomem *ioaddr) +static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) { u32 csi; csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff; - rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000); + rtl_csi_write(ioaddr, 0x070c, csi | bits); +} + +static void rtl_csi_access_enable_2(void __iomem *ioaddr) +{ + rtl_csi_access_enable(ioaddr, 0x27000000); } struct ephy_info { @@ -3403,7 +3408,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev) { 0x07, 0, 0x2000 } }; - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); @@ -3412,7 +3417,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev) static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev) { - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); @@ -3423,7 +3428,7 @@ static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev) static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev) { - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); @@ -3445,7 +3450,7 @@ static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev) { 0x06, 0x0080, 0x0000 } }; - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); @@ -3461,7 +3466,7 @@ static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev) { 0x03, 0x0400, 0x0220 } }; - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); @@ -3475,14 +3480,14 @@ static void rtl_hw_start_8168c_3(void __iomem *ioaddr, struct pci_dev *pdev) static void rtl_hw_start_8168c_4(void __iomem *ioaddr, struct pci_dev *pdev) { - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); __rtl_hw_start_8168cp(ioaddr, pdev); } static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) { - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); rtl_disable_clock_request(pdev); @@ -3611,7 +3616,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) }; u8 cfg1; - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); RTL_W8(DBG_REG, FIX_NAK_1); @@ -3632,7 +3637,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev) { - rtl_csi_access_enable(ioaddr); + rtl_csi_access_enable_2(ioaddr); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); -- cgit v1.2.3-59-g8ed1b From e6de30d63eb17c5cbb7affdfc71df95286bfa7d9 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Mon, 3 Jan 2011 15:08:37 +0000 Subject: r8169: more 8168dp support. Adapted from version 8.019.00 of Realtek's r8168 driver Signed-off-by: Francois Romieu Cc: Hayes Signed-off-by: David S. Miller --- drivers/net/r8169.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 9 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a468ee98ab9e..27a7c20f64cd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -121,7 +121,8 @@ enum mac_version { RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP RTL_GIGA_MAC_VER_25 = 0x19, // 8168D RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D - RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP + RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP + RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP }; #define _R(NAME,MAC,MASK) \ @@ -158,7 +159,8 @@ static const struct { _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880) // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E }; #undef _R @@ -301,6 +303,7 @@ enum rtl8168_registers { #define OCPAR_FLAG 0x80000000 #define OCPAR_GPHY_WRITE_CMD 0x8000f060 #define OCPAR_GPHY_READ_CMD 0x0000f060 + RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */ }; enum rtl_register_content { @@ -748,6 +751,40 @@ static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr) return RTL_R32(OCPDR) & OCPDR_DATA_MASK; } +#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 + +static void r8168dp_2_mdio_start(void __iomem *ioaddr) +{ + RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); +} + +static void r8168dp_2_mdio_stop(void __iomem *ioaddr) +{ + RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); +} + +static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +{ + r8168dp_2_mdio_start(ioaddr); + + r8169_mdio_write(ioaddr, reg_addr, value); + + r8168dp_2_mdio_stop(ioaddr); +} + +static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) +{ + int value; + + r8168dp_2_mdio_start(ioaddr); + + value = r8169_mdio_read(ioaddr, reg_addr); + + r8168dp_2_mdio_stop(ioaddr); + + return value; +} + static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) { tp->mdio_ops.write(tp->mmio_addr, location, val); @@ -1495,9 +1532,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, /* 8168D family. */ { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, - { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 }, { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 }, + /* 8168DP family. */ + { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 }, + { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 }, + /* 8168C family. */ { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, @@ -2246,6 +2286,22 @@ static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp) rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } +static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + { 0x1f, 0x0001 }, + { 0x17, 0x0cc0 }, + + { 0x1f, 0x0007 }, + { 0x1e, 0x002d }, + { 0x18, 0x0040 }, + { 0x1f, 0x0000 } + }; + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + rtl_patchphy(tp, 0x0d, 1 << 5); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -2327,6 +2383,9 @@ static void rtl_hw_phy_config(struct net_device *dev) case RTL_GIGA_MAC_VER_27: rtl8168d_3_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_28: + rtl8168d_4_hw_phy_config(tp); + break; default: break; @@ -2636,6 +2695,10 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) ops->write = r8168dp_1_mdio_write; ops->read = r8168dp_1_mdio_read; break; + case RTL_GIGA_MAC_VER_28: + ops->write = r8168dp_2_mdio_write; + ops->read = r8168dp_2_mdio_read; + break; default: ops->write = r8169_mdio_write; ops->read = r8169_mdio_read; @@ -2778,6 +2841,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_25: case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -3000,8 +3064,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->base_addr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); - if (tp->mac_version == RTL_GIGA_MAC_VER_27) + if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || + (tp->mac_version == RTL_GIGA_MAC_VER_28)) { rtl8168_driver_start(tp); + } rtl8169_init_phy(dev, tp); @@ -3038,8 +3104,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - if (tp->mac_version == RTL_GIGA_MAC_VER_27) + if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || + (tp->mac_version == RTL_GIGA_MAC_VER_28)) { rtl8168_driver_stop(tp); + } cancel_delayed_work_sync(&tp->task); @@ -3122,11 +3190,19 @@ err_pm_runtime_put: goto out; } -static void rtl8169_hw_reset(void __iomem *ioaddr) +static void rtl8169_hw_reset(struct rtl8169_private *tp) { + void __iomem *ioaddr = tp->mmio_addr; + /* Disable interrupts */ rtl8169_irq_mask_and_ack(ioaddr); + if (tp->mac_version == RTL_GIGA_MAC_VER_28) { + while (RTL_R8(TxPoll) & NPQ) + udelay(20); + + } + /* Reset the chipset */ RTL_W8(ChipCmd, CmdReset); @@ -3318,6 +3394,11 @@ static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) rtl_csi_write(ioaddr, 0x070c, csi | bits); } +static void rtl_csi_access_enable_1(void __iomem *ioaddr) +{ + rtl_csi_access_enable(ioaddr, 0x17000000); +} + static void rtl_csi_access_enable_2(void __iomem *ioaddr) { rtl_csi_access_enable(ioaddr, 0x27000000); @@ -3355,6 +3436,21 @@ static void rtl_disable_clock_request(struct pci_dev *pdev) } } +static void rtl_enable_clock_request(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8169_private *tp = netdev_priv(dev); + int cap = tp->pcie_cap; + + if (cap) { + u16 ctl; + + pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); + ctl |= PCI_EXP_LNKCTL_CLKREQ_EN; + pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); + } +} + #define R8168_CPCMD_QUIRK_MASK (\ EnableBist | \ Mac_dbgo_oe | \ @@ -3498,6 +3594,32 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } +static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8168d_4[] = { + { 0x0b, ~0, 0x48 }, + { 0x19, 0x20, 0x50 }, + { 0x0c, ~0, 0x20 } + }; + int i; + + rtl_csi_access_enable_1(ioaddr); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + RTL_W8(MaxTxPacketSize, TxPacketMax); + + for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) { + const struct ephy_info *e = e_info_8168d_4 + i; + u16 w; + + w = rtl_ephy_read(ioaddr, e->offset); + rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits); + } + + rtl_enable_clock_request(pdev); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3575,6 +3697,10 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_hw_start_8168d(ioaddr, pdev); break; + case RTL_GIGA_MAC_VER_28: + rtl_hw_start_8168d_4(ioaddr, pdev); + break; + default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", dev->name, tp->mac_version); @@ -3987,7 +4113,7 @@ static void rtl8169_tx_timeout(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - rtl8169_hw_reset(tp->mmio_addr); + rtl8169_hw_reset(tp); /* Let's wait a bit while any (async) irq lands on */ rtl8169_schedule_work(dev, rtl8169_reset_task); @@ -4145,7 +4271,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); struct pci_dev *pdev = tp->pci_dev; - void __iomem *ioaddr = tp->mmio_addr; u16 pci_status, pci_cmd; pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); @@ -4176,13 +4301,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) /* The infamous DAC f*ckup only happens at boot time */ if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) { + void __iomem *ioaddr = tp->mmio_addr; + netif_info(tp, intr, dev, "disabling PCI DAC\n"); tp->cp_cmd &= ~PCIDAC; RTL_W16(CPlusCmd, tp->cp_cmd); dev->features &= ~NETIF_F_HIGHDMA; } - rtl8169_hw_reset(ioaddr); + rtl8169_hw_reset(tp); rtl8169_schedule_work(dev, rtl8169_reinit_task); } -- cgit v1.2.3-59-g8ed1b From 554d1d027b19265c4aa3f718b3126d2b86e09a08 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 23 Dec 2010 12:38:21 +0100 Subject: iwlagn: enable only rfkill interrupt when device is down Since commit 6cd0b1cb872b3bf9fc5de4536404206ab74bafdd "iwlagn: fix hw-rfkill while the interface is down", we enable interrupts when device is not ready to receive them. However hardware, when it is in some inconsistent state, can generate other than rfkill interrupts and crash the system. I can reproduce crash with "kernel BUG at drivers/net/wireless/iwlwifi/iwl-agn.c:1010!" message, when forcing firmware restarts. To fix only enable rfkill interrupt when down device and after probe. I checked patch on laptop with 5100 device, rfkill change is still passed to user space when device is down. Signed-off-by: Stanislaw Gruszka Cc: stable@kernel.org Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-helpers.h | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c2636a7ab9ee..e0ec40ed43b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3530,9 +3530,10 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) flush_workqueue(priv->workqueue); - /* enable interrupts again in order to receive rfkill changes */ + /* User space software may expect getting rfkill changes + * even if interface is down */ iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_enable_interrupts(priv); + iwl_enable_rfkill_int(priv); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -4515,14 +4516,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 8. Enable interrupts and read RFKILL state *********************************************/ - /* enable interrupts if needed: hw bug w/a */ + /* enable rfkill interrupt: hw bug w/a */ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); } - iwl_enable_interrupts(priv); + iwl_enable_rfkill_int(priv); /* If platform's RF_KILL switch is NOT set to KILL */ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 1aaef70deaec..19f5586d362a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -163,6 +163,12 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv) IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); } +static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) +{ + IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); + iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); +} + static inline void iwl_enable_interrupts(struct iwl_priv *priv) { IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); -- cgit v1.2.3-59-g8ed1b From 919bbad580445801c22ef6ccbe624551fee652bd Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 30 Dec 2010 02:01:03 -0600 Subject: mac80211: fix mesh forwarding when ratelimited too Commit b51aff057c9d0ef6c529dc25fd9f775faf7b6c63 said: Under memory pressure, the mac80211 mesh code may helpfully print a message that it failed to clone a mesh frame and then will proceed to crash trying to use it anyway. Fix that. Avoid the reference whenever the frame copy is unsuccessful regardless of the debug message being suppressed or printed. Cc: stable@kernel.org [2.6.27+] Signed-off-by: Milton Miller Signed-off-by: John W. Linville --- net/mac80211/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b01e467b76c6..e98668fab503 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1788,11 +1788,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); - if (!fwd_skb && net_ratelimit()) { + if (!fwd_skb && net_ratelimit()) printk(KERN_DEBUG "%s: failed to clone mesh frame\n", sdata->name); + if (!fwd_skb) goto out; - } fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -- cgit v1.2.3-59-g8ed1b From d2460f4b2fa6dbdeec800414f9cf5b1fc8b71197 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 3 Jan 2011 19:42:24 +0100 Subject: mac80211: add missing synchronize_rcu commit ad0e2b5a00dbec303e4682b403bb6703d11dcdb2 Author: Johannes Berg Date: Tue Jun 1 10:19:19 2010 +0200 mac80211: simplify key locking removed the synchronization against RCU and thus opened a race window where we can use a key for TX while it is already freed. Put a synchronisation into the right place to close that window. Reported-by: Jussi Kivilinna Cc: stable@kernel.org [2.6.36+] Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/key.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index ccd676b2f599..aa1b734a5e99 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -366,6 +366,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) if (!key) return; + /* + * Synchronize so the TX path can no longer be using + * this key before we free/remove it. + */ + synchronize_rcu(); + if (key->local) ieee80211_key_disable_hw_accel(key); -- cgit v1.2.3-59-g8ed1b From 7b26e5ebd8b27b0126a84ae7f9a42aa8293d6c48 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Le Bail Date: Tue, 4 Jan 2011 09:10:20 +0000 Subject: net: typos in comments in include/linux/igmp.h There are typos in comments in include/linux/igmp.h: 83 #define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ 84 #define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ [snip] 88 #define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x11 */ 89 #define IGMP_HOST_LEAVE_MESSAGE 0x17 90 #define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x11 */ The line 88 and 90 are about REPORT messages. The IGMP_HOST_MEMBERSHIP_REPORT (IGMP V1) value is 0x12. So the comment on line 88 must be /* V2 version of 0x12 */, and the comment on line 90 must be /* V3 version of 0x12 */. Signed-off-by: Francois-Xavier Le Bail Signed-off-by: David S. Miller --- include/linux/igmp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/igmp.h b/include/linux/igmp.h index c4987f265109..74cfcff0148b 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -85,9 +85,9 @@ struct igmpv3_query { #define IGMP_DVMRP 0x13 /* DVMRP routing */ #define IGMP_PIM 0x14 /* PIM routing */ #define IGMP_TRACE 0x15 -#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x11 */ +#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */ #define IGMP_HOST_LEAVE_MESSAGE 0x17 -#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x11 */ +#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */ #define IGMP_MTRACE_RESP 0x1e #define IGMP_MTRACE 0x1f -- cgit v1.2.3-59-g8ed1b From cd2c5486526b744fb505e18c9d981b35feaf283a Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 22 Dec 2010 19:20:32 +0900 Subject: ath5k: Move mac80211 functions into new file Move mac80211 functions into new file mac80211-ops.c to have a better separation and to make base.c smaller. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/Makefile | 1 + drivers/net/wireless/ath/ath5k/base.c | 763 ++----------------------- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 774 ++++++++++++++++++++++++++ 3 files changed, 825 insertions(+), 713 deletions(-) create mode 100644 drivers/net/wireless/ath/ath5k/mac80211-ops.c diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 67dd9fd0650e..f60b3899afc4 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -14,6 +14,7 @@ ath5k-y += led.o ath5k-y += rfkill.o ath5k-y += ani.o ath5k-y += sysfs.o +ath5k-y += mac80211-ops.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o ath5k-$(CONFIG_ATH5K_AHB) += ahb.o ath5k-$(CONFIG_ATH5K_PCI) += pci.o diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index e4ec40c63396..56baee00ea0b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -61,7 +61,7 @@ #include "debug.h" #include "ani.h" -static int modparam_nohwcrypt; +int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -79,9 +79,8 @@ MODULE_LICENSE("Dual BSD/GPL"); static int ath5k_init(struct ieee80211_hw *hw); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu); -static int ath5k_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); +int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { @@ -177,38 +176,6 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; -static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, - struct ath5k_buf *bf) -{ - BUG_ON(!bf); - if (!bf->skb) - return; - dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len, - DMA_TO_DEVICE); - dev_kfree_skb_any(bf->skb); - bf->skb = NULL; - bf->skbaddr = 0; - bf->desc->ds_data = 0; -} - -static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, - struct ath5k_buf *bf) -{ - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - - BUG_ON(!bf); - if (!bf->skb) - return; - dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize, - DMA_FROM_DEVICE); - dev_kfree_skb_any(bf->skb); - bf->skb = NULL; - bf->skbaddr = 0; - bf->desc->ds_data = 0; -} - - static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) { u64 tsf = ath5k_hw_get_tsf64(ah); @@ -462,7 +429,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) * * Called with sc->lock. */ -static int +int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) { ATH5K_DBG(sc, ATH5K_DEBUG_RESET, @@ -537,8 +504,9 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->opmode = avf->opmode; } -static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, - struct ieee80211_vif *vif) +void +ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif) { struct ath_common *common = ath5k_hw_common(sc->ah); struct ath_vif_iter_data iter_data; @@ -577,7 +545,7 @@ static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); } -static void +void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) { struct ath5k_hw *ah = sc->ah; @@ -887,6 +855,37 @@ err: return ret; } +void +ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) +{ + BUG_ON(!bf); + if (!bf->skb) + return; + dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len, + DMA_TO_DEVICE); + dev_kfree_skb_any(bf->skb); + bf->skb = NULL; + bf->skbaddr = 0; + bf->desc->ds_data = 0; +} + +void +ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) +{ + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + + BUG_ON(!bf); + if (!bf->skb) + return; + dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize, + DMA_FROM_DEVICE); + dev_kfree_skb_any(bf->skb); + bf->skb = NULL; + bf->skbaddr = 0; + bf->desc->ds_data = 0; +} + static void ath5k_desc_free(struct ath5k_softc *sc) { @@ -1534,8 +1533,9 @@ unlock: * TX Handling * \*************/ -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq) +int +ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq) { struct ath5k_softc *sc = hw->priv; struct ath5k_buf *bf; @@ -1801,7 +1801,7 @@ err_unmap: * * Called with the beacon lock. */ -static int +int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { int ret; @@ -1947,7 +1947,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) * when we otherwise know we have to update the timers, but we keep it in this * function to have it all together in one place. */ -static void +void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) { struct ath5k_hw *ah = sc->ah; @@ -2049,7 +2049,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA * interrupts to detect TSF updates only. */ -static void +void ath5k_beacon_config(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; @@ -2525,7 +2525,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) return 0; } -static int +int ath5k_init_hw(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; @@ -2601,7 +2601,7 @@ static void stop_tasklets(struct ath5k_softc *sc) * if another thread does a system call and the thread doing the * stop is preempted). */ -static int +int ath5k_stop_hw(struct ath5k_softc *sc) { int ret; @@ -2939,230 +2939,8 @@ ath5k_deinit_softc(struct ath5k_softc *sc) free_irq(sc->irq, sc); } -/********************\ -* Mac80211 functions * -\********************/ - -static int -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ath5k_softc *sc = hw->priv; - u16 qnum = skb_get_queue_mapping(skb); - - if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { - dev_kfree_skb_any(skb); - return 0; - } - - return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); -} - -static int ath5k_start(struct ieee80211_hw *hw) -{ - return ath5k_init_hw(hw->priv); -} - -static void ath5k_stop(struct ieee80211_hw *hw) -{ - ath5k_stop_hw(hw->priv); -} - -static int ath5k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ath5k_softc *sc = hw->priv; - int ret; - struct ath5k_vif *avf = (void *)vif->drv_priv; - - mutex_lock(&sc->lock); - - if ((vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) - && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) { - ret = -ELNRNG; - goto end; - } - - /* Don't allow other interfaces if one ad-hoc is configured. - * TODO: Fix the problems with ad-hoc and multiple other interfaces. - * We would need to operate the HW in ad-hoc mode to allow TSF updates - * for the IBSS, but this breaks with additional AP or STA interfaces - * at the moment. */ - if (sc->num_adhoc_vifs || - (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { - ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n"); - ret = -ELNRNG; - goto end; - } - - switch (vif->type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - avf->opmode = vif->type; - break; - default: - ret = -EOPNOTSUPP; - goto end; - } - - sc->nvifs++; - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); - - /* Assign the vap/adhoc to a beacon xmit slot. */ - if ((avf->opmode == NL80211_IFTYPE_AP) || - (avf->opmode == NL80211_IFTYPE_ADHOC) || - (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { - int slot; - - WARN_ON(list_empty(&sc->bcbuf)); - avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf, - list); - list_del(&avf->bbuf->list); - - avf->bslot = 0; - for (slot = 0; slot < ATH_BCBUF; slot++) { - if (!sc->bslot[slot]) { - avf->bslot = slot; - break; - } - } - BUG_ON(sc->bslot[avf->bslot] != NULL); - sc->bslot[avf->bslot] = vif; - if (avf->opmode == NL80211_IFTYPE_AP) - sc->num_ap_vifs++; - else if (avf->opmode == NL80211_IFTYPE_ADHOC) - sc->num_adhoc_vifs++; - } - - /* Any MAC address is fine, all others are included through the - * filter. - */ - memcpy(&sc->lladdr, vif->addr, ETH_ALEN); - ath5k_hw_set_lladdr(sc->ah, vif->addr); - - memcpy(&avf->lladdr, vif->addr, ETH_ALEN); - - ath5k_mode_setup(sc, vif); - - ret = 0; -end: - mutex_unlock(&sc->lock); - return ret; -} - -static void -ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_vif *avf = (void *)vif->drv_priv; - unsigned int i; - - mutex_lock(&sc->lock); - sc->nvifs--; - - if (avf->bbuf) { - ath5k_txbuf_free_skb(sc, avf->bbuf); - list_add_tail(&avf->bbuf->list, &sc->bcbuf); - for (i = 0; i < ATH_BCBUF; i++) { - if (sc->bslot[i] == vif) { - sc->bslot[i] = NULL; - break; - } - } - avf->bbuf = NULL; - } - if (avf->opmode == NL80211_IFTYPE_AP) - sc->num_ap_vifs--; - else if (avf->opmode == NL80211_IFTYPE_ADHOC) - sc->num_adhoc_vifs--; - - ath5k_update_bssid_mask_and_opmode(sc, NULL); - mutex_unlock(&sc->lock); -} - -/* - * TODO: Phy disable/diversity etc - */ -static int -ath5k_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ieee80211_conf *conf = &hw->conf; - int ret = 0; - - mutex_lock(&sc->lock); - - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(sc, conf->channel); - if (ret < 0) - goto unlock; - } - - if ((changed & IEEE80211_CONF_CHANGE_POWER) && - (sc->power_level != conf->power_level)) { - sc->power_level = conf->power_level; - - /* Half dB steps */ - ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); - } - - /* TODO: - * 1) Move this on config_interface and handle each case - * separately eg. when we have only one STA vif, use - * AR5K_ANTMODE_SINGLE_AP - * - * 2) Allow the user to change antenna mode eg. when only - * one antenna is present - * - * 3) Allow the user to set default/tx antenna when possible - * - * 4) Default mode should handle 90% of the cases, together - * with fixed a/b and single AP modes we should be able to - * handle 99%. Sectored modes are extreme cases and i still - * haven't found a usage for them. If we decide to support them, - * then we must allow the user to set how many tx antennas we - * have available - */ - ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); - -unlock: - mutex_unlock(&sc->lock); - return ret; -} - -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - u32 mfilt[2], val; - u8 pos; - struct netdev_hw_addr *ha; - - mfilt[0] = 0; - mfilt[1] = 1; - - netdev_hw_addr_list_for_each(ha, mc_list) { - /* calculate XOR of eight 6-bit values */ - val = get_unaligned_le32(ha->addr + 0); - pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - val = get_unaligned_le32(ha->addr + 3); - pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - pos &= 0x3f; - mfilt[pos / 32] |= (1 << (pos % 32)); - /* XXX: we might be able to just do this instead, - * but not sure, needs testing, if we do use this we'd - * neet to inform below to not reset the mcast */ - /* ath5k_hw_set_mcast_filterindex(ah, - * ha->addr[5]); */ - } - - return ((u64)(mfilt[1]) << 32) | mfilt[0]; -} - -static bool ath_any_vif_assoc(struct ath5k_softc *sc) +bool +ath_any_vif_assoc(struct ath5k_softc *sc) { struct ath_vif_iter_data iter_data; iter_data.hw_macaddr = NULL; @@ -3175,262 +2953,7 @@ static bool ath_any_vif_assoc(struct ath5k_softc *sc) return iter_data.any_assoc; } -#define SUPPORTED_FIF_FLAGS \ - FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ - FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC -/* - * o always accept unicast, broadcast, and multicast traffic - * o multicast traffic for all BSSIDs will be enabled if mac80211 - * says it should be - * o maintain current state of phy ofdm or phy cck error reception. - * If the hardware detects any of these type of errors then - * ath5k_hw_get_rx_filter() will pass to us the respective - * hardware filters to be able to receive these type of frames. - * o probe request frames are accepted only when operating in - * hostap, adhoc, or monitor modes - * o enable promiscuous mode according to the interface state - * o accept beacons: - * - when operating in adhoc mode so the 802.11 layer creates - * node table entries for peers, - * - when operating in station mode for collecting rssi data when - * the station is otherwise quiet, or - * - when scanning - */ -static void ath5k_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - u32 mfilt[2], rfilt; - - mutex_lock(&sc->lock); - - mfilt[0] = multicast; - mfilt[1] = multicast >> 32; - - /* Only deal with supported flags */ - changed_flags &= SUPPORTED_FIF_FLAGS; - *new_flags &= SUPPORTED_FIF_FLAGS; - - /* If HW detects any phy or radar errors, leave those filters on. - * Also, always enable Unicast, Broadcasts and Multicast - * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ - rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | - (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | - AR5K_RX_FILTER_MCAST); - - if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { - if (*new_flags & FIF_PROMISC_IN_BSS) { - __set_bit(ATH_STAT_PROMISC, sc->status); - } else { - __clear_bit(ATH_STAT_PROMISC, sc->status); - } - } - - if (test_bit(ATH_STAT_PROMISC, sc->status)) - rfilt |= AR5K_RX_FILTER_PROM; - - /* Note, AR5K_RX_FILTER_MCAST is already enabled */ - if (*new_flags & FIF_ALLMULTI) { - mfilt[0] = ~0; - mfilt[1] = ~0; - } - - /* This is the best we can do */ - if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) - rfilt |= AR5K_RX_FILTER_PHYERR; - - /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons - * and probes for any BSSID */ - if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1)) - rfilt |= AR5K_RX_FILTER_BEACON; - - /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not - * set we should only pass on control frames for this - * station. This needs testing. I believe right now this - * enables *all* control frames, which is OK.. but - * but we should see if we can improve on granularity */ - if (*new_flags & FIF_CONTROL) - rfilt |= AR5K_RX_FILTER_CONTROL; - - /* Additional settings per mode -- this is per ath5k */ - - /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ - - switch (sc->opmode) { - case NL80211_IFTYPE_MESH_POINT: - rfilt |= AR5K_RX_FILTER_CONTROL | - AR5K_RX_FILTER_BEACON | - AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_PROM; - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - rfilt |= AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_BEACON; - break; - case NL80211_IFTYPE_STATION: - if (sc->assoc) - rfilt |= AR5K_RX_FILTER_BEACON; - default: - break; - } - - /* Set filters */ - ath5k_hw_set_rx_filter(ah, rfilt); - - /* Set multicast bits */ - ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); - /* Set the cached hw filter flags, this will later actually - * be set in HW */ - sc->filter_flags = rfilt; - - mutex_unlock(&sc->lock); -} - -static int -ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - int ret = 0; - - if (modparam_nohwcrypt) - return -EOPNOTSUPP; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - break; - case WLAN_CIPHER_SUITE_CCMP: - if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) - break; - return -EOPNOTSUPP; - default: - WARN_ON(1); - return -EINVAL; - } - - mutex_lock(&sc->lock); - - switch (cmd) { - case SET_KEY: - ret = ath_key_config(common, vif, sta, key); - if (ret >= 0) { - key->hw_key_idx = ret; - /* push IV and Michael MIC generation to stack */ - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; - ret = 0; - } - break; - case DISABLE_KEY: - ath_key_delete(common, key); - break; - default: - ret = -EINVAL; - } - - mmiowb(); - mutex_unlock(&sc->lock); - return ret; -} - -static int -ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct ath5k_softc *sc = hw->priv; - - /* Force update */ - ath5k_hw_update_mib_counters(sc->ah); - - stats->dot11ACKFailureCount = sc->stats.ack_fail; - stats->dot11RTSFailureCount = sc->stats.rts_fail; - stats->dot11RTSSuccessCount = sc->stats.rts_ok; - stats->dot11FCSErrorCount = sc->stats.fcs_error; - - return 0; -} - -static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct ath5k_softc *sc = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - struct ath_common *common = ath5k_hw_common(sc->ah); - struct ath_cycle_counters *cc = &common->cc_survey; - unsigned int div = common->clockrate * 1000; - - if (idx != 0) - return -ENOENT; - - spin_lock_bh(&common->cc_lock); - ath_hw_cycle_counters_update(common); - if (cc->cycles > 0) { - sc->survey.channel_time += cc->cycles / div; - sc->survey.channel_time_busy += cc->rx_busy / div; - sc->survey.channel_time_rx += cc->rx_frame / div; - sc->survey.channel_time_tx += cc->tx_frame / div; - } - memset(cc, 0, sizeof(*cc)); - spin_unlock_bh(&common->cc_lock); - - memcpy(survey, &sc->survey, sizeof(*survey)); - - survey->channel = conf->channel; - survey->noise = sc->ah->ah_noise_floor; - survey->filled = SURVEY_INFO_NOISE_DBM | - SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_RX | - SURVEY_INFO_CHANNEL_TIME_TX; - - return 0; -} - -static u64 -ath5k_get_tsf(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - - return ath5k_hw_get_tsf64(sc->ah); -} - -static void -ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) -{ - struct ath5k_softc *sc = hw->priv; - - ath5k_hw_set_tsf64(sc->ah, tsf); -} - -static void -ath5k_reset_tsf(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - - /* - * in IBSS mode we need to update the beacon timers too. - * this will also reset the TSF if we call it with 0 - */ - if (sc->opmode == NL80211_IFTYPE_ADHOC) - ath5k_beacon_update_timers(sc, 0); - else - ath5k_hw_reset_tsf(sc->ah); -} - -static void +void set_beacon_filter(struct ieee80211_hw *hw, bool enable) { struct ath5k_softc *sc = hw->priv; @@ -3444,189 +2967,3 @@ set_beacon_filter(struct ieee80211_hw *hw, bool enable) ath5k_hw_set_rx_filter(ah, rfilt); sc->filter_flags = rfilt; } - -static void ath5k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct ath5k_vif *avf = (void *)vif->drv_priv; - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; - - mutex_lock(&sc->lock); - - if (changes & BSS_CHANGED_BSSID) { - /* Cache for later use during resets */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = 0; - ath5k_hw_set_bssid(ah); - mmiowb(); - } - - if (changes & BSS_CHANGED_BEACON_INT) - sc->bintval = bss_conf->beacon_int; - - if (changes & BSS_CHANGED_ASSOC) { - avf->assoc = bss_conf->assoc; - if (bss_conf->assoc) - sc->assoc = bss_conf->assoc; - else - sc->assoc = ath_any_vif_assoc(sc); - - if (sc->opmode == NL80211_IFTYPE_STATION) - set_beacon_filter(hw, sc->assoc); - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); - if (bss_conf->assoc) { - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); - common->curaid = bss_conf->aid; - ath5k_hw_set_bssid(ah); - /* Once ANI is available you would start it here */ - } - } - - if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&sc->block, flags); - ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&sc->block, flags); - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) - sc->enable_beacon = bss_conf->enable_beacon; - - if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON_INT)) - ath5k_beacon_config(sc); - - mutex_unlock(&sc->lock); -} - -static void ath5k_sw_scan_start(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - if (!sc->assoc) - ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); -} - -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); -} - -/** - * ath5k_set_coverage_class - Set IEEE 802.11 coverage class - * - * @hw: struct ieee80211_hw pointer - * @coverage_class: IEEE 802.11 coverage class number - * - * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given - * coverage class. The values are persistent, they are restored after device - * reset. - */ -static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) -{ - struct ath5k_softc *sc = hw->priv; - - mutex_lock(&sc->lock); - ath5k_hw_set_coverage_class(sc->ah, coverage_class); - mutex_unlock(&sc->lock); -} - -static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath5k_txq_info qi; - int ret = 0; - - if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) - return 0; - - mutex_lock(&sc->lock); - - ath5k_hw_get_tx_queueprops(ah, queue, &qi); - - qi.tqi_aifs = params->aifs; - qi.tqi_cw_min = params->cw_min; - qi.tqi_cw_max = params->cw_max; - qi.tqi_burst_time = params->txop; - - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, - "Configure tx [queue %d], " - "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - queue, params->aifs, params->cw_min, - params->cw_max, params->txop); - - if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { - ATH5K_ERR(sc, - "Unable to update hardware queue %u!\n", queue); - ret = -EIO; - } else - ath5k_hw_reset_tx_queue(ah, queue); - - mutex_unlock(&sc->lock); - - return ret; -} - -static int ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) -{ - struct ath5k_softc *sc = hw->priv; - - if (tx_ant == 1 && rx_ant == 1) - ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A); - else if (tx_ant == 2 && rx_ant == 2) - ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B); - else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) - ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT); - else - return -EINVAL; - return 0; -} - -static int ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) -{ - struct ath5k_softc *sc = hw->priv; - - switch (sc->ah->ah_ant_mode) { - case AR5K_ANTMODE_FIXED_A: - *tx_ant = 1; *rx_ant = 1; break; - case AR5K_ANTMODE_FIXED_B: - *tx_ant = 2; *rx_ant = 2; break; - case AR5K_ANTMODE_DEFAULT: - *tx_ant = 3; *rx_ant = 3; break; - } - return 0; -} - -const struct ieee80211_ops ath5k_hw_ops = { - .tx = ath5k_tx, - .start = ath5k_start, - .stop = ath5k_stop, - .add_interface = ath5k_add_interface, - .remove_interface = ath5k_remove_interface, - .config = ath5k_config, - .prepare_multicast = ath5k_prepare_multicast, - .configure_filter = ath5k_configure_filter, - .set_key = ath5k_set_key, - .get_stats = ath5k_get_stats, - .get_survey = ath5k_get_survey, - .conf_tx = ath5k_conf_tx, - .get_tsf = ath5k_get_tsf, - .set_tsf = ath5k_set_tsf, - .reset_tsf = ath5k_reset_tsf, - .bss_info_changed = ath5k_bss_info_changed, - .sw_scan_start = ath5k_sw_scan_start, - .sw_scan_complete = ath5k_sw_scan_complete, - .set_coverage_class = ath5k_set_coverage_class, - .set_antenna = ath5k_set_antenna, - .get_antenna = ath5k_get_antenna, -}; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c new file mode 100644 index 000000000000..de257a3430be --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -0,0 +1,774 @@ +/*- + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting + * Copyright (c) 2004-2005 Atheros Communications, Inc. + * Copyright (c) 2006 Devicescape Software, Inc. + * Copyright (c) 2007 Jiri Slaby + * Copyright (c) 2007 Luis R. Rodriguez + * Copyright (c) 2010 Bruno Randolf + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include + +#include "base.h" +#include "reg.h" + +extern int modparam_nohwcrypt; + +/* functions used from base.c */ +void set_beacon_filter(struct ieee80211_hw *hw, bool enable); +bool ath_any_vif_assoc(struct ath5k_softc *sc); +int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq); +int ath5k_init_hw(struct ath5k_softc *sc); +int ath5k_stop_hw(struct ath5k_softc *sc); +void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); +void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif); +int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan); +void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); +int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void ath5k_beacon_config(struct ath5k_softc *sc); +void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); +void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); + +/********************\ +* Mac80211 functions * +\********************/ + +static int +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ath5k_softc *sc = hw->priv; + u16 qnum = skb_get_queue_mapping(skb); + + if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { + dev_kfree_skb_any(skb); + return 0; + } + + return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); +} + + +static int +ath5k_start(struct ieee80211_hw *hw) +{ + return ath5k_init_hw(hw->priv); +} + + +static void +ath5k_stop(struct ieee80211_hw *hw) +{ + ath5k_stop_hw(hw->priv); +} + + +static int +ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct ath5k_softc *sc = hw->priv; + int ret; + struct ath5k_vif *avf = (void *)vif->drv_priv; + + mutex_lock(&sc->lock); + + if ((vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_ADHOC) + && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) { + ret = -ELNRNG; + goto end; + } + + /* Don't allow other interfaces if one ad-hoc is configured. + * TODO: Fix the problems with ad-hoc and multiple other interfaces. + * We would need to operate the HW in ad-hoc mode to allow TSF updates + * for the IBSS, but this breaks with additional AP or STA interfaces + * at the moment. */ + if (sc->num_adhoc_vifs || + (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { + ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n"); + ret = -ELNRNG; + goto end; + } + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + avf->opmode = vif->type; + break; + default: + ret = -EOPNOTSUPP; + goto end; + } + + sc->nvifs++; + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); + + /* Assign the vap/adhoc to a beacon xmit slot. */ + if ((avf->opmode == NL80211_IFTYPE_AP) || + (avf->opmode == NL80211_IFTYPE_ADHOC) || + (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { + int slot; + + WARN_ON(list_empty(&sc->bcbuf)); + avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf, + list); + list_del(&avf->bbuf->list); + + avf->bslot = 0; + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (!sc->bslot[slot]) { + avf->bslot = slot; + break; + } + } + BUG_ON(sc->bslot[avf->bslot] != NULL); + sc->bslot[avf->bslot] = vif; + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs++; + else if (avf->opmode == NL80211_IFTYPE_ADHOC) + sc->num_adhoc_vifs++; + } + + /* Any MAC address is fine, all others are included through the + * filter. + */ + memcpy(&sc->lladdr, vif->addr, ETH_ALEN); + ath5k_hw_set_lladdr(sc->ah, vif->addr); + + memcpy(&avf->lladdr, vif->addr, ETH_ALEN); + + ath5k_mode_setup(sc, vif); + + ret = 0; +end: + mutex_unlock(&sc->lock); + return ret; +} + + +static void +ath5k_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_vif *avf = (void *)vif->drv_priv; + unsigned int i; + + mutex_lock(&sc->lock); + sc->nvifs--; + + if (avf->bbuf) { + ath5k_txbuf_free_skb(sc, avf->bbuf); + list_add_tail(&avf->bbuf->list, &sc->bcbuf); + for (i = 0; i < ATH_BCBUF; i++) { + if (sc->bslot[i] == vif) { + sc->bslot[i] = NULL; + break; + } + } + avf->bbuf = NULL; + } + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs--; + else if (avf->opmode == NL80211_IFTYPE_ADHOC) + sc->num_adhoc_vifs--; + + ath5k_update_bssid_mask_and_opmode(sc, NULL); + mutex_unlock(&sc->lock); +} + + +/* + * TODO: Phy disable/diversity etc + */ +static int +ath5k_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ieee80211_conf *conf = &hw->conf; + int ret = 0; + + mutex_lock(&sc->lock); + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + ret = ath5k_chan_set(sc, conf->channel); + if (ret < 0) + goto unlock; + } + + if ((changed & IEEE80211_CONF_CHANGE_POWER) && + (sc->power_level != conf->power_level)) { + sc->power_level = conf->power_level; + + /* Half dB steps */ + ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); + } + + /* TODO: + * 1) Move this on config_interface and handle each case + * separately eg. when we have only one STA vif, use + * AR5K_ANTMODE_SINGLE_AP + * + * 2) Allow the user to change antenna mode eg. when only + * one antenna is present + * + * 3) Allow the user to set default/tx antenna when possible + * + * 4) Default mode should handle 90% of the cases, together + * with fixed a/b and single AP modes we should be able to + * handle 99%. Sectored modes are extreme cases and i still + * haven't found a usage for them. If we decide to support them, + * then we must allow the user to set how many tx antennas we + * have available + */ + ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); + +unlock: + mutex_unlock(&sc->lock); + return ret; +} + + +static void +ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, u32 changes) +{ + struct ath5k_vif *avf = (void *)vif->drv_priv; + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + unsigned long flags; + + mutex_lock(&sc->lock); + + if (changes & BSS_CHANGED_BSSID) { + /* Cache for later use during resets */ + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = 0; + ath5k_hw_set_bssid(ah); + mmiowb(); + } + + if (changes & BSS_CHANGED_BEACON_INT) + sc->bintval = bss_conf->beacon_int; + + if (changes & BSS_CHANGED_ASSOC) { + avf->assoc = bss_conf->assoc; + if (bss_conf->assoc) + sc->assoc = bss_conf->assoc; + else + sc->assoc = ath_any_vif_assoc(sc); + + if (sc->opmode == NL80211_IFTYPE_STATION) + set_beacon_filter(hw, sc->assoc); + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); + if (bss_conf->assoc) { + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Bss Info ASSOC %d, bssid: %pM\n", + bss_conf->aid, common->curbssid); + common->curaid = bss_conf->aid; + ath5k_hw_set_bssid(ah); + /* Once ANI is available you would start it here */ + } + } + + if (changes & BSS_CHANGED_BEACON) { + spin_lock_irqsave(&sc->block, flags); + ath5k_beacon_update(hw, vif); + spin_unlock_irqrestore(&sc->block, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) + sc->enable_beacon = bss_conf->enable_beacon; + + if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | + BSS_CHANGED_BEACON_INT)) + ath5k_beacon_config(sc); + + mutex_unlock(&sc->lock); +} + + +static u64 +ath5k_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + u32 mfilt[2], val; + u8 pos; + struct netdev_hw_addr *ha; + + mfilt[0] = 0; + mfilt[1] = 1; + + netdev_hw_addr_list_for_each(ha, mc_list) { + /* calculate XOR of eight 6-bit values */ + val = get_unaligned_le32(ha->addr + 0); + pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + val = get_unaligned_le32(ha->addr + 3); + pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + pos &= 0x3f; + mfilt[pos / 32] |= (1 << (pos % 32)); + /* XXX: we might be able to just do this instead, + * but not sure, needs testing, if we do use this we'd + * neet to inform below to not reset the mcast */ + /* ath5k_hw_set_mcast_filterindex(ah, + * ha->addr[5]); */ + } + + return ((u64)(mfilt[1]) << 32) | mfilt[0]; +} + + +/* + * o always accept unicast, broadcast, and multicast traffic + * o multicast traffic for all BSSIDs will be enabled if mac80211 + * says it should be + * o maintain current state of phy ofdm or phy cck error reception. + * If the hardware detects any of these type of errors then + * ath5k_hw_get_rx_filter() will pass to us the respective + * hardware filters to be able to receive these type of frames. + * o probe request frames are accepted only when operating in + * hostap, adhoc, or monitor modes + * o enable promiscuous mode according to the interface state + * o accept beacons: + * - when operating in adhoc mode so the 802.11 layer creates + * node table entries for peers, + * - when operating in station mode for collecting rssi data when + * the station is otherwise quiet, or + * - when scanning + */ +static void +ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, + unsigned int *new_flags, u64 multicast) +{ +#define SUPPORTED_FIF_FLAGS \ + (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ + FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ + FIF_BCN_PRBRESP_PROMISC) + + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + u32 mfilt[2], rfilt; + + mutex_lock(&sc->lock); + + mfilt[0] = multicast; + mfilt[1] = multicast >> 32; + + /* Only deal with supported flags */ + changed_flags &= SUPPORTED_FIF_FLAGS; + *new_flags &= SUPPORTED_FIF_FLAGS; + + /* If HW detects any phy or radar errors, leave those filters on. + * Also, always enable Unicast, Broadcasts and Multicast + * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ + rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | + (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | + AR5K_RX_FILTER_MCAST); + + if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + if (*new_flags & FIF_PROMISC_IN_BSS) + __set_bit(ATH_STAT_PROMISC, sc->status); + else + __clear_bit(ATH_STAT_PROMISC, sc->status); + } + + if (test_bit(ATH_STAT_PROMISC, sc->status)) + rfilt |= AR5K_RX_FILTER_PROM; + + /* Note, AR5K_RX_FILTER_MCAST is already enabled */ + if (*new_flags & FIF_ALLMULTI) { + mfilt[0] = ~0; + mfilt[1] = ~0; + } + + /* This is the best we can do */ + if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) + rfilt |= AR5K_RX_FILTER_PHYERR; + + /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons + * and probes for any BSSID */ + if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1)) + rfilt |= AR5K_RX_FILTER_BEACON; + + /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not + * set we should only pass on control frames for this + * station. This needs testing. I believe right now this + * enables *all* control frames, which is OK.. but + * but we should see if we can improve on granularity */ + if (*new_flags & FIF_CONTROL) + rfilt |= AR5K_RX_FILTER_CONTROL; + + /* Additional settings per mode -- this is per ath5k */ + + /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ + + switch (sc->opmode) { + case NL80211_IFTYPE_MESH_POINT: + rfilt |= AR5K_RX_FILTER_CONTROL | + AR5K_RX_FILTER_BEACON | + AR5K_RX_FILTER_PROBEREQ | + AR5K_RX_FILTER_PROM; + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + rfilt |= AR5K_RX_FILTER_PROBEREQ | + AR5K_RX_FILTER_BEACON; + break; + case NL80211_IFTYPE_STATION: + if (sc->assoc) + rfilt |= AR5K_RX_FILTER_BEACON; + default: + break; + } + + /* Set filters */ + ath5k_hw_set_rx_filter(ah, rfilt); + + /* Set multicast bits */ + ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); + /* Set the cached hw filter flags, this will later actually + * be set in HW */ + sc->filter_flags = rfilt; + + mutex_unlock(&sc->lock); +} + + +static int +ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + int ret = 0; + + if (modparam_nohwcrypt) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + break; + case WLAN_CIPHER_SUITE_CCMP: + if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) + break; + return -EOPNOTSUPP; + default: + WARN_ON(1); + return -EINVAL; + } + + mutex_lock(&sc->lock); + + switch (cmd) { + case SET_KEY: + ret = ath_key_config(common, vif, sta, key); + if (ret >= 0) { + key->hw_key_idx = ret; + /* push IV and Michael MIC generation to stack */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + ret = 0; + } + break; + case DISABLE_KEY: + ath_key_delete(common, key); + break; + default: + ret = -EINVAL; + } + + mmiowb(); + mutex_unlock(&sc->lock); + return ret; +} + + +static void +ath5k_sw_scan_start(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + if (!sc->assoc) + ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); +} + + +static void +ath5k_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); +} + + +static int +ath5k_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct ath5k_softc *sc = hw->priv; + + /* Force update */ + ath5k_hw_update_mib_counters(sc->ah); + + stats->dot11ACKFailureCount = sc->stats.ack_fail; + stats->dot11RTSFailureCount = sc->stats.rts_fail; + stats->dot11RTSSuccessCount = sc->stats.rts_ok; + stats->dot11FCSErrorCount = sc->stats.fcs_error; + + return 0; +} + + +static int +ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath5k_txq_info qi; + int ret = 0; + + if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) + return 0; + + mutex_lock(&sc->lock); + + ath5k_hw_get_tx_queueprops(ah, queue, &qi); + + qi.tqi_aifs = params->aifs; + qi.tqi_cw_min = params->cw_min; + qi.tqi_cw_max = params->cw_max; + qi.tqi_burst_time = params->txop; + + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Configure tx [queue %d], " + "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + queue, params->aifs, params->cw_min, + params->cw_max, params->txop); + + if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { + ATH5K_ERR(sc, + "Unable to update hardware queue %u!\n", queue); + ret = -EIO; + } else + ath5k_hw_reset_tx_queue(ah, queue); + + mutex_unlock(&sc->lock); + + return ret; +} + + +static u64 +ath5k_get_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + return ath5k_hw_get_tsf64(sc->ah); +} + + +static void +ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + struct ath5k_softc *sc = hw->priv; + + ath5k_hw_set_tsf64(sc->ah, tsf); +} + + +static void +ath5k_reset_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + /* + * in IBSS mode we need to update the beacon timers too. + * this will also reset the TSF if we call it with 0 + */ + if (sc->opmode == NL80211_IFTYPE_ADHOC) + ath5k_beacon_update_timers(sc, 0); + else + ath5k_hw_reset_tsf(sc->ah); +} + + +static int +ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) +{ + struct ath5k_softc *sc = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + struct ath_common *common = ath5k_hw_common(sc->ah); + struct ath_cycle_counters *cc = &common->cc_survey; + unsigned int div = common->clockrate * 1000; + + if (idx != 0) + return -ENOENT; + + spin_lock_bh(&common->cc_lock); + ath_hw_cycle_counters_update(common); + if (cc->cycles > 0) { + sc->survey.channel_time += cc->cycles / div; + sc->survey.channel_time_busy += cc->rx_busy / div; + sc->survey.channel_time_rx += cc->rx_frame / div; + sc->survey.channel_time_tx += cc->tx_frame / div; + } + memset(cc, 0, sizeof(*cc)); + spin_unlock_bh(&common->cc_lock); + + memcpy(survey, &sc->survey, sizeof(*survey)); + + survey->channel = conf->channel; + survey->noise = sc->ah->ah_noise_floor; + survey->filled = SURVEY_INFO_NOISE_DBM | + SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + + return 0; +} + + +/** + * ath5k_set_coverage_class - Set IEEE 802.11 coverage class + * + * @hw: struct ieee80211_hw pointer + * @coverage_class: IEEE 802.11 coverage class number + * + * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given + * coverage class. The values are persistent, they are restored after device + * reset. + */ +static void +ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) +{ + struct ath5k_softc *sc = hw->priv; + + mutex_lock(&sc->lock); + ath5k_hw_set_coverage_class(sc->ah, coverage_class); + mutex_unlock(&sc->lock); +} + + +static int +ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) +{ + struct ath5k_softc *sc = hw->priv; + + if (tx_ant == 1 && rx_ant == 1) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A); + else if (tx_ant == 2 && rx_ant == 2) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B); + else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) + ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT); + else + return -EINVAL; + return 0; +} + + +static int +ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct ath5k_softc *sc = hw->priv; + + switch (sc->ah->ah_ant_mode) { + case AR5K_ANTMODE_FIXED_A: + *tx_ant = 1; *rx_ant = 1; break; + case AR5K_ANTMODE_FIXED_B: + *tx_ant = 2; *rx_ant = 2; break; + case AR5K_ANTMODE_DEFAULT: + *tx_ant = 3; *rx_ant = 3; break; + } + return 0; +} + + +const struct ieee80211_ops ath5k_hw_ops = { + .tx = ath5k_tx, + .start = ath5k_start, + .stop = ath5k_stop, + .add_interface = ath5k_add_interface, + /* .change_interface = not implemented */ + .remove_interface = ath5k_remove_interface, + .config = ath5k_config, + .bss_info_changed = ath5k_bss_info_changed, + .prepare_multicast = ath5k_prepare_multicast, + .configure_filter = ath5k_configure_filter, + /* .set_tim = not implemented */ + .set_key = ath5k_set_key, + /* .update_tkip_key = not implemented */ + /* .hw_scan = not implemented */ + .sw_scan_start = ath5k_sw_scan_start, + .sw_scan_complete = ath5k_sw_scan_complete, + .get_stats = ath5k_get_stats, + /* .get_tkip_seq = not implemented */ + /* .set_frag_threshold = not implemented */ + /* .set_rts_threshold = not implemented */ + /* .sta_add = not implemented */ + /* .sta_remove = not implemented */ + /* .sta_notify = not implemented */ + .conf_tx = ath5k_conf_tx, + .get_tsf = ath5k_get_tsf, + .set_tsf = ath5k_set_tsf, + .reset_tsf = ath5k_reset_tsf, + /* .tx_last_beacon = not implemented */ + /* .ampdu_action = not needed */ + .get_survey = ath5k_get_survey, + .set_coverage_class = ath5k_set_coverage_class, + /* .rfkill_poll = not implemented */ + /* .flush = not implemented */ + /* .channel_switch = not implemented */ + /* .napi_poll = not implemented */ + .set_antenna = ath5k_set_antenna, + .get_antenna = ath5k_get_antenna, +}; -- cgit v1.2.3-59-g8ed1b From cd017f25e391dfabaca185bb4a5aefd02fd6c0ca Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 23 Dec 2010 15:12:30 +0100 Subject: iwlagn: fix scan tx antenna setting on 5Ghz band Looks that we do not set correctly antennas when scanning on 5Ghz band and when bluetooth is enabled, because priv->cfg->scan_tx_antennas[band] is only defined for IEEE80211_BAND_2GHZ. To fix we check band before limiting antennas to first one. This allow to remove hard coded cfg->scan_tx_antennas[band]. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 7 +------ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 14 +++++--------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f4bec3201ef9..af505bcd7ae0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -596,12 +596,7 @@ struct iwl_cfg iwl6005_2bg_cfg = { .need_dc_calib = true, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true, \ - /* \ - *Due to bluetooth, we transmit 2.4 GHz probes \ - * only on antenna A \ - */ \ - .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A + .adv_pm = true \ struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4bc82fcf1652..3dee87e8f55d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1492,15 +1492,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->scan_rx_antennas[band]) rx_ant = priv->cfg->scan_rx_antennas[band]; - if (priv->cfg->scan_tx_antennas[band]) - scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; - - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ - scan_tx_antennas = first_antenna( - priv->cfg->scan_tx_antennas[band]); + if (band == IEEE80211_BAND_2GHZ && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + /* transmit 2.4 GHz probes only on first antenna */ + scan_tx_antennas = first_antenna(scan_tx_antennas); } priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f80685ad2674..a3474376fdbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -411,7 +411,6 @@ struct iwl_cfg { const bool need_dc_calib; /* if used set to true */ const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; - u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; enum iwl_led_mode led_mode; const bool adv_pm; const bool rx_with_siso_diversity; -- cgit v1.2.3-59-g8ed1b From 52671e43dbfb0e0dfa5fab604cb3984bd1d777a6 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Thu, 23 Dec 2010 21:06:57 +0530 Subject: ath9k: spin_lock_bh is not required within tasklet context. Disabling BH is not required while running from a tasklet context and so replace spin_lock_bh with just spin_lock. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c5cf8639e721..0f1b62456141 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -599,7 +599,7 @@ void ath9k_tasklet(unsigned long data) return; } - spin_lock_bh(&sc->sc_pcu_lock); + spin_lock(&sc->sc_pcu_lock); if (!ath9k_hw_check_alive(ah)) ieee80211_queue_work(sc->hw, &sc->hw_check_work); @@ -643,7 +643,7 @@ void ath9k_tasklet(unsigned long data) /* re-enable hardware interrupt */ ath9k_hw_enable_interrupts(ah); - spin_unlock_bh(&sc->sc_pcu_lock); + spin_unlock(&sc->sc_pcu_lock); ath9k_ps_restore(sc); } -- cgit v1.2.3-59-g8ed1b From ad9082adfc0a6bdcef1bad2f22485575479d7a9d Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 25 Dec 2010 15:03:58 +0900 Subject: airo: use simple_write_to_buffer Simplify write file operation for /proc files by using simple_write_to_buffer(). Signed-off-by: Akinobu Mita Cc: "John W. Linville" Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a36e7870b03e..57a79b0475f6 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -4652,24 +4652,18 @@ static ssize_t proc_write( struct file *file, size_t len, loff_t *offset ) { - loff_t pos = *offset; + ssize_t ret; struct proc_data *priv = file->private_data; if (!priv->wbuffer) return -EINVAL; - if (pos < 0) - return -EINVAL; - if (pos >= priv->maxwritelen) - return 0; - if (len > priv->maxwritelen - pos) - len = priv->maxwritelen - pos; - if (copy_from_user(priv->wbuffer + pos, buffer, len)) - return -EFAULT; - if ( pos + len > priv->writelen ) - priv->writelen = len + file->f_pos; - *offset = pos + len; - return len; + ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset, + buffer, len); + if (ret > 0) + priv->writelen = max_t(int, priv->writelen, *offset); + + return ret; } static int proc_status_open(struct inode *inode, struct file *file) -- cgit v1.2.3-59-g8ed1b From 44cefead807daf96d0f43eb494b1eb5edb5454bf Mon Sep 17 00:00:00 2001 From: Brian Prodoehl Date: Sat, 25 Dec 2010 14:34:43 -0500 Subject: ath9k: fix spur mitigation no-spur case for AR9002 For the AR9002, the spur frequency read from the EEPROM is mangled before being compared against AR_NO_SPUR. This results in the driver trying to set up the spur mitigation for bogus spurs, rather than cleanly breaking out. Signed-off-by: Brian Prodoehl Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 7ae66a889f5a..7d68d61e406b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -203,13 +203,14 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); + if (AR_NO_SPUR == cur_bb_spur) + break; + if (is2GHz) cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; else cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; - if (AR_NO_SPUR == cur_bb_spur) - break; cur_bb_spur = cur_bb_spur - freq; if (IS_CHAN_HT40(chan)) { -- cgit v1.2.3-59-g8ed1b From bb007554fe1f66c4796c7c7ae7bfc735fc8213f7 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 26 Dec 2010 12:10:05 -0500 Subject: ath5k: fix cycle counter inconsistent locking ath5k_reset is called from process context and takes the cc_lock with plain spin_lock(), but cc_lock can also be taken from tasklets in softirq context. Thus we need to at least use spin_lock_bh. This fixes the following lockdep warning: [ 19.967874] sky2 0000:01:00.0: eth0: enabling interface [ 19.982761] ieee80211 phy0: device now idle [ 20.904809] NET: Registered protocol family 17 [ 21.243857] ieee80211 phy0: device no longer idle - scanning [ 21.404343] [ 21.404346] ================================= [ 21.404450] [ INFO: inconsistent lock state ] [ 21.404518] 2.6.37-rc7-wl+ #242 [ 21.404582] --------------------------------- [ 21.404650] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. [ 21.404721] kworker/u:4/982 [HC0[0]:SC1[3]:HE1:SE0] takes: [ 21.404792] (&(&common->cc_lock)->rlock){+.?...}, at: [] ath5k_ani_calibration+0x29/0x5d9 [ath5k] [ 21.405011] {SOFTIRQ-ON-W} state was registered at: [ 21.405011] [] __lock_acquire+0x62f/0x13c1 [ 21.405011] [] lock_acquire+0xd5/0xf1 [ 21.405011] [] _raw_spin_lock+0x45/0x72 [ 21.405011] [] ath5k_reset+0x2c0/0x349 [ath5k] [ 21.405011] [] ath5k_start+0xb8/0x139 [ath5k] [ 21.405011] [] ieee80211_do_open+0x13f/0x819 [mac80211] [ 21.405011] [] ieee80211_open+0x63/0x66 [mac80211] [ 21.405011] [] __dev_open+0x8d/0xb6 [ 21.405011] [] __dev_change_flags+0x9d/0x114 [ 21.405011] [] dev_change_flags+0x18/0x44 [ 21.405011] [] do_setlink+0x23f/0x521 [ 21.405011] [] rtnl_setlink+0xe6/0xea [ 21.405011] [] rtnetlink_rcv_msg+0x18a/0x1a0 [ 21.405011] [] netlink_rcv_skb+0x35/0x7b [ 21.405011] [] rtnetlink_rcv+0x20/0x27 [ 21.405011] [] netlink_unicast+0x1bb/0x21e [ 21.405011] [] netlink_sendmsg+0x23b/0x288 [ 21.405011] [] sock_sendmsg+0xac/0xc4 [ 21.405011] [] sys_sendmsg+0x152/0x1a2 [ 21.405011] [] sys_socketcall+0x214/0x275 [ 21.405011] [] sysenter_do_call+0x12/0x36 [ 21.405011] irq event stamp: 138032 [ 21.405011] hardirqs last enabled at (138032): [] _raw_spin_unlock_irqrestore+0x3b/0x5e [ 21.405011] hardirqs last disabled at (138031): [] _raw_spin_lock_irqsave+0x18/0x7e [ 21.405011] softirqs last enabled at (138024): [] ieee80211_tx_skb+0x47/0x49 [mac80211] [ 21.405011] softirqs last disabled at (138027): [] do_softirq+0x63/0xb4 [ 21.405011] [ 21.405011] other info that might help us debug this: [ 21.405011] 3 locks held by kworker/u:4/982: [ 21.405011] #0: (name){+.+.+.}, at: [] process_one_work+0x1b8/0x41b [ 21.405011] #1: ((&(&local->scan_work)->work)){+.+.+.}, at: [] process_one_work+0x1b8/0x41b [ 21.405011] #2: (&local->mtx){+.+.+.}, at: [] ieee80211_scan_work+0x32/0x4a4 [mac80211] [ 21.405011] [ 21.405011] stack backtrace: [ 21.405011] Pid: 982, comm: kworker/u:4 Not tainted 2.6.37-rc7-wl+ #242 [ 21.405011] Call Trace: [ 21.405011] [] ? printk+0x1d/0x25 [ 21.405011] [] print_usage_bug+0x181/0x18b [ 21.405011] [] ? check_usage_forwards+0x0/0xb6 [ 21.405011] [] mark_lock+0x2a0/0x4aa [ 21.405011] [] ? trace_hardirqs_off+0xb/0xd [ 21.405011] [] __lock_acquire+0x5ba/0x13c1 [ 21.405011] [] ? trace_hardirqs_off_caller+0x18/0x8d [ 21.405011] [] ? trace_hardirqs_off+0xb/0xd [ 21.405011] [] ? local_clock+0x2c/0x4f [ 21.405011] [] ? save_trace+0x2/0xa0 [ 21.405011] [] ? mark_held_locks+0x43/0x5b [ 21.405011] [] ? _raw_spin_unlock_irqrestore+0x3b/0x5e [ 21.405011] [] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k] [ 21.405011] [] lock_acquire+0xd5/0xf1 [ 21.405011] [] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k] [ 21.405011] [] _raw_spin_lock_bh+0x4a/0x77 [ 21.405011] [] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k] [ 21.405011] [] ath5k_ani_calibration+0x29/0x5d9 [ath5k] [ 21.405011] [] ? mark_held_locks+0x43/0x5b [ 21.405011] [] ath5k_tasklet_ani+0x1d/0x27 [ath5k] [ 21.405011] [] tasklet_action+0x96/0x137 [ 21.405011] [] __do_softirq+0xde/0x1c3 [ 21.405011] [] ? arch_get_unmapped_area_topdown+0x3b/0x127 [ 21.405011] [] ? __do_softirq+0x0/0x1c3 [ 21.405011] [] ? irq_exit+0x3d/0x49 [ 21.405011] [] ? do_IRQ+0x98/0xac [ 21.405011] [] ? common_interrupt+0x2e/0x34 [ 21.405011] [] ? sys_unshare+0x57/0x226 [ 21.405011] [] ? queue_delayed_work+0x1/0x27 [ 21.405011] [] ? ieee80211_queue_delayed_work+0x2e/0x33 [mac80211] [ 21.405011] [] ? ieee80211_scan_work+0x45f/0x4a4 [mac80211] [ 21.405011] [] ? process_one_work+0x26e/0x41b [ 21.405011] [] ? process_one_work+0x1b8/0x41b [ 21.405011] [] ? ieee80211_scan_work+0x0/0x4a4 [mac80211] [ 21.405011] [] ? worker_thread+0x18a/0x2a5 [ 21.405011] [] ? _raw_spin_unlock_irqrestore+0x47/0x5e [ 21.405011] [] ? worker_thread+0x0/0x2a5 [ 21.405011] [] ? kthread+0x67/0x6c [ 21.405011] [] ? kthread+0x0/0x6c [ 21.405011] [] ? kernel_thread_helper+0x6/0x10 Signed-off-by: Bob Copeland Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 56baee00ea0b..fce9a987789c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2703,11 +2703,11 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, /* clear survey data and cycle counters */ memset(&sc->survey, 0, sizeof(sc->survey)); - spin_lock(&common->cc_lock); + spin_lock_bh(&common->cc_lock); ath_hw_cycle_counters_update(common); memset(&common->cc_survey, 0, sizeof(common->cc_survey)); memset(&common->cc_ani, 0, sizeof(common->cc_ani)); - spin_unlock(&common->cc_lock); + spin_unlock_bh(&common->cc_lock); /* * Change channels and update the h/w rate map if we're switching; -- cgit v1.2.3-59-g8ed1b From c9e57f0fdccf74ef7884fed61d212e524b9c4bcd Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Dec 2010 18:21:53 +0100 Subject: carl9170: add missing return-value check This patch adds a forgotten bail-out path. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 82bc81c4c930..122e75ee8eff 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1676,6 +1676,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, 0x200); + if (err) + return err; err = carl9170_init_rf_bank4_pwr(ar, channel->band == IEEE80211_BAND_5GHZ, -- cgit v1.2.3-59-g8ed1b From 3b386510f49ff5c6e6ac1001da4f3c922ae7de3f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Dec 2010 18:22:16 +0100 Subject: carl9170: reduce channel change delay By removing two "safety" msleeps (and an echo nop), the channel change delay is effectively halved. Previously, the delay could be as long as 260 ms and the device could not go off-channel without risking to miss the next DTIM beacon [interval ~307 ms]. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 122e75ee8eff..b6b0de600506 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1029,8 +1029,6 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, if (err) return err; - msleep(20); - return 0; } @@ -1660,12 +1658,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, return err; cmd = CARL9170_CMD_RF_INIT; - - msleep(100); - - err = carl9170_echo_test(ar, 0xaabbccdd); - if (err) - return err; } else { cmd = CARL9170_CMD_FREQUENCY; } -- cgit v1.2.3-59-g8ed1b From 97e2c40269e168df986daf94af1c62e07d4fc599 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Dec 2010 18:22:29 +0100 Subject: carl9170: fix usb pm suspend->resume woes This patch revamps some common code-paths which are shared between (re-)initialization and suspend/resume subroutines. It also adds some helpful comments about quirks and associated difficulties. It's quite big, but it should fix #25382: And hopefully the code is robust enough to deal with all possible suspend/resume scenarios without requiring the user to do any sort of manual and possibly dangerous work. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 53 +++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 2d947a30d29e..537732e5964f 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -834,7 +834,7 @@ static int carl9170_usb_load_firmware(struct ar9170 *ar) if (err) goto err_out; - /* firmware restarts cmd counter */ + /* now, start the command response counter */ ar->cmd_seq = -1; return 0; @@ -851,7 +851,12 @@ int carl9170_usb_restart(struct ar9170 *ar) if (ar->intf->condition != USB_INTERFACE_BOUND) return 0; - /* Disable command response sequence counter. */ + /* + * Disable the command response sequence counter check. + * We already know that the device/firmware is in a bad state. + * So, no extra points are awarded to anyone who reminds the + * driver about that. + */ ar->cmd_seq = -2; err = carl9170_reboot(ar); @@ -903,6 +908,15 @@ static int carl9170_usb_init_device(struct ar9170 *ar) { int err; + /* + * The carl9170 firmware let's the driver know when it's + * ready for action. But we have to be prepared to gracefully + * handle all spurious [flushed] messages after each (re-)boot. + * Thus the command response counter remains disabled until it + * can be safely synchronized. + */ + ar->cmd_seq = -2; + err = carl9170_usb_send_rx_irq_urb(ar); if (err) goto err_out; @@ -911,14 +925,21 @@ static int carl9170_usb_init_device(struct ar9170 *ar) if (err) goto err_unrx; + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + mutex_lock(&ar->mutex); err = carl9170_usb_load_firmware(ar); mutex_unlock(&ar->mutex); if (err) - goto err_unrx; + goto err_stop; return 0; +err_stop: + carl9170_usb_stop(ar); + err_unrx: carl9170_usb_cancel_urbs(ar); @@ -964,10 +985,6 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar) if (err) goto err_freefw; - err = carl9170_usb_open(ar); - if (err) - goto err_unrx; - err = carl9170_register(ar); carl9170_usb_stop(ar); @@ -1043,7 +1060,6 @@ static int carl9170_usb_probe(struct usb_interface *intf, atomic_set(&ar->rx_work_urbs, 0); atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); - ar->cmd_seq = -2; usb_get_dev(ar->udev); @@ -1090,10 +1106,6 @@ static int carl9170_usb_suspend(struct usb_interface *intf, carl9170_usb_cancel_urbs(ar); - /* - * firmware automatically reboots for usb suspend. - */ - return 0; } @@ -1106,12 +1118,20 @@ static int carl9170_usb_resume(struct usb_interface *intf) return -ENODEV; usb_unpoison_anchored_urbs(&ar->rx_anch); + carl9170_set_state(ar, CARL9170_STOPPED); - err = carl9170_usb_init_device(ar); - if (err) - goto err_unrx; + /* + * The USB documentation demands that [for suspend] all traffic + * to and from the device has to stop. This would be fine, but + * there's a catch: the device[usb phy] does not come back. + * + * Upon resume the firmware will "kill" itself and the + * boot-code sorts out the magic voodoo. + * Not very nice, but there's not much what could go wrong. + */ + msleep(1100); - err = carl9170_usb_open(ar); + err = carl9170_usb_init_device(ar); if (err) goto err_unrx; @@ -1133,6 +1153,7 @@ static struct usb_driver carl9170_driver = { #ifdef CONFIG_PM .suspend = carl9170_usb_suspend, .resume = carl9170_usb_resume, + .reset_resume = carl9170_usb_resume, #endif /* CONFIG_PM */ }; -- cgit v1.2.3-59-g8ed1b From c4d63244218bf93d1f0cdf4389e0906df8f506c1 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 27 Dec 2010 15:04:29 +0100 Subject: rt2x00: simplify txstatus_fifo handling Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 18 ++---------------- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index baa1468a56a8..aa97971a38af 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -688,14 +688,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) u32 status; u8 qid; - while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { - /* Now remove the tx status from the FIFO */ - if (kfifo_out(&rt2x00dev->txstatus_fifo, &status, - sizeof(status)) != sizeof(status)) { - WARN_ON(1); - break; - } - + while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); if (qid >= QID_RX) { /* @@ -803,14 +796,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) break; - if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) { - WARNING(rt2x00dev, "TX status FIFO overrun," - " drop tx status report.\n"); - break; - } - - if (kfifo_in(&rt2x00dev->txstatus_fifo, &status, - sizeof(status)) != sizeof(status)) { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { WARNING(rt2x00dev, "TX status FIFO overrun," "drop tx status report.\n"); break; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c254d5a62c7d..af1d3efc2949 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -908,7 +908,7 @@ struct rt2x00_dev { /* * FIFO for storing tx status reports between isr and tasklet. */ - struct kfifo txstatus_fifo; + DECLARE_KFIFO_PTR(txstatus_fifo, u32); /* * Tasklet for processing tx status reports (rt2800pci). -- cgit v1.2.3-59-g8ed1b From 5235189c8edddf2eb32982f814bc858b55e6350a Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 27 Dec 2010 15:04:54 +0100 Subject: rt2x00: allow txstatus_fifo w/o txstatus_tasklet When DRIVER_REQUIRE_TXSTATUS_FIFO is set, intialize the txstatus_fifo, but initialize rt2x00dev->txstatus_tasklet only when both DRIVER_REQUIRE_TXSTATUS_FIFO and rt2x00dev->ops->lib->txstatus_tasklet are set. This allows the txstatus_fifo to be used by rt2800usb which does not use txstatus_tasklet. Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index fa74acdd271f..97a8911571ce 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -813,8 +813,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) /* * Allocate tx status FIFO for driver use. */ - if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && - rt2x00dev->ops->lib->txstatus_tasklet) { + if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) { /* * Allocate txstatus fifo and tasklet, we use a size of 512 * for the kfifo which is big enough to store 512/4=128 tx @@ -828,9 +827,10 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) return status; /* tasklet for processing the tx status reports. */ - tasklet_init(&rt2x00dev->txstatus_tasklet, - rt2x00dev->ops->lib->txstatus_tasklet, - (unsigned long)rt2x00dev); + if (rt2x00dev->ops->lib->txstatus_tasklet) + tasklet_init(&rt2x00dev->txstatus_tasklet, + rt2x00dev->ops->lib->txstatus_tasklet, + (unsigned long)rt2x00dev); } -- cgit v1.2.3-59-g8ed1b From 773d1b98268a9effac047fd2ab1c47bf9f7a9e5f Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 27 Dec 2010 15:05:14 +0100 Subject: rt2x00: Remove intf->bssid field. The bssid field in struct rt2x00_intf is only written to once, and is never read from. Remove this field, as it appears to not be needed. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 5 ----- drivers/net/wireless/rt2x00/rt2x00mac.c | 11 ----------- 2 files changed, 16 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index af1d3efc2949..5f7f52ff74d2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -364,11 +364,6 @@ struct rt2x00_intf { */ u8 mac[ETH_ALEN]; - /* - * BBSID of the AP to associate with. - */ - u8 bssid[ETH_ALEN]; - /* * beacon->skb must be protected with the mutex. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4cac7ad60f47..23250a5d8331 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -614,17 +614,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return; - spin_lock(&intf->lock); - - /* - * conf->bssid can be NULL if coming from the internal - * beacon update routine. - */ - if (changes & BSS_CHANGED_BSSID) - memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN); - - spin_unlock(&intf->lock); - /* * Call rt2x00_config_intf() outside of the spinlock context since * the call will sleep for USB drivers. By using the ieee80211_if_conf -- cgit v1.2.3-59-g8ed1b From a39fd6be19bde021314262a6d2193b3792c808db Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 27 Dec 2010 15:05:35 +0100 Subject: rt2x00: remove intf->mac field. The mac field of the rt2x00_intf structure is written to once and used twice. In both these uses the mac address is available via other means. Remove this field as it does not appear to be necessary. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 5 ----- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 ++---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 5f7f52ff74d2..755b723400f5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -359,11 +359,6 @@ struct rt2x00_intf { */ spinlock_t lock; - /* - * MAC of the device. - */ - u8 mac[ETH_ALEN]; - /* * beacon->skb must be protected with the mutex. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 23250a5d8331..f8775c488be4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -282,9 +282,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, * STA interfaces at this time, since this can cause * invalid behavior in the device. */ - memcpy(&intf->mac, vif->addr, ETH_ALEN); rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, NULL); + vif->addr, NULL); /* * Some filters depend on the current working mode. We can force @@ -492,7 +491,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct rt2x00_intf *intf = vif_to_intf(vif); int (*set_key) (struct rt2x00_dev *rt2x00dev, struct rt2x00lib_crypto *crypto, struct ieee80211_key_conf *key); @@ -516,7 +514,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (rt2x00dev->intf_sta_count) crypto.bssidx = 0; else - crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1); + crypto.bssidx = vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1); crypto.cipher = rt2x00crypto_key_to_cipher(key); if (crypto.cipher == CIPHER_NONE) -- cgit v1.2.3-59-g8ed1b From 736e3acadce8438e610b897af2b1c472ed58444b Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 27 Dec 2010 15:05:55 +0100 Subject: rt2x00: Fix pointer errors. Fix some pointer errors in the various calls to memcpy, memset and memmove. Although none of these errors are fatal (the expression used now results in the same pointer value) it is better to use the proper expression. All errors are having to deal with arrays. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00config.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2x00mac.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 70ca9379833b..e7f67d5eda52 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -62,13 +62,13 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, * This will prevent the device being confused when it wants * to ACK frames or consideres itself associated. */ - memset(&conf.mac, 0, sizeof(conf.mac)); + memset(conf.mac, 0, sizeof(conf.mac)); if (mac) - memcpy(&conf.mac, mac, ETH_ALEN); + memcpy(conf.mac, mac, ETH_ALEN); - memset(&conf.bssid, 0, sizeof(conf.bssid)); + memset(conf.bssid, 0, sizeof(conf.bssid)); if (bssid) - memcpy(&conf.bssid, bssid, ETH_ALEN); + memcpy(conf.bssid, bssid, ETH_ALEN); flags |= CONFIG_UPDATE_TYPE; if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index f8775c488be4..a2266c7d86c2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -471,17 +471,17 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_tim); static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) { if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) - memcpy(&crypto->key, + memcpy(crypto->key, &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], sizeof(crypto->key)); if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) - memcpy(&crypto->tx_mic, + memcpy(crypto->tx_mic, &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], sizeof(crypto->tx_mic)); if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) - memcpy(&crypto->rx_mic, + memcpy(crypto->rx_mic, &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], sizeof(crypto->rx_mic)); } @@ -532,7 +532,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (crypto.cipher == CIPHER_TKIP) memcpy_tkip(&crypto, &key->key[0], key->keylen); else - memcpy(&crypto.key, &key->key[0], key->keylen); + memcpy(crypto.key, &key->key[0], key->keylen); /* * Each BSS has a maximum of 4 shared keys. * Shared key index values: -- cgit v1.2.3-59-g8ed1b From 11f16aefcc07178972f149f1a1d53e6868481394 Mon Sep 17 00:00:00 2001 From: Ismael Luceno Date: Mon, 27 Dec 2010 15:06:17 +0100 Subject: rt2x00: Fix panic on frame padding for rt2800 usb devices Backtrace: rt2800usb_write_tx_data rt2x00queue_write_tx_frame rt2x00mac_tx invoke_tx_handlers __ieee80211_tx ieee80211_tx virt_to_head_page ieee80211_xmit ieee80211_tx_skb ieee80211_scan_work schedule ieee80211_scan_work process_one_work ... It tried to expand the skb past it's end using skb_put. So I replaced it with a call to skb_padto, which takes the issue into account. Signed-off-by: Ismael Luceno Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3e0205ddf7b4..b97a4a54ff4c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -369,7 +369,10 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, static void rt2800usb_write_tx_data(struct queue_entry *entry, struct txentry_desc *txdesc) { - u8 padding_len; + unsigned int len; + int err; + + rt2800_write_tx_data(entry, txdesc); /* * pad(1~3 bytes) is added after each 802.11 payload. @@ -378,9 +381,14 @@ static void rt2800usb_write_tx_data(struct queue_entry *entry, * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | * |<------------- tx_pkt_len ------------->| */ - rt2800_write_tx_data(entry, txdesc); - padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len; - memset(skb_put(entry->skb, padding_len), 0, padding_len); + len = roundup(entry->skb->len, 4) + 4; + err = skb_padto(entry->skb, len); + if (unlikely(err)) { + WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n"); + return; + } + + entry->skb->len = len; } /* -- cgit v1.2.3-59-g8ed1b From f833eea0a77b0910ea202468175bfc80470d44d0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 27 Dec 2010 15:06:36 +0100 Subject: rt2x00: Remove superfluous assignment of mpdu_density The tx desciptor already gets initialized to 0. Hence, there's no need to explicitly assign 0 to mpdu_density here. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index c637bcaec5f8..b7ad46ecaa1d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -40,8 +40,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, if (tx_info->control.sta) txdesc->mpdu_density = tx_info->control.sta->ht_cap.ampdu_density; - else - txdesc->mpdu_density = 0; txdesc->ba_size = 7; /* FIXME: What value is needed? */ -- cgit v1.2.3-59-g8ed1b From bfe6a15d60671993eb3d4ac396b1f442ae08581c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 27 Dec 2010 15:06:57 +0100 Subject: rt2x00: Simplify intf->delayed_flags locking Instead of protecting delayed_flags with a spinlock use atomic bitops to make the code more readable. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 7 +++++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 15 +-------------- drivers/net/wireless/rt2x00/rt2x00mac.c | 4 +--- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 755b723400f5..b3f77d4f37ff 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -347,6 +347,10 @@ struct link { struct delayed_work watchdog_work; }; +enum rt2x00_delayed_flags { + DELAYED_UPDATE_BEACON, +}; + /* * Interface structure * Per interface configuration details, this structure @@ -374,8 +378,7 @@ struct rt2x00_intf { /* * Actions that needed rescheduling. */ - unsigned int delayed_flags; -#define DELAYED_UPDATE_BEACON 0x00000001 + unsigned long delayed_flags; /* * Software sequence counter, this is only required diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 97a8911571ce..9597a03242cc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -110,19 +110,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, { struct rt2x00_dev *rt2x00dev = data; struct rt2x00_intf *intf = vif_to_intf(vif); - int delayed_flags; - - /* - * Copy all data we need during this action under the protection - * of a spinlock. Otherwise race conditions might occur which results - * into an invalid configuration. - */ - spin_lock(&intf->lock); - - delayed_flags = intf->delayed_flags; - intf->delayed_flags = 0; - - spin_unlock(&intf->lock); /* * It is possible the radio was disabled while the work had been @@ -133,7 +120,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return; - if (delayed_flags & DELAYED_UPDATE_BEACON) + if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) rt2x00queue_update_beacon(rt2x00dev, vif, true); } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index a2266c7d86c2..297d972c229b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -444,9 +444,7 @@ static void rt2x00mac_set_tim_iter(void *data, u8 *mac, vif->type != NL80211_IFTYPE_WDS) return; - spin_lock(&intf->lock); - intf->delayed_flags |= DELAYED_UPDATE_BEACON; - spin_unlock(&intf->lock); + set_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags); } int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, -- cgit v1.2.3-59-g8ed1b From 48103d25c4ca00a1d0692895f9aa68fcac6bc6af Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 27 Dec 2010 15:07:16 +0100 Subject: rt2x00: Remove unused interface spinlock Since the last user of intf->lock is gone we can safely remove it. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 6 ------ drivers/net/wireless/rt2x00/rt2x00mac.c | 1 - 2 files changed, 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b3f77d4f37ff..84aaf393da43 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -357,12 +357,6 @@ enum rt2x00_delayed_flags { * is allocated as the private data for ieee80211_vif. */ struct rt2x00_intf { - /* - * All fields within the rt2x00_intf structure - * must be protected with a spinlock. - */ - spinlock_t lock; - /* * beacon->skb must be protected with the mutex. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 297d972c229b..b5dad0427a97 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -268,7 +268,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, else rt2x00dev->intf_sta_count++; - spin_lock_init(&intf->lock); spin_lock_init(&intf->seqlock); mutex_init(&intf->beacon_skb_mutex); intf->beacon = entry; -- cgit v1.2.3-59-g8ed1b From 5af3c1d195a6169a925a929e800dc4fce2a545ae Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 27 Dec 2010 15:07:35 +0100 Subject: rt2x00: Fix comment about removed spinlock The comment doesn't match the code anymore. Fix that. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00mac.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index b5dad0427a97..658542d2efe1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -610,10 +610,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, return; /* - * Call rt2x00_config_intf() outside of the spinlock context since - * the call will sleep for USB drivers. By using the ieee80211_if_conf - * values as arguments we make keep access to rt2x00_intf thread safe - * even without the lock. + * Update the BSSID. */ if (changes & BSS_CHANGED_BSSID) rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, -- cgit v1.2.3-59-g8ed1b From 4cfda47b69d0a37e5fc0292addba6d0f5f671a14 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 27 Dec 2010 23:21:26 +0100 Subject: mac80211: ignore PSM bit of reordered frames This patch tackles one of the problems of my reorder release timer patch from August. => What if the reorder release triggers and ap_sta_ps_end (called by ieee80211_rx_h_sta_process) accidentally clears the WLAN_STA_PS_STA flag, because 100ms ago - when the STA was still active - frames were put into the reorder buffer. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/rx.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eadaa243a3da..a9eb67380da6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -167,6 +167,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result; * @IEEE80211_RX_FRAGMENTED: fragmented frame * @IEEE80211_RX_AMSDU: a-MSDU packet * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed + * @IEEE80211_RX_DEFERRED_RELEASE: frame was subjected to receive reordering * * These are per-frame flags that are attached to a frame in the * @rx_flags field of &struct ieee80211_rx_status. @@ -177,6 +178,7 @@ enum ieee80211_packet_rx_flags { IEEE80211_RX_FRAGMENTED = BIT(2), IEEE80211_RX_AMSDU = BIT(3), IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), + IEEE80211_RX_DEFERRED_RELEASE = BIT(5), }; /** diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7c5d1b2ec453..260b48bac42e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -537,6 +537,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, struct sk_buff_head *frames) { struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; + struct ieee80211_rx_status *status; lockdep_assert_held(&tid_agg_rx->reorder_lock); @@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, /* release the frame from the reorder ring buffer */ tid_agg_rx->stored_mpdu_num--; tid_agg_rx->reorder_buf[index] = NULL; + status = IEEE80211_SKB_RXCB(skb); + status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; __skb_queue_tail(frames, skb); no_frame: @@ -1189,6 +1192,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) * exchange sequence. */ if (!ieee80211_has_morefrags(hdr->frame_control) && + !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && (rx->sdata->vif.type == NL80211_IFTYPE_AP || rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { if (test_sta_flags(sta, WLAN_STA_PS_STA)) { -- cgit v1.2.3-59-g8ed1b From ee832d3e9e72abf83931205a2f5379944be501c2 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 28 Dec 2010 13:06:26 +0530 Subject: ath9k: Few clean ups in beacon config parameters Some minor clean ups in assigning values to beacon config parameters Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 5e108c086904..385ba03134ba 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -566,8 +566,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc, * last beacon we received (which may be none). */ dtimperiod = conf->dtim_period; - if (dtimperiod <= 0) /* NB: 0 if not known */ - dtimperiod = 1; dtimcount = conf->dtim_count; if (dtimcount >= dtimperiod) /* NB: sanity check */ dtimcount = 0; @@ -575,8 +573,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc, cfpcount = 0; sleepduration = conf->listen_interval * intval; - if (sleepduration <= 0) - sleepduration = intval; /* * Pull nexttbtt forward to reflect the current @@ -662,8 +658,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, } static void ath_beacon_config_adhoc(struct ath_softc *sc, - struct ath_beacon_config *conf, - struct ieee80211_vif *vif) + struct ath_beacon_config *conf) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -718,18 +713,17 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) /* Setup the beacon configuration parameters */ if (vif) { struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - iftype = vif->type; - cur_conf->beacon_interval = bss_conf->beacon_int; cur_conf->dtim_period = bss_conf->dtim_period; + } else { + iftype = sc->sc_ah->opmode; + } + cur_conf->listen_interval = 1; cur_conf->dtim_count = 1; cur_conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; - } else { - iftype = sc->sc_ah->opmode; - } /* * It looks like mac80211 may end up using beacon interval of zero in @@ -740,13 +734,20 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) if (cur_conf->beacon_interval == 0) cur_conf->beacon_interval = 100; + /* + * Some times we dont parse dtim period from mac80211, in that case + * use a default value + */ + if (cur_conf->dtim_period == 0) + cur_conf->dtim_period = 1; + switch (iftype) { case NL80211_IFTYPE_AP: ath_beacon_config_ap(sc, cur_conf); break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: - ath_beacon_config_adhoc(sc, cur_conf, vif); + ath_beacon_config_adhoc(sc, cur_conf); break; case NL80211_IFTYPE_STATION: ath_beacon_config_sta(sc, cur_conf); -- cgit v1.2.3-59-g8ed1b From ff8f59b5bbdf1527235b8c88d859c7d23691324f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 28 Dec 2010 14:28:05 +0530 Subject: ath9k_htc: Handle pending URBs properly When doing a channel change, the pending URBs have to be killed properly on calling htc_stop(). This fixes the probe response timeout seen when sending UDP traffic at a high rate and running background scan at the same time. Cc: stable Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 40 ++++++++++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/hif_usb.h | 1 + 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index c20c8c8201a2..5ab3084eb9cb 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -153,16 +153,36 @@ static void hif_usb_tx_cb(struct urb *urb) case -ENODEV: case -ESHUTDOWN: /* - * The URB has been killed, free the SKBs - * and return. + * The URB has been killed, free the SKBs. */ ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); - return; + + /* + * If the URBs are being flushed, no need to add this + * URB to the free list. + */ + spin_lock(&hif_dev->tx.tx_lock); + if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { + spin_unlock(&hif_dev->tx.tx_lock); + return; + } + spin_unlock(&hif_dev->tx.tx_lock); + + /* + * In the stop() case, this URB has to be added to + * the free list. + */ + goto add_free; default: break; } - /* Check if TX has been stopped */ + /* + * Check if TX has been stopped, this is needed because + * this CB could have been invoked just after the TX lock + * was released in hif_stop() and kill_urb() hasn't been + * called yet. + */ spin_lock(&hif_dev->tx.tx_lock); if (hif_dev->tx.flags & HIF_USB_TX_STOP) { spin_unlock(&hif_dev->tx.tx_lock); @@ -314,6 +334,7 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) static void hif_usb_stop(void *hif_handle, u8 pipe_id) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; + struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; unsigned long flags; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); @@ -321,6 +342,12 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) hif_dev->tx.tx_skb_cnt = 0; hif_dev->tx.flags |= HIF_USB_TX_STOP; spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); + + /* The pending URBs have to be canceled. */ + list_for_each_entry_safe(tx_buf, tx_buf_tmp, + &hif_dev->tx.tx_pending, list) { + usb_kill_urb(tx_buf->urb); + } } static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, @@ -587,6 +614,7 @@ free: static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) { struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; + unsigned long flags; list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) { @@ -597,6 +625,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) kfree(tx_buf); } + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + hif_dev->tx.flags |= HIF_USB_TX_FLUSH; + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); + list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_pending, list) { usb_kill_urb(tx_buf->urb); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index e4a5e2e79541..7b9d863d4035 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -64,6 +64,7 @@ struct tx_buf { }; #define HIF_USB_TX_STOP BIT(0) +#define HIF_USB_TX_FLUSH BIT(1) struct hif_usb_tx { u8 flags; -- cgit v1.2.3-59-g8ed1b From 66e3547431a8738416b508badfb9f326d11dabcc Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 28 Dec 2010 14:28:14 +0530 Subject: ath9k_htc: Move work cancellation outside of mutex There is no need to lock the various work cancellation calls. This will be helpful when handling FATAL events. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index dd17909bd903..5f75f70db5a7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1218,6 +1218,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) int ret = 0; u8 cmd_rsp; + /* Cancel all the running timers/work .. */ + cancel_work_sync(&priv->ps_work); + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + ath9k_led_stop_brightness(priv); + mutex_lock(&priv->mutex); if (priv->op_flags & OP_INVALID) { @@ -1226,11 +1231,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) return; } - /* Cancel all the running timers/work .. */ - cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_led_blink_work); - ath9k_led_stop_brightness(priv); - ath9k_htc_ps_wakeup(priv); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); -- cgit v1.2.3-59-g8ed1b From 73908674c6957082e8ab57daed57d2bb97a1ebba Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 28 Dec 2010 14:28:27 +0530 Subject: ath9k_htc: Handle FATAL events The device has to be reset when a FATAL event is received. Not doing so would leave the card in a non-working state. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 6 ++- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 8 ++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 57 ++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/wmi.c | 18 ++++++++- drivers/net/wireless/ath/ath9k/wmi.h | 3 +- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e6c2f0aad28f..10622740dc76 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -377,7 +377,7 @@ struct ath9k_htc_priv { struct ieee80211_vif *vif; struct htc_beacon_config cur_beacon_conf; unsigned int rxfilter; - struct tasklet_struct wmi_tasklet; + struct tasklet_struct swba_tasklet; struct tasklet_struct rx_tasklet; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ath9k_htc_rx rx; @@ -385,6 +385,7 @@ struct ath9k_htc_priv { struct sk_buff_head tx_queue; struct delayed_work ath9k_ani_work; struct work_struct ps_work; + struct work_struct fatal_work; struct mutex htc_pm_lock; unsigned long ps_usecount; @@ -419,6 +420,8 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) common->bus_ops->read_cachesize(common, csz); } +void ath9k_htc_reset(struct ath9k_htc_priv *priv); + void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); @@ -434,6 +437,7 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, void ath9k_htc_station_work(struct work_struct *work); void ath9k_htc_aggr_work(struct work_struct *work); void ath9k_ani_work(struct work_struct *work);; +void ath_start_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 724f5451a415..9150ca665367 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -142,7 +142,7 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) { ath9k_htc_exit_debug(priv->ah); ath9k_hw_deinit(priv->ah); - tasklet_kill(&priv->wmi_tasklet); + tasklet_kill(&priv->swba_tasklet); tasklet_kill(&priv->rx_tasklet); tasklet_kill(&priv->tx_tasklet); kfree(priv->ah); @@ -647,13 +647,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, spin_lock_init(&priv->tx_lock); mutex_init(&priv->mutex); mutex_init(&priv->htc_pm_lock); - tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet, + tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet, (unsigned long)priv); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, (unsigned long)priv); - tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); + tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, + (unsigned long)priv); INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); + INIT_WORK(&priv->fatal_work, ath9k_fatal_work); /* * Cache line size is used to size and align various diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5f75f70db5a7..07f10ddee6a5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -116,6 +116,60 @@ void ath9k_ps_work(struct work_struct *work) ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); } +void ath9k_htc_reset(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_channel *channel = priv->hw->conf.channel; + struct ath9k_hw_cal_data *caldata; + enum htc_phymode mode; + __be16 htc_mode; + u8 cmd_rsp; + int ret; + + mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); + + if (priv->op_flags & OP_ASSOCIATED) + cancel_delayed_work_sync(&priv->ath9k_ani_work); + + ieee80211_stop_queues(priv->hw); + htc_stop(priv->htc); + WMI_CMD(WMI_DISABLE_INTR_CMDID); + WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); + WMI_CMD(WMI_STOP_RECV_CMDID); + + caldata = &priv->caldata[channel->hw_value]; + ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); + if (ret) { + ath_err(common, + "Unable to reset device (%u Mhz) reset status %d\n", + channel->center_freq, ret); + } + + ath_update_txpow(priv); + + WMI_CMD(WMI_START_RECV_CMDID); + ath9k_host_rx_init(priv); + + mode = ath9k_htc_get_curmode(priv, ah->curchan); + htc_mode = cpu_to_be16(mode); + WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); + + WMI_CMD(WMI_ENABLE_INTR_CMDID); + htc_start(priv->htc); + + if (priv->op_flags & OP_ASSOCIATED) { + ath9k_htc_beacon_config(priv, priv->vif); + ath_start_ani(priv); + } + + ieee80211_wake_queues(priv->hw); + + ath9k_htc_ps_restore(priv); + mutex_unlock(&priv->mutex); +} + static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, struct ieee80211_hw *hw, struct ath9k_channel *hchan) @@ -690,7 +744,7 @@ void ath9k_htc_debug_remove_root(void) /* ANI */ /*******/ -static void ath_start_ani(struct ath9k_htc_priv *priv) +void ath_start_ani(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); unsigned long timestamp = jiffies_to_msecs(jiffies); @@ -1219,6 +1273,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) u8 cmd_rsp; /* Cancel all the running timers/work .. */ + cancel_work_sync(&priv->fatal_work); cancel_work_sync(&priv->ps_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); ath9k_led_stop_brightness(priv); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 573daca135fd..dc862f5e1162 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -120,7 +120,7 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) kfree(priv->wmi); } -void ath9k_wmi_tasklet(unsigned long data) +void ath9k_swba_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath_common *common = ath9k_hw_common(priv->ah); @@ -131,6 +131,16 @@ void ath9k_wmi_tasklet(unsigned long data) } +void ath9k_fatal_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + fatal_work); + struct ath_common *common = ath9k_hw_common(priv->ah); + + ath_dbg(common, ATH_DBG_FATAL, "FATAL Event received, resetting device\n"); + ath9k_htc_reset(priv); +} + static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb) { skb_pull(skb, sizeof(struct wmi_cmd_hdr)); @@ -163,7 +173,11 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, switch (cmd_id) { case WMI_SWBA_EVENTID: wmi->beacon_pending = *(u8 *)wmi_event; - tasklet_schedule(&wmi->drv_priv->wmi_tasklet); + tasklet_schedule(&wmi->drv_priv->swba_tasklet); + break; + case WMI_FATAL_EVENTID: + ieee80211_queue_work(wmi->drv_priv->hw, + &wmi->drv_priv->fatal_work); break; case WMI_TXRATE_EVENTID: #ifdef CONFIG_ATH9K_HTC_DEBUGFS diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index ac61074af8ac..42084277522d 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -117,7 +117,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, u8 *cmd_buf, u32 cmd_len, u8 *rsp_buf, u32 rsp_len, u32 timeout); -void ath9k_wmi_tasklet(unsigned long data); +void ath9k_swba_tasklet(unsigned long data); +void ath9k_fatal_work(struct work_struct *work); #define WMI_CMD(_wmi_cmd) \ do { \ -- cgit v1.2.3-59-g8ed1b From 039a07215e0fca00c450f4bf1dc9b458bdfe8559 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 28 Dec 2010 14:28:37 +0530 Subject: ath9k_htc: Fix fast channel change When returning to the operating channel, a full HW reset has to be done instead of a fast channel change. Since sw_scan_complete() is called after the config() call for the home channel, we end up doing a FCC. Fix this issue by checking the OFFCHANNEL flag to determine FCC. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 19 +++++++++---------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 8 ++------ 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 10622740dc76..34456a85ab77 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -331,16 +331,15 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_INVALID BIT(0) #define OP_SCANNING BIT(1) -#define OP_FULL_RESET BIT(2) -#define OP_LED_ASSOCIATED BIT(3) -#define OP_LED_ON BIT(4) -#define OP_PREAMBLE_SHORT BIT(5) -#define OP_PROTECT_ENABLE BIT(6) -#define OP_ASSOCIATED BIT(7) -#define OP_ENABLE_BEACON BIT(8) -#define OP_LED_DEINIT BIT(9) -#define OP_BT_PRIORITY_DETECTED BIT(10) -#define OP_BT_SCAN BIT(11) +#define OP_LED_ASSOCIATED BIT(2) +#define OP_LED_ON BIT(3) +#define OP_PREAMBLE_SHORT BIT(4) +#define OP_PROTECT_ENABLE BIT(5) +#define OP_ASSOCIATED BIT(6) +#define OP_ENABLE_BEACON BIT(7) +#define OP_LED_DEINIT BIT(8) +#define OP_BT_PRIORITY_DETECTED BIT(9) +#define OP_BT_SCAN BIT(10) struct ath9k_htc_priv { struct device *dev; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 07f10ddee6a5..6da5e8867309 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -177,7 +177,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &common->hw->conf; - bool fastcc = true; + bool fastcc; struct ieee80211_channel *channel = hw->conf.channel; struct ath9k_hw_cal_data *caldata; enum htc_phymode mode; @@ -188,8 +188,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, if (priv->op_flags & OP_INVALID) return -EIO; - if (priv->op_flags & OP_FULL_RESET) - fastcc = false; + fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); ath9k_htc_ps_wakeup(priv); htc_stop(priv->htc); @@ -231,8 +230,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, goto err; htc_start(priv->htc); - - priv->op_flags &= ~OP_FULL_RESET; err: ath9k_htc_ps_restore(priv); return ret; @@ -1847,7 +1844,6 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) spin_lock_bh(&priv->beacon_lock); priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); - priv->op_flags |= OP_FULL_RESET; if (priv->op_flags & OP_ASSOCIATED) { ath9k_htc_beacon_config(priv, priv->vif); ath_start_ani(priv); -- cgit v1.2.3-59-g8ed1b From 1e1f4ad25fab29ca48b1166e74a81e9c89ddf0fb Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 28 Dec 2010 14:28:52 +0530 Subject: ath9k_htc: Move LED/RFKILL code to htc_drv_gpio.c And add the copyright/license header. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 5 + drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 327 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 313 +----------------------- 3 files changed, 333 insertions(+), 312 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 34456a85ab77..a099b3e87ed3 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -459,8 +459,13 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); void ath9k_ps_work(struct work_struct *work); bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, enum ath9k_power_mode mode); +void ath_update_txpow(struct ath9k_htc_priv *priv); void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); +void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); +void ath9k_htc_radio_enable(struct ieee80211_hw *hw); +void ath9k_htc_radio_disable(struct ieee80211_hw *hw); +void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv); void ath9k_init_leds(struct ath9k_htc_priv *priv); void ath9k_deinit_leds(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 283ff97ed446..fe70f67aa088 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include "htc.h" /******************/ @@ -131,3 +147,314 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) cancel_delayed_work_sync(&priv->coex_period_work); cancel_delayed_work_sync(&priv->duty_cycle_work); } + +/*******/ +/* LED */ +/*******/ + +static void ath9k_led_blink_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + ath9k_led_blink_work.work); + + if (!(priv->op_flags & OP_LED_ASSOCIATED)) + return; + + if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || + (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); + else + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, + (priv->op_flags & OP_LED_ON) ? 1 : 0); + + ieee80211_queue_delayed_work(priv->hw, + &priv->ath9k_led_blink_work, + (priv->op_flags & OP_LED_ON) ? + msecs_to_jiffies(priv->led_off_duration) : + msecs_to_jiffies(priv->led_on_duration)); + + priv->led_on_duration = priv->led_on_cnt ? + max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : + ATH_LED_ON_DURATION_IDLE; + priv->led_off_duration = priv->led_off_cnt ? + max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : + ATH_LED_OFF_DURATION_IDLE; + priv->led_on_cnt = priv->led_off_cnt = 0; + + if (priv->op_flags & OP_LED_ON) + priv->op_flags &= ~OP_LED_ON; + else + priv->op_flags |= OP_LED_ON; +} + +static void ath9k_led_brightness_work(struct work_struct *work) +{ + struct ath_led *led = container_of(work, struct ath_led, + brightness_work.work); + struct ath9k_htc_priv *priv = led->priv; + + switch (led->brightness) { + case LED_OFF: + if (led->led_type == ATH_LED_ASSOC || + led->led_type == ATH_LED_RADIO) { + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, + (led->led_type == ATH_LED_RADIO)); + priv->op_flags &= ~OP_LED_ASSOCIATED; + if (led->led_type == ATH_LED_RADIO) + priv->op_flags &= ~OP_LED_ON; + } else { + priv->led_off_cnt++; + } + break; + case LED_FULL: + if (led->led_type == ATH_LED_ASSOC) { + priv->op_flags |= OP_LED_ASSOCIATED; + ieee80211_queue_delayed_work(priv->hw, + &priv->ath9k_led_blink_work, 0); + } else if (led->led_type == ATH_LED_RADIO) { + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); + priv->op_flags |= OP_LED_ON; + } else { + priv->led_on_cnt++; + } + break; + default: + break; + } +} + +static void ath9k_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); + struct ath9k_htc_priv *priv = led->priv; + + led->brightness = brightness; + if (!(priv->op_flags & OP_LED_DEINIT)) + ieee80211_queue_delayed_work(priv->hw, + &led->brightness_work, 0); +} + +void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) +{ + cancel_delayed_work_sync(&priv->radio_led.brightness_work); + cancel_delayed_work_sync(&priv->assoc_led.brightness_work); + cancel_delayed_work_sync(&priv->tx_led.brightness_work); + cancel_delayed_work_sync(&priv->rx_led.brightness_work); +} + +static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, + char *trigger) +{ + int ret; + + led->priv = priv; + led->led_cdev.name = led->name; + led->led_cdev.default_trigger = trigger; + led->led_cdev.brightness_set = ath9k_led_brightness; + + ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); + if (ret) + ath_err(ath9k_hw_common(priv->ah), + "Failed to register led:%s", led->name); + else + led->registered = 1; + + INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); + + return ret; +} + +static void ath9k_unregister_led(struct ath_led *led) +{ + if (led->registered) { + led_classdev_unregister(&led->led_cdev); + led->registered = 0; + } +} + +void ath9k_deinit_leds(struct ath9k_htc_priv *priv) +{ + priv->op_flags |= OP_LED_DEINIT; + ath9k_unregister_led(&priv->assoc_led); + priv->op_flags &= ~OP_LED_ASSOCIATED; + ath9k_unregister_led(&priv->tx_led); + ath9k_unregister_led(&priv->rx_led); + ath9k_unregister_led(&priv->radio_led); +} + +void ath9k_init_leds(struct ath9k_htc_priv *priv) +{ + char *trigger; + int ret; + + if (AR_SREV_9287(priv->ah)) + priv->ah->led_pin = ATH_LED_PIN_9287; + else if (AR_SREV_9271(priv->ah)) + priv->ah->led_pin = ATH_LED_PIN_9271; + else if (AR_DEVID_7010(priv->ah)) + priv->ah->led_pin = ATH_LED_PIN_7010; + else + priv->ah->led_pin = ATH_LED_PIN_DEF; + + /* Configure gpio 1 for output */ + ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + /* LED off, active low */ + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); + + INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); + + trigger = ieee80211_get_radio_led_name(priv->hw); + snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), + "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->radio_led, trigger); + priv->radio_led.led_type = ATH_LED_RADIO; + if (ret) + goto fail; + + trigger = ieee80211_get_assoc_led_name(priv->hw); + snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), + "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->assoc_led, trigger); + priv->assoc_led.led_type = ATH_LED_ASSOC; + if (ret) + goto fail; + + trigger = ieee80211_get_tx_led_name(priv->hw); + snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), + "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->tx_led, trigger); + priv->tx_led.led_type = ATH_LED_TX; + if (ret) + goto fail; + + trigger = ieee80211_get_rx_led_name(priv->hw); + snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), + "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->rx_led, trigger); + priv->rx_led.led_type = ATH_LED_RX; + if (ret) + goto fail; + + priv->op_flags &= ~OP_LED_DEINIT; + + return; + +fail: + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + ath9k_deinit_leds(priv); +} + +/*******************/ +/* Rfkill */ +/*******************/ + +static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv) +{ + return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) == + priv->ah->rfkill_polarity; +} + +void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + bool blocked = !!ath_is_rfkill_set(priv); + + wiphy_rfkill_set_hw_state(hw->wiphy, blocked); +} + +void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) +{ + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + wiphy_rfkill_start_polling(priv->hw->wiphy); +} + +void ath9k_htc_radio_enable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); + if (ret) { + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); + } + + ath_update_txpow(priv); + + /* Start RX */ + WMI_CMD(WMI_START_RECV_CMDID); + ath9k_host_rx_init(priv); + + /* Start TX */ + htc_start(priv->htc); + spin_lock_bh(&priv->tx_lock); + priv->tx_queues_stop = false; + spin_unlock_bh(&priv->tx_lock); + ieee80211_wake_queues(hw); + + WMI_CMD(WMI_ENABLE_INTR_CMDID); + + /* Enable LED */ + ath9k_hw_cfg_output(ah, ah->led_pin, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath9k_hw_set_gpio(ah, ah->led_pin, 0); +} + +void ath9k_htc_radio_disable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + ath9k_htc_ps_wakeup(priv); + + /* Disable LED */ + ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_cfg_gpio_input(ah, ah->led_pin); + + WMI_CMD(WMI_DISABLE_INTR_CMDID); + + /* Stop TX */ + ieee80211_stop_queues(hw); + htc_stop(priv->htc); + WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); + skb_queue_purge(&priv->tx_queue); + + /* Stop RX */ + WMI_CMD(WMI_STOP_RECV_CMDID); + + /* + * The MIB counters have to be disabled here, + * since the target doesn't do it. + */ + ath9k_hw_disable_mib_counters(ah); + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); + if (ret) { + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); + } + + /* Disable the PHY */ + ath9k_hw_phy_disable(ah); + + ath9k_htc_ps_restore(priv); + ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 6da5e8867309..ad3dd3186ad2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -24,7 +24,7 @@ static struct dentry *ath9k_debugfs_root; /* Utilities */ /*************/ -static void ath_update_txpow(struct ath9k_htc_priv *priv) +void ath_update_txpow(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; @@ -840,317 +840,6 @@ set_timer: msecs_to_jiffies(cal_interval)); } -/*******/ -/* LED */ -/*******/ - -static void ath9k_led_blink_work(struct work_struct *work) -{ - struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, - ath9k_led_blink_work.work); - - if (!(priv->op_flags & OP_LED_ASSOCIATED)) - return; - - if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || - (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); - else - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, - (priv->op_flags & OP_LED_ON) ? 1 : 0); - - ieee80211_queue_delayed_work(priv->hw, - &priv->ath9k_led_blink_work, - (priv->op_flags & OP_LED_ON) ? - msecs_to_jiffies(priv->led_off_duration) : - msecs_to_jiffies(priv->led_on_duration)); - - priv->led_on_duration = priv->led_on_cnt ? - max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : - ATH_LED_ON_DURATION_IDLE; - priv->led_off_duration = priv->led_off_cnt ? - max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : - ATH_LED_OFF_DURATION_IDLE; - priv->led_on_cnt = priv->led_off_cnt = 0; - - if (priv->op_flags & OP_LED_ON) - priv->op_flags &= ~OP_LED_ON; - else - priv->op_flags |= OP_LED_ON; -} - -static void ath9k_led_brightness_work(struct work_struct *work) -{ - struct ath_led *led = container_of(work, struct ath_led, - brightness_work.work); - struct ath9k_htc_priv *priv = led->priv; - - switch (led->brightness) { - case LED_OFF: - if (led->led_type == ATH_LED_ASSOC || - led->led_type == ATH_LED_RADIO) { - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, - (led->led_type == ATH_LED_RADIO)); - priv->op_flags &= ~OP_LED_ASSOCIATED; - if (led->led_type == ATH_LED_RADIO) - priv->op_flags &= ~OP_LED_ON; - } else { - priv->led_off_cnt++; - } - break; - case LED_FULL: - if (led->led_type == ATH_LED_ASSOC) { - priv->op_flags |= OP_LED_ASSOCIATED; - ieee80211_queue_delayed_work(priv->hw, - &priv->ath9k_led_blink_work, 0); - } else if (led->led_type == ATH_LED_RADIO) { - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); - priv->op_flags |= OP_LED_ON; - } else { - priv->led_on_cnt++; - } - break; - default: - break; - } -} - -static void ath9k_led_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); - struct ath9k_htc_priv *priv = led->priv; - - led->brightness = brightness; - if (!(priv->op_flags & OP_LED_DEINIT)) - ieee80211_queue_delayed_work(priv->hw, - &led->brightness_work, 0); -} - -static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) -{ - cancel_delayed_work_sync(&priv->radio_led.brightness_work); - cancel_delayed_work_sync(&priv->assoc_led.brightness_work); - cancel_delayed_work_sync(&priv->tx_led.brightness_work); - cancel_delayed_work_sync(&priv->rx_led.brightness_work); -} - -static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, - char *trigger) -{ - int ret; - - led->priv = priv; - led->led_cdev.name = led->name; - led->led_cdev.default_trigger = trigger; - led->led_cdev.brightness_set = ath9k_led_brightness; - - ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); - if (ret) - ath_err(ath9k_hw_common(priv->ah), - "Failed to register led:%s", led->name); - else - led->registered = 1; - - INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); - - return ret; -} - -static void ath9k_unregister_led(struct ath_led *led) -{ - if (led->registered) { - led_classdev_unregister(&led->led_cdev); - led->registered = 0; - } -} - -void ath9k_deinit_leds(struct ath9k_htc_priv *priv) -{ - priv->op_flags |= OP_LED_DEINIT; - ath9k_unregister_led(&priv->assoc_led); - priv->op_flags &= ~OP_LED_ASSOCIATED; - ath9k_unregister_led(&priv->tx_led); - ath9k_unregister_led(&priv->rx_led); - ath9k_unregister_led(&priv->radio_led); -} - -void ath9k_init_leds(struct ath9k_htc_priv *priv) -{ - char *trigger; - int ret; - - if (AR_SREV_9287(priv->ah)) - priv->ah->led_pin = ATH_LED_PIN_9287; - else if (AR_SREV_9271(priv->ah)) - priv->ah->led_pin = ATH_LED_PIN_9271; - else if (AR_DEVID_7010(priv->ah)) - priv->ah->led_pin = ATH_LED_PIN_7010; - else - priv->ah->led_pin = ATH_LED_PIN_DEF; - - /* Configure gpio 1 for output */ - ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - /* LED off, active low */ - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); - - INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); - - trigger = ieee80211_get_radio_led_name(priv->hw); - snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), - "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); - ret = ath9k_register_led(priv, &priv->radio_led, trigger); - priv->radio_led.led_type = ATH_LED_RADIO; - if (ret) - goto fail; - - trigger = ieee80211_get_assoc_led_name(priv->hw); - snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), - "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); - ret = ath9k_register_led(priv, &priv->assoc_led, trigger); - priv->assoc_led.led_type = ATH_LED_ASSOC; - if (ret) - goto fail; - - trigger = ieee80211_get_tx_led_name(priv->hw); - snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), - "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); - ret = ath9k_register_led(priv, &priv->tx_led, trigger); - priv->tx_led.led_type = ATH_LED_TX; - if (ret) - goto fail; - - trigger = ieee80211_get_rx_led_name(priv->hw); - snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), - "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); - ret = ath9k_register_led(priv, &priv->rx_led, trigger); - priv->rx_led.led_type = ATH_LED_RX; - if (ret) - goto fail; - - priv->op_flags &= ~OP_LED_DEINIT; - - return; - -fail: - cancel_delayed_work_sync(&priv->ath9k_led_blink_work); - ath9k_deinit_leds(priv); -} - -/*******************/ -/* Rfkill */ -/*******************/ - -static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv) -{ - return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) == - priv->ah->rfkill_polarity; -} - -static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - bool blocked = !!ath_is_rfkill_set(priv); - - wiphy_rfkill_set_hw_state(hw->wiphy, blocked); -} - -void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) -{ - if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) - wiphy_rfkill_start_polling(priv->hw->wiphy); -} - -static void ath9k_htc_radio_enable(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - struct ath_hw *ah = priv->ah; - struct ath_common *common = ath9k_hw_common(ah); - int ret; - u8 cmd_rsp; - - if (!ah->curchan) - ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - - /* Reset the HW */ - ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); - if (ret) { - ath_err(common, - "Unable to reset hardware; reset status %d (freq %u MHz)\n", - ret, ah->curchan->channel); - } - - ath_update_txpow(priv); - - /* Start RX */ - WMI_CMD(WMI_START_RECV_CMDID); - ath9k_host_rx_init(priv); - - /* Start TX */ - htc_start(priv->htc); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); - ieee80211_wake_queues(hw); - - WMI_CMD(WMI_ENABLE_INTR_CMDID); - - /* Enable LED */ - ath9k_hw_cfg_output(ah, ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - ath9k_hw_set_gpio(ah, ah->led_pin, 0); -} - -static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - struct ath_hw *ah = priv->ah; - struct ath_common *common = ath9k_hw_common(ah); - int ret; - u8 cmd_rsp; - - ath9k_htc_ps_wakeup(priv); - - /* Disable LED */ - ath9k_hw_set_gpio(ah, ah->led_pin, 1); - ath9k_hw_cfg_gpio_input(ah, ah->led_pin); - - WMI_CMD(WMI_DISABLE_INTR_CMDID); - - /* Stop TX */ - ieee80211_stop_queues(hw); - htc_stop(priv->htc); - WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - skb_queue_purge(&priv->tx_queue); - - /* Stop RX */ - WMI_CMD(WMI_STOP_RECV_CMDID); - - /* - * The MIB counters have to be disabled here, - * since the target doesn't do it. - */ - ath9k_hw_disable_mib_counters(ah); - - if (!ah->curchan) - ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - - /* Reset the HW */ - ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); - if (ret) { - ath_err(common, - "Unable to reset hardware; reset status %d (freq %u MHz)\n", - ret, ah->curchan->channel); - } - - /* Disable the PHY */ - ath9k_hw_phy_disable(ah); - - ath9k_htc_ps_restore(priv); - ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); -} - /**********************/ /* mac80211 Callbacks */ /**********************/ -- cgit v1.2.3-59-g8ed1b From 1c30cc19081c16b1fe73ac13f2cb2abc009cdcc4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 28 Dec 2010 15:46:16 +0100 Subject: ath9k_hw: fix dma descriptor rx error bit parsing An Rx DMA descriptor can have multiple error bits set, and some error bits (e.g. MIC failure) are filtered by the driver based on other criteria. Remove the 'else' in various error bit checks so that all error information is properly passed to the driver. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 11 ++++++----- drivers/net/wireless/ath/ath9k/mac.c | 9 +++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index b6e4ee48ef78..4ceddbbdfcee 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -613,9 +613,9 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, * possibly be reviewing the last subframe. AR_CRCErr * is the CRC of the actual data. */ - if (rxsp->status11 & AR_CRCErr) { + if (rxsp->status11 & AR_CRCErr) rxs->rs_status |= ATH9K_RXERR_CRC; - } else if (rxsp->status11 & AR_PHYErr) { + if (rxsp->status11 & AR_PHYErr) { phyerr = MS(rxsp->status11, AR_PHYErrCode); /* * If we reach a point here where AR_PostDelimCRCErr is @@ -638,11 +638,12 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_phyerr = phyerr; } - } else if (rxsp->status11 & AR_DecryptCRCErr) { + } + if (rxsp->status11 & AR_DecryptCRCErr) rxs->rs_status |= ATH9K_RXERR_DECRYPT; - } else if (rxsp->status11 & AR_MichaelErr) { + if (rxsp->status11 & AR_MichaelErr) rxs->rs_status |= ATH9K_RXERR_MIC; - } else if (rxsp->status11 & AR_KeyMiss) + if (rxsp->status11 & AR_KeyMiss) rxs->rs_status |= ATH9K_RXERR_DECRYPT; } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e3d2ebf00e2e..180170d3ce25 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -692,15 +692,16 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { if (ads.ds_rxstatus8 & AR_CRCErr) rs->rs_status |= ATH9K_RXERR_CRC; - else if (ads.ds_rxstatus8 & AR_PHYErr) { + if (ads.ds_rxstatus8 & AR_PHYErr) { rs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); rs->rs_phyerr = phyerr; - } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) + } + if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (ads.ds_rxstatus8 & AR_MichaelErr) + if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; - else if (ads.ds_rxstatus8 & AR_KeyMiss) + if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; } -- cgit v1.2.3-59-g8ed1b From f76b57b47e5fd423f9827c7b0ba7bbd06cca6b9b Mon Sep 17 00:00:00 2001 From: Joel A Fernandes Date: Tue, 28 Dec 2010 19:28:11 -0600 Subject: mac80211: Fix mesh portal communication with other mesh nodes. Fixed a bug where if a mesh interface has a different MAC address from its bridge interface, then it would not be able to send data traffic to any other mesh node. This also adds support for communication between mesh nodes and external bridged nodes by using a 6 address format if the source is a node within the mesh and the destination is an external node proxied by a mesh portal. Signed-off-by: Joel A Fernandes Signed-off-by: John W. Linville --- net/mac80211/tx.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d2b4b67a7b53..11d013590166 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1747,6 +1747,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, __le16 fc; struct ieee80211_hdr hdr; struct ieee80211s_hdr mesh_hdr __maybe_unused; + struct mesh_path *mppath = NULL; const u8 *encaps_data; int encaps_len, skip_header_bytes; int nh_pos, h_pos; @@ -1807,16 +1808,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ret = NETDEV_TX_OK; goto fail; } + if (!is_multicast_ether_addr(skb->data)) + mppath = mpp_path_lookup(skb->data, sdata); + /* + * Do not use address extension, if it is a packet from + * the same interface and the destination is not being + * proxied by any other mest point. + */ if (compare_ether_addr(sdata->vif.addr, - skb->data + ETH_ALEN) == 0) { + skb->data + ETH_ALEN) == 0 && + (!mppath || !compare_ether_addr(mppath->mpp, skb->data))) { hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, skb->data, skb->data + ETH_ALEN); meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, NULL, NULL); } else { /* packet from other interface */ - struct mesh_path *mppath; int is_mesh_mcast = 1; const u8 *mesh_da; @@ -1827,8 +1835,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, else { static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - mppath = mpp_path_lookup(skb->data, sdata); if (mppath) { /* RA TA mDA mSA AE:DA SA */ mesh_da = mppath->mpp; -- cgit v1.2.3-59-g8ed1b From ff039c6fb372c87a3cc4fd25bb846790cb35edb8 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 29 Dec 2010 17:09:02 -0500 Subject: cfg80211: fix transposition of words in printk Fixes the misplaced article in the following: "cfg80211: Updating information on frequency 5785 MHz for 20 a MHz width channel with regulatory rule:" Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- net/wireless/reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 99d41831d76e..37693b6ef23a 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -752,7 +752,7 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); REG_DBG_PRINT("Updating information on frequency %d MHz " - "for %d a MHz width channel with regulatory rule:\n", + "for a %d MHz width channel with regulatory rule:\n", chan->center_freq, KHZ_TO_MHZ(desired_bw_khz)); -- cgit v1.2.3-59-g8ed1b From bd8027a72a1af95efd1dc8ea6df2fd9724c885b2 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 30 Dec 2010 12:18:01 +0530 Subject: Revert "ath9k: Parse DTIM period from mac80211" This reverts commit 0ce3bcfc84900a64347b0fe1140229bd81314008. Event though with the above commit we obtain the configured DTIM period from the AP rather than always hardcoding it to '1', this seems to cause problems under the following scenarios: * Preventing association with broken AP's * Adds latency in roaming So its better to always use the safe value of '1' for dtim period Cc: Jouni Malinen Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +-- drivers/net/wireless/ath/ath9k/init.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9150ca665367..38433f9bfe59 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -716,8 +716,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_NEED_DTIM_PERIOD; + IEEE80211_HW_PS_NULLFUNC_STACK; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index efb778d4356a..b6643b5bf050 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -648,8 +648,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_REPORTS_TX_ACK_STATUS | - IEEE80211_HW_NEED_DTIM_PERIOD; + IEEE80211_HW_REPORTS_TX_ACK_STATUS; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; -- cgit v1.2.3-59-g8ed1b From 1186488b4a4d4871e40cb1604ba3ede3d4b7cc90 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 30 Dec 2010 19:07:44 +0530 Subject: ath9k: fix beacon restart on channel change Restart the beacon timers only if the beacon was already configured. Otherwise beacons timers are restarted unnecessarily in unassociated state too. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0f1b62456141..a818e4fd56f5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -285,7 +285,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { - ath_beacon_config(sc, NULL); + if (sc->sc_flags & SC_OP_BEACONS) + ath_beacon_config(sc, NULL); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ath_start_ani(common); } -- cgit v1.2.3-59-g8ed1b From 24a8fdad35835e8d71f7c4b978a246fafed2e7b4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 30 Dec 2010 17:25:29 +0100 Subject: mac80211: serialize rx path workers This patch addresses the issue of serialization between the main rx path and various reorder release timers. It converts the previously local "frames" queue into a global rx queue [rx_skb_queue]. This way, everyone (be it the main rx-path or some reorder release timeout) can add frames to it. Only one active rx handler worker [ieee80211_rx_handlers] is needed. All other threads which have lost the race of "runnning_rx_handler" can now simply "return", knowing that the thread who had the "edge" will also take care of their workload. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 9 ++++++ net/mac80211/main.c | 3 ++ net/mac80211/rx.c | 80 +++++++++++++++++++++------------------------- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a9eb67380da6..1bf2fc8b9bde 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -761,6 +761,15 @@ struct ieee80211_local { struct sk_buff_head skb_queue; struct sk_buff_head skb_queue_unreliable; + /* + * Internal FIFO queue which is shared between multiple rx path + * stages. Its main task is to provide a serialization mechanism, + * so all rx handlers can enjoy having exclusive access to their + * private data structures. + */ + struct sk_buff_head rx_skb_queue; + bool running_rx_handler; /* protected by rx_skb_queue.lock */ + /* Station data */ /* * The mutex only protects the list and counter, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a21d049caf19..32e7ae0dac98 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -569,6 +569,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, spin_lock_init(&local->filter_lock); spin_lock_init(&local->queue_stop_reason_lock); + skb_queue_head_init(&local->rx_skb_queue); + INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); ieee80211_work_init(local); @@ -912,6 +914,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); skb_queue_purge(&local->skb_queue); skb_queue_purge(&local->skb_queue_unreliable); + skb_queue_purge(&local->rx_skb_queue); destroy_workqueue(local->workqueue); wiphy_unregister(local->hw.wiphy); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 260b48bac42e..12cbb4df81aa 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -533,9 +533,9 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, - int index, - struct sk_buff_head *frames) + int index) { + struct ieee80211_local *local = hw_to_local(hw); struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; struct ieee80211_rx_status *status; @@ -549,7 +549,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, tid_agg_rx->reorder_buf[index] = NULL; status = IEEE80211_SKB_RXCB(skb); status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; - __skb_queue_tail(frames, skb); + skb_queue_tail(&local->rx_skb_queue, skb); no_frame: tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); @@ -557,8 +557,7 @@ no_frame: static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, - u16 head_seq_num, - struct sk_buff_head *frames) + u16 head_seq_num) { int index; @@ -567,7 +566,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; - ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); + ieee80211_release_reorder_frame(hw, tid_agg_rx, index); } } @@ -583,8 +582,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, - struct tid_ampdu_rx *tid_agg_rx, - struct sk_buff_head *frames) + struct tid_ampdu_rx *tid_agg_rx) { int index, j; @@ -615,8 +613,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, wiphy_debug(hw->wiphy, "release an RX reorder frame due to timeout on earlier frames\n"); #endif - ieee80211_release_reorder_frame(hw, tid_agg_rx, - j, frames); + ieee80211_release_reorder_frame(hw, tid_agg_rx, j); /* * Increment the head seq# also for the skipped slots. @@ -626,7 +623,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, skipped = 0; } } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); + ieee80211_release_reorder_frame(hw, tid_agg_rx, index); index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; } @@ -682,8 +679,7 @@ set_release_timer: */ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, - struct sk_buff *skb, - struct sk_buff_head *frames) + struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u16 sc = le16_to_cpu(hdr->seq_ctrl); @@ -710,8 +706,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num, - frames); + ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); } /* Now the new frame is always in the range of the reordering buffer */ @@ -739,7 +734,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); + ieee80211_sta_reorder_release(hw, tid_agg_rx); out: spin_unlock(&tid_agg_rx->reorder_lock); @@ -750,8 +745,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns * true if the MPDU was buffered, false if it should be processed. */ -static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, - struct sk_buff_head *frames) +static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) { struct sk_buff *skb = rx->skb; struct ieee80211_local *local = rx->local; @@ -806,11 +800,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, * sure that we cannot get to it any more before doing * anything with it. */ - if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) + if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) return; dont_reorder: - __skb_queue_tail(frames, skb); + skb_queue_tail(&local->rx_skb_queue, skb); } static ieee80211_rx_result debug_noinline @@ -1931,7 +1925,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) } static ieee80211_rx_result debug_noinline -ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) +ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) { struct ieee80211_local *local = rx->local; struct ieee80211_hw *hw = &local->hw; @@ -1971,8 +1965,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) spin_lock(&tid_agg_rx->reorder_lock); /* release stored frames up to start of BAR */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, - frames); + ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); spin_unlock(&tid_agg_rx->reorder_lock); kfree_skb(skb); @@ -2489,8 +2482,7 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, } } -static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, - struct sk_buff_head *frames) +static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) { ieee80211_rx_result res = RX_DROP_MONITOR; struct sk_buff *skb; @@ -2502,7 +2494,15 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, goto rxh_next; \ } while (0); - while ((skb = __skb_dequeue(frames))) { + spin_lock(&rx->local->rx_skb_queue.lock); + if (rx->local->running_rx_handler) + goto unlock; + + rx->local->running_rx_handler = true; + + while ((skb = __skb_dequeue(&rx->local->rx_skb_queue))) { + spin_unlock(&rx->local->rx_skb_queue.lock); + /* * all the other fields are valid across frames * that belong to an aMPDU since they are on the @@ -2525,12 +2525,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, CALL_RXH(ieee80211_rx_h_mesh_fwding); #endif CALL_RXH(ieee80211_rx_h_data) - - /* special treatment -- needs the queue */ - res = ieee80211_rx_h_ctrl(rx, frames); - if (res != RX_CONTINUE) - goto rxh_next; - + CALL_RXH(ieee80211_rx_h_ctrl); CALL_RXH(ieee80211_rx_h_mgmt_check) CALL_RXH(ieee80211_rx_h_action) CALL_RXH(ieee80211_rx_h_userspace_mgmt) @@ -2539,18 +2534,20 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, rxh_next: ieee80211_rx_handlers_result(rx, res); - + spin_lock(&rx->local->rx_skb_queue.lock); #undef CALL_RXH } + + rx->local->running_rx_handler = false; + + unlock: + spin_unlock(&rx->local->rx_skb_queue.lock); } static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) { - struct sk_buff_head reorder_release; ieee80211_rx_result res = RX_DROP_MONITOR; - __skb_queue_head_init(&reorder_release); - #define CALL_RXH(rxh) \ do { \ res = rxh(rx); \ @@ -2561,9 +2558,9 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) CALL_RXH(ieee80211_rx_h_passive_scan) CALL_RXH(ieee80211_rx_h_check) - ieee80211_rx_reorder_ampdu(rx, &reorder_release); + ieee80211_rx_reorder_ampdu(rx); - ieee80211_rx_handlers(rx, &reorder_release); + ieee80211_rx_handlers(rx); return; rxh_next: @@ -2578,7 +2575,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) */ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) { - struct sk_buff_head frames; struct ieee80211_rx_data rx = { .sta = sta, .sdata = sta->sdata, @@ -2591,13 +2587,11 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) if (!tid_agg_rx) return; - __skb_queue_head_init(&frames); - spin_lock(&tid_agg_rx->reorder_lock); - ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); + ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); spin_unlock(&tid_agg_rx->reorder_lock); - ieee80211_rx_handlers(&rx, &frames); + ieee80211_rx_handlers(&rx); } /* main receive path */ -- cgit v1.2.3-59-g8ed1b From 707e634326448190bfe2d937c44ec05c8dea63c4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 30 Dec 2010 17:29:53 +0100 Subject: Revert "mac80211: temporarily disable reorder release timer" This reverts enables the reorder release timer once again. The issues laid out in: Have been addressed by: mac80211: serialize rx path workers mac80211: ignore PSM bit of reordered frames Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 12cbb4df81aa..9595e564badd 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -628,26 +628,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, tid_agg_rx->buf_size; } - /* - * Disable the reorder release timer for now. - * - * The current implementation lacks a proper locking scheme - * which would protect vital statistic and debug counters - * from being updated by two different but concurrent BHs. - * - * More information about the topic is available from: - * - thread: http://marc.info/?t=128635927000001 - * - * What was wrong: - * => http://marc.info/?l=linux-wireless&m=128636170811964 - * "Basically the thing is that until your patch, the data - * in the struct didn't actually need locking because it - * was accessed by the RX path only which is not concurrent." - * - * List of what needs to be fixed: - * => http://marc.info/?l=linux-wireless&m=128656352920957 - * - if (tid_agg_rx->stored_mpdu_num) { j = index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; @@ -666,10 +646,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, } else { del_timer(&tid_agg_rx->reorder_timer); } - */ - -set_release_timer: - return; } /* -- cgit v1.2.3-59-g8ed1b From 2ae79d52cdac733037490486792a53de9fb8d6b6 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 31 Dec 2010 20:49:00 +0530 Subject: ath9k : few rate control clean ups Remove some obvious looking dead code and rename few functions Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 16 ++++++++-------- drivers/net/wireless/ath/ath9k/rc.h | 3 --- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 896d12986b1e..e45147820eae 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -400,7 +400,7 @@ static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, } } -static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) +static void ath_rc_init_valid_rate_idx(struct ath_rate_priv *ath_rc_priv) { u8 i; @@ -408,7 +408,7 @@ static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) ath_rc_priv->valid_rate_index[i] = 0; } -static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, +static inline void ath_rc_set_valid_rate_idx(struct ath_rate_priv *ath_rc_priv, u8 index, int valid_tx_rate) { BUG_ON(index > ath_rc_priv->rate_table_size); @@ -489,7 +489,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; ath_rc_priv->valid_phy_ratecnt[phy] += 1; - ath_rc_set_valid_txmask(ath_rc_priv, i, 1); + ath_rc_set_valid_rate_idx(ath_rc_priv, i, 1); hi = i; } } @@ -532,7 +532,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, ath_rc_priv->valid_phy_rateidx[phy] [valid_rate_count] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; - ath_rc_set_valid_txmask(ath_rc_priv, j, 1); + ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); hi = A_MAX(hi, j); } } @@ -568,7 +568,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, ath_rc_priv->valid_phy_rateidx[phy] [ath_rc_priv->valid_phy_ratecnt[phy]] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; - ath_rc_set_valid_txmask(ath_rc_priv, j, 1); + ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); hi = A_MAX(hi, j); } } @@ -1210,7 +1210,7 @@ static void ath_rc_init(struct ath_softc *sc, } /* Determine the valid rates */ - ath_rc_init_valid_txmask(ath_rc_priv); + ath_rc_init_valid_rate_idx(ath_rc_priv); for (i = 0; i < WLAN_RC_PHY_MAX; i++) { for (j = 0; j < MAX_TX_RATE_PHY; j++) @@ -1321,7 +1321,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ath_rate_priv *ath_rc_priv = priv_sta; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; - int final_ts_idx = 0, tx_status = 0, is_underrun = 0; + int final_ts_idx = 0, tx_status = 0; int long_retry = 0; __le16 fc; int i; @@ -1358,7 +1358,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, tx_status = 1; ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, - (is_underrun) ? sc->hw->max_rate_tries : long_retry); + long_retry); /* Check if aggregation has to be enabled for this tid */ if (conf_is_ht(&sc->hw->conf) && diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 31a004cb60ac..5d984b8acdb1 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -195,7 +195,6 @@ struct ath_rc_stats { * @rate_max_phy: phy index for the max rate * @per: PER for every valid rate in % * @probe_interval: interval for ratectrl to probe for other rates - * @prev_data_rix: rate idx of last data frame * @ht_cap: HT capabilities * @neg_rates: Negotatied rates * @neg_ht_rates: Negotiated HT rates @@ -214,10 +213,8 @@ struct ath_rate_priv { u32 probe_time; u32 per_down_time; u32 probe_interval; - u32 prev_data_rix; struct ath_rateset neg_rates; struct ath_rateset neg_ht_rates; - struct ath_rate_softc *asc; const struct ath_rate_table *rate_table; struct dentry *debugfs_rcstats; -- cgit v1.2.3-59-g8ed1b From a8851d10aadb46b25db4459aa0d1150c957d2bc1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 3 Jan 2011 08:46:29 +0300 Subject: ath5k: ath5k_eeprom_mode_from_channel() returns signed ath5k_eeprom_mode_from_channel() returns -1 on error but we're storing the result in "ee_mode" which is an unsigned char. This breaks the error handling. This patch makes "ee_mode" an int. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 9306d5fda675..78c26fdccad1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1916,7 +1916,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) struct ieee80211_channel *channel = ah->ah_current_channel; bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; bool use_def_for_sg; - u8 def_ant, tx_ant, ee_mode; + int ee_mode; + u8 def_ant, tx_ant; u32 sta_id1 = 0; /* if channel is not initialized yet we can't set the antennas @@ -3081,7 +3082,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, { struct ath5k_rate_pcal_info rate_info; struct ieee80211_channel *curr_channel = ah->ah_current_channel; - u8 type, ee_mode; + int ee_mode; + u8 type; int ret; if (txpower > AR5K_TUNE_MAX_TXPOWER) { -- cgit v1.2.3-59-g8ed1b From cc72128750700d01c31f583a355c5f8f809498bb Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 3 Jan 2011 21:22:18 +0530 Subject: ath9k_htc: Fix packet injection To inject a packet in monitor mode, a dummy station has to be associated with the monitor interface in the target. Failing to do this would result in a firmware crash on the device. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 72 ++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ad3dd3186ad2..845b4c938d16 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -235,16 +235,38 @@ err: return ret; } +static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_vif hvif; + int ret = 0; + u8 cmd_rsp; + + memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); + memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); + hvif.index = 0; /* Should do for now */ + WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); + priv->nvifs--; +} + static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_target_vif hvif; + struct ath9k_htc_target_sta tsta; int ret = 0; u8 cmd_rsp; if (priv->nvifs > 0) return -ENOBUFS; + if (priv->nstations >= ATH9K_HTC_MAX_STA) + return -ENOBUFS; + + /* + * Add an interface. + */ + memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); @@ -257,23 +279,57 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) return ret; priv->nvifs++; + + /* + * Associate a station with the interface for packet injection. + */ + + memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); + + memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN); + + tsta.is_vif_sta = 1; + tsta.sta_index = priv->nstations; + tsta.vif_index = hvif.index; + tsta.maxampdu = 0xffff; + + WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); + if (ret) { + ath_err(common, "Unable to add station entry for monitor mode\n"); + goto err_vif; + } + + priv->nstations++; + return 0; + +err_vif: + /* + * Remove the interface from the target. + */ + __ath9k_htc_remove_monitor_interface(priv); + return ret; } static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); - struct ath9k_htc_target_vif hvif; int ret = 0; - u8 cmd_rsp; + u8 cmd_rsp, sta_idx; - memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); - memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - hvif.index = 0; /* Should do for now */ - WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); - priv->nvifs--; + __ath9k_htc_remove_monitor_interface(priv); - return ret; + sta_idx = 0; /* Only single interface, for now */ + + WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); + if (ret) { + ath_err(common, "Unable to remove station entry for monitor mode\n"); + return ret; + } + + priv->nstations--; + + return 0; } static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, -- cgit v1.2.3-59-g8ed1b From b5c34f662a3519d34f9634a14d8de638fdbe0ca3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 3 Jan 2011 19:51:09 +0100 Subject: mac80211: fix some key comments and code The key documentation is slightly out of date, fix that. Also, the list entry in the key struct is no longer used that way, so list_del_init() isn't necessary any more there. Finally, ieee80211_key_link() is no longer invoked under RCU read lock, but rather with an appropriate station lock held. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/key.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 84cf9196820f..315ee301b75e 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -30,19 +30,20 @@ * keys and per-station keys. Since each station belongs to an interface, * each station key also belongs to that interface. * - * Hardware acceleration is done on a best-effort basis, for each key - * that is eligible the hardware is asked to enable that key but if - * it cannot do that they key is simply kept for software encryption. - * There is currently no way of knowing this except by looking into - * debugfs. + * Hardware acceleration is done on a best-effort basis for algorithms + * that are implemented in software, for each key the hardware is asked + * to enable that key for offloading but if it cannot do that the key is + * simply kept for software encryption (unless it is for an algorithm + * that isn't implemented in software). + * There is currently no way of knowing whether a key is handled in SW + * or HW except by looking into debugfs. * - * All key operations are protected internally. - * - * Within mac80211, key references are, just as STA structure references, - * protected by RCU. Note, however, that some things are unprotected, - * namely the key->sta dereferences within the hardware acceleration - * functions. This means that sta_info_destroy() must remove the key - * which waits for an RCU grace period. + * All key management is internally protected by a mutex. Within all + * other parts of mac80211, key references are, just as STA structure + * references, protected by RCU. Note, however, that some things are + * unprotected, namely the key->sta dereferences within the hardware + * acceleration functions. This means that sta_info_destroy() must + * remove the key which waits for an RCU grace period. */ static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -279,13 +280,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, new->conf.keyidx); } - if (old) { - /* - * We'll use an empty list to indicate that the key - * has already been removed. - */ - list_del_init(&old->list); - } + if (old) + list_del(&old->list); } struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, @@ -420,8 +416,8 @@ int ieee80211_key_link(struct ieee80211_key *key, struct sta_info *ap; /* - * We're getting a sta pointer in, - * so must be under RCU read lock. + * We're getting a sta pointer in, so must be under + * appropriate locking for sta_info_get(). */ /* same here, the AP could be using QoS */ -- cgit v1.2.3-59-g8ed1b From db98a6cfcc9ac951067c9a2cb60459b618fd7b10 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Mon, 3 Jan 2011 12:03:44 -0800 Subject: libertas: down_interruptible() can return -EINTR, not EINTR Fix test in lbs_spi_thread(). down_interruptible() can return -EINTR, but not EINTR. Signed-off-by: Roel Kluin Cc: Dan Williams Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index ecd4d04b2c3c..00600239a053 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -784,7 +784,7 @@ static int lbs_spi_thread(void *data) up(&card->spi_thread_terminated); do_exit(0); } - } while (err == EINTR); + } while (err == -EINTR); /* Read the host interrupt status register to see what we * can do. */ -- cgit v1.2.3-59-g8ed1b From 3e6109c57468ed320beefd2861fe2cc418cccfc2 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 5 Jan 2011 09:39:17 -0500 Subject: ath9k: qualify global modparam_nohwcrypt variable Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/init.c | 6 +++--- drivers/net/wireless/ath/ath9k/main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index fcc087ce3bc3..3681caf54282 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -664,7 +664,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) } extern struct ieee80211_ops ath9k_ops; -extern int modparam_nohwcrypt; +extern int ath9k_modparam_nohwcrypt; extern int led_blink; extern int ath9k_pm_qos_value; extern bool is_ath9k_unloaded; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b6643b5bf050..767d8b86f1e1 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -29,8 +29,8 @@ static unsigned int ath9k_debug = ATH_DBG_DEFAULT; module_param_named(debug, ath9k_debug, uint, 0); MODULE_PARM_DESC(debug, "Debugging mask"); -int modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); +int ath9k_modparam_nohwcrypt; +module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); int led_blink; @@ -653,7 +653,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; - if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) + if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) hw->flags |= IEEE80211_HW_MFP_CAPABLE; hw->wiphy->interface_modes = diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a818e4fd56f5..f90a6ca94a76 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1829,7 +1829,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, struct ath_common *common = ath9k_hw_common(sc->sc_ah); int ret = 0; - if (modparam_nohwcrypt) + if (ath9k_modparam_nohwcrypt) return -ENOSPC; mutex_lock(&sc->mutex); -- cgit v1.2.3-59-g8ed1b From 18cb6e32e7aeea9c92af5793bee2b32536615502 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 5 Jan 2011 09:39:59 -0500 Subject: ath5k: qualify global modparam_nohwcrypt variable Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fce9a987789c..019a74d533a6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -61,8 +61,8 @@ #include "debug.h" #include "ani.h" -int modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); +int ath5k_modparam_nohwcrypt; +module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); static int modparam_all_channels; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index de257a3430be..d76d68c99f72 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -46,7 +46,7 @@ #include "base.h" #include "reg.h" -extern int modparam_nohwcrypt; +extern int ath5k_modparam_nohwcrypt; /* functions used from base.c */ void set_beacon_filter(struct ieee80211_hw *hw, bool enable); @@ -485,7 +485,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ath_common *common = ath5k_hw_common(ah); int ret = 0; - if (modparam_nohwcrypt) + if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; switch (key->cipher) { -- cgit v1.2.3-59-g8ed1b From 33af88138b859f515b365a074e0a014d7cdbf846 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 5 Jan 2011 14:05:00 -0500 Subject: ath9k: correct MODULE_PARM_DESC parameters for force_new_ani Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index fdb5a835fdcf..f8a7771faee2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -22,7 +22,7 @@ int modparam_force_new_ani; module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); -MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002"); +MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002"); /* General hardware code for the A5008/AR9001/AR9002 hadware families */ -- cgit v1.2.3-59-g8ed1b From 21f83589644bb2ed98079bf1e2154c8e70ca6a6c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 18 Dec 2010 17:20:47 +0100 Subject: mac80211: implement hardware offload for remain-on-channel This allows drivers to support remain-on-channel offload if they implement smarter timing or need to use a device implementation like iwlwifi. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 19 +++++++++++ net/mac80211/cfg.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/driver-ops.h | 30 ++++++++++++++++ net/mac80211/driver-trace.h | 80 +++++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 8 +++++ net/mac80211/iface.c | 9 +++-- net/mac80211/main.c | 5 ++- net/mac80211/offchannel.c | 75 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 306 insertions(+), 3 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 479c35e160e3..5b3fd5add7a4 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -365,6 +365,7 @@ enum mac80211_tx_control_flags { IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), IEEE80211_TX_CTL_LDPC = BIT(22), IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), + IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25), }; #define IEEE80211_TX_CTL_STBC_SHIFT 23 @@ -1824,6 +1825,12 @@ struct ieee80211_ops { int (*napi_poll)(struct ieee80211_hw *hw, int budget); int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); + + int (*remain_on_channel)(struct ieee80211_hw *hw, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + int duration); + int (*cancel_remain_on_channel)(struct ieee80211_hw *hw); }; /** @@ -2729,6 +2736,18 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, */ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf); +/** + * ieee80211_ready_on_channel - notification of remain-on-channel start + * @hw: pointer as obtained from ieee80211_alloc_hw() + */ +void ieee80211_ready_on_channel(struct ieee80211_hw *hw); + +/** + * ieee80211_remain_on_channel_expired - remain_on_channel duration expired + * @hw: pointer as obtained from ieee80211_alloc_hw() + */ +void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw); + /* Rate control API */ /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5892b0302454..168a6ba8fc28 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1593,6 +1593,37 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, return 0; } +static int ieee80211_remain_on_channel_hw(struct ieee80211_local *local, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type chantype, + unsigned int duration, u64 *cookie) +{ + int ret; + u32 random_cookie; + + lockdep_assert_held(&local->mtx); + + if (local->hw_roc_cookie) + return -EBUSY; + /* must be nonzero */ + random_cookie = random32() | 1; + + *cookie = random_cookie; + local->hw_roc_dev = dev; + local->hw_roc_cookie = random_cookie; + local->hw_roc_channel = chan; + local->hw_roc_channel_type = chantype; + local->hw_roc_duration = duration; + ret = drv_remain_on_channel(local, chan, chantype, duration); + if (ret) { + local->hw_roc_channel = NULL; + local->hw_roc_cookie = 0; + } + + return ret; +} + static int ieee80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, @@ -1601,16 +1632,62 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy, u64 *cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + + if (local->ops->remain_on_channel) { + int ret; + + mutex_lock(&local->mtx); + ret = ieee80211_remain_on_channel_hw(local, dev, + chan, channel_type, + duration, cookie); + mutex_unlock(&local->mtx); + + return ret; + } return ieee80211_wk_remain_on_channel(sdata, chan, channel_type, duration, cookie); } +static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local, + u64 cookie) +{ + int ret; + + lockdep_assert_held(&local->mtx); + + if (local->hw_roc_cookie != cookie) + return -ENOENT; + + ret = drv_cancel_remain_on_channel(local); + if (ret) + return ret; + + local->hw_roc_cookie = 0; + local->hw_roc_channel = NULL; + + ieee80211_recalc_idle(local); + + return 0; +} + static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, u64 cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + + if (local->ops->cancel_remain_on_channel) { + int ret; + + mutex_lock(&local->mtx); + ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); + mutex_unlock(&local->mtx); + + return ret; + } return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); } @@ -1662,6 +1739,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, channel_type != local->_oper_channel_type)) is_offchan = true; + if (chan == local->hw_roc_channel) { + /* TODO: check channel type? */ + is_offchan = false; + flags |= IEEE80211_TX_CTL_TX_OFFCHAN; + } + if (is_offchan && !offchan) return -EBUSY; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index af0c4398cceb..98d589960a49 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -465,4 +465,34 @@ static inline int drv_get_antenna(struct ieee80211_local *local, return ret; } +static inline int drv_remain_on_channel(struct ieee80211_local *local, + struct ieee80211_channel *chan, + enum nl80211_channel_type chantype, + unsigned int duration) +{ + int ret; + + might_sleep(); + + trace_drv_remain_on_channel(local, chan, chantype, duration); + ret = local->ops->remain_on_channel(&local->hw, chan, chantype, + duration); + trace_drv_return_int(local, ret); + + return ret; +} + +static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local) +{ + int ret; + + might_sleep(); + + trace_drv_cancel_remain_on_channel(local); + ret = local->ops->cancel_remain_on_channel(&local->hw); + trace_drv_return_int(local, ret); + + return ret; +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index c2772f23ac9c..49c84218b2f4 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -933,6 +933,50 @@ TRACE_EVENT(drv_get_antenna, ) ); +TRACE_EVENT(drv_remain_on_channel, + TP_PROTO(struct ieee80211_local *local, struct ieee80211_channel *chan, + enum nl80211_channel_type chantype, unsigned int duration), + + TP_ARGS(local, chan, chantype, duration), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(int, center_freq) + __field(int, channel_type) + __field(unsigned int, duration) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->center_freq = chan->center_freq; + __entry->channel_type = chantype; + __entry->duration = duration; + ), + + TP_printk( + LOCAL_PR_FMT " freq:%dMHz duration:%dms", + LOCAL_PR_ARG, __entry->center_freq, __entry->duration + ) +); + +TRACE_EVENT(drv_cancel_remain_on_channel, + TP_PROTO(struct ieee80211_local *local), + + TP_ARGS(local), + + TP_STRUCT__entry( + LOCAL_ENTRY + ), + + TP_fast_assign( + LOCAL_ASSIGN; + ), + + TP_printk( + LOCAL_PR_FMT, LOCAL_PR_ARG + ) +); + /* * Tracing for API calls that drivers call. */ @@ -1170,6 +1214,42 @@ TRACE_EVENT(api_chswitch_done, ) ); +TRACE_EVENT(api_ready_on_channel, + TP_PROTO(struct ieee80211_local *local), + + TP_ARGS(local), + + TP_STRUCT__entry( + LOCAL_ENTRY + ), + + TP_fast_assign( + LOCAL_ASSIGN; + ), + + TP_printk( + LOCAL_PR_FMT, LOCAL_PR_ARG + ) +); + +TRACE_EVENT(api_remain_on_channel_expired, + TP_PROTO(struct ieee80211_local *local), + + TP_ARGS(local), + + TP_STRUCT__entry( + LOCAL_ENTRY + ), + + TP_fast_assign( + LOCAL_ASSIGN; + ), + + TP_printk( + LOCAL_PR_FMT, LOCAL_PR_ARG + ) +); + /* * Tracing for internal functions * (which may also be called in response to driver calls) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 95cdd2a3f809..f866af8de5ac 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -951,6 +951,13 @@ struct ieee80211_local { } debugfs; #endif + struct ieee80211_channel *hw_roc_channel; + struct net_device *hw_roc_dev; + struct work_struct hw_roc_start, hw_roc_done; + enum nl80211_channel_type hw_roc_channel_type; + unsigned int hw_roc_duration; + u32 hw_roc_cookie; + /* dummy netdev for use w/ NAPI */ struct net_device napi_dev; @@ -1142,6 +1149,7 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local); void ieee80211_offchannel_stop_station(struct ieee80211_local *local); void ieee80211_offchannel_return(struct ieee80211_local *local, bool enable_beaconing); +void ieee80211_hw_roc_setup(struct ieee80211_local *local); /* interface handling */ int ieee80211_iface_init(void); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b6db237672ff..8acba456744e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1264,7 +1264,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int count = 0; - bool working = false, scanning = false; + bool working = false, scanning = false, hw_roc = false; struct ieee80211_work *wk; unsigned int led_trig_start = 0, led_trig_stop = 0; @@ -1308,6 +1308,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) local->scan_sdata->vif.bss_conf.idle = false; } + if (local->hw_roc_channel) + hw_roc = true; + list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->old_idle == sdata->vif.bss_conf.idle) continue; @@ -1316,7 +1319,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); } - if (working || scanning) + if (working || scanning || hw_roc) led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; else led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; @@ -1328,6 +1331,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); + if (hw_roc) + return ieee80211_idle_off(local, "hw remain-on-channel"); if (working) return ieee80211_idle_off(local, "working"); if (scanning) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4b088b3c25e8..485d36bc9a46 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -609,6 +609,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, ieee80211_led_names(local); + ieee80211_hw_roc_setup(local); + return local_to_hw(local); } EXPORT_SYMBOL(ieee80211_alloc_hw); @@ -753,7 +755,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } } - local->hw.wiphy->max_remain_on_channel_duration = 5000; + if (!local->ops->remain_on_channel) + local->hw.wiphy->max_remain_on_channel_duration = 5000; result = wiphy_register(local->hw.wiphy); if (result < 0) diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 4b564091e51d..49b9ec22d9b6 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -14,6 +14,7 @@ */ #include #include "ieee80211_i.h" +#include "driver-trace.h" /* * inform AP that we will go to sleep so that it will buffer the frames @@ -190,3 +191,77 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, } mutex_unlock(&local->iflist_mtx); } + +static void ieee80211_hw_roc_start(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, hw_roc_start); + + mutex_lock(&local->mtx); + + if (!local->hw_roc_channel) { + mutex_unlock(&local->mtx); + return; + } + + ieee80211_recalc_idle(local); + + cfg80211_ready_on_channel(local->hw_roc_dev, local->hw_roc_cookie, + local->hw_roc_channel, + local->hw_roc_channel_type, + local->hw_roc_duration, + GFP_KERNEL); + mutex_unlock(&local->mtx); +} + +void ieee80211_ready_on_channel(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_ready_on_channel(local); + + ieee80211_queue_work(hw, &local->hw_roc_start); +} +EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); + +static void ieee80211_hw_roc_done(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, hw_roc_done); + + mutex_lock(&local->mtx); + + if (!local->hw_roc_channel) { + mutex_unlock(&local->mtx); + return; + } + + cfg80211_remain_on_channel_expired(local->hw_roc_dev, + local->hw_roc_cookie, + local->hw_roc_channel, + local->hw_roc_channel_type, + GFP_KERNEL); + + local->hw_roc_channel = NULL; + local->hw_roc_cookie = 0; + + ieee80211_recalc_idle(local); + + mutex_unlock(&local->mtx); +} + +void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_remain_on_channel_expired(local); + + ieee80211_queue_work(hw, &local->hw_roc_done); +} +EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); + +void ieee80211_hw_roc_setup(struct ieee80211_local *local) +{ + INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); + INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); +} -- cgit v1.2.3-59-g8ed1b From 90fc4b3a5ba24f09af2a8c4a723651a328949460 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 18 Dec 2010 17:20:48 +0100 Subject: mac80211: implement off-channel TX using hw r-o-c offload When the driver has remain-on-channel offload, implement off-channel transmission using that primitive. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/offchannel.c | 30 +++++++++++++++-------- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 168a6ba8fc28..4bc8a9250cfd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1641,6 +1641,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy, ret = ieee80211_remain_on_channel_hw(local, dev, chan, channel_type, duration, cookie); + local->hw_roc_for_tx = false; mutex_unlock(&local->mtx); return ret; @@ -1783,6 +1784,49 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, *cookie = (unsigned long) skb; + if (is_offchan && local->ops->remain_on_channel) { + unsigned int duration; + int ret; + + mutex_lock(&local->mtx); + /* + * If the duration is zero, then the driver + * wouldn't actually do anything. Set it to + * 100 for now. + * + * TODO: cancel the off-channel operation + * when we get the SKB's TX status and + * the wait time was zero before. + */ + duration = 100; + if (wait) + duration = wait; + ret = ieee80211_remain_on_channel_hw(local, dev, chan, + channel_type, + duration, cookie); + if (ret) { + kfree_skb(skb); + mutex_unlock(&local->mtx); + return ret; + } + + local->hw_roc_for_tx = true; + local->hw_roc_duration = wait; + + /* + * queue up frame for transmission after + * ieee80211_ready_on_channel call + */ + + /* modify cookie to prevent API mismatches */ + *cookie ^= 2; + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; + local->hw_roc_skb = skb; + mutex_unlock(&local->mtx); + + return 0; + } + /* * Can transmit right away if the channel was the * right one and there's no wait involved... If a @@ -1823,6 +1867,21 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, int ret = -ENOENT; mutex_lock(&local->mtx); + + if (local->ops->cancel_remain_on_channel) { + cookie ^= 2; + ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); + + if (ret == 0) { + kfree_skb(local->hw_roc_skb); + local->hw_roc_skb = NULL; + } + + mutex_unlock(&local->mtx); + + return ret; + } + list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f866af8de5ac..c47d7c0e48a4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -953,10 +953,12 @@ struct ieee80211_local { struct ieee80211_channel *hw_roc_channel; struct net_device *hw_roc_dev; + struct sk_buff *hw_roc_skb; struct work_struct hw_roc_start, hw_roc_done; enum nl80211_channel_type hw_roc_channel_type; unsigned int hw_roc_duration; u32 hw_roc_cookie; + bool hw_roc_for_tx; /* dummy netdev for use w/ NAPI */ struct net_device napi_dev; diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 49b9ec22d9b6..b4e52676f3fb 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -196,6 +196,7 @@ static void ieee80211_hw_roc_start(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, hw_roc_start); + struct ieee80211_sub_if_data *sdata; mutex_lock(&local->mtx); @@ -206,11 +207,19 @@ static void ieee80211_hw_roc_start(struct work_struct *work) ieee80211_recalc_idle(local); - cfg80211_ready_on_channel(local->hw_roc_dev, local->hw_roc_cookie, - local->hw_roc_channel, - local->hw_roc_channel_type, - local->hw_roc_duration, - GFP_KERNEL); + if (local->hw_roc_skb) { + sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); + ieee80211_tx_skb(sdata, local->hw_roc_skb); + local->hw_roc_skb = NULL; + } else { + cfg80211_ready_on_channel(local->hw_roc_dev, + local->hw_roc_cookie, + local->hw_roc_channel, + local->hw_roc_channel_type, + local->hw_roc_duration, + GFP_KERNEL); + } + mutex_unlock(&local->mtx); } @@ -236,11 +245,12 @@ static void ieee80211_hw_roc_done(struct work_struct *work) return; } - cfg80211_remain_on_channel_expired(local->hw_roc_dev, - local->hw_roc_cookie, - local->hw_roc_channel, - local->hw_roc_channel_type, - GFP_KERNEL); + if (!local->hw_roc_for_tx) + cfg80211_remain_on_channel_expired(local->hw_roc_dev, + local->hw_roc_cookie, + local->hw_roc_channel, + local->hw_roc_channel_type, + GFP_KERNEL); local->hw_roc_channel = NULL; local->hw_roc_cookie = 0; -- cgit v1.2.3-59-g8ed1b From 06778b1c383afbdb88ffd837e117bec06a76f450 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Dec 2010 10:15:52 +0100 Subject: mac80211: remove stray extern Somehow this snuck into my earlier patch, and only now did I see a compiler warning: net/mac80211/led.c:218:13: warning: function '__ieee80211_create_tpt_led_trigger' with external linkage has definition Remove the stray extern. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/led.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/led.c b/net/mac80211/led.c index 4905eb8af572..14590332c81c 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -215,8 +215,8 @@ static void tpt_trig_timer(unsigned long data) read_unlock(&tpt_trig->trig.leddev_list_lock); } -extern char *__ieee80211_create_tpt_led_trigger( - struct ieee80211_hw *hw, unsigned int flags, +char *__ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, + unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len) { -- cgit v1.2.3-59-g8ed1b From 44b8288308ac9da27eab7d7bdbf1375a568805c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 5 Jan 2011 10:35:02 +0000 Subject: net_sched: pfifo_head_drop problem commit 57dbb2d83d100ea (sched: add head drop fifo queue) introduced pfifo_head_drop, and broke the invariant that sch->bstats.bytes and sch->bstats.packets are COUNTER (increasing counters only) This can break estimators because est_timer() handles unsigned deltas only. A decreasing counter can then give a huge unsigned delta. My mid term suggestion would be to change things so that sch->bstats.bytes and sch->bstats.packets are incremented in dequeue() only, not at enqueue() time. We also could add drop_bytes/drop_packets and provide estimations of drop rates. It would be more sensible anyway for very low speeds, and big bursts. Right now, if we drop packets, they still are accounted in byte/packets abolute counters and rate estimators. Before this mid term change, this patch makes pfifo_head_drop behavior similar to other qdiscs in case of drops : Dont decrement sch->bstats.bytes and sch->bstats.packets Signed-off-by: Eric Dumazet Acked-by: Hagen Paul Pfeifer Signed-off-by: David S. Miller --- net/sched/sch_fifo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 4dfecb0cba37..aa4d6337e43c 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -54,8 +54,6 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) /* queue full, remove one skb to fulfill the limit */ skb_head = qdisc_dequeue_head(sch); - sch->bstats.bytes -= qdisc_pkt_len(skb_head); - sch->bstats.packets--; sch->qstats.drops++; kfree_skb(skb_head); -- cgit v1.2.3-59-g8ed1b From 3610cda53f247e176bcbb7a7cca64bc53b12acdb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 5 Jan 2011 15:38:53 -0800 Subject: af_unix: Avoid socket->sk NULL OOPS in stream connect security hooks. unix_release() can asynchornously set socket->sk to NULL, and it does so without holding the unix_state_lock() on "other" during stream connects. However, the reverse mapping, sk->sk_socket, is only transitioned to NULL under the unix_state_lock(). Therefore make the security hooks follow the reverse mapping instead of the forward mapping. Reported-by: Jeremy Fitzhardinge Reported-by: Linus Torvalds Signed-off-by: David S. Miller --- include/linux/security.h | 15 +++++++-------- net/unix/af_unix.c | 2 +- security/capability.c | 2 +- security/security.c | 3 +-- security/selinux/hooks.c | 10 +++++----- security/smack/smack_lsm.c | 14 +++++++------- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index fd4d55fb8845..d47a4c24b3e4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -796,8 +796,9 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @unix_stream_connect: * Check permissions before establishing a Unix domain stream connection * between @sock and @other. - * @sock contains the socket structure. - * @other contains the peer socket structure. + * @sock contains the sock structure. + * @other contains the peer sock structure. + * @newsk contains the new sock structure. * Return 0 if permission is granted. * @unix_may_send: * Check permissions before connecting or sending datagrams from @sock to @@ -1568,8 +1569,7 @@ struct security_operations { int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); #ifdef CONFIG_SECURITY_NETWORK - int (*unix_stream_connect) (struct socket *sock, - struct socket *other, struct sock *newsk); + int (*unix_stream_connect) (struct sock *sock, struct sock *other, struct sock *newsk); int (*unix_may_send) (struct socket *sock, struct socket *other); int (*socket_create) (int family, int type, int protocol, int kern); @@ -2525,8 +2525,7 @@ static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 #ifdef CONFIG_SECURITY_NETWORK -int security_unix_stream_connect(struct socket *sock, struct socket *other, - struct sock *newsk); +int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk); int security_unix_may_send(struct socket *sock, struct socket *other); int security_socket_create(int family, int type, int protocol, int kern); int security_socket_post_create(struct socket *sock, int family, @@ -2567,8 +2566,8 @@ void security_tun_dev_post_create(struct sock *sk); int security_tun_dev_attach(struct sock *sk); #else /* CONFIG_SECURITY_NETWORK */ -static inline int security_unix_stream_connect(struct socket *sock, - struct socket *other, +static inline int security_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) { return 0; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 417d7a6c36cf..dd419d286204 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1157,7 +1157,7 @@ restart: goto restart; } - err = security_unix_stream_connect(sock, other->sk_socket, newsk); + err = security_unix_stream_connect(sk, other, newsk); if (err) { unix_state_unlock(sk); goto out_unlock; diff --git a/security/capability.c b/security/capability.c index c773635ca3a0..2a5df2b7da83 100644 --- a/security/capability.c +++ b/security/capability.c @@ -548,7 +548,7 @@ static int cap_sem_semop(struct sem_array *sma, struct sembuf *sops, } #ifdef CONFIG_SECURITY_NETWORK -static int cap_unix_stream_connect(struct socket *sock, struct socket *other, +static int cap_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { return 0; diff --git a/security/security.c b/security/security.c index 1b798d3df710..e5fb07a3052d 100644 --- a/security/security.c +++ b/security/security.c @@ -977,8 +977,7 @@ EXPORT_SYMBOL(security_inode_getsecctx); #ifdef CONFIG_SECURITY_NETWORK -int security_unix_stream_connect(struct socket *sock, struct socket *other, - struct sock *newsk) +int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { return security_ops->unix_stream_connect(sock, other, newsk); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c82538a4b1a4..6f637d2678ac 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3921,18 +3921,18 @@ static int selinux_socket_shutdown(struct socket *sock, int how) return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN); } -static int selinux_socket_unix_stream_connect(struct socket *sock, - struct socket *other, +static int selinux_socket_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) { - struct sk_security_struct *sksec_sock = sock->sk->sk_security; - struct sk_security_struct *sksec_other = other->sk->sk_security; + struct sk_security_struct *sksec_sock = sock->sk_security; + struct sk_security_struct *sksec_other = other->sk_security; struct sk_security_struct *sksec_new = newsk->sk_security; struct common_audit_data ad; int err; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.u.net.sk = other->sk; + ad.u.net.sk = other; err = avc_has_perm(sksec_sock->sid, sksec_other->sid, sksec_other->sclass, diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 489a85afa477..ccb71a044a1a 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2408,22 +2408,22 @@ static int smack_setprocattr(struct task_struct *p, char *name, /** * smack_unix_stream_connect - Smack access on UDS - * @sock: one socket - * @other: the other socket + * @sock: one sock + * @other: the other sock * @newsk: unused * * Return 0 if a subject with the smack of sock could access * an object with the smack of other, otherwise an error code */ -static int smack_unix_stream_connect(struct socket *sock, - struct socket *other, struct sock *newsk) +static int smack_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) { - struct inode *sp = SOCK_INODE(sock); - struct inode *op = SOCK_INODE(other); + struct inode *sp = SOCK_INODE(sock->sk_socket); + struct inode *op = SOCK_INODE(other->sk_socket); struct smk_audit_info ad; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); - smk_ad_setfield_u_net_sk(&ad, other->sk); + smk_ad_setfield_u_net_sk(&ad, other); return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE, &ad); } -- cgit v1.2.3-59-g8ed1b From 2c6607c611cb7bf0a6750bcea34a258144e302c5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 6 Jan 2011 10:54:29 -0800 Subject: net: add POLLPRI to sock_def_readable() Leonardo Chiquitto found poll() could block forever on tcp sockets and Urgent data was received, if the event flag only contains POLLPRI. He did a bisection and found commit 4938d7e0233 (poll: avoid extra wakeups in select/poll) was the source of the problem. Problem is TCP sockets use standard sock_def_readable() function for their sk_data_ready() handler, and sock_def_readable() doesnt signal POLLPRI. Only TCP is affected by the problem. Adding POLLPRI to the list of flags might trigger unnecessary schedules, but URGENT handling is such a seldom used feature this seems a good compromise. Thanks a lot to Leonardo for providing the bisection result and a test program as well. Reference : http://www.spinics.net/lists/netdev/msg151793.html Reported-and-bisected-by: Leonardo Chiquitto Signed-off-by: Eric Dumazet Tested-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/sock.c b/net/core/sock.c index a6b9e8061f34..a658aeb6d554 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1908,7 +1908,7 @@ static void sock_def_readable(struct sock *sk, int len) rcu_read_lock(); wq = rcu_dereference(sk->sk_wq); if (wq_has_sleeper(wq)) - wake_up_interruptible_sync_poll(&wq->wait, POLLIN | + wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND); sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); rcu_read_unlock(); -- cgit v1.2.3-59-g8ed1b From 238c855805c853eaec95b0bc3065effb64f955a0 Mon Sep 17 00:00:00 2001 From: Henry Ptasinski Date: Tue, 4 Jan 2011 16:07:14 +0000 Subject: include/linux/if_ether.h: Add #define ETH_P_LINK_CTL for HPNA and wlan local tunnel Ethertype used by HPNA control protocols (LARQ, rate, link, etc) and by Broadcom wlan drivers for local signalling. Signed-off-by: Henry Ptasinski Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index f9c3df03db0f..be69043d2896 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -72,6 +72,7 @@ #define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */ #define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */ #define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */ #define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport * over Ethernet */ -- cgit v1.2.3-59-g8ed1b From 0c6610017459ed9642548694fe88971d3f4206aa Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 4 Jan 2011 19:24:06 +0000 Subject: net: ixp4xx_eth: Return proper error for eth_init_one Return PTR_ERR(port->phydev) instead of 1 if phy_connect failed. Signed-off-by: Axel Lin Acked-by: Krzysztof Halasa Signed-off-by: David S. Miller --- drivers/net/arm/ixp4xx_eth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 6028226a7270..9eb9b98a7ae3 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -1229,8 +1229,10 @@ static int __devinit eth_init_one(struct platform_device *pdev) snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, PHY_INTERFACE_MODE_MII); - if ((err = IS_ERR(port->phydev))) + if (IS_ERR(port->phydev)) { + err = PTR_ERR(port->phydev); goto err_free_mem; + } port->phydev->irq = PHY_POLL; -- cgit v1.2.3-59-g8ed1b From 70bfa2d2e1bfd90ef26758b5e2749f043a940037 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 4 Jan 2011 21:03:12 +0000 Subject: dcb: unlock on error in dcbnl_ieee_get() There is a "goto nla_put_failure" hidden inside the NLA_PUT() macro, but we're holding the dcb_lock so we need to unlock first. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 9399af565715..4323bd441f0f 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1264,9 +1264,14 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, spin_lock(&dcb_lock); list_for_each_entry(itr, &dcb_app_list, list) { - if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0) - NLA_PUT(skb, DCB_ATTR_IEEE_APP, - sizeof(itr->app), &itr->app); + if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0) { + err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), + &itr->app); + if (err) { + spin_unlock(&dcb_lock); + goto nla_put_failure; + } + } } spin_unlock(&dcb_lock); nla_nest_end(skb, app); -- cgit v1.2.3-59-g8ed1b From 2a8fe003741aa90b6b9453e90af4bbb7bc42918c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 4 Jan 2011 21:03:44 +0000 Subject: dcb: use after free in dcb_flushapp() The original code has a use after free bug because it's not using the _safe() version of the list_for_each_entry() macro. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 4323bd441f0f..d900ab99814a 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1643,9 +1643,10 @@ EXPORT_SYMBOL(dcb_setapp); static void dcb_flushapp(void) { struct dcb_app_type *app; + struct dcb_app_type *tmp; spin_lock(&dcb_lock); - list_for_each_entry(app, &dcb_app_list, list) { + list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { list_del(&app->list); kfree(app); } -- cgit v1.2.3-59-g8ed1b From 9c86c0f4ba49b39f909d7f18731b91e563e07065 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 4 Jan 2011 22:40:04 +0000 Subject: net: r6040: Return proper error for r6040_init_one Return -ENOMEM instead of 0 for the case of mdiobus_alloc and kmalloc failure. Signed-off-by: Axel Lin Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 0b014c894686..27e6f6d43cac 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1153,6 +1153,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, lp->mii_bus = mdiobus_alloc(); if (!lp->mii_bus) { dev_err(&pdev->dev, "mdiobus_alloc() failed\n"); + err = -ENOMEM; goto err_out_unmap; } @@ -1165,6 +1166,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); if (!lp->mii_bus->irq) { dev_err(&pdev->dev, "mii_bus irq allocation failed\n"); + err = -ENOMEM; goto err_out_mdio; } -- cgit v1.2.3-59-g8ed1b From 6623e3b24a5ebb07e81648c478d286a1329ab891 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 5 Jan 2011 07:52:55 +0000 Subject: ipv4: IP defragmentation must be ECN aware RFC3168 (The Addition of Explicit Congestion Notification to IP) states : 5.3. Fragmentation ECN-capable packets MAY have the DF (Don't Fragment) bit set. Reassembly of a fragmented packet MUST NOT lose indications of congestion. In other words, if any fragment of an IP packet to be reassembled has the CE codepoint set, then one of two actions MUST be taken: * Set the CE codepoint on the reassembled packet. However, this MUST NOT occur if any of the other fragments contributing to this reassembly carries the Not-ECT codepoint. * The packet is dropped, instead of being reassembled, for any other reason. This patch implements this requirement for IPv4, choosing the first action : If one fragment had NO-ECT codepoint reassembled frame has NO-ECT ElIf one fragment had CE codepoint reassembled frame has CE Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_fragment.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index e6215bdd96c0..a1151b8adf3c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -45,6 +45,7 @@ #include #include #include +#include /* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6 * code now. If you change something here, _PLEASE_ update ipv6/reassembly.c @@ -70,11 +71,28 @@ struct ipq { __be32 daddr; __be16 id; u8 protocol; + u8 ecn; /* RFC3168 support */ int iif; unsigned int rid; struct inet_peer *peer; }; +#define IPFRAG_ECN_CLEAR 0x01 /* one frag had INET_ECN_NOT_ECT */ +#define IPFRAG_ECN_SET_CE 0x04 /* one frag had INET_ECN_CE */ + +static inline u8 ip4_frag_ecn(u8 tos) +{ + tos = (tos & INET_ECN_MASK) + 1; + /* + * After the last operation we have (in binary): + * INET_ECN_NOT_ECT => 001 + * INET_ECN_ECT_1 => 010 + * INET_ECN_ECT_0 => 011 + * INET_ECN_CE => 100 + */ + return (tos & 2) ? 0 : tos; +} + static struct inet_frags ip4_frags; int ip_frag_nqueues(struct net *net) @@ -137,6 +155,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a) qp->protocol = arg->iph->protocol; qp->id = arg->iph->id; + qp->ecn = ip4_frag_ecn(arg->iph->tos); qp->saddr = arg->iph->saddr; qp->daddr = arg->iph->daddr; qp->user = arg->user; @@ -316,6 +335,7 @@ static int ip_frag_reinit(struct ipq *qp) qp->q.fragments = NULL; qp->q.fragments_tail = NULL; qp->iif = 0; + qp->ecn = 0; return 0; } @@ -328,6 +348,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) int flags, offset; int ihl, end; int err = -ENOENT; + u8 ecn; if (qp->q.last_in & INET_FRAG_COMPLETE) goto err; @@ -339,6 +360,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) goto err; } + ecn = ip4_frag_ecn(ip_hdr(skb)->tos); offset = ntohs(ip_hdr(skb)->frag_off); flags = offset & ~IP_OFFSET; offset &= IP_OFFSET; @@ -472,6 +494,7 @@ found: } qp->q.stamp = skb->tstamp; qp->q.meat += skb->len; + qp->ecn |= ecn; atomic_add(skb->truesize, &qp->q.net->mem); if (offset == 0) qp->q.last_in |= INET_FRAG_FIRST_IN; @@ -583,6 +606,17 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, iph = ip_hdr(head); iph->frag_off = 0; iph->tot_len = htons(len); + /* RFC3168 5.3 Fragmentation support + * If one fragment had INET_ECN_NOT_ECT, + * reassembled frame also has INET_ECN_NOT_ECT + * Elif one fragment had INET_ECN_CE + * reassembled frame also has INET_ECN_CE + */ + if (qp->ecn & IPFRAG_ECN_CLEAR) + iph->tos &= ~INET_ECN_MASK; + else if (qp->ecn & IPFRAG_ECN_SET_CE) + iph->tos |= INET_ECN_CE; + IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); qp->q.fragments = NULL; qp->q.fragments_tail = NULL; -- cgit v1.2.3-59-g8ed1b From f682cefa5ad204d3bfaa54a58046c66d2d035ac1 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 5 Jan 2011 04:23:23 +0000 Subject: netfilter: fix the race when initializing nf_ct_expect_hash_rnd Since nf_ct_expect_dst_hash() may be called without nf_conntrack_lock locked, nf_ct_expect_hash_rnd should be initialized in the atomic way. In this patch, we use nf_conntrack_hash_rnd instead of nf_ct_expect_hash_rnd. Signed-off-by: Changli Gao Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/netfilter/nf_conntrack.h | 2 ++ net/netfilter/nf_conntrack_core.c | 30 +++++++++++++++++------------- net/netfilter/nf_conntrack_expect.c | 10 +++------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index caf17db87dbc..d85cff10e169 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -298,6 +298,8 @@ static inline int nf_ct_is_untracked(const struct nf_conn *ct) extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); extern unsigned int nf_conntrack_htable_size; extern unsigned int nf_conntrack_max; +extern unsigned int nf_conntrack_hash_rnd; +void init_nf_conntrack_hash_rnd(void); #define NF_CT_STAT_INC(net, count) \ __this_cpu_inc((net)->ct.stat->count) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 27a5ea6b6a0f..e61511929c66 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max); DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked); EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked); -static unsigned int nf_conntrack_hash_rnd __read_mostly; +unsigned int nf_conntrack_hash_rnd __read_mostly; static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone) { @@ -596,6 +596,21 @@ static noinline int early_drop(struct net *net, unsigned int hash) return dropped; } +void init_nf_conntrack_hash_rnd(void) +{ + unsigned int rand; + + /* + * Why not initialize nf_conntrack_rnd in a "init()" function ? + * Because there isn't enough entropy when system initializing, + * and we initialize it as late as possible. + */ + do { + get_random_bytes(&rand, sizeof(rand)); + } while (!rand); + cmpxchg(&nf_conntrack_hash_rnd, 0, rand); +} + static struct nf_conn * __nf_conntrack_alloc(struct net *net, u16 zone, const struct nf_conntrack_tuple *orig, @@ -605,18 +620,7 @@ __nf_conntrack_alloc(struct net *net, u16 zone, struct nf_conn *ct; if (unlikely(!nf_conntrack_hash_rnd)) { - unsigned int rand; - - /* - * Why not initialize nf_conntrack_rnd in a "init()" function ? - * Because there isn't enough entropy when system initializing, - * and we initialize it as late as possible. - */ - do { - get_random_bytes(&rand, sizeof(rand)); - } while (!rand); - cmpxchg(&nf_conntrack_hash_rnd, 0, rand); - + init_nf_conntrack_hash_rnd(); /* recompute the hash as nf_conntrack_hash_rnd is initialized */ hash = hash_conntrack_raw(orig, zone); } diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 46e8966912b1..a20fb0bd1efe 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -32,9 +32,7 @@ unsigned int nf_ct_expect_hsize __read_mostly; EXPORT_SYMBOL_GPL(nf_ct_expect_hsize); -static unsigned int nf_ct_expect_hash_rnd __read_mostly; unsigned int nf_ct_expect_max __read_mostly; -static int nf_ct_expect_hash_rnd_initted __read_mostly; static struct kmem_cache *nf_ct_expect_cachep __read_mostly; @@ -77,15 +75,13 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple { unsigned int hash; - if (unlikely(!nf_ct_expect_hash_rnd_initted)) { - get_random_bytes(&nf_ct_expect_hash_rnd, - sizeof(nf_ct_expect_hash_rnd)); - nf_ct_expect_hash_rnd_initted = 1; + if (unlikely(!nf_conntrack_hash_rnd)) { + init_nf_conntrack_hash_rnd(); } hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all), (((tuple->dst.protonum ^ tuple->src.l3num) << 16) | - (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd); + (__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd); return ((u64)hash * nf_ct_expect_hsize) >> 32; } -- cgit v1.2.3-59-g8ed1b From cba85b532e4aabdb97f44c18987d45141fd93faa Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 6 Jan 2011 11:25:00 -0800 Subject: netfilter: fix export secctx error handling In 1ae4de0cdf855305765592647025bde55e85e451, the secctx was exported via the /proc/net/netfilter/nf_conntrack and ctnetlink interfaces instead of the secmark. That patch introduced the use of security_secid_to_secctx() which may return a non-zero value on error. In one of my setups, I have NF_CONNTRACK_SECMARK enabled but no security modules. Thus, security_secid_to_secctx() returns a negative value that results in the breakage of the /proc and `conntrack -L' outputs. To fix this, we skip the inclusion of secctx if the aforementioned function fails. This patch also fixes the dynamic netlink message size calculation if security_secid_to_secctx() returns an error, since its logic is also wrong. This problem exists in Linux kernel >= 2.6.37. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 25 ++++++++++++---------- net/netfilter/nf_conntrack_standalone.c | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 37f8adb68c79..63f60fc5d26a 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c @@ -97,7 +97,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) ret = security_secid_to_secctx(ct->secmark, &secctx, &len); if (ret) - return ret; + return 0; ret = seq_printf(s, "secctx=%s ", secctx); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b729ace1dcc1..0cdba50c0d69 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -254,7 +254,7 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret = security_secid_to_secctx(ct->secmark, &secctx, &len); if (ret) - return ret; + return 0; ret = -1; nest_secctx = nla_nest_start(skb, CTA_SECCTX | NLA_F_NESTED); @@ -453,16 +453,22 @@ ctnetlink_counters_size(const struct nf_conn *ct) ; } -#ifdef CONFIG_NF_CONNTRACK_SECMARK -static int ctnetlink_nlmsg_secctx_size(const struct nf_conn *ct) +static inline int +ctnetlink_secctx_size(const struct nf_conn *ct) { - int len; +#ifdef CONFIG_NF_CONNTRACK_SECMARK + int len, ret; - security_secid_to_secctx(ct->secmark, NULL, &len); + ret = security_secid_to_secctx(ct->secmark, NULL, &len); + if (ret) + return 0; - return sizeof(char) * len; -} + return nla_total_size(0) /* CTA_SECCTX */ + + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ +#else + return 0; #endif +} static inline size_t ctnetlink_nlmsg_size(const struct nf_conn *ct) @@ -479,10 +485,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct) + nla_total_size(0) /* CTA_PROTOINFO */ + nla_total_size(0) /* CTA_HELP */ + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */ -#ifdef CONFIG_NF_CONNTRACK_SECMARK - + nla_total_size(0) /* CTA_SECCTX */ - + nla_total_size(ctnetlink_nlmsg_secctx_size(ct)) /* CTA_SECCTX_NAME */ -#endif + + ctnetlink_secctx_size(ct) #ifdef CONFIG_NF_NAT_NEEDED + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */ + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */ diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 0fb65705b44b..b4d7f0f24b27 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -118,7 +118,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) ret = security_secid_to_secctx(ct->secmark, &secctx, &len); if (ret) - return ret; + return 0; ret = seq_printf(s, "secctx=%s ", secctx); -- cgit v1.2.3-59-g8ed1b From 68d7c1aa2fee6acb11fcb826a207e4b81d8a1f57 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 5 Jan 2011 15:14:13 +0000 Subject: cnic: Fix the type field in SPQ messages The new firmware interface requires each Slow Path Queue (SPQ) message's type field to include the function number. The existing code does not do this consistently. We fix this by OR'ing in the function number into the type field centrally in cnic_submit_kwqe_16(). Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index aa5016ad9e19..263a2944566f 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1290,12 +1290,18 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid, struct cnic_local *cp = dev->cnic_priv; struct l5cm_spe kwqe; struct kwqe_16 *kwq[1]; + u16 type_16; int ret; kwqe.hdr.conn_and_cmd_data = cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) | BNX2X_HW_CID(cp, cid))); - kwqe.hdr.type = cpu_to_le16(type); + + type_16 = (type << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE; + type_16 |= (cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID; + + kwqe.hdr.type = cpu_to_le16(type_16); kwqe.hdr.reserved1 = 0; kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo); kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi); @@ -1819,19 +1825,15 @@ static int cnic_bnx2x_destroy_ramrod(struct cnic_dev *dev, u32 l5_cid) struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; union l5cm_specific_data l5_data; int ret; - u32 hw_cid, type; + u32 hw_cid; init_waitqueue_head(&ctx->waitq); ctx->wait_cond = 0; memset(&l5_data, 0, sizeof(l5_data)); hw_cid = BNX2X_HW_CID(cp, ctx->cid); - type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) - & SPE_HDR_CONN_TYPE; - type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & - SPE_HDR_FUNCTION_ID); ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, - hw_cid, type, &l5_data); + hw_cid, NONE_CONNECTION_TYPE, &l5_data); if (ret == 0) wait_event(ctx->waitq, ctx->wait_cond); @@ -2204,7 +2206,6 @@ static int cnic_bnx2x_fcoe_init1(struct cnic_dev *dev, struct kwqe *wqes[], cp->kcq2.sw_prod_idx = 0; cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); - printk(KERN_ERR "bdbg: submitting INIT RAMROD \n"); ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_INIT, cid, FCOE_CONNECTION_TYPE, &l5_data); *work = 3; @@ -4977,7 +4978,7 @@ static void cnic_init_rings(struct cnic_dev *dev) } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { u32 cli = cp->ethdev->iscsi_l2_client_id; u32 cid = cp->ethdev->iscsi_l2_cid; - u32 cl_qzone_id, type; + u32 cl_qzone_id; struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; struct ustorm_eth_rx_producers rx_prods = {0}; @@ -5009,15 +5010,10 @@ static void cnic_init_rings(struct cnic_dev *dev) l5_data.phy_address.lo = udev->l2_buf_map & 0xffffffff; l5_data.phy_address.hi = (u64) udev->l2_buf_map >> 32; - type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) - & SPE_HDR_CONN_TYPE; - type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & - SPE_HDR_FUNCTION_ID); - set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, - cid, type, &l5_data); + cid, ETH_CONNECTION_TYPE, &l5_data); i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && @@ -5047,7 +5043,6 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) u32 cid = cp->ethdev->iscsi_l2_cid; union l5cm_specific_data l5_data; int i; - u32 type; cnic_ring_ctl(dev, cid, cli, 0); @@ -5068,12 +5063,8 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); memset(&l5_data, 0, sizeof(l5_data)); - type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) - & SPE_HDR_CONN_TYPE; - type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & - SPE_HDR_FUNCTION_ID); cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, - cid, type, &l5_data); + cid, NONE_CONNECTION_TYPE, &l5_data); msleep(10); } clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); -- cgit v1.2.3-59-g8ed1b From 141dfba342b672588799432d74a3b6be88b5d713 Mon Sep 17 00:00:00 2001 From: Ferenc Wagner Date: Thu, 6 Jan 2011 05:11:19 +0000 Subject: netconsole: don't announce stopping if nothing happened Signed-off-by: Ferenc Wagner Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 94255f09093d..b2ad998040fa 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -664,6 +664,7 @@ static int netconsole_netdev_event(struct notifier_block *this, unsigned long flags; struct netconsole_target *nt; struct net_device *dev = ptr; + bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN)) @@ -690,13 +691,14 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_GOING_DOWN: case NETDEV_BONDING_DESLAVE: nt->enabled = 0; + stopped = true; break; } } netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); - if (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE) + if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)) printk(KERN_INFO "netconsole: network logging stopped, " "interface %s %s\n", dev->name, event == NETDEV_UNREGISTER ? "unregistered" : "released slaves"); -- cgit v1.2.3-59-g8ed1b From 38cfb907a55f3223445151b517b6e4678b8c9d66 Mon Sep 17 00:00:00 2001 From: Ferenc Wagner Date: Thu, 6 Jan 2011 05:11:20 +0000 Subject: netconsole: clarify stopping message Signed-off-by: Ferenc Wagner Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index b2ad998040fa..dfb67eb2a94b 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -699,8 +699,8 @@ static int netconsole_netdev_event(struct notifier_block *this, } spin_unlock_irqrestore(&target_list_lock, flags); if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)) - printk(KERN_INFO "netconsole: network logging stopped, " - "interface %s %s\n", dev->name, + printk(KERN_INFO "netconsole: network logging stopped on " + "interface %s as it %s\n", dev->name, event == NETDEV_UNREGISTER ? "unregistered" : "released slaves"); done: -- cgit v1.2.3-59-g8ed1b From f88de8de5a8c8a8a73960d4432ceef2d38b7f86f Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 25 Dec 2010 03:41:30 +0000 Subject: net: bridge: check the length of skb after nf_bridge_maybe_copy_header() Since nf_bridge_maybe_copy_header() may change the length of skb, we should check the length of skb after it to handle the ppoe skbs. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/bridge/br_forward.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 2bd11ec6d166..ee64287f1290 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -41,17 +41,13 @@ static inline unsigned packet_length(const struct sk_buff *skb) int br_dev_queue_push_xmit(struct sk_buff *skb) { - /* drop mtu oversized packets except gso */ - if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) + /* ip_fragment doesn't copy the MAC header */ + if (nf_bridge_maybe_copy_header(skb) || + (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))) { kfree_skb(skb); - else { - /* ip_fragment doesn't copy the MAC header */ - if (nf_bridge_maybe_copy_header(skb)) - kfree_skb(skb); - else { - skb_push(skb, ETH_HLEN); - dev_queue_xmit(skb); - } + } else { + skb_push(skb, ETH_HLEN); + dev_queue_xmit(skb); } return 0; -- cgit v1.2.3-59-g8ed1b From 2ad0d9d413abc3380fc1d89a9da7f8db59d9746b Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 6 Jan 2011 11:41:42 -0800 Subject: net: remove the duplicate #ifdef __KERNEL__ Since we are already in #ifdef __KERNEL__, we don't need to check it again. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/socket.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 86b652fabf6e..5f65f14c4f44 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -30,12 +30,10 @@ struct cred; #define __sockaddr_check_size(size) \ BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage))) -#ifdef __KERNEL__ -# ifdef CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS struct seq_file; extern void socket_seq_show(struct seq_file *seq); -# endif -#endif /* __KERNEL__ */ +#endif typedef unsigned short sa_family_t; @@ -311,7 +309,6 @@ struct ucred { /* IPX options */ #define IPX_TYPE 1 -#ifdef __KERNEL__ extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred); extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); @@ -333,6 +330,5 @@ struct timespec; extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); -#endif #endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */ -- cgit v1.2.3-59-g8ed1b From 4e3dbdb1392a83bd21a6ff8f6bc785495058d37c Mon Sep 17 00:00:00 2001 From: Richard Mortimer Date: Thu, 6 Jan 2011 11:50:30 -0800 Subject: cassini: Use local-mac-address prom property for Cassini MAC address Fallback on the local-mac-address prom property if the Cassini device does not have an address programmed in the VPD ROM. This uses the same technique as implemented by the sungem driver. The problem was reported by Frans van Berckel using Debian kernel 2.6.34-7 on Sun Fire V440. udev was assigning a new eth device name on each reboot because the cassini driver was using a random MAC address. Fix tested on 2.6.34-7 and 2.6.37 Sun Fire V440. Compile tested against 2.6.36 davem/sparc-2.6.git Reported-by: Frans van Berckel Tested-by: Frans van Berckel Reviewed-by: Julian Calaby Reviewed-by: Sam Ravnborg Signed-off-by: Richard Mortimer Signed-off-by: David S. Miller --- drivers/net/cassini.c | 16 ++++++++++++++++ drivers/net/cassini.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 73502fef8769..7206ab2cbbf8 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -3203,6 +3203,10 @@ static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr, int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */ int mac_off = 0; +#if defined(CONFIG_OF) + const unsigned char *addr; +#endif + /* give us access to the PROM */ writel(BIM_LOCAL_DEV_PROM | BIM_LOCAL_DEV_PAD, cp->regs + REG_BIM_LOCAL_DEV_EN); @@ -3350,6 +3354,14 @@ use_random_mac_addr: if (found & VPD_FOUND_MAC) goto done; +#if defined(CONFIG_OF) + addr = of_get_property(cp->of_node, "local-mac-address", NULL); + if (addr != NULL) { + memcpy(dev_addr, addr, 6); + goto done; + } +#endif + /* Sun MAC prefix then 3 random bytes. */ pr_info("MAC address not found in ROM VPD\n"); dev_addr[0] = 0x08; @@ -5019,6 +5031,10 @@ static int __devinit cas_init_one(struct pci_dev *pdev, cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE : cassini_debug; +#if defined(CONFIG_OF) + cp->of_node = pci_device_to_OF_node(pdev); +#endif + cp->link_transition = LINK_TRANSITION_UNKNOWN; cp->link_transition_jiffies_valid = 0; diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h index dbc47878d83b..faf4746a0f3e 100644 --- a/drivers/net/cassini.h +++ b/drivers/net/cassini.h @@ -2868,6 +2868,9 @@ struct cas { dma_addr_t block_dvma, tx_tiny_dvma[N_TX_RINGS]; struct pci_dev *pdev; struct net_device *dev; +#if defined(CONFIG_OF) + struct device_node *of_node; +#endif /* Firmware Info */ u16 fw_load_addr; -- cgit v1.2.3-59-g8ed1b